diff --git a/BearSSL-OG/Tools/bearssl.dll b/BearSSL-OG/Tools/bearssl.dll new file mode 100644 index 0000000..d601c32 Binary files /dev/null and b/BearSSL-OG/Tools/bearssl.dll differ diff --git a/BearSSL-OG/Tools/brssl.exe b/BearSSL-OG/Tools/brssl.exe new file mode 100644 index 0000000..32569ae Binary files /dev/null and b/BearSSL-OG/Tools/brssl.exe differ diff --git a/BearSSL-OG/Tools/testcrypto.exe b/BearSSL-OG/Tools/testcrypto.exe new file mode 100644 index 0000000..bb15fe5 Binary files /dev/null and b/BearSSL-OG/Tools/testcrypto.exe differ diff --git a/BearSSL-OG/Tools/testspeed.exe b/BearSSL-OG/Tools/testspeed.exe new file mode 100644 index 0000000..1fc146d Binary files /dev/null and b/BearSSL-OG/Tools/testspeed.exe differ diff --git a/BearSSL-OG/Tools/testx509.exe b/BearSSL-OG/Tools/testx509.exe new file mode 100644 index 0000000..791581c Binary files /dev/null and b/BearSSL-OG/Tools/testx509.exe differ diff --git a/BearSSL-OG/XboxOGBearSSL.ncb b/BearSSL-OG/XboxOGBearSSL.ncb new file mode 100644 index 0000000..282e38e Binary files /dev/null and b/BearSSL-OG/XboxOGBearSSL.ncb differ diff --git a/BearSSL-OG/XboxOGBearSSL.sln b/BearSSL-OG/XboxOGBearSSL.sln new file mode 100644 index 0000000..490d6ce --- /dev/null +++ b/BearSSL-OG/XboxOGBearSSL.sln @@ -0,0 +1,30 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XboxOGBearSSL", "XboxOGBearSSL.vcproj", "{021C5334-2823-495E-9E54-2DEC11E06040}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Profile = Profile + Profile_FastCap = Profile_FastCap + Release = Release + Release_LTCG = Release_LTCG + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {021C5334-2823-495E-9E54-2DEC11E06040}.Debug.ActiveCfg = Debug|Xbox + {021C5334-2823-495E-9E54-2DEC11E06040}.Debug.Build.0 = Debug|Xbox + {021C5334-2823-495E-9E54-2DEC11E06040}.Profile.ActiveCfg = Profile|Xbox + {021C5334-2823-495E-9E54-2DEC11E06040}.Profile.Build.0 = Profile|Xbox + {021C5334-2823-495E-9E54-2DEC11E06040}.Profile_FastCap.ActiveCfg = Profile_FastCap|Xbox + {021C5334-2823-495E-9E54-2DEC11E06040}.Profile_FastCap.Build.0 = Profile_FastCap|Xbox + {021C5334-2823-495E-9E54-2DEC11E06040}.Release.ActiveCfg = Release|Xbox + {021C5334-2823-495E-9E54-2DEC11E06040}.Release.Build.0 = Release|Xbox + {021C5334-2823-495E-9E54-2DEC11E06040}.Release_LTCG.ActiveCfg = Release_LTCG|Xbox + {021C5334-2823-495E-9E54-2DEC11E06040}.Release_LTCG.Build.0 = Release_LTCG|Xbox + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/BearSSL-OG/XboxOGBearSSL.suo b/BearSSL-OG/XboxOGBearSSL.suo new file mode 100644 index 0000000..8248849 Binary files /dev/null and b/BearSSL-OG/XboxOGBearSSL.suo differ diff --git a/BearSSL-OG/XboxOGBearSSL.vcproj b/BearSSL-OG/XboxOGBearSSL.vcproj new file mode 100644 index 0000000..0db671b --- /dev/null +++ b/BearSSL-OG/XboxOGBearSSL.vcproj @@ -0,0 +1,1381 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BearSSL-OG/bearssl.c b/BearSSL-OG/bearssl.c new file mode 100644 index 0000000..6e0af46 --- /dev/null +++ b/BearSSL-OG/bearssl.c @@ -0,0 +1,1640 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * BearSSL TLS backend for libcurl + * Designed for Xbox (Visual Studio 2003 / C89 compatible) + * + * This file implements the libcurl vtls interface using BearSSL. + * BearSSL is ideal for Xbox because: + * - Written in C89/C90 (VS 2003 compatible) + * - No dynamic memory allocation + * - Small footprint + * - No external dependencies + * + * Xbox-specific enhancements: + * - Trust anchors loaded from embedded CA database (750+ CAs) + * - Session caching for TLS resumption + * - Descriptive error messages + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_BEARSSL + +#include + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "vtls.h" +#include "connect.h" +#include "select.h" +#include "multiif.h" + +/* Xbox-specific BearSSL integration */ +#ifdef _XBOX +#include "bearssl_xbox.h" +#define BEARSSL_XBOX_INTEGRATION 1 +#else +#define BEARSSL_XBOX_INTEGRATION 0 +#endif + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Xbox time validation callback for X.509 certificate checking. + * + * The Xbox's internal RTC is unreliable: no NTP (Xbox Live for original Xbox + * is defunct), CMOS battery may be dead after 20+ years, and the clock can + * reset to 2000-01-01 or similar. A wrong system clock causes BearSSL's + * time(NULL)-based date validation to reject perfectly valid certificates. + * + * We skip date validation entirely. Trust anchor verification and optional + * certificate pinning provide the real security guarantees. + * + * Return: 0 = within validity period (always) + */ +#ifdef _XBOX +static int bearssl_xbox_time_check(void *tctx, + uint32_t not_before_days, uint32_t not_before_seconds, + uint32_t not_after_days, uint32_t not_after_seconds) +{ + (void)tctx; + (void)not_before_days; + (void)not_before_seconds; + (void)not_after_days; + (void)not_after_seconds; + return 0; +} +#endif + +/* Secure cipher suites - ECDHE with AEAD only */ +static const uint16_t bearssl_secure_suites[] = { + BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 +}; +#define BEARSSL_SECURE_SUITES_COUNT 6 + +/* + * ALPN protocol names for HTTP/1.1 + * + * ALPN (Application-Layer Protocol Negotiation) is a TLS extension that allows + * the client and server to negotiate which application protocol to use over + * the encrypted connection. Modern HTTPS servers (especially CDNs like + * Cloudflare) require ALPN to be present in the TLS handshake. + * + * Without ALPN, many servers will: + * - Reject the connection outright + * - Assume HTTP/2 and fail when receiving HTTP/1.1 + * - Reset the connection after handshake completes + * + * We advertise "http/1.1" since this libcurl build doesn't support HTTP/2. + */ +static const char *bearssl_alpn_protocols[] = { "http/1.1" }; +#define BEARSSL_ALPN_PROTOCOLS_COUNT 1 + +/* + * "No Anchor" X509 validator - wraps br_x509_minimal but accepts all certs. + * + * This approach uses BearSSL's proven certificate parsing code (br_x509_minimal) + * but overrides the validation result to always succeed. This is safer than + * implementing our own certificate decoder. + * + * Used when SSL_VERIFYPEER is disabled. + * + * NOTE: We use a POINTER to the minimal context (not embedded) to avoid + * memory layout issues with the union in ssl_backend_data. + */ +typedef struct { + const br_x509_class *vtable; + br_x509_minimal_context *minimal; /* Pointer to minimal validator */ + /* Certificate pinning: hash the leaf (first) certificate */ + br_sha256_context pin_sha256; /* SHA-256 running hash of leaf cert */ + unsigned char leaf_hash[32]; /* Final SHA-256 of leaf certificate */ + int cert_index; /* 0 = leaf cert, increments per cert */ + int leaf_hash_valid; /* 1 if leaf_hash has been computed */ + char pin_hostname[256]; /* Hostname for pin lookup */ +} br_x509_noanchor_context; + +/* Forward the call to minimal validator */ +static void xc_noanchor_start_chain(const br_x509_class **ctx, + const char *server_name) +{ + br_x509_noanchor_context *xc = (br_x509_noanchor_context *)ctx; +#ifdef _XBOX + { + char dbg[256]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: start_chain called, ctx=%p, xc=%p, minimal=%p\n", + (void*)ctx, (void*)xc, (void*)xc->minimal); + OutputDebugStringA(dbg); + if(xc->minimal) { + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: server=%s, minimal->vtable=%p\n", + server_name ? server_name : "(null)", + (void*)xc->minimal->vtable); + OutputDebugStringA(dbg); + } + } +#endif + if(!xc->minimal || !xc->minimal->vtable) { + OutputDebugStringA("BearSSL noanchor X509: ERROR - minimal or vtable is NULL!\n"); + return; + } + + /* Reset pinning state for this new chain */ + xc->cert_index = 0; + xc->leaf_hash_valid = 0; + memset(xc->leaf_hash, 0, sizeof(xc->leaf_hash)); + if(server_name) { + strncpy(xc->pin_hostname, server_name, sizeof(xc->pin_hostname) - 1); + xc->pin_hostname[sizeof(xc->pin_hostname) - 1] = '\0'; + } + else { + xc->pin_hostname[0] = '\0'; + } + + xc->minimal->vtable->start_chain(&xc->minimal->vtable, server_name); + OutputDebugStringA("BearSSL noanchor X509: start_chain forwarded OK\n"); +} + +static void xc_noanchor_start_cert(const br_x509_class **ctx, uint32_t length) +{ + br_x509_noanchor_context *xc = (br_x509_noanchor_context *)ctx; +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL noanchor X509: start_cert[%d], length=%u\n", + xc->cert_index, (unsigned)length); + OutputDebugStringA(dbg); + } +#endif + /* For the leaf certificate (index 0), start hashing for pin check */ + if(xc->cert_index == 0) { + br_sha256_init(&xc->pin_sha256); + } + xc->minimal->vtable->start_cert(&xc->minimal->vtable, length); +} + +static void xc_noanchor_append(const br_x509_class **ctx, + const unsigned char *buf, size_t len) +{ + br_x509_noanchor_context *xc = (br_x509_noanchor_context *)ctx; + /* Feed leaf certificate bytes into SHA-256 for pinning */ + if(xc->cert_index == 0) { + br_sha256_update(&xc->pin_sha256, buf, len); + } + xc->minimal->vtable->append(&xc->minimal->vtable, buf, len); +} + +static void xc_noanchor_end_cert(const br_x509_class **ctx) +{ + br_x509_noanchor_context *xc = (br_x509_noanchor_context *)ctx; +#ifdef _XBOX + { + char dbg[64]; + msnprintf(dbg, sizeof(dbg), "BearSSL noanchor X509: end_cert[%d]\n", + xc->cert_index); + OutputDebugStringA(dbg); + } +#endif + xc->minimal->vtable->end_cert(&xc->minimal->vtable); + + /* Finalize the SHA-256 hash of the leaf certificate */ + if(xc->cert_index == 0) { + br_sha256_out(&xc->pin_sha256, xc->leaf_hash); + xc->leaf_hash_valid = 1; +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: leaf cert SHA-256: " + "%02X%02X%02X%02X%02X%02X%02X%02X...\n", + xc->leaf_hash[0], xc->leaf_hash[1], + xc->leaf_hash[2], xc->leaf_hash[3], + xc->leaf_hash[4], xc->leaf_hash[5], + xc->leaf_hash[6], xc->leaf_hash[7]); + OutputDebugStringA(dbg); + } +#endif + } + xc->cert_index++; + +#ifdef _XBOX + /* Log the minimal validator's state after processing certificate */ + { + char dbg[256]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: minimal->err=%d, pkey.key_type=%d\n", + xc->minimal->err, xc->minimal->pkey.key_type); + OutputDebugStringA(dbg); + + if(xc->minimal->pkey.key_type == BR_KEYTYPE_RSA) { + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: RSA key - n=%p nlen=%u e=%p elen=%u\n", + (void*)xc->minimal->pkey.key.rsa.n, + (unsigned)xc->minimal->pkey.key.rsa.nlen, + (void*)xc->minimal->pkey.key.rsa.e, + (unsigned)xc->minimal->pkey.key.rsa.elen); + OutputDebugStringA(dbg); + } + else if(xc->minimal->pkey.key_type == BR_KEYTYPE_EC) { + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: EC key - curve=%d q=%p qlen=%u\n", + xc->minimal->pkey.key.ec.curve, + (void*)xc->minimal->pkey.key.ec.q, + (unsigned)xc->minimal->pkey.key.ec.qlen); + OutputDebugStringA(dbg); + } + } +#endif +} + +static unsigned xc_noanchor_end_chain(const br_x509_class **ctx) +{ + br_x509_noanchor_context *xc = (br_x509_noanchor_context *)ctx; + unsigned result; + + /* Call the minimal validator's end_chain */ + result = xc->minimal->vtable->end_chain(&xc->minimal->vtable); + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: end_chain, minimal returned %u (err=%d)\n", + result, xc->minimal->err); + OutputDebugStringA(dbg); + } +#endif + + /* + * Override the result: accept certificates in insecure mode. + * + * When SSL_VERIFYPEER is disabled, we accept all validation errors: + * - BR_ERR_X509_OK (32) - success + * - BR_ERR_X509_EXPIRED (54) - certificate expired or not yet valid + * - BR_ERR_X509_DN_MISMATCH (55) - issuer/subject DN mismatch + * - BR_ERR_X509_BAD_SERVER_NAME (56) - server name doesn't match cert + * - BR_ERR_X509_NOT_TRUSTED (62) - no matching trust anchor + * + * We only fail on actual parsing errors (33-52) which indicate a + * malformed certificate that cannot be used. + */ + if(result == BR_ERR_X509_OK || + result == BR_ERR_X509_EXPIRED || + result == BR_ERR_X509_DN_MISMATCH || + result == BR_ERR_X509_BAD_SERVER_NAME || + result == BR_ERR_X509_CRITICAL_EXTENSION || + result == BR_ERR_X509_NOT_CA || + result == BR_ERR_X509_FORBIDDEN_KEY_USAGE || + result == BR_ERR_X509_WEAK_PUBLIC_KEY || + result == BR_ERR_X509_NOT_TRUSTED) { + + /* + * Certificate pinning check: if a pin is registered for this hostname, + * verify the leaf certificate hash matches. This runs even in insecure + * mode because pinning is an explicit trust decision by the application. + */ +#if BEARSSL_XBOX_INTEGRATION + if(xc->leaf_hash_valid && xc->pin_hostname[0] != '\0') { + if(!bearssl_xbox_pin_verify_hash(xc->pin_hostname, xc->leaf_hash)) { +#ifdef _XBOX + OutputDebugStringA("BearSSL noanchor X509: CERTIFICATE PIN MISMATCH - rejecting!\n"); +#endif + return BR_ERR_X509_NOT_TRUSTED; + } + } +#endif + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: accepting certificate (insecure mode, result=%u)\n", + result); + OutputDebugStringA(dbg); + } +#endif + return 0; /* Success */ + } + + /* For actual parsing errors (bad certificate format, etc.), we still fail */ +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: certificate parsing error %u\n", result); + OutputDebugStringA(dbg); + } +#endif + return result; +} + +static const br_x509_pkey *xc_noanchor_get_pkey( + const br_x509_class *const *ctx, unsigned *usages) +{ + br_x509_noanchor_context *xc = (br_x509_noanchor_context *)ctx; + const br_x509_pkey *pk; + + /* Get the public key from the minimal validator */ + pk = xc->minimal->vtable->get_pkey(&xc->minimal->vtable, usages); + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: get_pkey returned %p (err=%d, key_type=%d)\n", + (void*)pk, xc->minimal->err, xc->minimal->pkey.key_type); + OutputDebugStringA(dbg); + } +#endif + + /* + * The minimal validator only returns the key if err is OK (32) or + * NOT_TRUSTED (62). For other validation errors like BAD_SERVER_NAME (56), + * EXPIRED (54), etc., it returns NULL even though the key was parsed. + * + * In insecure mode, we need to return the key for any validation error + * as long as the key itself was successfully parsed. + */ + if(!pk) { + /* + * Minimal validator didn't return key. Check if the key was parsed + * successfully - if so, return it directly. This handles validation + * errors like BAD_SERVER_NAME where the cert is valid but doesn't + * match requirements we're choosing to ignore. + */ + if(xc->minimal->pkey.key_type == BR_KEYTYPE_RSA || + xc->minimal->pkey.key_type == BR_KEYTYPE_EC) { +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: returning key directly (err=%d bypassed)\n", + xc->minimal->err); + OutputDebugStringA(dbg); + } +#endif + if(usages) + *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN; + return &xc->minimal->pkey; + } +#ifdef _XBOX + OutputDebugStringA("BearSSL noanchor X509: ERROR - no valid key available!\n"); +#endif + } + + return pk; +} + +static const br_x509_class br_x509_noanchor_vtable = { + sizeof(br_x509_noanchor_context), + xc_noanchor_start_chain, + xc_noanchor_start_cert, + xc_noanchor_append, + xc_noanchor_end_cert, + xc_noanchor_end_chain, + xc_noanchor_get_pkey +}; + +/* + * Legacy insecure validator kept for reference but not used. + * The noanchor approach above is preferred. + */ +#if 0 /* DISABLED - using noanchor instead */ + +typedef struct { + const br_x509_class *vtable; + br_x509_decoder_context decoder; + br_x509_pkey pkey; + unsigned char pkey_data[BR_EC_KBUF_PUB_MAX_SIZE]; + unsigned char rsa_n[512]; + unsigned char rsa_e[8]; + int first_cert; + int pkey_valid; + uint32_t expected_len; + uint32_t received_len; +} br_x509_insecure_context; + +static void xc_insecure_start_chain(const br_x509_class **ctx, + const char *server_name) +{ + br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; + (void)server_name; + xc->first_cert = 1; + xc->pkey_valid = 0; +} + +/* ... rest of insecure implementation ... */ + +#endif /* DISABLED */ + +/* BearSSL backend data structure */ +struct ssl_backend_data { + br_ssl_client_context sc; + br_x509_minimal_context xc_minimal; /* Minimal X509 validator */ + br_x509_noanchor_context xc_noanchor; /* Noanchor wrapper (small, just vtable + pointer) */ + int using_noanchor; /* Are we using the noanchor (no-verify) validator? */ + unsigned char iobuf[BR_SSL_BUFSIZE_BIDI]; + br_sslio_context ioc; + int active; /* Is the SSL connection active? */ + int session_resumed; /* Was session resumed? */ + int io_error; /* Have we had a socket I/O error? Skip graceful close if so */ + unsigned char leaf_cert_hash[32]; /* SHA-256 of leaf cert (from X.509 callback) */ + int leaf_cert_hash_valid; /* 1 if hash was captured */ + char hostname[256]; /* Hostname for session caching */ +#if BEARSSL_XBOX_INTEGRATION + br_x509_trust_anchor *file_anchors; /* Per-connection CAs from CURLOPT_CAINFO */ + size_t file_anchor_count; +#endif +}; + +#define BACKEND connssl->backend + +/* Forward declarations for send/recv functions */ +static Curl_recv bearssl_recv; +static Curl_send bearssl_send; + +/* Global state for trust anchor initialization */ +static int bearssl_trust_anchors_loaded = 0; +#if BEARSSL_XBOX_INTEGRATION +static int bearssl_trust_store_updated = 0; +#endif + +/* Low-level socket read callback for BearSSL */ +static int +sock_read(void *ctx, unsigned char *buf, size_t len) +{ + curl_socket_t fd = *(curl_socket_t *)ctx; + ssize_t rlen; + + /* + * Simple blocking read - no retry loop. + * The socket should already be in blocking mode, and libcurl manages + * timeouts at a higher level. We just do a single recv() call. + */ + rlen = recv(fd, (char *)buf, (int)len, 0); + + if(rlen > 0) { + /* Success - got data */ +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[64]; + msnprintf(dbg, sizeof(dbg), "BearSSL sock_read: got %d bytes\n", (int)rlen); + OutputDebugStringA(dbg); + } +#endif + return (int)rlen; + } + + if(rlen == 0) { + /* Connection closed by peer */ +#ifdef BEARSSL_VERBOSE_DEBUG + OutputDebugStringA("BearSSL sock_read: connection closed by peer\n"); +#endif + return -1; + } + + /* rlen < 0 - error */ + { + int err = SOCKERRNO; +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[64]; + msnprintf(dbg, sizeof(dbg), "BearSSL sock_read: recv error %d\n", err); + OutputDebugStringA(dbg); + } +#endif + + /* For EINTR, we could retry, but it's simpler to let the caller handle it */ + if(err == EWOULDBLOCK || err == EAGAIN) { + /* Would block - return 0 to indicate no data available yet */ + /* BearSSL will handle this appropriately */ + return 0; + } + + /* Real error - return -1 */ + return -1; + } +} + +/* Low-level socket write callback for BearSSL */ +static int +sock_write(void *ctx, const unsigned char *buf, size_t len) +{ + curl_socket_t fd = *(curl_socket_t *)ctx; + ssize_t wlen; + + /* + * Simple blocking write - no retry loop. + * The socket should already be in blocking mode, and libcurl manages + * timeouts at a higher level. We just do a single send() call. + */ + wlen = send(fd, (const char *)buf, (int)len, 0); + + if(wlen > 0) { + /* Success - data sent */ +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[64]; + msnprintf(dbg, sizeof(dbg), "BearSSL sock_write: sent %d bytes\n", (int)wlen); + OutputDebugStringA(dbg); + } +#endif + return (int)wlen; + } + + if(wlen == 0) { + /* No data sent - treat as would-block */ + return 0; + } + + /* wlen < 0 - error */ + { + int err = SOCKERRNO; +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[64]; + msnprintf(dbg, sizeof(dbg), "BearSSL sock_write: send error %d\n", err); + OutputDebugStringA(dbg); + } +#endif + + if(err == EWOULDBLOCK || err == EAGAIN) { + /* Would block - return 0 to indicate no data sent yet */ + return 0; + } + + /* Real error - return -1 */ + return -1; + } +} + +/* Get descriptive error message for BearSSL error code */ +static const char * +bearssl_error_string(int err) +{ +#if BEARSSL_XBOX_INTEGRATION + return bearssl_xbox_error_string(err); +#else + /* Fallback error messages for non-Xbox builds */ + switch(err) { + case BR_ERR_OK: return "Success"; + case BR_ERR_BAD_PARAM: return "Bad parameter"; + case BR_ERR_BAD_STATE: return "Invalid state"; + case BR_ERR_UNSUPPORTED_VERSION: return "Unsupported TLS version"; + case BR_ERR_BAD_VERSION: return "Bad TLS version"; + case BR_ERR_TOO_LARGE: return "Record too large"; + case BR_ERR_BAD_MAC: return "MAC verification failed"; + case BR_ERR_NO_RANDOM: return "No random seed"; + case BR_ERR_UNKNOWN_TYPE: return "Unknown record type"; + case BR_ERR_UNEXPECTED: return "Unexpected message"; + case BR_ERR_BAD_CCS: return "Bad ChangeCipherSpec"; + case BR_ERR_BAD_ALERT: return "Bad alert"; + case BR_ERR_BAD_HANDSHAKE: return "Bad handshake message"; + case BR_ERR_OVERSIZED_ID: return "Oversized ID"; + case BR_ERR_BAD_CIPHER_SUITE: return "Bad cipher suite"; + case BR_ERR_BAD_COMPRESSION: return "Bad compression"; + case BR_ERR_BAD_FRAGLEN: return "Bad fragment length"; + case BR_ERR_BAD_SECRENEG: return "Bad secure renegotiation"; + case BR_ERR_EXTRA_EXTENSION: return "Extra extension"; + case BR_ERR_BAD_SNI: return "Bad SNI"; + case BR_ERR_BAD_HELLO_DONE: return "Bad HelloDone"; + case BR_ERR_LIMIT_EXCEEDED: return "Limit exceeded"; + case BR_ERR_BAD_FINISHED: return "Bad Finished message"; + case BR_ERR_RESUME_MISMATCH: return "Session resume mismatch"; + case BR_ERR_INVALID_ALGORITHM: return "Invalid algorithm"; + case BR_ERR_BAD_SIGNATURE: return "Bad signature"; + case BR_ERR_WRONG_KEY_USAGE: return "Wrong key usage"; + case BR_ERR_NO_CLIENT_AUTH: return "No client auth"; + case BR_ERR_IO: return "I/O error"; + default: + if(err >= 256 && err < 512) + return "Received fatal alert from server"; + if(err >= 512) + return "Sent fatal alert to server"; + return "Unknown SSL error"; + } +#endif +} + +static int Curl_bearssl_init(void) +{ +#if BEARSSL_XBOX_INTEGRATION + /* Initialize trust anchors from Xbox certificate store */ + if(!bearssl_trust_anchors_loaded) { + bearssl_xbox_init_trust_anchors(); + bearssl_xbox_session_init(); + bearssl_trust_anchors_loaded = 1; + } +#endif + return 1; +} + +static void Curl_bearssl_cleanup(void) +{ +#if BEARSSL_XBOX_INTEGRATION + if(bearssl_trust_anchors_loaded) { + bearssl_xbox_session_shutdown(); + bearssl_xbox_cleanup_trust_anchors(); + bearssl_trust_anchors_loaded = 0; + bearssl_trust_store_updated = 0; + } +#endif +} + +static size_t Curl_bearssl_version(char *buffer, size_t size) +{ + return msnprintf(buffer, size, "BearSSL/0.6-Xbox"); +} + +static CURLcode Curl_bearssl_random(struct Curl_easy *data, + unsigned char *entropy, size_t length) +{ + br_hmac_drbg_context rng; + br_prng_seeder seeder; + + (void)data; + + seeder = br_prng_seeder_system(NULL); + if(!seeder) { + return CURLE_SSL_CONNECT_ERROR; + } + + br_hmac_drbg_init(&rng, &br_sha256_vtable, NULL, 0); + if(!seeder(&rng.vtable)) { + return CURLE_SSL_CONNECT_ERROR; + } + + br_hmac_drbg_generate(&rng, entropy, length); + return CURLE_OK; +} + +static CURLcode +bearssl_connect_step1(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + br_x509_trust_anchor *trust_anchors = NULL; + size_t trust_anchor_count = 0; + int session_resume = 0; +#if BEARSSL_XBOX_INTEGRATION + br_ssl_session_parameters session_params; +#endif + + /* + * NOTE: BACKEND memory is pre-allocated by the vtls layer in url.c as part + * of a single contiguous block for all SSL contexts. We must NOT allocate + * or free it ourselves - that would corrupt the heap. + * + * See url.c:allocate_conn() which does: + * conn->ssl[0].backend = (void *)ssl; + * conn->ssl[1].backend = (void *)(ssl + sslsize); + * conn->proxy_ssl[0].backend = (void *)(ssl + 2 * sslsize); + * conn->proxy_ssl[1].backend = (void *)(ssl + 3 * sslsize); + */ + DEBUGASSERT(BACKEND != NULL); + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL step1: Using pre-allocated backend at %p, size=%u bytes\n", + (void*)BACKEND, (unsigned)sizeof(struct ssl_backend_data)); + OutputDebugStringA(dbg); + } +#endif + + /* Clear the backend structure for fresh initialization */ + memset(BACKEND, 0, sizeof(struct ssl_backend_data)); + + /* Store hostname for session caching */ + strncpy(BACKEND->hostname, hostname, sizeof(BACKEND->hostname) - 1); + BACKEND->hostname[sizeof(BACKEND->hostname) - 1] = '\0'; + BACKEND->session_resumed = 0; + +#if BEARSSL_XBOX_INTEGRATION + /* Auto-download cacert.pem on first connection if not on disk. + * Done here (not in Curl_bearssl_init) because XNet needs time + * after DHCP before TCP connects work reliably. */ + if(!bearssl_trust_store_updated) { + bearssl_trust_store_updated = 1; + bearssl_xbox_update_trust_store(); + } +#endif + + /* Check if certificate verification is disabled */ + if(!SSL_CONN_CONFIG(verifypeer)) { + /* + * No verification - use the "noanchor" validator that wraps br_x509_minimal + * but accepts all certificates. This leverages BearSSL's proven certificate + * parsing code while bypassing the trust validation. + */ + OutputDebugStringA("BearSSL: Certificate verification DISABLED - using noanchor validator\n"); + BACKEND->using_noanchor = 1; + +#ifdef _XBOX + { + char dbg[512]; + msnprintf(dbg, sizeof(dbg), + "BearSSL: BACKEND=%p, sizeof(ssl_backend_data)=%u\n", + (void*)BACKEND, (unsigned)sizeof(struct ssl_backend_data)); + OutputDebugStringA(dbg); + msnprintf(dbg, sizeof(dbg), + "BearSSL: sizeof(br_ssl_client_context)=%u\n", + (unsigned)sizeof(br_ssl_client_context)); + OutputDebugStringA(dbg); + msnprintf(dbg, sizeof(dbg), + "BearSSL: sizeof(br_x509_minimal_context)=%u\n", + (unsigned)sizeof(br_x509_minimal_context)); + OutputDebugStringA(dbg); + msnprintf(dbg, sizeof(dbg), + "BearSSL: &BACKEND->sc=%p, &BACKEND->xc_minimal=%p\n", + (void*)&BACKEND->sc, (void*)&BACKEND->xc_minimal); + OutputDebugStringA(dbg); + } +#endif + + OutputDebugStringA("BearSSL: Calling br_ssl_client_init_full...\n"); + + /* + * Initialize the SSL client with the minimal X509 validator. + * We pass NULL trust anchors - the minimal validator will fail with + * NOT_TRUSTED, but our noanchor wrapper overrides that to accept anyway. + */ + br_ssl_client_init_full(&BACKEND->sc, &BACKEND->xc_minimal, NULL, 0); + + OutputDebugStringA("BearSSL: br_ssl_client_init_full done\n"); + +#ifdef _XBOX + { + char dbg[256]; + msnprintf(dbg, sizeof(dbg), + "BearSSL: xc_minimal at %p, xc_minimal.vtable = %p\n", + (void*)&BACKEND->xc_minimal, + (void*)BACKEND->xc_minimal.vtable); + OutputDebugStringA(dbg); + } +#endif + + /* Set up the noanchor wrapper to point to the minimal validator */ + BACKEND->xc_noanchor.vtable = &br_x509_noanchor_vtable; + BACKEND->xc_noanchor.minimal = &BACKEND->xc_minimal; + + OutputDebugStringA("BearSSL: Setting X509 engine to noanchor wrapper...\n"); + +#ifdef _XBOX + { + char dbg[256]; + msnprintf(dbg, sizeof(dbg), + "BearSSL: xc_noanchor at %p, vtable=%p, minimal=%p\n", + (void*)&BACKEND->xc_noanchor, + (void*)BACKEND->xc_noanchor.vtable, + (void*)BACKEND->xc_noanchor.minimal); + OutputDebugStringA(dbg); + } +#endif + + /* Replace the X509 engine with our noanchor validator wrapper */ + br_ssl_engine_set_x509(&BACKEND->sc.eng, &BACKEND->xc_noanchor.vtable); + OutputDebugStringA("BearSSL: Noanchor X509 validator installed\n"); + } + else { +#if BEARSSL_XBOX_INTEGRATION + { + /* Check for CURLOPT_CAINFO or default Xbox CA path */ + const char *cafile = SSL_CONN_CONFIG(CAfile); + + /* If no explicit CA file, try the default Xbox TDATA path */ + if(!cafile || !cafile[0]) { + cafile = BEARSSL_XBOX_DEFAULT_CA_FILE; + } + + /* Try loading CA bundle from PEM file */ + if(bearssl_xbox_load_ca_file(cafile, + &BACKEND->file_anchors, &BACKEND->file_anchor_count) == 0) { + trust_anchors = BACKEND->file_anchors; + trust_anchor_count = BACKEND->file_anchor_count; + infof(data, "BearSSL: Loaded %zu trust anchors from %s\n", + trust_anchor_count, cafile); + } + + /* Fall back to compiled-in trust anchors */ + if(!trust_anchors) { + trust_anchors = bearssl_xbox_get_trust_anchors(); + trust_anchor_count = bearssl_xbox_get_trust_anchor_count(); + } + } + + if(!trust_anchors || trust_anchor_count == 0) { + failf(data, "BearSSL: No trust anchors available for certificate verification"); + return CURLE_SSL_CACERT_BADFILE; + } + infof(data, "BearSSL: Using %zu trust anchors for verification\n", + trust_anchor_count); +#else + /* No trust anchors available - cannot verify */ + failf(data, "BearSSL: Certificate verification requested but no trust anchors available"); + return CURLE_SSL_CACERT_BADFILE; +#endif + + BACKEND->using_noanchor = 0; + /* Initialize the BearSSL client context with trust anchors */ + br_ssl_client_init_full(&BACKEND->sc, &BACKEND->xc_minimal, + trust_anchors, trust_anchor_count); + +#ifdef _XBOX + /* Skip certificate date validation - Xbox clock is unreliable */ + br_x509_minimal_set_time_callback(&BACKEND->xc_minimal, + NULL, bearssl_xbox_time_check); +#endif + } + + OutputDebugStringA("BearSSL: Setting protocol versions...\n"); + + /* Set protocol versions based on CURLOPT_SSLVERSION */ + { + /* + * Default to TLS 1.2 minimum for security. + * TLS 1.0 and 1.1 are deprecated and have known vulnerabilities. + */ + int min_ver = BR_TLS12; + int max_ver = BR_TLS12; + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_DEFAULT: + /* Default: TLS 1.2 only (most compatible + secure) */ + min_ver = BR_TLS12; + break; + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: + /* Allow TLS 1.0 if explicitly requested (legacy support) */ + min_ver = BR_TLS10; + break; + case CURL_SSLVERSION_TLSv1_1: + min_ver = BR_TLS11; + break; + case CURL_SSLVERSION_TLSv1_2: + min_ver = BR_TLS12; + break; + case CURL_SSLVERSION_TLSv1_3: + /* BearSSL doesn't support TLS 1.3 */ + failf(data, "BearSSL does not support TLS 1.3"); + return CURLE_SSL_CONNECT_ERROR; + default: + failf(data, "Unsupported SSL version"); + return CURLE_SSL_CONNECT_ERROR; + } + + br_ssl_engine_set_versions(&BACKEND->sc.eng, min_ver, max_ver); + } + OutputDebugStringA("BearSSL: Protocol versions set\n"); + + /* Use secure cipher suites only */ + br_ssl_engine_set_suites(&BACKEND->sc.eng, + bearssl_secure_suites, BEARSSL_SECURE_SUITES_COUNT); + OutputDebugStringA("BearSSL: Cipher suites set\n"); + + /* + * Set ALPN (Application-Layer Protocol Negotiation) protocols. + * + * This tells the server we want to speak HTTP/1.1. Without ALPN, modern + * servers like Cloudflare may reset the connection after handshake because + * they don't know what protocol the client expects. + */ + br_ssl_engine_set_protocol_names(&BACKEND->sc.eng, + bearssl_alpn_protocols, + BEARSSL_ALPN_PROTOCOLS_COUNT); + OutputDebugStringA("BearSSL: ALPN protocols set (http/1.1)\n"); + + /* Set I/O buffer */ + br_ssl_engine_set_buffer(&BACKEND->sc.eng, BACKEND->iobuf, + sizeof(BACKEND->iobuf), 1); + OutputDebugStringA("BearSSL: I/O buffer set\n"); + +#if BEARSSL_XBOX_INTEGRATION + /* Try to resume previous session */ + if(bearssl_xbox_session_get(hostname, &session_params)) { + br_ssl_engine_set_session_parameters(&BACKEND->sc.eng, &session_params); + session_resume = 1; + infof(data, "BearSSL: Attempting session resumption for %s\n", hostname); + } +#endif + + OutputDebugStringA("BearSSL: Calling br_ssl_client_reset...\n"); + + /* Reset the client context for the new connection */ + br_ssl_client_reset(&BACKEND->sc, hostname, session_resume); + + OutputDebugStringA("BearSSL: br_ssl_client_reset done\n"); + +#ifdef _XBOX + { + char dbg[256]; + msnprintf(dbg, sizeof(dbg), + "BearSSL step1: hostname=%s, socket=%d, sockindex=%d\n", + hostname, (int)conn->sock[sockindex], sockindex); + OutputDebugStringA(dbg); + + /* Verify socket is valid */ + if(conn->sock[sockindex] == CURL_SOCKET_BAD) { + OutputDebugStringA("BearSSL step1: ERROR - socket is INVALID!\n"); + } + } +#endif + + OutputDebugStringA("BearSSL: Calling br_sslio_init...\n"); + + /* Initialize the I/O wrapper */ + br_sslio_init(&BACKEND->ioc, &BACKEND->sc.eng, + sock_read, &conn->sock[sockindex], + sock_write, &conn->sock[sockindex]); + + OutputDebugStringA("BearSSL: br_sslio_init done\n"); + + /* Note: BACKEND->active is set in step3 after handshake completes */ + connssl->connecting_state = ssl_connect_2; + + OutputDebugStringA("BearSSL step1: complete, moving to step2\n"); + return CURLE_OK; +} + +static CURLcode +bearssl_connect_step2(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + unsigned state; + int err; + + state = br_ssl_engine_current_state(&BACKEND->sc.eng); + +#ifdef _XBOX + { + static int step2_call_count = 0; + char dbg[256]; + step2_call_count++; + msnprintf(dbg, sizeof(dbg), + "BearSSL step2 [%d]: state=0x%x (CLOSED=%d SENDREC=%d RECVREC=%d SENDAPP=%d)\n", + step2_call_count, state, + (state & BR_SSL_CLOSED) ? 1 : 0, + (state & BR_SSL_SENDREC) ? 1 : 0, + (state & BR_SSL_RECVREC) ? 1 : 0, + (state & BR_SSL_SENDAPP) ? 1 : 0); + OutputDebugStringA(dbg); + } +#endif + + /* Check for errors */ + err = br_ssl_engine_last_error(&BACKEND->sc.eng); + if(err != BR_ERR_OK) { +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL step2: engine error %d\n", err); + OutputDebugStringA(dbg); + } +#endif + failf(data, "BearSSL: %s (error %d)", bearssl_error_string(err), err); + return CURLE_SSL_CONNECT_ERROR; + } + + /* Check if handshake is complete */ + if(state & BR_SSL_SENDAPP) { + /* Handshake complete, application data can be sent */ + connssl->connecting_state = ssl_connect_3; + return CURLE_OK; + } + + /* Handshake still in progress */ + if(state & BR_SSL_SENDREC) { + /* Need to send data */ + int ret; + OutputDebugStringA("BearSSL step2: flushing send buffer...\n"); + ret = br_sslio_flush(&BACKEND->ioc); +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL step2: flush returned %d\n", ret); + OutputDebugStringA(dbg); + } +#endif + if(ret < 0) { + err = br_ssl_engine_last_error(&BACKEND->sc.eng); +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL step2: flush error, engine err=%d\n", err); + OutputDebugStringA(dbg); + } +#endif + if(err != BR_ERR_OK) { + failf(data, "BearSSL handshake: %s (error %d)", + bearssl_error_string(err), err); + return CURLE_SSL_CONNECT_ERROR; + } + } + } + + if(state & BR_SSL_RECVREC) { + /* Need to receive data - handled by sslio layer */ + unsigned char tmp[1]; + int ret; + OutputDebugStringA("BearSSL step2: attempting to receive...\n"); + ret = br_sslio_read(&BACKEND->ioc, tmp, 0); +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL step2: read returned %d\n", ret); + OutputDebugStringA(dbg); + } +#endif + if(ret < 0) { + err = br_ssl_engine_last_error(&BACKEND->sc.eng); +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL step2: read error, engine err=%d\n", err); + OutputDebugStringA(dbg); + } +#endif + if(err != BR_ERR_OK && err != BR_ERR_IO) { + failf(data, "BearSSL handshake: %s (error %d)", + bearssl_error_string(err), err); + return CURLE_SSL_CONNECT_ERROR; + } + } + } + + /* Check state again */ + state = br_ssl_engine_current_state(&BACKEND->sc.eng); + if(state & BR_SSL_SENDAPP) { + connssl->connecting_state = ssl_connect_3; + return CURLE_OK; + } + + /* Still connecting */ + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; +} + +static CURLcode +bearssl_connect_step3(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + br_ssl_session_parameters session_params; + unsigned version; + const char *version_str; + + /* Get negotiated TLS version */ + version = br_ssl_engine_get_version(&BACKEND->sc.eng); + switch(version) { + case BR_TLS10: version_str = "TLS 1.0"; break; + case BR_TLS11: version_str = "TLS 1.1"; break; + case BR_TLS12: version_str = "TLS 1.2"; break; + default: version_str = "Unknown"; break; + } + + /* Log ALPN negotiation result */ + { + const char *alpn_protocol; + alpn_protocol = br_ssl_engine_get_selected_protocol(&BACKEND->sc.eng); + if(alpn_protocol) { + infof(data, "BearSSL: ALPN negotiated protocol: %s\n", alpn_protocol); +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL: ALPN selected: %s\n", alpn_protocol); + OutputDebugStringA(dbg); + } +#endif + } + else { + infof(data, "BearSSL: ALPN not negotiated (server may not support it)\n"); +#ifdef _XBOX + OutputDebugStringA("BearSSL: ALPN not negotiated by server\n"); +#endif + } + } + + /* Check if session was resumed */ + br_ssl_engine_get_session_parameters(&BACKEND->sc.eng, &session_params); + if(session_params.session_id_len > 0) { + /* Check if this was a resumed session */ + /* Note: BearSSL doesn't have a direct "was resumed" flag, + but we can infer from session ID presence on a fresh context */ + infof(data, "BearSSL: %s connection using %s\n", + BACKEND->session_resumed ? "Resumed" : "New", version_str); + } + else { + infof(data, "BearSSL: New connection using %s\n", version_str); + } + +#if BEARSSL_XBOX_INTEGRATION + /* Store session for future resumption. + * Store if we have a session ID or a session ticket (RFC 5077). */ + if(session_params.session_id_len > 0 + || session_params.session_ticket_len > 0) { + bearssl_xbox_session_store(BACKEND->hostname, &session_params); + } + + /* Copy captured leaf certificate hash from X.509 callback */ + if(BACKEND->using_noanchor && BACKEND->xc_noanchor.leaf_hash_valid) { + memcpy(BACKEND->leaf_cert_hash, BACKEND->xc_noanchor.leaf_hash, 32); + BACKEND->leaf_cert_hash_valid = 1; +#ifdef _XBOX + { + char dbg[256]; + msnprintf(dbg, sizeof(dbg), + "BearSSL step3: Leaf cert SHA-256: " + "%02X%02X%02X%02X %02X%02X%02X%02X " + "%02X%02X%02X%02X %02X%02X%02X%02X " + "%02X%02X%02X%02X %02X%02X%02X%02X " + "%02X%02X%02X%02X %02X%02X%02X%02X\n", + BACKEND->leaf_cert_hash[0], BACKEND->leaf_cert_hash[1], + BACKEND->leaf_cert_hash[2], BACKEND->leaf_cert_hash[3], + BACKEND->leaf_cert_hash[4], BACKEND->leaf_cert_hash[5], + BACKEND->leaf_cert_hash[6], BACKEND->leaf_cert_hash[7], + BACKEND->leaf_cert_hash[8], BACKEND->leaf_cert_hash[9], + BACKEND->leaf_cert_hash[10], BACKEND->leaf_cert_hash[11], + BACKEND->leaf_cert_hash[12], BACKEND->leaf_cert_hash[13], + BACKEND->leaf_cert_hash[14], BACKEND->leaf_cert_hash[15], + BACKEND->leaf_cert_hash[16], BACKEND->leaf_cert_hash[17], + BACKEND->leaf_cert_hash[18], BACKEND->leaf_cert_hash[19], + BACKEND->leaf_cert_hash[20], BACKEND->leaf_cert_hash[21], + BACKEND->leaf_cert_hash[22], BACKEND->leaf_cert_hash[23], + BACKEND->leaf_cert_hash[24], BACKEND->leaf_cert_hash[25], + BACKEND->leaf_cert_hash[26], BACKEND->leaf_cert_hash[27], + BACKEND->leaf_cert_hash[28], BACKEND->leaf_cert_hash[29], + BACKEND->leaf_cert_hash[30], BACKEND->leaf_cert_hash[31]); + OutputDebugStringA(dbg); + } +#endif + } +#endif + + /* Connection is now established - mark SSL as active for proper cleanup */ + /* + * CRITICAL: Register our SSL send/recv functions with libcurl. + * + * libcurl uses conn->recv[sockindex] and conn->send[sockindex] for all + * data transfer. If we don't set these to our BearSSL functions, libcurl + * will send raw unencrypted data over the TLS connection, causing the + * server to reset the connection. + * + * This was the root cause of the "connection reset after handshake" bug. + */ + conn->recv[sockindex] = bearssl_recv; + conn->send[sockindex] = bearssl_send; + +#ifdef _XBOX + OutputDebugStringA("BearSSL: Registered send/recv handlers with libcurl\n"); +#endif + + BACKEND->active = 1; + connssl->connecting_state = ssl_connect_done; + connssl->state = ssl_connection_complete; + + return CURLE_OK; +} + +static CURLcode +bearssl_connect_common(struct connectdata *conn, int sockindex, + bool nonblocking, bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + long timeout_ms; + int what; + + /* Check if already connected */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + timeout_ms = Curl_timeleft(data, NULL, TRUE); + if(timeout_ms < 0) { + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + result = bearssl_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state) { + timeout_ms = Curl_timeleft(data, NULL, TRUE); + if(timeout_ms < 0) { + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* Check socket readiness */ + what = Curl_socket_check(sockfd, CURL_SOCKET_BAD, sockfd, + nonblocking ? 0 : timeout_ms); + if(what < 0) { + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + + result = bearssl_connect_step2(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_3 == connssl->connecting_state) { + result = bearssl_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + *done = TRUE; + } + else { + *done = FALSE; + } + + return CURLE_OK; +} + +static CURLcode +Curl_bearssl_connect_blocking(struct connectdata *conn, int sockindex) +{ + bool done = FALSE; + CURLcode result; + + result = bearssl_connect_common(conn, sockindex, FALSE, &done); + if(result) + return result; + + DEBUGASSERT(done); + return CURLE_OK; +} + +static CURLcode +Curl_bearssl_connect_nonblocking(struct connectdata *conn, int sockindex, + bool *done) +{ + return bearssl_connect_common(conn, sockindex, TRUE, done); +} + +static void Curl_bearssl_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL close: sockindex=%d, state=%d, backend=%p\n", + sockindex, (int)connssl->state, (void*)BACKEND); + OutputDebugStringA(dbg); + } +#endif + + /* Only cleanup if SSL was actually initialized on this connection */ + if(connssl->state == ssl_connection_none) + return; + + if(BACKEND) { + if(BACKEND->active) { + /* + * Attempt graceful TLS close only if the connection is still healthy. + * br_sslio_close() sends a close_notify alert, which calls sock_write(). + * If the socket is dead, sock_write() fails and BearSSL's I/O state + * becomes inconsistent, causing heap corruption. Guard against this by + * checking io_error (set by bearssl_send/recv on failure), the engine + * error code, and the engine closed flag. + */ + int err = br_ssl_engine_last_error(&BACKEND->sc.eng); + unsigned state = br_ssl_engine_current_state(&BACKEND->sc.eng); + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL close: io_error=%d, err=%d, state=0x%x\n", + BACKEND->io_error, err, state); + OutputDebugStringA(dbg); + } +#endif + + if(!BACKEND->io_error && err == BR_ERR_OK && !(state & BR_SSL_CLOSED)) { + br_sslio_close(&BACKEND->ioc); + } + BACKEND->active = 0; + } + /* + * NOTE: Do NOT free BACKEND! The vtls layer allocates all backend memory + * as a single block in url.c:allocate_conn(). Freeing BACKEND here would + * corrupt the heap because it's an offset into a larger allocation. + * + * Just clear the backend data to prepare for potential reuse. + */ +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL: Clearing backend at %p (NOT freeing - vtls manages memory)\n", + (void*)BACKEND); + OutputDebugStringA(dbg); + } +#endif + + /* Free per-connection file-loaded trust anchors before clearing */ +#if BEARSSL_XBOX_INTEGRATION + if(BACKEND->file_anchors) { + bearssl_xbox_free_loaded_anchors(BACKEND->file_anchors, + BACKEND->file_anchor_count); + } +#endif + + /* Clear backend data but do NOT free (vtls owns the memory) */ + memset(BACKEND, 0, sizeof(struct ssl_backend_data)); + } + + /* Reset state */ + connssl->state = ssl_connection_none; + connssl->connecting_state = ssl_connect_1; +} + +static void Curl_bearssl_close_all(struct Curl_easy *data) +{ + (void)data; +} + +static int Curl_bearssl_shutdown(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL shutdown: sockindex=%d, state=%d, backend=%p\n", + sockindex, (int)connssl->state, (void*)BACKEND); + OutputDebugStringA(dbg); + } +#endif + + /* Only shutdown if SSL was actually initialized */ + if(connssl->state == ssl_connection_none) + return 0; + + /* Check BACKEND exists before accessing it */ + if(!BACKEND) + return 0; + + if(BACKEND->active) { + /* + * Only attempt graceful TLS close if no I/O errors occurred. + * Avoid trying to send close_notify on a dead socket. + */ + int err = br_ssl_engine_last_error(&BACKEND->sc.eng); + unsigned state = br_ssl_engine_current_state(&BACKEND->sc.eng); + + if(!BACKEND->io_error && err == BR_ERR_OK && !(state & BR_SSL_CLOSED)) { + br_sslio_close(&BACKEND->ioc); + } + BACKEND->active = 0; + } + + return 0; +} + +static ssize_t bearssl_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + int ret; + int flush_ret; + + /* Defensive check - BACKEND must be valid */ + if(!BACKEND || !BACKEND->active) { + OutputDebugStringA("bearssl_send: BACKEND invalid, returning error\n"); + *curlcode = CURLE_SEND_ERROR; + return -1; + } + +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL send: len=%u, active=%d\n", + (unsigned)len, BACKEND->active); + OutputDebugStringA(dbg); + } +#endif + + ret = br_sslio_write(&BACKEND->ioc, mem, len); + +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[128]; + int err = br_ssl_engine_last_error(&BACKEND->sc.eng); + unsigned state = br_ssl_engine_current_state(&BACKEND->sc.eng); + msnprintf(dbg, sizeof(dbg), "BearSSL send: write returned %d, err=%d, state=0x%x\n", + ret, err, state); + OutputDebugStringA(dbg); + } +#endif + + if(ret < 0) { + int err = br_ssl_engine_last_error(&BACKEND->sc.eng); + /* Mark that we've had an I/O error - skip graceful close later */ + BACKEND->io_error = 1; + if(err == BR_ERR_OK || err == BR_ERR_IO) { + *curlcode = CURLE_AGAIN; + } + else { + *curlcode = CURLE_SEND_ERROR; + } + return -1; + } + + /* Flush the data to ensure it's sent immediately */ + flush_ret = br_sslio_flush(&BACKEND->ioc); + +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL send: flush returned %d\n", flush_ret); + OutputDebugStringA(dbg); + } +#endif + + if(flush_ret < 0) { + BACKEND->io_error = 1; + } + + return (ssize_t)ret; +} + +static ssize_t bearssl_recv(struct connectdata *conn, int sockindex, + char *buf, size_t buffersize, CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + int ret; + + /* Defensive check - BACKEND must be valid */ + if(!BACKEND || !BACKEND->active) { + OutputDebugStringA("bearssl_recv: BACKEND invalid, returning error\n"); + *curlcode = CURLE_RECV_ERROR; + return -1; + } + +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL recv: buffersize=%u, active=%d\n", + (unsigned)buffersize, BACKEND->active); + OutputDebugStringA(dbg); + } +#endif + + ret = br_sslio_read(&BACKEND->ioc, buf, buffersize); + +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[128]; + int err = br_ssl_engine_last_error(&BACKEND->sc.eng); + unsigned state = br_ssl_engine_current_state(&BACKEND->sc.eng); + msnprintf(dbg, sizeof(dbg), "BearSSL recv: read returned %d, err=%d, state=0x%x\n", + ret, err, state); + OutputDebugStringA(dbg); + } +#endif + + if(ret < 0) { + int err = br_ssl_engine_last_error(&BACKEND->sc.eng); + /* Mark that we've had an I/O error - skip graceful close later */ + BACKEND->io_error = 1; +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL recv: ERROR - setting io_error=1, err=%d\n", err); + OutputDebugStringA(dbg); + } +#endif + if(err == BR_ERR_OK || err == BR_ERR_IO) { + *curlcode = CURLE_AGAIN; + } + else { + *curlcode = CURLE_RECV_ERROR; + } + return -1; + } + + return (ssize_t)ret; +} + +static bool Curl_bearssl_data_pending(const struct connectdata *conn, + int sockindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + unsigned state; + + /* Check if SSL was initialized before accessing BACKEND */ + if(connssl->state == ssl_connection_none) + return FALSE; + + if(!BACKEND || !BACKEND->active) + return FALSE; + + state = br_ssl_engine_current_state(&BACKEND->sc.eng); + return (state & BR_SSL_RECVAPP) ? TRUE : FALSE; +} + +static int Curl_bearssl_check_cxn(struct connectdata *conn) +{ + struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; + int err; + + /* Check if SSL was initialized before accessing BACKEND */ + if(connssl->state == ssl_connection_none) + return 0; + + if(!BACKEND || !BACKEND->active) + return 0; + + err = br_ssl_engine_last_error(&BACKEND->sc.eng); + return (err == BR_ERR_OK) ? 1 : 0; +} + +static void *Curl_bearssl_get_internals(struct ssl_connect_data *connssl, + CURLINFO info) +{ + (void)info; + /* Check if SSL was initialized before accessing BACKEND */ + if(connssl->state == ssl_connection_none) + return NULL; + return BACKEND ? &BACKEND->sc : NULL; +} + +static void Curl_bearssl_session_free(void *ptr) +{ + (void)ptr; + /* BearSSL session handling is different; no dynamic session objects */ +} + +const struct Curl_ssl Curl_ssl_bearssl = { + { CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */ + SSLSUPP_CA_PATH | + SSLSUPP_SSL_CTX, /* supports */ + sizeof(struct ssl_backend_data), + + Curl_bearssl_init, /* init */ + Curl_bearssl_cleanup, /* cleanup */ + Curl_bearssl_version, /* version */ + Curl_bearssl_check_cxn, /* check_cxn */ + Curl_bearssl_shutdown, /* shutdown */ + Curl_bearssl_data_pending, /* data_pending */ + Curl_bearssl_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_bearssl_connect_blocking, /* connect_blocking */ + Curl_bearssl_connect_nonblocking, /* connect_nonblocking */ + Curl_bearssl_get_internals, /* get_internals */ + Curl_bearssl_close, /* close_one */ + Curl_bearssl_close_all, /* close_all */ + Curl_bearssl_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_none_md5sum, /* md5sum */ + NULL /* sha256sum */ +}; + +#endif /* USE_BEARSSL */ diff --git a/BearSSL-OG/bearssl_xbox.cpp b/BearSSL-OG/bearssl_xbox.cpp new file mode 100644 index 0000000..bd73a56 --- /dev/null +++ b/BearSSL-OG/bearssl_xbox.cpp @@ -0,0 +1,150 @@ +/* + * BearSSL Xbox Integration Implementation + * C-compatible wrappers for Xbox-specific SSL functionality + */ + +#include "bearssl_xbox.h" +#include "certificates.h" +#include "ca_loader.h" +#include "session_cache.h" +#include "ssl_errors.h" +#include "cert_pinning.h" + +extern "C" { + +/* + * Trust Anchor Management + */ +void bearssl_xbox_init_trust_anchors(void) +{ + certificates::initialize_trust_anchors(); +} + +void bearssl_xbox_cleanup_trust_anchors(void) +{ + certificates::close_trust_anchors(); +} + +br_x509_trust_anchor* bearssl_xbox_get_trust_anchors(void) +{ + return certificates::get_trust_anchors(); +} + +size_t bearssl_xbox_get_trust_anchor_count(void) +{ + return (size_t)certificates::get_num_trust_anchors(); +} + +/* + * Session Cache Management + */ +void bearssl_xbox_session_init(void) +{ + session_cache::initialize(); +} + +void bearssl_xbox_session_shutdown(void) +{ + session_cache::shutdown(); +} + +int bearssl_xbox_session_get(const char* hostname, br_ssl_session_parameters* params) +{ + return session_cache::get(hostname, params) ? 1 : 0; +} + +void bearssl_xbox_session_store(const char* hostname, const br_ssl_session_parameters* params) +{ + session_cache::store(hostname, params); +} + +void bearssl_xbox_session_remove(const char* hostname) +{ + session_cache::remove(hostname); +} + +void bearssl_xbox_session_clear(void) +{ + session_cache::clear(); +} + +/* + * Error Message Utilities + */ +const char* bearssl_xbox_error_string(int error) +{ + return ssl_errors::error_to_string(error); +} + +const char* bearssl_xbox_alert_string(int alert_code) +{ + return ssl_errors::alert_to_string(alert_code); +} + +/* + * CA Loader + */ +int bearssl_xbox_load_ca_file(const char *path, + br_x509_trust_anchor **anchors_out, size_t *count_out) +{ + return ca_loader::load_pem_file(path, anchors_out, count_out); +} + +void bearssl_xbox_free_loaded_anchors(br_x509_trust_anchor *anchors, + size_t count) +{ + ca_loader::free_trust_anchors(anchors, count); +} + +int bearssl_xbox_update_trust_store(void) +{ + return ca_loader::update_trust_store( + BEARSSL_XBOX_DEFAULT_CA_FILE, + certificates::get_trust_anchors(), + (size_t)certificates::get_num_trust_anchors()); +} + +/* + * Certificate Pinning + */ +void bearssl_xbox_pin_init(void) +{ + cert_pinning::initialize(); +} + +void bearssl_xbox_pin_shutdown(void) +{ + cert_pinning::shutdown(); +} + +int bearssl_xbox_pin_add(const char* hostname, const unsigned char* sha256_hash) +{ + return cert_pinning::add_pin(hostname, sha256_hash) ? 1 : 0; +} + +void bearssl_xbox_pin_remove(const char* hostname) +{ + cert_pinning::remove_pin(hostname); +} + +void bearssl_xbox_pin_clear(void) +{ + cert_pinning::clear(); +} + +int bearssl_xbox_pin_has(const char* hostname) +{ + return cert_pinning::has_pin(hostname) ? 1 : 0; +} + +int bearssl_xbox_pin_verify_hash(const char* hostname, const unsigned char* cert_sha256) +{ + return cert_pinning::verify_hash(hostname, cert_sha256) ? 1 : 0; +} + +int bearssl_xbox_pin_get_hash(const char* hostname, unsigned char* hash_out) +{ + return cert_pinning::get_pin_hash(hostname, hash_out) ? 1 : 0; +} + +} /* extern "C" */ diff --git a/BearSSL-OG/bearssl_xbox.h b/BearSSL-OG/bearssl_xbox.h new file mode 100644 index 0000000..6b86866 --- /dev/null +++ b/BearSSL-OG/bearssl_xbox.h @@ -0,0 +1,85 @@ +/* + * BearSSL Xbox Integration Header + * C-compatible wrappers for Xbox-specific SSL functionality + * + * This provides a C interface to the C++ classes for use by libcurl's bearssl.c + */ + +#ifndef BEARSSL_XBOX_H +#define BEARSSL_XBOX_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Default CA bundle path on Xbox HDD. + * T:\ maps to E:\TDATA\\ (title-persistent storage). + * Drop cacert.pem there to use updated root CAs without recompiling. + */ +#define BEARSSL_XBOX_DEFAULT_CA_FILE "T:\\cacert.pem" + +/* + * Trust Anchor Management + * Wraps certificates.cpp functionality + */ +void bearssl_xbox_init_trust_anchors(void); +void bearssl_xbox_cleanup_trust_anchors(void); +br_x509_trust_anchor* bearssl_xbox_get_trust_anchors(void); +size_t bearssl_xbox_get_trust_anchor_count(void); + +/* + * Session Cache Management + * Wraps session_cache.cpp functionality + */ +void bearssl_xbox_session_init(void); +void bearssl_xbox_session_shutdown(void); +int bearssl_xbox_session_get(const char* hostname, br_ssl_session_parameters* params); +void bearssl_xbox_session_store(const char* hostname, const br_ssl_session_parameters* params); +void bearssl_xbox_session_remove(const char* hostname); +void bearssl_xbox_session_clear(void); + +/* + * Error Message Utilities + * Wraps ssl_errors.cpp functionality + */ +const char* bearssl_xbox_error_string(int error); +const char* bearssl_xbox_alert_string(int alert_code); + +/* + * CA Loader - Runtime PEM certificate loading + * Wraps ca_loader.cpp functionality + */ +int bearssl_xbox_load_ca_file(const char *path, + br_x509_trust_anchor **anchors_out, size_t *count_out); +void bearssl_xbox_free_loaded_anchors(br_x509_trust_anchor *anchors, + size_t count); + +/* + * CA Auto-Update + * Downloads cacert.pem from curl.se if not already present on disk. + * Uses the compiled-in trust anchors (must be initialized first). + * Returns 0 on success (file existed or was downloaded), -1 on failure. + */ +int bearssl_xbox_update_trust_store(void); + +/* + * Certificate Pinning + * Wraps cert_pinning.cpp functionality + */ +void bearssl_xbox_pin_init(void); +void bearssl_xbox_pin_shutdown(void); +int bearssl_xbox_pin_add(const char* hostname, const unsigned char* sha256_hash); +void bearssl_xbox_pin_remove(const char* hostname); +void bearssl_xbox_pin_clear(void); +int bearssl_xbox_pin_has(const char* hostname); +int bearssl_xbox_pin_verify_hash(const char* hostname, const unsigned char* cert_sha256); +int bearssl_xbox_pin_get_hash(const char* hostname, unsigned char* hash_out); + +#ifdef __cplusplus +} +#endif + +#endif /* BEARSSL_XBOX_H */ diff --git a/BearSSL-OG/ca_loader.cpp b/BearSSL-OG/ca_loader.cpp new file mode 100644 index 0000000..457154a --- /dev/null +++ b/BearSSL-OG/ca_loader.cpp @@ -0,0 +1,861 @@ +#include "ca_loader.h" +#include "debug_utility.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DOWNLOAD_BUF_SIZE 8192 +#define CA_DNS_TIMEOUT_MS 30000 + +/* ------------------------------------------------------------------ */ +/* Inline socket/network helpers (avoids dependency on BearSSL-OG */ +/* socket_utility / network_utility which aren't in libbearssl) */ +/* ------------------------------------------------------------------ */ + +/* DNS resolution via Xbox XNet async API */ +static uint32_t ca_resolve_host(const char *host) +{ + XNDNS *dns = NULL; + WSAEVENT event_handle; + uint32_t result = 0; + + if (host == NULL || host[0] == '\0') + { + return 0; + } + + event_handle = WSACreateEvent(); + if (event_handle == NULL) + { + return 0; + } + + if (XNetDnsLookup(host, event_handle, &dns) != 0) + { + WSACloseEvent(event_handle); + return 0; + } + + if (WaitForSingleObject(event_handle, CA_DNS_TIMEOUT_MS) == WAIT_TIMEOUT) + { + WSACloseEvent(event_handle); + XNetDnsRelease(dns); + return 0; + } + + WSACloseEvent(event_handle); + + if (dns->iStatus == 0 && dns->cina > 0) + { + result = dns->aina[0].S_un.S_addr; + } + + XNetDnsRelease(dns); + return result; +} + +/* TCP connect to host:port, returns socket or INVALID_SOCKET. + * IMPORTANT: Xbox SOCKET handles are kernel pointers (e.g. 0xD001A828) + * which are negative as signed int -- never check < 0, always use + * INVALID_SOCKET. */ +static SOCKET ca_connect(uint32_t host_ip, uint16_t port) +{ + sockaddr_in addr; + SOCKET sock; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.S_un.S_addr = host_ip; + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == INVALID_SOCKET) + { + return INVALID_SOCKET; + } + + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) + { + closesocket(sock); + return INVALID_SOCKET; + } + + return sock; +} + +/* BearSSL I/O callback: read from socket with 2-second select timeout */ +static int ca_sock_read(void *ctx, unsigned char *buf, size_t len) +{ + SOCKET sock = *(SOCKET *)ctx; + fd_set fds; + struct timeval tv; + int n; + + while (1) + { + FD_ZERO(&fds); + FD_SET(sock, &fds); + tv.tv_sec = 2; + tv.tv_usec = 0; + + if (select(0, &fds, NULL, NULL, &tv) == 0) + { + return -1; /* timeout */ + } + + n = recv(sock, (char *)buf, (len > 0x7FFFFFFF) ? 0x7FFFFFFF : (int)len, 0); + if (n == SOCKET_ERROR) + { + if (WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEWOULDBLOCK) + { + continue; + } + return -1; + } + return n; /* 0 = peer closed, >0 = bytes read */ + } +} + +/* BearSSL I/O callback: write to socket */ +static int ca_sock_write(void *ctx, const unsigned char *buf, size_t len) +{ + SOCKET sock = *(SOCKET *)ctx; + int n; + + while (1) + { + n = send(sock, (const char *)buf, + (len > 0x7FFFFFFF) ? 0x7FFFFFFF : (int)len, 0); + if (n == SOCKET_ERROR) + { + if (WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEWOULDBLOCK) + { + continue; + } + return -1; + } + return n; + } +} + +/* Dynamic byte buffer used for accumulating DER and DN data */ +struct byte_buffer +{ + unsigned char *data; + size_t len; + size_t cap; + int error; /* set to 1 if any append failed (OOM) */ +}; + +static void byte_buffer_init(byte_buffer *bb) +{ + bb->data = NULL; + bb->len = 0; + bb->cap = 0; + bb->error = 0; +} + +static void byte_buffer_reset(byte_buffer *bb) +{ + bb->len = 0; + bb->error = 0; +} + +static void byte_buffer_free(byte_buffer *bb) +{ + free(bb->data); + bb->data = NULL; + bb->len = 0; + bb->cap = 0; + bb->error = 0; +} + +static int byte_buffer_append(byte_buffer *bb, const void *src, size_t len) +{ + if (len == 0) + { + return 0; + } + if (bb->len + len > bb->cap) + { + size_t new_cap = (bb->cap == 0) ? 4096 : bb->cap * 2; + while (new_cap < bb->len + len) + { + if (new_cap > ((size_t)-1) / 2) + { + return -1; + } + new_cap *= 2; + } + unsigned char *new_data = (unsigned char *)realloc(bb->data, new_cap); + if (new_data == NULL) + { + return -1; + } + bb->data = new_data; + bb->cap = new_cap; + } + memcpy(bb->data + bb->len, src, len); + bb->len += len; + return 0; +} + +/* PEM decoder callback: accumulates decoded DER bytes */ +static void pem_dest_callback(void *dest_ctx, const void *src, size_t len) +{ + byte_buffer *bb = (byte_buffer *)dest_ctx; + if (byte_buffer_append(bb, src, len) != 0) + { + bb->error = 1; + } +} + +/* X.509 decoder callback: accumulates subject DN bytes */ +static void dn_append_callback(void *ctx, const void *buf, size_t len) +{ + byte_buffer *bb = (byte_buffer *)ctx; + if (byte_buffer_append(bb, buf, len) != 0) + { + bb->error = 1; + } +} + +/* + * Deep-copy a decoded certificate into a new trust anchor entry. + * Returns 0 on success, -1 on allocation failure. + */ +static int add_trust_anchor( + br_x509_trust_anchor **anchors, size_t *count, size_t *cap, + byte_buffer *dn, br_x509_decoder_context *dc) +{ + br_x509_pkey *pk = br_x509_decoder_get_pkey(dc); + if (pk == NULL) + { + return -1; + } + + /* Grow anchor array if needed */ + if (*count >= *cap) + { + size_t new_cap = (*cap == 0) ? 32 : *cap * 2; + br_x509_trust_anchor *new_arr = (br_x509_trust_anchor *)realloc( + *anchors, new_cap * sizeof(br_x509_trust_anchor)); + if (new_arr == NULL) + { + return -1; + } + *anchors = new_arr; + *cap = new_cap; + } + + br_x509_trust_anchor *ta = &(*anchors)[*count]; + memset(ta, 0, sizeof(*ta)); + + /* Deep-copy DN */ + ta->dn.data = (unsigned char *)malloc(dn->len); + if (ta->dn.data == NULL) + { + return -1; + } + memcpy(ta->dn.data, dn->data, dn->len); + ta->dn.len = dn->len; + + /* Set CA flag */ + ta->flags = br_x509_decoder_isCA(dc) ? BR_X509_TA_CA : 0; + + /* Deep-copy public key */ + ta->pkey.key_type = pk->key_type; + if (pk->key_type == BR_KEYTYPE_RSA) + { + ta->pkey.key.rsa.n = (unsigned char *)malloc(pk->key.rsa.nlen); + ta->pkey.key.rsa.e = (unsigned char *)malloc(pk->key.rsa.elen); + if (ta->pkey.key.rsa.n == NULL || ta->pkey.key.rsa.e == NULL) + { + free(ta->pkey.key.rsa.n); + free(ta->pkey.key.rsa.e); + free(ta->dn.data); + return -1; + } + memcpy(ta->pkey.key.rsa.n, pk->key.rsa.n, pk->key.rsa.nlen); + ta->pkey.key.rsa.nlen = pk->key.rsa.nlen; + memcpy(ta->pkey.key.rsa.e, pk->key.rsa.e, pk->key.rsa.elen); + ta->pkey.key.rsa.elen = pk->key.rsa.elen; + } + else if (pk->key_type == BR_KEYTYPE_EC) + { + ta->pkey.key.ec.q = (unsigned char *)malloc(pk->key.ec.qlen); + if (ta->pkey.key.ec.q == NULL) + { + free(ta->dn.data); + memset(ta, 0, sizeof(*ta)); + return -1; + } + memcpy(ta->pkey.key.ec.q, pk->key.ec.q, pk->key.ec.qlen); + ta->pkey.key.ec.qlen = pk->key.ec.qlen; + ta->pkey.key.ec.curve = pk->key.ec.curve; + } + else + { + /* Unknown key type */ + free(ta->dn.data); + memset(ta, 0, sizeof(*ta)); + return -1; + } + + (*count)++; + return 0; +} + +int ca_loader::load_pem_file(const char *path, + br_x509_trust_anchor **anchors_out, size_t *count_out) +{ + *anchors_out = NULL; + *count_out = 0; + + /* Read entire PEM file into memory */ + FILE *f = fopen(path, "rb"); + if (f == NULL) + { + debug_utility::debug_print("ca_loader: cannot open %s\n", path); + return -1; + } + + fseek(f, 0, SEEK_END); + long file_size = ftell(f); + fseek(f, 0, SEEK_SET); + + if (file_size <= 0 || file_size > 2 * 1024 * 1024) + { + debug_utility::debug_print("ca_loader: file too large or empty (%ld bytes)\n", file_size); + fclose(f); + return -1; + } + + unsigned char *file_data = (unsigned char *)malloc((size_t)file_size); + if (file_data == NULL) + { + debug_utility::debug_print("ca_loader: malloc failed for file data\n"); + fclose(f); + return -1; + } + + size_t bytes_read = fread(file_data, 1, (size_t)file_size, f); + fclose(f); + + if (bytes_read != (size_t)file_size) + { + debug_utility::debug_print("ca_loader: short read (%u of %ld)\n", + (unsigned)bytes_read, file_size); + free(file_data); + return -1; + } + + /* Parse PEM, collecting DER blobs for each CERTIFICATE */ + br_pem_decoder_context pem; + br_pem_decoder_init(&pem); + + br_x509_trust_anchor *anchors = NULL; + size_t anchor_count = 0; + size_t anchor_cap = 0; + + byte_buffer der_buf; + byte_buffer_init(&der_buf); + + byte_buffer dn_buf; + byte_buffer_init(&dn_buf); + + int in_cert = 0; + int certs_parsed = 0; + int certs_failed = 0; + + const unsigned char *pos = file_data; + size_t remaining = bytes_read; + + while (remaining > 0) + { + size_t consumed = br_pem_decoder_push(&pem, pos, remaining); + pos += consumed; + remaining -= consumed; + + int event = br_pem_decoder_event(&pem); + switch (event) + { + case BR_PEM_BEGIN_OBJ: + if (strcmp(br_pem_decoder_name(&pem), "CERTIFICATE") == 0) + { + in_cert = 1; + byte_buffer_reset(&der_buf); + br_pem_decoder_setdest(&pem, pem_dest_callback, &der_buf); + } + else + { + /* Skip non-certificate objects (private keys, etc.) */ + in_cert = 0; + br_pem_decoder_setdest(&pem, NULL, NULL); + } + break; + + case BR_PEM_END_OBJ: + if (in_cert && der_buf.len > 0 && !der_buf.error) + { + /* Decode the DER certificate */ + br_x509_decoder_context dc; + byte_buffer_reset(&dn_buf); + br_x509_decoder_init(&dc, dn_append_callback, &dn_buf); + br_x509_decoder_push(&dc, der_buf.data, der_buf.len); + + int err = br_x509_decoder_last_error(&dc); + if (err == 0 && !dn_buf.error) + { + if (add_trust_anchor(&anchors, &anchor_count, &anchor_cap, + &dn_buf, &dc) == 0) + { + certs_parsed++; + } + else + { + certs_failed++; + } + } + else + { + certs_failed++; + } + } + else if (in_cert && (der_buf.error || dn_buf.error)) + { + certs_failed++; + } + in_cert = 0; + break; + + case BR_PEM_ERROR: + in_cert = 0; + break; + + case 0: + /* No event yet, decoder needs more data but push returned 0. + * This shouldn't happen with complete files, but guard against + * infinite loop by breaking if no progress was made. */ + if (consumed == 0) + { + remaining = 0; + } + break; + } + } + + byte_buffer_free(&der_buf); + byte_buffer_free(&dn_buf); + free(file_data); + + debug_utility::debug_print("ca_loader: loaded %d trust anchors from %s (%d failed)\n", + certs_parsed, path, certs_failed); + + if (anchor_count == 0) + { + free(anchors); + return -1; + } + + *anchors_out = anchors; + *count_out = anchor_count; + return 0; +} + +void ca_loader::free_trust_anchors(br_x509_trust_anchor *anchors, size_t count) +{ + size_t i; + + if (anchors == NULL) + { + return; + } + + for (i = 0; i < count; i++) + { + free(anchors[i].dn.data); + if (anchors[i].pkey.key_type == BR_KEYTYPE_RSA) + { + free(anchors[i].pkey.key.rsa.n); + free(anchors[i].pkey.key.rsa.e); + } + else if (anchors[i].pkey.key_type == BR_KEYTYPE_EC) + { + free(anchors[i].pkey.key.ec.q); + } + } + free(anchors); +} + +/* ------------------------------------------------------------------ */ +/* Auto-update: download CA bundle from curl.se over HTTPS */ +/* ------------------------------------------------------------------ */ + +/* Time check callback: always returns 0 (valid). + * This lets the compiled-in CAs work even if the Xbox clock is wrong. */ +static int download_time_check(void *tctx, + uint32_t not_before_days, uint32_t not_before_seconds, + uint32_t not_after_days, uint32_t not_after_seconds) +{ + (void)tctx; + (void)not_before_days; + (void)not_before_seconds; + (void)not_after_days; + (void)not_after_seconds; + return 0; +} + +/* Find \r\n in a buffer, return offset or -1 */ +static int find_line_end(const unsigned char *buf, size_t len) +{ + size_t i; + if (len < 2) return -1; + for (i = 0; i < len - 1; i++) + { + if (buf[i] == '\r' && buf[i + 1] == '\n') + { + return (int)i; + } + } + return -1; +} + +/* Case-insensitive prefix match */ +static int prefix_icmp(const char *str, const char *prefix) +{ + while (*prefix) + { + char a = *str; + char b = *prefix; + if (a >= 'A' && a <= 'Z') a += 32; + if (b >= 'A' && b <= 'Z') b += 32; + if (a != b) return 0; + str++; + prefix++; + } + return 1; +} + +int ca_loader::download_https(const char *host, const char *path, + uint16_t port, const char *save_path, + br_x509_trust_anchor *anchors, size_t anchor_count, + int max_redirects) +{ + int result = -1; + + /* DNS resolve */ + uint32_t host_ip = ca_resolve_host(host); + if (host_ip == 0) + { + debug_utility::debug_print("ca_loader: DNS failed for %s\n", host); + return -1; + } + + /* TCP connect */ + SOCKET sock = ca_connect(host_ip, port); + if (sock == INVALID_SOCKET) + { + debug_utility::debug_print("ca_loader: connect failed to %s:%u\n", + host, (unsigned)port); + return -1; + } + + /* Allocate BearSSL I/O buffer on the heap (too large for Xbox stack) */ + unsigned char *iobuf = (unsigned char *)malloc(BR_SSL_BUFSIZE_BIDI); + if (iobuf == NULL) + { + closesocket(sock); + return -1; + } + + /* Set up BearSSL with compiled-in CAs + time check bypass */ + br_ssl_client_context sc; + br_x509_minimal_context xc; + br_ssl_client_init_full(&sc, &xc, anchors, anchor_count); + br_x509_minimal_set_time_callback(&xc, NULL, download_time_check); + br_ssl_engine_set_buffer(&sc.eng, iobuf, BR_SSL_BUFSIZE_BIDI, 1); + br_ssl_client_reset(&sc, host, 0); + + br_sslio_context ioc; + br_sslio_init(&ioc, &sc.eng, + ca_sock_read, &sock, + ca_sock_write, &sock); + + /* Send HTTP GET */ + char request[512]; + _snprintf(request, sizeof(request) - 1, + "GET %s HTTP/1.1\r\n" + "Host: %s\r\n" + "Accept-Encoding: identity\r\n" + "Connection: close\r\n" + "\r\n", + path, host); + request[sizeof(request) - 1] = '\0'; + + br_sslio_write_all(&ioc, request, strlen(request)); + br_sslio_flush(&ioc); + + /* Read response into accumulation buffer */ + unsigned char *readbuf = (unsigned char *)malloc(DOWNLOAD_BUF_SIZE); + if (readbuf == NULL) + { + free(iobuf); + closesocket(sock); + return -1; + } + + /* Accumulate headers */ + byte_buffer hdr; + byte_buffer_init(&hdr); + + int status_code = 0; + int64_t content_length = -1; + char redirect_host[256]; + char redirect_path[512]; + int has_redirect = 0; + int headers_done = 0; + + redirect_host[0] = '\0'; + redirect_path[0] = '\0'; + + while (!headers_done) + { + int n = br_sslio_read(&ioc, readbuf, DOWNLOAD_BUF_SIZE); + if (n < 0) break; + byte_buffer_append(&hdr, readbuf, (size_t)n); + + /* Parse complete lines from the accumulated buffer */ + while (hdr.len > 0) + { + int crlf = find_line_end(hdr.data, hdr.len); + if (crlf < 0) break; + + /* Null-terminate the line for string operations */ + char *line = (char *)malloc((size_t)crlf + 1); + if (line == NULL) break; + memcpy(line, hdr.data, (size_t)crlf); + line[crlf] = '\0'; + + /* Remove the line + CRLF from the buffer */ + { + size_t remove_len = (size_t)crlf + 2; + if (remove_len < hdr.len) + { + memmove(hdr.data, hdr.data + remove_len, + hdr.len - remove_len); + } + hdr.len -= remove_len; + } + + /* Empty line = end of headers */ + if (line[0] == '\0') + { + free(line); + headers_done = 1; + break; + } + + /* Parse status line: "HTTP/1.x 200 OK" */ + if (status_code == 0 && strncmp(line, "HTTP/", 5) == 0) + { + char *sp = strchr(line, ' '); + if (sp) status_code = atoi(sp + 1); + } + + /* Parse Content-Length (cap at 10MB - CA bundles are ~250KB) */ + if (prefix_icmp(line, "content-length:")) + { + const char *val = line + 15; + while (*val == ' ') val++; + content_length = 0; + while (*val >= '0' && *val <= '9') + { + content_length = content_length * 10 + (*val - '0'); + if (content_length > 10 * 1024 * 1024) + { + content_length = -1; + break; + } + val++; + } + } + + /* Parse Location for redirects */ + if (prefix_icmp(line, "location:")) + { + const char *url = line + 9; + while (*url == ' ') url++; + + /* Parse "https://host/path" */ + if (strncmp(url, "https://", 8) == 0) + { + const char *hstart = url + 8; + const char *slash = strchr(hstart, '/'); + if (slash) + { + size_t hlen = (size_t)(slash - hstart); + if (hlen < sizeof(redirect_host)) + { + memcpy(redirect_host, hstart, hlen); + redirect_host[hlen] = '\0'; + _snprintf(redirect_path, + sizeof(redirect_path) - 1, "%s", slash); + redirect_path[sizeof(redirect_path) - 1] = '\0'; + has_redirect = 1; + } + } + } + } + + free(line); + } + } + + /* Handle redirect */ + if ((status_code == 301 || status_code == 302 || status_code == 307) + && has_redirect && max_redirects > 0) + { + debug_utility::debug_print("ca_loader: redirect %d -> %s%s\n", + status_code, redirect_host, redirect_path); + + byte_buffer_free(&hdr); + free(readbuf); + free(iobuf); + closesocket(sock); + + return download_https(redirect_host, redirect_path, port, + save_path, anchors, anchor_count, max_redirects - 1); + } + + if (status_code != 200) + { + debug_utility::debug_print("ca_loader: HTTP %d from %s%s\n", + status_code, host, path); + byte_buffer_free(&hdr); + free(readbuf); + free(iobuf); + closesocket(sock); + return -1; + } + + /* Write body to a temp file, then rename on success */ + char temp_path[280]; + _snprintf(temp_path, sizeof(temp_path) - 1, "%s.tmp", save_path); + temp_path[sizeof(temp_path) - 1] = '\0'; + + FILE *fp = fopen(temp_path, "wb"); + if (fp == NULL) + { + debug_utility::debug_print("ca_loader: cannot create %s (err=%lu)\n", + temp_path, GetLastError()); + byte_buffer_free(&hdr); + free(readbuf); + free(iobuf); + closesocket(sock); + return -1; + } + + /* Write any leftover data that was read past the headers */ + int64_t total_written = 0; + int write_error = 0; + if (hdr.len > 0) + { + if (fwrite(hdr.data, 1, hdr.len, fp) != hdr.len) + { + write_error = 1; + } + total_written += (int64_t)hdr.len; + } + byte_buffer_free(&hdr); + + /* Stream the rest of the body to disk */ + while (!write_error) + { + int n = br_sslio_read(&ioc, readbuf, DOWNLOAD_BUF_SIZE); + if (n < 0) break; + if (fwrite(readbuf, 1, (size_t)n, fp) != (size_t)n) + { + write_error = 1; + break; + } + total_written += (int64_t)n; + + if (content_length > 0 && total_written >= content_length) + { + break; + } + } + + fclose(fp); + free(readbuf); + free(iobuf); + closesocket(sock); + + /* Check for disk write errors */ + if (write_error) + { + debug_utility::debug_print("ca_loader: write error saving to %s\n", + temp_path); + remove(temp_path); + return -1; + } + + /* Sanity check: CA bundles are typically 200-300 KB */ + if (total_written < 1024) + { + debug_utility::debug_print("ca_loader: download too small (%I64d bytes)\n", + total_written); + remove(temp_path); + return -1; + } + + /* Atomic-ish replace: delete old, rename temp */ + remove(save_path); + if (rename(temp_path, save_path) != 0) + { + debug_utility::debug_print("ca_loader: rename %s -> %s failed\n", + temp_path, save_path); + remove(temp_path); + return -1; + } + + debug_utility::debug_print("ca_loader: downloaded %I64d bytes to %s\n", + total_written, save_path); + result = 0; + return result; +} + +int ca_loader::update_trust_store(const char *save_path, + br_x509_trust_anchor *anchors, size_t anchor_count) +{ + /* If the CA file already exists on disk, nothing to do */ + FILE *f = fopen(save_path, "rb"); + if (f != NULL) + { + fclose(f); + debug_utility::debug_print("ca_loader: %s already exists, skipping download\n", + save_path); + return 0; + } + + if (anchors == NULL || anchor_count == 0) + { + debug_utility::debug_print("ca_loader: no trust anchors for download\n"); + return -1; + } + + debug_utility::debug_print("ca_loader: downloading CA bundle from %s...\n", + CA_BUNDLE_HOST); + + return download_https(CA_BUNDLE_HOST, CA_BUNDLE_PATH, CA_BUNDLE_PORT, + save_path, anchors, anchor_count, 3); +} diff --git a/BearSSL-OG/ca_loader.h b/BearSSL-OG/ca_loader.h new file mode 100644 index 0000000..6ed4416 --- /dev/null +++ b/BearSSL-OG/ca_loader.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include +#include + +/* + * Runtime CA certificate loader. + * + * Parses PEM-encoded CA bundle files (e.g. cacert.pem from curl.se) + * into br_x509_trust_anchor arrays that BearSSL can use for certificate + * verification. + * + * Also provides auto-update: downloads a fresh CA bundle over HTTPS + * using the compiled-in trust anchors (with time validation bypassed) + * and saves it to title-persistent storage on the Xbox HDD. + */ + +/* Where to download the CA bundle from */ +#define CA_BUNDLE_HOST "curl.se" +#define CA_BUNDLE_PATH "/ca/cacert.pem" +#define CA_BUNDLE_PORT 443 + +class ca_loader +{ +public: + /* + * Load trust anchors from a PEM CA bundle file. + * Returns 0 on success, -1 on failure. + */ + static int load_pem_file(const char *path, + br_x509_trust_anchor **anchors_out, size_t *count_out); + + /* + * Free trust anchors that were loaded from a PEM file. + * Deep-frees DN data and key data, then frees the array. + */ + static void free_trust_anchors(br_x509_trust_anchor *anchors, + size_t count); + + /* + * Auto-update the trust store. + * + * If save_path does not exist, downloads a fresh CA bundle from + * curl.se over HTTPS (using the provided trust anchors with time + * validation disabled) and saves it to save_path. + * + * Returns 0 on success (file already existed or was downloaded). + * Returns -1 on failure (download failed, file I/O error, etc.). + */ + static int update_trust_store(const char *save_path, + br_x509_trust_anchor *anchors, size_t anchor_count); + +private: + /* + * Download an HTTPS resource and save to a file. + * Uses BearSSL with the given trust anchors (time check disabled). + * Follows up to max_redirects HTTP 301/302 redirects. + * Returns 0 on success, -1 on failure. + */ + static int download_https(const char *host, const char *path, + uint16_t port, const char *save_path, + br_x509_trust_anchor *anchors, size_t anchor_count, + int max_redirects); +}; diff --git a/BearSSL-OG/cert-ee-ec+rsa.pem b/BearSSL-OG/cert-ee-ec+rsa.pem new file mode 100644 index 0000000..07f5457 --- /dev/null +++ b/BearSSL-OG/cert-ee-ec+rsa.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICcTCCAVmgAwIBAgIUbmO7Sc5BfgOM9Ubyiq5hCDWwlLMwDQYJKoZIhvcNAQELBQAwJzELMAkG +A1UEBhMCQ0ExGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAeFw0xMDAxMDEwMDAwMDBaFw0zNzEy +MzEyMzU5NTlaMCExCzAJBgNVBAYTAkNBMRIwEAYDVQQDEwlsb2NhbGhvc3QwWTATBgcqhkjOPQIB +BggqhkjOPQMBBwNCAARfOJ2n/02Kr/Y0OUYa/Drf9COqqer7xQjeAI6+eaU3WExt3QHKq0ffibbH +Fx84/B0gFN1FwOCPk044C/zpmaFJo2YwZDAfBgNVHSMEGDAWgBR8z6PGKffzxaoZ0MAW6+BAD85E +pzAdBgNVHQ4EFgQUww6GqnW0FcDllQkyvl6SdankRJswDAYDVR0TAQH/BAIwADAUBgNVHREEDTAL +gglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAI6JY6ebqBCOnhjQpHrdLIIWjwsO1cpXu19v +/FcowCG6rZSoF0JF1zH3hFcZRiQ8x0k4P0h6CRrrUbrFdY5MsiWwxyI+5+VG27E2/BuFUbDtgxbw +OnnaXShq7mogTLBwXrDtem0tGsm0ccLEox0lhjBUsZgmwVHg+DGtZ0id5qFSOyBHyXDagLWk9D9y +azcwVzksRptE8dlOu6Zf45rFf2y2Zcu/QHKS0Gj2rnl+JMFbaDAoU3FhevQ2ezvCtuwf3DBABA3q +swrPddO9nqtxcWh/pUFSAOmzruQe8btpxjvV3tLCJWkIPDfM94Jq5ah7agLavaQBMzPz3kYA7HXP +4H0= +-----END CERTIFICATE----- diff --git a/BearSSL-OG/cert-ee-ec.pem b/BearSSL-OG/cert-ee-ec.pem new file mode 100644 index 0000000..ff8ddbc --- /dev/null +++ b/BearSSL-OG/cert-ee-ec.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBsDCCAVagAwIBAgIUHE0AkWniRqyQfGRcU/H/t8HLbnowCgYIKoZIzj0EAwIwJzELMAkGA1UE +BhMCQ0ExGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAeFw0xMDAxMDEwMDAwMDBaFw0zNzEyMzEy +MzU5NTlaMCExCzAJBgNVBAYTAkNBMRIwEAYDVQQDEwlsb2NhbGhvc3QwWTATBgcqhkjOPQIBBggq +hkjOPQMBBwNCAARfOJ2n/02Kr/Y0OUYa/Drf9COqqer7xQjeAI6+eaU3WExt3QHKq0ffibbHFx84 +/B0gFN1FwOCPk044C/zpmaFJo2YwZDAfBgNVHSMEGDAWgBTw0PEi+XpIFwZ7Pb249c1VnFw+cDAd +BgNVHQ4EFgQUww6GqnW0FcDllQkyvl6SdankRJswDAYDVR0TAQH/BAIwADAUBgNVHREEDTALggls +b2NhbGhvc3QwCgYIKoZIzj0EAwIDSAAwRQIhAJH79ATQ5S4B1IzwF2IP3MyAyhjEQHwnA8s0Aw2b +yFlNAiAFVWni2KFAMzQOfkkyZB0/ax/QLbcvUgRWr9M3j4eZog== +-----END CERTIFICATE----- diff --git a/BearSSL-OG/cert-ee-rsa.pem b/BearSSL-OG/cert-ee-rsa.pem new file mode 100644 index 0000000..ef33e40 --- /dev/null +++ b/BearSSL-OG/cert-ee-rsa.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIIDPDCCAiSgAwIBAgIUWNq6Ns3toNpcEDNzjgxkknmSrwMwDQYJKoZIhvcNAQELBQAwJzELMAkG +A1UEBhMCQ0ExGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAeFw0xMDAxMDEwMDAwMDBaFw0zNzEy +MzEyMzU5NTlaMCExCzAJBgNVBAYTAkNBMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDUeh0nuis6Z7KRavvng0TK7Rx1rd1Ng2LWqmiVsiQhexWuKplo +Fe1m8LhY59P1LsbZKl7nDi7n/GdZwMhhfUukb92f2ciFh2THuhoPKdSWqHiaa2IgqTLQ7qmMKGFH +olAqY/Yh3trY1fB/xQCCcOajv1yJJ09RkncDw7DMLjvsI/IvU0GviZP/0oCxQ5fe1hmgkhJ6PWZ5 +4cG84Xdwoos9RoRTP+ROQkE3kh4f/Tiz9++HOYDTVs/04BPeZLBypAOExEHtb/o+4soEINLX3CyC +K3ribaEcSNvPiU80lz0oqFPa58HhcxWjMHZ/jyNCFD1RNNJarTyby8j+f26OQPO9AgMBAAGjZjBk +MB8GA1UdIwQYMBaAFMUBrXzmY8mcF1/FoqfhUF/o9ajGMB0GA1UdDgQWBBTFAa185mPJnBdfxaKn +4VBf6PWoxjAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsF +AAOCAQEAcbNdIcIO19DG+Epzh00iAifQx/j9Gm1iWIIIdiAHwEiS8+mYWusNTlaVY2hNq9QAduA3 +zwsRYVlc3valFFnZJZ9Z2dNehqwdpiwyQhkyE0ALVM1nJra9tJakyh9/N9aodes6gVEwuflKAW/R +1u1P3z8wYAZnko5hhV8atYyzD2Gp+t9dxGQA6oexM199y6OFJG4sZTvqcz+G0/3o5ALGYWomF1IB +JVx/qM5pH6xhLLcEr/2kepnLJhVM/3TUcwxXDCbr1yrcXMNBu8Lzzha9jnv76d+rIQ2Rs43Yz8j0 +SbnQ4xZwP7Pe1Acl+kZEUolNicjiyrUzf8chvSjv/mZ0Aw== +-----END CERTIFICATE----- diff --git a/BearSSL-OG/cert-ica-ec.pem b/BearSSL-OG/cert-ica-ec.pem new file mode 100644 index 0000000..204ab76 --- /dev/null +++ b/BearSSL-OG/cert-ica-ec.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBqTCCAU6gAwIBAgIUINPr4oz+2uajLF478mY6KzZ7sMowCgYIKoZIzj0EAwIwHDELMAkGA1UE +BhMCQ0ExDTALBgNVBAMTBFJvb3QwHhcNMTAwMTAxMDAwMDAwWhcNMzcxMjMxMjM1OTU5WjAnMQsw +CQYDVQQGEwJDQTEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0D +AQcDQgAEcC6SggEXbG2r4dFjCUhJ0qY1UtM8c7uyiDeYh/GN4Oxlmg4T9e2RYci2bTOEbq6OVYDN +SZ4Hv9CunebQsycWoaNjMGEwHwYDVR0jBBgwFoAUlUG04meq8X+8j3nzaBRaa5IWokAwHQYDVR0O +BBYEFPDQ8SL5ekgXBns9vbj1zVWcXD5wMA4GA1UdDwEB/wQEAwIAhjAPBgNVHRMBAf8EBTADAQH/ +MAoGCCqGSM49BAMCA0kAMEYCIQCF40ZomdYCellmHLdPNS0INjhhfgVI2GlDH+tW6a0GDgIhAIJw +tGIDSUbIVFkF2XjbUxzgbmb1DxQ7yS04EnCRVvmp +-----END CERTIFICATE----- diff --git a/BearSSL-OG/cert-ica-rsa.pem b/BearSSL-OG/cert-ica-rsa.pem new file mode 100644 index 0000000..058ffab --- /dev/null +++ b/BearSSL-OG/cert-ica-rsa.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIIDNDCCAhygAwIBAgIUcA9g7vAHmpxprJdiJk9dBbb5j0gwDQYJKoZIhvcNAQELBQAwHDELMAkG +A1UEBhMCQ0ExDTALBgNVBAMTBFJvb3QwHhcNMTAwMTAxMDAwMDAwWhcNMzcxMjMxMjM1OTU5WjAn +MQswCQYDVQQGEwJDQTEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAs+hrr5wWUuOBDFCrJc7MDcfyH39Q3yxcNdZiLmMnQafkU6hLJ/oTkaP6 +CUovO17Pd7OKwc1JlZx1DWR07+TXS7mhm2jSMHFI6vdLFN8/R6nYu+yPKMz637QflHyW/AgFKPno +9C8v7mKcijrghVhgtg8tMLTAQVSRTB9frfEZ8MAipn3YP3k0WUJ7W7VBxGR/Us88NyKhL3kllCRB +wj/6x3X7SLUNGKf0VPMubthDWMSrUOgFrZG2HgF1s1Sc3qCZFfus8VyXSVHM71gSb3NrszQUAQ9a +nfqq1pPT4urDq7xO7cxRobj4lLa0LKiGKx/2UUMpUl4TibNqeGBOTsAbpQIDAQABo2MwYTAfBgNV +HSMEGDAWgBTDCry0kGOWkkW8J6DwWIkq1XgAEjAdBgNVHQ4EFgQUfM+jxin388WqGdDAFuvgQA/O +RKcwDgYDVR0PAQH/BAQDAgCGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFQ7 +9OrG5OjAWxKyrfq9qfRiA61XTG8Hp0c1dT5IoltxEAGPk5mdp0fjjj6vLboG/tTkl7wQjaalOjzm +Ics72hPjSiPrvLqlkJGtVW7V3YVLayfSOXYGLtQjW7tVtUk/fS8hy5Z1GZmpmfELuz7HEKeLelK5 +SeQUCHjnPdmYV9r/2rmNZnWAtV2532ll2xbnHsRA5EaKHnYyFueDZ9p4VqsPTFzxcNpmIPT4D/bc +L3KXa3hAeZ1bbb4DznBCqCpxEd8ugQHqhhKRT9AY7YSkSDC5uXtWPu+N4R/9kLJEhVhvpzB0fPGu +jJk/8U1XxZVowjay7MJoesCBqVUF58+vUKw= +-----END CERTIFICATE----- diff --git a/BearSSL-OG/cert-root-ec.pem b/BearSSL-OG/cert-root-ec.pem new file mode 100644 index 0000000..1bfd578 --- /dev/null +++ b/BearSSL-OG/cert-root-ec.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBijCCATCgAwIBAgIBCTAKBggqhkjOPQQDAjAcMQswCQYDVQQGEwJDQTENMAsGA1UEAxMEUm9v +dDAeFw0xMDAxMDEwMDAwMDBaFw0zNzEyMzEyMzU5NTlaMBwxCzAJBgNVBAYTAkNBMQ0wCwYDVQQD +EwRSb290MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcXS6q7kwLoHV5Vf58yBoDJz5ZNu0IA1t +6kDQSm5C/baaaCVE9t97xPze3Xu7xdt8dj9BZkBu26eHwuXYxfN/jaNjMGEwHwYDVR0jBBgwFoAU +lUG04meq8X+8j3nzaBRaa5IWokAwHQYDVR0OBBYEFJVBtOJnqvF/vI9582gUWmuSFqJAMA4GA1Ud +DwEB/wQEAwIAhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIQCz1GCIAoRtqU2h +x62hec7E+/XxnUGDORWnkliiGrcmxQIgNPq9NHD7ts0xYjTwZsd0bN62+iY93lM4LHbkNV9q/gA= +-----END CERTIFICATE----- diff --git a/BearSSL-OG/cert-root-rsa.pem b/BearSSL-OG/cert-root-rsa.pem new file mode 100644 index 0000000..6b5ebd0 --- /dev/null +++ b/BearSSL-OG/cert-root-rsa.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIDFjCCAf6gAwIBAgIBCDANBgkqhkiG9w0BAQsFADAcMQswCQYDVQQGEwJDQTENMAsGA1UEAxME +Um9vdDAeFw0xMDAxMDEwMDAwMDBaFw0zNzEyMzEyMzU5NTlaMBwxCzAJBgNVBAYTAkNBMQ0wCwYD +VQQDEwRSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAttk01FD9s696c/HOOL9d +b0Xh/U6xmMZggybSF9HFt5qjwd5jOZec8F5cyBwXuYgZbfC2LjBQoVRuk8DbzzDLnx4nefHDmVI1 +qj2237CtfMtJzcDt52YQKunOKB8hUPp3TC3a7zxY606/zun7Gtqjg6PNo8qTgNza8xfMeqszgJyy +1H9GP8U83GGUtycpbiq8Wwk21MY7Deu+ztsdHLwQanFxs/LKKJp38orsQu+xSo7i8hoyKs3ApkYs +msKFN5F/RqGTgaF0Zt+6szkgkZP6HaGohefk+Qf2EPaoJwG2fxLDQMPJ4rCrSRg6ZLZZt5W1ljbf +ImmqcmpUTicpow6XFQIDAQABo2MwYTAfBgNVHSMEGDAWgBTDCry0kGOWkkW8J6DwWIkq1XgAEjAd +BgNVHQ4EFgQUwwq8tJBjlpJFvCeg8FiJKtV4ABIwDgYDVR0PAQH/BAQDAgCGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAA7SaR2V1Gx71RiL5Cdfr15jkU88snnm+v+0PvIfQrNP +4RzKJkaD3j//oZf6Hr2yH6c7Bi3OhCxBFNbXjDXiAXVRoTjOSxNSwVq43utl9Z4IKAZzQlEYW5S5 +U0oskEq2q6jDEWoj8lUtQW4GAVuZhq7lNs0jJJu84IBsxHJFgZJ/7+LHFLXs+vQkz3hjzMZ7gIt+ +lwXI/gdY9ld1QB6WLLIzxs7zid+Z0LZTYi851vbmMwUqgL8V5Np0Q0EVHHy1c6LQ0hj1kVLay2ZN +d2dsUMCQJI5EF2kWon+xFDpAtv0vUT2xuMkYFhjS/aBxzevWCsXuUQphBYaIGli8P68NNPo= +-----END CERTIFICATE----- diff --git a/BearSSL-OG/cert_pinning.cpp b/BearSSL-OG/cert_pinning.cpp new file mode 100644 index 0000000..51fc3c9 --- /dev/null +++ b/BearSSL-OG/cert_pinning.cpp @@ -0,0 +1,163 @@ +#include "cert_pinning.h" +#include "ssl_debug.h" + +#include +#include + +/* Constant-time comparison for cryptographic material. + Returns 0 if equal, non-zero otherwise. */ +static int ct_memcmp(const unsigned char *a, const unsigned char *b, size_t n) +{ + unsigned char diff = 0; + size_t i; + for (i = 0; i < n; i++) { + diff |= a[i] ^ b[i]; + } + return diff; +} + +cert_pinning::pin_entry cert_pinning::pins[MAX_PINNED_HOSTS]; +bool cert_pinning::initialized = false; + +void cert_pinning::initialize() +{ + if (initialized) return; + + memset(pins, 0, sizeof(pins)); + initialized = true; + ssl_debug::log_verbose("Certificate pinning initialized\n"); +} + +void cert_pinning::shutdown() +{ + clear(); + initialized = false; +} + +int cert_pinning::find_pin(const char* hostname) +{ + for (int i = 0; i < MAX_PINNED_HOSTS; i++) { + if (pins[i].valid && _stricmp(pins[i].hostname, hostname) == 0) { + return i; + } + } + return -1; +} + +bool cert_pinning::add_pin(const char* hostname, const unsigned char* sha256_hash) +{ + if (!initialized) initialize(); + + // Check if already exists + int idx = find_pin(hostname); + if (idx >= 0) { + // Update existing + memcpy(pins[idx].sha256_hash, sha256_hash, 32); + ssl_debug::log_info("Certificate pin updated for %s\n", hostname); + return true; + } + + // Find free slot + for (int i = 0; i < MAX_PINNED_HOSTS; i++) { + if (!pins[i].valid) { + strncpy(pins[i].hostname, hostname, 255); + pins[i].hostname[255] = '\0'; + memcpy(pins[i].sha256_hash, sha256_hash, 32); + pins[i].valid = true; + ssl_debug::log_info("Certificate pin added for %s\n", hostname); + return true; + } + } + + ssl_debug::log_error("Certificate pin table full, cannot add %s\n", hostname); + return false; +} + +void cert_pinning::remove_pin(const char* hostname) +{ + int idx = find_pin(hostname); + if (idx >= 0) { + pins[idx].valid = false; + ssl_debug::log_info("Certificate pin removed for %s\n", hostname); + } +} + +void cert_pinning::clear() +{ + memset(pins, 0, sizeof(pins)); + ssl_debug::log_verbose("All certificate pins cleared\n"); +} + +bool cert_pinning::has_pin(const char* hostname) +{ + return find_pin(hostname) >= 0; +} + +bool cert_pinning::get_pin_hash(const char* hostname, unsigned char* hash_out) +{ + int idx = find_pin(hostname); + if (idx < 0) { + return false; + } + memcpy(hash_out, pins[idx].sha256_hash, 32); + return true; +} + +void cert_pinning::get_cert_hash(br_ssl_engine_context* engine, unsigned char* hash_out) +{ + /* + * This legacy function is kept for API compatibility but is not the + * recommended path. Use verify_hash() with a hash captured by the + * custom X.509 callback in bearssl.c instead. + */ + (void)engine; + memset(hash_out, 0, 32); +} + +bool cert_pinning::verify_hash(const char* hostname, const unsigned char* cert_sha256) +{ + if (!initialized) initialize(); + + int idx = find_pin(hostname); + if (idx < 0) { + /* No pin for this host - allow connection */ + return true; + } + + /* Compare the captured certificate hash against the stored pin. + Uses constant-time comparison to prevent timing side channels. */ + if (ct_memcmp(pins[idx].sha256_hash, cert_sha256, 32) == 0) { + ssl_debug::log_info("Certificate pin MATCH for %s\n", hostname); + return true; + } + + /* Pin mismatch */ + ssl_debug::log_error("Certificate pin MISMATCH for %s!\n", hostname); + ssl_debug::log_error(" Expected: %02X%02X%02X%02X...\n", + pins[idx].sha256_hash[0], pins[idx].sha256_hash[1], + pins[idx].sha256_hash[2], pins[idx].sha256_hash[3]); + ssl_debug::log_error(" Got: %02X%02X%02X%02X...\n", + cert_sha256[0], cert_sha256[1], cert_sha256[2], cert_sha256[3]); + return false; +} + +bool cert_pinning::verify(const char* hostname, br_ssl_engine_context* engine) +{ + if (!initialized) initialize(); + + int idx = find_pin(hostname); + if (idx < 0) { + /* No pin for this host - allow connection */ + return true; + } + + /* + * Legacy path: try to use the engine directly. + * The preferred path is verify_hash() called from the X.509 callback + * in bearssl.c, which captures the leaf cert hash during the handshake. + */ + ssl_debug::log_info("Certificate pin check for %s (via engine - use verify_hash for best results)\n", hostname); + + (void)engine; + return true; +} diff --git a/BearSSL-OG/cert_pinning.h b/BearSSL-OG/cert_pinning.h new file mode 100644 index 0000000..58c25b5 --- /dev/null +++ b/BearSSL-OG/cert_pinning.h @@ -0,0 +1,49 @@ +#pragma once + +#include + +#define MAX_PINNED_HOSTS 8 + +class cert_pinning +{ +public: + static void initialize(); + static void shutdown(); + + // Add a pin: hostname + SHA-256 hash of certificate + static bool add_pin(const char* hostname, const unsigned char* sha256_hash); + + // Remove a pin + static void remove_pin(const char* hostname); + + // Clear all pins + static void clear(); + + // Verify certificate hash matches pin (returns true if no pin exists or if pin matches) + static bool verify(const char* hostname, br_ssl_engine_context* engine); + + // Verify a pre-computed SHA-256 hash against stored pin + // Returns true if no pin exists for hostname, or if pin matches the hash + static bool verify_hash(const char* hostname, const unsigned char* cert_sha256); + + // Check if hostname has a pin + static bool has_pin(const char* hostname); + + // Get the stored pin hash for a hostname (returns false if no pin) + static bool get_pin_hash(const char* hostname, unsigned char* hash_out); + + // Get hash of current certificate (for setting up pins) + static void get_cert_hash(br_ssl_engine_context* engine, unsigned char* hash_out); + +private: + struct pin_entry { + char hostname[256]; + unsigned char sha256_hash[32]; + bool valid; + }; + + static pin_entry pins[MAX_PINNED_HOSTS]; + static bool initialized; + + static int find_pin(const char* hostname); +}; diff --git a/BearSSL-OG/certificates.cpp b/BearSSL-OG/certificates.cpp new file mode 100644 index 0000000..8c4020a --- /dev/null +++ b/BearSSL-OG/certificates.cpp @@ -0,0 +1,858 @@ +#include "certificates.h" +#include "ca_loader.h" +#include +#include + +#include "trust_anchors.h" + +#define NUM_TRUST_ANCHORS 750 + +namespace +{ + br_x509_trust_anchor* trust_anchors = NULL; + int trust_anchor_count = 0; + int loaded_from_file = 0; /* 1 = heap-allocated per-anchor data */ +} + +void certificates::initialize_trust_anchors() +{ + if (trust_anchors != NULL) + { + return; + } + trust_anchors = (br_x509_trust_anchor*)malloc(NUM_TRUST_ANCHORS * sizeof br_x509_trust_anchor); + if (trust_anchors == NULL) + { + OutputDebugStringA("certificates: FATAL - malloc failed for trust anchors!\n"); + return; + } + trust_anchor_count = NUM_TRUST_ANCHORS; + loaded_from_file = 0; + trust_anchors[0] = make_rsa_trust_anchor((unsigned char *)TA0_DN, sizeof TA0_DN, (unsigned char *)TA0_RSA_N, sizeof TA0_RSA_N, (unsigned char *)TA0_RSA_E, sizeof TA0_RSA_E); + trust_anchors[1] = make_ec_trust_anchor((unsigned char *)TA1_DN, sizeof TA1_DN, BR_EC_secp384r1, (unsigned char *)TA1_EC_Q, sizeof TA1_EC_Q); + trust_anchors[2] = make_rsa_trust_anchor((unsigned char *)TA2_DN, sizeof TA2_DN, (unsigned char *)TA2_RSA_N, sizeof TA2_RSA_N, (unsigned char *)TA2_RSA_E, sizeof TA2_RSA_E); + trust_anchors[3] = make_rsa_trust_anchor((unsigned char *)TA3_DN, sizeof TA3_DN, (unsigned char *)TA3_RSA_N, sizeof TA3_RSA_N, (unsigned char *)TA3_RSA_E, sizeof TA3_RSA_E); + trust_anchors[4] = make_ec_trust_anchor((unsigned char *)TA4_DN, sizeof TA4_DN, BR_EC_secp384r1, (unsigned char *)TA4_EC_Q, sizeof TA4_EC_Q); + trust_anchors[5] = make_rsa_trust_anchor((unsigned char *)TA5_DN, sizeof TA5_DN, (unsigned char *)TA5_RSA_N, sizeof TA5_RSA_N, (unsigned char *)TA5_RSA_E, sizeof TA5_RSA_E); + trust_anchors[6] = make_rsa_trust_anchor((unsigned char *)TA6_DN, sizeof TA6_DN, (unsigned char *)TA6_RSA_N, sizeof TA6_RSA_N, (unsigned char *)TA6_RSA_E, sizeof TA6_RSA_E); + trust_anchors[7] = make_ec_trust_anchor((unsigned char *)TA7_DN, sizeof TA7_DN, BR_EC_secp384r1, (unsigned char *)TA7_EC_Q, sizeof TA7_EC_Q); + trust_anchors[8] = make_rsa_trust_anchor((unsigned char *)TA8_DN, sizeof TA8_DN, (unsigned char *)TA8_RSA_N, sizeof TA8_RSA_N, (unsigned char *)TA8_RSA_E, sizeof TA8_RSA_E); + trust_anchors[9] = make_ec_trust_anchor((unsigned char *)TA9_DN, sizeof TA9_DN, BR_EC_secp384r1, (unsigned char *)TA9_EC_Q, sizeof TA9_EC_Q); + trust_anchors[10] = make_rsa_trust_anchor((unsigned char *)TA10_DN, sizeof TA10_DN, (unsigned char *)TA10_RSA_N, sizeof TA10_RSA_N, (unsigned char *)TA10_RSA_E, sizeof TA10_RSA_E); + trust_anchors[11] = make_ec_trust_anchor((unsigned char *)TA11_DN, sizeof TA11_DN, BR_EC_secp384r1, (unsigned char *)TA11_EC_Q, sizeof TA11_EC_Q); + trust_anchors[12] = make_rsa_trust_anchor((unsigned char *)TA12_DN, sizeof TA12_DN, (unsigned char *)TA12_RSA_N, sizeof TA12_RSA_N, (unsigned char *)TA12_RSA_E, sizeof TA12_RSA_E); + trust_anchors[13] = make_ec_trust_anchor((unsigned char *)TA13_DN, sizeof TA13_DN, BR_EC_secp384r1, (unsigned char *)TA13_EC_Q, sizeof TA13_EC_Q); + trust_anchors[14] = make_ec_trust_anchor((unsigned char *)TA14_DN, sizeof TA14_DN, BR_EC_secp384r1, (unsigned char *)TA14_EC_Q, sizeof TA14_EC_Q); + trust_anchors[15] = make_ec_trust_anchor((unsigned char *)TA15_DN, sizeof TA15_DN, BR_EC_secp256r1, (unsigned char *)TA15_EC_Q, sizeof TA15_EC_Q); + trust_anchors[16] = make_rsa_trust_anchor((unsigned char *)TA16_DN, sizeof TA16_DN, (unsigned char *)TA16_RSA_N, sizeof TA16_RSA_N, (unsigned char *)TA16_RSA_E, sizeof TA16_RSA_E); + trust_anchors[17] = make_rsa_trust_anchor((unsigned char *)TA17_DN, sizeof TA17_DN, (unsigned char *)TA17_RSA_N, sizeof TA17_RSA_N, (unsigned char *)TA17_RSA_E, sizeof TA17_RSA_E); + trust_anchors[18] = make_rsa_trust_anchor((unsigned char *)TA18_DN, sizeof TA18_DN, (unsigned char *)TA18_RSA_N, sizeof TA18_RSA_N, (unsigned char *)TA18_RSA_E, sizeof TA18_RSA_E); + trust_anchors[19] = make_rsa_trust_anchor((unsigned char *)TA19_DN, sizeof TA19_DN, (unsigned char *)TA19_RSA_N, sizeof TA19_RSA_N, (unsigned char *)TA19_RSA_E, sizeof TA19_RSA_E); + trust_anchors[20] = make_ec_trust_anchor((unsigned char *)TA20_DN, sizeof TA20_DN, BR_EC_secp384r1, (unsigned char *)TA20_EC_Q, sizeof TA20_EC_Q); + trust_anchors[21] = make_rsa_trust_anchor((unsigned char *)TA21_DN, sizeof TA21_DN, (unsigned char *)TA21_RSA_N, sizeof TA21_RSA_N, (unsigned char *)TA21_RSA_E, sizeof TA21_RSA_E); + trust_anchors[22] = make_ec_trust_anchor((unsigned char *)TA22_DN, sizeof TA22_DN, BR_EC_secp384r1, (unsigned char *)TA22_EC_Q, sizeof TA22_EC_Q); + trust_anchors[23] = make_ec_trust_anchor((unsigned char *)TA23_DN, sizeof TA23_DN, BR_EC_secp256r1, (unsigned char *)TA23_EC_Q, sizeof TA23_EC_Q); + trust_anchors[24] = make_rsa_trust_anchor((unsigned char *)TA24_DN, sizeof TA24_DN, (unsigned char *)TA24_RSA_N, sizeof TA24_RSA_N, (unsigned char *)TA24_RSA_E, sizeof TA24_RSA_E); + trust_anchors[25] = make_ec_trust_anchor((unsigned char *)TA25_DN, sizeof TA25_DN, BR_EC_secp384r1, (unsigned char *)TA25_EC_Q, sizeof TA25_EC_Q); + trust_anchors[26] = make_ec_trust_anchor((unsigned char *)TA26_DN, sizeof TA26_DN, BR_EC_secp384r1, (unsigned char *)TA26_EC_Q, sizeof TA26_EC_Q); + trust_anchors[27] = make_rsa_trust_anchor((unsigned char *)TA27_DN, sizeof TA27_DN, (unsigned char *)TA27_RSA_N, sizeof TA27_RSA_N, (unsigned char *)TA27_RSA_E, sizeof TA27_RSA_E); + trust_anchors[28] = make_rsa_trust_anchor((unsigned char *)TA28_DN, sizeof TA28_DN, (unsigned char *)TA28_RSA_N, sizeof TA28_RSA_N, (unsigned char *)TA28_RSA_E, sizeof TA28_RSA_E); + trust_anchors[29] = make_rsa_trust_anchor((unsigned char *)TA29_DN, sizeof TA29_DN, (unsigned char *)TA29_RSA_N, sizeof TA29_RSA_N, (unsigned char *)TA29_RSA_E, sizeof TA29_RSA_E); + trust_anchors[30] = make_rsa_trust_anchor((unsigned char *)TA30_DN, sizeof TA30_DN, (unsigned char *)TA30_RSA_N, sizeof TA30_RSA_N, (unsigned char *)TA30_RSA_E, sizeof TA30_RSA_E); + trust_anchors[31] = make_rsa_trust_anchor((unsigned char *)TA31_DN, sizeof TA31_DN, (unsigned char *)TA31_RSA_N, sizeof TA31_RSA_N, (unsigned char *)TA31_RSA_E, sizeof TA31_RSA_E); + trust_anchors[32] = make_rsa_trust_anchor((unsigned char *)TA32_DN, sizeof TA32_DN, (unsigned char *)TA32_RSA_N, sizeof TA32_RSA_N, (unsigned char *)TA32_RSA_E, sizeof TA32_RSA_E); + trust_anchors[33] = make_rsa_trust_anchor((unsigned char *)TA33_DN, sizeof TA33_DN, (unsigned char *)TA33_RSA_N, sizeof TA33_RSA_N, (unsigned char *)TA33_RSA_E, sizeof TA33_RSA_E); + trust_anchors[34] = make_rsa_trust_anchor((unsigned char *)TA34_DN, sizeof TA34_DN, (unsigned char *)TA34_RSA_N, sizeof TA34_RSA_N, (unsigned char *)TA34_RSA_E, sizeof TA34_RSA_E); + trust_anchors[35] = make_rsa_trust_anchor((unsigned char *)TA35_DN, sizeof TA35_DN, (unsigned char *)TA35_RSA_N, sizeof TA35_RSA_N, (unsigned char *)TA35_RSA_E, sizeof TA35_RSA_E); + trust_anchors[36] = make_ec_trust_anchor((unsigned char *)TA36_DN, sizeof TA36_DN, BR_EC_secp384r1, (unsigned char *)TA36_EC_Q, sizeof TA36_EC_Q); + trust_anchors[37] = make_rsa_trust_anchor((unsigned char *)TA37_DN, sizeof TA37_DN, (unsigned char *)TA37_RSA_N, sizeof TA37_RSA_N, (unsigned char *)TA37_RSA_E, sizeof TA37_RSA_E); + trust_anchors[38] = make_rsa_trust_anchor((unsigned char *)TA38_DN, sizeof TA38_DN, (unsigned char *)TA38_RSA_N, sizeof TA38_RSA_N, (unsigned char *)TA38_RSA_E, sizeof TA38_RSA_E); + trust_anchors[39] = make_ec_trust_anchor((unsigned char *)TA39_DN, sizeof TA39_DN, BR_EC_secp384r1, (unsigned char *)TA39_EC_Q, sizeof TA39_EC_Q); + trust_anchors[40] = make_rsa_trust_anchor((unsigned char *)TA40_DN, sizeof TA40_DN, (unsigned char *)TA40_RSA_N, sizeof TA40_RSA_N, (unsigned char *)TA40_RSA_E, sizeof TA40_RSA_E); + trust_anchors[41] = make_ec_trust_anchor((unsigned char *)TA41_DN, sizeof TA41_DN, BR_EC_secp384r1, (unsigned char *)TA41_EC_Q, sizeof TA41_EC_Q); + trust_anchors[42] = make_rsa_trust_anchor((unsigned char *)TA42_DN, sizeof TA42_DN, (unsigned char *)TA42_RSA_N, sizeof TA42_RSA_N, (unsigned char *)TA42_RSA_E, sizeof TA42_RSA_E); + trust_anchors[43] = make_rsa_trust_anchor((unsigned char *)TA43_DN, sizeof TA43_DN, (unsigned char *)TA43_RSA_N, sizeof TA43_RSA_N, (unsigned char *)TA43_RSA_E, sizeof TA43_RSA_E); + trust_anchors[44] = make_rsa_trust_anchor((unsigned char *)TA44_DN, sizeof TA44_DN, (unsigned char *)TA44_RSA_N, sizeof TA44_RSA_N, (unsigned char *)TA44_RSA_E, sizeof TA44_RSA_E); + trust_anchors[45] = make_ec_trust_anchor((unsigned char *)TA45_DN, sizeof TA45_DN, BR_EC_secp384r1, (unsigned char *)TA45_EC_Q, sizeof TA45_EC_Q); + trust_anchors[46] = make_rsa_trust_anchor((unsigned char *)TA46_DN, sizeof TA46_DN, (unsigned char *)TA46_RSA_N, sizeof TA46_RSA_N, (unsigned char *)TA46_RSA_E, sizeof TA46_RSA_E); + trust_anchors[47] = make_rsa_trust_anchor((unsigned char *)TA47_DN, sizeof TA47_DN, (unsigned char *)TA47_RSA_N, sizeof TA47_RSA_N, (unsigned char *)TA47_RSA_E, sizeof TA47_RSA_E); + trust_anchors[48] = make_rsa_trust_anchor((unsigned char *)TA48_DN, sizeof TA48_DN, (unsigned char *)TA48_RSA_N, sizeof TA48_RSA_N, (unsigned char *)TA48_RSA_E, sizeof TA48_RSA_E); + trust_anchors[49] = make_rsa_trust_anchor((unsigned char *)TA49_DN, sizeof TA49_DN, (unsigned char *)TA49_RSA_N, sizeof TA49_RSA_N, (unsigned char *)TA49_RSA_E, sizeof TA49_RSA_E); + trust_anchors[50] = make_rsa_trust_anchor((unsigned char *)TA50_DN, sizeof TA50_DN, (unsigned char *)TA50_RSA_N, sizeof TA50_RSA_N, (unsigned char *)TA50_RSA_E, sizeof TA50_RSA_E); + trust_anchors[51] = make_rsa_trust_anchor((unsigned char *)TA51_DN, sizeof TA51_DN, (unsigned char *)TA51_RSA_N, sizeof TA51_RSA_N, (unsigned char *)TA51_RSA_E, sizeof TA51_RSA_E); + trust_anchors[52] = make_ec_trust_anchor((unsigned char *)TA52_DN, sizeof TA52_DN, BR_EC_secp384r1, (unsigned char *)TA52_EC_Q, sizeof TA52_EC_Q); + trust_anchors[53] = make_rsa_trust_anchor((unsigned char *)TA53_DN, sizeof TA53_DN, (unsigned char *)TA53_RSA_N, sizeof TA53_RSA_N, (unsigned char *)TA53_RSA_E, sizeof TA53_RSA_E); + trust_anchors[54] = make_rsa_trust_anchor((unsigned char *)TA54_DN, sizeof TA54_DN, (unsigned char *)TA54_RSA_N, sizeof TA54_RSA_N, (unsigned char *)TA54_RSA_E, sizeof TA54_RSA_E); + trust_anchors[55] = make_rsa_trust_anchor((unsigned char *)TA55_DN, sizeof TA55_DN, (unsigned char *)TA55_RSA_N, sizeof TA55_RSA_N, (unsigned char *)TA55_RSA_E, sizeof TA55_RSA_E); + trust_anchors[56] = make_rsa_trust_anchor((unsigned char *)TA56_DN, sizeof TA56_DN, (unsigned char *)TA56_RSA_N, sizeof TA56_RSA_N, (unsigned char *)TA56_RSA_E, sizeof TA56_RSA_E); + trust_anchors[57] = make_ec_trust_anchor((unsigned char *)TA57_DN, sizeof TA57_DN, BR_EC_secp384r1, (unsigned char *)TA57_EC_Q, sizeof TA57_EC_Q); + trust_anchors[58] = make_rsa_trust_anchor((unsigned char *)TA58_DN, sizeof TA58_DN, (unsigned char *)TA58_RSA_N, sizeof TA58_RSA_N, (unsigned char *)TA58_RSA_E, sizeof TA58_RSA_E); + trust_anchors[59] = make_rsa_trust_anchor((unsigned char *)TA59_DN, sizeof TA59_DN, (unsigned char *)TA59_RSA_N, sizeof TA59_RSA_N, (unsigned char *)TA59_RSA_E, sizeof TA59_RSA_E); + trust_anchors[60] = make_ec_trust_anchor((unsigned char *)TA60_DN, sizeof TA60_DN, BR_EC_secp384r1, (unsigned char *)TA60_EC_Q, sizeof TA60_EC_Q); + trust_anchors[61] = make_rsa_trust_anchor((unsigned char *)TA61_DN, sizeof TA61_DN, (unsigned char *)TA61_RSA_N, sizeof TA61_RSA_N, (unsigned char *)TA61_RSA_E, sizeof TA61_RSA_E); + trust_anchors[62] = make_ec_trust_anchor((unsigned char *)TA62_DN, sizeof TA62_DN, BR_EC_secp384r1, (unsigned char *)TA62_EC_Q, sizeof TA62_EC_Q); + trust_anchors[63] = make_rsa_trust_anchor((unsigned char *)TA63_DN, sizeof TA63_DN, (unsigned char *)TA63_RSA_N, sizeof TA63_RSA_N, (unsigned char *)TA63_RSA_E, sizeof TA63_RSA_E); + trust_anchors[64] = make_rsa_trust_anchor((unsigned char *)TA64_DN, sizeof TA64_DN, (unsigned char *)TA64_RSA_N, sizeof TA64_RSA_N, (unsigned char *)TA64_RSA_E, sizeof TA64_RSA_E); + trust_anchors[65] = make_rsa_trust_anchor((unsigned char *)TA65_DN, sizeof TA65_DN, (unsigned char *)TA65_RSA_N, sizeof TA65_RSA_N, (unsigned char *)TA65_RSA_E, sizeof TA65_RSA_E); + trust_anchors[66] = make_rsa_trust_anchor((unsigned char *)TA66_DN, sizeof TA66_DN, (unsigned char *)TA66_RSA_N, sizeof TA66_RSA_N, (unsigned char *)TA66_RSA_E, sizeof TA66_RSA_E); + trust_anchors[67] = make_rsa_trust_anchor((unsigned char *)TA67_DN, sizeof TA67_DN, (unsigned char *)TA67_RSA_N, sizeof TA67_RSA_N, (unsigned char *)TA67_RSA_E, sizeof TA67_RSA_E); + trust_anchors[68] = make_rsa_trust_anchor((unsigned char *)TA68_DN, sizeof TA68_DN, (unsigned char *)TA68_RSA_N, sizeof TA68_RSA_N, (unsigned char *)TA68_RSA_E, sizeof TA68_RSA_E); + trust_anchors[69] = make_ec_trust_anchor((unsigned char *)TA69_DN, sizeof TA69_DN, BR_EC_secp384r1, (unsigned char *)TA69_EC_Q, sizeof TA69_EC_Q); + trust_anchors[70] = make_rsa_trust_anchor((unsigned char *)TA70_DN, sizeof TA70_DN, (unsigned char *)TA70_RSA_N, sizeof TA70_RSA_N, (unsigned char *)TA70_RSA_E, sizeof TA70_RSA_E); + trust_anchors[71] = make_rsa_trust_anchor((unsigned char *)TA71_DN, sizeof TA71_DN, (unsigned char *)TA71_RSA_N, sizeof TA71_RSA_N, (unsigned char *)TA71_RSA_E, sizeof TA71_RSA_E); + trust_anchors[72] = make_rsa_trust_anchor((unsigned char *)TA72_DN, sizeof TA72_DN, (unsigned char *)TA72_RSA_N, sizeof TA72_RSA_N, (unsigned char *)TA72_RSA_E, sizeof TA72_RSA_E); + trust_anchors[73] = make_rsa_trust_anchor((unsigned char *)TA73_DN, sizeof TA73_DN, (unsigned char *)TA73_RSA_N, sizeof TA73_RSA_N, (unsigned char *)TA73_RSA_E, sizeof TA73_RSA_E); + trust_anchors[74] = make_ec_trust_anchor((unsigned char *)TA74_DN, sizeof TA74_DN, BR_EC_secp384r1, (unsigned char *)TA74_EC_Q, sizeof TA74_EC_Q); + trust_anchors[75] = make_rsa_trust_anchor((unsigned char *)TA75_DN, sizeof TA75_DN, (unsigned char *)TA75_RSA_N, sizeof TA75_RSA_N, (unsigned char *)TA75_RSA_E, sizeof TA75_RSA_E); + trust_anchors[76] = make_rsa_trust_anchor((unsigned char *)TA76_DN, sizeof TA76_DN, (unsigned char *)TA76_RSA_N, sizeof TA76_RSA_N, (unsigned char *)TA76_RSA_E, sizeof TA76_RSA_E); + trust_anchors[77] = make_ec_trust_anchor((unsigned char *)TA77_DN, sizeof TA77_DN, BR_EC_secp384r1, (unsigned char *)TA77_EC_Q, sizeof TA77_EC_Q); + trust_anchors[78] = make_rsa_trust_anchor((unsigned char *)TA78_DN, sizeof TA78_DN, (unsigned char *)TA78_RSA_N, sizeof TA78_RSA_N, (unsigned char *)TA78_RSA_E, sizeof TA78_RSA_E); + trust_anchors[79] = make_rsa_trust_anchor((unsigned char *)TA79_DN, sizeof TA79_DN, (unsigned char *)TA79_RSA_N, sizeof TA79_RSA_N, (unsigned char *)TA79_RSA_E, sizeof TA79_RSA_E); + trust_anchors[80] = make_rsa_trust_anchor((unsigned char *)TA80_DN, sizeof TA80_DN, (unsigned char *)TA80_RSA_N, sizeof TA80_RSA_N, (unsigned char *)TA80_RSA_E, sizeof TA80_RSA_E); + trust_anchors[81] = make_rsa_trust_anchor((unsigned char *)TA81_DN, sizeof TA81_DN, (unsigned char *)TA81_RSA_N, sizeof TA81_RSA_N, (unsigned char *)TA81_RSA_E, sizeof TA81_RSA_E); + trust_anchors[82] = make_rsa_trust_anchor((unsigned char *)TA82_DN, sizeof TA82_DN, (unsigned char *)TA82_RSA_N, sizeof TA82_RSA_N, (unsigned char *)TA82_RSA_E, sizeof TA82_RSA_E); + trust_anchors[83] = make_rsa_trust_anchor((unsigned char *)TA83_DN, sizeof TA83_DN, (unsigned char *)TA83_RSA_N, sizeof TA83_RSA_N, (unsigned char *)TA83_RSA_E, sizeof TA83_RSA_E); + trust_anchors[84] = make_rsa_trust_anchor((unsigned char *)TA84_DN, sizeof TA84_DN, (unsigned char *)TA84_RSA_N, sizeof TA84_RSA_N, (unsigned char *)TA84_RSA_E, sizeof TA84_RSA_E); + trust_anchors[85] = make_ec_trust_anchor((unsigned char *)TA85_DN, sizeof TA85_DN, BR_EC_secp384r1, (unsigned char *)TA85_EC_Q, sizeof TA85_EC_Q); + trust_anchors[86] = make_ec_trust_anchor((unsigned char *)TA86_DN, sizeof TA86_DN, BR_EC_secp384r1, (unsigned char *)TA86_EC_Q, sizeof TA86_EC_Q); + trust_anchors[87] = make_ec_trust_anchor((unsigned char *)TA87_DN, sizeof TA87_DN, BR_EC_secp384r1, (unsigned char *)TA87_EC_Q, sizeof TA87_EC_Q); + trust_anchors[88] = make_rsa_trust_anchor((unsigned char *)TA88_DN, sizeof TA88_DN, (unsigned char *)TA88_RSA_N, sizeof TA88_RSA_N, (unsigned char *)TA88_RSA_E, sizeof TA88_RSA_E); + trust_anchors[89] = make_ec_trust_anchor((unsigned char *)TA89_DN, sizeof TA89_DN, BR_EC_secp384r1, (unsigned char *)TA89_EC_Q, sizeof TA89_EC_Q); + trust_anchors[90] = make_rsa_trust_anchor((unsigned char *)TA90_DN, sizeof TA90_DN, (unsigned char *)TA90_RSA_N, sizeof TA90_RSA_N, (unsigned char *)TA90_RSA_E, sizeof TA90_RSA_E); + trust_anchors[91] = make_rsa_trust_anchor((unsigned char *)TA91_DN, sizeof TA91_DN, (unsigned char *)TA91_RSA_N, sizeof TA91_RSA_N, (unsigned char *)TA91_RSA_E, sizeof TA91_RSA_E); + trust_anchors[92] = make_rsa_trust_anchor((unsigned char *)TA92_DN, sizeof TA92_DN, (unsigned char *)TA92_RSA_N, sizeof TA92_RSA_N, (unsigned char *)TA92_RSA_E, sizeof TA92_RSA_E); + trust_anchors[93] = make_rsa_trust_anchor((unsigned char *)TA93_DN, sizeof TA93_DN, (unsigned char *)TA93_RSA_N, sizeof TA93_RSA_N, (unsigned char *)TA93_RSA_E, sizeof TA93_RSA_E); + trust_anchors[94] = make_rsa_trust_anchor((unsigned char *)TA94_DN, sizeof TA94_DN, (unsigned char *)TA94_RSA_N, sizeof TA94_RSA_N, (unsigned char *)TA94_RSA_E, sizeof TA94_RSA_E); + trust_anchors[95] = make_rsa_trust_anchor((unsigned char *)TA95_DN, sizeof TA95_DN, (unsigned char *)TA95_RSA_N, sizeof TA95_RSA_N, (unsigned char *)TA95_RSA_E, sizeof TA95_RSA_E); + trust_anchors[96] = make_ec_trust_anchor((unsigned char *)TA96_DN, sizeof TA96_DN, BR_EC_secp384r1, (unsigned char *)TA96_EC_Q, sizeof TA96_EC_Q); + trust_anchors[97] = make_ec_trust_anchor((unsigned char *)TA97_DN, sizeof TA97_DN, BR_EC_secp384r1, (unsigned char *)TA97_EC_Q, sizeof TA97_EC_Q); + trust_anchors[98] = make_rsa_trust_anchor((unsigned char *)TA98_DN, sizeof TA98_DN, (unsigned char *)TA98_RSA_N, sizeof TA98_RSA_N, (unsigned char *)TA98_RSA_E, sizeof TA98_RSA_E); + trust_anchors[99] = make_rsa_trust_anchor((unsigned char *)TA99_DN, sizeof TA99_DN, (unsigned char *)TA99_RSA_N, sizeof TA99_RSA_N, (unsigned char *)TA99_RSA_E, sizeof TA99_RSA_E); + trust_anchors[100] = make_rsa_trust_anchor((unsigned char *)TA100_DN, sizeof TA100_DN, (unsigned char *)TA100_RSA_N, sizeof TA100_RSA_N, (unsigned char *)TA100_RSA_E, sizeof TA100_RSA_E); + trust_anchors[101] = make_rsa_trust_anchor((unsigned char *)TA101_DN, sizeof TA101_DN, (unsigned char *)TA101_RSA_N, sizeof TA101_RSA_N, (unsigned char *)TA101_RSA_E, sizeof TA101_RSA_E); + trust_anchors[102] = make_rsa_trust_anchor((unsigned char *)TA102_DN, sizeof TA102_DN, (unsigned char *)TA102_RSA_N, sizeof TA102_RSA_N, (unsigned char *)TA102_RSA_E, sizeof TA102_RSA_E); + trust_anchors[103] = make_rsa_trust_anchor((unsigned char *)TA103_DN, sizeof TA103_DN, (unsigned char *)TA103_RSA_N, sizeof TA103_RSA_N, (unsigned char *)TA103_RSA_E, sizeof TA103_RSA_E); + trust_anchors[104] = make_rsa_trust_anchor((unsigned char *)TA104_DN, sizeof TA104_DN, (unsigned char *)TA104_RSA_N, sizeof TA104_RSA_N, (unsigned char *)TA104_RSA_E, sizeof TA104_RSA_E); + trust_anchors[105] = make_rsa_trust_anchor((unsigned char *)TA105_DN, sizeof TA105_DN, (unsigned char *)TA105_RSA_N, sizeof TA105_RSA_N, (unsigned char *)TA105_RSA_E, sizeof TA105_RSA_E); + trust_anchors[106] = make_rsa_trust_anchor((unsigned char *)TA106_DN, sizeof TA106_DN, (unsigned char *)TA106_RSA_N, sizeof TA106_RSA_N, (unsigned char *)TA106_RSA_E, sizeof TA106_RSA_E); + trust_anchors[107] = make_ec_trust_anchor((unsigned char *)TA107_DN, sizeof TA107_DN, BR_EC_secp384r1, (unsigned char *)TA107_EC_Q, sizeof TA107_EC_Q); + trust_anchors[108] = make_ec_trust_anchor((unsigned char *)TA108_DN, sizeof TA108_DN, BR_EC_secp384r1, (unsigned char *)TA108_EC_Q, sizeof TA108_EC_Q); + trust_anchors[109] = make_ec_trust_anchor((unsigned char *)TA109_DN, sizeof TA109_DN, BR_EC_secp384r1, (unsigned char *)TA109_EC_Q, sizeof TA109_EC_Q); + trust_anchors[110] = make_rsa_trust_anchor((unsigned char *)TA110_DN, sizeof TA110_DN, (unsigned char *)TA110_RSA_N, sizeof TA110_RSA_N, (unsigned char *)TA110_RSA_E, sizeof TA110_RSA_E); + trust_anchors[111] = make_rsa_trust_anchor((unsigned char *)TA111_DN, sizeof TA111_DN, (unsigned char *)TA111_RSA_N, sizeof TA111_RSA_N, (unsigned char *)TA111_RSA_E, sizeof TA111_RSA_E); + trust_anchors[112] = make_rsa_trust_anchor((unsigned char *)TA112_DN, sizeof TA112_DN, (unsigned char *)TA112_RSA_N, sizeof TA112_RSA_N, (unsigned char *)TA112_RSA_E, sizeof TA112_RSA_E); + trust_anchors[113] = make_rsa_trust_anchor((unsigned char *)TA113_DN, sizeof TA113_DN, (unsigned char *)TA113_RSA_N, sizeof TA113_RSA_N, (unsigned char *)TA113_RSA_E, sizeof TA113_RSA_E); + trust_anchors[114] = make_rsa_trust_anchor((unsigned char *)TA114_DN, sizeof TA114_DN, (unsigned char *)TA114_RSA_N, sizeof TA114_RSA_N, (unsigned char *)TA114_RSA_E, sizeof TA114_RSA_E); + trust_anchors[115] = make_rsa_trust_anchor((unsigned char *)TA115_DN, sizeof TA115_DN, (unsigned char *)TA115_RSA_N, sizeof TA115_RSA_N, (unsigned char *)TA115_RSA_E, sizeof TA115_RSA_E); + trust_anchors[116] = make_rsa_trust_anchor((unsigned char *)TA116_DN, sizeof TA116_DN, (unsigned char *)TA116_RSA_N, sizeof TA116_RSA_N, (unsigned char *)TA116_RSA_E, sizeof TA116_RSA_E); + trust_anchors[117] = make_rsa_trust_anchor((unsigned char *)TA117_DN, sizeof TA117_DN, (unsigned char *)TA117_RSA_N, sizeof TA117_RSA_N, (unsigned char *)TA117_RSA_E, sizeof TA117_RSA_E); + trust_anchors[118] = make_rsa_trust_anchor((unsigned char *)TA118_DN, sizeof TA118_DN, (unsigned char *)TA118_RSA_N, sizeof TA118_RSA_N, (unsigned char *)TA118_RSA_E, sizeof TA118_RSA_E); + trust_anchors[119] = make_rsa_trust_anchor((unsigned char *)TA119_DN, sizeof TA119_DN, (unsigned char *)TA119_RSA_N, sizeof TA119_RSA_N, (unsigned char *)TA119_RSA_E, sizeof TA119_RSA_E); + trust_anchors[120] = make_ec_trust_anchor((unsigned char *)TA120_DN, sizeof TA120_DN, BR_EC_secp384r1, (unsigned char *)TA120_EC_Q, sizeof TA120_EC_Q); + trust_anchors[121] = make_ec_trust_anchor((unsigned char *)TA121_DN, sizeof TA121_DN, BR_EC_secp384r1, (unsigned char *)TA121_EC_Q, sizeof TA121_EC_Q); + trust_anchors[122] = make_ec_trust_anchor((unsigned char *)TA122_DN, sizeof TA122_DN, BR_EC_secp384r1, (unsigned char *)TA122_EC_Q, sizeof TA122_EC_Q); + trust_anchors[123] = make_rsa_trust_anchor((unsigned char *)TA123_DN, sizeof TA123_DN, (unsigned char *)TA123_RSA_N, sizeof TA123_RSA_N, (unsigned char *)TA123_RSA_E, sizeof TA123_RSA_E); + trust_anchors[124] = make_rsa_trust_anchor((unsigned char *)TA124_DN, sizeof TA124_DN, (unsigned char *)TA124_RSA_N, sizeof TA124_RSA_N, (unsigned char *)TA124_RSA_E, sizeof TA124_RSA_E); + trust_anchors[125] = make_ec_trust_anchor((unsigned char *)TA125_DN, sizeof TA125_DN, BR_EC_secp384r1, (unsigned char *)TA125_EC_Q, sizeof TA125_EC_Q); + trust_anchors[126] = make_rsa_trust_anchor((unsigned char *)TA126_DN, sizeof TA126_DN, (unsigned char *)TA126_RSA_N, sizeof TA126_RSA_N, (unsigned char *)TA126_RSA_E, sizeof TA126_RSA_E); + trust_anchors[127] = make_ec_trust_anchor((unsigned char *)TA127_DN, sizeof TA127_DN, BR_EC_secp384r1, (unsigned char *)TA127_EC_Q, sizeof TA127_EC_Q); + trust_anchors[128] = make_ec_trust_anchor((unsigned char *)TA128_DN, sizeof TA128_DN, BR_EC_secp384r1, (unsigned char *)TA128_EC_Q, sizeof TA128_EC_Q); + trust_anchors[129] = make_rsa_trust_anchor((unsigned char *)TA129_DN, sizeof TA129_DN, (unsigned char *)TA129_RSA_N, sizeof TA129_RSA_N, (unsigned char *)TA129_RSA_E, sizeof TA129_RSA_E); + trust_anchors[130] = make_rsa_trust_anchor((unsigned char *)TA130_DN, sizeof TA130_DN, (unsigned char *)TA130_RSA_N, sizeof TA130_RSA_N, (unsigned char *)TA130_RSA_E, sizeof TA130_RSA_E); + trust_anchors[131] = make_rsa_trust_anchor((unsigned char *)TA131_DN, sizeof TA131_DN, (unsigned char *)TA131_RSA_N, sizeof TA131_RSA_N, (unsigned char *)TA131_RSA_E, sizeof TA131_RSA_E); + trust_anchors[132] = make_ec_trust_anchor((unsigned char *)TA132_DN, sizeof TA132_DN, BR_EC_secp384r1, (unsigned char *)TA132_EC_Q, sizeof TA132_EC_Q); + trust_anchors[133] = make_rsa_trust_anchor((unsigned char *)TA133_DN, sizeof TA133_DN, (unsigned char *)TA133_RSA_N, sizeof TA133_RSA_N, (unsigned char *)TA133_RSA_E, sizeof TA133_RSA_E); + trust_anchors[134] = make_rsa_trust_anchor((unsigned char *)TA134_DN, sizeof TA134_DN, (unsigned char *)TA134_RSA_N, sizeof TA134_RSA_N, (unsigned char *)TA134_RSA_E, sizeof TA134_RSA_E); + trust_anchors[135] = make_ec_trust_anchor((unsigned char *)TA135_DN, sizeof TA135_DN, BR_EC_secp384r1, (unsigned char *)TA135_EC_Q, sizeof TA135_EC_Q); + trust_anchors[136] = make_ec_trust_anchor((unsigned char *)TA136_DN, sizeof TA136_DN, BR_EC_secp384r1, (unsigned char *)TA136_EC_Q, sizeof TA136_EC_Q); + trust_anchors[137] = make_rsa_trust_anchor((unsigned char *)TA137_DN, sizeof TA137_DN, (unsigned char *)TA137_RSA_N, sizeof TA137_RSA_N, (unsigned char *)TA137_RSA_E, sizeof TA137_RSA_E); + trust_anchors[138] = make_rsa_trust_anchor((unsigned char *)TA138_DN, sizeof TA138_DN, (unsigned char *)TA138_RSA_N, sizeof TA138_RSA_N, (unsigned char *)TA138_RSA_E, sizeof TA138_RSA_E); + trust_anchors[139] = make_ec_trust_anchor((unsigned char *)TA139_DN, sizeof TA139_DN, BR_EC_secp384r1, (unsigned char *)TA139_EC_Q, sizeof TA139_EC_Q); + trust_anchors[140] = make_ec_trust_anchor((unsigned char *)TA140_DN, sizeof TA140_DN, BR_EC_secp384r1, (unsigned char *)TA140_EC_Q, sizeof TA140_EC_Q); + trust_anchors[141] = make_rsa_trust_anchor((unsigned char *)TA141_DN, sizeof TA141_DN, (unsigned char *)TA141_RSA_N, sizeof TA141_RSA_N, (unsigned char *)TA141_RSA_E, sizeof TA141_RSA_E); + trust_anchors[142] = make_rsa_trust_anchor((unsigned char *)TA142_DN, sizeof TA142_DN, (unsigned char *)TA142_RSA_N, sizeof TA142_RSA_N, (unsigned char *)TA142_RSA_E, sizeof TA142_RSA_E); + trust_anchors[143] = make_ec_trust_anchor((unsigned char *)TA143_DN, sizeof TA143_DN, BR_EC_secp384r1, (unsigned char *)TA143_EC_Q, sizeof TA143_EC_Q); + trust_anchors[144] = make_rsa_trust_anchor((unsigned char *)TA144_DN, sizeof TA144_DN, (unsigned char *)TA144_RSA_N, sizeof TA144_RSA_N, (unsigned char *)TA144_RSA_E, sizeof TA144_RSA_E); + trust_anchors[145] = make_ec_trust_anchor((unsigned char *)TA145_DN, sizeof TA145_DN, BR_EC_secp384r1, (unsigned char *)TA145_EC_Q, sizeof TA145_EC_Q); + trust_anchors[146] = make_ec_trust_anchor((unsigned char *)TA146_DN, sizeof TA146_DN, BR_EC_secp384r1, (unsigned char *)TA146_EC_Q, sizeof TA146_EC_Q); + trust_anchors[147] = make_ec_trust_anchor((unsigned char *)TA147_DN, sizeof TA147_DN, BR_EC_secp256r1, (unsigned char *)TA147_EC_Q, sizeof TA147_EC_Q); + trust_anchors[148] = make_rsa_trust_anchor((unsigned char *)TA148_DN, sizeof TA148_DN, (unsigned char *)TA148_RSA_N, sizeof TA148_RSA_N, (unsigned char *)TA148_RSA_E, sizeof TA148_RSA_E); + trust_anchors[149] = make_rsa_trust_anchor((unsigned char *)TA149_DN, sizeof TA149_DN, (unsigned char *)TA149_RSA_N, sizeof TA149_RSA_N, (unsigned char *)TA149_RSA_E, sizeof TA149_RSA_E); + trust_anchors[150] = make_rsa_trust_anchor((unsigned char *)TA150_DN, sizeof TA150_DN, (unsigned char *)TA150_RSA_N, sizeof TA150_RSA_N, (unsigned char *)TA150_RSA_E, sizeof TA150_RSA_E); + trust_anchors[151] = make_ec_trust_anchor((unsigned char *)TA151_DN, sizeof TA151_DN, BR_EC_secp384r1, (unsigned char *)TA151_EC_Q, sizeof TA151_EC_Q); + trust_anchors[152] = make_rsa_trust_anchor((unsigned char *)TA152_DN, sizeof TA152_DN, (unsigned char *)TA152_RSA_N, sizeof TA152_RSA_N, (unsigned char *)TA152_RSA_E, sizeof TA152_RSA_E); + trust_anchors[153] = make_ec_trust_anchor((unsigned char *)TA153_DN, sizeof TA153_DN, BR_EC_secp384r1, (unsigned char *)TA153_EC_Q, sizeof TA153_EC_Q); + trust_anchors[154] = make_rsa_trust_anchor((unsigned char *)TA154_DN, sizeof TA154_DN, (unsigned char *)TA154_RSA_N, sizeof TA154_RSA_N, (unsigned char *)TA154_RSA_E, sizeof TA154_RSA_E); + trust_anchors[155] = make_rsa_trust_anchor((unsigned char *)TA155_DN, sizeof TA155_DN, (unsigned char *)TA155_RSA_N, sizeof TA155_RSA_N, (unsigned char *)TA155_RSA_E, sizeof TA155_RSA_E); + trust_anchors[156] = make_rsa_trust_anchor((unsigned char *)TA156_DN, sizeof TA156_DN, (unsigned char *)TA156_RSA_N, sizeof TA156_RSA_N, (unsigned char *)TA156_RSA_E, sizeof TA156_RSA_E); + trust_anchors[157] = make_rsa_trust_anchor((unsigned char *)TA157_DN, sizeof TA157_DN, (unsigned char *)TA157_RSA_N, sizeof TA157_RSA_N, (unsigned char *)TA157_RSA_E, sizeof TA157_RSA_E); + trust_anchors[158] = make_rsa_trust_anchor((unsigned char *)TA158_DN, sizeof TA158_DN, (unsigned char *)TA158_RSA_N, sizeof TA158_RSA_N, (unsigned char *)TA158_RSA_E, sizeof TA158_RSA_E); + trust_anchors[159] = make_rsa_trust_anchor((unsigned char *)TA159_DN, sizeof TA159_DN, (unsigned char *)TA159_RSA_N, sizeof TA159_RSA_N, (unsigned char *)TA159_RSA_E, sizeof TA159_RSA_E); + trust_anchors[160] = make_rsa_trust_anchor((unsigned char *)TA160_DN, sizeof TA160_DN, (unsigned char *)TA160_RSA_N, sizeof TA160_RSA_N, (unsigned char *)TA160_RSA_E, sizeof TA160_RSA_E); + trust_anchors[161] = make_ec_trust_anchor((unsigned char *)TA161_DN, sizeof TA161_DN, BR_EC_secp384r1, (unsigned char *)TA161_EC_Q, sizeof TA161_EC_Q); + trust_anchors[162] = make_ec_trust_anchor((unsigned char *)TA162_DN, sizeof TA162_DN, BR_EC_secp384r1, (unsigned char *)TA162_EC_Q, sizeof TA162_EC_Q); + trust_anchors[163] = make_rsa_trust_anchor((unsigned char *)TA163_DN, sizeof TA163_DN, (unsigned char *)TA163_RSA_N, sizeof TA163_RSA_N, (unsigned char *)TA163_RSA_E, sizeof TA163_RSA_E); + trust_anchors[164] = make_rsa_trust_anchor((unsigned char *)TA164_DN, sizeof TA164_DN, (unsigned char *)TA164_RSA_N, sizeof TA164_RSA_N, (unsigned char *)TA164_RSA_E, sizeof TA164_RSA_E); + trust_anchors[165] = make_rsa_trust_anchor((unsigned char *)TA165_DN, sizeof TA165_DN, (unsigned char *)TA165_RSA_N, sizeof TA165_RSA_N, (unsigned char *)TA165_RSA_E, sizeof TA165_RSA_E); + trust_anchors[166] = make_ec_trust_anchor((unsigned char *)TA166_DN, sizeof TA166_DN, BR_EC_secp384r1, (unsigned char *)TA166_EC_Q, sizeof TA166_EC_Q); + trust_anchors[167] = make_rsa_trust_anchor((unsigned char *)TA167_DN, sizeof TA167_DN, (unsigned char *)TA167_RSA_N, sizeof TA167_RSA_N, (unsigned char *)TA167_RSA_E, sizeof TA167_RSA_E); + trust_anchors[168] = make_rsa_trust_anchor((unsigned char *)TA168_DN, sizeof TA168_DN, (unsigned char *)TA168_RSA_N, sizeof TA168_RSA_N, (unsigned char *)TA168_RSA_E, sizeof TA168_RSA_E); + trust_anchors[169] = make_rsa_trust_anchor((unsigned char *)TA169_DN, sizeof TA169_DN, (unsigned char *)TA169_RSA_N, sizeof TA169_RSA_N, (unsigned char *)TA169_RSA_E, sizeof TA169_RSA_E); + trust_anchors[170] = make_rsa_trust_anchor((unsigned char *)TA170_DN, sizeof TA170_DN, (unsigned char *)TA170_RSA_N, sizeof TA170_RSA_N, (unsigned char *)TA170_RSA_E, sizeof TA170_RSA_E); + trust_anchors[171] = make_ec_trust_anchor((unsigned char *)TA171_DN, sizeof TA171_DN, BR_EC_secp384r1, (unsigned char *)TA171_EC_Q, sizeof TA171_EC_Q); + trust_anchors[172] = make_rsa_trust_anchor((unsigned char *)TA172_DN, sizeof TA172_DN, (unsigned char *)TA172_RSA_N, sizeof TA172_RSA_N, (unsigned char *)TA172_RSA_E, sizeof TA172_RSA_E); + trust_anchors[173] = make_ec_trust_anchor((unsigned char *)TA173_DN, sizeof TA173_DN, BR_EC_secp256r1, (unsigned char *)TA173_EC_Q, sizeof TA173_EC_Q); + trust_anchors[174] = make_rsa_trust_anchor((unsigned char *)TA174_DN, sizeof TA174_DN, (unsigned char *)TA174_RSA_N, sizeof TA174_RSA_N, (unsigned char *)TA174_RSA_E, sizeof TA174_RSA_E); + trust_anchors[175] = make_ec_trust_anchor((unsigned char *)TA175_DN, sizeof TA175_DN, BR_EC_secp384r1, (unsigned char *)TA175_EC_Q, sizeof TA175_EC_Q); + trust_anchors[176] = make_rsa_trust_anchor((unsigned char *)TA176_DN, sizeof TA176_DN, (unsigned char *)TA176_RSA_N, sizeof TA176_RSA_N, (unsigned char *)TA176_RSA_E, sizeof TA176_RSA_E); + trust_anchors[177] = make_rsa_trust_anchor((unsigned char *)TA177_DN, sizeof TA177_DN, (unsigned char *)TA177_RSA_N, sizeof TA177_RSA_N, (unsigned char *)TA177_RSA_E, sizeof TA177_RSA_E); + trust_anchors[178] = make_ec_trust_anchor((unsigned char *)TA178_DN, sizeof TA178_DN, BR_EC_secp384r1, (unsigned char *)TA178_EC_Q, sizeof TA178_EC_Q); + trust_anchors[179] = make_rsa_trust_anchor((unsigned char *)TA179_DN, sizeof TA179_DN, (unsigned char *)TA179_RSA_N, sizeof TA179_RSA_N, (unsigned char *)TA179_RSA_E, sizeof TA179_RSA_E); + trust_anchors[180] = make_rsa_trust_anchor((unsigned char *)TA180_DN, sizeof TA180_DN, (unsigned char *)TA180_RSA_N, sizeof TA180_RSA_N, (unsigned char *)TA180_RSA_E, sizeof TA180_RSA_E); + trust_anchors[181] = make_rsa_trust_anchor((unsigned char *)TA181_DN, sizeof TA181_DN, (unsigned char *)TA181_RSA_N, sizeof TA181_RSA_N, (unsigned char *)TA181_RSA_E, sizeof TA181_RSA_E); + trust_anchors[182] = make_ec_trust_anchor((unsigned char *)TA182_DN, sizeof TA182_DN, BR_EC_secp384r1, (unsigned char *)TA182_EC_Q, sizeof TA182_EC_Q); + trust_anchors[183] = make_ec_trust_anchor((unsigned char *)TA183_DN, sizeof TA183_DN, BR_EC_secp384r1, (unsigned char *)TA183_EC_Q, sizeof TA183_EC_Q); + trust_anchors[184] = make_rsa_trust_anchor((unsigned char *)TA184_DN, sizeof TA184_DN, (unsigned char *)TA184_RSA_N, sizeof TA184_RSA_N, (unsigned char *)TA184_RSA_E, sizeof TA184_RSA_E); + trust_anchors[185] = make_rsa_trust_anchor((unsigned char *)TA185_DN, sizeof TA185_DN, (unsigned char *)TA185_RSA_N, sizeof TA185_RSA_N, (unsigned char *)TA185_RSA_E, sizeof TA185_RSA_E); + trust_anchors[186] = make_rsa_trust_anchor((unsigned char *)TA186_DN, sizeof TA186_DN, (unsigned char *)TA186_RSA_N, sizeof TA186_RSA_N, (unsigned char *)TA186_RSA_E, sizeof TA186_RSA_E); + trust_anchors[187] = make_rsa_trust_anchor((unsigned char *)TA187_DN, sizeof TA187_DN, (unsigned char *)TA187_RSA_N, sizeof TA187_RSA_N, (unsigned char *)TA187_RSA_E, sizeof TA187_RSA_E); + trust_anchors[188] = make_rsa_trust_anchor((unsigned char *)TA188_DN, sizeof TA188_DN, (unsigned char *)TA188_RSA_N, sizeof TA188_RSA_N, (unsigned char *)TA188_RSA_E, sizeof TA188_RSA_E); + trust_anchors[189] = make_rsa_trust_anchor((unsigned char *)TA189_DN, sizeof TA189_DN, (unsigned char *)TA189_RSA_N, sizeof TA189_RSA_N, (unsigned char *)TA189_RSA_E, sizeof TA189_RSA_E); + trust_anchors[190] = make_rsa_trust_anchor((unsigned char *)TA190_DN, sizeof TA190_DN, (unsigned char *)TA190_RSA_N, sizeof TA190_RSA_N, (unsigned char *)TA190_RSA_E, sizeof TA190_RSA_E); + trust_anchors[191] = make_ec_trust_anchor((unsigned char *)TA191_DN, sizeof TA191_DN, BR_EC_secp384r1, (unsigned char *)TA191_EC_Q, sizeof TA191_EC_Q); + trust_anchors[192] = make_rsa_trust_anchor((unsigned char *)TA192_DN, sizeof TA192_DN, (unsigned char *)TA192_RSA_N, sizeof TA192_RSA_N, (unsigned char *)TA192_RSA_E, sizeof TA192_RSA_E); + trust_anchors[193] = make_rsa_trust_anchor((unsigned char *)TA193_DN, sizeof TA193_DN, (unsigned char *)TA193_RSA_N, sizeof TA193_RSA_N, (unsigned char *)TA193_RSA_E, sizeof TA193_RSA_E); + trust_anchors[194] = make_rsa_trust_anchor((unsigned char *)TA194_DN, sizeof TA194_DN, (unsigned char *)TA194_RSA_N, sizeof TA194_RSA_N, (unsigned char *)TA194_RSA_E, sizeof TA194_RSA_E); + trust_anchors[195] = make_rsa_trust_anchor((unsigned char *)TA195_DN, sizeof TA195_DN, (unsigned char *)TA195_RSA_N, sizeof TA195_RSA_N, (unsigned char *)TA195_RSA_E, sizeof TA195_RSA_E); + trust_anchors[196] = make_ec_trust_anchor((unsigned char *)TA196_DN, sizeof TA196_DN, BR_EC_secp384r1, (unsigned char *)TA196_EC_Q, sizeof TA196_EC_Q); + trust_anchors[197] = make_rsa_trust_anchor((unsigned char *)TA197_DN, sizeof TA197_DN, (unsigned char *)TA197_RSA_N, sizeof TA197_RSA_N, (unsigned char *)TA197_RSA_E, sizeof TA197_RSA_E); + trust_anchors[198] = make_rsa_trust_anchor((unsigned char *)TA198_DN, sizeof TA198_DN, (unsigned char *)TA198_RSA_N, sizeof TA198_RSA_N, (unsigned char *)TA198_RSA_E, sizeof TA198_RSA_E); + trust_anchors[199] = make_rsa_trust_anchor((unsigned char *)TA199_DN, sizeof TA199_DN, (unsigned char *)TA199_RSA_N, sizeof TA199_RSA_N, (unsigned char *)TA199_RSA_E, sizeof TA199_RSA_E); + trust_anchors[200] = make_ec_trust_anchor((unsigned char *)TA200_DN, sizeof TA200_DN, BR_EC_secp256r1, (unsigned char *)TA200_EC_Q, sizeof TA200_EC_Q); + trust_anchors[201] = make_ec_trust_anchor((unsigned char *)TA201_DN, sizeof TA201_DN, BR_EC_secp384r1, (unsigned char *)TA201_EC_Q, sizeof TA201_EC_Q); + trust_anchors[202] = make_rsa_trust_anchor((unsigned char *)TA202_DN, sizeof TA202_DN, (unsigned char *)TA202_RSA_N, sizeof TA202_RSA_N, (unsigned char *)TA202_RSA_E, sizeof TA202_RSA_E); + trust_anchors[203] = make_rsa_trust_anchor((unsigned char *)TA203_DN, sizeof TA203_DN, (unsigned char *)TA203_RSA_N, sizeof TA203_RSA_N, (unsigned char *)TA203_RSA_E, sizeof TA203_RSA_E); + trust_anchors[204] = make_ec_trust_anchor((unsigned char *)TA204_DN, sizeof TA204_DN, BR_EC_secp384r1, (unsigned char *)TA204_EC_Q, sizeof TA204_EC_Q); + trust_anchors[205] = make_rsa_trust_anchor((unsigned char *)TA205_DN, sizeof TA205_DN, (unsigned char *)TA205_RSA_N, sizeof TA205_RSA_N, (unsigned char *)TA205_RSA_E, sizeof TA205_RSA_E); + trust_anchors[206] = make_rsa_trust_anchor((unsigned char *)TA206_DN, sizeof TA206_DN, (unsigned char *)TA206_RSA_N, sizeof TA206_RSA_N, (unsigned char *)TA206_RSA_E, sizeof TA206_RSA_E); + trust_anchors[207] = make_ec_trust_anchor((unsigned char *)TA207_DN, sizeof TA207_DN, BR_EC_secp256r1, (unsigned char *)TA207_EC_Q, sizeof TA207_EC_Q); + trust_anchors[208] = make_rsa_trust_anchor((unsigned char *)TA208_DN, sizeof TA208_DN, (unsigned char *)TA208_RSA_N, sizeof TA208_RSA_N, (unsigned char *)TA208_RSA_E, sizeof TA208_RSA_E); + trust_anchors[209] = make_rsa_trust_anchor((unsigned char *)TA209_DN, sizeof TA209_DN, (unsigned char *)TA209_RSA_N, sizeof TA209_RSA_N, (unsigned char *)TA209_RSA_E, sizeof TA209_RSA_E); + trust_anchors[210] = make_rsa_trust_anchor((unsigned char *)TA210_DN, sizeof TA210_DN, (unsigned char *)TA210_RSA_N, sizeof TA210_RSA_N, (unsigned char *)TA210_RSA_E, sizeof TA210_RSA_E); + trust_anchors[211] = make_ec_trust_anchor((unsigned char *)TA211_DN, sizeof TA211_DN, BR_EC_secp384r1, (unsigned char *)TA211_EC_Q, sizeof TA211_EC_Q); + trust_anchors[212] = make_ec_trust_anchor((unsigned char *)TA212_DN, sizeof TA212_DN, BR_EC_secp384r1, (unsigned char *)TA212_EC_Q, sizeof TA212_EC_Q); + trust_anchors[213] = make_rsa_trust_anchor((unsigned char *)TA213_DN, sizeof TA213_DN, (unsigned char *)TA213_RSA_N, sizeof TA213_RSA_N, (unsigned char *)TA213_RSA_E, sizeof TA213_RSA_E); + trust_anchors[214] = make_rsa_trust_anchor((unsigned char *)TA214_DN, sizeof TA214_DN, (unsigned char *)TA214_RSA_N, sizeof TA214_RSA_N, (unsigned char *)TA214_RSA_E, sizeof TA214_RSA_E); + trust_anchors[215] = make_rsa_trust_anchor((unsigned char *)TA215_DN, sizeof TA215_DN, (unsigned char *)TA215_RSA_N, sizeof TA215_RSA_N, (unsigned char *)TA215_RSA_E, sizeof TA215_RSA_E); + trust_anchors[216] = make_ec_trust_anchor((unsigned char *)TA216_DN, sizeof TA216_DN, BR_EC_secp256r1, (unsigned char *)TA216_EC_Q, sizeof TA216_EC_Q); + trust_anchors[217] = make_rsa_trust_anchor((unsigned char *)TA217_DN, sizeof TA217_DN, (unsigned char *)TA217_RSA_N, sizeof TA217_RSA_N, (unsigned char *)TA217_RSA_E, sizeof TA217_RSA_E); + trust_anchors[218] = make_rsa_trust_anchor((unsigned char *)TA218_DN, sizeof TA218_DN, (unsigned char *)TA218_RSA_N, sizeof TA218_RSA_N, (unsigned char *)TA218_RSA_E, sizeof TA218_RSA_E); + trust_anchors[219] = make_ec_trust_anchor((unsigned char *)TA219_DN, sizeof TA219_DN, BR_EC_secp384r1, (unsigned char *)TA219_EC_Q, sizeof TA219_EC_Q); + trust_anchors[220] = make_rsa_trust_anchor((unsigned char *)TA220_DN, sizeof TA220_DN, (unsigned char *)TA220_RSA_N, sizeof TA220_RSA_N, (unsigned char *)TA220_RSA_E, sizeof TA220_RSA_E); + trust_anchors[221] = make_rsa_trust_anchor((unsigned char *)TA221_DN, sizeof TA221_DN, (unsigned char *)TA221_RSA_N, sizeof TA221_RSA_N, (unsigned char *)TA221_RSA_E, sizeof TA221_RSA_E); + trust_anchors[222] = make_rsa_trust_anchor((unsigned char *)TA222_DN, sizeof TA222_DN, (unsigned char *)TA222_RSA_N, sizeof TA222_RSA_N, (unsigned char *)TA222_RSA_E, sizeof TA222_RSA_E); + trust_anchors[223] = make_rsa_trust_anchor((unsigned char *)TA223_DN, sizeof TA223_DN, (unsigned char *)TA223_RSA_N, sizeof TA223_RSA_N, (unsigned char *)TA223_RSA_E, sizeof TA223_RSA_E); + trust_anchors[224] = make_ec_trust_anchor((unsigned char *)TA224_DN, sizeof TA224_DN, BR_EC_secp384r1, (unsigned char *)TA224_EC_Q, sizeof TA224_EC_Q); + trust_anchors[225] = make_rsa_trust_anchor((unsigned char *)TA225_DN, sizeof TA225_DN, (unsigned char *)TA225_RSA_N, sizeof TA225_RSA_N, (unsigned char *)TA225_RSA_E, sizeof TA225_RSA_E); + trust_anchors[226] = make_rsa_trust_anchor((unsigned char *)TA226_DN, sizeof TA226_DN, (unsigned char *)TA226_RSA_N, sizeof TA226_RSA_N, (unsigned char *)TA226_RSA_E, sizeof TA226_RSA_E); + trust_anchors[227] = make_rsa_trust_anchor((unsigned char *)TA227_DN, sizeof TA227_DN, (unsigned char *)TA227_RSA_N, sizeof TA227_RSA_N, (unsigned char *)TA227_RSA_E, sizeof TA227_RSA_E); + trust_anchors[228] = make_rsa_trust_anchor((unsigned char *)TA228_DN, sizeof TA228_DN, (unsigned char *)TA228_RSA_N, sizeof TA228_RSA_N, (unsigned char *)TA228_RSA_E, sizeof TA228_RSA_E); + trust_anchors[229] = make_rsa_trust_anchor((unsigned char *)TA229_DN, sizeof TA229_DN, (unsigned char *)TA229_RSA_N, sizeof TA229_RSA_N, (unsigned char *)TA229_RSA_E, sizeof TA229_RSA_E); + trust_anchors[230] = make_rsa_trust_anchor((unsigned char *)TA230_DN, sizeof TA230_DN, (unsigned char *)TA230_RSA_N, sizeof TA230_RSA_N, (unsigned char *)TA230_RSA_E, sizeof TA230_RSA_E); + trust_anchors[231] = make_rsa_trust_anchor((unsigned char *)TA231_DN, sizeof TA231_DN, (unsigned char *)TA231_RSA_N, sizeof TA231_RSA_N, (unsigned char *)TA231_RSA_E, sizeof TA231_RSA_E); + trust_anchors[232] = make_ec_trust_anchor((unsigned char *)TA232_DN, sizeof TA232_DN, BR_EC_secp384r1, (unsigned char *)TA232_EC_Q, sizeof TA232_EC_Q); + trust_anchors[233] = make_rsa_trust_anchor((unsigned char *)TA233_DN, sizeof TA233_DN, (unsigned char *)TA233_RSA_N, sizeof TA233_RSA_N, (unsigned char *)TA233_RSA_E, sizeof TA233_RSA_E); + trust_anchors[234] = make_rsa_trust_anchor((unsigned char *)TA234_DN, sizeof TA234_DN, (unsigned char *)TA234_RSA_N, sizeof TA234_RSA_N, (unsigned char *)TA234_RSA_E, sizeof TA234_RSA_E); + trust_anchors[235] = make_rsa_trust_anchor((unsigned char *)TA235_DN, sizeof TA235_DN, (unsigned char *)TA235_RSA_N, sizeof TA235_RSA_N, (unsigned char *)TA235_RSA_E, sizeof TA235_RSA_E); + trust_anchors[236] = make_rsa_trust_anchor((unsigned char *)TA236_DN, sizeof TA236_DN, (unsigned char *)TA236_RSA_N, sizeof TA236_RSA_N, (unsigned char *)TA236_RSA_E, sizeof TA236_RSA_E); + trust_anchors[237] = make_rsa_trust_anchor((unsigned char *)TA237_DN, sizeof TA237_DN, (unsigned char *)TA237_RSA_N, sizeof TA237_RSA_N, (unsigned char *)TA237_RSA_E, sizeof TA237_RSA_E); + trust_anchors[238] = make_ec_trust_anchor((unsigned char *)TA238_DN, sizeof TA238_DN, BR_EC_secp384r1, (unsigned char *)TA238_EC_Q, sizeof TA238_EC_Q); + trust_anchors[239] = make_rsa_trust_anchor((unsigned char *)TA239_DN, sizeof TA239_DN, (unsigned char *)TA239_RSA_N, sizeof TA239_RSA_N, (unsigned char *)TA239_RSA_E, sizeof TA239_RSA_E); + trust_anchors[240] = make_ec_trust_anchor((unsigned char *)TA240_DN, sizeof TA240_DN, BR_EC_secp384r1, (unsigned char *)TA240_EC_Q, sizeof TA240_EC_Q); + trust_anchors[241] = make_rsa_trust_anchor((unsigned char *)TA241_DN, sizeof TA241_DN, (unsigned char *)TA241_RSA_N, sizeof TA241_RSA_N, (unsigned char *)TA241_RSA_E, sizeof TA241_RSA_E); + trust_anchors[242] = make_rsa_trust_anchor((unsigned char *)TA242_DN, sizeof TA242_DN, (unsigned char *)TA242_RSA_N, sizeof TA242_RSA_N, (unsigned char *)TA242_RSA_E, sizeof TA242_RSA_E); + trust_anchors[243] = make_rsa_trust_anchor((unsigned char *)TA243_DN, sizeof TA243_DN, (unsigned char *)TA243_RSA_N, sizeof TA243_RSA_N, (unsigned char *)TA243_RSA_E, sizeof TA243_RSA_E); + trust_anchors[244] = make_rsa_trust_anchor((unsigned char *)TA244_DN, sizeof TA244_DN, (unsigned char *)TA244_RSA_N, sizeof TA244_RSA_N, (unsigned char *)TA244_RSA_E, sizeof TA244_RSA_E); + trust_anchors[245] = make_ec_trust_anchor((unsigned char *)TA245_DN, sizeof TA245_DN, BR_EC_secp384r1, (unsigned char *)TA245_EC_Q, sizeof TA245_EC_Q); + trust_anchors[246] = make_rsa_trust_anchor((unsigned char *)TA246_DN, sizeof TA246_DN, (unsigned char *)TA246_RSA_N, sizeof TA246_RSA_N, (unsigned char *)TA246_RSA_E, sizeof TA246_RSA_E); + trust_anchors[247] = make_rsa_trust_anchor((unsigned char *)TA247_DN, sizeof TA247_DN, (unsigned char *)TA247_RSA_N, sizeof TA247_RSA_N, (unsigned char *)TA247_RSA_E, sizeof TA247_RSA_E); + trust_anchors[248] = make_rsa_trust_anchor((unsigned char *)TA248_DN, sizeof TA248_DN, (unsigned char *)TA248_RSA_N, sizeof TA248_RSA_N, (unsigned char *)TA248_RSA_E, sizeof TA248_RSA_E); + trust_anchors[249] = make_rsa_trust_anchor((unsigned char *)TA249_DN, sizeof TA249_DN, (unsigned char *)TA249_RSA_N, sizeof TA249_RSA_N, (unsigned char *)TA249_RSA_E, sizeof TA249_RSA_E); + trust_anchors[250] = make_rsa_trust_anchor((unsigned char *)TA250_DN, sizeof TA250_DN, (unsigned char *)TA250_RSA_N, sizeof TA250_RSA_N, (unsigned char *)TA250_RSA_E, sizeof TA250_RSA_E); + trust_anchors[251] = make_ec_trust_anchor((unsigned char *)TA251_DN, sizeof TA251_DN, BR_EC_secp384r1, (unsigned char *)TA251_EC_Q, sizeof TA251_EC_Q); + trust_anchors[252] = make_rsa_trust_anchor((unsigned char *)TA252_DN, sizeof TA252_DN, (unsigned char *)TA252_RSA_N, sizeof TA252_RSA_N, (unsigned char *)TA252_RSA_E, sizeof TA252_RSA_E); + trust_anchors[253] = make_rsa_trust_anchor((unsigned char *)TA253_DN, sizeof TA253_DN, (unsigned char *)TA253_RSA_N, sizeof TA253_RSA_N, (unsigned char *)TA253_RSA_E, sizeof TA253_RSA_E); + trust_anchors[254] = make_ec_trust_anchor((unsigned char *)TA254_DN, sizeof TA254_DN, BR_EC_secp256r1, (unsigned char *)TA254_EC_Q, sizeof TA254_EC_Q); + trust_anchors[255] = make_ec_trust_anchor((unsigned char *)TA255_DN, sizeof TA255_DN, BR_EC_secp384r1, (unsigned char *)TA255_EC_Q, sizeof TA255_EC_Q); + trust_anchors[256] = make_rsa_trust_anchor((unsigned char *)TA256_DN, sizeof TA256_DN, (unsigned char *)TA256_RSA_N, sizeof TA256_RSA_N, (unsigned char *)TA256_RSA_E, sizeof TA256_RSA_E); + trust_anchors[257] = make_ec_trust_anchor((unsigned char *)TA257_DN, sizeof TA257_DN, BR_EC_secp384r1, (unsigned char *)TA257_EC_Q, sizeof TA257_EC_Q); + trust_anchors[258] = make_rsa_trust_anchor((unsigned char *)TA258_DN, sizeof TA258_DN, (unsigned char *)TA258_RSA_N, sizeof TA258_RSA_N, (unsigned char *)TA258_RSA_E, sizeof TA258_RSA_E); + trust_anchors[259] = make_rsa_trust_anchor((unsigned char *)TA259_DN, sizeof TA259_DN, (unsigned char *)TA259_RSA_N, sizeof TA259_RSA_N, (unsigned char *)TA259_RSA_E, sizeof TA259_RSA_E); + trust_anchors[260] = make_rsa_trust_anchor((unsigned char *)TA260_DN, sizeof TA260_DN, (unsigned char *)TA260_RSA_N, sizeof TA260_RSA_N, (unsigned char *)TA260_RSA_E, sizeof TA260_RSA_E); + trust_anchors[261] = make_ec_trust_anchor((unsigned char *)TA261_DN, sizeof TA261_DN, BR_EC_secp384r1, (unsigned char *)TA261_EC_Q, sizeof TA261_EC_Q); + trust_anchors[262] = make_rsa_trust_anchor((unsigned char *)TA262_DN, sizeof TA262_DN, (unsigned char *)TA262_RSA_N, sizeof TA262_RSA_N, (unsigned char *)TA262_RSA_E, sizeof TA262_RSA_E); + trust_anchors[263] = make_rsa_trust_anchor((unsigned char *)TA263_DN, sizeof TA263_DN, (unsigned char *)TA263_RSA_N, sizeof TA263_RSA_N, (unsigned char *)TA263_RSA_E, sizeof TA263_RSA_E); + trust_anchors[264] = make_rsa_trust_anchor((unsigned char *)TA264_DN, sizeof TA264_DN, (unsigned char *)TA264_RSA_N, sizeof TA264_RSA_N, (unsigned char *)TA264_RSA_E, sizeof TA264_RSA_E); + trust_anchors[265] = make_rsa_trust_anchor((unsigned char *)TA265_DN, sizeof TA265_DN, (unsigned char *)TA265_RSA_N, sizeof TA265_RSA_N, (unsigned char *)TA265_RSA_E, sizeof TA265_RSA_E); + trust_anchors[266] = make_rsa_trust_anchor((unsigned char *)TA266_DN, sizeof TA266_DN, (unsigned char *)TA266_RSA_N, sizeof TA266_RSA_N, (unsigned char *)TA266_RSA_E, sizeof TA266_RSA_E); + trust_anchors[267] = make_rsa_trust_anchor((unsigned char *)TA267_DN, sizeof TA267_DN, (unsigned char *)TA267_RSA_N, sizeof TA267_RSA_N, (unsigned char *)TA267_RSA_E, sizeof TA267_RSA_E); + trust_anchors[268] = make_ec_trust_anchor((unsigned char *)TA268_DN, sizeof TA268_DN, BR_EC_secp384r1, (unsigned char *)TA268_EC_Q, sizeof TA268_EC_Q); + trust_anchors[269] = make_rsa_trust_anchor((unsigned char *)TA269_DN, sizeof TA269_DN, (unsigned char *)TA269_RSA_N, sizeof TA269_RSA_N, (unsigned char *)TA269_RSA_E, sizeof TA269_RSA_E); + trust_anchors[270] = make_ec_trust_anchor((unsigned char *)TA270_DN, sizeof TA270_DN, BR_EC_secp384r1, (unsigned char *)TA270_EC_Q, sizeof TA270_EC_Q); + trust_anchors[271] = make_rsa_trust_anchor((unsigned char *)TA271_DN, sizeof TA271_DN, (unsigned char *)TA271_RSA_N, sizeof TA271_RSA_N, (unsigned char *)TA271_RSA_E, sizeof TA271_RSA_E); + trust_anchors[272] = make_rsa_trust_anchor((unsigned char *)TA272_DN, sizeof TA272_DN, (unsigned char *)TA272_RSA_N, sizeof TA272_RSA_N, (unsigned char *)TA272_RSA_E, sizeof TA272_RSA_E); + trust_anchors[273] = make_rsa_trust_anchor((unsigned char *)TA273_DN, sizeof TA273_DN, (unsigned char *)TA273_RSA_N, sizeof TA273_RSA_N, (unsigned char *)TA273_RSA_E, sizeof TA273_RSA_E); + trust_anchors[274] = make_ec_trust_anchor((unsigned char *)TA274_DN, sizeof TA274_DN, BR_EC_secp384r1, (unsigned char *)TA274_EC_Q, sizeof TA274_EC_Q); + trust_anchors[275] = make_rsa_trust_anchor((unsigned char *)TA275_DN, sizeof TA275_DN, (unsigned char *)TA275_RSA_N, sizeof TA275_RSA_N, (unsigned char *)TA275_RSA_E, sizeof TA275_RSA_E); + trust_anchors[276] = make_rsa_trust_anchor((unsigned char *)TA276_DN, sizeof TA276_DN, (unsigned char *)TA276_RSA_N, sizeof TA276_RSA_N, (unsigned char *)TA276_RSA_E, sizeof TA276_RSA_E); + trust_anchors[277] = make_rsa_trust_anchor((unsigned char *)TA277_DN, sizeof TA277_DN, (unsigned char *)TA277_RSA_N, sizeof TA277_RSA_N, (unsigned char *)TA277_RSA_E, sizeof TA277_RSA_E); + trust_anchors[278] = make_ec_trust_anchor((unsigned char *)TA278_DN, sizeof TA278_DN, BR_EC_secp384r1, (unsigned char *)TA278_EC_Q, sizeof TA278_EC_Q); + trust_anchors[279] = make_ec_trust_anchor((unsigned char *)TA279_DN, sizeof TA279_DN, BR_EC_secp384r1, (unsigned char *)TA279_EC_Q, sizeof TA279_EC_Q); + trust_anchors[280] = make_rsa_trust_anchor((unsigned char *)TA280_DN, sizeof TA280_DN, (unsigned char *)TA280_RSA_N, sizeof TA280_RSA_N, (unsigned char *)TA280_RSA_E, sizeof TA280_RSA_E); + trust_anchors[281] = make_rsa_trust_anchor((unsigned char *)TA281_DN, sizeof TA281_DN, (unsigned char *)TA281_RSA_N, sizeof TA281_RSA_N, (unsigned char *)TA281_RSA_E, sizeof TA281_RSA_E); + trust_anchors[282] = make_rsa_trust_anchor((unsigned char *)TA282_DN, sizeof TA282_DN, (unsigned char *)TA282_RSA_N, sizeof TA282_RSA_N, (unsigned char *)TA282_RSA_E, sizeof TA282_RSA_E); + trust_anchors[283] = make_ec_trust_anchor((unsigned char *)TA283_DN, sizeof TA283_DN, BR_EC_secp384r1, (unsigned char *)TA283_EC_Q, sizeof TA283_EC_Q); + trust_anchors[284] = make_rsa_trust_anchor((unsigned char *)TA284_DN, sizeof TA284_DN, (unsigned char *)TA284_RSA_N, sizeof TA284_RSA_N, (unsigned char *)TA284_RSA_E, sizeof TA284_RSA_E); + trust_anchors[285] = make_ec_trust_anchor((unsigned char *)TA285_DN, sizeof TA285_DN, BR_EC_secp384r1, (unsigned char *)TA285_EC_Q, sizeof TA285_EC_Q); + trust_anchors[286] = make_rsa_trust_anchor((unsigned char *)TA286_DN, sizeof TA286_DN, (unsigned char *)TA286_RSA_N, sizeof TA286_RSA_N, (unsigned char *)TA286_RSA_E, sizeof TA286_RSA_E); + trust_anchors[287] = make_rsa_trust_anchor((unsigned char *)TA287_DN, sizeof TA287_DN, (unsigned char *)TA287_RSA_N, sizeof TA287_RSA_N, (unsigned char *)TA287_RSA_E, sizeof TA287_RSA_E); + trust_anchors[288] = make_rsa_trust_anchor((unsigned char *)TA288_DN, sizeof TA288_DN, (unsigned char *)TA288_RSA_N, sizeof TA288_RSA_N, (unsigned char *)TA288_RSA_E, sizeof TA288_RSA_E); + trust_anchors[289] = make_rsa_trust_anchor((unsigned char *)TA289_DN, sizeof TA289_DN, (unsigned char *)TA289_RSA_N, sizeof TA289_RSA_N, (unsigned char *)TA289_RSA_E, sizeof TA289_RSA_E); + trust_anchors[290] = make_rsa_trust_anchor((unsigned char *)TA290_DN, sizeof TA290_DN, (unsigned char *)TA290_RSA_N, sizeof TA290_RSA_N, (unsigned char *)TA290_RSA_E, sizeof TA290_RSA_E); + trust_anchors[291] = make_ec_trust_anchor((unsigned char *)TA291_DN, sizeof TA291_DN, BR_EC_secp384r1, (unsigned char *)TA291_EC_Q, sizeof TA291_EC_Q); + trust_anchors[292] = make_rsa_trust_anchor((unsigned char *)TA292_DN, sizeof TA292_DN, (unsigned char *)TA292_RSA_N, sizeof TA292_RSA_N, (unsigned char *)TA292_RSA_E, sizeof TA292_RSA_E); + trust_anchors[293] = make_rsa_trust_anchor((unsigned char *)TA293_DN, sizeof TA293_DN, (unsigned char *)TA293_RSA_N, sizeof TA293_RSA_N, (unsigned char *)TA293_RSA_E, sizeof TA293_RSA_E); + trust_anchors[294] = make_ec_trust_anchor((unsigned char *)TA294_DN, sizeof TA294_DN, BR_EC_secp384r1, (unsigned char *)TA294_EC_Q, sizeof TA294_EC_Q); + trust_anchors[295] = make_rsa_trust_anchor((unsigned char *)TA295_DN, sizeof TA295_DN, (unsigned char *)TA295_RSA_N, sizeof TA295_RSA_N, (unsigned char *)TA295_RSA_E, sizeof TA295_RSA_E); + trust_anchors[296] = make_ec_trust_anchor((unsigned char *)TA296_DN, sizeof TA296_DN, BR_EC_secp384r1, (unsigned char *)TA296_EC_Q, sizeof TA296_EC_Q); + trust_anchors[297] = make_rsa_trust_anchor((unsigned char *)TA297_DN, sizeof TA297_DN, (unsigned char *)TA297_RSA_N, sizeof TA297_RSA_N, (unsigned char *)TA297_RSA_E, sizeof TA297_RSA_E); + trust_anchors[298] = make_rsa_trust_anchor((unsigned char *)TA298_DN, sizeof TA298_DN, (unsigned char *)TA298_RSA_N, sizeof TA298_RSA_N, (unsigned char *)TA298_RSA_E, sizeof TA298_RSA_E); + trust_anchors[299] = make_rsa_trust_anchor((unsigned char *)TA299_DN, sizeof TA299_DN, (unsigned char *)TA299_RSA_N, sizeof TA299_RSA_N, (unsigned char *)TA299_RSA_E, sizeof TA299_RSA_E); + trust_anchors[300] = make_rsa_trust_anchor((unsigned char *)TA300_DN, sizeof TA300_DN, (unsigned char *)TA300_RSA_N, sizeof TA300_RSA_N, (unsigned char *)TA300_RSA_E, sizeof TA300_RSA_E); + trust_anchors[301] = make_ec_trust_anchor((unsigned char *)TA301_DN, sizeof TA301_DN, BR_EC_secp384r1, (unsigned char *)TA301_EC_Q, sizeof TA301_EC_Q); + trust_anchors[302] = make_rsa_trust_anchor((unsigned char *)TA302_DN, sizeof TA302_DN, (unsigned char *)TA302_RSA_N, sizeof TA302_RSA_N, (unsigned char *)TA302_RSA_E, sizeof TA302_RSA_E); + trust_anchors[303] = make_ec_trust_anchor((unsigned char *)TA303_DN, sizeof TA303_DN, BR_EC_secp384r1, (unsigned char *)TA303_EC_Q, sizeof TA303_EC_Q); + trust_anchors[304] = make_rsa_trust_anchor((unsigned char *)TA304_DN, sizeof TA304_DN, (unsigned char *)TA304_RSA_N, sizeof TA304_RSA_N, (unsigned char *)TA304_RSA_E, sizeof TA304_RSA_E); + trust_anchors[305] = make_rsa_trust_anchor((unsigned char *)TA305_DN, sizeof TA305_DN, (unsigned char *)TA305_RSA_N, sizeof TA305_RSA_N, (unsigned char *)TA305_RSA_E, sizeof TA305_RSA_E); + trust_anchors[306] = make_rsa_trust_anchor((unsigned char *)TA306_DN, sizeof TA306_DN, (unsigned char *)TA306_RSA_N, sizeof TA306_RSA_N, (unsigned char *)TA306_RSA_E, sizeof TA306_RSA_E); + trust_anchors[307] = make_rsa_trust_anchor((unsigned char *)TA307_DN, sizeof TA307_DN, (unsigned char *)TA307_RSA_N, sizeof TA307_RSA_N, (unsigned char *)TA307_RSA_E, sizeof TA307_RSA_E); + trust_anchors[308] = make_ec_trust_anchor((unsigned char *)TA308_DN, sizeof TA308_DN, BR_EC_secp384r1, (unsigned char *)TA308_EC_Q, sizeof TA308_EC_Q); + trust_anchors[309] = make_ec_trust_anchor((unsigned char *)TA309_DN, sizeof TA309_DN, BR_EC_secp384r1, (unsigned char *)TA309_EC_Q, sizeof TA309_EC_Q); + trust_anchors[310] = make_ec_trust_anchor((unsigned char *)TA310_DN, sizeof TA310_DN, BR_EC_secp256r1, (unsigned char *)TA310_EC_Q, sizeof TA310_EC_Q); + trust_anchors[311] = make_ec_trust_anchor((unsigned char *)TA311_DN, sizeof TA311_DN, BR_EC_secp384r1, (unsigned char *)TA311_EC_Q, sizeof TA311_EC_Q); + trust_anchors[312] = make_rsa_trust_anchor((unsigned char *)TA312_DN, sizeof TA312_DN, (unsigned char *)TA312_RSA_N, sizeof TA312_RSA_N, (unsigned char *)TA312_RSA_E, sizeof TA312_RSA_E); + trust_anchors[313] = make_rsa_trust_anchor((unsigned char *)TA313_DN, sizeof TA313_DN, (unsigned char *)TA313_RSA_N, sizeof TA313_RSA_N, (unsigned char *)TA313_RSA_E, sizeof TA313_RSA_E); + trust_anchors[314] = make_rsa_trust_anchor((unsigned char *)TA314_DN, sizeof TA314_DN, (unsigned char *)TA314_RSA_N, sizeof TA314_RSA_N, (unsigned char *)TA314_RSA_E, sizeof TA314_RSA_E); + trust_anchors[315] = make_ec_trust_anchor((unsigned char *)TA315_DN, sizeof TA315_DN, BR_EC_secp384r1, (unsigned char *)TA315_EC_Q, sizeof TA315_EC_Q); + trust_anchors[316] = make_rsa_trust_anchor((unsigned char *)TA316_DN, sizeof TA316_DN, (unsigned char *)TA316_RSA_N, sizeof TA316_RSA_N, (unsigned char *)TA316_RSA_E, sizeof TA316_RSA_E); + trust_anchors[317] = make_rsa_trust_anchor((unsigned char *)TA317_DN, sizeof TA317_DN, (unsigned char *)TA317_RSA_N, sizeof TA317_RSA_N, (unsigned char *)TA317_RSA_E, sizeof TA317_RSA_E); + trust_anchors[318] = make_rsa_trust_anchor((unsigned char *)TA318_DN, sizeof TA318_DN, (unsigned char *)TA318_RSA_N, sizeof TA318_RSA_N, (unsigned char *)TA318_RSA_E, sizeof TA318_RSA_E); + trust_anchors[319] = make_ec_trust_anchor((unsigned char *)TA319_DN, sizeof TA319_DN, BR_EC_secp384r1, (unsigned char *)TA319_EC_Q, sizeof TA319_EC_Q); + trust_anchors[320] = make_rsa_trust_anchor((unsigned char *)TA320_DN, sizeof TA320_DN, (unsigned char *)TA320_RSA_N, sizeof TA320_RSA_N, (unsigned char *)TA320_RSA_E, sizeof TA320_RSA_E); + trust_anchors[321] = make_ec_trust_anchor((unsigned char *)TA321_DN, sizeof TA321_DN, BR_EC_secp384r1, (unsigned char *)TA321_EC_Q, sizeof TA321_EC_Q); + trust_anchors[322] = make_rsa_trust_anchor((unsigned char *)TA322_DN, sizeof TA322_DN, (unsigned char *)TA322_RSA_N, sizeof TA322_RSA_N, (unsigned char *)TA322_RSA_E, sizeof TA322_RSA_E); + trust_anchors[323] = make_rsa_trust_anchor((unsigned char *)TA323_DN, sizeof TA323_DN, (unsigned char *)TA323_RSA_N, sizeof TA323_RSA_N, (unsigned char *)TA323_RSA_E, sizeof TA323_RSA_E); + trust_anchors[324] = make_rsa_trust_anchor((unsigned char *)TA324_DN, sizeof TA324_DN, (unsigned char *)TA324_RSA_N, sizeof TA324_RSA_N, (unsigned char *)TA324_RSA_E, sizeof TA324_RSA_E); + trust_anchors[325] = make_rsa_trust_anchor((unsigned char *)TA325_DN, sizeof TA325_DN, (unsigned char *)TA325_RSA_N, sizeof TA325_RSA_N, (unsigned char *)TA325_RSA_E, sizeof TA325_RSA_E); + trust_anchors[326] = make_ec_trust_anchor((unsigned char *)TA326_DN, sizeof TA326_DN, BR_EC_secp384r1, (unsigned char *)TA326_EC_Q, sizeof TA326_EC_Q); + trust_anchors[327] = make_rsa_trust_anchor((unsigned char *)TA327_DN, sizeof TA327_DN, (unsigned char *)TA327_RSA_N, sizeof TA327_RSA_N, (unsigned char *)TA327_RSA_E, sizeof TA327_RSA_E); + trust_anchors[328] = make_rsa_trust_anchor((unsigned char *)TA328_DN, sizeof TA328_DN, (unsigned char *)TA328_RSA_N, sizeof TA328_RSA_N, (unsigned char *)TA328_RSA_E, sizeof TA328_RSA_E); + trust_anchors[329] = make_rsa_trust_anchor((unsigned char *)TA329_DN, sizeof TA329_DN, (unsigned char *)TA329_RSA_N, sizeof TA329_RSA_N, (unsigned char *)TA329_RSA_E, sizeof TA329_RSA_E); + trust_anchors[330] = make_rsa_trust_anchor((unsigned char *)TA330_DN, sizeof TA330_DN, (unsigned char *)TA330_RSA_N, sizeof TA330_RSA_N, (unsigned char *)TA330_RSA_E, sizeof TA330_RSA_E); + trust_anchors[331] = make_ec_trust_anchor((unsigned char *)TA331_DN, sizeof TA331_DN, BR_EC_secp384r1, (unsigned char *)TA331_EC_Q, sizeof TA331_EC_Q); + trust_anchors[332] = make_rsa_trust_anchor((unsigned char *)TA332_DN, sizeof TA332_DN, (unsigned char *)TA332_RSA_N, sizeof TA332_RSA_N, (unsigned char *)TA332_RSA_E, sizeof TA332_RSA_E); + trust_anchors[333] = make_rsa_trust_anchor((unsigned char *)TA333_DN, sizeof TA333_DN, (unsigned char *)TA333_RSA_N, sizeof TA333_RSA_N, (unsigned char *)TA333_RSA_E, sizeof TA333_RSA_E); + trust_anchors[334] = make_rsa_trust_anchor((unsigned char *)TA334_DN, sizeof TA334_DN, (unsigned char *)TA334_RSA_N, sizeof TA334_RSA_N, (unsigned char *)TA334_RSA_E, sizeof TA334_RSA_E); + trust_anchors[335] = make_rsa_trust_anchor((unsigned char *)TA335_DN, sizeof TA335_DN, (unsigned char *)TA335_RSA_N, sizeof TA335_RSA_N, (unsigned char *)TA335_RSA_E, sizeof TA335_RSA_E); + trust_anchors[336] = make_ec_trust_anchor((unsigned char *)TA336_DN, sizeof TA336_DN, BR_EC_secp384r1, (unsigned char *)TA336_EC_Q, sizeof TA336_EC_Q); + trust_anchors[337] = make_rsa_trust_anchor((unsigned char *)TA337_DN, sizeof TA337_DN, (unsigned char *)TA337_RSA_N, sizeof TA337_RSA_N, (unsigned char *)TA337_RSA_E, sizeof TA337_RSA_E); + trust_anchors[338] = make_rsa_trust_anchor((unsigned char *)TA338_DN, sizeof TA338_DN, (unsigned char *)TA338_RSA_N, sizeof TA338_RSA_N, (unsigned char *)TA338_RSA_E, sizeof TA338_RSA_E); + trust_anchors[339] = make_rsa_trust_anchor((unsigned char *)TA339_DN, sizeof TA339_DN, (unsigned char *)TA339_RSA_N, sizeof TA339_RSA_N, (unsigned char *)TA339_RSA_E, sizeof TA339_RSA_E); + trust_anchors[340] = make_rsa_trust_anchor((unsigned char *)TA340_DN, sizeof TA340_DN, (unsigned char *)TA340_RSA_N, sizeof TA340_RSA_N, (unsigned char *)TA340_RSA_E, sizeof TA340_RSA_E); + trust_anchors[341] = make_rsa_trust_anchor((unsigned char *)TA341_DN, sizeof TA341_DN, (unsigned char *)TA341_RSA_N, sizeof TA341_RSA_N, (unsigned char *)TA341_RSA_E, sizeof TA341_RSA_E); + trust_anchors[342] = make_ec_trust_anchor((unsigned char *)TA342_DN, sizeof TA342_DN, BR_EC_secp384r1, (unsigned char *)TA342_EC_Q, sizeof TA342_EC_Q); + trust_anchors[343] = make_rsa_trust_anchor((unsigned char *)TA343_DN, sizeof TA343_DN, (unsigned char *)TA343_RSA_N, sizeof TA343_RSA_N, (unsigned char *)TA343_RSA_E, sizeof TA343_RSA_E); + trust_anchors[344] = make_ec_trust_anchor((unsigned char *)TA344_DN, sizeof TA344_DN, BR_EC_secp384r1, (unsigned char *)TA344_EC_Q, sizeof TA344_EC_Q); + trust_anchors[345] = make_rsa_trust_anchor((unsigned char *)TA345_DN, sizeof TA345_DN, (unsigned char *)TA345_RSA_N, sizeof TA345_RSA_N, (unsigned char *)TA345_RSA_E, sizeof TA345_RSA_E); + trust_anchors[346] = make_ec_trust_anchor((unsigned char *)TA346_DN, sizeof TA346_DN, BR_EC_secp384r1, (unsigned char *)TA346_EC_Q, sizeof TA346_EC_Q); + trust_anchors[347] = make_rsa_trust_anchor((unsigned char *)TA347_DN, sizeof TA347_DN, (unsigned char *)TA347_RSA_N, sizeof TA347_RSA_N, (unsigned char *)TA347_RSA_E, sizeof TA347_RSA_E); + trust_anchors[348] = make_rsa_trust_anchor((unsigned char *)TA348_DN, sizeof TA348_DN, (unsigned char *)TA348_RSA_N, sizeof TA348_RSA_N, (unsigned char *)TA348_RSA_E, sizeof TA348_RSA_E); + trust_anchors[349] = make_ec_trust_anchor((unsigned char *)TA349_DN, sizeof TA349_DN, BR_EC_secp384r1, (unsigned char *)TA349_EC_Q, sizeof TA349_EC_Q); + trust_anchors[350] = make_rsa_trust_anchor((unsigned char *)TA350_DN, sizeof TA350_DN, (unsigned char *)TA350_RSA_N, sizeof TA350_RSA_N, (unsigned char *)TA350_RSA_E, sizeof TA350_RSA_E); + trust_anchors[351] = make_rsa_trust_anchor((unsigned char *)TA351_DN, sizeof TA351_DN, (unsigned char *)TA351_RSA_N, sizeof TA351_RSA_N, (unsigned char *)TA351_RSA_E, sizeof TA351_RSA_E); + trust_anchors[352] = make_rsa_trust_anchor((unsigned char *)TA352_DN, sizeof TA352_DN, (unsigned char *)TA352_RSA_N, sizeof TA352_RSA_N, (unsigned char *)TA352_RSA_E, sizeof TA352_RSA_E); + trust_anchors[353] = make_ec_trust_anchor((unsigned char *)TA353_DN, sizeof TA353_DN, BR_EC_secp384r1, (unsigned char *)TA353_EC_Q, sizeof TA353_EC_Q); + trust_anchors[354] = make_rsa_trust_anchor((unsigned char *)TA354_DN, sizeof TA354_DN, (unsigned char *)TA354_RSA_N, sizeof TA354_RSA_N, (unsigned char *)TA354_RSA_E, sizeof TA354_RSA_E); + trust_anchors[355] = make_rsa_trust_anchor((unsigned char *)TA355_DN, sizeof TA355_DN, (unsigned char *)TA355_RSA_N, sizeof TA355_RSA_N, (unsigned char *)TA355_RSA_E, sizeof TA355_RSA_E); + trust_anchors[356] = make_ec_trust_anchor((unsigned char *)TA356_DN, sizeof TA356_DN, BR_EC_secp384r1, (unsigned char *)TA356_EC_Q, sizeof TA356_EC_Q); + trust_anchors[357] = make_rsa_trust_anchor((unsigned char *)TA357_DN, sizeof TA357_DN, (unsigned char *)TA357_RSA_N, sizeof TA357_RSA_N, (unsigned char *)TA357_RSA_E, sizeof TA357_RSA_E); + trust_anchors[358] = make_rsa_trust_anchor((unsigned char *)TA358_DN, sizeof TA358_DN, (unsigned char *)TA358_RSA_N, sizeof TA358_RSA_N, (unsigned char *)TA358_RSA_E, sizeof TA358_RSA_E); + trust_anchors[359] = make_rsa_trust_anchor((unsigned char *)TA359_DN, sizeof TA359_DN, (unsigned char *)TA359_RSA_N, sizeof TA359_RSA_N, (unsigned char *)TA359_RSA_E, sizeof TA359_RSA_E); + trust_anchors[360] = make_rsa_trust_anchor((unsigned char *)TA360_DN, sizeof TA360_DN, (unsigned char *)TA360_RSA_N, sizeof TA360_RSA_N, (unsigned char *)TA360_RSA_E, sizeof TA360_RSA_E); + trust_anchors[361] = make_rsa_trust_anchor((unsigned char *)TA361_DN, sizeof TA361_DN, (unsigned char *)TA361_RSA_N, sizeof TA361_RSA_N, (unsigned char *)TA361_RSA_E, sizeof TA361_RSA_E); + trust_anchors[362] = make_rsa_trust_anchor((unsigned char *)TA362_DN, sizeof TA362_DN, (unsigned char *)TA362_RSA_N, sizeof TA362_RSA_N, (unsigned char *)TA362_RSA_E, sizeof TA362_RSA_E); + trust_anchors[363] = make_rsa_trust_anchor((unsigned char *)TA363_DN, sizeof TA363_DN, (unsigned char *)TA363_RSA_N, sizeof TA363_RSA_N, (unsigned char *)TA363_RSA_E, sizeof TA363_RSA_E); + trust_anchors[364] = make_rsa_trust_anchor((unsigned char *)TA364_DN, sizeof TA364_DN, (unsigned char *)TA364_RSA_N, sizeof TA364_RSA_N, (unsigned char *)TA364_RSA_E, sizeof TA364_RSA_E); + trust_anchors[365] = make_rsa_trust_anchor((unsigned char *)TA365_DN, sizeof TA365_DN, (unsigned char *)TA365_RSA_N, sizeof TA365_RSA_N, (unsigned char *)TA365_RSA_E, sizeof TA365_RSA_E); + trust_anchors[366] = make_rsa_trust_anchor((unsigned char *)TA366_DN, sizeof TA366_DN, (unsigned char *)TA366_RSA_N, sizeof TA366_RSA_N, (unsigned char *)TA366_RSA_E, sizeof TA366_RSA_E); + trust_anchors[367] = make_rsa_trust_anchor((unsigned char *)TA367_DN, sizeof TA367_DN, (unsigned char *)TA367_RSA_N, sizeof TA367_RSA_N, (unsigned char *)TA367_RSA_E, sizeof TA367_RSA_E); + trust_anchors[368] = make_ec_trust_anchor((unsigned char *)TA368_DN, sizeof TA368_DN, BR_EC_secp384r1, (unsigned char *)TA368_EC_Q, sizeof TA368_EC_Q); + trust_anchors[369] = make_rsa_trust_anchor((unsigned char *)TA369_DN, sizeof TA369_DN, (unsigned char *)TA369_RSA_N, sizeof TA369_RSA_N, (unsigned char *)TA369_RSA_E, sizeof TA369_RSA_E); + trust_anchors[370] = make_rsa_trust_anchor((unsigned char *)TA370_DN, sizeof TA370_DN, (unsigned char *)TA370_RSA_N, sizeof TA370_RSA_N, (unsigned char *)TA370_RSA_E, sizeof TA370_RSA_E); + trust_anchors[371] = make_rsa_trust_anchor((unsigned char *)TA371_DN, sizeof TA371_DN, (unsigned char *)TA371_RSA_N, sizeof TA371_RSA_N, (unsigned char *)TA371_RSA_E, sizeof TA371_RSA_E); + trust_anchors[372] = make_rsa_trust_anchor((unsigned char *)TA372_DN, sizeof TA372_DN, (unsigned char *)TA372_RSA_N, sizeof TA372_RSA_N, (unsigned char *)TA372_RSA_E, sizeof TA372_RSA_E); + trust_anchors[373] = make_ec_trust_anchor((unsigned char *)TA373_DN, sizeof TA373_DN, BR_EC_secp384r1, (unsigned char *)TA373_EC_Q, sizeof TA373_EC_Q); + trust_anchors[374] = make_rsa_trust_anchor((unsigned char *)TA374_DN, sizeof TA374_DN, (unsigned char *)TA374_RSA_N, sizeof TA374_RSA_N, (unsigned char *)TA374_RSA_E, sizeof TA374_RSA_E); + trust_anchors[375] = make_ec_trust_anchor((unsigned char *)TA375_DN, sizeof TA375_DN, BR_EC_secp256r1, (unsigned char *)TA375_EC_Q, sizeof TA375_EC_Q); + trust_anchors[376] = make_ec_trust_anchor((unsigned char *)TA376_DN, sizeof TA376_DN, BR_EC_secp384r1, (unsigned char *)TA376_EC_Q, sizeof TA376_EC_Q); + trust_anchors[377] = make_rsa_trust_anchor((unsigned char *)TA377_DN, sizeof TA377_DN, (unsigned char *)TA377_RSA_N, sizeof TA377_RSA_N, (unsigned char *)TA377_RSA_E, sizeof TA377_RSA_E); + trust_anchors[378] = make_rsa_trust_anchor((unsigned char *)TA378_DN, sizeof TA378_DN, (unsigned char *)TA378_RSA_N, sizeof TA378_RSA_N, (unsigned char *)TA378_RSA_E, sizeof TA378_RSA_E); + trust_anchors[379] = make_rsa_trust_anchor((unsigned char *)TA379_DN, sizeof TA379_DN, (unsigned char *)TA379_RSA_N, sizeof TA379_RSA_N, (unsigned char *)TA379_RSA_E, sizeof TA379_RSA_E); + trust_anchors[380] = make_ec_trust_anchor((unsigned char *)TA380_DN, sizeof TA380_DN, BR_EC_secp384r1, (unsigned char *)TA380_EC_Q, sizeof TA380_EC_Q); + trust_anchors[381] = make_rsa_trust_anchor((unsigned char *)TA381_DN, sizeof TA381_DN, (unsigned char *)TA381_RSA_N, sizeof TA381_RSA_N, (unsigned char *)TA381_RSA_E, sizeof TA381_RSA_E); + trust_anchors[382] = make_rsa_trust_anchor((unsigned char *)TA382_DN, sizeof TA382_DN, (unsigned char *)TA382_RSA_N, sizeof TA382_RSA_N, (unsigned char *)TA382_RSA_E, sizeof TA382_RSA_E); + trust_anchors[383] = make_rsa_trust_anchor((unsigned char *)TA383_DN, sizeof TA383_DN, (unsigned char *)TA383_RSA_N, sizeof TA383_RSA_N, (unsigned char *)TA383_RSA_E, sizeof TA383_RSA_E); + trust_anchors[384] = make_rsa_trust_anchor((unsigned char *)TA384_DN, sizeof TA384_DN, (unsigned char *)TA384_RSA_N, sizeof TA384_RSA_N, (unsigned char *)TA384_RSA_E, sizeof TA384_RSA_E); + trust_anchors[385] = make_ec_trust_anchor((unsigned char *)TA385_DN, sizeof TA385_DN, BR_EC_secp256r1, (unsigned char *)TA385_EC_Q, sizeof TA385_EC_Q); + trust_anchors[386] = make_rsa_trust_anchor((unsigned char *)TA386_DN, sizeof TA386_DN, (unsigned char *)TA386_RSA_N, sizeof TA386_RSA_N, (unsigned char *)TA386_RSA_E, sizeof TA386_RSA_E); + trust_anchors[387] = make_ec_trust_anchor((unsigned char *)TA387_DN, sizeof TA387_DN, BR_EC_secp384r1, (unsigned char *)TA387_EC_Q, sizeof TA387_EC_Q); + trust_anchors[388] = make_ec_trust_anchor((unsigned char *)TA388_DN, sizeof TA388_DN, BR_EC_secp384r1, (unsigned char *)TA388_EC_Q, sizeof TA388_EC_Q); + trust_anchors[389] = make_rsa_trust_anchor((unsigned char *)TA389_DN, sizeof TA389_DN, (unsigned char *)TA389_RSA_N, sizeof TA389_RSA_N, (unsigned char *)TA389_RSA_E, sizeof TA389_RSA_E); + trust_anchors[390] = make_rsa_trust_anchor((unsigned char *)TA390_DN, sizeof TA390_DN, (unsigned char *)TA390_RSA_N, sizeof TA390_RSA_N, (unsigned char *)TA390_RSA_E, sizeof TA390_RSA_E); + trust_anchors[391] = make_ec_trust_anchor((unsigned char *)TA391_DN, sizeof TA391_DN, BR_EC_secp384r1, (unsigned char *)TA391_EC_Q, sizeof TA391_EC_Q); + trust_anchors[392] = make_rsa_trust_anchor((unsigned char *)TA392_DN, sizeof TA392_DN, (unsigned char *)TA392_RSA_N, sizeof TA392_RSA_N, (unsigned char *)TA392_RSA_E, sizeof TA392_RSA_E); + trust_anchors[393] = make_rsa_trust_anchor((unsigned char *)TA393_DN, sizeof TA393_DN, (unsigned char *)TA393_RSA_N, sizeof TA393_RSA_N, (unsigned char *)TA393_RSA_E, sizeof TA393_RSA_E); + trust_anchors[394] = make_rsa_trust_anchor((unsigned char *)TA394_DN, sizeof TA394_DN, (unsigned char *)TA394_RSA_N, sizeof TA394_RSA_N, (unsigned char *)TA394_RSA_E, sizeof TA394_RSA_E); + trust_anchors[395] = make_ec_trust_anchor((unsigned char *)TA395_DN, sizeof TA395_DN, BR_EC_secp384r1, (unsigned char *)TA395_EC_Q, sizeof TA395_EC_Q); + trust_anchors[396] = make_rsa_trust_anchor((unsigned char *)TA396_DN, sizeof TA396_DN, (unsigned char *)TA396_RSA_N, sizeof TA396_RSA_N, (unsigned char *)TA396_RSA_E, sizeof TA396_RSA_E); + trust_anchors[397] = make_rsa_trust_anchor((unsigned char *)TA397_DN, sizeof TA397_DN, (unsigned char *)TA397_RSA_N, sizeof TA397_RSA_N, (unsigned char *)TA397_RSA_E, sizeof TA397_RSA_E); + trust_anchors[398] = make_rsa_trust_anchor((unsigned char *)TA398_DN, sizeof TA398_DN, (unsigned char *)TA398_RSA_N, sizeof TA398_RSA_N, (unsigned char *)TA398_RSA_E, sizeof TA398_RSA_E); + trust_anchors[399] = make_rsa_trust_anchor((unsigned char *)TA399_DN, sizeof TA399_DN, (unsigned char *)TA399_RSA_N, sizeof TA399_RSA_N, (unsigned char *)TA399_RSA_E, sizeof TA399_RSA_E); + trust_anchors[400] = make_rsa_trust_anchor((unsigned char *)TA400_DN, sizeof TA400_DN, (unsigned char *)TA400_RSA_N, sizeof TA400_RSA_N, (unsigned char *)TA400_RSA_E, sizeof TA400_RSA_E); + trust_anchors[401] = make_ec_trust_anchor((unsigned char *)TA401_DN, sizeof TA401_DN, BR_EC_secp384r1, (unsigned char *)TA401_EC_Q, sizeof TA401_EC_Q); + trust_anchors[402] = make_rsa_trust_anchor((unsigned char *)TA402_DN, sizeof TA402_DN, (unsigned char *)TA402_RSA_N, sizeof TA402_RSA_N, (unsigned char *)TA402_RSA_E, sizeof TA402_RSA_E); + trust_anchors[403] = make_rsa_trust_anchor((unsigned char *)TA403_DN, sizeof TA403_DN, (unsigned char *)TA403_RSA_N, sizeof TA403_RSA_N, (unsigned char *)TA403_RSA_E, sizeof TA403_RSA_E); + trust_anchors[404] = make_ec_trust_anchor((unsigned char *)TA404_DN, sizeof TA404_DN, BR_EC_secp256r1, (unsigned char *)TA404_EC_Q, sizeof TA404_EC_Q); + trust_anchors[405] = make_ec_trust_anchor((unsigned char *)TA405_DN, sizeof TA405_DN, BR_EC_secp384r1, (unsigned char *)TA405_EC_Q, sizeof TA405_EC_Q); + trust_anchors[406] = make_rsa_trust_anchor((unsigned char *)TA406_DN, sizeof TA406_DN, (unsigned char *)TA406_RSA_N, sizeof TA406_RSA_N, (unsigned char *)TA406_RSA_E, sizeof TA406_RSA_E); + trust_anchors[407] = make_ec_trust_anchor((unsigned char *)TA407_DN, sizeof TA407_DN, BR_EC_secp384r1, (unsigned char *)TA407_EC_Q, sizeof TA407_EC_Q); + trust_anchors[408] = make_rsa_trust_anchor((unsigned char *)TA408_DN, sizeof TA408_DN, (unsigned char *)TA408_RSA_N, sizeof TA408_RSA_N, (unsigned char *)TA408_RSA_E, sizeof TA408_RSA_E); + trust_anchors[409] = make_rsa_trust_anchor((unsigned char *)TA409_DN, sizeof TA409_DN, (unsigned char *)TA409_RSA_N, sizeof TA409_RSA_N, (unsigned char *)TA409_RSA_E, sizeof TA409_RSA_E); + trust_anchors[410] = make_rsa_trust_anchor((unsigned char *)TA410_DN, sizeof TA410_DN, (unsigned char *)TA410_RSA_N, sizeof TA410_RSA_N, (unsigned char *)TA410_RSA_E, sizeof TA410_RSA_E); + trust_anchors[411] = make_ec_trust_anchor((unsigned char *)TA411_DN, sizeof TA411_DN, BR_EC_secp384r1, (unsigned char *)TA411_EC_Q, sizeof TA411_EC_Q); + trust_anchors[412] = make_rsa_trust_anchor((unsigned char *)TA412_DN, sizeof TA412_DN, (unsigned char *)TA412_RSA_N, sizeof TA412_RSA_N, (unsigned char *)TA412_RSA_E, sizeof TA412_RSA_E); + trust_anchors[413] = make_rsa_trust_anchor((unsigned char *)TA413_DN, sizeof TA413_DN, (unsigned char *)TA413_RSA_N, sizeof TA413_RSA_N, (unsigned char *)TA413_RSA_E, sizeof TA413_RSA_E); + trust_anchors[414] = make_rsa_trust_anchor((unsigned char *)TA414_DN, sizeof TA414_DN, (unsigned char *)TA414_RSA_N, sizeof TA414_RSA_N, (unsigned char *)TA414_RSA_E, sizeof TA414_RSA_E); + trust_anchors[415] = make_rsa_trust_anchor((unsigned char *)TA415_DN, sizeof TA415_DN, (unsigned char *)TA415_RSA_N, sizeof TA415_RSA_N, (unsigned char *)TA415_RSA_E, sizeof TA415_RSA_E); + trust_anchors[416] = make_rsa_trust_anchor((unsigned char *)TA416_DN, sizeof TA416_DN, (unsigned char *)TA416_RSA_N, sizeof TA416_RSA_N, (unsigned char *)TA416_RSA_E, sizeof TA416_RSA_E); + trust_anchors[417] = make_rsa_trust_anchor((unsigned char *)TA417_DN, sizeof TA417_DN, (unsigned char *)TA417_RSA_N, sizeof TA417_RSA_N, (unsigned char *)TA417_RSA_E, sizeof TA417_RSA_E); + trust_anchors[418] = make_ec_trust_anchor((unsigned char *)TA418_DN, sizeof TA418_DN, BR_EC_secp384r1, (unsigned char *)TA418_EC_Q, sizeof TA418_EC_Q); + trust_anchors[419] = make_rsa_trust_anchor((unsigned char *)TA419_DN, sizeof TA419_DN, (unsigned char *)TA419_RSA_N, sizeof TA419_RSA_N, (unsigned char *)TA419_RSA_E, sizeof TA419_RSA_E); + trust_anchors[420] = make_ec_trust_anchor((unsigned char *)TA420_DN, sizeof TA420_DN, BR_EC_secp384r1, (unsigned char *)TA420_EC_Q, sizeof TA420_EC_Q); + trust_anchors[421] = make_rsa_trust_anchor((unsigned char *)TA421_DN, sizeof TA421_DN, (unsigned char *)TA421_RSA_N, sizeof TA421_RSA_N, (unsigned char *)TA421_RSA_E, sizeof TA421_RSA_E); + trust_anchors[422] = make_rsa_trust_anchor((unsigned char *)TA422_DN, sizeof TA422_DN, (unsigned char *)TA422_RSA_N, sizeof TA422_RSA_N, (unsigned char *)TA422_RSA_E, sizeof TA422_RSA_E); + trust_anchors[423] = make_rsa_trust_anchor((unsigned char *)TA423_DN, sizeof TA423_DN, (unsigned char *)TA423_RSA_N, sizeof TA423_RSA_N, (unsigned char *)TA423_RSA_E, sizeof TA423_RSA_E); + trust_anchors[424] = make_ec_trust_anchor((unsigned char *)TA424_DN, sizeof TA424_DN, BR_EC_secp384r1, (unsigned char *)TA424_EC_Q, sizeof TA424_EC_Q); + trust_anchors[425] = make_rsa_trust_anchor((unsigned char *)TA425_DN, sizeof TA425_DN, (unsigned char *)TA425_RSA_N, sizeof TA425_RSA_N, (unsigned char *)TA425_RSA_E, sizeof TA425_RSA_E); + trust_anchors[426] = make_rsa_trust_anchor((unsigned char *)TA426_DN, sizeof TA426_DN, (unsigned char *)TA426_RSA_N, sizeof TA426_RSA_N, (unsigned char *)TA426_RSA_E, sizeof TA426_RSA_E); + trust_anchors[427] = make_rsa_trust_anchor((unsigned char *)TA427_DN, sizeof TA427_DN, (unsigned char *)TA427_RSA_N, sizeof TA427_RSA_N, (unsigned char *)TA427_RSA_E, sizeof TA427_RSA_E); + trust_anchors[428] = make_ec_trust_anchor((unsigned char *)TA428_DN, sizeof TA428_DN, BR_EC_secp384r1, (unsigned char *)TA428_EC_Q, sizeof TA428_EC_Q); + trust_anchors[429] = make_ec_trust_anchor((unsigned char *)TA429_DN, sizeof TA429_DN, BR_EC_secp384r1, (unsigned char *)TA429_EC_Q, sizeof TA429_EC_Q); + trust_anchors[430] = make_rsa_trust_anchor((unsigned char *)TA430_DN, sizeof TA430_DN, (unsigned char *)TA430_RSA_N, sizeof TA430_RSA_N, (unsigned char *)TA430_RSA_E, sizeof TA430_RSA_E); + trust_anchors[431] = make_rsa_trust_anchor((unsigned char *)TA431_DN, sizeof TA431_DN, (unsigned char *)TA431_RSA_N, sizeof TA431_RSA_N, (unsigned char *)TA431_RSA_E, sizeof TA431_RSA_E); + trust_anchors[432] = make_rsa_trust_anchor((unsigned char *)TA432_DN, sizeof TA432_DN, (unsigned char *)TA432_RSA_N, sizeof TA432_RSA_N, (unsigned char *)TA432_RSA_E, sizeof TA432_RSA_E); + trust_anchors[433] = make_ec_trust_anchor((unsigned char *)TA433_DN, sizeof TA433_DN, BR_EC_secp384r1, (unsigned char *)TA433_EC_Q, sizeof TA433_EC_Q); + trust_anchors[434] = make_rsa_trust_anchor((unsigned char *)TA434_DN, sizeof TA434_DN, (unsigned char *)TA434_RSA_N, sizeof TA434_RSA_N, (unsigned char *)TA434_RSA_E, sizeof TA434_RSA_E); + trust_anchors[435] = make_ec_trust_anchor((unsigned char *)TA435_DN, sizeof TA435_DN, BR_EC_secp384r1, (unsigned char *)TA435_EC_Q, sizeof TA435_EC_Q); + trust_anchors[436] = make_rsa_trust_anchor((unsigned char *)TA436_DN, sizeof TA436_DN, (unsigned char *)TA436_RSA_N, sizeof TA436_RSA_N, (unsigned char *)TA436_RSA_E, sizeof TA436_RSA_E); + trust_anchors[437] = make_rsa_trust_anchor((unsigned char *)TA437_DN, sizeof TA437_DN, (unsigned char *)TA437_RSA_N, sizeof TA437_RSA_N, (unsigned char *)TA437_RSA_E, sizeof TA437_RSA_E); + trust_anchors[438] = make_rsa_trust_anchor((unsigned char *)TA438_DN, sizeof TA438_DN, (unsigned char *)TA438_RSA_N, sizeof TA438_RSA_N, (unsigned char *)TA438_RSA_E, sizeof TA438_RSA_E); + trust_anchors[439] = make_rsa_trust_anchor((unsigned char *)TA439_DN, sizeof TA439_DN, (unsigned char *)TA439_RSA_N, sizeof TA439_RSA_N, (unsigned char *)TA439_RSA_E, sizeof TA439_RSA_E); + trust_anchors[440] = make_rsa_trust_anchor((unsigned char *)TA440_DN, sizeof TA440_DN, (unsigned char *)TA440_RSA_N, sizeof TA440_RSA_N, (unsigned char *)TA440_RSA_E, sizeof TA440_RSA_E); + trust_anchors[441] = make_ec_trust_anchor((unsigned char *)TA441_DN, sizeof TA441_DN, BR_EC_secp384r1, (unsigned char *)TA441_EC_Q, sizeof TA441_EC_Q); + trust_anchors[442] = make_rsa_trust_anchor((unsigned char *)TA442_DN, sizeof TA442_DN, (unsigned char *)TA442_RSA_N, sizeof TA442_RSA_N, (unsigned char *)TA442_RSA_E, sizeof TA442_RSA_E); + trust_anchors[443] = make_rsa_trust_anchor((unsigned char *)TA443_DN, sizeof TA443_DN, (unsigned char *)TA443_RSA_N, sizeof TA443_RSA_N, (unsigned char *)TA443_RSA_E, sizeof TA443_RSA_E); + trust_anchors[444] = make_ec_trust_anchor((unsigned char *)TA444_DN, sizeof TA444_DN, BR_EC_secp384r1, (unsigned char *)TA444_EC_Q, sizeof TA444_EC_Q); + trust_anchors[445] = make_rsa_trust_anchor((unsigned char *)TA445_DN, sizeof TA445_DN, (unsigned char *)TA445_RSA_N, sizeof TA445_RSA_N, (unsigned char *)TA445_RSA_E, sizeof TA445_RSA_E); + trust_anchors[446] = make_ec_trust_anchor((unsigned char *)TA446_DN, sizeof TA446_DN, BR_EC_secp384r1, (unsigned char *)TA446_EC_Q, sizeof TA446_EC_Q); + trust_anchors[447] = make_rsa_trust_anchor((unsigned char *)TA447_DN, sizeof TA447_DN, (unsigned char *)TA447_RSA_N, sizeof TA447_RSA_N, (unsigned char *)TA447_RSA_E, sizeof TA447_RSA_E); + trust_anchors[448] = make_rsa_trust_anchor((unsigned char *)TA448_DN, sizeof TA448_DN, (unsigned char *)TA448_RSA_N, sizeof TA448_RSA_N, (unsigned char *)TA448_RSA_E, sizeof TA448_RSA_E); + trust_anchors[449] = make_rsa_trust_anchor((unsigned char *)TA449_DN, sizeof TA449_DN, (unsigned char *)TA449_RSA_N, sizeof TA449_RSA_N, (unsigned char *)TA449_RSA_E, sizeof TA449_RSA_E); + trust_anchors[450] = make_rsa_trust_anchor((unsigned char *)TA450_DN, sizeof TA450_DN, (unsigned char *)TA450_RSA_N, sizeof TA450_RSA_N, (unsigned char *)TA450_RSA_E, sizeof TA450_RSA_E); + trust_anchors[451] = make_ec_trust_anchor((unsigned char *)TA451_DN, sizeof TA451_DN, BR_EC_secp384r1, (unsigned char *)TA451_EC_Q, sizeof TA451_EC_Q); + trust_anchors[452] = make_rsa_trust_anchor((unsigned char *)TA452_DN, sizeof TA452_DN, (unsigned char *)TA452_RSA_N, sizeof TA452_RSA_N, (unsigned char *)TA452_RSA_E, sizeof TA452_RSA_E); + trust_anchors[453] = make_ec_trust_anchor((unsigned char *)TA453_DN, sizeof TA453_DN, BR_EC_secp384r1, (unsigned char *)TA453_EC_Q, sizeof TA453_EC_Q); + trust_anchors[454] = make_rsa_trust_anchor((unsigned char *)TA454_DN, sizeof TA454_DN, (unsigned char *)TA454_RSA_N, sizeof TA454_RSA_N, (unsigned char *)TA454_RSA_E, sizeof TA454_RSA_E); + trust_anchors[455] = make_rsa_trust_anchor((unsigned char *)TA455_DN, sizeof TA455_DN, (unsigned char *)TA455_RSA_N, sizeof TA455_RSA_N, (unsigned char *)TA455_RSA_E, sizeof TA455_RSA_E); + trust_anchors[456] = make_rsa_trust_anchor((unsigned char *)TA456_DN, sizeof TA456_DN, (unsigned char *)TA456_RSA_N, sizeof TA456_RSA_N, (unsigned char *)TA456_RSA_E, sizeof TA456_RSA_E); + trust_anchors[457] = make_rsa_trust_anchor((unsigned char *)TA457_DN, sizeof TA457_DN, (unsigned char *)TA457_RSA_N, sizeof TA457_RSA_N, (unsigned char *)TA457_RSA_E, sizeof TA457_RSA_E); + trust_anchors[458] = make_ec_trust_anchor((unsigned char *)TA458_DN, sizeof TA458_DN, BR_EC_secp384r1, (unsigned char *)TA458_EC_Q, sizeof TA458_EC_Q); + trust_anchors[459] = make_ec_trust_anchor((unsigned char *)TA459_DN, sizeof TA459_DN, BR_EC_secp384r1, (unsigned char *)TA459_EC_Q, sizeof TA459_EC_Q); + trust_anchors[460] = make_ec_trust_anchor((unsigned char *)TA460_DN, sizeof TA460_DN, BR_EC_secp256r1, (unsigned char *)TA460_EC_Q, sizeof TA460_EC_Q); + trust_anchors[461] = make_ec_trust_anchor((unsigned char *)TA461_DN, sizeof TA461_DN, BR_EC_secp384r1, (unsigned char *)TA461_EC_Q, sizeof TA461_EC_Q); + trust_anchors[462] = make_rsa_trust_anchor((unsigned char *)TA462_DN, sizeof TA462_DN, (unsigned char *)TA462_RSA_N, sizeof TA462_RSA_N, (unsigned char *)TA462_RSA_E, sizeof TA462_RSA_E); + trust_anchors[463] = make_rsa_trust_anchor((unsigned char *)TA463_DN, sizeof TA463_DN, (unsigned char *)TA463_RSA_N, sizeof TA463_RSA_N, (unsigned char *)TA463_RSA_E, sizeof TA463_RSA_E); + trust_anchors[464] = make_rsa_trust_anchor((unsigned char *)TA464_DN, sizeof TA464_DN, (unsigned char *)TA464_RSA_N, sizeof TA464_RSA_N, (unsigned char *)TA464_RSA_E, sizeof TA464_RSA_E); + trust_anchors[465] = make_ec_trust_anchor((unsigned char *)TA465_DN, sizeof TA465_DN, BR_EC_secp384r1, (unsigned char *)TA465_EC_Q, sizeof TA465_EC_Q); + trust_anchors[466] = make_rsa_trust_anchor((unsigned char *)TA466_DN, sizeof TA466_DN, (unsigned char *)TA466_RSA_N, sizeof TA466_RSA_N, (unsigned char *)TA466_RSA_E, sizeof TA466_RSA_E); + trust_anchors[467] = make_rsa_trust_anchor((unsigned char *)TA467_DN, sizeof TA467_DN, (unsigned char *)TA467_RSA_N, sizeof TA467_RSA_N, (unsigned char *)TA467_RSA_E, sizeof TA467_RSA_E); + trust_anchors[468] = make_rsa_trust_anchor((unsigned char *)TA468_DN, sizeof TA468_DN, (unsigned char *)TA468_RSA_N, sizeof TA468_RSA_N, (unsigned char *)TA468_RSA_E, sizeof TA468_RSA_E); + trust_anchors[469] = make_ec_trust_anchor((unsigned char *)TA469_DN, sizeof TA469_DN, BR_EC_secp384r1, (unsigned char *)TA469_EC_Q, sizeof TA469_EC_Q); + trust_anchors[470] = make_rsa_trust_anchor((unsigned char *)TA470_DN, sizeof TA470_DN, (unsigned char *)TA470_RSA_N, sizeof TA470_RSA_N, (unsigned char *)TA470_RSA_E, sizeof TA470_RSA_E); + trust_anchors[471] = make_ec_trust_anchor((unsigned char *)TA471_DN, sizeof TA471_DN, BR_EC_secp384r1, (unsigned char *)TA471_EC_Q, sizeof TA471_EC_Q); + trust_anchors[472] = make_rsa_trust_anchor((unsigned char *)TA472_DN, sizeof TA472_DN, (unsigned char *)TA472_RSA_N, sizeof TA472_RSA_N, (unsigned char *)TA472_RSA_E, sizeof TA472_RSA_E); + trust_anchors[473] = make_rsa_trust_anchor((unsigned char *)TA473_DN, sizeof TA473_DN, (unsigned char *)TA473_RSA_N, sizeof TA473_RSA_N, (unsigned char *)TA473_RSA_E, sizeof TA473_RSA_E); + trust_anchors[474] = make_rsa_trust_anchor((unsigned char *)TA474_DN, sizeof TA474_DN, (unsigned char *)TA474_RSA_N, sizeof TA474_RSA_N, (unsigned char *)TA474_RSA_E, sizeof TA474_RSA_E); + trust_anchors[475] = make_rsa_trust_anchor((unsigned char *)TA475_DN, sizeof TA475_DN, (unsigned char *)TA475_RSA_N, sizeof TA475_RSA_N, (unsigned char *)TA475_RSA_E, sizeof TA475_RSA_E); + trust_anchors[476] = make_ec_trust_anchor((unsigned char *)TA476_DN, sizeof TA476_DN, BR_EC_secp384r1, (unsigned char *)TA476_EC_Q, sizeof TA476_EC_Q); + trust_anchors[477] = make_rsa_trust_anchor((unsigned char *)TA477_DN, sizeof TA477_DN, (unsigned char *)TA477_RSA_N, sizeof TA477_RSA_N, (unsigned char *)TA477_RSA_E, sizeof TA477_RSA_E); + trust_anchors[478] = make_rsa_trust_anchor((unsigned char *)TA478_DN, sizeof TA478_DN, (unsigned char *)TA478_RSA_N, sizeof TA478_RSA_N, (unsigned char *)TA478_RSA_E, sizeof TA478_RSA_E); + trust_anchors[479] = make_rsa_trust_anchor((unsigned char *)TA479_DN, sizeof TA479_DN, (unsigned char *)TA479_RSA_N, sizeof TA479_RSA_N, (unsigned char *)TA479_RSA_E, sizeof TA479_RSA_E); + trust_anchors[480] = make_rsa_trust_anchor((unsigned char *)TA480_DN, sizeof TA480_DN, (unsigned char *)TA480_RSA_N, sizeof TA480_RSA_N, (unsigned char *)TA480_RSA_E, sizeof TA480_RSA_E); + trust_anchors[481] = make_ec_trust_anchor((unsigned char *)TA481_DN, sizeof TA481_DN, BR_EC_secp384r1, (unsigned char *)TA481_EC_Q, sizeof TA481_EC_Q); + trust_anchors[482] = make_rsa_trust_anchor((unsigned char *)TA482_DN, sizeof TA482_DN, (unsigned char *)TA482_RSA_N, sizeof TA482_RSA_N, (unsigned char *)TA482_RSA_E, sizeof TA482_RSA_E); + trust_anchors[483] = make_rsa_trust_anchor((unsigned char *)TA483_DN, sizeof TA483_DN, (unsigned char *)TA483_RSA_N, sizeof TA483_RSA_N, (unsigned char *)TA483_RSA_E, sizeof TA483_RSA_E); + trust_anchors[484] = make_rsa_trust_anchor((unsigned char *)TA484_DN, sizeof TA484_DN, (unsigned char *)TA484_RSA_N, sizeof TA484_RSA_N, (unsigned char *)TA484_RSA_E, sizeof TA484_RSA_E); + trust_anchors[485] = make_rsa_trust_anchor((unsigned char *)TA485_DN, sizeof TA485_DN, (unsigned char *)TA485_RSA_N, sizeof TA485_RSA_N, (unsigned char *)TA485_RSA_E, sizeof TA485_RSA_E); + trust_anchors[486] = make_ec_trust_anchor((unsigned char *)TA486_DN, sizeof TA486_DN, BR_EC_secp384r1, (unsigned char *)TA486_EC_Q, sizeof TA486_EC_Q); + trust_anchors[487] = make_rsa_trust_anchor((unsigned char *)TA487_DN, sizeof TA487_DN, (unsigned char *)TA487_RSA_N, sizeof TA487_RSA_N, (unsigned char *)TA487_RSA_E, sizeof TA487_RSA_E); + trust_anchors[488] = make_rsa_trust_anchor((unsigned char *)TA488_DN, sizeof TA488_DN, (unsigned char *)TA488_RSA_N, sizeof TA488_RSA_N, (unsigned char *)TA488_RSA_E, sizeof TA488_RSA_E); + trust_anchors[489] = make_rsa_trust_anchor((unsigned char *)TA489_DN, sizeof TA489_DN, (unsigned char *)TA489_RSA_N, sizeof TA489_RSA_N, (unsigned char *)TA489_RSA_E, sizeof TA489_RSA_E); + trust_anchors[490] = make_rsa_trust_anchor((unsigned char *)TA490_DN, sizeof TA490_DN, (unsigned char *)TA490_RSA_N, sizeof TA490_RSA_N, (unsigned char *)TA490_RSA_E, sizeof TA490_RSA_E); + trust_anchors[491] = make_rsa_trust_anchor((unsigned char *)TA491_DN, sizeof TA491_DN, (unsigned char *)TA491_RSA_N, sizeof TA491_RSA_N, (unsigned char *)TA491_RSA_E, sizeof TA491_RSA_E); + trust_anchors[492] = make_ec_trust_anchor((unsigned char *)TA492_DN, sizeof TA492_DN, BR_EC_secp384r1, (unsigned char *)TA492_EC_Q, sizeof TA492_EC_Q); + trust_anchors[493] = make_rsa_trust_anchor((unsigned char *)TA493_DN, sizeof TA493_DN, (unsigned char *)TA493_RSA_N, sizeof TA493_RSA_N, (unsigned char *)TA493_RSA_E, sizeof TA493_RSA_E); + trust_anchors[494] = make_ec_trust_anchor((unsigned char *)TA494_DN, sizeof TA494_DN, BR_EC_secp384r1, (unsigned char *)TA494_EC_Q, sizeof TA494_EC_Q); + trust_anchors[495] = make_rsa_trust_anchor((unsigned char *)TA495_DN, sizeof TA495_DN, (unsigned char *)TA495_RSA_N, sizeof TA495_RSA_N, (unsigned char *)TA495_RSA_E, sizeof TA495_RSA_E); + trust_anchors[496] = make_ec_trust_anchor((unsigned char *)TA496_DN, sizeof TA496_DN, BR_EC_secp384r1, (unsigned char *)TA496_EC_Q, sizeof TA496_EC_Q); + trust_anchors[497] = make_rsa_trust_anchor((unsigned char *)TA497_DN, sizeof TA497_DN, (unsigned char *)TA497_RSA_N, sizeof TA497_RSA_N, (unsigned char *)TA497_RSA_E, sizeof TA497_RSA_E); + trust_anchors[498] = make_rsa_trust_anchor((unsigned char *)TA498_DN, sizeof TA498_DN, (unsigned char *)TA498_RSA_N, sizeof TA498_RSA_N, (unsigned char *)TA498_RSA_E, sizeof TA498_RSA_E); + trust_anchors[499] = make_ec_trust_anchor((unsigned char *)TA499_DN, sizeof TA499_DN, BR_EC_secp384r1, (unsigned char *)TA499_EC_Q, sizeof TA499_EC_Q); + trust_anchors[500] = make_rsa_trust_anchor((unsigned char *)TA500_DN, sizeof TA500_DN, (unsigned char *)TA500_RSA_N, sizeof TA500_RSA_N, (unsigned char *)TA500_RSA_E, sizeof TA500_RSA_E); + trust_anchors[501] = make_rsa_trust_anchor((unsigned char *)TA501_DN, sizeof TA501_DN, (unsigned char *)TA501_RSA_N, sizeof TA501_RSA_N, (unsigned char *)TA501_RSA_E, sizeof TA501_RSA_E); + trust_anchors[502] = make_rsa_trust_anchor((unsigned char *)TA502_DN, sizeof TA502_DN, (unsigned char *)TA502_RSA_N, sizeof TA502_RSA_N, (unsigned char *)TA502_RSA_E, sizeof TA502_RSA_E); + trust_anchors[503] = make_ec_trust_anchor((unsigned char *)TA503_DN, sizeof TA503_DN, BR_EC_secp384r1, (unsigned char *)TA503_EC_Q, sizeof TA503_EC_Q); + trust_anchors[504] = make_rsa_trust_anchor((unsigned char *)TA504_DN, sizeof TA504_DN, (unsigned char *)TA504_RSA_N, sizeof TA504_RSA_N, (unsigned char *)TA504_RSA_E, sizeof TA504_RSA_E); + trust_anchors[505] = make_rsa_trust_anchor((unsigned char *)TA505_DN, sizeof TA505_DN, (unsigned char *)TA505_RSA_N, sizeof TA505_RSA_N, (unsigned char *)TA505_RSA_E, sizeof TA505_RSA_E); + trust_anchors[506] = make_ec_trust_anchor((unsigned char *)TA506_DN, sizeof TA506_DN, BR_EC_secp384r1, (unsigned char *)TA506_EC_Q, sizeof TA506_EC_Q); + trust_anchors[507] = make_rsa_trust_anchor((unsigned char *)TA507_DN, sizeof TA507_DN, (unsigned char *)TA507_RSA_N, sizeof TA507_RSA_N, (unsigned char *)TA507_RSA_E, sizeof TA507_RSA_E); + trust_anchors[508] = make_rsa_trust_anchor((unsigned char *)TA508_DN, sizeof TA508_DN, (unsigned char *)TA508_RSA_N, sizeof TA508_RSA_N, (unsigned char *)TA508_RSA_E, sizeof TA508_RSA_E); + trust_anchors[509] = make_rsa_trust_anchor((unsigned char *)TA509_DN, sizeof TA509_DN, (unsigned char *)TA509_RSA_N, sizeof TA509_RSA_N, (unsigned char *)TA509_RSA_E, sizeof TA509_RSA_E); + trust_anchors[510] = make_rsa_trust_anchor((unsigned char *)TA510_DN, sizeof TA510_DN, (unsigned char *)TA510_RSA_N, sizeof TA510_RSA_N, (unsigned char *)TA510_RSA_E, sizeof TA510_RSA_E); + trust_anchors[511] = make_rsa_trust_anchor((unsigned char *)TA511_DN, sizeof TA511_DN, (unsigned char *)TA511_RSA_N, sizeof TA511_RSA_N, (unsigned char *)TA511_RSA_E, sizeof TA511_RSA_E); + trust_anchors[512] = make_rsa_trust_anchor((unsigned char *)TA512_DN, sizeof TA512_DN, (unsigned char *)TA512_RSA_N, sizeof TA512_RSA_N, (unsigned char *)TA512_RSA_E, sizeof TA512_RSA_E); + trust_anchors[513] = make_rsa_trust_anchor((unsigned char *)TA513_DN, sizeof TA513_DN, (unsigned char *)TA513_RSA_N, sizeof TA513_RSA_N, (unsigned char *)TA513_RSA_E, sizeof TA513_RSA_E); + trust_anchors[514] = make_rsa_trust_anchor((unsigned char *)TA514_DN, sizeof TA514_DN, (unsigned char *)TA514_RSA_N, sizeof TA514_RSA_N, (unsigned char *)TA514_RSA_E, sizeof TA514_RSA_E); + trust_anchors[515] = make_rsa_trust_anchor((unsigned char *)TA515_DN, sizeof TA515_DN, (unsigned char *)TA515_RSA_N, sizeof TA515_RSA_N, (unsigned char *)TA515_RSA_E, sizeof TA515_RSA_E); + trust_anchors[516] = make_rsa_trust_anchor((unsigned char *)TA516_DN, sizeof TA516_DN, (unsigned char *)TA516_RSA_N, sizeof TA516_RSA_N, (unsigned char *)TA516_RSA_E, sizeof TA516_RSA_E); + trust_anchors[517] = make_rsa_trust_anchor((unsigned char *)TA517_DN, sizeof TA517_DN, (unsigned char *)TA517_RSA_N, sizeof TA517_RSA_N, (unsigned char *)TA517_RSA_E, sizeof TA517_RSA_E); + trust_anchors[518] = make_ec_trust_anchor((unsigned char *)TA518_DN, sizeof TA518_DN, BR_EC_secp384r1, (unsigned char *)TA518_EC_Q, sizeof TA518_EC_Q); + trust_anchors[519] = make_rsa_trust_anchor((unsigned char *)TA519_DN, sizeof TA519_DN, (unsigned char *)TA519_RSA_N, sizeof TA519_RSA_N, (unsigned char *)TA519_RSA_E, sizeof TA519_RSA_E); + trust_anchors[520] = make_rsa_trust_anchor((unsigned char *)TA520_DN, sizeof TA520_DN, (unsigned char *)TA520_RSA_N, sizeof TA520_RSA_N, (unsigned char *)TA520_RSA_E, sizeof TA520_RSA_E); + trust_anchors[521] = make_rsa_trust_anchor((unsigned char *)TA521_DN, sizeof TA521_DN, (unsigned char *)TA521_RSA_N, sizeof TA521_RSA_N, (unsigned char *)TA521_RSA_E, sizeof TA521_RSA_E); + trust_anchors[522] = make_rsa_trust_anchor((unsigned char *)TA522_DN, sizeof TA522_DN, (unsigned char *)TA522_RSA_N, sizeof TA522_RSA_N, (unsigned char *)TA522_RSA_E, sizeof TA522_RSA_E); + trust_anchors[523] = make_ec_trust_anchor((unsigned char *)TA523_DN, sizeof TA523_DN, BR_EC_secp384r1, (unsigned char *)TA523_EC_Q, sizeof TA523_EC_Q); + trust_anchors[524] = make_rsa_trust_anchor((unsigned char *)TA524_DN, sizeof TA524_DN, (unsigned char *)TA524_RSA_N, sizeof TA524_RSA_N, (unsigned char *)TA524_RSA_E, sizeof TA524_RSA_E); + trust_anchors[525] = make_ec_trust_anchor((unsigned char *)TA525_DN, sizeof TA525_DN, BR_EC_secp256r1, (unsigned char *)TA525_EC_Q, sizeof TA525_EC_Q); + trust_anchors[526] = make_ec_trust_anchor((unsigned char *)TA526_DN, sizeof TA526_DN, BR_EC_secp384r1, (unsigned char *)TA526_EC_Q, sizeof TA526_EC_Q); + trust_anchors[527] = make_rsa_trust_anchor((unsigned char *)TA527_DN, sizeof TA527_DN, (unsigned char *)TA527_RSA_N, sizeof TA527_RSA_N, (unsigned char *)TA527_RSA_E, sizeof TA527_RSA_E); + trust_anchors[528] = make_rsa_trust_anchor((unsigned char *)TA528_DN, sizeof TA528_DN, (unsigned char *)TA528_RSA_N, sizeof TA528_RSA_N, (unsigned char *)TA528_RSA_E, sizeof TA528_RSA_E); + trust_anchors[529] = make_rsa_trust_anchor((unsigned char *)TA529_DN, sizeof TA529_DN, (unsigned char *)TA529_RSA_N, sizeof TA529_RSA_N, (unsigned char *)TA529_RSA_E, sizeof TA529_RSA_E); + trust_anchors[530] = make_ec_trust_anchor((unsigned char *)TA530_DN, sizeof TA530_DN, BR_EC_secp384r1, (unsigned char *)TA530_EC_Q, sizeof TA530_EC_Q); + trust_anchors[531] = make_rsa_trust_anchor((unsigned char *)TA531_DN, sizeof TA531_DN, (unsigned char *)TA531_RSA_N, sizeof TA531_RSA_N, (unsigned char *)TA531_RSA_E, sizeof TA531_RSA_E); + trust_anchors[532] = make_rsa_trust_anchor((unsigned char *)TA532_DN, sizeof TA532_DN, (unsigned char *)TA532_RSA_N, sizeof TA532_RSA_N, (unsigned char *)TA532_RSA_E, sizeof TA532_RSA_E); + trust_anchors[533] = make_rsa_trust_anchor((unsigned char *)TA533_DN, sizeof TA533_DN, (unsigned char *)TA533_RSA_N, sizeof TA533_RSA_N, (unsigned char *)TA533_RSA_E, sizeof TA533_RSA_E); + trust_anchors[534] = make_rsa_trust_anchor((unsigned char *)TA534_DN, sizeof TA534_DN, (unsigned char *)TA534_RSA_N, sizeof TA534_RSA_N, (unsigned char *)TA534_RSA_E, sizeof TA534_RSA_E); + trust_anchors[535] = make_ec_trust_anchor((unsigned char *)TA535_DN, sizeof TA535_DN, BR_EC_secp256r1, (unsigned char *)TA535_EC_Q, sizeof TA535_EC_Q); + trust_anchors[536] = make_rsa_trust_anchor((unsigned char *)TA536_DN, sizeof TA536_DN, (unsigned char *)TA536_RSA_N, sizeof TA536_RSA_N, (unsigned char *)TA536_RSA_E, sizeof TA536_RSA_E); + trust_anchors[537] = make_ec_trust_anchor((unsigned char *)TA537_DN, sizeof TA537_DN, BR_EC_secp384r1, (unsigned char *)TA537_EC_Q, sizeof TA537_EC_Q); + trust_anchors[538] = make_ec_trust_anchor((unsigned char *)TA538_DN, sizeof TA538_DN, BR_EC_secp384r1, (unsigned char *)TA538_EC_Q, sizeof TA538_EC_Q); + trust_anchors[539] = make_rsa_trust_anchor((unsigned char *)TA539_DN, sizeof TA539_DN, (unsigned char *)TA539_RSA_N, sizeof TA539_RSA_N, (unsigned char *)TA539_RSA_E, sizeof TA539_RSA_E); + trust_anchors[540] = make_rsa_trust_anchor((unsigned char *)TA540_DN, sizeof TA540_DN, (unsigned char *)TA540_RSA_N, sizeof TA540_RSA_N, (unsigned char *)TA540_RSA_E, sizeof TA540_RSA_E); + trust_anchors[541] = make_ec_trust_anchor((unsigned char *)TA541_DN, sizeof TA541_DN, BR_EC_secp384r1, (unsigned char *)TA541_EC_Q, sizeof TA541_EC_Q); + trust_anchors[542] = make_rsa_trust_anchor((unsigned char *)TA542_DN, sizeof TA542_DN, (unsigned char *)TA542_RSA_N, sizeof TA542_RSA_N, (unsigned char *)TA542_RSA_E, sizeof TA542_RSA_E); + trust_anchors[543] = make_rsa_trust_anchor((unsigned char *)TA543_DN, sizeof TA543_DN, (unsigned char *)TA543_RSA_N, sizeof TA543_RSA_N, (unsigned char *)TA543_RSA_E, sizeof TA543_RSA_E); + trust_anchors[544] = make_rsa_trust_anchor((unsigned char *)TA544_DN, sizeof TA544_DN, (unsigned char *)TA544_RSA_N, sizeof TA544_RSA_N, (unsigned char *)TA544_RSA_E, sizeof TA544_RSA_E); + trust_anchors[545] = make_ec_trust_anchor((unsigned char *)TA545_DN, sizeof TA545_DN, BR_EC_secp384r1, (unsigned char *)TA545_EC_Q, sizeof TA545_EC_Q); + trust_anchors[546] = make_rsa_trust_anchor((unsigned char *)TA546_DN, sizeof TA546_DN, (unsigned char *)TA546_RSA_N, sizeof TA546_RSA_N, (unsigned char *)TA546_RSA_E, sizeof TA546_RSA_E); + trust_anchors[547] = make_rsa_trust_anchor((unsigned char *)TA547_DN, sizeof TA547_DN, (unsigned char *)TA547_RSA_N, sizeof TA547_RSA_N, (unsigned char *)TA547_RSA_E, sizeof TA547_RSA_E); + trust_anchors[548] = make_ec_trust_anchor((unsigned char *)TA548_DN, sizeof TA548_DN, BR_EC_secp384r1, (unsigned char *)TA548_EC_Q, sizeof TA548_EC_Q); + trust_anchors[549] = make_rsa_trust_anchor((unsigned char *)TA549_DN, sizeof TA549_DN, (unsigned char *)TA549_RSA_N, sizeof TA549_RSA_N, (unsigned char *)TA549_RSA_E, sizeof TA549_RSA_E); + trust_anchors[550] = make_rsa_trust_anchor((unsigned char *)TA550_DN, sizeof TA550_DN, (unsigned char *)TA550_RSA_N, sizeof TA550_RSA_N, (unsigned char *)TA550_RSA_E, sizeof TA550_RSA_E); + trust_anchors[551] = make_rsa_trust_anchor((unsigned char *)TA551_DN, sizeof TA551_DN, (unsigned char *)TA551_RSA_N, sizeof TA551_RSA_N, (unsigned char *)TA551_RSA_E, sizeof TA551_RSA_E); + trust_anchors[552] = make_ec_trust_anchor((unsigned char *)TA552_DN, sizeof TA552_DN, BR_EC_secp384r1, (unsigned char *)TA552_EC_Q, sizeof TA552_EC_Q); + trust_anchors[553] = make_rsa_trust_anchor((unsigned char *)TA553_DN, sizeof TA553_DN, (unsigned char *)TA553_RSA_N, sizeof TA553_RSA_N, (unsigned char *)TA553_RSA_E, sizeof TA553_RSA_E); + trust_anchors[554] = make_rsa_trust_anchor((unsigned char *)TA554_DN, sizeof TA554_DN, (unsigned char *)TA554_RSA_N, sizeof TA554_RSA_N, (unsigned char *)TA554_RSA_E, sizeof TA554_RSA_E); + trust_anchors[555] = make_rsa_trust_anchor((unsigned char *)TA555_DN, sizeof TA555_DN, (unsigned char *)TA555_RSA_N, sizeof TA555_RSA_N, (unsigned char *)TA555_RSA_E, sizeof TA555_RSA_E); + trust_anchors[556] = make_rsa_trust_anchor((unsigned char *)TA556_DN, sizeof TA556_DN, (unsigned char *)TA556_RSA_N, sizeof TA556_RSA_N, (unsigned char *)TA556_RSA_E, sizeof TA556_RSA_E); + trust_anchors[557] = make_rsa_trust_anchor((unsigned char *)TA557_DN, sizeof TA557_DN, (unsigned char *)TA557_RSA_N, sizeof TA557_RSA_N, (unsigned char *)TA557_RSA_E, sizeof TA557_RSA_E); + trust_anchors[558] = make_ec_trust_anchor((unsigned char *)TA558_DN, sizeof TA558_DN, BR_EC_secp384r1, (unsigned char *)TA558_EC_Q, sizeof TA558_EC_Q); + trust_anchors[559] = make_rsa_trust_anchor((unsigned char *)TA559_DN, sizeof TA559_DN, (unsigned char *)TA559_RSA_N, sizeof TA559_RSA_N, (unsigned char *)TA559_RSA_E, sizeof TA559_RSA_E); + trust_anchors[560] = make_rsa_trust_anchor((unsigned char *)TA560_DN, sizeof TA560_DN, (unsigned char *)TA560_RSA_N, sizeof TA560_RSA_N, (unsigned char *)TA560_RSA_E, sizeof TA560_RSA_E); + trust_anchors[561] = make_rsa_trust_anchor((unsigned char *)TA561_DN, sizeof TA561_DN, (unsigned char *)TA561_RSA_N, sizeof TA561_RSA_N, (unsigned char *)TA561_RSA_E, sizeof TA561_RSA_E); + trust_anchors[562] = make_rsa_trust_anchor((unsigned char *)TA562_DN, sizeof TA562_DN, (unsigned char *)TA562_RSA_N, sizeof TA562_RSA_N, (unsigned char *)TA562_RSA_E, sizeof TA562_RSA_E); + trust_anchors[563] = make_rsa_trust_anchor((unsigned char *)TA563_DN, sizeof TA563_DN, (unsigned char *)TA563_RSA_N, sizeof TA563_RSA_N, (unsigned char *)TA563_RSA_E, sizeof TA563_RSA_E); + trust_anchors[564] = make_ec_trust_anchor((unsigned char *)TA564_DN, sizeof TA564_DN, BR_EC_secp384r1, (unsigned char *)TA564_EC_Q, sizeof TA564_EC_Q); + trust_anchors[565] = make_ec_trust_anchor((unsigned char *)TA565_DN, sizeof TA565_DN, BR_EC_secp384r1, (unsigned char *)TA565_EC_Q, sizeof TA565_EC_Q); + trust_anchors[566] = make_rsa_trust_anchor((unsigned char *)TA566_DN, sizeof TA566_DN, (unsigned char *)TA566_RSA_N, sizeof TA566_RSA_N, (unsigned char *)TA566_RSA_E, sizeof TA566_RSA_E); + trust_anchors[567] = make_rsa_trust_anchor((unsigned char *)TA567_DN, sizeof TA567_DN, (unsigned char *)TA567_RSA_N, sizeof TA567_RSA_N, (unsigned char *)TA567_RSA_E, sizeof TA567_RSA_E); + trust_anchors[568] = make_rsa_trust_anchor((unsigned char *)TA568_DN, sizeof TA568_DN, (unsigned char *)TA568_RSA_N, sizeof TA568_RSA_N, (unsigned char *)TA568_RSA_E, sizeof TA568_RSA_E); + trust_anchors[569] = make_rsa_trust_anchor((unsigned char *)TA569_DN, sizeof TA569_DN, (unsigned char *)TA569_RSA_N, sizeof TA569_RSA_N, (unsigned char *)TA569_RSA_E, sizeof TA569_RSA_E); + trust_anchors[570] = make_ec_trust_anchor((unsigned char *)TA570_DN, sizeof TA570_DN, BR_EC_secp384r1, (unsigned char *)TA570_EC_Q, sizeof TA570_EC_Q); + trust_anchors[571] = make_rsa_trust_anchor((unsigned char *)TA571_DN, sizeof TA571_DN, (unsigned char *)TA571_RSA_N, sizeof TA571_RSA_N, (unsigned char *)TA571_RSA_E, sizeof TA571_RSA_E); + trust_anchors[572] = make_rsa_trust_anchor((unsigned char *)TA572_DN, sizeof TA572_DN, (unsigned char *)TA572_RSA_N, sizeof TA572_RSA_N, (unsigned char *)TA572_RSA_E, sizeof TA572_RSA_E); + trust_anchors[573] = make_rsa_trust_anchor((unsigned char *)TA573_DN, sizeof TA573_DN, (unsigned char *)TA573_RSA_N, sizeof TA573_RSA_N, (unsigned char *)TA573_RSA_E, sizeof TA573_RSA_E); + trust_anchors[574] = make_rsa_trust_anchor((unsigned char *)TA574_DN, sizeof TA574_DN, (unsigned char *)TA574_RSA_N, sizeof TA574_RSA_N, (unsigned char *)TA574_RSA_E, sizeof TA574_RSA_E); + trust_anchors[575] = make_rsa_trust_anchor((unsigned char *)TA575_DN, sizeof TA575_DN, (unsigned char *)TA575_RSA_N, sizeof TA575_RSA_N, (unsigned char *)TA575_RSA_E, sizeof TA575_RSA_E); + trust_anchors[576] = make_ec_trust_anchor((unsigned char *)TA576_DN, sizeof TA576_DN, BR_EC_secp384r1, (unsigned char *)TA576_EC_Q, sizeof TA576_EC_Q); + trust_anchors[577] = make_rsa_trust_anchor((unsigned char *)TA577_DN, sizeof TA577_DN, (unsigned char *)TA577_RSA_N, sizeof TA577_RSA_N, (unsigned char *)TA577_RSA_E, sizeof TA577_RSA_E); + trust_anchors[578] = make_rsa_trust_anchor((unsigned char *)TA578_DN, sizeof TA578_DN, (unsigned char *)TA578_RSA_N, sizeof TA578_RSA_N, (unsigned char *)TA578_RSA_E, sizeof TA578_RSA_E); + trust_anchors[579] = make_rsa_trust_anchor((unsigned char *)TA579_DN, sizeof TA579_DN, (unsigned char *)TA579_RSA_N, sizeof TA579_RSA_N, (unsigned char *)TA579_RSA_E, sizeof TA579_RSA_E); + trust_anchors[580] = make_rsa_trust_anchor((unsigned char *)TA580_DN, sizeof TA580_DN, (unsigned char *)TA580_RSA_N, sizeof TA580_RSA_N, (unsigned char *)TA580_RSA_E, sizeof TA580_RSA_E); + trust_anchors[581] = make_rsa_trust_anchor((unsigned char *)TA581_DN, sizeof TA581_DN, (unsigned char *)TA581_RSA_N, sizeof TA581_RSA_N, (unsigned char *)TA581_RSA_E, sizeof TA581_RSA_E); + trust_anchors[582] = make_rsa_trust_anchor((unsigned char *)TA582_DN, sizeof TA582_DN, (unsigned char *)TA582_RSA_N, sizeof TA582_RSA_N, (unsigned char *)TA582_RSA_E, sizeof TA582_RSA_E); + trust_anchors[583] = make_rsa_trust_anchor((unsigned char *)TA583_DN, sizeof TA583_DN, (unsigned char *)TA583_RSA_N, sizeof TA583_RSA_N, (unsigned char *)TA583_RSA_E, sizeof TA583_RSA_E); + trust_anchors[584] = make_ec_trust_anchor((unsigned char *)TA584_DN, sizeof TA584_DN, BR_EC_secp384r1, (unsigned char *)TA584_EC_Q, sizeof TA584_EC_Q); + trust_anchors[585] = make_rsa_trust_anchor((unsigned char *)TA585_DN, sizeof TA585_DN, (unsigned char *)TA585_RSA_N, sizeof TA585_RSA_N, (unsigned char *)TA585_RSA_E, sizeof TA585_RSA_E); + trust_anchors[586] = make_ec_trust_anchor((unsigned char *)TA586_DN, sizeof TA586_DN, BR_EC_secp384r1, (unsigned char *)TA586_EC_Q, sizeof TA586_EC_Q); + trust_anchors[587] = make_rsa_trust_anchor((unsigned char *)TA587_DN, sizeof TA587_DN, (unsigned char *)TA587_RSA_N, sizeof TA587_RSA_N, (unsigned char *)TA587_RSA_E, sizeof TA587_RSA_E); + trust_anchors[588] = make_rsa_trust_anchor((unsigned char *)TA588_DN, sizeof TA588_DN, (unsigned char *)TA588_RSA_N, sizeof TA588_RSA_N, (unsigned char *)TA588_RSA_E, sizeof TA588_RSA_E); + trust_anchors[589] = make_rsa_trust_anchor((unsigned char *)TA589_DN, sizeof TA589_DN, (unsigned char *)TA589_RSA_N, sizeof TA589_RSA_N, (unsigned char *)TA589_RSA_E, sizeof TA589_RSA_E); + trust_anchors[590] = make_rsa_trust_anchor((unsigned char *)TA590_DN, sizeof TA590_DN, (unsigned char *)TA590_RSA_N, sizeof TA590_RSA_N, (unsigned char *)TA590_RSA_E, sizeof TA590_RSA_E); + trust_anchors[591] = make_rsa_trust_anchor((unsigned char *)TA591_DN, sizeof TA591_DN, (unsigned char *)TA591_RSA_N, sizeof TA591_RSA_N, (unsigned char *)TA591_RSA_E, sizeof TA591_RSA_E); + trust_anchors[592] = make_ec_trust_anchor((unsigned char *)TA592_DN, sizeof TA592_DN, BR_EC_secp384r1, (unsigned char *)TA592_EC_Q, sizeof TA592_EC_Q); + trust_anchors[593] = make_ec_trust_anchor((unsigned char *)TA593_DN, sizeof TA593_DN, BR_EC_secp384r1, (unsigned char *)TA593_EC_Q, sizeof TA593_EC_Q); + trust_anchors[594] = make_ec_trust_anchor((unsigned char *)TA594_DN, sizeof TA594_DN, BR_EC_secp384r1, (unsigned char *)TA594_EC_Q, sizeof TA594_EC_Q); + trust_anchors[595] = make_rsa_trust_anchor((unsigned char *)TA595_DN, sizeof TA595_DN, (unsigned char *)TA595_RSA_N, sizeof TA595_RSA_N, (unsigned char *)TA595_RSA_E, sizeof TA595_RSA_E); + trust_anchors[596] = make_rsa_trust_anchor((unsigned char *)TA596_DN, sizeof TA596_DN, (unsigned char *)TA596_RSA_N, sizeof TA596_RSA_N, (unsigned char *)TA596_RSA_E, sizeof TA596_RSA_E); + trust_anchors[597] = make_rsa_trust_anchor((unsigned char *)TA597_DN, sizeof TA597_DN, (unsigned char *)TA597_RSA_N, sizeof TA597_RSA_N, (unsigned char *)TA597_RSA_E, sizeof TA597_RSA_E); + trust_anchors[598] = make_ec_trust_anchor((unsigned char *)TA598_DN, sizeof TA598_DN, BR_EC_secp384r1, (unsigned char *)TA598_EC_Q, sizeof TA598_EC_Q); + trust_anchors[599] = make_rsa_trust_anchor((unsigned char *)TA599_DN, sizeof TA599_DN, (unsigned char *)TA599_RSA_N, sizeof TA599_RSA_N, (unsigned char *)TA599_RSA_E, sizeof TA599_RSA_E); + trust_anchors[600] = make_rsa_trust_anchor((unsigned char *)TA600_DN, sizeof TA600_DN, (unsigned char *)TA600_RSA_N, sizeof TA600_RSA_N, (unsigned char *)TA600_RSA_E, sizeof TA600_RSA_E); + trust_anchors[601] = make_ec_trust_anchor((unsigned char *)TA601_DN, sizeof TA601_DN, BR_EC_secp384r1, (unsigned char *)TA601_EC_Q, sizeof TA601_EC_Q); + trust_anchors[602] = make_rsa_trust_anchor((unsigned char *)TA602_DN, sizeof TA602_DN, (unsigned char *)TA602_RSA_N, sizeof TA602_RSA_N, (unsigned char *)TA602_RSA_E, sizeof TA602_RSA_E); + trust_anchors[603] = make_ec_trust_anchor((unsigned char *)TA603_DN, sizeof TA603_DN, BR_EC_secp384r1, (unsigned char *)TA603_EC_Q, sizeof TA603_EC_Q); + trust_anchors[604] = make_rsa_trust_anchor((unsigned char *)TA604_DN, sizeof TA604_DN, (unsigned char *)TA604_RSA_N, sizeof TA604_RSA_N, (unsigned char *)TA604_RSA_E, sizeof TA604_RSA_E); + trust_anchors[605] = make_rsa_trust_anchor((unsigned char *)TA605_DN, sizeof TA605_DN, (unsigned char *)TA605_RSA_N, sizeof TA605_RSA_N, (unsigned char *)TA605_RSA_E, sizeof TA605_RSA_E); + trust_anchors[606] = make_ec_trust_anchor((unsigned char *)TA606_DN, sizeof TA606_DN, BR_EC_secp384r1, (unsigned char *)TA606_EC_Q, sizeof TA606_EC_Q); + trust_anchors[607] = make_rsa_trust_anchor((unsigned char *)TA607_DN, sizeof TA607_DN, (unsigned char *)TA607_RSA_N, sizeof TA607_RSA_N, (unsigned char *)TA607_RSA_E, sizeof TA607_RSA_E); + trust_anchors[608] = make_ec_trust_anchor((unsigned char *)TA608_DN, sizeof TA608_DN, BR_EC_secp384r1, (unsigned char *)TA608_EC_Q, sizeof TA608_EC_Q); + trust_anchors[609] = make_rsa_trust_anchor((unsigned char *)TA609_DN, sizeof TA609_DN, (unsigned char *)TA609_RSA_N, sizeof TA609_RSA_N, (unsigned char *)TA609_RSA_E, sizeof TA609_RSA_E); + trust_anchors[610] = make_rsa_trust_anchor((unsigned char *)TA610_DN, sizeof TA610_DN, (unsigned char *)TA610_RSA_N, sizeof TA610_RSA_N, (unsigned char *)TA610_RSA_E, sizeof TA610_RSA_E); + trust_anchors[611] = make_rsa_trust_anchor((unsigned char *)TA611_DN, sizeof TA611_DN, (unsigned char *)TA611_RSA_N, sizeof TA611_RSA_N, (unsigned char *)TA611_RSA_E, sizeof TA611_RSA_E); + trust_anchors[612] = make_rsa_trust_anchor((unsigned char *)TA612_DN, sizeof TA612_DN, (unsigned char *)TA612_RSA_N, sizeof TA612_RSA_N, (unsigned char *)TA612_RSA_E, sizeof TA612_RSA_E); + trust_anchors[613] = make_rsa_trust_anchor((unsigned char *)TA613_DN, sizeof TA613_DN, (unsigned char *)TA613_RSA_N, sizeof TA613_RSA_N, (unsigned char *)TA613_RSA_E, sizeof TA613_RSA_E); + trust_anchors[614] = make_rsa_trust_anchor((unsigned char *)TA614_DN, sizeof TA614_DN, (unsigned char *)TA614_RSA_N, sizeof TA614_RSA_N, (unsigned char *)TA614_RSA_E, sizeof TA614_RSA_E); + trust_anchors[615] = make_rsa_trust_anchor((unsigned char *)TA615_DN, sizeof TA615_DN, (unsigned char *)TA615_RSA_N, sizeof TA615_RSA_N, (unsigned char *)TA615_RSA_E, sizeof TA615_RSA_E); + trust_anchors[616] = make_rsa_trust_anchor((unsigned char *)TA616_DN, sizeof TA616_DN, (unsigned char *)TA616_RSA_N, sizeof TA616_RSA_N, (unsigned char *)TA616_RSA_E, sizeof TA616_RSA_E); + trust_anchors[617] = make_rsa_trust_anchor((unsigned char *)TA617_DN, sizeof TA617_DN, (unsigned char *)TA617_RSA_N, sizeof TA617_RSA_N, (unsigned char *)TA617_RSA_E, sizeof TA617_RSA_E); + trust_anchors[618] = make_rsa_trust_anchor((unsigned char *)TA618_DN, sizeof TA618_DN, (unsigned char *)TA618_RSA_N, sizeof TA618_RSA_N, (unsigned char *)TA618_RSA_E, sizeof TA618_RSA_E); + trust_anchors[619] = make_rsa_trust_anchor((unsigned char *)TA619_DN, sizeof TA619_DN, (unsigned char *)TA619_RSA_N, sizeof TA619_RSA_N, (unsigned char *)TA619_RSA_E, sizeof TA619_RSA_E); + trust_anchors[620] = make_rsa_trust_anchor((unsigned char *)TA620_DN, sizeof TA620_DN, (unsigned char *)TA620_RSA_N, sizeof TA620_RSA_N, (unsigned char *)TA620_RSA_E, sizeof TA620_RSA_E); + trust_anchors[621] = make_ec_trust_anchor((unsigned char *)TA621_DN, sizeof TA621_DN, BR_EC_secp384r1, (unsigned char *)TA621_EC_Q, sizeof TA621_EC_Q); + trust_anchors[622] = make_rsa_trust_anchor((unsigned char *)TA622_DN, sizeof TA622_DN, (unsigned char *)TA622_RSA_N, sizeof TA622_RSA_N, (unsigned char *)TA622_RSA_E, sizeof TA622_RSA_E); + trust_anchors[623] = make_rsa_trust_anchor((unsigned char *)TA623_DN, sizeof TA623_DN, (unsigned char *)TA623_RSA_N, sizeof TA623_RSA_N, (unsigned char *)TA623_RSA_E, sizeof TA623_RSA_E); + trust_anchors[624] = make_ec_trust_anchor((unsigned char *)TA624_DN, sizeof TA624_DN, BR_EC_secp256r1, (unsigned char *)TA624_EC_Q, sizeof TA624_EC_Q); + trust_anchors[625] = make_rsa_trust_anchor((unsigned char *)TA625_DN, sizeof TA625_DN, (unsigned char *)TA625_RSA_N, sizeof TA625_RSA_N, (unsigned char *)TA625_RSA_E, sizeof TA625_RSA_E); + trust_anchors[626] = make_ec_trust_anchor((unsigned char *)TA626_DN, sizeof TA626_DN, BR_EC_secp384r1, (unsigned char *)TA626_EC_Q, sizeof TA626_EC_Q); + trust_anchors[627] = make_ec_trust_anchor((unsigned char *)TA627_DN, sizeof TA627_DN, BR_EC_secp384r1, (unsigned char *)TA627_EC_Q, sizeof TA627_EC_Q); + trust_anchors[628] = make_ec_trust_anchor((unsigned char *)TA628_DN, sizeof TA628_DN, BR_EC_secp384r1, (unsigned char *)TA628_EC_Q, sizeof TA628_EC_Q); + trust_anchors[629] = make_rsa_trust_anchor((unsigned char *)TA629_DN, sizeof TA629_DN, (unsigned char *)TA629_RSA_N, sizeof TA629_RSA_N, (unsigned char *)TA629_RSA_E, sizeof TA629_RSA_E); + trust_anchors[630] = make_rsa_trust_anchor((unsigned char *)TA630_DN, sizeof TA630_DN, (unsigned char *)TA630_RSA_N, sizeof TA630_RSA_N, (unsigned char *)TA630_RSA_E, sizeof TA630_RSA_E); + trust_anchors[631] = make_ec_trust_anchor((unsigned char *)TA631_DN, sizeof TA631_DN, BR_EC_secp384r1, (unsigned char *)TA631_EC_Q, sizeof TA631_EC_Q); + trust_anchors[632] = make_rsa_trust_anchor((unsigned char *)TA632_DN, sizeof TA632_DN, (unsigned char *)TA632_RSA_N, sizeof TA632_RSA_N, (unsigned char *)TA632_RSA_E, sizeof TA632_RSA_E); + trust_anchors[633] = make_ec_trust_anchor((unsigned char *)TA633_DN, sizeof TA633_DN, BR_EC_secp384r1, (unsigned char *)TA633_EC_Q, sizeof TA633_EC_Q); + trust_anchors[634] = make_rsa_trust_anchor((unsigned char *)TA634_DN, sizeof TA634_DN, (unsigned char *)TA634_RSA_N, sizeof TA634_RSA_N, (unsigned char *)TA634_RSA_E, sizeof TA634_RSA_E); + trust_anchors[635] = make_ec_trust_anchor((unsigned char *)TA635_DN, sizeof TA635_DN, BR_EC_secp384r1, (unsigned char *)TA635_EC_Q, sizeof TA635_EC_Q); + trust_anchors[636] = make_ec_trust_anchor((unsigned char *)TA636_DN, sizeof TA636_DN, BR_EC_secp384r1, (unsigned char *)TA636_EC_Q, sizeof TA636_EC_Q); + trust_anchors[637] = make_rsa_trust_anchor((unsigned char *)TA637_DN, sizeof TA637_DN, (unsigned char *)TA637_RSA_N, sizeof TA637_RSA_N, (unsigned char *)TA637_RSA_E, sizeof TA637_RSA_E); + trust_anchors[638] = make_rsa_trust_anchor((unsigned char *)TA638_DN, sizeof TA638_DN, (unsigned char *)TA638_RSA_N, sizeof TA638_RSA_N, (unsigned char *)TA638_RSA_E, sizeof TA638_RSA_E); + trust_anchors[639] = make_rsa_trust_anchor((unsigned char *)TA639_DN, sizeof TA639_DN, (unsigned char *)TA639_RSA_N, sizeof TA639_RSA_N, (unsigned char *)TA639_RSA_E, sizeof TA639_RSA_E); + trust_anchors[640] = make_ec_trust_anchor((unsigned char *)TA640_DN, sizeof TA640_DN, BR_EC_secp384r1, (unsigned char *)TA640_EC_Q, sizeof TA640_EC_Q); + trust_anchors[641] = make_rsa_trust_anchor((unsigned char *)TA641_DN, sizeof TA641_DN, (unsigned char *)TA641_RSA_N, sizeof TA641_RSA_N, (unsigned char *)TA641_RSA_E, sizeof TA641_RSA_E); + trust_anchors[642] = make_rsa_trust_anchor((unsigned char *)TA642_DN, sizeof TA642_DN, (unsigned char *)TA642_RSA_N, sizeof TA642_RSA_N, (unsigned char *)TA642_RSA_E, sizeof TA642_RSA_E); + trust_anchors[643] = make_rsa_trust_anchor((unsigned char *)TA643_DN, sizeof TA643_DN, (unsigned char *)TA643_RSA_N, sizeof TA643_RSA_N, (unsigned char *)TA643_RSA_E, sizeof TA643_RSA_E); + trust_anchors[644] = make_ec_trust_anchor((unsigned char *)TA644_DN, sizeof TA644_DN, BR_EC_secp256r1, (unsigned char *)TA644_EC_Q, sizeof TA644_EC_Q); + trust_anchors[645] = make_rsa_trust_anchor((unsigned char *)TA645_DN, sizeof TA645_DN, (unsigned char *)TA645_RSA_N, sizeof TA645_RSA_N, (unsigned char *)TA645_RSA_E, sizeof TA645_RSA_E); + trust_anchors[646] = make_rsa_trust_anchor((unsigned char *)TA646_DN, sizeof TA646_DN, (unsigned char *)TA646_RSA_N, sizeof TA646_RSA_N, (unsigned char *)TA646_RSA_E, sizeof TA646_RSA_E); + trust_anchors[647] = make_rsa_trust_anchor((unsigned char *)TA647_DN, sizeof TA647_DN, (unsigned char *)TA647_RSA_N, sizeof TA647_RSA_N, (unsigned char *)TA647_RSA_E, sizeof TA647_RSA_E); + trust_anchors[648] = make_ec_trust_anchor((unsigned char *)TA648_DN, sizeof TA648_DN, BR_EC_secp384r1, (unsigned char *)TA648_EC_Q, sizeof TA648_EC_Q); + trust_anchors[649] = make_rsa_trust_anchor((unsigned char *)TA649_DN, sizeof TA649_DN, (unsigned char *)TA649_RSA_N, sizeof TA649_RSA_N, (unsigned char *)TA649_RSA_E, sizeof TA649_RSA_E); + trust_anchors[650] = make_ec_trust_anchor((unsigned char *)TA650_DN, sizeof TA650_DN, BR_EC_secp384r1, (unsigned char *)TA650_EC_Q, sizeof TA650_EC_Q); + trust_anchors[651] = make_rsa_trust_anchor((unsigned char *)TA651_DN, sizeof TA651_DN, (unsigned char *)TA651_RSA_N, sizeof TA651_RSA_N, (unsigned char *)TA651_RSA_E, sizeof TA651_RSA_E); + trust_anchors[652] = make_rsa_trust_anchor((unsigned char *)TA652_DN, sizeof TA652_DN, (unsigned char *)TA652_RSA_N, sizeof TA652_RSA_N, (unsigned char *)TA652_RSA_E, sizeof TA652_RSA_E); + trust_anchors[653] = make_rsa_trust_anchor((unsigned char *)TA653_DN, sizeof TA653_DN, (unsigned char *)TA653_RSA_N, sizeof TA653_RSA_N, (unsigned char *)TA653_RSA_E, sizeof TA653_RSA_E); + trust_anchors[654] = make_rsa_trust_anchor((unsigned char *)TA654_DN, sizeof TA654_DN, (unsigned char *)TA654_RSA_N, sizeof TA654_RSA_N, (unsigned char *)TA654_RSA_E, sizeof TA654_RSA_E); + trust_anchors[655] = make_rsa_trust_anchor((unsigned char *)TA655_DN, sizeof TA655_DN, (unsigned char *)TA655_RSA_N, sizeof TA655_RSA_N, (unsigned char *)TA655_RSA_E, sizeof TA655_RSA_E); + trust_anchors[656] = make_rsa_trust_anchor((unsigned char *)TA656_DN, sizeof TA656_DN, (unsigned char *)TA656_RSA_N, sizeof TA656_RSA_N, (unsigned char *)TA656_RSA_E, sizeof TA656_RSA_E); + trust_anchors[657] = make_rsa_trust_anchor((unsigned char *)TA657_DN, sizeof TA657_DN, (unsigned char *)TA657_RSA_N, sizeof TA657_RSA_N, (unsigned char *)TA657_RSA_E, sizeof TA657_RSA_E); + trust_anchors[658] = make_ec_trust_anchor((unsigned char *)TA658_DN, sizeof TA658_DN, BR_EC_secp384r1, (unsigned char *)TA658_EC_Q, sizeof TA658_EC_Q); + trust_anchors[659] = make_rsa_trust_anchor((unsigned char *)TA659_DN, sizeof TA659_DN, (unsigned char *)TA659_RSA_N, sizeof TA659_RSA_N, (unsigned char *)TA659_RSA_E, sizeof TA659_RSA_E); + trust_anchors[660] = make_rsa_trust_anchor((unsigned char *)TA660_DN, sizeof TA660_DN, (unsigned char *)TA660_RSA_N, sizeof TA660_RSA_N, (unsigned char *)TA660_RSA_E, sizeof TA660_RSA_E); + trust_anchors[661] = make_rsa_trust_anchor((unsigned char *)TA661_DN, sizeof TA661_DN, (unsigned char *)TA661_RSA_N, sizeof TA661_RSA_N, (unsigned char *)TA661_RSA_E, sizeof TA661_RSA_E); + trust_anchors[662] = make_rsa_trust_anchor((unsigned char *)TA662_DN, sizeof TA662_DN, (unsigned char *)TA662_RSA_N, sizeof TA662_RSA_N, (unsigned char *)TA662_RSA_E, sizeof TA662_RSA_E); + trust_anchors[663] = make_rsa_trust_anchor((unsigned char *)TA663_DN, sizeof TA663_DN, (unsigned char *)TA663_RSA_N, sizeof TA663_RSA_N, (unsigned char *)TA663_RSA_E, sizeof TA663_RSA_E); + trust_anchors[664] = make_ec_trust_anchor((unsigned char *)TA664_DN, sizeof TA664_DN, BR_EC_secp384r1, (unsigned char *)TA664_EC_Q, sizeof TA664_EC_Q); + trust_anchors[665] = make_rsa_trust_anchor((unsigned char *)TA665_DN, sizeof TA665_DN, (unsigned char *)TA665_RSA_N, sizeof TA665_RSA_N, (unsigned char *)TA665_RSA_E, sizeof TA665_RSA_E); + trust_anchors[666] = make_rsa_trust_anchor((unsigned char *)TA666_DN, sizeof TA666_DN, (unsigned char *)TA666_RSA_N, sizeof TA666_RSA_N, (unsigned char *)TA666_RSA_E, sizeof TA666_RSA_E); + trust_anchors[667] = make_rsa_trust_anchor((unsigned char *)TA667_DN, sizeof TA667_DN, (unsigned char *)TA667_RSA_N, sizeof TA667_RSA_N, (unsigned char *)TA667_RSA_E, sizeof TA667_RSA_E); + trust_anchors[668] = make_ec_trust_anchor((unsigned char *)TA668_DN, sizeof TA668_DN, BR_EC_secp384r1, (unsigned char *)TA668_EC_Q, sizeof TA668_EC_Q); + trust_anchors[669] = make_rsa_trust_anchor((unsigned char *)TA669_DN, sizeof TA669_DN, (unsigned char *)TA669_RSA_N, sizeof TA669_RSA_N, (unsigned char *)TA669_RSA_E, sizeof TA669_RSA_E); + trust_anchors[670] = make_ec_trust_anchor((unsigned char *)TA670_DN, sizeof TA670_DN, BR_EC_secp256r1, (unsigned char *)TA670_EC_Q, sizeof TA670_EC_Q); + trust_anchors[671] = make_ec_trust_anchor((unsigned char *)TA671_DN, sizeof TA671_DN, BR_EC_secp384r1, (unsigned char *)TA671_EC_Q, sizeof TA671_EC_Q); + trust_anchors[672] = make_rsa_trust_anchor((unsigned char *)TA672_DN, sizeof TA672_DN, (unsigned char *)TA672_RSA_N, sizeof TA672_RSA_N, (unsigned char *)TA672_RSA_E, sizeof TA672_RSA_E); + trust_anchors[673] = make_rsa_trust_anchor((unsigned char *)TA673_DN, sizeof TA673_DN, (unsigned char *)TA673_RSA_N, sizeof TA673_RSA_N, (unsigned char *)TA673_RSA_E, sizeof TA673_RSA_E); + trust_anchors[674] = make_rsa_trust_anchor((unsigned char *)TA674_DN, sizeof TA674_DN, (unsigned char *)TA674_RSA_N, sizeof TA674_RSA_N, (unsigned char *)TA674_RSA_E, sizeof TA674_RSA_E); + trust_anchors[675] = make_ec_trust_anchor((unsigned char *)TA675_DN, sizeof TA675_DN, BR_EC_secp384r1, (unsigned char *)TA675_EC_Q, sizeof TA675_EC_Q); + trust_anchors[676] = make_rsa_trust_anchor((unsigned char *)TA676_DN, sizeof TA676_DN, (unsigned char *)TA676_RSA_N, sizeof TA676_RSA_N, (unsigned char *)TA676_RSA_E, sizeof TA676_RSA_E); + trust_anchors[677] = make_rsa_trust_anchor((unsigned char *)TA677_DN, sizeof TA677_DN, (unsigned char *)TA677_RSA_N, sizeof TA677_RSA_N, (unsigned char *)TA677_RSA_E, sizeof TA677_RSA_E); + trust_anchors[678] = make_rsa_trust_anchor((unsigned char *)TA678_DN, sizeof TA678_DN, (unsigned char *)TA678_RSA_N, sizeof TA678_RSA_N, (unsigned char *)TA678_RSA_E, sizeof TA678_RSA_E); + trust_anchors[679] = make_rsa_trust_anchor((unsigned char *)TA679_DN, sizeof TA679_DN, (unsigned char *)TA679_RSA_N, sizeof TA679_RSA_N, (unsigned char *)TA679_RSA_E, sizeof TA679_RSA_E); + trust_anchors[680] = make_rsa_trust_anchor((unsigned char *)TA680_DN, sizeof TA680_DN, (unsigned char *)TA680_RSA_N, sizeof TA680_RSA_N, (unsigned char *)TA680_RSA_E, sizeof TA680_RSA_E); + trust_anchors[681] = make_rsa_trust_anchor((unsigned char *)TA681_DN, sizeof TA681_DN, (unsigned char *)TA681_RSA_N, sizeof TA681_RSA_N, (unsigned char *)TA681_RSA_E, sizeof TA681_RSA_E); + trust_anchors[682] = make_ec_trust_anchor((unsigned char *)TA682_DN, sizeof TA682_DN, BR_EC_secp384r1, (unsigned char *)TA682_EC_Q, sizeof TA682_EC_Q); + trust_anchors[683] = make_ec_trust_anchor((unsigned char *)TA683_DN, sizeof TA683_DN, BR_EC_secp384r1, (unsigned char *)TA683_EC_Q, sizeof TA683_EC_Q); + trust_anchors[684] = make_ec_trust_anchor((unsigned char *)TA684_DN, sizeof TA684_DN, BR_EC_secp384r1, (unsigned char *)TA684_EC_Q, sizeof TA684_EC_Q); + trust_anchors[685] = make_rsa_trust_anchor((unsigned char *)TA685_DN, sizeof TA685_DN, (unsigned char *)TA685_RSA_N, sizeof TA685_RSA_N, (unsigned char *)TA685_RSA_E, sizeof TA685_RSA_E); + trust_anchors[686] = make_ec_trust_anchor((unsigned char *)TA686_DN, sizeof TA686_DN, BR_EC_secp384r1, (unsigned char *)TA686_EC_Q, sizeof TA686_EC_Q); + trust_anchors[687] = make_rsa_trust_anchor((unsigned char *)TA687_DN, sizeof TA687_DN, (unsigned char *)TA687_RSA_N, sizeof TA687_RSA_N, (unsigned char *)TA687_RSA_E, sizeof TA687_RSA_E); + trust_anchors[688] = make_rsa_trust_anchor((unsigned char *)TA688_DN, sizeof TA688_DN, (unsigned char *)TA688_RSA_N, sizeof TA688_RSA_N, (unsigned char *)TA688_RSA_E, sizeof TA688_RSA_E); + trust_anchors[689] = make_rsa_trust_anchor((unsigned char *)TA689_DN, sizeof TA689_DN, (unsigned char *)TA689_RSA_N, sizeof TA689_RSA_N, (unsigned char *)TA689_RSA_E, sizeof TA689_RSA_E); + trust_anchors[690] = make_rsa_trust_anchor((unsigned char *)TA690_DN, sizeof TA690_DN, (unsigned char *)TA690_RSA_N, sizeof TA690_RSA_N, (unsigned char *)TA690_RSA_E, sizeof TA690_RSA_E); + trust_anchors[691] = make_rsa_trust_anchor((unsigned char *)TA691_DN, sizeof TA691_DN, (unsigned char *)TA691_RSA_N, sizeof TA691_RSA_N, (unsigned char *)TA691_RSA_E, sizeof TA691_RSA_E); + trust_anchors[692] = make_rsa_trust_anchor((unsigned char *)TA692_DN, sizeof TA692_DN, (unsigned char *)TA692_RSA_N, sizeof TA692_RSA_N, (unsigned char *)TA692_RSA_E, sizeof TA692_RSA_E); + trust_anchors[693] = make_ec_trust_anchor((unsigned char *)TA693_DN, sizeof TA693_DN, BR_EC_secp384r1, (unsigned char *)TA693_EC_Q, sizeof TA693_EC_Q); + trust_anchors[694] = make_rsa_trust_anchor((unsigned char *)TA694_DN, sizeof TA694_DN, (unsigned char *)TA694_RSA_N, sizeof TA694_RSA_N, (unsigned char *)TA694_RSA_E, sizeof TA694_RSA_E); + trust_anchors[695] = make_rsa_trust_anchor((unsigned char *)TA695_DN, sizeof TA695_DN, (unsigned char *)TA695_RSA_N, sizeof TA695_RSA_N, (unsigned char *)TA695_RSA_E, sizeof TA695_RSA_E); + trust_anchors[696] = make_ec_trust_anchor((unsigned char *)TA696_DN, sizeof TA696_DN, BR_EC_secp384r1, (unsigned char *)TA696_EC_Q, sizeof TA696_EC_Q); + trust_anchors[697] = make_rsa_trust_anchor((unsigned char *)TA697_DN, sizeof TA697_DN, (unsigned char *)TA697_RSA_N, sizeof TA697_RSA_N, (unsigned char *)TA697_RSA_E, sizeof TA697_RSA_E); + trust_anchors[698] = make_rsa_trust_anchor((unsigned char *)TA698_DN, sizeof TA698_DN, (unsigned char *)TA698_RSA_N, sizeof TA698_RSA_N, (unsigned char *)TA698_RSA_E, sizeof TA698_RSA_E); + trust_anchors[699] = make_rsa_trust_anchor((unsigned char *)TA699_DN, sizeof TA699_DN, (unsigned char *)TA699_RSA_N, sizeof TA699_RSA_N, (unsigned char *)TA699_RSA_E, sizeof TA699_RSA_E); + trust_anchors[700] = make_rsa_trust_anchor((unsigned char *)TA700_DN, sizeof TA700_DN, (unsigned char *)TA700_RSA_N, sizeof TA700_RSA_N, (unsigned char *)TA700_RSA_E, sizeof TA700_RSA_E); + trust_anchors[701] = make_ec_trust_anchor((unsigned char *)TA701_DN, sizeof TA701_DN, BR_EC_secp384r1, (unsigned char *)TA701_EC_Q, sizeof TA701_EC_Q); + trust_anchors[702] = make_rsa_trust_anchor((unsigned char *)TA702_DN, sizeof TA702_DN, (unsigned char *)TA702_RSA_N, sizeof TA702_RSA_N, (unsigned char *)TA702_RSA_E, sizeof TA702_RSA_E); + trust_anchors[703] = make_rsa_trust_anchor((unsigned char *)TA703_DN, sizeof TA703_DN, (unsigned char *)TA703_RSA_N, sizeof TA703_RSA_N, (unsigned char *)TA703_RSA_E, sizeof TA703_RSA_E); + trust_anchors[704] = make_rsa_trust_anchor((unsigned char *)TA704_DN, sizeof TA704_DN, (unsigned char *)TA704_RSA_N, sizeof TA704_RSA_N, (unsigned char *)TA704_RSA_E, sizeof TA704_RSA_E); + trust_anchors[705] = make_rsa_trust_anchor((unsigned char *)TA705_DN, sizeof TA705_DN, (unsigned char *)TA705_RSA_N, sizeof TA705_RSA_N, (unsigned char *)TA705_RSA_E, sizeof TA705_RSA_E); + trust_anchors[706] = make_rsa_trust_anchor((unsigned char *)TA706_DN, sizeof TA706_DN, (unsigned char *)TA706_RSA_N, sizeof TA706_RSA_N, (unsigned char *)TA706_RSA_E, sizeof TA706_RSA_E); + trust_anchors[707] = make_ec_trust_anchor((unsigned char *)TA707_DN, sizeof TA707_DN, BR_EC_secp384r1, (unsigned char *)TA707_EC_Q, sizeof TA707_EC_Q); + trust_anchors[708] = make_rsa_trust_anchor((unsigned char *)TA708_DN, sizeof TA708_DN, (unsigned char *)TA708_RSA_N, sizeof TA708_RSA_N, (unsigned char *)TA708_RSA_E, sizeof TA708_RSA_E); + trust_anchors[709] = make_rsa_trust_anchor((unsigned char *)TA709_DN, sizeof TA709_DN, (unsigned char *)TA709_RSA_N, sizeof TA709_RSA_N, (unsigned char *)TA709_RSA_E, sizeof TA709_RSA_E); + trust_anchors[710] = make_rsa_trust_anchor((unsigned char *)TA710_DN, sizeof TA710_DN, (unsigned char *)TA710_RSA_N, sizeof TA710_RSA_N, (unsigned char *)TA710_RSA_E, sizeof TA710_RSA_E); + trust_anchors[711] = make_rsa_trust_anchor((unsigned char *)TA711_DN, sizeof TA711_DN, (unsigned char *)TA711_RSA_N, sizeof TA711_RSA_N, (unsigned char *)TA711_RSA_E, sizeof TA711_RSA_E); + trust_anchors[712] = make_ec_trust_anchor((unsigned char *)TA712_DN, sizeof TA712_DN, BR_EC_secp384r1, (unsigned char *)TA712_EC_Q, sizeof TA712_EC_Q); + trust_anchors[713] = make_rsa_trust_anchor((unsigned char *)TA713_DN, sizeof TA713_DN, (unsigned char *)TA713_RSA_N, sizeof TA713_RSA_N, (unsigned char *)TA713_RSA_E, sizeof TA713_RSA_E); + trust_anchors[714] = make_ec_trust_anchor((unsigned char *)TA714_DN, sizeof TA714_DN, BR_EC_secp384r1, (unsigned char *)TA714_EC_Q, sizeof TA714_EC_Q); + trust_anchors[715] = make_rsa_trust_anchor((unsigned char *)TA715_DN, sizeof TA715_DN, (unsigned char *)TA715_RSA_N, sizeof TA715_RSA_N, (unsigned char *)TA715_RSA_E, sizeof TA715_RSA_E); + trust_anchors[716] = make_ec_trust_anchor((unsigned char *)TA716_DN, sizeof TA716_DN, BR_EC_secp384r1, (unsigned char *)TA716_EC_Q, sizeof TA716_EC_Q); + trust_anchors[717] = make_rsa_trust_anchor((unsigned char *)TA717_DN, sizeof TA717_DN, (unsigned char *)TA717_RSA_N, sizeof TA717_RSA_N, (unsigned char *)TA717_RSA_E, sizeof TA717_RSA_E); + trust_anchors[718] = make_ec_trust_anchor((unsigned char *)TA718_DN, sizeof TA718_DN, BR_EC_secp384r1, (unsigned char *)TA718_EC_Q, sizeof TA718_EC_Q); + trust_anchors[719] = make_rsa_trust_anchor((unsigned char *)TA719_DN, sizeof TA719_DN, (unsigned char *)TA719_RSA_N, sizeof TA719_RSA_N, (unsigned char *)TA719_RSA_E, sizeof TA719_RSA_E); + trust_anchors[720] = make_ec_trust_anchor((unsigned char *)TA720_DN, sizeof TA720_DN, BR_EC_secp384r1, (unsigned char *)TA720_EC_Q, sizeof TA720_EC_Q); + trust_anchors[721] = make_rsa_trust_anchor((unsigned char *)TA721_DN, sizeof TA721_DN, (unsigned char *)TA721_RSA_N, sizeof TA721_RSA_N, (unsigned char *)TA721_RSA_E, sizeof TA721_RSA_E); + trust_anchors[722] = make_rsa_trust_anchor((unsigned char *)TA722_DN, sizeof TA722_DN, (unsigned char *)TA722_RSA_N, sizeof TA722_RSA_N, (unsigned char *)TA722_RSA_E, sizeof TA722_RSA_E); + trust_anchors[723] = make_rsa_trust_anchor((unsigned char *)TA723_DN, sizeof TA723_DN, (unsigned char *)TA723_RSA_N, sizeof TA723_RSA_N, (unsigned char *)TA723_RSA_E, sizeof TA723_RSA_E); + trust_anchors[724] = make_rsa_trust_anchor((unsigned char *)TA724_DN, sizeof TA724_DN, (unsigned char *)TA724_RSA_N, sizeof TA724_RSA_N, (unsigned char *)TA724_RSA_E, sizeof TA724_RSA_E); + trust_anchors[725] = make_rsa_trust_anchor((unsigned char *)TA725_DN, sizeof TA725_DN, (unsigned char *)TA725_RSA_N, sizeof TA725_RSA_N, (unsigned char *)TA725_RSA_E, sizeof TA725_RSA_E); + trust_anchors[726] = make_rsa_trust_anchor((unsigned char *)TA726_DN, sizeof TA726_DN, (unsigned char *)TA726_RSA_N, sizeof TA726_RSA_N, (unsigned char *)TA726_RSA_E, sizeof TA726_RSA_E); + trust_anchors[727] = make_ec_trust_anchor((unsigned char *)TA727_DN, sizeof TA727_DN, BR_EC_secp384r1, (unsigned char *)TA727_EC_Q, sizeof TA727_EC_Q); + trust_anchors[728] = make_rsa_trust_anchor((unsigned char *)TA728_DN, sizeof TA728_DN, (unsigned char *)TA728_RSA_N, sizeof TA728_RSA_N, (unsigned char *)TA728_RSA_E, sizeof TA728_RSA_E); + trust_anchors[729] = make_rsa_trust_anchor((unsigned char *)TA729_DN, sizeof TA729_DN, (unsigned char *)TA729_RSA_N, sizeof TA729_RSA_N, (unsigned char *)TA729_RSA_E, sizeof TA729_RSA_E); + trust_anchors[730] = make_rsa_trust_anchor((unsigned char *)TA730_DN, sizeof TA730_DN, (unsigned char *)TA730_RSA_N, sizeof TA730_RSA_N, (unsigned char *)TA730_RSA_E, sizeof TA730_RSA_E); + trust_anchors[731] = make_rsa_trust_anchor((unsigned char *)TA731_DN, sizeof TA731_DN, (unsigned char *)TA731_RSA_N, sizeof TA731_RSA_N, (unsigned char *)TA731_RSA_E, sizeof TA731_RSA_E); + trust_anchors[732] = make_ec_trust_anchor((unsigned char *)TA732_DN, sizeof TA732_DN, BR_EC_secp384r1, (unsigned char *)TA732_EC_Q, sizeof TA732_EC_Q); + trust_anchors[733] = make_rsa_trust_anchor((unsigned char *)TA733_DN, sizeof TA733_DN, (unsigned char *)TA733_RSA_N, sizeof TA733_RSA_N, (unsigned char *)TA733_RSA_E, sizeof TA733_RSA_E); + trust_anchors[734] = make_ec_trust_anchor((unsigned char *)TA734_DN, sizeof TA734_DN, BR_EC_secp256r1, (unsigned char *)TA734_EC_Q, sizeof TA734_EC_Q); + trust_anchors[735] = make_ec_trust_anchor((unsigned char *)TA735_DN, sizeof TA735_DN, BR_EC_secp384r1, (unsigned char *)TA735_EC_Q, sizeof TA735_EC_Q); + trust_anchors[736] = make_rsa_trust_anchor((unsigned char *)TA736_DN, sizeof TA736_DN, (unsigned char *)TA736_RSA_N, sizeof TA736_RSA_N, (unsigned char *)TA736_RSA_E, sizeof TA736_RSA_E); + trust_anchors[737] = make_rsa_trust_anchor((unsigned char *)TA737_DN, sizeof TA737_DN, (unsigned char *)TA737_RSA_N, sizeof TA737_RSA_N, (unsigned char *)TA737_RSA_E, sizeof TA737_RSA_E); + trust_anchors[738] = make_rsa_trust_anchor((unsigned char *)TA738_DN, sizeof TA738_DN, (unsigned char *)TA738_RSA_N, sizeof TA738_RSA_N, (unsigned char *)TA738_RSA_E, sizeof TA738_RSA_E); + trust_anchors[739] = make_rsa_trust_anchor((unsigned char *)TA739_DN, sizeof TA739_DN, (unsigned char *)TA739_RSA_N, sizeof TA739_RSA_N, (unsigned char *)TA739_RSA_E, sizeof TA739_RSA_E); + trust_anchors[740] = make_rsa_trust_anchor((unsigned char *)TA740_DN, sizeof TA740_DN, (unsigned char *)TA740_RSA_N, sizeof TA740_RSA_N, (unsigned char *)TA740_RSA_E, sizeof TA740_RSA_E); + trust_anchors[741] = make_rsa_trust_anchor((unsigned char *)TA741_DN, sizeof TA741_DN, (unsigned char *)TA741_RSA_N, sizeof TA741_RSA_N, (unsigned char *)TA741_RSA_E, sizeof TA741_RSA_E); + trust_anchors[742] = make_rsa_trust_anchor((unsigned char *)TA742_DN, sizeof TA742_DN, (unsigned char *)TA742_RSA_N, sizeof TA742_RSA_N, (unsigned char *)TA742_RSA_E, sizeof TA742_RSA_E); + trust_anchors[743] = make_rsa_trust_anchor((unsigned char *)TA743_DN, sizeof TA743_DN, (unsigned char *)TA743_RSA_N, sizeof TA743_RSA_N, (unsigned char *)TA743_RSA_E, sizeof TA743_RSA_E); + trust_anchors[744] = make_rsa_trust_anchor((unsigned char *)TA744_DN, sizeof TA744_DN, (unsigned char *)TA744_RSA_N, sizeof TA744_RSA_N, (unsigned char *)TA744_RSA_E, sizeof TA744_RSA_E); + trust_anchors[745] = make_ec_trust_anchor((unsigned char *)TA745_DN, sizeof TA745_DN, BR_EC_secp384r1, (unsigned char *)TA745_EC_Q, sizeof TA745_EC_Q); + trust_anchors[746] = make_rsa_trust_anchor((unsigned char *)TA746_DN, sizeof TA746_DN, (unsigned char *)TA746_RSA_N, sizeof TA746_RSA_N, (unsigned char *)TA746_RSA_E, sizeof TA746_RSA_E); + trust_anchors[747] = make_ec_trust_anchor((unsigned char *)TA747_DN, sizeof TA747_DN, BR_EC_secp384r1, (unsigned char *)TA747_EC_Q, sizeof TA747_EC_Q); + trust_anchors[748] = make_rsa_trust_anchor((unsigned char *)TA748_DN, sizeof TA748_DN, (unsigned char *)TA748_RSA_N, sizeof TA748_RSA_N, (unsigned char *)TA748_RSA_E, sizeof TA748_RSA_E); + trust_anchors[749] = make_rsa_trust_anchor((unsigned char *)TA749_DN, sizeof TA749_DN, (unsigned char *)TA749_RSA_N, sizeof TA749_RSA_N, (unsigned char *)TA749_RSA_E, sizeof TA749_RSA_E); +} + +void certificates::close_trust_anchors() +{ + if (trust_anchors == NULL) + { + return; + } + if (loaded_from_file) + { + ca_loader::free_trust_anchors(trust_anchors, (size_t)trust_anchor_count); + } + else + { + free(trust_anchors); + } + trust_anchors = NULL; + trust_anchor_count = 0; + loaded_from_file = 0; +} + +br_x509_trust_anchor* certificates::get_trust_anchors() +{ + return trust_anchors; +} + +int certificates::get_num_trust_anchors() +{ + return trust_anchor_count; +} + +int certificates::load_from_file(const char *path) +{ + br_x509_trust_anchor *file_anchors = NULL; + size_t file_count = 0; + + if (ca_loader::load_pem_file(path, &file_anchors, &file_count) != 0) + { + return -1; + } + + /* Release any existing trust anchors */ + close_trust_anchors(); + + trust_anchors = file_anchors; + trust_anchor_count = (int)file_count; + loaded_from_file = 1; + return 0; +} + +// Private + +br_x509_trust_anchor certificates::make_rsa_trust_anchor(unsigned char *dn, size_t dn_len, unsigned char *n, size_t n_len, unsigned char *e, size_t e_len) +{ + br_x509_trust_anchor ta; + ta.dn.data = dn; + ta.dn.len = dn_len; + ta.flags = BR_X509_TA_CA; + ta.pkey.key_type = BR_KEYTYPE_RSA; + ta.pkey.key.rsa.n = n; + ta.pkey.key.rsa.nlen = n_len; + ta.pkey.key.rsa.e = e; + ta.pkey.key.rsa.elen = e_len; + return ta; +} + +br_x509_trust_anchor certificates::make_ec_trust_anchor(unsigned char *dn, size_t dn_len, int curve, unsigned char *q, size_t q_len) +{ + br_x509_trust_anchor ta; + ta.dn.data = dn; + ta.dn.len = dn_len; + ta.flags = BR_X509_TA_CA; + ta.pkey.key_type = BR_KEYTYPE_EC; + ta.pkey.key.ec.curve = curve; + ta.pkey.key.ec.q = q; + ta.pkey.key.ec.qlen = q_len; + return ta; +} diff --git a/BearSSL-OG/certificates.h b/BearSSL-OG/certificates.h new file mode 100644 index 0000000..def3705 --- /dev/null +++ b/BearSSL-OG/certificates.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +class certificates +{ +public: + static void initialize_trust_anchors(); + static void close_trust_anchors(); + static br_x509_trust_anchor* get_trust_anchors(); + static int get_num_trust_anchors(); + + /* + * Try to load trust anchors from a PEM CA bundle file. + * If successful, replaces the compiled-in trust store. + * Returns 0 on success, -1 on failure (compiled-in CAs unchanged). + */ + static int load_from_file(const char *path); + +private: + static br_x509_trust_anchor make_rsa_trust_anchor(unsigned char *dn, size_t dn_len, unsigned char *n, size_t n_len, unsigned char *e, size_t e_len); + static br_x509_trust_anchor make_ec_trust_anchor(unsigned char *dn, size_t dn_len, int curve, unsigned char *q, size_t q_len); +}; diff --git a/BearSSL-OG/chain-ec+rsa.h b/BearSSL-OG/chain-ec+rsa.h new file mode 100644 index 0000000..de9792e --- /dev/null +++ b/BearSSL-OG/chain-ec+rsa.h @@ -0,0 +1,171 @@ +#ifndef CHAIN_EC_RSA_H__ +#define CHAIN_EC_RSA_H__ + +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "bearssl.h" + +/* + * A sample server certificate chain with a single intermediate CA. + * Certificate key type: EC + * Signing algorithm for both certificates: RSA + */ + +static const unsigned char CERT0[] = { + 0x30, 0x82, 0x02, 0x71, 0x30, 0x82, 0x01, 0x59, 0xA0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x6E, 0x63, 0xBB, 0x49, 0xCE, 0x41, 0x7E, 0x03, 0x8C, + 0xF5, 0x46, 0xF2, 0x8A, 0xAE, 0x61, 0x08, 0x35, 0xB0, 0x94, 0xB3, 0x30, + 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, + 0x05, 0x00, 0x30, 0x27, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x43, 0x41, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x0F, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6D, 0x65, 0x64, + 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1E, 0x17, 0x0D, 0x31, + 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, + 0x17, 0x0D, 0x33, 0x37, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, + 0x35, 0x39, 0x5A, 0x30, 0x21, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x43, 0x41, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x09, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x68, 0x6F, + 0x73, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, + 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, + 0x07, 0x03, 0x42, 0x00, 0x04, 0x5F, 0x38, 0x9D, 0xA7, 0xFF, 0x4D, 0x8A, + 0xAF, 0xF6, 0x34, 0x39, 0x46, 0x1A, 0xFC, 0x3A, 0xDF, 0xF4, 0x23, 0xAA, + 0xA9, 0xEA, 0xFB, 0xC5, 0x08, 0xDE, 0x00, 0x8E, 0xBE, 0x79, 0xA5, 0x37, + 0x58, 0x4C, 0x6D, 0xDD, 0x01, 0xCA, 0xAB, 0x47, 0xDF, 0x89, 0xB6, 0xC7, + 0x17, 0x1F, 0x38, 0xFC, 0x1D, 0x20, 0x14, 0xDD, 0x45, 0xC0, 0xE0, 0x8F, + 0x93, 0x4E, 0x38, 0x0B, 0xFC, 0xE9, 0x99, 0xA1, 0x49, 0xA3, 0x66, 0x30, + 0x64, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x7C, 0xCF, 0xA3, 0xC6, 0x29, 0xF7, 0xF3, 0xC5, 0xAA, 0x19, + 0xD0, 0xC0, 0x16, 0xEB, 0xE0, 0x40, 0x0F, 0xCE, 0x44, 0xA7, 0x30, 0x1D, + 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xC3, 0x0E, 0x86, + 0xAA, 0x75, 0xB4, 0x15, 0xC0, 0xE5, 0x95, 0x09, 0x32, 0xBE, 0x5E, 0x92, + 0x75, 0xA9, 0xE4, 0x44, 0x9B, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, + 0x01, 0x01, 0xFF, 0x04, 0x02, 0x30, 0x00, 0x30, 0x14, 0x06, 0x03, 0x55, + 0x1D, 0x11, 0x04, 0x0D, 0x30, 0x0B, 0x82, 0x09, 0x6C, 0x6F, 0x63, 0x61, + 0x6C, 0x68, 0x6F, 0x73, 0x74, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, + 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x8E, 0x89, 0x63, 0xA7, 0x9B, 0xA8, 0x10, 0x8E, 0x9E, 0x18, 0xD0, + 0xA4, 0x7A, 0xDD, 0x2C, 0x82, 0x16, 0x8F, 0x0B, 0x0E, 0xD5, 0xCA, 0x57, + 0xBB, 0x5F, 0x6F, 0xFC, 0x57, 0x28, 0xC0, 0x21, 0xBA, 0xAD, 0x94, 0xA8, + 0x17, 0x42, 0x45, 0xD7, 0x31, 0xF7, 0x84, 0x57, 0x19, 0x46, 0x24, 0x3C, + 0xC7, 0x49, 0x38, 0x3F, 0x48, 0x7A, 0x09, 0x1A, 0xEB, 0x51, 0xBA, 0xC5, + 0x75, 0x8E, 0x4C, 0xB2, 0x25, 0xB0, 0xC7, 0x22, 0x3E, 0xE7, 0xE5, 0x46, + 0xDB, 0xB1, 0x36, 0xFC, 0x1B, 0x85, 0x51, 0xB0, 0xED, 0x83, 0x16, 0xF0, + 0x3A, 0x79, 0xDA, 0x5D, 0x28, 0x6A, 0xEE, 0x6A, 0x20, 0x4C, 0xB0, 0x70, + 0x5E, 0xB0, 0xED, 0x7A, 0x6D, 0x2D, 0x1A, 0xC9, 0xB4, 0x71, 0xC2, 0xC4, + 0xA3, 0x1D, 0x25, 0x86, 0x30, 0x54, 0xB1, 0x98, 0x26, 0xC1, 0x51, 0xE0, + 0xF8, 0x31, 0xAD, 0x67, 0x48, 0x9D, 0xE6, 0xA1, 0x52, 0x3B, 0x20, 0x47, + 0xC9, 0x70, 0xDA, 0x80, 0xB5, 0xA4, 0xF4, 0x3F, 0x72, 0x6B, 0x37, 0x30, + 0x57, 0x39, 0x2C, 0x46, 0x9B, 0x44, 0xF1, 0xD9, 0x4E, 0xBB, 0xA6, 0x5F, + 0xE3, 0x9A, 0xC5, 0x7F, 0x6C, 0xB6, 0x65, 0xCB, 0xBF, 0x40, 0x72, 0x92, + 0xD0, 0x68, 0xF6, 0xAE, 0x79, 0x7E, 0x24, 0xC1, 0x5B, 0x68, 0x30, 0x28, + 0x53, 0x71, 0x61, 0x7A, 0xF4, 0x36, 0x7B, 0x3B, 0xC2, 0xB6, 0xEC, 0x1F, + 0xDC, 0x30, 0x40, 0x04, 0x0D, 0xEA, 0xB3, 0x0A, 0xCF, 0x75, 0xD3, 0xBD, + 0x9E, 0xAB, 0x71, 0x71, 0x68, 0x7F, 0xA5, 0x41, 0x52, 0x00, 0xE9, 0xB3, + 0xAE, 0xE4, 0x1E, 0xF1, 0xBB, 0x69, 0xC6, 0x3B, 0xD5, 0xDE, 0xD2, 0xC2, + 0x25, 0x69, 0x08, 0x3C, 0x37, 0xCC, 0xF7, 0x82, 0x6A, 0xE5, 0xA8, 0x7B, + 0x6A, 0x02, 0xDA, 0xBD, 0xA4, 0x01, 0x33, 0x33, 0xF3, 0xDE, 0x46, 0x00, + 0xEC, 0x75, 0xCF, 0xE0, 0x7D +}; + +static const unsigned char CERT1[] = { + 0x30, 0x82, 0x03, 0x34, 0x30, 0x82, 0x02, 0x1C, 0xA0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x70, 0x0F, 0x60, 0xEE, 0xF0, 0x07, 0x9A, 0x9C, 0x69, + 0xAC, 0x97, 0x62, 0x26, 0x4F, 0x5D, 0x05, 0xB6, 0xF9, 0x8F, 0x48, 0x30, + 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, + 0x05, 0x00, 0x30, 0x1C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x43, 0x41, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x04, 0x52, 0x6F, 0x6F, 0x74, 0x30, 0x1E, 0x17, 0x0D, + 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x5A, 0x17, 0x0D, 0x33, 0x37, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, + 0x39, 0x35, 0x39, 0x5A, 0x30, 0x27, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x41, 0x31, 0x18, 0x30, 0x16, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x0F, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6D, + 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, + 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, + 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xB3, 0xE8, 0x6B, 0xAF, 0x9C, 0x16, + 0x52, 0xE3, 0x81, 0x0C, 0x50, 0xAB, 0x25, 0xCE, 0xCC, 0x0D, 0xC7, 0xF2, + 0x1F, 0x7F, 0x50, 0xDF, 0x2C, 0x5C, 0x35, 0xD6, 0x62, 0x2E, 0x63, 0x27, + 0x41, 0xA7, 0xE4, 0x53, 0xA8, 0x4B, 0x27, 0xFA, 0x13, 0x91, 0xA3, 0xFA, + 0x09, 0x4A, 0x2F, 0x3B, 0x5E, 0xCF, 0x77, 0xB3, 0x8A, 0xC1, 0xCD, 0x49, + 0x95, 0x9C, 0x75, 0x0D, 0x64, 0x74, 0xEF, 0xE4, 0xD7, 0x4B, 0xB9, 0xA1, + 0x9B, 0x68, 0xD2, 0x30, 0x71, 0x48, 0xEA, 0xF7, 0x4B, 0x14, 0xDF, 0x3F, + 0x47, 0xA9, 0xD8, 0xBB, 0xEC, 0x8F, 0x28, 0xCC, 0xFA, 0xDF, 0xB4, 0x1F, + 0x94, 0x7C, 0x96, 0xFC, 0x08, 0x05, 0x28, 0xF9, 0xE8, 0xF4, 0x2F, 0x2F, + 0xEE, 0x62, 0x9C, 0x8A, 0x3A, 0xE0, 0x85, 0x58, 0x60, 0xB6, 0x0F, 0x2D, + 0x30, 0xB4, 0xC0, 0x41, 0x54, 0x91, 0x4C, 0x1F, 0x5F, 0xAD, 0xF1, 0x19, + 0xF0, 0xC0, 0x22, 0xA6, 0x7D, 0xD8, 0x3F, 0x79, 0x34, 0x59, 0x42, 0x7B, + 0x5B, 0xB5, 0x41, 0xC4, 0x64, 0x7F, 0x52, 0xCF, 0x3C, 0x37, 0x22, 0xA1, + 0x2F, 0x79, 0x25, 0x94, 0x24, 0x41, 0xC2, 0x3F, 0xFA, 0xC7, 0x75, 0xFB, + 0x48, 0xB5, 0x0D, 0x18, 0xA7, 0xF4, 0x54, 0xF3, 0x2E, 0x6E, 0xD8, 0x43, + 0x58, 0xC4, 0xAB, 0x50, 0xE8, 0x05, 0xAD, 0x91, 0xB6, 0x1E, 0x01, 0x75, + 0xB3, 0x54, 0x9C, 0xDE, 0xA0, 0x99, 0x15, 0xFB, 0xAC, 0xF1, 0x5C, 0x97, + 0x49, 0x51, 0xCC, 0xEF, 0x58, 0x12, 0x6F, 0x73, 0x6B, 0xB3, 0x34, 0x14, + 0x01, 0x0F, 0x5A, 0x9D, 0xFA, 0xAA, 0xD6, 0x93, 0xD3, 0xE2, 0xEA, 0xC3, + 0xAB, 0xBC, 0x4E, 0xED, 0xCC, 0x51, 0xA1, 0xB8, 0xF8, 0x94, 0xB6, 0xB4, + 0x2C, 0xA8, 0x86, 0x2B, 0x1F, 0xF6, 0x51, 0x43, 0x29, 0x52, 0x5E, 0x13, + 0x89, 0xB3, 0x6A, 0x78, 0x60, 0x4E, 0x4E, 0xC0, 0x1B, 0xA5, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xA3, 0x63, 0x30, 0x61, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xC3, 0x0A, 0xBC, 0xB4, + 0x90, 0x63, 0x96, 0x92, 0x45, 0xBC, 0x27, 0xA0, 0xF0, 0x58, 0x89, 0x2A, + 0xD5, 0x78, 0x00, 0x12, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, + 0x16, 0x04, 0x14, 0x7C, 0xCF, 0xA3, 0xC6, 0x29, 0xF7, 0xF3, 0xC5, 0xAA, + 0x19, 0xD0, 0xC0, 0x16, 0xEB, 0xE0, 0x40, 0x0F, 0xCE, 0x44, 0xA7, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, + 0x02, 0x00, 0x86, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, + 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x54, 0x3B, 0xF4, 0xEA, 0xC6, 0xE4, 0xE8, 0xC0, + 0x5B, 0x12, 0xB2, 0xAD, 0xFA, 0xBD, 0xA9, 0xF4, 0x62, 0x03, 0xAD, 0x57, + 0x4C, 0x6F, 0x07, 0xA7, 0x47, 0x35, 0x75, 0x3E, 0x48, 0xA2, 0x5B, 0x71, + 0x10, 0x01, 0x8F, 0x93, 0x99, 0x9D, 0xA7, 0x47, 0xE3, 0x8E, 0x3E, 0xAF, + 0x2D, 0xBA, 0x06, 0xFE, 0xD4, 0xE4, 0x97, 0xBC, 0x10, 0x8D, 0xA6, 0xA5, + 0x3A, 0x3C, 0xE6, 0x21, 0xCB, 0x3B, 0xDA, 0x13, 0xE3, 0x4A, 0x23, 0xEB, + 0xBC, 0xBA, 0xA5, 0x90, 0x91, 0xAD, 0x55, 0x6E, 0xD5, 0xDD, 0x85, 0x4B, + 0x6B, 0x27, 0xD2, 0x39, 0x76, 0x06, 0x2E, 0xD4, 0x23, 0x5B, 0xBB, 0x55, + 0xB5, 0x49, 0x3F, 0x7D, 0x2F, 0x21, 0xCB, 0x96, 0x75, 0x19, 0x99, 0xA9, + 0x99, 0xF1, 0x0B, 0xBB, 0x3E, 0xC7, 0x10, 0xA7, 0x8B, 0x7A, 0x52, 0xB9, + 0x49, 0xE4, 0x14, 0x08, 0x78, 0xE7, 0x3D, 0xD9, 0x98, 0x57, 0xDA, 0xFF, + 0xDA, 0xB9, 0x8D, 0x66, 0x75, 0x80, 0xB5, 0x5D, 0xB9, 0xDF, 0x69, 0x65, + 0xDB, 0x16, 0xE7, 0x1E, 0xC4, 0x40, 0xE4, 0x46, 0x8A, 0x1E, 0x76, 0x32, + 0x16, 0xE7, 0x83, 0x67, 0xDA, 0x78, 0x56, 0xAB, 0x0F, 0x4C, 0x5C, 0xF1, + 0x70, 0xDA, 0x66, 0x20, 0xF4, 0xF8, 0x0F, 0xF6, 0xDC, 0x2F, 0x72, 0x97, + 0x6B, 0x78, 0x40, 0x79, 0x9D, 0x5B, 0x6D, 0xBE, 0x03, 0xCE, 0x70, 0x42, + 0xA8, 0x2A, 0x71, 0x11, 0xDF, 0x2E, 0x81, 0x01, 0xEA, 0x86, 0x12, 0x91, + 0x4F, 0xD0, 0x18, 0xED, 0x84, 0xA4, 0x48, 0x30, 0xB9, 0xB9, 0x7B, 0x56, + 0x3E, 0xEF, 0x8D, 0xE1, 0x1F, 0xFD, 0x90, 0xB2, 0x44, 0x85, 0x58, 0x6F, + 0xA7, 0x30, 0x74, 0x7C, 0xF1, 0xAE, 0x8C, 0x99, 0x3F, 0xF1, 0x4D, 0x57, + 0xC5, 0x95, 0x68, 0xC2, 0x36, 0xB2, 0xEC, 0xC2, 0x68, 0x7A, 0xC0, 0x81, + 0xA9, 0x55, 0x05, 0xE7, 0xCF, 0xAF, 0x50, 0xAC +}; + +static const br_x509_certificate CHAIN[] = { + { (unsigned char *)CERT0, sizeof CERT0 }, + { (unsigned char *)CERT1, sizeof CERT1 } +}; + +#define CHAIN_LEN 2 + +#endif /* CHAIN_EC_RSA_H__ */ diff --git a/BearSSL-OG/chain-ec.h b/BearSSL-OG/chain-ec.h new file mode 100644 index 0000000..97059bb --- /dev/null +++ b/BearSSL-OG/chain-ec.h @@ -0,0 +1,122 @@ +#ifndef CHAIN_EC_H__ +#define CHAIN_EC_H__ + +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "bearssl.h" + +/* + * A sample server certificate chain with a single intermediate CA. + * Certificate key type: EC + * Signing algorithm for both certificates: ECDSA + */ + +static const unsigned char CERT0[] = { + 0x30, 0x82, 0x01, 0xB0, 0x30, 0x82, 0x01, 0x56, 0xA0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x1C, 0x4D, 0x00, 0x91, 0x69, 0xE2, 0x46, 0xAC, 0x90, + 0x7C, 0x64, 0x5C, 0x53, 0xF1, 0xFF, 0xB7, 0xC1, 0xCB, 0x6E, 0x7A, 0x30, + 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, + 0x27, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x43, 0x41, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x0F, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6D, 0x65, 0x64, 0x69, 0x61, 0x74, + 0x65, 0x20, 0x43, 0x41, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x30, 0x30, 0x31, + 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, 0x33, + 0x37, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5A, + 0x30, 0x21, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x41, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x09, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x68, 0x6F, 0x73, 0x74, 0x30, + 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, + 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, + 0x00, 0x04, 0x5F, 0x38, 0x9D, 0xA7, 0xFF, 0x4D, 0x8A, 0xAF, 0xF6, 0x34, + 0x39, 0x46, 0x1A, 0xFC, 0x3A, 0xDF, 0xF4, 0x23, 0xAA, 0xA9, 0xEA, 0xFB, + 0xC5, 0x08, 0xDE, 0x00, 0x8E, 0xBE, 0x79, 0xA5, 0x37, 0x58, 0x4C, 0x6D, + 0xDD, 0x01, 0xCA, 0xAB, 0x47, 0xDF, 0x89, 0xB6, 0xC7, 0x17, 0x1F, 0x38, + 0xFC, 0x1D, 0x20, 0x14, 0xDD, 0x45, 0xC0, 0xE0, 0x8F, 0x93, 0x4E, 0x38, + 0x0B, 0xFC, 0xE9, 0x99, 0xA1, 0x49, 0xA3, 0x66, 0x30, 0x64, 0x30, 0x1F, + 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xF0, + 0xD0, 0xF1, 0x22, 0xF9, 0x7A, 0x48, 0x17, 0x06, 0x7B, 0x3D, 0xBD, 0xB8, + 0xF5, 0xCD, 0x55, 0x9C, 0x5C, 0x3E, 0x70, 0x30, 0x1D, 0x06, 0x03, 0x55, + 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xC3, 0x0E, 0x86, 0xAA, 0x75, 0xB4, + 0x15, 0xC0, 0xE5, 0x95, 0x09, 0x32, 0xBE, 0x5E, 0x92, 0x75, 0xA9, 0xE4, + 0x44, 0x9B, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, + 0x04, 0x02, 0x30, 0x00, 0x30, 0x14, 0x06, 0x03, 0x55, 0x1D, 0x11, 0x04, + 0x0D, 0x30, 0x0B, 0x82, 0x09, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x68, 0x6F, + 0x73, 0x74, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, + 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0x91, 0xFB, + 0xF4, 0x04, 0xD0, 0xE5, 0x2E, 0x01, 0xD4, 0x8C, 0xF0, 0x17, 0x62, 0x0F, + 0xDC, 0xCC, 0x80, 0xCA, 0x18, 0xC4, 0x40, 0x7C, 0x27, 0x03, 0xCB, 0x34, + 0x03, 0x0D, 0x9B, 0xC8, 0x59, 0x4D, 0x02, 0x20, 0x05, 0x55, 0x69, 0xE2, + 0xD8, 0xA1, 0x40, 0x33, 0x34, 0x0E, 0x7E, 0x49, 0x32, 0x64, 0x1D, 0x3F, + 0x6B, 0x1F, 0xD0, 0x2D, 0xB7, 0x2F, 0x52, 0x04, 0x56, 0xAF, 0xD3, 0x37, + 0x8F, 0x87, 0x99, 0xA2 +}; + +static const unsigned char CERT1[] = { + 0x30, 0x82, 0x01, 0xA9, 0x30, 0x82, 0x01, 0x4E, 0xA0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x20, 0xD3, 0xEB, 0xE2, 0x8C, 0xFE, 0xDA, 0xE6, 0xA3, + 0x2C, 0x5E, 0x3B, 0xF2, 0x66, 0x3A, 0x2B, 0x36, 0x7B, 0xB0, 0xCA, 0x30, + 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, + 0x1C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x43, 0x41, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x04, 0x52, 0x6F, 0x6F, 0x74, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x30, 0x30, + 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, + 0x33, 0x37, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, + 0x5A, 0x30, 0x27, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x43, 0x41, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x0F, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6D, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, + 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x70, 0x2E, 0x92, + 0x82, 0x01, 0x17, 0x6C, 0x6D, 0xAB, 0xE1, 0xD1, 0x63, 0x09, 0x48, 0x49, + 0xD2, 0xA6, 0x35, 0x52, 0xD3, 0x3C, 0x73, 0xBB, 0xB2, 0x88, 0x37, 0x98, + 0x87, 0xF1, 0x8D, 0xE0, 0xEC, 0x65, 0x9A, 0x0E, 0x13, 0xF5, 0xED, 0x91, + 0x61, 0xC8, 0xB6, 0x6D, 0x33, 0x84, 0x6E, 0xAE, 0x8E, 0x55, 0x80, 0xCD, + 0x49, 0x9E, 0x07, 0xBF, 0xD0, 0xAE, 0x9D, 0xE6, 0xD0, 0xB3, 0x27, 0x16, + 0xA1, 0xA3, 0x63, 0x30, 0x61, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, + 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x95, 0x41, 0xB4, 0xE2, 0x67, 0xAA, + 0xF1, 0x7F, 0xBC, 0x8F, 0x79, 0xF3, 0x68, 0x14, 0x5A, 0x6B, 0x92, 0x16, + 0xA2, 0x40, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, + 0x14, 0xF0, 0xD0, 0xF1, 0x22, 0xF9, 0x7A, 0x48, 0x17, 0x06, 0x7B, 0x3D, + 0xBD, 0xB8, 0xF5, 0xCD, 0x55, 0x9C, 0x5C, 0x3E, 0x70, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, 0x02, 0x00, + 0x86, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, + 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, + 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, + 0x21, 0x00, 0x85, 0xE3, 0x46, 0x68, 0x99, 0xD6, 0x02, 0x7A, 0x59, 0x66, + 0x1C, 0xB7, 0x4F, 0x35, 0x2D, 0x08, 0x36, 0x38, 0x61, 0x7E, 0x05, 0x48, + 0xD8, 0x69, 0x43, 0x1F, 0xEB, 0x56, 0xE9, 0xAD, 0x06, 0x0E, 0x02, 0x21, + 0x00, 0x82, 0x70, 0xB4, 0x62, 0x03, 0x49, 0x46, 0xC8, 0x54, 0x59, 0x05, + 0xD9, 0x78, 0xDB, 0x53, 0x1C, 0xE0, 0x6E, 0x66, 0xF5, 0x0F, 0x14, 0x3B, + 0xC9, 0x2D, 0x38, 0x12, 0x70, 0x91, 0x56, 0xF9, 0xA9 +}; + +static const br_x509_certificate CHAIN[] = { + { (unsigned char *)CERT0, sizeof CERT0 }, + { (unsigned char *)CERT1, sizeof CERT1 } +}; + +#define CHAIN_LEN 2 + +#endif /* CHAIN_EC_H__ */ diff --git a/BearSSL-OG/chain-rsa.h b/BearSSL-OG/chain-rsa.h new file mode 100644 index 0000000..0a695dd --- /dev/null +++ b/BearSSL-OG/chain-rsa.h @@ -0,0 +1,188 @@ +#ifndef CHAIN_RSA_H__ +#define CHAIN_RSA_H__ + +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "bearssl.h" + +/* + * A sample server certificate chain with a single intermediate CA. + * Certificate key type: RSA + * Signing algorithm for both certificates: RSA + */ + +static const unsigned char CERT0[] = { + 0x30, 0x82, 0x03, 0x3C, 0x30, 0x82, 0x02, 0x24, 0xA0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x58, 0xDA, 0xBA, 0x36, 0xCD, 0xED, 0xA0, 0xDA, 0x5C, + 0x10, 0x33, 0x73, 0x8E, 0x0C, 0x64, 0x92, 0x79, 0x92, 0xAF, 0x03, 0x30, + 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, + 0x05, 0x00, 0x30, 0x27, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x43, 0x41, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x0F, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6D, 0x65, 0x64, + 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1E, 0x17, 0x0D, 0x31, + 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, + 0x17, 0x0D, 0x33, 0x37, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, + 0x35, 0x39, 0x5A, 0x30, 0x21, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x43, 0x41, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x09, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x68, 0x6F, + 0x73, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, + 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xD4, + 0x7A, 0x1D, 0x27, 0xBA, 0x2B, 0x3A, 0x67, 0xB2, 0x91, 0x6A, 0xFB, 0xE7, + 0x83, 0x44, 0xCA, 0xED, 0x1C, 0x75, 0xAD, 0xDD, 0x4D, 0x83, 0x62, 0xD6, + 0xAA, 0x68, 0x95, 0xB2, 0x24, 0x21, 0x7B, 0x15, 0xAE, 0x2A, 0x99, 0x68, + 0x15, 0xED, 0x66, 0xF0, 0xB8, 0x58, 0xE7, 0xD3, 0xF5, 0x2E, 0xC6, 0xD9, + 0x2A, 0x5E, 0xE7, 0x0E, 0x2E, 0xE7, 0xFC, 0x67, 0x59, 0xC0, 0xC8, 0x61, + 0x7D, 0x4B, 0xA4, 0x6F, 0xDD, 0x9F, 0xD9, 0xC8, 0x85, 0x87, 0x64, 0xC7, + 0xBA, 0x1A, 0x0F, 0x29, 0xD4, 0x96, 0xA8, 0x78, 0x9A, 0x6B, 0x62, 0x20, + 0xA9, 0x32, 0xD0, 0xEE, 0xA9, 0x8C, 0x28, 0x61, 0x47, 0xA2, 0x50, 0x2A, + 0x63, 0xF6, 0x21, 0xDE, 0xDA, 0xD8, 0xD5, 0xF0, 0x7F, 0xC5, 0x00, 0x82, + 0x70, 0xE6, 0xA3, 0xBF, 0x5C, 0x89, 0x27, 0x4F, 0x51, 0x92, 0x77, 0x03, + 0xC3, 0xB0, 0xCC, 0x2E, 0x3B, 0xEC, 0x23, 0xF2, 0x2F, 0x53, 0x41, 0xAF, + 0x89, 0x93, 0xFF, 0xD2, 0x80, 0xB1, 0x43, 0x97, 0xDE, 0xD6, 0x19, 0xA0, + 0x92, 0x12, 0x7A, 0x3D, 0x66, 0x79, 0xE1, 0xC1, 0xBC, 0xE1, 0x77, 0x70, + 0xA2, 0x8B, 0x3D, 0x46, 0x84, 0x53, 0x3F, 0xE4, 0x4E, 0x42, 0x41, 0x37, + 0x92, 0x1E, 0x1F, 0xFD, 0x38, 0xB3, 0xF7, 0xEF, 0x87, 0x39, 0x80, 0xD3, + 0x56, 0xCF, 0xF4, 0xE0, 0x13, 0xDE, 0x64, 0xB0, 0x72, 0xA4, 0x03, 0x84, + 0xC4, 0x41, 0xED, 0x6F, 0xFA, 0x3E, 0xE2, 0xCA, 0x04, 0x20, 0xD2, 0xD7, + 0xDC, 0x2C, 0x82, 0x2B, 0x7A, 0xE2, 0x6D, 0xA1, 0x1C, 0x48, 0xDB, 0xCF, + 0x89, 0x4F, 0x34, 0x97, 0x3D, 0x28, 0xA8, 0x53, 0xDA, 0xE7, 0xC1, 0xE1, + 0x73, 0x15, 0xA3, 0x30, 0x76, 0x7F, 0x8F, 0x23, 0x42, 0x14, 0x3D, 0x51, + 0x34, 0xD2, 0x5A, 0xAD, 0x3C, 0x9B, 0xCB, 0xC8, 0xFE, 0x7F, 0x6E, 0x8E, + 0x40, 0xF3, 0xBD, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x66, 0x30, 0x64, + 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, + 0x14, 0xC5, 0x01, 0xAD, 0x7C, 0xE6, 0x63, 0xC9, 0x9C, 0x17, 0x5F, 0xC5, + 0xA2, 0xA7, 0xE1, 0x50, 0x5F, 0xE8, 0xF5, 0xA8, 0xC6, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xC5, 0x01, 0xAD, 0x7C, + 0xE6, 0x63, 0xC9, 0x9C, 0x17, 0x5F, 0xC5, 0xA2, 0xA7, 0xE1, 0x50, 0x5F, + 0xE8, 0xF5, 0xA8, 0xC6, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, + 0x01, 0xFF, 0x04, 0x02, 0x30, 0x00, 0x30, 0x14, 0x06, 0x03, 0x55, 0x1D, + 0x11, 0x04, 0x0D, 0x30, 0x0B, 0x82, 0x09, 0x6C, 0x6F, 0x63, 0x61, 0x6C, + 0x68, 0x6F, 0x73, 0x74, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x71, 0xB3, 0x5D, 0x21, 0xC2, 0x0E, 0xD7, 0xD0, 0xC6, 0xF8, 0x4A, 0x73, + 0x87, 0x4D, 0x22, 0x02, 0x27, 0xD0, 0xC7, 0xF8, 0xFD, 0x1A, 0x6D, 0x62, + 0x58, 0x82, 0x08, 0x76, 0x20, 0x07, 0xC0, 0x48, 0x92, 0xF3, 0xE9, 0x98, + 0x5A, 0xEB, 0x0D, 0x4E, 0x56, 0x95, 0x63, 0x68, 0x4D, 0xAB, 0xD4, 0x00, + 0x76, 0xE0, 0x37, 0xCF, 0x0B, 0x11, 0x61, 0x59, 0x5C, 0xDE, 0xF6, 0xA5, + 0x14, 0x59, 0xD9, 0x25, 0x9F, 0x59, 0xD9, 0xD3, 0x5E, 0x86, 0xAC, 0x1D, + 0xA6, 0x2C, 0x32, 0x42, 0x19, 0x32, 0x13, 0x40, 0x0B, 0x54, 0xCD, 0x67, + 0x26, 0xB6, 0xBD, 0xB4, 0x96, 0xA4, 0xCA, 0x1F, 0x7F, 0x37, 0xD6, 0xA8, + 0x75, 0xEB, 0x3A, 0x81, 0x51, 0x30, 0xB9, 0xF9, 0x4A, 0x01, 0x6F, 0xD1, + 0xD6, 0xED, 0x4F, 0xDF, 0x3F, 0x30, 0x60, 0x06, 0x67, 0x92, 0x8E, 0x61, + 0x85, 0x5F, 0x1A, 0xB5, 0x8C, 0xB3, 0x0F, 0x61, 0xA9, 0xFA, 0xDF, 0x5D, + 0xC4, 0x64, 0x00, 0xEA, 0x87, 0xB1, 0x33, 0x5F, 0x7D, 0xCB, 0xA3, 0x85, + 0x24, 0x6E, 0x2C, 0x65, 0x3B, 0xEA, 0x73, 0x3F, 0x86, 0xD3, 0xFD, 0xE8, + 0xE4, 0x02, 0xC6, 0x61, 0x6A, 0x26, 0x17, 0x52, 0x01, 0x25, 0x5C, 0x7F, + 0xA8, 0xCE, 0x69, 0x1F, 0xAC, 0x61, 0x2C, 0xB7, 0x04, 0xAF, 0xFD, 0xA4, + 0x7A, 0x99, 0xCB, 0x26, 0x15, 0x4C, 0xFF, 0x74, 0xD4, 0x73, 0x0C, 0x57, + 0x0C, 0x26, 0xEB, 0xD7, 0x2A, 0xDC, 0x5C, 0xC3, 0x41, 0xBB, 0xC2, 0xF3, + 0xCE, 0x16, 0xBD, 0x8E, 0x7B, 0xFB, 0xE9, 0xDF, 0xAB, 0x21, 0x0D, 0x91, + 0xB3, 0x8D, 0xD8, 0xCF, 0xC8, 0xF4, 0x49, 0xB9, 0xD0, 0xE3, 0x16, 0x70, + 0x3F, 0xB3, 0xDE, 0xD4, 0x07, 0x25, 0xFA, 0x46, 0x44, 0x52, 0x89, 0x4D, + 0x89, 0xC8, 0xE2, 0xCA, 0xB5, 0x33, 0x7F, 0xC7, 0x21, 0xBD, 0x28, 0xEF, + 0xFE, 0x66, 0x74, 0x03 +}; + +static const unsigned char CERT1[] = { + 0x30, 0x82, 0x03, 0x34, 0x30, 0x82, 0x02, 0x1C, 0xA0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x70, 0x0F, 0x60, 0xEE, 0xF0, 0x07, 0x9A, 0x9C, 0x69, + 0xAC, 0x97, 0x62, 0x26, 0x4F, 0x5D, 0x05, 0xB6, 0xF9, 0x8F, 0x48, 0x30, + 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, + 0x05, 0x00, 0x30, 0x1C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x43, 0x41, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x04, 0x52, 0x6F, 0x6F, 0x74, 0x30, 0x1E, 0x17, 0x0D, + 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x5A, 0x17, 0x0D, 0x33, 0x37, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, + 0x39, 0x35, 0x39, 0x5A, 0x30, 0x27, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x41, 0x31, 0x18, 0x30, 0x16, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x0F, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6D, + 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, + 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, + 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xB3, 0xE8, 0x6B, 0xAF, 0x9C, 0x16, + 0x52, 0xE3, 0x81, 0x0C, 0x50, 0xAB, 0x25, 0xCE, 0xCC, 0x0D, 0xC7, 0xF2, + 0x1F, 0x7F, 0x50, 0xDF, 0x2C, 0x5C, 0x35, 0xD6, 0x62, 0x2E, 0x63, 0x27, + 0x41, 0xA7, 0xE4, 0x53, 0xA8, 0x4B, 0x27, 0xFA, 0x13, 0x91, 0xA3, 0xFA, + 0x09, 0x4A, 0x2F, 0x3B, 0x5E, 0xCF, 0x77, 0xB3, 0x8A, 0xC1, 0xCD, 0x49, + 0x95, 0x9C, 0x75, 0x0D, 0x64, 0x74, 0xEF, 0xE4, 0xD7, 0x4B, 0xB9, 0xA1, + 0x9B, 0x68, 0xD2, 0x30, 0x71, 0x48, 0xEA, 0xF7, 0x4B, 0x14, 0xDF, 0x3F, + 0x47, 0xA9, 0xD8, 0xBB, 0xEC, 0x8F, 0x28, 0xCC, 0xFA, 0xDF, 0xB4, 0x1F, + 0x94, 0x7C, 0x96, 0xFC, 0x08, 0x05, 0x28, 0xF9, 0xE8, 0xF4, 0x2F, 0x2F, + 0xEE, 0x62, 0x9C, 0x8A, 0x3A, 0xE0, 0x85, 0x58, 0x60, 0xB6, 0x0F, 0x2D, + 0x30, 0xB4, 0xC0, 0x41, 0x54, 0x91, 0x4C, 0x1F, 0x5F, 0xAD, 0xF1, 0x19, + 0xF0, 0xC0, 0x22, 0xA6, 0x7D, 0xD8, 0x3F, 0x79, 0x34, 0x59, 0x42, 0x7B, + 0x5B, 0xB5, 0x41, 0xC4, 0x64, 0x7F, 0x52, 0xCF, 0x3C, 0x37, 0x22, 0xA1, + 0x2F, 0x79, 0x25, 0x94, 0x24, 0x41, 0xC2, 0x3F, 0xFA, 0xC7, 0x75, 0xFB, + 0x48, 0xB5, 0x0D, 0x18, 0xA7, 0xF4, 0x54, 0xF3, 0x2E, 0x6E, 0xD8, 0x43, + 0x58, 0xC4, 0xAB, 0x50, 0xE8, 0x05, 0xAD, 0x91, 0xB6, 0x1E, 0x01, 0x75, + 0xB3, 0x54, 0x9C, 0xDE, 0xA0, 0x99, 0x15, 0xFB, 0xAC, 0xF1, 0x5C, 0x97, + 0x49, 0x51, 0xCC, 0xEF, 0x58, 0x12, 0x6F, 0x73, 0x6B, 0xB3, 0x34, 0x14, + 0x01, 0x0F, 0x5A, 0x9D, 0xFA, 0xAA, 0xD6, 0x93, 0xD3, 0xE2, 0xEA, 0xC3, + 0xAB, 0xBC, 0x4E, 0xED, 0xCC, 0x51, 0xA1, 0xB8, 0xF8, 0x94, 0xB6, 0xB4, + 0x2C, 0xA8, 0x86, 0x2B, 0x1F, 0xF6, 0x51, 0x43, 0x29, 0x52, 0x5E, 0x13, + 0x89, 0xB3, 0x6A, 0x78, 0x60, 0x4E, 0x4E, 0xC0, 0x1B, 0xA5, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xA3, 0x63, 0x30, 0x61, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xC3, 0x0A, 0xBC, 0xB4, + 0x90, 0x63, 0x96, 0x92, 0x45, 0xBC, 0x27, 0xA0, 0xF0, 0x58, 0x89, 0x2A, + 0xD5, 0x78, 0x00, 0x12, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, + 0x16, 0x04, 0x14, 0x7C, 0xCF, 0xA3, 0xC6, 0x29, 0xF7, 0xF3, 0xC5, 0xAA, + 0x19, 0xD0, 0xC0, 0x16, 0xEB, 0xE0, 0x40, 0x0F, 0xCE, 0x44, 0xA7, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x01, 0x01, 0xFF, 0x04, 0x04, 0x03, + 0x02, 0x00, 0x86, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, + 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x54, 0x3B, 0xF4, 0xEA, 0xC6, 0xE4, 0xE8, 0xC0, + 0x5B, 0x12, 0xB2, 0xAD, 0xFA, 0xBD, 0xA9, 0xF4, 0x62, 0x03, 0xAD, 0x57, + 0x4C, 0x6F, 0x07, 0xA7, 0x47, 0x35, 0x75, 0x3E, 0x48, 0xA2, 0x5B, 0x71, + 0x10, 0x01, 0x8F, 0x93, 0x99, 0x9D, 0xA7, 0x47, 0xE3, 0x8E, 0x3E, 0xAF, + 0x2D, 0xBA, 0x06, 0xFE, 0xD4, 0xE4, 0x97, 0xBC, 0x10, 0x8D, 0xA6, 0xA5, + 0x3A, 0x3C, 0xE6, 0x21, 0xCB, 0x3B, 0xDA, 0x13, 0xE3, 0x4A, 0x23, 0xEB, + 0xBC, 0xBA, 0xA5, 0x90, 0x91, 0xAD, 0x55, 0x6E, 0xD5, 0xDD, 0x85, 0x4B, + 0x6B, 0x27, 0xD2, 0x39, 0x76, 0x06, 0x2E, 0xD4, 0x23, 0x5B, 0xBB, 0x55, + 0xB5, 0x49, 0x3F, 0x7D, 0x2F, 0x21, 0xCB, 0x96, 0x75, 0x19, 0x99, 0xA9, + 0x99, 0xF1, 0x0B, 0xBB, 0x3E, 0xC7, 0x10, 0xA7, 0x8B, 0x7A, 0x52, 0xB9, + 0x49, 0xE4, 0x14, 0x08, 0x78, 0xE7, 0x3D, 0xD9, 0x98, 0x57, 0xDA, 0xFF, + 0xDA, 0xB9, 0x8D, 0x66, 0x75, 0x80, 0xB5, 0x5D, 0xB9, 0xDF, 0x69, 0x65, + 0xDB, 0x16, 0xE7, 0x1E, 0xC4, 0x40, 0xE4, 0x46, 0x8A, 0x1E, 0x76, 0x32, + 0x16, 0xE7, 0x83, 0x67, 0xDA, 0x78, 0x56, 0xAB, 0x0F, 0x4C, 0x5C, 0xF1, + 0x70, 0xDA, 0x66, 0x20, 0xF4, 0xF8, 0x0F, 0xF6, 0xDC, 0x2F, 0x72, 0x97, + 0x6B, 0x78, 0x40, 0x79, 0x9D, 0x5B, 0x6D, 0xBE, 0x03, 0xCE, 0x70, 0x42, + 0xA8, 0x2A, 0x71, 0x11, 0xDF, 0x2E, 0x81, 0x01, 0xEA, 0x86, 0x12, 0x91, + 0x4F, 0xD0, 0x18, 0xED, 0x84, 0xA4, 0x48, 0x30, 0xB9, 0xB9, 0x7B, 0x56, + 0x3E, 0xEF, 0x8D, 0xE1, 0x1F, 0xFD, 0x90, 0xB2, 0x44, 0x85, 0x58, 0x6F, + 0xA7, 0x30, 0x74, 0x7C, 0xF1, 0xAE, 0x8C, 0x99, 0x3F, 0xF1, 0x4D, 0x57, + 0xC5, 0x95, 0x68, 0xC2, 0x36, 0xB2, 0xEC, 0xC2, 0x68, 0x7A, 0xC0, 0x81, + 0xA9, 0x55, 0x05, 0xE7, 0xCF, 0xAF, 0x50, 0xAC +}; + +static const br_x509_certificate CHAIN[] = { + { (unsigned char *)CERT0, sizeof CERT0 }, + { (unsigned char *)CERT1, sizeof CERT1 } +}; + +#define CHAIN_LEN 2 + +#endif /* CHAIN_RSA_H__ */ diff --git a/BearSSL-OG/client.cpp b/BearSSL-OG/client.cpp new file mode 100644 index 0000000..f99eed3 --- /dev/null +++ b/BearSSL-OG/client.cpp @@ -0,0 +1,461 @@ +#include "client.h" +#include "url_utility.h" +#include "debug_utility.h" +#include "network_utility.h" +#include "string_utility.h" +#include "socket_utility.h" +#include "certificates.h" +#include "ca_loader.h" +#include "data_store.h" + +#include +#include +#include +#include +#include +#include +#include "ssl_config.h" +#include "ssl_debug.h" +#include "session_cache.h" +#include "cert_pinning.h" + +#define READ_BUFFER_SIZE 65536 + +int client::download_file(const char* url, uint16_t port, const char* file_path) +{ + char *host = NULL; + char *path = NULL; + if (url_utility::parse_url(url, &host, &path) == false) + { + return -1; + } + + uint32_t host_ip = network_utility::resolve_host(host); + if (host_ip == 0) + { + ssl_debug::log_error("DNS resolution failed for host: %s\n", host); + free(host); + free(path); + return -3; /* DNS resolution failed */ + } + + int socket = socket_utility::connect_to_host(host_ip, port); + if (socket < 0) + { + ssl_debug::log_error("Failed to connect to %s:%d\n", host, port); + free(host); + free(path); + return -4; /* Connection failed */ + } + + /* Try loading CAs from PEM file on Xbox HDD */ + if (certificates::load_from_file(SSL_DEFAULT_CA_FILE) != 0) + { + /* No file on disk — load compiled-in CAs and auto-download */ + certificates::initialize_trust_anchors(); + ca_loader::update_trust_store(SSL_DEFAULT_CA_FILE, + certificates::get_trust_anchors(), + (size_t)certificates::get_num_trust_anchors()); + + /* If download succeeded, switch to the fresh CAs */ + certificates::load_from_file(SSL_DEFAULT_CA_FILE); + } + + br_ssl_client_context client_context; + br_x509_minimal_context cert_context; + br_ssl_client_init_full(&client_context, &cert_context, certificates::get_trust_anchors(), certificates::get_num_trust_anchors()); + + // Enforce TLS 1.2 minimum +#if SSL_ENFORCE_TLS12 + br_ssl_engine_set_versions(&client_context.eng, SSL_MIN_VERSION, SSL_MAX_VERSION); +#endif + + // Restrict to secure cipher suites +#if SSL_RESTRICT_CIPHERS + br_ssl_engine_set_suites(&client_context.eng, SSL_SECURE_SUITES, SSL_SECURE_SUITES_COUNT); +#endif + + unsigned char io_buffer[BR_SSL_BUFSIZE_BIDI]; + br_ssl_engine_set_buffer(&client_context.eng, io_buffer, BR_SSL_BUFSIZE_BIDI, 1); + + // Try to resume previous session + br_ssl_session_parameters session_params; + int resume = 0; +#if SSL_ENABLE_SESSION_CACHE + if (session_cache::get(host, &session_params)) { + br_ssl_engine_set_session_parameters(&client_context.eng, &session_params); + resume = 1; + } +#endif + + br_ssl_client_reset(&client_context, host, resume); + + br_sslio_context io_context; + br_sslio_init(&io_context, &client_context.eng, socket_utility::socket_read, &socket, socket_utility::socket_write, &socket); + + // Verify certificate pin if configured +#if SSL_ENABLE_CERT_PINNING + if (!cert_pinning::verify(host, &client_context.eng)) { + ssl_debug::log_error("Connection rejected due to certificate pin mismatch\n"); + closesocket(socket); + certificates::close_trust_anchors(); + free(host); + free(path); + return -2; // Pin verification failed + } +#endif + + char* request = string_utility::format_string("GET %s HTTP/1.1\r\nHost: %s\r\nAccept-Encoding: identity\r\nConnection: close\r\n\r\n", path, host); + if (request == NULL) + { + ssl_debug::log_error("Failed to allocate HTTP request string\n"); + closesocket(socket); + certificates::close_trust_anchors(); + free(host); + free(path); + return -5; + } + br_sslio_write_all(&io_context, request, strlen(request)); + br_sslio_flush(&io_context); + free(request); + + data_store* data = new data_store(); + pointer_vector* headers = new pointer_vector(false); + populate_headers(&io_context, data, headers); + + int64_t content_length = -1; + char* redirect_url = NULL; + + bool has_redirect = false; + for (uint32_t i = 0; i < headers->count(); i++) + { + pointer_vector* parts = string_utility::split_first(headers->get(i), ":", true); + if (parts->count() != 2) + { + continue; + } + if (strcmp(parts->get(0), "Content-Length") == 0) + { + content_length = string_utility::string_to_int64(parts->get(1)); + } + if (strcmp(parts->get(0), "Location") == 0) + { + has_redirect = true; + redirect_url = strdup(parts->get(1)); + } + delete parts; + } + + delete headers; + + if (has_redirect == true) + { + closesocket(socket); + certificates::close_trust_anchors(); + delete data; + free(host); + free(path); + + int result = download_file(redirect_url, port, file_path); + if (redirect_url != NULL) + { + free(redirect_url); + } + return result; + } + + if (redirect_url != NULL) + { + free(redirect_url); + } + + if (content_length < 0) + { + chunk_download(&io_context, data, file_path); + } + else + { + download(&io_context, data, file_path, content_length); + } + + // Cache session for future resumption +#if SSL_ENABLE_SESSION_CACHE + br_ssl_engine_get_session_parameters(&client_context.eng, &session_params); + session_cache::store(host, &session_params); +#endif + + closesocket(socket); + certificates::close_trust_anchors(); + delete data; + + int result = EXIT_FAILURE; + if (br_ssl_engine_current_state(&client_context.eng) == BR_SSL_CLOSED) + { + int error = br_ssl_engine_last_error(&client_context.eng); + if (error == 0) + { + ssl_debug::log_info("Connection closed cleanly\n"); + ssl_debug::log_handshake_result(&client_context.eng); + result = EXIT_SUCCESS; + } + else + { + ssl_debug::log_ssl_error(error); + result = EXIT_FAILURE; + } + } + else + { + ssl_debug::log_error("Socket closed without proper SSL termination\n"); + result = EXIT_FAILURE; + } + + /* Clean up allocated host and path */ + free(host); + free(path); + + return result; +} + +// Private + +/* Helper to check if character is linear whitespace (space or tab) */ +static bool is_lws(char c) +{ + return (c == ' ' || c == '\t'); +} + +void client::populate_headers(br_sslio_context* io_context, data_store* data, pointer_vector* headers) +{ + unsigned char* read_buffer = (unsigned char*)malloc(READ_BUFFER_SIZE); + if (read_buffer == NULL) + { + ssl_debug::log_error("Failed to allocate read buffer\n"); + return; + } + char* pending_header = NULL; /* For handling line continuations */ + + while (true) + { + int bytes_read = br_sslio_read(io_context, read_buffer, READ_BUFFER_SIZE); + if (bytes_read < 0) + { + break; + } + + data->add_range(read_buffer, 0, bytes_read); + + bool eof_headers = false; + while (true) + { + unsigned char* data_buffer = data->get_all(); + int offset = string_utility::find_crlf(data_buffer, data->count()); + if (offset < 0) + { + break; + } + + char* header_line = (char*)malloc(offset + 1); + if (header_line == NULL) + { + break; + } + memcpy(header_line, data_buffer, offset); + header_line[offset] = 0; + data->remove_range(0, offset + 2); + + /* Empty line signals end of headers */ + if (header_line[0] == 0) + { + free(header_line); + /* Flush any pending header */ + if (pending_header != NULL) + { + debug_utility::debug_print("Header Line: %s\n", pending_header); + headers->add(pending_header); + pending_header = NULL; + } + eof_headers = true; + break; + } + + /* RFC 7230: Line continuation - line starts with whitespace */ + if (is_lws(header_line[0]) && pending_header != NULL) + { + /* Skip leading whitespace on continuation line */ + char* continuation = header_line; + while (*continuation && is_lws(*continuation)) + { + continuation++; + } + + /* Append to pending header with single space separator */ + size_t pending_len = strlen(pending_header); + size_t cont_len = strlen(continuation); + char* merged = (char*)malloc(pending_len + 1 + cont_len + 1); + if (merged == NULL) + { + free(header_line); + free(pending_header); + pending_header = NULL; + break; + } + memcpy(merged, pending_header, pending_len); + merged[pending_len] = ' '; + memcpy(merged + pending_len + 1, continuation, cont_len + 1); + + free(pending_header); + free(header_line); + pending_header = merged; + } + else + { + /* New header - flush pending if any */ + if (pending_header != NULL) + { + debug_utility::debug_print("Header Line: %s\n", pending_header); + headers->add(pending_header); + } + pending_header = header_line; + } + } + + if (eof_headers == true) + { + break; + } + } + + /* Flush any remaining pending header */ + if (pending_header != NULL) + { + debug_utility::debug_print("Header Line: %s\n", pending_header); + headers->add(pending_header); + } + + free(read_buffer); +} + +void client::chunk_download(br_sslio_context* io_context, data_store* data, const char* file_path) +{ + unsigned char* read_buffer = (unsigned char*)malloc(READ_BUFFER_SIZE); + if (read_buffer == NULL) + { + ssl_debug::log_error("Failed to allocate read buffer\n"); + return; + } + + FILE* file = fopen(file_path, "wb"); + if (file == NULL) + { + ssl_debug::log_error("Failed to open file for writing: %s\n", file_path); + free(read_buffer); + return; + } + + int64_t chunk_size = 0; + bool looking_for_chunk_header = true; + + int64_t bytes_written = 0; + while (true) + { + int bytes_read = br_sslio_read(io_context, read_buffer, READ_BUFFER_SIZE); + if (bytes_read < 0) + { + break; + } + + data->add_range(read_buffer, 0, bytes_read); + + if (looking_for_chunk_header == true) + { + unsigned char* data_buffer = data->get_all(); + int offset = string_utility::find_crlf(data_buffer, data->count()); + if (offset < 0) + { + continue; + } + + char* chunk_hex = (char*)malloc(offset + 1); + if (chunk_hex == NULL) + { + break; + } + memcpy(chunk_hex, data_buffer, offset); + chunk_hex[offset] = 0; + + if (chunk_hex[0] != 0) + { + chunk_size = string_utility::hex_to_int64(chunk_hex); + looking_for_chunk_header = false; + } + + free(chunk_hex); + data->remove_range(0, offset + 2); + } + + if (looking_for_chunk_header == false) + { + int64_t bytes_to_get = min(chunk_size, (int64_t)data->count()); + if (bytes_to_get != chunk_size) + { + continue; + } + if (file != NULL) + { + fwrite(data->get_all(), 1, bytes_to_get, file); + } + + bytes_written += data->count(); + debug_utility::debug_print("Written %lld bytes of unknown bytes\n", bytes_written); + + data->remove_range(0, bytes_to_get); + looking_for_chunk_header = true; + } + } + + fclose(file); + free(read_buffer); +} + +void client::download(br_sslio_context* io_context, data_store* data, const char* file_path, int64_t content_length) +{ + unsigned char* read_buffer = (unsigned char*)malloc(READ_BUFFER_SIZE); + if (read_buffer == NULL) + { + ssl_debug::log_error("Failed to allocate read buffer\n"); + return; + } + + FILE* file = fopen(file_path, "wb"); + if (file == NULL) + { + ssl_debug::log_error("Failed to open file for writing: %s\n", file_path); + free(read_buffer); + return; + } + + int64_t bytes_written = 0; + while (true) + { + int bytes_read = br_sslio_read(io_context, read_buffer, READ_BUFFER_SIZE); + if (bytes_read < 0) + { + break; + } + + data->add_range(read_buffer, 0, bytes_read); + if (file != NULL) + { + fwrite(data->get_all(), 1, data->count(), file); + } + + bytes_written += data->count(); + debug_utility::debug_print("Written %lld bytes of ", bytes_written); + debug_utility::debug_print("%lld bytes\n", content_length); + data->remove_range(0, data->count()); + } + + fclose(file); + free(read_buffer); +} \ No newline at end of file diff --git a/BearSSL-OG/client.h b/BearSSL-OG/client.h new file mode 100644 index 0000000..0488e17 --- /dev/null +++ b/BearSSL-OG/client.h @@ -0,0 +1,17 @@ +#pragma once + +#include "pointer_vector.h" +#include "data_store.h" + +#include +#include + +class client +{ +public: + int download_file(const char* url, uint16_t port, const char* file_path); +private: + void populate_headers(br_sslio_context* io_context, data_store* data, pointer_vector* headers); + void chunk_download(br_sslio_context* io_context, data_store* data, const char* file_path); + void download(br_sslio_context* io_context, data_store* data, const char* file_path, int64_t content_length); +}; \ No newline at end of file diff --git a/BearSSL-OG/data_store.cpp b/BearSSL-OG/data_store.cpp new file mode 100644 index 0000000..b48cc20 --- /dev/null +++ b/BearSSL-OG/data_store.cpp @@ -0,0 +1,108 @@ +#include "data_store.h" + +#include +#include + +data_store::data_store() +{ + mSize = 0; + mMaxSize = DATA_SIZE_INCREMENT; + mValueContainer = (unsigned char*)malloc(mMaxSize); + if (mValueContainer == NULL) + { + mMaxSize = 0; + return; + } +} + +data_store::~data_store() +{ + free(mValueContainer); +} + +void data_store::add(unsigned char value) +{ + if (mSize == mMaxSize) + { + unsigned char* reallocedValueContainers = (unsigned char*)realloc(mValueContainer, (mMaxSize + DATA_SIZE_INCREMENT)); + if (reallocedValueContainers == NULL) + { + return; + } + mMaxSize += DATA_SIZE_INCREMENT; + mValueContainer = reallocedValueContainers; + } + + mValueContainer[mSize] = value; + mSize++; +} + +void data_store::add_range(unsigned char* buffer, uint32_t offset, uint32_t length) +{ + if (buffer == NULL || length == 0) + { + return; + } + for (uint32_t i = 0; i < length; i++) + { + add(buffer[offset + i]); + } +} + +void data_store::remove(uint32_t index) +{ + if (index >= mSize) + { + return; + } + for (uint32_t j = index; j < mSize - 1; j++) + { + mValueContainer[j] = mValueContainer[j + 1]; + } + mSize--; +} + +void data_store::remove_range(uint32_t index, uint32_t count) +{ + if (count == 0) + { + return; + } + if (index + count > mSize) + { + /* Clamp: remove everything from index onward */ + mSize = index; + return; + } + for (uint32_t j = index; j < mSize - count; j++) + { + mValueContainer[j] = mValueContainer[j + count]; + } + mSize -= count; +} + +unsigned char data_store::get(uint32_t index) +{ + if (index >= mSize) + { + return 0; + } + return mValueContainer[index]; +} + +unsigned char* data_store::get_all() +{ + return mValueContainer; +} + +uint32_t data_store::count() +{ + return mSize; +} + +void data_store::clear() +{ + mSize = 0; +} + + diff --git a/BearSSL-OG/data_store.h b/BearSSL-OG/data_store.h new file mode 100644 index 0000000..1524cbe --- /dev/null +++ b/BearSSL-OG/data_store.h @@ -0,0 +1,28 @@ +#pragma once + +#define DATA_SIZE_INCREMENT 65536 + +#include + +class data_store +{ +public: + data_store(); + ~data_store(); + + void add(unsigned char value); + void add_range(unsigned char* buffer, uint32_t offset, uint32_t length); + void remove(uint32_t index); + void remove_range(uint32_t index, uint32_t count); + unsigned char get(uint32_t index); + unsigned char* get_all(); + uint32_t count(); + void clear(); + +private: + + unsigned char* mValueContainer; + uint32_t mSize; + uint32_t mMaxSize; +}; + diff --git a/BearSSL-OG/debug_utility.cpp b/BearSSL-OG/debug_utility.cpp new file mode 100644 index 0000000..6ba3c4b --- /dev/null +++ b/BearSSL-OG/debug_utility.cpp @@ -0,0 +1,28 @@ +#include "debug_utility.h" + +#include +#include +#include + +int debug_utility::debug_print(const char* format, ...) +{ + /* Use a fixed buffer since VS2003 doesn't support va_copy */ + char message[512]; + va_list args; + int length; + + va_start(args, format); + length = _vsnprintf(message, sizeof(message) - 1, format, args); + va_end(args); + + /* Ensure null termination */ + if (length < 0 || length >= (int)sizeof(message)) { + message[sizeof(message) - 1] = '\0'; + length = (int)sizeof(message) - 1; + } else { + message[length] = '\0'; + } + + OutputDebugStringA(message); + return length; +} \ No newline at end of file diff --git a/BearSSL-OG/debug_utility.h b/BearSSL-OG/debug_utility.h new file mode 100644 index 0000000..62c7817 --- /dev/null +++ b/BearSSL-OG/debug_utility.h @@ -0,0 +1,7 @@ +#pragma once + +class debug_utility +{ +public: + static int debug_print(const char* format, ...); +}; diff --git a/BearSSL-OG/key-ec.h b/BearSSL-OG/key-ec.h new file mode 100644 index 0000000..1ca82f5 --- /dev/null +++ b/BearSSL-OG/key-ec.h @@ -0,0 +1,45 @@ +#ifndef KEY_EC_H__ +#define KEY_EC_H__ + +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "bearssl.h" + +/* + * The private key for the server certificate (EC). + */ + +static const unsigned char EC_X[] = { + 0x03, 0x91, 0x5B, 0x42, 0x06, 0x90, 0x73, 0x91, 0x1B, 0x48, 0xEF, 0x08, + 0xFB, 0xB5, 0xAD, 0x75, 0x65, 0xF9, 0xE6, 0xF7, 0x21, 0x47, 0x62, 0x48, + 0xFA, 0x3F, 0x97, 0x7B, 0x70, 0x9D, 0x86, 0xA5 +}; + +static const br_ec_private_key EC = { + 23, + (unsigned char *)EC_X, sizeof EC_X +}; + +#endif /* KEY_EC_H__ */ diff --git a/BearSSL-OG/key-ee-ec.pem b/BearSSL-OG/key-ee-ec.pem new file mode 100644 index 0000000..2e6a136 --- /dev/null +++ b/BearSSL-OG/key-ee-ec.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIAORW0IGkHORG0jvCPu1rXVl+eb3IUdiSPo/l3twnYaloAoGCCqGSM49AwEHoUQDQgAE +Xzidp/9Niq/2NDlGGvw63/Qjqqnq+8UI3gCOvnmlN1hMbd0ByqtH34m2xxcfOPwdIBTdRcDgj5NO +OAv86ZmhSQ== +-----END EC PRIVATE KEY----- diff --git a/BearSSL-OG/key-ee-rsa.pem b/BearSSL-OG/key-ee-rsa.pem new file mode 100644 index 0000000..e8b22b4 --- /dev/null +++ b/BearSSL-OG/key-ee-rsa.pem @@ -0,0 +1,23 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA1HodJ7orOmeykWr754NEyu0cda3dTYNi1qpolbIkIXsVriqZaBXtZvC4WOfT +9S7G2Spe5w4u5/xnWcDIYX1LpG/dn9nIhYdkx7oaDynUlqh4mmtiIKky0O6pjChhR6JQKmP2Id7a +2NXwf8UAgnDmo79ciSdPUZJ3A8OwzC477CPyL1NBr4mT/9KAsUOX3tYZoJISej1meeHBvOF3cKKL +PUaEUz/kTkJBN5IeH/04s/fvhzmA01bP9OAT3mSwcqQDhMRB7W/6PuLKBCDS19wsgit64m2hHEjb +z4lPNJc9KKhT2ufB4XMVozB2f48jQhQ9UTTSWq08m8vI/n9ujkDzvQIDAQABAoIBADzb40jzQpl+ +hT+wsIl96HDlXI76Z1Zh6SgKdF1YQpASdMHHstwE19Rx46OXd3cVWGBwifFNdzL8cU/cb6i43jcx +0X2NQCm6/6tTi05HkXw7shus4VTwkb0VdxvNnxuJCsQxkJjf/7g3AyVdtIkoNG+3ipZAW7BGLu+1 +mAjLv18h4LniI8JGWQK75z8xNQzEdOFVyqC1PujjC5emesxlRW8Ks+MzQ+20WTpHGkLAoLJZJ1XE +bDQqFbkRXu4imKLtA4iyBrEpXEKZR85tVO+NQOGdPyH/ugK23nSDcJlI2PTHSlGABTpZZUmigO4O +b8lppU7cFa2JemKG3kEj0BWDOWMCgYEA+fYynFHXcbJi7YEk2vapLMMtVZSVUeU2Ep4uH47YIiJk +XqP8YPAU3BBIb08afcw3Iyd2tjGq3nDJ7KsKUPHqeXl0vjurLmOXom8KRXvXbNJtG3AxA68miyjF ++ElnRUHx0zUFJyp5IdoGtj2i6DxA+m/E/PXEBeuaMapAfl7uIlsCgYEA2Zwa3JRR9sGW2g4RPzco +ejOwxL7faCvTHGVnejyvWVCrKTYXORVxl2LdzSXujf8mj3Ehvo+chU464STH4Urf0GCzxEQurHMW +XwfJOnNe2pvu4rSpPTMUe+6n1Kz3U+Y+8IVXTIuWG93XNvyJN1l1lnWLLvcELSmJ2befcTvi7ccC +gYEA5PwCLyvWRwTZFaRaI/EU17nRHPYpuEVXPMUFkclk/BgvhHeLay5knZiZEscPiLB8zkqHuK5V +TsNaZ+HkaHTFjRSTuvWkgrGfpqE8cpzZo4o9g4ZKkIpyr8bhXOu5nDumEgsfNlr1bupxfZ+HTmJs +UD/14JowQhAsSFUkEeBbHMMCgYEAjazgoDPAmVK4kAcQm4Ohys3UjINomD3QGHC8ygywbQnkJdSd +kgCwD8vCdEn54mD4DfOt8I83bGLeWq7Do55H0TbkUyfA622SZxR+optyagmToe3VMY8MCxP6GLDz +5Z/F4notuBw5ArOP5rDL9Uk9EVQ95bnU8kJVCXZPTD2dJQkCgYByDKfPBpVp9HUgNAPgz5pRk/VC +LvKFvs5POLWMoplC871lOOI0PyGd9b2zv3M8GN728H+hwlXyOOkOHjHn21HFcY1ncTqfVVJg7kX2 +CJiBt3sv8pZ9c9Cmq6qDSUE1qZBnztO5c1SqhACIiJAdhpvluM6JChtHYjHCP8OMhgk8hg== +-----END RSA PRIVATE KEY----- diff --git a/BearSSL-OG/key-ica-ec.pem b/BearSSL-OG/key-ica-ec.pem new file mode 100644 index 0000000..7443098 --- /dev/null +++ b/BearSSL-OG/key-ica-ec.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIEJOkvo4MZ9N+wlTodEzmWor1RauybudPe92K15viDbzoAoGCCqGSM49AwEHoUQDQgAE +cC6SggEXbG2r4dFjCUhJ0qY1UtM8c7uyiDeYh/GN4Oxlmg4T9e2RYci2bTOEbq6OVYDNSZ4Hv9Cu +nebQsycWoQ== +-----END EC PRIVATE KEY----- diff --git a/BearSSL-OG/key-ica-rsa.pem b/BearSSL-OG/key-ica-rsa.pem new file mode 100644 index 0000000..2e38e34 --- /dev/null +++ b/BearSSL-OG/key-ica-rsa.pem @@ -0,0 +1,23 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAs+hrr5wWUuOBDFCrJc7MDcfyH39Q3yxcNdZiLmMnQafkU6hLJ/oTkaP6CUov +O17Pd7OKwc1JlZx1DWR07+TXS7mhm2jSMHFI6vdLFN8/R6nYu+yPKMz637QflHyW/AgFKPno9C8v +7mKcijrghVhgtg8tMLTAQVSRTB9frfEZ8MAipn3YP3k0WUJ7W7VBxGR/Us88NyKhL3kllCRBwj/6 +x3X7SLUNGKf0VPMubthDWMSrUOgFrZG2HgF1s1Sc3qCZFfus8VyXSVHM71gSb3NrszQUAQ9anfqq +1pPT4urDq7xO7cxRobj4lLa0LKiGKx/2UUMpUl4TibNqeGBOTsAbpQIDAQABAoIBAAtBpQ85SGpK +QsZG+9ZjQIAyPPN8j05PY7uYnM8DNC8W9qHHW2B2dKf9pwTSx+7CiV+Xc7yZgBukzOwYF3r1CgV6 +aWKkZdZTGDlfXKrDJx3wQhfL/s8SODYr+nfbbcT6KXx9WnaAx1J2iA3cDjU5qN9rRqwP+yF7TZYC +NoXXGoTmHb7gj1H1IJNdiUgG0netXpM2HydRLzwHDweKav6sm4V4TTeHPYokVp8W7lL7xRhwQXVD +lcE1noY5NczXV88k9n0EbqGDwX3pJoDC/xWzBFh/+oupxotM4KY2dKJGmtKTmiIef3u43CPv5SYh +V2OcEXn+joV5qHGhg6yN+ri0/ucCgYEA4x2NBFNtbpx3lmc2r2hwfbawcTVKKlxqJWdoG2bd7HQz +bO+uqtxhLOxEou4S9uPUVylvpNlDs3xQ+DF9p8oTo5XlHvA6DT/cAjWSQ+MRHqCV30T0lDSd0McZ +4PaV1nq94bGuPVrGe/Dex5dL+VVhn2tpoqwudsyx5hHA8hFE1zcCgYEAysnhrQa1HZQ0hOaA2c/e +A8I47dEIyGi4N6uJVBUMM1ecKifs4FKybOtI+XM3mwuAXUyVQGi2SZBBpE4bN3oUDWGwYF7SAJV0 +JJHpBxlZBvYRC7Vfh8HFPYIQCynP0Q4BeQVDaCPW3puJsTWnn2lNhT/PsSm3v76JwTRrBoqaGgMC +gYAwyyiAxWu9V+BZb9NP3CBO4fEGYWyNrU0gvBahzHfhVRW3Ucc07iPygtA8MOniIRB9qWlTAVqK +NSswJ3HXmpKdkpanDvVp405hKyFBdIc5DUclsKrbLHK7aAsnSdLnQXeKBaJpjBcYiadTOi4YYz+W +AH2xdUyGOXP++dF6MDuaAQKBgQCtWyHygW5pR94R0t9J1FpuCiYSn4ULlgINjTXLzGZuqbGVlCX6 +qpdfZ1At92IMyCtHFwXsVtemUYzcAe1gYpsryVw3Njf+ScVM0fNMn02tFsQBp15wNqT/7OT8NhUz +GO8HXwl9yE2SZZKzDDQsoZ+kjqVlRU2QvDkVElN/9xK/swKBgDz6m4XHvhvITo2bd8/i4FxTN1gr +napgAc2DHOzCmeyYCjKvZAJDLeNleni1kj1UfrzVrH2BFM38asRJu8xPI4WjfH1fFktNjXVu6Ctk +YFu0/0TlWkzowZHmE/K0M0tuJLt42m/DLW8deMyl38x+PUPUZb4OdVAKAua/voOMZtQw +-----END RSA PRIVATE KEY----- diff --git a/BearSSL-OG/key-root-ec.pem b/BearSSL-OG/key-root-ec.pem new file mode 100644 index 0000000..e76db90 --- /dev/null +++ b/BearSSL-OG/key-root-ec.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEINx41f6h/utlj52XNFbIGJdkF3qZy1/g9hH2/yV4t/tnoAoGCCqGSM49AwEHoUQDQgAE +cXS6q7kwLoHV5Vf58yBoDJz5ZNu0IA1t6kDQSm5C/baaaCVE9t97xPze3Xu7xdt8dj9BZkBu26eH +wuXYxfN/jQ== +-----END EC PRIVATE KEY----- diff --git a/BearSSL-OG/key-root-rsa.pem b/BearSSL-OG/key-root-rsa.pem new file mode 100644 index 0000000..82a2eb0 --- /dev/null +++ b/BearSSL-OG/key-root-rsa.pem @@ -0,0 +1,23 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAttk01FD9s696c/HOOL9db0Xh/U6xmMZggybSF9HFt5qjwd5jOZec8F5cyBwX +uYgZbfC2LjBQoVRuk8DbzzDLnx4nefHDmVI1qj2237CtfMtJzcDt52YQKunOKB8hUPp3TC3a7zxY +606/zun7Gtqjg6PNo8qTgNza8xfMeqszgJyy1H9GP8U83GGUtycpbiq8Wwk21MY7Deu+ztsdHLwQ +anFxs/LKKJp38orsQu+xSo7i8hoyKs3ApkYsmsKFN5F/RqGTgaF0Zt+6szkgkZP6HaGohefk+Qf2 +EPaoJwG2fxLDQMPJ4rCrSRg6ZLZZt5W1ljbfImmqcmpUTicpow6XFQIDAQABAoIBAENjavKDBPWn +yygXKqtEb/GWHlNmoNKO7jv33z9TGxzvW8IULZqos3jtNiG0JNRGgiTALcx5FwZWYUiIMBq8v5bd +nKv3O+DyaP/crdzkNxRCsekoXSXGuleugsHLs1IudTA4yDMamSTkCZH/LwH3KYNXJ+9hNhqsiu9D +yqM9HIad2k/hmVFv4NDdH3VWqsQJFfrGEXgKRJKNpuzKeST3oo4iLcwH9NGiKXfjW23ekOiLYFwZ +q8Yd6tOgNLpGuDWk9rlXPJALyXFZ/3UXZaKU5f0ZRfPfMQgM8toeWeWJS0FW7g6aLCJATsfOu/II +j3nTVCPryvGF4mwe/y+Rgbd67xMCgYEA3Wpiac27hvbLzwbSTWYsKql5uKV0HTim3haNDuzMHJVY +ZRJSuTY+rZBoaiuDRKMCMI3dQM8AZUJfHQclyTxjtn17Ig8cTKMN6Wr2MRTBplCq3wNLVjbOPAE2 +cv74gUfgpRLdlyueYO7j6PcTS+l41+wB1A/zAEm346Eoxoztt5cCgYEA02ipYQFX4T+8BSkcEyzP +qeMT9d3BLPm4tTeq2sXRgcfEbF/ENcAX9OfPSEx4kVtzsfJXma5/dg0fuVgl1hO5WLBT+L6MJ/A2 +sGX3Y7x+doXI0xcNd/Epr7oWqZuCO7477vzJcNtud/KQJj2EmRNaHKKtaohqO5dnNhsM540lnDMC +gYBU40KT2eJ5ngkJeE4Mio2IVa1rE1PvGBcxsmemPzcKBl/7cAjzJU7mcCT3/3K2T+C5CMq43CQE +rmuUz3a3LkX0YytgJXbuEt10jiORMaoEv4yjL7okdaKf8r8TW5mexxXjc9Ys7PYtp6kNWhy1z+8a +qUsSKIM7qwerZ9AgP0usRQKBgQDEHy4y/coG/tdweii/aSzlT/Huf2B8VtaR1yi7eBTaLvb8CwO9 +UY1n970GN1sKjiqQhF/cBFPesmIh0bKYHQgvTLU555uiWWiC0LVmYzF2xrn9ij9GbAXeLeZkRg3V +Wq/DD+PYvNiIkhBESYG/eIJ6WjhCwna6/cQUH5gjH4AqnQKBgQCsKyjLtx+FeFu7PZ8AgCGWRVvs +suxB74pxlMqMgBbBHyAGQOTTuaaTr/gwNXAAErAXS1X9VsAcAkM/yFv19mdZmJQG9vUMOe48AZDB +c7xt3t3Ul71eAlbAYkrQGtq64yO3w7ny4C7GUVqMX03XwKToCrXqeKfGwrZGNP+lgZYrbw== +-----END RSA PRIVATE KEY----- diff --git a/BearSSL-OG/key-rsa.h b/BearSSL-OG/key-rsa.h new file mode 100644 index 0000000..da0ff38 --- /dev/null +++ b/BearSSL-OG/key-rsa.h @@ -0,0 +1,113 @@ +#ifndef KEY_RSA_H__ +#define KEY_RSA_H__ + +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "bearssl.h" + +/* + * The private key for the server certificate (RSA). + */ + +static const unsigned char RSA_P[] = { + 0xF9, 0xF6, 0x32, 0x9C, 0x51, 0xD7, 0x71, 0xB2, 0x62, 0xED, 0x81, 0x24, + 0xDA, 0xF6, 0xA9, 0x2C, 0xC3, 0x2D, 0x55, 0x94, 0x95, 0x51, 0xE5, 0x36, + 0x12, 0x9E, 0x2E, 0x1F, 0x8E, 0xD8, 0x22, 0x22, 0x64, 0x5E, 0xA3, 0xFC, + 0x60, 0xF0, 0x14, 0xDC, 0x10, 0x48, 0x6F, 0x4F, 0x1A, 0x7D, 0xCC, 0x37, + 0x23, 0x27, 0x76, 0xB6, 0x31, 0xAA, 0xDE, 0x70, 0xC9, 0xEC, 0xAB, 0x0A, + 0x50, 0xF1, 0xEA, 0x79, 0x79, 0x74, 0xBE, 0x3B, 0xAB, 0x2E, 0x63, 0x97, + 0xA2, 0x6F, 0x0A, 0x45, 0x7B, 0xD7, 0x6C, 0xD2, 0x6D, 0x1B, 0x70, 0x31, + 0x03, 0xAF, 0x26, 0x8B, 0x28, 0xC5, 0xF8, 0x49, 0x67, 0x45, 0x41, 0xF1, + 0xD3, 0x35, 0x05, 0x27, 0x2A, 0x79, 0x21, 0xDA, 0x06, 0xB6, 0x3D, 0xA2, + 0xE8, 0x3C, 0x40, 0xFA, 0x6F, 0xC4, 0xFC, 0xF5, 0xC4, 0x05, 0xEB, 0x9A, + 0x31, 0xAA, 0x40, 0x7E, 0x5E, 0xEE, 0x22, 0x5B +}; + +static const unsigned char RSA_Q[] = { + 0xD9, 0x9C, 0x1A, 0xDC, 0x94, 0x51, 0xF6, 0xC1, 0x96, 0xDA, 0x0E, 0x11, + 0x3F, 0x37, 0x28, 0x7A, 0x33, 0xB0, 0xC4, 0xBE, 0xDF, 0x68, 0x2B, 0xD3, + 0x1C, 0x65, 0x67, 0x7A, 0x3C, 0xAF, 0x59, 0x50, 0xAB, 0x29, 0x36, 0x17, + 0x39, 0x15, 0x71, 0x97, 0x62, 0xDD, 0xCD, 0x25, 0xEE, 0x8D, 0xFF, 0x26, + 0x8F, 0x71, 0x21, 0xBE, 0x8F, 0x9C, 0x85, 0x4E, 0x3A, 0xE1, 0x24, 0xC7, + 0xE1, 0x4A, 0xDF, 0xD0, 0x60, 0xB3, 0xC4, 0x44, 0x2E, 0xAC, 0x73, 0x16, + 0x5F, 0x07, 0xC9, 0x3A, 0x73, 0x5E, 0xDA, 0x9B, 0xEE, 0xE2, 0xB4, 0xA9, + 0x3D, 0x33, 0x14, 0x7B, 0xEE, 0xA7, 0xD4, 0xAC, 0xF7, 0x53, 0xE6, 0x3E, + 0xF0, 0x85, 0x57, 0x4C, 0x8B, 0x96, 0x1B, 0xDD, 0xD7, 0x36, 0xFC, 0x89, + 0x37, 0x59, 0x75, 0x96, 0x75, 0x8B, 0x2E, 0xF7, 0x04, 0x2D, 0x29, 0x89, + 0xD9, 0xB7, 0x9F, 0x71, 0x3B, 0xE2, 0xED, 0xC7 +}; + +static const unsigned char RSA_DP[] = { + 0xE4, 0xFC, 0x02, 0x2F, 0x2B, 0xD6, 0x47, 0x04, 0xD9, 0x15, 0xA4, 0x5A, + 0x23, 0xF1, 0x14, 0xD7, 0xB9, 0xD1, 0x1C, 0xF6, 0x29, 0xB8, 0x45, 0x57, + 0x3C, 0xC5, 0x05, 0x91, 0xC9, 0x64, 0xFC, 0x18, 0x2F, 0x84, 0x77, 0x8B, + 0x6B, 0x2E, 0x64, 0x9D, 0x98, 0x99, 0x12, 0xC7, 0x0F, 0x88, 0xB0, 0x7C, + 0xCE, 0x4A, 0x87, 0xB8, 0xAE, 0x55, 0x4E, 0xC3, 0x5A, 0x67, 0xE1, 0xE4, + 0x68, 0x74, 0xC5, 0x8D, 0x14, 0x93, 0xBA, 0xF5, 0xA4, 0x82, 0xB1, 0x9F, + 0xA6, 0xA1, 0x3C, 0x72, 0x9C, 0xD9, 0xA3, 0x8A, 0x3D, 0x83, 0x86, 0x4A, + 0x90, 0x8A, 0x72, 0xAF, 0xC6, 0xE1, 0x5C, 0xEB, 0xB9, 0x9C, 0x3B, 0xA6, + 0x12, 0x0B, 0x1F, 0x36, 0x5A, 0xF5, 0x6E, 0xEA, 0x71, 0x7D, 0x9F, 0x87, + 0x4E, 0x62, 0x6C, 0x50, 0x3F, 0xF5, 0xE0, 0x9A, 0x30, 0x42, 0x10, 0x2C, + 0x48, 0x55, 0x24, 0x11, 0xE0, 0x5B, 0x1C, 0xC3 +}; + +static const unsigned char RSA_DQ[] = { + 0x8D, 0xAC, 0xE0, 0xA0, 0x33, 0xC0, 0x99, 0x52, 0xB8, 0x90, 0x07, 0x10, + 0x9B, 0x83, 0xA1, 0xCA, 0xCD, 0xD4, 0x8C, 0x83, 0x68, 0x98, 0x3D, 0xD0, + 0x18, 0x70, 0xBC, 0xCA, 0x0C, 0xB0, 0x6D, 0x09, 0xE4, 0x25, 0xD4, 0x9D, + 0x92, 0x00, 0xB0, 0x0F, 0xCB, 0xC2, 0x74, 0x49, 0xF9, 0xE2, 0x60, 0xF8, + 0x0D, 0xF3, 0xAD, 0xF0, 0x8F, 0x37, 0x6C, 0x62, 0xDE, 0x5A, 0xAE, 0xC3, + 0xA3, 0x9E, 0x47, 0xD1, 0x36, 0xE4, 0x53, 0x27, 0xC0, 0xEB, 0x6D, 0x92, + 0x67, 0x14, 0x7E, 0xA2, 0x9B, 0x72, 0x6A, 0x09, 0x93, 0xA1, 0xED, 0xD5, + 0x31, 0x8F, 0x0C, 0x0B, 0x13, 0xFA, 0x18, 0xB0, 0xF3, 0xE5, 0x9F, 0xC5, + 0xE2, 0x7A, 0x2D, 0xB8, 0x1C, 0x39, 0x02, 0xB3, 0x8F, 0xE6, 0xB0, 0xCB, + 0xF5, 0x49, 0x3D, 0x11, 0x54, 0x3D, 0xE5, 0xB9, 0xD4, 0xF2, 0x42, 0x55, + 0x09, 0x76, 0x4F, 0x4C, 0x3D, 0x9D, 0x25, 0x09 +}; + +static const unsigned char RSA_IQ[] = { + 0x72, 0x0C, 0xA7, 0xCF, 0x06, 0x95, 0x69, 0xF4, 0x75, 0x20, 0x34, 0x03, + 0xE0, 0xCF, 0x9A, 0x51, 0x93, 0xF5, 0x42, 0x2E, 0xF2, 0x85, 0xBE, 0xCE, + 0x4F, 0x38, 0xB5, 0x8C, 0xA2, 0x99, 0x42, 0xF3, 0xBD, 0x65, 0x38, 0xE2, + 0x34, 0x3F, 0x21, 0x9D, 0xF5, 0xBD, 0xB3, 0xBF, 0x73, 0x3C, 0x18, 0xDE, + 0xF6, 0xF0, 0x7F, 0xA1, 0xC2, 0x55, 0xF2, 0x38, 0xE9, 0x0E, 0x1E, 0x31, + 0xE7, 0xDB, 0x51, 0xC5, 0x71, 0x8D, 0x67, 0x71, 0x3A, 0x9F, 0x55, 0x52, + 0x60, 0xEE, 0x45, 0xF6, 0x08, 0x98, 0x81, 0xB7, 0x7B, 0x2F, 0xF2, 0x96, + 0x7D, 0x73, 0xD0, 0xA6, 0xAB, 0xAA, 0x83, 0x49, 0x41, 0x35, 0xA9, 0x90, + 0x67, 0xCE, 0xD3, 0xB9, 0x73, 0x54, 0xAA, 0x84, 0x00, 0x88, 0x88, 0x90, + 0x1D, 0x86, 0x9B, 0xE5, 0xB8, 0xCE, 0x89, 0x0A, 0x1B, 0x47, 0x62, 0x31, + 0xC2, 0x3F, 0xC3, 0x8C, 0x86, 0x09, 0x3C, 0x86 +}; + +static const br_rsa_private_key RSA = { + 2048, + (unsigned char *)RSA_P, sizeof RSA_P, + (unsigned char *)RSA_Q, sizeof RSA_Q, + (unsigned char *)RSA_DP, sizeof RSA_DP, + (unsigned char *)RSA_DQ, sizeof RSA_DQ, + (unsigned char *)RSA_IQ, sizeof RSA_IQ +}; + +#endif /* KEY_RSA_H__ */ diff --git a/BearSSL-OG/libbearssl.vcproj b/BearSSL-OG/libbearssl.vcproj new file mode 100644 index 0000000..e791869 --- /dev/null +++ b/BearSSL-OG/libbearssl.vcproj @@ -0,0 +1,484 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BearSSL-OG/libbearssl/inc/bearssl.h b/BearSSL-OG/libbearssl/inc/bearssl.h new file mode 100644 index 0000000..310edb2 --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_H__ +#define BR_BEARSSL_H__ + +#include +#include + +/** \mainpage BearSSL API + * + * # API Layout + * + * The functions and structures defined by the BearSSL API are located + * in various header files: + * + * | Header file | Elements | + * | :-------------- | :------------------------------------------------ | + * | bearssl_hash.h | Hash functions | + * | bearssl_hmac.h | HMAC | + * | bearssl_kdf.h | Key Derivation Functions | + * | bearssl_rand.h | Pseudorandom byte generators | + * | bearssl_prf.h | PRF implementations (for SSL/TLS) | + * | bearssl_block.h | Symmetric encryption | + * | bearssl_aead.h | AEAD algorithms (combined encryption + MAC) | + * | bearssl_rsa.h | RSA encryption and signatures | + * | bearssl_ec.h | Elliptic curves support (including ECDSA) | + * | bearssl_ssl.h | SSL/TLS engine interface | + * | bearssl_x509.h | X.509 certificate decoding and validation | + * | bearssl_pem.h | Base64/PEM decoding support functions | + * + * Applications using BearSSL are supposed to simply include `bearssl.h` + * as follows: + * + * #include + * + * The `bearssl.h` file itself includes all the other header files. It is + * possible to include specific header files, but it has no practical + * advantage for the application. The API is separated into separate + * header files only for documentation convenience. + * + * + * # Conventions + * + * ## MUST and SHALL + * + * In all descriptions, the usual "MUST", "SHALL", "MAY",... terminology + * is used. Failure to meet requirements expressed with a "MUST" or + * "SHALL" implies undefined behaviour, which means that segmentation + * faults, buffer overflows, and other similar adverse events, may occur. + * + * In general, BearSSL is not very forgiving of programming errors, and + * does not include much failsafes or error reporting when the problem + * does not arise from external transient conditions, and can be fixed + * only in the application code. This is done so in order to make the + * total code footprint lighter. + * + * + * ## `NULL` values + * + * Function parameters with a pointer type shall not be `NULL` unless + * explicitly authorised by the documentation. As an exception, when + * the pointer aims at a sequence of bytes and is accompanied with + * a length parameter, and the length is zero (meaning that there is + * no byte at all to retrieve), then the pointer may be `NULL` even if + * not explicitly allowed. + * + * + * ## Memory Allocation + * + * BearSSL does not perform dynamic memory allocation. This implies that + * for any functionality that requires a non-transient state, the caller + * is responsible for allocating the relevant context structure. Such + * allocation can be done in any appropriate area, including static data + * segments, the heap, and the stack, provided that proper alignment is + * respected. The header files define these context structures + * (including size and contents), so the C compiler should handle + * alignment automatically. + * + * Since there is no dynamic resource allocation, there is also nothing to + * release. When the calling code is done with a BearSSL feature, it + * may simple release the context structures it allocated itself, with + * no "close function" to call. If the context structures were allocated + * on the stack (as local variables), then even that release operation is + * implicit. + * + * + * ## Structure Contents + * + * Except when explicitly indicated, structure contents are opaque: they + * are included in the header files so that calling code may know the + * structure sizes and alignment requirements, but callers SHALL NOT + * access individual fields directly. For fields that are supposed to + * be read from or written to, the API defines accessor functions (the + * simplest of these accessor functions are defined as `static inline` + * functions, and the C compiler will optimise them away). + * + * + * # API Usage + * + * BearSSL usage for running a SSL/TLS client or server is described + * on the [BearSSL Web site](https://www.bearssl.org/api1.html). The + * BearSSL source archive also comes with sample code. + */ + +#include "bearssl_hash.h" +#include "bearssl_hmac.h" +#include "bearssl_kdf.h" +#include "bearssl_rand.h" +#include "bearssl_prf.h" +#include "bearssl_block.h" +#include "bearssl_aead.h" +#include "bearssl_rsa.h" +#include "bearssl_ec.h" +#include "bearssl_ssl.h" +#include "bearssl_x509.h" +#include "bearssl_pem.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \brief Type for a configuration option. + * + * A "configuration option" is a value that is selected when the BearSSL + * library itself is compiled. Most options are boolean; their value is + * then either 1 (option is enabled) or 0 (option is disabled). Some + * values have other integer values. Option names correspond to macro + * names. Some of the options can be explicitly set in the internal + * `"config.h"` file. + */ +typedef struct { + /** \brief Configurable option name. */ + const char *name; + /** \brief Configurable option value. */ + long value; +} br_config_option; + +/** \brief Get configuration report. + * + * This function returns compiled configuration options, each as a + * 'long' value. Names match internal macro names, in particular those + * that can be set in the `"config.h"` inner file. For boolean options, + * the numerical value is 1 if enabled, 0 if disabled. For maximum + * key sizes, values are expressed in bits. + * + * The returned array is terminated by an entry whose `name` is `NULL`. + * + * \return the configuration report. + */ +const br_config_option *br_get_config(void); + +/* ======================================================================= */ + +/** \brief Version feature: support for time callback. */ +#define BR_FEATURE_X509_TIME_CALLBACK 1 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/inc/bearssl_aead.h b/BearSSL-OG/libbearssl/inc/bearssl_aead.h new file mode 100644 index 0000000..097e6e8 --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl_aead.h @@ -0,0 +1,1059 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_AEAD_H__ +#define BR_BEARSSL_AEAD_H__ + +#include +#include + +#include "bearssl_block.h" +#include "bearssl_hash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_aead.h + * + * # Authenticated Encryption with Additional Data + * + * This file documents the API for AEAD encryption. + * + * + * ## Procedural API + * + * An AEAD algorithm processes messages and provides confidentiality + * (encryption) and checked integrity (MAC). It uses the following + * parameters: + * + * - A symmetric key. Exact size depends on the AEAD algorithm. + * + * - A nonce (IV). Size depends on the AEAD algorithm; for most + * algorithms, it is crucial for security that any given nonce + * value is never used twice for the same key and distinct + * messages. + * + * - Data to encrypt and protect. + * + * - Additional authenticated data, which is covered by the MAC but + * otherwise left untouched (i.e. not encrypted). + * + * The AEAD algorithm encrypts the data, and produces an authentication + * tag. It is assumed that the encrypted data, the tag, the additional + * authenticated data and the nonce are sent to the receiver; the + * additional data and the nonce may be implicit (e.g. using elements of + * the underlying transport protocol, such as record sequence numbers). + * The receiver will recompute the tag value and compare it with the one + * received; if they match, then the data is correct, and can be + * decrypted and used; otherwise, at least one of the elements was + * altered in transit, normally leading to wholesale rejection of the + * complete message. + * + * For each AEAD algorithm, identified by a symbolic name (hereafter + * denoted as "`xxx`"), the following functions are defined: + * + * - `br_xxx_init()` + * + * Initialise the AEAD algorithm, on a provided context structure. + * Exact parameters depend on the algorithm, and may include + * pointers to extra implementations and context structures. The + * secret key is provided at this point, either directly or + * indirectly. + * + * - `br_xxx_reset()` + * + * Start a new AEAD computation. The nonce value is provided as + * parameter to this function. + * + * - `br_xxx_aad_inject()` + * + * Inject some additional authenticated data. Additional data may + * be provided in several chunks of arbitrary length. + * + * - `br_xxx_flip()` + * + * This function MUST be called after injecting all additional + * authenticated data, and before beginning to encrypt the plaintext + * (or decrypt the ciphertext). + * + * - `br_xxx_run()` + * + * Process some plaintext (to encrypt) or ciphertext (to decrypt). + * Encryption/decryption is done in place. Data may be provided in + * several chunks of arbitrary length. + * + * - `br_xxx_get_tag()` + * + * Compute the authentication tag. All message data (encrypted or + * decrypted) must have been injected at that point. Also, this + * call may modify internal context elements, so it may be called + * only once for a given AEAD computation. + * + * - `br_xxx_check_tag()` + * + * An alternative to `br_xxx_get_tag()`, meant to be used by the + * receiver: the authentication tag is internally recomputed, and + * compared with the one provided as parameter. + * + * This API makes the following assumptions on the AEAD algorithm: + * + * - Encryption does not expand the size of the ciphertext; there is + * no padding. This is true of most modern AEAD modes such as GCM. + * + * - The additional authenticated data must be processed first, + * before the encrypted/decrypted data. + * + * - Nonce, plaintext and additional authenticated data all consist + * in an integral number of bytes. There is no provision to use + * elements whose length in bits is not a multiple of 8. + * + * Each AEAD algorithm has its own requirements and limits on the sizes + * of additional data and plaintext. This API does not provide any + * way to report invalid usage; it is up to the caller to ensure that + * the provided key, nonce, and data elements all fit the algorithm's + * requirements. + * + * + * ## Object-Oriented API + * + * Each context structure begins with a field (called `vtable`) that + * points to an instance of a structure that references the relevant + * functions through pointers. Each such structure contains the + * following: + * + * - `reset` + * + * Pointer to the reset function, that allows starting a new + * computation. + * + * - `aad_inject` + * + * Pointer to the additional authenticated data injection function. + * + * - `flip` + * + * Pointer to the function that transitions from additional data + * to main message data processing. + * + * - `get_tag` + * + * Pointer to the function that computes and returns the tag. + * + * - `check_tag` + * + * Pointer to the function that computes and verifies the tag against + * a received value. + * + * Note that there is no OOP method for context initialisation: the + * various AEAD algorithms have different requirements that would not + * map well to a single initialisation API. + * + * The OOP API is not provided for CCM, due to its specific requirements + * (length of plaintext must be known in advance). + */ + +/** + * \brief Class type of an AEAD algorithm. + */ +typedef struct br_aead_class_ br_aead_class; +struct br_aead_class_ { + + /** + * \brief Size (in bytes) of authentication tags created by + * this AEAD algorithm. + */ + size_t tag_size; + + /** + * \brief Reset an AEAD context. + * + * This function resets an already initialised AEAD context for + * a new computation run. Implementations and keys are + * conserved. This function can be called at any time; it + * cancels any ongoing AEAD computation that uses the provided + * context structure. + + * The provided IV is a _nonce_. Each AEAD algorithm has its + * own requirements on IV size and contents; for most of them, + * it is crucial to security that each nonce value is used + * only once for a given secret key. + * + * \param cc AEAD context structure. + * \param iv AEAD nonce to use. + * \param len AEAD nonce length (in bytes). + */ + void (*reset)(const br_aead_class **cc, const void *iv, size_t len); + + /** + * \brief Inject additional authenticated data. + * + * The provided data is injected into a running AEAD + * computation. Additional data must be injected _before_ the + * call to `flip()`. Additional data can be injected in several + * chunks of arbitrary length. + * + * \param cc AEAD context structure. + * \param data pointer to additional authenticated data. + * \param len length of additional authenticated data (in bytes). + */ + void (*aad_inject)(const br_aead_class **cc, + const void *data, size_t len); + + /** + * \brief Finish injection of additional authenticated data. + * + * This function MUST be called before beginning the actual + * encryption or decryption (with `run()`), even if no + * additional authenticated data was injected. No additional + * authenticated data may be injected after this function call. + * + * \param cc AEAD context structure. + */ + void (*flip)(const br_aead_class **cc); + + /** + * \brief Encrypt or decrypt some data. + * + * Data encryption or decryption can be done after `flip()` has + * been called on the context. If `encrypt` is non-zero, then + * the provided data shall be plaintext, and it is encrypted in + * place. Otherwise, the data shall be ciphertext, and it is + * decrypted in place. + * + * Data may be provided in several chunks of arbitrary length. + * + * \param cc AEAD context structure. + * \param encrypt non-zero for encryption, zero for decryption. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ + void (*run)(const br_aead_class **cc, int encrypt, + void *data, size_t len); + + /** + * \brief Compute authentication tag. + * + * Compute the AEAD authentication tag. The tag length depends + * on the AEAD algorithm; it is written in the provided `tag` + * buffer. This call terminates the AEAD run: no data may be + * processed with that AEAD context afterwards, until `reset()` + * is called to initiate a new AEAD run. + * + * The tag value must normally be sent along with the encrypted + * data. When decrypting, the tag value must be recomputed and + * compared with the received tag: if the two tag values differ, + * then either the tag or the encrypted data was altered in + * transit. As an alternative to this function, the + * `check_tag()` function may be used to compute and check the + * tag value. + * + * Tag length depends on the AEAD algorithm. + * + * \param cc AEAD context structure. + * \param tag destination buffer for the tag. + */ + void (*get_tag)(const br_aead_class **cc, void *tag); + + /** + * \brief Compute and check authentication tag. + * + * This function is an alternative to `get_tag()`, and is + * normally used on the receiving end (i.e. when decrypting + * messages). The tag value is recomputed and compared with the + * provided tag value. If they match, 1 is returned; on + * mismatch, 0 is returned. A returned value of 0 means that the + * data or the tag was altered in transit, normally leading to + * wholesale rejection of the complete message. + * + * Tag length depends on the AEAD algorithm. + * + * \param cc AEAD context structure. + * \param tag tag value to compare with. + * \return 1 on success (exact match of tag value), 0 otherwise. + */ + uint32_t (*check_tag)(const br_aead_class **cc, const void *tag); + + /** + * \brief Compute authentication tag (with truncation). + * + * This function is similar to `get_tag()`, except that the tag + * length is provided. Some AEAD algorithms allow several tag + * lengths, usually by truncating the normal tag. Shorter tags + * mechanically increase success probability of forgeries. + * The range of allowed tag lengths depends on the algorithm. + * + * \param cc AEAD context structure. + * \param tag destination buffer for the tag. + * \param len tag length (in bytes). + */ + void (*get_tag_trunc)(const br_aead_class **cc, void *tag, size_t len); + + /** + * \brief Compute and check authentication tag (with truncation). + * + * This function is similar to `check_tag()` except that it + * works over an explicit tag length. See `get_tag()` for a + * discussion of explicit tag lengths; the range of allowed tag + * lengths depends on the algorithm. + * + * \param cc AEAD context structure. + * \param tag tag value to compare with. + * \param len tag length (in bytes). + * \return 1 on success (exact match of tag value), 0 otherwise. + */ + uint32_t (*check_tag_trunc)(const br_aead_class **cc, + const void *tag, size_t len); +}; + +/** + * \brief Context structure for GCM. + * + * GCM is an AEAD mode that combines a block cipher in CTR mode with a + * MAC based on GHASH, to provide authenticated encryption: + * + * - Any block cipher with 16-byte blocks can be used with GCM. + * + * - The nonce can have any length, from 0 up to 2^64-1 bits; however, + * 96-bit nonces (12 bytes) are recommended (nonces with a length + * distinct from 12 bytes are internally hashed, which risks reusing + * nonce value with a small but not always negligible probability). + * + * - Additional authenticated data may have length up to 2^64-1 bits. + * + * - Message length may range up to 2^39-256 bits at most. + * + * - The authentication tag has length 16 bytes. + * + * The GCM initialisation function receives as parameter an + * _initialised_ block cipher implementation context, with the secret + * key already set. A pointer to that context will be kept within the + * GCM context structure. It is up to the caller to allocate and + * initialise that block cipher context. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_aead_class *vtable; + +#ifndef BR_DOXYGEN_IGNORE + const br_block_ctr_class **bctx; + br_ghash gh; + unsigned char h[16]; + unsigned char j0_1[12]; + unsigned char buf[16]; + unsigned char y[16]; + uint32_t j0_2, jc; + uint64_t count_aad, count_ctr; +#endif +} br_gcm_context; + +/** + * \brief Initialize a GCM context. + * + * A block cipher implementation, with its initialised context structure, + * is provided. The block cipher MUST use 16-byte blocks in CTR mode, + * and its secret key MUST have been already set in the provided context. + * A GHASH implementation must also be provided. The parameters are linked + * in the GCM context. + * + * After this function has been called, the `br_gcm_reset()` function must + * be called, to provide the IV for GCM computation. + * + * \param ctx GCM context structure. + * \param bctx block cipher context (already initialised with secret key). + * \param gh GHASH implementation. + */ +void br_gcm_init(br_gcm_context *ctx, + const br_block_ctr_class **bctx, br_ghash gh); + +/** + * \brief Reset a GCM context. + * + * This function resets an already initialised GCM context for a new + * computation run. Implementations and keys are conserved. This function + * can be called at any time; it cancels any ongoing GCM computation that + * uses the provided context structure. + * + * The provided IV is a _nonce_. It is critical to GCM security that IV + * values are not repeated for the same encryption key. IV can have + * arbitrary length (up to 2^64-1 bits), but the "normal" length is + * 96 bits (12 bytes). + * + * \param ctx GCM context structure. + * \param iv GCM nonce to use. + * \param len GCM nonce length (in bytes). + */ +void br_gcm_reset(br_gcm_context *ctx, const void *iv, size_t len); + +/** + * \brief Inject additional authenticated data into GCM. + * + * The provided data is injected into a running GCM computation. Additional + * data must be injected _before_ the call to `br_gcm_flip()`. + * Additional data can be injected in several chunks of arbitrary length; + * the maximum total size of additional authenticated data is 2^64-1 + * bits. + * + * \param ctx GCM context structure. + * \param data pointer to additional authenticated data. + * \param len length of additional authenticated data (in bytes). + */ +void br_gcm_aad_inject(br_gcm_context *ctx, const void *data, size_t len); + +/** + * \brief Finish injection of additional authenticated data into GCM. + * + * This function MUST be called before beginning the actual encryption + * or decryption (with `br_gcm_run()`), even if no additional authenticated + * data was injected. No additional authenticated data may be injected + * after this function call. + * + * \param ctx GCM context structure. + */ +void br_gcm_flip(br_gcm_context *ctx); + +/** + * \brief Encrypt or decrypt some data with GCM. + * + * Data encryption or decryption can be done after `br_gcm_flip()` + * has been called on the context. If `encrypt` is non-zero, then the + * provided data shall be plaintext, and it is encrypted in place. + * Otherwise, the data shall be ciphertext, and it is decrypted in place. + * + * Data may be provided in several chunks of arbitrary length. The maximum + * total length for data is 2^39-256 bits, i.e. about 65 gigabytes. + * + * \param ctx GCM context structure. + * \param encrypt non-zero for encryption, zero for decryption. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ +void br_gcm_run(br_gcm_context *ctx, int encrypt, void *data, size_t len); + +/** + * \brief Compute GCM authentication tag. + * + * Compute the GCM authentication tag. The tag is a 16-byte value which + * is written in the provided `tag` buffer. This call terminates the + * GCM run: no data may be processed with that GCM context afterwards, + * until `br_gcm_reset()` is called to initiate a new GCM run. + * + * The tag value must normally be sent along with the encrypted data. + * When decrypting, the tag value must be recomputed and compared with + * the received tag: if the two tag values differ, then either the tag + * or the encrypted data was altered in transit. As an alternative to + * this function, the `br_gcm_check_tag()` function can be used to + * compute and check the tag value. + * + * \param ctx GCM context structure. + * \param tag destination buffer for the tag (16 bytes). + */ +void br_gcm_get_tag(br_gcm_context *ctx, void *tag); + +/** + * \brief Compute and check GCM authentication tag. + * + * This function is an alternative to `br_gcm_get_tag()`, normally used + * on the receiving end (i.e. when decrypting value). The tag value is + * recomputed and compared with the provided tag value. If they match, 1 + * is returned; on mismatch, 0 is returned. A returned value of 0 means + * that the data or the tag was altered in transit, normally leading to + * wholesale rejection of the complete message. + * + * \param ctx GCM context structure. + * \param tag tag value to compare with (16 bytes). + * \return 1 on success (exact match of tag value), 0 otherwise. + */ +uint32_t br_gcm_check_tag(br_gcm_context *ctx, const void *tag); + +/** + * \brief Compute GCM authentication tag (with truncation). + * + * This function is similar to `br_gcm_get_tag()`, except that it allows + * the tag to be truncated to a smaller length. The intended tag length + * is provided as `len` (in bytes); it MUST be no more than 16, but + * it may be smaller. Note that decreasing tag length mechanically makes + * forgeries easier; NIST SP 800-38D specifies that the tag length shall + * lie between 12 and 16 bytes (inclusive), but may be truncated down to + * 4 or 8 bytes, for specific applications that can tolerate it. It must + * also be noted that successful forgeries leak information on the + * authentication key, making subsequent forgeries easier. Therefore, + * tag truncation, and in particular truncation to sizes lower than 12 + * bytes, shall be envisioned only with great care. + * + * The tag is written in the provided `tag` buffer. This call terminates + * the GCM run: no data may be processed with that GCM context + * afterwards, until `br_gcm_reset()` is called to initiate a new GCM + * run. + * + * The tag value must normally be sent along with the encrypted data. + * When decrypting, the tag value must be recomputed and compared with + * the received tag: if the two tag values differ, then either the tag + * or the encrypted data was altered in transit. As an alternative to + * this function, the `br_gcm_check_tag_trunc()` function can be used to + * compute and check the tag value. + * + * \param ctx GCM context structure. + * \param tag destination buffer for the tag. + * \param len tag length (16 bytes or less). + */ +void br_gcm_get_tag_trunc(br_gcm_context *ctx, void *tag, size_t len); + +/** + * \brief Compute and check GCM authentication tag (with truncation). + * + * This function is an alternative to `br_gcm_get_tag_trunc()`, normally used + * on the receiving end (i.e. when decrypting value). The tag value is + * recomputed and compared with the provided tag value. If they match, 1 + * is returned; on mismatch, 0 is returned. A returned value of 0 means + * that the data or the tag was altered in transit, normally leading to + * wholesale rejection of the complete message. + * + * Tag length MUST be 16 bytes or less. The normal GCM tag length is 16 + * bytes. See `br_check_tag_trunc()` for some discussion on the potential + * perils of truncating authentication tags. + * + * \param ctx GCM context structure. + * \param tag tag value to compare with. + * \param len tag length (in bytes). + * \return 1 on success (exact match of tag value), 0 otherwise. + */ +uint32_t br_gcm_check_tag_trunc(br_gcm_context *ctx, + const void *tag, size_t len); + +/** + * \brief Class instance for GCM. + */ +extern const br_aead_class br_gcm_vtable; + +/** + * \brief Context structure for EAX. + * + * EAX is an AEAD mode that combines a block cipher in CTR mode with + * CBC-MAC using the same block cipher and the same key, to provide + * authenticated encryption: + * + * - Any block cipher with 16-byte blocks can be used with EAX + * (technically, other block sizes are defined as well, but this + * is not implemented by these functions; shorter blocks also + * imply numerous security issues). + * + * - The nonce can have any length, as long as nonce values are + * not reused (thus, if nonces are randomly selected, the nonce + * size should be such that reuse probability is negligible). + * + * - Additional authenticated data length is unlimited. + * + * - Message length is unlimited. + * + * - The authentication tag has length 16 bytes. + * + * The EAX initialisation function receives as parameter an + * _initialised_ block cipher implementation context, with the secret + * key already set. A pointer to that context will be kept within the + * EAX context structure. It is up to the caller to allocate and + * initialise that block cipher context. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_aead_class *vtable; + +#ifndef BR_DOXYGEN_IGNORE + const br_block_ctrcbc_class **bctx; + unsigned char L2[16]; + unsigned char L4[16]; + unsigned char nonce[16]; + unsigned char head[16]; + unsigned char ctr[16]; + unsigned char cbcmac[16]; + unsigned char buf[16]; + size_t ptr; +#endif +} br_eax_context; + +/** + * \brief EAX captured state. + * + * Some internal values computed by EAX may be captured at various + * points, and reused for another EAX run with the same secret key, + * for lower per-message overhead. Captured values do not depend on + * the nonce. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + unsigned char st[3][16]; +#endif +} br_eax_state; + +/** + * \brief Initialize an EAX context. + * + * A block cipher implementation, with its initialised context + * structure, is provided. The block cipher MUST use 16-byte blocks in + * CTR + CBC-MAC mode, and its secret key MUST have been already set in + * the provided context. The parameters are linked in the EAX context. + * + * After this function has been called, the `br_eax_reset()` function must + * be called, to provide the nonce for EAX computation. + * + * \param ctx EAX context structure. + * \param bctx block cipher context (already initialised with secret key). + */ +void br_eax_init(br_eax_context *ctx, const br_block_ctrcbc_class **bctx); + +/** + * \brief Capture pre-AAD state. + * + * This function precomputes key-dependent data, and stores it in the + * provided `st` structure. This structure should then be used with + * `br_eax_reset_pre_aad()`, or updated with `br_eax_get_aad_mac()` + * and then used with `br_eax_reset_post_aad()`. + * + * The EAX context structure is unmodified by this call. + * + * \param ctx EAX context structure. + * \param st recipient for captured state. + */ +void br_eax_capture(const br_eax_context *ctx, br_eax_state *st); + +/** + * \brief Reset an EAX context. + * + * This function resets an already initialised EAX context for a new + * computation run. Implementations and keys are conserved. This function + * can be called at any time; it cancels any ongoing EAX computation that + * uses the provided context structure. + * + * It is critical to EAX security that nonce values are not repeated for + * the same encryption key. Nonces can have arbitrary length. If nonces + * are randomly generated, then a nonce length of at least 128 bits (16 + * bytes) is recommended, to make nonce reuse probability sufficiently + * low. + * + * \param ctx EAX context structure. + * \param nonce EAX nonce to use. + * \param len EAX nonce length (in bytes). + */ +void br_eax_reset(br_eax_context *ctx, const void *nonce, size_t len); + +/** + * \brief Reset an EAX context with a pre-AAD captured state. + * + * This function is an alternative to `br_eax_reset()`, that reuses a + * previously captured state structure for lower per-message overhead. + * The state should have been populated with `br_eax_capture_state()` + * but not updated with `br_eax_get_aad_mac()`. + * + * After this function is called, additional authenticated data MUST + * be injected. At least one byte of additional authenticated data + * MUST be provided with `br_eax_aad_inject()`; computation result will + * be incorrect if `br_eax_flip()` is called right away. + * + * After injection of the AAD and call to `br_eax_flip()`, at least + * one message byte must be provided. Empty messages are not supported + * with this reset mode. + * + * \param ctx EAX context structure. + * \param st pre-AAD captured state. + * \param nonce EAX nonce to use. + * \param len EAX nonce length (in bytes). + */ +void br_eax_reset_pre_aad(br_eax_context *ctx, const br_eax_state *st, + const void *nonce, size_t len); + +/** + * \brief Reset an EAX context with a post-AAD captured state. + * + * This function is an alternative to `br_eax_reset()`, that reuses a + * previously captured state structure for lower per-message overhead. + * The state should have been populated with `br_eax_capture_state()` + * and then updated with `br_eax_get_aad_mac()`. + * + * After this function is called, message data MUST be injected. The + * `br_eax_flip()` function MUST NOT be called. At least one byte of + * message data MUST be provided with `br_eax_run()`; empty messages + * are not supported with this reset mode. + * + * \param ctx EAX context structure. + * \param st post-AAD captured state. + * \param nonce EAX nonce to use. + * \param len EAX nonce length (in bytes). + */ +void br_eax_reset_post_aad(br_eax_context *ctx, const br_eax_state *st, + const void *nonce, size_t len); + +/** + * \brief Inject additional authenticated data into EAX. + * + * The provided data is injected into a running EAX computation. Additional + * data must be injected _before_ the call to `br_eax_flip()`. + * Additional data can be injected in several chunks of arbitrary length; + * the total amount of additional authenticated data is unlimited. + * + * \param ctx EAX context structure. + * \param data pointer to additional authenticated data. + * \param len length of additional authenticated data (in bytes). + */ +void br_eax_aad_inject(br_eax_context *ctx, const void *data, size_t len); + +/** + * \brief Finish injection of additional authenticated data into EAX. + * + * This function MUST be called before beginning the actual encryption + * or decryption (with `br_eax_run()`), even if no additional authenticated + * data was injected. No additional authenticated data may be injected + * after this function call. + * + * \param ctx EAX context structure. + */ +void br_eax_flip(br_eax_context *ctx); + +/** + * \brief Obtain a copy of the MAC on additional authenticated data. + * + * This function may be called only after `br_eax_flip()`; it copies the + * AAD-specific MAC value into the provided state. The MAC value depends + * on the secret key and the additional data itself, but not on the + * nonce. The updated state `st` is meant to be used as parameter for a + * further `br_eax_reset_post_aad()` call. + * + * \param ctx EAX context structure. + * \param st captured state to update. + */ +static __inline void +br_eax_get_aad_mac(const br_eax_context *ctx, br_eax_state *st) +{ + memcpy(st->st[1], ctx->head, sizeof ctx->head); +} + +/** + * \brief Encrypt or decrypt some data with EAX. + * + * Data encryption or decryption can be done after `br_eax_flip()` + * has been called on the context. If `encrypt` is non-zero, then the + * provided data shall be plaintext, and it is encrypted in place. + * Otherwise, the data shall be ciphertext, and it is decrypted in place. + * + * Data may be provided in several chunks of arbitrary length. + * + * \param ctx EAX context structure. + * \param encrypt non-zero for encryption, zero for decryption. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ +void br_eax_run(br_eax_context *ctx, int encrypt, void *data, size_t len); + +/** + * \brief Compute EAX authentication tag. + * + * Compute the EAX authentication tag. The tag is a 16-byte value which + * is written in the provided `tag` buffer. This call terminates the + * EAX run: no data may be processed with that EAX context afterwards, + * until `br_eax_reset()` is called to initiate a new EAX run. + * + * The tag value must normally be sent along with the encrypted data. + * When decrypting, the tag value must be recomputed and compared with + * the received tag: if the two tag values differ, then either the tag + * or the encrypted data was altered in transit. As an alternative to + * this function, the `br_eax_check_tag()` function can be used to + * compute and check the tag value. + * + * \param ctx EAX context structure. + * \param tag destination buffer for the tag (16 bytes). + */ +void br_eax_get_tag(br_eax_context *ctx, void *tag); + +/** + * \brief Compute and check EAX authentication tag. + * + * This function is an alternative to `br_eax_get_tag()`, normally used + * on the receiving end (i.e. when decrypting value). The tag value is + * recomputed and compared with the provided tag value. If they match, 1 + * is returned; on mismatch, 0 is returned. A returned value of 0 means + * that the data or the tag was altered in transit, normally leading to + * wholesale rejection of the complete message. + * + * \param ctx EAX context structure. + * \param tag tag value to compare with (16 bytes). + * \return 1 on success (exact match of tag value), 0 otherwise. + */ +uint32_t br_eax_check_tag(br_eax_context *ctx, const void *tag); + +/** + * \brief Compute EAX authentication tag (with truncation). + * + * This function is similar to `br_eax_get_tag()`, except that it allows + * the tag to be truncated to a smaller length. The intended tag length + * is provided as `len` (in bytes); it MUST be no more than 16, but + * it may be smaller. Note that decreasing tag length mechanically makes + * forgeries easier; NIST SP 800-38D specifies that the tag length shall + * lie between 12 and 16 bytes (inclusive), but may be truncated down to + * 4 or 8 bytes, for specific applications that can tolerate it. It must + * also be noted that successful forgeries leak information on the + * authentication key, making subsequent forgeries easier. Therefore, + * tag truncation, and in particular truncation to sizes lower than 12 + * bytes, shall be envisioned only with great care. + * + * The tag is written in the provided `tag` buffer. This call terminates + * the EAX run: no data may be processed with that EAX context + * afterwards, until `br_eax_reset()` is called to initiate a new EAX + * run. + * + * The tag value must normally be sent along with the encrypted data. + * When decrypting, the tag value must be recomputed and compared with + * the received tag: if the two tag values differ, then either the tag + * or the encrypted data was altered in transit. As an alternative to + * this function, the `br_eax_check_tag_trunc()` function can be used to + * compute and check the tag value. + * + * \param ctx EAX context structure. + * \param tag destination buffer for the tag. + * \param len tag length (16 bytes or less). + */ +void br_eax_get_tag_trunc(br_eax_context *ctx, void *tag, size_t len); + +/** + * \brief Compute and check EAX authentication tag (with truncation). + * + * This function is an alternative to `br_eax_get_tag_trunc()`, normally used + * on the receiving end (i.e. when decrypting value). The tag value is + * recomputed and compared with the provided tag value. If they match, 1 + * is returned; on mismatch, 0 is returned. A returned value of 0 means + * that the data or the tag was altered in transit, normally leading to + * wholesale rejection of the complete message. + * + * Tag length MUST be 16 bytes or less. The normal EAX tag length is 16 + * bytes. See `br_check_tag_trunc()` for some discussion on the potential + * perils of truncating authentication tags. + * + * \param ctx EAX context structure. + * \param tag tag value to compare with. + * \param len tag length (in bytes). + * \return 1 on success (exact match of tag value), 0 otherwise. + */ +uint32_t br_eax_check_tag_trunc(br_eax_context *ctx, + const void *tag, size_t len); + +/** + * \brief Class instance for EAX. + */ +extern const br_aead_class br_eax_vtable; + +/** + * \brief Context structure for CCM. + * + * CCM is an AEAD mode that combines a block cipher in CTR mode with + * CBC-MAC using the same block cipher and the same key, to provide + * authenticated encryption: + * + * - Any block cipher with 16-byte blocks can be used with CCM + * (technically, other block sizes are defined as well, but this + * is not implemented by these functions; shorter blocks also + * imply numerous security issues). + * + * - The authentication tag length, and plaintext length, MUST be + * known when starting processing data. Plaintext and ciphertext + * can still be provided by chunks, but the total size must match + * the value provided upon initialisation. + * + * - The nonce length is constrained between 7 and 13 bytes (inclusive). + * Furthermore, the plaintext length, when encoded, must fit over + * 15-nonceLen bytes; thus, if the nonce has length 13 bytes, then + * the plaintext length cannot exceed 65535 bytes. + * + * - Additional authenticated data length is practically unlimited + * (formal limit is at 2^64 bytes). + * + * - The authentication tag has length 4 to 16 bytes (even values only). + * + * The CCM initialisation function receives as parameter an + * _initialised_ block cipher implementation context, with the secret + * key already set. A pointer to that context will be kept within the + * CCM context structure. It is up to the caller to allocate and + * initialise that block cipher context. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + const br_block_ctrcbc_class **bctx; + unsigned char ctr[16]; + unsigned char cbcmac[16]; + unsigned char tagmask[16]; + unsigned char buf[16]; + size_t ptr; + size_t tag_len; +#endif +} br_ccm_context; + +/** + * \brief Initialize a CCM context. + * + * A block cipher implementation, with its initialised context + * structure, is provided. The block cipher MUST use 16-byte blocks in + * CTR + CBC-MAC mode, and its secret key MUST have been already set in + * the provided context. The parameters are linked in the CCM context. + * + * After this function has been called, the `br_ccm_reset()` function must + * be called, to provide the nonce for CCM computation. + * + * \param ctx CCM context structure. + * \param bctx block cipher context (already initialised with secret key). + */ +void br_ccm_init(br_ccm_context *ctx, const br_block_ctrcbc_class **bctx); + +/** + * \brief Reset a CCM context. + * + * This function resets an already initialised CCM context for a new + * computation run. Implementations and keys are conserved. This function + * can be called at any time; it cancels any ongoing CCM computation that + * uses the provided context structure. + * + * The `aad_len` parameter contains the total length, in bytes, of the + * additional authenticated data. It may be zero. That length MUST be + * exact. + * + * The `data_len` parameter contains the total length, in bytes, of the + * data that will be injected (plaintext or ciphertext). That length MUST + * be exact. Moreover, that length MUST be less than 2^(8*(15-nonce_len)). + * + * The nonce length (`nonce_len`), in bytes, must be in the 7..13 range + * (inclusive). + * + * The tag length (`tag_len`), in bytes, must be in the 4..16 range, and + * be an even integer. Short tags mechanically allow for higher forgery + * probabilities; hence, tag sizes smaller than 12 bytes shall be used only + * with care. + * + * It is critical to CCM security that nonce values are not repeated for + * the same encryption key. Random generation of nonces is not generally + * recommended, due to the relatively small maximum nonce value. + * + * Returned value is 1 on success, 0 on error. An error is reported if + * the tag or nonce length is out of range, or if the + * plaintext/ciphertext length cannot be encoded with the specified + * nonce length. + * + * \param ctx CCM context structure. + * \param nonce CCM nonce to use. + * \param nonce_len CCM nonce length (in bytes, 7 to 13). + * \param aad_len additional authenticated data length (in bytes). + * \param data_len plaintext/ciphertext length (in bytes). + * \param tag_len tag length (in bytes). + * \return 1 on success, 0 on error. + */ +int br_ccm_reset(br_ccm_context *ctx, const void *nonce, size_t nonce_len, + uint64_t aad_len, uint64_t data_len, size_t tag_len); + +/** + * \brief Inject additional authenticated data into CCM. + * + * The provided data is injected into a running CCM computation. Additional + * data must be injected _before_ the call to `br_ccm_flip()`. + * Additional data can be injected in several chunks of arbitrary length, + * but the total amount MUST exactly match the value which was provided + * to `br_ccm_reset()`. + * + * \param ctx CCM context structure. + * \param data pointer to additional authenticated data. + * \param len length of additional authenticated data (in bytes). + */ +void br_ccm_aad_inject(br_ccm_context *ctx, const void *data, size_t len); + +/** + * \brief Finish injection of additional authenticated data into CCM. + * + * This function MUST be called before beginning the actual encryption + * or decryption (with `br_ccm_run()`), even if no additional authenticated + * data was injected. No additional authenticated data may be injected + * after this function call. + * + * \param ctx CCM context structure. + */ +void br_ccm_flip(br_ccm_context *ctx); + +/** + * \brief Encrypt or decrypt some data with CCM. + * + * Data encryption or decryption can be done after `br_ccm_flip()` + * has been called on the context. If `encrypt` is non-zero, then the + * provided data shall be plaintext, and it is encrypted in place. + * Otherwise, the data shall be ciphertext, and it is decrypted in place. + * + * Data may be provided in several chunks of arbitrary length, provided + * that the total length exactly matches the length provided to the + * `br_ccm_reset()` call. + * + * \param ctx CCM context structure. + * \param encrypt non-zero for encryption, zero for decryption. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ +void br_ccm_run(br_ccm_context *ctx, int encrypt, void *data, size_t len); + +/** + * \brief Compute CCM authentication tag. + * + * Compute the CCM authentication tag. This call terminates the CCM + * run: all data must have been injected with `br_ccm_run()` (in zero, + * one or more successive calls). After this function has been called, + * no more data can br processed; a `br_ccm_reset()` call is required + * to start a new message. + * + * The tag length was provided upon context initialisation (last call + * to `br_ccm_reset()`); it is returned by this function. + * + * The tag value must normally be sent along with the encrypted data. + * When decrypting, the tag value must be recomputed and compared with + * the received tag: if the two tag values differ, then either the tag + * or the encrypted data was altered in transit. As an alternative to + * this function, the `br_ccm_check_tag()` function can be used to + * compute and check the tag value. + * + * \param ctx CCM context structure. + * \param tag destination buffer for the tag (up to 16 bytes). + * \return the tag length (in bytes). + */ +size_t br_ccm_get_tag(br_ccm_context *ctx, void *tag); + +/** + * \brief Compute and check CCM authentication tag. + * + * This function is an alternative to `br_ccm_get_tag()`, normally used + * on the receiving end (i.e. when decrypting value). The tag value is + * recomputed and compared with the provided tag value. If they match, 1 + * is returned; on mismatch, 0 is returned. A returned value of 0 means + * that the data or the tag was altered in transit, normally leading to + * wholesale rejection of the complete message. + * + * \param ctx CCM context structure. + * \param tag tag value to compare with (up to 16 bytes). + * \return 1 on success (exact match of tag value), 0 otherwise. + */ +uint32_t br_ccm_check_tag(br_ccm_context *ctx, const void *tag); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/inc/bearssl_block.h b/BearSSL-OG/libbearssl/inc/bearssl_block.h new file mode 100644 index 0000000..683a490 --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl_block.h @@ -0,0 +1,2618 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_BLOCK_H__ +#define BR_BEARSSL_BLOCK_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_block.h + * + * # Block Ciphers and Symmetric Ciphers + * + * This file documents the API for block ciphers and other symmetric + * ciphers. + * + * + * ## Procedural API + * + * For a block cipher implementation, up to three separate sets of + * functions are provided, for CBC encryption, CBC decryption, and CTR + * encryption/decryption. Each set has its own context structure, + * initialised with the encryption key. + * + * For CBC encryption and decryption, the data to encrypt or decrypt is + * referenced as a sequence of blocks. The implementations assume that + * there is no partial block; no padding is applied or removed. The + * caller is responsible for handling any kind of padding. + * + * Function for CTR encryption are defined only for block ciphers with + * blocks of 16 bytes or more (i.e. AES, but not DES/3DES). + * + * Each implemented block cipher is identified by an "internal name" + * from which are derived the names of structures and functions that + * implement the cipher. For the block cipher of internal name "`xxx`", + * the following are defined: + * + * - `br_xxx_BLOCK_SIZE` + * + * A macro that evaluates to the block size (in bytes) of the + * cipher. For all implemented block ciphers, this value is a + * power of two. + * + * - `br_xxx_cbcenc_keys` + * + * Context structure that contains the subkeys resulting from the key + * expansion. These subkeys are appropriate for CBC encryption. The + * structure first field is called `vtable` and points to the + * appropriate OOP structure. + * + * - `br_xxx_cbcenc_init(br_xxx_cbcenc_keys *ctx, const void *key, size_t len)` + * + * Perform key expansion: subkeys for CBC encryption are computed and + * written in the provided context structure. The key length MUST be + * adequate for the implemented block cipher. This function also sets + * the `vtable` field. + * + * - `br_xxx_cbcenc_run(const br_xxx_cbcenc_keys *ctx, void *iv, void *data, size_t len)` + * + * Perform CBC encryption of `len` bytes, in place. The encrypted data + * replaces the cleartext. `len` MUST be a multiple of the block length + * (if it is not, the function may loop forever or overflow a buffer). + * The IV is provided with the `iv` pointer; it is also updated with + * a copy of the last encrypted block. + * + * - `br_xxx_cbcdec_keys` + * + * Context structure that contains the subkeys resulting from the key + * expansion. These subkeys are appropriate for CBC decryption. The + * structure first field is called `vtable` and points to the + * appropriate OOP structure. + * + * - `br_xxx_cbcdec_init(br_xxx_cbcenc_keys *ctx, const void *key, size_t len)` + * + * Perform key expansion: subkeys for CBC decryption are computed and + * written in the provided context structure. The key length MUST be + * adequate for the implemented block cipher. This function also sets + * the `vtable` field. + * + * - `br_xxx_cbcdec_run(const br_xxx_cbcdec_keys *ctx, void *iv, void *data, size_t num_blocks)` + * + * Perform CBC decryption of `len` bytes, in place. The decrypted data + * replaces the ciphertext. `len` MUST be a multiple of the block length + * (if it is not, the function may loop forever or overflow a buffer). + * The IV is provided with the `iv` pointer; it is also updated with + * a copy of the last _encrypted_ block. + * + * - `br_xxx_ctr_keys` + * + * Context structure that contains the subkeys resulting from the key + * expansion. These subkeys are appropriate for CTR encryption and + * decryption. The structure first field is called `vtable` and + * points to the appropriate OOP structure. + * + * - `br_xxx_ctr_init(br_xxx_ctr_keys *ctx, const void *key, size_t len)` + * + * Perform key expansion: subkeys for CTR encryption and decryption + * are computed and written in the provided context structure. The + * key length MUST be adequate for the implemented block cipher. This + * function also sets the `vtable` field. + * + * - `br_xxx_ctr_run(const br_xxx_ctr_keys *ctx, const void *iv, uint32_t cc, void *data, size_t len)` (returns `uint32_t`) + * + * Perform CTR encryption/decryption of some data. Processing is done + * "in place" (the output data replaces the input data). This function + * implements the "standard incrementing function" from NIST SP800-38A, + * annex B: the IV length shall be 4 bytes less than the block size + * (i.e. 12 bytes for AES) and the counter is the 32-bit value starting + * with `cc`. The data length (`len`) is not necessarily a multiple of + * the block size. The new counter value is returned, which supports + * chunked processing, provided that each chunk length (except possibly + * the last one) is a multiple of the block size. + * + * - `br_xxx_ctrcbc_keys` + * + * Context structure that contains the subkeys resulting from the + * key expansion. These subkeys are appropriate for doing combined + * CTR encryption/decryption and CBC-MAC, as used in the CCM and EAX + * authenticated encryption modes. The structure first field is + * called `vtable` and points to the appropriate OOP structure. + * + * - `br_xxx_ctrcbc_init(br_xxx_ctr_keys *ctx, const void *key, size_t len)` + * + * Perform key expansion: subkeys for combined CTR + * encryption/decryption and CBC-MAC are computed and written in the + * provided context structure. The key length MUST be adequate for + * the implemented block cipher. This function also sets the + * `vtable` field. + * + * - `br_xxx_ctrcbc_encrypt(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len)` + * + * Perform CTR encryption of some data, and CBC-MAC. Processing is + * done "in place" (the output data replaces the input data). This + * function applies CTR encryption on the data, using a full + * block-size counter (i.e. for 128-bit blocks, the counter is + * incremented as a 128-bit value). The 'ctr' array contains the + * initial value for the counter (used in the first block) and it is + * updated with the new value after data processing. The 'cbcmac' + * value shall point to a block-sized value which is used as IV for + * CBC-MAC, computed over the encrypted data (output of CTR + * encryption); the resulting CBC-MAC is written over 'cbcmac' on + * output. + * + * The data length MUST be a multiple of the block size. + * + * - `br_xxx_ctrcbc_decrypt(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len)` + * + * Perform CTR decryption of some data, and CBC-MAC. Processing is + * done "in place" (the output data replaces the input data). This + * function applies CTR decryption on the data, using a full + * block-size counter (i.e. for 128-bit blocks, the counter is + * incremented as a 128-bit value). The 'ctr' array contains the + * initial value for the counter (used in the first block) and it is + * updated with the new value after data processing. The 'cbcmac' + * value shall point to a block-sized value which is used as IV for + * CBC-MAC, computed over the encrypted data (input of CTR + * encryption); the resulting CBC-MAC is written over 'cbcmac' on + * output. + * + * The data length MUST be a multiple of the block size. + * + * - `br_xxx_ctrcbc_ctr(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *data, size_t len)` + * + * Perform CTR encryption or decryption of the provided data. The + * data is processed "in place" (the output data replaces the input + * data). A full block-sized counter is applied (i.e. for 128-bit + * blocks, the counter is incremented as a 128-bit value). The 'ctr' + * array contains the initial value for the counter (used in the + * first block), and it is updated with the new value after data + * processing. + * + * The data length MUST be a multiple of the block size. + * + * - `br_xxx_ctrcbc_mac(const br_xxx_ctrcbc_keys *ctx, void *cbcmac, const void *data, size_t len)` + * + * Compute CBC-MAC over the provided data. The IV for CBC-MAC is + * provided as 'cbcmac'; the output is written over the same array. + * The data itself is untouched. The data length MUST be a multiple + * of the block size. + * + * + * It shall be noted that the key expansion functions return `void`. If + * the provided key length is not allowed, then there will be no error + * reporting; implementations need not validate the key length, thus an + * invalid key length may result in undefined behaviour (e.g. buffer + * overflow). + * + * Subkey structures contain no interior pointer, and no external + * resources are allocated upon key expansion. They can thus be + * discarded without any explicit deallocation. + * + * + * ## Object-Oriented API + * + * Each context structure begins with a field (called `vtable`) that + * points to an instance of a structure that references the relevant + * functions through pointers. Each such structure contains the + * following: + * + * - `context_size` + * + * The size (in bytes) of the context structure for subkeys. + * + * - `block_size` + * + * The cipher block size (in bytes). + * + * - `log_block_size` + * + * The base-2 logarithm of cipher block size (e.g. 4 for blocks + * of 16 bytes). + * + * - `init` + * + * Pointer to the key expansion function. + * + * - `run` + * + * Pointer to the encryption/decryption function. + * + * For combined CTR/CBC-MAC encryption, the `vtable` has a slightly + * different structure: + * + * - `context_size` + * + * The size (in bytes) of the context structure for subkeys. + * + * - `block_size` + * + * The cipher block size (in bytes). + * + * - `log_block_size` + * + * The base-2 logarithm of cipher block size (e.g. 4 for blocks + * of 16 bytes). + * + * - `init` + * + * Pointer to the key expansion function. + * + * - `encrypt` + * + * Pointer to the CTR encryption + CBC-MAC function. + * + * - `decrypt` + * + * Pointer to the CTR decryption + CBC-MAC function. + * + * - `ctr` + * + * Pointer to the CTR encryption/decryption function. + * + * - `mac` + * + * Pointer to the CBC-MAC function. + * + * For block cipher "`xxx`", static, constant instances of these + * structures are defined, under the names: + * + * - `br_xxx_cbcenc_vtable` + * - `br_xxx_cbcdec_vtable` + * - `br_xxx_ctr_vtable` + * - `br_xxx_ctrcbc_vtable` + * + * + * ## Implemented Block Ciphers + * + * Provided implementations are: + * + * | Name | Function | Block Size (bytes) | Key lengths (bytes) | + * | :-------- | :------- | :----------------: | :-----------------: | + * | aes_big | AES | 16 | 16, 24 and 32 | + * | aes_small | AES | 16 | 16, 24 and 32 | + * | aes_ct | AES | 16 | 16, 24 and 32 | + * | aes_ct64 | AES | 16 | 16, 24 and 32 | + * | aes_x86ni | AES | 16 | 16, 24 and 32 | + * | aes_pwr8 | AES | 16 | 16, 24 and 32 | + * | des_ct | DES/3DES | 8 | 8, 16 and 24 | + * | des_tab | DES/3DES | 8 | 8, 16 and 24 | + * + * **Note:** DES/3DES nominally uses keys of 64, 128 and 192 bits (i.e. 8, + * 16 and 24 bytes), but some of the bits are ignored by the algorithm, so + * the _effective_ key lengths, from a security point of view, are 56, + * 112 and 168 bits, respectively. + * + * `aes_big` is a "classical" AES implementation, using tables. It + * is fast but not constant-time, since it makes data-dependent array + * accesses. + * + * `aes_small` is an AES implementation optimized for code size. It + * is substantially slower than `aes_big`; it is not constant-time + * either. + * + * `aes_ct` is a constant-time implementation of AES; its code is about + * as big as that of `aes_big`, while its performance is comparable to + * that of `aes_small`. However, it is constant-time. This + * implementation should thus be considered to be the "default" AES in + * BearSSL, to be used unless the operational context guarantees that a + * non-constant-time implementation is safe, or an architecture-specific + * constant-time implementation can be used (e.g. using dedicated + * hardware opcodes). + * + * `aes_ct64` is another constant-time implementation of AES. It is + * similar to `aes_ct` but uses 64-bit values. On 32-bit machines, + * `aes_ct64` is not faster than `aes_ct`, often a bit slower, and has + * a larger footprint; however, on 64-bit architectures, `aes_ct64` + * is typically twice faster than `aes_ct` for modes that allow parallel + * operations (i.e. CTR, and CBC decryption, but not CBC encryption). + * + * `aes_x86ni` exists only on x86 architectures (32-bit and 64-bit). It + * uses the AES-NI opcodes when available. + * + * `aes_pwr8` exists only on PowerPC / POWER architectures (32-bit and + * 64-bit, both little-endian and big-endian). It uses the AES opcodes + * present in POWER8 and later. + * + * `des_tab` is a classic, table-based implementation of DES/3DES. It + * is not constant-time. + * + * `des_ct` is an constant-time implementation of DES/3DES. It is + * substantially slower than `des_tab`. + * + * ## ChaCha20 and Poly1305 + * + * ChaCha20 is a stream cipher. Poly1305 is a MAC algorithm. They + * are described in [RFC 7539](https://tools.ietf.org/html/rfc7539). + * + * Two function pointer types are defined: + * + * - `br_chacha20_run` describes a function that implements ChaCha20 + * only. + * + * - `br_poly1305_run` describes an implementation of Poly1305, + * in the AEAD combination with ChaCha20 specified in RFC 7539 + * (the ChaCha20 implementation is provided as a function pointer). + * + * `chacha20_ct` is a straightforward implementation of ChaCha20 in + * plain C; it is constant-time, small, and reasonably fast. + * + * `chacha20_sse2` leverages SSE2 opcodes (on x86 architectures that + * support these opcodes). It is faster than `chacha20_ct`. + * + * `poly1305_ctmul` is an implementation of the ChaCha20+Poly1305 AEAD + * construction, where the Poly1305 part is performed with mixed 32-bit + * multiplications (operands are 32-bit, result is 64-bit). + * + * `poly1305_ctmul32` implements ChaCha20+Poly1305 using pure 32-bit + * multiplications (32-bit operands, 32-bit result). It is slower than + * `poly1305_ctmul`, except on some specific architectures such as + * the ARM Cortex M0+. + * + * `poly1305_ctmulq` implements ChaCha20+Poly1305 with mixed 64-bit + * multiplications (operands are 64-bit, result is 128-bit) on 64-bit + * platforms that support such operations. + * + * `poly1305_i15` implements ChaCha20+Poly1305 with the generic "i15" + * big integer implementation. It is meant mostly for testing purposes, + * although it can help with saving a few hundred bytes of code footprint + * on systems where code size is scarce. + */ + +/** + * \brief Class type for CBC encryption implementations. + * + * A `br_block_cbcenc_class` instance points to the functions implementing + * a specific block cipher, when used in CBC mode for encrypting data. + */ +typedef struct br_block_cbcenc_class_ br_block_cbcenc_class; +struct br_block_cbcenc_class_ { + /** + * \brief Size (in bytes) of the context structure appropriate + * for containing subkeys. + */ + size_t context_size; + + /** + * \brief Size of individual blocks (in bytes). + */ + unsigned block_size; + + /** + * \brief Base-2 logarithm of the size of individual blocks, + * expressed in bytes. + */ + unsigned log_block_size; + + /** + * \brief Initialisation function. + * + * This function sets the `vtable` field in the context structure. + * The key length MUST be one of the key lengths supported by + * the implementation. + * + * \param ctx context structure to initialise. + * \param key secret key. + * \param key_len key length (in bytes). + */ + void (*init)(const br_block_cbcenc_class **ctx, + const void *key, size_t key_len); + + /** + * \brief Run the CBC encryption. + * + * The `iv` parameter points to the IV for this run; it is + * updated with a copy of the last encrypted block. The data + * is encrypted "in place"; its length (`len`) MUST be a + * multiple of the block size. + * + * \param ctx context structure (already initialised). + * \param iv IV for CBC encryption (updated). + * \param data data to encrypt. + * \param len data length (in bytes, multiple of block size). + */ + void (*run)(const br_block_cbcenc_class *const *ctx, + void *iv, void *data, size_t len); +}; + +/** + * \brief Class type for CBC decryption implementations. + * + * A `br_block_cbcdec_class` instance points to the functions implementing + * a specific block cipher, when used in CBC mode for decrypting data. + */ +typedef struct br_block_cbcdec_class_ br_block_cbcdec_class; +struct br_block_cbcdec_class_ { + /** + * \brief Size (in bytes) of the context structure appropriate + * for containing subkeys. + */ + size_t context_size; + + /** + * \brief Size of individual blocks (in bytes). + */ + unsigned block_size; + + /** + * \brief Base-2 logarithm of the size of individual blocks, + * expressed in bytes. + */ + unsigned log_block_size; + + /** + * \brief Initialisation function. + * + * This function sets the `vtable` field in the context structure. + * The key length MUST be one of the key lengths supported by + * the implementation. + * + * \param ctx context structure to initialise. + * \param key secret key. + * \param key_len key length (in bytes). + */ + void (*init)(const br_block_cbcdec_class **ctx, + const void *key, size_t key_len); + + /** + * \brief Run the CBC decryption. + * + * The `iv` parameter points to the IV for this run; it is + * updated with a copy of the last encrypted block. The data + * is decrypted "in place"; its length (`len`) MUST be a + * multiple of the block size. + * + * \param ctx context structure (already initialised). + * \param iv IV for CBC decryption (updated). + * \param data data to decrypt. + * \param len data length (in bytes, multiple of block size). + */ + void (*run)(const br_block_cbcdec_class *const *ctx, + void *iv, void *data, size_t len); +}; + +/** + * \brief Class type for CTR encryption/decryption implementations. + * + * A `br_block_ctr_class` instance points to the functions implementing + * a specific block cipher, when used in CTR mode for encrypting or + * decrypting data. + */ +typedef struct br_block_ctr_class_ br_block_ctr_class; +struct br_block_ctr_class_ { + /** + * \brief Size (in bytes) of the context structure appropriate + * for containing subkeys. + */ + size_t context_size; + + /** + * \brief Size of individual blocks (in bytes). + */ + unsigned block_size; + + /** + * \brief Base-2 logarithm of the size of individual blocks, + * expressed in bytes. + */ + unsigned log_block_size; + + /** + * \brief Initialisation function. + * + * This function sets the `vtable` field in the context structure. + * The key length MUST be one of the key lengths supported by + * the implementation. + * + * \param ctx context structure to initialise. + * \param key secret key. + * \param key_len key length (in bytes). + */ + void (*init)(const br_block_ctr_class **ctx, + const void *key, size_t key_len); + + /** + * \brief Run the CTR encryption or decryption. + * + * The `iv` parameter points to the IV for this run; its + * length is exactly 4 bytes less than the block size (e.g. + * 12 bytes for AES/CTR). The IV is combined with a 32-bit + * block counter to produce the block value which is processed + * with the block cipher. + * + * The data to encrypt or decrypt is updated "in place". Its + * length (`len` bytes) is not required to be a multiple of + * the block size; if the final block is partial, then the + * corresponding key stream bits are dropped. + * + * The resulting counter value is returned. + * + * \param ctx context structure (already initialised). + * \param iv IV for CTR encryption/decryption. + * \param cc initial value for the block counter. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + * \return the new block counter value. + */ + uint32_t (*run)(const br_block_ctr_class *const *ctx, + const void *iv, uint32_t cc, void *data, size_t len); +}; + +/** + * \brief Class type for combined CTR and CBC-MAC implementations. + * + * A `br_block_ctrcbc_class` instance points to the functions implementing + * a specific block cipher, when used in CTR mode for encrypting or + * decrypting data, along with CBC-MAC. + */ +typedef struct br_block_ctrcbc_class_ br_block_ctrcbc_class; +struct br_block_ctrcbc_class_ { + /** + * \brief Size (in bytes) of the context structure appropriate + * for containing subkeys. + */ + size_t context_size; + + /** + * \brief Size of individual blocks (in bytes). + */ + unsigned block_size; + + /** + * \brief Base-2 logarithm of the size of individual blocks, + * expressed in bytes. + */ + unsigned log_block_size; + + /** + * \brief Initialisation function. + * + * This function sets the `vtable` field in the context structure. + * The key length MUST be one of the key lengths supported by + * the implementation. + * + * \param ctx context structure to initialise. + * \param key secret key. + * \param key_len key length (in bytes). + */ + void (*init)(const br_block_ctrcbc_class **ctx, + const void *key, size_t key_len); + + /** + * \brief Run the CTR encryption + CBC-MAC. + * + * The `ctr` parameter points to the counter; its length shall + * be equal to the block size. It is updated by this function + * as encryption proceeds. + * + * The `cbcmac` parameter points to the IV for CBC-MAC. The MAC + * is computed over the encrypted data (output of CTR + * encryption). Its length shall be equal to the block size. The + * computed CBC-MAC value is written over the `cbcmac` array. + * + * The data to encrypt is updated "in place". Its length (`len` + * bytes) MUST be a multiple of the block size. + * + * \param ctx context structure (already initialised). + * \param ctr counter for CTR encryption (initial and final). + * \param cbcmac IV and output buffer for CBC-MAC. + * \param data data to encrypt. + * \param len data length (in bytes). + */ + void (*encrypt)(const br_block_ctrcbc_class *const *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + + /** + * \brief Run the CTR decryption + CBC-MAC. + * + * The `ctr` parameter points to the counter; its length shall + * be equal to the block size. It is updated by this function + * as decryption proceeds. + * + * The `cbcmac` parameter points to the IV for CBC-MAC. The MAC + * is computed over the encrypted data (i.e. before CTR + * decryption). Its length shall be equal to the block size. The + * computed CBC-MAC value is written over the `cbcmac` array. + * + * The data to decrypt is updated "in place". Its length (`len` + * bytes) MUST be a multiple of the block size. + * + * \param ctx context structure (already initialised). + * \param ctr counter for CTR encryption (initial and final). + * \param cbcmac IV and output buffer for CBC-MAC. + * \param data data to decrypt. + * \param len data length (in bytes). + */ + void (*decrypt)(const br_block_ctrcbc_class *const *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + + /** + * \brief Run the CTR encryption/decryption only. + * + * The `ctr` parameter points to the counter; its length shall + * be equal to the block size. It is updated by this function + * as decryption proceeds. + * + * The data to decrypt is updated "in place". Its length (`len` + * bytes) MUST be a multiple of the block size. + * + * \param ctx context structure (already initialised). + * \param ctr counter for CTR encryption (initial and final). + * \param data data to decrypt. + * \param len data length (in bytes). + */ + void (*ctr)(const br_block_ctrcbc_class *const *ctx, + void *ctr, void *data, size_t len); + + /** + * \brief Run the CBC-MAC only. + * + * The `cbcmac` parameter points to the IV for CBC-MAC. The MAC + * is computed over the encrypted data (i.e. before CTR + * decryption). Its length shall be equal to the block size. The + * computed CBC-MAC value is written over the `cbcmac` array. + * + * The data is unmodified. Its length (`len` bytes) MUST be a + * multiple of the block size. + * + * \param ctx context structure (already initialised). + * \param cbcmac IV and output buffer for CBC-MAC. + * \param data data to decrypt. + * \param len data length (in bytes). + */ + void (*mac)(const br_block_ctrcbc_class *const *ctx, + void *cbcmac, const void *data, size_t len); +}; + +/* + * Traditional, table-based AES implementation. It is fast, but uses + * internal tables (in particular a 1 kB table for encryption, another + * 1 kB table for decryption, and a 256-byte table for key schedule), + * and it is not constant-time. In contexts where cache-timing attacks + * apply, this implementation may leak the secret key. + */ + +/** \brief AES block size (16 bytes). */ +#define br_aes_big_BLOCK_SIZE 16 + +/** + * \brief Context for AES subkeys (`aes_big` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_big_cbcenc_keys; + +/** + * \brief Context for AES subkeys (`aes_big` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_big_cbcdec_keys; + +/** + * \brief Context for AES subkeys (`aes_big` implementation, CTR encryption + * and decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctr_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_big_ctr_keys; + +/** + * \brief Context for AES subkeys (`aes_big` implementation, CTR encryption + * and decryption + CBC-MAC). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctrcbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_big_ctrcbc_keys; + +/** + * \brief Class instance for AES CBC encryption (`aes_big` implementation). + */ +extern const br_block_cbcenc_class br_aes_big_cbcenc_vtable; + +/** + * \brief Class instance for AES CBC decryption (`aes_big` implementation). + */ +extern const br_block_cbcdec_class br_aes_big_cbcdec_vtable; + +/** + * \brief Class instance for AES CTR encryption and decryption + * (`aes_big` implementation). + */ +extern const br_block_ctr_class br_aes_big_ctr_vtable; + +/** + * \brief Class instance for AES CTR encryption/decryption + CBC-MAC + * (`aes_big` implementation). + */ +extern const br_block_ctrcbc_class br_aes_big_ctrcbc_vtable; + +/** + * \brief Context initialisation (key schedule) for AES CBC encryption + * (`aes_big` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_big_cbcenc_init(br_aes_big_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CBC decryption + * (`aes_big` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_big_cbcdec_init(br_aes_big_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR encryption + * and decryption (`aes_big` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_big_ctr_init(br_aes_big_ctr_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC + * (`aes_big` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_big_ctrcbc_init(br_aes_big_ctrcbc_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_big_cbcenc_run(const br_aes_big_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_big_cbcdec_run(const br_aes_big_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CTR encryption and decryption with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (constant, 12 bytes). + * \param cc initial block counter value. + * \param data data to encrypt or decrypt (updated). + * \param len data length (in bytes). + * \return new block counter value. + */ +uint32_t br_aes_big_ctr_run(const br_aes_big_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief CTR encryption + CBC-MAC with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_big_ctrcbc_encrypt(const br_aes_big_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR decryption + CBC-MAC with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_big_ctrcbc_decrypt(const br_aes_big_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR encryption/decryption with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param data data to MAC (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_big_ctrcbc_ctr(const br_aes_big_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len); + +/** + * \brief CBC-MAC with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to MAC (unmodified). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_big_ctrcbc_mac(const br_aes_big_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len); + +/* + * AES implementation optimized for size. It is slower than the + * traditional table-based AES implementation, but requires much less + * code. It still uses data-dependent table accesses (albeit within a + * much smaller 256-byte table), which makes it conceptually vulnerable + * to cache-timing attacks. + */ + +/** \brief AES block size (16 bytes). */ +#define br_aes_small_BLOCK_SIZE 16 + +/** + * \brief Context for AES subkeys (`aes_small` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_small_cbcenc_keys; + +/** + * \brief Context for AES subkeys (`aes_small` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_small_cbcdec_keys; + +/** + * \brief Context for AES subkeys (`aes_small` implementation, CTR encryption + * and decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctr_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_small_ctr_keys; + +/** + * \brief Context for AES subkeys (`aes_small` implementation, CTR encryption + * and decryption + CBC-MAC). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctrcbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_small_ctrcbc_keys; + +/** + * \brief Class instance for AES CBC encryption (`aes_small` implementation). + */ +extern const br_block_cbcenc_class br_aes_small_cbcenc_vtable; + +/** + * \brief Class instance for AES CBC decryption (`aes_small` implementation). + */ +extern const br_block_cbcdec_class br_aes_small_cbcdec_vtable; + +/** + * \brief Class instance for AES CTR encryption and decryption + * (`aes_small` implementation). + */ +extern const br_block_ctr_class br_aes_small_ctr_vtable; + +/** + * \brief Class instance for AES CTR encryption/decryption + CBC-MAC + * (`aes_small` implementation). + */ +extern const br_block_ctrcbc_class br_aes_small_ctrcbc_vtable; + +/** + * \brief Context initialisation (key schedule) for AES CBC encryption + * (`aes_small` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_small_cbcenc_init(br_aes_small_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CBC decryption + * (`aes_small` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_small_cbcdec_init(br_aes_small_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR encryption + * and decryption (`aes_small` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_small_ctr_init(br_aes_small_ctr_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC + * (`aes_small` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_small_ctrcbc_init(br_aes_small_ctrcbc_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_small_cbcenc_run(const br_aes_small_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_small_cbcdec_run(const br_aes_small_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CTR encryption and decryption with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (constant, 12 bytes). + * \param cc initial block counter value. + * \param data data to decrypt (updated). + * \param len data length (in bytes). + * \return new block counter value. + */ +uint32_t br_aes_small_ctr_run(const br_aes_small_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief CTR encryption + CBC-MAC with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_small_ctrcbc_encrypt(const br_aes_small_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR decryption + CBC-MAC with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_small_ctrcbc_decrypt(const br_aes_small_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR encryption/decryption with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param data data to MAC (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_small_ctrcbc_ctr(const br_aes_small_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len); + +/** + * \brief CBC-MAC with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to MAC (unmodified). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_small_ctrcbc_mac(const br_aes_small_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len); + +/* + * Constant-time AES implementation. Its size is similar to that of + * 'aes_big', and its performance is similar to that of 'aes_small' (faster + * decryption, slower encryption). However, it is constant-time, i.e. + * immune to cache-timing and similar attacks. + */ + +/** \brief AES block size (16 bytes). */ +#define br_aes_ct_BLOCK_SIZE 16 + +/** + * \brief Context for AES subkeys (`aes_ct` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_ct_cbcenc_keys; + +/** + * \brief Context for AES subkeys (`aes_ct` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_ct_cbcdec_keys; + +/** + * \brief Context for AES subkeys (`aes_ct` implementation, CTR encryption + * and decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctr_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_ct_ctr_keys; + +/** + * \brief Context for AES subkeys (`aes_ct` implementation, CTR encryption + * and decryption + CBC-MAC). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctrcbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_ct_ctrcbc_keys; + +/** + * \brief Class instance for AES CBC encryption (`aes_ct` implementation). + */ +extern const br_block_cbcenc_class br_aes_ct_cbcenc_vtable; + +/** + * \brief Class instance for AES CBC decryption (`aes_ct` implementation). + */ +extern const br_block_cbcdec_class br_aes_ct_cbcdec_vtable; + +/** + * \brief Class instance for AES CTR encryption and decryption + * (`aes_ct` implementation). + */ +extern const br_block_ctr_class br_aes_ct_ctr_vtable; + +/** + * \brief Class instance for AES CTR encryption/decryption + CBC-MAC + * (`aes_ct` implementation). + */ +extern const br_block_ctrcbc_class br_aes_ct_ctrcbc_vtable; + +/** + * \brief Context initialisation (key schedule) for AES CBC encryption + * (`aes_ct` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct_cbcenc_init(br_aes_ct_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CBC decryption + * (`aes_ct` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct_cbcdec_init(br_aes_ct_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR encryption + * and decryption (`aes_ct` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct_ctr_init(br_aes_ct_ctr_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC + * (`aes_ct` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct_ctrcbc_init(br_aes_ct_ctrcbc_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_ct_cbcenc_run(const br_aes_ct_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_ct_cbcdec_run(const br_aes_ct_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CTR encryption and decryption with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (constant, 12 bytes). + * \param cc initial block counter value. + * \param data data to decrypt (updated). + * \param len data length (in bytes). + * \return new block counter value. + */ +uint32_t br_aes_ct_ctr_run(const br_aes_ct_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief CTR encryption + CBC-MAC with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct_ctrcbc_encrypt(const br_aes_ct_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR decryption + CBC-MAC with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct_ctrcbc_decrypt(const br_aes_ct_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR encryption/decryption with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param data data to MAC (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct_ctrcbc_ctr(const br_aes_ct_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len); + +/** + * \brief CBC-MAC with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to MAC (unmodified). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct_ctrcbc_mac(const br_aes_ct_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len); + +/* + * 64-bit constant-time AES implementation. It is similar to 'aes_ct' + * but uses 64-bit registers, making it about twice faster than 'aes_ct' + * on 64-bit platforms, while remaining constant-time and with a similar + * code size. (The doubling in performance is only for CBC decryption + * and CTR mode; CBC encryption is non-parallel and cannot benefit from + * the larger registers.) + */ + +/** \brief AES block size (16 bytes). */ +#define br_aes_ct64_BLOCK_SIZE 16 + +/** + * \brief Context for AES subkeys (`aes_ct64` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t skey[30]; + unsigned num_rounds; +#endif +} br_aes_ct64_cbcenc_keys; + +/** + * \brief Context for AES subkeys (`aes_ct64` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t skey[30]; + unsigned num_rounds; +#endif +} br_aes_ct64_cbcdec_keys; + +/** + * \brief Context for AES subkeys (`aes_ct64` implementation, CTR encryption + * and decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctr_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t skey[30]; + unsigned num_rounds; +#endif +} br_aes_ct64_ctr_keys; + +/** + * \brief Context for AES subkeys (`aes_ct64` implementation, CTR encryption + * and decryption + CBC-MAC). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctrcbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t skey[30]; + unsigned num_rounds; +#endif +} br_aes_ct64_ctrcbc_keys; + +/** + * \brief Class instance for AES CBC encryption (`aes_ct64` implementation). + */ +extern const br_block_cbcenc_class br_aes_ct64_cbcenc_vtable; + +/** + * \brief Class instance for AES CBC decryption (`aes_ct64` implementation). + */ +extern const br_block_cbcdec_class br_aes_ct64_cbcdec_vtable; + +/** + * \brief Class instance for AES CTR encryption and decryption + * (`aes_ct64` implementation). + */ +extern const br_block_ctr_class br_aes_ct64_ctr_vtable; + +/** + * \brief Class instance for AES CTR encryption/decryption + CBC-MAC + * (`aes_ct64` implementation). + */ +extern const br_block_ctrcbc_class br_aes_ct64_ctrcbc_vtable; + +/** + * \brief Context initialisation (key schedule) for AES CBC encryption + * (`aes_ct64` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct64_cbcenc_init(br_aes_ct64_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CBC decryption + * (`aes_ct64` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct64_cbcdec_init(br_aes_ct64_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR encryption + * and decryption (`aes_ct64` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct64_ctr_init(br_aes_ct64_ctr_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC + * (`aes_ct64` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct64_ctrcbc_init(br_aes_ct64_ctrcbc_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_ct64_cbcenc_run(const br_aes_ct64_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_ct64_cbcdec_run(const br_aes_ct64_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CTR encryption and decryption with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (constant, 12 bytes). + * \param cc initial block counter value. + * \param data data to decrypt (updated). + * \param len data length (in bytes). + * \return new block counter value. + */ +uint32_t br_aes_ct64_ctr_run(const br_aes_ct64_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief CTR encryption + CBC-MAC with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct64_ctrcbc_encrypt(const br_aes_ct64_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR decryption + CBC-MAC with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct64_ctrcbc_decrypt(const br_aes_ct64_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR encryption/decryption with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param data data to MAC (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct64_ctrcbc_ctr(const br_aes_ct64_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len); + +/** + * \brief CBC-MAC with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to MAC (unmodified). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct64_ctrcbc_mac(const br_aes_ct64_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len); + +/* + * AES implementation using AES-NI opcodes (x86 platform). + */ + +/** \brief AES block size (16 bytes). */ +#define br_aes_x86ni_BLOCK_SIZE 16 + +/** + * \brief Context for AES subkeys (`aes_x86ni` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_x86ni_cbcenc_keys; + +/** + * \brief Context for AES subkeys (`aes_x86ni` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_x86ni_cbcdec_keys; + +/** + * \brief Context for AES subkeys (`aes_x86ni` implementation, CTR encryption + * and decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctr_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_x86ni_ctr_keys; + +/** + * \brief Context for AES subkeys (`aes_x86ni` implementation, CTR encryption + * and decryption + CBC-MAC). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctrcbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_x86ni_ctrcbc_keys; + +/** + * \brief Class instance for AES CBC encryption (`aes_x86ni` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_x86ni_cbcenc_get_vtable()`. + */ +extern const br_block_cbcenc_class br_aes_x86ni_cbcenc_vtable; + +/** + * \brief Class instance for AES CBC decryption (`aes_x86ni` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_x86ni_cbcdec_get_vtable()`. + */ +extern const br_block_cbcdec_class br_aes_x86ni_cbcdec_vtable; + +/** + * \brief Class instance for AES CTR encryption and decryption + * (`aes_x86ni` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_x86ni_ctr_get_vtable()`. + */ +extern const br_block_ctr_class br_aes_x86ni_ctr_vtable; + +/** + * \brief Class instance for AES CTR encryption/decryption + CBC-MAC + * (`aes_x86ni` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_x86ni_ctrcbc_get_vtable()`. + */ +extern const br_block_ctrcbc_class br_aes_x86ni_ctrcbc_vtable; + +/** + * \brief Context initialisation (key schedule) for AES CBC encryption + * (`aes_x86ni` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_x86ni_cbcenc_init(br_aes_x86ni_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CBC decryption + * (`aes_x86ni` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_x86ni_cbcdec_init(br_aes_x86ni_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR encryption + * and decryption (`aes_x86ni` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_x86ni_ctr_init(br_aes_x86ni_ctr_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC + * (`aes_x86ni` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_x86ni_ctrcbc_init(br_aes_x86ni_ctrcbc_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_x86ni_cbcenc_run(const br_aes_x86ni_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_x86ni_cbcdec_run(const br_aes_x86ni_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CTR encryption and decryption with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (constant, 12 bytes). + * \param cc initial block counter value. + * \param data data to decrypt (updated). + * \param len data length (in bytes). + * \return new block counter value. + */ +uint32_t br_aes_x86ni_ctr_run(const br_aes_x86ni_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief CTR encryption + CBC-MAC with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_x86ni_ctrcbc_encrypt(const br_aes_x86ni_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR decryption + CBC-MAC with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_x86ni_ctrcbc_decrypt(const br_aes_x86ni_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR encryption/decryption with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param data data to MAC (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_x86ni_ctrcbc_ctr(const br_aes_x86ni_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len); + +/** + * \brief CBC-MAC with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to MAC (unmodified). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_x86ni_ctrcbc_mac(const br_aes_x86ni_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len); + +/** + * \brief Obtain the `aes_x86ni` AES-CBC (encryption) implementation, if + * available. + * + * This function returns a pointer to `br_aes_x86ni_cbcenc_vtable`, if + * that implementation was compiled in the library _and_ the x86 AES + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_x86ni` AES-CBC (encryption) implementation, or `NULL`. + */ +const br_block_cbcenc_class *br_aes_x86ni_cbcenc_get_vtable(void); + +/** + * \brief Obtain the `aes_x86ni` AES-CBC (decryption) implementation, if + * available. + * + * This function returns a pointer to `br_aes_x86ni_cbcdec_vtable`, if + * that implementation was compiled in the library _and_ the x86 AES + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_x86ni` AES-CBC (decryption) implementation, or `NULL`. + */ +const br_block_cbcdec_class *br_aes_x86ni_cbcdec_get_vtable(void); + +/** + * \brief Obtain the `aes_x86ni` AES-CTR implementation, if available. + * + * This function returns a pointer to `br_aes_x86ni_ctr_vtable`, if + * that implementation was compiled in the library _and_ the x86 AES + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_x86ni` AES-CTR implementation, or `NULL`. + */ +const br_block_ctr_class *br_aes_x86ni_ctr_get_vtable(void); + +/** + * \brief Obtain the `aes_x86ni` AES-CTR + CBC-MAC implementation, if + * available. + * + * This function returns a pointer to `br_aes_x86ni_ctrcbc_vtable`, if + * that implementation was compiled in the library _and_ the x86 AES + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_x86ni` AES-CTR implementation, or `NULL`. + */ +const br_block_ctrcbc_class *br_aes_x86ni_ctrcbc_get_vtable(void); + +/* + * AES implementation using POWER8 opcodes. + */ + +/** \brief AES block size (16 bytes). */ +#define br_aes_pwr8_BLOCK_SIZE 16 + +/** + * \brief Context for AES subkeys (`aes_pwr8` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_pwr8_cbcenc_keys; + +/** + * \brief Context for AES subkeys (`aes_pwr8` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_pwr8_cbcdec_keys; + +/** + * \brief Context for AES subkeys (`aes_pwr8` implementation, CTR encryption + * and decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctr_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_pwr8_ctr_keys; + +/** + * \brief Context for AES subkeys (`aes_pwr8` implementation, CTR encryption + * and decryption + CBC-MAC). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctrcbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_pwr8_ctrcbc_keys; + +/** + * \brief Class instance for AES CBC encryption (`aes_pwr8` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_pwr8_cbcenc_get_vtable()`. + */ +extern const br_block_cbcenc_class br_aes_pwr8_cbcenc_vtable; + +/** + * \brief Class instance for AES CBC decryption (`aes_pwr8` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_pwr8_cbcdec_get_vtable()`. + */ +extern const br_block_cbcdec_class br_aes_pwr8_cbcdec_vtable; + +/** + * \brief Class instance for AES CTR encryption and decryption + * (`aes_pwr8` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_pwr8_ctr_get_vtable()`. + */ +extern const br_block_ctr_class br_aes_pwr8_ctr_vtable; + +/** + * \brief Class instance for AES CTR encryption/decryption + CBC-MAC + * (`aes_pwr8` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_pwr8_ctrcbc_get_vtable()`. + */ +extern const br_block_ctrcbc_class br_aes_pwr8_ctrcbc_vtable; + +/** + * \brief Context initialisation (key schedule) for AES CBC encryption + * (`aes_pwr8` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_pwr8_cbcenc_init(br_aes_pwr8_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CBC decryption + * (`aes_pwr8` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_pwr8_cbcdec_init(br_aes_pwr8_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR encryption + * and decryption (`aes_pwr8` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_pwr8_ctr_init(br_aes_pwr8_ctr_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC + * (`aes_pwr8` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_pwr8_ctrcbc_init(br_aes_pwr8_ctrcbc_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_pwr8_cbcenc_run(const br_aes_pwr8_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_pwr8_cbcdec_run(const br_aes_pwr8_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CTR encryption and decryption with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (constant, 12 bytes). + * \param cc initial block counter value. + * \param data data to decrypt (updated). + * \param len data length (in bytes). + * \return new block counter value. + */ +uint32_t br_aes_pwr8_ctr_run(const br_aes_pwr8_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief CTR encryption + CBC-MAC with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_pwr8_ctrcbc_encrypt(const br_aes_pwr8_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR decryption + CBC-MAC with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_pwr8_ctrcbc_decrypt(const br_aes_pwr8_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR encryption/decryption with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param data data to MAC (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_pwr8_ctrcbc_ctr(const br_aes_pwr8_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len); + +/** + * \brief CBC-MAC with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to MAC (unmodified). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_pwr8_ctrcbc_mac(const br_aes_pwr8_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len); + +/** + * \brief Obtain the `aes_pwr8` AES-CBC (encryption) implementation, if + * available. + * + * This function returns a pointer to `br_aes_pwr8_cbcenc_vtable`, if + * that implementation was compiled in the library _and_ the POWER8 + * crypto opcodes are available on the currently running CPU. If either + * of these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_pwr8` AES-CBC (encryption) implementation, or `NULL`. + */ +const br_block_cbcenc_class *br_aes_pwr8_cbcenc_get_vtable(void); + +/** + * \brief Obtain the `aes_pwr8` AES-CBC (decryption) implementation, if + * available. + * + * This function returns a pointer to `br_aes_pwr8_cbcdec_vtable`, if + * that implementation was compiled in the library _and_ the POWER8 + * crypto opcodes are available on the currently running CPU. If either + * of these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_pwr8` AES-CBC (decryption) implementation, or `NULL`. + */ +const br_block_cbcdec_class *br_aes_pwr8_cbcdec_get_vtable(void); + +/** + * \brief Obtain the `aes_pwr8` AES-CTR implementation, if available. + * + * This function returns a pointer to `br_aes_pwr8_ctr_vtable`, if that + * implementation was compiled in the library _and_ the POWER8 crypto + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_pwr8` AES-CTR implementation, or `NULL`. + */ +const br_block_ctr_class *br_aes_pwr8_ctr_get_vtable(void); + +/** + * \brief Obtain the `aes_pwr8` AES-CTR + CBC-MAC implementation, if + * available. + * + * This function returns a pointer to `br_aes_pwr8_ctrcbc_vtable`, if + * that implementation was compiled in the library _and_ the POWER8 AES + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_pwr8` AES-CTR implementation, or `NULL`. + */ +const br_block_ctrcbc_class *br_aes_pwr8_ctrcbc_get_vtable(void); + +/** + * \brief Aggregate structure large enough to be used as context for + * subkeys (CBC encryption) for all AES implementations. + */ +typedef union { + const br_block_cbcenc_class *vtable; + br_aes_big_cbcenc_keys c_big; + br_aes_small_cbcenc_keys c_small; + br_aes_ct_cbcenc_keys c_ct; + br_aes_ct64_cbcenc_keys c_ct64; + br_aes_x86ni_cbcenc_keys c_x86ni; + br_aes_pwr8_cbcenc_keys c_pwr8; +} br_aes_gen_cbcenc_keys; + +/** + * \brief Aggregate structure large enough to be used as context for + * subkeys (CBC decryption) for all AES implementations. + */ +typedef union { + const br_block_cbcdec_class *vtable; + br_aes_big_cbcdec_keys c_big; + br_aes_small_cbcdec_keys c_small; + br_aes_ct_cbcdec_keys c_ct; + br_aes_ct64_cbcdec_keys c_ct64; + br_aes_x86ni_cbcdec_keys c_x86ni; + br_aes_pwr8_cbcdec_keys c_pwr8; +} br_aes_gen_cbcdec_keys; + +/** + * \brief Aggregate structure large enough to be used as context for + * subkeys (CTR encryption and decryption) for all AES implementations. + */ +typedef union { + const br_block_ctr_class *vtable; + br_aes_big_ctr_keys c_big; + br_aes_small_ctr_keys c_small; + br_aes_ct_ctr_keys c_ct; + br_aes_ct64_ctr_keys c_ct64; + br_aes_x86ni_ctr_keys c_x86ni; + br_aes_pwr8_ctr_keys c_pwr8; +} br_aes_gen_ctr_keys; + +/** + * \brief Aggregate structure large enough to be used as context for + * subkeys (CTR encryption/decryption + CBC-MAC) for all AES implementations. + */ +typedef union { + const br_block_ctrcbc_class *vtable; + br_aes_big_ctrcbc_keys c_big; + br_aes_small_ctrcbc_keys c_small; + br_aes_ct_ctrcbc_keys c_ct; + br_aes_ct64_ctrcbc_keys c_ct64; + br_aes_x86ni_ctrcbc_keys c_x86ni; + br_aes_pwr8_ctrcbc_keys c_pwr8; +} br_aes_gen_ctrcbc_keys; + +/* + * Traditional, table-based implementation for DES/3DES. Since tables are + * used, cache-timing attacks are conceptually possible. + */ + +/** \brief DES/3DES block size (8 bytes). */ +#define br_des_tab_BLOCK_SIZE 8 + +/** + * \brief Context for DES subkeys (`des_tab` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[96]; + unsigned num_rounds; +#endif +} br_des_tab_cbcenc_keys; + +/** + * \brief Context for DES subkeys (`des_tab` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[96]; + unsigned num_rounds; +#endif +} br_des_tab_cbcdec_keys; + +/** + * \brief Class instance for DES CBC encryption (`des_tab` implementation). + */ +extern const br_block_cbcenc_class br_des_tab_cbcenc_vtable; + +/** + * \brief Class instance for DES CBC decryption (`des_tab` implementation). + */ +extern const br_block_cbcdec_class br_des_tab_cbcdec_vtable; + +/** + * \brief Context initialisation (key schedule) for DES CBC encryption + * (`des_tab` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_des_tab_cbcenc_init(br_des_tab_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for DES CBC decryption + * (`des_tab` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_des_tab_cbcdec_init(br_des_tab_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with DES (`des_tab` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 8). + */ +void br_des_tab_cbcenc_run(const br_des_tab_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with DES (`des_tab` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 8). + */ +void br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/* + * Constant-time implementation for DES/3DES. It is substantially slower + * (by a factor of about 4x), but also immune to cache-timing attacks. + */ + +/** \brief DES/3DES block size (8 bytes). */ +#define br_des_ct_BLOCK_SIZE 8 + +/** + * \brief Context for DES subkeys (`des_ct` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[96]; + unsigned num_rounds; +#endif +} br_des_ct_cbcenc_keys; + +/** + * \brief Context for DES subkeys (`des_ct` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[96]; + unsigned num_rounds; +#endif +} br_des_ct_cbcdec_keys; + +/** + * \brief Class instance for DES CBC encryption (`des_ct` implementation). + */ +extern const br_block_cbcenc_class br_des_ct_cbcenc_vtable; + +/** + * \brief Class instance for DES CBC decryption (`des_ct` implementation). + */ +extern const br_block_cbcdec_class br_des_ct_cbcdec_vtable; + +/** + * \brief Context initialisation (key schedule) for DES CBC encryption + * (`des_ct` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_des_ct_cbcenc_init(br_des_ct_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for DES CBC decryption + * (`des_ct` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_des_ct_cbcdec_init(br_des_ct_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with DES (`des_ct` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 8). + */ +void br_des_ct_cbcenc_run(const br_des_ct_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with DES (`des_ct` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 8). + */ +void br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/* + * These structures are large enough to accommodate subkeys for all + * DES/3DES implementations. + */ + +/** + * \brief Aggregate structure large enough to be used as context for + * subkeys (CBC encryption) for all DES implementations. + */ +typedef union { + const br_block_cbcenc_class *vtable; + br_des_tab_cbcenc_keys tab; + br_des_ct_cbcenc_keys ct; +} br_des_gen_cbcenc_keys; + +/** + * \brief Aggregate structure large enough to be used as context for + * subkeys (CBC decryption) for all DES implementations. + */ +typedef union { + const br_block_cbcdec_class *vtable; + br_des_tab_cbcdec_keys c_tab; + br_des_ct_cbcdec_keys c_ct; +} br_des_gen_cbcdec_keys; + +/** + * \brief Type for a ChaCha20 implementation. + * + * An implementation follows the description in RFC 7539: + * + * - Key is 256 bits (`key` points to exactly 32 bytes). + * + * - IV is 96 bits (`iv` points to exactly 12 bytes). + * + * - Block counter is over 32 bits and starts at value `cc`; the + * resulting value is returned. + * + * Data (pointed to by `data`, of length `len`) is encrypted/decrypted + * in place. If `len` is not a multiple of 64, then the excess bytes from + * the last block processing are dropped (therefore, "chunked" processing + * works only as long as each non-final chunk has a length multiple of 64). + * + * \param key secret key (32 bytes). + * \param iv IV (12 bytes). + * \param cc initial counter value. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ +typedef uint32_t (*br_chacha20_run)(const void *key, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief ChaCha20 implementation (straightforward C code, constant-time). + * + * \see br_chacha20_run + * + * \param key secret key (32 bytes). + * \param iv IV (12 bytes). + * \param cc initial counter value. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ +uint32_t br_chacha20_ct_run(const void *key, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief ChaCha20 implementation (SSE2 code, constant-time). + * + * This implementation is available only on x86 platforms, depending on + * compiler support. Moreover, in 32-bit mode, it might not actually run, + * if the underlying hardware does not implement the SSE2 opcode (in + * 64-bit mode, SSE2 is part of the ABI, so if the code could be compiled + * at all, then it can run). Use `br_chacha20_sse2_get()` to safely obtain + * a pointer to that function. + * + * \see br_chacha20_run + * + * \param key secret key (32 bytes). + * \param iv IV (12 bytes). + * \param cc initial counter value. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ +uint32_t br_chacha20_sse2_run(const void *key, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief Obtain the `sse2` ChaCha20 implementation, if available. + * + * This function returns a pointer to `br_chacha20_sse2_run`, if + * that implementation was compiled in the library _and_ the SSE2 + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `0`. + * + * \return the `sse2` ChaCha20 implementation, or `0`. + */ +br_chacha20_run br_chacha20_sse2_get(void); + +/** + * \brief Type for a ChaCha20+Poly1305 AEAD implementation. + * + * The provided data is encrypted or decrypted with ChaCha20. The + * authentication tag is computed on the concatenation of the + * additional data and the ciphertext, with the padding and lengths + * as described in RFC 7539 (section 2.8). + * + * After decryption, the caller is responsible for checking that the + * computed tag matches the expected value. + * + * \param key secret key (32 bytes). + * \param iv nonce (12 bytes). + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + * \param aad additional authenticated data. + * \param aad_len length of additional authenticated data (in bytes). + * \param tag output buffer for the authentication tag. + * \param ichacha implementation of ChaCha20. + * \param encrypt non-zero for encryption, zero for decryption. + */ +typedef void (*br_poly1305_run)(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt); + +/** + * \brief ChaCha20+Poly1305 AEAD implementation (mixed 32-bit multiplications). + * + * \see br_poly1305_run + * + * \param key secret key (32 bytes). + * \param iv nonce (12 bytes). + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + * \param aad additional authenticated data. + * \param aad_len length of additional authenticated data (in bytes). + * \param tag output buffer for the authentication tag. + * \param ichacha implementation of ChaCha20. + * \param encrypt non-zero for encryption, zero for decryption. + */ +void br_poly1305_ctmul_run(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt); + +/** + * \brief ChaCha20+Poly1305 AEAD implementation (pure 32-bit multiplications). + * + * \see br_poly1305_run + * + * \param key secret key (32 bytes). + * \param iv nonce (12 bytes). + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + * \param aad additional authenticated data. + * \param aad_len length of additional authenticated data (in bytes). + * \param tag output buffer for the authentication tag. + * \param ichacha implementation of ChaCha20. + * \param encrypt non-zero for encryption, zero for decryption. + */ +void br_poly1305_ctmul32_run(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt); + +/** + * \brief ChaCha20+Poly1305 AEAD implementation (i15). + * + * This implementation relies on the generic big integer code "i15" + * (which uses pure 32-bit multiplications). As such, it may save a + * little code footprint in a context where "i15" is already included + * (e.g. for elliptic curves or for RSA); however, it is also + * substantially slower than the ctmul and ctmul32 implementations. + * + * \see br_poly1305_run + * + * \param key secret key (32 bytes). + * \param iv nonce (12 bytes). + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + * \param aad additional authenticated data. + * \param aad_len length of additional authenticated data (in bytes). + * \param tag output buffer for the authentication tag. + * \param ichacha implementation of ChaCha20. + * \param encrypt non-zero for encryption, zero for decryption. + */ +void br_poly1305_i15_run(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt); + +/** + * \brief ChaCha20+Poly1305 AEAD implementation (ctmulq). + * + * This implementation uses 64-bit multiplications (result over 128 bits). + * It is available only on platforms that offer such a primitive (in + * practice, 64-bit architectures). Use `br_poly1305_ctmulq_get()` to + * dynamically obtain a pointer to that function, or 0 if not supported. + * + * \see br_poly1305_run + * + * \param key secret key (32 bytes). + * \param iv nonce (12 bytes). + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + * \param aad additional authenticated data. + * \param aad_len length of additional authenticated data (in bytes). + * \param tag output buffer for the authentication tag. + * \param ichacha implementation of ChaCha20. + * \param encrypt non-zero for encryption, zero for decryption. + */ +void br_poly1305_ctmulq_run(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt); + +/** + * \brief Get the ChaCha20+Poly1305 "ctmulq" implementation, if available. + * + * This function returns a pointer to the `br_poly1305_ctmulq_run()` + * function if supported on the current platform; otherwise, it returns 0. + * + * \return the ctmulq ChaCha20+Poly1305 implementation, or 0. + */ +br_poly1305_run br_poly1305_ctmulq_get(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/inc/bearssl_ec.h b/BearSSL-OG/libbearssl/inc/bearssl_ec.h new file mode 100644 index 0000000..acd3a2b --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl_ec.h @@ -0,0 +1,967 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_EC_H__ +#define BR_BEARSSL_EC_H__ + +#include +#include + +#include "bearssl_rand.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_ec.h + * + * # Elliptic Curves + * + * This file documents the EC implementations provided with BearSSL, and + * ECDSA. + * + * ## Elliptic Curve API + * + * Only "named curves" are supported. Each EC implementation supports + * one or several named curves, identified by symbolic identifiers. + * These identifiers are small integers, that correspond to the values + * registered by the + * [IANA](http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8). + * + * Since all currently defined elliptic curve identifiers are in the 0..31 + * range, it is convenient to encode support of some curves in a 32-bit + * word, such that bit x corresponds to curve of identifier x. + * + * An EC implementation is incarnated by a `br_ec_impl` instance, that + * offers the following fields: + * + * - `supported_curves` + * + * A 32-bit word that documents the identifiers of the curves supported + * by this implementation. + * + * - `generator()` + * + * Callback method that returns a pointer to the conventional generator + * point for that curve. + * + * - `order()` + * + * Callback method that returns a pointer to the subgroup order for + * that curve. That value uses unsigned big-endian encoding. + * + * - `xoff()` + * + * Callback method that returns the offset and length of the X + * coordinate in an encoded point. + * + * - `mul()` + * + * Multiply a curve point with an integer. + * + * - `mulgen()` + * + * Multiply the curve generator with an integer. This may be faster + * than the generic `mul()`. + * + * - `muladd()` + * + * Multiply two curve points by two integers, and return the sum of + * the two products. + * + * All curve points are represented in uncompressed format. The `mul()` + * and `muladd()` methods take care to validate that the provided points + * are really part of the relevant curve subgroup. + * + * For all point multiplication functions, the following holds: + * + * - Functions validate that the provided points are valid members + * of the relevant curve subgroup. An error is reported if that is + * not the case. + * + * - Processing is constant-time, even if the point operands are not + * valid. This holds for both the source and resulting points, and + * the multipliers (integers). Only the byte length of the provided + * multiplier arrays (not their actual value length in bits) may + * leak through timing-based side channels. + * + * - The multipliers (integers) MUST be lower than the subgroup order. + * If this property is not met, then the result is indeterminate, + * but an error value is not necessarily returned. + * + * + * ## ECDSA + * + * ECDSA signatures have two standard formats, called "raw" and "asn1". + * Internally, such a signature is a pair of modular integers `(r,s)`. + * The "raw" format is the concatenation of the unsigned big-endian + * encodings of these two integers, possibly left-padded with zeros so + * that they have the same encoded length. The "asn1" format is the + * DER encoding of an ASN.1 structure that contains the two integer + * values: + * + * ECDSASignature ::= SEQUENCE { + * r INTEGER, + * s INTEGER + * } + * + * In general, in all of X.509 and SSL/TLS, the "asn1" format is used. + * BearSSL offers ECDSA implementations for both formats; conversion + * functions between the two formats are also provided. Conversion of a + * "raw" format signature into "asn1" may enlarge a signature by no more + * than 9 bytes for all supported curves; conversely, conversion of an + * "asn1" signature to "raw" may expand the signature but the "raw" + * length will never be more than twice the length of the "asn1" length + * (and usually it will be shorter). + * + * Note that for a given signature, the "raw" format is not fully + * deterministic, in that it does not enforce a minimal common length. + */ + +/* + * Standard curve ID. These ID are equal to the assigned numerical + * identifiers assigned to these curves for TLS: + * http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 + */ + +/** \brief Identifier for named curve sect163k1. */ +#define BR_EC_sect163k1 1 + +/** \brief Identifier for named curve sect163r1. */ +#define BR_EC_sect163r1 2 + +/** \brief Identifier for named curve sect163r2. */ +#define BR_EC_sect163r2 3 + +/** \brief Identifier for named curve sect193r1. */ +#define BR_EC_sect193r1 4 + +/** \brief Identifier for named curve sect193r2. */ +#define BR_EC_sect193r2 5 + +/** \brief Identifier for named curve sect233k1. */ +#define BR_EC_sect233k1 6 + +/** \brief Identifier for named curve sect233r1. */ +#define BR_EC_sect233r1 7 + +/** \brief Identifier for named curve sect239k1. */ +#define BR_EC_sect239k1 8 + +/** \brief Identifier for named curve sect283k1. */ +#define BR_EC_sect283k1 9 + +/** \brief Identifier for named curve sect283r1. */ +#define BR_EC_sect283r1 10 + +/** \brief Identifier for named curve sect409k1. */ +#define BR_EC_sect409k1 11 + +/** \brief Identifier for named curve sect409r1. */ +#define BR_EC_sect409r1 12 + +/** \brief Identifier for named curve sect571k1. */ +#define BR_EC_sect571k1 13 + +/** \brief Identifier for named curve sect571r1. */ +#define BR_EC_sect571r1 14 + +/** \brief Identifier for named curve secp160k1. */ +#define BR_EC_secp160k1 15 + +/** \brief Identifier for named curve secp160r1. */ +#define BR_EC_secp160r1 16 + +/** \brief Identifier for named curve secp160r2. */ +#define BR_EC_secp160r2 17 + +/** \brief Identifier for named curve secp192k1. */ +#define BR_EC_secp192k1 18 + +/** \brief Identifier for named curve secp192r1. */ +#define BR_EC_secp192r1 19 + +/** \brief Identifier for named curve secp224k1. */ +#define BR_EC_secp224k1 20 + +/** \brief Identifier for named curve secp224r1. */ +#define BR_EC_secp224r1 21 + +/** \brief Identifier for named curve secp256k1. */ +#define BR_EC_secp256k1 22 + +/** \brief Identifier for named curve secp256r1. */ +#define BR_EC_secp256r1 23 + +/** \brief Identifier for named curve secp384r1. */ +#define BR_EC_secp384r1 24 + +/** \brief Identifier for named curve secp521r1. */ +#define BR_EC_secp521r1 25 + +/** \brief Identifier for named curve brainpoolP256r1. */ +#define BR_EC_brainpoolP256r1 26 + +/** \brief Identifier for named curve brainpoolP384r1. */ +#define BR_EC_brainpoolP384r1 27 + +/** \brief Identifier for named curve brainpoolP512r1. */ +#define BR_EC_brainpoolP512r1 28 + +/** \brief Identifier for named curve Curve25519. */ +#define BR_EC_curve25519 29 + +/** \brief Identifier for named curve Curve448. */ +#define BR_EC_curve448 30 + +/** + * \brief Structure for an EC public key. + */ +typedef struct { + /** \brief Identifier for the curve used by this key. */ + int curve; + /** \brief Public curve point (uncompressed format). */ + unsigned char *q; + /** \brief Length of public curve point (in bytes). */ + size_t qlen; +} br_ec_public_key; + +/** + * \brief Structure for an EC private key. + * + * The private key is an integer modulo the curve subgroup order. The + * encoding below tolerates extra leading zeros. In general, it is + * recommended that the private key has the same length as the curve + * subgroup order. + */ +typedef struct { + /** \brief Identifier for the curve used by this key. */ + int curve; + /** \brief Private key (integer, unsigned big-endian encoding). */ + unsigned char *x; + /** \brief Private key length (in bytes). */ + size_t xlen; +} br_ec_private_key; + +/** + * \brief Type for an EC implementation. + */ +typedef struct { + /** + * \brief Supported curves. + * + * This word is a bitfield: bit `x` is set if the curve of ID `x` + * is supported. E.g. an implementation supporting both NIST P-256 + * (secp256r1, ID 23) and NIST P-384 (secp384r1, ID 24) will have + * value `0x01800000` in this field. + */ + uint32_t supported_curves; + + /** + * \brief Get the conventional generator. + * + * This function returns the conventional generator (encoded + * curve point) for the specified curve. This function MUST NOT + * be called if the curve is not supported. + * + * \param curve curve identifier. + * \param len receiver for the encoded generator length (in bytes). + * \return the encoded generator. + */ + const unsigned char *(*generator)(int curve, size_t *len); + + /** + * \brief Get the subgroup order. + * + * This function returns the order of the subgroup generated by + * the conventional generator, for the specified curve. Unsigned + * big-endian encoding is used. This function MUST NOT be called + * if the curve is not supported. + * + * \param curve curve identifier. + * \param len receiver for the encoded order length (in bytes). + * \return the encoded order. + */ + const unsigned char *(*order)(int curve, size_t *len); + + /** + * \brief Get the offset and length for the X coordinate. + * + * This function returns the offset and length (in bytes) of + * the X coordinate in an encoded non-zero point. + * + * \param curve curve identifier. + * \param len receiver for the X coordinate length (in bytes). + * \return the offset for the X coordinate (in bytes). + */ + size_t (*xoff)(int curve, size_t *len); + + /** + * \brief Multiply a curve point by an integer. + * + * The source point is provided in array `G` (of size `Glen` bytes); + * the multiplication result is written over it. The multiplier + * `x` (of size `xlen` bytes) uses unsigned big-endian encoding. + * + * Rules: + * + * - The specified curve MUST be supported. + * + * - The source point must be a valid point on the relevant curve + * subgroup (and not the "point at infinity" either). If this is + * not the case, then this function returns an error (0). + * + * - The multiplier integer MUST be non-zero and less than the + * curve subgroup order. If this property does not hold, then + * the result is indeterminate and an error code is not + * guaranteed. + * + * Returned value is 1 on success, 0 on error. On error, the + * contents of `G` are indeterminate. + * + * \param G point to multiply. + * \param Glen length of the encoded point (in bytes). + * \param x multiplier (unsigned big-endian). + * \param xlen multiplier length (in bytes). + * \param curve curve identifier. + * \return 1 on success, 0 on error. + */ + uint32_t (*mul)(unsigned char *G, size_t Glen, + const unsigned char *x, size_t xlen, int curve); + + /** + * \brief Multiply the generator by an integer. + * + * The multiplier MUST be non-zero and less than the curve + * subgroup order. Results are indeterminate if this property + * does not hold. + * + * \param R output buffer for the point. + * \param x multiplier (unsigned big-endian). + * \param xlen multiplier length (in bytes). + * \param curve curve identifier. + * \return encoded result point length (in bytes). + */ + size_t (*mulgen)(unsigned char *R, + const unsigned char *x, size_t xlen, int curve); + + /** + * \brief Multiply two points by two integers and add the + * results. + * + * The point `x*A + y*B` is computed and written back in the `A` + * array. + * + * Rules: + * + * - The specified curve MUST be supported. + * + * - The source points (`A` and `B`) must be valid points on + * the relevant curve subgroup (and not the "point at + * infinity" either). If this is not the case, then this + * function returns an error (0). + * + * - If the `B` pointer is `NULL`, then the conventional + * subgroup generator is used. With some implementations, + * this may be faster than providing a pointer to the + * generator. + * + * - The multiplier integers (`x` and `y`) MUST be non-zero + * and less than the curve subgroup order. If either integer + * is zero, then an error is reported, but if one of them is + * not lower than the subgroup order, then the result is + * indeterminate and an error code is not guaranteed. + * + * - If the final result is the point at infinity, then an + * error is returned. + * + * Returned value is 1 on success, 0 on error. On error, the + * contents of `A` are indeterminate. + * + * \param A first point to multiply. + * \param B second point to multiply (`NULL` for the generator). + * \param len common length of the encoded points (in bytes). + * \param x multiplier for `A` (unsigned big-endian). + * \param xlen length of multiplier for `A` (in bytes). + * \param y multiplier for `A` (unsigned big-endian). + * \param ylen length of multiplier for `A` (in bytes). + * \param curve curve identifier. + * \return 1 on success, 0 on error. + */ + uint32_t (*muladd)(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve); +} br_ec_impl; + +/** + * \brief EC implementation "i31". + * + * This implementation internally uses generic code for modular integers, + * with a representation as sequences of 31-bit words. It supports secp256r1, + * secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521). + */ +extern const br_ec_impl br_ec_prime_i31; + +/** + * \brief EC implementation "i15". + * + * This implementation internally uses generic code for modular integers, + * with a representation as sequences of 15-bit words. It supports secp256r1, + * secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521). + */ +extern const br_ec_impl br_ec_prime_i15; + +/** + * \brief EC implementation "m15" for P-256. + * + * This implementation uses specialised code for curve secp256r1 (also + * known as NIST P-256), with optional Karatsuba decomposition, and fast + * modular reduction thanks to the field modulus special format. Only + * 32-bit multiplications are used (with 32-bit results, not 64-bit). + */ +extern const br_ec_impl br_ec_p256_m15; + +/** + * \brief EC implementation "m31" for P-256. + * + * This implementation uses specialised code for curve secp256r1 (also + * known as NIST P-256), relying on multiplications of 31-bit values + * (MUL31). + */ +extern const br_ec_impl br_ec_p256_m31; + +/** + * \brief EC implementation "m62" (specialised code) for P-256. + * + * This implementation uses custom code relying on multiplication of + * integers up to 64 bits, with a 128-bit result. This implementation is + * defined only on platforms that offer the 64x64->128 multiplication + * support; use `br_ec_p256_m62_get()` to dynamically obtain a pointer + * to that implementation. + */ +extern const br_ec_impl br_ec_p256_m62; + +/** + * \brief Get the "m62" implementation of P-256, if available. + * + * \return the implementation, or 0. + */ +const br_ec_impl *br_ec_p256_m62_get(void); + +/** + * \brief EC implementation "m64" (specialised code) for P-256. + * + * This implementation uses custom code relying on multiplication of + * integers up to 64 bits, with a 128-bit result. This implementation is + * defined only on platforms that offer the 64x64->128 multiplication + * support; use `br_ec_p256_m64_get()` to dynamically obtain a pointer + * to that implementation. + */ +extern const br_ec_impl br_ec_p256_m64; + +/** + * \brief Get the "m64" implementation of P-256, if available. + * + * \return the implementation, or 0. + */ +const br_ec_impl *br_ec_p256_m64_get(void); + +/** + * \brief EC implementation "i15" (generic code) for Curve25519. + * + * This implementation uses the generic code for modular integers (with + * 15-bit words) to support Curve25519. Due to the specificities of the + * curve definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). + */ +extern const br_ec_impl br_ec_c25519_i15; + +/** + * \brief EC implementation "i31" (generic code) for Curve25519. + * + * This implementation uses the generic code for modular integers (with + * 31-bit words) to support Curve25519. Due to the specificities of the + * curve definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). + */ +extern const br_ec_impl br_ec_c25519_i31; + +/** + * \brief EC implementation "m15" (specialised code) for Curve25519. + * + * This implementation uses custom code relying on multiplication of + * integers up to 15 bits. Due to the specificities of the curve + * definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). + */ +extern const br_ec_impl br_ec_c25519_m15; + +/** + * \brief EC implementation "m31" (specialised code) for Curve25519. + * + * This implementation uses custom code relying on multiplication of + * integers up to 31 bits. Due to the specificities of the curve + * definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). + */ +extern const br_ec_impl br_ec_c25519_m31; + +/** + * \brief EC implementation "m62" (specialised code) for Curve25519. + * + * This implementation uses custom code relying on multiplication of + * integers up to 62 bits, with a 124-bit result. This implementation is + * defined only on platforms that offer the 64x64->128 multiplication + * support; use `br_ec_c25519_m62_get()` to dynamically obtain a pointer + * to that implementation. Due to the specificities of the curve + * definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). + */ +extern const br_ec_impl br_ec_c25519_m62; + +/** + * \brief Get the "m62" implementation of Curve25519, if available. + * + * \return the implementation, or 0. + */ +const br_ec_impl *br_ec_c25519_m62_get(void); + +/** + * \brief EC implementation "m64" (specialised code) for Curve25519. + * + * This implementation uses custom code relying on multiplication of + * integers up to 64 bits, with a 128-bit result. This implementation is + * defined only on platforms that offer the 64x64->128 multiplication + * support; use `br_ec_c25519_m64_get()` to dynamically obtain a pointer + * to that implementation. Due to the specificities of the curve + * definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). + */ +extern const br_ec_impl br_ec_c25519_m64; + +/** + * \brief Get the "m64" implementation of Curve25519, if available. + * + * \return the implementation, or 0. + */ +const br_ec_impl *br_ec_c25519_m64_get(void); + +/** + * \brief Aggregate EC implementation "m15". + * + * This implementation is a wrapper for: + * + * - `br_ec_c25519_m15` for Curve25519 + * - `br_ec_p256_m15` for NIST P-256 + * - `br_ec_prime_i15` for other curves (NIST P-384 and NIST-P512) + */ +extern const br_ec_impl br_ec_all_m15; + +/** + * \brief Aggregate EC implementation "m31". + * + * This implementation is a wrapper for: + * + * - `br_ec_c25519_m31` for Curve25519 + * - `br_ec_p256_m31` for NIST P-256 + * - `br_ec_prime_i31` for other curves (NIST P-384 and NIST-P512) + */ +extern const br_ec_impl br_ec_all_m31; + +/** + * \brief Get the "default" EC implementation for the current system. + * + * This returns a pointer to the preferred implementation on the + * current system. + * + * \return the default EC implementation. + */ +const br_ec_impl *br_ec_get_default(void); + +/** + * \brief Convert a signature from "raw" to "asn1". + * + * Conversion is done "in place" and the new length is returned. + * Conversion may enlarge the signature, but by no more than 9 bytes at + * most. On error, 0 is returned (error conditions include an odd raw + * signature length, or an oversized integer). + * + * \param sig signature to convert. + * \param sig_len signature length (in bytes). + * \return the new signature length, or 0 on error. + */ +size_t br_ecdsa_raw_to_asn1(void *sig, size_t sig_len); + +/** + * \brief Convert a signature from "asn1" to "raw". + * + * Conversion is done "in place" and the new length is returned. + * Conversion may enlarge the signature, but the new signature length + * will be less than twice the source length at most. On error, 0 is + * returned (error conditions include an invalid ASN.1 structure or an + * oversized integer). + * + * \param sig signature to convert. + * \param sig_len signature length (in bytes). + * \return the new signature length, or 0 on error. + */ +size_t br_ecdsa_asn1_to_raw(void *sig, size_t sig_len); + +/** + * \brief Type for an ECDSA signer function. + * + * A pointer to the EC implementation is provided. The hash value is + * assumed to have the length inferred from the designated hash function + * class. + * + * Signature is written in the buffer pointed to by `sig`, and the length + * (in bytes) is returned. On error, nothing is written in the buffer, + * and 0 is returned. This function returns 0 if the specified curve is + * not supported by the provided EC implementation. + * + * The signature format is either "raw" or "asn1", depending on the + * implementation; maximum length is predictable from the implemented + * curve: + * + * | curve | raw | asn1 | + * | :--------- | --: | ---: | + * | NIST P-256 | 64 | 72 | + * | NIST P-384 | 96 | 104 | + * | NIST P-521 | 132 | 139 | + * + * \param impl EC implementation to use. + * \param hf hash function used to process the data. + * \param hash_value signed data (hashed). + * \param sk EC private key. + * \param sig destination buffer. + * \return the signature length (in bytes), or 0 on error. + */ +typedef size_t (*br_ecdsa_sign)(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig); + +/** + * \brief Type for an ECDSA signature verification function. + * + * A pointer to the EC implementation is provided. The hashed value, + * computed over the purportedly signed data, is also provided with + * its length. + * + * The signature format is either "raw" or "asn1", depending on the + * implementation. + * + * Returned value is 1 on success (valid signature), 0 on error. This + * function returns 0 if the specified curve is not supported by the + * provided EC implementation. + * + * \param impl EC implementation to use. + * \param hash signed data (hashed). + * \param hash_len hash value length (in bytes). + * \param pk EC public key. + * \param sig signature. + * \param sig_len signature length (in bytes). + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_ecdsa_vrfy)(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, const void *sig, size_t sig_len); + +/** + * \brief ECDSA signature generator, "i31" implementation, "asn1" format. + * + * \see br_ecdsa_sign() + * + * \param impl EC implementation to use. + * \param hf hash function used to process the data. + * \param hash_value signed data (hashed). + * \param sk EC private key. + * \param sig destination buffer. + * \return the signature length (in bytes), or 0 on error. + */ +size_t br_ecdsa_i31_sign_asn1(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig); + +/** + * \brief ECDSA signature generator, "i31" implementation, "raw" format. + * + * \see br_ecdsa_sign() + * + * \param impl EC implementation to use. + * \param hf hash function used to process the data. + * \param hash_value signed data (hashed). + * \param sk EC private key. + * \param sig destination buffer. + * \return the signature length (in bytes), or 0 on error. + */ +size_t br_ecdsa_i31_sign_raw(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig); + +/** + * \brief ECDSA signature verifier, "i31" implementation, "asn1" format. + * + * \see br_ecdsa_vrfy() + * + * \param impl EC implementation to use. + * \param hash signed data (hashed). + * \param hash_len hash value length (in bytes). + * \param pk EC public key. + * \param sig signature. + * \param sig_len signature length (in bytes). + * \return 1 on success, 0 on error. + */ +uint32_t br_ecdsa_i31_vrfy_asn1(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, const void *sig, size_t sig_len); + +/** + * \brief ECDSA signature verifier, "i31" implementation, "raw" format. + * + * \see br_ecdsa_vrfy() + * + * \param impl EC implementation to use. + * \param hash signed data (hashed). + * \param hash_len hash value length (in bytes). + * \param pk EC public key. + * \param sig signature. + * \param sig_len signature length (in bytes). + * \return 1 on success, 0 on error. + */ +uint32_t br_ecdsa_i31_vrfy_raw(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, const void *sig, size_t sig_len); + +/** + * \brief ECDSA signature generator, "i15" implementation, "asn1" format. + * + * \see br_ecdsa_sign() + * + * \param impl EC implementation to use. + * \param hf hash function used to process the data. + * \param hash_value signed data (hashed). + * \param sk EC private key. + * \param sig destination buffer. + * \return the signature length (in bytes), or 0 on error. + */ +size_t br_ecdsa_i15_sign_asn1(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig); + +/** + * \brief ECDSA signature generator, "i15" implementation, "raw" format. + * + * \see br_ecdsa_sign() + * + * \param impl EC implementation to use. + * \param hf hash function used to process the data. + * \param hash_value signed data (hashed). + * \param sk EC private key. + * \param sig destination buffer. + * \return the signature length (in bytes), or 0 on error. + */ +size_t br_ecdsa_i15_sign_raw(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig); + +/** + * \brief ECDSA signature verifier, "i15" implementation, "asn1" format. + * + * \see br_ecdsa_vrfy() + * + * \param impl EC implementation to use. + * \param hash signed data (hashed). + * \param hash_len hash value length (in bytes). + * \param pk EC public key. + * \param sig signature. + * \param sig_len signature length (in bytes). + * \return 1 on success, 0 on error. + */ +uint32_t br_ecdsa_i15_vrfy_asn1(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, const void *sig, size_t sig_len); + +/** + * \brief ECDSA signature verifier, "i15" implementation, "raw" format. + * + * \see br_ecdsa_vrfy() + * + * \param impl EC implementation to use. + * \param hash signed data (hashed). + * \param hash_len hash value length (in bytes). + * \param pk EC public key. + * \param sig signature. + * \param sig_len signature length (in bytes). + * \return 1 on success, 0 on error. + */ +uint32_t br_ecdsa_i15_vrfy_raw(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, const void *sig, size_t sig_len); + +/** + * \brief Get "default" ECDSA implementation (signer, asn1 format). + * + * This returns the preferred implementation of ECDSA signature generation + * ("asn1" output format) on the current system. + * + * \return the default implementation. + */ +br_ecdsa_sign br_ecdsa_sign_asn1_get_default(void); + +/** + * \brief Get "default" ECDSA implementation (signer, raw format). + * + * This returns the preferred implementation of ECDSA signature generation + * ("raw" output format) on the current system. + * + * \return the default implementation. + */ +br_ecdsa_sign br_ecdsa_sign_raw_get_default(void); + +/** + * \brief Get "default" ECDSA implementation (verifier, asn1 format). + * + * This returns the preferred implementation of ECDSA signature verification + * ("asn1" output format) on the current system. + * + * \return the default implementation. + */ +br_ecdsa_vrfy br_ecdsa_vrfy_asn1_get_default(void); + +/** + * \brief Get "default" ECDSA implementation (verifier, raw format). + * + * This returns the preferred implementation of ECDSA signature verification + * ("raw" output format) on the current system. + * + * \return the default implementation. + */ +br_ecdsa_vrfy br_ecdsa_vrfy_raw_get_default(void); + +/** + * \brief Maximum size for EC private key element buffer. + * + * This is the largest number of bytes that `br_ec_keygen()` may need or + * ever return. + */ +#define BR_EC_KBUF_PRIV_MAX_SIZE 72 + +/** + * \brief Maximum size for EC public key element buffer. + * + * This is the largest number of bytes that `br_ec_compute_public()` may + * need or ever return. + */ +#define BR_EC_KBUF_PUB_MAX_SIZE 145 + +/** + * \brief Generate a new EC private key. + * + * If the specified `curve` is not supported by the elliptic curve + * implementation (`impl`), then this function returns zero. + * + * The `sk` structure fields are set to the new private key data. In + * particular, `sk.x` is made to point to the provided key buffer (`kbuf`), + * in which the actual private key data is written. That buffer is assumed + * to be large enough. The `BR_EC_KBUF_PRIV_MAX_SIZE` defines the maximum + * size for all supported curves. + * + * The number of bytes used in `kbuf` is returned. If `kbuf` is `NULL`, then + * the private key is not actually generated, and `sk` may also be `NULL`; + * the minimum length for `kbuf` is still computed and returned. + * + * If `sk` is `NULL` but `kbuf` is not `NULL`, then the private key is + * still generated and stored in `kbuf`. + * + * \param rng_ctx source PRNG context (already initialized). + * \param impl the elliptic curve implementation. + * \param sk the private key structure to fill, or `NULL`. + * \param kbuf the key element buffer, or `NULL`. + * \param curve the curve identifier. + * \return the key data length (in bytes), or zero. + */ +size_t br_ec_keygen(const br_prng_class **rng_ctx, + const br_ec_impl *impl, br_ec_private_key *sk, + void *kbuf, int curve); + +/** + * \brief Compute EC public key from EC private key. + * + * This function uses the provided elliptic curve implementation (`impl`) + * to compute the public key corresponding to the private key held in `sk`. + * The public key point is written into `kbuf`, which is then linked from + * the `*pk` structure. The size of the public key point, i.e. the number + * of bytes used in `kbuf`, is returned. + * + * If `kbuf` is `NULL`, then the public key point is NOT computed, and + * the public key structure `*pk` is unmodified (`pk` may be `NULL` in + * that case). The size of the public key point is still returned. + * + * If `pk` is `NULL` but `kbuf` is not `NULL`, then the public key + * point is computed and stored in `kbuf`, and its size is returned. + * + * If the curve used by the private key is not supported by the curve + * implementation, then this function returns zero. + * + * The private key MUST be valid. An off-range private key value is not + * necessarily detected, and leads to unpredictable results. + * + * \param impl the elliptic curve implementation. + * \param pk the public key structure to fill (or `NULL`). + * \param kbuf the public key point buffer (or `NULL`). + * \param sk the source private key. + * \return the public key point length (in bytes), or zero. + */ +size_t br_ec_compute_pub(const br_ec_impl *impl, br_ec_public_key *pk, + void *kbuf, const br_ec_private_key *sk); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/inc/bearssl_hash.h b/BearSSL-OG/libbearssl/inc/bearssl_hash.h new file mode 100644 index 0000000..7d7d233 --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl_hash.h @@ -0,0 +1,1345 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_HASH_H__ +#define BR_BEARSSL_HASH_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_hash.h + * + * # Hash Functions + * + * This file documents the API for hash functions. + * + * + * ## Procedural API + * + * For each implemented hash function, of name "`xxx`", the following + * elements are defined: + * + * - `br_xxx_vtable` + * + * An externally defined instance of `br_hash_class`. + * + * - `br_xxx_SIZE` + * + * A macro that evaluates to the output size (in bytes) of the + * hash function. + * + * - `br_xxx_ID` + * + * A macro that evaluates to a symbolic identifier for the hash + * function. Such identifiers are used with HMAC and signature + * algorithm implementations. + * + * NOTE: for the "standard" hash functions defined in [the TLS + * standard](https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1), + * the symbolic identifiers match the constants used in TLS, i.e. + * 1 to 6 for MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512, + * respectively. + * + * - `br_xxx_context` + * + * Context for an ongoing computation. It is allocated by the + * caller, and a pointer to it is passed to all functions. A + * context contains no interior pointer, so it can be moved around + * and cloned (with a simple `memcpy()` or equivalent) in order to + * capture the function state at some point. Computations that use + * distinct context structures are independent of each other. The + * first field of `br_xxx_context` is always a pointer to the + * `br_xxx_vtable` structure; `br_xxx_init()` sets that pointer. + * + * - `br_xxx_init(br_xxx_context *ctx)` + * + * Initialise the provided context. Previous contents of the structure + * are ignored. This calls resets the context to the start of a new + * hash computation; it also sets the first field of the context + * structure (called `vtable`) to a pointer to the statically + * allocated constant `br_xxx_vtable` structure. + * + * - `br_xxx_update(br_xxx_context *ctx, const void *data, size_t len)` + * + * Add some more bytes to the hash computation represented by the + * provided context. + * + * - `br_xxx_out(const br_xxx_context *ctx, void *out)` + * + * Complete the hash computation and write the result in the provided + * buffer. The output buffer MUST be large enough to accommodate the + * result. The context is NOT modified by this operation, so this + * function can be used to get a "partial hash" while still keeping + * the possibility of adding more bytes to the input. + * + * - `br_xxx_state(const br_xxx_context *ctx, void *out)` + * + * Get a copy of the "current state" for the computation so far. For + * MD functions (MD5, SHA-1, SHA-2 family), this is the running state + * resulting from the processing of the last complete input block. + * Returned value is the current input length (in bytes). + * + * - `br_xxx_set_state(br_xxx_context *ctx, const void *stb, uint64_t count)` + * + * Set the internal state to the provided values. The 'stb' and + * 'count' values shall match that which was obtained from + * `br_xxx_state()`. This restores the hash state only if the state + * values were at an appropriate block boundary. This does NOT set + * the `vtable` pointer in the context. + * + * Context structures can be discarded without any explicit deallocation. + * Hash function implementations are purely software and don't reserve + * any resources outside of the context structure itself. + * + * + * ## Object-Oriented API + * + * For each hash function that follows the procedural API described + * above, an object-oriented API is also provided. In that API, function + * pointers from the vtable (`br_xxx_vtable`) are used. The vtable + * incarnates object-oriented programming. An introduction on the OOP + * concept used here can be read on the BearSSL Web site:
+ *    [https://www.bearssl.org/oop.html](https://www.bearssl.org/oop.html) + * + * The vtable offers functions called `init()`, `update()`, `out()`, + * `set()` and `set_state()`, which are in fact the functions from + * the procedural API. That vtable also contains two informative fields: + * + * - `context_size` + * + * The size of the context structure (`br_xxx_context`), in bytes. + * This can be used by generic implementations to perform dynamic + * context allocation. + * + * - `desc` + * + * A "descriptor" field that encodes some information on the hash + * function: symbolic identifier, output size, state size, + * internal block size, details on the padding. + * + * Users of this object-oriented API (in particular generic HMAC + * implementations) may make the following assumptions: + * + * - Hash output size is no more than 64 bytes. + * - Hash internal state size is no more than 64 bytes. + * - Internal block size is a power of two, no less than 16 and no more + * than 256. + * + * + * ## Implemented Hash Functions + * + * Implemented hash functions are: + * + * | Function | Name | Output length | State length | + * | :-------- | :------ | :-----------: | :----------: | + * | MD5 | md5 | 16 | 16 | + * | SHA-1 | sha1 | 20 | 20 | + * | SHA-224 | sha224 | 28 | 32 | + * | SHA-256 | sha256 | 32 | 32 | + * | SHA-384 | sha384 | 48 | 64 | + * | SHA-512 | sha512 | 64 | 64 | + * | MD5+SHA-1 | md5sha1 | 36 | 36 | + * + * (MD5+SHA-1 is the concatenation of MD5 and SHA-1 computed over the + * same input; in the implementation, the internal data buffer is + * shared, thus making it more memory-efficient than separate MD5 and + * SHA-1. It can be useful in implementing SSL 3.0, TLS 1.0 and TLS + * 1.1.) + * + * + * ## Multi-Hasher + * + * An aggregate hasher is provided, that can compute several standard + * hash functions in parallel. It uses `br_multihash_context` and a + * procedural API. It is configured with the implementations (the vtables) + * that it should use; it will then compute all these hash functions in + * parallel, on the same input. It is meant to be used in cases when the + * hash of an object will be used, but the exact hash function is not + * known yet (typically, streamed processing on X.509 certificates). + * + * Only the standard hash functions (MD5, SHA-1, SHA-224, SHA-256, SHA-384 + * and SHA-512) are supported by the multi-hasher. + * + * + * ## GHASH + * + * GHASH is not a generic hash function; it is a _universal_ hash function, + * which, as the name does not say, means that it CANNOT be used in most + * places where a hash function is needed. GHASH is used within the GCM + * encryption mode, to provide the checked integrity functionality. + * + * A GHASH implementation is basically a function that uses the type defined + * in this file under the name `br_ghash`: + * + * typedef void (*br_ghash)(void *y, const void *h, const void *data, size_t len); + * + * The `y` pointer refers to a 16-byte value which is used as input, and + * receives the output of the GHASH invocation. `h` is a 16-byte secret + * value (that serves as key). `data` and `len` define the input data. + * + * Three GHASH implementations are provided, all constant-time, based on + * the use of integer multiplications with appropriate masking to cancel + * carry propagation. + */ + +/** + * \brief Class type for hash function implementations. + * + * A `br_hash_class` instance references the methods implementing a hash + * function. Constant instances of this structure are defined for each + * implemented hash function. Such instances are also called "vtables". + * + * Vtables are used to support object-oriented programming, as + * described on [the BearSSL Web site](https://www.bearssl.org/oop.html). + */ +typedef struct br_hash_class_ br_hash_class; +struct br_hash_class_ { + /** + * \brief Size (in bytes) of the context structure appropriate for + * computing this hash function. + */ + size_t context_size; + + /** + * \brief Descriptor word that contains information about the hash + * function. + * + * For each word `xxx` described below, use `BR_HASHDESC_xxx_OFF` + * and `BR_HASHDESC_xxx_MASK` to access the specific value, as + * follows: + * + * (hf->desc >> BR_HASHDESC_xxx_OFF) & BR_HASHDESC_xxx_MASK + * + * The defined elements are: + * + * - `ID`: the symbolic identifier for the function, as defined + * in [TLS](https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1) + * (MD5 = 1, SHA-1 = 2,...). + * + * - `OUT`: hash output size, in bytes. + * + * - `STATE`: internal running state size, in bytes. + * + * - `LBLEN`: base-2 logarithm for the internal block size, as + * defined for HMAC processing (this is 6 for MD5, SHA-1, SHA-224 + * and SHA-256, since these functions use 64-byte blocks; for + * SHA-384 and SHA-512, this is 7, corresponding to their + * 128-byte blocks). + * + * The descriptor may contain a few other flags. + */ + uint32_t desc; + + /** + * \brief Initialisation method. + * + * This method takes as parameter a pointer to a context area, + * that it initialises. The first field of the context is set + * to this vtable; other elements are initialised for a new hash + * computation. + * + * \param ctx pointer to (the first field of) the context. + */ + void (*init)(const br_hash_class **ctx); + + /** + * \brief Data injection method. + * + * The `len` bytes starting at address `data` are injected into + * the running hash computation incarnated by the specified + * context. The context is updated accordingly. It is allowed + * to have `len == 0`, in which case `data` is ignored (and could + * be `NULL`), and nothing happens. + * on the input data. + * + * \param ctx pointer to (the first field of) the context. + * \param data pointer to the first data byte to inject. + * \param len number of bytes to inject. + */ + void (*update)(const br_hash_class **ctx, const void *data, size_t len); + + /** + * \brief Produce hash output. + * + * The hash output corresponding to all data bytes injected in the + * context since the last `init()` call is computed, and written + * in the buffer pointed to by `dst`. The hash output size depends + * on the implemented hash function (e.g. 16 bytes for MD5). + * The context is _not_ modified by this call, so further bytes + * may be afterwards injected to continue the current computation. + * + * \param ctx pointer to (the first field of) the context. + * \param dst destination buffer for the hash output. + */ + void (*out)(const br_hash_class *const *ctx, void *dst); + + /** + * \brief Get running state. + * + * This method saves the current running state into the `dst` + * buffer. What constitutes the "running state" depends on the + * hash function; for Merkle-DamgÃ¥rd hash functions (like + * MD5 or SHA-1), this is the output obtained after processing + * each block. The number of bytes injected so far is returned. + * The context is not modified by this call. + * + * \param ctx pointer to (the first field of) the context. + * \param dst destination buffer for the state. + * \return the injected total byte length. + */ + uint64_t (*state)(const br_hash_class *const *ctx, void *dst); + + /** + * \brief Set running state. + * + * This methods replaces the running state for the function. + * + * \param ctx pointer to (the first field of) the context. + * \param stb source buffer for the state. + * \param count injected total byte length. + */ + void (*set_state)(const br_hash_class **ctx, + const void *stb, uint64_t count); +}; + +#ifndef BR_DOXYGEN_IGNORE +#define BR_HASHDESC_ID(id) ((uint32_t)(id) << BR_HASHDESC_ID_OFF) +#define BR_HASHDESC_ID_OFF 0 +#define BR_HASHDESC_ID_MASK 0xFF + +#define BR_HASHDESC_OUT(size) ((uint32_t)(size) << BR_HASHDESC_OUT_OFF) +#define BR_HASHDESC_OUT_OFF 8 +#define BR_HASHDESC_OUT_MASK 0x7F + +#define BR_HASHDESC_STATE(size) ((uint32_t)(size) << BR_HASHDESC_STATE_OFF) +#define BR_HASHDESC_STATE_OFF 15 +#define BR_HASHDESC_STATE_MASK 0xFF + +#define BR_HASHDESC_LBLEN(ls) ((uint32_t)(ls) << BR_HASHDESC_LBLEN_OFF) +#define BR_HASHDESC_LBLEN_OFF 23 +#define BR_HASHDESC_LBLEN_MASK 0x0F + +#define BR_HASHDESC_MD_PADDING ((uint32_t)1 << 28) +#define BR_HASHDESC_MD_PADDING_128 ((uint32_t)1 << 29) +#define BR_HASHDESC_MD_PADDING_BE ((uint32_t)1 << 30) +#endif + +/* + * Specific hash functions. + * + * Rules for contexts: + * -- No interior pointer. + * -- No pointer to external dynamically allocated resources. + * -- First field is called 'vtable' and is a pointer to a + * const-qualified br_hash_class instance (pointer is set by init()). + * -- SHA-224 and SHA-256 contexts are identical. + * -- SHA-384 and SHA-512 contexts are identical. + * + * Thus, contexts can be moved and cloned to capture the hash function + * current state; and there is no need for any explicit "release" function. + */ + +/** + * \brief Symbolic identifier for MD5. + */ +#define br_md5_ID 1 + +/** + * \brief MD5 output size (in bytes). + */ +#define br_md5_SIZE 16 + +/** + * \brief Constant vtable for MD5. + */ +extern const br_hash_class br_md5_vtable; + +/** + * \brief MD5 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char buf[64]; + uint64_t count; + uint32_t val[4]; +#endif +} br_md5_context; + +/** + * \brief MD5 context initialisation. + * + * This function initialises or resets a context for a new MD5 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_md5_init(br_md5_context *ctx); + +/** + * \brief Inject some data bytes in a running MD5 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_md5_update(br_md5_context *ctx, const void *data, size_t len); + +/** + * \brief Compute MD5 output. + * + * The MD5 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_md5_out(const br_md5_context *ctx, void *out); + +/** + * \brief Save MD5 running state. + * + * The running state for MD5 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_md5_state(const br_md5_context *ctx, void *out); + +/** + * \brief Restore MD5 running state. + * + * The running state for MD5 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_md5_set_state(br_md5_context *ctx, const void *stb, uint64_t count); + +/** + * \brief Symbolic identifier for SHA-1. + */ +#define br_sha1_ID 2 + +/** + * \brief SHA-1 output size (in bytes). + */ +#define br_sha1_SIZE 20 + +/** + * \brief Constant vtable for SHA-1. + */ +extern const br_hash_class br_sha1_vtable; + +/** + * \brief SHA-1 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char buf[64]; + uint64_t count; + uint32_t val[5]; +#endif +} br_sha1_context; + +/** + * \brief SHA-1 context initialisation. + * + * This function initialises or resets a context for a new SHA-1 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_sha1_init(br_sha1_context *ctx); + +/** + * \brief Inject some data bytes in a running SHA-1 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_sha1_update(br_sha1_context *ctx, const void *data, size_t len); + +/** + * \brief Compute SHA-1 output. + * + * The SHA-1 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_sha1_out(const br_sha1_context *ctx, void *out); + +/** + * \brief Save SHA-1 running state. + * + * The running state for SHA-1 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_sha1_state(const br_sha1_context *ctx, void *out); + +/** + * \brief Restore SHA-1 running state. + * + * The running state for SHA-1 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_sha1_set_state(br_sha1_context *ctx, const void *stb, uint64_t count); + +/** + * \brief Symbolic identifier for SHA-224. + */ +#define br_sha224_ID 3 + +/** + * \brief SHA-224 output size (in bytes). + */ +#define br_sha224_SIZE 28 + +/** + * \brief Constant vtable for SHA-224. + */ +extern const br_hash_class br_sha224_vtable; + +/** + * \brief SHA-224 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char buf[64]; + uint64_t count; + uint32_t val[8]; +#endif +} br_sha224_context; + +/** + * \brief SHA-224 context initialisation. + * + * This function initialises or resets a context for a new SHA-224 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_sha224_init(br_sha224_context *ctx); + +/** + * \brief Inject some data bytes in a running SHA-224 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_sha224_update(br_sha224_context *ctx, const void *data, size_t len); + +/** + * \brief Compute SHA-224 output. + * + * The SHA-224 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_sha224_out(const br_sha224_context *ctx, void *out); + +/** + * \brief Save SHA-224 running state. + * + * The running state for SHA-224 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_sha224_state(const br_sha224_context *ctx, void *out); + +/** + * \brief Restore SHA-224 running state. + * + * The running state for SHA-224 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_sha224_set_state(br_sha224_context *ctx, + const void *stb, uint64_t count); + +/** + * \brief Symbolic identifier for SHA-256. + */ +#define br_sha256_ID 4 + +/** + * \brief SHA-256 output size (in bytes). + */ +#define br_sha256_SIZE 32 + +/** + * \brief Constant vtable for SHA-256. + */ +extern const br_hash_class br_sha256_vtable; + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief SHA-256 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +} br_sha256_context; +#else +typedef br_sha224_context br_sha256_context; +#endif + +/** + * \brief SHA-256 context initialisation. + * + * This function initialises or resets a context for a new SHA-256 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_sha256_init(br_sha256_context *ctx); + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief Inject some data bytes in a running SHA-256 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_sha256_update(br_sha256_context *ctx, const void *data, size_t len); +#else +#define br_sha256_update br_sha224_update +#endif + +/** + * \brief Compute SHA-256 output. + * + * The SHA-256 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_sha256_out(const br_sha256_context *ctx, void *out); + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief Save SHA-256 running state. + * + * The running state for SHA-256 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_sha256_state(const br_sha256_context *ctx, void *out); +#else +#define br_sha256_state br_sha224_state +#endif + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief Restore SHA-256 running state. + * + * The running state for SHA-256 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_sha256_set_state(br_sha256_context *ctx, + const void *stb, uint64_t count); +#else +#define br_sha256_set_state br_sha224_set_state +#endif + +/** + * \brief Symbolic identifier for SHA-384. + */ +#define br_sha384_ID 5 + +/** + * \brief SHA-384 output size (in bytes). + */ +#define br_sha384_SIZE 48 + +/** + * \brief Constant vtable for SHA-384. + */ +extern const br_hash_class br_sha384_vtable; + +/** + * \brief SHA-384 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char buf[128]; + uint64_t count; + uint64_t val[8]; +#endif +} br_sha384_context; + +/** + * \brief SHA-384 context initialisation. + * + * This function initialises or resets a context for a new SHA-384 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_sha384_init(br_sha384_context *ctx); + +/** + * \brief Inject some data bytes in a running SHA-384 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_sha384_update(br_sha384_context *ctx, const void *data, size_t len); + +/** + * \brief Compute SHA-384 output. + * + * The SHA-384 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_sha384_out(const br_sha384_context *ctx, void *out); + +/** + * \brief Save SHA-384 running state. + * + * The running state for SHA-384 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_sha384_state(const br_sha384_context *ctx, void *out); + +/** + * \brief Restore SHA-384 running state. + * + * The running state for SHA-384 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_sha384_set_state(br_sha384_context *ctx, + const void *stb, uint64_t count); + +/** + * \brief Symbolic identifier for SHA-512. + */ +#define br_sha512_ID 6 + +/** + * \brief SHA-512 output size (in bytes). + */ +#define br_sha512_SIZE 64 + +/** + * \brief Constant vtable for SHA-512. + */ +extern const br_hash_class br_sha512_vtable; + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief SHA-512 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +} br_sha512_context; +#else +typedef br_sha384_context br_sha512_context; +#endif + +/** + * \brief SHA-512 context initialisation. + * + * This function initialises or resets a context for a new SHA-512 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_sha512_init(br_sha512_context *ctx); + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief Inject some data bytes in a running SHA-512 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_sha512_update(br_sha512_context *ctx, const void *data, size_t len); +#else +#define br_sha512_update br_sha384_update +#endif + +/** + * \brief Compute SHA-512 output. + * + * The SHA-512 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_sha512_out(const br_sha512_context *ctx, void *out); + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief Save SHA-512 running state. + * + * The running state for SHA-512 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_sha512_state(const br_sha512_context *ctx, void *out); +#else +#define br_sha512_state br_sha384_state +#endif + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief Restore SHA-512 running state. + * + * The running state for SHA-512 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_sha512_set_state(br_sha512_context *ctx, + const void *stb, uint64_t count); +#else +#define br_sha512_set_state br_sha384_set_state +#endif + +/* + * "md5sha1" is a special hash function that computes both MD5 and SHA-1 + * on the same input, and produces a 36-byte output (MD5 and SHA-1 + * concatenation, in that order). State size is also 36 bytes. + */ + +/** + * \brief Symbolic identifier for MD5+SHA-1. + * + * MD5+SHA-1 is the concatenation of MD5 and SHA-1, computed over the + * same input. It is not one of the functions identified in TLS, so + * we give it a symbolic identifier of value 0. + */ +#define br_md5sha1_ID 0 + +/** + * \brief MD5+SHA-1 output size (in bytes). + */ +#define br_md5sha1_SIZE 36 + +/** + * \brief Constant vtable for MD5+SHA-1. + */ +extern const br_hash_class br_md5sha1_vtable; + +/** + * \brief MD5+SHA-1 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char buf[64]; + uint64_t count; + uint32_t val_md5[4]; + uint32_t val_sha1[5]; +#endif +} br_md5sha1_context; + +/** + * \brief MD5+SHA-1 context initialisation. + * + * This function initialises or resets a context for a new SHA-512 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_md5sha1_init(br_md5sha1_context *ctx); + +/** + * \brief Inject some data bytes in a running MD5+SHA-1 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_md5sha1_update(br_md5sha1_context *ctx, const void *data, size_t len); + +/** + * \brief Compute MD5+SHA-1 output. + * + * The MD5+SHA-1 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_md5sha1_out(const br_md5sha1_context *ctx, void *out); + +/** + * \brief Save MD5+SHA-1 running state. + * + * The running state for MD5+SHA-1 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_md5sha1_state(const br_md5sha1_context *ctx, void *out); + +/** + * \brief Restore MD5+SHA-1 running state. + * + * The running state for MD5+SHA-1 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_md5sha1_set_state(br_md5sha1_context *ctx, + const void *stb, uint64_t count); + +/** + * \brief Aggregate context for configurable hash function support. + * + * The `br_hash_compat_context` type is a type which is large enough to + * serve as context for all standard hash functions defined above. + */ +typedef union { + const br_hash_class *vtable; + br_md5_context md5; + br_sha1_context sha1; + br_sha224_context sha224; + br_sha256_context sha256; + br_sha384_context sha384; + br_sha512_context sha512; + br_md5sha1_context md5sha1; +} br_hash_compat_context; + +/* + * The multi-hasher is a construct that handles hashing of the same input + * data with several hash functions, with a single shared input buffer. + * It can handle MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 + * simultaneously, though which functions are activated depends on + * the set implementation pointers. + */ + +/** + * \brief Multi-hasher context structure. + * + * The multi-hasher runs up to six hash functions in the standard TLS list + * (MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512) in parallel, over + * the same input. + * + * The multi-hasher does _not_ follow the OOP structure with a vtable. + * Instead, it is configured with the vtables of the hash functions it + * should run. Structure fields are not supposed to be accessed directly. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + unsigned char buf[128]; + uint64_t count; + uint32_t val_32[25]; + uint64_t val_64[16]; + const br_hash_class *impl[6]; +#endif +} br_multihash_context; + +/** + * \brief Clear a multi-hasher context. + * + * This should always be called once on a given context, _before_ setting + * the implementation pointers. + * + * \param ctx the multi-hasher context. + */ +void br_multihash_zero(br_multihash_context *ctx); + +/** + * \brief Set a hash function implementation. + * + * Implementations shall be set _after_ clearing the context (with + * `br_multihash_zero()`) but _before_ initialising the computation + * (with `br_multihash_init()`). The hash function implementation + * MUST be one of the standard hash functions (MD5, SHA-1, SHA-224, + * SHA-256, SHA-384 or SHA-512); it may also be `NULL` to remove + * an implementation from the multi-hasher. + * + * \param ctx the multi-hasher context. + * \param id the hash function symbolic identifier. + * \param impl the hash function vtable, or `NULL`. + */ +static __inline void br_multihash_setimpl(br_multihash_context *ctx, + int id, const br_hash_class *impl) +{ + /* + * This code relies on hash functions ID being values 1 to 6, + * in the MD5 to SHA-512 order. + */ + ctx->impl[id - 1] = impl; +} + +/** + * \brief Get a hash function implementation. + * + * This function returns the currently configured vtable for a given + * hash function (by symbolic ID). If no such function was configured in + * the provided multi-hasher context, then this function returns `NULL`. + * + * \param ctx the multi-hasher context. + * \param id the hash function symbolic identifier. + * \return the hash function vtable, or `NULL`. + */ +static __inline const br_hash_class * +br_multihash_getimpl(const br_multihash_context *ctx, int id) +{ + return ctx->impl[id - 1]; +} + +/** + * \brief Reset a multi-hasher context. + * + * This function prepares the context for a new hashing computation, + * for all implementations configured at that point. + * + * \param ctx the multi-hasher context. + */ +void br_multihash_init(br_multihash_context *ctx); + +/** + * \brief Inject some data bytes in a running multi-hashing computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_multihash_update(br_multihash_context *ctx, + const void *data, size_t len); + +/** + * \brief Compute a hash output from a multi-hasher. + * + * The hash output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `dst`. The hash + * function to use is identified by `id` and must be one of the standard + * hash functions. If that hash function was indeed configured in the + * multi-hasher context, the corresponding hash value is written in + * `dst` and its length (in bytes) is returned. If the hash function + * was _not_ configured, then nothing is written in `dst` and 0 is + * returned. + * + * The context itself is not modified, so extra bytes may be injected + * afterwards to continue the hash computations. + * + * \param ctx pointer to the context structure. + * \param id the hash function symbolic identifier. + * \param dst destination buffer for the hash output. + * \return the hash output length (in bytes), or 0. + */ +size_t br_multihash_out(const br_multihash_context *ctx, int id, void *dst); + +/** + * \brief Type for a GHASH implementation. + * + * GHASH is a sort of keyed hash meant to be used to implement GCM in + * combination with a block cipher (with 16-byte blocks). + * + * The `y` array has length 16 bytes and is used for input and output; in + * a complete GHASH run, it starts with an all-zero value. `h` is a 16-byte + * value that serves as key (it is derived from the encryption key in GCM, + * using the block cipher). The data length (`len`) is expressed in bytes. + * The `y` array is updated. + * + * If the data length is not a multiple of 16, then the data is implicitly + * padded with zeros up to the next multiple of 16. Thus, when using GHASH + * in GCM, this method may be called twice, for the associated data and + * for the ciphertext, respectively; the zero-padding implements exactly + * the GCM rules. + * + * \param y the array to update. + * \param h the GHASH key. + * \param data the input data (may be `NULL` if `len` is zero). + * \param len the input data length (in bytes). + */ +typedef void (*br_ghash)(void *y, const void *h, const void *data, size_t len); + +/** + * \brief GHASH implementation using multiplications (mixed 32-bit). + * + * This implementation uses multiplications of 32-bit values, with a + * 64-bit result. It is constant-time (if multiplications are + * constant-time). + * + * \param y the array to update. + * \param h the GHASH key. + * \param data the input data (may be `NULL` if `len` is zero). + * \param len the input data length (in bytes). + */ +void br_ghash_ctmul(void *y, const void *h, const void *data, size_t len); + +/** + * \brief GHASH implementation using multiplications (strict 32-bit). + * + * This implementation uses multiplications of 32-bit values, with a + * 32-bit result. It is usually somewhat slower than `br_ghash_ctmul()`, + * but it is expected to be faster on architectures for which the + * 32-bit multiplication opcode does not yield the upper 32 bits of the + * product. It is constant-time (if multiplications are constant-time). + * + * \param y the array to update. + * \param h the GHASH key. + * \param data the input data (may be `NULL` if `len` is zero). + * \param len the input data length (in bytes). + */ +void br_ghash_ctmul32(void *y, const void *h, const void *data, size_t len); + +/** + * \brief GHASH implementation using multiplications (64-bit). + * + * This implementation uses multiplications of 64-bit values, with a + * 64-bit result. It is constant-time (if multiplications are + * constant-time). It is substantially faster than `br_ghash_ctmul()` + * and `br_ghash_ctmul32()` on most 64-bit architectures. + * + * \param y the array to update. + * \param h the GHASH key. + * \param data the input data (may be `NULL` if `len` is zero). + * \param len the input data length (in bytes). + */ +void br_ghash_ctmul64(void *y, const void *h, const void *data, size_t len); + +/** + * \brief GHASH implementation using the `pclmulqdq` opcode (part of the + * AES-NI instructions). + * + * This implementation is available only on x86 platforms where the + * compiler supports the relevant intrinsic functions. Even if the + * compiler supports these functions, the local CPU might not support + * the `pclmulqdq` opcode, meaning that a call will fail with an + * illegal instruction exception. To safely obtain a pointer to this + * function when supported (or 0 otherwise), use `br_ghash_pclmul_get()`. + * + * \param y the array to update. + * \param h the GHASH key. + * \param data the input data (may be `NULL` if `len` is zero). + * \param len the input data length (in bytes). + */ +void br_ghash_pclmul(void *y, const void *h, const void *data, size_t len); + +/** + * \brief Obtain the `pclmul` GHASH implementation, if available. + * + * If the `pclmul` implementation was compiled in the library (depending + * on the compiler abilities) _and_ the local CPU appears to support the + * opcode, then this function will return a pointer to the + * `br_ghash_pclmul()` function. Otherwise, it will return `0`. + * + * \return the `pclmul` GHASH implementation, or `0`. + */ +br_ghash br_ghash_pclmul_get(void); + +/** + * \brief GHASH implementation using the POWER8 opcodes. + * + * This implementation is available only on POWER8 platforms (and later). + * To safely obtain a pointer to this function when supported (or 0 + * otherwise), use `br_ghash_pwr8_get()`. + * + * \param y the array to update. + * \param h the GHASH key. + * \param data the input data (may be `NULL` if `len` is zero). + * \param len the input data length (in bytes). + */ +void br_ghash_pwr8(void *y, const void *h, const void *data, size_t len); + +/** + * \brief Obtain the `pwr8` GHASH implementation, if available. + * + * If the `pwr8` implementation was compiled in the library (depending + * on the compiler abilities) _and_ the local CPU appears to support the + * opcode, then this function will return a pointer to the + * `br_ghash_pwr8()` function. Otherwise, it will return `0`. + * + * \return the `pwr8` GHASH implementation, or `0`. + */ +br_ghash br_ghash_pwr8_get(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/inc/bearssl_hmac.h b/BearSSL-OG/libbearssl/inc/bearssl_hmac.h new file mode 100644 index 0000000..baa968b --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl_hmac.h @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_HMAC_H__ +#define BR_BEARSSL_HMAC_H__ + +#include +#include + +#include "bearssl_hash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_hmac.h + * + * # HMAC + * + * HMAC is initialized with a key and an underlying hash function; it + * then fills a "key context". That context contains the processed + * key. + * + * With the key context, a HMAC context can be initialized to process + * the input bytes and obtain the MAC output. The key context is not + * modified during that process, and can be reused. + * + * IMPORTANT: HMAC shall be used only with functions that have the + * following properties: + * + * - hash output size does not exceed 64 bytes; + * - hash internal state size does not exceed 64 bytes; + * - internal block length is a power of 2 between 16 and 256 bytes. + */ + +/** + * \brief HMAC key context. + * + * The HMAC key context is initialised with a hash function implementation + * and a secret key. Contents are opaque (callers should not access them + * directly). The caller is responsible for allocating the context where + * appropriate. Context initialisation and usage incurs no dynamic + * allocation, so there is no release function. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + const br_hash_class *dig_vtable; + unsigned char ksi[64], kso[64]; +#endif +} br_hmac_key_context; + +/** + * \brief HMAC key context initialisation. + * + * Initialise the key context with the provided key, using the hash function + * identified by `digest_vtable`. This supports arbitrary key lengths. + * + * \param kc HMAC key context to initialise. + * \param digest_vtable pointer to the hash function implementation vtable. + * \param key pointer to the HMAC secret key. + * \param key_len HMAC secret key length (in bytes). + */ +void br_hmac_key_init(br_hmac_key_context *kc, + const br_hash_class *digest_vtable, const void *key, size_t key_len); + +/* + * \brief Get the underlying hash function. + * + * This function returns a pointer to the implementation vtable of the + * hash function used for this HMAC key context. + * + * \param kc HMAC key context. + * \return the hash function implementation. + */ +static __inline const br_hash_class *br_hmac_key_get_digest( + const br_hmac_key_context *kc) +{ + return kc->dig_vtable; +} + +/** + * \brief HMAC computation context. + * + * The HMAC computation context maintains the state for a single HMAC + * computation. It is modified as input bytes are injected. The context + * is caller-allocated and has no release function since it does not + * dynamically allocate external resources. Its contents are opaque. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + br_hash_compat_context dig; + unsigned char kso[64]; + size_t out_len; +#endif +} br_hmac_context; + +/** + * \brief HMAC computation initialisation. + * + * Initialise a HMAC context with a key context. The key context is + * unmodified. Relevant data from the key context is immediately copied; + * the key context can thus be independently reused, modified or released + * without impacting this HMAC computation. + * + * An explicit output length can be specified; the actual output length + * will be the minimum of that value and the natural HMAC output length. + * If `out_len` is 0, then the natural HMAC output length is selected. The + * "natural output length" is the output length of the underlying hash + * function. + * + * \param ctx HMAC context to initialise. + * \param kc HMAC key context (already initialised with the key). + * \param out_len HMAC output length (0 to select "natural length"). + */ +void br_hmac_init(br_hmac_context *ctx, + const br_hmac_key_context *kc, size_t out_len); + +/** + * \brief Get the HMAC output size. + * + * The HMAC output size is the number of bytes that will actually be + * produced with `br_hmac_out()` with the provided context. This function + * MUST NOT be called on a non-initialised HMAC computation context. + * The returned value is the minimum of the HMAC natural length (output + * size of the underlying hash function) and the `out_len` parameter which + * was used with the last `br_hmac_init()` call on that context (if the + * initialisation `out_len` parameter was 0, then this function will + * return the HMAC natural length). + * + * \param ctx the (already initialised) HMAC computation context. + * \return the HMAC actual output size. + */ +static __inline size_t +br_hmac_size(br_hmac_context *ctx) +{ + return ctx->out_len; +} + +/* + * \brief Get the underlying hash function. + * + * This function returns a pointer to the implementation vtable of the + * hash function used for this HMAC context. + * + * \param hc HMAC context. + * \return the hash function implementation. + */ +static __inline const br_hash_class *br_hmac_get_digest( + const br_hmac_context *hc) +{ + return hc->dig.vtable; +} + +/** + * \brief Inject some bytes in HMAC. + * + * The provided `len` bytes are injected as extra input in the HMAC + * computation incarnated by the `ctx` HMAC context. It is acceptable + * that `len` is zero, in which case `data` is ignored (and may be + * `NULL`) and this function does nothing. + */ +void br_hmac_update(br_hmac_context *ctx, const void *data, size_t len); + +/** + * \brief Compute the HMAC output. + * + * The destination buffer MUST be large enough to accommodate the result; + * its length is at most the "natural length" of HMAC (i.e. the output + * length of the underlying hash function). The context is NOT modified; + * further bytes may be processed. Thus, "partial HMAC" values can be + * efficiently obtained. + * + * Returned value is the output length (in bytes). + * + * \param ctx HMAC computation context. + * \param out destination buffer for the HMAC output. + * \return the produced value length (in bytes). + */ +size_t br_hmac_out(const br_hmac_context *ctx, void *out); + +/** + * \brief Constant-time HMAC computation. + * + * This function compute the HMAC output in constant time. Some extra + * input bytes are processed, then the output is computed. The extra + * input consists in the `len` bytes pointed to by `data`. The `len` + * parameter must lie between `min_len` and `max_len` (inclusive); + * `max_len` bytes are actually read from `data`. Computing time (and + * memory access pattern) will not depend upon the data byte contents or + * the value of `len`. + * + * The output is written in the `out` buffer, that MUST be large enough + * to receive it. + * + * The difference `max_len - min_len` MUST be less than 230 + * (i.e. about one gigabyte). + * + * This function computes the output properly only if the underlying + * hash function uses MD padding (i.e. MD5, SHA-1, SHA-224, SHA-256, + * SHA-384 or SHA-512). + * + * The provided context is NOT modified. + * + * \param ctx the (already initialised) HMAC computation context. + * \param data the extra input bytes. + * \param len the extra input length (in bytes). + * \param min_len minimum extra input length (in bytes). + * \param max_len maximum extra input length (in bytes). + * \param out destination buffer for the HMAC output. + * \return the produced value length (in bytes). + */ +size_t br_hmac_outCT(const br_hmac_context *ctx, + const void *data, size_t len, size_t min_len, size_t max_len, + void *out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/inc/bearssl_kdf.h b/BearSSL-OG/libbearssl/inc/bearssl_kdf.h new file mode 100644 index 0000000..955b843 --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl_kdf.h @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_KDF_H__ +#define BR_BEARSSL_KDF_H__ + +#include +#include + +#include "bearssl_hash.h" +#include "bearssl_hmac.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_kdf.h + * + * # Key Derivation Functions + * + * KDF are functions that takes a variable length input, and provide a + * variable length output, meant to be used to derive subkeys from a + * master key. + * + * ## HKDF + * + * HKDF is a KDF defined by [RFC 5869](https://tools.ietf.org/html/rfc5869). + * It is based on HMAC, itself using an underlying hash function. Any + * hash function can be used, as long as it is compatible with the rules + * for the HMAC implementation (i.e. output size is 64 bytes or less, hash + * internal state size is 64 bytes or less, and the internal block length is + * a power of 2 between 16 and 256 bytes). HKDF has two phases: + * + * - HKDF-Extract: the input data in ingested, along with a "salt" value. + * + * - HKDF-Expand: the output is produced, from the result of processing + * the input and salt, and using an extra non-secret parameter called + * "info". + * + * The "salt" and "info" strings are non-secret and can be empty. Their role + * is normally to bind the input and output, respectively, to conventional + * identifiers that qualifu them within the used protocol or application. + * + * The implementation defined in this file uses the following functions: + * + * - `br_hkdf_init()`: initialize an HKDF context, with a hash function, + * and the salt. This starts the HKDF-Extract process. + * + * - `br_hkdf_inject()`: inject more input bytes. This function may be + * called repeatedly if the input data is provided by chunks. + * + * - `br_hkdf_flip()`: end the HKDF-Extract process, and start the + * HKDF-Expand process. + * + * - `br_hkdf_produce()`: get the next bytes of output. This function + * may be called several times to obtain the full output by chunks. + * For correct HKDF processing, the same "info" string must be + * provided for each call. + * + * Note that the HKDF total output size (the number of bytes that + * HKDF-Expand is willing to produce) is limited: if the hash output size + * is _n_ bytes, then the maximum output size is _255*n_. + * + * ## SHAKE + * + * SHAKE is defined in + * [FIPS 202](https://csrc.nist.gov/publications/detail/fips/202/final) + * under two versions: SHAKE128 and SHAKE256, offering an alleged + * "security level" of 128 and 256 bits, respectively (SHAKE128 is + * about 20 to 25% faster than SHAKE256). SHAKE internally relies on + * the Keccak family of sponge functions, not on any externally provided + * hash function. Contrary to HKDF, SHAKE does not have a concept of + * either a "salt" or an "info" string. The API consists in four + * functions: + * + * - `br_shake_init()`: initialize a SHAKE context for a given + * security level. + * + * - `br_shake_inject()`: inject more input bytes. This function may be + * called repeatedly if the input data is provided by chunks. + * + * - `br_shake_flip()`: end the data injection process, and start the + * data production process. + * + * - `br_shake_produce()`: get the next bytes of output. This function + * may be called several times to obtain the full output by chunks. + */ + +/** + * \brief HKDF context. + * + * The HKDF context is initialized with a hash function implementation + * and a salt value. Contents are opaque (callers should not access them + * directly). The caller is responsible for allocating the context where + * appropriate. Context initialisation and usage incurs no dynamic + * allocation, so there is no release function. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + union { + br_hmac_context hmac_ctx; + br_hmac_key_context prk_ctx; + } u; + unsigned char buf[64]; + size_t ptr; + size_t dig_len; + unsigned chunk_num; +#endif +} br_hkdf_context; + +/** + * \brief HKDF context initialization. + * + * The underlying hash function and salt value are provided. Arbitrary + * salt lengths can be used. + * + * HKDF makes a difference between a salt of length zero, and an + * absent salt (the latter being equivalent to a salt consisting of + * bytes of value zero, of the same length as the hash function output). + * If `salt_len` is zero, then this function assumes that the salt is + * present but of length zero. To specify an _absent_ salt, use + * `BR_HKDF_NO_SALT` as `salt` parameter (`salt_len` is then ignored). + * + * \param hc HKDF context to initialise. + * \param digest_vtable pointer to the hash function implementation vtable. + * \param salt HKDF-Extract salt. + * \param salt_len HKDF-Extract salt length (in bytes). + */ +void br_hkdf_init(br_hkdf_context *hc, const br_hash_class *digest_vtable, + const void *salt, size_t salt_len); + +/** + * \brief The special "absent salt" value for HKDF. + */ +#define BR_HKDF_NO_SALT (&br_hkdf_no_salt) + +#ifndef BR_DOXYGEN_IGNORE +extern const unsigned char br_hkdf_no_salt; +#endif + +/** + * \brief HKDF input injection (HKDF-Extract). + * + * This function injects some more input bytes ("key material") into + * HKDF. This function may be called several times, after `br_hkdf_init()` + * but before `br_hkdf_flip()`. + * + * \param hc HKDF context. + * \param ikm extra input bytes. + * \param ikm_len number of extra input bytes. + */ +void br_hkdf_inject(br_hkdf_context *hc, const void *ikm, size_t ikm_len); + +/** + * \brief HKDF switch to the HKDF-Expand phase. + * + * This call terminates the HKDF-Extract process (input injection), and + * starts the HKDF-Expand process (output production). + * + * \param hc HKDF context. + */ +void br_hkdf_flip(br_hkdf_context *hc); + +/** + * \brief HKDF output production (HKDF-Expand). + * + * Produce more output bytes from the current state. This function may be + * called several times, but only after `br_hkdf_flip()`. + * + * Returned value is the number of actually produced bytes. The total + * output length is limited to 255 times the output length of the + * underlying hash function. + * + * \param hc HKDF context. + * \param info application specific information string. + * \param info_len application specific information string length (in bytes). + * \param out destination buffer for the HKDF output. + * \param out_len the length of the requested output (in bytes). + * \return the produced output length (in bytes). + */ +size_t br_hkdf_produce(br_hkdf_context *hc, + const void *info, size_t info_len, void *out, size_t out_len); + +/** + * \brief SHAKE context. + * + * The HKDF context is initialized with a "security level". The internal + * notion is called "capacity"; the capacity is twice the security level + * (for instance, SHAKE128 has capacity 256). + * + * The caller is responsible for allocating the context where + * appropriate. Context initialisation and usage incurs no dynamic + * allocation, so there is no release function. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + unsigned char dbuf[200]; + size_t dptr; + size_t rate; + uint64_t A[25]; +#endif +} br_shake_context; + +/** + * \brief SHAKE context initialization. + * + * The context is initialized for the provided "security level". + * Internally, this sets the "capacity" to twice the security level; + * thus, for SHAKE128, the `security_level` parameter should be 128, + * which corresponds to a 256-bit capacity. + * + * Allowed security levels are all multiples of 32, from 32 to 768, + * inclusive. Larger security levels imply lower performance; levels + * beyond 256 bits don't make much sense. Standard levels are 128 + * and 256 bits (for SHAKE128 and SHAKE256, respectively). + * + * \param sc SHAKE context to initialise. + * \param security_level security level (in bits). + */ +void br_shake_init(br_shake_context *sc, int security_level); + +/** + * \brief SHAKE input injection. + * + * This function injects some more input bytes ("key material") into + * SHAKE. This function may be called several times, after `br_shake_init()` + * but before `br_shake_flip()`. + * + * \param sc SHAKE context. + * \param data extra input bytes. + * \param len number of extra input bytes. + */ +void br_shake_inject(br_shake_context *sc, const void *data, size_t len); + +/** + * \brief SHAKE switch to production phase. + * + * This call terminates the input injection process, and starts the + * output production process. + * + * \param sc SHAKE context. + */ +void br_shake_flip(br_shake_context *hc); + +/** + * \brief SHAKE output production. + * + * Produce more output bytes from the current state. This function may be + * called several times, but only after `br_shake_flip()`. + * + * There is no practical limit to the number of bytes that may be produced. + * + * \param sc SHAKE context. + * \param out destination buffer for the SHAKE output. + * \param len the length of the requested output (in bytes). + */ +void br_shake_produce(br_shake_context *sc, void *out, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/inc/bearssl_pem.h b/BearSSL-OG/libbearssl/inc/bearssl_pem.h new file mode 100644 index 0000000..d61cc36 --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl_pem.h @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_PEM_H__ +#define BR_BEARSSL_PEM_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_pem.h + * + * # PEM Support + * + * PEM is a traditional encoding layer use to store binary objects (in + * particular X.509 certificates, and private keys) in text files. While + * the acronym comes from an old, defunct standard ("Privacy Enhanced + * Mail"), the format has been reused, with some variations, by many + * systems, and is a _de facto_ standard, even though it is not, actually, + * specified in all clarity anywhere. + * + * ## Format Details + * + * BearSSL contains a generic, streamed PEM decoder, which handles the + * following format: + * + * - The input source (a sequence of bytes) is assumed to be the + * encoding of a text file in an ASCII-compatible charset. This + * includes ISO-8859-1, Windows-1252, and UTF-8 encodings. Each + * line ends on a newline character (U+000A LINE FEED). The + * U+000D CARRIAGE RETURN characters are ignored, so the code + * accepts both Windows-style and Unix-style line endings. + * + * - Each object begins with a banner that occurs at the start of + * a line; the first banner characters are "`-----BEGIN `" (five + * dashes, the word "BEGIN", and a space). The banner matching is + * not case-sensitive. + * + * - The _object name_ consists in the characters that follow the + * banner start sequence, up to the end of the line, but without + * trailing dashes (in "normal" PEM, there are five trailing + * dashes, but this implementation is not picky about these dashes). + * The BearSSL decoder normalises the name characters to uppercase + * (for ASCII letters only) and accepts names up to 127 characters. + * + * - The object ends with a banner that again occurs at the start of + * a line, and starts with "`-----END `" (again case-insensitive). + * + * - Between that start and end banner, only Base64 data shall occur. + * Base64 converts each sequence of three bytes into four + * characters; the four characters are ASCII letters, digits, "`+`" + * or "`-`" signs, and one or two "`=`" signs may occur in the last + * quartet. Whitespace is ignored (whitespace is any ASCII character + * of code 32 or less, so control characters are whitespace) and + * lines may have arbitrary length; the only restriction is that the + * four characters of a quartet must appear on the same line (no + * line break inside a quartet). + * + * - A single file may contain more than one PEM object. Bytes that + * occur between objects are ignored. + * + * + * ## PEM Decoder API + * + * The PEM decoder offers a state-machine API. The caller allocates a + * decoder context, then injects source bytes. Source bytes are pushed + * with `br_pem_decoder_push()`. The decoder stops accepting bytes when + * it reaches an "event", which is either the start of an object, the + * end of an object, or a decoding error within an object. + * + * The `br_pem_decoder_event()` function is used to obtain the current + * event; it also clears it, thus allowing the decoder to accept more + * bytes. When a object start event is raised, the decoder context + * offers the found object name (normalised to ASCII uppercase). + * + * When an object is reached, the caller must set an appropriate callback + * function, which will receive (by chunks) the decoded object data. + * + * Since the decoder context makes no dynamic allocation, it requires + * no explicit deallocation. + */ + +/** + * \brief PEM decoder context. + * + * Contents are opaque (they should not be accessed directly). + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + /* CPU for the T0 virtual machine. */ + struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; + } cpu; + uint32_t dp_stack[32]; + uint32_t rp_stack[32]; + int err; + + const unsigned char *hbuf; + size_t hlen; + + void (*dest)(void *dest_ctx, const void *src, size_t len); + void *dest_ctx; + + unsigned char event; + char name[128]; + unsigned char buf[255]; + size_t ptr; +#endif +} br_pem_decoder_context; + +/** + * \brief Initialise a PEM decoder structure. + * + * \param ctx decoder context to initialise. + */ +void br_pem_decoder_init(br_pem_decoder_context *ctx); + +/** + * \brief Push some bytes into the decoder. + * + * Returned value is the number of bytes actually consumed; this may be + * less than the number of provided bytes if an event is raised. When an + * event is raised, it must be read (with `br_pem_decoder_event()`); + * until the event is read, this function will return 0. + * + * \param ctx decoder context. + * \param data new data bytes. + * \param len number of new data bytes. + * \return the number of bytes actually received (may be less than `len`). + */ +size_t br_pem_decoder_push(br_pem_decoder_context *ctx, + const void *data, size_t len); + +/** + * \brief Set the receiver for decoded data. + * + * When an object is entered, the provided function (with opaque context + * pointer) will be called repeatedly with successive chunks of decoded + * data for that object. If `dest` is set to 0, then decoded data is + * simply ignored. The receiver can be set at any time, but, in practice, + * it should be called immediately after receiving a "start of object" + * event. + * + * \param ctx decoder context. + * \param dest callback for receiving decoded data. + * \param dest_ctx opaque context pointer for the `dest` callback. + */ +static __inline void +br_pem_decoder_setdest(br_pem_decoder_context *ctx, + void (*dest)(void *dest_ctx, const void *src, size_t len), + void *dest_ctx) +{ + ctx->dest = dest; + ctx->dest_ctx = dest_ctx; +} + +/** + * \brief Get the last event. + * + * If an event was raised, then this function returns the event value, and + * also clears it, thereby allowing the decoder to proceed. If no event + * was raised since the last call to `br_pem_decoder_event()`, then this + * function returns 0. + * + * \param ctx decoder context. + * \return the raised event, or 0. + */ +int br_pem_decoder_event(br_pem_decoder_context *ctx); + +/** + * \brief Event: start of object. + * + * This event is raised when the start of a new object has been detected. + * The object name (normalised to uppercase) can be accessed with + * `br_pem_decoder_name()`. + */ +#define BR_PEM_BEGIN_OBJ 1 + +/** + * \brief Event: end of object. + * + * This event is raised when the end of the current object is reached + * (normally, i.e. with no decoding error). + */ +#define BR_PEM_END_OBJ 2 + +/** + * \brief Event: decoding error. + * + * This event is raised when decoding fails within an object. + * This formally closes the current object and brings the decoder back + * to the "out of any object" state. The offending line in the source + * is consumed. + */ +#define BR_PEM_ERROR 3 + +/** + * \brief Get the name of the encountered object. + * + * The encountered object name is defined only when the "start of object" + * event is raised. That name is normalised to uppercase (for ASCII letters + * only) and does not include trailing dashes. + * + * \param ctx decoder context. + * \return the current object name. + */ +static __inline const char * +br_pem_decoder_name(br_pem_decoder_context *ctx) +{ + return ctx->name; +} + +/** + * \brief Encode an object in PEM. + * + * This function encodes the provided binary object (`data`, of length `len` + * bytes) into PEM. The `banner` text will be included in the header and + * footer (e.g. use `"CERTIFICATE"` to get a `"BEGIN CERTIFICATE"` header). + * + * The length (in characters) of the PEM output is returned; that length + * does NOT include the terminating zero, that this function nevertheless + * adds. If using the returned value for allocation purposes, the allocated + * buffer size MUST be at least one byte larger than the returned size. + * + * If `dest` is `NULL`, then the encoding does not happen; however, the + * length of the encoded object is still computed and returned. + * + * The `data` pointer may be `NULL` only if `len` is zero (when encoding + * an object of length zero, which is not very useful), or when `dest` + * is `NULL` (in that case, source data bytes are ignored). + * + * Some `flags` can be specified to alter the encoding behaviour: + * + * - If `BR_PEM_LINE64` is set, then line-breaking will occur after + * every 64 characters of output, instead of the default of 76. + * + * - If `BR_PEM_CRLF` is set, then end-of-line sequence will use + * CR+LF instead of a single LF. + * + * The `data` and `dest` buffers may overlap, in which case the source + * binary data is destroyed in the process. Note that the PEM-encoded output + * is always larger than the source binary. + * + * \param dest the destination buffer (or `NULL`). + * \param data the source buffer (can be `NULL` in some cases). + * \param len the source length (in bytes). + * \param banner the PEM banner expression. + * \param flags the behavioural flags. + * \return the PEM object length (in characters), EXCLUDING the final zero. + */ +size_t br_pem_encode(void *dest, const void *data, size_t len, + const char *banner, unsigned flags); + +/** + * \brief PEM encoding flag: split lines at 64 characters. + */ +#define BR_PEM_LINE64 0x0001 + +/** + * \brief PEM encoding flag: use CR+LF line endings. + */ +#define BR_PEM_CRLF 0x0002 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/inc/bearssl_prf.h b/BearSSL-OG/libbearssl/inc/bearssl_prf.h new file mode 100644 index 0000000..fdf608c --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl_prf.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_PRF_H__ +#define BR_BEARSSL_PRF_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_prf.h + * + * # The TLS PRF + * + * The "PRF" is the pseudorandom function used internally during the + * SSL/TLS handshake, notably to expand negotiated shared secrets into + * the symmetric encryption keys that will be used to process the + * application data. + * + * TLS 1.0 and 1.1 define a PRF that is based on both MD5 and SHA-1. This + * is implemented by the `br_tls10_prf()` function. + * + * TLS 1.2 redefines the PRF, using an explicit hash function. The + * `br_tls12_sha256_prf()` and `br_tls12_sha384_prf()` functions apply that + * PRF with, respectively, SHA-256 and SHA-384. Most standard cipher suites + * rely on the SHA-256 based PRF, but some use SHA-384. + * + * The PRF always uses as input three parameters: a "secret" (some + * bytes), a "label" (ASCII string), and a "seed" (again some bytes). An + * arbitrary output length can be produced. The "seed" is provided as an + * arbitrary number of binary chunks, that gets internally concatenated. + */ + +/** + * \brief Type for a seed chunk. + * + * Each chunk may have an arbitrary length, and may be empty (no byte at + * all). If the chunk length is zero, then the pointer to the chunk data + * may be `NULL`. + */ +typedef struct { + /** + * \brief Pointer to the chunk data. + */ + const void *data; + + /** + * \brief Chunk length (in bytes). + */ + size_t len; +} br_tls_prf_seed_chunk; + +/** + * \brief PRF implementation for TLS 1.0 and 1.1. + * + * This PRF is the one specified by TLS 1.0 and 1.1. It internally uses + * MD5 and SHA-1. + * + * \param dst destination buffer. + * \param len output length (in bytes). + * \param secret secret value (key) for this computation. + * \param secret_len length of "secret" (in bytes). + * \param label PRF label (zero-terminated ASCII string). + * \param seed_num number of seed chunks. + * \param seed seed chnks for this computation (usually non-secret). + */ +void br_tls10_prf(void *dst, size_t len, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed); + +/** + * \brief PRF implementation for TLS 1.2, with SHA-256. + * + * This PRF is the one specified by TLS 1.2, when the underlying hash + * function is SHA-256. + * + * \param dst destination buffer. + * \param len output length (in bytes). + * \param secret secret value (key) for this computation. + * \param secret_len length of "secret" (in bytes). + * \param label PRF label (zero-terminated ASCII string). + * \param seed_num number of seed chunks. + * \param seed seed chnks for this computation (usually non-secret). + */ +void br_tls12_sha256_prf(void *dst, size_t len, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed); + +/** + * \brief PRF implementation for TLS 1.2, with SHA-384. + * + * This PRF is the one specified by TLS 1.2, when the underlying hash + * function is SHA-384. + * + * \param dst destination buffer. + * \param len output length (in bytes). + * \param secret secret value (key) for this computation. + * \param secret_len length of "secret" (in bytes). + * \param label PRF label (zero-terminated ASCII string). + * \param seed_num number of seed chunks. + * \param seed seed chnks for this computation (usually non-secret). + */ +void br_tls12_sha384_prf(void *dst, size_t len, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed); + +/** + * brief A convenient type name for a PRF implementation. + * + * \param dst destination buffer. + * \param len output length (in bytes). + * \param secret secret value (key) for this computation. + * \param secret_len length of "secret" (in bytes). + * \param label PRF label (zero-terminated ASCII string). + * \param seed_num number of seed chunks. + * \param seed seed chnks for this computation (usually non-secret). + */ +typedef void (*br_tls_prf_impl)(void *dst, size_t len, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/inc/bearssl_rand.h b/BearSSL-OG/libbearssl/inc/bearssl_rand.h new file mode 100644 index 0000000..e338d8f --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl_rand.h @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_RAND_H__ +#define BR_BEARSSL_RAND_H__ + +#include +#include + +#include "bearssl_block.h" +#include "bearssl_hash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_rand.h + * + * # Pseudo-Random Generators + * + * A PRNG is a state-based engine that outputs pseudo-random bytes on + * demand. It is initialized with an initial seed, and additional seed + * bytes can be added afterwards. Bytes produced depend on the seeds and + * also on the exact sequence of calls (including sizes requested for + * each call). + * + * + * ## Procedural and OOP API + * + * For the PRNG of name "`xxx`", two API are provided. The _procedural_ + * API defined a context structure `br_xxx_context` and three functions: + * + * - `br_xxx_init()` + * + * Initialise the context with an initial seed. + * + * - `br_xxx_generate()` + * + * Produce some pseudo-random bytes. + * + * - `br_xxx_update()` + * + * Inject some additional seed. + * + * The initialisation function sets the first context field (`vtable`) + * to a pointer to the vtable that supports the OOP API. The OOP API + * provides access to the same functions through function pointers, + * named `init()`, `generate()` and `update()`. + * + * Note that the context initialisation method may accept additional + * parameters, provided as a 'const void *' pointer at API level. These + * additional parameters depend on the implemented PRNG. + * + * + * ## HMAC_DRBG + * + * HMAC_DRBG is defined in [NIST SP 800-90A Revision + * 1](http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf). + * It uses HMAC repeatedly, over some configurable underlying hash + * function. In BearSSL, it is implemented under the "`hmac_drbg`" name. + * The "extra parameters" pointer for context initialisation should be + * set to a pointer to the vtable for the underlying hash function (e.g. + * pointer to `br_sha256_vtable` to use HMAC_DRBG with SHA-256). + * + * According to the NIST standard, each request shall produce up to + * 219 bits (i.e. 64 kB of data); moreover, the context shall + * be reseeded at least once every 248 requests. This + * implementation does not maintain the reseed counter (the threshold is + * too high to be reached in practice) and does not object to producing + * more than 64 kB in a single request; thus, the code cannot fail, + * which corresponds to the fact that the API has no room for error + * codes. However, this implies that requesting more than 64 kB in one + * `generate()` request, or making more than 248 requests + * without reseeding, is formally out of NIST specification. There is + * no currently known security penalty for exceeding the NIST limits, + * and, in any case, HMAC_DRBG usage in implementing SSL/TLS always + * stays much below these thresholds. + * + * + * ## AESCTR_DRBG + * + * AESCTR_DRBG is a custom PRNG based on AES-128 in CTR mode. This is + * meant to be used only in situations where you are desperate for + * speed, and have an hardware-optimized AES/CTR implementation. Whether + * this will yield perceptible improvements depends on what you use the + * pseudorandom bytes for, and how many you want; for instance, RSA key + * pair generation uses a substantial amount of randomness, and using + * AESCTR_DRBG instead of HMAC_DRBG yields a 15 to 20% increase in key + * generation speed on a recent x86 CPU (Intel Core i7-6567U at 3.30 GHz). + * + * Internally, it uses CTR mode with successive counter values, starting + * at zero (counter value expressed over 128 bits, big-endian convention). + * The counter is not allowed to reach 32768; thus, every 32768*16 bytes + * at most, the `update()` function is run (on an empty seed, if none is + * provided). The `update()` function computes the new AES-128 key by + * applying a custom hash function to the concatenation of a state-dependent + * word (encryption of an all-one block with the current key) and the new + * seed. The custom hash function uses Hirose's construction over AES-256; + * see the comments in `aesctr_drbg.c` for details. + * + * This DRBG does not follow an existing standard, and thus should be + * considered as inadequate for production use until it has been properly + * analysed. + */ + +/** + * \brief Class type for PRNG implementations. + * + * A `br_prng_class` instance references the methods implementing a PRNG. + * Constant instances of this structure are defined for each implemented + * PRNG. Such instances are also called "vtables". + */ +typedef struct br_prng_class_ br_prng_class; +struct br_prng_class_ { + /** + * \brief Size (in bytes) of the context structure appropriate for + * running this PRNG. + */ + size_t context_size; + + /** + * \brief Initialisation method. + * + * The context to initialise is provided as a pointer to its + * first field (the vtable pointer); this function sets that + * first field to a pointer to the vtable. + * + * The extra parameters depend on the implementation; each + * implementation defines what kind of extra parameters it + * expects (if any). + * + * Requirements on the initial seed depend on the implemented + * PRNG. + * + * \param ctx PRNG context to initialise. + * \param params extra parameters for the PRNG. + * \param seed initial seed. + * \param seed_len initial seed length (in bytes). + */ + void (*init)(const br_prng_class **ctx, const void *params, + const void *seed, size_t seed_len); + + /** + * \brief Random bytes generation. + * + * This method produces `len` pseudorandom bytes, in the `out` + * buffer. The context is updated accordingly. + * + * \param ctx PRNG context. + * \param out output buffer. + * \param len number of pseudorandom bytes to produce. + */ + void (*generate)(const br_prng_class **ctx, void *out, size_t len); + + /** + * \brief Inject additional seed bytes. + * + * The provided seed bytes are added into the PRNG internal + * entropy pool. + * + * \param ctx PRNG context. + * \param seed additional seed. + * \param seed_len additional seed length (in bytes). + */ + void (*update)(const br_prng_class **ctx, + const void *seed, size_t seed_len); +}; + +/** + * \brief Context for HMAC_DRBG. + * + * The context contents are opaque, except the first field, which + * supports OOP. + */ +typedef struct { + /** + * \brief Pointer to the vtable. + * + * This field is set with the initialisation method/function. + */ + const br_prng_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char K[64]; + unsigned char V[64]; + const br_hash_class *digest_class; +#endif +} br_hmac_drbg_context; + +/** + * \brief Statically allocated, constant vtable for HMAC_DRBG. + */ +extern const br_prng_class br_hmac_drbg_vtable; + +/** + * \brief HMAC_DRBG initialisation. + * + * The context to initialise is provided as a pointer to its first field + * (the vtable pointer); this function sets that first field to a + * pointer to the vtable. + * + * The `seed` value is what is called, in NIST terminology, the + * concatenation of the "seed", "nonce" and "personalization string", in + * that order. + * + * The `digest_class` parameter defines the underlying hash function. + * Formally, the NIST standard specifies that the hash function shall + * be only SHA-1 or one of the SHA-2 functions. This implementation also + * works with any other implemented hash function (such as MD5), but + * this is non-standard and therefore not recommended. + * + * \param ctx HMAC_DRBG context to initialise. + * \param digest_class vtable for the underlying hash function. + * \param seed initial seed. + * \param seed_len initial seed length (in bytes). + */ +void br_hmac_drbg_init(br_hmac_drbg_context *ctx, + const br_hash_class *digest_class, const void *seed, size_t seed_len); + +/** + * \brief Random bytes generation with HMAC_DRBG. + * + * This method produces `len` pseudorandom bytes, in the `out` + * buffer. The context is updated accordingly. Formally, requesting + * more than 65536 bytes in one request falls out of specification + * limits (but it won't fail). + * + * \param ctx HMAC_DRBG context. + * \param out output buffer. + * \param len number of pseudorandom bytes to produce. + */ +void br_hmac_drbg_generate(br_hmac_drbg_context *ctx, void *out, size_t len); + +/** + * \brief Inject additional seed bytes in HMAC_DRBG. + * + * The provided seed bytes are added into the HMAC_DRBG internal + * entropy pool. The process does not _replace_ existing entropy, + * thus pushing non-random bytes (i.e. bytes which are known to the + * attackers) does not degrade the overall quality of generated bytes. + * + * \param ctx HMAC_DRBG context. + * \param seed additional seed. + * \param seed_len additional seed length (in bytes). + */ +void br_hmac_drbg_update(br_hmac_drbg_context *ctx, + const void *seed, size_t seed_len); + +/** + * \brief Get the hash function implementation used by a given instance of + * HMAC_DRBG. + * + * This calls MUST NOT be performed on a context which was not + * previously initialised. + * + * \param ctx HMAC_DRBG context. + * \return the hash function vtable. + */ +static __inline const br_hash_class * +br_hmac_drbg_get_hash(const br_hmac_drbg_context *ctx) +{ + return ctx->digest_class; +} + +/** + * \brief Type for a provider of entropy seeds. + * + * A "seeder" is a function that is able to obtain random values from + * some source and inject them as entropy seed in a PRNG. A seeder + * shall guarantee that the total entropy of the injected seed is large + * enough to seed a PRNG for purposes of cryptographic key generation + * (i.e. at least 128 bits). + * + * A seeder may report a failure to obtain adequate entropy. Seeders + * shall endeavour to fix themselves transient errors by trying again; + * thus, callers may consider reported errors as permanent. + * + * \param ctx PRNG context to seed. + * \return 1 on success, 0 on error. + */ +typedef int (*br_prng_seeder)(const br_prng_class **ctx); + +/** + * \brief Get a seeder backed by the operating system or hardware. + * + * Get a seeder that feeds on RNG facilities provided by the current + * operating system or hardware. If no such facility is known, then 0 + * is returned. + * + * If `name` is not `NULL`, then `*name` is set to a symbolic string + * that identifies the seeder implementation. If no seeder is returned + * and `name` is not `NULL`, then `*name` is set to a pointer to the + * constant string `"none"`. + * + * \param name receiver for seeder name, or `NULL`. + * \return the system seeder, if available, or 0. + */ +br_prng_seeder br_prng_seeder_system(const char **name); + +/** + * \brief Context for AESCTR_DRBG. + * + * The context contents are opaque, except the first field, which + * supports OOP. + */ +typedef struct { + /** + * \brief Pointer to the vtable. + * + * This field is set with the initialisation method/function. + */ + const br_prng_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + br_aes_gen_ctr_keys sk; + uint32_t cc; +#endif +} br_aesctr_drbg_context; + +/** + * \brief Statically allocated, constant vtable for AESCTR_DRBG. + */ +extern const br_prng_class br_aesctr_drbg_vtable; + +/** + * \brief AESCTR_DRBG initialisation. + * + * The context to initialise is provided as a pointer to its first field + * (the vtable pointer); this function sets that first field to a + * pointer to the vtable. + * + * The internal AES key is first set to the all-zero key; then, the + * `br_aesctr_drbg_update()` function is called with the provided `seed`. + * The call is performed even if the seed length (`seed_len`) is zero. + * + * The `aesctr` parameter defines the underlying AES/CTR implementation. + * + * \param ctx AESCTR_DRBG context to initialise. + * \param aesctr vtable for the AES/CTR implementation. + * \param seed initial seed (can be `NULL` if `seed_len` is zero). + * \param seed_len initial seed length (in bytes). + */ +void br_aesctr_drbg_init(br_aesctr_drbg_context *ctx, + const br_block_ctr_class *aesctr, const void *seed, size_t seed_len); + +/** + * \brief Random bytes generation with AESCTR_DRBG. + * + * This method produces `len` pseudorandom bytes, in the `out` + * buffer. The context is updated accordingly. + * + * \param ctx AESCTR_DRBG context. + * \param out output buffer. + * \param len number of pseudorandom bytes to produce. + */ +void br_aesctr_drbg_generate(br_aesctr_drbg_context *ctx, + void *out, size_t len); + +/** + * \brief Inject additional seed bytes in AESCTR_DRBG. + * + * The provided seed bytes are added into the AESCTR_DRBG internal + * entropy pool. The process does not _replace_ existing entropy, + * thus pushing non-random bytes (i.e. bytes which are known to the + * attackers) does not degrade the overall quality of generated bytes. + * + * \param ctx AESCTR_DRBG context. + * \param seed additional seed. + * \param seed_len additional seed length (in bytes). + */ +void br_aesctr_drbg_update(br_aesctr_drbg_context *ctx, + const void *seed, size_t seed_len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/inc/bearssl_rsa.h b/BearSSL-OG/libbearssl/inc/bearssl_rsa.h new file mode 100644 index 0000000..0a069fd --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl_rsa.h @@ -0,0 +1,1655 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_RSA_H__ +#define BR_BEARSSL_RSA_H__ + +#include +#include + +#include "bearssl_hash.h" +#include "bearssl_rand.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_rsa.h + * + * # RSA + * + * This file documents the RSA implementations provided with BearSSL. + * Note that the SSL engine accesses these implementations through a + * configurable API, so it is possible to, for instance, run a SSL + * server which uses a RSA engine which is not based on this code. + * + * ## Key Elements + * + * RSA public and private keys consist in lists of big integers. All + * such integers are represented with big-endian unsigned notation: + * first byte is the most significant, and the value is positive (so + * there is no dedicated "sign bit"). Public and private key structures + * thus contain, for each such integer, a pointer to the first value byte + * (`unsigned char *`), and a length (`size_t`) which is the number of + * relevant bytes. As a general rule, minimal-length encoding is not + * enforced: values may have extra leading bytes of value 0. + * + * RSA public keys consist in two integers: + * + * - the modulus (`n`); + * - the public exponent (`e`). + * + * RSA private keys, as defined in + * [PKCS#1](https://tools.ietf.org/html/rfc3447), contain eight integers: + * + * - the modulus (`n`); + * - the public exponent (`e`); + * - the private exponent (`d`); + * - the first prime factor (`p`); + * - the second prime factor (`q`); + * - the first reduced exponent (`dp`, which is `d` modulo `p-1`); + * - the second reduced exponent (`dq`, which is `d` modulo `q-1`); + * - the CRT coefficient (`iq`, the inverse of `q` modulo `p`). + * + * However, the implementations defined in BearSSL use only five of + * these integers: `p`, `q`, `dp`, `dq` and `iq`. + * + * ## Security Features and Limitations + * + * The implementations contained in BearSSL have the following limitations + * and features: + * + * - They are constant-time. This means that the execution time and + * memory access pattern may depend on the _lengths_ of the private + * key components, but not on their value, nor on the value of + * the operand. Note that this property is not achieved through + * random masking, but "true" constant-time code. + * + * - They support only private keys with two prime factors. RSA private + * keys with three or more prime factors are nominally supported, but + * rarely used; they may offer faster operations, at the expense of + * more code and potentially a reduction in security if there are + * "too many" prime factors. + * + * - The public exponent may have arbitrary length. Of course, it is + * a good idea to keep public exponents small, so that public key + * operations are fast; but, contrary to some widely deployed + * implementations, BearSSL has no problem with public exponents + * longer than 32 bits. + * + * - The two prime factors of the modulus need not have the same length + * (but severely imbalanced factor lengths might reduce security). + * Similarly, there is no requirement that the first factor (`p`) + * be greater than the second factor (`q`). + * + * - Prime factors and modulus must be smaller than a compile-time limit. + * This is made necessary by the use of fixed-size stack buffers, and + * the limit has been adjusted to keep stack usage under 2 kB for the + * RSA operations. Currently, the maximum modulus size is 4096 bits, + * and the maximum prime factor size is 2080 bits. + * + * - The RSA functions themselves do not enforce lower size limits, + * except that which is absolutely necessary for the operation to + * mathematically make sense (e.g. a PKCS#1 v1.5 signature with + * SHA-1 requires a modulus of at least 361 bits). It is up to users + * of this code to enforce size limitations when appropriate (e.g. + * the X.509 validation engine, by default, rejects RSA keys of + * less than 1017 bits). + * + * - Within the size constraints expressed above, arbitrary bit lengths + * are supported. There is no requirement that prime factors or + * modulus have a size multiple of 8 or 16. + * + * - When verifying PKCS#1 v1.5 signatures, both variants of the hash + * function identifying header (with and without the ASN.1 NULL) are + * supported. When producing such signatures, the variant with the + * ASN.1 NULL is used. + * + * ## Implementations + * + * Three RSA implementations are included: + * + * - The **i32** implementation internally represents big integers + * as arrays of 32-bit integers. It is perfunctory and portable, + * but not very efficient. + * + * - The **i31** implementation uses 32-bit integers, each containing + * 31 bits worth of integer data. The i31 implementation is somewhat + * faster than the i32 implementation (the reduced integer size makes + * carry propagation easier) for a similar code footprint, but uses + * very slightly larger stack buffers (about 4% bigger). + * + * - The **i62** implementation is similar to the i31 implementation, + * except that it internally leverages the 64x64->128 multiplication + * opcode. This implementation is available only on architectures + * where such an opcode exists. It is much faster than i31. + * + * - The **i15** implementation uses 16-bit integers, each containing + * 15 bits worth of integer data. Multiplication results fit on + * 32 bits, so this won't use the "widening" multiplication routine + * on ARM Cortex M0/M0+, for much better performance and constant-time + * execution. + */ + +/** + * \brief RSA public key. + * + * The structure references the modulus and the public exponent. Both + * integers use unsigned big-endian representation; extra leading bytes + * of value 0 are allowed. + */ +typedef struct { + /** \brief Modulus. */ + unsigned char *n; + /** \brief Modulus length (in bytes). */ + size_t nlen; + /** \brief Public exponent. */ + unsigned char *e; + /** \brief Public exponent length (in bytes). */ + size_t elen; +} br_rsa_public_key; + +/** + * \brief RSA private key. + * + * The structure references the private factors, reduced private + * exponents, and CRT coefficient. It also contains the bit length of + * the modulus. The big integers use unsigned big-endian representation; + * extra leading bytes of value 0 are allowed. However, the modulus bit + * length (`n_bitlen`) MUST be exact. + */ +typedef struct { + /** \brief Modulus bit length (in bits, exact value). */ + uint32_t n_bitlen; + /** \brief First prime factor. */ + unsigned char *p; + /** \brief First prime factor length (in bytes). */ + size_t plen; + /** \brief Second prime factor. */ + unsigned char *q; + /** \brief Second prime factor length (in bytes). */ + size_t qlen; + /** \brief First reduced private exponent. */ + unsigned char *dp; + /** \brief First reduced private exponent length (in bytes). */ + size_t dplen; + /** \brief Second reduced private exponent. */ + unsigned char *dq; + /** \brief Second reduced private exponent length (in bytes). */ + size_t dqlen; + /** \brief CRT coefficient. */ + unsigned char *iq; + /** \brief CRT coefficient length (in bytes). */ + size_t iqlen; +} br_rsa_private_key; + +/** + * \brief Type for a RSA public key engine. + * + * The public key engine performs the modular exponentiation of the + * provided value with the public exponent. The value is modified in + * place. + * + * The value length (`xlen`) is verified to have _exactly_ the same + * length as the modulus (actual modulus length, without extra leading + * zeros in the modulus representation in memory). If the length does + * not match, then this function returns 0 and `x[]` is unmodified. + * + * It `xlen` is correct, then `x[]` is modified. Returned value is 1 + * on success, 0 on error. Error conditions include an oversized `x[]` + * (the array has the same length as the modulus, but the numerical value + * is not lower than the modulus) and an invalid modulus (e.g. an even + * integer). If an error is reported, then the new contents of `x[]` are + * unspecified. + * + * \param x operand to exponentiate. + * \param xlen length of the operand (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_public)(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk); + +/** + * \brief Type for a RSA signature verification engine (PKCS#1 v1.5). + * + * Parameters are: + * + * - The signature itself. The provided array is NOT modified. + * + * - The encoded OID for the hash function. The provided array must begin + * with a single byte that contains the length of the OID value (in + * bytes), followed by exactly that many bytes. This parameter may + * also be `NULL`, in which case the raw hash value should be used + * with the PKCS#1 v1.5 "type 1" padding (as used in SSL/TLS up + * to TLS-1.1, with a 36-byte hash value). + * + * - The hash output length, in bytes. + * + * - The public key. + * + * - An output buffer for the hash value. The caller must still compare + * it with the hash of the data over which the signature is computed. + * + * **Constraints:** + * + * - Hash length MUST be no more than 64 bytes. + * + * - OID value length MUST be no more than 32 bytes (i.e. `hash_oid[0]` + * must have a value in the 0..32 range, inclusive). + * + * This function verifies that the signature length (`xlen`) matches the + * modulus length (this function returns 0 on mismatch). If the modulus + * size exceeds the maximum supported RSA size, then the function also + * returns 0. + * + * Returned value is 1 on success, 0 on error. + * + * Implementations of this type need not be constant-time. + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash_len expected hash value length (in bytes). + * \param pk RSA public key. + * \param hash_out output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_pkcs1_vrfy)(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out); + +/** + * \brief Type for a RSA signature verification engine (PSS). + * + * Parameters are: + * + * - The signature itself. The provided array is NOT modified. + * + * - The hash function which was used to hash the message. + * + * - The hash function to use with MGF1 within the PSS padding. This + * is not necessarily the same hash function as the one which was + * used to hash the signed message. + * + * - The hashed message (as an array of bytes). + * + * - The PSS salt length (in bytes). + * + * - The public key. + * + * **Constraints:** + * + * - Hash message length MUST be no more than 64 bytes. + * + * Note that, contrary to PKCS#1 v1.5 signature, the hash value of the + * signed data cannot be extracted from the signature; it must be + * provided to the verification function. + * + * This function verifies that the signature length (`xlen`) matches the + * modulus length (this function returns 0 on mismatch). If the modulus + * size exceeds the maximum supported RSA size, then the function also + * returns 0. + * + * Returned value is 1 on success, 0 on error. + * + * Implementations of this type need not be constant-time. + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hf_data hash function applied on the message. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hash value of the signed message. + * \param salt_len PSS salt length (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_pss_vrfy)(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk); + +/** + * \brief Type for a RSA encryption engine (OAEP). + * + * Parameters are: + * + * - A source of random bytes. The source must be already initialized. + * + * - A hash function, used internally with the mask generation function + * (MGF1). + * + * - A label. The `label` pointer may be `NULL` if `label_len` is zero + * (an empty label, which is the default in PKCS#1 v2.2). + * + * - The public key. + * + * - The destination buffer. Its maximum length (in bytes) is provided; + * if that length is lower than the public key length, then an error + * is reported. + * + * - The source message. + * + * The encrypted message output has exactly the same length as the modulus + * (mathematical length, in bytes, not counting extra leading zeros in the + * modulus representation in the public key). + * + * The source message (`src`, length `src_len`) may overlap with the + * destination buffer (`dst`, length `dst_max_len`). + * + * This function returns the actual encrypted message length, in bytes; + * on error, zero is returned. An error is reported if the output buffer + * is not large enough, or the public is invalid, or the public key + * modulus exceeds the maximum supported RSA size. + * + * \param rnd source of random bytes. + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param pk RSA public key. + * \param dst destination buffer. + * \param dst_max_len destination buffer length (maximum encrypted data size). + * \param src message to encrypt. + * \param src_len source message length (in bytes). + * \return encrypted message length (in bytes), or 0 on error. + */ +typedef size_t (*br_rsa_oaep_encrypt)( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len); + +/** + * \brief Type for a RSA private key engine. + * + * The `x[]` buffer is modified in place, and its length is inferred from + * the modulus length (`x[]` is assumed to have a length of + * `(sk->n_bitlen+7)/8` bytes). + * + * Returned value is 1 on success, 0 on error. + * + * \param x operand to exponentiate. + * \param sk RSA private key. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_private)(unsigned char *x, + const br_rsa_private_key *sk); + +/** + * \brief Type for a RSA signature generation engine (PKCS#1 v1.5). + * + * Parameters are: + * + * - The encoded OID for the hash function. The provided array must begin + * with a single byte that contains the length of the OID value (in + * bytes), followed by exactly that many bytes. This parameter may + * also be `NULL`, in which case the raw hash value should be used + * with the PKCS#1 v1.5 "type 1" padding (as used in SSL/TLS up + * to TLS-1.1, with a 36-byte hash value). + * + * - The hash value computes over the data to sign (its length is + * expressed in bytes). + * + * - The RSA private key. + * + * - The output buffer, that receives the signature. + * + * Returned value is 1 on success, 0 on error. Error conditions include + * a too small modulus for the provided hash OID and value, or some + * invalid key parameters. The signature length is exactly + * `(sk->n_bitlen+7)/8` bytes. + * + * This function is expected to be constant-time with regards to the + * private key bytes (lengths of the modulus and the individual factors + * may leak, though) and to the hashed data. + * + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash hash value. + * \param hash_len hash value length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the signature value. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_pkcs1_sign)(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief Type for a RSA signature generation engine (PSS). + * + * Parameters are: + * + * - An initialized PRNG for salt generation. If the salt length is + * zero (`salt_len` parameter), then the PRNG is optional (this is + * not the typical case, as the security proof of RSA/PSS is + * tighter when a non-empty salt is used). + * + * - The hash function which was used to hash the message. + * + * - The hash function to use with MGF1 within the PSS padding. This + * is not necessarily the same function as the one used to hash the + * message. + * + * - The hashed message. + * + * - The salt length, in bytes. + * + * - The RSA private key. + * + * - The output buffer, that receives the signature. + * + * Returned value is 1 on success, 0 on error. Error conditions include + * a too small modulus for the provided hash and salt lengths, or some + * invalid key parameters. The signature length is exactly + * `(sk->n_bitlen+7)/8` bytes. + * + * This function is expected to be constant-time with regards to the + * private key bytes (lengths of the modulus and the individual factors + * may leak, though) and to the hashed data. + * + * \param rng PRNG for salt generation (`NULL` if `salt_len` is zero). + * \param hf_data hash function used to hash the signed data. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hashed message. + * \param salt_len salt length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the signature value. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_pss_sign)(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash_value, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief Encoded OID for SHA-1 (in RSA PKCS#1 signatures). + */ +#define BR_HASH_OID_SHA1 \ + ((const unsigned char *)"\x05\x2B\x0E\x03\x02\x1A") + +/** + * \brief Encoded OID for SHA-224 (in RSA PKCS#1 signatures). + */ +#define BR_HASH_OID_SHA224 \ + ((const unsigned char *)"\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04") + +/** + * \brief Encoded OID for SHA-256 (in RSA PKCS#1 signatures). + */ +#define BR_HASH_OID_SHA256 \ + ((const unsigned char *)"\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01") + +/** + * \brief Encoded OID for SHA-384 (in RSA PKCS#1 signatures). + */ +#define BR_HASH_OID_SHA384 \ + ((const unsigned char *)"\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02") + +/** + * \brief Encoded OID for SHA-512 (in RSA PKCS#1 signatures). + */ +#define BR_HASH_OID_SHA512 \ + ((const unsigned char *)"\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03") + +/** + * \brief Type for a RSA decryption engine (OAEP). + * + * Parameters are: + * + * - A hash function, used internally with the mask generation function + * (MGF1). + * + * - A label. The `label` pointer may be `NULL` if `label_len` is zero + * (an empty label, which is the default in PKCS#1 v2.2). + * + * - The private key. + * + * - The source and destination buffer. The buffer initially contains + * the encrypted message; the buffer contents are altered, and the + * decrypted message is written at the start of that buffer + * (decrypted message is always shorter than the encrypted message). + * + * If decryption fails in any way, then `*len` is unmodified, and the + * function returns 0. Otherwise, `*len` is set to the decrypted message + * length, and 1 is returned. The implementation is responsible for + * checking that the input message length matches the key modulus length, + * and that the padding is correct. + * + * Implementations MUST use constant-time check of the validity of the + * OAEP padding, at least until the leading byte and hash value have + * been checked. Whether overall decryption worked, and the length of + * the decrypted message, may leak. + * + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param sk RSA private key. + * \param data input/output buffer. + * \param len encrypted/decrypted message length. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_oaep_decrypt)( + const br_hash_class *dig, const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len); + +/* + * RSA "i32" engine. Integers are internally represented as arrays of + * 32-bit integers, and the core multiplication primitive is the + * 32x32->64 multiplication. + */ + +/** + * \brief RSA public key engine "i32". + * + * \see br_rsa_public + * + * \param x operand to exponentiate. + * \param xlen length of the operand (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_public(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk); + +/** + * \brief RSA signature verification engine "i32" (PKCS#1 v1.5 signatures). + * + * \see br_rsa_pkcs1_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash_len expected hash value length (in bytes). + * \param pk RSA public key. + * \param hash_out output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_pkcs1_vrfy(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out); + +/** + * \brief RSA signature verification engine "i32" (PSS signatures). + * + * \see br_rsa_pss_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hf_data hash function applied on the message. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hash value of the signed message. + * \param salt_len PSS salt length (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_pss_vrfy(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk); + +/** + * \brief RSA private key engine "i32". + * + * \see br_rsa_private + * + * \param x operand to exponentiate. + * \param sk RSA private key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_private(unsigned char *x, + const br_rsa_private_key *sk); + +/** + * \brief RSA signature generation engine "i32" (PKCS#1 v1.5 signatures). + * + * \see br_rsa_pkcs1_sign + * + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash hash value. + * \param hash_len hash value length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_pkcs1_sign(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief RSA signature generation engine "i32" (PSS signatures). + * + * \see br_rsa_pss_sign + * + * \param rng PRNG for salt generation (`NULL` if `salt_len` is zero). + * \param hf_data hash function used to hash the signed data. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hashed message. + * \param salt_len salt length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the signature value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_pss_sign(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash_value, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x); + +/* + * RSA "i31" engine. Similar to i32, but only 31 bits are used per 32-bit + * word. This uses slightly more stack space (about 4% more) and code + * space, but it quite faster. + */ + +/** + * \brief RSA public key engine "i31". + * + * \see br_rsa_public + * + * \param x operand to exponentiate. + * \param xlen length of the operand (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_public(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk); + +/** + * \brief RSA signature verification engine "i31" (PKCS#1 v1.5 signatures). + * + * \see br_rsa_pkcs1_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash_len expected hash value length (in bytes). + * \param pk RSA public key. + * \param hash_out output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_pkcs1_vrfy(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out); + +/** + * \brief RSA signature verification engine "i31" (PSS signatures). + * + * \see br_rsa_pss_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hf_data hash function applied on the message. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hash value of the signed message. + * \param salt_len PSS salt length (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_pss_vrfy(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk); + +/** + * \brief RSA private key engine "i31". + * + * \see br_rsa_private + * + * \param x operand to exponentiate. + * \param sk RSA private key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_private(unsigned char *x, + const br_rsa_private_key *sk); + +/** + * \brief RSA signature generation engine "i31" (PKCS#1 v1.5 signatures). + * + * \see br_rsa_pkcs1_sign + * + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash hash value. + * \param hash_len hash value length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_pkcs1_sign(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief RSA signature generation engine "i31" (PSS signatures). + * + * \see br_rsa_pss_sign + * + * \param rng PRNG for salt generation (`NULL` if `salt_len` is zero). + * \param hf_data hash function used to hash the signed data. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hashed message. + * \param salt_len salt length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the signature value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_pss_sign(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash_value, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x); + +/* + * RSA "i62" engine. Similar to i31, but internal multiplication use + * 64x64->128 multiplications. This is available only on architecture + * that offer such an opcode. + */ + +/** + * \brief RSA public key engine "i62". + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_public_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_public + * + * \param x operand to exponentiate. + * \param xlen length of the operand (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_public(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk); + +/** + * \brief RSA signature verification engine "i62" (PKCS#1 v1.5 signatures). + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_pkcs1_vrfy_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_pkcs1_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash_len expected hash value length (in bytes). + * \param pk RSA public key. + * \param hash_out output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_pkcs1_vrfy(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out); + +/** + * \brief RSA signature verification engine "i62" (PSS signatures). + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_pss_vrfy_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_pss_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hf_data hash function applied on the message. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hash value of the signed message. + * \param salt_len PSS salt length (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_pss_vrfy(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk); + +/** + * \brief RSA private key engine "i62". + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_private_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_private + * + * \param x operand to exponentiate. + * \param sk RSA private key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_private(unsigned char *x, + const br_rsa_private_key *sk); + +/** + * \brief RSA signature generation engine "i62" (PKCS#1 v1.5 signatures). + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_pkcs1_sign_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_pkcs1_sign + * + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash hash value. + * \param hash_len hash value length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_pkcs1_sign(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief RSA signature generation engine "i62" (PSS signatures). + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_pss_sign_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_pss_sign + * + * \param rng PRNG for salt generation (`NULL` if `salt_len` is zero). + * \param hf_data hash function used to hash the signed data. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hashed message. + * \param salt_len salt length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the signature value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_pss_sign(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash_value, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief Get the RSA "i62" implementation (public key operations), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_public br_rsa_i62_public_get(void); + +/** + * \brief Get the RSA "i62" implementation (PKCS#1 v1.5 signature verification), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_pkcs1_vrfy br_rsa_i62_pkcs1_vrfy_get(void); + +/** + * \brief Get the RSA "i62" implementation (PSS signature verification), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_pss_vrfy br_rsa_i62_pss_vrfy_get(void); + +/** + * \brief Get the RSA "i62" implementation (private key operations), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_private br_rsa_i62_private_get(void); + +/** + * \brief Get the RSA "i62" implementation (PKCS#1 v1.5 signature generation), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_pkcs1_sign br_rsa_i62_pkcs1_sign_get(void); + +/** + * \brief Get the RSA "i62" implementation (PSS signature generation), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_pss_sign br_rsa_i62_pss_sign_get(void); + +/** + * \brief Get the RSA "i62" implementation (OAEP encryption), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_oaep_encrypt br_rsa_i62_oaep_encrypt_get(void); + +/** + * \brief Get the RSA "i62" implementation (OAEP decryption), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_oaep_decrypt br_rsa_i62_oaep_decrypt_get(void); + +/* + * RSA "i15" engine. Integers are represented as 15-bit integers, so + * the code uses only 32-bit multiplication (no 64-bit result), which + * is vastly faster (and constant-time) on the ARM Cortex M0/M0+. + */ + +/** + * \brief RSA public key engine "i15". + * + * \see br_rsa_public + * + * \param x operand to exponentiate. + * \param xlen length of the operand (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_public(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk); + +/** + * \brief RSA signature verification engine "i15" (PKCS#1 v1.5 signatures). + * + * \see br_rsa_pkcs1_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash_len expected hash value length (in bytes). + * \param pk RSA public key. + * \param hash_out output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_pkcs1_vrfy(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out); + +/** + * \brief RSA signature verification engine "i15" (PSS signatures). + * + * \see br_rsa_pss_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hf_data hash function applied on the message. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hash value of the signed message. + * \param salt_len PSS salt length (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_pss_vrfy(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk); + +/** + * \brief RSA private key engine "i15". + * + * \see br_rsa_private + * + * \param x operand to exponentiate. + * \param sk RSA private key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_private(unsigned char *x, + const br_rsa_private_key *sk); + +/** + * \brief RSA signature generation engine "i15" (PKCS#1 v1.5 signatures). + * + * \see br_rsa_pkcs1_sign + * + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash hash value. + * \param hash_len hash value length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_pkcs1_sign(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief RSA signature generation engine "i15" (PSS signatures). + * + * \see br_rsa_pss_sign + * + * \param rng PRNG for salt generation (`NULL` if `salt_len` is zero). + * \param hf_data hash function used to hash the signed data. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hashed message. + * \param salt_len salt length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the signature value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_pss_sign(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash_value, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief Get "default" RSA implementation (public-key operations). + * + * This returns the preferred implementation of RSA (public-key operations) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_public br_rsa_public_get_default(void); + +/** + * \brief Get "default" RSA implementation (private-key operations). + * + * This returns the preferred implementation of RSA (private-key operations) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_private br_rsa_private_get_default(void); + +/** + * \brief Get "default" RSA implementation (PKCS#1 v1.5 signature verification). + * + * This returns the preferred implementation of RSA (signature verification) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_pkcs1_vrfy br_rsa_pkcs1_vrfy_get_default(void); + +/** + * \brief Get "default" RSA implementation (PSS signature verification). + * + * This returns the preferred implementation of RSA (signature verification) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_pss_vrfy br_rsa_pss_vrfy_get_default(void); + +/** + * \brief Get "default" RSA implementation (PKCS#1 v1.5 signature generation). + * + * This returns the preferred implementation of RSA (signature generation) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_pkcs1_sign br_rsa_pkcs1_sign_get_default(void); + +/** + * \brief Get "default" RSA implementation (PSS signature generation). + * + * This returns the preferred implementation of RSA (signature generation) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_pss_sign br_rsa_pss_sign_get_default(void); + +/** + * \brief Get "default" RSA implementation (OAEP encryption). + * + * This returns the preferred implementation of RSA (OAEP encryption) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_oaep_encrypt br_rsa_oaep_encrypt_get_default(void); + +/** + * \brief Get "default" RSA implementation (OAEP decryption). + * + * This returns the preferred implementation of RSA (OAEP decryption) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_oaep_decrypt br_rsa_oaep_decrypt_get_default(void); + +/** + * \brief RSA decryption helper, for SSL/TLS. + * + * This function performs the RSA decryption for a RSA-based key exchange + * in a SSL/TLS server. The provided RSA engine is used. The `data` + * parameter points to the value to decrypt, of length `len` bytes. On + * success, the 48-byte pre-master secret is copied into `data`, starting + * at the first byte of that buffer; on error, the contents of `data` + * become indeterminate. + * + * This function first checks that the provided value length (`len`) is + * not lower than 59 bytes, and matches the RSA modulus length; if neither + * of this property is met, then this function returns 0 and the buffer + * is unmodified. + * + * Otherwise, decryption and then padding verification are performed, both + * in constant-time. A decryption error, or a bad padding, or an + * incorrect decrypted value length are reported with a returned value of + * 0; on success, 1 is returned. The caller (SSL server engine) is supposed + * to proceed with a random pre-master secret in case of error. + * + * \param core RSA private key engine. + * \param sk RSA private key. + * \param data input/output buffer. + * \param len length (in bytes) of the data to decrypt. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_ssl_decrypt(br_rsa_private core, const br_rsa_private_key *sk, + unsigned char *data, size_t len); + +/** + * \brief RSA encryption (OAEP) with the "i15" engine. + * + * \see br_rsa_oaep_encrypt + * + * \param rnd source of random bytes. + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param pk RSA public key. + * \param dst destination buffer. + * \param dst_max_len destination buffer length (maximum encrypted data size). + * \param src message to encrypt. + * \param src_len source message length (in bytes). + * \return encrypted message length (in bytes), or 0 on error. + */ +size_t br_rsa_i15_oaep_encrypt( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len); + +/** + * \brief RSA decryption (OAEP) with the "i15" engine. + * + * \see br_rsa_oaep_decrypt + * + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param sk RSA private key. + * \param data input/output buffer. + * \param len encrypted/decrypted message length. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_oaep_decrypt( + const br_hash_class *dig, const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len); + +/** + * \brief RSA encryption (OAEP) with the "i31" engine. + * + * \see br_rsa_oaep_encrypt + * + * \param rnd source of random bytes. + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param pk RSA public key. + * \param dst destination buffer. + * \param dst_max_len destination buffer length (maximum encrypted data size). + * \param src message to encrypt. + * \param src_len source message length (in bytes). + * \return encrypted message length (in bytes), or 0 on error. + */ +size_t br_rsa_i31_oaep_encrypt( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len); + +/** + * \brief RSA decryption (OAEP) with the "i31" engine. + * + * \see br_rsa_oaep_decrypt + * + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param sk RSA private key. + * \param data input/output buffer. + * \param len encrypted/decrypted message length. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_oaep_decrypt( + const br_hash_class *dig, const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len); + +/** + * \brief RSA encryption (OAEP) with the "i32" engine. + * + * \see br_rsa_oaep_encrypt + * + * \param rnd source of random bytes. + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param pk RSA public key. + * \param dst destination buffer. + * \param dst_max_len destination buffer length (maximum encrypted data size). + * \param src message to encrypt. + * \param src_len source message length (in bytes). + * \return encrypted message length (in bytes), or 0 on error. + */ +size_t br_rsa_i32_oaep_encrypt( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len); + +/** + * \brief RSA decryption (OAEP) with the "i32" engine. + * + * \see br_rsa_oaep_decrypt + * + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param sk RSA private key. + * \param data input/output buffer. + * \param len encrypted/decrypted message length. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_oaep_decrypt( + const br_hash_class *dig, const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len); + +/** + * \brief RSA encryption (OAEP) with the "i62" engine. + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_oaep_encrypt_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_oaep_encrypt + * + * \param rnd source of random bytes. + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param pk RSA public key. + * \param dst destination buffer. + * \param dst_max_len destination buffer length (maximum encrypted data size). + * \param src message to encrypt. + * \param src_len source message length (in bytes). + * \return encrypted message length (in bytes), or 0 on error. + */ +size_t br_rsa_i62_oaep_encrypt( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len); + +/** + * \brief RSA decryption (OAEP) with the "i62" engine. + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_oaep_decrypt_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_oaep_decrypt + * + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param sk RSA private key. + * \param data input/output buffer. + * \param len encrypted/decrypted message length. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_oaep_decrypt( + const br_hash_class *dig, const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len); + +/** + * \brief Get buffer size to hold RSA private key elements. + * + * This macro returns the length (in bytes) of the buffer needed to + * receive the elements of a RSA private key, as generated by one of + * the `br_rsa_*_keygen()` functions. If the provided size is a constant + * expression, then the whole macro evaluates to a constant expression. + * + * \param size target key size (modulus size, in bits) + * \return the length of the private key buffer, in bytes. + */ +#define BR_RSA_KBUF_PRIV_SIZE(size) (5 * (((size) + 15) >> 4)) + +/** + * \brief Get buffer size to hold RSA public key elements. + * + * This macro returns the length (in bytes) of the buffer needed to + * receive the elements of a RSA public key, as generated by one of + * the `br_rsa_*_keygen()` functions. If the provided size is a constant + * expression, then the whole macro evaluates to a constant expression. + * + * \param size target key size (modulus size, in bits) + * \return the length of the public key buffer, in bytes. + */ +#define BR_RSA_KBUF_PUB_SIZE(size) (4 + (((size) + 7) >> 3)) + +/** + * \brief Type for RSA key pair generator implementation. + * + * This function generates a new RSA key pair whose modulus has bit + * length `size` bits. The private key elements are written in the + * `kbuf_priv` buffer, and pointer values and length fields to these + * elements are populated in the provided private key structure `sk`. + * Similarly, the public key elements are written in `kbuf_pub`, with + * pointers and lengths set in `pk`. + * + * If `pk` is `NULL`, then `kbuf_pub` may be `NULL`, and only the + * private key is set. + * + * If `pubexp` is not zero, then its value will be used as public + * exponent. Valid RSA public exponent values are odd integers + * greater than 1. If `pubexp` is zero, then the public exponent will + * have value 3. + * + * The provided PRNG (`rng_ctx`) must have already been initialized + * and seeded. + * + * Returned value is 1 on success, 0 on error. An error is reported + * if the requested range is outside of the supported key sizes, or + * if an invalid non-zero public exponent value is provided. Supported + * range starts at 512 bits, and up to an implementation-defined + * maximum (by default 4096 bits). Note that key sizes up to 768 bits + * have been broken in practice, and sizes lower than 2048 bits are + * usually considered to be weak and should not be used. + * + * \param rng_ctx source PRNG context (already initialized) + * \param sk RSA private key structure (destination) + * \param kbuf_priv buffer for private key elements + * \param pk RSA public key structure (destination), or `NULL` + * \param kbuf_pub buffer for public key elements, or `NULL` + * \param size target RSA modulus size (in bits) + * \param pubexp public exponent to use, or zero + * \return 1 on success, 0 on error (invalid parameters) + */ +typedef uint32_t (*br_rsa_keygen)( + const br_prng_class **rng_ctx, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp); + +/** + * \brief RSA key pair generation with the "i15" engine. + * + * \see br_rsa_keygen + * + * \param rng_ctx source PRNG context (already initialized) + * \param sk RSA private key structure (destination) + * \param kbuf_priv buffer for private key elements + * \param pk RSA public key structure (destination), or `NULL` + * \param kbuf_pub buffer for public key elements, or `NULL` + * \param size target RSA modulus size (in bits) + * \param pubexp public exponent to use, or zero + * \return 1 on success, 0 on error (invalid parameters) + */ +uint32_t br_rsa_i15_keygen( + const br_prng_class **rng_ctx, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp); + +/** + * \brief RSA key pair generation with the "i31" engine. + * + * \see br_rsa_keygen + * + * \param rng_ctx source PRNG context (already initialized) + * \param sk RSA private key structure (destination) + * \param kbuf_priv buffer for private key elements + * \param pk RSA public key structure (destination), or `NULL` + * \param kbuf_pub buffer for public key elements, or `NULL` + * \param size target RSA modulus size (in bits) + * \param pubexp public exponent to use, or zero + * \return 1 on success, 0 on error (invalid parameters) + */ +uint32_t br_rsa_i31_keygen( + const br_prng_class **rng_ctx, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp); + +/** + * \brief RSA key pair generation with the "i62" engine. + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_keygen_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_keygen + * + * \param rng_ctx source PRNG context (already initialized) + * \param sk RSA private key structure (destination) + * \param kbuf_priv buffer for private key elements + * \param pk RSA public key structure (destination), or `NULL` + * \param kbuf_pub buffer for public key elements, or `NULL` + * \param size target RSA modulus size (in bits) + * \param pubexp public exponent to use, or zero + * \return 1 on success, 0 on error (invalid parameters) + */ +uint32_t br_rsa_i62_keygen( + const br_prng_class **rng_ctx, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp); + +/** + * \brief Get the RSA "i62" implementation (key pair generation), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_keygen br_rsa_i62_keygen_get(void); + +/** + * \brief Get "default" RSA implementation (key pair generation). + * + * This returns the preferred implementation of RSA (key pair generation) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_keygen br_rsa_keygen_get_default(void); + +/** + * \brief Type for a modulus computing function. + * + * Such a function computes the public modulus from the private key. The + * encoded modulus (unsigned big-endian) is written on `n`, and the size + * (in bytes) is returned. If `n` is `NULL`, then the size is returned but + * the modulus itself is not computed. + * + * If the key size exceeds an internal limit, 0 is returned. + * + * \param n destination buffer (or `NULL`). + * \param sk RSA private key. + * \return the modulus length (in bytes), or 0. + */ +typedef size_t (*br_rsa_compute_modulus)(void *n, const br_rsa_private_key *sk); + +/** + * \brief Recompute RSA modulus ("i15" engine). + * + * \see br_rsa_compute_modulus + * + * \param n destination buffer (or `NULL`). + * \param sk RSA private key. + * \return the modulus length (in bytes), or 0. + */ +size_t br_rsa_i15_compute_modulus(void *n, const br_rsa_private_key *sk); + +/** + * \brief Recompute RSA modulus ("i31" engine). + * + * \see br_rsa_compute_modulus + * + * \param n destination buffer (or `NULL`). + * \param sk RSA private key. + * \return the modulus length (in bytes), or 0. + */ +size_t br_rsa_i31_compute_modulus(void *n, const br_rsa_private_key *sk); + +/** + * \brief Get "default" RSA implementation (recompute modulus). + * + * This returns the preferred implementation of RSA (recompute modulus) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_compute_modulus br_rsa_compute_modulus_get_default(void); + +/** + * \brief Type for a public exponent computing function. + * + * Such a function recomputes the public exponent from the private key. + * 0 is returned if any of the following occurs: + * + * - Either `p` or `q` is not equal to 3 modulo 4. + * + * - The public exponent does not fit on 32 bits. + * + * - An internal limit is exceeded. + * + * - The private key is invalid in some way. + * + * For all private keys produced by the key generator functions + * (`br_rsa_keygen` type), this function succeeds and returns the true + * public exponent. The public exponent is always an odd integer greater + * than 1. + * + * \return the public exponent, or 0. + */ +typedef uint32_t (*br_rsa_compute_pubexp)(const br_rsa_private_key *sk); + +/** + * \brief Recompute RSA public exponent ("i15" engine). + * + * \see br_rsa_compute_pubexp + * + * \return the public exponent, or 0. + */ +uint32_t br_rsa_i15_compute_pubexp(const br_rsa_private_key *sk); + +/** + * \brief Recompute RSA public exponent ("i31" engine). + * + * \see br_rsa_compute_pubexp + * + * \return the public exponent, or 0. + */ +uint32_t br_rsa_i31_compute_pubexp(const br_rsa_private_key *sk); + +/** + * \brief Get "default" RSA implementation (recompute public exponent). + * + * This returns the preferred implementation of RSA (recompute public + * exponent) on the current system. + * + * \return the default implementation. + */ +br_rsa_compute_pubexp br_rsa_compute_pubexp_get_default(void); + +/** + * \brief Type for a private exponent computing function. + * + * An RSA private key (`br_rsa_private_key`) contains two reduced + * private exponents, which are sufficient to perform private key + * operations. However, standard encoding formats for RSA private keys + * require also a copy of the complete private exponent (non-reduced), + * which this function recomputes. + * + * This function suceeds if all the following conditions hold: + * + * - Both private factors `p` and `q` are equal to 3 modulo 4. + * + * - The provided public exponent `pubexp` is correct, and, in particular, + * is odd, relatively prime to `p-1` and `q-1`, and greater than 1. + * + * - No internal storage limit is exceeded. + * + * For all private keys produced by the key generator functions + * (`br_rsa_keygen` type), this function succeeds. Note that the API + * restricts the public exponent to a maximum size of 32 bits. + * + * The encoded private exponent is written in `d` (unsigned big-endian + * convention), and the length (in bytes) is returned. If `d` is `NULL`, + * then the exponent is not written anywhere, but the length is still + * returned. On error, 0 is returned. + * + * Not all error conditions are detected when `d` is `NULL`; therefore, the + * returned value shall be checked also when actually producing the value. + * + * \param d destination buffer (or `NULL`). + * \param sk RSA private key. + * \param pubexp the public exponent. + * \return the private exponent length (in bytes), or 0. + */ +typedef size_t (*br_rsa_compute_privexp)(void *d, + const br_rsa_private_key *sk, uint32_t pubexp); + +/** + * \brief Recompute RSA private exponent ("i15" engine). + * + * \see br_rsa_compute_privexp + * + * \param d destination buffer (or `NULL`). + * \param sk RSA private key. + * \param pubexp the public exponent. + * \return the private exponent length (in bytes), or 0. + */ +size_t br_rsa_i15_compute_privexp(void *d, + const br_rsa_private_key *sk, uint32_t pubexp); + +/** + * \brief Recompute RSA private exponent ("i31" engine). + * + * \see br_rsa_compute_privexp + * + * \param d destination buffer (or `NULL`). + * \param sk RSA private key. + * \param pubexp the public exponent. + * \return the private exponent length (in bytes), or 0. + */ +size_t br_rsa_i31_compute_privexp(void *d, + const br_rsa_private_key *sk, uint32_t pubexp); + +/** + * \brief Get "default" RSA implementation (recompute private exponent). + * + * This returns the preferred implementation of RSA (recompute private + * exponent) on the current system. + * + * \return the default implementation. + */ +br_rsa_compute_privexp br_rsa_compute_privexp_get_default(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/inc/bearssl_ssl.h b/BearSSL-OG/libbearssl/inc/bearssl_ssl.h new file mode 100644 index 0000000..3f84e6b --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl_ssl.h @@ -0,0 +1,4307 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_SSL_H__ +#define BR_BEARSSL_SSL_H__ + +#include +#include + +#include "bearssl_block.h" +#include "bearssl_hash.h" +#include "bearssl_hmac.h" +#include "bearssl_prf.h" +#include "bearssl_rand.h" +#include "bearssl_x509.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_ssl.h + * + * # SSL + * + * For an overview of the SSL/TLS API, see [the BearSSL Web + * site](https://www.bearssl.org/api1.html). + * + * The `BR_TLS_*` constants correspond to the standard cipher suites and + * their values in the [IANA + * registry](http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4). + * + * The `BR_ALERT_*` constants are for standard TLS alert messages. When + * a fatal alert message is sent of received, then the SSL engine context + * status is set to the sum of that alert value (an integer in the 0..255 + * range) and a fixed offset (`BR_ERR_SEND_FATAL_ALERT` for a sent alert, + * `BR_ERR_RECV_FATAL_ALERT` for a received alert). + */ + +/** \brief Optimal input buffer size. */ +#define BR_SSL_BUFSIZE_INPUT (16384 + 325) + +/** \brief Optimal output buffer size. */ +#define BR_SSL_BUFSIZE_OUTPUT (16384 + 85) + +/** \brief Optimal buffer size for monodirectional engine + (shared input/output buffer). */ +#define BR_SSL_BUFSIZE_MONO BR_SSL_BUFSIZE_INPUT + +/** \brief Optimal buffer size for bidirectional engine + (single buffer split into two separate input/output buffers). */ +#define BR_SSL_BUFSIZE_BIDI (BR_SSL_BUFSIZE_INPUT + BR_SSL_BUFSIZE_OUTPUT) + +/* + * Constants for known SSL/TLS protocol versions (SSL 3.0, TLS 1.0, TLS 1.1 + * and TLS 1.2). Note that though there is a constant for SSL 3.0, that + * protocol version is not actually supported. + */ + +/** \brief Protocol version: SSL 3.0 (unsupported). */ +#define BR_SSL30 0x0300 +/** \brief Protocol version: TLS 1.0. */ +#define BR_TLS10 0x0301 +/** \brief Protocol version: TLS 1.1. */ +#define BR_TLS11 0x0302 +/** \brief Protocol version: TLS 1.2. */ +#define BR_TLS12 0x0303 + +/* + * Error constants. They are used to report the reason why a context has + * been marked as failed. + * + * Implementation note: SSL-level error codes should be in the 1..31 + * range. The 32..63 range is for certificate decoding and validation + * errors. Received fatal alerts imply an error code in the 256..511 range. + */ + +/** \brief SSL status: no error so far (0). */ +#define BR_ERR_OK 0 + +/** \brief SSL status: caller-provided parameter is incorrect. */ +#define BR_ERR_BAD_PARAM 1 + +/** \brief SSL status: operation requested by the caller cannot be applied + with the current context state (e.g. reading data while outgoing data + is waiting to be sent). */ +#define BR_ERR_BAD_STATE 2 + +/** \brief SSL status: incoming protocol or record version is unsupported. */ +#define BR_ERR_UNSUPPORTED_VERSION 3 + +/** \brief SSL status: incoming record version does not match the expected + version. */ +#define BR_ERR_BAD_VERSION 4 + +/** \brief SSL status: incoming record length is invalid. */ +#define BR_ERR_BAD_LENGTH 5 + +/** \brief SSL status: incoming record is too large to be processed, or + buffer is too small for the handshake message to send. */ +#define BR_ERR_TOO_LARGE 6 + +/** \brief SSL status: decryption found an invalid padding, or the record + MAC is not correct. */ +#define BR_ERR_BAD_MAC 7 + +/** \brief SSL status: no initial entropy was provided, and none can be + obtained from the OS. */ +#define BR_ERR_NO_RANDOM 8 + +/** \brief SSL status: incoming record type is unknown. */ +#define BR_ERR_UNKNOWN_TYPE 9 + +/** \brief SSL status: incoming record or message has wrong type with + regards to the current engine state. */ +#define BR_ERR_UNEXPECTED 10 + +/** \brief SSL status: ChangeCipherSpec message from the peer has invalid + contents. */ +#define BR_ERR_BAD_CCS 12 + +/** \brief SSL status: alert message from the peer has invalid contents + (odd length). */ +#define BR_ERR_BAD_ALERT 13 + +/** \brief SSL status: incoming handshake message decoding failed. */ +#define BR_ERR_BAD_HANDSHAKE 14 + +/** \brief SSL status: ServerHello contains a session ID which is larger + than 32 bytes. */ +#define BR_ERR_OVERSIZED_ID 15 + +/** \brief SSL status: server wants to use a cipher suite that we did + not claim to support. This is also reported if we tried to advertise + a cipher suite that we do not support. */ +#define BR_ERR_BAD_CIPHER_SUITE 16 + +/** \brief SSL status: server wants to use a compression that we did not + claim to support. */ +#define BR_ERR_BAD_COMPRESSION 17 + +/** \brief SSL status: server's max fragment length does not match + client's. */ +#define BR_ERR_BAD_FRAGLEN 18 + +/** \brief SSL status: secure renegotiation failed. */ +#define BR_ERR_BAD_SECRENEG 19 + +/** \brief SSL status: server sent an extension type that we did not + announce, or used the same extension type several times in a single + ServerHello. */ +#define BR_ERR_EXTRA_EXTENSION 20 + +/** \brief SSL status: invalid Server Name Indication contents (when + used by the server, this extension shall be empty). */ +#define BR_ERR_BAD_SNI 21 + +/** \brief SSL status: invalid ServerHelloDone from the server (length + is not 0). */ +#define BR_ERR_BAD_HELLO_DONE 22 + +/** \brief SSL status: internal limit exceeded (e.g. server's public key + is too large). */ +#define BR_ERR_LIMIT_EXCEEDED 23 + +/** \brief SSL status: Finished message from peer does not match the + expected value. */ +#define BR_ERR_BAD_FINISHED 24 + +/** \brief SSL status: session resumption attempt with distinct version + or cipher suite. */ +#define BR_ERR_RESUME_MISMATCH 25 + +/** \brief SSL status: unsupported or invalid algorithm (ECDHE curve, + signature algorithm, hash function). */ +#define BR_ERR_INVALID_ALGORITHM 26 + +/** \brief SSL status: invalid signature (on ServerKeyExchange from + server, or in CertificateVerify from client). */ +#define BR_ERR_BAD_SIGNATURE 27 + +/** \brief SSL status: peer's public key does not have the proper type + or is not allowed for requested operation. */ +#define BR_ERR_WRONG_KEY_USAGE 28 + +/** \brief SSL status: client did not send a certificate upon request, + or the client certificate could not be validated. */ +#define BR_ERR_NO_CLIENT_AUTH 29 + +/** \brief SSL status: I/O error or premature close on underlying + transport stream. This error code is set only by the simplified + I/O API ("br_sslio_*"). */ +#define BR_ERR_IO 31 + +/** \brief SSL status: base value for a received fatal alert. + + When a fatal alert is received from the peer, the alert value + is added to this constant. */ +#define BR_ERR_RECV_FATAL_ALERT 256 + +/** \brief SSL status: base value for a sent fatal alert. + + When a fatal alert is sent to the peer, the alert value is added + to this constant. */ +#define BR_ERR_SEND_FATAL_ALERT 512 + +/* ===================================================================== */ + +/** + * \brief Decryption engine for SSL. + * + * When processing incoming records, the SSL engine will use a decryption + * engine that uses a specific context structure, and has a set of + * methods (a vtable) that follows this template. + * + * The decryption engine is responsible for applying decryption, verifying + * MAC, and keeping track of the record sequence number. + */ +typedef struct br_sslrec_in_class_ br_sslrec_in_class; +struct br_sslrec_in_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Test validity of the incoming record length. + * + * This function returns 1 if the announced length for an + * incoming record is valid, 0 otherwise, + * + * \param ctx decryption engine context. + * \param record_len incoming record length. + * \return 1 of a valid length, 0 otherwise. + */ + int (*check_length)(const br_sslrec_in_class *const *ctx, + size_t record_len); + + /** + * \brief Decrypt the incoming record. + * + * This function may assume that the record length is valid + * (it has been previously tested with `check_length()`). + * Decryption is done in place; `*len` is updated with the + * cleartext length, and the address of the first plaintext + * byte is returned. If the record is correct but empty, then + * `*len` is set to 0 and a non-`NULL` pointer is returned. + * + * On decryption/MAC error, `NULL` is returned. + * + * \param ctx decryption engine context. + * \param record_type record type (23 for application data, etc). + * \param version record version. + * \param payload address of encrypted payload. + * \param len pointer to payload length (updated). + * \return pointer to plaintext, or `NULL` on error. + */ + unsigned char *(*decrypt)(const br_sslrec_in_class **ctx, + int record_type, unsigned version, + void *payload, size_t *len); +}; + +/** + * \brief Encryption engine for SSL. + * + * When building outgoing records, the SSL engine will use an encryption + * engine that uses a specific context structure, and has a set of + * methods (a vtable) that follows this template. + * + * The encryption engine is responsible for applying encryption and MAC, + * and keeping track of the record sequence number. + */ +typedef struct br_sslrec_out_class_ br_sslrec_out_class; +struct br_sslrec_out_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Compute maximum plaintext sizes and offsets. + * + * When this function is called, the `*start` and `*end` + * values contain offsets designating the free area in the + * outgoing buffer for plaintext data; that free area is + * preceded by a 5-byte space which will receive the record + * header. + * + * The `max_plaintext()` function is responsible for adjusting + * both `*start` and `*end` to make room for any record-specific + * header, MAC, padding, and possible split. + * + * \param ctx encryption engine context. + * \param start pointer to start of plaintext offset (updated). + * \param end pointer to start of plaintext offset (updated). + */ + void (*max_plaintext)(const br_sslrec_out_class *const *ctx, + size_t *start, size_t *end); + + /** + * \brief Perform record encryption. + * + * This function encrypts the record. The plaintext address and + * length are provided. Returned value is the start of the + * encrypted record (or sequence of records, if a split was + * performed), _including_ the 5-byte header, and `*len` is + * adjusted to the total size of the record(s), there again + * including the header(s). + * + * \param ctx decryption engine context. + * \param record_type record type (23 for application data, etc). + * \param version record version. + * \param plaintext address of plaintext. + * \param len pointer to plaintext length (updated). + * \return pointer to start of built record. + */ + unsigned char *(*encrypt)(const br_sslrec_out_class **ctx, + int record_type, unsigned version, + void *plaintext, size_t *len); +}; + +/** + * \brief Context for a no-encryption engine. + * + * The no-encryption engine processes outgoing records during the initial + * handshake, before encryption is applied. + */ +typedef struct { + /** \brief No-encryption engine vtable. */ + const br_sslrec_out_class *vtable; +} br_sslrec_out_clear_context; + +/** \brief Static, constant vtable for the no-encryption engine. */ +extern const br_sslrec_out_class br_sslrec_out_clear_vtable; + +/* ===================================================================== */ + +/** + * \brief Record decryption engine class, for CBC mode. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for CBC processing: block cipher implementation, block cipher key, + * HMAC parameters (hash function, key, MAC length), and IV. If the + * IV is `NULL`, then a per-record IV will be used (TLS 1.1+). + */ +typedef struct br_sslrec_in_cbc_class_ br_sslrec_in_cbc_class; +struct br_sslrec_in_cbc_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CBC decryption). + * \param bc_key block cipher key. + * \param bc_key_len block cipher key length (in bytes). + * \param dig_impl hash function for HMAC. + * \param mac_key HMAC key. + * \param mac_key_len HMAC key length (in bytes). + * \param mac_out_len HMAC output length (in bytes). + * \param iv initial IV (or `NULL`). + */ + void (*init)(const br_sslrec_in_cbc_class **ctx, + const br_block_cbcdec_class *bc_impl, + const void *bc_key, size_t bc_key_len, + const br_hash_class *dig_impl, + const void *mac_key, size_t mac_key_len, size_t mac_out_len, + const void *iv); +}; + +/** + * \brief Record encryption engine class, for CBC mode. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for CBC processing: block cipher implementation, block cipher key, + * HMAC parameters (hash function, key, MAC length), and IV. If the + * IV is `NULL`, then a per-record IV will be used (TLS 1.1+). + */ +typedef struct br_sslrec_out_cbc_class_ br_sslrec_out_cbc_class; +struct br_sslrec_out_cbc_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CBC encryption). + * \param bc_key block cipher key. + * \param bc_key_len block cipher key length (in bytes). + * \param dig_impl hash function for HMAC. + * \param mac_key HMAC key. + * \param mac_key_len HMAC key length (in bytes). + * \param mac_out_len HMAC output length (in bytes). + * \param iv initial IV (or `NULL`). + */ + void (*init)(const br_sslrec_out_cbc_class **ctx, + const br_block_cbcenc_class *bc_impl, + const void *bc_key, size_t bc_key_len, + const br_hash_class *dig_impl, + const void *mac_key, size_t mac_key_len, size_t mac_out_len, + const void *iv); +}; + +/** + * \brief Context structure for decrypting incoming records with + * CBC + HMAC. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_sslrec_in_cbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_cbcdec_class *vtable; + br_aes_gen_cbcdec_keys aes; + br_des_gen_cbcdec_keys des; + } bc; + br_hmac_key_context mac; + size_t mac_len; + unsigned char iv[16]; + int explicit_IV; +#endif +} br_sslrec_in_cbc_context; + +/** + * \brief Static, constant vtable for record decryption with CBC. + */ +extern const br_sslrec_in_cbc_class br_sslrec_in_cbc_vtable; + +/** + * \brief Context structure for encrypting outgoing records with + * CBC + HMAC. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_sslrec_out_cbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_cbcenc_class *vtable; + br_aes_gen_cbcenc_keys aes; + br_des_gen_cbcenc_keys des; + } bc; + br_hmac_key_context mac; + size_t mac_len; + unsigned char iv[16]; + int explicit_IV; +#endif +} br_sslrec_out_cbc_context; + +/** + * \brief Static, constant vtable for record encryption with CBC. + */ +extern const br_sslrec_out_cbc_class br_sslrec_out_cbc_vtable; + +/* ===================================================================== */ + +/** + * \brief Record decryption engine class, for GCM mode. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for GCM processing: block cipher implementation, block cipher key, + * GHASH implementation, and 4-byte IV. + */ +typedef struct br_sslrec_in_gcm_class_ br_sslrec_in_gcm_class; +struct br_sslrec_in_gcm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param gh_impl GHASH implementation. + * \param iv static IV (4 bytes). + */ + void (*init)(const br_sslrec_in_gcm_class **ctx, + const br_block_ctr_class *bc_impl, + const void *key, size_t key_len, + br_ghash gh_impl, + const void *iv); +}; + +/** + * \brief Record encryption engine class, for GCM mode. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for GCM processing: block cipher implementation, block cipher key, + * GHASH implementation, and 4-byte IV. + */ +typedef struct br_sslrec_out_gcm_class_ br_sslrec_out_gcm_class; +struct br_sslrec_out_gcm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param gh_impl GHASH implementation. + * \param iv static IV (4 bytes). + */ + void (*init)(const br_sslrec_out_gcm_class **ctx, + const br_block_ctr_class *bc_impl, + const void *key, size_t key_len, + br_ghash gh_impl, + const void *iv); +}; + +/** + * \brief Context structure for processing records with GCM. + * + * The same context structure is used for encrypting and decrypting. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + union { + const void *gen; + const br_sslrec_in_gcm_class *in; + const br_sslrec_out_gcm_class *out; + } vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_ctr_class *vtable; + br_aes_gen_ctr_keys aes; + } bc; + br_ghash gh; + unsigned char iv[4]; + unsigned char h[16]; +#endif +} br_sslrec_gcm_context; + +/** + * \brief Static, constant vtable for record decryption with GCM. + */ +extern const br_sslrec_in_gcm_class br_sslrec_in_gcm_vtable; + +/** + * \brief Static, constant vtable for record encryption with GCM. + */ +extern const br_sslrec_out_gcm_class br_sslrec_out_gcm_vtable; + +/* ===================================================================== */ + +/** + * \brief Record decryption engine class, for ChaCha20+Poly1305. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for ChaCha20+Poly1305 processing: ChaCha20 implementation, + * Poly1305 implementation, key, and 12-byte IV. + */ +typedef struct br_sslrec_in_chapol_class_ br_sslrec_in_chapol_class; +struct br_sslrec_in_chapol_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param ichacha ChaCha20 implementation. + * \param ipoly Poly1305 implementation. + * \param key secret key (32 bytes). + * \param iv static IV (12 bytes). + */ + void (*init)(const br_sslrec_in_chapol_class **ctx, + br_chacha20_run ichacha, + br_poly1305_run ipoly, + const void *key, const void *iv); +}; + +/** + * \brief Record encryption engine class, for ChaCha20+Poly1305. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for ChaCha20+Poly1305 processing: ChaCha20 implementation, + * Poly1305 implementation, key, and 12-byte IV. + */ +typedef struct br_sslrec_out_chapol_class_ br_sslrec_out_chapol_class; +struct br_sslrec_out_chapol_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param ichacha ChaCha20 implementation. + * \param ipoly Poly1305 implementation. + * \param key secret key (32 bytes). + * \param iv static IV (12 bytes). + */ + void (*init)(const br_sslrec_out_chapol_class **ctx, + br_chacha20_run ichacha, + br_poly1305_run ipoly, + const void *key, const void *iv); +}; + +/** + * \brief Context structure for processing records with ChaCha20+Poly1305. + * + * The same context structure is used for encrypting and decrypting. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + union { + const void *gen; + const br_sslrec_in_chapol_class *in; + const br_sslrec_out_chapol_class *out; + } vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + unsigned char key[32]; + unsigned char iv[12]; + br_chacha20_run ichacha; + br_poly1305_run ipoly; +#endif +} br_sslrec_chapol_context; + +/** + * \brief Static, constant vtable for record decryption with ChaCha20+Poly1305. + */ +extern const br_sslrec_in_chapol_class br_sslrec_in_chapol_vtable; + +/** + * \brief Static, constant vtable for record encryption with ChaCha20+Poly1305. + */ +extern const br_sslrec_out_chapol_class br_sslrec_out_chapol_vtable; + +/* ===================================================================== */ + +/** + * \brief Record decryption engine class, for CCM mode. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for CCM processing: block cipher implementation, block cipher key, + * and 4-byte IV. + */ +typedef struct br_sslrec_in_ccm_class_ br_sslrec_in_ccm_class; +struct br_sslrec_in_ccm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR+CBC). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param iv static IV (4 bytes). + * \param tag_len tag length (in bytes) + */ + void (*init)(const br_sslrec_in_ccm_class **ctx, + const br_block_ctrcbc_class *bc_impl, + const void *key, size_t key_len, + const void *iv, size_t tag_len); +}; + +/** + * \brief Record encryption engine class, for CCM mode. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for CCM processing: block cipher implementation, block cipher key, + * and 4-byte IV. + */ +typedef struct br_sslrec_out_ccm_class_ br_sslrec_out_ccm_class; +struct br_sslrec_out_ccm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR+CBC). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param iv static IV (4 bytes). + * \param tag_len tag length (in bytes) + */ + void (*init)(const br_sslrec_out_ccm_class **ctx, + const br_block_ctrcbc_class *bc_impl, + const void *key, size_t key_len, + const void *iv, size_t tag_len); +}; + +/** + * \brief Context structure for processing records with CCM. + * + * The same context structure is used for encrypting and decrypting. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + union { + const void *gen; + const br_sslrec_in_ccm_class *in; + const br_sslrec_out_ccm_class *out; + } vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_ctrcbc_class *vtable; + br_aes_gen_ctrcbc_keys aes; + } bc; + unsigned char iv[4]; + size_t tag_len; +#endif +} br_sslrec_ccm_context; + +/** + * \brief Static, constant vtable for record decryption with CCM. + */ +extern const br_sslrec_in_ccm_class br_sslrec_in_ccm_vtable; + +/** + * \brief Static, constant vtable for record encryption with CCM. + */ +extern const br_sslrec_out_ccm_class br_sslrec_out_ccm_vtable; + +/* ===================================================================== */ + +/** + * \brief Type for session parameters, to be saved for session resumption. + */ +typedef struct { + /** \brief Session ID buffer. */ + unsigned char session_id[32]; + /** \brief Session ID length (in bytes, at most 32). */ + unsigned char session_id_len; + /** \brief Protocol version. */ + uint16_t version; + /** \brief Cipher suite. */ + uint16_t cipher_suite; + /** \brief Master secret. */ + unsigned char master_secret[48]; + /** \brief Session ticket (RFC 5077), opaque blob from server. */ + unsigned char session_ticket[1024]; + /** \brief Session ticket length (0 if no ticket). */ + uint16_t session_ticket_len; +} br_ssl_session_parameters; + +#ifndef BR_DOXYGEN_IGNORE +/* + * Maximum number of cipher suites supported by a client or server. + */ +#define BR_MAX_CIPHER_SUITES 48 +#endif + +/** + * \brief Context structure for SSL engine. + * + * This strucuture is common to the client and server; both the client + * context (`br_ssl_client_context`) and the server context + * (`br_ssl_server_context`) include a `br_ssl_engine_context` as their + * first field. + * + * The engine context manages records, including alerts, closures, and + * transitions to new encryption/MAC algorithms. Processing of handshake + * records is delegated to externally provided code. This structure + * should not be used directly. + * + * Structure contents are opaque and shall not be accessed directly. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + /* + * The error code. When non-zero, then the state is "failed" and + * no I/O may occur until reset. + */ + int err; + + /* + * Configured I/O buffers. They are either disjoint, or identical. + */ + unsigned char *ibuf, *obuf; + size_t ibuf_len, obuf_len; + + /* + * Maximum fragment length applies to outgoing records; incoming + * records can be processed as long as they fit in the input + * buffer. It is guaranteed that incoming records at least as big + * as max_frag_len can be processed. + */ + uint16_t max_frag_len; + unsigned char log_max_frag_len; + unsigned char peer_log_max_frag_len; + + /* + * Buffering management registers. + */ + size_t ixa, ixb, ixc; + size_t oxa, oxb, oxc; + unsigned char iomode; + unsigned char incrypt; + + /* + * Shutdown flag: when set to non-zero, incoming record bytes + * will not be accepted anymore. This is used after a close_notify + * has been received: afterwards, the engine no longer claims that + * it could receive bytes from the transport medium. + */ + unsigned char shutdown_recv; + + /* + * 'record_type_in' is set to the incoming record type when the + * record header has been received. + * 'record_type_out' is used to make the next outgoing record + * header when it is ready to go. + */ + unsigned char record_type_in, record_type_out; + + /* + * When a record is received, its version is extracted: + * -- if 'version_in' is 0, then it is set to the received version; + * -- otherwise, if the received version is not identical to + * the 'version_in' contents, then a failure is reported. + * + * This implements the SSL requirement that all records shall + * use the negotiated protocol version, once decided (in the + * ServerHello). It is up to the handshake handler to adjust this + * field when necessary. + */ + uint16_t version_in; + + /* + * 'version_out' is used when the next outgoing record is ready + * to go. + */ + uint16_t version_out; + + /* + * Record handler contexts. + */ + union { + const br_sslrec_in_class *vtable; + br_sslrec_in_cbc_context cbc; + br_sslrec_gcm_context gcm; + br_sslrec_chapol_context chapol; + br_sslrec_ccm_context ccm; + } in; + union { + const br_sslrec_out_class *vtable; + br_sslrec_out_clear_context clear; + br_sslrec_out_cbc_context cbc; + br_sslrec_gcm_context gcm; + br_sslrec_chapol_context chapol; + br_sslrec_ccm_context ccm; + } out; + + /* + * The "application data" flag. Value: + * 0 handshake is in process, no application data acceptable + * 1 application data can be sent and received + * 2 closing, no application data can be sent, but some + * can still be received (and discarded) + */ + unsigned char application_data; + + /* + * Context RNG. + * + * rng_init_done is initially 0. It is set to 1 when the + * basic structure of the RNG is set, and 2 when some + * entropy has been pushed in. The value 2 marks the RNG + * as "properly seeded". + * + * rng_os_rand_done is initially 0. It is set to 1 when + * some seeding from the OS or hardware has been attempted. + */ + br_hmac_drbg_context rng; + int rng_init_done; + int rng_os_rand_done; + + /* + * Supported minimum and maximum versions, and cipher suites. + */ + uint16_t version_min; + uint16_t version_max; + uint16_t suites_buf[BR_MAX_CIPHER_SUITES]; + unsigned char suites_num; + + /* + * For clients, the server name to send as a SNI extension. For + * servers, the name received in the SNI extension (if any). + */ + char server_name[256]; + + /* + * "Security parameters". These are filled by the handshake + * handler, and used when switching encryption state. + */ + unsigned char client_random[32]; + unsigned char server_random[32]; + br_ssl_session_parameters session; + + /* + * ECDHE elements: curve and point from the peer. The server also + * uses that buffer for the point to send to the client. + */ + unsigned char ecdhe_curve; + unsigned char ecdhe_point[133]; + unsigned char ecdhe_point_len; + + /* + * Secure renegotiation (RFC 5746): 'reneg' can be: + * 0 first handshake (server support is not known) + * 1 peer does not support secure renegotiation + * 2 peer supports secure renegotiation + * + * The saved_finished buffer contains the client and the + * server "Finished" values from the last handshake, in + * that order (12 bytes each). + */ + unsigned char reneg; + unsigned char saved_finished[24]; + + /* + * Session ticket (RFC 5077) support flag. Set to 1 when the + * server confirms ticket support in its ServerHello extensions. + */ + unsigned char session_ticket_ok; + + /* + * Behavioural flags. + */ + uint32_t flags; + + /* + * Context variables for the handshake processor. The 'pad' must + * be large enough to accommodate an RSA-encrypted pre-master + * secret, or an RSA signature; since we want to support up to + * RSA-4096, this means at least 512 bytes. (Other pad usages + * require its length to be at least 256.) + */ + struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; + } cpu; + uint32_t dp_stack[32]; + uint32_t rp_stack[32]; + unsigned char pad[512]; + unsigned char *hbuf_in, *hbuf_out, *saved_hbuf_out; + size_t hlen_in, hlen_out; + void (*hsrun)(void *ctx); + + /* + * The 'action' value communicates OOB information between the + * engine and the handshake processor. + * + * From the engine: + * 0 invocation triggered by I/O + * 1 invocation triggered by explicit close + * 2 invocation triggered by explicit renegotiation + */ + unsigned char action; + + /* + * State for alert messages. Value is either 0, or the value of + * the alert level byte (level is either 1 for warning, or 2 for + * fatal; we convert all other values to 'fatal'). + */ + unsigned char alert; + + /* + * Closure flags. This flag is set when a close_notify has been + * received from the peer. + */ + unsigned char close_received; + + /* + * Multi-hasher for the handshake messages. The handshake handler + * is responsible for resetting it when appropriate. + */ + br_multihash_context mhash; + + /* + * Pointer to the X.509 engine. The engine is supposed to be + * already initialized. It is used to validate the peer's + * certificate. + */ + const br_x509_class **x509ctx; + + /* + * Certificate chain to send. This is used by both client and + * server, when they send their respective Certificate messages. + * If chain_len is 0, then chain may be NULL. + */ + const br_x509_certificate *chain; + size_t chain_len; + const unsigned char *cert_cur; + size_t cert_len; + + /* + * List of supported protocol names (ALPN extension). If unset, + * (number of names is 0), then: + * - the client sends no ALPN extension; + * - the server ignores any incoming ALPN extension. + * + * Otherwise: + * - the client sends an ALPN extension with all the names; + * - the server selects the first protocol in its list that + * the client also supports, or fails (fatal alert 120) + * if the client sends an ALPN extension and there is no + * match. + * + * The 'selected_protocol' field contains 1+n if the matching + * name has index n in the list (the value is 0 if no match was + * performed, e.g. the peer did not send an ALPN extension). + */ + const char **protocol_names; + uint16_t protocol_names_num; + uint16_t selected_protocol; + + /* + * Pointers to implementations; left to NULL for unsupported + * functions. For the raw hash functions, implementations are + * referenced from the multihasher (mhash field). + */ + br_tls_prf_impl prf10; + br_tls_prf_impl prf_sha256; + br_tls_prf_impl prf_sha384; + const br_block_cbcenc_class *iaes_cbcenc; + const br_block_cbcdec_class *iaes_cbcdec; + const br_block_ctr_class *iaes_ctr; + const br_block_ctrcbc_class *iaes_ctrcbc; + const br_block_cbcenc_class *ides_cbcenc; + const br_block_cbcdec_class *ides_cbcdec; + br_ghash ighash; + br_chacha20_run ichacha; + br_poly1305_run ipoly; + const br_sslrec_in_cbc_class *icbc_in; + const br_sslrec_out_cbc_class *icbc_out; + const br_sslrec_in_gcm_class *igcm_in; + const br_sslrec_out_gcm_class *igcm_out; + const br_sslrec_in_chapol_class *ichapol_in; + const br_sslrec_out_chapol_class *ichapol_out; + const br_sslrec_in_ccm_class *iccm_in; + const br_sslrec_out_ccm_class *iccm_out; + const br_ec_impl *iec; + br_rsa_pkcs1_vrfy irsavrfy; + br_ecdsa_vrfy iecdsa; +#endif +} br_ssl_engine_context; + +/** + * \brief Get currently defined engine behavioural flags. + * + * \param cc SSL engine context. + * \return the flags. + */ +static __inline uint32_t +br_ssl_engine_get_flags(br_ssl_engine_context *cc) +{ + return cc->flags; +} + +/** + * \brief Set all engine behavioural flags. + * + * \param cc SSL engine context. + * \param flags new value for all flags. + */ +static __inline void +br_ssl_engine_set_all_flags(br_ssl_engine_context *cc, uint32_t flags) +{ + cc->flags = flags; +} + +/** + * \brief Set some engine behavioural flags. + * + * The flags set in the `flags` parameter are set in the context; other + * flags are untouched. + * + * \param cc SSL engine context. + * \param flags additional set flags. + */ +static __inline void +br_ssl_engine_add_flags(br_ssl_engine_context *cc, uint32_t flags) +{ + cc->flags |= flags; +} + +/** + * \brief Clear some engine behavioural flags. + * + * The flags set in the `flags` parameter are cleared from the context; other + * flags are untouched. + * + * \param cc SSL engine context. + * \param flags flags to remove. + */ +static __inline void +br_ssl_engine_remove_flags(br_ssl_engine_context *cc, uint32_t flags) +{ + cc->flags &= ~flags; +} + +/** + * \brief Behavioural flag: enforce server preferences. + * + * If this flag is set, then the server will enforce its own cipher suite + * preference order; otherwise, it follows the client preferences. + */ +#define BR_OPT_ENFORCE_SERVER_PREFERENCES ((uint32_t)1 << 0) + +/** + * \brief Behavioural flag: disable renegotiation. + * + * If this flag is set, then renegotiations are rejected unconditionally: + * they won't be honoured if asked for programmatically, and requests from + * the peer are rejected. + */ +#define BR_OPT_NO_RENEGOTIATION ((uint32_t)1 << 1) + +/** + * \brief Behavioural flag: tolerate lack of client authentication. + * + * If this flag is set in a server and the server requests a client + * certificate, but the authentication fails (the client does not send + * a certificate, or the client's certificate chain cannot be validated), + * then the connection keeps on. Without this flag, a failed client + * authentication terminates the connection. + * + * Notes: + * + * - If the client's certificate can be validated and its public key is + * supported, then a wrong signature value terminates the connection + * regardless of that flag. + * + * - If using full-static ECDH, then a failure to validate the client's + * certificate prevents the handshake from succeeding. + */ +#define BR_OPT_TOLERATE_NO_CLIENT_AUTH ((uint32_t)1 << 2) + +/** + * \brief Behavioural flag: fail on application protocol mismatch. + * + * The ALPN extension ([RFC 7301](https://tools.ietf.org/html/rfc7301)) + * allows the client to send a list of application protocol names, and + * the server to select one. A mismatch is one of the following occurrences: + * + * - On the client: the client sends a list of names, the server + * responds with a protocol name which is _not_ part of the list of + * names sent by the client. + * + * - On the server: the client sends a list of names, and the server + * is also configured with a list of names, but there is no common + * protocol name between the two lists. + * + * Normal behaviour in case of mismatch is to report no matching name + * (`br_ssl_engine_get_selected_protocol()` returns `NULL`) and carry on. + * If the flag is set, then a mismatch implies a protocol failure (if + * the mismatch is detected by the server, it will send a fatal alert). + * + * Note: even with this flag, `br_ssl_engine_get_selected_protocol()` + * may still return `NULL` if the client or the server does not send an + * ALPN extension at all. + */ +#define BR_OPT_FAIL_ON_ALPN_MISMATCH ((uint32_t)1 << 3) + +/** + * \brief Set the minimum and maximum supported protocol versions. + * + * The two provided versions MUST be supported by the implementation + * (i.e. TLS 1.0, 1.1 and 1.2), and `version_max` MUST NOT be lower + * than `version_min`. + * + * \param cc SSL engine context. + * \param version_min minimum supported TLS version. + * \param version_max maximum supported TLS version. + */ +static __inline void +br_ssl_engine_set_versions(br_ssl_engine_context *cc, + unsigned version_min, unsigned version_max) +{ + cc->version_min = (uint16_t)version_min; + cc->version_max = (uint16_t)version_max; +} + +/** + * \brief Set the list of cipher suites advertised by this context. + * + * The provided array is copied into the context. It is the caller + * responsibility to ensure that all provided suites will be supported + * by the context. The engine context has enough room to receive _all_ + * suites supported by the implementation. The provided array MUST NOT + * contain duplicates. + * + * If the engine is for a client, the "signaling" pseudo-cipher suite + * `TLS_FALLBACK_SCSV` can be added at the end of the list, if the + * calling application is performing a voluntary downgrade (voluntary + * downgrades are not recommended, but if such a downgrade is done, then + * adding the fallback pseudo-suite is a good idea). + * + * \param cc SSL engine context. + * \param suites cipher suites. + * \param suites_num number of cipher suites. + */ +void br_ssl_engine_set_suites(br_ssl_engine_context *cc, + const uint16_t *suites, size_t suites_num); + +/** + * \brief Set the X.509 engine. + * + * The caller shall ensure that the X.509 engine is properly initialised. + * + * \param cc SSL engine context. + * \param x509ctx X.509 certificate validation context. + */ +static __inline void +br_ssl_engine_set_x509(br_ssl_engine_context *cc, const br_x509_class **x509ctx) +{ + cc->x509ctx = x509ctx; +} + +/** + * \brief Set the supported protocol names. + * + * Protocol names are part of the ALPN extension ([RFC + * 7301](https://tools.ietf.org/html/rfc7301)). Each protocol name is a + * character string, containing no more than 255 characters (256 with the + * terminating zero). When names are set, then: + * + * - The client will send an ALPN extension, containing the names. If + * the server responds with an ALPN extension, the client will verify + * that the response contains one of its name, and report that name + * through `br_ssl_engine_get_selected_protocol()`. + * + * - The server will parse incoming ALPN extension (from clients), and + * try to find a common protocol; if none is found, the connection + * is aborted with a fatal alert. On match, a response ALPN extension + * is sent, and name is reported through + * `br_ssl_engine_get_selected_protocol()`. + * + * The provided array is linked in, and must remain valid while the + * connection is live. + * + * Names MUST NOT be empty. Names MUST NOT be longer than 255 characters + * (excluding the terminating 0). + * + * \param ctx SSL engine context. + * \param names list of protocol names (zero-terminated). + * \param num number of protocol names (MUST be 1 or more). + */ +static __inline void +br_ssl_engine_set_protocol_names(br_ssl_engine_context *ctx, + const char **names, size_t num) +{ + ctx->protocol_names = names; + ctx->protocol_names_num = (uint16_t)num; +} + +/** + * \brief Get the selected protocol. + * + * If this context was initialised with a non-empty list of protocol + * names, and both client and server sent ALPN extensions during the + * handshake, and a common name was found, then that name is returned. + * Otherwise, `NULL` is returned. + * + * The returned pointer is one of the pointers provided to the context + * with `br_ssl_engine_set_protocol_names()`. + * + * \return the selected protocol, or `NULL`. + */ +static __inline const char * +br_ssl_engine_get_selected_protocol(br_ssl_engine_context *ctx) +{ + unsigned k; + + k = ctx->selected_protocol; + return (k == 0 || k == 0xFFFF) ? NULL : ctx->protocol_names[k - 1]; +} + +/** + * \brief Set a hash function implementation (by ID). + * + * Hash functions set with this call will be used for SSL/TLS specific + * usages, not X.509 certificate validation. Only "standard" hash functions + * may be set (MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512). If `impl` + * is `NULL`, then the hash function support is removed, not added. + * + * \param ctx SSL engine context. + * \param id hash function identifier. + * \param impl hash function implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_hash(br_ssl_engine_context *ctx, + int id, const br_hash_class *impl) +{ + br_multihash_setimpl(&ctx->mhash, id, impl); +} + +/** + * \brief Get a hash function implementation (by ID). + * + * This function retrieves a hash function implementation which was + * set with `br_ssl_engine_set_hash()`. + * + * \param ctx SSL engine context. + * \param id hash function identifier. + * \return the hash function implementation (or `NULL`). + */ +static __inline const br_hash_class * +br_ssl_engine_get_hash(br_ssl_engine_context *ctx, int id) +{ + return br_multihash_getimpl(&ctx->mhash, id); +} + +/** + * \brief Set the PRF implementation (for TLS 1.0 and 1.1). + * + * This function sets (or removes, if `impl` is `NULL`) the implementation + * for the PRF used in TLS 1.0 and 1.1. + * + * \param cc SSL engine context. + * \param impl PRF implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_prf10(br_ssl_engine_context *cc, br_tls_prf_impl impl) +{ + cc->prf10 = impl; +} + +/** + * \brief Set the PRF implementation with SHA-256 (for TLS 1.2). + * + * This function sets (or removes, if `impl` is `NULL`) the implementation + * for the SHA-256 variant of the PRF used in TLS 1.2. + * + * \param cc SSL engine context. + * \param impl PRF implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_prf_sha256(br_ssl_engine_context *cc, br_tls_prf_impl impl) +{ + cc->prf_sha256 = impl; +} + +/** + * \brief Set the PRF implementation with SHA-384 (for TLS 1.2). + * + * This function sets (or removes, if `impl` is `NULL`) the implementation + * for the SHA-384 variant of the PRF used in TLS 1.2. + * + * \param cc SSL engine context. + * \param impl PRF implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_prf_sha384(br_ssl_engine_context *cc, br_tls_prf_impl impl) +{ + cc->prf_sha384 = impl; +} + +/** + * \brief Set the AES/CBC implementations. + * + * \param cc SSL engine context. + * \param impl_enc AES/CBC encryption implementation (or `NULL`). + * \param impl_dec AES/CBC decryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_aes_cbc(br_ssl_engine_context *cc, + const br_block_cbcenc_class *impl_enc, + const br_block_cbcdec_class *impl_dec) +{ + cc->iaes_cbcenc = impl_enc; + cc->iaes_cbcdec = impl_dec; +} + +/** + * \brief Set the "default" AES/CBC implementations. + * + * This function configures in the engine the AES implementations that + * should provide best runtime performance on the local system, while + * still being safe (in particular, constant-time). It also sets the + * handlers for CBC records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_aes_cbc(br_ssl_engine_context *cc); + +/** + * \brief Set the AES/CTR implementation. + * + * \param cc SSL engine context. + * \param impl AES/CTR encryption/decryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_aes_ctr(br_ssl_engine_context *cc, + const br_block_ctr_class *impl) +{ + cc->iaes_ctr = impl; +} + +/** + * \brief Set the "default" implementations for AES/GCM (AES/CTR + GHASH). + * + * This function configures in the engine the AES/CTR and GHASH + * implementation that should provide best runtime performance on the local + * system, while still being safe (in particular, constant-time). It also + * sets the handlers for GCM records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_aes_gcm(br_ssl_engine_context *cc); + +/** + * \brief Set the DES/CBC implementations. + * + * \param cc SSL engine context. + * \param impl_enc DES/CBC encryption implementation (or `NULL`). + * \param impl_dec DES/CBC decryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_des_cbc(br_ssl_engine_context *cc, + const br_block_cbcenc_class *impl_enc, + const br_block_cbcdec_class *impl_dec) +{ + cc->ides_cbcenc = impl_enc; + cc->ides_cbcdec = impl_dec; +} + +/** + * \brief Set the "default" DES/CBC implementations. + * + * This function configures in the engine the DES implementations that + * should provide best runtime performance on the local system, while + * still being safe (in particular, constant-time). It also sets the + * handlers for CBC records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc); + +/** + * \brief Set the GHASH implementation (used in GCM mode). + * + * \param cc SSL engine context. + * \param impl GHASH implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_ghash(br_ssl_engine_context *cc, br_ghash impl) +{ + cc->ighash = impl; +} + +/** + * \brief Set the ChaCha20 implementation. + * + * \param cc SSL engine context. + * \param ichacha ChaCha20 implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_chacha20(br_ssl_engine_context *cc, + br_chacha20_run ichacha) +{ + cc->ichacha = ichacha; +} + +/** + * \brief Set the Poly1305 implementation. + * + * \param cc SSL engine context. + * \param ipoly Poly1305 implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_poly1305(br_ssl_engine_context *cc, + br_poly1305_run ipoly) +{ + cc->ipoly = ipoly; +} + +/** + * \brief Set the "default" ChaCha20 and Poly1305 implementations. + * + * This function configures in the engine the ChaCha20 and Poly1305 + * implementations that should provide best runtime performance on the + * local system, while still being safe (in particular, constant-time). + * It also sets the handlers for ChaCha20+Poly1305 records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_chapol(br_ssl_engine_context *cc); + +/** + * \brief Set the AES/CTR+CBC implementation. + * + * \param cc SSL engine context. + * \param impl AES/CTR+CBC encryption/decryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_aes_ctrcbc(br_ssl_engine_context *cc, + const br_block_ctrcbc_class *impl) +{ + cc->iaes_ctrcbc = impl; +} + +/** + * \brief Set the "default" implementations for AES/CCM. + * + * This function configures in the engine the AES/CTR+CBC + * implementation that should provide best runtime performance on the local + * system, while still being safe (in particular, constant-time). It also + * sets the handlers for CCM records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_aes_ccm(br_ssl_engine_context *cc); + +/** + * \brief Set the record encryption and decryption engines for CBC + HMAC. + * + * \param cc SSL engine context. + * \param impl_in record CBC decryption implementation (or `NULL`). + * \param impl_out record CBC encryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_cbc(br_ssl_engine_context *cc, + const br_sslrec_in_cbc_class *impl_in, + const br_sslrec_out_cbc_class *impl_out) +{ + cc->icbc_in = impl_in; + cc->icbc_out = impl_out; +} + +/** + * \brief Set the record encryption and decryption engines for GCM. + * + * \param cc SSL engine context. + * \param impl_in record GCM decryption implementation (or `NULL`). + * \param impl_out record GCM encryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_gcm(br_ssl_engine_context *cc, + const br_sslrec_in_gcm_class *impl_in, + const br_sslrec_out_gcm_class *impl_out) +{ + cc->igcm_in = impl_in; + cc->igcm_out = impl_out; +} + +/** + * \brief Set the record encryption and decryption engines for CCM. + * + * \param cc SSL engine context. + * \param impl_in record CCM decryption implementation (or `NULL`). + * \param impl_out record CCM encryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_ccm(br_ssl_engine_context *cc, + const br_sslrec_in_ccm_class *impl_in, + const br_sslrec_out_ccm_class *impl_out) +{ + cc->iccm_in = impl_in; + cc->iccm_out = impl_out; +} + +/** + * \brief Set the record encryption and decryption engines for + * ChaCha20+Poly1305. + * + * \param cc SSL engine context. + * \param impl_in record ChaCha20 decryption implementation (or `NULL`). + * \param impl_out record ChaCha20 encryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_chapol(br_ssl_engine_context *cc, + const br_sslrec_in_chapol_class *impl_in, + const br_sslrec_out_chapol_class *impl_out) +{ + cc->ichapol_in = impl_in; + cc->ichapol_out = impl_out; +} + +/** + * \brief Set the EC implementation. + * + * The elliptic curve implementation will be used for ECDH and ECDHE + * cipher suites, and for ECDSA support. + * + * \param cc SSL engine context. + * \param iec EC implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_ec(br_ssl_engine_context *cc, const br_ec_impl *iec) +{ + cc->iec = iec; +} + +/** + * \brief Set the "default" EC implementation. + * + * This function sets the elliptic curve implementation for ECDH and + * ECDHE cipher suites, and for ECDSA support. It selects the fastest + * implementation on the current system. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_ec(br_ssl_engine_context *cc); + +/** + * \brief Get the EC implementation configured in the provided engine. + * + * \param cc SSL engine context. + * \return the EC implementation. + */ +static __inline const br_ec_impl * +br_ssl_engine_get_ec(br_ssl_engine_context *cc) +{ + return cc->iec; +} + +/** + * \brief Set the RSA signature verification implementation. + * + * On the client, this is used to verify the server's signature on its + * ServerKeyExchange message (for ECDHE_RSA cipher suites). On the server, + * this is used to verify the client's CertificateVerify message (if a + * client certificate is requested, and that certificate contains a RSA key). + * + * \param cc SSL engine context. + * \param irsavrfy RSA signature verification implementation. + */ +static __inline void +br_ssl_engine_set_rsavrfy(br_ssl_engine_context *cc, br_rsa_pkcs1_vrfy irsavrfy) +{ + cc->irsavrfy = irsavrfy; +} + +/** + * \brief Set the "default" RSA implementation (signature verification). + * + * This function sets the RSA implementation (signature verification) + * to the fastest implementation available on the current platform. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_rsavrfy(br_ssl_engine_context *cc); + +/** + * \brief Get the RSA implementation (signature verification) configured + * in the provided engine. + * + * \param cc SSL engine context. + * \return the RSA signature verification implementation. + */ +static __inline br_rsa_pkcs1_vrfy +br_ssl_engine_get_rsavrfy(br_ssl_engine_context *cc) +{ + return cc->irsavrfy; +} + +/* + * \brief Set the ECDSA implementation (signature verification). + * + * On the client, this is used to verify the server's signature on its + * ServerKeyExchange message (for ECDHE_ECDSA cipher suites). On the server, + * this is used to verify the client's CertificateVerify message (if a + * client certificate is requested, that certificate contains an EC key, + * and full-static ECDH is not used). + * + * The ECDSA implementation will use the EC core implementation configured + * in the engine context. + * + * \param cc client context. + * \param iecdsa ECDSA verification implementation. + */ +static __inline void +br_ssl_engine_set_ecdsa(br_ssl_engine_context *cc, br_ecdsa_vrfy iecdsa) +{ + cc->iecdsa = iecdsa; +} + +/** + * \brief Set the "default" ECDSA implementation (signature verification). + * + * This function sets the ECDSA implementation (signature verification) + * to the fastest implementation available on the current platform. This + * call also sets the elliptic curve implementation itself, there again + * to the fastest EC implementation available. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_ecdsa(br_ssl_engine_context *cc); + +/** + * \brief Get the ECDSA implementation (signature verification) configured + * in the provided engine. + * + * \param cc SSL engine context. + * \return the ECDSA signature verification implementation. + */ +static __inline br_ecdsa_vrfy +br_ssl_engine_get_ecdsa(br_ssl_engine_context *cc) +{ + return cc->iecdsa; +} + +/** + * \brief Set the I/O buffer for the SSL engine. + * + * Once this call has been made, `br_ssl_client_reset()` or + * `br_ssl_server_reset()` MUST be called before using the context. + * + * The provided buffer will be used as long as the engine context is + * used. The caller is responsible for keeping it available. + * + * If `bidi` is 0, then the engine will operate in half-duplex mode + * (it won't be able to send data while there is unprocessed incoming + * data in the buffer, and it won't be able to receive data while there + * is unsent data in the buffer). The optimal buffer size in half-duplex + * mode is `BR_SSL_BUFSIZE_MONO`; if the buffer is larger, then extra + * bytes are ignored. If the buffer is smaller, then this limits the + * capacity of the engine to support all allowed record sizes. + * + * If `bidi` is 1, then the engine will split the buffer into two + * parts, for separate handling of outgoing and incoming data. This + * enables full-duplex processing, but requires more RAM. The optimal + * buffer size in full-duplex mode is `BR_SSL_BUFSIZE_BIDI`; if the + * buffer is larger, then extra bytes are ignored. If the buffer is + * smaller, then the split will favour the incoming part, so that + * interoperability is maximised. + * + * \param cc SSL engine context + * \param iobuf I/O buffer. + * \param iobuf_len I/O buffer length (in bytes). + * \param bidi non-zero for full-duplex mode. + */ +void br_ssl_engine_set_buffer(br_ssl_engine_context *cc, + void *iobuf, size_t iobuf_len, int bidi); + +/** + * \brief Set the I/O buffers for the SSL engine. + * + * Once this call has been made, `br_ssl_client_reset()` or + * `br_ssl_server_reset()` MUST be called before using the context. + * + * This function is similar to `br_ssl_engine_set_buffer()`, except + * that it enforces full-duplex mode, and the two I/O buffers are + * provided as separate chunks. + * + * The macros `BR_SSL_BUFSIZE_INPUT` and `BR_SSL_BUFSIZE_OUTPUT` + * evaluate to the optimal (maximum) sizes for the input and output + * buffer, respectively. + * + * \param cc SSL engine context + * \param ibuf input buffer. + * \param ibuf_len input buffer length (in bytes). + * \param obuf output buffer. + * \param obuf_len output buffer length (in bytes). + */ +void br_ssl_engine_set_buffers_bidi(br_ssl_engine_context *cc, + void *ibuf, size_t ibuf_len, void *obuf, size_t obuf_len); + +/** + * \brief Inject some "initial entropy" in the context. + * + * This entropy will be added to what can be obtained from the + * underlying operating system, if that OS is supported. + * + * This function may be called several times; all injected entropy chunks + * are cumulatively mixed. + * + * If entropy gathering from the OS is supported and compiled in, then this + * step is optional. Otherwise, it is mandatory to inject randomness, and + * the caller MUST take care to push (as one or several successive calls) + * enough entropy to achieve cryptographic resistance (at least 80 bits, + * preferably 128 or more). The engine will report an error if no entropy + * was provided and none can be obtained from the OS. + * + * Take care that this function cannot assess the cryptographic quality of + * the provided bytes. + * + * In all generality, "entropy" must here be considered to mean "that + * which the attacker cannot predict". If your OS/architecture does not + * have a suitable source of randomness, then you can make do with the + * combination of a large enough secret value (possibly a copy of an + * asymmetric private key that you also store on the system) AND a + * non-repeating value (e.g. current time, provided that the local clock + * cannot be reset or altered by the attacker). + * + * \param cc SSL engine context. + * \param data extra entropy to inject. + * \param len length of the extra data (in bytes). + */ +void br_ssl_engine_inject_entropy(br_ssl_engine_context *cc, + const void *data, size_t len); + +/** + * \brief Get the "server name" in this engine. + * + * For clients, this is the name provided with `br_ssl_client_reset()`; + * for servers, this is the name received from the client as part of the + * ClientHello message. If there is no such name (e.g. the client did + * not send an SNI extension) then the returned string is empty + * (returned pointer points to a byte of value 0). + * + * The returned pointer refers to a buffer inside the context, which may + * be overwritten as part of normal SSL activity (even within the same + * connection, if a renegotiation occurs). + * + * \param cc SSL engine context. + * \return the server name (possibly empty). + */ +static __inline const char * +br_ssl_engine_get_server_name(const br_ssl_engine_context *cc) +{ + return cc->server_name; +} + +/** + * \brief Get the protocol version. + * + * This function returns the protocol version that is used by the + * engine. That value is set after sending (for a server) or receiving + * (for a client) the ServerHello message. + * + * \param cc SSL engine context. + * \return the protocol version. + */ +static __inline unsigned +br_ssl_engine_get_version(const br_ssl_engine_context *cc) +{ + return cc->session.version; +} + +/** + * \brief Get a copy of the session parameters. + * + * The session parameters are filled during the handshake, so this + * function shall not be called before completion of the handshake. + * The initial handshake is completed when the context first allows + * application data to be injected. + * + * This function copies the current session parameters into the provided + * structure. Beware that the session parameters include the master + * secret, which is sensitive data, to handle with great care. + * + * \param cc SSL engine context. + * \param pp destination structure for the session parameters. + */ +static __inline void +br_ssl_engine_get_session_parameters(const br_ssl_engine_context *cc, + br_ssl_session_parameters *pp) +{ + memcpy(pp, &cc->session, sizeof *pp); +} + +/** + * \brief Set the session parameters to the provided values. + * + * This function is meant to be used in the client, before doing a new + * handshake; a session resumption will be attempted with these + * parameters. In the server, this function has no effect. + * + * \param cc SSL engine context. + * \param pp source structure for the session parameters. + */ +static __inline void +br_ssl_engine_set_session_parameters(br_ssl_engine_context *cc, + const br_ssl_session_parameters *pp) +{ + memcpy(&cc->session, pp, sizeof *pp); +} + +/** + * \brief Get identifier for the curve used for key exchange. + * + * If the cipher suite uses ECDHE, then this function returns the + * identifier for the curve used for transient parameters. This is + * defined during the course of the handshake, when the ServerKeyExchange + * is sent (on the server) or received (on the client). If the + * cipher suite does not use ECDHE (e.g. static ECDH, or RSA key + * exchange), then this value is indeterminate. + * + * @param cc SSL engine context. + * @return the ECDHE curve identifier. + */ +static __inline int +br_ssl_engine_get_ecdhe_curve(br_ssl_engine_context *cc) +{ + return cc->ecdhe_curve; +} + +/** + * \brief Get the current engine state. + * + * An SSL engine (client or server) has, at any time, a state which is + * the combination of zero, one or more of these flags: + * + * - `BR_SSL_CLOSED` + * + * Engine is finished, no more I/O (until next reset). + * + * - `BR_SSL_SENDREC` + * + * Engine has some bytes to send to the peer. + * + * - `BR_SSL_RECVREC` + * + * Engine expects some bytes from the peer. + * + * - `BR_SSL_SENDAPP` + * + * Engine may receive application data to send (or flush). + * + * - `BR_SSL_RECVAPP` + * + * Engine has obtained some application data from the peer, + * that should be read by the caller. + * + * If no flag at all is set (state value is 0), then the engine is not + * fully initialised yet. + * + * The `BR_SSL_CLOSED` flag is exclusive; when it is set, no other flag + * is set. To distinguish between a normal closure and an error, use + * `br_ssl_engine_last_error()`. + * + * Generally speaking, `BR_SSL_SENDREC` and `BR_SSL_SENDAPP` are mutually + * exclusive: the input buffer, at any point, either accumulates + * plaintext data, or contains an assembled record that is being sent. + * Similarly, `BR_SSL_RECVREC` and `BR_SSL_RECVAPP` are mutually exclusive. + * This may change in a future library version. + * + * \param cc SSL engine context. + * \return the current engine state. + */ +unsigned br_ssl_engine_current_state(const br_ssl_engine_context *cc); + +/** \brief SSL engine state: closed or failed. */ +#define BR_SSL_CLOSED 0x0001 +/** \brief SSL engine state: record data is ready to be sent to the peer. */ +#define BR_SSL_SENDREC 0x0002 +/** \brief SSL engine state: engine may receive records from the peer. */ +#define BR_SSL_RECVREC 0x0004 +/** \brief SSL engine state: engine may accept application data to send. */ +#define BR_SSL_SENDAPP 0x0008 +/** \brief SSL engine state: engine has received application data. */ +#define BR_SSL_RECVAPP 0x0010 + +/** + * \brief Get the engine error indicator. + * + * The error indicator is `BR_ERR_OK` (0) if no error was encountered + * since the last call to `br_ssl_client_reset()` or + * `br_ssl_server_reset()`. Other status values are "sticky": they + * remain set, and prevent all I/O activity, until cleared. Only the + * reset calls clear the error indicator. + * + * \param cc SSL engine context. + * \return 0, or a non-zero error code. + */ +static __inline int +br_ssl_engine_last_error(const br_ssl_engine_context *cc) +{ + return cc->err; +} + +/* + * There are four I/O operations, each identified by a symbolic name: + * + * sendapp inject application data in the engine + * recvapp retrieving application data from the engine + * sendrec sending records on the transport medium + * recvrec receiving records from the transport medium + * + * Terminology works thus: in a layered model where the SSL engine sits + * between the application and the network, "send" designates operations + * where bytes flow from application to network, and "recv" for the + * reverse operation. Application data (the plaintext that is to be + * conveyed through SSL) is "app", while encrypted records are "rec". + * Note that from the SSL engine point of view, "sendapp" and "recvrec" + * designate bytes that enter the engine ("inject" operation), while + * "recvapp" and "sendrec" designate bytes that exit the engine + * ("extract" operation). + * + * For the operation 'xxx', two functions are defined: + * + * br_ssl_engine_xxx_buf + * Returns a pointer and length to the buffer to use for that + * operation. '*len' is set to the number of bytes that may be read + * from the buffer (extract operation) or written to the buffer + * (inject operation). If no byte may be exchanged for that operation + * at that point, then '*len' is set to zero, and NULL is returned. + * The engine state is unmodified by this call. + * + * br_ssl_engine_xxx_ack + * Informs the engine that 'len' bytes have been read from the buffer + * (extract operation) or written to the buffer (inject operation). + * The 'len' value MUST NOT be zero. The 'len' value MUST NOT exceed + * that which was obtained from a preceding br_ssl_engine_xxx_buf() + * call. + */ + +/** + * \brief Get buffer for application data to send. + * + * If the engine is ready to accept application data to send to the + * peer, then this call returns a pointer to the buffer where such + * data shall be written, and its length is written in `*len`. + * Otherwise, `*len` is set to 0 and `NULL` is returned. + * + * \param cc SSL engine context. + * \param len receives the application data output buffer length, or 0. + * \return the application data output buffer, or `NULL`. + */ +unsigned char *br_ssl_engine_sendapp_buf( + const br_ssl_engine_context *cc, size_t *len); + +/** + * \brief Inform the engine of some new application data. + * + * After writing `len` bytes in the buffer returned by + * `br_ssl_engine_sendapp_buf()`, the application shall call this + * function to trigger any relevant processing. The `len` parameter + * MUST NOT be 0, and MUST NOT exceed the value obtained in the + * `br_ssl_engine_sendapp_buf()` call. + * + * \param cc SSL engine context. + * \param len number of bytes pushed (not zero). + */ +void br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len); + +/** + * \brief Get buffer for received application data. + * + * If the engine has received application data from the peer, then this + * call returns a pointer to the buffer from where such data shall be + * read, and its length is written in `*len`. Otherwise, `*len` is set + * to 0 and `NULL` is returned. + * + * \param cc SSL engine context. + * \param len receives the application data input buffer length, or 0. + * \return the application data input buffer, or `NULL`. + */ +unsigned char *br_ssl_engine_recvapp_buf( + const br_ssl_engine_context *cc, size_t *len); + +/** + * \brief Acknowledge some received application data. + * + * After reading `len` bytes from the buffer returned by + * `br_ssl_engine_recvapp_buf()`, the application shall call this + * function to trigger any relevant processing. The `len` parameter + * MUST NOT be 0, and MUST NOT exceed the value obtained in the + * `br_ssl_engine_recvapp_buf()` call. + * + * \param cc SSL engine context. + * \param len number of bytes read (not zero). + */ +void br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len); + +/** + * \brief Get buffer for record data to send. + * + * If the engine has prepared some records to send to the peer, then this + * call returns a pointer to the buffer from where such data shall be + * read, and its length is written in `*len`. Otherwise, `*len` is set + * to 0 and `NULL` is returned. + * + * \param cc SSL engine context. + * \param len receives the record data output buffer length, or 0. + * \return the record data output buffer, or `NULL`. + */ +unsigned char *br_ssl_engine_sendrec_buf( + const br_ssl_engine_context *cc, size_t *len); + +/** + * \brief Acknowledge some sent record data. + * + * After reading `len` bytes from the buffer returned by + * `br_ssl_engine_sendrec_buf()`, the application shall call this + * function to trigger any relevant processing. The `len` parameter + * MUST NOT be 0, and MUST NOT exceed the value obtained in the + * `br_ssl_engine_sendrec_buf()` call. + * + * \param cc SSL engine context. + * \param len number of bytes read (not zero). + */ +void br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len); + +/** + * \brief Get buffer for incoming records. + * + * If the engine is ready to accept records from the peer, then this + * call returns a pointer to the buffer where such data shall be + * written, and its length is written in `*len`. Otherwise, `*len` is + * set to 0 and `NULL` is returned. + * + * \param cc SSL engine context. + * \param len receives the record data input buffer length, or 0. + * \return the record data input buffer, or `NULL`. + */ +unsigned char *br_ssl_engine_recvrec_buf( + const br_ssl_engine_context *cc, size_t *len); + +/** + * \brief Inform the engine of some new record data. + * + * After writing `len` bytes in the buffer returned by + * `br_ssl_engine_recvrec_buf()`, the application shall call this + * function to trigger any relevant processing. The `len` parameter + * MUST NOT be 0, and MUST NOT exceed the value obtained in the + * `br_ssl_engine_recvrec_buf()` call. + * + * \param cc SSL engine context. + * \param len number of bytes pushed (not zero). + */ +void br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len); + +/** + * \brief Flush buffered application data. + * + * If some application data has been buffered in the engine, then wrap + * it into a record and mark it for sending. If no application data has + * been buffered but the engine would be ready to accept some, AND the + * `force` parameter is non-zero, then an empty record is assembled and + * marked for sending. In all other cases, this function does nothing. + * + * Empty records are technically legal, but not all existing SSL/TLS + * implementations support them. Empty records can be useful as a + * transparent "keep-alive" mechanism to maintain some low-level + * network activity. + * + * \param cc SSL engine context. + * \param force non-zero to force sending an empty record. + */ +void br_ssl_engine_flush(br_ssl_engine_context *cc, int force); + +/** + * \brief Initiate a closure. + * + * If, at that point, the context is open and in ready state, then a + * `close_notify` alert is assembled and marked for sending; this + * triggers the closure protocol. Otherwise, no such alert is assembled. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_close(br_ssl_engine_context *cc); + +/** + * \brief Initiate a renegotiation. + * + * If the engine is failed or closed, or if the peer is known not to + * support secure renegotiation (RFC 5746), or if renegotiations have + * been disabled with the `BR_OPT_NO_RENEGOTIATION` flag, or if there + * is buffered incoming application data, then this function returns 0 + * and nothing else happens. + * + * Otherwise, this function returns 1, and a renegotiation attempt is + * triggered (if a handshake is already ongoing at that point, then + * no new handshake is triggered). + * + * \param cc SSL engine context. + * \return 1 on success, 0 on error. + */ +int br_ssl_engine_renegotiate(br_ssl_engine_context *cc); + +/** + * \brief Export key material from a connected SSL engine (RFC 5705). + * + * This calls compute a secret key of arbitrary length from the master + * secret of a connected SSL engine. If the provided context is not + * currently in "application data" state (initial handshake is not + * finished, another handshake is ongoing, or the connection failed or + * was closed), then this function returns 0. Otherwise, a secret key of + * length `len` bytes is computed and written in the buffer pointed to + * by `dst`, and 1 is returned. + * + * The computed key follows the specification described in RFC 5705. + * That RFC includes two key computations, with and without a "context + * value". If `context` is `NULL`, then the variant without context is + * used; otherwise, the `context_len` bytes located at the address + * pointed to by `context` are used in the computation. Note that it + * is possible to have a "with context" key with a context length of + * zero bytes, by setting `context` to a non-`NULL` value but + * `context_len` to 0. + * + * When context bytes are used, the context length MUST NOT exceed + * 65535 bytes. + * + * \param cc SSL engine context. + * \param dst destination buffer for exported key. + * \param len exported key length (in bytes). + * \param label disambiguation label. + * \param context context value (or `NULL`). + * \param context_len context length (in bytes). + * \return 1 on success, 0 on error. + */ +int br_ssl_key_export(br_ssl_engine_context *cc, + void *dst, size_t len, const char *label, + const void *context, size_t context_len); + +/* + * Pre-declaration for the SSL client context. + */ +typedef struct br_ssl_client_context_ br_ssl_client_context; + +/** + * \brief Type for the client certificate, if requested by the server. + */ +typedef struct { + /** + * \brief Authentication type. + * + * This is either `BR_AUTH_RSA` (RSA signature), `BR_AUTH_ECDSA` + * (ECDSA signature), or `BR_AUTH_ECDH` (static ECDH key exchange). + */ + int auth_type; + + /** + * \brief Hash function for computing the CertificateVerify. + * + * This is the symbolic identifier for the hash function that + * will be used to produce the hash of handshake messages, to + * be signed into the CertificateVerify. For full static ECDH + * (client and server certificates are both EC in the same + * curve, and static ECDH is used), this value is set to -1. + * + * Take care that with TLS 1.0 and 1.1, that value MUST match + * the protocol requirements: value must be 0 (MD5+SHA-1) for + * a RSA signature, or 2 (SHA-1) for an ECDSA signature. Only + * TLS 1.2 allows for other hash functions. + */ + int hash_id; + + /** + * \brief Certificate chain to send to the server. + * + * This is an array of `br_x509_certificate` objects, each + * normally containing a DER-encoded certificate. The client + * code does not try to decode these elements. If there is no + * chain to send to the server, then this pointer shall be + * set to `NULL`. + */ + const br_x509_certificate *chain; + + /** + * \brief Certificate chain length (number of certificates). + * + * If there is no chain to send to the server, then this value + * shall be set to 0. + */ + size_t chain_len; + +} br_ssl_client_certificate; + +/* + * Note: the constants below for signatures match the TLS constants. + */ + +/** \brief Client authentication type: static ECDH. */ +#define BR_AUTH_ECDH 0 +/** \brief Client authentication type: RSA signature. */ +#define BR_AUTH_RSA 1 +/** \brief Client authentication type: ECDSA signature. */ +#define BR_AUTH_ECDSA 3 + +/** + * \brief Class type for a certificate handler (client side). + * + * A certificate handler selects a client certificate chain to send to + * the server, upon explicit request from that server. It receives + * the list of trust anchor DN from the server, and supported types + * of certificates and signatures, and returns the chain to use. It + * is also invoked to perform the corresponding private key operation + * (a signature, or an ECDH computation). + * + * The SSL client engine will first push the trust anchor DN with + * `start_name_list()`, `start_name()`, `append_name()`, `end_name()` + * and `end_name_list()`. Then it will call `choose()`, to select the + * actual chain (and signature/hash algorithms). Finally, it will call + * either `do_sign()` or `do_keyx()`, depending on the algorithm choices. + */ +typedef struct br_ssl_client_certificate_class_ br_ssl_client_certificate_class; +struct br_ssl_client_certificate_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Begin reception of a list of trust anchor names. This + * is called while parsing the incoming CertificateRequest. + * + * \param pctx certificate handler context. + */ + void (*start_name_list)(const br_ssl_client_certificate_class **pctx); + + /** + * \brief Begin reception of a new trust anchor name. + * + * The total encoded name length is provided; it is less than + * 65535 bytes. + * + * \param pctx certificate handler context. + * \param len encoded name length (in bytes). + */ + void (*start_name)(const br_ssl_client_certificate_class **pctx, + size_t len); + + /** + * \brief Receive some more bytes for the current trust anchor name. + * + * The provided reference (`data`) points to a transient buffer + * they may be reused as soon as this function returns. The chunk + * length (`len`) is never zero. + * + * \param pctx certificate handler context. + * \param data anchor name chunk. + * \param len anchor name chunk length (in bytes). + */ + void (*append_name)(const br_ssl_client_certificate_class **pctx, + const unsigned char *data, size_t len); + + /** + * \brief End current trust anchor name. + * + * This function is called when all the encoded anchor name data + * has been provided. + * + * \param pctx certificate handler context. + */ + void (*end_name)(const br_ssl_client_certificate_class **pctx); + + /** + * \brief End list of trust anchor names. + * + * This function is called when all the anchor names in the + * CertificateRequest message have been obtained. + * + * \param pctx certificate handler context. + */ + void (*end_name_list)(const br_ssl_client_certificate_class **pctx); + + /** + * \brief Select client certificate and algorithms. + * + * This callback function shall fill the provided `choices` + * structure with the selected algorithms and certificate chain. + * The `hash_id`, `chain` and `chain_len` fields must be set. If + * the client cannot or does not wish to send a certificate, + * then it shall set `chain` to `NULL` and `chain_len` to 0. + * + * The `auth_types` parameter describes the authentication types, + * signature algorithms and hash functions that are supported by + * both the client context and the server, and compatible with + * the current protocol version. This is a bit field with the + * following contents: + * + * - If RSA signatures with hash function x are supported, then + * bit x is set. + * + * - If ECDSA signatures with hash function x are supported, + * then bit 8+x is set. + * + * - If static ECDH is supported, with a RSA-signed certificate, + * then bit 16 is set. + * + * - If static ECDH is supported, with an ECDSA-signed certificate, + * then bit 17 is set. + * + * Notes: + * + * - When using TLS 1.0 or 1.1, the hash function for RSA + * signatures is always the special MD5+SHA-1 (id 0), and the + * hash function for ECDSA signatures is always SHA-1 (id 2). + * + * - When using TLS 1.2, the list of hash functions is trimmed + * down to include only hash functions that the client context + * can support. The actual server list can be obtained with + * `br_ssl_client_get_server_hashes()`; that list may be used + * to select the certificate chain to send to the server. + * + * \param pctx certificate handler context. + * \param cc SSL client context. + * \param auth_types supported authentication types and algorithms. + * \param choices destination structure for the policy choices. + */ + void (*choose)(const br_ssl_client_certificate_class **pctx, + const br_ssl_client_context *cc, uint32_t auth_types, + br_ssl_client_certificate *choices); + + /** + * \brief Perform key exchange (client part). + * + * This callback is invoked in case of a full static ECDH key + * exchange: + * + * - the cipher suite uses `ECDH_RSA` or `ECDH_ECDSA`; + * + * - the server requests a client certificate; + * + * - the client has, and sends, a client certificate that + * uses an EC key in the same curve as the server's key, + * and chooses static ECDH (the `hash_id` field in the choice + * structure was set to -1). + * + * In that situation, this callback is invoked to compute the + * client-side ECDH: the provided `data` (of length `*len` bytes) + * is the server's public key point (as decoded from its + * certificate), and the client shall multiply that point with + * its own private key, and write back the X coordinate of the + * resulting point in the same buffer, starting at offset 0. + * The `*len` value shall be modified to designate the actual + * length of the X coordinate. + * + * The callback must uphold the following: + * + * - If the input array does not have the proper length for + * an encoded curve point, then an error (0) shall be reported. + * + * - If the input array has the proper length, then processing + * MUST be constant-time, even if the data is not a valid + * encoded point. + * + * - This callback MUST check that the input point is valid. + * + * Returned value is 1 on success, 0 on error. + * + * \param pctx certificate handler context. + * \param data server public key point. + * \param len public key point length / X coordinate length. + * \return 1 on success, 0 on error. + */ + uint32_t (*do_keyx)(const br_ssl_client_certificate_class **pctx, + unsigned char *data, size_t *len); + + /** + * \brief Perform a signature (client authentication). + * + * This callback is invoked when a client certificate was sent, + * and static ECDH is not used. It shall compute a signature, + * using the client's private key, over the provided hash value + * (which is the hash of all previous handshake messages). + * + * On input, the hash value to sign is in `data`, of size + * `hv_len`; the involved hash function is identified by + * `hash_id`. The signature shall be computed and written + * back into `data`; the total size of that buffer is `len` + * bytes. + * + * This callback shall verify that the signature length does not + * exceed `len` bytes, and abstain from writing the signature if + * it does not fit. + * + * For RSA signatures, the `hash_id` may be 0, in which case + * this is the special header-less signature specified in TLS 1.0 + * and 1.1, with a 36-byte hash value. Otherwise, normal PKCS#1 + * v1.5 signatures shall be computed. + * + * For ECDSA signatures, the signature value shall use the ASN.1 + * based encoding. + * + * Returned value is the signature length (in bytes), or 0 on error. + * + * \param pctx certificate handler context. + * \param hash_id hash function identifier. + * \param hv_len hash value length (in bytes). + * \param data input/output buffer (hash value, then signature). + * \param len total buffer length (in bytes). + * \return signature length (in bytes) on success, or 0 on error. + */ + size_t (*do_sign)(const br_ssl_client_certificate_class **pctx, + int hash_id, size_t hv_len, unsigned char *data, size_t len); +}; + +/** + * \brief A single-chain RSA client certificate handler. + * + * This handler uses a single certificate chain, with a RSA + * signature. The list of trust anchor DN is ignored. + * + * Apart from the first field (vtable pointer), its contents are + * opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_client_certificate_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + const br_x509_certificate *chain; + size_t chain_len; + const br_rsa_private_key *sk; + br_rsa_pkcs1_sign irsasign; +#endif +} br_ssl_client_certificate_rsa_context; + +/** + * \brief A single-chain EC client certificate handler. + * + * This handler uses a single certificate chain, with a RSA + * signature. The list of trust anchor DN is ignored. + * + * This handler may support both static ECDH, and ECDSA signatures + * (either usage may be selectively disabled). + * + * Apart from the first field (vtable pointer), its contents are + * opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_client_certificate_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + const br_x509_certificate *chain; + size_t chain_len; + const br_ec_private_key *sk; + unsigned allowed_usages; + unsigned issuer_key_type; + const br_multihash_context *mhash; + const br_ec_impl *iec; + br_ecdsa_sign iecdsa; +#endif +} br_ssl_client_certificate_ec_context; + +/** + * \brief Context structure for a SSL client. + * + * The first field (called `eng`) is the SSL engine; all functions that + * work on a `br_ssl_engine_context` structure shall take as parameter + * a pointer to that field. The other structure fields are opaque and + * must not be accessed directly. + */ +struct br_ssl_client_context_ { + /** + * \brief The encapsulated engine context. + */ + br_ssl_engine_context eng; + +#ifndef BR_DOXYGEN_IGNORE + /* + * Minimum ClientHello length; padding with an extension (RFC + * 7685) is added if necessary to match at least that length. + * Such padding is nominally unnecessary, but it has been used + * to work around some server implementation bugs. + */ + uint16_t min_clienthello_len; + + /* + * Bit field for algoithms (hash + signature) supported by the + * server when requesting a client certificate. + */ + uint32_t hashes; + + /* + * Server's public key curve. + */ + int server_curve; + + /* + * Context for certificate handler. + */ + const br_ssl_client_certificate_class **client_auth_vtable; + + /* + * Client authentication type. + */ + unsigned char auth_type; + + /* + * Hash function to use for the client signature. This is 0xFF + * if static ECDH is used. + */ + unsigned char hash_id; + + /* + * For the core certificate handlers, thus avoiding (in most + * cases) the need for an externally provided policy context. + */ + union { + const br_ssl_client_certificate_class *vtable; + br_ssl_client_certificate_rsa_context single_rsa; + br_ssl_client_certificate_ec_context single_ec; + } client_auth; + + /* + * Implementations. + */ + br_rsa_public irsapub; +#endif +}; + +/** + * \brief Get the hash functions and signature algorithms supported by + * the server. + * + * This value is a bit field: + * + * - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`, + * then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1, + * or 2 to 6 for the SHA family). + * + * - If ECDSA is supported with hash function of ID `x`, then bit `8+x` + * is set. + * + * - Newer algorithms are symbolic 16-bit identifiers that do not + * represent signature algorithm and hash function separately. If + * the TLS-level identifier is `0x0800+x` for a `x` in the 0..15 + * range, then bit `16+x` is set. + * + * "New algorithms" are currently defined only in draft documents, so + * this support is subject to possible change. Right now (early 2017), + * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA + * on Curve448) to bit 24. If the identifiers on the wire change in + * future document, then the decoding mechanism in BearSSL will be + * amended to keep mapping ed25519 and ed448 on bits 23 and 24, + * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not + * guaranteed yet. + * + * \param cc client context. + * \return the server-supported hash functions and signature algorithms. + */ +static __inline uint32_t +br_ssl_client_get_server_hashes(const br_ssl_client_context *cc) +{ + return cc->hashes; +} + +/** + * \brief Get the server key curve. + * + * This function returns the ID for the curve used by the server's public + * key. This is set when the server's certificate chain is processed; + * this value is 0 if the server's key is not an EC key. + * + * \return the server's public key curve ID, or 0. + */ +static __inline int +br_ssl_client_get_server_curve(const br_ssl_client_context *cc) +{ + return cc->server_curve; +} + +/* + * Each br_ssl_client_init_xxx() function sets the list of supported + * cipher suites and used implementations, as specified by the profile + * name 'xxx'. Defined profile names are: + * + * full all supported versions and suites; constant-time implementations + * TODO: add other profiles + */ + +/** + * \brief SSL client profile: full. + * + * This function initialises the provided SSL client context with + * all supported algorithms and cipher suites. It also initialises + * a companion X.509 validation engine with all supported algorithms, + * and the provided trust anchors; the X.509 engine will be used by + * the client context to validate the server's certificate. + * + * \param cc client context to initialise. + * \param xc X.509 validation context to initialise. + * \param trust_anchors trust anchors to use. + * \param trust_anchors_num number of trust anchors. + */ +void br_ssl_client_init_full(br_ssl_client_context *cc, + br_x509_minimal_context *xc, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); + +/** + * \brief Clear the complete contents of a SSL client context. + * + * Everything is cleared, including the reference to the configured buffer, + * implementations, cipher suites and state. This is a preparatory step + * to assembling a custom profile. + * + * \param cc client context to clear. + */ +void br_ssl_client_zero(br_ssl_client_context *cc); + +/** + * \brief Set an externally provided client certificate handler context. + * + * The handler's methods are invoked when the server requests a client + * certificate. + * + * \param cc client context. + * \param pctx certificate handler context (pointer to its vtable field). + */ +static __inline void +br_ssl_client_set_client_certificate(br_ssl_client_context *cc, + const br_ssl_client_certificate_class **pctx) +{ + cc->client_auth_vtable = pctx; +} + +/** + * \brief Set the RSA public-key operations implementation. + * + * This will be used to encrypt the pre-master secret with the server's + * RSA public key (RSA-encryption cipher suites only). + * + * \param cc client context. + * \param irsapub RSA public-key encryption implementation. + */ +static __inline void +br_ssl_client_set_rsapub(br_ssl_client_context *cc, br_rsa_public irsapub) +{ + cc->irsapub = irsapub; +} + +/** + * \brief Set the "default" RSA implementation for public-key operations. + * + * This sets the RSA implementation in the client context (for encrypting + * the pre-master secret, in `TLS_RSA_*` cipher suites) to the fastest + * available on the current platform. + * + * \param cc client context. + */ +void br_ssl_client_set_default_rsapub(br_ssl_client_context *cc); + +/** + * \brief Set the minimum ClientHello length (RFC 7685 padding). + * + * If this value is set and the ClientHello would be shorter, then + * the Pad ClientHello extension will be added with enough padding bytes + * to reach the target size. Because of the extension header, the resulting + * size will sometimes be slightly more than `len` bytes if the target + * size cannot be exactly met. + * + * The target length relates to the _contents_ of the ClientHello, not + * counting its 4-byte header. For instance, if `len` is set to 512, + * then the padding will bring the ClientHello size to 516 bytes with its + * header, and 521 bytes when counting the 5-byte record header. + * + * \param cc client context. + * \param len minimum ClientHello length (in bytes). + */ +static __inline void +br_ssl_client_set_min_clienthello_len(br_ssl_client_context *cc, uint16_t len) +{ + cc->min_clienthello_len = len; +} + +/** + * \brief Prepare or reset a client context for a new connection. + * + * The `server_name` parameter is used to fill the SNI extension; the + * X.509 "minimal" engine will also match that name against the server + * names included in the server's certificate. If the parameter is + * `NULL` then no SNI extension will be sent, and the X.509 "minimal" + * engine (if used for server certificate validation) will not check + * presence of any specific name in the received certificate. + * + * Therefore, setting the `server_name` to `NULL` shall be reserved + * to cases where alternate or additional methods are used to ascertain + * that the right server public key is used (e.g. a "known key" model). + * + * If `resume_session` is non-zero and the context was previously used + * then the session parameters may be reused (depending on whether the + * server previously sent a non-empty session ID, and accepts the session + * resumption). The session parameters for session resumption can also + * be set explicitly with `br_ssl_engine_set_session_parameters()`. + * + * On failure, the context is marked as failed, and this function + * returns 0. A possible failure condition is when no initial entropy + * was injected, and none could be obtained from the OS (either OS + * randomness gathering is not supported, or it failed). + * + * \param cc client context. + * \param server_name target server name, or `NULL`. + * \param resume_session non-zero to try session resumption. + * \return 0 on failure, 1 on success. + */ +int br_ssl_client_reset(br_ssl_client_context *cc, + const char *server_name, int resume_session); + +/** + * \brief Forget any session in the context. + * + * This means that the next handshake that uses this context will + * necessarily be a full handshake (this applies both to new connections + * and to renegotiations). + * + * \param cc client context. + */ +static __inline void +br_ssl_client_forget_session(br_ssl_client_context *cc) +{ + cc->eng.session.session_id_len = 0; + cc->eng.session.session_ticket_len = 0; +} + +/** + * \brief Set client certificate chain and key (single RSA case). + * + * This function sets a client certificate chain, that the client will + * send to the server whenever a client certificate is requested. This + * certificate uses an RSA public key; the corresponding private key is + * invoked for authentication. Trust anchor names sent by the server are + * ignored. + * + * The provided chain and private key are linked in the client context; + * they must remain valid as long as they may be used, i.e. normally + * for the duration of the connection, since they might be invoked + * again upon renegotiations. + * + * \param cc SSL client context. + * \param chain client certificate chain (SSL order: EE comes first). + * \param chain_len client chain length (number of certificates). + * \param sk client private key. + * \param irsasign RSA signature implementation (PKCS#1 v1.5). + */ +void br_ssl_client_set_single_rsa(br_ssl_client_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk, br_rsa_pkcs1_sign irsasign); + +/* + * \brief Set the client certificate chain and key (single EC case). + * + * This function sets a client certificate chain, that the client will + * send to the server whenever a client certificate is requested. This + * certificate uses an EC public key; the corresponding private key is + * invoked for authentication. Trust anchor names sent by the server are + * ignored. + * + * The provided chain and private key are linked in the client context; + * they must remain valid as long as they may be used, i.e. normally + * for the duration of the connection, since they might be invoked + * again upon renegotiations. + * + * The `allowed_usages` is a combination of usages, namely + * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`. The `BR_KEYTYPE_KEYX` + * value allows full static ECDH, while the `BR_KEYTYPE_SIGN` value + * allows ECDSA signatures. If ECDSA signatures are used, then an ECDSA + * signature implementation must be provided; otherwise, the `iecdsa` + * parameter may be 0. + * + * The `cert_issuer_key_type` value is either `BR_KEYTYPE_RSA` or + * `BR_KEYTYPE_EC`; it is the type of the public key used the the CA + * that issued (signed) the client certificate. That value is used with + * full static ECDH: support of the certificate by the server depends + * on how the certificate was signed. (Note: when using TLS 1.2, this + * parameter is ignored; but its value matters for TLS 1.0 and 1.1.) + * + * \param cc server context. + * \param chain server certificate chain to send. + * \param chain_len chain length (number of certificates). + * \param sk server private key (EC). + * \param allowed_usages allowed private key usages. + * \param cert_issuer_key_type issuing CA's key type. + * \param iec EC core implementation. + * \param iecdsa ECDSA signature implementation ("asn1" format). + */ +void br_ssl_client_set_single_ec(br_ssl_client_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk, unsigned allowed_usages, + unsigned cert_issuer_key_type, + const br_ec_impl *iec, br_ecdsa_sign iecdsa); + +/** + * \brief Type for a "translated cipher suite", as an array of two + * 16-bit integers. + * + * The first element is the cipher suite identifier (as used on the wire). + * The second element is the concatenation of four 4-bit elements which + * characterise the cipher suite contents. In most to least significant + * order, these 4-bit elements are: + * + * - Bits 12 to 15: key exchange + server key type + * + * | val | symbolic constant | suite type | details | + * | :-- | :----------------------- | :---------- | :----------------------------------------------- | + * | 0 | `BR_SSLKEYX_RSA` | RSA | RSA key exchange, key is RSA (encryption) | + * | 1 | `BR_SSLKEYX_ECDHE_RSA` | ECDHE_RSA | ECDHE key exchange, key is RSA (signature) | + * | 2 | `BR_SSLKEYX_ECDHE_ECDSA` | ECDHE_ECDSA | ECDHE key exchange, key is EC (signature) | + * | 3 | `BR_SSLKEYX_ECDH_RSA` | ECDH_RSA | Key is EC (key exchange), cert signed with RSA | + * | 4 | `BR_SSLKEYX_ECDH_ECDSA` | ECDH_ECDSA | Key is EC (key exchange), cert signed with ECDSA | + * + * - Bits 8 to 11: symmetric encryption algorithm + * + * | val | symbolic constant | symmetric encryption | key strength (bits) | + * | :-- | :--------------------- | :------------------- | :------------------ | + * | 0 | `BR_SSLENC_3DES_CBC` | 3DES/CBC | 168 | + * | 1 | `BR_SSLENC_AES128_CBC` | AES-128/CBC | 128 | + * | 2 | `BR_SSLENC_AES256_CBC` | AES-256/CBC | 256 | + * | 3 | `BR_SSLENC_AES128_GCM` | AES-128/GCM | 128 | + * | 4 | `BR_SSLENC_AES256_GCM` | AES-256/GCM | 256 | + * | 5 | `BR_SSLENC_CHACHA20` | ChaCha20/Poly1305 | 256 | + * + * - Bits 4 to 7: MAC algorithm + * + * | val | symbolic constant | MAC type | details | + * | :-- | :----------------- | :----------- | :------------------------------------ | + * | 0 | `BR_SSLMAC_AEAD` | AEAD | No dedicated MAC (encryption is AEAD) | + * | 2 | `BR_SSLMAC_SHA1` | HMAC/SHA-1 | Value matches `br_sha1_ID` | + * | 4 | `BR_SSLMAC_SHA256` | HMAC/SHA-256 | Value matches `br_sha256_ID` | + * | 5 | `BR_SSLMAC_SHA384` | HMAC/SHA-384 | Value matches `br_sha384_ID` | + * + * - Bits 0 to 3: hash function for PRF when used with TLS-1.2 + * + * | val | symbolic constant | hash function | details | + * | :-- | :----------------- | :------------ | :----------------------------------- | + * | 4 | `BR_SSLPRF_SHA256` | SHA-256 | Value matches `br_sha256_ID` | + * | 5 | `BR_SSLPRF_SHA384` | SHA-384 | Value matches `br_sha384_ID` | + * + * For instance, cipher suite `TLS_RSA_WITH_AES_128_GCM_SHA256` has + * standard identifier 0x009C, and is translated to 0x0304, for, in + * that order: RSA key exchange (0), AES-128/GCM (3), AEAD integrity (0), + * SHA-256 in the TLS PRF (4). + */ +typedef uint16_t br_suite_translated[2]; + +#ifndef BR_DOXYGEN_IGNORE +/* + * Constants are already documented in the br_suite_translated type. + */ + +#define BR_SSLKEYX_RSA 0 +#define BR_SSLKEYX_ECDHE_RSA 1 +#define BR_SSLKEYX_ECDHE_ECDSA 2 +#define BR_SSLKEYX_ECDH_RSA 3 +#define BR_SSLKEYX_ECDH_ECDSA 4 + +#define BR_SSLENC_3DES_CBC 0 +#define BR_SSLENC_AES128_CBC 1 +#define BR_SSLENC_AES256_CBC 2 +#define BR_SSLENC_AES128_GCM 3 +#define BR_SSLENC_AES256_GCM 4 +#define BR_SSLENC_CHACHA20 5 + +#define BR_SSLMAC_AEAD 0 +#define BR_SSLMAC_SHA1 br_sha1_ID +#define BR_SSLMAC_SHA256 br_sha256_ID +#define BR_SSLMAC_SHA384 br_sha384_ID + +#define BR_SSLPRF_SHA256 br_sha256_ID +#define BR_SSLPRF_SHA384 br_sha384_ID + +#endif + +/* + * Pre-declaration for the SSL server context. + */ +typedef struct br_ssl_server_context_ br_ssl_server_context; + +/** + * \brief Type for the server policy choices, taken after analysis of + * the client message (ClientHello). + */ +typedef struct { + /** + * \brief Cipher suite to use with that client. + */ + uint16_t cipher_suite; + + /** + * \brief Hash function or algorithm for signing the ServerKeyExchange. + * + * This parameter is ignored for `TLS_RSA_*` and `TLS_ECDH_*` + * cipher suites; it is used only for `TLS_ECDHE_*` suites, in + * which the server _signs_ the ephemeral EC Diffie-Hellman + * parameters sent to the client. + * + * This identifier must be one of the following values: + * + * - `0xFF00 + id`, where `id` is a hash function identifier + * (0 for MD5+SHA-1, or 2 to 6 for one of the SHA functions); + * + * - a full 16-bit identifier, lower than `0xFF00`. + * + * If the first option is used, then the SSL engine will + * compute the hash of the data that is to be signed, with the + * designated hash function. The `do_sign()` method will be + * invoked with that hash value provided in the the `data` + * buffer. + * + * If the second option is used, then the SSL engine will NOT + * compute a hash on the data; instead, it will provide the + * to-be-signed data itself in `data`, i.e. the concatenation of + * the client random, server random, and encoded ECDH + * parameters. Furthermore, with TLS-1.2 and later, the 16-bit + * identifier will be used "as is" in the protocol, in the + * SignatureAndHashAlgorithm; for instance, `0x0401` stands for + * RSA PKCS#1 v1.5 signature (the `01`) with SHA-256 as hash + * function (the `04`). + * + * Take care that with TLS 1.0 and 1.1, the hash function is + * constrainted by the protocol: RSA signature must use + * MD5+SHA-1 (so use `0xFF00`), while ECDSA must use SHA-1 + * (`0xFF02`). Since TLS 1.0 and 1.1 don't include a + * SignatureAndHashAlgorithm field in their ServerKeyExchange + * messages, any value below `0xFF00` will be usable to send the + * raw ServerKeyExchange data to the `do_sign()` callback, but + * that callback must still follow the protocol requirements + * when generating the signature. + */ + unsigned algo_id; + + /** + * \brief Certificate chain to send to the client. + * + * This is an array of `br_x509_certificate` objects, each + * normally containing a DER-encoded certificate. The server + * code does not try to decode these elements. + */ + const br_x509_certificate *chain; + + /** + * \brief Certificate chain length (number of certificates). + */ + size_t chain_len; + +} br_ssl_server_choices; + +/** + * \brief Class type for a policy handler (server side). + * + * A policy handler selects the policy parameters for a connection + * (cipher suite and other algorithms, and certificate chain to send to + * the client); it also performs the server-side computations involving + * its permanent private key. + * + * The SSL server engine will invoke first `choose()`, once the + * ClientHello message has been received, then either `do_keyx()` + * `do_sign()`, depending on the cipher suite. + */ +typedef struct br_ssl_server_policy_class_ br_ssl_server_policy_class; +struct br_ssl_server_policy_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Select algorithms and certificates for this connection. + * + * This callback function shall fill the provided `choices` + * structure with the policy choices for this connection. This + * entails selecting the cipher suite, hash function for signing + * the ServerKeyExchange (applicable only to ECDHE cipher suites), + * and certificate chain to send. + * + * The callback receives a pointer to the server context that + * contains the relevant data. In particular, the functions + * `br_ssl_server_get_client_suites()`, + * `br_ssl_server_get_client_hashes()` and + * `br_ssl_server_get_client_curves()` can be used to obtain + * the cipher suites, hash functions and elliptic curves + * supported by both the client and server, respectively. The + * `br_ssl_engine_get_version()` and `br_ssl_engine_get_server_name()` + * functions yield the protocol version and requested server name + * (SNI), respectively. + * + * This function may modify its context structure (`pctx`) in + * arbitrary ways to keep track of its own choices. + * + * This function shall return 1 if appropriate policy choices + * could be made, or 0 if this connection cannot be pursued. + * + * \param pctx policy context. + * \param cc SSL server context. + * \param choices destination structure for the policy choices. + * \return 1 on success, 0 on error. + */ + int (*choose)(const br_ssl_server_policy_class **pctx, + const br_ssl_server_context *cc, + br_ssl_server_choices *choices); + + /** + * \brief Perform key exchange (server part). + * + * This callback is invoked to perform the server-side cryptographic + * operation for a key exchange that is not ECDHE. This callback + * uses the private key. + * + * **For RSA key exchange**, the provided `data` (of length `*len` + * bytes) shall be decrypted with the server's private key, and + * the 48-byte premaster secret copied back to the first 48 bytes + * of `data`. + * + * - The caller makes sure that `*len` is at least 59 bytes. + * + * - This callback MUST check that the provided length matches + * that of the key modulus; it shall report an error otherwise. + * + * - If the length matches that of the RSA key modulus, then + * processing MUST be constant-time, even if decryption fails, + * or the padding is incorrect, or the plaintext message length + * is not exactly 48 bytes. + * + * - This callback needs not check the two first bytes of the + * obtained pre-master secret (the caller will do that). + * + * - If an error is reported (0), then what the callback put + * in the first 48 bytes of `data` is unimportant (the caller + * will use random bytes instead). + * + * **For ECDH key exchange**, the provided `data` (of length `*len` + * bytes) is the elliptic curve point from the client. The + * callback shall multiply it with its private key, and store + * the resulting X coordinate in `data`, starting at offset 0, + * and set `*len` to the length of the X coordinate. + * + * - If the input array does not have the proper length for + * an encoded curve point, then an error (0) shall be reported. + * + * - If the input array has the proper length, then processing + * MUST be constant-time, even if the data is not a valid + * encoded point. + * + * - This callback MUST check that the input point is valid. + * + * Returned value is 1 on success, 0 on error. + * + * \param pctx policy context. + * \param data key exchange data from the client. + * \param len key exchange data length (in bytes). + * \return 1 on success, 0 on error. + */ + uint32_t (*do_keyx)(const br_ssl_server_policy_class **pctx, + unsigned char *data, size_t *len); + + /** + * \brief Perform a signature (for a ServerKeyExchange message). + * + * This callback function is invoked for ECDHE cipher suites. On + * input, the hash value or message to sign is in `data`, of + * size `hv_len`; the involved hash function or algorithm is + * identified by `algo_id`. The signature shall be computed and + * written back into `data`; the total size of that buffer is + * `len` bytes. + * + * This callback shall verify that the signature length does not + * exceed `len` bytes, and abstain from writing the signature if + * it does not fit. + * + * The `algo_id` value matches that which was written in the + * `choices` structures by the `choose()` callback. This will be + * one of the following: + * + * - `0xFF00 + id` for a hash function identifier `id`. In + * that case, the `data` buffer contains a hash value + * already computed over the data that is to be signed, + * of length `hv_len`. The `id` may be 0 to designate the + * special MD5+SHA-1 concatenation (old-style RSA signing). + * + * - Another value, lower than `0xFF00`. The `data` buffer + * then contains the raw, non-hashed data to be signed + * (concatenation of the client and server randoms and + * ECDH parameters). The callback is responsible to apply + * any relevant hashing as part of the signing process. + * + * Returned value is the signature length (in bytes), or 0 on error. + * + * \param pctx policy context. + * \param algo_id hash function / algorithm identifier. + * \param data input/output buffer (message/hash, then signature). + * \param hv_len hash value or message length (in bytes). + * \param len total buffer length (in bytes). + * \return signature length (in bytes) on success, or 0 on error. + */ + size_t (*do_sign)(const br_ssl_server_policy_class **pctx, + unsigned algo_id, + unsigned char *data, size_t hv_len, size_t len); +}; + +/** + * \brief A single-chain RSA policy handler. + * + * This policy context uses a single certificate chain, and a RSA + * private key. The context can be restricted to only signatures or + * only key exchange. + * + * Apart from the first field (vtable pointer), its contents are + * opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_server_policy_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + const br_x509_certificate *chain; + size_t chain_len; + const br_rsa_private_key *sk; + unsigned allowed_usages; + br_rsa_private irsacore; + br_rsa_pkcs1_sign irsasign; +#endif +} br_ssl_server_policy_rsa_context; + +/** + * \brief A single-chain EC policy handler. + * + * This policy context uses a single certificate chain, and an EC + * private key. The context can be restricted to only signatures or + * only key exchange. + * + * Due to how TLS is defined, this context must be made aware whether + * the server certificate was itself signed with RSA or ECDSA. The code + * does not try to decode the certificate to obtain that information. + * + * Apart from the first field (vtable pointer), its contents are + * opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_server_policy_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + const br_x509_certificate *chain; + size_t chain_len; + const br_ec_private_key *sk; + unsigned allowed_usages; + unsigned cert_issuer_key_type; + const br_multihash_context *mhash; + const br_ec_impl *iec; + br_ecdsa_sign iecdsa; +#endif +} br_ssl_server_policy_ec_context; + +/** + * \brief Class type for a session parameter cache. + * + * Session parameters are saved in the cache with `save()`, and + * retrieved with `load()`. The cache implementation can apply any + * storage and eviction strategy that it sees fit. The SSL server + * context that performs the request is provided, so that its + * functionalities may be used by the implementation (e.g. hash + * functions or random number generation). + */ +typedef struct br_ssl_session_cache_class_ br_ssl_session_cache_class; +struct br_ssl_session_cache_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Record a session. + * + * This callback should record the provided session parameters. + * The `params` structure is transient, so its contents shall + * be copied into the cache. The session ID has been randomly + * generated and always has length exactly 32 bytes. + * + * \param ctx session cache context. + * \param server_ctx SSL server context. + * \param params session parameters to save. + */ + void (*save)(const br_ssl_session_cache_class **ctx, + br_ssl_server_context *server_ctx, + const br_ssl_session_parameters *params); + + /** + * \brief Lookup a session in the cache. + * + * The session ID to lookup is in `params` and always has length + * exactly 32 bytes. If the session parameters are found in the + * cache, then the parameters shall be copied into the `params` + * structure. Returned value is 1 on successful lookup, 0 + * otherwise. + * + * \param ctx session cache context. + * \param server_ctx SSL server context. + * \param params destination for session parameters. + * \return 1 if found, 0 otherwise. + */ + int (*load)(const br_ssl_session_cache_class **ctx, + br_ssl_server_context *server_ctx, + br_ssl_session_parameters *params); +}; + +/** + * \brief Context for a basic cache system. + * + * The system stores session parameters in a buffer provided at + * initialisation time. Each entry uses exactly 100 bytes, and + * buffer sizes up to 4294967295 bytes are supported. + * + * Entries are evicted with a LRU (Least Recently Used) policy. A + * search tree is maintained to keep lookups fast even with large + * caches. + * + * Apart from the first field (vtable pointer), the structure + * contents are opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_session_cache_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char *store; + size_t store_len, store_ptr; + unsigned char index_key[32]; + const br_hash_class *hash; + int init_done; + uint32_t head, tail, root; +#endif +} br_ssl_session_cache_lru; + +/** + * \brief Initialise a LRU session cache with the provided storage space. + * + * The provided storage space must remain valid as long as the cache + * is used. Arbitrary lengths are supported, up to 4294967295 bytes; + * each entry uses up exactly 100 bytes. + * + * \param cc session cache context. + * \param store storage space for cached entries. + * \param store_len storage space length (in bytes). + */ +void br_ssl_session_cache_lru_init(br_ssl_session_cache_lru *cc, + unsigned char *store, size_t store_len); + +/** + * \brief Forget an entry in an LRU session cache. + * + * The session cache context must have been initialised. The entry + * with the provided session ID (of exactly 32 bytes) is looked for + * in the cache; if located, it is disabled. + * + * \param cc session cache context. + * \param id session ID to forget. + */ +void br_ssl_session_cache_lru_forget( + br_ssl_session_cache_lru *cc, const unsigned char *id); + +/** + * \brief Context structure for a SSL server. + * + * The first field (called `eng`) is the SSL engine; all functions that + * work on a `br_ssl_engine_context` structure shall take as parameter + * a pointer to that field. The other structure fields are opaque and + * must not be accessed directly. + */ +struct br_ssl_server_context_ { + /** + * \brief The encapsulated engine context. + */ + br_ssl_engine_context eng; + +#ifndef BR_DOXYGEN_IGNORE + /* + * Maximum version from the client. + */ + uint16_t client_max_version; + + /* + * Session cache. + */ + const br_ssl_session_cache_class **cache_vtable; + + /* + * Translated cipher suites supported by the client. The list + * is trimmed to include only the cipher suites that the + * server also supports; they are in the same order as in the + * client message. + */ + br_suite_translated client_suites[BR_MAX_CIPHER_SUITES]; + unsigned char client_suites_num; + + /* + * Hash functions supported by the client, with ECDSA and RSA + * (bit mask). For hash function with id 'x', set bit index is + * x for RSA, x+8 for ECDSA. For newer algorithms, with ID + * 0x08**, bit 16+k is set for algorithm 0x0800+k. + */ + uint32_t hashes; + + /* + * Curves supported by the client (bit mask, for named curves). + */ + uint32_t curves; + + /* + * Context for chain handler. + */ + const br_ssl_server_policy_class **policy_vtable; + uint16_t sign_hash_id; + + /* + * For the core handlers, thus avoiding (in most cases) the + * need for an externally provided policy context. + */ + union { + const br_ssl_server_policy_class *vtable; + br_ssl_server_policy_rsa_context single_rsa; + br_ssl_server_policy_ec_context single_ec; + } chain_handler; + + /* + * Buffer for the ECDHE private key. + */ + unsigned char ecdhe_key[70]; + size_t ecdhe_key_len; + + /* + * Trust anchor names for client authentication. "ta_names" and + * "tas" cannot be both non-NULL. + */ + const br_x500_name *ta_names; + const br_x509_trust_anchor *tas; + size_t num_tas; + size_t cur_dn_index; + const unsigned char *cur_dn; + size_t cur_dn_len; + + /* + * Buffer for the hash value computed over all handshake messages + * prior to CertificateVerify, and identifier for the hash function. + */ + unsigned char hash_CV[64]; + size_t hash_CV_len; + int hash_CV_id; + + /* + * Server-specific implementations. + * (none for now) + */ +#endif +}; + +/* + * Each br_ssl_server_init_xxx() function sets the list of supported + * cipher suites and used implementations, as specified by the profile + * name 'xxx'. Defined profile names are: + * + * full_rsa all supported algorithm, server key type is RSA + * full_ec all supported algorithm, server key type is EC + * TODO: add other profiles + * + * Naming scheme for "minimal" profiles: min123 + * + * -- character 1: key exchange + * r = RSA + * e = ECDHE_RSA + * f = ECDHE_ECDSA + * u = ECDH_RSA + * v = ECDH_ECDSA + * -- character 2: version / PRF + * 0 = TLS 1.0 / 1.1 with MD5+SHA-1 + * 2 = TLS 1.2 with SHA-256 + * 3 = TLS 1.2 with SHA-384 + * -- character 3: encryption + * a = AES/CBC + * d = 3DES/CBC + * g = AES/GCM + * c = ChaCha20+Poly1305 + */ + +/** + * \brief SSL server profile: full_rsa. + * + * This function initialises the provided SSL server context with + * all supported algorithms and cipher suites that rely on a RSA + * key pair. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_full_rsa(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: full_ec. + * + * This function initialises the provided SSL server context with + * all supported algorithms and cipher suites that rely on an EC + * key pair. + * + * The key type of the CA that issued the server's certificate must + * be provided, since it matters for ECDH cipher suites (ECDH_RSA + * suites require a RSA-powered CA). The key type is either + * `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len chain length (number of certificates). + * \param cert_issuer_key_type certificate issuer's key type. + * \param sk EC private key. + */ +void br_ssl_server_init_full_ec(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + unsigned cert_issuer_key_type, const br_ec_private_key *sk); + +/** + * \brief SSL server profile: minr2g. + * + * This profile uses only TLS_RSA_WITH_AES_128_GCM_SHA256. Server key is + * RSA, and RSA key exchange is used (not forward secure, but uses little + * CPU in the client). + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_minr2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: mine2g. + * + * This profile uses only TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256. Server key + * is RSA, and ECDHE key exchange is used. This suite provides forward + * security, with a higher CPU expense on the client, and a somewhat + * larger code footprint (compared to "minr2g"). + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_mine2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: minf2g. + * + * This profile uses only TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256. + * Server key is EC, and ECDHE key exchange is used. This suite provides + * forward security, with a higher CPU expense on the client and server + * (by a factor of about 3 to 4), and a somewhat larger code footprint + * (compared to "minu2g" and "minv2g"). + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minf2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + +/** + * \brief SSL server profile: minu2g. + * + * This profile uses only TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256. + * Server key is EC, and ECDH key exchange is used; the issuing CA used + * a RSA key. + * + * The "minu2g" and "minv2g" profiles do not provide forward secrecy, + * but are the lightest on the server (for CPU usage), and are rather + * inexpensive on the client as well. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minu2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + +/** + * \brief SSL server profile: minv2g. + * + * This profile uses only TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256. + * Server key is EC, and ECDH key exchange is used; the issuing CA used + * an EC key. + * + * The "minu2g" and "minv2g" profiles do not provide forward secrecy, + * but are the lightest on the server (for CPU usage), and are rather + * inexpensive on the client as well. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minv2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + +/** + * \brief SSL server profile: mine2c. + * + * This profile uses only TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256. + * Server key is RSA, and ECDHE key exchange is used. This suite + * provides forward security. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_mine2c(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: minf2c. + * + * This profile uses only TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256. + * Server key is EC, and ECDHE key exchange is used. This suite provides + * forward security. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minf2c(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + +/** + * \brief Get the supported client suites. + * + * This function shall be called only after the ClientHello has been + * processed, typically from the policy engine. The returned array + * contains the cipher suites that are supported by both the client + * and the server; these suites are in client preference order, unless + * the `BR_OPT_ENFORCE_SERVER_PREFERENCES` flag was set, in which case + * they are in server preference order. + * + * The suites are _translated_, which means that each suite is given + * as two 16-bit integers: the standard suite identifier, and its + * translated version, broken down into its individual components, + * as explained with the `br_suite_translated` type. + * + * The returned array is allocated in the context and will be rewritten + * by each handshake. + * + * \param cc server context. + * \param num receives the array size (number of suites). + * \return the translated common cipher suites, in preference order. + */ +static __inline const br_suite_translated * +br_ssl_server_get_client_suites(const br_ssl_server_context *cc, size_t *num) +{ + *num = cc->client_suites_num; + return cc->client_suites; +} + +/** + * \brief Get the hash functions and signature algorithms supported by + * the client. + * + * This value is a bit field: + * + * - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`, + * then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1, + * or 2 to 6 for the SHA family). + * + * - If ECDSA is supported with hash function of ID `x`, then bit `8+x` + * is set. + * + * - Newer algorithms are symbolic 16-bit identifiers that do not + * represent signature algorithm and hash function separately. If + * the TLS-level identifier is `0x0800+x` for a `x` in the 0..15 + * range, then bit `16+x` is set. + * + * "New algorithms" are currently defined only in draft documents, so + * this support is subject to possible change. Right now (early 2017), + * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA + * on Curve448) to bit 24. If the identifiers on the wire change in + * future document, then the decoding mechanism in BearSSL will be + * amended to keep mapping ed25519 and ed448 on bits 23 and 24, + * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not + * guaranteed yet. + * + * \param cc server context. + * \return the client-supported hash functions and signature algorithms. + */ +static __inline uint32_t +br_ssl_server_get_client_hashes(const br_ssl_server_context *cc) +{ + return cc->hashes; +} + +/** + * \brief Get the elliptic curves supported by the client. + * + * This is a bit field (bit x is set if curve of ID x is supported). + * + * \param cc server context. + * \return the client-supported elliptic curves. + */ +static __inline uint32_t +br_ssl_server_get_client_curves(const br_ssl_server_context *cc) +{ + return cc->curves; +} + +/** + * \brief Clear the complete contents of a SSL server context. + * + * Everything is cleared, including the reference to the configured buffer, + * implementations, cipher suites and state. This is a preparatory step + * to assembling a custom profile. + * + * \param cc server context to clear. + */ +void br_ssl_server_zero(br_ssl_server_context *cc); + +/** + * \brief Set an externally provided policy context. + * + * The policy context's methods are invoked to decide the cipher suite + * and certificate chain, and to perform operations involving the server's + * private key. + * + * \param cc server context. + * \param pctx policy context (pointer to its vtable field). + */ +static __inline void +br_ssl_server_set_policy(br_ssl_server_context *cc, + const br_ssl_server_policy_class **pctx) +{ + cc->policy_vtable = pctx; +} + +/** + * \brief Set the server certificate chain and key (single RSA case). + * + * This function uses a policy context included in the server context. + * It configures use of a single server certificate chain with a RSA + * private key. The `allowed_usages` is a combination of usages, namely + * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`; this enables or disables + * the corresponding cipher suites (i.e. `TLS_RSA_*` use the RSA key for + * key exchange, while `TLS_ECDHE_RSA_*` use the RSA key for signatures). + * + * \param cc server context. + * \param chain server certificate chain to send to the client. + * \param chain_len chain length (number of certificates). + * \param sk server private key (RSA). + * \param allowed_usages allowed private key usages. + * \param irsacore RSA core implementation. + * \param irsasign RSA signature implementation (PKCS#1 v1.5). + */ +void br_ssl_server_set_single_rsa(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk, unsigned allowed_usages, + br_rsa_private irsacore, br_rsa_pkcs1_sign irsasign); + +/** + * \brief Set the server certificate chain and key (single EC case). + * + * This function uses a policy context included in the server context. + * It configures use of a single server certificate chain with an EC + * private key. The `allowed_usages` is a combination of usages, namely + * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`; this enables or disables + * the corresponding cipher suites (i.e. `TLS_ECDH_*` use the EC key for + * key exchange, while `TLS_ECDHE_ECDSA_*` use the EC key for signatures). + * + * In order to support `TLS_ECDH_*` cipher suites (non-ephemeral ECDH), + * the algorithm type of the key used by the issuing CA to sign the + * server's certificate must be provided, as `cert_issuer_key_type` + * parameter (this value is either `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`). + * + * \param cc server context. + * \param chain server certificate chain to send. + * \param chain_len chain length (number of certificates). + * \param sk server private key (EC). + * \param allowed_usages allowed private key usages. + * \param cert_issuer_key_type issuing CA's key type. + * \param iec EC core implementation. + * \param iecdsa ECDSA signature implementation ("asn1" format). + */ +void br_ssl_server_set_single_ec(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk, unsigned allowed_usages, + unsigned cert_issuer_key_type, + const br_ec_impl *iec, br_ecdsa_sign iecdsa); + +/** + * \brief Activate client certificate authentication. + * + * The trust anchor encoded X.500 names (DN) to send to the client are + * provided. A client certificate will be requested and validated through + * the X.509 validator configured in the SSL engine. If `num` is 0, then + * client certificate authentication is disabled. + * + * If the client does not send a certificate, or on validation failure, + * the handshake aborts. Unauthenticated clients can be tolerated by + * setting the `BR_OPT_TOLERATE_NO_CLIENT_AUTH` flag. + * + * The provided array is linked in, not copied, so that pointer must + * remain valid as long as anchor names may be used. + * + * \param cc server context. + * \param ta_names encoded trust anchor names. + * \param num number of encoded trust anchor names. + */ +static __inline void +br_ssl_server_set_trust_anchor_names(br_ssl_server_context *cc, + const br_x500_name *ta_names, size_t num) +{ + cc->ta_names = ta_names; + cc->tas = NULL; + cc->num_tas = num; +} + +/** + * \brief Activate client certificate authentication. + * + * This is a variant for `br_ssl_server_set_trust_anchor_names()`: the + * trust anchor names are provided not as an array of stand-alone names + * (`br_x500_name` structures), but as an array of trust anchors + * (`br_x509_trust_anchor` structures). The server engine itself will + * only use the `dn` field of each trust anchor. This is meant to allow + * defining a single array of trust anchors, to be used here and in the + * X.509 validation engine itself. + * + * The provided array is linked in, not copied, so that pointer must + * remain valid as long as anchor names may be used. + * + * \param cc server context. + * \param tas trust anchors (only names are used). + * \param num number of trust anchors. + */ +static __inline void +br_ssl_server_set_trust_anchor_names_alt(br_ssl_server_context *cc, + const br_x509_trust_anchor *tas, size_t num) +{ + cc->ta_names = NULL; + cc->tas = tas; + cc->num_tas = num; +} + +/** + * \brief Configure the cache for session parameters. + * + * The cache context is provided as a pointer to its first field (vtable + * pointer). + * + * \param cc server context. + * \param vtable session cache context. + */ +static __inline void +br_ssl_server_set_cache(br_ssl_server_context *cc, + const br_ssl_session_cache_class **vtable) +{ + cc->cache_vtable = vtable; +} + +/** + * \brief Prepare or reset a server context for handling an incoming client. + * + * \param cc server context. + * \return 1 on success, 0 on error. + */ +int br_ssl_server_reset(br_ssl_server_context *cc); + +/* ===================================================================== */ + +/* + * Context for the simplified I/O context. The transport medium is accessed + * through the low_read() and low_write() callback functions, each with + * its own opaque context pointer. + * + * low_read() read some bytes, at most 'len' bytes, into data[]. The + * returned value is the number of read bytes, or -1 on error. + * The 'len' parameter is guaranteed never to exceed 20000, + * so the length always fits in an 'int' on all platforms. + * + * low_write() write up to 'len' bytes, to be read from data[]. The + * returned value is the number of written bytes, or -1 on + * error. The 'len' parameter is guaranteed never to exceed + * 20000, so the length always fits in an 'int' on all + * parameters. + * + * A socket closure (if the transport medium is a socket) should be reported + * as an error (-1). The callbacks shall endeavour to block until at least + * one byte can be read or written; a callback returning 0 at times is + * acceptable, but this normally leads to the callback being immediately + * called again, so the callback should at least always try to block for + * some time if no I/O can take place. + * + * The SSL engine naturally applies some buffering, so the callbacks need + * not apply buffers of their own. + */ +/** + * \brief Context structure for the simplified SSL I/O wrapper. + * + * This structure is initialised with `br_sslio_init()`. Its contents + * are opaque and shall not be accessed directly. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + br_ssl_engine_context *engine; + int (*low_read)(void *read_context, + unsigned char *data, size_t len); + void *read_context; + int (*low_write)(void *write_context, + const unsigned char *data, size_t len); + void *write_context; +#endif +} br_sslio_context; + +/** + * \brief Initialise a simplified I/O wrapper context. + * + * The simplified I/O wrapper offers a simpler read/write API for a SSL + * engine (client or server), using the provided callback functions for + * reading data from, or writing data to, the transport medium. + * + * The callback functions have the following semantics: + * + * - Each callback receives an opaque context value (of type `void *`) + * that the callback may use arbitrarily (or possibly ignore). + * + * - `low_read()` reads at least one byte, at most `len` bytes, from + * the transport medium. Read bytes shall be written in `data`. + * + * - `low_write()` writes at least one byte, at most `len` bytes, unto + * the transport medium. The bytes to write are read from `data`. + * + * - The `len` parameter is never zero, and is always lower than 20000. + * + * - The number of processed bytes (read or written) is returned. Since + * that number is less than 20000, it always fits on an `int`. + * + * - On error, the callbacks return -1. Reaching end-of-stream is an + * error. Errors are permanent: the SSL connection is terminated. + * + * - Callbacks SHOULD NOT return 0. This is tolerated, as long as + * callbacks endeavour to block for some non-negligible amount of + * time until at least one byte can be sent or received (if a + * callback returns 0, then the wrapper invokes it again + * immediately). + * + * - Callbacks MAY return as soon as at least one byte is processed; + * they MAY also insist on reading or writing _all_ requested bytes. + * Since SSL is a self-terminated protocol (each record has a length + * header), this does not change semantics. + * + * - Callbacks need not apply any buffering (for performance) since SSL + * itself uses buffers. + * + * \param ctx wrapper context to initialise. + * \param engine SSL engine to wrap. + * \param low_read callback for reading data from the transport. + * \param read_context context pointer for `low_read()`. + * \param low_write callback for writing data on the transport. + * \param write_context context pointer for `low_write()`. + */ +void br_sslio_init(br_sslio_context *ctx, + br_ssl_engine_context *engine, + int (*low_read)(void *read_context, + unsigned char *data, size_t len), + void *read_context, + int (*low_write)(void *write_context, + const unsigned char *data, size_t len), + void *write_context); + +/** + * \brief Read some application data from a SSL connection. + * + * If `len` is zero, then this function returns 0 immediately. In + * all other cases, it never returns 0. + * + * This call returns only when at least one byte has been obtained. + * Returned value is the number of bytes read, or -1 on error. The + * number of bytes always fits on an 'int' (data from a single SSL/TLS + * record is returned). + * + * On error or SSL closure, this function returns -1. The caller should + * inspect the error status on the SSL engine to distinguish between + * normal closure and error. + * + * \param cc SSL wrapper context. + * \param dst destination buffer for application data. + * \param len maximum number of bytes to obtain. + * \return number of bytes obtained, or -1 on error. + */ +int br_sslio_read(br_sslio_context *cc, void *dst, size_t len); + +/** + * \brief Read application data from a SSL connection. + * + * This calls returns only when _all_ requested `len` bytes are read, + * or an error is reached. Returned value is 0 on success, -1 on error. + * A normal (verified) SSL closure before that many bytes are obtained + * is reported as an error by this function. + * + * \param cc SSL wrapper context. + * \param dst destination buffer for application data. + * \param len number of bytes to obtain. + * \return 0 on success, or -1 on error. + */ +int br_sslio_read_all(br_sslio_context *cc, void *dst, size_t len); + +/** + * \brief Write some application data unto a SSL connection. + * + * If `len` is zero, then this function returns 0 immediately. In + * all other cases, it never returns 0. + * + * This call returns only when at least one byte has been written. + * Returned value is the number of bytes written, or -1 on error. The + * number of bytes always fits on an 'int' (less than 20000). + * + * On error or SSL closure, this function returns -1. The caller should + * inspect the error status on the SSL engine to distinguish between + * normal closure and error. + * + * **Important:** SSL is buffered; a "written" byte is a byte that was + * injected into the wrapped SSL engine, but this does not necessarily mean + * that it has been scheduled for sending. Use `br_sslio_flush()` to + * ensure that all pending data has been sent to the transport medium. + * + * \param cc SSL wrapper context. + * \param src source buffer for application data. + * \param len maximum number of bytes to write. + * \return number of bytes written, or -1 on error. + */ +int br_sslio_write(br_sslio_context *cc, const void *src, size_t len); + +/** + * \brief Write application data unto a SSL connection. + * + * This calls returns only when _all_ requested `len` bytes have been + * written, or an error is reached. Returned value is 0 on success, -1 + * on error. A normal (verified) SSL closure before that many bytes are + * written is reported as an error by this function. + * + * **Important:** SSL is buffered; a "written" byte is a byte that was + * injected into the wrapped SSL engine, but this does not necessarily mean + * that it has been scheduled for sending. Use `br_sslio_flush()` to + * ensure that all pending data has been sent to the transport medium. + * + * \param cc SSL wrapper context. + * \param src source buffer for application data. + * \param len number of bytes to write. + * \return 0 on success, or -1 on error. + */ +int br_sslio_write_all(br_sslio_context *cc, const void *src, size_t len); + +/** + * \brief Flush pending data. + * + * This call makes sure that any buffered application data in the + * provided context (including the wrapped SSL engine) has been sent + * to the transport medium (i.e. accepted by the `low_write()` callback + * method). If there is no such pending data, then this function does + * nothing (and returns a success, i.e. 0). + * + * If the underlying transport medium has its own buffers, then it is + * up to the caller to ensure the corresponding flushing. + * + * Returned value is 0 on success, -1 on error. + * + * \param cc SSL wrapper context. + * \return 0 on success, or -1 on error. + */ +int br_sslio_flush(br_sslio_context *cc); + +/** + * \brief Close the SSL connection. + * + * This call runs the SSL closure protocol (sending a `close_notify`, + * receiving the response `close_notify`). When it returns, the SSL + * connection is finished. It is still up to the caller to manage the + * possible transport-level termination, if applicable (alternatively, + * the underlying transport stream may be reused for non-SSL messages). + * + * Returned value is 0 on success, -1 on error. A failure by the peer + * to process the complete closure protocol (i.e. sending back the + * `close_notify`) is an error. + * + * \param cc SSL wrapper context. + * \return 0 on success, or -1 on error. + */ +int br_sslio_close(br_sslio_context *cc); + +/* ===================================================================== */ + +/* + * Symbolic constants for cipher suites. + */ + +/* From RFC 5246 */ +#define BR_TLS_NULL_WITH_NULL_NULL 0x0000 +#define BR_TLS_RSA_WITH_NULL_MD5 0x0001 +#define BR_TLS_RSA_WITH_NULL_SHA 0x0002 +#define BR_TLS_RSA_WITH_NULL_SHA256 0x003B +#define BR_TLS_RSA_WITH_RC4_128_MD5 0x0004 +#define BR_TLS_RSA_WITH_RC4_128_SHA 0x0005 +#define BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x000A +#define BR_TLS_RSA_WITH_AES_128_CBC_SHA 0x002F +#define BR_TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 +#define BR_TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C +#define BR_TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D +#define BR_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA 0x000D +#define BR_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA 0x0010 +#define BR_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA 0x0013 +#define BR_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016 +#define BR_TLS_DH_DSS_WITH_AES_128_CBC_SHA 0x0030 +#define BR_TLS_DH_RSA_WITH_AES_128_CBC_SHA 0x0031 +#define BR_TLS_DHE_DSS_WITH_AES_128_CBC_SHA 0x0032 +#define BR_TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033 +#define BR_TLS_DH_DSS_WITH_AES_256_CBC_SHA 0x0036 +#define BR_TLS_DH_RSA_WITH_AES_256_CBC_SHA 0x0037 +#define BR_TLS_DHE_DSS_WITH_AES_256_CBC_SHA 0x0038 +#define BR_TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039 +#define BR_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 0x003E +#define BR_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 0x003F +#define BR_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 0x0040 +#define BR_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067 +#define BR_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 0x0068 +#define BR_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 0x0069 +#define BR_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 0x006A +#define BR_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B +#define BR_TLS_DH_anon_WITH_RC4_128_MD5 0x0018 +#define BR_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA 0x001B +#define BR_TLS_DH_anon_WITH_AES_128_CBC_SHA 0x0034 +#define BR_TLS_DH_anon_WITH_AES_256_CBC_SHA 0x003A +#define BR_TLS_DH_anon_WITH_AES_128_CBC_SHA256 0x006C +#define BR_TLS_DH_anon_WITH_AES_256_CBC_SHA256 0x006D + +/* From RFC 4492 */ +#define BR_TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 +#define BR_TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 +#define BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 +#define BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 +#define BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 +#define BR_TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 +#define BR_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 +#define BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A +#define BR_TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B +#define BR_TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C +#define BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D +#define BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E +#define BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F +#define BR_TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 +#define BR_TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 +#define BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 +#define BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 +#define BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 +#define BR_TLS_ECDH_anon_WITH_NULL_SHA 0xC015 +#define BR_TLS_ECDH_anon_WITH_RC4_128_SHA 0xC016 +#define BR_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA 0xC017 +#define BR_TLS_ECDH_anon_WITH_AES_128_CBC_SHA 0xC018 +#define BR_TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019 + +/* From RFC 5288 */ +#define BR_TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C +#define BR_TLS_RSA_WITH_AES_256_GCM_SHA384 0x009D +#define BR_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x009E +#define BR_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x009F +#define BR_TLS_DH_RSA_WITH_AES_128_GCM_SHA256 0x00A0 +#define BR_TLS_DH_RSA_WITH_AES_256_GCM_SHA384 0x00A1 +#define BR_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 0x00A2 +#define BR_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 0x00A3 +#define BR_TLS_DH_DSS_WITH_AES_128_GCM_SHA256 0x00A4 +#define BR_TLS_DH_DSS_WITH_AES_256_GCM_SHA384 0x00A5 +#define BR_TLS_DH_anon_WITH_AES_128_GCM_SHA256 0x00A6 +#define BR_TLS_DH_anon_WITH_AES_256_GCM_SHA384 0x00A7 + +/* From RFC 5289 */ +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 +#define BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 +#define BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 +#define BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 +#define BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 +#define BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 +#define BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C +#define BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D +#define BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E +#define BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F +#define BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 +#define BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 +#define BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 + +/* From RFC 6655 and 7251 */ +#define BR_TLS_RSA_WITH_AES_128_CCM 0xC09C +#define BR_TLS_RSA_WITH_AES_256_CCM 0xC09D +#define BR_TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 +#define BR_TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF + +/* From RFC 7905 */ +#define BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 +#define BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 +#define BR_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA +#define BR_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAB +#define BR_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC +#define BR_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD +#define BR_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE + +/* From RFC 7507 */ +#define BR_TLS_FALLBACK_SCSV 0x5600 + +/* + * Symbolic constants for alerts. + */ +#define BR_ALERT_CLOSE_NOTIFY 0 +#define BR_ALERT_UNEXPECTED_MESSAGE 10 +#define BR_ALERT_BAD_RECORD_MAC 20 +#define BR_ALERT_RECORD_OVERFLOW 22 +#define BR_ALERT_DECOMPRESSION_FAILURE 30 +#define BR_ALERT_HANDSHAKE_FAILURE 40 +#define BR_ALERT_BAD_CERTIFICATE 42 +#define BR_ALERT_UNSUPPORTED_CERTIFICATE 43 +#define BR_ALERT_CERTIFICATE_REVOKED 44 +#define BR_ALERT_CERTIFICATE_EXPIRED 45 +#define BR_ALERT_CERTIFICATE_UNKNOWN 46 +#define BR_ALERT_ILLEGAL_PARAMETER 47 +#define BR_ALERT_UNKNOWN_CA 48 +#define BR_ALERT_ACCESS_DENIED 49 +#define BR_ALERT_DECODE_ERROR 50 +#define BR_ALERT_DECRYPT_ERROR 51 +#define BR_ALERT_PROTOCOL_VERSION 70 +#define BR_ALERT_INSUFFICIENT_SECURITY 71 +#define BR_ALERT_INTERNAL_ERROR 80 +#define BR_ALERT_USER_CANCELED 90 +#define BR_ALERT_NO_RENEGOTIATION 100 +#define BR_ALERT_UNSUPPORTED_EXTENSION 110 +#define BR_ALERT_NO_APPLICATION_PROTOCOL 120 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/inc/bearssl_x509.h b/BearSSL-OG/libbearssl/inc/bearssl_x509.h new file mode 100644 index 0000000..f19624a --- /dev/null +++ b/BearSSL-OG/libbearssl/inc/bearssl_x509.h @@ -0,0 +1,1474 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_X509_H__ +#define BR_BEARSSL_X509_H__ + +#include +#include + +#include "bearssl_ec.h" +#include "bearssl_hash.h" +#include "bearssl_rsa.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_x509.h + * + * # X.509 Certificate Chain Processing + * + * An X.509 processing engine receives an X.509 chain, chunk by chunk, + * as received from a SSL/TLS client or server (the client receives the + * server's certificate chain, and the server receives the client's + * certificate chain if it requested a client certificate). The chain + * is thus injected in the engine in SSL order (end-entity first). + * + * The engine's job is to return the public key to use for SSL/TLS. + * How exactly that key is obtained and verified is entirely up to the + * engine. + * + * **The "known key" engine** returns a public key which is already known + * from out-of-band information (e.g. the client _remembers_ the key from + * a previous connection, as in the usual SSH model). This is the simplest + * engine since it simply ignores the chain, thereby avoiding the need + * for any decoding logic. + * + * **The "minimal" engine** implements minimal X.509 decoding and chain + * validation: + * + * - The provided chain should validate "as is". There is no attempt + * at reordering, skipping or downloading extra certificates. + * + * - X.509 v1, v2 and v3 certificates are supported. + * + * - Trust anchors are a DN and a public key. Each anchor is either a + * "CA" anchor, or a non-CA. + * + * - If the end-entity certificate matches a non-CA anchor (subject DN + * is equal to the non-CA name, and public key is also identical to + * the anchor key), then this is a _direct trust_ case and the + * remaining certificates are ignored. + * + * - Unless direct trust is applied, the chain must be verifiable up to + * a certificate whose issuer DN matches the DN from a "CA" trust anchor, + * and whose signature is verifiable against that anchor's public key. + * Subsequent certificates in the chain are ignored. + * + * - The engine verifies subject/issuer DN matching, and enforces + * processing of Basic Constraints and Key Usage extensions. The + * Authority Key Identifier, Subject Key Identifier, Issuer Alt Name, + * Subject Directory Attribute, CRL Distribution Points, Freshest CRL, + * Authority Info Access and Subject Info Access extensions are + * ignored. The Subject Alt Name is decoded for the end-entity + * certificate under some conditions (see below). Other extensions + * are ignored if non-critical, or imply chain rejection if critical. + * + * - The Subject Alt Name extension is parsed for names of type `dNSName` + * when decoding the end-entity certificate, and only if there is a + * server name to match. If there is no SAN extension, then the + * Common Name from the subjectDN is used. That name matching is + * case-insensitive and honours a single starting wildcard (i.e. if + * the name in the certificate starts with "`*.`" then this matches + * any word as first element). Note: this name matching is performed + * also in the "direct trust" model. + * + * - DN matching is byte-to-byte equality (a future version might + * include some limited processing for case-insensitive matching and + * whitespace normalisation). + * + * - Successful validation produces a public key type but also a set + * of allowed usages (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`). + * The caller is responsible for checking that the key type and + * usages are compatible with the expected values (e.g. with the + * selected cipher suite, when the client validates the server's + * certificate). + * + * **Important caveats:** + * + * - The "minimal" engine does not check revocation status. The relevant + * extensions are ignored, and CRL or OCSP responses are not gathered + * or checked. + * + * - The "minimal" engine does not currently support Name Constraints + * (some basic functionality to handle sub-domains may be added in a + * later version). + * + * - The decoder is not "validating" in the sense that it won't reject + * some certificates with invalid field values when these fields are + * not actually processed. + */ + +/* + * X.509 error codes are in the 32..63 range. + */ + +/** \brief X.509 status: validation was successful; this is not actually + an error. */ +#define BR_ERR_X509_OK 32 + +/** \brief X.509 status: invalid value in an ASN.1 structure. */ +#define BR_ERR_X509_INVALID_VALUE 33 + +/** \brief X.509 status: truncated certificate. */ +#define BR_ERR_X509_TRUNCATED 34 + +/** \brief X.509 status: empty certificate chain (no certificate at all). */ +#define BR_ERR_X509_EMPTY_CHAIN 35 + +/** \brief X.509 status: decoding error: inner element extends beyond + outer element size. */ +#define BR_ERR_X509_INNER_TRUNC 36 + +/** \brief X.509 status: decoding error: unsupported tag class (application + or private). */ +#define BR_ERR_X509_BAD_TAG_CLASS 37 + +/** \brief X.509 status: decoding error: unsupported tag value. */ +#define BR_ERR_X509_BAD_TAG_VALUE 38 + +/** \brief X.509 status: decoding error: indefinite length. */ +#define BR_ERR_X509_INDEFINITE_LENGTH 39 + +/** \brief X.509 status: decoding error: extraneous element. */ +#define BR_ERR_X509_EXTRA_ELEMENT 40 + +/** \brief X.509 status: decoding error: unexpected element. */ +#define BR_ERR_X509_UNEXPECTED 41 + +/** \brief X.509 status: decoding error: expected constructed element, but + is primitive. */ +#define BR_ERR_X509_NOT_CONSTRUCTED 42 + +/** \brief X.509 status: decoding error: expected primitive element, but + is constructed. */ +#define BR_ERR_X509_NOT_PRIMITIVE 43 + +/** \brief X.509 status: decoding error: BIT STRING length is not multiple + of 8. */ +#define BR_ERR_X509_PARTIAL_BYTE 44 + +/** \brief X.509 status: decoding error: BOOLEAN value has invalid length. */ +#define BR_ERR_X509_BAD_BOOLEAN 45 + +/** \brief X.509 status: decoding error: value is off-limits. */ +#define BR_ERR_X509_OVERFLOW 46 + +/** \brief X.509 status: invalid distinguished name. */ +#define BR_ERR_X509_BAD_DN 47 + +/** \brief X.509 status: invalid date/time representation. */ +#define BR_ERR_X509_BAD_TIME 48 + +/** \brief X.509 status: certificate contains unsupported features that + cannot be ignored. */ +#define BR_ERR_X509_UNSUPPORTED 49 + +/** \brief X.509 status: key or signature size exceeds internal limits. */ +#define BR_ERR_X509_LIMIT_EXCEEDED 50 + +/** \brief X.509 status: key type does not match that which was expected. */ +#define BR_ERR_X509_WRONG_KEY_TYPE 51 + +/** \brief X.509 status: signature is invalid. */ +#define BR_ERR_X509_BAD_SIGNATURE 52 + +/** \brief X.509 status: validation time is unknown. */ +#define BR_ERR_X509_TIME_UNKNOWN 53 + +/** \brief X.509 status: certificate is expired or not yet valid. */ +#define BR_ERR_X509_EXPIRED 54 + +/** \brief X.509 status: issuer/subject DN mismatch in the chain. */ +#define BR_ERR_X509_DN_MISMATCH 55 + +/** \brief X.509 status: expected server name was not found in the chain. */ +#define BR_ERR_X509_BAD_SERVER_NAME 56 + +/** \brief X.509 status: unknown critical extension in certificate. */ +#define BR_ERR_X509_CRITICAL_EXTENSION 57 + +/** \brief X.509 status: not a CA, or path length constraint violation */ +#define BR_ERR_X509_NOT_CA 58 + +/** \brief X.509 status: Key Usage extension prohibits intended usage. */ +#define BR_ERR_X509_FORBIDDEN_KEY_USAGE 59 + +/** \brief X.509 status: public key found in certificate is too small. */ +#define BR_ERR_X509_WEAK_PUBLIC_KEY 60 + +/** \brief X.509 status: chain could not be linked to a trust anchor. */ +#define BR_ERR_X509_NOT_TRUSTED 62 + +/** + * \brief Aggregate structure for public keys. + */ +typedef struct { + /** \brief Key type: `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC` */ + unsigned char key_type; + /** \brief Actual public key. */ + union { + /** \brief RSA public key. */ + br_rsa_public_key rsa; + /** \brief EC public key. */ + br_ec_public_key ec; + } key; +} br_x509_pkey; + +/** + * \brief Distinguished Name (X.500) structure. + * + * The DN is DER-encoded. + */ +typedef struct { + /** \brief Encoded DN data. */ + unsigned char *data; + /** \brief Encoded DN length (in bytes). */ + size_t len; +} br_x500_name; + +/** + * \brief Trust anchor structure. + */ +typedef struct { + /** \brief Encoded DN (X.500 name). */ + br_x500_name dn; + /** \brief Anchor flags (e.g. `BR_X509_TA_CA`). */ + unsigned flags; + /** \brief Anchor public key. */ + br_x509_pkey pkey; +} br_x509_trust_anchor; + +/** + * \brief Trust anchor flag: CA. + * + * A "CA" anchor is deemed fit to verify signatures on certificates. + * A "non-CA" anchor is accepted only for direct trust (server's + * certificate name and key match the anchor). + */ +#define BR_X509_TA_CA 0x0001 + +/* + * Key type: combination of a basic key type (low 4 bits) and some + * optional flags. + * + * For a public key, the basic key type only is set. + * + * For an expected key type, the flags indicate the intended purpose(s) + * for the key; the basic key type may be set to 0 to indicate that any + * key type compatible with the indicated purpose is acceptable. + */ +/** \brief Key type: algorithm is RSA. */ +#define BR_KEYTYPE_RSA 1 +/** \brief Key type: algorithm is EC. */ +#define BR_KEYTYPE_EC 2 + +/** + * \brief Key type: usage is "key exchange". + * + * This value is combined (with bitwise OR) with the algorithm + * (`BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`) when informing the X.509 + * validation engine that it should find a public key of that type, + * fit for key exchanges (e.g. `TLS_RSA_*` and `TLS_ECDH_*` cipher + * suites). + */ +#define BR_KEYTYPE_KEYX 0x10 + +/** + * \brief Key type: usage is "signature". + * + * This value is combined (with bitwise OR) with the algorithm + * (`BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`) when informing the X.509 + * validation engine that it should find a public key of that type, + * fit for signatures (e.g. `TLS_ECDHE_*` cipher suites). + */ +#define BR_KEYTYPE_SIGN 0x20 + +/* + * start_chain Called when a new chain is started. If 'server_name' + * is not NULL and non-empty, then it is a name that + * should be looked for in the EE certificate (in the + * SAN extension as dNSName, or in the subjectDN's CN + * if there is no SAN extension). + * The caller ensures that the provided 'server_name' + * pointer remains valid throughout validation. + * + * start_cert Begins a new certificate in the chain. The provided + * length is in bytes; this is the total certificate length. + * + * append Get some additional bytes for the current certificate. + * + * end_cert Ends the current certificate. + * + * end_chain Called at the end of the chain. Returned value is + * 0 on success, or a non-zero error code. + * + * get_pkey Returns the EE certificate public key. + * + * For a complete chain, start_chain() and end_chain() are always + * called. For each certificate, start_cert(), some append() calls, then + * end_cert() are called, in that order. There may be no append() call + * at all if the certificate is empty (which is not valid but may happen + * if the peer sends exactly that). + * + * get_pkey() shall return a pointer to a structure that is valid as + * long as a new chain is not started. This may be a sub-structure + * within the context for the engine. This function MAY return a valid + * pointer to a public key even in some cases of validation failure, + * depending on the validation engine. + */ + +/** + * \brief Class type for an X.509 engine. + * + * A certificate chain validation uses a caller-allocated context, which + * contains the running state for that validation. Methods are called + * in due order: + * + * - `start_chain()` is called at the start of the validation. + * - Certificates are processed one by one, in SSL order (end-entity + * comes first). For each certificate, the following methods are + * called: + * + * - `start_cert()` at the beginning of the certificate. + * - `append()` is called zero, one or more times, to provide + * the certificate (possibly in chunks). + * - `end_cert()` at the end of the certificate. + * + * - `end_chain()` is called when the last certificate in the chain + * was processed. + * - `get_pkey()` is called after chain processing, if the chain + * validation was successful. + * + * A context structure may be reused; the `start_chain()` method shall + * ensure (re)initialisation. + */ +typedef struct br_x509_class_ br_x509_class; +struct br_x509_class_ { + /** + * \brief X.509 context size, in bytes. + */ + size_t context_size; + + /** + * \brief Start a new chain. + * + * This method shall set the vtable (first field) of the context + * structure. + * + * The `server_name`, if not `NULL`, will be considered as a + * fully qualified domain name, to be matched against the `dNSName` + * elements of the end-entity certificate's SAN extension (if there + * is no SAN, then the Common Name from the subjectDN will be used). + * If `server_name` is `NULL` then no such matching is performed. + * + * \param ctx validation context. + * \param server_name server name to match (or `NULL`). + */ + void (*start_chain)(const br_x509_class **ctx, + const char *server_name); + + /** + * \brief Start a new certificate. + * + * \param ctx validation context. + * \param length new certificate length (in bytes). + */ + void (*start_cert)(const br_x509_class **ctx, uint32_t length); + + /** + * \brief Receive some bytes for the current certificate. + * + * This function may be called several times in succession for + * a given certificate. The caller guarantees that for each + * call, `len` is not zero, and the sum of all chunk lengths + * for a certificate matches the total certificate length which + * was provided in the previous `start_cert()` call. + * + * If the new certificate is empty (no byte at all) then this + * function won't be called at all. + * + * \param ctx validation context. + * \param buf certificate data chunk. + * \param len certificate data chunk length (in bytes). + */ + void (*append)(const br_x509_class **ctx, + const unsigned char *buf, size_t len); + + /** + * \brief Finish the current certificate. + * + * This function is called when the end of the current certificate + * is reached. + * + * \param ctx validation context. + */ + void (*end_cert)(const br_x509_class **ctx); + + /** + * \brief Finish the chain. + * + * This function is called at the end of the chain. It shall + * return either 0 if the validation was successful, or a + * non-zero error code. The `BR_ERR_X509_*` constants are + * error codes, though other values may be possible. + * + * \param ctx validation context. + * \return 0 on success, or a non-zero error code. + */ + unsigned (*end_chain)(const br_x509_class **ctx); + + /** + * \brief Get the resulting end-entity public key. + * + * The decoded public key is returned. The returned pointer + * may be valid only as long as the context structure is + * unmodified, i.e. it may cease to be valid if the context + * is released or reused. + * + * This function _may_ return `NULL` if the validation failed. + * However, returning a public key does not mean that the + * validation was wholly successful; some engines may return + * a decoded public key even if the chain did not end on a + * trusted anchor. + * + * If validation succeeded and `usage` is not `NULL`, then + * `*usage` is filled with a combination of `BR_KEYTYPE_SIGN` + * and/or `BR_KEYTYPE_KEYX` that specifies the validated key + * usage types. It is the caller's responsibility to check + * that value against the intended use of the public key. + * + * \param ctx validation context. + * \return the end-entity public key, or `NULL`. + */ + const br_x509_pkey *(*get_pkey)( + const br_x509_class *const *ctx, unsigned *usages); +}; + +/** + * \brief The "known key" X.509 engine structure. + * + * The structure contents are opaque (they shall not be accessed directly), + * except for the first field (the vtable). + * + * The "known key" engine returns an externally configured public key, + * and totally ignores the certificate contents. + */ +typedef struct { + /** \brief Reference to the context vtable. */ + const br_x509_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + br_x509_pkey pkey; + unsigned usages; +#endif +} br_x509_knownkey_context; + +/** + * \brief Class instance for the "known key" X.509 engine. + */ +extern const br_x509_class br_x509_knownkey_vtable; + +/** + * \brief Initialize a "known key" X.509 engine with a known RSA public key. + * + * The `usages` parameter indicates the allowed key usages for that key + * (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`). + * + * The provided pointers are linked in, not copied, so they must remain + * valid while the public key may be in usage. + * + * \param ctx context to initialise. + * \param pk known public key. + * \param usages allowed key usages. + */ +void br_x509_knownkey_init_rsa(br_x509_knownkey_context *ctx, + const br_rsa_public_key *pk, unsigned usages); + +/** + * \brief Initialize a "known key" X.509 engine with a known EC public key. + * + * The `usages` parameter indicates the allowed key usages for that key + * (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`). + * + * The provided pointers are linked in, not copied, so they must remain + * valid while the public key may be in usage. + * + * \param ctx context to initialise. + * \param pk known public key. + * \param usages allowed key usages. + */ +void br_x509_knownkey_init_ec(br_x509_knownkey_context *ctx, + const br_ec_public_key *pk, unsigned usages); + +#ifndef BR_DOXYGEN_IGNORE +/* + * The minimal X.509 engine has some state buffers which must be large + * enough to simultaneously accommodate: + * -- the public key extracted from the current certificate; + * -- the signature on the current certificate or on the previous + * certificate; + * -- the public key extracted from the EE certificate. + * + * We store public key elements in their raw unsigned big-endian + * encoding. We want to support up to RSA-4096 with a short (up to 64 + * bits) public exponent, thus a buffer for a public key must have + * length at least 520 bytes. Similarly, a RSA-4096 signature has length + * 512 bytes. + * + * Though RSA public exponents can formally be as large as the modulus + * (mathematically, even larger exponents would work, but PKCS#1 forbids + * them), exponents that do not fit on 32 bits are extremely rare, + * notably because some widespread implementations (e.g. Microsoft's + * CryptoAPI) don't support them. Moreover, large public exponent do not + * seem to imply any tangible security benefit, and they increase the + * cost of public key operations. The X.509 "minimal" engine will tolerate + * public exponents of arbitrary size as long as the modulus and the + * exponent can fit together in the dedicated buffer. + * + * EC public keys are shorter than RSA public keys; even with curve + * NIST P-521 (the largest curve we care to support), a public key is + * encoded over 133 bytes only. + */ +#define BR_X509_BUFSIZE_KEY 520 +#define BR_X509_BUFSIZE_SIG 512 +#endif + +/** + * \brief Type for receiving a name element. + * + * An array of such structures can be provided to the X.509 decoding + * engines. If the specified elements are found in the certificate + * subject DN or the SAN extension, then the name contents are copied + * as zero-terminated strings into the buffer. + * + * The decoder converts TeletexString and BMPString to UTF8String, and + * ensures that the resulting string is zero-terminated. If the string + * does not fit in the provided buffer, then the copy is aborted and an + * error is reported. + */ +typedef struct { + /** + * \brief Element OID. + * + * For X.500 name elements (to be extracted from the subject DN), + * this is the encoded OID for the requested name element; the + * first byte shall contain the length of the DER-encoded OID + * value, followed by the OID value (for instance, OID 2.5.4.3, + * for id-at-commonName, will be `03 55 04 03`). This is + * equivalent to full DER encoding with the length but without + * the tag. + * + * For SAN name elements, the first byte (`oid[0]`) has value 0, + * followed by another byte that matches the expected GeneralName + * tag. Allowed second byte values are then: + * + * - 1: `rfc822Name` + * + * - 2: `dNSName` + * + * - 6: `uniformResourceIdentifier` + * + * - 0: `otherName` + * + * If first and second byte are 0, then this is a SAN element of + * type `otherName`; the `oid[]` array should then contain, right + * after the two bytes of value 0, an encoded OID (with the same + * conventions as for X.500 name elements). If a match is found + * for that OID, then the corresponding name element will be + * extracted, as long as it is a supported string type. + */ + const unsigned char *oid; + + /** + * \brief Destination buffer. + */ + char *buf; + + /** + * \brief Length (in bytes) of the destination buffer. + * + * The buffer MUST NOT be smaller than 1 byte. + */ + size_t len; + + /** + * \brief Decoding status. + * + * Status is 0 if the name element was not found, 1 if it was + * found and decoded, or -1 on error. Error conditions include + * an unrecognised encoding, an invalid encoding, or a string + * too large for the destination buffer. + */ + int status; + +} br_name_element; + +/** + * \brief Callback for validity date checks. + * + * The function receives as parameter an arbitrary user-provided context, + * and the notBefore and notAfter dates specified in an X.509 certificate, + * both expressed as a number of days and a number of seconds: + * + * - Days are counted in a proleptic Gregorian calendar since + * January 1st, 0 AD. Year "0 AD" is the one that preceded "1 AD"; + * it is also traditionally known as "1 BC". + * + * - Seconds are counted since midnight, from 0 to 86400 (a count of + * 86400 is possible only if a leap second happened). + * + * Each date and time is understood in the UTC time zone. The "Unix + * Epoch" (January 1st, 1970, 00:00 UTC) corresponds to days=719528 and + * seconds=0; the "Windows Epoch" (January 1st, 1601, 00:00 UTC) is + * days=584754, seconds=0. + * + * This function must return -1 if the current date is strictly before + * the "notBefore" time, or +1 if the current date is strictly after the + * "notAfter" time. If neither condition holds, then the function returns + * 0, which means that the current date falls within the validity range of + * the certificate. If the function returns a value distinct from -1, 0 + * and +1, then this is interpreted as an unavailability of the current + * time, which normally ends the validation process with a + * `BR_ERR_X509_TIME_UNKNOWN` error. + * + * During path validation, this callback will be invoked for each + * considered X.509 certificate. Validation fails if any of the calls + * returns a non-zero value. + * + * The context value is an abritrary pointer set by the caller when + * configuring this callback. + * + * \param tctx context pointer. + * \param not_before_days notBefore date (days since Jan 1st, 0 AD). + * \param not_before_seconds notBefore time (seconds, at most 86400). + * \param not_after_days notAfter date (days since Jan 1st, 0 AD). + * \param not_after_seconds notAfter time (seconds, at most 86400). + * \return -1, 0 or +1. + */ +typedef int (*br_x509_time_check)(void *tctx, + uint32_t not_before_days, uint32_t not_before_seconds, + uint32_t not_after_days, uint32_t not_after_seconds); + +/** + * \brief The "minimal" X.509 engine structure. + * + * The structure contents are opaque (they shall not be accessed directly), + * except for the first field (the vtable). + * + * The "minimal" engine performs a rudimentary but serviceable X.509 path + * validation. + */ +typedef struct { + const br_x509_class *vtable; + +#ifndef BR_DOXYGEN_IGNORE + /* Structure for returning the EE public key. */ + br_x509_pkey pkey; + + /* CPU for the T0 virtual machine. */ + struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; + } cpu; + uint32_t dp_stack[31]; + uint32_t rp_stack[31]; + int err; + + /* Server name to match with the SAN / CN of the EE certificate. */ + const char *server_name; + + /* Validated key usages. */ + unsigned char key_usages; + + /* Explicitly set date and time. */ + uint32_t days, seconds; + + /* Current certificate length (in bytes). Set to 0 when the + certificate has been fully processed. */ + uint32_t cert_length; + + /* Number of certificates processed so far in the current chain. + It is incremented at the end of the processing of a certificate, + so it is 0 for the EE. */ + uint32_t num_certs; + + /* Certificate data chunk. */ + const unsigned char *hbuf; + size_t hlen; + + /* The pad serves as destination for various operations. */ + unsigned char pad[256]; + + /* Buffer for EE public key data. */ + unsigned char ee_pkey_data[BR_X509_BUFSIZE_KEY]; + + /* Buffer for currently decoded public key. */ + unsigned char pkey_data[BR_X509_BUFSIZE_KEY]; + + /* Signature type: signer key type, offset to the hash + function OID (in the T0 data block) and hash function + output length (TBS hash length). */ + unsigned char cert_signer_key_type; + uint16_t cert_sig_hash_oid; + unsigned char cert_sig_hash_len; + + /* Current/last certificate signature. */ + unsigned char cert_sig[BR_X509_BUFSIZE_SIG]; + uint16_t cert_sig_len; + + /* Minimum RSA key length (difference in bytes from 128). */ + int16_t min_rsa_size; + + /* Configured trust anchors. */ + const br_x509_trust_anchor *trust_anchors; + size_t trust_anchors_num; + + /* + * Multi-hasher for the TBS. + */ + unsigned char do_mhash; + br_multihash_context mhash; + unsigned char tbs_hash[64]; + + /* + * Simple hasher for the subject/issuer DN. + */ + unsigned char do_dn_hash; + const br_hash_class *dn_hash_impl; + br_hash_compat_context dn_hash; + unsigned char current_dn_hash[64]; + unsigned char next_dn_hash[64]; + unsigned char saved_dn_hash[64]; + + /* + * Name elements to gather. + */ + br_name_element *name_elts; + size_t num_name_elts; + + /* + * Callback function (and context) to get the current date. + */ + void *itime_ctx; + br_x509_time_check itime; + + /* + * Public key cryptography implementations (signature verification). + */ + br_rsa_pkcs1_vrfy irsa; + br_ecdsa_vrfy iecdsa; + const br_ec_impl *iec; +#endif + +} br_x509_minimal_context; + +/** + * \brief Class instance for the "minimal" X.509 engine. + */ +extern const br_x509_class br_x509_minimal_vtable; + +/** + * \brief Initialise a "minimal" X.509 engine. + * + * The `dn_hash_impl` parameter shall be a hash function internally used + * to match X.500 names (subject/issuer DN, and anchor names). Any standard + * hash function may be used, but a collision-resistant hash function is + * advised. + * + * After initialization, some implementations for signature verification + * (hash functions and signature algorithms) MUST be added. + * + * \param ctx context to initialise. + * \param dn_hash_impl hash function for DN comparisons. + * \param trust_anchors trust anchors. + * \param trust_anchors_num number of trust anchors. + */ +void br_x509_minimal_init(br_x509_minimal_context *ctx, + const br_hash_class *dn_hash_impl, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); + +/** + * \brief Set a supported hash function in an X.509 "minimal" engine. + * + * Hash functions are used with signature verification algorithms. + * Once initialised (with `br_x509_minimal_init()`), the context must + * be configured with the hash functions it shall support for that + * purpose. The hash function identifier MUST be one of the standard + * hash function identifiers (1 to 6, for MD5, SHA-1, SHA-224, SHA-256, + * SHA-384 and SHA-512). + * + * If `impl` is `NULL`, this _removes_ support for the designated + * hash function. + * + * \param ctx validation context. + * \param id hash function identifier (from 1 to 6). + * \param impl hash function implementation (or `NULL`). + */ +static __inline void +br_x509_minimal_set_hash(br_x509_minimal_context *ctx, + int id, const br_hash_class *impl) +{ + br_multihash_setimpl(&ctx->mhash, id, impl); +} + +/** + * \brief Set a RSA signature verification implementation in the X.509 + * "minimal" engine. + * + * Once initialised (with `br_x509_minimal_init()`), the context must + * be configured with the signature verification implementations that + * it is supposed to support. If `irsa` is `0`, then the RSA support + * is disabled. + * + * \param ctx validation context. + * \param irsa RSA signature verification implementation (or `0`). + */ +static __inline void +br_x509_minimal_set_rsa(br_x509_minimal_context *ctx, + br_rsa_pkcs1_vrfy irsa) +{ + ctx->irsa = irsa; +} + +/** + * \brief Set a ECDSA signature verification implementation in the X.509 + * "minimal" engine. + * + * Once initialised (with `br_x509_minimal_init()`), the context must + * be configured with the signature verification implementations that + * it is supposed to support. + * + * If `iecdsa` is `0`, then this call disables ECDSA support; in that + * case, `iec` may be `NULL`. Otherwise, `iecdsa` MUST point to a function + * that verifies ECDSA signatures with format "asn1", and it will use + * `iec` as underlying elliptic curve support. + * + * \param ctx validation context. + * \param iec elliptic curve implementation (or `NULL`). + * \param iecdsa ECDSA implementation (or `0`). + */ +static __inline void +br_x509_minimal_set_ecdsa(br_x509_minimal_context *ctx, + const br_ec_impl *iec, br_ecdsa_vrfy iecdsa) +{ + ctx->iecdsa = iecdsa; + ctx->iec = iec; +} + +/** + * \brief Initialise a "minimal" X.509 engine with default algorithms. + * + * This function performs the same job as `br_x509_minimal_init()`, but + * also sets implementations for RSA, ECDSA, and the standard hash + * functions. + * + * \param ctx context to initialise. + * \param trust_anchors trust anchors. + * \param trust_anchors_num number of trust anchors. + */ +void br_x509_minimal_init_full(br_x509_minimal_context *ctx, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); + +/** + * \brief Set the validation time for the X.509 "minimal" engine. + * + * The validation time is set as two 32-bit integers, for days and + * seconds since a fixed epoch: + * + * - Days are counted in a proleptic Gregorian calendar since + * January 1st, 0 AD. Year "0 AD" is the one that preceded "1 AD"; + * it is also traditionally known as "1 BC". + * + * - Seconds are counted since midnight, from 0 to 86400 (a count of + * 86400 is possible only if a leap second happened). + * + * The validation date and time is understood in the UTC time zone. The + * "Unix Epoch" (January 1st, 1970, 00:00 UTC) corresponds to days=719528 + * and seconds=0; the "Windows Epoch" (January 1st, 1601, 00:00 UTC) is + * days=584754, seconds=0. + * + * If the validation date and time are not explicitly set, but BearSSL + * was compiled with support for the system clock on the underlying + * platform, then the current time will automatically be used. Otherwise, + * not setting the validation date and time implies a validation + * failure (except in case of direct trust of the EE key). + * + * \param ctx validation context. + * \param days days since January 1st, 0 AD (Gregorian calendar). + * \param seconds seconds since midnight (0 to 86400). + */ +static __inline void +br_x509_minimal_set_time(br_x509_minimal_context *ctx, + uint32_t days, uint32_t seconds) +{ + ctx->days = days; + ctx->seconds = seconds; + ctx->itime = 0; +} + +/** + * \brief Set the validity range callback function for the X.509 + * "minimal" engine. + * + * The provided function will be invoked to check whether the validation + * date is within the validity range for a given X.509 certificate; a + * call will be issued for each considered certificate. The provided + * context pointer (itime_ctx) will be passed as first parameter to the + * callback. + * + * \param tctx context for callback invocation. + * \param cb callback function. + */ +static __inline void +br_x509_minimal_set_time_callback(br_x509_minimal_context *ctx, + void *itime_ctx, br_x509_time_check itime) +{ + ctx->itime_ctx = itime_ctx; + ctx->itime = itime; +} + +/** + * \brief Set the minimal acceptable length for RSA keys (X.509 "minimal" + * engine). + * + * The RSA key length is expressed in bytes. The default minimum key + * length is 128 bytes, corresponding to 1017 bits. RSA keys shorter + * than the configured length will be rejected, implying validation + * failure. This setting applies to keys extracted from certificates + * (both end-entity, and intermediate CA) but not to "CA" trust anchors. + * + * \param ctx validation context. + * \param byte_length minimum RSA key length, **in bytes** (not bits). + */ +static __inline void +br_x509_minimal_set_minrsa(br_x509_minimal_context *ctx, int byte_length) +{ + ctx->min_rsa_size = (int16_t)(byte_length - 128); +} + +/** + * \brief Set the name elements to gather. + * + * The provided array is linked in the context. The elements are + * gathered from the EE certificate. If the same element type is + * requested several times, then the relevant structures will be filled + * in the order the matching values are encountered in the certificate. + * + * \param ctx validation context. + * \param elts array of name element structures to fill. + * \param num_elts number of name element structures to fill. + */ +static __inline void +br_x509_minimal_set_name_elements(br_x509_minimal_context *ctx, + br_name_element *elts, size_t num_elts) +{ + ctx->name_elts = elts; + ctx->num_name_elts = num_elts; +} + +/** + * \brief X.509 decoder context. + * + * This structure is _not_ for X.509 validation, but for extracting + * names and public keys from encoded certificates. Intended usage is + * to use (self-signed) certificates as trust anchors. + * + * Contents are opaque and shall not be accessed directly. + */ +typedef struct { + +#ifndef BR_DOXYGEN_IGNORE + /* Structure for returning the public key. */ + br_x509_pkey pkey; + + /* CPU for the T0 virtual machine. */ + struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; + } cpu; + uint32_t dp_stack[32]; + uint32_t rp_stack[32]; + int err; + + /* The pad serves as destination for various operations. */ + unsigned char pad[256]; + + /* Flag set when decoding succeeds. */ + unsigned char decoded; + + /* Validity dates. */ + uint32_t notbefore_days, notbefore_seconds; + uint32_t notafter_days, notafter_seconds; + + /* The "CA" flag. This is set to true if the certificate contains + a Basic Constraints extension that asserts CA status. */ + unsigned char isCA; + + /* DN processing: the subject DN is extracted and pushed to the + provided callback. */ + unsigned char copy_dn; + void *append_dn_ctx; + void (*append_dn)(void *ctx, const void *buf, size_t len); + + /* Certificate data chunk. */ + const unsigned char *hbuf; + size_t hlen; + + /* Buffer for decoded public key. */ + unsigned char pkey_data[BR_X509_BUFSIZE_KEY]; + + /* Type of key and hash function used in the certificate signature. */ + unsigned char signer_key_type; + unsigned char signer_hash_id; +#endif + +} br_x509_decoder_context; + +/** + * \brief Initialise an X.509 decoder context for processing a new + * certificate. + * + * The `append_dn()` callback (with opaque context `append_dn_ctx`) + * will be invoked to receive, chunk by chunk, the certificate's + * subject DN. If `append_dn` is `0` then the subject DN will be + * ignored. + * + * \param ctx X.509 decoder context to initialise. + * \param append_dn DN receiver callback (or `0`). + * \param append_dn_ctx context for the DN receiver callback. + */ +void br_x509_decoder_init(br_x509_decoder_context *ctx, + void (*append_dn)(void *ctx, const void *buf, size_t len), + void *append_dn_ctx); + +/** + * \brief Push some certificate bytes into a decoder context. + * + * If `len` is non-zero, then that many bytes are pushed, from address + * `data`, into the provided decoder context. + * + * \param ctx X.509 decoder context. + * \param data certificate data chunk. + * \param len certificate data chunk length (in bytes). + */ +void br_x509_decoder_push(br_x509_decoder_context *ctx, + const void *data, size_t len); + +/** + * \brief Obtain the decoded public key. + * + * Returned value is a pointer to a structure internal to the decoder + * context; releasing or reusing the decoder context invalidates that + * structure. + * + * If decoding was not finished, or failed, then `NULL` is returned. + * + * \param ctx X.509 decoder context. + * \return the public key, or `NULL` on unfinished/error. + */ +static __inline br_x509_pkey * +br_x509_decoder_get_pkey(br_x509_decoder_context *ctx) +{ + if (ctx->decoded && ctx->err == 0) { + return &ctx->pkey; + } else { + return NULL; + } +} + +/** + * \brief Get decoder error status. + * + * If no error was reported yet but the certificate decoding is not + * finished, then the error code is `BR_ERR_X509_TRUNCATED`. If decoding + * was successful, then 0 is returned. + * + * \param ctx X.509 decoder context. + * \return 0 on successful decoding, or a non-zero error code. + */ +static __inline int +br_x509_decoder_last_error(br_x509_decoder_context *ctx) +{ + if (ctx->err != 0) { + return ctx->err; + } + if (!ctx->decoded) { + return BR_ERR_X509_TRUNCATED; + } + return 0; +} + +/** + * \brief Get the "isCA" flag from an X.509 decoder context. + * + * This flag is set if the decoded certificate claims to be a CA through + * a Basic Constraints extension. This flag should not be read before + * decoding completed successfully. + * + * \param ctx X.509 decoder context. + * \return the "isCA" flag. + */ +static __inline int +br_x509_decoder_isCA(br_x509_decoder_context *ctx) +{ + return ctx->isCA; +} + +/** + * \brief Get the issuing CA key type (type of algorithm used to sign the + * decoded certificate). + * + * This is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. The value 0 is returned + * if the signature type was not recognised. + * + * \param ctx X.509 decoder context. + * \return the issuing CA key type. + */ +static __inline int +br_x509_decoder_get_signer_key_type(br_x509_decoder_context *ctx) +{ + return ctx->signer_key_type; +} + +/** + * \brief Get the identifier for the hash function used to sign the decoded + * certificate. + * + * This is 0 if the hash function was not recognised. + * + * \param ctx X.509 decoder context. + * \return the signature hash function identifier. + */ +static __inline int +br_x509_decoder_get_signer_hash_id(br_x509_decoder_context *ctx) +{ + return ctx->signer_hash_id; +} + +/** + * \brief Type for an X.509 certificate (DER-encoded). + */ +typedef struct { + /** \brief The DER-encoded certificate data. */ + unsigned char *data; + /** \brief The DER-encoded certificate length (in bytes). */ + size_t data_len; +} br_x509_certificate; + +/** + * \brief Private key decoder context. + * + * The private key decoder recognises RSA and EC private keys, either in + * their raw, DER-encoded format, or wrapped in an unencrypted PKCS#8 + * archive (again DER-encoded). + * + * Structure contents are opaque and shall not be accessed directly. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + /* Structure for returning the private key. */ + union { + br_rsa_private_key rsa; + br_ec_private_key ec; + } key; + + /* CPU for the T0 virtual machine. */ + struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; + } cpu; + uint32_t dp_stack[32]; + uint32_t rp_stack[32]; + int err; + + /* Private key data chunk. */ + const unsigned char *hbuf; + size_t hlen; + + /* The pad serves as destination for various operations. */ + unsigned char pad[256]; + + /* Decoded key type; 0 until decoding is complete. */ + unsigned char key_type; + + /* Buffer for the private key elements. It shall be large enough + to accommodate all elements for a RSA-4096 private key (roughly + five 2048-bit integers, possibly a bit more). */ + unsigned char key_data[3 * BR_X509_BUFSIZE_SIG]; +#endif +} br_skey_decoder_context; + +/** + * \brief Initialise a private key decoder context. + * + * \param ctx key decoder context to initialise. + */ +void br_skey_decoder_init(br_skey_decoder_context *ctx); + +/** + * \brief Push some data bytes into a private key decoder context. + * + * If `len` is non-zero, then that many data bytes, starting at address + * `data`, are pushed into the decoder. + * + * \param ctx key decoder context. + * \param data private key data chunk. + * \param len private key data chunk length (in bytes). + */ +void br_skey_decoder_push(br_skey_decoder_context *ctx, + const void *data, size_t len); + +/** + * \brief Get the decoding status for a private key. + * + * Decoding status is 0 on success, or a non-zero error code. If the + * decoding is unfinished when this function is called, then the + * status code `BR_ERR_X509_TRUNCATED` is returned. + * + * \param ctx key decoder context. + * \return 0 on successful decoding, or a non-zero error code. + */ +static __inline int +br_skey_decoder_last_error(const br_skey_decoder_context *ctx) +{ + if (ctx->err != 0) { + return ctx->err; + } + if (ctx->key_type == 0) { + return BR_ERR_X509_TRUNCATED; + } + return 0; +} + +/** + * \brief Get the decoded private key type. + * + * Private key type is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. If decoding is + * not finished or failed, then 0 is returned. + * + * \param ctx key decoder context. + * \return decoded private key type, or 0. + */ +static __inline int +br_skey_decoder_key_type(const br_skey_decoder_context *ctx) +{ + if (ctx->err == 0) { + return ctx->key_type; + } else { + return 0; + } +} + +/** + * \brief Get the decoded RSA private key. + * + * This function returns `NULL` if the decoding failed, or is not + * finished, or the key is not RSA. The returned pointer references + * structures within the context that can become invalid if the context + * is reused or released. + * + * \param ctx key decoder context. + * \return decoded RSA private key, or `NULL`. + */ +static __inline const br_rsa_private_key * +br_skey_decoder_get_rsa(const br_skey_decoder_context *ctx) +{ + if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_RSA) { + return &ctx->key.rsa; + } else { + return NULL; + } +} + +/** + * \brief Get the decoded EC private key. + * + * This function returns `NULL` if the decoding failed, or is not + * finished, or the key is not EC. The returned pointer references + * structures within the context that can become invalid if the context + * is reused or released. + * + * \param ctx key decoder context. + * \return decoded EC private key, or `NULL`. + */ +static __inline const br_ec_private_key * +br_skey_decoder_get_ec(const br_skey_decoder_context *ctx) +{ + if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_EC) { + return &ctx->key.ec; + } else { + return NULL; + } +} + +/** + * \brief Encode an RSA private key (raw DER format). + * + * This function encodes the provided key into the "raw" format specified + * in PKCS#1 (RFC 8017, Appendix C, type `RSAPrivateKey`), with DER + * encoding rules. + * + * The key elements are: + * + * - `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`) + * + * - `pk`: the public key (`n` and `e`) + * + * - `d` (size: `dlen` bytes): the private exponent + * + * The public key elements, and the private exponent `d`, can be + * recomputed from the private key (see `br_rsa_compute_modulus()`, + * `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`). + * + * If `dest` is not `NULL`, then the encoded key is written at that + * address, and the encoded length (in bytes) is returned. If `dest` is + * `NULL`, then nothing is written, but the encoded length is still + * computed and returned. + * + * \param dest the destination buffer (or `NULL`). + * \param sk the RSA private key. + * \param pk the RSA public key. + * \param d the RSA private exponent. + * \param dlen the RSA private exponent length (in bytes). + * \return the encoded key length (in bytes). + */ +size_t br_encode_rsa_raw_der(void *dest, const br_rsa_private_key *sk, + const br_rsa_public_key *pk, const void *d, size_t dlen); + +/** + * \brief Encode an RSA private key (PKCS#8 DER format). + * + * This function encodes the provided key into the PKCS#8 format + * (RFC 5958, type `OneAsymmetricKey`). It wraps around the "raw DER" + * format for the RSA key, as implemented by `br_encode_rsa_raw_der()`. + * + * The key elements are: + * + * - `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`) + * + * - `pk`: the public key (`n` and `e`) + * + * - `d` (size: `dlen` bytes): the private exponent + * + * The public key elements, and the private exponent `d`, can be + * recomputed from the private key (see `br_rsa_compute_modulus()`, + * `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`). + * + * If `dest` is not `NULL`, then the encoded key is written at that + * address, and the encoded length (in bytes) is returned. If `dest` is + * `NULL`, then nothing is written, but the encoded length is still + * computed and returned. + * + * \param dest the destination buffer (or `NULL`). + * \param sk the RSA private key. + * \param pk the RSA public key. + * \param d the RSA private exponent. + * \param dlen the RSA private exponent length (in bytes). + * \return the encoded key length (in bytes). + */ +size_t br_encode_rsa_pkcs8_der(void *dest, const br_rsa_private_key *sk, + const br_rsa_public_key *pk, const void *d, size_t dlen); + +/** + * \brief Encode an EC private key (raw DER format). + * + * This function encodes the provided key into the "raw" format specified + * in RFC 5915 (type `ECPrivateKey`), with DER encoding rules. + * + * The private key is provided in `sk`, the public key being `pk`. If + * `pk` is `NULL`, then the encoded key will not include the public key + * in its `publicKey` field (which is nominally optional). + * + * If `dest` is not `NULL`, then the encoded key is written at that + * address, and the encoded length (in bytes) is returned. If `dest` is + * `NULL`, then nothing is written, but the encoded length is still + * computed and returned. + * + * If the key cannot be encoded (e.g. because there is no known OBJECT + * IDENTIFIER for the used curve), then 0 is returned. + * + * \param dest the destination buffer (or `NULL`). + * \param sk the EC private key. + * \param pk the EC public key (or `NULL`). + * \return the encoded key length (in bytes), or 0. + */ +size_t br_encode_ec_raw_der(void *dest, + const br_ec_private_key *sk, const br_ec_public_key *pk); + +/** + * \brief Encode an EC private key (PKCS#8 DER format). + * + * This function encodes the provided key into the PKCS#8 format + * (RFC 5958, type `OneAsymmetricKey`). The curve is identified + * by an OID provided as parameters to the `privateKeyAlgorithm` + * field. The private key value (contents of the `privateKey` field) + * contains the DER encoding of the `ECPrivateKey` type defined in + * RFC 5915, without the `parameters` field (since they would be + * redundant with the information in `privateKeyAlgorithm`). + * + * The private key is provided in `sk`, the public key being `pk`. If + * `pk` is not `NULL`, then the encoded public key is included in the + * `publicKey` field of the private key value (but not in the `publicKey` + * field of the PKCS#8 `OneAsymmetricKey` wrapper). + * + * If `dest` is not `NULL`, then the encoded key is written at that + * address, and the encoded length (in bytes) is returned. If `dest` is + * `NULL`, then nothing is written, but the encoded length is still + * computed and returned. + * + * If the key cannot be encoded (e.g. because there is no known OBJECT + * IDENTIFIER for the used curve), then 0 is returned. + * + * \param dest the destination buffer (or `NULL`). + * \param sk the EC private key. + * \param pk the EC public key (or `NULL`). + * \return the encoded key length (in bytes), or 0. + */ +size_t br_encode_ec_pkcs8_der(void *dest, + const br_ec_private_key *sk, const br_ec_public_key *pk); + +/** + * \brief PEM banner for RSA private key (raw). + */ +#define BR_ENCODE_PEM_RSA_RAW "RSA PRIVATE KEY" + +/** + * \brief PEM banner for EC private key (raw). + */ +#define BR_ENCODE_PEM_EC_RAW "EC PRIVATE KEY" + +/** + * \brief PEM banner for an RSA or EC private key in PKCS#8 format. + */ +#define BR_ENCODE_PEM_PKCS8 "PRIVATE KEY" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BearSSL-OG/libbearssl/src/aead/ccm.c b/BearSSL-OG/libbearssl/src/aead/ccm.c new file mode 100644 index 0000000..68cc913 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/aead/ccm.c @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Implementation Notes + * ==================== + * + * The combined CTR + CBC-MAC functions can only handle full blocks, + * so some buffering is necessary. + * + * - 'ptr' contains a value from 0 to 15, which is the number of bytes + * accumulated in buf[] that still needs to be processed with the + * current CBC-MAC computation. + * + * - When processing the message itself, CTR encryption/decryption is + * also done at the same time. The first 'ptr' bytes of buf[] then + * contains the plaintext bytes, while the last '16 - ptr' bytes of + * buf[] are the remnants of the stream block, to be used against + * the next input bytes, when available. When 'ptr' is 0, the + * contents of buf[] are to be ignored. + * + * - The current counter and running CBC-MAC values are kept in 'ctr' + * and 'cbcmac', respectively. + */ + +/* see bearssl_block.h */ +void +br_ccm_init(br_ccm_context *ctx, const br_block_ctrcbc_class **bctx) +{ + ctx->bctx = bctx; +} + +/* see bearssl_block.h */ +int +br_ccm_reset(br_ccm_context *ctx, const void *nonce, size_t nonce_len, + uint64_t aad_len, uint64_t data_len, size_t tag_len) +{ + unsigned char tmp[16]; + unsigned u, q; + + if (nonce_len < 7 || nonce_len > 13) { + return 0; + } + if (tag_len < 4 || tag_len > 16 || (tag_len & 1) != 0) { + return 0; + } + q = 15 - (unsigned)nonce_len; + ctx->tag_len = tag_len; + + /* + * Block B0, to start CBC-MAC. + */ + tmp[0] = (aad_len > 0 ? 0x40 : 0x00) + | (((unsigned)tag_len - 2) << 2) + | (q - 1); + memcpy(tmp + 1, nonce, nonce_len); + for (u = 0; u < q; u ++) { + tmp[15 - u] = (unsigned char)data_len; + data_len >>= 8; + } + if (data_len != 0) { + /* + * If the data length was not entirely consumed in the + * loop above, then it exceeds the maximum limit of + * q bytes (when encoded). + */ + return 0; + } + + /* + * Start CBC-MAC. + */ + memset(ctx->cbcmac, 0, sizeof ctx->cbcmac); + (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, tmp, sizeof tmp); + + /* + * Assemble AAD length header. + */ + if ((aad_len >> 32) != 0) { + ctx->buf[0] = 0xFF; + ctx->buf[1] = 0xFF; + br_enc64be(ctx->buf + 2, aad_len); + ctx->ptr = 10; + } else if (aad_len >= 0xFF00) { + ctx->buf[0] = 0xFF; + ctx->buf[1] = 0xFE; + br_enc32be(ctx->buf + 2, (uint32_t)aad_len); + ctx->ptr = 6; + } else if (aad_len > 0) { + br_enc16be(ctx->buf, (unsigned)aad_len); + ctx->ptr = 2; + } else { + ctx->ptr = 0; + } + + /* + * Make initial counter value and compute tag mask. + */ + ctx->ctr[0] = q - 1; + memcpy(ctx->ctr + 1, nonce, nonce_len); + memset(ctx->ctr + 1 + nonce_len, 0, q); + memset(ctx->tagmask, 0, sizeof ctx->tagmask); + (*ctx->bctx)->ctr(ctx->bctx, ctx->ctr, + ctx->tagmask, sizeof ctx->tagmask); + + return 1; +} + +/* see bearssl_block.h */ +void +br_ccm_aad_inject(br_ccm_context *ctx, const void *data, size_t len) +{ + const unsigned char *dbuf; + size_t ptr; + + dbuf = data; + + /* + * Complete partial block, if needed. + */ + ptr = ctx->ptr; + if (ptr != 0) { + size_t clen; + + clen = (sizeof ctx->buf) - ptr; + if (clen > len) { + memcpy(ctx->buf + ptr, dbuf, len); + ctx->ptr = ptr + len; + return; + } + memcpy(ctx->buf + ptr, dbuf, clen); + dbuf += clen; + len -= clen; + (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, + ctx->buf, sizeof ctx->buf); + } + + /* + * Process complete blocks. + */ + ptr = len & 15; + len -= ptr; + (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, dbuf, len); + dbuf += len; + + /* + * Copy last partial block in the context buffer. + */ + memcpy(ctx->buf, dbuf, ptr); + ctx->ptr = ptr; +} + +/* see bearssl_block.h */ +void +br_ccm_flip(br_ccm_context *ctx) +{ + size_t ptr; + + /* + * Complete AAD partial block with zeros, if necessary. + */ + ptr = ctx->ptr; + if (ptr != 0) { + memset(ctx->buf + ptr, 0, (sizeof ctx->buf) - ptr); + (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, + ctx->buf, sizeof ctx->buf); + ctx->ptr = 0; + } + + /* + * Counter was already set by br_ccm_reset(). + */ +} + +/* see bearssl_block.h */ +void +br_ccm_run(br_ccm_context *ctx, int encrypt, void *data, size_t len) +{ + unsigned char *dbuf; + size_t ptr; + + dbuf = data; + + /* + * Complete a partial block, if any: ctx->buf[] contains + * ctx->ptr plaintext bytes (already reported), and the other + * bytes are CTR stream output. + */ + ptr = ctx->ptr; + if (ptr != 0) { + size_t clen; + size_t u; + + clen = (sizeof ctx->buf) - ptr; + if (clen > len) { + clen = len; + } + if (encrypt) { + for (u = 0; u < clen; u ++) { + unsigned w, x; + + w = ctx->buf[ptr + u]; + x = dbuf[u]; + ctx->buf[ptr + u] = x; + dbuf[u] = w ^ x; + } + } else { + for (u = 0; u < clen; u ++) { + unsigned w; + + w = ctx->buf[ptr + u] ^ dbuf[u]; + dbuf[u] = w; + ctx->buf[ptr + u] = w; + } + } + dbuf += clen; + len -= clen; + ptr += clen; + if (ptr < sizeof ctx->buf) { + ctx->ptr = ptr; + return; + } + (*ctx->bctx)->mac(ctx->bctx, + ctx->cbcmac, ctx->buf, sizeof ctx->buf); + } + + /* + * Process all complete blocks. Note that the ctrcbc API is for + * encrypt-then-MAC (CBC-MAC is computed over the encrypted + * blocks) while CCM uses MAC-and-encrypt (CBC-MAC is computed + * over the plaintext blocks). Therefore, we need to use the + * _decryption_ function for encryption, and the encryption + * function for decryption (this works because CTR encryption + * and decryption are identical, so the choice really is about + * computing the CBC-MAC before or after XORing with the CTR + * stream). + */ + ptr = len & 15; + len -= ptr; + if (encrypt) { + (*ctx->bctx)->decrypt(ctx->bctx, ctx->ctr, ctx->cbcmac, + dbuf, len); + } else { + (*ctx->bctx)->encrypt(ctx->bctx, ctx->ctr, ctx->cbcmac, + dbuf, len); + } + dbuf += len; + + /* + * If there is some remaining data, then we need to compute an + * extra block of CTR stream. + */ + if (ptr != 0) { + size_t u; + + memset(ctx->buf, 0, sizeof ctx->buf); + (*ctx->bctx)->ctr(ctx->bctx, ctx->ctr, + ctx->buf, sizeof ctx->buf); + if (encrypt) { + for (u = 0; u < ptr; u ++) { + unsigned w, x; + + w = ctx->buf[u]; + x = dbuf[u]; + ctx->buf[u] = x; + dbuf[u] = w ^ x; + } + } else { + for (u = 0; u < ptr; u ++) { + unsigned w; + + w = ctx->buf[u] ^ dbuf[u]; + dbuf[u] = w; + ctx->buf[u] = w; + } + } + } + ctx->ptr = ptr; +} + +/* see bearssl_block.h */ +size_t +br_ccm_get_tag(br_ccm_context *ctx, void *tag) +{ + size_t ptr; + size_t u; + + /* + * If there is some buffered data, then we need to pad it with + * zeros and finish up CBC-MAC. + */ + ptr = ctx->ptr; + if (ptr != 0) { + memset(ctx->buf + ptr, 0, (sizeof ctx->buf) - ptr); + (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, + ctx->buf, sizeof ctx->buf); + } + + /* + * XOR the tag mask into the CBC-MAC output. + */ + for (u = 0; u < ctx->tag_len; u ++) { + ctx->cbcmac[u] ^= ctx->tagmask[u]; + } + memcpy(tag, ctx->cbcmac, ctx->tag_len); + return ctx->tag_len; +} + +/* see bearssl_block.h */ +uint32_t +br_ccm_check_tag(br_ccm_context *ctx, const void *tag) +{ + unsigned char tmp[16]; + size_t u, tag_len; + uint32_t z; + + tag_len = br_ccm_get_tag(ctx, tmp); + z = 0; + for (u = 0; u < tag_len; u ++) { + z |= tmp[u] ^ ((const unsigned char *)tag)[u]; + } + return EQ0(z); +} diff --git a/BearSSL-OG/libbearssl/src/aead/eax.c b/BearSSL-OG/libbearssl/src/aead/eax.c new file mode 100644 index 0000000..bcc704a --- /dev/null +++ b/BearSSL-OG/libbearssl/src/aead/eax.c @@ -0,0 +1,525 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Implementation Notes + * ==================== + * + * The combined CTR + CBC-MAC functions can only handle full blocks, + * so some buffering is necessary. Moreover, EAX has a special padding + * rule for CBC-MAC, which implies that we cannot compute the MAC over + * the last received full block until we know whether we are at the + * end of the data or not. + * + * - 'ptr' contains a value from 1 to 16, which is the number of bytes + * accumulated in buf[] that still needs to be processed with the + * current OMAC computation. Beware that this can go to 16: a + * complete block cannot be processed until it is known whether it + * is the last block or not. However, it can never be 0, because + * OMAC^t works on an input that is at least one-block long. + * + * - When processing the message itself, CTR encryption/decryption is + * also done at the same time. The first 'ptr' bytes of buf[] then + * contains the encrypted bytes, while the last '16 - ptr' bytes of + * buf[] are the remnants of the stream block, to be used against + * the next input bytes, when available. + * + * - The current counter and running CBC-MAC values are kept in 'ctr' + * and 'cbcmac', respectively. + * + * - The derived keys for padding are kept in L2 and L4 (double and + * quadruple of Enc_K(0^n), in GF(2^128), respectively). + */ + +/* + * Start an OMAC computation; the first block is the big-endian + * representation of the provided value ('val' must fit on one byte). + * We make it a delayed block because it may also be the last one, + */ +static void +omac_start(br_eax_context *ctx, unsigned val) +{ + memset(ctx->cbcmac, 0, sizeof ctx->cbcmac); + memset(ctx->buf, 0, sizeof ctx->buf); + ctx->buf[15] = val; + ctx->ptr = 16; +} + +/* + * Double a value in finite field GF(2^128), defined with modulus + * X^128+X^7+X^2+X+1. + */ +static void +double_gf128(unsigned char *dst, const unsigned char *src) +{ + unsigned cc; + int i; + + cc = 0x87 & -((unsigned)src[0] >> 7); + for (i = 15; i >= 0; i --) { + unsigned z; + + z = (src[i] << 1) ^ cc; + cc = z >> 8; + dst[i] = (unsigned char)z; + } +} + +/* + * Apply padding to the last block, currently in ctx->buf (with + * ctx->ptr bytes), and finalize OMAC computation. + */ +static void +do_pad(br_eax_context *ctx) +{ + unsigned char *pad; + size_t ptr, u; + + ptr = ctx->ptr; + if (ptr == 16) { + pad = ctx->L2; + } else { + ctx->buf[ptr ++] = 0x80; + memset(ctx->buf + ptr, 0x00, 16 - ptr); + pad = ctx->L4; + } + for (u = 0; u < sizeof ctx->buf; u ++) { + ctx->buf[u] ^= pad[u]; + } + (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, ctx->buf, sizeof ctx->buf); +} + +/* + * Apply CBC-MAC on the provided data, with buffering management. + * + * Upon entry, two situations are acceptable: + * + * ctx->ptr == 0: there is no data to process in ctx->buf + * ctx->ptr == 16: there is a full block of unprocessed data in ctx->buf + * + * Upon exit, ctx->ptr may be zero only if it was already zero on entry, + * and len == 0. In all other situations, ctx->ptr will be non-zero on + * exit (and may have value 16). + */ +static void +do_cbcmac_chunk(br_eax_context *ctx, const void *data, size_t len) +{ + size_t ptr; + + if (len == 0) { + return; + } + ptr = len & (size_t)15; + if (ptr == 0) { + len -= 16; + ptr = 16; + } else { + len -= ptr; + } + if (ctx->ptr == 16) { + (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, + ctx->buf, sizeof ctx->buf); + } + (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, data, len); + memcpy(ctx->buf, (const unsigned char *)data + len, ptr); + ctx->ptr = ptr; +} + +/* see bearssl_aead.h */ +void +br_eax_init(br_eax_context *ctx, const br_block_ctrcbc_class **bctx) +{ + unsigned char tmp[16], iv[16]; + + ctx->vtable = &br_eax_vtable; + ctx->bctx = bctx; + + /* + * Encrypt a whole-zero block to compute L2 and L4. + */ + memset(tmp, 0, sizeof tmp); + memset(iv, 0, sizeof iv); + (*bctx)->ctr(bctx, iv, tmp, sizeof tmp); + double_gf128(ctx->L2, tmp); + double_gf128(ctx->L4, ctx->L2); +} + +/* see bearssl_aead.h */ +void +br_eax_capture(const br_eax_context *ctx, br_eax_state *st) +{ + /* + * We capture the three OMAC* states _after_ processing the + * initial block (assuming that nonce, message and AAD are + * all non-empty). + */ + int i; + + memset(st->st, 0, sizeof st->st); + for (i = 0; i < 3; i ++) { + unsigned char tmp[16]; + + memset(tmp, 0, sizeof tmp); + tmp[15] = (unsigned char)i; + (*ctx->bctx)->mac(ctx->bctx, st->st[i], tmp, sizeof tmp); + } +} + +/* see bearssl_aead.h */ +void +br_eax_reset(br_eax_context *ctx, const void *nonce, size_t len) +{ + /* + * Process nonce with OMAC^0. + */ + omac_start(ctx, 0); + do_cbcmac_chunk(ctx, nonce, len); + do_pad(ctx); + memcpy(ctx->nonce, ctx->cbcmac, sizeof ctx->cbcmac); + + /* + * Start OMAC^1 for the AAD ("header" in the EAX specification). + */ + omac_start(ctx, 1); + + /* + * We use ctx->head[0] as temporary flag to mark that we are + * using a "normal" reset(). + */ + ctx->head[0] = 0; +} + +/* see bearssl_aead.h */ +void +br_eax_reset_pre_aad(br_eax_context *ctx, const br_eax_state *st, + const void *nonce, size_t len) +{ + if (len == 0) { + omac_start(ctx, 0); + } else { + memcpy(ctx->cbcmac, st->st[0], sizeof ctx->cbcmac); + ctx->ptr = 0; + do_cbcmac_chunk(ctx, nonce, len); + } + do_pad(ctx); + memcpy(ctx->nonce, ctx->cbcmac, sizeof ctx->cbcmac); + + memcpy(ctx->cbcmac, st->st[1], sizeof ctx->cbcmac); + ctx->ptr = 0; + + memcpy(ctx->ctr, st->st[2], sizeof ctx->ctr); + + /* + * We use ctx->head[0] as a flag to indicate that we use a + * a recorded state, with ctx->ctr containing the preprocessed + * first block for OMAC^2. + */ + ctx->head[0] = 1; +} + +/* see bearssl_aead.h */ +void +br_eax_reset_post_aad(br_eax_context *ctx, const br_eax_state *st, + const void *nonce, size_t len) +{ + if (len == 0) { + omac_start(ctx, 0); + } else { + memcpy(ctx->cbcmac, st->st[0], sizeof ctx->cbcmac); + ctx->ptr = 0; + do_cbcmac_chunk(ctx, nonce, len); + } + do_pad(ctx); + memcpy(ctx->nonce, ctx->cbcmac, sizeof ctx->cbcmac); + memcpy(ctx->ctr, ctx->nonce, sizeof ctx->nonce); + + memcpy(ctx->head, st->st[1], sizeof ctx->head); + + memcpy(ctx->cbcmac, st->st[2], sizeof ctx->cbcmac); + ctx->ptr = 0; +} + +/* see bearssl_aead.h */ +void +br_eax_aad_inject(br_eax_context *ctx, const void *data, size_t len) +{ + size_t ptr; + + ptr = ctx->ptr; + + /* + * If there is a partial block, first complete it. + */ + if (ptr < 16) { + size_t clen; + + clen = 16 - ptr; + if (len <= clen) { + memcpy(ctx->buf + ptr, data, len); + ctx->ptr = ptr + len; + return; + } + memcpy(ctx->buf + ptr, data, clen); + data = (const unsigned char *)data + clen; + len -= clen; + } + + /* + * We now have a full block in buf[], and this is not the last + * block. + */ + do_cbcmac_chunk(ctx, data, len); +} + +/* see bearssl_aead.h */ +void +br_eax_flip(br_eax_context *ctx) +{ + int from_capture; + + /* + * ctx->head[0] may be non-zero if the context was reset with + * a pre-AAD captured state. In that case, ctx->ctr[] contains + * the state for OMAC^2 _after_ processing the first block. + */ + from_capture = ctx->head[0]; + + /* + * Complete the OMAC computation on the AAD. + */ + do_pad(ctx); + memcpy(ctx->head, ctx->cbcmac, sizeof ctx->cbcmac); + + /* + * Start OMAC^2 for the encrypted data. + * If the context was initialized from a captured state, then + * the OMAC^2 value is in the ctr[] array. + */ + if (from_capture) { + memcpy(ctx->cbcmac, ctx->ctr, sizeof ctx->cbcmac); + ctx->ptr = 0; + } else { + omac_start(ctx, 2); + } + + /* + * Initial counter value for CTR is the processed nonce. + */ + memcpy(ctx->ctr, ctx->nonce, sizeof ctx->nonce); +} + +/* see bearssl_aead.h */ +void +br_eax_run(br_eax_context *ctx, int encrypt, void *data, size_t len) +{ + unsigned char *dbuf; + size_t ptr; + + /* + * Ensure that there is actual data to process. + */ + if (len == 0) { + return; + } + + dbuf = data; + ptr = ctx->ptr; + + /* + * We may have ptr == 0 here if we initialized from a captured + * state. In that case, there is no partially consumed block + * or unprocessed data. + */ + if (ptr != 0 && ptr != 16) { + /* + * We have a partially consumed block. + */ + size_t u, clen; + + clen = 16 - ptr; + if (len <= clen) { + clen = len; + } + if (encrypt) { + for (u = 0; u < clen; u ++) { + ctx->buf[ptr + u] ^= dbuf[u]; + } + memcpy(dbuf, ctx->buf + ptr, clen); + } else { + for (u = 0; u < clen; u ++) { + unsigned dx, sx; + + sx = ctx->buf[ptr + u]; + dx = dbuf[u]; + ctx->buf[ptr + u] = dx; + dbuf[u] = sx ^ dx; + } + } + + if (len <= clen) { + ctx->ptr = ptr + clen; + return; + } + dbuf += clen; + len -= clen; + } + + /* + * We now have a complete encrypted block in buf[] that must still + * be processed with OMAC, and this is not the final buf. + * Exception: when ptr == 0, no block has been produced yet. + */ + if (ptr != 0) { + (*ctx->bctx)->mac(ctx->bctx, ctx->cbcmac, + ctx->buf, sizeof ctx->buf); + } + + /* + * Do CTR encryption or decryption and CBC-MAC for all full blocks + * except the last. + */ + ptr = len & (size_t)15; + if (ptr == 0) { + len -= 16; + ptr = 16; + } else { + len -= ptr; + } + if (encrypt) { + (*ctx->bctx)->encrypt(ctx->bctx, ctx->ctr, ctx->cbcmac, + dbuf, len); + } else { + (*ctx->bctx)->decrypt(ctx->bctx, ctx->ctr, ctx->cbcmac, + dbuf, len); + } + dbuf += len; + + /* + * Compute next block of CTR stream, and use it to finish + * encrypting or decrypting the data. + */ + memset(ctx->buf, 0, sizeof ctx->buf); + (*ctx->bctx)->ctr(ctx->bctx, ctx->ctr, ctx->buf, sizeof ctx->buf); + if (encrypt) { + size_t u; + + for (u = 0; u < ptr; u ++) { + ctx->buf[u] ^= dbuf[u]; + } + memcpy(dbuf, ctx->buf, ptr); + } else { + size_t u; + + for (u = 0; u < ptr; u ++) { + unsigned dx, sx; + + sx = ctx->buf[u]; + dx = dbuf[u]; + ctx->buf[u] = dx; + dbuf[u] = sx ^ dx; + } + } + ctx->ptr = ptr; +} + +/* + * Complete tag computation. The final tag is written in ctx->cbcmac. + */ +static void +do_final(br_eax_context *ctx) +{ + size_t u; + + do_pad(ctx); + + /* + * Authentication tag is the XOR of the three OMAC outputs for + * the nonce, AAD and encrypted data. + */ + for (u = 0; u < 16; u ++) { + ctx->cbcmac[u] ^= ctx->nonce[u] ^ ctx->head[u]; + } +} + +/* see bearssl_aead.h */ +void +br_eax_get_tag(br_eax_context *ctx, void *tag) +{ + do_final(ctx); + memcpy(tag, ctx->cbcmac, sizeof ctx->cbcmac); +} + +/* see bearssl_aead.h */ +void +br_eax_get_tag_trunc(br_eax_context *ctx, void *tag, size_t len) +{ + do_final(ctx); + memcpy(tag, ctx->cbcmac, len); +} + +/* see bearssl_aead.h */ +uint32_t +br_eax_check_tag_trunc(br_eax_context *ctx, const void *tag, size_t len) +{ + unsigned char tmp[16]; + size_t u; + int x; + + br_eax_get_tag(ctx, tmp); + x = 0; + for (u = 0; u < len; u ++) { + x |= tmp[u] ^ ((const unsigned char *)tag)[u]; + } + return EQ0(x); +} + +/* see bearssl_aead.h */ +uint32_t +br_eax_check_tag(br_eax_context *ctx, const void *tag) +{ + return br_eax_check_tag_trunc(ctx, tag, 16); +} + +/* see bearssl_aead.h */ +const br_aead_class br_eax_vtable = { + 16, + (void (*)(const br_aead_class **, const void *, size_t)) + &br_eax_reset, + (void (*)(const br_aead_class **, const void *, size_t)) + &br_eax_aad_inject, + (void (*)(const br_aead_class **)) + &br_eax_flip, + (void (*)(const br_aead_class **, int, void *, size_t)) + &br_eax_run, + (void (*)(const br_aead_class **, void *)) + &br_eax_get_tag, + (uint32_t (*)(const br_aead_class **, const void *)) + &br_eax_check_tag, + (void (*)(const br_aead_class **, void *, size_t)) + &br_eax_get_tag_trunc, + (uint32_t (*)(const br_aead_class **, const void *, size_t)) + &br_eax_check_tag_trunc +}; diff --git a/BearSSL-OG/libbearssl/src/aead/gcm.c b/BearSSL-OG/libbearssl/src/aead/gcm.c new file mode 100644 index 0000000..ede5f08 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/aead/gcm.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Implementation Notes + * ==================== + * + * Since CTR and GHASH implementations can handle only full blocks, a + * 16-byte buffer (buf[]) is maintained in the context: + * + * - When processing AAD, buf[] contains the 0-15 unprocessed bytes. + * + * - When doing CTR encryption / decryption, buf[] contains the AES output + * for the last partial block, to be used with the next few bytes of + * data, as well as the already encrypted bytes. For instance, if the + * processed data length so far is 21 bytes, then buf[0..4] contains + * the five last encrypted bytes, and buf[5..15] contains the next 11 + * AES output bytes to be XORed with the next 11 bytes of input. + * + * The recorded AES output bytes are used to complete the block when + * the corresponding bytes are obtained. Note that buf[] always + * contains the _encrypted_ bytes, whether we apply encryption or + * decryption: these bytes are used as input to GHASH when the block + * is complete. + * + * In both cases, the low bits of the data length counters (count_aad, + * count_ctr) are used to work out the current situation. + */ + +/* see bearssl_aead.h */ +void +br_gcm_init(br_gcm_context *ctx, const br_block_ctr_class **bctx, br_ghash gh) +{ + unsigned char iv[12]; + + ctx->vtable = &br_gcm_vtable; + ctx->bctx = bctx; + ctx->gh = gh; + + /* + * The GHASH key h[] is the raw encryption of the all-zero + * block. Since we only have a CTR implementation, we use it + * with an all-zero IV and a zero counter, to CTR-encrypt an + * all-zero block. + */ + memset(ctx->h, 0, sizeof ctx->h); + memset(iv, 0, sizeof iv); + (*bctx)->run(bctx, iv, 0, ctx->h, sizeof ctx->h); +} + +/* see bearssl_aead.h */ +void +br_gcm_reset(br_gcm_context *ctx, const void *iv, size_t len) +{ + /* + * If the provided nonce is 12 bytes, then this is the initial + * IV for CTR mode; it will be used with a counter that starts + * at 2 (value 1 is for encrypting the GHASH output into the tag). + * + * If the provided nonce has any other length, then it is hashed + * (with GHASH) into a 16-byte value that will be the IV for CTR + * (both 12-byte IV and 32-bit counter). + */ + if (len == 12) { + memcpy(ctx->j0_1, iv, 12); + ctx->j0_2 = 1; + } else { + unsigned char ty[16], tmp[16]; + + memset(ty, 0, sizeof ty); + ctx->gh(ty, ctx->h, iv, len); + memset(tmp, 0, 8); + br_enc64be(tmp + 8, (uint64_t)len << 3); + ctx->gh(ty, ctx->h, tmp, 16); + memcpy(ctx->j0_1, ty, 12); + ctx->j0_2 = br_dec32be(ty + 12); + } + ctx->jc = ctx->j0_2 + 1; + memset(ctx->y, 0, sizeof ctx->y); + ctx->count_aad = 0; + ctx->count_ctr = 0; +} + +/* see bearssl_aead.h */ +void +br_gcm_aad_inject(br_gcm_context *ctx, const void *data, size_t len) +{ + size_t ptr, dlen; + + ptr = (size_t)ctx->count_aad & (size_t)15; + if (ptr != 0) { + /* + * If there is a partial block, then we first try to + * complete it. + */ + size_t clen; + + clen = 16 - ptr; + if (len < clen) { + memcpy(ctx->buf + ptr, data, len); + ctx->count_aad += (uint64_t)len; + return; + } + memcpy(ctx->buf + ptr, data, clen); + ctx->gh(ctx->y, ctx->h, ctx->buf, 16); + data = (const unsigned char *)data + clen; + len -= clen; + ctx->count_aad += (uint64_t)clen; + } + + /* + * Now AAD is aligned on a 16-byte block (with regards to GHASH). + * We process all complete blocks, and save the last partial + * block. + */ + dlen = len & ~(size_t)15; + ctx->gh(ctx->y, ctx->h, data, dlen); + memcpy(ctx->buf, (const unsigned char *)data + dlen, len - dlen); + ctx->count_aad += (uint64_t)len; +} + +/* see bearssl_aead.h */ +void +br_gcm_flip(br_gcm_context *ctx) +{ + /* + * We complete the GHASH computation if there is a partial block. + * The GHASH implementation automatically applies padding with + * zeros. + */ + size_t ptr; + + ptr = (size_t)ctx->count_aad & (size_t)15; + if (ptr != 0) { + ctx->gh(ctx->y, ctx->h, ctx->buf, ptr); + } +} + +/* see bearssl_aead.h */ +void +br_gcm_run(br_gcm_context *ctx, int encrypt, void *data, size_t len) +{ + unsigned char *buf; + size_t ptr, dlen; + + buf = data; + ptr = (size_t)ctx->count_ctr & (size_t)15; + if (ptr != 0) { + /* + * If we have a partial block, then we try to complete it. + */ + size_t u, clen; + + clen = 16 - ptr; + if (len < clen) { + clen = len; + } + for (u = 0; u < clen; u ++) { + unsigned x, y; + + x = buf[u]; + y = x ^ ctx->buf[ptr + u]; + ctx->buf[ptr + u] = encrypt ? y : x; + buf[u] = y; + } + ctx->count_ctr += (uint64_t)clen; + buf += clen; + len -= clen; + if (ptr + clen < 16) { + return; + } + ctx->gh(ctx->y, ctx->h, ctx->buf, 16); + } + + /* + * Process full blocks. + */ + dlen = len & ~(size_t)15; + if (!encrypt) { + ctx->gh(ctx->y, ctx->h, buf, dlen); + } + ctx->jc = (*ctx->bctx)->run(ctx->bctx, ctx->j0_1, ctx->jc, buf, dlen); + if (encrypt) { + ctx->gh(ctx->y, ctx->h, buf, dlen); + } + buf += dlen; + len -= dlen; + ctx->count_ctr += (uint64_t)dlen; + + if (len > 0) { + /* + * There is a partial block. + */ + size_t u; + + memset(ctx->buf, 0, sizeof ctx->buf); + ctx->jc = (*ctx->bctx)->run(ctx->bctx, ctx->j0_1, + ctx->jc, ctx->buf, 16); + for (u = 0; u < len; u ++) { + unsigned x, y; + + x = buf[u]; + y = x ^ ctx->buf[u]; + ctx->buf[u] = encrypt ? y : x; + buf[u] = y; + } + ctx->count_ctr += (uint64_t)len; + } +} + +/* see bearssl_aead.h */ +void +br_gcm_get_tag(br_gcm_context *ctx, void *tag) +{ + size_t ptr; + unsigned char tmp[16]; + + ptr = (size_t)ctx->count_ctr & (size_t)15; + if (ptr > 0) { + /* + * There is a partial block: encrypted/decrypted data has + * been produced, but the encrypted bytes must still be + * processed by GHASH. + */ + ctx->gh(ctx->y, ctx->h, ctx->buf, ptr); + } + + /* + * Final block for GHASH: the AAD and plaintext lengths (in bits). + */ + br_enc64be(tmp, ctx->count_aad << 3); + br_enc64be(tmp + 8, ctx->count_ctr << 3); + ctx->gh(ctx->y, ctx->h, tmp, 16); + + /* + * Tag is the GHASH output XORed with the encryption of the + * nonce with the initial counter value. + */ + memcpy(tag, ctx->y, 16); + (*ctx->bctx)->run(ctx->bctx, ctx->j0_1, ctx->j0_2, tag, 16); +} + +/* see bearssl_aead.h */ +void +br_gcm_get_tag_trunc(br_gcm_context *ctx, void *tag, size_t len) +{ + unsigned char tmp[16]; + + br_gcm_get_tag(ctx, tmp); + memcpy(tag, tmp, len); +} + +/* see bearssl_aead.h */ +uint32_t +br_gcm_check_tag_trunc(br_gcm_context *ctx, const void *tag, size_t len) +{ + unsigned char tmp[16]; + size_t u; + int x; + + br_gcm_get_tag(ctx, tmp); + x = 0; + for (u = 0; u < len; u ++) { + x |= tmp[u] ^ ((const unsigned char *)tag)[u]; + } + return EQ0(x); +} + +/* see bearssl_aead.h */ +uint32_t +br_gcm_check_tag(br_gcm_context *ctx, const void *tag) +{ + return br_gcm_check_tag_trunc(ctx, tag, 16); +} + +/* see bearssl_aead.h */ +const br_aead_class br_gcm_vtable = { + 16, + (void (*)(const br_aead_class **, const void *, size_t)) + &br_gcm_reset, + (void (*)(const br_aead_class **, const void *, size_t)) + &br_gcm_aad_inject, + (void (*)(const br_aead_class **)) + &br_gcm_flip, + (void (*)(const br_aead_class **, int, void *, size_t)) + &br_gcm_run, + (void (*)(const br_aead_class **, void *)) + &br_gcm_get_tag, + (uint32_t (*)(const br_aead_class **, const void *)) + &br_gcm_check_tag, + (void (*)(const br_aead_class **, void *, size_t)) + &br_gcm_get_tag_trunc, + (uint32_t (*)(const br_aead_class **, const void *, size_t)) + &br_gcm_check_tag_trunc +}; diff --git a/BearSSL-OG/libbearssl/src/codec/ccopy.c b/BearSSL-OG/libbearssl/src/codec/ccopy.c new file mode 100644 index 0000000..2beace7 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/ccopy.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_ccopy(uint32_t ctl, void *dst, const void *src, size_t len) +{ + unsigned char *d; + const unsigned char *s; + + d = dst; + s = src; + while (len -- > 0) { + uint32_t x, y; + + x = *s ++; + y = *d; + *d = MUX(ctl, x, y); + d ++; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/dec16be.c b/BearSSL-OG/libbearssl/src/codec/dec16be.c new file mode 100644 index 0000000..4f3f7f4 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/dec16be.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_range_dec16be(uint16_t *v, size_t num, const void *src) +{ + const unsigned char *buf; + + buf = src; + while (num -- > 0) { + *v ++ = br_dec16be(buf); + buf += 2; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/dec16le.c b/BearSSL-OG/libbearssl/src/codec/dec16le.c new file mode 100644 index 0000000..84d8536 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/dec16le.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_range_dec16le(uint16_t *v, size_t num, const void *src) +{ + const unsigned char *buf; + + buf = src; + while (num -- > 0) { + *v ++ = br_dec16le(buf); + buf += 2; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/dec32be.c b/BearSSL-OG/libbearssl/src/codec/dec32be.c new file mode 100644 index 0000000..5a8fc59 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/dec32be.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_range_dec32be(uint32_t *v, size_t num, const void *src) +{ + const unsigned char *buf; + + buf = src; + while (num -- > 0) { + *v ++ = br_dec32be(buf); + buf += 4; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/dec32le.c b/BearSSL-OG/libbearssl/src/codec/dec32le.c new file mode 100644 index 0000000..ed36e71 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/dec32le.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_range_dec32le(uint32_t *v, size_t num, const void *src) +{ + const unsigned char *buf; + + buf = src; + while (num -- > 0) { + *v ++ = br_dec32le(buf); + buf += 4; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/dec64be.c b/BearSSL-OG/libbearssl/src/codec/dec64be.c new file mode 100644 index 0000000..0c40a76 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/dec64be.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_range_dec64be(uint64_t *v, size_t num, const void *src) +{ + const unsigned char *buf; + + buf = src; + while (num -- > 0) { + *v ++ = br_dec64be(buf); + buf += 8; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/dec64le.c b/BearSSL-OG/libbearssl/src/codec/dec64le.c new file mode 100644 index 0000000..cbd02c2 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/dec64le.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_range_dec64le(uint64_t *v, size_t num, const void *src) +{ + const unsigned char *buf; + + buf = src; + while (num -- > 0) { + *v ++ = br_dec64le(buf); + buf += 8; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/enc16be.c b/BearSSL-OG/libbearssl/src/codec/enc16be.c new file mode 100644 index 0000000..6e06652 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/enc16be.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_range_enc16be(void *dst, const uint16_t *v, size_t num) +{ + unsigned char *buf; + + buf = dst; + while (num -- > 0) { + br_enc16be(buf, *v ++); + buf += 2; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/enc16le.c b/BearSSL-OG/libbearssl/src/codec/enc16le.c new file mode 100644 index 0000000..3e5049a --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/enc16le.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_range_enc16le(void *dst, const uint16_t *v, size_t num) +{ + unsigned char *buf; + + buf = dst; + while (num -- > 0) { + br_enc16le(buf, *v ++); + buf += 2; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/enc32be.c b/BearSSL-OG/libbearssl/src/codec/enc32be.c new file mode 100644 index 0000000..97298b5 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/enc32be.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_range_enc32be(void *dst, const uint32_t *v, size_t num) +{ + unsigned char *buf; + + buf = dst; + while (num -- > 0) { + br_enc32be(buf, *v ++); + buf += 4; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/enc32le.c b/BearSSL-OG/libbearssl/src/codec/enc32le.c new file mode 100644 index 0000000..9e9c856 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/enc32le.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_range_enc32le(void *dst, const uint32_t *v, size_t num) +{ + unsigned char *buf; + + buf = dst; + while (num -- > 0) { + br_enc32le(buf, *v ++); + buf += 4; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/enc64be.c b/BearSSL-OG/libbearssl/src/codec/enc64be.c new file mode 100644 index 0000000..d548944 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/enc64be.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_range_enc64be(void *dst, const uint64_t *v, size_t num) +{ + unsigned char *buf; + + buf = dst; + while (num -- > 0) { + br_enc64be(buf, *v ++); + buf += 8; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/enc64le.c b/BearSSL-OG/libbearssl/src/codec/enc64le.c new file mode 100644 index 0000000..1f1d68e --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/enc64le.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_range_enc64le(void *dst, const uint64_t *v, size_t num) +{ + unsigned char *buf; + + buf = dst; + while (num -- > 0) { + br_enc64le(buf, *v ++); + buf += 8; + } +} diff --git a/BearSSL-OG/libbearssl/src/codec/pemdec.c b/BearSSL-OG/libbearssl/src/codec/pemdec.c new file mode 100644 index 0000000..8e54e6d --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/pemdec.c @@ -0,0 +1,526 @@ +/* Automatically generated code; do not modify directly. */ + +#include +#include + +typedef struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; +} t0_context; + +static uint32_t +t0_parse7E_unsigned(const unsigned char **p) +{ + uint32_t x; + + x = 0; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + return x; + } + } +} + +static int32_t +t0_parse7E_signed(const unsigned char **p) +{ + int neg; + uint32_t x; + + neg = ((**p) >> 6) & 1; + x = (uint32_t)-neg; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + if (neg) { + return -(int32_t)~x - 1; + } else { + return (int32_t)x; + } + } + } +} + +#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) +#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) +#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) +#define T0_INT1(x) T0_FBYTE(x, 0) +#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) + +/* static const unsigned char t0_datablock[]; */ + + +void br_pem_decoder_init_main(void *t0ctx); + +void br_pem_decoder_run(void *t0ctx); + + + +#include "inner.h" + +#define CTX ((br_pem_decoder_context *)(void *)((unsigned char *)t0ctx - offsetof(br_pem_decoder_context, cpu))) + +/* see bearssl_pem.h */ +void +br_pem_decoder_init(br_pem_decoder_context *ctx) +{ + memset(ctx, 0, sizeof *ctx); + ctx->cpu.dp = &ctx->dp_stack[0]; + ctx->cpu.rp = &ctx->rp_stack[0]; + br_pem_decoder_init_main(&ctx->cpu); + br_pem_decoder_run(&ctx->cpu); +} + +/* see bearssl_pem.h */ +size_t +br_pem_decoder_push(br_pem_decoder_context *ctx, + const void *data, size_t len) +{ + if (ctx->event) { + return 0; + } + ctx->hbuf = data; + ctx->hlen = len; + br_pem_decoder_run(&ctx->cpu); + return len - ctx->hlen; +} + +/* see bearssl_pem.h */ +int +br_pem_decoder_event(br_pem_decoder_context *ctx) +{ + int event; + + event = ctx->event; + ctx->event = 0; + return event; +} + + + +static const unsigned char t0_datablock[] = { + 0x00, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, + 0x00, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x00 +}; + +static const unsigned char t0_codeblock[] = { + 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x01, 0x01, 0x07, 0x00, 0x00, 0x01, + 0x01, 0x08, 0x00, 0x00, 0x13, 0x13, 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_pem_decoder_context, event)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_pem_decoder_context, name)), 0x00, 0x00, 0x05, + 0x14, 0x2C, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x03, 0x13, 0x04, 0x76, 0x01, + 0x2D, 0x0C, 0x06, 0x05, 0x2E, 0x01, 0x03, 0x2D, 0x00, 0x01, 0x0D, 0x27, + 0x05, 0x04, 0x01, 0x03, 0x2D, 0x00, 0x15, 0x2E, 0x01, 0x02, 0x2D, 0x00, + 0x01, 0x01, 0x7F, 0x03, 0x00, 0x25, 0x01, 0x00, 0x18, 0x0D, 0x06, 0x03, + 0x13, 0x04, 0x3C, 0x01, 0x7F, 0x18, 0x0D, 0x06, 0x13, 0x13, 0x02, 0x00, + 0x05, 0x06, 0x2E, 0x01, 0x03, 0x2D, 0x04, 0x03, 0x01, 0x7F, 0x23, 0x01, + 0x00, 0x00, 0x04, 0x23, 0x01, 0x01, 0x18, 0x0D, 0x06, 0x09, 0x13, 0x01, + 0x00, 0x23, 0x01, 0x00, 0x00, 0x04, 0x14, 0x01, 0x02, 0x18, 0x0D, 0x06, + 0x06, 0x13, 0x01, 0x7F, 0x00, 0x04, 0x08, 0x13, 0x01, 0x03, 0x2D, 0x01, + 0x00, 0x00, 0x13, 0x01, 0x00, 0x03, 0x00, 0x04, 0xFF, 0x33, 0x01, 0x2C, + 0x14, 0x01, 0x2D, 0x0D, 0x06, 0x04, 0x13, 0x01, 0x7F, 0x00, 0x14, 0x31, + 0x06, 0x02, 0x13, 0x29, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x04, 0x13, 0x01, + 0x02, 0x00, 0x16, 0x14, 0x1D, 0x06, 0x05, 0x13, 0x2E, 0x01, 0x03, 0x00, + 0x03, 0x00, 0x29, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x04, 0x13, 0x01, 0x03, + 0x00, 0x16, 0x14, 0x1D, 0x06, 0x05, 0x13, 0x2E, 0x01, 0x03, 0x00, 0x02, + 0x00, 0x01, 0x06, 0x0A, 0x07, 0x03, 0x00, 0x29, 0x14, 0x01, 0x0A, 0x0D, + 0x06, 0x04, 0x13, 0x01, 0x03, 0x00, 0x14, 0x01, 0x3D, 0x0D, 0x06, 0x2E, + 0x13, 0x29, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x04, 0x13, 0x01, 0x03, 0x00, + 0x2F, 0x05, 0x04, 0x13, 0x01, 0x03, 0x00, 0x01, 0x3D, 0x0C, 0x06, 0x03, + 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x0F, 0x10, 0x06, 0x03, 0x01, 0x03, + 0x00, 0x02, 0x00, 0x01, 0x04, 0x0F, 0x1C, 0x01, 0x01, 0x00, 0x16, 0x14, + 0x1D, 0x06, 0x05, 0x13, 0x2E, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x06, + 0x0A, 0x07, 0x03, 0x00, 0x29, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x04, 0x13, + 0x01, 0x03, 0x00, 0x14, 0x01, 0x3D, 0x0D, 0x06, 0x20, 0x13, 0x2F, 0x05, + 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x03, 0x10, 0x06, 0x03, 0x01, + 0x03, 0x00, 0x02, 0x00, 0x01, 0x0A, 0x0F, 0x1C, 0x02, 0x00, 0x01, 0x02, + 0x0F, 0x1C, 0x01, 0x01, 0x00, 0x16, 0x14, 0x1D, 0x06, 0x05, 0x13, 0x2E, + 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x06, 0x0A, 0x07, 0x03, 0x00, 0x02, + 0x00, 0x01, 0x10, 0x0F, 0x1C, 0x02, 0x00, 0x01, 0x08, 0x0F, 0x1C, 0x02, + 0x00, 0x1C, 0x01, 0x00, 0x00, 0x00, 0x28, 0x01, 0x01, 0x2D, 0x24, 0x06, + 0x02, 0x04, 0x7B, 0x04, 0x75, 0x00, 0x14, 0x12, 0x2A, 0x14, 0x05, 0x04, + 0x20, 0x01, 0x7F, 0x00, 0x2C, 0x2A, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x05, + 0x13, 0x20, 0x01, 0x00, 0x00, 0x0D, 0x05, 0x05, 0x13, 0x2E, 0x01, 0x00, + 0x00, 0x1E, 0x04, 0x5E, 0x00, 0x01, 0x01, 0x27, 0x06, 0x0B, 0x22, 0x01, + 0x80, 0x7F, 0x2B, 0x14, 0x06, 0x02, 0x30, 0x00, 0x13, 0x04, 0x6E, 0x00, + 0x2C, 0x14, 0x31, 0x05, 0x01, 0x00, 0x13, 0x04, 0x77, 0x00, 0x14, 0x14, + 0x01, 0x80, 0x61, 0x0E, 0x1B, 0x01, 0x80, 0x7A, 0x0B, 0x10, 0x06, 0x03, + 0x01, 0x20, 0x08, 0x00, 0x01, 0x14, 0x03, 0x00, 0x1B, 0x18, 0x05, 0x05, + 0x20, 0x2E, 0x01, 0x00, 0x00, 0x2C, 0x14, 0x01, 0x0A, 0x0D, 0x06, 0x06, + 0x20, 0x02, 0x00, 0x1B, 0x08, 0x00, 0x14, 0x01, 0x0D, 0x0D, 0x06, 0x03, + 0x13, 0x04, 0x03, 0x2A, 0x18, 0x1A, 0x1E, 0x1B, 0x1F, 0x1B, 0x04, 0x59, + 0x00, 0x19, 0x14, 0x1D, 0x05, 0x01, 0x00, 0x13, 0x11, 0x04, 0x76, 0x00, + 0x21, 0x1A, 0x11, 0x00, 0x00, 0x2C, 0x01, 0x0A, 0x0C, 0x06, 0x02, 0x04, + 0x78, 0x00, 0x01, 0x01, 0x7F, 0x03, 0x00, 0x2C, 0x14, 0x01, 0x0A, 0x0C, + 0x06, 0x09, 0x31, 0x05, 0x04, 0x01, 0x00, 0x03, 0x00, 0x04, 0x70, 0x13, + 0x02, 0x00, 0x00, 0x00, 0x14, 0x06, 0x14, 0x1F, 0x14, 0x22, 0x07, 0x17, + 0x01, 0x2D, 0x0C, 0x06, 0x08, 0x22, 0x07, 0x1E, 0x01, 0x00, 0x1B, 0x1A, + 0x00, 0x04, 0x69, 0x22, 0x1A, 0x00, 0x00, 0x14, 0x01, 0x0A, 0x0C, 0x1B, + 0x01, 0x20, 0x0B, 0x10, 0x00 +}; + +static const uint16_t t0_caddr[] = { + 0, + 5, + 10, + 15, + 19, + 24, + 29, + 67, + 149, + 384, + 396, + 431, + 450, + 460, + 479, + 523, + 534, + 539, + 549, + 574, + 601 +}; + +#define T0_INTERPRETED 29 + +#define T0_ENTER(ip, rp, slot) do { \ + const unsigned char *t0_newip; \ + uint32_t t0_lnum; \ + t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ + t0_lnum = t0_parse7E_unsigned(&t0_newip); \ + (rp) += t0_lnum; \ + *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ + (ip) = t0_newip; \ + } while (0) + +#define T0_DEFENTRY(name, slot) \ +void \ +name(void *ctx) \ +{ \ + t0_context *t0ctx = ctx; \ + t0ctx->ip = &t0_codeblock[0]; \ + T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ +} + +T0_DEFENTRY(br_pem_decoder_init_main, 38) + +#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) + +void +br_pem_decoder_run(void *t0ctx) +{ + uint32_t *dp, *rp; + const unsigned char *ip; + +#define T0_LOCAL(x) (*(rp - 2 - (x))) +#define T0_POP() (*-- dp) +#define T0_POPi() (*(int32_t *)(-- dp)) +#define T0_PEEK(x) (*(dp - 1 - (x))) +#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) +#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) +#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) +#define T0_RPOP() (*-- rp) +#define T0_RPOPi() (*(int32_t *)(-- rp)) +#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) +#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) +#define T0_ROLL(x) do { \ + size_t t0len = (size_t)(x); \ + uint32_t t0tmp = *(dp - 1 - t0len); \ + memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_SWAP() do { \ + uint32_t t0tmp = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_ROT() do { \ + uint32_t t0tmp = *(dp - 3); \ + *(dp - 3) = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_NROT() do { \ + uint32_t t0tmp = *(dp - 1); \ + *(dp - 1) = *(dp - 2); \ + *(dp - 2) = *(dp - 3); \ + *(dp - 3) = t0tmp; \ +} while (0) +#define T0_PICK(x) do { \ + uint32_t t0depth = (x); \ + T0_PUSH(T0_PEEK(t0depth)); \ +} while (0) +#define T0_CO() do { \ + goto t0_exit; \ +} while (0) +#define T0_RET() goto t0_next + + dp = ((t0_context *)t0ctx)->dp; + rp = ((t0_context *)t0ctx)->rp; + ip = ((t0_context *)t0ctx)->ip; + goto t0_next; + for (;;) { + uint32_t t0x; + + t0_next: + t0x = T0_NEXT(&ip); + if (t0x < T0_INTERPRETED) { + switch (t0x) { + int32_t t0off; + + case 0: /* ret */ + t0x = T0_RPOP(); + rp -= (t0x >> 16); + t0x &= 0xFFFF; + if (t0x == 0) { + ip = NULL; + goto t0_exit; + } + ip = &t0_codeblock[t0x]; + break; + case 1: /* literal constant */ + T0_PUSHi(t0_parse7E_signed(&ip)); + break; + case 2: /* read local */ + T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); + break; + case 3: /* write local */ + T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); + break; + case 4: /* jump */ + t0off = t0_parse7E_signed(&ip); + ip += t0off; + break; + case 5: /* jump if */ + t0off = t0_parse7E_signed(&ip); + if (T0_POP()) { + ip += t0off; + } + break; + case 6: /* jump if not */ + t0off = t0_parse7E_signed(&ip); + if (!T0_POP()) { + ip += t0off; + } + break; + case 7: { + /* + */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a + b); + + } + break; + case 8: { + /* - */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a - b); + + } + break; + case 9: { + /* < */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a < b)); + + } + break; + case 10: { + /* << */ + + int c = (int)T0_POPi(); + uint32_t x = T0_POP(); + T0_PUSH(x << c); + + } + break; + case 11: { + /* <= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a <= b)); + + } + break; + case 12: { + /* <> */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a != b)); + + } + break; + case 13: { + /* = */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a == b)); + + } + break; + case 14: { + /* >= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a >= b)); + + } + break; + case 15: { + /* >> */ + + int c = (int)T0_POPi(); + int32_t x = T0_POPi(); + T0_PUSHi(x >> c); + + } + break; + case 16: { + /* and */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a & b); + + } + break; + case 17: { + /* co */ + T0_CO(); + } + break; + case 18: { + /* data-get8 */ + + size_t addr = T0_POP(); + T0_PUSH(t0_datablock[addr]); + + } + break; + case 19: { + /* drop */ + (void)T0_POP(); + } + break; + case 20: { + /* dup */ + T0_PUSH(T0_PEEK(0)); + } + break; + case 21: { + /* flush-buf */ + + if (CTX->ptr > 0) { + if (CTX->dest) { + CTX->dest(CTX->dest_ctx, CTX->buf, CTX->ptr); + } + CTX->ptr = 0; + } + + } + break; + case 22: { + /* from-base64 */ + + uint32_t c = T0_POP(); + uint32_t p, q, r, z; + p = c - 0x41; + q = c - 0x61; + r = c - 0x30; + + z = ((p + 2) & -LT(p, 26)) + | ((q + 28) & -LT(q, 26)) + | ((r + 54) & -LT(r, 10)) + | (64 & -EQ(c, 0x2B)) + | (65 & -EQ(c, 0x2F)) + | EQ(c, 0x3D); + T0_PUSHi((int32_t)z - 2); + + } + break; + case 23: { + /* get8 */ + + size_t addr = T0_POP(); + T0_PUSH(*((unsigned char *)CTX + addr)); + + } + break; + case 24: { + /* over */ + T0_PUSH(T0_PEEK(1)); + } + break; + case 25: { + /* read8-native */ + + if (CTX->hlen > 0) { + T0_PUSH(*CTX->hbuf ++); + CTX->hlen --; + } else { + T0_PUSHi(-1); + } + + } + break; + case 26: { + /* set8 */ + + size_t addr = T0_POP(); + unsigned x = T0_POP(); + *((unsigned char *)CTX + addr) = x; + + } + break; + case 27: { + /* swap */ + T0_SWAP(); + } + break; + case 28: { + /* write8 */ + + unsigned char x = (unsigned char)T0_POP(); + CTX->buf[CTX->ptr ++] = x; + if (CTX->ptr == sizeof CTX->buf) { + if (CTX->dest) { + CTX->dest(CTX->dest_ctx, CTX->buf, sizeof CTX->buf); + } + CTX->ptr = 0; + } + + } + break; + } + + } else { + T0_ENTER(ip, rp, t0x); + } + } +t0_exit: + ((t0_context *)t0ctx)->dp = dp; + ((t0_context *)t0ctx)->rp = rp; + ((t0_context *)t0ctx)->ip = ip; +} diff --git a/BearSSL-OG/libbearssl/src/codec/pemdec.t0 b/BearSSL-OG/libbearssl/src/codec/pemdec.t0 new file mode 100644 index 0000000..2237abb --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/pemdec.t0 @@ -0,0 +1,314 @@ +\ Copyright (c) 2016 Thomas Pornin +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +\ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +\ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +\ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +\ SOFTWARE. + +preamble { + +#include "inner.h" + +#define CTX ((br_pem_decoder_context *)(void *)((unsigned char *)t0ctx - offsetof(br_pem_decoder_context, cpu))) + +/* see bearssl_pem.h */ +void +br_pem_decoder_init(br_pem_decoder_context *ctx) +{ + memset(ctx, 0, sizeof *ctx); + ctx->cpu.dp = &ctx->dp_stack[0]; + ctx->cpu.rp = &ctx->rp_stack[0]; + br_pem_decoder_init_main(&ctx->cpu); + br_pem_decoder_run(&ctx->cpu); +} + +/* see bearssl_pem.h */ +size_t +br_pem_decoder_push(br_pem_decoder_context *ctx, + const void *data, size_t len) +{ + if (ctx->event) { + return 0; + } + ctx->hbuf = data; + ctx->hlen = len; + br_pem_decoder_run(&ctx->cpu); + return len - ctx->hlen; +} + +/* see bearssl_pem.h */ +int +br_pem_decoder_event(br_pem_decoder_context *ctx) +{ + int event; + + event = ctx->event; + ctx->event = 0; + return event; +} + +} + +\ Define a word that evaluates to the address of a field within the +\ decoder context. +: addr: + next-word { field } + "addr-" field + 0 1 define-word + 0 8191 "offsetof(br_pem_decoder_context, " field + ")" + make-CX + postpone literal postpone ; ; + +addr: event +addr: name +addr: buf +addr: ptr + +\ Set a byte at a specific address (offset within the context). +cc: set8 ( value addr -- ) { + size_t addr = T0_POP(); + unsigned x = T0_POP(); + *((unsigned char *)CTX + addr) = x; +} + +\ Get a byte at a specific address (offset within the context). +cc: get8 ( addr -- value ) { + size_t addr = T0_POP(); + T0_PUSH(*((unsigned char *)CTX + addr)); +} + +\ Send an event. +: send-event ( event -- ) + addr-event set8 co ; + +\ Low-level function to read a single byte. Returned value is the byte +\ (0 to 255), or -1 if there is no available data. +cc: read8-native ( -- x ) { + if (CTX->hlen > 0) { + T0_PUSH(*CTX->hbuf ++); + CTX->hlen --; + } else { + T0_PUSHi(-1); + } +} + +\ Read next byte. Block until the next byte is available. +: read8 ( -- x ) + begin read8-native dup 0< ifnot ret then drop co again ; + +\ Read bytes until next end-of-line. +: skip-newline ( -- ) + begin read8 `\n <> while repeat ; + +\ Read bytes until next end-of-line; verify that they are all whitespace. +\ This returns -1 if they were all whitespace, 0 otherwise. +: skip-newline-ws ( -- bool ) + -1 { r } + begin read8 dup `\n <> while ws? ifnot 0 >r then repeat + drop r ; + +\ Normalise a byte to uppercase (ASCII only). +: norm-upper ( x -- x ) + dup dup `a >= swap `z <= and if 32 - then ; + +\ Read bytes and compare with the provided string. On mismatch, the +\ rest of the line is consumed. Matching is not case sensitive. +: match-string ( str -- bool ) + begin + dup data-get8 norm-upper dup ifnot 2drop -1 ret then + read8 norm-upper dup `\n = if drop 2drop 0 ret then + = ifnot drop skip-newline 0 ret then + 1+ + again ; + +\ Read bytes into the provided buffer, but no more than the provided +\ count. Reading stops when end-of-line is reached. Returned value +\ is the count of bytes written to the buffer, or 0 if the buffer size +\ was exceeded. All bytes are normalised to uppercase (ASCII only). +: read-bytes ( addr len -- len ) + dup { orig-len } + swap + begin + over ifnot 2drop skip-newline 0 ret then + read8 dup `\n = if 2drop orig-len swap - ret then + dup `\r = if drop else norm-upper over set8 then + 1+ swap 1- swap + again ; + +\ Remove trailing dashes from the name buffer. +: trim-dashes ( len -- ) + begin dup while + 1- + dup addr-name + get8 `- <> if + addr-name + 1+ 0 swap set8 ret + then + repeat + addr-name set8 ; + +\ Scan input for next "begin" banner. +: next-banner-begin ( -- ) + begin + "-----BEGIN " match-string if + addr-name 127 read-bytes + dup if trim-dashes ret then + drop + then + again ; + +\ Convert a Base64 character to its numerical value. Returned value is +\ 0 to 63 for Base64 characters, -1 for '=', and -2 for all other characters. +cc: from-base64 ( char -- x ) { + uint32_t c = T0_POP(); + uint32_t p, q, r, z; + p = c - 0x41; + q = c - 0x61; + r = c - 0x30; + + z = ((p + 2) & -LT(p, 26)) + | ((q + 28) & -LT(q, 26)) + | ((r + 54) & -LT(r, 10)) + | (64 & -EQ(c, 0x2B)) + | (65 & -EQ(c, 0x2F)) + | EQ(c, 0x3D); + T0_PUSHi((int32_t)z - 2); +} + +\ Test whether a character is whitespace (but not a newline). +: ws? ( x -- bool ) + dup `\n <> swap 32 <= and ; + +\ Read next character, skipping whitespace (except newline). +: next-nonws ( -- x ) + begin + read8 dup ws? ifnot ret then + drop + again ; + +\ Write one byte in the output buffer. +cc: write8 ( x -- ) { + unsigned char x = (unsigned char)T0_POP(); + CTX->buf[CTX->ptr ++] = x; + if (CTX->ptr == sizeof CTX->buf) { + if (CTX->dest) { + CTX->dest(CTX->dest_ctx, CTX->buf, sizeof CTX->buf); + } + CTX->ptr = 0; + } +} + +\ Flush the output buffer. +cc: flush-buf ( -- ) { + if (CTX->ptr > 0) { + if (CTX->dest) { + CTX->dest(CTX->dest_ctx, CTX->buf, CTX->ptr); + } + CTX->ptr = 0; + } +} + +\ Decode the four next Base64 characters. Returned value is: +\ 0 quartet processed, three bytes produced. +\ -1 dash encountered as first character (no leading whitespace). +\ 1 quartet processed, one or two bytes produced, terminator reached. +\ 2 end-of-line reached. +\ 3 error. +\ For all positive return values, the remaining of the current line has been +\ consumed. +: decode-next-quartet ( -- r ) + \ Process first character. It may be a dash. + read8 dup `- = if drop -1 ret then + dup ws? if drop next-nonws then + dup `\n = if drop 2 ret then + from-base64 dup 0< if drop skip-newline 3 ret then + { acc } + + \ Second character. + next-nonws dup `\n = if drop 3 ret then + from-base64 dup 0< if drop skip-newline 3 ret then + acc 6 << + >acc + + \ Third character: may be an equal sign. + next-nonws dup `\n = if drop 3 ret then + dup `= = if + \ Fourth character must be an equal sign. + drop + next-nonws dup `\n = if drop 3 ret then + skip-newline-ws ifnot drop 3 ret then + `= <> if 3 ret then + acc 0x0F and if 3 ret then + acc 4 >> write8 + 1 ret + then + from-base64 dup 0< if drop skip-newline 3 ret then + acc 6 << + >acc + + \ Fourth character: may be an equal sign. + next-nonws dup `\n = if drop 3 ret then + dup `= = if + drop skip-newline-ws ifnot 3 ret then + acc 0x03 and if 3 ret then + acc 10 >> write8 + acc 2 >> write8 + 1 ret + then + from-base64 dup 0< if drop skip-newline 3 ret then + acc 6 << + >acc + acc 16 >> write8 + acc 8 >> write8 + acc write8 + 0 ; + +\ Check trailer line (possibly, the leading dash has been read). This +\ sends the appropriate event. +: check-trailer ( bool -- ) + ifnot + begin read8 dup `\n = while drop repeat + `- <> if skip-newline 3 send-event ret then + then + "----END " match-string ifnot 3 send-event ret then + flush-buf + skip-newline 2 send-event ; + +\ Decode one line worth of characters. Returned value is 0 if the end of the +\ object is reached, -1 otherwise. The end of object or error event is sent. +: decode-line ( -- bool ) + -1 { first } + begin + decode-next-quartet + case + 0 of endof + -1 of + first ifnot + skip-newline 3 send-event + else + -1 check-trailer + then + 0 ret + endof + 1 of 0 check-trailer 0 ret endof + 2 of -1 ret endof + + \ On decoding error + drop 3 send-event 0 ret + endcase + 0 >first + again ; + +: main ( -- ! ) + begin + next-banner-begin 1 send-event + begin decode-line while repeat + again ; diff --git a/BearSSL-OG/libbearssl/src/codec/pemenc.c b/BearSSL-OG/libbearssl/src/codec/pemenc.c new file mode 100644 index 0000000..236601e --- /dev/null +++ b/BearSSL-OG/libbearssl/src/codec/pemenc.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Get the appropriate Base64 character for a numeric value in the + * 0..63 range. This is constant-time. + */ +static char +b64char(uint32_t x) +{ + /* + * Values 0 to 25 map to 0x41..0x5A ('A' to 'Z') + * Values 26 to 51 map to 0x61..0x7A ('a' to 'z') + * Values 52 to 61 map to 0x30..0x39 ('0' to '9') + * Value 62 maps to 0x2B ('+') + * Value 63 maps to 0x2F ('/') + */ + uint32_t a, b, c; + + a = x - 26; + b = x - 52; + c = x - 62; + + /* + * Looking at bits 8..15 of values a, b and c: + * + * x a b c + * --------------------- + * 0..25 FF FF FF + * 26..51 00 FF FF + * 52..61 00 00 FF + * 62..63 00 00 00 + */ + return (char)(((x + 0x41) & ((a & b & c) >> 8)) + | ((x + (0x61 - 26)) & ((~a & b & c) >> 8)) + | ((x - (52 - 0x30)) & ((~a & ~b & c) >> 8)) + | ((0x2B + ((x & 1) << 2)) & (~(a | b | c) >> 8))); +} + +/* see bearssl_pem.h */ +size_t +br_pem_encode(void *dest, const void *data, size_t len, + const char *banner, unsigned flags) +{ + size_t dlen, banner_len, lines; + char *d; + unsigned char *buf; + size_t u; + int off, lim; + + banner_len = strlen(banner); + /* FIXME: try to avoid divisions here, as they may pull + an extra libc function. */ + if ((flags & BR_PEM_LINE64) != 0) { + lines = (len + 47) / 48; + } else { + lines = (len + 56) / 57; + } + dlen = (banner_len << 1) + 30 + (((len + 2) / 3) << 2) + + lines + 2; + if ((flags & BR_PEM_CRLF) != 0) { + dlen += lines + 2; + } + + if (dest == NULL) { + return dlen; + } + + d = dest; + + /* + * We always move the source data to the end of output buffer; + * the encoding process never "catches up" except at the very + * end. This also handles all conditions of partial or total + * overlap. + */ + buf = (unsigned char *)d + dlen - len; + memmove(buf, data, len); + + memcpy(d, "-----BEGIN ", 11); + d += 11; + memcpy(d, banner, banner_len); + d += banner_len; + memcpy(d, "-----", 5); + d += 5; + if ((flags & BR_PEM_CRLF) != 0) { + *d ++ = 0x0D; + } + *d ++ = 0x0A; + + off = 0; + lim = (flags & BR_PEM_LINE64) != 0 ? 16 : 19; + for (u = 0; (u + 2) < len; u += 3) { + uint32_t w; + + w = ((uint32_t)buf[u] << 16) + | ((uint32_t)buf[u + 1] << 8) + | (uint32_t)buf[u + 2]; + *d ++ = b64char(w >> 18); + *d ++ = b64char((w >> 12) & 0x3F); + *d ++ = b64char((w >> 6) & 0x3F); + *d ++ = b64char(w & 0x3F); + if (++ off == lim) { + off = 0; + if ((flags & BR_PEM_CRLF) != 0) { + *d ++ = 0x0D; + } + *d ++ = 0x0A; + } + } + if (u < len) { + uint32_t w; + + w = (uint32_t)buf[u] << 16; + if (u + 1 < len) { + w |= (uint32_t)buf[u + 1] << 8; + } + *d ++ = b64char(w >> 18); + *d ++ = b64char((w >> 12) & 0x3F); + if (u + 1 < len) { + *d ++ = b64char((w >> 6) & 0x3F); + } else { + *d ++ = 0x3D; + } + *d ++ = 0x3D; + off ++; + } + if (off != 0) { + if ((flags & BR_PEM_CRLF) != 0) { + *d ++ = 0x0D; + } + *d ++ = 0x0A; + } + + memcpy(d, "-----END ", 9); + d += 9; + memcpy(d, banner, banner_len); + d += banner_len; + memcpy(d, "-----", 5); + d += 5; + if ((flags & BR_PEM_CRLF) != 0) { + *d ++ = 0x0D; + } + *d ++ = 0x0A; + + /* Final zero, not counted in returned length. */ + *d ++ = 0x00; + + return dlen; +} diff --git a/BearSSL-OG/libbearssl/src/config.h b/BearSSL-OG/libbearssl/src/config.h new file mode 100644 index 0000000..dcc3a2b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/config.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef CONFIG_H__ +#define CONFIG_H__ + +/* + * This file contains compile-time flags that can override the + * autodetection performed in relevant files. Each flag is a macro; it + * deactivates the feature if defined to 0, activates it if defined to a + * non-zero integer (normally 1). If the macro is not defined, then + * autodetection applies. + */ + +/* + * When BR_64 is enabled, 64-bit integer types are assumed to be + * efficient (i.e. the architecture has 64-bit registers and can + * do 64-bit operations as fast as 32-bit operations). + * +#define BR_64 1 + */ + +/* + * When BR_LOMUL is enabled, then multiplications of 32-bit values whose + * result are truncated to the low 32 bits are assumed to be + * substantially more efficient than 32-bit multiplications that yield + * 64-bit results. This is typically the case on low-end ARM Cortex M + * systems (M0, M0+, M1, and arguably M3 and M4 as well). + * +#define BR_LOMUL 1 + */ + +/* + * When BR_SLOW_MUL is enabled, multiplications are assumed to be + * substantially slow with regards to other integer operations, thus + * making it worth to make more operations for a given task if it allows + * using less multiplications. + * +#define BR_SLOW_MUL 1 + */ + +/* + * When BR_SLOW_MUL15 is enabled, short multplications (on 15-bit words) + * are assumed to be substantially slow with regards to other integer + * operations, thus making it worth to make more integer operations if + * it allows using less multiplications. + * +#define BR_SLOW_MUL15 1 + */ + +/* + * When BR_CT_MUL31 is enabled, multiplications of 31-bit values (used + * in the "i31" big integer implementation) use an alternate implementation + * which is slower and larger than the normal multiplication, but should + * ensure constant-time multiplications even on architectures where the + * multiplication opcode takes a variable number of cycles to complete. + * +#define BR_CT_MUL31 1 + */ + +/* + * When BR_CT_MUL15 is enabled, multiplications of 15-bit values (held + * in 32-bit words) use an alternate implementation which is slower and + * larger than the normal multiplication, but should ensure + * constant-time multiplications on most/all architectures where the + * basic multiplication is not constant-time. +#define BR_CT_MUL15 1 + */ + +/* + * When BR_NO_ARITH_SHIFT is enabled, arithmetic right shifts (with sign + * extension) are performed with a sequence of operations which is bigger + * and slower than a simple right shift on a signed value. This avoids + * relying on an implementation-defined behaviour. However, most if not + * all C compilers use sign extension for right shifts on signed values, + * so this alternate macro is disabled by default. +#define BR_NO_ARITH_SHIFT 1 + */ + +/* + * When BR_RDRAND is enabled, the SSL engine will use the RDRAND opcode + * to automatically obtain quality randomness for seeding its internal + * PRNG. Since that opcode is present only in recent x86 CPU, its + * support is dynamically tested; if the current CPU does not support + * it, then another random source will be used, such as /dev/urandom or + * CryptGenRandom(). + * +#define BR_RDRAND 1 + */ + +/* + * When BR_USE_GETENTROPY is enabled, the SSL engine will use the + * getentropy() function to obtain quality randomness for seeding its + * internal PRNG. On Linux and FreeBSD, getentropy() is implemented by + * the standard library with the system call getrandom(); on OpenBSD, + * getentropy() is the system call, and there is no getrandom() wrapper, + * hence the use of the getentropy() function for maximum portability. + * + * If the getentropy() call fails, and BR_USE_URANDOM is not explicitly + * disabled, then /dev/urandom will be used as a fallback mechanism. On + * FreeBSD and OpenBSD, this does not change much, since /dev/urandom + * will block if not enough entropy has been obtained since last boot. + * On Linux, /dev/urandom might not block, which can be troublesome in + * early boot stages, which is why getentropy() is preferred. + * +#define BR_USE_GETENTROPY 1 + */ + +/* + * When BR_USE_URANDOM is enabled, the SSL engine will use /dev/urandom + * to automatically obtain quality randomness for seeding its internal + * PRNG. + * +#define BR_USE_URANDOM 1 + */ + +/* + * When BR_USE_WIN32_RAND is enabled, the SSL engine will use the Win32 + * (CryptoAPI) functions (CryptAcquireContext(), CryptGenRandom()...) to + * automatically obtain quality randomness for seeding its internal PRNG. + * + * Note: if both BR_USE_URANDOM and BR_USE_WIN32_RAND are defined, the + * former takes precedence. + * +#define BR_USE_WIN32_RAND 1 + */ + +/* + * When BR_USE_XBOX_RAND is enabled, the SSL engine will use custom code for xbox + * + * Note: if both BR_USE_URANDOM and BR_USE_XBOX_RAND are defined, the + * former takes precedence. + * +#define BR_USE_XBOX_RAND 1 + */ + +/* + * When BR_USE_UNIX_TIME is enabled, the X.509 validation engine obtains + * the current time from the OS by calling time(), and assuming that the + * returned value (a 'time_t') is an integer that counts time in seconds + * since the Unix Epoch (Jan 1st, 1970, 00:00 UTC). + * +#define BR_USE_UNIX_TIME 1 + */ + +/* + * When BR_USE_WIN32_TIME is enabled, the X.509 validation engine obtains + * the current time from the OS by calling the Win32 function + * GetSystemTimeAsFileTime(). + * + * Note: if both BR_USE_UNIX_TIME and BR_USE_WIN32_TIME are defined, the + * former takes precedence. + * +#define BR_USE_WIN32_TIME 1 + */ + +/* + * When BR_ARMEL_CORTEXM_GCC is enabled, some operations are replaced with + * inline assembly which is shorter and/or faster. This should be used + * only when all of the following are true: + * - target architecture is ARM in Thumb mode + * - target endianness is little-endian + * - compiler is GCC (or GCC-compatible for inline assembly syntax) + * + * This is meant for the low-end cores (Cortex M0, M0+, M1, M3). + * Note: if BR_LOMUL is not explicitly enabled or disabled, then + * enabling BR_ARMEL_CORTEXM_GCC also enables BR_LOMUL. + * +#define BR_ARMEL_CORTEXM_GCC 1 + */ + +/* + * When BR_AES_X86NI is enabled, the AES implementation using the x86 "NI" + * instructions (dedicated AES opcodes) will be compiled. If this is not + * enabled explicitly, then that AES implementation will be compiled only + * if a compatible compiler is detected. If set explicitly to 0, the + * implementation will not be compiled at all. + * +#define BR_AES_X86NI 1 + */ + +/* + * When BR_SSE2 is enabled, SSE2 intrinsics will be used for some + * algorithm implementations that use them (e.g. chacha20_sse2). If this + * is not enabled explicitly, then support for SSE2 intrinsics will be + * automatically detected. If set explicitly to 0, then SSE2 code will + * not be compiled at all. + * +#define BR_SSE2 0 + */ + +/* + * When BR_POWER8 is enabled, the AES implementation using the POWER ISA + * 2.07 opcodes (available on POWER8 processors and later) is compiled. + * If this is not enabled explicitly, then that implementation will be + * compiled only if a compatible compiler is detected, _and_ the target + * architecture is POWER8 or later. + * +#define BR_POWER8 1 + */ + +/* + * When BR_INT128 is enabled, then code using the 'unsigned __int64' + * and 'unsigned __int128' types will be used to leverage 64x64->128 + * unsigned multiplications. This should work with GCC and compatible + * compilers on 64-bit architectures. + * +#define BR_INT128 0 + */ + +/* + * When BR_UMUL128 is enabled, then code using the '_umul128()' and + * '_addcarry_u64()' intrinsics will be used to implement 64x64->128 + * unsigned multiplications. This should work on Visual C on x64 systems. + * +#define BR_UMUL128 0 + */ + +/* + * When BR_LE_UNALIGNED is enabled, then the current architecture is + * assumed to use little-endian encoding for integers, and to tolerate + * unaligned accesses with no or minimal time penalty. + * +#define BR_LE_UNALIGNED 1 + */ + +/* + * When BR_BE_UNALIGNED is enabled, then the current architecture is + * assumed to use big-endian encoding for integers, and to tolerate + * unaligned accesses with no or minimal time penalty. + * +#define BR_BE_UNALIGNED 1 + */ + +#endif diff --git a/BearSSL-OG/libbearssl/src/ec/ec_all_m15.c b/BearSSL-OG/libbearssl/src/ec/ec_all_m15.c new file mode 100644 index 0000000..bb550e1 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_all_m15.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + switch (curve) { + case BR_EC_secp256r1: + return br_ec_p256_m15.generator(curve, len); + case BR_EC_curve25519: + return br_ec_c25519_m15.generator(curve, len); + default: + return br_ec_prime_i15.generator(curve, len); + } +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + switch (curve) { + case BR_EC_secp256r1: + return br_ec_p256_m15.order(curve, len); + case BR_EC_curve25519: + return br_ec_c25519_m15.order(curve, len); + default: + return br_ec_prime_i15.order(curve, len); + } +} + +static size_t +api_xoff(int curve, size_t *len) +{ + switch (curve) { + case BR_EC_secp256r1: + return br_ec_p256_m15.xoff(curve, len); + case BR_EC_curve25519: + return br_ec_c25519_m15.xoff(curve, len); + default: + return br_ec_prime_i15.xoff(curve, len); + } +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *kb, size_t kblen, int curve) +{ + switch (curve) { + case BR_EC_secp256r1: + return br_ec_p256_m15.mul(G, Glen, kb, kblen, curve); + case BR_EC_curve25519: + return br_ec_c25519_m15.mul(G, Glen, kb, kblen, curve); + default: + return br_ec_prime_i15.mul(G, Glen, kb, kblen, curve); + } +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + switch (curve) { + case BR_EC_secp256r1: + return br_ec_p256_m15.mulgen(R, x, xlen, curve); + case BR_EC_curve25519: + return br_ec_c25519_m15.mulgen(R, x, xlen, curve); + default: + return br_ec_prime_i15.mulgen(R, x, xlen, curve); + } +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + switch (curve) { + case BR_EC_secp256r1: + return br_ec_p256_m15.muladd(A, B, len, + x, xlen, y, ylen, curve); + case BR_EC_curve25519: + return br_ec_c25519_m15.muladd(A, B, len, + x, xlen, y, ylen, curve); + default: + return br_ec_prime_i15.muladd(A, B, len, + x, xlen, y, ylen, curve); + } +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_all_m15 = { + (uint32_t)0x23800000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_all_m31.c b/BearSSL-OG/libbearssl/src/ec/ec_all_m31.c new file mode 100644 index 0000000..8fd8c3c --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_all_m31.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + switch (curve) { + case BR_EC_secp256r1: +#if BR_INT128 || BR_UMUL128 + return br_ec_p256_m64.generator(curve, len); +#else + return br_ec_p256_m31.generator(curve, len); +#endif + case BR_EC_curve25519: +#if BR_INT128 || BR_UMUL128 + return br_ec_c25519_m64.generator(curve, len); +#else + return br_ec_c25519_m31.generator(curve, len); +#endif + default: + return br_ec_prime_i31.generator(curve, len); + } +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + switch (curve) { + case BR_EC_secp256r1: +#if BR_INT128 || BR_UMUL128 + return br_ec_p256_m64.order(curve, len); +#else + return br_ec_p256_m31.order(curve, len); +#endif + case BR_EC_curve25519: +#if BR_INT128 || BR_UMUL128 + return br_ec_c25519_m64.order(curve, len); +#else + return br_ec_c25519_m31.order(curve, len); +#endif + default: + return br_ec_prime_i31.order(curve, len); + } +} + +static size_t +api_xoff(int curve, size_t *len) +{ + switch (curve) { + case BR_EC_secp256r1: +#if BR_INT128 || BR_UMUL128 + return br_ec_p256_m64.xoff(curve, len); +#else + return br_ec_p256_m31.xoff(curve, len); +#endif + case BR_EC_curve25519: +#if BR_INT128 || BR_UMUL128 + return br_ec_c25519_m64.xoff(curve, len); +#else + return br_ec_c25519_m31.xoff(curve, len); +#endif + default: + return br_ec_prime_i31.xoff(curve, len); + } +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *kb, size_t kblen, int curve) +{ + switch (curve) { + case BR_EC_secp256r1: +#if BR_INT128 || BR_UMUL128 + return br_ec_p256_m64.mul(G, Glen, kb, kblen, curve); +#else + return br_ec_p256_m31.mul(G, Glen, kb, kblen, curve); +#endif + case BR_EC_curve25519: +#if BR_INT128 || BR_UMUL128 + return br_ec_c25519_m64.mul(G, Glen, kb, kblen, curve); +#else + return br_ec_c25519_m31.mul(G, Glen, kb, kblen, curve); +#endif + default: + return br_ec_prime_i31.mul(G, Glen, kb, kblen, curve); + } +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + switch (curve) { + case BR_EC_secp256r1: +#if BR_INT128 || BR_UMUL128 + return br_ec_p256_m64.mulgen(R, x, xlen, curve); +#else + return br_ec_p256_m31.mulgen(R, x, xlen, curve); +#endif + case BR_EC_curve25519: +#if BR_INT128 || BR_UMUL128 + return br_ec_c25519_m64.mulgen(R, x, xlen, curve); +#else + return br_ec_c25519_m31.mulgen(R, x, xlen, curve); +#endif + default: + return br_ec_prime_i31.mulgen(R, x, xlen, curve); + } +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + switch (curve) { + case BR_EC_secp256r1: +#if BR_INT128 || BR_UMUL128 + return br_ec_p256_m64.muladd(A, B, len, + x, xlen, y, ylen, curve); +#else + return br_ec_p256_m31.muladd(A, B, len, + x, xlen, y, ylen, curve); +#endif + case BR_EC_curve25519: +#if BR_INT128 || BR_UMUL128 + return br_ec_c25519_m64.muladd(A, B, len, + x, xlen, y, ylen, curve); +#else + return br_ec_c25519_m31.muladd(A, B, len, + x, xlen, y, ylen, curve); +#endif + default: + return br_ec_prime_i31.muladd(A, B, len, + x, xlen, y, ylen, curve); + } +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_all_m31 = { + (uint32_t)0x23800000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_c25519_i15.c b/BearSSL-OG/libbearssl/src/ec/ec_c25519_i15.c new file mode 100644 index 0000000..8fadcf4 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_c25519_i15.c @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Parameters for the field: + * - field modulus p = 2^255-19 + * - R^2 mod p (R = 2^(15k) for the smallest k such that R >= p) + */ + +static const uint16_t C255_P[] = { + 0x0110, + 0x7FED, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + 0x7FFF +}; + +#define P0I 0x4A1B + +static const uint16_t C255_R2[] = { + 0x0110, + 0x0169, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000 +}; + +/* obsolete +#include +#include +static void +print_int_mont(const char *name, const uint16_t *x) +{ + uint16_t y[18]; + unsigned char tmp[32]; + size_t u; + + printf("%s = ", name); + memcpy(y, x, sizeof y); + br_i15_from_monty(y, C255_P, P0I); + br_i15_encode(tmp, sizeof tmp, y); + for (u = 0; u < sizeof tmp; u ++) { + printf("%02X", tmp[u]); + } + printf("\n"); +} +*/ + +static const uint16_t C255_A24[] = { + 0x0110, + 0x45D3, 0x0046, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000 +}; + +static const unsigned char GEN[] = { + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const unsigned char ORDER[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return GEN; +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return ORDER; +} + +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 0; +} + +static void +cswap(uint16_t *a, uint16_t *b, uint32_t ctl) +{ + int i; + + ctl = -ctl; + for (i = 0; i < 18; i ++) { + uint32_t aw, bw, tw; + + aw = a[i]; + bw = b[i]; + tw = ctl & (aw ^ bw); + a[i] = aw ^ tw; + b[i] = bw ^ tw; + } +} + +static void +c255_add(uint16_t *d, const uint16_t *a, const uint16_t *b) +{ + uint32_t ctl; + uint16_t t[18]; + + memcpy(t, a, sizeof t); + ctl = br_i15_add(t, b, 1); + ctl |= NOT(br_i15_sub(t, C255_P, 0)); + br_i15_sub(t, C255_P, ctl); + memcpy(d, t, sizeof t); +} + +static void +c255_sub(uint16_t *d, const uint16_t *a, const uint16_t *b) +{ + uint16_t t[18]; + + memcpy(t, a, sizeof t); + br_i15_add(t, C255_P, br_i15_sub(t, b, 1)); + memcpy(d, t, sizeof t); +} + +static void +c255_mul(uint16_t *d, const uint16_t *a, const uint16_t *b) +{ + uint16_t t[18]; + + br_i15_montymul(t, a, b, C255_P, P0I); + memcpy(d, t, sizeof t); +} + +static void +byteswap(unsigned char *G) +{ + int i; + + for (i = 0; i < 16; i ++) { + unsigned char t; + + t = G[i]; + G[i] = G[31 - i]; + G[31 - i] = t; + } +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *kb, size_t kblen, int curve) +{ +#define ILEN (18 * sizeof(uint16_t)) + + /* + * The a[] and b[] arrays have an extra word to allow for + * decoding without using br_i15_decode_reduce(). + */ + uint16_t x1[18], x2[18], x3[18], z2[18], z3[18]; + uint16_t a[19], aa[18], b[19], bb[18]; + uint16_t c[18], d[18], e[18], da[18], cb[18]; + unsigned char k[32]; + uint32_t swap; + int i; + + (void)curve; + + /* + * Points are encoded over exactly 32 bytes. Multipliers must fit + * in 32 bytes as well. + * RFC 7748 mandates that the high bit of the last point byte must + * be ignored/cleared. + */ + if (Glen != 32 || kblen > 32) { + return 0; + } + G[31] &= 0x7F; + + /* + * Byteswap the point encoding, because it uses little-endian, and + * the generic decoding routine uses big-endian. + */ + byteswap(G); + + /* + * Decode the point ('u' coordinate). This should be reduced + * modulo p, but we prefer to avoid the dependency on + * br_i15_decode_reduce(). Instead, we use br_i15_decode_mod() + * with a synthetic modulus of value 2^255 (this must work + * since G was truncated to 255 bits), then use a conditional + * subtraction. We use br_i15_decode_mod() and not + * br_i15_decode(), because the ec_prime_i15 implementation uses + * the former but not the latter. + * br_i15_decode_reduce(a, G, 32, C255_P); + */ + br_i15_zero(b, 0x111); + b[18] = 1; + br_i15_decode_mod(a, G, 32, b); + a[0] = 0x110; + br_i15_sub(a, C255_P, NOT(br_i15_sub(a, C255_P, 0))); + + /* + * Initialise variables x1, x2, z2, x3 and z3. We set all of them + * into Montgomery representation. + */ + br_i15_montymul(x1, a, C255_R2, C255_P, P0I); + memcpy(x3, x1, ILEN); + br_i15_zero(z2, C255_P[0]); + memcpy(x2, z2, ILEN); + x2[1] = 19; + memcpy(z3, x2, ILEN); + + memset(k, 0, (sizeof k) - kblen); + memcpy(k + (sizeof k) - kblen, kb, kblen); + k[31] &= 0xF8; + k[0] &= 0x7F; + k[0] |= 0x40; + + /* obsolete + print_int_mont("x1", x1); + */ + + swap = 0; + for (i = 254; i >= 0; i --) { + uint32_t kt; + + kt = (k[31 - (i >> 3)] >> (i & 7)) & 1; + swap ^= kt; + cswap(x2, x3, swap); + cswap(z2, z3, swap); + swap = kt; + + /* obsolete + print_int_mont("x2", x2); + print_int_mont("z2", z2); + print_int_mont("x3", x3); + print_int_mont("z3", z3); + */ + + c255_add(a, x2, z2); + c255_mul(aa, a, a); + c255_sub(b, x2, z2); + c255_mul(bb, b, b); + c255_sub(e, aa, bb); + c255_add(c, x3, z3); + c255_sub(d, x3, z3); + c255_mul(da, d, a); + c255_mul(cb, c, b); + + /* obsolete + print_int_mont("a ", a); + print_int_mont("aa", aa); + print_int_mont("b ", b); + print_int_mont("bb", bb); + print_int_mont("e ", e); + print_int_mont("c ", c); + print_int_mont("d ", d); + print_int_mont("da", da); + print_int_mont("cb", cb); + */ + + c255_add(x3, da, cb); + c255_mul(x3, x3, x3); + c255_sub(z3, da, cb); + c255_mul(z3, z3, z3); + c255_mul(z3, z3, x1); + c255_mul(x2, aa, bb); + c255_mul(z2, C255_A24, e); + c255_add(z2, z2, aa); + c255_mul(z2, e, z2); + + /* obsolete + print_int_mont("x2", x2); + print_int_mont("z2", z2); + print_int_mont("x3", x3); + print_int_mont("z3", z3); + */ + } + cswap(x2, x3, swap); + cswap(z2, z3, swap); + + /* + * Inverse z2 with a modular exponentiation. This is a simple + * square-and-multiply algorithm; we mutualise most non-squarings + * since the exponent contains almost only ones. + */ + memcpy(a, z2, ILEN); + for (i = 0; i < 15; i ++) { + c255_mul(a, a, a); + c255_mul(a, a, z2); + } + memcpy(b, a, ILEN); + for (i = 0; i < 14; i ++) { + int j; + + for (j = 0; j < 16; j ++) { + c255_mul(b, b, b); + } + c255_mul(b, b, a); + } + for (i = 14; i >= 0; i --) { + c255_mul(b, b, b); + if ((0xFFEB >> i) & 1) { + c255_mul(b, z2, b); + } + } + c255_mul(b, x2, b); + + /* + * To avoid a dependency on br_i15_from_monty(), we use a + * Montgomery multiplication with 1. + * memcpy(x2, b, ILEN); + * br_i15_from_monty(x2, C255_P, P0I); + */ + br_i15_zero(a, C255_P[0]); + a[1] = 1; + br_i15_montymul(x2, a, b, C255_P, P0I); + + br_i15_encode(G, 32, x2); + byteswap(G); + return 1; + +#undef ILEN +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + const unsigned char *G; + size_t Glen; + + G = api_generator(curve, &Glen); + memcpy(R, G, Glen); + api_mul(R, Glen, x, xlen, curve); + return Glen; +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + /* + * We don't implement this method, since it is used for ECDSA + * only, and there is no ECDSA over Curve25519 (which instead + * uses EdDSA). + */ + (void)A; + (void)B; + (void)len; + (void)x; + (void)xlen; + (void)y; + (void)ylen; + (void)curve; + return 0; +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_c25519_i15 = { + (uint32_t)0x20000000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_c25519_i31.c b/BearSSL-OG/libbearssl/src/ec/ec_c25519_i31.c new file mode 100644 index 0000000..f8ffc2c --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_c25519_i31.c @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Parameters for the field: + * - field modulus p = 2^255-19 + * - R^2 mod p (R = 2^(31k) for the smallest k such that R >= p) + */ + +static const uint32_t C255_P[] = { + 0x00000107, + 0x7FFFFFED, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, + 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x0000007F +}; + +#define P0I 0x286BCA1B + +static const uint32_t C255_R2[] = { + 0x00000107, + 0x00000000, 0x02D20000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +static const uint32_t C255_A24[] = { + 0x00000107, + 0x53000000, 0x0000468B, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +/* obsolete +#include +#include +static void +print_int_mont(const char *name, const uint32_t *x) +{ + uint32_t y[10]; + unsigned char tmp[32]; + size_t u; + + printf("%s = ", name); + memcpy(y, x, sizeof y); + br_i31_from_monty(y, C255_P, P0I); + br_i31_encode(tmp, sizeof tmp, y); + for (u = 0; u < sizeof tmp; u ++) { + printf("%02X", tmp[u]); + } + printf("\n"); +} +*/ + +static const unsigned char GEN[] = { + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const unsigned char ORDER[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return GEN; +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return ORDER; +} + +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 0; +} + +static void +cswap(uint32_t *a, uint32_t *b, uint32_t ctl) +{ + int i; + + ctl = -ctl; + for (i = 0; i < 10; i ++) { + uint32_t aw, bw, tw; + + aw = a[i]; + bw = b[i]; + tw = ctl & (aw ^ bw); + a[i] = aw ^ tw; + b[i] = bw ^ tw; + } +} + +static void +c255_add(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + uint32_t ctl; + uint32_t t[10]; + + memcpy(t, a, sizeof t); + ctl = br_i31_add(t, b, 1); + ctl |= NOT(br_i31_sub(t, C255_P, 0)); + br_i31_sub(t, C255_P, ctl); + memcpy(d, t, sizeof t); +} + +static void +c255_sub(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + uint32_t t[10]; + + memcpy(t, a, sizeof t); + br_i31_add(t, C255_P, br_i31_sub(t, b, 1)); + memcpy(d, t, sizeof t); +} + +static void +c255_mul(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + uint32_t t[10]; + + br_i31_montymul(t, a, b, C255_P, P0I); + memcpy(d, t, sizeof t); +} + +static void +byteswap(unsigned char *G) +{ + int i; + + for (i = 0; i < 16; i ++) { + unsigned char t; + + t = G[i]; + G[i] = G[31 - i]; + G[31 - i] = t; + } +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *kb, size_t kblen, int curve) +{ + uint32_t x1[10], x2[10], x3[10], z2[10], z3[10]; + uint32_t a[10], aa[10], b[10], bb[10]; + uint32_t c[10], d[10], e[10], da[10], cb[10]; + unsigned char k[32]; + uint32_t swap; + int i; + + (void)curve; + + /* + * Points are encoded over exactly 32 bytes. Multipliers must fit + * in 32 bytes as well. + * RFC 7748 mandates that the high bit of the last point byte must + * be ignored/cleared. + */ + if (Glen != 32 || kblen > 32) { + return 0; + } + G[31] &= 0x7F; + + /* + * Byteswap the point encoding, because it uses little-endian, and + * the generic decoding routine uses big-endian. + */ + byteswap(G); + + /* + * Decode the point ('u' coordinate). This should be reduced + * modulo p, but we prefer to avoid the dependency on + * br_i31_decode_reduce(). Instead, we use br_i31_decode_mod() + * with a synthetic modulus of value 2^255 (this must work + * since G was truncated to 255 bits), then use a conditional + * subtraction. We use br_i31_decode_mod() and not + * br_i31_decode(), because the ec_prime_i31 implementation uses + * the former but not the latter. + * br_i31_decode_reduce(a, G, 32, C255_P); + */ + br_i31_zero(b, 0x108); + b[9] = 0x0080; + br_i31_decode_mod(a, G, 32, b); + a[0] = 0x107; + br_i31_sub(a, C255_P, NOT(br_i31_sub(a, C255_P, 0))); + + /* + * Initialise variables x1, x2, z2, x3 and z3. We set all of them + * into Montgomery representation. + */ + br_i31_montymul(x1, a, C255_R2, C255_P, P0I); + memcpy(x3, x1, sizeof x1); + br_i31_zero(z2, C255_P[0]); + memcpy(x2, z2, sizeof z2); + x2[1] = 0x13000000; + memcpy(z3, x2, sizeof x2); + + /* + * kb[] is in big-endian notation, but possibly shorter than k[]. + */ + memset(k, 0, (sizeof k) - kblen); + memcpy(k + (sizeof k) - kblen, kb, kblen); + k[31] &= 0xF8; + k[0] &= 0x7F; + k[0] |= 0x40; + + /* obsolete + print_int_mont("x1", x1); + */ + + swap = 0; + for (i = 254; i >= 0; i --) { + uint32_t kt; + + kt = (k[31 - (i >> 3)] >> (i & 7)) & 1; + swap ^= kt; + cswap(x2, x3, swap); + cswap(z2, z3, swap); + swap = kt; + + /* obsolete + print_int_mont("x2", x2); + print_int_mont("z2", z2); + print_int_mont("x3", x3); + print_int_mont("z3", z3); + */ + + c255_add(a, x2, z2); + c255_mul(aa, a, a); + c255_sub(b, x2, z2); + c255_mul(bb, b, b); + c255_sub(e, aa, bb); + c255_add(c, x3, z3); + c255_sub(d, x3, z3); + c255_mul(da, d, a); + c255_mul(cb, c, b); + + /* obsolete + print_int_mont("a ", a); + print_int_mont("aa", aa); + print_int_mont("b ", b); + print_int_mont("bb", bb); + print_int_mont("e ", e); + print_int_mont("c ", c); + print_int_mont("d ", d); + print_int_mont("da", da); + print_int_mont("cb", cb); + */ + + c255_add(x3, da, cb); + c255_mul(x3, x3, x3); + c255_sub(z3, da, cb); + c255_mul(z3, z3, z3); + c255_mul(z3, z3, x1); + c255_mul(x2, aa, bb); + c255_mul(z2, C255_A24, e); + c255_add(z2, z2, aa); + c255_mul(z2, e, z2); + + /* obsolete + print_int_mont("x2", x2); + print_int_mont("z2", z2); + print_int_mont("x3", x3); + print_int_mont("z3", z3); + */ + } + cswap(x2, x3, swap); + cswap(z2, z3, swap); + + /* + * Inverse z2 with a modular exponentiation. This is a simple + * square-and-multiply algorithm; we mutualise most non-squarings + * since the exponent contains almost only ones. + */ + memcpy(a, z2, sizeof z2); + for (i = 0; i < 15; i ++) { + c255_mul(a, a, a); + c255_mul(a, a, z2); + } + memcpy(b, a, sizeof a); + for (i = 0; i < 14; i ++) { + int j; + + for (j = 0; j < 16; j ++) { + c255_mul(b, b, b); + } + c255_mul(b, b, a); + } + for (i = 14; i >= 0; i --) { + c255_mul(b, b, b); + if ((0xFFEB >> i) & 1) { + c255_mul(b, z2, b); + } + } + c255_mul(b, x2, b); + + /* + * To avoid a dependency on br_i31_from_monty(), we use + * a Montgomery multiplication with 1. + * memcpy(x2, b, sizeof b); + * br_i31_from_monty(x2, C255_P, P0I); + */ + br_i31_zero(a, C255_P[0]); + a[1] = 1; + br_i31_montymul(x2, a, b, C255_P, P0I); + + br_i31_encode(G, 32, x2); + byteswap(G); + return 1; +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + const unsigned char *G; + size_t Glen; + + G = api_generator(curve, &Glen); + memcpy(R, G, Glen); + api_mul(R, Glen, x, xlen, curve); + return Glen; +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + /* + * We don't implement this method, since it is used for ECDSA + * only, and there is no ECDSA over Curve25519 (which instead + * uses EdDSA). + */ + (void)A; + (void)B; + (void)len; + (void)x; + (void)xlen; + (void)y; + (void)ylen; + (void)curve; + return 0; +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_c25519_i31 = { + (uint32_t)0x20000000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_c25519_m15.c b/BearSSL-OG/libbearssl/src/ec/ec_c25519_m15.c new file mode 100644 index 0000000..289d37c --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_c25519_m15.c @@ -0,0 +1,1478 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* obsolete +#include +#include +static void +print_int(const char *name, const uint32_t *x) +{ + size_t u; + unsigned char tmp[36]; + + printf("%s = ", name); + for (u = 0; u < 20; u ++) { + if (x[u] > 0x1FFF) { + printf("INVALID:"); + for (u = 0; u < 20; u ++) { + printf(" %04X", x[u]); + } + printf("\n"); + return; + } + } + memset(tmp, 0, sizeof tmp); + for (u = 0; u < 20; u ++) { + uint32_t w; + int j, k; + + w = x[u]; + j = 13 * (int)u; + k = j & 7; + if (k != 0) { + w <<= k; + j -= k; + } + k = j >> 3; + tmp[35 - k] |= (unsigned char)w; + tmp[34 - k] |= (unsigned char)(w >> 8); + tmp[33 - k] |= (unsigned char)(w >> 16); + tmp[32 - k] |= (unsigned char)(w >> 24); + } + for (u = 4; u < 36; u ++) { + printf("%02X", tmp[u]); + } + printf("\n"); +} +*/ + +/* + * If BR_NO_ARITH_SHIFT is undefined, or defined to 0, then we _assume_ + * that right-shifting a signed negative integer copies the sign bit + * (arithmetic right-shift). This is "implementation-defined behaviour", + * i.e. it is not undefined, but it may differ between compilers. Each + * compiler is supposed to document its behaviour in that respect. GCC + * explicitly defines that an arithmetic right shift is used. We expect + * all other compilers to do the same, because underlying CPU offer an + * arithmetic right shift opcode that could not be used otherwise. + */ +#if BR_NO_ARITH_SHIFT +#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ + | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) +#else +#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) +#endif + +/* + * Convert an integer from unsigned little-endian encoding to a sequence of + * 13-bit words in little-endian order. The final "partial" word is + * returned. + */ +static uint32_t +le8_to_le13(uint32_t *dst, const unsigned char *src, size_t len) +{ + uint32_t acc; + int acc_len; + + acc = 0; + acc_len = 0; + while (len -- > 0) { + acc |= (uint32_t)(*src ++) << acc_len; + acc_len += 8; + if (acc_len >= 13) { + *dst ++ = acc & 0x1FFF; + acc >>= 13; + acc_len -= 13; + } + } + return acc; +} + +/* + * Convert an integer (13-bit words, little-endian) to unsigned + * little-endian encoding. The total encoding length is provided; all + * the destination bytes will be filled. + */ +static void +le13_to_le8(unsigned char *dst, size_t len, const uint32_t *src) +{ + uint32_t acc; + int acc_len; + + acc = 0; + acc_len = 0; + while (len -- > 0) { + if (acc_len < 8) { + acc |= (*src ++) << acc_len; + acc_len += 13; + } + *dst ++ = (unsigned char)acc; + acc >>= 8; + acc_len -= 8; + } +} + +/* + * Normalise an array of words to a strict 13 bits per word. Returned + * value is the resulting carry. The source (w) and destination (d) + * arrays may be identical, but shall not overlap partially. + */ +static __inline uint32_t +norm13(uint32_t *d, const uint32_t *w, size_t len) +{ + size_t u; + uint32_t cc; + + cc = 0; + for (u = 0; u < len; u ++) { + int32_t z; + + z = w[u] + cc; + d[u] = z & 0x1FFF; + cc = ARSH(z, 13); + } + return cc; +} + +/* + * mul20() multiplies two 260-bit integers together. Each word must fit + * on 13 bits; source operands use 20 words, destination operand + * receives 40 words. All overlaps allowed. + * + * square20() computes the square of a 260-bit integer. Each word must + * fit on 13 bits; source operand uses 20 words, destination operand + * receives 40 words. All overlaps allowed. + */ + +#if BR_SLOW_MUL15 + +static void +mul20(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + /* + * Two-level Karatsuba: turns a 20x20 multiplication into + * nine 5x5 multiplications. We use 13-bit words but do not + * propagate carries immediately, so words may expand: + * + * - First Karatsuba decomposition turns the 20x20 mul on + * 13-bit words into three 10x10 muls, two on 13-bit words + * and one on 14-bit words. + * + * - Second Karatsuba decomposition further splits these into: + * + * * four 5x5 muls on 13-bit words + * * four 5x5 muls on 14-bit words + * * one 5x5 mul on 15-bit words + * + * Highest word value is 8191, 16382 or 32764, for 13-bit, 14-bit + * or 15-bit words, respectively. + */ + uint32_t u[45], v[45], w[90]; + uint32_t cc; + int i; + +#define ZADD(dw, d_off, s1w, s1_off, s2w, s2_off) do { \ + (dw)[5 * (d_off) + 0] = (s1w)[5 * (s1_off) + 0] \ + + (s2w)[5 * (s2_off) + 0]; \ + (dw)[5 * (d_off) + 1] = (s1w)[5 * (s1_off) + 1] \ + + (s2w)[5 * (s2_off) + 1]; \ + (dw)[5 * (d_off) + 2] = (s1w)[5 * (s1_off) + 2] \ + + (s2w)[5 * (s2_off) + 2]; \ + (dw)[5 * (d_off) + 3] = (s1w)[5 * (s1_off) + 3] \ + + (s2w)[5 * (s2_off) + 3]; \ + (dw)[5 * (d_off) + 4] = (s1w)[5 * (s1_off) + 4] \ + + (s2w)[5 * (s2_off) + 4]; \ + } while (0) + +#define ZADDT(dw, d_off, sw, s_off) do { \ + (dw)[5 * (d_off) + 0] += (sw)[5 * (s_off) + 0]; \ + (dw)[5 * (d_off) + 1] += (sw)[5 * (s_off) + 1]; \ + (dw)[5 * (d_off) + 2] += (sw)[5 * (s_off) + 2]; \ + (dw)[5 * (d_off) + 3] += (sw)[5 * (s_off) + 3]; \ + (dw)[5 * (d_off) + 4] += (sw)[5 * (s_off) + 4]; \ + } while (0) + +#define ZSUB2F(dw, d_off, s1w, s1_off, s2w, s2_off) do { \ + (dw)[5 * (d_off) + 0] -= (s1w)[5 * (s1_off) + 0] \ + + (s2w)[5 * (s2_off) + 0]; \ + (dw)[5 * (d_off) + 1] -= (s1w)[5 * (s1_off) + 1] \ + + (s2w)[5 * (s2_off) + 1]; \ + (dw)[5 * (d_off) + 2] -= (s1w)[5 * (s1_off) + 2] \ + + (s2w)[5 * (s2_off) + 2]; \ + (dw)[5 * (d_off) + 3] -= (s1w)[5 * (s1_off) + 3] \ + + (s2w)[5 * (s2_off) + 3]; \ + (dw)[5 * (d_off) + 4] -= (s1w)[5 * (s1_off) + 4] \ + + (s2w)[5 * (s2_off) + 4]; \ + } while (0) + +#define CPR1(w, cprcc) do { \ + uint32_t cprz = (w) + cprcc; \ + (w) = cprz & 0x1FFF; \ + cprcc = cprz >> 13; \ + } while (0) + +#define CPR(dw, d_off) do { \ + uint32_t cprcc; \ + cprcc = 0; \ + CPR1((dw)[(d_off) + 0], cprcc); \ + CPR1((dw)[(d_off) + 1], cprcc); \ + CPR1((dw)[(d_off) + 2], cprcc); \ + CPR1((dw)[(d_off) + 3], cprcc); \ + CPR1((dw)[(d_off) + 4], cprcc); \ + CPR1((dw)[(d_off) + 5], cprcc); \ + CPR1((dw)[(d_off) + 6], cprcc); \ + CPR1((dw)[(d_off) + 7], cprcc); \ + CPR1((dw)[(d_off) + 8], cprcc); \ + (dw)[(d_off) + 9] = cprcc; \ + } while (0) + + memcpy(u, a, 20 * sizeof *a); + ZADD(u, 4, a, 0, a, 1); + ZADD(u, 5, a, 2, a, 3); + ZADD(u, 6, a, 0, a, 2); + ZADD(u, 7, a, 1, a, 3); + ZADD(u, 8, u, 6, u, 7); + + memcpy(v, b, 20 * sizeof *b); + ZADD(v, 4, b, 0, b, 1); + ZADD(v, 5, b, 2, b, 3); + ZADD(v, 6, b, 0, b, 2); + ZADD(v, 7, b, 1, b, 3); + ZADD(v, 8, v, 6, v, 7); + + /* + * Do the eight first 8x8 muls. Source words are at most 16382 + * each, so we can add product results together "as is" in 32-bit + * words. + */ + for (i = 0; i < 40; i += 5) { + w[(i << 1) + 0] = MUL15(u[i + 0], v[i + 0]); + w[(i << 1) + 1] = MUL15(u[i + 0], v[i + 1]) + + MUL15(u[i + 1], v[i + 0]); + w[(i << 1) + 2] = MUL15(u[i + 0], v[i + 2]) + + MUL15(u[i + 1], v[i + 1]) + + MUL15(u[i + 2], v[i + 0]); + w[(i << 1) + 3] = MUL15(u[i + 0], v[i + 3]) + + MUL15(u[i + 1], v[i + 2]) + + MUL15(u[i + 2], v[i + 1]) + + MUL15(u[i + 3], v[i + 0]); + w[(i << 1) + 4] = MUL15(u[i + 0], v[i + 4]) + + MUL15(u[i + 1], v[i + 3]) + + MUL15(u[i + 2], v[i + 2]) + + MUL15(u[i + 3], v[i + 1]) + + MUL15(u[i + 4], v[i + 0]); + w[(i << 1) + 5] = MUL15(u[i + 1], v[i + 4]) + + MUL15(u[i + 2], v[i + 3]) + + MUL15(u[i + 3], v[i + 2]) + + MUL15(u[i + 4], v[i + 1]); + w[(i << 1) + 6] = MUL15(u[i + 2], v[i + 4]) + + MUL15(u[i + 3], v[i + 3]) + + MUL15(u[i + 4], v[i + 2]); + w[(i << 1) + 7] = MUL15(u[i + 3], v[i + 4]) + + MUL15(u[i + 4], v[i + 3]); + w[(i << 1) + 8] = MUL15(u[i + 4], v[i + 4]); + w[(i << 1) + 9] = 0; + } + + /* + * For the 9th multiplication, source words are up to 32764, + * so we must do some carry propagation. If we add up to + * 4 products and the carry is no more than 524224, then the + * result fits in 32 bits, and the next carry will be no more + * than 524224 (because 4*(32764^2)+524224 < 8192*524225). + * + * We thus just skip one of the products in the middle word, + * then do a carry propagation (this reduces words to 13 bits + * each, except possibly the last, which may use up to 17 bits + * or so), then add the missing product. + */ + w[80 + 0] = MUL15(u[40 + 0], v[40 + 0]); + w[80 + 1] = MUL15(u[40 + 0], v[40 + 1]) + + MUL15(u[40 + 1], v[40 + 0]); + w[80 + 2] = MUL15(u[40 + 0], v[40 + 2]) + + MUL15(u[40 + 1], v[40 + 1]) + + MUL15(u[40 + 2], v[40 + 0]); + w[80 + 3] = MUL15(u[40 + 0], v[40 + 3]) + + MUL15(u[40 + 1], v[40 + 2]) + + MUL15(u[40 + 2], v[40 + 1]) + + MUL15(u[40 + 3], v[40 + 0]); + w[80 + 4] = MUL15(u[40 + 0], v[40 + 4]) + + MUL15(u[40 + 1], v[40 + 3]) + + MUL15(u[40 + 2], v[40 + 2]) + + MUL15(u[40 + 3], v[40 + 1]); + /* + MUL15(u[40 + 4], v[40 + 0]) */ + w[80 + 5] = MUL15(u[40 + 1], v[40 + 4]) + + MUL15(u[40 + 2], v[40 + 3]) + + MUL15(u[40 + 3], v[40 + 2]) + + MUL15(u[40 + 4], v[40 + 1]); + w[80 + 6] = MUL15(u[40 + 2], v[40 + 4]) + + MUL15(u[40 + 3], v[40 + 3]) + + MUL15(u[40 + 4], v[40 + 2]); + w[80 + 7] = MUL15(u[40 + 3], v[40 + 4]) + + MUL15(u[40 + 4], v[40 + 3]); + w[80 + 8] = MUL15(u[40 + 4], v[40 + 4]); + + CPR(w, 80); + + w[80 + 4] += MUL15(u[40 + 4], v[40 + 0]); + + /* + * The products on 14-bit words in slots 6 and 7 yield values + * up to 5*(16382^2) each, and we need to subtract two such + * values from the higher word. We need the subtraction to fit + * in a _signed_ 32-bit integer, i.e. 31 bits + a sign bit. + * However, 10*(16382^2) does not fit. So we must perform a + * bit of reduction here. + */ + CPR(w, 60); + CPR(w, 70); + + /* + * Recompose results. + */ + + /* 0..1*0..1 into 0..3 */ + ZSUB2F(w, 8, w, 0, w, 2); + ZSUB2F(w, 9, w, 1, w, 3); + ZADDT(w, 1, w, 8); + ZADDT(w, 2, w, 9); + + /* 2..3*2..3 into 4..7 */ + ZSUB2F(w, 10, w, 4, w, 6); + ZSUB2F(w, 11, w, 5, w, 7); + ZADDT(w, 5, w, 10); + ZADDT(w, 6, w, 11); + + /* (0..1+2..3)*(0..1+2..3) into 12..15 */ + ZSUB2F(w, 16, w, 12, w, 14); + ZSUB2F(w, 17, w, 13, w, 15); + ZADDT(w, 13, w, 16); + ZADDT(w, 14, w, 17); + + /* first-level recomposition */ + ZSUB2F(w, 12, w, 0, w, 4); + ZSUB2F(w, 13, w, 1, w, 5); + ZSUB2F(w, 14, w, 2, w, 6); + ZSUB2F(w, 15, w, 3, w, 7); + ZADDT(w, 2, w, 12); + ZADDT(w, 3, w, 13); + ZADDT(w, 4, w, 14); + ZADDT(w, 5, w, 15); + + /* + * Perform carry propagation to bring all words down to 13 bits. + */ + cc = norm13(d, w, 40); + d[39] += (cc << 13); + +#undef ZADD +#undef ZADDT +#undef ZSUB2F +#undef CPR1 +#undef CPR +} + +static inline void +square20(uint32_t *d, const uint32_t *a) +{ + mul20(d, a, a); +} + +#else + +static void +mul20(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + uint32_t t[39]; + + t[ 0] = MUL15(a[ 0], b[ 0]); + t[ 1] = MUL15(a[ 0], b[ 1]) + + MUL15(a[ 1], b[ 0]); + t[ 2] = MUL15(a[ 0], b[ 2]) + + MUL15(a[ 1], b[ 1]) + + MUL15(a[ 2], b[ 0]); + t[ 3] = MUL15(a[ 0], b[ 3]) + + MUL15(a[ 1], b[ 2]) + + MUL15(a[ 2], b[ 1]) + + MUL15(a[ 3], b[ 0]); + t[ 4] = MUL15(a[ 0], b[ 4]) + + MUL15(a[ 1], b[ 3]) + + MUL15(a[ 2], b[ 2]) + + MUL15(a[ 3], b[ 1]) + + MUL15(a[ 4], b[ 0]); + t[ 5] = MUL15(a[ 0], b[ 5]) + + MUL15(a[ 1], b[ 4]) + + MUL15(a[ 2], b[ 3]) + + MUL15(a[ 3], b[ 2]) + + MUL15(a[ 4], b[ 1]) + + MUL15(a[ 5], b[ 0]); + t[ 6] = MUL15(a[ 0], b[ 6]) + + MUL15(a[ 1], b[ 5]) + + MUL15(a[ 2], b[ 4]) + + MUL15(a[ 3], b[ 3]) + + MUL15(a[ 4], b[ 2]) + + MUL15(a[ 5], b[ 1]) + + MUL15(a[ 6], b[ 0]); + t[ 7] = MUL15(a[ 0], b[ 7]) + + MUL15(a[ 1], b[ 6]) + + MUL15(a[ 2], b[ 5]) + + MUL15(a[ 3], b[ 4]) + + MUL15(a[ 4], b[ 3]) + + MUL15(a[ 5], b[ 2]) + + MUL15(a[ 6], b[ 1]) + + MUL15(a[ 7], b[ 0]); + t[ 8] = MUL15(a[ 0], b[ 8]) + + MUL15(a[ 1], b[ 7]) + + MUL15(a[ 2], b[ 6]) + + MUL15(a[ 3], b[ 5]) + + MUL15(a[ 4], b[ 4]) + + MUL15(a[ 5], b[ 3]) + + MUL15(a[ 6], b[ 2]) + + MUL15(a[ 7], b[ 1]) + + MUL15(a[ 8], b[ 0]); + t[ 9] = MUL15(a[ 0], b[ 9]) + + MUL15(a[ 1], b[ 8]) + + MUL15(a[ 2], b[ 7]) + + MUL15(a[ 3], b[ 6]) + + MUL15(a[ 4], b[ 5]) + + MUL15(a[ 5], b[ 4]) + + MUL15(a[ 6], b[ 3]) + + MUL15(a[ 7], b[ 2]) + + MUL15(a[ 8], b[ 1]) + + MUL15(a[ 9], b[ 0]); + t[10] = MUL15(a[ 0], b[10]) + + MUL15(a[ 1], b[ 9]) + + MUL15(a[ 2], b[ 8]) + + MUL15(a[ 3], b[ 7]) + + MUL15(a[ 4], b[ 6]) + + MUL15(a[ 5], b[ 5]) + + MUL15(a[ 6], b[ 4]) + + MUL15(a[ 7], b[ 3]) + + MUL15(a[ 8], b[ 2]) + + MUL15(a[ 9], b[ 1]) + + MUL15(a[10], b[ 0]); + t[11] = MUL15(a[ 0], b[11]) + + MUL15(a[ 1], b[10]) + + MUL15(a[ 2], b[ 9]) + + MUL15(a[ 3], b[ 8]) + + MUL15(a[ 4], b[ 7]) + + MUL15(a[ 5], b[ 6]) + + MUL15(a[ 6], b[ 5]) + + MUL15(a[ 7], b[ 4]) + + MUL15(a[ 8], b[ 3]) + + MUL15(a[ 9], b[ 2]) + + MUL15(a[10], b[ 1]) + + MUL15(a[11], b[ 0]); + t[12] = MUL15(a[ 0], b[12]) + + MUL15(a[ 1], b[11]) + + MUL15(a[ 2], b[10]) + + MUL15(a[ 3], b[ 9]) + + MUL15(a[ 4], b[ 8]) + + MUL15(a[ 5], b[ 7]) + + MUL15(a[ 6], b[ 6]) + + MUL15(a[ 7], b[ 5]) + + MUL15(a[ 8], b[ 4]) + + MUL15(a[ 9], b[ 3]) + + MUL15(a[10], b[ 2]) + + MUL15(a[11], b[ 1]) + + MUL15(a[12], b[ 0]); + t[13] = MUL15(a[ 0], b[13]) + + MUL15(a[ 1], b[12]) + + MUL15(a[ 2], b[11]) + + MUL15(a[ 3], b[10]) + + MUL15(a[ 4], b[ 9]) + + MUL15(a[ 5], b[ 8]) + + MUL15(a[ 6], b[ 7]) + + MUL15(a[ 7], b[ 6]) + + MUL15(a[ 8], b[ 5]) + + MUL15(a[ 9], b[ 4]) + + MUL15(a[10], b[ 3]) + + MUL15(a[11], b[ 2]) + + MUL15(a[12], b[ 1]) + + MUL15(a[13], b[ 0]); + t[14] = MUL15(a[ 0], b[14]) + + MUL15(a[ 1], b[13]) + + MUL15(a[ 2], b[12]) + + MUL15(a[ 3], b[11]) + + MUL15(a[ 4], b[10]) + + MUL15(a[ 5], b[ 9]) + + MUL15(a[ 6], b[ 8]) + + MUL15(a[ 7], b[ 7]) + + MUL15(a[ 8], b[ 6]) + + MUL15(a[ 9], b[ 5]) + + MUL15(a[10], b[ 4]) + + MUL15(a[11], b[ 3]) + + MUL15(a[12], b[ 2]) + + MUL15(a[13], b[ 1]) + + MUL15(a[14], b[ 0]); + t[15] = MUL15(a[ 0], b[15]) + + MUL15(a[ 1], b[14]) + + MUL15(a[ 2], b[13]) + + MUL15(a[ 3], b[12]) + + MUL15(a[ 4], b[11]) + + MUL15(a[ 5], b[10]) + + MUL15(a[ 6], b[ 9]) + + MUL15(a[ 7], b[ 8]) + + MUL15(a[ 8], b[ 7]) + + MUL15(a[ 9], b[ 6]) + + MUL15(a[10], b[ 5]) + + MUL15(a[11], b[ 4]) + + MUL15(a[12], b[ 3]) + + MUL15(a[13], b[ 2]) + + MUL15(a[14], b[ 1]) + + MUL15(a[15], b[ 0]); + t[16] = MUL15(a[ 0], b[16]) + + MUL15(a[ 1], b[15]) + + MUL15(a[ 2], b[14]) + + MUL15(a[ 3], b[13]) + + MUL15(a[ 4], b[12]) + + MUL15(a[ 5], b[11]) + + MUL15(a[ 6], b[10]) + + MUL15(a[ 7], b[ 9]) + + MUL15(a[ 8], b[ 8]) + + MUL15(a[ 9], b[ 7]) + + MUL15(a[10], b[ 6]) + + MUL15(a[11], b[ 5]) + + MUL15(a[12], b[ 4]) + + MUL15(a[13], b[ 3]) + + MUL15(a[14], b[ 2]) + + MUL15(a[15], b[ 1]) + + MUL15(a[16], b[ 0]); + t[17] = MUL15(a[ 0], b[17]) + + MUL15(a[ 1], b[16]) + + MUL15(a[ 2], b[15]) + + MUL15(a[ 3], b[14]) + + MUL15(a[ 4], b[13]) + + MUL15(a[ 5], b[12]) + + MUL15(a[ 6], b[11]) + + MUL15(a[ 7], b[10]) + + MUL15(a[ 8], b[ 9]) + + MUL15(a[ 9], b[ 8]) + + MUL15(a[10], b[ 7]) + + MUL15(a[11], b[ 6]) + + MUL15(a[12], b[ 5]) + + MUL15(a[13], b[ 4]) + + MUL15(a[14], b[ 3]) + + MUL15(a[15], b[ 2]) + + MUL15(a[16], b[ 1]) + + MUL15(a[17], b[ 0]); + t[18] = MUL15(a[ 0], b[18]) + + MUL15(a[ 1], b[17]) + + MUL15(a[ 2], b[16]) + + MUL15(a[ 3], b[15]) + + MUL15(a[ 4], b[14]) + + MUL15(a[ 5], b[13]) + + MUL15(a[ 6], b[12]) + + MUL15(a[ 7], b[11]) + + MUL15(a[ 8], b[10]) + + MUL15(a[ 9], b[ 9]) + + MUL15(a[10], b[ 8]) + + MUL15(a[11], b[ 7]) + + MUL15(a[12], b[ 6]) + + MUL15(a[13], b[ 5]) + + MUL15(a[14], b[ 4]) + + MUL15(a[15], b[ 3]) + + MUL15(a[16], b[ 2]) + + MUL15(a[17], b[ 1]) + + MUL15(a[18], b[ 0]); + t[19] = MUL15(a[ 0], b[19]) + + MUL15(a[ 1], b[18]) + + MUL15(a[ 2], b[17]) + + MUL15(a[ 3], b[16]) + + MUL15(a[ 4], b[15]) + + MUL15(a[ 5], b[14]) + + MUL15(a[ 6], b[13]) + + MUL15(a[ 7], b[12]) + + MUL15(a[ 8], b[11]) + + MUL15(a[ 9], b[10]) + + MUL15(a[10], b[ 9]) + + MUL15(a[11], b[ 8]) + + MUL15(a[12], b[ 7]) + + MUL15(a[13], b[ 6]) + + MUL15(a[14], b[ 5]) + + MUL15(a[15], b[ 4]) + + MUL15(a[16], b[ 3]) + + MUL15(a[17], b[ 2]) + + MUL15(a[18], b[ 1]) + + MUL15(a[19], b[ 0]); + t[20] = MUL15(a[ 1], b[19]) + + MUL15(a[ 2], b[18]) + + MUL15(a[ 3], b[17]) + + MUL15(a[ 4], b[16]) + + MUL15(a[ 5], b[15]) + + MUL15(a[ 6], b[14]) + + MUL15(a[ 7], b[13]) + + MUL15(a[ 8], b[12]) + + MUL15(a[ 9], b[11]) + + MUL15(a[10], b[10]) + + MUL15(a[11], b[ 9]) + + MUL15(a[12], b[ 8]) + + MUL15(a[13], b[ 7]) + + MUL15(a[14], b[ 6]) + + MUL15(a[15], b[ 5]) + + MUL15(a[16], b[ 4]) + + MUL15(a[17], b[ 3]) + + MUL15(a[18], b[ 2]) + + MUL15(a[19], b[ 1]); + t[21] = MUL15(a[ 2], b[19]) + + MUL15(a[ 3], b[18]) + + MUL15(a[ 4], b[17]) + + MUL15(a[ 5], b[16]) + + MUL15(a[ 6], b[15]) + + MUL15(a[ 7], b[14]) + + MUL15(a[ 8], b[13]) + + MUL15(a[ 9], b[12]) + + MUL15(a[10], b[11]) + + MUL15(a[11], b[10]) + + MUL15(a[12], b[ 9]) + + MUL15(a[13], b[ 8]) + + MUL15(a[14], b[ 7]) + + MUL15(a[15], b[ 6]) + + MUL15(a[16], b[ 5]) + + MUL15(a[17], b[ 4]) + + MUL15(a[18], b[ 3]) + + MUL15(a[19], b[ 2]); + t[22] = MUL15(a[ 3], b[19]) + + MUL15(a[ 4], b[18]) + + MUL15(a[ 5], b[17]) + + MUL15(a[ 6], b[16]) + + MUL15(a[ 7], b[15]) + + MUL15(a[ 8], b[14]) + + MUL15(a[ 9], b[13]) + + MUL15(a[10], b[12]) + + MUL15(a[11], b[11]) + + MUL15(a[12], b[10]) + + MUL15(a[13], b[ 9]) + + MUL15(a[14], b[ 8]) + + MUL15(a[15], b[ 7]) + + MUL15(a[16], b[ 6]) + + MUL15(a[17], b[ 5]) + + MUL15(a[18], b[ 4]) + + MUL15(a[19], b[ 3]); + t[23] = MUL15(a[ 4], b[19]) + + MUL15(a[ 5], b[18]) + + MUL15(a[ 6], b[17]) + + MUL15(a[ 7], b[16]) + + MUL15(a[ 8], b[15]) + + MUL15(a[ 9], b[14]) + + MUL15(a[10], b[13]) + + MUL15(a[11], b[12]) + + MUL15(a[12], b[11]) + + MUL15(a[13], b[10]) + + MUL15(a[14], b[ 9]) + + MUL15(a[15], b[ 8]) + + MUL15(a[16], b[ 7]) + + MUL15(a[17], b[ 6]) + + MUL15(a[18], b[ 5]) + + MUL15(a[19], b[ 4]); + t[24] = MUL15(a[ 5], b[19]) + + MUL15(a[ 6], b[18]) + + MUL15(a[ 7], b[17]) + + MUL15(a[ 8], b[16]) + + MUL15(a[ 9], b[15]) + + MUL15(a[10], b[14]) + + MUL15(a[11], b[13]) + + MUL15(a[12], b[12]) + + MUL15(a[13], b[11]) + + MUL15(a[14], b[10]) + + MUL15(a[15], b[ 9]) + + MUL15(a[16], b[ 8]) + + MUL15(a[17], b[ 7]) + + MUL15(a[18], b[ 6]) + + MUL15(a[19], b[ 5]); + t[25] = MUL15(a[ 6], b[19]) + + MUL15(a[ 7], b[18]) + + MUL15(a[ 8], b[17]) + + MUL15(a[ 9], b[16]) + + MUL15(a[10], b[15]) + + MUL15(a[11], b[14]) + + MUL15(a[12], b[13]) + + MUL15(a[13], b[12]) + + MUL15(a[14], b[11]) + + MUL15(a[15], b[10]) + + MUL15(a[16], b[ 9]) + + MUL15(a[17], b[ 8]) + + MUL15(a[18], b[ 7]) + + MUL15(a[19], b[ 6]); + t[26] = MUL15(a[ 7], b[19]) + + MUL15(a[ 8], b[18]) + + MUL15(a[ 9], b[17]) + + MUL15(a[10], b[16]) + + MUL15(a[11], b[15]) + + MUL15(a[12], b[14]) + + MUL15(a[13], b[13]) + + MUL15(a[14], b[12]) + + MUL15(a[15], b[11]) + + MUL15(a[16], b[10]) + + MUL15(a[17], b[ 9]) + + MUL15(a[18], b[ 8]) + + MUL15(a[19], b[ 7]); + t[27] = MUL15(a[ 8], b[19]) + + MUL15(a[ 9], b[18]) + + MUL15(a[10], b[17]) + + MUL15(a[11], b[16]) + + MUL15(a[12], b[15]) + + MUL15(a[13], b[14]) + + MUL15(a[14], b[13]) + + MUL15(a[15], b[12]) + + MUL15(a[16], b[11]) + + MUL15(a[17], b[10]) + + MUL15(a[18], b[ 9]) + + MUL15(a[19], b[ 8]); + t[28] = MUL15(a[ 9], b[19]) + + MUL15(a[10], b[18]) + + MUL15(a[11], b[17]) + + MUL15(a[12], b[16]) + + MUL15(a[13], b[15]) + + MUL15(a[14], b[14]) + + MUL15(a[15], b[13]) + + MUL15(a[16], b[12]) + + MUL15(a[17], b[11]) + + MUL15(a[18], b[10]) + + MUL15(a[19], b[ 9]); + t[29] = MUL15(a[10], b[19]) + + MUL15(a[11], b[18]) + + MUL15(a[12], b[17]) + + MUL15(a[13], b[16]) + + MUL15(a[14], b[15]) + + MUL15(a[15], b[14]) + + MUL15(a[16], b[13]) + + MUL15(a[17], b[12]) + + MUL15(a[18], b[11]) + + MUL15(a[19], b[10]); + t[30] = MUL15(a[11], b[19]) + + MUL15(a[12], b[18]) + + MUL15(a[13], b[17]) + + MUL15(a[14], b[16]) + + MUL15(a[15], b[15]) + + MUL15(a[16], b[14]) + + MUL15(a[17], b[13]) + + MUL15(a[18], b[12]) + + MUL15(a[19], b[11]); + t[31] = MUL15(a[12], b[19]) + + MUL15(a[13], b[18]) + + MUL15(a[14], b[17]) + + MUL15(a[15], b[16]) + + MUL15(a[16], b[15]) + + MUL15(a[17], b[14]) + + MUL15(a[18], b[13]) + + MUL15(a[19], b[12]); + t[32] = MUL15(a[13], b[19]) + + MUL15(a[14], b[18]) + + MUL15(a[15], b[17]) + + MUL15(a[16], b[16]) + + MUL15(a[17], b[15]) + + MUL15(a[18], b[14]) + + MUL15(a[19], b[13]); + t[33] = MUL15(a[14], b[19]) + + MUL15(a[15], b[18]) + + MUL15(a[16], b[17]) + + MUL15(a[17], b[16]) + + MUL15(a[18], b[15]) + + MUL15(a[19], b[14]); + t[34] = MUL15(a[15], b[19]) + + MUL15(a[16], b[18]) + + MUL15(a[17], b[17]) + + MUL15(a[18], b[16]) + + MUL15(a[19], b[15]); + t[35] = MUL15(a[16], b[19]) + + MUL15(a[17], b[18]) + + MUL15(a[18], b[17]) + + MUL15(a[19], b[16]); + t[36] = MUL15(a[17], b[19]) + + MUL15(a[18], b[18]) + + MUL15(a[19], b[17]); + t[37] = MUL15(a[18], b[19]) + + MUL15(a[19], b[18]); + t[38] = MUL15(a[19], b[19]); + + d[39] = norm13(d, t, 39); +} + +static void +square20(uint32_t *d, const uint32_t *a) +{ + uint32_t t[39]; + + t[ 0] = MUL15(a[ 0], a[ 0]); + t[ 1] = ((MUL15(a[ 0], a[ 1])) << 1); + t[ 2] = MUL15(a[ 1], a[ 1]) + + ((MUL15(a[ 0], a[ 2])) << 1); + t[ 3] = ((MUL15(a[ 0], a[ 3]) + + MUL15(a[ 1], a[ 2])) << 1); + t[ 4] = MUL15(a[ 2], a[ 2]) + + ((MUL15(a[ 0], a[ 4]) + + MUL15(a[ 1], a[ 3])) << 1); + t[ 5] = ((MUL15(a[ 0], a[ 5]) + + MUL15(a[ 1], a[ 4]) + + MUL15(a[ 2], a[ 3])) << 1); + t[ 6] = MUL15(a[ 3], a[ 3]) + + ((MUL15(a[ 0], a[ 6]) + + MUL15(a[ 1], a[ 5]) + + MUL15(a[ 2], a[ 4])) << 1); + t[ 7] = ((MUL15(a[ 0], a[ 7]) + + MUL15(a[ 1], a[ 6]) + + MUL15(a[ 2], a[ 5]) + + MUL15(a[ 3], a[ 4])) << 1); + t[ 8] = MUL15(a[ 4], a[ 4]) + + ((MUL15(a[ 0], a[ 8]) + + MUL15(a[ 1], a[ 7]) + + MUL15(a[ 2], a[ 6]) + + MUL15(a[ 3], a[ 5])) << 1); + t[ 9] = ((MUL15(a[ 0], a[ 9]) + + MUL15(a[ 1], a[ 8]) + + MUL15(a[ 2], a[ 7]) + + MUL15(a[ 3], a[ 6]) + + MUL15(a[ 4], a[ 5])) << 1); + t[10] = MUL15(a[ 5], a[ 5]) + + ((MUL15(a[ 0], a[10]) + + MUL15(a[ 1], a[ 9]) + + MUL15(a[ 2], a[ 8]) + + MUL15(a[ 3], a[ 7]) + + MUL15(a[ 4], a[ 6])) << 1); + t[11] = ((MUL15(a[ 0], a[11]) + + MUL15(a[ 1], a[10]) + + MUL15(a[ 2], a[ 9]) + + MUL15(a[ 3], a[ 8]) + + MUL15(a[ 4], a[ 7]) + + MUL15(a[ 5], a[ 6])) << 1); + t[12] = MUL15(a[ 6], a[ 6]) + + ((MUL15(a[ 0], a[12]) + + MUL15(a[ 1], a[11]) + + MUL15(a[ 2], a[10]) + + MUL15(a[ 3], a[ 9]) + + MUL15(a[ 4], a[ 8]) + + MUL15(a[ 5], a[ 7])) << 1); + t[13] = ((MUL15(a[ 0], a[13]) + + MUL15(a[ 1], a[12]) + + MUL15(a[ 2], a[11]) + + MUL15(a[ 3], a[10]) + + MUL15(a[ 4], a[ 9]) + + MUL15(a[ 5], a[ 8]) + + MUL15(a[ 6], a[ 7])) << 1); + t[14] = MUL15(a[ 7], a[ 7]) + + ((MUL15(a[ 0], a[14]) + + MUL15(a[ 1], a[13]) + + MUL15(a[ 2], a[12]) + + MUL15(a[ 3], a[11]) + + MUL15(a[ 4], a[10]) + + MUL15(a[ 5], a[ 9]) + + MUL15(a[ 6], a[ 8])) << 1); + t[15] = ((MUL15(a[ 0], a[15]) + + MUL15(a[ 1], a[14]) + + MUL15(a[ 2], a[13]) + + MUL15(a[ 3], a[12]) + + MUL15(a[ 4], a[11]) + + MUL15(a[ 5], a[10]) + + MUL15(a[ 6], a[ 9]) + + MUL15(a[ 7], a[ 8])) << 1); + t[16] = MUL15(a[ 8], a[ 8]) + + ((MUL15(a[ 0], a[16]) + + MUL15(a[ 1], a[15]) + + MUL15(a[ 2], a[14]) + + MUL15(a[ 3], a[13]) + + MUL15(a[ 4], a[12]) + + MUL15(a[ 5], a[11]) + + MUL15(a[ 6], a[10]) + + MUL15(a[ 7], a[ 9])) << 1); + t[17] = ((MUL15(a[ 0], a[17]) + + MUL15(a[ 1], a[16]) + + MUL15(a[ 2], a[15]) + + MUL15(a[ 3], a[14]) + + MUL15(a[ 4], a[13]) + + MUL15(a[ 5], a[12]) + + MUL15(a[ 6], a[11]) + + MUL15(a[ 7], a[10]) + + MUL15(a[ 8], a[ 9])) << 1); + t[18] = MUL15(a[ 9], a[ 9]) + + ((MUL15(a[ 0], a[18]) + + MUL15(a[ 1], a[17]) + + MUL15(a[ 2], a[16]) + + MUL15(a[ 3], a[15]) + + MUL15(a[ 4], a[14]) + + MUL15(a[ 5], a[13]) + + MUL15(a[ 6], a[12]) + + MUL15(a[ 7], a[11]) + + MUL15(a[ 8], a[10])) << 1); + t[19] = ((MUL15(a[ 0], a[19]) + + MUL15(a[ 1], a[18]) + + MUL15(a[ 2], a[17]) + + MUL15(a[ 3], a[16]) + + MUL15(a[ 4], a[15]) + + MUL15(a[ 5], a[14]) + + MUL15(a[ 6], a[13]) + + MUL15(a[ 7], a[12]) + + MUL15(a[ 8], a[11]) + + MUL15(a[ 9], a[10])) << 1); + t[20] = MUL15(a[10], a[10]) + + ((MUL15(a[ 1], a[19]) + + MUL15(a[ 2], a[18]) + + MUL15(a[ 3], a[17]) + + MUL15(a[ 4], a[16]) + + MUL15(a[ 5], a[15]) + + MUL15(a[ 6], a[14]) + + MUL15(a[ 7], a[13]) + + MUL15(a[ 8], a[12]) + + MUL15(a[ 9], a[11])) << 1); + t[21] = ((MUL15(a[ 2], a[19]) + + MUL15(a[ 3], a[18]) + + MUL15(a[ 4], a[17]) + + MUL15(a[ 5], a[16]) + + MUL15(a[ 6], a[15]) + + MUL15(a[ 7], a[14]) + + MUL15(a[ 8], a[13]) + + MUL15(a[ 9], a[12]) + + MUL15(a[10], a[11])) << 1); + t[22] = MUL15(a[11], a[11]) + + ((MUL15(a[ 3], a[19]) + + MUL15(a[ 4], a[18]) + + MUL15(a[ 5], a[17]) + + MUL15(a[ 6], a[16]) + + MUL15(a[ 7], a[15]) + + MUL15(a[ 8], a[14]) + + MUL15(a[ 9], a[13]) + + MUL15(a[10], a[12])) << 1); + t[23] = ((MUL15(a[ 4], a[19]) + + MUL15(a[ 5], a[18]) + + MUL15(a[ 6], a[17]) + + MUL15(a[ 7], a[16]) + + MUL15(a[ 8], a[15]) + + MUL15(a[ 9], a[14]) + + MUL15(a[10], a[13]) + + MUL15(a[11], a[12])) << 1); + t[24] = MUL15(a[12], a[12]) + + ((MUL15(a[ 5], a[19]) + + MUL15(a[ 6], a[18]) + + MUL15(a[ 7], a[17]) + + MUL15(a[ 8], a[16]) + + MUL15(a[ 9], a[15]) + + MUL15(a[10], a[14]) + + MUL15(a[11], a[13])) << 1); + t[25] = ((MUL15(a[ 6], a[19]) + + MUL15(a[ 7], a[18]) + + MUL15(a[ 8], a[17]) + + MUL15(a[ 9], a[16]) + + MUL15(a[10], a[15]) + + MUL15(a[11], a[14]) + + MUL15(a[12], a[13])) << 1); + t[26] = MUL15(a[13], a[13]) + + ((MUL15(a[ 7], a[19]) + + MUL15(a[ 8], a[18]) + + MUL15(a[ 9], a[17]) + + MUL15(a[10], a[16]) + + MUL15(a[11], a[15]) + + MUL15(a[12], a[14])) << 1); + t[27] = ((MUL15(a[ 8], a[19]) + + MUL15(a[ 9], a[18]) + + MUL15(a[10], a[17]) + + MUL15(a[11], a[16]) + + MUL15(a[12], a[15]) + + MUL15(a[13], a[14])) << 1); + t[28] = MUL15(a[14], a[14]) + + ((MUL15(a[ 9], a[19]) + + MUL15(a[10], a[18]) + + MUL15(a[11], a[17]) + + MUL15(a[12], a[16]) + + MUL15(a[13], a[15])) << 1); + t[29] = ((MUL15(a[10], a[19]) + + MUL15(a[11], a[18]) + + MUL15(a[12], a[17]) + + MUL15(a[13], a[16]) + + MUL15(a[14], a[15])) << 1); + t[30] = MUL15(a[15], a[15]) + + ((MUL15(a[11], a[19]) + + MUL15(a[12], a[18]) + + MUL15(a[13], a[17]) + + MUL15(a[14], a[16])) << 1); + t[31] = ((MUL15(a[12], a[19]) + + MUL15(a[13], a[18]) + + MUL15(a[14], a[17]) + + MUL15(a[15], a[16])) << 1); + t[32] = MUL15(a[16], a[16]) + + ((MUL15(a[13], a[19]) + + MUL15(a[14], a[18]) + + MUL15(a[15], a[17])) << 1); + t[33] = ((MUL15(a[14], a[19]) + + MUL15(a[15], a[18]) + + MUL15(a[16], a[17])) << 1); + t[34] = MUL15(a[17], a[17]) + + ((MUL15(a[15], a[19]) + + MUL15(a[16], a[18])) << 1); + t[35] = ((MUL15(a[16], a[19]) + + MUL15(a[17], a[18])) << 1); + t[36] = MUL15(a[18], a[18]) + + ((MUL15(a[17], a[19])) << 1); + t[37] = ((MUL15(a[18], a[19])) << 1); + t[38] = MUL15(a[19], a[19]); + + d[39] = norm13(d, t, 39); +} + +#endif + +/* + * Perform a "final reduction" in field F255 (field for Curve25519) + * The source value must be less than twice the modulus. If the value + * is not lower than the modulus, then the modulus is subtracted and + * this function returns 1; otherwise, it leaves it untouched and it + * returns 0. + */ +static uint32_t +reduce_final_f255(uint32_t *d) +{ + uint32_t t[20]; + uint32_t cc; + int i; + + memcpy(t, d, sizeof t); + cc = 19; + for (i = 0; i < 20; i ++) { + uint32_t w; + + w = t[i] + cc; + cc = w >> 13; + t[i] = w & 0x1FFF; + } + cc = t[19] >> 8; + t[19] &= 0xFF; + CCOPY(cc, d, t, sizeof t); + return cc; +} + +static void +f255_mulgen(uint32_t *d, const uint32_t *a, const uint32_t *b, int square) +{ + uint32_t t[40], cc, w; + + /* + * Compute raw multiplication. All result words fit in 13 bits + * each; upper word (t[39]) must fit on 5 bits, since the product + * of two 256-bit integers must fit on 512 bits. + */ + if (square) { + square20(t, a); + } else { + mul20(t, a, b); + } + + /* + * Modular reduction: each high word is added where necessary. + * Since the modulus is 2^255-19 and word 20 corresponds to + * offset 20*13 = 260, word 20+k must be added to word k with + * a factor of 19*2^5 = 608. The extra bits in word 19 are also + * added that way. + */ + cc = MUL15(t[19] >> 8, 19); + t[19] &= 0xFF; + +#define MM1(x) do { \ + w = t[x] + cc + MUL15(t[(x) + 20], 608); \ + t[x] = w & 0x1FFF; \ + cc = w >> 13; \ + } while (0) + + MM1( 0); + MM1( 1); + MM1( 2); + MM1( 3); + MM1( 4); + MM1( 5); + MM1( 6); + MM1( 7); + MM1( 8); + MM1( 9); + MM1(10); + MM1(11); + MM1(12); + MM1(13); + MM1(14); + MM1(15); + MM1(16); + MM1(17); + MM1(18); + MM1(19); + +#undef MM1 + + cc = MUL15(w >> 8, 19); + t[19] &= 0xFF; + +#define MM2(x) do { \ + w = t[x] + cc; \ + d[x] = w & 0x1FFF; \ + cc = w >> 13; \ + } while (0) + + MM2( 0); + MM2( 1); + MM2( 2); + MM2( 3); + MM2( 4); + MM2( 5); + MM2( 6); + MM2( 7); + MM2( 8); + MM2( 9); + MM2(10); + MM2(11); + MM2(12); + MM2(13); + MM2(14); + MM2(15); + MM2(16); + MM2(17); + MM2(18); + MM2(19); + +#undef MM2 +} + +/* + * Perform a multiplication of two integers modulo 2^255-19. + * Operands are arrays of 20 words, each containing 13 bits of data, in + * little-endian order. Input value may be up to 2^256-1; on output, value + * fits on 256 bits and is lower than twice the modulus. + * + * f255_mul() is the general multiplication, f255_square() is specialised + * for squarings. + */ +#define f255_mul(d, a, b) f255_mulgen(d, a, b, 0) +#define f255_square(d, a) f255_mulgen(d, a, a, 1) + +/* + * Add two values in F255. Partial reduction is performed (down to less + * than twice the modulus). + */ +static void +f255_add(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + int i; + uint32_t cc, w; + + cc = 0; + for (i = 0; i < 20; i ++) { + w = a[i] + b[i] + cc; + d[i] = w & 0x1FFF; + cc = w >> 13; + } + cc = MUL15(w >> 8, 19); + d[19] &= 0xFF; + for (i = 0; i < 20; i ++) { + w = d[i] + cc; + d[i] = w & 0x1FFF; + cc = w >> 13; + } +} + +/* + * Subtract one value from another in F255. Partial reduction is + * performed (down to less than twice the modulus). + */ +static void +f255_sub(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + /* + * We actually compute a - b + 2*p, so that the final value is + * necessarily positive. + */ + int i; + uint32_t cc, w; + + cc = (uint32_t)-38; + for (i = 0; i < 20; i ++) { + w = a[i] - b[i] + cc; + d[i] = w & 0x1FFF; + cc = ARSH(w, 13); + } + cc = MUL15((w + 0x200) >> 8, 19); + d[19] &= 0xFF; + for (i = 0; i < 20; i ++) { + w = d[i] + cc; + d[i] = w & 0x1FFF; + cc = w >> 13; + } +} + +/* + * Multiply an integer by the 'A24' constant (121665). Partial reduction + * is performed (down to less than twice the modulus). + */ +static void +f255_mul_a24(uint32_t *d, const uint32_t *a) +{ + int i; + uint32_t cc, w; + + cc = 0; + for (i = 0; i < 20; i ++) { + w = MUL15(a[i], 121665) + cc; + d[i] = w & 0x1FFF; + cc = w >> 13; + } + cc = MUL15(w >> 8, 19); + d[19] &= 0xFF; + for (i = 0; i < 20; i ++) { + w = d[i] + cc; + d[i] = w & 0x1FFF; + cc = w >> 13; + } +} + +static const unsigned char GEN[] = { + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const unsigned char ORDER[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return GEN; +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return ORDER; +} + +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 0; +} + +static void +cswap(uint32_t *a, uint32_t *b, uint32_t ctl) +{ + int i; + + ctl = -ctl; + for (i = 0; i < 20; i ++) { + uint32_t aw, bw, tw; + + aw = a[i]; + bw = b[i]; + tw = ctl & (aw ^ bw); + a[i] = aw ^ tw; + b[i] = bw ^ tw; + } +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *kb, size_t kblen, int curve) +{ + uint32_t x1[20], x2[20], x3[20], z2[20], z3[20]; + uint32_t a[20], aa[20], b[20], bb[20]; + uint32_t c[20], d[20], e[20], da[20], cb[20]; + unsigned char k[32]; + uint32_t swap; + int i; + + (void)curve; + + /* + * Points are encoded over exactly 32 bytes. Multipliers must fit + * in 32 bytes as well. + * RFC 7748 mandates that the high bit of the last point byte must + * be ignored/cleared. + */ + if (Glen != 32 || kblen > 32) { + return 0; + } + G[31] &= 0x7F; + + /* + * Initialise variables x1, x2, z2, x3 and z3. We set all of them + * into Montgomery representation. + */ + x1[19] = le8_to_le13(x1, G, 32); + memcpy(x3, x1, sizeof x1); + memset(z2, 0, sizeof z2); + memset(x2, 0, sizeof x2); + x2[0] = 1; + memset(z3, 0, sizeof z3); + z3[0] = 1; + + memset(k, 0, (sizeof k) - kblen); + memcpy(k + (sizeof k) - kblen, kb, kblen); + k[31] &= 0xF8; + k[0] &= 0x7F; + k[0] |= 0x40; + + /* obsolete + print_int("x1", x1); + */ + + swap = 0; + for (i = 254; i >= 0; i --) { + uint32_t kt; + + kt = (k[31 - (i >> 3)] >> (i & 7)) & 1; + swap ^= kt; + cswap(x2, x3, swap); + cswap(z2, z3, swap); + swap = kt; + + /* obsolete + print_int("x2", x2); + print_int("z2", z2); + print_int("x3", x3); + print_int("z3", z3); + */ + + f255_add(a, x2, z2); + f255_square(aa, a); + f255_sub(b, x2, z2); + f255_square(bb, b); + f255_sub(e, aa, bb); + f255_add(c, x3, z3); + f255_sub(d, x3, z3); + f255_mul(da, d, a); + f255_mul(cb, c, b); + + /* obsolete + print_int("a ", a); + print_int("aa", aa); + print_int("b ", b); + print_int("bb", bb); + print_int("e ", e); + print_int("c ", c); + print_int("d ", d); + print_int("da", da); + print_int("cb", cb); + */ + + f255_add(x3, da, cb); + f255_square(x3, x3); + f255_sub(z3, da, cb); + f255_square(z3, z3); + f255_mul(z3, z3, x1); + f255_mul(x2, aa, bb); + f255_mul_a24(z2, e); + f255_add(z2, z2, aa); + f255_mul(z2, e, z2); + + /* obsolete + print_int("x2", x2); + print_int("z2", z2); + print_int("x3", x3); + print_int("z3", z3); + */ + } + cswap(x2, x3, swap); + cswap(z2, z3, swap); + + /* + * Inverse z2 with a modular exponentiation. This is a simple + * square-and-multiply algorithm; we mutualise most non-squarings + * since the exponent contains almost only ones. + */ + memcpy(a, z2, sizeof z2); + for (i = 0; i < 15; i ++) { + f255_square(a, a); + f255_mul(a, a, z2); + } + memcpy(b, a, sizeof a); + for (i = 0; i < 14; i ++) { + int j; + + for (j = 0; j < 16; j ++) { + f255_square(b, b); + } + f255_mul(b, b, a); + } + for (i = 14; i >= 0; i --) { + f255_square(b, b); + if ((0xFFEB >> i) & 1) { + f255_mul(b, z2, b); + } + } + f255_mul(x2, x2, b); + reduce_final_f255(x2); + le13_to_le8(G, 32, x2); + return 1; +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + const unsigned char *G; + size_t Glen; + + G = api_generator(curve, &Glen); + memcpy(R, G, Glen); + api_mul(R, Glen, x, xlen, curve); + return Glen; +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + /* + * We don't implement this method, since it is used for ECDSA + * only, and there is no ECDSA over Curve25519 (which instead + * uses EdDSA). + */ + (void)A; + (void)B; + (void)len; + (void)x; + (void)xlen; + (void)y; + (void)ylen; + (void)curve; + return 0; +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_c25519_m15 = { + (uint32_t)0x20000000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_c25519_m31.c b/BearSSL-OG/libbearssl/src/ec/ec_c25519_m31.c new file mode 100644 index 0000000..1dd6d51 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_c25519_m31.c @@ -0,0 +1,800 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* obsolete +#include +#include +static void +print_int(const char *name, const uint32_t *x) +{ + size_t u; + unsigned char tmp[40]; + + printf("%s = ", name); + for (u = 0; u < 9; u ++) { + if (x[u] > 0x3FFFFFFF) { + printf("INVALID:"); + for (u = 0; u < 9; u ++) { + printf(" %08X", x[u]); + } + printf("\n"); + return; + } + } + memset(tmp, 0, sizeof tmp); + for (u = 0; u < 9; u ++) { + uint64_t w; + int j, k; + + w = x[u]; + j = 30 * (int)u; + k = j & 7; + if (k != 0) { + w <<= k; + j -= k; + } + k = j >> 3; + for (j = 0; j < 8; j ++) { + tmp[39 - k - j] |= (unsigned char)w; + w >>= 8; + } + } + for (u = 8; u < 40; u ++) { + printf("%02X", tmp[u]); + } + printf("\n"); +} +*/ + +/* + * If BR_NO_ARITH_SHIFT is undefined, or defined to 0, then we _assume_ + * that right-shifting a signed negative integer copies the sign bit + * (arithmetic right-shift). This is "implementation-defined behaviour", + * i.e. it is not undefined, but it may differ between compilers. Each + * compiler is supposed to document its behaviour in that respect. GCC + * explicitly defines that an arithmetic right shift is used. We expect + * all other compilers to do the same, because underlying CPU offer an + * arithmetic right shift opcode that could not be used otherwise. + */ +#if BR_NO_ARITH_SHIFT +#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ + | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) +#else +#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) +#endif + +/* + * Convert an integer from unsigned little-endian encoding to a sequence of + * 30-bit words in little-endian order. The final "partial" word is + * returned. + */ +static uint32_t +le8_to_le30(uint32_t *dst, const unsigned char *src, size_t len) +{ + uint32_t acc; + int acc_len; + + acc = 0; + acc_len = 0; + while (len -- > 0) { + uint32_t b; + + b = *src ++; + if (acc_len < 22) { + acc |= b << acc_len; + acc_len += 8; + } else { + *dst ++ = (acc | (b << acc_len)) & 0x3FFFFFFF; + acc = b >> (30 - acc_len); + acc_len -= 22; + } + } + return acc; +} + +/* + * Convert an integer (30-bit words, little-endian) to unsigned + * little-endian encoding. The total encoding length is provided; all + * the destination bytes will be filled. + */ +static void +le30_to_le8(unsigned char *dst, size_t len, const uint32_t *src) +{ + uint32_t acc; + int acc_len; + + acc = 0; + acc_len = 0; + while (len -- > 0) { + if (acc_len < 8) { + uint32_t w; + + w = *src ++; + *dst ++ = (unsigned char)(acc | (w << acc_len)); + acc = w >> (8 - acc_len); + acc_len += 22; + } else { + *dst ++ = (unsigned char)acc; + acc >>= 8; + acc_len -= 8; + } + } +} + +/* + * Multiply two integers. Source integers are represented as arrays of + * nine 30-bit words, for values up to 2^270-1. Result is encoded over + * 18 words of 30 bits each. + */ +static void +mul9(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + /* + * Maximum intermediate result is no more than + * 10376293531797946367, which fits in 64 bits. Reason: + * + * 10376293531797946367 = 9 * (2^30-1)^2 + 9663676406 + * 10376293531797946367 < 9663676407 * 2^30 + * + * Thus, adding together 9 products of 30-bit integers, with + * a carry of at most 9663676406, yields an integer that fits + * on 64 bits and generates a carry of at most 9663676406. + */ + uint64_t t[17]; + uint64_t cc; + int i; + + t[ 0] = MUL31(a[0], b[0]); + t[ 1] = MUL31(a[0], b[1]) + + MUL31(a[1], b[0]); + t[ 2] = MUL31(a[0], b[2]) + + MUL31(a[1], b[1]) + + MUL31(a[2], b[0]); + t[ 3] = MUL31(a[0], b[3]) + + MUL31(a[1], b[2]) + + MUL31(a[2], b[1]) + + MUL31(a[3], b[0]); + t[ 4] = MUL31(a[0], b[4]) + + MUL31(a[1], b[3]) + + MUL31(a[2], b[2]) + + MUL31(a[3], b[1]) + + MUL31(a[4], b[0]); + t[ 5] = MUL31(a[0], b[5]) + + MUL31(a[1], b[4]) + + MUL31(a[2], b[3]) + + MUL31(a[3], b[2]) + + MUL31(a[4], b[1]) + + MUL31(a[5], b[0]); + t[ 6] = MUL31(a[0], b[6]) + + MUL31(a[1], b[5]) + + MUL31(a[2], b[4]) + + MUL31(a[3], b[3]) + + MUL31(a[4], b[2]) + + MUL31(a[5], b[1]) + + MUL31(a[6], b[0]); + t[ 7] = MUL31(a[0], b[7]) + + MUL31(a[1], b[6]) + + MUL31(a[2], b[5]) + + MUL31(a[3], b[4]) + + MUL31(a[4], b[3]) + + MUL31(a[5], b[2]) + + MUL31(a[6], b[1]) + + MUL31(a[7], b[0]); + t[ 8] = MUL31(a[0], b[8]) + + MUL31(a[1], b[7]) + + MUL31(a[2], b[6]) + + MUL31(a[3], b[5]) + + MUL31(a[4], b[4]) + + MUL31(a[5], b[3]) + + MUL31(a[6], b[2]) + + MUL31(a[7], b[1]) + + MUL31(a[8], b[0]); + t[ 9] = MUL31(a[1], b[8]) + + MUL31(a[2], b[7]) + + MUL31(a[3], b[6]) + + MUL31(a[4], b[5]) + + MUL31(a[5], b[4]) + + MUL31(a[6], b[3]) + + MUL31(a[7], b[2]) + + MUL31(a[8], b[1]); + t[10] = MUL31(a[2], b[8]) + + MUL31(a[3], b[7]) + + MUL31(a[4], b[6]) + + MUL31(a[5], b[5]) + + MUL31(a[6], b[4]) + + MUL31(a[7], b[3]) + + MUL31(a[8], b[2]); + t[11] = MUL31(a[3], b[8]) + + MUL31(a[4], b[7]) + + MUL31(a[5], b[6]) + + MUL31(a[6], b[5]) + + MUL31(a[7], b[4]) + + MUL31(a[8], b[3]); + t[12] = MUL31(a[4], b[8]) + + MUL31(a[5], b[7]) + + MUL31(a[6], b[6]) + + MUL31(a[7], b[5]) + + MUL31(a[8], b[4]); + t[13] = MUL31(a[5], b[8]) + + MUL31(a[6], b[7]) + + MUL31(a[7], b[6]) + + MUL31(a[8], b[5]); + t[14] = MUL31(a[6], b[8]) + + MUL31(a[7], b[7]) + + MUL31(a[8], b[6]); + t[15] = MUL31(a[7], b[8]) + + MUL31(a[8], b[7]); + t[16] = MUL31(a[8], b[8]); + + /* + * Propagate carries. + */ + cc = 0; + for (i = 0; i < 17; i ++) { + uint64_t w; + + w = t[i] + cc; + d[i] = (uint32_t)w & 0x3FFFFFFF; + cc = w >> 30; + } + d[17] = (uint32_t)cc; +} + +/* + * Square a 270-bit integer, represented as an array of nine 30-bit words. + * Result uses 18 words of 30 bits each. + */ +static void +square9(uint32_t *d, const uint32_t *a) +{ + uint64_t t[17]; + uint64_t cc; + int i; + + t[ 0] = MUL31(a[0], a[0]); + t[ 1] = ((MUL31(a[0], a[1])) << 1); + t[ 2] = MUL31(a[1], a[1]) + + ((MUL31(a[0], a[2])) << 1); + t[ 3] = ((MUL31(a[0], a[3]) + + MUL31(a[1], a[2])) << 1); + t[ 4] = MUL31(a[2], a[2]) + + ((MUL31(a[0], a[4]) + + MUL31(a[1], a[3])) << 1); + t[ 5] = ((MUL31(a[0], a[5]) + + MUL31(a[1], a[4]) + + MUL31(a[2], a[3])) << 1); + t[ 6] = MUL31(a[3], a[3]) + + ((MUL31(a[0], a[6]) + + MUL31(a[1], a[5]) + + MUL31(a[2], a[4])) << 1); + t[ 7] = ((MUL31(a[0], a[7]) + + MUL31(a[1], a[6]) + + MUL31(a[2], a[5]) + + MUL31(a[3], a[4])) << 1); + t[ 8] = MUL31(a[4], a[4]) + + ((MUL31(a[0], a[8]) + + MUL31(a[1], a[7]) + + MUL31(a[2], a[6]) + + MUL31(a[3], a[5])) << 1); + t[ 9] = ((MUL31(a[1], a[8]) + + MUL31(a[2], a[7]) + + MUL31(a[3], a[6]) + + MUL31(a[4], a[5])) << 1); + t[10] = MUL31(a[5], a[5]) + + ((MUL31(a[2], a[8]) + + MUL31(a[3], a[7]) + + MUL31(a[4], a[6])) << 1); + t[11] = ((MUL31(a[3], a[8]) + + MUL31(a[4], a[7]) + + MUL31(a[5], a[6])) << 1); + t[12] = MUL31(a[6], a[6]) + + ((MUL31(a[4], a[8]) + + MUL31(a[5], a[7])) << 1); + t[13] = ((MUL31(a[5], a[8]) + + MUL31(a[6], a[7])) << 1); + t[14] = MUL31(a[7], a[7]) + + ((MUL31(a[6], a[8])) << 1); + t[15] = ((MUL31(a[7], a[8])) << 1); + t[16] = MUL31(a[8], a[8]); + + /* + * Propagate carries. + */ + cc = 0; + for (i = 0; i < 17; i ++) { + uint64_t w; + + w = t[i] + cc; + d[i] = (uint32_t)w & 0x3FFFFFFF; + cc = w >> 30; + } + d[17] = (uint32_t)cc; +} + +/* + * Perform a "final reduction" in field F255 (field for Curve25519) + * The source value must be less than twice the modulus. If the value + * is not lower than the modulus, then the modulus is subtracted and + * this function returns 1; otherwise, it leaves it untouched and it + * returns 0. + */ +static uint32_t +reduce_final_f255(uint32_t *d) +{ + uint32_t t[9]; + uint32_t cc; + int i; + + memcpy(t, d, sizeof t); + cc = 19; + for (i = 0; i < 9; i ++) { + uint32_t w; + + w = t[i] + cc; + cc = w >> 30; + t[i] = w & 0x3FFFFFFF; + } + cc = t[8] >> 15; + t[8] &= 0x7FFF; + CCOPY(cc, d, t, sizeof t); + return cc; +} + +/* + * Perform a multiplication of two integers modulo 2^255-19. + * Operands are arrays of 9 words, each containing 30 bits of data, in + * little-endian order. Input value may be up to 2^256-1; on output, value + * fits on 256 bits and is lower than twice the modulus. + */ +static void +f255_mul(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + uint32_t t[18], cc; + int i; + + /* + * Compute raw multiplication. All result words fit in 30 bits + * each; upper word (t[17]) must fit on 2 bits, since the product + * of two 256-bit integers must fit on 512 bits. + */ + mul9(t, a, b); + + /* + * Modular reduction: each high word is added where necessary. + * Since the modulus is 2^255-19 and word 9 corresponds to + * offset 9*30 = 270, word 9+k must be added to word k with + * a factor of 19*2^15 = 622592. The extra bits in word 8 are also + * added that way. + * + * Keeping the carry on 32 bits helps with 32-bit architectures, + * and does not noticeably impact performance on 64-bit systems. + */ + cc = MUL15(t[8] >> 15, 19); /* at most 19*(2^15-1) = 622573 */ + t[8] &= 0x7FFF; + for (i = 0; i < 9; i ++) { + uint64_t w; + + w = (uint64_t)t[i] + (uint64_t)cc + MUL31(t[i + 9], 622592); + t[i] = (uint32_t)w & 0x3FFFFFFF; + cc = (uint32_t)(w >> 30); /* at most 622592 */ + } + + /* + * Original product was up to (2^256-1)^2, i.e. a 512-bit integer. + * This was split into two parts (upper of 257 bits, lower of 255 + * bits), and the upper was added to the lower with a factor 19, + * which means that the intermediate value is less than 77*2^255 + * (19*2^257 + 2^255). Therefore, the extra bits "t[8] >> 15" are + * less than 77, and the initial carry cc is at most 76*19 = 1444. + */ + cc = MUL15(t[8] >> 15, 19); + t[8] &= 0x7FFF; + for (i = 0; i < 9; i ++) { + uint32_t z; + + z = t[i] + cc; + d[i] = z & 0x3FFFFFFF; + cc = z >> 30; + } + + /* + * Final result is at most 2^255 + 1443. In particular, the last + * carry is necessarily 0, since t[8] was truncated to 15 bits. + */ +} + +/* + * Perform a squaring of an integer modulo 2^255-19. + * Operands are arrays of 9 words, each containing 30 bits of data, in + * little-endian order. Input value may be up to 2^256-1; on output, value + * fits on 256 bits and is lower than twice the modulus. + */ +static void +f255_square(uint32_t *d, const uint32_t *a) +{ + uint32_t t[18], cc; + int i; + + /* + * Compute raw squaring. All result words fit in 30 bits + * each; upper word (t[17]) must fit on 2 bits, since the square + * of a 256-bit integers must fit on 512 bits. + */ + square9(t, a); + + /* + * Modular reduction: each high word is added where necessary. + * See f255_mul() for details on the reduction and carry limits. + */ + cc = MUL15(t[8] >> 15, 19); + t[8] &= 0x7FFF; + for (i = 0; i < 9; i ++) { + uint64_t w; + + w = (uint64_t)t[i] + (uint64_t)cc + MUL31(t[i + 9], 622592); + t[i] = (uint32_t)w & 0x3FFFFFFF; + cc = (uint32_t)(w >> 30); + } + cc = MUL15(t[8] >> 15, 19); + t[8] &= 0x7FFF; + for (i = 0; i < 9; i ++) { + uint32_t z; + + z = t[i] + cc; + d[i] = z & 0x3FFFFFFF; + cc = z >> 30; + } +} + +/* + * Add two values in F255. Partial reduction is performed (down to less + * than twice the modulus). + */ +static void +f255_add(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + /* + * Since operand words fit on 30 bits, we can use 32-bit + * variables throughout. + */ + int i; + uint32_t cc, w; + + cc = 0; + for (i = 0; i < 9; i ++) { + w = a[i] + b[i] + cc; + d[i] = w & 0x3FFFFFFF; + cc = w >> 30; + } + cc = MUL15(w >> 15, 19); + d[8] &= 0x7FFF; + for (i = 0; i < 9; i ++) { + w = d[i] + cc; + d[i] = w & 0x3FFFFFFF; + cc = w >> 30; + } +} + +/* + * Subtract one value from another in F255. Partial reduction is + * performed (down to less than twice the modulus). + */ +static void +f255_sub(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + /* + * We actually compute a - b + 2*p, so that the final value is + * necessarily positive. + */ + int i; + uint32_t cc, w; + + cc = (uint32_t)-38; + for (i = 0; i < 9; i ++) { + w = a[i] - b[i] + cc; + d[i] = w & 0x3FFFFFFF; + cc = ARSH(w, 30); + } + cc = MUL15((w + 0x10000) >> 15, 19); + d[8] &= 0x7FFF; + for (i = 0; i < 9; i ++) { + w = d[i] + cc; + d[i] = w & 0x3FFFFFFF; + cc = w >> 30; + } +} + +/* + * Multiply an integer by the 'A24' constant (121665). Partial reduction + * is performed (down to less than twice the modulus). + */ +static void +f255_mul_a24(uint32_t *d, const uint32_t *a) +{ + int i; + uint64_t w; + uint32_t cc; + + /* + * a[] is over 256 bits, thus a[8] has length at most 16 bits. + * We single out the processing of the last word: intermediate + * value w is up to 121665*2^16, yielding a carry for the next + * loop of at most 19*(121665*2^16/2^15) = 4623289. + */ + cc = 0; + for (i = 0; i < 8; i ++) { + w = MUL31(a[i], 121665) + (uint64_t)cc; + d[i] = (uint32_t)w & 0x3FFFFFFF; + cc = (uint32_t)(w >> 30); + } + w = MUL31(a[8], 121665) + (uint64_t)cc; + d[8] = (uint32_t)w & 0x7FFF; + cc = MUL15((uint32_t)(w >> 15), 19); + + for (i = 0; i < 9; i ++) { + uint32_t z; + + z = d[i] + cc; + d[i] = z & 0x3FFFFFFF; + cc = z >> 30; + } +} + +static const unsigned char GEN[] = { + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const unsigned char ORDER[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return GEN; +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return ORDER; +} + +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 0; +} + +static void +cswap(uint32_t *a, uint32_t *b, uint32_t ctl) +{ + int i; + + ctl = -ctl; + for (i = 0; i < 9; i ++) { + uint32_t aw, bw, tw; + + aw = a[i]; + bw = b[i]; + tw = ctl & (aw ^ bw); + a[i] = aw ^ tw; + b[i] = bw ^ tw; + } +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *kb, size_t kblen, int curve) +{ + uint32_t x1[9], x2[9], x3[9], z2[9], z3[9]; + uint32_t a[9], aa[9], b[9], bb[9]; + uint32_t c[9], d[9], e[9], da[9], cb[9]; + unsigned char k[32]; + uint32_t swap; + int i; + + (void)curve; + + /* + * Points are encoded over exactly 32 bytes. Multipliers must fit + * in 32 bytes as well. + * RFC 7748 mandates that the high bit of the last point byte must + * be ignored/cleared. + */ + if (Glen != 32 || kblen > 32) { + return 0; + } + G[31] &= 0x7F; + + /* + * Initialise variables x1, x2, z2, x3 and z3. We set all of them + * into Montgomery representation. + */ + x1[8] = le8_to_le30(x1, G, 32); + memcpy(x3, x1, sizeof x1); + memset(z2, 0, sizeof z2); + memset(x2, 0, sizeof x2); + x2[0] = 1; + memset(z3, 0, sizeof z3); + z3[0] = 1; + + memset(k, 0, (sizeof k) - kblen); + memcpy(k + (sizeof k) - kblen, kb, kblen); + k[31] &= 0xF8; + k[0] &= 0x7F; + k[0] |= 0x40; + + /* obsolete + print_int("x1", x1); + */ + + swap = 0; + for (i = 254; i >= 0; i --) { + uint32_t kt; + + kt = (k[31 - (i >> 3)] >> (i & 7)) & 1; + swap ^= kt; + cswap(x2, x3, swap); + cswap(z2, z3, swap); + swap = kt; + + /* obsolete + print_int("x2", x2); + print_int("z2", z2); + print_int("x3", x3); + print_int("z3", z3); + */ + + f255_add(a, x2, z2); + f255_square(aa, a); + f255_sub(b, x2, z2); + f255_square(bb, b); + f255_sub(e, aa, bb); + f255_add(c, x3, z3); + f255_sub(d, x3, z3); + f255_mul(da, d, a); + f255_mul(cb, c, b); + + /* obsolete + print_int("a ", a); + print_int("aa", aa); + print_int("b ", b); + print_int("bb", bb); + print_int("e ", e); + print_int("c ", c); + print_int("d ", d); + print_int("da", da); + print_int("cb", cb); + */ + + f255_add(x3, da, cb); + f255_square(x3, x3); + f255_sub(z3, da, cb); + f255_square(z3, z3); + f255_mul(z3, z3, x1); + f255_mul(x2, aa, bb); + f255_mul_a24(z2, e); + f255_add(z2, z2, aa); + f255_mul(z2, e, z2); + + /* obsolete + print_int("x2", x2); + print_int("z2", z2); + print_int("x3", x3); + print_int("z3", z3); + */ + } + cswap(x2, x3, swap); + cswap(z2, z3, swap); + + /* + * Inverse z2 with a modular exponentiation. This is a simple + * square-and-multiply algorithm; we mutualise most non-squarings + * since the exponent contains almost only ones. + */ + memcpy(a, z2, sizeof z2); + for (i = 0; i < 15; i ++) { + f255_square(a, a); + f255_mul(a, a, z2); + } + memcpy(b, a, sizeof a); + for (i = 0; i < 14; i ++) { + int j; + + for (j = 0; j < 16; j ++) { + f255_square(b, b); + } + f255_mul(b, b, a); + } + for (i = 14; i >= 0; i --) { + f255_square(b, b); + if ((0xFFEB >> i) & 1) { + f255_mul(b, z2, b); + } + } + f255_mul(x2, x2, b); + reduce_final_f255(x2); + le30_to_le8(G, 32, x2); + return 1; +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + const unsigned char *G; + size_t Glen; + + G = api_generator(curve, &Glen); + memcpy(R, G, Glen); + api_mul(R, Glen, x, xlen, curve); + return Glen; +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + /* + * We don't implement this method, since it is used for ECDSA + * only, and there is no ECDSA over Curve25519 (which instead + * uses EdDSA). + */ + (void)A; + (void)B; + (void)len; + (void)x; + (void)xlen; + (void)y; + (void)ylen; + (void)curve; + return 0; +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_c25519_m31 = { + (uint32_t)0x20000000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_c25519_m62.c b/BearSSL-OG/libbearssl/src/ec/ec_c25519_m62.c new file mode 100644 index 0000000..6b058eb --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_c25519_m62.c @@ -0,0 +1,605 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +#if BR_UMUL128 +#include +#endif + +static const unsigned char GEN[] = { + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const unsigned char ORDER[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return GEN; +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return ORDER; +} + +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 0; +} + +/* + * A field element is encoded as five 64-bit integers, in basis 2^51. + * Limbs may be occasionally larger than 2^51, to save on carry + * propagation costs. + */ + +#define MASK51 (((uint64_t)1 << 51) - (uint64_t)1) + +/* + * Swap two field elements, conditionally on a flag. + */ +static inline void +f255_cswap(uint64_t *a, uint64_t *b, uint32_t ctl) +{ + uint64_t m, w; + + m = -(uint64_t)ctl; + w = m & (a[0] ^ b[0]); a[0] ^= w; b[0] ^= w; + w = m & (a[1] ^ b[1]); a[1] ^= w; b[1] ^= w; + w = m & (a[2] ^ b[2]); a[2] ^= w; b[2] ^= w; + w = m & (a[3] ^ b[3]); a[3] ^= w; b[3] ^= w; + w = m & (a[4] ^ b[4]); a[4] ^= w; b[4] ^= w; +} + +/* + * Addition with no carry propagation. Limbs double in size. + */ +static inline void +f255_add(uint64_t *d, const uint64_t *a, const uint64_t *b) +{ + d[0] = a[0] + b[0]; + d[1] = a[1] + b[1]; + d[2] = a[2] + b[2]; + d[3] = a[3] + b[3]; + d[4] = a[4] + b[4]; +} + +/* + * Subtraction. + * On input, limbs must fit on 60 bits each. On output, result is + * partially reduced, with max value 2^255+19456; moreover, all + * limbs will fit on 51 bits, except the low limb, which may have + * value up to 2^51+19455. + */ +static inline void +f255_sub(uint64_t *d, const uint64_t *a, const uint64_t *b) +{ + uint64_t cc, w; + + /* + * We compute d = (2^255-19)*1024 + a - b. Since the limbs + * fit on 60 bits, the maximum value of operands are slightly + * more than 2^264, but much less than 2^265-19456. This + * ensures that the result is positive. + */ + + /* + * Initial carry is 19456, since we add 2^265-19456. Each + * individual subtraction may yield a carry up to 513. + */ + w = a[0] - b[0] - 19456; + d[0] = w & MASK51; + cc = -(w >> 51) & 0x3FF; + w = a[1] - b[1] - cc; + d[1] = w & MASK51; + cc = -(w >> 51) & 0x3FF; + w = a[2] - b[2] - cc; + d[2] = w & MASK51; + cc = -(w >> 51) & 0x3FF; + w = a[3] - b[3] - cc; + d[3] = w & MASK51; + cc = -(w >> 51) & 0x3FF; + d[4] = ((uint64_t)1 << 61) + a[4] - b[4] - cc; + + /* + * Partial reduction. The intermediate result may be up to + * slightly above 2^265, but less than 2^265+2^255. When we + * truncate to 255 bits, the upper bits will be at most 1024. + */ + d[0] += 19 * (d[4] >> 51); + d[4] &= MASK51; +} + +/* + * UMUL51(hi, lo, x, y) computes: + * + * hi = floor((x * y) / (2^51)) + * lo = x * y mod 2^51 + * + * Note that lo < 2^51, but "hi" may be larger, if the input operands are + * larger. + */ +#if BR_INT128 + +#define UMUL51(hi, lo, x, y) do { \ + unsigned __int128 umul_tmp; \ + umul_tmp = (unsigned __int128)(x) * (unsigned __int128)(y); \ + (hi) = (uint64_t)(umul_tmp >> 51); \ + (lo) = (uint64_t)umul_tmp & MASK51; \ + } while (0) + +#elif BR_UMUL128 + +#define UMUL51(hi, lo, x, y) do { \ + uint64_t umul_hi, umul_lo; \ + umul_lo = _umul128((x), (y), &umul_hi); \ + (hi) = (umul_hi << 13) | (umul_lo >> 51); \ + (lo) = umul_lo & MASK51; \ + } while (0) + +#endif + +/* + * Multiplication. + * On input, limbs must fit on 54 bits each. + * On output, limb 0 is at most 2^51 + 155647, and other limbs fit + * on 51 bits each. + */ +static inline void +f255_mul(uint64_t *d, uint64_t *a, uint64_t *b) +{ + uint64_t t[10], hi, lo, w, cc; + + /* + * Perform cross products, accumulating values without carry + * propagation. + * + * Since input limbs fit on 54 bits each, each individual + * UMUL51 will produce a "hi" of less than 2^57. The maximum + * sum will be at most 5*(2^57-1) + 4*(2^51-1) (for t[5]), + * i.e. less than 324*2^51. + */ + + UMUL51(t[1], t[0], a[0], b[0]); + + UMUL51(t[2], lo, a[1], b[0]); t[1] += lo; + UMUL51(hi, lo, a[0], b[1]); t[1] += lo; t[2] += hi; + + UMUL51(t[3], lo, a[2], b[0]); t[2] += lo; + UMUL51(hi, lo, a[1], b[1]); t[2] += lo; t[3] += hi; + UMUL51(hi, lo, a[0], b[2]); t[2] += lo; t[3] += hi; + + UMUL51(t[4], lo, a[3], b[0]); t[3] += lo; + UMUL51(hi, lo, a[2], b[1]); t[3] += lo; t[4] += hi; + UMUL51(hi, lo, a[1], b[2]); t[3] += lo; t[4] += hi; + UMUL51(hi, lo, a[0], b[3]); t[3] += lo; t[4] += hi; + + UMUL51(t[5], lo, a[4], b[0]); t[4] += lo; + UMUL51(hi, lo, a[3], b[1]); t[4] += lo; t[5] += hi; + UMUL51(hi, lo, a[2], b[2]); t[4] += lo; t[5] += hi; + UMUL51(hi, lo, a[1], b[3]); t[4] += lo; t[5] += hi; + UMUL51(hi, lo, a[0], b[4]); t[4] += lo; t[5] += hi; + + UMUL51(t[6], lo, a[4], b[1]); t[5] += lo; + UMUL51(hi, lo, a[3], b[2]); t[5] += lo; t[6] += hi; + UMUL51(hi, lo, a[2], b[3]); t[5] += lo; t[6] += hi; + UMUL51(hi, lo, a[1], b[4]); t[5] += lo; t[6] += hi; + + UMUL51(t[7], lo, a[4], b[2]); t[6] += lo; + UMUL51(hi, lo, a[3], b[3]); t[6] += lo; t[7] += hi; + UMUL51(hi, lo, a[2], b[4]); t[6] += lo; t[7] += hi; + + UMUL51(t[8], lo, a[4], b[3]); t[7] += lo; + UMUL51(hi, lo, a[3], b[4]); t[7] += lo; t[8] += hi; + + UMUL51(t[9], lo, a[4], b[4]); t[8] += lo; + + /* + * The upper words t[5]..t[9] are folded back into the lower + * words, using the rule that 2^255 = 19 in the field. + * + * Since each t[i] is less than 324*2^51, the additions below + * will yield less than 6480*2^51 in each limb; this fits in + * 64 bits (6480*2^51 < 8192*2^51 = 2^64), hence there is + * no overflow. + */ + t[0] += 19 * t[5]; + t[1] += 19 * t[6]; + t[2] += 19 * t[7]; + t[3] += 19 * t[8]; + t[4] += 19 * t[9]; + + /* + * Propagate carries. + */ + w = t[0]; + d[0] = w & MASK51; + cc = w >> 51; + w = t[1] + cc; + d[1] = w & MASK51; + cc = w >> 51; + w = t[2] + cc; + d[2] = w & MASK51; + cc = w >> 51; + w = t[3] + cc; + d[3] = w & MASK51; + cc = w >> 51; + w = t[4] + cc; + d[4] = w & MASK51; + cc = w >> 51; + + /* + * Since the limbs were 64-bit values, the top carry is at + * most 8192 (in practice, that cannot be reached). We simply + * performed a partial reduction. + */ + d[0] += 19 * cc; +} + +/* + * Multiplication by A24 = 121665. + * Input must have limbs of 60 bits at most. + */ +static inline void +f255_mul_a24(uint64_t *d, const uint64_t *a) +{ + uint64_t t[5], cc, w; + + /* + * 121665 = 15 * 8111. We first multiply by 15, with carry + * propagation and partial reduction. + */ + w = a[0] * 15; + t[0] = w & MASK51; + cc = w >> 51; + w = a[1] * 15 + cc; + t[1] = w & MASK51; + cc = w >> 51; + w = a[2] * 15 + cc; + t[2] = w & MASK51; + cc = w >> 51; + w = a[3] * 15 + cc; + t[3] = w & MASK51; + cc = w >> 51; + w = a[4] * 15 + cc; + t[4] = w & MASK51; + t[0] += 19 * (w >> 51); + + /* + * Then multiplication by 8111. At that point, we known that + * t[0] is less than 2^51 + 19*8192, and other limbs are less + * than 2^51; thus, there will be no overflow. + */ + w = t[0] * 8111; + d[0] = w & MASK51; + cc = w >> 51; + w = t[1] * 8111 + cc; + d[1] = w & MASK51; + cc = w >> 51; + w = t[2] * 8111 + cc; + d[2] = w & MASK51; + cc = w >> 51; + w = t[3] * 8111 + cc; + d[3] = w & MASK51; + cc = w >> 51; + w = t[4] * 8111 + cc; + d[4] = w & MASK51; + d[0] += 19 * (w >> 51); +} + +/* + * Finalize reduction. + * On input, limbs must fit on 51 bits, except possibly the low limb, + * which may be slightly above 2^51. + */ +static inline void +f255_final_reduce(uint64_t *a) +{ + uint64_t t[5], cc, w; + + /* + * We add 19. If the result (in t[]) is below 2^255, then a[] + * is already less than 2^255-19, thus already reduced. + * Otherwise, we subtract 2^255 from t[], in which case we + * have t = a - (2^255-19), and that's our result. + */ + w = a[0] + 19; + t[0] = w & MASK51; + cc = w >> 51; + w = a[1] + cc; + t[1] = w & MASK51; + cc = w >> 51; + w = a[2] + cc; + t[2] = w & MASK51; + cc = w >> 51; + w = a[3] + cc; + t[3] = w & MASK51; + cc = w >> 51; + w = a[4] + cc; + t[4] = w & MASK51; + cc = w >> 51; + + /* + * The bit 255 of t is in cc. If that bit is 0, when a[] must + * be unchanged; otherwise, it must be replaced with t[]. + */ + cc = -cc; + a[0] ^= cc & (a[0] ^ t[0]); + a[1] ^= cc & (a[1] ^ t[1]); + a[2] ^= cc & (a[2] ^ t[2]); + a[3] ^= cc & (a[3] ^ t[3]); + a[4] ^= cc & (a[4] ^ t[4]); +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *kb, size_t kblen, int curve) +{ + unsigned char k[32]; + uint64_t x1[5], x2[5], z2[5], x3[5], z3[5]; + uint32_t swap; + int i; + + (void)curve; + + /* + * Points are encoded over exactly 32 bytes. Multipliers must fit + * in 32 bytes as well. + */ + if (Glen != 32 || kblen > 32) { + return 0; + } + + /* + * RFC 7748 mandates that the high bit of the last point byte must + * be ignored/cleared; the "& MASK51" in the initialization for + * x1[4] clears that bit. + */ + x1[0] = br_dec64le(&G[0]) & MASK51; + x1[1] = (br_dec64le(&G[6]) >> 3) & MASK51; + x1[2] = (br_dec64le(&G[12]) >> 6) & MASK51; + x1[3] = (br_dec64le(&G[19]) >> 1) & MASK51; + x1[4] = (br_dec64le(&G[24]) >> 12) & MASK51; + + /* + * We can use memset() to clear values, because exact-width types + * like uint64_t are guaranteed to have no padding bits or + * trap representations. + */ + memset(x2, 0, sizeof x2); + x2[0] = 1; + memset(z2, 0, sizeof z2); + memcpy(x3, x1, sizeof x1); + memcpy(z3, x2, sizeof x2); + + /* + * The multiplier is provided in big-endian notation, and + * possibly shorter than 32 bytes. + */ + memset(k, 0, (sizeof k) - kblen); + memcpy(k + (sizeof k) - kblen, kb, kblen); + k[31] &= 0xF8; + k[0] &= 0x7F; + k[0] |= 0x40; + + swap = 0; + + for (i = 254; i >= 0; i --) { + uint64_t a[5], aa[5], b[5], bb[5], e[5]; + uint64_t c[5], d[5], da[5], cb[5]; + uint32_t kt; + + kt = (k[31 - (i >> 3)] >> (i & 7)) & 1; + swap ^= kt; + f255_cswap(x2, x3, swap); + f255_cswap(z2, z3, swap); + swap = kt; + + /* + * At that point, limbs of x_2 and z_2 are assumed to fit + * on at most 52 bits each. + * + * Each f255_add() adds one bit to the maximum range of + * the values, but f255_sub() and f255_mul() bring back + * the limbs into 52 bits. All f255_add() outputs are + * used only as inputs for f255_mul(), which ensures + * that limbs remain in the proper range. + */ + + /* A = x_2 + z_2 -- limbs fit on 53 bits each */ + f255_add(a, x2, z2); + + /* AA = A^2 */ + f255_mul(aa, a, a); + + /* B = x_2 - z_2 */ + f255_sub(b, x2, z2); + + /* BB = B^2 */ + f255_mul(bb, b, b); + + /* E = AA - BB */ + f255_sub(e, aa, bb); + + /* C = x_3 + z_3 -- limbs fit on 53 bits each */ + f255_add(c, x3, z3); + + /* D = x_3 - z_3 */ + f255_sub(d, x3, z3); + + /* DA = D * A */ + f255_mul(da, d, a); + + /* CB = C * B */ + f255_mul(cb, c, b); + + /* x_3 = (DA + CB)^2 */ + f255_add(x3, da, cb); + f255_mul(x3, x3, x3); + + /* z_3 = x_1 * (DA - CB)^2 */ + f255_sub(z3, da, cb); + f255_mul(z3, z3, z3); + f255_mul(z3, x1, z3); + + /* x_2 = AA * BB */ + f255_mul(x2, aa, bb); + + /* z_2 = E * (AA + a24 * E) */ + f255_mul_a24(z2, e); + f255_add(z2, aa, z2); + f255_mul(z2, e, z2); + } + + f255_cswap(x2, x3, swap); + f255_cswap(z2, z3, swap); + + /* + * Compute 1/z2 = z2^(p-2). Since p = 2^255-19, we can mutualize + * most non-squarings. We use x1 and x3, now useless, as temporaries. + */ + memcpy(x1, z2, sizeof z2); + for (i = 0; i < 15; i ++) { + f255_mul(x1, x1, x1); + f255_mul(x1, x1, z2); + } + memcpy(x3, x1, sizeof x1); + for (i = 0; i < 14; i ++) { + int j; + + for (j = 0; j < 16; j ++) { + f255_mul(x3, x3, x3); + } + f255_mul(x3, x3, x1); + } + for (i = 14; i >= 0; i --) { + f255_mul(x3, x3, x3); + if ((0xFFEB >> i) & 1) { + f255_mul(x3, z2, x3); + } + } + + /* + * Compute x2/z2. We have 1/z2 in x3. + */ + f255_mul(x2, x2, x3); + f255_final_reduce(x2); + + /* + * Encode the final x2 value in little-endian. We first assemble + * the limbs into 64-bit values. + */ + x2[0] |= x2[1] << 51; + x2[1] = (x2[1] >> 13) | (x2[2] << 38); + x2[2] = (x2[2] >> 26) | (x2[3] << 25); + x2[3] = (x2[3] >> 39) | (x2[4] << 12); + br_enc64le(G, x2[0]); + br_enc64le(G + 8, x2[1]); + br_enc64le(G + 16, x2[2]); + br_enc64le(G + 24, x2[3]); + return 1; +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + const unsigned char *G; + size_t Glen; + + G = api_generator(curve, &Glen); + memcpy(R, G, Glen); + api_mul(R, Glen, x, xlen, curve); + return Glen; +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + /* + * We don't implement this method, since it is used for ECDSA + * only, and there is no ECDSA over Curve25519 (which instead + * uses EdDSA). + */ + (void)A; + (void)B; + (void)len; + (void)x; + (void)xlen; + (void)y; + (void)ylen; + (void)curve; + return 0; +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_c25519_m62 = { + (uint32_t)0x20000000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; + +/* see bearssl_ec.h */ +const br_ec_impl * +br_ec_c25519_m62_get(void) +{ + return &br_ec_c25519_m62; +} + +#else + +/* see bearssl_ec.h */ +const br_ec_impl * +br_ec_c25519_m62_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/ec/ec_c25519_m64.c b/BearSSL-OG/libbearssl/src/ec/ec_c25519_m64.c new file mode 100644 index 0000000..df48834 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_c25519_m64.c @@ -0,0 +1,831 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +#if BR_UMUL128 +#include +#endif + +static const unsigned char GEN[] = { + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const unsigned char ORDER[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return GEN; +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return ORDER; +} + +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 0; +} + +/* + * A field element is encoded as four 64-bit integers, in basis 2^63. + * Operations return partially reduced values, which may range up to + * 2^255+37. + */ + +#define MASK63 (((uint64_t)1 << 63) - (uint64_t)1) + +/* + * Swap two field elements, conditionally on a flag. + */ +static inline void +f255_cswap(uint64_t *a, uint64_t *b, uint32_t ctl) +{ + uint64_t m, w; + + m = -(uint64_t)ctl; + w = m & (a[0] ^ b[0]); a[0] ^= w; b[0] ^= w; + w = m & (a[1] ^ b[1]); a[1] ^= w; b[1] ^= w; + w = m & (a[2] ^ b[2]); a[2] ^= w; b[2] ^= w; + w = m & (a[3] ^ b[3]); a[3] ^= w; b[3] ^= w; +} + +/* + * Addition in the field. + */ +static inline void +f255_add(uint64_t *d, const uint64_t *a, const uint64_t *b) +{ +#if BR_INT128 + + uint64_t t0, t1, t2, t3, cc; + unsigned __int128 z; + + z = (unsigned __int128)a[0] + (unsigned __int128)b[0]; + t0 = (uint64_t)z; + z = (unsigned __int128)a[1] + (unsigned __int128)b[1] + (z >> 64); + t1 = (uint64_t)z; + z = (unsigned __int128)a[2] + (unsigned __int128)b[2] + (z >> 64); + t2 = (uint64_t)z; + z = (unsigned __int128)a[3] + (unsigned __int128)b[3] + (z >> 64); + t3 = (uint64_t)z & MASK63; + cc = (uint64_t)(z >> 63); + + /* + * Since operands are at most 2^255+37, the sum is at most + * 2^256+74; thus, the carry cc is equal to 0, 1 or 2. + * + * We use: 2^255 = 19 mod p. + * Since we add 0, 19 or 38 to a value that fits on 255 bits, + * the result is at most 2^255+37. + */ + z = (unsigned __int128)t0 + (unsigned __int128)(19 * cc); + d[0] = (uint64_t)z; + z = (unsigned __int128)t1 + (z >> 64); + d[1] = (uint64_t)z; + z = (unsigned __int128)t2 + (z >> 64); + d[2] = (uint64_t)z; + d[3] = t3 + (uint64_t)(z >> 64); + +#elif BR_UMUL128 + + uint64_t t0, t1, t2, t3, cc; + unsigned char k; + + k = _addcarry_u64(0, a[0], b[0], &t0); + k = _addcarry_u64(k, a[1], b[1], &t1); + k = _addcarry_u64(k, a[2], b[2], &t2); + k = _addcarry_u64(k, a[3], b[3], &t3); + cc = (k << 1) + (t3 >> 63); + t3 &= MASK63; + + /* + * Since operands are at most 2^255+37, the sum is at most + * 2^256+74; thus, the carry cc is equal to 0, 1 or 2. + * + * We use: 2^255 = 19 mod p. + * Since we add 0, 19 or 38 to a value that fits on 255 bits, + * the result is at most 2^255+37. + */ + k = _addcarry_u64(0, t0, 19 * cc, &d[0]); + k = _addcarry_u64(k, t1, 0, &d[1]); + k = _addcarry_u64(k, t2, 0, &d[2]); + (void)_addcarry_u64(k, t3, 0, &d[3]); + +#endif +} + +/* + * Subtraction. + */ +static inline void +f255_sub(uint64_t *d, const uint64_t *a, const uint64_t *b) +{ +#if BR_INT128 + + /* + * We compute t = 2^256 - 38 + a - b, which is necessarily + * positive but lower than 2^256 + 2^255, since a <= 2^255 + 37 + * and b <= 2^255 + 37. We then subtract 0, p or 2*p, depending + * on the two upper bits of t (bits 255 and 256). + */ + + uint64_t t0, t1, t2, t3, t4, cc; + unsigned __int128 z; + + z = (unsigned __int128)a[0] - (unsigned __int128)b[0] - 38; + t0 = (uint64_t)z; + cc = -(uint64_t)(z >> 64); + z = (unsigned __int128)a[1] - (unsigned __int128)b[1] + - (unsigned __int128)cc; + t1 = (uint64_t)z; + cc = -(uint64_t)(z >> 64); + z = (unsigned __int128)a[2] - (unsigned __int128)b[2] + - (unsigned __int128)cc; + t2 = (uint64_t)z; + cc = -(uint64_t)(z >> 64); + z = (unsigned __int128)a[3] - (unsigned __int128)b[3] + - (unsigned __int128)cc; + t3 = (uint64_t)z; + t4 = 1 + (uint64_t)(z >> 64); + + /* + * We have a 257-bit result. The two top bits can be 00, 01 or 10, + * but not 11 (value t <= 2^256 - 38 + 2^255 + 37 = 2^256 + 2^255 - 1). + * Therefore, we can truncate to 255 bits, and add 0, 19 or 38. + * This guarantees that the result is at most 2^255+37. + */ + cc = (38 & -t4) + (19 & -(t3 >> 63)); + t3 &= MASK63; + z = (unsigned __int128)t0 + (unsigned __int128)cc; + d[0] = (uint64_t)z; + z = (unsigned __int128)t1 + (z >> 64); + d[1] = (uint64_t)z; + z = (unsigned __int128)t2 + (z >> 64); + d[2] = (uint64_t)z; + d[3] = t3 + (uint64_t)(z >> 64); + +#elif BR_UMUL128 + + /* + * We compute t = 2^256 - 38 + a - b, which is necessarily + * positive but lower than 2^256 + 2^255, since a <= 2^255 + 37 + * and b <= 2^255 + 37. We then subtract 0, p or 2*p, depending + * on the two upper bits of t (bits 255 and 256). + */ + + uint64_t t0, t1, t2, t3, t4; + unsigned char k; + + k = _subborrow_u64(0, a[0], b[0], &t0); + k = _subborrow_u64(k, a[1], b[1], &t1); + k = _subborrow_u64(k, a[2], b[2], &t2); + k = _subborrow_u64(k, a[3], b[3], &t3); + (void)_subborrow_u64(k, 1, 0, &t4); + + k = _subborrow_u64(0, t0, 38, &t0); + k = _subborrow_u64(k, t1, 0, &t1); + k = _subborrow_u64(k, t2, 0, &t2); + k = _subborrow_u64(k, t3, 0, &t3); + (void)_subborrow_u64(k, t4, 0, &t4); + + /* + * We have a 257-bit result. The two top bits can be 00, 01 or 10, + * but not 11 (value t <= 2^256 - 38 + 2^255 + 37 = 2^256 + 2^255 - 1). + * Therefore, we can truncate to 255 bits, and add 0, 19 or 38. + * This guarantees that the result is at most 2^255+37. + */ + t4 = (38 & -t4) + (19 & -(t3 >> 63)); + t3 &= MASK63; + k = _addcarry_u64(0, t0, t4, &d[0]); + k = _addcarry_u64(k, t1, 0, &d[1]); + k = _addcarry_u64(k, t2, 0, &d[2]); + (void)_addcarry_u64(k, t3, 0, &d[3]); + +#endif +} + +/* + * Multiplication. + */ +static inline void +f255_mul(uint64_t *d, uint64_t *a, uint64_t *b) +{ +#if BR_INT128 + + unsigned __int128 z; + uint64_t t0, t1, t2, t3, t4, t5, t6, t7, th; + + /* + * Compute the product a*b over plain integers. + */ + z = (unsigned __int128)a[0] * (unsigned __int128)b[0]; + t0 = (uint64_t)z; + z = (unsigned __int128)a[0] * (unsigned __int128)b[1] + (z >> 64); + t1 = (uint64_t)z; + z = (unsigned __int128)a[0] * (unsigned __int128)b[2] + (z >> 64); + t2 = (uint64_t)z; + z = (unsigned __int128)a[0] * (unsigned __int128)b[3] + (z >> 64); + t3 = (uint64_t)z; + t4 = (uint64_t)(z >> 64); + + z = (unsigned __int128)a[1] * (unsigned __int128)b[0] + + (unsigned __int128)t1; + t1 = (uint64_t)z; + z = (unsigned __int128)a[1] * (unsigned __int128)b[1] + + (unsigned __int128)t2 + (z >> 64); + t2 = (uint64_t)z; + z = (unsigned __int128)a[1] * (unsigned __int128)b[2] + + (unsigned __int128)t3 + (z >> 64); + t3 = (uint64_t)z; + z = (unsigned __int128)a[1] * (unsigned __int128)b[3] + + (unsigned __int128)t4 + (z >> 64); + t4 = (uint64_t)z; + t5 = (uint64_t)(z >> 64); + + z = (unsigned __int128)a[2] * (unsigned __int128)b[0] + + (unsigned __int128)t2; + t2 = (uint64_t)z; + z = (unsigned __int128)a[2] * (unsigned __int128)b[1] + + (unsigned __int128)t3 + (z >> 64); + t3 = (uint64_t)z; + z = (unsigned __int128)a[2] * (unsigned __int128)b[2] + + (unsigned __int128)t4 + (z >> 64); + t4 = (uint64_t)z; + z = (unsigned __int128)a[2] * (unsigned __int128)b[3] + + (unsigned __int128)t5 + (z >> 64); + t5 = (uint64_t)z; + t6 = (uint64_t)(z >> 64); + + z = (unsigned __int128)a[3] * (unsigned __int128)b[0] + + (unsigned __int128)t3; + t3 = (uint64_t)z; + z = (unsigned __int128)a[3] * (unsigned __int128)b[1] + + (unsigned __int128)t4 + (z >> 64); + t4 = (uint64_t)z; + z = (unsigned __int128)a[3] * (unsigned __int128)b[2] + + (unsigned __int128)t5 + (z >> 64); + t5 = (uint64_t)z; + z = (unsigned __int128)a[3] * (unsigned __int128)b[3] + + (unsigned __int128)t6 + (z >> 64); + t6 = (uint64_t)z; + t7 = (uint64_t)(z >> 64); + + /* + * Modulo p, we have: + * + * 2^255 = 19 + * 2^510 = 19*19 = 361 + * + * We split the intermediate t into three parts, in basis + * 2^255. The low one will be in t0..t3; the middle one in t4..t7. + * The upper one can only be a single bit (th), since the + * multiplication operands are at most 2^255+37 each. + */ + th = t7 >> 62; + t7 = ((t7 << 1) | (t6 >> 63)) & MASK63; + t6 = (t6 << 1) | (t5 >> 63); + t5 = (t5 << 1) | (t4 >> 63); + t4 = (t4 << 1) | (t3 >> 63); + t3 &= MASK63; + + /* + * Multiply the middle part (t4..t7) by 19. We truncate it to + * 255 bits; the extra bits will go along with th. + */ + z = (unsigned __int128)t4 * 19; + t4 = (uint64_t)z; + z = (unsigned __int128)t5 * 19 + (z >> 64); + t5 = (uint64_t)z; + z = (unsigned __int128)t6 * 19 + (z >> 64); + t6 = (uint64_t)z; + z = (unsigned __int128)t7 * 19 + (z >> 64); + t7 = (uint64_t)z & MASK63; + + th = (361 & -th) + (19 * (uint64_t)(z >> 63)); + + /* + * Add elements together. + * At this point: + * t0..t3 fits on 255 bits. + * t4..t7 fits on 255 bits. + * th <= 361 + 342 = 703. + */ + z = (unsigned __int128)t0 + (unsigned __int128)t4 + + (unsigned __int128)th; + t0 = (uint64_t)z; + z = (unsigned __int128)t1 + (unsigned __int128)t5 + (z >> 64); + t1 = (uint64_t)z; + z = (unsigned __int128)t2 + (unsigned __int128)t6 + (z >> 64); + t2 = (uint64_t)z; + z = (unsigned __int128)t3 + (unsigned __int128)t7 + (z >> 64); + t3 = (uint64_t)z & MASK63; + th = (uint64_t)(z >> 63); + + /* + * Since the sum is at most 2^256 + 703, the two upper bits, in th, + * can only have value 0, 1 or 2. We just add th*19, which + * guarantees a result of at most 2^255+37. + */ + z = (unsigned __int128)t0 + (19 * th); + d[0] = (uint64_t)z; + z = (unsigned __int128)t1 + (z >> 64); + d[1] = (uint64_t)z; + z = (unsigned __int128)t2 + (z >> 64); + d[2] = (uint64_t)z; + d[3] = t3 + (uint64_t)(z >> 64); + +#elif BR_UMUL128 + + uint64_t t0, t1, t2, t3, t4, t5, t6, t7, th; + uint64_t h0, h1, h2, h3; + unsigned char k; + + /* + * Compute the product a*b over plain integers. + */ + t0 = _umul128(a[0], b[0], &h0); + t1 = _umul128(a[0], b[1], &h1); + k = _addcarry_u64(0, t1, h0, &t1); + t2 = _umul128(a[0], b[2], &h2); + k = _addcarry_u64(k, t2, h1, &t2); + t3 = _umul128(a[0], b[3], &h3); + k = _addcarry_u64(k, t3, h2, &t3); + (void)_addcarry_u64(k, h3, 0, &t4); + + k = _addcarry_u64(0, _umul128(a[1], b[0], &h0), t1, &t1); + k = _addcarry_u64(k, _umul128(a[1], b[1], &h1), t2, &t2); + k = _addcarry_u64(k, _umul128(a[1], b[2], &h2), t3, &t3); + k = _addcarry_u64(k, _umul128(a[1], b[3], &h3), t4, &t4); + t5 = k; + k = _addcarry_u64(0, t2, h0, &t2); + k = _addcarry_u64(k, t3, h1, &t3); + k = _addcarry_u64(k, t4, h2, &t4); + (void)_addcarry_u64(k, t5, h3, &t5); + + k = _addcarry_u64(0, _umul128(a[2], b[0], &h0), t2, &t2); + k = _addcarry_u64(k, _umul128(a[2], b[1], &h1), t3, &t3); + k = _addcarry_u64(k, _umul128(a[2], b[2], &h2), t4, &t4); + k = _addcarry_u64(k, _umul128(a[2], b[3], &h3), t5, &t5); + t6 = k; + k = _addcarry_u64(0, t3, h0, &t3); + k = _addcarry_u64(k, t4, h1, &t4); + k = _addcarry_u64(k, t5, h2, &t5); + (void)_addcarry_u64(k, t6, h3, &t6); + + k = _addcarry_u64(0, _umul128(a[3], b[0], &h0), t3, &t3); + k = _addcarry_u64(k, _umul128(a[3], b[1], &h1), t4, &t4); + k = _addcarry_u64(k, _umul128(a[3], b[2], &h2), t5, &t5); + k = _addcarry_u64(k, _umul128(a[3], b[3], &h3), t6, &t6); + t7 = k; + k = _addcarry_u64(0, t4, h0, &t4); + k = _addcarry_u64(k, t5, h1, &t5); + k = _addcarry_u64(k, t6, h2, &t6); + (void)_addcarry_u64(k, t7, h3, &t7); + + /* + * Modulo p, we have: + * + * 2^255 = 19 + * 2^510 = 19*19 = 361 + * + * We split the intermediate t into three parts, in basis + * 2^255. The low one will be in t0..t3; the middle one in t4..t7. + * The upper one can only be a single bit (th), since the + * multiplication operands are at most 2^255+37 each. + */ + th = t7 >> 62; + t7 = ((t7 << 1) | (t6 >> 63)) & MASK63; + t6 = (t6 << 1) | (t5 >> 63); + t5 = (t5 << 1) | (t4 >> 63); + t4 = (t4 << 1) | (t3 >> 63); + t3 &= MASK63; + + /* + * Multiply the middle part (t4..t7) by 19. We truncate it to + * 255 bits; the extra bits will go along with th. + */ + t4 = _umul128(t4, 19, &h0); + t5 = _umul128(t5, 19, &h1); + t6 = _umul128(t6, 19, &h2); + t7 = _umul128(t7, 19, &h3); + k = _addcarry_u64(0, t5, h0, &t5); + k = _addcarry_u64(k, t6, h1, &t6); + k = _addcarry_u64(k, t7, h2, &t7); + (void)_addcarry_u64(k, h3, 0, &h3); + th = (361 & -th) + (19 * ((h3 << 1) + (t7 >> 63))); + t7 &= MASK63; + + /* + * Add elements together. + * At this point: + * t0..t3 fits on 255 bits. + * t4..t7 fits on 255 bits. + * th <= 361 + 342 = 703. + */ + k = _addcarry_u64(0, t0, t4, &t0); + k = _addcarry_u64(k, t1, t5, &t1); + k = _addcarry_u64(k, t2, t6, &t2); + k = _addcarry_u64(k, t3, t7, &t3); + t4 = k; + k = _addcarry_u64(0, t0, th, &t0); + k = _addcarry_u64(k, t1, 0, &t1); + k = _addcarry_u64(k, t2, 0, &t2); + k = _addcarry_u64(k, t3, 0, &t3); + (void)_addcarry_u64(k, t4, 0, &t4); + + th = (t4 << 1) + (t3 >> 63); + t3 &= MASK63; + + /* + * Since the sum is at most 2^256 + 703, the two upper bits, in th, + * can only have value 0, 1 or 2. We just add th*19, which + * guarantees a result of at most 2^255+37. + */ + k = _addcarry_u64(0, t0, 19 * th, &d[0]); + k = _addcarry_u64(k, t1, 0, &d[1]); + k = _addcarry_u64(k, t2, 0, &d[2]); + (void)_addcarry_u64(k, t3, 0, &d[3]); + +#endif +} + +/* + * Multiplication by A24 = 121665. + */ +static inline void +f255_mul_a24(uint64_t *d, const uint64_t *a) +{ +#if BR_INT128 + + uint64_t t0, t1, t2, t3; + unsigned __int128 z; + + z = (unsigned __int128)a[0] * 121665; + t0 = (uint64_t)z; + z = (unsigned __int128)a[1] * 121665 + (z >> 64); + t1 = (uint64_t)z; + z = (unsigned __int128)a[2] * 121665 + (z >> 64); + t2 = (uint64_t)z; + z = (unsigned __int128)a[3] * 121665 + (z >> 64); + t3 = (uint64_t)z & MASK63; + + z = (unsigned __int128)t0 + (19 * (uint64_t)(z >> 63)); + t0 = (uint64_t)z; + z = (unsigned __int128)t1 + (z >> 64); + t1 = (uint64_t)z; + z = (unsigned __int128)t2 + (z >> 64); + t2 = (uint64_t)z; + t3 = t3 + (uint64_t)(z >> 64); + + z = (unsigned __int128)t0 + (19 & -(t3 >> 63)); + d[0] = (uint64_t)z; + z = (unsigned __int128)t1 + (z >> 64); + d[1] = (uint64_t)z; + z = (unsigned __int128)t2 + (z >> 64); + d[2] = (uint64_t)z; + d[3] = (t3 & MASK63) + (uint64_t)(z >> 64); + +#elif BR_UMUL128 + + uint64_t t0, t1, t2, t3, t4, h0, h1, h2, h3; + unsigned char k; + + t0 = _umul128(a[0], 121665, &h0); + t1 = _umul128(a[1], 121665, &h1); + k = _addcarry_u64(0, t1, h0, &t1); + t2 = _umul128(a[2], 121665, &h2); + k = _addcarry_u64(k, t2, h1, &t2); + t3 = _umul128(a[3], 121665, &h3); + k = _addcarry_u64(k, t3, h2, &t3); + (void)_addcarry_u64(k, h3, 0, &t4); + + t4 = (t4 << 1) + (t3 >> 63); + t3 &= MASK63; + k = _addcarry_u64(0, t0, 19 * t4, &t0); + k = _addcarry_u64(k, t1, 0, &t1); + k = _addcarry_u64(k, t2, 0, &t2); + (void)_addcarry_u64(k, t3, 0, &t3); + + t4 = 19 & -(t3 >> 63); + t3 &= MASK63; + k = _addcarry_u64(0, t0, t4, &d[0]); + k = _addcarry_u64(k, t1, 0, &d[1]); + k = _addcarry_u64(k, t2, 0, &d[2]); + (void)_addcarry_u64(k, t3, 0, &d[3]); + +#endif +} + +/* + * Finalize reduction. + */ +static inline void +f255_final_reduce(uint64_t *a) +{ +#if BR_INT128 + + uint64_t t0, t1, t2, t3, m; + unsigned __int128 z; + + /* + * We add 19. If the result (in t) is below 2^255, then a[] + * is already less than 2^255-19, thus already reduced. + * Otherwise, we subtract 2^255 from t[], in which case we + * have t = a - (2^255-19), and that's our result. + */ + z = (unsigned __int128)a[0] + 19; + t0 = (uint64_t)z; + z = (unsigned __int128)a[1] + (z >> 64); + t1 = (uint64_t)z; + z = (unsigned __int128)a[2] + (z >> 64); + t2 = (uint64_t)z; + t3 = a[3] + (uint64_t)(z >> 64); + + m = -(t3 >> 63); + t3 &= MASK63; + a[0] ^= m & (a[0] ^ t0); + a[1] ^= m & (a[1] ^ t1); + a[2] ^= m & (a[2] ^ t2); + a[3] ^= m & (a[3] ^ t3); + +#elif BR_UMUL128 + + uint64_t t0, t1, t2, t3, m; + unsigned char k; + + /* + * We add 19. If the result (in t) is below 2^255, then a[] + * is already less than 2^255-19, thus already reduced. + * Otherwise, we subtract 2^255 from t[], in which case we + * have t = a - (2^255-19), and that's our result. + */ + k = _addcarry_u64(0, a[0], 19, &t0); + k = _addcarry_u64(k, a[1], 0, &t1); + k = _addcarry_u64(k, a[2], 0, &t2); + (void)_addcarry_u64(k, a[3], 0, &t3); + + m = -(t3 >> 63); + t3 &= MASK63; + a[0] ^= m & (a[0] ^ t0); + a[1] ^= m & (a[1] ^ t1); + a[2] ^= m & (a[2] ^ t2); + a[3] ^= m & (a[3] ^ t3); + +#endif +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *kb, size_t kblen, int curve) +{ + unsigned char k[32]; + uint64_t x1[4], x2[4], z2[4], x3[4], z3[4]; + uint32_t swap; + int i; + + (void)curve; + + /* + * Points are encoded over exactly 32 bytes. Multipliers must fit + * in 32 bytes as well. + */ + if (Glen != 32 || kblen > 32) { + return 0; + } + + /* + * RFC 7748 mandates that the high bit of the last point byte must + * be ignored/cleared. + */ + x1[0] = br_dec64le(&G[ 0]); + x1[1] = br_dec64le(&G[ 8]); + x1[2] = br_dec64le(&G[16]); + x1[3] = br_dec64le(&G[24]) & MASK63; + + /* + * We can use memset() to clear values, because exact-width types + * like uint64_t are guaranteed to have no padding bits or + * trap representations. + */ + memset(x2, 0, sizeof x2); + x2[0] = 1; + memset(z2, 0, sizeof z2); + memcpy(x3, x1, sizeof x1); + memcpy(z3, x2, sizeof x2); + + /* + * The multiplier is provided in big-endian notation, and + * possibly shorter than 32 bytes. + */ + memset(k, 0, (sizeof k) - kblen); + memcpy(k + (sizeof k) - kblen, kb, kblen); + k[31] &= 0xF8; + k[0] &= 0x7F; + k[0] |= 0x40; + + swap = 0; + + for (i = 254; i >= 0; i --) { + uint64_t a[4], aa[4], b[4], bb[4], e[4]; + uint64_t c[4], d[4], da[4], cb[4]; + uint32_t kt; + + kt = (k[31 - (i >> 3)] >> (i & 7)) & 1; + swap ^= kt; + f255_cswap(x2, x3, swap); + f255_cswap(z2, z3, swap); + swap = kt; + + /* A = x_2 + z_2 */ + f255_add(a, x2, z2); + + /* AA = A^2 */ + f255_mul(aa, a, a); + + /* B = x_2 - z_2 */ + f255_sub(b, x2, z2); + + /* BB = B^2 */ + f255_mul(bb, b, b); + + /* E = AA - BB */ + f255_sub(e, aa, bb); + + /* C = x_3 + z_3 */ + f255_add(c, x3, z3); + + /* D = x_3 - z_3 */ + f255_sub(d, x3, z3); + + /* DA = D * A */ + f255_mul(da, d, a); + + /* CB = C * B */ + f255_mul(cb, c, b); + + /* x_3 = (DA + CB)^2 */ + f255_add(x3, da, cb); + f255_mul(x3, x3, x3); + + /* z_3 = x_1 * (DA - CB)^2 */ + f255_sub(z3, da, cb); + f255_mul(z3, z3, z3); + f255_mul(z3, x1, z3); + + /* x_2 = AA * BB */ + f255_mul(x2, aa, bb); + + /* z_2 = E * (AA + a24 * E) */ + f255_mul_a24(z2, e); + f255_add(z2, aa, z2); + f255_mul(z2, e, z2); + } + + f255_cswap(x2, x3, swap); + f255_cswap(z2, z3, swap); + + /* + * Compute 1/z2 = z2^(p-2). Since p = 2^255-19, we can mutualize + * most non-squarings. We use x1 and x3, now useless, as temporaries. + */ + memcpy(x1, z2, sizeof z2); + for (i = 0; i < 15; i ++) { + f255_mul(x1, x1, x1); + f255_mul(x1, x1, z2); + } + memcpy(x3, x1, sizeof x1); + for (i = 0; i < 14; i ++) { + int j; + + for (j = 0; j < 16; j ++) { + f255_mul(x3, x3, x3); + } + f255_mul(x3, x3, x1); + } + for (i = 14; i >= 0; i --) { + f255_mul(x3, x3, x3); + if ((0xFFEB >> i) & 1) { + f255_mul(x3, z2, x3); + } + } + + /* + * Compute x2/z2. We have 1/z2 in x3. + */ + f255_mul(x2, x2, x3); + f255_final_reduce(x2); + + /* + * Encode the final x2 value in little-endian. + */ + br_enc64le(G, x2[0]); + br_enc64le(G + 8, x2[1]); + br_enc64le(G + 16, x2[2]); + br_enc64le(G + 24, x2[3]); + return 1; +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + const unsigned char *G; + size_t Glen; + + G = api_generator(curve, &Glen); + memcpy(R, G, Glen); + api_mul(R, Glen, x, xlen, curve); + return Glen; +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + /* + * We don't implement this method, since it is used for ECDSA + * only, and there is no ECDSA over Curve25519 (which instead + * uses EdDSA). + */ + (void)A; + (void)B; + (void)len; + (void)x; + (void)xlen; + (void)y; + (void)ylen; + (void)curve; + return 0; +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_c25519_m64 = { + (uint32_t)0x20000000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; + +/* see bearssl_ec.h */ +const br_ec_impl * +br_ec_c25519_m64_get(void) +{ + return &br_ec_c25519_m64; +} + +#else + +/* see bearssl_ec.h */ +const br_ec_impl * +br_ec_c25519_m64_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/ec/ec_curve25519.c b/BearSSL-OG/libbearssl/src/ec/ec_curve25519.c new file mode 100644 index 0000000..a47d215 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_curve25519.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static const unsigned char GEN[] = { + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const unsigned char ORDER[] = { + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +/* see inner.h */ +const br_ec_curve_def br_curve25519 = { + BR_EC_curve25519, + ORDER, sizeof ORDER, + GEN, sizeof GEN +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_default.c b/BearSSL-OG/libbearssl/src/ec/ec_default.c new file mode 100644 index 0000000..7bb6e0c --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_default.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ec.h */ +const br_ec_impl * +br_ec_get_default(void) +{ +#if BR_LOMUL + return &br_ec_all_m15; +#else + return &br_ec_all_m31; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/ec/ec_keygen.c b/BearSSL-OG/libbearssl/src/ec/ec_keygen.c new file mode 100644 index 0000000..02a3096 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_keygen.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ec.h */ +size_t +br_ec_keygen(const br_prng_class **rng_ctx, + const br_ec_impl *impl, br_ec_private_key *sk, + void *kbuf, int curve) +{ + const unsigned char *order; + unsigned char *buf; + size_t len; + unsigned mask; + + if (curve < 0 || curve >= 32 + || ((impl->supported_curves >> curve) & 1) == 0) + { + return 0; + } + order = impl->order(curve, &len); + while (len > 0 && *order == 0) { + order ++; + len --; + } + if (kbuf == NULL || len == 0) { + return len; + } + mask = order[0]; + mask |= (mask >> 1); + mask |= (mask >> 2); + mask |= (mask >> 4); + + /* + * We generate sequences of random bits of the right size, until + * the value is strictly lower than the curve order (we also + * check for all-zero values, which are invalid). + */ + buf = kbuf; + for (;;) { + size_t u; + unsigned cc, zz; + + (*rng_ctx)->generate(rng_ctx, buf, len); + buf[0] &= mask; + cc = 0; + u = len; + zz = 0; + while (u -- > 0) { + cc = ((unsigned)(buf[u] - order[u] - cc) >> 8) & 1; + zz |= buf[u]; + } + if (cc != 0 && zz != 0) { + break; + } + } + + if (sk != NULL) { + sk->curve = curve; + sk->x = buf; + sk->xlen = len; + } + return len; +} diff --git a/BearSSL-OG/libbearssl/src/ec/ec_p256_m15.c b/BearSSL-OG/libbearssl/src/ec/ec_p256_m15.c new file mode 100644 index 0000000..1242438 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_p256_m15.c @@ -0,0 +1,2124 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * If BR_NO_ARITH_SHIFT is undefined, or defined to 0, then we _assume_ + * that right-shifting a signed negative integer copies the sign bit + * (arithmetic right-shift). This is "implementation-defined behaviour", + * i.e. it is not undefined, but it may differ between compilers. Each + * compiler is supposed to document its behaviour in that respect. GCC + * explicitly defines that an arithmetic right shift is used. We expect + * all other compilers to do the same, because underlying CPU offer an + * arithmetic right shift opcode that could not be used otherwise. + */ +#if BR_NO_ARITH_SHIFT +#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ + | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) +#else +#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) +#endif + +/* + * Convert an integer from unsigned big-endian encoding to a sequence of + * 13-bit words in little-endian order. The final "partial" word is + * returned. + */ +static uint32_t +be8_to_le13(uint32_t *dst, const unsigned char *src, size_t len) +{ + uint32_t acc; + int acc_len; + + acc = 0; + acc_len = 0; + while (len -- > 0) { + acc |= (uint32_t)src[len] << acc_len; + acc_len += 8; + if (acc_len >= 13) { + *dst ++ = acc & 0x1FFF; + acc >>= 13; + acc_len -= 13; + } + } + return acc; +} + +/* + * Convert an integer (13-bit words, little-endian) to unsigned + * big-endian encoding. The total encoding length is provided; all + * the destination bytes will be filled. + */ +static void +le13_to_be8(unsigned char *dst, size_t len, const uint32_t *src) +{ + uint32_t acc; + int acc_len; + + acc = 0; + acc_len = 0; + while (len -- > 0) { + if (acc_len < 8) { + acc |= (*src ++) << acc_len; + acc_len += 13; + } + dst[len] = (unsigned char)acc; + acc >>= 8; + acc_len -= 8; + } +} + +/* + * Normalise an array of words to a strict 13 bits per word. Returned + * value is the resulting carry. The source (w) and destination (d) + * arrays may be identical, but shall not overlap partially. + */ +static __inline uint32_t +norm13(uint32_t *d, const uint32_t *w, size_t len) +{ + size_t u; + uint32_t cc; + + cc = 0; + for (u = 0; u < len; u ++) { + int32_t z; + + z = w[u] + cc; + d[u] = z & 0x1FFF; + cc = ARSH(z, 13); + } + return cc; +} + +/* + * mul20() multiplies two 260-bit integers together. Each word must fit + * on 13 bits; source operands use 20 words, destination operand + * receives 40 words. All overlaps allowed. + * + * square20() computes the square of a 260-bit integer. Each word must + * fit on 13 bits; source operand uses 20 words, destination operand + * receives 40 words. All overlaps allowed. + */ + +#if BR_SLOW_MUL15 + +static void +mul20(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + /* + * Two-level Karatsuba: turns a 20x20 multiplication into + * nine 5x5 multiplications. We use 13-bit words but do not + * propagate carries immediately, so words may expand: + * + * - First Karatsuba decomposition turns the 20x20 mul on + * 13-bit words into three 10x10 muls, two on 13-bit words + * and one on 14-bit words. + * + * - Second Karatsuba decomposition further splits these into: + * + * * four 5x5 muls on 13-bit words + * * four 5x5 muls on 14-bit words + * * one 5x5 mul on 15-bit words + * + * Highest word value is 8191, 16382 or 32764, for 13-bit, 14-bit + * or 15-bit words, respectively. + */ + uint32_t u[45], v[45], w[90]; + uint32_t cc; + int i; + +#define ZADD(dw, d_off, s1w, s1_off, s2w, s2_off) do { \ + (dw)[5 * (d_off) + 0] = (s1w)[5 * (s1_off) + 0] \ + + (s2w)[5 * (s2_off) + 0]; \ + (dw)[5 * (d_off) + 1] = (s1w)[5 * (s1_off) + 1] \ + + (s2w)[5 * (s2_off) + 1]; \ + (dw)[5 * (d_off) + 2] = (s1w)[5 * (s1_off) + 2] \ + + (s2w)[5 * (s2_off) + 2]; \ + (dw)[5 * (d_off) + 3] = (s1w)[5 * (s1_off) + 3] \ + + (s2w)[5 * (s2_off) + 3]; \ + (dw)[5 * (d_off) + 4] = (s1w)[5 * (s1_off) + 4] \ + + (s2w)[5 * (s2_off) + 4]; \ + } while (0) + +#define ZADDT(dw, d_off, sw, s_off) do { \ + (dw)[5 * (d_off) + 0] += (sw)[5 * (s_off) + 0]; \ + (dw)[5 * (d_off) + 1] += (sw)[5 * (s_off) + 1]; \ + (dw)[5 * (d_off) + 2] += (sw)[5 * (s_off) + 2]; \ + (dw)[5 * (d_off) + 3] += (sw)[5 * (s_off) + 3]; \ + (dw)[5 * (d_off) + 4] += (sw)[5 * (s_off) + 4]; \ + } while (0) + +#define ZSUB2F(dw, d_off, s1w, s1_off, s2w, s2_off) do { \ + (dw)[5 * (d_off) + 0] -= (s1w)[5 * (s1_off) + 0] \ + + (s2w)[5 * (s2_off) + 0]; \ + (dw)[5 * (d_off) + 1] -= (s1w)[5 * (s1_off) + 1] \ + + (s2w)[5 * (s2_off) + 1]; \ + (dw)[5 * (d_off) + 2] -= (s1w)[5 * (s1_off) + 2] \ + + (s2w)[5 * (s2_off) + 2]; \ + (dw)[5 * (d_off) + 3] -= (s1w)[5 * (s1_off) + 3] \ + + (s2w)[5 * (s2_off) + 3]; \ + (dw)[5 * (d_off) + 4] -= (s1w)[5 * (s1_off) + 4] \ + + (s2w)[5 * (s2_off) + 4]; \ + } while (0) + +#define CPR1(w, cprcc) do { \ + uint32_t cprz = (w) + cprcc; \ + (w) = cprz & 0x1FFF; \ + cprcc = cprz >> 13; \ + } while (0) + +#define CPR(dw, d_off) do { \ + uint32_t cprcc; \ + cprcc = 0; \ + CPR1((dw)[(d_off) + 0], cprcc); \ + CPR1((dw)[(d_off) + 1], cprcc); \ + CPR1((dw)[(d_off) + 2], cprcc); \ + CPR1((dw)[(d_off) + 3], cprcc); \ + CPR1((dw)[(d_off) + 4], cprcc); \ + CPR1((dw)[(d_off) + 5], cprcc); \ + CPR1((dw)[(d_off) + 6], cprcc); \ + CPR1((dw)[(d_off) + 7], cprcc); \ + CPR1((dw)[(d_off) + 8], cprcc); \ + (dw)[(d_off) + 9] = cprcc; \ + } while (0) + + memcpy(u, a, 20 * sizeof *a); + ZADD(u, 4, a, 0, a, 1); + ZADD(u, 5, a, 2, a, 3); + ZADD(u, 6, a, 0, a, 2); + ZADD(u, 7, a, 1, a, 3); + ZADD(u, 8, u, 6, u, 7); + + memcpy(v, b, 20 * sizeof *b); + ZADD(v, 4, b, 0, b, 1); + ZADD(v, 5, b, 2, b, 3); + ZADD(v, 6, b, 0, b, 2); + ZADD(v, 7, b, 1, b, 3); + ZADD(v, 8, v, 6, v, 7); + + /* + * Do the eight first 8x8 muls. Source words are at most 16382 + * each, so we can add product results together "as is" in 32-bit + * words. + */ + for (i = 0; i < 40; i += 5) { + w[(i << 1) + 0] = MUL15(u[i + 0], v[i + 0]); + w[(i << 1) + 1] = MUL15(u[i + 0], v[i + 1]) + + MUL15(u[i + 1], v[i + 0]); + w[(i << 1) + 2] = MUL15(u[i + 0], v[i + 2]) + + MUL15(u[i + 1], v[i + 1]) + + MUL15(u[i + 2], v[i + 0]); + w[(i << 1) + 3] = MUL15(u[i + 0], v[i + 3]) + + MUL15(u[i + 1], v[i + 2]) + + MUL15(u[i + 2], v[i + 1]) + + MUL15(u[i + 3], v[i + 0]); + w[(i << 1) + 4] = MUL15(u[i + 0], v[i + 4]) + + MUL15(u[i + 1], v[i + 3]) + + MUL15(u[i + 2], v[i + 2]) + + MUL15(u[i + 3], v[i + 1]) + + MUL15(u[i + 4], v[i + 0]); + w[(i << 1) + 5] = MUL15(u[i + 1], v[i + 4]) + + MUL15(u[i + 2], v[i + 3]) + + MUL15(u[i + 3], v[i + 2]) + + MUL15(u[i + 4], v[i + 1]); + w[(i << 1) + 6] = MUL15(u[i + 2], v[i + 4]) + + MUL15(u[i + 3], v[i + 3]) + + MUL15(u[i + 4], v[i + 2]); + w[(i << 1) + 7] = MUL15(u[i + 3], v[i + 4]) + + MUL15(u[i + 4], v[i + 3]); + w[(i << 1) + 8] = MUL15(u[i + 4], v[i + 4]); + w[(i << 1) + 9] = 0; + } + + /* + * For the 9th multiplication, source words are up to 32764, + * so we must do some carry propagation. If we add up to + * 4 products and the carry is no more than 524224, then the + * result fits in 32 bits, and the next carry will be no more + * than 524224 (because 4*(32764^2)+524224 < 8192*524225). + * + * We thus just skip one of the products in the middle word, + * then do a carry propagation (this reduces words to 13 bits + * each, except possibly the last, which may use up to 17 bits + * or so), then add the missing product. + */ + w[80 + 0] = MUL15(u[40 + 0], v[40 + 0]); + w[80 + 1] = MUL15(u[40 + 0], v[40 + 1]) + + MUL15(u[40 + 1], v[40 + 0]); + w[80 + 2] = MUL15(u[40 + 0], v[40 + 2]) + + MUL15(u[40 + 1], v[40 + 1]) + + MUL15(u[40 + 2], v[40 + 0]); + w[80 + 3] = MUL15(u[40 + 0], v[40 + 3]) + + MUL15(u[40 + 1], v[40 + 2]) + + MUL15(u[40 + 2], v[40 + 1]) + + MUL15(u[40 + 3], v[40 + 0]); + w[80 + 4] = MUL15(u[40 + 0], v[40 + 4]) + + MUL15(u[40 + 1], v[40 + 3]) + + MUL15(u[40 + 2], v[40 + 2]) + + MUL15(u[40 + 3], v[40 + 1]); + /* + MUL15(u[40 + 4], v[40 + 0]) */ + w[80 + 5] = MUL15(u[40 + 1], v[40 + 4]) + + MUL15(u[40 + 2], v[40 + 3]) + + MUL15(u[40 + 3], v[40 + 2]) + + MUL15(u[40 + 4], v[40 + 1]); + w[80 + 6] = MUL15(u[40 + 2], v[40 + 4]) + + MUL15(u[40 + 3], v[40 + 3]) + + MUL15(u[40 + 4], v[40 + 2]); + w[80 + 7] = MUL15(u[40 + 3], v[40 + 4]) + + MUL15(u[40 + 4], v[40 + 3]); + w[80 + 8] = MUL15(u[40 + 4], v[40 + 4]); + + CPR(w, 80); + + w[80 + 4] += MUL15(u[40 + 4], v[40 + 0]); + + /* + * The products on 14-bit words in slots 6 and 7 yield values + * up to 5*(16382^2) each, and we need to subtract two such + * values from the higher word. We need the subtraction to fit + * in a _signed_ 32-bit integer, i.e. 31 bits + a sign bit. + * However, 10*(16382^2) does not fit. So we must perform a + * bit of reduction here. + */ + CPR(w, 60); + CPR(w, 70); + + /* + * Recompose results. + */ + + /* 0..1*0..1 into 0..3 */ + ZSUB2F(w, 8, w, 0, w, 2); + ZSUB2F(w, 9, w, 1, w, 3); + ZADDT(w, 1, w, 8); + ZADDT(w, 2, w, 9); + + /* 2..3*2..3 into 4..7 */ + ZSUB2F(w, 10, w, 4, w, 6); + ZSUB2F(w, 11, w, 5, w, 7); + ZADDT(w, 5, w, 10); + ZADDT(w, 6, w, 11); + + /* (0..1+2..3)*(0..1+2..3) into 12..15 */ + ZSUB2F(w, 16, w, 12, w, 14); + ZSUB2F(w, 17, w, 13, w, 15); + ZADDT(w, 13, w, 16); + ZADDT(w, 14, w, 17); + + /* first-level recomposition */ + ZSUB2F(w, 12, w, 0, w, 4); + ZSUB2F(w, 13, w, 1, w, 5); + ZSUB2F(w, 14, w, 2, w, 6); + ZSUB2F(w, 15, w, 3, w, 7); + ZADDT(w, 2, w, 12); + ZADDT(w, 3, w, 13); + ZADDT(w, 4, w, 14); + ZADDT(w, 5, w, 15); + + /* + * Perform carry propagation to bring all words down to 13 bits. + */ + cc = norm13(d, w, 40); + d[39] += (cc << 13); + +#undef ZADD +#undef ZADDT +#undef ZSUB2F +#undef CPR1 +#undef CPR +} + +static inline void +square20(uint32_t *d, const uint32_t *a) +{ + mul20(d, a, a); +} + +#else + +static void +mul20(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + uint32_t t[39]; + + t[ 0] = MUL15(a[ 0], b[ 0]); + t[ 1] = MUL15(a[ 0], b[ 1]) + + MUL15(a[ 1], b[ 0]); + t[ 2] = MUL15(a[ 0], b[ 2]) + + MUL15(a[ 1], b[ 1]) + + MUL15(a[ 2], b[ 0]); + t[ 3] = MUL15(a[ 0], b[ 3]) + + MUL15(a[ 1], b[ 2]) + + MUL15(a[ 2], b[ 1]) + + MUL15(a[ 3], b[ 0]); + t[ 4] = MUL15(a[ 0], b[ 4]) + + MUL15(a[ 1], b[ 3]) + + MUL15(a[ 2], b[ 2]) + + MUL15(a[ 3], b[ 1]) + + MUL15(a[ 4], b[ 0]); + t[ 5] = MUL15(a[ 0], b[ 5]) + + MUL15(a[ 1], b[ 4]) + + MUL15(a[ 2], b[ 3]) + + MUL15(a[ 3], b[ 2]) + + MUL15(a[ 4], b[ 1]) + + MUL15(a[ 5], b[ 0]); + t[ 6] = MUL15(a[ 0], b[ 6]) + + MUL15(a[ 1], b[ 5]) + + MUL15(a[ 2], b[ 4]) + + MUL15(a[ 3], b[ 3]) + + MUL15(a[ 4], b[ 2]) + + MUL15(a[ 5], b[ 1]) + + MUL15(a[ 6], b[ 0]); + t[ 7] = MUL15(a[ 0], b[ 7]) + + MUL15(a[ 1], b[ 6]) + + MUL15(a[ 2], b[ 5]) + + MUL15(a[ 3], b[ 4]) + + MUL15(a[ 4], b[ 3]) + + MUL15(a[ 5], b[ 2]) + + MUL15(a[ 6], b[ 1]) + + MUL15(a[ 7], b[ 0]); + t[ 8] = MUL15(a[ 0], b[ 8]) + + MUL15(a[ 1], b[ 7]) + + MUL15(a[ 2], b[ 6]) + + MUL15(a[ 3], b[ 5]) + + MUL15(a[ 4], b[ 4]) + + MUL15(a[ 5], b[ 3]) + + MUL15(a[ 6], b[ 2]) + + MUL15(a[ 7], b[ 1]) + + MUL15(a[ 8], b[ 0]); + t[ 9] = MUL15(a[ 0], b[ 9]) + + MUL15(a[ 1], b[ 8]) + + MUL15(a[ 2], b[ 7]) + + MUL15(a[ 3], b[ 6]) + + MUL15(a[ 4], b[ 5]) + + MUL15(a[ 5], b[ 4]) + + MUL15(a[ 6], b[ 3]) + + MUL15(a[ 7], b[ 2]) + + MUL15(a[ 8], b[ 1]) + + MUL15(a[ 9], b[ 0]); + t[10] = MUL15(a[ 0], b[10]) + + MUL15(a[ 1], b[ 9]) + + MUL15(a[ 2], b[ 8]) + + MUL15(a[ 3], b[ 7]) + + MUL15(a[ 4], b[ 6]) + + MUL15(a[ 5], b[ 5]) + + MUL15(a[ 6], b[ 4]) + + MUL15(a[ 7], b[ 3]) + + MUL15(a[ 8], b[ 2]) + + MUL15(a[ 9], b[ 1]) + + MUL15(a[10], b[ 0]); + t[11] = MUL15(a[ 0], b[11]) + + MUL15(a[ 1], b[10]) + + MUL15(a[ 2], b[ 9]) + + MUL15(a[ 3], b[ 8]) + + MUL15(a[ 4], b[ 7]) + + MUL15(a[ 5], b[ 6]) + + MUL15(a[ 6], b[ 5]) + + MUL15(a[ 7], b[ 4]) + + MUL15(a[ 8], b[ 3]) + + MUL15(a[ 9], b[ 2]) + + MUL15(a[10], b[ 1]) + + MUL15(a[11], b[ 0]); + t[12] = MUL15(a[ 0], b[12]) + + MUL15(a[ 1], b[11]) + + MUL15(a[ 2], b[10]) + + MUL15(a[ 3], b[ 9]) + + MUL15(a[ 4], b[ 8]) + + MUL15(a[ 5], b[ 7]) + + MUL15(a[ 6], b[ 6]) + + MUL15(a[ 7], b[ 5]) + + MUL15(a[ 8], b[ 4]) + + MUL15(a[ 9], b[ 3]) + + MUL15(a[10], b[ 2]) + + MUL15(a[11], b[ 1]) + + MUL15(a[12], b[ 0]); + t[13] = MUL15(a[ 0], b[13]) + + MUL15(a[ 1], b[12]) + + MUL15(a[ 2], b[11]) + + MUL15(a[ 3], b[10]) + + MUL15(a[ 4], b[ 9]) + + MUL15(a[ 5], b[ 8]) + + MUL15(a[ 6], b[ 7]) + + MUL15(a[ 7], b[ 6]) + + MUL15(a[ 8], b[ 5]) + + MUL15(a[ 9], b[ 4]) + + MUL15(a[10], b[ 3]) + + MUL15(a[11], b[ 2]) + + MUL15(a[12], b[ 1]) + + MUL15(a[13], b[ 0]); + t[14] = MUL15(a[ 0], b[14]) + + MUL15(a[ 1], b[13]) + + MUL15(a[ 2], b[12]) + + MUL15(a[ 3], b[11]) + + MUL15(a[ 4], b[10]) + + MUL15(a[ 5], b[ 9]) + + MUL15(a[ 6], b[ 8]) + + MUL15(a[ 7], b[ 7]) + + MUL15(a[ 8], b[ 6]) + + MUL15(a[ 9], b[ 5]) + + MUL15(a[10], b[ 4]) + + MUL15(a[11], b[ 3]) + + MUL15(a[12], b[ 2]) + + MUL15(a[13], b[ 1]) + + MUL15(a[14], b[ 0]); + t[15] = MUL15(a[ 0], b[15]) + + MUL15(a[ 1], b[14]) + + MUL15(a[ 2], b[13]) + + MUL15(a[ 3], b[12]) + + MUL15(a[ 4], b[11]) + + MUL15(a[ 5], b[10]) + + MUL15(a[ 6], b[ 9]) + + MUL15(a[ 7], b[ 8]) + + MUL15(a[ 8], b[ 7]) + + MUL15(a[ 9], b[ 6]) + + MUL15(a[10], b[ 5]) + + MUL15(a[11], b[ 4]) + + MUL15(a[12], b[ 3]) + + MUL15(a[13], b[ 2]) + + MUL15(a[14], b[ 1]) + + MUL15(a[15], b[ 0]); + t[16] = MUL15(a[ 0], b[16]) + + MUL15(a[ 1], b[15]) + + MUL15(a[ 2], b[14]) + + MUL15(a[ 3], b[13]) + + MUL15(a[ 4], b[12]) + + MUL15(a[ 5], b[11]) + + MUL15(a[ 6], b[10]) + + MUL15(a[ 7], b[ 9]) + + MUL15(a[ 8], b[ 8]) + + MUL15(a[ 9], b[ 7]) + + MUL15(a[10], b[ 6]) + + MUL15(a[11], b[ 5]) + + MUL15(a[12], b[ 4]) + + MUL15(a[13], b[ 3]) + + MUL15(a[14], b[ 2]) + + MUL15(a[15], b[ 1]) + + MUL15(a[16], b[ 0]); + t[17] = MUL15(a[ 0], b[17]) + + MUL15(a[ 1], b[16]) + + MUL15(a[ 2], b[15]) + + MUL15(a[ 3], b[14]) + + MUL15(a[ 4], b[13]) + + MUL15(a[ 5], b[12]) + + MUL15(a[ 6], b[11]) + + MUL15(a[ 7], b[10]) + + MUL15(a[ 8], b[ 9]) + + MUL15(a[ 9], b[ 8]) + + MUL15(a[10], b[ 7]) + + MUL15(a[11], b[ 6]) + + MUL15(a[12], b[ 5]) + + MUL15(a[13], b[ 4]) + + MUL15(a[14], b[ 3]) + + MUL15(a[15], b[ 2]) + + MUL15(a[16], b[ 1]) + + MUL15(a[17], b[ 0]); + t[18] = MUL15(a[ 0], b[18]) + + MUL15(a[ 1], b[17]) + + MUL15(a[ 2], b[16]) + + MUL15(a[ 3], b[15]) + + MUL15(a[ 4], b[14]) + + MUL15(a[ 5], b[13]) + + MUL15(a[ 6], b[12]) + + MUL15(a[ 7], b[11]) + + MUL15(a[ 8], b[10]) + + MUL15(a[ 9], b[ 9]) + + MUL15(a[10], b[ 8]) + + MUL15(a[11], b[ 7]) + + MUL15(a[12], b[ 6]) + + MUL15(a[13], b[ 5]) + + MUL15(a[14], b[ 4]) + + MUL15(a[15], b[ 3]) + + MUL15(a[16], b[ 2]) + + MUL15(a[17], b[ 1]) + + MUL15(a[18], b[ 0]); + t[19] = MUL15(a[ 0], b[19]) + + MUL15(a[ 1], b[18]) + + MUL15(a[ 2], b[17]) + + MUL15(a[ 3], b[16]) + + MUL15(a[ 4], b[15]) + + MUL15(a[ 5], b[14]) + + MUL15(a[ 6], b[13]) + + MUL15(a[ 7], b[12]) + + MUL15(a[ 8], b[11]) + + MUL15(a[ 9], b[10]) + + MUL15(a[10], b[ 9]) + + MUL15(a[11], b[ 8]) + + MUL15(a[12], b[ 7]) + + MUL15(a[13], b[ 6]) + + MUL15(a[14], b[ 5]) + + MUL15(a[15], b[ 4]) + + MUL15(a[16], b[ 3]) + + MUL15(a[17], b[ 2]) + + MUL15(a[18], b[ 1]) + + MUL15(a[19], b[ 0]); + t[20] = MUL15(a[ 1], b[19]) + + MUL15(a[ 2], b[18]) + + MUL15(a[ 3], b[17]) + + MUL15(a[ 4], b[16]) + + MUL15(a[ 5], b[15]) + + MUL15(a[ 6], b[14]) + + MUL15(a[ 7], b[13]) + + MUL15(a[ 8], b[12]) + + MUL15(a[ 9], b[11]) + + MUL15(a[10], b[10]) + + MUL15(a[11], b[ 9]) + + MUL15(a[12], b[ 8]) + + MUL15(a[13], b[ 7]) + + MUL15(a[14], b[ 6]) + + MUL15(a[15], b[ 5]) + + MUL15(a[16], b[ 4]) + + MUL15(a[17], b[ 3]) + + MUL15(a[18], b[ 2]) + + MUL15(a[19], b[ 1]); + t[21] = MUL15(a[ 2], b[19]) + + MUL15(a[ 3], b[18]) + + MUL15(a[ 4], b[17]) + + MUL15(a[ 5], b[16]) + + MUL15(a[ 6], b[15]) + + MUL15(a[ 7], b[14]) + + MUL15(a[ 8], b[13]) + + MUL15(a[ 9], b[12]) + + MUL15(a[10], b[11]) + + MUL15(a[11], b[10]) + + MUL15(a[12], b[ 9]) + + MUL15(a[13], b[ 8]) + + MUL15(a[14], b[ 7]) + + MUL15(a[15], b[ 6]) + + MUL15(a[16], b[ 5]) + + MUL15(a[17], b[ 4]) + + MUL15(a[18], b[ 3]) + + MUL15(a[19], b[ 2]); + t[22] = MUL15(a[ 3], b[19]) + + MUL15(a[ 4], b[18]) + + MUL15(a[ 5], b[17]) + + MUL15(a[ 6], b[16]) + + MUL15(a[ 7], b[15]) + + MUL15(a[ 8], b[14]) + + MUL15(a[ 9], b[13]) + + MUL15(a[10], b[12]) + + MUL15(a[11], b[11]) + + MUL15(a[12], b[10]) + + MUL15(a[13], b[ 9]) + + MUL15(a[14], b[ 8]) + + MUL15(a[15], b[ 7]) + + MUL15(a[16], b[ 6]) + + MUL15(a[17], b[ 5]) + + MUL15(a[18], b[ 4]) + + MUL15(a[19], b[ 3]); + t[23] = MUL15(a[ 4], b[19]) + + MUL15(a[ 5], b[18]) + + MUL15(a[ 6], b[17]) + + MUL15(a[ 7], b[16]) + + MUL15(a[ 8], b[15]) + + MUL15(a[ 9], b[14]) + + MUL15(a[10], b[13]) + + MUL15(a[11], b[12]) + + MUL15(a[12], b[11]) + + MUL15(a[13], b[10]) + + MUL15(a[14], b[ 9]) + + MUL15(a[15], b[ 8]) + + MUL15(a[16], b[ 7]) + + MUL15(a[17], b[ 6]) + + MUL15(a[18], b[ 5]) + + MUL15(a[19], b[ 4]); + t[24] = MUL15(a[ 5], b[19]) + + MUL15(a[ 6], b[18]) + + MUL15(a[ 7], b[17]) + + MUL15(a[ 8], b[16]) + + MUL15(a[ 9], b[15]) + + MUL15(a[10], b[14]) + + MUL15(a[11], b[13]) + + MUL15(a[12], b[12]) + + MUL15(a[13], b[11]) + + MUL15(a[14], b[10]) + + MUL15(a[15], b[ 9]) + + MUL15(a[16], b[ 8]) + + MUL15(a[17], b[ 7]) + + MUL15(a[18], b[ 6]) + + MUL15(a[19], b[ 5]); + t[25] = MUL15(a[ 6], b[19]) + + MUL15(a[ 7], b[18]) + + MUL15(a[ 8], b[17]) + + MUL15(a[ 9], b[16]) + + MUL15(a[10], b[15]) + + MUL15(a[11], b[14]) + + MUL15(a[12], b[13]) + + MUL15(a[13], b[12]) + + MUL15(a[14], b[11]) + + MUL15(a[15], b[10]) + + MUL15(a[16], b[ 9]) + + MUL15(a[17], b[ 8]) + + MUL15(a[18], b[ 7]) + + MUL15(a[19], b[ 6]); + t[26] = MUL15(a[ 7], b[19]) + + MUL15(a[ 8], b[18]) + + MUL15(a[ 9], b[17]) + + MUL15(a[10], b[16]) + + MUL15(a[11], b[15]) + + MUL15(a[12], b[14]) + + MUL15(a[13], b[13]) + + MUL15(a[14], b[12]) + + MUL15(a[15], b[11]) + + MUL15(a[16], b[10]) + + MUL15(a[17], b[ 9]) + + MUL15(a[18], b[ 8]) + + MUL15(a[19], b[ 7]); + t[27] = MUL15(a[ 8], b[19]) + + MUL15(a[ 9], b[18]) + + MUL15(a[10], b[17]) + + MUL15(a[11], b[16]) + + MUL15(a[12], b[15]) + + MUL15(a[13], b[14]) + + MUL15(a[14], b[13]) + + MUL15(a[15], b[12]) + + MUL15(a[16], b[11]) + + MUL15(a[17], b[10]) + + MUL15(a[18], b[ 9]) + + MUL15(a[19], b[ 8]); + t[28] = MUL15(a[ 9], b[19]) + + MUL15(a[10], b[18]) + + MUL15(a[11], b[17]) + + MUL15(a[12], b[16]) + + MUL15(a[13], b[15]) + + MUL15(a[14], b[14]) + + MUL15(a[15], b[13]) + + MUL15(a[16], b[12]) + + MUL15(a[17], b[11]) + + MUL15(a[18], b[10]) + + MUL15(a[19], b[ 9]); + t[29] = MUL15(a[10], b[19]) + + MUL15(a[11], b[18]) + + MUL15(a[12], b[17]) + + MUL15(a[13], b[16]) + + MUL15(a[14], b[15]) + + MUL15(a[15], b[14]) + + MUL15(a[16], b[13]) + + MUL15(a[17], b[12]) + + MUL15(a[18], b[11]) + + MUL15(a[19], b[10]); + t[30] = MUL15(a[11], b[19]) + + MUL15(a[12], b[18]) + + MUL15(a[13], b[17]) + + MUL15(a[14], b[16]) + + MUL15(a[15], b[15]) + + MUL15(a[16], b[14]) + + MUL15(a[17], b[13]) + + MUL15(a[18], b[12]) + + MUL15(a[19], b[11]); + t[31] = MUL15(a[12], b[19]) + + MUL15(a[13], b[18]) + + MUL15(a[14], b[17]) + + MUL15(a[15], b[16]) + + MUL15(a[16], b[15]) + + MUL15(a[17], b[14]) + + MUL15(a[18], b[13]) + + MUL15(a[19], b[12]); + t[32] = MUL15(a[13], b[19]) + + MUL15(a[14], b[18]) + + MUL15(a[15], b[17]) + + MUL15(a[16], b[16]) + + MUL15(a[17], b[15]) + + MUL15(a[18], b[14]) + + MUL15(a[19], b[13]); + t[33] = MUL15(a[14], b[19]) + + MUL15(a[15], b[18]) + + MUL15(a[16], b[17]) + + MUL15(a[17], b[16]) + + MUL15(a[18], b[15]) + + MUL15(a[19], b[14]); + t[34] = MUL15(a[15], b[19]) + + MUL15(a[16], b[18]) + + MUL15(a[17], b[17]) + + MUL15(a[18], b[16]) + + MUL15(a[19], b[15]); + t[35] = MUL15(a[16], b[19]) + + MUL15(a[17], b[18]) + + MUL15(a[18], b[17]) + + MUL15(a[19], b[16]); + t[36] = MUL15(a[17], b[19]) + + MUL15(a[18], b[18]) + + MUL15(a[19], b[17]); + t[37] = MUL15(a[18], b[19]) + + MUL15(a[19], b[18]); + t[38] = MUL15(a[19], b[19]); + d[39] = norm13(d, t, 39); +} + +static void +square20(uint32_t *d, const uint32_t *a) +{ + uint32_t t[39]; + + t[ 0] = MUL15(a[ 0], a[ 0]); + t[ 1] = ((MUL15(a[ 0], a[ 1])) << 1); + t[ 2] = MUL15(a[ 1], a[ 1]) + + ((MUL15(a[ 0], a[ 2])) << 1); + t[ 3] = ((MUL15(a[ 0], a[ 3]) + + MUL15(a[ 1], a[ 2])) << 1); + t[ 4] = MUL15(a[ 2], a[ 2]) + + ((MUL15(a[ 0], a[ 4]) + + MUL15(a[ 1], a[ 3])) << 1); + t[ 5] = ((MUL15(a[ 0], a[ 5]) + + MUL15(a[ 1], a[ 4]) + + MUL15(a[ 2], a[ 3])) << 1); + t[ 6] = MUL15(a[ 3], a[ 3]) + + ((MUL15(a[ 0], a[ 6]) + + MUL15(a[ 1], a[ 5]) + + MUL15(a[ 2], a[ 4])) << 1); + t[ 7] = ((MUL15(a[ 0], a[ 7]) + + MUL15(a[ 1], a[ 6]) + + MUL15(a[ 2], a[ 5]) + + MUL15(a[ 3], a[ 4])) << 1); + t[ 8] = MUL15(a[ 4], a[ 4]) + + ((MUL15(a[ 0], a[ 8]) + + MUL15(a[ 1], a[ 7]) + + MUL15(a[ 2], a[ 6]) + + MUL15(a[ 3], a[ 5])) << 1); + t[ 9] = ((MUL15(a[ 0], a[ 9]) + + MUL15(a[ 1], a[ 8]) + + MUL15(a[ 2], a[ 7]) + + MUL15(a[ 3], a[ 6]) + + MUL15(a[ 4], a[ 5])) << 1); + t[10] = MUL15(a[ 5], a[ 5]) + + ((MUL15(a[ 0], a[10]) + + MUL15(a[ 1], a[ 9]) + + MUL15(a[ 2], a[ 8]) + + MUL15(a[ 3], a[ 7]) + + MUL15(a[ 4], a[ 6])) << 1); + t[11] = ((MUL15(a[ 0], a[11]) + + MUL15(a[ 1], a[10]) + + MUL15(a[ 2], a[ 9]) + + MUL15(a[ 3], a[ 8]) + + MUL15(a[ 4], a[ 7]) + + MUL15(a[ 5], a[ 6])) << 1); + t[12] = MUL15(a[ 6], a[ 6]) + + ((MUL15(a[ 0], a[12]) + + MUL15(a[ 1], a[11]) + + MUL15(a[ 2], a[10]) + + MUL15(a[ 3], a[ 9]) + + MUL15(a[ 4], a[ 8]) + + MUL15(a[ 5], a[ 7])) << 1); + t[13] = ((MUL15(a[ 0], a[13]) + + MUL15(a[ 1], a[12]) + + MUL15(a[ 2], a[11]) + + MUL15(a[ 3], a[10]) + + MUL15(a[ 4], a[ 9]) + + MUL15(a[ 5], a[ 8]) + + MUL15(a[ 6], a[ 7])) << 1); + t[14] = MUL15(a[ 7], a[ 7]) + + ((MUL15(a[ 0], a[14]) + + MUL15(a[ 1], a[13]) + + MUL15(a[ 2], a[12]) + + MUL15(a[ 3], a[11]) + + MUL15(a[ 4], a[10]) + + MUL15(a[ 5], a[ 9]) + + MUL15(a[ 6], a[ 8])) << 1); + t[15] = ((MUL15(a[ 0], a[15]) + + MUL15(a[ 1], a[14]) + + MUL15(a[ 2], a[13]) + + MUL15(a[ 3], a[12]) + + MUL15(a[ 4], a[11]) + + MUL15(a[ 5], a[10]) + + MUL15(a[ 6], a[ 9]) + + MUL15(a[ 7], a[ 8])) << 1); + t[16] = MUL15(a[ 8], a[ 8]) + + ((MUL15(a[ 0], a[16]) + + MUL15(a[ 1], a[15]) + + MUL15(a[ 2], a[14]) + + MUL15(a[ 3], a[13]) + + MUL15(a[ 4], a[12]) + + MUL15(a[ 5], a[11]) + + MUL15(a[ 6], a[10]) + + MUL15(a[ 7], a[ 9])) << 1); + t[17] = ((MUL15(a[ 0], a[17]) + + MUL15(a[ 1], a[16]) + + MUL15(a[ 2], a[15]) + + MUL15(a[ 3], a[14]) + + MUL15(a[ 4], a[13]) + + MUL15(a[ 5], a[12]) + + MUL15(a[ 6], a[11]) + + MUL15(a[ 7], a[10]) + + MUL15(a[ 8], a[ 9])) << 1); + t[18] = MUL15(a[ 9], a[ 9]) + + ((MUL15(a[ 0], a[18]) + + MUL15(a[ 1], a[17]) + + MUL15(a[ 2], a[16]) + + MUL15(a[ 3], a[15]) + + MUL15(a[ 4], a[14]) + + MUL15(a[ 5], a[13]) + + MUL15(a[ 6], a[12]) + + MUL15(a[ 7], a[11]) + + MUL15(a[ 8], a[10])) << 1); + t[19] = ((MUL15(a[ 0], a[19]) + + MUL15(a[ 1], a[18]) + + MUL15(a[ 2], a[17]) + + MUL15(a[ 3], a[16]) + + MUL15(a[ 4], a[15]) + + MUL15(a[ 5], a[14]) + + MUL15(a[ 6], a[13]) + + MUL15(a[ 7], a[12]) + + MUL15(a[ 8], a[11]) + + MUL15(a[ 9], a[10])) << 1); + t[20] = MUL15(a[10], a[10]) + + ((MUL15(a[ 1], a[19]) + + MUL15(a[ 2], a[18]) + + MUL15(a[ 3], a[17]) + + MUL15(a[ 4], a[16]) + + MUL15(a[ 5], a[15]) + + MUL15(a[ 6], a[14]) + + MUL15(a[ 7], a[13]) + + MUL15(a[ 8], a[12]) + + MUL15(a[ 9], a[11])) << 1); + t[21] = ((MUL15(a[ 2], a[19]) + + MUL15(a[ 3], a[18]) + + MUL15(a[ 4], a[17]) + + MUL15(a[ 5], a[16]) + + MUL15(a[ 6], a[15]) + + MUL15(a[ 7], a[14]) + + MUL15(a[ 8], a[13]) + + MUL15(a[ 9], a[12]) + + MUL15(a[10], a[11])) << 1); + t[22] = MUL15(a[11], a[11]) + + ((MUL15(a[ 3], a[19]) + + MUL15(a[ 4], a[18]) + + MUL15(a[ 5], a[17]) + + MUL15(a[ 6], a[16]) + + MUL15(a[ 7], a[15]) + + MUL15(a[ 8], a[14]) + + MUL15(a[ 9], a[13]) + + MUL15(a[10], a[12])) << 1); + t[23] = ((MUL15(a[ 4], a[19]) + + MUL15(a[ 5], a[18]) + + MUL15(a[ 6], a[17]) + + MUL15(a[ 7], a[16]) + + MUL15(a[ 8], a[15]) + + MUL15(a[ 9], a[14]) + + MUL15(a[10], a[13]) + + MUL15(a[11], a[12])) << 1); + t[24] = MUL15(a[12], a[12]) + + ((MUL15(a[ 5], a[19]) + + MUL15(a[ 6], a[18]) + + MUL15(a[ 7], a[17]) + + MUL15(a[ 8], a[16]) + + MUL15(a[ 9], a[15]) + + MUL15(a[10], a[14]) + + MUL15(a[11], a[13])) << 1); + t[25] = ((MUL15(a[ 6], a[19]) + + MUL15(a[ 7], a[18]) + + MUL15(a[ 8], a[17]) + + MUL15(a[ 9], a[16]) + + MUL15(a[10], a[15]) + + MUL15(a[11], a[14]) + + MUL15(a[12], a[13])) << 1); + t[26] = MUL15(a[13], a[13]) + + ((MUL15(a[ 7], a[19]) + + MUL15(a[ 8], a[18]) + + MUL15(a[ 9], a[17]) + + MUL15(a[10], a[16]) + + MUL15(a[11], a[15]) + + MUL15(a[12], a[14])) << 1); + t[27] = ((MUL15(a[ 8], a[19]) + + MUL15(a[ 9], a[18]) + + MUL15(a[10], a[17]) + + MUL15(a[11], a[16]) + + MUL15(a[12], a[15]) + + MUL15(a[13], a[14])) << 1); + t[28] = MUL15(a[14], a[14]) + + ((MUL15(a[ 9], a[19]) + + MUL15(a[10], a[18]) + + MUL15(a[11], a[17]) + + MUL15(a[12], a[16]) + + MUL15(a[13], a[15])) << 1); + t[29] = ((MUL15(a[10], a[19]) + + MUL15(a[11], a[18]) + + MUL15(a[12], a[17]) + + MUL15(a[13], a[16]) + + MUL15(a[14], a[15])) << 1); + t[30] = MUL15(a[15], a[15]) + + ((MUL15(a[11], a[19]) + + MUL15(a[12], a[18]) + + MUL15(a[13], a[17]) + + MUL15(a[14], a[16])) << 1); + t[31] = ((MUL15(a[12], a[19]) + + MUL15(a[13], a[18]) + + MUL15(a[14], a[17]) + + MUL15(a[15], a[16])) << 1); + t[32] = MUL15(a[16], a[16]) + + ((MUL15(a[13], a[19]) + + MUL15(a[14], a[18]) + + MUL15(a[15], a[17])) << 1); + t[33] = ((MUL15(a[14], a[19]) + + MUL15(a[15], a[18]) + + MUL15(a[16], a[17])) << 1); + t[34] = MUL15(a[17], a[17]) + + ((MUL15(a[15], a[19]) + + MUL15(a[16], a[18])) << 1); + t[35] = ((MUL15(a[16], a[19]) + + MUL15(a[17], a[18])) << 1); + t[36] = MUL15(a[18], a[18]) + + ((MUL15(a[17], a[19])) << 1); + t[37] = ((MUL15(a[18], a[19])) << 1); + t[38] = MUL15(a[19], a[19]); + d[39] = norm13(d, t, 39); +} + +#endif + +/* + * Modulus for field F256 (field for point coordinates in curve P-256). + */ +static const uint32_t F256[] = { + 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x001F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0400, 0x0000, + 0x0000, 0x1FF8, 0x1FFF, 0x01FF +}; + +/* + * The 'b' curve equation coefficient for P-256. + */ +static const uint32_t P256_B[] = { + 0x004B, 0x1E93, 0x0F89, 0x1C78, 0x03BC, 0x187B, 0x114E, 0x1619, + 0x1D06, 0x0328, 0x01AF, 0x0D31, 0x1557, 0x15DE, 0x1ECF, 0x127C, + 0x0A3A, 0x0EC5, 0x118D, 0x00B5 +}; + +/* + * Perform a "short reduction" in field F256 (field for curve P-256). + * The source value should be less than 262 bits; on output, it will + * be at most 257 bits, and less than twice the modulus. + */ +static void +reduce_f256(uint32_t *d) +{ + uint32_t x; + + x = d[19] >> 9; + d[19] &= 0x01FF; + d[17] += x << 3; + d[14] -= x << 10; + d[7] -= x << 5; + d[0] += x; + norm13(d, d, 20); +} + +/* + * Perform a "final reduction" in field F256 (field for curve P-256). + * The source value must be less than twice the modulus. If the value + * is not lower than the modulus, then the modulus is subtracted and + * this function returns 1; otherwise, it leaves it untouched and it + * returns 0. + */ +static uint32_t +reduce_final_f256(uint32_t *d) +{ + uint32_t t[20]; + uint32_t cc; + int i; + + memcpy(t, d, sizeof t); + cc = 0; + for (i = 0; i < 20; i ++) { + uint32_t w; + + w = t[i] - F256[i] - cc; + cc = w >> 31; + t[i] = w & 0x1FFF; + } + cc ^= 1; + CCOPY(cc, d, t, sizeof t); + return cc; +} + +/* + * Perform a multiplication of two integers modulo + * 2^256-2^224+2^192+2^96-1 (for NIST curve P-256). Operands are arrays + * of 20 words, each containing 13 bits of data, in little-endian order. + * On input, upper word may be up to 13 bits (hence value up to 2^260-1); + * on output, value fits on 257 bits and is lower than twice the modulus. + */ +static void +mul_f256(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + uint32_t t[40], cc; + int i; + + /* + * Compute raw multiplication. All result words fit in 13 bits + * each. + */ + mul20(t, a, b); + + /* + * Modular reduction: each high word in added/subtracted where + * necessary. + * + * The modulus is: + * p = 2^256 - 2^224 + 2^192 + 2^96 - 1 + * Therefore: + * 2^256 = 2^224 - 2^192 - 2^96 + 1 mod p + * + * For a word x at bit offset n (n >= 256), we have: + * x*2^n = x*2^(n-32) - x*2^(n-64) + * - x*2^(n - 160) + x*2^(n-256) mod p + * + * Thus, we can nullify the high word if we reinject it at some + * proper emplacements. + */ + for (i = 39; i >= 20; i --) { + uint32_t x; + + x = t[i]; + t[i - 2] += ARSH(x, 6); + t[i - 3] += (x << 7) & 0x1FFF; + t[i - 4] -= ARSH(x, 12); + t[i - 5] -= (x << 1) & 0x1FFF; + t[i - 12] -= ARSH(x, 4); + t[i - 13] -= (x << 9) & 0x1FFF; + t[i - 19] += ARSH(x, 9); + t[i - 20] += (x << 4) & 0x1FFF; + } + + /* + * Propagate carries. This is a signed propagation, and the + * result may be negative. The loop above may enlarge values, + * but not two much: worst case is the chain involving t[i - 3], + * in which a value may be added to itself up to 7 times. Since + * starting values are 13-bit each, all words fit on 20 bits + * (21 to account for the sign bit). + */ + cc = norm13(t, t, 20); + + /* + * Perform modular reduction again for the bits beyond 256 (the carry + * and the bits 256..259). Since the largest shift below is by 10 + * bits, and the values fit on 21 bits, values fit in 32-bit words, + * thereby allowing injecting full word values. + */ + cc = (cc << 4) | (t[19] >> 9); + t[19] &= 0x01FF; + t[17] += cc << 3; + t[14] -= cc << 10; + t[7] -= cc << 5; + t[0] += cc; + + /* + * If the carry is negative, then after carry propagation, we may + * end up with a value which is negative, and we don't want that. + * Thus, in that case, we add the modulus. Note that the subtraction + * result, when the carry is negative, is always smaller than the + * modulus, so the extra addition will not make the value exceed + * twice the modulus. + */ + cc >>= 31; + t[0] -= cc; + t[7] += cc << 5; + t[14] += cc << 10; + t[17] -= cc << 3; + t[19] += cc << 9; + + norm13(d, t, 20); +} + +/* + * Square an integer modulo 2^256-2^224+2^192+2^96-1 (for NIST curve + * P-256). Operand is an array of 20 words, each containing 13 bits of + * data, in little-endian order. On input, upper word may be up to 13 + * bits (hence value up to 2^260-1); on output, value fits on 257 bits + * and is lower than twice the modulus. + */ +static void +square_f256(uint32_t *d, const uint32_t *a) +{ + uint32_t t[40], cc; + int i; + + /* + * Compute raw square. All result words fit in 13 bits each. + */ + square20(t, a); + + /* + * Modular reduction: each high word in added/subtracted where + * necessary. + * + * The modulus is: + * p = 2^256 - 2^224 + 2^192 + 2^96 - 1 + * Therefore: + * 2^256 = 2^224 - 2^192 - 2^96 + 1 mod p + * + * For a word x at bit offset n (n >= 256), we have: + * x*2^n = x*2^(n-32) - x*2^(n-64) + * - x*2^(n - 160) + x*2^(n-256) mod p + * + * Thus, we can nullify the high word if we reinject it at some + * proper emplacements. + */ + for (i = 39; i >= 20; i --) { + uint32_t x; + + x = t[i]; + t[i - 2] += ARSH(x, 6); + t[i - 3] += (x << 7) & 0x1FFF; + t[i - 4] -= ARSH(x, 12); + t[i - 5] -= (x << 1) & 0x1FFF; + t[i - 12] -= ARSH(x, 4); + t[i - 13] -= (x << 9) & 0x1FFF; + t[i - 19] += ARSH(x, 9); + t[i - 20] += (x << 4) & 0x1FFF; + } + + /* + * Propagate carries. This is a signed propagation, and the + * result may be negative. The loop above may enlarge values, + * but not two much: worst case is the chain involving t[i - 3], + * in which a value may be added to itself up to 7 times. Since + * starting values are 13-bit each, all words fit on 20 bits + * (21 to account for the sign bit). + */ + cc = norm13(t, t, 20); + + /* + * Perform modular reduction again for the bits beyond 256 (the carry + * and the bits 256..259). Since the largest shift below is by 10 + * bits, and the values fit on 21 bits, values fit in 32-bit words, + * thereby allowing injecting full word values. + */ + cc = (cc << 4) | (t[19] >> 9); + t[19] &= 0x01FF; + t[17] += cc << 3; + t[14] -= cc << 10; + t[7] -= cc << 5; + t[0] += cc; + + /* + * If the carry is negative, then after carry propagation, we may + * end up with a value which is negative, and we don't want that. + * Thus, in that case, we add the modulus. Note that the subtraction + * result, when the carry is negative, is always smaller than the + * modulus, so the extra addition will not make the value exceed + * twice the modulus. + */ + cc >>= 31; + t[0] -= cc; + t[7] += cc << 5; + t[14] += cc << 10; + t[17] -= cc << 3; + t[19] += cc << 9; + + norm13(d, t, 20); +} + +/* + * Jacobian coordinates for a point in P-256: affine coordinates (X,Y) + * are such that: + * X = x / z^2 + * Y = y / z^3 + * For the point at infinity, z = 0. + * Each point thus admits many possible representations. + * + * Coordinates are represented in arrays of 32-bit integers, each holding + * 13 bits of data. Values may also be slightly greater than the modulus, + * but they will always be lower than twice the modulus. + */ +typedef struct { + uint32_t x[20]; + uint32_t y[20]; + uint32_t z[20]; +} p256_jacobian; + +/* + * Convert a point to affine coordinates: + * - If the point is the point at infinity, then all three coordinates + * are set to 0. + * - Otherwise, the 'z' coordinate is set to 1, and the 'x' and 'y' + * coordinates are the 'X' and 'Y' affine coordinates. + * The coordinates are guaranteed to be lower than the modulus. + */ +static void +p256_to_affine(p256_jacobian *P) +{ + uint32_t t1[20], t2[20]; + int i; + + /* + * Invert z with a modular exponentiation: the modulus is + * p = 2^256 - 2^224 + 2^192 + 2^96 - 1, and the exponent is + * p-2. Exponent bit pattern (from high to low) is: + * - 32 bits of value 1 + * - 31 bits of value 0 + * - 1 bit of value 1 + * - 96 bits of value 0 + * - 94 bits of value 1 + * - 1 bit of value 0 + * - 1 bit of value 1 + * Thus, we precompute z^(2^31-1) to speed things up. + * + * If z = 0 (point at infinity) then the modular exponentiation + * will yield 0, which leads to the expected result (all three + * coordinates set to 0). + */ + + /* + * A simple square-and-multiply for z^(2^31-1). We could save about + * two dozen multiplications here with an addition chain, but + * this would require a bit more code, and extra stack buffers. + */ + memcpy(t1, P->z, sizeof P->z); + for (i = 0; i < 30; i ++) { + square_f256(t1, t1); + mul_f256(t1, t1, P->z); + } + + /* + * Square-and-multiply. Apart from the squarings, we have a few + * multiplications to set bits to 1; we multiply by the original z + * for setting 1 bit, and by t1 for setting 31 bits. + */ + memcpy(t2, P->z, sizeof P->z); + for (i = 1; i < 256; i ++) { + square_f256(t2, t2); + switch (i) { + case 31: + case 190: + case 221: + case 252: + mul_f256(t2, t2, t1); + break; + case 63: + case 253: + case 255: + mul_f256(t2, t2, P->z); + break; + } + } + + /* + * Now that we have 1/z, multiply x by 1/z^2 and y by 1/z^3. + */ + mul_f256(t1, t2, t2); + mul_f256(P->x, t1, P->x); + mul_f256(t1, t1, t2); + mul_f256(P->y, t1, P->y); + reduce_final_f256(P->x); + reduce_final_f256(P->y); + + /* + * Multiply z by 1/z. If z = 0, then this will yield 0, otherwise + * this will set z to 1. + */ + mul_f256(P->z, P->z, t2); + reduce_final_f256(P->z); +} + +/* + * Double a point in P-256. This function works for all valid points, + * including the point at infinity. + */ +static void +p256_double(p256_jacobian *Q) +{ + /* + * Doubling formulas are: + * + * s = 4*x*y^2 + * m = 3*(x + z^2)*(x - z^2) + * x' = m^2 - 2*s + * y' = m*(s - x') - 8*y^4 + * z' = 2*y*z + * + * These formulas work for all points, including points of order 2 + * and points at infinity: + * - If y = 0 then z' = 0. But there is no such point in P-256 + * anyway. + * - If z = 0 then z' = 0. + */ + uint32_t t1[20], t2[20], t3[20], t4[20]; + int i; + + /* + * Compute z^2 in t1. + */ + square_f256(t1, Q->z); + + /* + * Compute x-z^2 in t2 and x+z^2 in t1. + */ + for (i = 0; i < 20; i ++) { + t2[i] = (F256[i] << 1) + Q->x[i] - t1[i]; + t1[i] += Q->x[i]; + } + norm13(t1, t1, 20); + norm13(t2, t2, 20); + + /* + * Compute 3*(x+z^2)*(x-z^2) in t1. + */ + mul_f256(t3, t1, t2); + for (i = 0; i < 20; i ++) { + t1[i] = MUL15(3, t3[i]); + } + norm13(t1, t1, 20); + + /* + * Compute 4*x*y^2 (in t2) and 2*y^2 (in t3). + */ + square_f256(t3, Q->y); + for (i = 0; i < 20; i ++) { + t3[i] <<= 1; + } + norm13(t3, t3, 20); + mul_f256(t2, Q->x, t3); + for (i = 0; i < 20; i ++) { + t2[i] <<= 1; + } + norm13(t2, t2, 20); + reduce_f256(t2); + + /* + * Compute x' = m^2 - 2*s. + */ + square_f256(Q->x, t1); + for (i = 0; i < 20; i ++) { + Q->x[i] += (F256[i] << 2) - (t2[i] << 1); + } + norm13(Q->x, Q->x, 20); + reduce_f256(Q->x); + + /* + * Compute z' = 2*y*z. + */ + mul_f256(t4, Q->y, Q->z); + for (i = 0; i < 20; i ++) { + Q->z[i] = t4[i] << 1; + } + norm13(Q->z, Q->z, 20); + reduce_f256(Q->z); + + /* + * Compute y' = m*(s - x') - 8*y^4. Note that we already have + * 2*y^2 in t3. + */ + for (i = 0; i < 20; i ++) { + t2[i] += (F256[i] << 1) - Q->x[i]; + } + norm13(t2, t2, 20); + mul_f256(Q->y, t1, t2); + square_f256(t4, t3); + for (i = 0; i < 20; i ++) { + Q->y[i] += (F256[i] << 2) - (t4[i] << 1); + } + norm13(Q->y, Q->y, 20); + reduce_f256(Q->y); +} + +/* + * Add point P2 to point P1. + * + * This function computes the wrong result in the following cases: + * + * - If P1 == 0 but P2 != 0 + * - If P1 != 0 but P2 == 0 + * - If P1 == P2 + * + * In all three cases, P1 is set to the point at infinity. + * + * Returned value is 0 if one of the following occurs: + * + * - P1 and P2 have the same Y coordinate + * - P1 == 0 and P2 == 0 + * - The Y coordinate of one of the points is 0 and the other point is + * the point at infinity. + * + * The third case cannot actually happen with valid points, since a point + * with Y == 0 is a point of order 2, and there is no point of order 2 on + * curve P-256. + * + * Therefore, assuming that P1 != 0 and P2 != 0 on input, then the caller + * can apply the following: + * + * - If the result is not the point at infinity, then it is correct. + * - Otherwise, if the returned value is 1, then this is a case of + * P1+P2 == 0, so the result is indeed the point at infinity. + * - Otherwise, P1 == P2, so a "double" operation should have been + * performed. + */ +static uint32_t +p256_add(p256_jacobian *P1, const p256_jacobian *P2) +{ + /* + * Addtions formulas are: + * + * u1 = x1 * z2^2 + * u2 = x2 * z1^2 + * s1 = y1 * z2^3 + * s2 = y2 * z1^3 + * h = u2 - u1 + * r = s2 - s1 + * x3 = r^2 - h^3 - 2 * u1 * h^2 + * y3 = r * (u1 * h^2 - x3) - s1 * h^3 + * z3 = h * z1 * z2 + */ + uint32_t t1[20], t2[20], t3[20], t4[20], t5[20], t6[20], t7[20]; + uint32_t ret; + int i; + + /* + * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3). + */ + square_f256(t3, P2->z); + mul_f256(t1, P1->x, t3); + mul_f256(t4, P2->z, t3); + mul_f256(t3, P1->y, t4); + + /* + * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). + */ + square_f256(t4, P1->z); + mul_f256(t2, P2->x, t4); + mul_f256(t5, P1->z, t4); + mul_f256(t4, P2->y, t5); + + /* + * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). + * We need to test whether r is zero, so we will do some extra + * reduce. + */ + for (i = 0; i < 20; i ++) { + t2[i] += (F256[i] << 1) - t1[i]; + t4[i] += (F256[i] << 1) - t3[i]; + } + norm13(t2, t2, 20); + norm13(t4, t4, 20); + reduce_f256(t4); + reduce_final_f256(t4); + ret = 0; + for (i = 0; i < 20; i ++) { + ret |= t4[i]; + } + ret = (ret | -ret) >> 31; + + /* + * Compute u1*h^2 (in t6) and h^3 (in t5); + */ + square_f256(t7, t2); + mul_f256(t6, t1, t7); + mul_f256(t5, t7, t2); + + /* + * Compute x3 = r^2 - h^3 - 2*u1*h^2. + */ + square_f256(P1->x, t4); + for (i = 0; i < 20; i ++) { + P1->x[i] += (F256[i] << 3) - t5[i] - (t6[i] << 1); + } + norm13(P1->x, P1->x, 20); + reduce_f256(P1->x); + + /* + * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. + */ + for (i = 0; i < 20; i ++) { + t6[i] += (F256[i] << 1) - P1->x[i]; + } + norm13(t6, t6, 20); + mul_f256(P1->y, t4, t6); + mul_f256(t1, t5, t3); + for (i = 0; i < 20; i ++) { + P1->y[i] += (F256[i] << 1) - t1[i]; + } + norm13(P1->y, P1->y, 20); + reduce_f256(P1->y); + + /* + * Compute z3 = h*z1*z2. + */ + mul_f256(t1, P1->z, P2->z); + mul_f256(P1->z, t1, t2); + + return ret; +} + +/* + * Add point P2 to point P1. This is a specialised function for the + * case when P2 is a non-zero point in affine coordinate. + * + * This function computes the wrong result in the following cases: + * + * - If P1 == 0 + * - If P1 == P2 + * + * In both cases, P1 is set to the point at infinity. + * + * Returned value is 0 if one of the following occurs: + * + * - P1 and P2 have the same Y coordinate + * - The Y coordinate of P2 is 0 and P1 is the point at infinity. + * + * The second case cannot actually happen with valid points, since a point + * with Y == 0 is a point of order 2, and there is no point of order 2 on + * curve P-256. + * + * Therefore, assuming that P1 != 0 on input, then the caller + * can apply the following: + * + * - If the result is not the point at infinity, then it is correct. + * - Otherwise, if the returned value is 1, then this is a case of + * P1+P2 == 0, so the result is indeed the point at infinity. + * - Otherwise, P1 == P2, so a "double" operation should have been + * performed. + */ +static uint32_t +p256_add_mixed(p256_jacobian *P1, const p256_jacobian *P2) +{ + /* + * Addtions formulas are: + * + * u1 = x1 + * u2 = x2 * z1^2 + * s1 = y1 + * s2 = y2 * z1^3 + * h = u2 - u1 + * r = s2 - s1 + * x3 = r^2 - h^3 - 2 * u1 * h^2 + * y3 = r * (u1 * h^2 - x3) - s1 * h^3 + * z3 = h * z1 + */ + uint32_t t1[20], t2[20], t3[20], t4[20], t5[20], t6[20], t7[20]; + uint32_t ret; + int i; + + /* + * Compute u1 = x1 (in t1) and s1 = y1 (in t3). + */ + memcpy(t1, P1->x, sizeof t1); + memcpy(t3, P1->y, sizeof t3); + + /* + * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). + */ + square_f256(t4, P1->z); + mul_f256(t2, P2->x, t4); + mul_f256(t5, P1->z, t4); + mul_f256(t4, P2->y, t5); + + /* + * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). + * We need to test whether r is zero, so we will do some extra + * reduce. + */ + for (i = 0; i < 20; i ++) { + t2[i] += (F256[i] << 1) - t1[i]; + t4[i] += (F256[i] << 1) - t3[i]; + } + norm13(t2, t2, 20); + norm13(t4, t4, 20); + reduce_f256(t4); + reduce_final_f256(t4); + ret = 0; + for (i = 0; i < 20; i ++) { + ret |= t4[i]; + } + ret = (ret | -ret) >> 31; + + /* + * Compute u1*h^2 (in t6) and h^3 (in t5); + */ + square_f256(t7, t2); + mul_f256(t6, t1, t7); + mul_f256(t5, t7, t2); + + /* + * Compute x3 = r^2 - h^3 - 2*u1*h^2. + */ + square_f256(P1->x, t4); + for (i = 0; i < 20; i ++) { + P1->x[i] += (F256[i] << 3) - t5[i] - (t6[i] << 1); + } + norm13(P1->x, P1->x, 20); + reduce_f256(P1->x); + + /* + * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. + */ + for (i = 0; i < 20; i ++) { + t6[i] += (F256[i] << 1) - P1->x[i]; + } + norm13(t6, t6, 20); + mul_f256(P1->y, t4, t6); + mul_f256(t1, t5, t3); + for (i = 0; i < 20; i ++) { + P1->y[i] += (F256[i] << 1) - t1[i]; + } + norm13(P1->y, P1->y, 20); + reduce_f256(P1->y); + + /* + * Compute z3 = h*z1*z2. + */ + mul_f256(P1->z, P1->z, t2); + + return ret; +} + +/* + * Decode a P-256 point. This function does not support the point at + * infinity. Returned value is 0 if the point is invalid, 1 otherwise. + */ +static uint32_t +p256_decode(p256_jacobian *P, const void *src, size_t len) +{ + const unsigned char *buf; + uint32_t tx[20], ty[20], t1[20], t2[20]; + uint32_t bad; + int i; + + if (len != 65) { + return 0; + } + buf = src; + + /* + * First byte must be 0x04 (uncompressed format). We could support + * "hybrid format" (first byte is 0x06 or 0x07, and encodes the + * least significant bit of the Y coordinate), but it is explicitly + * forbidden by RFC 5480 (section 2.2). + */ + bad = NEQ(buf[0], 0x04); + + /* + * Decode the coordinates, and check that they are both lower + * than the modulus. + */ + tx[19] = be8_to_le13(tx, buf + 1, 32); + ty[19] = be8_to_le13(ty, buf + 33, 32); + bad |= reduce_final_f256(tx); + bad |= reduce_final_f256(ty); + + /* + * Check curve equation. + */ + square_f256(t1, tx); + mul_f256(t1, tx, t1); + square_f256(t2, ty); + for (i = 0; i < 20; i ++) { + t1[i] += (F256[i] << 3) - MUL15(3, tx[i]) + P256_B[i] - t2[i]; + } + norm13(t1, t1, 20); + reduce_f256(t1); + reduce_final_f256(t1); + for (i = 0; i < 20; i ++) { + bad |= t1[i]; + } + + /* + * Copy coordinates to the point structure. + */ + memcpy(P->x, tx, sizeof tx); + memcpy(P->y, ty, sizeof ty); + memset(P->z, 0, sizeof P->z); + P->z[0] = 1; + return EQ(bad, 0); +} + +/* + * Encode a point into a buffer. This function assumes that the point is + * valid, in affine coordinates, and not the point at infinity. + */ +static void +p256_encode(void *dst, const p256_jacobian *P) +{ + unsigned char *buf; + + buf = dst; + buf[0] = 0x04; + le13_to_be8(buf + 1, 32, P->x); + le13_to_be8(buf + 33, 32, P->y); +} + +/* + * Multiply a curve point by an integer. The integer is assumed to be + * lower than the curve order, and the base point must not be the point + * at infinity. + */ +static void +p256_mul(p256_jacobian *P, const unsigned char *x, size_t xlen) +{ + /* + * qz is a flag that is initially 1, and remains equal to 1 + * as long as the point is the point at infinity. + * + * We use a 2-bit window to handle multiplier bits by pairs. + * The precomputed window really is the points P2 and P3. + */ + uint32_t qz; + p256_jacobian P2, P3, Q, T, U; + + /* + * Compute window values. + */ + P2 = *P; + p256_double(&P2); + P3 = *P; + p256_add(&P3, &P2); + + /* + * We start with Q = 0. We process multiplier bits 2 by 2. + */ + memset(&Q, 0, sizeof Q); + qz = 1; + while (xlen -- > 0) { + int k; + + for (k = 6; k >= 0; k -= 2) { + uint32_t bits; + uint32_t bnz; + + p256_double(&Q); + p256_double(&Q); + T = *P; + U = Q; + bits = (*x >> k) & (uint32_t)3; + bnz = NEQ(bits, 0); + CCOPY(EQ(bits, 2), &T, &P2, sizeof T); + CCOPY(EQ(bits, 3), &T, &P3, sizeof T); + p256_add(&U, &T); + CCOPY(bnz & qz, &Q, &T, sizeof Q); + CCOPY(bnz & ~qz, &Q, &U, sizeof Q); + qz &= ~bnz; + } + x ++; + } + *P = Q; +} + +/* + * Precomputed window: k*G points, where G is the curve generator, and k + * is an integer from 1 to 15 (inclusive). The X and Y coordinates of + * the point are encoded as 20 words of 13 bits each (little-endian + * order); 13-bit words are then grouped 2-by-2 into 32-bit words + * (little-endian order within each word). + */ +static const uint32_t Gwin[15][20] = { + + { 0x04C60296, 0x02721176, 0x19D00F4A, 0x102517AC, + 0x13B8037D, 0x0748103C, 0x1E730E56, 0x08481FE2, + 0x0F97012C, 0x00D605F4, 0x1DFA11F5, 0x0C801A0D, + 0x0F670CBB, 0x0AED0CC5, 0x115E0E33, 0x181F0785, + 0x13F514A7, 0x0FF30E3B, 0x17171E1A, 0x009F18D0 }, + + { 0x1B341978, 0x16911F11, 0x0D9A1A60, 0x1C4E1FC8, + 0x1E040969, 0x096A06B0, 0x091C0030, 0x09EF1A29, + 0x18C40D03, 0x00F91C9E, 0x13C313D1, 0x096F0748, + 0x011419E0, 0x1CC713A6, 0x1DD31DAD, 0x1EE80C36, + 0x1ECD0C69, 0x1A0800A4, 0x08861B8E, 0x000E1DD5 }, + + { 0x173F1D6C, 0x02CC06F1, 0x14C21FB4, 0x043D1EB6, + 0x0F3606B7, 0x1A971C59, 0x1BF71951, 0x01481323, + 0x068D0633, 0x00BD12F9, 0x13EA1032, 0x136209E8, + 0x1C1E19A7, 0x06C7013E, 0x06C10AB0, 0x14C908BB, + 0x05830CE1, 0x1FEF18DD, 0x00620998, 0x010E0D19 }, + + { 0x18180852, 0x0604111A, 0x0B771509, 0x1B6F0156, + 0x00181FE2, 0x1DCC0AF4, 0x16EF0659, 0x11F70E80, + 0x11A912D0, 0x01C414D2, 0x027618C6, 0x05840FC6, + 0x100215C4, 0x187E0C3B, 0x12771C96, 0x150C0B5D, + 0x0FF705FD, 0x07981C67, 0x1AD20C63, 0x01C11C55 }, + + { 0x1E8113ED, 0x0A940370, 0x12920215, 0x1FA31D6F, + 0x1F7C0C82, 0x10CD03F7, 0x02640560, 0x081A0B5E, + 0x1BD21151, 0x00A21642, 0x0D0B0DA4, 0x0176113F, + 0x04440D1D, 0x001A1360, 0x1068012F, 0x1F141E49, + 0x10DF136B, 0x0E4F162B, 0x0D44104A, 0x01C1105F }, + + { 0x011411A9, 0x01551A4F, 0x0ADA0C6B, 0x01BD0EC8, + 0x18120C74, 0x112F1778, 0x099202CB, 0x0C05124B, + 0x195316A4, 0x01600685, 0x1E3B1FE2, 0x189014E3, + 0x0B5E1FD7, 0x0E0311F8, 0x08E000F7, 0x174E00DE, + 0x160702DF, 0x1B5A15BF, 0x03A11237, 0x01D01704 }, + + { 0x0C3D12A3, 0x0C501C0C, 0x17AD1300, 0x1715003F, + 0x03F719F8, 0x18031ED8, 0x1D980667, 0x0F681896, + 0x1B7D00BF, 0x011C14CE, 0x0FA000B4, 0x1C3501B0, + 0x0D901C55, 0x06790C10, 0x029E0736, 0x0DEB0400, + 0x034F183A, 0x030619B4, 0x0DEF0033, 0x00E71AC7 }, + + { 0x1B7D1393, 0x1B3B1076, 0x0BED1B4D, 0x13011F3A, + 0x0E0E1238, 0x156A132B, 0x013A02D3, 0x160A0D01, + 0x1CED1EE9, 0x00C5165D, 0x184C157E, 0x08141A83, + 0x153C0DA5, 0x1ED70F9D, 0x05170D51, 0x02CF13B8, + 0x18AE1771, 0x1B04113F, 0x05EC11E9, 0x015A16B3 }, + + { 0x04A41EE0, 0x1D1412E4, 0x1C591D79, 0x118511B7, + 0x14F00ACB, 0x1AE31E1C, 0x049C0D51, 0x016E061E, + 0x1DB71EDF, 0x01D41A35, 0x0E8208FA, 0x14441293, + 0x011F1E85, 0x1D54137A, 0x026B114F, 0x151D0832, + 0x00A50964, 0x1F9C1E1C, 0x064B12C9, 0x005409D1 }, + + { 0x062B123F, 0x0C0D0501, 0x183704C3, 0x08E31120, + 0x0A2E0A6C, 0x14440FED, 0x090A0D1E, 0x13271964, + 0x0B590A3A, 0x019D1D9B, 0x05780773, 0x09770A91, + 0x0F770CA3, 0x053F19D4, 0x02C80DED, 0x1A761304, + 0x091E0DD9, 0x15D201B8, 0x151109AA, 0x010F0198 }, + + { 0x05E101D1, 0x072314DD, 0x045F1433, 0x1A041541, + 0x10B3142E, 0x01840736, 0x1C1B19DB, 0x098B0418, + 0x1DBC083B, 0x007D1444, 0x01511740, 0x11DD1F3A, + 0x04ED0E2F, 0x1B4B1A62, 0x10480D04, 0x09E911A2, + 0x04211AFA, 0x19140893, 0x04D60CC4, 0x01210648 }, + + { 0x112703C4, 0x018B1BA1, 0x164C1D50, 0x05160BE0, + 0x0BCC1830, 0x01CB1554, 0x13291732, 0x1B2B1918, + 0x0DED0817, 0x00E80775, 0x0A2401D3, 0x0BFE08B3, + 0x0E531199, 0x058616E9, 0x04770B91, 0x110F0C55, + 0x19C11554, 0x0BFB1159, 0x03541C38, 0x000E1C2D }, + + { 0x10390C01, 0x02BB0751, 0x0AC5098E, 0x096C17AB, + 0x03C90E28, 0x10BD18BF, 0x002E1F2D, 0x092B0986, + 0x1BD700AC, 0x002E1F20, 0x1E3D1FD8, 0x077718BB, + 0x06F919C4, 0x187407ED, 0x11370E14, 0x081E139C, + 0x00481ADB, 0x14AB0289, 0x066A0EBE, 0x00C70ED6 }, + + { 0x0694120B, 0x124E1CC9, 0x0E2F0570, 0x17CF081A, + 0x078906AC, 0x066D17CF, 0x1B3207F4, 0x0C5705E9, + 0x10001C38, 0x00A919DE, 0x06851375, 0x0F900BD8, + 0x080401BA, 0x0EEE0D42, 0x1B8B11EA, 0x0B4519F0, + 0x090F18C0, 0x062E1508, 0x0DD909F4, 0x01EB067C }, + + { 0x0CDC1D5F, 0x0D1818F9, 0x07781636, 0x125B18E8, + 0x0D7003AF, 0x13110099, 0x1D9B1899, 0x175C1EB7, + 0x0E34171A, 0x01E01153, 0x081A0F36, 0x0B391783, + 0x1D1F147E, 0x19CE16D7, 0x11511B21, 0x1F2C10F9, + 0x12CA0E51, 0x05A31D39, 0x171A192E, 0x016B0E4F } +}; + +/* + * Lookup one of the Gwin[] values, by index. This is constant-time. + */ +static void +lookup_Gwin(p256_jacobian *T, uint32_t idx) +{ + uint32_t xy[20]; + uint32_t k; + size_t u; + + memset(xy, 0, sizeof xy); + for (k = 0; k < 15; k ++) { + uint32_t m; + + m = -EQ(idx, k + 1); + for (u = 0; u < 20; u ++) { + xy[u] |= m & Gwin[k][u]; + } + } + for (u = 0; u < 10; u ++) { + T->x[(u << 1) + 0] = xy[u] & 0xFFFF; + T->x[(u << 1) + 1] = xy[u] >> 16; + T->y[(u << 1) + 0] = xy[u + 10] & 0xFFFF; + T->y[(u << 1) + 1] = xy[u + 10] >> 16; + } + memset(T->z, 0, sizeof T->z); + T->z[0] = 1; +} + +/* + * Multiply the generator by an integer. The integer is assumed non-zero + * and lower than the curve order. + */ +static void +p256_mulgen(p256_jacobian *P, const unsigned char *x, size_t xlen) +{ + /* + * qz is a flag that is initially 1, and remains equal to 1 + * as long as the point is the point at infinity. + * + * We use a 4-bit window to handle multiplier bits by groups + * of 4. The precomputed window is constant static data, with + * points in affine coordinates; we use a constant-time lookup. + */ + p256_jacobian Q; + uint32_t qz; + + memset(&Q, 0, sizeof Q); + qz = 1; + while (xlen -- > 0) { + int k; + unsigned bx; + + bx = *x ++; + for (k = 0; k < 2; k ++) { + uint32_t bits; + uint32_t bnz; + p256_jacobian T, U; + + p256_double(&Q); + p256_double(&Q); + p256_double(&Q); + p256_double(&Q); + bits = (bx >> 4) & 0x0F; + bnz = NEQ(bits, 0); + lookup_Gwin(&T, bits); + U = Q; + p256_add_mixed(&U, &T); + CCOPY(bnz & qz, &Q, &T, sizeof Q); + CCOPY(bnz & ~qz, &Q, &U, sizeof Q); + qz &= ~bnz; + bx <<= 4; + } + } + *P = Q; +} + +static const unsigned char P256_G[] = { + 0x04, 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, + 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, + 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, + 0x98, 0xC2, 0x96, 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, + 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, 0x2B, + 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, + 0x68, 0x37, 0xBF, 0x51, 0xF5 +}; + +static const unsigned char P256_N[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, + 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, + 0x25, 0x51 +}; + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + (void)curve; + *len = sizeof P256_G; + return P256_G; +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + (void)curve; + *len = sizeof P256_N; + return P256_N; +} + +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 1; +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *x, size_t xlen, int curve) +{ + uint32_t r; + p256_jacobian P; + + (void)curve; + if (Glen != 65) { + return 0; + } + r = p256_decode(&P, G, Glen); + p256_mul(&P, x, xlen); + p256_to_affine(&P); + p256_encode(G, &P); + return r; +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + p256_jacobian P; + + (void)curve; + p256_mulgen(&P, x, xlen); + p256_to_affine(&P); + p256_encode(R, &P); + return 65; +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + p256_jacobian P, Q; + uint32_t r, t, z; + int i; + + (void)curve; + if (len != 65) { + return 0; + } + r = p256_decode(&P, A, len); + p256_mul(&P, x, xlen); + if (B == NULL) { + p256_mulgen(&Q, y, ylen); + } else { + r &= p256_decode(&Q, B, len); + p256_mul(&Q, y, ylen); + } + + /* + * The final addition may fail in case both points are equal. + */ + t = p256_add(&P, &Q); + reduce_final_f256(P.z); + z = 0; + for (i = 0; i < 20; i ++) { + z |= P.z[i]; + } + z = EQ(z, 0); + p256_double(&Q); + + /* + * If z is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we + * have the following: + * + * z = 0, t = 0 return P (normal addition) + * z = 0, t = 1 return P (normal addition) + * z = 1, t = 0 return Q (a 'double' case) + * z = 1, t = 1 report an error (P+Q = 0) + */ + CCOPY(z & ~t, &P, &Q, sizeof Q); + p256_to_affine(&P); + p256_encode(A, &P); + r &= ~(z & t); + return r; +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_p256_m15 = { + (uint32_t)0x00800000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_p256_m31.c b/BearSSL-OG/libbearssl/src/ec/ec_p256_m31.c new file mode 100644 index 0000000..b185937 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_p256_m31.c @@ -0,0 +1,1469 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * If BR_NO_ARITH_SHIFT is undefined, or defined to 0, then we _assume_ + * that right-shifting a signed negative integer copies the sign bit + * (arithmetic right-shift). This is "implementation-defined behaviour", + * i.e. it is not undefined, but it may differ between compilers. Each + * compiler is supposed to document its behaviour in that respect. GCC + * explicitly defines that an arithmetic right shift is used. We expect + * all other compilers to do the same, because underlying CPU offer an + * arithmetic right shift opcode that could not be used otherwise. + */ +#if BR_NO_ARITH_SHIFT +#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ + | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) +#define ARSHW(x, n) (((uint64_t)(x) >> (n)) \ + | ((-((uint64_t)(x) >> 63)) << (64 - (n)))) +#else +#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) +#define ARSHW(x, n) ((*(int64_t *)&(x)) >> (n)) +#endif + +/* + * Convert an integer from unsigned big-endian encoding to a sequence of + * 30-bit words in little-endian order. The final "partial" word is + * returned. + */ +static uint32_t +be8_to_le30(uint32_t *dst, const unsigned char *src, size_t len) +{ + uint32_t acc; + int acc_len; + + acc = 0; + acc_len = 0; + while (len -- > 0) { + uint32_t b; + + b = src[len]; + if (acc_len < 22) { + acc |= b << acc_len; + acc_len += 8; + } else { + *dst ++ = (acc | (b << acc_len)) & 0x3FFFFFFF; + acc = b >> (30 - acc_len); + acc_len -= 22; + } + } + return acc; +} + +/* + * Convert an integer (30-bit words, little-endian) to unsigned + * big-endian encoding. The total encoding length is provided; all + * the destination bytes will be filled. + */ +static void +le30_to_be8(unsigned char *dst, size_t len, const uint32_t *src) +{ + uint32_t acc; + int acc_len; + + acc = 0; + acc_len = 0; + while (len -- > 0) { + if (acc_len < 8) { + uint32_t w; + + w = *src ++; + dst[len] = (unsigned char)(acc | (w << acc_len)); + acc = w >> (8 - acc_len); + acc_len += 22; + } else { + dst[len] = (unsigned char)acc; + acc >>= 8; + acc_len -= 8; + } + } +} + +/* + * Multiply two integers. Source integers are represented as arrays of + * nine 30-bit words, for values up to 2^270-1. Result is encoded over + * 18 words of 30 bits each. + */ +static void +mul9(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + /* + * Maximum intermediate result is no more than + * 10376293531797946367, which fits in 64 bits. Reason: + * + * 10376293531797946367 = 9 * (2^30-1)^2 + 9663676406 + * 10376293531797946367 < 9663676407 * 2^30 + * + * Thus, adding together 9 products of 30-bit integers, with + * a carry of at most 9663676406, yields an integer that fits + * on 64 bits and generates a carry of at most 9663676406. + */ + uint64_t t[17]; + uint64_t cc; + int i; + + t[ 0] = MUL31(a[0], b[0]); + t[ 1] = MUL31(a[0], b[1]) + + MUL31(a[1], b[0]); + t[ 2] = MUL31(a[0], b[2]) + + MUL31(a[1], b[1]) + + MUL31(a[2], b[0]); + t[ 3] = MUL31(a[0], b[3]) + + MUL31(a[1], b[2]) + + MUL31(a[2], b[1]) + + MUL31(a[3], b[0]); + t[ 4] = MUL31(a[0], b[4]) + + MUL31(a[1], b[3]) + + MUL31(a[2], b[2]) + + MUL31(a[3], b[1]) + + MUL31(a[4], b[0]); + t[ 5] = MUL31(a[0], b[5]) + + MUL31(a[1], b[4]) + + MUL31(a[2], b[3]) + + MUL31(a[3], b[2]) + + MUL31(a[4], b[1]) + + MUL31(a[5], b[0]); + t[ 6] = MUL31(a[0], b[6]) + + MUL31(a[1], b[5]) + + MUL31(a[2], b[4]) + + MUL31(a[3], b[3]) + + MUL31(a[4], b[2]) + + MUL31(a[5], b[1]) + + MUL31(a[6], b[0]); + t[ 7] = MUL31(a[0], b[7]) + + MUL31(a[1], b[6]) + + MUL31(a[2], b[5]) + + MUL31(a[3], b[4]) + + MUL31(a[4], b[3]) + + MUL31(a[5], b[2]) + + MUL31(a[6], b[1]) + + MUL31(a[7], b[0]); + t[ 8] = MUL31(a[0], b[8]) + + MUL31(a[1], b[7]) + + MUL31(a[2], b[6]) + + MUL31(a[3], b[5]) + + MUL31(a[4], b[4]) + + MUL31(a[5], b[3]) + + MUL31(a[6], b[2]) + + MUL31(a[7], b[1]) + + MUL31(a[8], b[0]); + t[ 9] = MUL31(a[1], b[8]) + + MUL31(a[2], b[7]) + + MUL31(a[3], b[6]) + + MUL31(a[4], b[5]) + + MUL31(a[5], b[4]) + + MUL31(a[6], b[3]) + + MUL31(a[7], b[2]) + + MUL31(a[8], b[1]); + t[10] = MUL31(a[2], b[8]) + + MUL31(a[3], b[7]) + + MUL31(a[4], b[6]) + + MUL31(a[5], b[5]) + + MUL31(a[6], b[4]) + + MUL31(a[7], b[3]) + + MUL31(a[8], b[2]); + t[11] = MUL31(a[3], b[8]) + + MUL31(a[4], b[7]) + + MUL31(a[5], b[6]) + + MUL31(a[6], b[5]) + + MUL31(a[7], b[4]) + + MUL31(a[8], b[3]); + t[12] = MUL31(a[4], b[8]) + + MUL31(a[5], b[7]) + + MUL31(a[6], b[6]) + + MUL31(a[7], b[5]) + + MUL31(a[8], b[4]); + t[13] = MUL31(a[5], b[8]) + + MUL31(a[6], b[7]) + + MUL31(a[7], b[6]) + + MUL31(a[8], b[5]); + t[14] = MUL31(a[6], b[8]) + + MUL31(a[7], b[7]) + + MUL31(a[8], b[6]); + t[15] = MUL31(a[7], b[8]) + + MUL31(a[8], b[7]); + t[16] = MUL31(a[8], b[8]); + + /* + * Propagate carries. + */ + cc = 0; + for (i = 0; i < 17; i ++) { + uint64_t w; + + w = t[i] + cc; + d[i] = (uint32_t)w & 0x3FFFFFFF; + cc = w >> 30; + } + d[17] = (uint32_t)cc; +} + +/* + * Square a 270-bit integer, represented as an array of nine 30-bit words. + * Result uses 18 words of 30 bits each. + */ +static void +square9(uint32_t *d, const uint32_t *a) +{ + uint64_t t[17]; + uint64_t cc; + int i; + + t[ 0] = MUL31(a[0], a[0]); + t[ 1] = ((MUL31(a[0], a[1])) << 1); + t[ 2] = MUL31(a[1], a[1]) + + ((MUL31(a[0], a[2])) << 1); + t[ 3] = ((MUL31(a[0], a[3]) + + MUL31(a[1], a[2])) << 1); + t[ 4] = MUL31(a[2], a[2]) + + ((MUL31(a[0], a[4]) + + MUL31(a[1], a[3])) << 1); + t[ 5] = ((MUL31(a[0], a[5]) + + MUL31(a[1], a[4]) + + MUL31(a[2], a[3])) << 1); + t[ 6] = MUL31(a[3], a[3]) + + ((MUL31(a[0], a[6]) + + MUL31(a[1], a[5]) + + MUL31(a[2], a[4])) << 1); + t[ 7] = ((MUL31(a[0], a[7]) + + MUL31(a[1], a[6]) + + MUL31(a[2], a[5]) + + MUL31(a[3], a[4])) << 1); + t[ 8] = MUL31(a[4], a[4]) + + ((MUL31(a[0], a[8]) + + MUL31(a[1], a[7]) + + MUL31(a[2], a[6]) + + MUL31(a[3], a[5])) << 1); + t[ 9] = ((MUL31(a[1], a[8]) + + MUL31(a[2], a[7]) + + MUL31(a[3], a[6]) + + MUL31(a[4], a[5])) << 1); + t[10] = MUL31(a[5], a[5]) + + ((MUL31(a[2], a[8]) + + MUL31(a[3], a[7]) + + MUL31(a[4], a[6])) << 1); + t[11] = ((MUL31(a[3], a[8]) + + MUL31(a[4], a[7]) + + MUL31(a[5], a[6])) << 1); + t[12] = MUL31(a[6], a[6]) + + ((MUL31(a[4], a[8]) + + MUL31(a[5], a[7])) << 1); + t[13] = ((MUL31(a[5], a[8]) + + MUL31(a[6], a[7])) << 1); + t[14] = MUL31(a[7], a[7]) + + ((MUL31(a[6], a[8])) << 1); + t[15] = ((MUL31(a[7], a[8])) << 1); + t[16] = MUL31(a[8], a[8]); + + /* + * Propagate carries. + */ + cc = 0; + for (i = 0; i < 17; i ++) { + uint64_t w; + + w = t[i] + cc; + d[i] = (uint32_t)w & 0x3FFFFFFF; + cc = w >> 30; + } + d[17] = (uint32_t)cc; +} + +/* + * Base field modulus for P-256. + */ +static const uint32_t F256[] = { + + 0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF, 0x0000003F, 0x00000000, + 0x00000000, 0x00001000, 0x3FFFC000, 0x0000FFFF +}; + +/* + * The 'b' curve equation coefficient for P-256. + */ +static const uint32_t P256_B[] = { + + 0x27D2604B, 0x2F38F0F8, 0x053B0F63, 0x0741AC33, 0x1886BC65, + 0x2EF555DA, 0x293E7B3E, 0x0D762A8E, 0x00005AC6 +}; + +/* + * Addition in the field. Source operands shall fit on 257 bits; output + * will be lower than twice the modulus. + */ +static void +add_f256(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + uint32_t w, cc; + int i; + + cc = 0; + for (i = 0; i < 9; i ++) { + w = a[i] + b[i] + cc; + d[i] = w & 0x3FFFFFFF; + cc = w >> 30; + } + w >>= 16; + d[8] &= 0xFFFF; + d[3] -= w << 6; + d[6] -= w << 12; + d[7] += w << 14; + cc = w; + for (i = 0; i < 9; i ++) { + w = d[i] + cc; + d[i] = w & 0x3FFFFFFF; + cc = ARSH(w, 30); + } +} + +/* + * Subtraction in the field. Source operands shall be smaller than twice + * the modulus; the result will fulfil the same property. + */ +static void +sub_f256(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + uint32_t w, cc; + int i; + + /* + * We really compute a - b + 2*p to make sure that the result is + * positive. + */ + w = a[0] - b[0] - 0x00002; + d[0] = w & 0x3FFFFFFF; + w = a[1] - b[1] + ARSH(w, 30); + d[1] = w & 0x3FFFFFFF; + w = a[2] - b[2] + ARSH(w, 30); + d[2] = w & 0x3FFFFFFF; + w = a[3] - b[3] + ARSH(w, 30) + 0x00080; + d[3] = w & 0x3FFFFFFF; + w = a[4] - b[4] + ARSH(w, 30); + d[4] = w & 0x3FFFFFFF; + w = a[5] - b[5] + ARSH(w, 30); + d[5] = w & 0x3FFFFFFF; + w = a[6] - b[6] + ARSH(w, 30) + 0x02000; + d[6] = w & 0x3FFFFFFF; + w = a[7] - b[7] + ARSH(w, 30) - 0x08000; + d[7] = w & 0x3FFFFFFF; + w = a[8] - b[8] + ARSH(w, 30) + 0x20000; + d[8] = w & 0xFFFF; + w >>= 16; + d[8] &= 0xFFFF; + d[3] -= w << 6; + d[6] -= w << 12; + d[7] += w << 14; + cc = w; + for (i = 0; i < 9; i ++) { + w = d[i] + cc; + d[i] = w & 0x3FFFFFFF; + cc = ARSH(w, 30); + } +} + +/* + * Compute a multiplication in F256. Source operands shall be less than + * twice the modulus. + */ +static void +mul_f256(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + uint32_t t[18]; + uint64_t s[18]; + uint64_t cc, x; + uint32_t z, c; + int i; + + mul9(t, a, b); + + /* + * Modular reduction: each high word in added/subtracted where + * necessary. + * + * The modulus is: + * p = 2^256 - 2^224 + 2^192 + 2^96 - 1 + * Therefore: + * 2^256 = 2^224 - 2^192 - 2^96 + 1 mod p + * + * For a word x at bit offset n (n >= 256), we have: + * x*2^n = x*2^(n-32) - x*2^(n-64) + * - x*2^(n - 160) + x*2^(n-256) mod p + * + * Thus, we can nullify the high word if we reinject it at some + * proper emplacements. + * + * We use 64-bit intermediate words to allow for carries to + * accumulate easily, before performing the final propagation. + */ + for (i = 0; i < 18; i ++) { + s[i] = t[i]; + } + + for (i = 17; i >= 9; i --) { + uint64_t y; + + y = s[i]; + s[i - 1] += ARSHW(y, 2); + s[i - 2] += (y << 28) & 0x3FFFFFFF; + s[i - 2] -= ARSHW(y, 4); + s[i - 3] -= (y << 26) & 0x3FFFFFFF; + s[i - 5] -= ARSHW(y, 10); + s[i - 6] -= (y << 20) & 0x3FFFFFFF; + s[i - 8] += ARSHW(y, 16); + s[i - 9] += (y << 14) & 0x3FFFFFFF; + } + + /* + * Carry propagation must be signed. Moreover, we may have overdone + * it a bit, and obtain a negative result. + * + * The loop above ran 9 times; each time, each word was augmented + * by at most one extra word (in absolute value). Thus, the top + * word must in fine fit in 39 bits, so the carry below will fit + * on 9 bits. + */ + cc = 0; + for (i = 0; i < 9; i ++) { + x = s[i] + cc; + d[i] = (uint32_t)x & 0x3FFFFFFF; + cc = ARSHW(x, 30); + } + + /* + * All nine words fit on 30 bits, but there may be an extra + * carry for a few bits (at most 9), and that carry may be + * negative. Moreover, we want the result to fit on 257 bits. + * The two lines below ensure that the word in d[] has length + * 256 bits, and the (signed) carry (beyond 2^256) is in cc. The + * significant length of cc is less than 24 bits, so we will be + * able to switch to 32-bit operations. + */ + cc = ARSHW(x, 16); + d[8] &= 0xFFFF; + + /* + * One extra round of reduction, for cc*2^256, which means + * adding cc*(2^224-2^192-2^96+1) to a 256-bit (nonnegative) + * value. If cc is negative, then it may happen (rarely, but + * not neglectibly so) that the result would be negative. In + * order to avoid that, if cc is negative, then we add the + * modulus once. Note that if cc is negative, then propagating + * that carry must yield a value lower than the modulus, so + * adding the modulus once will keep the final result under + * twice the modulus. + */ + z = (uint32_t)cc; + d[3] -= z << 6; + d[6] -= (z << 12) & 0x3FFFFFFF; + d[7] -= ARSH(z, 18); + d[7] += (z << 14) & 0x3FFFFFFF; + d[8] += ARSH(z, 16); + c = z >> 31; + d[0] -= c; + d[3] += c << 6; + d[6] += c << 12; + d[7] -= c << 14; + d[8] += c << 16; + for (i = 0; i < 9; i ++) { + uint32_t w; + + w = d[i] + z; + d[i] = w & 0x3FFFFFFF; + z = ARSH(w, 30); + } +} + +/* + * Compute a square in F256. Source operand shall be less than + * twice the modulus. + */ +static void +square_f256(uint32_t *d, const uint32_t *a) +{ + uint32_t t[18]; + uint64_t s[18]; + uint64_t cc, x; + uint32_t z, c; + int i; + + square9(t, a); + + /* + * Modular reduction: each high word in added/subtracted where + * necessary. + * + * The modulus is: + * p = 2^256 - 2^224 + 2^192 + 2^96 - 1 + * Therefore: + * 2^256 = 2^224 - 2^192 - 2^96 + 1 mod p + * + * For a word x at bit offset n (n >= 256), we have: + * x*2^n = x*2^(n-32) - x*2^(n-64) + * - x*2^(n - 160) + x*2^(n-256) mod p + * + * Thus, we can nullify the high word if we reinject it at some + * proper emplacements. + * + * We use 64-bit intermediate words to allow for carries to + * accumulate easily, before performing the final propagation. + */ + for (i = 0; i < 18; i ++) { + s[i] = t[i]; + } + + for (i = 17; i >= 9; i --) { + uint64_t y; + + y = s[i]; + s[i - 1] += ARSHW(y, 2); + s[i - 2] += (y << 28) & 0x3FFFFFFF; + s[i - 2] -= ARSHW(y, 4); + s[i - 3] -= (y << 26) & 0x3FFFFFFF; + s[i - 5] -= ARSHW(y, 10); + s[i - 6] -= (y << 20) & 0x3FFFFFFF; + s[i - 8] += ARSHW(y, 16); + s[i - 9] += (y << 14) & 0x3FFFFFFF; + } + + /* + * Carry propagation must be signed. Moreover, we may have overdone + * it a bit, and obtain a negative result. + * + * The loop above ran 9 times; each time, each word was augmented + * by at most one extra word (in absolute value). Thus, the top + * word must in fine fit in 39 bits, so the carry below will fit + * on 9 bits. + */ + cc = 0; + for (i = 0; i < 9; i ++) { + x = s[i] + cc; + d[i] = (uint32_t)x & 0x3FFFFFFF; + cc = ARSHW(x, 30); + } + + /* + * All nine words fit on 30 bits, but there may be an extra + * carry for a few bits (at most 9), and that carry may be + * negative. Moreover, we want the result to fit on 257 bits. + * The two lines below ensure that the word in d[] has length + * 256 bits, and the (signed) carry (beyond 2^256) is in cc. The + * significant length of cc is less than 24 bits, so we will be + * able to switch to 32-bit operations. + */ + cc = ARSHW(x, 16); + d[8] &= 0xFFFF; + + /* + * One extra round of reduction, for cc*2^256, which means + * adding cc*(2^224-2^192-2^96+1) to a 256-bit (nonnegative) + * value. If cc is negative, then it may happen (rarely, but + * not neglectibly so) that the result would be negative. In + * order to avoid that, if cc is negative, then we add the + * modulus once. Note that if cc is negative, then propagating + * that carry must yield a value lower than the modulus, so + * adding the modulus once will keep the final result under + * twice the modulus. + */ + z = (uint32_t)cc; + d[3] -= z << 6; + d[6] -= (z << 12) & 0x3FFFFFFF; + d[7] -= ARSH(z, 18); + d[7] += (z << 14) & 0x3FFFFFFF; + d[8] += ARSH(z, 16); + c = z >> 31; + d[0] -= c; + d[3] += c << 6; + d[6] += c << 12; + d[7] -= c << 14; + d[8] += c << 16; + for (i = 0; i < 9; i ++) { + uint32_t w; + + w = d[i] + z; + d[i] = w & 0x3FFFFFFF; + z = ARSH(w, 30); + } +} + +/* + * Perform a "final reduction" in field F256 (field for curve P-256). + * The source value must be less than twice the modulus. If the value + * is not lower than the modulus, then the modulus is subtracted and + * this function returns 1; otherwise, it leaves it untouched and it + * returns 0. + */ +static uint32_t +reduce_final_f256(uint32_t *d) +{ + uint32_t t[9]; + uint32_t cc; + int i; + + cc = 0; + for (i = 0; i < 9; i ++) { + uint32_t w; + + w = d[i] - F256[i] - cc; + cc = w >> 31; + t[i] = w & 0x3FFFFFFF; + } + cc ^= 1; + CCOPY(cc, d, t, sizeof t); + return cc; +} + +/* + * Jacobian coordinates for a point in P-256: affine coordinates (X,Y) + * are such that: + * X = x / z^2 + * Y = y / z^3 + * For the point at infinity, z = 0. + * Each point thus admits many possible representations. + * + * Coordinates are represented in arrays of 32-bit integers, each holding + * 30 bits of data. Values may also be slightly greater than the modulus, + * but they will always be lower than twice the modulus. + */ +typedef struct { + uint32_t x[9]; + uint32_t y[9]; + uint32_t z[9]; +} p256_jacobian; + +/* + * Convert a point to affine coordinates: + * - If the point is the point at infinity, then all three coordinates + * are set to 0. + * - Otherwise, the 'z' coordinate is set to 1, and the 'x' and 'y' + * coordinates are the 'X' and 'Y' affine coordinates. + * The coordinates are guaranteed to be lower than the modulus. + */ +static void +p256_to_affine(p256_jacobian *P) +{ + uint32_t t1[9], t2[9]; + int i; + + /* + * Invert z with a modular exponentiation: the modulus is + * p = 2^256 - 2^224 + 2^192 + 2^96 - 1, and the exponent is + * p-2. Exponent bit pattern (from high to low) is: + * - 32 bits of value 1 + * - 31 bits of value 0 + * - 1 bit of value 1 + * - 96 bits of value 0 + * - 94 bits of value 1 + * - 1 bit of value 0 + * - 1 bit of value 1 + * Thus, we precompute z^(2^31-1) to speed things up. + * + * If z = 0 (point at infinity) then the modular exponentiation + * will yield 0, which leads to the expected result (all three + * coordinates set to 0). + */ + + /* + * A simple square-and-multiply for z^(2^31-1). We could save about + * two dozen multiplications here with an addition chain, but + * this would require a bit more code, and extra stack buffers. + */ + memcpy(t1, P->z, sizeof P->z); + for (i = 0; i < 30; i ++) { + square_f256(t1, t1); + mul_f256(t1, t1, P->z); + } + + /* + * Square-and-multiply. Apart from the squarings, we have a few + * multiplications to set bits to 1; we multiply by the original z + * for setting 1 bit, and by t1 for setting 31 bits. + */ + memcpy(t2, P->z, sizeof P->z); + for (i = 1; i < 256; i ++) { + square_f256(t2, t2); + switch (i) { + case 31: + case 190: + case 221: + case 252: + mul_f256(t2, t2, t1); + break; + case 63: + case 253: + case 255: + mul_f256(t2, t2, P->z); + break; + } + } + + /* + * Now that we have 1/z, multiply x by 1/z^2 and y by 1/z^3. + */ + mul_f256(t1, t2, t2); + mul_f256(P->x, t1, P->x); + mul_f256(t1, t1, t2); + mul_f256(P->y, t1, P->y); + reduce_final_f256(P->x); + reduce_final_f256(P->y); + + /* + * Multiply z by 1/z. If z = 0, then this will yield 0, otherwise + * this will set z to 1. + */ + mul_f256(P->z, P->z, t2); + reduce_final_f256(P->z); +} + +/* + * Double a point in P-256. This function works for all valid points, + * including the point at infinity. + */ +static void +p256_double(p256_jacobian *Q) +{ + /* + * Doubling formulas are: + * + * s = 4*x*y^2 + * m = 3*(x + z^2)*(x - z^2) + * x' = m^2 - 2*s + * y' = m*(s - x') - 8*y^4 + * z' = 2*y*z + * + * These formulas work for all points, including points of order 2 + * and points at infinity: + * - If y = 0 then z' = 0. But there is no such point in P-256 + * anyway. + * - If z = 0 then z' = 0. + */ + uint32_t t1[9], t2[9], t3[9], t4[9]; + + /* + * Compute z^2 in t1. + */ + square_f256(t1, Q->z); + + /* + * Compute x-z^2 in t2 and x+z^2 in t1. + */ + add_f256(t2, Q->x, t1); + sub_f256(t1, Q->x, t1); + + /* + * Compute 3*(x+z^2)*(x-z^2) in t1. + */ + mul_f256(t3, t1, t2); + add_f256(t1, t3, t3); + add_f256(t1, t3, t1); + + /* + * Compute 4*x*y^2 (in t2) and 2*y^2 (in t3). + */ + square_f256(t3, Q->y); + add_f256(t3, t3, t3); + mul_f256(t2, Q->x, t3); + add_f256(t2, t2, t2); + + /* + * Compute x' = m^2 - 2*s. + */ + square_f256(Q->x, t1); + sub_f256(Q->x, Q->x, t2); + sub_f256(Q->x, Q->x, t2); + + /* + * Compute z' = 2*y*z. + */ + mul_f256(t4, Q->y, Q->z); + add_f256(Q->z, t4, t4); + + /* + * Compute y' = m*(s - x') - 8*y^4. Note that we already have + * 2*y^2 in t3. + */ + sub_f256(t2, t2, Q->x); + mul_f256(Q->y, t1, t2); + square_f256(t4, t3); + add_f256(t4, t4, t4); + sub_f256(Q->y, Q->y, t4); +} + +/* + * Add point P2 to point P1. + * + * This function computes the wrong result in the following cases: + * + * - If P1 == 0 but P2 != 0 + * - If P1 != 0 but P2 == 0 + * - If P1 == P2 + * + * In all three cases, P1 is set to the point at infinity. + * + * Returned value is 0 if one of the following occurs: + * + * - P1 and P2 have the same Y coordinate + * - P1 == 0 and P2 == 0 + * - The Y coordinate of one of the points is 0 and the other point is + * the point at infinity. + * + * The third case cannot actually happen with valid points, since a point + * with Y == 0 is a point of order 2, and there is no point of order 2 on + * curve P-256. + * + * Therefore, assuming that P1 != 0 and P2 != 0 on input, then the caller + * can apply the following: + * + * - If the result is not the point at infinity, then it is correct. + * - Otherwise, if the returned value is 1, then this is a case of + * P1+P2 == 0, so the result is indeed the point at infinity. + * - Otherwise, P1 == P2, so a "double" operation should have been + * performed. + */ +static uint32_t +p256_add(p256_jacobian *P1, const p256_jacobian *P2) +{ + /* + * Addtions formulas are: + * + * u1 = x1 * z2^2 + * u2 = x2 * z1^2 + * s1 = y1 * z2^3 + * s2 = y2 * z1^3 + * h = u2 - u1 + * r = s2 - s1 + * x3 = r^2 - h^3 - 2 * u1 * h^2 + * y3 = r * (u1 * h^2 - x3) - s1 * h^3 + * z3 = h * z1 * z2 + */ + uint32_t t1[9], t2[9], t3[9], t4[9], t5[9], t6[9], t7[9]; + uint32_t ret; + int i; + + /* + * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3). + */ + square_f256(t3, P2->z); + mul_f256(t1, P1->x, t3); + mul_f256(t4, P2->z, t3); + mul_f256(t3, P1->y, t4); + + /* + * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). + */ + square_f256(t4, P1->z); + mul_f256(t2, P2->x, t4); + mul_f256(t5, P1->z, t4); + mul_f256(t4, P2->y, t5); + + /* + * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). + * We need to test whether r is zero, so we will do some extra + * reduce. + */ + sub_f256(t2, t2, t1); + sub_f256(t4, t4, t3); + reduce_final_f256(t4); + ret = 0; + for (i = 0; i < 9; i ++) { + ret |= t4[i]; + } + ret = (ret | -ret) >> 31; + + /* + * Compute u1*h^2 (in t6) and h^3 (in t5); + */ + square_f256(t7, t2); + mul_f256(t6, t1, t7); + mul_f256(t5, t7, t2); + + /* + * Compute x3 = r^2 - h^3 - 2*u1*h^2. + */ + square_f256(P1->x, t4); + sub_f256(P1->x, P1->x, t5); + sub_f256(P1->x, P1->x, t6); + sub_f256(P1->x, P1->x, t6); + + /* + * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. + */ + sub_f256(t6, t6, P1->x); + mul_f256(P1->y, t4, t6); + mul_f256(t1, t5, t3); + sub_f256(P1->y, P1->y, t1); + + /* + * Compute z3 = h*z1*z2. + */ + mul_f256(t1, P1->z, P2->z); + mul_f256(P1->z, t1, t2); + + return ret; +} + +/* + * Add point P2 to point P1. This is a specialised function for the + * case when P2 is a non-zero point in affine coordinate. + * + * This function computes the wrong result in the following cases: + * + * - If P1 == 0 + * - If P1 == P2 + * + * In both cases, P1 is set to the point at infinity. + * + * Returned value is 0 if one of the following occurs: + * + * - P1 and P2 have the same Y coordinate + * - The Y coordinate of P2 is 0 and P1 is the point at infinity. + * + * The second case cannot actually happen with valid points, since a point + * with Y == 0 is a point of order 2, and there is no point of order 2 on + * curve P-256. + * + * Therefore, assuming that P1 != 0 on input, then the caller + * can apply the following: + * + * - If the result is not the point at infinity, then it is correct. + * - Otherwise, if the returned value is 1, then this is a case of + * P1+P2 == 0, so the result is indeed the point at infinity. + * - Otherwise, P1 == P2, so a "double" operation should have been + * performed. + */ +static uint32_t +p256_add_mixed(p256_jacobian *P1, const p256_jacobian *P2) +{ + /* + * Addtions formulas are: + * + * u1 = x1 + * u2 = x2 * z1^2 + * s1 = y1 + * s2 = y2 * z1^3 + * h = u2 - u1 + * r = s2 - s1 + * x3 = r^2 - h^3 - 2 * u1 * h^2 + * y3 = r * (u1 * h^2 - x3) - s1 * h^3 + * z3 = h * z1 + */ + uint32_t t1[9], t2[9], t3[9], t4[9], t5[9], t6[9], t7[9]; + uint32_t ret; + int i; + + /* + * Compute u1 = x1 (in t1) and s1 = y1 (in t3). + */ + memcpy(t1, P1->x, sizeof t1); + memcpy(t3, P1->y, sizeof t3); + + /* + * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). + */ + square_f256(t4, P1->z); + mul_f256(t2, P2->x, t4); + mul_f256(t5, P1->z, t4); + mul_f256(t4, P2->y, t5); + + /* + * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). + * We need to test whether r is zero, so we will do some extra + * reduce. + */ + sub_f256(t2, t2, t1); + sub_f256(t4, t4, t3); + reduce_final_f256(t4); + ret = 0; + for (i = 0; i < 9; i ++) { + ret |= t4[i]; + } + ret = (ret | -ret) >> 31; + + /* + * Compute u1*h^2 (in t6) and h^3 (in t5); + */ + square_f256(t7, t2); + mul_f256(t6, t1, t7); + mul_f256(t5, t7, t2); + + /* + * Compute x3 = r^2 - h^3 - 2*u1*h^2. + */ + square_f256(P1->x, t4); + sub_f256(P1->x, P1->x, t5); + sub_f256(P1->x, P1->x, t6); + sub_f256(P1->x, P1->x, t6); + + /* + * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. + */ + sub_f256(t6, t6, P1->x); + mul_f256(P1->y, t4, t6); + mul_f256(t1, t5, t3); + sub_f256(P1->y, P1->y, t1); + + /* + * Compute z3 = h*z1*z2. + */ + mul_f256(P1->z, P1->z, t2); + + return ret; +} + +/* + * Decode a P-256 point. This function does not support the point at + * infinity. Returned value is 0 if the point is invalid, 1 otherwise. + */ +static uint32_t +p256_decode(p256_jacobian *P, const void *src, size_t len) +{ + const unsigned char *buf; + uint32_t tx[9], ty[9], t1[9], t2[9]; + uint32_t bad; + int i; + + if (len != 65) { + return 0; + } + buf = src; + + /* + * First byte must be 0x04 (uncompressed format). We could support + * "hybrid format" (first byte is 0x06 or 0x07, and encodes the + * least significant bit of the Y coordinate), but it is explicitly + * forbidden by RFC 5480 (section 2.2). + */ + bad = NEQ(buf[0], 0x04); + + /* + * Decode the coordinates, and check that they are both lower + * than the modulus. + */ + tx[8] = be8_to_le30(tx, buf + 1, 32); + ty[8] = be8_to_le30(ty, buf + 33, 32); + bad |= reduce_final_f256(tx); + bad |= reduce_final_f256(ty); + + /* + * Check curve equation. + */ + square_f256(t1, tx); + mul_f256(t1, tx, t1); + square_f256(t2, ty); + sub_f256(t1, t1, tx); + sub_f256(t1, t1, tx); + sub_f256(t1, t1, tx); + add_f256(t1, t1, P256_B); + sub_f256(t1, t1, t2); + reduce_final_f256(t1); + for (i = 0; i < 9; i ++) { + bad |= t1[i]; + } + + /* + * Copy coordinates to the point structure. + */ + memcpy(P->x, tx, sizeof tx); + memcpy(P->y, ty, sizeof ty); + memset(P->z, 0, sizeof P->z); + P->z[0] = 1; + return EQ(bad, 0); +} + +/* + * Encode a point into a buffer. This function assumes that the point is + * valid, in affine coordinates, and not the point at infinity. + */ +static void +p256_encode(void *dst, const p256_jacobian *P) +{ + unsigned char *buf; + + buf = dst; + buf[0] = 0x04; + le30_to_be8(buf + 1, 32, P->x); + le30_to_be8(buf + 33, 32, P->y); +} + +/* + * Multiply a curve point by an integer. The integer is assumed to be + * lower than the curve order, and the base point must not be the point + * at infinity. + */ +static void +p256_mul(p256_jacobian *P, const unsigned char *x, size_t xlen) +{ + /* + * qz is a flag that is initially 1, and remains equal to 1 + * as long as the point is the point at infinity. + * + * We use a 2-bit window to handle multiplier bits by pairs. + * The precomputed window really is the points P2 and P3. + */ + uint32_t qz; + p256_jacobian P2, P3, Q, T, U; + + /* + * Compute window values. + */ + P2 = *P; + p256_double(&P2); + P3 = *P; + p256_add(&P3, &P2); + + /* + * We start with Q = 0. We process multiplier bits 2 by 2. + */ + memset(&Q, 0, sizeof Q); + qz = 1; + while (xlen -- > 0) { + int k; + + for (k = 6; k >= 0; k -= 2) { + uint32_t bits; + uint32_t bnz; + + p256_double(&Q); + p256_double(&Q); + T = *P; + U = Q; + bits = (*x >> k) & (uint32_t)3; + bnz = NEQ(bits, 0); + CCOPY(EQ(bits, 2), &T, &P2, sizeof T); + CCOPY(EQ(bits, 3), &T, &P3, sizeof T); + p256_add(&U, &T); + CCOPY(bnz & qz, &Q, &T, sizeof Q); + CCOPY(bnz & ~qz, &Q, &U, sizeof Q); + qz &= ~bnz; + } + x ++; + } + *P = Q; +} + +/* + * Precomputed window: k*G points, where G is the curve generator, and k + * is an integer from 1 to 15 (inclusive). The X and Y coordinates of + * the point are encoded as 9 words of 30 bits each (little-endian + * order). + */ +static const uint32_t Gwin[15][18] = { + + { 0x1898C296, 0x1284E517, 0x1EB33A0F, 0x00DF604B, + 0x2440F277, 0x339B958E, 0x04247F8B, 0x347CB84B, + 0x00006B17, 0x37BF51F5, 0x2ED901A0, 0x3315ECEC, + 0x338CD5DA, 0x0F9E162B, 0x1FAD29F0, 0x27F9B8EE, + 0x10B8BF86, 0x00004FE3 }, + + { 0x07669978, 0x182D23F1, 0x3F21B35A, 0x225A789D, + 0x351AC3C0, 0x08E00C12, 0x34F7E8A5, 0x1EC62340, + 0x00007CF2, 0x227873D1, 0x3812DE74, 0x0E982299, + 0x1F6B798F, 0x3430DBBA, 0x366B1A7D, 0x2D040293, + 0x154436E3, 0x00000777 }, + + { 0x06E7FD6C, 0x2D05986F, 0x3ADA985F, 0x31ADC87B, + 0x0BF165E6, 0x1FBE5475, 0x30A44C8F, 0x3934698C, + 0x00005ECB, 0x227D5032, 0x29E6C49E, 0x04FB83D9, + 0x0AAC0D8E, 0x24A2ECD8, 0x2C1B3869, 0x0FF7E374, + 0x19031266, 0x00008734 }, + + { 0x2B030852, 0x024C0911, 0x05596EF5, 0x07F8B6DE, + 0x262BD003, 0x3779967B, 0x08FBBA02, 0x128D4CB4, + 0x0000E253, 0x184ED8C6, 0x310B08FC, 0x30EE0055, + 0x3F25B0FC, 0x062D764E, 0x3FB97F6A, 0x33CC719D, + 0x15D69318, 0x0000E0F1 }, + + { 0x03D033ED, 0x05552837, 0x35BE5242, 0x2320BF47, + 0x268FDFEF, 0x13215821, 0x140D2D78, 0x02DE9454, + 0x00005159, 0x3DA16DA4, 0x0742ED13, 0x0D80888D, + 0x004BC035, 0x0A79260D, 0x06FCDAFE, 0x2727D8AE, + 0x1F6A2412, 0x0000E0C1 }, + + { 0x3C2291A9, 0x1AC2ABA4, 0x3B215B4C, 0x131D037A, + 0x17DDE302, 0x0C90B2E2, 0x0602C92D, 0x05CA9DA9, + 0x0000B01A, 0x0FC77FE2, 0x35F1214E, 0x07E16BDF, + 0x003DDC07, 0x2703791C, 0x3038B7EE, 0x3DAD56FE, + 0x041D0C8D, 0x0000E85C }, + + { 0x3187B2A3, 0x0018A1C0, 0x00FEF5B3, 0x3E7E2E2A, + 0x01FB607E, 0x2CC199F0, 0x37B4625B, 0x0EDBE82F, + 0x00008E53, 0x01F400B4, 0x15786A1B, 0x3041B21C, + 0x31CD8CF2, 0x35900053, 0x1A7E0E9B, 0x318366D0, + 0x076F780C, 0x000073EB }, + + { 0x1B6FB393, 0x13767707, 0x3CE97DBB, 0x348E2603, + 0x354CADC1, 0x09D0B4EA, 0x1B053404, 0x1DE76FBA, + 0x000062D9, 0x0F09957E, 0x295029A8, 0x3E76A78D, + 0x3B547DAE, 0x27CEE0A2, 0x0575DC45, 0x1D8244FF, + 0x332F647A, 0x0000AD5A }, + + { 0x10949EE0, 0x1E7A292E, 0x06DF8B3D, 0x02B2E30B, + 0x31F8729E, 0x24E35475, 0x30B71878, 0x35EDBFB7, + 0x0000EA68, 0x0DD048FA, 0x21688929, 0x0DE823FE, + 0x1C53FAA9, 0x0EA0C84D, 0x052A592A, 0x1FCE7870, + 0x11325CB2, 0x00002A27 }, + + { 0x04C5723F, 0x30D81A50, 0x048306E4, 0x329B11C7, + 0x223FB545, 0x085347A8, 0x2993E591, 0x1B5ACA8E, + 0x0000CEF6, 0x04AF0773, 0x28D2EEA9, 0x2751EEEC, + 0x037B4A7F, 0x3B4C1059, 0x08F37674, 0x2AE906E1, + 0x18A88A6A, 0x00008786 }, + + { 0x34BC21D1, 0x0CCE474D, 0x15048BF4, 0x1D0BB409, + 0x021CDA16, 0x20DE76C3, 0x34C59063, 0x04EDE20E, + 0x00003ED1, 0x282A3740, 0x0BE3BBF3, 0x29889DAE, + 0x03413697, 0x34C68A09, 0x210EBE93, 0x0C8A224C, + 0x0826B331, 0x00009099 }, + + { 0x0624E3C4, 0x140317BA, 0x2F82C99D, 0x260C0A2C, + 0x25D55179, 0x194DCC83, 0x3D95E462, 0x356F6A05, + 0x0000741D, 0x0D4481D3, 0x2657FC8B, 0x1BA5CA71, + 0x3AE44B0D, 0x07B1548E, 0x0E0D5522, 0x05FDC567, + 0x2D1AA70E, 0x00000770 }, + + { 0x06072C01, 0x23857675, 0x1EAD58A9, 0x0B8A12D9, + 0x1EE2FC79, 0x0177CB61, 0x0495A618, 0x20DEB82B, + 0x0000177C, 0x2FC7BFD8, 0x310EEF8B, 0x1FB4DF39, + 0x3B8530E8, 0x0F4E7226, 0x0246B6D0, 0x2A558A24, + 0x163353AF, 0x000063BB }, + + { 0x24D2920B, 0x1C249DCC, 0x2069C5E5, 0x09AB2F9E, + 0x36DF3CF1, 0x1991FD0C, 0x062B97A7, 0x1E80070E, + 0x000054E7, 0x20D0B375, 0x2E9F20BD, 0x35090081, + 0x1C7A9DDC, 0x22E7C371, 0x087E3016, 0x03175421, + 0x3C6ECA7D, 0x0000F599 }, + + { 0x259B9D5F, 0x0D9A318F, 0x23A0EF16, 0x00EBE4B7, + 0x088265AE, 0x2CDE2666, 0x2BAE7ADF, 0x1371A5C6, + 0x0000F045, 0x0D034F36, 0x1F967378, 0x1B5FA3F4, + 0x0EC8739D, 0x1643E62A, 0x1653947E, 0x22D1F4E6, + 0x0FB8D64B, 0x0000B5B9 } +}; + +/* + * Lookup one of the Gwin[] values, by index. This is constant-time. + */ +static void +lookup_Gwin(p256_jacobian *T, uint32_t idx) +{ + uint32_t xy[18]; + uint32_t k; + size_t u; + + memset(xy, 0, sizeof xy); + for (k = 0; k < 15; k ++) { + uint32_t m; + + m = -EQ(idx, k + 1); + for (u = 0; u < 18; u ++) { + xy[u] |= m & Gwin[k][u]; + } + } + memcpy(T->x, &xy[0], sizeof T->x); + memcpy(T->y, &xy[9], sizeof T->y); + memset(T->z, 0, sizeof T->z); + T->z[0] = 1; +} + +/* + * Multiply the generator by an integer. The integer is assumed non-zero + * and lower than the curve order. + */ +static void +p256_mulgen(p256_jacobian *P, const unsigned char *x, size_t xlen) +{ + /* + * qz is a flag that is initially 1, and remains equal to 1 + * as long as the point is the point at infinity. + * + * We use a 4-bit window to handle multiplier bits by groups + * of 4. The precomputed window is constant static data, with + * points in affine coordinates; we use a constant-time lookup. + */ + p256_jacobian Q; + uint32_t qz; + + memset(&Q, 0, sizeof Q); + qz = 1; + while (xlen -- > 0) { + int k; + unsigned bx; + + bx = *x ++; + for (k = 0; k < 2; k ++) { + uint32_t bits; + uint32_t bnz; + p256_jacobian T, U; + + p256_double(&Q); + p256_double(&Q); + p256_double(&Q); + p256_double(&Q); + bits = (bx >> 4) & 0x0F; + bnz = NEQ(bits, 0); + lookup_Gwin(&T, bits); + U = Q; + p256_add_mixed(&U, &T); + CCOPY(bnz & qz, &Q, &T, sizeof Q); + CCOPY(bnz & ~qz, &Q, &U, sizeof Q); + qz &= ~bnz; + bx <<= 4; + } + } + *P = Q; +} + +static const unsigned char P256_G[] = { + 0x04, 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, + 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, + 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, + 0x98, 0xC2, 0x96, 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, + 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, 0x2B, + 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, + 0x68, 0x37, 0xBF, 0x51, 0xF5 +}; + +static const unsigned char P256_N[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, + 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, + 0x25, 0x51 +}; + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + (void)curve; + *len = sizeof P256_G; + return P256_G; +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + (void)curve; + *len = sizeof P256_N; + return P256_N; +} + +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 1; +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *x, size_t xlen, int curve) +{ + uint32_t r; + p256_jacobian P; + + (void)curve; + if (Glen != 65) { + return 0; + } + r = p256_decode(&P, G, Glen); + p256_mul(&P, x, xlen); + p256_to_affine(&P); + p256_encode(G, &P); + return r; +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + p256_jacobian P; + + (void)curve; + p256_mulgen(&P, x, xlen); + p256_to_affine(&P); + p256_encode(R, &P); + return 65; +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + p256_jacobian P, Q; + uint32_t r, t, z; + int i; + + (void)curve; + if (len != 65) { + return 0; + } + r = p256_decode(&P, A, len); + p256_mul(&P, x, xlen); + if (B == NULL) { + p256_mulgen(&Q, y, ylen); + } else { + r &= p256_decode(&Q, B, len); + p256_mul(&Q, y, ylen); + } + + /* + * The final addition may fail in case both points are equal. + */ + t = p256_add(&P, &Q); + reduce_final_f256(P.z); + z = 0; + for (i = 0; i < 9; i ++) { + z |= P.z[i]; + } + z = EQ(z, 0); + p256_double(&Q); + + /* + * If z is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we + * have the following: + * + * z = 0, t = 0 return P (normal addition) + * z = 0, t = 1 return P (normal addition) + * z = 1, t = 0 return Q (a 'double' case) + * z = 1, t = 1 report an error (P+Q = 0) + */ + CCOPY(z & ~t, &P, &Q, sizeof Q); + p256_to_affine(&P); + p256_encode(A, &P); + r &= ~(z & t); + return r; +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_p256_m31 = { + (uint32_t)0x00800000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_p256_m62.c b/BearSSL-OG/libbearssl/src/ec/ec_p256_m62.c new file mode 100644 index 0000000..a431790 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_p256_m62.c @@ -0,0 +1,1765 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +#if BR_UMUL128 +#include +#endif + +static const unsigned char P256_G[] = { + 0x04, 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, + 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, + 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, + 0x98, 0xC2, 0x96, 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, + 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, 0x2B, + 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, + 0x68, 0x37, 0xBF, 0x51, 0xF5 +}; + +static const unsigned char P256_N[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, + 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, + 0x25, 0x51 +}; + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + (void)curve; + *len = sizeof P256_G; + return P256_G; +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + (void)curve; + *len = sizeof P256_N; + return P256_N; +} + +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 1; +} + +/* + * A field element is encoded as five 64-bit integers, in basis 2^52. + * Limbs may occasionally exceed 2^52. + * + * A _partially reduced_ value is such that the following hold: + * - top limb is less than 2^48 + 2^30 + * - the other limbs fit on 53 bits each + * In particular, such a value is less than twice the modulus p. + */ + +#define BIT(n) ((uint64_t)1 << (n)) +#define MASK48 (BIT(48) - BIT(0)) +#define MASK52 (BIT(52) - BIT(0)) + +/* R = 2^260 mod p */ +static const uint64_t F256_R[] = { + 0x0000000000010, 0xF000000000000, 0xFFFFFFFFFFFFF, + 0xFFEFFFFFFFFFF, 0x00000000FFFFF +}; + +/* Curve equation is y^2 = x^3 - 3*x + B. This constant is B*R mod p + (Montgomery representation of B). */ +static const uint64_t P256_B_MONTY[] = { + 0xDF6229C4BDDFD, 0xCA8843090D89C, 0x212ED6ACF005C, + 0x83415A220ABF7, 0x0C30061DD4874 +}; + +/* + * Addition in the field. Carry propagation is not performed. + * On input, limbs may be up to 63 bits each; on output, they will + * be up to one bit more than on input. + */ +static inline void +f256_add(uint64_t *d, const uint64_t *a, const uint64_t *b) +{ + d[0] = a[0] + b[0]; + d[1] = a[1] + b[1]; + d[2] = a[2] + b[2]; + d[3] = a[3] + b[3]; + d[4] = a[4] + b[4]; +} + +/* + * Partially reduce the provided value. + * Input: limbs can go up to 61 bits each. + * Output: partially reduced. + */ +static inline void +f256_partial_reduce(uint64_t *a) +{ + uint64_t w, cc, s; + + /* + * Propagate carries. + */ + w = a[0]; + a[0] = w & MASK52; + cc = w >> 52; + w = a[1] + cc; + a[1] = w & MASK52; + cc = w >> 52; + w = a[2] + cc; + a[2] = w & MASK52; + cc = w >> 52; + w = a[3] + cc; + a[3] = w & MASK52; + cc = w >> 52; + a[4] += cc; + + s = a[4] >> 48; /* s < 2^14 */ + a[0] += s; /* a[0] < 2^52 + 2^14 */ + w = a[1] - (s << 44); + a[1] = w & MASK52; /* a[1] < 2^52 */ + cc = -(w >> 52) & 0xFFF; /* cc < 16 */ + w = a[2] - cc; + a[2] = w & MASK52; /* a[2] < 2^52 */ + cc = w >> 63; /* cc = 0 or 1 */ + w = a[3] - cc - (s << 36); + a[3] = w & MASK52; /* a[3] < 2^52 */ + cc = w >> 63; /* cc = 0 or 1 */ + w = a[4] & MASK48; + a[4] = w + (s << 16) - cc; /* a[4] < 2^48 + 2^30 */ +} + +/* + * Subtraction in the field. + * Input: limbs must fit on 60 bits each; in particular, the complete + * integer will be less than 2^268 + 2^217. + * Output: partially reduced. + */ +static inline void +f256_sub(uint64_t *d, const uint64_t *a, const uint64_t *b) +{ + uint64_t t[5], w, s, cc; + + /* + * We compute d = 2^13*p + a - b; this ensures a positive + * intermediate value. + * + * Each individual addition/subtraction may yield a positive or + * negative result; thus, we need to handle a signed carry, thus + * with sign extension. We prefer not to use signed types (int64_t) + * because conversion from unsigned to signed is cumbersome (a + * direct cast with the top bit set is undefined behavior; instead, + * we have to use pointer aliasing, using the guaranteed properties + * of exact-width types, but this requires the compiler to optimize + * away the writes and reads from RAM), and right-shifting a + * signed negative value is implementation-defined. Therefore, + * we use a custom sign extension. + */ + + w = a[0] - b[0] - BIT(13); + t[0] = w & MASK52; + cc = w >> 52; + cc |= -(cc & BIT(11)); + w = a[1] - b[1] + cc; + t[1] = w & MASK52; + cc = w >> 52; + cc |= -(cc & BIT(11)); + w = a[2] - b[2] + cc; + t[2] = (w & MASK52) + BIT(5); + cc = w >> 52; + cc |= -(cc & BIT(11)); + w = a[3] - b[3] + cc; + t[3] = (w & MASK52) + BIT(49); + cc = w >> 52; + cc |= -(cc & BIT(11)); + t[4] = (BIT(61) - BIT(29)) + a[4] - b[4] + cc; + + /* + * Perform partial reduction. Rule is: + * 2^256 = 2^224 - 2^192 - 2^96 + 1 mod p + * + * At that point: + * 0 <= t[0] <= 2^52 - 1 + * 0 <= t[1] <= 2^52 - 1 + * 2^5 <= t[2] <= 2^52 + 2^5 - 1 + * 2^49 <= t[3] <= 2^52 + 2^49 - 1 + * 2^59 < t[4] <= 2^61 + 2^60 - 2^29 + * + * Thus, the value 's' (t[4] / 2^48) will be necessarily + * greater than 2048, and less than 12288. + */ + s = t[4] >> 48; + + d[0] = t[0] + s; /* d[0] <= 2^52 + 12287 */ + w = t[1] - (s << 44); + d[1] = w & MASK52; /* d[1] <= 2^52 - 1 */ + cc = -(w >> 52) & 0xFFF; /* cc <= 48 */ + w = t[2] - cc; + cc = w >> 63; /* cc = 0 or 1 */ + d[2] = w + (cc << 52); /* d[2] <= 2^52 + 31 */ + w = t[3] - cc - (s << 36); + cc = w >> 63; /* cc = 0 or 1 */ + d[3] = w + (cc << 52); /* t[3] <= 2^52 + 2^49 - 1 */ + d[4] = (t[4] & MASK48) + (s << 16) - cc; /* d[4] < 2^48 + 2^30 */ + + /* + * If s = 0, then none of the limbs is modified, and there cannot + * be an overflow; if s != 0, then (s << 16) > cc, and there is + * no overflow either. + */ +} + +/* + * Montgomery multiplication in the field. + * Input: limbs must fit on 56 bits each. + * Output: partially reduced. + */ +static void +f256_montymul(uint64_t *d, const uint64_t *a, const uint64_t *b) +{ +#if BR_INT128 + + int i; + uint64_t t[5]; + + t[0] = 0; + t[1] = 0; + t[2] = 0; + t[3] = 0; + t[4] = 0; + for (i = 0; i < 5; i ++) { + uint64_t x, f, cc, w, s; + unsigned __int128 z; + + /* + * Since limbs of a[] and b[] fit on 56 bits each, + * each individual product fits on 112 bits. Also, + * the factor f fits on 52 bits, so f<<48 fits on + * 112 bits too. This guarantees that carries (cc) + * will fit on 62 bits, thus no overflow. + * + * The operations below compute: + * t <- (t + x*b + f*p) / 2^64 + */ + x = a[i]; + z = (unsigned __int128)b[0] * (unsigned __int128)x + + (unsigned __int128)t[0]; + f = (uint64_t)z & MASK52; + cc = (uint64_t)(z >> 52); + z = (unsigned __int128)b[1] * (unsigned __int128)x + + (unsigned __int128)t[1] + cc + + ((unsigned __int128)f << 44); + t[0] = (uint64_t)z & MASK52; + cc = (uint64_t)(z >> 52); + z = (unsigned __int128)b[2] * (unsigned __int128)x + + (unsigned __int128)t[2] + cc; + t[1] = (uint64_t)z & MASK52; + cc = (uint64_t)(z >> 52); + z = (unsigned __int128)b[3] * (unsigned __int128)x + + (unsigned __int128)t[3] + cc + + ((unsigned __int128)f << 36); + t[2] = (uint64_t)z & MASK52; + cc = (uint64_t)(z >> 52); + z = (unsigned __int128)b[4] * (unsigned __int128)x + + (unsigned __int128)t[4] + cc + + ((unsigned __int128)f << 48) + - ((unsigned __int128)f << 16); + t[3] = (uint64_t)z & MASK52; + t[4] = (uint64_t)(z >> 52); + + /* + * t[4] may be up to 62 bits here; we need to do a + * partial reduction. Note that limbs t[0] to t[3] + * fit on 52 bits each. + */ + s = t[4] >> 48; /* s < 2^14 */ + t[0] += s; /* t[0] < 2^52 + 2^14 */ + w = t[1] - (s << 44); + t[1] = w & MASK52; /* t[1] < 2^52 */ + cc = -(w >> 52) & 0xFFF; /* cc < 16 */ + w = t[2] - cc; + t[2] = w & MASK52; /* t[2] < 2^52 */ + cc = w >> 63; /* cc = 0 or 1 */ + w = t[3] - cc - (s << 36); + t[3] = w & MASK52; /* t[3] < 2^52 */ + cc = w >> 63; /* cc = 0 or 1 */ + w = t[4] & MASK48; + t[4] = w + (s << 16) - cc; /* t[4] < 2^48 + 2^30 */ + + /* + * The final t[4] cannot overflow because cc is 0 or 1, + * and cc can be 1 only if s != 0. + */ + } + + d[0] = t[0]; + d[1] = t[1]; + d[2] = t[2]; + d[3] = t[3]; + d[4] = t[4]; + +#elif BR_UMUL128 + + int i; + uint64_t t[5]; + + t[0] = 0; + t[1] = 0; + t[2] = 0; + t[3] = 0; + t[4] = 0; + for (i = 0; i < 5; i ++) { + uint64_t x, f, cc, w, s, zh, zl; + unsigned char k; + + /* + * Since limbs of a[] and b[] fit on 56 bits each, + * each individual product fits on 112 bits. Also, + * the factor f fits on 52 bits, so f<<48 fits on + * 112 bits too. This guarantees that carries (cc) + * will fit on 62 bits, thus no overflow. + * + * The operations below compute: + * t <- (t + x*b + f*p) / 2^64 + */ + x = a[i]; + zl = _umul128(b[0], x, &zh); + k = _addcarry_u64(0, t[0], zl, &zl); + (void)_addcarry_u64(k, 0, zh, &zh); + f = zl & MASK52; + cc = (zl >> 52) | (zh << 12); + + zl = _umul128(b[1], x, &zh); + k = _addcarry_u64(0, t[1], zl, &zl); + (void)_addcarry_u64(k, 0, zh, &zh); + k = _addcarry_u64(0, cc, zl, &zl); + (void)_addcarry_u64(k, 0, zh, &zh); + k = _addcarry_u64(0, f << 44, zl, &zl); + (void)_addcarry_u64(k, f >> 20, zh, &zh); + t[0] = zl & MASK52; + cc = (zl >> 52) | (zh << 12); + + zl = _umul128(b[2], x, &zh); + k = _addcarry_u64(0, t[2], zl, &zl); + (void)_addcarry_u64(k, 0, zh, &zh); + k = _addcarry_u64(0, cc, zl, &zl); + (void)_addcarry_u64(k, 0, zh, &zh); + t[1] = zl & MASK52; + cc = (zl >> 52) | (zh << 12); + + zl = _umul128(b[3], x, &zh); + k = _addcarry_u64(0, t[3], zl, &zl); + (void)_addcarry_u64(k, 0, zh, &zh); + k = _addcarry_u64(0, cc, zl, &zl); + (void)_addcarry_u64(k, 0, zh, &zh); + k = _addcarry_u64(0, f << 36, zl, &zl); + (void)_addcarry_u64(k, f >> 28, zh, &zh); + t[2] = zl & MASK52; + cc = (zl >> 52) | (zh << 12); + + zl = _umul128(b[4], x, &zh); + k = _addcarry_u64(0, t[4], zl, &zl); + (void)_addcarry_u64(k, 0, zh, &zh); + k = _addcarry_u64(0, cc, zl, &zl); + (void)_addcarry_u64(k, 0, zh, &zh); + k = _addcarry_u64(0, f << 48, zl, &zl); + (void)_addcarry_u64(k, f >> 16, zh, &zh); + k = _subborrow_u64(0, zl, f << 16, &zl); + (void)_subborrow_u64(k, zh, f >> 48, &zh); + t[3] = zl & MASK52; + t[4] = (zl >> 52) | (zh << 12); + + /* + * t[4] may be up to 62 bits here; we need to do a + * partial reduction. Note that limbs t[0] to t[3] + * fit on 52 bits each. + */ + s = t[4] >> 48; /* s < 2^14 */ + t[0] += s; /* t[0] < 2^52 + 2^14 */ + w = t[1] - (s << 44); + t[1] = w & MASK52; /* t[1] < 2^52 */ + cc = -(w >> 52) & 0xFFF; /* cc < 16 */ + w = t[2] - cc; + t[2] = w & MASK52; /* t[2] < 2^52 */ + cc = w >> 63; /* cc = 0 or 1 */ + w = t[3] - cc - (s << 36); + t[3] = w & MASK52; /* t[3] < 2^52 */ + cc = w >> 63; /* cc = 0 or 1 */ + w = t[4] & MASK48; + t[4] = w + (s << 16) - cc; /* t[4] < 2^48 + 2^30 */ + + /* + * The final t[4] cannot overflow because cc is 0 or 1, + * and cc can be 1 only if s != 0. + */ + } + + d[0] = t[0]; + d[1] = t[1]; + d[2] = t[2]; + d[3] = t[3]; + d[4] = t[4]; + +#endif +} + +/* + * Montgomery squaring in the field; currently a basic wrapper around + * multiplication (inline, should be optimized away). + * TODO: see if some extra speed can be gained here. + */ +static inline void +f256_montysquare(uint64_t *d, const uint64_t *a) +{ + f256_montymul(d, a, a); +} + +/* + * Convert to Montgomery representation. + */ +static void +f256_tomonty(uint64_t *d, const uint64_t *a) +{ + /* + * R2 = 2^520 mod p. + * If R = 2^260 mod p, then R2 = R^2 mod p; and the Montgomery + * multiplication of a by R2 is: a*R2/R = a*R mod p, i.e. the + * conversion to Montgomery representation. + */ + static const uint64_t R2[] = { + 0x0000000000300, 0xFFFFFFFF00000, 0xFFFFEFFFFFFFB, + 0xFDFFFFFFFFFFF, 0x0000004FFFFFF + }; + + f256_montymul(d, a, R2); +} + +/* + * Convert from Montgomery representation. + */ +static void +f256_frommonty(uint64_t *d, const uint64_t *a) +{ + /* + * Montgomery multiplication by 1 is division by 2^260 modulo p. + */ + static const uint64_t one[] = { 1, 0, 0, 0, 0 }; + + f256_montymul(d, a, one); +} + +/* + * Inversion in the field. If the source value is 0 modulo p, then this + * returns 0 or p. This function uses Montgomery representation. + */ +static void +f256_invert(uint64_t *d, const uint64_t *a) +{ + /* + * We compute a^(p-2) mod p. The exponent pattern (from high to + * low) is: + * - 32 bits of value 1 + * - 31 bits of value 0 + * - 1 bit of value 1 + * - 96 bits of value 0 + * - 94 bits of value 1 + * - 1 bit of value 0 + * - 1 bit of value 1 + * To speed up the square-and-multiply algorithm, we precompute + * a^(2^31-1). + */ + + uint64_t r[5], t[5]; + int i; + + memcpy(t, a, sizeof t); + for (i = 0; i < 30; i ++) { + f256_montysquare(t, t); + f256_montymul(t, t, a); + } + + memcpy(r, t, sizeof t); + for (i = 224; i >= 0; i --) { + f256_montysquare(r, r); + switch (i) { + case 0: + case 2: + case 192: + case 224: + f256_montymul(r, r, a); + break; + case 3: + case 34: + case 65: + f256_montymul(r, r, t); + break; + } + } + memcpy(d, r, sizeof r); +} + +/* + * Finalize reduction. + * Input value should be partially reduced. + * On output, limbs a[0] to a[3] fit on 52 bits each, limb a[4] fits + * on 48 bits, and the integer is less than p. + */ +static inline void +f256_final_reduce(uint64_t *a) +{ + uint64_t r[5], t[5], w, cc; + int i; + + /* + * Propagate carries to ensure that limbs 0 to 3 fit on 52 bits. + */ + cc = 0; + for (i = 0; i < 5; i ++) { + w = a[i] + cc; + r[i] = w & MASK52; + cc = w >> 52; + } + + /* + * We compute t = r + (2^256 - p) = r + 2^224 - 2^192 - 2^96 + 1. + * If t < 2^256, then r < p, and we return r. Otherwise, we + * want to return r - p = t - 2^256. + */ + + /* + * Add 2^224 + 1, and propagate carries to ensure that limbs + * t[0] to t[3] fit in 52 bits each. + */ + w = r[0] + 1; + t[0] = w & MASK52; + cc = w >> 52; + w = r[1] + cc; + t[1] = w & MASK52; + cc = w >> 52; + w = r[2] + cc; + t[2] = w & MASK52; + cc = w >> 52; + w = r[3] + cc; + t[3] = w & MASK52; + cc = w >> 52; + t[4] = r[4] + cc + BIT(16); + + /* + * Subtract 2^192 + 2^96. Since we just added 2^224 + 1, the + * result cannot be negative. + */ + w = t[1] - BIT(44); + t[1] = w & MASK52; + cc = w >> 63; + w = t[2] - cc; + t[2] = w & MASK52; + cc = w >> 63; + w = t[3] - BIT(36) - cc; + t[3] = w & MASK52; + cc = w >> 63; + t[4] -= cc; + + /* + * If the top limb t[4] fits on 48 bits, then r[] is already + * in the proper range. Otherwise, t[] is the value to return + * (truncated to 256 bits). + */ + cc = -(t[4] >> 48); + t[4] &= MASK48; + for (i = 0; i < 5; i ++) { + a[i] = r[i] ^ (cc & (r[i] ^ t[i])); + } +} + +/* + * Points in affine and Jacobian coordinates. + * + * - In affine coordinates, the point-at-infinity cannot be encoded. + * - Jacobian coordinates (X,Y,Z) correspond to affine (X/Z^2,Y/Z^3); + * if Z = 0 then this is the point-at-infinity. + */ +typedef struct { + uint64_t x[5]; + uint64_t y[5]; +} p256_affine; + +typedef struct { + uint64_t x[5]; + uint64_t y[5]; + uint64_t z[5]; +} p256_jacobian; + +/* + * Decode a field element (unsigned big endian notation). + */ +static void +f256_decode(uint64_t *a, const unsigned char *buf) +{ + uint64_t w0, w1, w2, w3; + + w3 = br_dec64be(buf + 0); + w2 = br_dec64be(buf + 8); + w1 = br_dec64be(buf + 16); + w0 = br_dec64be(buf + 24); + a[0] = w0 & MASK52; + a[1] = ((w0 >> 52) | (w1 << 12)) & MASK52; + a[2] = ((w1 >> 40) | (w2 << 24)) & MASK52; + a[3] = ((w2 >> 28) | (w3 << 36)) & MASK52; + a[4] = w3 >> 16; +} + +/* + * Encode a field element (unsigned big endian notation). The field + * element MUST be fully reduced. + */ +static void +f256_encode(unsigned char *buf, const uint64_t *a) +{ + uint64_t w0, w1, w2, w3; + + w0 = a[0] | (a[1] << 52); + w1 = (a[1] >> 12) | (a[2] << 40); + w2 = (a[2] >> 24) | (a[3] << 28); + w3 = (a[3] >> 36) | (a[4] << 16); + br_enc64be(buf + 0, w3); + br_enc64be(buf + 8, w2); + br_enc64be(buf + 16, w1); + br_enc64be(buf + 24, w0); +} + +/* + * Decode a point. The returned point is in Jacobian coordinates, but + * with z = 1. If the encoding is invalid, or encodes a point which is + * not on the curve, or encodes the point at infinity, then this function + * returns 0. Otherwise, 1 is returned. + * + * The buffer is assumed to have length exactly 65 bytes. + */ +static uint32_t +point_decode(p256_jacobian *P, const unsigned char *buf) +{ + uint64_t x[5], y[5], t[5], x3[5], tt; + uint32_t r; + + /* + * Header byte shall be 0x04. + */ + r = EQ(buf[0], 0x04); + + /* + * Decode X and Y coordinates, and convert them into + * Montgomery representation. + */ + f256_decode(x, buf + 1); + f256_decode(y, buf + 33); + f256_tomonty(x, x); + f256_tomonty(y, y); + + /* + * Verify y^2 = x^3 + A*x + B. In curve P-256, A = -3. + * Note that the Montgomery representation of 0 is 0. We must + * take care to apply the final reduction to make sure we have + * 0 and not p. + */ + f256_montysquare(t, y); + f256_montysquare(x3, x); + f256_montymul(x3, x3, x); + f256_sub(t, t, x3); + f256_add(t, t, x); + f256_add(t, t, x); + f256_add(t, t, x); + f256_sub(t, t, P256_B_MONTY); + f256_final_reduce(t); + tt = t[0] | t[1] | t[2] | t[3] | t[4]; + r &= EQ((uint32_t)(tt | (tt >> 32)), 0); + + /* + * Return the point in Jacobian coordinates (and Montgomery + * representation). + */ + memcpy(P->x, x, sizeof x); + memcpy(P->y, y, sizeof y); + memcpy(P->z, F256_R, sizeof F256_R); + return r; +} + +/* + * Final conversion for a point: + * - The point is converted back to affine coordinates. + * - Final reduction is performed. + * - The point is encoded into the provided buffer. + * + * If the point is the point-at-infinity, all operations are performed, + * but the buffer contents are indeterminate, and 0 is returned. Otherwise, + * the encoded point is written in the buffer, and 1 is returned. + */ +static uint32_t +point_encode(unsigned char *buf, const p256_jacobian *P) +{ + uint64_t t1[5], t2[5], z; + + /* Set t1 = 1/z^2 and t2 = 1/z^3. */ + f256_invert(t2, P->z); + f256_montysquare(t1, t2); + f256_montymul(t2, t2, t1); + + /* Compute affine coordinates x (in t1) and y (in t2). */ + f256_montymul(t1, P->x, t1); + f256_montymul(t2, P->y, t2); + + /* Convert back from Montgomery representation, and finalize + reductions. */ + f256_frommonty(t1, t1); + f256_frommonty(t2, t2); + f256_final_reduce(t1); + f256_final_reduce(t2); + + /* Encode. */ + buf[0] = 0x04; + f256_encode(buf + 1, t1); + f256_encode(buf + 33, t2); + + /* Return success if and only if P->z != 0. */ + z = P->z[0] | P->z[1] | P->z[2] | P->z[3] | P->z[4]; + return NEQ((uint32_t)(z | z >> 32), 0); +} + +/* + * Point doubling in Jacobian coordinates: point P is doubled. + * Note: if the source point is the point-at-infinity, then the result is + * still the point-at-infinity, which is correct. Moreover, if the three + * coordinates were zero, then they still are zero in the returned value. + */ +static void +p256_double(p256_jacobian *P) +{ + /* + * Doubling formulas are: + * + * s = 4*x*y^2 + * m = 3*(x + z^2)*(x - z^2) + * x' = m^2 - 2*s + * y' = m*(s - x') - 8*y^4 + * z' = 2*y*z + * + * These formulas work for all points, including points of order 2 + * and points at infinity: + * - If y = 0 then z' = 0. But there is no such point in P-256 + * anyway. + * - If z = 0 then z' = 0. + */ + uint64_t t1[5], t2[5], t3[5], t4[5]; + + /* + * Compute z^2 in t1. + */ + f256_montysquare(t1, P->z); + + /* + * Compute x-z^2 in t2 and x+z^2 in t1. + */ + f256_add(t2, P->x, t1); + f256_sub(t1, P->x, t1); + + /* + * Compute 3*(x+z^2)*(x-z^2) in t1. + */ + f256_montymul(t3, t1, t2); + f256_add(t1, t3, t3); + f256_add(t1, t3, t1); + + /* + * Compute 4*x*y^2 (in t2) and 2*y^2 (in t3). + */ + f256_montysquare(t3, P->y); + f256_add(t3, t3, t3); + f256_montymul(t2, P->x, t3); + f256_add(t2, t2, t2); + + /* + * Compute x' = m^2 - 2*s. + */ + f256_montysquare(P->x, t1); + f256_sub(P->x, P->x, t2); + f256_sub(P->x, P->x, t2); + + /* + * Compute z' = 2*y*z. + */ + f256_montymul(t4, P->y, P->z); + f256_add(P->z, t4, t4); + f256_partial_reduce(P->z); + + /* + * Compute y' = m*(s - x') - 8*y^4. Note that we already have + * 2*y^2 in t3. + */ + f256_sub(t2, t2, P->x); + f256_montymul(P->y, t1, t2); + f256_montysquare(t4, t3); + f256_add(t4, t4, t4); + f256_sub(P->y, P->y, t4); +} + +/* + * Point addition (Jacobian coordinates): P1 is replaced with P1+P2. + * This function computes the wrong result in the following cases: + * + * - If P1 == 0 but P2 != 0 + * - If P1 != 0 but P2 == 0 + * - If P1 == P2 + * + * In all three cases, P1 is set to the point at infinity. + * + * Returned value is 0 if one of the following occurs: + * + * - P1 and P2 have the same Y coordinate. + * - P1 == 0 and P2 == 0. + * - The Y coordinate of one of the points is 0 and the other point is + * the point at infinity. + * + * The third case cannot actually happen with valid points, since a point + * with Y == 0 is a point of order 2, and there is no point of order 2 on + * curve P-256. + * + * Therefore, assuming that P1 != 0 and P2 != 0 on input, then the caller + * can apply the following: + * + * - If the result is not the point at infinity, then it is correct. + * - Otherwise, if the returned value is 1, then this is a case of + * P1+P2 == 0, so the result is indeed the point at infinity. + * - Otherwise, P1 == P2, so a "double" operation should have been + * performed. + * + * Note that you can get a returned value of 0 with a correct result, + * e.g. if P1 and P2 have the same Y coordinate, but distinct X coordinates. + */ +static uint32_t +p256_add(p256_jacobian *P1, const p256_jacobian *P2) +{ + /* + * Addtions formulas are: + * + * u1 = x1 * z2^2 + * u2 = x2 * z1^2 + * s1 = y1 * z2^3 + * s2 = y2 * z1^3 + * h = u2 - u1 + * r = s2 - s1 + * x3 = r^2 - h^3 - 2 * u1 * h^2 + * y3 = r * (u1 * h^2 - x3) - s1 * h^3 + * z3 = h * z1 * z2 + */ + uint64_t t1[5], t2[5], t3[5], t4[5], t5[5], t6[5], t7[5], tt; + uint32_t ret; + + /* + * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3). + */ + f256_montysquare(t3, P2->z); + f256_montymul(t1, P1->x, t3); + f256_montymul(t4, P2->z, t3); + f256_montymul(t3, P1->y, t4); + + /* + * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). + */ + f256_montysquare(t4, P1->z); + f256_montymul(t2, P2->x, t4); + f256_montymul(t5, P1->z, t4); + f256_montymul(t4, P2->y, t5); + + /* + * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). + * We need to test whether r is zero, so we will do some extra + * reduce. + */ + f256_sub(t2, t2, t1); + f256_sub(t4, t4, t3); + f256_final_reduce(t4); + tt = t4[0] | t4[1] | t4[2] | t4[3] | t4[4]; + ret = (uint32_t)(tt | (tt >> 32)); + ret = (ret | -ret) >> 31; + + /* + * Compute u1*h^2 (in t6) and h^3 (in t5); + */ + f256_montysquare(t7, t2); + f256_montymul(t6, t1, t7); + f256_montymul(t5, t7, t2); + + /* + * Compute x3 = r^2 - h^3 - 2*u1*h^2. + */ + f256_montysquare(P1->x, t4); + f256_sub(P1->x, P1->x, t5); + f256_sub(P1->x, P1->x, t6); + f256_sub(P1->x, P1->x, t6); + + /* + * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. + */ + f256_sub(t6, t6, P1->x); + f256_montymul(P1->y, t4, t6); + f256_montymul(t1, t5, t3); + f256_sub(P1->y, P1->y, t1); + + /* + * Compute z3 = h*z1*z2. + */ + f256_montymul(t1, P1->z, P2->z); + f256_montymul(P1->z, t1, t2); + + return ret; +} + +/* + * Point addition (mixed coordinates): P1 is replaced with P1+P2. + * This is a specialised function for the case when P2 is a non-zero point + * in affine coordinates. + * + * This function computes the wrong result in the following cases: + * + * - If P1 == 0 + * - If P1 == P2 + * + * In both cases, P1 is set to the point at infinity. + * + * Returned value is 0 if one of the following occurs: + * + * - P1 and P2 have the same Y (affine) coordinate. + * - The Y coordinate of P2 is 0 and P1 is the point at infinity. + * + * The second case cannot actually happen with valid points, since a point + * with Y == 0 is a point of order 2, and there is no point of order 2 on + * curve P-256. + * + * Therefore, assuming that P1 != 0 on input, then the caller + * can apply the following: + * + * - If the result is not the point at infinity, then it is correct. + * - Otherwise, if the returned value is 1, then this is a case of + * P1+P2 == 0, so the result is indeed the point at infinity. + * - Otherwise, P1 == P2, so a "double" operation should have been + * performed. + * + * Again, a value of 0 may be returned in some cases where the addition + * result is correct. + */ +static uint32_t +p256_add_mixed(p256_jacobian *P1, const p256_affine *P2) +{ + /* + * Addtions formulas are: + * + * u1 = x1 + * u2 = x2 * z1^2 + * s1 = y1 + * s2 = y2 * z1^3 + * h = u2 - u1 + * r = s2 - s1 + * x3 = r^2 - h^3 - 2 * u1 * h^2 + * y3 = r * (u1 * h^2 - x3) - s1 * h^3 + * z3 = h * z1 + */ + uint64_t t1[5], t2[5], t3[5], t4[5], t5[5], t6[5], t7[5], tt; + uint32_t ret; + + /* + * Compute u1 = x1 (in t1) and s1 = y1 (in t3). + */ + memcpy(t1, P1->x, sizeof t1); + memcpy(t3, P1->y, sizeof t3); + + /* + * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). + */ + f256_montysquare(t4, P1->z); + f256_montymul(t2, P2->x, t4); + f256_montymul(t5, P1->z, t4); + f256_montymul(t4, P2->y, t5); + + /* + * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). + * We need to test whether r is zero, so we will do some extra + * reduce. + */ + f256_sub(t2, t2, t1); + f256_sub(t4, t4, t3); + f256_final_reduce(t4); + tt = t4[0] | t4[1] | t4[2] | t4[3] | t4[4]; + ret = (uint32_t)(tt | (tt >> 32)); + ret = (ret | -ret) >> 31; + + /* + * Compute u1*h^2 (in t6) and h^3 (in t5); + */ + f256_montysquare(t7, t2); + f256_montymul(t6, t1, t7); + f256_montymul(t5, t7, t2); + + /* + * Compute x3 = r^2 - h^3 - 2*u1*h^2. + */ + f256_montysquare(P1->x, t4); + f256_sub(P1->x, P1->x, t5); + f256_sub(P1->x, P1->x, t6); + f256_sub(P1->x, P1->x, t6); + + /* + * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. + */ + f256_sub(t6, t6, P1->x); + f256_montymul(P1->y, t4, t6); + f256_montymul(t1, t5, t3); + f256_sub(P1->y, P1->y, t1); + + /* + * Compute z3 = h*z1*z2. + */ + f256_montymul(P1->z, P1->z, t2); + + return ret; +} + +#if 0 +/* unused */ +/* + * Point addition (mixed coordinates, complete): P1 is replaced with P1+P2. + * This is a specialised function for the case when P2 is a non-zero point + * in affine coordinates. + * + * This function returns the correct result in all cases. + */ +static uint32_t +p256_add_complete_mixed(p256_jacobian *P1, const p256_affine *P2) +{ + /* + * Addtions formulas, in the general case, are: + * + * u1 = x1 + * u2 = x2 * z1^2 + * s1 = y1 + * s2 = y2 * z1^3 + * h = u2 - u1 + * r = s2 - s1 + * x3 = r^2 - h^3 - 2 * u1 * h^2 + * y3 = r * (u1 * h^2 - x3) - s1 * h^3 + * z3 = h * z1 + * + * These formulas mishandle the two following cases: + * + * - If P1 is the point-at-infinity (z1 = 0), then z3 is + * incorrectly set to 0. + * + * - If P1 = P2, then u1 = u2 and s1 = s2, and x3, y3 and z3 + * are all set to 0. + * + * However, if P1 + P2 = 0, then u1 = u2 but s1 != s2, and then + * we correctly get z3 = 0 (the point-at-infinity). + * + * To fix the case P1 = 0, we perform at the end a copy of P2 + * over P1, conditional to z1 = 0. + * + * For P1 = P2: in that case, both h and r are set to 0, and + * we get x3, y3 and z3 equal to 0. We can test for that + * occurrence to make a mask which will be all-one if P1 = P2, + * or all-zero otherwise; then we can compute the double of P2 + * and add it, combined with the mask, to (x3,y3,z3). + * + * Using the doubling formulas in p256_double() on (x2,y2), + * simplifying since P2 is affine (i.e. z2 = 1, implicitly), + * we get: + * s = 4*x2*y2^2 + * m = 3*(x2 + 1)*(x2 - 1) + * x' = m^2 - 2*s + * y' = m*(s - x') - 8*y2^4 + * z' = 2*y2 + * which requires only 6 multiplications. Added to the 11 + * multiplications of the normal mixed addition in Jacobian + * coordinates, we get a cost of 17 multiplications in total. + */ + uint64_t t1[5], t2[5], t3[5], t4[5], t5[5], t6[5], t7[5], tt, zz; + int i; + + /* + * Set zz to -1 if P1 is the point at infinity, 0 otherwise. + */ + zz = P1->z[0] | P1->z[1] | P1->z[2] | P1->z[3] | P1->z[4]; + zz = ((zz | -zz) >> 63) - (uint64_t)1; + + /* + * Compute u1 = x1 (in t1) and s1 = y1 (in t3). + */ + memcpy(t1, P1->x, sizeof t1); + memcpy(t3, P1->y, sizeof t3); + + /* + * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). + */ + f256_montysquare(t4, P1->z); + f256_montymul(t2, P2->x, t4); + f256_montymul(t5, P1->z, t4); + f256_montymul(t4, P2->y, t5); + + /* + * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). + * reduce. + */ + f256_sub(t2, t2, t1); + f256_sub(t4, t4, t3); + + /* + * If both h = 0 and r = 0, then P1 = P2, and we want to set + * the mask tt to -1; otherwise, the mask will be 0. + */ + f256_final_reduce(t2); + f256_final_reduce(t4); + tt = t2[0] | t2[1] | t2[2] | t2[3] | t2[4] + | t4[0] | t4[1] | t4[2] | t4[3] | t4[4]; + tt = ((tt | -tt) >> 63) - (uint64_t)1; + + /* + * Compute u1*h^2 (in t6) and h^3 (in t5); + */ + f256_montysquare(t7, t2); + f256_montymul(t6, t1, t7); + f256_montymul(t5, t7, t2); + + /* + * Compute x3 = r^2 - h^3 - 2*u1*h^2. + */ + f256_montysquare(P1->x, t4); + f256_sub(P1->x, P1->x, t5); + f256_sub(P1->x, P1->x, t6); + f256_sub(P1->x, P1->x, t6); + + /* + * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. + */ + f256_sub(t6, t6, P1->x); + f256_montymul(P1->y, t4, t6); + f256_montymul(t1, t5, t3); + f256_sub(P1->y, P1->y, t1); + + /* + * Compute z3 = h*z1. + */ + f256_montymul(P1->z, P1->z, t2); + + /* + * The "double" result, in case P1 = P2. + */ + + /* + * Compute z' = 2*y2 (in t1). + */ + f256_add(t1, P2->y, P2->y); + f256_partial_reduce(t1); + + /* + * Compute 2*(y2^2) (in t2) and s = 4*x2*(y2^2) (in t3). + */ + f256_montysquare(t2, P2->y); + f256_add(t2, t2, t2); + f256_add(t3, t2, t2); + f256_montymul(t3, P2->x, t3); + + /* + * Compute m = 3*(x2^2 - 1) (in t4). + */ + f256_montysquare(t4, P2->x); + f256_sub(t4, t4, F256_R); + f256_add(t5, t4, t4); + f256_add(t4, t4, t5); + + /* + * Compute x' = m^2 - 2*s (in t5). + */ + f256_montysquare(t5, t4); + f256_sub(t5, t3); + f256_sub(t5, t3); + + /* + * Compute y' = m*(s - x') - 8*y2^4 (in t6). + */ + f256_sub(t6, t3, t5); + f256_montymul(t6, t6, t4); + f256_montysquare(t7, t2); + f256_sub(t6, t6, t7); + f256_sub(t6, t6, t7); + + /* + * We now have the alternate (doubling) coordinates in (t5,t6,t1). + * We combine them with (x3,y3,z3). + */ + for (i = 0; i < 5; i ++) { + P1->x[i] |= tt & t5[i]; + P1->y[i] |= tt & t6[i]; + P1->z[i] |= tt & t1[i]; + } + + /* + * If P1 = 0, then we get z3 = 0 (which is invalid); if z1 is 0, + * then we want to replace the result with a copy of P2. The + * test on z1 was done at the start, in the zz mask. + */ + for (i = 0; i < 5; i ++) { + P1->x[i] ^= zz & (P1->x[i] ^ P2->x[i]); + P1->y[i] ^= zz & (P1->y[i] ^ P2->y[i]); + P1->z[i] ^= zz & (P1->z[i] ^ F256_R[i]); + } +} +#endif + +/* + * Inner function for computing a point multiplication. A window is + * provided, with points 1*P to 15*P in affine coordinates. + * + * Assumptions: + * - All provided points are valid points on the curve. + * - Multiplier is non-zero, and smaller than the curve order. + * - Everything is in Montgomery representation. + */ +static void +point_mul_inner(p256_jacobian *R, const p256_affine *W, + const unsigned char *k, size_t klen) +{ + p256_jacobian Q; + uint32_t qz; + + memset(&Q, 0, sizeof Q); + qz = 1; + while (klen -- > 0) { + int i; + unsigned bk; + + bk = *k ++; + for (i = 0; i < 2; i ++) { + uint32_t bits; + uint32_t bnz; + p256_affine T; + p256_jacobian U; + uint32_t n; + int j; + uint64_t m; + + p256_double(&Q); + p256_double(&Q); + p256_double(&Q); + p256_double(&Q); + bits = (bk >> 4) & 0x0F; + bnz = NEQ(bits, 0); + + /* + * Lookup point in window. If the bits are 0, + * we get something invalid, which is not a + * problem because we will use it only if the + * bits are non-zero. + */ + memset(&T, 0, sizeof T); + for (n = 0; n < 15; n ++) { + m = -(uint64_t)EQ(bits, n + 1); + T.x[0] |= m & W[n].x[0]; + T.x[1] |= m & W[n].x[1]; + T.x[2] |= m & W[n].x[2]; + T.x[3] |= m & W[n].x[3]; + T.x[4] |= m & W[n].x[4]; + T.y[0] |= m & W[n].y[0]; + T.y[1] |= m & W[n].y[1]; + T.y[2] |= m & W[n].y[2]; + T.y[3] |= m & W[n].y[3]; + T.y[4] |= m & W[n].y[4]; + } + + U = Q; + p256_add_mixed(&U, &T); + + /* + * If qz is still 1, then Q was all-zeros, and this + * is conserved through p256_double(). + */ + m = -(uint64_t)(bnz & qz); + for (j = 0; j < 5; j ++) { + Q.x[j] ^= m & (Q.x[j] ^ T.x[j]); + Q.y[j] ^= m & (Q.y[j] ^ T.y[j]); + Q.z[j] ^= m & (Q.z[j] ^ F256_R[j]); + } + CCOPY(bnz & ~qz, &Q, &U, sizeof Q); + qz &= ~bnz; + bk <<= 4; + } + } + *R = Q; +} + +/* + * Convert a window from Jacobian to affine coordinates. A single + * field inversion is used. This function works for windows up to + * 32 elements. + * + * The destination array (aff[]) and the source array (jac[]) may + * overlap, provided that the start of aff[] is not after the start of + * jac[]. Even if the arrays do _not_ overlap, the source array is + * modified. + */ +static void +window_to_affine(p256_affine *aff, p256_jacobian *jac, int num) +{ + /* + * Convert the window points to affine coordinates. We use the + * following trick to mutualize the inversion computation: if + * we have z1, z2, z3, and z4, and want to invert all of them, + * we compute u = 1/(z1*z2*z3*z4), and then we have: + * 1/z1 = u*z2*z3*z4 + * 1/z2 = u*z1*z3*z4 + * 1/z3 = u*z1*z2*z4 + * 1/z4 = u*z1*z2*z3 + * + * The partial products are computed recursively: + * + * - on input (z_1,z_2), return (z_2,z_1) and z_1*z_2 + * - on input (z_1,z_2,... z_n): + * recurse on (z_1,z_2,... z_(n/2)) -> r1 and m1 + * recurse on (z_(n/2+1),z_(n/2+2)... z_n) -> r2 and m2 + * multiply elements of r1 by m2 -> s1 + * multiply elements of r2 by m1 -> s2 + * return r1||r2 and m1*m2 + * + * In the example below, we suppose that we have 14 elements. + * Let z1, z2,... zE be the 14 values to invert (index noted in + * hexadecimal, starting at 1). + * + * - Depth 1: + * swap(z1, z2); z12 = z1*z2 + * swap(z3, z4); z34 = z3*z4 + * swap(z5, z6); z56 = z5*z6 + * swap(z7, z8); z78 = z7*z8 + * swap(z9, zA); z9A = z9*zA + * swap(zB, zC); zBC = zB*zC + * swap(zD, zE); zDE = zD*zE + * + * - Depth 2: + * z1 <- z1*z34, z2 <- z2*z34, z3 <- z3*z12, z4 <- z4*z12 + * z1234 = z12*z34 + * z5 <- z5*z78, z6 <- z6*z78, z7 <- z7*z56, z8 <- z8*z56 + * z5678 = z56*z78 + * z9 <- z9*zBC, zA <- zA*zBC, zB <- zB*z9A, zC <- zC*z9A + * z9ABC = z9A*zBC + * + * - Depth 3: + * z1 <- z1*z5678, z2 <- z2*z5678, z3 <- z3*z5678, z4 <- z4*z5678 + * z5 <- z5*z1234, z6 <- z6*z1234, z7 <- z7*z1234, z8 <- z8*z1234 + * z12345678 = z1234*z5678 + * z9 <- z9*zDE, zA <- zA*zDE, zB <- zB*zDE, zC <- zC*zDE + * zD <- zD*z9ABC, zE*z9ABC + * z9ABCDE = z9ABC*zDE + * + * - Depth 4: + * multiply z1..z8 by z9ABCDE + * multiply z9..zE by z12345678 + * final z = z12345678*z9ABCDE + */ + + uint64_t z[16][5]; + int i, k, s; +#define zt (z[15]) +#define zu (z[14]) +#define zv (z[13]) + + /* + * First recursion step (pairwise swapping and multiplication). + * If there is an odd number of elements, then we "invent" an + * extra one with coordinate Z = 1 (in Montgomery representation). + */ + for (i = 0; (i + 1) < num; i += 2) { + memcpy(zt, jac[i].z, sizeof zt); + memcpy(jac[i].z, jac[i + 1].z, sizeof zt); + memcpy(jac[i + 1].z, zt, sizeof zt); + f256_montymul(z[i >> 1], jac[i].z, jac[i + 1].z); + } + if ((num & 1) != 0) { + memcpy(z[num >> 1], jac[num - 1].z, sizeof zt); + memcpy(jac[num - 1].z, F256_R, sizeof F256_R); + } + + /* + * Perform further recursion steps. At the entry of each step, + * the process has been done for groups of 's' points. The + * integer k is the log2 of s. + */ + for (k = 1, s = 2; s < num; k ++, s <<= 1) { + int n; + + for (i = 0; i < num; i ++) { + f256_montymul(jac[i].z, jac[i].z, z[(i >> k) ^ 1]); + } + n = (num + s - 1) >> k; + for (i = 0; i < (n >> 1); i ++) { + f256_montymul(z[i], z[i << 1], z[(i << 1) + 1]); + } + if ((n & 1) != 0) { + memmove(z[n >> 1], z[n], sizeof zt); + } + } + + /* + * Invert the final result, and convert all points. + */ + f256_invert(zt, z[0]); + for (i = 0; i < num; i ++) { + f256_montymul(zv, jac[i].z, zt); + f256_montysquare(zu, zv); + f256_montymul(zv, zv, zu); + f256_montymul(aff[i].x, jac[i].x, zu); + f256_montymul(aff[i].y, jac[i].y, zv); + } +} + +/* + * Multiply the provided point by an integer. + * Assumptions: + * - Source point is a valid curve point. + * - Source point is not the point-at-infinity. + * - Integer is not 0, and is lower than the curve order. + * If these conditions are not met, then the result is indeterminate + * (but the process is still constant-time). + */ +static void +p256_mul(p256_jacobian *P, const unsigned char *k, size_t klen) +{ + union { + p256_affine aff[15]; + p256_jacobian jac[15]; + } window; + int i; + + /* + * Compute window, in Jacobian coordinates. + */ + window.jac[0] = *P; + for (i = 2; i < 16; i ++) { + window.jac[i - 1] = window.jac[(i >> 1) - 1]; + if ((i & 1) == 0) { + p256_double(&window.jac[i - 1]); + } else { + p256_add(&window.jac[i - 1], &window.jac[i >> 1]); + } + } + + /* + * Convert the window points to affine coordinates. Point + * window[0] is the source point, already in affine coordinates. + */ + window_to_affine(window.aff, window.jac, 15); + + /* + * Perform point multiplication. + */ + point_mul_inner(P, window.aff, k, klen); +} + +/* + * Precomputed window for the conventional generator: P256_Gwin[n] + * contains (n+1)*G (affine coordinates, in Montgomery representation). + */ +static const p256_affine P256_Gwin[] = { + { + { 0x30D418A9143C1, 0xC4FEDB60179E7, 0x62251075BA95F, + 0x5C669FB732B77, 0x08905F76B5375 }, + { 0x5357CE95560A8, 0x43A19E45CDDF2, 0x21F3258B4AB8E, + 0xD8552E88688DD, 0x0571FF18A5885 } + }, + { + { 0x46D410DDD64DF, 0x0B433827D8500, 0x1490D9AA6AE3C, + 0xA3A832205038D, 0x06BB32E52DCF3 }, + { 0x48D361BEE1A57, 0xB7B236FF82F36, 0x042DBE152CD7C, + 0xA3AA9A8FB0E92, 0x08C577517A5B8 } + }, + { + { 0x3F904EEBC1272, 0x9E87D81FBFFAC, 0xCBBC98B027F84, + 0x47E46AD77DD87, 0x06936A3FD6FF7 }, + { 0x5C1FC983A7EBD, 0xC3861FE1AB04C, 0x2EE98E583E47A, + 0xC06A88208311A, 0x05F06A2AB587C } + }, + { + { 0xB50D46918DCC5, 0xD7623C17374B0, 0x100AF24650A6E, + 0x76ABCDAACACE8, 0x077362F591B01 }, + { 0xF24CE4CBABA68, 0x17AD6F4472D96, 0xDDD22E1762847, + 0x862EB6C36DEE5, 0x04B14C39CC5AB } + }, + { + { 0x8AAEC45C61F5C, 0x9D4B9537DBE1B, 0x76C20C90EC649, + 0x3C7D41CB5AAD0, 0x0907960649052 }, + { 0x9B4AE7BA4F107, 0xF75EB882BEB30, 0x7A1F6873C568E, + 0x915C540A9877E, 0x03A076BB9DD1E } + }, + { + { 0x47373E77664A1, 0xF246CEE3E4039, 0x17A3AD55AE744, + 0x673C50A961A5B, 0x03074B5964213 }, + { 0x6220D377E44BA, 0x30DFF14B593D3, 0x639F11299C2B5, + 0x75F5424D44CEF, 0x04C9916DEA07F } + }, + { + { 0x354EA0173B4F1, 0x3C23C00F70746, 0x23BB082BD2021, + 0xE03E43EAAB50C, 0x03BA5119D3123 }, + { 0xD0303F5B9D4DE, 0x17DA67BDD2847, 0xC941956742F2F, + 0x8670F933BDC77, 0x0AEDD9164E240 } + }, + { + { 0x4CD19499A78FB, 0x4BF9B345527F1, 0x2CFC6B462AB5C, + 0x30CDF90F02AF0, 0x0763891F62652 }, + { 0xA3A9532D49775, 0xD7F9EBA15F59D, 0x60BBF021E3327, + 0xF75C23C7B84BE, 0x06EC12F2C706D } + }, + { + { 0x6E8F264E20E8E, 0xC79A7A84175C9, 0xC8EB00ABE6BFE, + 0x16A4CC09C0444, 0x005B3081D0C4E }, + { 0x777AA45F33140, 0xDCE5D45E31EB7, 0xB12F1A56AF7BE, + 0xF9B2B6E019A88, 0x086659CDFD835 } + }, + { + { 0xDBD19DC21EC8C, 0x94FCF81392C18, 0x250B4998F9868, + 0x28EB37D2CD648, 0x0C61C947E4B34 }, + { 0x407880DD9E767, 0x0C83FBE080C2B, 0x9BE5D2C43A899, + 0xAB4EF7D2D6577, 0x08719A555B3B4 } + }, + { + { 0x260A6245E4043, 0x53E7FDFE0EA7D, 0xAC1AB59DE4079, + 0x072EFF3A4158D, 0x0E7090F1949C9 }, + { 0x85612B944E886, 0xE857F61C81A76, 0xAD643D250F939, + 0x88DAC0DAA891E, 0x089300244125B } + }, + { + { 0x1AA7D26977684, 0x58A345A3304B7, 0x37385EABDEDEF, + 0x155E409D29DEE, 0x0EE1DF780B83E }, + { 0x12D91CBB5B437, 0x65A8956370CAC, 0xDE6D66170ED2F, + 0xAC9B8228CFA8A, 0x0FF57C95C3238 } + }, + { + { 0x25634B2ED7097, 0x9156FD30DCCC4, 0x9E98110E35676, + 0x7594CBCD43F55, 0x038477ACC395B }, + { 0x2B90C00EE17FF, 0xF842ED2E33575, 0x1F5BC16874838, + 0x7968CD06422BD, 0x0BC0876AB9E7B } + }, + { + { 0xA35BB0CF664AF, 0x68F9707E3A242, 0x832660126E48F, + 0x72D2717BF54C6, 0x0AAE7333ED12C }, + { 0x2DB7995D586B1, 0xE732237C227B5, 0x65E7DBBE29569, + 0xBBBD8E4193E2A, 0x052706DC3EAA1 } + }, + { + { 0xD8B7BC60055BE, 0xD76E27E4B72BC, 0x81937003CC23E, + 0xA090E337424E4, 0x02AA0E43EAD3D }, + { 0x524F6383C45D2, 0x422A41B2540B8, 0x8A4797D766355, + 0xDF444EFA6DE77, 0x0042170A9079A } + }, +}; + +/* + * Multiply the conventional generator of the curve by the provided + * integer. Return is written in *P. + * + * Assumptions: + * - Integer is not 0, and is lower than the curve order. + * If this conditions is not met, then the result is indeterminate + * (but the process is still constant-time). + */ +static void +p256_mulgen(p256_jacobian *P, const unsigned char *k, size_t klen) +{ + point_mul_inner(P, P256_Gwin, k, klen); +} + +/* + * Return 1 if all of the following hold: + * - klen <= 32 + * - k != 0 + * - k is lower than the curve order + * Otherwise, return 0. + * + * Constant-time behaviour: only klen may be observable. + */ +static uint32_t +check_scalar(const unsigned char *k, size_t klen) +{ + uint32_t z; + int32_t c; + size_t u; + + if (klen > 32) { + return 0; + } + z = 0; + for (u = 0; u < klen; u ++) { + z |= k[u]; + } + if (klen == 32) { + c = 0; + for (u = 0; u < klen; u ++) { + c |= -(int32_t)EQ0(c) & CMP(k[u], P256_N[u]); + } + } else { + c = -1; + } + return NEQ(z, 0) & LT0(c); +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *k, size_t klen, int curve) +{ + uint32_t r; + p256_jacobian P; + + (void)curve; + if (Glen != 65) { + return 0; + } + r = check_scalar(k, klen); + r &= point_decode(&P, G); + p256_mul(&P, k, klen); + r &= point_encode(G, &P); + return r; +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *k, size_t klen, int curve) +{ + p256_jacobian P; + + (void)curve; + p256_mulgen(&P, k, klen); + point_encode(R, &P); + return 65; +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + /* + * We might want to use Shamir's trick here: make a composite + * window of u*P+v*Q points, to merge the two doubling-ladders + * into one. This, however, has some complications: + * + * - During the computation, we may hit the point-at-infinity. + * Thus, we would need p256_add_complete_mixed() (complete + * formulas for point addition), with a higher cost (17 muls + * instead of 11). + * + * - A 4-bit window would be too large, since it would involve + * 16*16-1 = 255 points. For the same window size as in the + * p256_mul() case, we would need to reduce the window size + * to 2 bits, and thus perform twice as many non-doubling + * point additions. + * + * - The window may itself contain the point-at-infinity, and + * thus cannot be in all generality be made of affine points. + * Instead, we would need to make it a window of points in + * Jacobian coordinates. Even p256_add_complete_mixed() would + * be inappropriate. + * + * For these reasons, the code below performs two separate + * point multiplications, then computes the final point addition + * (which is both a "normal" addition, and a doubling, to handle + * all cases). + */ + + p256_jacobian P, Q; + uint32_t r, t, s; + uint64_t z; + + (void)curve; + if (len != 65) { + return 0; + } + r = point_decode(&P, A); + p256_mul(&P, x, xlen); + if (B == NULL) { + p256_mulgen(&Q, y, ylen); + } else { + r &= point_decode(&Q, B); + p256_mul(&Q, y, ylen); + } + + /* + * The final addition may fail in case both points are equal. + */ + t = p256_add(&P, &Q); + f256_final_reduce(P.z); + z = P.z[0] | P.z[1] | P.z[2] | P.z[3] | P.z[4]; + s = EQ((uint32_t)(z | (z >> 32)), 0); + p256_double(&Q); + + /* + * If s is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we + * have the following: + * + * s = 0, t = 0 return P (normal addition) + * s = 0, t = 1 return P (normal addition) + * s = 1, t = 0 return Q (a 'double' case) + * s = 1, t = 1 report an error (P+Q = 0) + */ + CCOPY(s & ~t, &P, &Q, sizeof Q); + point_encode(A, &P); + r &= ~(s & t); + return r; +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_p256_m62 = { + (uint32_t)0x00800000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; + +/* see bearssl_ec.h */ +const br_ec_impl * +br_ec_p256_m62_get(void) +{ + return &br_ec_p256_m62; +} + +#else + +/* see bearssl_ec.h */ +const br_ec_impl * +br_ec_p256_m62_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/ec/ec_p256_m64.c b/BearSSL-OG/libbearssl/src/ec/ec_p256_m64.c new file mode 100644 index 0000000..71a527c --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_p256_m64.c @@ -0,0 +1,1781 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +#if BR_UMUL128 +#include +#endif + +static const unsigned char P256_G[] = { + 0x04, 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, + 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, + 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, + 0x98, 0xC2, 0x96, 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, + 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16, 0x2B, + 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, + 0x68, 0x37, 0xBF, 0x51, 0xF5 +}; + +static const unsigned char P256_N[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, + 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, + 0x25, 0x51 +}; + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + (void)curve; + *len = sizeof P256_G; + return P256_G; +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + (void)curve; + *len = sizeof P256_N; + return P256_N; +} + +static size_t +api_xoff(int curve, size_t *len) +{ + (void)curve; + *len = 32; + return 1; +} + +/* + * A field element is encoded as four 64-bit integers, in basis 2^64. + * Values may reach up to 2^256-1. Montgomery multiplication is used. + */ + +/* R = 2^256 mod p */ +static const uint64_t F256_R[] = { + 0x0000000000000001, 0xFFFFFFFF00000000, + 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFE +}; + +/* Curve equation is y^2 = x^3 - 3*x + B. This constant is B*R mod p + (Montgomery representation of B). */ +static const uint64_t P256_B_MONTY[] = { + 0xD89CDF6229C4BDDF, 0xACF005CD78843090, + 0xE5A220ABF7212ED6, 0xDC30061D04874834 +}; + +/* + * Addition in the field. + */ +static inline void +f256_add(uint64_t *d, const uint64_t *a, const uint64_t *b) +{ +#if BR_INT128 + unsigned __int128 w; + uint64_t t; + + /* + * Do the addition, with an extra carry in t. + */ + w = (unsigned __int128)a[0] + b[0]; + d[0] = (uint64_t)w; + w = (unsigned __int128)a[1] + b[1] + (w >> 64); + d[1] = (uint64_t)w; + w = (unsigned __int128)a[2] + b[2] + (w >> 64); + d[2] = (uint64_t)w; + w = (unsigned __int128)a[3] + b[3] + (w >> 64); + d[3] = (uint64_t)w; + t = (uint64_t)(w >> 64); + + /* + * Fold carry t, using: 2^256 = 2^224 - 2^192 - 2^96 + 1 mod p. + */ + w = (unsigned __int128)d[0] + t; + d[0] = (uint64_t)w; + w = (unsigned __int128)d[1] + (w >> 64) - (t << 32); + d[1] = (uint64_t)w; + /* Here, carry "w >> 64" can only be 0 or -1 */ + w = (unsigned __int128)d[2] - ((w >> 64) & 1); + d[2] = (uint64_t)w; + /* Again, carry is 0 or -1. But there can be carry only if t = 1, + in which case the addition of (t << 32) - t is positive. */ + w = (unsigned __int128)d[3] - ((w >> 64) & 1) + (t << 32) - t; + d[3] = (uint64_t)w; + t = (uint64_t)(w >> 64); + + /* + * There can be an extra carry here, which we must fold again. + */ + w = (unsigned __int128)d[0] + t; + d[0] = (uint64_t)w; + w = (unsigned __int128)d[1] + (w >> 64) - (t << 32); + d[1] = (uint64_t)w; + w = (unsigned __int128)d[2] - ((w >> 64) & 1); + d[2] = (uint64_t)w; + d[3] += (t << 32) - t - (uint64_t)((w >> 64) & 1); + +#elif BR_UMUL128 + + unsigned char cc; + uint64_t t; + + cc = _addcarry_u64(0, a[0], b[0], &d[0]); + cc = _addcarry_u64(cc, a[1], b[1], &d[1]); + cc = _addcarry_u64(cc, a[2], b[2], &d[2]); + cc = _addcarry_u64(cc, a[3], b[3], &d[3]); + + /* + * If there is a carry, then we want to subtract p, which we + * do by adding 2^256 - p. + */ + t = cc; + cc = _addcarry_u64(cc, d[0], 0, &d[0]); + cc = _addcarry_u64(cc, d[1], -(t << 32), &d[1]); + cc = _addcarry_u64(cc, d[2], -t, &d[2]); + cc = _addcarry_u64(cc, d[3], (t << 32) - (t << 1), &d[3]); + + /* + * We have to do it again if there still is a carry. + */ + t = cc; + cc = _addcarry_u64(cc, d[0], 0, &d[0]); + cc = _addcarry_u64(cc, d[1], -(t << 32), &d[1]); + cc = _addcarry_u64(cc, d[2], -t, &d[2]); + (void)_addcarry_u64(cc, d[3], (t << 32) - (t << 1), &d[3]); + +#endif +} + +/* + * Subtraction in the field. + */ +static inline void +f256_sub(uint64_t *d, const uint64_t *a, const uint64_t *b) +{ +#if BR_INT128 + + unsigned __int128 w; + uint64_t t; + + w = (unsigned __int128)a[0] - b[0]; + d[0] = (uint64_t)w; + w = (unsigned __int128)a[1] - b[1] - ((w >> 64) & 1); + d[1] = (uint64_t)w; + w = (unsigned __int128)a[2] - b[2] - ((w >> 64) & 1); + d[2] = (uint64_t)w; + w = (unsigned __int128)a[3] - b[3] - ((w >> 64) & 1); + d[3] = (uint64_t)w; + t = (uint64_t)(w >> 64) & 1; + + /* + * If there is a borrow (t = 1), then we must add the modulus + * p = 2^256 - 2^224 + 2^192 + 2^96 - 1. + */ + w = (unsigned __int128)d[0] - t; + d[0] = (uint64_t)w; + w = (unsigned __int128)d[1] + (t << 32) - ((w >> 64) & 1); + d[1] = (uint64_t)w; + /* Here, carry "w >> 64" can only be 0 or +1 */ + w = (unsigned __int128)d[2] + (w >> 64); + d[2] = (uint64_t)w; + /* Again, carry is 0 or +1 */ + w = (unsigned __int128)d[3] + (w >> 64) - (t << 32) + t; + d[3] = (uint64_t)w; + t = (uint64_t)(w >> 64) & 1; + + /* + * There may be again a borrow, in which case we must add the + * modulus again. + */ + w = (unsigned __int128)d[0] - t; + d[0] = (uint64_t)w; + w = (unsigned __int128)d[1] + (t << 32) - ((w >> 64) & 1); + d[1] = (uint64_t)w; + w = (unsigned __int128)d[2] + (w >> 64); + d[2] = (uint64_t)w; + d[3] += (uint64_t)(w >> 64) - (t << 32) + t; + +#elif BR_UMUL128 + + unsigned char cc; + uint64_t t; + + cc = _subborrow_u64(0, a[0], b[0], &d[0]); + cc = _subborrow_u64(cc, a[1], b[1], &d[1]); + cc = _subborrow_u64(cc, a[2], b[2], &d[2]); + cc = _subborrow_u64(cc, a[3], b[3], &d[3]); + + /* + * If there is a borrow, then we need to add p. We (virtually) + * add 2^256, then subtract 2^256 - p. + */ + t = cc; + cc = _subborrow_u64(0, d[0], t, &d[0]); + cc = _subborrow_u64(cc, d[1], -(t << 32), &d[1]); + cc = _subborrow_u64(cc, d[2], -t, &d[2]); + cc = _subborrow_u64(cc, d[3], (t << 32) - (t << 1), &d[3]); + + /* + * If there still is a borrow, then we need to add p again. + */ + t = cc; + cc = _subborrow_u64(0, d[0], t, &d[0]); + cc = _subborrow_u64(cc, d[1], -(t << 32), &d[1]); + cc = _subborrow_u64(cc, d[2], -t, &d[2]); + (void)_subborrow_u64(cc, d[3], (t << 32) - (t << 1), &d[3]); + +#endif +} + +/* + * Montgomery multiplication in the field. + */ +static void +f256_montymul(uint64_t *d, const uint64_t *a, const uint64_t *b) +{ +#if BR_INT128 + + uint64_t x, f, t0, t1, t2, t3, t4; + unsigned __int128 z, ff; + int i; + + /* + * When computing d <- d + a[u]*b, we also add f*p such + * that d + a[u]*b + f*p is a multiple of 2^64. Since + * p = -1 mod 2^64, we can compute f = d[0] + a[u]*b[0] mod 2^64. + */ + + /* + * Step 1: t <- (a[0]*b + f*p) / 2^64 + * We have f = a[0]*b[0] mod 2^64. Since p = -1 mod 2^64, this + * ensures that (a[0]*b + f*p) is a multiple of 2^64. + * + * We also have: f*p = f*2^256 - f*2^224 + f*2^192 + f*2^96 - f. + */ + x = a[0]; + z = (unsigned __int128)b[0] * x; + f = (uint64_t)z; + z = (unsigned __int128)b[1] * x + (z >> 64) + (uint64_t)(f << 32); + t0 = (uint64_t)z; + z = (unsigned __int128)b[2] * x + (z >> 64) + (uint64_t)(f >> 32); + t1 = (uint64_t)z; + z = (unsigned __int128)b[3] * x + (z >> 64) + f; + t2 = (uint64_t)z; + t3 = (uint64_t)(z >> 64); + ff = ((unsigned __int128)f << 64) - ((unsigned __int128)f << 32); + z = (unsigned __int128)t2 + (uint64_t)ff; + t2 = (uint64_t)z; + z = (unsigned __int128)t3 + (z >> 64) + (ff >> 64); + t3 = (uint64_t)z; + t4 = (uint64_t)(z >> 64); + + /* + * Steps 2 to 4: t <- (t + a[i]*b + f*p) / 2^64 + */ + for (i = 1; i < 4; i ++) { + x = a[i]; + + /* t <- (t + x*b - f) / 2^64 */ + z = (unsigned __int128)b[0] * x + t0; + f = (uint64_t)z; + z = (unsigned __int128)b[1] * x + t1 + (z >> 64); + t0 = (uint64_t)z; + z = (unsigned __int128)b[2] * x + t2 + (z >> 64); + t1 = (uint64_t)z; + z = (unsigned __int128)b[3] * x + t3 + (z >> 64); + t2 = (uint64_t)z; + z = t4 + (z >> 64); + t3 = (uint64_t)z; + t4 = (uint64_t)(z >> 64); + + /* t <- t + f*2^32, carry in the upper half of z */ + z = (unsigned __int128)t0 + (uint64_t)(f << 32); + t0 = (uint64_t)z; + z = (z >> 64) + (unsigned __int128)t1 + (uint64_t)(f >> 32); + t1 = (uint64_t)z; + + /* t <- t + f*2^192 - f*2^160 + f*2^128 */ + ff = ((unsigned __int128)f << 64) + - ((unsigned __int128)f << 32) + f; + z = (z >> 64) + (unsigned __int128)t2 + (uint64_t)ff; + t2 = (uint64_t)z; + z = (unsigned __int128)t3 + (z >> 64) + (ff >> 64); + t3 = (uint64_t)z; + t4 += (uint64_t)(z >> 64); + } + + /* + * At that point, we have computed t = (a*b + F*p) / 2^256, where + * F is a 256-bit integer whose limbs are the "f" coefficients + * in the steps above. We have: + * a <= 2^256-1 + * b <= 2^256-1 + * F <= 2^256-1 + * Hence: + * a*b + F*p <= (2^256-1)*(2^256-1) + p*(2^256-1) + * a*b + F*p <= 2^256*(2^256 - 2 + p) + 1 - p + * Therefore: + * t < 2^256 + p - 2 + * Since p < 2^256, it follows that: + * t4 can be only 0 or 1 + * t - p < 2^256 + * We can therefore subtract p from t, conditionally on t4, to + * get a nonnegative result that fits on 256 bits. + */ + z = (unsigned __int128)t0 + t4; + t0 = (uint64_t)z; + z = (unsigned __int128)t1 - (t4 << 32) + (z >> 64); + t1 = (uint64_t)z; + z = (unsigned __int128)t2 - (z >> 127); + t2 = (uint64_t)z; + t3 = t3 - (uint64_t)(z >> 127) - t4 + (t4 << 32); + + d[0] = t0; + d[1] = t1; + d[2] = t2; + d[3] = t3; + +#elif BR_UMUL128 + + uint64_t x, f, t0, t1, t2, t3, t4; + uint64_t zl, zh, ffl, ffh; + unsigned char k, m; + int i; + + /* + * When computing d <- d + a[u]*b, we also add f*p such + * that d + a[u]*b + f*p is a multiple of 2^64. Since + * p = -1 mod 2^64, we can compute f = d[0] + a[u]*b[0] mod 2^64. + */ + + /* + * Step 1: t <- (a[0]*b + f*p) / 2^64 + * We have f = a[0]*b[0] mod 2^64. Since p = -1 mod 2^64, this + * ensures that (a[0]*b + f*p) is a multiple of 2^64. + * + * We also have: f*p = f*2^256 - f*2^224 + f*2^192 + f*2^96 - f. + */ + x = a[0]; + + zl = _umul128(b[0], x, &zh); + f = zl; + t0 = zh; + + zl = _umul128(b[1], x, &zh); + k = _addcarry_u64(0, zl, t0, &zl); + (void)_addcarry_u64(k, zh, 0, &zh); + k = _addcarry_u64(0, zl, f << 32, &zl); + (void)_addcarry_u64(k, zh, 0, &zh); + t0 = zl; + t1 = zh; + + zl = _umul128(b[2], x, &zh); + k = _addcarry_u64(0, zl, t1, &zl); + (void)_addcarry_u64(k, zh, 0, &zh); + k = _addcarry_u64(0, zl, f >> 32, &zl); + (void)_addcarry_u64(k, zh, 0, &zh); + t1 = zl; + t2 = zh; + + zl = _umul128(b[3], x, &zh); + k = _addcarry_u64(0, zl, t2, &zl); + (void)_addcarry_u64(k, zh, 0, &zh); + k = _addcarry_u64(0, zl, f, &zl); + (void)_addcarry_u64(k, zh, 0, &zh); + t2 = zl; + t3 = zh; + + t4 = _addcarry_u64(0, t3, f, &t3); + k = _subborrow_u64(0, t2, f << 32, &t2); + k = _subborrow_u64(k, t3, f >> 32, &t3); + (void)_subborrow_u64(k, t4, 0, &t4); + + /* + * Steps 2 to 4: t <- (t + a[i]*b + f*p) / 2^64 + */ + for (i = 1; i < 4; i ++) { + x = a[i]; + /* f = t0 + x * b[0]; -- computed below */ + + /* t <- (t + x*b - f) / 2^64 */ + zl = _umul128(b[0], x, &zh); + k = _addcarry_u64(0, zl, t0, &f); + (void)_addcarry_u64(k, zh, 0, &t0); + + zl = _umul128(b[1], x, &zh); + k = _addcarry_u64(0, zl, t0, &zl); + (void)_addcarry_u64(k, zh, 0, &zh); + k = _addcarry_u64(0, zl, t1, &t0); + (void)_addcarry_u64(k, zh, 0, &t1); + + zl = _umul128(b[2], x, &zh); + k = _addcarry_u64(0, zl, t1, &zl); + (void)_addcarry_u64(k, zh, 0, &zh); + k = _addcarry_u64(0, zl, t2, &t1); + (void)_addcarry_u64(k, zh, 0, &t2); + + zl = _umul128(b[3], x, &zh); + k = _addcarry_u64(0, zl, t2, &zl); + (void)_addcarry_u64(k, zh, 0, &zh); + k = _addcarry_u64(0, zl, t3, &t2); + (void)_addcarry_u64(k, zh, 0, &t3); + + t4 = _addcarry_u64(0, t3, t4, &t3); + + /* t <- t + f*2^32, carry in k */ + k = _addcarry_u64(0, t0, f << 32, &t0); + k = _addcarry_u64(k, t1, f >> 32, &t1); + + /* t <- t + f*2^192 - f*2^160 + f*2^128 */ + m = _subborrow_u64(0, f, f << 32, &ffl); + (void)_subborrow_u64(m, f, f >> 32, &ffh); + k = _addcarry_u64(k, t2, ffl, &t2); + k = _addcarry_u64(k, t3, ffh, &t3); + (void)_addcarry_u64(k, t4, 0, &t4); + } + + /* + * At that point, we have computed t = (a*b + F*p) / 2^256, where + * F is a 256-bit integer whose limbs are the "f" coefficients + * in the steps above. We have: + * a <= 2^256-1 + * b <= 2^256-1 + * F <= 2^256-1 + * Hence: + * a*b + F*p <= (2^256-1)*(2^256-1) + p*(2^256-1) + * a*b + F*p <= 2^256*(2^256 - 2 + p) + 1 - p + * Therefore: + * t < 2^256 + p - 2 + * Since p < 2^256, it follows that: + * t4 can be only 0 or 1 + * t - p < 2^256 + * We can therefore subtract p from t, conditionally on t4, to + * get a nonnegative result that fits on 256 bits. + */ + k = _addcarry_u64(0, t0, t4, &t0); + k = _addcarry_u64(k, t1, -(t4 << 32), &t1); + k = _addcarry_u64(k, t2, -t4, &t2); + (void)_addcarry_u64(k, t3, (t4 << 32) - (t4 << 1), &t3); + + d[0] = t0; + d[1] = t1; + d[2] = t2; + d[3] = t3; + +#endif +} + +/* + * Montgomery squaring in the field; currently a basic wrapper around + * multiplication (inline, should be optimized away). + * TODO: see if some extra speed can be gained here. + */ +static inline void +f256_montysquare(uint64_t *d, const uint64_t *a) +{ + f256_montymul(d, a, a); +} + +/* + * Convert to Montgomery representation. + */ +static void +f256_tomonty(uint64_t *d, const uint64_t *a) +{ + /* + * R2 = 2^512 mod p. + * If R = 2^256 mod p, then R2 = R^2 mod p; and the Montgomery + * multiplication of a by R2 is: a*R2/R = a*R mod p, i.e. the + * conversion to Montgomery representation. + */ + static const uint64_t R2[] = { + 0x0000000000000003, + 0xFFFFFFFBFFFFFFFF, + 0xFFFFFFFFFFFFFFFE, + 0x00000004FFFFFFFD + }; + + f256_montymul(d, a, R2); +} + +/* + * Convert from Montgomery representation. + */ +static void +f256_frommonty(uint64_t *d, const uint64_t *a) +{ + /* + * Montgomery multiplication by 1 is division by 2^256 modulo p. + */ + static const uint64_t one[] = { 1, 0, 0, 0 }; + + f256_montymul(d, a, one); +} + +/* + * Inversion in the field. If the source value is 0 modulo p, then this + * returns 0 or p. This function uses Montgomery representation. + */ +static void +f256_invert(uint64_t *d, const uint64_t *a) +{ + /* + * We compute a^(p-2) mod p. The exponent pattern (from high to + * low) is: + * - 32 bits of value 1 + * - 31 bits of value 0 + * - 1 bit of value 1 + * - 96 bits of value 0 + * - 94 bits of value 1 + * - 1 bit of value 0 + * - 1 bit of value 1 + * To speed up the square-and-multiply algorithm, we precompute + * a^(2^31-1). + */ + + uint64_t r[4], t[4]; + int i; + + memcpy(t, a, sizeof t); + for (i = 0; i < 30; i ++) { + f256_montysquare(t, t); + f256_montymul(t, t, a); + } + + memcpy(r, t, sizeof t); + for (i = 224; i >= 0; i --) { + f256_montysquare(r, r); + switch (i) { + case 0: + case 2: + case 192: + case 224: + f256_montymul(r, r, a); + break; + case 3: + case 34: + case 65: + f256_montymul(r, r, t); + break; + } + } + memcpy(d, r, sizeof r); +} + +/* + * Finalize reduction. + * Input value fits on 256 bits. This function subtracts p if and only + * if the input is greater than or equal to p. + */ +static inline void +f256_final_reduce(uint64_t *a) +{ +#if BR_INT128 + + uint64_t t0, t1, t2, t3, cc; + unsigned __int128 z; + + /* + * We add 2^224 - 2^192 - 2^96 + 1 to a. If there is no carry, + * then a < p; otherwise, the addition result we computed is + * the value we must return. + */ + z = (unsigned __int128)a[0] + 1; + t0 = (uint64_t)z; + z = (unsigned __int128)a[1] + (z >> 64) - ((uint64_t)1 << 32); + t1 = (uint64_t)z; + z = (unsigned __int128)a[2] - (z >> 127); + t2 = (uint64_t)z; + z = (unsigned __int128)a[3] - (z >> 127) + 0xFFFFFFFF; + t3 = (uint64_t)z; + cc = -(uint64_t)(z >> 64); + + a[0] ^= cc & (a[0] ^ t0); + a[1] ^= cc & (a[1] ^ t1); + a[2] ^= cc & (a[2] ^ t2); + a[3] ^= cc & (a[3] ^ t3); + +#elif BR_UMUL128 + + uint64_t t0, t1, t2, t3, m; + unsigned char k; + + k = _addcarry_u64(0, a[0], (uint64_t)1, &t0); + k = _addcarry_u64(k, a[1], -((uint64_t)1 << 32), &t1); + k = _addcarry_u64(k, a[2], -(uint64_t)1, &t2); + k = _addcarry_u64(k, a[3], ((uint64_t)1 << 32) - 2, &t3); + m = -(uint64_t)k; + + a[0] ^= m & (a[0] ^ t0); + a[1] ^= m & (a[1] ^ t1); + a[2] ^= m & (a[2] ^ t2); + a[3] ^= m & (a[3] ^ t3); + +#endif +} + +/* + * Points in affine and Jacobian coordinates. + * + * - In affine coordinates, the point-at-infinity cannot be encoded. + * - Jacobian coordinates (X,Y,Z) correspond to affine (X/Z^2,Y/Z^3); + * if Z = 0 then this is the point-at-infinity. + */ +typedef struct { + uint64_t x[4]; + uint64_t y[4]; +} p256_affine; + +typedef struct { + uint64_t x[4]; + uint64_t y[4]; + uint64_t z[4]; +} p256_jacobian; + +/* + * Decode a point. The returned point is in Jacobian coordinates, but + * with z = 1. If the encoding is invalid, or encodes a point which is + * not on the curve, or encodes the point at infinity, then this function + * returns 0. Otherwise, 1 is returned. + * + * The buffer is assumed to have length exactly 65 bytes. + */ +static uint32_t +point_decode(p256_jacobian *P, const unsigned char *buf) +{ + uint64_t x[4], y[4], t[4], x3[4], tt; + uint32_t r; + + /* + * Header byte shall be 0x04. + */ + r = EQ(buf[0], 0x04); + + /* + * Decode X and Y coordinates, and convert them into + * Montgomery representation. + */ + x[3] = br_dec64be(buf + 1); + x[2] = br_dec64be(buf + 9); + x[1] = br_dec64be(buf + 17); + x[0] = br_dec64be(buf + 25); + y[3] = br_dec64be(buf + 33); + y[2] = br_dec64be(buf + 41); + y[1] = br_dec64be(buf + 49); + y[0] = br_dec64be(buf + 57); + f256_tomonty(x, x); + f256_tomonty(y, y); + + /* + * Verify y^2 = x^3 + A*x + B. In curve P-256, A = -3. + * Note that the Montgomery representation of 0 is 0. We must + * take care to apply the final reduction to make sure we have + * 0 and not p. + */ + f256_montysquare(t, y); + f256_montysquare(x3, x); + f256_montymul(x3, x3, x); + f256_sub(t, t, x3); + f256_add(t, t, x); + f256_add(t, t, x); + f256_add(t, t, x); + f256_sub(t, t, P256_B_MONTY); + f256_final_reduce(t); + tt = t[0] | t[1] | t[2] | t[3]; + r &= EQ((uint32_t)(tt | (tt >> 32)), 0); + + /* + * Return the point in Jacobian coordinates (and Montgomery + * representation). + */ + memcpy(P->x, x, sizeof x); + memcpy(P->y, y, sizeof y); + memcpy(P->z, F256_R, sizeof F256_R); + return r; +} + +/* + * Final conversion for a point: + * - The point is converted back to affine coordinates. + * - Final reduction is performed. + * - The point is encoded into the provided buffer. + * + * If the point is the point-at-infinity, all operations are performed, + * but the buffer contents are indeterminate, and 0 is returned. Otherwise, + * the encoded point is written in the buffer, and 1 is returned. + */ +static uint32_t +point_encode(unsigned char *buf, const p256_jacobian *P) +{ + uint64_t t1[4], t2[4], z; + + /* Set t1 = 1/z^2 and t2 = 1/z^3. */ + f256_invert(t2, P->z); + f256_montysquare(t1, t2); + f256_montymul(t2, t2, t1); + + /* Compute affine coordinates x (in t1) and y (in t2). */ + f256_montymul(t1, P->x, t1); + f256_montymul(t2, P->y, t2); + + /* Convert back from Montgomery representation, and finalize + reductions. */ + f256_frommonty(t1, t1); + f256_frommonty(t2, t2); + f256_final_reduce(t1); + f256_final_reduce(t2); + + /* Encode. */ + buf[0] = 0x04; + br_enc64be(buf + 1, t1[3]); + br_enc64be(buf + 9, t1[2]); + br_enc64be(buf + 17, t1[1]); + br_enc64be(buf + 25, t1[0]); + br_enc64be(buf + 33, t2[3]); + br_enc64be(buf + 41, t2[2]); + br_enc64be(buf + 49, t2[1]); + br_enc64be(buf + 57, t2[0]); + + /* Return success if and only if P->z != 0. */ + z = P->z[0] | P->z[1] | P->z[2] | P->z[3]; + return NEQ((uint32_t)(z | z >> 32), 0); +} + +/* + * Point doubling in Jacobian coordinates: point P is doubled. + * Note: if the source point is the point-at-infinity, then the result is + * still the point-at-infinity, which is correct. Moreover, if the three + * coordinates were zero, then they still are zero in the returned value. + * + * (Note: this is true even without the final reduction: if the three + * coordinates are encoded as four words of value zero each, then the + * result will also have all-zero coordinate encodings, not the alternate + * encoding as the integer p.) + */ +static void +p256_double(p256_jacobian *P) +{ + /* + * Doubling formulas are: + * + * s = 4*x*y^2 + * m = 3*(x + z^2)*(x - z^2) + * x' = m^2 - 2*s + * y' = m*(s - x') - 8*y^4 + * z' = 2*y*z + * + * These formulas work for all points, including points of order 2 + * and points at infinity: + * - If y = 0 then z' = 0. But there is no such point in P-256 + * anyway. + * - If z = 0 then z' = 0. + */ + uint64_t t1[4], t2[4], t3[4], t4[4]; + + /* + * Compute z^2 in t1. + */ + f256_montysquare(t1, P->z); + + /* + * Compute x-z^2 in t2 and x+z^2 in t1. + */ + f256_add(t2, P->x, t1); + f256_sub(t1, P->x, t1); + + /* + * Compute 3*(x+z^2)*(x-z^2) in t1. + */ + f256_montymul(t3, t1, t2); + f256_add(t1, t3, t3); + f256_add(t1, t3, t1); + + /* + * Compute 4*x*y^2 (in t2) and 2*y^2 (in t3). + */ + f256_montysquare(t3, P->y); + f256_add(t3, t3, t3); + f256_montymul(t2, P->x, t3); + f256_add(t2, t2, t2); + + /* + * Compute x' = m^2 - 2*s. + */ + f256_montysquare(P->x, t1); + f256_sub(P->x, P->x, t2); + f256_sub(P->x, P->x, t2); + + /* + * Compute z' = 2*y*z. + */ + f256_montymul(t4, P->y, P->z); + f256_add(P->z, t4, t4); + + /* + * Compute y' = m*(s - x') - 8*y^4. Note that we already have + * 2*y^2 in t3. + */ + f256_sub(t2, t2, P->x); + f256_montymul(P->y, t1, t2); + f256_montysquare(t4, t3); + f256_add(t4, t4, t4); + f256_sub(P->y, P->y, t4); +} + +/* + * Point addition (Jacobian coordinates): P1 is replaced with P1+P2. + * This function computes the wrong result in the following cases: + * + * - If P1 == 0 but P2 != 0 + * - If P1 != 0 but P2 == 0 + * - If P1 == P2 + * + * In all three cases, P1 is set to the point at infinity. + * + * Returned value is 0 if one of the following occurs: + * + * - P1 and P2 have the same Y coordinate. + * - P1 == 0 and P2 == 0. + * - The Y coordinate of one of the points is 0 and the other point is + * the point at infinity. + * + * The third case cannot actually happen with valid points, since a point + * with Y == 0 is a point of order 2, and there is no point of order 2 on + * curve P-256. + * + * Therefore, assuming that P1 != 0 and P2 != 0 on input, then the caller + * can apply the following: + * + * - If the result is not the point at infinity, then it is correct. + * - Otherwise, if the returned value is 1, then this is a case of + * P1+P2 == 0, so the result is indeed the point at infinity. + * - Otherwise, P1 == P2, so a "double" operation should have been + * performed. + * + * Note that you can get a returned value of 0 with a correct result, + * e.g. if P1 and P2 have the same Y coordinate, but distinct X coordinates. + */ +static uint32_t +p256_add(p256_jacobian *P1, const p256_jacobian *P2) +{ + /* + * Addtions formulas are: + * + * u1 = x1 * z2^2 + * u2 = x2 * z1^2 + * s1 = y1 * z2^3 + * s2 = y2 * z1^3 + * h = u2 - u1 + * r = s2 - s1 + * x3 = r^2 - h^3 - 2 * u1 * h^2 + * y3 = r * (u1 * h^2 - x3) - s1 * h^3 + * z3 = h * z1 * z2 + */ + uint64_t t1[4], t2[4], t3[4], t4[4], t5[4], t6[4], t7[4], tt; + uint32_t ret; + + /* + * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3). + */ + f256_montysquare(t3, P2->z); + f256_montymul(t1, P1->x, t3); + f256_montymul(t4, P2->z, t3); + f256_montymul(t3, P1->y, t4); + + /* + * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). + */ + f256_montysquare(t4, P1->z); + f256_montymul(t2, P2->x, t4); + f256_montymul(t5, P1->z, t4); + f256_montymul(t4, P2->y, t5); + + /* + * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). + * We need to test whether r is zero, so we will do some extra + * reduce. + */ + f256_sub(t2, t2, t1); + f256_sub(t4, t4, t3); + f256_final_reduce(t4); + tt = t4[0] | t4[1] | t4[2] | t4[3]; + ret = (uint32_t)(tt | (tt >> 32)); + ret = (ret | -ret) >> 31; + + /* + * Compute u1*h^2 (in t6) and h^3 (in t5); + */ + f256_montysquare(t7, t2); + f256_montymul(t6, t1, t7); + f256_montymul(t5, t7, t2); + + /* + * Compute x3 = r^2 - h^3 - 2*u1*h^2. + */ + f256_montysquare(P1->x, t4); + f256_sub(P1->x, P1->x, t5); + f256_sub(P1->x, P1->x, t6); + f256_sub(P1->x, P1->x, t6); + + /* + * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. + */ + f256_sub(t6, t6, P1->x); + f256_montymul(P1->y, t4, t6); + f256_montymul(t1, t5, t3); + f256_sub(P1->y, P1->y, t1); + + /* + * Compute z3 = h*z1*z2. + */ + f256_montymul(t1, P1->z, P2->z); + f256_montymul(P1->z, t1, t2); + + return ret; +} + +/* + * Point addition (mixed coordinates): P1 is replaced with P1+P2. + * This is a specialised function for the case when P2 is a non-zero point + * in affine coordinates. + * + * This function computes the wrong result in the following cases: + * + * - If P1 == 0 + * - If P1 == P2 + * + * In both cases, P1 is set to the point at infinity. + * + * Returned value is 0 if one of the following occurs: + * + * - P1 and P2 have the same Y (affine) coordinate. + * - The Y coordinate of P2 is 0 and P1 is the point at infinity. + * + * The second case cannot actually happen with valid points, since a point + * with Y == 0 is a point of order 2, and there is no point of order 2 on + * curve P-256. + * + * Therefore, assuming that P1 != 0 on input, then the caller + * can apply the following: + * + * - If the result is not the point at infinity, then it is correct. + * - Otherwise, if the returned value is 1, then this is a case of + * P1+P2 == 0, so the result is indeed the point at infinity. + * - Otherwise, P1 == P2, so a "double" operation should have been + * performed. + * + * Again, a value of 0 may be returned in some cases where the addition + * result is correct. + */ +static uint32_t +p256_add_mixed(p256_jacobian *P1, const p256_affine *P2) +{ + /* + * Addtions formulas are: + * + * u1 = x1 + * u2 = x2 * z1^2 + * s1 = y1 + * s2 = y2 * z1^3 + * h = u2 - u1 + * r = s2 - s1 + * x3 = r^2 - h^3 - 2 * u1 * h^2 + * y3 = r * (u1 * h^2 - x3) - s1 * h^3 + * z3 = h * z1 + */ + uint64_t t1[4], t2[4], t3[4], t4[4], t5[4], t6[4], t7[4], tt; + uint32_t ret; + + /* + * Compute u1 = x1 (in t1) and s1 = y1 (in t3). + */ + memcpy(t1, P1->x, sizeof t1); + memcpy(t3, P1->y, sizeof t3); + + /* + * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). + */ + f256_montysquare(t4, P1->z); + f256_montymul(t2, P2->x, t4); + f256_montymul(t5, P1->z, t4); + f256_montymul(t4, P2->y, t5); + + /* + * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). + * We need to test whether r is zero, so we will do some extra + * reduce. + */ + f256_sub(t2, t2, t1); + f256_sub(t4, t4, t3); + f256_final_reduce(t4); + tt = t4[0] | t4[1] | t4[2] | t4[3]; + ret = (uint32_t)(tt | (tt >> 32)); + ret = (ret | -ret) >> 31; + + /* + * Compute u1*h^2 (in t6) and h^3 (in t5); + */ + f256_montysquare(t7, t2); + f256_montymul(t6, t1, t7); + f256_montymul(t5, t7, t2); + + /* + * Compute x3 = r^2 - h^3 - 2*u1*h^2. + */ + f256_montysquare(P1->x, t4); + f256_sub(P1->x, P1->x, t5); + f256_sub(P1->x, P1->x, t6); + f256_sub(P1->x, P1->x, t6); + + /* + * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. + */ + f256_sub(t6, t6, P1->x); + f256_montymul(P1->y, t4, t6); + f256_montymul(t1, t5, t3); + f256_sub(P1->y, P1->y, t1); + + /* + * Compute z3 = h*z1*z2. + */ + f256_montymul(P1->z, P1->z, t2); + + return ret; +} + +#if 0 +/* unused */ +/* + * Point addition (mixed coordinates, complete): P1 is replaced with P1+P2. + * This is a specialised function for the case when P2 is a non-zero point + * in affine coordinates. + * + * This function returns the correct result in all cases. + */ +static uint32_t +p256_add_complete_mixed(p256_jacobian *P1, const p256_affine *P2) +{ + /* + * Addtions formulas, in the general case, are: + * + * u1 = x1 + * u2 = x2 * z1^2 + * s1 = y1 + * s2 = y2 * z1^3 + * h = u2 - u1 + * r = s2 - s1 + * x3 = r^2 - h^3 - 2 * u1 * h^2 + * y3 = r * (u1 * h^2 - x3) - s1 * h^3 + * z3 = h * z1 + * + * These formulas mishandle the two following cases: + * + * - If P1 is the point-at-infinity (z1 = 0), then z3 is + * incorrectly set to 0. + * + * - If P1 = P2, then u1 = u2 and s1 = s2, and x3, y3 and z3 + * are all set to 0. + * + * However, if P1 + P2 = 0, then u1 = u2 but s1 != s2, and then + * we correctly get z3 = 0 (the point-at-infinity). + * + * To fix the case P1 = 0, we perform at the end a copy of P2 + * over P1, conditional to z1 = 0. + * + * For P1 = P2: in that case, both h and r are set to 0, and + * we get x3, y3 and z3 equal to 0. We can test for that + * occurrence to make a mask which will be all-one if P1 = P2, + * or all-zero otherwise; then we can compute the double of P2 + * and add it, combined with the mask, to (x3,y3,z3). + * + * Using the doubling formulas in p256_double() on (x2,y2), + * simplifying since P2 is affine (i.e. z2 = 1, implicitly), + * we get: + * s = 4*x2*y2^2 + * m = 3*(x2 + 1)*(x2 - 1) + * x' = m^2 - 2*s + * y' = m*(s - x') - 8*y2^4 + * z' = 2*y2 + * which requires only 6 multiplications. Added to the 11 + * multiplications of the normal mixed addition in Jacobian + * coordinates, we get a cost of 17 multiplications in total. + */ + uint64_t t1[4], t2[4], t3[4], t4[4], t5[4], t6[4], t7[4], tt, zz; + int i; + + /* + * Set zz to -1 if P1 is the point at infinity, 0 otherwise. + */ + zz = P1->z[0] | P1->z[1] | P1->z[2] | P1->z[3]; + zz = ((zz | -zz) >> 63) - (uint64_t)1; + + /* + * Compute u1 = x1 (in t1) and s1 = y1 (in t3). + */ + memcpy(t1, P1->x, sizeof t1); + memcpy(t3, P1->y, sizeof t3); + + /* + * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). + */ + f256_montysquare(t4, P1->z); + f256_montymul(t2, P2->x, t4); + f256_montymul(t5, P1->z, t4); + f256_montymul(t4, P2->y, t5); + + /* + * Compute h = h2 - u1 (in t2) and r = s2 - s1 (in t4). + * reduce. + */ + f256_sub(t2, t2, t1); + f256_sub(t4, t4, t3); + + /* + * If both h = 0 and r = 0, then P1 = P2, and we want to set + * the mask tt to -1; otherwise, the mask will be 0. + */ + f256_final_reduce(t2); + f256_final_reduce(t4); + tt = t2[0] | t2[1] | t2[2] | t2[3] | t4[0] | t4[1] | t4[2] | t4[3]; + tt = ((tt | -tt) >> 63) - (uint64_t)1; + + /* + * Compute u1*h^2 (in t6) and h^3 (in t5); + */ + f256_montysquare(t7, t2); + f256_montymul(t6, t1, t7); + f256_montymul(t5, t7, t2); + + /* + * Compute x3 = r^2 - h^3 - 2*u1*h^2. + */ + f256_montysquare(P1->x, t4); + f256_sub(P1->x, P1->x, t5); + f256_sub(P1->x, P1->x, t6); + f256_sub(P1->x, P1->x, t6); + + /* + * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. + */ + f256_sub(t6, t6, P1->x); + f256_montymul(P1->y, t4, t6); + f256_montymul(t1, t5, t3); + f256_sub(P1->y, P1->y, t1); + + /* + * Compute z3 = h*z1. + */ + f256_montymul(P1->z, P1->z, t2); + + /* + * The "double" result, in case P1 = P2. + */ + + /* + * Compute z' = 2*y2 (in t1). + */ + f256_add(t1, P2->y, P2->y); + + /* + * Compute 2*(y2^2) (in t2) and s = 4*x2*(y2^2) (in t3). + */ + f256_montysquare(t2, P2->y); + f256_add(t2, t2, t2); + f256_add(t3, t2, t2); + f256_montymul(t3, P2->x, t3); + + /* + * Compute m = 3*(x2^2 - 1) (in t4). + */ + f256_montysquare(t4, P2->x); + f256_sub(t4, t4, F256_R); + f256_add(t5, t4, t4); + f256_add(t4, t4, t5); + + /* + * Compute x' = m^2 - 2*s (in t5). + */ + f256_montysquare(t5, t4); + f256_sub(t5, t3); + f256_sub(t5, t3); + + /* + * Compute y' = m*(s - x') - 8*y2^4 (in t6). + */ + f256_sub(t6, t3, t5); + f256_montymul(t6, t6, t4); + f256_montysquare(t7, t2); + f256_sub(t6, t6, t7); + f256_sub(t6, t6, t7); + + /* + * We now have the alternate (doubling) coordinates in (t5,t6,t1). + * We combine them with (x3,y3,z3). + */ + for (i = 0; i < 4; i ++) { + P1->x[i] |= tt & t5[i]; + P1->y[i] |= tt & t6[i]; + P1->z[i] |= tt & t1[i]; + } + + /* + * If P1 = 0, then we get z3 = 0 (which is invalid); if z1 is 0, + * then we want to replace the result with a copy of P2. The + * test on z1 was done at the start, in the zz mask. + */ + for (i = 0; i < 4; i ++) { + P1->x[i] ^= zz & (P1->x[i] ^ P2->x[i]); + P1->y[i] ^= zz & (P1->y[i] ^ P2->y[i]); + P1->z[i] ^= zz & (P1->z[i] ^ F256_R[i]); + } +} +#endif + +/* + * Inner function for computing a point multiplication. A window is + * provided, with points 1*P to 15*P in affine coordinates. + * + * Assumptions: + * - All provided points are valid points on the curve. + * - Multiplier is non-zero, and smaller than the curve order. + * - Everything is in Montgomery representation. + */ +static void +point_mul_inner(p256_jacobian *R, const p256_affine *W, + const unsigned char *k, size_t klen) +{ + p256_jacobian Q; + uint32_t qz; + + memset(&Q, 0, sizeof Q); + qz = 1; + while (klen -- > 0) { + int i; + unsigned bk; + + bk = *k ++; + for (i = 0; i < 2; i ++) { + uint32_t bits; + uint32_t bnz; + p256_affine T; + p256_jacobian U; + uint32_t n; + int j; + uint64_t m; + + p256_double(&Q); + p256_double(&Q); + p256_double(&Q); + p256_double(&Q); + bits = (bk >> 4) & 0x0F; + bnz = NEQ(bits, 0); + + /* + * Lookup point in window. If the bits are 0, + * we get something invalid, which is not a + * problem because we will use it only if the + * bits are non-zero. + */ + memset(&T, 0, sizeof T); + for (n = 0; n < 15; n ++) { + m = -(uint64_t)EQ(bits, n + 1); + T.x[0] |= m & W[n].x[0]; + T.x[1] |= m & W[n].x[1]; + T.x[2] |= m & W[n].x[2]; + T.x[3] |= m & W[n].x[3]; + T.y[0] |= m & W[n].y[0]; + T.y[1] |= m & W[n].y[1]; + T.y[2] |= m & W[n].y[2]; + T.y[3] |= m & W[n].y[3]; + } + + U = Q; + p256_add_mixed(&U, &T); + + /* + * If qz is still 1, then Q was all-zeros, and this + * is conserved through p256_double(). + */ + m = -(uint64_t)(bnz & qz); + for (j = 0; j < 4; j ++) { + Q.x[j] |= m & T.x[j]; + Q.y[j] |= m & T.y[j]; + Q.z[j] |= m & F256_R[j]; + } + CCOPY(bnz & ~qz, &Q, &U, sizeof Q); + qz &= ~bnz; + bk <<= 4; + } + } + *R = Q; +} + +/* + * Convert a window from Jacobian to affine coordinates. A single + * field inversion is used. This function works for windows up to + * 32 elements. + * + * The destination array (aff[]) and the source array (jac[]) may + * overlap, provided that the start of aff[] is not after the start of + * jac[]. Even if the arrays do _not_ overlap, the source array is + * modified. + */ +static void +window_to_affine(p256_affine *aff, p256_jacobian *jac, int num) +{ + /* + * Convert the window points to affine coordinates. We use the + * following trick to mutualize the inversion computation: if + * we have z1, z2, z3, and z4, and want to inverse all of them, + * we compute u = 1/(z1*z2*z3*z4), and then we have: + * 1/z1 = u*z2*z3*z4 + * 1/z2 = u*z1*z3*z4 + * 1/z3 = u*z1*z2*z4 + * 1/z4 = u*z1*z2*z3 + * + * The partial products are computed recursively: + * + * - on input (z_1,z_2), return (z_2,z_1) and z_1*z_2 + * - on input (z_1,z_2,... z_n): + * recurse on (z_1,z_2,... z_(n/2)) -> r1 and m1 + * recurse on (z_(n/2+1),z_(n/2+2)... z_n) -> r2 and m2 + * multiply elements of r1 by m2 -> s1 + * multiply elements of r2 by m1 -> s2 + * return r1||r2 and m1*m2 + * + * In the example below, we suppose that we have 14 elements. + * Let z1, z2,... zE be the 14 values to invert (index noted in + * hexadecimal, starting at 1). + * + * - Depth 1: + * swap(z1, z2); z12 = z1*z2 + * swap(z3, z4); z34 = z3*z4 + * swap(z5, z6); z56 = z5*z6 + * swap(z7, z8); z78 = z7*z8 + * swap(z9, zA); z9A = z9*zA + * swap(zB, zC); zBC = zB*zC + * swap(zD, zE); zDE = zD*zE + * + * - Depth 2: + * z1 <- z1*z34, z2 <- z2*z34, z3 <- z3*z12, z4 <- z4*z12 + * z1234 = z12*z34 + * z5 <- z5*z78, z6 <- z6*z78, z7 <- z7*z56, z8 <- z8*z56 + * z5678 = z56*z78 + * z9 <- z9*zBC, zA <- zA*zBC, zB <- zB*z9A, zC <- zC*z9A + * z9ABC = z9A*zBC + * + * - Depth 3: + * z1 <- z1*z5678, z2 <- z2*z5678, z3 <- z3*z5678, z4 <- z4*z5678 + * z5 <- z5*z1234, z6 <- z6*z1234, z7 <- z7*z1234, z8 <- z8*z1234 + * z12345678 = z1234*z5678 + * z9 <- z9*zDE, zA <- zA*zDE, zB <- zB*zDE, zC <- zC*zDE + * zD <- zD*z9ABC, zE*z9ABC + * z9ABCDE = z9ABC*zDE + * + * - Depth 4: + * multiply z1..z8 by z9ABCDE + * multiply z9..zE by z12345678 + * final z = z12345678*z9ABCDE + */ + + uint64_t z[16][4]; + int i, k, s; +#define zt (z[15]) +#define zu (z[14]) +#define zv (z[13]) + + /* + * First recursion step (pairwise swapping and multiplication). + * If there is an odd number of elements, then we "invent" an + * extra one with coordinate Z = 1 (in Montgomery representation). + */ + for (i = 0; (i + 1) < num; i += 2) { + memcpy(zt, jac[i].z, sizeof zt); + memcpy(jac[i].z, jac[i + 1].z, sizeof zt); + memcpy(jac[i + 1].z, zt, sizeof zt); + f256_montymul(z[i >> 1], jac[i].z, jac[i + 1].z); + } + if ((num & 1) != 0) { + memcpy(z[num >> 1], jac[num - 1].z, sizeof zt); + memcpy(jac[num - 1].z, F256_R, sizeof F256_R); + } + + /* + * Perform further recursion steps. At the entry of each step, + * the process has been done for groups of 's' points. The + * integer k is the log2 of s. + */ + for (k = 1, s = 2; s < num; k ++, s <<= 1) { + int n; + + for (i = 0; i < num; i ++) { + f256_montymul(jac[i].z, jac[i].z, z[(i >> k) ^ 1]); + } + n = (num + s - 1) >> k; + for (i = 0; i < (n >> 1); i ++) { + f256_montymul(z[i], z[i << 1], z[(i << 1) + 1]); + } + if ((n & 1) != 0) { + memmove(z[n >> 1], z[n], sizeof zt); + } + } + + /* + * Invert the final result, and convert all points. + */ + f256_invert(zt, z[0]); + for (i = 0; i < num; i ++) { + f256_montymul(zv, jac[i].z, zt); + f256_montysquare(zu, zv); + f256_montymul(zv, zv, zu); + f256_montymul(aff[i].x, jac[i].x, zu); + f256_montymul(aff[i].y, jac[i].y, zv); + } +} + +/* + * Multiply the provided point by an integer. + * Assumptions: + * - Source point is a valid curve point. + * - Source point is not the point-at-infinity. + * - Integer is not 0, and is lower than the curve order. + * If these conditions are not met, then the result is indeterminate + * (but the process is still constant-time). + */ +static void +p256_mul(p256_jacobian *P, const unsigned char *k, size_t klen) +{ + union { + p256_affine aff[15]; + p256_jacobian jac[15]; + } window; + int i; + + /* + * Compute window, in Jacobian coordinates. + */ + window.jac[0] = *P; + for (i = 2; i < 16; i ++) { + window.jac[i - 1] = window.jac[(i >> 1) - 1]; + if ((i & 1) == 0) { + p256_double(&window.jac[i - 1]); + } else { + p256_add(&window.jac[i - 1], &window.jac[i >> 1]); + } + } + + /* + * Convert the window points to affine coordinates. Point + * window[0] is the source point, already in affine coordinates. + */ + window_to_affine(window.aff, window.jac, 15); + + /* + * Perform point multiplication. + */ + point_mul_inner(P, window.aff, k, klen); +} + +/* + * Precomputed window for the conventional generator: P256_Gwin[n] + * contains (n+1)*G (affine coordinates, in Montgomery representation). + */ +static const p256_affine P256_Gwin[] = { + { + { 0x79E730D418A9143C, 0x75BA95FC5FEDB601, + 0x79FB732B77622510, 0x18905F76A53755C6 }, + { 0xDDF25357CE95560A, 0x8B4AB8E4BA19E45C, + 0xD2E88688DD21F325, 0x8571FF1825885D85 } + }, + { + { 0x850046D410DDD64D, 0xAA6AE3C1A433827D, + 0x732205038D1490D9, 0xF6BB32E43DCF3A3B }, + { 0x2F3648D361BEE1A5, 0x152CD7CBEB236FF8, + 0x19A8FB0E92042DBE, 0x78C577510A5B8A3B } + }, + { + { 0xFFAC3F904EEBC127, 0xB027F84A087D81FB, + 0x66AD77DD87CBBC98, 0x26936A3FB6FF747E }, + { 0xB04C5C1FC983A7EB, 0x583E47AD0861FE1A, + 0x788208311A2EE98E, 0xD5F06A29E587CC07 } + }, + { + { 0x74B0B50D46918DCC, 0x4650A6EDC623C173, + 0x0CDAACACE8100AF2, 0x577362F541B0176B }, + { 0x2D96F24CE4CBABA6, 0x17628471FAD6F447, + 0x6B6C36DEE5DDD22E, 0x84B14C394C5AB863 } + }, + { + { 0xBE1B8AAEC45C61F5, 0x90EC649A94B9537D, + 0x941CB5AAD076C20C, 0xC9079605890523C8 }, + { 0xEB309B4AE7BA4F10, 0x73C568EFE5EB882B, + 0x3540A9877E7A1F68, 0x73A076BB2DD1E916 } + }, + { + { 0x403947373E77664A, 0x55AE744F346CEE3E, + 0xD50A961A5B17A3AD, 0x13074B5954213673 }, + { 0x93D36220D377E44B, 0x299C2B53ADFF14B5, + 0xF424D44CEF639F11, 0xA4C9916D4A07F75F } + }, + { + { 0x0746354EA0173B4F, 0x2BD20213D23C00F7, + 0xF43EAAB50C23BB08, 0x13BA5119C3123E03 }, + { 0x2847D0303F5B9D4D, 0x6742F2F25DA67BDD, + 0xEF933BDC77C94195, 0xEAEDD9156E240867 } + }, + { + { 0x27F14CD19499A78F, 0x462AB5C56F9B3455, + 0x8F90F02AF02CFC6B, 0xB763891EB265230D }, + { 0xF59DA3A9532D4977, 0x21E3327DCF9EBA15, + 0x123C7B84BE60BBF0, 0x56EC12F27706DF76 } + }, + { + { 0x75C96E8F264E20E8, 0xABE6BFED59A7A841, + 0x2CC09C0444C8EB00, 0xE05B3080F0C4E16B }, + { 0x1EB7777AA45F3314, 0x56AF7BEDCE5D45E3, + 0x2B6E019A88B12F1A, 0x086659CDFD835F9B } + }, + { + { 0x2C18DBD19DC21EC8, 0x98F9868A0FCF8139, + 0x737D2CD648250B49, 0xCC61C94724B3428F }, + { 0x0C2B407880DD9E76, 0xC43A8991383FBE08, + 0x5F7D2D65779BE5D2, 0x78719A54EB3B4AB5 } + }, + { + { 0xEA7D260A6245E404, 0x9DE407956E7FDFE0, + 0x1FF3A4158DAC1AB5, 0x3E7090F1649C9073 }, + { 0x1A7685612B944E88, 0x250F939EE57F61C8, + 0x0C0DAA891EAD643D, 0x68930023E125B88E } + }, + { + { 0x04B71AA7D2697768, 0xABDEDEF5CA345A33, + 0x2409D29DEE37385E, 0x4EE1DF77CB83E156 }, + { 0x0CAC12D91CBB5B43, 0x170ED2F6CA895637, + 0x28228CFA8ADE6D66, 0x7FF57C9553238ACA } + }, + { + { 0xCCC425634B2ED709, 0x0E356769856FD30D, + 0xBCBCD43F559E9811, 0x738477AC5395B759 }, + { 0x35752B90C00EE17F, 0x68748390742ED2E3, + 0x7CD06422BD1F5BC1, 0xFBC08769C9E7B797 } + }, + { + { 0xA242A35BB0CF664A, 0x126E48F77F9707E3, + 0x1717BF54C6832660, 0xFAAE7332FD12C72E }, + { 0x27B52DB7995D586B, 0xBE29569E832237C2, + 0xE8E4193E2A65E7DB, 0x152706DC2EAA1BBB } + }, + { + { 0x72BCD8B7BC60055B, 0x03CC23EE56E27E4B, + 0xEE337424E4819370, 0xE2AA0E430AD3DA09 }, + { 0x40B8524F6383C45D, 0xD766355442A41B25, + 0x64EFA6DE778A4797, 0x2042170A7079ADF4 } + } +}; + +/* + * Multiply the conventional generator of the curve by the provided + * integer. Return is written in *P. + * + * Assumptions: + * - Integer is not 0, and is lower than the curve order. + * If this conditions is not met, then the result is indeterminate + * (but the process is still constant-time). + */ +static void +p256_mulgen(p256_jacobian *P, const unsigned char *k, size_t klen) +{ + point_mul_inner(P, P256_Gwin, k, klen); +} + +/* + * Return 1 if all of the following hold: + * - klen <= 32 + * - k != 0 + * - k is lower than the curve order + * Otherwise, return 0. + * + * Constant-time behaviour: only klen may be observable. + */ +static uint32_t +check_scalar(const unsigned char *k, size_t klen) +{ + uint32_t z; + int32_t c; + size_t u; + + if (klen > 32) { + return 0; + } + z = 0; + for (u = 0; u < klen; u ++) { + z |= k[u]; + } + if (klen == 32) { + c = 0; + for (u = 0; u < klen; u ++) { + c |= -(int32_t)EQ0(c) & CMP(k[u], P256_N[u]); + } + } else { + c = -1; + } + return NEQ(z, 0) & LT0(c); +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *k, size_t klen, int curve) +{ + uint32_t r; + p256_jacobian P; + + (void)curve; + if (Glen != 65) { + return 0; + } + r = check_scalar(k, klen); + r &= point_decode(&P, G); + p256_mul(&P, k, klen); + r &= point_encode(G, &P); + return r; +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *k, size_t klen, int curve) +{ + p256_jacobian P; + + (void)curve; + p256_mulgen(&P, k, klen); + point_encode(R, &P); + return 65; +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + /* + * We might want to use Shamir's trick here: make a composite + * window of u*P+v*Q points, to merge the two doubling-ladders + * into one. This, however, has some complications: + * + * - During the computation, we may hit the point-at-infinity. + * Thus, we would need p256_add_complete_mixed() (complete + * formulas for point addition), with a higher cost (17 muls + * instead of 11). + * + * - A 4-bit window would be too large, since it would involve + * 16*16-1 = 255 points. For the same window size as in the + * p256_mul() case, we would need to reduce the window size + * to 2 bits, and thus perform twice as many non-doubling + * point additions. + * + * - The window may itself contain the point-at-infinity, and + * thus cannot be in all generality be made of affine points. + * Instead, we would need to make it a window of points in + * Jacobian coordinates. Even p256_add_complete_mixed() would + * be inappropriate. + * + * For these reasons, the code below performs two separate + * point multiplications, then computes the final point addition + * (which is both a "normal" addition, and a doubling, to handle + * all cases). + */ + + p256_jacobian P, Q; + uint32_t r, t, s; + uint64_t z; + + (void)curve; + if (len != 65) { + return 0; + } + r = point_decode(&P, A); + p256_mul(&P, x, xlen); + if (B == NULL) { + p256_mulgen(&Q, y, ylen); + } else { + r &= point_decode(&Q, B); + p256_mul(&Q, y, ylen); + } + + /* + * The final addition may fail in case both points are equal. + */ + t = p256_add(&P, &Q); + f256_final_reduce(P.z); + z = P.z[0] | P.z[1] | P.z[2] | P.z[3]; + s = EQ((uint32_t)(z | (z >> 32)), 0); + p256_double(&Q); + + /* + * If s is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we + * have the following: + * + * s = 0, t = 0 return P (normal addition) + * s = 0, t = 1 return P (normal addition) + * s = 1, t = 0 return Q (a 'double' case) + * s = 1, t = 1 report an error (P+Q = 0) + */ + CCOPY(s & ~t, &P, &Q, sizeof Q); + point_encode(A, &P); + r &= ~(s & t); + return r; +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_p256_m64 = { + (uint32_t)0x00800000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; + +/* see bearssl_ec.h */ +const br_ec_impl * +br_ec_p256_m64_get(void) +{ + return &br_ec_p256_m64; +} + +#else + +/* see bearssl_ec.h */ +const br_ec_impl * +br_ec_p256_m64_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/ec/ec_prime_i15.c b/BearSSL-OG/libbearssl/src/ec/ec_prime_i15.c new file mode 100644 index 0000000..d4f5c2c --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_prime_i15.c @@ -0,0 +1,824 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Parameters for supported curves: + * - field modulus p + * - R^2 mod p (R = 2^(15k) for the smallest k such that R >= p) + * - b*R mod p (b is the second curve equation parameter) + */ + +static const uint16_t P256_P[] = { + 0x0111, + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x003F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x4000, 0x7FFF, + 0x7FFF, 0x0001 +}; + +static const uint16_t P256_R2[] = { + 0x0111, + 0x0000, 0x6000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FFC, 0x7FFF, + 0x7FBF, 0x7FFF, 0x7FBF, 0x7FFF, 0x7FFF, 0x7FFF, 0x77FF, 0x7FFF, + 0x4FFF, 0x0000 +}; + +static const uint16_t P256_B[] = { + 0x0111, + 0x770C, 0x5EEF, 0x29C4, 0x3EC4, 0x6273, 0x0486, 0x4543, 0x3993, + 0x3C01, 0x6B56, 0x212E, 0x57EE, 0x4882, 0x204B, 0x7483, 0x3C16, + 0x0187, 0x0000 +}; + +static const uint16_t P384_P[] = { + 0x0199, + 0x7FFF, 0x7FFF, 0x0003, 0x0000, 0x0000, 0x0000, 0x7FC0, 0x7FFF, + 0x7EFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + 0x7FFF, 0x01FF +}; + +static const uint16_t P384_R2[] = { + 0x0199, + 0x1000, 0x0000, 0x0000, 0x7FFF, 0x7FFF, 0x0001, 0x0000, 0x0010, + 0x0000, 0x0000, 0x0000, 0x7F00, 0x7FFF, 0x01FF, 0x0000, 0x1000, + 0x0000, 0x2000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000 +}; + +static const uint16_t P384_B[] = { + 0x0199, + 0x7333, 0x2096, 0x70D1, 0x2310, 0x3020, 0x6197, 0x1464, 0x35BB, + 0x70CA, 0x0117, 0x1920, 0x4136, 0x5FC8, 0x5713, 0x4938, 0x7DD2, + 0x4DD2, 0x4A71, 0x0220, 0x683E, 0x2C87, 0x4DB1, 0x7BFF, 0x6C09, + 0x0452, 0x0084 +}; + +static const uint16_t P521_P[] = { + 0x022B, + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, + 0x7FFF, 0x7FFF, 0x07FF +}; + +static const uint16_t P521_R2[] = { + 0x022B, + 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000 +}; + +static const uint16_t P521_B[] = { + 0x022B, + 0x7002, 0x6A07, 0x751A, 0x228F, 0x71EF, 0x5869, 0x20F4, 0x1EFC, + 0x7357, 0x37E0, 0x4EEC, 0x605E, 0x1652, 0x26F6, 0x31FA, 0x4A8F, + 0x6193, 0x3C2A, 0x3C42, 0x48C7, 0x3489, 0x6771, 0x4C57, 0x5CCD, + 0x2725, 0x545B, 0x503B, 0x5B42, 0x21A0, 0x2534, 0x687E, 0x70E4, + 0x1618, 0x27D7, 0x0465 +}; + +typedef struct { + const uint16_t *p; + const uint16_t *b; + const uint16_t *R2; + uint16_t p0i; + size_t point_len; +} curve_params; + +static __inline const curve_params * +id_to_curve(int curve) +{ + static const curve_params pp[] = { + { P256_P, P256_B, P256_R2, 0x0001, 65 }, + { P384_P, P384_B, P384_R2, 0x0001, 97 }, + { P521_P, P521_B, P521_R2, 0x0001, 133 } + }; + + return &pp[curve - BR_EC_secp256r1]; +} + +#define I15_LEN ((BR_MAX_EC_SIZE + 29) / 15) + +/* + * Type for a point in Jacobian coordinates: + * -- three values, x, y and z, in Montgomery representation + * -- affine coordinates are X = x / z^2 and Y = y / z^3 + * -- for the point at infinity, z = 0 + */ +typedef struct { + uint16_t c[3][I15_LEN]; +} jacobian; + +/* + * We use a custom interpreter that uses a dozen registers, and + * only six operations: + * MSET(d, a) copy a into d + * MADD(d, a) d = d+a (modular) + * MSUB(d, a) d = d-a (modular) + * MMUL(d, a, b) d = a*b (Montgomery multiplication) + * MINV(d, a, b) invert d modulo p; a and b are used as scratch registers + * MTZ(d) clear return value if d = 0 + * Destination of MMUL (d) must be distinct from operands (a and b). + * There is no such constraint for MSUB and MADD. + * + * Registers include the operand coordinates, and temporaries. + */ +#define MSET(d, a) (0x0000 + ((d) << 8) + ((a) << 4)) +#define MADD(d, a) (0x1000 + ((d) << 8) + ((a) << 4)) +#define MSUB(d, a) (0x2000 + ((d) << 8) + ((a) << 4)) +#define MMUL(d, a, b) (0x3000 + ((d) << 8) + ((a) << 4) + (b)) +#define MINV(d, a, b) (0x4000 + ((d) << 8) + ((a) << 4) + (b)) +#define MTZ(d) (0x5000 + ((d) << 8)) +#define ENDCODE 0 + +/* + * Registers for the input operands. + */ +#define P1x 0 +#define P1y 1 +#define P1z 2 +#define P2x 3 +#define P2y 4 +#define P2z 5 + +/* + * Alternate names for the first input operand. + */ +#define Px 0 +#define Py 1 +#define Pz 2 + +/* + * Temporaries. + */ +#define t1 6 +#define t2 7 +#define t3 8 +#define t4 9 +#define t5 10 +#define t6 11 +#define t7 12 + +/* + * Extra scratch registers available when there is no second operand (e.g. + * for "double" and "affine"). + */ +#define t8 3 +#define t9 4 +#define t10 5 + +/* + * Doubling formulas are: + * + * s = 4*x*y^2 + * m = 3*(x + z^2)*(x - z^2) + * x' = m^2 - 2*s + * y' = m*(s - x') - 8*y^4 + * z' = 2*y*z + * + * If y = 0 (P has order 2) then this yields infinity (z' = 0), as it + * should. This case should not happen anyway, because our curves have + * prime order, and thus do not contain any point of order 2. + * + * If P is infinity (z = 0), then again the formulas yield infinity, + * which is correct. Thus, this code works for all points. + * + * Cost: 8 multiplications + */ +static const uint16_t code_double[] = { + /* + * Compute z^2 (in t1). + */ + MMUL(t1, Pz, Pz), + + /* + * Compute x-z^2 (in t2) and then x+z^2 (in t1). + */ + MSET(t2, Px), + MSUB(t2, t1), + MADD(t1, Px), + + /* + * Compute m = 3*(x+z^2)*(x-z^2) (in t1). + */ + MMUL(t3, t1, t2), + MSET(t1, t3), + MADD(t1, t3), + MADD(t1, t3), + + /* + * Compute s = 4*x*y^2 (in t2) and 2*y^2 (in t3). + */ + MMUL(t3, Py, Py), + MADD(t3, t3), + MMUL(t2, Px, t3), + MADD(t2, t2), + + /* + * Compute x' = m^2 - 2*s. + */ + MMUL(Px, t1, t1), + MSUB(Px, t2), + MSUB(Px, t2), + + /* + * Compute z' = 2*y*z. + */ + MMUL(t4, Py, Pz), + MSET(Pz, t4), + MADD(Pz, t4), + + /* + * Compute y' = m*(s - x') - 8*y^4. Note that we already have + * 2*y^2 in t3. + */ + MSUB(t2, Px), + MMUL(Py, t1, t2), + MMUL(t4, t3, t3), + MSUB(Py, t4), + MSUB(Py, t4), + + ENDCODE +}; + +/* + * Addtions formulas are: + * + * u1 = x1 * z2^2 + * u2 = x2 * z1^2 + * s1 = y1 * z2^3 + * s2 = y2 * z1^3 + * h = u2 - u1 + * r = s2 - s1 + * x3 = r^2 - h^3 - 2 * u1 * h^2 + * y3 = r * (u1 * h^2 - x3) - s1 * h^3 + * z3 = h * z1 * z2 + * + * If both P1 and P2 are infinity, then z1 == 0 and z2 == 0, implying that + * z3 == 0, so the result is correct. + * If either of P1 or P2 is infinity, but not both, then z3 == 0, which is + * not correct. + * h == 0 only if u1 == u2; this happens in two cases: + * -- if s1 == s2 then P1 and/or P2 is infinity, or P1 == P2 + * -- if s1 != s2 then P1 + P2 == infinity (but neither P1 or P2 is infinity) + * + * Thus, the following situations are not handled correctly: + * -- P1 = 0 and P2 != 0 + * -- P1 != 0 and P2 = 0 + * -- P1 = P2 + * All other cases are properly computed. However, even in "incorrect" + * situations, the three coordinates still are properly formed field + * elements. + * + * The returned flag is cleared if r == 0. This happens in the following + * cases: + * -- Both points are on the same horizontal line (same Y coordinate). + * -- Both points are infinity. + * -- One point is infinity and the other is on line Y = 0. + * The third case cannot happen with our curves (there is no valid point + * on line Y = 0 since that would be a point of order 2). If the two + * source points are non-infinity, then remains only the case where the + * two points are on the same horizontal line. + * + * This allows us to detect the "P1 == P2" case, assuming that P1 != 0 and + * P2 != 0: + * -- If the returned value is not the point at infinity, then it was properly + * computed. + * -- Otherwise, if the returned flag is 1, then P1+P2 = 0, and the result + * is indeed the point at infinity. + * -- Otherwise (result is infinity, flag is 0), then P1 = P2 and we should + * use the 'double' code. + * + * Cost: 16 multiplications + */ +static const uint16_t code_add[] = { + /* + * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3). + */ + MMUL(t3, P2z, P2z), + MMUL(t1, P1x, t3), + MMUL(t4, P2z, t3), + MMUL(t3, P1y, t4), + + /* + * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). + */ + MMUL(t4, P1z, P1z), + MMUL(t2, P2x, t4), + MMUL(t5, P1z, t4), + MMUL(t4, P2y, t5), + + /* + * Compute h = u2 - u1 (in t2) and r = s2 - s1 (in t4). + */ + MSUB(t2, t1), + MSUB(t4, t3), + + /* + * Report cases where r = 0 through the returned flag. + */ + MTZ(t4), + + /* + * Compute u1*h^2 (in t6) and h^3 (in t5). + */ + MMUL(t7, t2, t2), + MMUL(t6, t1, t7), + MMUL(t5, t7, t2), + + /* + * Compute x3 = r^2 - h^3 - 2*u1*h^2. + * t1 and t7 can be used as scratch registers. + */ + MMUL(P1x, t4, t4), + MSUB(P1x, t5), + MSUB(P1x, t6), + MSUB(P1x, t6), + + /* + * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. + */ + MSUB(t6, P1x), + MMUL(P1y, t4, t6), + MMUL(t1, t5, t3), + MSUB(P1y, t1), + + /* + * Compute z3 = h*z1*z2. + */ + MMUL(t1, P1z, P2z), + MMUL(P1z, t1, t2), + + ENDCODE +}; + +/* + * Check that the point is on the curve. This code snippet assumes the + * following conventions: + * -- Coordinates x and y have been freshly decoded in P1 (but not + * converted to Montgomery coordinates yet). + * -- P2x, P2y and P2z are set to, respectively, R^2, b*R and 1. + */ +static const uint16_t code_check[] = { + + /* Convert x and y to Montgomery representation. */ + MMUL(t1, P1x, P2x), + MMUL(t2, P1y, P2x), + MSET(P1x, t1), + MSET(P1y, t2), + + /* Compute x^3 in t1. */ + MMUL(t2, P1x, P1x), + MMUL(t1, P1x, t2), + + /* Subtract 3*x from t1. */ + MSUB(t1, P1x), + MSUB(t1, P1x), + MSUB(t1, P1x), + + /* Add b. */ + MADD(t1, P2y), + + /* Compute y^2 in t2. */ + MMUL(t2, P1y, P1y), + + /* Compare y^2 with x^3 - 3*x + b; they must match. */ + MSUB(t1, t2), + MTZ(t1), + + /* Set z to 1 (in Montgomery representation). */ + MMUL(P1z, P2x, P2z), + + ENDCODE +}; + +/* + * Conversion back to affine coordinates. This code snippet assumes that + * the z coordinate of P2 is set to 1 (not in Montgomery representation). + */ +static const uint16_t code_affine[] = { + + /* Save z*R in t1. */ + MSET(t1, P1z), + + /* Compute z^3 in t2. */ + MMUL(t2, P1z, P1z), + MMUL(t3, P1z, t2), + MMUL(t2, t3, P2z), + + /* Invert to (1/z^3) in t2. */ + MINV(t2, t3, t4), + + /* Compute y. */ + MSET(t3, P1y), + MMUL(P1y, t2, t3), + + /* Compute (1/z^2) in t3. */ + MMUL(t3, t2, t1), + + /* Compute x. */ + MSET(t2, P1x), + MMUL(P1x, t2, t3), + + ENDCODE +}; + +static uint32_t +run_code(jacobian *P1, const jacobian *P2, + const curve_params *cc, const uint16_t *code) +{ + uint32_t r; + uint16_t t[13][I15_LEN]; + size_t u; + + r = 1; + + /* + * Copy the two operands in the dedicated registers. + */ + memcpy(t[P1x], P1->c, 3 * I15_LEN * sizeof(uint16_t)); + memcpy(t[P2x], P2->c, 3 * I15_LEN * sizeof(uint16_t)); + + /* + * Run formulas. + */ + for (u = 0;; u ++) { + unsigned op, d, a, b; + + op = code[u]; + if (op == 0) { + break; + } + d = (op >> 8) & 0x0F; + a = (op >> 4) & 0x0F; + b = op & 0x0F; + op >>= 12; + switch (op) { + uint32_t ctl; + size_t plen; + unsigned char tp[(BR_MAX_EC_SIZE + 7) >> 3]; + + case 0: + memcpy(t[d], t[a], I15_LEN * sizeof(uint16_t)); + break; + case 1: + ctl = br_i15_add(t[d], t[a], 1); + ctl |= NOT(br_i15_sub(t[d], cc->p, 0)); + br_i15_sub(t[d], cc->p, ctl); + break; + case 2: + br_i15_add(t[d], cc->p, br_i15_sub(t[d], t[a], 1)); + break; + case 3: + br_i15_montymul(t[d], t[a], t[b], cc->p, cc->p0i); + break; + case 4: + plen = (cc->p[0] - (cc->p[0] >> 4) + 7) >> 3; + br_i15_encode(tp, plen, cc->p); + tp[plen - 1] -= 2; + br_i15_modpow(t[d], tp, plen, + cc->p, cc->p0i, t[a], t[b]); + break; + default: + r &= ~br_i15_iszero(t[d]); + break; + } + } + + /* + * Copy back result. + */ + memcpy(P1->c, t[P1x], 3 * I15_LEN * sizeof(uint16_t)); + return r; +} + +static void +set_one(uint16_t *x, const uint16_t *p) +{ + size_t plen; + + plen = (p[0] + 31) >> 4; + memset(x, 0, plen * sizeof *x); + x[0] = p[0]; + x[1] = 0x0001; +} + +static void +point_zero(jacobian *P, const curve_params *cc) +{ + memset(P, 0, sizeof *P); + P->c[0][0] = P->c[1][0] = P->c[2][0] = cc->p[0]; +} + +static __inline void +point_double(jacobian *P, const curve_params *cc) +{ + run_code(P, P, cc, code_double); +} + +static __inline uint32_t +point_add(jacobian *P1, const jacobian *P2, const curve_params *cc) +{ + return run_code(P1, P2, cc, code_add); +} + +static void +point_mul(jacobian *P, const unsigned char *x, size_t xlen, + const curve_params *cc) +{ + /* + * We do a simple double-and-add ladder with a 2-bit window + * to make only one add every two doublings. We thus first + * precompute 2P and 3P in some local buffers. + * + * We always perform two doublings and one addition; the + * addition is with P, 2P and 3P and is done in a temporary + * array. + * + * The addition code cannot handle cases where one of the + * operands is infinity, which is the case at the start of the + * ladder. We therefore need to maintain a flag that controls + * this situation. + */ + uint32_t qz; + jacobian P2, P3, Q, T, U; + + memcpy(&P2, P, sizeof P2); + point_double(&P2, cc); + memcpy(&P3, P, sizeof P3); + point_add(&P3, &P2, cc); + + point_zero(&Q, cc); + qz = 1; + while (xlen -- > 0) { + int k; + + for (k = 6; k >= 0; k -= 2) { + uint32_t bits; + uint32_t bnz; + + point_double(&Q, cc); + point_double(&Q, cc); + memcpy(&T, P, sizeof T); + memcpy(&U, &Q, sizeof U); + bits = (*x >> k) & (uint32_t)3; + bnz = NEQ(bits, 0); + CCOPY(EQ(bits, 2), &T, &P2, sizeof T); + CCOPY(EQ(bits, 3), &T, &P3, sizeof T); + point_add(&U, &T, cc); + CCOPY(bnz & qz, &Q, &T, sizeof Q); + CCOPY(bnz & ~qz, &Q, &U, sizeof Q); + qz &= ~bnz; + } + x ++; + } + memcpy(P, &Q, sizeof Q); +} + +/* + * Decode point into Jacobian coordinates. This function does not support + * the point at infinity. If the point is invalid then this returns 0, but + * the coordinates are still set to properly formed field elements. + */ +static uint32_t +point_decode(jacobian *P, const void *src, size_t len, const curve_params *cc) +{ + /* + * Points must use uncompressed format: + * -- first byte is 0x04; + * -- coordinates X and Y use unsigned big-endian, with the same + * length as the field modulus. + * + * We don't support hybrid format (uncompressed, but first byte + * has value 0x06 or 0x07, depending on the least significant bit + * of Y) because it is rather useless, and explicitly forbidden + * by PKIX (RFC 5480, section 2.2). + * + * We don't support compressed format either, because it is not + * much used in practice (there are or were patent-related + * concerns about point compression, which explains the lack of + * generalised support). Also, point compression support would + * need a bit more code. + */ + const unsigned char *buf; + size_t plen, zlen; + uint32_t r; + jacobian Q; + + buf = src; + point_zero(P, cc); + plen = (cc->p[0] - (cc->p[0] >> 4) + 7) >> 3; + if (len != 1 + (plen << 1)) { + return 0; + } + r = br_i15_decode_mod(P->c[0], buf + 1, plen, cc->p); + r &= br_i15_decode_mod(P->c[1], buf + 1 + plen, plen, cc->p); + + /* + * Check first byte. + */ + r &= EQ(buf[0], 0x04); + /* obsolete + r &= EQ(buf[0], 0x04) | (EQ(buf[0] & 0xFE, 0x06) + & ~(uint32_t)(buf[0] ^ buf[plen << 1])); + */ + + /* + * Convert coordinates and check that the point is valid. + */ + zlen = ((cc->p[0] + 31) >> 4) * sizeof(uint16_t); + memcpy(Q.c[0], cc->R2, zlen); + memcpy(Q.c[1], cc->b, zlen); + set_one(Q.c[2], cc->p); + r &= ~run_code(P, &Q, cc, code_check); + return r; +} + +/* + * Encode a point. This method assumes that the point is correct and is + * not the point at infinity. Encoded size is always 1+2*plen, where + * plen is the field modulus length, in bytes. + */ +static void +point_encode(void *dst, const jacobian *P, const curve_params *cc) +{ + unsigned char *buf; + size_t plen; + jacobian Q, T; + + buf = dst; + plen = (cc->p[0] - (cc->p[0] >> 4) + 7) >> 3; + buf[0] = 0x04; + memcpy(&Q, P, sizeof *P); + set_one(T.c[2], cc->p); + run_code(&Q, &T, cc, code_affine); + br_i15_encode(buf + 1, plen, Q.c[0]); + br_i15_encode(buf + 1 + plen, plen, Q.c[1]); +} + +static const br_ec_curve_def * +id_to_curve_def(int curve) +{ + switch (curve) { + case BR_EC_secp256r1: + return &br_secp256r1; + case BR_EC_secp384r1: + return &br_secp384r1; + case BR_EC_secp521r1: + return &br_secp521r1; + } + return NULL; +} + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + const br_ec_curve_def *cd; + + cd = id_to_curve_def(curve); + *len = cd->generator_len; + return cd->generator; +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + const br_ec_curve_def *cd; + + cd = id_to_curve_def(curve); + *len = cd->order_len; + return cd->order; +} + +static size_t +api_xoff(int curve, size_t *len) +{ + api_generator(curve, len); + *len >>= 1; + return 1; +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *x, size_t xlen, int curve) +{ + uint32_t r; + const curve_params *cc; + jacobian P; + + cc = id_to_curve(curve); + if (Glen != cc->point_len) { + return 0; + } + r = point_decode(&P, G, Glen, cc); + point_mul(&P, x, xlen, cc); + point_encode(G, &P, cc); + return r; +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + const unsigned char *G; + size_t Glen; + + G = api_generator(curve, &Glen); + memcpy(R, G, Glen); + api_mul(R, Glen, x, xlen, curve); + return Glen; +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + uint32_t r, t, z; + const curve_params *cc; + jacobian P, Q; + + /* + * TODO: see about merging the two ladders. Right now, we do + * two independent point multiplications, which is a bit + * wasteful of CPU resources (but yields short code). + */ + + cc = id_to_curve(curve); + if (len != cc->point_len) { + return 0; + } + r = point_decode(&P, A, len, cc); + if (B == NULL) { + size_t Glen; + + B = api_generator(curve, &Glen); + } + r &= point_decode(&Q, B, len, cc); + point_mul(&P, x, xlen, cc); + point_mul(&Q, y, ylen, cc); + + /* + * We want to compute P+Q. Since the base points A and B are distinct + * from infinity, and the multipliers are non-zero and lower than the + * curve order, then we know that P and Q are non-infinity. This + * leaves two special situations to test for: + * -- If P = Q then we must use point_double(). + * -- If P+Q = 0 then we must report an error. + */ + t = point_add(&P, &Q, cc); + point_double(&Q, cc); + z = br_i15_iszero(P.c[2]); + + /* + * If z is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we + * have the following: + * + * z = 0, t = 0 return P (normal addition) + * z = 0, t = 1 return P (normal addition) + * z = 1, t = 0 return Q (a 'double' case) + * z = 1, t = 1 report an error (P+Q = 0) + */ + CCOPY(z & ~t, &P, &Q, sizeof Q); + point_encode(A, &P, cc); + r &= ~(z & t); + + return r; +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_prime_i15 = { + (uint32_t)0x03800000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_prime_i31.c b/BearSSL-OG/libbearssl/src/ec/ec_prime_i31.c new file mode 100644 index 0000000..8a977bd --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_prime_i31.c @@ -0,0 +1,826 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Parameters for supported curves (field modulus, and 'b' equation + * parameter; both values use the 'i31' format, and 'b' is in Montgomery + * representation). + */ + +static const uint32_t P256_P[] = { + 0x00000108, + 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x00000007, + 0x00000000, 0x00000000, 0x00000040, 0x7FFFFF80, + 0x000000FF +}; + +static const uint32_t P256_R2[] = { + 0x00000108, + 0x00014000, 0x00018000, 0x00000000, 0x7FF40000, + 0x7FEFFFFF, 0x7FF7FFFF, 0x7FAFFFFF, 0x005FFFFF, + 0x00000000 +}; + +static const uint32_t P256_B[] = { + 0x00000108, + 0x6FEE1803, 0x6229C4BD, 0x21B139BE, 0x327150AA, + 0x3567802E, 0x3F7212ED, 0x012E4355, 0x782DD38D, + 0x0000000E +}; + +static const uint32_t P384_P[] = { + 0x0000018C, + 0x7FFFFFFF, 0x00000001, 0x00000000, 0x7FFFFFF8, + 0x7FFFFFEF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, + 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, + 0x00000FFF +}; + +static const uint32_t P384_R2[] = { + 0x0000018C, + 0x00000000, 0x00000080, 0x7FFFFE00, 0x000001FF, + 0x00000800, 0x00000000, 0x7FFFE000, 0x00001FFF, + 0x00008000, 0x00008000, 0x00000000, 0x00000000, + 0x00000000 +}; + +static const uint32_t P384_B[] = { + 0x0000018C, + 0x6E666840, 0x070D0392, 0x5D810231, 0x7651D50C, + 0x17E218D6, 0x1B192002, 0x44EFE441, 0x3A524E2B, + 0x2719BA5F, 0x41F02209, 0x36C5643E, 0x5813EFFE, + 0x000008A5 +}; + +static const uint32_t P521_P[] = { + 0x00000219, + 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, + 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, + 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, + 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, + 0x01FFFFFF +}; + +static const uint32_t P521_R2[] = { + 0x00000219, + 0x00001000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000 +}; + +static const uint32_t P521_B[] = { + 0x00000219, + 0x540FC00A, 0x228FEA35, 0x2C34F1EF, 0x67BF107A, + 0x46FC1CD5, 0x1605E9DD, 0x6937B165, 0x272A3D8F, + 0x42785586, 0x44C8C778, 0x15F3B8B4, 0x64B73366, + 0x03BA8B69, 0x0D05B42A, 0x21F929A2, 0x2C31C393, + 0x00654FAE +}; + +typedef struct { + const uint32_t *p; + const uint32_t *b; + const uint32_t *R2; + uint32_t p0i; + size_t point_len; +} curve_params; + +static __inline const curve_params * +id_to_curve(int curve) +{ + static const curve_params pp[] = { + { P256_P, P256_B, P256_R2, 0x00000001, 65 }, + { P384_P, P384_B, P384_R2, 0x00000001, 97 }, + { P521_P, P521_B, P521_R2, 0x00000001, 133 } + }; + + return &pp[curve - BR_EC_secp256r1]; +} + +#define I31_LEN ((BR_MAX_EC_SIZE + 61) / 31) + +/* + * Type for a point in Jacobian coordinates: + * -- three values, x, y and z, in Montgomery representation + * -- affine coordinates are X = x / z^2 and Y = y / z^3 + * -- for the point at infinity, z = 0 + */ +typedef struct { + uint32_t c[3][I31_LEN]; +} jacobian; + +/* + * We use a custom interpreter that uses a dozen registers, and + * only six operations: + * MSET(d, a) copy a into d + * MADD(d, a) d = d+a (modular) + * MSUB(d, a) d = d-a (modular) + * MMUL(d, a, b) d = a*b (Montgomery multiplication) + * MINV(d, a, b) invert d modulo p; a and b are used as scratch registers + * MTZ(d) clear return value if d = 0 + * Destination of MMUL (d) must be distinct from operands (a and b). + * There is no such constraint for MSUB and MADD. + * + * Registers include the operand coordinates, and temporaries. + */ +#define MSET(d, a) (0x0000 + ((d) << 8) + ((a) << 4)) +#define MADD(d, a) (0x1000 + ((d) << 8) + ((a) << 4)) +#define MSUB(d, a) (0x2000 + ((d) << 8) + ((a) << 4)) +#define MMUL(d, a, b) (0x3000 + ((d) << 8) + ((a) << 4) + (b)) +#define MINV(d, a, b) (0x4000 + ((d) << 8) + ((a) << 4) + (b)) +#define MTZ(d) (0x5000 + ((d) << 8)) +#define ENDCODE 0 + +/* + * Registers for the input operands. + */ +#define P1x 0 +#define P1y 1 +#define P1z 2 +#define P2x 3 +#define P2y 4 +#define P2z 5 + +/* + * Alternate names for the first input operand. + */ +#define Px 0 +#define Py 1 +#define Pz 2 + +/* + * Temporaries. + */ +#define t1 6 +#define t2 7 +#define t3 8 +#define t4 9 +#define t5 10 +#define t6 11 +#define t7 12 + +/* + * Extra scratch registers available when there is no second operand (e.g. + * for "double" and "affine"). + */ +#define t8 3 +#define t9 4 +#define t10 5 + +/* + * Doubling formulas are: + * + * s = 4*x*y^2 + * m = 3*(x + z^2)*(x - z^2) + * x' = m^2 - 2*s + * y' = m*(s - x') - 8*y^4 + * z' = 2*y*z + * + * If y = 0 (P has order 2) then this yields infinity (z' = 0), as it + * should. This case should not happen anyway, because our curves have + * prime order, and thus do not contain any point of order 2. + * + * If P is infinity (z = 0), then again the formulas yield infinity, + * which is correct. Thus, this code works for all points. + * + * Cost: 8 multiplications + */ +static const uint16_t code_double[] = { + /* + * Compute z^2 (in t1). + */ + MMUL(t1, Pz, Pz), + + /* + * Compute x-z^2 (in t2) and then x+z^2 (in t1). + */ + MSET(t2, Px), + MSUB(t2, t1), + MADD(t1, Px), + + /* + * Compute m = 3*(x+z^2)*(x-z^2) (in t1). + */ + MMUL(t3, t1, t2), + MSET(t1, t3), + MADD(t1, t3), + MADD(t1, t3), + + /* + * Compute s = 4*x*y^2 (in t2) and 2*y^2 (in t3). + */ + MMUL(t3, Py, Py), + MADD(t3, t3), + MMUL(t2, Px, t3), + MADD(t2, t2), + + /* + * Compute x' = m^2 - 2*s. + */ + MMUL(Px, t1, t1), + MSUB(Px, t2), + MSUB(Px, t2), + + /* + * Compute z' = 2*y*z. + */ + MMUL(t4, Py, Pz), + MSET(Pz, t4), + MADD(Pz, t4), + + /* + * Compute y' = m*(s - x') - 8*y^4. Note that we already have + * 2*y^2 in t3. + */ + MSUB(t2, Px), + MMUL(Py, t1, t2), + MMUL(t4, t3, t3), + MSUB(Py, t4), + MSUB(Py, t4), + + ENDCODE +}; + +/* + * Addtions formulas are: + * + * u1 = x1 * z2^2 + * u2 = x2 * z1^2 + * s1 = y1 * z2^3 + * s2 = y2 * z1^3 + * h = u2 - u1 + * r = s2 - s1 + * x3 = r^2 - h^3 - 2 * u1 * h^2 + * y3 = r * (u1 * h^2 - x3) - s1 * h^3 + * z3 = h * z1 * z2 + * + * If both P1 and P2 are infinity, then z1 == 0 and z2 == 0, implying that + * z3 == 0, so the result is correct. + * If either of P1 or P2 is infinity, but not both, then z3 == 0, which is + * not correct. + * h == 0 only if u1 == u2; this happens in two cases: + * -- if s1 == s2 then P1 and/or P2 is infinity, or P1 == P2 + * -- if s1 != s2 then P1 + P2 == infinity (but neither P1 or P2 is infinity) + * + * Thus, the following situations are not handled correctly: + * -- P1 = 0 and P2 != 0 + * -- P1 != 0 and P2 = 0 + * -- P1 = P2 + * All other cases are properly computed. However, even in "incorrect" + * situations, the three coordinates still are properly formed field + * elements. + * + * The returned flag is cleared if r == 0. This happens in the following + * cases: + * -- Both points are on the same horizontal line (same Y coordinate). + * -- Both points are infinity. + * -- One point is infinity and the other is on line Y = 0. + * The third case cannot happen with our curves (there is no valid point + * on line Y = 0 since that would be a point of order 2). If the two + * source points are non-infinity, then remains only the case where the + * two points are on the same horizontal line. + * + * This allows us to detect the "P1 == P2" case, assuming that P1 != 0 and + * P2 != 0: + * -- If the returned value is not the point at infinity, then it was properly + * computed. + * -- Otherwise, if the returned flag is 1, then P1+P2 = 0, and the result + * is indeed the point at infinity. + * -- Otherwise (result is infinity, flag is 0), then P1 = P2 and we should + * use the 'double' code. + * + * Cost: 16 multiplications + */ +static const uint16_t code_add[] = { + /* + * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3). + */ + MMUL(t3, P2z, P2z), + MMUL(t1, P1x, t3), + MMUL(t4, P2z, t3), + MMUL(t3, P1y, t4), + + /* + * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4). + */ + MMUL(t4, P1z, P1z), + MMUL(t2, P2x, t4), + MMUL(t5, P1z, t4), + MMUL(t4, P2y, t5), + + /* + * Compute h = u2 - u1 (in t2) and r = s2 - s1 (in t4). + */ + MSUB(t2, t1), + MSUB(t4, t3), + + /* + * Report cases where r = 0 through the returned flag. + */ + MTZ(t4), + + /* + * Compute u1*h^2 (in t6) and h^3 (in t5). + */ + MMUL(t7, t2, t2), + MMUL(t6, t1, t7), + MMUL(t5, t7, t2), + + /* + * Compute x3 = r^2 - h^3 - 2*u1*h^2. + * t1 and t7 can be used as scratch registers. + */ + MMUL(P1x, t4, t4), + MSUB(P1x, t5), + MSUB(P1x, t6), + MSUB(P1x, t6), + + /* + * Compute y3 = r*(u1*h^2 - x3) - s1*h^3. + */ + MSUB(t6, P1x), + MMUL(P1y, t4, t6), + MMUL(t1, t5, t3), + MSUB(P1y, t1), + + /* + * Compute z3 = h*z1*z2. + */ + MMUL(t1, P1z, P2z), + MMUL(P1z, t1, t2), + + ENDCODE +}; + +/* + * Check that the point is on the curve. This code snippet assumes the + * following conventions: + * -- Coordinates x and y have been freshly decoded in P1 (but not + * converted to Montgomery coordinates yet). + * -- P2x, P2y and P2z are set to, respectively, R^2, b*R and 1. + */ +static const uint16_t code_check[] = { + + /* Convert x and y to Montgomery representation. */ + MMUL(t1, P1x, P2x), + MMUL(t2, P1y, P2x), + MSET(P1x, t1), + MSET(P1y, t2), + + /* Compute x^3 in t1. */ + MMUL(t2, P1x, P1x), + MMUL(t1, P1x, t2), + + /* Subtract 3*x from t1. */ + MSUB(t1, P1x), + MSUB(t1, P1x), + MSUB(t1, P1x), + + /* Add b. */ + MADD(t1, P2y), + + /* Compute y^2 in t2. */ + MMUL(t2, P1y, P1y), + + /* Compare y^2 with x^3 - 3*x + b; they must match. */ + MSUB(t1, t2), + MTZ(t1), + + /* Set z to 1 (in Montgomery representation). */ + MMUL(P1z, P2x, P2z), + + ENDCODE +}; + +/* + * Conversion back to affine coordinates. This code snippet assumes that + * the z coordinate of P2 is set to 1 (not in Montgomery representation). + */ +static const uint16_t code_affine[] = { + + /* Save z*R in t1. */ + MSET(t1, P1z), + + /* Compute z^3 in t2. */ + MMUL(t2, P1z, P1z), + MMUL(t3, P1z, t2), + MMUL(t2, t3, P2z), + + /* Invert to (1/z^3) in t2. */ + MINV(t2, t3, t4), + + /* Compute y. */ + MSET(t3, P1y), + MMUL(P1y, t2, t3), + + /* Compute (1/z^2) in t3. */ + MMUL(t3, t2, t1), + + /* Compute x. */ + MSET(t2, P1x), + MMUL(P1x, t2, t3), + + ENDCODE +}; + +static uint32_t +run_code(jacobian *P1, const jacobian *P2, + const curve_params *cc, const uint16_t *code) +{ + uint32_t r; + uint32_t t[13][I31_LEN]; + size_t u; + + r = 1; + + /* + * Copy the two operands in the dedicated registers. + */ + memcpy(t[P1x], P1->c, 3 * I31_LEN * sizeof(uint32_t)); + memcpy(t[P2x], P2->c, 3 * I31_LEN * sizeof(uint32_t)); + + /* + * Run formulas. + */ + for (u = 0;; u ++) { + unsigned op, d, a, b; + + op = code[u]; + if (op == 0) { + break; + } + d = (op >> 8) & 0x0F; + a = (op >> 4) & 0x0F; + b = op & 0x0F; + op >>= 12; + switch (op) { + uint32_t ctl; + size_t plen; + unsigned char tp[(BR_MAX_EC_SIZE + 7) >> 3]; + + case 0: + memcpy(t[d], t[a], I31_LEN * sizeof(uint32_t)); + break; + case 1: + ctl = br_i31_add(t[d], t[a], 1); + ctl |= NOT(br_i31_sub(t[d], cc->p, 0)); + br_i31_sub(t[d], cc->p, ctl); + break; + case 2: + br_i31_add(t[d], cc->p, br_i31_sub(t[d], t[a], 1)); + break; + case 3: + br_i31_montymul(t[d], t[a], t[b], cc->p, cc->p0i); + break; + case 4: + plen = (cc->p[0] - (cc->p[0] >> 5) + 7) >> 3; + br_i31_encode(tp, plen, cc->p); + tp[plen - 1] -= 2; + br_i31_modpow(t[d], tp, plen, + cc->p, cc->p0i, t[a], t[b]); + break; + default: + r &= ~br_i31_iszero(t[d]); + break; + } + } + + /* + * Copy back result. + */ + memcpy(P1->c, t[P1x], 3 * I31_LEN * sizeof(uint32_t)); + return r; +} + +static void +set_one(uint32_t *x, const uint32_t *p) +{ + size_t plen; + + plen = (p[0] + 63) >> 5; + memset(x, 0, plen * sizeof *x); + x[0] = p[0]; + x[1] = 0x00000001; +} + +static void +point_zero(jacobian *P, const curve_params *cc) +{ + memset(P, 0, sizeof *P); + P->c[0][0] = P->c[1][0] = P->c[2][0] = cc->p[0]; +} + +static __inline void +point_double(jacobian *P, const curve_params *cc) +{ + run_code(P, P, cc, code_double); +} + +static __inline uint32_t +point_add(jacobian *P1, const jacobian *P2, const curve_params *cc) +{ + return run_code(P1, P2, cc, code_add); +} + +static void +point_mul(jacobian *P, const unsigned char *x, size_t xlen, + const curve_params *cc) +{ + /* + * We do a simple double-and-add ladder with a 2-bit window + * to make only one add every two doublings. We thus first + * precompute 2P and 3P in some local buffers. + * + * We always perform two doublings and one addition; the + * addition is with P, 2P and 3P and is done in a temporary + * array. + * + * The addition code cannot handle cases where one of the + * operands is infinity, which is the case at the start of the + * ladder. We therefore need to maintain a flag that controls + * this situation. + */ + uint32_t qz; + jacobian P2, P3, Q, T, U; + + memcpy(&P2, P, sizeof P2); + point_double(&P2, cc); + memcpy(&P3, P, sizeof P3); + point_add(&P3, &P2, cc); + + point_zero(&Q, cc); + qz = 1; + while (xlen -- > 0) { + int k; + + for (k = 6; k >= 0; k -= 2) { + uint32_t bits; + uint32_t bnz; + + point_double(&Q, cc); + point_double(&Q, cc); + memcpy(&T, P, sizeof T); + memcpy(&U, &Q, sizeof U); + bits = (*x >> k) & (uint32_t)3; + bnz = NEQ(bits, 0); + CCOPY(EQ(bits, 2), &T, &P2, sizeof T); + CCOPY(EQ(bits, 3), &T, &P3, sizeof T); + point_add(&U, &T, cc); + CCOPY(bnz & qz, &Q, &T, sizeof Q); + CCOPY(bnz & ~qz, &Q, &U, sizeof Q); + qz &= ~bnz; + } + x ++; + } + memcpy(P, &Q, sizeof Q); +} + +/* + * Decode point into Jacobian coordinates. This function does not support + * the point at infinity. If the point is invalid then this returns 0, but + * the coordinates are still set to properly formed field elements. + */ +static uint32_t +point_decode(jacobian *P, const void *src, size_t len, const curve_params *cc) +{ + /* + * Points must use uncompressed format: + * -- first byte is 0x04; + * -- coordinates X and Y use unsigned big-endian, with the same + * length as the field modulus. + * + * We don't support hybrid format (uncompressed, but first byte + * has value 0x06 or 0x07, depending on the least significant bit + * of Y) because it is rather useless, and explicitly forbidden + * by PKIX (RFC 5480, section 2.2). + * + * We don't support compressed format either, because it is not + * much used in practice (there are or were patent-related + * concerns about point compression, which explains the lack of + * generalised support). Also, point compression support would + * need a bit more code. + */ + const unsigned char *buf; + size_t plen, zlen; + uint32_t r; + jacobian Q; + + buf = src; + point_zero(P, cc); + plen = (cc->p[0] - (cc->p[0] >> 5) + 7) >> 3; + if (len != 1 + (plen << 1)) { + return 0; + } + r = br_i31_decode_mod(P->c[0], buf + 1, plen, cc->p); + r &= br_i31_decode_mod(P->c[1], buf + 1 + plen, plen, cc->p); + + /* + * Check first byte. + */ + r &= EQ(buf[0], 0x04); + /* obsolete + r &= EQ(buf[0], 0x04) | (EQ(buf[0] & 0xFE, 0x06) + & ~(uint32_t)(buf[0] ^ buf[plen << 1])); + */ + + /* + * Convert coordinates and check that the point is valid. + */ + zlen = ((cc->p[0] + 63) >> 5) * sizeof(uint32_t); + memcpy(Q.c[0], cc->R2, zlen); + memcpy(Q.c[1], cc->b, zlen); + set_one(Q.c[2], cc->p); + r &= ~run_code(P, &Q, cc, code_check); + return r; +} + +/* + * Encode a point. This method assumes that the point is correct and is + * not the point at infinity. Encoded size is always 1+2*plen, where + * plen is the field modulus length, in bytes. + */ +static void +point_encode(void *dst, const jacobian *P, const curve_params *cc) +{ + unsigned char *buf; + uint32_t xbl; + size_t plen; + jacobian Q, T; + + buf = dst; + xbl = cc->p[0]; + xbl -= (xbl >> 5); + plen = (xbl + 7) >> 3; + buf[0] = 0x04; + memcpy(&Q, P, sizeof *P); + set_one(T.c[2], cc->p); + run_code(&Q, &T, cc, code_affine); + br_i31_encode(buf + 1, plen, Q.c[0]); + br_i31_encode(buf + 1 + plen, plen, Q.c[1]); +} + +static const br_ec_curve_def * +id_to_curve_def(int curve) +{ + switch (curve) { + case BR_EC_secp256r1: + return &br_secp256r1; + case BR_EC_secp384r1: + return &br_secp384r1; + case BR_EC_secp521r1: + return &br_secp521r1; + } + return NULL; +} + +static const unsigned char * +api_generator(int curve, size_t *len) +{ + const br_ec_curve_def *cd; + + cd = id_to_curve_def(curve); + *len = cd->generator_len; + return cd->generator; +} + +static const unsigned char * +api_order(int curve, size_t *len) +{ + const br_ec_curve_def *cd; + + cd = id_to_curve_def(curve); + *len = cd->order_len; + return cd->order; +} + +static size_t +api_xoff(int curve, size_t *len) +{ + api_generator(curve, len); + *len >>= 1; + return 1; +} + +static uint32_t +api_mul(unsigned char *G, size_t Glen, + const unsigned char *x, size_t xlen, int curve) +{ + uint32_t r; + const curve_params *cc; + jacobian P; + + cc = id_to_curve(curve); + if (Glen != cc->point_len) { + return 0; + } + r = point_decode(&P, G, Glen, cc); + point_mul(&P, x, xlen, cc); + point_encode(G, &P, cc); + return r; +} + +static size_t +api_mulgen(unsigned char *R, + const unsigned char *x, size_t xlen, int curve) +{ + const unsigned char *G; + size_t Glen; + + G = api_generator(curve, &Glen); + memcpy(R, G, Glen); + api_mul(R, Glen, x, xlen, curve); + return Glen; +} + +static uint32_t +api_muladd(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve) +{ + uint32_t r, t, z; + const curve_params *cc; + jacobian P, Q; + + /* + * TODO: see about merging the two ladders. Right now, we do + * two independent point multiplications, which is a bit + * wasteful of CPU resources (but yields short code). + */ + + cc = id_to_curve(curve); + if (len != cc->point_len) { + return 0; + } + r = point_decode(&P, A, len, cc); + if (B == NULL) { + size_t Glen; + + B = api_generator(curve, &Glen); + } + r &= point_decode(&Q, B, len, cc); + point_mul(&P, x, xlen, cc); + point_mul(&Q, y, ylen, cc); + + /* + * We want to compute P+Q. Since the base points A and B are distinct + * from infinity, and the multipliers are non-zero and lower than the + * curve order, then we know that P and Q are non-infinity. This + * leaves two special situations to test for: + * -- If P = Q then we must use point_double(). + * -- If P+Q = 0 then we must report an error. + */ + t = point_add(&P, &Q, cc); + point_double(&Q, cc); + z = br_i31_iszero(P.c[2]); + + /* + * If z is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we + * have the following: + * + * z = 0, t = 0 return P (normal addition) + * z = 0, t = 1 return P (normal addition) + * z = 1, t = 0 return Q (a 'double' case) + * z = 1, t = 1 report an error (P+Q = 0) + */ + CCOPY(z & ~t, &P, &Q, sizeof Q); + point_encode(A, &P, cc); + r &= ~(z & t); + + return r; +} + +/* see bearssl_ec.h */ +const br_ec_impl br_ec_prime_i31 = { + (uint32_t)0x03800000, + &api_generator, + &api_order, + &api_xoff, + &api_mul, + &api_mulgen, + &api_muladd +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_pubkey.c b/BearSSL-OG/libbearssl/src/ec/ec_pubkey.c new file mode 100644 index 0000000..383ff28 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_pubkey.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static const unsigned char POINT_LEN[] = { + 0, /* 0: not a valid curve ID */ + 43, /* sect163k1 */ + 43, /* sect163r1 */ + 43, /* sect163r2 */ + 51, /* sect193r1 */ + 51, /* sect193r2 */ + 61, /* sect233k1 */ + 61, /* sect233r1 */ + 61, /* sect239k1 */ + 73, /* sect283k1 */ + 73, /* sect283r1 */ + 105, /* sect409k1 */ + 105, /* sect409r1 */ + 145, /* sect571k1 */ + 145, /* sect571r1 */ + 41, /* secp160k1 */ + 41, /* secp160r1 */ + 41, /* secp160r2 */ + 49, /* secp192k1 */ + 49, /* secp192r1 */ + 57, /* secp224k1 */ + 57, /* secp224r1 */ + 65, /* secp256k1 */ + 65, /* secp256r1 */ + 97, /* secp384r1 */ + 133, /* secp521r1 */ + 65, /* brainpoolP256r1 */ + 97, /* brainpoolP384r1 */ + 129, /* brainpoolP512r1 */ + 32, /* curve25519 */ + 56, /* curve448 */ +}; + +/* see bearssl_ec.h */ +size_t +br_ec_compute_pub(const br_ec_impl *impl, br_ec_public_key *pk, + void *kbuf, const br_ec_private_key *sk) +{ + int curve; + size_t len; + + curve = sk->curve; + if (curve < 0 || curve >= 32 || curve >= (int)(sizeof POINT_LEN) + || ((impl->supported_curves >> curve) & 1) == 0) + { + return 0; + } + if (kbuf == NULL) { + return POINT_LEN[curve]; + } + len = impl->mulgen(kbuf, sk->x, sk->xlen, curve); + if (pk != NULL) { + pk->curve = curve; + pk->q = kbuf; + pk->qlen = len; + } + return len; +} diff --git a/BearSSL-OG/libbearssl/src/ec/ec_secp256r1.c b/BearSSL-OG/libbearssl/src/ec/ec_secp256r1.c new file mode 100644 index 0000000..a9d6c45 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_secp256r1.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static const unsigned char P256_N[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 +}; + +static const unsigned char P256_G[] = { + 0x04, 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, + 0x47, 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, + 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, + 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, + 0x96, 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, + 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, + 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, + 0xCE, 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, + 0xF5 +}; + +/* see inner.h */ +const br_ec_curve_def br_secp256r1 = { + BR_EC_secp256r1, + P256_N, sizeof P256_N, + P256_G, sizeof P256_G +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_secp384r1.c b/BearSSL-OG/libbearssl/src/ec/ec_secp384r1.c new file mode 100644 index 0000000..693d93e --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_secp384r1.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static const unsigned char P384_N[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, + 0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A, + 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 +}; + +static const unsigned char P384_G[] = { + 0x04, 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, + 0x37, 0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, + 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, + 0x98, 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, + 0x38, 0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, + 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, + 0xB7, 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, + 0x6F, 0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, + 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, + 0x7C, 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, + 0xC0, 0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, + 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, + 0x5F +}; + +/* see inner.h */ +const br_ec_curve_def br_secp384r1 = { + BR_EC_secp384r1, + P384_N, sizeof P384_N, + P384_G, sizeof P384_G +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ec_secp521r1.c b/BearSSL-OG/libbearssl/src/ec/ec_secp521r1.c new file mode 100644 index 0000000..161acd0 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ec_secp521r1.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static const unsigned char P521_N[] = { + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, + 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, + 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, + 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, + 0x64, 0x09 +}; + +static const unsigned char P521_G[] = { + 0x04, 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, + 0x04, 0xE9, 0xCD, 0x9E, 0x3E, 0xCB, 0x66, 0x23, + 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, + 0x3F, 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, + 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, 0x5E, 0x77, 0xEF, + 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, + 0xFF, 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, + 0x6A, 0x42, 0x9B, 0xF9, 0x7E, 0x7E, 0x31, 0xC2, + 0xE5, 0xBD, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6A, + 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A, 0x5F, + 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, + 0x49, 0x57, 0x9B, 0x44, 0x68, 0x17, 0xAF, 0xBD, + 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE, 0x72, + 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, + 0x01, 0x3F, 0xAD, 0x07, 0x61, 0x35, 0x3C, 0x70, + 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE, 0x94, + 0x76, 0x9F, 0xD1, 0x66, 0x50 +}; + +/* see inner.h */ +const br_ec_curve_def br_secp521r1 = { + BR_EC_secp521r1, + P521_N, sizeof P521_N, + P521_G, sizeof P521_G +}; diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_atr.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_atr.c new file mode 100644 index 0000000..3a11226 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_atr.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ec.h */ +size_t +br_ecdsa_asn1_to_raw(void *sig, size_t sig_len) +{ + /* + * Note: this code is a bit lenient in that it accepts a few + * deviations to DER with regards to minimality of encoding of + * lengths and integer values. These deviations are still + * unambiguous. + * + * Signature format is a SEQUENCE of two INTEGER values. We + * support only integers of less than 127 bytes each (signed + * encoding) so the resulting raw signature will have length + * at most 254 bytes. + */ + + unsigned char *buf, *r, *s; + size_t zlen, rlen, slen, off; + unsigned char tmp[254]; + + buf = sig; + if (sig_len < 8) { + return 0; + } + + /* + * First byte is SEQUENCE tag. + */ + if (buf[0] != 0x30) { + return 0; + } + + /* + * The SEQUENCE length will be encoded over one or two bytes. We + * limit the total SEQUENCE contents to 255 bytes, because it + * makes things simpler; this is enough for subgroup orders up + * to 999 bits. + */ + zlen = buf[1]; + if (zlen > 0x80) { + if (zlen != 0x81) { + return 0; + } + zlen = buf[2]; + if (zlen != sig_len - 3) { + return 0; + } + off = 3; + } else { + if (zlen != sig_len - 2) { + return 0; + } + off = 2; + } + + /* + * First INTEGER (r). + */ + if (buf[off ++] != 0x02) { + return 0; + } + rlen = buf[off ++]; + if (rlen >= 0x80) { + return 0; + } + r = buf + off; + off += rlen; + + /* + * Second INTEGER (s). + */ + if (off + 2 > sig_len) { + return 0; + } + if (buf[off ++] != 0x02) { + return 0; + } + slen = buf[off ++]; + if (slen >= 0x80 || slen != sig_len - off) { + return 0; + } + s = buf + off; + + /* + * Removing leading zeros from r and s. + */ + while (rlen > 0 && *r == 0) { + rlen --; + r ++; + } + while (slen > 0 && *s == 0) { + slen --; + s ++; + } + + /* + * Compute common length for the two integers, then copy integers + * into the temporary buffer, and finally copy it back over the + * signature buffer. + */ + zlen = rlen > slen ? rlen : slen; + sig_len = zlen << 1; + memset(tmp, 0, sig_len); + memcpy(tmp + zlen - rlen, r, rlen); + memcpy(tmp + sig_len - slen, s, slen); + memcpy(sig, tmp, sig_len); + return sig_len; +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_default_sign_asn1.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_default_sign_asn1.c new file mode 100644 index 0000000..afbf8ac --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_default_sign_asn1.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ec.h */ +br_ecdsa_sign +br_ecdsa_sign_asn1_get_default(void) +{ +#if BR_LOMUL + return &br_ecdsa_i15_sign_asn1; +#else + return &br_ecdsa_i31_sign_asn1; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_default_sign_raw.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_default_sign_raw.c new file mode 100644 index 0000000..287c970 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_default_sign_raw.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ec.h */ +br_ecdsa_sign +br_ecdsa_sign_raw_get_default(void) +{ +#if BR_LOMUL + return &br_ecdsa_i15_sign_raw; +#else + return &br_ecdsa_i31_sign_raw; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_default_vrfy_asn1.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_default_vrfy_asn1.c new file mode 100644 index 0000000..fe0996e --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_default_vrfy_asn1.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ec.h */ +br_ecdsa_vrfy +br_ecdsa_vrfy_asn1_get_default(void) +{ +#if BR_LOMUL + return &br_ecdsa_i15_vrfy_asn1; +#else + return &br_ecdsa_i31_vrfy_asn1; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_default_vrfy_raw.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_default_vrfy_raw.c new file mode 100644 index 0000000..e564a10 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_default_vrfy_raw.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ec.h */ +br_ecdsa_vrfy +br_ecdsa_vrfy_raw_get_default(void) +{ +#if BR_LOMUL + return &br_ecdsa_i15_vrfy_raw; +#else + return &br_ecdsa_i31_vrfy_raw; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_bits.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_bits.c new file mode 100644 index 0000000..402d14a --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_bits.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_ecdsa_i15_bits2int(uint16_t *x, + const void *src, size_t len, uint32_t ebitlen) +{ + uint32_t bitlen, hbitlen; + int sc; + + bitlen = ebitlen - (ebitlen >> 4); + hbitlen = (uint32_t)len << 3; + if (hbitlen > bitlen) { + len = (bitlen + 7) >> 3; + sc = (int)((hbitlen - bitlen) & 7); + } else { + sc = 0; + } + br_i15_zero(x, ebitlen); + br_i15_decode(x, src, len); + br_i15_rshift(x, sc); + x[0] = ebitlen; +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_sign_asn1.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_sign_asn1.c new file mode 100644 index 0000000..ab4a283 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_sign_asn1.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define ORDER_LEN ((BR_MAX_EC_SIZE + 7) >> 3) + +/* see bearssl_ec.h */ +size_t +br_ecdsa_i15_sign_asn1(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig) +{ + unsigned char rsig[(ORDER_LEN << 1) + 12]; + size_t sig_len; + + sig_len = br_ecdsa_i15_sign_raw(impl, hf, hash_value, sk, rsig); + if (sig_len == 0) { + return 0; + } + sig_len = br_ecdsa_raw_to_asn1(rsig, sig_len); + memcpy(sig, rsig, sig_len); + return sig_len; +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_sign_raw.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_sign_raw.c new file mode 100644 index 0000000..39b2e1d --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_sign_raw.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define I15_LEN ((BR_MAX_EC_SIZE + 29) / 15) +#define POINT_LEN (1 + (((BR_MAX_EC_SIZE + 7) >> 3) << 1)) +#define ORDER_LEN ((BR_MAX_EC_SIZE + 7) >> 3) + +/* see bearssl_ec.h */ +size_t +br_ecdsa_i15_sign_raw(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig) +{ + /* + * IMPORTANT: this code is fit only for curves with a prime + * order. This is needed so that modular reduction of the X + * coordinate of a point can be done with a simple subtraction. + * We also rely on the last byte of the curve order to be distinct + * from 0 and 1. + */ + const br_ec_curve_def *cd; + uint16_t n[I15_LEN], r[I15_LEN], s[I15_LEN], x[I15_LEN]; + uint16_t m[I15_LEN], k[I15_LEN], t1[I15_LEN], t2[I15_LEN]; + unsigned char tt[ORDER_LEN << 1]; + unsigned char eU[POINT_LEN]; + size_t hash_len, nlen, ulen; + uint16_t n0i; + uint32_t ctl; + br_hmac_drbg_context drbg; + + /* + * If the curve is not supported, then exit with an error. + */ + if (((impl->supported_curves >> sk->curve) & 1) == 0) { + return 0; + } + + /* + * Get the curve parameters (generator and order). + */ + switch (sk->curve) { + case BR_EC_secp256r1: + cd = &br_secp256r1; + break; + case BR_EC_secp384r1: + cd = &br_secp384r1; + break; + case BR_EC_secp521r1: + cd = &br_secp521r1; + break; + default: + return 0; + } + + /* + * Get modulus. + */ + nlen = cd->order_len; + br_i15_decode(n, cd->order, nlen); + n0i = br_i15_ninv15(n[1]); + + /* + * Get private key as an i15 integer. This also checks that the + * private key is well-defined (not zero, and less than the + * curve order). + */ + if (!br_i15_decode_mod(x, sk->x, sk->xlen, n)) { + return 0; + } + if (br_i15_iszero(x)) { + return 0; + } + + /* + * Get hash length. + */ + hash_len = (hf->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; + + /* + * Truncate and reduce the hash value modulo the curve order. + */ + br_ecdsa_i15_bits2int(m, hash_value, hash_len, n[0]); + br_i15_sub(m, n, br_i15_sub(m, n, 0) ^ 1); + + /* + * RFC 6979 generation of the "k" value. + * + * The process uses HMAC_DRBG (with the hash function used to + * process the message that is to be signed). The seed is the + * concatenation of the encodings of the private key and + * the hash value (after truncation and modular reduction). + */ + br_i15_encode(tt, nlen, x); + br_i15_encode(tt + nlen, nlen, m); + br_hmac_drbg_init(&drbg, hf, tt, nlen << 1); + for (;;) { + br_hmac_drbg_generate(&drbg, tt, nlen); + br_ecdsa_i15_bits2int(k, tt, nlen, n[0]); + if (br_i15_iszero(k)) { + continue; + } + if (br_i15_sub(k, n, 0)) { + break; + } + } + + /* + * Compute k*G and extract the X coordinate, then reduce it + * modulo the curve order. Since we support only curves with + * prime order, that reduction is only a matter of computing + * a subtraction. + */ + br_i15_encode(tt, nlen, k); + ulen = impl->mulgen(eU, tt, nlen, sk->curve); + br_i15_zero(r, n[0]); + br_i15_decode(r, &eU[1], ulen >> 1); + r[0] = n[0]; + br_i15_sub(r, n, br_i15_sub(r, n, 0) ^ 1); + + /* + * Compute 1/k in double-Montgomery representation. We do so by + * first converting _from_ Montgomery representation (twice), + * then using a modular exponentiation. + */ + br_i15_from_monty(k, n, n0i); + br_i15_from_monty(k, n, n0i); + memcpy(tt, cd->order, nlen); + tt[nlen - 1] -= 2; + br_i15_modpow(k, tt, nlen, n, n0i, t1, t2); + + /* + * Compute s = (m+xr)/k (mod n). + * The k[] array contains R^2/k (double-Montgomery representation); + * we thus can use direct Montgomery multiplications and conversions + * from Montgomery, avoiding any call to br_i15_to_monty() (which + * is slower). + */ + br_i15_from_monty(m, n, n0i); + br_i15_montymul(t1, x, r, n, n0i); + ctl = br_i15_add(t1, m, 1); + ctl |= br_i15_sub(t1, n, 0) ^ 1; + br_i15_sub(t1, n, ctl); + br_i15_montymul(s, t1, k, n, n0i); + + /* + * Encode r and s in the signature. + */ + br_i15_encode(sig, nlen, r); + br_i15_encode((unsigned char *)sig + nlen, nlen, s); + return nlen << 1; +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_vrfy_asn1.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_vrfy_asn1.c new file mode 100644 index 0000000..f4bef99 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_vrfy_asn1.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define FIELD_LEN ((BR_MAX_EC_SIZE + 7) >> 3) + +/* see bearssl_ec.h */ +uint32_t +br_ecdsa_i15_vrfy_asn1(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, + const void *sig, size_t sig_len) +{ + /* + * We use a double-sized buffer because a malformed ASN.1 signature + * may trigger a size expansion when converting to "raw" format. + */ + unsigned char rsig[(FIELD_LEN << 2) + 24]; + + if (sig_len > ((sizeof rsig) >> 1)) { + return 0; + } + memcpy(rsig, sig, sig_len); + sig_len = br_ecdsa_asn1_to_raw(rsig, sig_len); + return br_ecdsa_i15_vrfy_raw(impl, hash, hash_len, pk, rsig, sig_len); +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_vrfy_raw.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_vrfy_raw.c new file mode 100644 index 0000000..14dd5e4 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_i15_vrfy_raw.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define I15_LEN ((BR_MAX_EC_SIZE + 29) / 15) +#define POINT_LEN (1 + (((BR_MAX_EC_SIZE + 7) >> 3) << 1)) + +/* see bearssl_ec.h */ +uint32_t +br_ecdsa_i15_vrfy_raw(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, + const void *sig, size_t sig_len) +{ + /* + * IMPORTANT: this code is fit only for curves with a prime + * order. This is needed so that modular reduction of the X + * coordinate of a point can be done with a simple subtraction. + */ + const br_ec_curve_def *cd; + uint16_t n[I15_LEN], r[I15_LEN], s[I15_LEN], t1[I15_LEN], t2[I15_LEN]; + unsigned char tx[(BR_MAX_EC_SIZE + 7) >> 3]; + unsigned char ty[(BR_MAX_EC_SIZE + 7) >> 3]; + unsigned char eU[POINT_LEN]; + size_t nlen, rlen, ulen; + uint16_t n0i; + uint32_t res; + + /* + * If the curve is not supported, then report an error. + */ + if (((impl->supported_curves >> pk->curve) & 1) == 0) { + return 0; + } + + /* + * Get the curve parameters (generator and order). + */ + switch (pk->curve) { + case BR_EC_secp256r1: + cd = &br_secp256r1; + break; + case BR_EC_secp384r1: + cd = &br_secp384r1; + break; + case BR_EC_secp521r1: + cd = &br_secp521r1; + break; + default: + return 0; + } + + /* + * Signature length must be even. + */ + if (sig_len & 1) { + return 0; + } + rlen = sig_len >> 1; + + /* + * Public key point must have the proper size for this curve. + */ + if (pk->qlen != cd->generator_len) { + return 0; + } + + /* + * Get modulus; then decode the r and s values. They must be + * lower than the modulus, and s must not be null. + */ + nlen = cd->order_len; + br_i15_decode(n, cd->order, nlen); + n0i = br_i15_ninv15(n[1]); + if (!br_i15_decode_mod(r, sig, rlen, n)) { + return 0; + } + if (!br_i15_decode_mod(s, (const unsigned char *)sig + rlen, rlen, n)) { + return 0; + } + if (br_i15_iszero(s)) { + return 0; + } + + /* + * Invert s. We do that with a modular exponentiation; we use + * the fact that for all the curves we support, the least + * significant byte is not 0 or 1, so we can subtract 2 without + * any carry to process. + * We also want 1/s in Montgomery representation, which can be + * done by converting _from_ Montgomery representation before + * the inversion (because (1/s)*R = 1/(s/R)). + */ + br_i15_from_monty(s, n, n0i); + memcpy(tx, cd->order, nlen); + tx[nlen - 1] -= 2; + br_i15_modpow(s, tx, nlen, n, n0i, t1, t2); + + /* + * Truncate the hash to the modulus length (in bits) and reduce + * it modulo the curve order. The modular reduction can be done + * with a subtraction since the truncation already reduced the + * value to the modulus bit length. + */ + br_ecdsa_i15_bits2int(t1, hash, hash_len, n[0]); + br_i15_sub(t1, n, br_i15_sub(t1, n, 0) ^ 1); + + /* + * Multiply the (truncated, reduced) hash value with 1/s, result in + * t2, encoded in ty. + */ + br_i15_montymul(t2, t1, s, n, n0i); + br_i15_encode(ty, nlen, t2); + + /* + * Multiply r with 1/s, result in t1, encoded in tx. + */ + br_i15_montymul(t1, r, s, n, n0i); + br_i15_encode(tx, nlen, t1); + + /* + * Compute the point x*Q + y*G. + */ + ulen = cd->generator_len; + memcpy(eU, pk->q, ulen); + res = impl->muladd(eU, NULL, ulen, + tx, nlen, ty, nlen, cd->curve); + + /* + * Get the X coordinate, reduce modulo the curve order, and + * compare with the 'r' value. + * + * The modular reduction can be done with subtractions because + * we work with curves of prime order, so the curve order is + * close to the field order (Hasse's theorem). + */ + br_i15_zero(t1, n[0]); + br_i15_decode(t1, &eU[1], ulen >> 1); + t1[0] = n[0]; + br_i15_sub(t1, n, br_i15_sub(t1, n, 0) ^ 1); + res &= ~br_i15_sub(t1, r, 1); + res &= br_i15_iszero(t1); + return res; +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_bits.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_bits.c new file mode 100644 index 0000000..9a8d673 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_bits.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_ecdsa_i31_bits2int(uint32_t *x, + const void *src, size_t len, uint32_t ebitlen) +{ + uint32_t bitlen, hbitlen; + int sc; + + bitlen = ebitlen - (ebitlen >> 5); + hbitlen = (uint32_t)len << 3; + if (hbitlen > bitlen) { + len = (bitlen + 7) >> 3; + sc = (int)((hbitlen - bitlen) & 7); + } else { + sc = 0; + } + br_i31_zero(x, ebitlen); + br_i31_decode(x, src, len); + br_i31_rshift(x, sc); + x[0] = ebitlen; +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_sign_asn1.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_sign_asn1.c new file mode 100644 index 0000000..cf0d351 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_sign_asn1.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define ORDER_LEN ((BR_MAX_EC_SIZE + 7) >> 3) + +/* see bearssl_ec.h */ +size_t +br_ecdsa_i31_sign_asn1(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig) +{ + unsigned char rsig[(ORDER_LEN << 1) + 12]; + size_t sig_len; + + sig_len = br_ecdsa_i31_sign_raw(impl, hf, hash_value, sk, rsig); + if (sig_len == 0) { + return 0; + } + sig_len = br_ecdsa_raw_to_asn1(rsig, sig_len); + memcpy(sig, rsig, sig_len); + return sig_len; +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_sign_raw.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_sign_raw.c new file mode 100644 index 0000000..1df98fe --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_sign_raw.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define I31_LEN ((BR_MAX_EC_SIZE + 61) / 31) +#define POINT_LEN (1 + (((BR_MAX_EC_SIZE + 7) >> 3) << 1)) +#define ORDER_LEN ((BR_MAX_EC_SIZE + 7) >> 3) + +/* see bearssl_ec.h */ +size_t +br_ecdsa_i31_sign_raw(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig) +{ + /* + * IMPORTANT: this code is fit only for curves with a prime + * order. This is needed so that modular reduction of the X + * coordinate of a point can be done with a simple subtraction. + * We also rely on the last byte of the curve order to be distinct + * from 0 and 1. + */ + const br_ec_curve_def *cd; + uint32_t n[I31_LEN], r[I31_LEN], s[I31_LEN], x[I31_LEN]; + uint32_t m[I31_LEN], k[I31_LEN], t1[I31_LEN], t2[I31_LEN]; + unsigned char tt[ORDER_LEN << 1]; + unsigned char eU[POINT_LEN]; + size_t hash_len, nlen, ulen; + uint32_t n0i, ctl; + br_hmac_drbg_context drbg; + + /* + * If the curve is not supported, then exit with an error. + */ + if (((impl->supported_curves >> sk->curve) & 1) == 0) { + return 0; + } + + /* + * Get the curve parameters (generator and order). + */ + switch (sk->curve) { + case BR_EC_secp256r1: + cd = &br_secp256r1; + break; + case BR_EC_secp384r1: + cd = &br_secp384r1; + break; + case BR_EC_secp521r1: + cd = &br_secp521r1; + break; + default: + return 0; + } + + /* + * Get modulus. + */ + nlen = cd->order_len; + br_i31_decode(n, cd->order, nlen); + n0i = br_i31_ninv31(n[1]); + + /* + * Get private key as an i31 integer. This also checks that the + * private key is well-defined (not zero, and less than the + * curve order). + */ + if (!br_i31_decode_mod(x, sk->x, sk->xlen, n)) { + return 0; + } + if (br_i31_iszero(x)) { + return 0; + } + + /* + * Get hash length. + */ + hash_len = (hf->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; + + /* + * Truncate and reduce the hash value modulo the curve order. + */ + br_ecdsa_i31_bits2int(m, hash_value, hash_len, n[0]); + br_i31_sub(m, n, br_i31_sub(m, n, 0) ^ 1); + + /* + * RFC 6979 generation of the "k" value. + * + * The process uses HMAC_DRBG (with the hash function used to + * process the message that is to be signed). The seed is the + * concatenation of the encodings of the private key and + * the hash value (after truncation and modular reduction). + */ + br_i31_encode(tt, nlen, x); + br_i31_encode(tt + nlen, nlen, m); + br_hmac_drbg_init(&drbg, hf, tt, nlen << 1); + for (;;) { + br_hmac_drbg_generate(&drbg, tt, nlen); + br_ecdsa_i31_bits2int(k, tt, nlen, n[0]); + if (br_i31_iszero(k)) { + continue; + } + if (br_i31_sub(k, n, 0)) { + break; + } + } + + /* + * Compute k*G and extract the X coordinate, then reduce it + * modulo the curve order. Since we support only curves with + * prime order, that reduction is only a matter of computing + * a subtraction. + */ + br_i31_encode(tt, nlen, k); + ulen = impl->mulgen(eU, tt, nlen, sk->curve); + br_i31_zero(r, n[0]); + br_i31_decode(r, &eU[1], ulen >> 1); + r[0] = n[0]; + br_i31_sub(r, n, br_i31_sub(r, n, 0) ^ 1); + + /* + * Compute 1/k in double-Montgomery representation. We do so by + * first converting _from_ Montgomery representation (twice), + * then using a modular exponentiation. + */ + br_i31_from_monty(k, n, n0i); + br_i31_from_monty(k, n, n0i); + memcpy(tt, cd->order, nlen); + tt[nlen - 1] -= 2; + br_i31_modpow(k, tt, nlen, n, n0i, t1, t2); + + /* + * Compute s = (m+xr)/k (mod n). + * The k[] array contains R^2/k (double-Montgomery representation); + * we thus can use direct Montgomery multiplications and conversions + * from Montgomery, avoiding any call to br_i31_to_monty() (which + * is slower). + */ + br_i31_from_monty(m, n, n0i); + br_i31_montymul(t1, x, r, n, n0i); + ctl = br_i31_add(t1, m, 1); + ctl |= br_i31_sub(t1, n, 0) ^ 1; + br_i31_sub(t1, n, ctl); + br_i31_montymul(s, t1, k, n, n0i); + + /* + * Encode r and s in the signature. + */ + br_i31_encode(sig, nlen, r); + br_i31_encode((unsigned char *)sig + nlen, nlen, s); + return nlen << 1; +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_vrfy_asn1.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_vrfy_asn1.c new file mode 100644 index 0000000..4161aaa --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_vrfy_asn1.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define FIELD_LEN ((BR_MAX_EC_SIZE + 7) >> 3) + +/* see bearssl_ec.h */ +uint32_t +br_ecdsa_i31_vrfy_asn1(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, + const void *sig, size_t sig_len) +{ + /* + * We use a double-sized buffer because a malformed ASN.1 signature + * may trigger a size expansion when converting to "raw" format. + */ + unsigned char rsig[(FIELD_LEN << 2) + 24]; + + if (sig_len > ((sizeof rsig) >> 1)) { + return 0; + } + memcpy(rsig, sig, sig_len); + sig_len = br_ecdsa_asn1_to_raw(rsig, sig_len); + return br_ecdsa_i31_vrfy_raw(impl, hash, hash_len, pk, rsig, sig_len); +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_vrfy_raw.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_vrfy_raw.c new file mode 100644 index 0000000..259477f --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_i31_vrfy_raw.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define I31_LEN ((BR_MAX_EC_SIZE + 61) / 31) +#define POINT_LEN (1 + (((BR_MAX_EC_SIZE + 7) >> 3) << 1)) + +/* see bearssl_ec.h */ +uint32_t +br_ecdsa_i31_vrfy_raw(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, + const void *sig, size_t sig_len) +{ + /* + * IMPORTANT: this code is fit only for curves with a prime + * order. This is needed so that modular reduction of the X + * coordinate of a point can be done with a simple subtraction. + */ + const br_ec_curve_def *cd; + uint32_t n[I31_LEN], r[I31_LEN], s[I31_LEN], t1[I31_LEN], t2[I31_LEN]; + unsigned char tx[(BR_MAX_EC_SIZE + 7) >> 3]; + unsigned char ty[(BR_MAX_EC_SIZE + 7) >> 3]; + unsigned char eU[POINT_LEN]; + size_t nlen, rlen, ulen; + uint32_t n0i, res; + + /* + * If the curve is not supported, then report an error. + */ + if (((impl->supported_curves >> pk->curve) & 1) == 0) { + return 0; + } + + /* + * Get the curve parameters (generator and order). + */ + switch (pk->curve) { + case BR_EC_secp256r1: + cd = &br_secp256r1; + break; + case BR_EC_secp384r1: + cd = &br_secp384r1; + break; + case BR_EC_secp521r1: + cd = &br_secp521r1; + break; + default: + return 0; + } + + /* + * Signature length must be even. + */ + if (sig_len & 1) { + return 0; + } + rlen = sig_len >> 1; + + /* + * Public key point must have the proper size for this curve. + */ + if (pk->qlen != cd->generator_len) { + return 0; + } + + /* + * Get modulus; then decode the r and s values. They must be + * lower than the modulus, and s must not be null. + */ + nlen = cd->order_len; + br_i31_decode(n, cd->order, nlen); + n0i = br_i31_ninv31(n[1]); + if (!br_i31_decode_mod(r, sig, rlen, n)) { + return 0; + } + if (!br_i31_decode_mod(s, (const unsigned char *)sig + rlen, rlen, n)) { + return 0; + } + if (br_i31_iszero(s)) { + return 0; + } + + /* + * Invert s. We do that with a modular exponentiation; we use + * the fact that for all the curves we support, the least + * significant byte is not 0 or 1, so we can subtract 2 without + * any carry to process. + * We also want 1/s in Montgomery representation, which can be + * done by converting _from_ Montgomery representation before + * the inversion (because (1/s)*R = 1/(s/R)). + */ + br_i31_from_monty(s, n, n0i); + memcpy(tx, cd->order, nlen); + tx[nlen - 1] -= 2; + br_i31_modpow(s, tx, nlen, n, n0i, t1, t2); + + /* + * Truncate the hash to the modulus length (in bits) and reduce + * it modulo the curve order. The modular reduction can be done + * with a subtraction since the truncation already reduced the + * value to the modulus bit length. + */ + br_ecdsa_i31_bits2int(t1, hash, hash_len, n[0]); + br_i31_sub(t1, n, br_i31_sub(t1, n, 0) ^ 1); + + /* + * Multiply the (truncated, reduced) hash value with 1/s, result in + * t2, encoded in ty. + */ + br_i31_montymul(t2, t1, s, n, n0i); + br_i31_encode(ty, nlen, t2); + + /* + * Multiply r with 1/s, result in t1, encoded in tx. + */ + br_i31_montymul(t1, r, s, n, n0i); + br_i31_encode(tx, nlen, t1); + + /* + * Compute the point x*Q + y*G. + */ + ulen = cd->generator_len; + memcpy(eU, pk->q, ulen); + res = impl->muladd(eU, NULL, ulen, + tx, nlen, ty, nlen, cd->curve); + + /* + * Get the X coordinate, reduce modulo the curve order, and + * compare with the 'r' value. + * + * The modular reduction can be done with subtractions because + * we work with curves of prime order, so the curve order is + * close to the field order (Hasse's theorem). + */ + br_i31_zero(t1, n[0]); + br_i31_decode(t1, &eU[1], ulen >> 1); + t1[0] = n[0]; + br_i31_sub(t1, n, br_i31_sub(t1, n, 0) ^ 1); + res &= ~br_i31_sub(t1, r, 1); + res &= br_i31_iszero(t1); + return res; +} diff --git a/BearSSL-OG/libbearssl/src/ec/ecdsa_rta.c b/BearSSL-OG/libbearssl/src/ec/ecdsa_rta.c new file mode 100644 index 0000000..005c62c --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ec/ecdsa_rta.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Compute ASN.1 encoded length for the provided integer. The ASN.1 + * encoding is signed, so its leading bit must have value 0; it must + * also be of minimal length (so leading bytes of value 0 must be + * removed, except if that would contradict the rule about the sign + * bit). + */ +static size_t +asn1_int_length(const unsigned char *x, size_t xlen) +{ + while (xlen > 0 && *x == 0) { + x ++; + xlen --; + } + if (xlen == 0 || *x >= 0x80) { + xlen ++; + } + return xlen; +} + +/* see bearssl_ec.h */ +size_t +br_ecdsa_raw_to_asn1(void *sig, size_t sig_len) +{ + /* + * Internal buffer is large enough to accommodate a signature + * such that r and s fit on 125 bytes each (signed encoding), + * meaning a curve order of up to 999 bits. This is the limit + * that ensures "simple" length encodings. + */ + unsigned char *buf; + size_t hlen, rlen, slen, zlen, off; + unsigned char tmp[257]; + + buf = sig; + if ((sig_len & 1) != 0) { + return 0; + } + + /* + * Compute lengths for the two integers. + */ + hlen = sig_len >> 1; + rlen = asn1_int_length(buf, hlen); + slen = asn1_int_length(buf + hlen, hlen); + if (rlen > 125 || slen > 125) { + return 0; + } + + /* + * SEQUENCE header. + */ + tmp[0] = 0x30; + zlen = rlen + slen + 4; + if (zlen >= 0x80) { + tmp[1] = 0x81; + tmp[2] = zlen; + off = 3; + } else { + tmp[1] = zlen; + off = 2; + } + + /* + * First INTEGER (r). + */ + tmp[off ++] = 0x02; + tmp[off ++] = rlen; + if (rlen > hlen) { + tmp[off] = 0x00; + memcpy(tmp + off + 1, buf, hlen); + } else { + memcpy(tmp + off, buf + hlen - rlen, rlen); + } + off += rlen; + + /* + * Second INTEGER (s). + */ + tmp[off ++] = 0x02; + tmp[off ++] = slen; + if (slen > hlen) { + tmp[off] = 0x00; + memcpy(tmp + off + 1, buf + hlen, hlen); + } else { + memcpy(tmp + off, buf + sig_len - slen, slen); + } + off += slen; + + /* + * Return ASN.1 signature. + */ + memcpy(sig, tmp, off); + return off; +} diff --git a/BearSSL-OG/libbearssl/src/hash/dig_oid.c b/BearSSL-OG/libbearssl/src/hash/dig_oid.c new file mode 100644 index 0000000..cd9692c --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/dig_oid.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * This file contains the encoded OID for the standard hash functions. + * Such OID appear in, for instance, the PKCS#1 v1.5 padding for RSA + * signatures. + */ + +static const unsigned char md5_OID[] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05 +}; + +static const unsigned char sha1_OID[] = { + 0x2B, 0x0E, 0x03, 0x02, 0x1A +}; + +static const unsigned char sha224_OID[] = { + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 +}; + +static const unsigned char sha256_OID[] = { + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 +}; + +static const unsigned char sha384_OID[] = { + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 +}; + +static const unsigned char sha512_OID[] = { + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 +}; + +/* see inner.h */ +const unsigned char * +br_digest_OID(int digest_id, size_t *len) +{ + switch (digest_id) { + case br_md5_ID: + *len = sizeof md5_OID; + return md5_OID; + case br_sha1_ID: + *len = sizeof sha1_OID; + return sha1_OID; + case br_sha224_ID: + *len = sizeof sha224_OID; + return sha224_OID; + case br_sha256_ID: + *len = sizeof sha256_OID; + return sha256_OID; + case br_sha384_ID: + *len = sizeof sha384_OID; + return sha384_OID; + case br_sha512_ID: + *len = sizeof sha512_OID; + return sha512_OID; + default: + *len = 0; + return NULL; + } +} diff --git a/BearSSL-OG/libbearssl/src/hash/dig_size.c b/BearSSL-OG/libbearssl/src/hash/dig_size.c new file mode 100644 index 0000000..4625d2c --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/dig_size.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +size_t +br_digest_size_by_ID(int digest_id) +{ + switch (digest_id) { + case br_md5sha1_ID: + return br_md5_SIZE + br_sha1_SIZE; + case br_md5_ID: + return br_md5_SIZE; + case br_sha1_ID: + return br_sha1_SIZE; + case br_sha224_ID: + return br_sha224_SIZE; + case br_sha256_ID: + return br_sha256_SIZE; + case br_sha384_ID: + return br_sha384_SIZE; + case br_sha512_ID: + return br_sha512_SIZE; + default: + /* abort(); */ + return 0; + } +} diff --git a/BearSSL-OG/libbearssl/src/hash/ghash_ctmul.c b/BearSSL-OG/libbearssl/src/hash/ghash_ctmul.c new file mode 100644 index 0000000..940a4e1 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/ghash_ctmul.c @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * We compute "carryless multiplications" through normal integer + * multiplications, masking out enough bits to create "holes" in which + * carries may expand without altering our bits; we really use 8 data + * bits per 32-bit word, spaced every fourth bit. Accumulated carries + * may not exceed 8 in total, which fits in 4 bits. + * + * It would be possible to use a 3-bit spacing, allowing two operands, + * one with 7 non-zero data bits, the other one with 10 or 11 non-zero + * data bits; this asymmetric splitting makes the overall code more + * complex with thresholds and exceptions, and does not appear to be + * worth the effort. + */ + +/* + * We cannot really autodetect whether multiplications are "slow" or + * not. A typical example is the ARM Cortex M0+, which exists in two + * versions: one with a 1-cycle multiplication opcode, the other with + * a 32-cycle multiplication opcode. They both use exactly the same + * architecture and ABI, and cannot be distinguished from each other + * at compile-time. + * + * Since most modern CPU (even embedded CPU) still have fast + * multiplications, we use the "fast mul" code by default. + */ + +#if BR_SLOW_MUL + +/* + * This implementation uses Karatsuba-like reduction to make fewer + * integer multiplications (9 instead of 16), at the expense of extra + * logical operations (XOR, shifts...). On modern x86 CPU that offer + * fast, pipelined multiplications, this code is about twice slower than + * the simpler code with 16 multiplications. This tendency may be + * reversed on low-end platforms with expensive multiplications. + */ + +#define MUL32(h, l, x, y) do { \ + uint64_t mul32tmp = MUL(x, y); \ + (h) = (uint32_t)(mul32tmp >> 32); \ + (l) = (uint32_t)mul32tmp; \ + } while (0) + +static inline void +bmul(uint32_t *hi, uint32_t *lo, uint32_t x, uint32_t y) +{ + uint32_t x0, x1, x2, x3; + uint32_t y0, y1, y2, y3; + uint32_t a0, a1, a2, a3, a4, a5, a6, a7, a8; + uint32_t b0, b1, b2, b3, b4, b5, b6, b7, b8; + + x0 = x & (uint32_t)0x11111111; + x1 = x & (uint32_t)0x22222222; + x2 = x & (uint32_t)0x44444444; + x3 = x & (uint32_t)0x88888888; + y0 = y & (uint32_t)0x11111111; + y1 = y & (uint32_t)0x22222222; + y2 = y & (uint32_t)0x44444444; + y3 = y & (uint32_t)0x88888888; + + /* + * (x0+W*x1)*(y0+W*y1) -> a0:b0 + * (x2+W*x3)*(y2+W*y3) -> a3:b3 + * ((x0+x2)+W*(x1+x3))*((y0+y2)+W*(y1+y3)) -> a6:b6 + */ + a0 = x0; + b0 = y0; + a1 = x1 >> 1; + b1 = y1 >> 1; + a2 = a0 ^ a1; + b2 = b0 ^ b1; + a3 = x2 >> 2; + b3 = y2 >> 2; + a4 = x3 >> 3; + b4 = y3 >> 3; + a5 = a3 ^ a4; + b5 = b3 ^ b4; + a6 = a0 ^ a3; + b6 = b0 ^ b3; + a7 = a1 ^ a4; + b7 = b1 ^ b4; + a8 = a6 ^ a7; + b8 = b6 ^ b7; + + MUL32(b0, a0, b0, a0); + MUL32(b1, a1, b1, a1); + MUL32(b2, a2, b2, a2); + MUL32(b3, a3, b3, a3); + MUL32(b4, a4, b4, a4); + MUL32(b5, a5, b5, a5); + MUL32(b6, a6, b6, a6); + MUL32(b7, a7, b7, a7); + MUL32(b8, a8, b8, a8); + + a0 &= (uint32_t)0x11111111; + a1 &= (uint32_t)0x11111111; + a2 &= (uint32_t)0x11111111; + a3 &= (uint32_t)0x11111111; + a4 &= (uint32_t)0x11111111; + a5 &= (uint32_t)0x11111111; + a6 &= (uint32_t)0x11111111; + a7 &= (uint32_t)0x11111111; + a8 &= (uint32_t)0x11111111; + b0 &= (uint32_t)0x11111111; + b1 &= (uint32_t)0x11111111; + b2 &= (uint32_t)0x11111111; + b3 &= (uint32_t)0x11111111; + b4 &= (uint32_t)0x11111111; + b5 &= (uint32_t)0x11111111; + b6 &= (uint32_t)0x11111111; + b7 &= (uint32_t)0x11111111; + b8 &= (uint32_t)0x11111111; + + a2 ^= a0 ^ a1; + b2 ^= b0 ^ b1; + a0 ^= (a2 << 1) ^ (a1 << 2); + b0 ^= (b2 << 1) ^ (b1 << 2); + a5 ^= a3 ^ a4; + b5 ^= b3 ^ b4; + a3 ^= (a5 << 1) ^ (a4 << 2); + b3 ^= (b5 << 1) ^ (b4 << 2); + a8 ^= a6 ^ a7; + b8 ^= b6 ^ b7; + a6 ^= (a8 << 1) ^ (a7 << 2); + b6 ^= (b8 << 1) ^ (b7 << 2); + a6 ^= a0 ^ a3; + b6 ^= b0 ^ b3; + *lo = a0 ^ (a6 << 2) ^ (a3 << 4); + *hi = b0 ^ (b6 << 2) ^ (b3 << 4) ^ (a6 >> 30) ^ (a3 >> 28); +} + +#else + +/* + * Simple multiplication in GF(2)[X], using 16 integer multiplications. + */ + +static __inline void +bmul(uint32_t *hi, uint32_t *lo, uint32_t x, uint32_t y) +{ + uint32_t x0, x1, x2, x3; + uint32_t y0, y1, y2, y3; + uint64_t z0, z1, z2, z3; + uint64_t z; + + x0 = x & (uint32_t)0x11111111; + x1 = x & (uint32_t)0x22222222; + x2 = x & (uint32_t)0x44444444; + x3 = x & (uint32_t)0x88888888; + y0 = y & (uint32_t)0x11111111; + y1 = y & (uint32_t)0x22222222; + y2 = y & (uint32_t)0x44444444; + y3 = y & (uint32_t)0x88888888; + z0 = MUL(x0, y0) ^ MUL(x1, y3) ^ MUL(x2, y2) ^ MUL(x3, y1); + z1 = MUL(x0, y1) ^ MUL(x1, y0) ^ MUL(x2, y3) ^ MUL(x3, y2); + z2 = MUL(x0, y2) ^ MUL(x1, y1) ^ MUL(x2, y0) ^ MUL(x3, y3); + z3 = MUL(x0, y3) ^ MUL(x1, y2) ^ MUL(x2, y1) ^ MUL(x3, y0); + z0 &= (uint64_t)0x1111111111111111; + z1 &= (uint64_t)0x2222222222222222; + z2 &= (uint64_t)0x4444444444444444; + z3 &= (uint64_t)0x8888888888888888; + z = z0 | z1 | z2 | z3; + *lo = (uint32_t)z; + *hi = (uint32_t)(z >> 32); +} + +#endif + +/* see bearssl_hash.h */ +void +br_ghash_ctmul(void *y, const void *h, const void *data, size_t len) +{ + const unsigned char *buf, *hb; + unsigned char *yb; + uint32_t yw[4]; + uint32_t hw[4]; + + /* + * Throughout the loop we handle the y and h values as arrays + * of 32-bit words. + */ + buf = data; + yb = y; + hb = h; + yw[3] = br_dec32be(yb); + yw[2] = br_dec32be(yb + 4); + yw[1] = br_dec32be(yb + 8); + yw[0] = br_dec32be(yb + 12); + hw[3] = br_dec32be(hb); + hw[2] = br_dec32be(hb + 4); + hw[1] = br_dec32be(hb + 8); + hw[0] = br_dec32be(hb + 12); + while (len > 0) { + const unsigned char *src; + unsigned char tmp[16]; + int i; + uint32_t a[9], b[9], zw[8]; + uint32_t c0, c1, c2, c3, d0, d1, d2, d3, e0, e1, e2, e3; + + /* + * Get the next 16-byte block (using zero-padding if + * necessary). + */ + if (len >= 16) { + src = buf; + buf += 16; + len -= 16; + } else { + memcpy(tmp, buf, len); + memset(tmp + len, 0, (sizeof tmp) - len); + src = tmp; + len = 0; + } + + /* + * Decode the block. The GHASH standard mandates + * big-endian encoding. + */ + yw[3] ^= br_dec32be(src); + yw[2] ^= br_dec32be(src + 4); + yw[1] ^= br_dec32be(src + 8); + yw[0] ^= br_dec32be(src + 12); + + /* + * We multiply two 128-bit field elements. We use + * Karatsuba to turn that into three 64-bit + * multiplications, which are themselves done with a + * total of nine 32-bit multiplications. + */ + + /* + * y[0,1]*h[0,1] -> 0..2 + * y[2,3]*h[2,3] -> 3..5 + * (y[0,1]+y[2,3])*(h[0,1]+h[2,3]) -> 6..8 + */ + a[0] = yw[0]; + b[0] = hw[0]; + a[1] = yw[1]; + b[1] = hw[1]; + a[2] = a[0] ^ a[1]; + b[2] = b[0] ^ b[1]; + + a[3] = yw[2]; + b[3] = hw[2]; + a[4] = yw[3]; + b[4] = hw[3]; + a[5] = a[3] ^ a[4]; + b[5] = b[3] ^ b[4]; + + a[6] = a[0] ^ a[3]; + b[6] = b[0] ^ b[3]; + a[7] = a[1] ^ a[4]; + b[7] = b[1] ^ b[4]; + a[8] = a[6] ^ a[7]; + b[8] = b[6] ^ b[7]; + + for (i = 0; i < 9; i ++) { + bmul(&b[i], &a[i], b[i], a[i]); + } + + c0 = a[0]; + c1 = b[0] ^ a[2] ^ a[0] ^ a[1]; + c2 = a[1] ^ b[2] ^ b[0] ^ b[1]; + c3 = b[1]; + d0 = a[3]; + d1 = b[3] ^ a[5] ^ a[3] ^ a[4]; + d2 = a[4] ^ b[5] ^ b[3] ^ b[4]; + d3 = b[4]; + e0 = a[6]; + e1 = b[6] ^ a[8] ^ a[6] ^ a[7]; + e2 = a[7] ^ b[8] ^ b[6] ^ b[7]; + e3 = b[7]; + + e0 ^= c0 ^ d0; + e1 ^= c1 ^ d1; + e2 ^= c2 ^ d2; + e3 ^= c3 ^ d3; + c2 ^= e0; + c3 ^= e1; + d0 ^= e2; + d1 ^= e3; + + /* + * GHASH specification has the bits "reversed" (most + * significant is in fact least significant), which does + * not matter for a carryless multiplication, except that + * the 255-bit result must be shifted by 1 bit. + */ + zw[0] = c0 << 1; + zw[1] = (c1 << 1) | (c0 >> 31); + zw[2] = (c2 << 1) | (c1 >> 31); + zw[3] = (c3 << 1) | (c2 >> 31); + zw[4] = (d0 << 1) | (c3 >> 31); + zw[5] = (d1 << 1) | (d0 >> 31); + zw[6] = (d2 << 1) | (d1 >> 31); + zw[7] = (d3 << 1) | (d2 >> 31); + + /* + * We now do the reduction modulo the field polynomial + * to get back to 128 bits. + */ + for (i = 0; i < 4; i ++) { + uint32_t lw; + + lw = zw[i]; + zw[i + 4] ^= lw ^ (lw >> 1) ^ (lw >> 2) ^ (lw >> 7); + zw[i + 3] ^= (lw << 31) ^ (lw << 30) ^ (lw << 25); + } + memcpy(yw, zw + 4, sizeof yw); + } + + /* + * Encode back the result. + */ + br_enc32be(yb, yw[3]); + br_enc32be(yb + 4, yw[2]); + br_enc32be(yb + 8, yw[1]); + br_enc32be(yb + 12, yw[0]); +} diff --git a/BearSSL-OG/libbearssl/src/hash/ghash_ctmul32.c b/BearSSL-OG/libbearssl/src/hash/ghash_ctmul32.c new file mode 100644 index 0000000..de02344 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/ghash_ctmul32.c @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * This implementation uses 32-bit multiplications, and only the low + * 32 bits for each multiplication result. This is meant primarily for + * the ARM Cortex M0 and M0+, whose multiplication opcode does not yield + * the upper 32 bits; but it might also be useful on architectures where + * access to the upper 32 bits requires use of specific registers that + * create contention (e.g. on i386, "mul" necessarily outputs the result + * in edx:eax, while "imul" can use any registers but is limited to the + * low 32 bits). + * + * The implementation trick that is used here is bit-reversing (bit 0 + * is swapped with bit 31, bit 1 with bit 30, and so on). In GF(2)[X], + * for all values x and y, we have: + * rev32(x) * rev32(y) = rev64(x * y) + * In other words, if we bit-reverse (over 32 bits) the operands, then we + * bit-reverse (over 64 bits) the result. + */ + +/* + * Multiplication in GF(2)[X], truncated to its low 32 bits. + */ +static __inline uint32_t +bmul32(uint32_t x, uint32_t y) +{ + uint32_t x0, x1, x2, x3; + uint32_t y0, y1, y2, y3; + uint32_t z0, z1, z2, z3; + + x0 = x & (uint32_t)0x11111111; + x1 = x & (uint32_t)0x22222222; + x2 = x & (uint32_t)0x44444444; + x3 = x & (uint32_t)0x88888888; + y0 = y & (uint32_t)0x11111111; + y1 = y & (uint32_t)0x22222222; + y2 = y & (uint32_t)0x44444444; + y3 = y & (uint32_t)0x88888888; + z0 = (x0 * y0) ^ (x1 * y3) ^ (x2 * y2) ^ (x3 * y1); + z1 = (x0 * y1) ^ (x1 * y0) ^ (x2 * y3) ^ (x3 * y2); + z2 = (x0 * y2) ^ (x1 * y1) ^ (x2 * y0) ^ (x3 * y3); + z3 = (x0 * y3) ^ (x1 * y2) ^ (x2 * y1) ^ (x3 * y0); + z0 &= (uint32_t)0x11111111; + z1 &= (uint32_t)0x22222222; + z2 &= (uint32_t)0x44444444; + z3 &= (uint32_t)0x88888888; + return z0 | z1 | z2 | z3; +} + +/* + * Bit-reverse a 32-bit word. + */ +static uint32_t +rev32(uint32_t x) +{ +#define RMS(m, s) do { \ + x = ((x & (uint32_t)(m)) << (s)) \ + | ((x >> (s)) & (uint32_t)(m)); \ + } while (0) + + RMS(0x55555555, 1); + RMS(0x33333333, 2); + RMS(0x0F0F0F0F, 4); + RMS(0x00FF00FF, 8); + return (x << 16) | (x >> 16); + +#undef RMS +} + +/* see bearssl_hash.h */ +void +br_ghash_ctmul32(void *y, const void *h, const void *data, size_t len) +{ + /* + * This implementation is similar to br_ghash_ctmul() except + * that we have to do the multiplication twice, with the + * "normal" and "bit reversed" operands. Hence we end up with + * eighteen 32-bit multiplications instead of nine. + */ + + const unsigned char *buf, *hb; + unsigned char *yb; + uint32_t yw[4]; + uint32_t hw[4], hwr[4]; + + buf = data; + yb = y; + hb = h; + yw[3] = br_dec32be(yb); + yw[2] = br_dec32be(yb + 4); + yw[1] = br_dec32be(yb + 8); + yw[0] = br_dec32be(yb + 12); + hw[3] = br_dec32be(hb); + hw[2] = br_dec32be(hb + 4); + hw[1] = br_dec32be(hb + 8); + hw[0] = br_dec32be(hb + 12); + hwr[3] = rev32(hw[3]); + hwr[2] = rev32(hw[2]); + hwr[1] = rev32(hw[1]); + hwr[0] = rev32(hw[0]); + while (len > 0) { + const unsigned char *src; + unsigned char tmp[16]; + int i; + uint32_t a[18], b[18], c[18]; + uint32_t d0, d1, d2, d3, d4, d5, d6, d7; + uint32_t zw[8]; + + if (len >= 16) { + src = buf; + buf += 16; + len -= 16; + } else { + memcpy(tmp, buf, len); + memset(tmp + len, 0, (sizeof tmp) - len); + src = tmp; + len = 0; + } + yw[3] ^= br_dec32be(src); + yw[2] ^= br_dec32be(src + 4); + yw[1] ^= br_dec32be(src + 8); + yw[0] ^= br_dec32be(src + 12); + + /* + * We are using Karatsuba: the 128x128 multiplication is + * reduced to three 64x64 multiplications, hence nine + * 32x32 multiplications. With the bit-reversal trick, + * we have to perform 18 32x32 multiplications. + */ + + /* + * y[0,1]*h[0,1] -> 0,1,4 + * y[2,3]*h[2,3] -> 2,3,5 + * (y[0,1]+y[2,3])*(h[0,1]+h[2,3]) -> 6,7,8 + */ + + a[0] = yw[0]; + a[1] = yw[1]; + a[2] = yw[2]; + a[3] = yw[3]; + a[4] = a[0] ^ a[1]; + a[5] = a[2] ^ a[3]; + a[6] = a[0] ^ a[2]; + a[7] = a[1] ^ a[3]; + a[8] = a[6] ^ a[7]; + + a[ 9] = rev32(yw[0]); + a[10] = rev32(yw[1]); + a[11] = rev32(yw[2]); + a[12] = rev32(yw[3]); + a[13] = a[ 9] ^ a[10]; + a[14] = a[11] ^ a[12]; + a[15] = a[ 9] ^ a[11]; + a[16] = a[10] ^ a[12]; + a[17] = a[15] ^ a[16]; + + b[0] = hw[0]; + b[1] = hw[1]; + b[2] = hw[2]; + b[3] = hw[3]; + b[4] = b[0] ^ b[1]; + b[5] = b[2] ^ b[3]; + b[6] = b[0] ^ b[2]; + b[7] = b[1] ^ b[3]; + b[8] = b[6] ^ b[7]; + + b[ 9] = hwr[0]; + b[10] = hwr[1]; + b[11] = hwr[2]; + b[12] = hwr[3]; + b[13] = b[ 9] ^ b[10]; + b[14] = b[11] ^ b[12]; + b[15] = b[ 9] ^ b[11]; + b[16] = b[10] ^ b[12]; + b[17] = b[15] ^ b[16]; + + for (i = 0; i < 18; i ++) { + c[i] = bmul32(a[i], b[i]); + } + + c[4] ^= c[0] ^ c[1]; + c[5] ^= c[2] ^ c[3]; + c[8] ^= c[6] ^ c[7]; + + c[13] ^= c[ 9] ^ c[10]; + c[14] ^= c[11] ^ c[12]; + c[17] ^= c[15] ^ c[16]; + + /* + * y[0,1]*h[0,1] -> 0,9^4,1^13,10 + * y[2,3]*h[2,3] -> 2,11^5,3^14,12 + * (y[0,1]+y[2,3])*(h[0,1]+h[2,3]) -> 6,15^8,7^17,16 + */ + d0 = c[0]; + d1 = c[4] ^ (rev32(c[9]) >> 1); + d2 = c[1] ^ c[0] ^ c[2] ^ c[6] ^ (rev32(c[13]) >> 1); + d3 = c[4] ^ c[5] ^ c[8] + ^ (rev32(c[10] ^ c[9] ^ c[11] ^ c[15]) >> 1); + d4 = c[2] ^ c[1] ^ c[3] ^ c[7] + ^ (rev32(c[13] ^ c[14] ^ c[17]) >> 1); + d5 = c[5] ^ (rev32(c[11] ^ c[10] ^ c[12] ^ c[16]) >> 1); + d6 = c[3] ^ (rev32(c[14]) >> 1); + d7 = rev32(c[12]) >> 1; + + zw[0] = d0 << 1; + zw[1] = (d1 << 1) | (d0 >> 31); + zw[2] = (d2 << 1) | (d1 >> 31); + zw[3] = (d3 << 1) | (d2 >> 31); + zw[4] = (d4 << 1) | (d3 >> 31); + zw[5] = (d5 << 1) | (d4 >> 31); + zw[6] = (d6 << 1) | (d5 >> 31); + zw[7] = (d7 << 1) | (d6 >> 31); + + for (i = 0; i < 4; i ++) { + uint32_t lw; + + lw = zw[i]; + zw[i + 4] ^= lw ^ (lw >> 1) ^ (lw >> 2) ^ (lw >> 7); + zw[i + 3] ^= (lw << 31) ^ (lw << 30) ^ (lw << 25); + } + memcpy(yw, zw + 4, sizeof yw); + } + br_enc32be(yb, yw[3]); + br_enc32be(yb + 4, yw[2]); + br_enc32be(yb + 8, yw[1]); + br_enc32be(yb + 12, yw[0]); +} diff --git a/BearSSL-OG/libbearssl/src/hash/ghash_ctmul64.c b/BearSSL-OG/libbearssl/src/hash/ghash_ctmul64.c new file mode 100644 index 0000000..a5a5e36 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/ghash_ctmul64.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * This is the 64-bit variant of br_ghash_ctmul32(), with 64-bit operands + * and bit reversal of 64-bit words. + */ + +static __inline uint64_t +bmul64(uint64_t x, uint64_t y) +{ + uint64_t x0, x1, x2, x3; + uint64_t y0, y1, y2, y3; + uint64_t z0, z1, z2, z3; + + x0 = x & (uint64_t)0x1111111111111111; + x1 = x & (uint64_t)0x2222222222222222; + x2 = x & (uint64_t)0x4444444444444444; + x3 = x & (uint64_t)0x8888888888888888; + y0 = y & (uint64_t)0x1111111111111111; + y1 = y & (uint64_t)0x2222222222222222; + y2 = y & (uint64_t)0x4444444444444444; + y3 = y & (uint64_t)0x8888888888888888; + z0 = (x0 * y0) ^ (x1 * y3) ^ (x2 * y2) ^ (x3 * y1); + z1 = (x0 * y1) ^ (x1 * y0) ^ (x2 * y3) ^ (x3 * y2); + z2 = (x0 * y2) ^ (x1 * y1) ^ (x2 * y0) ^ (x3 * y3); + z3 = (x0 * y3) ^ (x1 * y2) ^ (x2 * y1) ^ (x3 * y0); + z0 &= (uint64_t)0x1111111111111111; + z1 &= (uint64_t)0x2222222222222222; + z2 &= (uint64_t)0x4444444444444444; + z3 &= (uint64_t)0x8888888888888888; + return z0 | z1 | z2 | z3; +} + +static uint64_t +rev64(uint64_t x) +{ +#define RMS(m, s) do { \ + x = ((x & (uint64_t)(m)) << (s)) \ + | ((x >> (s)) & (uint64_t)(m)); \ + } while (0) + + RMS(0x5555555555555555, 1); + RMS(0x3333333333333333, 2); + RMS(0x0F0F0F0F0F0F0F0F, 4); + RMS(0x00FF00FF00FF00FF, 8); + RMS(0x0000FFFF0000FFFF, 16); + return (x << 32) | (x >> 32); + +#undef RMS +} + +/* see bearssl_ghash.h */ +void +br_ghash_ctmul64(void *y, const void *h, const void *data, size_t len) +{ + const unsigned char *buf, *hb; + unsigned char *yb; + uint64_t y0, y1; + uint64_t h0, h1, h2, h0r, h1r, h2r; + + buf = data; + yb = y; + hb = h; + y1 = br_dec64be(yb); + y0 = br_dec64be(yb + 8); + h1 = br_dec64be(hb); + h0 = br_dec64be(hb + 8); + h0r = rev64(h0); + h1r = rev64(h1); + h2 = h0 ^ h1; + h2r = h0r ^ h1r; + while (len > 0) { + const unsigned char *src; + unsigned char tmp[16]; + uint64_t y0r, y1r, y2, y2r; + uint64_t z0, z1, z2, z0h, z1h, z2h; + uint64_t v0, v1, v2, v3; + + if (len >= 16) { + src = buf; + buf += 16; + len -= 16; + } else { + memcpy(tmp, buf, len); + memset(tmp + len, 0, (sizeof tmp) - len); + src = tmp; + len = 0; + } + y1 ^= br_dec64be(src); + y0 ^= br_dec64be(src + 8); + + y0r = rev64(y0); + y1r = rev64(y1); + y2 = y0 ^ y1; + y2r = y0r ^ y1r; + + z0 = bmul64(y0, h0); + z1 = bmul64(y1, h1); + z2 = bmul64(y2, h2); + z0h = bmul64(y0r, h0r); + z1h = bmul64(y1r, h1r); + z2h = bmul64(y2r, h2r); + z2 ^= z0 ^ z1; + z2h ^= z0h ^ z1h; + z0h = rev64(z0h) >> 1; + z1h = rev64(z1h) >> 1; + z2h = rev64(z2h) >> 1; + + v0 = z0; + v1 = z0h ^ z2; + v2 = z1 ^ z2h; + v3 = z1h; + + v3 = (v3 << 1) | (v2 >> 63); + v2 = (v2 << 1) | (v1 >> 63); + v1 = (v1 << 1) | (v0 >> 63); + v0 = (v0 << 1); + + v2 ^= v0 ^ (v0 >> 1) ^ (v0 >> 2) ^ (v0 >> 7); + v1 ^= (v0 << 63) ^ (v0 << 62) ^ (v0 << 57); + v3 ^= v1 ^ (v1 >> 1) ^ (v1 >> 2) ^ (v1 >> 7); + v2 ^= (v1 << 63) ^ (v1 << 62) ^ (v1 << 57); + + y0 = v2; + y1 = v3; + } + + br_enc64be(yb, y1); + br_enc64be(yb + 8, y0); +} diff --git a/BearSSL-OG/libbearssl/src/hash/ghash_pclmul.c b/BearSSL-OG/libbearssl/src/hash/ghash_pclmul.c new file mode 100644 index 0000000..a58e7dc --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/ghash_pclmul.c @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_ENABLE_INTRINSICS 1 +#include "inner.h" + +/* + * This is the GHASH implementation that leverages the pclmulqdq opcode + * (from the AES-NI instructions). + */ + +#if BR_AES_X86NI + +/* + * Test CPU support for PCLMULQDQ. + */ +static inline int +pclmul_supported(void) +{ + /* + * Bit mask for features in ECX: + * 1 PCLMULQDQ support + */ + return br_cpuid(0, 0, 0x00000002, 0); +} + +/* see bearssl_hash.h */ +br_ghash +br_ghash_pclmul_get(void) +{ + return pclmul_supported() ? &br_ghash_pclmul : 0; +} + +BR_TARGETS_X86_UP + +/* + * GHASH is defined over elements of GF(2^128) with "full little-endian" + * representation: leftmost byte is least significant, and, within each + * byte, leftmost _bit_ is least significant. The natural ordering in + * x86 is "mixed little-endian": bytes are ordered from least to most + * significant, but bits within a byte are in most-to-least significant + * order. Going to full little-endian representation would require + * reversing bits within each byte, which is doable but expensive. + * + * Instead, we go to full big-endian representation, by swapping bytes + * around, which is done with a single _mm_shuffle_epi8() opcode (it + * comes with SSSE3; all CPU that offer pclmulqdq also have SSSE3). We + * can use a full big-endian representation because in a carryless + * multiplication, we have a nice bit reversal property: + * + * rev_128(x) * rev_128(y) = rev_255(x * y) + * + * So by using full big-endian, we still get the right result, except + * that it is right-shifted by 1 bit. The left-shift is relatively + * inexpensive, and it can be mutualised. + * + * + * Since SSE2 opcodes do not have facilities for shitfting full 128-bit + * values with bit precision, we have to break down values into 64-bit + * chunks. We number chunks from 0 to 3 in left to right order. + */ + +/* + * Byte-swap a complete 128-bit value. This normally uses + * _mm_shuffle_epi8(), which gets translated to pshufb (an SSSE3 opcode). + * However, this crashes old Clang versions, so, for Clang before 3.8, + * we use an alternate (and less efficient) version. + */ +#if BR_CLANG && !BR_CLANG_3_8 +#define BYTESWAP_DECL +#define BYTESWAP_PREP (void)0 +#define BYTESWAP(x) do { \ + __m128i byteswap1, byteswap2; \ + byteswap1 = (x); \ + byteswap2 = _mm_srli_epi16(byteswap1, 8); \ + byteswap1 = _mm_slli_epi16(byteswap1, 8); \ + byteswap1 = _mm_or_si128(byteswap1, byteswap2); \ + byteswap1 = _mm_shufflelo_epi16(byteswap1, 0x1B); \ + byteswap1 = _mm_shufflehi_epi16(byteswap1, 0x1B); \ + (x) = _mm_shuffle_epi32(byteswap1, 0x4E); \ + } while (0) +#else +#define BYTESWAP_DECL __m128i byteswap_index; +#define BYTESWAP_PREP do { \ + byteswap_index = _mm_set_epi8( \ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); \ + } while (0) +#define BYTESWAP(x) do { \ + (x) = _mm_shuffle_epi8((x), byteswap_index); \ + } while (0) +#endif + +/* + * Call pclmulqdq. Clang appears to have trouble with the intrinsic, so, + * for that compiler, we use inline assembly. Inline assembly is + * potentially a bit slower because the compiler does not understand + * what the opcode does, and thus cannot optimize instruction + * scheduling. + * + * We use a target of "sse2" only, so that Clang may still handle the + * '__m128i' type and allocate SSE2 registers. + */ +#if BR_CLANG +BR_TARGET("sse2") +static inline __m128i +pclmulqdq00(__m128i x, __m128i y) +{ + __asm__ ("pclmulqdq $0x00, %1, %0" : "+x" (x) : "x" (y)); + return x; +} +BR_TARGET("sse2") +static inline __m128i +pclmulqdq11(__m128i x, __m128i y) +{ + __asm__ ("pclmulqdq $0x11, %1, %0" : "+x" (x) : "x" (y)); + return x; +} +#else +#define pclmulqdq00(x, y) _mm_clmulepi64_si128(x, y, 0x00) +#define pclmulqdq11(x, y) _mm_clmulepi64_si128(x, y, 0x11) +#endif + +/* + * From a 128-bit value kw, compute kx as the XOR of the two 64-bit + * halves of kw (into the right half of kx; left half is unspecified). + */ +#define BK(kw, kx) do { \ + kx = _mm_xor_si128(kw, _mm_shuffle_epi32(kw, 0x0E)); \ + } while (0) + +/* + * Combine two 64-bit values (k0:k1) into a 128-bit (kw) value and + * the XOR of the two values (kx). + */ +#define PBK(k0, k1, kw, kx) do { \ + kw = _mm_unpacklo_epi64(k1, k0); \ + kx = _mm_xor_si128(k0, k1); \ + } while (0) + +/* + * Left-shift by 1 bit a 256-bit value (in four 64-bit words). + */ +#define SL_256(x0, x1, x2, x3) do { \ + x0 = _mm_or_si128( \ + _mm_slli_epi64(x0, 1), \ + _mm_srli_epi64(x1, 63)); \ + x1 = _mm_or_si128( \ + _mm_slli_epi64(x1, 1), \ + _mm_srli_epi64(x2, 63)); \ + x2 = _mm_or_si128( \ + _mm_slli_epi64(x2, 1), \ + _mm_srli_epi64(x3, 63)); \ + x3 = _mm_slli_epi64(x3, 1); \ + } while (0) + +/* + * Perform reduction in GF(2^128). The 256-bit value is in x0..x3; + * result is written in x0..x1. + */ +#define REDUCE_F128(x0, x1, x2, x3) do { \ + x1 = _mm_xor_si128( \ + x1, \ + _mm_xor_si128( \ + _mm_xor_si128( \ + x3, \ + _mm_srli_epi64(x3, 1)), \ + _mm_xor_si128( \ + _mm_srli_epi64(x3, 2), \ + _mm_srli_epi64(x3, 7)))); \ + x2 = _mm_xor_si128( \ + _mm_xor_si128( \ + x2, \ + _mm_slli_epi64(x3, 63)), \ + _mm_xor_si128( \ + _mm_slli_epi64(x3, 62), \ + _mm_slli_epi64(x3, 57))); \ + x0 = _mm_xor_si128( \ + x0, \ + _mm_xor_si128( \ + _mm_xor_si128( \ + x2, \ + _mm_srli_epi64(x2, 1)), \ + _mm_xor_si128( \ + _mm_srli_epi64(x2, 2), \ + _mm_srli_epi64(x2, 7)))); \ + x1 = _mm_xor_si128( \ + _mm_xor_si128( \ + x1, \ + _mm_slli_epi64(x2, 63)), \ + _mm_xor_si128( \ + _mm_slli_epi64(x2, 62), \ + _mm_slli_epi64(x2, 57))); \ + } while (0) + +/* + * Square value kw into (dw,dx). + */ +#define SQUARE_F128(kw, dw, dx) do { \ + __m128i z0, z1, z2, z3; \ + z1 = pclmulqdq11(kw, kw); \ + z3 = pclmulqdq00(kw, kw); \ + z0 = _mm_shuffle_epi32(z1, 0x0E); \ + z2 = _mm_shuffle_epi32(z3, 0x0E); \ + SL_256(z0, z1, z2, z3); \ + REDUCE_F128(z0, z1, z2, z3); \ + PBK(z0, z1, dw, dx); \ + } while (0) + +/* see bearssl_hash.h */ +BR_TARGET("ssse3,pclmul") +void +br_ghash_pclmul(void *y, const void *h, const void *data, size_t len) +{ + const unsigned char *buf1, *buf2; + unsigned char tmp[64]; + size_t num4, num1; + __m128i yw, h1w, h1x; + BYTESWAP_DECL + + /* + * We split data into two chunks. First chunk starts at buf1 + * and contains num4 blocks of 64-byte values. Second chunk + * starts at buf2 and contains num1 blocks of 16-byte values. + * We want the first chunk to be as large as possible. + */ + buf1 = data; + num4 = len >> 6; + len &= 63; + buf2 = buf1 + (num4 << 6); + num1 = (len + 15) >> 4; + if ((len & 15) != 0) { + memcpy(tmp, buf2, len); + memset(tmp + len, 0, (num1 << 4) - len); + buf2 = tmp; + } + + /* + * Preparatory step for endian conversions. + */ + BYTESWAP_PREP; + + /* + * Load y and h. + */ + yw = _mm_loadu_si128(y); + h1w = _mm_loadu_si128(h); + BYTESWAP(yw); + BYTESWAP(h1w); + BK(h1w, h1x); + + if (num4 > 0) { + __m128i h2w, h2x, h3w, h3x, h4w, h4x; + __m128i t0, t1, t2, t3; + + /* + * Compute h2 = h^2. + */ + SQUARE_F128(h1w, h2w, h2x); + + /* + * Compute h3 = h^3 = h*(h^2). + */ + t1 = pclmulqdq11(h1w, h2w); + t3 = pclmulqdq00(h1w, h2w); + t2 = _mm_xor_si128(pclmulqdq00(h1x, h2x), + _mm_xor_si128(t1, t3)); + t0 = _mm_shuffle_epi32(t1, 0x0E); + t1 = _mm_xor_si128(t1, _mm_shuffle_epi32(t2, 0x0E)); + t2 = _mm_xor_si128(t2, _mm_shuffle_epi32(t3, 0x0E)); + SL_256(t0, t1, t2, t3); + REDUCE_F128(t0, t1, t2, t3); + PBK(t0, t1, h3w, h3x); + + /* + * Compute h4 = h^4 = (h^2)^2. + */ + SQUARE_F128(h2w, h4w, h4x); + + while (num4 -- > 0) { + __m128i aw0, aw1, aw2, aw3; + __m128i ax0, ax1, ax2, ax3; + + aw0 = _mm_loadu_si128((void *)(buf1 + 0)); + aw1 = _mm_loadu_si128((void *)(buf1 + 16)); + aw2 = _mm_loadu_si128((void *)(buf1 + 32)); + aw3 = _mm_loadu_si128((void *)(buf1 + 48)); + BYTESWAP(aw0); + BYTESWAP(aw1); + BYTESWAP(aw2); + BYTESWAP(aw3); + buf1 += 64; + + aw0 = _mm_xor_si128(aw0, yw); + BK(aw1, ax1); + BK(aw2, ax2); + BK(aw3, ax3); + BK(aw0, ax0); + + t1 = _mm_xor_si128( + _mm_xor_si128( + pclmulqdq11(aw0, h4w), + pclmulqdq11(aw1, h3w)), + _mm_xor_si128( + pclmulqdq11(aw2, h2w), + pclmulqdq11(aw3, h1w))); + t3 = _mm_xor_si128( + _mm_xor_si128( + pclmulqdq00(aw0, h4w), + pclmulqdq00(aw1, h3w)), + _mm_xor_si128( + pclmulqdq00(aw2, h2w), + pclmulqdq00(aw3, h1w))); + t2 = _mm_xor_si128( + _mm_xor_si128( + pclmulqdq00(ax0, h4x), + pclmulqdq00(ax1, h3x)), + _mm_xor_si128( + pclmulqdq00(ax2, h2x), + pclmulqdq00(ax3, h1x))); + t2 = _mm_xor_si128(t2, _mm_xor_si128(t1, t3)); + t0 = _mm_shuffle_epi32(t1, 0x0E); + t1 = _mm_xor_si128(t1, _mm_shuffle_epi32(t2, 0x0E)); + t2 = _mm_xor_si128(t2, _mm_shuffle_epi32(t3, 0x0E)); + SL_256(t0, t1, t2, t3); + REDUCE_F128(t0, t1, t2, t3); + yw = _mm_unpacklo_epi64(t1, t0); + } + } + + while (num1 -- > 0) { + __m128i aw, ax; + __m128i t0, t1, t2, t3; + + aw = _mm_loadu_si128((void *)buf2); + BYTESWAP(aw); + buf2 += 16; + + aw = _mm_xor_si128(aw, yw); + BK(aw, ax); + + t1 = pclmulqdq11(aw, h1w); + t3 = pclmulqdq00(aw, h1w); + t2 = pclmulqdq00(ax, h1x); + t2 = _mm_xor_si128(t2, _mm_xor_si128(t1, t3)); + t0 = _mm_shuffle_epi32(t1, 0x0E); + t1 = _mm_xor_si128(t1, _mm_shuffle_epi32(t2, 0x0E)); + t2 = _mm_xor_si128(t2, _mm_shuffle_epi32(t3, 0x0E)); + SL_256(t0, t1, t2, t3); + REDUCE_F128(t0, t1, t2, t3); + yw = _mm_unpacklo_epi64(t1, t0); + } + + BYTESWAP(yw); + _mm_storeu_si128(y, yw); +} + +BR_TARGETS_X86_DOWN + +#else + +/* see bearssl_hash.h */ +br_ghash +br_ghash_pclmul_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/hash/ghash_pwr8.c b/BearSSL-OG/libbearssl/src/hash/ghash_pwr8.c new file mode 100644 index 0000000..2e7b0f4 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/ghash_pwr8.c @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_POWER_ASM_MACROS 1 +#include "inner.h" + +/* + * This is the GHASH implementation that leverages the POWER8 opcodes. + */ + +#if BR_POWER8 + +/* + * Some symbolic names for registers. + * HB0 = 16 bytes of value 0 + * HB1 = 16 bytes of value 1 + * HB2 = 16 bytes of value 2 + * HB6 = 16 bytes of value 6 + * HB7 = 16 bytes of value 7 + * TT0, TT1 and TT2 are temporaries + * + * BSW holds the pattern for byteswapping 32-bit words; this is set only + * on little-endian systems. XBSW is the same register with the +32 offset + * for access with the VSX opcodes. + */ +#define HB0 0 +#define HB1 1 +#define HB2 2 +#define HB6 3 +#define HB7 4 +#define TT0 5 +#define TT1 6 +#define TT2 7 + +#define BSW 8 +#define XBSW 40 + +/* + * Macro to initialise the constants. + */ +#define INIT \ + vxor(HB0, HB0, HB0) \ + vspltisb(HB1, 1) \ + vspltisb(HB2, 2) \ + vspltisb(HB6, 6) \ + vspltisb(HB7, 7) \ + INIT_BSW + +/* + * Fix endianness of a value after reading it or before writing it, if + * necessary. + */ +#if BR_POWER8_LE +#define INIT_BSW lxvw4x(XBSW, 0, %[idx2be]) +#define FIX_ENDIAN(xx) vperm(xx, xx, xx, BSW) +#else +#define INIT_BSW +#define FIX_ENDIAN(xx) +#endif + +/* + * Left-shift x0:x1 by one bit to the left. This is a corrective action + * needed because GHASH is defined in full little-endian specification, + * while the opcodes use full big-endian convention, so the 255-bit product + * ends up one bit to the right. + */ +#define SL_256(x0, x1) \ + vsldoi(TT0, HB0, x1, 1) \ + vsl(x0, x0, HB1) \ + vsr(TT0, TT0, HB7) \ + vsl(x1, x1, HB1) \ + vxor(x0, x0, TT0) + +/* + * Reduce x0:x1 in GF(2^128), result in xd (register xd may be the same as + * x0 or x1, or a different register). x0 and x1 are modified. + */ +#define REDUCE_F128(xd, x0, x1) \ + vxor(x0, x0, x1) \ + vsr(TT0, x1, HB1) \ + vsr(TT1, x1, HB2) \ + vsr(TT2, x1, HB7) \ + vxor(x0, x0, TT0) \ + vxor(TT1, TT1, TT2) \ + vxor(x0, x0, TT1) \ + vsldoi(x1, x1, HB0, 15) \ + vsl(TT1, x1, HB6) \ + vsl(TT2, x1, HB1) \ + vxor(x1, TT1, TT2) \ + vsr(TT0, x1, HB1) \ + vsr(TT1, x1, HB2) \ + vsr(TT2, x1, HB7) \ + vxor(x0, x0, x1) \ + vxor(x0, x0, TT0) \ + vxor(TT1, TT1, TT2) \ + vxor(xd, x0, TT1) + +/* see bearssl_hash.h */ +void +br_ghash_pwr8(void *y, const void *h, const void *data, size_t len) +{ + const unsigned char *buf1, *buf2; + size_t num4, num1; + unsigned char tmp[64]; + long cc0, cc1, cc2, cc3; + +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + + buf1 = data; + + /* + * Assembly code requires data into two chunks; first chunk + * must contain a number of blocks which is a multiple of 4. + * Since the processing for the first chunk is faster, we want + * to make it as big as possible. + * + * For the remainder, there are two possibilities: + * -- if the remainder size is a multiple of 16, then use it + * in place; + * -- otherwise, copy it to the tmp[] array and pad it with + * zeros. + */ + num4 = len >> 6; + buf2 = buf1 + (num4 << 6); + len &= 63; + num1 = (len + 15) >> 4; + if ((len & 15) != 0) { + memcpy(tmp, buf2, len); + memset(tmp + len, 0, (num1 << 4) - len); + buf2 = tmp; + } + + cc0 = 0; + cc1 = 16; + cc2 = 32; + cc3 = 48; + asm volatile ( + INIT + + /* + * Load current h (denoted hereafter h1) in v9. + */ + lxvw4x(41, 0, %[h]) + FIX_ENDIAN(9) + + /* + * Load current y into v28. + */ + lxvw4x(60, 0, %[y]) + FIX_ENDIAN(28) + + /* + * Split h1 into three registers: + * v17 = h1_1:h1_0 + * v18 = 0:h1_0 + * v19 = h1_1:0 + */ + xxpermdi(49, 41, 41, 2) + vsldoi(18, HB0, 9, 8) + vsldoi(19, 9, HB0, 8) + + /* + * If num4 is 0, skip directly to the second chunk. + */ + cmpldi(%[num4], 0) + beq(chunk1) + + /* + * Compute h2 = h*h in v10. + */ + vpmsumd(10, 18, 18) + vpmsumd(11, 19, 19) + SL_256(10, 11) + REDUCE_F128(10, 10, 11) + + /* + * Compute h3 = h*h*h in v11. + * We first split h2 into: + * v10 = h2_0:h2_1 + * v11 = 0:h2_0 + * v12 = h2_1:0 + * Then we do the product with h1, and reduce into v11. + */ + vsldoi(11, HB0, 10, 8) + vsldoi(12, 10, HB0, 8) + vpmsumd(13, 10, 17) + vpmsumd(11, 11, 18) + vpmsumd(12, 12, 19) + vsldoi(14, HB0, 13, 8) + vsldoi(15, 13, HB0, 8) + vxor(11, 11, 14) + vxor(12, 12, 15) + SL_256(11, 12) + REDUCE_F128(11, 11, 12) + + /* + * Compute h4 = h*h*h*h in v12. This is done by squaring h2. + */ + vsldoi(12, HB0, 10, 8) + vsldoi(13, 10, HB0, 8) + vpmsumd(12, 12, 12) + vpmsumd(13, 13, 13) + SL_256(12, 13) + REDUCE_F128(12, 12, 13) + + /* + * Repack h1, h2, h3 and h4: + * v13 = h4_0:h3_0 + * v14 = h4_1:h3_1 + * v15 = h2_0:h1_0 + * v16 = h2_1:h1_1 + */ + xxpermdi(45, 44, 43, 0) + xxpermdi(46, 44, 43, 3) + xxpermdi(47, 42, 41, 0) + xxpermdi(48, 42, 41, 3) + + /* + * Loop for each group of four blocks. + */ + mtctr(%[num4]) + label(loop4) + /* + * Read the four next blocks. + * v20 = y + a0 = b0 + * v21 = a1 = b1 + * v22 = a2 = b2 + * v23 = a3 = b3 + */ + lxvw4x(52, %[cc0], %[buf1]) + lxvw4x(53, %[cc1], %[buf1]) + lxvw4x(54, %[cc2], %[buf1]) + lxvw4x(55, %[cc3], %[buf1]) + FIX_ENDIAN(20) + FIX_ENDIAN(21) + FIX_ENDIAN(22) + FIX_ENDIAN(23) + addi(%[buf1], %[buf1], 64) + vxor(20, 20, 28) + + /* + * Repack the blocks into v9, v10, v11 and v12. + * v9 = b0_0:b1_0 + * v10 = b0_1:b1_1 + * v11 = b2_0:b3_0 + * v12 = b2_1:b3_1 + */ + xxpermdi(41, 52, 53, 0) + xxpermdi(42, 52, 53, 3) + xxpermdi(43, 54, 55, 0) + xxpermdi(44, 54, 55, 3) + + /* + * Compute the products. + * v20 = b0_0*h4_0 + b1_0*h3_0 + * v21 = b0_1*h4_0 + b1_1*h3_0 + * v22 = b0_0*h4_1 + b1_0*h3_1 + * v23 = b0_1*h4_1 + b1_1*h3_1 + * v24 = b2_0*h2_0 + b3_0*h1_0 + * v25 = b2_1*h2_0 + b3_1*h1_0 + * v26 = b2_0*h2_1 + b3_0*h1_1 + * v27 = b2_1*h2_1 + b3_1*h1_1 + */ + vpmsumd(20, 13, 9) + vpmsumd(21, 13, 10) + vpmsumd(22, 14, 9) + vpmsumd(23, 14, 10) + vpmsumd(24, 15, 11) + vpmsumd(25, 15, 12) + vpmsumd(26, 16, 11) + vpmsumd(27, 16, 12) + + /* + * Sum products into a single 256-bit result in v11:v12. + */ + vxor(11, 20, 24) + vxor(12, 23, 27) + vxor( 9, 21, 22) + vxor(10, 25, 26) + vxor(20, 9, 10) + vsldoi( 9, HB0, 20, 8) + vsldoi(10, 20, HB0, 8) + vxor(11, 11, 9) + vxor(12, 12, 10) + + /* + * Fix and reduce in GF(2^128); this is the new y (in v28). + */ + SL_256(11, 12) + REDUCE_F128(28, 11, 12) + + /* + * Loop for next group of four blocks. + */ + bdnz(loop4) + + /* + * Process second chunk, one block at a time. + */ + label(chunk1) + cmpldi(%[num1], 0) + beq(done) + + mtctr(%[num1]) + label(loop1) + /* + * Load next data block and XOR it into y. + */ + lxvw4x(41, 0, %[buf2]) +#if BR_POWER8_LE + FIX_ENDIAN(9) +#endif + addi(%[buf2], %[buf2], 16) + vxor(9, 28, 9) + + /* + * Split y into doublewords: + * v9 = y_0:y_1 + * v10 = 0:y_0 + * v11 = y_1:0 + */ + vsldoi(10, HB0, 9, 8) + vsldoi(11, 9, HB0, 8) + + /* + * Compute products with h: + * v12 = y_0 * h_0 + * v13 = y_1 * h_1 + * v14 = y_1 * h_0 + y_0 * h_1 + */ + vpmsumd(14, 9, 17) + vpmsumd(12, 10, 18) + vpmsumd(13, 11, 19) + + /* + * Propagate v14 into v12:v13 to finalise product. + */ + vsldoi(10, HB0, 14, 8) + vsldoi(11, 14, HB0, 8) + vxor(12, 12, 10) + vxor(13, 13, 11) + + /* + * Fix result and reduce into v28 (next value for y). + */ + SL_256(12, 13) + REDUCE_F128(28, 12, 13) + bdnz(loop1) + + label(done) + /* + * Write back the new y. + */ + FIX_ENDIAN(28) + stxvw4x(60, 0, %[y]) + +: [buf1] "+b" (buf1), [buf2] "+b" (buf2) +: [y] "b" (y), [h] "b" (h), [num4] "b" (num4), [num1] "b" (num1), + [cc0] "b" (cc0), [cc1] "b" (cc1), [cc2] "b" (cc2), [cc3] "b" (cc3) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", + "ctr", "memory" + ); +} + +/* see bearssl_hash.h */ +br_ghash +br_ghash_pwr8_get(void) +{ + return &br_ghash_pwr8; +} + +#else + +/* see bearssl_hash.h */ +br_ghash +br_ghash_pwr8_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/hash/md5.c b/BearSSL-OG/libbearssl/src/hash/md5.c new file mode 100644 index 0000000..0df7abe --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/md5.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define F(B, C, D) ((((C) ^ (D)) & (B)) ^ (D)) +#define G(B, C, D) ((((C) ^ (B)) & (D)) ^ (C)) +#define H(B, C, D) ((B) ^ (C) ^ (D)) +#define I(B, C, D) ((C) ^ ((B) | ~(D))) + +#define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + +/* see inner.h */ +const uint32_t br_md5_IV[4] = { + 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476 +}; + +static const uint32_t K[64] = { + 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, + 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, + 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, + 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821, + + 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, + 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, + 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, + 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A, + + 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, + 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70, + 0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, + 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665, + + 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, + 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1, + 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1, + 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391 +}; + +static const unsigned char MP[48] = { + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 +}; + +/* see inner.h */ +void +br_md5_round(const unsigned char *buf, uint32_t *val) +{ + uint32_t m[16]; + uint32_t a, b, c, d; + int i; + + a = val[0]; + b = val[1]; + c = val[2]; + d = val[3]; + /* obsolete + for (i = 0; i < 16; i ++) { + m[i] = br_dec32le(buf + (i << 2)); + } + */ + br_range_dec32le(m, 16, buf); + + for (i = 0; i < 16; i += 4) { + a = b + ROTL(a + F(b, c, d) + m[i + 0] + K[i + 0], 7); + d = a + ROTL(d + F(a, b, c) + m[i + 1] + K[i + 1], 12); + c = d + ROTL(c + F(d, a, b) + m[i + 2] + K[i + 2], 17); + b = c + ROTL(b + F(c, d, a) + m[i + 3] + K[i + 3], 22); + } + for (i = 16; i < 32; i += 4) { + a = b + ROTL(a + G(b, c, d) + m[MP[i - 16]] + K[i + 0], 5); + d = a + ROTL(d + G(a, b, c) + m[MP[i - 15]] + K[i + 1], 9); + c = d + ROTL(c + G(d, a, b) + m[MP[i - 14]] + K[i + 2], 14); + b = c + ROTL(b + G(c, d, a) + m[MP[i - 13]] + K[i + 3], 20); + } + for (i = 32; i < 48; i += 4) { + a = b + ROTL(a + H(b, c, d) + m[MP[i - 16]] + K[i + 0], 4); + d = a + ROTL(d + H(a, b, c) + m[MP[i - 15]] + K[i + 1], 11); + c = d + ROTL(c + H(d, a, b) + m[MP[i - 14]] + K[i + 2], 16); + b = c + ROTL(b + H(c, d, a) + m[MP[i - 13]] + K[i + 3], 23); + } + for (i = 48; i < 64; i += 4) { + a = b + ROTL(a + I(b, c, d) + m[MP[i - 16]] + K[i + 0], 6); + d = a + ROTL(d + I(a, b, c) + m[MP[i - 15]] + K[i + 1], 10); + c = d + ROTL(c + I(d, a, b) + m[MP[i - 14]] + K[i + 2], 15); + b = c + ROTL(b + I(c, d, a) + m[MP[i - 13]] + K[i + 3], 21); + } + + val[0] += a; + val[1] += b; + val[2] += c; + val[3] += d; +} + +/* see bearssl.h */ +void +br_md5_init(br_md5_context *cc) +{ + cc->vtable = &br_md5_vtable; + memcpy(cc->val, br_md5_IV, sizeof cc->val); + cc->count = 0; +} + +/* see bearssl.h */ +void +br_md5_update(br_md5_context *cc, const void *data, size_t len) +{ + const unsigned char *buf; + size_t ptr; + + buf = data; + ptr = (size_t)cc->count & 63; + while (len > 0) { + size_t clen; + + clen = 64 - ptr; + if (clen > len) { + clen = len; + } + memcpy(cc->buf + ptr, buf, clen); + ptr += clen; + buf += clen; + len -= clen; + cc->count += (uint64_t)clen; + if (ptr == 64) { + br_md5_round(cc->buf, cc->val); + ptr = 0; + } + } +} + +/* see bearssl.h */ +void +br_md5_out(const br_md5_context *cc, void *dst) +{ + unsigned char buf[64]; + uint32_t val[4]; + size_t ptr; + + ptr = (size_t)cc->count & 63; + memcpy(buf, cc->buf, ptr); + memcpy(val, cc->val, sizeof val); + buf[ptr ++] = 0x80; + if (ptr > 56) { + memset(buf + ptr, 0, 64 - ptr); + br_md5_round(buf, val); + memset(buf, 0, 56); + } else { + memset(buf + ptr, 0, 56 - ptr); + } + br_enc64le(buf + 56, cc->count << 3); + br_md5_round(buf, val); + br_range_enc32le(dst, val, 4); +} + +/* see bearssl.h */ +uint64_t +br_md5_state(const br_md5_context *cc, void *dst) +{ + br_range_enc32le(dst, cc->val, 4); + return cc->count; +} + +/* see bearssl.h */ +void +br_md5_set_state(br_md5_context *cc, const void *stb, uint64_t count) +{ + br_range_dec32le(cc->val, 4, stb); + cc->count = count; +} + +/* see bearssl.h */ +const br_hash_class br_md5_vtable = { + sizeof(br_md5_context), + BR_HASHDESC_ID(br_md5_ID) + | BR_HASHDESC_OUT(16) + | BR_HASHDESC_STATE(16) + | BR_HASHDESC_LBLEN(6) + | BR_HASHDESC_MD_PADDING, + (void (*)(const br_hash_class **))&br_md5_init, + (void (*)(const br_hash_class **, const void *, size_t))&br_md5_update, + (void (*)(const br_hash_class *const *, void *))&br_md5_out, + (uint64_t (*)(const br_hash_class *const *, void *))&br_md5_state, + (void (*)(const br_hash_class **, const void *, uint64_t)) + &br_md5_set_state +}; diff --git a/BearSSL-OG/libbearssl/src/hash/md5sha1.c b/BearSSL-OG/libbearssl/src/hash/md5sha1.c new file mode 100644 index 0000000..f701aee --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/md5sha1.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl.h */ +void +br_md5sha1_init(br_md5sha1_context *cc) +{ + cc->vtable = &br_md5sha1_vtable; + memcpy(cc->val_md5, br_md5_IV, sizeof cc->val_md5); + memcpy(cc->val_sha1, br_sha1_IV, sizeof cc->val_sha1); + cc->count = 0; +} + +/* see bearssl.h */ +void +br_md5sha1_update(br_md5sha1_context *cc, const void *data, size_t len) +{ + const unsigned char *buf; + size_t ptr; + + buf = data; + ptr = (size_t)cc->count & 63; + while (len > 0) { + size_t clen; + + clen = 64 - ptr; + if (clen > len) { + clen = len; + } + memcpy(cc->buf + ptr, buf, clen); + ptr += clen; + buf += clen; + len -= clen; + cc->count += (uint64_t)clen; + if (ptr == 64) { + br_md5_round(cc->buf, cc->val_md5); + br_sha1_round(cc->buf, cc->val_sha1); + ptr = 0; + } + } +} + +/* see bearssl.h */ +void +br_md5sha1_out(const br_md5sha1_context *cc, void *dst) +{ + unsigned char buf[64]; + uint32_t val_md5[4]; + uint32_t val_sha1[5]; + size_t ptr; + unsigned char *out; + uint64_t count; + + count = cc->count; + ptr = (size_t)count & 63; + memcpy(buf, cc->buf, ptr); + memcpy(val_md5, cc->val_md5, sizeof val_md5); + memcpy(val_sha1, cc->val_sha1, sizeof val_sha1); + buf[ptr ++] = 0x80; + if (ptr > 56) { + memset(buf + ptr, 0, 64 - ptr); + br_md5_round(buf, val_md5); + br_sha1_round(buf, val_sha1); + memset(buf, 0, 56); + } else { + memset(buf + ptr, 0, 56 - ptr); + } + count <<= 3; + br_enc64le(buf + 56, count); + br_md5_round(buf, val_md5); + br_enc64be(buf + 56, count); + br_sha1_round(buf, val_sha1); + out = dst; + br_range_enc32le(out, val_md5, 4); + br_range_enc32be(out + 16, val_sha1, 5); +} + +/* see bearssl.h */ +uint64_t +br_md5sha1_state(const br_md5sha1_context *cc, void *dst) +{ + unsigned char *out; + + out = dst; + br_range_enc32le(out, cc->val_md5, 4); + br_range_enc32be(out + 16, cc->val_sha1, 5); + return cc->count; +} + +/* see bearssl.h */ +void +br_md5sha1_set_state(br_md5sha1_context *cc, const void *stb, uint64_t count) +{ + const unsigned char *buf; + + buf = stb; + br_range_dec32le(cc->val_md5, 4, buf); + br_range_dec32be(cc->val_sha1, 5, buf + 16); + cc->count = count; +} + +/* see bearssl.h */ +const br_hash_class br_md5sha1_vtable = { + sizeof(br_md5sha1_context), + BR_HASHDESC_ID(br_md5sha1_ID) + | BR_HASHDESC_OUT(36) + | BR_HASHDESC_STATE(36) + | BR_HASHDESC_LBLEN(6), + (void (*)(const br_hash_class **))&br_md5sha1_init, + (void (*)(const br_hash_class **, const void *, size_t)) + &br_md5sha1_update, + (void (*)(const br_hash_class *const *, void *)) + &br_md5sha1_out, + (uint64_t (*)(const br_hash_class *const *, void *)) + &br_md5sha1_state, + (void (*)(const br_hash_class **, const void *, uint64_t)) + &br_md5sha1_set_state +}; diff --git a/BearSSL-OG/libbearssl/src/hash/mgf1.c b/BearSSL-OG/libbearssl/src/hash/mgf1.c new file mode 100644 index 0000000..7a23588 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/mgf1.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_mgf1_xor(void *data, size_t len, + const br_hash_class *dig, const void *seed, size_t seed_len) +{ + unsigned char *buf; + size_t u, hlen; + uint32_t c; + + buf = data; + hlen = br_digest_size(dig); + for (u = 0, c = 0; u < len; u += hlen, c ++) { + br_hash_compat_context hc; + unsigned char tmp[64]; + size_t v; + + hc.vtable = dig; + dig->init(&hc.vtable); + dig->update(&hc.vtable, seed, seed_len); + br_enc32be(tmp, c); + dig->update(&hc.vtable, tmp, 4); + dig->out(&hc.vtable, tmp); + for (v = 0; v < hlen; v ++) { + if ((u + v) >= len) { + break; + } + buf[u + v] ^= tmp[v]; + } + } +} diff --git a/BearSSL-OG/libbearssl/src/hash/multihash.c b/BearSSL-OG/libbearssl/src/hash/multihash.c new file mode 100644 index 0000000..b6df2e0 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/multihash.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * An aggregate context that is large enough for all supported hash + * functions. + */ +typedef union { + const br_hash_class *vtable; + br_md5_context md5; + br_sha1_context sha1; + br_sha224_context sha224; + br_sha256_context sha256; + br_sha384_context sha384; + br_sha512_context sha512; +} gen_hash_context; + +/* + * Get the offset to the state for a specific hash function within the + * context structure. This shall be called only for the supported hash + * functions, + */ +static size_t +get_state_offset(int id) +{ + if (id >= 5) { + /* + * SHA-384 has id 5, and SHA-512 has id 6. Both use + * eight 64-bit words for their state. + */ + return offsetof(br_multihash_context, val_64) + + ((size_t)(id - 5) * (8 * sizeof(uint64_t))); + } else { + /* + * MD5 has id 1, SHA-1 has id 2, SHA-224 has id 3 and + * SHA-256 has id 4. They use 32-bit words for their + * states (4 words for MD5, 5 for SHA-1, 8 for SHA-224 + * and 8 for SHA-256). + */ + unsigned x; + + x = id - 1; + x = ((x + (x & (x >> 1))) << 2) + (x >> 1); + return offsetof(br_multihash_context, val_32) + + x * sizeof(uint32_t); + } +} + +/* see bearssl_hash.h */ +void +br_multihash_zero(br_multihash_context *ctx) +{ + /* + * This is not standard, but yields very short and efficient code, + * and it works "everywhere". + */ + memset(ctx, 0, sizeof *ctx); +} + +/* see bearssl_hash.h */ +void +br_multihash_init(br_multihash_context *ctx) +{ + int i; + + ctx->count = 0; + for (i = 1; i <= 6; i ++) { + const br_hash_class *hc; + + hc = ctx->impl[i - 1]; + if (hc != NULL) { + gen_hash_context g; + + hc->init(&g.vtable); + hc->state(&g.vtable, + (unsigned char *)ctx + get_state_offset(i)); + } + } +} + +/* see bearssl_hash.h */ +void +br_multihash_update(br_multihash_context *ctx, const void *data, size_t len) +{ + const unsigned char *buf; + size_t ptr; + + buf = data; + ptr = (size_t)ctx->count & 127; + while (len > 0) { + size_t clen; + + clen = 128 - ptr; + if (clen > len) { + clen = len; + } + memcpy(ctx->buf + ptr, buf, clen); + ptr += clen; + buf += clen; + len -= clen; + ctx->count += (uint64_t)clen; + if (ptr == 128) { + int i; + + for (i = 1; i <= 6; i ++) { + const br_hash_class *hc; + + hc = ctx->impl[i - 1]; + if (hc != NULL) { + gen_hash_context g; + unsigned char *state; + + state = (unsigned char *)ctx + + get_state_offset(i); + hc->set_state(&g.vtable, + state, ctx->count - 128); + hc->update(&g.vtable, ctx->buf, 128); + hc->state(&g.vtable, state); + } + } + ptr = 0; + } + } +} + +/* see bearssl_hash.h */ +size_t +br_multihash_out(const br_multihash_context *ctx, int id, void *dst) +{ + const br_hash_class *hc; + gen_hash_context g; + const unsigned char *state; + + hc = ctx->impl[id - 1]; + if (hc == NULL) { + return 0; + } + state = (const unsigned char *)ctx + get_state_offset(id); + hc->set_state(&g.vtable, state, ctx->count & ~(uint64_t)127); + hc->update(&g.vtable, ctx->buf, ctx->count & (uint64_t)127); + hc->out(&g.vtable, dst); + return (hc->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; +} diff --git a/BearSSL-OG/libbearssl/src/hash/sha1.c b/BearSSL-OG/libbearssl/src/hash/sha1.c new file mode 100644 index 0000000..4f65d84 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/sha1.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define F(B, C, D) ((((C) ^ (D)) & (B)) ^ (D)) +#define G(B, C, D) ((B) ^ (C) ^ (D)) +#define H(B, C, D) (((D) & (C)) | (((D) | (C)) & (B))) +#define I(B, C, D) G(B, C, D) + +#define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + +#define K1 ((uint32_t)0x5A827999) +#define K2 ((uint32_t)0x6ED9EBA1) +#define K3 ((uint32_t)0x8F1BBCDC) +#define K4 ((uint32_t)0xCA62C1D6) + +/* see inner.h */ +const uint32_t br_sha1_IV[5] = { + 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 +}; + +/* see inner.h */ +void +br_sha1_round(const unsigned char *buf, uint32_t *val) +{ + uint32_t m[80]; + uint32_t a, b, c, d, e; + int i; + + a = val[0]; + b = val[1]; + c = val[2]; + d = val[3]; + e = val[4]; + br_range_dec32be(m, 16, buf); + for (i = 16; i < 80; i ++) { + uint32_t x = m[i - 3] ^ m[i - 8] ^ m[i - 14] ^ m[i - 16]; + m[i] = ROTL(x, 1); + } + + for (i = 0; i < 20; i += 5) { + e += ROTL(a, 5) + F(b, c, d) + K1 + m[i + 0]; b = ROTL(b, 30); + d += ROTL(e, 5) + F(a, b, c) + K1 + m[i + 1]; a = ROTL(a, 30); + c += ROTL(d, 5) + F(e, a, b) + K1 + m[i + 2]; e = ROTL(e, 30); + b += ROTL(c, 5) + F(d, e, a) + K1 + m[i + 3]; d = ROTL(d, 30); + a += ROTL(b, 5) + F(c, d, e) + K1 + m[i + 4]; c = ROTL(c, 30); + } + for (i = 20; i < 40; i += 5) { + e += ROTL(a, 5) + G(b, c, d) + K2 + m[i + 0]; b = ROTL(b, 30); + d += ROTL(e, 5) + G(a, b, c) + K2 + m[i + 1]; a = ROTL(a, 30); + c += ROTL(d, 5) + G(e, a, b) + K2 + m[i + 2]; e = ROTL(e, 30); + b += ROTL(c, 5) + G(d, e, a) + K2 + m[i + 3]; d = ROTL(d, 30); + a += ROTL(b, 5) + G(c, d, e) + K2 + m[i + 4]; c = ROTL(c, 30); + } + for (i = 40; i < 60; i += 5) { + e += ROTL(a, 5) + H(b, c, d) + K3 + m[i + 0]; b = ROTL(b, 30); + d += ROTL(e, 5) + H(a, b, c) + K3 + m[i + 1]; a = ROTL(a, 30); + c += ROTL(d, 5) + H(e, a, b) + K3 + m[i + 2]; e = ROTL(e, 30); + b += ROTL(c, 5) + H(d, e, a) + K3 + m[i + 3]; d = ROTL(d, 30); + a += ROTL(b, 5) + H(c, d, e) + K3 + m[i + 4]; c = ROTL(c, 30); + } + for (i = 60; i < 80; i += 5) { + e += ROTL(a, 5) + I(b, c, d) + K4 + m[i + 0]; b = ROTL(b, 30); + d += ROTL(e, 5) + I(a, b, c) + K4 + m[i + 1]; a = ROTL(a, 30); + c += ROTL(d, 5) + I(e, a, b) + K4 + m[i + 2]; e = ROTL(e, 30); + b += ROTL(c, 5) + I(d, e, a) + K4 + m[i + 3]; d = ROTL(d, 30); + a += ROTL(b, 5) + I(c, d, e) + K4 + m[i + 4]; c = ROTL(c, 30); + } + + val[0] += a; + val[1] += b; + val[2] += c; + val[3] += d; + val[4] += e; +} + +/* see bearssl.h */ +void +br_sha1_init(br_sha1_context *cc) +{ + cc->vtable = &br_sha1_vtable; + memcpy(cc->val, br_sha1_IV, sizeof cc->val); + cc->count = 0; +} + +/* see bearssl.h */ +void +br_sha1_update(br_sha1_context *cc, const void *data, size_t len) +{ + const unsigned char *buf; + size_t ptr; + + buf = data; + ptr = (size_t)cc->count & 63; + while (len > 0) { + size_t clen; + + clen = 64 - ptr; + if (clen > len) { + clen = len; + } + memcpy(cc->buf + ptr, buf, clen); + ptr += clen; + buf += clen; + len -= clen; + cc->count += (uint64_t)clen; + if (ptr == 64) { + br_sha1_round(cc->buf, cc->val); + ptr = 0; + } + } +} + +/* see bearssl.h */ +void +br_sha1_out(const br_sha1_context *cc, void *dst) +{ + unsigned char buf[64]; + uint32_t val[5]; + size_t ptr; + + ptr = (size_t)cc->count & 63; + memcpy(buf, cc->buf, ptr); + memcpy(val, cc->val, sizeof val); + buf[ptr ++] = 0x80; + if (ptr > 56) { + memset(buf + ptr, 0, 64 - ptr); + br_sha1_round(buf, val); + memset(buf, 0, 56); + } else { + memset(buf + ptr, 0, 56 - ptr); + } + br_enc64be(buf + 56, cc->count << 3); + br_sha1_round(buf, val); + br_range_enc32be(dst, val, 5); +} + +/* see bearssl.h */ +uint64_t +br_sha1_state(const br_sha1_context *cc, void *dst) +{ + br_range_enc32be(dst, cc->val, 5); + return cc->count; +} + +/* see bearssl.h */ +void +br_sha1_set_state(br_sha1_context *cc, const void *stb, uint64_t count) +{ + br_range_dec32be(cc->val, 5, stb); + cc->count = count; +} + +/* see bearssl.h */ +const br_hash_class br_sha1_vtable = { + sizeof(br_sha1_context), + BR_HASHDESC_ID(br_sha1_ID) + | BR_HASHDESC_OUT(20) + | BR_HASHDESC_STATE(20) + | BR_HASHDESC_LBLEN(6) + | BR_HASHDESC_MD_PADDING + | BR_HASHDESC_MD_PADDING_BE, + (void (*)(const br_hash_class **))&br_sha1_init, + (void (*)(const br_hash_class **, const void *, size_t))&br_sha1_update, + (void (*)(const br_hash_class *const *, void *))&br_sha1_out, + (uint64_t (*)(const br_hash_class *const *, void *))&br_sha1_state, + (void (*)(const br_hash_class **, const void *, uint64_t)) + &br_sha1_set_state +}; diff --git a/BearSSL-OG/libbearssl/src/hash/sha2big.c b/BearSSL-OG/libbearssl/src/hash/sha2big.c new file mode 100644 index 0000000..5be92ed --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/sha2big.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define CH(X, Y, Z) ((((Y) ^ (Z)) & (X)) ^ (Z)) +#define MAJ(X, Y, Z) (((Y) & (Z)) | (((Y) | (Z)) & (X))) + +#define ROTR(x, n) (((uint64_t)(x) << (64 - (n))) | ((uint64_t)(x) >> (n))) + +#define BSG5_0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) +#define BSG5_1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) +#define SSG5_0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ (uint64_t)((x) >> 7)) +#define SSG5_1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ (uint64_t)((x) >> 6)) + +static const uint64_t IV384[8] = { + 0xCBBB9D5DC1059ED8, 0x629A292A367CD507, + 0x9159015A3070DD17, 0x152FECD8F70E5939, + 0x67332667FFC00B31, 0x8EB44A8768581511, + 0xDB0C2E0D64F98FA7, 0x47B5481DBEFA4FA4 +}; + +static const uint64_t IV512[8] = { + 0x6A09E667F3BCC908, 0xBB67AE8584CAA73B, + 0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1, + 0x510E527FADE682D1, 0x9B05688C2B3E6C1F, + 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179 +}; + +static const uint64_t K[80] = { + 0x428A2F98D728AE22, 0x7137449123EF65CD, + 0xB5C0FBCFEC4D3B2F, 0xE9B5DBA58189DBBC, + 0x3956C25BF348B538, 0x59F111F1B605D019, + 0x923F82A4AF194F9B, 0xAB1C5ED5DA6D8118, + 0xD807AA98A3030242, 0x12835B0145706FBE, + 0x243185BE4EE4B28C, 0x550C7DC3D5FFB4E2, + 0x72BE5D74F27B896F, 0x80DEB1FE3B1696B1, + 0x9BDC06A725C71235, 0xC19BF174CF692694, + 0xE49B69C19EF14AD2, 0xEFBE4786384F25E3, + 0x0FC19DC68B8CD5B5, 0x240CA1CC77AC9C65, + 0x2DE92C6F592B0275, 0x4A7484AA6EA6E483, + 0x5CB0A9DCBD41FBD4, 0x76F988DA831153B5, + 0x983E5152EE66DFAB, 0xA831C66D2DB43210, + 0xB00327C898FB213F, 0xBF597FC7BEEF0EE4, + 0xC6E00BF33DA88FC2, 0xD5A79147930AA725, + 0x06CA6351E003826F, 0x142929670A0E6E70, + 0x27B70A8546D22FFC, 0x2E1B21385C26C926, + 0x4D2C6DFC5AC42AED, 0x53380D139D95B3DF, + 0x650A73548BAF63DE, 0x766A0ABB3C77B2A8, + 0x81C2C92E47EDAEE6, 0x92722C851482353B, + 0xA2BFE8A14CF10364, 0xA81A664BBC423001, + 0xC24B8B70D0F89791, 0xC76C51A30654BE30, + 0xD192E819D6EF5218, 0xD69906245565A910, + 0xF40E35855771202A, 0x106AA07032BBD1B8, + 0x19A4C116B8D2D0C8, 0x1E376C085141AB53, + 0x2748774CDF8EEB99, 0x34B0BCB5E19B48A8, + 0x391C0CB3C5C95A63, 0x4ED8AA4AE3418ACB, + 0x5B9CCA4F7763E373, 0x682E6FF3D6B2B8A3, + 0x748F82EE5DEFB2FC, 0x78A5636F43172F60, + 0x84C87814A1F0AB72, 0x8CC702081A6439EC, + 0x90BEFFFA23631E28, 0xA4506CEBDE82BDE9, + 0xBEF9A3F7B2C67915, 0xC67178F2E372532B, + 0xCA273ECEEA26619C, 0xD186B8C721C0C207, + 0xEADA7DD6CDE0EB1E, 0xF57D4F7FEE6ED178, + 0x06F067AA72176FBA, 0x0A637DC5A2C898A6, + 0x113F9804BEF90DAE, 0x1B710B35131C471B, + 0x28DB77F523047D84, 0x32CAAB7B40C72493, + 0x3C9EBE0A15C9BEBC, 0x431D67C49C100D4C, + 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, + 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817 +}; + +static void +sha2big_round(const unsigned char *buf, uint64_t *val) +{ + +#define SHA2BIG_STEP(A, B, C, D, E, F, G, H, j) do { \ + uint64_t T1, T2; \ + T1 = H + BSG5_1(E) + CH(E, F, G) + K[j] + w[j]; \ + T2 = BSG5_0(A) + MAJ(A, B, C); \ + D += T1; \ + H = T1 + T2; \ + } while (0) + + int i; + uint64_t a, b, c, d, e, f, g, h; + uint64_t w[80]; + + br_range_dec64be(w, 16, buf); + for (i = 16; i < 80; i ++) { + w[i] = SSG5_1(w[i - 2]) + w[i - 7] + + SSG5_0(w[i - 15]) + w[i - 16]; + } + a = val[0]; + b = val[1]; + c = val[2]; + d = val[3]; + e = val[4]; + f = val[5]; + g = val[6]; + h = val[7]; + for (i = 0; i < 80; i += 8) { + SHA2BIG_STEP(a, b, c, d, e, f, g, h, i + 0); + SHA2BIG_STEP(h, a, b, c, d, e, f, g, i + 1); + SHA2BIG_STEP(g, h, a, b, c, d, e, f, i + 2); + SHA2BIG_STEP(f, g, h, a, b, c, d, e, i + 3); + SHA2BIG_STEP(e, f, g, h, a, b, c, d, i + 4); + SHA2BIG_STEP(d, e, f, g, h, a, b, c, i + 5); + SHA2BIG_STEP(c, d, e, f, g, h, a, b, i + 6); + SHA2BIG_STEP(b, c, d, e, f, g, h, a, i + 7); + } + val[0] += a; + val[1] += b; + val[2] += c; + val[3] += d; + val[4] += e; + val[5] += f; + val[6] += g; + val[7] += h; +} + +static void +sha2big_update(br_sha384_context *cc, const void *data, size_t len) +{ + const unsigned char *buf; + size_t ptr; + + buf = data; + ptr = (size_t)cc->count & 127; + cc->count += (uint64_t)len; + while (len > 0) { + size_t clen; + + clen = 128 - ptr; + if (clen > len) { + clen = len; + } + memcpy(cc->buf + ptr, buf, clen); + ptr += clen; + buf += clen; + len -= clen; + if (ptr == 128) { + sha2big_round(cc->buf, cc->val); + ptr = 0; + } + } +} + +static void +sha2big_out(const br_sha384_context *cc, void *dst, int num) +{ + unsigned char buf[128]; + uint64_t val[8]; + size_t ptr; + + ptr = (size_t)cc->count & 127; + memcpy(buf, cc->buf, ptr); + memcpy(val, cc->val, sizeof val); + buf[ptr ++] = 0x80; + if (ptr > 112) { + memset(buf + ptr, 0, 128 - ptr); + sha2big_round(buf, val); + memset(buf, 0, 112); + } else { + memset(buf + ptr, 0, 112 - ptr); + } + br_enc64be(buf + 112, cc->count >> 61); + br_enc64be(buf + 120, cc->count << 3); + sha2big_round(buf, val); + br_range_enc64be(dst, val, num); +} + +/* see bearssl.h */ +void +br_sha384_init(br_sha384_context *cc) +{ + cc->vtable = &br_sha384_vtable; + memcpy(cc->val, IV384, sizeof IV384); + cc->count = 0; +} + +/* see bearssl.h */ +void +br_sha384_update(br_sha384_context *cc, const void *data, size_t len) +{ + sha2big_update(cc, data, len); +} + +/* see bearssl.h */ +void +br_sha384_out(const br_sha384_context *cc, void *dst) +{ + sha2big_out(cc, dst, 6); +} + +/* see bearssl.h */ +uint64_t +br_sha384_state(const br_sha384_context *cc, void *dst) +{ + br_range_enc64be(dst, cc->val, 8); + return cc->count; +} + +/* see bearssl.h */ +void +br_sha384_set_state(br_sha384_context *cc, const void *stb, uint64_t count) +{ + br_range_dec64be(cc->val, 8, stb); + cc->count = count; +} + +/* see bearssl.h */ +void +br_sha512_init(br_sha512_context *cc) +{ + cc->vtable = &br_sha512_vtable; + memcpy(cc->val, IV512, sizeof IV512); + cc->count = 0; +} + +/* see bearssl.h */ +void +br_sha512_out(const br_sha512_context *cc, void *dst) +{ + sha2big_out(cc, dst, 8); +} + +/* see bearssl.h */ +const br_hash_class br_sha384_vtable = { + sizeof(br_sha384_context), + BR_HASHDESC_ID(br_sha384_ID) + | BR_HASHDESC_OUT(48) + | BR_HASHDESC_STATE(64) + | BR_HASHDESC_LBLEN(7) + | BR_HASHDESC_MD_PADDING + | BR_HASHDESC_MD_PADDING_BE + | BR_HASHDESC_MD_PADDING_128, + (void (*)(const br_hash_class **))&br_sha384_init, + (void (*)(const br_hash_class **, const void *, size_t)) + &br_sha384_update, + (void (*)(const br_hash_class *const *, void *))&br_sha384_out, + (uint64_t (*)(const br_hash_class *const *, void *))&br_sha384_state, + (void (*)(const br_hash_class **, const void *, uint64_t)) + &br_sha384_set_state +}; + +/* see bearssl.h */ +const br_hash_class br_sha512_vtable = { + sizeof(br_sha512_context), + BR_HASHDESC_ID(br_sha512_ID) + | BR_HASHDESC_OUT(64) + | BR_HASHDESC_STATE(64) + | BR_HASHDESC_LBLEN(7) + | BR_HASHDESC_MD_PADDING + | BR_HASHDESC_MD_PADDING_BE + | BR_HASHDESC_MD_PADDING_128, + (void (*)(const br_hash_class **))&br_sha512_init, + (void (*)(const br_hash_class **, const void *, size_t)) + &br_sha512_update, + (void (*)(const br_hash_class *const *, void *))&br_sha512_out, + (uint64_t (*)(const br_hash_class *const *, void *))&br_sha512_state, + (void (*)(const br_hash_class **, const void *, uint64_t)) + &br_sha512_set_state +}; diff --git a/BearSSL-OG/libbearssl/src/hash/sha2small.c b/BearSSL-OG/libbearssl/src/hash/sha2small.c new file mode 100644 index 0000000..ca19655 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/hash/sha2small.c @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define CH(X, Y, Z) ((((Y) ^ (Z)) & (X)) ^ (Z)) +#define MAJ(X, Y, Z) (((Y) & (Z)) | (((Y) | (Z)) & (X))) + +#define ROTR(x, n) (((uint32_t)(x) << (32 - (n))) | ((uint32_t)(x) >> (n))) + +#define BSG2_0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define BSG2_1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define SSG2_0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ (uint32_t)((x) >> 3)) +#define SSG2_1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ (uint32_t)((x) >> 10)) + +/* see inner.h */ +const uint32_t br_sha224_IV[8] = { + 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, + 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4 +}; + +/* see inner.h */ +const uint32_t br_sha256_IV[8] = { + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 +}; + +static const uint32_t K[64] = { + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 +}; + +/* see inner.h */ +void +br_sha2small_round(const unsigned char *buf, uint32_t *val) +{ + +#define SHA2_STEP(A, B, C, D, E, F, G, H, j) do { \ + uint32_t T1, T2; \ + T1 = H + BSG2_1(E) + CH(E, F, G) + K[j] + w[j]; \ + T2 = BSG2_0(A) + MAJ(A, B, C); \ + D += T1; \ + H = T1 + T2; \ + } while (0) + + int i; + uint32_t a, b, c, d, e, f, g, h; + uint32_t w[64]; + + br_range_dec32be(w, 16, buf); + for (i = 16; i < 64; i ++) { + w[i] = SSG2_1(w[i - 2]) + w[i - 7] + + SSG2_0(w[i - 15]) + w[i - 16]; + } + a = val[0]; + b = val[1]; + c = val[2]; + d = val[3]; + e = val[4]; + f = val[5]; + g = val[6]; + h = val[7]; + for (i = 0; i < 64; i += 8) { + SHA2_STEP(a, b, c, d, e, f, g, h, i + 0); + SHA2_STEP(h, a, b, c, d, e, f, g, i + 1); + SHA2_STEP(g, h, a, b, c, d, e, f, i + 2); + SHA2_STEP(f, g, h, a, b, c, d, e, i + 3); + SHA2_STEP(e, f, g, h, a, b, c, d, i + 4); + SHA2_STEP(d, e, f, g, h, a, b, c, i + 5); + SHA2_STEP(c, d, e, f, g, h, a, b, i + 6); + SHA2_STEP(b, c, d, e, f, g, h, a, i + 7); + } + val[0] += a; + val[1] += b; + val[2] += c; + val[3] += d; + val[4] += e; + val[5] += f; + val[6] += g; + val[7] += h; + +#if 0 +/* obsolete */ +#define SHA2_MEXP1(pc) do { \ + W[pc] = br_dec32be(buf + ((pc) << 2)); \ + } while (0) + +#define SHA2_MEXP2(pc) do { \ + W[(pc) & 0x0F] = SSG2_1(W[((pc) - 2) & 0x0F]) \ + + W[((pc) - 7) & 0x0F] \ + + SSG2_0(W[((pc) - 15) & 0x0F]) + W[(pc) & 0x0F]; \ + } while (0) + +#define SHA2_STEPn(n, a, b, c, d, e, f, g, h, pc) do { \ + uint32_t t1, t2; \ + SHA2_MEXP ## n(pc); \ + t1 = h + BSG2_1(e) + CH(e, f, g) \ + + K[pcount + (pc)] + W[(pc) & 0x0F]; \ + t2 = BSG2_0(a) + MAJ(a, b, c); \ + d += t1; \ + h = t1 + t2; \ + } while (0) + +#define SHA2_STEP1(a, b, c, d, e, f, g, h, pc) \ + SHA2_STEPn(1, a, b, c, d, e, f, g, h, pc) +#define SHA2_STEP2(a, b, c, d, e, f, g, h, pc) \ + SHA2_STEPn(2, a, b, c, d, e, f, g, h, pc) + + uint32_t A, B, C, D, E, F, G, H; + uint32_t W[16]; + unsigned pcount; + + A = val[0]; + B = val[1]; + C = val[2]; + D = val[3]; + E = val[4]; + F = val[5]; + G = val[6]; + H = val[7]; + pcount = 0; + SHA2_STEP1(A, B, C, D, E, F, G, H, 0); + SHA2_STEP1(H, A, B, C, D, E, F, G, 1); + SHA2_STEP1(G, H, A, B, C, D, E, F, 2); + SHA2_STEP1(F, G, H, A, B, C, D, E, 3); + SHA2_STEP1(E, F, G, H, A, B, C, D, 4); + SHA2_STEP1(D, E, F, G, H, A, B, C, 5); + SHA2_STEP1(C, D, E, F, G, H, A, B, 6); + SHA2_STEP1(B, C, D, E, F, G, H, A, 7); + SHA2_STEP1(A, B, C, D, E, F, G, H, 8); + SHA2_STEP1(H, A, B, C, D, E, F, G, 9); + SHA2_STEP1(G, H, A, B, C, D, E, F, 10); + SHA2_STEP1(F, G, H, A, B, C, D, E, 11); + SHA2_STEP1(E, F, G, H, A, B, C, D, 12); + SHA2_STEP1(D, E, F, G, H, A, B, C, 13); + SHA2_STEP1(C, D, E, F, G, H, A, B, 14); + SHA2_STEP1(B, C, D, E, F, G, H, A, 15); + for (pcount = 16; pcount < 64; pcount += 16) { + SHA2_STEP2(A, B, C, D, E, F, G, H, 0); + SHA2_STEP2(H, A, B, C, D, E, F, G, 1); + SHA2_STEP2(G, H, A, B, C, D, E, F, 2); + SHA2_STEP2(F, G, H, A, B, C, D, E, 3); + SHA2_STEP2(E, F, G, H, A, B, C, D, 4); + SHA2_STEP2(D, E, F, G, H, A, B, C, 5); + SHA2_STEP2(C, D, E, F, G, H, A, B, 6); + SHA2_STEP2(B, C, D, E, F, G, H, A, 7); + SHA2_STEP2(A, B, C, D, E, F, G, H, 8); + SHA2_STEP2(H, A, B, C, D, E, F, G, 9); + SHA2_STEP2(G, H, A, B, C, D, E, F, 10); + SHA2_STEP2(F, G, H, A, B, C, D, E, 11); + SHA2_STEP2(E, F, G, H, A, B, C, D, 12); + SHA2_STEP2(D, E, F, G, H, A, B, C, 13); + SHA2_STEP2(C, D, E, F, G, H, A, B, 14); + SHA2_STEP2(B, C, D, E, F, G, H, A, 15); + } + val[0] += A; + val[1] += B; + val[2] += C; + val[3] += D; + val[4] += E; + val[5] += F; + val[6] += G; + val[7] += H; +#endif +} + +static void +sha2small_update(br_sha224_context *cc, const void *data, size_t len) +{ + const unsigned char *buf; + size_t ptr; + + buf = data; + ptr = (size_t)cc->count & 63; + cc->count += (uint64_t)len; + while (len > 0) { + size_t clen; + + clen = 64 - ptr; + if (clen > len) { + clen = len; + } + memcpy(cc->buf + ptr, buf, clen); + ptr += clen; + buf += clen; + len -= clen; + if (ptr == 64) { + br_sha2small_round(cc->buf, cc->val); + ptr = 0; + } + } +} + +static void +sha2small_out(const br_sha224_context *cc, void *dst, int num) +{ + unsigned char buf[64]; + uint32_t val[8]; + size_t ptr; + + ptr = (size_t)cc->count & 63; + memcpy(buf, cc->buf, ptr); + memcpy(val, cc->val, sizeof val); + buf[ptr ++] = 0x80; + if (ptr > 56) { + memset(buf + ptr, 0, 64 - ptr); + br_sha2small_round(buf, val); + memset(buf, 0, 56); + } else { + memset(buf + ptr, 0, 56 - ptr); + } + br_enc64be(buf + 56, cc->count << 3); + br_sha2small_round(buf, val); + br_range_enc32be(dst, val, num); +} + +/* see bearssl.h */ +void +br_sha224_init(br_sha224_context *cc) +{ + cc->vtable = &br_sha224_vtable; + memcpy(cc->val, br_sha224_IV, sizeof cc->val); + cc->count = 0; +} + +/* see bearssl.h */ +void +br_sha224_update(br_sha224_context *cc, const void *data, size_t len) +{ + sha2small_update(cc, data, len); +} + +/* see bearssl.h */ +void +br_sha224_out(const br_sha224_context *cc, void *dst) +{ + sha2small_out(cc, dst, 7); +} + +/* see bearssl.h */ +uint64_t +br_sha224_state(const br_sha224_context *cc, void *dst) +{ + br_range_enc32be(dst, cc->val, 8); + return cc->count; +} + +/* see bearssl.h */ +void +br_sha224_set_state(br_sha224_context *cc, const void *stb, uint64_t count) +{ + br_range_dec32be(cc->val, 8, stb); + cc->count = count; +} + +/* see bearssl.h */ +void +br_sha256_init(br_sha256_context *cc) +{ + cc->vtable = &br_sha256_vtable; + memcpy(cc->val, br_sha256_IV, sizeof cc->val); + cc->count = 0; +} + +/* see bearssl.h */ +void +br_sha256_out(const br_sha256_context *cc, void *dst) +{ + sha2small_out(cc, dst, 8); +} + +/* see bearssl.h */ +const br_hash_class br_sha224_vtable = { + sizeof(br_sha224_context), + BR_HASHDESC_ID(br_sha224_ID) + | BR_HASHDESC_OUT(28) + | BR_HASHDESC_STATE(32) + | BR_HASHDESC_LBLEN(6) + | BR_HASHDESC_MD_PADDING + | BR_HASHDESC_MD_PADDING_BE, + (void (*)(const br_hash_class **))&br_sha224_init, + (void (*)(const br_hash_class **, + const void *, size_t))&br_sha224_update, + (void (*)(const br_hash_class *const *, void *))&br_sha224_out, + (uint64_t (*)(const br_hash_class *const *, void *))&br_sha224_state, + (void (*)(const br_hash_class **, const void *, uint64_t)) + &br_sha224_set_state +}; + +/* see bearssl.h */ +const br_hash_class br_sha256_vtable = { + sizeof(br_sha256_context), + BR_HASHDESC_ID(br_sha256_ID) + | BR_HASHDESC_OUT(32) + | BR_HASHDESC_STATE(32) + | BR_HASHDESC_LBLEN(6) + | BR_HASHDESC_MD_PADDING + | BR_HASHDESC_MD_PADDING_BE, + (void (*)(const br_hash_class **))&br_sha256_init, + (void (*)(const br_hash_class **, + const void *, size_t))&br_sha256_update, + (void (*)(const br_hash_class *const *, void *))&br_sha256_out, + (uint64_t (*)(const br_hash_class *const *, void *))&br_sha256_state, + (void (*)(const br_hash_class **, const void *, uint64_t)) + &br_sha256_set_state +}; diff --git a/BearSSL-OG/libbearssl/src/inner.h b/BearSSL-OG/libbearssl/src/inner.h new file mode 100644 index 0000000..acb5b9a --- /dev/null +++ b/BearSSL-OG/libbearssl/src/inner.h @@ -0,0 +1,2584 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef INNER_H__ +#define INNER_H__ + +#include +#include + +#include "config.h" +#include "bearssl.h" + +/* + * On MSVC, disable the warning about applying unary minus on an + * unsigned type: it is standard, we do it all the time, and for + * good reasons. + */ +#if _MSC_VER +#pragma warning( disable : 4146 ) +#endif + +/* + * Maximum size for a RSA modulus (in bits). Allocated stack buffers + * depend on that size, so this value should be kept small. Currently, + * 2048-bit RSA keys offer adequate security, and should still do so for + * the next few decades; however, a number of widespread PKI have + * already set their root keys to RSA-4096, so we should be able to + * process such keys. + * + * This value MUST be a multiple of 64. This value MUST NOT exceed 47666 + * (some computations in RSA key generation rely on the factor size being + * no more than 23833 bits). RSA key sizes beyond 3072 bits don't make a + * lot of sense anyway. + */ +#define BR_MAX_RSA_SIZE 4096 + +/* + * Minimum size for a RSA modulus (in bits); this value is used only to + * filter out invalid parameters for key pair generation. Normally, + * applications should not use RSA keys smaller than 2048 bits; but some + * specific cases might need shorter keys, for legacy or research + * purposes. + */ +#define BR_MIN_RSA_SIZE 512 + +/* + * Maximum size for a RSA factor (in bits). This is for RSA private-key + * operations. Default is to support factors up to a bit more than half + * the maximum modulus size. + * + * This value MUST be a multiple of 32. + */ +#define BR_MAX_RSA_FACTOR ((BR_MAX_RSA_SIZE + 64) >> 1) + +/* + * Maximum size for an EC curve (modulus or order), in bits. Size of + * stack buffers depends on that parameter. This size MUST be a multiple + * of 8 (so that decoding an integer with that many bytes does not + * overflow). + */ +#define BR_MAX_EC_SIZE 528 + +/* + * Some macros to recognize the current architecture. Right now, we are + * interested into automatically recognizing architecture with efficient + * 64-bit types so that we may automatically use implementations that + * use 64-bit registers in that case. Future versions may detect, e.g., + * availability of SSE2 intrinsics. + * + * If 'unsigned long' is a 64-bit type, then we assume that 64-bit types + * are efficient. Otherwise, we rely on macros that depend on compiler, + * OS and architecture. In any case, failure to detect the architecture + * as 64-bit means that the 32-bit code will be used, and that code + * works also on 64-bit architectures (the 64-bit code may simply be + * more efficient). + * + * The test on 'unsigned long' should already catch most cases, the one + * notable exception being Windows code where 'unsigned long' is kept to + * 32-bit for compatibility with all the legacy code that liberally uses + * the 'DWORD' type for 32-bit values. + * + * Macro names are taken from: http://nadeausoftware.com/articles/2012/02/c_c_tip_how_detect_processor_type_using_compiler_predefined_macros + */ +#ifndef BR_64 +#if ((ULONG_MAX >> 31) >> 31) == 3 +#define BR_64 1 +#elif defined(__ia64) || defined(__itanium__) || defined(_M_IA64) +#define BR_64 1 +#elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) \ + || defined(__64BIT__) || defined(_LP64) || defined(__LP64__) +#define BR_64 1 +#elif defined(__sparc64__) +#define BR_64 1 +#elif defined(__x86_64__) || defined(_M_X64) +#define BR_64 1 +#elif defined(__aarch64__) || defined(_M_ARM64) +#define BR_64 1 +#elif defined(__mips64) +#define BR_64 1 +#endif +#endif + +/* + * Set BR_LOMUL on platforms where it makes sense. + */ +#ifndef BR_LOMUL +#if BR_ARMEL_CORTEXM_GCC +#define BR_LOMUL 1 +#endif +#endif + +/* + * Architecture detection. + */ +#ifndef BR_i386 +#if __i386__ || _M_IX86 +#define BR_i386 1 +#endif +#endif + +#ifndef BR_amd64 +#if __x86_64__ || _M_X64 +#define BR_amd64 1 +#endif +#endif + +/* + * Compiler brand and version. + * + * Implementations that use intrinsics need to detect the compiler type + * and version because some specific actions may be needed to activate + * the corresponding opcodes, both for header inclusion, and when using + * them in a function. + * + * BR_GCC, BR_CLANG and BR_MSC will be set to 1 for, respectively, GCC, + * Clang and MS Visual C. For each of them, sub-macros will be defined + * for versions; each sub-macro is set whenever the compiler version is + * at least as recent as the one corresponding to the macro. + */ + +/* + * GCC thresholds are on versions 4.4 to 4.9 and 5.0. + */ +#ifndef BR_GCC +#if __GNUC__ && !__clang__ +#define BR_GCC 1 + +#if __GNUC__ > 4 +#define BR_GCC_5_0 1 +#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 9 +#define BR_GCC_4_9 1 +#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 8 +#define BR_GCC_4_8 1 +#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 7 +#define BR_GCC_4_7 1 +#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 6 +#define BR_GCC_4_6 1 +#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 5 +#define BR_GCC_4_5 1 +#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 4 +#define BR_GCC_4_4 1 +#endif + +#if BR_GCC_5_0 +#define BR_GCC_4_9 1 +#endif +#if BR_GCC_4_9 +#define BR_GCC_4_8 1 +#endif +#if BR_GCC_4_8 +#define BR_GCC_4_7 1 +#endif +#if BR_GCC_4_7 +#define BR_GCC_4_6 1 +#endif +#if BR_GCC_4_6 +#define BR_GCC_4_5 1 +#endif +#if BR_GCC_4_5 +#define BR_GCC_4_4 1 +#endif + +#endif +#endif + +/* + * Clang thresholds are on versions 3.7.0 and 3.8.0. + */ +#ifndef BR_CLANG +#if __clang__ +#define BR_CLANG 1 + +#if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 8) +#define BR_CLANG_3_8 1 +#elif __clang_major__ == 3 && __clang_minor__ >= 7 +#define BR_CLANG_3_7 1 +#endif + +#if BR_CLANG_3_8 +#define BR_CLANG_3_7 1 +#endif + +#endif +#endif + +/* + * MS Visual C thresholds are on Visual Studio 2005 to 2015. + */ +#ifndef BR_MSC +#if _MSC_VER && !defined(_XBOX) +#define BR_MSC 1 + +#if _MSC_VER >= 1900 +#define BR_MSC_2015 1 +#elif _MSC_VER >= 1800 +#define BR_MSC_2013 1 +#elif _MSC_VER >= 1700 +#define BR_MSC_2012 1 +#elif _MSC_VER >= 1600 +#define BR_MSC_2010 1 +#elif _MSC_VER >= 1500 +#define BR_MSC_2008 1 +#elif _MSC_VER >= 1400 +#define BR_MSC_2005 1 +#endif + +#if BR_MSC_2015 +#define BR_MSC_2013 1 +#endif +#if BR_MSC_2013 +#define BR_MSC_2012 1 +#endif +#if BR_MSC_2012 +#define BR_MSC_2010 1 +#endif +#if BR_MSC_2010 +#define BR_MSC_2008 1 +#endif +#if BR_MSC_2008 +#define BR_MSC_2005 1 +#endif + +#endif +#endif + +/* + * GCC 4.4+ and Clang 3.7+ allow tagging specific functions with a + * 'target' attribute that activates support for specific opcodes. + */ +#if BR_GCC_4_4 || BR_CLANG_3_7 +#define BR_TARGET(x) __attribute__((target(x))) +#else +#define BR_TARGET(x) +#endif + +/* + * AES-NI intrinsics are available on x86 (32-bit and 64-bit) with + * GCC 4.8+, Clang 3.7+ and MSC 2012+. + */ +#ifndef BR_AES_X86NI +#if (BR_i386 || BR_amd64) && (BR_GCC_4_8 || BR_CLANG_3_7 || BR_MSC_2012) +#define BR_AES_X86NI 1 +#endif +#endif + +/* + * SSE2 intrinsics are available on x86 (32-bit and 64-bit) with + * GCC 4.4+, Clang 3.7+ and MSC 2005+. + */ +#ifndef BR_SSE2 +#if (BR_i386 || BR_amd64) && (BR_GCC_4_4 || BR_CLANG_3_7 || BR_MSC_2005) +#define BR_SSE2 1 +#endif +#endif + +/* + * RDRAND intrinsics are available on x86 (32-bit and 64-bit) with + * GCC 4.6+, Clang 3.7+ and MSC 2012+. + */ +#ifndef BR_RDRAND +#if (BR_i386 || BR_amd64) && (BR_GCC_4_6 || BR_CLANG_3_7 || BR_MSC_2012) +#define BR_RDRAND 1 +#endif +#endif + +/* + * Determine type of OS for random number generation. Macro names and + * values are documented on: + * https://sourceforge.net/p/predef/wiki/OperatingSystems/ + * + * Win32's CryptGenRandom() should be available on Windows systems. + * + * /dev/urandom should work on all Unix-like systems (including macOS X). + * + * getentropy() is present on Linux (Glibc 2.25+), FreeBSD (12.0+) and + * OpenBSD (5.6+). For OpenBSD, there does not seem to be easy to use + * macros to test the minimum version, so we just assume that it is + * recent enough (last version without getentropy() has gone out of + * support in May 2015). + * + * Ideally we should use getentropy() on macOS (10.12+) too, but I don't + * know how to test the exact OS version with preprocessor macros. + * + * TODO: enrich the list of detected system. + */ + +#ifndef BR_USE_URANDOM +#if defined _AIX \ + || defined __ANDROID__ \ + || defined __FreeBSD__ \ + || defined __NetBSD__ \ + || defined __OpenBSD__ \ + || defined __DragonFly__ \ + || defined __linux__ \ + || (defined __sun && (defined __SVR4 || defined __svr4__)) \ + || (defined __APPLE__ && defined __MACH__) +#define BR_USE_URANDOM 1 +#endif +#endif + +#ifndef BR_USE_GETENTROPY +#if (defined __linux__ \ + && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))) \ + || (defined __FreeBSD__ && __FreeBSD__ >= 12) \ + || defined __OpenBSD__ +#define BR_USE_GETENTROPY 1 +#endif +#endif + +#ifndef _XBOX +#ifndef BR_USE_WIN32_RAND +#if defined _WIN32 || defined _WIN64 +#define BR_USE_WIN32_RAND 1 +#endif +#endif +#endif + +#ifdef _XBOX +#define BR_USE_XBOX_RAND 1 +#endif + + +/* + * POWER8 crypto support. We rely on compiler macros for the + * architecture, since we do not have a reliable, simple way to detect + * the required support at runtime (we could try running an opcode, and + * trapping the exception or signal on illegal instruction, but this + * induces some non-trivial OS dependencies that we would prefer to + * avoid if possible). + */ +#ifndef BR_POWER8 +#if __GNUC__ && ((_ARCH_PWR8 || _ARCH_PPC) && __CRYPTO__) +#define BR_POWER8 1 +#endif +#endif + +/* + * Detect endinanness on POWER8. + */ +#if BR_POWER8 +#if defined BR_POWER8_LE +#undef BR_POWER8_BE +#if BR_POWER8_LE +#define BR_POWER8_BE 0 +#else +#define BR_POWER8_BE 1 +#endif +#elif defined BR_POWER8_BE +#undef BR_POWER8_LE +#if BR_POWER8_BE +#define BR_POWER8_LE 0 +#else +#define BR_POWER8_LE 1 +#endif +#else +#if __LITTLE_ENDIAN__ +#define BR_POWER8_LE 1 +#define BR_POWER8_BE 0 +#else +#define BR_POWER8_LE 0 +#define BR_POWER8_BE 1 +#endif +#endif +#endif + +/* + * Detect support for 128-bit integers. + */ +#if !defined BR_INT128 && !defined BR_UMUL128 +#ifdef __SIZEOF_INT128__ +#define BR_INT128 1 +#elif _M_X64 +#define BR_UMUL128 1 +#endif +#endif + +/* + * Detect support for unaligned accesses with known endianness. + * + * x86 (both 32-bit and 64-bit) is little-endian and allows unaligned + * accesses. + * + * POWER/PowerPC allows unaligned accesses when big-endian. POWER8 and + * later also allow unaligned accesses when little-endian. + */ +#if !defined BR_LE_UNALIGNED && !defined BR_BE_UNALIGNED + +#if __i386 || __i386__ || __x86_64__ || _M_IX86 || _M_X64 +#define BR_LE_UNALIGNED 1 +#elif BR_POWER8_BE +#define BR_BE_UNALIGNED 1 +#elif BR_POWER8_LE +#define BR_LE_UNALIGNED 1 +#elif (__powerpc__ || __powerpc64__ || _M_PPC || _ARCH_PPC || _ARCH_PPC64) \ + && __BIG_ENDIAN__ +#define BR_BE_UNALIGNED 1 +#endif + +#endif + +/* + * Detect support for an OS-provided time source. + */ + +#ifndef BR_USE_UNIX_TIME +#if defined __unix__ || defined __linux__ \ + || defined _POSIX_SOURCE || defined _POSIX_C_SOURCE \ + || (defined __APPLE__ && defined __MACH__) +#define BR_USE_UNIX_TIME 1 +#endif +#endif + +#ifndef BR_USE_WIN32_TIME +#if defined _WIN32 || defined _WIN64 || defined _XBOX +#define BR_USE_WIN32_TIME 1 +#endif +#endif + +/* ==================================================================== */ +/* + * Encoding/decoding functions. + * + * 32-bit and 64-bit decoding, both little-endian and big-endian, is + * implemented with the inline functions below. + * + * When allowed by some compile-time options (autodetected or provided), + * optimised code is used, to perform direct memory access when the + * underlying architecture supports it, both for endianness and + * alignment. This, however, may trigger strict aliasing issues; the + * code below uses unions to perform (supposedly) safe type punning. + * Since the C aliasing rules are relatively complex and were amended, + * or at least re-explained with different phrasing, in all successive + * versions of the C standard, it is always a bit risky to bet that any + * specific version of a C compiler got it right, for some notion of + * "right". + */ + +typedef union { + uint16_t u; + unsigned char b[sizeof(uint16_t)]; +} br_union_u16; + +typedef union { + uint32_t u; + unsigned char b[sizeof(uint32_t)]; +} br_union_u32; + +typedef union { + uint64_t u; + unsigned char b[sizeof(uint64_t)]; +} br_union_u64; + +static __inline void +br_enc16le(void *dst, unsigned x) +{ +#if BR_LE_UNALIGNED + ((br_union_u16 *)dst)->u = x; +#else + unsigned char *buf; + + buf = dst; + buf[0] = (unsigned char)x; + buf[1] = (unsigned char)(x >> 8); +#endif +} + +static __inline void +br_enc16be(void *dst, unsigned x) +{ +#if BR_BE_UNALIGNED + ((br_union_u16 *)dst)->u = x; +#else + unsigned char *buf; + + buf = dst; + buf[0] = (unsigned char)(x >> 8); + buf[1] = (unsigned char)x; +#endif +} + +static __inline unsigned +br_dec16le(const void *src) +{ +#if BR_LE_UNALIGNED + return ((const br_union_u16 *)src)->u; +#else + const unsigned char *buf; + + buf = src; + return (unsigned)buf[0] | ((unsigned)buf[1] << 8); +#endif +} + +static __inline unsigned +br_dec16be(const void *src) +{ +#if BR_BE_UNALIGNED + return ((const br_union_u16 *)src)->u; +#else + const unsigned char *buf; + + buf = src; + return ((unsigned)buf[0] << 8) | (unsigned)buf[1]; +#endif +} + +static __inline void +br_enc32le(void *dst, uint32_t x) +{ +#if BR_LE_UNALIGNED + ((br_union_u32 *)dst)->u = x; +#else + unsigned char *buf; + + buf = dst; + buf[0] = (unsigned char)x; + buf[1] = (unsigned char)(x >> 8); + buf[2] = (unsigned char)(x >> 16); + buf[3] = (unsigned char)(x >> 24); +#endif +} + +static __inline void +br_enc32be(void *dst, uint32_t x) +{ +#if BR_BE_UNALIGNED + ((br_union_u32 *)dst)->u = x; +#else + unsigned char *buf; + + buf = dst; + buf[0] = (unsigned char)(x >> 24); + buf[1] = (unsigned char)(x >> 16); + buf[2] = (unsigned char)(x >> 8); + buf[3] = (unsigned char)x; +#endif +} + +static __inline uint32_t +br_dec32le(const void *src) +{ +#if BR_LE_UNALIGNED + return ((const br_union_u32 *)src)->u; +#else + const unsigned char *buf; + + buf = src; + return (uint32_t)buf[0] + | ((uint32_t)buf[1] << 8) + | ((uint32_t)buf[2] << 16) + | ((uint32_t)buf[3] << 24); +#endif +} + +static __inline uint32_t +br_dec32be(const void *src) +{ +#if BR_BE_UNALIGNED + return ((const br_union_u32 *)src)->u; +#else + const unsigned char *buf; + + buf = src; + return ((uint32_t)buf[0] << 24) + | ((uint32_t)buf[1] << 16) + | ((uint32_t)buf[2] << 8) + | (uint32_t)buf[3]; +#endif +} + +static __inline void +br_enc64le(void *dst, uint64_t x) +{ +#if BR_LE_UNALIGNED + ((br_union_u64 *)dst)->u = x; +#else + unsigned char *buf; + + buf = dst; + br_enc32le(buf, (uint32_t)x); + br_enc32le(buf + 4, (uint32_t)(x >> 32)); +#endif +} + +static __inline void +br_enc64be(void *dst, uint64_t x) +{ +#if BR_BE_UNALIGNED + ((br_union_u64 *)dst)->u = x; +#else + unsigned char *buf; + + buf = dst; + br_enc32be(buf, (uint32_t)(x >> 32)); + br_enc32be(buf + 4, (uint32_t)x); +#endif +} + +static __inline uint64_t +br_dec64le(const void *src) +{ +#if BR_LE_UNALIGNED + return ((const br_union_u64 *)src)->u; +#else + const unsigned char *buf; + + buf = src; + return (uint64_t)br_dec32le(buf) + | ((uint64_t)br_dec32le(buf + 4) << 32); +#endif +} + +static __inline uint64_t +br_dec64be(const void *src) +{ +#if BR_BE_UNALIGNED + return ((const br_union_u64 *)src)->u; +#else + const unsigned char *buf; + + buf = src; + return ((uint64_t)br_dec32be(buf) << 32) + | (uint64_t)br_dec32be(buf + 4); +#endif +} + +/* + * Range decoding and encoding (for several successive values). + */ +void br_range_dec16le(uint16_t *v, size_t num, const void *src); +void br_range_dec16be(uint16_t *v, size_t num, const void *src); +void br_range_enc16le(void *dst, const uint16_t *v, size_t num); +void br_range_enc16be(void *dst, const uint16_t *v, size_t num); + +void br_range_dec32le(uint32_t *v, size_t num, const void *src); +void br_range_dec32be(uint32_t *v, size_t num, const void *src); +void br_range_enc32le(void *dst, const uint32_t *v, size_t num); +void br_range_enc32be(void *dst, const uint32_t *v, size_t num); + +void br_range_dec64le(uint64_t *v, size_t num, const void *src); +void br_range_dec64be(uint64_t *v, size_t num, const void *src); +void br_range_enc64le(void *dst, const uint64_t *v, size_t num); +void br_range_enc64be(void *dst, const uint64_t *v, size_t num); + +/* + * Byte-swap a 32-bit integer. + */ +static __inline uint32_t +br_swap32(uint32_t x) +{ + x = ((x & (uint32_t)0x00FF00FF) << 8) + | ((x >> 8) & (uint32_t)0x00FF00FF); + return (x << 16) | (x >> 16); +} + +/* ==================================================================== */ +/* + * Support code for hash functions. + */ + +/* + * IV for MD5, SHA-1, SHA-224 and SHA-256. + */ +extern const uint32_t br_md5_IV[]; +extern const uint32_t br_sha1_IV[]; +extern const uint32_t br_sha224_IV[]; +extern const uint32_t br_sha256_IV[]; + +/* + * Round functions for MD5, SHA-1, SHA-224 and SHA-256 (SHA-224 and + * SHA-256 use the same round function). + */ +void br_md5_round(const unsigned char *buf, uint32_t *val); +void br_sha1_round(const unsigned char *buf, uint32_t *val); +void br_sha2small_round(const unsigned char *buf, uint32_t *val); + +/* + * The core function for the TLS PRF. It computes + * P_hash(secret, label + seed), and XORs the result into the dst buffer. + */ +void br_tls_phash(void *dst, size_t len, + const br_hash_class *dig, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed); + +/* + * Copy all configured hash implementations from a multihash context + * to another. + */ +static __inline void +br_multihash_copyimpl(br_multihash_context *dst, + const br_multihash_context *src) +{ + memcpy((void *)dst->impl, src->impl, sizeof src->impl); +} + +/* ==================================================================== */ +/* + * Constant-time primitives. These functions manipulate 32-bit values in + * order to provide constant-time comparisons and multiplexers. + * + * Boolean values (the "ctl" bits) MUST have value 0 or 1. + * + * Implementation notes: + * ===================== + * + * The uintN_t types are unsigned and with width exactly N bits; the C + * standard guarantees that computations are performed modulo 2^N, and + * there can be no overflow. Negation (unary '-') works on unsigned types + * as well. + * + * The intN_t types are guaranteed to have width exactly N bits, with no + * padding bit, and using two's complement representation. Casting + * intN_t to uintN_t really is conversion modulo 2^N. Beware that intN_t + * types, being signed, trigger implementation-defined behaviour on + * overflow (including raising some signal): with GCC, while modular + * arithmetics are usually applied, the optimizer may assume that + * overflows don't occur (unless the -fwrapv command-line option is + * added); Clang has the additional -ftrapv option to explicitly trap on + * integer overflow or underflow. + */ + +/* + * Negate a boolean. + */ +static __inline uint32_t +NOT(uint32_t ctl) +{ + return ctl ^ 1; +} + +/* + * Multiplexer: returns x if ctl == 1, y if ctl == 0. + */ +static __inline uint32_t +MUX(uint32_t ctl, uint32_t x, uint32_t y) +{ + return y ^ (-ctl & (x ^ y)); +} + +/* + * Equality check: returns 1 if x == y, 0 otherwise. + */ +static __inline uint32_t +EQ(uint32_t x, uint32_t y) +{ + uint32_t q; + + q = x ^ y; + return NOT((q | -q) >> 31); +} + +/* + * Inequality check: returns 1 if x != y, 0 otherwise. + */ +static __inline uint32_t +NEQ(uint32_t x, uint32_t y) +{ + uint32_t q; + + q = x ^ y; + return (q | -q) >> 31; +} + +/* + * Comparison: returns 1 if x > y, 0 otherwise. + */ +static __inline uint32_t +GT(uint32_t x, uint32_t y) +{ + /* + * If both x < 2^31 and x < 2^31, then y-x will have its high + * bit set if x > y, cleared otherwise. + * + * If either x >= 2^31 or y >= 2^31 (but not both), then the + * result is the high bit of x. + * + * If both x >= 2^31 and y >= 2^31, then we can virtually + * subtract 2^31 from both, and we are back to the first case. + * Since (y-2^31)-(x-2^31) = y-x, the subtraction is already + * fine. + */ + uint32_t z; + + z = y - x; + return (z ^ ((x ^ y) & (x ^ z))) >> 31; +} + +/* + * Other comparisons (greater-or-equal, lower-than, lower-or-equal). + */ +#define GE(x, y) NOT(GT(y, x)) +#define LT(x, y) GT(y, x) +#define LE(x, y) NOT(GT(x, y)) + +/* + * General comparison: returned value is -1, 0 or 1, depending on + * whether x is lower than, equal to, or greater than y. + */ +static __inline int32_t +CMP(uint32_t x, uint32_t y) +{ + return (int32_t)GT(x, y) | -(int32_t)GT(y, x); +} + +/* + * Returns 1 if x == 0, 0 otherwise. Take care that the operand is signed. + */ +static __inline uint32_t +EQ0(int32_t x) +{ + uint32_t q; + + q = (uint32_t)x; + return ~(q | -q) >> 31; +} + +/* + * Returns 1 if x > 0, 0 otherwise. Take care that the operand is signed. + */ +static __inline uint32_t +GT0(int32_t x) +{ + /* + * High bit of -x is 0 if x == 0, but 1 if x > 0. + */ + uint32_t q; + + q = (uint32_t)x; + return (~q & -q) >> 31; +} + +/* + * Returns 1 if x >= 0, 0 otherwise. Take care that the operand is signed. + */ +static __inline uint32_t +GE0(int32_t x) +{ + return ~(uint32_t)x >> 31; +} + +/* + * Returns 1 if x < 0, 0 otherwise. Take care that the operand is signed. + */ +static __inline uint32_t +LT0(int32_t x) +{ + return (uint32_t)x >> 31; +} + +/* + * Returns 1 if x <= 0, 0 otherwise. Take care that the operand is signed. + */ +static __inline uint32_t +LE0(int32_t x) +{ + uint32_t q; + + /* + * ~-x has its high bit set if and only if -x is nonnegative (as + * a signed int), i.e. x is in the -(2^31-1) to 0 range. We must + * do an OR with x itself to account for x = -2^31. + */ + q = (uint32_t)x; + return (q | ~-q) >> 31; +} + +/* + * Conditional copy: src[] is copied into dst[] if and only if ctl is 1. + * dst[] and src[] may overlap completely (but not partially). + */ +void br_ccopy(uint32_t ctl, void *dst, const void *src, size_t len); + +#define CCOPY br_ccopy + +/* + * Compute the bit length of a 32-bit integer. Returned value is between 0 + * and 32 (inclusive). + */ +static __inline uint32_t +BIT_LENGTH(uint32_t x) +{ + uint32_t k, c; + + k = NEQ(x, 0); + c = GT(x, 0xFFFF); x = MUX(c, x >> 16, x); k += c << 4; + c = GT(x, 0x00FF); x = MUX(c, x >> 8, x); k += c << 3; + c = GT(x, 0x000F); x = MUX(c, x >> 4, x); k += c << 2; + c = GT(x, 0x0003); x = MUX(c, x >> 2, x); k += c << 1; + k += GT(x, 0x0001); + return k; +} + +/* + * Compute the minimum of x and y. + */ +static __inline uint32_t +MIN(uint32_t x, uint32_t y) +{ + return MUX(GT(x, y), y, x); +} + +/* + * Compute the maximum of x and y. + */ +static __inline uint32_t +MAX(uint32_t x, uint32_t y) +{ + return MUX(GT(x, y), x, y); +} + +/* + * Multiply two 32-bit integers, with a 64-bit result. This default + * implementation assumes that the basic multiplication operator + * yields constant-time code. + */ +#define MUL(x, y) ((uint64_t)(x) * (uint64_t)(y)) + +#if BR_CT_MUL31 + +/* + * Alternate implementation of MUL31, that will be constant-time on some + * (old) platforms where the default MUL31 is not. Unfortunately, it is + * also substantially slower, and yields larger code, on more modern + * platforms, which is why it is deactivated by default. + * + * MUL31_lo() must do some extra work because on some platforms, the + * _signed_ multiplication may return early if the top bits are 1. + * Simply truncating (casting) the output of MUL31() would not be + * sufficient, because the compiler may notice that we keep only the low + * word, and then replace automatically the unsigned multiplication with + * a signed multiplication opcode. + */ +#define MUL31(x, y) ((uint64_t)((x) | (uint32_t)0x80000000) \ + * (uint64_t)((y) | (uint32_t)0x80000000) \ + - ((uint64_t)(x) << 31) - ((uint64_t)(y) << 31) \ + - ((uint64_t)1 << 62)) +static __inline uint32_t +MUL31_lo(uint32_t x, uint32_t y) +{ + uint32_t xl, xh; + uint32_t yl, yh; + + xl = (x & 0xFFFF) | (uint32_t)0x80000000; + xh = (x >> 16) | (uint32_t)0x80000000; + yl = (y & 0xFFFF) | (uint32_t)0x80000000; + yh = (y >> 16) | (uint32_t)0x80000000; + return (xl * yl + ((xl * yh + xh * yl) << 16)) & (uint32_t)0x7FFFFFFF; +} + +#else + +/* + * Multiply two 31-bit integers, with a 62-bit result. This default + * implementation assumes that the basic multiplication operator + * yields constant-time code. + * The MUL31_lo() macro returns only the low 31 bits of the product. + */ +#define MUL31(x, y) ((uint64_t)(x) * (uint64_t)(y)) +#define MUL31_lo(x, y) (((uint32_t)(x) * (uint32_t)(y)) & (uint32_t)0x7FFFFFFF) + +#endif + +/* + * Multiply two words together; the sum of the lengths of the two + * operands must not exceed 31 (for instance, one operand may use 16 + * bits if the other fits on 15). If BR_CT_MUL15 is non-zero, then the + * macro will contain some extra operations that help in making the + * operation constant-time on some platforms, where the basic 32-bit + * multiplication is not constant-time. + */ +#if BR_CT_MUL15 +#define MUL15(x, y) (((uint32_t)(x) | (uint32_t)0x80000000) \ + * ((uint32_t)(y) | (uint32_t)0x80000000) \ + & (uint32_t)0x7FFFFFFF) +#else +#define MUL15(x, y) ((uint32_t)(x) * (uint32_t)(y)) +#endif + +/* + * Arithmetic right shift (sign bit is copied). What happens when + * right-shifting a negative value is _implementation-defined_, so it + * does not trigger undefined behaviour, but it is still up to each + * compiler to define (and document) what it does. Most/all compilers + * will do an arithmetic shift, the sign bit being used to fill the + * holes; this is a native operation on the underlying CPU, and it would + * make little sense for the compiler to do otherwise. GCC explicitly + * documents that it follows that convention. + * + * Still, if BR_NO_ARITH_SHIFT is defined (and non-zero), then an + * alternate version will be used, that does not rely on such + * implementation-defined behaviour. Unfortunately, it is also slower + * and yields bigger code, which is why it is deactivated by default. + */ +#if BR_NO_ARITH_SHIFT +#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ + | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) +#else +#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) +#endif + +/* + * Constant-time division. The dividend hi:lo is divided by the + * divisor d; the quotient is returned and the remainder is written + * in *r. If hi == d, then the quotient does not fit on 32 bits; + * returned value is thus truncated. If hi > d, returned values are + * indeterminate. + */ +uint32_t br_divrem(uint32_t hi, uint32_t lo, uint32_t d, uint32_t *r); + +/* + * Wrapper for br_divrem(); the remainder is returned, and the quotient + * is discarded. + */ +static __inline uint32_t +br_rem(uint32_t hi, uint32_t lo, uint32_t d) +{ + uint32_t r; + + br_divrem(hi, lo, d, &r); + return r; +} + +/* + * Wrapper for br_divrem(); the quotient is returned, and the remainder + * is discarded. + */ +static __inline uint32_t +br_div(uint32_t hi, uint32_t lo, uint32_t d) +{ + uint32_t r; + + return br_divrem(hi, lo, d, &r); +} + +/* ==================================================================== */ + +/* + * Integers 'i32' + * -------------- + * + * The 'i32' functions implement computations on big integers using + * an internal representation as an array of 32-bit integers. For + * an array x[]: + * -- x[0] contains the "announced bit length" of the integer + * -- x[1], x[2]... contain the value in little-endian order (x[1] + * contains the least significant 32 bits) + * + * Multiplications rely on the elementary 32x32->64 multiplication. + * + * The announced bit length specifies the number of bits that are + * significant in the subsequent 32-bit words. Unused bits in the + * last (most significant) word are set to 0; subsequent words are + * uninitialized and need not exist at all. + * + * The execution time and memory access patterns of all computations + * depend on the announced bit length, but not on the actual word + * values. For modular integers, the announced bit length of any integer + * modulo n is equal to the actual bit length of n; thus, computations + * on modular integers are "constant-time" (only the modulus length may + * leak). + */ + +/* + * Compute the actual bit length of an integer. The argument x should + * point to the first (least significant) value word of the integer. + * The len 'xlen' contains the number of 32-bit words to access. + * + * CT: value or length of x does not leak. + */ +uint32_t br_i32_bit_length(uint32_t *x, size_t xlen); + +/* + * Decode an integer from its big-endian unsigned representation. The + * "true" bit length of the integer is computed, but all words of x[] + * corresponding to the full 'len' bytes of the source are set. + * + * CT: value or length of x does not leak. + */ +void br_i32_decode(uint32_t *x, const void *src, size_t len); + +/* + * Decode an integer from its big-endian unsigned representation. The + * integer MUST be lower than m[]; the announced bit length written in + * x[] will be equal to that of m[]. All 'len' bytes from the source are + * read. + * + * Returned value is 1 if the decode value fits within the modulus, 0 + * otherwise. In the latter case, the x[] buffer will be set to 0 (but + * still with the announced bit length of m[]). + * + * CT: value or length of x does not leak. Memory access pattern depends + * only of 'len' and the announced bit length of m. Whether x fits or + * not does not leak either. + */ +uint32_t br_i32_decode_mod(uint32_t *x, + const void *src, size_t len, const uint32_t *m); + +/* + * Reduce an integer (a[]) modulo another (m[]). The result is written + * in x[] and its announced bit length is set to be equal to that of m[]. + * + * x[] MUST be distinct from a[] and m[]. + * + * CT: only announced bit lengths leak, not values of x, a or m. + */ +void br_i32_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m); + +/* + * Decode an integer from its big-endian unsigned representation, and + * reduce it modulo the provided modulus m[]. The announced bit length + * of the result is set to be equal to that of the modulus. + * + * x[] MUST be distinct from m[]. + */ +void br_i32_decode_reduce(uint32_t *x, + const void *src, size_t len, const uint32_t *m); + +/* + * Encode an integer into its big-endian unsigned representation. The + * output length in bytes is provided (parameter 'len'); if the length + * is too short then the integer is appropriately truncated; if it is + * too long then the extra bytes are set to 0. + */ +void br_i32_encode(void *dst, size_t len, const uint32_t *x); + +/* + * Multiply x[] by 2^32 and then add integer z, modulo m[]. This + * function assumes that x[] and m[] have the same announced bit + * length, and the announced bit length of m[] matches its true + * bit length. + * + * x[] and m[] MUST be distinct arrays. + * + * CT: only the common announced bit length of x and m leaks, not + * the values of x, z or m. + */ +void br_i32_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m); + +/* + * Extract one word from an integer. The offset is counted in bits. + * The word MUST entirely fit within the word elements corresponding + * to the announced bit length of a[]. + */ +static __inline uint32_t +br_i32_word(const uint32_t *a, uint32_t off) +{ + size_t u; + unsigned j; + + u = (size_t)(off >> 5) + 1; + j = (unsigned)off & 31; + if (j == 0) { + return a[u]; + } else { + return (a[u] >> j) | (a[u + 1] << (32 - j)); + } +} + +/* + * Test whether an integer is zero. + */ +uint32_t br_i32_iszero(const uint32_t *x); + +/* + * Add b[] to a[] and return the carry (0 or 1). If ctl is 0, then a[] + * is unmodified, but the carry is still computed and returned. The + * arrays a[] and b[] MUST have the same announced bit length. + * + * a[] and b[] MAY be the same array, but partial overlap is not allowed. + */ +uint32_t br_i32_add(uint32_t *a, const uint32_t *b, uint32_t ctl); + +/* + * Subtract b[] from a[] and return the carry (0 or 1). If ctl is 0, + * then a[] is unmodified, but the carry is still computed and returned. + * The arrays a[] and b[] MUST have the same announced bit length. + * + * a[] and b[] MAY be the same array, but partial overlap is not allowed. + */ +uint32_t br_i32_sub(uint32_t *a, const uint32_t *b, uint32_t ctl); + +/* + * Compute d+a*b, result in d. The initial announced bit length of d[] + * MUST match that of a[]. The d[] array MUST be large enough to + * accommodate the full result, plus (possibly) an extra word. The + * resulting announced bit length of d[] will be the sum of the announced + * bit lengths of a[] and b[] (therefore, it may be larger than the actual + * bit length of the numerical result). + * + * a[] and b[] may be the same array. d[] must be disjoint from both a[] + * and b[]. + */ +void br_i32_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b); + +/* + * Zeroize an integer. The announced bit length is set to the provided + * value, and the corresponding words are set to 0. + */ +static __inline void +br_i32_zero(uint32_t *x, uint32_t bit_len) +{ + *x ++ = bit_len; + memset(x, 0, ((bit_len + 31) >> 5) * sizeof *x); +} + +/* + * Compute -(1/x) mod 2^32. If x is even, then this function returns 0. + */ +uint32_t br_i32_ninv32(uint32_t x); + +/* + * Convert a modular integer to Montgomery representation. The integer x[] + * MUST be lower than m[], but with the same announced bit length. + */ +void br_i32_to_monty(uint32_t *x, const uint32_t *m); + +/* + * Convert a modular integer back from Montgomery representation. The + * integer x[] MUST be lower than m[], but with the same announced bit + * length. The "m0i" parameter is equal to -(1/m0) mod 2^32, where m0 is + * the least significant value word of m[] (this works only if m[] is + * an odd integer). + */ +void br_i32_from_monty(uint32_t *x, const uint32_t *m, uint32_t m0i); + +/* + * Compute a modular Montgomery multiplication. d[] is filled with the + * value of x*y/R modulo m[] (where R is the Montgomery factor). The + * array d[] MUST be distinct from x[], y[] and m[]. x[] and y[] MUST be + * numerically lower than m[]. x[] and y[] MAY be the same array. The + * "m0i" parameter is equal to -(1/m0) mod 2^32, where m0 is the least + * significant value word of m[] (this works only if m[] is an odd + * integer). + */ +void br_i32_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, + const uint32_t *m, uint32_t m0i); + +/* + * Compute a modular exponentiation. x[] MUST be an integer modulo m[] + * (same announced bit length, lower value). m[] MUST be odd. The + * exponent is in big-endian unsigned notation, over 'elen' bytes. The + * "m0i" parameter is equal to -(1/m0) mod 2^32, where m0 is the least + * significant value word of m[] (this works only if m[] is an odd + * integer). The t1[] and t2[] parameters must be temporary arrays, + * each large enough to accommodate an integer with the same size as m[]. + */ +void br_i32_modpow(uint32_t *x, const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2); + +/* ==================================================================== */ + +/* + * Integers 'i31' + * -------------- + * + * The 'i31' functions implement computations on big integers using + * an internal representation as an array of 32-bit integers. For + * an array x[]: + * -- x[0] encodes the array length and the "announced bit length" + * of the integer: namely, if the announced bit length is k, + * then x[0] = ((k / 31) << 5) + (k % 31). + * -- x[1], x[2]... contain the value in little-endian order, 31 + * bits per word (x[1] contains the least significant 31 bits). + * The upper bit of each word is 0. + * + * Multiplications rely on the elementary 32x32->64 multiplication. + * + * The announced bit length specifies the number of bits that are + * significant in the subsequent 32-bit words. Unused bits in the + * last (most significant) word are set to 0; subsequent words are + * uninitialized and need not exist at all. + * + * The execution time and memory access patterns of all computations + * depend on the announced bit length, but not on the actual word + * values. For modular integers, the announced bit length of any integer + * modulo n is equal to the actual bit length of n; thus, computations + * on modular integers are "constant-time" (only the modulus length may + * leak). + */ + +/* + * Test whether an integer is zero. + */ +uint32_t br_i31_iszero(const uint32_t *x); + +/* + * Add b[] to a[] and return the carry (0 or 1). If ctl is 0, then a[] + * is unmodified, but the carry is still computed and returned. The + * arrays a[] and b[] MUST have the same announced bit length. + * + * a[] and b[] MAY be the same array, but partial overlap is not allowed. + */ +uint32_t br_i31_add(uint32_t *a, const uint32_t *b, uint32_t ctl); + +/* + * Subtract b[] from a[] and return the carry (0 or 1). If ctl is 0, + * then a[] is unmodified, but the carry is still computed and returned. + * The arrays a[] and b[] MUST have the same announced bit length. + * + * a[] and b[] MAY be the same array, but partial overlap is not allowed. + */ +uint32_t br_i31_sub(uint32_t *a, const uint32_t *b, uint32_t ctl); + +/* + * Compute the ENCODED actual bit length of an integer. The argument x + * should point to the first (least significant) value word of the + * integer. The len 'xlen' contains the number of 32-bit words to + * access. The upper bit of each value word MUST be 0. + * Returned value is ((k / 31) << 5) + (k % 31) if the bit length is k. + * + * CT: value or length of x does not leak. + */ +uint32_t br_i31_bit_length(uint32_t *x, size_t xlen); + +/* + * Decode an integer from its big-endian unsigned representation. The + * "true" bit length of the integer is computed and set in the encoded + * announced bit length (x[0]), but all words of x[] corresponding to + * the full 'len' bytes of the source are set. + * + * CT: value or length of x does not leak. + */ +void br_i31_decode(uint32_t *x, const void *src, size_t len); + +/* + * Decode an integer from its big-endian unsigned representation. The + * integer MUST be lower than m[]; the (encoded) announced bit length + * written in x[] will be equal to that of m[]. All 'len' bytes from the + * source are read. + * + * Returned value is 1 if the decode value fits within the modulus, 0 + * otherwise. In the latter case, the x[] buffer will be set to 0 (but + * still with the announced bit length of m[]). + * + * CT: value or length of x does not leak. Memory access pattern depends + * only of 'len' and the announced bit length of m. Whether x fits or + * not does not leak either. + */ +uint32_t br_i31_decode_mod(uint32_t *x, + const void *src, size_t len, const uint32_t *m); + +/* + * Zeroize an integer. The announced bit length is set to the provided + * value, and the corresponding words are set to 0. The ENCODED bit length + * is expected here. + */ +static __inline void +br_i31_zero(uint32_t *x, uint32_t bit_len) +{ + *x ++ = bit_len; + memset(x, 0, ((bit_len + 31) >> 5) * sizeof *x); +} + +/* + * Right-shift an integer. The shift amount must be lower than 31 + * bits. + */ +void br_i31_rshift(uint32_t *x, int count); + +/* + * Reduce an integer (a[]) modulo another (m[]). The result is written + * in x[] and its announced bit length is set to be equal to that of m[]. + * + * x[] MUST be distinct from a[] and m[]. + * + * CT: only announced bit lengths leak, not values of x, a or m. + */ +void br_i31_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m); + +/* + * Decode an integer from its big-endian unsigned representation, and + * reduce it modulo the provided modulus m[]. The announced bit length + * of the result is set to be equal to that of the modulus. + * + * x[] MUST be distinct from m[]. + */ +void br_i31_decode_reduce(uint32_t *x, + const void *src, size_t len, const uint32_t *m); + +/* + * Multiply x[] by 2^31 and then add integer z, modulo m[]. This + * function assumes that x[] and m[] have the same announced bit + * length, the announced bit length of m[] matches its true + * bit length. + * + * x[] and m[] MUST be distinct arrays. z MUST fit in 31 bits (upper + * bit set to 0). + * + * CT: only the common announced bit length of x and m leaks, not + * the values of x, z or m. + */ +void br_i31_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m); + +/* + * Encode an integer into its big-endian unsigned representation. The + * output length in bytes is provided (parameter 'len'); if the length + * is too short then the integer is appropriately truncated; if it is + * too long then the extra bytes are set to 0. + */ +void br_i31_encode(void *dst, size_t len, const uint32_t *x); + +/* + * Compute -(1/x) mod 2^31. If x is even, then this function returns 0. + */ +uint32_t br_i31_ninv31(uint32_t x); + +/* + * Compute a modular Montgomery multiplication. d[] is filled with the + * value of x*y/R modulo m[] (where R is the Montgomery factor). The + * array d[] MUST be distinct from x[], y[] and m[]. x[] and y[] MUST be + * numerically lower than m[]. x[] and y[] MAY be the same array. The + * "m0i" parameter is equal to -(1/m0) mod 2^31, where m0 is the least + * significant value word of m[] (this works only if m[] is an odd + * integer). + */ +void br_i31_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, + const uint32_t *m, uint32_t m0i); + +/* + * Convert a modular integer to Montgomery representation. The integer x[] + * MUST be lower than m[], but with the same announced bit length. + */ +void br_i31_to_monty(uint32_t *x, const uint32_t *m); + +/* + * Convert a modular integer back from Montgomery representation. The + * integer x[] MUST be lower than m[], but with the same announced bit + * length. The "m0i" parameter is equal to -(1/m0) mod 2^32, where m0 is + * the least significant value word of m[] (this works only if m[] is + * an odd integer). + */ +void br_i31_from_monty(uint32_t *x, const uint32_t *m, uint32_t m0i); + +/* + * Compute a modular exponentiation. x[] MUST be an integer modulo m[] + * (same announced bit length, lower value). m[] MUST be odd. The + * exponent is in big-endian unsigned notation, over 'elen' bytes. The + * "m0i" parameter is equal to -(1/m0) mod 2^31, where m0 is the least + * significant value word of m[] (this works only if m[] is an odd + * integer). The t1[] and t2[] parameters must be temporary arrays, + * each large enough to accommodate an integer with the same size as m[]. + */ +void br_i31_modpow(uint32_t *x, const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2); + +/* + * Compute a modular exponentiation. x[] MUST be an integer modulo m[] + * (same announced bit length, lower value). m[] MUST be odd. The + * exponent is in big-endian unsigned notation, over 'elen' bytes. The + * "m0i" parameter is equal to -(1/m0) mod 2^31, where m0 is the least + * significant value word of m[] (this works only if m[] is an odd + * integer). The tmp[] array is used for temporaries, and has size + * 'twlen' words; it must be large enough to accommodate at least two + * temporary values with the same size as m[] (including the leading + * "bit length" word). If there is room for more temporaries, then this + * function may use the extra room for window-based optimisation, + * resulting in faster computations. + * + * Returned value is 1 on success, 0 on error. An error is reported if + * the provided tmp[] array is too short. + */ +uint32_t br_i31_modpow_opt(uint32_t *x, const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *tmp, size_t twlen); + +/* + * Compute d+a*b, result in d. The initial announced bit length of d[] + * MUST match that of a[]. The d[] array MUST be large enough to + * accommodate the full result, plus (possibly) an extra word. The + * resulting announced bit length of d[] will be the sum of the announced + * bit lengths of a[] and b[] (therefore, it may be larger than the actual + * bit length of the numerical result). + * + * a[] and b[] may be the same array. d[] must be disjoint from both a[] + * and b[]. + */ +void br_i31_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b); + +/* + * Compute x/y mod m, result in x. Values x and y must be between 0 and + * m-1, and have the same announced bit length as m. Modulus m must be + * odd. The "m0i" parameter is equal to -1/m mod 2^31. The array 't' + * must point to a temporary area that can hold at least three integers + * of the size of m. + * + * m may not overlap x and y. x and y may overlap each other (this can + * be useful to test whether a value is invertible modulo m). t must be + * disjoint from all other arrays. + * + * Returned value is 1 on success, 0 otherwise. Success is attained if + * y is invertible modulo m. + */ +uint32_t br_i31_moddiv(uint32_t *x, const uint32_t *y, + const uint32_t *m, uint32_t m0i, uint32_t *t); + +/* ==================================================================== */ + +/* + * FIXME: document "i15" functions. + */ + +static __inline void +br_i15_zero(uint16_t *x, uint16_t bit_len) +{ + *x ++ = bit_len; + memset(x, 0, ((bit_len + 15) >> 4) * sizeof *x); +} + +uint32_t br_i15_iszero(const uint16_t *x); + +uint16_t br_i15_ninv15(uint16_t x); + +uint32_t br_i15_add(uint16_t *a, const uint16_t *b, uint32_t ctl); + +uint32_t br_i15_sub(uint16_t *a, const uint16_t *b, uint32_t ctl); + +void br_i15_muladd_small(uint16_t *x, uint16_t z, const uint16_t *m); + +void br_i15_montymul(uint16_t *d, const uint16_t *x, const uint16_t *y, + const uint16_t *m, uint16_t m0i); + +void br_i15_to_monty(uint16_t *x, const uint16_t *m); + +void br_i15_modpow(uint16_t *x, const unsigned char *e, size_t elen, + const uint16_t *m, uint16_t m0i, uint16_t *t1, uint16_t *t2); + +uint32_t br_i15_modpow_opt(uint16_t *x, const unsigned char *e, size_t elen, + const uint16_t *m, uint16_t m0i, uint16_t *tmp, size_t twlen); + +void br_i15_encode(void *dst, size_t len, const uint16_t *x); + +uint32_t br_i15_decode_mod(uint16_t *x, + const void *src, size_t len, const uint16_t *m); + +void br_i15_rshift(uint16_t *x, int count); + +uint32_t br_i15_bit_length(uint16_t *x, size_t xlen); + +void br_i15_decode(uint16_t *x, const void *src, size_t len); + +void br_i15_from_monty(uint16_t *x, const uint16_t *m, uint16_t m0i); + +void br_i15_decode_reduce(uint16_t *x, + const void *src, size_t len, const uint16_t *m); + +void br_i15_reduce(uint16_t *x, const uint16_t *a, const uint16_t *m); + +void br_i15_mulacc(uint16_t *d, const uint16_t *a, const uint16_t *b); + +uint32_t br_i15_moddiv(uint16_t *x, const uint16_t *y, + const uint16_t *m, uint16_t m0i, uint16_t *t); + +/* + * Variant of br_i31_modpow_opt() that internally uses 64x64->128 + * multiplications. It expects the same parameters as br_i31_modpow_opt(), + * except that the temporaries should be 64-bit integers, not 32-bit + * integers. + */ +uint32_t br_i62_modpow_opt(uint32_t *x31, const unsigned char *e, size_t elen, + const uint32_t *m31, uint32_t m0i31, uint64_t *tmp, size_t twlen); + +/* + * Type for a function with the same API as br_i31_modpow_opt() (some + * implementations of this type may have stricter alignment requirements + * on the temporaries). + */ +typedef uint32_t (*br_i31_modpow_opt_type)(uint32_t *x, + const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *tmp, size_t twlen); + +/* + * Wrapper for br_i62_modpow_opt() that uses the same type as + * br_i31_modpow_opt(); however, it requires its 'tmp' argument to the + * 64-bit aligned. + */ +uint32_t br_i62_modpow_opt_as_i31(uint32_t *x, + const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *tmp, size_t twlen); + +/* ==================================================================== */ + +static __inline size_t +br_digest_size(const br_hash_class *digest_class) +{ + return (size_t)(digest_class->desc >> BR_HASHDESC_OUT_OFF) + & BR_HASHDESC_OUT_MASK; +} + +/* + * Get the output size (in bytes) of a hash function. + */ +size_t br_digest_size_by_ID(int digest_id); + +/* + * Get the OID (encoded OBJECT IDENTIFIER value, without tag and length) + * for a hash function. If digest_id is not a supported digest identifier + * (in particular if it is equal to 0, i.e. br_md5sha1_ID), then NULL is + * returned and *len is set to 0. + */ +const unsigned char *br_digest_OID(int digest_id, size_t *len); + +/* ==================================================================== */ +/* + * DES support functions. + */ + +/* + * Apply DES Initial Permutation. + */ +void br_des_do_IP(uint32_t *xl, uint32_t *xr); + +/* + * Apply DES Final Permutation (inverse of IP). + */ +void br_des_do_invIP(uint32_t *xl, uint32_t *xr); + +/* + * Key schedule unit: for a DES key (8 bytes), compute 16 subkeys. Each + * subkey is two 28-bit words represented as two 32-bit words; the PC-2 + * bit extration is NOT applied. + */ +void br_des_keysched_unit(uint32_t *skey, const void *key); + +/* + * Reversal of 16 DES sub-keys (for decryption). + */ +void br_des_rev_skey(uint32_t *skey); + +/* + * DES/3DES key schedule for 'des_tab' (encryption direction). Returned + * value is the number of rounds. + */ +unsigned br_des_tab_keysched(uint32_t *skey, const void *key, size_t key_len); + +/* + * DES/3DES key schedule for 'des_ct' (encryption direction). Returned + * value is the number of rounds. + */ +unsigned br_des_ct_keysched(uint32_t *skey, const void *key, size_t key_len); + +/* + * DES/3DES subkey decompression (from the compressed bitsliced subkeys). + */ +void br_des_ct_skey_expand(uint32_t *sk_exp, + unsigned num_rounds, const uint32_t *skey); + +/* + * DES/3DES block encryption/decryption ('des_tab'). + */ +void br_des_tab_process_block(unsigned num_rounds, + const uint32_t *skey, void *block); + +/* + * DES/3DES block encryption/decryption ('des_ct'). + */ +void br_des_ct_process_block(unsigned num_rounds, + const uint32_t *skey, void *block); + +/* ==================================================================== */ +/* + * AES support functions. + */ + +/* + * The AES S-box (256-byte table). + */ +extern const unsigned char br_aes_S[]; + +/* + * AES key schedule. skey[] is filled with n+1 128-bit subkeys, where n + * is the number of rounds (10 to 14, depending on key size). The number + * of rounds is returned. If the key size is invalid (not 16, 24 or 32), + * then 0 is returned. + * + * This implementation uses a 256-byte table and is NOT constant-time. + */ +unsigned br_aes_keysched(uint32_t *skey, const void *key, size_t key_len); + +/* + * AES key schedule for decryption ('aes_big' implementation). + */ +unsigned br_aes_big_keysched_inv(uint32_t *skey, + const void *key, size_t key_len); + +/* + * AES block encryption with the 'aes_big' implementation (fast, but + * not constant-time). This function encrypts a single block "in place". + */ +void br_aes_big_encrypt(unsigned num_rounds, const uint32_t *skey, void *data); + +/* + * AES block decryption with the 'aes_big' implementation (fast, but + * not constant-time). This function decrypts a single block "in place". + */ +void br_aes_big_decrypt(unsigned num_rounds, const uint32_t *skey, void *data); + +/* + * AES block encryption with the 'aes_small' implementation (small, but + * slow and not constant-time). This function encrypts a single block + * "in place". + */ +void br_aes_small_encrypt(unsigned num_rounds, + const uint32_t *skey, void *data); + +/* + * AES block decryption with the 'aes_small' implementation (small, but + * slow and not constant-time). This function decrypts a single block + * "in place". + */ +void br_aes_small_decrypt(unsigned num_rounds, + const uint32_t *skey, void *data); + +/* + * The constant-time implementation is "bitsliced": the 128-bit state is + * split over eight 32-bit words q* in the following way: + * + * -- Input block consists in 16 bytes: + * a00 a10 a20 a30 a01 a11 a21 a31 a02 a12 a22 a32 a03 a13 a23 a33 + * In the terminology of FIPS 197, this is a 4x4 matrix which is read + * column by column. + * + * -- Each byte is split into eight bits which are distributed over the + * eight words, at the same rank. Thus, for a byte x at rank k, bit 0 + * (least significant) of x will be at rank k in q0 (if that bit is b, + * then it contributes "b << k" to the value of q0), bit 1 of x will be + * at rank k in q1, and so on. + * + * -- Ranks given to bits are in "row order" and are either all even, or + * all odd. Two independent AES states are thus interleaved, one using + * the even ranks, the other the odd ranks. Row order means: + * a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23 a30 a31 a32 a33 + * + * Converting input bytes from two AES blocks to bitslice representation + * is done in the following way: + * -- Decode first block into the four words q0 q2 q4 q6, in that order, + * using little-endian convention. + * -- Decode second block into the four words q1 q3 q5 q7, in that order, + * using little-endian convention. + * -- Call br_aes_ct_ortho(). + * + * Converting back to bytes is done by using the reverse operations. Note + * that br_aes_ct_ortho() is its own inverse. + */ + +/* + * Perform bytewise orthogonalization of eight 32-bit words. Bytes + * of q0..q7 are spread over all words: for a byte x that occurs + * at rank i in q[j] (byte x uses bits 8*i to 8*i+7 in q[j]), the bit + * of rank k in x (0 <= k <= 7) goes to q[k] at rank 8*i+j. + * + * This operation is an involution. + */ +void br_aes_ct_ortho(uint32_t *q); + +/* + * The AES S-box, as a bitsliced constant-time version. The input array + * consists in eight 32-bit words; 32 S-box instances are computed in + * parallel. Bits 0 to 7 of each S-box input (bit 0 is least significant) + * are spread over the words 0 to 7, at the same rank. + */ +void br_aes_ct_bitslice_Sbox(uint32_t *q); + +/* + * Like br_aes_bitslice_Sbox(), but for the inverse S-box. + */ +void br_aes_ct_bitslice_invSbox(uint32_t *q); + +/* + * Compute AES encryption on bitsliced data. Since input is stored on + * eight 32-bit words, two block encryptions are actually performed + * in parallel. + */ +void br_aes_ct_bitslice_encrypt(unsigned num_rounds, + const uint32_t *skey, uint32_t *q); + +/* + * Compute AES decryption on bitsliced data. Since input is stored on + * eight 32-bit words, two block decryptions are actually performed + * in parallel. + */ +void br_aes_ct_bitslice_decrypt(unsigned num_rounds, + const uint32_t *skey, uint32_t *q); + +/* + * AES key schedule, constant-time version. skey[] is filled with n+1 + * 128-bit subkeys, where n is the number of rounds (10 to 14, depending + * on key size). The number of rounds is returned. If the key size is + * invalid (not 16, 24 or 32), then 0 is returned. + */ +unsigned br_aes_ct_keysched(uint32_t *comp_skey, + const void *key, size_t key_len); + +/* + * Expand AES subkeys as produced by br_aes_ct_keysched(), into + * a larger array suitable for br_aes_ct_bitslice_encrypt() and + * br_aes_ct_bitslice_decrypt(). + */ +void br_aes_ct_skey_expand(uint32_t *skey, + unsigned num_rounds, const uint32_t *comp_skey); + +/* + * For the ct64 implementation, the same bitslicing technique is used, + * but four instances are interleaved. First instance uses bits 0, 4, + * 8, 12,... of each word; second instance uses bits 1, 5, 9, 13,... + * and so on. + */ + +/* + * Perform bytewise orthogonalization of eight 64-bit words. Bytes + * of q0..q7 are spread over all words: for a byte x that occurs + * at rank i in q[j] (byte x uses bits 8*i to 8*i+7 in q[j]), the bit + * of rank k in x (0 <= k <= 7) goes to q[k] at rank 8*i+j. + * + * This operation is an involution. + */ +void br_aes_ct64_ortho(uint64_t *q); + +/* + * Interleave bytes for an AES input block. If input bytes are + * denoted 0123456789ABCDEF, and have been decoded with little-endian + * convention (w[0] contains 0123, with '3' being most significant; + * w[1] contains 4567, and so on), then output word q0 will be + * set to 08192A3B (again little-endian convention) and q1 will + * be set to 4C5D6E7F. + */ +void br_aes_ct64_interleave_in(uint64_t *q0, uint64_t *q1, const uint32_t *w); + +/* + * Perform the opposite of br_aes_ct64_interleave_in(). + */ +void br_aes_ct64_interleave_out(uint32_t *w, uint64_t q0, uint64_t q1); + +/* + * The AES S-box, as a bitsliced constant-time version. The input array + * consists in eight 64-bit words; 64 S-box instances are computed in + * parallel. Bits 0 to 7 of each S-box input (bit 0 is least significant) + * are spread over the words 0 to 7, at the same rank. + */ +void br_aes_ct64_bitslice_Sbox(uint64_t *q); + +/* + * Like br_aes_bitslice_Sbox(), but for the inverse S-box. + */ +void br_aes_ct64_bitslice_invSbox(uint64_t *q); + +/* + * Compute AES encryption on bitsliced data. Since input is stored on + * eight 64-bit words, four block encryptions are actually performed + * in parallel. + */ +void br_aes_ct64_bitslice_encrypt(unsigned num_rounds, + const uint64_t *skey, uint64_t *q); + +/* + * Compute AES decryption on bitsliced data. Since input is stored on + * eight 64-bit words, four block decryptions are actually performed + * in parallel. + */ +void br_aes_ct64_bitslice_decrypt(unsigned num_rounds, + const uint64_t *skey, uint64_t *q); + +/* + * AES key schedule, constant-time version. skey[] is filled with n+1 + * 128-bit subkeys, where n is the number of rounds (10 to 14, depending + * on key size). The number of rounds is returned. If the key size is + * invalid (not 16, 24 or 32), then 0 is returned. + */ +unsigned br_aes_ct64_keysched(uint64_t *comp_skey, + const void *key, size_t key_len); + +/* + * Expand AES subkeys as produced by br_aes_ct64_keysched(), into + * a larger array suitable for br_aes_ct64_bitslice_encrypt() and + * br_aes_ct64_bitslice_decrypt(). + */ +void br_aes_ct64_skey_expand(uint64_t *skey, + unsigned num_rounds, const uint64_t *comp_skey); + +/* + * Test support for AES-NI opcodes. + */ +int br_aes_x86ni_supported(void); + +/* + * AES key schedule, using x86 AES-NI instructions. This yields the + * subkeys in the encryption direction. Number of rounds is returned. + * Key size MUST be 16, 24 or 32 bytes; otherwise, 0 is returned. + */ +unsigned br_aes_x86ni_keysched_enc(unsigned char *skni, + const void *key, size_t len); + +/* + * AES key schedule, using x86 AES-NI instructions. This yields the + * subkeys in the decryption direction. Number of rounds is returned. + * Key size MUST be 16, 24 or 32 bytes; otherwise, 0 is returned. + */ +unsigned br_aes_x86ni_keysched_dec(unsigned char *skni, + const void *key, size_t len); + +/* + * Test support for AES POWER8 opcodes. + */ +int br_aes_pwr8_supported(void); + +/* + * AES key schedule, using POWER8 instructions. This yields the + * subkeys in the encryption direction. Number of rounds is returned. + * Key size MUST be 16, 24 or 32 bytes; otherwise, 0 is returned. + */ +unsigned br_aes_pwr8_keysched(unsigned char *skni, + const void *key, size_t len); + +/* ==================================================================== */ +/* + * RSA. + */ + +/* + * Apply proper PKCS#1 v1.5 padding (for signatures). 'hash_oid' is + * the encoded hash function OID, or NULL. + */ +uint32_t br_rsa_pkcs1_sig_pad(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + uint32_t n_bitlen, unsigned char *x); + +/* + * Check PKCS#1 v1.5 padding (for signatures). 'hash_oid' is the encoded + * hash function OID, or NULL. The provided 'sig' value is _after_ the + * modular exponentiation, i.e. it should be the padded hash. On + * success, the hashed message is extracted. + */ +uint32_t br_rsa_pkcs1_sig_unpad(const unsigned char *sig, size_t sig_len, + const unsigned char *hash_oid, size_t hash_len, + unsigned char *hash_out); + +/* + * Apply proper PSS padding. The 'x' buffer is output only: it + * receives the value that is to be exponentiated. + */ +uint32_t br_rsa_pss_sig_pad(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash, size_t salt_len, + uint32_t n_bitlen, unsigned char *x); + +/* + * Check PSS padding. The provided value is the one _after_ + * the modular exponentiation; it is modified by this function. + * This function infers the signature length from the public key + * size, i.e. it assumes that this has already been verified (as + * part of the exponentiation). + */ +uint32_t br_rsa_pss_sig_unpad( + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash, size_t salt_len, + const br_rsa_public_key *pk, unsigned char *x); + +/* + * Apply OAEP padding. Returned value is the actual padded string length, + * or zero on error. + */ +size_t br_rsa_oaep_pad(const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, const br_rsa_public_key *pk, + void *dst, size_t dst_nax_len, const void *src, size_t src_len); + +/* + * Unravel and check OAEP padding. If the padding is correct, then 1 is + * returned, '*len' is adjusted to the length of the message, and the + * data is moved to the start of the 'data' buffer. If the padding is + * incorrect, then 0 is returned and '*len' is untouched. Either way, + * the complete buffer contents are altered. + */ +uint32_t br_rsa_oaep_unpad(const br_hash_class *dig, + const void *label, size_t label_len, void *data, size_t *len); + +/* + * Compute MGF1 for a given seed, and XOR the output into the provided + * buffer. + */ +void br_mgf1_xor(void *data, size_t len, + const br_hash_class *dig, const void *seed, size_t seed_len); + +/* + * Inner function for RSA key generation; used by the "i31" and "i62" + * implementations. + */ +uint32_t br_rsa_i31_keygen_inner(const br_prng_class **rng, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp, br_i31_modpow_opt_type mp31); + +/* ==================================================================== */ +/* + * Elliptic curves. + */ + +/* + * Type for generic EC parameters: curve order (unsigned big-endian + * encoding) and encoded conventional generator. + */ +typedef struct { + int curve; + const unsigned char *order; + size_t order_len; + const unsigned char *generator; + size_t generator_len; +} br_ec_curve_def; + +extern const br_ec_curve_def br_secp256r1; +extern const br_ec_curve_def br_secp384r1; +extern const br_ec_curve_def br_secp521r1; + +/* + * For Curve25519, the advertised "order" really is 2^255-1, since the + * point multipliction function really works over arbitrary 255-bit + * scalars. This value is only meant as a hint for ECDH key generation; + * only ECDSA uses the exact curve order, and ECDSA is not used with + * that specific curve. + */ +extern const br_ec_curve_def br_curve25519; + +/* + * Decode some bytes as an i31 integer, with truncation (corresponding + * to the 'bits2int' operation in RFC 6979). The target ENCODED bit + * length is provided as last parameter. The resulting value will have + * this declared bit length, and consists the big-endian unsigned decoding + * of exactly that many bits in the source (capped at the source length). + */ +void br_ecdsa_i31_bits2int(uint32_t *x, + const void *src, size_t len, uint32_t ebitlen); + +/* + * Decode some bytes as an i15 integer, with truncation (corresponding + * to the 'bits2int' operation in RFC 6979). The target ENCODED bit + * length is provided as last parameter. The resulting value will have + * this declared bit length, and consists the big-endian unsigned decoding + * of exactly that many bits in the source (capped at the source length). + */ +void br_ecdsa_i15_bits2int(uint16_t *x, + const void *src, size_t len, uint32_t ebitlen); + +/* ==================================================================== */ +/* + * ASN.1 support functions. + */ + +/* + * A br_asn1_uint structure contains encoding information about an + * INTEGER nonnegative value: pointer to the integer contents (unsigned + * big-endian representation), length of the integer contents, + * and length of the encoded value. The data shall have minimal length: + * - If the integer value is zero, then 'len' must be zero. + * - If the integer value is not zero, then data[0] must be non-zero. + * + * Under these conditions, 'asn1len' is necessarily equal to either len + * or len+1. + */ +typedef struct { + const unsigned char *data; + size_t len; + size_t asn1len; +} br_asn1_uint; + +/* + * Given an encoded integer (unsigned big-endian, with possible leading + * bytes of value 0), returned the "prepared INTEGER" structure. + */ +br_asn1_uint br_asn1_uint_prepare(const void *xdata, size_t xlen); + +/* + * Encode an ASN.1 length. The length of the encoded length is returned. + * If 'dest' is NULL, then no encoding is performed, but the length of + * the encoded length is still computed and returned. + */ +size_t br_asn1_encode_length(void *dest, size_t len); + +/* + * Convenient macro for computing lengths of lengths. + */ +#define len_of_len(len) br_asn1_encode_length(NULL, len) + +/* + * Encode a (prepared) ASN.1 INTEGER. The encoded length is returned. + * If 'dest' is NULL, then no encoding is performed, but the length of + * the encoded integer is still computed and returned. + */ +size_t br_asn1_encode_uint(void *dest, br_asn1_uint pp); + +/* + * Get the OID that identifies an elliptic curve. Returned value is + * the DER-encoded OID, with the length (always one byte) but without + * the tag. Thus, the first byte of the returned buffer contains the + * number of subsequent bytes in the value. If the curve is not + * recognised, NULL is returned. + */ +const unsigned char *br_get_curve_OID(int curve); + +/* + * Inner function for EC private key encoding. This is equivalent to + * the API function br_encode_ec_raw_der(), except for an extra + * parameter: if 'include_curve_oid' is zero, then the curve OID is + * _not_ included in the output blob (this is for PKCS#8 support). + */ +size_t br_encode_ec_raw_der_inner(void *dest, + const br_ec_private_key *sk, const br_ec_public_key *pk, + int include_curve_oid); + +/* ==================================================================== */ +/* + * SSL/TLS support functions. + */ + +/* + * Record types. + */ +#define BR_SSL_CHANGE_CIPHER_SPEC 20 +#define BR_SSL_ALERT 21 +#define BR_SSL_HANDSHAKE 22 +#define BR_SSL_APPLICATION_DATA 23 + +/* + * Handshake message types. + */ +#define BR_SSL_HELLO_REQUEST 0 +#define BR_SSL_CLIENT_HELLO 1 +#define BR_SSL_SERVER_HELLO 2 +#define BR_SSL_CERTIFICATE 11 +#define BR_SSL_SERVER_KEY_EXCHANGE 12 +#define BR_SSL_CERTIFICATE_REQUEST 13 +#define BR_SSL_SERVER_HELLO_DONE 14 +#define BR_SSL_CERTIFICATE_VERIFY 15 +#define BR_SSL_CLIENT_KEY_EXCHANGE 16 +#define BR_SSL_FINISHED 20 + +/* + * Alert levels. + */ +#define BR_LEVEL_WARNING 1 +#define BR_LEVEL_FATAL 2 + +/* + * Low-level I/O state. + */ +#define BR_IO_FAILED 0 +#define BR_IO_IN 1 +#define BR_IO_OUT 2 +#define BR_IO_INOUT 3 + +/* + * Mark a SSL engine as failed. The provided error code is recorded if + * the engine was not already marked as failed. If 'err' is 0, then the + * engine is marked as closed (without error). + */ +void br_ssl_engine_fail(br_ssl_engine_context *cc, int err); + +/* + * Test whether the engine is closed (normally or as a failure). + */ +static __inline int +br_ssl_engine_closed(const br_ssl_engine_context *cc) +{ + return cc->iomode == BR_IO_FAILED; +} + +/* + * Configure a new maximum fragment length. If possible, the maximum + * length for outgoing records is immediately adjusted (if there are + * not already too many buffered bytes for that). + */ +void br_ssl_engine_new_max_frag_len( + br_ssl_engine_context *rc, unsigned max_frag_len); + +/* + * Test whether the current incoming record has been fully received + * or not. This functions returns 0 only if a complete record header + * has been received, but some of the (possibly encrypted) payload + * has not yet been obtained. + */ +int br_ssl_engine_recvrec_finished(const br_ssl_engine_context *rc); + +/* + * Flush the current record (if not empty). This is meant to be called + * from the handshake processor only. + */ +void br_ssl_engine_flush_record(br_ssl_engine_context *cc); + +/* + * Test whether there is some accumulated payload to send. + */ +static __inline int +br_ssl_engine_has_pld_to_send(const br_ssl_engine_context *rc) +{ + return rc->oxa != rc->oxb && rc->oxa != rc->oxc; +} + +/* + * Initialize RNG in engine. Returned value is 1 on success, 0 on error. + * This function will try to use the OS-provided RNG, if available. If + * there is no OS-provided RNG, or if it failed, and no entropy was + * injected by the caller, then a failure will be reported. On error, + * the context error code is set. + */ +int br_ssl_engine_init_rand(br_ssl_engine_context *cc); + +/* + * Reset the handshake-related parts of the engine. + */ +void br_ssl_engine_hs_reset(br_ssl_engine_context *cc, + void (*hsinit)(void *), void (*hsrun)(void *)); + +/* + * Get the PRF to use for this context, for the provided PRF hash + * function ID. + */ +br_tls_prf_impl br_ssl_engine_get_PRF(br_ssl_engine_context *cc, int prf_id); + +/* + * Consume the provided pre-master secret and compute the corresponding + * master secret. The 'prf_id' is the ID of the hash function to use + * with the TLS 1.2 PRF (ignored if the version is TLS 1.0 or 1.1). + */ +void br_ssl_engine_compute_master(br_ssl_engine_context *cc, + int prf_id, const void *pms, size_t len); + +/* + * Switch to CBC decryption for incoming records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF (ignored if not TLS 1.2+) + * mac_id id of hash function for HMAC + * bc_impl block cipher implementation (CBC decryption) + * cipher_key_len block cipher key length (in bytes) + */ +void br_ssl_engine_switch_cbc_in(br_ssl_engine_context *cc, + int is_client, int prf_id, int mac_id, + const br_block_cbcdec_class *bc_impl, size_t cipher_key_len); + +/* + * Switch to CBC encryption for outgoing records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF (ignored if not TLS 1.2+) + * mac_id id of hash function for HMAC + * bc_impl block cipher implementation (CBC encryption) + * cipher_key_len block cipher key length (in bytes) + */ +void br_ssl_engine_switch_cbc_out(br_ssl_engine_context *cc, + int is_client, int prf_id, int mac_id, + const br_block_cbcenc_class *bc_impl, size_t cipher_key_len); + +/* + * Switch to GCM decryption for incoming records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF + * bc_impl block cipher implementation (CTR) + * cipher_key_len block cipher key length (in bytes) + */ +void br_ssl_engine_switch_gcm_in(br_ssl_engine_context *cc, + int is_client, int prf_id, + const br_block_ctr_class *bc_impl, size_t cipher_key_len); + +/* + * Switch to GCM encryption for outgoing records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF + * bc_impl block cipher implementation (CTR) + * cipher_key_len block cipher key length (in bytes) + */ +void br_ssl_engine_switch_gcm_out(br_ssl_engine_context *cc, + int is_client, int prf_id, + const br_block_ctr_class *bc_impl, size_t cipher_key_len); + +/* + * Switch to ChaCha20+Poly1305 decryption for incoming records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF + */ +void br_ssl_engine_switch_chapol_in(br_ssl_engine_context *cc, + int is_client, int prf_id); + +/* + * Switch to ChaCha20+Poly1305 encryption for outgoing records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF + */ +void br_ssl_engine_switch_chapol_out(br_ssl_engine_context *cc, + int is_client, int prf_id); + +/* + * Switch to CCM decryption for incoming records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF + * bc_impl block cipher implementation (CTR+CBC) + * cipher_key_len block cipher key length (in bytes) + * tag_len tag length (in bytes) + */ +void br_ssl_engine_switch_ccm_in(br_ssl_engine_context *cc, + int is_client, int prf_id, + const br_block_ctrcbc_class *bc_impl, + size_t cipher_key_len, size_t tag_len); + +/* + * Switch to GCM encryption for outgoing records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF + * bc_impl block cipher implementation (CTR+CBC) + * cipher_key_len block cipher key length (in bytes) + * tag_len tag length (in bytes) + */ +void br_ssl_engine_switch_ccm_out(br_ssl_engine_context *cc, + int is_client, int prf_id, + const br_block_ctrcbc_class *bc_impl, + size_t cipher_key_len, size_t tag_len); + +/* + * Calls to T0-generated code. + */ +void br_ssl_hs_client_init_main(void *ctx); +void br_ssl_hs_client_run(void *ctx); +void br_ssl_hs_server_init_main(void *ctx); +void br_ssl_hs_server_run(void *ctx); + +/* + * Get the hash function to use for signatures, given a bit mask of + * supported hash functions. This implements a strict choice order + * (namely SHA-256, SHA-384, SHA-512, SHA-224, SHA-1). If the mask + * does not document support of any of these hash functions, then this + * functions returns 0. + */ +int br_ssl_choose_hash(unsigned bf); + +/* ==================================================================== */ + +/* + * PowerPC / POWER assembly stuff. The special BR_POWER_ASM_MACROS macro + * must be defined before including this file; this is done by source + * files that use some inline assembly for PowerPC / POWER machines. + */ + +#if BR_POWER_ASM_MACROS + +#define lxvw4x(xt, ra, rb) lxvw4x_(xt, ra, rb) +#define stxvw4x(xt, ra, rb) stxvw4x_(xt, ra, rb) + +#define bdnz(foo) bdnz_(foo) +#define bdz(foo) bdz_(foo) +#define beq(foo) beq_(foo) + +#define li(rx, value) li_(rx, value) +#define addi(rx, ra, imm) addi_(rx, ra, imm) +#define cmpldi(rx, imm) cmpldi_(rx, imm) +#define mtctr(rx) mtctr_(rx) +#define vspltb(vrt, vrb, uim) vspltb_(vrt, vrb, uim) +#define vspltw(vrt, vrb, uim) vspltw_(vrt, vrb, uim) +#define vspltisb(vrt, imm) vspltisb_(vrt, imm) +#define vspltisw(vrt, imm) vspltisw_(vrt, imm) +#define vrlw(vrt, vra, vrb) vrlw_(vrt, vra, vrb) +#define vsbox(vrt, vra) vsbox_(vrt, vra) +#define vxor(vrt, vra, vrb) vxor_(vrt, vra, vrb) +#define vand(vrt, vra, vrb) vand_(vrt, vra, vrb) +#define vsro(vrt, vra, vrb) vsro_(vrt, vra, vrb) +#define vsl(vrt, vra, vrb) vsl_(vrt, vra, vrb) +#define vsldoi(vt, va, vb, sh) vsldoi_(vt, va, vb, sh) +#define vsr(vrt, vra, vrb) vsr_(vrt, vra, vrb) +#define vaddcuw(vrt, vra, vrb) vaddcuw_(vrt, vra, vrb) +#define vadduwm(vrt, vra, vrb) vadduwm_(vrt, vra, vrb) +#define vsububm(vrt, vra, vrb) vsububm_(vrt, vra, vrb) +#define vsubuwm(vrt, vra, vrb) vsubuwm_(vrt, vra, vrb) +#define vsrw(vrt, vra, vrb) vsrw_(vrt, vra, vrb) +#define vcipher(vt, va, vb) vcipher_(vt, va, vb) +#define vcipherlast(vt, va, vb) vcipherlast_(vt, va, vb) +#define vncipher(vt, va, vb) vncipher_(vt, va, vb) +#define vncipherlast(vt, va, vb) vncipherlast_(vt, va, vb) +#define vperm(vt, va, vb, vc) vperm_(vt, va, vb, vc) +#define vpmsumd(vt, va, vb) vpmsumd_(vt, va, vb) +#define xxpermdi(vt, va, vb, d) xxpermdi_(vt, va, vb, d) + +#define lxvw4x_(xt, ra, rb) "\tlxvw4x\t" #xt "," #ra "," #rb "\n" +#define stxvw4x_(xt, ra, rb) "\tstxvw4x\t" #xt "," #ra "," #rb "\n" + +#define label(foo) #foo "%=:\n" +#define bdnz_(foo) "\tbdnz\t" #foo "%=\n" +#define bdz_(foo) "\tbdz\t" #foo "%=\n" +#define beq_(foo) "\tbeq\t" #foo "%=\n" + +#define li_(rx, value) "\tli\t" #rx "," #value "\n" +#define addi_(rx, ra, imm) "\taddi\t" #rx "," #ra "," #imm "\n" +#define cmpldi_(rx, imm) "\tcmpldi\t" #rx "," #imm "\n" +#define mtctr_(rx) "\tmtctr\t" #rx "\n" +#define vspltb_(vrt, vrb, uim) "\tvspltb\t" #vrt "," #vrb "," #uim "\n" +#define vspltw_(vrt, vrb, uim) "\tvspltw\t" #vrt "," #vrb "," #uim "\n" +#define vspltisb_(vrt, imm) "\tvspltisb\t" #vrt "," #imm "\n" +#define vspltisw_(vrt, imm) "\tvspltisw\t" #vrt "," #imm "\n" +#define vrlw_(vrt, vra, vrb) "\tvrlw\t" #vrt "," #vra "," #vrb "\n" +#define vsbox_(vrt, vra) "\tvsbox\t" #vrt "," #vra "\n" +#define vxor_(vrt, vra, vrb) "\tvxor\t" #vrt "," #vra "," #vrb "\n" +#define vand_(vrt, vra, vrb) "\tvand\t" #vrt "," #vra "," #vrb "\n" +#define vsro_(vrt, vra, vrb) "\tvsro\t" #vrt "," #vra "," #vrb "\n" +#define vsl_(vrt, vra, vrb) "\tvsl\t" #vrt "," #vra "," #vrb "\n" +#define vsldoi_(vt, va, vb, sh) "\tvsldoi\t" #vt "," #va "," #vb "," #sh "\n" +#define vsr_(vrt, vra, vrb) "\tvsr\t" #vrt "," #vra "," #vrb "\n" +#define vaddcuw_(vrt, vra, vrb) "\tvaddcuw\t" #vrt "," #vra "," #vrb "\n" +#define vadduwm_(vrt, vra, vrb) "\tvadduwm\t" #vrt "," #vra "," #vrb "\n" +#define vsububm_(vrt, vra, vrb) "\tvsububm\t" #vrt "," #vra "," #vrb "\n" +#define vsubuwm_(vrt, vra, vrb) "\tvsubuwm\t" #vrt "," #vra "," #vrb "\n" +#define vsrw_(vrt, vra, vrb) "\tvsrw\t" #vrt "," #vra "," #vrb "\n" +#define vcipher_(vt, va, vb) "\tvcipher\t" #vt "," #va "," #vb "\n" +#define vcipherlast_(vt, va, vb) "\tvcipherlast\t" #vt "," #va "," #vb "\n" +#define vncipher_(vt, va, vb) "\tvncipher\t" #vt "," #va "," #vb "\n" +#define vncipherlast_(vt, va, vb) "\tvncipherlast\t" #vt "," #va "," #vb "\n" +#define vperm_(vt, va, vb, vc) "\tvperm\t" #vt "," #va "," #vb "," #vc "\n" +#define vpmsumd_(vt, va, vb) "\tvpmsumd\t" #vt "," #va "," #vb "\n" +#define xxpermdi_(vt, va, vb, d) "\txxpermdi\t" #vt "," #va "," #vb "," #d "\n" + +#endif + +/* ==================================================================== */ +/* + * Special "activate intrinsics" code, needed for some compiler versions. + * This is defined at the end of this file, so that it won't impact any + * of the inline functions defined previously; and it is controlled by + * a specific macro defined in the caller code. + * + * Calling code conventions: + * + * - Caller must define BR_ENABLE_INTRINSICS before including "inner.h". + * - Functions that use intrinsics must be enclosed in an "enabled" + * region (between BR_TARGETS_X86_UP and BR_TARGETS_X86_DOWN). + * - Functions that use intrinsics must be tagged with the appropriate + * BR_TARGET(). + */ + +#if BR_ENABLE_INTRINSICS && (BR_GCC_4_4 || BR_CLANG_3_7 || BR_MSC_2005) + +/* + * x86 intrinsics (both 32-bit and 64-bit). + */ +#if BR_i386 || BR_amd64 + +/* + * On GCC before version 5.0, we need to use the pragma to enable the + * target options globally, because the 'target' function attribute + * appears to be unreliable. Before 4.6 we must also avoid the + * push_options / pop_options mechanism, because it tends to trigger + * some internal compiler errors. + */ +#if BR_GCC && !BR_GCC_5_0 +#if BR_GCC_4_6 +#define BR_TARGETS_X86_UP \ + _Pragma("GCC push_options") \ + _Pragma("GCC target(\"sse2,ssse3,sse4.1,aes,pclmul,rdrnd\")") +#define BR_TARGETS_X86_DOWN \ + _Pragma("GCC pop_options") +#else +#define BR_TARGETS_X86_UP \ + _Pragma("GCC target(\"sse2,ssse3,sse4.1,aes,pclmul\")") +#define BR_TARGETS_X86_DOWN +#endif +#pragma GCC diagnostic ignored "-Wpsabi" +#endif + +#if BR_CLANG && !BR_CLANG_3_8 +#undef __SSE2__ +#undef __SSE3__ +#undef __SSSE3__ +#undef __SSE4_1__ +#undef __AES__ +#undef __PCLMUL__ +#undef __RDRND__ +#define __SSE2__ 1 +#define __SSE3__ 1 +#define __SSSE3__ 1 +#define __SSE4_1__ 1 +#define __AES__ 1 +#define __PCLMUL__ 1 +#define __RDRND__ 1 +#endif + +#ifndef BR_TARGETS_X86_UP +#define BR_TARGETS_X86_UP +#endif +#ifndef BR_TARGETS_X86_DOWN +#define BR_TARGETS_X86_DOWN +#endif + +#if BR_GCC || BR_CLANG +BR_TARGETS_X86_UP +#include +#include +#define br_bswap32 __builtin_bswap32 +BR_TARGETS_X86_DOWN +#endif + +#if BR_MSC +#include +#include +#include +#define br_bswap32 _byteswap_ulong +#endif + +static __inline int +br_cpuid(uint32_t mask_eax, uint32_t mask_ebx, + uint32_t mask_ecx, uint32_t mask_edx) +{ +#if BR_GCC || BR_CLANG + unsigned eax, ebx, ecx, edx; + + if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) { + if ((eax & mask_eax) == mask_eax + && (ebx & mask_ebx) == mask_ebx + && (ecx & mask_ecx) == mask_ecx + && (edx & mask_edx) == mask_edx) + { + return 1; + } + } +#elif BR_MSC + int info[4]; + + __cpuid(info, 1); + if (((uint32_t)info[0] & mask_eax) == mask_eax + && ((uint32_t)info[1] & mask_ebx) == mask_ebx + && ((uint32_t)info[2] & mask_ecx) == mask_ecx + && ((uint32_t)info[3] & mask_edx) == mask_edx) + { + return 1; + } +#endif + return 0; +} + +#endif + +#endif + +/* ==================================================================== */ + +#endif diff --git a/BearSSL-OG/libbearssl/src/int/i15_add.c b/BearSSL-OG/libbearssl/src/int/i15_add.c new file mode 100644 index 0000000..97e29b8 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_add.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i15_add(uint16_t *a, const uint16_t *b, uint32_t ctl) +{ + uint32_t cc; + size_t u, m; + + cc = 0; + m = (a[0] + 31) >> 4; + for (u = 1; u < m; u ++) { + uint32_t aw, bw, naw; + + aw = a[u]; + bw = b[u]; + naw = aw + bw + cc; + cc = naw >> 15; + a[u] = MUX(ctl, naw & 0x7FFF, aw); + } + return cc; +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_bitlen.c b/BearSSL-OG/libbearssl/src/int/i15_bitlen.c new file mode 100644 index 0000000..ad74467 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_bitlen.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i15_bit_length(uint16_t *x, size_t xlen) +{ + uint32_t tw, twk; + + tw = 0; + twk = 0; + while (xlen -- > 0) { + uint32_t w, c; + + c = EQ(tw, 0); + w = x[xlen]; + tw = MUX(c, w, tw); + twk = MUX(c, (uint32_t)xlen, twk); + } + return (twk << 4) + BIT_LENGTH(tw); +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_decmod.c b/BearSSL-OG/libbearssl/src/int/i15_decmod.c new file mode 100644 index 0000000..6076c57 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_decmod.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i15_decode_mod(uint16_t *x, const void *src, size_t len, const uint16_t *m) +{ + /* + * Two-pass algorithm: in the first pass, we determine whether the + * value fits; in the second pass, we do the actual write. + * + * During the first pass, 'r' contains the comparison result so + * far: + * 0x00000000 value is equal to the modulus + * 0x00000001 value is greater than the modulus + * 0xFFFFFFFF value is lower than the modulus + * + * Since we iterate starting with the least significant bytes (at + * the end of src[]), each new comparison overrides the previous + * except when the comparison yields 0 (equal). + * + * During the second pass, 'r' is either 0xFFFFFFFF (value fits) + * or 0x00000000 (value does not fit). + * + * We must iterate over all bytes of the source, _and_ possibly + * some extra virtual bytes (with value 0) so as to cover the + * complete modulus as well. We also add 4 such extra bytes beyond + * the modulus length because it then guarantees that no accumulated + * partial word remains to be processed. + */ + const unsigned char *buf; + size_t mlen, tlen; + int pass; + uint32_t r; + + buf = src; + mlen = (m[0] + 15) >> 4; + tlen = (mlen << 1); + if (tlen < len) { + tlen = len; + } + tlen += 4; + r = 0; + for (pass = 0; pass < 2; pass ++) { + size_t u, v; + uint32_t acc; + int acc_len; + + v = 1; + acc = 0; + acc_len = 0; + for (u = 0; u < tlen; u ++) { + uint32_t b; + + if (u < len) { + b = buf[len - 1 - u]; + } else { + b = 0; + } + acc |= (b << acc_len); + acc_len += 8; + if (acc_len >= 15) { + uint32_t xw; + + xw = acc & (uint32_t)0x7FFF; + acc_len -= 15; + acc = b >> (8 - acc_len); + if (v <= mlen) { + if (pass) { + x[v] = r & xw; + } else { + uint32_t cc; + + cc = (uint32_t)CMP(xw, m[v]); + r = MUX(EQ(cc, 0), r, cc); + } + } else { + if (!pass) { + r = MUX(EQ(xw, 0), r, 1); + } + } + v ++; + } + } + + /* + * When we reach this point at the end of the first pass: + * r is either 0, 1 or -1; we want to set r to 0 if it + * is equal to 0 or 1, and leave it to -1 otherwise. + * + * When we reach this point at the end of the second pass: + * r is either 0 or -1; we want to leave that value + * untouched. This is a subcase of the previous. + */ + r >>= 1; + r |= (r << 1); + } + + x[0] = m[0]; + return r & (uint32_t)1; +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_decode.c b/BearSSL-OG/libbearssl/src/int/i15_decode.c new file mode 100644 index 0000000..fc2c0be --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_decode.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i15_decode(uint16_t *x, const void *src, size_t len) +{ + const unsigned char *buf; + size_t v; + uint32_t acc; + int acc_len; + + buf = src; + v = 1; + acc = 0; + acc_len = 0; + while (len -- > 0) { + uint32_t b; + + b = buf[len]; + acc |= (b << acc_len); + acc_len += 8; + if (acc_len >= 15) { + x[v ++] = acc & 0x7FFF; + acc_len -= 15; + acc >>= 15; + } + } + if (acc_len != 0) { + x[v ++] = acc; + } + x[0] = br_i15_bit_length(x + 1, v - 1); +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_decred.c b/BearSSL-OG/libbearssl/src/int/i15_decred.c new file mode 100644 index 0000000..81e7dd1 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_decred.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i15_decode_reduce(uint16_t *x, + const void *src, size_t len, const uint16_t *m) +{ + uint32_t m_ebitlen, m_rbitlen; + size_t mblen, k; + const unsigned char *buf; + uint32_t acc; + int acc_len; + + /* + * Get the encoded bit length. + */ + m_ebitlen = m[0]; + + /* + * Special case for an invalid (null) modulus. + */ + if (m_ebitlen == 0) { + x[0] = 0; + return; + } + + /* + * Clear the destination. + */ + br_i15_zero(x, m_ebitlen); + + /* + * First decode directly as many bytes as possible. This requires + * computing the actual bit length. + */ + m_rbitlen = m_ebitlen >> 4; + m_rbitlen = (m_ebitlen & 15) + (m_rbitlen << 4) - m_rbitlen; + mblen = (m_rbitlen + 7) >> 3; + k = mblen - 1; + if (k >= len) { + br_i15_decode(x, src, len); + x[0] = m_ebitlen; + return; + } + buf = src; + br_i15_decode(x, buf, k); + x[0] = m_ebitlen; + + /* + * Input remaining bytes, using 15-bit words. + */ + acc = 0; + acc_len = 0; + while (k < len) { + uint32_t v; + + v = buf[k ++]; + acc = (acc << 8) | v; + acc_len += 8; + if (acc_len >= 15) { + br_i15_muladd_small(x, acc >> (acc_len - 15), m); + acc_len -= 15; + acc &= ~((uint32_t)-1 << acc_len); + } + } + + /* + * We may have some bits accumulated. We then perform a shift to + * be able to inject these bits as a full 15-bit word. + */ + if (acc_len != 0) { + acc = (acc | (x[1] << acc_len)) & 0x7FFF; + br_i15_rshift(x, 15 - acc_len); + br_i15_muladd_small(x, acc, m); + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_encode.c b/BearSSL-OG/libbearssl/src/int/i15_encode.c new file mode 100644 index 0000000..50668f4 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_encode.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i15_encode(void *dst, size_t len, const uint16_t *x) +{ + unsigned char *buf; + size_t u, xlen; + uint32_t acc; + int acc_len; + + xlen = (x[0] + 15) >> 4; + if (xlen == 0) { + memset(dst, 0, len); + return; + } + u = 1; + acc = 0; + acc_len = 0; + buf = dst; + while (len -- > 0) { + if (acc_len < 8) { + if (u <= xlen) { + acc += (uint32_t)x[u ++] << acc_len; + } + acc_len += 15; + } + buf[len] = (unsigned char)acc; + acc >>= 8; + acc_len -= 8; + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_fmont.c b/BearSSL-OG/libbearssl/src/int/i15_fmont.c new file mode 100644 index 0000000..3450b72 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_fmont.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i15_from_monty(uint16_t *x, const uint16_t *m, uint16_t m0i) +{ + size_t len, u, v; + + len = (m[0] + 15) >> 4; + for (u = 0; u < len; u ++) { + uint32_t f, cc; + + f = MUL15(x[1], m0i) & 0x7FFF; + cc = 0; + for (v = 0; v < len; v ++) { + uint32_t z; + + z = (uint32_t)x[v + 1] + MUL15(f, m[v + 1]) + cc; + cc = z >> 15; + if (v != 0) { + x[v] = z & 0x7FFF; + } + } + x[len] = cc; + } + + /* + * We may have to do an extra subtraction, but only if the + * value in x[] is indeed greater than or equal to that of m[], + * which is why we must do two calls (first call computes the + * carry, second call performs the subtraction only if the carry + * is 0). + */ + br_i15_sub(x, m, NOT(br_i15_sub(x, m, 0))); +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_iszero.c b/BearSSL-OG/libbearssl/src/int/i15_iszero.c new file mode 100644 index 0000000..d4b6f10 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_iszero.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i15_iszero(const uint16_t *x) +{ + uint32_t z; + size_t u; + + z = 0; + for (u = (x[0] + 15) >> 4; u > 0; u --) { + z |= x[u]; + } + return ~(z | -z) >> 31; +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_moddiv.c b/BearSSL-OG/libbearssl/src/int/i15_moddiv.c new file mode 100644 index 0000000..45af756 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_moddiv.c @@ -0,0 +1,465 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * In this file, we handle big integers with a custom format, i.e. + * without the usual one-word header. Value is split into 15-bit words, + * each stored in a 16-bit slot (top bit is zero) in little-endian + * order. The length (in words) is provided explicitly. In some cases, + * the value can be negative (using two's complement representation). In + * some cases, the top word is allowed to have a 16th bit. + */ + +/* + * Negate big integer conditionally. The value consists of 'len' words, + * with 15 bits in each word (the top bit of each word should be 0, + * except possibly for the last word). If 'ctl' is 1, the negation is + * computed; otherwise, if 'ctl' is 0, then the value is unchanged. + */ +static void +cond_negate(uint16_t *a, size_t len, uint32_t ctl) +{ + size_t k; + uint32_t cc, xm; + + cc = ctl; + xm = 0x7FFF & -ctl; + for (k = 0; k < len; k ++) { + uint32_t aw; + + aw = a[k]; + aw = (aw ^ xm) + cc; + a[k] = aw & 0x7FFF; + cc = (aw >> 15) & 1; + } +} + +/* + * Finish modular reduction. Rules on input parameters: + * + * if neg = 1, then -m <= a < 0 + * if neg = 0, then 0 <= a < 2*m + * + * If neg = 0, then the top word of a[] may use 16 bits. + * + * Also, modulus m must be odd. + */ +static void +finish_mod(uint16_t *a, size_t len, const uint16_t *m, uint32_t neg) +{ + size_t k; + uint32_t cc, xm, ym; + + /* + * First pass: compare a (assumed nonnegative) with m. + */ + cc = 0; + for (k = 0; k < len; k ++) { + uint32_t aw, mw; + + aw = a[k]; + mw = m[k]; + cc = (aw - mw - cc) >> 31; + } + + /* + * At this point: + * if neg = 1, then we must add m (regardless of cc) + * if neg = 0 and cc = 0, then we must subtract m + * if neg = 0 and cc = 1, then we must do nothing + */ + xm = 0x7FFF & -neg; + ym = -(neg | (1 - cc)); + cc = neg; + for (k = 0; k < len; k ++) { + uint32_t aw, mw; + + aw = a[k]; + mw = (m[k] ^ xm) & ym; + aw = aw - mw - cc; + a[k] = aw & 0x7FFF; + cc = aw >> 31; + } +} + +/* + * Compute: + * a <- (a*pa+b*pb)/(2^15) + * b <- (a*qa+b*qb)/(2^15) + * The division is assumed to be exact (i.e. the low word is dropped). + * If the final a is negative, then it is negated. Similarly for b. + * Returned value is the combination of two bits: + * bit 0: 1 if a had to be negated, 0 otherwise + * bit 1: 1 if b had to be negated, 0 otherwise + * + * Factors pa, pb, qa and qb must be at most 2^15 in absolute value. + * Source integers a and b must be nonnegative; top word is not allowed + * to contain an extra 16th bit. + */ +static uint32_t +co_reduce(uint16_t *a, uint16_t *b, size_t len, + int32_t pa, int32_t pb, int32_t qa, int32_t qb) +{ + size_t k; + int32_t cca, ccb; + uint32_t nega, negb; + + cca = 0; + ccb = 0; + for (k = 0; k < len; k ++) { + uint32_t wa, wb, za, zb; + uint16_t tta, ttb; + + /* + * Since: + * |pa| <= 2^15 + * |pb| <= 2^15 + * 0 <= wa <= 2^15 - 1 + * 0 <= wb <= 2^15 - 1 + * |cca| <= 2^16 - 1 + * Then: + * |za| <= (2^15-1)*(2^16) + (2^16-1) = 2^31 - 1 + * + * Thus, the new value of cca is such that |cca| <= 2^16 - 1. + * The same applies to ccb. + */ + wa = a[k]; + wb = b[k]; + za = wa * (uint32_t)pa + wb * (uint32_t)pb + (uint32_t)cca; + zb = wa * (uint32_t)qa + wb * (uint32_t)qb + (uint32_t)ccb; + if (k > 0) { + a[k - 1] = za & 0x7FFF; + b[k - 1] = zb & 0x7FFF; + } + tta = za >> 15; + ttb = zb >> 15; + cca = *(int16_t *)&tta; + ccb = *(int16_t *)&ttb; + } + a[len - 1] = (uint16_t)cca; + b[len - 1] = (uint16_t)ccb; + nega = (uint32_t)cca >> 31; + negb = (uint32_t)ccb >> 31; + cond_negate(a, len, nega); + cond_negate(b, len, negb); + return nega | (negb << 1); +} + +/* + * Compute: + * a <- (a*pa+b*pb)/(2^15) mod m + * b <- (a*qa+b*qb)/(2^15) mod m + * + * m0i is equal to -1/m[0] mod 2^15. + * + * Factors pa, pb, qa and qb must be at most 2^15 in absolute value. + * Source integers a and b must be nonnegative; top word is not allowed + * to contain an extra 16th bit. + */ +static void +co_reduce_mod(uint16_t *a, uint16_t *b, size_t len, + int32_t pa, int32_t pb, int32_t qa, int32_t qb, + const uint16_t *m, uint16_t m0i) +{ + size_t k; + int32_t cca, ccb, fa, fb; + + cca = 0; + ccb = 0; + fa = ((a[0] * (uint32_t)pa + b[0] * (uint32_t)pb) * m0i) & 0x7FFF; + fb = ((a[0] * (uint32_t)qa + b[0] * (uint32_t)qb) * m0i) & 0x7FFF; + for (k = 0; k < len; k ++) { + uint32_t wa, wb, za, zb; + uint32_t tta, ttb; + + /* + * In this loop, carries 'cca' and 'ccb' always fit on + * 17 bits (in absolute value). + */ + wa = a[k]; + wb = b[k]; + za = wa * (uint32_t)pa + wb * (uint32_t)pb + + m[k] * (uint32_t)fa + (uint32_t)cca; + zb = wa * (uint32_t)qa + wb * (uint32_t)qb + + m[k] * (uint32_t)fb + (uint32_t)ccb; + if (k > 0) { + a[k - 1] = za & 0x7FFF; + b[k - 1] = zb & 0x7FFF; + } + + /* + * The XOR-and-sub construction below does an arithmetic + * right shift in a portable way (technically, right-shifting + * a negative signed value is implementation-defined in C). + */ +#define M ((uint32_t)1 << 16) + tta = za >> 15; + ttb = zb >> 15; + tta = (tta ^ M) - M; + ttb = (ttb ^ M) - M; + cca = *(int32_t *)&tta; + ccb = *(int32_t *)&ttb; +#undef M + } + a[len - 1] = (uint32_t)cca; + b[len - 1] = (uint32_t)ccb; + + /* + * At this point: + * -m <= a < 2*m + * -m <= b < 2*m + * (this is a case of Montgomery reduction) + * The top word of 'a' and 'b' may have a 16-th bit set. + * We may have to add or subtract the modulus. + */ + finish_mod(a, len, m, (uint32_t)cca >> 31); + finish_mod(b, len, m, (uint32_t)ccb >> 31); +} + +/* see inner.h */ +uint32_t +br_i15_moddiv(uint16_t *x, const uint16_t *y, const uint16_t *m, uint16_t m0i, + uint16_t *t) +{ + /* + * Algorithm is an extended binary GCD. We maintain four values + * a, b, u and v, with the following invariants: + * + * a * x = y * u mod m + * b * x = y * v mod m + * + * Starting values are: + * + * a = y + * b = m + * u = x + * v = 0 + * + * The formal definition of the algorithm is a sequence of steps: + * + * - If a is even, then a <- a/2 and u <- u/2 mod m. + * - Otherwise, if b is even, then b <- b/2 and v <- v/2 mod m. + * - Otherwise, if a > b, then a <- (a-b)/2 and u <- (u-v)/2 mod m. + * - Otherwise, b <- (b-a)/2 and v <- (v-u)/2 mod m. + * + * Algorithm stops when a = b. At that point, they both are equal + * to GCD(y,m); the modular division succeeds if that value is 1. + * The result of the modular division is then u (or v: both are + * equal at that point). + * + * Each step makes either a or b shrink by at least one bit; hence, + * if m has bit length k bits, then 2k-2 steps are sufficient. + * + * + * Though complexity is quadratic in the size of m, the bit-by-bit + * processing is not very efficient. We can speed up processing by + * remarking that the decisions are taken based only on observation + * of the top and low bits of a and b. + * + * In the loop below, at each iteration, we use the two top words + * of a and b, and the low words of a and b, to compute reduction + * parameters pa, pb, qa and qb such that the new values for a + * and b are: + * + * a' = (a*pa + b*pb) / (2^15) + * b' = (a*qa + b*qb) / (2^15) + * + * the division being exact. + * + * Since the choices are based on the top words, they may be slightly + * off, requiring an optional correction: if a' < 0, then we replace + * pa with -pa, and pb with -pb. The total length of a and b is + * thus reduced by at least 14 bits at each iteration. + * + * The stopping conditions are still the same, though: when a + * and b become equal, they must be both odd (since m is odd, + * the GCD cannot be even), therefore the next operation is a + * subtraction, and one of the values becomes 0. At that point, + * nothing else happens, i.e. one value is stuck at 0, and the + * other one is the GCD. + */ + size_t len, k; + uint16_t *a, *b, *u, *v; + uint32_t num, r; + + len = (m[0] + 15) >> 4; + a = t; + b = a + len; + u = x + 1; + v = b + len; + memcpy(a, y + 1, len * sizeof *y); + memcpy(b, m + 1, len * sizeof *m); + memset(v, 0, len * sizeof *v); + + /* + * Loop below ensures that a and b are reduced by some bits each, + * for a total of at least 14 bits. + */ + for (num = ((m[0] - (m[0] >> 4)) << 1) + 14; num >= 14; num -= 14) { + size_t j; + uint32_t c0, c1; + uint32_t a0, a1, b0, b1; + uint32_t a_hi, b_hi, a_lo, b_lo; + int32_t pa, pb, qa, qb; + int i; + + /* + * Extract top words of a and b. If j is the highest + * index >= 1 such that a[j] != 0 or b[j] != 0, then we want + * (a[j] << 15) + a[j - 1], and (b[j] << 15) + b[j - 1]. + * If a and b are down to one word each, then we use a[0] + * and b[0]. + */ + c0 = (uint32_t)-1; + c1 = (uint32_t)-1; + a0 = 0; + a1 = 0; + b0 = 0; + b1 = 0; + j = len; + while (j -- > 0) { + uint32_t aw, bw; + + aw = a[j]; + bw = b[j]; + a0 ^= (a0 ^ aw) & c0; + a1 ^= (a1 ^ aw) & c1; + b0 ^= (b0 ^ bw) & c0; + b1 ^= (b1 ^ bw) & c1; + c1 = c0; + c0 &= (((aw | bw) + 0xFFFF) >> 16) - (uint32_t)1; + } + + /* + * If c1 = 0, then we grabbed two words for a and b. + * If c1 != 0 but c0 = 0, then we grabbed one word. It + * is not possible that c1 != 0 and c0 != 0, because that + * would mean that both integers are zero. + */ + a1 |= a0 & c1; + a0 &= ~c1; + b1 |= b0 & c1; + b0 &= ~c1; + a_hi = (a0 << 15) + a1; + b_hi = (b0 << 15) + b1; + a_lo = a[0]; + b_lo = b[0]; + + /* + * Compute reduction factors: + * + * a' = a*pa + b*pb + * b' = a*qa + b*qb + * + * such that a' and b' are both multiple of 2^15, but are + * only marginally larger than a and b. + */ + pa = 1; + pb = 0; + qa = 0; + qb = 1; + for (i = 0; i < 15; i ++) { + /* + * At each iteration: + * + * a <- (a-b)/2 if: a is odd, b is odd, a_hi > b_hi + * b <- (b-a)/2 if: a is odd, b is odd, a_hi <= b_hi + * a <- a/2 if: a is even + * b <- b/2 if: a is odd, b is even + * + * We multiply a_lo and b_lo by 2 at each + * iteration, thus a division by 2 really is a + * non-multiplication by 2. + */ + uint32_t r, oa, ob, cAB, cBA, cA; + + /* + * cAB = 1 if b must be subtracted from a + * cBA = 1 if a must be subtracted from b + * cA = 1 if a is divided by 2, 0 otherwise + * + * Rules: + * + * cAB and cBA cannot be both 1. + * if a is not divided by 2, b is. + */ + r = GT(a_hi, b_hi); + oa = (a_lo >> i) & 1; + ob = (b_lo >> i) & 1; + cAB = oa & ob & r; + cBA = oa & ob & NOT(r); + cA = cAB | NOT(oa); + + /* + * Conditional subtractions. + */ + a_lo -= b_lo & -cAB; + a_hi -= b_hi & -cAB; + pa -= qa & -(int32_t)cAB; + pb -= qb & -(int32_t)cAB; + b_lo -= a_lo & -cBA; + b_hi -= a_hi & -cBA; + qa -= pa & -(int32_t)cBA; + qb -= pb & -(int32_t)cBA; + + /* + * Shifting. + */ + a_lo += a_lo & (cA - 1); + pa += pa & ((int32_t)cA - 1); + pb += pb & ((int32_t)cA - 1); + a_hi ^= (a_hi ^ (a_hi >> 1)) & -cA; + b_lo += b_lo & -cA; + qa += qa & -(int32_t)cA; + qb += qb & -(int32_t)cA; + b_hi ^= (b_hi ^ (b_hi >> 1)) & (cA - 1); + } + + /* + * Replace a and b with new values a' and b'. + */ + r = co_reduce(a, b, len, pa, pb, qa, qb); + pa -= pa * ((r & 1) << 1); + pb -= pb * ((r & 1) << 1); + qa -= qa * (r & 2); + qb -= qb * (r & 2); + co_reduce_mod(u, v, len, pa, pb, qa, qb, m + 1, m0i); + } + + /* + * Now one of the arrays should be 0, and the other contains + * the GCD. If a is 0, then u is 0 as well, and v contains + * the division result. + * Result is correct if and only if GCD is 1. + */ + r = (a[0] | b[0]) ^ 1; + u[0] |= v[0]; + for (k = 1; k < len; k ++) { + r |= a[k] | b[k]; + u[k] |= v[k]; + } + return EQ0(r); +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_modpow.c b/BearSSL-OG/libbearssl/src/int/i15_modpow.c new file mode 100644 index 0000000..9bf304e --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_modpow.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i15_modpow(uint16_t *x, + const unsigned char *e, size_t elen, + const uint16_t *m, uint16_t m0i, uint16_t *t1, uint16_t *t2) +{ + size_t mlen; + unsigned k; + + mlen = ((m[0] + 31) >> 4) * sizeof m[0]; + memcpy(t1, x, mlen); + br_i15_to_monty(t1, m); + br_i15_zero(x, m[0]); + x[1] = 1; + for (k = 0; k < ((unsigned)elen << 3); k ++) { + uint32_t ctl; + + ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1; + br_i15_montymul(t2, x, t1, m, m0i); + CCOPY(ctl, x, t2, mlen); + br_i15_montymul(t2, t1, t1, m, m0i); + memcpy(t1, t2, mlen); + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_modpow2.c b/BearSSL-OG/libbearssl/src/int/i15_modpow2.c new file mode 100644 index 0000000..4b32118 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_modpow2.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i15_modpow_opt(uint16_t *x, + const unsigned char *e, size_t elen, + const uint16_t *m, uint16_t m0i, uint16_t *tmp, size_t twlen) +{ + size_t mlen, mwlen; + uint16_t *t1, *t2, *base; + size_t u, v; + uint32_t acc; + int acc_len, win_len; + + /* + * Get modulus size. + */ + mwlen = (m[0] + 31) >> 4; + mlen = mwlen * sizeof m[0]; + mwlen += (mwlen & 1); + t1 = tmp; + t2 = tmp + mwlen; + + /* + * Compute possible window size, with a maximum of 5 bits. + * When the window has size 1 bit, we use a specific code + * that requires only two temporaries. Otherwise, for a + * window of k bits, we need 2^k+1 temporaries. + */ + if (twlen < (mwlen << 1)) { + return 0; + } + for (win_len = 5; win_len > 1; win_len --) { + if ((((uint32_t)1 << win_len) + 1) * mwlen <= twlen) { + break; + } + } + + /* + * Everything is done in Montgomery representation. + */ + br_i15_to_monty(x, m); + + /* + * Compute window contents. If the window has size one bit only, + * then t2 is set to x; otherwise, t2[0] is left untouched, and + * t2[k] is set to x^k (for k >= 1). + */ + if (win_len == 1) { + memcpy(t2, x, mlen); + } else { + memcpy(t2 + mwlen, x, mlen); + base = t2 + mwlen; + for (u = 2; u < ((unsigned)1 << win_len); u ++) { + br_i15_montymul(base + mwlen, base, x, m, m0i); + base += mwlen; + } + } + + /* + * We need to set x to 1, in Montgomery representation. This can + * be done efficiently by setting the high word to 1, then doing + * one word-sized shift. + */ + br_i15_zero(x, m[0]); + x[(m[0] + 15) >> 4] = 1; + br_i15_muladd_small(x, 0, m); + + /* + * We process bits from most to least significant. At each + * loop iteration, we have acc_len bits in acc. + */ + acc = 0; + acc_len = 0; + while (acc_len > 0 || elen > 0) { + int i, k; + uint32_t bits; + + /* + * Get the next bits. + */ + k = win_len; + if (acc_len < win_len) { + if (elen > 0) { + acc = (acc << 8) | *e ++; + elen --; + acc_len += 8; + } else { + k = acc_len; + } + } + bits = (acc >> (acc_len - k)) & (((uint32_t)1 << k) - 1); + acc_len -= k; + + /* + * We could get exactly k bits. Compute k squarings. + */ + for (i = 0; i < k; i ++) { + br_i15_montymul(t1, x, x, m, m0i); + memcpy(x, t1, mlen); + } + + /* + * Window lookup: we want to set t2 to the window + * lookup value, assuming the bits are non-zero. If + * the window length is 1 bit only, then t2 is + * already set; otherwise, we do a constant-time lookup. + */ + if (win_len > 1) { + br_i15_zero(t2, m[0]); + base = t2 + mwlen; + for (u = 1; u < ((uint32_t)1 << k); u ++) { + uint32_t mask; + + mask = -EQ(u, bits); + for (v = 1; v < mwlen; v ++) { + t2[v] |= mask & base[v]; + } + base += mwlen; + } + } + + /* + * Multiply with the looked-up value. We keep the + * product only if the exponent bits are not all-zero. + */ + br_i15_montymul(t1, x, t2, m, m0i); + CCOPY(NEQ(bits, 0), x, t1, mlen); + } + + /* + * Convert back from Montgomery representation, and exit. + */ + br_i15_from_monty(x, m, m0i); + return 1; +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_montmul.c b/BearSSL-OG/libbearssl/src/int/i15_montmul.c new file mode 100644 index 0000000..e98bc32 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_montmul.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i15_montymul(uint16_t *d, const uint16_t *x, const uint16_t *y, + const uint16_t *m, uint16_t m0i) +{ + size_t len, len4, u, v; + uint32_t dh; + + len = (m[0] + 15) >> 4; + len4 = len & ~(size_t)3; + br_i15_zero(d, m[0]); + dh = 0; + for (u = 0; u < len; u ++) { + uint32_t f, xu, r, zh; + + xu = x[u + 1]; + f = MUL15((d[1] + MUL15(x[u + 1], y[1])) & 0x7FFF, m0i) + & 0x7FFF; +#if BR_ARMEL_CORTEXM_GCC + if (len4 != 0) { + uint16_t *limit; + + limit = d + len4; + asm volatile ( +"\n\ + @ carry: r=r2 \n\ + @ multipliers: xu=r3 f=r4 \n\ + @ base registers: d+v=r5 y+v=r6 m+v=r7 \n\ + @ r8 contains 0x7FFF \n\ + @ r9 contains d+len4 \n\ + ldr r0, %[limit] \n\ + ldr r3, %[xu] \n\ + mov r9, r0 \n\ + ldr r4, %[f] \n\ + eor r2, r2 \n\ + ldr r5, %[d] \n\ + sub r1, r2, #1 \n\ + ldr r6, %[y] \n\ + lsr r1, r1, #17 \n\ + ldr r7, %[m] \n\ + mov r8, r1 \n\ +loop%=: \n\ + ldrh r0, [r6, #2] \n\ + ldrh r1, [r7, #2] \n\ + mul r0, r3 \n\ + mul r1, r4 \n\ + add r2, r0, r2 \n\ + ldrh r0, [r5, #2] \n\ + add r2, r1, r2 \n\ + mov r1, r8 \n\ + add r2, r0, r2 \n\ + and r1, r2 \n\ + lsr r2, r2, #15 \n\ + strh r1, [r5, #0] \n\ + \n\ + ldrh r0, [r6, #4] \n\ + ldrh r1, [r7, #4] \n\ + mul r0, r3 \n\ + mul r1, r4 \n\ + add r2, r0, r2 \n\ + ldrh r0, [r5, #4] \n\ + add r2, r1, r2 \n\ + mov r1, r8 \n\ + add r2, r0, r2 \n\ + and r1, r2 \n\ + lsr r2, r2, #15 \n\ + strh r1, [r5, #2] \n\ + \n\ + ldrh r0, [r6, #6] \n\ + ldrh r1, [r7, #6] \n\ + mul r0, r3 \n\ + mul r1, r4 \n\ + add r2, r0, r2 \n\ + ldrh r0, [r5, #6] \n\ + add r2, r1, r2 \n\ + mov r1, r8 \n\ + add r2, r0, r2 \n\ + and r1, r2 \n\ + lsr r2, r2, #15 \n\ + strh r1, [r5, #4] \n\ + \n\ + ldrh r0, [r6, #8] \n\ + ldrh r1, [r7, #8] \n\ + mul r0, r3 \n\ + mul r1, r4 \n\ + add r2, r0, r2 \n\ + ldrh r0, [r5, #8] \n\ + add r2, r1, r2 \n\ + mov r1, r8 \n\ + add r2, r0, r2 \n\ + and r1, r2 \n\ + lsr r2, r2, #15 \n\ + strh r1, [r5, #6] \n\ + \n\ + add r5, r5, #8 \n\ + add r6, r6, #8 \n\ + add r7, r7, #8 \n\ + cmp r5, r9 \n\ + bne loop%= \n\ + \n\ + str r2, %[carry] \n\ +" +: [carry] "=m" (r) +: [xu] "m" (xu), [f] "m" (f), [d] "m" (d), [y] "m" (y), + [m] "m" (m), [limit] "m" (limit) +: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + } else { + r = 0; + } + v = len4; +#else + r = 0; + for (v = 0; v < len4; v += 4) { + uint32_t z; + + z = d[v + 1] + MUL15(xu, y[v + 1]) + + MUL15(f, m[v + 1]) + r; + r = z >> 15; + d[v + 0] = z & 0x7FFF; + z = d[v + 2] + MUL15(xu, y[v + 2]) + + MUL15(f, m[v + 2]) + r; + r = z >> 15; + d[v + 1] = z & 0x7FFF; + z = d[v + 3] + MUL15(xu, y[v + 3]) + + MUL15(f, m[v + 3]) + r; + r = z >> 15; + d[v + 2] = z & 0x7FFF; + z = d[v + 4] + MUL15(xu, y[v + 4]) + + MUL15(f, m[v + 4]) + r; + r = z >> 15; + d[v + 3] = z & 0x7FFF; + } +#endif + for (; v < len; v ++) { + uint32_t z; + + z = d[v + 1] + MUL15(xu, y[v + 1]) + + MUL15(f, m[v + 1]) + r; + r = z >> 15; + d[v + 0] = z & 0x7FFF; + } + + zh = dh + r; + d[len] = zh & 0x7FFF; + dh = zh >> 15; + } + + /* + * Restore the bit length (it was overwritten in the loop above). + */ + d[0] = m[0]; + + /* + * d[] may be greater than m[], but it is still lower than twice + * the modulus. + */ + br_i15_sub(d, m, NEQ(dh, 0) | NOT(br_i15_sub(d, m, 0))); +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_mulacc.c b/BearSSL-OG/libbearssl/src/int/i15_mulacc.c new file mode 100644 index 0000000..7a073ac --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_mulacc.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i15_mulacc(uint16_t *d, const uint16_t *a, const uint16_t *b) +{ + size_t alen, blen, u; + unsigned dl, dh; + + alen = (a[0] + 15) >> 4; + blen = (b[0] + 15) >> 4; + + /* + * Announced bit length of d[] will be the sum of the announced + * bit lengths of a[] and b[]; but the lengths are encoded. + */ + dl = (a[0] & 15) + (b[0] & 15); + dh = (a[0] >> 4) + (b[0] >> 4); + d[0] = (dh << 4) + dl + (~(uint32_t)(dl - 15) >> 31); + + for (u = 0; u < blen; u ++) { + uint32_t f; + size_t v; + uint32_t cc; + + f = b[1 + u]; + cc = 0; + for (v = 0; v < alen; v ++) { + uint32_t z; + + z = (uint32_t)d[1 + u + v] + MUL15(f, a[1 + v]) + cc; + cc = z >> 15; + d[1 + u + v] = z & 0x7FFF; + } + d[1 + u + alen] = cc; + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_muladd.c b/BearSSL-OG/libbearssl/src/int/i15_muladd.c new file mode 100644 index 0000000..c4b7216 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_muladd.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Constant-time division. The divisor must not be larger than 16 bits, + * and the quotient must fit on 17 bits. + */ +static uint32_t +divrem16(uint32_t x, uint32_t d, uint32_t *r) +{ + int i; + uint32_t q; + + q = 0; + d <<= 16; + for (i = 16; i >= 0; i --) { + uint32_t ctl; + + ctl = LE(d, x); + q |= ctl << i; + x -= (-ctl) & d; + d >>= 1; + } + if (r != NULL) { + *r = x; + } + return q; +} + +/* see inner.h */ +void +br_i15_muladd_small(uint16_t *x, uint16_t z, const uint16_t *m) +{ + /* + * Constant-time: we accept to leak the exact bit length of the + * modulus m. + */ + unsigned m_bitlen, mblr; + size_t u, mlen; + uint32_t hi, a0, a, b, q; + uint32_t cc, tb, over, under; + + /* + * Simple case: the modulus fits on one word. + */ + m_bitlen = m[0]; + if (m_bitlen == 0) { + return; + } + if (m_bitlen <= 15) { + uint32_t rem; + + divrem16(((uint32_t)x[1] << 15) | z, m[1], &rem); + x[1] = rem; + return; + } + mlen = (m_bitlen + 15) >> 4; + mblr = m_bitlen & 15; + + /* + * Principle: we estimate the quotient (x*2^15+z)/m by + * doing a 30/15 division with the high words. + * + * Let: + * w = 2^15 + * a = (w*a0 + a1) * w^N + a2 + * b = b0 * w^N + b2 + * such that: + * 0 <= a0 < w + * 0 <= a1 < w + * 0 <= a2 < w^N + * w/2 <= b0 < w + * 0 <= b2 < w^N + * a < w*b + * I.e. the two top words of a are a0:a1, the top word of b is + * b0, we ensured that b0 is "full" (high bit set), and a is + * such that the quotient q = a/b fits on one word (0 <= q < w). + * + * If a = b*q + r (with 0 <= r < q), then we can estimate q by + * using a division on the top words: + * a0*w + a1 = b0*u + v (with 0 <= v < b0) + * Then the following holds: + * 0 <= u <= w + * u-2 <= q <= u + */ + hi = x[mlen]; + if (mblr == 0) { + a0 = x[mlen]; + memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); + x[1] = z; + a = (a0 << 15) + x[mlen]; + b = m[mlen]; + } else { + a0 = (x[mlen] << (15 - mblr)) | (x[mlen - 1] >> mblr); + memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); + x[1] = z; + a = (a0 << 15) | (((x[mlen] << (15 - mblr)) + | (x[mlen - 1] >> mblr)) & 0x7FFF); + b = (m[mlen] << (15 - mblr)) | (m[mlen - 1] >> mblr); + } + q = divrem16(a, b, NULL); + + /* + * We computed an estimate for q, but the real one may be q, + * q-1 or q-2; moreover, the division may have returned a value + * 8000 or even 8001 if the two high words were identical, and + * we want to avoid values beyond 7FFF. We thus adjust q so + * that the "true" multiplier will be q+1, q or q-1, and q is + * in the 0000..7FFF range. + */ + q = MUX(EQ(b, a0), 0x7FFF, q - 1 + ((q - 1) >> 31)); + + /* + * We subtract q*m from x (x has an extra high word of value 'hi'). + * Since q may be off by 1 (in either direction), we may have to + * add or subtract m afterwards. + * + * The 'tb' flag will be true (1) at the end of the loop if the + * result is greater than or equal to the modulus (not counting + * 'hi' or the carry). + */ + cc = 0; + tb = 1; + for (u = 1; u <= mlen; u ++) { + uint32_t mw, zl, xw, nxw; + + mw = m[u]; + zl = MUL15(mw, q) + cc; + cc = zl >> 15; + zl &= 0x7FFF; + xw = x[u]; + nxw = xw - zl; + cc += nxw >> 31; + nxw &= 0x7FFF; + x[u] = nxw; + tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw)); + } + + /* + * If we underestimated q, then either cc < hi (one extra bit + * beyond the top array word), or cc == hi and tb is true (no + * extra bit, but the result is not lower than the modulus). + * + * If we overestimated q, then cc > hi. + */ + over = GT(cc, hi); + under = ~over & (tb | LT(cc, hi)); + br_i15_add(x, m, over); + br_i15_sub(x, m, under); +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_ninv15.c b/BearSSL-OG/libbearssl/src/int/i15_ninv15.c new file mode 100644 index 0000000..de3a3ba --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_ninv15.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint16_t +br_i15_ninv15(uint16_t x) +{ + uint32_t y; + + y = 2 - x; + y = MUL15(y, 2 - MUL15(x, y)); + y = MUL15(y, 2 - MUL15(x, y)); + y = MUL15(y, 2 - MUL15(x, y)); + return MUX(x & 1, -y, 0) & 0x7FFF; +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_reduce.c b/BearSSL-OG/libbearssl/src/int/i15_reduce.c new file mode 100644 index 0000000..0931b10 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_reduce.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i15_reduce(uint16_t *x, const uint16_t *a, const uint16_t *m) +{ + uint32_t m_bitlen, a_bitlen; + size_t mlen, alen, u; + + m_bitlen = m[0]; + mlen = (m_bitlen + 15) >> 4; + + x[0] = m_bitlen; + if (m_bitlen == 0) { + return; + } + + /* + * If the source is shorter, then simply copy all words from a[] + * and zero out the upper words. + */ + a_bitlen = a[0]; + alen = (a_bitlen + 15) >> 4; + if (a_bitlen < m_bitlen) { + memcpy(x + 1, a + 1, alen * sizeof *a); + for (u = alen; u < mlen; u ++) { + x[u + 1] = 0; + } + return; + } + + /* + * The source length is at least equal to that of the modulus. + * We must thus copy N-1 words, and input the remaining words + * one by one. + */ + memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a); + x[mlen] = 0; + for (u = 1 + alen - mlen; u > 0; u --) { + br_i15_muladd_small(x, a[u], m); + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_rshift.c b/BearSSL-OG/libbearssl/src/int/i15_rshift.c new file mode 100644 index 0000000..f9991ab --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_rshift.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i15_rshift(uint16_t *x, int count) +{ + size_t u, len; + unsigned r; + + len = (x[0] + 15) >> 4; + if (len == 0) { + return; + } + r = x[1] >> count; + for (u = 2; u <= len; u ++) { + unsigned w; + + w = x[u]; + x[u - 1] = ((w << (15 - count)) | r) & 0x7FFF; + r = w >> count; + } + x[len] = r; +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_sub.c b/BearSSL-OG/libbearssl/src/int/i15_sub.c new file mode 100644 index 0000000..1983c4d --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_sub.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i15_sub(uint16_t *a, const uint16_t *b, uint32_t ctl) +{ + uint32_t cc; + size_t u, m; + + cc = 0; + m = (a[0] + 31) >> 4; + for (u = 1; u < m; u ++) { + uint32_t aw, bw, naw; + + aw = a[u]; + bw = b[u]; + naw = aw - bw - cc; + cc = naw >> 31; + a[u] = MUX(ctl, naw & 0x7FFF, aw); + } + return cc; +} diff --git a/BearSSL-OG/libbearssl/src/int/i15_tmont.c b/BearSSL-OG/libbearssl/src/int/i15_tmont.c new file mode 100644 index 0000000..d5c4b8b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i15_tmont.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i15_to_monty(uint16_t *x, const uint16_t *m) +{ + unsigned k; + + for (k = (m[0] + 15) >> 4; k > 0; k --) { + br_i15_muladd_small(x, 0, m); + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_add.c b/BearSSL-OG/libbearssl/src/int/i31_add.c new file mode 100644 index 0000000..2ca47c6 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_add.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i31_add(uint32_t *a, const uint32_t *b, uint32_t ctl) +{ + uint32_t cc; + size_t u, m; + + cc = 0; + m = (a[0] + 63) >> 5; + for (u = 1; u < m; u ++) { + uint32_t aw, bw, naw; + + aw = a[u]; + bw = b[u]; + naw = aw + bw + cc; + cc = naw >> 31; + a[u] = MUX(ctl, naw & (uint32_t)0x7FFFFFFF, aw); + } + return cc; +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_bitlen.c b/BearSSL-OG/libbearssl/src/int/i31_bitlen.c new file mode 100644 index 0000000..3e127c2 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_bitlen.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i31_bit_length(uint32_t *x, size_t xlen) +{ + uint32_t tw, twk; + + tw = 0; + twk = 0; + while (xlen -- > 0) { + uint32_t w, c; + + c = EQ(tw, 0); + w = x[xlen]; + tw = MUX(c, w, tw); + twk = MUX(c, (uint32_t)xlen, twk); + } + return (twk << 5) + BIT_LENGTH(tw); +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_decmod.c b/BearSSL-OG/libbearssl/src/int/i31_decmod.c new file mode 100644 index 0000000..3cd7bfe --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_decmod.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i31_decode_mod(uint32_t *x, const void *src, size_t len, const uint32_t *m) +{ + /* + * Two-pass algorithm: in the first pass, we determine whether the + * value fits; in the second pass, we do the actual write. + * + * During the first pass, 'r' contains the comparison result so + * far: + * 0x00000000 value is equal to the modulus + * 0x00000001 value is greater than the modulus + * 0xFFFFFFFF value is lower than the modulus + * + * Since we iterate starting with the least significant bytes (at + * the end of src[]), each new comparison overrides the previous + * except when the comparison yields 0 (equal). + * + * During the second pass, 'r' is either 0xFFFFFFFF (value fits) + * or 0x00000000 (value does not fit). + * + * We must iterate over all bytes of the source, _and_ possibly + * some extra virtual bytes (with value 0) so as to cover the + * complete modulus as well. We also add 4 such extra bytes beyond + * the modulus length because it then guarantees that no accumulated + * partial word remains to be processed. + */ + const unsigned char *buf; + size_t mlen, tlen; + int pass; + uint32_t r; + + buf = src; + mlen = (m[0] + 31) >> 5; + tlen = (mlen << 2); + if (tlen < len) { + tlen = len; + } + tlen += 4; + r = 0; + for (pass = 0; pass < 2; pass ++) { + size_t u, v; + uint32_t acc; + int acc_len; + + v = 1; + acc = 0; + acc_len = 0; + for (u = 0; u < tlen; u ++) { + uint32_t b; + + if (u < len) { + b = buf[len - 1 - u]; + } else { + b = 0; + } + acc |= (b << acc_len); + acc_len += 8; + if (acc_len >= 31) { + uint32_t xw; + + xw = acc & (uint32_t)0x7FFFFFFF; + acc_len -= 31; + acc = b >> (8 - acc_len); + if (v <= mlen) { + if (pass) { + x[v] = r & xw; + } else { + uint32_t cc; + + cc = (uint32_t)CMP(xw, m[v]); + r = MUX(EQ(cc, 0), r, cc); + } + } else { + if (!pass) { + r = MUX(EQ(xw, 0), r, 1); + } + } + v ++; + } + } + + /* + * When we reach this point at the end of the first pass: + * r is either 0, 1 or -1; we want to set r to 0 if it + * is equal to 0 or 1, and leave it to -1 otherwise. + * + * When we reach this point at the end of the second pass: + * r is either 0 or -1; we want to leave that value + * untouched. This is a subcase of the previous. + */ + r >>= 1; + r |= (r << 1); + } + + x[0] = m[0]; + return r & (uint32_t)1; +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_decode.c b/BearSSL-OG/libbearssl/src/int/i31_decode.c new file mode 100644 index 0000000..8ec6d90 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_decode.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i31_decode(uint32_t *x, const void *src, size_t len) +{ + const unsigned char *buf; + size_t u, v; + uint32_t acc; + int acc_len; + + buf = src; + u = len; + v = 1; + acc = 0; + acc_len = 0; + while (u -- > 0) { + uint32_t b; + + b = buf[u]; + acc |= (b << acc_len); + acc_len += 8; + if (acc_len >= 31) { + x[v ++] = acc & (uint32_t)0x7FFFFFFF; + acc_len -= 31; + acc = b >> (8 - acc_len); + } + } + if (acc_len != 0) { + x[v ++] = acc; + } + x[0] = br_i31_bit_length(x + 1, v - 1); +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_decred.c b/BearSSL-OG/libbearssl/src/int/i31_decred.c new file mode 100644 index 0000000..43db662 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_decred.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i31_decode_reduce(uint32_t *x, + const void *src, size_t len, const uint32_t *m) +{ + uint32_t m_ebitlen, m_rbitlen; + size_t mblen, k; + const unsigned char *buf; + uint32_t acc; + int acc_len; + + /* + * Get the encoded bit length. + */ + m_ebitlen = m[0]; + + /* + * Special case for an invalid (null) modulus. + */ + if (m_ebitlen == 0) { + x[0] = 0; + return; + } + + /* + * Clear the destination. + */ + br_i31_zero(x, m_ebitlen); + + /* + * First decode directly as many bytes as possible. This requires + * computing the actual bit length. + */ + m_rbitlen = m_ebitlen >> 5; + m_rbitlen = (m_ebitlen & 31) + (m_rbitlen << 5) - m_rbitlen; + mblen = (m_rbitlen + 7) >> 3; + k = mblen - 1; + if (k >= len) { + br_i31_decode(x, src, len); + x[0] = m_ebitlen; + return; + } + buf = src; + br_i31_decode(x, buf, k); + x[0] = m_ebitlen; + + /* + * Input remaining bytes, using 31-bit words. + */ + acc = 0; + acc_len = 0; + while (k < len) { + uint32_t v; + + v = buf[k ++]; + if (acc_len >= 23) { + acc_len -= 23; + acc <<= (8 - acc_len); + acc |= v >> acc_len; + br_i31_muladd_small(x, acc, m); + acc = v & (0xFF >> (8 - acc_len)); + } else { + acc = (acc << 8) | v; + acc_len += 8; + } + } + + /* + * We may have some bits accumulated. We then perform a shift to + * be able to inject these bits as a full 31-bit word. + */ + if (acc_len != 0) { + acc = (acc | (x[1] << acc_len)) & 0x7FFFFFFF; + br_i31_rshift(x, 31 - acc_len); + br_i31_muladd_small(x, acc, m); + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_encode.c b/BearSSL-OG/libbearssl/src/int/i31_encode.c new file mode 100644 index 0000000..b6b40c4 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_encode.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i31_encode(void *dst, size_t len, const uint32_t *x) +{ + unsigned char *buf; + size_t k, xlen; + uint32_t acc; + int acc_len; + + xlen = (x[0] + 31) >> 5; + if (xlen == 0) { + memset(dst, 0, len); + return; + } + buf = (unsigned char *)dst + len; + k = 1; + acc = 0; + acc_len = 0; + while (len != 0) { + uint32_t w; + + w = (k <= xlen) ? x[k] : 0; + k ++; + if (acc_len == 0) { + acc = w; + acc_len = 31; + } else { + uint32_t z; + + z = acc | (w << acc_len); + acc_len --; + acc = w >> (31 - acc_len); + if (len >= 4) { + buf -= 4; + len -= 4; + br_enc32be(buf, z); + } else { + switch (len) { + case 3: + buf[-3] = (unsigned char)(z >> 16); + /* fall through */ + case 2: + buf[-2] = (unsigned char)(z >> 8); + /* fall through */ + case 1: + buf[-1] = (unsigned char)z; + break; + } + return; + } + } + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_fmont.c b/BearSSL-OG/libbearssl/src/int/i31_fmont.c new file mode 100644 index 0000000..c24b417 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_fmont.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i31_from_monty(uint32_t *x, const uint32_t *m, uint32_t m0i) +{ + size_t len, u, v; + + len = (m[0] + 31) >> 5; + for (u = 0; u < len; u ++) { + uint32_t f; + uint64_t cc; + + f = MUL31_lo(x[1], m0i); + cc = 0; + for (v = 0; v < len; v ++) { + uint64_t z; + + z = (uint64_t)x[v + 1] + MUL31(f, m[v + 1]) + cc; + cc = z >> 31; + if (v != 0) { + x[v] = (uint32_t)z & 0x7FFFFFFF; + } + } + x[len] = (uint32_t)cc; + } + + /* + * We may have to do an extra subtraction, but only if the + * value in x[] is indeed greater than or equal to that of m[], + * which is why we must do two calls (first call computes the + * carry, second call performs the subtraction only if the carry + * is 0). + */ + br_i31_sub(x, m, NOT(br_i31_sub(x, m, 0))); +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_iszero.c b/BearSSL-OG/libbearssl/src/int/i31_iszero.c new file mode 100644 index 0000000..8a7ea44 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_iszero.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i31_iszero(const uint32_t *x) +{ + uint32_t z; + size_t u; + + z = 0; + for (u = (x[0] + 31) >> 5; u > 0; u --) { + z |= x[u]; + } + return ~(z | -z) >> 31; +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_moddiv.c b/BearSSL-OG/libbearssl/src/int/i31_moddiv.c new file mode 100644 index 0000000..9950591 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_moddiv.c @@ -0,0 +1,488 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * In this file, we handle big integers with a custom format, i.e. + * without the usual one-word header. Value is split into 31-bit words, + * each stored in a 32-bit slot (top bit is zero) in little-endian + * order. The length (in words) is provided explicitly. In some cases, + * the value can be negative (using two's complement representation). In + * some cases, the top word is allowed to have a 32th bit. + */ + +/* + * Negate big integer conditionally. The value consists of 'len' words, + * with 31 bits in each word (the top bit of each word should be 0, + * except possibly for the last word). If 'ctl' is 1, the negation is + * computed; otherwise, if 'ctl' is 0, then the value is unchanged. + */ +static void +cond_negate(uint32_t *a, size_t len, uint32_t ctl) +{ + size_t k; + uint32_t cc, xm; + + cc = ctl; + xm = -ctl >> 1; + for (k = 0; k < len; k ++) { + uint32_t aw; + + aw = a[k]; + aw = (aw ^ xm) + cc; + a[k] = aw & 0x7FFFFFFF; + cc = aw >> 31; + } +} + +/* + * Finish modular reduction. Rules on input parameters: + * + * if neg = 1, then -m <= a < 0 + * if neg = 0, then 0 <= a < 2*m + * + * If neg = 0, then the top word of a[] may use 32 bits. + * + * Also, modulus m must be odd. + */ +static void +finish_mod(uint32_t *a, size_t len, const uint32_t *m, uint32_t neg) +{ + size_t k; + uint32_t cc, xm, ym; + + /* + * First pass: compare a (assumed nonnegative) with m. + * Note that if the final word uses the top extra bit, then + * subtracting m must yield a value less than 2^31, since we + * assumed that a < 2*m. + */ + cc = 0; + for (k = 0; k < len; k ++) { + uint32_t aw, mw; + + aw = a[k]; + mw = m[k]; + cc = (aw - mw - cc) >> 31; + } + + /* + * At this point: + * if neg = 1, then we must add m (regardless of cc) + * if neg = 0 and cc = 0, then we must subtract m + * if neg = 0 and cc = 1, then we must do nothing + */ + xm = -neg >> 1; + ym = -(neg | (1 - cc)); + cc = neg; + for (k = 0; k < len; k ++) { + uint32_t aw, mw; + + aw = a[k]; + mw = (m[k] ^ xm) & ym; + aw = aw - mw - cc; + a[k] = aw & 0x7FFFFFFF; + cc = aw >> 31; + } +} + +/* + * Compute: + * a <- (a*pa+b*pb)/(2^31) + * b <- (a*qa+b*qb)/(2^31) + * The division is assumed to be exact (i.e. the low word is dropped). + * If the final a is negative, then it is negated. Similarly for b. + * Returned value is the combination of two bits: + * bit 0: 1 if a had to be negated, 0 otherwise + * bit 1: 1 if b had to be negated, 0 otherwise + * + * Factors pa, pb, qa and qb must be at most 2^31 in absolute value. + * Source integers a and b must be nonnegative; top word is not allowed + * to contain an extra 32th bit. + */ +static uint32_t +co_reduce(uint32_t *a, uint32_t *b, size_t len, + int64_t pa, int64_t pb, int64_t qa, int64_t qb) +{ + size_t k; + int64_t cca, ccb; + uint32_t nega, negb; + + cca = 0; + ccb = 0; + for (k = 0; k < len; k ++) { + uint32_t wa, wb; + uint64_t za, zb; + uint64_t tta, ttb; + + /* + * Since: + * |pa| <= 2^31 + * |pb| <= 2^31 + * 0 <= wa <= 2^31 - 1 + * 0 <= wb <= 2^31 - 1 + * |cca| <= 2^32 - 1 + * Then: + * |za| <= (2^31-1)*(2^32) + (2^32-1) = 2^63 - 1 + * + * Thus, the new value of cca is such that |cca| <= 2^32 - 1. + * The same applies to ccb. + */ + wa = a[k]; + wb = b[k]; + za = wa * (uint64_t)pa + wb * (uint64_t)pb + (uint64_t)cca; + zb = wa * (uint64_t)qa + wb * (uint64_t)qb + (uint64_t)ccb; + if (k > 0) { + a[k - 1] = za & 0x7FFFFFFF; + b[k - 1] = zb & 0x7FFFFFFF; + } + + /* + * For the new values of cca and ccb, we need a signed + * right-shift; since, in C, right-shifting a signed + * negative value is implementation-defined, we use a + * custom portable sign extension expression. + */ +#define M ((uint64_t)1 << 32) + tta = za >> 31; + ttb = zb >> 31; + tta = (tta ^ M) - M; + ttb = (ttb ^ M) - M; + cca = *(int64_t *)&tta; + ccb = *(int64_t *)&ttb; +#undef M + } + a[len - 1] = (uint32_t)cca; + b[len - 1] = (uint32_t)ccb; + + nega = (uint32_t)((uint64_t)cca >> 63); + negb = (uint32_t)((uint64_t)ccb >> 63); + cond_negate(a, len, nega); + cond_negate(b, len, negb); + return nega | (negb << 1); +} + +/* + * Compute: + * a <- (a*pa+b*pb)/(2^31) mod m + * b <- (a*qa+b*qb)/(2^31) mod m + * + * m0i is equal to -1/m[0] mod 2^31. + * + * Factors pa, pb, qa and qb must be at most 2^31 in absolute value. + * Source integers a and b must be nonnegative; top word is not allowed + * to contain an extra 32th bit. + */ +static void +co_reduce_mod(uint32_t *a, uint32_t *b, size_t len, + int64_t pa, int64_t pb, int64_t qa, int64_t qb, + const uint32_t *m, uint32_t m0i) +{ + size_t k; + int64_t cca, ccb; + uint32_t fa, fb; + + cca = 0; + ccb = 0; + fa = ((a[0] * (uint32_t)pa + b[0] * (uint32_t)pb) * m0i) & 0x7FFFFFFF; + fb = ((a[0] * (uint32_t)qa + b[0] * (uint32_t)qb) * m0i) & 0x7FFFFFFF; + for (k = 0; k < len; k ++) { + uint32_t wa, wb; + uint64_t za, zb; + uint64_t tta, ttb; + + /* + * In this loop, carries 'cca' and 'ccb' always fit on + * 33 bits (in absolute value). + */ + wa = a[k]; + wb = b[k]; + za = wa * (uint64_t)pa + wb * (uint64_t)pb + + m[k] * (uint64_t)fa + (uint64_t)cca; + zb = wa * (uint64_t)qa + wb * (uint64_t)qb + + m[k] * (uint64_t)fb + (uint64_t)ccb; + if (k > 0) { + a[k - 1] = (uint32_t)za & 0x7FFFFFFF; + b[k - 1] = (uint32_t)zb & 0x7FFFFFFF; + } + +#define M ((uint64_t)1 << 32) + tta = za >> 31; + ttb = zb >> 31; + tta = (tta ^ M) - M; + ttb = (ttb ^ M) - M; + cca = *(int64_t *)&tta; + ccb = *(int64_t *)&ttb; +#undef M + } + a[len - 1] = (uint32_t)cca; + b[len - 1] = (uint32_t)ccb; + + /* + * At this point: + * -m <= a < 2*m + * -m <= b < 2*m + * (this is a case of Montgomery reduction) + * The top word of 'a' and 'b' may have a 32-th bit set. + * We may have to add or subtract the modulus. + */ + finish_mod(a, len, m, (uint32_t)((uint64_t)cca >> 63)); + finish_mod(b, len, m, (uint32_t)((uint64_t)ccb >> 63)); +} + +/* see inner.h */ +uint32_t +br_i31_moddiv(uint32_t *x, const uint32_t *y, const uint32_t *m, uint32_t m0i, + uint32_t *t) +{ + /* + * Algorithm is an extended binary GCD. We maintain four values + * a, b, u and v, with the following invariants: + * + * a * x = y * u mod m + * b * x = y * v mod m + * + * Starting values are: + * + * a = y + * b = m + * u = x + * v = 0 + * + * The formal definition of the algorithm is a sequence of steps: + * + * - If a is even, then a <- a/2 and u <- u/2 mod m. + * - Otherwise, if b is even, then b <- b/2 and v <- v/2 mod m. + * - Otherwise, if a > b, then a <- (a-b)/2 and u <- (u-v)/2 mod m. + * - Otherwise, b <- (b-a)/2 and v <- (v-u)/2 mod m. + * + * Algorithm stops when a = b. At that point, they both are equal + * to GCD(y,m); the modular division succeeds if that value is 1. + * The result of the modular division is then u (or v: both are + * equal at that point). + * + * Each step makes either a or b shrink by at least one bit; hence, + * if m has bit length k bits, then 2k-2 steps are sufficient. + * + * + * Though complexity is quadratic in the size of m, the bit-by-bit + * processing is not very efficient. We can speed up processing by + * remarking that the decisions are taken based only on observation + * of the top and low bits of a and b. + * + * In the loop below, at each iteration, we use the two top words + * of a and b, and the low words of a and b, to compute reduction + * parameters pa, pb, qa and qb such that the new values for a + * and b are: + * + * a' = (a*pa + b*pb) / (2^31) + * b' = (a*qa + b*qb) / (2^31) + * + * the division being exact. + * + * Since the choices are based on the top words, they may be slightly + * off, requiring an optional correction: if a' < 0, then we replace + * pa with -pa, and pb with -pb. The total length of a and b is + * thus reduced by at least 30 bits at each iteration. + * + * The stopping conditions are still the same, though: when a + * and b become equal, they must be both odd (since m is odd, + * the GCD cannot be even), therefore the next operation is a + * subtraction, and one of the values becomes 0. At that point, + * nothing else happens, i.e. one value is stuck at 0, and the + * other one is the GCD. + */ + size_t len, k; + uint32_t *a, *b, *u, *v; + uint32_t num, r; + + len = (m[0] + 31) >> 5; + a = t; + b = a + len; + u = x + 1; + v = b + len; + memcpy(a, y + 1, len * sizeof *y); + memcpy(b, m + 1, len * sizeof *m); + memset(v, 0, len * sizeof *v); + + /* + * Loop below ensures that a and b are reduced by some bits each, + * for a total of at least 30 bits. + */ + for (num = ((m[0] - (m[0] >> 5)) << 1) + 30; num >= 30; num -= 30) { + size_t j; + uint32_t c0, c1; + uint32_t a0, a1, b0, b1; + uint64_t a_hi, b_hi; + uint32_t a_lo, b_lo; + int64_t pa, pb, qa, qb; + int i; + + /* + * Extract top words of a and b. If j is the highest + * index >= 1 such that a[j] != 0 or b[j] != 0, then we want + * (a[j] << 31) + a[j - 1], and (b[j] << 31) + b[j - 1]. + * If a and b are down to one word each, then we use a[0] + * and b[0]. + */ + c0 = (uint32_t)-1; + c1 = (uint32_t)-1; + a0 = 0; + a1 = 0; + b0 = 0; + b1 = 0; + j = len; + while (j -- > 0) { + uint32_t aw, bw; + + aw = a[j]; + bw = b[j]; + a0 ^= (a0 ^ aw) & c0; + a1 ^= (a1 ^ aw) & c1; + b0 ^= (b0 ^ bw) & c0; + b1 ^= (b1 ^ bw) & c1; + c1 = c0; + c0 &= (((aw | bw) + 0x7FFFFFFF) >> 31) - (uint32_t)1; + } + + /* + * If c1 = 0, then we grabbed two words for a and b. + * If c1 != 0 but c0 = 0, then we grabbed one word. It + * is not possible that c1 != 0 and c0 != 0, because that + * would mean that both integers are zero. + */ + a1 |= a0 & c1; + a0 &= ~c1; + b1 |= b0 & c1; + b0 &= ~c1; + a_hi = ((uint64_t)a0 << 31) + a1; + b_hi = ((uint64_t)b0 << 31) + b1; + a_lo = a[0]; + b_lo = b[0]; + + /* + * Compute reduction factors: + * + * a' = a*pa + b*pb + * b' = a*qa + b*qb + * + * such that a' and b' are both multiple of 2^31, but are + * only marginally larger than a and b. + */ + pa = 1; + pb = 0; + qa = 0; + qb = 1; + for (i = 0; i < 31; i ++) { + /* + * At each iteration: + * + * a <- (a-b)/2 if: a is odd, b is odd, a_hi > b_hi + * b <- (b-a)/2 if: a is odd, b is odd, a_hi <= b_hi + * a <- a/2 if: a is even + * b <- b/2 if: a is odd, b is even + * + * We multiply a_lo and b_lo by 2 at each + * iteration, thus a division by 2 really is a + * non-multiplication by 2. + */ + uint32_t r, oa, ob, cAB, cBA, cA; + uint64_t rz; + + /* + * r = GT(a_hi, b_hi) + * But the GT() function works on uint32_t operands, + * so we inline a 64-bit version here. + */ + rz = b_hi - a_hi; + r = (uint32_t)((rz ^ ((a_hi ^ b_hi) + & (a_hi ^ rz))) >> 63); + + /* + * cAB = 1 if b must be subtracted from a + * cBA = 1 if a must be subtracted from b + * cA = 1 if a is divided by 2, 0 otherwise + * + * Rules: + * + * cAB and cBA cannot be both 1. + * if a is not divided by 2, b is. + */ + oa = (a_lo >> i) & 1; + ob = (b_lo >> i) & 1; + cAB = oa & ob & r; + cBA = oa & ob & NOT(r); + cA = cAB | NOT(oa); + + /* + * Conditional subtractions. + */ + a_lo -= b_lo & -cAB; + a_hi -= b_hi & -(uint64_t)cAB; + pa -= qa & -(int64_t)cAB; + pb -= qb & -(int64_t)cAB; + b_lo -= a_lo & -cBA; + b_hi -= a_hi & -(uint64_t)cBA; + qa -= pa & -(int64_t)cBA; + qb -= pb & -(int64_t)cBA; + + /* + * Shifting. + */ + a_lo += a_lo & (cA - 1); + pa += pa & ((int64_t)cA - 1); + pb += pb & ((int64_t)cA - 1); + a_hi ^= (a_hi ^ (a_hi >> 1)) & -(uint64_t)cA; + b_lo += b_lo & -cA; + qa += qa & -(int64_t)cA; + qb += qb & -(int64_t)cA; + b_hi ^= (b_hi ^ (b_hi >> 1)) & ((uint64_t)cA - 1); + } + + /* + * Replace a and b with new values a' and b'. + */ + r = co_reduce(a, b, len, pa, pb, qa, qb); + pa -= pa * ((r & 1) << 1); + pb -= pb * ((r & 1) << 1); + qa -= qa * (r & 2); + qb -= qb * (r & 2); + co_reduce_mod(u, v, len, pa, pb, qa, qb, m + 1, m0i); + } + + /* + * Now one of the arrays should be 0, and the other contains + * the GCD. If a is 0, then u is 0 as well, and v contains + * the division result. + * Result is correct if and only if GCD is 1. + */ + r = (a[0] | b[0]) ^ 1; + u[0] |= v[0]; + for (k = 1; k < len; k ++) { + r |= a[k] | b[k]; + u[k] |= v[k]; + } + return EQ0(r); +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_modpow.c b/BearSSL-OG/libbearssl/src/int/i31_modpow.c new file mode 100644 index 0000000..4ef3f5d --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_modpow.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i31_modpow(uint32_t *x, + const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2) +{ + size_t mlen; + uint32_t k; + + /* + * 'mlen' is the length of m[] expressed in bytes (including + * the "bit length" first field). + */ + mlen = ((m[0] + 63) >> 5) * sizeof m[0]; + + /* + * Throughout the algorithm: + * -- t1[] is in Montgomery representation; it contains x, x^2, + * x^4, x^8... + * -- The result is accumulated, in normal representation, in + * the x[] array. + * -- t2[] is used as destination buffer for each multiplication. + * + * Note that there is no need to call br_i32_from_monty(). + */ + memcpy(t1, x, mlen); + br_i31_to_monty(t1, m); + br_i31_zero(x, m[0]); + x[1] = 1; + for (k = 0; k < ((uint32_t)elen << 3); k ++) { + uint32_t ctl; + + ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1; + br_i31_montymul(t2, x, t1, m, m0i); + CCOPY(ctl, x, t2, mlen); + br_i31_montymul(t2, t1, t1, m, m0i); + memcpy(t1, t2, mlen); + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_modpow2.c b/BearSSL-OG/libbearssl/src/int/i31_modpow2.c new file mode 100644 index 0000000..0b8f8cf --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_modpow2.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i31_modpow_opt(uint32_t *x, + const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *tmp, size_t twlen) +{ + size_t mlen, mwlen; + uint32_t *t1, *t2, *base; + size_t u, v; + uint32_t acc; + int acc_len, win_len; + + /* + * Get modulus size. + */ + mwlen = (m[0] + 63) >> 5; + mlen = mwlen * sizeof m[0]; + mwlen += (mwlen & 1); + t1 = tmp; + t2 = tmp + mwlen; + + /* + * Compute possible window size, with a maximum of 5 bits. + * When the window has size 1 bit, we use a specific code + * that requires only two temporaries. Otherwise, for a + * window of k bits, we need 2^k+1 temporaries. + */ + if (twlen < (mwlen << 1)) { + return 0; + } + for (win_len = 5; win_len > 1; win_len --) { + if ((((uint32_t)1 << win_len) + 1) * mwlen <= twlen) { + break; + } + } + + /* + * Everything is done in Montgomery representation. + */ + br_i31_to_monty(x, m); + + /* + * Compute window contents. If the window has size one bit only, + * then t2 is set to x; otherwise, t2[0] is left untouched, and + * t2[k] is set to x^k (for k >= 1). + */ + if (win_len == 1) { + memcpy(t2, x, mlen); + } else { + memcpy(t2 + mwlen, x, mlen); + base = t2 + mwlen; + for (u = 2; u < ((unsigned)1 << win_len); u ++) { + br_i31_montymul(base + mwlen, base, x, m, m0i); + base += mwlen; + } + } + + /* + * We need to set x to 1, in Montgomery representation. This can + * be done efficiently by setting the high word to 1, then doing + * one word-sized shift. + */ + br_i31_zero(x, m[0]); + x[(m[0] + 31) >> 5] = 1; + br_i31_muladd_small(x, 0, m); + + /* + * We process bits from most to least significant. At each + * loop iteration, we have acc_len bits in acc. + */ + acc = 0; + acc_len = 0; + while (acc_len > 0 || elen > 0) { + int i, k; + uint32_t bits; + + /* + * Get the next bits. + */ + k = win_len; + if (acc_len < win_len) { + if (elen > 0) { + acc = (acc << 8) | *e ++; + elen --; + acc_len += 8; + } else { + k = acc_len; + } + } + bits = (acc >> (acc_len - k)) & (((uint32_t)1 << k) - 1); + acc_len -= k; + + /* + * We could get exactly k bits. Compute k squarings. + */ + for (i = 0; i < k; i ++) { + br_i31_montymul(t1, x, x, m, m0i); + memcpy(x, t1, mlen); + } + + /* + * Window lookup: we want to set t2 to the window + * lookup value, assuming the bits are non-zero. If + * the window length is 1 bit only, then t2 is + * already set; otherwise, we do a constant-time lookup. + */ + if (win_len > 1) { + br_i31_zero(t2, m[0]); + base = t2 + mwlen; + for (u = 1; u < ((uint32_t)1 << k); u ++) { + uint32_t mask; + + mask = -EQ(u, bits); + for (v = 1; v < mwlen; v ++) { + t2[v] |= mask & base[v]; + } + base += mwlen; + } + } + + /* + * Multiply with the looked-up value. We keep the + * product only if the exponent bits are not all-zero. + */ + br_i31_montymul(t1, x, t2, m, m0i); + CCOPY(NEQ(bits, 0), x, t1, mlen); + } + + /* + * Convert back from Montgomery representation, and exit. + */ + br_i31_from_monty(x, m, m0i); + return 1; +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_montmul.c b/BearSSL-OG/libbearssl/src/int/i31_montmul.c new file mode 100644 index 0000000..758f8f4 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_montmul.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i31_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, + const uint32_t *m, uint32_t m0i) +{ + /* + * Each outer loop iteration computes: + * d <- (d + xu*y + f*m) / 2^31 + * We have xu <= 2^31-1 and f <= 2^31-1. + * Thus, if d <= 2*m-1 on input, then: + * 2*m-1 + 2*(2^31-1)*m <= (2^32)*m-1 + * and the new d value is less than 2*m. + * + * We represent d over 31-bit words, with an extra word 'dh' + * which can thus be only 0 or 1. + */ + size_t len, len4, u, v; + uint32_t dh; + + len = (m[0] + 31) >> 5; + len4 = len & ~(size_t)3; + br_i31_zero(d, m[0]); + dh = 0; + for (u = 0; u < len; u ++) { + /* + * The carry for each operation fits on 32 bits: + * d[v+1] <= 2^31-1 + * xu*y[v+1] <= (2^31-1)*(2^31-1) + * f*m[v+1] <= (2^31-1)*(2^31-1) + * r <= 2^32-1 + * (2^31-1) + 2*(2^31-1)*(2^31-1) + (2^32-1) = 2^63 - 2^31 + * After division by 2^31, the new r is then at most 2^32-1 + * + * Using a 32-bit carry has performance benefits on 32-bit + * systems; however, on 64-bit architectures, we prefer to + * keep the carry (r) in a 64-bit register, thus avoiding some + * "clear high bits" operations. + */ + uint32_t f, xu; +#if BR_64 + uint64_t r; +#else + uint32_t r; +#endif + + xu = x[u + 1]; + f = MUL31_lo((d[1] + MUL31_lo(x[u + 1], y[1])), m0i); + + r = 0; + for (v = 0; v < len4; v += 4) { + uint64_t z; + + z = (uint64_t)d[v + 1] + MUL31(xu, y[v + 1]) + + MUL31(f, m[v + 1]) + r; + r = z >> 31; + d[v + 0] = (uint32_t)z & 0x7FFFFFFF; + z = (uint64_t)d[v + 2] + MUL31(xu, y[v + 2]) + + MUL31(f, m[v + 2]) + r; + r = z >> 31; + d[v + 1] = (uint32_t)z & 0x7FFFFFFF; + z = (uint64_t)d[v + 3] + MUL31(xu, y[v + 3]) + + MUL31(f, m[v + 3]) + r; + r = z >> 31; + d[v + 2] = (uint32_t)z & 0x7FFFFFFF; + z = (uint64_t)d[v + 4] + MUL31(xu, y[v + 4]) + + MUL31(f, m[v + 4]) + r; + r = z >> 31; + d[v + 3] = (uint32_t)z & 0x7FFFFFFF; + } + for (; v < len; v ++) { + uint64_t z; + + z = (uint64_t)d[v + 1] + MUL31(xu, y[v + 1]) + + MUL31(f, m[v + 1]) + r; + r = z >> 31; + d[v] = (uint32_t)z & 0x7FFFFFFF; + } + + /* + * Since the new dh can only be 0 or 1, the addition of + * the old dh with the carry MUST fit on 32 bits, and + * thus can be done into dh itself. + */ + dh += r; + d[len] = dh & 0x7FFFFFFF; + dh >>= 31; + } + + /* + * We must write back the bit length because it was overwritten in + * the loop (not overwriting it would require a test in the loop, + * which would yield bigger and slower code). + */ + d[0] = m[0]; + + /* + * d[] may still be greater than m[] at that point; notably, the + * 'dh' word may be non-zero. + */ + br_i31_sub(d, m, NEQ(dh, 0) | NOT(br_i31_sub(d, m, 0))); +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_mulacc.c b/BearSSL-OG/libbearssl/src/int/i31_mulacc.c new file mode 100644 index 0000000..7410e54 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_mulacc.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i31_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + size_t alen, blen, u; + uint32_t dl, dh; + + alen = (a[0] + 31) >> 5; + blen = (b[0] + 31) >> 5; + + /* + * We want to add the two bit lengths, but these are encoded, + * which requires some extra care. + */ + dl = (a[0] & 31) + (b[0] & 31); + dh = (a[0] >> 5) + (b[0] >> 5); + d[0] = (dh << 5) + dl + (~(uint32_t)(dl - 31) >> 31); + + for (u = 0; u < blen; u ++) { + uint32_t f; + size_t v; + + /* + * Carry always fits on 31 bits; we want to keep it in a + * 32-bit register on 32-bit architectures (on a 64-bit + * architecture, cast down from 64 to 32 bits means + * clearing the high bits, which is not free; on a 32-bit + * architecture, the same operation really means ignoring + * the top register, which has negative or zero cost). + */ +#if BR_64 + uint64_t cc; +#else + uint32_t cc; +#endif + + f = b[1 + u]; + cc = 0; + for (v = 0; v < alen; v ++) { + uint64_t z; + + z = (uint64_t)d[1 + u + v] + MUL31(f, a[1 + v]) + cc; + cc = z >> 31; + d[1 + u + v] = (uint32_t)z & 0x7FFFFFFF; + } + d[1 + u + alen] = (uint32_t)cc; + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_muladd.c b/BearSSL-OG/libbearssl/src/int/i31_muladd.c new file mode 100644 index 0000000..eecd9e2 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_muladd.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i31_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m) +{ + uint32_t m_bitlen; + unsigned mblr; + size_t u, mlen; + uint32_t a0, a1, b0, hi, g, q, tb; + uint32_t under, over; + uint32_t cc; + + /* + * We can test on the modulus bit length since we accept to + * leak that length. + */ + m_bitlen = m[0]; + if (m_bitlen == 0) { + return; + } + if (m_bitlen <= 31) { + uint32_t lo; + + hi = x[1] >> 1; + lo = (x[1] << 31) | z; + x[1] = br_rem(hi, lo, m[1]); + return; + } + mlen = (m_bitlen + 31) >> 5; + mblr = (unsigned)m_bitlen & 31; + + /* + * Principle: we estimate the quotient (x*2^31+z)/m by + * doing a 64/32 division with the high words. + * + * Let: + * w = 2^31 + * a = (w*a0 + a1) * w^N + a2 + * b = b0 * w^N + b2 + * such that: + * 0 <= a0 < w + * 0 <= a1 < w + * 0 <= a2 < w^N + * w/2 <= b0 < w + * 0 <= b2 < w^N + * a < w*b + * I.e. the two top words of a are a0:a1, the top word of b is + * b0, we ensured that b0 is "full" (high bit set), and a is + * such that the quotient q = a/b fits on one word (0 <= q < w). + * + * If a = b*q + r (with 0 <= r < q), we can estimate q by + * doing an Euclidean division on the top words: + * a0*w+a1 = b0*u + v (with 0 <= v < b0) + * Then the following holds: + * 0 <= u <= w + * u-2 <= q <= u + */ + hi = x[mlen]; + if (mblr == 0) { + a0 = x[mlen]; + memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); + x[1] = z; + a1 = x[mlen]; + b0 = m[mlen]; + } else { + a0 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr)) + & 0x7FFFFFFF; + memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); + x[1] = z; + a1 = ((x[mlen] << (31 - mblr)) | (x[mlen - 1] >> mblr)) + & 0x7FFFFFFF; + b0 = ((m[mlen] << (31 - mblr)) | (m[mlen - 1] >> mblr)) + & 0x7FFFFFFF; + } + + /* + * We estimate a divisor q. If the quotient returned by br_div() + * is g: + * -- If a0 == b0 then g == 0; we want q = 0x7FFFFFFF. + * -- Otherwise: + * -- if g == 0 then we set q = 0; + * -- otherwise, we set q = g - 1. + * The properties described above then ensure that the true + * quotient is q-1, q or q+1. + * + * Take care that a0, a1 and b0 are 31-bit words, not 32-bit. We + * must adjust the parameters to br_div() accordingly. + */ + g = br_div(a0 >> 1, a1 | (a0 << 31), b0); + q = MUX(EQ(a0, b0), 0x7FFFFFFF, MUX(EQ(g, 0), 0, g - 1)); + + /* + * We subtract q*m from x (with the extra high word of value 'hi'). + * Since q may be off by 1 (in either direction), we may have to + * add or subtract m afterwards. + * + * The 'tb' flag will be true (1) at the end of the loop if the + * result is greater than or equal to the modulus (not counting + * 'hi' or the carry). + */ + cc = 0; + tb = 1; + for (u = 1; u <= mlen; u ++) { + uint32_t mw, zw, xw, nxw; + uint64_t zl; + + mw = m[u]; + zl = MUL31(mw, q) + cc; + cc = (uint32_t)(zl >> 31); + zw = (uint32_t)zl & (uint32_t)0x7FFFFFFF; + xw = x[u]; + nxw = xw - zw; + cc += nxw >> 31; + nxw &= 0x7FFFFFFF; + x[u] = nxw; + tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw)); + } + + /* + * If we underestimated q, then either cc < hi (one extra bit + * beyond the top array word), or cc == hi and tb is true (no + * extra bit, but the result is not lower than the modulus). In + * these cases we must subtract m once. + * + * Otherwise, we may have overestimated, which will show as + * cc > hi (thus a negative result). Correction is adding m once. + */ + over = GT(cc, hi); + under = ~over & (tb | LT(cc, hi)); + br_i31_add(x, m, over); + br_i31_sub(x, m, under); +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_ninv31.c b/BearSSL-OG/libbearssl/src/int/i31_ninv31.c new file mode 100644 index 0000000..dd83c96 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_ninv31.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i31_ninv31(uint32_t x) +{ + uint32_t y; + + y = 2 - x; + y *= 2 - y * x; + y *= 2 - y * x; + y *= 2 - y * x; + y *= 2 - y * x; + return MUX(x & 1, -y, 0) & 0x7FFFFFFF; +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_reduce.c b/BearSSL-OG/libbearssl/src/int/i31_reduce.c new file mode 100644 index 0000000..5c9523e --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_reduce.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i31_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m) +{ + uint32_t m_bitlen, a_bitlen; + size_t mlen, alen, u; + + m_bitlen = m[0]; + mlen = (m_bitlen + 31) >> 5; + + x[0] = m_bitlen; + if (m_bitlen == 0) { + return; + } + + /* + * If the source is shorter, then simply copy all words from a[] + * and zero out the upper words. + */ + a_bitlen = a[0]; + alen = (a_bitlen + 31) >> 5; + if (a_bitlen < m_bitlen) { + memcpy(x + 1, a + 1, alen * sizeof *a); + for (u = alen; u < mlen; u ++) { + x[u + 1] = 0; + } + return; + } + + /* + * The source length is at least equal to that of the modulus. + * We must thus copy N-1 words, and input the remaining words + * one by one. + */ + memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a); + x[mlen] = 0; + for (u = 1 + alen - mlen; u > 0; u --) { + br_i31_muladd_small(x, a[u], m); + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_rshift.c b/BearSSL-OG/libbearssl/src/int/i31_rshift.c new file mode 100644 index 0000000..db6ba0b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_rshift.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i31_rshift(uint32_t *x, int count) +{ + size_t u, len; + uint32_t r; + + len = (x[0] + 31) >> 5; + if (len == 0) { + return; + } + r = x[1] >> count; + for (u = 2; u <= len; u ++) { + uint32_t w; + + w = x[u]; + x[u - 1] = ((w << (31 - count)) | r) & 0x7FFFFFFF; + r = w >> count; + } + x[len] = r; +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_sub.c b/BearSSL-OG/libbearssl/src/int/i31_sub.c new file mode 100644 index 0000000..3910895 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_sub.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i31_sub(uint32_t *a, const uint32_t *b, uint32_t ctl) +{ + uint32_t cc; + size_t u, m; + + cc = 0; + m = (a[0] + 63) >> 5; + for (u = 1; u < m; u ++) { + uint32_t aw, bw, naw; + + aw = a[u]; + bw = b[u]; + naw = aw - bw - cc; + cc = naw >> 31; + a[u] = MUX(ctl, naw & 0x7FFFFFFF, aw); + } + return cc; +} diff --git a/BearSSL-OG/libbearssl/src/int/i31_tmont.c b/BearSSL-OG/libbearssl/src/int/i31_tmont.c new file mode 100644 index 0000000..4798ff6 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i31_tmont.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i31_to_monty(uint32_t *x, const uint32_t *m) +{ + uint32_t k; + + for (k = (m[0] + 31) >> 5; k > 0; k --) { + br_i31_muladd_small(x, 0, m); + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_add.c b/BearSSL-OG/libbearssl/src/int/i32_add.c new file mode 100644 index 0000000..620baff --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_add.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i32_add(uint32_t *a, const uint32_t *b, uint32_t ctl) +{ + uint32_t cc; + size_t u, m; + + cc = 0; + m = (a[0] + 63) >> 5; + for (u = 1; u < m; u ++) { + uint32_t aw, bw, naw; + + aw = a[u]; + bw = b[u]; + naw = aw + bw + cc; + + /* + * Carry is 1 if naw < aw. Carry is also 1 if naw == aw + * AND the carry was already 1. + */ + cc = (cc & EQ(naw, aw)) | LT(naw, aw); + a[u] = MUX(ctl, naw, aw); + } + return cc; +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_bitlen.c b/BearSSL-OG/libbearssl/src/int/i32_bitlen.c new file mode 100644 index 0000000..40ce9fa --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_bitlen.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i32_bit_length(uint32_t *x, size_t xlen) +{ + uint32_t tw, twk; + + tw = 0; + twk = 0; + while (xlen -- > 0) { + uint32_t w, c; + + c = EQ(tw, 0); + w = x[xlen]; + tw = MUX(c, w, tw); + twk = MUX(c, (uint32_t)xlen, twk); + } + return (twk << 5) + BIT_LENGTH(tw); +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_decmod.c b/BearSSL-OG/libbearssl/src/int/i32_decmod.c new file mode 100644 index 0000000..a859af1 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_decmod.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i32_decode_mod(uint32_t *x, const void *src, size_t len, const uint32_t *m) +{ + const unsigned char *buf; + uint32_t r; + size_t u, v, mlen; + + buf = src; + + /* + * First pass: determine whether the value fits. The 'r' value + * will contain the comparison result, as 0x00000000 (value is + * equal to the modulus), 0x00000001 (value is greater than the + * modulus), or 0xFFFFFFFF (value is lower than the modulus). + */ + mlen = (m[0] + 7) >> 3; + r = 0; + for (u = (mlen > len) ? mlen : len; u > 0; u --) { + uint32_t mb, xb; + + v = u - 1; + if (v >= mlen) { + mb = 0; + } else { + mb = (m[1 + (v >> 2)] >> ((v & 3) << 3)) & 0xFF; + } + if (v >= len) { + xb = 0; + } else { + xb = buf[len - u]; + } + r = MUX(EQ(r, 0), (uint32_t)CMP(xb, mb), r); + } + + /* + * Only r == 0xFFFFFFFF is acceptable. We want to set r to 0xFF if + * the value fits, 0x00 otherwise. + */ + r >>= 24; + br_i32_zero(x, m[0]); + u = (mlen > len) ? len : mlen; + while (u > 0) { + uint32_t xb; + + xb = buf[len - u] & r; + u --; + x[1 + (u >> 2)] |= xb << ((u & 3) << 3); + } + return r >> 7; +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_decode.c b/BearSSL-OG/libbearssl/src/int/i32_decode.c new file mode 100644 index 0000000..f289038 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_decode.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i32_decode(uint32_t *x, const void *src, size_t len) +{ + const unsigned char *buf; + size_t u, v; + + buf = src; + u = len; + v = 1; + for (;;) { + if (u < 4) { + uint32_t w; + + if (u < 2) { + if (u == 0) { + break; + } else { + w = buf[0]; + } + } else { + if (u == 2) { + w = br_dec16be(buf); + } else { + w = ((uint32_t)buf[0] << 16) + | br_dec16be(buf + 1); + } + } + x[v ++] = w; + break; + } else { + u -= 4; + x[v ++] = br_dec32be(buf + u); + } + } + x[0] = br_i32_bit_length(x + 1, v - 1); +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_decred.c b/BearSSL-OG/libbearssl/src/int/i32_decred.c new file mode 100644 index 0000000..dc476db --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_decred.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i32_decode_reduce(uint32_t *x, + const void *src, size_t len, const uint32_t *m) +{ + uint32_t m_bitlen; + size_t mblen, k, q; + const unsigned char *buf; + + m_bitlen = m[0]; + + /* + * Special case for an invalid modulus. + */ + if (m_bitlen == 0) { + x[0] = 0; + return; + } + + /* + * Clear the destination. + */ + br_i32_zero(x, m_bitlen); + + /* + * First decode directly as many bytes as possible without + * reduction, taking care to leave a number of bytes which + * is a multiple of 4. + */ + mblen = (m_bitlen + 7) >> 3; + k = mblen - 1; + + /* + * Up to k bytes can be safely decoded. + */ + if (k >= len) { + br_i32_decode(x, src, len); + x[0] = m_bitlen; + return; + } + + /* + * We want to first inject some bytes with direct decoding, + * then extra bytes by whole 32-bit words. First compute + * the size that should be injected that way. + */ + buf = src; + q = (len - k + 3) & ~(size_t)3; + + /* + * It may happen that this is more than what we already have + * (by at most 3 bytes). Such a case may happen only with + * a very short modulus. In that case, we must process the first + * bytes "manually". + */ + if (q > len) { + int i; + uint32_t w; + + w = 0; + for (i = 0; i < 4; i ++) { + w <<= 8; + if (q <= len) { + w |= buf[len - q]; + } + q --; + } + br_i32_muladd_small(x, w, m); + } else { + br_i32_decode(x, buf, len - q); + x[0] = m_bitlen; + } + + /* + * At that point, we have exactly q bytes to inject, and q is + * a multiple of 4. + */ + for (k = len - q; k < len; k += 4) { + br_i32_muladd_small(x, br_dec32be(buf + k), m); + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_div32.c b/BearSSL-OG/libbearssl/src/int/i32_div32.c new file mode 100644 index 0000000..d8b8023 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_div32.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_divrem(uint32_t hi, uint32_t lo, uint32_t d, uint32_t *r) +{ + /* TODO: optimize this */ + uint32_t q; + uint32_t ch, cf; + int k; + + q = 0; + ch = EQ(hi, d); + hi = MUX(ch, 0, hi); + for (k = 31; k > 0; k --) { + int j; + uint32_t w, ctl, hi2, lo2; + + j = 32 - k; + w = (hi << j) | (lo >> k); + ctl = GE(w, d) | (hi >> k); + hi2 = (w - d) >> j; + lo2 = lo - (d << k); + hi = MUX(ctl, hi2, hi); + lo = MUX(ctl, lo2, lo); + q |= ctl << k; + } + cf = GE(lo, d) | hi; + q |= cf; + *r = MUX(cf, lo - d, lo); + return q; +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_encode.c b/BearSSL-OG/libbearssl/src/int/i32_encode.c new file mode 100644 index 0000000..303652f --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_encode.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i32_encode(void *dst, size_t len, const uint32_t *x) +{ + unsigned char *buf; + size_t k; + + buf = dst; + + /* + * Compute the announced size of x in bytes; extra bytes are + * filled with zeros. + */ + k = (x[0] + 7) >> 3; + while (len > k) { + *buf ++ = 0; + len --; + } + + /* + * Now we use k as index within x[]. That index starts at 1; + * we initialize it to the topmost complete word, and process + * any remaining incomplete word. + */ + k = (len + 3) >> 2; + switch (len & 3) { + case 3: + *buf ++ = x[k] >> 16; + /* fall through */ + case 2: + *buf ++ = x[k] >> 8; + /* fall through */ + case 1: + *buf ++ = x[k]; + k --; + } + + /* + * Encode all complete words. + */ + while (k > 0) { + br_enc32be(buf, x[k]); + k --; + buf += 4; + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_fmont.c b/BearSSL-OG/libbearssl/src/int/i32_fmont.c new file mode 100644 index 0000000..dc1c934 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_fmont.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i32_from_monty(uint32_t *x, const uint32_t *m, uint32_t m0i) +{ + size_t len, u, v; + + len = (m[0] + 31) >> 5; + for (u = 0; u < len; u ++) { + uint32_t f; + uint64_t cc; + + f = x[1] * m0i; + cc = 0; + for (v = 0; v < len; v ++) { + uint64_t z; + + z = (uint64_t)x[v + 1] + MUL(f, m[v + 1]) + cc; + cc = z >> 32; + if (v != 0) { + x[v] = (uint32_t)z; + } + } + x[len] = (uint32_t)cc; + } + + /* + * We may have to do an extra subtraction, but only if the + * value in x[] is indeed greater than or equal to that of m[], + * which is why we must do two calls (first call computes the + * carry, second call performs the subtraction only if the carry + * is 0). + */ + br_i32_sub(x, m, NOT(br_i32_sub(x, m, 0))); +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_iszero.c b/BearSSL-OG/libbearssl/src/int/i32_iszero.c new file mode 100644 index 0000000..659df7f --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_iszero.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i32_iszero(const uint32_t *x) +{ + uint32_t z; + size_t u; + + z = 0; + for (u = (x[0] + 31) >> 5; u > 0; u --) { + z |= x[u]; + } + return ~(z | -z) >> 31; +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_modpow.c b/BearSSL-OG/libbearssl/src/int/i32_modpow.c new file mode 100644 index 0000000..034aba0 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_modpow.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i32_modpow(uint32_t *x, + const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2) +{ + size_t mlen; + uint32_t k; + + /* + * 'mlen' is the length of m[] expressed in bytes (including + * the "bit length" first field). + */ + mlen = ((m[0] + 63) >> 5) * sizeof m[0]; + + /* + * Throughout the algorithm: + * -- t1[] is in Montgomery representation; it contains x, x^2, + * x^4, x^8... + * -- The result is accumulated, in normal representation, in + * the x[] array. + * -- t2[] is used as destination buffer for each multiplication. + * + * Note that there is no need to call br_i32_from_monty(). + */ + memcpy(t1, x, mlen); + br_i32_to_monty(t1, m); + br_i32_zero(x, m[0]); + x[1] = 1; + for (k = 0; k < ((uint32_t)elen << 3); k ++) { + uint32_t ctl; + + ctl = (e[elen - 1 - (k >> 3)] >> (k & 7)) & 1; + br_i32_montymul(t2, x, t1, m, m0i); + CCOPY(ctl, x, t2, mlen); + br_i32_montymul(t2, t1, t1, m, m0i); + memcpy(t1, t2, mlen); + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_montmul.c b/BearSSL-OG/libbearssl/src/int/i32_montmul.c new file mode 100644 index 0000000..7edb376 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_montmul.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i32_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, + const uint32_t *m, uint32_t m0i) +{ + size_t len, u, v; + uint64_t dh; + + len = (m[0] + 31) >> 5; + br_i32_zero(d, m[0]); + dh = 0; + for (u = 0; u < len; u ++) { + uint32_t f, xu; + uint64_t r1, r2, zh; + + xu = x[u + 1]; + f = (d[1] + x[u + 1] * y[1]) * m0i; + r1 = 0; + r2 = 0; + for (v = 0; v < len; v ++) { + uint64_t z; + uint32_t t; + + z = (uint64_t)d[v + 1] + MUL(xu, y[v + 1]) + r1; + r1 = z >> 32; + t = (uint32_t)z; + z = (uint64_t)t + MUL(f, m[v + 1]) + r2; + r2 = z >> 32; + if (v != 0) { + d[v] = (uint32_t)z; + } + } + zh = dh + r1 + r2; + d[len] = (uint32_t)zh; + dh = zh >> 32; + } + + /* + * d[] may still be greater than m[] at that point; notably, the + * 'dh' word may be non-zero. + */ + br_i32_sub(d, m, NEQ(dh, 0) | NOT(br_i32_sub(d, m, 0))); +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_mulacc.c b/BearSSL-OG/libbearssl/src/int/i32_mulacc.c new file mode 100644 index 0000000..55da385 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_mulacc.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i32_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b) +{ + size_t alen, blen, u; + + alen = (a[0] + 31) >> 5; + blen = (b[0] + 31) >> 5; + d[0] = a[0] + b[0]; + for (u = 0; u < blen; u ++) { + uint32_t f; + size_t v; +#if BR_64 + uint64_t cc; +#else + uint32_t cc; +#endif + + f = b[1 + u]; + cc = 0; + for (v = 0; v < alen; v ++) { + uint64_t z; + + z = (uint64_t)d[1 + u + v] + MUL(f, a[1 + v]) + cc; + cc = z >> 32; + d[1 + u + v] = (uint32_t)z; + } + d[1 + u + alen] = (uint32_t)cc; + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_muladd.c b/BearSSL-OG/libbearssl/src/int/i32_muladd.c new file mode 100644 index 0000000..dd526ad --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_muladd.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i32_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m) +{ + uint32_t m_bitlen; + size_t u, mlen; + uint32_t a0, a1, b0, hi, g, q, tb; + uint32_t chf, clow, under, over; + uint64_t cc; + + /* + * We can test on the modulus bit length since we accept to + * leak that length. + */ + m_bitlen = m[0]; + if (m_bitlen == 0) { + return; + } + if (m_bitlen <= 32) { + x[1] = br_rem(x[1], z, m[1]); + return; + } + mlen = (m_bitlen + 31) >> 5; + + /* + * Principle: we estimate the quotient (x*2^32+z)/m by + * doing a 64/32 division with the high words. + * + * Let: + * w = 2^32 + * a = (w*a0 + a1) * w^N + a2 + * b = b0 * w^N + b2 + * such that: + * 0 <= a0 < w + * 0 <= a1 < w + * 0 <= a2 < w^N + * w/2 <= b0 < w + * 0 <= b2 < w^N + * a < w*b + * I.e. the two top words of a are a0:a1, the top word of b is + * b0, we ensured that b0 is "full" (high bit set), and a is + * such that the quotient q = a/b fits on one word (0 <= q < w). + * + * If a = b*q + r (with 0 <= r < q), we can estimate q by + * doing an Euclidean division on the top words: + * a0*w+a1 = b0*u + v (with 0 <= v < w) + * Then the following holds: + * 0 <= u <= w + * u-2 <= q <= u + */ + a0 = br_i32_word(x, m_bitlen - 32); + hi = x[mlen]; + memmove(x + 2, x + 1, (mlen - 1) * sizeof *x); + x[1] = z; + a1 = br_i32_word(x, m_bitlen - 32); + b0 = br_i32_word(m, m_bitlen - 32); + + /* + * We estimate a divisor q. If the quotient returned by br_div() + * is g: + * -- If a0 == b0 then g == 0; we want q = 0xFFFFFFFF. + * -- Otherwise: + * -- if g == 0 then we set q = 0; + * -- otherwise, we set q = g - 1. + * The properties described above then ensure that the true + * quotient is q-1, q or q+1. + */ + g = br_div(a0, a1, b0); + q = MUX(EQ(a0, b0), 0xFFFFFFFF, MUX(EQ(g, 0), 0, g - 1)); + + /* + * We subtract q*m from x (with the extra high word of value 'hi'). + * Since q may be off by 1 (in either direction), we may have to + * add or subtract m afterwards. + * + * The 'tb' flag will be true (1) at the end of the loop if the + * result is greater than or equal to the modulus (not counting + * 'hi' or the carry). + */ + cc = 0; + tb = 1; + for (u = 1; u <= mlen; u ++) { + uint32_t mw, zw, xw, nxw; + uint64_t zl; + + mw = m[u]; + zl = MUL(mw, q) + cc; + cc = (uint32_t)(zl >> 32); + zw = (uint32_t)zl; + xw = x[u]; + nxw = xw - zw; + cc += (uint64_t)GT(nxw, xw); + x[u] = nxw; + tb = MUX(EQ(nxw, mw), tb, GT(nxw, mw)); + } + + /* + * If we underestimated q, then either cc < hi (one extra bit + * beyond the top array word), or cc == hi and tb is true (no + * extra bit, but the result is not lower than the modulus). In + * these cases we must subtract m once. + * + * Otherwise, we may have overestimated, which will show as + * cc > hi (thus a negative result). Correction is adding m once. + */ + chf = (uint32_t)(cc >> 32); + clow = (uint32_t)cc; + over = chf | GT(clow, hi); + under = ~over & (tb | (~chf & LT(clow, hi))); + br_i32_add(x, m, over); + br_i32_sub(x, m, under); +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_ninv32.c b/BearSSL-OG/libbearssl/src/int/i32_ninv32.c new file mode 100644 index 0000000..6564434 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_ninv32.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i32_ninv32(uint32_t x) +{ + uint32_t y; + + y = 2 - x; + y *= 2 - y * x; + y *= 2 - y * x; + y *= 2 - y * x; + y *= 2 - y * x; + return MUX(x & 1, -y, 0); +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_reduce.c b/BearSSL-OG/libbearssl/src/int/i32_reduce.c new file mode 100644 index 0000000..90fff09 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_reduce.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i32_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m) +{ + uint32_t m_bitlen, a_bitlen; + size_t mlen, alen, u; + + m_bitlen = m[0]; + mlen = (m_bitlen + 31) >> 5; + + x[0] = m_bitlen; + if (m_bitlen == 0) { + return; + } + + /* + * If the source is shorter, then simply copy all words from a[] + * and zero out the upper words. + */ + a_bitlen = a[0]; + alen = (a_bitlen + 31) >> 5; + if (a_bitlen < m_bitlen) { + memcpy(x + 1, a + 1, alen * sizeof *a); + for (u = alen; u < mlen; u ++) { + x[u + 1] = 0; + } + return; + } + + /* + * The source length is at least equal to that of the modulus. + * We must thus copy N-1 words, and input the remaining words + * one by one. + */ + memcpy(x + 1, a + 2 + (alen - mlen), (mlen - 1) * sizeof *a); + x[mlen] = 0; + for (u = 1 + alen - mlen; u > 0; u --) { + br_i32_muladd_small(x, a[u], m); + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_sub.c b/BearSSL-OG/libbearssl/src/int/i32_sub.c new file mode 100644 index 0000000..9c50023 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_sub.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_i32_sub(uint32_t *a, const uint32_t *b, uint32_t ctl) +{ + uint32_t cc; + size_t u, m; + + cc = 0; + m = (a[0] + 63) >> 5; + for (u = 1; u < m; u ++) { + uint32_t aw, bw, naw; + + aw = a[u]; + bw = b[u]; + naw = aw - bw - cc; + + /* + * Carry is 1 if naw > aw. Carry is 1 also if naw == aw + * AND the carry was already 1. + */ + cc = (cc & EQ(naw, aw)) | GT(naw, aw); + a[u] = MUX(ctl, naw, aw); + } + return cc; +} diff --git a/BearSSL-OG/libbearssl/src/int/i32_tmont.c b/BearSSL-OG/libbearssl/src/int/i32_tmont.c new file mode 100644 index 0000000..058cd88 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i32_tmont.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_i32_to_monty(uint32_t *x, const uint32_t *m) +{ + uint32_t k; + + for (k = (m[0] + 31) >> 5; k > 0; k --) { + br_i32_muladd_small(x, 0, m); + } +} diff --git a/BearSSL-OG/libbearssl/src/int/i62_modpow2.c b/BearSSL-OG/libbearssl/src/int/i62_modpow2.c new file mode 100644 index 0000000..2db537f --- /dev/null +++ b/BearSSL-OG/libbearssl/src/int/i62_modpow2.c @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +#if BR_INT128 + +/* + * Compute x*y+v1+v2. Operands are 64-bit, and result is 128-bit, with + * high word in "hi" and low word in "lo". + */ +#define FMA1(hi, lo, x, y, v1, v2) do { \ + unsigned __int128 fmaz; \ + fmaz = (unsigned __int128)(x) * (unsigned __int128)(y) \ + + (unsigned __int128)(v1) + (unsigned __int128)(v2); \ + (hi) = (uint64_t)(fmaz >> 64); \ + (lo) = (uint64_t)fmaz; \ + } while (0) + +/* + * Compute x1*y1+x2*y2+v1+v2. Operands are 64-bit, and result is 128-bit, + * with high word in "hi" and low word in "lo". + * + * Callers should ensure that the two inner products, and the v1 and v2 + * operands, are multiple of 4 (this is not used by this specific definition + * but may help other implementations). + */ +#define FMA2(hi, lo, x1, y1, x2, y2, v1, v2) do { \ + unsigned __int128 fmaz; \ + fmaz = (unsigned __int128)(x1) * (unsigned __int128)(y1) \ + + (unsigned __int128)(x2) * (unsigned __int128)(y2) \ + + (unsigned __int128)(v1) + (unsigned __int128)(v2); \ + (hi) = (uint64_t)(fmaz >> 64); \ + (lo) = (uint64_t)fmaz; \ + } while (0) + +#elif BR_UMUL128 + +#include + +#define FMA1(hi, lo, x, y, v1, v2) do { \ + uint64_t fmahi, fmalo; \ + unsigned char fmacc; \ + fmalo = _umul128((x), (y), &fmahi); \ + fmacc = _addcarry_u64(0, fmalo, (v1), &fmalo); \ + _addcarry_u64(fmacc, fmahi, 0, &fmahi); \ + fmacc = _addcarry_u64(0, fmalo, (v2), &(lo)); \ + _addcarry_u64(fmacc, fmahi, 0, &(hi)); \ + } while (0) + +/* + * Normally we should use _addcarry_u64() for FMA2 too, but it makes + * Visual Studio crash. Instead we use this version, which leverages + * the fact that the vx operands, and the products, are multiple of 4. + * This is unfortunately slower. + */ +#define FMA2(hi, lo, x1, y1, x2, y2, v1, v2) do { \ + uint64_t fma1hi, fma1lo; \ + uint64_t fma2hi, fma2lo; \ + uint64_t fmatt; \ + fma1lo = _umul128((x1), (y1), &fma1hi); \ + fma2lo = _umul128((x2), (y2), &fma2hi); \ + fmatt = (fma1lo >> 2) + (fma2lo >> 2) \ + + ((v1) >> 2) + ((v2) >> 2); \ + (lo) = fmatt << 2; \ + (hi) = fma1hi + fma2hi + (fmatt >> 62); \ + } while (0) + +/* + * The FMA2 macro definition we would prefer to use, but it triggers + * an internal compiler error in Visual Studio 2015. + * +#define FMA2(hi, lo, x1, y1, x2, y2, v1, v2) do { \ + uint64_t fma1hi, fma1lo; \ + uint64_t fma2hi, fma2lo; \ + unsigned char fmacc; \ + fma1lo = _umul128((x1), (y1), &fma1hi); \ + fma2lo = _umul128((x2), (y2), &fma2hi); \ + fmacc = _addcarry_u64(0, fma1lo, (v1), &fma1lo); \ + _addcarry_u64(fmacc, fma1hi, 0, &fma1hi); \ + fmacc = _addcarry_u64(0, fma2lo, (v2), &fma2lo); \ + _addcarry_u64(fmacc, fma2hi, 0, &fma2hi); \ + fmacc = _addcarry_u64(0, fma1lo, fma2lo, &(lo)); \ + _addcarry_u64(fmacc, fma1hi, fma2hi, &(hi)); \ + } while (0) + */ + +#endif + +#define MASK62 ((uint64_t)0x3FFFFFFFFFFFFFFF) +#define MUL62_lo(x, y) (((uint64_t)(x) * (uint64_t)(y)) & MASK62) + +/* + * Subtract b from a, and return the final carry. If 'ctl32' is 0, then + * a[] is kept unmodified, but the final carry is still computed and + * returned. + */ +static uint32_t +i62_sub(uint64_t *a, const uint64_t *b, size_t num, uint32_t ctl32) +{ + uint64_t cc, mask; + size_t u; + + cc = 0; + ctl32 = -ctl32; + mask = (uint64_t)ctl32 | ((uint64_t)ctl32 << 32); + for (u = 0; u < num; u ++) { + uint64_t aw, bw, dw; + + aw = a[u]; + bw = b[u]; + dw = aw - bw - cc; + cc = dw >> 63; + dw &= MASK62; + a[u] = aw ^ (mask & (dw ^ aw)); + } + return (uint32_t)cc; +} + +/* + * Montgomery multiplication, over arrays of 62-bit values. The + * destination array (d) must be distinct from the other operands + * (x, y and m). All arrays are in little-endian format (least + * significant word comes first) over 'num' words. + */ +static void +montymul(uint64_t *d, const uint64_t *x, const uint64_t *y, + const uint64_t *m, size_t num, uint64_t m0i) +{ + uint64_t dh; + size_t u, num4; + + num4 = 1 + ((num - 1) & ~(size_t)3); + memset(d, 0, num * sizeof *d); + dh = 0; + for (u = 0; u < num; u ++) { + size_t v; + uint64_t f, xu; + uint64_t r, zh; + uint64_t hi, lo; + + xu = x[u] << 2; + f = MUL62_lo(d[0] + MUL62_lo(x[u], y[0]), m0i) << 2; + + FMA2(hi, lo, xu, y[0], f, m[0], d[0] << 2, 0); + r = hi; + + for (v = 1; v < num4; v += 4) { + FMA2(hi, lo, xu, y[v + 0], + f, m[v + 0], d[v + 0] << 2, r << 2); + r = hi + (r >> 62); + d[v - 1] = lo >> 2; + FMA2(hi, lo, xu, y[v + 1], + f, m[v + 1], d[v + 1] << 2, r << 2); + r = hi + (r >> 62); + d[v + 0] = lo >> 2; + FMA2(hi, lo, xu, y[v + 2], + f, m[v + 2], d[v + 2] << 2, r << 2); + r = hi + (r >> 62); + d[v + 1] = lo >> 2; + FMA2(hi, lo, xu, y[v + 3], + f, m[v + 3], d[v + 3] << 2, r << 2); + r = hi + (r >> 62); + d[v + 2] = lo >> 2; + } + for (; v < num; v ++) { + FMA2(hi, lo, xu, y[v], f, m[v], d[v] << 2, r << 2); + r = hi + (r >> 62); + d[v - 1] = lo >> 2; + } + + zh = dh + r; + d[num - 1] = zh & MASK62; + dh = zh >> 62; + } + i62_sub(d, m, num, (uint32_t)dh | NOT(i62_sub(d, m, num, 0))); +} + +/* + * Conversion back from Montgomery representation. + */ +static void +frommonty(uint64_t *x, const uint64_t *m, size_t num, uint64_t m0i) +{ + size_t u, v; + + for (u = 0; u < num; u ++) { + uint64_t f, cc; + + f = MUL62_lo(x[0], m0i) << 2; + cc = 0; + for (v = 0; v < num; v ++) { + uint64_t hi, lo; + + FMA1(hi, lo, f, m[v], x[v] << 2, cc); + cc = hi << 2; + if (v != 0) { + x[v - 1] = lo >> 2; + } + } + x[num - 1] = cc >> 2; + } + i62_sub(x, m, num, NOT(i62_sub(x, m, num, 0))); +} + +/* see inner.h */ +uint32_t +br_i62_modpow_opt(uint32_t *x31, const unsigned char *e, size_t elen, + const uint32_t *m31, uint32_t m0i31, uint64_t *tmp, size_t twlen) +{ + size_t u, mw31num, mw62num; + uint64_t *x, *m, *t1, *t2; + uint64_t m0i; + uint32_t acc; + int win_len, acc_len; + + /* + * Get modulus size, in words. + */ + mw31num = (m31[0] + 31) >> 5; + mw62num = (mw31num + 1) >> 1; + + /* + * In order to apply this function, we must have enough room to + * copy the operand and modulus into the temporary array, along + * with at least two temporaries. If there is not enough room, + * switch to br_i31_modpow(). We also use br_i31_modpow() if the + * modulus length is not at least four words (94 bits or more). + */ + if (mw31num < 4 || (mw62num << 2) > twlen) { + /* + * We assume here that we can split an aligned uint64_t + * into two properly aligned uint32_t. Since both types + * are supposed to have an exact width with no padding, + * then this property must hold. + */ + size_t txlen; + + txlen = mw31num + 1; + if (twlen < txlen) { + return 0; + } + br_i31_modpow(x31, e, elen, m31, m0i31, + (uint32_t *)tmp, (uint32_t *)tmp + txlen); + return 1; + } + + /* + * Convert x to Montgomery representation: this means that + * we replace x with x*2^z mod m, where z is the smallest multiple + * of the word size such that 2^z >= m. We want to reuse the 31-bit + * functions here (for constant-time operation), but we need z + * for a 62-bit word size. + */ + for (u = 0; u < mw62num; u ++) { + br_i31_muladd_small(x31, 0, m31); + br_i31_muladd_small(x31, 0, m31); + } + + /* + * Assemble operands into arrays of 62-bit words. Note that + * all the arrays of 62-bit words that we will handle here + * are without any leading size word. + * + * We also adjust tmp and twlen to account for the words used + * for these extra arrays. + */ + m = tmp; + x = tmp + mw62num; + tmp += (mw62num << 1); + twlen -= (mw62num << 1); + for (u = 0; u < mw31num; u += 2) { + size_t v; + + v = u >> 1; + if ((u + 1) == mw31num) { + m[v] = (uint64_t)m31[u + 1]; + x[v] = (uint64_t)x31[u + 1]; + } else { + m[v] = (uint64_t)m31[u + 1] + + ((uint64_t)m31[u + 2] << 31); + x[v] = (uint64_t)x31[u + 1] + + ((uint64_t)x31[u + 2] << 31); + } + } + + /* + * Compute window size. We support windows up to 5 bits; for a + * window of size k bits, we need 2^k+1 temporaries (for k = 1, + * we use special code that uses only 2 temporaries). + */ + for (win_len = 5; win_len > 1; win_len --) { + if ((((uint32_t)1 << win_len) + 1) * mw62num <= twlen) { + break; + } + } + + t1 = tmp; + t2 = tmp + mw62num; + + /* + * Compute m0i, which is equal to -(1/m0) mod 2^62. We were + * provided with m0i31, which already fulfills this property + * modulo 2^31; the single expression below is then sufficient. + */ + m0i = (uint64_t)m0i31; + m0i = MUL62_lo(m0i, (uint64_t)2 + MUL62_lo(m0i, m[0])); + + /* + * Compute window contents. If the window has size one bit only, + * then t2 is set to x; otherwise, t2[0] is left untouched, and + * t2[k] is set to x^k (for k >= 1). + */ + if (win_len == 1) { + memcpy(t2, x, mw62num * sizeof *x); + } else { + uint64_t *base; + + memcpy(t2 + mw62num, x, mw62num * sizeof *x); + base = t2 + mw62num; + for (u = 2; u < ((unsigned)1 << win_len); u ++) { + montymul(base + mw62num, base, x, m, mw62num, m0i); + base += mw62num; + } + } + + /* + * Set x to 1, in Montgomery representation. We again use the + * 31-bit code. + */ + br_i31_zero(x31, m31[0]); + x31[(m31[0] + 31) >> 5] = 1; + br_i31_muladd_small(x31, 0, m31); + if (mw31num & 1) { + br_i31_muladd_small(x31, 0, m31); + } + for (u = 0; u < mw31num; u += 2) { + size_t v; + + v = u >> 1; + if ((u + 1) == mw31num) { + x[v] = (uint64_t)x31[u + 1]; + } else { + x[v] = (uint64_t)x31[u + 1] + + ((uint64_t)x31[u + 2] << 31); + } + } + + /* + * We process bits from most to least significant. At each + * loop iteration, we have acc_len bits in acc. + */ + acc = 0; + acc_len = 0; + while (acc_len > 0 || elen > 0) { + int i, k; + uint32_t bits; + uint64_t mask1, mask2; + + /* + * Get the next bits. + */ + k = win_len; + if (acc_len < win_len) { + if (elen > 0) { + acc = (acc << 8) | *e ++; + elen --; + acc_len += 8; + } else { + k = acc_len; + } + } + bits = (acc >> (acc_len - k)) & (((uint32_t)1 << k) - 1); + acc_len -= k; + + /* + * We could get exactly k bits. Compute k squarings. + */ + for (i = 0; i < k; i ++) { + montymul(t1, x, x, m, mw62num, m0i); + memcpy(x, t1, mw62num * sizeof *x); + } + + /* + * Window lookup: we want to set t2 to the window + * lookup value, assuming the bits are non-zero. If + * the window length is 1 bit only, then t2 is + * already set; otherwise, we do a constant-time lookup. + */ + if (win_len > 1) { + uint64_t *base; + + memset(t2, 0, mw62num * sizeof *t2); + base = t2 + mw62num; + for (u = 1; u < ((uint32_t)1 << k); u ++) { + uint64_t mask; + size_t v; + + mask = -(uint64_t)EQ(u, bits); + for (v = 0; v < mw62num; v ++) { + t2[v] |= mask & base[v]; + } + base += mw62num; + } + } + + /* + * Multiply with the looked-up value. We keep the product + * only if the exponent bits are not all-zero. + */ + montymul(t1, x, t2, m, mw62num, m0i); + mask1 = -(uint64_t)EQ(bits, 0); + mask2 = ~mask1; + for (u = 0; u < mw62num; u ++) { + x[u] = (mask1 & x[u]) | (mask2 & t1[u]); + } + } + + /* + * Convert back from Montgomery representation. + */ + frommonty(x, m, mw62num, m0i); + + /* + * Convert result into 31-bit words. + */ + for (u = 0; u < mw31num; u += 2) { + uint64_t zw; + + zw = x[u >> 1]; + x31[u + 1] = (uint32_t)zw & 0x7FFFFFFF; + if ((u + 1) < mw31num) { + x31[u + 2] = (uint32_t)(zw >> 31); + } + } + return 1; +} + +#else + +/* see inner.h */ +uint32_t +br_i62_modpow_opt(uint32_t *x31, const unsigned char *e, size_t elen, + const uint32_t *m31, uint32_t m0i31, uint64_t *tmp, size_t twlen) +{ + size_t mwlen; + + mwlen = (m31[0] + 63) >> 5; + if (twlen < mwlen) { + return 0; + } + return br_i31_modpow_opt(x31, e, elen, m31, m0i31, + (uint32_t *)tmp, twlen << 1); +} + +#endif + +/* see inner.h */ +uint32_t +br_i62_modpow_opt_as_i31(uint32_t *x31, const unsigned char *e, size_t elen, + const uint32_t *m31, uint32_t m0i31, uint32_t *tmp, size_t twlen) +{ + /* + * As documented, this function expects the 'tmp' argument to be + * 64-bit aligned. This is OK since this function is internal (it + * is not part of BearSSL's public API). + */ + return br_i62_modpow_opt(x31, e, elen, m31, m0i31, + (uint64_t *)tmp, twlen >> 1); +} diff --git a/BearSSL-OG/libbearssl/src/kdf/hkdf.c b/BearSSL-OG/libbearssl/src/kdf/hkdf.c new file mode 100644 index 0000000..6a36851 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/kdf/hkdf.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +const unsigned char br_hkdf_no_salt = 0; + +/* see bearssl_kdf.h */ +void +br_hkdf_init(br_hkdf_context *hc, const br_hash_class *digest_vtable, + const void *salt, size_t salt_len) +{ + br_hmac_key_context kc; + unsigned char tmp[64]; + + if (salt == BR_HKDF_NO_SALT) { + salt = tmp; + salt_len = br_digest_size(digest_vtable); + memset(tmp, 0, salt_len); + } + br_hmac_key_init(&kc, digest_vtable, salt, salt_len); + br_hmac_init(&hc->u.hmac_ctx, &kc, 0); + hc->dig_len = br_hmac_size(&hc->u.hmac_ctx); +} + +/* see bearssl_kdf.h */ +void +br_hkdf_inject(br_hkdf_context *hc, const void *ikm, size_t ikm_len) +{ + br_hmac_update(&hc->u.hmac_ctx, ikm, ikm_len); +} + +/* see bearssl_kdf.h */ +void +br_hkdf_flip(br_hkdf_context *hc) +{ + unsigned char tmp[64]; + + br_hmac_out(&hc->u.hmac_ctx, tmp); + br_hmac_key_init(&hc->u.prk_ctx, + br_hmac_get_digest(&hc->u.hmac_ctx), tmp, hc->dig_len); + hc->ptr = hc->dig_len; + hc->chunk_num = 0; +} + +/* see bearssl_kdf.h */ +size_t +br_hkdf_produce(br_hkdf_context *hc, + const void *info, size_t info_len, void *out, size_t out_len) +{ + size_t tlen; + + tlen = 0; + while (out_len > 0) { + size_t clen; + + if (hc->ptr == hc->dig_len) { + br_hmac_context hmac_ctx; + unsigned char x; + + hc->chunk_num ++; + if (hc->chunk_num == 256) { + return tlen; + } + x = hc->chunk_num; + br_hmac_init(&hmac_ctx, &hc->u.prk_ctx, 0); + if (x != 1) { + br_hmac_update(&hmac_ctx, hc->buf, hc->dig_len); + } + br_hmac_update(&hmac_ctx, info, info_len); + br_hmac_update(&hmac_ctx, &x, 1); + br_hmac_out(&hmac_ctx, hc->buf); + hc->ptr = 0; + } + clen = hc->dig_len - hc->ptr; + if (clen > out_len) { + clen = out_len; + } + memcpy(out, hc->buf + hc->ptr, clen); + out = (unsigned char *)out + clen; + out_len -= clen; + hc->ptr += clen; + tlen += clen; + } + return tlen; +} diff --git a/BearSSL-OG/libbearssl/src/kdf/shake.c b/BearSSL-OG/libbearssl/src/kdf/shake.c new file mode 100644 index 0000000..80d7176 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/kdf/shake.c @@ -0,0 +1,590 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Round constants. + */ +static const uint64_t RC[] = { + 0x0000000000000001, 0x0000000000008082, + 0x800000000000808A, 0x8000000080008000, + 0x000000000000808B, 0x0000000080000001, + 0x8000000080008081, 0x8000000000008009, + 0x000000000000008A, 0x0000000000000088, + 0x0000000080008009, 0x000000008000000A, + 0x000000008000808B, 0x800000000000008B, + 0x8000000000008089, 0x8000000000008003, + 0x8000000000008002, 0x8000000000000080, + 0x000000000000800A, 0x800000008000000A, + 0x8000000080008081, 0x8000000000008080, + 0x0000000080000001, 0x8000000080008008 +}; + +/* + * XOR a block of data into the provided state. This supports only + * blocks whose length is a multiple of 64 bits. + */ +static void +xor_block(uint64_t *A, const void *data, size_t rate) +{ + size_t u; + + for (u = 0; u < rate; u += 8) { + A[u >> 3] ^= br_dec64le((const unsigned char *)data + u); + } +} + +/* + * Process a block with the provided data. The data length must be a + * multiple of 8 (in bytes); normally, this is the "rate". + */ +static void +process_block(uint64_t *A) +{ + uint64_t t0, t1, t2, t3, t4; + uint64_t tt0, tt1, tt2, tt3; + uint64_t t, kt; + uint64_t c0, c1, c2, c3, c4, bnn; + int j; + + /* + * Compute the 24 rounds. This loop is partially unrolled (each + * iteration computes two rounds). + */ + for (j = 0; j < 24; j += 2) { + + tt0 = A[ 1] ^ A[ 6]; + tt1 = A[11] ^ A[16]; + tt0 ^= A[21] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >> 63); + tt2 = A[ 4] ^ A[ 9]; + tt3 = A[14] ^ A[19]; + tt0 ^= A[24]; + tt2 ^= tt3; + t0 = tt0 ^ tt2; + + tt0 = A[ 2] ^ A[ 7]; + tt1 = A[12] ^ A[17]; + tt0 ^= A[22] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >> 63); + tt2 = A[ 0] ^ A[ 5]; + tt3 = A[10] ^ A[15]; + tt0 ^= A[20]; + tt2 ^= tt3; + t1 = tt0 ^ tt2; + + tt0 = A[ 3] ^ A[ 8]; + tt1 = A[13] ^ A[18]; + tt0 ^= A[23] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >> 63); + tt2 = A[ 1] ^ A[ 6]; + tt3 = A[11] ^ A[16]; + tt0 ^= A[21]; + tt2 ^= tt3; + t2 = tt0 ^ tt2; + + tt0 = A[ 4] ^ A[ 9]; + tt1 = A[14] ^ A[19]; + tt0 ^= A[24] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >> 63); + tt2 = A[ 2] ^ A[ 7]; + tt3 = A[12] ^ A[17]; + tt0 ^= A[22]; + tt2 ^= tt3; + t3 = tt0 ^ tt2; + + tt0 = A[ 0] ^ A[ 5]; + tt1 = A[10] ^ A[15]; + tt0 ^= A[20] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >> 63); + tt2 = A[ 3] ^ A[ 8]; + tt3 = A[13] ^ A[18]; + tt0 ^= A[23]; + tt2 ^= tt3; + t4 = tt0 ^ tt2; + + A[ 0] = A[ 0] ^ t0; + A[ 5] = A[ 5] ^ t0; + A[10] = A[10] ^ t0; + A[15] = A[15] ^ t0; + A[20] = A[20] ^ t0; + A[ 1] = A[ 1] ^ t1; + A[ 6] = A[ 6] ^ t1; + A[11] = A[11] ^ t1; + A[16] = A[16] ^ t1; + A[21] = A[21] ^ t1; + A[ 2] = A[ 2] ^ t2; + A[ 7] = A[ 7] ^ t2; + A[12] = A[12] ^ t2; + A[17] = A[17] ^ t2; + A[22] = A[22] ^ t2; + A[ 3] = A[ 3] ^ t3; + A[ 8] = A[ 8] ^ t3; + A[13] = A[13] ^ t3; + A[18] = A[18] ^ t3; + A[23] = A[23] ^ t3; + A[ 4] = A[ 4] ^ t4; + A[ 9] = A[ 9] ^ t4; + A[14] = A[14] ^ t4; + A[19] = A[19] ^ t4; + A[24] = A[24] ^ t4; + A[ 5] = (A[ 5] << 36) | (A[ 5] >> (64 - 36)); + A[10] = (A[10] << 3) | (A[10] >> (64 - 3)); + A[15] = (A[15] << 41) | (A[15] >> (64 - 41)); + A[20] = (A[20] << 18) | (A[20] >> (64 - 18)); + A[ 1] = (A[ 1] << 1) | (A[ 1] >> (64 - 1)); + A[ 6] = (A[ 6] << 44) | (A[ 6] >> (64 - 44)); + A[11] = (A[11] << 10) | (A[11] >> (64 - 10)); + A[16] = (A[16] << 45) | (A[16] >> (64 - 45)); + A[21] = (A[21] << 2) | (A[21] >> (64 - 2)); + A[ 2] = (A[ 2] << 62) | (A[ 2] >> (64 - 62)); + A[ 7] = (A[ 7] << 6) | (A[ 7] >> (64 - 6)); + A[12] = (A[12] << 43) | (A[12] >> (64 - 43)); + A[17] = (A[17] << 15) | (A[17] >> (64 - 15)); + A[22] = (A[22] << 61) | (A[22] >> (64 - 61)); + A[ 3] = (A[ 3] << 28) | (A[ 3] >> (64 - 28)); + A[ 8] = (A[ 8] << 55) | (A[ 8] >> (64 - 55)); + A[13] = (A[13] << 25) | (A[13] >> (64 - 25)); + A[18] = (A[18] << 21) | (A[18] >> (64 - 21)); + A[23] = (A[23] << 56) | (A[23] >> (64 - 56)); + A[ 4] = (A[ 4] << 27) | (A[ 4] >> (64 - 27)); + A[ 9] = (A[ 9] << 20) | (A[ 9] >> (64 - 20)); + A[14] = (A[14] << 39) | (A[14] >> (64 - 39)); + A[19] = (A[19] << 8) | (A[19] >> (64 - 8)); + A[24] = (A[24] << 14) | (A[24] >> (64 - 14)); + bnn = ~A[12]; + kt = A[ 6] | A[12]; + c0 = A[ 0] ^ kt; + kt = bnn | A[18]; + c1 = A[ 6] ^ kt; + kt = A[18] & A[24]; + c2 = A[12] ^ kt; + kt = A[24] | A[ 0]; + c3 = A[18] ^ kt; + kt = A[ 0] & A[ 6]; + c4 = A[24] ^ kt; + A[ 0] = c0; + A[ 6] = c1; + A[12] = c2; + A[18] = c3; + A[24] = c4; + bnn = ~A[22]; + kt = A[ 9] | A[10]; + c0 = A[ 3] ^ kt; + kt = A[10] & A[16]; + c1 = A[ 9] ^ kt; + kt = A[16] | bnn; + c2 = A[10] ^ kt; + kt = A[22] | A[ 3]; + c3 = A[16] ^ kt; + kt = A[ 3] & A[ 9]; + c4 = A[22] ^ kt; + A[ 3] = c0; + A[ 9] = c1; + A[10] = c2; + A[16] = c3; + A[22] = c4; + bnn = ~A[19]; + kt = A[ 7] | A[13]; + c0 = A[ 1] ^ kt; + kt = A[13] & A[19]; + c1 = A[ 7] ^ kt; + kt = bnn & A[20]; + c2 = A[13] ^ kt; + kt = A[20] | A[ 1]; + c3 = bnn ^ kt; + kt = A[ 1] & A[ 7]; + c4 = A[20] ^ kt; + A[ 1] = c0; + A[ 7] = c1; + A[13] = c2; + A[19] = c3; + A[20] = c4; + bnn = ~A[17]; + kt = A[ 5] & A[11]; + c0 = A[ 4] ^ kt; + kt = A[11] | A[17]; + c1 = A[ 5] ^ kt; + kt = bnn | A[23]; + c2 = A[11] ^ kt; + kt = A[23] & A[ 4]; + c3 = bnn ^ kt; + kt = A[ 4] | A[ 5]; + c4 = A[23] ^ kt; + A[ 4] = c0; + A[ 5] = c1; + A[11] = c2; + A[17] = c3; + A[23] = c4; + bnn = ~A[ 8]; + kt = bnn & A[14]; + c0 = A[ 2] ^ kt; + kt = A[14] | A[15]; + c1 = bnn ^ kt; + kt = A[15] & A[21]; + c2 = A[14] ^ kt; + kt = A[21] | A[ 2]; + c3 = A[15] ^ kt; + kt = A[ 2] & A[ 8]; + c4 = A[21] ^ kt; + A[ 2] = c0; + A[ 8] = c1; + A[14] = c2; + A[15] = c3; + A[21] = c4; + A[ 0] = A[ 0] ^ RC[j + 0]; + + tt0 = A[ 6] ^ A[ 9]; + tt1 = A[ 7] ^ A[ 5]; + tt0 ^= A[ 8] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >> 63); + tt2 = A[24] ^ A[22]; + tt3 = A[20] ^ A[23]; + tt0 ^= A[21]; + tt2 ^= tt3; + t0 = tt0 ^ tt2; + + tt0 = A[12] ^ A[10]; + tt1 = A[13] ^ A[11]; + tt0 ^= A[14] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >> 63); + tt2 = A[ 0] ^ A[ 3]; + tt3 = A[ 1] ^ A[ 4]; + tt0 ^= A[ 2]; + tt2 ^= tt3; + t1 = tt0 ^ tt2; + + tt0 = A[18] ^ A[16]; + tt1 = A[19] ^ A[17]; + tt0 ^= A[15] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >> 63); + tt2 = A[ 6] ^ A[ 9]; + tt3 = A[ 7] ^ A[ 5]; + tt0 ^= A[ 8]; + tt2 ^= tt3; + t2 = tt0 ^ tt2; + + tt0 = A[24] ^ A[22]; + tt1 = A[20] ^ A[23]; + tt0 ^= A[21] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >> 63); + tt2 = A[12] ^ A[10]; + tt3 = A[13] ^ A[11]; + tt0 ^= A[14]; + tt2 ^= tt3; + t3 = tt0 ^ tt2; + + tt0 = A[ 0] ^ A[ 3]; + tt1 = A[ 1] ^ A[ 4]; + tt0 ^= A[ 2] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >> 63); + tt2 = A[18] ^ A[16]; + tt3 = A[19] ^ A[17]; + tt0 ^= A[15]; + tt2 ^= tt3; + t4 = tt0 ^ tt2; + + A[ 0] = A[ 0] ^ t0; + A[ 3] = A[ 3] ^ t0; + A[ 1] = A[ 1] ^ t0; + A[ 4] = A[ 4] ^ t0; + A[ 2] = A[ 2] ^ t0; + A[ 6] = A[ 6] ^ t1; + A[ 9] = A[ 9] ^ t1; + A[ 7] = A[ 7] ^ t1; + A[ 5] = A[ 5] ^ t1; + A[ 8] = A[ 8] ^ t1; + A[12] = A[12] ^ t2; + A[10] = A[10] ^ t2; + A[13] = A[13] ^ t2; + A[11] = A[11] ^ t2; + A[14] = A[14] ^ t2; + A[18] = A[18] ^ t3; + A[16] = A[16] ^ t3; + A[19] = A[19] ^ t3; + A[17] = A[17] ^ t3; + A[15] = A[15] ^ t3; + A[24] = A[24] ^ t4; + A[22] = A[22] ^ t4; + A[20] = A[20] ^ t4; + A[23] = A[23] ^ t4; + A[21] = A[21] ^ t4; + A[ 3] = (A[ 3] << 36) | (A[ 3] >> (64 - 36)); + A[ 1] = (A[ 1] << 3) | (A[ 1] >> (64 - 3)); + A[ 4] = (A[ 4] << 41) | (A[ 4] >> (64 - 41)); + A[ 2] = (A[ 2] << 18) | (A[ 2] >> (64 - 18)); + A[ 6] = (A[ 6] << 1) | (A[ 6] >> (64 - 1)); + A[ 9] = (A[ 9] << 44) | (A[ 9] >> (64 - 44)); + A[ 7] = (A[ 7] << 10) | (A[ 7] >> (64 - 10)); + A[ 5] = (A[ 5] << 45) | (A[ 5] >> (64 - 45)); + A[ 8] = (A[ 8] << 2) | (A[ 8] >> (64 - 2)); + A[12] = (A[12] << 62) | (A[12] >> (64 - 62)); + A[10] = (A[10] << 6) | (A[10] >> (64 - 6)); + A[13] = (A[13] << 43) | (A[13] >> (64 - 43)); + A[11] = (A[11] << 15) | (A[11] >> (64 - 15)); + A[14] = (A[14] << 61) | (A[14] >> (64 - 61)); + A[18] = (A[18] << 28) | (A[18] >> (64 - 28)); + A[16] = (A[16] << 55) | (A[16] >> (64 - 55)); + A[19] = (A[19] << 25) | (A[19] >> (64 - 25)); + A[17] = (A[17] << 21) | (A[17] >> (64 - 21)); + A[15] = (A[15] << 56) | (A[15] >> (64 - 56)); + A[24] = (A[24] << 27) | (A[24] >> (64 - 27)); + A[22] = (A[22] << 20) | (A[22] >> (64 - 20)); + A[20] = (A[20] << 39) | (A[20] >> (64 - 39)); + A[23] = (A[23] << 8) | (A[23] >> (64 - 8)); + A[21] = (A[21] << 14) | (A[21] >> (64 - 14)); + bnn = ~A[13]; + kt = A[ 9] | A[13]; + c0 = A[ 0] ^ kt; + kt = bnn | A[17]; + c1 = A[ 9] ^ kt; + kt = A[17] & A[21]; + c2 = A[13] ^ kt; + kt = A[21] | A[ 0]; + c3 = A[17] ^ kt; + kt = A[ 0] & A[ 9]; + c4 = A[21] ^ kt; + A[ 0] = c0; + A[ 9] = c1; + A[13] = c2; + A[17] = c3; + A[21] = c4; + bnn = ~A[14]; + kt = A[22] | A[ 1]; + c0 = A[18] ^ kt; + kt = A[ 1] & A[ 5]; + c1 = A[22] ^ kt; + kt = A[ 5] | bnn; + c2 = A[ 1] ^ kt; + kt = A[14] | A[18]; + c3 = A[ 5] ^ kt; + kt = A[18] & A[22]; + c4 = A[14] ^ kt; + A[18] = c0; + A[22] = c1; + A[ 1] = c2; + A[ 5] = c3; + A[14] = c4; + bnn = ~A[23]; + kt = A[10] | A[19]; + c0 = A[ 6] ^ kt; + kt = A[19] & A[23]; + c1 = A[10] ^ kt; + kt = bnn & A[ 2]; + c2 = A[19] ^ kt; + kt = A[ 2] | A[ 6]; + c3 = bnn ^ kt; + kt = A[ 6] & A[10]; + c4 = A[ 2] ^ kt; + A[ 6] = c0; + A[10] = c1; + A[19] = c2; + A[23] = c3; + A[ 2] = c4; + bnn = ~A[11]; + kt = A[ 3] & A[ 7]; + c0 = A[24] ^ kt; + kt = A[ 7] | A[11]; + c1 = A[ 3] ^ kt; + kt = bnn | A[15]; + c2 = A[ 7] ^ kt; + kt = A[15] & A[24]; + c3 = bnn ^ kt; + kt = A[24] | A[ 3]; + c4 = A[15] ^ kt; + A[24] = c0; + A[ 3] = c1; + A[ 7] = c2; + A[11] = c3; + A[15] = c4; + bnn = ~A[16]; + kt = bnn & A[20]; + c0 = A[12] ^ kt; + kt = A[20] | A[ 4]; + c1 = bnn ^ kt; + kt = A[ 4] & A[ 8]; + c2 = A[20] ^ kt; + kt = A[ 8] | A[12]; + c3 = A[ 4] ^ kt; + kt = A[12] & A[16]; + c4 = A[ 8] ^ kt; + A[12] = c0; + A[16] = c1; + A[20] = c2; + A[ 4] = c3; + A[ 8] = c4; + A[ 0] = A[ 0] ^ RC[j + 1]; + t = A[ 5]; + A[ 5] = A[18]; + A[18] = A[11]; + A[11] = A[10]; + A[10] = A[ 6]; + A[ 6] = A[22]; + A[22] = A[20]; + A[20] = A[12]; + A[12] = A[19]; + A[19] = A[15]; + A[15] = A[24]; + A[24] = A[ 8]; + A[ 8] = t; + t = A[ 1]; + A[ 1] = A[ 9]; + A[ 9] = A[14]; + A[14] = A[ 2]; + A[ 2] = A[13]; + A[13] = A[23]; + A[23] = A[ 4]; + A[ 4] = A[21]; + A[21] = A[16]; + A[16] = A[ 3]; + A[ 3] = A[17]; + A[17] = A[ 7]; + A[ 7] = t; + } +} + +/* see bearssl_kdf.h */ +void +br_shake_init(br_shake_context *sc, int security_level) +{ + sc->rate = 200 - (size_t)(security_level >> 2); + sc->dptr = 0; + memset(sc->A, 0, sizeof sc->A); + sc->A[ 1] = ~(uint64_t)0; + sc->A[ 2] = ~(uint64_t)0; + sc->A[ 8] = ~(uint64_t)0; + sc->A[12] = ~(uint64_t)0; + sc->A[17] = ~(uint64_t)0; + sc->A[20] = ~(uint64_t)0; +} + +/* see bearssl_kdf.h */ +void +br_shake_inject(br_shake_context *sc, const void *data, size_t len) +{ + const unsigned char *buf; + size_t rate, dptr; + + buf = data; + rate = sc->rate; + dptr = sc->dptr; + while (len > 0) { + size_t clen; + + clen = rate - dptr; + if (clen > len) { + clen = len; + } + memcpy(sc->dbuf + dptr, buf, clen); + dptr += clen; + buf += clen; + len -= clen; + if (dptr == rate) { + xor_block(sc->A, sc->dbuf, rate); + process_block(sc->A); + dptr = 0; + } + } + sc->dptr = dptr; +} + +/* see bearssl_kdf.h */ +void +br_shake_flip(br_shake_context *sc) +{ + /* + * We apply padding and pre-XOR the value into the state. We + * set dptr to the end of the buffer, so that first call to + * shake_extract() will process the block. + */ + if ((sc->dptr + 1) == sc->rate) { + sc->dbuf[sc->dptr ++] = 0x9F; + } else { + sc->dbuf[sc->dptr ++] = 0x1F; + memset(sc->dbuf + sc->dptr, 0x00, sc->rate - sc->dptr - 1); + sc->dbuf[sc->rate - 1] = 0x80; + sc->dptr = sc->rate; + } + xor_block(sc->A, sc->dbuf, sc->rate); +} + +/* see bearssl_kdf.h */ +void +br_shake_produce(br_shake_context *sc, void *out, size_t len) +{ + unsigned char *buf; + size_t dptr, rate; + + buf = out; + dptr = sc->dptr; + rate = sc->rate; + while (len > 0) { + size_t clen; + + if (dptr == rate) { + unsigned char *dbuf; + uint64_t *A; + + A = sc->A; + dbuf = sc->dbuf; + process_block(A); + br_enc64le(dbuf + 0, A[ 0]); + br_enc64le(dbuf + 8, ~A[ 1]); + br_enc64le(dbuf + 16, ~A[ 2]); + br_enc64le(dbuf + 24, A[ 3]); + br_enc64le(dbuf + 32, A[ 4]); + br_enc64le(dbuf + 40, A[ 5]); + br_enc64le(dbuf + 48, A[ 6]); + br_enc64le(dbuf + 56, A[ 7]); + br_enc64le(dbuf + 64, ~A[ 8]); + br_enc64le(dbuf + 72, A[ 9]); + br_enc64le(dbuf + 80, A[10]); + br_enc64le(dbuf + 88, A[11]); + br_enc64le(dbuf + 96, ~A[12]); + br_enc64le(dbuf + 104, A[13]); + br_enc64le(dbuf + 112, A[14]); + br_enc64le(dbuf + 120, A[15]); + br_enc64le(dbuf + 128, A[16]); + br_enc64le(dbuf + 136, ~A[17]); + br_enc64le(dbuf + 144, A[18]); + br_enc64le(dbuf + 152, A[19]); + br_enc64le(dbuf + 160, ~A[20]); + br_enc64le(dbuf + 168, A[21]); + br_enc64le(dbuf + 176, A[22]); + br_enc64le(dbuf + 184, A[23]); + br_enc64le(dbuf + 192, A[24]); + dptr = 0; + } + clen = rate - dptr; + if (clen > len) { + clen = len; + } + memcpy(buf, sc->dbuf + dptr, clen); + dptr += clen; + buf += clen; + len -= clen; + } + sc->dptr = dptr; +} diff --git a/BearSSL-OG/libbearssl/src/mac/hmac.c b/BearSSL-OG/libbearssl/src/mac/hmac.c new file mode 100644 index 0000000..5de836d --- /dev/null +++ b/BearSSL-OG/libbearssl/src/mac/hmac.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static __inline size_t +block_size(const br_hash_class *dig) +{ + unsigned ls; + + ls = (unsigned)(dig->desc >> BR_HASHDESC_LBLEN_OFF) + & BR_HASHDESC_LBLEN_MASK; + return (size_t)1 << ls; +} + +static void +process_key(const br_hash_class **hc, void *ks, + const void *key, size_t key_len, unsigned bb) +{ + unsigned char tmp[256]; + size_t blen, u; + + blen = block_size(*hc); + memcpy(tmp, key, key_len); + for (u = 0; u < key_len; u ++) { + tmp[u] ^= (unsigned char)bb; + } + memset(tmp + key_len, bb, blen - key_len); + (*hc)->init(hc); + (*hc)->update(hc, tmp, blen); + (*hc)->state(hc, ks); +} + +/* see bearssl.h */ +void +br_hmac_key_init(br_hmac_key_context *kc, + const br_hash_class *dig, const void *key, size_t key_len) +{ + br_hash_compat_context hc; + unsigned char kbuf[64]; + + kc->dig_vtable = dig; + hc.vtable = dig; + if (key_len > block_size(dig)) { + dig->init(&hc.vtable); + dig->update(&hc.vtable, key, key_len); + dig->out(&hc.vtable, kbuf); + key = kbuf; + key_len = br_digest_size(dig); + } + process_key(&hc.vtable, kc->ksi, key, key_len, 0x36); + process_key(&hc.vtable, kc->kso, key, key_len, 0x5C); +} + +/* see bearssl.h */ +void +br_hmac_init(br_hmac_context *ctx, + const br_hmac_key_context *kc, size_t out_len) +{ + const br_hash_class *dig; + size_t blen, hlen; + + dig = kc->dig_vtable; + blen = block_size(dig); + dig->init(&ctx->dig.vtable); + dig->set_state(&ctx->dig.vtable, kc->ksi, (uint64_t)blen); + memcpy(ctx->kso, kc->kso, sizeof kc->kso); + hlen = br_digest_size(dig); + if (out_len > 0 && out_len < hlen) { + hlen = out_len; + } + ctx->out_len = hlen; +} + +/* see bearssl.h */ +void +br_hmac_update(br_hmac_context *ctx, const void *data, size_t len) +{ + ctx->dig.vtable->update(&ctx->dig.vtable, data, len); +} + +/* see bearssl.h */ +size_t +br_hmac_out(const br_hmac_context *ctx, void *out) +{ + const br_hash_class *dig; + br_hash_compat_context hc; + unsigned char tmp[64]; + size_t blen, hlen; + + dig = ctx->dig.vtable; + dig->out(&ctx->dig.vtable, tmp); + blen = block_size(dig); + dig->init(&hc.vtable); + dig->set_state(&hc.vtable, ctx->kso, (uint64_t)blen); + hlen = br_digest_size(dig); + dig->update(&hc.vtable, tmp, hlen); + dig->out(&hc.vtable, tmp); + memcpy(out, tmp, ctx->out_len); + return ctx->out_len; +} diff --git a/BearSSL-OG/libbearssl/src/mac/hmac_ct.c b/BearSSL-OG/libbearssl/src/mac/hmac_ct.c new file mode 100644 index 0000000..30b3363 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/mac/hmac_ct.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static __inline size_t +hash_size(const br_hash_class *dig) +{ + return (unsigned)(dig->desc >> BR_HASHDESC_OUT_OFF) + & BR_HASHDESC_OUT_MASK; +} + +static __inline size_t +block_size(const br_hash_class *dig) +{ + unsigned ls; + + ls = (unsigned)(dig->desc >> BR_HASHDESC_LBLEN_OFF) + & BR_HASHDESC_LBLEN_MASK; + return (size_t)1 << ls; +} + +/* see bearssl.h */ +size_t +br_hmac_outCT(const br_hmac_context *ctx, + const void *data, size_t len, size_t min_len, size_t max_len, + void *out) +{ + /* + * Method implemented here is inspired from the descriptions on: + * https://www.imperialviolet.org/2013/02/04/luckythirteen.html + * + * Principle: we input bytes one by one. We use a MUX to push + * padding bytes instead of data bytes when appropriate. At each + * block limit, we get the current hash function state: this is + * a potential output, since we handle MD padding ourselves. + * + * be 1 for big-endian, 0 for little-endian + * po minimal MD padding length + * bs block size (always a power of 2) + * hlen hash output size + */ + + const br_hash_class *dig; + br_hash_compat_context hc; + int be; + uint32_t po, bs; + uint32_t kr, km, kl, kz, u; + uint64_t count, ncount, bit_len; + unsigned char tmp1[64], tmp2[64]; + size_t hlen; + + /* + * Copy the current hash context. + */ + hc = ctx->dig; + + /* + * Get function-specific information. + */ + dig = hc.vtable; + be = (dig->desc & BR_HASHDESC_MD_PADDING_BE) != 0; + po = 9; + if (dig->desc & BR_HASHDESC_MD_PADDING_128) { + po += 8; + } + bs = block_size(dig); + hlen = hash_size(dig); + + /* + * Get current input length and compute total bit length. + */ + count = dig->state(&hc.vtable, tmp1); + bit_len = (count + (uint64_t)len) << 3; + + /* + * We can input the blocks that we are sure we will use. + * This offers better performance (no MUX for these blocks) + * and also ensures that the remaining lengths fit on 32 bits. + */ + ncount = (count + (uint64_t)min_len) & ~(uint64_t)(bs - 1); + if (ncount > count) { + size_t zlen; + + zlen = (size_t)(ncount - count); + dig->update(&hc.vtable, data, zlen); + data = (const unsigned char *)data + zlen; + len -= zlen; + max_len -= zlen; + count = ncount; + } + + /* + * At that point: + * -- 'count' contains the number of bytes already processed + * (in total). + * -- We must input 'len' bytes. 'min_len' is unimportant: we + * used it to know how many full blocks we could process + * directly. Now only len and max_len matter. + * + * We compute kr, kl, kz and km. + * kr number of input bytes already in the current block + * km index of the first byte after the end of the last padding + * block, if length is max_len + * kz index of the last byte of the actual last padding block + * kl index of the start of the encoded length + * + * km, kz and kl are counted from the current offset in the + * input data. + */ + kr = (uint32_t)count & (bs - 1); + kz = ((kr + (uint32_t)len + po + bs - 1) & ~(bs - 1)) - 1 - kr; + kl = kz - 7; + km = ((kr + (uint32_t)max_len + po + bs - 1) & ~(bs - 1)) - kr; + + /* + * We must now process km bytes. For index u from 0 to km-1: + * d is from data[] if u < max_len, 0x00 otherwise + * e is an encoded length byte or 0x00, depending on u + * The tests for d and e need not be constant-time, since + * they relate only to u and max_len, not to the actual length. + * + * Actual input length is then: + * d if u < len + * 0x80 if u == len + * 0x00 if u > len and u < kl + * e if u >= kl + * + * Hash state is obtained whenever we reach a full block. This + * is the result we want if and only if u == kz. + */ + memset(tmp2, 0, sizeof tmp2); + for (u = 0; u < km; u ++) { + uint32_t v; + uint32_t d, e, x0, x1; + unsigned char x[1]; + + d = (u < max_len) ? ((const unsigned char *)data)[u] : 0x00; + v = (kr + u) & (bs - 1); + if (v >= (bs - 8)) { + unsigned j; + + j = (v - (bs - 8)) << 3; + if (be) { + e = (uint32_t)(bit_len >> (56 - j)); + } else { + e = (uint32_t)(bit_len >> j); + } + e &= 0xFF; + } else { + e = 0x00; + } + x0 = MUX(EQ(u, (uint32_t)len), 0x80, d); + x1 = MUX(LT(u, kl), 0x00, e); + x[0] = MUX(LE(u, (uint32_t)len), x0, x1); + dig->update(&hc.vtable, x, 1); + if (v == (bs - 1)) { + dig->state(&hc.vtable, tmp1); + CCOPY(EQ(u, kz), tmp2, tmp1, hlen); + } + } + + /* + * Inner hash output is in tmp2[]; we finish processing. + */ + dig->init(&hc.vtable); + dig->set_state(&hc.vtable, ctx->kso, (uint64_t)bs); + dig->update(&hc.vtable, tmp2, hlen); + dig->out(&hc.vtable, tmp2); + memcpy(out, tmp2, ctx->out_len); + return ctx->out_len; +} diff --git a/BearSSL-OG/libbearssl/src/rand/aesctr_drbg.c b/BearSSL-OG/libbearssl/src/rand/aesctr_drbg.c new file mode 100644 index 0000000..8dbd501 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rand/aesctr_drbg.c @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rand.h */ +void +br_aesctr_drbg_init(br_aesctr_drbg_context *ctx, + const br_block_ctr_class *aesctr, + const void *seed, size_t len) +{ + unsigned char tmp[16]; + + ctx->vtable = &br_aesctr_drbg_vtable; + memset(tmp, 0, sizeof tmp); + aesctr->init(&ctx->sk.vtable, tmp, 16); + ctx->cc = 0; + br_aesctr_drbg_update(ctx, seed, len); +} + +/* see bearssl_rand.h */ +void +br_aesctr_drbg_generate(br_aesctr_drbg_context *ctx, void *out, size_t len) +{ + unsigned char *buf; + unsigned char iv[12]; + + buf = out; + memset(iv, 0, sizeof iv); + while (len > 0) { + size_t clen; + + /* + * We generate data by blocks of at most 65280 bytes. This + * allows for unambiguously testing the counter overflow + * condition; also, it should work on 16-bit architectures + * (where 'size_t' is 16 bits only). + */ + clen = len; + if (clen > 65280) { + clen = 65280; + } + + /* + * We make sure that the counter won't exceed the configured + * limit. + */ + if ((uint32_t)(ctx->cc + ((clen + 15) >> 4)) > 32768) { + clen = (32768 - ctx->cc) << 4; + if (clen > len) { + clen = len; + } + } + + /* + * Run CTR. + */ + memset(buf, 0, clen); + ctx->cc = ctx->sk.vtable->run(&ctx->sk.vtable, + iv, ctx->cc, buf, clen); + buf += clen; + len -= clen; + + /* + * Every 32768 blocks, we force a state update. + */ + if (ctx->cc >= 32768) { + br_aesctr_drbg_update(ctx, NULL, 0); + } + } +} + +/* see bearssl_rand.h */ +void +br_aesctr_drbg_update(br_aesctr_drbg_context *ctx, const void *seed, size_t len) +{ + /* + * We use a Hirose construction on AES-256 to make a hash function. + * Function definition: + * - running state consists in two 16-byte blocks G and H + * - initial values of G and H are conventional + * - there is a fixed block-sized constant C + * - for next data block m: + * set AES key to H||m + * G' = E(G) xor G + * H' = E(G xor C) xor G xor C + * G <- G', H <- H' + * - once all blocks have been processed, output is H||G + * + * Constants: + * G_init = B6 B6 ... B6 + * H_init = A5 A5 ... A5 + * C = 01 00 ... 00 + * + * With this hash function h(), we compute the new state as + * follows: + * - produce a state-dependent value s as encryption of an + * all-one block with AES and the current key + * - compute the new key as the first 128 bits of h(s||seed) + * + * Original Hirose article: + * https://www.iacr.org/archive/fse2006/40470213/40470213.pdf + */ + + unsigned char s[16], iv[12]; + unsigned char G[16], H[16]; + int first; + + /* + * Use an all-one IV to get a fresh output block that depends on the + * current seed. + */ + memset(iv, 0xFF, sizeof iv); + memset(s, 0, 16); + ctx->sk.vtable->run(&ctx->sk.vtable, iv, 0xFFFFFFFF, s, 16); + + /* + * Set G[] and H[] to conventional start values. + */ + memset(G, 0xB6, sizeof G); + memset(H, 0x5A, sizeof H); + + /* + * Process the concatenation of the current state and the seed + * with the custom hash function. + */ + first = 1; + for (;;) { + unsigned char tmp[32]; + unsigned char newG[16]; + + /* + * Assemble new key H||m into tmp[]. + */ + memcpy(tmp, H, 16); + if (first) { + memcpy(tmp + 16, s, 16); + first = 0; + } else { + size_t clen; + + if (len == 0) { + break; + } + clen = len < 16 ? len : 16; + memcpy(tmp + 16, seed, clen); + memset(tmp + 16 + clen, 0, 16 - clen); + seed = (const unsigned char *)seed + clen; + len -= clen; + } + ctx->sk.vtable->init(&ctx->sk.vtable, tmp, 32); + + /* + * Compute new G and H values. + */ + memcpy(iv, G, 12); + memcpy(newG, G, 16); + ctx->sk.vtable->run(&ctx->sk.vtable, iv, + br_dec32be(G + 12), newG, 16); + iv[0] ^= 0x01; + memcpy(H, G, 16); + H[0] ^= 0x01; + ctx->sk.vtable->run(&ctx->sk.vtable, iv, + br_dec32be(G + 12), H, 16); + memcpy(G, newG, 16); + } + + /* + * Output hash value is H||G. We truncate it to its first 128 bits, + * i.e. H; that's our new AES key. + */ + ctx->sk.vtable->init(&ctx->sk.vtable, H, 16); + ctx->cc = 0; +} + +/* see bearssl_rand.h */ +const br_prng_class br_aesctr_drbg_vtable = { + sizeof(br_aesctr_drbg_context), + (void (*)(const br_prng_class **, const void *, const void *, size_t)) + &br_aesctr_drbg_init, + (void (*)(const br_prng_class **, void *, size_t)) + &br_aesctr_drbg_generate, + (void (*)(const br_prng_class **, const void *, size_t)) + &br_aesctr_drbg_update +}; diff --git a/BearSSL-OG/libbearssl/src/rand/hmac_drbg.c b/BearSSL-OG/libbearssl/src/rand/hmac_drbg.c new file mode 100644 index 0000000..d746756 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rand/hmac_drbg.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl.h */ +void +br_hmac_drbg_init(br_hmac_drbg_context *ctx, + const br_hash_class *digest_class, const void *seed, size_t len) +{ + size_t hlen; + + ctx->vtable = &br_hmac_drbg_vtable; + hlen = br_digest_size(digest_class); + memset(ctx->K, 0x00, hlen); + memset(ctx->V, 0x01, hlen); + ctx->digest_class = digest_class; + br_hmac_drbg_update(ctx, seed, len); +} + +/* see bearssl.h */ +void +br_hmac_drbg_generate(br_hmac_drbg_context *ctx, void *out, size_t len) +{ + const br_hash_class *dig; + br_hmac_key_context kc; + br_hmac_context hc; + size_t hlen; + unsigned char *buf; + unsigned char x; + + dig = ctx->digest_class; + hlen = br_digest_size(dig); + br_hmac_key_init(&kc, dig, ctx->K, hlen); + buf = out; + while (len > 0) { + size_t clen; + + br_hmac_init(&hc, &kc, 0); + br_hmac_update(&hc, ctx->V, hlen); + br_hmac_out(&hc, ctx->V); + clen = hlen; + if (clen > len) { + clen = len; + } + memcpy(buf, ctx->V, clen); + buf += clen; + len -= clen; + } + + /* + * To prepare the state for the next request, we should call + * br_hmac_drbg_update() with an empty additional seed. However, + * we already have an initialized HMAC context with the right + * initial key, and we don't want to push another one on the + * stack, so we inline that update() call here. + */ + br_hmac_init(&hc, &kc, 0); + br_hmac_update(&hc, ctx->V, hlen); + x = 0x00; + br_hmac_update(&hc, &x, 1); + br_hmac_out(&hc, ctx->K); + br_hmac_key_init(&kc, dig, ctx->K, hlen); + br_hmac_init(&hc, &kc, 0); + br_hmac_update(&hc, ctx->V, hlen); + br_hmac_out(&hc, ctx->V); +} + +/* see bearssl.h */ +void +br_hmac_drbg_update(br_hmac_drbg_context *ctx, const void *seed, size_t len) +{ + const br_hash_class *dig; + br_hmac_key_context kc; + br_hmac_context hc; + size_t hlen; + unsigned char x; + + dig = ctx->digest_class; + hlen = br_digest_size(dig); + + /* + * 1. K = HMAC(K, V || 0x00 || seed) + */ + br_hmac_key_init(&kc, dig, ctx->K, hlen); + br_hmac_init(&hc, &kc, 0); + br_hmac_update(&hc, ctx->V, hlen); + x = 0x00; + br_hmac_update(&hc, &x, 1); + br_hmac_update(&hc, seed, len); + br_hmac_out(&hc, ctx->K); + br_hmac_key_init(&kc, dig, ctx->K, hlen); + + /* + * 2. V = HMAC(K, V) + */ + br_hmac_init(&hc, &kc, 0); + br_hmac_update(&hc, ctx->V, hlen); + br_hmac_out(&hc, ctx->V); + + /* + * 3. If the additional seed is empty, then stop here. + */ + if (len == 0) { + return; + } + + /* + * 4. K = HMAC(K, V || 0x01 || seed) + */ + br_hmac_init(&hc, &kc, 0); + br_hmac_update(&hc, ctx->V, hlen); + x = 0x01; + br_hmac_update(&hc, &x, 1); + br_hmac_update(&hc, seed, len); + br_hmac_out(&hc, ctx->K); + br_hmac_key_init(&kc, dig, ctx->K, hlen); + + /* + * 5. V = HMAC(K, V) + */ + br_hmac_init(&hc, &kc, 0); + br_hmac_update(&hc, ctx->V, hlen); + br_hmac_out(&hc, ctx->V); +} + +/* see bearssl.h */ +const br_prng_class br_hmac_drbg_vtable = { + sizeof(br_hmac_drbg_context), + (void (*)(const br_prng_class **, const void *, const void *, size_t)) + &br_hmac_drbg_init, + (void (*)(const br_prng_class **, void *, size_t)) + &br_hmac_drbg_generate, + (void (*)(const br_prng_class **, const void *, size_t)) + &br_hmac_drbg_update +}; diff --git a/BearSSL-OG/libbearssl/src/rand/sysrng.c b/BearSSL-OG/libbearssl/src/rand/sysrng.c new file mode 100644 index 0000000..b39f25d --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rand/sysrng.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_ENABLE_INTRINSICS 1 +#include "inner.h" + +#if BR_USE_GETENTROPY +#include +#endif + +#if BR_USE_URANDOM +#include +#include +#include +#include +#endif + +#if BR_USE_WIN32_RAND +#include +#include +#pragma comment(lib, "advapi32") +#endif + +#if BR_USE_XBOX_RAND +#include +#endif + +/* + * Seeder that uses the RDRAND opcodes (on x86 CPU). + */ +#if BR_RDRAND +BR_TARGETS_X86_UP +BR_TARGET("rdrnd") +static int +seeder_rdrand(const br_prng_class **ctx) +{ + unsigned char tmp[32]; + size_t u; + + for (u = 0; u < sizeof tmp; u += sizeof(uint32_t)) { + int j; + uint32_t x; + + /* + * We use the 32-bit intrinsic so that code is compatible + * with both 32-bit and 64-bit architectures. + * + * Intel recommends trying at least 10 times in case of + * failure. + * + * AMD bug: there are reports that some AMD processors + * have a bug that makes them fail silently after a + * suspend/resume cycle, in which case RDRAND will report + * a success but always return 0xFFFFFFFF. + * see: https://bugzilla.kernel.org/show_bug.cgi?id=85911 + * + * As a mitigation, if the 32-bit value is 0 or -1, then + * it is considered a failure and tried again. This should + * reliably detect the buggy case, at least. This also + * implies that the selected seed values can never be + * 0x00000000 or 0xFFFFFFFF, which is not a problem since + * we are generating a seed for a PRNG, and we overdo it + * a bit (we generate 32 bytes of randomness, and 256 bits + * of entropy are really overkill). + */ + for (j = 0; j < 10; j ++) { + if (_rdrand32_step(&x) && x != 0 && x != (uint32_t)-1) { + goto next_word; + } + } + return 0; + next_word: + br_enc32le(tmp + u, x); + } + (*ctx)->update(ctx, tmp, sizeof tmp); + return 1; +} +BR_TARGETS_X86_DOWN + +static int +rdrand_supported(void) +{ + /* + * The RDRND support is bit 30 of ECX, as returned by CPUID. + */ + return br_cpuid(0, 0, 0x40000000, 0); +} +#endif + +/* + * Seeder that uses /dev/urandom (on Unix-like systems). + */ +#if BR_USE_URANDOM +static int +seeder_urandom(const br_prng_class **ctx) +{ + int f; + + f = open("/dev/urandom", O_RDONLY); + if (f >= 0) { + unsigned char tmp[32]; + size_t u; + + for (u = 0; u < sizeof tmp;) { + ssize_t len; + + len = read(f, tmp + u, (sizeof tmp) - u); + if (len < 0) { + if (errno == EINTR) { + continue; + } + break; + } + u += (size_t)len; + } + close(f); + if (u == sizeof tmp) { + (*ctx)->update(ctx, tmp, sizeof tmp); + return 1; + } + } + return 0; +} +#endif + +/* + * Seeder that uses getentropy() (backed by getrandom() on some systems, + * e.g. Linux). On failure, it will use the /dev/urandom seeder (if + * enabled). + */ +#if BR_USE_GETENTROPY +static int +seeder_getentropy(const br_prng_class **ctx) +{ + unsigned char tmp[32]; + + if (getentropy(tmp, sizeof tmp) == 0) { + (*ctx)->update(ctx, tmp, sizeof tmp); + return 1; + } +#if BR_USE_URANDOM + return seeder_urandom(ctx); +#else + return 0; +#endif +} +#endif + +/* + * Seeder that uses CryptGenRandom() (on Windows). + */ +#if BR_USE_WIN32_RAND +static int +seeder_win32(const br_prng_class **ctx) +{ + HCRYPTPROV hp; + + if (CryptAcquireContext(&hp, 0, 0, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + { + BYTE buf[32]; + BOOL r; + + r = CryptGenRandom(hp, sizeof buf, buf); + CryptReleaseContext(hp, 0); + if (r) { + (*ctx)->update(ctx, buf, sizeof buf); + return 1; + } + } + return 0; +} +#endif + +#if BR_USE_XBOX_RAND +#include /* For XNetRandom() */ + +static int +seeder_xbox(const br_prng_class **ctx) +{ + unsigned char buf[32]; + + /* + * Use Xbox's XNetRandom() for cryptographically secure random data. + * This function provides hardware-backed random bytes suitable for + * TLS key generation and other cryptographic operations. + * + * Note: XNetStartup() must have been called before using this. + */ + XNetRandom(buf, sizeof(buf)); + + (*ctx)->update(ctx, buf, sizeof(buf)); + return 1; +} +#endif + +/* + * An aggregate seeder that uses RDRAND, and falls back to an OS-provided + * source if RDRAND fails. + */ +#if BR_RDRAND && (BR_USE_GETENTROPY || BR_USE_URANDOM || BR_USE_WIN32_RAND || BR_USE_XBOX_RAND) +static int +seeder_rdrand_with_fallback(const br_prng_class **ctx) +{ + if (!seeder_rdrand(ctx)) { +#if BR_USE_GETENTROPY + return seeder_getentropy(ctx); +#elif BR_USE_URANDOM + return seeder_urandom(ctx); +#elif BR_USE_WIN32_RAND + return seeder_win32(ctx); +#elif BR_USE_XBOX_RAND + return seeder_xbox(ctx); +#else +#error "macro selection has gone wrong" +#endif + } + return 1; +} +#endif + +/* see bearssl_rand.h */ +br_prng_seeder +br_prng_seeder_system(const char **name) +{ +#if BR_RDRAND + if (rdrand_supported()) { + if (name != NULL) { + *name = "rdrand"; + } +#if BR_USE_GETENTROPY || BR_USE_URANDOM || BR_USE_WIN32_RAND || BR_USE_XBOX_RAND + return &seeder_rdrand_with_fallback; +#else + return &seeder_rdrand; +#endif + } +#endif +#if BR_USE_GETENTROPY + if (name != NULL) { + *name = "getentropy"; + } + return &seeder_getentropy; +#elif BR_USE_URANDOM + if (name != NULL) { + *name = "urandom"; + } + return &seeder_urandom; +#elif BR_USE_WIN32_RAND + if (name != NULL) { + *name = "win32"; + } + return &seeder_win32; +#elif BR_USE_XBOX_RAND + if (name != NULL) { + *name = "xbox"; + } + return &seeder_xbox; +#else + if (name != NULL) { + *name = "none"; + } + return 0; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_default_keygen.c b/BearSSL-OG/libbearssl/src/rsa/rsa_default_keygen.c new file mode 100644 index 0000000..f2e83c8 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_default_keygen.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +br_rsa_keygen +br_rsa_keygen_get_default(void) +{ +#if BR_INT128 || BR_UMUL128 + return &br_rsa_i62_keygen; +#elif BR_LOMUL + return &br_rsa_i15_keygen; +#else + return &br_rsa_i31_keygen; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_default_modulus.c b/BearSSL-OG/libbearssl/src/rsa/rsa_default_modulus.c new file mode 100644 index 0000000..57d4be5 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_default_modulus.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +br_rsa_compute_modulus +br_rsa_compute_modulus_get_default(void) +{ +#if BR_LOMUL + return &br_rsa_i15_compute_modulus; +#else + return &br_rsa_i31_compute_modulus; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_default_oaep_decrypt.c b/BearSSL-OG/libbearssl/src/rsa/rsa_default_oaep_decrypt.c new file mode 100644 index 0000000..7345d64 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_default_oaep_decrypt.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +br_rsa_oaep_decrypt +br_rsa_oaep_decrypt_get_default(void) +{ +#if BR_INT128 || BR_UMUL128 + return &br_rsa_i62_oaep_decrypt; +#elif BR_LOMUL + return &br_rsa_i15_oaep_decrypt; +#else + return &br_rsa_i31_oaep_decrypt; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_default_oaep_encrypt.c b/BearSSL-OG/libbearssl/src/rsa/rsa_default_oaep_encrypt.c new file mode 100644 index 0000000..ae33fcc --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_default_oaep_encrypt.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +br_rsa_oaep_encrypt +br_rsa_oaep_encrypt_get_default(void) +{ +#if BR_INT128 || BR_UMUL128 + return &br_rsa_i62_oaep_encrypt; +#elif BR_LOMUL + return &br_rsa_i15_oaep_encrypt; +#else + return &br_rsa_i31_oaep_encrypt; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_default_pkcs1_sign.c b/BearSSL-OG/libbearssl/src/rsa/rsa_default_pkcs1_sign.c new file mode 100644 index 0000000..e926704 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_default_pkcs1_sign.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +br_rsa_pkcs1_sign +br_rsa_pkcs1_sign_get_default(void) +{ +#if BR_INT128 || BR_UMUL128 + return &br_rsa_i62_pkcs1_sign; +#elif BR_LOMUL + return &br_rsa_i15_pkcs1_sign; +#else + return &br_rsa_i31_pkcs1_sign; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_default_pkcs1_vrfy.c b/BearSSL-OG/libbearssl/src/rsa/rsa_default_pkcs1_vrfy.c new file mode 100644 index 0000000..b3dbeb7 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_default_pkcs1_vrfy.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +br_rsa_pkcs1_vrfy +br_rsa_pkcs1_vrfy_get_default(void) +{ +#if BR_INT128 || BR_UMUL128 + return &br_rsa_i62_pkcs1_vrfy; +#elif BR_LOMUL + return &br_rsa_i15_pkcs1_vrfy; +#else + return &br_rsa_i31_pkcs1_vrfy; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_default_priv.c b/BearSSL-OG/libbearssl/src/rsa/rsa_default_priv.c new file mode 100644 index 0000000..bb0b2c0 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_default_priv.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +br_rsa_private +br_rsa_private_get_default(void) +{ +#if BR_INT128 || BR_UMUL128 + return &br_rsa_i62_private; +#elif BR_LOMUL + return &br_rsa_i15_private; +#else + return &br_rsa_i31_private; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_default_privexp.c b/BearSSL-OG/libbearssl/src/rsa/rsa_default_privexp.c new file mode 100644 index 0000000..cda4555 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_default_privexp.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +br_rsa_compute_privexp +br_rsa_compute_privexp_get_default(void) +{ +#if BR_LOMUL + return &br_rsa_i15_compute_privexp; +#else + return &br_rsa_i31_compute_privexp; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_default_pss_sign.c b/BearSSL-OG/libbearssl/src/rsa/rsa_default_pss_sign.c new file mode 100644 index 0000000..ce4f3e0 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_default_pss_sign.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +br_rsa_pss_sign +br_rsa_pss_sign_get_default(void) +{ +#if BR_INT128 || BR_UMUL128 + return &br_rsa_i62_pss_sign; +#elif BR_LOMUL + return &br_rsa_i15_pss_sign; +#else + return &br_rsa_i31_pss_sign; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_default_pss_vrfy.c b/BearSSL-OG/libbearssl/src/rsa/rsa_default_pss_vrfy.c new file mode 100644 index 0000000..e3a9ad9 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_default_pss_vrfy.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +br_rsa_pss_vrfy +br_rsa_pss_vrfy_get_default(void) +{ +#if BR_INT128 || BR_UMUL128 + return &br_rsa_i62_pss_vrfy; +#elif BR_LOMUL + return &br_rsa_i15_pss_vrfy; +#else + return &br_rsa_i31_pss_vrfy; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_default_pub.c b/BearSSL-OG/libbearssl/src/rsa/rsa_default_pub.c new file mode 100644 index 0000000..a1f03ef --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_default_pub.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +br_rsa_public +br_rsa_public_get_default(void) +{ +#if BR_INT128 || BR_UMUL128 + return &br_rsa_i62_public; +#elif BR_LOMUL + return &br_rsa_i15_public; +#else + return &br_rsa_i31_public; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_default_pubexp.c b/BearSSL-OG/libbearssl/src/rsa/rsa_default_pubexp.c new file mode 100644 index 0000000..47bc000 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_default_pubexp.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +br_rsa_compute_pubexp +br_rsa_compute_pubexp_get_default(void) +{ +#if BR_LOMUL + return &br_rsa_i15_compute_pubexp; +#else + return &br_rsa_i31_compute_pubexp; +#endif +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i15_keygen.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_keygen.c new file mode 100644 index 0000000..e8da419 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_keygen.c @@ -0,0 +1,583 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Make a random integer of the provided size. The size is encoded. + * The header word is untouched. + */ +static void +mkrand(const br_prng_class **rng, uint16_t *x, uint32_t esize) +{ + size_t u, len; + unsigned m; + + len = (esize + 15) >> 4; + (*rng)->generate(rng, x + 1, len * sizeof(uint16_t)); + for (u = 1; u < len; u ++) { + x[u] &= 0x7FFF; + } + m = esize & 15; + if (m == 0) { + x[len] &= 0x7FFF; + } else { + x[len] &= 0x7FFF >> (15 - m); + } +} + +/* + * This is the big-endian unsigned representation of the product of + * all small primes from 13 to 1481. + */ +static const unsigned char SMALL_PRIMES[] = { + 0x2E, 0xAB, 0x92, 0xD1, 0x8B, 0x12, 0x47, 0x31, 0x54, 0x0A, + 0x99, 0x5D, 0x25, 0x5E, 0xE2, 0x14, 0x96, 0x29, 0x1E, 0xB7, + 0x78, 0x70, 0xCC, 0x1F, 0xA5, 0xAB, 0x8D, 0x72, 0x11, 0x37, + 0xFB, 0xD8, 0x1E, 0x3F, 0x5B, 0x34, 0x30, 0x17, 0x8B, 0xE5, + 0x26, 0x28, 0x23, 0xA1, 0x8A, 0xA4, 0x29, 0xEA, 0xFD, 0x9E, + 0x39, 0x60, 0x8A, 0xF3, 0xB5, 0xA6, 0xEB, 0x3F, 0x02, 0xB6, + 0x16, 0xC3, 0x96, 0x9D, 0x38, 0xB0, 0x7D, 0x82, 0x87, 0x0C, + 0xF7, 0xBE, 0x24, 0xE5, 0x5F, 0x41, 0x04, 0x79, 0x76, 0x40, + 0xE7, 0x00, 0x22, 0x7E, 0xB5, 0x85, 0x7F, 0x8D, 0x01, 0x50, + 0xE9, 0xD3, 0x29, 0x42, 0x08, 0xB3, 0x51, 0x40, 0x7B, 0xD7, + 0x8D, 0xCC, 0x10, 0x01, 0x64, 0x59, 0x28, 0xB6, 0x53, 0xF3, + 0x50, 0x4E, 0xB1, 0xF2, 0x58, 0xCD, 0x6E, 0xF5, 0x56, 0x3E, + 0x66, 0x2F, 0xD7, 0x07, 0x7F, 0x52, 0x4C, 0x13, 0x24, 0xDC, + 0x8E, 0x8D, 0xCC, 0xED, 0x77, 0xC4, 0x21, 0xD2, 0xFD, 0x08, + 0xEA, 0xD7, 0xC0, 0x5C, 0x13, 0x82, 0x81, 0x31, 0x2F, 0x2B, + 0x08, 0xE4, 0x80, 0x04, 0x7A, 0x0C, 0x8A, 0x3C, 0xDC, 0x22, + 0xE4, 0x5A, 0x7A, 0xB0, 0x12, 0x5E, 0x4A, 0x76, 0x94, 0x77, + 0xC2, 0x0E, 0x92, 0xBA, 0x8A, 0xA0, 0x1F, 0x14, 0x51, 0x1E, + 0x66, 0x6C, 0x38, 0x03, 0x6C, 0xC7, 0x4A, 0x4B, 0x70, 0x80, + 0xAF, 0xCA, 0x84, 0x51, 0xD8, 0xD2, 0x26, 0x49, 0xF5, 0xA8, + 0x5E, 0x35, 0x4B, 0xAC, 0xCE, 0x29, 0x92, 0x33, 0xB7, 0xA2, + 0x69, 0x7D, 0x0C, 0xE0, 0x9C, 0xDB, 0x04, 0xD6, 0xB4, 0xBC, + 0x39, 0xD7, 0x7F, 0x9E, 0x9D, 0x78, 0x38, 0x7F, 0x51, 0x54, + 0x50, 0x8B, 0x9E, 0x9C, 0x03, 0x6C, 0xF5, 0x9D, 0x2C, 0x74, + 0x57, 0xF0, 0x27, 0x2A, 0xC3, 0x47, 0xCA, 0xB9, 0xD7, 0x5C, + 0xFF, 0xC2, 0xAC, 0x65, 0x4E, 0xBD +}; + +/* + * We need temporary values for at least 7 integers of the same size + * as a factor (including header word); more space helps with performance + * (in modular exponentiations), but we much prefer to remain under + * 2 kilobytes in total, to save stack space. The macro TEMPS below + * exceeds 1024 (which is a count in 16-bit words) when BR_MAX_RSA_SIZE + * is greater than 4350 (default value is 4096, so the 2-kB limit is + * maintained unless BR_MAX_RSA_SIZE was modified). + */ +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define TEMPS MAX(1024, 7 * ((((BR_MAX_RSA_SIZE + 1) >> 1) + 29) / 15)) + +/* + * Perform trial division on a candidate prime. This computes + * y = SMALL_PRIMES mod x, then tries to compute y/y mod x. The + * br_i15_moddiv() function will report an error if y is not invertible + * modulo x. Returned value is 1 on success (none of the small primes + * divides x), 0 on error (a non-trivial GCD is obtained). + * + * This function assumes that x is odd. + */ +static uint32_t +trial_divisions(const uint16_t *x, uint16_t *t) +{ + uint16_t *y; + uint16_t x0i; + + y = t; + t += 1 + ((x[0] + 15) >> 4); + x0i = br_i15_ninv15(x[1]); + br_i15_decode_reduce(y, SMALL_PRIMES, sizeof SMALL_PRIMES, x); + return br_i15_moddiv(y, y, x, x0i, t); +} + +/* + * Perform n rounds of Miller-Rabin on the candidate prime x. This + * function assumes that x = 3 mod 4. + * + * Returned value is 1 on success (all rounds completed successfully), + * 0 otherwise. + */ +static uint32_t +miller_rabin(const br_prng_class **rng, const uint16_t *x, int n, + uint16_t *t, size_t tlen) +{ + /* + * Since x = 3 mod 4, the Miller-Rabin test is simple: + * - get a random base a (such that 1 < a < x-1) + * - compute z = a^((x-1)/2) mod x + * - if z != 1 and z != x-1, the number x is composite + * + * We generate bases 'a' randomly with a size which is + * one bit less than x, which ensures that a < x-1. It + * is not useful to verify that a > 1 because the probability + * that we get a value a equal to 0 or 1 is much smaller + * than the probability of our Miller-Rabin tests not to + * detect a composite, which is already quite smaller than the + * probability of the hardware misbehaving and return a + * composite integer because of some glitch (e.g. bad RAM + * or ill-timed cosmic ray). + */ + unsigned char *xm1d2; + size_t xlen, xm1d2_len, xm1d2_len_u16, u; + uint32_t asize; + unsigned cc; + uint16_t x0i; + + /* + * Compute (x-1)/2 (encoded). + */ + xm1d2 = (unsigned char *)t; + xm1d2_len = ((x[0] - (x[0] >> 4)) + 7) >> 3; + br_i15_encode(xm1d2, xm1d2_len, x); + cc = 0; + for (u = 0; u < xm1d2_len; u ++) { + unsigned w; + + w = xm1d2[u]; + xm1d2[u] = (unsigned char)((w >> 1) | cc); + cc = w << 7; + } + + /* + * We used some words of the provided buffer for (x-1)/2. + */ + xm1d2_len_u16 = (xm1d2_len + 1) >> 1; + t += xm1d2_len_u16; + tlen -= xm1d2_len_u16; + + xlen = (x[0] + 15) >> 4; + asize = x[0] - 1 - EQ0(x[0] & 15); + x0i = br_i15_ninv15(x[1]); + while (n -- > 0) { + uint16_t *a; + uint32_t eq1, eqm1; + + /* + * Generate a random base. We don't need the base to be + * really uniform modulo x, so we just get a random + * number which is one bit shorter than x. + */ + a = t; + a[0] = x[0]; + a[xlen] = 0; + mkrand(rng, a, asize); + + /* + * Compute a^((x-1)/2) mod x. We assume here that the + * function will not fail (the temporary array is large + * enough). + */ + br_i15_modpow_opt(a, xm1d2, xm1d2_len, + x, x0i, t + 1 + xlen, tlen - 1 - xlen); + + /* + * We must obtain either 1 or x-1. Note that x is odd, + * hence x-1 differs from x only in its low word (no + * carry). + */ + eq1 = a[1] ^ 1; + eqm1 = a[1] ^ (x[1] - 1); + for (u = 2; u <= xlen; u ++) { + eq1 |= a[u]; + eqm1 |= a[u] ^ x[u]; + } + + if ((EQ0(eq1) | EQ0(eqm1)) == 0) { + return 0; + } + } + return 1; +} + +/* + * Create a random prime of the provided size. 'size' is the _encoded_ + * bit length. The two top bits and the two bottom bits are set to 1. + */ +static void +mkprime(const br_prng_class **rng, uint16_t *x, uint32_t esize, + uint32_t pubexp, uint16_t *t, size_t tlen) +{ + size_t len; + + x[0] = esize; + len = (esize + 15) >> 4; + for (;;) { + size_t u; + uint32_t m3, m5, m7, m11; + int rounds; + + /* + * Generate random bits. We force the two top bits and the + * two bottom bits to 1. + */ + mkrand(rng, x, esize); + if ((esize & 15) == 0) { + x[len] |= 0x6000; + } else if ((esize & 15) == 1) { + x[len] |= 0x0001; + x[len - 1] |= 0x4000; + } else { + x[len] |= 0x0003 << ((esize & 15) - 2); + } + x[1] |= 0x0003; + + /* + * Trial division with low primes (3, 5, 7 and 11). We + * use the following properties: + * + * 2^2 = 1 mod 3 + * 2^4 = 1 mod 5 + * 2^3 = 1 mod 7 + * 2^10 = 1 mod 11 + */ + m3 = 0; + m5 = 0; + m7 = 0; + m11 = 0; + for (u = 0; u < len; u ++) { + uint32_t w; + + w = x[1 + u]; + m3 += w << (u & 1); + m3 = (m3 & 0xFF) + (m3 >> 8); + m5 += w << ((4 - u) & 3); + m5 = (m5 & 0xFF) + (m5 >> 8); + m7 += w; + m7 = (m7 & 0x1FF) + (m7 >> 9); + m11 += w << (5 & -(u & 1)); + m11 = (m11 & 0x3FF) + (m11 >> 10); + } + + /* + * Maximum values of m* at this point: + * m3: 511 + * m5: 2310 + * m7: 510 + * m11: 2047 + * We use the same properties to make further reductions. + */ + + m3 = (m3 & 0x0F) + (m3 >> 4); /* max: 46 */ + m3 = (m3 & 0x0F) + (m3 >> 4); /* max: 16 */ + m3 = ((m3 * 43) >> 5) & 3; + + m5 = (m5 & 0xFF) + (m5 >> 8); /* max: 263 */ + m5 = (m5 & 0x0F) + (m5 >> 4); /* max: 30 */ + m5 = (m5 & 0x0F) + (m5 >> 4); /* max: 15 */ + m5 -= 10 & -GT(m5, 9); + m5 -= 5 & -GT(m5, 4); + + m7 = (m7 & 0x3F) + (m7 >> 6); /* max: 69 */ + m7 = (m7 & 7) + (m7 >> 3); /* max: 14 */ + m7 = ((m7 * 147) >> 7) & 7; + + /* + * 2^5 = 32 = -1 mod 11. + */ + m11 = (m11 & 0x1F) + 66 - (m11 >> 5); /* max: 97 */ + m11 -= 88 & -GT(m11, 87); + m11 -= 44 & -GT(m11, 43); + m11 -= 22 & -GT(m11, 21); + m11 -= 11 & -GT(m11, 10); + + /* + * If any of these modulo is 0, then the candidate is + * not prime. Also, if pubexp is 3, 5, 7 or 11, and the + * corresponding modulus is 1, then the candidate must + * be rejected, because we need e to be invertible + * modulo p-1. We can use simple comparisons here + * because they won't leak information on a candidate + * that we keep, only on one that we reject (and is thus + * not secret). + */ + if (m3 == 0 || m5 == 0 || m7 == 0 || m11 == 0) { + continue; + } + if ((pubexp == 3 && m3 == 1) + || (pubexp == 5 && m5 == 1) + || (pubexp == 7 && m7 == 1) + || (pubexp == 11 && m11 == 1)) + { + continue; + } + + /* + * More trial divisions. + */ + if (!trial_divisions(x, t)) { + continue; + } + + /* + * Miller-Rabin algorithm. Since we selected a random + * integer, not a maliciously crafted integer, we can use + * relatively few rounds to lower the risk of a false + * positive (i.e. declaring prime a non-prime) under + * 2^(-80). It is not useful to lower the probability much + * below that, since that would be substantially below + * the probability of the hardware misbehaving. Sufficient + * numbers of rounds are extracted from the Handbook of + * Applied Cryptography, note 4.49 (page 149). + * + * Since we work on the encoded size (esize), we need to + * compare with encoded thresholds. + */ + if (esize < 320) { + rounds = 12; + } else if (esize < 480) { + rounds = 9; + } else if (esize < 693) { + rounds = 6; + } else if (esize < 906) { + rounds = 4; + } else if (esize < 1386) { + rounds = 3; + } else { + rounds = 2; + } + + if (miller_rabin(rng, x, rounds, t, tlen)) { + return; + } + } +} + +/* + * Let p be a prime (p > 2^33, p = 3 mod 4). Let m = (p-1)/2, provided + * as parameter (with announced bit length equal to that of p). This + * function computes d = 1/e mod p-1 (for an odd integer e). Returned + * value is 1 on success, 0 on error (an error is reported if e is not + * invertible modulo p-1). + * + * The temporary buffer (t) must have room for at least 4 integers of + * the size of p. + */ +static uint32_t +invert_pubexp(uint16_t *d, const uint16_t *m, uint32_t e, uint16_t *t) +{ + uint16_t *f; + uint32_t r; + + f = t; + t += 1 + ((m[0] + 15) >> 4); + + /* + * Compute d = 1/e mod m. Since p = 3 mod 4, m is odd. + */ + br_i15_zero(d, m[0]); + d[1] = 1; + br_i15_zero(f, m[0]); + f[1] = e & 0x7FFF; + f[2] = (e >> 15) & 0x7FFF; + f[3] = e >> 30; + r = br_i15_moddiv(d, f, m, br_i15_ninv15(m[1]), t); + + /* + * We really want d = 1/e mod p-1, with p = 2m. By the CRT, + * the result is either the d we got, or d + m. + * + * Let's write e*d = 1 + k*m, for some integer k. Integers e + * and m are odd. If d is odd, then e*d is odd, which implies + * that k must be even; in that case, e*d = 1 + (k/2)*2m, and + * thus d is already fine. Conversely, if d is even, then k + * is odd, and we must add m to d in order to get the correct + * result. + */ + br_i15_add(d, m, (uint32_t)(1 - (d[1] & 1))); + + return r; +} + +/* + * Swap two buffers in RAM. They must be disjoint. + */ +static void +bufswap(void *b1, void *b2, size_t len) +{ + size_t u; + unsigned char *buf1, *buf2; + + buf1 = b1; + buf2 = b2; + for (u = 0; u < len; u ++) { + unsigned w; + + w = buf1[u]; + buf1[u] = buf2[u]; + buf2[u] = w; + } +} + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i15_keygen(const br_prng_class **rng, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp) +{ + uint32_t esize_p, esize_q; + size_t plen, qlen, tlen; + uint16_t *p, *q, *t; + uint16_t tmp[TEMPS]; + uint32_t r; + + if (size < BR_MIN_RSA_SIZE || size > BR_MAX_RSA_SIZE) { + return 0; + } + if (pubexp == 0) { + pubexp = 3; + } else if (pubexp == 1 || (pubexp & 1) == 0) { + return 0; + } + + esize_p = (size + 1) >> 1; + esize_q = size - esize_p; + sk->n_bitlen = size; + sk->p = kbuf_priv; + sk->plen = (esize_p + 7) >> 3; + sk->q = sk->p + sk->plen; + sk->qlen = (esize_q + 7) >> 3; + sk->dp = sk->q + sk->qlen; + sk->dplen = sk->plen; + sk->dq = sk->dp + sk->dplen; + sk->dqlen = sk->qlen; + sk->iq = sk->dq + sk->dqlen; + sk->iqlen = sk->plen; + + if (pk != NULL) { + pk->n = kbuf_pub; + pk->nlen = (size + 7) >> 3; + pk->e = pk->n + pk->nlen; + pk->elen = 4; + br_enc32be(pk->e, pubexp); + while (*pk->e == 0) { + pk->e ++; + pk->elen --; + } + } + + /* + * We now switch to encoded sizes. + * + * floor((x * 17477) / (2^18)) is equal to floor(x/15) for all + * integers x from 0 to 23833. + */ + esize_p += MUL15(esize_p, 17477) >> 18; + esize_q += MUL15(esize_q, 17477) >> 18; + plen = (esize_p + 15) >> 4; + qlen = (esize_q + 15) >> 4; + p = tmp; + q = p + 1 + plen; + t = q + 1 + qlen; + tlen = ((sizeof tmp) / sizeof(uint16_t)) - (2 + plen + qlen); + + /* + * When looking for primes p and q, we temporarily divide + * candidates by 2, in order to compute the inverse of the + * public exponent. + */ + + for (;;) { + mkprime(rng, p, esize_p, pubexp, t, tlen); + br_i15_rshift(p, 1); + if (invert_pubexp(t, p, pubexp, t + 1 + plen)) { + br_i15_add(p, p, 1); + p[1] |= 1; + br_i15_encode(sk->p, sk->plen, p); + br_i15_encode(sk->dp, sk->dplen, t); + break; + } + } + + for (;;) { + mkprime(rng, q, esize_q, pubexp, t, tlen); + br_i15_rshift(q, 1); + if (invert_pubexp(t, q, pubexp, t + 1 + qlen)) { + br_i15_add(q, q, 1); + q[1] |= 1; + br_i15_encode(sk->q, sk->qlen, q); + br_i15_encode(sk->dq, sk->dqlen, t); + break; + } + } + + /* + * If p and q have the same size, then it is possible that q > p + * (when the target modulus size is odd, we generate p with a + * greater bit length than q). If q > p, we want to swap p and q + * (and also dp and dq) for two reasons: + * - The final step below (inversion of q modulo p) is easier if + * p > q. + * - While BearSSL's RSA code is perfectly happy with RSA keys such + * that p < q, some other implementations have restrictions and + * require p > q. + * + * Note that we can do a simple non-constant-time swap here, + * because the only information we leak here is that we insist on + * returning p and q such that p > q, which is not a secret. + */ + if (esize_p == esize_q && br_i15_sub(p, q, 0) == 1) { + bufswap(p, q, (1 + plen) * sizeof *p); + bufswap(sk->p, sk->q, sk->plen); + bufswap(sk->dp, sk->dq, sk->dplen); + } + + /* + * We have produced p, q, dp and dq. We can now compute iq = 1/d mod p. + * + * We ensured that p >= q, so this is just a matter of updating the + * header word for q (and possibly adding an extra word). + * + * Theoretically, the call below may fail, in case we were + * extraordinarily unlucky, and p = q. Another failure case is if + * Miller-Rabin failed us _twice_, and p and q are non-prime and + * have a factor is common. We report the error mostly because it + * is cheap and we can, but in practice this never happens (or, at + * least, it happens way less often than hardware glitches). + */ + q[0] = p[0]; + if (plen > qlen) { + q[plen] = 0; + t ++; + tlen --; + } + br_i15_zero(t, p[0]); + t[1] = 1; + r = br_i15_moddiv(t, q, p, br_i15_ninv15(p[1]), t + 1 + plen); + br_i15_encode(sk->iq, sk->iqlen, t); + + /* + * Compute the public modulus too, if required. + */ + if (pk != NULL) { + br_i15_zero(t, p[0]); + br_i15_mulacc(t, p, q); + br_i15_encode(pk->n, pk->nlen, t); + } + + return r; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i15_modulus.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_modulus.c new file mode 100644 index 0000000..16458c3 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_modulus.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +size_t +br_rsa_i15_compute_modulus(void *n, const br_rsa_private_key *sk) +{ + uint16_t tmp[4 * (((BR_MAX_RSA_SIZE / 2) + 14) / 15) + 5]; + uint16_t *t, *p, *q; + const unsigned char *pbuf, *qbuf; + size_t nlen, plen, qlen, tlen; + + /* + * Compute actual byte and lengths for p and q. + */ + pbuf = sk->p; + plen = sk->plen; + while (plen > 0 && *pbuf == 0) { + pbuf ++; + plen --; + } + qbuf = sk->q; + qlen = sk->qlen; + while (qlen > 0 && *qbuf == 0) { + qbuf ++; + qlen --; + } + + t = tmp; + tlen = (sizeof tmp) / (sizeof tmp[0]); + + /* + * Decode p. + */ + if ((15 * tlen) < (plen << 3) + 15) { + return 0; + } + br_i15_decode(t, pbuf, plen); + p = t; + plen = (p[0] + 31) >> 4; + t += plen; + tlen -= plen; + + /* + * Decode q. + */ + if ((15 * tlen) < (qlen << 3) + 15) { + return 0; + } + br_i15_decode(t, qbuf, qlen); + q = t; + qlen = (q[0] + 31) >> 4; + t += qlen; + tlen -= qlen; + + /* + * Computation can proceed only if we have enough room for the + * modulus. + */ + if (tlen < (plen + qlen + 1)) { + return 0; + } + + /* + * Private key already contains the modulus bit length, from which + * we can infer the output length. Even if n is NULL, we still had + * to decode p and q to make sure that the product can be computed. + */ + nlen = (sk->n_bitlen + 7) >> 3; + if (n != NULL) { + br_i15_zero(t, p[0]); + br_i15_mulacc(t, p, q); + br_i15_encode(n, nlen, t); + } + return nlen; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i15_oaep_decrypt.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_oaep_decrypt.c new file mode 100644 index 0000000..927eecd --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_oaep_decrypt.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i15_oaep_decrypt(const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len) +{ + uint32_t r; + + if (*len != ((sk->n_bitlen + 7) >> 3)) { + return 0; + } + r = br_rsa_i15_private(data, sk); + r &= br_rsa_oaep_unpad(dig, label, label_len, data, len); + return r; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i15_oaep_encrypt.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_oaep_encrypt.c new file mode 100644 index 0000000..b9a6cfa --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_oaep_encrypt.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +size_t +br_rsa_i15_oaep_encrypt( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len) +{ + size_t dlen; + + dlen = br_rsa_oaep_pad(rnd, dig, label, label_len, + pk, dst, dst_max_len, src, src_len); + if (dlen == 0) { + return 0; + } + return dlen & -(size_t)br_rsa_i15_public(dst, dlen, pk); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pkcs1_sign.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pkcs1_sign.c new file mode 100644 index 0000000..f519423 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pkcs1_sign.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i15_pkcs1_sign(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x) +{ + if (!br_rsa_pkcs1_sig_pad(hash_oid, hash, hash_len, sk->n_bitlen, x)) { + return 0; + } + return br_rsa_i15_private(x, sk); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pkcs1_vrfy.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pkcs1_vrfy.c new file mode 100644 index 0000000..2c35184 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pkcs1_vrfy.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i15_pkcs1_vrfy(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out) +{ + unsigned char sig[BR_MAX_RSA_SIZE >> 3]; + + if (xlen > (sizeof sig)) { + return 0; + } + memcpy(sig, x, xlen); + if (!br_rsa_i15_public(sig, xlen, pk)) { + return 0; + } + return br_rsa_pkcs1_sig_unpad(sig, xlen, hash_oid, hash_len, hash_out); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i15_priv.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_priv.c new file mode 100644 index 0000000..177cc3a --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_priv.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define U (2 + ((BR_MAX_RSA_FACTOR + 14) / 15)) +#define TLEN (8 * U) + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i15_private(unsigned char *x, const br_rsa_private_key *sk) +{ + const unsigned char *p, *q; + size_t plen, qlen; + size_t fwlen; + uint16_t p0i, q0i; + size_t xlen, u; + uint16_t tmp[1 + TLEN]; + long z; + uint16_t *mp, *mq, *s1, *s2, *t1, *t2, *t3; + uint32_t r; + + /* + * Compute the actual lengths of p and q, in bytes. + * These lengths are not considered secret (we cannot really hide + * them anyway in constant-time code). + */ + p = sk->p; + plen = sk->plen; + while (plen > 0 && *p == 0) { + p ++; + plen --; + } + q = sk->q; + qlen = sk->qlen; + while (qlen > 0 && *q == 0) { + q ++; + qlen --; + } + + /* + * Compute the maximum factor length, in words. + */ + z = (long)(plen > qlen ? plen : qlen) << 3; + fwlen = 1; + while (z > 0) { + z -= 15; + fwlen ++; + } + /* + * Round up the word length to an even number. + */ + fwlen += (fwlen & 1); + + /* + * We need to fit at least 6 values in the stack buffer. + */ + if (6 * fwlen > TLEN) { + return 0; + } + + /* + * Compute signature length (in bytes). + */ + xlen = (sk->n_bitlen + 7) >> 3; + + /* + * Ensure 32-bit alignment for value words. + */ + mq = tmp; + if (((uintptr_t)mq & 2) == 0) { + mq ++; + } + + /* + * Decode q. + */ + br_i15_decode(mq, q, qlen); + + /* + * Decode p. + */ + t1 = mq + fwlen; + br_i15_decode(t1, p, plen); + + /* + * Compute the modulus (product of the two factors), to compare + * it with the source value. We use br_i15_mulacc(), since it's + * already used later on. + */ + t2 = mq + 2 * fwlen; + br_i15_zero(t2, mq[0]); + br_i15_mulacc(t2, mq, t1); + + /* + * We encode the modulus into bytes, to perform the comparison + * with bytes. We know that the product length, in bytes, is + * exactly xlen. + * The comparison actually computes the carry when subtracting + * the modulus from the source value; that carry must be 1 for + * a value in the correct range. We keep it in r, which is our + * accumulator for the error code. + */ + t3 = mq + 4 * fwlen; + br_i15_encode(t3, xlen, t2); + u = xlen; + r = 0; + while (u > 0) { + uint32_t wn, wx; + + u --; + wn = ((unsigned char *)t3)[u]; + wx = x[u]; + r = ((wx - (wn + r)) >> 8) & 1; + } + + /* + * Move the decoded p to another temporary buffer. + */ + mp = mq + 2 * fwlen; + memmove(mp, t1, fwlen * sizeof *t1); + + /* + * Compute s2 = x^dq mod q. + */ + q0i = br_i15_ninv15(mq[1]); + s2 = mq + fwlen; + br_i15_decode_reduce(s2, x, xlen, mq); + r &= br_i15_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i, + mq + 3 * fwlen, TLEN - 3 * fwlen); + + /* + * Compute s1 = x^dq mod q. + */ + p0i = br_i15_ninv15(mp[1]); + s1 = mq + 3 * fwlen; + br_i15_decode_reduce(s1, x, xlen, mp); + r &= br_i15_modpow_opt(s1, sk->dp, sk->dplen, mp, p0i, + mq + 4 * fwlen, TLEN - 4 * fwlen); + + /* + * Compute: + * h = (s1 - s2)*(1/q) mod p + * s1 is an integer modulo p, but s2 is modulo q. PKCS#1 is + * unclear about whether p may be lower than q (some existing, + * widely deployed implementations of RSA don't tolerate p < q), + * but we want to support that occurrence, so we need to use the + * reduction function. + * + * Since we use br_i15_decode_reduce() for iq (purportedly, the + * inverse of q modulo p), we also tolerate improperly large + * values for this parameter. + */ + t1 = mq + 4 * fwlen; + t2 = mq + 5 * fwlen; + br_i15_reduce(t2, s2, mp); + br_i15_add(s1, mp, br_i15_sub(s1, t2, 1)); + br_i15_to_monty(s1, mp); + br_i15_decode_reduce(t1, sk->iq, sk->iqlen, mp); + br_i15_montymul(t2, s1, t1, mp, p0i); + + /* + * h is now in t2. We compute the final result: + * s = s2 + q*h + * All these operations are non-modular. + * + * We need mq, s2 and t2. We use the t3 buffer as destination. + * The buffers mp, s1 and t1 are no longer needed, so we can + * reuse them for t3. Moreover, the first step of the computation + * is to copy s2 into t3, after which s2 is not needed. Right + * now, mq is in slot 0, s2 is in slot 1, and t2 in slot 5. + * Therefore, we have ample room for t3 by simply using s2. + */ + t3 = s2; + br_i15_mulacc(t3, mq, t2); + + /* + * Encode the result. Since we already checked the value of xlen, + * we can just use it right away. + */ + br_i15_encode(x, xlen, t3); + + /* + * The only error conditions remaining at that point are invalid + * values for p and q (even integers). + */ + return p0i & q0i & r; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i15_privexp.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_privexp.c new file mode 100644 index 0000000..57d6918 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_privexp.c @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +size_t +br_rsa_i15_compute_privexp(void *d, + const br_rsa_private_key *sk, uint32_t e) +{ + /* + * We want to invert e modulo phi = (p-1)(q-1). This first + * requires computing phi, which is easy since we have the factors + * p and q in the private key structure. + * + * Since p = 3 mod 4 and q = 3 mod 4, phi/4 is an odd integer. + * We could invert e modulo phi/4 then patch the result to + * modulo phi, but this would involve assembling three modulus-wide + * values (phi/4, 1 and e) and calling moddiv, that requires + * three more temporaries, for a total of six big integers, or + * slightly more than 3 kB of stack space for RSA-4096. This + * exceeds our stack requirements. + * + * Instead, we first use one step of the extended GCD: + * + * - We compute phi = k*e + r (Euclidean division of phi by e). + * If public exponent e is correct, then r != 0 (e must be + * invertible modulo phi). We also have k != 0 since we + * enforce non-ridiculously-small factors. + * + * - We find small u, v such that u*e - v*r = 1 (using a + * binary GCD; we can arrange for u < r and v < e, i.e. all + * values fit on 32 bits). + * + * - Solution is: d = u + v*k + * This last computation is exact: since u < r and v < e, + * the above implies d < r + e*((phi-r)/e) = phi + */ + + uint16_t tmp[4 * ((BR_MAX_RSA_FACTOR + 14) / 15) + 12]; + uint16_t *p, *q, *k, *m, *z, *phi; + const unsigned char *pbuf, *qbuf; + size_t plen, qlen, u, len, dlen; + uint32_t r, a, b, u0, v0, u1, v1, he, hr; + int i; + + /* + * Check that e is correct. + */ + if (e < 3 || (e & 1) == 0) { + return 0; + } + + /* + * Check lengths of p and q, and that they are both odd. + */ + pbuf = sk->p; + plen = sk->plen; + while (plen > 0 && *pbuf == 0) { + pbuf ++; + plen --; + } + if (plen < 5 || plen > (BR_MAX_RSA_FACTOR / 8) + || (pbuf[plen - 1] & 1) != 1) + { + return 0; + } + qbuf = sk->q; + qlen = sk->qlen; + while (qlen > 0 && *qbuf == 0) { + qbuf ++; + qlen --; + } + if (qlen < 5 || qlen > (BR_MAX_RSA_FACTOR / 8) + || (qbuf[qlen - 1] & 1) != 1) + { + return 0; + } + + /* + * Output length is that of the modulus. + */ + dlen = (sk->n_bitlen + 7) >> 3; + if (d == NULL) { + return dlen; + } + + p = tmp; + br_i15_decode(p, pbuf, plen); + plen = (p[0] + 15) >> 4; + q = p + 1 + plen; + br_i15_decode(q, qbuf, qlen); + qlen = (q[0] + 15) >> 4; + + /* + * Compute phi = (p-1)*(q-1), then move it over p-1 and q-1 (that + * we do not need anymore). The mulacc function sets the announced + * bit length of t to be the sum of the announced bit lengths of + * p-1 and q-1, which is usually exact but may overshoot by one 1 + * bit in some cases; we readjust it to its true length. + */ + p[1] --; + q[1] --; + phi = q + 1 + qlen; + br_i15_zero(phi, p[0]); + br_i15_mulacc(phi, p, q); + len = (phi[0] + 15) >> 4; + memmove(tmp, phi, (1 + len) * sizeof *phi); + phi = tmp; + phi[0] = br_i15_bit_length(phi + 1, len); + len = (phi[0] + 15) >> 4; + + /* + * Divide phi by public exponent e. The final remainder r must be + * non-zero (otherwise, the key is invalid). The quotient is k, + * which we write over phi, since we don't need phi after that. + */ + r = 0; + for (u = len; u >= 1; u --) { + /* + * Upon entry, r < e, and phi[u] < 2^15; hence, + * hi:lo < e*2^15. Thus, the produced word k[u] + * must be lower than 2^15, and the new remainder r + * is lower than e. + */ + uint32_t hi, lo; + + hi = r >> 17; + lo = (r << 15) + phi[u]; + phi[u] = br_divrem(hi, lo, e, &r); + } + if (r == 0) { + return 0; + } + k = phi; + + /* + * Compute u and v such that u*e - v*r = GCD(e,r). We use + * a binary GCD algorithm, with 6 extra integers a, b, + * u0, u1, v0 and v1. Initial values are: + * a = e u0 = 1 v0 = 0 + * b = r u1 = r v1 = e-1 + * The following invariants are maintained: + * a = u0*e - v0*r + * b = u1*e - v1*r + * 0 < a <= e + * 0 < b <= r + * 0 <= u0 <= r + * 0 <= v0 <= e + * 0 <= u1 <= r + * 0 <= v1 <= e + * + * At each iteration, we reduce either a or b by one bit, and + * adjust u0, u1, v0 and v1 to maintain the invariants: + * - if a is even, then a <- a/2 + * - otherwise, if b is even, then b <- b/2 + * - otherwise, if a > b, then a <- (a-b)/2 + * - otherwise, if b > a, then b <- (b-a)/2 + * Algorithm stops when a = b. At that point, the common value + * is the GCD of e and r; it must be 1 (otherwise, the private + * key or public exponent is not valid). The (u0,v0) or (u1,v1) + * pairs are the solution we are looking for. + * + * Since either a or b is reduced by at least 1 bit at each + * iteration, 62 iterations are enough to reach the end + * condition. + * + * To maintain the invariants, we must compute the same operations + * on the u* and v* values that we do on a and b: + * - When a is divided by 2, u0 and v0 must be divided by 2. + * - When b is divided by 2, u1 and v1 must be divided by 2. + * - When b is subtracted from a, u1 and v1 are subtracted from + * u0 and v0, respectively. + * - When a is subtracted from b, u0 and v0 are subtracted from + * u1 and v1, respectively. + * + * However, we want to keep the u* and v* values in their proper + * ranges. The following remarks apply: + * + * - When a is divided by 2, then a is even. Therefore: + * + * * If r is odd, then u0 and v0 must have the same parity; + * if they are both odd, then adding r to u0 and e to v0 + * makes them both even, and the division by 2 brings them + * back to the proper range. + * + * * If r is even, then u0 must be even; if v0 is odd, then + * adding r to u0 and e to v0 makes them both even, and the + * division by 2 brings them back to the proper range. + * + * Thus, all we need to do is to look at the parity of v0, + * and add (r,e) to (u0,v0) when v0 is odd. In order to avoid + * a 32-bit overflow, we can add ((r+1)/2,(e/2)+1) after the + * division (r+1 does not overflow since r < e; and (e/2)+1 + * is equal to (e+1)/2 since e is odd). + * + * - When we subtract b from a, three cases may occur: + * + * * u1 <= u0 and v1 <= v0: just do the subtractions + * + * * u1 > u0 and v1 > v0: compute: + * (u0, v0) <- (u0 + r - u1, v0 + e - v1) + * + * * u1 <= u0 and v1 > v0: compute: + * (u0, v0) <- (u0 + r - u1, v0 + e - v1) + * + * The fourth case (u1 > u0 and v1 <= v0) is not possible + * because it would contradict "b < a" (which is the reason + * why we subtract b from a). + * + * The tricky case is the third one: from the equations, it + * seems that u0 may go out of range. However, the invariants + * and ranges of other values imply that, in that case, the + * new u0 does not actually exceed the range. + * + * We can thus handle the subtraction by adding (r,e) based + * solely on the comparison between v0 and v1. + */ + a = e; + b = r; + u0 = 1; + v0 = 0; + u1 = r; + v1 = e - 1; + hr = (r + 1) >> 1; + he = (e >> 1) + 1; + for (i = 0; i < 62; i ++) { + uint32_t oa, ob, agtb, bgta; + uint32_t sab, sba, da, db; + uint32_t ctl; + + oa = a & 1; /* 1 if a is odd */ + ob = b & 1; /* 1 if b is odd */ + agtb = GT(a, b); /* 1 if a > b */ + bgta = GT(b, a); /* 1 if b > a */ + + sab = oa & ob & agtb; /* 1 if a <- a-b */ + sba = oa & ob & bgta; /* 1 if b <- b-a */ + + /* a <- a-b, u0 <- u0-u1, v0 <- v0-v1 */ + ctl = GT(v1, v0); + a -= b & -sab; + u0 -= (u1 - (r & -ctl)) & -sab; + v0 -= (v1 - (e & -ctl)) & -sab; + + /* b <- b-a, u1 <- u1-u0 mod r, v1 <- v1-v0 mod e */ + ctl = GT(v0, v1); + b -= a & -sba; + u1 -= (u0 - (r & -ctl)) & -sba; + v1 -= (v0 - (e & -ctl)) & -sba; + + da = NOT(oa) | sab; /* 1 if a <- a/2 */ + db = (oa & NOT(ob)) | sba; /* 1 if b <- b/2 */ + + /* a <- a/2, u0 <- u0/2, v0 <- v0/2 */ + ctl = v0 & 1; + a ^= (a ^ (a >> 1)) & -da; + u0 ^= (u0 ^ ((u0 >> 1) + (hr & -ctl))) & -da; + v0 ^= (v0 ^ ((v0 >> 1) + (he & -ctl))) & -da; + + /* b <- b/2, u1 <- u1/2 mod r, v1 <- v1/2 mod e */ + ctl = v1 & 1; + b ^= (b ^ (b >> 1)) & -db; + u1 ^= (u1 ^ ((u1 >> 1) + (hr & -ctl))) & -db; + v1 ^= (v1 ^ ((v1 >> 1) + (he & -ctl))) & -db; + } + + /* + * Check that the GCD is indeed 1. If not, then the key is invalid + * (and there's no harm in leaking that piece of information). + */ + if (a != 1) { + return 0; + } + + /* + * Now we have u0*e - v0*r = 1. Let's compute the result as: + * d = u0 + v0*k + * We still have k in the tmp[] array, and its announced bit + * length is that of phi. + */ + m = k + 1 + len; + m[0] = (2 << 4) + 2; /* bit length is 32 bits, encoded */ + m[1] = v0 & 0x7FFF; + m[2] = (v0 >> 15) & 0x7FFF; + m[3] = v0 >> 30; + z = m + 4; + br_i15_zero(z, k[0]); + z[1] = u0 & 0x7FFF; + z[2] = (u0 >> 15) & 0x7FFF; + z[3] = u0 >> 30; + br_i15_mulacc(z, k, m); + + /* + * Encode the result. + */ + br_i15_encode(d, dlen, z); + return dlen; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pss_sign.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pss_sign.c new file mode 100644 index 0000000..dd9385b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pss_sign.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i15_pss_sign(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x) +{ + if (!br_rsa_pss_sig_pad(rng, hf_data, hf_mgf1, hash, + salt_len, sk->n_bitlen, x)) + { + return 0; + } + return br_rsa_i15_private(x, sk); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pss_vrfy.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pss_vrfy.c new file mode 100644 index 0000000..7d9f2cb --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pss_vrfy.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i15_pss_vrfy(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk) +{ + unsigned char sig[BR_MAX_RSA_SIZE >> 3]; + + if (xlen > (sizeof sig)) { + return 0; + } + memcpy(sig, x, xlen); + if (!br_rsa_i15_public(sig, xlen, pk)) { + return 0; + } + return br_rsa_pss_sig_unpad(hf_data, hf_mgf1, + hash, salt_len, pk, sig); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pub.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pub.c new file mode 100644 index 0000000..9eab5e8 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pub.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * As a strict minimum, we need four buffers that can hold a + * modular integer. + */ +#define TLEN (4 * (2 + ((BR_MAX_RSA_SIZE + 14) / 15))) + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i15_public(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk) +{ + const unsigned char *n; + size_t nlen; + uint16_t tmp[1 + TLEN]; + uint16_t *m, *a, *t; + size_t fwlen; + long z; + uint16_t m0i; + uint32_t r; + + /* + * Get the actual length of the modulus, and see if it fits within + * our stack buffer. We also check that the length of x[] is valid. + */ + n = pk->n; + nlen = pk->nlen; + while (nlen > 0 && *n == 0) { + n ++; + nlen --; + } + if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) { + return 0; + } + z = (long)nlen << 3; + fwlen = 1; + while (z > 0) { + z -= 15; + fwlen ++; + } + /* + * Round up length to an even number. + */ + fwlen += (fwlen & 1); + + /* + * The modulus gets decoded into m[]. + * The value to exponentiate goes into a[]. + * The temporaries for modular exponentiations are in t[]. + * + * We want the first value word of each integer to be aligned + * on a 32-bit boundary. + */ + m = tmp; + if (((uintptr_t)m & 2) == 0) { + m ++; + } + a = m + fwlen; + t = m + 2 * fwlen; + + /* + * Decode the modulus. + */ + br_i15_decode(m, n, nlen); + m0i = br_i15_ninv15(m[1]); + + /* + * Note: if m[] is even, then m0i == 0. Otherwise, m0i must be + * an odd integer. + */ + r = m0i & 1; + + /* + * Decode x[] into a[]; we also check that its value is proper. + */ + r &= br_i15_decode_mod(a, x, xlen, m); + + /* + * Compute the modular exponentiation. + */ + br_i15_modpow_opt(a, pk->e, pk->elen, m, m0i, t, TLEN - 2 * fwlen); + + /* + * Encode the result. + */ + br_i15_encode(x, xlen, a); + return r; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pubexp.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pubexp.c new file mode 100644 index 0000000..803bff7 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i15_pubexp.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Recompute public exponent, based on factor p and reduced private + * exponent dp. + */ +static uint32_t +get_pubexp(const unsigned char *pbuf, size_t plen, + const unsigned char *dpbuf, size_t dplen) +{ + /* + * dp is the inverse of e modulo p-1. If p = 3 mod 4, then + * p-1 = 2*((p-1)/2). Taken modulo 2, e is odd and has inverse 1; + * thus, dp must be odd. + * + * We compute the inverse of dp modulo (p-1)/2. This requires + * first reducing dp modulo (p-1)/2 (this can be done with a + * conditional subtract, no need to use the generic modular + * reduction function); then, we use moddiv. + */ + + uint16_t tmp[6 * ((BR_MAX_RSA_FACTOR + 29) / 15)]; + uint16_t *p, *dp, *x; + size_t len; + uint32_t e; + + /* + * Compute actual factor length (in bytes) and check that it fits + * under our size constraints. + */ + while (plen > 0 && *pbuf == 0) { + pbuf ++; + plen --; + } + if (plen == 0 || plen < 5 || plen > (BR_MAX_RSA_FACTOR / 8)) { + return 0; + } + + /* + * Compute actual reduced exponent length (in bytes) and check that + * it is not longer than p. + */ + while (dplen > 0 && *dpbuf == 0) { + dpbuf ++; + dplen --; + } + if (dplen > plen || dplen == 0 + || (dplen == plen && dpbuf[0] > pbuf[0])) + { + return 0; + } + + /* + * Verify that p = 3 mod 4 and that dp is odd. + */ + if ((pbuf[plen - 1] & 3) != 3 || (dpbuf[dplen - 1] & 1) != 1) { + return 0; + } + + /* + * Decode p and compute (p-1)/2. + */ + p = tmp; + br_i15_decode(p, pbuf, plen); + len = (p[0] + 31) >> 4; + br_i15_rshift(p, 1); + + /* + * Decode dp and make sure its announced bit length matches that of + * p (we already know that the size of dp, in bits, does not exceed + * the size of p, so we just have to copy the header word). + */ + dp = p + len; + memset(dp, 0, len * sizeof *dp); + br_i15_decode(dp, dpbuf, dplen); + dp[0] = p[0]; + + /* + * Subtract (p-1)/2 from dp if necessary. + */ + br_i15_sub(dp, p, NOT(br_i15_sub(dp, p, 0))); + + /* + * If another subtraction is needed, then this means that the + * value was invalid. We don't care to leak information about + * invalid keys. + */ + if (br_i15_sub(dp, p, 0) == 0) { + return 0; + } + + /* + * Invert dp modulo (p-1)/2. If the inversion fails, then the + * key value was invalid. + */ + x = dp + len; + br_i15_zero(x, p[0]); + x[1] = 1; + if (br_i15_moddiv(x, dp, p, br_i15_ninv15(p[1]), x + len) == 0) { + return 0; + } + + /* + * We now have an inverse. We must set it to zero (error) if its + * length is greater than 32 bits and/or if it is an even integer. + * Take care that the bit_length function returns an encoded + * bit length. + */ + e = (uint32_t)x[1] | ((uint32_t)x[2] << 15) | ((uint32_t)x[3] << 30); + e &= -LT(br_i15_bit_length(x + 1, len - 1), 35); + e &= -(e & 1); + return e; +} + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i15_compute_pubexp(const br_rsa_private_key *sk) +{ + /* + * Get the public exponent from both p and q. This is the right + * exponent if we get twice the same value. + */ + uint32_t ep, eq; + + ep = get_pubexp(sk->p, sk->plen, sk->dp, sk->dplen); + eq = get_pubexp(sk->q, sk->qlen, sk->dq, sk->dqlen); + return ep & -EQ(ep, eq); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_keygen.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_keygen.c new file mode 100644 index 0000000..77708f8 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_keygen.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i31_keygen(const br_prng_class **rng, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp) +{ + return br_rsa_i31_keygen_inner(rng, + sk, kbuf_priv, pk, kbuf_pub, size, pubexp, + &br_i31_modpow_opt); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_keygen_inner.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_keygen_inner.c new file mode 100644 index 0000000..98df445 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_keygen_inner.c @@ -0,0 +1,608 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Make a random integer of the provided size. The size is encoded. + * The header word is untouched. + */ +static void +mkrand(const br_prng_class **rng, uint32_t *x, uint32_t esize) +{ + size_t u, len; + unsigned m; + + len = (esize + 31) >> 5; + (*rng)->generate(rng, x + 1, len * sizeof(uint32_t)); + for (u = 1; u < len; u ++) { + x[u] &= 0x7FFFFFFF; + } + m = esize & 31; + if (m == 0) { + x[len] &= 0x7FFFFFFF; + } else { + x[len] &= 0x7FFFFFFF >> (31 - m); + } +} + +/* + * This is the big-endian unsigned representation of the product of + * all small primes from 13 to 1481. + */ +static const unsigned char SMALL_PRIMES[] = { + 0x2E, 0xAB, 0x92, 0xD1, 0x8B, 0x12, 0x47, 0x31, 0x54, 0x0A, + 0x99, 0x5D, 0x25, 0x5E, 0xE2, 0x14, 0x96, 0x29, 0x1E, 0xB7, + 0x78, 0x70, 0xCC, 0x1F, 0xA5, 0xAB, 0x8D, 0x72, 0x11, 0x37, + 0xFB, 0xD8, 0x1E, 0x3F, 0x5B, 0x34, 0x30, 0x17, 0x8B, 0xE5, + 0x26, 0x28, 0x23, 0xA1, 0x8A, 0xA4, 0x29, 0xEA, 0xFD, 0x9E, + 0x39, 0x60, 0x8A, 0xF3, 0xB5, 0xA6, 0xEB, 0x3F, 0x02, 0xB6, + 0x16, 0xC3, 0x96, 0x9D, 0x38, 0xB0, 0x7D, 0x82, 0x87, 0x0C, + 0xF7, 0xBE, 0x24, 0xE5, 0x5F, 0x41, 0x04, 0x79, 0x76, 0x40, + 0xE7, 0x00, 0x22, 0x7E, 0xB5, 0x85, 0x7F, 0x8D, 0x01, 0x50, + 0xE9, 0xD3, 0x29, 0x42, 0x08, 0xB3, 0x51, 0x40, 0x7B, 0xD7, + 0x8D, 0xCC, 0x10, 0x01, 0x64, 0x59, 0x28, 0xB6, 0x53, 0xF3, + 0x50, 0x4E, 0xB1, 0xF2, 0x58, 0xCD, 0x6E, 0xF5, 0x56, 0x3E, + 0x66, 0x2F, 0xD7, 0x07, 0x7F, 0x52, 0x4C, 0x13, 0x24, 0xDC, + 0x8E, 0x8D, 0xCC, 0xED, 0x77, 0xC4, 0x21, 0xD2, 0xFD, 0x08, + 0xEA, 0xD7, 0xC0, 0x5C, 0x13, 0x82, 0x81, 0x31, 0x2F, 0x2B, + 0x08, 0xE4, 0x80, 0x04, 0x7A, 0x0C, 0x8A, 0x3C, 0xDC, 0x22, + 0xE4, 0x5A, 0x7A, 0xB0, 0x12, 0x5E, 0x4A, 0x76, 0x94, 0x77, + 0xC2, 0x0E, 0x92, 0xBA, 0x8A, 0xA0, 0x1F, 0x14, 0x51, 0x1E, + 0x66, 0x6C, 0x38, 0x03, 0x6C, 0xC7, 0x4A, 0x4B, 0x70, 0x80, + 0xAF, 0xCA, 0x84, 0x51, 0xD8, 0xD2, 0x26, 0x49, 0xF5, 0xA8, + 0x5E, 0x35, 0x4B, 0xAC, 0xCE, 0x29, 0x92, 0x33, 0xB7, 0xA2, + 0x69, 0x7D, 0x0C, 0xE0, 0x9C, 0xDB, 0x04, 0xD6, 0xB4, 0xBC, + 0x39, 0xD7, 0x7F, 0x9E, 0x9D, 0x78, 0x38, 0x7F, 0x51, 0x54, + 0x50, 0x8B, 0x9E, 0x9C, 0x03, 0x6C, 0xF5, 0x9D, 0x2C, 0x74, + 0x57, 0xF0, 0x27, 0x2A, 0xC3, 0x47, 0xCA, 0xB9, 0xD7, 0x5C, + 0xFF, 0xC2, 0xAC, 0x65, 0x4E, 0xBD +}; + +/* + * We need temporary values for at least 7 integers of the same size + * as a factor (including header word); more space helps with performance + * (in modular exponentiations), but we much prefer to remain under + * 2 kilobytes in total, to save stack space. The macro TEMPS below + * exceeds 512 (which is a count in 32-bit words) when BR_MAX_RSA_SIZE + * is greater than 4464 (default value is 4096, so the 2-kB limit is + * maintained unless BR_MAX_RSA_SIZE was modified). + */ +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define ROUND2(x) ((((x) + 1) >> 1) << 1) + +#define TEMPS MAX(512, ROUND2(7 * ((((BR_MAX_RSA_SIZE + 1) >> 1) + 61) / 31))) + +/* + * Perform trial division on a candidate prime. This computes + * y = SMALL_PRIMES mod x, then tries to compute y/y mod x. The + * br_i31_moddiv() function will report an error if y is not invertible + * modulo x. Returned value is 1 on success (none of the small primes + * divides x), 0 on error (a non-trivial GCD is obtained). + * + * This function assumes that x is odd. + */ +static uint32_t +trial_divisions(const uint32_t *x, uint32_t *t) +{ + uint32_t *y; + uint32_t x0i; + + y = t; + t += 1 + ((x[0] + 31) >> 5); + x0i = br_i31_ninv31(x[1]); + br_i31_decode_reduce(y, SMALL_PRIMES, sizeof SMALL_PRIMES, x); + return br_i31_moddiv(y, y, x, x0i, t); +} + +/* + * Perform n rounds of Miller-Rabin on the candidate prime x. This + * function assumes that x = 3 mod 4. + * + * Returned value is 1 on success (all rounds completed successfully), + * 0 otherwise. + */ +static uint32_t +miller_rabin(const br_prng_class **rng, const uint32_t *x, int n, + uint32_t *t, size_t tlen, br_i31_modpow_opt_type mp31) +{ + /* + * Since x = 3 mod 4, the Miller-Rabin test is simple: + * - get a random base a (such that 1 < a < x-1) + * - compute z = a^((x-1)/2) mod x + * - if z != 1 and z != x-1, the number x is composite + * + * We generate bases 'a' randomly with a size which is + * one bit less than x, which ensures that a < x-1. It + * is not useful to verify that a > 1 because the probability + * that we get a value a equal to 0 or 1 is much smaller + * than the probability of our Miller-Rabin tests not to + * detect a composite, which is already quite smaller than the + * probability of the hardware misbehaving and return a + * composite integer because of some glitch (e.g. bad RAM + * or ill-timed cosmic ray). + */ + unsigned char *xm1d2; + size_t xlen, xm1d2_len, xm1d2_len_u32, u; + uint32_t asize; + unsigned cc; + uint32_t x0i; + + /* + * Compute (x-1)/2 (encoded). + */ + xm1d2 = (unsigned char *)t; + xm1d2_len = ((x[0] - (x[0] >> 5)) + 7) >> 3; + br_i31_encode(xm1d2, xm1d2_len, x); + cc = 0; + for (u = 0; u < xm1d2_len; u ++) { + unsigned w; + + w = xm1d2[u]; + xm1d2[u] = (unsigned char)((w >> 1) | cc); + cc = w << 7; + } + + /* + * We used some words of the provided buffer for (x-1)/2. + */ + xm1d2_len_u32 = (xm1d2_len + 3) >> 2; + t += xm1d2_len_u32; + tlen -= xm1d2_len_u32; + + xlen = (x[0] + 31) >> 5; + asize = x[0] - 1 - EQ0(x[0] & 31); + x0i = br_i31_ninv31(x[1]); + while (n -- > 0) { + uint32_t *a, *t2; + uint32_t eq1, eqm1; + size_t t2len; + + /* + * Generate a random base. We don't need the base to be + * really uniform modulo x, so we just get a random + * number which is one bit shorter than x. + */ + a = t; + a[0] = x[0]; + a[xlen] = 0; + mkrand(rng, a, asize); + + /* + * Compute a^((x-1)/2) mod x. We assume here that the + * function will not fail (the temporary array is large + * enough). + */ + t2 = t + 1 + xlen; + t2len = tlen - 1 - xlen; + if ((t2len & 1) != 0) { + /* + * Since the source array is 64-bit aligned and + * has an even number of elements (TEMPS), we + * can use the parity of the remaining length to + * detect and adjust alignment. + */ + t2 ++; + t2len --; + } + mp31(a, xm1d2, xm1d2_len, x, x0i, t2, t2len); + + /* + * We must obtain either 1 or x-1. Note that x is odd, + * hence x-1 differs from x only in its low word (no + * carry). + */ + eq1 = a[1] ^ 1; + eqm1 = a[1] ^ (x[1] - 1); + for (u = 2; u <= xlen; u ++) { + eq1 |= a[u]; + eqm1 |= a[u] ^ x[u]; + } + + if ((EQ0(eq1) | EQ0(eqm1)) == 0) { + return 0; + } + } + return 1; +} + +/* + * Create a random prime of the provided size. 'size' is the _encoded_ + * bit length. The two top bits and the two bottom bits are set to 1. + */ +static void +mkprime(const br_prng_class **rng, uint32_t *x, uint32_t esize, + uint32_t pubexp, uint32_t *t, size_t tlen, br_i31_modpow_opt_type mp31) +{ + size_t len; + + x[0] = esize; + len = (esize + 31) >> 5; + for (;;) { + size_t u; + uint32_t m3, m5, m7, m11; + int rounds, s7, s11; + + /* + * Generate random bits. We force the two top bits and the + * two bottom bits to 1. + */ + mkrand(rng, x, esize); + if ((esize & 31) == 0) { + x[len] |= 0x60000000; + } else if ((esize & 31) == 1) { + x[len] |= 0x00000001; + x[len - 1] |= 0x40000000; + } else { + x[len] |= 0x00000003 << ((esize & 31) - 2); + } + x[1] |= 0x00000003; + + /* + * Trial division with low primes (3, 5, 7 and 11). We + * use the following properties: + * + * 2^2 = 1 mod 3 + * 2^4 = 1 mod 5 + * 2^3 = 1 mod 7 + * 2^10 = 1 mod 11 + */ + m3 = 0; + m5 = 0; + m7 = 0; + m11 = 0; + s7 = 0; + s11 = 0; + for (u = 0; u < len; u ++) { + uint32_t w, w3, w5, w7, w11; + + w = x[1 + u]; + w3 = (w & 0xFFFF) + (w >> 16); /* max: 98302 */ + w5 = (w & 0xFFFF) + (w >> 16); /* max: 98302 */ + w7 = (w & 0x7FFF) + (w >> 15); /* max: 98302 */ + w11 = (w & 0xFFFFF) + (w >> 20); /* max: 1050622 */ + + m3 += w3 << (u & 1); + m3 = (m3 & 0xFF) + (m3 >> 8); /* max: 1025 */ + + m5 += w5 << ((4 - u) & 3); + m5 = (m5 & 0xFFF) + (m5 >> 12); /* max: 4479 */ + + m7 += w7 << s7; + m7 = (m7 & 0x1FF) + (m7 >> 9); /* max: 1280 */ + if (++ s7 == 3) { + s7 = 0; + } + + m11 += w11 << s11; + if (++ s11 == 10) { + s11 = 0; + } + m11 = (m11 & 0x3FF) + (m11 >> 10); /* max: 526847 */ + } + + m3 = (m3 & 0x3F) + (m3 >> 6); /* max: 78 */ + m3 = (m3 & 0x0F) + (m3 >> 4); /* max: 18 */ + m3 = ((m3 * 43) >> 5) & 3; + + m5 = (m5 & 0xFF) + (m5 >> 8); /* max: 271 */ + m5 = (m5 & 0x0F) + (m5 >> 4); /* max: 31 */ + m5 -= 20 & -GT(m5, 19); + m5 -= 10 & -GT(m5, 9); + m5 -= 5 & -GT(m5, 4); + + m7 = (m7 & 0x3F) + (m7 >> 6); /* max: 82 */ + m7 = (m7 & 0x07) + (m7 >> 3); /* max: 16 */ + m7 = ((m7 * 147) >> 7) & 7; + + /* + * 2^5 = 32 = -1 mod 11. + */ + m11 = (m11 & 0x3FF) + (m11 >> 10); /* max: 1536 */ + m11 = (m11 & 0x3FF) + (m11 >> 10); /* max: 1023 */ + m11 = (m11 & 0x1F) + 33 - (m11 >> 5); /* max: 64 */ + m11 -= 44 & -GT(m11, 43); + m11 -= 22 & -GT(m11, 21); + m11 -= 11 & -GT(m11, 10); + + /* + * If any of these modulo is 0, then the candidate is + * not prime. Also, if pubexp is 3, 5, 7 or 11, and the + * corresponding modulus is 1, then the candidate must + * be rejected, because we need e to be invertible + * modulo p-1. We can use simple comparisons here + * because they won't leak information on a candidate + * that we keep, only on one that we reject (and is thus + * not secret). + */ + if (m3 == 0 || m5 == 0 || m7 == 0 || m11 == 0) { + continue; + } + if ((pubexp == 3 && m3 == 1) + || (pubexp == 5 && m5 == 1) + || (pubexp == 7 && m7 == 1) + || (pubexp == 11 && m11 == 1)) + { + continue; + } + + /* + * More trial divisions. + */ + if (!trial_divisions(x, t)) { + continue; + } + + /* + * Miller-Rabin algorithm. Since we selected a random + * integer, not a maliciously crafted integer, we can use + * relatively few rounds to lower the risk of a false + * positive (i.e. declaring prime a non-prime) under + * 2^(-80). It is not useful to lower the probability much + * below that, since that would be substantially below + * the probability of the hardware misbehaving. Sufficient + * numbers of rounds are extracted from the Handbook of + * Applied Cryptography, note 4.49 (page 149). + * + * Since we work on the encoded size (esize), we need to + * compare with encoded thresholds. + */ + if (esize < 309) { + rounds = 12; + } else if (esize < 464) { + rounds = 9; + } else if (esize < 670) { + rounds = 6; + } else if (esize < 877) { + rounds = 4; + } else if (esize < 1341) { + rounds = 3; + } else { + rounds = 2; + } + + if (miller_rabin(rng, x, rounds, t, tlen, mp31)) { + return; + } + } +} + +/* + * Let p be a prime (p > 2^33, p = 3 mod 4). Let m = (p-1)/2, provided + * as parameter (with announced bit length equal to that of p). This + * function computes d = 1/e mod p-1 (for an odd integer e). Returned + * value is 1 on success, 0 on error (an error is reported if e is not + * invertible modulo p-1). + * + * The temporary buffer (t) must have room for at least 4 integers of + * the size of p. + */ +static uint32_t +invert_pubexp(uint32_t *d, const uint32_t *m, uint32_t e, uint32_t *t) +{ + uint32_t *f; + uint32_t r; + + f = t; + t += 1 + ((m[0] + 31) >> 5); + + /* + * Compute d = 1/e mod m. Since p = 3 mod 4, m is odd. + */ + br_i31_zero(d, m[0]); + d[1] = 1; + br_i31_zero(f, m[0]); + f[1] = e & 0x7FFFFFFF; + f[2] = e >> 31; + r = br_i31_moddiv(d, f, m, br_i31_ninv31(m[1]), t); + + /* + * We really want d = 1/e mod p-1, with p = 2m. By the CRT, + * the result is either the d we got, or d + m. + * + * Let's write e*d = 1 + k*m, for some integer k. Integers e + * and m are odd. If d is odd, then e*d is odd, which implies + * that k must be even; in that case, e*d = 1 + (k/2)*2m, and + * thus d is already fine. Conversely, if d is even, then k + * is odd, and we must add m to d in order to get the correct + * result. + */ + br_i31_add(d, m, (uint32_t)(1 - (d[1] & 1))); + + return r; +} + +/* + * Swap two buffers in RAM. They must be disjoint. + */ +static void +bufswap(void *b1, void *b2, size_t len) +{ + size_t u; + unsigned char *buf1, *buf2; + + buf1 = b1; + buf2 = b2; + for (u = 0; u < len; u ++) { + unsigned w; + + w = buf1[u]; + buf1[u] = buf2[u]; + buf2[u] = w; + } +} + +/* see inner.h */ +uint32_t +br_rsa_i31_keygen_inner(const br_prng_class **rng, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp, br_i31_modpow_opt_type mp31) +{ + uint32_t esize_p, esize_q; + size_t plen, qlen, tlen; + uint32_t *p, *q, *t; + union { + uint32_t t32[TEMPS]; + uint64_t t64[TEMPS >> 1]; /* for 64-bit alignment */ + } tmp; + uint32_t r; + + if (size < BR_MIN_RSA_SIZE || size > BR_MAX_RSA_SIZE) { + return 0; + } + if (pubexp == 0) { + pubexp = 3; + } else if (pubexp == 1 || (pubexp & 1) == 0) { + return 0; + } + + esize_p = (size + 1) >> 1; + esize_q = size - esize_p; + sk->n_bitlen = size; + sk->p = kbuf_priv; + sk->plen = (esize_p + 7) >> 3; + sk->q = sk->p + sk->plen; + sk->qlen = (esize_q + 7) >> 3; + sk->dp = sk->q + sk->qlen; + sk->dplen = sk->plen; + sk->dq = sk->dp + sk->dplen; + sk->dqlen = sk->qlen; + sk->iq = sk->dq + sk->dqlen; + sk->iqlen = sk->plen; + + if (pk != NULL) { + pk->n = kbuf_pub; + pk->nlen = (size + 7) >> 3; + pk->e = pk->n + pk->nlen; + pk->elen = 4; + br_enc32be(pk->e, pubexp); + while (*pk->e == 0) { + pk->e ++; + pk->elen --; + } + } + + /* + * We now switch to encoded sizes. + * + * floor((x * 16913) / (2^19)) is equal to floor(x/31) for all + * integers x from 0 to 34966; the intermediate product fits on + * 30 bits, thus we can use MUL31(). + */ + esize_p += MUL31(esize_p, 16913) >> 19; + esize_q += MUL31(esize_q, 16913) >> 19; + plen = (esize_p + 31) >> 5; + qlen = (esize_q + 31) >> 5; + p = tmp.t32; + q = p + 1 + plen; + t = q + 1 + qlen; + tlen = ((sizeof tmp.t32) / sizeof(uint32_t)) - (2 + plen + qlen); + + /* + * When looking for primes p and q, we temporarily divide + * candidates by 2, in order to compute the inverse of the + * public exponent. + */ + + for (;;) { + mkprime(rng, p, esize_p, pubexp, t, tlen, mp31); + br_i31_rshift(p, 1); + if (invert_pubexp(t, p, pubexp, t + 1 + plen)) { + br_i31_add(p, p, 1); + p[1] |= 1; + br_i31_encode(sk->p, sk->plen, p); + br_i31_encode(sk->dp, sk->dplen, t); + break; + } + } + + for (;;) { + mkprime(rng, q, esize_q, pubexp, t, tlen, mp31); + br_i31_rshift(q, 1); + if (invert_pubexp(t, q, pubexp, t + 1 + qlen)) { + br_i31_add(q, q, 1); + q[1] |= 1; + br_i31_encode(sk->q, sk->qlen, q); + br_i31_encode(sk->dq, sk->dqlen, t); + break; + } + } + + /* + * If p and q have the same size, then it is possible that q > p + * (when the target modulus size is odd, we generate p with a + * greater bit length than q). If q > p, we want to swap p and q + * (and also dp and dq) for two reasons: + * - The final step below (inversion of q modulo p) is easier if + * p > q. + * - While BearSSL's RSA code is perfectly happy with RSA keys such + * that p < q, some other implementations have restrictions and + * require p > q. + * + * Note that we can do a simple non-constant-time swap here, + * because the only information we leak here is that we insist on + * returning p and q such that p > q, which is not a secret. + */ + if (esize_p == esize_q && br_i31_sub(p, q, 0) == 1) { + bufswap(p, q, (1 + plen) * sizeof *p); + bufswap(sk->p, sk->q, sk->plen); + bufswap(sk->dp, sk->dq, sk->dplen); + } + + /* + * We have produced p, q, dp and dq. We can now compute iq = 1/d mod p. + * + * We ensured that p >= q, so this is just a matter of updating the + * header word for q (and possibly adding an extra word). + * + * Theoretically, the call below may fail, in case we were + * extraordinarily unlucky, and p = q. Another failure case is if + * Miller-Rabin failed us _twice_, and p and q are non-prime and + * have a factor is common. We report the error mostly because it + * is cheap and we can, but in practice this never happens (or, at + * least, it happens way less often than hardware glitches). + */ + q[0] = p[0]; + if (plen > qlen) { + q[plen] = 0; + t ++; + tlen --; + } + br_i31_zero(t, p[0]); + t[1] = 1; + r = br_i31_moddiv(t, q, p, br_i31_ninv31(p[1]), t + 1 + plen); + br_i31_encode(sk->iq, sk->iqlen, t); + + /* + * Compute the public modulus too, if required. + */ + if (pk != NULL) { + br_i31_zero(t, p[0]); + br_i31_mulacc(t, p, q); + br_i31_encode(pk->n, pk->nlen, t); + } + + return r; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_modulus.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_modulus.c new file mode 100644 index 0000000..f5f997f --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_modulus.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +size_t +br_rsa_i31_compute_modulus(void *n, const br_rsa_private_key *sk) +{ + uint32_t tmp[4 * (((BR_MAX_RSA_SIZE / 2) + 30) / 31) + 5]; + uint32_t *t, *p, *q; + const unsigned char *pbuf, *qbuf; + size_t nlen, plen, qlen, tlen; + + /* + * Compute actual byte and lengths for p and q. + */ + pbuf = sk->p; + plen = sk->plen; + while (plen > 0 && *pbuf == 0) { + pbuf ++; + plen --; + } + qbuf = sk->q; + qlen = sk->qlen; + while (qlen > 0 && *qbuf == 0) { + qbuf ++; + qlen --; + } + + t = tmp; + tlen = (sizeof tmp) / (sizeof tmp[0]); + + /* + * Decode p. + */ + if ((31 * tlen) < (plen << 3) + 31) { + return 0; + } + br_i31_decode(t, pbuf, plen); + p = t; + plen = (p[0] + 63) >> 5; + t += plen; + tlen -= plen; + + /* + * Decode q. + */ + if ((31 * tlen) < (qlen << 3) + 31) { + return 0; + } + br_i31_decode(t, qbuf, qlen); + q = t; + qlen = (q[0] + 63) >> 5; + t += qlen; + tlen -= qlen; + + /* + * Computation can proceed only if we have enough room for the + * modulus. + */ + if (tlen < (plen + qlen + 1)) { + return 0; + } + + /* + * Private key already contains the modulus bit length, from which + * we can infer the output length. Even if n is NULL, we still had + * to decode p and q to make sure that the product can be computed. + */ + nlen = (sk->n_bitlen + 7) >> 3; + if (n != NULL) { + br_i31_zero(t, p[0]); + br_i31_mulacc(t, p, q); + br_i31_encode(n, nlen, t); + } + return nlen; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_oaep_decrypt.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_oaep_decrypt.c new file mode 100644 index 0000000..06fdd93 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_oaep_decrypt.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i31_oaep_decrypt(const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len) +{ + uint32_t r; + + if (*len != ((sk->n_bitlen + 7) >> 3)) { + return 0; + } + r = br_rsa_i31_private(data, sk); + r &= br_rsa_oaep_unpad(dig, label, label_len, data, len); + return r; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_oaep_encrypt.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_oaep_encrypt.c new file mode 100644 index 0000000..367008c --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_oaep_encrypt.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +size_t +br_rsa_i31_oaep_encrypt( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len) +{ + size_t dlen; + + dlen = br_rsa_oaep_pad(rnd, dig, label, label_len, + pk, dst, dst_max_len, src, src_len); + if (dlen == 0) { + return 0; + } + return dlen & -(size_t)br_rsa_i31_public(dst, dlen, pk); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pkcs1_sign.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pkcs1_sign.c new file mode 100644 index 0000000..784d3c2 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pkcs1_sign.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i31_pkcs1_sign(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x) +{ + if (!br_rsa_pkcs1_sig_pad(hash_oid, hash, hash_len, sk->n_bitlen, x)) { + return 0; + } + return br_rsa_i31_private(x, sk); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pkcs1_vrfy.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pkcs1_vrfy.c new file mode 100644 index 0000000..e79a002 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pkcs1_vrfy.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i31_pkcs1_vrfy(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out) +{ + unsigned char sig[BR_MAX_RSA_SIZE >> 3]; + + if (xlen > (sizeof sig)) { + return 0; + } + memcpy(sig, x, xlen); + if (!br_rsa_i31_public(sig, xlen, pk)) { + return 0; + } + return br_rsa_pkcs1_sig_unpad(sig, xlen, hash_oid, hash_len, hash_out); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_priv.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_priv.c new file mode 100644 index 0000000..b1e1244 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_priv.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define U (2 + ((BR_MAX_RSA_FACTOR + 30) / 31)) +#define TLEN (8 * U) + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i31_private(unsigned char *x, const br_rsa_private_key *sk) +{ + const unsigned char *p, *q; + size_t plen, qlen; + size_t fwlen; + uint32_t p0i, q0i; + size_t xlen, u; + uint32_t tmp[1 + TLEN]; + long z; + uint32_t *mp, *mq, *s1, *s2, *t1, *t2, *t3; + uint32_t r; + + /* + * Compute the actual lengths of p and q, in bytes. + * These lengths are not considered secret (we cannot really hide + * them anyway in constant-time code). + */ + p = sk->p; + plen = sk->plen; + while (plen > 0 && *p == 0) { + p ++; + plen --; + } + q = sk->q; + qlen = sk->qlen; + while (qlen > 0 && *q == 0) { + q ++; + qlen --; + } + + /* + * Compute the maximum factor length, in words. + */ + z = (long)(plen > qlen ? plen : qlen) << 3; + fwlen = 1; + while (z > 0) { + z -= 31; + fwlen ++; + } + + /* + * Round up the word length to an even number. + */ + fwlen += (fwlen & 1); + + /* + * We need to fit at least 6 values in the stack buffer. + */ + if (6 * fwlen > TLEN) { + return 0; + } + + /* + * Compute modulus length (in bytes). + */ + xlen = (sk->n_bitlen + 7) >> 3; + + /* + * Decode q. + */ + mq = tmp; + br_i31_decode(mq, q, qlen); + + /* + * Decode p. + */ + t1 = mq + fwlen; + br_i31_decode(t1, p, plen); + + /* + * Compute the modulus (product of the two factors), to compare + * it with the source value. We use br_i31_mulacc(), since it's + * already used later on. + */ + t2 = mq + 2 * fwlen; + br_i31_zero(t2, mq[0]); + br_i31_mulacc(t2, mq, t1); + + /* + * We encode the modulus into bytes, to perform the comparison + * with bytes. We know that the product length, in bytes, is + * exactly xlen. + * The comparison actually computes the carry when subtracting + * the modulus from the source value; that carry must be 1 for + * a value in the correct range. We keep it in r, which is our + * accumulator for the error code. + */ + t3 = mq + 4 * fwlen; + br_i31_encode(t3, xlen, t2); + u = xlen; + r = 0; + while (u > 0) { + uint32_t wn, wx; + + u --; + wn = ((unsigned char *)t3)[u]; + wx = x[u]; + r = ((wx - (wn + r)) >> 8) & 1; + } + + /* + * Move the decoded p to another temporary buffer. + */ + mp = mq + 2 * fwlen; + memmove(mp, t1, fwlen * sizeof *t1); + + /* + * Compute s2 = x^dq mod q. + */ + q0i = br_i31_ninv31(mq[1]); + s2 = mq + fwlen; + br_i31_decode_reduce(s2, x, xlen, mq); + r &= br_i31_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i, + mq + 3 * fwlen, TLEN - 3 * fwlen); + + /* + * Compute s1 = x^dp mod p. + */ + p0i = br_i31_ninv31(mp[1]); + s1 = mq + 3 * fwlen; + br_i31_decode_reduce(s1, x, xlen, mp); + r &= br_i31_modpow_opt(s1, sk->dp, sk->dplen, mp, p0i, + mq + 4 * fwlen, TLEN - 4 * fwlen); + + /* + * Compute: + * h = (s1 - s2)*(1/q) mod p + * s1 is an integer modulo p, but s2 is modulo q. PKCS#1 is + * unclear about whether p may be lower than q (some existing, + * widely deployed implementations of RSA don't tolerate p < q), + * but we want to support that occurrence, so we need to use the + * reduction function. + * + * Since we use br_i31_decode_reduce() for iq (purportedly, the + * inverse of q modulo p), we also tolerate improperly large + * values for this parameter. + */ + t1 = mq + 4 * fwlen; + t2 = mq + 5 * fwlen; + br_i31_reduce(t2, s2, mp); + br_i31_add(s1, mp, br_i31_sub(s1, t2, 1)); + br_i31_to_monty(s1, mp); + br_i31_decode_reduce(t1, sk->iq, sk->iqlen, mp); + br_i31_montymul(t2, s1, t1, mp, p0i); + + /* + * h is now in t2. We compute the final result: + * s = s2 + q*h + * All these operations are non-modular. + * + * We need mq, s2 and t2. We use the t3 buffer as destination. + * The buffers mp, s1 and t1 are no longer needed, so we can + * reuse them for t3. Moreover, the first step of the computation + * is to copy s2 into t3, after which s2 is not needed. Right + * now, mq is in slot 0, s2 is in slot 1, and t2 is in slot 5. + * Therefore, we have ample room for t3 by simply using s2. + */ + t3 = s2; + br_i31_mulacc(t3, mq, t2); + + /* + * Encode the result. Since we already checked the value of xlen, + * we can just use it right away. + */ + br_i31_encode(x, xlen, t3); + + /* + * The only error conditions remaining at that point are invalid + * values for p and q (even integers). + */ + return p0i & q0i & r; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_privexp.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_privexp.c new file mode 100644 index 0000000..eee62a0 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_privexp.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +size_t +br_rsa_i31_compute_privexp(void *d, + const br_rsa_private_key *sk, uint32_t e) +{ + /* + * We want to invert e modulo phi = (p-1)(q-1). This first + * requires computing phi, which is easy since we have the factors + * p and q in the private key structure. + * + * Since p = 3 mod 4 and q = 3 mod 4, phi/4 is an odd integer. + * We could invert e modulo phi/4 then patch the result to + * modulo phi, but this would involve assembling three modulus-wide + * values (phi/4, 1 and e) and calling moddiv, that requires + * three more temporaries, for a total of six big integers, or + * slightly more than 3 kB of stack space for RSA-4096. This + * exceeds our stack requirements. + * + * Instead, we first use one step of the extended GCD: + * + * - We compute phi = k*e + r (Euclidean division of phi by e). + * If public exponent e is correct, then r != 0 (e must be + * invertible modulo phi). We also have k != 0 since we + * enforce non-ridiculously-small factors. + * + * - We find small u, v such that u*e - v*r = 1 (using a + * binary GCD; we can arrange for u < r and v < e, i.e. all + * values fit on 32 bits). + * + * - Solution is: d = u + v*k + * This last computation is exact: since u < r and v < e, + * the above implies d < r + e*((phi-r)/e) = phi + */ + + uint32_t tmp[4 * ((BR_MAX_RSA_FACTOR + 30) / 31) + 12]; + uint32_t *p, *q, *k, *m, *z, *phi; + const unsigned char *pbuf, *qbuf; + size_t plen, qlen, u, len, dlen; + uint32_t r, a, b, u0, v0, u1, v1, he, hr; + int i; + + /* + * Check that e is correct. + */ + if (e < 3 || (e & 1) == 0) { + return 0; + } + + /* + * Check lengths of p and q, and that they are both odd. + */ + pbuf = sk->p; + plen = sk->plen; + while (plen > 0 && *pbuf == 0) { + pbuf ++; + plen --; + } + if (plen < 5 || plen > (BR_MAX_RSA_FACTOR / 8) + || (pbuf[plen - 1] & 1) != 1) + { + return 0; + } + qbuf = sk->q; + qlen = sk->qlen; + while (qlen > 0 && *qbuf == 0) { + qbuf ++; + qlen --; + } + if (qlen < 5 || qlen > (BR_MAX_RSA_FACTOR / 8) + || (qbuf[qlen - 1] & 1) != 1) + { + return 0; + } + + /* + * Output length is that of the modulus. + */ + dlen = (sk->n_bitlen + 7) >> 3; + if (d == NULL) { + return dlen; + } + + p = tmp; + br_i31_decode(p, pbuf, plen); + plen = (p[0] + 31) >> 5; + q = p + 1 + plen; + br_i31_decode(q, qbuf, qlen); + qlen = (q[0] + 31) >> 5; + + /* + * Compute phi = (p-1)*(q-1), then move it over p-1 and q-1 (that + * we do not need anymore). The mulacc function sets the announced + * bit length of t to be the sum of the announced bit lengths of + * p-1 and q-1, which is usually exact but may overshoot by one 1 + * bit in some cases; we readjust it to its true length. + */ + p[1] --; + q[1] --; + phi = q + 1 + qlen; + br_i31_zero(phi, p[0]); + br_i31_mulacc(phi, p, q); + len = (phi[0] + 31) >> 5; + memmove(tmp, phi, (1 + len) * sizeof *phi); + phi = tmp; + phi[0] = br_i31_bit_length(phi + 1, len); + len = (phi[0] + 31) >> 5; + + /* + * Divide phi by public exponent e. The final remainder r must be + * non-zero (otherwise, the key is invalid). The quotient is k, + * which we write over phi, since we don't need phi after that. + */ + r = 0; + for (u = len; u >= 1; u --) { + /* + * Upon entry, r < e, and phi[u] < 2^31; hence, + * hi:lo < e*2^31. Thus, the produced word k[u] + * must be lower than 2^31, and the new remainder r + * is lower than e. + */ + uint32_t hi, lo; + + hi = r >> 1; + lo = (r << 31) + phi[u]; + phi[u] = br_divrem(hi, lo, e, &r); + } + if (r == 0) { + return 0; + } + k = phi; + + /* + * Compute u and v such that u*e - v*r = GCD(e,r). We use + * a binary GCD algorithm, with 6 extra integers a, b, + * u0, u1, v0 and v1. Initial values are: + * a = e u0 = 1 v0 = 0 + * b = r u1 = r v1 = e-1 + * The following invariants are maintained: + * a = u0*e - v0*r + * b = u1*e - v1*r + * 0 < a <= e + * 0 < b <= r + * 0 <= u0 <= r + * 0 <= v0 <= e + * 0 <= u1 <= r + * 0 <= v1 <= e + * + * At each iteration, we reduce either a or b by one bit, and + * adjust u0, u1, v0 and v1 to maintain the invariants: + * - if a is even, then a <- a/2 + * - otherwise, if b is even, then b <- b/2 + * - otherwise, if a > b, then a <- (a-b)/2 + * - otherwise, if b > a, then b <- (b-a)/2 + * Algorithm stops when a = b. At that point, the common value + * is the GCD of e and r; it must be 1 (otherwise, the private + * key or public exponent is not valid). The (u0,v0) or (u1,v1) + * pairs are the solution we are looking for. + * + * Since either a or b is reduced by at least 1 bit at each + * iteration, 62 iterations are enough to reach the end + * condition. + * + * To maintain the invariants, we must compute the same operations + * on the u* and v* values that we do on a and b: + * - When a is divided by 2, u0 and v0 must be divided by 2. + * - When b is divided by 2, u1 and v1 must be divided by 2. + * - When b is subtracted from a, u1 and v1 are subtracted from + * u0 and v0, respectively. + * - When a is subtracted from b, u0 and v0 are subtracted from + * u1 and v1, respectively. + * + * However, we want to keep the u* and v* values in their proper + * ranges. The following remarks apply: + * + * - When a is divided by 2, then a is even. Therefore: + * + * * If r is odd, then u0 and v0 must have the same parity; + * if they are both odd, then adding r to u0 and e to v0 + * makes them both even, and the division by 2 brings them + * back to the proper range. + * + * * If r is even, then u0 must be even; if v0 is odd, then + * adding r to u0 and e to v0 makes them both even, and the + * division by 2 brings them back to the proper range. + * + * Thus, all we need to do is to look at the parity of v0, + * and add (r,e) to (u0,v0) when v0 is odd. In order to avoid + * a 32-bit overflow, we can add ((r+1)/2,(e/2)+1) after the + * division (r+1 does not overflow since r < e; and (e/2)+1 + * is equal to (e+1)/2 since e is odd). + * + * - When we subtract b from a, three cases may occur: + * + * * u1 <= u0 and v1 <= v0: just do the subtractions + * + * * u1 > u0 and v1 > v0: compute: + * (u0, v0) <- (u0 + r - u1, v0 + e - v1) + * + * * u1 <= u0 and v1 > v0: compute: + * (u0, v0) <- (u0 + r - u1, v0 + e - v1) + * + * The fourth case (u1 > u0 and v1 <= v0) is not possible + * because it would contradict "b < a" (which is the reason + * why we subtract b from a). + * + * The tricky case is the third one: from the equations, it + * seems that u0 may go out of range. However, the invariants + * and ranges of other values imply that, in that case, the + * new u0 does not actually exceed the range. + * + * We can thus handle the subtraction by adding (r,e) based + * solely on the comparison between v0 and v1. + */ + a = e; + b = r; + u0 = 1; + v0 = 0; + u1 = r; + v1 = e - 1; + hr = (r + 1) >> 1; + he = (e >> 1) + 1; + for (i = 0; i < 62; i ++) { + uint32_t oa, ob, agtb, bgta; + uint32_t sab, sba, da, db; + uint32_t ctl; + + oa = a & 1; /* 1 if a is odd */ + ob = b & 1; /* 1 if b is odd */ + agtb = GT(a, b); /* 1 if a > b */ + bgta = GT(b, a); /* 1 if b > a */ + + sab = oa & ob & agtb; /* 1 if a <- a-b */ + sba = oa & ob & bgta; /* 1 if b <- b-a */ + + /* a <- a-b, u0 <- u0-u1, v0 <- v0-v1 */ + ctl = GT(v1, v0); + a -= b & -sab; + u0 -= (u1 - (r & -ctl)) & -sab; + v0 -= (v1 - (e & -ctl)) & -sab; + + /* b <- b-a, u1 <- u1-u0 mod r, v1 <- v1-v0 mod e */ + ctl = GT(v0, v1); + b -= a & -sba; + u1 -= (u0 - (r & -ctl)) & -sba; + v1 -= (v0 - (e & -ctl)) & -sba; + + da = NOT(oa) | sab; /* 1 if a <- a/2 */ + db = (oa & NOT(ob)) | sba; /* 1 if b <- b/2 */ + + /* a <- a/2, u0 <- u0/2, v0 <- v0/2 */ + ctl = v0 & 1; + a ^= (a ^ (a >> 1)) & -da; + u0 ^= (u0 ^ ((u0 >> 1) + (hr & -ctl))) & -da; + v0 ^= (v0 ^ ((v0 >> 1) + (he & -ctl))) & -da; + + /* b <- b/2, u1 <- u1/2 mod r, v1 <- v1/2 mod e */ + ctl = v1 & 1; + b ^= (b ^ (b >> 1)) & -db; + u1 ^= (u1 ^ ((u1 >> 1) + (hr & -ctl))) & -db; + v1 ^= (v1 ^ ((v1 >> 1) + (he & -ctl))) & -db; + } + + /* + * Check that the GCD is indeed 1. If not, then the key is invalid + * (and there's no harm in leaking that piece of information). + */ + if (a != 1) { + return 0; + } + + /* + * Now we have u0*e - v0*r = 1. Let's compute the result as: + * d = u0 + v0*k + * We still have k in the tmp[] array, and its announced bit + * length is that of phi. + */ + m = k + 1 + len; + m[0] = (1 << 5) + 1; /* bit length is 32 bits, encoded */ + m[1] = v0 & 0x7FFFFFFF; + m[2] = v0 >> 31; + z = m + 3; + br_i31_zero(z, k[0]); + z[1] = u0 & 0x7FFFFFFF; + z[2] = u0 >> 31; + br_i31_mulacc(z, k, m); + + /* + * Encode the result. + */ + br_i31_encode(d, dlen, z); + return dlen; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pss_sign.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pss_sign.c new file mode 100644 index 0000000..b06f3e2 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pss_sign.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i31_pss_sign(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x) +{ + if (!br_rsa_pss_sig_pad(rng, hf_data, hf_mgf1, hash, + salt_len, sk->n_bitlen, x)) + { + return 0; + } + return br_rsa_i31_private(x, sk); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pss_vrfy.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pss_vrfy.c new file mode 100644 index 0000000..77a9b28 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pss_vrfy.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i31_pss_vrfy(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk) +{ + unsigned char sig[BR_MAX_RSA_SIZE >> 3]; + + if (xlen > (sizeof sig)) { + return 0; + } + memcpy(sig, x, xlen); + if (!br_rsa_i31_public(sig, xlen, pk)) { + return 0; + } + return br_rsa_pss_sig_unpad(hf_data, hf_mgf1, + hash, salt_len, pk, sig); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pub.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pub.c new file mode 100644 index 0000000..d5f3fe2 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pub.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * As a strict minimum, we need four buffers that can hold a + * modular integer. + */ +#define TLEN (4 * (2 + ((BR_MAX_RSA_SIZE + 30) / 31))) + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i31_public(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk) +{ + const unsigned char *n; + size_t nlen; + uint32_t tmp[1 + TLEN]; + uint32_t *m, *a, *t; + size_t fwlen; + long z; + uint32_t m0i, r; + + /* + * Get the actual length of the modulus, and see if it fits within + * our stack buffer. We also check that the length of x[] is valid. + */ + n = pk->n; + nlen = pk->nlen; + while (nlen > 0 && *n == 0) { + n ++; + nlen --; + } + if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) { + return 0; + } + z = (long)nlen << 3; + fwlen = 1; + while (z > 0) { + z -= 31; + fwlen ++; + } + /* + * Round up length to an even number. + */ + fwlen += (fwlen & 1); + + /* + * The modulus gets decoded into m[]. + * The value to exponentiate goes into a[]. + * The temporaries for modular exponentiation are in t[]. + */ + m = tmp; + a = m + fwlen; + t = m + 2 * fwlen; + + /* + * Decode the modulus. + */ + br_i31_decode(m, n, nlen); + m0i = br_i31_ninv31(m[1]); + + /* + * Note: if m[] is even, then m0i == 0. Otherwise, m0i must be + * an odd integer. + */ + r = m0i & 1; + + /* + * Decode x[] into a[]; we also check that its value is proper. + */ + r &= br_i31_decode_mod(a, x, xlen, m); + + /* + * Compute the modular exponentiation. + */ + br_i31_modpow_opt(a, pk->e, pk->elen, m, m0i, t, TLEN - 2 * fwlen); + + /* + * Encode the result. + */ + br_i31_encode(x, xlen, a); + return r; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pubexp.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pubexp.c new file mode 100644 index 0000000..f26537d --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i31_pubexp.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Recompute public exponent, based on factor p and reduced private + * exponent dp. + */ +static uint32_t +get_pubexp(const unsigned char *pbuf, size_t plen, + const unsigned char *dpbuf, size_t dplen) +{ + /* + * dp is the inverse of e modulo p-1. If p = 3 mod 4, then + * p-1 = 2*((p-1)/2). Taken modulo 2, e is odd and has inverse 1; + * thus, dp must be odd. + * + * We compute the inverse of dp modulo (p-1)/2. This requires + * first reducing dp modulo (p-1)/2 (this can be done with a + * conditional subtract, no need to use the generic modular + * reduction function); then, we use moddiv. + */ + + uint32_t tmp[6 * ((BR_MAX_RSA_FACTOR + 61) / 31)]; + uint32_t *p, *dp, *x; + size_t len; + uint32_t e; + + /* + * Compute actual factor length (in bytes) and check that it fits + * under our size constraints. + */ + while (plen > 0 && *pbuf == 0) { + pbuf ++; + plen --; + } + if (plen == 0 || plen < 5 || plen > (BR_MAX_RSA_FACTOR / 8)) { + return 0; + } + + /* + * Compute actual reduced exponent length (in bytes) and check that + * it is not longer than p. + */ + while (dplen > 0 && *dpbuf == 0) { + dpbuf ++; + dplen --; + } + if (dplen > plen || dplen == 0 + || (dplen == plen && dpbuf[0] > pbuf[0])) + { + return 0; + } + + /* + * Verify that p = 3 mod 4 and that dp is odd. + */ + if ((pbuf[plen - 1] & 3) != 3 || (dpbuf[dplen - 1] & 1) != 1) { + return 0; + } + + /* + * Decode p and compute (p-1)/2. + */ + p = tmp; + br_i31_decode(p, pbuf, plen); + len = (p[0] + 63) >> 5; + br_i31_rshift(p, 1); + + /* + * Decode dp and make sure its announced bit length matches that of + * p (we already know that the size of dp, in bits, does not exceed + * the size of p, so we just have to copy the header word). + */ + dp = p + len; + memset(dp, 0, len * sizeof *dp); + br_i31_decode(dp, dpbuf, dplen); + dp[0] = p[0]; + + /* + * Subtract (p-1)/2 from dp if necessary. + */ + br_i31_sub(dp, p, NOT(br_i31_sub(dp, p, 0))); + + /* + * If another subtraction is needed, then this means that the + * value was invalid. We don't care to leak information about + * invalid keys. + */ + if (br_i31_sub(dp, p, 0) == 0) { + return 0; + } + + /* + * Invert dp modulo (p-1)/2. If the inversion fails, then the + * key value was invalid. + */ + x = dp + len; + br_i31_zero(x, p[0]); + x[1] = 1; + if (br_i31_moddiv(x, dp, p, br_i31_ninv31(p[1]), x + len) == 0) { + return 0; + } + + /* + * We now have an inverse. We must set it to zero (error) if its + * length is greater than 32 bits and/or if it is an even integer. + * Take care that the bit_length function returns an encoded + * bit length. + */ + e = (uint32_t)x[1] | ((uint32_t)x[2] << 31); + e &= -LT(br_i31_bit_length(x + 1, len - 1), 34); + e &= -(e & 1); + return e; +} + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i31_compute_pubexp(const br_rsa_private_key *sk) +{ + /* + * Get the public exponent from both p and q. This is the right + * exponent if we get twice the same value. + */ + uint32_t ep, eq; + + ep = get_pubexp(sk->p, sk->plen, sk->dp, sk->dplen); + eq = get_pubexp(sk->q, sk->qlen, sk->dq, sk->dqlen); + return ep & -EQ(ep, eq); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i32_oaep_decrypt.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_oaep_decrypt.c new file mode 100644 index 0000000..ecfd92b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_oaep_decrypt.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i32_oaep_decrypt(const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len) +{ + uint32_t r; + + if (*len != ((sk->n_bitlen + 7) >> 3)) { + return 0; + } + r = br_rsa_i32_private(data, sk); + r &= br_rsa_oaep_unpad(dig, label, label_len, data, len); + return r; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i32_oaep_encrypt.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_oaep_encrypt.c new file mode 100644 index 0000000..dc17f3f --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_oaep_encrypt.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +size_t +br_rsa_i32_oaep_encrypt( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len) +{ + size_t dlen; + + dlen = br_rsa_oaep_pad(rnd, dig, label, label_len, + pk, dst, dst_max_len, src, src_len); + if (dlen == 0) { + return 0; + } + return dlen & -(size_t)br_rsa_i32_public(dst, dlen, pk); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pkcs1_sign.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pkcs1_sign.c new file mode 100644 index 0000000..44b6e6d --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pkcs1_sign.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i32_pkcs1_sign(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x) +{ + if (!br_rsa_pkcs1_sig_pad(hash_oid, hash, hash_len, sk->n_bitlen, x)) { + return 0; + } + return br_rsa_i32_private(x, sk); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pkcs1_vrfy.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pkcs1_vrfy.c new file mode 100644 index 0000000..6ee7a19 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pkcs1_vrfy.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i32_pkcs1_vrfy(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out) +{ + unsigned char sig[BR_MAX_RSA_SIZE >> 3]; + + if (xlen > (sizeof sig)) { + return 0; + } + memcpy(sig, x, xlen); + if (!br_rsa_i32_public(sig, xlen, pk)) { + return 0; + } + return br_rsa_pkcs1_sig_unpad(sig, xlen, hash_oid, hash_len, hash_out); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i32_priv.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_priv.c new file mode 100644 index 0000000..05c22ec --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_priv.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define U (1 + (BR_MAX_RSA_FACTOR >> 5)) + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i32_private(unsigned char *x, const br_rsa_private_key *sk) +{ + const unsigned char *p, *q; + size_t plen, qlen; + uint32_t tmp[6 * U]; + uint32_t *mp, *mq, *s1, *s2, *t1, *t2, *t3; + uint32_t p0i, q0i; + size_t xlen, u; + uint32_t r; + + /* + * All our temporary buffers are from the tmp[] array. + * + * The mp, mq, s1, s2, t1 and t2 buffers are large enough to + * contain a RSA factor. The t3 buffer can contain a complete + * RSA modulus. t3 shares its storage space with s2, s1 and t1, + * in that order (this is important, see below). + */ + mq = tmp; + mp = tmp + U; + t2 = tmp + 2 * U; + s2 = tmp + 3 * U; + s1 = tmp + 4 * U; + t1 = tmp + 5 * U; + t3 = s2; + + /* + * Compute the actual lengths (in bytes) of p and q, and check + * that they fit within our stack buffers. + */ + p = sk->p; + plen = sk->plen; + while (plen > 0 && *p == 0) { + p ++; + plen --; + } + q = sk->q; + qlen = sk->qlen; + while (qlen > 0 && *q == 0) { + q ++; + qlen --; + } + if (plen > (BR_MAX_RSA_FACTOR >> 3) + || qlen > (BR_MAX_RSA_FACTOR >> 3)) + { + return 0; + } + + /* + * Decode p and q. + */ + br_i32_decode(mp, p, plen); + br_i32_decode(mq, q, qlen); + + /* + * Recompute modulus, to compare with the source value. + */ + br_i32_zero(t2, mp[0]); + br_i32_mulacc(t2, mp, mq); + xlen = (sk->n_bitlen + 7) >> 3; + br_i32_encode(t2 + 2 * U, xlen, t2); + u = xlen; + r = 0; + while (u > 0) { + uint32_t wn, wx; + + u --; + wn = ((unsigned char *)(t2 + 2 * U))[u]; + wx = x[u]; + r = ((wx - (wn + r)) >> 8) & 1; + } + + /* + * Compute s1 = x^dp mod p. + */ + p0i = br_i32_ninv32(mp[1]); + br_i32_decode_reduce(s1, x, xlen, mp); + br_i32_modpow(s1, sk->dp, sk->dplen, mp, p0i, t1, t2); + + /* + * Compute s2 = x^dq mod q. + */ + q0i = br_i32_ninv32(mq[1]); + br_i32_decode_reduce(s2, x, xlen, mq); + br_i32_modpow(s2, sk->dq, sk->dqlen, mq, q0i, t1, t2); + + /* + * Compute: + * h = (s1 - s2)*(1/q) mod p + * s1 is an integer modulo p, but s2 is modulo q. PKCS#1 is + * unclear about whether p may be lower than q (some existing, + * widely deployed implementations of RSA don't tolerate p < q), + * but we want to support that occurrence, so we need to use the + * reduction function. + * + * Since we use br_i32_decode_reduce() for iq (purportedly, the + * inverse of q modulo p), we also tolerate improperly large + * values for this parameter. + */ + br_i32_reduce(t2, s2, mp); + br_i32_add(s1, mp, br_i32_sub(s1, t2, 1)); + br_i32_to_monty(s1, mp); + br_i32_decode_reduce(t1, sk->iq, sk->iqlen, mp); + br_i32_montymul(t2, s1, t1, mp, p0i); + + /* + * h is now in t2. We compute the final result: + * s = s2 + q*h + * All these operations are non-modular. + * + * We need mq, s2 and t2. We use the t3 buffer as destination. + * The buffers mp, s1 and t1 are no longer needed. Moreover, + * the first step is to copy s2 into the destination buffer t3. + * We thus arranged for t3 to actually share space with s2, and + * to be followed by the space formerly used by s1 and t1. + */ + br_i32_mulacc(t3, mq, t2); + + /* + * Encode the result. Since we already checked the value of xlen, + * we can just use it right away. + */ + br_i32_encode(x, xlen, t3); + + /* + * The only error conditions remaining at that point are invalid + * values for p and q (even integers). + */ + return p0i & q0i & r; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pss_sign.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pss_sign.c new file mode 100644 index 0000000..0f72f92 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pss_sign.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i32_pss_sign(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x) +{ + if (!br_rsa_pss_sig_pad(rng, hf_data, hf_mgf1, hash, + salt_len, sk->n_bitlen, x)) + { + return 0; + } + return br_rsa_i32_private(x, sk); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pss_vrfy.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pss_vrfy.c new file mode 100644 index 0000000..2e70d23 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pss_vrfy.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i32_pss_vrfy(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk) +{ + unsigned char sig[BR_MAX_RSA_SIZE >> 3]; + + if (xlen > (sizeof sig)) { + return 0; + } + memcpy(sig, x, xlen); + if (!br_rsa_i32_public(sig, xlen, pk)) { + return 0; + } + return br_rsa_pss_sig_unpad(hf_data, hf_mgf1, + hash, salt_len, pk, sig); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pub.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pub.c new file mode 100644 index 0000000..6e8d8e3 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i32_pub.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i32_public(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk) +{ + const unsigned char *n; + size_t nlen; + uint32_t m[1 + (BR_MAX_RSA_SIZE >> 5)]; + uint32_t a[1 + (BR_MAX_RSA_SIZE >> 5)]; + uint32_t t1[1 + (BR_MAX_RSA_SIZE >> 5)]; + uint32_t t2[1 + (BR_MAX_RSA_SIZE >> 5)]; + uint32_t m0i, r; + + /* + * Get the actual length of the modulus, and see if it fits within + * our stack buffer. We also check that the length of x[] is valid. + */ + n = pk->n; + nlen = pk->nlen; + while (nlen > 0 && *n == 0) { + n ++; + nlen --; + } + if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) { + return 0; + } + br_i32_decode(m, n, nlen); + m0i = br_i32_ninv32(m[1]); + + /* + * Note: if m[] is even, then m0i == 0. Otherwise, m0i must be + * an odd integer. + */ + r = m0i & 1; + + /* + * Decode x[] into a[]; we also check that its value is proper. + */ + r &= br_i32_decode_mod(a, x, xlen, m); + + /* + * Compute the modular exponentiation. + */ + br_i32_modpow(a, pk->e, pk->elen, m, m0i, t1, t2); + + /* + * Encode the result. + */ + br_i32_encode(x, xlen, a); + return r; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i62_keygen.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_keygen.c new file mode 100644 index 0000000..992fe97 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_keygen.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i62_keygen(const br_prng_class **rng, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp) +{ + return br_rsa_i31_keygen_inner(rng, + sk, kbuf_priv, pk, kbuf_pub, size, pubexp, + &br_i62_modpow_opt_as_i31); +} + +/* see bearssl_rsa.h */ +br_rsa_keygen +br_rsa_i62_keygen_get(void) +{ + return &br_rsa_i62_keygen; +} + +#else + +/* see bearssl_rsa.h */ +br_rsa_keygen +br_rsa_i62_keygen_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i62_oaep_decrypt.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_oaep_decrypt.c new file mode 100644 index 0000000..38470dd --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_oaep_decrypt.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i62_oaep_decrypt(const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len) +{ + uint32_t r; + + if (*len != ((sk->n_bitlen + 7) >> 3)) { + return 0; + } + r = br_rsa_i62_private(data, sk); + r &= br_rsa_oaep_unpad(dig, label, label_len, data, len); + return r; +} + +/* see bearssl_rsa.h */ +br_rsa_oaep_decrypt +br_rsa_i62_oaep_decrypt_get(void) +{ + return &br_rsa_i62_oaep_decrypt; +} + +#else + +/* see bearssl_rsa.h */ +br_rsa_oaep_decrypt +br_rsa_i62_oaep_decrypt_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i62_oaep_encrypt.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_oaep_encrypt.c new file mode 100644 index 0000000..cf41ecb --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_oaep_encrypt.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +/* see bearssl_rsa.h */ +size_t +br_rsa_i62_oaep_encrypt( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len) +{ + size_t dlen; + + dlen = br_rsa_oaep_pad(rnd, dig, label, label_len, + pk, dst, dst_max_len, src, src_len); + if (dlen == 0) { + return 0; + } + return dlen & -(size_t)br_rsa_i62_public(dst, dlen, pk); +} + +/* see bearssl_rsa.h */ +br_rsa_oaep_encrypt +br_rsa_i62_oaep_encrypt_get(void) +{ + return &br_rsa_i62_oaep_encrypt; +} + +#else + +/* see bearssl_rsa.h */ +br_rsa_oaep_encrypt +br_rsa_i62_oaep_encrypt_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pkcs1_sign.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pkcs1_sign.c new file mode 100644 index 0000000..a20a084 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pkcs1_sign.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i62_pkcs1_sign(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x) +{ + if (!br_rsa_pkcs1_sig_pad(hash_oid, hash, hash_len, sk->n_bitlen, x)) { + return 0; + } + return br_rsa_i62_private(x, sk); +} + +/* see bearssl_rsa.h */ +br_rsa_pkcs1_sign +br_rsa_i62_pkcs1_sign_get(void) +{ + return &br_rsa_i62_pkcs1_sign; +} + +#else + +/* see bearssl_rsa.h */ +br_rsa_pkcs1_sign +br_rsa_i62_pkcs1_sign_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pkcs1_vrfy.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pkcs1_vrfy.c new file mode 100644 index 0000000..6519161 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pkcs1_vrfy.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i62_pkcs1_vrfy(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out) +{ + unsigned char sig[BR_MAX_RSA_SIZE >> 3]; + + if (xlen > (sizeof sig)) { + return 0; + } + memcpy(sig, x, xlen); + if (!br_rsa_i62_public(sig, xlen, pk)) { + return 0; + } + return br_rsa_pkcs1_sig_unpad(sig, xlen, hash_oid, hash_len, hash_out); +} + +/* see bearssl_rsa.h */ +br_rsa_pkcs1_vrfy +br_rsa_i62_pkcs1_vrfy_get(void) +{ + return &br_rsa_i62_pkcs1_vrfy; +} + +#else + +/* see bearssl_rsa.h */ +br_rsa_pkcs1_vrfy +br_rsa_i62_pkcs1_vrfy_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i62_priv.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_priv.c new file mode 100644 index 0000000..f0da600 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_priv.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +#define U (2 + ((BR_MAX_RSA_FACTOR + 30) / 31)) +#define TLEN (4 * U) /* TLEN is counted in 64-bit words */ + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i62_private(unsigned char *x, const br_rsa_private_key *sk) +{ + const unsigned char *p, *q; + size_t plen, qlen; + size_t fwlen; + uint32_t p0i, q0i; + size_t xlen, u; + uint64_t tmp[TLEN]; + long z; + uint32_t *mp, *mq, *s1, *s2, *t1, *t2, *t3; + uint32_t r; + + /* + * Compute the actual lengths of p and q, in bytes. + * These lengths are not considered secret (we cannot really hide + * them anyway in constant-time code). + */ + p = sk->p; + plen = sk->plen; + while (plen > 0 && *p == 0) { + p ++; + plen --; + } + q = sk->q; + qlen = sk->qlen; + while (qlen > 0 && *q == 0) { + q ++; + qlen --; + } + + /* + * Compute the maximum factor length, in words. + */ + z = (long)(plen > qlen ? plen : qlen) << 3; + fwlen = 1; + while (z > 0) { + z -= 31; + fwlen ++; + } + + /* + * Convert size to 62-bit words. + */ + fwlen = (fwlen + 1) >> 1; + + /* + * We need to fit at least 6 values in the stack buffer. + */ + if (6 * fwlen > TLEN) { + return 0; + } + + /* + * Compute signature length (in bytes). + */ + xlen = (sk->n_bitlen + 7) >> 3; + + /* + * Decode q. + */ + mq = (uint32_t *)tmp; + br_i31_decode(mq, q, qlen); + + /* + * Decode p. + */ + t1 = (uint32_t *)(tmp + fwlen); + br_i31_decode(t1, p, plen); + + /* + * Compute the modulus (product of the two factors), to compare + * it with the source value. We use br_i31_mulacc(), since it's + * already used later on. + */ + t2 = (uint32_t *)(tmp + 2 * fwlen); + br_i31_zero(t2, mq[0]); + br_i31_mulacc(t2, mq, t1); + + /* + * We encode the modulus into bytes, to perform the comparison + * with bytes. We know that the product length, in bytes, is + * exactly xlen. + * The comparison actually computes the carry when subtracting + * the modulus from the source value; that carry must be 1 for + * a value in the correct range. We keep it in r, which is our + * accumulator for the error code. + */ + t3 = (uint32_t *)(tmp + 4 * fwlen); + br_i31_encode(t3, xlen, t2); + u = xlen; + r = 0; + while (u > 0) { + uint32_t wn, wx; + + u --; + wn = ((unsigned char *)t3)[u]; + wx = x[u]; + r = ((wx - (wn + r)) >> 8) & 1; + } + + /* + * Move the decoded p to another temporary buffer. + */ + mp = (uint32_t *)(tmp + 2 * fwlen); + memmove(mp, t1, 2 * fwlen * sizeof *t1); + + /* + * Compute s2 = x^dq mod q. + */ + q0i = br_i31_ninv31(mq[1]); + s2 = (uint32_t *)(tmp + fwlen); + br_i31_decode_reduce(s2, x, xlen, mq); + r &= br_i62_modpow_opt(s2, sk->dq, sk->dqlen, mq, q0i, + tmp + 3 * fwlen, TLEN - 3 * fwlen); + + /* + * Compute s1 = x^dp mod p. + */ + p0i = br_i31_ninv31(mp[1]); + s1 = (uint32_t *)(tmp + 3 * fwlen); + br_i31_decode_reduce(s1, x, xlen, mp); + r &= br_i62_modpow_opt(s1, sk->dp, sk->dplen, mp, p0i, + tmp + 4 * fwlen, TLEN - 4 * fwlen); + + /* + * Compute: + * h = (s1 - s2)*(1/q) mod p + * s1 is an integer modulo p, but s2 is modulo q. PKCS#1 is + * unclear about whether p may be lower than q (some existing, + * widely deployed implementations of RSA don't tolerate p < q), + * but we want to support that occurrence, so we need to use the + * reduction function. + * + * Since we use br_i31_decode_reduce() for iq (purportedly, the + * inverse of q modulo p), we also tolerate improperly large + * values for this parameter. + */ + t1 = (uint32_t *)(tmp + 4 * fwlen); + t2 = (uint32_t *)(tmp + 5 * fwlen); + br_i31_reduce(t2, s2, mp); + br_i31_add(s1, mp, br_i31_sub(s1, t2, 1)); + br_i31_to_monty(s1, mp); + br_i31_decode_reduce(t1, sk->iq, sk->iqlen, mp); + br_i31_montymul(t2, s1, t1, mp, p0i); + + /* + * h is now in t2. We compute the final result: + * s = s2 + q*h + * All these operations are non-modular. + * + * We need mq, s2 and t2. We use the t3 buffer as destination. + * The buffers mp, s1 and t1 are no longer needed, so we can + * reuse them for t3. Moreover, the first step of the computation + * is to copy s2 into t3, after which s2 is not needed. Right + * now, mq is in slot 0, s2 is in slot 1, and t2 is in slot 5. + * Therefore, we have ample room for t3 by simply using s2. + */ + t3 = s2; + br_i31_mulacc(t3, mq, t2); + + /* + * Encode the result. Since we already checked the value of xlen, + * we can just use it right away. + */ + br_i31_encode(x, xlen, t3); + + /* + * The only error conditions remaining at that point are invalid + * values for p and q (even integers). + */ + return p0i & q0i & r; +} + +/* see bearssl_rsa.h */ +br_rsa_private +br_rsa_i62_private_get(void) +{ + return &br_rsa_i62_private; +} + +#else + +/* see bearssl_rsa.h */ +br_rsa_private +br_rsa_i62_private_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pss_sign.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pss_sign.c new file mode 100644 index 0000000..7232f6d --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pss_sign.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i62_pss_sign(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x) +{ + if (!br_rsa_pss_sig_pad(rng, hf_data, hf_mgf1, hash, + salt_len, sk->n_bitlen, x)) + { + return 0; + } + return br_rsa_i62_private(x, sk); +} + +/* see bearssl_rsa.h */ +br_rsa_pss_sign +br_rsa_i62_pss_sign_get(void) +{ + return &br_rsa_i62_pss_sign; +} + +#else + +/* see bearssl_rsa.h */ +br_rsa_pss_sign +br_rsa_i62_pss_sign_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pss_vrfy.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pss_vrfy.c new file mode 100644 index 0000000..e726e82 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pss_vrfy.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i62_pss_vrfy(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk) +{ + unsigned char sig[BR_MAX_RSA_SIZE >> 3]; + + if (xlen > (sizeof sig)) { + return 0; + } + memcpy(sig, x, xlen); + if (!br_rsa_i62_public(sig, xlen, pk)) { + return 0; + } + return br_rsa_pss_sig_unpad(hf_data, hf_mgf1, + hash, salt_len, pk, sig); +} + +/* see bearssl_rsa.h */ +br_rsa_pss_vrfy +br_rsa_i62_pss_vrfy_get(void) +{ + return &br_rsa_i62_pss_vrfy; +} + +#else + +/* see bearssl_rsa.h */ +br_rsa_pss_vrfy +br_rsa_i62_pss_vrfy_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pub.c b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pub.c new file mode 100644 index 0000000..70cf61b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_i62_pub.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +/* + * As a strict minimum, we need four buffers that can hold a + * modular integer. But TLEN is expressed in 64-bit words. + */ +#define TLEN (2 * (2 + ((BR_MAX_RSA_SIZE + 30) / 31))) + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_i62_public(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk) +{ + const unsigned char *n; + size_t nlen; + uint64_t tmp[TLEN]; + uint32_t *m, *a; + size_t fwlen; + long z; + uint32_t m0i, r; + + /* + * Get the actual length of the modulus, and see if it fits within + * our stack buffer. We also check that the length of x[] is valid. + */ + n = pk->n; + nlen = pk->nlen; + while (nlen > 0 && *n == 0) { + n ++; + nlen --; + } + if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) { + return 0; + } + z = (long)nlen << 3; + fwlen = 1; + while (z > 0) { + z -= 31; + fwlen ++; + } + /* + * Convert fwlen to a count in 62-bit words. + */ + fwlen = (fwlen + 1) >> 1; + + /* + * The modulus gets decoded into m[]. + * The value to exponentiate goes into a[]. + */ + m = (uint32_t *)tmp; + a = (uint32_t *)(tmp + fwlen); + + /* + * Decode the modulus. + */ + br_i31_decode(m, n, nlen); + m0i = br_i31_ninv31(m[1]); + + /* + * Note: if m[] is even, then m0i == 0. Otherwise, m0i must be + * an odd integer. + */ + r = m0i & 1; + + /* + * Decode x[] into a[]; we also check that its value is proper. + */ + r &= br_i31_decode_mod(a, x, xlen, m); + + /* + * Compute the modular exponentiation. + */ + br_i62_modpow_opt(a, pk->e, pk->elen, m, m0i, + tmp + 2 * fwlen, TLEN - 2 * fwlen); + + /* + * Encode the result. + */ + br_i31_encode(x, xlen, a); + return r; +} + +/* see bearssl_rsa.h */ +br_rsa_public +br_rsa_i62_public_get(void) +{ + return &br_rsa_i62_public; +} + +#else + +/* see bearssl_rsa.h */ +br_rsa_public +br_rsa_i62_public_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_oaep_pad.c b/BearSSL-OG/libbearssl/src/rsa/rsa_oaep_pad.c new file mode 100644 index 0000000..5327dc2 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_oaep_pad.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Hash some data. This is put as a separate function so that stack + * allocation of the hash function context is done only for the duration + * of the hash. + */ +static void +hash_data(const br_hash_class *dig, void *dst, const void *src, size_t len) +{ + br_hash_compat_context hc; + + hc.vtable = dig; + dig->init(&hc.vtable); + dig->update(&hc.vtable, src, len); + dig->out(&hc.vtable, dst); +} + +/* see inner.h */ +size_t +br_rsa_oaep_pad(const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len) +{ + size_t k, hlen; + unsigned char *buf; + + hlen = br_digest_size(dig); + + /* + * Compute actual modulus length (in bytes). + */ + k = pk->nlen; + while (k > 0 && pk->n[k - 1] == 0) { + k --; + } + + /* + * An error is reported if: + * - the modulus is too short; + * - the source message length is too long; + * - the destination buffer is too short. + */ + if (k < ((hlen << 1) + 2) + || src_len > (k - (hlen << 1) - 2) + || dst_max_len < k) + { + return 0; + } + + /* + * Apply padding. At this point, things cannot fail. + */ + buf = dst; + + /* + * Assemble: DB = lHash || PS || 0x01 || M + * We first place the source message M with memmove(), so that + * overlaps between source and destination buffers are supported. + */ + memmove(buf + k - src_len, src, src_len); + hash_data(dig, buf + 1 + hlen, label, label_len); + memset(buf + 1 + (hlen << 1), 0, k - src_len - (hlen << 1) - 2); + buf[k - src_len - 1] = 0x01; + + /* + * Make the random seed. + */ + (*rnd)->generate(rnd, buf + 1, hlen); + + /* + * Mask DB with the mask generated from the seed. + */ + br_mgf1_xor(buf + 1 + hlen, k - hlen - 1, dig, buf + 1, hlen); + + /* + * Mask the seed with the mask generated from the masked DB. + */ + br_mgf1_xor(buf + 1, hlen, dig, buf + 1 + hlen, k - hlen - 1); + + /* + * Padding result: EM = 0x00 || maskedSeed || maskedDB. + */ + buf[0] = 0x00; + return k; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_oaep_unpad.c b/BearSSL-OG/libbearssl/src/rsa/rsa_oaep_unpad.c new file mode 100644 index 0000000..7c4be6a --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_oaep_unpad.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Hash some data and XOR the result into the provided buffer. This is put + * as a separate function so that stack allocation of the hash function + * context is done only for the duration of the hash. + */ +static void +xor_hash_data(const br_hash_class *dig, void *dst, const void *src, size_t len) +{ + br_hash_compat_context hc; + unsigned char tmp[64]; + unsigned char *buf; + size_t u, hlen; + + hc.vtable = dig; + dig->init(&hc.vtable); + dig->update(&hc.vtable, src, len); + dig->out(&hc.vtable, tmp); + buf = dst; + hlen = br_digest_size(dig); + for (u = 0; u < hlen; u ++) { + buf[u] ^= tmp[u]; + } +} + +/* see inner.h */ +uint32_t +br_rsa_oaep_unpad(const br_hash_class *dig, + const void *label, size_t label_len, + void *data, size_t *len) +{ + size_t u, k, hlen; + unsigned char *buf; + uint32_t r, s, zlen; + + hlen = br_digest_size(dig); + k = *len; + buf = data; + + /* + * There must be room for the padding. + */ + if (k < ((hlen << 1) + 2)) { + return 0; + } + + /* + * Unmask the seed, then the DB value. + */ + br_mgf1_xor(buf + 1, hlen, dig, buf + 1 + hlen, k - hlen - 1); + br_mgf1_xor(buf + 1 + hlen, k - hlen - 1, dig, buf + 1, hlen); + + /* + * Hash the label and XOR it with the value in the array; if + * they are equal then these should yield only zeros. + */ + xor_hash_data(dig, buf + 1 + hlen, label, label_len); + + /* + * At that point, if the padding was correct, when we should + * have: 0x00 || seed || 0x00 ... 0x00 0x01 || M + * Padding is valid as long as: + * - There is at least hlen+1 leading bytes of value 0x00. + * - There is at least one non-zero byte. + * - The first (leftmost) non-zero byte has value 0x01. + * + * Ultimately, we may leak the resulting message length, i.e. + * the position of the byte of value 0x01, but we must take care + * to do so only if the number of zero bytes has been verified + * to be at least hlen+1. + * + * The loop below counts the number of bytes of value 0x00, and + * checks that the next byte has value 0x01, in constant-time. + * + * - If the initial byte (before the seed) is not 0x00, then + * r and s are set to 0, and stay there. + * - Value r is 1 until the first non-zero byte is reached + * (after the seed); it switches to 0 at that point. + * - Value s is set to 1 if and only if the data encountered + * at the time of the transition of r from 1 to 0 has value + * exactly 0x01. + * - Value zlen counts the number of leading bytes of value zero + * (after the seed). + */ + r = 1 - ((buf[0] + 0xFF) >> 8); + s = 0; + zlen = 0; + for (u = hlen + 1; u < k; u ++) { + uint32_t w, nz; + + w = buf[u]; + + /* + * nz == 1 only for the first non-zero byte. + */ + nz = r & ((w + 0xFF) >> 8); + s |= nz & EQ(w, 0x01); + r &= NOT(nz); + zlen += r; + } + + /* + * Padding is correct only if s == 1, _and_ zlen >= hlen. + */ + s &= GE(zlen, (uint32_t)hlen); + + /* + * At that point, padding was verified, and we are now allowed + * to make conditional jumps. + */ + if (s) { + size_t plen; + + plen = 2 + hlen + zlen; + k -= plen; + memmove(buf, buf + plen, k); + *len = k; + } + return s; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_pkcs1_sig_pad.c b/BearSSL-OG/libbearssl/src/rsa/rsa_pkcs1_sig_pad.c new file mode 100644 index 0000000..06c3bd7 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_pkcs1_sig_pad.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_rsa_pkcs1_sig_pad(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + uint32_t n_bitlen, unsigned char *x) +{ + size_t u, x3, xlen; + + /* + * Padded hash value has format: + * 00 01 FF .. FF 00 30 x1 30 x2 06 x3 OID 05 00 04 x4 HASH + * + * with the following rules: + * + * -- Total length is equal to the modulus length (unsigned + * encoding). + * + * -- There must be at least eight bytes of value 0xFF. + * + * -- x4 is equal to the hash length (hash_len). + * + * -- x3 is equal to the encoded OID value length (hash_oid[0]). + * + * -- x2 = x3 + 4. + * + * -- x1 = x2 + x4 + 4 = x3 + x4 + 8. + * + * Note: the "05 00" is optional (signatures with and without + * that sequence exist in practice), but notes in PKCS#1 seem to + * indicate that the presence of that sequence (specifically, + * an ASN.1 NULL value for the hash parameters) may be slightly + * more "standard" than the opposite. + */ + xlen = (n_bitlen + 7) >> 3; + + if (hash_oid == NULL) { + if (xlen < hash_len + 11) { + return 0; + } + x[0] = 0x00; + x[1] = 0x01; + u = xlen - hash_len; + memset(x + 2, 0xFF, u - 3); + x[u - 1] = 0x00; + } else { + x3 = hash_oid[0]; + + /* + * Check that there is enough room for all the elements, + * including at least eight bytes of value 0xFF. + */ + if (xlen < (x3 + hash_len + 21)) { + return 0; + } + x[0] = 0x00; + x[1] = 0x01; + u = xlen - x3 - hash_len - 11; + memset(x + 2, 0xFF, u - 2); + x[u] = 0x00; + x[u + 1] = 0x30; + x[u + 2] = x3 + hash_len + 8; + x[u + 3] = 0x30; + x[u + 4] = x3 + 4; + x[u + 5] = 0x06; + memcpy(x + u + 6, hash_oid, x3 + 1); + u += x3 + 7; + x[u ++] = 0x05; + x[u ++] = 0x00; + x[u ++] = 0x04; + x[u ++] = hash_len; + } + memcpy(x + u, hash, hash_len); + return 1; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_pkcs1_sig_unpad.c b/BearSSL-OG/libbearssl/src/rsa/rsa_pkcs1_sig_unpad.c new file mode 100644 index 0000000..c8ae08f --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_pkcs1_sig_unpad.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_pkcs1_sig_unpad(const unsigned char *sig, size_t sig_len, + const unsigned char *hash_oid, size_t hash_len, + unsigned char *hash_out) +{ + static const unsigned char pad1[] = { + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + + unsigned char pad2[43]; + size_t u, x2, x3, pad_len, zlen; + + if (sig_len < 11) { + return 0; + } + + /* + * Expected format: + * 00 01 FF ... FF 00 30 x1 30 x2 06 x3 OID [ 05 00 ] 04 x4 HASH + * + * with the following rules: + * + * -- Total length is that of the modulus and the signature + * (this was already verified by br_rsa_i31_public()). + * + * -- There are at least eight bytes of value 0xFF. + * + * -- x4 is equal to the hash length (hash_len). + * + * -- x3 is equal to the encoded OID value length (so x3 is the + * first byte of hash_oid[]). + * + * -- If the "05 00" is present, then x2 == x3 + 4; otherwise, + * x2 == x3 + 2. + * + * -- x1 == x2 + x4 + 4. + * + * So the total length after the last "FF" is either x3 + x4 + 11 + * (with the "05 00") or x3 + x4 + 9 (without the "05 00"). + */ + + /* + * Check the "00 01 FF .. FF 00" with at least eight 0xFF bytes. + * The comparison is valid because we made sure that the signature + * is at least 11 bytes long. + */ + if (memcmp(sig, pad1, sizeof pad1) != 0) { + return 0; + } + for (u = sizeof pad1; u < sig_len; u ++) { + if (sig[u] != 0xFF) { + break; + } + } + + /* + * Remaining length is sig_len - u bytes (including the 00 just + * after the last FF). This must be equal to one of the two + * possible values (depending on whether the "05 00" sequence is + * present or not). + */ + if (hash_oid == NULL) { + if (sig_len - u != hash_len + 1 || sig[u] != 0x00) { + return 0; + } + } else { + x3 = hash_oid[0]; + pad_len = x3 + 9; + memset(pad2, 0, pad_len); + zlen = sig_len - u - hash_len; + if (zlen == pad_len) { + x2 = x3 + 2; + } else if (zlen == pad_len + 2) { + x2 = x3 + 4; + pad_len = zlen; + pad2[pad_len - 4] = 0x05; + } else { + return 0; + } + pad2[1] = 0x30; + pad2[2] = x2 + hash_len + 4; + pad2[3] = 0x30; + pad2[4] = x2; + pad2[5] = 0x06; + memcpy(pad2 + 6, hash_oid, x3 + 1); + pad2[pad_len - 2] = 0x04; + pad2[pad_len - 1] = hash_len; + if (memcmp(pad2, sig + u, pad_len) != 0) { + return 0; + } + } + memcpy(hash_out, sig + sig_len - hash_len, hash_len); + return 1; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_pss_sig_pad.c b/BearSSL-OG/libbearssl/src/rsa/rsa_pss_sig_pad.c new file mode 100644 index 0000000..13e9027 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_pss_sig_pad.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_rsa_pss_sig_pad(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash, size_t salt_len, + uint32_t n_bitlen, unsigned char *x) +{ + size_t xlen, hash_len; + br_hash_compat_context hc; + unsigned char *salt, *seed; + + hash_len = br_digest_size(hf_data); + + /* + * The padded string is one bit smaller than the modulus; + * notably, if the modulus length is equal to 1 modulo 8, then + * the padded string will be one _byte_ smaller, and the first + * byte will be set to 0. We apply these transformations here. + */ + n_bitlen --; + if ((n_bitlen & 7) == 0) { + *x ++ = 0; + } + xlen = (n_bitlen + 7) >> 3; + + /* + * Check that the modulus is large enough for the hash value + * length combined with the intended salt length. + */ + if (hash_len > xlen || salt_len > xlen + || (hash_len + salt_len + 2) > xlen) + { + return 0; + } + + /* + * Produce a random salt. + */ + salt = x + xlen - hash_len - salt_len - 1; + if (salt_len != 0) { + (*rng)->generate(rng, salt, salt_len); + } + + /* + * Compute the seed for MGF1. + */ + seed = x + xlen - hash_len - 1; + hf_data->init(&hc.vtable); + memset(seed, 0, 8); + hf_data->update(&hc.vtable, seed, 8); + hf_data->update(&hc.vtable, hash, hash_len); + hf_data->update(&hc.vtable, salt, salt_len); + hf_data->out(&hc.vtable, seed); + + /* + * Prepare string PS (padded salt). The salt is already at the + * right place. + */ + memset(x, 0, xlen - salt_len - hash_len - 2); + x[xlen - salt_len - hash_len - 2] = 0x01; + + /* + * Generate the mask and XOR it into PS. + */ + br_mgf1_xor(x, xlen - hash_len - 1, hf_mgf1, seed, hash_len); + + /* + * Clear the top bits to ensure the value is lower than the + * modulus. + */ + x[0] &= 0xFF >> (((uint32_t)xlen << 3) - n_bitlen); + + /* + * The seed (H) is already in the right place. We just set the + * last byte. + */ + x[xlen - 1] = 0xBC; + + return 1; +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_pss_sig_unpad.c b/BearSSL-OG/libbearssl/src/rsa/rsa_pss_sig_unpad.c new file mode 100644 index 0000000..0c6ae99 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_pss_sig_unpad.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +uint32_t +br_rsa_pss_sig_unpad(const br_hash_class *hf_data, + const br_hash_class *hf_mgf1, + const unsigned char *hash, size_t salt_len, + const br_rsa_public_key *pk, unsigned char *x) +{ + size_t u, xlen, hash_len; + br_hash_compat_context hc; + unsigned char *seed, *salt; + unsigned char tmp[64]; + uint32_t r, n_bitlen; + + hash_len = br_digest_size(hf_data); + + /* + * Value r will be set to a non-zero value is any test fails. + */ + r = 0; + + /* + * The value bit length (as an integer) must be strictly less than + * that of the modulus. + */ + for (u = 0; u < pk->nlen; u ++) { + if (pk->n[u] != 0) { + break; + } + } + if (u == pk->nlen) { + return 0; + } + n_bitlen = BIT_LENGTH(pk->n[u]) + ((uint32_t)(pk->nlen - u - 1) << 3); + n_bitlen --; + if ((n_bitlen & 7) == 0) { + r |= *x ++; + } else { + r |= x[0] & (0xFF << (n_bitlen & 7)); + } + xlen = (n_bitlen + 7) >> 3; + + /* + * Check that the modulus is large enough for the hash value + * length combined with the intended salt length. + */ + if (hash_len > xlen || salt_len > xlen + || (hash_len + salt_len + 2) > xlen) + { + return 0; + } + + /* + * Check value of rightmost byte. + */ + r |= x[xlen - 1] ^ 0xBC; + + /* + * Generate the mask and XOR it into the first bytes to reveal PS; + * we must also mask out the leading bits. + */ + seed = x + xlen - hash_len - 1; + br_mgf1_xor(x, xlen - hash_len - 1, hf_mgf1, seed, hash_len); + if ((n_bitlen & 7) != 0) { + x[0] &= 0xFF >> (8 - (n_bitlen & 7)); + } + + /* + * Check that all padding bytes have the expected value. + */ + for (u = 0; u < (xlen - hash_len - salt_len - 2); u ++) { + r |= x[u]; + } + r |= x[xlen - hash_len - salt_len - 2] ^ 0x01; + + /* + * Recompute H. + */ + salt = x + xlen - hash_len - salt_len - 1; + hf_data->init(&hc.vtable); + memset(tmp, 0, 8); + hf_data->update(&hc.vtable, tmp, 8); + hf_data->update(&hc.vtable, hash, hash_len); + hf_data->update(&hc.vtable, salt, salt_len); + hf_data->out(&hc.vtable, tmp); + + /* + * Check that the recomputed H value matches the one appearing + * in the string. + */ + for (u = 0; u < hash_len; u ++) { + r |= tmp[u] ^ x[(xlen - hash_len - 1) + u]; + } + + return EQ0(r); +} diff --git a/BearSSL-OG/libbearssl/src/rsa/rsa_ssl_decrypt.c b/BearSSL-OG/libbearssl/src/rsa/rsa_ssl_decrypt.c new file mode 100644 index 0000000..047eb18 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/rsa/rsa_ssl_decrypt.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_rsa.h */ +uint32_t +br_rsa_ssl_decrypt(br_rsa_private core, const br_rsa_private_key *sk, + unsigned char *data, size_t len) +{ + uint32_t x; + size_t u; + + /* + * A first check on length. Since this test works only on the + * buffer length, it needs not (and cannot) be constant-time. + */ + if (len < 59 || len != (sk->n_bitlen + 7) >> 3) { + return 0; + } + x = core(data, sk); + + x &= EQ(data[0], 0x00); + x &= EQ(data[1], 0x02); + for (u = 2; u < (len - 49); u ++) { + x &= NEQ(data[u], 0); + } + x &= EQ(data[len - 49], 0x00); + memmove(data, data + len - 48, 48); + return x; +} diff --git a/BearSSL-OG/libbearssl/src/settings.c b/BearSSL-OG/libbearssl/src/settings.c new file mode 100644 index 0000000..0014609 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/settings.c @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static const br_config_option config[] = { + { "BR_64", +#if BR_64 + 1 +#else + 0 +#endif + }, + { "BR_AES_X86NI", +#if BR_AES_X86NI + 1 +#else + 0 +#endif + }, + { "BR_amd64", +#if BR_amd64 + 1 +#else + 0 +#endif + }, + { "BR_ARMEL_CORTEXM_GCC", +#if BR_ARMEL_CORTEXM_GCC + 1 +#else + 0 +#endif + }, + { "BR_BE_UNALIGNED", +#if BR_BE_UNALIGNED + 1 +#else + 0 +#endif + }, + { "BR_CLANG", +#if BR_CLANG + 1 +#else + 0 +#endif + }, + { "BR_CLANG_3_7", +#if BR_CLANG_3_7 + 1 +#else + 0 +#endif + }, + { "BR_CLANG_3_8", +#if BR_CLANG_3_8 + 1 +#else + 0 +#endif + }, + { "BR_CT_MUL15", +#if BR_CT_MUL15 + 1 +#else + 0 +#endif + }, + { "BR_CT_MUL31", +#if BR_CT_MUL31 + 1 +#else + 0 +#endif + }, + { "BR_GCC", +#if BR_GCC + 1 +#else + 0 +#endif + }, + { "BR_GCC_4_4", +#if BR_GCC_4_4 + 1 +#else + 0 +#endif + }, + { "BR_GCC_4_5", +#if BR_GCC_4_5 + 1 +#else + 0 +#endif + }, + { "BR_GCC_4_6", +#if BR_GCC_4_6 + 1 +#else + 0 +#endif + }, + { "BR_GCC_4_7", +#if BR_GCC_4_7 + 1 +#else + 0 +#endif + }, + { "BR_GCC_4_8", +#if BR_GCC_4_8 + 1 +#else + 0 +#endif + }, + { "BR_GCC_4_9", +#if BR_GCC_4_9 + 1 +#else + 0 +#endif + }, + { "BR_GCC_5_0", +#if BR_GCC_5_0 + 1 +#else + 0 +#endif + }, + { "BR_i386", +#if BR_i386 + 1 +#else + 0 +#endif + }, + { "BR_INT128", +#if BR_INT128 + 1 +#else + 0 +#endif + }, + { "BR_LE_UNALIGNED", +#if BR_LE_UNALIGNED + 1 +#else + 0 +#endif + }, + { "BR_LOMUL", +#if BR_LOMUL + 1 +#else + 0 +#endif + }, + { "BR_MAX_EC_SIZE", BR_MAX_EC_SIZE }, + { "BR_MAX_RSA_SIZE", BR_MAX_RSA_SIZE }, + { "BR_MAX_RSA_FACTOR", BR_MAX_RSA_FACTOR }, + { "BR_MSC", +#if BR_MSC + 1 +#else + 0 +#endif + }, + { "BR_MSC_2005", +#if BR_MSC_2005 + 1 +#else + 0 +#endif + }, + { "BR_MSC_2008", +#if BR_MSC_2008 + 1 +#else + 0 +#endif + }, + { "BR_MSC_2010", +#if BR_MSC_2010 + 1 +#else + 0 +#endif + }, + { "BR_MSC_2012", +#if BR_MSC_2012 + 1 +#else + 0 +#endif + }, + { "BR_MSC_2013", +#if BR_MSC_2013 + 1 +#else + 0 +#endif + }, + { "BR_MSC_2015", +#if BR_MSC_2015 + 1 +#else + 0 +#endif + }, + { "BR_POWER8", +#if BR_POWER8 + 1 +#else + 0 +#endif + }, + { "BR_RDRAND", +#if BR_RDRAND + 1 +#else + 0 +#endif + }, + { "BR_SLOW_MUL", +#if BR_SLOW_MUL + 1 +#else + 0 +#endif + }, + { "BR_SLOW_MUL15", +#if BR_SLOW_MUL15 + 1 +#else + 0 +#endif + }, + { "BR_SSE2", +#if BR_SSE2 + 1 +#else + 0 +#endif + }, + { "BR_UMUL128", +#if BR_UMUL128 + 1 +#else + 0 +#endif + }, + { "BR_USE_UNIX_TIME", +#if BR_USE_UNIX_TIME + 1 +#else + 0 +#endif + }, + { "BR_USE_WIN32_RAND", +#if BR_USE_WIN32_RAND + 1 +#else + 0 +#endif + }, + { "BR_USE_XBOX_RAND", +#if BR_USE_XBOX_RAND + 1 +#else + 0 +#endif + }, + { "BR_USE_WIN32_TIME", +#if BR_USE_WIN32_TIME + 1 +#else + 0 +#endif + }, + + { NULL, 0 } +}; + +/* see bearssl.h */ +const br_config_option * +br_get_config(void) +{ + return config; +} diff --git a/BearSSL-OG/libbearssl/src/ssl/prf.c b/BearSSL-OG/libbearssl/src/ssl/prf.c new file mode 100644 index 0000000..f04a5fb --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/prf.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_tls_phash(void *dst, size_t len, + const br_hash_class *dig, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed) +{ + unsigned char *buf; + unsigned char tmp[64], a[64]; + br_hmac_key_context kc; + br_hmac_context hc; + size_t label_len, hlen, u; + + if (len == 0) { + return; + } + buf = dst; + for (label_len = 0; label[label_len]; label_len ++); + hlen = br_digest_size(dig); + br_hmac_key_init(&kc, dig, secret, secret_len); + br_hmac_init(&hc, &kc, 0); + br_hmac_update(&hc, label, label_len); + for (u = 0; u < seed_num; u ++) { + br_hmac_update(&hc, seed[u].data, seed[u].len); + } + br_hmac_out(&hc, a); + for (;;) { + br_hmac_init(&hc, &kc, 0); + br_hmac_update(&hc, a, hlen); + br_hmac_update(&hc, label, label_len); + for (u = 0; u < seed_num; u ++) { + br_hmac_update(&hc, seed[u].data, seed[u].len); + } + br_hmac_out(&hc, tmp); + for (u = 0; u < hlen && u < len; u ++) { + buf[u] ^= tmp[u]; + } + buf += u; + len -= u; + if (len == 0) { + return; + } + br_hmac_init(&hc, &kc, 0); + br_hmac_update(&hc, a, hlen); + br_hmac_out(&hc, a); + } +} diff --git a/BearSSL-OG/libbearssl/src/ssl/prf_md5sha1.c b/BearSSL-OG/libbearssl/src/ssl/prf_md5sha1.c new file mode 100644 index 0000000..3212833 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/prf_md5sha1.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl.h */ +void +br_tls10_prf(void *dst, size_t len, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed) +{ + const unsigned char *s1; + size_t slen; + + s1 = secret; + slen = (secret_len + 1) >> 1; + memset(dst, 0, len); + br_tls_phash(dst, len, &br_md5_vtable, + s1, slen, label, seed_num, seed); + br_tls_phash(dst, len, &br_sha1_vtable, + s1 + secret_len - slen, slen, label, seed_num, seed); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/prf_sha256.c b/BearSSL-OG/libbearssl/src/ssl/prf_sha256.c new file mode 100644 index 0000000..76041de --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/prf_sha256.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl.h */ +void +br_tls12_sha256_prf(void *dst, size_t len, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed) +{ + memset(dst, 0, len); + br_tls_phash(dst, len, &br_sha256_vtable, + secret, secret_len, label, seed_num, seed); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/prf_sha384.c b/BearSSL-OG/libbearssl/src/ssl/prf_sha384.c new file mode 100644 index 0000000..c20c4e6 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/prf_sha384.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl.h */ +void +br_tls12_sha384_prf(void *dst, size_t len, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed) +{ + memset(dst, 0, len); + br_tls_phash(dst, len, &br_sha384_vtable, + secret, secret_len, label, seed_num, seed); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_ccert_single_ec.c b/BearSSL-OG/libbearssl/src/ssl/ssl_ccert_single_ec.c new file mode 100644 index 0000000..2e1e54f --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_ccert_single_ec.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static void +cc_none0(const br_ssl_client_certificate_class **pctx) +{ + (void)pctx; +} + +static void +cc_none1(const br_ssl_client_certificate_class **pctx, size_t len) +{ + (void)pctx; + (void)len; +} + +static void +cc_none2(const br_ssl_client_certificate_class **pctx, + const unsigned char *data, size_t len) +{ + (void)pctx; + (void)data; + (void)len; +} + +static void +cc_choose(const br_ssl_client_certificate_class **pctx, + const br_ssl_client_context *cc, uint32_t auth_types, + br_ssl_client_certificate *choices) +{ + br_ssl_client_certificate_ec_context *zc; + int x; + int scurve; + + zc = (br_ssl_client_certificate_ec_context *)pctx; + scurve = br_ssl_client_get_server_curve(cc); + + if ((zc->allowed_usages & BR_KEYTYPE_KEYX) != 0 + && scurve == zc->sk->curve) + { + int x; + + x = (zc->issuer_key_type == BR_KEYTYPE_RSA) ? 16 : 17; + if (((auth_types >> x) & 1) != 0) { + choices->auth_type = BR_AUTH_ECDH; + choices->hash_id = -1; + choices->chain = zc->chain; + choices->chain_len = zc->chain_len; + return; + } + } + + /* + * For ECDSA authentication, we must choose an appropriate + * hash function. + */ + x = br_ssl_choose_hash((unsigned)(auth_types >> 8)); + if (x == 0 || (zc->allowed_usages & BR_KEYTYPE_SIGN) == 0) { + memset(choices, 0, sizeof *choices); + return; + } + choices->auth_type = BR_AUTH_ECDSA; + choices->hash_id = x; + choices->chain = zc->chain; + choices->chain_len = zc->chain_len; +} + +static uint32_t +cc_do_keyx(const br_ssl_client_certificate_class **pctx, + unsigned char *data, size_t *len) +{ + br_ssl_client_certificate_ec_context *zc; + uint32_t r; + size_t xoff, xlen; + + zc = (br_ssl_client_certificate_ec_context *)pctx; + r = zc->iec->mul(data, *len, zc->sk->x, zc->sk->xlen, zc->sk->curve); + xoff = zc->iec->xoff(zc->sk->curve, &xlen); + memmove(data, data + xoff, xlen); + *len = xlen; + return r; +} + +static size_t +cc_do_sign(const br_ssl_client_certificate_class **pctx, + int hash_id, size_t hv_len, unsigned char *data, size_t len) +{ + br_ssl_client_certificate_ec_context *zc; + unsigned char hv[64]; + const br_hash_class *hc; + + zc = (br_ssl_client_certificate_ec_context *)pctx; + memcpy(hv, data, hv_len); + hc = br_multihash_getimpl(zc->mhash, hash_id); + if (hc == NULL) { + return 0; + } + if (len < 139) { + return 0; + } + return zc->iecdsa(zc->iec, hc, hv, zc->sk, data); +} + +static const br_ssl_client_certificate_class ccert_vtable = { + sizeof(br_ssl_client_certificate_ec_context), + cc_none0, /* start_name_list */ + cc_none1, /* start_name */ + cc_none2, /* append_name */ + cc_none0, /* end_name */ + cc_none0, /* end_name_list */ + cc_choose, + cc_do_keyx, + cc_do_sign +}; + +/* see bearssl_ssl.h */ +void +br_ssl_client_set_single_ec(br_ssl_client_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk, unsigned allowed_usages, + unsigned cert_issuer_key_type, + const br_ec_impl *iec, br_ecdsa_sign iecdsa) +{ + cc->client_auth.single_ec.vtable = &ccert_vtable; + cc->client_auth.single_ec.chain = chain; + cc->client_auth.single_ec.chain_len = chain_len; + cc->client_auth.single_ec.sk = sk; + cc->client_auth.single_ec.allowed_usages = allowed_usages; + cc->client_auth.single_ec.issuer_key_type = cert_issuer_key_type; + cc->client_auth.single_ec.mhash = &cc->eng.mhash; + cc->client_auth.single_ec.iec = iec; + cc->client_auth.single_ec.iecdsa = iecdsa; + cc->client_auth_vtable = &cc->client_auth.single_ec.vtable; +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_ccert_single_rsa.c b/BearSSL-OG/libbearssl/src/ssl/ssl_ccert_single_rsa.c new file mode 100644 index 0000000..690df20 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_ccert_single_rsa.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static void +cc_none0(const br_ssl_client_certificate_class **pctx) +{ + (void)pctx; +} + +static void +cc_none1(const br_ssl_client_certificate_class **pctx, size_t len) +{ + (void)pctx; + (void)len; +} + +static void +cc_none2(const br_ssl_client_certificate_class **pctx, + const unsigned char *data, size_t len) +{ + (void)pctx; + (void)data; + (void)len; +} + +static void +cc_choose(const br_ssl_client_certificate_class **pctx, + const br_ssl_client_context *cc, uint32_t auth_types, + br_ssl_client_certificate *choices) +{ + br_ssl_client_certificate_rsa_context *zc; + int x; + + (void)cc; + zc = (br_ssl_client_certificate_rsa_context *)pctx; + x = br_ssl_choose_hash((unsigned)auth_types); + if (x == 0 && (auth_types & 1) == 0) { + memset(choices, 0, sizeof *choices); + } + choices->auth_type = BR_AUTH_RSA; + choices->hash_id = x; + choices->chain = zc->chain; + choices->chain_len = zc->chain_len; +} + +/* + * OID for hash functions in RSA signatures. + */ +static const unsigned char HASH_OID_SHA1[] = { + 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A +}; + +static const unsigned char HASH_OID_SHA224[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 +}; + +static const unsigned char HASH_OID_SHA256[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 +}; + +static const unsigned char HASH_OID_SHA384[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 +}; + +static const unsigned char HASH_OID_SHA512[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 +}; + +static const unsigned char *HASH_OID[] = { + HASH_OID_SHA1, + HASH_OID_SHA224, + HASH_OID_SHA256, + HASH_OID_SHA384, + HASH_OID_SHA512 +}; + +static size_t +cc_do_sign(const br_ssl_client_certificate_class **pctx, + int hash_id, size_t hv_len, unsigned char *data, size_t len) +{ + br_ssl_client_certificate_rsa_context *zc; + unsigned char hv[64]; + const unsigned char *hash_oid; + size_t sig_len; + + zc = (br_ssl_client_certificate_rsa_context *)pctx; + memcpy(hv, data, hv_len); + if (hash_id == 0) { + hash_oid = NULL; + } else if (hash_id >= 2 && hash_id <= 6) { + hash_oid = HASH_OID[hash_id - 2]; + } else { + return 0; + } + sig_len = (zc->sk->n_bitlen + 7) >> 3; + if (len < sig_len) { + return 0; + } + return zc->irsasign(hash_oid, hv, hv_len, zc->sk, data) ? sig_len : 0; +} + +static const br_ssl_client_certificate_class ccert_vtable = { + sizeof(br_ssl_client_certificate_rsa_context), + cc_none0, /* start_name_list */ + cc_none1, /* start_name */ + cc_none2, /* append_name */ + cc_none0, /* end_name */ + cc_none0, /* end_name_list */ + cc_choose, + 0, + cc_do_sign +}; + +/* see bearssl_ssl.h */ +void +br_ssl_client_set_single_rsa(br_ssl_client_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk, br_rsa_pkcs1_sign irsasign) +{ + cc->client_auth.single_rsa.vtable = &ccert_vtable; + cc->client_auth.single_rsa.chain = chain; + cc->client_auth.single_rsa.chain_len = chain_len; + cc->client_auth.single_rsa.sk = sk; + cc->client_auth.single_rsa.irsasign = irsasign; + cc->client_auth_vtable = &cc->client_auth.single_rsa.vtable; +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_client.c b/BearSSL-OG/libbearssl/src/ssl/ssl_client.c new file mode 100644 index 0000000..28c404b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_client.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_client_zero(br_ssl_client_context *cc) +{ + /* + * For really standard C, we should explicitly set to NULL all + * pointers, and 0 all other fields. However, on all our target + * architectures, a direct memset() will work, be faster, and + * use a lot less code. + */ + memset(cc, 0, sizeof *cc); +} + +/* see bearssl_ssl.h */ +int +br_ssl_client_reset(br_ssl_client_context *cc, + const char *server_name, int resume_session) +{ + size_t n; + + br_ssl_engine_set_buffer(&cc->eng, NULL, 0, 0); + cc->eng.version_out = cc->eng.version_min; + if (!resume_session) { + br_ssl_client_forget_session(cc); + } + if (!br_ssl_engine_init_rand(&cc->eng)) { + return 0; + } + + /* + * We always set back the "reneg" flag to 0 because we use it + * to distinguish between first handshake and renegotiation. + * Note that "renegotiation" and "session resumption" are two + * different things. + */ + cc->eng.reneg = 0; + + if (server_name == NULL) { + cc->eng.server_name[0] = 0; + } else { + n = strlen(server_name) + 1; + if (n > sizeof cc->eng.server_name) { + br_ssl_engine_fail(&cc->eng, BR_ERR_BAD_PARAM); + return 0; + } + memcpy(cc->eng.server_name, server_name, n); + } + + br_ssl_engine_hs_reset(&cc->eng, + br_ssl_hs_client_init_main, br_ssl_hs_client_run); + return br_ssl_engine_last_error(&cc->eng) == BR_ERR_OK; +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_client_default_rsapub.c b/BearSSL-OG/libbearssl/src/ssl/ssl_client_default_rsapub.c new file mode 100644 index 0000000..2cdaab8 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_client_default_rsapub.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_client_set_default_rsapub(br_ssl_client_context *cc) +{ + br_ssl_client_set_rsapub(cc, br_rsa_public_get_default()); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_client_full.c b/BearSSL-OG/libbearssl/src/ssl/ssl_client_full.c new file mode 100644 index 0000000..9814349 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_client_full.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_client_init_full(br_ssl_client_context *cc, + br_x509_minimal_context *xc, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) +{ + /* + * The "full" profile supports all implemented cipher suites. + * + * Rationale for suite order, from most important to least + * important rule: + * + * -- Don't use 3DES if AES or ChaCha20 is available. + * -- Try to have Forward Secrecy (ECDHE suite) if possible. + * -- When not using Forward Secrecy, ECDH key exchange is + * better than RSA key exchange (slightly more expensive on the + * client, but much cheaper on the server, and it implies smaller + * messages). + * -- ChaCha20+Poly1305 is better than AES/GCM (faster, smaller code). + * -- GCM is better than CCM and CBC. CCM is better than CBC. + * -- CCM is preferable over CCM_8 (with CCM_8, forgeries may succeed + * with probability 2^(-64)). + * -- AES-128 is preferred over AES-256 (AES-128 is already + * strong enough, and AES-256 is 40% more expensive). + */ + static const uint16_t suites[] = { + BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + BR_TLS_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_RSA_WITH_AES_128_CCM, + BR_TLS_RSA_WITH_AES_256_CCM, + BR_TLS_RSA_WITH_AES_128_CCM_8, + BR_TLS_RSA_WITH_AES_256_CCM_8, + BR_TLS_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_RSA_WITH_AES_256_CBC_SHA256, + BR_TLS_RSA_WITH_AES_128_CBC_SHA, + BR_TLS_RSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA + }; + + /* + * All hash functions are activated. + * Note: the X.509 validation engine will nonetheless refuse to + * validate signatures that use MD5 as hash function. + */ + static const br_hash_class *hashes[] = { + &br_md5_vtable, + &br_sha1_vtable, + &br_sha224_vtable, + &br_sha256_vtable, + &br_sha384_vtable, + &br_sha512_vtable + }; + + int id; + + /* + * Reset client context and set supported versions from TLS-1.0 + * to TLS-1.2 (inclusive). + */ + br_ssl_client_zero(cc); + br_ssl_engine_set_versions(&cc->eng, BR_TLS10, BR_TLS12); + + /* + * X.509 engine uses SHA-256 to hash certificate DN (for + * comparisons). + */ + br_x509_minimal_init(xc, &br_sha256_vtable, + trust_anchors, trust_anchors_num); + + /* + * Set suites and asymmetric crypto implementations. We use the + * "i31" code for RSA (it is somewhat faster than the "i32" + * implementation). + * TODO: change that when better implementations are made available. + */ + br_ssl_engine_set_suites(&cc->eng, suites, + (sizeof suites) / (sizeof suites[0])); + br_ssl_client_set_default_rsapub(cc); + br_ssl_engine_set_default_rsavrfy(&cc->eng); + br_ssl_engine_set_default_ecdsa(&cc->eng); + br_x509_minimal_set_rsa(xc, br_ssl_engine_get_rsavrfy(&cc->eng)); + br_x509_minimal_set_ecdsa(xc, + br_ssl_engine_get_ec(&cc->eng), + br_ssl_engine_get_ecdsa(&cc->eng)); + + /* + * Set supported hash functions, for the SSL engine and for the + * X.509 engine. + */ + for (id = br_md5_ID; id <= br_sha512_ID; id ++) { + const br_hash_class *hc; + + hc = hashes[id - 1]; + br_ssl_engine_set_hash(&cc->eng, id, hc); + br_x509_minimal_set_hash(xc, id, hc); + } + + /* + * Link the X.509 engine in the SSL engine. + */ + br_ssl_engine_set_x509(&cc->eng, &xc->vtable); + + /* + * Set the PRF implementations. + */ + br_ssl_engine_set_prf10(&cc->eng, &br_tls10_prf); + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf); + + /* + * Symmetric encryption. We use the "default" implementations + * (fastest among constant-time implementations). + */ + br_ssl_engine_set_default_aes_cbc(&cc->eng); + br_ssl_engine_set_default_aes_ccm(&cc->eng); + br_ssl_engine_set_default_aes_gcm(&cc->eng); + br_ssl_engine_set_default_des_cbc(&cc->eng); + br_ssl_engine_set_default_chapol(&cc->eng); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_engine.c b/BearSSL-OG/libbearssl/src/ssl/ssl_engine.c new file mode 100644 index 0000000..fc8b05a --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_engine.c @@ -0,0 +1,1589 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if 0 +/* obsolete */ + +/* + * If BR_USE_URANDOM is not defined, then try to autodetect its presence + * through compiler macros. + */ +#ifndef BR_USE_URANDOM + +/* + * Macro values documented on: + * https://sourceforge.net/p/predef/wiki/OperatingSystems/ + * + * Only the most common systems have been included here for now. This + * should be enriched later on. + */ +#if defined _AIX \ + || defined __ANDROID__ \ + || defined __FreeBSD__ \ + || defined __NetBSD__ \ + || defined __OpenBSD__ \ + || defined __DragonFly__ \ + || defined __linux__ \ + || (defined __sun && (defined __SVR4 || defined __svr4__)) \ + || (defined __APPLE__ && defined __MACH__) +#define BR_USE_URANDOM 1 +#endif + +#endif + +/* + * If BR_USE_WIN32_RAND is not defined, perform autodetection here. + */ +#ifndef _XBOX +#ifndef BR_USE_WIN32_RAND +#if defined _WIN32 || defined _WIN64 +#define BR_USE_WIN32_RAND 1 +#endif +#endif + +#ifdef _XBOX +#define BR_USE_XBOX_RAND 1 +#endif + +#endif + +#if BR_USE_URANDOM +#include +#include +#include +#include +#endif + +#if BR_USE_WIN32_RAND +#include +#include +#pragma comment(lib, "advapi32") +#endif + +#endif + +/* ==================================================================== */ +/* + * This part of the file does the low-level record management. + */ + +/* + * IMPLEMENTATION NOTES + * ==================== + * + * In this file, we designate by "input" (and the "i" letter) the "recv" + * operations: incoming records from the peer, from which payload data + * is obtained, and must be extracted by the application (or the SSL + * handshake engine). Similarly, "output" (and the "o" letter) is for + * "send": payload data injected by the application (and SSL handshake + * engine), to be wrapped into records, that are then conveyed to the + * peer over the transport medium. + * + * The input and output buffers may be distinct or shared. When + * shared, input and output cannot occur concurrently; the caller + * must make sure that it never needs to output data while input + * data has been received. In practice, a shared buffer prevents + * pipelining of HTTP requests, or similar protocols; however, a + * shared buffer saves RAM. + * + * The input buffer is pointed to by 'ibuf' and has size 'ibuf_len'; + * the output buffer is pointed to by 'obuf' and has size 'obuf_len'. + * From the size of these buffers is derived the maximum fragment + * length, which will be honoured upon sending records; regardless of + * that length, incoming records will be processed as long as they + * fit in the input buffer, and their length still complies with the + * protocol specification (maximum plaintext payload length is 16384 + * bytes). + * + * Three registers are used to manage buffering in ibuf, called ixa, + * ixb and ixc. Similarly, three registers are used to manage buffering + * in obuf, called oxa, oxb and oxc. + * + * + * At any time, the engine is in one of the following modes: + * -- Failed mode: an error occurs, no I/O can happen. + * -- Input mode: the engine can either receive record bytes from the + * transport layer, or it has some buffered payload bytes to yield. + * -- Output mode: the engine can either receive payload bytes, or it + * has some record bytes to send to the transport layer. + * -- Input/Output mode: both input and output modes are active. When + * the buffer is shared, this can happen only when the buffer is empty + * (no buffered payload bytes or record bytes in either direction). + * + * + * Failed mode: + * ------------ + * + * I/O failed for some reason (invalid received data, not enough room + * for the next record...). No I/O may ever occur again for this context, + * until an explicit reset is performed. This mode, and the error code, + * are also used for protocol errors, especially handshake errors. + * + * + * Input mode: + * ----------- + * + * ixa index within ibuf[] for the currently read data + * ixb maximum index within ibuf[] for the currently read data + * ixc number of bytes not yet received for the current record + * + * -- When ixa == ixb, there is no available data for readers. When + * ixa != ixb, there is available data and it starts at offset ixa. + * + * -- When waiting for the next record header, ixa and ixb are equal + * and contain a value ranging from 0 to 4; ixc is equal to 5-ixa. + * + * -- When the header has been received, record data is obtained. The + * ixc field records how many bytes are still needed to reach the + * end of the current record. + * + * ** If encryption is active, then ixa and ixb are kept equal, and + * point to the end of the currently received record bytes. When + * ixc reaches 0, decryption/MAC is applied, and ixa and ixb are + * adjusted. + * + * ** If encryption is not active, then ixa and ixb are distinct + * and data can be read right away. Additional record data is + * obtained only when ixa == ixb. + * + * Note: in input mode and no encryption, records larger than the buffer + * size are allowed. When encryption is active, the complete record must + * fit within the buffer, since it cannot be decrypted/MACed until it + * has been completely received. + * + * -- When receiving the next record header, 'version_in' contains the + * expected input version (0 if not expecting a specific version); on + * mismatch, the mode switches to 'failed'. + * + * -- When the header has been received, 'version_in' contains the received + * version. It is up to the caller to check and adjust the 'version_in' field + * to implement the required semantics. + * + * -- The 'record_type_in' field is updated with the incoming record type + * when the next record header has been received. + * + * + * Output mode: + * ------------ + * + * oxa index within obuf[] for the currently accumulated data + * oxb maximum index within obuf[] for record data + * oxc pointer for start of record data, and for record sending + * + * -- When oxa != oxb, more data can be accumulated into the current + * record; when oxa == oxb, a closed record is being sent. + * + * -- When accumulating data, oxc points to the start of the data. + * + * -- During record sending, oxa (and oxb) point to the next record byte + * to send, and oxc indicates the end of the current record. + * + * Note: sent records must fit within the buffer, since the header is + * adjusted only when the complete record has been assembled. + * + * -- The 'version_out' and 'record_type_out' fields are used to build the + * record header when the mode is switched to 'sending'. + * + * + * Modes: + * ------ + * + * The state register iomode contains one of the following values: + * + * BR_IO_FAILED I/O failed + * BR_IO_IN input mode + * BR_IO_OUT output mode + * BR_IO_INOUT input/output mode + * + * Whether encryption is active on incoming records is indicated by the + * incrypt flag. For outgoing records, there is no such flag; "encryption" + * is always considered active, but initially uses functions that do not + * encrypt anything. The 'incrypt' flag is needed because when there is + * no active encryption, records larger than the I/O buffer are accepted. + * + * Note: we do not support no-encryption modes (MAC only). + * + * TODO: implement GCM support + * + * + * Misc: + * ----- + * + * 'max_frag_len' is the maximum plaintext size for an outgoing record. + * By default, it is set to the maximum value that fits in the provided + * buffers, in the following list: 512, 1024, 2048, 4096, 16384. The + * caller may change it if needed, but the new value MUST still fit in + * the buffers, and it MUST be one of the list above for compatibility + * with the Maximum Fragment Length extension. + * + * For incoming records, only the total buffer length and current + * encryption mode impact the maximum length for incoming records. The + * 'max_frag_len' value is still adjusted so that records up to that + * length can be both received and sent. + * + * + * Offsets and lengths: + * -------------------- + * + * When sending fragments with TLS-1.1+, the maximum overhead is: + * 5 bytes for the record header + * 16 bytes for the explicit IV + * 48 bytes for the MAC (HMAC/SHA-384) + * 16 bytes for the padding (AES) + * so a total of 85 extra bytes. Note that we support block cipher sizes + * up to 16 bytes (AES) and HMAC output sizes up to 48 bytes (SHA-384). + * + * With TLS-1.0 and CBC mode, we apply a 1/n-1 split, for a maximum + * overhead of: + * 5 bytes for the first record header + * 32 bytes for the first record payload (AES-CBC + HMAC/SHA-1) + * 5 bytes for the second record header + * 20 bytes for the MAC (HMAC/SHA-1) + * 16 bytes for the padding (AES) + * -1 byte to account for the payload byte in the first record + * so a total of 77 extra bytes at most, less than the 85 bytes above. + * Note that with TLS-1.0, the MAC is HMAC with either MD5 or SHA-1, but + * no other hash function. + * + * The implementation does not try to send larger records when the current + * encryption mode has less overhead. + * + * Maximum input record overhead is: + * 5 bytes for the record header + * 16 bytes for the explicit IV (TLS-1.1+) + * 48 bytes for the MAC (HMAC/SHA-384) + * 256 bytes for the padding + * so a total of 325 extra bytes. + * + * When receiving the next record header, it is written into the buffer + * bytes 0 to 4 (inclusive). Record data is always written into buf[] + * starting at offset 5. When encryption is active, the plaintext data + * may start at a larger offset (e.g. because of an explicit IV). + */ + +#define MAX_OUT_OVERHEAD 85 +#define MAX_IN_OVERHEAD 325 + +/* see inner.h */ +void +br_ssl_engine_fail(br_ssl_engine_context *rc, int err) +{ + if (rc->iomode != BR_IO_FAILED) { + rc->iomode = BR_IO_FAILED; + rc->err = err; + } +} + +/* + * Adjust registers for a new incoming record. + */ +static void +make_ready_in(br_ssl_engine_context *rc) +{ + rc->ixa = rc->ixb = 0; + rc->ixc = 5; + if (rc->iomode == BR_IO_IN) { + rc->iomode = BR_IO_INOUT; + } +} + +/* + * Adjust registers for a new outgoing record. + */ +static void +make_ready_out(br_ssl_engine_context *rc) +{ + size_t a, b; + + a = 5; + b = rc->obuf_len - a; + rc->out.vtable->max_plaintext(&rc->out.vtable, &a, &b); + if ((b - a) > rc->max_frag_len) { + b = a + rc->max_frag_len; + } + rc->oxa = a; + rc->oxb = b; + rc->oxc = a; + if (rc->iomode == BR_IO_OUT) { + rc->iomode = BR_IO_INOUT; + } +} + +/* see inner.h */ +void +br_ssl_engine_new_max_frag_len(br_ssl_engine_context *rc, unsigned max_frag_len) +{ + size_t nxb; + + rc->max_frag_len = max_frag_len; + nxb = rc->oxc + max_frag_len; + if (rc->oxa < rc->oxb && rc->oxb > nxb && rc->oxa < nxb) { + rc->oxb = nxb; + } +} + +/* see bearssl_ssl.h */ +void +br_ssl_engine_set_buffer(br_ssl_engine_context *rc, + void *buf, size_t buf_len, int bidi) +{ + if (buf == NULL) { + br_ssl_engine_set_buffers_bidi(rc, NULL, 0, NULL, 0); + } else { + /* + * In bidirectional mode, we want to maximise input + * buffer size, since we support arbitrary fragmentation + * when sending, but the peer will not necessarily + * comply to any low fragment length (in particular if + * we are the server, because the maximum fragment + * length extension is under client control). + * + * We keep a minimum size of 512 bytes for the plaintext + * of our outgoing records. + * + * br_ssl_engine_set_buffers_bidi() will compute the maximum + * fragment length for outgoing records by using the minimum + * of allocated spaces for both input and output records, + * rounded down to a standard length. + */ + if (bidi) { + size_t w; + + if (buf_len < (512 + MAX_IN_OVERHEAD + + 512 + MAX_OUT_OVERHEAD)) + { + rc->iomode = BR_IO_FAILED; + rc->err = BR_ERR_BAD_PARAM; + return; + } else if (buf_len < (16384 + MAX_IN_OVERHEAD + + 512 + MAX_OUT_OVERHEAD)) + { + w = 512 + MAX_OUT_OVERHEAD; + } else { + w = buf_len - (16384 + MAX_IN_OVERHEAD); + } + br_ssl_engine_set_buffers_bidi(rc, + buf, buf_len - w, + (unsigned char *)buf + w, w); + } else { + br_ssl_engine_set_buffers_bidi(rc, + buf, buf_len, NULL, 0); + } + } +} + +/* see bearssl_ssl.h */ +void +br_ssl_engine_set_buffers_bidi(br_ssl_engine_context *rc, + void *ibuf, size_t ibuf_len, void *obuf, size_t obuf_len) +{ + rc->iomode = BR_IO_INOUT; + rc->incrypt = 0; + rc->err = BR_ERR_OK; + rc->version_in = 0; + rc->record_type_in = 0; + rc->version_out = 0; + rc->record_type_out = 0; + if (ibuf == NULL) { + if (rc->ibuf == NULL) { + br_ssl_engine_fail(rc, BR_ERR_BAD_PARAM); + } + } else { + unsigned u; + + rc->ibuf = ibuf; + rc->ibuf_len = ibuf_len; + if (obuf == NULL) { + obuf = ibuf; + obuf_len = ibuf_len; + } + rc->obuf = obuf; + rc->obuf_len = obuf_len; + + /* + * Compute the maximum fragment length, that fits for + * both incoming and outgoing records. This length will + * be used in fragment length negotiation, so we must + * honour it both ways. Regardless, larger incoming + * records will be accepted, as long as they fit in the + * actual buffer size. + */ + for (u = 14; u >= 9; u --) { + size_t flen; + + flen = (size_t)1 << u; + if (obuf_len >= flen + MAX_OUT_OVERHEAD + && ibuf_len >= flen + MAX_IN_OVERHEAD) + { + break; + } + } + if (u == 8) { + br_ssl_engine_fail(rc, BR_ERR_BAD_PARAM); + return; + } else if (u == 13) { + u = 12; + } + rc->max_frag_len = (size_t)1 << u; + rc->log_max_frag_len = u; + rc->peer_log_max_frag_len = 0; + } + rc->out.vtable = &br_sslrec_out_clear_vtable; + make_ready_in(rc); + make_ready_out(rc); +} + +/* + * Clear buffers in both directions. + */ +static void +engine_clearbuf(br_ssl_engine_context *rc) +{ + make_ready_in(rc); + make_ready_out(rc); +} + +/* + * Make sure the internal PRNG is initialised (but not necessarily + * seeded properly yet). + */ +static int +rng_init(br_ssl_engine_context *cc) +{ + const br_hash_class *h; + + if (cc->rng_init_done != 0) { + return 1; + } + + /* + * If using TLS-1.2, then SHA-256 or SHA-384 must be present (or + * both); we prefer SHA-256 which is faster for 32-bit systems. + * + * If using TLS-1.0 or 1.1 then SHA-1 must be present. + * + * Though HMAC_DRBG/SHA-1 is, as far as we know, as safe as + * these things can be, we still prefer the SHA-2 functions over + * SHA-1, if only for public relations (known theoretical + * weaknesses of SHA-1 with regards to collisions are mostly + * irrelevant here, but they still make people nervous). + */ + h = br_multihash_getimpl(&cc->mhash, br_sha256_ID); + if (!h) { + h = br_multihash_getimpl(&cc->mhash, br_sha384_ID); + if (!h) { + h = br_multihash_getimpl(&cc->mhash, + br_sha1_ID); + if (!h) { + br_ssl_engine_fail(cc, BR_ERR_BAD_STATE); + return 0; + } + } + } + br_hmac_drbg_init(&cc->rng, h, NULL, 0); + cc->rng_init_done = 1; + return 1; +} + +/* see inner.h */ +int +br_ssl_engine_init_rand(br_ssl_engine_context *cc) +{ + if (!rng_init(cc)) { + return 0; + } + + /* + * We always try OS/hardware seeding once. If it works, then + * we assume proper seeding. If not, then external entropy must + * have been injected; otherwise, we report an error. + */ + if (!cc->rng_os_rand_done) { + br_prng_seeder sd; + + sd = br_prng_seeder_system(NULL); + if (sd != 0 && sd(&cc->rng.vtable)) { + cc->rng_init_done = 2; + } + cc->rng_os_rand_done = 1; + } + if (cc->rng_init_done < 2) { + br_ssl_engine_fail(cc, BR_ERR_NO_RANDOM); + return 0; + } + return 1; +} + +/* see bearssl_ssl.h */ +void +br_ssl_engine_inject_entropy(br_ssl_engine_context *cc, + const void *data, size_t len) +{ + /* + * Externally provided entropy is assumed to be "good enough" + * (we cannot really test its quality) so if the RNG structure + * could be initialised at all, then we marked the RNG as + * "properly seeded". + */ + if (!rng_init(cc)) { + return; + } + br_hmac_drbg_update(&cc->rng, data, len); + cc->rng_init_done = 2; +} + +/* + * We define a few internal functions that implement the low-level engine + * API for I/O; the external API (br_ssl_engine_sendapp_buf() and similar + * functions) is built upon these function, with special processing for + * records which are not of type "application data". + * + * recvrec_buf, recvrec_ack receives bytes from transport medium + * sendrec_buf, sendrec_ack send bytes to transport medium + * recvpld_buf, recvpld_ack receives payload data from engine + * sendpld_buf, sendpld_ack send payload data to engine + */ + +static unsigned char * +recvrec_buf(const br_ssl_engine_context *rc, size_t *len) +{ + if (rc->shutdown_recv) { + *len = 0; + return NULL; + } + + /* + * Bytes from the transport can be injected only if the mode is + * compatible (in or in/out), and ixa == ixb; ixc then contains + * the number of bytes that are still expected (but it may + * exceed our buffer size). + * + * We cannot get "stuck" here (buffer is full, but still more + * data is expected) because oversized records are detected when + * their header is processed. + */ + switch (rc->iomode) { + case BR_IO_IN: + case BR_IO_INOUT: + if (rc->ixa == rc->ixb) { + size_t z; + + z = rc->ixc; + if (z > rc->ibuf_len - rc->ixa) { + z = rc->ibuf_len - rc->ixa; + } + *len = z; + return rc->ibuf + rc->ixa; + } + break; + } + *len = 0; + return NULL; +} + +static void +recvrec_ack(br_ssl_engine_context *rc, size_t len) +{ + unsigned char *pbuf; + size_t pbuf_len; + + /* + * Adjust state if necessary (for a shared input/output buffer): + * we got some incoming bytes, so we cannot (temporarily) handle + * outgoing data. + */ + if (rc->iomode == BR_IO_INOUT && rc->ibuf == rc->obuf) { + rc->iomode = BR_IO_IN; + } + + /* + * Adjust data pointers. + */ + rc->ixb = (rc->ixa += len); + rc->ixc -= len; + + /* + * If we are receiving a header and did not fully obtained it + * yet, then just wait for the next bytes. + */ + if (rc->ixa < 5) { + return; + } + + /* + * If we just obtained a full header, process it. + */ + if (rc->ixa == 5) { + unsigned version; + unsigned rlen; + + /* + * Get record type and version. We support only versions + * 3.x (if the version major number does not match, then + * we suppose that the record format is too alien for us + * to process it). + * + * Note: right now, we reject clients that try to send + * a ClientHello in a format compatible with SSL-2.0. It + * is unclear whether this will ever be supported; and + * if we want to support it, then this might be done in + * in the server-specific code, not here. + */ + rc->record_type_in = rc->ibuf[0]; + version = br_dec16be(rc->ibuf + 1); + if ((version >> 8) != 3) { + br_ssl_engine_fail(rc, BR_ERR_UNSUPPORTED_VERSION); + return; + } + + /* + * We ensure that successive records have the same + * version. The handshake code must check and adjust the + * variables when necessary to accommodate the protocol + * negotiation details. + */ + if (rc->version_in != 0 && rc->version_in != version) { + br_ssl_engine_fail(rc, BR_ERR_BAD_VERSION); + return; + } + rc->version_in = version; + + /* + * Decode record length. We must check that the length + * is valid (relatively to the current encryption mode) + * and also (if encryption is active) that the record + * will fit in our buffer. + * + * When no encryption is active, we can process records + * by chunks, and thus accept any record up to the + * maximum allowed plaintext length (16384 bytes). + */ + rlen = br_dec16be(rc->ibuf + 3); + if (rc->incrypt) { + if (!rc->in.vtable->check_length( + &rc->in.vtable, rlen)) + { + br_ssl_engine_fail(rc, BR_ERR_BAD_LENGTH); + return; + } + if (rlen > (rc->ibuf_len - 5)) { + br_ssl_engine_fail(rc, BR_ERR_TOO_LARGE); + return; + } + } else { + if (rlen > 16384) { + br_ssl_engine_fail(rc, BR_ERR_BAD_LENGTH); + return; + } + } + + /* + * If the record is completely empty then we must switch + * to a new record. Note that, in that case, we + * completely ignore the record type, which is fitting + * since we received no actual data of that type. + * + * A completely empty record is technically allowed as + * long as encryption/MAC is not active, i.e. before + * completion of the first handshake. It it still weird; + * it might conceptually be useful as a heartbeat or + * keep-alive mechanism while some lengthy operation is + * going on, e.g. interaction with a human user. + */ + if (rlen == 0) { + make_ready_in(rc); + } else { + rc->ixa = rc->ixb = 5; + rc->ixc = rlen; + } + return; + } + + /* + * If there is no active encryption, then the data can be read + * right away. Note that we do not receive bytes from the + * transport medium when we still have payload bytes to be + * acknowledged. + */ + if (!rc->incrypt) { + rc->ixa = 5; + return; + } + + /* + * Since encryption is active, we must wait for a full record + * before processing it. + */ + if (rc->ixc != 0) { + return; + } + + /* + * We got the full record. Decrypt it. + */ + pbuf_len = rc->ixa - 5; + pbuf = rc->in.vtable->decrypt(&rc->in.vtable, + rc->record_type_in, rc->version_in, rc->ibuf + 5, &pbuf_len); + if (pbuf == 0) { + br_ssl_engine_fail(rc, BR_ERR_BAD_MAC); + return; + } + rc->ixa = (size_t)(pbuf - rc->ibuf); + rc->ixb = rc->ixa + pbuf_len; + + /* + * Decryption may have yielded an empty record, in which case + * we get back to "ready" state immediately. + */ + if (rc->ixa == rc->ixb) { + make_ready_in(rc); + } +} + +/* see inner.h */ +int +br_ssl_engine_recvrec_finished(const br_ssl_engine_context *rc) +{ + switch (rc->iomode) { + case BR_IO_IN: + case BR_IO_INOUT: + return rc->ixc == 0 || rc->ixa < 5; + default: + return 1; + } +} + +static unsigned char * +recvpld_buf(const br_ssl_engine_context *rc, size_t *len) +{ + /* + * There is payload data to be read only if the mode is + * compatible, and ixa != ixb. + */ + switch (rc->iomode) { + case BR_IO_IN: + case BR_IO_INOUT: + *len = rc->ixb - rc->ixa; + return (*len == 0) ? NULL : (rc->ibuf + rc->ixa); + default: + *len = 0; + return NULL; + } +} + +static void +recvpld_ack(br_ssl_engine_context *rc, size_t len) +{ + rc->ixa += len; + + /* + * If we read all the available data, then we either expect + * the remainder of the current record (if the current record + * was not finished; this may happen when encryption is not + * active), or go to "ready" state. + */ + if (rc->ixa == rc->ixb) { + if (rc->ixc == 0) { + make_ready_in(rc); + } else { + rc->ixa = rc->ixb = 5; + } + } +} + +static unsigned char * +sendpld_buf(const br_ssl_engine_context *rc, size_t *len) +{ + /* + * Payload data can be injected only if the current mode is + * compatible, and oxa != oxb. + */ + switch (rc->iomode) { + case BR_IO_OUT: + case BR_IO_INOUT: + *len = rc->oxb - rc->oxa; + return (*len == 0) ? NULL : (rc->obuf + rc->oxa); + default: + *len = 0; + return NULL; + } +} + +/* + * If some payload bytes have been accumulated, then wrap them into + * an outgoing record. Otherwise, this function does nothing, unless + * 'force' is non-zero, in which case an empty record is assembled. + * + * The caller must take care not to invoke this function if the engine + * is not currently ready to receive payload bytes to send. + */ +static void +sendpld_flush(br_ssl_engine_context *rc, int force) +{ + size_t xlen; + unsigned char *buf; + + if (rc->oxa == rc->oxb) { + return; + } + xlen = rc->oxa - rc->oxc; + if (xlen == 0 && !force) { + return; + } + buf = rc->out.vtable->encrypt(&rc->out.vtable, + rc->record_type_out, rc->version_out, + rc->obuf + rc->oxc, &xlen); + rc->oxb = rc->oxa = (size_t)(buf - rc->obuf); + rc->oxc = rc->oxa + xlen; +} + +static void +sendpld_ack(br_ssl_engine_context *rc, size_t len) +{ + /* + * If using a shared buffer, then we may have to modify the + * current mode. + */ + if (rc->iomode == BR_IO_INOUT && rc->ibuf == rc->obuf) { + rc->iomode = BR_IO_OUT; + } + rc->oxa += len; + if (rc->oxa >= rc->oxb) { + /* + * Set oxb to one more than oxa so that sendpld_flush() + * does not mistakingly believe that a record is + * already prepared and being sent. + */ + rc->oxb = rc->oxa + 1; + sendpld_flush(rc, 0); + } +} + +static unsigned char * +sendrec_buf(const br_ssl_engine_context *rc, size_t *len) +{ + /* + * When still gathering payload bytes, oxc points to the start + * of the record data, so oxc <= oxa. However, when a full + * record has been completed, oxc points to the end of the record, + * so oxc > oxa. + */ + switch (rc->iomode) { + case BR_IO_OUT: + case BR_IO_INOUT: + if (rc->oxc > rc->oxa) { + *len = rc->oxc - rc->oxa; + return rc->obuf + rc->oxa; + } + break; + } + *len = 0; + return NULL; +} + +static void +sendrec_ack(br_ssl_engine_context *rc, size_t len) +{ + rc->oxb = (rc->oxa += len); + if (rc->oxa == rc->oxc) { + make_ready_out(rc); + } +} + +/* + * Test whether there is some buffered outgoing record that still must + * sent. + */ +static __inline int +has_rec_tosend(const br_ssl_engine_context *rc) +{ + return rc->oxa == rc->oxb && rc->oxa != rc->oxc; +} + +/* + * The "no encryption" mode has no overhead. It limits the payload size + * to the maximum size allowed by the standard (16384 bytes); the caller + * is responsible for possibly enforcing a smaller fragment length. + */ +static void +clear_max_plaintext(const br_sslrec_out_clear_context *cc, + size_t *start, size_t *end) +{ + size_t len; + + (void)cc; + len = *end - *start; + if (len > 16384) { + *end = *start + 16384; + } +} + +/* + * In "no encryption" mode, encryption is trivial (a no-operation) so + * we just have to encode the header. + */ +static unsigned char * +clear_encrypt(br_sslrec_out_clear_context *cc, + int record_type, unsigned version, void *data, size_t *data_len) +{ + unsigned char *buf; + + (void)cc; + buf = (unsigned char *)data - 5; + buf[0] = record_type; + br_enc16be(buf + 1, version); + br_enc16be(buf + 3, *data_len); + *data_len += 5; + return buf; +} + +/* see bearssl_ssl.h */ +const br_sslrec_out_class br_sslrec_out_clear_vtable = { + sizeof(br_sslrec_out_clear_context), + (void (*)(const br_sslrec_out_class *const *, size_t *, size_t *)) + &clear_max_plaintext, + (unsigned char *(*)(const br_sslrec_out_class **, + int, unsigned, void *, size_t *)) + &clear_encrypt +}; + +/* ==================================================================== */ +/* + * In this part of the file, we handle the various record types, and + * communications with the handshake processor. + */ + +/* + * IMPLEMENTATION NOTES + * ==================== + * + * The handshake processor is written in T0 and runs as a coroutine. + * It receives the contents of all records except application data, and + * is responsible for producing the contents of all records except + * application data. + * + * A state flag is maintained, which specifies whether application data + * is acceptable or not. When it is set: + * + * -- Application data can be injected as payload data (provided that + * the output buffer is ready for that). + * + * -- Incoming application data records are accepted, and yield data + * that the caller may retrieve. + * + * When the flag is cleared, application data is not accepted from the + * application, and incoming application data records trigger an error. + * + * + * Records of type handshake, alert or change-cipher-spec are handled + * by the handshake processor. The handshake processor is written in T0 + * and runs as a coroutine; it gets invoked whenever one of the following + * situations is reached: + * + * -- An incoming record has type handshake, alert or change-cipher-spec, + * and yields data that can be read (zero-length records are thus + * ignored). + * + * -- An outgoing record has just finished being sent, and the "application + * data" flag is cleared. + * + * -- The caller wishes to perform a close (call to br_ssl_engine_close()). + * + * -- The caller wishes to perform a renegotiation (call to + * br_ssl_engine_renegotiate()). + * + * Whenever the handshake processor is entered, access to the payload + * buffers is provided, along with some information about explicit + * closures or renegotiations. + */ + +/* see bearssl_ssl.h */ +void +br_ssl_engine_set_suites(br_ssl_engine_context *cc, + const uint16_t *suites, size_t suites_num) +{ + if ((suites_num * sizeof *suites) > sizeof cc->suites_buf) { + br_ssl_engine_fail(cc, BR_ERR_BAD_PARAM); + return; + } + memcpy(cc->suites_buf, suites, suites_num * sizeof *suites); + cc->suites_num = suites_num; +} + +/* + * Give control to handshake processor. 'action' is 1 for a close, + * 2 for a renegotiation, or 0 for a jump due to I/O completion. + */ +static void +jump_handshake(br_ssl_engine_context *cc, int action) +{ + /* + * We use a loop because the handshake processor actions may + * allow for more actions; namely, if the processor reads all + * input data, then it may allow for output data to be produced, + * in case of a shared in/out buffer. + */ + for (;;) { + size_t hlen_in, hlen_out; + + /* + * Get input buffer. We do not want to provide + * application data to the handshake processor (we could + * get called with an explicit close or renegotiation + * while there is application data ready to be read). + */ + cc->hbuf_in = recvpld_buf(cc, &hlen_in); + if (cc->hbuf_in != NULL + && cc->record_type_in == BR_SSL_APPLICATION_DATA) + { + hlen_in = 0; + } + + /* + * Get output buffer. The handshake processor never + * leaves an unfinished outgoing record, so if there is + * buffered output, then it MUST be some application + * data, so the processor cannot write to it. + */ + cc->saved_hbuf_out = cc->hbuf_out = sendpld_buf(cc, &hlen_out); + if (cc->hbuf_out != NULL && br_ssl_engine_has_pld_to_send(cc)) { + hlen_out = 0; + } + + /* + * Note: hlen_in and hlen_out can be both non-zero only if + * the input and output buffers are disjoint. Thus, we can + * offer both buffers to the handshake code. + */ + + cc->hlen_in = hlen_in; + cc->hlen_out = hlen_out; + cc->action = action; + cc->hsrun(&cc->cpu); + if (br_ssl_engine_closed(cc)) { + return; + } + if (cc->hbuf_out != cc->saved_hbuf_out) { + sendpld_ack(cc, cc->hbuf_out - cc->saved_hbuf_out); + } + if (hlen_in != cc->hlen_in) { + recvpld_ack(cc, hlen_in - cc->hlen_in); + if (cc->hlen_in == 0) { + /* + * We read all data bytes, which may have + * released the output buffer in case it + * is shared with the input buffer, and + * the handshake code might be waiting for + * that. + */ + action = 0; + continue; + } + } + break; + } +} + +/* see inner.h */ +void +br_ssl_engine_flush_record(br_ssl_engine_context *cc) +{ + if (cc->hbuf_out != cc->saved_hbuf_out) { + sendpld_ack(cc, cc->hbuf_out - cc->saved_hbuf_out); + } + if (br_ssl_engine_has_pld_to_send(cc)) { + sendpld_flush(cc, 0); + } + cc->saved_hbuf_out = cc->hbuf_out = sendpld_buf(cc, &cc->hlen_out); +} + +/* see bearssl_ssl.h */ +unsigned char * +br_ssl_engine_sendapp_buf(const br_ssl_engine_context *cc, size_t *len) +{ + if (!(cc->application_data & 1)) { + *len = 0; + return NULL; + } + return sendpld_buf(cc, len); +} + +/* see bearssl_ssl.h */ +void +br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len) +{ + sendpld_ack(cc, len); +} + +/* see bearssl_ssl.h */ +unsigned char * +br_ssl_engine_recvapp_buf(const br_ssl_engine_context *cc, size_t *len) +{ + if (!(cc->application_data & 1) + || cc->record_type_in != BR_SSL_APPLICATION_DATA) + { + *len = 0; + return NULL; + } + return recvpld_buf(cc, len); +} + +/* see bearssl_ssl.h */ +void +br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len) +{ + recvpld_ack(cc, len); +} + +/* see bearssl_ssl.h */ +unsigned char * +br_ssl_engine_sendrec_buf(const br_ssl_engine_context *cc, size_t *len) +{ + return sendrec_buf(cc, len); +} + +/* see bearssl_ssl.h */ +void +br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len) +{ + sendrec_ack(cc, len); + if (len != 0 && !has_rec_tosend(cc) + && (cc->record_type_out != BR_SSL_APPLICATION_DATA + || (cc->application_data & 1) == 0)) + { + jump_handshake(cc, 0); + } +} + +/* see bearssl_ssl.h */ +unsigned char * +br_ssl_engine_recvrec_buf(const br_ssl_engine_context *cc, size_t *len) +{ + return recvrec_buf(cc, len); +} + +/* see bearssl_ssl.h */ +void +br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len) +{ + unsigned char *buf; + + recvrec_ack(cc, len); + if (br_ssl_engine_closed(cc)) { + return; + } + + /* + * We just received some bytes from the peer. This may have + * yielded some payload bytes, in which case we must process + * them according to the record type. + */ + buf = recvpld_buf(cc, &len); + if (buf != NULL) { + switch (cc->record_type_in) { + case BR_SSL_CHANGE_CIPHER_SPEC: + case BR_SSL_ALERT: + case BR_SSL_HANDSHAKE: + jump_handshake(cc, 0); + break; + case BR_SSL_APPLICATION_DATA: + if (cc->application_data == 1) { + break; + } + + /* + * If we are currently closing, and waiting for + * a close_notify from the peer, then incoming + * application data should be discarded. + */ + if (cc->application_data == 2) { + recvpld_ack(cc, len); + break; + } + + /* Fall through */ + default: + br_ssl_engine_fail(cc, BR_ERR_UNEXPECTED); + break; + } + } +} + +/* see bearssl_ssl.h */ +void +br_ssl_engine_close(br_ssl_engine_context *cc) +{ + if (!br_ssl_engine_closed(cc)) { + /* + * If we are not already closed, then we need to + * initiate the closure. Once closing, any incoming + * application data is discarded; we should also discard + * application data which is already there but has not + * been acknowledged by the application yet (this mimics + * usual semantics on BSD sockets: you cannot read() + * once you called close(), even if there was some + * unread data already buffered). + */ + size_t len; + + if (br_ssl_engine_recvapp_buf(cc, &len) != NULL && len != 0) { + br_ssl_engine_recvapp_ack(cc, len); + } + jump_handshake(cc, 1); + } +} + +/* see bearssl_ssl.h */ +int +br_ssl_engine_renegotiate(br_ssl_engine_context *cc) +{ + size_t len; + + if (br_ssl_engine_closed(cc) || cc->reneg == 1 + || (cc->flags & BR_OPT_NO_RENEGOTIATION) != 0 + || br_ssl_engine_recvapp_buf(cc, &len) != NULL) + { + return 0; + } + jump_handshake(cc, 2); + return 1; +} + +/* see bearssl.h */ +unsigned +br_ssl_engine_current_state(const br_ssl_engine_context *cc) +{ + unsigned s; + size_t len; + + if (br_ssl_engine_closed(cc)) { + return BR_SSL_CLOSED; + } + + s = 0; + if (br_ssl_engine_sendrec_buf(cc, &len) != NULL) { + s |= BR_SSL_SENDREC; + } + if (br_ssl_engine_recvrec_buf(cc, &len) != NULL) { + s |= BR_SSL_RECVREC; + } + if (br_ssl_engine_sendapp_buf(cc, &len) != NULL) { + s |= BR_SSL_SENDAPP; + } + if (br_ssl_engine_recvapp_buf(cc, &len) != NULL) { + s |= BR_SSL_RECVAPP; + } + return s; +} + +/* see bearssl_ssl.h */ +void +br_ssl_engine_flush(br_ssl_engine_context *cc, int force) +{ + if (!br_ssl_engine_closed(cc) && (cc->application_data & 1) != 0) { + sendpld_flush(cc, force); + } +} + +/* see inner.h */ +void +br_ssl_engine_hs_reset(br_ssl_engine_context *cc, + void (*hsinit)(void *), void (*hsrun)(void *)) +{ + engine_clearbuf(cc); + cc->cpu.dp = cc->dp_stack; + cc->cpu.rp = cc->rp_stack; + hsinit(&cc->cpu); + cc->hsrun = hsrun; + cc->shutdown_recv = 0; + cc->application_data = 0; + cc->alert = 0; + jump_handshake(cc, 0); +} + +/* see inner.h */ +br_tls_prf_impl +br_ssl_engine_get_PRF(br_ssl_engine_context *cc, int prf_id) +{ + if (cc->session.version >= BR_TLS12) { + if (prf_id == br_sha384_ID) { + return cc->prf_sha384; + } else { + return cc->prf_sha256; + } + } else { + return cc->prf10; + } +} + +/* see inner.h */ +void +br_ssl_engine_compute_master(br_ssl_engine_context *cc, + int prf_id, const void *pms, size_t pms_len) +{ + br_tls_prf_impl iprf; + br_tls_prf_seed_chunk seed[2] = { + { cc->client_random, sizeof cc->client_random }, + { cc->server_random, sizeof cc->server_random } + }; + + iprf = br_ssl_engine_get_PRF(cc, prf_id); + iprf(cc->session.master_secret, sizeof cc->session.master_secret, + pms, pms_len, "master secret", 2, seed); +} + +/* + * Compute key block. + */ +static void +compute_key_block(br_ssl_engine_context *cc, int prf_id, + size_t half_len, unsigned char *kb) +{ + br_tls_prf_impl iprf; + br_tls_prf_seed_chunk seed[2] = { + { cc->server_random, sizeof cc->server_random }, + { cc->client_random, sizeof cc->client_random } + }; + + iprf = br_ssl_engine_get_PRF(cc, prf_id); + iprf(kb, half_len << 1, + cc->session.master_secret, sizeof cc->session.master_secret, + "key expansion", 2, seed); +} + +/* see inner.h */ +void +br_ssl_engine_switch_cbc_in(br_ssl_engine_context *cc, + int is_client, int prf_id, int mac_id, + const br_block_cbcdec_class *bc_impl, size_t cipher_key_len) +{ + unsigned char kb[192]; + unsigned char *cipher_key, *mac_key, *iv; + const br_hash_class *imh; + size_t mac_key_len, mac_out_len, iv_len; + + imh = br_ssl_engine_get_hash(cc, mac_id); + mac_out_len = (imh->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; + mac_key_len = mac_out_len; + + /* + * TLS 1.1+ uses per-record explicit IV, so no IV to generate here. + */ + if (cc->session.version >= BR_TLS11) { + iv_len = 0; + } else { + iv_len = bc_impl->block_size; + } + compute_key_block(cc, prf_id, + mac_key_len + cipher_key_len + iv_len, kb); + if (is_client) { + mac_key = &kb[mac_key_len]; + cipher_key = &kb[(mac_key_len << 1) + cipher_key_len]; + iv = &kb[((mac_key_len + cipher_key_len) << 1) + iv_len]; + } else { + mac_key = &kb[0]; + cipher_key = &kb[mac_key_len << 1]; + iv = &kb[(mac_key_len + cipher_key_len) << 1]; + } + if (iv_len == 0) { + iv = NULL; + } + cc->icbc_in->init(&cc->in.cbc.vtable, + bc_impl, cipher_key, cipher_key_len, + imh, mac_key, mac_key_len, mac_out_len, iv); + cc->incrypt = 1; +} + +/* see inner.h */ +void +br_ssl_engine_switch_cbc_out(br_ssl_engine_context *cc, + int is_client, int prf_id, int mac_id, + const br_block_cbcenc_class *bc_impl, size_t cipher_key_len) +{ + unsigned char kb[192]; + unsigned char *cipher_key, *mac_key, *iv; + const br_hash_class *imh; + size_t mac_key_len, mac_out_len, iv_len; + + imh = br_ssl_engine_get_hash(cc, mac_id); + mac_out_len = (imh->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; + mac_key_len = mac_out_len; + + /* + * TLS 1.1+ uses per-record explicit IV, so no IV to generate here. + */ + if (cc->session.version >= BR_TLS11) { + iv_len = 0; + } else { + iv_len = bc_impl->block_size; + } + compute_key_block(cc, prf_id, + mac_key_len + cipher_key_len + iv_len, kb); + if (is_client) { + mac_key = &kb[0]; + cipher_key = &kb[mac_key_len << 1]; + iv = &kb[(mac_key_len + cipher_key_len) << 1]; + } else { + mac_key = &kb[mac_key_len]; + cipher_key = &kb[(mac_key_len << 1) + cipher_key_len]; + iv = &kb[((mac_key_len + cipher_key_len) << 1) + iv_len]; + } + if (iv_len == 0) { + iv = NULL; + } + cc->icbc_out->init(&cc->out.cbc.vtable, + bc_impl, cipher_key, cipher_key_len, + imh, mac_key, mac_key_len, mac_out_len, iv); +} + +/* see inner.h */ +void +br_ssl_engine_switch_gcm_in(br_ssl_engine_context *cc, + int is_client, int prf_id, + const br_block_ctr_class *bc_impl, size_t cipher_key_len) +{ + unsigned char kb[72]; + unsigned char *cipher_key, *iv; + + compute_key_block(cc, prf_id, cipher_key_len + 4, kb); + if (is_client) { + cipher_key = &kb[cipher_key_len]; + iv = &kb[(cipher_key_len << 1) + 4]; + } else { + cipher_key = &kb[0]; + iv = &kb[cipher_key_len << 1]; + } + cc->igcm_in->init(&cc->in.gcm.vtable.in, + bc_impl, cipher_key, cipher_key_len, cc->ighash, iv); + cc->incrypt = 1; +} + +/* see inner.h */ +void +br_ssl_engine_switch_gcm_out(br_ssl_engine_context *cc, + int is_client, int prf_id, + const br_block_ctr_class *bc_impl, size_t cipher_key_len) +{ + unsigned char kb[72]; + unsigned char *cipher_key, *iv; + + compute_key_block(cc, prf_id, cipher_key_len + 4, kb); + if (is_client) { + cipher_key = &kb[0]; + iv = &kb[cipher_key_len << 1]; + } else { + cipher_key = &kb[cipher_key_len]; + iv = &kb[(cipher_key_len << 1) + 4]; + } + cc->igcm_out->init(&cc->out.gcm.vtable.out, + bc_impl, cipher_key, cipher_key_len, cc->ighash, iv); +} + +/* see inner.h */ +void +br_ssl_engine_switch_chapol_in(br_ssl_engine_context *cc, + int is_client, int prf_id) +{ + unsigned char kb[88]; + unsigned char *cipher_key, *iv; + + compute_key_block(cc, prf_id, 44, kb); + if (is_client) { + cipher_key = &kb[32]; + iv = &kb[76]; + } else { + cipher_key = &kb[0]; + iv = &kb[64]; + } + cc->ichapol_in->init(&cc->in.chapol.vtable.in, + cc->ichacha, cc->ipoly, cipher_key, iv); + cc->incrypt = 1; +} + +/* see inner.h */ +void +br_ssl_engine_switch_chapol_out(br_ssl_engine_context *cc, + int is_client, int prf_id) +{ + unsigned char kb[88]; + unsigned char *cipher_key, *iv; + + compute_key_block(cc, prf_id, 44, kb); + if (is_client) { + cipher_key = &kb[0]; + iv = &kb[64]; + } else { + cipher_key = &kb[32]; + iv = &kb[76]; + } + cc->ichapol_out->init(&cc->out.chapol.vtable.out, + cc->ichacha, cc->ipoly, cipher_key, iv); +} + +/* see inner.h */ +void +br_ssl_engine_switch_ccm_in(br_ssl_engine_context *cc, + int is_client, int prf_id, + const br_block_ctrcbc_class *bc_impl, + size_t cipher_key_len, size_t tag_len) +{ + unsigned char kb[72]; + unsigned char *cipher_key, *iv; + + compute_key_block(cc, prf_id, cipher_key_len + 4, kb); + if (is_client) { + cipher_key = &kb[cipher_key_len]; + iv = &kb[(cipher_key_len << 1) + 4]; + } else { + cipher_key = &kb[0]; + iv = &kb[cipher_key_len << 1]; + } + cc->iccm_in->init(&cc->in.ccm.vtable.in, + bc_impl, cipher_key, cipher_key_len, iv, tag_len); + cc->incrypt = 1; +} + +/* see inner.h */ +void +br_ssl_engine_switch_ccm_out(br_ssl_engine_context *cc, + int is_client, int prf_id, + const br_block_ctrcbc_class *bc_impl, + size_t cipher_key_len, size_t tag_len) +{ + unsigned char kb[72]; + unsigned char *cipher_key, *iv; + + compute_key_block(cc, prf_id, cipher_key_len + 4, kb); + if (is_client) { + cipher_key = &kb[0]; + iv = &kb[cipher_key_len << 1]; + } else { + cipher_key = &kb[cipher_key_len]; + iv = &kb[(cipher_key_len << 1) + 4]; + } + cc->iccm_out->init(&cc->out.ccm.vtable.out, + bc_impl, cipher_key, cipher_key_len, iv, tag_len); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_aescbc.c b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_aescbc.c new file mode 100644 index 0000000..8c5cdb5 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_aescbc.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_engine_set_default_aes_cbc(br_ssl_engine_context *cc) +{ +#if BR_AES_X86NI || BR_POWER8 + const br_block_cbcenc_class *ienc; + const br_block_cbcdec_class *idec; +#endif + + br_ssl_engine_set_cbc(cc, + &br_sslrec_in_cbc_vtable, + &br_sslrec_out_cbc_vtable); +#if BR_AES_X86NI + ienc = br_aes_x86ni_cbcenc_get_vtable(); + idec = br_aes_x86ni_cbcdec_get_vtable(); + if (ienc != NULL && idec != NULL) { + br_ssl_engine_set_aes_cbc(cc, ienc, idec); + return; + } +#endif +#if BR_POWER8 + ienc = br_aes_pwr8_cbcenc_get_vtable(); + idec = br_aes_pwr8_cbcdec_get_vtable(); + if (ienc != NULL && idec != NULL) { + br_ssl_engine_set_aes_cbc(cc, ienc, idec); + return; + } +#endif +#if BR_64 + br_ssl_engine_set_aes_cbc(cc, + &br_aes_ct64_cbcenc_vtable, + &br_aes_ct64_cbcdec_vtable); +#else + br_ssl_engine_set_aes_cbc(cc, + &br_aes_ct_cbcenc_vtable, + &br_aes_ct_cbcdec_vtable); +#endif +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_aesccm.c b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_aesccm.c new file mode 100644 index 0000000..15c0a78 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_aesccm.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_engine_set_default_aes_ccm(br_ssl_engine_context *cc) +{ +#if BR_AES_X86NI || BR_POWER8 + const br_block_ctrcbc_class *ictrcbc; +#endif + + br_ssl_engine_set_ccm(cc, + &br_sslrec_in_ccm_vtable, + &br_sslrec_out_ccm_vtable); +#if BR_AES_X86NI + ictrcbc = br_aes_x86ni_ctrcbc_get_vtable(); + if (ictrcbc != NULL) { + br_ssl_engine_set_aes_ctrcbc(cc, ictrcbc); + } else { +#if BR_64 + br_ssl_engine_set_aes_ctrcbc(cc, &br_aes_ct64_ctrcbc_vtable); +#else + br_ssl_engine_set_aes_ctrcbc(cc, &br_aes_ct_ctrcbc_vtable); +#endif + } +#elif BR_POWER8 + ictrcbc = br_aes_pwr8_ctrcbc_get_vtable(); + if (ictrcbc != NULL) { + br_ssl_engine_set_aes_ctrcbc(cc, ictrcbc); + } else { +#if BR_64 + br_ssl_engine_set_aes_ctrcbc(cc, &br_aes_ct64_ctrcbc_vtable); +#else + br_ssl_engine_set_aes_ctrcbc(cc, &br_aes_ct_ctrcbc_vtable); +#endif + } +#else +#if BR_64 + br_ssl_engine_set_aes_ctrcbc(cc, &br_aes_ct64_ctrcbc_vtable); +#else + br_ssl_engine_set_aes_ctrcbc(cc, &br_aes_ct_ctrcbc_vtable); +#endif +#endif +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_aesgcm.c b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_aesgcm.c new file mode 100644 index 0000000..c44a707 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_aesgcm.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_engine_set_default_aes_gcm(br_ssl_engine_context *cc) +{ +#if BR_AES_X86NI || BR_POWER8 + const br_block_ctr_class *ictr; + br_ghash ighash; +#endif + + br_ssl_engine_set_gcm(cc, + &br_sslrec_in_gcm_vtable, + &br_sslrec_out_gcm_vtable); +#if BR_AES_X86NI + ictr = br_aes_x86ni_ctr_get_vtable(); + if (ictr != NULL) { + br_ssl_engine_set_aes_ctr(cc, ictr); + } else { +#if BR_64 + br_ssl_engine_set_aes_ctr(cc, &br_aes_ct64_ctr_vtable); +#else + br_ssl_engine_set_aes_ctr(cc, &br_aes_ct_ctr_vtable); +#endif + } +#elif BR_POWER8 + ictr = br_aes_pwr8_ctr_get_vtable(); + if (ictr != NULL) { + br_ssl_engine_set_aes_ctr(cc, ictr); + } else { +#if BR_64 + br_ssl_engine_set_aes_ctr(cc, &br_aes_ct64_ctr_vtable); +#else + br_ssl_engine_set_aes_ctr(cc, &br_aes_ct_ctr_vtable); +#endif + } +#else +#if BR_64 + br_ssl_engine_set_aes_ctr(cc, &br_aes_ct64_ctr_vtable); +#else + br_ssl_engine_set_aes_ctr(cc, &br_aes_ct_ctr_vtable); +#endif +#endif +#if BR_AES_X86NI + ighash = br_ghash_pclmul_get(); + if (ighash != 0) { + br_ssl_engine_set_ghash(cc, ighash); + return; + } +#endif +#if BR_POWER8 + ighash = br_ghash_pwr8_get(); + if (ighash != 0) { + br_ssl_engine_set_ghash(cc, ighash); + return; + } +#endif +#if BR_LOMUL + br_ssl_engine_set_ghash(cc, &br_ghash_ctmul32); +#elif BR_64 + br_ssl_engine_set_ghash(cc, &br_ghash_ctmul64); +#else + br_ssl_engine_set_ghash(cc, &br_ghash_ctmul); +#endif +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_chapol.c b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_chapol.c new file mode 100644 index 0000000..47a0c98 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_chapol.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_engine_set_default_chapol(br_ssl_engine_context *cc) +{ +#if BR_INT128 || BR_UMUL128 + br_poly1305_run bp; +#endif +#if BR_SSE2 + br_chacha20_run bc; +#endif + + br_ssl_engine_set_chapol(cc, + &br_sslrec_in_chapol_vtable, + &br_sslrec_out_chapol_vtable); +#if BR_SSE2 + bc = br_chacha20_sse2_get(); + if (bc) { + br_ssl_engine_set_chacha20(cc, bc); + } else { +#endif + br_ssl_engine_set_chacha20(cc, &br_chacha20_ct_run); +#if BR_SSE2 + } +#endif +#if BR_INT128 || BR_UMUL128 + bp = br_poly1305_ctmulq_get(); + if (bp) { + br_ssl_engine_set_poly1305(cc, bp); + } else { +#endif +#if BR_LOMUL + br_ssl_engine_set_poly1305(cc, &br_poly1305_ctmul32_run); +#else + br_ssl_engine_set_poly1305(cc, &br_poly1305_ctmul_run); +#endif +#if BR_INT128 || BR_UMUL128 + } +#endif +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_descbc.c b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_descbc.c new file mode 100644 index 0000000..0253cb2 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_descbc.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc) +{ + br_ssl_engine_set_cbc(cc, + &br_sslrec_in_cbc_vtable, + &br_sslrec_out_cbc_vtable); + br_ssl_engine_set_des_cbc(cc, + &br_des_ct_cbcenc_vtable, + &br_des_ct_cbcdec_vtable); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_ec.c b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_ec.c new file mode 100644 index 0000000..0213ae6 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_ec.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_engine_set_default_ec(br_ssl_engine_context *cc) +{ +#if BR_LOMUL + br_ssl_engine_set_ec(cc, &br_ec_all_m15); +#else + br_ssl_engine_set_ec(cc, &br_ec_all_m31); +#endif +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_ecdsa.c b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_ecdsa.c new file mode 100644 index 0000000..1304002 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_ecdsa.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_engine_set_default_ecdsa(br_ssl_engine_context *cc) +{ +#if BR_LOMUL + br_ssl_engine_set_ec(cc, &br_ec_all_m15); + br_ssl_engine_set_ecdsa(cc, &br_ecdsa_i15_vrfy_asn1); +#else + br_ssl_engine_set_ec(cc, &br_ec_all_m31); + br_ssl_engine_set_ecdsa(cc, &br_ecdsa_i31_vrfy_asn1); +#endif +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_rsavrfy.c b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_rsavrfy.c new file mode 100644 index 0000000..ad0628a --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_engine_default_rsavrfy.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_engine_set_default_rsavrfy(br_ssl_engine_context *cc) +{ + br_ssl_engine_set_rsavrfy(cc, br_rsa_pkcs1_vrfy_get_default()); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_hashes.c b/BearSSL-OG/libbearssl/src/ssl/ssl_hashes.c new file mode 100644 index 0000000..e10a980 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_hashes.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +int +br_ssl_choose_hash(unsigned bf) +{ + static const unsigned char pref[] = { + br_sha256_ID, br_sha384_ID, br_sha512_ID, + br_sha224_ID, br_sha1_ID + }; + size_t u; + + for (u = 0; u < sizeof pref; u ++) { + int x; + + x = pref[u]; + if ((bf >> x) & 1) { + return x; + } + } + return 0; +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_hs_client.c b/BearSSL-OG/libbearssl/src/ssl/ssl_hs_client.c new file mode 100644 index 0000000..3fc96d0 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_hs_client.c @@ -0,0 +1,1967 @@ +/* Automatically generated code; do not modify directly. */ + +#include +#include + +typedef struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; +} t0_context; + +static uint32_t +t0_parse7E_unsigned(const unsigned char **p) +{ + uint32_t x; + + x = 0; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + return x; + } + } +} + +static int32_t +t0_parse7E_signed(const unsigned char **p) +{ + int neg; + uint32_t x; + + neg = ((**p) >> 6) & 1; + x = (uint32_t)-neg; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + if (neg) { + return -(int32_t)~x - 1; + } else { + return (int32_t)x; + } + } + } +} + +#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) +#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) +#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) +#define T0_INT1(x) T0_FBYTE(x, 0) +#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) + +/* static const unsigned char t0_datablock[]; */ + + +void br_ssl_hs_client_init_main(void *t0ctx); + +void br_ssl_hs_client_run(void *t0ctx); + + + +#include +#include + +#include "inner.h" + +/* + * This macro evaluates to a pointer to the current engine context. + */ +#define ENG ((br_ssl_engine_context *)(void *)((unsigned char *)t0ctx - offsetof(br_ssl_engine_context, cpu))) + + + + + +/* + * This macro evaluates to a pointer to the client context, under that + * specific name. It must be noted that since the engine context is the + * first field of the br_ssl_client_context structure ('eng'), then + * pointers values of both types are interchangeable, modulo an + * appropriate cast. This also means that "addresses" computed as offsets + * within the structure work for both kinds of context. + */ +#define CTX ((br_ssl_client_context *)ENG) + +/* + * Generate the pre-master secret for RSA key exchange, and encrypt it + * with the server's public key. Returned value is either the encrypted + * data length (in bytes), or -x on error, with 'x' being an error code. + * + * This code assumes that the public key has been already verified (it + * was properly obtained by the X.509 engine, and it has the right type, + * i.e. it is of type RSA and suitable for encryption). + */ +static int +make_pms_rsa(br_ssl_client_context *ctx, int prf_id) +{ + const br_x509_class **xc; + const br_x509_pkey *pk; + const unsigned char *n; + unsigned char *pms; + size_t nlen, u; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + + /* + * Compute actual RSA key length, in case there are leading zeros. + */ + n = pk->key.rsa.n; + nlen = pk->key.rsa.nlen; + while (nlen > 0 && *n == 0) { + n ++; + nlen --; + } + + /* + * We need at least 59 bytes (48 bytes for pre-master secret, and + * 11 bytes for the PKCS#1 type 2 padding). Note that the X.509 + * minimal engine normally blocks RSA keys shorter than 128 bytes, + * so this is mostly for public keys provided explicitly by the + * caller. + */ + if (nlen < 59) { + return -BR_ERR_X509_WEAK_PUBLIC_KEY; + } + if (nlen > sizeof ctx->eng.pad) { + return -BR_ERR_LIMIT_EXCEEDED; + } + + /* + * Make PMS. + */ + pms = ctx->eng.pad + nlen - 48; + br_enc16be(pms, ctx->eng.version_max); + br_hmac_drbg_generate(&ctx->eng.rng, pms + 2, 46); + br_ssl_engine_compute_master(&ctx->eng, prf_id, pms, 48); + + /* + * Apply PKCS#1 type 2 padding. + */ + ctx->eng.pad[0] = 0x00; + ctx->eng.pad[1] = 0x02; + ctx->eng.pad[nlen - 49] = 0x00; + br_hmac_drbg_generate(&ctx->eng.rng, ctx->eng.pad + 2, nlen - 51); + for (u = 2; u < nlen - 49; u ++) { + while (ctx->eng.pad[u] == 0) { + br_hmac_drbg_generate(&ctx->eng.rng, + &ctx->eng.pad[u], 1); + } + } + + /* + * Compute RSA encryption. + */ + if (!ctx->irsapub(ctx->eng.pad, nlen, &pk->key.rsa)) { + return -BR_ERR_LIMIT_EXCEEDED; + } + return (int)nlen; +} + +/* + * OID for hash functions in RSA signatures. + */ +static const unsigned char *HASH_OID[] = { + BR_HASH_OID_SHA1, + BR_HASH_OID_SHA224, + BR_HASH_OID_SHA256, + BR_HASH_OID_SHA384, + BR_HASH_OID_SHA512 +}; + +/* + * Check the RSA signature on the ServerKeyExchange message. + * + * hash hash function ID (2 to 6), or 0 for MD5+SHA-1 (with RSA only) + * use_rsa non-zero for RSA signature, zero for ECDSA + * sig_len signature length (in bytes); signature value is in the pad + * + * Returned value is 0 on success, or an error code. + */ +static int +verify_SKE_sig(br_ssl_client_context *ctx, + int hash, int use_rsa, size_t sig_len) +{ + const br_x509_class **xc; + const br_x509_pkey *pk; + br_multihash_context mhc; + unsigned char hv[64], head[4]; + size_t hv_len; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + br_multihash_zero(&mhc); + br_multihash_copyimpl(&mhc, &ctx->eng.mhash); + br_multihash_init(&mhc); + br_multihash_update(&mhc, + ctx->eng.client_random, sizeof ctx->eng.client_random); + br_multihash_update(&mhc, + ctx->eng.server_random, sizeof ctx->eng.server_random); + head[0] = 3; + head[1] = 0; + head[2] = ctx->eng.ecdhe_curve; + head[3] = ctx->eng.ecdhe_point_len; + br_multihash_update(&mhc, head, sizeof head); + br_multihash_update(&mhc, + ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len); + if (hash) { + hv_len = br_multihash_out(&mhc, hash, hv); + if (hv_len == 0) { + return BR_ERR_INVALID_ALGORITHM; + } + } else { + if (!br_multihash_out(&mhc, br_md5_ID, hv) + || !br_multihash_out(&mhc, br_sha1_ID, hv + 16)) + { + return BR_ERR_INVALID_ALGORITHM; + } + hv_len = 36; + } + if (use_rsa) { + unsigned char tmp[64]; + const unsigned char *hash_oid; + + if (hash) { + hash_oid = HASH_OID[hash - 2]; + } else { + hash_oid = NULL; + } + if (!ctx->eng.irsavrfy(ctx->eng.pad, sig_len, + hash_oid, hv_len, &pk->key.rsa, tmp) + || memcmp(tmp, hv, hv_len) != 0) + { + return BR_ERR_BAD_SIGNATURE; + } + } else { + if (!ctx->eng.iecdsa(ctx->eng.iec, hv, hv_len, &pk->key.ec, + ctx->eng.pad, sig_len)) + { + return BR_ERR_BAD_SIGNATURE; + } + } + return 0; +} + +/* + * Perform client-side ECDH (or ECDHE). The point that should be sent to + * the server is written in the pad; returned value is either the point + * length (in bytes), or -x on error, with 'x' being an error code. + * + * The point _from_ the server is taken from ecdhe_point[] if 'ecdhe' + * is non-zero, or from the X.509 engine context if 'ecdhe' is zero + * (for static ECDH). + */ +static int +make_pms_ecdh(br_ssl_client_context *ctx, unsigned ecdhe, int prf_id) +{ + int curve; + unsigned char key[66], point[133]; + const unsigned char *order, *point_src; + size_t glen, olen, point_len, xoff, xlen; + unsigned char mask; + + if (ecdhe) { + curve = ctx->eng.ecdhe_curve; + point_src = ctx->eng.ecdhe_point; + point_len = ctx->eng.ecdhe_point_len; + } else { + const br_x509_class **xc; + const br_x509_pkey *pk; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + curve = pk->key.ec.curve; + point_src = pk->key.ec.q; + point_len = pk->key.ec.qlen; + } + if ((ctx->eng.iec->supported_curves & ((uint32_t)1 << curve)) == 0) { + return -BR_ERR_INVALID_ALGORITHM; + } + + /* + * We need to generate our key, as a non-zero random value which + * is lower than the curve order, in a "large enough" range. We + * force top bit to 0 and bottom bit to 1, which guarantees that + * the value is in the proper range. + */ + order = ctx->eng.iec->order(curve, &olen); + mask = 0xFF; + while (mask >= order[0]) { + mask >>= 1; + } + br_hmac_drbg_generate(&ctx->eng.rng, key, olen); + key[0] &= mask; + key[olen - 1] |= 0x01; + + /* + * Compute the common ECDH point, whose X coordinate is the + * pre-master secret. + */ + ctx->eng.iec->generator(curve, &glen); + if (glen != point_len) { + return -BR_ERR_INVALID_ALGORITHM; + } + + memcpy(point, point_src, glen); + if (!ctx->eng.iec->mul(point, glen, key, olen, curve)) { + return -BR_ERR_INVALID_ALGORITHM; + } + + /* + * The pre-master secret is the X coordinate. + */ + xoff = ctx->eng.iec->xoff(curve, &xlen); + br_ssl_engine_compute_master(&ctx->eng, prf_id, point + xoff, xlen); + + ctx->eng.iec->mulgen(point, key, olen, curve); + memcpy(ctx->eng.pad, point, glen); + return (int)glen; +} + +/* + * Perform full static ECDH. This occurs only in the context of client + * authentication with certificates: the server uses an EC public key, + * the cipher suite is of type ECDH (not ECDHE), the server requested a + * client certificate and accepts static ECDH, the client has a + * certificate with an EC public key in the same curve, and accepts + * static ECDH as well. + * + * Returned value is 0 on success, -1 on error. + */ +static int +make_pms_static_ecdh(br_ssl_client_context *ctx, int prf_id) +{ + unsigned char point[133]; + size_t point_len; + const br_x509_class **xc; + const br_x509_pkey *pk; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + point_len = pk->key.ec.qlen; + if (point_len > sizeof point) { + return -1; + } + memcpy(point, pk->key.ec.q, point_len); + if (!(*ctx->client_auth_vtable)->do_keyx( + ctx->client_auth_vtable, point, &point_len)) + { + return -1; + } + br_ssl_engine_compute_master(&ctx->eng, + prf_id, point, point_len); + return 0; +} + +/* + * Compute the client-side signature. This is invoked only when a + * signature-based client authentication was selected. The computed + * signature is in the pad; its length (in bytes) is returned. On + * error, 0 is returned. + */ +static size_t +make_client_sign(br_ssl_client_context *ctx) +{ + size_t hv_len; + + /* + * Compute hash of handshake messages so far. This "cannot" fail + * because the list of supported hash functions provided to the + * client certificate handler was trimmed to include only the + * hash functions that the multi-hasher supports. + */ + if (ctx->hash_id) { + hv_len = br_multihash_out(&ctx->eng.mhash, + ctx->hash_id, ctx->eng.pad); + } else { + br_multihash_out(&ctx->eng.mhash, + br_md5_ID, ctx->eng.pad); + br_multihash_out(&ctx->eng.mhash, + br_sha1_ID, ctx->eng.pad + 16); + hv_len = 36; + } + return (*ctx->client_auth_vtable)->do_sign( + ctx->client_auth_vtable, ctx->hash_id, hv_len, + ctx->eng.pad, sizeof ctx->eng.pad); +} + + + +static const unsigned char t0_datablock[] = { + 0x00, 0x00, 0x0A, 0x00, 0x24, 0x00, 0x2F, 0x01, 0x24, 0x00, 0x35, 0x02, + 0x24, 0x00, 0x3C, 0x01, 0x44, 0x00, 0x3D, 0x02, 0x44, 0x00, 0x9C, 0x03, + 0x04, 0x00, 0x9D, 0x04, 0x05, 0xC0, 0x03, 0x40, 0x24, 0xC0, 0x04, 0x41, + 0x24, 0xC0, 0x05, 0x42, 0x24, 0xC0, 0x08, 0x20, 0x24, 0xC0, 0x09, 0x21, + 0x24, 0xC0, 0x0A, 0x22, 0x24, 0xC0, 0x0D, 0x30, 0x24, 0xC0, 0x0E, 0x31, + 0x24, 0xC0, 0x0F, 0x32, 0x24, 0xC0, 0x12, 0x10, 0x24, 0xC0, 0x13, 0x11, + 0x24, 0xC0, 0x14, 0x12, 0x24, 0xC0, 0x23, 0x21, 0x44, 0xC0, 0x24, 0x22, + 0x55, 0xC0, 0x25, 0x41, 0x44, 0xC0, 0x26, 0x42, 0x55, 0xC0, 0x27, 0x11, + 0x44, 0xC0, 0x28, 0x12, 0x55, 0xC0, 0x29, 0x31, 0x44, 0xC0, 0x2A, 0x32, + 0x55, 0xC0, 0x2B, 0x23, 0x04, 0xC0, 0x2C, 0x24, 0x05, 0xC0, 0x2D, 0x43, + 0x04, 0xC0, 0x2E, 0x44, 0x05, 0xC0, 0x2F, 0x13, 0x04, 0xC0, 0x30, 0x14, + 0x05, 0xC0, 0x31, 0x33, 0x04, 0xC0, 0x32, 0x34, 0x05, 0xC0, 0x9C, 0x06, + 0x04, 0xC0, 0x9D, 0x07, 0x04, 0xC0, 0xA0, 0x08, 0x04, 0xC0, 0xA1, 0x09, + 0x04, 0xC0, 0xAC, 0x26, 0x04, 0xC0, 0xAD, 0x27, 0x04, 0xC0, 0xAE, 0x28, + 0x04, 0xC0, 0xAF, 0x29, 0x04, 0xCC, 0xA8, 0x15, 0x04, 0xCC, 0xA9, 0x25, + 0x04, 0x00, 0x00 +}; + +static const unsigned char t0_codeblock[] = { + 0x00, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x01, + 0x00, 0x0E, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x01, 0x01, 0x08, + 0x00, 0x00, 0x01, 0x01, 0x09, 0x00, 0x00, 0x01, 0x02, 0x08, 0x00, 0x00, + 0x01, 0x02, 0x09, 0x00, 0x00, 0x26, 0x26, 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_CCS), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_CIPHER_SUITE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_COMPRESSION), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_FINISHED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_FRAGLEN), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_HANDSHAKE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_HELLO_DONE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_PARAM), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_SECRENEG), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_SNI), 0x00, 0x00, 0x01, T0_INT1(BR_ERR_BAD_VERSION), + 0x00, 0x00, 0x01, T0_INT1(BR_ERR_EXTRA_EXTENSION), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_INVALID_ALGORITHM), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, T0_INT1(BR_ERR_OK), + 0x00, 0x00, 0x01, T0_INT1(BR_ERR_OVERSIZED_ID), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_RESUME_MISMATCH), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_UNEXPECTED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_UNSUPPORTED_VERSION), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_WRONG_KEY_USAGE), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, action)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, alert)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, application_data)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_client_context, auth_type)), 0x00, 0x00, + 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, cipher_suite)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, client_random)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, close_received)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, ecdhe_curve)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, ecdhe_point)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, ecdhe_point_len)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, flags)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_client_context, hash_id)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_client_context, hashes)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, log_max_frag_len)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_client_context, min_clienthello_len)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, pad)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, protocol_names_num)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, record_type_in)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, record_type_out)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, reneg)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, saved_finished)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, selected_protocol)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, server_name)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, server_random)), 0x00, 0x00, + 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_id)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_id_len)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_ticket)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_ticket_len)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session_ticket_ok)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, shutdown_recv)), + 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, suites_buf)), + 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, suites_num)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, version)), + 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_in)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, version_max)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_min)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_out)), + 0x00, 0x00, 0x09, 0x27, 0x5A, 0x06, 0x02, 0x6A, 0x29, 0x00, 0x00, 0x06, + 0x08, 0x2D, 0x0E, 0x05, 0x02, 0x73, 0x29, 0x04, 0x01, 0x3E, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x01, 0x03, 0x00, 0x9E, 0x27, 0x60, 0x46, 0xA2, 0x27, + 0x05, 0x04, 0x62, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0E, 0x06, 0x02, 0xA2, + 0x00, 0x60, 0x04, 0x6B, 0x00, 0x06, 0x02, 0x6A, 0x29, 0x00, 0x00, 0x27, + 0x8B, 0x46, 0x05, 0x03, 0x01, 0x0C, 0x08, 0x46, 0x7B, 0x2D, 0xB1, 0x1C, + 0x86, 0x01, 0x0C, 0x32, 0x00, 0x00, 0x27, 0x1F, 0x01, 0x08, 0x0B, 0x46, + 0x5E, 0x1F, 0x08, 0x00, 0x01, 0x03, 0x00, 0x79, 0x2F, 0x02, 0x00, 0x37, + 0x17, 0x01, 0x01, 0x0B, 0x79, 0x40, 0x2A, 0x1A, 0x37, 0x06, 0x07, 0x02, + 0x00, 0xD7, 0x03, 0x00, 0x04, 0x75, 0x01, 0x00, 0xCD, 0x02, 0x00, 0x27, + 0x1A, 0x17, 0x06, 0x02, 0x71, 0x29, 0xD7, 0x04, 0x76, 0x02, 0x01, 0x00, + 0x79, 0x40, 0x01, 0x16, 0x89, 0x40, 0x01, 0x00, 0x8C, 0x3E, 0x01, 0x00, + 0x93, 0x40, 0x35, 0xDD, 0x2A, 0xBC, 0x01, 0x00, 0x03, 0x00, 0x05, 0x34, + 0x93, 0x2F, 0x92, 0x2D, 0x01, 0x00, 0x0F, 0x17, 0x06, 0x28, 0x30, 0x37, + 0x06, 0x0C, 0xD6, 0x01, 0x07, 0x17, 0x27, 0x5C, 0x06, 0x03, 0x26, 0x04, + 0x75, 0x26, 0x88, 0x2F, 0x01, 0x14, 0x0E, 0x06, 0x06, 0x01, 0x7F, 0x03, + 0x00, 0x04, 0x0B, 0x3A, 0x01, 0x04, 0x0E, 0x06, 0x05, 0xBB, 0x01, 0x7F, + 0x03, 0x00, 0x04, 0x04, 0x01, 0x7F, 0x03, 0x00, 0x02, 0x00, 0x06, 0x09, + 0x01, 0x7F, 0xB6, 0x01, 0x7F, 0xDA, 0x04, 0x80, 0x53, 0xB8, 0x7B, 0x2D, + 0xA6, 0x01, T0_INT1(BR_KEYTYPE_SIGN), 0x17, 0x06, 0x01, 0xBD, 0xC0, + 0x27, 0x01, 0x0D, 0x0E, 0x06, 0x07, 0x26, 0xBF, 0xC0, 0x01, 0x7F, 0x04, + 0x02, 0x01, 0x00, 0x03, 0x01, 0x01, 0x0E, 0x0E, 0x05, 0x02, 0x74, 0x29, + 0x06, 0x02, 0x69, 0x29, 0x34, 0x06, 0x02, 0x74, 0x29, 0x02, 0x01, 0x06, + 0x1C, 0xDB, 0x82, 0x2F, 0x01, 0x81, 0x7F, 0x0E, 0x06, 0x0D, 0x26, 0x01, + 0x10, 0xE6, 0x01, 0x00, 0xE5, 0x7B, 0x2D, 0xB1, 0x25, 0x04, 0x04, 0xDE, + 0x06, 0x01, 0xDC, 0x04, 0x01, 0xDE, 0x01, 0x7F, 0xDA, 0x01, 0x7F, 0xB6, + 0x01, 0x01, 0x79, 0x40, 0x01, 0x17, 0x89, 0x40, 0x00, 0x00, 0x39, 0x39, + 0x00, 0x00, 0x9F, 0x01, 0x0C, 0x11, 0x01, 0x00, 0x39, 0x0E, 0x06, 0x05, + 0x26, 0x01, T0_INT1(BR_KEYTYPE_RSA | BR_KEYTYPE_KEYX), 0x04, 0x30, + 0x01, 0x01, 0x39, 0x0E, 0x06, 0x05, 0x26, 0x01, + T0_INT1(BR_KEYTYPE_RSA | BR_KEYTYPE_SIGN), 0x04, 0x25, 0x01, 0x02, + 0x39, 0x0E, 0x06, 0x05, 0x26, 0x01, + T0_INT1(BR_KEYTYPE_EC | BR_KEYTYPE_SIGN), 0x04, 0x1A, 0x01, 0x03, + 0x39, 0x0E, 0x06, 0x05, 0x26, 0x01, + T0_INT1(BR_KEYTYPE_EC | BR_KEYTYPE_KEYX), 0x04, 0x0F, 0x01, 0x04, + 0x39, 0x0E, 0x06, 0x05, 0x26, 0x01, + T0_INT1(BR_KEYTYPE_EC | BR_KEYTYPE_KEYX), 0x04, 0x04, 0x01, 0x00, + 0x46, 0x26, 0x00, 0x00, 0x84, 0x2F, 0x01, 0x0E, 0x0E, 0x06, 0x04, 0x01, + 0x00, 0x04, 0x02, 0x01, 0x05, 0x00, 0x00, 0x42, 0x06, 0x04, 0x01, 0x06, + 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x8A, 0x2F, 0x27, 0x06, 0x08, 0x01, + 0x01, 0x09, 0x01, 0x11, 0x07, 0x04, 0x03, 0x26, 0x01, 0x05, 0x00, 0x00, + 0x92, 0x2D, 0x01, 0x04, 0x08, 0x00, 0x01, 0x43, 0x03, 0x00, 0x26, 0x01, + 0x00, 0x45, 0x06, 0x03, 0x02, 0x00, 0x08, 0x44, 0x06, 0x03, 0x02, 0x00, + 0x08, 0x27, 0x06, 0x06, 0x01, 0x01, 0x0B, 0x01, 0x06, 0x08, 0x00, 0x00, + 0x8D, 0x41, 0x27, 0x06, 0x03, 0x01, 0x09, 0x08, 0x00, 0x01, 0x42, 0x27, + 0x06, 0x1E, 0x01, 0x00, 0x03, 0x00, 0x27, 0x06, 0x0E, 0x27, 0x01, 0x01, + 0x17, 0x02, 0x00, 0x08, 0x03, 0x00, 0x01, 0x01, 0x11, 0x04, 0x6F, 0x26, + 0x02, 0x00, 0x01, 0x01, 0x0B, 0x01, 0x06, 0x08, 0x00, 0x00, 0x81, 0x2E, + 0x46, 0x11, 0x01, 0x01, 0x17, 0x36, 0x00, 0x00, 0xA4, 0xD6, 0x27, 0x01, + 0x07, 0x17, 0x01, 0x00, 0x39, 0x0E, 0x06, 0x09, 0x26, 0x01, 0x10, 0x17, + 0x06, 0x01, 0xA4, 0x04, 0x35, 0x01, 0x01, 0x39, 0x0E, 0x06, 0x2C, 0x26, + 0x26, 0x01, 0x00, 0x79, 0x40, 0xBA, 0x8A, 0x2F, 0x01, 0x01, 0x0E, 0x01, + 0x01, 0xAE, 0x38, 0x06, 0x17, 0x2A, 0x1A, 0x37, 0x06, 0x04, 0xD6, 0x26, + 0x04, 0x78, 0x01, 0x80, 0x64, 0xCD, 0x01, 0x01, 0x79, 0x40, 0x01, 0x17, + 0x89, 0x40, 0x04, 0x01, 0xA4, 0x04, 0x03, 0x74, 0x29, 0x26, 0x04, 0xFF, + 0x34, 0x01, 0x27, 0x03, 0x00, 0x09, 0x27, 0x5A, 0x06, 0x02, 0x6A, 0x29, + 0x02, 0x00, 0x00, 0x00, 0x9F, 0x01, 0x0F, 0x17, 0x00, 0x00, 0x78, 0x2F, + 0x01, 0x00, 0x39, 0x0E, 0x06, 0x10, 0x26, 0x27, 0x01, 0x01, 0x0D, 0x06, + 0x03, 0x26, 0x01, 0x02, 0x78, 0x40, 0x01, 0x00, 0x04, 0x21, 0x01, 0x01, + 0x39, 0x0E, 0x06, 0x14, 0x26, 0x01, 0x00, 0x78, 0x40, 0x27, 0x01, 0x80, + 0x64, 0x0E, 0x06, 0x05, 0x01, 0x82, 0x00, 0x08, 0x29, 0x5C, 0x04, 0x07, + 0x26, 0x01, 0x82, 0x00, 0x08, 0x29, 0x26, 0x00, 0x00, 0x01, 0x00, 0x30, + 0x06, 0x05, 0x3C, 0xB2, 0x38, 0x04, 0x78, 0x27, 0x06, 0x04, 0x01, 0x01, + 0x94, 0x40, 0x00, 0x01, 0xC7, 0xB0, 0xC7, 0xB0, 0xC9, 0x86, 0x46, 0x27, + 0x03, 0x00, 0xBE, 0xA0, 0xA0, 0x02, 0x00, 0x4F, 0x27, 0x5A, 0x06, 0x0A, + 0x01, 0x03, 0xAE, 0x06, 0x02, 0x74, 0x29, 0x26, 0x04, 0x03, 0x5E, 0x8C, + 0x3E, 0x00, 0x00, 0x30, 0x06, 0x0B, 0x88, 0x2F, 0x01, 0x14, 0x0D, 0x06, + 0x02, 0x74, 0x29, 0x04, 0x11, 0xD6, 0x01, 0x07, 0x17, 0x27, 0x01, 0x02, + 0x0D, 0x06, 0x06, 0x06, 0x02, 0x74, 0x29, 0x04, 0x70, 0x26, 0xCA, 0x01, + 0x01, 0x0D, 0x34, 0x38, 0x06, 0x02, 0x63, 0x29, 0x27, 0x01, 0x01, 0xD0, + 0x37, 0xB9, 0x00, 0x00, 0x93, 0x2F, 0x06, 0x2A, 0x30, 0x06, 0x0A, 0x88, + 0x2F, 0x01, 0x16, 0x0E, 0x06, 0x01, 0xBB, 0x04, 0x1D, 0xD6, 0x01, 0x07, + 0x17, 0x27, 0x01, 0x01, 0x0E, 0x06, 0x04, 0x26, 0xBB, 0x01, 0x00, 0x27, + 0x01, 0x02, 0x0D, 0x06, 0x08, 0x27, 0x06, 0x02, 0x74, 0x29, 0x26, 0x04, + 0x64, 0x26, 0xB5, 0x00, 0x01, 0xC0, 0x01, 0x0B, 0x0E, 0x05, 0x02, 0x74, + 0x29, 0x27, 0x01, 0x03, 0x0E, 0x06, 0x08, 0xC8, 0x06, 0x02, 0x6A, 0x29, + 0x46, 0x26, 0x00, 0x46, 0x59, 0xC8, 0xB0, 0x27, 0x06, 0x23, 0xC8, 0xB0, + 0x27, 0x58, 0x27, 0x06, 0x18, 0x27, 0x01, 0x82, 0x00, 0x0F, 0x06, 0x05, + 0x01, 0x82, 0x00, 0x04, 0x01, 0x27, 0x03, 0x00, 0x86, 0x02, 0x00, 0xBE, + 0x02, 0x00, 0x55, 0x04, 0x65, 0xA0, 0x56, 0x04, 0x5A, 0xA0, 0xA0, 0x57, + 0x27, 0x06, 0x02, 0x36, 0x00, 0x26, 0x2C, 0x00, 0x00, 0x7B, 0x2D, 0xA6, + 0x01, 0x7F, 0xB7, 0x27, 0x5A, 0x06, 0x02, 0x36, 0x29, 0x27, 0x05, 0x02, + 0x74, 0x29, 0x39, 0x17, 0x0D, 0x06, 0x02, 0x76, 0x29, 0x3D, 0x00, 0x00, + 0xA1, 0xC0, 0x01, 0x14, 0x0D, 0x06, 0x02, 0x74, 0x29, 0x86, 0x01, 0x0C, + 0x08, 0x01, 0x0C, 0xBE, 0xA0, 0x86, 0x27, 0x01, 0x0C, 0x08, 0x01, 0x0C, + 0x31, 0x05, 0x02, 0x66, 0x29, 0x00, 0x00, 0xC1, 0x06, 0x02, 0x74, 0x29, + 0x06, 0x02, 0x68, 0x29, 0x00, 0x01, 0xC0, 0x01, 0x04, 0x0E, 0x05, 0x02, + 0x74, 0x29, 0xC7, 0x26, 0xC7, 0x26, 0xC7, 0x03, 0x00, 0x02, 0x00, 0x01, + 0x88, 0x00, 0x0F, 0x06, 0x09, 0x02, 0x00, 0xCE, 0x01, 0x00, 0x92, 0x3E, + 0x04, 0x08, 0x91, 0x02, 0x00, 0xBE, 0x02, 0x00, 0x92, 0x3E, 0x02, 0x00, + 0x20, 0xA0, 0x00, 0x0B, 0xC0, 0x01, 0x02, 0x0E, 0x05, 0x02, 0x74, 0x29, + 0xC7, 0x03, 0x00, 0x02, 0x00, 0x9A, 0x2D, 0x0A, 0x02, 0x00, 0x99, 0x2D, + 0x0F, 0x38, 0x06, 0x02, 0x75, 0x29, 0x02, 0x00, 0x98, 0x2D, 0x0D, 0x06, + 0x02, 0x6D, 0x29, 0x02, 0x00, 0x9B, 0x3E, 0x8E, 0x01, 0x20, 0xBE, 0x01, + 0x00, 0x03, 0x01, 0xC9, 0x03, 0x02, 0x02, 0x02, 0x01, 0x20, 0x0F, 0x06, + 0x02, 0x72, 0x29, 0x86, 0x02, 0x02, 0xBE, 0x02, 0x02, 0x90, 0x2F, 0x0E, + 0x02, 0x02, 0x01, 0x00, 0x0F, 0x17, 0x06, 0x0B, 0x8F, 0x86, 0x02, 0x02, + 0x31, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x01, 0x8F, 0x86, 0x02, 0x02, 0x32, + 0x02, 0x02, 0x90, 0x40, 0x02, 0x00, 0x97, 0x02, 0x01, 0x9D, 0xC7, 0x27, + 0xCB, 0x5A, 0x06, 0x02, 0x64, 0x29, 0x27, 0xD5, 0x02, 0x00, 0x01, 0x86, + 0x03, 0x0A, 0x17, 0x06, 0x02, 0x64, 0x29, 0x7B, 0x02, 0x01, 0x9D, 0xC9, + 0x06, 0x02, 0x65, 0x29, 0x27, 0x06, 0x81, 0x64, 0xC7, 0xB0, 0xAC, 0x03, + 0x03, 0xA9, 0x03, 0x04, 0xA7, 0x03, 0x05, 0xAB, 0x03, 0x06, 0xAD, 0x03, + 0x07, 0xA8, 0x03, 0x08, 0xAA, 0x03, 0x09, 0x28, 0x03, 0x0A, 0x27, 0x06, + 0x81, 0x32, 0xC7, 0x01, 0x00, 0x39, 0x0E, 0x06, 0x0F, 0x26, 0x02, 0x03, + 0x05, 0x02, 0x6E, 0x29, 0x01, 0x00, 0x03, 0x03, 0xC6, 0x04, 0x81, 0x19, + 0x01, 0x01, 0x39, 0x0E, 0x06, 0x0F, 0x26, 0x02, 0x05, 0x05, 0x02, 0x6E, + 0x29, 0x01, 0x00, 0x03, 0x05, 0xC4, 0x04, 0x81, 0x04, 0x01, 0x83, 0xFE, + 0x01, 0x39, 0x0E, 0x06, 0x0F, 0x26, 0x02, 0x04, 0x05, 0x02, 0x6E, 0x29, + 0x01, 0x00, 0x03, 0x04, 0xC5, 0x04, 0x80, 0x6D, 0x01, 0x0D, 0x39, 0x0E, + 0x06, 0x0F, 0x26, 0x02, 0x06, 0x05, 0x02, 0x6E, 0x29, 0x01, 0x00, 0x03, + 0x06, 0xC2, 0x04, 0x80, 0x58, 0x01, 0x0A, 0x39, 0x0E, 0x06, 0x0F, 0x26, + 0x02, 0x07, 0x05, 0x02, 0x6E, 0x29, 0x01, 0x00, 0x03, 0x07, 0xC2, 0x04, + 0x80, 0x43, 0x01, 0x0B, 0x39, 0x0E, 0x06, 0x0E, 0x26, 0x02, 0x08, 0x05, + 0x02, 0x6E, 0x29, 0x01, 0x00, 0x03, 0x08, 0xC2, 0x04, 0x2F, 0x01, 0x10, + 0x39, 0x0E, 0x06, 0x0E, 0x26, 0x02, 0x0A, 0x05, 0x02, 0x6E, 0x29, 0x01, + 0x00, 0x03, 0x0A, 0xB4, 0x04, 0x1B, 0x01, 0x23, 0x39, 0x0E, 0x06, 0x12, + 0x26, 0x02, 0x09, 0x05, 0x02, 0x6E, 0x29, 0x01, 0x00, 0x03, 0x09, 0xC2, + 0x01, 0x01, 0x93, 0x40, 0x04, 0x03, 0x6E, 0x29, 0x26, 0x04, 0xFE, 0x4A, + 0x02, 0x04, 0x06, 0x0D, 0x02, 0x04, 0x01, 0x05, 0x0F, 0x06, 0x02, 0x6B, + 0x29, 0x01, 0x01, 0x8A, 0x40, 0xA0, 0x04, 0x0C, 0xA9, 0x01, 0x05, 0x0F, + 0x06, 0x02, 0x6B, 0x29, 0x01, 0x01, 0x8A, 0x40, 0xA0, 0x02, 0x01, 0x00, + 0x04, 0xC0, 0x01, 0x0C, 0x0E, 0x05, 0x02, 0x74, 0x29, 0xC9, 0x01, 0x03, + 0x0E, 0x05, 0x02, 0x6F, 0x29, 0xC7, 0x27, 0x7E, 0x40, 0x27, 0x01, 0x20, + 0x10, 0x06, 0x02, 0x6F, 0x29, 0x42, 0x46, 0x11, 0x01, 0x01, 0x17, 0x05, + 0x02, 0x6F, 0x29, 0xC9, 0x27, 0x01, 0x81, 0x05, 0x0F, 0x06, 0x02, 0x6F, + 0x29, 0x27, 0x80, 0x40, 0x7F, 0x46, 0xBE, 0x97, 0x2D, 0x01, 0x86, 0x03, + 0x10, 0x03, 0x00, 0x7B, 0x2D, 0xD3, 0x03, 0x01, 0x01, 0x02, 0x03, 0x02, + 0x02, 0x00, 0x06, 0x21, 0xC9, 0x27, 0x27, 0x01, 0x02, 0x0A, 0x46, 0x01, + 0x06, 0x0F, 0x38, 0x06, 0x02, 0x6F, 0x29, 0x03, 0x02, 0xC9, 0x02, 0x01, + 0x01, 0x01, 0x0B, 0x01, 0x03, 0x08, 0x0E, 0x05, 0x02, 0x6F, 0x29, 0x04, + 0x08, 0x02, 0x01, 0x06, 0x04, 0x01, 0x00, 0x03, 0x02, 0xC7, 0x27, 0x03, + 0x03, 0x27, 0x01, 0x84, 0x00, 0x0F, 0x06, 0x02, 0x70, 0x29, 0x86, 0x46, + 0xBE, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x52, 0x27, 0x06, 0x01, 0x29, + 0x26, 0xA0, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x9C, 0x02, + 0x01, 0x02, 0x00, 0x3B, 0x27, 0x01, 0x00, 0x0E, 0x06, 0x02, 0x62, 0x00, + 0xD8, 0x04, 0x74, 0x02, 0x01, 0x00, 0x03, 0x00, 0xC9, 0xB0, 0x27, 0x06, + 0x80, 0x43, 0xC9, 0x01, 0x01, 0x39, 0x0E, 0x06, 0x06, 0x26, 0x01, 0x81, + 0x7F, 0x04, 0x2E, 0x01, 0x80, 0x40, 0x39, 0x0E, 0x06, 0x07, 0x26, 0x01, + 0x83, 0xFE, 0x00, 0x04, 0x20, 0x01, 0x80, 0x41, 0x39, 0x0E, 0x06, 0x07, + 0x26, 0x01, 0x84, 0x80, 0x00, 0x04, 0x12, 0x01, 0x80, 0x42, 0x39, 0x0E, + 0x06, 0x07, 0x26, 0x01, 0x88, 0x80, 0x00, 0x04, 0x04, 0x01, 0x00, 0x46, + 0x26, 0x02, 0x00, 0x38, 0x03, 0x00, 0x04, 0xFF, 0x39, 0xA0, 0x7B, 0x2D, + 0xD1, 0x05, 0x09, 0x02, 0x00, 0x01, 0x83, 0xFF, 0x7F, 0x17, 0x03, 0x00, + 0x97, 0x2D, 0x01, 0x86, 0x03, 0x10, 0x06, 0x3A, 0xC3, 0x27, 0x83, 0x3F, + 0x43, 0x26, 0x27, 0x01, 0x08, 0x0B, 0x38, 0x01, 0x8C, 0x80, 0x00, 0x38, + 0x17, 0x02, 0x00, 0x17, 0x02, 0x00, 0x01, 0x8C, 0x80, 0x00, 0x17, 0x06, + 0x19, 0x27, 0x01, 0x81, 0x7F, 0x17, 0x06, 0x05, 0x01, 0x84, 0x80, 0x00, + 0x38, 0x27, 0x01, 0x83, 0xFE, 0x00, 0x17, 0x06, 0x05, 0x01, 0x88, 0x80, + 0x00, 0x38, 0x03, 0x00, 0x04, 0x09, 0x02, 0x00, 0x01, 0x8C, 0x88, 0x01, + 0x17, 0x03, 0x00, 0x16, 0xC7, 0xB0, 0x27, 0x06, 0x23, 0xC7, 0xB0, 0x27, + 0x15, 0x27, 0x06, 0x18, 0x27, 0x01, 0x82, 0x00, 0x0F, 0x06, 0x05, 0x01, + 0x82, 0x00, 0x04, 0x01, 0x27, 0x03, 0x01, 0x86, 0x02, 0x01, 0xBE, 0x02, + 0x01, 0x12, 0x04, 0x65, 0xA0, 0x13, 0x04, 0x5A, 0xA0, 0x14, 0xA0, 0x02, + 0x00, 0x2B, 0x00, 0x00, 0xC1, 0x27, 0x5C, 0x06, 0x07, 0x26, 0x06, 0x02, + 0x68, 0x29, 0x04, 0x74, 0x00, 0x00, 0xCA, 0x01, 0x03, 0xC8, 0x46, 0x26, + 0x46, 0x00, 0x00, 0xC7, 0xCE, 0x00, 0x03, 0x01, 0x00, 0x03, 0x00, 0xC7, + 0xB0, 0x27, 0x06, 0x80, 0x50, 0xC9, 0x03, 0x01, 0xC9, 0x03, 0x02, 0x02, + 0x01, 0x01, 0x08, 0x0E, 0x06, 0x16, 0x02, 0x02, 0x01, 0x0F, 0x0C, 0x06, + 0x0D, 0x01, 0x01, 0x02, 0x02, 0x01, 0x10, 0x08, 0x0B, 0x02, 0x00, 0x38, + 0x03, 0x00, 0x04, 0x2A, 0x02, 0x01, 0x01, 0x02, 0x10, 0x02, 0x01, 0x01, + 0x06, 0x0C, 0x17, 0x02, 0x02, 0x01, 0x01, 0x0E, 0x02, 0x02, 0x01, 0x03, + 0x0E, 0x38, 0x17, 0x06, 0x11, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x5F, + 0x01, 0x02, 0x0B, 0x02, 0x01, 0x08, 0x0B, 0x38, 0x03, 0x00, 0x04, 0xFF, + 0x2C, 0xA0, 0x02, 0x00, 0x00, 0x00, 0xC7, 0x01, 0x01, 0x0E, 0x05, 0x02, + 0x67, 0x29, 0xC9, 0x01, 0x08, 0x08, 0x84, 0x2F, 0x0E, 0x05, 0x02, 0x67, + 0x29, 0x00, 0x00, 0xC7, 0x8A, 0x2F, 0x05, 0x15, 0x01, 0x01, 0x0E, 0x05, + 0x02, 0x6B, 0x29, 0xC9, 0x01, 0x00, 0x0E, 0x05, 0x02, 0x6B, 0x29, 0x01, + 0x02, 0x8A, 0x40, 0x04, 0x1C, 0x01, 0x19, 0x0E, 0x05, 0x02, 0x6B, 0x29, + 0xC9, 0x01, 0x18, 0x0E, 0x05, 0x02, 0x6B, 0x29, 0x86, 0x01, 0x18, 0xBE, + 0x8B, 0x86, 0x01, 0x18, 0x31, 0x05, 0x02, 0x6B, 0x29, 0x00, 0x00, 0xC7, + 0x06, 0x02, 0x6C, 0x29, 0x00, 0x00, 0x01, 0x02, 0x9C, 0xCA, 0x01, 0x08, + 0x0B, 0xCA, 0x08, 0x00, 0x00, 0x01, 0x03, 0x9C, 0xCA, 0x01, 0x08, 0x0B, + 0xCA, 0x08, 0x01, 0x08, 0x0B, 0xCA, 0x08, 0x00, 0x00, 0x01, 0x01, 0x9C, + 0xCA, 0x00, 0x00, 0x3C, 0x27, 0x5A, 0x05, 0x01, 0x00, 0x26, 0xD8, 0x04, + 0x76, 0x02, 0x03, 0x00, 0x96, 0x2F, 0x03, 0x01, 0x01, 0x00, 0x27, 0x02, + 0x01, 0x0A, 0x06, 0x10, 0x27, 0x01, 0x01, 0x0B, 0x95, 0x08, 0x2D, 0x02, + 0x00, 0x0E, 0x06, 0x01, 0x00, 0x5E, 0x04, 0x6A, 0x26, 0x01, 0x7F, 0x00, + 0x00, 0x01, 0x15, 0x89, 0x40, 0x46, 0x54, 0x26, 0x54, 0x26, 0x2A, 0x00, + 0x00, 0x01, 0x01, 0x46, 0xCC, 0x00, 0x00, 0x46, 0x39, 0x9C, 0x46, 0x27, + 0x06, 0x05, 0xCA, 0x26, 0x5F, 0x04, 0x78, 0x26, 0x00, 0x00, 0x27, 0x01, + 0x81, 0xAC, 0x00, 0x0E, 0x06, 0x04, 0x26, 0x01, 0x7F, 0x00, 0x9F, 0x5B, + 0x00, 0x02, 0x03, 0x00, 0x7B, 0x2D, 0x9F, 0x03, 0x01, 0x02, 0x01, 0x01, + 0x0F, 0x17, 0x02, 0x01, 0x01, 0x04, 0x11, 0x01, 0x0F, 0x17, 0x02, 0x01, + 0x01, 0x08, 0x11, 0x01, 0x0F, 0x17, 0x01, 0x00, 0x39, 0x0E, 0x06, 0x10, + 0x26, 0x01, 0x00, 0x01, 0x18, 0x02, 0x00, 0x06, 0x03, 0x4B, 0x04, 0x01, + 0x4C, 0x04, 0x81, 0x0D, 0x01, 0x01, 0x39, 0x0E, 0x06, 0x10, 0x26, 0x01, + 0x01, 0x01, 0x10, 0x02, 0x00, 0x06, 0x03, 0x4B, 0x04, 0x01, 0x4C, 0x04, + 0x80, 0x77, 0x01, 0x02, 0x39, 0x0E, 0x06, 0x10, 0x26, 0x01, 0x01, 0x01, + 0x20, 0x02, 0x00, 0x06, 0x03, 0x4B, 0x04, 0x01, 0x4C, 0x04, 0x80, 0x61, + 0x01, 0x03, 0x39, 0x0E, 0x06, 0x0F, 0x26, 0x26, 0x01, 0x10, 0x02, 0x00, + 0x06, 0x03, 0x49, 0x04, 0x01, 0x4A, 0x04, 0x80, 0x4C, 0x01, 0x04, 0x39, + 0x0E, 0x06, 0x0E, 0x26, 0x26, 0x01, 0x20, 0x02, 0x00, 0x06, 0x03, 0x49, + 0x04, 0x01, 0x4A, 0x04, 0x38, 0x01, 0x05, 0x39, 0x0E, 0x06, 0x0C, 0x26, + 0x26, 0x02, 0x00, 0x06, 0x03, 0x4D, 0x04, 0x01, 0x4E, 0x04, 0x26, 0x27, + 0x01, 0x09, 0x0F, 0x06, 0x02, 0x6A, 0x29, 0x46, 0x26, 0x27, 0x01, 0x01, + 0x17, 0x01, 0x04, 0x0B, 0x01, 0x10, 0x08, 0x46, 0x01, 0x08, 0x17, 0x01, + 0x10, 0x46, 0x09, 0x02, 0x00, 0x06, 0x03, 0x47, 0x04, 0x01, 0x48, 0x00, + 0x26, 0x00, 0x00, 0x9F, 0x01, 0x0C, 0x11, 0x01, 0x02, 0x0F, 0x00, 0x00, + 0x9F, 0x01, 0x0C, 0x11, 0x27, 0x5D, 0x46, 0x01, 0x03, 0x0A, 0x17, 0x00, + 0x00, 0x9F, 0x01, 0x0C, 0x11, 0x01, 0x01, 0x0E, 0x00, 0x00, 0x9F, 0x01, + 0x0C, 0x11, 0x5C, 0x00, 0x00, 0x9F, 0x01, 0x81, 0x70, 0x17, 0x01, 0x20, + 0x0D, 0x00, 0x00, 0x1B, 0x01, 0x00, 0x77, 0x2F, 0x27, 0x06, 0x22, 0x01, + 0x01, 0x39, 0x0E, 0x06, 0x06, 0x26, 0x01, 0x00, 0xA3, 0x04, 0x14, 0x01, + 0x02, 0x39, 0x0E, 0x06, 0x0D, 0x26, 0x79, 0x2F, 0x01, 0x01, 0x0E, 0x06, + 0x03, 0x01, 0x10, 0x38, 0x04, 0x01, 0x26, 0x04, 0x01, 0x26, 0x7D, 0x2F, + 0x05, 0x33, 0x30, 0x06, 0x30, 0x88, 0x2F, 0x01, 0x14, 0x39, 0x0E, 0x06, + 0x06, 0x26, 0x01, 0x02, 0x38, 0x04, 0x22, 0x01, 0x15, 0x39, 0x0E, 0x06, + 0x09, 0x26, 0xB3, 0x06, 0x03, 0x01, 0x7F, 0xA3, 0x04, 0x13, 0x01, 0x16, + 0x39, 0x0E, 0x06, 0x06, 0x26, 0x01, 0x01, 0x38, 0x04, 0x07, 0x26, 0x01, + 0x04, 0x38, 0x01, 0x00, 0x26, 0x1A, 0x06, 0x03, 0x01, 0x08, 0x38, 0x00, + 0x00, 0x1B, 0x27, 0x05, 0x13, 0x30, 0x06, 0x10, 0x88, 0x2F, 0x01, 0x15, + 0x0E, 0x06, 0x08, 0x26, 0xB3, 0x01, 0x00, 0x79, 0x40, 0x04, 0x01, 0x21, + 0x00, 0x00, 0xD6, 0x01, 0x07, 0x17, 0x01, 0x01, 0x0F, 0x06, 0x02, 0x74, + 0x29, 0x00, 0x01, 0x03, 0x00, 0x2A, 0x1A, 0x06, 0x05, 0x02, 0x00, 0x89, + 0x40, 0x00, 0xD6, 0x26, 0x04, 0x74, 0x00, 0x01, 0x14, 0xD9, 0x01, 0x01, + 0xE6, 0x2A, 0x27, 0x01, 0x00, 0xD0, 0x01, 0x16, 0xD9, 0xDF, 0x2A, 0x00, + 0x00, 0x01, 0x0B, 0xE6, 0x50, 0x27, 0x27, 0x01, 0x03, 0x08, 0xE5, 0xE5, + 0x18, 0x27, 0x5A, 0x06, 0x02, 0x26, 0x00, 0xE5, 0x1D, 0x27, 0x06, 0x05, + 0x86, 0x46, 0xE0, 0x04, 0x77, 0x26, 0x04, 0x6C, 0x00, 0x22, 0x01, 0x0F, + 0xE6, 0x27, 0x97, 0x2D, 0x01, 0x86, 0x03, 0x10, 0x06, 0x0C, 0x01, 0x04, + 0x08, 0xE5, 0x82, 0x2F, 0xE6, 0x7A, 0x2F, 0xE6, 0x04, 0x02, 0x60, 0xE5, + 0x27, 0xE4, 0x86, 0x46, 0xE0, 0x00, 0x02, 0xA9, 0xAC, 0x08, 0xA7, 0x08, + 0xAB, 0x08, 0xAD, 0x08, 0xA8, 0x08, 0x28, 0x08, 0xAA, 0x08, 0x03, 0x00, + 0x01, 0x01, 0xE6, 0x01, 0x27, 0x90, 0x2F, 0x08, 0x96, 0x2F, 0x01, 0x01, + 0x0B, 0x08, 0x02, 0x00, 0x06, 0x04, 0x60, 0x02, 0x00, 0x08, 0x85, 0x2D, + 0x39, 0x09, 0x27, 0x5D, 0x06, 0x24, 0x02, 0x00, 0x05, 0x04, 0x46, 0x60, + 0x46, 0x61, 0x01, 0x04, 0x09, 0x27, 0x5A, 0x06, 0x03, 0x26, 0x01, 0x00, + 0x27, 0x01, 0x04, 0x08, 0x02, 0x00, 0x08, 0x03, 0x00, 0x46, 0x01, 0x04, + 0x08, 0x39, 0x08, 0x46, 0x04, 0x03, 0x26, 0x01, 0x7F, 0x03, 0x01, 0xE5, + 0x99, 0x2D, 0xE4, 0x7C, 0x01, 0x04, 0x19, 0x7C, 0x01, 0x04, 0x08, 0x01, + 0x1C, 0x33, 0x7C, 0x01, 0x20, 0xE0, 0x8F, 0x90, 0x2F, 0xE2, 0x96, 0x2F, + 0x27, 0x01, 0x01, 0x0B, 0xE4, 0x95, 0x46, 0x27, 0x06, 0x0F, 0x5F, 0x39, + 0x2D, 0x27, 0xCF, 0x05, 0x02, 0x64, 0x29, 0xE4, 0x46, 0x60, 0x46, 0x04, + 0x6E, 0x62, 0x01, 0x01, 0xE6, 0x01, 0x00, 0xE6, 0x02, 0x00, 0x06, 0x81, + 0x6A, 0x02, 0x00, 0xE4, 0xA9, 0x06, 0x0E, 0x01, 0x83, 0xFE, 0x01, 0xE4, + 0x8B, 0xA9, 0x01, 0x04, 0x09, 0x27, 0xE4, 0x5F, 0xE2, 0xAC, 0x06, 0x16, + 0x01, 0x00, 0xE4, 0x8D, 0xAC, 0x01, 0x04, 0x09, 0x27, 0xE4, 0x01, 0x02, + 0x09, 0x27, 0xE4, 0x01, 0x00, 0xE6, 0x01, 0x03, 0x09, 0xE1, 0xA7, 0x06, + 0x0C, 0x01, 0x01, 0xE4, 0x01, 0x01, 0xE4, 0x84, 0x2F, 0x01, 0x08, 0x09, + 0xE6, 0xAB, 0x06, 0x19, 0x01, 0x0D, 0xE4, 0xAB, 0x01, 0x04, 0x09, 0x27, + 0xE4, 0x01, 0x02, 0x09, 0xE4, 0x44, 0x06, 0x03, 0x01, 0x03, 0xE3, 0x45, + 0x06, 0x03, 0x01, 0x01, 0xE3, 0xAD, 0x27, 0x06, 0x36, 0x01, 0x0A, 0xE4, + 0x01, 0x04, 0x09, 0x27, 0xE4, 0x61, 0xE4, 0x42, 0x01, 0x00, 0x27, 0x01, + 0x82, 0x80, 0x80, 0x80, 0x00, 0x17, 0x06, 0x0A, 0x01, 0xFD, 0xFF, 0xFF, + 0xFF, 0x7F, 0x17, 0x01, 0x1D, 0xE4, 0x27, 0x01, 0x20, 0x0A, 0x06, 0x0C, + 0xA5, 0x11, 0x01, 0x01, 0x17, 0x06, 0x02, 0x27, 0xE4, 0x5E, 0x04, 0x6E, + 0x62, 0x04, 0x01, 0x26, 0xA8, 0x06, 0x0A, 0x01, 0x0B, 0xE4, 0x01, 0x02, + 0xE4, 0x01, 0x82, 0x00, 0xE4, 0x28, 0x27, 0x06, 0x1F, 0x01, 0x10, 0xE4, + 0x01, 0x04, 0x09, 0x27, 0xE4, 0x61, 0xE4, 0x87, 0x2D, 0x01, 0x00, 0xA5, + 0x0F, 0x06, 0x0A, 0x27, 0x1E, 0x27, 0xE6, 0x86, 0x46, 0xE0, 0x5E, 0x04, + 0x72, 0x62, 0x04, 0x01, 0x26, 0x01, 0x23, 0xE4, 0x92, 0x2D, 0x27, 0xE4, + 0x27, 0x06, 0x05, 0x91, 0x46, 0xE0, 0x04, 0x01, 0x26, 0x02, 0x01, 0x5A, + 0x05, 0x11, 0x01, 0x15, 0xE4, 0x02, 0x01, 0x27, 0xE4, 0x27, 0x06, 0x06, + 0x5F, 0x01, 0x00, 0xE6, 0x04, 0x77, 0x26, 0x00, 0x00, 0x01, 0x10, 0xE6, + 0x7B, 0x2D, 0x27, 0xD4, 0x06, 0x0C, 0xB1, 0x24, 0x27, 0x60, 0xE5, 0x27, + 0xE4, 0x86, 0x46, 0xE0, 0x04, 0x0D, 0x27, 0xD2, 0x46, 0xB1, 0x23, 0x27, + 0x5E, 0xE5, 0x27, 0xE6, 0x86, 0x46, 0xE0, 0x00, 0x00, 0xA1, 0x01, 0x14, + 0xE6, 0x01, 0x0C, 0xE5, 0x86, 0x01, 0x0C, 0xE0, 0x00, 0x00, 0x53, 0x27, + 0x01, 0x00, 0x0E, 0x06, 0x02, 0x62, 0x00, 0xD6, 0x26, 0x04, 0x73, 0x00, + 0x27, 0xE4, 0xE0, 0x00, 0x00, 0x27, 0xE6, 0xE0, 0x00, 0x01, 0x03, 0x00, + 0x43, 0x26, 0x27, 0x01, 0x10, 0x17, 0x06, 0x06, 0x01, 0x04, 0xE6, 0x02, + 0x00, 0xE6, 0x27, 0x01, 0x08, 0x17, 0x06, 0x06, 0x01, 0x03, 0xE6, 0x02, + 0x00, 0xE6, 0x27, 0x01, 0x20, 0x17, 0x06, 0x06, 0x01, 0x05, 0xE6, 0x02, + 0x00, 0xE6, 0x27, 0x01, 0x80, 0x40, 0x17, 0x06, 0x06, 0x01, 0x06, 0xE6, + 0x02, 0x00, 0xE6, 0x01, 0x04, 0x17, 0x06, 0x06, 0x01, 0x02, 0xE6, 0x02, + 0x00, 0xE6, 0x00, 0x00, 0x27, 0x01, 0x08, 0x51, 0xE6, 0xE6, 0x00, 0x00, + 0x27, 0x01, 0x10, 0x51, 0xE6, 0xE4, 0x00, 0x00, 0x27, 0x54, 0x06, 0x02, + 0x26, 0x00, 0xD6, 0x26, 0x04, 0x76 +}; + +static const uint16_t t0_caddr[] = { + 0, + 5, + 10, + 15, + 20, + 25, + 30, + 35, + 40, + 44, + 48, + 52, + 56, + 60, + 64, + 68, + 72, + 76, + 80, + 84, + 88, + 92, + 96, + 100, + 104, + 108, + 112, + 116, + 120, + 124, + 129, + 134, + 139, + 144, + 149, + 154, + 159, + 164, + 169, + 174, + 179, + 184, + 189, + 194, + 199, + 204, + 209, + 214, + 219, + 224, + 229, + 234, + 239, + 244, + 249, + 254, + 259, + 264, + 269, + 274, + 279, + 284, + 289, + 294, + 299, + 304, + 309, + 318, + 331, + 335, + 360, + 366, + 385, + 396, + 437, + 625, + 629, + 694, + 709, + 720, + 738, + 745, + 774, + 784, + 820, + 830, + 908, + 922, + 928, + 987, + 1006, + 1041, + 1090, + 1139, + 1215, + 1242, + 1273, + 1284, + 1330, + 1711, + 1858, + 1882, + 2098, + 2112, + 2121, + 2125, + 2220, + 2241, + 2297, + 2304, + 2315, + 2331, + 2337, + 2348, + 2383, + 2395, + 2401, + 2416, + 2432, + 2625, + 2634, + 2647, + 2656, + 2663, + 2673, + 2779, + 2804, + 2817, + 2833, + 2851, + 2883, + 2917, + 3303, + 3339, + 3352, + 3366, + 3371, + 3376, + 3442, + 3450, + 3458 +}; + +#define T0_INTERPRETED 90 + +#define T0_ENTER(ip, rp, slot) do { \ + const unsigned char *t0_newip; \ + uint32_t t0_lnum; \ + t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ + t0_lnum = t0_parse7E_unsigned(&t0_newip); \ + (rp) += t0_lnum; \ + *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ + (ip) = t0_newip; \ + } while (0) + +#define T0_DEFENTRY(name, slot) \ +void \ +name(void *ctx) \ +{ \ + t0_context *t0ctx = ctx; \ + t0ctx->ip = &t0_codeblock[0]; \ + T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ +} + +T0_DEFENTRY(br_ssl_hs_client_init_main, 175) + +#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) + +void +br_ssl_hs_client_run(void *t0ctx) +{ + uint32_t *dp, *rp; + const unsigned char *ip; + +#define T0_LOCAL(x) (*(rp - 2 - (x))) +#define T0_POP() (*-- dp) +#define T0_POPi() (*(int32_t *)(-- dp)) +#define T0_PEEK(x) (*(dp - 1 - (x))) +#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) +#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) +#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) +#define T0_RPOP() (*-- rp) +#define T0_RPOPi() (*(int32_t *)(-- rp)) +#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) +#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) +#define T0_ROLL(x) do { \ + size_t t0len = (size_t)(x); \ + uint32_t t0tmp = *(dp - 1 - t0len); \ + memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_SWAP() do { \ + uint32_t t0tmp = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_ROT() do { \ + uint32_t t0tmp = *(dp - 3); \ + *(dp - 3) = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_NROT() do { \ + uint32_t t0tmp = *(dp - 1); \ + *(dp - 1) = *(dp - 2); \ + *(dp - 2) = *(dp - 3); \ + *(dp - 3) = t0tmp; \ +} while (0) +#define T0_PICK(x) do { \ + uint32_t t0depth = (x); \ + T0_PUSH(T0_PEEK(t0depth)); \ +} while (0) +#define T0_CO() do { \ + goto t0_exit; \ +} while (0) +#define T0_RET() goto t0_next + + dp = ((t0_context *)t0ctx)->dp; + rp = ((t0_context *)t0ctx)->rp; + ip = ((t0_context *)t0ctx)->ip; + goto t0_next; + for (;;) { + uint32_t t0x; + + t0_next: + t0x = T0_NEXT(&ip); + if (t0x < T0_INTERPRETED) { + switch (t0x) { + int32_t t0off; + + case 0: /* ret */ + t0x = T0_RPOP(); + rp -= (t0x >> 16); + t0x &= 0xFFFF; + if (t0x == 0) { + ip = NULL; + goto t0_exit; + } + ip = &t0_codeblock[t0x]; + break; + case 1: /* literal constant */ + T0_PUSHi(t0_parse7E_signed(&ip)); + break; + case 2: /* read local */ + T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); + break; + case 3: /* write local */ + T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); + break; + case 4: /* jump */ + t0off = t0_parse7E_signed(&ip); + ip += t0off; + break; + case 5: /* jump if */ + t0off = t0_parse7E_signed(&ip); + if (T0_POP()) { + ip += t0off; + } + break; + case 6: /* jump if not */ + t0off = t0_parse7E_signed(&ip); + if (!T0_POP()) { + ip += t0off; + } + break; + case 7: { + /* * */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a * b); + + } + break; + case 8: { + /* + */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a + b); + + } + break; + case 9: { + /* - */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a - b); + + } + break; + case 10: { + /* < */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a < b)); + + } + break; + case 11: { + /* << */ + + int c = (int)T0_POPi(); + uint32_t x = T0_POP(); + T0_PUSH(x << c); + + } + break; + case 12: { + /* <= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a <= b)); + + } + break; + case 13: { + /* <> */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a != b)); + + } + break; + case 14: { + /* = */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a == b)); + + } + break; + case 15: { + /* > */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a > b)); + + } + break; + case 16: { + /* >= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a >= b)); + + } + break; + case 17: { + /* >> */ + + int c = (int)T0_POPi(); + int32_t x = T0_POPi(); + T0_PUSHi(x >> c); + + } + break; + case 18: { + /* anchor-dn-append-name */ + + size_t len; + + len = T0_POP(); + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->append_name( + CTX->client_auth_vtable, ENG->pad, len); + } + + } + break; + case 19: { + /* anchor-dn-end-name */ + + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->end_name( + CTX->client_auth_vtable); + } + + } + break; + case 20: { + /* anchor-dn-end-name-list */ + + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->end_name_list( + CTX->client_auth_vtable); + } + + } + break; + case 21: { + /* anchor-dn-start-name */ + + size_t len; + + len = T0_POP(); + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->start_name( + CTX->client_auth_vtable, len); + } + + } + break; + case 22: { + /* anchor-dn-start-name-list */ + + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->start_name_list( + CTX->client_auth_vtable); + } + + } + break; + case 23: { + /* and */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a & b); + + } + break; + case 24: { + /* begin-cert */ + + if (ENG->chain_len == 0) { + T0_PUSHi(-1); + } else { + ENG->cert_cur = ENG->chain->data; + ENG->cert_len = ENG->chain->data_len; + ENG->chain ++; + ENG->chain_len --; + T0_PUSH(ENG->cert_len); + } + + } + break; + case 25: { + /* bzero */ + + size_t len = (size_t)T0_POP(); + void *addr = (unsigned char *)ENG + (size_t)T0_POP(); + memset(addr, 0, len); + + } + break; + case 26: { + /* can-output? */ + + T0_PUSHi(-(ENG->hlen_out > 0)); + + } + break; + case 27: { + /* co */ + T0_CO(); + } + break; + case 28: { + /* compute-Finished-inner */ + + int prf_id = T0_POP(); + int from_client = T0_POPi(); + unsigned char tmp[48]; + br_tls_prf_seed_chunk seed; + + br_tls_prf_impl prf = br_ssl_engine_get_PRF(ENG, prf_id); + seed.data = tmp; + if (ENG->session.version >= BR_TLS12) { + seed.len = br_multihash_out(&ENG->mhash, prf_id, tmp); + } else { + br_multihash_out(&ENG->mhash, br_md5_ID, tmp); + br_multihash_out(&ENG->mhash, br_sha1_ID, tmp + 16); + seed.len = 36; + } + prf(ENG->pad, 12, ENG->session.master_secret, + sizeof ENG->session.master_secret, + from_client ? "client finished" : "server finished", + 1, &seed); + + } + break; + case 29: { + /* copy-cert-chunk */ + + size_t clen; + + clen = ENG->cert_len; + if (clen > sizeof ENG->pad) { + clen = sizeof ENG->pad; + } + memcpy(ENG->pad, ENG->cert_cur, clen); + ENG->cert_cur += clen; + ENG->cert_len -= clen; + T0_PUSH(clen); + + } + break; + case 30: { + /* copy-protocol-name */ + + size_t idx = T0_POP(); + size_t len = strlen(ENG->protocol_names[idx]); + memcpy(ENG->pad, ENG->protocol_names[idx], len); + T0_PUSH(len); + + } + break; + case 31: { + /* data-get8 */ + + size_t addr = T0_POP(); + T0_PUSH(t0_datablock[addr]); + + } + break; + case 32: { + /* debug-session-ticket */ + + extern void __stdcall OutputDebugStringA(const char *); + extern int sprintf(char *, const char *, ...); + char buf[80]; + size_t len = T0_POP(); + sprintf(buf, "BearSSL: NewSessionTicket received (%u bytes)\r\n", + (unsigned)len); + OutputDebugStringA(buf); + + } + break; + case 33: { + /* discard-input */ + + ENG->hlen_in = 0; + + } + break; + case 34: { + /* do-client-sign */ + + size_t sig_len; + + sig_len = make_client_sign(CTX); + if (sig_len == 0) { + br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM); + T0_CO(); + } + T0_PUSH(sig_len); + + } + break; + case 35: { + /* do-ecdh */ + + unsigned prf_id = T0_POP(); + unsigned ecdhe = T0_POP(); + int x; + + x = make_pms_ecdh(CTX, ecdhe, prf_id); + if (x < 0) { + br_ssl_engine_fail(ENG, -x); + T0_CO(); + } else { + T0_PUSH(x); + } + + } + break; + case 36: { + /* do-rsa-encrypt */ + + int x; + + x = make_pms_rsa(CTX, T0_POP()); + if (x < 0) { + br_ssl_engine_fail(ENG, -x); + T0_CO(); + } else { + T0_PUSH(x); + } + + } + break; + case 37: { + /* do-static-ecdh */ + + unsigned prf_id = T0_POP(); + + if (make_pms_static_ecdh(CTX, prf_id) < 0) { + br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM); + T0_CO(); + } + + } + break; + case 38: { + /* drop */ + (void)T0_POP(); + } + break; + case 39: { + /* dup */ + T0_PUSH(T0_PEEK(0)); + } + break; + case 40: { + /* ext-ALPN-length */ + + size_t u, len; + + if (ENG->protocol_names_num == 0) { + T0_PUSH(0); + T0_RET(); + } + len = 6; + for (u = 0; u < ENG->protocol_names_num; u ++) { + len += 1 + strlen(ENG->protocol_names[u]); + } + T0_PUSH(len); + + } + break; + case 41: { + /* fail */ + + br_ssl_engine_fail(ENG, (int)T0_POPi()); + T0_CO(); + + } + break; + case 42: { + /* flush-record */ + + br_ssl_engine_flush_record(ENG); + + } + break; + case 43: { + /* get-client-chain */ + + uint32_t auth_types; + + auth_types = T0_POP(); + if (CTX->client_auth_vtable != NULL) { + br_ssl_client_certificate ux; + + (*CTX->client_auth_vtable)->choose(CTX->client_auth_vtable, + CTX, auth_types, &ux); + CTX->auth_type = (unsigned char)ux.auth_type; + CTX->hash_id = (unsigned char)ux.hash_id; + ENG->chain = ux.chain; + ENG->chain_len = ux.chain_len; + } else { + CTX->hash_id = 0; + ENG->chain_len = 0; + } + + } + break; + case 44: { + /* get-key-type-usages */ + + const br_x509_class *xc; + const br_x509_pkey *pk; + unsigned usages; + + xc = *(ENG->x509ctx); + pk = xc->get_pkey(ENG->x509ctx, &usages); + if (pk == NULL) { + T0_PUSH(0); + } else { + T0_PUSH(pk->key_type | usages); + } + + } + break; + case 45: { + /* get16 */ + + size_t addr = (size_t)T0_POP(); + T0_PUSH(*(uint16_t *)(void *)((unsigned char *)ENG + addr)); + + } + break; + case 46: { + /* get32 */ + + size_t addr = (size_t)T0_POP(); + T0_PUSH(*(uint32_t *)(void *)((unsigned char *)ENG + addr)); + + } + break; + case 47: { + /* get8 */ + + size_t addr = (size_t)T0_POP(); + T0_PUSH(*((unsigned char *)ENG + addr)); + + } + break; + case 48: { + /* has-input? */ + + T0_PUSHi(-(ENG->hlen_in != 0)); + + } + break; + case 49: { + /* memcmp */ + + size_t len = (size_t)T0_POP(); + void *addr2 = (unsigned char *)ENG + (size_t)T0_POP(); + void *addr1 = (unsigned char *)ENG + (size_t)T0_POP(); + int x = memcmp(addr1, addr2, len); + T0_PUSH((uint32_t)-(x == 0)); + + } + break; + case 50: { + /* memcpy */ + + size_t len = (size_t)T0_POP(); + void *src = (unsigned char *)ENG + (size_t)T0_POP(); + void *dst = (unsigned char *)ENG + (size_t)T0_POP(); + memcpy(dst, src, len); + + } + break; + case 51: { + /* mkrand */ + + size_t len = (size_t)T0_POP(); + void *addr = (unsigned char *)ENG + (size_t)T0_POP(); + br_hmac_drbg_generate(&ENG->rng, addr, len); + + } + break; + case 52: { + /* more-incoming-bytes? */ + + T0_PUSHi(ENG->hlen_in != 0 || !br_ssl_engine_recvrec_finished(ENG)); + + } + break; + case 53: { + /* multihash-init */ + + br_multihash_init(&ENG->mhash); + + } + break; + case 54: { + /* neg */ + + uint32_t a = T0_POP(); + T0_PUSH(-a); + + } + break; + case 55: { + /* not */ + + uint32_t a = T0_POP(); + T0_PUSH(~a); + + } + break; + case 56: { + /* or */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a | b); + + } + break; + case 57: { + /* over */ + T0_PUSH(T0_PEEK(1)); + } + break; + case 58: { + /* peek-hs-msg-type */ + + if (ENG->hlen_in > 0) { + T0_PUSH(*ENG->hbuf_in); + } else { + T0_PUSHi(-1); + } + + } + break; + case 59: { + /* read-chunk-native */ + + size_t clen = ENG->hlen_in; + if (clen > 0) { + uint32_t addr, len; + + len = T0_POP(); + addr = T0_POP(); + if ((size_t)len < clen) { + clen = (size_t)len; + } + memcpy((unsigned char *)ENG + addr, ENG->hbuf_in, clen); + if (ENG->record_type_in == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, ENG->hbuf_in, clen); + } + T0_PUSH(addr + (uint32_t)clen); + T0_PUSH(len - (uint32_t)clen); + ENG->hbuf_in += clen; + ENG->hlen_in -= clen; + } + + } + break; + case 60: { + /* read8-native */ + + if (ENG->hlen_in > 0) { + unsigned char x; + + x = *ENG->hbuf_in ++; + if (ENG->record_type_in == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, &x, 1); + } + T0_PUSH(x); + ENG->hlen_in --; + } else { + T0_PUSHi(-1); + } + + } + break; + case 61: { + /* set-server-curve */ + + const br_x509_class *xc; + const br_x509_pkey *pk; + + xc = *(ENG->x509ctx); + pk = xc->get_pkey(ENG->x509ctx, NULL); + CTX->server_curve = + (pk->key_type == BR_KEYTYPE_EC) ? pk->key.ec.curve : 0; + + } + break; + case 62: { + /* set16 */ + + size_t addr = (size_t)T0_POP(); + *(uint16_t *)(void *)((unsigned char *)ENG + addr) = (uint16_t)T0_POP(); + + } + break; + case 63: { + /* set32 */ + + size_t addr = (size_t)T0_POP(); + *(uint32_t *)(void *)((unsigned char *)ENG + addr) = (uint32_t)T0_POP(); + + } + break; + case 64: { + /* set8 */ + + size_t addr = (size_t)T0_POP(); + *((unsigned char *)ENG + addr) = (unsigned char)T0_POP(); + + } + break; + case 65: { + /* strlen */ + + void *str = (unsigned char *)ENG + (size_t)T0_POP(); + T0_PUSH((uint32_t)strlen(str)); + + } + break; + case 66: { + /* supported-curves */ + + uint32_t x = ENG->iec == NULL ? 0 : ENG->iec->supported_curves; + T0_PUSH(x); + + } + break; + case 67: { + /* supported-hash-functions */ + + int i; + unsigned x, num; + + x = 0; + num = 0; + for (i = br_sha1_ID; i <= br_sha512_ID; i ++) { + if (br_multihash_getimpl(&ENG->mhash, i)) { + x |= 1U << i; + num ++; + } + } + T0_PUSH(x); + T0_PUSH(num); + + } + break; + case 68: { + /* supports-ecdsa? */ + + T0_PUSHi(-(ENG->iecdsa != 0)); + + } + break; + case 69: { + /* supports-rsa-sign? */ + + T0_PUSHi(-(ENG->irsavrfy != 0)); + + } + break; + case 70: { + /* swap */ + T0_SWAP(); + } + break; + case 71: { + /* switch-aesccm-in */ + + int is_client, prf_id; + unsigned cipher_key_len, tag_len; + + tag_len = T0_POP(); + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_ccm_in(ENG, is_client, prf_id, + ENG->iaes_ctrcbc, cipher_key_len, tag_len); + + } + break; + case 72: { + /* switch-aesccm-out */ + + int is_client, prf_id; + unsigned cipher_key_len, tag_len; + + tag_len = T0_POP(); + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_ccm_out(ENG, is_client, prf_id, + ENG->iaes_ctrcbc, cipher_key_len, tag_len); + + } + break; + case 73: { + /* switch-aesgcm-in */ + + int is_client, prf_id; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_gcm_in(ENG, is_client, prf_id, + ENG->iaes_ctr, cipher_key_len); + + } + break; + case 74: { + /* switch-aesgcm-out */ + + int is_client, prf_id; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_gcm_out(ENG, is_client, prf_id, + ENG->iaes_ctr, cipher_key_len); + + } + break; + case 75: { + /* switch-cbc-in */ + + int is_client, prf_id, mac_id, aes; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + aes = T0_POP(); + mac_id = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_cbc_in(ENG, is_client, prf_id, mac_id, + aes ? ENG->iaes_cbcdec : ENG->ides_cbcdec, cipher_key_len); + + } + break; + case 76: { + /* switch-cbc-out */ + + int is_client, prf_id, mac_id, aes; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + aes = T0_POP(); + mac_id = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_cbc_out(ENG, is_client, prf_id, mac_id, + aes ? ENG->iaes_cbcenc : ENG->ides_cbcenc, cipher_key_len); + + } + break; + case 77: { + /* switch-chapol-in */ + + int is_client, prf_id; + + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_chapol_in(ENG, is_client, prf_id); + + } + break; + case 78: { + /* switch-chapol-out */ + + int is_client, prf_id; + + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_chapol_out(ENG, is_client, prf_id); + + } + break; + case 79: { + /* test-protocol-name */ + + size_t len = T0_POP(); + size_t u; + + for (u = 0; u < ENG->protocol_names_num; u ++) { + const char *name; + + name = ENG->protocol_names[u]; + if (len == strlen(name) && memcmp(ENG->pad, name, len) == 0) { + T0_PUSH(u); + T0_RET(); + } + } + T0_PUSHi(-1); + + } + break; + case 80: { + /* total-chain-length */ + + size_t u; + uint32_t total; + + total = 0; + for (u = 0; u < ENG->chain_len; u ++) { + total += 3 + (uint32_t)ENG->chain[u].data_len; + } + T0_PUSH(total); + + } + break; + case 81: { + /* u>> */ + + int c = (int)T0_POPi(); + uint32_t x = T0_POP(); + T0_PUSH(x >> c); + + } + break; + case 82: { + /* verify-SKE-sig */ + + size_t sig_len = T0_POP(); + int use_rsa = T0_POPi(); + int hash = T0_POPi(); + + T0_PUSH(verify_SKE_sig(CTX, hash, use_rsa, sig_len)); + + } + break; + case 83: { + /* write-blob-chunk */ + + size_t clen = ENG->hlen_out; + if (clen > 0) { + uint32_t addr, len; + + len = T0_POP(); + addr = T0_POP(); + if ((size_t)len < clen) { + clen = (size_t)len; + } + memcpy(ENG->hbuf_out, (unsigned char *)ENG + addr, clen); + if (ENG->record_type_out == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, ENG->hbuf_out, clen); + } + T0_PUSH(addr + (uint32_t)clen); + T0_PUSH(len - (uint32_t)clen); + ENG->hbuf_out += clen; + ENG->hlen_out -= clen; + } + + } + break; + case 84: { + /* write8-native */ + + unsigned char x; + + x = (unsigned char)T0_POP(); + if (ENG->hlen_out > 0) { + if (ENG->record_type_out == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, &x, 1); + } + *ENG->hbuf_out ++ = x; + ENG->hlen_out --; + T0_PUSHi(-1); + } else { + T0_PUSHi(0); + } + + } + break; + case 85: { + /* x509-append */ + + const br_x509_class *xc; + size_t len; + + xc = *(ENG->x509ctx); + len = T0_POP(); + xc->append(ENG->x509ctx, ENG->pad, len); + + } + break; + case 86: { + /* x509-end-cert */ + + const br_x509_class *xc; + + xc = *(ENG->x509ctx); + xc->end_cert(ENG->x509ctx); + + } + break; + case 87: { + /* x509-end-chain */ + + const br_x509_class *xc; + + xc = *(ENG->x509ctx); + T0_PUSH(xc->end_chain(ENG->x509ctx)); + + } + break; + case 88: { + /* x509-start-cert */ + + const br_x509_class *xc; + + xc = *(ENG->x509ctx); + xc->start_cert(ENG->x509ctx, T0_POP()); + + } + break; + case 89: { + /* x509-start-chain */ + + const br_x509_class *xc; + uint32_t bc; + + bc = T0_POP(); + xc = *(ENG->x509ctx); + xc->start_chain(ENG->x509ctx, bc ? ENG->server_name : NULL); + + } + break; + } + + } else { + T0_ENTER(ip, rp, t0x); + } + } +t0_exit: + ((t0_context *)t0ctx)->dp = dp; + ((t0_context *)t0ctx)->rp = rp; + ((t0_context *)t0ctx)->ip = ip; +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_hs_client.t0 b/BearSSL-OG/libbearssl/src/ssl/ssl_hs_client.t0 new file mode 100644 index 0000000..69a1d94 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_hs_client.t0 @@ -0,0 +1,1398 @@ +\ Copyright (c) 2016 Thomas Pornin +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +\ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +\ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +\ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +\ SOFTWARE. + +\ ---------------------------------------------------------------------- +\ Handshake processing code, for the client. +\ The common T0 code (ssl_hs_common.t0) shall be read first. + +preamble { + +/* + * This macro evaluates to a pointer to the client context, under that + * specific name. It must be noted that since the engine context is the + * first field of the br_ssl_client_context structure ('eng'), then + * pointers values of both types are interchangeable, modulo an + * appropriate cast. This also means that "addresses" computed as offsets + * within the structure work for both kinds of context. + */ +#define CTX ((br_ssl_client_context *)ENG) + +/* + * Generate the pre-master secret for RSA key exchange, and encrypt it + * with the server's public key. Returned value is either the encrypted + * data length (in bytes), or -x on error, with 'x' being an error code. + * + * This code assumes that the public key has been already verified (it + * was properly obtained by the X.509 engine, and it has the right type, + * i.e. it is of type RSA and suitable for encryption). + */ +static int +make_pms_rsa(br_ssl_client_context *ctx, int prf_id) +{ + const br_x509_class **xc; + const br_x509_pkey *pk; + const unsigned char *n; + unsigned char *pms; + size_t nlen, u; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + + /* + * Compute actual RSA key length, in case there are leading zeros. + */ + n = pk->key.rsa.n; + nlen = pk->key.rsa.nlen; + while (nlen > 0 && *n == 0) { + n ++; + nlen --; + } + + /* + * We need at least 59 bytes (48 bytes for pre-master secret, and + * 11 bytes for the PKCS#1 type 2 padding). Note that the X.509 + * minimal engine normally blocks RSA keys shorter than 128 bytes, + * so this is mostly for public keys provided explicitly by the + * caller. + */ + if (nlen < 59) { + return -BR_ERR_X509_WEAK_PUBLIC_KEY; + } + if (nlen > sizeof ctx->eng.pad) { + return -BR_ERR_LIMIT_EXCEEDED; + } + + /* + * Make PMS. + */ + pms = ctx->eng.pad + nlen - 48; + br_enc16be(pms, ctx->eng.version_max); + br_hmac_drbg_generate(&ctx->eng.rng, pms + 2, 46); + br_ssl_engine_compute_master(&ctx->eng, prf_id, pms, 48); + + /* + * Apply PKCS#1 type 2 padding. + */ + ctx->eng.pad[0] = 0x00; + ctx->eng.pad[1] = 0x02; + ctx->eng.pad[nlen - 49] = 0x00; + br_hmac_drbg_generate(&ctx->eng.rng, ctx->eng.pad + 2, nlen - 51); + for (u = 2; u < nlen - 49; u ++) { + while (ctx->eng.pad[u] == 0) { + br_hmac_drbg_generate(&ctx->eng.rng, + &ctx->eng.pad[u], 1); + } + } + + /* + * Compute RSA encryption. + */ + if (!ctx->irsapub(ctx->eng.pad, nlen, &pk->key.rsa)) { + return -BR_ERR_LIMIT_EXCEEDED; + } + return (int)nlen; +} + +/* + * OID for hash functions in RSA signatures. + */ +static const unsigned char *HASH_OID[] = { + BR_HASH_OID_SHA1, + BR_HASH_OID_SHA224, + BR_HASH_OID_SHA256, + BR_HASH_OID_SHA384, + BR_HASH_OID_SHA512 +}; + +/* + * Check the RSA signature on the ServerKeyExchange message. + * + * hash hash function ID (2 to 6), or 0 for MD5+SHA-1 (with RSA only) + * use_rsa non-zero for RSA signature, zero for ECDSA + * sig_len signature length (in bytes); signature value is in the pad + * + * Returned value is 0 on success, or an error code. + */ +static int +verify_SKE_sig(br_ssl_client_context *ctx, + int hash, int use_rsa, size_t sig_len) +{ + const br_x509_class **xc; + const br_x509_pkey *pk; + br_multihash_context mhc; + unsigned char hv[64], head[4]; + size_t hv_len; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + br_multihash_zero(&mhc); + br_multihash_copyimpl(&mhc, &ctx->eng.mhash); + br_multihash_init(&mhc); + br_multihash_update(&mhc, + ctx->eng.client_random, sizeof ctx->eng.client_random); + br_multihash_update(&mhc, + ctx->eng.server_random, sizeof ctx->eng.server_random); + head[0] = 3; + head[1] = 0; + head[2] = ctx->eng.ecdhe_curve; + head[3] = ctx->eng.ecdhe_point_len; + br_multihash_update(&mhc, head, sizeof head); + br_multihash_update(&mhc, + ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len); + if (hash) { + hv_len = br_multihash_out(&mhc, hash, hv); + if (hv_len == 0) { + return BR_ERR_INVALID_ALGORITHM; + } + } else { + if (!br_multihash_out(&mhc, br_md5_ID, hv) + || !br_multihash_out(&mhc, br_sha1_ID, hv + 16)) + { + return BR_ERR_INVALID_ALGORITHM; + } + hv_len = 36; + } + if (use_rsa) { + unsigned char tmp[64]; + const unsigned char *hash_oid; + + if (hash) { + hash_oid = HASH_OID[hash - 2]; + } else { + hash_oid = NULL; + } + if (!ctx->eng.irsavrfy(ctx->eng.pad, sig_len, + hash_oid, hv_len, &pk->key.rsa, tmp) + || memcmp(tmp, hv, hv_len) != 0) + { + return BR_ERR_BAD_SIGNATURE; + } + } else { + if (!ctx->eng.iecdsa(ctx->eng.iec, hv, hv_len, &pk->key.ec, + ctx->eng.pad, sig_len)) + { + return BR_ERR_BAD_SIGNATURE; + } + } + return 0; +} + +/* + * Perform client-side ECDH (or ECDHE). The point that should be sent to + * the server is written in the pad; returned value is either the point + * length (in bytes), or -x on error, with 'x' being an error code. + * + * The point _from_ the server is taken from ecdhe_point[] if 'ecdhe' + * is non-zero, or from the X.509 engine context if 'ecdhe' is zero + * (for static ECDH). + */ +static int +make_pms_ecdh(br_ssl_client_context *ctx, unsigned ecdhe, int prf_id) +{ + int curve; + unsigned char key[66], point[133]; + const unsigned char *order, *point_src; + size_t glen, olen, point_len, xoff, xlen; + unsigned char mask; + + if (ecdhe) { + curve = ctx->eng.ecdhe_curve; + point_src = ctx->eng.ecdhe_point; + point_len = ctx->eng.ecdhe_point_len; + } else { + const br_x509_class **xc; + const br_x509_pkey *pk; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + curve = pk->key.ec.curve; + point_src = pk->key.ec.q; + point_len = pk->key.ec.qlen; + } + if ((ctx->eng.iec->supported_curves & ((uint32_t)1 << curve)) == 0) { + return -BR_ERR_INVALID_ALGORITHM; + } + + /* + * We need to generate our key, as a non-zero random value which + * is lower than the curve order, in a "large enough" range. We + * force top bit to 0 and bottom bit to 1, which guarantees that + * the value is in the proper range. + */ + order = ctx->eng.iec->order(curve, &olen); + mask = 0xFF; + while (mask >= order[0]) { + mask >>= 1; + } + br_hmac_drbg_generate(&ctx->eng.rng, key, olen); + key[0] &= mask; + key[olen - 1] |= 0x01; + + /* + * Compute the common ECDH point, whose X coordinate is the + * pre-master secret. + */ + ctx->eng.iec->generator(curve, &glen); + if (glen != point_len) { + return -BR_ERR_INVALID_ALGORITHM; + } + + memcpy(point, point_src, glen); + if (!ctx->eng.iec->mul(point, glen, key, olen, curve)) { + return -BR_ERR_INVALID_ALGORITHM; + } + + /* + * The pre-master secret is the X coordinate. + */ + xoff = ctx->eng.iec->xoff(curve, &xlen); + br_ssl_engine_compute_master(&ctx->eng, prf_id, point + xoff, xlen); + + ctx->eng.iec->mulgen(point, key, olen, curve); + memcpy(ctx->eng.pad, point, glen); + return (int)glen; +} + +/* + * Perform full static ECDH. This occurs only in the context of client + * authentication with certificates: the server uses an EC public key, + * the cipher suite is of type ECDH (not ECDHE), the server requested a + * client certificate and accepts static ECDH, the client has a + * certificate with an EC public key in the same curve, and accepts + * static ECDH as well. + * + * Returned value is 0 on success, -1 on error. + */ +static int +make_pms_static_ecdh(br_ssl_client_context *ctx, int prf_id) +{ + unsigned char point[133]; + size_t point_len; + const br_x509_class **xc; + const br_x509_pkey *pk; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + point_len = pk->key.ec.qlen; + if (point_len > sizeof point) { + return -1; + } + memcpy(point, pk->key.ec.q, point_len); + if (!(*ctx->client_auth_vtable)->do_keyx( + ctx->client_auth_vtable, point, &point_len)) + { + return -1; + } + br_ssl_engine_compute_master(&ctx->eng, + prf_id, point, point_len); + return 0; +} + +/* + * Compute the client-side signature. This is invoked only when a + * signature-based client authentication was selected. The computed + * signature is in the pad; its length (in bytes) is returned. On + * error, 0 is returned. + */ +static size_t +make_client_sign(br_ssl_client_context *ctx) +{ + size_t hv_len; + + /* + * Compute hash of handshake messages so far. This "cannot" fail + * because the list of supported hash functions provided to the + * client certificate handler was trimmed to include only the + * hash functions that the multi-hasher supports. + */ + if (ctx->hash_id) { + hv_len = br_multihash_out(&ctx->eng.mhash, + ctx->hash_id, ctx->eng.pad); + } else { + br_multihash_out(&ctx->eng.mhash, + br_md5_ID, ctx->eng.pad); + br_multihash_out(&ctx->eng.mhash, + br_sha1_ID, ctx->eng.pad + 16); + hv_len = 36; + } + return (*ctx->client_auth_vtable)->do_sign( + ctx->client_auth_vtable, ctx->hash_id, hv_len, + ctx->eng.pad, sizeof ctx->eng.pad); +} + +} + +\ ======================================================================= + +: addr-ctx: + next-word { field } + "addr-" field + 0 1 define-word + 0 8191 "offsetof(br_ssl_client_context, " field + ")" + make-CX + postpone literal postpone ; ; + +addr-ctx: min_clienthello_len +addr-ctx: hashes +addr-ctx: auth_type +addr-ctx: hash_id + +\ Length of the Secure Renegotiation extension. This is 5 for the +\ first handshake, 17 for a renegotiation (if the server supports the +\ extension), or 0 if we know that the server does not support the +\ extension. +: ext-reneg-length ( -- n ) + addr-reneg get8 dup if 1 - 17 * else drop 5 then ; + +\ Length of SNI extension. +: ext-sni-length ( -- len ) + addr-server_name strlen dup if 9 + then ; + +\ Length of Maximum Fragment Length extension. +: ext-frag-length ( -- len ) + addr-log_max_frag_len get8 14 = if 0 else 5 then ; + +\ Length of Signatures extension. +: ext-signatures-length ( -- len ) + supported-hash-functions { num } drop 0 + supports-rsa-sign? if num + then + supports-ecdsa? if num + then + dup if 1 << 6 + then ; + +\ Write supported hash functions ( sign -- ) +: write-hashes + { sign } + supported-hash-functions drop + \ We advertise hash functions in the following preference order: + \ SHA-256 SHA-224 SHA-384 SHA-512 SHA-1 + \ Rationale: + \ -- SHA-256 and SHA-224 are more efficient on 32-bit architectures + \ -- SHA-1 is less than ideally collision-resistant + dup 0x10 and if 4 write8 sign write8 then + dup 0x08 and if 3 write8 sign write8 then + dup 0x20 and if 5 write8 sign write8 then + dup 0x40 and if 6 write8 sign write8 then + 0x04 and if 2 write8 sign write8 then ; + +\ Length of Supported Curves extension. +: ext-supported-curves-length ( -- len ) + supported-curves dup if + 0 { x } + begin dup while + dup 1 and x + >x + 1 >> + repeat + drop x 1 << 6 + + then ; + +\ Length of Supported Point Formats extension. +: ext-point-format-length ( -- len ) + supported-curves if 6 else 0 then ; + +\ Length of ALPN extension. +cc: ext-ALPN-length ( -- len ) { + size_t u, len; + + if (ENG->protocol_names_num == 0) { + T0_PUSH(0); + T0_RET(); + } + len = 6; + for (u = 0; u < ENG->protocol_names_num; u ++) { + len += 1 + strlen(ENG->protocol_names[u]); + } + T0_PUSH(len); +} + +\ Length of Session Ticket extension (RFC 5077). +\ Always sent (to signal support). If we have a stored ticket, include it. +: ext-session-ticket-length ( -- len ) + addr-session_ticket_len get16 4 + ; + +\ Write handshake message: ClientHello +: write-ClientHello ( -- ) + { ; total-ext-length } + + \ Compute length for extensions (without the general two-byte header). + \ This does not take padding extension into account. + ext-reneg-length ext-sni-length + ext-frag-length + + ext-signatures-length + + ext-supported-curves-length + ext-point-format-length + + ext-ALPN-length + + ext-session-ticket-length + + >total-ext-length + + \ ClientHello type + 1 write8 + + \ Compute and write length + 39 addr-session_id_len get8 + addr-suites_num get8 1 << + + total-ext-length if 2+ total-ext-length + then + \ Compute padding (if requested). + addr-min_clienthello_len get16 over - dup 0> if + \ We well add a Pad ClientHello extension, which has its + \ own header (4 bytes) and might be the only extension + \ (2 extra bytes for the extension list header). + total-ext-length ifnot swap 2+ swap 2- then + \ Account for the extension header. + 4 - dup 0< if drop 0 then + \ Adjust total extension length. + dup 4 + total-ext-length + >total-ext-length + \ Adjust ClientHello length. + swap 4 + over + swap + else + drop + -1 + then + { ext-padding-amount } + write24 + + \ Protocol version + addr-version_max get16 write16 + + \ Client random + addr-client_random 4 bzero + addr-client_random 4 + 28 mkrand + addr-client_random 32 write-blob + + \ Session ID + addr-session_id addr-session_id_len get8 write-blob-head8 + + \ Supported cipher suites. We also check here that we indeed + \ support all these suites. + addr-suites_num get8 dup 1 << write16 + addr-suites_buf swap + begin + dup while 1- + over get16 + dup suite-supported? ifnot ERR_BAD_CIPHER_SUITE fail then + write16 + swap 2+ swap + repeat + 2drop + + \ Compression methods (only "null" compression) + 1 write8 0 write8 + + \ Extensions + total-ext-length if + total-ext-length write16 + ext-reneg-length if + 0xFF01 write16 \ extension type (0xFF01) + addr-saved_finished + ext-reneg-length 4 - dup write16 \ extension length + 1- write-blob-head8 \ verify data + then + ext-sni-length if + 0x0000 write16 \ extension type (0) + addr-server_name + ext-sni-length 4 - dup write16 \ extension length + 2 - dup write16 \ ServerNameList length + 0 write8 \ name type: host_name + 3 - write-blob-head16 \ the name itself + then + ext-frag-length if + 0x0001 write16 \ extension type (1) + 0x0001 write16 \ extension length + addr-log_max_frag_len get8 8 - write8 + then + ext-signatures-length if + 0x000D write16 \ extension type (13) + ext-signatures-length 4 - dup write16 \ extension length + 2 - write16 \ list length + supports-ecdsa? if 3 write-hashes then + supports-rsa-sign? if 1 write-hashes then + then + \ TODO: add an API to specify preference order for curves. + \ Right now we send Curve25519 first, then other curves in + \ increasing ID values (hence P-256 in second). + ext-supported-curves-length dup if + 0x000A write16 \ extension type (10) + 4 - dup write16 \ extension length + 2- write16 \ list length + supported-curves 0 + dup 0x20000000 and if + 0xDFFFFFFF and 29 write16 + then + begin dup 32 < while + dup2 >> 1 and if dup write16 then + 1+ + repeat + 2drop + else + drop + then + ext-point-format-length if + 0x000B write16 \ extension type (11) + 0x0002 write16 \ extension length + 0x0100 write16 \ value: 1 format: uncompressed + then + ext-ALPN-length dup if + 0x0010 write16 \ extension type (16) + 4 - dup write16 \ extension length + 2- write16 \ list length + addr-protocol_names_num get16 0 + begin + dup2 > while + dup copy-protocol-name + dup write8 addr-pad swap write-blob + 1+ + repeat + 2drop + else + drop + then + \ Session Ticket extension (RFC 5077). + 0x0023 write16 \ extension type (35) + addr-session_ticket_len get16 + dup write16 \ extension data length + dup if + addr-session_ticket swap write-blob + else + drop + then + ext-padding-amount 0< ifnot + 0x0015 write16 \ extension value (21) + ext-padding-amount + dup write16 \ extension length + begin dup while + 1- 0 write8 repeat \ value (only zeros) + drop + then + then + ; + +\ ======================================================================= + +\ Parse server SNI extension. If present, then it should be empty. +: read-server-sni ( lim -- lim ) + read16 if ERR_BAD_SNI fail then ; + +\ Parse server Max Fragment Length extension. If present, then it should +\ advertise the same length as the client. Note that whether the server +\ sends it or not changes nothing for us: we won't send any record larger +\ than the advertised value anyway, and we will accept incoming records +\ up to our input buffer length. +: read-server-frag ( lim -- lim ) + read16 1 = ifnot ERR_BAD_FRAGLEN fail then + read8 8 + addr-log_max_frag_len get8 = ifnot ERR_BAD_FRAGLEN fail then ; + +\ Parse server Secure Renegotiation extension. This is called only if +\ the client sent that extension, so we only have two cases to +\ distinguish: first handshake, and renegotiation; in the latter case, +\ we know that the server supports the extension, otherwise the client +\ would not have sent it. +: read-server-reneg ( lim -- lim ) + read16 + addr-reneg get8 ifnot + \ "reneg" is 0, so this is a first handshake. The server's + \ extension MUST be empty. We also learn that the server + \ supports the extension. + 1 = ifnot ERR_BAD_SECRENEG fail then + read8 0 = ifnot ERR_BAD_SECRENEG fail then + 2 addr-reneg set8 + else + \ "reneg" is non-zero, and we sent an extension, so it must + \ be 2 and this is a renegotiation. We must verify that + \ the extension contents have length exactly 24 bytes and + \ match the saved client and server "Finished". + 25 = ifnot ERR_BAD_SECRENEG fail then + read8 24 = ifnot ERR_BAD_SECRENEG fail then + addr-pad 24 read-blob + addr-saved_finished addr-pad 24 memcmp ifnot + ERR_BAD_SECRENEG fail + then + then ; + +\ Read the ALPN extension from the server. It must contain a single name, +\ and that name must match one of our names. +: read-ALPN-from-server ( lim -- lim ) + \ Extension contents length. + read16 open-elt + \ Length of list of names. + read16 open-elt + \ There should be a single name. + read8 addr-pad swap dup { len } read-blob + close-elt + close-elt + len test-protocol-name dup 0< if + 3 flag? if ERR_UNEXPECTED fail then + drop + else + 1+ addr-selected_protocol set16 + then ; + +\ Save a value in a 16-bit field, or check it in case of session resumption. +: check-resume ( val addr resume -- ) + if get16 = ifnot ERR_RESUME_MISMATCH fail then else set16 then ; + +cc: DEBUG-BLOB ( addr len -- ) { + extern int printf(const char *fmt, ...); + + size_t len = T0_POP(); + unsigned char *buf = (unsigned char *)CTX + T0_POP(); + size_t u; + + printf("BLOB:"); + for (u = 0; u < len; u ++) { + if (u % 16 == 0) { + printf("\n "); + } + printf(" %02x", buf[u]); + } + printf("\n"); +} + +\ Parse incoming ServerHello. Returned value is true (-1) on session +\ resumption. +: read-ServerHello ( -- bool ) + \ Get header, and check message type. + read-handshake-header 2 = ifnot ERR_UNEXPECTED fail then + + \ Get protocol version. + read16 { version } + version addr-version_min get16 < version addr-version_max get16 > or if + ERR_UNSUPPORTED_VERSION fail + then + + \ Enforce chosen version for subsequent records in both directions. + version addr-version_in get16 <> if ERR_BAD_VERSION fail then + version addr-version_out set16 + + \ Server random. + addr-server_random 32 read-blob + + \ The "session resumption" flag. + 0 { resume } + + \ Session ID. + read8 { idlen } + idlen 32 > if ERR_OVERSIZED_ID fail then + addr-pad idlen read-blob + idlen addr-session_id_len get8 = idlen 0 > and if + addr-session_id addr-pad idlen memcmp if + \ Server session ID is non-empty and matches what + \ we sent, so this is a session resumption. + -1 >resume + then + then + addr-session_id addr-pad idlen memcpy + idlen addr-session_id_len set8 + + \ Record version. + version addr-version resume check-resume + + \ Cipher suite. We check that it is part of the list of cipher + \ suites that we advertised. + read16 + dup scan-suite 0< if ERR_BAD_CIPHER_SUITE fail then + \ Also check that the cipher suite is compatible with the + \ announced version: suites that don't use HMAC/SHA-1 are + \ for TLS-1.2 only, not older versions. + dup use-tls12? version 0x0303 < and if ERR_BAD_CIPHER_SUITE fail then + addr-cipher_suite resume check-resume + + \ Compression method. Should be 0 (no compression). + read8 if ERR_BAD_COMPRESSION fail then + + \ Parse extensions (if any). If there is no extension, then the + \ read limit (on the TOS) should be 0 at that point. + dup if + \ Length of extension list. + \ message size. + read16 open-elt + + \ Enumerate extensions. For each of them, check that we + \ sent an extension of that type, and did not see it + \ yet; and then process it. + ext-sni-length { ok-sni } + ext-reneg-length { ok-reneg } + ext-frag-length { ok-frag } + ext-signatures-length { ok-signatures } + ext-supported-curves-length { ok-curves } + ext-point-format-length { ok-points } + ext-session-ticket-length { ok-session-ticket } + ext-ALPN-length { ok-ALPN } + begin dup while + read16 + case + \ Server Name Indication. The server may + \ send such an extension if it uses the SNI + \ from the client, but that "response + \ extension" is supposed to be empty. + 0x0000 of + ok-sni ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-sni + read-server-sni + endof + + \ Max Frag Length. The contents shall be + \ a single byte whose value matches the one + \ sent by the client. + 0x0001 of + ok-frag ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-frag + read-server-frag + endof + + \ Secure Renegotiation. + 0xFF01 of + ok-reneg ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-reneg + read-server-reneg + endof + + \ Signature Algorithms. + \ Normally, the server should never send this + \ extension (so says RFC 5246 #7.4.1.4.1), + \ but some existing servers do. + 0x000D of + ok-signatures ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-signatures + read-ignore-16 + endof + + \ Supported Curves. + 0x000A of + ok-curves ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-curves + read-ignore-16 + endof + + \ Supported Point Formats. + 0x000B of + ok-points ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-points + read-ignore-16 + endof + + \ ALPN. + 0x0010 of + ok-ALPN ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-ALPN + read-ALPN-from-server + endof + + \ Session Ticket (RFC 5077). + 0x0023 of + ok-session-ticket ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-session-ticket + read-ignore-16 + 1 addr-session_ticket_ok set8 + endof + + ERR_EXTRA_EXTENSION fail + endcase + repeat + + \ If we sent a secure renegotiation extension but did not + \ receive a response, then the server does not support + \ secure renegotiation. This is a hard failure if this + \ is a renegotiation. + ok-reneg if + ok-reneg 5 > if ERR_BAD_SECRENEG fail then + 1 addr-reneg set8 + then + close-elt + else + \ No extension received at all, so the server does not + \ support secure renegotiation. This is a hard failure + \ if the server was previously known to support it (i.e. + \ this is a renegotiation). + ext-reneg-length 5 > if ERR_BAD_SECRENEG fail then + 1 addr-reneg set8 + then + close-elt + resume + ; + +cc: set-server-curve ( -- ) { + const br_x509_class *xc; + const br_x509_pkey *pk; + + xc = *(ENG->x509ctx); + pk = xc->get_pkey(ENG->x509ctx, NULL); + CTX->server_curve = + (pk->key_type == BR_KEYTYPE_EC) ? pk->key.ec.curve : 0; +} + +\ Read Certificate message from server. +: read-Certificate-from-server ( -- ) + addr-cipher_suite get16 expected-key-type + -1 read-Certificate + dup 0< if neg fail then + dup ifnot ERR_UNEXPECTED fail then + over and <> if ERR_WRONG_KEY_USAGE fail then + + \ Set server curve (used for static ECDH). + set-server-curve ; + +\ Verify signature on ECDHE point sent by the server. +\ 'hash' is the hash function to use (1 to 6, or 0 for RSA with MD5+SHA-1) +\ 'use-rsa' is 0 for ECDSA, -1 for for RSA +\ 'sig-len' is the signature length (in bytes) +\ The signature itself is in the pad. +cc: verify-SKE-sig ( hash use-rsa sig-len -- err ) { + size_t sig_len = T0_POP(); + int use_rsa = T0_POPi(); + int hash = T0_POPi(); + + T0_PUSH(verify_SKE_sig(CTX, hash, use_rsa, sig_len)); +} + +\ Parse ServerKeyExchange +: read-ServerKeyExchange ( -- ) + \ Get header, and check message type. + read-handshake-header 12 = ifnot ERR_UNEXPECTED fail then + + \ We expect a named curve, and we must support it. + read8 3 = ifnot ERR_INVALID_ALGORITHM fail then + read16 dup addr-ecdhe_curve set8 + dup 32 >= if ERR_INVALID_ALGORITHM fail then + supported-curves swap >> 1 and ifnot ERR_INVALID_ALGORITHM fail then + + \ Read the server point. + read8 + dup 133 > if ERR_INVALID_ALGORITHM fail then + dup addr-ecdhe_point_len set8 + addr-ecdhe_point swap read-blob + + \ If using TLS-1.2+, then the hash function and signature algorithm + \ are explicitly provided; the signature algorithm must match what + \ the cipher suite specifies. With TLS-1.0 and 1.1, the signature + \ algorithm is inferred from the cipher suite, and the hash is + \ either MD5+SHA-1 (for RSA signatures) or SHA-1 (for ECDSA). + addr-version get16 0x0303 >= { tls1.2+ } + addr-cipher_suite get16 use-rsa-ecdhe? { use-rsa } + 2 { hash } + tls1.2+ if + \ Read hash function; accept only the SHA-* identifiers + \ (from SHA-1 to SHA-512, no MD5 here). + read8 + dup dup 2 < swap 6 > or if ERR_INVALID_ALGORITHM fail then + >hash + read8 + \ Get expected signature algorithm and compare with what + \ the server just sent. Expected value is 1 for RSA, 3 + \ for ECDSA. Note that 'use-rsa' evaluates to -1 for RSA, + \ 0 for ECDSA. + use-rsa 1 << 3 + = ifnot ERR_INVALID_ALGORITHM fail then + else + \ For MD5+SHA-1, we set 'hash' to 0. + use-rsa if 0 >hash then + then + + \ Read signature into the pad. + read16 dup { sig-len } + + dup 512 > if ERR_LIMIT_EXCEEDED fail then + addr-pad swap read-blob + + \ Verify signature. + hash use-rsa sig-len verify-SKE-sig + dup if fail then drop + + close-elt ; + +\ Client certificate: start processing of anchor names. +cc: anchor-dn-start-name-list ( -- ) { + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->start_name_list( + CTX->client_auth_vtable); + } +} + +\ Client certificate: start a new anchor DN (length is 16-bit). +cc: anchor-dn-start-name ( length -- ) { + size_t len; + + len = T0_POP(); + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->start_name( + CTX->client_auth_vtable, len); + } +} + +\ Client certificate: push some data for current anchor DN. +cc: anchor-dn-append-name ( length -- ) { + size_t len; + + len = T0_POP(); + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->append_name( + CTX->client_auth_vtable, ENG->pad, len); + } +} + +\ Client certificate: end current anchor DN. +cc: anchor-dn-end-name ( -- ) { + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->end_name( + CTX->client_auth_vtable); + } +} + +\ Client certificate: end list of anchor DN. +cc: anchor-dn-end-name-list ( -- ) { + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->end_name_list( + CTX->client_auth_vtable); + } +} + +\ Client certificate: obtain the client certificate chain. +cc: get-client-chain ( auth_types -- ) { + uint32_t auth_types; + + auth_types = T0_POP(); + if (CTX->client_auth_vtable != NULL) { + br_ssl_client_certificate ux; + + (*CTX->client_auth_vtable)->choose(CTX->client_auth_vtable, + CTX, auth_types, &ux); + CTX->auth_type = (unsigned char)ux.auth_type; + CTX->hash_id = (unsigned char)ux.hash_id; + ENG->chain = ux.chain; + ENG->chain_len = ux.chain_len; + } else { + CTX->hash_id = 0; + ENG->chain_len = 0; + } +} + +\ Parse CertificateRequest. Header has already been read. +: read-contents-CertificateRequest ( lim -- ) + \ Read supported client authentication types. We keep only + \ RSA, ECDSA, and ECDH. + 0 { auth_types } + read8 open-elt + begin dup while + read8 case + 1 of 0x0000FF endof + 64 of 0x00FF00 endof + 65 of 0x010000 endof + 66 of 0x020000 endof + 0 swap + endcase + auth_types or >auth_types + repeat + close-elt + + \ Full static ECDH is allowed only if the cipher suite is ECDH + \ (not ECDHE). It would be theoretically feasible to use static + \ ECDH on the client side with an ephemeral key pair from the + \ server, but RFC 4492 (section 3) forbids it because ECDHE suites + \ are supposed to provide forward secrecy, and static ECDH would + \ negate that property. + addr-cipher_suite get16 use-ecdh? ifnot + auth_types 0xFFFF and >auth_types + then + + \ Note: if the cipher suite is ECDH, then the X.509 validation + \ engine was invoked with the BR_KEYTYPE_EC | BR_KEYTYPE_KEYX + \ combination, so the server's public key has already been + \ checked to be fit for a key exchange. + + \ With TLS 1.2: + \ - rsa_fixed_ecdh and ecdsa_fixed_ecdh are synoymous. + \ - There is an explicit list of supported sign+hash. + \ With TLS 1.0, + addr-version get16 0x0303 >= if + \ With TLS 1.2: + \ - There is an explicit list of supported sign+hash. + \ - The ECDH flags must be adjusted for RSA/ECDSA + \ support. + read-list-sign-algos dup addr-hashes set32 + + \ Trim down the list depending on what hash functions + \ we support (since the hashing itself is done by the SSL + \ engine, not by the certificate handler). + supported-hash-functions drop dup 8 << or 0x030000 or and + + auth_types and + auth_types 0x030000 and if + dup 0x0000FF and if 0x010000 or then + dup 0x00FF00 and if 0x020000 or then + then + >auth_types + else + \ TLS 1.0 or 1.1. The hash function is fixed for signatures + \ (MD5+SHA-1 for RSA, SHA-1 for ECDSA). + auth_types 0x030401 and >auth_types + then + + \ Parse list of anchor DN. + anchor-dn-start-name-list + read16 open-elt + begin dup while + read16 open-elt + dup anchor-dn-start-name + + \ We read the DN by chunks through the pad, so + \ as to use the existing reading function (read-blob) + \ that also ensures proper hashing. + begin + dup while + dup 256 > if 256 else dup then { len } + addr-pad len read-blob + len anchor-dn-append-name + repeat + close-elt + anchor-dn-end-name + repeat + close-elt + anchor-dn-end-name-list + + \ We should have reached the message end. + close-elt + + \ Obtain the client chain. + auth_types get-client-chain + ; + +\ (obsolete) +\ Write an empty Certificate message. +\ : write-empty-Certificate ( -- ) +\ 11 write8 3 write24 0 write24 ; + +cc: do-rsa-encrypt ( prf_id -- nlen ) { + int x; + + x = make_pms_rsa(CTX, T0_POP()); + if (x < 0) { + br_ssl_engine_fail(ENG, -x); + T0_CO(); + } else { + T0_PUSH(x); + } +} + +cc: do-ecdh ( echde prf_id -- ulen ) { + unsigned prf_id = T0_POP(); + unsigned ecdhe = T0_POP(); + int x; + + x = make_pms_ecdh(CTX, ecdhe, prf_id); + if (x < 0) { + br_ssl_engine_fail(ENG, -x); + T0_CO(); + } else { + T0_PUSH(x); + } +} + +cc: do-static-ecdh ( prf-id -- ) { + unsigned prf_id = T0_POP(); + + if (make_pms_static_ecdh(CTX, prf_id) < 0) { + br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM); + T0_CO(); + } +} + +cc: do-client-sign ( -- sig_len ) { + size_t sig_len; + + sig_len = make_client_sign(CTX); + if (sig_len == 0) { + br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM); + T0_CO(); + } + T0_PUSH(sig_len); +} + +\ Write ClientKeyExchange. +: write-ClientKeyExchange ( -- ) + 16 write8 + addr-cipher_suite get16 + dup use-rsa-keyx? if + prf-id do-rsa-encrypt + dup 2+ write24 + dup write16 + addr-pad swap write-blob + else + dup use-ecdhe? swap prf-id do-ecdh + dup 1+ write24 + dup write8 + addr-pad swap write-blob + then ; + +\ Write CertificateVerify. This is invoked only if a client certificate +\ was requested and sent, and the authentication is not full static ECDH. +: write-CertificateVerify ( -- ) + do-client-sign + 15 write8 dup + addr-version get16 0x0303 >= if + 4 + write24 + addr-hash_id get8 write8 + addr-auth_type get8 write8 + else + 2+ write24 + then + dup write16 addr-pad swap write-blob ; + +\ ======================================================================= + +\ Peek at the first byte of the handshake input buffer without consuming +\ it. Returns the byte value, or -1 if the buffer is empty. +cc: peek-hs-msg-type ( -- type ) { + if (ENG->hlen_in > 0) { + T0_PUSH(*ENG->hbuf_in); + } else { + T0_PUSHi(-1); + } +} + +\ Read a NewSessionTicket message (handshake type 4, RFC 5077). +\ Format: uint32 lifetime_hint, opaque ticket<0..2^16-1> +cc: debug-session-ticket ( len -- ) { + extern void __stdcall OutputDebugStringA(const char *); + extern int sprintf(char *, const char *, ...); + char buf[80]; + size_t len = T0_POP(); + sprintf(buf, "BearSSL: NewSessionTicket received (%u bytes)\r\n", + (unsigned)len); + OutputDebugStringA(buf); +} + +: read-NewSessionTicket-message ( -- ) + read-handshake-header 4 = ifnot ERR_UNEXPECTED fail then + \ Skip the 4-byte lifetime_hint. + read16 drop read16 drop + \ Read ticket length, then ticket data. + read16 { tlen } + tlen 1024 > if + \ Ticket too large for our buffer; skip it. + tlen skip-blob + 0 addr-session_ticket_len set16 + else + addr-session_ticket tlen read-blob + tlen addr-session_ticket_len set16 + then + tlen debug-session-ticket + close-elt ; + +\ Read optional NewSessionTicket (RFC 5077) then CCS+Finished. +\ During abbreviated handshakes the server MAY send a renewed ticket +\ before CCS, but it is not guaranteed. We peek at the next record +\ type: if it is a handshake record we read the ticket; if it is CCS +\ we skip straight to read-CCS-Finished. +: read-CCS-Finished-with-ticket ( is-client -- ) + addr-session_ticket_ok get8 if + has-input? if + addr-record_type_in get8 22 = if + read-NewSessionTicket-message + then + else + begin + wait-co 0x07 and + dup 0x01 = if + drop read-NewSessionTicket-message 0 + then + dup 0x02 <> while + dup if ERR_UNEXPECTED fail then + drop + repeat + drop + then + then + read-CCS-Finished ; + +\ Perform a handshake. +: do-handshake ( -- ) + 0 addr-application_data set8 + 22 addr-record_type_out set8 + 0 addr-selected_protocol set16 + 0 addr-session_ticket_ok set8 + multihash-init + + write-ClientHello + flush-record + read-ServerHello + + \ Track whether this is a ticket-based resumption detected by + \ peeking at the next server message (RFC 5077). + 0 { ticket-resume } + + ifnot + \ Not a session ID resumption. Check for ticket-based + \ resumption: if we sent a ticket and the server confirmed + \ ticket support, peek at the next record to decide. + addr-session_ticket_ok get8 + addr-session_ticket_len get16 0 > and if + \ Wait for data from server. + has-input? not if + begin wait-co 0x07 and dup 0= while + drop repeat drop + then + addr-record_type_in get8 20 = if + \ CCS → ticket resumption, no renewed ticket. + -1 >ticket-resume + else + \ Handshake record. Peek at message type. + peek-hs-msg-type 4 = if + \ NewSessionTicket → ticket resumption + \ with a renewed ticket. + read-NewSessionTicket-message + -1 >ticket-resume + then + then + then + else + -1 >ticket-resume + then + + ticket-resume if + \ Session resumption (session-ID or ticket-based). + -1 read-CCS-Finished-with-ticket + -1 write-CCS-Finished + else + \ Full handshake. + + \ Read certificate; then check key type and usages against + \ cipher suite. + read-Certificate-from-server + + \ Depending on cipher suite, we may now expect a + \ ServerKeyExchange. + addr-cipher_suite get16 expected-key-type + CX 0 63 { BR_KEYTYPE_SIGN } and if + read-ServerKeyExchange + then + + \ Get next header. + read-handshake-header + + \ If this is a CertificateRequest, parse it, then read + \ next header. + dup 13 = if + drop read-contents-CertificateRequest + read-handshake-header + -1 + else + 0 + then + { seen-CR } + + \ At that point, we should have a ServerHelloDone, + \ whose length must be 0. + 14 = ifnot ERR_UNEXPECTED fail then + if ERR_BAD_HELLO_DONE fail then + + \ There should not be more bytes in the record at that point. + more-incoming-bytes? if ERR_UNEXPECTED fail then + + seen-CR if + \ If the server requested a client certificate, then + \ we must write a Certificate message (it may be + \ empty). + write-Certificate + + \ If using static ECDH, then the ClientKeyExchange + \ is empty, and there is no CertificateVerify. + \ Otherwise, there is a ClientKeyExchange; there + \ will then be a CertificateVerify if a client chain + \ was indeed sent. + addr-hash_id get8 0xFF = if + drop + 16 write8 0 write24 + addr-cipher_suite get16 prf-id do-static-ecdh + else + write-ClientKeyExchange + if write-CertificateVerify then + then + else + write-ClientKeyExchange + then + + -1 write-CCS-Finished + -1 read-CCS-Finished-with-ticket + then + + \ Now we should be invoked only in case of renegotiation. + 1 addr-application_data set8 + 23 addr-record_type_out set8 ; + +\ Read a HelloRequest message. +: read-HelloRequest ( -- ) + \ A HelloRequest has length 0 and type 0. + read-handshake-header-core + if ERR_UNEXPECTED fail then + if ERR_BAD_HANDSHAKE fail then ; + +\ Entry point. +: main ( -- ! ) + \ Perform initial handshake. + do-handshake + + begin + \ Wait for further invocation. At that point, we should + \ get either an explicit call for renegotiation, or + \ an incoming HelloRequest handshake message. + wait-co + dup 0x07 and case + 0x00 of + 0x10 and if + do-handshake + then + endof + 0x01 of + drop + 0 addr-application_data set8 + read-HelloRequest + \ Reject renegotiations if the peer does not + \ support secure renegotiation, or if the + \ "no renegotiation" flag is set. + addr-reneg get8 1 = 1 flag? or if + flush-record + begin can-output? not while + wait-co drop + repeat + 100 send-warning + \ We rejected the renegotiation, + \ but the connection is not dead. + \ We must set back things into + \ working "application data" state. + 1 addr-application_data set8 + 23 addr-record_type_out set8 + else + do-handshake + then + endof + ERR_UNEXPECTED fail + endcase + again + ; diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_hs_common.t0 b/BearSSL-OG/libbearssl/src/ssl/ssl_hs_common.t0 new file mode 100644 index 0000000..06c3d15 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_hs_common.t0 @@ -0,0 +1,1385 @@ +\ Copyright (c) 2016 Thomas Pornin +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +\ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +\ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +\ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +\ SOFTWARE. + +\ ---------------------------------------------------------------------- +\ This is the common T0 code for processing handshake messages (code that +\ is used by both client and server). + +preamble { + +#include +#include + +#include "inner.h" + +/* + * This macro evaluates to a pointer to the current engine context. + */ +#define ENG ((br_ssl_engine_context *)(void *)((unsigned char *)t0ctx - offsetof(br_ssl_engine_context, cpu))) + +} + +\ IMPLEMENTATION NOTES +\ ==================== +\ +\ This code handles all records except application data records. +\ Application data is accepted (incoming records, outgoing payload data) +\ only when the application_data flag is set, which is done at the end +\ of the handshake; and it is cleared whenever a renegotiation or a +\ closure takes place. +\ +\ Incoming alerts are processed on the fly; fatal alerts terminate the +\ context, while warnings are ignored, except for close_notify, which +\ triggers the closure procedure. That procedure never returns (it ends +\ with an 'ERR_OK fail' call). We can thus make this processing right +\ into the read functions. +\ +\ Specific actions from the caller (closure or renegotiation) may happen +\ only when jumping back into the T0 code, i.e. just after a 'co' call. +\ Similarly, incoming record type may change only while the caller has +\ control, so we need to check that type only when returning from a 'co'. +\ +\ The handshake processor needs to defer back to the caller ('co') only +\ in one of the following situations: +\ +\ -- Some handshake data is expected. +\ +\ -- The handshake is finished, and application data may flow. There may +\ be some incoming handshake data (HelloRequest from the server). This +\ is the only situation where a renegotiation call won't be ignored. +\ +\ -- Some change-cipher-spec data is expected. +\ +\ -- An alert record is expected. Other types of incoming records will be +\ skipped. +\ +\ -- Waiting for the currently accumulated record to be sent and the +\ output buffer to become free again for another record. + +\ Placeholder for handling not yet implemented functionalities. +: NYI ( -- ! ) + "NOT YET IMPLEMENTED!" puts cr -1 fail ; + +\ Debug function that prints a string (and a newline) on stderr. +cc: DBG ( addr -- ) { + extern void *stderr; + extern int fprintf(void *, const char *, ...); + fprintf(stderr, "%s\n", &t0_datablock[T0_POPi()]); +} + +\ Debug function that prints a string and an integer value (followed +\ by a newline) on stderr. +cc: DBG2 ( addr x -- ) { + extern void *stderr; + extern int fprintf(void *, const char *, ...); + int32_t x = T0_POPi(); + fprintf(stderr, "%s: %ld (0x%08lX)\n", + &t0_datablock[T0_POPi()], (long)x, (unsigned long)(uint32_t)x); +} + +\ Mark the context as failed with a specific error code. This also +\ returns control to the caller. +cc: fail ( err -- ! ) { + br_ssl_engine_fail(ENG, (int)T0_POPi()); + T0_CO(); +} + +\ Read a byte from the context (address is offset in context). +cc: get8 ( addr -- val ) { + size_t addr = (size_t)T0_POP(); + T0_PUSH(*((unsigned char *)ENG + addr)); +} + +\ Read a 16-bit word from the context (address is offset in context). +cc: get16 ( addr -- val ) { + size_t addr = (size_t)T0_POP(); + T0_PUSH(*(uint16_t *)(void *)((unsigned char *)ENG + addr)); +} + +\ Read a 32-bit word from the context (address is offset in context). +cc: get32 ( addr -- val ) { + size_t addr = (size_t)T0_POP(); + T0_PUSH(*(uint32_t *)(void *)((unsigned char *)ENG + addr)); +} + +\ Set a byte in the context (address is offset in context). +cc: set8 ( val addr -- ) { + size_t addr = (size_t)T0_POP(); + *((unsigned char *)ENG + addr) = (unsigned char)T0_POP(); +} + +\ Set a 16-bit word in the context (address is offset in context). +cc: set16 ( val addr -- ) { + size_t addr = (size_t)T0_POP(); + *(uint16_t *)(void *)((unsigned char *)ENG + addr) = (uint16_t)T0_POP(); +} + +\ Set a 32-bit word in the context (address is offset in context). +cc: set32 ( val addr -- ) { + size_t addr = (size_t)T0_POP(); + *(uint32_t *)(void *)((unsigned char *)ENG + addr) = (uint32_t)T0_POP(); +} + +\ Define a word that evaluates as an address of a field within the +\ engine context. The field name (C identifier) must follow in the +\ source. For field 'foo', the defined word is 'addr-foo'. +: addr-eng: + next-word { field } + "addr-" field + 0 1 define-word + 0 8191 "offsetof(br_ssl_engine_context, " field + ")" + make-CX + postpone literal postpone ; ; + +addr-eng: max_frag_len +addr-eng: log_max_frag_len +addr-eng: peer_log_max_frag_len +addr-eng: shutdown_recv +addr-eng: record_type_in +addr-eng: record_type_out +addr-eng: version_in +addr-eng: version_out +addr-eng: application_data +addr-eng: version_min +addr-eng: version_max +addr-eng: suites_buf +addr-eng: suites_num +addr-eng: server_name +addr-eng: client_random +addr-eng: server_random +addr-eng: ecdhe_curve +addr-eng: ecdhe_point +addr-eng: ecdhe_point_len +addr-eng: reneg +addr-eng: saved_finished +addr-eng: flags +addr-eng: pad +addr-eng: action +addr-eng: alert +addr-eng: close_received +addr-eng: protocol_names_num +addr-eng: selected_protocol +addr-eng: session_ticket_ok + +\ Similar to 'addr-eng:', for fields in the 'session' substructure. +: addr-session-field: + next-word { field } + "addr-" field + 0 1 define-word + 0 8191 "offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, " field + ")" + make-CX + postpone literal postpone ; ; + +addr-session-field: session_id +addr-session-field: session_id_len +addr-session-field: version +addr-session-field: cipher_suite +addr-session-field: master_secret +addr-session-field: session_ticket +addr-session-field: session_ticket_len + +\ Check a server flag by index. +: flag? ( index -- bool ) + addr-flags get32 swap >> 1 and neg ; + +\ Define a word that evaluates to an error constant. This assumes that +\ all relevant error codes are in the 0..63 range. +: err: + next-word { name } + name 0 1 define-word + 0 63 "BR_" name + make-CX postpone literal postpone ; ; + +err: ERR_OK +err: ERR_BAD_PARAM +err: ERR_BAD_STATE +err: ERR_UNSUPPORTED_VERSION +err: ERR_BAD_VERSION +err: ERR_BAD_LENGTH +err: ERR_TOO_LARGE +err: ERR_BAD_MAC +err: ERR_NO_RANDOM +err: ERR_UNKNOWN_TYPE +err: ERR_UNEXPECTED +err: ERR_BAD_CCS +err: ERR_BAD_ALERT +err: ERR_BAD_HANDSHAKE +err: ERR_OVERSIZED_ID +err: ERR_BAD_CIPHER_SUITE +err: ERR_BAD_COMPRESSION +err: ERR_BAD_FRAGLEN +err: ERR_BAD_SECRENEG +err: ERR_EXTRA_EXTENSION +err: ERR_BAD_SNI +err: ERR_BAD_HELLO_DONE +err: ERR_LIMIT_EXCEEDED +err: ERR_BAD_FINISHED +err: ERR_RESUME_MISMATCH +err: ERR_INVALID_ALGORITHM +err: ERR_BAD_SIGNATURE +err: ERR_WRONG_KEY_USAGE +err: ERR_NO_CLIENT_AUTH + +\ Get supported curves (bit mask). +cc: supported-curves ( -- x ) { + uint32_t x = ENG->iec == NULL ? 0 : ENG->iec->supported_curves; + T0_PUSH(x); +} + +\ Get supported hash functions (bit mask and number). +\ Note: this (on purpose) skips MD5. +cc: supported-hash-functions ( -- x num ) { + int i; + unsigned x, num; + + x = 0; + num = 0; + for (i = br_sha1_ID; i <= br_sha512_ID; i ++) { + if (br_multihash_getimpl(&ENG->mhash, i)) { + x |= 1U << i; + num ++; + } + } + T0_PUSH(x); + T0_PUSH(num); +} + +\ Test support for RSA signatures. +cc: supports-rsa-sign? ( -- bool ) { + T0_PUSHi(-(ENG->irsavrfy != 0)); +} + +\ Test support for ECDSA signatures. +cc: supports-ecdsa? ( -- bool ) { + T0_PUSHi(-(ENG->iecdsa != 0)); +} + +\ (Re)initialise the multihasher. +cc: multihash-init ( -- ) { + br_multihash_init(&ENG->mhash); +} + +\ Flush the current record: if some payload data has been accumulated, +\ close the record and schedule it for sending. If there is no such data, +\ this function does nothing. +cc: flush-record ( -- ) { + br_ssl_engine_flush_record(ENG); +} + +\ Yield control to the caller. +\ When the control is returned to us, react to the new context. Returned +\ value is a bitwise combination of the following: +\ 0x01 handshake data is available +\ 0x02 change-cipher-spec data is available +\ 0x04 some data other than handshake or change-cipher-spec is available +\ 0x08 output buffer is ready for a new outgoing record +\ 0x10 renegotiation is requested and not to be ignored +\ Flags 0x01, 0x02 and 0x04 are mutually exclusive. +: wait-co ( -- state ) + co + 0 + addr-action get8 dup if + case + 1 of 0 do-close endof + 2 of addr-application_data get8 1 = if + 0x10 or + then endof + endcase + else + drop + then + addr-close_received get8 ifnot + has-input? if + addr-record_type_in get8 case + + \ ChangeCipherSpec + 20 of 0x02 or endof + + \ Alert -- if close_notify received, trigger + \ the closure sequence. + 21 of process-alerts if -1 do-close then endof + + \ Handshake + 22 of 0x01 or endof + + \ Not CCS, Alert or Handshake. + drop 0x04 or 0 + endcase + then + then + can-output? if 0x08 or then ; + +\ Send an alert message. This shall be called only when there is room for +\ an outgoing record. +: send-alert ( level alert -- ) + 21 addr-record_type_out set8 + swap write8-native drop write8-native drop + flush-record ; + +\ Send an alert message of level "warning". This shall be called only when +\ there is room for an outgoing record. +: send-warning ( alert -- ) + 1 swap send-alert ; + +\ Fail by sending a fatal alert. +: fail-alert ( alert -- ! ) + { alert } + flush-record + begin can-output? not while wait-co drop repeat + 2 alert send-alert + begin can-output? not while wait-co drop repeat + alert 512 + fail ; + +\ Perform the close operation: +\ -- Prevent new application data from the caller. +\ -- Incoming data is discarded (except alerts). +\ -- Outgoing data is flushed. +\ -- A close_notify alert is sent. +\ -- If 'cnr' is zero, then incoming data is discarded until a close_notify +\ is received. +\ -- At the end, the context is terminated. +\ +\ cnr shall be either 0 or -1. +: do-close ( cnr -- ! ) + \ 'cnr' is set to non-zero when a close_notify is received from + \ the peer. + { cnr } + + \ Get out of application data state. If we were accepting + \ application data (flag is 1), and we still expect a close_notify + \ from the peer (cnr is 0), then we should set the flag to 2. + \ In all other cases, flag should be set to 0. + addr-application_data get8 cnr not and 1 << addr-application_data set8 + + \ Flush existing payload if any. + flush-record + + \ Wait for room to send the close_notify. Since individual records + \ can always hold at least 512 bytes, we know that when there is + \ room, then there is room for a complete close_notify (two bytes). + begin can-output? not while cnr wait-for-close >cnr repeat + + \ Write the close_notify and flush it. + \ 21 addr-record_type_out set8 + \ 1 write8-native 0 write8-native 2drop + \ flush-record + 0 send-warning + + \ Loop until our record has been sent (we know it's gone when + \ writing is again possible) and a close_notify has been received. + cnr + begin + dup can-output? and if ERR_OK fail then + wait-for-close + again ; + +\ Yield control to the engine, with a possible flush. If 'cnr' is 0, +\ then input is analysed: all input is discarded, until a close_notify +\ is received. +: wait-for-close ( cnr -- cnr ) + co + dup ifnot + has-input? if + addr-record_type_in get8 21 = if + drop process-alerts + \ If we received a close_notify then we + \ no longer accept incoming application + \ data records. + 0 addr-application_data set8 + else + discard-input + then + then + then ; + +\ Test whether there is some accumulated payload that still needs to be +\ sent. +cc: payload-to-send? ( -- bool ) { + T0_PUSHi(-br_ssl_engine_has_pld_to_send(ENG)); +} + +\ Test whether there is some available input data. +cc: has-input? ( -- bool ) { + T0_PUSHi(-(ENG->hlen_in != 0)); +} + +\ Test whether some payload bytes may be written. +cc: can-output? ( -- bool ) { + T0_PUSHi(-(ENG->hlen_out > 0)); +} + +\ Discard current input entirely. +cc: discard-input ( -- ) { + ENG->hlen_in = 0; +} + +\ Low-level read for one byte. If there is no available byte right +\ away, then -1 is returned. Otherwise, the byte value is returned. +\ If the current record type is "handshake" then the read byte is also +\ injected in the multi-hasher. +cc: read8-native ( -- x ) { + if (ENG->hlen_in > 0) { + unsigned char x; + + x = *ENG->hbuf_in ++; + if (ENG->record_type_in == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, &x, 1); + } + T0_PUSH(x); + ENG->hlen_in --; + } else { + T0_PUSHi(-1); + } +} + +\ Low-level read for several bytes. On entry, this expects an address +\ (offset in the engine context) and a length; these values designate +\ where the chunk should go. Upon exit, the new address and length +\ are pushed; that output length contains how many bytes could not be +\ read. If there is no available byte for reading, the address and +\ length are unchanged. +\ If the current record type is "handshake" then the read bytes are +\ injected in the multi-hasher. +cc: read-chunk-native ( addr len -- addr len ) { + size_t clen = ENG->hlen_in; + if (clen > 0) { + uint32_t addr, len; + + len = T0_POP(); + addr = T0_POP(); + if ((size_t)len < clen) { + clen = (size_t)len; + } + memcpy((unsigned char *)ENG + addr, ENG->hbuf_in, clen); + if (ENG->record_type_in == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, ENG->hbuf_in, clen); + } + T0_PUSH(addr + (uint32_t)clen); + T0_PUSH(len - (uint32_t)clen); + ENG->hbuf_in += clen; + ENG->hlen_in -= clen; + } +} + +\ Process available alert bytes. If a fatal alert is received, then the +\ context is terminated; otherwise, this returns either true (-1) if a +\ close_notify was received, false (0) otherwise. +: process-alerts ( -- bool ) + 0 + begin has-input? while read8-native process-alert-byte or repeat + dup if 1 addr-shutdown_recv set8 then ; + +\ Process an alert byte. Returned value is non-zero if this is a close_notify, +\ zero otherwise. +: process-alert-byte ( x -- bool ) + addr-alert get8 case + 0 of + \ 'alert' field is 0, so this byte shall be a level. + \ Levels shall be 1 (warning) or 2 (fatal); we convert + \ all other values to "fatal". + dup 1 <> if drop 2 then + addr-alert set8 0 + endof + 1 of + 0 addr-alert set8 + \ close_notify has value 0. + \ no_renegotiation has value 100, and we treat it + \ as a fatal alert. + dup 100 = if 256 + fail then + 0= + endof + \ Fatal alert implies context termination. + drop 256 + fail + endcase ; + +\ In general we only deal with handshake data here. Alerts are processed +\ in specific code right when they are received, and ChangeCipherSpec has +\ its own handling code. So we need to check that the data is "handshake" +\ only when returning from a coroutine call. + +\ Yield control to the engine. Alerts are processed; if incoming data is +\ neither handshake or alert, then an error is triggered. +: wait-for-handshake ( -- ) + wait-co 0x07 and 0x01 > if ERR_UNEXPECTED fail then ; + +\ Flush outgoing data (if any), then wait for the output buffer to be +\ clear; when this is done, set the output record type to the specified +\ value. +: wait-rectype-out ( rectype -- ) + { rectype } + flush-record + begin + can-output? if rectype addr-record_type_out set8 ret then + wait-co drop + again ; + +\ Read one byte of handshake data. Block until that byte is available. +\ This does not check any length. +: read8-nc ( -- x ) + begin + read8-native dup 0< ifnot ret then + drop wait-for-handshake + again ; + +\ Test whether there are some more bytes in the current record. These +\ bytes have not necessarily been received yet (processing of unencrypted +\ records may begin before all bytes are received). +cc: more-incoming-bytes? ( -- bool ) { + T0_PUSHi(ENG->hlen_in != 0 || !br_ssl_engine_recvrec_finished(ENG)); +} + +\ For reading functions, the TOS is supposed to contain the number of bytes +\ that can still be read (from encapsulating structure header), and it is +\ updated. + +: check-len ( lim len -- lim ) + - dup 0< if ERR_BAD_PARAM fail then ; + +\ Read one byte of handshake data. This pushes an integer in the 0..255 range. +: read8 ( lim -- lim x ) + 1 check-len read8-nc ; + +\ Read a 16-bit value (in the 0..65535 range) +: read16 ( lim -- lim n ) + 2 check-len read8-nc 8 << read8-nc + ; + +\ Read a 24-bit value (in the 0..16777215 range) +: read24 ( lim -- lim n ) + 3 check-len read8-nc 8 << read8-nc + 8 << read8-nc + ; + +\ Read some bytes. The "address" is an offset within the context +\ structure. +: read-blob ( lim addr len -- lim ) + { addr len } + len check-len + addr len + begin + read-chunk-native + dup 0 = if 2drop ret then + wait-for-handshake + again ; + +\ Read some bytes and drop them. +: skip-blob ( lim len -- lim ) + swap over check-len swap + begin dup while read8-nc drop 1- repeat + drop ; + +\ Read a 16-bit length, then skip exactly that many bytes. +: read-ignore-16 ( lim -- lim ) + read16 skip-blob ; + +\ Open a substructure: the inner structure length is checked against, +\ and subtracted, from the output structure current limit. +: open-elt ( lim len -- lim-outer lim-inner ) + dup { len } + - dup 0< if ERR_BAD_PARAM fail then + len ; + +\ Close the current structure. This checks that the limit is 0. +: close-elt ( lim -- ) + if ERR_BAD_PARAM fail then ; + +\ Write one byte of handshake data. +: write8 ( n -- ) + begin + dup write8-native if drop ret then + wait-co drop + again ; + +\ Low-level write for one byte. On exit, it pushes either -1 (byte was +\ written) or 0 (no room in output buffer). +cc: write8-native ( x -- bool ) { + unsigned char x; + + x = (unsigned char)T0_POP(); + if (ENG->hlen_out > 0) { + if (ENG->record_type_out == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, &x, 1); + } + *ENG->hbuf_out ++ = x; + ENG->hlen_out --; + T0_PUSHi(-1); + } else { + T0_PUSHi(0); + } +} + +\ Write a 16-bit value. +: write16 ( n -- ) + dup 8 u>> write8 write8 ; + +\ Write a 24-bit value. +: write24 ( n -- ) + dup 16 u>> write8 write16 ; + +\ Write some bytes. The "address" is an offset within the context +\ structure. +: write-blob ( addr len -- ) + begin + write-blob-chunk + dup 0 = if 2drop ret then + wait-co drop + again ; + +cc: write-blob-chunk ( addr len -- addr len ) { + size_t clen = ENG->hlen_out; + if (clen > 0) { + uint32_t addr, len; + + len = T0_POP(); + addr = T0_POP(); + if ((size_t)len < clen) { + clen = (size_t)len; + } + memcpy(ENG->hbuf_out, (unsigned char *)ENG + addr, clen); + if (ENG->record_type_out == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, ENG->hbuf_out, clen); + } + T0_PUSH(addr + (uint32_t)clen); + T0_PUSH(len - (uint32_t)clen); + ENG->hbuf_out += clen; + ENG->hlen_out -= clen; + } +} + +\ Write a blob with the length as header (over one byte) +: write-blob-head8 ( addr len -- ) + dup write8 write-blob ; + +\ Write a blob with the length as header (over two bytes) +: write-blob-head16 ( addr len -- ) + dup write16 write-blob ; + +\ Perform a byte-to-byte comparison between two blobs. Each blob is +\ provided as an "address" (offset in the context structure); the +\ length is common. Returned value is true (-1) if the two blobs are +\ equal, false (0) otherwise. +cc: memcmp ( addr1 addr2 len -- bool ) { + size_t len = (size_t)T0_POP(); + void *addr2 = (unsigned char *)ENG + (size_t)T0_POP(); + void *addr1 = (unsigned char *)ENG + (size_t)T0_POP(); + int x = memcmp(addr1, addr2, len); + T0_PUSH((uint32_t)-(x == 0)); +} + +\ Copy bytes between two areas, whose addresses are provided as +\ offsets in the context structure. +cc: memcpy ( dst src len -- ) { + size_t len = (size_t)T0_POP(); + void *src = (unsigned char *)ENG + (size_t)T0_POP(); + void *dst = (unsigned char *)ENG + (size_t)T0_POP(); + memcpy(dst, src, len); +} + +\ Get string length (zero-terminated). The string address is provided as +\ an offset relative to the context start. Returned length does not include +\ the terminated 0. +cc: strlen ( str -- len ) { + void *str = (unsigned char *)ENG + (size_t)T0_POP(); + T0_PUSH((uint32_t)strlen(str)); +} + +\ Fill a buffer with zeros. The buffer address is an offset in the context. +cc: bzero ( addr len -- ) { + size_t len = (size_t)T0_POP(); + void *addr = (unsigned char *)ENG + (size_t)T0_POP(); + memset(addr, 0, len); +} + +\ Scan the list of supported cipher suites for a given value. If found, +\ then the list index at which it was found is returned; otherwise, -1 +\ is returned. +: scan-suite ( suite -- index ) + { suite } + addr-suites_num get8 { num } + 0 + begin dup num < while + dup 1 << addr-suites_buf + get16 suite = if ret then + 1+ + repeat + drop -1 ; + +\ ======================================================================= + +\ Generate random bytes into buffer (address is offset in context). +cc: mkrand ( addr len -- ) { + size_t len = (size_t)T0_POP(); + void *addr = (unsigned char *)ENG + (size_t)T0_POP(); + br_hmac_drbg_generate(&ENG->rng, addr, len); +} + +\ Read a handshake message header: type and length. These are returned +\ in reverse order (type is TOS, length is below it). +: read-handshake-header-core ( -- lim type ) + read8-nc 3 read24 swap drop swap ; + +\ Read a handshake message header: type and length. If the header is for +\ a HelloRequest message, then it is discarded and a new header is read +\ (repeatedly if necessary). +: read-handshake-header ( -- lim type ) + begin + read-handshake-header-core dup 0= while + drop if ERR_BAD_HANDSHAKE fail then + repeat ; + +\ ======================================================================= + +\ Cipher suite processing. +\ +\ Unfortunately, cipher suite identifiers are attributed mostly arbitrary, +\ so we have to map the cipher suite numbers we support into aggregate +\ words that encode the information we need. Table below is organized +\ as a sequence of pairs of 16-bit words, the first being the cipher suite +\ identifier, the second encoding the algorithm elements. The suites are +\ ordered by increasing cipher suite ID, so that fast lookups may be +\ performed with a binary search (not implemented for the moment, since it +\ does not appear to matter much in practice). +\ +\ Algorithm elements are encoded over 4 bits each, in the following order +\ (most significant to least significant): +\ +\ -- Server key type: +\ 0 RSA (RSA key exchange) +\ 1 ECDHE-RSA (ECDHE key exchange, RSA signature) +\ 2 ECDHE-ECDSA (ECDHE key exchange, ECDSA signature) +\ 3 ECDH-RSA (ECDH key exchange, certificate is RSA-signed) +\ 4 ECDH-ECDSA (ECDH key exchange, certificate is ECDSA-signed) +\ -- Encryption algorithm: +\ 0 3DES/CBC +\ 1 AES-128/CBC +\ 2 AES-256/CBC +\ 3 AES-128/GCM +\ 4 AES-256/GCM +\ 5 ChaCha20/Poly1305 +\ 6 AES-128/CCM +\ 7 AES-256/CCM +\ 8 AES-128/CCM8 +\ 9 AES-256/CCM8 +\ -- MAC algorithm: +\ 0 none (for suites with AEAD encryption) +\ 2 HMAC/SHA-1 +\ 4 HMAC/SHA-256 +\ 5 HMAC/SHA-384 +\ -- PRF for TLS-1.2: +\ 4 with SHA-256 +\ 5 with SHA-384 +\ +\ WARNING: if adding a new cipher suite that does not use SHA-256 for the +\ PRF (with TLS 1.2), be sure to check the suites_sha384[] array defined +\ in ssl/ssl_keyexport.c + +data: cipher-suite-def + +hexb| 000A 0024 | \ TLS_RSA_WITH_3DES_EDE_CBC_SHA +hexb| 002F 0124 | \ TLS_RSA_WITH_AES_128_CBC_SHA +hexb| 0035 0224 | \ TLS_RSA_WITH_AES_256_CBC_SHA +hexb| 003C 0144 | \ TLS_RSA_WITH_AES_128_CBC_SHA256 +hexb| 003D 0244 | \ TLS_RSA_WITH_AES_256_CBC_SHA256 + +hexb| 009C 0304 | \ TLS_RSA_WITH_AES_128_GCM_SHA256 +hexb| 009D 0405 | \ TLS_RSA_WITH_AES_256_GCM_SHA384 + +hexb| C003 4024 | \ TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA +hexb| C004 4124 | \ TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA +hexb| C005 4224 | \ TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA +hexb| C008 2024 | \ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA +hexb| C009 2124 | \ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA +hexb| C00A 2224 | \ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA +hexb| C00D 3024 | \ TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA +hexb| C00E 3124 | \ TLS_ECDH_RSA_WITH_AES_128_CBC_SHA +hexb| C00F 3224 | \ TLS_ECDH_RSA_WITH_AES_256_CBC_SHA +hexb| C012 1024 | \ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA +hexb| C013 1124 | \ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA +hexb| C014 1224 | \ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + +hexb| C023 2144 | \ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 +hexb| C024 2255 | \ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 +hexb| C025 4144 | \ TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 +hexb| C026 4255 | \ TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 +hexb| C027 1144 | \ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 +hexb| C028 1255 | \ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 +hexb| C029 3144 | \ TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 +hexb| C02A 3255 | \ TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 +hexb| C02B 2304 | \ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 +hexb| C02C 2405 | \ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 +hexb| C02D 4304 | \ TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 +hexb| C02E 4405 | \ TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 +hexb| C02F 1304 | \ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 +hexb| C030 1405 | \ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 +hexb| C031 3304 | \ TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 +hexb| C032 3405 | \ TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + +hexb| C09C 0604 | \ TLS_RSA_WITH_AES_128_CCM +hexb| C09D 0704 | \ TLS_RSA_WITH_AES_256_CCM +hexb| C0A0 0804 | \ TLS_RSA_WITH_AES_128_CCM_8 +hexb| C0A1 0904 | \ TLS_RSA_WITH_AES_256_CCM_8 +hexb| C0AC 2604 | \ TLS_ECDHE_ECDSA_WITH_AES_128_CCM +hexb| C0AD 2704 | \ TLS_ECDHE_ECDSA_WITH_AES_256_CCM +hexb| C0AE 2804 | \ TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 +hexb| C0AF 2904 | \ TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 + +hexb| CCA8 1504 | \ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 +hexb| CCA9 2504 | \ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + +hexb| 0000 | \ List terminator. + +\ Convert cipher suite identifier to element words. This returns 0 if +\ the cipher suite is not known. +: cipher-suite-to-elements ( suite -- elts ) + { id } + cipher-suite-def + begin + dup 2+ swap data-get16 + dup ifnot 2drop 0 ret then + id = if data-get16 ret then + 2+ + again ; + +\ Check that a given cipher suite is supported. Note that this also +\ returns true (-1) for the TLS_FALLBACK_SCSV pseudo-ciphersuite. +: suite-supported? ( suite -- bool ) + dup 0x5600 = if drop -1 ret then + cipher-suite-to-elements 0<> ; + +\ Get expected key type for cipher suite. The key type is one of +\ BR_KEYTYPE_RSA or BR_KEYTYPE_EC, combined with either BR_KEYTYPE_KEYX +\ (RSA encryption or static ECDH) or BR_KEYTYPE_SIGN (RSA or ECDSA +\ signature, for ECDHE cipher suites). +: expected-key-type ( suite -- key-type ) + cipher-suite-to-elements 12 >> + case + 0 of CX 0 63 { BR_KEYTYPE_RSA | BR_KEYTYPE_KEYX } endof + 1 of CX 0 63 { BR_KEYTYPE_RSA | BR_KEYTYPE_SIGN } endof + 2 of CX 0 63 { BR_KEYTYPE_EC | BR_KEYTYPE_SIGN } endof + 3 of CX 0 63 { BR_KEYTYPE_EC | BR_KEYTYPE_KEYX } endof + 4 of CX 0 63 { BR_KEYTYPE_EC | BR_KEYTYPE_KEYX } endof + 0 swap + endcase ; + +\ Test whether the cipher suite uses RSA key exchange. +: use-rsa-keyx? ( suite -- bool ) + cipher-suite-to-elements 12 >> 0= ; + +\ Test whether the cipher suite uses ECDHE key exchange, signed with RSA. +: use-rsa-ecdhe? ( suite -- bool ) + cipher-suite-to-elements 12 >> 1 = ; + +\ Test whether the cipher suite uses ECDHE key exchange, signed with ECDSA. +: use-ecdsa-ecdhe? ( suite -- bool ) + cipher-suite-to-elements 12 >> 2 = ; + +\ Test whether the cipher suite uses ECDHE key exchange (with RSA or ECDSA). +: use-ecdhe? ( suite -- bool ) + cipher-suite-to-elements 12 >> dup 0> swap 3 < and ; + +\ Test whether the cipher suite uses ECDH (static) key exchange. +: use-ecdh? ( suite -- bool ) + cipher-suite-to-elements 12 >> 2 > ; + +\ Get identifier for the PRF (TLS 1.2). +: prf-id ( suite -- id ) + cipher-suite-to-elements 15 and ; + +\ Test whether a cipher suite is only for TLS-1.2. Cipher suites that +\ can be used with TLS-1.0 or 1.1 use HMAC/SHA-1. RFC do not formally +\ forbid using a CBC-based TLS-1.2 cipher suite, e.g. based on HMAC/SHA-256, +\ with older protocol versions; however, servers should not do that, since +\ it may confuse clients. Since the server code does not try such games, +\ for consistency, the client should reject it as well (normal servers +\ don't do that, so any attempt is a sign of foul play). +: use-tls12? ( suite -- bool ) + cipher-suite-to-elements 0xF0 and 0x20 <> ; + +\ Switch to negotiated security parameters for input or output. +: switch-encryption ( is-client for-input -- ) + { for-input } + addr-cipher_suite get16 cipher-suite-to-elements { elts } + + \ prf_id + elts 15 and + + \ mac_id + elts 4 >> 15 and + + \ cipher type and key length + elts 8 >> 15 and case + \ 3DES/CBC + 0 of 0 24 + for-input if + switch-cbc-in + else + switch-cbc-out + then + endof + + \ AES-128/CBC + 1 of 1 16 + for-input if + switch-cbc-in + else + switch-cbc-out + then + endof + + \ AES-256/CBC + 2 of 1 32 + for-input if + switch-cbc-in + else + switch-cbc-out + then + endof + + \ AES-128/GCM + 3 of drop 16 + for-input if + switch-aesgcm-in + else + switch-aesgcm-out + then + endof + + \ AES-256/GCM + 4 of drop 32 + for-input if + switch-aesgcm-in + else + switch-aesgcm-out + then + endof + + \ ChaCha20+Poly1305 + 5 of drop + for-input if + switch-chapol-in + else + switch-chapol-out + then + endof + + \ Now we only have AES/CCM suites (6 to 9). Since the + \ input is between 0 and 15, and we checked values 0 to 5, + \ we only need to reject values larger than 9. + dup 9 > if + ERR_BAD_PARAM fail + then + + \ Stack: is_client prf_id mac_id cipher_id + \ We want to remove the mac_id (it is zero for CCM suites) + \ and replace the cipher_id with the key and tag lengths. + \ The following table applies: + \ id key length tag length + \ 6 16 16 + \ 7 32 16 + \ 8 16 8 + \ 9 32 8 + swap drop + dup 1 and 4 << 16 + swap + 8 and 16 swap - + for-input if + switch-aesccm-in + else + switch-aesccm-out + then + ret + endcase + ; + +cc: switch-cbc-out ( is_client prf_id mac_id aes cipher_key_len -- ) { + int is_client, prf_id, mac_id, aes; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + aes = T0_POP(); + mac_id = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_cbc_out(ENG, is_client, prf_id, mac_id, + aes ? ENG->iaes_cbcenc : ENG->ides_cbcenc, cipher_key_len); +} + +cc: switch-cbc-in ( is_client prf_id mac_id aes cipher_key_len -- ) { + int is_client, prf_id, mac_id, aes; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + aes = T0_POP(); + mac_id = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_cbc_in(ENG, is_client, prf_id, mac_id, + aes ? ENG->iaes_cbcdec : ENG->ides_cbcdec, cipher_key_len); +} + +cc: switch-aesgcm-out ( is_client prf_id cipher_key_len -- ) { + int is_client, prf_id; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_gcm_out(ENG, is_client, prf_id, + ENG->iaes_ctr, cipher_key_len); +} + +cc: switch-aesgcm-in ( is_client prf_id cipher_key_len -- ) { + int is_client, prf_id; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_gcm_in(ENG, is_client, prf_id, + ENG->iaes_ctr, cipher_key_len); +} + +cc: switch-chapol-out ( is_client prf_id -- ) { + int is_client, prf_id; + + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_chapol_out(ENG, is_client, prf_id); +} + +cc: switch-chapol-in ( is_client prf_id -- ) { + int is_client, prf_id; + + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_chapol_in(ENG, is_client, prf_id); +} + +cc: switch-aesccm-out ( is_client prf_id cipher_key_len tag_len -- ) { + int is_client, prf_id; + unsigned cipher_key_len, tag_len; + + tag_len = T0_POP(); + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_ccm_out(ENG, is_client, prf_id, + ENG->iaes_ctrcbc, cipher_key_len, tag_len); +} + +cc: switch-aesccm-in ( is_client prf_id cipher_key_len tag_len -- ) { + int is_client, prf_id; + unsigned cipher_key_len, tag_len; + + tag_len = T0_POP(); + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_ccm_in(ENG, is_client, prf_id, + ENG->iaes_ctrcbc, cipher_key_len, tag_len); +} + +\ Write Finished message. +: write-Finished ( from_client -- ) + compute-Finished + 20 write8 12 write24 addr-pad 12 write-blob ; + +\ Read Finished message. +: read-Finished ( from_client -- ) + compute-Finished + read-handshake-header 20 <> if ERR_UNEXPECTED fail then + addr-pad 12 + 12 read-blob + close-elt + addr-pad dup 12 + 12 memcmp ifnot ERR_BAD_FINISHED fail then ; + +\ Compute the "Finished" contents (either the value to send, or the +\ expected value). The 12-byte string is written in the pad. The +\ "from_client" value is non-zero for the Finished sent by the client. +\ The computed value is also saved in the relevant buffer for handling +\ secure renegotiation. +: compute-Finished ( from_client -- ) + dup addr-saved_finished swap ifnot 12 + then swap + addr-cipher_suite get16 prf-id compute-Finished-inner + addr-pad 12 memcpy ; + +cc: compute-Finished-inner ( from_client prf_id -- ) { + int prf_id = T0_POP(); + int from_client = T0_POPi(); + unsigned char tmp[48]; + br_tls_prf_seed_chunk seed; + + br_tls_prf_impl prf = br_ssl_engine_get_PRF(ENG, prf_id); + seed.data = tmp; + if (ENG->session.version >= BR_TLS12) { + seed.len = br_multihash_out(&ENG->mhash, prf_id, tmp); + } else { + br_multihash_out(&ENG->mhash, br_md5_ID, tmp); + br_multihash_out(&ENG->mhash, br_sha1_ID, tmp + 16); + seed.len = 36; + } + prf(ENG->pad, 12, ENG->session.master_secret, + sizeof ENG->session.master_secret, + from_client ? "client finished" : "server finished", + 1, &seed); +} + +\ Receive ChangeCipherSpec and Finished from the peer. +: read-CCS-Finished ( is-client -- ) + has-input? if + addr-record_type_in get8 20 <> if ERR_UNEXPECTED fail then + else + begin + wait-co 0x07 and dup 0x02 <> while + if ERR_UNEXPECTED fail then + repeat + drop + then + read8-nc 1 <> more-incoming-bytes? or if ERR_BAD_CCS fail then + dup 1 switch-encryption + + \ Read and verify Finished from peer. + not read-Finished ; + +\ Send ChangeCipherSpec and Finished to the peer. +: write-CCS-Finished ( is-client -- ) + \ Flush and wait for output buffer to be clear, so that we may + \ write our ChangeCipherSpec. We must switch immediately after + \ triggering the flush. + 20 wait-rectype-out + 1 write8 + flush-record + dup 0 switch-encryption + 22 wait-rectype-out + write-Finished + flush-record ; + +\ Read and parse a list of supported signature algorithms (with hash +\ functions). The resulting bit field is returned. +: read-list-sign-algos ( lim -- lim value ) + 0 { hashes } + read16 open-elt + begin dup while + read8 { hash } read8 { sign } + + \ If hash is 0x08 then this is a "new algorithm" identifier, + \ and we set the corresponding bit if it is in the 0..15 + \ range. Otherwise, we keep the value only if the signature + \ is either 1 (RSA) or 3 (ECDSA), and the hash is one of the + \ SHA-* functions (2 to 6). Note that we reject MD5. + hash 8 = if + sign 15 <= if + 1 sign 16 + << hashes or >hashes + then + else + hash 2 >= hash 6 <= and + sign 1 = sign 3 = or + and if + hashes 1 sign 1- 2 << hash + << or >hashes + then + then + repeat + close-elt + hashes ; + +\ ======================================================================= + +\ Compute total chain length. This includes the individual certificate +\ headers, but not the total chain header. This also sets the cert_cur, +\ cert_len and chain_len context fields. +cc: total-chain-length ( -- len ) { + size_t u; + uint32_t total; + + total = 0; + for (u = 0; u < ENG->chain_len; u ++) { + total += 3 + (uint32_t)ENG->chain[u].data_len; + } + T0_PUSH(total); +} + +\ Get length for current certificate in the chain; if the chain end was +\ reached, then this returns -1. +cc: begin-cert ( -- len ) { + if (ENG->chain_len == 0) { + T0_PUSHi(-1); + } else { + ENG->cert_cur = ENG->chain->data; + ENG->cert_len = ENG->chain->data_len; + ENG->chain ++; + ENG->chain_len --; + T0_PUSH(ENG->cert_len); + } +} + +\ Copy a chunk of certificate data into the pad. Returned value is the +\ chunk length, or 0 if the certificate end is reached. +cc: copy-cert-chunk ( -- len ) { + size_t clen; + + clen = ENG->cert_len; + if (clen > sizeof ENG->pad) { + clen = sizeof ENG->pad; + } + memcpy(ENG->pad, ENG->cert_cur, clen); + ENG->cert_cur += clen; + ENG->cert_len -= clen; + T0_PUSH(clen); +} + +\ Write a Certificate message. Total chain length (excluding the 3-byte +\ header) is returned; it is 0 if the chain is empty. +: write-Certificate ( -- total_chain_len ) + 11 write8 + total-chain-length dup + dup 3 + write24 write24 + begin + begin-cert + dup 0< if drop ret then write24 + begin copy-cert-chunk dup while + addr-pad swap write-blob + repeat + drop + again ; + +cc: x509-start-chain ( by_client -- ) { + const br_x509_class *xc; + uint32_t bc; + + bc = T0_POP(); + xc = *(ENG->x509ctx); + xc->start_chain(ENG->x509ctx, bc ? ENG->server_name : NULL); +} + +cc: x509-start-cert ( length -- ) { + const br_x509_class *xc; + + xc = *(ENG->x509ctx); + xc->start_cert(ENG->x509ctx, T0_POP()); +} + +cc: x509-append ( length -- ) { + const br_x509_class *xc; + size_t len; + + xc = *(ENG->x509ctx); + len = T0_POP(); + xc->append(ENG->x509ctx, ENG->pad, len); +} + +cc: x509-end-cert ( -- ) { + const br_x509_class *xc; + + xc = *(ENG->x509ctx); + xc->end_cert(ENG->x509ctx); +} + +cc: x509-end-chain ( -- err ) { + const br_x509_class *xc; + + xc = *(ENG->x509ctx); + T0_PUSH(xc->end_chain(ENG->x509ctx)); +} + +cc: get-key-type-usages ( -- key-type-usages ) { + const br_x509_class *xc; + const br_x509_pkey *pk; + unsigned usages; + + xc = *(ENG->x509ctx); + pk = xc->get_pkey(ENG->x509ctx, &usages); + if (pk == NULL) { + T0_PUSH(0); + } else { + T0_PUSH(pk->key_type | usages); + } +} + +\ Read a Certificate message. +\ Parameter: non-zero if this is a read by the client of a certificate +\ sent by the server; zero otherwise. +\ Returned value: +\ - Empty: 0 +\ - Valid: combination of key type and allowed key usages. +\ - Invalid: negative (-x for error code x) +: read-Certificate ( by_client -- key-type-usages ) + \ Get header, and check message type. + read-handshake-header 11 = ifnot ERR_UNEXPECTED fail then + + \ If the chain is empty, do some special processing. + dup 3 = if + read24 if ERR_BAD_PARAM fail then + swap drop ret + then + + \ Start processing the chain through the X.509 engine. + swap x509-start-chain + + \ Total chain length is a 24-bit integer. + read24 open-elt + begin + dup while + read24 open-elt + dup x509-start-cert + + \ We read the certificate by chunks through the pad, so + \ as to use the existing reading function (read-blob) + \ that also ensures proper hashing. + begin + dup while + dup 256 > if 256 else dup then { len } + addr-pad len read-blob + len x509-append + repeat + close-elt + x509-end-cert + repeat + + \ We must close the chain AND the handshake message. + close-elt + close-elt + + \ Chain processing is finished; get the error code. + x509-end-chain + dup if neg ret then drop + + \ Return key type and usages. + get-key-type-usages ; + +\ ======================================================================= + +\ Copy a specific protocol name from the list to the pad. The byte +\ length is returned. +cc: copy-protocol-name ( idx -- len ) { + size_t idx = T0_POP(); + size_t len = strlen(ENG->protocol_names[idx]); + memcpy(ENG->pad, ENG->protocol_names[idx], len); + T0_PUSH(len); +} + +\ Compare name in pad with the configured list of protocol names. +\ If a match is found, then the index is returned; otherwise, -1 +\ is returned. +cc: test-protocol-name ( len -- n ) { + size_t len = T0_POP(); + size_t u; + + for (u = 0; u < ENG->protocol_names_num; u ++) { + const char *name; + + name = ENG->protocol_names[u]; + if (len == strlen(name) && memcmp(ENG->pad, name, len) == 0) { + T0_PUSH(u); + T0_RET(); + } + } + T0_PUSHi(-1); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_hs_server.c b/BearSSL-OG/libbearssl/src/ssl/ssl_hs_server.c new file mode 100644 index 0000000..5f8cae7 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_hs_server.c @@ -0,0 +1,2009 @@ +/* Automatically generated code; do not modify directly. */ + +#include +#include + +typedef struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; +} t0_context; + +static uint32_t +t0_parse7E_unsigned(const unsigned char **p) +{ + uint32_t x; + + x = 0; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + return x; + } + } +} + +static int32_t +t0_parse7E_signed(const unsigned char **p) +{ + int neg; + uint32_t x; + + neg = ((**p) >> 6) & 1; + x = (uint32_t)-neg; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + if (neg) { + return -(int32_t)~x - 1; + } else { + return (int32_t)x; + } + } + } +} + +#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) +#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) +#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) +#define T0_INT1(x) T0_FBYTE(x, 0) +#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) + +/* static const unsigned char t0_datablock[]; */ + + +void br_ssl_hs_server_init_main(void *t0ctx); + +void br_ssl_hs_server_run(void *t0ctx); + + + +#include +#include + +#include "inner.h" + +/* + * This macro evaluates to a pointer to the current engine context. + */ +#define ENG ((br_ssl_engine_context *)(void *)((unsigned char *)t0ctx - offsetof(br_ssl_engine_context, cpu))) + + + + + +/* + * This macro evaluates to a pointer to the server context, under that + * specific name. It must be noted that since the engine context is the + * first field of the br_ssl_server_context structure ('eng'), then + * pointers values of both types are interchangeable, modulo an + * appropriate cast. This also means that "addresses" computed as offsets + * within the structure work for both kinds of context. + */ +#define CTX ((br_ssl_server_context *)ENG) + +/* + * Decrypt the pre-master secret (RSA key exchange). + */ +static void +do_rsa_decrypt(br_ssl_server_context *ctx, int prf_id, + unsigned char *epms, size_t len) +{ + uint32_t x; + unsigned char rpms[48]; + + /* + * Decrypt the PMS. + */ + x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, epms, &len); + + /* + * Set the first two bytes to the maximum supported client + * protocol version. These bytes are used for version rollback + * detection; forceing the two bytes will make the master secret + * wrong if the bytes are not correct. This process is + * recommended by RFC 5246 (section 7.4.7.1). + */ + br_enc16be(epms, ctx->client_max_version); + + /* + * Make a random PMS and copy it above the decrypted value if the + * decryption failed. Note that we use a constant-time conditional + * copy. + */ + br_hmac_drbg_generate(&ctx->eng.rng, rpms, sizeof rpms); + br_ccopy(x ^ 1, epms, rpms, sizeof rpms); + + /* + * Compute master secret. + */ + br_ssl_engine_compute_master(&ctx->eng, prf_id, epms, 48); + + /* + * Clear the pre-master secret from RAM: it is normally a buffer + * in the context, hence potentially long-lived. + */ + memset(epms, 0, len); +} + +/* + * Common part for ECDH and ECDHE. + */ +static void +ecdh_common(br_ssl_server_context *ctx, int prf_id, + unsigned char *xcoor, size_t xcoor_len, uint32_t ctl) +{ + unsigned char rpms[80]; + + if (xcoor_len > sizeof rpms) { + xcoor_len = sizeof rpms; + ctl = 0; + } + + /* + * Make a random PMS and copy it above the decrypted value if the + * decryption failed. Note that we use a constant-time conditional + * copy. + */ + br_hmac_drbg_generate(&ctx->eng.rng, rpms, xcoor_len); + br_ccopy(ctl ^ 1, xcoor, rpms, xcoor_len); + + /* + * Compute master secret. + */ + br_ssl_engine_compute_master(&ctx->eng, prf_id, xcoor, xcoor_len); + + /* + * Clear the pre-master secret from RAM: it is normally a buffer + * in the context, hence potentially long-lived. + */ + memset(xcoor, 0, xcoor_len); +} + +/* + * Do the ECDH key exchange (not ECDHE). + */ +static void +do_ecdh(br_ssl_server_context *ctx, int prf_id, + unsigned char *cpoint, size_t cpoint_len) +{ + uint32_t x; + + /* + * Finalise the key exchange. + */ + x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, + cpoint, &cpoint_len); + ecdh_common(ctx, prf_id, cpoint, cpoint_len, x); +} + +/* + * Do the full static ECDH key exchange. When this function is called, + * it has already been verified that the cipher suite uses ECDH (not ECDHE), + * and the client's public key (from its certificate) has type EC and is + * apt for key exchange. + */ +static void +do_static_ecdh(br_ssl_server_context *ctx, int prf_id) +{ + unsigned char cpoint[133]; + size_t cpoint_len; + const br_x509_class **xc; + const br_x509_pkey *pk; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + cpoint_len = pk->key.ec.qlen; + if (cpoint_len > sizeof cpoint) { + /* + * If the point is larger than our buffer then we need to + * restrict it. Length 2 is not a valid point length, so + * the ECDH will fail. + */ + cpoint_len = 2; + } + memcpy(cpoint, pk->key.ec.q, cpoint_len); + do_ecdh(ctx, prf_id, cpoint, cpoint_len); +} + +static size_t +hash_data(br_ssl_server_context *ctx, + void *dst, int hash_id, const void *src, size_t len) +{ + const br_hash_class *hf; + br_hash_compat_context hc; + + if (hash_id == 0) { + unsigned char tmp[36]; + + hf = br_multihash_getimpl(&ctx->eng.mhash, br_md5_ID); + if (hf == NULL) { + return 0; + } + hf->init(&hc.vtable); + hf->update(&hc.vtable, src, len); + hf->out(&hc.vtable, tmp); + hf = br_multihash_getimpl(&ctx->eng.mhash, br_sha1_ID); + if (hf == NULL) { + return 0; + } + hf->init(&hc.vtable); + hf->update(&hc.vtable, src, len); + hf->out(&hc.vtable, tmp + 16); + memcpy(dst, tmp, 36); + return 36; + } else { + hf = br_multihash_getimpl(&ctx->eng.mhash, hash_id); + if (hf == NULL) { + return 0; + } + hf->init(&hc.vtable); + hf->update(&hc.vtable, src, len); + hf->out(&hc.vtable, dst); + return (hf->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; + } +} + +/* + * Do the ECDHE key exchange (part 1: generation of transient key, and + * computing of the point to send to the client). Returned value is the + * signature length (in bytes), or -x on error (with x being an error + * code). The encoded point is written in the ecdhe_point[] context buffer + * (length in ecdhe_point_len). + */ +static int +do_ecdhe_part1(br_ssl_server_context *ctx, int curve) +{ + unsigned algo_id; + unsigned mask; + const unsigned char *order; + size_t olen, glen; + size_t hv_len, sig_len; + + if (!((ctx->eng.iec->supported_curves >> curve) & 1)) { + return -BR_ERR_INVALID_ALGORITHM; + } + ctx->eng.ecdhe_curve = curve; + + /* + * Generate our private key. We need a non-zero random value + * which is lower than the curve order, in a "large enough" + * range. We force the top bit to 0 and bottom bit to 1, which + * does the trick. Note that contrary to what happens in ECDSA, + * this is not a problem if we do not cover the full range of + * possible values. + */ + order = ctx->eng.iec->order(curve, &olen); + mask = 0xFF; + while (mask >= order[0]) { + mask >>= 1; + } + br_hmac_drbg_generate(&ctx->eng.rng, ctx->ecdhe_key, olen); + ctx->ecdhe_key[0] &= mask; + ctx->ecdhe_key[olen - 1] |= 0x01; + ctx->ecdhe_key_len = olen; + + /* + * Compute our ECDH point. + */ + glen = ctx->eng.iec->mulgen(ctx->eng.ecdhe_point, + ctx->ecdhe_key, olen, curve); + ctx->eng.ecdhe_point_len = glen; + + /* + * Assemble the message to be signed, and possibly hash it. + */ + memcpy(ctx->eng.pad, ctx->eng.client_random, 32); + memcpy(ctx->eng.pad + 32, ctx->eng.server_random, 32); + ctx->eng.pad[64 + 0] = 0x03; + ctx->eng.pad[64 + 1] = 0x00; + ctx->eng.pad[64 + 2] = curve; + ctx->eng.pad[64 + 3] = ctx->eng.ecdhe_point_len; + memcpy(ctx->eng.pad + 64 + 4, + ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len); + hv_len = 64 + 4 + ctx->eng.ecdhe_point_len; + algo_id = ctx->sign_hash_id; + if (algo_id >= (unsigned)0xFF00) { + hv_len = hash_data(ctx, ctx->eng.pad, algo_id & 0xFF, + ctx->eng.pad, hv_len); + if (hv_len == 0) { + return -BR_ERR_INVALID_ALGORITHM; + } + } + + sig_len = (*ctx->policy_vtable)->do_sign(ctx->policy_vtable, + algo_id, ctx->eng.pad, hv_len, sizeof ctx->eng.pad); + return sig_len ? (int)sig_len : -BR_ERR_INVALID_ALGORITHM; +} + +/* + * Do the ECDHE key exchange (part 2: computation of the shared secret + * from the point sent by the client). + */ +static void +do_ecdhe_part2(br_ssl_server_context *ctx, int prf_id, + unsigned char *cpoint, size_t cpoint_len) +{ + int curve; + uint32_t ctl; + size_t xoff, xlen; + + curve = ctx->eng.ecdhe_curve; + + /* + * Finalise the key exchange. + */ + ctl = ctx->eng.iec->mul(cpoint, cpoint_len, + ctx->ecdhe_key, ctx->ecdhe_key_len, curve); + xoff = ctx->eng.iec->xoff(curve, &xlen); + ecdh_common(ctx, prf_id, cpoint + xoff, xlen, ctl); + + /* + * Clear the ECDHE private key. Forward Secrecy is achieved insofar + * as that key does not get stolen, so we'd better destroy it + * as soon as it ceases to be useful. + */ + memset(ctx->ecdhe_key, 0, ctx->ecdhe_key_len); +} + +/* + * Offset for hash value within the pad (when obtaining all hash values, + * in preparation for verification of the CertificateVerify message). + * Order is MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512; last value + * is used to get the total length. + */ +static const unsigned char HASH_PAD_OFF[] = { 0, 16, 36, 64, 96, 144, 208 }; + +/* + * OID for hash functions in RSA signatures. + */ +static const unsigned char HASH_OID_SHA1[] = { + 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A +}; + +static const unsigned char HASH_OID_SHA224[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 +}; + +static const unsigned char HASH_OID_SHA256[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 +}; + +static const unsigned char HASH_OID_SHA384[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 +}; + +static const unsigned char HASH_OID_SHA512[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 +}; + +static const unsigned char *HASH_OID[] = { + HASH_OID_SHA1, + HASH_OID_SHA224, + HASH_OID_SHA256, + HASH_OID_SHA384, + HASH_OID_SHA512 +}; + +/* + * Verify the signature in CertificateVerify. Returned value is 0 on + * success, or a non-zero error code. Lack of implementation of the + * designated signature algorithm is reported as a "bad signature" + * error (because it means that the peer did not honour our advertised + * set of supported signature algorithms). + */ +static int +verify_CV_sig(br_ssl_server_context *ctx, size_t sig_len) +{ + const br_x509_class **xc; + const br_x509_pkey *pk; + int id; + + id = ctx->hash_CV_id; + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + if (pk->key_type == BR_KEYTYPE_RSA) { + unsigned char tmp[64]; + const unsigned char *hash_oid; + + if (id == 0) { + hash_oid = NULL; + } else { + hash_oid = HASH_OID[id - 2]; + } + if (ctx->eng.irsavrfy == 0) { + return BR_ERR_BAD_SIGNATURE; + } + if (!ctx->eng.irsavrfy(ctx->eng.pad, sig_len, + hash_oid, ctx->hash_CV_len, &pk->key.rsa, tmp) + || memcmp(tmp, ctx->hash_CV, ctx->hash_CV_len) != 0) + { + return BR_ERR_BAD_SIGNATURE; + } + } else { + if (ctx->eng.iecdsa == 0) { + return BR_ERR_BAD_SIGNATURE; + } + if (!ctx->eng.iecdsa(ctx->eng.iec, + ctx->hash_CV, ctx->hash_CV_len, + &pk->key.ec, ctx->eng.pad, sig_len)) + { + return BR_ERR_BAD_SIGNATURE; + } + } + return 0; +} + + + +static const unsigned char t0_datablock[] = { + 0x00, 0x00, 0x0A, 0x00, 0x24, 0x00, 0x2F, 0x01, 0x24, 0x00, 0x35, 0x02, + 0x24, 0x00, 0x3C, 0x01, 0x44, 0x00, 0x3D, 0x02, 0x44, 0x00, 0x9C, 0x03, + 0x04, 0x00, 0x9D, 0x04, 0x05, 0xC0, 0x03, 0x40, 0x24, 0xC0, 0x04, 0x41, + 0x24, 0xC0, 0x05, 0x42, 0x24, 0xC0, 0x08, 0x20, 0x24, 0xC0, 0x09, 0x21, + 0x24, 0xC0, 0x0A, 0x22, 0x24, 0xC0, 0x0D, 0x30, 0x24, 0xC0, 0x0E, 0x31, + 0x24, 0xC0, 0x0F, 0x32, 0x24, 0xC0, 0x12, 0x10, 0x24, 0xC0, 0x13, 0x11, + 0x24, 0xC0, 0x14, 0x12, 0x24, 0xC0, 0x23, 0x21, 0x44, 0xC0, 0x24, 0x22, + 0x55, 0xC0, 0x25, 0x41, 0x44, 0xC0, 0x26, 0x42, 0x55, 0xC0, 0x27, 0x11, + 0x44, 0xC0, 0x28, 0x12, 0x55, 0xC0, 0x29, 0x31, 0x44, 0xC0, 0x2A, 0x32, + 0x55, 0xC0, 0x2B, 0x23, 0x04, 0xC0, 0x2C, 0x24, 0x05, 0xC0, 0x2D, 0x43, + 0x04, 0xC0, 0x2E, 0x44, 0x05, 0xC0, 0x2F, 0x13, 0x04, 0xC0, 0x30, 0x14, + 0x05, 0xC0, 0x31, 0x33, 0x04, 0xC0, 0x32, 0x34, 0x05, 0xC0, 0x9C, 0x06, + 0x04, 0xC0, 0x9D, 0x07, 0x04, 0xC0, 0xA0, 0x08, 0x04, 0xC0, 0xA1, 0x09, + 0x04, 0xC0, 0xAC, 0x26, 0x04, 0xC0, 0xAD, 0x27, 0x04, 0xC0, 0xAE, 0x28, + 0x04, 0xC0, 0xAF, 0x29, 0x04, 0xCC, 0xA8, 0x15, 0x04, 0xCC, 0xA9, 0x25, + 0x04, 0x00, 0x00 +}; + +static const unsigned char t0_codeblock[] = { + 0x00, 0x01, 0x00, 0x0B, 0x00, 0x00, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x01, + 0x00, 0x0F, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x01, 0x08, + 0x00, 0x00, 0x01, 0x01, 0x09, 0x00, 0x00, 0x01, 0x02, 0x08, 0x00, 0x00, + 0x01, 0x02, 0x09, 0x00, 0x00, 0x29, 0x29, 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_CCS), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_FINISHED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_FRAGLEN), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_HANDSHAKE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_PARAM), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_SECRENEG), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_SIGNATURE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_VERSION), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_INVALID_ALGORITHM), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_NO_CLIENT_AUTH), 0x00, 0x00, 0x01, T0_INT1(BR_ERR_OK), + 0x00, 0x00, 0x01, T0_INT1(BR_ERR_OVERSIZED_ID), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_UNEXPECTED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_WRONG_KEY_USAGE), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, action)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, alert)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, application_data)), 0x00, 0x00, + 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, cipher_suite)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_server_context, client_max_version)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, client_random)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_server_context, client_suites)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_server_context, client_suites_num)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, close_received)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_server_context, curves)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, ecdhe_point)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, ecdhe_point_len)), + 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, flags)), + 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_server_context, hashes)), + 0x00, 0x00, 0x7B, 0x01, + T0_INT2(BR_MAX_CIPHER_SUITES * sizeof(br_suite_translated)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, log_max_frag_len)), + 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, pad)), 0x00, + 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, peer_log_max_frag_len)), 0x00, + 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, protocol_names_num)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, record_type_in)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, record_type_out)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, reneg)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, saved_finished)), 0x00, + 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, selected_protocol)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, server_name)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, server_random)), 0x00, 0x00, + 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_id)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_id_len)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, shutdown_recv)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_server_context, sign_hash_id)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, suites_buf)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, suites_num)), 0x00, + 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, version)), + 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_in)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, version_max)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_min)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_out)), + 0x00, 0x00, 0x09, 0x2A, 0x5D, 0x06, 0x02, 0x6A, 0x2B, 0x00, 0x00, 0x01, + 0x01, 0x00, 0x01, 0x03, 0x00, 0x9B, 0x2A, 0x63, 0x47, 0x9F, 0x2A, 0x05, + 0x04, 0x65, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0F, 0x06, 0x02, 0x9F, 0x00, + 0x63, 0x04, 0x6B, 0x00, 0x06, 0x02, 0x6A, 0x2B, 0x00, 0x00, 0x2A, 0x8B, + 0x47, 0x05, 0x03, 0x01, 0x0C, 0x08, 0x47, 0x78, 0x2E, 0xA8, 0x1C, 0x85, + 0x01, 0x0C, 0x33, 0x00, 0x00, 0x2A, 0x22, 0x01, 0x08, 0x0C, 0x47, 0x61, + 0x22, 0x08, 0x00, 0x01, 0x03, 0x00, 0x77, 0x30, 0x02, 0x00, 0x38, 0x13, + 0x01, 0x01, 0x0C, 0x77, 0x42, 0x2C, 0x19, 0x38, 0x06, 0x07, 0x02, 0x00, + 0xD0, 0x03, 0x00, 0x04, 0x75, 0x01, 0x00, 0xC7, 0x02, 0x00, 0x2A, 0x19, + 0x13, 0x06, 0x02, 0x71, 0x2B, 0xD0, 0x04, 0x76, 0x00, 0x01, 0x00, 0x77, + 0x42, 0x01, 0x16, 0x89, 0x42, 0x01, 0x00, 0x8C, 0x40, 0x36, 0xB1, 0x35, + 0x06, 0x02, 0x73, 0x2B, 0x06, 0x0A, 0xD7, 0x01, 0x00, 0xD3, 0x01, 0x00, + 0xAD, 0x04, 0x80, 0x46, 0xD7, 0xD4, 0x29, 0xD9, 0x50, 0x06, 0x01, 0xD5, + 0xD8, 0x2C, 0x50, 0x06, 0x31, 0x01, 0x00, 0xAE, 0x2A, 0x5D, 0x06, 0x0F, + 0x01, 0x02, 0xA4, 0x05, 0x02, 0x37, 0x2B, 0x29, 0xB2, 0xB0, 0x2A, 0xC9, + 0x29, 0x04, 0x19, 0x2A, 0x5F, 0x06, 0x0B, 0x29, 0x01, 0x02, 0xA4, 0x05, + 0x02, 0x70, 0x2B, 0xB2, 0x04, 0x0A, 0xB4, 0x2A, 0x05, 0x04, 0x29, 0xAB, + 0x04, 0x02, 0xB3, 0xAF, 0x04, 0x01, 0xB2, 0x01, 0x00, 0xAD, 0x01, 0x00, + 0xD3, 0x3E, 0x01, 0x01, 0x77, 0x42, 0x01, 0x17, 0x89, 0x42, 0x00, 0x00, + 0x3A, 0x3A, 0x00, 0x01, 0x03, 0x00, 0x2C, 0x19, 0x38, 0x06, 0x04, 0xCF, + 0x29, 0x04, 0x78, 0x01, 0x02, 0x02, 0x00, 0xC6, 0x19, 0x38, 0x06, 0x04, + 0xCF, 0x29, 0x04, 0x78, 0x02, 0x00, 0x01, 0x84, 0x00, 0x08, 0x2B, 0x00, + 0x00, 0x81, 0x2F, 0x47, 0x12, 0x01, 0x01, 0x13, 0x37, 0x00, 0x00, 0x2A, + 0x05, 0x04, 0x29, 0x01, 0x7F, 0x00, 0x01, 0x00, 0xA2, 0x12, 0x01, 0x01, + 0x13, 0x5F, 0x06, 0x03, 0x61, 0x04, 0x75, 0x47, 0x29, 0x00, 0x00, 0x01, + 0x7F, 0xA1, 0xCF, 0x2A, 0x01, 0x07, 0x13, 0x01, 0x00, 0x3A, 0x0F, 0x06, + 0x0D, 0x29, 0x01, 0x10, 0x13, 0x06, 0x05, 0x01, 0x00, 0x77, 0x42, 0xC5, + 0x04, 0x33, 0x01, 0x01, 0x3A, 0x0F, 0x06, 0x2A, 0x29, 0x29, 0x8A, 0x30, + 0x01, 0x01, 0x0F, 0x01, 0x01, 0xA4, 0x39, 0x06, 0x18, 0xC8, 0x2C, 0x19, + 0x38, 0x06, 0x04, 0xCF, 0x29, 0x04, 0x78, 0x01, 0x80, 0x64, 0xC7, 0x01, + 0x01, 0x77, 0x42, 0x01, 0x17, 0x89, 0x42, 0x04, 0x03, 0x01, 0x00, 0xA1, + 0x04, 0x03, 0x73, 0x2B, 0x29, 0x04, 0xFF, 0x32, 0x01, 0x2A, 0x03, 0x00, + 0x09, 0x2A, 0x5D, 0x06, 0x02, 0x6A, 0x2B, 0x02, 0x00, 0x00, 0x00, 0x9C, + 0x01, 0x0F, 0x13, 0x00, 0x00, 0x76, 0x30, 0x01, 0x00, 0x3A, 0x0F, 0x06, + 0x10, 0x29, 0x2A, 0x01, 0x01, 0x0E, 0x06, 0x03, 0x29, 0x01, 0x02, 0x76, + 0x42, 0x01, 0x00, 0x04, 0x21, 0x01, 0x01, 0x3A, 0x0F, 0x06, 0x14, 0x29, + 0x01, 0x00, 0x76, 0x42, 0x2A, 0x01, 0x80, 0x64, 0x0F, 0x06, 0x05, 0x01, + 0x82, 0x00, 0x08, 0x2B, 0x5F, 0x04, 0x07, 0x29, 0x01, 0x82, 0x00, 0x08, + 0x2B, 0x29, 0x00, 0x00, 0x01, 0x00, 0x31, 0x06, 0x05, 0x3D, 0xA9, 0x39, + 0x04, 0x78, 0x2A, 0x06, 0x04, 0x01, 0x01, 0x91, 0x42, 0x00, 0x00, 0x01, + 0x1F, 0x13, 0x01, 0x12, 0x0F, 0x05, 0x02, 0x74, 0x2B, 0x78, 0x2E, 0x2A, + 0xCB, 0x05, 0x02, 0x73, 0x2B, 0xA8, 0x28, 0x00, 0x02, 0x87, 0x2E, 0x05, + 0x02, 0xBC, 0x00, 0xC0, 0xA7, 0xC0, 0xA7, 0x01, 0x7E, 0x03, 0x00, 0x2A, + 0x06, 0x17, 0xC2, 0x2A, 0x03, 0x01, 0x85, 0x47, 0xB6, 0x02, 0x01, 0x51, + 0x2A, 0x02, 0x00, 0x53, 0x06, 0x04, 0x03, 0x00, 0x04, 0x01, 0x29, 0x04, + 0x66, 0x9D, 0x9D, 0x02, 0x00, 0x61, 0x8C, 0x40, 0x00, 0x00, 0x31, 0x06, + 0x0B, 0x88, 0x30, 0x01, 0x14, 0x0E, 0x06, 0x02, 0x73, 0x2B, 0x04, 0x11, + 0xCF, 0x01, 0x07, 0x13, 0x2A, 0x01, 0x02, 0x0E, 0x06, 0x06, 0x06, 0x02, + 0x73, 0x2B, 0x04, 0x70, 0x29, 0xC3, 0x01, 0x01, 0x0E, 0x35, 0x39, 0x06, + 0x02, 0x66, 0x2B, 0x2A, 0x01, 0x01, 0xCA, 0x38, 0xB5, 0x00, 0x01, 0xBA, + 0x01, 0x0B, 0x0F, 0x05, 0x02, 0x73, 0x2B, 0x2A, 0x01, 0x03, 0x0F, 0x06, + 0x08, 0xC1, 0x06, 0x02, 0x6A, 0x2B, 0x47, 0x29, 0x00, 0x47, 0x5C, 0xC1, + 0xA7, 0x2A, 0x06, 0x23, 0xC1, 0xA7, 0x2A, 0x5B, 0x2A, 0x06, 0x18, 0x2A, + 0x01, 0x82, 0x00, 0x10, 0x06, 0x05, 0x01, 0x82, 0x00, 0x04, 0x01, 0x2A, + 0x03, 0x00, 0x85, 0x02, 0x00, 0xB6, 0x02, 0x00, 0x58, 0x04, 0x65, 0x9D, + 0x59, 0x04, 0x5A, 0x9D, 0x9D, 0x5A, 0x2A, 0x06, 0x02, 0x37, 0x00, 0x29, + 0x2D, 0x00, 0x02, 0x2A, 0x01, 0x20, 0x13, 0x05, 0x02, 0x74, 0x2B, 0x01, + 0x0F, 0x13, 0x03, 0x00, 0xB0, 0x95, 0x2E, 0x01, 0x86, 0x03, 0x11, 0x06, + 0x23, 0xC0, 0x2A, 0x01, 0x81, 0x7F, 0x13, 0x61, 0x01, 0x01, 0x12, 0x02, + 0x00, 0x0F, 0x05, 0x02, 0x6C, 0x2B, 0x01, 0x08, 0x12, 0x2A, 0x01, 0x02, + 0x0B, 0x3A, 0x01, 0x06, 0x10, 0x39, 0x06, 0x02, 0x6E, 0x2B, 0x04, 0x0D, + 0x02, 0x00, 0x01, 0x01, 0x0F, 0x06, 0x04, 0x01, 0x00, 0x04, 0x02, 0x01, + 0x02, 0x20, 0x05, 0x02, 0x6E, 0x2B, 0xC0, 0x2A, 0x03, 0x01, 0x2A, 0x01, + 0x84, 0x00, 0x10, 0x06, 0x02, 0x6F, 0x2B, 0x85, 0x47, 0xB6, 0x02, 0x01, + 0x55, 0x2A, 0x06, 0x01, 0x2B, 0x29, 0x9D, 0x00, 0x00, 0x1D, 0xBA, 0x01, + 0x0F, 0x0F, 0x05, 0x02, 0x73, 0x2B, 0x00, 0x0A, 0xBA, 0x01, 0x01, 0x0F, + 0x05, 0x02, 0x73, 0x2B, 0xC0, 0x2A, 0x03, 0x00, 0x79, 0x40, 0x7A, 0x01, + 0x20, 0xB6, 0xC2, 0x2A, 0x01, 0x20, 0x10, 0x06, 0x02, 0x72, 0x2B, 0x2A, + 0x90, 0x42, 0x8F, 0x47, 0xB6, 0x1A, 0x03, 0x01, 0xC0, 0xA7, 0x01, 0x00, + 0x03, 0x02, 0x01, 0x00, 0x03, 0x03, 0x83, 0xA2, 0x17, 0x3A, 0x08, 0x03, + 0x04, 0x03, 0x05, 0x2A, 0x06, 0x80, 0x6D, 0xC0, 0x2A, 0x03, 0x06, 0x02, + 0x01, 0x06, 0x0A, 0x2A, 0x78, 0x2E, 0x0F, 0x06, 0x04, 0x01, 0x7F, 0x03, + 0x03, 0x2A, 0x01, 0x81, 0x7F, 0x0F, 0x06, 0x0A, 0x8A, 0x30, 0x06, 0x02, + 0x6B, 0x2B, 0x01, 0x7F, 0x03, 0x02, 0x2A, 0x01, 0x81, 0xAC, 0x00, 0x0F, + 0x06, 0x11, 0x02, 0x00, 0x98, 0x2E, 0x11, 0x02, 0x00, 0x97, 0x2E, 0x0B, + 0x13, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x00, 0xC4, 0x2A, 0x5D, 0x06, 0x03, + 0x29, 0x04, 0x26, 0x01, 0x00, 0xA4, 0x06, 0x0B, 0x01, 0x02, 0x0C, 0x7B, + 0x08, 0x02, 0x06, 0x47, 0x40, 0x04, 0x16, 0x29, 0x02, 0x05, 0x02, 0x04, + 0x11, 0x06, 0x02, 0x69, 0x2B, 0x02, 0x06, 0x02, 0x05, 0x40, 0x02, 0x05, + 0x01, 0x04, 0x08, 0x03, 0x05, 0x04, 0xFF, 0x0F, 0x29, 0x01, 0x00, 0x03, + 0x07, 0xC2, 0xA7, 0x2A, 0x06, 0x09, 0xC2, 0x05, 0x04, 0x01, 0x7F, 0x03, + 0x07, 0x04, 0x74, 0x9D, 0x01, 0x00, 0x8D, 0x42, 0x01, 0x88, 0x04, 0x82, + 0x41, 0x01, 0x84, 0x80, 0x80, 0x00, 0x7E, 0x41, 0x2A, 0x06, 0x80, 0x4E, + 0xC0, 0xA7, 0x2A, 0x06, 0x80, 0x47, 0xC0, 0x01, 0x00, 0x3A, 0x0F, 0x06, + 0x04, 0x29, 0xB9, 0x04, 0x39, 0x01, 0x01, 0x3A, 0x0F, 0x06, 0x04, 0x29, + 0xB7, 0x04, 0x2F, 0x01, 0x83, 0xFE, 0x01, 0x3A, 0x0F, 0x06, 0x04, 0x29, + 0xB8, 0x04, 0x23, 0x01, 0x0D, 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xBE, 0x04, + 0x19, 0x01, 0x0A, 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xBF, 0x04, 0x0F, 0x01, + 0x10, 0x3A, 0x0F, 0x06, 0x04, 0x29, 0xAC, 0x04, 0x05, 0x29, 0xBC, 0x01, + 0x00, 0x29, 0x04, 0xFF, 0x35, 0x9D, 0x9D, 0x02, 0x01, 0x02, 0x03, 0x13, + 0x03, 0x01, 0x02, 0x00, 0x5D, 0x06, 0x08, 0x79, 0x2E, 0x99, 0x40, 0x01, + 0x80, 0x56, 0xA3, 0x97, 0x2E, 0x2A, 0x02, 0x00, 0x10, 0x06, 0x03, 0x29, + 0x02, 0x00, 0x2A, 0x01, 0x86, 0x00, 0x0B, 0x06, 0x02, 0x6D, 0x2B, 0x02, + 0x00, 0x98, 0x2E, 0x0B, 0x06, 0x04, 0x01, 0x80, 0x46, 0xA3, 0x02, 0x01, + 0x06, 0x10, 0x95, 0x2E, 0x02, 0x00, 0x0D, 0x06, 0x05, 0x29, 0x95, 0x2E, + 0x04, 0x04, 0x01, 0x00, 0x03, 0x01, 0x2A, 0x95, 0x40, 0x2A, 0x96, 0x40, + 0x2A, 0x99, 0x40, 0x01, 0x86, 0x03, 0x11, 0x03, 0x08, 0x02, 0x02, 0x06, + 0x04, 0x01, 0x02, 0x8A, 0x42, 0x8A, 0x30, 0x05, 0x04, 0x01, 0x01, 0x8A, + 0x42, 0x02, 0x07, 0x05, 0x03, 0x01, 0x28, 0xA3, 0x44, 0x29, 0x01, 0x82, + 0x01, 0x07, 0x01, 0xFC, 0x80, 0x00, 0x39, 0x82, 0x2F, 0x13, 0x2A, 0x82, + 0x41, 0x2A, 0x01, 0x81, 0x7F, 0x13, 0x5E, 0x37, 0x47, 0x01, 0x08, 0x12, + 0x5E, 0x01, 0x02, 0x13, 0x39, 0x01, 0x0C, 0x0C, 0x03, 0x09, 0x7E, 0x2F, + 0x43, 0x13, 0x2A, 0x7E, 0x41, 0x05, 0x04, 0x01, 0x00, 0x03, 0x09, 0x02, + 0x01, 0x06, 0x03, 0x01, 0x7F, 0x00, 0x8F, 0x01, 0x20, 0x34, 0x01, 0x20, + 0x90, 0x42, 0x7B, 0x2A, 0x03, 0x05, 0x2A, 0x02, 0x04, 0x0B, 0x06, 0x80, + 0x49, 0x2A, 0x2E, 0x2A, 0x9C, 0x2A, 0x01, 0x0C, 0x12, 0x2A, 0x01, 0x01, + 0x0F, 0x47, 0x01, 0x02, 0x0F, 0x39, 0x06, 0x0A, 0x2A, 0x02, 0x09, 0x13, + 0x05, 0x04, 0x65, 0x01, 0x00, 0x2A, 0x02, 0x08, 0x05, 0x0E, 0x2A, 0x01, + 0x81, 0x70, 0x13, 0x01, 0x20, 0x0E, 0x06, 0x04, 0x65, 0x01, 0x00, 0x2A, + 0x2A, 0x06, 0x10, 0x02, 0x05, 0x63, 0x40, 0x02, 0x05, 0x40, 0x02, 0x05, + 0x01, 0x04, 0x08, 0x03, 0x05, 0x04, 0x01, 0x65, 0x01, 0x04, 0x08, 0x04, + 0xFF, 0x30, 0x29, 0x02, 0x05, 0x7B, 0x09, 0x01, 0x02, 0x12, 0x2A, 0x05, + 0x03, 0x01, 0x28, 0xA3, 0x7C, 0x42, 0x8C, 0x2E, 0x01, 0x83, 0xFF, 0x7F, + 0x0F, 0x06, 0x0D, 0x01, 0x03, 0xA4, 0x06, 0x04, 0x01, 0x80, 0x78, 0xA3, + 0x01, 0x00, 0x8C, 0x40, 0x18, 0x05, 0x03, 0x01, 0x28, 0xA3, 0x01, 0x00, + 0x00, 0x00, 0xB4, 0xB3, 0x00, 0x04, 0x78, 0x2E, 0xCE, 0x06, 0x16, 0xC0, + 0x2A, 0x01, 0x84, 0x00, 0x10, 0x06, 0x02, 0x6F, 0x2B, 0x2A, 0x03, 0x00, + 0x85, 0x47, 0xB6, 0x02, 0x00, 0x78, 0x2E, 0xA8, 0x27, 0x78, 0x2E, 0x2A, + 0xCC, 0x47, 0xCB, 0x03, 0x01, 0x03, 0x02, 0x02, 0x01, 0x02, 0x02, 0x39, + 0x06, 0x14, 0xC2, 0x2A, 0x03, 0x03, 0x85, 0x47, 0xB6, 0x02, 0x03, 0x78, + 0x2E, 0xA8, 0x02, 0x02, 0x06, 0x03, 0x26, 0x04, 0x01, 0x24, 0x9D, 0x00, + 0x00, 0xBA, 0x01, 0x10, 0x0F, 0x05, 0x02, 0x73, 0x2B, 0x00, 0x00, 0x9E, + 0xBA, 0x01, 0x14, 0x0E, 0x06, 0x02, 0x73, 0x2B, 0x85, 0x01, 0x0C, 0x08, + 0x01, 0x0C, 0xB6, 0x9D, 0x85, 0x2A, 0x01, 0x0C, 0x08, 0x01, 0x0C, 0x32, + 0x05, 0x02, 0x67, 0x2B, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, + 0x9A, 0x02, 0x01, 0x02, 0x00, 0x3C, 0x2A, 0x01, 0x00, 0x0F, 0x06, 0x02, + 0x65, 0x00, 0xD1, 0x04, 0x74, 0x00, 0xC0, 0x01, 0x01, 0x0E, 0x06, 0x02, + 0x68, 0x2B, 0xC2, 0x2A, 0x2A, 0x5F, 0x47, 0x01, 0x05, 0x11, 0x39, 0x06, + 0x02, 0x68, 0x2B, 0x01, 0x08, 0x08, 0x2A, 0x84, 0x30, 0x0B, 0x06, 0x0D, + 0x2A, 0x01, 0x01, 0x47, 0x0C, 0x3F, 0x2A, 0x84, 0x42, 0x86, 0x42, 0x04, + 0x01, 0x29, 0x00, 0x00, 0xC0, 0x8A, 0x30, 0x01, 0x00, 0x3A, 0x0F, 0x06, + 0x13, 0x29, 0x01, 0x01, 0x0F, 0x05, 0x02, 0x6B, 0x2B, 0xC2, 0x06, 0x02, + 0x6B, 0x2B, 0x01, 0x02, 0x8A, 0x42, 0x04, 0x28, 0x01, 0x02, 0x3A, 0x0F, + 0x06, 0x1F, 0x29, 0x01, 0x0D, 0x0F, 0x05, 0x02, 0x6B, 0x2B, 0xC2, 0x01, + 0x0C, 0x0F, 0x05, 0x02, 0x6B, 0x2B, 0x85, 0x01, 0x0C, 0xB6, 0x8B, 0x85, + 0x01, 0x0C, 0x32, 0x05, 0x02, 0x6B, 0x2B, 0x04, 0x03, 0x6B, 0x2B, 0x29, + 0x00, 0x00, 0xC0, 0xA7, 0xC0, 0xA7, 0x2A, 0x06, 0x1D, 0xC2, 0x06, 0x03, + 0xBC, 0x04, 0x15, 0xC0, 0x2A, 0x01, 0x81, 0x7F, 0x0D, 0x06, 0x0C, 0x2A, + 0x8D, 0x08, 0x01, 0x00, 0x47, 0x42, 0x8D, 0x47, 0xB6, 0x04, 0x01, 0xC9, + 0x04, 0x60, 0x9D, 0x9D, 0x00, 0x00, 0xBB, 0x2A, 0x5F, 0x06, 0x07, 0x29, + 0x06, 0x02, 0x69, 0x2B, 0x04, 0x74, 0x00, 0x00, 0xC3, 0x01, 0x03, 0xC1, + 0x47, 0x29, 0x47, 0x00, 0x00, 0xC0, 0xC9, 0x00, 0x03, 0x01, 0x00, 0x03, + 0x00, 0xC0, 0xA7, 0x2A, 0x06, 0x80, 0x50, 0xC2, 0x03, 0x01, 0xC2, 0x03, + 0x02, 0x02, 0x01, 0x01, 0x08, 0x0F, 0x06, 0x16, 0x02, 0x02, 0x01, 0x0F, + 0x0D, 0x06, 0x0D, 0x01, 0x01, 0x02, 0x02, 0x01, 0x10, 0x08, 0x0C, 0x02, + 0x00, 0x39, 0x03, 0x00, 0x04, 0x2A, 0x02, 0x01, 0x01, 0x02, 0x11, 0x02, + 0x01, 0x01, 0x06, 0x0D, 0x13, 0x02, 0x02, 0x01, 0x01, 0x0F, 0x02, 0x02, + 0x01, 0x03, 0x0F, 0x39, 0x13, 0x06, 0x11, 0x02, 0x00, 0x01, 0x01, 0x02, + 0x02, 0x62, 0x01, 0x02, 0x0C, 0x02, 0x01, 0x08, 0x0C, 0x39, 0x03, 0x00, + 0x04, 0xFF, 0x2C, 0x9D, 0x02, 0x00, 0x00, 0x00, 0xC0, 0xA7, 0xBD, 0x82, + 0x41, 0x9D, 0x00, 0x00, 0xC0, 0xA7, 0xC0, 0xA7, 0x01, 0x00, 0x7E, 0x41, + 0x2A, 0x06, 0x15, 0xC0, 0x2A, 0x01, 0x20, 0x0B, 0x06, 0x0B, 0x01, 0x01, + 0x47, 0x0C, 0x7E, 0x2F, 0x39, 0x7E, 0x41, 0x04, 0x01, 0x29, 0x04, 0x68, + 0x9D, 0x9D, 0x00, 0x00, 0x01, 0x02, 0x9A, 0xC3, 0x01, 0x08, 0x0C, 0xC3, + 0x08, 0x00, 0x00, 0x01, 0x03, 0x9A, 0xC3, 0x01, 0x08, 0x0C, 0xC3, 0x08, + 0x01, 0x08, 0x0C, 0xC3, 0x08, 0x00, 0x00, 0x01, 0x01, 0x9A, 0xC3, 0x00, + 0x00, 0x3D, 0x2A, 0x5D, 0x05, 0x01, 0x00, 0x29, 0xD1, 0x04, 0x76, 0x02, + 0x03, 0x00, 0x94, 0x30, 0x03, 0x01, 0x01, 0x00, 0x2A, 0x02, 0x01, 0x0B, + 0x06, 0x10, 0x2A, 0x01, 0x01, 0x0C, 0x93, 0x08, 0x2E, 0x02, 0x00, 0x0F, + 0x06, 0x01, 0x00, 0x61, 0x04, 0x6A, 0x29, 0x01, 0x7F, 0x00, 0x00, 0x2C, + 0x19, 0x38, 0x06, 0x04, 0xCF, 0x29, 0x04, 0x78, 0x01, 0x16, 0x89, 0x42, + 0x01, 0x00, 0xE2, 0x01, 0x00, 0xE1, 0x2C, 0x01, 0x17, 0x89, 0x42, 0x00, + 0x00, 0x01, 0x15, 0x89, 0x42, 0x47, 0x57, 0x29, 0x57, 0x29, 0x2C, 0x00, + 0x00, 0x01, 0x01, 0x47, 0xC6, 0x00, 0x00, 0xBB, 0x01, 0x01, 0x0F, 0x05, + 0x02, 0x73, 0x2B, 0x2A, 0xC9, 0x29, 0x00, 0x00, 0x47, 0x3A, 0x9A, 0x47, + 0x2A, 0x06, 0x05, 0xC3, 0x29, 0x62, 0x04, 0x78, 0x29, 0x00, 0x02, 0x03, + 0x00, 0x78, 0x2E, 0x9C, 0x03, 0x01, 0x02, 0x01, 0x01, 0x0F, 0x13, 0x02, + 0x01, 0x01, 0x04, 0x12, 0x01, 0x0F, 0x13, 0x02, 0x01, 0x01, 0x08, 0x12, + 0x01, 0x0F, 0x13, 0x01, 0x00, 0x3A, 0x0F, 0x06, 0x10, 0x29, 0x01, 0x00, + 0x01, 0x18, 0x02, 0x00, 0x06, 0x03, 0x4C, 0x04, 0x01, 0x4D, 0x04, 0x81, + 0x0D, 0x01, 0x01, 0x3A, 0x0F, 0x06, 0x10, 0x29, 0x01, 0x01, 0x01, 0x10, + 0x02, 0x00, 0x06, 0x03, 0x4C, 0x04, 0x01, 0x4D, 0x04, 0x80, 0x77, 0x01, + 0x02, 0x3A, 0x0F, 0x06, 0x10, 0x29, 0x01, 0x01, 0x01, 0x20, 0x02, 0x00, + 0x06, 0x03, 0x4C, 0x04, 0x01, 0x4D, 0x04, 0x80, 0x61, 0x01, 0x03, 0x3A, + 0x0F, 0x06, 0x0F, 0x29, 0x29, 0x01, 0x10, 0x02, 0x00, 0x06, 0x03, 0x4A, + 0x04, 0x01, 0x4B, 0x04, 0x80, 0x4C, 0x01, 0x04, 0x3A, 0x0F, 0x06, 0x0E, + 0x29, 0x29, 0x01, 0x20, 0x02, 0x00, 0x06, 0x03, 0x4A, 0x04, 0x01, 0x4B, + 0x04, 0x38, 0x01, 0x05, 0x3A, 0x0F, 0x06, 0x0C, 0x29, 0x29, 0x02, 0x00, + 0x06, 0x03, 0x4E, 0x04, 0x01, 0x4F, 0x04, 0x26, 0x2A, 0x01, 0x09, 0x10, + 0x06, 0x02, 0x6A, 0x2B, 0x47, 0x29, 0x2A, 0x01, 0x01, 0x13, 0x01, 0x04, + 0x0C, 0x01, 0x10, 0x08, 0x47, 0x01, 0x08, 0x13, 0x01, 0x10, 0x47, 0x09, + 0x02, 0x00, 0x06, 0x03, 0x48, 0x04, 0x01, 0x49, 0x00, 0x29, 0x00, 0x00, + 0x9C, 0x01, 0x0C, 0x12, 0x01, 0x02, 0x10, 0x00, 0x00, 0x9C, 0x01, 0x0C, + 0x12, 0x2A, 0x60, 0x47, 0x01, 0x03, 0x0B, 0x13, 0x00, 0x00, 0x9C, 0x01, + 0x0C, 0x12, 0x01, 0x01, 0x0F, 0x00, 0x00, 0x9C, 0x01, 0x0C, 0x12, 0x5F, + 0x00, 0x00, 0x1B, 0x01, 0x00, 0x75, 0x30, 0x2A, 0x06, 0x22, 0x01, 0x01, + 0x3A, 0x0F, 0x06, 0x06, 0x29, 0x01, 0x00, 0xA0, 0x04, 0x14, 0x01, 0x02, + 0x3A, 0x0F, 0x06, 0x0D, 0x29, 0x77, 0x30, 0x01, 0x01, 0x0F, 0x06, 0x03, + 0x01, 0x10, 0x39, 0x04, 0x01, 0x29, 0x04, 0x01, 0x29, 0x7D, 0x30, 0x05, + 0x33, 0x31, 0x06, 0x30, 0x88, 0x30, 0x01, 0x14, 0x3A, 0x0F, 0x06, 0x06, + 0x29, 0x01, 0x02, 0x39, 0x04, 0x22, 0x01, 0x15, 0x3A, 0x0F, 0x06, 0x09, + 0x29, 0xAA, 0x06, 0x03, 0x01, 0x7F, 0xA0, 0x04, 0x13, 0x01, 0x16, 0x3A, + 0x0F, 0x06, 0x06, 0x29, 0x01, 0x01, 0x39, 0x04, 0x07, 0x29, 0x01, 0x04, + 0x39, 0x01, 0x00, 0x29, 0x19, 0x06, 0x03, 0x01, 0x08, 0x39, 0x00, 0x00, + 0x1B, 0x2A, 0x05, 0x13, 0x31, 0x06, 0x10, 0x88, 0x30, 0x01, 0x15, 0x0F, + 0x06, 0x08, 0x29, 0xAA, 0x01, 0x00, 0x77, 0x42, 0x04, 0x01, 0x23, 0x00, + 0x00, 0xCF, 0x01, 0x07, 0x13, 0x01, 0x01, 0x10, 0x06, 0x02, 0x73, 0x2B, + 0x00, 0x01, 0x03, 0x00, 0x2C, 0x19, 0x06, 0x05, 0x02, 0x00, 0x89, 0x42, + 0x00, 0xCF, 0x29, 0x04, 0x74, 0x00, 0x01, 0x14, 0xD2, 0x01, 0x01, 0xE2, + 0x2C, 0x2A, 0x01, 0x00, 0xCA, 0x01, 0x16, 0xD2, 0xD6, 0x2C, 0x00, 0x00, + 0x01, 0x0B, 0xE2, 0x52, 0x2A, 0x2A, 0x01, 0x03, 0x08, 0xE1, 0xE1, 0x14, + 0x2A, 0x5D, 0x06, 0x02, 0x29, 0x00, 0xE1, 0x1E, 0x2A, 0x06, 0x05, 0x85, + 0x47, 0xDA, 0x04, 0x77, 0x29, 0x04, 0x6C, 0x00, 0x01, 0x00, 0xDC, 0x95, + 0x2E, 0x01, 0x86, 0x03, 0x11, 0x06, 0x05, 0x63, 0x01, 0x00, 0xDD, 0x08, + 0x50, 0x08, 0x01, 0x03, 0x08, 0x01, 0x0D, 0xE2, 0xE1, 0x01, 0x00, 0xDC, + 0xE2, 0x01, 0x01, 0xDC, 0x29, 0x95, 0x2E, 0x01, 0x86, 0x03, 0x11, 0x06, + 0x08, 0x01, 0x00, 0xDD, 0xE0, 0x01, 0x01, 0xDD, 0x29, 0x50, 0xE0, 0x16, + 0x15, 0x2A, 0x5D, 0x06, 0x02, 0x29, 0x00, 0xE0, 0x1F, 0x2A, 0x06, 0x05, + 0x85, 0x47, 0xDA, 0x04, 0x77, 0x29, 0x04, 0x6C, 0x00, 0x9E, 0x01, 0x14, + 0xE2, 0x01, 0x0C, 0xE1, 0x85, 0x01, 0x0C, 0xDA, 0x00, 0x04, 0x03, 0x00, + 0x01, 0x02, 0xE2, 0x01, 0x80, 0x46, 0x8A, 0x30, 0x01, 0x02, 0x0F, 0x06, + 0x0C, 0x02, 0x00, 0x06, 0x04, 0x01, 0x05, 0x04, 0x02, 0x01, 0x1D, 0x04, + 0x02, 0x01, 0x00, 0x03, 0x01, 0x86, 0x30, 0x06, 0x04, 0x01, 0x05, 0x04, + 0x02, 0x01, 0x00, 0x03, 0x02, 0x8C, 0x2E, 0x2A, 0x06, 0x05, 0x62, 0x21, + 0x01, 0x07, 0x08, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x02, 0x03, + 0x08, 0x2A, 0x06, 0x03, 0x01, 0x02, 0x08, 0x08, 0xE1, 0x95, 0x2E, 0xE0, + 0x8E, 0x01, 0x04, 0x17, 0x8E, 0x01, 0x04, 0x08, 0x01, 0x1C, 0x34, 0x8E, + 0x01, 0x20, 0xDA, 0x01, 0x20, 0xE2, 0x8F, 0x01, 0x20, 0xDA, 0x78, 0x2E, + 0xE0, 0x01, 0x00, 0xE2, 0x02, 0x01, 0x02, 0x02, 0x08, 0x02, 0x03, 0x08, + 0x2A, 0x06, 0x80, 0x40, 0xE0, 0x02, 0x01, 0x2A, 0x06, 0x10, 0x01, 0x83, + 0xFE, 0x01, 0xE0, 0x01, 0x04, 0x09, 0x2A, 0xE0, 0x62, 0x8B, 0x47, 0xDB, + 0x04, 0x01, 0x29, 0x02, 0x02, 0x06, 0x0C, 0x01, 0x01, 0xE0, 0x01, 0x01, + 0xE0, 0x86, 0x30, 0x01, 0x08, 0x09, 0xE2, 0x02, 0x03, 0x2A, 0x06, 0x11, + 0x01, 0x10, 0xE0, 0x01, 0x04, 0x09, 0x2A, 0xE0, 0x64, 0x2A, 0xE0, 0x62, + 0x85, 0x47, 0xDB, 0x04, 0x01, 0x29, 0x04, 0x01, 0x29, 0x00, 0x00, 0x01, + 0x0E, 0xE2, 0x01, 0x00, 0xE1, 0x00, 0x03, 0x78, 0x2E, 0xCC, 0x05, 0x01, + 0x00, 0x7E, 0x2F, 0x2A, 0x01, 0x82, 0x80, 0x80, 0x80, 0x00, 0x13, 0x06, + 0x05, 0x29, 0x01, 0x1D, 0x04, 0x0E, 0x2A, 0x01, 0x83, 0xC0, 0x80, 0x80, + 0x00, 0x13, 0x2A, 0x06, 0x01, 0x47, 0x29, 0xA5, 0x03, 0x00, 0x02, 0x00, + 0x25, 0x2A, 0x5D, 0x06, 0x02, 0x37, 0x2B, 0x03, 0x01, 0x95, 0x2E, 0x01, + 0x86, 0x03, 0x11, 0x03, 0x02, 0x01, 0x0C, 0xE2, 0x02, 0x01, 0x80, 0x30, + 0x08, 0x02, 0x02, 0x01, 0x02, 0x13, 0x08, 0x01, 0x06, 0x08, 0xE1, 0x01, + 0x03, 0xE2, 0x02, 0x00, 0xE0, 0x7F, 0x80, 0x30, 0xDB, 0x02, 0x02, 0x06, + 0x1C, 0x92, 0x2E, 0x2A, 0x01, 0x83, 0xFE, 0x00, 0x0B, 0x06, 0x03, 0xE0, + 0x04, 0x0F, 0x01, 0x81, 0x7F, 0x13, 0xE2, 0x78, 0x2E, 0xCD, 0x01, 0x01, + 0x0C, 0x01, 0x03, 0x08, 0xE2, 0x02, 0x01, 0xE0, 0x85, 0x02, 0x01, 0xDA, + 0x00, 0x00, 0x56, 0x2A, 0x01, 0x00, 0x0F, 0x06, 0x02, 0x65, 0x00, 0xCF, + 0x29, 0x04, 0x73, 0x00, 0x2A, 0xE2, 0xDA, 0x00, 0x00, 0x01, 0x00, 0x78, + 0x2E, 0xCB, 0x06, 0x0C, 0x63, 0x3A, 0x06, 0x08, 0x01, 0x80, 0x41, 0xE2, + 0x01, 0x80, 0x42, 0xE2, 0x46, 0x06, 0x07, 0x61, 0x3A, 0x06, 0x03, 0x01, + 0x01, 0xE2, 0x45, 0x06, 0x08, 0x61, 0x3A, 0x06, 0x04, 0x01, 0x80, 0x40, + 0xE2, 0x47, 0x29, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x46, 0x45, 0x39, + 0x05, 0x14, 0x01, 0x01, 0x01, 0x80, 0x7C, 0xDE, 0x03, 0x00, 0x01, 0x03, + 0x01, 0x80, 0x7C, 0xDE, 0x02, 0x00, 0x08, 0x47, 0x29, 0x00, 0x46, 0x06, + 0x07, 0x01, 0x01, 0x44, 0x29, 0xDE, 0x03, 0x00, 0x45, 0x06, 0x0A, 0x01, + 0x03, 0x44, 0x29, 0xDE, 0x02, 0x00, 0x08, 0x03, 0x00, 0x29, 0x02, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x04, 0xDF, 0x01, 0x05, 0xDF, 0x01, 0x06, + 0xDF, 0x01, 0x03, 0xDF, 0x01, 0x02, 0xDF, 0x0A, 0x65, 0x00, 0x01, 0x03, + 0x00, 0x3A, 0x01, 0x01, 0x02, 0x00, 0x0C, 0x13, 0x05, 0x01, 0x00, 0x63, + 0x01, 0x03, 0x3B, 0x06, 0x07, 0x02, 0x00, 0xE2, 0x01, 0x02, 0x3B, 0xE2, + 0x00, 0x00, 0x2A, 0x01, 0x08, 0x54, 0xE2, 0xE2, 0x00, 0x00, 0x2A, 0x01, + 0x10, 0x54, 0xE2, 0xE0, 0x00, 0x00, 0x2A, 0x57, 0x06, 0x02, 0x29, 0x00, + 0xCF, 0x29, 0x04, 0x76 +}; + +static const uint16_t t0_caddr[] = { + 0, + 5, + 10, + 15, + 20, + 25, + 30, + 35, + 40, + 44, + 48, + 52, + 56, + 60, + 64, + 68, + 72, + 76, + 80, + 84, + 88, + 92, + 96, + 100, + 104, + 109, + 114, + 119, + 124, + 129, + 134, + 139, + 144, + 149, + 154, + 159, + 164, + 169, + 174, + 180, + 185, + 190, + 195, + 200, + 205, + 210, + 215, + 220, + 225, + 230, + 235, + 240, + 245, + 250, + 255, + 260, + 265, + 270, + 275, + 280, + 285, + 290, + 299, + 303, + 328, + 334, + 353, + 364, + 405, + 516, + 520, + 553, + 563, + 587, + 669, + 683, + 689, + 748, + 767, + 789, + 838, + 887, + 963, + 1065, + 1076, + 1670, + 1674, + 1741, + 1751, + 1782, + 1806, + 1852, + 1922, + 1962, + 1976, + 1985, + 1989, + 2084, + 2092, + 2128, + 2139, + 2155, + 2161, + 2172, + 2207, + 2233, + 2245, + 2251, + 2264, + 2279, + 2472, + 2481, + 2494, + 2503, + 2510, + 2616, + 2641, + 2654, + 2670, + 2688, + 2720, + 2793, + 2806, + 2987, + 2995, + 3122, + 3136, + 3141, + 3185, + 3242, + 3263, + 3290, + 3298, + 3306 +}; + +#define T0_INTERPRETED 93 + +#define T0_ENTER(ip, rp, slot) do { \ + const unsigned char *t0_newip; \ + uint32_t t0_lnum; \ + t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ + t0_lnum = t0_parse7E_unsigned(&t0_newip); \ + (rp) += t0_lnum; \ + *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ + (ip) = t0_newip; \ + } while (0) + +#define T0_DEFENTRY(name, slot) \ +void \ +name(void *ctx) \ +{ \ + t0_context *t0ctx = ctx; \ + t0ctx->ip = &t0_codeblock[0]; \ + T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ +} + +T0_DEFENTRY(br_ssl_hs_server_init_main, 166) + +#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) + +void +br_ssl_hs_server_run(void *t0ctx) +{ + uint32_t *dp, *rp; + const unsigned char *ip; + +#define T0_LOCAL(x) (*(rp - 2 - (x))) +#define T0_POP() (*-- dp) +#define T0_POPi() (*(int32_t *)(-- dp)) +#define T0_PEEK(x) (*(dp - 1 - (x))) +#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) +#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) +#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) +#define T0_RPOP() (*-- rp) +#define T0_RPOPi() (*(int32_t *)(-- rp)) +#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) +#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) +#define T0_ROLL(x) do { \ + size_t t0len = (size_t)(x); \ + uint32_t t0tmp = *(dp - 1 - t0len); \ + memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_SWAP() do { \ + uint32_t t0tmp = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_ROT() do { \ + uint32_t t0tmp = *(dp - 3); \ + *(dp - 3) = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_NROT() do { \ + uint32_t t0tmp = *(dp - 1); \ + *(dp - 1) = *(dp - 2); \ + *(dp - 2) = *(dp - 3); \ + *(dp - 3) = t0tmp; \ +} while (0) +#define T0_PICK(x) do { \ + uint32_t t0depth = (x); \ + T0_PUSH(T0_PEEK(t0depth)); \ +} while (0) +#define T0_CO() do { \ + goto t0_exit; \ +} while (0) +#define T0_RET() goto t0_next + + dp = ((t0_context *)t0ctx)->dp; + rp = ((t0_context *)t0ctx)->rp; + ip = ((t0_context *)t0ctx)->ip; + goto t0_next; + for (;;) { + uint32_t t0x; + + t0_next: + t0x = T0_NEXT(&ip); + if (t0x < T0_INTERPRETED) { + switch (t0x) { + int32_t t0off; + + case 0: /* ret */ + t0x = T0_RPOP(); + rp -= (t0x >> 16); + t0x &= 0xFFFF; + if (t0x == 0) { + ip = NULL; + goto t0_exit; + } + ip = &t0_codeblock[t0x]; + break; + case 1: /* literal constant */ + T0_PUSHi(t0_parse7E_signed(&ip)); + break; + case 2: /* read local */ + T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); + break; + case 3: /* write local */ + T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); + break; + case 4: /* jump */ + t0off = t0_parse7E_signed(&ip); + ip += t0off; + break; + case 5: /* jump if */ + t0off = t0_parse7E_signed(&ip); + if (T0_POP()) { + ip += t0off; + } + break; + case 6: /* jump if not */ + t0off = t0_parse7E_signed(&ip); + if (!T0_POP()) { + ip += t0off; + } + break; + case 7: { + /* * */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a * b); + + } + break; + case 8: { + /* + */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a + b); + + } + break; + case 9: { + /* - */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a - b); + + } + break; + case 10: { + /* -rot */ + T0_NROT(); + } + break; + case 11: { + /* < */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a < b)); + + } + break; + case 12: { + /* << */ + + int c = (int)T0_POPi(); + uint32_t x = T0_POP(); + T0_PUSH(x << c); + + } + break; + case 13: { + /* <= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a <= b)); + + } + break; + case 14: { + /* <> */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a != b)); + + } + break; + case 15: { + /* = */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a == b)); + + } + break; + case 16: { + /* > */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a > b)); + + } + break; + case 17: { + /* >= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a >= b)); + + } + break; + case 18: { + /* >> */ + + int c = (int)T0_POPi(); + int32_t x = T0_POPi(); + T0_PUSHi(x >> c); + + } + break; + case 19: { + /* and */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a & b); + + } + break; + case 20: { + /* begin-cert */ + + if (ENG->chain_len == 0) { + T0_PUSHi(-1); + } else { + ENG->cert_cur = ENG->chain->data; + ENG->cert_len = ENG->chain->data_len; + ENG->chain ++; + ENG->chain_len --; + T0_PUSH(ENG->cert_len); + } + + } + break; + case 21: { + /* begin-ta-name */ + + const br_x500_name *dn; + if (CTX->cur_dn_index >= CTX->num_tas) { + T0_PUSHi(-1); + } else { + if (CTX->ta_names == NULL) { + dn = &CTX->tas[CTX->cur_dn_index].dn; + } else { + dn = &CTX->ta_names[CTX->cur_dn_index]; + } + CTX->cur_dn_index ++; + CTX->cur_dn = dn->data; + CTX->cur_dn_len = dn->len; + T0_PUSH(CTX->cur_dn_len); + } + + } + break; + case 22: { + /* begin-ta-name-list */ + + CTX->cur_dn_index = 0; + + } + break; + case 23: { + /* bzero */ + + size_t len = (size_t)T0_POP(); + void *addr = (unsigned char *)ENG + (size_t)T0_POP(); + memset(addr, 0, len); + + } + break; + case 24: { + /* call-policy-handler */ + + int x; + br_ssl_server_choices choices; + + x = (*CTX->policy_vtable)->choose( + CTX->policy_vtable, CTX, &choices); + ENG->session.cipher_suite = choices.cipher_suite; + CTX->sign_hash_id = choices.algo_id; + ENG->chain = choices.chain; + ENG->chain_len = choices.chain_len; + T0_PUSHi(-(x != 0)); + + } + break; + case 25: { + /* can-output? */ + + T0_PUSHi(-(ENG->hlen_out > 0)); + + } + break; + case 26: { + /* check-resume */ + + if (ENG->session.session_id_len == 32 + && CTX->cache_vtable != NULL && (*CTX->cache_vtable)->load( + CTX->cache_vtable, CTX, &ENG->session)) + { + T0_PUSHi(-1); + } else { + T0_PUSH(0); + } + + } + break; + case 27: { + /* co */ + T0_CO(); + } + break; + case 28: { + /* compute-Finished-inner */ + + int prf_id = T0_POP(); + int from_client = T0_POPi(); + unsigned char tmp[48]; + br_tls_prf_seed_chunk seed; + + br_tls_prf_impl prf = br_ssl_engine_get_PRF(ENG, prf_id); + seed.data = tmp; + if (ENG->session.version >= BR_TLS12) { + seed.len = br_multihash_out(&ENG->mhash, prf_id, tmp); + } else { + br_multihash_out(&ENG->mhash, br_md5_ID, tmp); + br_multihash_out(&ENG->mhash, br_sha1_ID, tmp + 16); + seed.len = 36; + } + prf(ENG->pad, 12, ENG->session.master_secret, + sizeof ENG->session.master_secret, + from_client ? "client finished" : "server finished", + 1, &seed); + + } + break; + case 29: { + /* compute-hash-CV */ + + int i; + + for (i = 1; i <= 6; i ++) { + br_multihash_out(&ENG->mhash, i, + ENG->pad + HASH_PAD_OFF[i - 1]); + } + + } + break; + case 30: { + /* copy-cert-chunk */ + + size_t clen; + + clen = ENG->cert_len; + if (clen > sizeof ENG->pad) { + clen = sizeof ENG->pad; + } + memcpy(ENG->pad, ENG->cert_cur, clen); + ENG->cert_cur += clen; + ENG->cert_len -= clen; + T0_PUSH(clen); + + } + break; + case 31: { + /* copy-dn-chunk */ + + size_t clen; + + clen = CTX->cur_dn_len; + if (clen > sizeof ENG->pad) { + clen = sizeof ENG->pad; + } + memcpy(ENG->pad, CTX->cur_dn, clen); + CTX->cur_dn += clen; + CTX->cur_dn_len -= clen; + T0_PUSH(clen); + + } + break; + case 32: { + /* copy-hash-CV */ + + int id = T0_POP(); + size_t off, len; + + if (id == 0) { + off = 0; + len = 36; + } else { + if (br_multihash_getimpl(&ENG->mhash, id) == 0) { + T0_PUSH(0); + T0_RET(); + } + off = HASH_PAD_OFF[id - 1]; + len = HASH_PAD_OFF[id] - off; + } + memcpy(CTX->hash_CV, ENG->pad + off, len); + CTX->hash_CV_len = len; + CTX->hash_CV_id = id; + T0_PUSHi(-1); + + } + break; + case 33: { + /* copy-protocol-name */ + + size_t idx = T0_POP(); + size_t len = strlen(ENG->protocol_names[idx]); + memcpy(ENG->pad, ENG->protocol_names[idx], len); + T0_PUSH(len); + + } + break; + case 34: { + /* data-get8 */ + + size_t addr = T0_POP(); + T0_PUSH(t0_datablock[addr]); + + } + break; + case 35: { + /* discard-input */ + + ENG->hlen_in = 0; + + } + break; + case 36: { + /* do-ecdh */ + + int prf_id = T0_POPi(); + size_t len = T0_POP(); + do_ecdh(CTX, prf_id, ENG->pad, len); + + } + break; + case 37: { + /* do-ecdhe-part1 */ + + int curve = T0_POPi(); + T0_PUSHi(do_ecdhe_part1(CTX, curve)); + + } + break; + case 38: { + /* do-ecdhe-part2 */ + + int prf_id = T0_POPi(); + size_t len = T0_POP(); + do_ecdhe_part2(CTX, prf_id, ENG->pad, len); + + } + break; + case 39: { + /* do-rsa-decrypt */ + + int prf_id = T0_POPi(); + size_t len = T0_POP(); + do_rsa_decrypt(CTX, prf_id, ENG->pad, len); + + } + break; + case 40: { + /* do-static-ecdh */ + + do_static_ecdh(CTX, T0_POP()); + + } + break; + case 41: { + /* drop */ + (void)T0_POP(); + } + break; + case 42: { + /* dup */ + T0_PUSH(T0_PEEK(0)); + } + break; + case 43: { + /* fail */ + + br_ssl_engine_fail(ENG, (int)T0_POPi()); + T0_CO(); + + } + break; + case 44: { + /* flush-record */ + + br_ssl_engine_flush_record(ENG); + + } + break; + case 45: { + /* get-key-type-usages */ + + const br_x509_class *xc; + const br_x509_pkey *pk; + unsigned usages; + + xc = *(ENG->x509ctx); + pk = xc->get_pkey(ENG->x509ctx, &usages); + if (pk == NULL) { + T0_PUSH(0); + } else { + T0_PUSH(pk->key_type | usages); + } + + } + break; + case 46: { + /* get16 */ + + size_t addr = (size_t)T0_POP(); + T0_PUSH(*(uint16_t *)(void *)((unsigned char *)ENG + addr)); + + } + break; + case 47: { + /* get32 */ + + size_t addr = (size_t)T0_POP(); + T0_PUSH(*(uint32_t *)(void *)((unsigned char *)ENG + addr)); + + } + break; + case 48: { + /* get8 */ + + size_t addr = (size_t)T0_POP(); + T0_PUSH(*((unsigned char *)ENG + addr)); + + } + break; + case 49: { + /* has-input? */ + + T0_PUSHi(-(ENG->hlen_in != 0)); + + } + break; + case 50: { + /* memcmp */ + + size_t len = (size_t)T0_POP(); + void *addr2 = (unsigned char *)ENG + (size_t)T0_POP(); + void *addr1 = (unsigned char *)ENG + (size_t)T0_POP(); + int x = memcmp(addr1, addr2, len); + T0_PUSH((uint32_t)-(x == 0)); + + } + break; + case 51: { + /* memcpy */ + + size_t len = (size_t)T0_POP(); + void *src = (unsigned char *)ENG + (size_t)T0_POP(); + void *dst = (unsigned char *)ENG + (size_t)T0_POP(); + memcpy(dst, src, len); + + } + break; + case 52: { + /* mkrand */ + + size_t len = (size_t)T0_POP(); + void *addr = (unsigned char *)ENG + (size_t)T0_POP(); + br_hmac_drbg_generate(&ENG->rng, addr, len); + + } + break; + case 53: { + /* more-incoming-bytes? */ + + T0_PUSHi(ENG->hlen_in != 0 || !br_ssl_engine_recvrec_finished(ENG)); + + } + break; + case 54: { + /* multihash-init */ + + br_multihash_init(&ENG->mhash); + + } + break; + case 55: { + /* neg */ + + uint32_t a = T0_POP(); + T0_PUSH(-a); + + } + break; + case 56: { + /* not */ + + uint32_t a = T0_POP(); + T0_PUSH(~a); + + } + break; + case 57: { + /* or */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a | b); + + } + break; + case 58: { + /* over */ + T0_PUSH(T0_PEEK(1)); + } + break; + case 59: { + /* pick */ + T0_PICK(T0_POP()); + } + break; + case 60: { + /* read-chunk-native */ + + size_t clen = ENG->hlen_in; + if (clen > 0) { + uint32_t addr, len; + + len = T0_POP(); + addr = T0_POP(); + if ((size_t)len < clen) { + clen = (size_t)len; + } + memcpy((unsigned char *)ENG + addr, ENG->hbuf_in, clen); + if (ENG->record_type_in == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, ENG->hbuf_in, clen); + } + T0_PUSH(addr + (uint32_t)clen); + T0_PUSH(len - (uint32_t)clen); + ENG->hbuf_in += clen; + ENG->hlen_in -= clen; + } + + } + break; + case 61: { + /* read8-native */ + + if (ENG->hlen_in > 0) { + unsigned char x; + + x = *ENG->hbuf_in ++; + if (ENG->record_type_in == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, &x, 1); + } + T0_PUSH(x); + ENG->hlen_in --; + } else { + T0_PUSHi(-1); + } + + } + break; + case 62: { + /* save-session */ + + if (CTX->cache_vtable != NULL) { + (*CTX->cache_vtable)->save( + CTX->cache_vtable, CTX, &ENG->session); + } + + } + break; + case 63: { + /* set-max-frag-len */ + + size_t max_frag_len = T0_POP(); + + br_ssl_engine_new_max_frag_len(ENG, max_frag_len); + + /* + * We must adjust our own output limit. Since we call this only + * after receiving a ClientHello and before beginning to send + * the ServerHello, the next output record should be empty at + * that point, so we can use max_frag_len as a limit. + */ + if (ENG->hlen_out > max_frag_len) { + ENG->hlen_out = max_frag_len; + } + + } + break; + case 64: { + /* set16 */ + + size_t addr = (size_t)T0_POP(); + *(uint16_t *)(void *)((unsigned char *)ENG + addr) = (uint16_t)T0_POP(); + + } + break; + case 65: { + /* set32 */ + + size_t addr = (size_t)T0_POP(); + *(uint32_t *)(void *)((unsigned char *)ENG + addr) = (uint32_t)T0_POP(); + + } + break; + case 66: { + /* set8 */ + + size_t addr = (size_t)T0_POP(); + *((unsigned char *)ENG + addr) = (unsigned char)T0_POP(); + + } + break; + case 67: { + /* supported-curves */ + + uint32_t x = ENG->iec == NULL ? 0 : ENG->iec->supported_curves; + T0_PUSH(x); + + } + break; + case 68: { + /* supported-hash-functions */ + + int i; + unsigned x, num; + + x = 0; + num = 0; + for (i = br_sha1_ID; i <= br_sha512_ID; i ++) { + if (br_multihash_getimpl(&ENG->mhash, i)) { + x |= 1U << i; + num ++; + } + } + T0_PUSH(x); + T0_PUSH(num); + + } + break; + case 69: { + /* supports-ecdsa? */ + + T0_PUSHi(-(ENG->iecdsa != 0)); + + } + break; + case 70: { + /* supports-rsa-sign? */ + + T0_PUSHi(-(ENG->irsavrfy != 0)); + + } + break; + case 71: { + /* swap */ + T0_SWAP(); + } + break; + case 72: { + /* switch-aesccm-in */ + + int is_client, prf_id; + unsigned cipher_key_len, tag_len; + + tag_len = T0_POP(); + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_ccm_in(ENG, is_client, prf_id, + ENG->iaes_ctrcbc, cipher_key_len, tag_len); + + } + break; + case 73: { + /* switch-aesccm-out */ + + int is_client, prf_id; + unsigned cipher_key_len, tag_len; + + tag_len = T0_POP(); + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_ccm_out(ENG, is_client, prf_id, + ENG->iaes_ctrcbc, cipher_key_len, tag_len); + + } + break; + case 74: { + /* switch-aesgcm-in */ + + int is_client, prf_id; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_gcm_in(ENG, is_client, prf_id, + ENG->iaes_ctr, cipher_key_len); + + } + break; + case 75: { + /* switch-aesgcm-out */ + + int is_client, prf_id; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_gcm_out(ENG, is_client, prf_id, + ENG->iaes_ctr, cipher_key_len); + + } + break; + case 76: { + /* switch-cbc-in */ + + int is_client, prf_id, mac_id, aes; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + aes = T0_POP(); + mac_id = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_cbc_in(ENG, is_client, prf_id, mac_id, + aes ? ENG->iaes_cbcdec : ENG->ides_cbcdec, cipher_key_len); + + } + break; + case 77: { + /* switch-cbc-out */ + + int is_client, prf_id, mac_id, aes; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + aes = T0_POP(); + mac_id = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_cbc_out(ENG, is_client, prf_id, mac_id, + aes ? ENG->iaes_cbcenc : ENG->ides_cbcenc, cipher_key_len); + + } + break; + case 78: { + /* switch-chapol-in */ + + int is_client, prf_id; + + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_chapol_in(ENG, is_client, prf_id); + + } + break; + case 79: { + /* switch-chapol-out */ + + int is_client, prf_id; + + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_chapol_out(ENG, is_client, prf_id); + + } + break; + case 80: { + /* ta-names-total-length */ + + size_t u, len; + + len = 0; + if (CTX->ta_names != NULL) { + for (u = 0; u < CTX->num_tas; u ++) { + len += CTX->ta_names[u].len + 2; + } + } else if (CTX->tas != NULL) { + for (u = 0; u < CTX->num_tas; u ++) { + len += CTX->tas[u].dn.len + 2; + } + } + T0_PUSH(len); + + } + break; + case 81: { + /* test-protocol-name */ + + size_t len = T0_POP(); + size_t u; + + for (u = 0; u < ENG->protocol_names_num; u ++) { + const char *name; + + name = ENG->protocol_names[u]; + if (len == strlen(name) && memcmp(ENG->pad, name, len) == 0) { + T0_PUSH(u); + T0_RET(); + } + } + T0_PUSHi(-1); + + } + break; + case 82: { + /* total-chain-length */ + + size_t u; + uint32_t total; + + total = 0; + for (u = 0; u < ENG->chain_len; u ++) { + total += 3 + (uint32_t)ENG->chain[u].data_len; + } + T0_PUSH(total); + + } + break; + case 83: { + /* u< */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a < b)); + + } + break; + case 84: { + /* u>> */ + + int c = (int)T0_POPi(); + uint32_t x = T0_POP(); + T0_PUSH(x >> c); + + } + break; + case 85: { + /* verify-CV-sig */ + + int err; + + err = verify_CV_sig(CTX, T0_POP()); + T0_PUSHi(err); + + } + break; + case 86: { + /* write-blob-chunk */ + + size_t clen = ENG->hlen_out; + if (clen > 0) { + uint32_t addr, len; + + len = T0_POP(); + addr = T0_POP(); + if ((size_t)len < clen) { + clen = (size_t)len; + } + memcpy(ENG->hbuf_out, (unsigned char *)ENG + addr, clen); + if (ENG->record_type_out == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, ENG->hbuf_out, clen); + } + T0_PUSH(addr + (uint32_t)clen); + T0_PUSH(len - (uint32_t)clen); + ENG->hbuf_out += clen; + ENG->hlen_out -= clen; + } + + } + break; + case 87: { + /* write8-native */ + + unsigned char x; + + x = (unsigned char)T0_POP(); + if (ENG->hlen_out > 0) { + if (ENG->record_type_out == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, &x, 1); + } + *ENG->hbuf_out ++ = x; + ENG->hlen_out --; + T0_PUSHi(-1); + } else { + T0_PUSHi(0); + } + + } + break; + case 88: { + /* x509-append */ + + const br_x509_class *xc; + size_t len; + + xc = *(ENG->x509ctx); + len = T0_POP(); + xc->append(ENG->x509ctx, ENG->pad, len); + + } + break; + case 89: { + /* x509-end-cert */ + + const br_x509_class *xc; + + xc = *(ENG->x509ctx); + xc->end_cert(ENG->x509ctx); + + } + break; + case 90: { + /* x509-end-chain */ + + const br_x509_class *xc; + + xc = *(ENG->x509ctx); + T0_PUSH(xc->end_chain(ENG->x509ctx)); + + } + break; + case 91: { + /* x509-start-cert */ + + const br_x509_class *xc; + + xc = *(ENG->x509ctx); + xc->start_cert(ENG->x509ctx, T0_POP()); + + } + break; + case 92: { + /* x509-start-chain */ + + const br_x509_class *xc; + uint32_t bc; + + bc = T0_POP(); + xc = *(ENG->x509ctx); + xc->start_chain(ENG->x509ctx, bc ? ENG->server_name : NULL); + + } + break; + } + + } else { + T0_ENTER(ip, rp, t0x); + } + } +t0_exit: + ((t0_context *)t0ctx)->dp = dp; + ((t0_context *)t0ctx)->rp = rp; + ((t0_context *)t0ctx)->ip = ip; +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_hs_server.t0 b/BearSSL-OG/libbearssl/src/ssl/ssl_hs_server.t0 new file mode 100644 index 0000000..9f6e934 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_hs_server.t0 @@ -0,0 +1,1510 @@ +\ Copyright (c) 2016 Thomas Pornin +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +\ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +\ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +\ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +\ SOFTWARE. + +\ ---------------------------------------------------------------------- +\ Handshake processing code, for the server. +\ The common T0 code (ssl_hs_common.t0) shall be read first. + +preamble { + +/* + * This macro evaluates to a pointer to the server context, under that + * specific name. It must be noted that since the engine context is the + * first field of the br_ssl_server_context structure ('eng'), then + * pointers values of both types are interchangeable, modulo an + * appropriate cast. This also means that "addresses" computed as offsets + * within the structure work for both kinds of context. + */ +#define CTX ((br_ssl_server_context *)ENG) + +/* + * Decrypt the pre-master secret (RSA key exchange). + */ +static void +do_rsa_decrypt(br_ssl_server_context *ctx, int prf_id, + unsigned char *epms, size_t len) +{ + uint32_t x; + unsigned char rpms[48]; + + /* + * Decrypt the PMS. + */ + x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, epms, &len); + + /* + * Set the first two bytes to the maximum supported client + * protocol version. These bytes are used for version rollback + * detection; forceing the two bytes will make the master secret + * wrong if the bytes are not correct. This process is + * recommended by RFC 5246 (section 7.4.7.1). + */ + br_enc16be(epms, ctx->client_max_version); + + /* + * Make a random PMS and copy it above the decrypted value if the + * decryption failed. Note that we use a constant-time conditional + * copy. + */ + br_hmac_drbg_generate(&ctx->eng.rng, rpms, sizeof rpms); + br_ccopy(x ^ 1, epms, rpms, sizeof rpms); + + /* + * Compute master secret. + */ + br_ssl_engine_compute_master(&ctx->eng, prf_id, epms, 48); + + /* + * Clear the pre-master secret from RAM: it is normally a buffer + * in the context, hence potentially long-lived. + */ + memset(epms, 0, len); +} + +/* + * Common part for ECDH and ECDHE. + */ +static void +ecdh_common(br_ssl_server_context *ctx, int prf_id, + unsigned char *xcoor, size_t xcoor_len, uint32_t ctl) +{ + unsigned char rpms[80]; + + if (xcoor_len > sizeof rpms) { + xcoor_len = sizeof rpms; + ctl = 0; + } + + /* + * Make a random PMS and copy it above the decrypted value if the + * decryption failed. Note that we use a constant-time conditional + * copy. + */ + br_hmac_drbg_generate(&ctx->eng.rng, rpms, xcoor_len); + br_ccopy(ctl ^ 1, xcoor, rpms, xcoor_len); + + /* + * Compute master secret. + */ + br_ssl_engine_compute_master(&ctx->eng, prf_id, xcoor, xcoor_len); + + /* + * Clear the pre-master secret from RAM: it is normally a buffer + * in the context, hence potentially long-lived. + */ + memset(xcoor, 0, xcoor_len); +} + +/* + * Do the ECDH key exchange (not ECDHE). + */ +static void +do_ecdh(br_ssl_server_context *ctx, int prf_id, + unsigned char *cpoint, size_t cpoint_len) +{ + uint32_t x; + + /* + * Finalise the key exchange. + */ + x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, + cpoint, &cpoint_len); + ecdh_common(ctx, prf_id, cpoint, cpoint_len, x); +} + +/* + * Do the full static ECDH key exchange. When this function is called, + * it has already been verified that the cipher suite uses ECDH (not ECDHE), + * and the client's public key (from its certificate) has type EC and is + * apt for key exchange. + */ +static void +do_static_ecdh(br_ssl_server_context *ctx, int prf_id) +{ + unsigned char cpoint[133]; + size_t cpoint_len; + const br_x509_class **xc; + const br_x509_pkey *pk; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + cpoint_len = pk->key.ec.qlen; + if (cpoint_len > sizeof cpoint) { + /* + * If the point is larger than our buffer then we need to + * restrict it. Length 2 is not a valid point length, so + * the ECDH will fail. + */ + cpoint_len = 2; + } + memcpy(cpoint, pk->key.ec.q, cpoint_len); + do_ecdh(ctx, prf_id, cpoint, cpoint_len); +} + +static size_t +hash_data(br_ssl_server_context *ctx, + void *dst, int hash_id, const void *src, size_t len) +{ + const br_hash_class *hf; + br_hash_compat_context hc; + + if (hash_id == 0) { + unsigned char tmp[36]; + + hf = br_multihash_getimpl(&ctx->eng.mhash, br_md5_ID); + if (hf == NULL) { + return 0; + } + hf->init(&hc.vtable); + hf->update(&hc.vtable, src, len); + hf->out(&hc.vtable, tmp); + hf = br_multihash_getimpl(&ctx->eng.mhash, br_sha1_ID); + if (hf == NULL) { + return 0; + } + hf->init(&hc.vtable); + hf->update(&hc.vtable, src, len); + hf->out(&hc.vtable, tmp + 16); + memcpy(dst, tmp, 36); + return 36; + } else { + hf = br_multihash_getimpl(&ctx->eng.mhash, hash_id); + if (hf == NULL) { + return 0; + } + hf->init(&hc.vtable); + hf->update(&hc.vtable, src, len); + hf->out(&hc.vtable, dst); + return (hf->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; + } +} + +/* + * Do the ECDHE key exchange (part 1: generation of transient key, and + * computing of the point to send to the client). Returned value is the + * signature length (in bytes), or -x on error (with x being an error + * code). The encoded point is written in the ecdhe_point[] context buffer + * (length in ecdhe_point_len). + */ +static int +do_ecdhe_part1(br_ssl_server_context *ctx, int curve) +{ + unsigned algo_id; + unsigned mask; + const unsigned char *order; + size_t olen, glen; + size_t hv_len, sig_len; + + if (!((ctx->eng.iec->supported_curves >> curve) & 1)) { + return -BR_ERR_INVALID_ALGORITHM; + } + ctx->eng.ecdhe_curve = curve; + + /* + * Generate our private key. We need a non-zero random value + * which is lower than the curve order, in a "large enough" + * range. We force the top bit to 0 and bottom bit to 1, which + * does the trick. Note that contrary to what happens in ECDSA, + * this is not a problem if we do not cover the full range of + * possible values. + */ + order = ctx->eng.iec->order(curve, &olen); + mask = 0xFF; + while (mask >= order[0]) { + mask >>= 1; + } + br_hmac_drbg_generate(&ctx->eng.rng, ctx->ecdhe_key, olen); + ctx->ecdhe_key[0] &= mask; + ctx->ecdhe_key[olen - 1] |= 0x01; + ctx->ecdhe_key_len = olen; + + /* + * Compute our ECDH point. + */ + glen = ctx->eng.iec->mulgen(ctx->eng.ecdhe_point, + ctx->ecdhe_key, olen, curve); + ctx->eng.ecdhe_point_len = glen; + + /* + * Assemble the message to be signed, and possibly hash it. + */ + memcpy(ctx->eng.pad, ctx->eng.client_random, 32); + memcpy(ctx->eng.pad + 32, ctx->eng.server_random, 32); + ctx->eng.pad[64 + 0] = 0x03; + ctx->eng.pad[64 + 1] = 0x00; + ctx->eng.pad[64 + 2] = curve; + ctx->eng.pad[64 + 3] = ctx->eng.ecdhe_point_len; + memcpy(ctx->eng.pad + 64 + 4, + ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len); + hv_len = 64 + 4 + ctx->eng.ecdhe_point_len; + algo_id = ctx->sign_hash_id; + if (algo_id >= (unsigned)0xFF00) { + hv_len = hash_data(ctx, ctx->eng.pad, algo_id & 0xFF, + ctx->eng.pad, hv_len); + if (hv_len == 0) { + return -BR_ERR_INVALID_ALGORITHM; + } + } + + sig_len = (*ctx->policy_vtable)->do_sign(ctx->policy_vtable, + algo_id, ctx->eng.pad, hv_len, sizeof ctx->eng.pad); + return sig_len ? (int)sig_len : -BR_ERR_INVALID_ALGORITHM; +} + +/* + * Do the ECDHE key exchange (part 2: computation of the shared secret + * from the point sent by the client). + */ +static void +do_ecdhe_part2(br_ssl_server_context *ctx, int prf_id, + unsigned char *cpoint, size_t cpoint_len) +{ + int curve; + uint32_t ctl; + size_t xoff, xlen; + + curve = ctx->eng.ecdhe_curve; + + /* + * Finalise the key exchange. + */ + ctl = ctx->eng.iec->mul(cpoint, cpoint_len, + ctx->ecdhe_key, ctx->ecdhe_key_len, curve); + xoff = ctx->eng.iec->xoff(curve, &xlen); + ecdh_common(ctx, prf_id, cpoint + xoff, xlen, ctl); + + /* + * Clear the ECDHE private key. Forward Secrecy is achieved insofar + * as that key does not get stolen, so we'd better destroy it + * as soon as it ceases to be useful. + */ + memset(ctx->ecdhe_key, 0, ctx->ecdhe_key_len); +} + +/* + * Offset for hash value within the pad (when obtaining all hash values, + * in preparation for verification of the CertificateVerify message). + * Order is MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512; last value + * is used to get the total length. + */ +static const unsigned char HASH_PAD_OFF[] = { 0, 16, 36, 64, 96, 144, 208 }; + +/* + * OID for hash functions in RSA signatures. + */ +static const unsigned char HASH_OID_SHA1[] = { + 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A +}; + +static const unsigned char HASH_OID_SHA224[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 +}; + +static const unsigned char HASH_OID_SHA256[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 +}; + +static const unsigned char HASH_OID_SHA384[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 +}; + +static const unsigned char HASH_OID_SHA512[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 +}; + +static const unsigned char *HASH_OID[] = { + HASH_OID_SHA1, + HASH_OID_SHA224, + HASH_OID_SHA256, + HASH_OID_SHA384, + HASH_OID_SHA512 +}; + +/* + * Verify the signature in CertificateVerify. Returned value is 0 on + * success, or a non-zero error code. Lack of implementation of the + * designated signature algorithm is reported as a "bad signature" + * error (because it means that the peer did not honour our advertised + * set of supported signature algorithms). + */ +static int +verify_CV_sig(br_ssl_server_context *ctx, size_t sig_len) +{ + const br_x509_class **xc; + const br_x509_pkey *pk; + int id; + + id = ctx->hash_CV_id; + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + if (pk->key_type == BR_KEYTYPE_RSA) { + unsigned char tmp[64]; + const unsigned char *hash_oid; + + if (id == 0) { + hash_oid = NULL; + } else { + hash_oid = HASH_OID[id - 2]; + } + if (ctx->eng.irsavrfy == 0) { + return BR_ERR_BAD_SIGNATURE; + } + if (!ctx->eng.irsavrfy(ctx->eng.pad, sig_len, + hash_oid, ctx->hash_CV_len, &pk->key.rsa, tmp) + || memcmp(tmp, ctx->hash_CV, ctx->hash_CV_len) != 0) + { + return BR_ERR_BAD_SIGNATURE; + } + } else { + if (ctx->eng.iecdsa == 0) { + return BR_ERR_BAD_SIGNATURE; + } + if (!ctx->eng.iecdsa(ctx->eng.iec, + ctx->hash_CV, ctx->hash_CV_len, + &pk->key.ec, ctx->eng.pad, sig_len)) + { + return BR_ERR_BAD_SIGNATURE; + } + } + return 0; +} + +} + +\ ======================================================================= + +: addr-ctx: + next-word { field } + "addr-" field + 0 1 define-word + 0 8191 "offsetof(br_ssl_server_context, " field + ")" + make-CX + postpone literal postpone ; ; + +addr-ctx: client_max_version +addr-ctx: client_suites +addr-ctx: client_suites_num +addr-ctx: hashes +addr-ctx: curves +addr-ctx: sign_hash_id + +\ Get address and length of the client_suites[] buffer. Length is expressed +\ in bytes. +: addr-len-client_suites ( -- addr len ) + addr-client_suites + CX 0 1023 { BR_MAX_CIPHER_SUITES * sizeof(br_suite_translated) } ; + +\ Read the client SNI extension. +: read-client-sni ( lim -- lim ) + \ Open extension value. + read16 open-elt + + \ Open ServerNameList. + read16 open-elt + + \ Find if there is a name of type 0 (host_name) with a length + \ that fits in our dedicated buffer. + begin dup while + read8 if + read-ignore-16 + else + read16 + dup 255 <= if + dup addr-server_name + 0 swap set8 + addr-server_name swap read-blob + else + skip-blob + then + then + repeat + + \ Close ServerNameList. + close-elt + + \ Close extension value. + close-elt ; + +\ Set the new maximum fragment length. BEWARE: this shall be called only +\ after reading the ClientHello and before writing the ServerHello. +cc: set-max-frag-len ( len -- ) { + size_t max_frag_len = T0_POP(); + + br_ssl_engine_new_max_frag_len(ENG, max_frag_len); + + /* + * We must adjust our own output limit. Since we call this only + * after receiving a ClientHello and before beginning to send + * the ServerHello, the next output record should be empty at + * that point, so we can use max_frag_len as a limit. + */ + if (ENG->hlen_out > max_frag_len) { + ENG->hlen_out = max_frag_len; + } +} + +\ Read the client Max Frag Length extension. +: read-client-frag ( lim -- lim ) + \ Extension value must have length exactly 1 byte. + read16 1 <> if ERR_BAD_FRAGLEN fail then + read8 + + \ The byte value must be 1, 2, 3 or 4. + dup dup 0= swap 5 >= or if ERR_BAD_FRAGLEN fail then + + \ If our own maximum fragment length is greater, then we reduce + \ our length. + 8 + dup addr-log_max_frag_len get8 < if + dup 1 swap << set-max-frag-len + dup addr-log_max_frag_len set8 + addr-peer_log_max_frag_len set8 + else + drop + then ; + +\ Read the Secure Renegotiation extension from the client. +: read-client-reneg ( lim -- lim ) + \ Get value length. + read16 + + \ The "reneg" value is one of: + \ 0 on first handshake, client support is unknown + \ 1 client does not support secure renegotiation + \ 2 client supports secure renegotiation + addr-reneg get8 case + 0 of + \ First handshake, value length shall be 1. + 1 = ifnot ERR_BAD_SECRENEG fail then + read8 if ERR_BAD_SECRENEG fail then + 2 addr-reneg set8 + endof + 2 of + \ Renegotiation, value shall consist of 13 bytes + \ (header + copy of the saved client "Finished"). + 13 = ifnot ERR_BAD_SECRENEG fail then + read8 12 = ifnot ERR_BAD_SECRENEG fail then + addr-pad 12 read-blob + addr-saved_finished addr-pad 12 memcmp ifnot + ERR_BAD_SECRENEG fail + then + endof + + \ If "reneg" is 1 then the client is not supposed to support + \ the extension, and it sends it nonetheless, which means + \ foul play. + ERR_BAD_SECRENEG fail + endcase ; + +\ Read the Signature Algorithms extension. +: read-signatures ( lim -- lim ) + \ Open extension value. + read16 open-elt + + read-list-sign-algos addr-hashes set32 + + \ Close extension value. + close-elt ; + +\ Read the Supported Curves extension. +: read-supported-curves ( lim -- lim ) + \ Open extension value. + read16 open-elt + + \ Open list of curve identifiers. + read16 open-elt + + \ Get all supported curves. + 0 addr-curves set32 + begin dup while + read16 dup 32 < if + 1 swap << addr-curves get32 or addr-curves set32 + else + drop + then + repeat + close-elt + close-elt ; + +\ Read the ALPN extension from client. +: read-ALPN-from-client ( lim -- lim ) + \ If we do not have configured names, then we just ignore the + \ extension. + addr-protocol_names_num get16 ifnot read-ignore-16 ret then + + \ Open extension value. + read16 open-elt + + \ Open list of protocol names. + read16 open-elt + + \ Get all names and test for their support. We keep the one with + \ the lowest index (because we apply server's preferences, as + \ recommended by RFC 7301, section 3.2. We set the 'found' variable + \ to -2 and use an unsigned comparison, making -2 a huge value. + -2 { found } + begin dup while + read8 dup { len } addr-pad swap read-blob + len test-protocol-name dup found u< if + >found + else + drop + then + repeat + + \ End of extension. + close-elt + close-elt + + \ Write back found name index (or not). If no match was found, + \ then we write -1 (0xFFFF) in the index value, not 0, so that + \ the caller knows that we tried to match, and failed. + found 1+ addr-selected_protocol set16 ; + +\ Call policy handler to get cipher suite, hash function identifier and +\ certificate chain. Returned value is 0 (false) on failure. +cc: call-policy-handler ( -- bool ) { + int x; + br_ssl_server_choices choices; + + x = (*CTX->policy_vtable)->choose( + CTX->policy_vtable, CTX, &choices); + ENG->session.cipher_suite = choices.cipher_suite; + CTX->sign_hash_id = choices.algo_id; + ENG->chain = choices.chain; + ENG->chain_len = choices.chain_len; + T0_PUSHi(-(x != 0)); +} + +\ Check for a remembered session. +cc: check-resume ( -- bool ) { + if (ENG->session.session_id_len == 32 + && CTX->cache_vtable != NULL && (*CTX->cache_vtable)->load( + CTX->cache_vtable, CTX, &ENG->session)) + { + T0_PUSHi(-1); + } else { + T0_PUSH(0); + } +} + +\ Save the current session. +cc: save-session ( -- ) { + if (CTX->cache_vtable != NULL) { + (*CTX->cache_vtable)->save( + CTX->cache_vtable, CTX, &ENG->session); + } +} + +\ Read and drop ClientHello. This is used when a client-triggered +\ renegotiation attempt is rejected. +: skip-ClientHello ( -- ) + read-handshake-header-core + 1 = ifnot ERR_UNEXPECTED fail then + dup skip-blob drop ; + +\ Read ClientHello. If the session is resumed, then -1 is returned. +: read-ClientHello ( -- resume ) + \ Get header, and check message type. + read-handshake-header 1 = ifnot ERR_UNEXPECTED fail then + + \ Get maximum protocol version from client. + read16 dup { client-version-max } addr-client_max_version set16 + + \ Client random. + addr-client_random 32 read-blob + + \ Client session ID. + read8 dup 32 > if ERR_OVERSIZED_ID fail then + dup addr-session_id_len set8 + addr-session_id swap read-blob + + \ Lookup session for resumption. We should do that here because + \ we need to verify that the remembered cipher suite is still + \ matched by this ClientHello. + check-resume { resume } + + \ Cipher suites. We read all cipher suites from client, each time + \ matching against our own list. We accumulate suites in the + \ client_suites[] context buffer: we keep suites that are + \ supported by both the client and the server (so the list size + \ cannot exceed that of the server list), and we keep them in + \ either client or server preference order (depending on the + \ relevant flag). + \ + \ We also need to identify the pseudo cipher suite for secure + \ renegotiation here. + read16 open-elt + 0 { reneg-scsv } + 0 { resume-suite } + addr-len-client_suites dup2 bzero + over + { css-off css-max } + begin + dup while + read16 dup { suite } + + \ Check that when resuming a session, the requested + \ suite is still valid. + resume if + dup addr-cipher_suite get16 = if + -1 >resume-suite + then + then + + \ Special handling for TLS_EMPTY_RENEGOTIATION_INFO_SCSV. + \ This fake cipher suite may occur only in the first + \ handshake. + dup 0x00FF = if + addr-reneg get8 if ERR_BAD_SECRENEG fail then + -1 >reneg-scsv + then + + \ Special handling for TLS_FALLBACK_SCSV. If the client + \ maximum version is less than our own maximum version, + \ then this is an undue downgrade. We mark it by setting + \ the client max version to 0x10000. + dup 0x5600 = if + client-version-max addr-version_min get16 >= + client-version-max addr-version_max get16 < and if + -1 >client-version-max + then + then + + \ Test whether the suite is supported by the server. + scan-suite dup 0< if + \ We do not support this cipher suite. Note + \ that this also covers the case of pseudo + \ cipher suites. + drop + else + \ If we use server order, then we place the + \ suite at the computed offset; otherwise, we + \ append it to the list at the current place. + 0 flag? if + 2 << addr-client_suites + suite swap set16 + else + drop + \ We need to test for list length because + \ the client list may have duplicates, + \ that we do not filter. Duplicates are + \ invalid so this is not a problem if we + \ reject such clients. + css-off css-max >= if + ERR_BAD_HANDSHAKE fail + then + suite css-off set16 + css-off 4 + >css-off + then + then + repeat + drop + + \ Compression methods. We need method 0 (no compression). + 0 { ok-compression } + read8 open-elt + begin dup while + read8 ifnot -1 >ok-compression then + repeat + close-elt + + \ Set default values for parameters that may be affected by + \ extensions: + \ -- server name is empty + \ -- client is reputed to know RSA and ECDSA, both with SHA-1 + \ -- the default elliptic curve is P-256 (secp256r1, id = 23) + 0 addr-server_name set8 + 0x0404 addr-hashes set32 + 0x800000 addr-curves set32 + + \ Process extensions, if any. + dup if + read16 open-elt + begin dup while + read16 case + \ Server Name Indication. + 0x0000 of + read-client-sni + endof + \ Max Frag Length. + 0x0001 of + read-client-frag + endof + \ Secure Renegotiation. + 0xFF01 of + read-client-reneg + endof + \ Signature Algorithms. + 0x000D of + read-signatures + endof + \ Supported Curves. + 0x000A of + read-supported-curves + endof + \ Supported Point Formats. + \ We only support "uncompressed", that all + \ implementations are supposed to support, + \ so we can simply ignore that extension. + \ 0x000B of + \ read-ignore-16 + \ endof + + \ ALPN + 0x0010 of + read-ALPN-from-client + endof + + \ Other extensions are ignored. + drop read-ignore-16 0 + endcase + repeat + close-elt + then + + \ Close message. + close-elt + + \ Cancel session resumption if the cipher suite was not found. + resume resume-suite and >resume + + \ Now check the received data. Since the client is expecting an + \ answer, we can send an appropriate fatal alert on any error. + + \ Compute protocol version as the minimum of our maximum version, + \ and the maximum version sent by the client. If that is less than + \ 0x0300 (SSL-3.0), then fail. Otherwise, we may at least send an + \ alert with that version. We still reject versions lower than our + \ configured minimum. + \ As a special case, in case of undue downgrade, we send a specific + \ alert (see RFC 7507). Note that this case may happen only if + \ we would otherwise accept the client's version. + client-version-max 0< if + addr-client_max_version get16 addr-version_out set16 + 86 fail-alert + then + addr-version_max get16 + dup client-version-max > if drop client-version-max then + dup 0x0300 < if ERR_BAD_VERSION fail then + client-version-max addr-version_min get16 < if + 70 fail-alert + then + \ If resuming the session, then enforce the previously negotiated + \ version (if still possible). + resume if + addr-version get16 client-version-max <= if + drop addr-version get16 + else + 0 >resume + then + then + dup addr-version set16 + dup addr-version_in set16 + dup addr-version_out set16 + 0x0303 >= { can-tls12 } + + \ If the client sent TLS_EMPTY_RENEGOTIATION_INFO_SCSV, then + \ we should mark the client as "supporting secure renegotiation". + reneg-scsv if 2 addr-reneg set8 then + + \ If, at that point, the 'reneg' value is still 0, then the client + \ did not send the extension or the SCSV, so we have to assume + \ that secure renegotiation is not supported by that client. + addr-reneg get8 ifnot 1 addr-reneg set8 then + + \ Check compression. + ok-compression ifnot 40 fail-alert then + + \ Filter hash function support by what the server also supports. + \ If no common hash function remains with RSA and/or ECDSA, then + \ the corresponding ECDHE suites are not possible. + supported-hash-functions drop 257 * 0xFFFF0000 or + addr-hashes get32 and dup addr-hashes set32 + \ In 'can-ecdhe', bit 12 is set if ECDHE_RSA is possible, bit 13 is + \ set if ECDHE_ECDSA is possible. + dup 0xFF and 0<> neg + swap 8 >> 0<> 2 and or 12 << { can-ecdhe } + + \ Filter supported curves. If there is no common curve between + \ client and us, then ECDHE suites cannot be used. Note that we + \ may still allow ECDH, depending on the EC key handler. + addr-curves get32 supported-curves and dup addr-curves set32 + ifnot 0 >can-ecdhe then + + \ If resuming a session, then the next steps are not necessary; + \ we won't invoke the policy handler. + resume if -1 ret then + + \ We are not resuming, so a new session ID should be generated. + \ We don't check that the new ID is distinct from the one sent + \ by the client because probability of such an event is 2^(-256), + \ i.e. much (much) lower than that of an undetected transmission + \ error or hardware miscomputation, and with similar consequences + \ (handshake simply fails). + addr-session_id 32 mkrand + 32 addr-session_id_len set8 + + \ Translate common cipher suites, then squeeze out holes: there + \ may be holes because of the way we fill the list when the + \ server preference order is enforced, and also in case some + \ suites are filtered out. In particular: + \ -- ECDHE suites are removed if there is no common hash function + \ (for the relevant signature algorithm) or no common curve. + \ -- TLS-1.2-only suites are removed if the negotiated version is + \ TLS-1.1 or lower. + addr-client_suites dup >css-off + begin dup css-max < while + dup get16 dup cipher-suite-to-elements + dup 12 >> dup 1 = swap 2 = or if + dup can-ecdhe and ifnot + 2drop 0 dup + then + then + can-tls12 ifnot + \ Suites compatible with TLS-1.0 and TLS-1.1 are + \ exactly the ones that use HMAC/SHA-1. + dup 0xF0 and 0x20 <> if + 2drop 0 dup + then + then + dup if + css-off 2+ set16 css-off set16 + css-off 4 + >css-off + else + 2drop + then + 4 + + repeat + drop + css-off addr-client_suites - 2 >> + dup ifnot + \ No common cipher suite: handshake failure. + 40 fail-alert + then + addr-client_suites_num set8 + + \ Check ALPN. + addr-selected_protocol get16 0xFFFF = if + 3 flag? if 120 fail-alert then + 0 addr-selected_protocol set16 + then + + \ Call policy handler to obtain the cipher suite and other + \ parameters. + call-policy-handler ifnot 40 fail-alert then + + \ We are not resuming a session. + 0 ; + +\ Write ServerHello. +: write-ServerHello ( initial -- ) + { initial } + \ Compute ServerHello length. + 2 write8 70 + + \ Compute length of Secure Renegotiation extension. + addr-reneg get8 2 = if + initial if 5 else 29 then + else + 0 + then + { ext-reneg-len } + + \ Compute length of Max Fragment Length extension. + addr-peer_log_max_frag_len get8 if 5 else 0 then + { ext-max-frag-len } + + \ Compute length of ALPN extension. This also copy the + \ selected protocol name into the pad. + addr-selected_protocol get16 dup if 1- copy-protocol-name 7 + then + { ext-ALPN-len } + + \ Adjust ServerHello length to account for the extensions. + ext-reneg-len ext-max-frag-len + ext-ALPN-len + dup if 2 + then + + write24 + + \ Protocol version + addr-version get16 write16 + + \ Server random + addr-server_random 4 bzero + addr-server_random 4 + 28 mkrand + addr-server_random 32 write-blob + + \ Session ID + \ TODO: if we have no session cache at all, we might send here + \ an empty session ID. This would save a bit of network + \ bandwidth. + 32 write8 + addr-session_id 32 write-blob + + \ Cipher suite + addr-cipher_suite get16 write16 + + \ Compression method + 0 write8 + + \ Extensions + ext-reneg-len ext-max-frag-len + ext-ALPN-len + dup if + write16 + ext-reneg-len dup if + 0xFF01 write16 + 4 - dup write16 + 1- addr-saved_finished swap write-blob-head8 + else + drop + then + ext-max-frag-len if + 0x0001 write16 + 1 write16 addr-peer_log_max_frag_len get8 8 - write8 + then + ext-ALPN-len dup if + \ Note: the selected protocol name was previously + \ copied into the pad. + 0x0010 write16 + 4 - dup write16 + 2- dup write16 + 1- addr-pad swap write-blob-head8 + else + drop + then + else + drop + then ; + +\ Do the first part of ECDHE. Returned value is the computed signature +\ length, or a negative error code on error. +cc: do-ecdhe-part1 ( curve -- len ) { + int curve = T0_POPi(); + T0_PUSHi(do_ecdhe_part1(CTX, curve)); +} + +\ Get index of first bit set to 1 (in low to high order). +: lowest-1 ( bits -- n ) + dup ifnot drop -1 ret then + 0 begin dup2 >> 1 and 0= while 1+ repeat + swap drop ; + +\ Write the Server Key Exchange message (if applicable). +: write-ServerKeyExchange ( -- ) + addr-cipher_suite get16 use-ecdhe? ifnot ret then + + \ We must select an appropriate curve among the curves that + \ are supported both by us and the peer. Right now, we apply + \ a fixed preference order: Curve25519, P-256, P-384, P-521, + \ then the common curve with the lowest ID. + \ (TODO: add some option to make that behaviour configurable.) + \ + \ This loop always terminates because previous processing made + \ sure that ECDHE suites are not selectable if there is no common + \ curve. + addr-curves get32 + dup 0x20000000 and if + drop 29 + else + dup 0x38000000 and dup if swap then + drop lowest-1 + then + { curve-id } + + \ Compute the signed curve point to send. + curve-id do-ecdhe-part1 dup 0< if neg fail then { sig-len } + + \ If using TLS-1.2+, then the hash function and signature + \ algorithm are explicitly encoded in the message. + addr-version get16 0x0303 >= { tls1.2+ } + + 12 write8 + sig-len addr-ecdhe_point_len get8 + tls1.2+ 2 and + 6 + write24 + + \ Curve parameters: named curve with 16-bit ID. + 3 write8 curve-id write16 + + \ Public point. + addr-ecdhe_point addr-ecdhe_point_len get8 write-blob-head8 + + \ If TLS-1.2+, write hash and signature identifiers. + tls1.2+ if + \ sign_hash_id contains either a hash identifier, + \ or the complete 16-bit value to write. + addr-sign_hash_id get16 + dup 0xFF00 < if + write16 + else + 0xFF and write8 + \ 'use-rsa-ecdhe?' returns -1 for RSA, 0 for + \ ECDSA. The byte on the wire shall be 1 for RSA, + \ 3 for ECDSA. + addr-cipher_suite get16 use-rsa-ecdhe? 1 << 3 + write8 + then + then + + \ Signature. + sig-len write16 + addr-pad sig-len write-blob ; + +\ Get length of the list of anchor names to send to the client. The length +\ includes the per-name 2-byte header, but _not_ the 2-byte header for +\ the list itself. If no client certificate is requested, then this +\ returns 0. +cc: ta-names-total-length ( -- len ) { + size_t u, len; + + len = 0; + if (CTX->ta_names != NULL) { + for (u = 0; u < CTX->num_tas; u ++) { + len += CTX->ta_names[u].len + 2; + } + } else if (CTX->tas != NULL) { + for (u = 0; u < CTX->num_tas; u ++) { + len += CTX->tas[u].dn.len + 2; + } + } + T0_PUSH(len); +} + +\ Compute length and optionally write the contents of the list of +\ supported client authentication methods. +: write-list-auth ( do_write -- len ) + 0 + addr-cipher_suite get16 use-ecdh? if + 2+ over if 65 write8 66 write8 then + then + supports-rsa-sign? if 1+ over if 1 write8 then then + supports-ecdsa? if 1+ over if 64 write8 then then + swap drop ; + +: write-signhash-inner2 ( dow algo hashes len id -- dow algo hashes len ) + { id } + over 1 id << and ifnot ret then + 2+ + 3 pick if id write8 2 pick write8 then ; + +: write-signhash-inner1 ( dow algo hashes -- dow len ) + 0 + 4 write-signhash-inner2 + 5 write-signhash-inner2 + 6 write-signhash-inner2 + 3 write-signhash-inner2 + 2 write-signhash-inner2 + -rot 2drop ; + +\ Compute length and optionally write the contents of the list of +\ supported sign+hash algorithms. +: write-list-signhash ( do_write -- len ) + 0 { len } + \ If supporting neither RSA nor ECDSA in the engine, then we + \ will do only static ECDH, and thus we claim support for + \ everything (for the X.509 validator). + supports-rsa-sign? supports-ecdsa? or ifnot + 1 0x7C write-signhash-inner1 >len + 3 0x7C write-signhash-inner1 len + + swap drop ret + then + supports-rsa-sign? if + 1 supported-hash-functions drop + write-signhash-inner1 >len + then + supports-ecdsa? if + 3 supported-hash-functions drop + write-signhash-inner1 len + >len + then + drop len ; + +\ Initialise index for sending the list of anchor DN. +cc: begin-ta-name-list ( -- ) { + CTX->cur_dn_index = 0; +} + +\ Switch to next DN in the list. Returned value is the DN length, or -1 +\ if the end of the list was reached. +cc: begin-ta-name ( -- len ) { + const br_x500_name *dn; + if (CTX->cur_dn_index >= CTX->num_tas) { + T0_PUSHi(-1); + } else { + if (CTX->ta_names == NULL) { + dn = &CTX->tas[CTX->cur_dn_index].dn; + } else { + dn = &CTX->ta_names[CTX->cur_dn_index]; + } + CTX->cur_dn_index ++; + CTX->cur_dn = dn->data; + CTX->cur_dn_len = dn->len; + T0_PUSH(CTX->cur_dn_len); + } +} + +\ Copy a chunk of the current DN into the pad. Returned value is the +\ chunk length; this is 0 when the end of the current DN is reached. +cc: copy-dn-chunk ( -- len ) { + size_t clen; + + clen = CTX->cur_dn_len; + if (clen > sizeof ENG->pad) { + clen = sizeof ENG->pad; + } + memcpy(ENG->pad, CTX->cur_dn, clen); + CTX->cur_dn += clen; + CTX->cur_dn_len -= clen; + T0_PUSH(clen); +} + +\ Write a CertificateRequest message. +: write-CertificateRequest ( -- ) + \ The list of client authentication types includes: + \ rsa_sign (1) + \ ecdsa_sign (64) + \ rsa_fixed_ecdh (65) + \ ecdsa_fixed_ecdh (66) + \ rsa_sign and ecdsa_sign require, respectively, RSA and ECDSA + \ support. Static ECDH requires that the cipher suite is ECDH. + \ When we ask for static ECDH, we always send both rsa_fixed_ecdh + \ and ecdsa_fixed_ecdh because what matters there is what the + \ X.509 engine may support, and we do not control that. + \ + \ With TLS 1.2, we must also send a list of supported signature + \ and hash algorithms. That list is supposed to qualify both + \ the engine itself, and the X.509 validator, which are separate + \ in BearSSL. There again, we use the engine capabilities in that + \ list, and resort to a generic all-support list if only + \ static ECDH is accepted. + \ + \ (In practice, client implementations tend to have at most one + \ or two certificates, and send the chain regardless of what + \ algorithms are used in it.) + + 0 write-list-auth + addr-version get16 0x0303 >= if + 2+ 0 write-list-signhash + + then + ta-names-total-length + 3 + + + \ Message header + 13 write8 write24 + + \ List of authentication methods + 0 write-list-auth write8 1 write-list-auth drop + + \ For TLS 1.2+, list of sign+hash + addr-version get16 0x0303 >= if + 0 write-list-signhash write16 1 write-list-signhash drop + then + + \ Trust anchor names + ta-names-total-length write16 + begin-ta-name-list + begin + begin-ta-name + dup 0< if drop ret then write16 + begin copy-dn-chunk dup while + addr-pad swap write-blob + repeat + drop + again ; + +\ Write the Server Hello Done message. +: write-ServerHelloDone ( -- ) + 14 write8 0 write24 ; + +\ Perform RSA decryption of the client-sent pre-master secret. The value +\ is in the pad, and its length is provided as parameter. +cc: do-rsa-decrypt ( len prf_id -- ) { + int prf_id = T0_POPi(); + size_t len = T0_POP(); + do_rsa_decrypt(CTX, prf_id, ENG->pad, len); +} + +\ Perform ECDH (not ECDHE). The point from the client is in the pad, and +\ its length is provided as parameter. +cc: do-ecdh ( len prf_id -- ) { + int prf_id = T0_POPi(); + size_t len = T0_POP(); + do_ecdh(CTX, prf_id, ENG->pad, len); +} + +\ Do the second part of ECDHE. +cc: do-ecdhe-part2 ( len prf_id -- ) { + int prf_id = T0_POPi(); + size_t len = T0_POP(); + do_ecdhe_part2(CTX, prf_id, ENG->pad, len); +} + +\ Perform static ECDH. The point from the client is the public key +\ extracted from its certificate. +cc: do-static-ecdh ( prf_id -- ) { + do_static_ecdh(CTX, T0_POP()); +} + +\ Read a ClientKeyExchange header. +: read-ClientKeyExchange-header ( -- len ) + read-handshake-header 16 = ifnot ERR_UNEXPECTED fail then ; + +\ Read the Client Key Exchange contents (non-empty case). +: read-ClientKeyExchange-contents ( lim -- ) + \ What we should get depends on the cipher suite. + addr-cipher_suite get16 use-rsa-keyx? if + \ RSA key exchange: we expect a RSA-encrypted value. + read16 + dup 512 > if ERR_LIMIT_EXCEEDED fail then + dup { enc-rsa-len } + addr-pad swap read-blob + enc-rsa-len addr-cipher_suite get16 prf-id do-rsa-decrypt + then + addr-cipher_suite get16 dup use-ecdhe? swap use-ecdh? { ecdhe ecdh } + ecdh ecdhe or if + \ ECDH or ECDHE key exchange: we expect an EC point. + read8 dup { ec-point-len } + addr-pad swap read-blob + ec-point-len addr-cipher_suite get16 prf-id + ecdhe if do-ecdhe-part2 else do-ecdh then + then + close-elt ; + +\ Read the Client Key Exchange (normal case). +: read-ClientKeyExchange ( -- ) + read-ClientKeyExchange-header + read-ClientKeyExchange-contents ; + +\ Obtain all possible hash values for handshake messages so far. This +\ is done because we need the hash value for the CertificateVerify +\ _before_ knowing which hash function will actually be used, as this +\ information is obtained from decoding the message header itself. +\ All hash values are stored in the pad (208 bytes in total). +cc: compute-hash-CV ( -- ) { + int i; + + for (i = 1; i <= 6; i ++) { + br_multihash_out(&ENG->mhash, i, + ENG->pad + HASH_PAD_OFF[i - 1]); + } +} + +\ Copy the proper hash value from the pad into the dedicated buffer. +\ Returned value is true (-1) on success, false (0) on error (error +\ being an unimplemented hash function). The id has already been verified +\ to be either 0 (for MD5+SHA-1) or one of the SHA-* functions. +cc: copy-hash-CV ( hash_id -- bool ) { + int id = T0_POP(); + size_t off, len; + + if (id == 0) { + off = 0; + len = 36; + } else { + if (br_multihash_getimpl(&ENG->mhash, id) == 0) { + T0_PUSH(0); + T0_RET(); + } + off = HASH_PAD_OFF[id - 1]; + len = HASH_PAD_OFF[id] - off; + } + memcpy(CTX->hash_CV, ENG->pad + off, len); + CTX->hash_CV_len = len; + CTX->hash_CV_id = id; + T0_PUSHi(-1); +} + +\ Verify signature in CertificateVerify. Output is 0 on success, or a +\ non-zero error code. +cc: verify-CV-sig ( sig-len -- err ) { + int err; + + err = verify_CV_sig(CTX, T0_POP()); + T0_PUSHi(err); +} + +\ Process static ECDH. +: process-static-ECDH ( ktu -- ) + \ Static ECDH is allowed only if the cipher suite uses ECDH, and + \ the client's public key has type EC and allows key exchange. + \ BR_KEYTYPE_KEYX is 0x10, and BR_KEYTYPE_EC is 2. + 0x1F and 0x12 = ifnot ERR_WRONG_KEY_USAGE fail then + addr-cipher_suite get16 + dup use-ecdh? ifnot ERR_UNEXPECTED fail then + prf-id + do-static-ecdh ; + +\ Read CertificateVerify header. +: read-CertificateVerify-header ( -- lim ) + compute-hash-CV + read-handshake-header 15 = ifnot ERR_UNEXPECTED fail then ; + +\ Read CertificateVerify. The client key type + usage is expected on the +\ stack. +: read-CertificateVerify ( ktu -- ) + \ Check that the key allows for signatures. + dup 0x20 and ifnot ERR_WRONG_KEY_USAGE fail then + 0x0F and { key-type } + + \ Get header. + read-CertificateVerify-header + + \ With TLS 1.2+, there is an explicit hash + signature indication, + \ which must be compatible with the key type. + addr-version get16 0x0303 >= if + \ Get hash function, then signature algorithm. The + \ signature algorithm is 1 (RSA) or 3 (ECDSA) while our + \ symbolic constants for key types are 1 (RSA) or 2 (EC). + read16 + dup 0xFF and 1+ 1 >> key-type = ifnot + ERR_BAD_SIGNATURE fail + then + 8 >> + + \ We support only SHA-1, SHA-224, SHA-256, SHA-384 + \ and SHA-512. We explicitly reject MD5. + dup 2 < over 6 > or if ERR_INVALID_ALGORITHM fail then + else + \ With TLS 1.0 and 1.1, hash is MD5+SHA-1 (0) for RSA, + \ SHA-1 (2) for ECDSA. + key-type 0x01 = if 0 else 2 then + then + copy-hash-CV ifnot ERR_INVALID_ALGORITHM fail then + + \ Read signature. + read16 dup { sig-len } + dup 512 > if ERR_LIMIT_EXCEEDED fail then + addr-pad swap read-blob + sig-len verify-CV-sig + dup if fail then drop + + close-elt ; + +\ Send a HelloRequest. +: send-HelloRequest ( -- ) + flush-record + begin can-output? not while wait-co drop repeat + 22 addr-record_type_out set8 + 0 write8 0 write24 flush-record + 23 addr-record_type_out set8 ; + +\ Make a handshake. +: do-handshake ( initial -- ) + 0 addr-application_data set8 + 22 addr-record_type_out set8 + 0 addr-selected_protocol set16 + multihash-init + read-ClientHello + more-incoming-bytes? if ERR_UNEXPECTED fail then + if + \ Session resumption + write-ServerHello + 0 write-CCS-Finished + 0 read-CCS-Finished + else + \ Not a session resumption + write-ServerHello + write-Certificate drop + write-ServerKeyExchange + ta-names-total-length if + write-CertificateRequest + then + write-ServerHelloDone + flush-record + + \ If we sent a CertificateRequest then we expect a + \ Certificate message. + ta-names-total-length if + \ Read client certificate. + 0 read-Certificate + + choice + dup 0< uf + \ Client certificate validation failed. + 2 flag? ifnot neg fail then + drop + read-ClientKeyExchange + read-CertificateVerify-header + dup skip-blob drop + enduf + dup 0= uf + \ Client sent no certificate at all. + drop + 2 flag? ifnot + ERR_NO_CLIENT_AUTH fail + then + read-ClientKeyExchange + enduf + + \ Client certificate was validated. + read-ClientKeyExchange-header + dup ifnot + \ Empty ClientKeyExchange. + drop + process-static-ECDH + else + read-ClientKeyExchange-contents + read-CertificateVerify + then + endchoice + else + \ No client certificate request, we just expect + \ a non-empty ClientKeyExchange. + read-ClientKeyExchange + then + 0 read-CCS-Finished + 0 write-CCS-Finished + save-session + then + 1 addr-application_data set8 + 23 addr-record_type_out set8 ; + +\ Entry point. +: main ( -- ! ) + \ Perform initial handshake. + -1 do-handshake + + begin + \ Wait for further invocation. At that point, we should + \ get either an explicit call for renegotiation, or + \ an incoming ClientHello handshake message. + wait-co + dup 0x07 and case + 0x00 of + 0x10 and if + \ The best we can do is ask for a + \ renegotiation, then wait for it + \ to happen. + 0 addr-application_data set8 + send-HelloRequest + then + endof + 0x01 of + \ Reject renegotiations if the peer does not + \ support secure renegotiation, or if the + \ "no renegotiation" flag is set. + drop + addr-reneg get8 1 = 1 flag? or if + skip-ClientHello + flush-record + begin can-output? not while + wait-co drop + repeat + 100 send-warning + \ Put back connection in "application + \ data" state: it's not dead yet. + 1 addr-application_data set8 + 23 addr-record_type_out set8 + else + 0 do-handshake + then + endof + ERR_UNEXPECTED fail + endcase + again + ; diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_io.c b/BearSSL-OG/libbearssl/src/ssl/ssl_io.c new file mode 100644 index 0000000..1952615 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_io.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_sslio_init(br_sslio_context *ctx, + br_ssl_engine_context *engine, + int (*low_read)(void *read_context, + unsigned char *data, size_t len), + void *read_context, + int (*low_write)(void *write_context, + const unsigned char *data, size_t len), + void *write_context) +{ + ctx->engine = engine; + ctx->low_read = low_read; + ctx->read_context = read_context; + ctx->low_write = low_write; + ctx->write_context = write_context; +} + +/* + * Run the engine, until the specified target state is achieved, or + * an error occurs. The target state is SENDAPP, RECVAPP, or the + * combination of both (the combination matches either). When a match is + * achieved, this function returns 0. On error, it returns -1. + */ +static int +run_until(br_sslio_context *ctx, unsigned target) +{ + for (;;) { + unsigned state; + + state = br_ssl_engine_current_state(ctx->engine); + if (state & BR_SSL_CLOSED) { + return -1; + } + + /* + * If there is some record data to send, do it. This takes + * precedence over everything else. + */ + if (state & BR_SSL_SENDREC) { + unsigned char *buf; + size_t len; + int wlen; + + buf = br_ssl_engine_sendrec_buf(ctx->engine, &len); + wlen = ctx->low_write(ctx->write_context, buf, len); + if (wlen < 0) { + /* + * If we received a close_notify and we + * still send something, then we have our + * own response close_notify to send, and + * the peer is allowed by RFC 5246 not to + * wait for it. + */ + if (!ctx->engine->shutdown_recv) { + br_ssl_engine_fail( + ctx->engine, BR_ERR_IO); + } + return -1; + } + if (wlen > 0) { + br_ssl_engine_sendrec_ack(ctx->engine, wlen); + } + continue; + } + + /* + * If we reached our target, then we are finished. + */ + if (state & target) { + return 0; + } + + /* + * If some application data must be read, and we did not + * exit, then this means that we are trying to write data, + * and that's not possible until the application data is + * read. This may happen if using a shared in/out buffer, + * and the underlying protocol is not strictly half-duplex. + * This is unrecoverable here, so we report an error. + */ + if (state & BR_SSL_RECVAPP) { + return -1; + } + + /* + * If we reached that point, then either we are trying + * to read data and there is some, or the engine is stuck + * until a new record is obtained. + */ + if (state & BR_SSL_RECVREC) { + unsigned char *buf; + size_t len; + int rlen; + + buf = br_ssl_engine_recvrec_buf(ctx->engine, &len); + rlen = ctx->low_read(ctx->read_context, buf, len); + if (rlen < 0) { + br_ssl_engine_fail(ctx->engine, BR_ERR_IO); + return -1; + } + if (rlen > 0) { + br_ssl_engine_recvrec_ack(ctx->engine, rlen); + } + continue; + } + + /* + * We can reach that point if the target RECVAPP, and + * the state contains SENDAPP only. This may happen with + * a shared in/out buffer. In that case, we must flush + * the buffered data to "make room" for a new incoming + * record. + */ + br_ssl_engine_flush(ctx->engine, 0); + } +} + +/* see bearssl_ssl.h */ +int +br_sslio_read(br_sslio_context *ctx, void *dst, size_t len) +{ + unsigned char *buf; + size_t alen; + + if (len == 0) { + return 0; + } + if (run_until(ctx, BR_SSL_RECVAPP) < 0) { + return -1; + } + buf = br_ssl_engine_recvapp_buf(ctx->engine, &alen); + if (alen > len) { + alen = len; + } + memcpy(dst, buf, alen); + br_ssl_engine_recvapp_ack(ctx->engine, alen); + return (int)alen; +} + +/* see bearssl_ssl.h */ +int +br_sslio_read_all(br_sslio_context *ctx, void *dst, size_t len) +{ + unsigned char *buf; + + buf = dst; + while (len > 0) { + int rlen; + + rlen = br_sslio_read(ctx, buf, len); + if (rlen < 0) { + return -1; + } + buf += rlen; + len -= (size_t)rlen; + } + return 0; +} + +/* see bearssl_ssl.h */ +int +br_sslio_write(br_sslio_context *ctx, const void *src, size_t len) +{ + unsigned char *buf; + size_t alen; + + if (len == 0) { + return 0; + } + if (run_until(ctx, BR_SSL_SENDAPP) < 0) { + return -1; + } + buf = br_ssl_engine_sendapp_buf(ctx->engine, &alen); + if (alen > len) { + alen = len; + } + memcpy(buf, src, alen); + br_ssl_engine_sendapp_ack(ctx->engine, alen); + return (int)alen; +} + +/* see bearssl_ssl.h */ +int +br_sslio_write_all(br_sslio_context *ctx, const void *src, size_t len) +{ + const unsigned char *buf; + + buf = src; + while (len > 0) { + int wlen; + + wlen = br_sslio_write(ctx, buf, len); + if (wlen < 0) { + return -1; + } + buf += wlen; + len -= (size_t)wlen; + } + return 0; +} + +/* see bearssl_ssl.h */ +int +br_sslio_flush(br_sslio_context *ctx) +{ + /* + * We trigger a flush. We know the data is gone when there is + * no longer any record data to send, and we can either read + * or write application data. The call to run_until() does the + * job because it ensures that any assembled record data is + * first sent down the wire before considering anything else. + */ + br_ssl_engine_flush(ctx->engine, 0); + return run_until(ctx, BR_SSL_SENDAPP | BR_SSL_RECVAPP); +} + +/* see bearssl_ssl.h */ +int +br_sslio_close(br_sslio_context *ctx) +{ + br_ssl_engine_close(ctx->engine); + while (br_ssl_engine_current_state(ctx->engine) != BR_SSL_CLOSED) { + /* + * Discard any incoming application data. + */ + size_t len; + + run_until(ctx, BR_SSL_RECVAPP); + if (br_ssl_engine_recvapp_buf(ctx->engine, &len) != NULL) { + br_ssl_engine_recvapp_ack(ctx->engine, len); + } + } + return br_ssl_engine_last_error(ctx->engine) == BR_ERR_OK; +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_keyexport.c b/BearSSL-OG/libbearssl/src/ssl/ssl_keyexport.c new file mode 100644 index 0000000..58e6dc3 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_keyexport.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Supported cipher suites that use SHA-384 for the PRF when selected + * for TLS 1.2. All other cipher suites are deemed to use SHA-256. + */ +static const uint16_t suites_sha384[] = { + BR_TLS_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 +}; + +/* see bearssl_ssl.h */ +int +br_ssl_key_export(br_ssl_engine_context *cc, + void *dst, size_t len, const char *label, + const void *context, size_t context_len) +{ + br_tls_prf_seed_chunk chunks[4]; + br_tls_prf_impl iprf; + size_t num_chunks, u; + unsigned char tmp[2]; + int prf_id; + + if (cc->application_data != 1) { + return 0; + } + chunks[0].data = cc->client_random; + chunks[0].len = sizeof cc->client_random; + chunks[1].data = cc->server_random; + chunks[1].len = sizeof cc->server_random; + if (context != NULL) { + br_enc16be(tmp, (unsigned)context_len); + chunks[2].data = tmp; + chunks[2].len = 2; + chunks[3].data = context; + chunks[3].len = context_len; + num_chunks = 4; + } else { + num_chunks = 2; + } + prf_id = BR_SSLPRF_SHA256; + for (u = 0; u < (sizeof suites_sha384) / sizeof(uint16_t); u ++) { + if (suites_sha384[u] == cc->session.cipher_suite) { + prf_id = BR_SSLPRF_SHA384; + } + } + iprf = br_ssl_engine_get_PRF(cc, prf_id); + iprf(dst, len, + cc->session.master_secret, sizeof cc->session.master_secret, + label, num_chunks, chunks); + return 1; +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_lru.c b/BearSSL-OG/libbearssl/src/ssl/ssl_lru.c new file mode 100644 index 0000000..6577d5a --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_lru.c @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Each entry consists in a fixed number of bytes. Entries are concatenated + * in the store block. "Addresses" are really offsets in the block, + * expressed over 32 bits (so the cache may have size at most 4 GB, which + * "ought to be enough for everyone"). The "null address" is 0xFFFFFFFF. + * Note that since the storage block alignment is in no way guaranteed, we + * perform only accesses that can handle unaligned data. + * + * Two concurrent data structures are maintained: + * + * -- Entries are organised in a doubly-linked list; saved entries are added + * at the head, and loaded entries are moved to the head. Eviction uses + * the list tail (this is the LRU algorithm). + * + * -- Entries are indexed with a binary tree: all left descendants of a + * node have a lower session ID (in lexicographic order), while all + * right descendants have a higher session ID. The tree is heuristically + * balanced. + * + * Entry format: + * + * session ID 32 bytes + * master secret 48 bytes + * protocol version 2 bytes (big endian) + * cipher suite 2 bytes (big endian) + * list prev 4 bytes (big endian) + * list next 4 bytes (big endian) + * tree left child 4 bytes (big endian) + * tree right child 4 bytes (big endian) + * + * If an entry has a protocol version set to 0, then it is "disabled": + * it was a session pushed to the cache at some point, but it has + * been explicitly removed. + * + * We need to keep the tree balanced because an attacker could make + * handshakes, selecting some specific sessions (by reusing them) to + * try to make us make an imbalanced tree that makes lookups expensive + * (a denial-of-service attack that would persist as long as the cache + * remains, i.e. even after the attacker made all his connections). + * To do that, we replace the session ID (or the start of the session ID) + * with a HMAC value computed over the replaced part; the hash function + * implementation and the key are obtained from the server context upon + * first save() call. + * + * Theoretically, an attacker could use the exact timing of the lookup + * to infer the current tree topology, and try to revive entries to make + * it as unbalanced as possible. However, since the session ID are + * chosen randomly by the server, and the attacker cannot see the + * indexing values and must thus rely on blind selection, it should be + * exponentially difficult for the attacker to maintain a large + * imbalance. + */ +#define SESSION_ID_LEN 32 +#define MASTER_SECRET_LEN 48 + +#define SESSION_ID_OFF 0 +#define MASTER_SECRET_OFF 32 +#define VERSION_OFF 80 +#define CIPHER_SUITE_OFF 82 +#define LIST_PREV_OFF 84 +#define LIST_NEXT_OFF 88 +#define TREE_LEFT_OFF 92 +#define TREE_RIGHT_OFF 96 + +#define LRU_ENTRY_LEN 100 + +#define ADDR_NULL ((uint32_t)-1) + +#define GETSET(name, off) \ +static __inline uint32_t get_ ## name(br_ssl_session_cache_lru *cc, uint32_t x) \ +{ \ + return br_dec32be(cc->store + x + (off)); \ +} \ +static __inline void set_ ## name(br_ssl_session_cache_lru *cc, \ + uint32_t x, uint32_t val) \ +{ \ + br_enc32be(cc->store + x + (off), val); \ +} + +GETSET(prev, LIST_PREV_OFF) +GETSET(next, LIST_NEXT_OFF) +GETSET(left, TREE_LEFT_OFF) +GETSET(right, TREE_RIGHT_OFF) + +/* + * Transform the session ID by replacing the first N bytes with a HMAC + * value computed over these bytes, using the random key K (the HMAC + * value is truncated if needed). HMAC will use the same hash function + * as the DRBG in the SSL server context, so with SHA-256, SHA-384, + * or SHA-1, depending on what is available. + * + * The risk of collision is considered too small to be a concern; and + * the impact of a collision is low (the handshake won't succeed). This + * risk is much lower than any transmission error, which would lead to + * the same consequences. + * + * Source and destination arrays msut be disjoint. + */ +static void +mask_id(br_ssl_session_cache_lru *cc, + const unsigned char *src, unsigned char *dst) +{ + br_hmac_key_context hkc; + br_hmac_context hc; + + memcpy(dst, src, SESSION_ID_LEN); + br_hmac_key_init(&hkc, cc->hash, cc->index_key, sizeof cc->index_key); + br_hmac_init(&hc, &hkc, SESSION_ID_LEN); + br_hmac_update(&hc, src, SESSION_ID_LEN); + br_hmac_out(&hc, dst); +} + +/* + * Find a node by ID. Returned value is the node address, or ADDR_NULL if + * the node is not found. + * + * If addr_link is not NULL, then '*addr_link' is set to the address of the + * last followed link. If the found node is the root, or if the tree is + * empty, then '*addr_link' is set to ADDR_NULL. + */ +static uint32_t +find_node(br_ssl_session_cache_lru *cc, const unsigned char *id, + uint32_t *addr_link) +{ + uint32_t x, y; + + x = cc->root; + y = ADDR_NULL; + while (x != ADDR_NULL) { + int r; + + r = memcmp(id, cc->store + x + SESSION_ID_OFF, SESSION_ID_LEN); + if (r < 0) { + y = x + TREE_LEFT_OFF; + x = get_left(cc, x); + } else if (r == 0) { + if (addr_link != NULL) { + *addr_link = y; + } + return x; + } else { + y = x + TREE_RIGHT_OFF; + x = get_right(cc, x); + } + } + if (addr_link != NULL) { + *addr_link = y; + } + return ADDR_NULL; +} + +/* + * For node x, find its replacement upon removal. + * + * -- If node x has no child, then this returns ADDR_NULL. + * -- Otherwise, if node x has a left child, then the replacement is the + * rightmost left-descendent. + * -- Otherwise, the replacement is the leftmost right-descendent. + * + * If a node is returned, then '*al' is set to the address of the field + * that points to that node. Otherwise (node x has no child), '*al' is + * set to ADDR_NULL. + * + * Note that the replacement node, when found, is always a descendent + * of node 'x', so it cannot be the tree root. Thus, '*al' can be set + * to ADDR_NULL only when no node is found and ADDR_NULL is returned. + */ +static uint32_t +find_replacement_node(br_ssl_session_cache_lru *cc, uint32_t x, uint32_t *al) +{ + uint32_t y1, y2; + + y1 = get_left(cc, x); + if (y1 != ADDR_NULL) { + y2 = x + TREE_LEFT_OFF; + for (;;) { + uint32_t z; + + z = get_right(cc, y1); + if (z == ADDR_NULL) { + *al = y2; + return y1; + } + y2 = y1 + TREE_RIGHT_OFF; + y1 = z; + } + } + y1 = get_right(cc, x); + if (y1 != ADDR_NULL) { + y2 = x + TREE_RIGHT_OFF; + for (;;) { + uint32_t z; + + z = get_left(cc, y1); + if (z == ADDR_NULL) { + *al = y2; + return y1; + } + y2 = y1 + TREE_LEFT_OFF; + y1 = z; + } + } + *al = ADDR_NULL; + return ADDR_NULL; +} + +/* + * Set the link at address 'alx' to point to node 'x'. If 'alx' is + * ADDR_NULL, then this sets the tree root to 'x'. + */ +static __inline void +set_link(br_ssl_session_cache_lru *cc, uint32_t alx, uint32_t x) +{ + if (alx == ADDR_NULL) { + cc->root = x; + } else { + br_enc32be(cc->store + alx, x); + } +} + +/* + * Remove node 'x' from the tree. This function shall not be called if + * node 'x' is not part of the tree. + */ +static void +remove_node(br_ssl_session_cache_lru *cc, uint32_t x) +{ + uint32_t alx, y, aly; + + /* + * Removal algorithm: + * ------------------ + * + * - If we remove the root, then the tree becomes empty. + * + * - If the removed node has no child, then we can simply remove + * it, with nothing else to do. + * + * - Otherwise, the removed node must be replaced by either its + * rightmost left-descendent, or its leftmost right-descendent. + * The replacement node itself must be removed from its current + * place. By definition, that replacement node has either no + * child, or at most a single child that will replace it in the + * tree. + */ + + /* + * Find node back and its ancestor link. If the node was the + * root, then alx is set to ADDR_NULL. + */ + find_node(cc, cc->store + x + SESSION_ID_OFF, &alx); + + /* + * Find replacement node 'y', and 'aly' is set to the address of + * the link to that replacement node. If the removed node has no + * child, then both 'y' and 'aly' are set to ADDR_NULL. + */ + y = find_replacement_node(cc, x, &aly); + + if (y != ADDR_NULL) { + uint32_t z; + + /* + * The unlinked replacement node may have one child (but + * not two) that takes its place. + */ + z = get_left(cc, y); + if (z == ADDR_NULL) { + z = get_right(cc, y); + } + set_link(cc, aly, z); + + /* + * Link the replacement node in its new place, overwriting + * the current link to the node 'x' (which removes 'x'). + */ + set_link(cc, alx, y); + + /* + * The replacement node adopts the left and right children + * of the removed node. Note that this also works even if + * the replacement node was a direct descendent of the + * removed node, since we unlinked it previously. + */ + set_left(cc, y, get_left(cc, x)); + set_right(cc, y, get_right(cc, x)); + } else { + /* + * No replacement, we simply unlink the node 'x'. + */ + set_link(cc, alx, ADDR_NULL); + } +} + +static void +lru_save(const br_ssl_session_cache_class **ctx, + br_ssl_server_context *server_ctx, + const br_ssl_session_parameters *params) +{ + br_ssl_session_cache_lru *cc; + unsigned char id[SESSION_ID_LEN]; + uint32_t x, alx; + + cc = (br_ssl_session_cache_lru *)ctx; + + /* + * If the buffer is too small, we don't record anything. This + * test avoids problems in subsequent code. + */ + if (cc->store_len < LRU_ENTRY_LEN) { + return; + } + + /* + * Upon the first save in a session cache instance, we obtain + * a random key for our indexing. + */ + if (!cc->init_done) { + br_hmac_drbg_generate(&server_ctx->eng.rng, + cc->index_key, sizeof cc->index_key); + cc->hash = br_hmac_drbg_get_hash(&server_ctx->eng.rng); + cc->init_done = 1; + } + mask_id(cc, params->session_id, id); + + /* + * Look for the node in the tree. If the same ID is already used, + * then reject it. This is a collision event, which should be + * exceedingly rare. + * Note: we do NOT record the emplacement here, because the + * removal of an entry may change the tree topology. + */ + if (find_node(cc, id, NULL) != ADDR_NULL) { + return; + } + + /* + * Find some room for the new parameters. If the cache is not + * full yet, add it to the end of the area and bump the pointer up. + * Otherwise, evict the list tail entry. Note that we already + * filtered out the case of a ridiculously small buffer that + * cannot hold any entry at all; thus, if there is no room for an + * extra entry, then the cache cannot be empty. + */ + if (cc->store_ptr > (cc->store_len - LRU_ENTRY_LEN)) { + /* + * Evict tail. If the buffer has room for a single entry, + * then this may also be the head. + */ + x = cc->tail; + cc->tail = get_prev(cc, x); + if (cc->tail == ADDR_NULL) { + cc->head = ADDR_NULL; + } else { + set_next(cc, cc->tail, ADDR_NULL); + } + + /* + * Remove the node from the tree. + */ + remove_node(cc, x); + } else { + /* + * Allocate room for new node. + */ + x = cc->store_ptr; + cc->store_ptr += LRU_ENTRY_LEN; + } + + /* + * Find the emplacement for the new node, and link it. + */ + find_node(cc, id, &alx); + set_link(cc, alx, x); + set_left(cc, x, ADDR_NULL); + set_right(cc, x, ADDR_NULL); + + /* + * New entry becomes new list head. It may also become the list + * tail if the cache was empty at that point. + */ + if (cc->head == ADDR_NULL) { + cc->tail = x; + } else { + set_prev(cc, cc->head, x); + } + set_prev(cc, x, ADDR_NULL); + set_next(cc, x, cc->head); + cc->head = x; + + /* + * Fill data in the entry. + */ + memcpy(cc->store + x + SESSION_ID_OFF, id, SESSION_ID_LEN); + memcpy(cc->store + x + MASTER_SECRET_OFF, + params->master_secret, MASTER_SECRET_LEN); + br_enc16be(cc->store + x + VERSION_OFF, params->version); + br_enc16be(cc->store + x + CIPHER_SUITE_OFF, params->cipher_suite); +} + +static int +lru_load(const br_ssl_session_cache_class **ctx, + br_ssl_server_context *server_ctx, + br_ssl_session_parameters *params) +{ + br_ssl_session_cache_lru *cc; + unsigned char id[SESSION_ID_LEN]; + uint32_t x; + + (void)server_ctx; + cc = (br_ssl_session_cache_lru *)ctx; + if (!cc->init_done) { + return 0; + } + mask_id(cc, params->session_id, id); + x = find_node(cc, id, NULL); + if (x != ADDR_NULL) { + unsigned version; + + version = br_dec16be(cc->store + x + VERSION_OFF); + if (version == 0) { + /* + * Entry is disabled, we pretend we did not find it. + * Notably, we don't move it to the front of the + * LRU list. + */ + return 0; + } + params->version = version; + params->cipher_suite = br_dec16be( + cc->store + x + CIPHER_SUITE_OFF); + memcpy(params->master_secret, + cc->store + x + MASTER_SECRET_OFF, + MASTER_SECRET_LEN); + if (x != cc->head) { + /* + * Found node is not at list head, so move + * it to the head. + */ + uint32_t p, n; + + p = get_prev(cc, x); + n = get_next(cc, x); + set_next(cc, p, n); + if (n == ADDR_NULL) { + cc->tail = p; + } else { + set_prev(cc, n, p); + } + set_prev(cc, cc->head, x); + set_next(cc, x, cc->head); + set_prev(cc, x, ADDR_NULL); + cc->head = x; + } + return 1; + } + return 0; +} + +static const br_ssl_session_cache_class lru_class = { + sizeof(br_ssl_session_cache_lru), + &lru_save, + &lru_load +}; + +/* see inner.h */ +void +br_ssl_session_cache_lru_init(br_ssl_session_cache_lru *cc, + unsigned char *store, size_t store_len) +{ + cc->vtable = &lru_class; + cc->store = store; + cc->store_len = store_len; + cc->store_ptr = 0; + cc->init_done = 0; + cc->head = ADDR_NULL; + cc->tail = ADDR_NULL; + cc->root = ADDR_NULL; +} + +/* see bearssl_ssl.h */ +void br_ssl_session_cache_lru_forget( + br_ssl_session_cache_lru *cc, const unsigned char *id) +{ + unsigned char mid[SESSION_ID_LEN]; + uint32_t addr; + + /* + * If the cache is not initialised yet, then it is empty, and + * there is nothing to forget. + */ + if (!cc->init_done) { + return; + } + + /* + * Look for the node in the tree. If found, the entry is marked + * as "disabled"; it will be reused in due course, as it ages + * through the list. + * + * We do not go through the complex moves of actually releasing + * the entry right away because explicitly forgetting sessions + * should be a rare event, meant mostly for testing purposes, + * so this is not worth the extra code size. + */ + mask_id(cc, id, mid); + addr = find_node(cc, mid, NULL); + if (addr != ADDR_NULL) { + br_enc16be(cc->store + addr + VERSION_OFF, 0); + } +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_rec_cbc.c b/BearSSL-OG/libbearssl/src/ssl/ssl_rec_cbc.c new file mode 100644 index 0000000..765efcc --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_rec_cbc.c @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static void +in_cbc_init(br_sslrec_in_cbc_context *cc, + const br_block_cbcdec_class *bc_impl, + const void *bc_key, size_t bc_key_len, + const br_hash_class *dig_impl, + const void *mac_key, size_t mac_key_len, size_t mac_out_len, + const void *iv) +{ + cc->vtable = &br_sslrec_in_cbc_vtable; + cc->seq = 0; + bc_impl->init(&cc->bc.vtable, bc_key, bc_key_len); + br_hmac_key_init(&cc->mac, dig_impl, mac_key, mac_key_len); + cc->mac_len = mac_out_len; + if (iv == NULL) { + memset(cc->iv, 0, sizeof cc->iv); + cc->explicit_IV = 1; + } else { + memcpy(cc->iv, iv, bc_impl->block_size); + cc->explicit_IV = 0; + } +} + +static int +cbc_check_length(const br_sslrec_in_cbc_context *cc, size_t rlen) +{ + /* + * Plaintext size: at most 16384 bytes + * Padding: at most 256 bytes + * MAC: mac_len extra bytes + * TLS 1.1+: each record has an explicit IV + * + * Minimum length includes at least one byte of padding, and the + * MAC. + * + * Total length must be a multiple of the block size. + */ + size_t blen; + size_t min_len, max_len; + + blen = cc->bc.vtable->block_size; + min_len = (blen + cc->mac_len) & ~(blen - 1); + max_len = (16384 + 256 + cc->mac_len) & ~(blen - 1); + if (cc->explicit_IV) { + min_len += blen; + max_len += blen; + } + return min_len <= rlen && rlen <= max_len; +} + +/* + * Rotate array buf[] of length 'len' to the left (towards low indices) + * by 'num' bytes if ctl is 1; otherwise, leave it unchanged. This is + * constant-time. 'num' MUST be lower than 'len'. 'len' MUST be lower + * than or equal to 64. + */ +static void +cond_rotate(uint32_t ctl, unsigned char *buf, size_t len, size_t num) +{ + unsigned char tmp[64]; + size_t u, v; + + for (u = 0, v = num; u < len; u ++) { + tmp[u] = (unsigned char)MUX(ctl, buf[v], buf[u]); + if (++ v == len) { + v = 0; + } + } + memcpy(buf, tmp, len); +} + +static unsigned char * +cbc_decrypt(br_sslrec_in_cbc_context *cc, + int record_type, unsigned version, void *data, size_t *data_len) +{ + /* + * We represent all lengths on 32-bit integers, because: + * -- SSL record lengths always fit in 32 bits; + * -- our constant-time primitives operate on 32-bit integers. + */ + unsigned char *buf; + uint32_t u, v, len, blen, min_len, max_len; + uint32_t good, pad_len, rot_count, len_withmac, len_nomac; + unsigned char tmp1[64], tmp2[64]; + int i; + br_hmac_context hc; + + buf = data; + len = *data_len; + blen = cc->bc.vtable->block_size; + + /* + * Decrypt data, and skip the explicit IV (if applicable). Note + * that the total length is supposed to have been verified by + * the caller. If there is an explicit IV, then we actually + * "decrypt" it using the implicit IV (from previous record), + * which is useless but harmless. + */ + cc->bc.vtable->run(&cc->bc.vtable, cc->iv, data, len); + if (cc->explicit_IV) { + buf += blen; + len -= blen; + } + + /* + * Compute minimum and maximum length of plaintext + MAC. These + * lengths can be inferred from the outside: they are not secret. + */ + min_len = (cc->mac_len + 256 < len) ? len - 256 : cc->mac_len; + max_len = len - 1; + + /* + * Use the last decrypted byte to compute the actual payload + * length. Take care not to overflow (we use unsigned types). + */ + pad_len = buf[max_len]; + good = LE(pad_len, (uint32_t)(max_len - min_len)); + len = MUX(good, (uint32_t)(max_len - pad_len), min_len); + + /* + * Check padding contents: all padding bytes must be equal to + * the value of pad_len. + */ + for (u = min_len; u < max_len; u ++) { + good &= LT(u, len) | EQ(buf[u], pad_len); + } + + /* + * Extract the MAC value. This is done in one pass, but results + * in a "rotated" MAC value depending on where it actually + * occurs. The 'rot_count' value is set to the offset of the + * first MAC byte within tmp1[]. + * + * min_len and max_len are also adjusted to the minimum and + * maximum lengths of the plaintext alone (without the MAC). + */ + len_withmac = (uint32_t)len; + len_nomac = len_withmac - cc->mac_len; + min_len -= cc->mac_len; + rot_count = 0; + memset(tmp1, 0, cc->mac_len); + v = 0; + for (u = min_len; u < max_len; u ++) { + tmp1[v] |= MUX(GE(u, len_nomac) & LT(u, len_withmac), + buf[u], 0x00); + rot_count = MUX(EQ(u, len_nomac), v, rot_count); + if (++ v == cc->mac_len) { + v = 0; + } + } + max_len -= cc->mac_len; + + /* + * Rotate back the MAC value. The loop below does the constant-time + * rotation in time n*log n for a MAC output of length n. We assume + * that the MAC output length is no more than 64 bytes, so the + * rotation count fits on 6 bits. + */ + for (i = 5; i >= 0; i --) { + uint32_t rc; + + rc = (uint32_t)1 << i; + cond_rotate(rot_count >> i, tmp1, cc->mac_len, rc); + rot_count &= ~rc; + } + + /* + * Recompute the HMAC value. The input is the concatenation of + * the sequence number (8 bytes), the record header (5 bytes), + * and the payload. + * + * At that point, min_len is the minimum plaintext length, but + * max_len still includes the MAC length. + */ + br_enc64be(tmp2, cc->seq ++); + tmp2[8] = (unsigned char)record_type; + br_enc16be(tmp2 + 9, version); + br_enc16be(tmp2 + 11, len_nomac); + br_hmac_init(&hc, &cc->mac, cc->mac_len); + br_hmac_update(&hc, tmp2, 13); + br_hmac_outCT(&hc, buf, len_nomac, min_len, max_len, tmp2); + + /* + * Compare the extracted and recomputed MAC values. + */ + for (u = 0; u < cc->mac_len; u ++) { + good &= EQ0(tmp1[u] ^ tmp2[u]); + } + + /* + * Check that the plaintext length is valid. The previous + * check was on the encrypted length, but the padding may have + * turned shorter than expected. + * + * Once this final test is done, the critical "constant-time" + * section ends and we can make conditional jumps again. + */ + good &= LE(len_nomac, 16384); + + if (!good) { + return 0; + } + *data_len = len_nomac; + return buf; +} + +/* see bearssl_ssl.h */ +const br_sslrec_in_cbc_class br_sslrec_in_cbc_vtable = { + { + sizeof(br_sslrec_in_cbc_context), + (int (*)(const br_sslrec_in_class *const *, size_t)) + &cbc_check_length, + (unsigned char *(*)(const br_sslrec_in_class **, + int, unsigned, void *, size_t *)) + &cbc_decrypt + }, + (void (*)(const br_sslrec_in_cbc_class **, + const br_block_cbcdec_class *, const void *, size_t, + const br_hash_class *, const void *, size_t, size_t, + const void *)) + &in_cbc_init +}; + +/* + * For CBC output: + * + * -- With TLS 1.1+, there is an explicit IV. Generation method uses + * HMAC, computed over the current sequence number, and the current MAC + * key. The resulting value is truncated to the size of a block, and + * added at the head of the plaintext; it will get encrypted along with + * the data. This custom generation mechanism is "safe" under the + * assumption that HMAC behaves like a random oracle; since the MAC for + * a record is computed over the concatenation of the sequence number, + * the record header and the plaintext, the HMAC-for-IV will not collide + * with the normal HMAC. + * + * -- With TLS 1.0, for application data, we want to enforce a 1/n-1 + * split, as a countermeasure against chosen-plaintext attacks. We thus + * need to leave some room in the buffer for that extra record. + */ + +static void +out_cbc_init(br_sslrec_out_cbc_context *cc, + const br_block_cbcenc_class *bc_impl, + const void *bc_key, size_t bc_key_len, + const br_hash_class *dig_impl, + const void *mac_key, size_t mac_key_len, size_t mac_out_len, + const void *iv) +{ + cc->vtable = &br_sslrec_out_cbc_vtable; + cc->seq = 0; + bc_impl->init(&cc->bc.vtable, bc_key, bc_key_len); + br_hmac_key_init(&cc->mac, dig_impl, mac_key, mac_key_len); + cc->mac_len = mac_out_len; + if (iv == NULL) { + memset(cc->iv, 0, sizeof cc->iv); + cc->explicit_IV = 1; + } else { + memcpy(cc->iv, iv, bc_impl->block_size); + cc->explicit_IV = 0; + } +} + +static void +cbc_max_plaintext(const br_sslrec_out_cbc_context *cc, + size_t *start, size_t *end) +{ + size_t blen, len; + + blen = cc->bc.vtable->block_size; + if (cc->explicit_IV) { + *start += blen; + } else { + *start += 4 + ((cc->mac_len + blen + 1) & ~(blen - 1)); + } + len = (*end - *start) & ~(blen - 1); + len -= 1 + cc->mac_len; + if (len > 16384) { + len = 16384; + } + *end = *start + len; +} + +static unsigned char * +cbc_encrypt(br_sslrec_out_cbc_context *cc, + int record_type, unsigned version, void *data, size_t *data_len) +{ + unsigned char *buf, *rbuf; + size_t len, blen, plen; + unsigned char tmp[13]; + br_hmac_context hc; + + buf = data; + len = *data_len; + blen = cc->bc.vtable->block_size; + + /* + * If using TLS 1.0, with more than one byte of plaintext, and + * the record is application data, then we need to compute + * a "split". We do not perform the split on other record types + * because it turned out that some existing, deployed + * implementations of SSL/TLS do not tolerate the splitting of + * some message types (in particular the Finished message). + * + * If using TLS 1.1+, then there is an explicit IV. We produce + * that IV by adding an extra initial plaintext block, whose + * value is computed with HMAC over the record sequence number. + */ + if (cc->explicit_IV) { + /* + * We use here the fact that all the HMAC variants we + * support can produce at least 16 bytes, while all the + * block ciphers we support have blocks of no more than + * 16 bytes. Thus, we can always truncate the HMAC output + * down to the block size. + */ + br_enc64be(tmp, cc->seq); + br_hmac_init(&hc, &cc->mac, blen); + br_hmac_update(&hc, tmp, 8); + br_hmac_out(&hc, buf - blen); + rbuf = buf - blen - 5; + } else { + if (len > 1 && record_type == BR_SSL_APPLICATION_DATA) { + /* + * To do the split, we use a recursive invocation; + * since we only give one byte to the inner call, + * the recursion stops there. + * + * We need to compute the exact size of the extra + * record, so that the two resulting records end up + * being sequential in RAM. + * + * We use here the fact that cbc_max_plaintext() + * adjusted the start offset to leave room for the + * initial fragment. + */ + size_t xlen; + + rbuf = buf - 4 + - ((cc->mac_len + blen + 1) & ~(blen - 1)); + rbuf[0] = buf[0]; + xlen = 1; + rbuf = cbc_encrypt(cc, record_type, + version, rbuf, &xlen); + buf ++; + len --; + } else { + rbuf = buf - 5; + } + } + + /* + * Compute MAC. + */ + br_enc64be(tmp, cc->seq ++); + tmp[8] = record_type; + br_enc16be(tmp + 9, version); + br_enc16be(tmp + 11, len); + br_hmac_init(&hc, &cc->mac, cc->mac_len); + br_hmac_update(&hc, tmp, 13); + br_hmac_update(&hc, buf, len); + br_hmac_out(&hc, buf + len); + len += cc->mac_len; + + /* + * Add padding. + */ + plen = blen - (len & (blen - 1)); + memset(buf + len, (unsigned)plen - 1, plen); + len += plen; + + /* + * If an explicit IV is used, the corresponding extra block was + * already put in place earlier; we just have to account for it + * here. + */ + if (cc->explicit_IV) { + buf -= blen; + len += blen; + } + + /* + * Encrypt the whole thing. If there is an explicit IV, we also + * encrypt it, which is fine (encryption of a uniformly random + * block is still a uniformly random block). + */ + cc->bc.vtable->run(&cc->bc.vtable, cc->iv, buf, len); + + /* + * Add the header and return. + */ + buf[-5] = record_type; + br_enc16be(buf - 4, version); + br_enc16be(buf - 2, len); + *data_len = (size_t)((buf + len) - rbuf); + return rbuf; +} + +/* see bearssl_ssl.h */ +const br_sslrec_out_cbc_class br_sslrec_out_cbc_vtable = { + { + sizeof(br_sslrec_out_cbc_context), + (void (*)(const br_sslrec_out_class *const *, + size_t *, size_t *)) + &cbc_max_plaintext, + (unsigned char *(*)(const br_sslrec_out_class **, + int, unsigned, void *, size_t *)) + &cbc_encrypt + }, + (void (*)(const br_sslrec_out_cbc_class **, + const br_block_cbcenc_class *, const void *, size_t, + const br_hash_class *, const void *, size_t, size_t, + const void *)) + &out_cbc_init +}; diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_rec_ccm.c b/BearSSL-OG/libbearssl/src/ssl/ssl_rec_ccm.c new file mode 100644 index 0000000..92c3295 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_rec_ccm.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * CCM initialisation. This does everything except setting the vtable, + * which depends on whether this is a context for encrypting or for + * decrypting. + */ +static void +gen_ccm_init(br_sslrec_ccm_context *cc, + const br_block_ctrcbc_class *bc_impl, + const void *key, size_t key_len, + const void *iv, size_t tag_len) +{ + cc->seq = 0; + bc_impl->init(&cc->bc.vtable, key, key_len); + memcpy(cc->iv, iv, sizeof cc->iv); + cc->tag_len = tag_len; +} + +static void +in_ccm_init(br_sslrec_ccm_context *cc, + const br_block_ctrcbc_class *bc_impl, + const void *key, size_t key_len, + const void *iv, size_t tag_len) +{ + cc->vtable.in = &br_sslrec_in_ccm_vtable; + gen_ccm_init(cc, bc_impl, key, key_len, iv, tag_len); +} + +static int +ccm_check_length(const br_sslrec_ccm_context *cc, size_t rlen) +{ + /* + * CCM overhead is 8 bytes for nonce_explicit, and the tag + * (normally 8 or 16 bytes, depending on cipher suite). + */ + size_t over; + + over = 8 + cc->tag_len; + return rlen >= over && rlen <= (16384 + over); +} + +static unsigned char * +ccm_decrypt(br_sslrec_ccm_context *cc, + int record_type, unsigned version, void *data, size_t *data_len) +{ + br_ccm_context zc; + unsigned char *buf; + unsigned char nonce[12], header[13]; + size_t len; + + buf = (unsigned char *)data + 8; + len = *data_len - (8 + cc->tag_len); + + /* + * Make nonce (implicit + explicit parts). + */ + memcpy(nonce, cc->iv, sizeof cc->iv); + memcpy(nonce + 4, data, 8); + + /* + * Assemble synthetic header for the AAD. + */ + br_enc64be(header, cc->seq ++); + header[8] = (unsigned char)record_type; + br_enc16be(header + 9, version); + br_enc16be(header + 11, len); + + /* + * Perform CCM decryption. + */ + br_ccm_init(&zc, &cc->bc.vtable); + br_ccm_reset(&zc, nonce, sizeof nonce, sizeof header, len, cc->tag_len); + br_ccm_aad_inject(&zc, header, sizeof header); + br_ccm_flip(&zc); + br_ccm_run(&zc, 0, buf, len); + if (!br_ccm_check_tag(&zc, buf + len)) { + return NULL; + } + *data_len = len; + return buf; +} + +/* see bearssl_ssl.h */ +const br_sslrec_in_ccm_class br_sslrec_in_ccm_vtable = { + { + sizeof(br_sslrec_ccm_context), + (int (*)(const br_sslrec_in_class *const *, size_t)) + &ccm_check_length, + (unsigned char *(*)(const br_sslrec_in_class **, + int, unsigned, void *, size_t *)) + &ccm_decrypt + }, + (void (*)(const br_sslrec_in_ccm_class **, + const br_block_ctrcbc_class *, const void *, size_t, + const void *, size_t)) + &in_ccm_init +}; + +static void +out_ccm_init(br_sslrec_ccm_context *cc, + const br_block_ctrcbc_class *bc_impl, + const void *key, size_t key_len, + const void *iv, size_t tag_len) +{ + cc->vtable.out = &br_sslrec_out_ccm_vtable; + gen_ccm_init(cc, bc_impl, key, key_len, iv, tag_len); +} + +static void +ccm_max_plaintext(const br_sslrec_ccm_context *cc, + size_t *start, size_t *end) +{ + size_t len; + + *start += 8; + len = *end - *start - cc->tag_len; + if (len > 16384) { + len = 16384; + } + *end = *start + len; +} + +static unsigned char * +ccm_encrypt(br_sslrec_ccm_context *cc, + int record_type, unsigned version, void *data, size_t *data_len) +{ + br_ccm_context zc; + unsigned char *buf; + unsigned char nonce[12], header[13]; + size_t len; + + buf = (unsigned char *)data; + len = *data_len; + + /* + * Make nonce; the explicit part is an encoding of the sequence + * number. + */ + memcpy(nonce, cc->iv, sizeof cc->iv); + br_enc64be(nonce + 4, cc->seq); + + /* + * Assemble synthetic header for the AAD. + */ + br_enc64be(header, cc->seq ++); + header[8] = (unsigned char)record_type; + br_enc16be(header + 9, version); + br_enc16be(header + 11, len); + + /* + * Perform CCM encryption. + */ + br_ccm_init(&zc, &cc->bc.vtable); + br_ccm_reset(&zc, nonce, sizeof nonce, sizeof header, len, cc->tag_len); + br_ccm_aad_inject(&zc, header, sizeof header); + br_ccm_flip(&zc); + br_ccm_run(&zc, 1, buf, len); + br_ccm_get_tag(&zc, buf + len); + + /* + * Assemble header and adjust pointer/length. + */ + len += 8 + cc->tag_len; + buf -= 13; + memcpy(buf + 5, nonce + 4, 8); + buf[0] = (unsigned char)record_type; + br_enc16be(buf + 1, version); + br_enc16be(buf + 3, len); + *data_len = len + 5; + return buf; +} + +/* see bearssl_ssl.h */ +const br_sslrec_out_ccm_class br_sslrec_out_ccm_vtable = { + { + sizeof(br_sslrec_ccm_context), + (void (*)(const br_sslrec_out_class *const *, + size_t *, size_t *)) + &ccm_max_plaintext, + (unsigned char *(*)(const br_sslrec_out_class **, + int, unsigned, void *, size_t *)) + &ccm_encrypt + }, + (void (*)(const br_sslrec_out_ccm_class **, + const br_block_ctrcbc_class *, const void *, size_t, + const void *, size_t)) + &out_ccm_init +}; diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_rec_chapol.c b/BearSSL-OG/libbearssl/src/ssl/ssl_rec_chapol.c new file mode 100644 index 0000000..73b3c78 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_rec_chapol.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static void +gen_chapol_init(br_sslrec_chapol_context *cc, + br_chacha20_run ichacha, br_poly1305_run ipoly, + const void *key, const void *iv) +{ + cc->seq = 0; + cc->ichacha = ichacha; + cc->ipoly = ipoly; + memcpy(cc->key, key, sizeof cc->key); + memcpy(cc->iv, iv, sizeof cc->iv); +} + +static void +gen_chapol_process(br_sslrec_chapol_context *cc, + int record_type, unsigned version, void *data, size_t len, + void *tag, int encrypt) +{ + unsigned char header[13]; + unsigned char nonce[12]; + uint64_t seq; + size_t u; + + seq = cc->seq ++; + br_enc64be(header, seq); + header[8] = (unsigned char)record_type; + br_enc16be(header + 9, version); + br_enc16be(header + 11, len); + memcpy(nonce, cc->iv, 12); + for (u = 0; u < 8; u ++) { + nonce[11 - u] ^= (unsigned char)seq; + seq >>= 8; + } + cc->ipoly(cc->key, nonce, data, len, header, sizeof header, + tag, cc->ichacha, encrypt); +} + +static void +in_chapol_init(br_sslrec_chapol_context *cc, + br_chacha20_run ichacha, br_poly1305_run ipoly, + const void *key, const void *iv) +{ + cc->vtable.in = &br_sslrec_in_chapol_vtable; + gen_chapol_init(cc, ichacha, ipoly, key, iv); +} + +static int +chapol_check_length(const br_sslrec_chapol_context *cc, size_t rlen) +{ + /* + * Overhead is just the authentication tag (16 bytes). + */ + (void)cc; + return rlen >= 16 && rlen <= (16384 + 16); +} + +static unsigned char * +chapol_decrypt(br_sslrec_chapol_context *cc, + int record_type, unsigned version, void *data, size_t *data_len) +{ + unsigned char *buf; + size_t u, len; + unsigned char tag[16]; + unsigned bad; + + buf = data; + len = *data_len - 16; + gen_chapol_process(cc, record_type, version, buf, len, tag, 0); + bad = 0; + for (u = 0; u < 16; u ++) { + bad |= tag[u] ^ buf[len + u]; + } + if (bad) { + return NULL; + } + *data_len = len; + return buf; +} + +/* see bearssl_ssl.h */ +const br_sslrec_in_chapol_class br_sslrec_in_chapol_vtable = { + { + sizeof(br_sslrec_chapol_context), + (int (*)(const br_sslrec_in_class *const *, size_t)) + &chapol_check_length, + (unsigned char *(*)(const br_sslrec_in_class **, + int, unsigned, void *, size_t *)) + &chapol_decrypt + }, + (void (*)(const br_sslrec_in_chapol_class **, + br_chacha20_run, br_poly1305_run, + const void *, const void *)) + &in_chapol_init +}; + +static void +out_chapol_init(br_sslrec_chapol_context *cc, + br_chacha20_run ichacha, br_poly1305_run ipoly, + const void *key, const void *iv) +{ + cc->vtable.out = &br_sslrec_out_chapol_vtable; + gen_chapol_init(cc, ichacha, ipoly, key, iv); +} + +static void +chapol_max_plaintext(const br_sslrec_chapol_context *cc, + size_t *start, size_t *end) +{ + size_t len; + + (void)cc; + len = *end - *start - 16; + if (len > 16384) { + len = 16384; + } + *end = *start + len; +} + +static unsigned char * +chapol_encrypt(br_sslrec_chapol_context *cc, + int record_type, unsigned version, void *data, size_t *data_len) +{ + unsigned char *buf; + size_t len; + + buf = data; + len = *data_len; + gen_chapol_process(cc, record_type, version, buf, len, buf + len, 1); + buf -= 5; + buf[0] = (unsigned char)record_type; + br_enc16be(buf + 1, version); + br_enc16be(buf + 3, len + 16); + *data_len = len + 21; + return buf; +} + +/* see bearssl_ssl.h */ +const br_sslrec_out_chapol_class br_sslrec_out_chapol_vtable = { + { + sizeof(br_sslrec_chapol_context), + (void (*)(const br_sslrec_out_class *const *, + size_t *, size_t *)) + &chapol_max_plaintext, + (unsigned char *(*)(const br_sslrec_out_class **, + int, unsigned, void *, size_t *)) + &chapol_encrypt + }, + (void (*)(const br_sslrec_out_chapol_class **, + br_chacha20_run, br_poly1305_run, + const void *, const void *)) + &out_chapol_init +}; diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_rec_gcm.c b/BearSSL-OG/libbearssl/src/ssl/ssl_rec_gcm.c new file mode 100644 index 0000000..70df277 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_rec_gcm.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * GCM initialisation. This does everything except setting the vtable, + * which depends on whether this is a context for encrypting or for + * decrypting. + */ +static void +gen_gcm_init(br_sslrec_gcm_context *cc, + const br_block_ctr_class *bc_impl, + const void *key, size_t key_len, + br_ghash gh_impl, + const void *iv) +{ + unsigned char tmp[12]; + + cc->seq = 0; + bc_impl->init(&cc->bc.vtable, key, key_len); + cc->gh = gh_impl; + memcpy(cc->iv, iv, sizeof cc->iv); + memset(cc->h, 0, sizeof cc->h); + memset(tmp, 0, sizeof tmp); + bc_impl->run(&cc->bc.vtable, tmp, 0, cc->h, sizeof cc->h); +} + +static void +in_gcm_init(br_sslrec_gcm_context *cc, + const br_block_ctr_class *bc_impl, + const void *key, size_t key_len, + br_ghash gh_impl, + const void *iv) +{ + cc->vtable.in = &br_sslrec_in_gcm_vtable; + gen_gcm_init(cc, bc_impl, key, key_len, gh_impl, iv); +} + +static int +gcm_check_length(const br_sslrec_gcm_context *cc, size_t rlen) +{ + /* + * GCM adds a fixed overhead: + * 8 bytes for the nonce_explicit (before the ciphertext) + * 16 bytes for the authentication tag (after the ciphertext) + */ + (void)cc; + return rlen >= 24 && rlen <= (16384 + 24); +} + +/* + * Compute the authentication tag. The value written in 'tag' must still + * be CTR-encrypted. + */ +static void +do_tag(br_sslrec_gcm_context *cc, + int record_type, unsigned version, + void *data, size_t len, void *tag) +{ + unsigned char header[13]; + unsigned char footer[16]; + + /* + * Compute authentication tag. Three elements must be injected in + * sequence, each possibly 0-padded to reach a length multiple + * of the block size: the 13-byte header (sequence number, record + * type, protocol version, record length), the cipher text, and + * the word containing the encodings of the bit lengths of the two + * other elements. + */ + br_enc64be(header, cc->seq ++); + header[8] = (unsigned char)record_type; + br_enc16be(header + 9, version); + br_enc16be(header + 11, len); + br_enc64be(footer, (uint64_t)(sizeof header) << 3); + br_enc64be(footer + 8, (uint64_t)len << 3); + memset(tag, 0, 16); + cc->gh(tag, cc->h, header, sizeof header); + cc->gh(tag, cc->h, data, len); + cc->gh(tag, cc->h, footer, sizeof footer); +} + +/* + * Do CTR encryption. This also does CTR encryption of a single block at + * address 'xortag' with the counter value appropriate for the final + * processing of the authentication tag. + */ +static void +do_ctr(br_sslrec_gcm_context *cc, const void *nonce, void *data, size_t len, + void *xortag) +{ + unsigned char iv[12]; + + memcpy(iv, cc->iv, 4); + memcpy(iv + 4, nonce, 8); + cc->bc.vtable->run(&cc->bc.vtable, iv, 2, data, len); + cc->bc.vtable->run(&cc->bc.vtable, iv, 1, xortag, 16); +} + +static unsigned char * +gcm_decrypt(br_sslrec_gcm_context *cc, + int record_type, unsigned version, void *data, size_t *data_len) +{ + unsigned char *buf; + size_t len, u; + uint32_t bad; + unsigned char tag[16]; + + buf = (unsigned char *)data + 8; + len = *data_len - 24; + do_tag(cc, record_type, version, buf, len, tag); + do_ctr(cc, data, buf, len, tag); + + /* + * Compare the computed tag with the value from the record. It + * is possibly useless to do a constant-time comparison here, + * but it does not hurt. + */ + bad = 0; + for (u = 0; u < 16; u ++) { + bad |= tag[u] ^ buf[len + u]; + } + if (bad) { + return NULL; + } + *data_len = len; + return buf; +} + +/* see bearssl_ssl.h */ +const br_sslrec_in_gcm_class br_sslrec_in_gcm_vtable = { + { + sizeof(br_sslrec_gcm_context), + (int (*)(const br_sslrec_in_class *const *, size_t)) + &gcm_check_length, + (unsigned char *(*)(const br_sslrec_in_class **, + int, unsigned, void *, size_t *)) + &gcm_decrypt + }, + (void (*)(const br_sslrec_in_gcm_class **, + const br_block_ctr_class *, const void *, size_t, + br_ghash, const void *)) + &in_gcm_init +}; + +static void +out_gcm_init(br_sslrec_gcm_context *cc, + const br_block_ctr_class *bc_impl, + const void *key, size_t key_len, + br_ghash gh_impl, + const void *iv) +{ + cc->vtable.out = &br_sslrec_out_gcm_vtable; + gen_gcm_init(cc, bc_impl, key, key_len, gh_impl, iv); +} + +static void +gcm_max_plaintext(const br_sslrec_gcm_context *cc, + size_t *start, size_t *end) +{ + size_t len; + + (void)cc; + *start += 8; + len = *end - *start - 16; + if (len > 16384) { + len = 16384; + } + *end = *start + len; +} + +static unsigned char * +gcm_encrypt(br_sslrec_gcm_context *cc, + int record_type, unsigned version, void *data, size_t *data_len) +{ + unsigned char *buf; + size_t u, len; + unsigned char tmp[16]; + + buf = (unsigned char *)data; + len = *data_len; + memset(tmp, 0, sizeof tmp); + br_enc64be(buf - 8, cc->seq); + do_ctr(cc, buf - 8, buf, len, tmp); + do_tag(cc, record_type, version, buf, len, buf + len); + for (u = 0; u < 16; u ++) { + buf[len + u] ^= tmp[u]; + } + len += 24; + buf -= 13; + buf[0] = (unsigned char)record_type; + br_enc16be(buf + 1, version); + br_enc16be(buf + 3, len); + *data_len = len + 5; + return buf; +} + +/* see bearssl_ssl.h */ +const br_sslrec_out_gcm_class br_sslrec_out_gcm_vtable = { + { + sizeof(br_sslrec_gcm_context), + (void (*)(const br_sslrec_out_class *const *, + size_t *, size_t *)) + &gcm_max_plaintext, + (unsigned char *(*)(const br_sslrec_out_class **, + int, unsigned, void *, size_t *)) + &gcm_encrypt + }, + (void (*)(const br_sslrec_out_gcm_class **, + const br_block_ctr_class *, const void *, size_t, + br_ghash, const void *)) + &out_gcm_init +}; diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_scert_single_ec.c b/BearSSL-OG/libbearssl/src/ssl/ssl_scert_single_ec.c new file mode 100644 index 0000000..ce8d753 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_scert_single_ec.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static int +se_choose(const br_ssl_server_policy_class **pctx, + const br_ssl_server_context *cc, + br_ssl_server_choices *choices) +{ + br_ssl_server_policy_ec_context *pc; + const br_suite_translated *st; + size_t u, st_num; + unsigned hash_id; + + pc = (br_ssl_server_policy_ec_context *)pctx; + st = br_ssl_server_get_client_suites(cc, &st_num); + hash_id = br_ssl_choose_hash(br_ssl_server_get_client_hashes(cc) >> 8); + if (cc->eng.session.version < BR_TLS12) { + hash_id = br_sha1_ID; + } + choices->chain = pc->chain; + choices->chain_len = pc->chain_len; + for (u = 0; u < st_num; u ++) { + unsigned tt; + + tt = st[u][1]; + switch (tt >> 12) { + case BR_SSLKEYX_ECDH_RSA: + if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0 + && pc->cert_issuer_key_type == BR_KEYTYPE_RSA) + { + choices->cipher_suite = st[u][0]; + return 1; + } + break; + case BR_SSLKEYX_ECDH_ECDSA: + if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0 + && pc->cert_issuer_key_type == BR_KEYTYPE_EC) + { + choices->cipher_suite = st[u][0]; + return 1; + } + break; + case BR_SSLKEYX_ECDHE_ECDSA: + if ((pc->allowed_usages & BR_KEYTYPE_SIGN) != 0 + && hash_id != 0) + { + choices->cipher_suite = st[u][0]; + choices->algo_id = hash_id + 0xFF00; + return 1; + } + break; + } + } + return 0; +} + +static uint32_t +se_do_keyx(const br_ssl_server_policy_class **pctx, + unsigned char *data, size_t *len) +{ + br_ssl_server_policy_ec_context *pc; + uint32_t r; + size_t xoff, xlen; + + pc = (br_ssl_server_policy_ec_context *)pctx; + r = pc->iec->mul(data, *len, pc->sk->x, pc->sk->xlen, pc->sk->curve); + xoff = pc->iec->xoff(pc->sk->curve, &xlen); + memmove(data, data + xoff, xlen); + *len = xlen; + return r; +} + +static size_t +se_do_sign(const br_ssl_server_policy_class **pctx, + unsigned algo_id, unsigned char *data, size_t hv_len, size_t len) +{ + br_ssl_server_policy_ec_context *pc; + unsigned char hv[64]; + const br_hash_class *hc; + + algo_id &= 0xFF; + pc = (br_ssl_server_policy_ec_context *)pctx; + hc = br_multihash_getimpl(pc->mhash, algo_id); + if (hc == NULL) { + return 0; + } + memcpy(hv, data, hv_len); + if (len < 139) { + return 0; + } + return pc->iecdsa(pc->iec, hc, hv, pc->sk, data); +} + +static const br_ssl_server_policy_class se_policy_vtable = { + sizeof(br_ssl_server_policy_ec_context), + se_choose, + se_do_keyx, + se_do_sign +}; + +/* see bearssl_ssl.h */ +void +br_ssl_server_set_single_ec(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk, unsigned allowed_usages, + unsigned cert_issuer_key_type, + const br_ec_impl *iec, br_ecdsa_sign iecdsa) +{ + cc->chain_handler.single_ec.vtable = &se_policy_vtable; + cc->chain_handler.single_ec.chain = chain; + cc->chain_handler.single_ec.chain_len = chain_len; + cc->chain_handler.single_ec.sk = sk; + cc->chain_handler.single_ec.allowed_usages = allowed_usages; + cc->chain_handler.single_ec.cert_issuer_key_type = cert_issuer_key_type; + cc->chain_handler.single_ec.mhash = &cc->eng.mhash; + cc->chain_handler.single_ec.iec = iec; + cc->chain_handler.single_ec.iecdsa = iecdsa; + cc->policy_vtable = &cc->chain_handler.single_ec.vtable; +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_scert_single_rsa.c b/BearSSL-OG/libbearssl/src/ssl/ssl_scert_single_rsa.c new file mode 100644 index 0000000..b2c7767 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_scert_single_rsa.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static int +sr_choose(const br_ssl_server_policy_class **pctx, + const br_ssl_server_context *cc, + br_ssl_server_choices *choices) +{ + br_ssl_server_policy_rsa_context *pc; + const br_suite_translated *st; + size_t u, st_num; + unsigned hash_id; + int fh; + + pc = (br_ssl_server_policy_rsa_context *)pctx; + st = br_ssl_server_get_client_suites(cc, &st_num); + if (cc->eng.session.version < BR_TLS12) { + hash_id = 0; + fh = 1; + } else { + hash_id = br_ssl_choose_hash( + br_ssl_server_get_client_hashes(cc)); + fh = (hash_id != 0); + } + choices->chain = pc->chain; + choices->chain_len = pc->chain_len; + for (u = 0; u < st_num; u ++) { + unsigned tt; + + tt = st[u][1]; + switch (tt >> 12) { + case BR_SSLKEYX_RSA: + if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0) { + choices->cipher_suite = st[u][0]; + return 1; + } + break; + case BR_SSLKEYX_ECDHE_RSA: + if ((pc->allowed_usages & BR_KEYTYPE_SIGN) != 0 && fh) { + choices->cipher_suite = st[u][0]; + choices->algo_id = hash_id + 0xFF00; + return 1; + } + break; + } + } + return 0; +} + +static uint32_t +sr_do_keyx(const br_ssl_server_policy_class **pctx, + unsigned char *data, size_t *len) +{ + br_ssl_server_policy_rsa_context *pc; + + pc = (br_ssl_server_policy_rsa_context *)pctx; + return br_rsa_ssl_decrypt(pc->irsacore, pc->sk, data, *len); +} + +/* + * OID for hash functions in RSA signatures. + */ +static const unsigned char HASH_OID_SHA1[] = { + 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A +}; + +static const unsigned char HASH_OID_SHA224[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 +}; + +static const unsigned char HASH_OID_SHA256[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 +}; + +static const unsigned char HASH_OID_SHA384[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 +}; + +static const unsigned char HASH_OID_SHA512[] = { + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 +}; + +static const unsigned char *HASH_OID[] = { + HASH_OID_SHA1, + HASH_OID_SHA224, + HASH_OID_SHA256, + HASH_OID_SHA384, + HASH_OID_SHA512 +}; + +static size_t +sr_do_sign(const br_ssl_server_policy_class **pctx, + unsigned algo_id, unsigned char *data, size_t hv_len, size_t len) +{ + br_ssl_server_policy_rsa_context *pc; + unsigned char hv[64]; + size_t sig_len; + const unsigned char *hash_oid; + + pc = (br_ssl_server_policy_rsa_context *)pctx; + memcpy(hv, data, hv_len); + algo_id &= 0xFF; + if (algo_id == 0) { + hash_oid = NULL; + } else if (algo_id >= 2 && algo_id <= 6) { + hash_oid = HASH_OID[algo_id - 2]; + } else { + return 0; + } + sig_len = (pc->sk->n_bitlen + 7) >> 3; + if (len < sig_len) { + return 0; + } + return pc->irsasign(hash_oid, hv, hv_len, pc->sk, data) ? sig_len : 0; +} + +static const br_ssl_server_policy_class sr_policy_vtable = { + sizeof(br_ssl_server_policy_rsa_context), + sr_choose, + sr_do_keyx, + sr_do_sign +}; + +/* see bearssl_ssl.h */ +void +br_ssl_server_set_single_rsa(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk, unsigned allowed_usages, + br_rsa_private irsacore, br_rsa_pkcs1_sign irsasign) +{ + cc->chain_handler.single_rsa.vtable = &sr_policy_vtable; + cc->chain_handler.single_rsa.chain = chain; + cc->chain_handler.single_rsa.chain_len = chain_len; + cc->chain_handler.single_rsa.sk = sk; + cc->chain_handler.single_rsa.allowed_usages = allowed_usages; + cc->chain_handler.single_rsa.irsacore = irsacore; + cc->chain_handler.single_rsa.irsasign = irsasign; + cc->policy_vtable = &cc->chain_handler.single_rsa.vtable; +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_server.c b/BearSSL-OG/libbearssl/src/ssl/ssl_server.c new file mode 100644 index 0000000..5578b63 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_server.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_server_zero(br_ssl_server_context *cc) +{ + /* + * For really standard C, we should explicitly set to NULL all + * pointers, and 0 all other fields. However, on all our target + * architectures, a direct memset() will work, be faster, and + * use a lot less code. + */ + memset(cc, 0, sizeof *cc); +} + +/* see bearssl_ssl.h */ +int +br_ssl_server_reset(br_ssl_server_context *cc) +{ + br_ssl_engine_set_buffer(&cc->eng, NULL, 0, 0); + if (!br_ssl_engine_init_rand(&cc->eng)) { + return 0; + } + cc->eng.reneg = 0; + br_ssl_engine_hs_reset(&cc->eng, + br_ssl_hs_server_init_main, br_ssl_hs_server_run); + return br_ssl_engine_last_error(&cc->eng) == BR_ERR_OK; +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_server_full_ec.c b/BearSSL-OG/libbearssl/src/ssl/ssl_server_full_ec.c new file mode 100644 index 0000000..bccc093 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_server_full_ec.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_server_init_full_ec(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + unsigned cert_issuer_key_type, const br_ec_private_key *sk) +{ + /* + * The "full" profile supports all implemented cipher suites. + * + * Rationale for suite order, from most important to least + * important rule: + * + * -- Don't use 3DES if AES is available. + * -- Try to have Forward Secrecy (ECDHE suite) if possible. + * -- ChaCha20+Poly1305 is better than AES/GCM (faster, smaller). + * -- GCM is better than CCM and CBC. CCM is better than CBC. + * -- CCM is better than CCM_8. + * -- AES-128 is preferred over AES-256 (AES-128 is already + * strong enough, and AES-256 is 40% more expensive). + * + * Note that for ECDH suites, the list will be automatically + * filtered based on the issuing CA key type. + */ + static const uint16_t suites[] = { + BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + }; + + /* + * All hash functions are activated. + * Note: the X.509 validation engine will nonetheless refuse to + * validate signatures that use MD5 as hash function. + */ + static const br_hash_class *hashes[] = { + &br_md5_vtable, + &br_sha1_vtable, + &br_sha224_vtable, + &br_sha256_vtable, + &br_sha384_vtable, + &br_sha512_vtable + }; + + int id; + + /* + * Reset server context and set supported versions from TLS-1.0 + * to TLS-1.2 (inclusive). + */ + br_ssl_server_zero(cc); + br_ssl_engine_set_versions(&cc->eng, BR_TLS10, BR_TLS12); + + /* + * Set suites and elliptic curve implementation (for ECDHE). + */ + br_ssl_engine_set_suites(&cc->eng, suites, + (sizeof suites) / (sizeof suites[0])); + br_ssl_engine_set_default_ec(&cc->eng); + + /* + * Set the "server policy": handler for the certificate chain + * and private key operations. + */ + br_ssl_server_set_single_ec(cc, chain, chain_len, sk, + BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, + cert_issuer_key_type, + br_ssl_engine_get_ec(&cc->eng), +#if BR_LOMUL + br_ecdsa_i15_sign_asn1 +#else + br_ecdsa_i31_sign_asn1 +#endif + ); + + /* + * Set supported hash functions. + */ + for (id = br_md5_ID; id <= br_sha512_ID; id ++) { + const br_hash_class *hc; + + hc = hashes[id - 1]; + br_ssl_engine_set_hash(&cc->eng, id, hc); + } + + /* + * Set the PRF implementations. + */ + br_ssl_engine_set_prf10(&cc->eng, &br_tls10_prf); + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf); + + /* + * Symmetric encryption. + */ + br_ssl_engine_set_default_aes_cbc(&cc->eng); + br_ssl_engine_set_default_aes_ccm(&cc->eng); + br_ssl_engine_set_default_aes_gcm(&cc->eng); + br_ssl_engine_set_default_des_cbc(&cc->eng); + br_ssl_engine_set_default_chapol(&cc->eng); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_server_full_rsa.c b/BearSSL-OG/libbearssl/src/ssl/ssl_server_full_rsa.c new file mode 100644 index 0000000..d67c076 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_server_full_rsa.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_server_init_full_rsa(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk) +{ + /* + * The "full" profile supports all implemented cipher suites. + * + * Rationale for suite order, from most important to least + * important rule: + * + * -- Don't use 3DES if AES is available. + * -- Try to have Forward Secrecy (ECDHE suite) if possible. + * -- ChaCha20+Poly1305 is better than AES/GCM (faster, smaller). + * -- GCM is better than CBC. + * -- AES-128 is preferred over AES-256 (AES-128 is already + * strong enough, and AES-256 is 40% more expensive). + */ + static const uint16_t suites[] = { + BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + BR_TLS_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_RSA_WITH_AES_128_CCM, + BR_TLS_RSA_WITH_AES_256_CCM, + BR_TLS_RSA_WITH_AES_128_CCM_8, + BR_TLS_RSA_WITH_AES_256_CCM_8, + BR_TLS_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_RSA_WITH_AES_256_CBC_SHA256, + BR_TLS_RSA_WITH_AES_128_CBC_SHA, + BR_TLS_RSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA + }; + + /* + * All hash functions are activated. + * Note: the X.509 validation engine will nonetheless refuse to + * validate signatures that use MD5 as hash function. + */ + static const br_hash_class *hashes[] = { + &br_md5_vtable, + &br_sha1_vtable, + &br_sha224_vtable, + &br_sha256_vtable, + &br_sha384_vtable, + &br_sha512_vtable + }; + + int id; + + /* + * Reset server context and set supported versions from TLS-1.0 + * to TLS-1.2 (inclusive). + */ + br_ssl_server_zero(cc); + br_ssl_engine_set_versions(&cc->eng, BR_TLS10, BR_TLS12); + + /* + * Set suites and elliptic curve implementation (for ECDHE). + */ + br_ssl_engine_set_suites(&cc->eng, suites, + (sizeof suites) / (sizeof suites[0])); + br_ssl_engine_set_default_ec(&cc->eng); + + /* + * Set the "server policy": handler for the certificate chain + * and private key operations. + */ + br_ssl_server_set_single_rsa(cc, chain, chain_len, sk, + BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, + br_rsa_private_get_default(), + br_rsa_pkcs1_sign_get_default()); + + /* + * Set supported hash functions. + */ + for (id = br_md5_ID; id <= br_sha512_ID; id ++) { + const br_hash_class *hc; + + hc = hashes[id - 1]; + br_ssl_engine_set_hash(&cc->eng, id, hc); + } + + /* + * Set the PRF implementations. + */ + br_ssl_engine_set_prf10(&cc->eng, &br_tls10_prf); + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf); + + /* + * Symmetric encryption. + */ + br_ssl_engine_set_default_aes_cbc(&cc->eng); + br_ssl_engine_set_default_aes_ccm(&cc->eng); + br_ssl_engine_set_default_aes_gcm(&cc->eng); + br_ssl_engine_set_default_des_cbc(&cc->eng); + br_ssl_engine_set_default_chapol(&cc->eng); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_server_mine2c.c b/BearSSL-OG/libbearssl/src/ssl/ssl_server_mine2c.c new file mode 100644 index 0000000..bf61b56 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_server_mine2c.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_server_init_mine2c(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk) +{ + static const uint16_t suites[] = { + BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + }; + + /* + * Reset server context and set supported versions to TLS-1.2 (only). + */ + br_ssl_server_zero(cc); + br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); + + /* + * Set suites and elliptic curve implementation (for ECDHE). + */ + br_ssl_engine_set_suites(&cc->eng, suites, + (sizeof suites) / (sizeof suites[0])); + br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); + + /* + * Set the "server policy": handler for the certificate chain + * and private key operations. + */ + br_ssl_server_set_single_rsa(cc, chain, chain_len, sk, + BR_KEYTYPE_SIGN, 0, br_rsa_i31_pkcs1_sign); + + /* + * Set supported hash functions. + */ + br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); + + /* + * Set the PRF implementations. + */ + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + + /* + * Symmetric encryption. + */ + br_ssl_engine_set_default_chapol(&cc->eng); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_server_mine2g.c b/BearSSL-OG/libbearssl/src/ssl/ssl_server_mine2g.c new file mode 100644 index 0000000..80fa5b1 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_server_mine2g.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_server_init_mine2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk) +{ + static const uint16_t suites[] = { + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + }; + + /* + * Reset server context and set supported versions to TLS-1.2 (only). + */ + br_ssl_server_zero(cc); + br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); + + /* + * Set suites and elliptic curve implementation (for ECDHE). + */ + br_ssl_engine_set_suites(&cc->eng, suites, + (sizeof suites) / (sizeof suites[0])); + br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); + + /* + * Set the "server policy": handler for the certificate chain + * and private key operations. + */ + br_ssl_server_set_single_rsa(cc, chain, chain_len, sk, + BR_KEYTYPE_SIGN, 0, br_rsa_i31_pkcs1_sign); + + /* + * Set supported hash functions. + */ + br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); + + /* + * Set the PRF implementations. + */ + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + + /* + * Symmetric encryption. + */ + br_ssl_engine_set_default_aes_gcm(&cc->eng); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_server_minf2c.c b/BearSSL-OG/libbearssl/src/ssl/ssl_server_minf2c.c new file mode 100644 index 0000000..3f44236 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_server_minf2c.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_server_init_minf2c(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk) +{ + static const uint16_t suites[] = { + BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + }; + + /* + * Reset server context and set supported versions to TLS-1.2 (only). + */ + br_ssl_server_zero(cc); + br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); + + /* + * Set suites and elliptic curve implementation (for ECDHE). + */ + br_ssl_engine_set_suites(&cc->eng, suites, + (sizeof suites) / (sizeof suites[0])); + br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); + + /* + * Set the "server policy": handler for the certificate chain + * and private key operations. + */ + br_ssl_server_set_single_ec(cc, chain, chain_len, sk, + BR_KEYTYPE_SIGN, 0, &br_ec_all_m15, br_ecdsa_i31_sign_asn1); + + /* + * Set supported hash functions. + */ + br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); + + /* + * Set the PRF implementations. + */ + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + + /* + * Symmetric encryption. + */ + br_ssl_engine_set_default_chapol(&cc->eng); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_server_minf2g.c b/BearSSL-OG/libbearssl/src/ssl/ssl_server_minf2g.c new file mode 100644 index 0000000..8613de1 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_server_minf2g.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_server_init_minf2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk) +{ + static const uint16_t suites[] = { + BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + }; + + /* + * Reset server context and set supported versions to TLS-1.2 (only). + */ + br_ssl_server_zero(cc); + br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); + + /* + * Set suites and elliptic curve implementation (for ECDHE). + */ + br_ssl_engine_set_suites(&cc->eng, suites, + (sizeof suites) / (sizeof suites[0])); + br_ssl_engine_set_ec(&cc->eng, &br_ec_all_m15); + + /* + * Set the "server policy": handler for the certificate chain + * and private key operations. + */ + br_ssl_server_set_single_ec(cc, chain, chain_len, sk, + BR_KEYTYPE_SIGN, 0, &br_ec_all_m15, br_ecdsa_i31_sign_asn1); + + /* + * Set supported hash functions. + */ + br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); + + /* + * Set the PRF implementations. + */ + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + + /* + * Symmetric encryption. + */ + br_ssl_engine_set_default_aes_gcm(&cc->eng); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_server_minr2g.c b/BearSSL-OG/libbearssl/src/ssl/ssl_server_minr2g.c new file mode 100644 index 0000000..83c238b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_server_minr2g.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_server_init_minr2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk) +{ + static const uint16_t suites[] = { + BR_TLS_RSA_WITH_AES_128_GCM_SHA256 + }; + + /* + * Reset server context and set supported versions to TLS-1.2 (only). + */ + br_ssl_server_zero(cc); + br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); + + /* + * Set suites. + */ + br_ssl_engine_set_suites(&cc->eng, suites, + (sizeof suites) / (sizeof suites[0])); + + /* + * Set the "server policy": handler for the certificate chain + * and private key operations. + */ + br_ssl_server_set_single_rsa(cc, chain, chain_len, sk, + BR_KEYTYPE_KEYX, br_rsa_i31_private, 0); + + /* + * Set supported hash functions. + */ + br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); + + /* + * Set the PRF implementations. + */ + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + + /* + * Symmetric encryption. + */ + br_ssl_engine_set_default_aes_gcm(&cc->eng); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_server_minu2g.c b/BearSSL-OG/libbearssl/src/ssl/ssl_server_minu2g.c new file mode 100644 index 0000000..6721384 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_server_minu2g.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_server_init_minu2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk) +{ + static const uint16_t suites[] = { + BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + }; + + /* + * Reset server context and set supported versions to TLS-1.2 (only). + */ + br_ssl_server_zero(cc); + br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); + + /* + * Set suites. + */ + br_ssl_engine_set_suites(&cc->eng, suites, + (sizeof suites) / (sizeof suites[0])); + + /* + * Set the "server policy": handler for the certificate chain + * and private key operations. + */ + br_ssl_server_set_single_ec(cc, chain, chain_len, sk, + BR_KEYTYPE_KEYX, BR_KEYTYPE_RSA, &br_ec_all_m15, 0); + + /* + * Set supported hash functions. + */ + br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); + + /* + * Set the PRF implementations. + */ + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + + /* + * Symmetric encryption. + */ + br_ssl_engine_set_default_aes_gcm(&cc->eng); +} diff --git a/BearSSL-OG/libbearssl/src/ssl/ssl_server_minv2g.c b/BearSSL-OG/libbearssl/src/ssl/ssl_server_minv2g.c new file mode 100644 index 0000000..194e654 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/ssl/ssl_server_minv2g.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_ssl.h */ +void +br_ssl_server_init_minv2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk) +{ + static const uint16_t suites[] = { + BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + }; + + /* + * Reset server context and set supported versions to TLS-1.2 (only). + */ + br_ssl_server_zero(cc); + br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); + + /* + * Set suites. + */ + br_ssl_engine_set_suites(&cc->eng, suites, + (sizeof suites) / (sizeof suites[0])); + + /* + * Set the "server policy": handler for the certificate chain + * and private key operations. + */ + br_ssl_server_set_single_ec(cc, chain, chain_len, sk, + BR_KEYTYPE_KEYX, BR_KEYTYPE_EC, &br_ec_all_m15, 0); + + /* + * Set supported hash functions. + */ + br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); + + /* + * Set the PRF implementations. + */ + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + + /* + * Symmetric encryption. + */ + br_ssl_engine_set_default_aes_gcm(&cc->eng); +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_big_cbcdec.c b/BearSSL-OG/libbearssl/src/symcipher/aes_big_cbcdec.c new file mode 100644 index 0000000..d969a3b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_big_cbcdec.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_big_cbcdec_init(br_aes_big_cbcdec_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_big_cbcdec_vtable; + ctx->num_rounds = br_aes_big_keysched_inv(ctx->skey, key, len); +} + +/* see bearssl_block.h */ +void +br_aes_big_cbcdec_run(const br_aes_big_cbcdec_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf, *ivbuf; + + ivbuf = iv; + buf = data; + while (len > 0) { + unsigned char tmp[16]; + int i; + + memcpy(tmp, buf, 16); + br_aes_big_decrypt(ctx->num_rounds, ctx->skey, buf); + for (i = 0; i < 16; i ++) { + buf[i] ^= ivbuf[i]; + } + memcpy(ivbuf, tmp, 16); + buf += 16; + len -= 16; + } +} + +/* see bearssl_block.h */ +const br_block_cbcdec_class br_aes_big_cbcdec_vtable = { + sizeof(br_aes_big_cbcdec_keys), + 16, + 4, + (void (*)(const br_block_cbcdec_class **, const void *, size_t)) + &br_aes_big_cbcdec_init, + (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) + &br_aes_big_cbcdec_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_big_cbcenc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_big_cbcenc.c new file mode 100644 index 0000000..265e53b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_big_cbcenc.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_big_cbcenc_init(br_aes_big_cbcenc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_big_cbcenc_vtable; + ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); +} + +/* see bearssl_block.h */ +void +br_aes_big_cbcenc_run(const br_aes_big_cbcenc_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf, *ivbuf; + + ivbuf = iv; + buf = data; + while (len > 0) { + int i; + + for (i = 0; i < 16; i ++) { + buf[i] ^= ivbuf[i]; + } + br_aes_big_encrypt(ctx->num_rounds, ctx->skey, buf); + memcpy(ivbuf, buf, 16); + buf += 16; + len -= 16; + } +} + +/* see bearssl_block.h */ +const br_block_cbcenc_class br_aes_big_cbcenc_vtable = { + sizeof(br_aes_big_cbcenc_keys), + 16, + 4, + (void (*)(const br_block_cbcenc_class **, const void *, size_t)) + &br_aes_big_cbcenc_init, + (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) + &br_aes_big_cbcenc_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_big_ctr.c b/BearSSL-OG/libbearssl/src/symcipher/aes_big_ctr.c new file mode 100644 index 0000000..18fbb84 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_big_ctr.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_big_ctr_init(br_aes_big_ctr_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_big_ctr_vtable; + ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); +} + +static void +xorbuf(void *dst, const void *src, size_t len) +{ + unsigned char *d; + const unsigned char *s; + + d = dst; + s = src; + while (len -- > 0) { + *d ++ ^= *s ++; + } +} + +/* see bearssl_block.h */ +uint32_t +br_aes_big_ctr_run(const br_aes_big_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len) +{ + unsigned char *buf; + + buf = data; + while (len > 0) { + unsigned char tmp[16]; + + memcpy(tmp, iv, 12); + br_enc32be(tmp + 12, cc ++); + br_aes_big_encrypt(ctx->num_rounds, ctx->skey, tmp); + if (len <= 16) { + xorbuf(buf, tmp, len); + break; + } + xorbuf(buf, tmp, 16); + buf += 16; + len -= 16; + } + return cc; +} + +/* see bearssl_block.h */ +const br_block_ctr_class br_aes_big_ctr_vtable = { + sizeof(br_aes_big_ctr_keys), + 16, + 4, + (void (*)(const br_block_ctr_class **, const void *, size_t)) + &br_aes_big_ctr_init, + (uint32_t (*)(const br_block_ctr_class *const *, + const void *, uint32_t, void *, size_t)) + &br_aes_big_ctr_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_big_ctrcbc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_big_ctrcbc.c new file mode 100644 index 0000000..d45ca76 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_big_ctrcbc.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_big_ctrcbc_init(br_aes_big_ctrcbc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_big_ctrcbc_vtable; + ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); +} + +static void +xorbuf(void *dst, const void *src, size_t len) +{ + unsigned char *d; + const unsigned char *s; + + d = dst; + s = src; + while (len -- > 0) { + *d ++ ^= *s ++; + } +} + +/* see bearssl_block.h */ +void +br_aes_big_ctrcbc_ctr(const br_aes_big_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len) +{ + unsigned char *buf, *bctr; + uint32_t cc0, cc1, cc2, cc3; + + buf = data; + bctr = ctr; + cc3 = br_dec32be(bctr + 0); + cc2 = br_dec32be(bctr + 4); + cc1 = br_dec32be(bctr + 8); + cc0 = br_dec32be(bctr + 12); + while (len > 0) { + unsigned char tmp[16]; + uint32_t carry; + + br_enc32be(tmp + 0, cc3); + br_enc32be(tmp + 4, cc2); + br_enc32be(tmp + 8, cc1); + br_enc32be(tmp + 12, cc0); + br_aes_big_encrypt(ctx->num_rounds, ctx->skey, tmp); + xorbuf(buf, tmp, 16); + buf += 16; + len -= 16; + cc0 ++; + carry = (~(cc0 | -cc0)) >> 31; + cc1 += carry; + carry &= (~(cc1 | -cc1)) >> 31; + cc2 += carry; + carry &= (~(cc2 | -cc2)) >> 31; + cc3 += carry; + } + br_enc32be(bctr + 0, cc3); + br_enc32be(bctr + 4, cc2); + br_enc32be(bctr + 8, cc1); + br_enc32be(bctr + 12, cc0); +} + +/* see bearssl_block.h */ +void +br_aes_big_ctrcbc_mac(const br_aes_big_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len) +{ + const unsigned char *buf; + + buf = data; + while (len > 0) { + xorbuf(cbcmac, buf, 16); + br_aes_big_encrypt(ctx->num_rounds, ctx->skey, cbcmac); + buf += 16; + len -= 16; + } +} + +/* see bearssl_block.h */ +void +br_aes_big_ctrcbc_encrypt(const br_aes_big_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len) +{ + br_aes_big_ctrcbc_ctr(ctx, ctr, data, len); + br_aes_big_ctrcbc_mac(ctx, cbcmac, data, len); +} + +/* see bearssl_block.h */ +void +br_aes_big_ctrcbc_decrypt(const br_aes_big_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len) +{ + br_aes_big_ctrcbc_mac(ctx, cbcmac, data, len); + br_aes_big_ctrcbc_ctr(ctx, ctr, data, len); +} + +/* see bearssl_block.h */ +const br_block_ctrcbc_class br_aes_big_ctrcbc_vtable = { + sizeof(br_aes_big_ctrcbc_keys), + 16, + 4, + (void (*)(const br_block_ctrcbc_class **, const void *, size_t)) + &br_aes_big_ctrcbc_init, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, void *, size_t)) + &br_aes_big_ctrcbc_encrypt, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, void *, size_t)) + &br_aes_big_ctrcbc_decrypt, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, size_t)) + &br_aes_big_ctrcbc_ctr, + (void (*)(const br_block_ctrcbc_class *const *, + void *, const void *, size_t)) + &br_aes_big_ctrcbc_mac +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_big_dec.c b/BearSSL-OG/libbearssl/src/symcipher/aes_big_dec.c new file mode 100644 index 0000000..27a3a36 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_big_dec.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Inverse S-box (used in key schedule for decryption). + */ +static const unsigned char iS[] = { + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, + 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, + 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, + 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, + 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, + 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, + 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, + 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, + 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, + 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, + 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, + 0x55, 0x21, 0x0C, 0x7D +}; + +static const uint32_t iSsm0[] = { + 0x51F4A750, 0x7E416553, 0x1A17A4C3, 0x3A275E96, 0x3BAB6BCB, 0x1F9D45F1, + 0xACFA58AB, 0x4BE30393, 0x2030FA55, 0xAD766DF6, 0x88CC7691, 0xF5024C25, + 0x4FE5D7FC, 0xC52ACBD7, 0x26354480, 0xB562A38F, 0xDEB15A49, 0x25BA1B67, + 0x45EA0E98, 0x5DFEC0E1, 0xC32F7502, 0x814CF012, 0x8D4697A3, 0x6BD3F9C6, + 0x038F5FE7, 0x15929C95, 0xBF6D7AEB, 0x955259DA, 0xD4BE832D, 0x587421D3, + 0x49E06929, 0x8EC9C844, 0x75C2896A, 0xF48E7978, 0x99583E6B, 0x27B971DD, + 0xBEE14FB6, 0xF088AD17, 0xC920AC66, 0x7DCE3AB4, 0x63DF4A18, 0xE51A3182, + 0x97513360, 0x62537F45, 0xB16477E0, 0xBB6BAE84, 0xFE81A01C, 0xF9082B94, + 0x70486858, 0x8F45FD19, 0x94DE6C87, 0x527BF8B7, 0xAB73D323, 0x724B02E2, + 0xE31F8F57, 0x6655AB2A, 0xB2EB2807, 0x2FB5C203, 0x86C57B9A, 0xD33708A5, + 0x302887F2, 0x23BFA5B2, 0x02036ABA, 0xED16825C, 0x8ACF1C2B, 0xA779B492, + 0xF307F2F0, 0x4E69E2A1, 0x65DAF4CD, 0x0605BED5, 0xD134621F, 0xC4A6FE8A, + 0x342E539D, 0xA2F355A0, 0x058AE132, 0xA4F6EB75, 0x0B83EC39, 0x4060EFAA, + 0x5E719F06, 0xBD6E1051, 0x3E218AF9, 0x96DD063D, 0xDD3E05AE, 0x4DE6BD46, + 0x91548DB5, 0x71C45D05, 0x0406D46F, 0x605015FF, 0x1998FB24, 0xD6BDE997, + 0x894043CC, 0x67D99E77, 0xB0E842BD, 0x07898B88, 0xE7195B38, 0x79C8EEDB, + 0xA17C0A47, 0x7C420FE9, 0xF8841EC9, 0x00000000, 0x09808683, 0x322BED48, + 0x1E1170AC, 0x6C5A724E, 0xFD0EFFFB, 0x0F853856, 0x3DAED51E, 0x362D3927, + 0x0A0FD964, 0x685CA621, 0x9B5B54D1, 0x24362E3A, 0x0C0A67B1, 0x9357E70F, + 0xB4EE96D2, 0x1B9B919E, 0x80C0C54F, 0x61DC20A2, 0x5A774B69, 0x1C121A16, + 0xE293BA0A, 0xC0A02AE5, 0x3C22E043, 0x121B171D, 0x0E090D0B, 0xF28BC7AD, + 0x2DB6A8B9, 0x141EA9C8, 0x57F11985, 0xAF75074C, 0xEE99DDBB, 0xA37F60FD, + 0xF701269F, 0x5C72F5BC, 0x44663BC5, 0x5BFB7E34, 0x8B432976, 0xCB23C6DC, + 0xB6EDFC68, 0xB8E4F163, 0xD731DCCA, 0x42638510, 0x13972240, 0x84C61120, + 0x854A247D, 0xD2BB3DF8, 0xAEF93211, 0xC729A16D, 0x1D9E2F4B, 0xDCB230F3, + 0x0D8652EC, 0x77C1E3D0, 0x2BB3166C, 0xA970B999, 0x119448FA, 0x47E96422, + 0xA8FC8CC4, 0xA0F03F1A, 0x567D2CD8, 0x223390EF, 0x87494EC7, 0xD938D1C1, + 0x8CCAA2FE, 0x98D40B36, 0xA6F581CF, 0xA57ADE28, 0xDAB78E26, 0x3FADBFA4, + 0x2C3A9DE4, 0x5078920D, 0x6A5FCC9B, 0x547E4662, 0xF68D13C2, 0x90D8B8E8, + 0x2E39F75E, 0x82C3AFF5, 0x9F5D80BE, 0x69D0937C, 0x6FD52DA9, 0xCF2512B3, + 0xC8AC993B, 0x10187DA7, 0xE89C636E, 0xDB3BBB7B, 0xCD267809, 0x6E5918F4, + 0xEC9AB701, 0x834F9AA8, 0xE6956E65, 0xAAFFE67E, 0x21BCCF08, 0xEF15E8E6, + 0xBAE79BD9, 0x4A6F36CE, 0xEA9F09D4, 0x29B07CD6, 0x31A4B2AF, 0x2A3F2331, + 0xC6A59430, 0x35A266C0, 0x744EBC37, 0xFC82CAA6, 0xE090D0B0, 0x33A7D815, + 0xF104984A, 0x41ECDAF7, 0x7FCD500E, 0x1791F62F, 0x764DD68D, 0x43EFB04D, + 0xCCAA4D54, 0xE49604DF, 0x9ED1B5E3, 0x4C6A881B, 0xC12C1FB8, 0x4665517F, + 0x9D5EEA04, 0x018C355D, 0xFA877473, 0xFB0B412E, 0xB3671D5A, 0x92DBD252, + 0xE9105633, 0x6DD64713, 0x9AD7618C, 0x37A10C7A, 0x59F8148E, 0xEB133C89, + 0xCEA927EE, 0xB761C935, 0xE11CE5ED, 0x7A47B13C, 0x9CD2DF59, 0x55F2733F, + 0x1814CE79, 0x73C737BF, 0x53F7CDEA, 0x5FFDAA5B, 0xDF3D6F14, 0x7844DB86, + 0xCAAFF381, 0xB968C43E, 0x3824342C, 0xC2A3405F, 0x161DC372, 0xBCE2250C, + 0x283C498B, 0xFF0D9541, 0x39A80171, 0x080CB3DE, 0xD8B4E49C, 0x6456C190, + 0x7BCB8461, 0xD532B670, 0x486C5C74, 0xD0B85742 +}; + +static unsigned +mul2(unsigned x) +{ + x <<= 1; + return x ^ ((unsigned)(-(int)(x >> 8)) & 0x11B); +} + +static unsigned +mul9(unsigned x) +{ + return x ^ mul2(mul2(mul2(x))); +} + +static unsigned +mulb(unsigned x) +{ + unsigned x2; + + x2 = mul2(x); + return x ^ x2 ^ mul2(mul2(x2)); +} + +static unsigned +muld(unsigned x) +{ + unsigned x4; + + x4 = mul2(mul2(x)); + return x ^ x4 ^ mul2(x4); +} + +static unsigned +mule(unsigned x) +{ + unsigned x2, x4; + + x2 = mul2(x); + x4 = mul2(x2); + return x2 ^ x4 ^ mul2(x4); +} + +/* see inner.h */ +unsigned +br_aes_big_keysched_inv(uint32_t *skey, const void *key, size_t key_len) +{ + unsigned num_rounds; + int i, m; + + /* + * Sub-keys for decryption are distinct from encryption sub-keys + * in that InvMixColumns() is already applied for the inner + * rounds. + */ + num_rounds = br_aes_keysched(skey, key, key_len); + m = (int)(num_rounds << 2); + for (i = 4; i < m; i ++) { + uint32_t p; + unsigned p0, p1, p2, p3; + uint32_t q0, q1, q2, q3; + + p = skey[i]; + p0 = p >> 24; + p1 = (p >> 16) & 0xFF; + p2 = (p >> 8) & 0xFF; + p3 = p & 0xFF; + q0 = mule(p0) ^ mulb(p1) ^ muld(p2) ^ mul9(p3); + q1 = mul9(p0) ^ mule(p1) ^ mulb(p2) ^ muld(p3); + q2 = muld(p0) ^ mul9(p1) ^ mule(p2) ^ mulb(p3); + q3 = mulb(p0) ^ muld(p1) ^ mul9(p2) ^ mule(p3); + skey[i] = (q0 << 24) | (q1 << 16) | (q2 << 8) | q3; + } + return num_rounds; +} + +static __inline uint32_t +rotr(uint32_t x, int n) +{ + return (x << (32 - n)) | (x >> n); +} + +#define iSboxExt0(x) (iSsm0[x]) +#define iSboxExt1(x) (rotr(iSsm0[x], 8)) +#define iSboxExt2(x) (rotr(iSsm0[x], 16)) +#define iSboxExt3(x) (rotr(iSsm0[x], 24)) + +/* see bearssl.h */ +void +br_aes_big_decrypt(unsigned num_rounds, const uint32_t *skey, void *data) +{ + unsigned char *buf; + uint32_t s0, s1, s2, s3; + uint32_t t0, t1, t2, t3; + unsigned u; + + buf = data; + s0 = br_dec32be(buf); + s1 = br_dec32be(buf + 4); + s2 = br_dec32be(buf + 8); + s3 = br_dec32be(buf + 12); + s0 ^= skey[(num_rounds << 2) + 0]; + s1 ^= skey[(num_rounds << 2) + 1]; + s2 ^= skey[(num_rounds << 2) + 2]; + s3 ^= skey[(num_rounds << 2) + 3]; + for (u = num_rounds - 1; u > 0; u --) { + uint32_t v0 = iSboxExt0(s0 >> 24) + ^ iSboxExt1((s3 >> 16) & 0xFF) + ^ iSboxExt2((s2 >> 8) & 0xFF) + ^ iSboxExt3(s1 & 0xFF); + uint32_t v1 = iSboxExt0(s1 >> 24) + ^ iSboxExt1((s0 >> 16) & 0xFF) + ^ iSboxExt2((s3 >> 8) & 0xFF) + ^ iSboxExt3(s2 & 0xFF); + uint32_t v2 = iSboxExt0(s2 >> 24) + ^ iSboxExt1((s1 >> 16) & 0xFF) + ^ iSboxExt2((s0 >> 8) & 0xFF) + ^ iSboxExt3(s3 & 0xFF); + uint32_t v3 = iSboxExt0(s3 >> 24) + ^ iSboxExt1((s2 >> 16) & 0xFF) + ^ iSboxExt2((s1 >> 8) & 0xFF) + ^ iSboxExt3(s0 & 0xFF); + s0 = v0; + s1 = v1; + s2 = v2; + s3 = v3; + s0 ^= skey[u << 2]; + s1 ^= skey[(u << 2) + 1]; + s2 ^= skey[(u << 2) + 2]; + s3 ^= skey[(u << 2) + 3]; + } + t0 = ((uint32_t)iS[s0 >> 24] << 24) + | ((uint32_t)iS[(s3 >> 16) & 0xFF] << 16) + | ((uint32_t)iS[(s2 >> 8) & 0xFF] << 8) + | (uint32_t)iS[s1 & 0xFF]; + t1 = ((uint32_t)iS[s1 >> 24] << 24) + | ((uint32_t)iS[(s0 >> 16) & 0xFF] << 16) + | ((uint32_t)iS[(s3 >> 8) & 0xFF] << 8) + | (uint32_t)iS[s2 & 0xFF]; + t2 = ((uint32_t)iS[s2 >> 24] << 24) + | ((uint32_t)iS[(s1 >> 16) & 0xFF] << 16) + | ((uint32_t)iS[(s0 >> 8) & 0xFF] << 8) + | (uint32_t)iS[s3 & 0xFF]; + t3 = ((uint32_t)iS[s3 >> 24] << 24) + | ((uint32_t)iS[(s2 >> 16) & 0xFF] << 16) + | ((uint32_t)iS[(s1 >> 8) & 0xFF] << 8) + | (uint32_t)iS[s0 & 0xFF]; + s0 = t0 ^ skey[0]; + s1 = t1 ^ skey[1]; + s2 = t2 ^ skey[2]; + s3 = t3 ^ skey[3]; + br_enc32be(buf, s0); + br_enc32be(buf + 4, s1); + br_enc32be(buf + 8, s2); + br_enc32be(buf + 12, s3); +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_big_enc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_big_enc.c new file mode 100644 index 0000000..f506fa8 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_big_enc.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define S br_aes_S + +static const uint32_t Ssm0[] = { + 0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, + 0xDE6F6FB1, 0x91C5C554, 0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, + 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A, 0x8FCACA45, 0x1F82829D, + 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B, + 0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, + 0xE4727296, 0x9BC0C05B, 0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, + 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F, 0x6834345C, 0x51A5A5F4, + 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F, + 0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, + 0x0A05050F, 0x2F9A9AB5, 0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, + 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F, 0x1209091B, 0x1D83839E, + 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB, + 0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, + 0x5E2F2F71, 0x13848497, 0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, + 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED, 0xD46A6ABE, 0x8DCBCB46, + 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A, + 0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, + 0x66333355, 0x11858594, 0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, + 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3, 0xA25151F3, 0x5DA3A3FE, + 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504, + 0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, + 0xFDF3F30E, 0xBFD2D26D, 0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, + 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739, 0x93C4C457, 0x55A7A7F2, + 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395, + 0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, + 0x3B9090AB, 0x0B888883, 0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, + 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76, 0xDBE0E03B, 0x64323256, + 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4, + 0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, + 0xD3E4E437, 0xF279798B, 0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, + 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0, 0xD86C6CB4, 0xAC5656FA, + 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818, + 0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, + 0x73B4B4C7, 0x97C6C651, 0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, + 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85, 0xE0707090, 0x7C3E3E42, + 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12, + 0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, + 0x3A1D1D27, 0x279E9EB9, 0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, + 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7, 0x2D9B9BB6, 0x3C1E1E22, + 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A, + 0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, + 0x844242C6, 0xD06868B8, 0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, + 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A +}; + +static __inline uint32_t +rotr(uint32_t x, int n) +{ + return (x << (32 - n)) | (x >> n); +} + +#define SboxExt0(x) (Ssm0[x]) +#define SboxExt1(x) (rotr(Ssm0[x], 8)) +#define SboxExt2(x) (rotr(Ssm0[x], 16)) +#define SboxExt3(x) (rotr(Ssm0[x], 24)) + + +/* see bearssl.h */ +void +br_aes_big_encrypt(unsigned num_rounds, const uint32_t *skey, void *data) +{ + unsigned char *buf; + uint32_t s0, s1, s2, s3; + uint32_t t0, t1, t2, t3; + unsigned u; + + buf = data; + s0 = br_dec32be(buf); + s1 = br_dec32be(buf + 4); + s2 = br_dec32be(buf + 8); + s3 = br_dec32be(buf + 12); + s0 ^= skey[0]; + s1 ^= skey[1]; + s2 ^= skey[2]; + s3 ^= skey[3]; + for (u = 1; u < num_rounds; u ++) { + uint32_t v0, v1, v2, v3; + + v0 = SboxExt0(s0 >> 24) + ^ SboxExt1((s1 >> 16) & 0xFF) + ^ SboxExt2((s2 >> 8) & 0xFF) + ^ SboxExt3(s3 & 0xFF); + v1 = SboxExt0(s1 >> 24) + ^ SboxExt1((s2 >> 16) & 0xFF) + ^ SboxExt2((s3 >> 8) & 0xFF) + ^ SboxExt3(s0 & 0xFF); + v2 = SboxExt0(s2 >> 24) + ^ SboxExt1((s3 >> 16) & 0xFF) + ^ SboxExt2((s0 >> 8) & 0xFF) + ^ SboxExt3(s1 & 0xFF); + v3 = SboxExt0(s3 >> 24) + ^ SboxExt1((s0 >> 16) & 0xFF) + ^ SboxExt2((s1 >> 8) & 0xFF) + ^ SboxExt3(s2 & 0xFF); + s0 = v0; + s1 = v1; + s2 = v2; + s3 = v3; + s0 ^= skey[u << 2]; + s1 ^= skey[(u << 2) + 1]; + s2 ^= skey[(u << 2) + 2]; + s3 ^= skey[(u << 2) + 3]; + } + t0 = ((uint32_t)S[s0 >> 24] << 24) + | ((uint32_t)S[(s1 >> 16) & 0xFF] << 16) + | ((uint32_t)S[(s2 >> 8) & 0xFF] << 8) + | (uint32_t)S[s3 & 0xFF]; + t1 = ((uint32_t)S[s1 >> 24] << 24) + | ((uint32_t)S[(s2 >> 16) & 0xFF] << 16) + | ((uint32_t)S[(s3 >> 8) & 0xFF] << 8) + | (uint32_t)S[s0 & 0xFF]; + t2 = ((uint32_t)S[s2 >> 24] << 24) + | ((uint32_t)S[(s3 >> 16) & 0xFF] << 16) + | ((uint32_t)S[(s0 >> 8) & 0xFF] << 8) + | (uint32_t)S[s1 & 0xFF]; + t3 = ((uint32_t)S[s3 >> 24] << 24) + | ((uint32_t)S[(s0 >> 16) & 0xFF] << 16) + | ((uint32_t)S[(s1 >> 8) & 0xFF] << 8) + | (uint32_t)S[s2 & 0xFF]; + s0 = t0 ^ skey[num_rounds << 2]; + s1 = t1 ^ skey[(num_rounds << 2) + 1]; + s2 = t2 ^ skey[(num_rounds << 2) + 2]; + s3 = t3 ^ skey[(num_rounds << 2) + 3]; + br_enc32be(buf, s0); + br_enc32be(buf + 4, s1); + br_enc32be(buf + 8, s2); + br_enc32be(buf + 12, s3); +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_common.c b/BearSSL-OG/libbearssl/src/symcipher/aes_common.c new file mode 100644 index 0000000..72c64fb --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_common.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static const uint32_t Rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, + 0x40000000, 0x80000000, 0x1B000000, 0x36000000 +}; + +#define S br_aes_S + +/* see inner.h */ +const unsigned char br_aes_S[] = { + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, + 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, + 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, + 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, + 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, + 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, + 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, + 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, + 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, + 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, + 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, + 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, + 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, + 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, + 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, + 0xB0, 0x54, 0xBB, 0x16 +}; + +static uint32_t +SubWord(uint32_t x) +{ + return ((uint32_t)S[x >> 24] << 24) + | ((uint32_t)S[(x >> 16) & 0xFF] << 16) + | ((uint32_t)S[(x >> 8) & 0xFF] << 8) + | (uint32_t)S[x & 0xFF]; +} + +/* see inner.h */ +unsigned +br_aes_keysched(uint32_t *skey, const void *key, size_t key_len) +{ + unsigned num_rounds; + int i, j, k, nk, nkf; + + switch (key_len) { + case 16: + num_rounds = 10; + break; + case 24: + num_rounds = 12; + break; + case 32: + num_rounds = 14; + break; + default: + /* abort(); */ + return 0; + } + nk = (int)(key_len >> 2); + nkf = (int)((num_rounds + 1) << 2); + for (i = 0; i < nk; i ++) { + skey[i] = br_dec32be((const unsigned char *)key + (i << 2)); + } + for (i = nk, j = 0, k = 0; i < nkf; i ++) { + uint32_t tmp; + + tmp = skey[i - 1]; + if (j == 0) { + tmp = (tmp << 8) | (tmp >> 24); + tmp = SubWord(tmp) ^ Rcon[k]; + } else if (nk > 6 && j == 4) { + tmp = SubWord(tmp); + } + skey[i] = skey[i - nk] ^ tmp; + if (++ j == nk) { + j = 0; + k ++; + } + } + return num_rounds; +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct.c new file mode 100644 index 0000000..66776d9 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct.c @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_aes_ct_bitslice_Sbox(uint32_t *q) +{ + /* + * This S-box implementation is a straightforward translation of + * the circuit described by Boyar and Peralta in "A new + * combinational logic minimization technique with applications + * to cryptology" (https://eprint.iacr.org/2009/191.pdf). + * + * Note that variables x* (input) and s* (output) are numbered + * in "reverse" order (x0 is the high bit, x7 is the low bit). + */ + + uint32_t x0, x1, x2, x3, x4, x5, x6, x7; + uint32_t y1, y2, y3, y4, y5, y6, y7, y8, y9; + uint32_t y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; + uint32_t y20, y21; + uint32_t z0, z1, z2, z3, z4, z5, z6, z7, z8, z9; + uint32_t z10, z11, z12, z13, z14, z15, z16, z17; + uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; + uint32_t t10, t11, t12, t13, t14, t15, t16, t17, t18, t19; + uint32_t t20, t21, t22, t23, t24, t25, t26, t27, t28, t29; + uint32_t t30, t31, t32, t33, t34, t35, t36, t37, t38, t39; + uint32_t t40, t41, t42, t43, t44, t45, t46, t47, t48, t49; + uint32_t t50, t51, t52, t53, t54, t55, t56, t57, t58, t59; + uint32_t t60, t61, t62, t63, t64, t65, t66, t67; + uint32_t s0, s1, s2, s3, s4, s5, s6, s7; + + x0 = q[7]; + x1 = q[6]; + x2 = q[5]; + x3 = q[4]; + x4 = q[3]; + x5 = q[2]; + x6 = q[1]; + x7 = q[0]; + + /* + * Top linear transformation. + */ + y14 = x3 ^ x5; + y13 = x0 ^ x6; + y9 = x0 ^ x3; + y8 = x0 ^ x5; + t0 = x1 ^ x2; + y1 = t0 ^ x7; + y4 = y1 ^ x3; + y12 = y13 ^ y14; + y2 = y1 ^ x0; + y5 = y1 ^ x6; + y3 = y5 ^ y8; + t1 = x4 ^ y12; + y15 = t1 ^ x5; + y20 = t1 ^ x1; + y6 = y15 ^ x7; + y10 = y15 ^ t0; + y11 = y20 ^ y9; + y7 = x7 ^ y11; + y17 = y10 ^ y11; + y19 = y10 ^ y8; + y16 = t0 ^ y11; + y21 = y13 ^ y16; + y18 = x0 ^ y16; + + /* + * Non-linear section. + */ + t2 = y12 & y15; + t3 = y3 & y6; + t4 = t3 ^ t2; + t5 = y4 & x7; + t6 = t5 ^ t2; + t7 = y13 & y16; + t8 = y5 & y1; + t9 = t8 ^ t7; + t10 = y2 & y7; + t11 = t10 ^ t7; + t12 = y9 & y11; + t13 = y14 & y17; + t14 = t13 ^ t12; + t15 = y8 & y10; + t16 = t15 ^ t12; + t17 = t4 ^ t14; + t18 = t6 ^ t16; + t19 = t9 ^ t14; + t20 = t11 ^ t16; + t21 = t17 ^ y20; + t22 = t18 ^ y19; + t23 = t19 ^ y21; + t24 = t20 ^ y18; + + t25 = t21 ^ t22; + t26 = t21 & t23; + t27 = t24 ^ t26; + t28 = t25 & t27; + t29 = t28 ^ t22; + t30 = t23 ^ t24; + t31 = t22 ^ t26; + t32 = t31 & t30; + t33 = t32 ^ t24; + t34 = t23 ^ t33; + t35 = t27 ^ t33; + t36 = t24 & t35; + t37 = t36 ^ t34; + t38 = t27 ^ t36; + t39 = t29 & t38; + t40 = t25 ^ t39; + + t41 = t40 ^ t37; + t42 = t29 ^ t33; + t43 = t29 ^ t40; + t44 = t33 ^ t37; + t45 = t42 ^ t41; + z0 = t44 & y15; + z1 = t37 & y6; + z2 = t33 & x7; + z3 = t43 & y16; + z4 = t40 & y1; + z5 = t29 & y7; + z6 = t42 & y11; + z7 = t45 & y17; + z8 = t41 & y10; + z9 = t44 & y12; + z10 = t37 & y3; + z11 = t33 & y4; + z12 = t43 & y13; + z13 = t40 & y5; + z14 = t29 & y2; + z15 = t42 & y9; + z16 = t45 & y14; + z17 = t41 & y8; + + /* + * Bottom linear transformation. + */ + t46 = z15 ^ z16; + t47 = z10 ^ z11; + t48 = z5 ^ z13; + t49 = z9 ^ z10; + t50 = z2 ^ z12; + t51 = z2 ^ z5; + t52 = z7 ^ z8; + t53 = z0 ^ z3; + t54 = z6 ^ z7; + t55 = z16 ^ z17; + t56 = z12 ^ t48; + t57 = t50 ^ t53; + t58 = z4 ^ t46; + t59 = z3 ^ t54; + t60 = t46 ^ t57; + t61 = z14 ^ t57; + t62 = t52 ^ t58; + t63 = t49 ^ t58; + t64 = z4 ^ t59; + t65 = t61 ^ t62; + t66 = z1 ^ t63; + s0 = t59 ^ t63; + s6 = t56 ^ ~t62; + s7 = t48 ^ ~t60; + t67 = t64 ^ t65; + s3 = t53 ^ t66; + s4 = t51 ^ t66; + s5 = t47 ^ t65; + s1 = t64 ^ ~s3; + s2 = t55 ^ ~t67; + + q[7] = s0; + q[6] = s1; + q[5] = s2; + q[4] = s3; + q[3] = s4; + q[2] = s5; + q[1] = s6; + q[0] = s7; +} + +/* see inner.h */ +void +br_aes_ct_ortho(uint32_t *q) +{ +#define SWAPN(cl, ch, s, x, y) do { \ + uint32_t a, b; \ + a = (x); \ + b = (y); \ + (x) = (a & (uint32_t)cl) | ((b & (uint32_t)cl) << (s)); \ + (y) = ((a & (uint32_t)ch) >> (s)) | (b & (uint32_t)ch); \ + } while (0) + +#define SWAP2(x, y) SWAPN(0x55555555, 0xAAAAAAAA, 1, x, y) +#define SWAP4(x, y) SWAPN(0x33333333, 0xCCCCCCCC, 2, x, y) +#define SWAP8(x, y) SWAPN(0x0F0F0F0F, 0xF0F0F0F0, 4, x, y) + + SWAP2(q[0], q[1]); + SWAP2(q[2], q[3]); + SWAP2(q[4], q[5]); + SWAP2(q[6], q[7]); + + SWAP4(q[0], q[2]); + SWAP4(q[1], q[3]); + SWAP4(q[4], q[6]); + SWAP4(q[5], q[7]); + + SWAP8(q[0], q[4]); + SWAP8(q[1], q[5]); + SWAP8(q[2], q[6]); + SWAP8(q[3], q[7]); +} + +static const unsigned char Rcon[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 +}; + +static uint32_t +sub_word(uint32_t x) +{ + uint32_t q[8]; + int i; + + for (i = 0; i < 8; i ++) { + q[i] = x; + } + br_aes_ct_ortho(q); + br_aes_ct_bitslice_Sbox(q); + br_aes_ct_ortho(q); + return q[0]; +} + +/* see inner.h */ +unsigned +br_aes_ct_keysched(uint32_t *comp_skey, const void *key, size_t key_len) +{ + unsigned num_rounds; + int i, j, k, nk, nkf; + uint32_t tmp; + uint32_t skey[120]; + + switch (key_len) { + case 16: + num_rounds = 10; + break; + case 24: + num_rounds = 12; + break; + case 32: + num_rounds = 14; + break; + default: + /* abort(); */ + return 0; + } + nk = (int)(key_len >> 2); + nkf = (int)((num_rounds + 1) << 2); + tmp = 0; + for (i = 0; i < nk; i ++) { + tmp = br_dec32le((const unsigned char *)key + (i << 2)); + skey[(i << 1) + 0] = tmp; + skey[(i << 1) + 1] = tmp; + } + for (i = nk, j = 0, k = 0; i < nkf; i ++) { + if (j == 0) { + tmp = (tmp << 24) | (tmp >> 8); + tmp = sub_word(tmp) ^ Rcon[k]; + } else if (nk > 6 && j == 4) { + tmp = sub_word(tmp); + } + tmp ^= skey[(i - nk) << 1]; + skey[(i << 1) + 0] = tmp; + skey[(i << 1) + 1] = tmp; + if (++ j == nk) { + j = 0; + k ++; + } + } + for (i = 0; i < nkf; i += 4) { + br_aes_ct_ortho(skey + (i << 1)); + } + for (i = 0, j = 0; i < nkf; i ++, j += 2) { + comp_skey[i] = (skey[j + 0] & 0x55555555) + | (skey[j + 1] & 0xAAAAAAAA); + } + return num_rounds; +} + +/* see inner.h */ +void +br_aes_ct_skey_expand(uint32_t *skey, + unsigned num_rounds, const uint32_t *comp_skey) +{ + unsigned u, v, n; + + n = (num_rounds + 1) << 2; + for (u = 0, v = 0; u < n; u ++, v += 2) { + uint32_t x, y; + + x = y = comp_skey[u]; + x &= 0x55555555; + skey[v + 0] = x | (x << 1); + y &= 0xAAAAAAAA; + skey[v + 1] = y | (y >> 1); + } +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct64.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64.c new file mode 100644 index 0000000..1523811 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64.c @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_aes_ct64_bitslice_Sbox(uint64_t *q) +{ + /* + * This S-box implementation is a straightforward translation of + * the circuit described by Boyar and Peralta in "A new + * combinational logic minimization technique with applications + * to cryptology" (https://eprint.iacr.org/2009/191.pdf). + * + * Note that variables x* (input) and s* (output) are numbered + * in "reverse" order (x0 is the high bit, x7 is the low bit). + */ + + uint64_t x0, x1, x2, x3, x4, x5, x6, x7; + uint64_t y1, y2, y3, y4, y5, y6, y7, y8, y9; + uint64_t y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; + uint64_t y20, y21; + uint64_t z0, z1, z2, z3, z4, z5, z6, z7, z8, z9; + uint64_t z10, z11, z12, z13, z14, z15, z16, z17; + uint64_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; + uint64_t t10, t11, t12, t13, t14, t15, t16, t17, t18, t19; + uint64_t t20, t21, t22, t23, t24, t25, t26, t27, t28, t29; + uint64_t t30, t31, t32, t33, t34, t35, t36, t37, t38, t39; + uint64_t t40, t41, t42, t43, t44, t45, t46, t47, t48, t49; + uint64_t t50, t51, t52, t53, t54, t55, t56, t57, t58, t59; + uint64_t t60, t61, t62, t63, t64, t65, t66, t67; + uint64_t s0, s1, s2, s3, s4, s5, s6, s7; + + x0 = q[7]; + x1 = q[6]; + x2 = q[5]; + x3 = q[4]; + x4 = q[3]; + x5 = q[2]; + x6 = q[1]; + x7 = q[0]; + + /* + * Top linear transformation. + */ + y14 = x3 ^ x5; + y13 = x0 ^ x6; + y9 = x0 ^ x3; + y8 = x0 ^ x5; + t0 = x1 ^ x2; + y1 = t0 ^ x7; + y4 = y1 ^ x3; + y12 = y13 ^ y14; + y2 = y1 ^ x0; + y5 = y1 ^ x6; + y3 = y5 ^ y8; + t1 = x4 ^ y12; + y15 = t1 ^ x5; + y20 = t1 ^ x1; + y6 = y15 ^ x7; + y10 = y15 ^ t0; + y11 = y20 ^ y9; + y7 = x7 ^ y11; + y17 = y10 ^ y11; + y19 = y10 ^ y8; + y16 = t0 ^ y11; + y21 = y13 ^ y16; + y18 = x0 ^ y16; + + /* + * Non-linear section. + */ + t2 = y12 & y15; + t3 = y3 & y6; + t4 = t3 ^ t2; + t5 = y4 & x7; + t6 = t5 ^ t2; + t7 = y13 & y16; + t8 = y5 & y1; + t9 = t8 ^ t7; + t10 = y2 & y7; + t11 = t10 ^ t7; + t12 = y9 & y11; + t13 = y14 & y17; + t14 = t13 ^ t12; + t15 = y8 & y10; + t16 = t15 ^ t12; + t17 = t4 ^ t14; + t18 = t6 ^ t16; + t19 = t9 ^ t14; + t20 = t11 ^ t16; + t21 = t17 ^ y20; + t22 = t18 ^ y19; + t23 = t19 ^ y21; + t24 = t20 ^ y18; + + t25 = t21 ^ t22; + t26 = t21 & t23; + t27 = t24 ^ t26; + t28 = t25 & t27; + t29 = t28 ^ t22; + t30 = t23 ^ t24; + t31 = t22 ^ t26; + t32 = t31 & t30; + t33 = t32 ^ t24; + t34 = t23 ^ t33; + t35 = t27 ^ t33; + t36 = t24 & t35; + t37 = t36 ^ t34; + t38 = t27 ^ t36; + t39 = t29 & t38; + t40 = t25 ^ t39; + + t41 = t40 ^ t37; + t42 = t29 ^ t33; + t43 = t29 ^ t40; + t44 = t33 ^ t37; + t45 = t42 ^ t41; + z0 = t44 & y15; + z1 = t37 & y6; + z2 = t33 & x7; + z3 = t43 & y16; + z4 = t40 & y1; + z5 = t29 & y7; + z6 = t42 & y11; + z7 = t45 & y17; + z8 = t41 & y10; + z9 = t44 & y12; + z10 = t37 & y3; + z11 = t33 & y4; + z12 = t43 & y13; + z13 = t40 & y5; + z14 = t29 & y2; + z15 = t42 & y9; + z16 = t45 & y14; + z17 = t41 & y8; + + /* + * Bottom linear transformation. + */ + t46 = z15 ^ z16; + t47 = z10 ^ z11; + t48 = z5 ^ z13; + t49 = z9 ^ z10; + t50 = z2 ^ z12; + t51 = z2 ^ z5; + t52 = z7 ^ z8; + t53 = z0 ^ z3; + t54 = z6 ^ z7; + t55 = z16 ^ z17; + t56 = z12 ^ t48; + t57 = t50 ^ t53; + t58 = z4 ^ t46; + t59 = z3 ^ t54; + t60 = t46 ^ t57; + t61 = z14 ^ t57; + t62 = t52 ^ t58; + t63 = t49 ^ t58; + t64 = z4 ^ t59; + t65 = t61 ^ t62; + t66 = z1 ^ t63; + s0 = t59 ^ t63; + s6 = t56 ^ ~t62; + s7 = t48 ^ ~t60; + t67 = t64 ^ t65; + s3 = t53 ^ t66; + s4 = t51 ^ t66; + s5 = t47 ^ t65; + s1 = t64 ^ ~s3; + s2 = t55 ^ ~t67; + + q[7] = s0; + q[6] = s1; + q[5] = s2; + q[4] = s3; + q[3] = s4; + q[2] = s5; + q[1] = s6; + q[0] = s7; +} + +/* see inner.h */ +void +br_aes_ct64_ortho(uint64_t *q) +{ +#define SWAPN(cl, ch, s, x, y) do { \ + uint64_t a, b; \ + a = (x); \ + b = (y); \ + (x) = (a & (uint64_t)cl) | ((b & (uint64_t)cl) << (s)); \ + (y) = ((a & (uint64_t)ch) >> (s)) | (b & (uint64_t)ch); \ + } while (0) + +#define SWAP2(x, y) SWAPN(0x5555555555555555, 0xAAAAAAAAAAAAAAAA, 1, x, y) +#define SWAP4(x, y) SWAPN(0x3333333333333333, 0xCCCCCCCCCCCCCCCC, 2, x, y) +#define SWAP8(x, y) SWAPN(0x0F0F0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0F0, 4, x, y) + + SWAP2(q[0], q[1]); + SWAP2(q[2], q[3]); + SWAP2(q[4], q[5]); + SWAP2(q[6], q[7]); + + SWAP4(q[0], q[2]); + SWAP4(q[1], q[3]); + SWAP4(q[4], q[6]); + SWAP4(q[5], q[7]); + + SWAP8(q[0], q[4]); + SWAP8(q[1], q[5]); + SWAP8(q[2], q[6]); + SWAP8(q[3], q[7]); +} + +/* see inner.h */ +void +br_aes_ct64_interleave_in(uint64_t *q0, uint64_t *q1, const uint32_t *w) +{ + uint64_t x0, x1, x2, x3; + + x0 = w[0]; + x1 = w[1]; + x2 = w[2]; + x3 = w[3]; + x0 |= (x0 << 16); + x1 |= (x1 << 16); + x2 |= (x2 << 16); + x3 |= (x3 << 16); + x0 &= (uint64_t)0x0000FFFF0000FFFF; + x1 &= (uint64_t)0x0000FFFF0000FFFF; + x2 &= (uint64_t)0x0000FFFF0000FFFF; + x3 &= (uint64_t)0x0000FFFF0000FFFF; + x0 |= (x0 << 8); + x1 |= (x1 << 8); + x2 |= (x2 << 8); + x3 |= (x3 << 8); + x0 &= (uint64_t)0x00FF00FF00FF00FF; + x1 &= (uint64_t)0x00FF00FF00FF00FF; + x2 &= (uint64_t)0x00FF00FF00FF00FF; + x3 &= (uint64_t)0x00FF00FF00FF00FF; + *q0 = x0 | (x2 << 8); + *q1 = x1 | (x3 << 8); +} + +/* see inner.h */ +void +br_aes_ct64_interleave_out(uint32_t *w, uint64_t q0, uint64_t q1) +{ + uint64_t x0, x1, x2, x3; + + x0 = q0 & (uint64_t)0x00FF00FF00FF00FF; + x1 = q1 & (uint64_t)0x00FF00FF00FF00FF; + x2 = (q0 >> 8) & (uint64_t)0x00FF00FF00FF00FF; + x3 = (q1 >> 8) & (uint64_t)0x00FF00FF00FF00FF; + x0 |= (x0 >> 8); + x1 |= (x1 >> 8); + x2 |= (x2 >> 8); + x3 |= (x3 >> 8); + x0 &= (uint64_t)0x0000FFFF0000FFFF; + x1 &= (uint64_t)0x0000FFFF0000FFFF; + x2 &= (uint64_t)0x0000FFFF0000FFFF; + x3 &= (uint64_t)0x0000FFFF0000FFFF; + w[0] = (uint32_t)x0 | (uint32_t)(x0 >> 16); + w[1] = (uint32_t)x1 | (uint32_t)(x1 >> 16); + w[2] = (uint32_t)x2 | (uint32_t)(x2 >> 16); + w[3] = (uint32_t)x3 | (uint32_t)(x3 >> 16); +} + +static const unsigned char Rcon[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 +}; + +static uint32_t +sub_word(uint32_t x) +{ + uint64_t q[8]; + + memset(q, 0, sizeof q); + q[0] = x; + br_aes_ct64_ortho(q); + br_aes_ct64_bitslice_Sbox(q); + br_aes_ct64_ortho(q); + return (uint32_t)q[0]; +} + +/* see inner.h */ +unsigned +br_aes_ct64_keysched(uint64_t *comp_skey, const void *key, size_t key_len) +{ + unsigned num_rounds; + int i, j, k, nk, nkf; + uint32_t tmp; + uint32_t skey[60]; + + switch (key_len) { + case 16: + num_rounds = 10; + break; + case 24: + num_rounds = 12; + break; + case 32: + num_rounds = 14; + break; + default: + /* abort(); */ + return 0; + } + nk = (int)(key_len >> 2); + nkf = (int)((num_rounds + 1) << 2); + br_range_dec32le(skey, (key_len >> 2), key); + tmp = skey[(key_len >> 2) - 1]; + for (i = nk, j = 0, k = 0; i < nkf; i ++) { + if (j == 0) { + tmp = (tmp << 24) | (tmp >> 8); + tmp = sub_word(tmp) ^ Rcon[k]; + } else if (nk > 6 && j == 4) { + tmp = sub_word(tmp); + } + tmp ^= skey[i - nk]; + skey[i] = tmp; + if (++ j == nk) { + j = 0; + k ++; + } + } + + for (i = 0, j = 0; i < nkf; i += 4, j += 2) { + uint64_t q[8]; + + br_aes_ct64_interleave_in(&q[0], &q[4], skey + i); + q[1] = q[0]; + q[2] = q[0]; + q[3] = q[0]; + q[5] = q[4]; + q[6] = q[4]; + q[7] = q[4]; + br_aes_ct64_ortho(q); + comp_skey[j + 0] = + (q[0] & (uint64_t)0x1111111111111111) + | (q[1] & (uint64_t)0x2222222222222222) + | (q[2] & (uint64_t)0x4444444444444444) + | (q[3] & (uint64_t)0x8888888888888888); + comp_skey[j + 1] = + (q[4] & (uint64_t)0x1111111111111111) + | (q[5] & (uint64_t)0x2222222222222222) + | (q[6] & (uint64_t)0x4444444444444444) + | (q[7] & (uint64_t)0x8888888888888888); + } + return num_rounds; +} + +/* see inner.h */ +void +br_aes_ct64_skey_expand(uint64_t *skey, + unsigned num_rounds, const uint64_t *comp_skey) +{ + unsigned u, v, n; + + n = (num_rounds + 1) << 1; + for (u = 0, v = 0; u < n; u ++, v += 4) { + uint64_t x0, x1, x2, x3; + + x0 = x1 = x2 = x3 = comp_skey[u]; + x0 &= (uint64_t)0x1111111111111111; + x1 &= (uint64_t)0x2222222222222222; + x2 &= (uint64_t)0x4444444444444444; + x3 &= (uint64_t)0x8888888888888888; + x1 >>= 1; + x2 >>= 2; + x3 >>= 3; + skey[v + 0] = (x0 << 4) - x0; + skey[v + 1] = (x1 << 4) - x1; + skey[v + 2] = (x2 << 4) - x2; + skey[v + 3] = (x3 << 4) - x3; + } +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_cbcdec.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_cbcdec.c new file mode 100644 index 0000000..5a7360b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_cbcdec.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_ct64_cbcdec_init(br_aes_ct64_cbcdec_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_ct64_cbcdec_vtable; + ctx->num_rounds = br_aes_ct64_keysched(ctx->skey, key, len); +} + +/* see bearssl_block.h */ +void +br_aes_ct64_cbcdec_run(const br_aes_ct64_cbcdec_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf; + uint64_t sk_exp[120]; + uint32_t ivw[4]; + + br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + br_range_dec32le(ivw, 4, iv); + buf = data; + while (len > 0) { + uint64_t q[8]; + uint32_t w1[16], w2[16]; + int i; + + if (len >= 64) { + br_range_dec32le(w1, 16, buf); + } else { + br_range_dec32le(w1, len >> 2, buf); + } + for (i = 0; i < 4; i ++) { + br_aes_ct64_interleave_in( + &q[i], &q[i + 4], w1 + (i << 2)); + } + br_aes_ct64_ortho(q); + br_aes_ct64_bitslice_decrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct64_ortho(q); + for (i = 0; i < 4; i ++) { + br_aes_ct64_interleave_out( + w2 + (i << 2), q[i], q[i + 4]); + } + for (i = 0; i < 4; i ++) { + w2[i] ^= ivw[i]; + } + if (len >= 64) { + for (i = 4; i < 16; i ++) { + w2[i] ^= w1[i - 4]; + } + memcpy(ivw, w1 + 12, sizeof ivw); + br_range_enc32le(buf, w2, 16); + } else { + int j; + + j = (int)(len >> 2); + for (i = 4; i < j; i ++) { + w2[i] ^= w1[i - 4]; + } + memcpy(ivw, w1 + j - 4, sizeof ivw); + br_range_enc32le(buf, w2, j); + break; + } + buf += 64; + len -= 64; + } + br_range_enc32le(iv, ivw, 4); +} + +/* see bearssl_block.h */ +const br_block_cbcdec_class br_aes_ct64_cbcdec_vtable = { + sizeof(br_aes_ct64_cbcdec_keys), + 16, + 4, + (void (*)(const br_block_cbcdec_class **, const void *, size_t)) + &br_aes_ct64_cbcdec_init, + (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) + &br_aes_ct64_cbcdec_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_cbcenc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_cbcenc.c new file mode 100644 index 0000000..6cb9dec --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_cbcenc.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_ct64_cbcenc_init(br_aes_ct64_cbcenc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_ct64_cbcenc_vtable; + ctx->num_rounds = br_aes_ct64_keysched(ctx->skey, key, len); +} + +/* see bearssl_block.h */ +void +br_aes_ct64_cbcenc_run(const br_aes_ct64_cbcenc_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf; + uint64_t sk_exp[120]; + uint32_t ivw[4]; + + br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + br_range_dec32le(ivw, 4, iv); + buf = data; + while (len > 0) { + uint32_t w[4]; + uint64_t q[8]; + + w[0] = ivw[0] ^ br_dec32le(buf); + w[1] = ivw[1] ^ br_dec32le(buf + 4); + w[2] = ivw[2] ^ br_dec32le(buf + 8); + w[3] = ivw[3] ^ br_dec32le(buf + 12); + br_aes_ct64_interleave_in(&q[0], &q[4], w); + br_aes_ct64_ortho(q); + br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct64_ortho(q); + br_aes_ct64_interleave_out(w, q[0], q[4]); + memcpy(ivw, w, sizeof w); + br_enc32le(buf, w[0]); + br_enc32le(buf + 4, w[1]); + br_enc32le(buf + 8, w[2]); + br_enc32le(buf + 12, w[3]); + buf += 16; + len -= 16; + } + br_range_enc32le(iv, ivw, 4); +} + +/* see bearssl_block.h */ +const br_block_cbcenc_class br_aes_ct64_cbcenc_vtable = { + sizeof(br_aes_ct64_cbcenc_keys), + 16, + 4, + (void (*)(const br_block_cbcenc_class **, const void *, size_t)) + &br_aes_ct64_cbcenc_init, + (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) + &br_aes_ct64_cbcenc_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_ctr.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_ctr.c new file mode 100644 index 0000000..1275873 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_ctr.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_ct64_ctr_init(br_aes_ct64_ctr_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_ct64_ctr_vtable; + ctx->num_rounds = br_aes_ct64_keysched(ctx->skey, key, len); +} + +static void +xorbuf(void *dst, const void *src, size_t len) +{ + unsigned char *d; + const unsigned char *s; + + d = dst; + s = src; + while (len -- > 0) { + *d ++ ^= *s ++; + } +} + +/* see bearssl_block.h */ +uint32_t +br_aes_ct64_ctr_run(const br_aes_ct64_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len) +{ + unsigned char *buf; + uint32_t ivw[16]; + uint64_t sk_exp[120]; + + br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + br_range_dec32le(ivw, 3, iv); + memcpy(ivw + 4, ivw, 3 * sizeof(uint32_t)); + memcpy(ivw + 8, ivw, 3 * sizeof(uint32_t)); + memcpy(ivw + 12, ivw, 3 * sizeof(uint32_t)); + buf = data; + while (len > 0) { + uint64_t q[8]; + uint32_t w[16]; + unsigned char tmp[64]; + int i; + + /* + * TODO: see if we can save on the first br_aes_ct64_ortho() + * call, since iv0/iv1/iv2 are constant for the whole run. + */ + memcpy(w, ivw, sizeof ivw); + w[3] = br_swap32(cc); + w[7] = br_swap32(cc + 1); + w[11] = br_swap32(cc + 2); + w[15] = br_swap32(cc + 3); + for (i = 0; i < 4; i ++) { + br_aes_ct64_interleave_in( + &q[i], &q[i + 4], w + (i << 2)); + } + br_aes_ct64_ortho(q); + br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct64_ortho(q); + for (i = 0; i < 4; i ++) { + br_aes_ct64_interleave_out( + w + (i << 2), q[i], q[i + 4]); + } + br_range_enc32le(tmp, w, 16); + if (len <= 64) { + xorbuf(buf, tmp, len); + cc += (uint32_t)len >> 4; + break; + } + xorbuf(buf, tmp, 64); + buf += 64; + len -= 64; + cc += 4; + } + return cc; +} + +/* see bearssl_block.h */ +const br_block_ctr_class br_aes_ct64_ctr_vtable = { + sizeof(br_aes_ct64_ctr_keys), + 16, + 4, + (void (*)(const br_block_ctr_class **, const void *, size_t)) + &br_aes_ct64_ctr_init, + (uint32_t (*)(const br_block_ctr_class *const *, + const void *, uint32_t, void *, size_t)) + &br_aes_ct64_ctr_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_ctrcbc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_ctrcbc.c new file mode 100644 index 0000000..21bb8ef --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_ctrcbc.c @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_ct64_ctrcbc_init(br_aes_ct64_ctrcbc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_ct64_ctrcbc_vtable; + ctx->num_rounds = br_aes_ct64_keysched(ctx->skey, key, len); +} + +static void +xorbuf(void *dst, const void *src, size_t len) +{ + unsigned char *d; + const unsigned char *s; + + d = dst; + s = src; + while (len -- > 0) { + *d ++ ^= *s ++; + } +} + +/* see bearssl_block.h */ +void +br_aes_ct64_ctrcbc_ctr(const br_aes_ct64_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len) +{ + unsigned char *buf; + unsigned char *ivbuf; + uint32_t iv0, iv1, iv2, iv3; + uint64_t sk_exp[120]; + + br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + + /* + * We keep the counter as four 32-bit values, with big-endian + * convention, because that's what is expected for purposes of + * incrementing the counter value. + */ + ivbuf = ctr; + iv0 = br_dec32be(ivbuf + 0); + iv1 = br_dec32be(ivbuf + 4); + iv2 = br_dec32be(ivbuf + 8); + iv3 = br_dec32be(ivbuf + 12); + + buf = data; + while (len > 0) { + uint64_t q[8]; + uint32_t w[16]; + unsigned char tmp[64]; + int i, j; + + /* + * The bitslice implementation expects values in + * little-endian convention, so we have to byteswap them. + */ + j = (len >= 64) ? 16 : (int)(len >> 2); + for (i = 0; i < j; i += 4) { + uint32_t carry; + + w[i + 0] = br_swap32(iv0); + w[i + 1] = br_swap32(iv1); + w[i + 2] = br_swap32(iv2); + w[i + 3] = br_swap32(iv3); + iv3 ++; + carry = ~(iv3 | -iv3) >> 31; + iv2 += carry; + carry &= -(~(iv2 | -iv2) >> 31); + iv1 += carry; + carry &= -(~(iv1 | -iv1) >> 31); + iv0 += carry; + } + memset(w + i, 0, (16 - i) * sizeof(uint32_t)); + + for (i = 0; i < 4; i ++) { + br_aes_ct64_interleave_in( + &q[i], &q[i + 4], w + (i << 2)); + } + br_aes_ct64_ortho(q); + br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct64_ortho(q); + for (i = 0; i < 4; i ++) { + br_aes_ct64_interleave_out( + w + (i << 2), q[i], q[i + 4]); + } + + br_range_enc32le(tmp, w, 16); + if (len <= 64) { + xorbuf(buf, tmp, len); + break; + } + xorbuf(buf, tmp, 64); + buf += 64; + len -= 64; + } + br_enc32be(ivbuf + 0, iv0); + br_enc32be(ivbuf + 4, iv1); + br_enc32be(ivbuf + 8, iv2); + br_enc32be(ivbuf + 12, iv3); +} + +/* see bearssl_block.h */ +void +br_aes_ct64_ctrcbc_mac(const br_aes_ct64_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len) +{ + const unsigned char *buf; + uint32_t cm0, cm1, cm2, cm3; + uint64_t q[8]; + uint64_t sk_exp[120]; + + br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + + cm0 = br_dec32le((unsigned char *)cbcmac + 0); + cm1 = br_dec32le((unsigned char *)cbcmac + 4); + cm2 = br_dec32le((unsigned char *)cbcmac + 8); + cm3 = br_dec32le((unsigned char *)cbcmac + 12); + + buf = data; + memset(q, 0, sizeof q); + while (len > 0) { + uint32_t w[4]; + + w[0] = cm0 ^ br_dec32le(buf + 0); + w[1] = cm1 ^ br_dec32le(buf + 4); + w[2] = cm2 ^ br_dec32le(buf + 8); + w[3] = cm3 ^ br_dec32le(buf + 12); + + br_aes_ct64_interleave_in(&q[0], &q[4], w); + br_aes_ct64_ortho(q); + br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct64_ortho(q); + br_aes_ct64_interleave_out(w, q[0], q[4]); + + cm0 = w[0]; + cm1 = w[1]; + cm2 = w[2]; + cm3 = w[3]; + buf += 16; + len -= 16; + } + + br_enc32le((unsigned char *)cbcmac + 0, cm0); + br_enc32le((unsigned char *)cbcmac + 4, cm1); + br_enc32le((unsigned char *)cbcmac + 8, cm2); + br_enc32le((unsigned char *)cbcmac + 12, cm3); +} + +/* see bearssl_block.h */ +void +br_aes_ct64_ctrcbc_encrypt(const br_aes_ct64_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len) +{ + /* + * When encrypting, the CBC-MAC processing must be lagging by + * one block, since it operates on the encrypted values, so + * it must wait for that encryption to complete. + */ + + unsigned char *buf; + unsigned char *ivbuf; + uint32_t iv0, iv1, iv2, iv3; + uint32_t cm0, cm1, cm2, cm3; + uint64_t sk_exp[120]; + uint64_t q[8]; + int first_iter; + + br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + + /* + * We keep the counter as four 32-bit values, with big-endian + * convention, because that's what is expected for purposes of + * incrementing the counter value. + */ + ivbuf = ctr; + iv0 = br_dec32be(ivbuf + 0); + iv1 = br_dec32be(ivbuf + 4); + iv2 = br_dec32be(ivbuf + 8); + iv3 = br_dec32be(ivbuf + 12); + + /* + * The current CBC-MAC value is kept in little-endian convention. + */ + cm0 = br_dec32le((unsigned char *)cbcmac + 0); + cm1 = br_dec32le((unsigned char *)cbcmac + 4); + cm2 = br_dec32le((unsigned char *)cbcmac + 8); + cm3 = br_dec32le((unsigned char *)cbcmac + 12); + + buf = data; + first_iter = 1; + memset(q, 0, sizeof q); + while (len > 0) { + uint32_t w[8], carry; + + /* + * The bitslice implementation expects values in + * little-endian convention, so we have to byteswap them. + */ + w[0] = br_swap32(iv0); + w[1] = br_swap32(iv1); + w[2] = br_swap32(iv2); + w[3] = br_swap32(iv3); + iv3 ++; + carry = ~(iv3 | -iv3) >> 31; + iv2 += carry; + carry &= -(~(iv2 | -iv2) >> 31); + iv1 += carry; + carry &= -(~(iv1 | -iv1) >> 31); + iv0 += carry; + + /* + * The block for CBC-MAC. + */ + w[4] = cm0; + w[5] = cm1; + w[6] = cm2; + w[7] = cm3; + + br_aes_ct64_interleave_in(&q[0], &q[4], w); + br_aes_ct64_interleave_in(&q[1], &q[5], w + 4); + br_aes_ct64_ortho(q); + br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct64_ortho(q); + br_aes_ct64_interleave_out(w, q[0], q[4]); + br_aes_ct64_interleave_out(w + 4, q[1], q[5]); + + /* + * We do the XOR with the plaintext in 32-bit registers, + * so that the value are available for CBC-MAC processing + * as well. + */ + w[0] ^= br_dec32le(buf + 0); + w[1] ^= br_dec32le(buf + 4); + w[2] ^= br_dec32le(buf + 8); + w[3] ^= br_dec32le(buf + 12); + br_enc32le(buf + 0, w[0]); + br_enc32le(buf + 4, w[1]); + br_enc32le(buf + 8, w[2]); + br_enc32le(buf + 12, w[3]); + + buf += 16; + len -= 16; + + /* + * We set the cm* values to the block to encrypt in the + * next iteration. + */ + if (first_iter) { + first_iter = 0; + cm0 ^= w[0]; + cm1 ^= w[1]; + cm2 ^= w[2]; + cm3 ^= w[3]; + } else { + cm0 = w[0] ^ w[4]; + cm1 = w[1] ^ w[5]; + cm2 = w[2] ^ w[6]; + cm3 = w[3] ^ w[7]; + } + + /* + * If this was the last iteration, then compute the + * extra block encryption to complete CBC-MAC. + */ + if (len == 0) { + w[0] = cm0; + w[1] = cm1; + w[2] = cm2; + w[3] = cm3; + br_aes_ct64_interleave_in(&q[0], &q[4], w); + br_aes_ct64_ortho(q); + br_aes_ct64_bitslice_encrypt( + ctx->num_rounds, sk_exp, q); + br_aes_ct64_ortho(q); + br_aes_ct64_interleave_out(w, q[0], q[4]); + cm0 = w[0]; + cm1 = w[1]; + cm2 = w[2]; + cm3 = w[3]; + break; + } + } + + br_enc32be(ivbuf + 0, iv0); + br_enc32be(ivbuf + 4, iv1); + br_enc32be(ivbuf + 8, iv2); + br_enc32be(ivbuf + 12, iv3); + br_enc32le((unsigned char *)cbcmac + 0, cm0); + br_enc32le((unsigned char *)cbcmac + 4, cm1); + br_enc32le((unsigned char *)cbcmac + 8, cm2); + br_enc32le((unsigned char *)cbcmac + 12, cm3); +} + +/* see bearssl_block.h */ +void +br_aes_ct64_ctrcbc_decrypt(const br_aes_ct64_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len) +{ + unsigned char *buf; + unsigned char *ivbuf; + uint32_t iv0, iv1, iv2, iv3; + uint32_t cm0, cm1, cm2, cm3; + uint64_t sk_exp[120]; + uint64_t q[8]; + + br_aes_ct64_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + + /* + * We keep the counter as four 32-bit values, with big-endian + * convention, because that's what is expected for purposes of + * incrementing the counter value. + */ + ivbuf = ctr; + iv0 = br_dec32be(ivbuf + 0); + iv1 = br_dec32be(ivbuf + 4); + iv2 = br_dec32be(ivbuf + 8); + iv3 = br_dec32be(ivbuf + 12); + + /* + * The current CBC-MAC value is kept in little-endian convention. + */ + cm0 = br_dec32le((unsigned char *)cbcmac + 0); + cm1 = br_dec32le((unsigned char *)cbcmac + 4); + cm2 = br_dec32le((unsigned char *)cbcmac + 8); + cm3 = br_dec32le((unsigned char *)cbcmac + 12); + + buf = data; + memset(q, 0, sizeof q); + while (len > 0) { + uint32_t w[8], carry; + unsigned char tmp[16]; + + /* + * The bitslice implementation expects values in + * little-endian convention, so we have to byteswap them. + */ + w[0] = br_swap32(iv0); + w[1] = br_swap32(iv1); + w[2] = br_swap32(iv2); + w[3] = br_swap32(iv3); + iv3 ++; + carry = ~(iv3 | -iv3) >> 31; + iv2 += carry; + carry &= -(~(iv2 | -iv2) >> 31); + iv1 += carry; + carry &= -(~(iv1 | -iv1) >> 31); + iv0 += carry; + + /* + * The block for CBC-MAC. + */ + w[4] = cm0 ^ br_dec32le(buf + 0); + w[5] = cm1 ^ br_dec32le(buf + 4); + w[6] = cm2 ^ br_dec32le(buf + 8); + w[7] = cm3 ^ br_dec32le(buf + 12); + + br_aes_ct64_interleave_in(&q[0], &q[4], w); + br_aes_ct64_interleave_in(&q[1], &q[5], w + 4); + br_aes_ct64_ortho(q); + br_aes_ct64_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct64_ortho(q); + br_aes_ct64_interleave_out(w, q[0], q[4]); + br_aes_ct64_interleave_out(w + 4, q[1], q[5]); + + br_enc32le(tmp + 0, w[0]); + br_enc32le(tmp + 4, w[1]); + br_enc32le(tmp + 8, w[2]); + br_enc32le(tmp + 12, w[3]); + xorbuf(buf, tmp, 16); + cm0 = w[4]; + cm1 = w[5]; + cm2 = w[6]; + cm3 = w[7]; + buf += 16; + len -= 16; + } + + br_enc32be(ivbuf + 0, iv0); + br_enc32be(ivbuf + 4, iv1); + br_enc32be(ivbuf + 8, iv2); + br_enc32be(ivbuf + 12, iv3); + br_enc32le((unsigned char *)cbcmac + 0, cm0); + br_enc32le((unsigned char *)cbcmac + 4, cm1); + br_enc32le((unsigned char *)cbcmac + 8, cm2); + br_enc32le((unsigned char *)cbcmac + 12, cm3); +} + +/* see bearssl_block.h */ +const br_block_ctrcbc_class br_aes_ct64_ctrcbc_vtable = { + sizeof(br_aes_ct64_ctrcbc_keys), + 16, + 4, + (void (*)(const br_block_ctrcbc_class **, const void *, size_t)) + &br_aes_ct64_ctrcbc_init, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, void *, size_t)) + &br_aes_ct64_ctrcbc_encrypt, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, void *, size_t)) + &br_aes_ct64_ctrcbc_decrypt, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, size_t)) + &br_aes_ct64_ctrcbc_ctr, + (void (*)(const br_block_ctrcbc_class *const *, + void *, const void *, size_t)) + &br_aes_ct64_ctrcbc_mac +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_dec.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_dec.c new file mode 100644 index 0000000..2c3abee --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_dec.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_aes_ct64_bitslice_invSbox(uint64_t *q) +{ + /* + * See br_aes_ct_bitslice_invSbox(). This is the natural extension + * to 64-bit registers. + */ + uint64_t q0, q1, q2, q3, q4, q5, q6, q7; + + q0 = ~q[0]; + q1 = ~q[1]; + q2 = q[2]; + q3 = q[3]; + q4 = q[4]; + q5 = ~q[5]; + q6 = ~q[6]; + q7 = q[7]; + q[7] = q1 ^ q4 ^ q6; + q[6] = q0 ^ q3 ^ q5; + q[5] = q7 ^ q2 ^ q4; + q[4] = q6 ^ q1 ^ q3; + q[3] = q5 ^ q0 ^ q2; + q[2] = q4 ^ q7 ^ q1; + q[1] = q3 ^ q6 ^ q0; + q[0] = q2 ^ q5 ^ q7; + + br_aes_ct64_bitslice_Sbox(q); + + q0 = ~q[0]; + q1 = ~q[1]; + q2 = q[2]; + q3 = q[3]; + q4 = q[4]; + q5 = ~q[5]; + q6 = ~q[6]; + q7 = q[7]; + q[7] = q1 ^ q4 ^ q6; + q[6] = q0 ^ q3 ^ q5; + q[5] = q7 ^ q2 ^ q4; + q[4] = q6 ^ q1 ^ q3; + q[3] = q5 ^ q0 ^ q2; + q[2] = q4 ^ q7 ^ q1; + q[1] = q3 ^ q6 ^ q0; + q[0] = q2 ^ q5 ^ q7; +} + +static void +add_round_key(uint64_t *q, const uint64_t *sk) +{ + int i; + + for (i = 0; i < 8; i ++) { + q[i] ^= sk[i]; + } +} + +static void +inv_shift_rows(uint64_t *q) +{ + int i; + + for (i = 0; i < 8; i ++) { + uint64_t x; + + x = q[i]; + q[i] = (x & (uint64_t)0x000000000000FFFF) + | ((x & (uint64_t)0x000000000FFF0000) << 4) + | ((x & (uint64_t)0x00000000F0000000) >> 12) + | ((x & (uint64_t)0x000000FF00000000) << 8) + | ((x & (uint64_t)0x0000FF0000000000) >> 8) + | ((x & (uint64_t)0x000F000000000000) << 12) + | ((x & (uint64_t)0xFFF0000000000000) >> 4); + } +} + +static __inline uint64_t +rotr32(uint64_t x) +{ + return (x << 32) | (x >> 32); +} + +static void +inv_mix_columns(uint64_t *q) +{ + uint64_t q0, q1, q2, q3, q4, q5, q6, q7; + uint64_t r0, r1, r2, r3, r4, r5, r6, r7; + + q0 = q[0]; + q1 = q[1]; + q2 = q[2]; + q3 = q[3]; + q4 = q[4]; + q5 = q[5]; + q6 = q[6]; + q7 = q[7]; + r0 = (q0 >> 16) | (q0 << 48); + r1 = (q1 >> 16) | (q1 << 48); + r2 = (q2 >> 16) | (q2 << 48); + r3 = (q3 >> 16) | (q3 << 48); + r4 = (q4 >> 16) | (q4 << 48); + r5 = (q5 >> 16) | (q5 << 48); + r6 = (q6 >> 16) | (q6 << 48); + r7 = (q7 >> 16) | (q7 << 48); + + q[0] = q5 ^ q6 ^ q7 ^ r0 ^ r5 ^ r7 ^ rotr32(q0 ^ q5 ^ q6 ^ r0 ^ r5); + q[1] = q0 ^ q5 ^ r0 ^ r1 ^ r5 ^ r6 ^ r7 ^ rotr32(q1 ^ q5 ^ q7 ^ r1 ^ r5 ^ r6); + q[2] = q0 ^ q1 ^ q6 ^ r1 ^ r2 ^ r6 ^ r7 ^ rotr32(q0 ^ q2 ^ q6 ^ r2 ^ r6 ^ r7); + q[3] = q0 ^ q1 ^ q2 ^ q5 ^ q6 ^ r0 ^ r2 ^ r3 ^ r5 ^ rotr32(q0 ^ q1 ^ q3 ^ q5 ^ q6 ^ q7 ^ r0 ^ r3 ^ r5 ^ r7); + q[4] = q1 ^ q2 ^ q3 ^ q5 ^ r1 ^ r3 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr32(q1 ^ q2 ^ q4 ^ q5 ^ q7 ^ r1 ^ r4 ^ r5 ^ r6); + q[5] = q2 ^ q3 ^ q4 ^ q6 ^ r2 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr32(q2 ^ q3 ^ q5 ^ q6 ^ r2 ^ r5 ^ r6 ^ r7); + q[6] = q3 ^ q4 ^ q5 ^ q7 ^ r3 ^ r5 ^ r6 ^ r7 ^ rotr32(q3 ^ q4 ^ q6 ^ q7 ^ r3 ^ r6 ^ r7); + q[7] = q4 ^ q5 ^ q6 ^ r4 ^ r6 ^ r7 ^ rotr32(q4 ^ q5 ^ q7 ^ r4 ^ r7); +} + +/* see inner.h */ +void +br_aes_ct64_bitslice_decrypt(unsigned num_rounds, + const uint64_t *skey, uint64_t *q) +{ + unsigned u; + + add_round_key(q, skey + (num_rounds << 3)); + for (u = num_rounds - 1; u > 0; u --) { + inv_shift_rows(q); + br_aes_ct64_bitslice_invSbox(q); + add_round_key(q, skey + (u << 3)); + inv_mix_columns(q); + } + inv_shift_rows(q); + br_aes_ct64_bitslice_invSbox(q); + add_round_key(q, skey); +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_enc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_enc.c new file mode 100644 index 0000000..0f08eeb --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct64_enc.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static __inline void +add_round_key(uint64_t *q, const uint64_t *sk) +{ + q[0] ^= sk[0]; + q[1] ^= sk[1]; + q[2] ^= sk[2]; + q[3] ^= sk[3]; + q[4] ^= sk[4]; + q[5] ^= sk[5]; + q[6] ^= sk[6]; + q[7] ^= sk[7]; +} + +static __inline void +shift_rows(uint64_t *q) +{ + int i; + + for (i = 0; i < 8; i ++) { + uint64_t x; + + x = q[i]; + q[i] = (x & (uint64_t)0x000000000000FFFF) + | ((x & (uint64_t)0x00000000FFF00000) >> 4) + | ((x & (uint64_t)0x00000000000F0000) << 12) + | ((x & (uint64_t)0x0000FF0000000000) >> 8) + | ((x & (uint64_t)0x000000FF00000000) << 8) + | ((x & (uint64_t)0xF000000000000000) >> 12) + | ((x & (uint64_t)0x0FFF000000000000) << 4); + } +} + +static __inline uint64_t +rotr32(uint64_t x) +{ + return (x << 32) | (x >> 32); +} + +static __inline void +mix_columns(uint64_t *q) +{ + uint64_t q0, q1, q2, q3, q4, q5, q6, q7; + uint64_t r0, r1, r2, r3, r4, r5, r6, r7; + + q0 = q[0]; + q1 = q[1]; + q2 = q[2]; + q3 = q[3]; + q4 = q[4]; + q5 = q[5]; + q6 = q[6]; + q7 = q[7]; + r0 = (q0 >> 16) | (q0 << 48); + r1 = (q1 >> 16) | (q1 << 48); + r2 = (q2 >> 16) | (q2 << 48); + r3 = (q3 >> 16) | (q3 << 48); + r4 = (q4 >> 16) | (q4 << 48); + r5 = (q5 >> 16) | (q5 << 48); + r6 = (q6 >> 16) | (q6 << 48); + r7 = (q7 >> 16) | (q7 << 48); + + q[0] = q7 ^ r7 ^ r0 ^ rotr32(q0 ^ r0); + q[1] = q0 ^ r0 ^ q7 ^ r7 ^ r1 ^ rotr32(q1 ^ r1); + q[2] = q1 ^ r1 ^ r2 ^ rotr32(q2 ^ r2); + q[3] = q2 ^ r2 ^ q7 ^ r7 ^ r3 ^ rotr32(q3 ^ r3); + q[4] = q3 ^ r3 ^ q7 ^ r7 ^ r4 ^ rotr32(q4 ^ r4); + q[5] = q4 ^ r4 ^ r5 ^ rotr32(q5 ^ r5); + q[6] = q5 ^ r5 ^ r6 ^ rotr32(q6 ^ r6); + q[7] = q6 ^ r6 ^ r7 ^ rotr32(q7 ^ r7); +} + +/* see inner.h */ +void +br_aes_ct64_bitslice_encrypt(unsigned num_rounds, + const uint64_t *skey, uint64_t *q) +{ + unsigned u; + + add_round_key(q, skey); + for (u = 1; u < num_rounds; u ++) { + br_aes_ct64_bitslice_Sbox(q); + shift_rows(q); + mix_columns(q); + add_round_key(q, skey + (u << 3)); + } + br_aes_ct64_bitslice_Sbox(q); + shift_rows(q); + add_round_key(q, skey + (num_rounds << 3)); +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct_cbcdec.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct_cbcdec.c new file mode 100644 index 0000000..522645a --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct_cbcdec.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_ct_cbcdec_init(br_aes_ct_cbcdec_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_ct_cbcdec_vtable; + ctx->num_rounds = br_aes_ct_keysched(ctx->skey, key, len); +} + +/* see bearssl_block.h */ +void +br_aes_ct_cbcdec_run(const br_aes_ct_cbcdec_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf, *ivbuf; + uint32_t iv0, iv1, iv2, iv3; + uint32_t sk_exp[120]; + + br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + ivbuf = iv; + iv0 = br_dec32le(ivbuf); + iv1 = br_dec32le(ivbuf + 4); + iv2 = br_dec32le(ivbuf + 8); + iv3 = br_dec32le(ivbuf + 12); + buf = data; + while (len > 0) { + uint32_t q[8], sq[8]; + + q[0] = br_dec32le(buf); + q[2] = br_dec32le(buf + 4); + q[4] = br_dec32le(buf + 8); + q[6] = br_dec32le(buf + 12); + if (len >= 32) { + q[1] = br_dec32le(buf + 16); + q[3] = br_dec32le(buf + 20); + q[5] = br_dec32le(buf + 24); + q[7] = br_dec32le(buf + 28); + } else { + q[1] = 0; + q[3] = 0; + q[5] = 0; + q[7] = 0; + } + memcpy(sq, q, sizeof q); + br_aes_ct_ortho(q); + br_aes_ct_bitslice_decrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct_ortho(q); + br_enc32le(buf, q[0] ^ iv0); + br_enc32le(buf + 4, q[2] ^ iv1); + br_enc32le(buf + 8, q[4] ^ iv2); + br_enc32le(buf + 12, q[6] ^ iv3); + if (len < 32) { + iv0 = sq[0]; + iv1 = sq[2]; + iv2 = sq[4]; + iv3 = sq[6]; + break; + } + br_enc32le(buf + 16, q[1] ^ sq[0]); + br_enc32le(buf + 20, q[3] ^ sq[2]); + br_enc32le(buf + 24, q[5] ^ sq[4]); + br_enc32le(buf + 28, q[7] ^ sq[6]); + iv0 = sq[1]; + iv1 = sq[3]; + iv2 = sq[5]; + iv3 = sq[7]; + buf += 32; + len -= 32; + } + br_enc32le(ivbuf, iv0); + br_enc32le(ivbuf + 4, iv1); + br_enc32le(ivbuf + 8, iv2); + br_enc32le(ivbuf + 12, iv3); +} + +/* see bearssl_block.h */ +const br_block_cbcdec_class br_aes_ct_cbcdec_vtable = { + sizeof(br_aes_ct_cbcdec_keys), + 16, + 4, + (void (*)(const br_block_cbcdec_class **, const void *, size_t)) + &br_aes_ct_cbcdec_init, + (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) + &br_aes_ct_cbcdec_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct_cbcenc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct_cbcenc.c new file mode 100644 index 0000000..cb85977 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct_cbcenc.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_ct_cbcenc_init(br_aes_ct_cbcenc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_ct_cbcenc_vtable; + ctx->num_rounds = br_aes_ct_keysched(ctx->skey, key, len); +} + +/* see bearssl_block.h */ +void +br_aes_ct_cbcenc_run(const br_aes_ct_cbcenc_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf, *ivbuf; + uint32_t q[8]; + uint32_t iv0, iv1, iv2, iv3; + uint32_t sk_exp[120]; + + q[1] = 0; + q[3] = 0; + q[5] = 0; + q[7] = 0; + br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + ivbuf = iv; + iv0 = br_dec32le(ivbuf); + iv1 = br_dec32le(ivbuf + 4); + iv2 = br_dec32le(ivbuf + 8); + iv3 = br_dec32le(ivbuf + 12); + buf = data; + while (len > 0) { + q[0] = iv0 ^ br_dec32le(buf); + q[2] = iv1 ^ br_dec32le(buf + 4); + q[4] = iv2 ^ br_dec32le(buf + 8); + q[6] = iv3 ^ br_dec32le(buf + 12); + br_aes_ct_ortho(q); + br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct_ortho(q); + iv0 = q[0]; + iv1 = q[2]; + iv2 = q[4]; + iv3 = q[6]; + br_enc32le(buf, iv0); + br_enc32le(buf + 4, iv1); + br_enc32le(buf + 8, iv2); + br_enc32le(buf + 12, iv3); + buf += 16; + len -= 16; + } + br_enc32le(ivbuf, iv0); + br_enc32le(ivbuf + 4, iv1); + br_enc32le(ivbuf + 8, iv2); + br_enc32le(ivbuf + 12, iv3); +} + +/* see bearssl_block.h */ +const br_block_cbcenc_class br_aes_ct_cbcenc_vtable = { + sizeof(br_aes_ct_cbcenc_keys), + 16, + 4, + (void (*)(const br_block_cbcenc_class **, const void *, size_t)) + &br_aes_ct_cbcenc_init, + (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) + &br_aes_ct_cbcenc_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct_ctr.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct_ctr.c new file mode 100644 index 0000000..f407689 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct_ctr.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_ct_ctr_init(br_aes_ct_ctr_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_ct_ctr_vtable; + ctx->num_rounds = br_aes_ct_keysched(ctx->skey, key, len); +} + +static void +xorbuf(void *dst, const void *src, size_t len) +{ + unsigned char *d; + const unsigned char *s; + + d = dst; + s = src; + while (len -- > 0) { + *d ++ ^= *s ++; + } +} + +/* see bearssl_block.h */ +uint32_t +br_aes_ct_ctr_run(const br_aes_ct_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len) +{ + unsigned char *buf; + const unsigned char *ivbuf; + uint32_t iv0, iv1, iv2; + uint32_t sk_exp[120]; + + br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + ivbuf = iv; + iv0 = br_dec32le(ivbuf); + iv1 = br_dec32le(ivbuf + 4); + iv2 = br_dec32le(ivbuf + 8); + buf = data; + while (len > 0) { + uint32_t q[8]; + unsigned char tmp[32]; + + /* + * TODO: see if we can save on the first br_aes_ct_ortho() + * call, since iv0/iv1/iv2 are constant for the whole run. + */ + q[0] = q[1] = iv0; + q[2] = q[3] = iv1; + q[4] = q[5] = iv2; + q[6] = br_swap32(cc); + q[7] = br_swap32(cc + 1); + br_aes_ct_ortho(q); + br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct_ortho(q); + br_enc32le(tmp, q[0]); + br_enc32le(tmp + 4, q[2]); + br_enc32le(tmp + 8, q[4]); + br_enc32le(tmp + 12, q[6]); + br_enc32le(tmp + 16, q[1]); + br_enc32le(tmp + 20, q[3]); + br_enc32le(tmp + 24, q[5]); + br_enc32le(tmp + 28, q[7]); + + if (len <= 32) { + xorbuf(buf, tmp, len); + cc ++; + if (len > 16) { + cc ++; + } + break; + } + xorbuf(buf, tmp, 32); + buf += 32; + len -= 32; + cc += 2; + } + return cc; +} + +/* see bearssl_block.h */ +const br_block_ctr_class br_aes_ct_ctr_vtable = { + sizeof(br_aes_ct_ctr_keys), + 16, + 4, + (void (*)(const br_block_ctr_class **, const void *, size_t)) + &br_aes_ct_ctr_init, + (uint32_t (*)(const br_block_ctr_class *const *, + const void *, uint32_t, void *, size_t)) + &br_aes_ct_ctr_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct_ctrcbc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct_ctrcbc.c new file mode 100644 index 0000000..8ae9fc7 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct_ctrcbc.c @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_ct_ctrcbc_init(br_aes_ct_ctrcbc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_ct_ctrcbc_vtable; + ctx->num_rounds = br_aes_ct_keysched(ctx->skey, key, len); +} + +static void +xorbuf(void *dst, const void *src, size_t len) +{ + unsigned char *d; + const unsigned char *s; + + d = dst; + s = src; + while (len -- > 0) { + *d ++ ^= *s ++; + } +} + +/* see bearssl_block.h */ +void +br_aes_ct_ctrcbc_ctr(const br_aes_ct_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len) +{ + unsigned char *buf; + unsigned char *ivbuf; + uint32_t iv0, iv1, iv2, iv3; + uint32_t sk_exp[120]; + + br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + + /* + * We keep the counter as four 32-bit values, with big-endian + * convention, because that's what is expected for purposes of + * incrementing the counter value. + */ + ivbuf = ctr; + iv0 = br_dec32be(ivbuf + 0); + iv1 = br_dec32be(ivbuf + 4); + iv2 = br_dec32be(ivbuf + 8); + iv3 = br_dec32be(ivbuf + 12); + + buf = data; + while (len > 0) { + uint32_t q[8], carry; + unsigned char tmp[32]; + + /* + * The bitslice implementation expects values in + * little-endian convention, so we have to byteswap them. + */ + q[0] = br_swap32(iv0); + q[2] = br_swap32(iv1); + q[4] = br_swap32(iv2); + q[6] = br_swap32(iv3); + iv3 ++; + carry = ~(iv3 | -iv3) >> 31; + iv2 += carry; + carry &= -(~(iv2 | -iv2) >> 31); + iv1 += carry; + carry &= -(~(iv1 | -iv1) >> 31); + iv0 += carry; + q[1] = br_swap32(iv0); + q[3] = br_swap32(iv1); + q[5] = br_swap32(iv2); + q[7] = br_swap32(iv3); + if (len > 16) { + iv3 ++; + carry = ~(iv3 | -iv3) >> 31; + iv2 += carry; + carry &= -(~(iv2 | -iv2) >> 31); + iv1 += carry; + carry &= -(~(iv1 | -iv1) >> 31); + iv0 += carry; + } + + br_aes_ct_ortho(q); + br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct_ortho(q); + + br_enc32le(tmp, q[0]); + br_enc32le(tmp + 4, q[2]); + br_enc32le(tmp + 8, q[4]); + br_enc32le(tmp + 12, q[6]); + br_enc32le(tmp + 16, q[1]); + br_enc32le(tmp + 20, q[3]); + br_enc32le(tmp + 24, q[5]); + br_enc32le(tmp + 28, q[7]); + + if (len <= 32) { + xorbuf(buf, tmp, len); + break; + } + xorbuf(buf, tmp, 32); + buf += 32; + len -= 32; + } + br_enc32be(ivbuf + 0, iv0); + br_enc32be(ivbuf + 4, iv1); + br_enc32be(ivbuf + 8, iv2); + br_enc32be(ivbuf + 12, iv3); +} + +/* see bearssl_block.h */ +void +br_aes_ct_ctrcbc_mac(const br_aes_ct_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len) +{ + const unsigned char *buf; + uint32_t cm0, cm1, cm2, cm3; + uint32_t q[8]; + uint32_t sk_exp[120]; + + br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + + buf = data; + cm0 = br_dec32le((unsigned char *)cbcmac + 0); + cm1 = br_dec32le((unsigned char *)cbcmac + 4); + cm2 = br_dec32le((unsigned char *)cbcmac + 8); + cm3 = br_dec32le((unsigned char *)cbcmac + 12); + q[1] = 0; + q[3] = 0; + q[5] = 0; + q[7] = 0; + + while (len > 0) { + q[0] = cm0 ^ br_dec32le(buf + 0); + q[2] = cm1 ^ br_dec32le(buf + 4); + q[4] = cm2 ^ br_dec32le(buf + 8); + q[6] = cm3 ^ br_dec32le(buf + 12); + + br_aes_ct_ortho(q); + br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct_ortho(q); + + cm0 = q[0]; + cm1 = q[2]; + cm2 = q[4]; + cm3 = q[6]; + buf += 16; + len -= 16; + } + + br_enc32le((unsigned char *)cbcmac + 0, cm0); + br_enc32le((unsigned char *)cbcmac + 4, cm1); + br_enc32le((unsigned char *)cbcmac + 8, cm2); + br_enc32le((unsigned char *)cbcmac + 12, cm3); +} + +/* see bearssl_block.h */ +void +br_aes_ct_ctrcbc_encrypt(const br_aes_ct_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len) +{ + /* + * When encrypting, the CBC-MAC processing must be lagging by + * one block, since it operates on the encrypted values, so + * it must wait for that encryption to complete. + */ + + unsigned char *buf; + unsigned char *ivbuf; + uint32_t iv0, iv1, iv2, iv3; + uint32_t cm0, cm1, cm2, cm3; + uint32_t sk_exp[120]; + int first_iter; + + br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + + /* + * We keep the counter as four 32-bit values, with big-endian + * convention, because that's what is expected for purposes of + * incrementing the counter value. + */ + ivbuf = ctr; + iv0 = br_dec32be(ivbuf + 0); + iv1 = br_dec32be(ivbuf + 4); + iv2 = br_dec32be(ivbuf + 8); + iv3 = br_dec32be(ivbuf + 12); + + /* + * The current CBC-MAC value is kept in little-endian convention. + */ + cm0 = br_dec32le((unsigned char *)cbcmac + 0); + cm1 = br_dec32le((unsigned char *)cbcmac + 4); + cm2 = br_dec32le((unsigned char *)cbcmac + 8); + cm3 = br_dec32le((unsigned char *)cbcmac + 12); + + buf = data; + first_iter = 1; + while (len > 0) { + uint32_t q[8], carry; + + /* + * The bitslice implementation expects values in + * little-endian convention, so we have to byteswap them. + */ + q[0] = br_swap32(iv0); + q[2] = br_swap32(iv1); + q[4] = br_swap32(iv2); + q[6] = br_swap32(iv3); + iv3 ++; + carry = ~(iv3 | -iv3) >> 31; + iv2 += carry; + carry &= -(~(iv2 | -iv2) >> 31); + iv1 += carry; + carry &= -(~(iv1 | -iv1) >> 31); + iv0 += carry; + + /* + * The odd values are used for CBC-MAC. + */ + q[1] = cm0; + q[3] = cm1; + q[5] = cm2; + q[7] = cm3; + + br_aes_ct_ortho(q); + br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct_ortho(q); + + /* + * We do the XOR with the plaintext in 32-bit registers, + * so that the value are available for CBC-MAC processing + * as well. + */ + q[0] ^= br_dec32le(buf + 0); + q[2] ^= br_dec32le(buf + 4); + q[4] ^= br_dec32le(buf + 8); + q[6] ^= br_dec32le(buf + 12); + br_enc32le(buf + 0, q[0]); + br_enc32le(buf + 4, q[2]); + br_enc32le(buf + 8, q[4]); + br_enc32le(buf + 12, q[6]); + + buf += 16; + len -= 16; + + /* + * We set the cm* values to the block to encrypt in the + * next iteration. + */ + if (first_iter) { + first_iter = 0; + cm0 ^= q[0]; + cm1 ^= q[2]; + cm2 ^= q[4]; + cm3 ^= q[6]; + } else { + cm0 = q[0] ^ q[1]; + cm1 = q[2] ^ q[3]; + cm2 = q[4] ^ q[5]; + cm3 = q[6] ^ q[7]; + } + + /* + * If this was the last iteration, then compute the + * extra block encryption to complete CBC-MAC. + */ + if (len == 0) { + q[0] = cm0; + q[2] = cm1; + q[4] = cm2; + q[6] = cm3; + br_aes_ct_ortho(q); + br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct_ortho(q); + cm0 = q[0]; + cm1 = q[2]; + cm2 = q[4]; + cm3 = q[6]; + break; + } + } + + br_enc32be(ivbuf + 0, iv0); + br_enc32be(ivbuf + 4, iv1); + br_enc32be(ivbuf + 8, iv2); + br_enc32be(ivbuf + 12, iv3); + br_enc32le((unsigned char *)cbcmac + 0, cm0); + br_enc32le((unsigned char *)cbcmac + 4, cm1); + br_enc32le((unsigned char *)cbcmac + 8, cm2); + br_enc32le((unsigned char *)cbcmac + 12, cm3); +} + +/* see bearssl_block.h */ +void +br_aes_ct_ctrcbc_decrypt(const br_aes_ct_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len) +{ + unsigned char *buf; + unsigned char *ivbuf; + uint32_t iv0, iv1, iv2, iv3; + uint32_t cm0, cm1, cm2, cm3; + uint32_t sk_exp[120]; + + br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + + /* + * We keep the counter as four 32-bit values, with big-endian + * convention, because that's what is expected for purposes of + * incrementing the counter value. + */ + ivbuf = ctr; + iv0 = br_dec32be(ivbuf + 0); + iv1 = br_dec32be(ivbuf + 4); + iv2 = br_dec32be(ivbuf + 8); + iv3 = br_dec32be(ivbuf + 12); + + /* + * The current CBC-MAC value is kept in little-endian convention. + */ + cm0 = br_dec32le((unsigned char *)cbcmac + 0); + cm1 = br_dec32le((unsigned char *)cbcmac + 4); + cm2 = br_dec32le((unsigned char *)cbcmac + 8); + cm3 = br_dec32le((unsigned char *)cbcmac + 12); + + buf = data; + while (len > 0) { + uint32_t q[8], carry; + unsigned char tmp[16]; + + /* + * The bitslice implementation expects values in + * little-endian convention, so we have to byteswap them. + */ + q[0] = br_swap32(iv0); + q[2] = br_swap32(iv1); + q[4] = br_swap32(iv2); + q[6] = br_swap32(iv3); + iv3 ++; + carry = ~(iv3 | -iv3) >> 31; + iv2 += carry; + carry &= -(~(iv2 | -iv2) >> 31); + iv1 += carry; + carry &= -(~(iv1 | -iv1) >> 31); + iv0 += carry; + + /* + * The odd values are used for CBC-MAC. + */ + q[1] = cm0 ^ br_dec32le(buf + 0); + q[3] = cm1 ^ br_dec32le(buf + 4); + q[5] = cm2 ^ br_dec32le(buf + 8); + q[7] = cm3 ^ br_dec32le(buf + 12); + + br_aes_ct_ortho(q); + br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q); + br_aes_ct_ortho(q); + + br_enc32le(tmp + 0, q[0]); + br_enc32le(tmp + 4, q[2]); + br_enc32le(tmp + 8, q[4]); + br_enc32le(tmp + 12, q[6]); + xorbuf(buf, tmp, 16); + cm0 = q[1]; + cm1 = q[3]; + cm2 = q[5]; + cm3 = q[7]; + buf += 16; + len -= 16; + } + + br_enc32be(ivbuf + 0, iv0); + br_enc32be(ivbuf + 4, iv1); + br_enc32be(ivbuf + 8, iv2); + br_enc32be(ivbuf + 12, iv3); + br_enc32le((unsigned char *)cbcmac + 0, cm0); + br_enc32le((unsigned char *)cbcmac + 4, cm1); + br_enc32le((unsigned char *)cbcmac + 8, cm2); + br_enc32le((unsigned char *)cbcmac + 12, cm3); +} + +/* see bearssl_block.h */ +const br_block_ctrcbc_class br_aes_ct_ctrcbc_vtable = { + sizeof(br_aes_ct_ctrcbc_keys), + 16, + 4, + (void (*)(const br_block_ctrcbc_class **, const void *, size_t)) + &br_aes_ct_ctrcbc_init, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, void *, size_t)) + &br_aes_ct_ctrcbc_encrypt, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, void *, size_t)) + &br_aes_ct_ctrcbc_decrypt, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, size_t)) + &br_aes_ct_ctrcbc_ctr, + (void (*)(const br_block_ctrcbc_class *const *, + void *, const void *, size_t)) + &br_aes_ct_ctrcbc_mac +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct_dec.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct_dec.c new file mode 100644 index 0000000..d581b24 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct_dec.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_aes_ct_bitslice_invSbox(uint32_t *q) +{ + /* + * AES S-box is: + * S(x) = A(I(x)) ^ 0x63 + * where I() is inversion in GF(256), and A() is a linear + * transform (0 is formally defined to be its own inverse). + * Since inversion is an involution, the inverse S-box can be + * computed from the S-box as: + * iS(x) = B(S(B(x ^ 0x63)) ^ 0x63) + * where B() is the inverse of A(). Indeed, for any y in GF(256): + * iS(S(y)) = B(A(I(B(A(I(y)) ^ 0x63 ^ 0x63))) ^ 0x63 ^ 0x63) = y + * + * Note: we reuse the implementation of the forward S-box, + * instead of duplicating it here, so that total code size is + * lower. By merging the B() transforms into the S-box circuit + * we could make faster CBC decryption, but CBC decryption is + * already quite faster than CBC encryption because we can + * process two blocks in parallel. + */ + uint32_t q0, q1, q2, q3, q4, q5, q6, q7; + + q0 = ~q[0]; + q1 = ~q[1]; + q2 = q[2]; + q3 = q[3]; + q4 = q[4]; + q5 = ~q[5]; + q6 = ~q[6]; + q7 = q[7]; + q[7] = q1 ^ q4 ^ q6; + q[6] = q0 ^ q3 ^ q5; + q[5] = q7 ^ q2 ^ q4; + q[4] = q6 ^ q1 ^ q3; + q[3] = q5 ^ q0 ^ q2; + q[2] = q4 ^ q7 ^ q1; + q[1] = q3 ^ q6 ^ q0; + q[0] = q2 ^ q5 ^ q7; + + br_aes_ct_bitslice_Sbox(q); + + q0 = ~q[0]; + q1 = ~q[1]; + q2 = q[2]; + q3 = q[3]; + q4 = q[4]; + q5 = ~q[5]; + q6 = ~q[6]; + q7 = q[7]; + q[7] = q1 ^ q4 ^ q6; + q[6] = q0 ^ q3 ^ q5; + q[5] = q7 ^ q2 ^ q4; + q[4] = q6 ^ q1 ^ q3; + q[3] = q5 ^ q0 ^ q2; + q[2] = q4 ^ q7 ^ q1; + q[1] = q3 ^ q6 ^ q0; + q[0] = q2 ^ q5 ^ q7; +} + +static void +add_round_key(uint32_t *q, const uint32_t *sk) +{ + int i; + + for (i = 0; i < 8; i ++) { + q[i] ^= sk[i]; + } +} + +static void +inv_shift_rows(uint32_t *q) +{ + int i; + + for (i = 0; i < 8; i ++) { + uint32_t x; + + x = q[i]; + q[i] = (x & 0x000000FF) + | ((x & 0x00003F00) << 2) | ((x & 0x0000C000) >> 6) + | ((x & 0x000F0000) << 4) | ((x & 0x00F00000) >> 4) + | ((x & 0x03000000) << 6) | ((x & 0xFC000000) >> 2); + } +} + +static __inline uint32_t +rotr16(uint32_t x) +{ + return (x << 16) | (x >> 16); +} + +static void +inv_mix_columns(uint32_t *q) +{ + uint32_t q0, q1, q2, q3, q4, q5, q6, q7; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + + q0 = q[0]; + q1 = q[1]; + q2 = q[2]; + q3 = q[3]; + q4 = q[4]; + q5 = q[5]; + q6 = q[6]; + q7 = q[7]; + r0 = (q0 >> 8) | (q0 << 24); + r1 = (q1 >> 8) | (q1 << 24); + r2 = (q2 >> 8) | (q2 << 24); + r3 = (q3 >> 8) | (q3 << 24); + r4 = (q4 >> 8) | (q4 << 24); + r5 = (q5 >> 8) | (q5 << 24); + r6 = (q6 >> 8) | (q6 << 24); + r7 = (q7 >> 8) | (q7 << 24); + + q[0] = q5 ^ q6 ^ q7 ^ r0 ^ r5 ^ r7 ^ rotr16(q0 ^ q5 ^ q6 ^ r0 ^ r5); + q[1] = q0 ^ q5 ^ r0 ^ r1 ^ r5 ^ r6 ^ r7 ^ rotr16(q1 ^ q5 ^ q7 ^ r1 ^ r5 ^ r6); + q[2] = q0 ^ q1 ^ q6 ^ r1 ^ r2 ^ r6 ^ r7 ^ rotr16(q0 ^ q2 ^ q6 ^ r2 ^ r6 ^ r7); + q[3] = q0 ^ q1 ^ q2 ^ q5 ^ q6 ^ r0 ^ r2 ^ r3 ^ r5 ^ rotr16(q0 ^ q1 ^ q3 ^ q5 ^ q6 ^ q7 ^ r0 ^ r3 ^ r5 ^ r7); + q[4] = q1 ^ q2 ^ q3 ^ q5 ^ r1 ^ r3 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr16(q1 ^ q2 ^ q4 ^ q5 ^ q7 ^ r1 ^ r4 ^ r5 ^ r6); + q[5] = q2 ^ q3 ^ q4 ^ q6 ^ r2 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr16(q2 ^ q3 ^ q5 ^ q6 ^ r2 ^ r5 ^ r6 ^ r7); + q[6] = q3 ^ q4 ^ q5 ^ q7 ^ r3 ^ r5 ^ r6 ^ r7 ^ rotr16(q3 ^ q4 ^ q6 ^ q7 ^ r3 ^ r6 ^ r7); + q[7] = q4 ^ q5 ^ q6 ^ r4 ^ r6 ^ r7 ^ rotr16(q4 ^ q5 ^ q7 ^ r4 ^ r7); +} + +/* see inner.h */ +void +br_aes_ct_bitslice_decrypt(unsigned num_rounds, + const uint32_t *skey, uint32_t *q) +{ + unsigned u; + + add_round_key(q, skey + (num_rounds << 3)); + for (u = num_rounds - 1; u > 0; u --) { + inv_shift_rows(q); + br_aes_ct_bitslice_invSbox(q); + add_round_key(q, skey + (u << 3)); + inv_mix_columns(q); + } + inv_shift_rows(q); + br_aes_ct_bitslice_invSbox(q); + add_round_key(q, skey); +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_ct_enc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_ct_enc.c new file mode 100644 index 0000000..b0b8cc7 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_ct_enc.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +static __inline void +add_round_key(uint32_t *q, const uint32_t *sk) +{ + q[0] ^= sk[0]; + q[1] ^= sk[1]; + q[2] ^= sk[2]; + q[3] ^= sk[3]; + q[4] ^= sk[4]; + q[5] ^= sk[5]; + q[6] ^= sk[6]; + q[7] ^= sk[7]; +} + +static __inline void +shift_rows(uint32_t *q) +{ + int i; + + for (i = 0; i < 8; i ++) { + uint32_t x; + + x = q[i]; + q[i] = (x & 0x000000FF) + | ((x & 0x0000FC00) >> 2) | ((x & 0x00000300) << 6) + | ((x & 0x00F00000) >> 4) | ((x & 0x000F0000) << 4) + | ((x & 0xC0000000) >> 6) | ((x & 0x3F000000) << 2); + } +} + +static __inline uint32_t +rotr16(uint32_t x) +{ + return (x << 16) | (x >> 16); +} + +static __inline void +mix_columns(uint32_t *q) +{ + uint32_t q0, q1, q2, q3, q4, q5, q6, q7; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7; + + q0 = q[0]; + q1 = q[1]; + q2 = q[2]; + q3 = q[3]; + q4 = q[4]; + q5 = q[5]; + q6 = q[6]; + q7 = q[7]; + r0 = (q0 >> 8) | (q0 << 24); + r1 = (q1 >> 8) | (q1 << 24); + r2 = (q2 >> 8) | (q2 << 24); + r3 = (q3 >> 8) | (q3 << 24); + r4 = (q4 >> 8) | (q4 << 24); + r5 = (q5 >> 8) | (q5 << 24); + r6 = (q6 >> 8) | (q6 << 24); + r7 = (q7 >> 8) | (q7 << 24); + + q[0] = q7 ^ r7 ^ r0 ^ rotr16(q0 ^ r0); + q[1] = q0 ^ r0 ^ q7 ^ r7 ^ r1 ^ rotr16(q1 ^ r1); + q[2] = q1 ^ r1 ^ r2 ^ rotr16(q2 ^ r2); + q[3] = q2 ^ r2 ^ q7 ^ r7 ^ r3 ^ rotr16(q3 ^ r3); + q[4] = q3 ^ r3 ^ q7 ^ r7 ^ r4 ^ rotr16(q4 ^ r4); + q[5] = q4 ^ r4 ^ r5 ^ rotr16(q5 ^ r5); + q[6] = q5 ^ r5 ^ r6 ^ rotr16(q6 ^ r6); + q[7] = q6 ^ r6 ^ r7 ^ rotr16(q7 ^ r7); +} + +/* see inner.h */ +void +br_aes_ct_bitslice_encrypt(unsigned num_rounds, + const uint32_t *skey, uint32_t *q) +{ + unsigned u; + + add_round_key(q, skey); + for (u = 1; u < num_rounds; u ++) { + br_aes_ct_bitslice_Sbox(q); + shift_rows(q); + mix_columns(q); + add_round_key(q, skey + (u << 3)); + } + br_aes_ct_bitslice_Sbox(q); + shift_rows(q); + add_round_key(q, skey + (num_rounds << 3)); +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8.c b/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8.c new file mode 100644 index 0000000..b2c63c3 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8.c @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_POWER_ASM_MACROS 1 +#include "inner.h" + +/* + * This code contains the AES key schedule implementation using the + * POWER8 opcodes. + */ + +#if BR_POWER8 + +static void +key_schedule_128(unsigned char *sk, const unsigned char *key) +{ + long cc; + + static const uint32_t fmod[] = { 0x11B, 0x11B, 0x11B, 0x11B }; +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + + cc = 0; + + /* + * We use the VSX instructions for loading and storing the + * key/subkeys, since they support unaligned accesses. The rest + * of the computation is VMX only. VMX register 0 is VSX + * register 32. + */ + asm volatile ( + + /* + * v0 = all-zero word + * v1 = constant -8 / +8, copied into four words + * v2 = current subkey + * v3 = Rcon (x4 words) + * v6 = constant 8, copied into four words + * v7 = constant 0x11B, copied into four words + * v8 = constant for byteswapping words + */ + vspltisw(0, 0) +#if BR_POWER8_LE + vspltisw(1, -8) +#else + vspltisw(1, 8) +#endif + lxvw4x(34, 0, %[key]) + vspltisw(3, 1) + vspltisw(6, 8) + lxvw4x(39, 0, %[fmod]) +#if BR_POWER8_LE + lxvw4x(40, 0, %[idx2be]) +#endif + + /* + * First subkey is a copy of the key itself. + */ +#if BR_POWER8_LE + vperm(4, 2, 2, 8) + stxvw4x(36, 0, %[sk]) +#else + stxvw4x(34, 0, %[sk]) +#endif + + /* + * Loop must run 10 times. + */ + li(%[cc], 10) + mtctr(%[cc]) + label(loop) + /* Increment subkey address */ + addi(%[sk], %[sk], 16) + + /* Compute SubWord(RotWord(temp)) xor Rcon (into v4, splat) */ + vrlw(4, 2, 1) + vsbox(4, 4) +#if BR_POWER8_LE + vxor(4, 4, 3) +#else + vsldoi(5, 3, 0, 3) + vxor(4, 4, 5) +#endif + vspltw(4, 4, 3) + + /* XOR words for next subkey */ + vsldoi(5, 0, 2, 12) + vxor(2, 2, 5) + vsldoi(5, 0, 2, 12) + vxor(2, 2, 5) + vsldoi(5, 0, 2, 12) + vxor(2, 2, 5) + vxor(2, 2, 4) + + /* Store next subkey */ +#if BR_POWER8_LE + vperm(4, 2, 2, 8) + stxvw4x(36, 0, %[sk]) +#else + stxvw4x(34, 0, %[sk]) +#endif + + /* Update Rcon */ + vadduwm(3, 3, 3) + vsrw(4, 3, 6) + vsubuwm(4, 0, 4) + vand(4, 4, 7) + vxor(3, 3, 4) + + bdnz(loop) + +: [sk] "+b" (sk), [cc] "+b" (cc) +: [key] "b" (key), [fmod] "b" (fmod) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "ctr", "memory" + ); +} + +static void +key_schedule_192(unsigned char *sk, const unsigned char *key) +{ + long cc; + +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + + cc = 0; + + /* + * We use the VSX instructions for loading and storing the + * key/subkeys, since they support unaligned accesses. The rest + * of the computation is VMX only. VMX register 0 is VSX + * register 32. + */ + asm volatile ( + + /* + * v0 = all-zero word + * v1 = constant -8 / +8, copied into four words + * v2, v3 = current subkey + * v5 = Rcon (x4 words) (already shifted on big-endian) + * v6 = constant 8, copied into four words + * v8 = constant for byteswapping words + * + * The left two words of v3 are ignored. + */ + vspltisw(0, 0) +#if BR_POWER8_LE + vspltisw(1, -8) +#else + vspltisw(1, 8) +#endif + li(%[cc], 8) + lxvw4x(34, 0, %[key]) + lxvw4x(35, %[cc], %[key]) + vsldoi(3, 3, 0, 8) + vspltisw(5, 1) +#if !BR_POWER8_LE + vsldoi(5, 5, 0, 3) +#endif + vspltisw(6, 8) +#if BR_POWER8_LE + lxvw4x(40, 0, %[idx2be]) +#endif + + /* + * Loop must run 8 times. Each iteration produces 256 + * bits of subkeys, with a 64-bit overlap. + */ + li(%[cc], 8) + mtctr(%[cc]) + li(%[cc], 16) + label(loop) + + /* + * Last 6 words in v2:v3l. Compute next 6 words into + * v3r:v4. + */ + vrlw(10, 3, 1) + vsbox(10, 10) + vxor(10, 10, 5) + vspltw(10, 10, 1) + vsldoi(11, 0, 10, 8) + + vsldoi(12, 0, 2, 12) + vxor(12, 2, 12) + vsldoi(13, 0, 12, 12) + vxor(12, 12, 13) + vsldoi(13, 0, 12, 12) + vxor(12, 12, 13) + + vspltw(13, 12, 3) + vxor(13, 13, 3) + vsldoi(14, 0, 3, 12) + vxor(13, 13, 14) + + vsldoi(4, 12, 13, 8) + vsldoi(14, 0, 3, 8) + vsldoi(3, 14, 12, 8) + + vxor(3, 3, 11) + vxor(4, 4, 10) + + /* + * Update Rcon. Since for a 192-bit key, we use only 8 + * such constants, we will not hit the field modulus, + * so a simple shift (addition) works well. + */ + vadduwm(5, 5, 5) + + /* + * Write out the two left 128-bit words + */ +#if BR_POWER8_LE + vperm(10, 2, 2, 8) + vperm(11, 3, 3, 8) + stxvw4x(42, 0, %[sk]) + stxvw4x(43, %[cc], %[sk]) +#else + stxvw4x(34, 0, %[sk]) + stxvw4x(35, %[cc], %[sk]) +#endif + addi(%[sk], %[sk], 24) + + /* + * Shift words for next iteration. + */ + vsldoi(2, 3, 4, 8) + vsldoi(3, 4, 0, 8) + + bdnz(loop) + + /* + * The loop wrote the first 50 subkey words, but we need + * to produce 52, so we must do one last write. + */ +#if BR_POWER8_LE + vperm(10, 2, 2, 8) + stxvw4x(42, 0, %[sk]) +#else + stxvw4x(34, 0, %[sk]) +#endif + +: [sk] "+b" (sk), [cc] "+b" (cc) +: [key] "b" (key) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", "v12", "v13", "v14", "ctr", "memory" + ); +} + +static void +key_schedule_256(unsigned char *sk, const unsigned char *key) +{ + long cc; + +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + + cc = 0; + + /* + * We use the VSX instructions for loading and storing the + * key/subkeys, since they support unaligned accesses. The rest + * of the computation is VMX only. VMX register 0 is VSX + * register 32. + */ + asm volatile ( + + /* + * v0 = all-zero word + * v1 = constant -8 / +8, copied into four words + * v2, v3 = current subkey + * v6 = Rcon (x4 words) (already shifted on big-endian) + * v7 = constant 8, copied into four words + * v8 = constant for byteswapping words + * + * The left two words of v3 are ignored. + */ + vspltisw(0, 0) +#if BR_POWER8_LE + vspltisw(1, -8) +#else + vspltisw(1, 8) +#endif + li(%[cc], 16) + lxvw4x(34, 0, %[key]) + lxvw4x(35, %[cc], %[key]) + vspltisw(6, 1) +#if !BR_POWER8_LE + vsldoi(6, 6, 0, 3) +#endif + vspltisw(7, 8) +#if BR_POWER8_LE + lxvw4x(40, 0, %[idx2be]) +#endif + + /* + * Loop must run 7 times. Each iteration produces two + * subkeys. + */ + li(%[cc], 7) + mtctr(%[cc]) + li(%[cc], 16) + label(loop) + + /* + * Current words are in v2:v3. Compute next word in v4. + */ + vrlw(10, 3, 1) + vsbox(10, 10) + vxor(10, 10, 6) + vspltw(10, 10, 3) + + vsldoi(4, 0, 2, 12) + vxor(4, 2, 4) + vsldoi(5, 0, 4, 12) + vxor(4, 4, 5) + vsldoi(5, 0, 4, 12) + vxor(4, 4, 5) + vxor(4, 4, 10) + + /* + * Then other word in v5. + */ + vsbox(10, 4) + vspltw(10, 10, 3) + + vsldoi(5, 0, 3, 12) + vxor(5, 3, 5) + vsldoi(11, 0, 5, 12) + vxor(5, 5, 11) + vsldoi(11, 0, 5, 12) + vxor(5, 5, 11) + vxor(5, 5, 10) + + /* + * Update Rcon. Since for a 256-bit key, we use only 7 + * such constants, we will not hit the field modulus, + * so a simple shift (addition) works well. + */ + vadduwm(6, 6, 6) + + /* + * Write out the two left 128-bit words + */ +#if BR_POWER8_LE + vperm(10, 2, 2, 8) + vperm(11, 3, 3, 8) + stxvw4x(42, 0, %[sk]) + stxvw4x(43, %[cc], %[sk]) +#else + stxvw4x(34, 0, %[sk]) + stxvw4x(35, %[cc], %[sk]) +#endif + addi(%[sk], %[sk], 32) + + /* + * Replace v2:v3 with v4:v5. + */ + vxor(2, 0, 4) + vxor(3, 0, 5) + + bdnz(loop) + + /* + * The loop wrote the first 14 subkeys, but we need 15, + * so we must do an extra write. + */ +#if BR_POWER8_LE + vperm(10, 2, 2, 8) + stxvw4x(42, 0, %[sk]) +#else + stxvw4x(34, 0, %[sk]) +#endif + +: [sk] "+b" (sk), [cc] "+b" (cc) +: [key] "b" (key) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", "v12", "v13", "v14", "ctr", "memory" + ); +} + +/* see inner.h */ +int +br_aes_pwr8_supported(void) +{ + return 1; +} + +/* see inner.h */ +unsigned +br_aes_pwr8_keysched(unsigned char *sk, const void *key, size_t len) +{ + switch (len) { + case 16: + key_schedule_128(sk, key); + return 10; + case 24: + key_schedule_192(sk, key); + return 12; + default: + key_schedule_256(sk, key); + return 14; + } +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8_cbcdec.c b/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8_cbcdec.c new file mode 100644 index 0000000..e535ba6 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8_cbcdec.c @@ -0,0 +1,670 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_POWER_ASM_MACROS 1 +#include "inner.h" + +#if BR_POWER8 + +/* see bearssl_block.h */ +void +br_aes_pwr8_cbcdec_init(br_aes_pwr8_cbcdec_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_pwr8_cbcdec_vtable; + ctx->num_rounds = br_aes_pwr8_keysched(ctx->skey.skni, key, len); +} + +static void +cbcdec_128(const unsigned char *sk, + const unsigned char *iv, unsigned char *buf, size_t num_blocks) +{ + long cc0, cc1, cc2, cc3; + +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + + cc0 = 0; + cc1 = 16; + cc2 = 32; + cc3 = 48; + asm volatile ( + + /* + * Load subkeys into v0..v10 + */ + lxvw4x(32, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(33, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(34, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(35, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(36, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(37, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(38, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(39, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(40, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(41, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(42, %[cc0], %[sk]) + li(%[cc0], 0) + +#if BR_POWER8_LE + /* + * v15 = constant for byteswapping words + */ + lxvw4x(47, 0, %[idx2be]) +#endif + /* + * Load IV into v24. + */ + lxvw4x(56, 0, %[iv]) +#if BR_POWER8_LE + vperm(24, 24, 24, 15) +#endif + + mtctr(%[num_blocks]) + label(loop) + /* + * Load next ciphertext words in v16..v19. Also save them + * in v20..v23. + */ + lxvw4x(48, %[cc0], %[buf]) + lxvw4x(49, %[cc1], %[buf]) + lxvw4x(50, %[cc2], %[buf]) + lxvw4x(51, %[cc3], %[buf]) +#if BR_POWER8_LE + vperm(16, 16, 16, 15) + vperm(17, 17, 17, 15) + vperm(18, 18, 18, 15) + vperm(19, 19, 19, 15) +#endif + vand(20, 16, 16) + vand(21, 17, 17) + vand(22, 18, 18) + vand(23, 19, 19) + + /* + * Decrypt the blocks. + */ + vxor(16, 16, 10) + vxor(17, 17, 10) + vxor(18, 18, 10) + vxor(19, 19, 10) + vncipher(16, 16, 9) + vncipher(17, 17, 9) + vncipher(18, 18, 9) + vncipher(19, 19, 9) + vncipher(16, 16, 8) + vncipher(17, 17, 8) + vncipher(18, 18, 8) + vncipher(19, 19, 8) + vncipher(16, 16, 7) + vncipher(17, 17, 7) + vncipher(18, 18, 7) + vncipher(19, 19, 7) + vncipher(16, 16, 6) + vncipher(17, 17, 6) + vncipher(18, 18, 6) + vncipher(19, 19, 6) + vncipher(16, 16, 5) + vncipher(17, 17, 5) + vncipher(18, 18, 5) + vncipher(19, 19, 5) + vncipher(16, 16, 4) + vncipher(17, 17, 4) + vncipher(18, 18, 4) + vncipher(19, 19, 4) + vncipher(16, 16, 3) + vncipher(17, 17, 3) + vncipher(18, 18, 3) + vncipher(19, 19, 3) + vncipher(16, 16, 2) + vncipher(17, 17, 2) + vncipher(18, 18, 2) + vncipher(19, 19, 2) + vncipher(16, 16, 1) + vncipher(17, 17, 1) + vncipher(18, 18, 1) + vncipher(19, 19, 1) + vncipherlast(16, 16, 0) + vncipherlast(17, 17, 0) + vncipherlast(18, 18, 0) + vncipherlast(19, 19, 0) + + /* + * XOR decrypted blocks with IV / previous block. + */ + vxor(16, 16, 24) + vxor(17, 17, 20) + vxor(18, 18, 21) + vxor(19, 19, 22) + + /* + * Store back result (with byteswap) + */ +#if BR_POWER8_LE + vperm(16, 16, 16, 15) + vperm(17, 17, 17, 15) + vperm(18, 18, 18, 15) + vperm(19, 19, 19, 15) +#endif + stxvw4x(48, %[cc0], %[buf]) + stxvw4x(49, %[cc1], %[buf]) + stxvw4x(50, %[cc2], %[buf]) + stxvw4x(51, %[cc3], %[buf]) + + /* + * Fourth encrypted block is IV for next run. + */ + vand(24, 23, 23) + + addi(%[buf], %[buf], 64) + + bdnz(loop) + +: [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), + [buf] "+b" (buf) +: [sk] "b" (sk), [iv] "b" (iv), [num_blocks] "b" (num_blocks >> 2) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", + "ctr", "memory" + ); +} + +static void +cbcdec_192(const unsigned char *sk, + const unsigned char *iv, unsigned char *buf, size_t num_blocks) +{ + long cc0, cc1, cc2, cc3; + +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + + cc0 = 0; + cc1 = 16; + cc2 = 32; + cc3 = 48; + asm volatile ( + + /* + * Load subkeys into v0..v12 + */ + lxvw4x(32, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(33, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(34, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(35, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(36, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(37, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(38, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(39, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(40, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(41, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(42, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(43, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(44, %[cc0], %[sk]) + li(%[cc0], 0) + +#if BR_POWER8_LE + /* + * v15 = constant for byteswapping words + */ + lxvw4x(47, 0, %[idx2be]) +#endif + /* + * Load IV into v24. + */ + lxvw4x(56, 0, %[iv]) +#if BR_POWER8_LE + vperm(24, 24, 24, 15) +#endif + + mtctr(%[num_blocks]) + label(loop) + /* + * Load next ciphertext words in v16..v19. Also save them + * in v20..v23. + */ + lxvw4x(48, %[cc0], %[buf]) + lxvw4x(49, %[cc1], %[buf]) + lxvw4x(50, %[cc2], %[buf]) + lxvw4x(51, %[cc3], %[buf]) +#if BR_POWER8_LE + vperm(16, 16, 16, 15) + vperm(17, 17, 17, 15) + vperm(18, 18, 18, 15) + vperm(19, 19, 19, 15) +#endif + vand(20, 16, 16) + vand(21, 17, 17) + vand(22, 18, 18) + vand(23, 19, 19) + + /* + * Decrypt the blocks. + */ + vxor(16, 16, 12) + vxor(17, 17, 12) + vxor(18, 18, 12) + vxor(19, 19, 12) + vncipher(16, 16, 11) + vncipher(17, 17, 11) + vncipher(18, 18, 11) + vncipher(19, 19, 11) + vncipher(16, 16, 10) + vncipher(17, 17, 10) + vncipher(18, 18, 10) + vncipher(19, 19, 10) + vncipher(16, 16, 9) + vncipher(17, 17, 9) + vncipher(18, 18, 9) + vncipher(19, 19, 9) + vncipher(16, 16, 8) + vncipher(17, 17, 8) + vncipher(18, 18, 8) + vncipher(19, 19, 8) + vncipher(16, 16, 7) + vncipher(17, 17, 7) + vncipher(18, 18, 7) + vncipher(19, 19, 7) + vncipher(16, 16, 6) + vncipher(17, 17, 6) + vncipher(18, 18, 6) + vncipher(19, 19, 6) + vncipher(16, 16, 5) + vncipher(17, 17, 5) + vncipher(18, 18, 5) + vncipher(19, 19, 5) + vncipher(16, 16, 4) + vncipher(17, 17, 4) + vncipher(18, 18, 4) + vncipher(19, 19, 4) + vncipher(16, 16, 3) + vncipher(17, 17, 3) + vncipher(18, 18, 3) + vncipher(19, 19, 3) + vncipher(16, 16, 2) + vncipher(17, 17, 2) + vncipher(18, 18, 2) + vncipher(19, 19, 2) + vncipher(16, 16, 1) + vncipher(17, 17, 1) + vncipher(18, 18, 1) + vncipher(19, 19, 1) + vncipherlast(16, 16, 0) + vncipherlast(17, 17, 0) + vncipherlast(18, 18, 0) + vncipherlast(19, 19, 0) + + /* + * XOR decrypted blocks with IV / previous block. + */ + vxor(16, 16, 24) + vxor(17, 17, 20) + vxor(18, 18, 21) + vxor(19, 19, 22) + + /* + * Store back result (with byteswap) + */ +#if BR_POWER8_LE + vperm(16, 16, 16, 15) + vperm(17, 17, 17, 15) + vperm(18, 18, 18, 15) + vperm(19, 19, 19, 15) +#endif + stxvw4x(48, %[cc0], %[buf]) + stxvw4x(49, %[cc1], %[buf]) + stxvw4x(50, %[cc2], %[buf]) + stxvw4x(51, %[cc3], %[buf]) + + /* + * Fourth encrypted block is IV for next run. + */ + vand(24, 23, 23) + + addi(%[buf], %[buf], 64) + + bdnz(loop) + +: [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), + [buf] "+b" (buf) +: [sk] "b" (sk), [iv] "b" (iv), [num_blocks] "b" (num_blocks >> 2) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", + "ctr", "memory" + ); +} + +static void +cbcdec_256(const unsigned char *sk, + const unsigned char *iv, unsigned char *buf, size_t num_blocks) +{ + long cc0, cc1, cc2, cc3; + +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + + cc0 = 0; + cc1 = 16; + cc2 = 32; + cc3 = 48; + asm volatile ( + + /* + * Load subkeys into v0..v14 + */ + lxvw4x(32, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(33, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(34, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(35, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(36, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(37, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(38, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(39, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(40, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(41, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(42, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(43, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(44, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(45, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(46, %[cc0], %[sk]) + li(%[cc0], 0) + +#if BR_POWER8_LE + /* + * v15 = constant for byteswapping words + */ + lxvw4x(47, 0, %[idx2be]) +#endif + /* + * Load IV into v24. + */ + lxvw4x(56, 0, %[iv]) +#if BR_POWER8_LE + vperm(24, 24, 24, 15) +#endif + + mtctr(%[num_blocks]) + label(loop) + /* + * Load next ciphertext words in v16..v19. Also save them + * in v20..v23. + */ + lxvw4x(48, %[cc0], %[buf]) + lxvw4x(49, %[cc1], %[buf]) + lxvw4x(50, %[cc2], %[buf]) + lxvw4x(51, %[cc3], %[buf]) +#if BR_POWER8_LE + vperm(16, 16, 16, 15) + vperm(17, 17, 17, 15) + vperm(18, 18, 18, 15) + vperm(19, 19, 19, 15) +#endif + vand(20, 16, 16) + vand(21, 17, 17) + vand(22, 18, 18) + vand(23, 19, 19) + + /* + * Decrypt the blocks. + */ + vxor(16, 16, 14) + vxor(17, 17, 14) + vxor(18, 18, 14) + vxor(19, 19, 14) + vncipher(16, 16, 13) + vncipher(17, 17, 13) + vncipher(18, 18, 13) + vncipher(19, 19, 13) + vncipher(16, 16, 12) + vncipher(17, 17, 12) + vncipher(18, 18, 12) + vncipher(19, 19, 12) + vncipher(16, 16, 11) + vncipher(17, 17, 11) + vncipher(18, 18, 11) + vncipher(19, 19, 11) + vncipher(16, 16, 10) + vncipher(17, 17, 10) + vncipher(18, 18, 10) + vncipher(19, 19, 10) + vncipher(16, 16, 9) + vncipher(17, 17, 9) + vncipher(18, 18, 9) + vncipher(19, 19, 9) + vncipher(16, 16, 8) + vncipher(17, 17, 8) + vncipher(18, 18, 8) + vncipher(19, 19, 8) + vncipher(16, 16, 7) + vncipher(17, 17, 7) + vncipher(18, 18, 7) + vncipher(19, 19, 7) + vncipher(16, 16, 6) + vncipher(17, 17, 6) + vncipher(18, 18, 6) + vncipher(19, 19, 6) + vncipher(16, 16, 5) + vncipher(17, 17, 5) + vncipher(18, 18, 5) + vncipher(19, 19, 5) + vncipher(16, 16, 4) + vncipher(17, 17, 4) + vncipher(18, 18, 4) + vncipher(19, 19, 4) + vncipher(16, 16, 3) + vncipher(17, 17, 3) + vncipher(18, 18, 3) + vncipher(19, 19, 3) + vncipher(16, 16, 2) + vncipher(17, 17, 2) + vncipher(18, 18, 2) + vncipher(19, 19, 2) + vncipher(16, 16, 1) + vncipher(17, 17, 1) + vncipher(18, 18, 1) + vncipher(19, 19, 1) + vncipherlast(16, 16, 0) + vncipherlast(17, 17, 0) + vncipherlast(18, 18, 0) + vncipherlast(19, 19, 0) + + /* + * XOR decrypted blocks with IV / previous block. + */ + vxor(16, 16, 24) + vxor(17, 17, 20) + vxor(18, 18, 21) + vxor(19, 19, 22) + + /* + * Store back result (with byteswap) + */ +#if BR_POWER8_LE + vperm(16, 16, 16, 15) + vperm(17, 17, 17, 15) + vperm(18, 18, 18, 15) + vperm(19, 19, 19, 15) +#endif + stxvw4x(48, %[cc0], %[buf]) + stxvw4x(49, %[cc1], %[buf]) + stxvw4x(50, %[cc2], %[buf]) + stxvw4x(51, %[cc3], %[buf]) + + /* + * Fourth encrypted block is IV for next run. + */ + vand(24, 23, 23) + + addi(%[buf], %[buf], 64) + + bdnz(loop) + +: [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), + [buf] "+b" (buf) +: [sk] "b" (sk), [iv] "b" (iv), [num_blocks] "b" (num_blocks >> 2) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", + "ctr", "memory" + ); +} + +/* see bearssl_block.h */ +void +br_aes_pwr8_cbcdec_run(const br_aes_pwr8_cbcdec_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char nextiv[16]; + unsigned char *buf; + + if (len == 0) { + return; + } + buf = data; + memcpy(nextiv, buf + len - 16, 16); + if (len >= 64) { + size_t num_blocks; + unsigned char tmp[16]; + + num_blocks = (len >> 4) & ~(size_t)3; + memcpy(tmp, buf + (num_blocks << 4) - 16, 16); + switch (ctx->num_rounds) { + case 10: + cbcdec_128(ctx->skey.skni, iv, buf, num_blocks); + break; + case 12: + cbcdec_192(ctx->skey.skni, iv, buf, num_blocks); + break; + default: + cbcdec_256(ctx->skey.skni, iv, buf, num_blocks); + break; + } + buf += num_blocks << 4; + len &= 63; + memcpy(iv, tmp, 16); + } + if (len > 0) { + unsigned char tmp[64]; + + memcpy(tmp, buf, len); + memset(tmp + len, 0, (sizeof tmp) - len); + switch (ctx->num_rounds) { + case 10: + cbcdec_128(ctx->skey.skni, iv, tmp, 4); + break; + case 12: + cbcdec_192(ctx->skey.skni, iv, tmp, 4); + break; + default: + cbcdec_256(ctx->skey.skni, iv, tmp, 4); + break; + } + memcpy(buf, tmp, len); + } + memcpy(iv, nextiv, 16); +} + +/* see bearssl_block.h */ +const br_block_cbcdec_class br_aes_pwr8_cbcdec_vtable = { + sizeof(br_aes_pwr8_cbcdec_keys), + 16, + 4, + (void (*)(const br_block_cbcdec_class **, const void *, size_t)) + &br_aes_pwr8_cbcdec_init, + (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) + &br_aes_pwr8_cbcdec_run +}; + +/* see bearssl_block.h */ +const br_block_cbcdec_class * +br_aes_pwr8_cbcdec_get_vtable(void) +{ + return br_aes_pwr8_supported() ? &br_aes_pwr8_cbcdec_vtable : NULL; +} + +#else + +/* see bearssl_block.h */ +const br_block_cbcdec_class * +br_aes_pwr8_cbcdec_get_vtable(void) +{ + return NULL; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8_cbcenc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8_cbcenc.c new file mode 100644 index 0000000..00f8eca --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8_cbcenc.c @@ -0,0 +1,417 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_POWER_ASM_MACROS 1 +#include "inner.h" + +#if BR_POWER8 + +/* see bearssl_block.h */ +void +br_aes_pwr8_cbcenc_init(br_aes_pwr8_cbcenc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_pwr8_cbcenc_vtable; + ctx->num_rounds = br_aes_pwr8_keysched(ctx->skey.skni, key, len); +} + +static void +cbcenc_128(const unsigned char *sk, + const unsigned char *iv, unsigned char *buf, size_t len) +{ + long cc; + +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + + cc = 0; + asm volatile ( + + /* + * Load subkeys into v0..v10 + */ + lxvw4x(32, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(33, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(34, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(35, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(36, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(37, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(38, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(39, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(40, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(41, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(42, %[cc], %[sk]) + +#if BR_POWER8_LE + /* + * v15 = constant for byteswapping words + */ + lxvw4x(47, 0, %[idx2be]) +#endif + /* + * Load IV into v16. + */ + lxvw4x(48, 0, %[iv]) +#if BR_POWER8_LE + vperm(16, 16, 16, 15) +#endif + + mtctr(%[num_blocks]) + label(loop) + /* + * Load next plaintext word and XOR with current IV. + */ + lxvw4x(49, 0, %[buf]) +#if BR_POWER8_LE + vperm(17, 17, 17, 15) +#endif + vxor(16, 16, 17) + + /* + * Encrypt the block. + */ + vxor(16, 16, 0) + vcipher(16, 16, 1) + vcipher(16, 16, 2) + vcipher(16, 16, 3) + vcipher(16, 16, 4) + vcipher(16, 16, 5) + vcipher(16, 16, 6) + vcipher(16, 16, 7) + vcipher(16, 16, 8) + vcipher(16, 16, 9) + vcipherlast(16, 16, 10) + + /* + * Store back result (with byteswap) + */ +#if BR_POWER8_LE + vperm(17, 16, 16, 15) + stxvw4x(49, 0, %[buf]) +#else + stxvw4x(48, 0, %[buf]) +#endif + addi(%[buf], %[buf], 16) + + bdnz(loop) + +: [cc] "+b" (cc), [buf] "+b" (buf) +: [sk] "b" (sk), [iv] "b" (iv), [num_blocks] "b" (len >> 4) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", + "ctr", "memory" + ); +} + +static void +cbcenc_192(const unsigned char *sk, + const unsigned char *iv, unsigned char *buf, size_t len) +{ + long cc; + +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + + cc = 0; + asm volatile ( + + /* + * Load subkeys into v0..v12 + */ + lxvw4x(32, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(33, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(34, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(35, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(36, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(37, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(38, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(39, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(40, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(41, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(42, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(43, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(44, %[cc], %[sk]) + +#if BR_POWER8_LE + /* + * v15 = constant for byteswapping words + */ + lxvw4x(47, 0, %[idx2be]) +#endif + /* + * Load IV into v16. + */ + lxvw4x(48, 0, %[iv]) +#if BR_POWER8_LE + vperm(16, 16, 16, 15) +#endif + + mtctr(%[num_blocks]) + label(loop) + /* + * Load next plaintext word and XOR with current IV. + */ + lxvw4x(49, 0, %[buf]) +#if BR_POWER8_LE + vperm(17, 17, 17, 15) +#endif + vxor(16, 16, 17) + + /* + * Encrypt the block. + */ + vxor(16, 16, 0) + vcipher(16, 16, 1) + vcipher(16, 16, 2) + vcipher(16, 16, 3) + vcipher(16, 16, 4) + vcipher(16, 16, 5) + vcipher(16, 16, 6) + vcipher(16, 16, 7) + vcipher(16, 16, 8) + vcipher(16, 16, 9) + vcipher(16, 16, 10) + vcipher(16, 16, 11) + vcipherlast(16, 16, 12) + + /* + * Store back result (with byteswap) + */ +#if BR_POWER8_LE + vperm(17, 16, 16, 15) + stxvw4x(49, 0, %[buf]) +#else + stxvw4x(48, 0, %[buf]) +#endif + addi(%[buf], %[buf], 16) + + bdnz(loop) + +: [cc] "+b" (cc), [buf] "+b" (buf) +: [sk] "b" (sk), [iv] "b" (iv), [num_blocks] "b" (len >> 4) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", + "ctr", "memory" + ); +} + +static void +cbcenc_256(const unsigned char *sk, + const unsigned char *iv, unsigned char *buf, size_t len) +{ + long cc; + +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + + cc = 0; + asm volatile ( + + /* + * Load subkeys into v0..v14 + */ + lxvw4x(32, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(33, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(34, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(35, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(36, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(37, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(38, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(39, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(40, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(41, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(42, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(43, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(44, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(45, %[cc], %[sk]) + addi(%[cc], %[cc], 16) + lxvw4x(46, %[cc], %[sk]) + +#if BR_POWER8_LE + /* + * v15 = constant for byteswapping words + */ + lxvw4x(47, 0, %[idx2be]) +#endif + /* + * Load IV into v16. + */ + lxvw4x(48, 0, %[iv]) +#if BR_POWER8_LE + vperm(16, 16, 16, 15) +#endif + + mtctr(%[num_blocks]) + label(loop) + /* + * Load next plaintext word and XOR with current IV. + */ + lxvw4x(49, 0, %[buf]) +#if BR_POWER8_LE + vperm(17, 17, 17, 15) +#endif + vxor(16, 16, 17) + + /* + * Encrypt the block. + */ + vxor(16, 16, 0) + vcipher(16, 16, 1) + vcipher(16, 16, 2) + vcipher(16, 16, 3) + vcipher(16, 16, 4) + vcipher(16, 16, 5) + vcipher(16, 16, 6) + vcipher(16, 16, 7) + vcipher(16, 16, 8) + vcipher(16, 16, 9) + vcipher(16, 16, 10) + vcipher(16, 16, 11) + vcipher(16, 16, 12) + vcipher(16, 16, 13) + vcipherlast(16, 16, 14) + + /* + * Store back result (with byteswap) + */ +#if BR_POWER8_LE + vperm(17, 16, 16, 15) + stxvw4x(49, 0, %[buf]) +#else + stxvw4x(48, 0, %[buf]) +#endif + addi(%[buf], %[buf], 16) + + bdnz(loop) + +: [cc] "+b" (cc), [buf] "+b" (buf) +: [sk] "b" (sk), [iv] "b" (iv), [num_blocks] "b" (len >> 4) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", + "ctr", "memory" + ); +} + +/* see bearssl_block.h */ +void +br_aes_pwr8_cbcenc_run(const br_aes_pwr8_cbcenc_keys *ctx, + void *iv, void *data, size_t len) +{ + if (len > 0) { + switch (ctx->num_rounds) { + case 10: + cbcenc_128(ctx->skey.skni, iv, data, len); + break; + case 12: + cbcenc_192(ctx->skey.skni, iv, data, len); + break; + default: + cbcenc_256(ctx->skey.skni, iv, data, len); + break; + } + memcpy(iv, (unsigned char *)data + (len - 16), 16); + } +} + +/* see bearssl_block.h */ +const br_block_cbcenc_class br_aes_pwr8_cbcenc_vtable = { + sizeof(br_aes_pwr8_cbcenc_keys), + 16, + 4, + (void (*)(const br_block_cbcenc_class **, const void *, size_t)) + &br_aes_pwr8_cbcenc_init, + (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) + &br_aes_pwr8_cbcenc_run +}; + +/* see bearssl_block.h */ +const br_block_cbcenc_class * +br_aes_pwr8_cbcenc_get_vtable(void) +{ + return br_aes_pwr8_supported() ? &br_aes_pwr8_cbcenc_vtable : NULL; +} + +#else + +/* see bearssl_block.h */ +const br_block_cbcenc_class * +br_aes_pwr8_cbcenc_get_vtable(void) +{ + return NULL; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8_ctr.c b/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8_ctr.c new file mode 100644 index 0000000..f5d20c0 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8_ctr.c @@ -0,0 +1,717 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_POWER_ASM_MACROS 1 +#include "inner.h" + +#if BR_POWER8 + +/* see bearssl_block.h */ +void +br_aes_pwr8_ctr_init(br_aes_pwr8_ctr_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_pwr8_ctr_vtable; + ctx->num_rounds = br_aes_pwr8_keysched(ctx->skey.skni, key, len); +} + +static void +ctr_128(const unsigned char *sk, const unsigned char *ivbuf, + unsigned char *buf, size_t num_blocks) +{ + long cc0, cc1, cc2, cc3; + +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + static const uint32_t ctrinc[] = { + 0, 0, 0, 4 + }; + + cc0 = 0; + cc1 = 16; + cc2 = 32; + cc3 = 48; + asm volatile ( + + /* + * Load subkeys into v0..v10 + */ + lxvw4x(32, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(33, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(34, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(35, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(36, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(37, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(38, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(39, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(40, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(41, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(42, %[cc0], %[sk]) + li(%[cc0], 0) + +#if BR_POWER8_LE + /* + * v15 = constant for byteswapping words + */ + lxvw4x(47, 0, %[idx2be]) +#endif + /* + * v28 = increment for IV counter. + */ + lxvw4x(60, 0, %[ctrinc]) + + /* + * Load IV into v16..v19 + */ + lxvw4x(48, %[cc0], %[ivbuf]) + lxvw4x(49, %[cc1], %[ivbuf]) + lxvw4x(50, %[cc2], %[ivbuf]) + lxvw4x(51, %[cc3], %[ivbuf]) +#if BR_POWER8_LE + vperm(16, 16, 16, 15) + vperm(17, 17, 17, 15) + vperm(18, 18, 18, 15) + vperm(19, 19, 19, 15) +#endif + + mtctr(%[num_blocks]) + label(loop) + /* + * Compute next IV into v24..v27 + */ + vadduwm(24, 16, 28) + vadduwm(25, 17, 28) + vadduwm(26, 18, 28) + vadduwm(27, 19, 28) + + /* + * Load next data blocks. We do this early on but we + * won't need them until IV encryption is done. + */ + lxvw4x(52, %[cc0], %[buf]) + lxvw4x(53, %[cc1], %[buf]) + lxvw4x(54, %[cc2], %[buf]) + lxvw4x(55, %[cc3], %[buf]) + + /* + * Encrypt the current IV. + */ + vxor(16, 16, 0) + vxor(17, 17, 0) + vxor(18, 18, 0) + vxor(19, 19, 0) + vcipher(16, 16, 1) + vcipher(17, 17, 1) + vcipher(18, 18, 1) + vcipher(19, 19, 1) + vcipher(16, 16, 2) + vcipher(17, 17, 2) + vcipher(18, 18, 2) + vcipher(19, 19, 2) + vcipher(16, 16, 3) + vcipher(17, 17, 3) + vcipher(18, 18, 3) + vcipher(19, 19, 3) + vcipher(16, 16, 4) + vcipher(17, 17, 4) + vcipher(18, 18, 4) + vcipher(19, 19, 4) + vcipher(16, 16, 5) + vcipher(17, 17, 5) + vcipher(18, 18, 5) + vcipher(19, 19, 5) + vcipher(16, 16, 6) + vcipher(17, 17, 6) + vcipher(18, 18, 6) + vcipher(19, 19, 6) + vcipher(16, 16, 7) + vcipher(17, 17, 7) + vcipher(18, 18, 7) + vcipher(19, 19, 7) + vcipher(16, 16, 8) + vcipher(17, 17, 8) + vcipher(18, 18, 8) + vcipher(19, 19, 8) + vcipher(16, 16, 9) + vcipher(17, 17, 9) + vcipher(18, 18, 9) + vcipher(19, 19, 9) + vcipherlast(16, 16, 10) + vcipherlast(17, 17, 10) + vcipherlast(18, 18, 10) + vcipherlast(19, 19, 10) + +#if BR_POWER8_LE + vperm(16, 16, 16, 15) + vperm(17, 17, 17, 15) + vperm(18, 18, 18, 15) + vperm(19, 19, 19, 15) +#endif + + /* + * Load next plaintext word and XOR with encrypted IV. + */ + vxor(16, 20, 16) + vxor(17, 21, 17) + vxor(18, 22, 18) + vxor(19, 23, 19) + stxvw4x(48, %[cc0], %[buf]) + stxvw4x(49, %[cc1], %[buf]) + stxvw4x(50, %[cc2], %[buf]) + stxvw4x(51, %[cc3], %[buf]) + + addi(%[buf], %[buf], 64) + + /* + * Update IV. + */ + vand(16, 24, 24) + vand(17, 25, 25) + vand(18, 26, 26) + vand(19, 27, 27) + + bdnz(loop) + +: [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), + [buf] "+b" (buf) +: [sk] "b" (sk), [ivbuf] "b" (ivbuf), [num_blocks] "b" (num_blocks >> 2), + [ctrinc] "b" (ctrinc) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", + "ctr", "memory" + ); +} + +static void +ctr_192(const unsigned char *sk, const unsigned char *ivbuf, + unsigned char *buf, size_t num_blocks) +{ + long cc0, cc1, cc2, cc3; + +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + static const uint32_t ctrinc[] = { + 0, 0, 0, 4 + }; + + cc0 = 0; + cc1 = 16; + cc2 = 32; + cc3 = 48; + asm volatile ( + + /* + * Load subkeys into v0..v12 + */ + lxvw4x(32, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(33, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(34, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(35, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(36, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(37, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(38, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(39, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(40, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(41, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(42, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(43, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(44, %[cc0], %[sk]) + li(%[cc0], 0) + +#if BR_POWER8_LE + /* + * v15 = constant for byteswapping words + */ + lxvw4x(47, 0, %[idx2be]) +#endif + /* + * v28 = increment for IV counter. + */ + lxvw4x(60, 0, %[ctrinc]) + + /* + * Load IV into v16..v19 + */ + lxvw4x(48, %[cc0], %[ivbuf]) + lxvw4x(49, %[cc1], %[ivbuf]) + lxvw4x(50, %[cc2], %[ivbuf]) + lxvw4x(51, %[cc3], %[ivbuf]) +#if BR_POWER8_LE + vperm(16, 16, 16, 15) + vperm(17, 17, 17, 15) + vperm(18, 18, 18, 15) + vperm(19, 19, 19, 15) +#endif + + mtctr(%[num_blocks]) + label(loop) + /* + * Compute next IV into v24..v27 + */ + vadduwm(24, 16, 28) + vadduwm(25, 17, 28) + vadduwm(26, 18, 28) + vadduwm(27, 19, 28) + + /* + * Load next data blocks. We do this early on but we + * won't need them until IV encryption is done. + */ + lxvw4x(52, %[cc0], %[buf]) + lxvw4x(53, %[cc1], %[buf]) + lxvw4x(54, %[cc2], %[buf]) + lxvw4x(55, %[cc3], %[buf]) + + /* + * Encrypt the current IV. + */ + vxor(16, 16, 0) + vxor(17, 17, 0) + vxor(18, 18, 0) + vxor(19, 19, 0) + vcipher(16, 16, 1) + vcipher(17, 17, 1) + vcipher(18, 18, 1) + vcipher(19, 19, 1) + vcipher(16, 16, 2) + vcipher(17, 17, 2) + vcipher(18, 18, 2) + vcipher(19, 19, 2) + vcipher(16, 16, 3) + vcipher(17, 17, 3) + vcipher(18, 18, 3) + vcipher(19, 19, 3) + vcipher(16, 16, 4) + vcipher(17, 17, 4) + vcipher(18, 18, 4) + vcipher(19, 19, 4) + vcipher(16, 16, 5) + vcipher(17, 17, 5) + vcipher(18, 18, 5) + vcipher(19, 19, 5) + vcipher(16, 16, 6) + vcipher(17, 17, 6) + vcipher(18, 18, 6) + vcipher(19, 19, 6) + vcipher(16, 16, 7) + vcipher(17, 17, 7) + vcipher(18, 18, 7) + vcipher(19, 19, 7) + vcipher(16, 16, 8) + vcipher(17, 17, 8) + vcipher(18, 18, 8) + vcipher(19, 19, 8) + vcipher(16, 16, 9) + vcipher(17, 17, 9) + vcipher(18, 18, 9) + vcipher(19, 19, 9) + vcipher(16, 16, 10) + vcipher(17, 17, 10) + vcipher(18, 18, 10) + vcipher(19, 19, 10) + vcipher(16, 16, 11) + vcipher(17, 17, 11) + vcipher(18, 18, 11) + vcipher(19, 19, 11) + vcipherlast(16, 16, 12) + vcipherlast(17, 17, 12) + vcipherlast(18, 18, 12) + vcipherlast(19, 19, 12) + +#if BR_POWER8_LE + vperm(16, 16, 16, 15) + vperm(17, 17, 17, 15) + vperm(18, 18, 18, 15) + vperm(19, 19, 19, 15) +#endif + + /* + * Load next plaintext word and XOR with encrypted IV. + */ + vxor(16, 20, 16) + vxor(17, 21, 17) + vxor(18, 22, 18) + vxor(19, 23, 19) + stxvw4x(48, %[cc0], %[buf]) + stxvw4x(49, %[cc1], %[buf]) + stxvw4x(50, %[cc2], %[buf]) + stxvw4x(51, %[cc3], %[buf]) + + addi(%[buf], %[buf], 64) + + /* + * Update IV. + */ + vand(16, 24, 24) + vand(17, 25, 25) + vand(18, 26, 26) + vand(19, 27, 27) + + bdnz(loop) + +: [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), + [buf] "+b" (buf) +: [sk] "b" (sk), [ivbuf] "b" (ivbuf), [num_blocks] "b" (num_blocks >> 2), + [ctrinc] "b" (ctrinc) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", + "ctr", "memory" + ); +} + +static void +ctr_256(const unsigned char *sk, const unsigned char *ivbuf, + unsigned char *buf, size_t num_blocks) +{ + long cc0, cc1, cc2, cc3; + +#if BR_POWER8_LE + static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C + }; +#endif + static const uint32_t ctrinc[] = { + 0, 0, 0, 4 + }; + + cc0 = 0; + cc1 = 16; + cc2 = 32; + cc3 = 48; + asm volatile ( + + /* + * Load subkeys into v0..v14 + */ + lxvw4x(32, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(33, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(34, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(35, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(36, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(37, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(38, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(39, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(40, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(41, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(42, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(43, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(44, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(45, %[cc0], %[sk]) + addi(%[cc0], %[cc0], 16) + lxvw4x(46, %[cc0], %[sk]) + li(%[cc0], 0) + +#if BR_POWER8_LE + /* + * v15 = constant for byteswapping words + */ + lxvw4x(47, 0, %[idx2be]) +#endif + /* + * v28 = increment for IV counter. + */ + lxvw4x(60, 0, %[ctrinc]) + + /* + * Load IV into v16..v19 + */ + lxvw4x(48, %[cc0], %[ivbuf]) + lxvw4x(49, %[cc1], %[ivbuf]) + lxvw4x(50, %[cc2], %[ivbuf]) + lxvw4x(51, %[cc3], %[ivbuf]) +#if BR_POWER8_LE + vperm(16, 16, 16, 15) + vperm(17, 17, 17, 15) + vperm(18, 18, 18, 15) + vperm(19, 19, 19, 15) +#endif + + mtctr(%[num_blocks]) + label(loop) + /* + * Compute next IV into v24..v27 + */ + vadduwm(24, 16, 28) + vadduwm(25, 17, 28) + vadduwm(26, 18, 28) + vadduwm(27, 19, 28) + + /* + * Load next data blocks. We do this early on but we + * won't need them until IV encryption is done. + */ + lxvw4x(52, %[cc0], %[buf]) + lxvw4x(53, %[cc1], %[buf]) + lxvw4x(54, %[cc2], %[buf]) + lxvw4x(55, %[cc3], %[buf]) + + /* + * Encrypt the current IV. + */ + vxor(16, 16, 0) + vxor(17, 17, 0) + vxor(18, 18, 0) + vxor(19, 19, 0) + vcipher(16, 16, 1) + vcipher(17, 17, 1) + vcipher(18, 18, 1) + vcipher(19, 19, 1) + vcipher(16, 16, 2) + vcipher(17, 17, 2) + vcipher(18, 18, 2) + vcipher(19, 19, 2) + vcipher(16, 16, 3) + vcipher(17, 17, 3) + vcipher(18, 18, 3) + vcipher(19, 19, 3) + vcipher(16, 16, 4) + vcipher(17, 17, 4) + vcipher(18, 18, 4) + vcipher(19, 19, 4) + vcipher(16, 16, 5) + vcipher(17, 17, 5) + vcipher(18, 18, 5) + vcipher(19, 19, 5) + vcipher(16, 16, 6) + vcipher(17, 17, 6) + vcipher(18, 18, 6) + vcipher(19, 19, 6) + vcipher(16, 16, 7) + vcipher(17, 17, 7) + vcipher(18, 18, 7) + vcipher(19, 19, 7) + vcipher(16, 16, 8) + vcipher(17, 17, 8) + vcipher(18, 18, 8) + vcipher(19, 19, 8) + vcipher(16, 16, 9) + vcipher(17, 17, 9) + vcipher(18, 18, 9) + vcipher(19, 19, 9) + vcipher(16, 16, 10) + vcipher(17, 17, 10) + vcipher(18, 18, 10) + vcipher(19, 19, 10) + vcipher(16, 16, 11) + vcipher(17, 17, 11) + vcipher(18, 18, 11) + vcipher(19, 19, 11) + vcipher(16, 16, 12) + vcipher(17, 17, 12) + vcipher(18, 18, 12) + vcipher(19, 19, 12) + vcipher(16, 16, 13) + vcipher(17, 17, 13) + vcipher(18, 18, 13) + vcipher(19, 19, 13) + vcipherlast(16, 16, 14) + vcipherlast(17, 17, 14) + vcipherlast(18, 18, 14) + vcipherlast(19, 19, 14) + +#if BR_POWER8_LE + vperm(16, 16, 16, 15) + vperm(17, 17, 17, 15) + vperm(18, 18, 18, 15) + vperm(19, 19, 19, 15) +#endif + + /* + * Load next plaintext word and XOR with encrypted IV. + */ + vxor(16, 20, 16) + vxor(17, 21, 17) + vxor(18, 22, 18) + vxor(19, 23, 19) + stxvw4x(48, %[cc0], %[buf]) + stxvw4x(49, %[cc1], %[buf]) + stxvw4x(50, %[cc2], %[buf]) + stxvw4x(51, %[cc3], %[buf]) + + addi(%[buf], %[buf], 64) + + /* + * Update IV. + */ + vand(16, 24, 24) + vand(17, 25, 25) + vand(18, 26, 26) + vand(19, 27, 27) + + bdnz(loop) + +: [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3), + [buf] "+b" (buf) +: [sk] "b" (sk), [ivbuf] "b" (ivbuf), [num_blocks] "b" (num_blocks >> 2), + [ctrinc] "b" (ctrinc) +#if BR_POWER8_LE + , [idx2be] "b" (idx2be) +#endif +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", + "ctr", "memory" + ); +} + +/* see bearssl_block.h */ +uint32_t +br_aes_pwr8_ctr_run(const br_aes_pwr8_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len) +{ + unsigned char *buf; + unsigned char ivbuf[64]; + + buf = data; + memcpy(ivbuf + 0, iv, 12); + memcpy(ivbuf + 16, iv, 12); + memcpy(ivbuf + 32, iv, 12); + memcpy(ivbuf + 48, iv, 12); + if (len >= 64) { + br_enc32be(ivbuf + 12, cc + 0); + br_enc32be(ivbuf + 28, cc + 1); + br_enc32be(ivbuf + 44, cc + 2); + br_enc32be(ivbuf + 60, cc + 3); + switch (ctx->num_rounds) { + case 10: + ctr_128(ctx->skey.skni, ivbuf, buf, + (len >> 4) & ~(size_t)3); + break; + case 12: + ctr_192(ctx->skey.skni, ivbuf, buf, + (len >> 4) & ~(size_t)3); + break; + default: + ctr_256(ctx->skey.skni, ivbuf, buf, + (len >> 4) & ~(size_t)3); + break; + } + cc += (len >> 4) & ~(size_t)3; + buf += len & ~(size_t)63; + len &= 63; + } + if (len > 0) { + unsigned char tmp[64]; + + memcpy(tmp, buf, len); + memset(tmp + len, 0, (sizeof tmp) - len); + br_enc32be(ivbuf + 12, cc + 0); + br_enc32be(ivbuf + 28, cc + 1); + br_enc32be(ivbuf + 44, cc + 2); + br_enc32be(ivbuf + 60, cc + 3); + switch (ctx->num_rounds) { + case 10: + ctr_128(ctx->skey.skni, ivbuf, tmp, 4); + break; + case 12: + ctr_192(ctx->skey.skni, ivbuf, tmp, 4); + break; + default: + ctr_256(ctx->skey.skni, ivbuf, tmp, 4); + break; + } + memcpy(buf, tmp, len); + cc += (len + 15) >> 4; + } + return cc; +} + +/* see bearssl_block.h */ +const br_block_ctr_class br_aes_pwr8_ctr_vtable = { + sizeof(br_aes_pwr8_ctr_keys), + 16, + 4, + (void (*)(const br_block_ctr_class **, const void *, size_t)) + &br_aes_pwr8_ctr_init, + (uint32_t (*)(const br_block_ctr_class *const *, + const void *, uint32_t, void *, size_t)) + &br_aes_pwr8_ctr_run +}; + +/* see bearssl_block.h */ +const br_block_ctr_class * +br_aes_pwr8_ctr_get_vtable(void) +{ + return br_aes_pwr8_supported() ? &br_aes_pwr8_ctr_vtable : NULL; +} + +#else + +/* see bearssl_block.h */ +const br_block_ctr_class * +br_aes_pwr8_ctr_get_vtable(void) +{ + return NULL; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8_ctrcbc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8_ctrcbc.c new file mode 100644 index 0000000..a67d30b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_pwr8_ctrcbc.c @@ -0,0 +1,946 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_POWER_ASM_MACROS 1 +#include "inner.h" + +#if BR_POWER8 + +/* see bearssl_block.h */ +const br_block_ctrcbc_class * +br_aes_pwr8_ctrcbc_get_vtable(void) +{ + return br_aes_pwr8_supported() ? &br_aes_pwr8_ctrcbc_vtable : NULL; +} + +/* see bearssl_block.h */ +void +br_aes_pwr8_ctrcbc_init(br_aes_pwr8_ctrcbc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_pwr8_ctrcbc_vtable; + ctx->num_rounds = br_aes_pwr8_keysched(ctx->skey.skni, key, len); +} + +/* + * Register conventions for CTR + CBC-MAC: + * + * AES subkeys are in registers 0 to 10/12/14 (depending on keys size) + * Register v15 contains the byteswap index register (little-endian only) + * Register v16 contains the CTR counter value + * Register v17 contains the CBC-MAC current value + * Registers v18 to v27 are scratch + * Counter increment uses v28, v29 and v30 + * + * For CTR alone: + * + * AES subkeys are in registers 0 to 10/12/14 (depending on keys size) + * Register v15 contains the byteswap index register (little-endian only) + * Registers v16 to v19 contain the CTR counter values (four blocks) + * Registers v20 to v27 are scratch + * Counter increment uses v28, v29 and v30 + */ + +#define LOAD_SUBKEYS_128 \ + lxvw4x(32, %[cc], %[sk]) \ + addi(%[cc], %[cc], 16) \ + lxvw4x(33, %[cc], %[sk]) \ + addi(%[cc], %[cc], 16) \ + lxvw4x(34, %[cc], %[sk]) \ + addi(%[cc], %[cc], 16) \ + lxvw4x(35, %[cc], %[sk]) \ + addi(%[cc], %[cc], 16) \ + lxvw4x(36, %[cc], %[sk]) \ + addi(%[cc], %[cc], 16) \ + lxvw4x(37, %[cc], %[sk]) \ + addi(%[cc], %[cc], 16) \ + lxvw4x(38, %[cc], %[sk]) \ + addi(%[cc], %[cc], 16) \ + lxvw4x(39, %[cc], %[sk]) \ + addi(%[cc], %[cc], 16) \ + lxvw4x(40, %[cc], %[sk]) \ + addi(%[cc], %[cc], 16) \ + lxvw4x(41, %[cc], %[sk]) \ + addi(%[cc], %[cc], 16) \ + lxvw4x(42, %[cc], %[sk]) + +#define LOAD_SUBKEYS_192 \ + LOAD_SUBKEYS_128 \ + addi(%[cc], %[cc], 16) \ + lxvw4x(43, %[cc], %[sk]) \ + addi(%[cc], %[cc], 16) \ + lxvw4x(44, %[cc], %[sk]) + +#define LOAD_SUBKEYS_256 \ + LOAD_SUBKEYS_192 \ + addi(%[cc], %[cc], 16) \ + lxvw4x(45, %[cc], %[sk]) \ + addi(%[cc], %[cc], 16) \ + lxvw4x(46, %[cc], %[sk]) + +#define BLOCK_ENCRYPT_128(x) \ + vxor(x, x, 0) \ + vcipher(x, x, 1) \ + vcipher(x, x, 2) \ + vcipher(x, x, 3) \ + vcipher(x, x, 4) \ + vcipher(x, x, 5) \ + vcipher(x, x, 6) \ + vcipher(x, x, 7) \ + vcipher(x, x, 8) \ + vcipher(x, x, 9) \ + vcipherlast(x, x, 10) + +#define BLOCK_ENCRYPT_192(x) \ + vxor(x, x, 0) \ + vcipher(x, x, 1) \ + vcipher(x, x, 2) \ + vcipher(x, x, 3) \ + vcipher(x, x, 4) \ + vcipher(x, x, 5) \ + vcipher(x, x, 6) \ + vcipher(x, x, 7) \ + vcipher(x, x, 8) \ + vcipher(x, x, 9) \ + vcipher(x, x, 10) \ + vcipher(x, x, 11) \ + vcipherlast(x, x, 12) + +#define BLOCK_ENCRYPT_256(x) \ + vxor(x, x, 0) \ + vcipher(x, x, 1) \ + vcipher(x, x, 2) \ + vcipher(x, x, 3) \ + vcipher(x, x, 4) \ + vcipher(x, x, 5) \ + vcipher(x, x, 6) \ + vcipher(x, x, 7) \ + vcipher(x, x, 8) \ + vcipher(x, x, 9) \ + vcipher(x, x, 10) \ + vcipher(x, x, 11) \ + vcipher(x, x, 12) \ + vcipher(x, x, 13) \ + vcipherlast(x, x, 14) + +#define BLOCK_ENCRYPT_X2_128(x, y) \ + vxor(x, x, 0) \ + vxor(y, y, 0) \ + vcipher(x, x, 1) \ + vcipher(y, y, 1) \ + vcipher(x, x, 2) \ + vcipher(y, y, 2) \ + vcipher(x, x, 3) \ + vcipher(y, y, 3) \ + vcipher(x, x, 4) \ + vcipher(y, y, 4) \ + vcipher(x, x, 5) \ + vcipher(y, y, 5) \ + vcipher(x, x, 6) \ + vcipher(y, y, 6) \ + vcipher(x, x, 7) \ + vcipher(y, y, 7) \ + vcipher(x, x, 8) \ + vcipher(y, y, 8) \ + vcipher(x, x, 9) \ + vcipher(y, y, 9) \ + vcipherlast(x, x, 10) \ + vcipherlast(y, y, 10) + +#define BLOCK_ENCRYPT_X2_192(x, y) \ + vxor(x, x, 0) \ + vxor(y, y, 0) \ + vcipher(x, x, 1) \ + vcipher(y, y, 1) \ + vcipher(x, x, 2) \ + vcipher(y, y, 2) \ + vcipher(x, x, 3) \ + vcipher(y, y, 3) \ + vcipher(x, x, 4) \ + vcipher(y, y, 4) \ + vcipher(x, x, 5) \ + vcipher(y, y, 5) \ + vcipher(x, x, 6) \ + vcipher(y, y, 6) \ + vcipher(x, x, 7) \ + vcipher(y, y, 7) \ + vcipher(x, x, 8) \ + vcipher(y, y, 8) \ + vcipher(x, x, 9) \ + vcipher(y, y, 9) \ + vcipher(x, x, 10) \ + vcipher(y, y, 10) \ + vcipher(x, x, 11) \ + vcipher(y, y, 11) \ + vcipherlast(x, x, 12) \ + vcipherlast(y, y, 12) + +#define BLOCK_ENCRYPT_X2_256(x, y) \ + vxor(x, x, 0) \ + vxor(y, y, 0) \ + vcipher(x, x, 1) \ + vcipher(y, y, 1) \ + vcipher(x, x, 2) \ + vcipher(y, y, 2) \ + vcipher(x, x, 3) \ + vcipher(y, y, 3) \ + vcipher(x, x, 4) \ + vcipher(y, y, 4) \ + vcipher(x, x, 5) \ + vcipher(y, y, 5) \ + vcipher(x, x, 6) \ + vcipher(y, y, 6) \ + vcipher(x, x, 7) \ + vcipher(y, y, 7) \ + vcipher(x, x, 8) \ + vcipher(y, y, 8) \ + vcipher(x, x, 9) \ + vcipher(y, y, 9) \ + vcipher(x, x, 10) \ + vcipher(y, y, 10) \ + vcipher(x, x, 11) \ + vcipher(y, y, 11) \ + vcipher(x, x, 12) \ + vcipher(y, y, 12) \ + vcipher(x, x, 13) \ + vcipher(y, y, 13) \ + vcipherlast(x, x, 14) \ + vcipherlast(y, y, 14) + +#define BLOCK_ENCRYPT_X4_128(x0, x1, x2, x3) \ + vxor(x0, x0, 0) \ + vxor(x1, x1, 0) \ + vxor(x2, x2, 0) \ + vxor(x3, x3, 0) \ + vcipher(x0, x0, 1) \ + vcipher(x1, x1, 1) \ + vcipher(x2, x2, 1) \ + vcipher(x3, x3, 1) \ + vcipher(x0, x0, 2) \ + vcipher(x1, x1, 2) \ + vcipher(x2, x2, 2) \ + vcipher(x3, x3, 2) \ + vcipher(x0, x0, 3) \ + vcipher(x1, x1, 3) \ + vcipher(x2, x2, 3) \ + vcipher(x3, x3, 3) \ + vcipher(x0, x0, 4) \ + vcipher(x1, x1, 4) \ + vcipher(x2, x2, 4) \ + vcipher(x3, x3, 4) \ + vcipher(x0, x0, 5) \ + vcipher(x1, x1, 5) \ + vcipher(x2, x2, 5) \ + vcipher(x3, x3, 5) \ + vcipher(x0, x0, 6) \ + vcipher(x1, x1, 6) \ + vcipher(x2, x2, 6) \ + vcipher(x3, x3, 6) \ + vcipher(x0, x0, 7) \ + vcipher(x1, x1, 7) \ + vcipher(x2, x2, 7) \ + vcipher(x3, x3, 7) \ + vcipher(x0, x0, 8) \ + vcipher(x1, x1, 8) \ + vcipher(x2, x2, 8) \ + vcipher(x3, x3, 8) \ + vcipher(x0, x0, 9) \ + vcipher(x1, x1, 9) \ + vcipher(x2, x2, 9) \ + vcipher(x3, x3, 9) \ + vcipherlast(x0, x0, 10) \ + vcipherlast(x1, x1, 10) \ + vcipherlast(x2, x2, 10) \ + vcipherlast(x3, x3, 10) + +#define BLOCK_ENCRYPT_X4_192(x0, x1, x2, x3) \ + vxor(x0, x0, 0) \ + vxor(x1, x1, 0) \ + vxor(x2, x2, 0) \ + vxor(x3, x3, 0) \ + vcipher(x0, x0, 1) \ + vcipher(x1, x1, 1) \ + vcipher(x2, x2, 1) \ + vcipher(x3, x3, 1) \ + vcipher(x0, x0, 2) \ + vcipher(x1, x1, 2) \ + vcipher(x2, x2, 2) \ + vcipher(x3, x3, 2) \ + vcipher(x0, x0, 3) \ + vcipher(x1, x1, 3) \ + vcipher(x2, x2, 3) \ + vcipher(x3, x3, 3) \ + vcipher(x0, x0, 4) \ + vcipher(x1, x1, 4) \ + vcipher(x2, x2, 4) \ + vcipher(x3, x3, 4) \ + vcipher(x0, x0, 5) \ + vcipher(x1, x1, 5) \ + vcipher(x2, x2, 5) \ + vcipher(x3, x3, 5) \ + vcipher(x0, x0, 6) \ + vcipher(x1, x1, 6) \ + vcipher(x2, x2, 6) \ + vcipher(x3, x3, 6) \ + vcipher(x0, x0, 7) \ + vcipher(x1, x1, 7) \ + vcipher(x2, x2, 7) \ + vcipher(x3, x3, 7) \ + vcipher(x0, x0, 8) \ + vcipher(x1, x1, 8) \ + vcipher(x2, x2, 8) \ + vcipher(x3, x3, 8) \ + vcipher(x0, x0, 9) \ + vcipher(x1, x1, 9) \ + vcipher(x2, x2, 9) \ + vcipher(x3, x3, 9) \ + vcipher(x0, x0, 10) \ + vcipher(x1, x1, 10) \ + vcipher(x2, x2, 10) \ + vcipher(x3, x3, 10) \ + vcipher(x0, x0, 11) \ + vcipher(x1, x1, 11) \ + vcipher(x2, x2, 11) \ + vcipher(x3, x3, 11) \ + vcipherlast(x0, x0, 12) \ + vcipherlast(x1, x1, 12) \ + vcipherlast(x2, x2, 12) \ + vcipherlast(x3, x3, 12) + +#define BLOCK_ENCRYPT_X4_256(x0, x1, x2, x3) \ + vxor(x0, x0, 0) \ + vxor(x1, x1, 0) \ + vxor(x2, x2, 0) \ + vxor(x3, x3, 0) \ + vcipher(x0, x0, 1) \ + vcipher(x1, x1, 1) \ + vcipher(x2, x2, 1) \ + vcipher(x3, x3, 1) \ + vcipher(x0, x0, 2) \ + vcipher(x1, x1, 2) \ + vcipher(x2, x2, 2) \ + vcipher(x3, x3, 2) \ + vcipher(x0, x0, 3) \ + vcipher(x1, x1, 3) \ + vcipher(x2, x2, 3) \ + vcipher(x3, x3, 3) \ + vcipher(x0, x0, 4) \ + vcipher(x1, x1, 4) \ + vcipher(x2, x2, 4) \ + vcipher(x3, x3, 4) \ + vcipher(x0, x0, 5) \ + vcipher(x1, x1, 5) \ + vcipher(x2, x2, 5) \ + vcipher(x3, x3, 5) \ + vcipher(x0, x0, 6) \ + vcipher(x1, x1, 6) \ + vcipher(x2, x2, 6) \ + vcipher(x3, x3, 6) \ + vcipher(x0, x0, 7) \ + vcipher(x1, x1, 7) \ + vcipher(x2, x2, 7) \ + vcipher(x3, x3, 7) \ + vcipher(x0, x0, 8) \ + vcipher(x1, x1, 8) \ + vcipher(x2, x2, 8) \ + vcipher(x3, x3, 8) \ + vcipher(x0, x0, 9) \ + vcipher(x1, x1, 9) \ + vcipher(x2, x2, 9) \ + vcipher(x3, x3, 9) \ + vcipher(x0, x0, 10) \ + vcipher(x1, x1, 10) \ + vcipher(x2, x2, 10) \ + vcipher(x3, x3, 10) \ + vcipher(x0, x0, 11) \ + vcipher(x1, x1, 11) \ + vcipher(x2, x2, 11) \ + vcipher(x3, x3, 11) \ + vcipher(x0, x0, 12) \ + vcipher(x1, x1, 12) \ + vcipher(x2, x2, 12) \ + vcipher(x3, x3, 12) \ + vcipher(x0, x0, 13) \ + vcipher(x1, x1, 13) \ + vcipher(x2, x2, 13) \ + vcipher(x3, x3, 13) \ + vcipherlast(x0, x0, 14) \ + vcipherlast(x1, x1, 14) \ + vcipherlast(x2, x2, 14) \ + vcipherlast(x3, x3, 14) + +#if BR_POWER8_LE +static const uint32_t idx2be[] = { + 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C +}; +#define BYTESWAP_INIT lxvw4x(47, 0, %[idx2be]) +#define BYTESWAP(x) vperm(x, x, x, 15) +#define BYTESWAPX(d, s) vperm(d, s, s, 15) +#define BYTESWAP_REG , [idx2be] "b" (idx2be) +#else +#define BYTESWAP_INIT +#define BYTESWAP(x) +#define BYTESWAPX(d, s) vand(d, s, s) +#define BYTESWAP_REG +#endif + +static const uint32_t ctrinc[] = { + 0, 0, 0, 1 +}; +static const uint32_t ctrinc_x4[] = { + 0, 0, 0, 4 +}; +#define INCR_128_INIT lxvw4x(60, 0, %[ctrinc]) +#define INCR_128_X4_INIT lxvw4x(60, 0, %[ctrinc_x4]) +#define INCR_128(d, s) \ + vaddcuw(29, s, 28) \ + vadduwm(d, s, 28) \ + vsldoi(30, 29, 29, 4) \ + vaddcuw(29, d, 30) \ + vadduwm(d, d, 30) \ + vsldoi(30, 29, 29, 4) \ + vaddcuw(29, d, 30) \ + vadduwm(d, d, 30) \ + vsldoi(30, 29, 29, 4) \ + vadduwm(d, d, 30) + +#define MKCTR(size) \ +static void \ +ctr_ ## size(const unsigned char *sk, \ + unsigned char *ctrbuf, unsigned char *buf, size_t num_blocks_x4) \ +{ \ + long cc, cc0, cc1, cc2, cc3; \ + \ + cc = 0; \ + cc0 = 0; \ + cc1 = 16; \ + cc2 = 32; \ + cc3 = 48; \ + asm volatile ( \ + \ + /* \ + * Load subkeys into v0..v10 \ + */ \ + LOAD_SUBKEYS_ ## size \ + li(%[cc], 0) \ + \ + BYTESWAP_INIT \ + INCR_128_X4_INIT \ + \ + /* \ + * Load current CTR counters into v16 to v19. \ + */ \ + lxvw4x(48, %[cc0], %[ctrbuf]) \ + lxvw4x(49, %[cc1], %[ctrbuf]) \ + lxvw4x(50, %[cc2], %[ctrbuf]) \ + lxvw4x(51, %[cc3], %[ctrbuf]) \ + BYTESWAP(16) \ + BYTESWAP(17) \ + BYTESWAP(18) \ + BYTESWAP(19) \ + \ + mtctr(%[num_blocks_x4]) \ + \ + label(loop) \ + /* \ + * Compute next counter values into v20..v23. \ + */ \ + INCR_128(20, 16) \ + INCR_128(21, 17) \ + INCR_128(22, 18) \ + INCR_128(23, 19) \ + \ + /* \ + * Encrypt counter values and XOR into next data blocks. \ + */ \ + lxvw4x(56, %[cc0], %[buf]) \ + lxvw4x(57, %[cc1], %[buf]) \ + lxvw4x(58, %[cc2], %[buf]) \ + lxvw4x(59, %[cc3], %[buf]) \ + BYTESWAP(24) \ + BYTESWAP(25) \ + BYTESWAP(26) \ + BYTESWAP(27) \ + BLOCK_ENCRYPT_X4_ ## size(16, 17, 18, 19) \ + vxor(16, 16, 24) \ + vxor(17, 17, 25) \ + vxor(18, 18, 26) \ + vxor(19, 19, 27) \ + BYTESWAP(16) \ + BYTESWAP(17) \ + BYTESWAP(18) \ + BYTESWAP(19) \ + stxvw4x(48, %[cc0], %[buf]) \ + stxvw4x(49, %[cc1], %[buf]) \ + stxvw4x(50, %[cc2], %[buf]) \ + stxvw4x(51, %[cc3], %[buf]) \ + \ + /* \ + * Update counters and data pointer. \ + */ \ + vand(16, 20, 20) \ + vand(17, 21, 21) \ + vand(18, 22, 22) \ + vand(19, 23, 23) \ + addi(%[buf], %[buf], 64) \ + \ + bdnz(loop) \ + \ + /* \ + * Write back new counter values. \ + */ \ + BYTESWAP(16) \ + BYTESWAP(17) \ + BYTESWAP(18) \ + BYTESWAP(19) \ + stxvw4x(48, %[cc0], %[ctrbuf]) \ + stxvw4x(49, %[cc1], %[ctrbuf]) \ + stxvw4x(50, %[cc2], %[ctrbuf]) \ + stxvw4x(51, %[cc3], %[ctrbuf]) \ + \ +: [cc] "+b" (cc), [buf] "+b" (buf), \ + [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3) \ +: [sk] "b" (sk), [ctrbuf] "b" (ctrbuf), \ + [num_blocks_x4] "b" (num_blocks_x4), [ctrinc_x4] "b" (ctrinc_x4) \ + BYTESWAP_REG \ +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \ + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \ + "v30", "ctr", "memory" \ + ); \ +} + +MKCTR(128) +MKCTR(192) +MKCTR(256) + +#define MKCBCMAC(size) \ +static void \ +cbcmac_ ## size(const unsigned char *sk, \ + unsigned char *cbcmac, const unsigned char *buf, size_t num_blocks) \ +{ \ + long cc; \ + \ + cc = 0; \ + asm volatile ( \ + \ + /* \ + * Load subkeys into v0..v10 \ + */ \ + LOAD_SUBKEYS_ ## size \ + li(%[cc], 0) \ + \ + BYTESWAP_INIT \ + \ + /* \ + * Load current CBC-MAC value into v16. \ + */ \ + lxvw4x(48, %[cc], %[cbcmac]) \ + BYTESWAP(16) \ + \ + mtctr(%[num_blocks]) \ + \ + label(loop) \ + /* \ + * Load next block, XOR into current CBC-MAC value, \ + * and then encrypt it. \ + */ \ + lxvw4x(49, %[cc], %[buf]) \ + BYTESWAP(17) \ + vxor(16, 16, 17) \ + BLOCK_ENCRYPT_ ## size(16) \ + addi(%[buf], %[buf], 16) \ + \ + bdnz(loop) \ + \ + /* \ + * Write back new CBC-MAC value. \ + */ \ + BYTESWAP(16) \ + stxvw4x(48, %[cc], %[cbcmac]) \ + \ +: [cc] "+b" (cc), [buf] "+b" (buf) \ +: [sk] "b" (sk), [cbcmac] "b" (cbcmac), [num_blocks] "b" (num_blocks) \ + BYTESWAP_REG \ +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \ + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \ + "v30", "ctr", "memory" \ + ); \ +} + +MKCBCMAC(128) +MKCBCMAC(192) +MKCBCMAC(256) + +#define MKENCRYPT(size) \ +static void \ +ctrcbc_ ## size ## _encrypt(const unsigned char *sk, \ + unsigned char *ctr, unsigned char *cbcmac, unsigned char *buf, \ + size_t num_blocks) \ +{ \ + long cc; \ + \ + cc = 0; \ + asm volatile ( \ + \ + /* \ + * Load subkeys into v0..v10 \ + */ \ + LOAD_SUBKEYS_ ## size \ + li(%[cc], 0) \ + \ + BYTESWAP_INIT \ + INCR_128_INIT \ + \ + /* \ + * Load current CTR counter into v16, and current \ + * CBC-MAC IV into v17. \ + */ \ + lxvw4x(48, %[cc], %[ctr]) \ + lxvw4x(49, %[cc], %[cbcmac]) \ + BYTESWAP(16) \ + BYTESWAP(17) \ + \ + /* \ + * At each iteration, we do two parallel encryption: \ + * - new counter value for encryption of the next block; \ + * - CBC-MAC over the previous encrypted block. \ + * Thus, each plaintext block implies two AES instances, \ + * over two successive iterations. This requires a single \ + * counter encryption before the loop, and a single \ + * CBC-MAC encryption after the loop. \ + */ \ + \ + /* \ + * Encrypt first block (into v20). \ + */ \ + lxvw4x(52, %[cc], %[buf]) \ + BYTESWAP(20) \ + INCR_128(22, 16) \ + BLOCK_ENCRYPT_ ## size(16) \ + vxor(20, 20, 16) \ + BYTESWAPX(21, 20) \ + stxvw4x(53, %[cc], %[buf]) \ + vand(16, 22, 22) \ + addi(%[buf], %[buf], 16) \ + \ + /* \ + * Load loop counter; skip the loop if there is only \ + * one block in total (already handled by the boundary \ + * conditions). \ + */ \ + mtctr(%[num_blocks]) \ + bdz(fastexit) \ + \ + label(loop) \ + /* \ + * Upon loop entry: \ + * v16 counter value for next block \ + * v17 current CBC-MAC value \ + * v20 encrypted previous block \ + */ \ + vxor(17, 17, 20) \ + INCR_128(22, 16) \ + lxvw4x(52, %[cc], %[buf]) \ + BYTESWAP(20) \ + BLOCK_ENCRYPT_X2_ ## size(16, 17) \ + vxor(20, 20, 16) \ + BYTESWAPX(21, 20) \ + stxvw4x(53, %[cc], %[buf]) \ + addi(%[buf], %[buf], 16) \ + vand(16, 22, 22) \ + \ + bdnz(loop) \ + \ + label(fastexit) \ + vxor(17, 17, 20) \ + BLOCK_ENCRYPT_ ## size(17) \ + BYTESWAP(16) \ + BYTESWAP(17) \ + stxvw4x(48, %[cc], %[ctr]) \ + stxvw4x(49, %[cc], %[cbcmac]) \ + \ +: [cc] "+b" (cc), [buf] "+b" (buf) \ +: [sk] "b" (sk), [ctr] "b" (ctr), [cbcmac] "b" (cbcmac), \ + [num_blocks] "b" (num_blocks), [ctrinc] "b" (ctrinc) \ + BYTESWAP_REG \ +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \ + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \ + "v30", "ctr", "memory" \ + ); \ +} + +MKENCRYPT(128) +MKENCRYPT(192) +MKENCRYPT(256) + +#define MKDECRYPT(size) \ +static void \ +ctrcbc_ ## size ## _decrypt(const unsigned char *sk, \ + unsigned char *ctr, unsigned char *cbcmac, unsigned char *buf, \ + size_t num_blocks) \ +{ \ + long cc; \ + \ + cc = 0; \ + asm volatile ( \ + \ + /* \ + * Load subkeys into v0..v10 \ + */ \ + LOAD_SUBKEYS_ ## size \ + li(%[cc], 0) \ + \ + BYTESWAP_INIT \ + INCR_128_INIT \ + \ + /* \ + * Load current CTR counter into v16, and current \ + * CBC-MAC IV into v17. \ + */ \ + lxvw4x(48, %[cc], %[ctr]) \ + lxvw4x(49, %[cc], %[cbcmac]) \ + BYTESWAP(16) \ + BYTESWAP(17) \ + \ + /* \ + * At each iteration, we do two parallel encryption: \ + * - new counter value for decryption of the next block; \ + * - CBC-MAC over the next encrypted block. \ + * Each iteration performs the two AES instances related \ + * to the current block; there is thus no need for some \ + * extra pre-loop and post-loop work as in encryption. \ + */ \ + \ + mtctr(%[num_blocks]) \ + \ + label(loop) \ + /* \ + * Upon loop entry: \ + * v16 counter value for next block \ + * v17 current CBC-MAC value \ + */ \ + lxvw4x(52, %[cc], %[buf]) \ + BYTESWAP(20) \ + vxor(17, 17, 20) \ + INCR_128(22, 16) \ + BLOCK_ENCRYPT_X2_ ## size(16, 17) \ + vxor(20, 20, 16) \ + BYTESWAPX(21, 20) \ + stxvw4x(53, %[cc], %[buf]) \ + addi(%[buf], %[buf], 16) \ + vand(16, 22, 22) \ + \ + bdnz(loop) \ + \ + /* \ + * Store back counter and CBC-MAC value. \ + */ \ + BYTESWAP(16) \ + BYTESWAP(17) \ + stxvw4x(48, %[cc], %[ctr]) \ + stxvw4x(49, %[cc], %[cbcmac]) \ + \ +: [cc] "+b" (cc), [buf] "+b" (buf) \ +: [sk] "b" (sk), [ctr] "b" (ctr), [cbcmac] "b" (cbcmac), \ + [num_blocks] "b" (num_blocks), [ctrinc] "b" (ctrinc) \ + BYTESWAP_REG \ +: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \ + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \ + "v30", "ctr", "memory" \ + ); \ +} + +MKDECRYPT(128) +MKDECRYPT(192) +MKDECRYPT(256) + +/* see bearssl_block.h */ +void +br_aes_pwr8_ctrcbc_encrypt(const br_aes_pwr8_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len) +{ + if (len == 0) { + return; + } + switch (ctx->num_rounds) { + case 10: + ctrcbc_128_encrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4); + break; + case 12: + ctrcbc_192_encrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4); + break; + default: + ctrcbc_256_encrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4); + break; + } +} + +/* see bearssl_block.h */ +void +br_aes_pwr8_ctrcbc_decrypt(const br_aes_pwr8_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len) +{ + if (len == 0) { + return; + } + switch (ctx->num_rounds) { + case 10: + ctrcbc_128_decrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4); + break; + case 12: + ctrcbc_192_decrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4); + break; + default: + ctrcbc_256_decrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4); + break; + } +} + +static inline void +incr_ctr(void *dst, const void *src) +{ + uint64_t hi, lo; + + hi = br_dec64be(src); + lo = br_dec64be((const unsigned char *)src + 8); + lo ++; + hi += ((lo | -lo) >> 63) ^ (uint64_t)1; + br_enc64be(dst, hi); + br_enc64be((unsigned char *)dst + 8, lo); +} + +/* see bearssl_block.h */ +void +br_aes_pwr8_ctrcbc_ctr(const br_aes_pwr8_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len) +{ + unsigned char ctrbuf[64]; + + memcpy(ctrbuf, ctr, 16); + incr_ctr(ctrbuf + 16, ctrbuf); + incr_ctr(ctrbuf + 32, ctrbuf + 16); + incr_ctr(ctrbuf + 48, ctrbuf + 32); + if (len >= 64) { + switch (ctx->num_rounds) { + case 10: + ctr_128(ctx->skey.skni, ctrbuf, data, len >> 6); + break; + case 12: + ctr_192(ctx->skey.skni, ctrbuf, data, len >> 6); + break; + default: + ctr_256(ctx->skey.skni, ctrbuf, data, len >> 6); + break; + } + data = (unsigned char *)data + (len & ~(size_t)63); + len &= 63; + } + if (len > 0) { + unsigned char tmp[64]; + + if (len >= 32) { + if (len >= 48) { + memcpy(ctr, ctrbuf + 48, 16); + } else { + memcpy(ctr, ctrbuf + 32, 16); + } + } else { + if (len >= 16) { + memcpy(ctr, ctrbuf + 16, 16); + } + } + memcpy(tmp, data, len); + memset(tmp + len, 0, (sizeof tmp) - len); + switch (ctx->num_rounds) { + case 10: + ctr_128(ctx->skey.skni, ctrbuf, tmp, 1); + break; + case 12: + ctr_192(ctx->skey.skni, ctrbuf, tmp, 1); + break; + default: + ctr_256(ctx->skey.skni, ctrbuf, tmp, 1); + break; + } + memcpy(data, tmp, len); + } else { + memcpy(ctr, ctrbuf, 16); + } +} + +/* see bearssl_block.h */ +void +br_aes_pwr8_ctrcbc_mac(const br_aes_pwr8_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len) +{ + if (len > 0) { + switch (ctx->num_rounds) { + case 10: + cbcmac_128(ctx->skey.skni, cbcmac, data, len >> 4); + break; + case 12: + cbcmac_192(ctx->skey.skni, cbcmac, data, len >> 4); + break; + default: + cbcmac_256(ctx->skey.skni, cbcmac, data, len >> 4); + break; + } + } +} + +/* see bearssl_block.h */ +const br_block_ctrcbc_class br_aes_pwr8_ctrcbc_vtable = { + sizeof(br_aes_pwr8_ctrcbc_keys), + 16, + 4, + (void (*)(const br_block_ctrcbc_class **, const void *, size_t)) + &br_aes_pwr8_ctrcbc_init, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, void *, size_t)) + &br_aes_pwr8_ctrcbc_encrypt, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, void *, size_t)) + &br_aes_pwr8_ctrcbc_decrypt, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, size_t)) + &br_aes_pwr8_ctrcbc_ctr, + (void (*)(const br_block_ctrcbc_class *const *, + void *, const void *, size_t)) + &br_aes_pwr8_ctrcbc_mac +}; + +#else + +/* see bearssl_block.h */ +const br_block_ctrcbc_class * +br_aes_pwr8_ctrcbc_get_vtable(void) +{ + return NULL; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_small_cbcdec.c b/BearSSL-OG/libbearssl/src/symcipher/aes_small_cbcdec.c new file mode 100644 index 0000000..8567244 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_small_cbcdec.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_small_cbcdec_init(br_aes_small_cbcdec_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_small_cbcdec_vtable; + ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); +} + +/* see bearssl_block.h */ +void +br_aes_small_cbcdec_run(const br_aes_small_cbcdec_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf, *ivbuf; + + ivbuf = iv; + buf = data; + while (len > 0) { + unsigned char tmp[16]; + int i; + + memcpy(tmp, buf, 16); + br_aes_small_decrypt(ctx->num_rounds, ctx->skey, buf); + for (i = 0; i < 16; i ++) { + buf[i] ^= ivbuf[i]; + } + memcpy(ivbuf, tmp, 16); + buf += 16; + len -= 16; + } +} + +/* see bearssl_block.h */ +const br_block_cbcdec_class br_aes_small_cbcdec_vtable = { + sizeof(br_aes_small_cbcdec_keys), + 16, + 4, + (void (*)(const br_block_cbcdec_class **, const void *, size_t)) + &br_aes_small_cbcdec_init, + (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) + &br_aes_small_cbcdec_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_small_cbcenc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_small_cbcenc.c new file mode 100644 index 0000000..0dc2910 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_small_cbcenc.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_small_cbcenc_init(br_aes_small_cbcenc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_small_cbcenc_vtable; + ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); +} + +/* see bearssl_block.h */ +void +br_aes_small_cbcenc_run(const br_aes_small_cbcenc_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf, *ivbuf; + + ivbuf = iv; + buf = data; + while (len > 0) { + int i; + + for (i = 0; i < 16; i ++) { + buf[i] ^= ivbuf[i]; + } + br_aes_small_encrypt(ctx->num_rounds, ctx->skey, buf); + memcpy(ivbuf, buf, 16); + buf += 16; + len -= 16; + } +} + +/* see bearssl_block.h */ +const br_block_cbcenc_class br_aes_small_cbcenc_vtable = { + sizeof(br_aes_small_cbcenc_keys), + 16, + 4, + (void (*)(const br_block_cbcenc_class **, const void *, size_t)) + &br_aes_small_cbcenc_init, + (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) + &br_aes_small_cbcenc_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_small_ctr.c b/BearSSL-OG/libbearssl/src/symcipher/aes_small_ctr.c new file mode 100644 index 0000000..d5d371c --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_small_ctr.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_small_ctr_init(br_aes_small_ctr_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_small_ctr_vtable; + ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); +} + +static void +xorbuf(void *dst, const void *src, size_t len) +{ + unsigned char *d; + const unsigned char *s; + + d = dst; + s = src; + while (len -- > 0) { + *d ++ ^= *s ++; + } +} + +/* see bearssl_block.h */ +uint32_t +br_aes_small_ctr_run(const br_aes_small_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len) +{ + unsigned char *buf; + + buf = data; + while (len > 0) { + unsigned char tmp[16]; + + memcpy(tmp, iv, 12); + br_enc32be(tmp + 12, cc ++); + br_aes_small_encrypt(ctx->num_rounds, ctx->skey, tmp); + if (len <= 16) { + xorbuf(buf, tmp, len); + break; + } + xorbuf(buf, tmp, 16); + buf += 16; + len -= 16; + } + return cc; +} + +/* see bearssl_block.h */ +const br_block_ctr_class br_aes_small_ctr_vtable = { + sizeof(br_aes_small_ctr_keys), + 16, + 4, + (void (*)(const br_block_ctr_class **, const void *, size_t)) + &br_aes_small_ctr_init, + (uint32_t (*)(const br_block_ctr_class *const *, + const void *, uint32_t, void *, size_t)) + &br_aes_small_ctr_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_small_ctrcbc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_small_ctrcbc.c new file mode 100644 index 0000000..2d6ba32 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_small_ctrcbc.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_aes_small_ctrcbc_init(br_aes_small_ctrcbc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_small_ctrcbc_vtable; + ctx->num_rounds = br_aes_keysched(ctx->skey, key, len); +} + +static void +xorbuf(void *dst, const void *src, size_t len) +{ + unsigned char *d; + const unsigned char *s; + + d = dst; + s = src; + while (len -- > 0) { + *d ++ ^= *s ++; + } +} + +/* see bearssl_block.h */ +void +br_aes_small_ctrcbc_ctr(const br_aes_small_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len) +{ + unsigned char *buf, *bctr; + uint32_t cc0, cc1, cc2, cc3; + + buf = data; + bctr = ctr; + cc3 = br_dec32be(bctr + 0); + cc2 = br_dec32be(bctr + 4); + cc1 = br_dec32be(bctr + 8); + cc0 = br_dec32be(bctr + 12); + while (len > 0) { + unsigned char tmp[16]; + uint32_t carry; + + br_enc32be(tmp + 0, cc3); + br_enc32be(tmp + 4, cc2); + br_enc32be(tmp + 8, cc1); + br_enc32be(tmp + 12, cc0); + br_aes_small_encrypt(ctx->num_rounds, ctx->skey, tmp); + xorbuf(buf, tmp, 16); + buf += 16; + len -= 16; + cc0 ++; + carry = (~(cc0 | -cc0)) >> 31; + cc1 += carry; + carry &= (~(cc1 | -cc1)) >> 31; + cc2 += carry; + carry &= (~(cc2 | -cc2)) >> 31; + cc3 += carry; + } + br_enc32be(bctr + 0, cc3); + br_enc32be(bctr + 4, cc2); + br_enc32be(bctr + 8, cc1); + br_enc32be(bctr + 12, cc0); +} + +/* see bearssl_block.h */ +void +br_aes_small_ctrcbc_mac(const br_aes_small_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len) +{ + const unsigned char *buf; + + buf = data; + while (len > 0) { + xorbuf(cbcmac, buf, 16); + br_aes_small_encrypt(ctx->num_rounds, ctx->skey, cbcmac); + buf += 16; + len -= 16; + } +} + +/* see bearssl_block.h */ +void +br_aes_small_ctrcbc_encrypt(const br_aes_small_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len) +{ + br_aes_small_ctrcbc_ctr(ctx, ctr, data, len); + br_aes_small_ctrcbc_mac(ctx, cbcmac, data, len); +} + +/* see bearssl_block.h */ +void +br_aes_small_ctrcbc_decrypt(const br_aes_small_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len) +{ + br_aes_small_ctrcbc_mac(ctx, cbcmac, data, len); + br_aes_small_ctrcbc_ctr(ctx, ctr, data, len); +} + +/* see bearssl_block.h */ +const br_block_ctrcbc_class br_aes_small_ctrcbc_vtable = { + sizeof(br_aes_small_ctrcbc_keys), + 16, + 4, + (void (*)(const br_block_ctrcbc_class **, const void *, size_t)) + &br_aes_small_ctrcbc_init, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, void *, size_t)) + &br_aes_small_ctrcbc_encrypt, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, void *, size_t)) + &br_aes_small_ctrcbc_decrypt, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, size_t)) + &br_aes_small_ctrcbc_ctr, + (void (*)(const br_block_ctrcbc_class *const *, + void *, const void *, size_t)) + &br_aes_small_ctrcbc_mac +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_small_dec.c b/BearSSL-OG/libbearssl/src/symcipher/aes_small_dec.c new file mode 100644 index 0000000..610ff13 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_small_dec.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Inverse S-box. + */ +static const unsigned char iS[] = { + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, + 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, + 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, + 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, + 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, + 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, + 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, + 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, + 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, + 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, + 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, + 0x55, 0x21, 0x0C, 0x7D +}; + +static void +add_round_key(unsigned *state, const uint32_t *skeys) +{ + int i; + + for (i = 0; i < 16; i += 4) { + uint32_t k; + + k = *skeys ++; + state[i + 0] ^= (unsigned)(k >> 24); + state[i + 1] ^= (unsigned)(k >> 16) & 0xFF; + state[i + 2] ^= (unsigned)(k >> 8) & 0xFF; + state[i + 3] ^= (unsigned)k & 0xFF; + } +} + +static void +inv_sub_bytes(unsigned *state) +{ + int i; + + for (i = 0; i < 16; i ++) { + state[i] = iS[state[i]]; + } +} + +static void +inv_shift_rows(unsigned *state) +{ + unsigned tmp; + + tmp = state[13]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = state[1]; + state[1] = tmp; + + tmp = state[2]; + state[2] = state[10]; + state[10] = tmp; + tmp = state[6]; + state[6] = state[14]; + state[14] = tmp; + + tmp = state[3]; + state[3] = state[7]; + state[7] = state[11]; + state[11] = state[15]; + state[15] = tmp; +} + +static __inline unsigned +gf256red(unsigned x) +{ + unsigned y; + + y = x >> 8; + return (x ^ y ^ (y << 1) ^ (y << 3) ^ (y << 4)) & 0xFF; +} + +static void +inv_mix_columns(unsigned *state) +{ + int i; + + for (i = 0; i < 16; i += 4) { + unsigned s0, s1, s2, s3; + unsigned t0, t1, t2, t3; + + s0 = state[i + 0]; + s1 = state[i + 1]; + s2 = state[i + 2]; + s3 = state[i + 3]; + t0 = (s0 << 1) ^ (s0 << 2) ^ (s0 << 3) + ^ s1 ^ (s1 << 1) ^ (s1 << 3) + ^ s2 ^ (s2 << 2) ^ (s2 << 3) + ^ s3 ^ (s3 << 3); + t1 = s0 ^ (s0 << 3) + ^ (s1 << 1) ^ (s1 << 2) ^ (s1 << 3) + ^ s2 ^ (s2 << 1) ^ (s2 << 3) + ^ s3 ^ (s3 << 2) ^ (s3 << 3); + t2 = s0 ^ (s0 << 2) ^ (s0 << 3) + ^ s1 ^ (s1 << 3) + ^ (s2 << 1) ^ (s2 << 2) ^ (s2 << 3) + ^ s3 ^ (s3 << 1) ^ (s3 << 3); + t3 = s0 ^ (s0 << 1) ^ (s0 << 3) + ^ s1 ^ (s1 << 2) ^ (s1 << 3) + ^ s2 ^ (s2 << 3) + ^ (s3 << 1) ^ (s3 << 2) ^ (s3 << 3); + state[i + 0] = gf256red(t0); + state[i + 1] = gf256red(t1); + state[i + 2] = gf256red(t2); + state[i + 3] = gf256red(t3); + } +} + +/* see inner.h */ +void +br_aes_small_decrypt(unsigned num_rounds, const uint32_t *skey, void *data) +{ + unsigned char *buf; + unsigned state[16]; + unsigned u; + + buf = data; + for (u = 0; u < 16; u ++) { + state[u] = buf[u]; + } + add_round_key(state, skey + (num_rounds << 2)); + for (u = num_rounds - 1; u > 0; u --) { + inv_shift_rows(state); + inv_sub_bytes(state); + add_round_key(state, skey + (u << 2)); + inv_mix_columns(state); + } + inv_shift_rows(state); + inv_sub_bytes(state); + add_round_key(state, skey); + for (u = 0; u < 16; u ++) { + buf[u] = state[u]; + } +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_small_enc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_small_enc.c new file mode 100644 index 0000000..29f48a8 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_small_enc.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#define S br_aes_S + +static void +add_round_key(unsigned *state, const uint32_t *skeys) +{ + int i; + + for (i = 0; i < 16; i += 4) { + uint32_t k; + + k = *skeys ++; + state[i + 0] ^= (unsigned)(k >> 24); + state[i + 1] ^= (unsigned)(k >> 16) & 0xFF; + state[i + 2] ^= (unsigned)(k >> 8) & 0xFF; + state[i + 3] ^= (unsigned)k & 0xFF; + } +} + +static void +sub_bytes(unsigned *state) +{ + int i; + + for (i = 0; i < 16; i ++) { + state[i] = S[state[i]]; + } +} + +static void +shift_rows(unsigned *state) +{ + unsigned tmp; + + tmp = state[1]; + state[1] = state[5]; + state[5] = state[9]; + state[9] = state[13]; + state[13] = tmp; + + tmp = state[2]; + state[2] = state[10]; + state[10] = tmp; + tmp = state[6]; + state[6] = state[14]; + state[14] = tmp; + + tmp = state[15]; + state[15] = state[11]; + state[11] = state[7]; + state[7] = state[3]; + state[3] = tmp; +} + +static void +mix_columns(unsigned *state) +{ + int i; + + for (i = 0; i < 16; i += 4) { + unsigned s0, s1, s2, s3; + unsigned t0, t1, t2, t3; + + s0 = state[i + 0]; + s1 = state[i + 1]; + s2 = state[i + 2]; + s3 = state[i + 3]; + t0 = (s0 << 1) ^ s1 ^ (s1 << 1) ^ s2 ^ s3; + t1 = s0 ^ (s1 << 1) ^ s2 ^ (s2 << 1) ^ s3; + t2 = s0 ^ s1 ^ (s2 << 1) ^ s3 ^ (s3 << 1); + t3 = s0 ^ (s0 << 1) ^ s1 ^ s2 ^ (s3 << 1); + state[i + 0] = t0 ^ ((unsigned)(-(int)(t0 >> 8)) & 0x11B); + state[i + 1] = t1 ^ ((unsigned)(-(int)(t1 >> 8)) & 0x11B); + state[i + 2] = t2 ^ ((unsigned)(-(int)(t2 >> 8)) & 0x11B); + state[i + 3] = t3 ^ ((unsigned)(-(int)(t3 >> 8)) & 0x11B); + } +} + +/* see inner.h */ +void +br_aes_small_encrypt(unsigned num_rounds, const uint32_t *skey, void *data) +{ + unsigned char *buf; + unsigned state[16]; + unsigned u; + + buf = data; + for (u = 0; u < 16; u ++) { + state[u] = buf[u]; + } + add_round_key(state, skey); + for (u = 1; u < num_rounds; u ++) { + sub_bytes(state); + shift_rows(state); + mix_columns(state); + add_round_key(state, skey + (u << 2)); + } + sub_bytes(state); + shift_rows(state); + add_round_key(state, skey + (num_rounds << 2)); + for (u = 0; u < 16; u ++) { + buf[u] = state[u]; + } +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni.c b/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni.c new file mode 100644 index 0000000..d5408f1 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_ENABLE_INTRINSICS 1 +#include "inner.h" + +/* + * This code contains the AES key schedule implementation using the + * AES-NI opcodes. + */ + +#if BR_AES_X86NI + +/* see inner.h */ +int +br_aes_x86ni_supported(void) +{ + /* + * Bit mask for features in ECX: + * 19 SSE4.1 (used for _mm_insert_epi32(), for AES-CTR) + * 25 AES-NI + */ + return br_cpuid(0, 0, 0x02080000, 0); +} + +BR_TARGETS_X86_UP + +BR_TARGET("sse2,aes") +static inline __m128i +expand_step128(__m128i k, __m128i k2) +{ + k = _mm_xor_si128(k, _mm_slli_si128(k, 4)); + k = _mm_xor_si128(k, _mm_slli_si128(k, 4)); + k = _mm_xor_si128(k, _mm_slli_si128(k, 4)); + k2 = _mm_shuffle_epi32(k2, 0xFF); + return _mm_xor_si128(k, k2); +} + +BR_TARGET("sse2,aes") +static inline void +expand_step192(__m128i *t1, __m128i *t2, __m128i *t3) +{ + __m128i t4; + + *t2 = _mm_shuffle_epi32(*t2, 0x55); + t4 = _mm_slli_si128(*t1, 0x4); + *t1 = _mm_xor_si128(*t1, t4); + t4 = _mm_slli_si128(t4, 0x4); + *t1 = _mm_xor_si128(*t1, t4); + t4 = _mm_slli_si128(t4, 0x4); + *t1 = _mm_xor_si128(*t1, t4); + *t1 = _mm_xor_si128(*t1, *t2); + *t2 = _mm_shuffle_epi32(*t1, 0xFF); + t4 = _mm_slli_si128(*t3, 0x4); + *t3 = _mm_xor_si128(*t3, t4); + *t3 = _mm_xor_si128(*t3, *t2); +} + +BR_TARGET("sse2,aes") +static inline void +expand_step256_1(__m128i *t1, __m128i *t2) +{ + __m128i t4; + + *t2 = _mm_shuffle_epi32(*t2, 0xFF); + t4 = _mm_slli_si128(*t1, 0x4); + *t1 = _mm_xor_si128(*t1, t4); + t4 = _mm_slli_si128(t4, 0x4); + *t1 = _mm_xor_si128(*t1, t4); + t4 = _mm_slli_si128(t4, 0x4); + *t1 = _mm_xor_si128(*t1, t4); + *t1 = _mm_xor_si128(*t1, *t2); +} + +BR_TARGET("sse2,aes") +static inline void +expand_step256_2(__m128i *t1, __m128i *t3) +{ + __m128i t2, t4; + + t4 = _mm_aeskeygenassist_si128(*t1, 0x0); + t2 = _mm_shuffle_epi32(t4, 0xAA); + t4 = _mm_slli_si128(*t3, 0x4); + *t3 = _mm_xor_si128(*t3, t4); + t4 = _mm_slli_si128(t4, 0x4); + *t3 = _mm_xor_si128(*t3, t4); + t4 = _mm_slli_si128(t4, 0x4); + *t3 = _mm_xor_si128(*t3, t4); + *t3 = _mm_xor_si128(*t3, t2); +} + +/* + * Perform key schedule for AES, encryption direction. Subkeys are written + * in sk[], and the number of rounds is returned. Key length MUST be 16, + * 24 or 32 bytes. + */ +BR_TARGET("sse2,aes") +static unsigned +x86ni_keysched(__m128i *sk, const void *key, size_t len) +{ + const unsigned char *kb; + +#define KEXP128(k, i, rcon) do { \ + k = expand_step128(k, _mm_aeskeygenassist_si128(k, rcon)); \ + sk[i] = k; \ + } while (0) + +#define KEXP192(i, rcon1, rcon2) do { \ + sk[(i) + 0] = t1; \ + sk[(i) + 1] = t3; \ + t2 = _mm_aeskeygenassist_si128(t3, rcon1); \ + expand_step192(&t1, &t2, &t3); \ + sk[(i) + 1] = _mm_castpd_si128(_mm_shuffle_pd( \ + _mm_castsi128_pd(sk[(i) + 1]), \ + _mm_castsi128_pd(t1), 0)); \ + sk[(i) + 2] = _mm_castpd_si128(_mm_shuffle_pd( \ + _mm_castsi128_pd(t1), \ + _mm_castsi128_pd(t3), 1)); \ + t2 = _mm_aeskeygenassist_si128(t3, rcon2); \ + expand_step192(&t1, &t2, &t3); \ + } while (0) + +#define KEXP256(i, rcon) do { \ + sk[(i) + 0] = t3; \ + t2 = _mm_aeskeygenassist_si128(t3, rcon); \ + expand_step256_1(&t1, &t2); \ + sk[(i) + 1] = t1; \ + expand_step256_2(&t1, &t3); \ + } while (0) + + kb = key; + switch (len) { + __m128i t1, t2, t3; + + case 16: + t1 = _mm_loadu_si128((const void *)kb); + sk[0] = t1; + KEXP128(t1, 1, 0x01); + KEXP128(t1, 2, 0x02); + KEXP128(t1, 3, 0x04); + KEXP128(t1, 4, 0x08); + KEXP128(t1, 5, 0x10); + KEXP128(t1, 6, 0x20); + KEXP128(t1, 7, 0x40); + KEXP128(t1, 8, 0x80); + KEXP128(t1, 9, 0x1B); + KEXP128(t1, 10, 0x36); + return 10; + + case 24: + t1 = _mm_loadu_si128((const void *)kb); + t3 = _mm_loadu_si128((const void *)(kb + 8)); + t3 = _mm_shuffle_epi32(t3, 0x4E); + KEXP192(0, 0x01, 0x02); + KEXP192(3, 0x04, 0x08); + KEXP192(6, 0x10, 0x20); + KEXP192(9, 0x40, 0x80); + sk[12] = t1; + return 12; + + case 32: + t1 = _mm_loadu_si128((const void *)kb); + t3 = _mm_loadu_si128((const void *)(kb + 16)); + sk[0] = t1; + KEXP256( 1, 0x01); + KEXP256( 3, 0x02); + KEXP256( 5, 0x04); + KEXP256( 7, 0x08); + KEXP256( 9, 0x10); + KEXP256(11, 0x20); + sk[13] = t3; + t2 = _mm_aeskeygenassist_si128(t3, 0x40); + expand_step256_1(&t1, &t2); + sk[14] = t1; + return 14; + + default: + return 0; + } + +#undef KEXP128 +#undef KEXP192 +#undef KEXP256 +} + +/* see inner.h */ +BR_TARGET("sse2,aes") +unsigned +br_aes_x86ni_keysched_enc(unsigned char *skni, const void *key, size_t len) +{ + __m128i sk[15]; + unsigned num_rounds; + + num_rounds = x86ni_keysched(sk, key, len); + memcpy(skni, sk, (num_rounds + 1) << 4); + return num_rounds; +} + +/* see inner.h */ +BR_TARGET("sse2,aes") +unsigned +br_aes_x86ni_keysched_dec(unsigned char *skni, const void *key, size_t len) +{ + __m128i sk[15]; + unsigned u, num_rounds; + + num_rounds = x86ni_keysched(sk, key, len); + _mm_storeu_si128((void *)skni, sk[num_rounds]); + for (u = 1; u < num_rounds; u ++) { + _mm_storeu_si128((void *)(skni + (u << 4)), + _mm_aesimc_si128(sk[num_rounds - u])); + } + _mm_storeu_si128((void *)(skni + (num_rounds << 4)), sk[0]); + return num_rounds; +} + +BR_TARGETS_X86_DOWN + +#endif diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni_cbcdec.c b/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni_cbcdec.c new file mode 100644 index 0000000..862b1b5 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni_cbcdec.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_ENABLE_INTRINSICS 1 +#include "inner.h" + +#if BR_AES_X86NI + +/* see bearssl_block.h */ +const br_block_cbcdec_class * +br_aes_x86ni_cbcdec_get_vtable(void) +{ + return br_aes_x86ni_supported() ? &br_aes_x86ni_cbcdec_vtable : NULL; +} + +/* see bearssl_block.h */ +void +br_aes_x86ni_cbcdec_init(br_aes_x86ni_cbcdec_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_x86ni_cbcdec_vtable; + ctx->num_rounds = br_aes_x86ni_keysched_dec(ctx->skey.skni, key, len); +} + +BR_TARGETS_X86_UP + +/* see bearssl_block.h */ +BR_TARGET("sse2,aes") +void +br_aes_x86ni_cbcdec_run(const br_aes_x86ni_cbcdec_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf; + unsigned num_rounds; + __m128i sk[15], ivx; + unsigned u; + + buf = data; + ivx = _mm_loadu_si128(iv); + num_rounds = ctx->num_rounds; + for (u = 0; u <= num_rounds; u ++) { + sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4))); + } + while (len > 0) { + __m128i x0, x1, x2, x3, e0, e1, e2, e3; + + x0 = _mm_loadu_si128((void *)(buf + 0)); + if (len >= 64) { + x1 = _mm_loadu_si128((void *)(buf + 16)); + x2 = _mm_loadu_si128((void *)(buf + 32)); + x3 = _mm_loadu_si128((void *)(buf + 48)); + } else { + x0 = _mm_loadu_si128((void *)(buf + 0)); + if (len >= 32) { + x1 = _mm_loadu_si128((void *)(buf + 16)); + if (len >= 48) { + x2 = _mm_loadu_si128( + (void *)(buf + 32)); + x3 = x2; + } else { + x2 = x0; + x3 = x1; + } + } else { + x1 = x0; + x2 = x0; + x3 = x0; + } + } + e0 = x0; + e1 = x1; + e2 = x2; + e3 = x3; + x0 = _mm_xor_si128(x0, sk[0]); + x1 = _mm_xor_si128(x1, sk[0]); + x2 = _mm_xor_si128(x2, sk[0]); + x3 = _mm_xor_si128(x3, sk[0]); + x0 = _mm_aesdec_si128(x0, sk[1]); + x1 = _mm_aesdec_si128(x1, sk[1]); + x2 = _mm_aesdec_si128(x2, sk[1]); + x3 = _mm_aesdec_si128(x3, sk[1]); + x0 = _mm_aesdec_si128(x0, sk[2]); + x1 = _mm_aesdec_si128(x1, sk[2]); + x2 = _mm_aesdec_si128(x2, sk[2]); + x3 = _mm_aesdec_si128(x3, sk[2]); + x0 = _mm_aesdec_si128(x0, sk[3]); + x1 = _mm_aesdec_si128(x1, sk[3]); + x2 = _mm_aesdec_si128(x2, sk[3]); + x3 = _mm_aesdec_si128(x3, sk[3]); + x0 = _mm_aesdec_si128(x0, sk[4]); + x1 = _mm_aesdec_si128(x1, sk[4]); + x2 = _mm_aesdec_si128(x2, sk[4]); + x3 = _mm_aesdec_si128(x3, sk[4]); + x0 = _mm_aesdec_si128(x0, sk[5]); + x1 = _mm_aesdec_si128(x1, sk[5]); + x2 = _mm_aesdec_si128(x2, sk[5]); + x3 = _mm_aesdec_si128(x3, sk[5]); + x0 = _mm_aesdec_si128(x0, sk[6]); + x1 = _mm_aesdec_si128(x1, sk[6]); + x2 = _mm_aesdec_si128(x2, sk[6]); + x3 = _mm_aesdec_si128(x3, sk[6]); + x0 = _mm_aesdec_si128(x0, sk[7]); + x1 = _mm_aesdec_si128(x1, sk[7]); + x2 = _mm_aesdec_si128(x2, sk[7]); + x3 = _mm_aesdec_si128(x3, sk[7]); + x0 = _mm_aesdec_si128(x0, sk[8]); + x1 = _mm_aesdec_si128(x1, sk[8]); + x2 = _mm_aesdec_si128(x2, sk[8]); + x3 = _mm_aesdec_si128(x3, sk[8]); + x0 = _mm_aesdec_si128(x0, sk[9]); + x1 = _mm_aesdec_si128(x1, sk[9]); + x2 = _mm_aesdec_si128(x2, sk[9]); + x3 = _mm_aesdec_si128(x3, sk[9]); + if (num_rounds == 10) { + x0 = _mm_aesdeclast_si128(x0, sk[10]); + x1 = _mm_aesdeclast_si128(x1, sk[10]); + x2 = _mm_aesdeclast_si128(x2, sk[10]); + x3 = _mm_aesdeclast_si128(x3, sk[10]); + } else if (num_rounds == 12) { + x0 = _mm_aesdec_si128(x0, sk[10]); + x1 = _mm_aesdec_si128(x1, sk[10]); + x2 = _mm_aesdec_si128(x2, sk[10]); + x3 = _mm_aesdec_si128(x3, sk[10]); + x0 = _mm_aesdec_si128(x0, sk[11]); + x1 = _mm_aesdec_si128(x1, sk[11]); + x2 = _mm_aesdec_si128(x2, sk[11]); + x3 = _mm_aesdec_si128(x3, sk[11]); + x0 = _mm_aesdeclast_si128(x0, sk[12]); + x1 = _mm_aesdeclast_si128(x1, sk[12]); + x2 = _mm_aesdeclast_si128(x2, sk[12]); + x3 = _mm_aesdeclast_si128(x3, sk[12]); + } else { + x0 = _mm_aesdec_si128(x0, sk[10]); + x1 = _mm_aesdec_si128(x1, sk[10]); + x2 = _mm_aesdec_si128(x2, sk[10]); + x3 = _mm_aesdec_si128(x3, sk[10]); + x0 = _mm_aesdec_si128(x0, sk[11]); + x1 = _mm_aesdec_si128(x1, sk[11]); + x2 = _mm_aesdec_si128(x2, sk[11]); + x3 = _mm_aesdec_si128(x3, sk[11]); + x0 = _mm_aesdec_si128(x0, sk[12]); + x1 = _mm_aesdec_si128(x1, sk[12]); + x2 = _mm_aesdec_si128(x2, sk[12]); + x3 = _mm_aesdec_si128(x3, sk[12]); + x0 = _mm_aesdec_si128(x0, sk[13]); + x1 = _mm_aesdec_si128(x1, sk[13]); + x2 = _mm_aesdec_si128(x2, sk[13]); + x3 = _mm_aesdec_si128(x3, sk[13]); + x0 = _mm_aesdeclast_si128(x0, sk[14]); + x1 = _mm_aesdeclast_si128(x1, sk[14]); + x2 = _mm_aesdeclast_si128(x2, sk[14]); + x3 = _mm_aesdeclast_si128(x3, sk[14]); + } + x0 = _mm_xor_si128(x0, ivx); + x1 = _mm_xor_si128(x1, e0); + x2 = _mm_xor_si128(x2, e1); + x3 = _mm_xor_si128(x3, e2); + ivx = e3; + _mm_storeu_si128((void *)(buf + 0), x0); + if (len >= 64) { + _mm_storeu_si128((void *)(buf + 16), x1); + _mm_storeu_si128((void *)(buf + 32), x2); + _mm_storeu_si128((void *)(buf + 48), x3); + buf += 64; + len -= 64; + } else { + if (len >= 32) { + _mm_storeu_si128((void *)(buf + 16), x1); + if (len >= 48) { + _mm_storeu_si128( + (void *)(buf + 32), x2); + } + } + break; + } + } + _mm_storeu_si128(iv, ivx); +} + +BR_TARGETS_X86_DOWN + +/* see bearssl_block.h */ +const br_block_cbcdec_class br_aes_x86ni_cbcdec_vtable = { + sizeof(br_aes_x86ni_cbcdec_keys), + 16, + 4, + (void (*)(const br_block_cbcdec_class **, const void *, size_t)) + &br_aes_x86ni_cbcdec_init, + (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) + &br_aes_x86ni_cbcdec_run +}; + +#else + +/* see bearssl_block.h */ +const br_block_cbcdec_class * +br_aes_x86ni_cbcdec_get_vtable(void) +{ + return NULL; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni_cbcenc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni_cbcenc.c new file mode 100644 index 0000000..85feecd --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni_cbcenc.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_ENABLE_INTRINSICS 1 +#include "inner.h" + +#if BR_AES_X86NI + +/* see bearssl_block.h */ +const br_block_cbcenc_class * +br_aes_x86ni_cbcenc_get_vtable(void) +{ + return br_aes_x86ni_supported() ? &br_aes_x86ni_cbcenc_vtable : NULL; +} + +/* see bearssl_block.h */ +void +br_aes_x86ni_cbcenc_init(br_aes_x86ni_cbcenc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_x86ni_cbcenc_vtable; + ctx->num_rounds = br_aes_x86ni_keysched_enc(ctx->skey.skni, key, len); +} + +BR_TARGETS_X86_UP + +/* see bearssl_block.h */ +BR_TARGET("sse2,aes") +void +br_aes_x86ni_cbcenc_run(const br_aes_x86ni_cbcenc_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf; + unsigned num_rounds; + __m128i sk[15], ivx; + unsigned u; + + buf = data; + ivx = _mm_loadu_si128(iv); + num_rounds = ctx->num_rounds; + for (u = 0; u <= num_rounds; u ++) { + sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4))); + } + while (len > 0) { + __m128i x; + + x = _mm_xor_si128(_mm_loadu_si128((void *)buf), ivx); + x = _mm_xor_si128(x, sk[0]); + x = _mm_aesenc_si128(x, sk[1]); + x = _mm_aesenc_si128(x, sk[2]); + x = _mm_aesenc_si128(x, sk[3]); + x = _mm_aesenc_si128(x, sk[4]); + x = _mm_aesenc_si128(x, sk[5]); + x = _mm_aesenc_si128(x, sk[6]); + x = _mm_aesenc_si128(x, sk[7]); + x = _mm_aesenc_si128(x, sk[8]); + x = _mm_aesenc_si128(x, sk[9]); + if (num_rounds == 10) { + x = _mm_aesenclast_si128(x, sk[10]); + } else if (num_rounds == 12) { + x = _mm_aesenc_si128(x, sk[10]); + x = _mm_aesenc_si128(x, sk[11]); + x = _mm_aesenclast_si128(x, sk[12]); + } else { + x = _mm_aesenc_si128(x, sk[10]); + x = _mm_aesenc_si128(x, sk[11]); + x = _mm_aesenc_si128(x, sk[12]); + x = _mm_aesenc_si128(x, sk[13]); + x = _mm_aesenclast_si128(x, sk[14]); + } + ivx = x; + _mm_storeu_si128((void *)buf, x); + buf += 16; + len -= 16; + } + _mm_storeu_si128(iv, ivx); +} + +BR_TARGETS_X86_DOWN + +/* see bearssl_block.h */ +const br_block_cbcenc_class br_aes_x86ni_cbcenc_vtable = { + sizeof(br_aes_x86ni_cbcenc_keys), + 16, + 4, + (void (*)(const br_block_cbcenc_class **, const void *, size_t)) + &br_aes_x86ni_cbcenc_init, + (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) + &br_aes_x86ni_cbcenc_run +}; + +#else + +/* see bearssl_block.h */ +const br_block_cbcenc_class * +br_aes_x86ni_cbcenc_get_vtable(void) +{ + return NULL; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni_ctr.c b/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni_ctr.c new file mode 100644 index 0000000..1cddd60 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni_ctr.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_ENABLE_INTRINSICS 1 +#include "inner.h" + +#if BR_AES_X86NI + +/* see bearssl_block.h */ +const br_block_ctr_class * +br_aes_x86ni_ctr_get_vtable(void) +{ + return br_aes_x86ni_supported() ? &br_aes_x86ni_ctr_vtable : NULL; +} + +/* see bearssl_block.h */ +void +br_aes_x86ni_ctr_init(br_aes_x86ni_ctr_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_x86ni_ctr_vtable; + ctx->num_rounds = br_aes_x86ni_keysched_enc(ctx->skey.skni, key, len); +} + +BR_TARGETS_X86_UP + +/* see bearssl_block.h */ +BR_TARGET("sse2,sse4.1,aes") +uint32_t +br_aes_x86ni_ctr_run(const br_aes_x86ni_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len) +{ + unsigned char *buf; + unsigned char ivbuf[16]; + unsigned num_rounds; + __m128i sk[15]; + __m128i ivx; + unsigned u; + + buf = data; + memcpy(ivbuf, iv, 12); + num_rounds = ctx->num_rounds; + for (u = 0; u <= num_rounds; u ++) { + sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4))); + } + ivx = _mm_loadu_si128((void *)ivbuf); + while (len > 0) { + __m128i x0, x1, x2, x3; + + x0 = _mm_insert_epi32(ivx, br_bswap32(cc + 0), 3); + x1 = _mm_insert_epi32(ivx, br_bswap32(cc + 1), 3); + x2 = _mm_insert_epi32(ivx, br_bswap32(cc + 2), 3); + x3 = _mm_insert_epi32(ivx, br_bswap32(cc + 3), 3); + x0 = _mm_xor_si128(x0, sk[0]); + x1 = _mm_xor_si128(x1, sk[0]); + x2 = _mm_xor_si128(x2, sk[0]); + x3 = _mm_xor_si128(x3, sk[0]); + x0 = _mm_aesenc_si128(x0, sk[1]); + x1 = _mm_aesenc_si128(x1, sk[1]); + x2 = _mm_aesenc_si128(x2, sk[1]); + x3 = _mm_aesenc_si128(x3, sk[1]); + x0 = _mm_aesenc_si128(x0, sk[2]); + x1 = _mm_aesenc_si128(x1, sk[2]); + x2 = _mm_aesenc_si128(x2, sk[2]); + x3 = _mm_aesenc_si128(x3, sk[2]); + x0 = _mm_aesenc_si128(x0, sk[3]); + x1 = _mm_aesenc_si128(x1, sk[3]); + x2 = _mm_aesenc_si128(x2, sk[3]); + x3 = _mm_aesenc_si128(x3, sk[3]); + x0 = _mm_aesenc_si128(x0, sk[4]); + x1 = _mm_aesenc_si128(x1, sk[4]); + x2 = _mm_aesenc_si128(x2, sk[4]); + x3 = _mm_aesenc_si128(x3, sk[4]); + x0 = _mm_aesenc_si128(x0, sk[5]); + x1 = _mm_aesenc_si128(x1, sk[5]); + x2 = _mm_aesenc_si128(x2, sk[5]); + x3 = _mm_aesenc_si128(x3, sk[5]); + x0 = _mm_aesenc_si128(x0, sk[6]); + x1 = _mm_aesenc_si128(x1, sk[6]); + x2 = _mm_aesenc_si128(x2, sk[6]); + x3 = _mm_aesenc_si128(x3, sk[6]); + x0 = _mm_aesenc_si128(x0, sk[7]); + x1 = _mm_aesenc_si128(x1, sk[7]); + x2 = _mm_aesenc_si128(x2, sk[7]); + x3 = _mm_aesenc_si128(x3, sk[7]); + x0 = _mm_aesenc_si128(x0, sk[8]); + x1 = _mm_aesenc_si128(x1, sk[8]); + x2 = _mm_aesenc_si128(x2, sk[8]); + x3 = _mm_aesenc_si128(x3, sk[8]); + x0 = _mm_aesenc_si128(x0, sk[9]); + x1 = _mm_aesenc_si128(x1, sk[9]); + x2 = _mm_aesenc_si128(x2, sk[9]); + x3 = _mm_aesenc_si128(x3, sk[9]); + if (num_rounds == 10) { + x0 = _mm_aesenclast_si128(x0, sk[10]); + x1 = _mm_aesenclast_si128(x1, sk[10]); + x2 = _mm_aesenclast_si128(x2, sk[10]); + x3 = _mm_aesenclast_si128(x3, sk[10]); + } else if (num_rounds == 12) { + x0 = _mm_aesenc_si128(x0, sk[10]); + x1 = _mm_aesenc_si128(x1, sk[10]); + x2 = _mm_aesenc_si128(x2, sk[10]); + x3 = _mm_aesenc_si128(x3, sk[10]); + x0 = _mm_aesenc_si128(x0, sk[11]); + x1 = _mm_aesenc_si128(x1, sk[11]); + x2 = _mm_aesenc_si128(x2, sk[11]); + x3 = _mm_aesenc_si128(x3, sk[11]); + x0 = _mm_aesenclast_si128(x0, sk[12]); + x1 = _mm_aesenclast_si128(x1, sk[12]); + x2 = _mm_aesenclast_si128(x2, sk[12]); + x3 = _mm_aesenclast_si128(x3, sk[12]); + } else { + x0 = _mm_aesenc_si128(x0, sk[10]); + x1 = _mm_aesenc_si128(x1, sk[10]); + x2 = _mm_aesenc_si128(x2, sk[10]); + x3 = _mm_aesenc_si128(x3, sk[10]); + x0 = _mm_aesenc_si128(x0, sk[11]); + x1 = _mm_aesenc_si128(x1, sk[11]); + x2 = _mm_aesenc_si128(x2, sk[11]); + x3 = _mm_aesenc_si128(x3, sk[11]); + x0 = _mm_aesenc_si128(x0, sk[12]); + x1 = _mm_aesenc_si128(x1, sk[12]); + x2 = _mm_aesenc_si128(x2, sk[12]); + x3 = _mm_aesenc_si128(x3, sk[12]); + x0 = _mm_aesenc_si128(x0, sk[13]); + x1 = _mm_aesenc_si128(x1, sk[13]); + x2 = _mm_aesenc_si128(x2, sk[13]); + x3 = _mm_aesenc_si128(x3, sk[13]); + x0 = _mm_aesenclast_si128(x0, sk[14]); + x1 = _mm_aesenclast_si128(x1, sk[14]); + x2 = _mm_aesenclast_si128(x2, sk[14]); + x3 = _mm_aesenclast_si128(x3, sk[14]); + } + if (len >= 64) { + x0 = _mm_xor_si128(x0, + _mm_loadu_si128((void *)(buf + 0))); + x1 = _mm_xor_si128(x1, + _mm_loadu_si128((void *)(buf + 16))); + x2 = _mm_xor_si128(x2, + _mm_loadu_si128((void *)(buf + 32))); + x3 = _mm_xor_si128(x3, + _mm_loadu_si128((void *)(buf + 48))); + _mm_storeu_si128((void *)(buf + 0), x0); + _mm_storeu_si128((void *)(buf + 16), x1); + _mm_storeu_si128((void *)(buf + 32), x2); + _mm_storeu_si128((void *)(buf + 48), x3); + buf += 64; + len -= 64; + cc += 4; + } else { + unsigned char tmp[64]; + + _mm_storeu_si128((void *)(tmp + 0), x0); + _mm_storeu_si128((void *)(tmp + 16), x1); + _mm_storeu_si128((void *)(tmp + 32), x2); + _mm_storeu_si128((void *)(tmp + 48), x3); + for (u = 0; u < len; u ++) { + buf[u] ^= tmp[u]; + } + cc += (uint32_t)len >> 4; + break; + } + } + return cc; +} + +BR_TARGETS_X86_DOWN + +/* see bearssl_block.h */ +const br_block_ctr_class br_aes_x86ni_ctr_vtable = { + sizeof(br_aes_x86ni_ctr_keys), + 16, + 4, + (void (*)(const br_block_ctr_class **, const void *, size_t)) + &br_aes_x86ni_ctr_init, + (uint32_t (*)(const br_block_ctr_class *const *, + const void *, uint32_t, void *, size_t)) + &br_aes_x86ni_ctr_run +}; + +#else + +/* see bearssl_block.h */ +const br_block_ctr_class * +br_aes_x86ni_ctr_get_vtable(void) +{ + return NULL; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni_ctrcbc.c b/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni_ctrcbc.c new file mode 100644 index 0000000..f57fead --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/aes_x86ni_ctrcbc.c @@ -0,0 +1,596 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_ENABLE_INTRINSICS 1 +#include "inner.h" + +#if BR_AES_X86NI + +/* see bearssl_block.h */ +const br_block_ctrcbc_class * +br_aes_x86ni_ctrcbc_get_vtable(void) +{ + return br_aes_x86ni_supported() ? &br_aes_x86ni_ctrcbc_vtable : NULL; +} + +/* see bearssl_block.h */ +void +br_aes_x86ni_ctrcbc_init(br_aes_x86ni_ctrcbc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_aes_x86ni_ctrcbc_vtable; + ctx->num_rounds = br_aes_x86ni_keysched_enc(ctx->skey.skni, key, len); +} + +BR_TARGETS_X86_UP + +/* see bearssl_block.h */ +BR_TARGET("sse2,sse4.1,aes") +void +br_aes_x86ni_ctrcbc_ctr(const br_aes_x86ni_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len) +{ + unsigned char *buf; + unsigned num_rounds; + __m128i sk[15]; + __m128i ivx0, ivx1, ivx2, ivx3; + __m128i erev, zero, one, four, notthree; + unsigned u; + + buf = data; + num_rounds = ctx->num_rounds; + for (u = 0; u <= num_rounds; u ++) { + sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4))); + } + + /* + * Some SSE2 constants. + */ + erev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15); + zero = _mm_setzero_si128(); + one = _mm_set_epi64x(0, 1); + four = _mm_set_epi64x(0, 4); + notthree = _mm_sub_epi64(zero, four); + + /* + * Decode the counter in big-endian and pre-increment the other + * three counters. + */ + ivx0 = _mm_shuffle_epi8(_mm_loadu_si128((void *)ctr), erev); + ivx1 = _mm_add_epi64(ivx0, one); + ivx1 = _mm_sub_epi64(ivx1, + _mm_slli_si128(_mm_cmpeq_epi64(ivx1, zero), 8)); + ivx2 = _mm_add_epi64(ivx1, one); + ivx2 = _mm_sub_epi64(ivx2, + _mm_slli_si128(_mm_cmpeq_epi64(ivx2, zero), 8)); + ivx3 = _mm_add_epi64(ivx2, one); + ivx3 = _mm_sub_epi64(ivx3, + _mm_slli_si128(_mm_cmpeq_epi64(ivx3, zero), 8)); + while (len > 0) { + __m128i x0, x1, x2, x3; + + /* + * Load counter values; we need to byteswap them because + * the specification says that they use big-endian. + */ + x0 = _mm_shuffle_epi8(ivx0, erev); + x1 = _mm_shuffle_epi8(ivx1, erev); + x2 = _mm_shuffle_epi8(ivx2, erev); + x3 = _mm_shuffle_epi8(ivx3, erev); + + x0 = _mm_xor_si128(x0, sk[0]); + x1 = _mm_xor_si128(x1, sk[0]); + x2 = _mm_xor_si128(x2, sk[0]); + x3 = _mm_xor_si128(x3, sk[0]); + x0 = _mm_aesenc_si128(x0, sk[1]); + x1 = _mm_aesenc_si128(x1, sk[1]); + x2 = _mm_aesenc_si128(x2, sk[1]); + x3 = _mm_aesenc_si128(x3, sk[1]); + x0 = _mm_aesenc_si128(x0, sk[2]); + x1 = _mm_aesenc_si128(x1, sk[2]); + x2 = _mm_aesenc_si128(x2, sk[2]); + x3 = _mm_aesenc_si128(x3, sk[2]); + x0 = _mm_aesenc_si128(x0, sk[3]); + x1 = _mm_aesenc_si128(x1, sk[3]); + x2 = _mm_aesenc_si128(x2, sk[3]); + x3 = _mm_aesenc_si128(x3, sk[3]); + x0 = _mm_aesenc_si128(x0, sk[4]); + x1 = _mm_aesenc_si128(x1, sk[4]); + x2 = _mm_aesenc_si128(x2, sk[4]); + x3 = _mm_aesenc_si128(x3, sk[4]); + x0 = _mm_aesenc_si128(x0, sk[5]); + x1 = _mm_aesenc_si128(x1, sk[5]); + x2 = _mm_aesenc_si128(x2, sk[5]); + x3 = _mm_aesenc_si128(x3, sk[5]); + x0 = _mm_aesenc_si128(x0, sk[6]); + x1 = _mm_aesenc_si128(x1, sk[6]); + x2 = _mm_aesenc_si128(x2, sk[6]); + x3 = _mm_aesenc_si128(x3, sk[6]); + x0 = _mm_aesenc_si128(x0, sk[7]); + x1 = _mm_aesenc_si128(x1, sk[7]); + x2 = _mm_aesenc_si128(x2, sk[7]); + x3 = _mm_aesenc_si128(x3, sk[7]); + x0 = _mm_aesenc_si128(x0, sk[8]); + x1 = _mm_aesenc_si128(x1, sk[8]); + x2 = _mm_aesenc_si128(x2, sk[8]); + x3 = _mm_aesenc_si128(x3, sk[8]); + x0 = _mm_aesenc_si128(x0, sk[9]); + x1 = _mm_aesenc_si128(x1, sk[9]); + x2 = _mm_aesenc_si128(x2, sk[9]); + x3 = _mm_aesenc_si128(x3, sk[9]); + if (num_rounds == 10) { + x0 = _mm_aesenclast_si128(x0, sk[10]); + x1 = _mm_aesenclast_si128(x1, sk[10]); + x2 = _mm_aesenclast_si128(x2, sk[10]); + x3 = _mm_aesenclast_si128(x3, sk[10]); + } else if (num_rounds == 12) { + x0 = _mm_aesenc_si128(x0, sk[10]); + x1 = _mm_aesenc_si128(x1, sk[10]); + x2 = _mm_aesenc_si128(x2, sk[10]); + x3 = _mm_aesenc_si128(x3, sk[10]); + x0 = _mm_aesenc_si128(x0, sk[11]); + x1 = _mm_aesenc_si128(x1, sk[11]); + x2 = _mm_aesenc_si128(x2, sk[11]); + x3 = _mm_aesenc_si128(x3, sk[11]); + x0 = _mm_aesenclast_si128(x0, sk[12]); + x1 = _mm_aesenclast_si128(x1, sk[12]); + x2 = _mm_aesenclast_si128(x2, sk[12]); + x3 = _mm_aesenclast_si128(x3, sk[12]); + } else { + x0 = _mm_aesenc_si128(x0, sk[10]); + x1 = _mm_aesenc_si128(x1, sk[10]); + x2 = _mm_aesenc_si128(x2, sk[10]); + x3 = _mm_aesenc_si128(x3, sk[10]); + x0 = _mm_aesenc_si128(x0, sk[11]); + x1 = _mm_aesenc_si128(x1, sk[11]); + x2 = _mm_aesenc_si128(x2, sk[11]); + x3 = _mm_aesenc_si128(x3, sk[11]); + x0 = _mm_aesenc_si128(x0, sk[12]); + x1 = _mm_aesenc_si128(x1, sk[12]); + x2 = _mm_aesenc_si128(x2, sk[12]); + x3 = _mm_aesenc_si128(x3, sk[12]); + x0 = _mm_aesenc_si128(x0, sk[13]); + x1 = _mm_aesenc_si128(x1, sk[13]); + x2 = _mm_aesenc_si128(x2, sk[13]); + x3 = _mm_aesenc_si128(x3, sk[13]); + x0 = _mm_aesenclast_si128(x0, sk[14]); + x1 = _mm_aesenclast_si128(x1, sk[14]); + x2 = _mm_aesenclast_si128(x2, sk[14]); + x3 = _mm_aesenclast_si128(x3, sk[14]); + } + if (len >= 64) { + x0 = _mm_xor_si128(x0, + _mm_loadu_si128((void *)(buf + 0))); + x1 = _mm_xor_si128(x1, + _mm_loadu_si128((void *)(buf + 16))); + x2 = _mm_xor_si128(x2, + _mm_loadu_si128((void *)(buf + 32))); + x3 = _mm_xor_si128(x3, + _mm_loadu_si128((void *)(buf + 48))); + _mm_storeu_si128((void *)(buf + 0), x0); + _mm_storeu_si128((void *)(buf + 16), x1); + _mm_storeu_si128((void *)(buf + 32), x2); + _mm_storeu_si128((void *)(buf + 48), x3); + buf += 64; + len -= 64; + } else { + unsigned char tmp[64]; + + _mm_storeu_si128((void *)(tmp + 0), x0); + _mm_storeu_si128((void *)(tmp + 16), x1); + _mm_storeu_si128((void *)(tmp + 32), x2); + _mm_storeu_si128((void *)(tmp + 48), x3); + for (u = 0; u < len; u ++) { + buf[u] ^= tmp[u]; + } + switch (len) { + case 16: + ivx0 = ivx1; + break; + case 32: + ivx0 = ivx2; + break; + case 48: + ivx0 = ivx3; + break; + } + break; + } + + /* + * Add 4 to each counter value. For carry propagation + * into the upper 64-bit words, we would need to compare + * the results with 4, but SSE2+ has only _signed_ + * comparisons. Instead, we mask out the low two bits, + * and check whether the remaining bits are zero. + */ + ivx0 = _mm_add_epi64(ivx0, four); + ivx1 = _mm_add_epi64(ivx1, four); + ivx2 = _mm_add_epi64(ivx2, four); + ivx3 = _mm_add_epi64(ivx3, four); + ivx0 = _mm_sub_epi64(ivx0, + _mm_slli_si128(_mm_cmpeq_epi64( + _mm_and_si128(ivx0, notthree), zero), 8)); + ivx1 = _mm_sub_epi64(ivx1, + _mm_slli_si128(_mm_cmpeq_epi64( + _mm_and_si128(ivx1, notthree), zero), 8)); + ivx2 = _mm_sub_epi64(ivx2, + _mm_slli_si128(_mm_cmpeq_epi64( + _mm_and_si128(ivx2, notthree), zero), 8)); + ivx3 = _mm_sub_epi64(ivx3, + _mm_slli_si128(_mm_cmpeq_epi64( + _mm_and_si128(ivx3, notthree), zero), 8)); + } + + /* + * Write back new counter value. The loop took care to put the + * right counter value in ivx0. + */ + _mm_storeu_si128((void *)ctr, _mm_shuffle_epi8(ivx0, erev)); +} + +/* see bearssl_block.h */ +BR_TARGET("sse2,sse4.1,aes") +void +br_aes_x86ni_ctrcbc_mac(const br_aes_x86ni_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len) +{ + const unsigned char *buf; + unsigned num_rounds; + __m128i sk[15], ivx; + unsigned u; + + buf = data; + ivx = _mm_loadu_si128(cbcmac); + num_rounds = ctx->num_rounds; + for (u = 0; u <= num_rounds; u ++) { + sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4))); + } + while (len > 0) { + __m128i x; + + x = _mm_xor_si128(_mm_loadu_si128((void *)buf), ivx); + x = _mm_xor_si128(x, sk[0]); + x = _mm_aesenc_si128(x, sk[1]); + x = _mm_aesenc_si128(x, sk[2]); + x = _mm_aesenc_si128(x, sk[3]); + x = _mm_aesenc_si128(x, sk[4]); + x = _mm_aesenc_si128(x, sk[5]); + x = _mm_aesenc_si128(x, sk[6]); + x = _mm_aesenc_si128(x, sk[7]); + x = _mm_aesenc_si128(x, sk[8]); + x = _mm_aesenc_si128(x, sk[9]); + if (num_rounds == 10) { + x = _mm_aesenclast_si128(x, sk[10]); + } else if (num_rounds == 12) { + x = _mm_aesenc_si128(x, sk[10]); + x = _mm_aesenc_si128(x, sk[11]); + x = _mm_aesenclast_si128(x, sk[12]); + } else { + x = _mm_aesenc_si128(x, sk[10]); + x = _mm_aesenc_si128(x, sk[11]); + x = _mm_aesenc_si128(x, sk[12]); + x = _mm_aesenc_si128(x, sk[13]); + x = _mm_aesenclast_si128(x, sk[14]); + } + ivx = x; + buf += 16; + len -= 16; + } + _mm_storeu_si128(cbcmac, ivx); +} + +/* see bearssl_block.h */ +BR_TARGET("sse2,sse4.1,aes") +void +br_aes_x86ni_ctrcbc_encrypt(const br_aes_x86ni_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len) +{ + unsigned char *buf; + unsigned num_rounds; + __m128i sk[15]; + __m128i ivx, cmx; + __m128i erev, zero, one; + unsigned u; + int first_iter; + + num_rounds = ctx->num_rounds; + for (u = 0; u <= num_rounds; u ++) { + sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4))); + } + + /* + * Some SSE2 constants. + */ + erev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15); + zero = _mm_setzero_si128(); + one = _mm_set_epi64x(0, 1); + + /* + * Decode the counter in big-endian. + */ + ivx = _mm_shuffle_epi8(_mm_loadu_si128(ctr), erev); + cmx = _mm_loadu_si128(cbcmac); + + buf = data; + first_iter = 1; + while (len > 0) { + __m128i dx, x0, x1; + + /* + * Load initial values: + * dx encrypted block of data + * x0 counter (for CTR encryption) + * x1 input for CBC-MAC + */ + dx = _mm_loadu_si128((void *)buf); + x0 = _mm_shuffle_epi8(ivx, erev); + x1 = cmx; + + x0 = _mm_xor_si128(x0, sk[0]); + x1 = _mm_xor_si128(x1, sk[0]); + x0 = _mm_aesenc_si128(x0, sk[1]); + x1 = _mm_aesenc_si128(x1, sk[1]); + x0 = _mm_aesenc_si128(x0, sk[2]); + x1 = _mm_aesenc_si128(x1, sk[2]); + x0 = _mm_aesenc_si128(x0, sk[3]); + x1 = _mm_aesenc_si128(x1, sk[3]); + x0 = _mm_aesenc_si128(x0, sk[4]); + x1 = _mm_aesenc_si128(x1, sk[4]); + x0 = _mm_aesenc_si128(x0, sk[5]); + x1 = _mm_aesenc_si128(x1, sk[5]); + x0 = _mm_aesenc_si128(x0, sk[6]); + x1 = _mm_aesenc_si128(x1, sk[6]); + x0 = _mm_aesenc_si128(x0, sk[7]); + x1 = _mm_aesenc_si128(x1, sk[7]); + x0 = _mm_aesenc_si128(x0, sk[8]); + x1 = _mm_aesenc_si128(x1, sk[8]); + x0 = _mm_aesenc_si128(x0, sk[9]); + x1 = _mm_aesenc_si128(x1, sk[9]); + if (num_rounds == 10) { + x0 = _mm_aesenclast_si128(x0, sk[10]); + x1 = _mm_aesenclast_si128(x1, sk[10]); + } else if (num_rounds == 12) { + x0 = _mm_aesenc_si128(x0, sk[10]); + x1 = _mm_aesenc_si128(x1, sk[10]); + x0 = _mm_aesenc_si128(x0, sk[11]); + x1 = _mm_aesenc_si128(x1, sk[11]); + x0 = _mm_aesenclast_si128(x0, sk[12]); + x1 = _mm_aesenclast_si128(x1, sk[12]); + } else { + x0 = _mm_aesenc_si128(x0, sk[10]); + x1 = _mm_aesenc_si128(x1, sk[10]); + x0 = _mm_aesenc_si128(x0, sk[11]); + x1 = _mm_aesenc_si128(x1, sk[11]); + x0 = _mm_aesenc_si128(x0, sk[12]); + x1 = _mm_aesenc_si128(x1, sk[12]); + x0 = _mm_aesenc_si128(x0, sk[13]); + x1 = _mm_aesenc_si128(x1, sk[13]); + x0 = _mm_aesenclast_si128(x0, sk[14]); + x1 = _mm_aesenclast_si128(x1, sk[14]); + } + + x0 = _mm_xor_si128(x0, dx); + if (first_iter) { + cmx = _mm_xor_si128(cmx, x0); + first_iter = 0; + } else { + cmx = _mm_xor_si128(x1, x0); + } + _mm_storeu_si128((void *)buf, x0); + + buf += 16; + len -= 16; + + /* + * Increment the counter value. + */ + ivx = _mm_add_epi64(ivx, one); + ivx = _mm_sub_epi64(ivx, + _mm_slli_si128(_mm_cmpeq_epi64(ivx, zero), 8)); + + /* + * If this was the last iteration, then compute the + * extra block encryption to complete CBC-MAC. + */ + if (len == 0) { + cmx = _mm_xor_si128(cmx, sk[0]); + cmx = _mm_aesenc_si128(cmx, sk[1]); + cmx = _mm_aesenc_si128(cmx, sk[2]); + cmx = _mm_aesenc_si128(cmx, sk[3]); + cmx = _mm_aesenc_si128(cmx, sk[4]); + cmx = _mm_aesenc_si128(cmx, sk[5]); + cmx = _mm_aesenc_si128(cmx, sk[6]); + cmx = _mm_aesenc_si128(cmx, sk[7]); + cmx = _mm_aesenc_si128(cmx, sk[8]); + cmx = _mm_aesenc_si128(cmx, sk[9]); + if (num_rounds == 10) { + cmx = _mm_aesenclast_si128(cmx, sk[10]); + } else if (num_rounds == 12) { + cmx = _mm_aesenc_si128(cmx, sk[10]); + cmx = _mm_aesenc_si128(cmx, sk[11]); + cmx = _mm_aesenclast_si128(cmx, sk[12]); + } else { + cmx = _mm_aesenc_si128(cmx, sk[10]); + cmx = _mm_aesenc_si128(cmx, sk[11]); + cmx = _mm_aesenc_si128(cmx, sk[12]); + cmx = _mm_aesenc_si128(cmx, sk[13]); + cmx = _mm_aesenclast_si128(cmx, sk[14]); + } + break; + } + } + + /* + * Write back new counter value and CBC-MAC value. + */ + _mm_storeu_si128(ctr, _mm_shuffle_epi8(ivx, erev)); + _mm_storeu_si128(cbcmac, cmx); +} + +/* see bearssl_block.h */ +BR_TARGET("sse2,sse4.1,aes") +void +br_aes_x86ni_ctrcbc_decrypt(const br_aes_x86ni_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len) +{ + unsigned char *buf; + unsigned num_rounds; + __m128i sk[15]; + __m128i ivx, cmx; + __m128i erev, zero, one; + unsigned u; + + num_rounds = ctx->num_rounds; + for (u = 0; u <= num_rounds; u ++) { + sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4))); + } + + /* + * Some SSE2 constants. + */ + erev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15); + zero = _mm_setzero_si128(); + one = _mm_set_epi64x(0, 1); + + /* + * Decode the counter in big-endian. + */ + ivx = _mm_shuffle_epi8(_mm_loadu_si128(ctr), erev); + cmx = _mm_loadu_si128(cbcmac); + + buf = data; + while (len > 0) { + __m128i dx, x0, x1; + + /* + * Load initial values: + * dx encrypted block of data + * x0 counter (for CTR encryption) + * x1 input for CBC-MAC + */ + dx = _mm_loadu_si128((void *)buf); + x0 = _mm_shuffle_epi8(ivx, erev); + x1 = _mm_xor_si128(cmx, dx); + + x0 = _mm_xor_si128(x0, sk[0]); + x1 = _mm_xor_si128(x1, sk[0]); + x0 = _mm_aesenc_si128(x0, sk[1]); + x1 = _mm_aesenc_si128(x1, sk[1]); + x0 = _mm_aesenc_si128(x0, sk[2]); + x1 = _mm_aesenc_si128(x1, sk[2]); + x0 = _mm_aesenc_si128(x0, sk[3]); + x1 = _mm_aesenc_si128(x1, sk[3]); + x0 = _mm_aesenc_si128(x0, sk[4]); + x1 = _mm_aesenc_si128(x1, sk[4]); + x0 = _mm_aesenc_si128(x0, sk[5]); + x1 = _mm_aesenc_si128(x1, sk[5]); + x0 = _mm_aesenc_si128(x0, sk[6]); + x1 = _mm_aesenc_si128(x1, sk[6]); + x0 = _mm_aesenc_si128(x0, sk[7]); + x1 = _mm_aesenc_si128(x1, sk[7]); + x0 = _mm_aesenc_si128(x0, sk[8]); + x1 = _mm_aesenc_si128(x1, sk[8]); + x0 = _mm_aesenc_si128(x0, sk[9]); + x1 = _mm_aesenc_si128(x1, sk[9]); + if (num_rounds == 10) { + x0 = _mm_aesenclast_si128(x0, sk[10]); + x1 = _mm_aesenclast_si128(x1, sk[10]); + } else if (num_rounds == 12) { + x0 = _mm_aesenc_si128(x0, sk[10]); + x1 = _mm_aesenc_si128(x1, sk[10]); + x0 = _mm_aesenc_si128(x0, sk[11]); + x1 = _mm_aesenc_si128(x1, sk[11]); + x0 = _mm_aesenclast_si128(x0, sk[12]); + x1 = _mm_aesenclast_si128(x1, sk[12]); + } else { + x0 = _mm_aesenc_si128(x0, sk[10]); + x1 = _mm_aesenc_si128(x1, sk[10]); + x0 = _mm_aesenc_si128(x0, sk[11]); + x1 = _mm_aesenc_si128(x1, sk[11]); + x0 = _mm_aesenc_si128(x0, sk[12]); + x1 = _mm_aesenc_si128(x1, sk[12]); + x0 = _mm_aesenc_si128(x0, sk[13]); + x1 = _mm_aesenc_si128(x1, sk[13]); + x0 = _mm_aesenclast_si128(x0, sk[14]); + x1 = _mm_aesenclast_si128(x1, sk[14]); + } + x0 = _mm_xor_si128(x0, dx); + cmx = x1; + _mm_storeu_si128((void *)buf, x0); + + buf += 16; + len -= 16; + + /* + * Increment the counter value. + */ + ivx = _mm_add_epi64(ivx, one); + ivx = _mm_sub_epi64(ivx, + _mm_slli_si128(_mm_cmpeq_epi64(ivx, zero), 8)); + } + + /* + * Write back new counter value and CBC-MAC value. + */ + _mm_storeu_si128(ctr, _mm_shuffle_epi8(ivx, erev)); + _mm_storeu_si128(cbcmac, cmx); +} + +BR_TARGETS_X86_DOWN + +/* see bearssl_block.h */ +const br_block_ctrcbc_class br_aes_x86ni_ctrcbc_vtable = { + sizeof(br_aes_x86ni_ctrcbc_keys), + 16, + 4, + (void (*)(const br_block_ctrcbc_class **, const void *, size_t)) + &br_aes_x86ni_ctrcbc_init, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, void *, size_t)) + &br_aes_x86ni_ctrcbc_encrypt, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, void *, size_t)) + &br_aes_x86ni_ctrcbc_decrypt, + (void (*)(const br_block_ctrcbc_class *const *, + void *, void *, size_t)) + &br_aes_x86ni_ctrcbc_ctr, + (void (*)(const br_block_ctrcbc_class *const *, + void *, const void *, size_t)) + &br_aes_x86ni_ctrcbc_mac +}; + +#else + +/* see bearssl_block.h */ +const br_block_ctrcbc_class * +br_aes_x86ni_ctrcbc_get_vtable(void) +{ + return NULL; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/symcipher/chacha20_ct.c b/BearSSL-OG/libbearssl/src/symcipher/chacha20_ct.c new file mode 100644 index 0000000..9961eb1 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/chacha20_ct.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +uint32_t +br_chacha20_ct_run(const void *key, + const void *iv, uint32_t cc, void *data, size_t len) +{ + unsigned char *buf; + uint32_t kw[8], ivw[3]; + size_t u; + + static const uint32_t CW[] = { + 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 + }; + + buf = data; + for (u = 0; u < 8; u ++) { + kw[u] = br_dec32le((const unsigned char *)key + (u << 2)); + } + for (u = 0; u < 3; u ++) { + ivw[u] = br_dec32le((const unsigned char *)iv + (u << 2)); + } + while (len > 0) { + uint32_t state[16]; + int i; + size_t clen; + unsigned char tmp[64]; + + memcpy(&state[0], CW, sizeof CW); + memcpy(&state[4], kw, sizeof kw); + state[12] = cc; + memcpy(&state[13], ivw, sizeof ivw); + for (i = 0; i < 10; i ++) { + +#define QROUND(a, b, c, d) do { \ + state[a] += state[b]; \ + state[d] ^= state[a]; \ + state[d] = (state[d] << 16) | (state[d] >> 16); \ + state[c] += state[d]; \ + state[b] ^= state[c]; \ + state[b] = (state[b] << 12) | (state[b] >> 20); \ + state[a] += state[b]; \ + state[d] ^= state[a]; \ + state[d] = (state[d] << 8) | (state[d] >> 24); \ + state[c] += state[d]; \ + state[b] ^= state[c]; \ + state[b] = (state[b] << 7) | (state[b] >> 25); \ + } while (0) + + QROUND( 0, 4, 8, 12); + QROUND( 1, 5, 9, 13); + QROUND( 2, 6, 10, 14); + QROUND( 3, 7, 11, 15); + QROUND( 0, 5, 10, 15); + QROUND( 1, 6, 11, 12); + QROUND( 2, 7, 8, 13); + QROUND( 3, 4, 9, 14); + +#undef QROUND + + } + for (u = 0; u < 4; u ++) { + br_enc32le(&tmp[u << 2], state[u] + CW[u]); + } + for (u = 4; u < 12; u ++) { + br_enc32le(&tmp[u << 2], state[u] + kw[u - 4]); + } + br_enc32le(&tmp[48], state[12] + cc); + for (u = 13; u < 16; u ++) { + br_enc32le(&tmp[u << 2], state[u] + ivw[u - 13]); + } + + clen = len < 64 ? len : 64; + for (u = 0; u < clen; u ++) { + buf[u] ^= tmp[u]; + } + buf += clen; + len -= clen; + cc ++; + } + return cc; +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/chacha20_sse2.c b/BearSSL-OG/libbearssl/src/symcipher/chacha20_sse2.c new file mode 100644 index 0000000..92b4a4a --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/chacha20_sse2.c @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BR_ENABLE_INTRINSICS 1 +#include "inner.h" + +#if BR_SSE2 + +/* + * This file contains a ChaCha20 implementation that leverages SSE2 + * opcodes for better performance. + */ + +/* see bearssl_block.h */ +br_chacha20_run +br_chacha20_sse2_get(void) +{ + /* + * If using 64-bit mode, then SSE2 opcodes should be automatically + * available, since they are part of the ABI. + * + * In 32-bit mode, we use CPUID to detect the SSE2 feature. + */ + +#if BR_amd64 + return &br_chacha20_sse2_run; +#else + + /* + * SSE2 support is indicated by bit 26 in EDX. + */ + if (br_cpuid(0, 0, 0, 0x04000000)) { + return &br_chacha20_sse2_run; + } else { + return 0; + } +#endif +} + +BR_TARGETS_X86_UP + +/* see bearssl_block.h */ +BR_TARGET("sse2") +uint32_t +br_chacha20_sse2_run(const void *key, + const void *iv, uint32_t cc, void *data, size_t len) +{ + unsigned char *buf; + uint32_t ivtmp[4]; + __m128i kw0, kw1; + __m128i iw, cw; + __m128i one; + + static const uint32_t CW[] = { + 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 + }; + + buf = data; + kw0 = _mm_loadu_si128(key); + kw1 = _mm_loadu_si128((const void *)((const unsigned char *)key + 16)); + ivtmp[0] = cc; + memcpy(ivtmp + 1, iv, 12); + iw = _mm_loadu_si128((const void *)ivtmp); + cw = _mm_loadu_si128((const void *)CW); + one = _mm_set_epi32(0, 0, 0, 1); + + while (len > 0) { + /* + * sj contains state words 4*j to 4*j+3. + */ + __m128i s0, s1, s2, s3; + int i; + + s0 = cw; + s1 = kw0; + s2 = kw1; + s3 = iw; + for (i = 0; i < 10; i ++) { + /* + * Even round is straightforward application on + * the state words. + */ + s0 = _mm_add_epi32(s0, s1); + s3 = _mm_xor_si128(s3, s0); + s3 = _mm_or_si128( + _mm_slli_epi32(s3, 16), + _mm_srli_epi32(s3, 16)); + + s2 = _mm_add_epi32(s2, s3); + s1 = _mm_xor_si128(s1, s2); + s1 = _mm_or_si128( + _mm_slli_epi32(s1, 12), + _mm_srli_epi32(s1, 20)); + + s0 = _mm_add_epi32(s0, s1); + s3 = _mm_xor_si128(s3, s0); + s3 = _mm_or_si128( + _mm_slli_epi32(s3, 8), + _mm_srli_epi32(s3, 24)); + + s2 = _mm_add_epi32(s2, s3); + s1 = _mm_xor_si128(s1, s2); + s1 = _mm_or_si128( + _mm_slli_epi32(s1, 7), + _mm_srli_epi32(s1, 25)); + + /* + * For the odd round, we must rotate some state + * words so that the computations apply on the + * right combinations of words. + */ + s1 = _mm_shuffle_epi32(s1, 0x39); + s2 = _mm_shuffle_epi32(s2, 0x4E); + s3 = _mm_shuffle_epi32(s3, 0x93); + + s0 = _mm_add_epi32(s0, s1); + s3 = _mm_xor_si128(s3, s0); + s3 = _mm_or_si128( + _mm_slli_epi32(s3, 16), + _mm_srli_epi32(s3, 16)); + + s2 = _mm_add_epi32(s2, s3); + s1 = _mm_xor_si128(s1, s2); + s1 = _mm_or_si128( + _mm_slli_epi32(s1, 12), + _mm_srli_epi32(s1, 20)); + + s0 = _mm_add_epi32(s0, s1); + s3 = _mm_xor_si128(s3, s0); + s3 = _mm_or_si128( + _mm_slli_epi32(s3, 8), + _mm_srli_epi32(s3, 24)); + + s2 = _mm_add_epi32(s2, s3); + s1 = _mm_xor_si128(s1, s2); + s1 = _mm_or_si128( + _mm_slli_epi32(s1, 7), + _mm_srli_epi32(s1, 25)); + + /* + * After the odd round, we rotate back the values + * to undo the rotate at the start of the odd round. + */ + s1 = _mm_shuffle_epi32(s1, 0x93); + s2 = _mm_shuffle_epi32(s2, 0x4E); + s3 = _mm_shuffle_epi32(s3, 0x39); + } + + /* + * Addition with the initial state. + */ + s0 = _mm_add_epi32(s0, cw); + s1 = _mm_add_epi32(s1, kw0); + s2 = _mm_add_epi32(s2, kw1); + s3 = _mm_add_epi32(s3, iw); + + /* + * Increment block counter. + */ + iw = _mm_add_epi32(iw, one); + + /* + * XOR final state with the data. + */ + if (len < 64) { + unsigned char tmp[64]; + size_t u; + + _mm_storeu_si128((void *)(tmp + 0), s0); + _mm_storeu_si128((void *)(tmp + 16), s1); + _mm_storeu_si128((void *)(tmp + 32), s2); + _mm_storeu_si128((void *)(tmp + 48), s3); + for (u = 0; u < len; u ++) { + buf[u] ^= tmp[u]; + } + break; + } else { + __m128i b0, b1, b2, b3; + + b0 = _mm_loadu_si128((const void *)(buf + 0)); + b1 = _mm_loadu_si128((const void *)(buf + 16)); + b2 = _mm_loadu_si128((const void *)(buf + 32)); + b3 = _mm_loadu_si128((const void *)(buf + 48)); + b0 = _mm_xor_si128(b0, s0); + b1 = _mm_xor_si128(b1, s1); + b2 = _mm_xor_si128(b2, s2); + b3 = _mm_xor_si128(b3, s3); + _mm_storeu_si128((void *)(buf + 0), b0); + _mm_storeu_si128((void *)(buf + 16), b1); + _mm_storeu_si128((void *)(buf + 32), b2); + _mm_storeu_si128((void *)(buf + 48), b3); + buf += 64; + len -= 64; + } + } + + /* + * _mm_extract_epi32() requires SSE4.1. We prefer to stick to + * raw SSE2, thus we use _mm_extract_epi16(). + */ + return (uint32_t)_mm_extract_epi16(iw, 0) + | ((uint32_t)_mm_extract_epi16(iw, 1) << 16); +} + +BR_TARGETS_X86_DOWN + +#else + +/* see bearssl_block.h */ +br_chacha20_run +br_chacha20_sse2_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/symcipher/des_ct.c b/BearSSL-OG/libbearssl/src/symcipher/des_ct.c new file mode 100644 index 0000000..c1e1704 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/des_ct.c @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * During key schedule, we need to apply bit extraction PC-2 then permute + * things into our bitslice representation. PC-2 extracts 48 bits out + * of two 28-bit words (kl and kr), and we store these bits into two + * 32-bit words sk0 and sk1. + * + * -- bit 16+x of sk0 comes from bit QL0[x] of kl + * -- bit x of sk0 comes from bit QR0[x] of kr + * -- bit 16+x of sk1 comes from bit QL1[x] of kl + * -- bit x of sk1 comes from bit QR1[x] of kr + */ + +static const unsigned char QL0[] = { + 17, 4, 27, 23, 13, 22, 7, 18, + 16, 24, 2, 20, 1, 8, 15, 26 +}; + +static const unsigned char QR0[] = { + 25, 19, 9, 1, 5, 11, 23, 8, + 17, 0, 22, 3, 6, 20, 27, 24 +}; + +static const unsigned char QL1[] = { + 28, 28, 14, 11, 28, 28, 25, 0, + 28, 28, 5, 9, 28, 28, 12, 21 +}; + +static const unsigned char QR1[] = { + 28, 28, 15, 4, 28, 28, 26, 16, + 28, 28, 12, 7, 28, 28, 10, 14 +}; + +/* + * 32-bit rotation. The C compiler is supposed to recognize it as a + * rotation and use the local architecture rotation opcode (if available). + */ +static __inline uint32_t +rotl(uint32_t x, int n) +{ + return (x << n) | (x >> (32 - n)); +} + +/* + * Compute key schedule for 8 key bytes (produces 32 subkey words). + */ +static void +keysched_unit(uint32_t *skey, const void *key) +{ + int i; + + br_des_keysched_unit(skey, key); + + /* + * Apply PC-2 + bitslicing. + */ + for (i = 0; i < 16; i ++) { + uint32_t kl, kr, sk0, sk1; + int j; + + kl = skey[(i << 1) + 0]; + kr = skey[(i << 1) + 1]; + sk0 = 0; + sk1 = 0; + for (j = 0; j < 16; j ++) { + sk0 <<= 1; + sk1 <<= 1; + sk0 |= ((kl >> QL0[j]) & (uint32_t)1) << 16; + sk0 |= (kr >> QR0[j]) & (uint32_t)1; + sk1 |= ((kl >> QL1[j]) & (uint32_t)1) << 16; + sk1 |= (kr >> QR1[j]) & (uint32_t)1; + } + + skey[(i << 1) + 0] = sk0; + skey[(i << 1) + 1] = sk1; + } + +#if 0 + /* + * Speed-optimized version for PC-2 + bitslicing. + * (Unused. Kept for reference only.) + */ + sk0 = kl & (uint32_t)0x00100000; + sk0 |= (kl & (uint32_t)0x08008000) << 2; + sk0 |= (kl & (uint32_t)0x00400000) << 4; + sk0 |= (kl & (uint32_t)0x00800000) << 5; + sk0 |= (kl & (uint32_t)0x00040000) << 6; + sk0 |= (kl & (uint32_t)0x00010000) << 7; + sk0 |= (kl & (uint32_t)0x00000100) << 10; + sk0 |= (kl & (uint32_t)0x00022000) << 14; + sk0 |= (kl & (uint32_t)0x00000082) << 18; + sk0 |= (kl & (uint32_t)0x00000004) << 19; + sk0 |= (kl & (uint32_t)0x04000000) >> 10; + sk0 |= (kl & (uint32_t)0x00000010) << 26; + sk0 |= (kl & (uint32_t)0x01000000) >> 2; + + sk0 |= kr & (uint32_t)0x00000100; + sk0 |= (kr & (uint32_t)0x00000008) << 1; + sk0 |= (kr & (uint32_t)0x00000200) << 4; + sk0 |= rotl(kr & (uint32_t)0x08000021, 6); + sk0 |= (kr & (uint32_t)0x01000000) >> 24; + sk0 |= (kr & (uint32_t)0x00000002) << 11; + sk0 |= (kr & (uint32_t)0x00100000) >> 18; + sk0 |= (kr & (uint32_t)0x00400000) >> 17; + sk0 |= (kr & (uint32_t)0x00800000) >> 14; + sk0 |= (kr & (uint32_t)0x02020000) >> 10; + sk0 |= (kr & (uint32_t)0x00080000) >> 5; + sk0 |= (kr & (uint32_t)0x00000040) >> 3; + sk0 |= (kr & (uint32_t)0x00000800) >> 1; + + sk1 = kl & (uint32_t)0x02000000; + sk1 |= (kl & (uint32_t)0x00001000) << 5; + sk1 |= (kl & (uint32_t)0x00000200) << 11; + sk1 |= (kl & (uint32_t)0x00004000) << 15; + sk1 |= (kl & (uint32_t)0x00000020) << 16; + sk1 |= (kl & (uint32_t)0x00000800) << 17; + sk1 |= (kl & (uint32_t)0x00000001) << 24; + sk1 |= (kl & (uint32_t)0x00200000) >> 5; + + sk1 |= (kr & (uint32_t)0x00000010) << 8; + sk1 |= (kr & (uint32_t)0x04000000) >> 17; + sk1 |= (kr & (uint32_t)0x00004000) >> 14; + sk1 |= (kr & (uint32_t)0x00000400) >> 9; + sk1 |= (kr & (uint32_t)0x00010000) >> 8; + sk1 |= (kr & (uint32_t)0x00001000) >> 7; + sk1 |= (kr & (uint32_t)0x00000080) >> 3; + sk1 |= (kr & (uint32_t)0x00008000) >> 2; +#endif +} + +/* see inner.h */ +unsigned +br_des_ct_keysched(uint32_t *skey, const void *key, size_t key_len) +{ + switch (key_len) { + case 8: + keysched_unit(skey, key); + return 1; + case 16: + keysched_unit(skey, key); + keysched_unit(skey + 32, (const unsigned char *)key + 8); + br_des_rev_skey(skey + 32); + memcpy(skey + 64, skey, 32 * sizeof *skey); + return 3; + default: + keysched_unit(skey, key); + keysched_unit(skey + 32, (const unsigned char *)key + 8); + br_des_rev_skey(skey + 32); + keysched_unit(skey + 64, (const unsigned char *)key + 16); + return 3; + } +} + +/* + * DES confusion function. This function performs expansion E (32 to + * 48 bits), XOR with subkey, S-boxes, and permutation P. + */ +static __inline uint32_t +Fconf(uint32_t r0, const uint32_t *sk) +{ + /* + * Each 6->4 S-box is virtually turned into four 6->1 boxes; we + * thus end up with 32 boxes that we call "T-boxes" here. We will + * evaluate them with bitslice code. + * + * Each T-box is a circuit of multiplexers (sort of) and thus + * takes 70 inputs: the 6 actual T-box inputs, and 64 constants + * that describe the T-box output for all combinations of the + * 6 inputs. With this model, all T-boxes are identical (with + * distinct inputs) and thus can be executed in parallel with + * bitslice code. + * + * T-boxes are numbered from 0 to 31, in least-to-most + * significant order. Thus, S-box S1 corresponds to T-boxes 31, + * 30, 29 and 28, in that order. T-box 'n' is computed with the + * bits at rank 'n' in the 32-bit words. + * + * Words x0 to x5 contain the T-box inputs 0 to 5. + */ + uint32_t x0, x1, x2, x3, x4, x5, z0; + uint32_t y0, y1, y2, y3, y4, y5, y6, y7, y8, y9; + uint32_t y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; + uint32_t y20, y21, y22, y23, y24, y25, y26, y27, y28, y29; + uint32_t y30; + + /* + * Spread input bits over the 6 input words x*. + */ + x1 = r0 & (uint32_t)0x11111111; + x2 = (r0 >> 1) & (uint32_t)0x11111111; + x3 = (r0 >> 2) & (uint32_t)0x11111111; + x4 = (r0 >> 3) & (uint32_t)0x11111111; + x1 = (x1 << 4) - x1; + x2 = (x2 << 4) - x2; + x3 = (x3 << 4) - x3; + x4 = (x4 << 4) - x4; + x0 = (x4 << 4) | (x4 >> 28); + x5 = (x1 >> 4) | (x1 << 28); + + /* + * XOR with the subkey for this round. + */ + x0 ^= sk[0]; + x1 ^= sk[1]; + x2 ^= sk[2]; + x3 ^= sk[3]; + x4 ^= sk[4]; + x5 ^= sk[5]; + + /* + * The T-boxes are done in parallel, since they all use a + * "tree of multiplexer". We use "fake multiplexers": + * + * y = a ^ (x & b) + * + * computes y as either 'a' (if x == 0) or 'a ^ b' (if x == 1). + */ + y0 = (uint32_t)0xEFA72C4D ^ (x0 & (uint32_t)0xEC7AC69C); + y1 = (uint32_t)0xAEAAEDFF ^ (x0 & (uint32_t)0x500FB821); + y2 = (uint32_t)0x37396665 ^ (x0 & (uint32_t)0x40EFA809); + y3 = (uint32_t)0x68D7B833 ^ (x0 & (uint32_t)0xA5EC0B28); + y4 = (uint32_t)0xC9C755BB ^ (x0 & (uint32_t)0x252CF820); + y5 = (uint32_t)0x73FC3606 ^ (x0 & (uint32_t)0x40205801); + y6 = (uint32_t)0xA2A0A918 ^ (x0 & (uint32_t)0xE220F929); + y7 = (uint32_t)0x8222BD90 ^ (x0 & (uint32_t)0x44A3F9E1); + y8 = (uint32_t)0xD6B6AC77 ^ (x0 & (uint32_t)0x794F104A); + y9 = (uint32_t)0x3069300C ^ (x0 & (uint32_t)0x026F320B); + y10 = (uint32_t)0x6CE0D5CC ^ (x0 & (uint32_t)0x7640B01A); + y11 = (uint32_t)0x59A9A22D ^ (x0 & (uint32_t)0x238F1572); + y12 = (uint32_t)0xAC6D0BD4 ^ (x0 & (uint32_t)0x7A63C083); + y13 = (uint32_t)0x21C83200 ^ (x0 & (uint32_t)0x11CCA000); + y14 = (uint32_t)0xA0E62188 ^ (x0 & (uint32_t)0x202F69AA); + /* y15 = (uint32_t)0x00000000 ^ (x0 & (uint32_t)0x00000000); */ + y16 = (uint32_t)0xAF7D655A ^ (x0 & (uint32_t)0x51B33BE9); + y17 = (uint32_t)0xF0168AA3 ^ (x0 & (uint32_t)0x3B0FE8AE); + y18 = (uint32_t)0x90AA30C6 ^ (x0 & (uint32_t)0x90BF8816); + y19 = (uint32_t)0x5AB2750A ^ (x0 & (uint32_t)0x09E34F9B); + y20 = (uint32_t)0x5391BE65 ^ (x0 & (uint32_t)0x0103BE88); + y21 = (uint32_t)0x93372BAF ^ (x0 & (uint32_t)0x49AC8E25); + y22 = (uint32_t)0xF288210C ^ (x0 & (uint32_t)0x922C313D); + y23 = (uint32_t)0x920AF5C0 ^ (x0 & (uint32_t)0x70EF31B0); + y24 = (uint32_t)0x63D312C0 ^ (x0 & (uint32_t)0x6A707100); + y25 = (uint32_t)0x537B3006 ^ (x0 & (uint32_t)0xB97C9011); + y26 = (uint32_t)0xA2EFB0A5 ^ (x0 & (uint32_t)0xA320C959); + y27 = (uint32_t)0xBC8F96A5 ^ (x0 & (uint32_t)0x6EA0AB4A); + y28 = (uint32_t)0xFAD176A5 ^ (x0 & (uint32_t)0x6953DDF8); + y29 = (uint32_t)0x665A14A3 ^ (x0 & (uint32_t)0xF74F3E2B); + y30 = (uint32_t)0xF2EFF0CC ^ (x0 & (uint32_t)0xF0306CAD); + /* y31 = (uint32_t)0x00000000 ^ (x0 & (uint32_t)0x00000000); */ + + y0 = y0 ^ (x1 & y1); + y1 = y2 ^ (x1 & y3); + y2 = y4 ^ (x1 & y5); + y3 = y6 ^ (x1 & y7); + y4 = y8 ^ (x1 & y9); + y5 = y10 ^ (x1 & y11); + y6 = y12 ^ (x1 & y13); + y7 = y14; /* was: y14 ^ (x1 & y15) */ + y8 = y16 ^ (x1 & y17); + y9 = y18 ^ (x1 & y19); + y10 = y20 ^ (x1 & y21); + y11 = y22 ^ (x1 & y23); + y12 = y24 ^ (x1 & y25); + y13 = y26 ^ (x1 & y27); + y14 = y28 ^ (x1 & y29); + y15 = y30; /* was: y30 ^ (x1 & y31) */ + + y0 = y0 ^ (x2 & y1); + y1 = y2 ^ (x2 & y3); + y2 = y4 ^ (x2 & y5); + y3 = y6 ^ (x2 & y7); + y4 = y8 ^ (x2 & y9); + y5 = y10 ^ (x2 & y11); + y6 = y12 ^ (x2 & y13); + y7 = y14 ^ (x2 & y15); + + y0 = y0 ^ (x3 & y1); + y1 = y2 ^ (x3 & y3); + y2 = y4 ^ (x3 & y5); + y3 = y6 ^ (x3 & y7); + + y0 = y0 ^ (x4 & y1); + y1 = y2 ^ (x4 & y3); + + y0 = y0 ^ (x5 & y1); + + /* + * The P permutation: + * -- Each bit move is converted into a mask + left rotation. + * -- Rotations that use the same movement are coalesced together. + * -- Left and right shifts are used as alternatives to a rotation + * where appropriate (this will help architectures that do not have + * a rotation opcode). + */ + z0 = (y0 & (uint32_t)0x00000004) << 3; + z0 |= (y0 & (uint32_t)0x00004000) << 4; + z0 |= rotl(y0 & 0x12020120, 5); + z0 |= (y0 & (uint32_t)0x00100000) << 6; + z0 |= (y0 & (uint32_t)0x00008000) << 9; + z0 |= (y0 & (uint32_t)0x04000000) >> 22; + z0 |= (y0 & (uint32_t)0x00000001) << 11; + z0 |= rotl(y0 & 0x20000200, 12); + z0 |= (y0 & (uint32_t)0x00200000) >> 19; + z0 |= (y0 & (uint32_t)0x00000040) << 14; + z0 |= (y0 & (uint32_t)0x00010000) << 15; + z0 |= (y0 & (uint32_t)0x00000002) << 16; + z0 |= rotl(y0 & 0x40801800, 17); + z0 |= (y0 & (uint32_t)0x00080000) >> 13; + z0 |= (y0 & (uint32_t)0x00000010) << 21; + z0 |= (y0 & (uint32_t)0x01000000) >> 10; + z0 |= rotl(y0 & 0x88000008, 24); + z0 |= (y0 & (uint32_t)0x00000480) >> 7; + z0 |= (y0 & (uint32_t)0x00442000) >> 6; + return z0; +} + +/* + * Process one block through 16 successive rounds, omitting the swap + * in the final round. + */ +static void +process_block_unit(uint32_t *pl, uint32_t *pr, const uint32_t *sk_exp) +{ + int i; + uint32_t l, r; + + l = *pl; + r = *pr; + for (i = 0; i < 16; i ++) { + uint32_t t; + + t = l ^ Fconf(r, sk_exp); + l = r; + r = t; + sk_exp += 6; + } + *pl = r; + *pr = l; +} + +/* see inner.h */ +void +br_des_ct_process_block(unsigned num_rounds, + const uint32_t *sk_exp, void *block) +{ + unsigned char *buf; + uint32_t l, r; + + buf = block; + l = br_dec32be(buf); + r = br_dec32be(buf + 4); + br_des_do_IP(&l, &r); + while (num_rounds -- > 0) { + process_block_unit(&l, &r, sk_exp); + sk_exp += 96; + } + br_des_do_invIP(&l, &r); + br_enc32be(buf, l); + br_enc32be(buf + 4, r); +} + +/* see inner.h */ +void +br_des_ct_skey_expand(uint32_t *sk_exp, + unsigned num_rounds, const uint32_t *skey) +{ + num_rounds <<= 4; + while (num_rounds -- > 0) { + uint32_t v, w0, w1, w2, w3; + + v = *skey ++; + w0 = v & 0x11111111; + w1 = (v >> 1) & 0x11111111; + w2 = (v >> 2) & 0x11111111; + w3 = (v >> 3) & 0x11111111; + *sk_exp ++ = (w0 << 4) - w0; + *sk_exp ++ = (w1 << 4) - w1; + *sk_exp ++ = (w2 << 4) - w2; + *sk_exp ++ = (w3 << 4) - w3; + v = *skey ++; + w0 = v & 0x11111111; + w1 = (v >> 1) & 0x11111111; + *sk_exp ++ = (w0 << 4) - w0; + *sk_exp ++ = (w1 << 4) - w1; + } +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/des_ct_cbcdec.c b/BearSSL-OG/libbearssl/src/symcipher/des_ct_cbcdec.c new file mode 100644 index 0000000..d208a3d --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/des_ct_cbcdec.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_des_ct_cbcdec_init(br_des_ct_cbcdec_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_des_ct_cbcdec_vtable; + ctx->num_rounds = br_des_ct_keysched(ctx->skey, key, len); + if (len == 8) { + br_des_rev_skey(ctx->skey); + } else { + int i; + + for (i = 0; i < 48; i += 2) { + uint32_t t; + + t = ctx->skey[i]; + ctx->skey[i] = ctx->skey[94 - i]; + ctx->skey[94 - i] = t; + t = ctx->skey[i + 1]; + ctx->skey[i + 1] = ctx->skey[95 - i]; + ctx->skey[95 - i] = t; + } + } +} + +/* see bearssl_block.h */ +void +br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf, *ivbuf; + uint32_t sk_exp[288]; + + br_des_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + ivbuf = iv; + buf = data; + while (len > 0) { + unsigned char tmp[8]; + int i; + + memcpy(tmp, buf, 8); + br_des_ct_process_block(ctx->num_rounds, sk_exp, buf); + for (i = 0; i < 8; i ++) { + buf[i] ^= ivbuf[i]; + } + memcpy(ivbuf, tmp, 8); + buf += 8; + len -= 8; + } +} + +/* see bearssl_block.h */ +const br_block_cbcdec_class br_des_ct_cbcdec_vtable = { + sizeof(br_des_ct_cbcdec_keys), + 8, + 3, + (void (*)(const br_block_cbcdec_class **, const void *, size_t)) + &br_des_ct_cbcdec_init, + (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) + &br_des_ct_cbcdec_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/des_ct_cbcenc.c b/BearSSL-OG/libbearssl/src/symcipher/des_ct_cbcenc.c new file mode 100644 index 0000000..4b3610e --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/des_ct_cbcenc.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_des_ct_cbcenc_init(br_des_ct_cbcenc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_des_ct_cbcenc_vtable; + ctx->num_rounds = br_des_ct_keysched(ctx->skey, key, len); +} + +/* see bearssl_block.h */ +void +br_des_ct_cbcenc_run(const br_des_ct_cbcenc_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf, *ivbuf; + uint32_t sk_exp[288]; + + br_des_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey); + ivbuf = iv; + buf = data; + while (len > 0) { + int i; + + for (i = 0; i < 8; i ++) { + buf[i] ^= ivbuf[i]; + } + br_des_ct_process_block(ctx->num_rounds, sk_exp, buf); + memcpy(ivbuf, buf, 8); + buf += 8; + len -= 8; + } +} + +/* see bearssl_block.h */ +const br_block_cbcenc_class br_des_ct_cbcenc_vtable = { + sizeof(br_des_ct_cbcenc_keys), + 8, + 3, + (void (*)(const br_block_cbcenc_class **, const void *, size_t)) + &br_des_ct_cbcenc_init, + (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) + &br_des_ct_cbcenc_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/des_support.c b/BearSSL-OG/libbearssl/src/symcipher/des_support.c new file mode 100644 index 0000000..37f6db3 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/des_support.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +void +br_des_do_IP(uint32_t *xl, uint32_t *xr) +{ + /* + * Permutation algorithm is initially from Richard Outerbridge; + * implementation here is adapted from Crypto++ "des.cpp" file + * (which is in public domain). + */ + uint32_t l, r, t; + + l = *xl; + r = *xr; + t = ((l >> 4) ^ r) & (uint32_t)0x0F0F0F0F; + r ^= t; + l ^= t << 4; + t = ((l >> 16) ^ r) & (uint32_t)0x0000FFFF; + r ^= t; + l ^= t << 16; + t = ((r >> 2) ^ l) & (uint32_t)0x33333333; + l ^= t; + r ^= t << 2; + t = ((r >> 8) ^ l) & (uint32_t)0x00FF00FF; + l ^= t; + r ^= t << 8; + t = ((l >> 1) ^ r) & (uint32_t)0x55555555; + r ^= t; + l ^= t << 1; + *xl = l; + *xr = r; +} + +/* see inner.h */ +void +br_des_do_invIP(uint32_t *xl, uint32_t *xr) +{ + /* + * See br_des_do_IP(). + */ + uint32_t l, r, t; + + l = *xl; + r = *xr; + t = ((l >> 1) ^ r) & 0x55555555; + r ^= t; + l ^= t << 1; + t = ((r >> 8) ^ l) & 0x00FF00FF; + l ^= t; + r ^= t << 8; + t = ((r >> 2) ^ l) & 0x33333333; + l ^= t; + r ^= t << 2; + t = ((l >> 16) ^ r) & 0x0000FFFF; + r ^= t; + l ^= t << 16; + t = ((l >> 4) ^ r) & 0x0F0F0F0F; + r ^= t; + l ^= t << 4; + *xl = l; + *xr = r; +} + +/* see inner.h */ +void +br_des_keysched_unit(uint32_t *skey, const void *key) +{ + uint32_t xl, xr, kl, kr; + int i; + + xl = br_dec32be(key); + xr = br_dec32be((const unsigned char *)key + 4); + + /* + * Permutation PC-1 is quite similar to the IP permutation. + * Definition of IP (in FIPS 46-3 notations) is: + * 58 50 42 34 26 18 10 2 + * 60 52 44 36 28 20 12 4 + * 62 54 46 38 30 22 14 6 + * 64 56 48 40 32 24 16 8 + * 57 49 41 33 25 17 9 1 + * 59 51 43 35 27 19 11 3 + * 61 53 45 37 29 21 13 5 + * 63 55 47 39 31 23 15 7 + * + * Definition of PC-1 is: + * 57 49 41 33 25 17 9 1 + * 58 50 42 34 26 18 10 2 + * 59 51 43 35 27 19 11 3 + * 60 52 44 36 + * 63 55 47 39 31 23 15 7 + * 62 54 46 38 30 22 14 6 + * 61 53 45 37 29 21 13 5 + * 28 20 12 4 + */ + br_des_do_IP(&xl, &xr); + kl = ((xr & (uint32_t)0xFF000000) >> 4) + | ((xl & (uint32_t)0xFF000000) >> 12) + | ((xr & (uint32_t)0x00FF0000) >> 12) + | ((xl & (uint32_t)0x00FF0000) >> 20); + kr = ((xr & (uint32_t)0x000000FF) << 20) + | ((xl & (uint32_t)0x0000FF00) << 4) + | ((xr & (uint32_t)0x0000FF00) >> 4) + | ((xl & (uint32_t)0x000F0000) >> 16); + + /* + * For each round, rotate the two 28-bit words kl and kr. + * The extraction of the 48-bit subkey (PC-2) is not done yet. + */ + for (i = 0; i < 16; i ++) { + if ((1 << i) & 0x8103) { + kl = (kl << 1) | (kl >> 27); + kr = (kr << 1) | (kr >> 27); + } else { + kl = (kl << 2) | (kl >> 26); + kr = (kr << 2) | (kr >> 26); + } + kl &= (uint32_t)0x0FFFFFFF; + kr &= (uint32_t)0x0FFFFFFF; + skey[(i << 1) + 0] = kl; + skey[(i << 1) + 1] = kr; + } +} + +/* see inner.h */ +void +br_des_rev_skey(uint32_t *skey) +{ + int i; + + for (i = 0; i < 16; i += 2) { + uint32_t t; + + t = skey[i + 0]; + skey[i + 0] = skey[30 - i]; + skey[30 - i] = t; + t = skey[i + 1]; + skey[i + 1] = skey[31 - i]; + skey[31 - i] = t; + } +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/des_tab.c b/BearSSL-OG/libbearssl/src/symcipher/des_tab.c new file mode 100644 index 0000000..d7aba0c --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/des_tab.c @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * PC2left[x] tells where bit x goes when applying PC-2. 'x' is a bit + * position in the left rotated key word. Both position are in normal + * order (rightmost bit is 0). + */ +static const unsigned char PC2left[] = { + 16, 3, 7, 24, 20, 11, 24, + 13, 2, 10, 24, 22, 5, 15, + 23, 1, 9, 21, 12, 24, 6, + 4, 14, 18, 8, 17, 0, 19 +}; + +/* + * Similar to PC2left[x], for the right rotated key word. + */ +static const unsigned char PC2right[] = { + 8, 18, 24, 6, 22, 15, 3, + 10, 12, 19, 5, 14, 11, 24, + 4, 23, 16, 9, 24, 20, 2, + 24, 7, 13, 0, 21, 17, 1 +}; + +/* + * S-boxes and PC-1 merged. + */ +static const uint32_t S1[] = { + 0x00808200, 0x00000000, 0x00008000, 0x00808202, + 0x00808002, 0x00008202, 0x00000002, 0x00008000, + 0x00000200, 0x00808200, 0x00808202, 0x00000200, + 0x00800202, 0x00808002, 0x00800000, 0x00000002, + 0x00000202, 0x00800200, 0x00800200, 0x00008200, + 0x00008200, 0x00808000, 0x00808000, 0x00800202, + 0x00008002, 0x00800002, 0x00800002, 0x00008002, + 0x00000000, 0x00000202, 0x00008202, 0x00800000, + 0x00008000, 0x00808202, 0x00000002, 0x00808000, + 0x00808200, 0x00800000, 0x00800000, 0x00000200, + 0x00808002, 0x00008000, 0x00008200, 0x00800002, + 0x00000200, 0x00000002, 0x00800202, 0x00008202, + 0x00808202, 0x00008002, 0x00808000, 0x00800202, + 0x00800002, 0x00000202, 0x00008202, 0x00808200, + 0x00000202, 0x00800200, 0x00800200, 0x00000000, + 0x00008002, 0x00008200, 0x00000000, 0x00808002 +}; + +static const uint32_t S2[] = { + 0x40084010, 0x40004000, 0x00004000, 0x00084010, + 0x00080000, 0x00000010, 0x40080010, 0x40004010, + 0x40000010, 0x40084010, 0x40084000, 0x40000000, + 0x40004000, 0x00080000, 0x00000010, 0x40080010, + 0x00084000, 0x00080010, 0x40004010, 0x00000000, + 0x40000000, 0x00004000, 0x00084010, 0x40080000, + 0x00080010, 0x40000010, 0x00000000, 0x00084000, + 0x00004010, 0x40084000, 0x40080000, 0x00004010, + 0x00000000, 0x00084010, 0x40080010, 0x00080000, + 0x40004010, 0x40080000, 0x40084000, 0x00004000, + 0x40080000, 0x40004000, 0x00000010, 0x40084010, + 0x00084010, 0x00000010, 0x00004000, 0x40000000, + 0x00004010, 0x40084000, 0x00080000, 0x40000010, + 0x00080010, 0x40004010, 0x40000010, 0x00080010, + 0x00084000, 0x00000000, 0x40004000, 0x00004010, + 0x40000000, 0x40080010, 0x40084010, 0x00084000 +}; + +static const uint32_t S3[] = { + 0x00000104, 0x04010100, 0x00000000, 0x04010004, + 0x04000100, 0x00000000, 0x00010104, 0x04000100, + 0x00010004, 0x04000004, 0x04000004, 0x00010000, + 0x04010104, 0x00010004, 0x04010000, 0x00000104, + 0x04000000, 0x00000004, 0x04010100, 0x00000100, + 0x00010100, 0x04010000, 0x04010004, 0x00010104, + 0x04000104, 0x00010100, 0x00010000, 0x04000104, + 0x00000004, 0x04010104, 0x00000100, 0x04000000, + 0x04010100, 0x04000000, 0x00010004, 0x00000104, + 0x00010000, 0x04010100, 0x04000100, 0x00000000, + 0x00000100, 0x00010004, 0x04010104, 0x04000100, + 0x04000004, 0x00000100, 0x00000000, 0x04010004, + 0x04000104, 0x00010000, 0x04000000, 0x04010104, + 0x00000004, 0x00010104, 0x00010100, 0x04000004, + 0x04010000, 0x04000104, 0x00000104, 0x04010000, + 0x00010104, 0x00000004, 0x04010004, 0x00010100 +}; + +static const uint32_t S4[] = { + 0x80401000, 0x80001040, 0x80001040, 0x00000040, + 0x00401040, 0x80400040, 0x80400000, 0x80001000, + 0x00000000, 0x00401000, 0x00401000, 0x80401040, + 0x80000040, 0x00000000, 0x00400040, 0x80400000, + 0x80000000, 0x00001000, 0x00400000, 0x80401000, + 0x00000040, 0x00400000, 0x80001000, 0x00001040, + 0x80400040, 0x80000000, 0x00001040, 0x00400040, + 0x00001000, 0x00401040, 0x80401040, 0x80000040, + 0x00400040, 0x80400000, 0x00401000, 0x80401040, + 0x80000040, 0x00000000, 0x00000000, 0x00401000, + 0x00001040, 0x00400040, 0x80400040, 0x80000000, + 0x80401000, 0x80001040, 0x80001040, 0x00000040, + 0x80401040, 0x80000040, 0x80000000, 0x00001000, + 0x80400000, 0x80001000, 0x00401040, 0x80400040, + 0x80001000, 0x00001040, 0x00400000, 0x80401000, + 0x00000040, 0x00400000, 0x00001000, 0x00401040 +}; + +static const uint32_t S5[] = { + 0x00000080, 0x01040080, 0x01040000, 0x21000080, + 0x00040000, 0x00000080, 0x20000000, 0x01040000, + 0x20040080, 0x00040000, 0x01000080, 0x20040080, + 0x21000080, 0x21040000, 0x00040080, 0x20000000, + 0x01000000, 0x20040000, 0x20040000, 0x00000000, + 0x20000080, 0x21040080, 0x21040080, 0x01000080, + 0x21040000, 0x20000080, 0x00000000, 0x21000000, + 0x01040080, 0x01000000, 0x21000000, 0x00040080, + 0x00040000, 0x21000080, 0x00000080, 0x01000000, + 0x20000000, 0x01040000, 0x21000080, 0x20040080, + 0x01000080, 0x20000000, 0x21040000, 0x01040080, + 0x20040080, 0x00000080, 0x01000000, 0x21040000, + 0x21040080, 0x00040080, 0x21000000, 0x21040080, + 0x01040000, 0x00000000, 0x20040000, 0x21000000, + 0x00040080, 0x01000080, 0x20000080, 0x00040000, + 0x00000000, 0x20040000, 0x01040080, 0x20000080 +}; + +static const uint32_t S6[] = { + 0x10000008, 0x10200000, 0x00002000, 0x10202008, + 0x10200000, 0x00000008, 0x10202008, 0x00200000, + 0x10002000, 0x00202008, 0x00200000, 0x10000008, + 0x00200008, 0x10002000, 0x10000000, 0x00002008, + 0x00000000, 0x00200008, 0x10002008, 0x00002000, + 0x00202000, 0x10002008, 0x00000008, 0x10200008, + 0x10200008, 0x00000000, 0x00202008, 0x10202000, + 0x00002008, 0x00202000, 0x10202000, 0x10000000, + 0x10002000, 0x00000008, 0x10200008, 0x00202000, + 0x10202008, 0x00200000, 0x00002008, 0x10000008, + 0x00200000, 0x10002000, 0x10000000, 0x00002008, + 0x10000008, 0x10202008, 0x00202000, 0x10200000, + 0x00202008, 0x10202000, 0x00000000, 0x10200008, + 0x00000008, 0x00002000, 0x10200000, 0x00202008, + 0x00002000, 0x00200008, 0x10002008, 0x00000000, + 0x10202000, 0x10000000, 0x00200008, 0x10002008 +}; + +static const uint32_t S7[] = { + 0x00100000, 0x02100001, 0x02000401, 0x00000000, + 0x00000400, 0x02000401, 0x00100401, 0x02100400, + 0x02100401, 0x00100000, 0x00000000, 0x02000001, + 0x00000001, 0x02000000, 0x02100001, 0x00000401, + 0x02000400, 0x00100401, 0x00100001, 0x02000400, + 0x02000001, 0x02100000, 0x02100400, 0x00100001, + 0x02100000, 0x00000400, 0x00000401, 0x02100401, + 0x00100400, 0x00000001, 0x02000000, 0x00100400, + 0x02000000, 0x00100400, 0x00100000, 0x02000401, + 0x02000401, 0x02100001, 0x02100001, 0x00000001, + 0x00100001, 0x02000000, 0x02000400, 0x00100000, + 0x02100400, 0x00000401, 0x00100401, 0x02100400, + 0x00000401, 0x02000001, 0x02100401, 0x02100000, + 0x00100400, 0x00000000, 0x00000001, 0x02100401, + 0x00000000, 0x00100401, 0x02100000, 0x00000400, + 0x02000001, 0x02000400, 0x00000400, 0x00100001 +}; + +static const uint32_t S8[] = { + 0x08000820, 0x00000800, 0x00020000, 0x08020820, + 0x08000000, 0x08000820, 0x00000020, 0x08000000, + 0x00020020, 0x08020000, 0x08020820, 0x00020800, + 0x08020800, 0x00020820, 0x00000800, 0x00000020, + 0x08020000, 0x08000020, 0x08000800, 0x00000820, + 0x00020800, 0x00020020, 0x08020020, 0x08020800, + 0x00000820, 0x00000000, 0x00000000, 0x08020020, + 0x08000020, 0x08000800, 0x00020820, 0x00020000, + 0x00020820, 0x00020000, 0x08020800, 0x00000800, + 0x00000020, 0x08020020, 0x00000800, 0x00020820, + 0x08000800, 0x00000020, 0x08000020, 0x08020000, + 0x08020020, 0x08000000, 0x00020000, 0x08000820, + 0x00000000, 0x08020820, 0x00020020, 0x08000020, + 0x08020000, 0x08000800, 0x08000820, 0x00000000, + 0x08020820, 0x00020800, 0x00020800, 0x00000820, + 0x00000820, 0x00020020, 0x08000000, 0x08020800 +}; + +static __inline uint32_t +Fconf(uint32_t r0, uint32_t skl, uint32_t skr) +{ + uint32_t r1; + + r1 = (r0 << 16) | (r0 >> 16); + return + S1[((r1 >> 11) ^ (skl >> 18)) & 0x3F] + | S2[((r0 >> 23) ^ (skl >> 12)) & 0x3F] + | S3[((r0 >> 19) ^ (skl >> 6)) & 0x3F] + | S4[((r0 >> 15) ^ (skl )) & 0x3F] + | S5[((r0 >> 11) ^ (skr >> 18)) & 0x3F] + | S6[((r0 >> 7) ^ (skr >> 12)) & 0x3F] + | S7[((r0 >> 3) ^ (skr >> 6)) & 0x3F] + | S8[((r1 >> 15) ^ (skr )) & 0x3F]; +} + +static void +process_block_unit(uint32_t *pl, uint32_t *pr, const uint32_t *skey) +{ + int i; + uint32_t l, r; + + l = *pl; + r = *pr; + for (i = 0; i < 16; i ++) { + uint32_t t; + + t = l ^ Fconf(r, skey[(i << 1) + 0], skey[(i << 1) + 1]); + l = r; + r = t; + } + *pl = r; + *pr = l; +} + +/* see inner.h */ +void +br_des_tab_process_block(unsigned num_rounds, const uint32_t *skey, void *block) +{ + unsigned char *buf; + uint32_t l, r; + + buf = block; + l = br_dec32be(buf); + r = br_dec32be(buf + 4); + br_des_do_IP(&l, &r); + while (num_rounds -- > 0) { + process_block_unit(&l, &r, skey); + skey += 32; + } + br_des_do_invIP(&l, &r); + br_enc32be(buf, l); + br_enc32be(buf + 4, r); +} + +static void +keysched_unit(uint32_t *skey, const void *key) +{ + int i; + + br_des_keysched_unit(skey, key); + + /* + * Apply PC-2 to get the 48-bit subkeys. + */ + for (i = 0; i < 16; i ++) { + uint32_t xl, xr, ul, ur; + int j; + + xl = skey[(i << 1) + 0]; + xr = skey[(i << 1) + 1]; + ul = 0; + ur = 0; + for (j = 0; j < 28; j ++) { + ul |= (xl & 1) << PC2left[j]; + ur |= (xr & 1) << PC2right[j]; + xl >>= 1; + xr >>= 1; + } + skey[(i << 1) + 0] = ul; + skey[(i << 1) + 1] = ur; + } +} + +/* see inner.h */ +unsigned +br_des_tab_keysched(uint32_t *skey, const void *key, size_t key_len) +{ + switch (key_len) { + case 8: + keysched_unit(skey, key); + return 1; + case 16: + keysched_unit(skey, key); + keysched_unit(skey + 32, (const unsigned char *)key + 8); + br_des_rev_skey(skey + 32); + memcpy(skey + 64, skey, 32 * sizeof *skey); + return 3; + default: + keysched_unit(skey, key); + keysched_unit(skey + 32, (const unsigned char *)key + 8); + br_des_rev_skey(skey + 32); + keysched_unit(skey + 64, (const unsigned char *)key + 16); + return 3; + } +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/des_tab_cbcdec.c b/BearSSL-OG/libbearssl/src/symcipher/des_tab_cbcdec.c new file mode 100644 index 0000000..e7eabe9 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/des_tab_cbcdec.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_des_tab_cbcdec_init(br_des_tab_cbcdec_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_des_tab_cbcdec_vtable; + ctx->num_rounds = br_des_tab_keysched(ctx->skey, key, len); + if (len == 8) { + br_des_rev_skey(ctx->skey); + } else { + int i; + + for (i = 0; i < 48; i += 2) { + uint32_t t; + + t = ctx->skey[i]; + ctx->skey[i] = ctx->skey[94 - i]; + ctx->skey[94 - i] = t; + t = ctx->skey[i + 1]; + ctx->skey[i + 1] = ctx->skey[95 - i]; + ctx->skey[95 - i] = t; + } + } +} + +/* see bearssl_block.h */ +void +br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf, *ivbuf; + + ivbuf = iv; + buf = data; + while (len > 0) { + unsigned char tmp[8]; + int i; + + memcpy(tmp, buf, 8); + br_des_tab_process_block(ctx->num_rounds, ctx->skey, buf); + for (i = 0; i < 8; i ++) { + buf[i] ^= ivbuf[i]; + } + memcpy(ivbuf, tmp, 8); + buf += 8; + len -= 8; + } +} + +/* see bearssl_block.h */ +const br_block_cbcdec_class br_des_tab_cbcdec_vtable = { + sizeof(br_des_tab_cbcdec_keys), + 8, + 3, + (void (*)(const br_block_cbcdec_class **, const void *, size_t)) + &br_des_tab_cbcdec_init, + (void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t)) + &br_des_tab_cbcdec_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/des_tab_cbcenc.c b/BearSSL-OG/libbearssl/src/symcipher/des_tab_cbcenc.c new file mode 100644 index 0000000..3a45ba3 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/des_tab_cbcenc.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_block.h */ +void +br_des_tab_cbcenc_init(br_des_tab_cbcenc_keys *ctx, + const void *key, size_t len) +{ + ctx->vtable = &br_des_tab_cbcenc_vtable; + ctx->num_rounds = br_des_tab_keysched(ctx->skey, key, len); +} + +/* see bearssl_block.h */ +void +br_des_tab_cbcenc_run(const br_des_tab_cbcenc_keys *ctx, + void *iv, void *data, size_t len) +{ + unsigned char *buf, *ivbuf; + + ivbuf = iv; + buf = data; + while (len > 0) { + int i; + + for (i = 0; i < 8; i ++) { + buf[i] ^= ivbuf[i]; + } + br_des_tab_process_block(ctx->num_rounds, ctx->skey, buf); + memcpy(ivbuf, buf, 8); + buf += 8; + len -= 8; + } +} + +/* see bearssl_block.h */ +const br_block_cbcenc_class br_des_tab_cbcenc_vtable = { + sizeof(br_des_tab_cbcenc_keys), + 8, + 3, + (void (*)(const br_block_cbcenc_class **, const void *, size_t)) + &br_des_tab_cbcenc_init, + (void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t)) + &br_des_tab_cbcenc_run +}; diff --git a/BearSSL-OG/libbearssl/src/symcipher/poly1305_ctmul.c b/BearSSL-OG/libbearssl/src/symcipher/poly1305_ctmul.c new file mode 100644 index 0000000..150e610 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/poly1305_ctmul.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Perform the inner processing of blocks for Poly1305. The accumulator + * and the r key are provided as arrays of 26-bit words (these words + * are allowed to have an extra bit, i.e. use 27 bits). + * + * On output, all accumulator words fit on 26 bits, except acc[1], which + * may be slightly larger (but by a very small amount only). + */ +static void +poly1305_inner(uint32_t *acc, const uint32_t *r, const void *data, size_t len) +{ + /* + * Implementation notes: we split the 130-bit values into five + * 26-bit words. This gives us some space for carries. + * + * This code is inspired from the public-domain code available + * on: + * https://github.com/floodyberry/poly1305-donna + * + * Since we compute modulo 2^130-5, the "upper words" become + * low words with a factor of 5; that is, x*2^130 = x*5 mod p. + */ + const unsigned char *buf; + uint32_t a0, a1, a2, a3, a4; + uint32_t r0, r1, r2, r3, r4; + uint32_t u1, u2, u3, u4; + + r0 = r[0]; + r1 = r[1]; + r2 = r[2]; + r3 = r[3]; + r4 = r[4]; + + u1 = r1 * 5; + u2 = r2 * 5; + u3 = r3 * 5; + u4 = r4 * 5; + + a0 = acc[0]; + a1 = acc[1]; + a2 = acc[2]; + a3 = acc[3]; + a4 = acc[4]; + + buf = data; + while (len > 0) { + uint64_t w0, w1, w2, w3, w4; + uint64_t c; + unsigned char tmp[16]; + + /* + * If there is a partial block, right-pad it with zeros. + */ + if (len < 16) { + memset(tmp, 0, sizeof tmp); + memcpy(tmp, buf, len); + buf = tmp; + len = 16; + } + + /* + * Decode next block and apply the "high bit"; that value + * is added to the accumulator. + */ + a0 += br_dec32le(buf) & 0x03FFFFFF; + a1 += (br_dec32le(buf + 3) >> 2) & 0x03FFFFFF; + a2 += (br_dec32le(buf + 6) >> 4) & 0x03FFFFFF; + a3 += (br_dec32le(buf + 9) >> 6) & 0x03FFFFFF; + a4 += (br_dec32le(buf + 12) >> 8) | 0x01000000; + + /* + * Compute multiplication. + */ +#define M(x, y) ((uint64_t)(x) * (uint64_t)(y)) + + w0 = M(a0, r0) + M(a1, u4) + M(a2, u3) + M(a3, u2) + M(a4, u1); + w1 = M(a0, r1) + M(a1, r0) + M(a2, u4) + M(a3, u3) + M(a4, u2); + w2 = M(a0, r2) + M(a1, r1) + M(a2, r0) + M(a3, u4) + M(a4, u3); + w3 = M(a0, r3) + M(a1, r2) + M(a2, r1) + M(a3, r0) + M(a4, u4); + w4 = M(a0, r4) + M(a1, r3) + M(a2, r2) + M(a3, r1) + M(a4, r0); + +#undef M + /* + * Perform some (partial) modular reduction. This step is + * enough to keep values in ranges such that there won't + * be carry overflows. Most of the reduction was done in + * the multiplication step (by using the 'u*' values, and + * using the fact that 2^130 = -5 mod p); here we perform + * some carry propagation. + */ + c = w0 >> 26; + a0 = (uint32_t)w0 & 0x3FFFFFF; + w1 += c; + c = w1 >> 26; + a1 = (uint32_t)w1 & 0x3FFFFFF; + w2 += c; + c = w2 >> 26; + a2 = (uint32_t)w2 & 0x3FFFFFF; + w3 += c; + c = w3 >> 26; + a3 = (uint32_t)w3 & 0x3FFFFFF; + w4 += c; + c = w4 >> 26; + a4 = (uint32_t)w4 & 0x3FFFFFF; + a0 += (uint32_t)c * 5; + a1 += a0 >> 26; + a0 &= 0x3FFFFFF; + + buf += 16; + len -= 16; + } + + acc[0] = a0; + acc[1] = a1; + acc[2] = a2; + acc[3] = a3; + acc[4] = a4; +} + +/* see bearssl_block.h */ +void +br_poly1305_ctmul_run(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt) +{ + unsigned char pkey[32], foot[16]; + uint32_t r[5], acc[5], cc, ctl, hi; + uint64_t w; + int i; + + /* + * Compute the MAC key. The 'r' value is the first 16 bytes of + * pkey[]. + */ + memset(pkey, 0, sizeof pkey); + ichacha(key, iv, 0, pkey, sizeof pkey); + + /* + * If encrypting, ChaCha20 must run first, followed by Poly1305. + * When decrypting, the operations are reversed. + */ + if (encrypt) { + ichacha(key, iv, 1, data, len); + } + + /* + * Run Poly1305. We must process the AAD, then ciphertext, then + * the footer (with the lengths). Note that the AAD and ciphertext + * are meant to be padded with zeros up to the next multiple of 16, + * and the length of the footer is 16 bytes as well. + */ + + /* + * Decode the 'r' value into 26-bit words, with the "clamping" + * operation applied. + */ + r[0] = br_dec32le(pkey) & 0x03FFFFFF; + r[1] = (br_dec32le(pkey + 3) >> 2) & 0x03FFFF03; + r[2] = (br_dec32le(pkey + 6) >> 4) & 0x03FFC0FF; + r[3] = (br_dec32le(pkey + 9) >> 6) & 0x03F03FFF; + r[4] = (br_dec32le(pkey + 12) >> 8) & 0x000FFFFF; + + /* + * Accumulator is 0. + */ + memset(acc, 0, sizeof acc); + + /* + * Process the additional authenticated data, ciphertext, and + * footer in due order. + */ + br_enc64le(foot, (uint64_t)aad_len); + br_enc64le(foot + 8, (uint64_t)len); + poly1305_inner(acc, r, aad, aad_len); + poly1305_inner(acc, r, data, len); + poly1305_inner(acc, r, foot, sizeof foot); + + /* + * Finalise modular reduction. This is done with carry propagation + * and applying the '2^130 = -5 mod p' rule. Note that the output + * of poly1035_inner() is already mostly reduced, since only + * acc[1] may be (very slightly) above 2^26. A single loop back + * to acc[1] will be enough to make the value fit in 130 bits. + */ + cc = 0; + for (i = 1; i <= 6; i ++) { + int j; + + j = (i >= 5) ? i - 5 : i; + acc[j] += cc; + cc = acc[j] >> 26; + acc[j] &= 0x03FFFFFF; + } + + /* + * We may still have a value in the 2^130-5..2^130-1 range, in + * which case we must reduce it again. The code below selects, + * in constant-time, between 'acc' and 'acc-p', + */ + ctl = GT(acc[0], 0x03FFFFFA); + for (i = 1; i < 5; i ++) { + ctl &= EQ(acc[i], 0x03FFFFFF); + } + cc = 5; + for (i = 0; i < 5; i ++) { + uint32_t t; + + t = (acc[i] + cc); + cc = t >> 26; + t &= 0x03FFFFFF; + acc[i] = MUX(ctl, t, acc[i]); + } + + /* + * Convert back the accumulator to 32-bit words, and add the + * 's' value (second half of pkey[]). That addition is done + * modulo 2^128. + */ + w = (uint64_t)acc[0] + ((uint64_t)acc[1] << 26) + br_dec32le(pkey + 16); + br_enc32le((unsigned char *)tag, (uint32_t)w); + w = (w >> 32) + ((uint64_t)acc[2] << 20) + br_dec32le(pkey + 20); + br_enc32le((unsigned char *)tag + 4, (uint32_t)w); + w = (w >> 32) + ((uint64_t)acc[3] << 14) + br_dec32le(pkey + 24); + br_enc32le((unsigned char *)tag + 8, (uint32_t)w); + hi = (uint32_t)(w >> 32) + (acc[4] << 8) + br_dec32le(pkey + 28); + br_enc32le((unsigned char *)tag + 12, hi); + + /* + * If decrypting, then ChaCha20 runs _after_ Poly1305. + */ + if (!encrypt) { + ichacha(key, iv, 1, data, len); + } +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/poly1305_ctmul32.c b/BearSSL-OG/libbearssl/src/symcipher/poly1305_ctmul32.c new file mode 100644 index 0000000..15d9635 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/poly1305_ctmul32.c @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * Perform the inner processing of blocks for Poly1305. + */ +static void +poly1305_inner(uint32_t *a, const uint32_t *r, const void *data, size_t len) +{ + /* + * Implementation notes: we split the 130-bit values into ten + * 13-bit words. This gives us some space for carries and allows + * using only 32x32->32 multiplications, which are way faster than + * 32x32->64 multiplications on the ARM Cortex-M0/M0+, and also + * help in making constant-time code on the Cortex-M3. + * + * Since we compute modulo 2^130-5, the "upper words" become + * low words with a factor of 5; that is, x*2^130 = x*5 mod p. + * This has already been integrated in the r[] array, which + * is extended to the 0..18 range. + * + * In each loop iteration, a[] and r[] words are 13-bit each, + * except a[1] which may use 14 bits. + */ + const unsigned char *buf; + + buf = data; + while (len > 0) { + unsigned char tmp[16]; + uint32_t b[10]; + unsigned u, v; + uint32_t z, cc1, cc2; + + /* + * If there is a partial block, right-pad it with zeros. + */ + if (len < 16) { + memset(tmp, 0, sizeof tmp); + memcpy(tmp, buf, len); + buf = tmp; + len = 16; + } + + /* + * Decode next block and apply the "high bit"; that value + * is added to the accumulator. + */ + v = br_dec16le(buf); + a[0] += v & 0x01FFF; + v >>= 13; + v |= buf[2] << 3; + v |= buf[3] << 11; + a[1] += v & 0x01FFF; + v >>= 13; + v |= buf[4] << 6; + a[2] += v & 0x01FFF; + v >>= 13; + v |= buf[5] << 1; + v |= buf[6] << 9; + a[3] += v & 0x01FFF; + v >>= 13; + v |= buf[7] << 4; + v |= buf[8] << 12; + a[4] += v & 0x01FFF; + v >>= 13; + v |= buf[9] << 7; + a[5] += v & 0x01FFF; + v >>= 13; + v |= buf[10] << 2; + v |= buf[11] << 10; + a[6] += v & 0x01FFF; + v >>= 13; + v |= buf[12] << 5; + a[7] += v & 0x01FFF; + v = br_dec16le(buf + 13); + a[8] += v & 0x01FFF; + v >>= 13; + v |= buf[15] << 3; + a[9] += v | 0x00800; + + /* + * At that point, all a[] values fit on 14 bits, while + * all r[] values fit on 13 bits. Thus products fit on + * 27 bits, and we can accumulate up to 31 of them in + * a 32-bit word and still have some room for carries. + */ + + /* + * Now a[] contains words with values up to 14 bits each. + * We perform the multiplication with r[]. + * + * The extended words of r[] may be larger than 13 bits + * (they are 5 times a 13-bit word) so the full summation + * may yield values up to 46 times a 27-bit word, which + * does not fit on a 32-bit word. To avoid that issue, we + * must split the loop below in two, with a carry + * propagation operation in the middle. + */ + cc1 = 0; + for (u = 0; u < 10; u ++) { + uint32_t s; + + s = cc1 + + MUL15(a[0], r[u + 9 - 0]) + + MUL15(a[1], r[u + 9 - 1]) + + MUL15(a[2], r[u + 9 - 2]) + + MUL15(a[3], r[u + 9 - 3]) + + MUL15(a[4], r[u + 9 - 4]); + b[u] = s & 0x1FFF; + cc1 = s >> 13; + } + cc2 = 0; + for (u = 0; u < 10; u ++) { + uint32_t s; + + s = b[u] + cc2 + + MUL15(a[5], r[u + 9 - 5]) + + MUL15(a[6], r[u + 9 - 6]) + + MUL15(a[7], r[u + 9 - 7]) + + MUL15(a[8], r[u + 9 - 8]) + + MUL15(a[9], r[u + 9 - 9]); + b[u] = s & 0x1FFF; + cc2 = s >> 13; + } + memcpy(a, b, sizeof b); + + /* + * The two carries "loop back" with a factor of 5. We + * propagate them into a[0] and a[1]. + */ + z = cc1 + cc2; + z += (z << 2) + a[0]; + a[0] = z & 0x1FFF; + a[1] += z >> 13; + + buf += 16; + len -= 16; + } +} + +/* see bearssl_block.h */ +void +br_poly1305_ctmul32_run(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt) +{ + unsigned char pkey[32], foot[16]; + uint32_t z, r[19], acc[10], cc, ctl; + int i; + + /* + * Compute the MAC key. The 'r' value is the first 16 bytes of + * pkey[]. + */ + memset(pkey, 0, sizeof pkey); + ichacha(key, iv, 0, pkey, sizeof pkey); + + /* + * If encrypting, ChaCha20 must run first, followed by Poly1305. + * When decrypting, the operations are reversed. + */ + if (encrypt) { + ichacha(key, iv, 1, data, len); + } + + /* + * Run Poly1305. We must process the AAD, then ciphertext, then + * the footer (with the lengths). Note that the AAD and ciphertext + * are meant to be padded with zeros up to the next multiple of 16, + * and the length of the footer is 16 bytes as well. + */ + + /* + * Decode the 'r' value into 13-bit words, with the "clamping" + * operation applied. + */ + z = br_dec32le(pkey) & 0x03FFFFFF; + r[9] = z & 0x1FFF; + r[10] = z >> 13; + z = (br_dec32le(pkey + 3) >> 2) & 0x03FFFF03; + r[11] = z & 0x1FFF; + r[12] = z >> 13; + z = (br_dec32le(pkey + 6) >> 4) & 0x03FFC0FF; + r[13] = z & 0x1FFF; + r[14] = z >> 13; + z = (br_dec32le(pkey + 9) >> 6) & 0x03F03FFF; + r[15] = z & 0x1FFF; + r[16] = z >> 13; + z = (br_dec32le(pkey + 12) >> 8) & 0x000FFFFF; + r[17] = z & 0x1FFF; + r[18] = z >> 13; + + /* + * Extend r[] with the 5x factor pre-applied. + */ + for (i = 0; i < 9; i ++) { + r[i] = MUL15(5, r[i + 10]); + } + + /* + * Accumulator is 0. + */ + memset(acc, 0, sizeof acc); + + /* + * Process the additional authenticated data, ciphertext, and + * footer in due order. + */ + br_enc64le(foot, (uint64_t)aad_len); + br_enc64le(foot + 8, (uint64_t)len); + poly1305_inner(acc, r, aad, aad_len); + poly1305_inner(acc, r, data, len); + poly1305_inner(acc, r, foot, sizeof foot); + + /* + * Finalise modular reduction. This is done with carry propagation + * and applying the '2^130 = -5 mod p' rule. Note that the output + * of poly1035_inner() is already mostly reduced, since only + * acc[1] may be (very slightly) above 2^13. A single loop back + * to acc[1] will be enough to make the value fit in 130 bits. + */ + cc = 0; + for (i = 1; i < 10; i ++) { + z = acc[i] + cc; + acc[i] = z & 0x1FFF; + cc = z >> 13; + } + z = acc[0] + cc + (cc << 2); + acc[0] = z & 0x1FFF; + acc[1] += z >> 13; + + /* + * We may still have a value in the 2^130-5..2^130-1 range, in + * which case we must reduce it again. The code below selects, + * in constant-time, between 'acc' and 'acc-p', + */ + ctl = GT(acc[0], 0x1FFA); + for (i = 1; i < 10; i ++) { + ctl &= EQ(acc[i], 0x1FFF); + } + acc[0] = MUX(ctl, acc[0] - 0x1FFB, acc[0]); + for (i = 1; i < 10; i ++) { + acc[i] &= ~(-ctl); + } + + /* + * Convert back the accumulator to 32-bit words, and add the + * 's' value (second half of pkey[]). That addition is done + * modulo 2^128. + */ + z = acc[0] + (acc[1] << 13) + br_dec16le(pkey + 16); + br_enc16le((unsigned char *)tag, z & 0xFFFF); + z = (z >> 16) + (acc[2] << 10) + br_dec16le(pkey + 18); + br_enc16le((unsigned char *)tag + 2, z & 0xFFFF); + z = (z >> 16) + (acc[3] << 7) + br_dec16le(pkey + 20); + br_enc16le((unsigned char *)tag + 4, z & 0xFFFF); + z = (z >> 16) + (acc[4] << 4) + br_dec16le(pkey + 22); + br_enc16le((unsigned char *)tag + 6, z & 0xFFFF); + z = (z >> 16) + (acc[5] << 1) + (acc[6] << 14) + br_dec16le(pkey + 24); + br_enc16le((unsigned char *)tag + 8, z & 0xFFFF); + z = (z >> 16) + (acc[7] << 11) + br_dec16le(pkey + 26); + br_enc16le((unsigned char *)tag + 10, z & 0xFFFF); + z = (z >> 16) + (acc[8] << 8) + br_dec16le(pkey + 28); + br_enc16le((unsigned char *)tag + 12, z & 0xFFFF); + z = (z >> 16) + (acc[9] << 5) + br_dec16le(pkey + 30); + br_enc16le((unsigned char *)tag + 14, z & 0xFFFF); + + /* + * If decrypting, then ChaCha20 runs _after_ Poly1305. + */ + if (!encrypt) { + ichacha(key, iv, 1, data, len); + } +} diff --git a/BearSSL-OG/libbearssl/src/symcipher/poly1305_ctmulq.c b/BearSSL-OG/libbearssl/src/symcipher/poly1305_ctmulq.c new file mode 100644 index 0000000..b00683a --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/poly1305_ctmulq.c @@ -0,0 +1,475 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +#if BR_INT128 || BR_UMUL128 + +#if BR_INT128 + +#define MUL128(hi, lo, x, y) do { \ + unsigned __int128 mul128tmp; \ + mul128tmp = (unsigned __int128)(x) * (unsigned __int128)(y); \ + (hi) = (uint64_t)(mul128tmp >> 64); \ + (lo) = (uint64_t)mul128tmp; \ + } while (0) + +#elif BR_UMUL128 + +#include + +#define MUL128(hi, lo, x, y) do { \ + (lo) = _umul128((x), (y), &(hi)); \ + } while (0) + +#endif + +#define MASK42 ((uint64_t)0x000003FFFFFFFFFF) +#define MASK44 ((uint64_t)0x00000FFFFFFFFFFF) + +/* + * The "accumulator" word is nominally a 130-bit value. We split it into + * words of 44 bits, each held in a 64-bit variable. + * + * If the current accumulator is a = a0 + a1*W + a2*W^2 (where W = 2^44) + * and r = r0 + r1*W + r2*W^2, then: + * + * a*r = (a0*r0) + * + (a0*r1 + a1*r0) * W + * + (a0*r2 + a1*r1 + a2*r0) * W^2 + * + (a1*r2 + a2*r1) * W^3 + * + (a2*r2) * W^4 + * + * We want to reduce that value modulo p = 2^130-5, so W^3 = 20 mod p, + * and W^4 = 20*W mod p. Thus, if we define u1 = 20*r1 and u2 = 20*r2, + * then the equations above become: + * + * b0 = a0*r0 + a1*u2 + a2*u1 + * b1 = a0*r1 + a1*r0 + a2*u2 + * b2 = a0*r2 + a1*r1 + a2*r0 + * + * In order to make u1 fit in 44 bits, we can change these equations + * into: + * + * b0 = a0*r0 + a1*u2 + a2*t1 + * b1 = a0*r1 + a1*r0 + a2*t2 + * b2 = a0*r2 + a1*r1 + a2*r0 + * + * Where t1 is u1 truncated to 44 bits, and t2 is u2 added to the extra + * bits of u1. Note that since r is clamped down to a 124-bit value, the + * values u2 and t2 fit on 44 bits too. + * + * The bx values are larger than 44 bits, so we may split them into a + * lower half (cx, 44 bits) and an upper half (dx). The new values for + * the accumulator are then: + * + * e0 = c0 + 20*d2 + * e1 = c1 + d0 + * e2 = c2 + d1 + * + * The equations allow for some room, i.e. the ax values may be larger + * than 44 bits. Similarly, the ex values will usually be larger than + * the ax. Thus, some sort of carry propagation must be done regularly, + * though not necessarily at each iteration. In particular, we do not + * need to compute the additions (for the bx values) over 128-bit + * quantities; we can stick to 64-bit computations. + * + * + * Since the 128-bit result of a 64x64 multiplication is actually + * represented over two 64-bit registers, it is cheaper to arrange for + * any split that happens between the "high" and "low" halves to be on + * that 64-bit boundary. This is done by left shifting the rx, ux and tx + * by 20 bits (since they all fit on 44 bits each, this shift is + * always possible). + */ + +static void +poly1305_inner_big(uint64_t *acc, uint64_t *r, const void *data, size_t len) +{ + +#define MX(hi, lo, m0, m1, m2) do { \ + uint64_t mxhi, mxlo; \ + MUL128(mxhi, mxlo, a0, m0); \ + (hi) = mxhi; \ + (lo) = mxlo >> 20; \ + MUL128(mxhi, mxlo, a1, m1); \ + (hi) += mxhi; \ + (lo) += mxlo >> 20; \ + MUL128(mxhi, mxlo, a2, m2); \ + (hi) += mxhi; \ + (lo) += mxlo >> 20; \ + } while (0) + + const unsigned char *buf; + uint64_t a0, a1, a2; + uint64_t r0, r1, r2, t1, t2, u2; + + r0 = r[0]; + r1 = r[1]; + r2 = r[2]; + t1 = r[3]; + t2 = r[4]; + u2 = r[5]; + a0 = acc[0]; + a1 = acc[1]; + a2 = acc[2]; + buf = data; + + while (len > 0) { + uint64_t v0, v1, v2; + uint64_t c0, c1, c2, d0, d1, d2; + + v0 = br_dec64le(buf + 0); + v1 = br_dec64le(buf + 8); + v2 = v1 >> 24; + v1 = ((v0 >> 44) | (v1 << 20)) & MASK44; + v0 &= MASK44; + a0 += v0; + a1 += v1; + a2 += v2 + ((uint64_t)1 << 40); + MX(d0, c0, r0, u2, t1); + MX(d1, c1, r1, r0, t2); + MX(d2, c2, r2, r1, r0); + a0 = c0 + 20 * d2; + a1 = c1 + d0; + a2 = c2 + d1; + + v0 = br_dec64le(buf + 16); + v1 = br_dec64le(buf + 24); + v2 = v1 >> 24; + v1 = ((v0 >> 44) | (v1 << 20)) & MASK44; + v0 &= MASK44; + a0 += v0; + a1 += v1; + a2 += v2 + ((uint64_t)1 << 40); + MX(d0, c0, r0, u2, t1); + MX(d1, c1, r1, r0, t2); + MX(d2, c2, r2, r1, r0); + a0 = c0 + 20 * d2; + a1 = c1 + d0; + a2 = c2 + d1; + + v0 = br_dec64le(buf + 32); + v1 = br_dec64le(buf + 40); + v2 = v1 >> 24; + v1 = ((v0 >> 44) | (v1 << 20)) & MASK44; + v0 &= MASK44; + a0 += v0; + a1 += v1; + a2 += v2 + ((uint64_t)1 << 40); + MX(d0, c0, r0, u2, t1); + MX(d1, c1, r1, r0, t2); + MX(d2, c2, r2, r1, r0); + a0 = c0 + 20 * d2; + a1 = c1 + d0; + a2 = c2 + d1; + + v0 = br_dec64le(buf + 48); + v1 = br_dec64le(buf + 56); + v2 = v1 >> 24; + v1 = ((v0 >> 44) | (v1 << 20)) & MASK44; + v0 &= MASK44; + a0 += v0; + a1 += v1; + a2 += v2 + ((uint64_t)1 << 40); + MX(d0, c0, r0, u2, t1); + MX(d1, c1, r1, r0, t2); + MX(d2, c2, r2, r1, r0); + a0 = c0 + 20 * d2; + a1 = c1 + d0; + a2 = c2 + d1; + + a1 += a0 >> 44; + a0 &= MASK44; + a2 += a1 >> 44; + a1 &= MASK44; + a0 += 20 * (a2 >> 44); + a2 &= MASK44; + + buf += 64; + len -= 64; + } + acc[0] = a0; + acc[1] = a1; + acc[2] = a2; + +#undef MX +} + +static void +poly1305_inner_small(uint64_t *acc, uint64_t *r, const void *data, size_t len) +{ + const unsigned char *buf; + uint64_t a0, a1, a2; + uint64_t r0, r1, r2, t1, t2, u2; + + r0 = r[0]; + r1 = r[1]; + r2 = r[2]; + t1 = r[3]; + t2 = r[4]; + u2 = r[5]; + a0 = acc[0]; + a1 = acc[1]; + a2 = acc[2]; + buf = data; + + while (len > 0) { + uint64_t v0, v1, v2; + uint64_t c0, c1, c2, d0, d1, d2; + unsigned char tmp[16]; + + if (len < 16) { + memcpy(tmp, buf, len); + memset(tmp + len, 0, (sizeof tmp) - len); + buf = tmp; + len = 16; + } + v0 = br_dec64le(buf + 0); + v1 = br_dec64le(buf + 8); + + v2 = v1 >> 24; + v1 = ((v0 >> 44) | (v1 << 20)) & MASK44; + v0 &= MASK44; + + a0 += v0; + a1 += v1; + a2 += v2 + ((uint64_t)1 << 40); + +#define MX(hi, lo, m0, m1, m2) do { \ + uint64_t mxhi, mxlo; \ + MUL128(mxhi, mxlo, a0, m0); \ + (hi) = mxhi; \ + (lo) = mxlo >> 20; \ + MUL128(mxhi, mxlo, a1, m1); \ + (hi) += mxhi; \ + (lo) += mxlo >> 20; \ + MUL128(mxhi, mxlo, a2, m2); \ + (hi) += mxhi; \ + (lo) += mxlo >> 20; \ + } while (0) + + MX(d0, c0, r0, u2, t1); + MX(d1, c1, r1, r0, t2); + MX(d2, c2, r2, r1, r0); + +#undef MX + + a0 = c0 + 20 * d2; + a1 = c1 + d0; + a2 = c2 + d1; + + a1 += a0 >> 44; + a0 &= MASK44; + a2 += a1 >> 44; + a1 &= MASK44; + a0 += 20 * (a2 >> 44); + a2 &= MASK44; + + buf += 16; + len -= 16; + } + acc[0] = a0; + acc[1] = a1; + acc[2] = a2; +} + +static inline void +poly1305_inner(uint64_t *acc, uint64_t *r, const void *data, size_t len) +{ + if (len >= 64) { + size_t len2; + + len2 = len & ~(size_t)63; + poly1305_inner_big(acc, r, data, len2); + data = (const unsigned char *)data + len2; + len -= len2; + } + if (len > 0) { + poly1305_inner_small(acc, r, data, len); + } +} + +/* see bearssl_block.h */ +void +br_poly1305_ctmulq_run(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt) +{ + unsigned char pkey[32], foot[16]; + uint64_t r[6], acc[3], r0, r1; + uint32_t v0, v1, v2, v3, v4; + uint64_t w0, w1, w2, w3; + uint32_t ctl; + + /* + * Compute the MAC key. The 'r' value is the first 16 bytes of + * pkey[]. + */ + memset(pkey, 0, sizeof pkey); + ichacha(key, iv, 0, pkey, sizeof pkey); + + /* + * If encrypting, ChaCha20 must run first, followed by Poly1305. + * When decrypting, the operations are reversed. + */ + if (encrypt) { + ichacha(key, iv, 1, data, len); + } + + /* + * Run Poly1305. We must process the AAD, then ciphertext, then + * the footer (with the lengths). Note that the AAD and ciphertext + * are meant to be padded with zeros up to the next multiple of 16, + * and the length of the footer is 16 bytes as well. + */ + + /* + * Apply the "clamping" on r. + */ + pkey[ 3] &= 0x0F; + pkey[ 4] &= 0xFC; + pkey[ 7] &= 0x0F; + pkey[ 8] &= 0xFC; + pkey[11] &= 0x0F; + pkey[12] &= 0xFC; + pkey[15] &= 0x0F; + + /* + * Decode the 'r' value into 44-bit words, left-shifted by 20 bits. + * Also compute the u1 and u2 values. + */ + r0 = br_dec64le(pkey + 0); + r1 = br_dec64le(pkey + 8); + r[0] = r0 << 20; + r[1] = ((r0 >> 24) | (r1 << 40)) & ~(uint64_t)0xFFFFF; + r[2] = (r1 >> 4) & ~(uint64_t)0xFFFFF; + r1 = 20 * (r[1] >> 20); + r[3] = r1 << 20; + r[5] = 20 * r[2]; + r[4] = (r[5] + (r1 >> 24)) & ~(uint64_t)0xFFFFF; + + /* + * Accumulator is 0. + */ + acc[0] = 0; + acc[1] = 0; + acc[2] = 0; + + /* + * Process the additional authenticated data, ciphertext, and + * footer in due order. + */ + br_enc64le(foot, (uint64_t)aad_len); + br_enc64le(foot + 8, (uint64_t)len); + poly1305_inner(acc, r, aad, aad_len); + poly1305_inner(acc, r, data, len); + poly1305_inner_small(acc, r, foot, sizeof foot); + + /* + * Finalise modular reduction. At that point, the value consists + * in three 44-bit values (the lowest one might be slightly above + * 2^44). Two loops shall be sufficient. + */ + acc[1] += (acc[0] >> 44); + acc[0] &= MASK44; + acc[2] += (acc[1] >> 44); + acc[1] &= MASK44; + acc[0] += 5 * (acc[2] >> 42); + acc[2] &= MASK42; + acc[1] += (acc[0] >> 44); + acc[0] &= MASK44; + acc[2] += (acc[1] >> 44); + acc[1] &= MASK44; + acc[0] += 5 * (acc[2] >> 42); + acc[2] &= MASK42; + + /* + * The value may still fall in the 2^130-5..2^130-1 range, in + * which case we must reduce it again. The code below selects, + * in constant-time, between 'acc' and 'acc-p'. We encode the + * value over four 32-bit integers to finish the operation. + */ + v0 = (uint32_t)acc[0]; + v1 = (uint32_t)(acc[0] >> 32) | ((uint32_t)acc[1] << 12); + v2 = (uint32_t)(acc[1] >> 20) | ((uint32_t)acc[2] << 24); + v3 = (uint32_t)(acc[2] >> 8); + v4 = (uint32_t)(acc[2] >> 40); + + ctl = GT(v0, 0xFFFFFFFA); + ctl &= EQ(v1, 0xFFFFFFFF); + ctl &= EQ(v2, 0xFFFFFFFF); + ctl &= EQ(v3, 0xFFFFFFFF); + ctl &= EQ(v4, 0x00000003); + v0 = MUX(ctl, v0 + 5, v0); + v1 = MUX(ctl, 0, v1); + v2 = MUX(ctl, 0, v2); + v3 = MUX(ctl, 0, v3); + + /* + * Add the "s" value. This is done modulo 2^128. Don't forget + * carry propagation... + */ + w0 = (uint64_t)v0 + (uint64_t)br_dec32le(pkey + 16); + w1 = (uint64_t)v1 + (uint64_t)br_dec32le(pkey + 20) + (w0 >> 32); + w2 = (uint64_t)v2 + (uint64_t)br_dec32le(pkey + 24) + (w1 >> 32); + w3 = (uint64_t)v3 + (uint64_t)br_dec32le(pkey + 28) + (w2 >> 32); + v0 = (uint32_t)w0; + v1 = (uint32_t)w1; + v2 = (uint32_t)w2; + v3 = (uint32_t)w3; + + /* + * Encode the tag. + */ + br_enc32le((unsigned char *)tag + 0, v0); + br_enc32le((unsigned char *)tag + 4, v1); + br_enc32le((unsigned char *)tag + 8, v2); + br_enc32le((unsigned char *)tag + 12, v3); + + /* + * If decrypting, then ChaCha20 runs _after_ Poly1305. + */ + if (!encrypt) { + ichacha(key, iv, 1, data, len); + } +} + +/* see bearssl_block.h */ +br_poly1305_run +br_poly1305_ctmulq_get(void) +{ + return &br_poly1305_ctmulq_run; +} + +#else + +/* see bearssl_block.h */ +br_poly1305_run +br_poly1305_ctmulq_get(void) +{ + return 0; +} + +#endif diff --git a/BearSSL-OG/libbearssl/src/symcipher/poly1305_i15.c b/BearSSL-OG/libbearssl/src/symcipher/poly1305_i15.c new file mode 100644 index 0000000..6f89212 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/symcipher/poly1305_i15.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* + * This is a "reference" implementation of Poly1305 that uses the + * generic "i15" code for big integers. It is slow, but it handles all + * big-integer operations with generic code, thereby avoiding most + * tricky situations with carry propagation and modular reduction. + */ + +/* + * Modulus: 2^130-5. + */ +static const uint16_t P1305[] = { + 0x008A, + 0x7FFB, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x03FF +}; + +/* + * -p mod 2^15. + */ +#define P0I 0x4CCD + +/* + * R^2 mod p, for conversion to Montgomery representation (R = 2^135, + * since we use 9 words of 15 bits each, and 15*9 = 135). + */ +static const uint16_t R2[] = { + 0x008A, + 0x6400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 +}; + +/* + * Perform the inner processing of blocks for Poly1305. The "r" array + * is in Montgomery representation, while the "a" array is not. + */ +static void +poly1305_inner(uint16_t *a, const uint16_t *r, const void *data, size_t len) +{ + const unsigned char *buf; + + buf = data; + while (len > 0) { + unsigned char tmp[16], rev[16]; + uint16_t b[10]; + uint32_t ctl; + int i; + + /* + * If there is a partial block, right-pad it with zeros. + */ + if (len < 16) { + memset(tmp, 0, sizeof tmp); + memcpy(tmp, buf, len); + buf = tmp; + len = 16; + } + + /* + * Decode next block and apply the "high bit". Since + * decoding is little-endian, we must byte-swap the buffer. + */ + for (i = 0; i < 16; i ++) { + rev[i] = buf[15 - i]; + } + br_i15_decode_mod(b, rev, sizeof rev, P1305); + b[9] |= 0x0100; + + /* + * Add the accumulator to the decoded block (modular + * addition). + */ + ctl = br_i15_add(b, a, 1); + ctl |= NOT(br_i15_sub(b, P1305, 0)); + br_i15_sub(b, P1305, ctl); + + /* + * Multiply by r, result is the new accumulator value. + */ + br_i15_montymul(a, b, r, P1305, P0I); + + buf += 16; + len -= 16; + } +} + +/* + * Byteswap a 16-byte value. + */ +static void +byteswap16(unsigned char *buf) +{ + int i; + + for (i = 0; i < 8; i ++) { + unsigned x; + + x = buf[i]; + buf[i] = buf[15 - i]; + buf[15 - i] = x; + } +} + +/* see bearssl_block.h */ +void +br_poly1305_i15_run(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt) +{ + unsigned char pkey[32], foot[16]; + uint16_t t[10], r[10], acc[10]; + + /* + * Compute the MAC key. The 'r' value is the first 16 bytes of + * pkey[]. + */ + memset(pkey, 0, sizeof pkey); + ichacha(key, iv, 0, pkey, sizeof pkey); + + /* + * If encrypting, ChaCha20 must run first, followed by Poly1305. + * When decrypting, the operations are reversed. + */ + if (encrypt) { + ichacha(key, iv, 1, data, len); + } + + /* + * Run Poly1305. We must process the AAD, then ciphertext, then + * the footer (with the lengths). Note that the AAD and ciphertext + * are meant to be padded with zeros up to the next multiple of 16, + * and the length of the footer is 16 bytes as well. + */ + + /* + * Apply the "clamping" operation on the encoded 'r' value. + */ + pkey[ 3] &= 0x0F; + pkey[ 7] &= 0x0F; + pkey[11] &= 0x0F; + pkey[15] &= 0x0F; + pkey[ 4] &= 0xFC; + pkey[ 8] &= 0xFC; + pkey[12] &= 0xFC; + + /* + * Decode the clamped 'r' value. Decoding should use little-endian + * so we must byteswap the value first. + */ + byteswap16(pkey); + br_i15_decode_mod(t, pkey, 16, P1305); + + /* + * Convert 'r' to Montgomery representation. + */ + br_i15_montymul(r, t, R2, P1305, P0I); + + /* + * Accumulator is 0. + */ + br_i15_zero(acc, 0x8A); + + /* + * Process the additional authenticated data, ciphertext, and + * footer in due order. + */ + br_enc64le(foot, (uint64_t)aad_len); + br_enc64le(foot + 8, (uint64_t)len); + poly1305_inner(acc, r, aad, aad_len); + poly1305_inner(acc, r, data, len); + poly1305_inner(acc, r, foot, sizeof foot); + + /* + * Decode the value 's'. Again, a byteswap is needed. + */ + byteswap16(pkey + 16); + br_i15_decode_mod(t, pkey + 16, 16, P1305); + + /* + * Add the value 's' to the accumulator. That addition is done + * modulo 2^128, so we just ignore the carry. + */ + br_i15_add(acc, t, 1); + + /* + * Encode the result (128 low bits) to the tag. Encoding should + * be little-endian. + */ + br_i15_encode(tag, 16, acc); + byteswap16(tag); + + /* + * If decrypting, then ChaCha20 runs _after_ Poly1305. + */ + if (!encrypt) { + ichacha(key, iv, 1, data, len); + } +} diff --git a/BearSSL-OG/libbearssl/src/x509/asn1.t0 b/BearSSL-OG/libbearssl/src/x509/asn1.t0 new file mode 100644 index 0000000..c329514 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/asn1.t0 @@ -0,0 +1,757 @@ +\ Copyright (c) 2016 Thomas Pornin +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +\ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +\ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +\ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +\ SOFTWARE. + +\ ======================================================================= + +\ This file contains code which is common to all engines that do some +\ ASN.1 decoding. It should not be compiled on its own, but only along +\ with another file (e.g. x509_minimal.t0) which uses it. +\ +\ Users must define several things: +\ +\ -- In the preamble, a macro called "CTX" that evaluates to the current +\ context structure. +\ +\ -- In the preamble, a macro called "CONTEXT_NAME" that evaluates to the +\ context structure type. This will be invoked during compilation. +\ +\ -- A word called "read8-low" ( -- x ) that reads the next byte, or -1 +\ if the input buffer is empty. That word is usually written in C. +\ +\ -- A word called "read-blob-inner" ( addr len -- addr len ) that is +\ the multi-byte version of read8-low. +\ +\ -- A word called "skip-remaining-inner" ( lim -- lim ) which reads but +\ drops some input bytes. + +preamble { + +#include "inner.h" + +} + +\ Read next source character, skipping blanks. +: skip-blanks begin char dup 32 > if ret then drop again ; + +: fail-oid + "Invalid OID" puts cr exitvm ; + +\ Read a decimal integer, followed by either a dot or whitespace. +\ Note: this does not check for overflows. +: parse-number ( -- val nextchar ) + char decval + begin + char + dup dup `. = swap 32 <= or if ret then + decval swap 10 * + + again ; + +\ Encode a number in unsigned 7E format. +: encode7E ( val -- ) + 0 encode7E-inner ; + +: encode7E-inner ( val eb -- ) + swap dup 0x7F > if + dup 7 u>> 0x80 encode7E-inner 0x7F and + then + or data-add8 ; + +\ Decode an OID from source, and encode it. First byte is length, +\ followed by encoded ASN.1 DER value. The OID is encoded in the +\ current data block. +: OID + \ Get current data address, and push a 0 for length. + current-data 0 data-add8 + \ Skip blanks and get first digit, which must be 0, 1 or 2. + skip-blanks decval dup 2 > if fail-oid then + 40 * + \ Next character must be a dot. + char `. <> if fail-oid then + \ Second group must be one or two digits. + parse-number { nextchar } + dup 40 >= if fail-oid then + + encode7E + \ While next character is a dot, keep encoding numbers. + begin nextchar `. = while + parse-number >nextchar + encode7E + repeat + \ Write back length in the first byte. + dup current-data swap - 1- swap data-set8 + ; immediate + +\ Define a new data word for an encoded OID. The OID is read from the +\ source. +: OID: + new-data-block next-word define-data-word postpone OID ; + +\ Define a word that evaluates to the address of a field within the +\ context. +: addr: + next-word { field } + "addr-" field + 0 1 define-word + 0 8191 "offsetof(CONTEXT_NAME, " field + ")" + make-CX + postpone literal postpone ; ; + +addr: pad + +\ Define a word that evaluates to an error code through a macro name. +: err: + next-word { name } + name 0 1 define-word + 0 63 "BR_" name + make-CX postpone literal postpone ; ; + +err: ERR_X509_INVALID_VALUE +err: ERR_X509_TRUNCATED +err: ERR_X509_EMPTY_CHAIN +err: ERR_X509_INNER_TRUNC +err: ERR_X509_BAD_TAG_CLASS +err: ERR_X509_BAD_TAG_VALUE +err: ERR_X509_INDEFINITE_LENGTH +err: ERR_X509_EXTRA_ELEMENT +err: ERR_X509_UNEXPECTED +err: ERR_X509_NOT_CONSTRUCTED +err: ERR_X509_NOT_PRIMITIVE +err: ERR_X509_PARTIAL_BYTE +err: ERR_X509_BAD_BOOLEAN +err: ERR_X509_OVERFLOW +err: ERR_X509_BAD_DN +err: ERR_X509_BAD_TIME +err: ERR_X509_UNSUPPORTED +err: ERR_X509_LIMIT_EXCEEDED +err: ERR_X509_WRONG_KEY_TYPE +err: ERR_X509_BAD_SIGNATURE +err: ERR_X509_EXPIRED +err: ERR_X509_DN_MISMATCH +err: ERR_X509_BAD_SERVER_NAME +err: ERR_X509_CRITICAL_EXTENSION +err: ERR_X509_NOT_CA +err: ERR_X509_FORBIDDEN_KEY_USAGE +err: ERR_X509_WEAK_PUBLIC_KEY + +: KEYTYPE_RSA CX 0 15 { BR_KEYTYPE_RSA } ; +: KEYTYPE_EC CX 0 15 { BR_KEYTYPE_EC } ; + +cc: fail ( err -- ! ) { + CTX->err = T0_POPi(); + T0_CO(); +} + +\ Read one byte from the stream. +: read8-nc ( -- x ) + begin + read8-low dup 0 >= if ret then + drop co + again ; + +\ Read one byte, enforcing current read limit. +: read8 ( lim -- lim x ) + dup ifnot ERR_X509_INNER_TRUNC fail then + 1- read8-nc ; + +\ Read a 16-bit value, big-endian encoding. +: read16be ( lim -- lim x ) + read8 8 << swap read8 rot + ; + +\ Read a 16-bit value, little-endian encoding. +: read16le ( lim -- lim x ) + read8 swap read8 8 << rot + ; + +\ Read all bytes from the current element, then close it (i.e. drop the +\ limit). Destination address is an offset within the context. +: read-blob ( lim addr -- ) + swap + begin dup while read-blob-inner dup if co then repeat + 2drop ; + +\ Skip remaining bytes in the current structure, but do not close it +\ (thus, this leaves the value 0 on the stack). +: skip-remaining ( lim -- lim ) + begin dup while skip-remaining-inner dup if co then repeat ; + +: skip-remaining-inner ( lim -- lim ) + 0 over read-blob-inner -rot 2drop ; + +cc: set8 ( val addr -- ) { + uint32_t addr = T0_POP(); + *((unsigned char *)CTX + addr) = (unsigned char)T0_POP(); +} + +cc: set16 ( val addr -- ) { + uint32_t addr = T0_POP(); + *(uint16_t *)(void *)((unsigned char *)CTX + addr) = T0_POP(); +} + +cc: set32 ( val addr -- ) { + uint32_t addr = T0_POP(); + *(uint32_t *)(void *)((unsigned char *)CTX + addr) = T0_POP(); +} + +cc: get8 ( addr -- val ) { + uint32_t addr = T0_POP(); + T0_PUSH(*((unsigned char *)CTX + addr)); +} + +cc: get16 ( addr -- val ) { + uint32_t addr = T0_POP(); + T0_PUSH(*(uint16_t *)(void *)((unsigned char *)CTX + addr)); +} + +cc: get32 ( addr -- val ) { + uint32_t addr = T0_POP(); + T0_PUSH(*(uint32_t *)(void *)((unsigned char *)CTX + addr)); +} + +\ Read an ASN.1 tag. This function returns the "constructed" status +\ and the tag value. The constructed status is a boolean (-1 for +\ constructed, 0 for primitive). The tag value is either 0 to 31 for +\ a universal tag, or 32+x for a contextual tag of value x. Tag classes +\ "application" and "private" are rejected. Universal tags beyond 30 +\ are rejected. Contextual tags beyond 30 are rejected. Thus, accepted +\ tags will necessarily fit on exactly one byte. This does not support +\ the whole of ASN.1/BER, but is sufficient for certificate parsing. +: read-tag ( lim -- lim constructed value ) + read8 { fb } + + \ Constructed flag is bit 5. + fb 5 >> 0x01 and neg + + \ Class is in bits 6 and 7. Accepted classes are 00 (universal) + \ and 10 (context). We check that bit 6 is 0, and shift back + \ bit 7 so that we get 0 (universal) or 32 (context). + fb 6 >> dup 0x01 and if ERR_X509_BAD_TAG_CLASS fail then + 4 << + + \ Tag value is in bits 0..4. If the value is 31, then this is + \ an extended tag, encoded over subsequent bytes, and we do + \ not support that. + fb 0x1F and dup 0x1F = if ERR_X509_BAD_TAG_VALUE fail then + + ; + +\ Read a tag, but only if not at the end of the current object. If there +\ is no room for another element (limit is zero), then this will push a +\ synthetic "no tag" value (primitive, with value -1). +: read-tag-or-end ( lim -- lim constructed value ) + dup ifnot 0 -1 ret then + read-tag ; + +\ Compare the read tag with the provided value. If equal, then the +\ element is skipped, and a new tag is read (or end of object). +: iftag-skip ( lim constructed value ref -- lim constructed value ) + over = if + 2drop + read-length-open-elt skip-close-elt + read-tag-or-end + then ; + +\ Read an ASN.1 length. This supports only definite lengths (theoretically, +\ certificates may use an indefinite length for the outer structure, using +\ DER only in the TBS, but this never happens in practice, except in a +\ single example certificate from 15 years ago that also fails to decode +\ properly for other reasons). +: read-length ( lim -- lim length ) + read8 + \ Lengths in 0x00..0x7F get encoded as a single byte. + dup 0x80 < if ret then + + \ If the byte is 0x80 then this is an indefinite length, and we + \ do not support that. + 0x80 - dup ifnot ERR_X509_INDEFINITE_LENGTH fail then + + \ Masking out bit 7, this yields the number of bytes over which + \ the value is encoded. Since the total certificate length must + \ fit over 3 bytes (this is a consequence of SSL/TLS message + \ format), we can reject big lengths and keep the length in a + \ single integer. + { n } 0 + begin n 0 > while n 1- >n + dup 0x7FFFFF > if ERR_X509_INNER_TRUNC fail then + 8 << swap read8 rot + + repeat ; + +\ Open a sub-structure. This subtracts the length from the limit, and +\ pushes the length back as new limit. +: open-elt ( lim length -- lim_outer lim_inner ) + dup2 < if ERR_X509_INNER_TRUNC fail then + dup { len } - len ; + +\ Read a length and open the value as a sub-structure. +: read-length-open-elt ( lim -- lim_outer lim_inner ) + read-length open-elt ; + +\ Close a sub-structure. This verifies that there is no remaining +\ element to read. +: close-elt ( lim -- ) + if ERR_X509_EXTRA_ELEMENT fail then ; + +\ Skip remaining bytes in the current structure, then close it. +: skip-close-elt ( lim -- ) + skip-remaining drop ; + +\ Read a length and then skip the value. +: read-length-skip ( lim -- lim ) + read-length-open-elt skip-close-elt ; + +\ Check that a given tag is constructed and has the expected value. +: check-tag-constructed ( constructed value refvalue -- ) + = ifnot ERR_X509_UNEXPECTED fail then + check-constructed ; + +\ Check that the top value is true; report a "not constructed" +\ error otherwise. +: check-constructed ( constructed -- ) + ifnot ERR_X509_NOT_CONSTRUCTED fail then ; + +\ Check that a given tag is primitive and has the expected value. +: check-tag-primitive ( constructed value refvalue -- ) + = ifnot ERR_X509_UNEXPECTED fail then + check-primitive ; + +\ Check that the top value is true; report a "not primitive" +\ error otherwise. +: check-primitive ( constructed -- ) + if ERR_X509_NOT_PRIMITIVE fail then ; + +\ Check that the tag is for a constructed SEQUENCE. +: check-sequence ( constructed value -- ) + 0x10 check-tag-constructed ; + +\ Read a tag, check that it is for a constructed SEQUENCE, and open +\ it as a sub-element. +: read-sequence-open ( lim -- lim_outer lim_inner ) + read-tag check-sequence read-length-open-elt ; + +\ Read the next element as a BIT STRING with no ignore bits, and open +\ it as a sub-element. +: read-bits-open ( lim -- lim_outer lim_inner ) + read-tag 0x03 check-tag-primitive + read-length-open-elt + read8 if ERR_X509_PARTIAL_BYTE fail then ; + +OID: rsaEncryption 1.2.840.113549.1.1.1 + +OID: sha1WithRSAEncryption 1.2.840.113549.1.1.5 +OID: sha224WithRSAEncryption 1.2.840.113549.1.1.14 +OID: sha256WithRSAEncryption 1.2.840.113549.1.1.11 +OID: sha384WithRSAEncryption 1.2.840.113549.1.1.12 +OID: sha512WithRSAEncryption 1.2.840.113549.1.1.13 + +OID: id-sha1 1.3.14.3.2.26 +OID: id-sha224 2.16.840.1.101.3.4.2.4 +OID: id-sha256 2.16.840.1.101.3.4.2.1 +OID: id-sha384 2.16.840.1.101.3.4.2.2 +OID: id-sha512 2.16.840.1.101.3.4.2.3 + +OID: id-ecPublicKey 1.2.840.10045.2.1 + +OID: ansix9p256r1 1.2.840.10045.3.1.7 +OID: ansix9p384r1 1.3.132.0.34 +OID: ansix9p521r1 1.3.132.0.35 + +OID: ecdsa-with-SHA1 1.2.840.10045.4.1 +OID: ecdsa-with-SHA224 1.2.840.10045.4.3.1 +OID: ecdsa-with-SHA256 1.2.840.10045.4.3.2 +OID: ecdsa-with-SHA384 1.2.840.10045.4.3.3 +OID: ecdsa-with-SHA512 1.2.840.10045.4.3.4 + +OID: id-at-commonName 2.5.4.3 + +\ Read a "small value". This assumes that the tag has just been read +\ and processed, but not the length. The first pad byte is set to the +\ value length; the encoded value itself follows. If the value length +\ exceeds 255 bytes, then a single 0 is written in the pad, and this +\ method returns false (0). Otherwise, it returns true (-1). +\ Either way, the element is fully read. +: read-small-value ( lim -- lim bool ) + read-length-open-elt + dup 255 > if skip-close-elt 0 addr-pad set8 0 ret then + dup addr-pad set8 + addr-pad 1+ read-blob + -1 ; + +\ Read an OID as a "small value" (tag, length and value). A boolean +\ value is returned, which is true (-1) if the OID value fits on the pad, +\ false (0) otherwise. +: read-OID ( lim -- lim bool ) + read-tag 0x06 check-tag-primitive read-small-value ; + +\ Read a UTF-8 code point. On error, return 0. Reading a code point of +\ value 0 is considered to be an error. +: read-UTF8 ( lim -- lim val ) + read8 + choice + dup 0x80 < uf ret enduf + dup 0xC0 < uf drop 0 ret enduf + dup 0xE0 < uf 0x1F and 1 read-UTF8-next 0x80 0x7FF enduf + dup 0xF0 < uf 0x0F and 2 read-UTF8-next 0x800 0xFFFF enduf + dup 0xF8 < uf 0x07 and 3 read-UTF8-next 0x10000 0x10FFFF enduf + drop 0 ret + endchoice + between? ifnot drop 0 then + ; + +\ Read n subsequent bytes to complete the provided first byte. The final +\ value is -1 on error, or the code point numerical value. The final +\ value is duplicated. +: read-UTF8-next ( lim val n -- lim val val ) + begin dup while + -rot + read-UTF8-chunk + rot 1- + repeat + drop dup ; + +\ Read one byte, that should be a trailing UTF-8 byte, and complement the +\ current value. On error, value is set to -1. +: read-UTF8-chunk ( lim val -- lim val ) + swap + \ If we are at the end of the value, report an error but don't fail. + dup ifnot 2drop 0 -1 ret then + read8 rot + dup 0< if swap drop ret then 6 << + swap dup 6 >> 2 <> if 2drop -1 ret then + 0x3F and + ; + +: high-surrogate? ( x -- x bool ) + dup 0xD800 0xDBFF between? ; + +: low-surrogate? ( x -- x bool ) + dup 0xDC00 0xDFFF between? ; + +: assemble-surrogate-pair ( hi lim lo -- lim val ) + low-surrogate? ifnot rot 2drop 0 ret then + rot 10 << + 0x35FDC00 - ; + +\ Read a UTF-16 code point (big-endian). Returned value is 0 on error. +: read-UTF16BE ( lim -- lim val ) + read16be + choice + high-surrogate? uf + swap dup ifnot 2drop 0 0 ret then + read16be assemble-surrogate-pair + enduf + low-surrogate? uf + drop 0 + enduf + endchoice ; + +\ Read a UTF-16 code point (little-endian). Returned value is 0 on error. +: read-UTF16LE ( lim -- lim val ) + read16le + choice + high-surrogate? uf + swap dup ifnot 2drop 0 0 ret then + read16le assemble-surrogate-pair + enduf + low-surrogate? uf + drop 0 + enduf + endchoice ; + +\ Add byte to current pad value. Offset is updated, or set to 0 on error. +: pad-append ( off val -- off ) + over dup 0= swap 256 >= or if 2drop 0 ret then + over addr-pad + set8 1+ ; + +\ Add UTF-8 chunk byte to the pad. The 'nn' parameter is the shift count. +: pad-append-UTF8-chunk ( off val nn -- off ) + >> 0x3F and 0x80 or pad-append ; + +\ Test whether a code point is invalid when encoding. This rejects the +\ 66 noncharacters, and also the surrogate range; this function does NOT +\ check that the value is in the 0..10FFFF range. +: valid-unicode? ( val -- bool ) + dup 0xFDD0 0xFDEF between? if drop 0 ret then + dup 0xD800 0xDFFF between? if drop 0 ret then + 0xFFFF and 0xFFFE < ; + +\ Encode a code point in UTF-8. Offset is in the pad; it is updated, or +\ set to 0 on error. Leading BOM are ignored. +: encode-UTF8 ( val off -- off ) + \ Skip leading BOM (U+FEFF when off is 1). + dup2 1 = swap 0xFEFF = and if swap drop ret then + + swap dup { val } + dup valid-unicode? ifnot 2drop 0 ret then + choice + dup 0x80 < uf pad-append enduf + dup 0x800 < uf + 6 >> 0xC0 or pad-append + val 0 pad-append-UTF8-chunk + enduf + dup 0xFFFF < uf + 12 >> 0xE0 or pad-append + val 6 pad-append-UTF8-chunk + val 0 pad-append-UTF8-chunk + enduf + 18 >> 0xF0 or pad-append + val 12 pad-append-UTF8-chunk + val 6 pad-append-UTF8-chunk + val 0 pad-append-UTF8-chunk + endchoice ; + +\ Read a string value into the pad; this function checks that the source +\ characters are UTF-8 and non-zero. The string length (in bytes) is +\ written in the first pad byte. Returned value is true (-1) on success, +\ false (0) on error. +: read-value-UTF8 ( lim -- lim bool ) + read-length-open-elt + 1 { off } + begin dup while + read-UTF8 dup ifnot drop skip-close-elt 0 ret then + off encode-UTF8 >off + repeat + drop off dup ifnot ret then 1- addr-pad set8 -1 ; + +\ Decode a UTF-16 string into the pad. The string is converted to UTF-8, +\ and the length is written in the first pad byte. A leading BOM is +\ honoured (big-endian is assumed if there is no BOM). A code point of +\ value 0 is an error. Returned value is true (-1) on success, false (0) +\ on error. +: read-value-UTF16 ( lim -- lim bool ) + read-length-open-elt + dup ifnot addr-pad set8 -1 ret then + 1 { off } + read-UTF16BE dup 0xFFFE = if + \ Leading BOM, and indicates little-endian. + drop + begin dup while + read-UTF16LE dup ifnot drop skip-close-elt 0 ret then + off encode-UTF8 >off + repeat + else + dup ifnot drop skip-close-elt 0 ret then + \ Big-endian BOM, or no BOM. + begin + off encode-UTF8 >off + dup while + read-UTF16BE dup ifnot drop skip-close-elt 0 ret then + repeat + then + drop off dup ifnot ret then 1- addr-pad set8 -1 ; + +\ Decode a latin-1 string into the pad. The string is converted to UTF-8, +\ and the length is written in the first pad byte. A source byte of +\ value 0 is an error. Returned value is true (-1) on success, false (0) +\ on error. +: read-value-latin1 ( lim -- lim bool ) + read-length-open-elt + 1 { off } + begin dup while + read8 dup ifnot drop skip-close-elt 0 ret then + off encode-UTF8 >off + repeat + drop off dup ifnot ret then 1- addr-pad set8 -1 ; + +\ Read a value and interpret it as an INTEGER or ENUMERATED value. If +\ the integer value does not fit on an unsigned 32-bit value, an error +\ is reported. This function assumes that the tag has just been read +\ and processed, but not the length. +: read-small-int-value ( lim -- lim x ) + read-length-open-elt + dup ifnot ERR_X509_OVERFLOW fail then + read8 dup 0x80 >= if ERR_X509_OVERFLOW fail then + { x } + begin dup while + read8 x dup 0xFFFFFF >= if ERR_X509_OVERFLOW fail then + 8 << + >x + repeat + drop x ; + +\ Compare the OID in the pad with an OID in the constant data block. +\ Returned value is -1 on equality, 0 otherwise. +cc: eqOID ( addrConst -- bool ) { + const unsigned char *a2 = &t0_datablock[T0_POP()]; + const unsigned char *a1 = &CTX->pad[0]; + size_t len = a1[0]; + int x; + if (len == a2[0]) { + x = -(memcmp(a1 + 1, a2 + 1, len) == 0); + } else { + x = 0; + } + T0_PUSH((uint32_t)x); +} + +\ Compare two blobs in the context. Returned value is -1 on equality, 0 +\ otherwise. +cc: eqblob ( addr1 addr2 len -- bool ) { + size_t len = T0_POP(); + const unsigned char *a2 = (const unsigned char *)CTX + T0_POP(); + const unsigned char *a1 = (const unsigned char *)CTX + T0_POP(); + T0_PUSHi(-(memcmp(a1, a2, len) == 0)); +} + +\ Check that a value is in a given range (inclusive). +: between? ( x min max -- bool ) + { min max } dup min >= swap max <= and ; + +\ Convert the provided byte value into a number in the 0..9 range, +\ assuming that it is an ASCII digit. A non-digit triggers an error +\ (a "bad time" error since this is used in date/time decoding). +: digit-dec ( char -- value ) + `0 - dup 0 9 between? ifnot ERR_X509_BAD_TIME fail then ; + +\ Read two ASCII digits and return the value in the 0..99 range. An +\ error is reported if the characters are not ASCII digits. +: read-dec2 ( lim -- lim x ) + read8 digit-dec 10 * { x } read8 digit-dec x + ; + +\ Read two ASCII digits and check that the value is in the provided +\ range (inclusive). +: read-dec2-range ( lim min max -- lim x ) + { min max } + read-dec2 dup min max between? ifnot ERR_X509_BAD_TIME fail then ; + +\ Maximum days in a month and accumulated day count. Each +\ 16-bit value contains the month day count in its lower 5 bits. The first +\ 12 values are for a normal year, the other 12 for a leap year. +data: month-to-days +hexb| 001F 03FC 077F 0B5E 0F1F 12FE 16BF 1A9F 1E7E 223F 261E 29DF | +hexb| 001F 03FD 079F 0B7E 0F3F 131E 16DF 1ABF 1E9E 225F 263E 29FF | + +\ Read a date (UTCTime or GeneralizedTime). The date value is converted +\ to a day count and a second count. The day count starts at 0 for +\ January 1st, 0 AD (that's they year before 1 AD, also known as 1 BC) +\ in a proleptic Gregorian calendar (i.e. Gregorian rules are assumed to +\ extend indefinitely in the past). The second count is between 0 and +\ 86400 (inclusive, in case of a leap second). +: read-date ( lim -- lim days seconds ) + \ Read tag; must be UTCTime or GeneralizedTime. Year count is + \ 4 digits with GeneralizedTime, 2 digits with UTCTime. + read-tag + dup 0x17 0x18 between? ifnot ERR_X509_BAD_TIME fail then + 0x18 = { y4d } + check-primitive + read-length-open-elt + + \ We compute the days and seconds counts during decoding, in + \ order to minimize the number of needed temporary variables. + { ; days seconds x } + + \ Year is 4-digit with GeneralizedTime. With UTCTime, the year + \ is in the 1950..2049 range, and only the last two digits are + \ present in the encoding. + read-dec2 + y4d if + 100 * >x read-dec2 x + + else + dup 50 < if 100 + then 1900 + + then + >x + x 365 * x 3 + 4 / + x 99 + 100 / - x 399 + 400 / + >days + + \ Month is 1..12. Number of days in a months depend on the + \ month and on the year (year count is in x at that point). + 1 12 read-dec2-range + 1- 1 << + x 4 % 0= x 100 % 0<> x 400 % 0= or and if 24 + then + month-to-days + data-get16 + dup 5 >> days + >days + 0x1F and + + \ Day. At this point, the TOS contains the maximum day count for + \ the current month. + 1 swap read-dec2-range + days + 1- >days + + \ Hour, minute and seconds. Count of seconds is allowed to go to + \ 60 in case of leap seconds (in practice, leap seconds really + \ occur only at the very end of the day, so this computation is + \ exact for a real leap second, and a spurious leap second only + \ implies a one-second shift that we can ignore). + 0 23 read-dec2-range 3600 * >seconds + 0 59 read-dec2-range 60 * seconds + >seconds + 0 60 read-dec2-range seconds + >seconds + + \ At this point, we may have fractional seconds. This should + \ happen only with GeneralizedTime, but we accept it for UTCTime + \ too (and, anyway, we ignore these fractional seconds). + read8 dup `. = if + drop + begin read8 dup `0 `9 between? while drop repeat + then + + \ The time zone should be 'Z', not followed by anything. Other + \ time zone indications are not DER and thus not supposed to + \ appear in certificates. + `Z <> if ERR_X509_BAD_TIME fail then + close-elt + days seconds ; + +\ Read an INTEGER (tag, length and value). The INTEGER is supposed to be +\ positive; its unsigned big-endian encoding is stored in the provided +\ in-context buffer. Returned value is the decoded length. If the integer +\ did not fit, or the value is negative, then an error is reported. +: read-integer ( lim addr len -- lim dlen ) + rot read-tag 0x02 check-tag-primitive -rot + read-integer-next ; + +\ Identical to read-integer, but the tag has already been read and checked. +: read-integer-next ( lim addr len -- lim dlen ) + dup { addr len origlen } + read-length-open-elt + \ Read first byte; sign bit must be 0. + read8 dup 0x80 >= if ERR_X509_OVERFLOW fail then + \ Skip leading bytes of value 0. If there are only bytes of + \ value 0, then return. + begin dup 0 = while + drop dup ifnot drop 0 ret then + read8 + repeat + \ At that point, we have the first non-zero byte on the stack. + begin + len dup ifnot ERR_X509_LIMIT_EXCEEDED fail then 1- >len + addr set8 addr 1+ >addr + dup while read8 + repeat + drop origlen len - ; + +\ Read a BOOLEAN value. This should be called immediately after reading +\ the tag. +: read-boolean ( lim constructed value -- lim bool ) + 0x01 check-tag-primitive + read-length 1 <> if ERR_X509_BAD_BOOLEAN fail then + read8 0<> ; + +\ Identify an elliptic curve: read the OID, then check it against the +\ known curve OID. +: read-curve-ID ( lim -- lim curve ) + read-OID ifnot ERR_X509_UNSUPPORTED fail then + choice + ansix9p256r1 eqOID uf 23 enduf + ansix9p384r1 eqOID uf 24 enduf + ansix9p521r1 eqOID uf 25 enduf + ERR_X509_UNSUPPORTED fail + endchoice ; + +\ A convenient debug word: print the current data stack contents. +cc: DEBUG ( -- ) { + extern int printf(const char *fmt, ...); + uint32_t *p; + + printf("dp_stack[0]; p != dp; p ++) { + printf(" %lu", (unsigned long)*p); + } + printf(" >\n"); +} diff --git a/BearSSL-OG/libbearssl/src/x509/asn1enc.c b/BearSSL-OG/libbearssl/src/x509/asn1enc.c new file mode 100644 index 0000000..7a74963 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/asn1enc.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +br_asn1_uint +br_asn1_uint_prepare(const void *xdata, size_t xlen) +{ + const unsigned char *x; + br_asn1_uint t; + + x = xdata; + while (xlen > 0 && *x == 0) { + x ++; + xlen --; + } + t.data = x; + t.len = xlen; + t.asn1len = xlen; + if (xlen == 0 || x[0] >= 0x80) { + t.asn1len ++; + } + return t; +} + +/* see inner.h */ +size_t +br_asn1_encode_length(void *dest, size_t len) +{ + unsigned char *buf; + size_t z; + int i, j; + + buf = dest; + if (len < 0x80) { + if (buf != NULL) { + *buf = len; + } + return 1; + } + i = 0; + for (z = len; z != 0; z >>= 8) { + i ++; + } + if (buf != NULL) { + *buf ++ = 0x80 + i; + for (j = i - 1; j >= 0; j --) { + *buf ++ = len >> (j << 3); + } + } + return i + 1; +} + +/* see inner.h */ +size_t +br_asn1_encode_uint(void *dest, br_asn1_uint pp) +{ + unsigned char *buf; + size_t lenlen; + + if (dest == NULL) { + return 1 + br_asn1_encode_length(NULL, pp.asn1len) + pp.asn1len; + } + buf = dest; + *buf ++ = 0x02; + lenlen = br_asn1_encode_length(buf, pp.asn1len); + buf += lenlen; + *buf = 0x00; + memcpy(buf + pp.asn1len - pp.len, pp.data, pp.len); + return 1 + lenlen + pp.asn1len; +} diff --git a/BearSSL-OG/libbearssl/src/x509/encode_ec_pk8der.c b/BearSSL-OG/libbearssl/src/x509/encode_ec_pk8der.c new file mode 100644 index 0000000..53717ce --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/encode_ec_pk8der.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_x509.h */ +size_t +br_encode_ec_pkcs8_der(void *dest, + const br_ec_private_key *sk, const br_ec_public_key *pk) +{ + /* + * ASN.1 format: + * + * OneAsymmetricKey ::= SEQUENCE { + * version Version, + * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + * privateKey PrivateKey, + * attributes [0] Attributes OPTIONAL, + * ..., + * [[2: publicKey [1] PublicKey OPTIONAL ]], + * ... + * } + * + * We don't include attributes or public key (the public key + * is included in the private key value instead). The + * 'version' field is an INTEGER that we will set to 0 + * (meaning 'v1', compatible with previous versions of PKCS#8). + * The 'privateKeyAlgorithm' structure is an AlgorithmIdentifier + * whose OID should be id-ecPublicKey, with, as parameters, the + * curve OID. The 'privateKey' is an OCTET STRING, whose value + * is the "raw DER" encoding of the key pair. + */ + + /* + * OID id-ecPublicKey (1.2.840.10045.2.1), DER-encoded (with + * the tag). + */ + static const unsigned char OID_ECPUBKEY[] = { + 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01 + }; + + size_t len_version, len_privateKeyAlgorithm, len_privateKeyValue; + size_t len_privateKey, len_seq; + const unsigned char *oid; + + oid = br_get_curve_OID(sk->curve); + if (oid == NULL) { + return 0; + } + len_version = 3; + len_privateKeyAlgorithm = 2 + sizeof OID_ECPUBKEY + 2 + oid[0]; + len_privateKeyValue = br_encode_ec_raw_der_inner(NULL, sk, pk, 0); + len_privateKey = 1 + len_of_len(len_privateKeyValue) + + len_privateKeyValue; + len_seq = len_version + len_privateKeyAlgorithm + len_privateKey; + + if (dest == NULL) { + return 1 + len_of_len(len_seq) + len_seq; + } else { + unsigned char *buf; + size_t lenlen; + + buf = dest; + *buf ++ = 0x30; /* SEQUENCE tag */ + lenlen = br_asn1_encode_length(buf, len_seq); + buf += lenlen; + + /* version */ + *buf ++ = 0x02; + *buf ++ = 0x01; + *buf ++ = 0x00; + + /* privateKeyAlgorithm */ + *buf ++ = 0x30; + *buf ++ = (sizeof OID_ECPUBKEY) + 2 + oid[0]; + memcpy(buf, OID_ECPUBKEY, sizeof OID_ECPUBKEY); + buf += sizeof OID_ECPUBKEY; + *buf ++ = 0x06; + memcpy(buf, oid, 1 + oid[0]); + buf += 1 + oid[0]; + + /* privateKey */ + *buf ++ = 0x04; + buf += br_asn1_encode_length(buf, len_privateKeyValue); + br_encode_ec_raw_der_inner(buf, sk, pk, 0); + + return 1 + lenlen + len_seq; + } +} diff --git a/BearSSL-OG/libbearssl/src/x509/encode_ec_rawder.c b/BearSSL-OG/libbearssl/src/x509/encode_ec_rawder.c new file mode 100644 index 0000000..5985909 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/encode_ec_rawder.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see inner.h */ +const unsigned char * +br_get_curve_OID(int curve) +{ + static const unsigned char OID_secp256r1[] = { + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 + }; + static const unsigned char OID_secp384r1[] = { + 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 + }; + static const unsigned char OID_secp521r1[] = { + 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23 + }; + + switch (curve) { + case BR_EC_secp256r1: return OID_secp256r1; + case BR_EC_secp384r1: return OID_secp384r1; + case BR_EC_secp521r1: return OID_secp521r1; + default: + return NULL; + } +} + +/* see inner.h */ +size_t +br_encode_ec_raw_der_inner(void *dest, + const br_ec_private_key *sk, const br_ec_public_key *pk, + int include_curve_oid) +{ + /* + * ASN.1 format: + * + * ECPrivateKey ::= SEQUENCE { + * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + * privateKey OCTET STRING, + * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + * publicKey [1] BIT STRING OPTIONAL + * } + * + * The tages '[0]' and '[1]' are explicit. The 'ECParameters' + * is a CHOICE; in our case, it will always be an OBJECT IDENTIFIER + * that identifies the curve. + * + * The value of the 'privateKey' field is the raw unsigned big-endian + * encoding of the private key (integer modulo the curve subgroup + * order); there is no INTEGER tag, and the leading bit may be 1. + * Also, leading bytes of value 0x00 are _not_ removed. + * + * The 'publicKey' contents are the raw encoded public key point, + * normally uncompressed (leading byte of value 0x04, followed + * by the unsigned big-endian encodings of the X and Y coordinates, + * padded to the full field length if necessary). + */ + + size_t len_version, len_privateKey, len_parameters, len_publicKey; + size_t len_publicKey_bits, len_seq; + const unsigned char *oid; + + if (include_curve_oid) { + oid = br_get_curve_OID(sk->curve); + if (oid == NULL) { + return 0; + } + } else { + oid = NULL; + } + len_version = 3; + len_privateKey = 1 + len_of_len(sk->xlen) + sk->xlen; + if (include_curve_oid) { + len_parameters = 4 + oid[0]; + } else { + len_parameters = 0; + } + if (pk == NULL) { + len_publicKey = 0; + len_publicKey_bits = 0; + } else { + len_publicKey_bits = 2 + len_of_len(pk->qlen) + pk->qlen; + len_publicKey = 1 + len_of_len(len_publicKey_bits) + + len_publicKey_bits; + } + len_seq = len_version + len_privateKey + len_parameters + len_publicKey; + if (dest == NULL) { + return 1 + len_of_len(len_seq) + len_seq; + } else { + unsigned char *buf; + size_t lenlen; + + buf = dest; + *buf ++ = 0x30; /* SEQUENCE tag */ + lenlen = br_asn1_encode_length(buf, len_seq); + buf += lenlen; + + /* version */ + *buf ++ = 0x02; + *buf ++ = 0x01; + *buf ++ = 0x01; + + /* privateKey */ + *buf ++ = 0x04; + buf += br_asn1_encode_length(buf, sk->xlen); + memcpy(buf, sk->x, sk->xlen); + buf += sk->xlen; + + /* parameters */ + if (include_curve_oid) { + *buf ++ = 0xA0; + *buf ++ = oid[0] + 2; + *buf ++ = 0x06; + memcpy(buf, oid, oid[0] + 1); + buf += oid[0] + 1; + } + + /* publicKey */ + if (pk != NULL) { + *buf ++ = 0xA1; + buf += br_asn1_encode_length(buf, len_publicKey_bits); + *buf ++ = 0x03; + buf += br_asn1_encode_length(buf, pk->qlen + 1); + *buf ++ = 0x00; + memcpy(buf, pk->q, pk->qlen); + /* buf += pk->qlen; */ + } + + return 1 + lenlen + len_seq; + } +} + +/* see bearssl_x509.h */ +size_t +br_encode_ec_raw_der(void *dest, + const br_ec_private_key *sk, const br_ec_public_key *pk) +{ + return br_encode_ec_raw_der_inner(dest, sk, pk, 1); +} diff --git a/BearSSL-OG/libbearssl/src/x509/encode_rsa_pk8der.c b/BearSSL-OG/libbearssl/src/x509/encode_rsa_pk8der.c new file mode 100644 index 0000000..c053503 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/encode_rsa_pk8der.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_x509.h */ +size_t +br_encode_rsa_pkcs8_der(void *dest, const br_rsa_private_key *sk, + const br_rsa_public_key *pk, const void *d, size_t dlen) +{ + /* + * ASN.1 format: + * + * OneAsymmetricKey ::= SEQUENCE { + * version Version, + * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + * privateKey PrivateKey, + * attributes [0] Attributes OPTIONAL, + * ..., + * [[2: publicKey [1] PublicKey OPTIONAL ]], + * ... + * } + * + * We don't include attributes or public key. The 'version' field + * is an INTEGER that we will set to 0 (meaning 'v1', compatible + * with previous versions of PKCS#8). The 'privateKeyAlgorithm' + * structure is an AlgorithmIdentifier whose OID should be + * rsaEncryption, with NULL parameters. The 'privateKey' is an + * OCTET STRING, whose value is the "raw DER" encoding of the + * key pair. + * + * Since the private key value comes last, this function really + * adds a header, which is mostly fixed (only some lengths have + * to be modified. + */ + + /* + * Concatenation of: + * - DER encoding of an INTEGER of value 0 (the 'version' field) + * - DER encoding of a PrivateKeyAlgorithmIdentifier that uses + * the rsaEncryption OID, and NULL parameters + * - An OCTET STRING tag + */ + static const unsigned char PK8_HEAD[] = { + 0x02, 0x01, 0x00, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x04 + }; + + size_t len_raw, len_seq; + + len_raw = br_encode_rsa_raw_der(NULL, sk, pk, d, dlen); + len_seq = (sizeof PK8_HEAD) + len_of_len(len_raw) + len_raw; + if (dest == NULL) { + return 1 + len_of_len(len_seq) + len_seq; + } else { + unsigned char *buf; + size_t lenlen; + + buf = dest; + *buf ++ = 0x30; /* SEQUENCE tag */ + lenlen = br_asn1_encode_length(buf, len_seq); + buf += lenlen; + + /* version, privateKeyAlgorithm, privateKey tag */ + memcpy(buf, PK8_HEAD, sizeof PK8_HEAD); + buf += sizeof PK8_HEAD; + + /* privateKey */ + buf += br_asn1_encode_length(buf, len_raw); + br_encode_rsa_raw_der(buf, sk, pk, d, dlen); + + return 1 + lenlen + len_seq; + } +} diff --git a/BearSSL-OG/libbearssl/src/x509/encode_rsa_rawder.c b/BearSSL-OG/libbearssl/src/x509/encode_rsa_rawder.c new file mode 100644 index 0000000..1a8052b --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/encode_rsa_rawder.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_x509.h */ +size_t +br_encode_rsa_raw_der(void *dest, const br_rsa_private_key *sk, + const br_rsa_public_key *pk, const void *d, size_t dlen) +{ + /* + * ASN.1 format: + * + * RSAPrivateKey ::= SEQUENCE { + * version Version, + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p-1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER, -- (inverse of q) mod p + * otherPrimeInfos OtherPrimeInfos OPTIONAL + * } + * + * The 'version' field is an INTEGER of value 0 (meaning: there + * are exactly two prime factors), and 'otherPrimeInfos' will + * be absent (because there are exactly two prime factors). + */ + + br_asn1_uint num[9]; + size_t u, slen; + + /* + * For all INTEGER values, get the pointer and length for the + * data bytes. + */ + num[0] = br_asn1_uint_prepare(NULL, 0); + num[1] = br_asn1_uint_prepare(pk->n, pk->nlen); + num[2] = br_asn1_uint_prepare(pk->e, pk->elen); + num[3] = br_asn1_uint_prepare(d, dlen); + num[4] = br_asn1_uint_prepare(sk->p, sk->plen); + num[5] = br_asn1_uint_prepare(sk->q, sk->qlen); + num[6] = br_asn1_uint_prepare(sk->dp, sk->dplen); + num[7] = br_asn1_uint_prepare(sk->dq, sk->dqlen); + num[8] = br_asn1_uint_prepare(sk->iq, sk->iqlen); + + /* + * Get the length of the SEQUENCE contents. + */ + slen = 0; + for (u = 0; u < 9; u ++) { + uint32_t ilen; + + ilen = num[u].asn1len; + slen += 1 + len_of_len(ilen) + ilen; + } + + if (dest == NULL) { + return 1 + len_of_len(slen) + slen; + } else { + unsigned char *buf; + size_t lenlen; + + buf = dest; + *buf ++ = 0x30; /* SEQUENCE tag */ + lenlen = br_asn1_encode_length(buf, slen); + buf += lenlen; + for (u = 0; u < 9; u ++) { + buf += br_asn1_encode_uint(buf, num[u]); + } + return 1 + lenlen + slen; + } +} diff --git a/BearSSL-OG/libbearssl/src/x509/skey_decoder.c b/BearSSL-OG/libbearssl/src/x509/skey_decoder.c new file mode 100644 index 0000000..9e285d7 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/skey_decoder.c @@ -0,0 +1,650 @@ +/* Automatically generated code; do not modify directly. */ + +#include +#include + +typedef struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; +} t0_context; + +static uint32_t +t0_parse7E_unsigned(const unsigned char **p) +{ + uint32_t x; + + x = 0; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + return x; + } + } +} + +static int32_t +t0_parse7E_signed(const unsigned char **p) +{ + int neg; + uint32_t x; + + neg = ((**p) >> 6) & 1; + x = (uint32_t)-neg; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + if (neg) { + return -(int32_t)~x - 1; + } else { + return (int32_t)x; + } + } + } +} + +#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) +#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) +#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) +#define T0_INT1(x) T0_FBYTE(x, 0) +#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) + +/* static const unsigned char t0_datablock[]; */ + + +void br_skey_decoder_init_main(void *t0ctx); + +void br_skey_decoder_run(void *t0ctx); + + + +#include "inner.h" + + + + + +#include "inner.h" + +#define CTX ((br_skey_decoder_context *)(void *)((unsigned char *)t0ctx - offsetof(br_skey_decoder_context, cpu))) +#define CONTEXT_NAME br_skey_decoder_context + +/* see bearssl_x509.h */ +void +br_skey_decoder_init(br_skey_decoder_context *ctx) +{ + memset(ctx, 0, sizeof *ctx); + ctx->cpu.dp = &ctx->dp_stack[0]; + ctx->cpu.rp = &ctx->rp_stack[0]; + br_skey_decoder_init_main(&ctx->cpu); + br_skey_decoder_run(&ctx->cpu); +} + +/* see bearssl_x509.h */ +void +br_skey_decoder_push(br_skey_decoder_context *ctx, + const void *data, size_t len) +{ + ctx->hbuf = data; + ctx->hlen = len; + br_skey_decoder_run(&ctx->cpu); +} + + + +static const unsigned char t0_datablock[] = { + 0x00, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x07, + 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x08, 0x2A, 0x86, 0x48, 0xCE, + 0x3D, 0x03, 0x01, 0x07, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x05, 0x2B, + 0x81, 0x04, 0x00, 0x23 +}; + +static const unsigned char t0_codeblock[] = { + 0x00, 0x01, 0x01, 0x07, 0x00, 0x00, 0x01, 0x01, 0x08, 0x00, 0x00, 0x13, + 0x13, 0x00, 0x00, 0x01, T0_INT1(BR_ERR_X509_BAD_TAG_CLASS), 0x00, 0x00, + 0x01, T0_INT1(BR_ERR_X509_BAD_TAG_VALUE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_EXTRA_ELEMENT), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_INDEFINITE_LENGTH), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_INNER_TRUNC), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_INVALID_VALUE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_NOT_CONSTRUCTED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_NOT_PRIMITIVE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_OVERFLOW), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_UNEXPECTED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_UNSUPPORTED), 0x00, 0x00, 0x01, + T0_INT1(BR_KEYTYPE_EC), 0x00, 0x00, 0x01, T0_INT1(BR_KEYTYPE_RSA), + 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, key_data)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, key_type)), 0x00, 0x00, + 0x33, 0x48, 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, pad)), + 0x00, 0x00, 0x01, 0x13, 0x00, 0x00, 0x01, 0x1C, 0x00, 0x00, 0x01, 0x22, + 0x00, 0x00, 0x05, 0x02, 0x2C, 0x16, 0x00, 0x00, 0x06, 0x02, 0x2D, 0x16, + 0x00, 0x00, 0x01, 0x10, 0x3D, 0x00, 0x00, 0x0D, 0x05, 0x02, 0x2F, 0x16, + 0x3A, 0x00, 0x00, 0x0D, 0x05, 0x02, 0x2F, 0x16, 0x3B, 0x00, 0x00, 0x06, + 0x02, 0x27, 0x16, 0x00, 0x01, 0x03, 0x00, 0x54, 0x57, 0x01, 0x02, 0x3E, + 0x55, 0x23, 0x06, 0x02, 0x30, 0x16, 0x57, 0x01, 0x04, 0x3E, 0x02, 0x00, + 0x41, 0x3F, 0x00, 0x02, 0x03, 0x00, 0x53, 0x14, 0x14, 0x03, 0x01, 0x48, + 0x0E, 0x06, 0x02, 0x30, 0x16, 0x33, 0x4C, 0x58, 0x01, 0x7F, 0x19, 0x0D, + 0x06, 0x04, 0x13, 0x13, 0x04, 0x29, 0x01, 0x20, 0x19, 0x0D, 0x06, 0x16, + 0x13, 0x3A, 0x53, 0x4D, 0x02, 0x00, 0x06, 0x09, 0x02, 0x00, 0x0C, 0x06, + 0x02, 0x2A, 0x16, 0x04, 0x02, 0x03, 0x00, 0x3F, 0x04, 0x0D, 0x01, 0x21, + 0x19, 0x0D, 0x06, 0x04, 0x13, 0x3A, 0x04, 0x03, 0x30, 0x16, 0x13, 0x5D, + 0x02, 0x00, 0x05, 0x02, 0x30, 0x16, 0x02, 0x00, 0x02, 0x01, 0x1D, 0x00, + 0x02, 0x53, 0x4B, 0x05, 0x02, 0x30, 0x16, 0x5B, 0x15, 0x06, 0x07, 0x5D, + 0x01, 0x7F, 0x03, 0x01, 0x04, 0x16, 0x46, 0x15, 0x06, 0x10, 0x01, 0x00, + 0x03, 0x01, 0x14, 0x06, 0x03, 0x4D, 0x04, 0x02, 0x01, 0x00, 0x03, 0x00, + 0x04, 0x02, 0x30, 0x16, 0x3F, 0x57, 0x01, 0x04, 0x3E, 0x53, 0x02, 0x01, + 0x06, 0x03, 0x43, 0x04, 0x03, 0x02, 0x00, 0x40, 0x3F, 0x5D, 0x02, 0x01, + 0x06, 0x03, 0x32, 0x04, 0x01, 0x31, 0x00, 0x00, 0x54, 0x57, 0x01, 0x02, + 0x3E, 0x55, 0x06, 0x02, 0x30, 0x16, 0x57, 0x01, 0x02, 0x3E, 0x44, 0x3F, + 0x00, 0x07, 0x35, 0x50, 0x14, 0x05, 0x02, 0x2F, 0x16, 0x23, 0x01, 0x03, + 0x0B, 0x33, 0x17, 0x47, 0x07, 0x03, 0x00, 0x4F, 0x4F, 0x35, 0x4E, 0x14, + 0x14, 0x03, 0x01, 0x03, 0x02, 0x51, 0x14, 0x03, 0x03, 0x02, 0x02, 0x07, + 0x14, 0x03, 0x02, 0x51, 0x14, 0x03, 0x04, 0x02, 0x02, 0x07, 0x14, 0x03, + 0x02, 0x51, 0x14, 0x03, 0x05, 0x02, 0x02, 0x07, 0x14, 0x03, 0x02, 0x51, + 0x03, 0x06, 0x02, 0x00, 0x02, 0x01, 0x02, 0x03, 0x02, 0x04, 0x02, 0x05, + 0x02, 0x06, 0x1E, 0x00, 0x00, 0x19, 0x19, 0x00, 0x00, 0x01, 0x0B, 0x00, + 0x00, 0x01, 0x00, 0x20, 0x14, 0x06, 0x08, 0x01, 0x01, 0x21, 0x20, 0x22, + 0x20, 0x04, 0x75, 0x13, 0x00, 0x00, 0x01, + T0_INT2(3 * BR_X509_BUFSIZE_SIG), 0x00, 0x01, 0x01, 0x87, 0xFF, 0xFF, + 0x7F, 0x54, 0x57, 0x01, 0x02, 0x3E, 0x55, 0x01, 0x01, 0x0E, 0x06, 0x02, + 0x30, 0x16, 0x57, 0x01, 0x02, 0x19, 0x0D, 0x06, 0x06, 0x13, 0x3B, 0x44, + 0x32, 0x04, 0x1C, 0x01, 0x04, 0x19, 0x0D, 0x06, 0x08, 0x13, 0x3B, 0x01, + 0x00, 0x41, 0x31, 0x04, 0x0E, 0x01, 0x10, 0x19, 0x0D, 0x06, 0x05, 0x13, + 0x3A, 0x42, 0x04, 0x03, 0x30, 0x16, 0x13, 0x03, 0x00, 0x3F, 0x02, 0x00, + 0x34, 0x1F, 0x5A, 0x27, 0x16, 0x00, 0x01, 0x45, 0x0A, 0x06, 0x02, 0x29, + 0x16, 0x14, 0x03, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x57, 0x01, 0x06, + 0x3E, 0x56, 0x00, 0x00, 0x20, 0x14, 0x06, 0x07, 0x1A, 0x14, 0x06, 0x01, + 0x12, 0x04, 0x76, 0x24, 0x00, 0x00, 0x4B, 0x05, 0x02, 0x30, 0x16, 0x37, + 0x15, 0x06, 0x04, 0x01, 0x17, 0x04, 0x12, 0x38, 0x15, 0x06, 0x04, 0x01, + 0x18, 0x04, 0x0A, 0x39, 0x15, 0x06, 0x04, 0x01, 0x19, 0x04, 0x02, 0x30, + 0x16, 0x00, 0x00, 0x1C, 0x57, 0x01, 0x02, 0x3E, 0x09, 0x50, 0x00, 0x00, + 0x35, 0x4E, 0x13, 0x00, 0x03, 0x14, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, + 0x53, 0x59, 0x14, 0x01, 0x81, 0x00, 0x0F, 0x06, 0x02, 0x2E, 0x16, 0x14, + 0x01, 0x00, 0x0D, 0x06, 0x0B, 0x13, 0x14, 0x05, 0x04, 0x13, 0x01, 0x00, + 0x00, 0x59, 0x04, 0x6F, 0x02, 0x01, 0x14, 0x05, 0x02, 0x2B, 0x16, 0x23, + 0x03, 0x01, 0x02, 0x02, 0x1F, 0x02, 0x02, 0x22, 0x03, 0x02, 0x14, 0x06, + 0x03, 0x59, 0x04, 0x68, 0x13, 0x02, 0x00, 0x02, 0x01, 0x08, 0x00, 0x00, + 0x14, 0x35, 0x1C, 0x08, 0x20, 0x1C, 0x07, 0x20, 0x4E, 0x00, 0x01, 0x59, + 0x14, 0x01, 0x81, 0x00, 0x0A, 0x06, 0x01, 0x00, 0x01, 0x81, 0x00, 0x08, + 0x14, 0x05, 0x02, 0x28, 0x16, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, + 0x00, 0x0E, 0x06, 0x19, 0x02, 0x00, 0x23, 0x03, 0x00, 0x14, 0x01, 0x83, + 0xFF, 0xFF, 0x7F, 0x0E, 0x06, 0x02, 0x29, 0x16, 0x01, 0x08, 0x0B, 0x20, + 0x59, 0x1C, 0x07, 0x04, 0x60, 0x00, 0x00, 0x52, 0x4A, 0x00, 0x00, 0x57, + 0x3C, 0x53, 0x00, 0x01, 0x53, 0x14, 0x05, 0x02, 0x2E, 0x16, 0x59, 0x14, + 0x01, 0x81, 0x00, 0x0F, 0x06, 0x02, 0x2E, 0x16, 0x03, 0x00, 0x14, 0x06, + 0x16, 0x59, 0x02, 0x00, 0x14, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x0F, 0x06, + 0x02, 0x2E, 0x16, 0x01, 0x08, 0x0B, 0x07, 0x03, 0x00, 0x04, 0x67, 0x13, + 0x02, 0x00, 0x00, 0x00, 0x53, 0x14, 0x01, 0x81, 0x7F, 0x0E, 0x06, 0x08, + 0x5C, 0x01, 0x00, 0x36, 0x1F, 0x01, 0x00, 0x00, 0x14, 0x36, 0x1F, 0x36, + 0x22, 0x4C, 0x01, 0x7F, 0x00, 0x01, 0x59, 0x03, 0x00, 0x02, 0x00, 0x01, + 0x05, 0x10, 0x01, 0x01, 0x11, 0x18, 0x02, 0x00, 0x01, 0x06, 0x10, 0x14, + 0x01, 0x01, 0x11, 0x06, 0x02, 0x25, 0x16, 0x01, 0x04, 0x0B, 0x02, 0x00, + 0x01, 0x1F, 0x11, 0x14, 0x01, 0x1F, 0x0D, 0x06, 0x02, 0x26, 0x16, 0x07, + 0x00, 0x00, 0x14, 0x05, 0x05, 0x01, 0x00, 0x01, 0x7F, 0x00, 0x57, 0x00, + 0x00, 0x14, 0x05, 0x02, 0x29, 0x16, 0x23, 0x5A, 0x00, 0x00, 0x1B, 0x14, + 0x01, 0x00, 0x0F, 0x06, 0x01, 0x00, 0x13, 0x12, 0x04, 0x74, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x5D, 0x13, 0x00, 0x00, 0x14, 0x06, 0x07, 0x5E, 0x14, + 0x06, 0x01, 0x12, 0x04, 0x76, 0x00, 0x00, 0x01, 0x00, 0x19, 0x1A, 0x09, + 0x24, 0x00 +}; + +static const uint16_t t0_caddr[] = { + 0, + 5, + 10, + 14, + 18, + 22, + 26, + 30, + 34, + 38, + 42, + 46, + 50, + 54, + 58, + 62, + 66, + 70, + 75, + 80, + 84, + 89, + 93, + 97, + 101, + 107, + 113, + 118, + 126, + 134, + 140, + 163, + 244, + 311, + 329, + 404, + 408, + 412, + 429, + 434, + 505, + 519, + 526, + 540, + 573, + 582, + 587, + 654, + 665, + 721, + 725, + 730, + 778, + 804, + 848, + 859, + 868, + 881, + 885, + 889, + 901 +}; + +#define T0_INTERPRETED 34 + +#define T0_ENTER(ip, rp, slot) do { \ + const unsigned char *t0_newip; \ + uint32_t t0_lnum; \ + t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ + t0_lnum = t0_parse7E_unsigned(&t0_newip); \ + (rp) += t0_lnum; \ + *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ + (ip) = t0_newip; \ + } while (0) + +#define T0_DEFENTRY(name, slot) \ +void \ +name(void *ctx) \ +{ \ + t0_context *t0ctx = ctx; \ + t0ctx->ip = &t0_codeblock[0]; \ + T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ +} + +T0_DEFENTRY(br_skey_decoder_init_main, 73) + +#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) + +void +br_skey_decoder_run(void *t0ctx) +{ + uint32_t *dp, *rp; + const unsigned char *ip; + +#define T0_LOCAL(x) (*(rp - 2 - (x))) +#define T0_POP() (*-- dp) +#define T0_POPi() (*(int32_t *)(-- dp)) +#define T0_PEEK(x) (*(dp - 1 - (x))) +#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) +#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) +#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) +#define T0_RPOP() (*-- rp) +#define T0_RPOPi() (*(int32_t *)(-- rp)) +#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) +#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) +#define T0_ROLL(x) do { \ + size_t t0len = (size_t)(x); \ + uint32_t t0tmp = *(dp - 1 - t0len); \ + memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_SWAP() do { \ + uint32_t t0tmp = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_ROT() do { \ + uint32_t t0tmp = *(dp - 3); \ + *(dp - 3) = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_NROT() do { \ + uint32_t t0tmp = *(dp - 1); \ + *(dp - 1) = *(dp - 2); \ + *(dp - 2) = *(dp - 3); \ + *(dp - 3) = t0tmp; \ +} while (0) +#define T0_PICK(x) do { \ + uint32_t t0depth = (x); \ + T0_PUSH(T0_PEEK(t0depth)); \ +} while (0) +#define T0_CO() do { \ + goto t0_exit; \ +} while (0) +#define T0_RET() goto t0_next + + dp = ((t0_context *)t0ctx)->dp; + rp = ((t0_context *)t0ctx)->rp; + ip = ((t0_context *)t0ctx)->ip; + goto t0_next; + for (;;) { + uint32_t t0x; + + t0_next: + t0x = T0_NEXT(&ip); + if (t0x < T0_INTERPRETED) { + switch (t0x) { + int32_t t0off; + + case 0: /* ret */ + t0x = T0_RPOP(); + rp -= (t0x >> 16); + t0x &= 0xFFFF; + if (t0x == 0) { + ip = NULL; + goto t0_exit; + } + ip = &t0_codeblock[t0x]; + break; + case 1: /* literal constant */ + T0_PUSHi(t0_parse7E_signed(&ip)); + break; + case 2: /* read local */ + T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); + break; + case 3: /* write local */ + T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); + break; + case 4: /* jump */ + t0off = t0_parse7E_signed(&ip); + ip += t0off; + break; + case 5: /* jump if */ + t0off = t0_parse7E_signed(&ip); + if (T0_POP()) { + ip += t0off; + } + break; + case 6: /* jump if not */ + t0off = t0_parse7E_signed(&ip); + if (!T0_POP()) { + ip += t0off; + } + break; + case 7: { + /* + */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a + b); + + } + break; + case 8: { + /* - */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a - b); + + } + break; + case 9: { + /* -rot */ + T0_NROT(); + } + break; + case 10: { + /* < */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a < b)); + + } + break; + case 11: { + /* << */ + + int c = (int)T0_POPi(); + uint32_t x = T0_POP(); + T0_PUSH(x << c); + + } + break; + case 12: { + /* <> */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a != b)); + + } + break; + case 13: { + /* = */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a == b)); + + } + break; + case 14: { + /* > */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a > b)); + + } + break; + case 15: { + /* >= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a >= b)); + + } + break; + case 16: { + /* >> */ + + int c = (int)T0_POPi(); + int32_t x = T0_POPi(); + T0_PUSHi(x >> c); + + } + break; + case 17: { + /* and */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a & b); + + } + break; + case 18: { + /* co */ + T0_CO(); + } + break; + case 19: { + /* drop */ + (void)T0_POP(); + } + break; + case 20: { + /* dup */ + T0_PUSH(T0_PEEK(0)); + } + break; + case 21: { + /* eqOID */ + + const unsigned char *a2 = &t0_datablock[T0_POP()]; + const unsigned char *a1 = &CTX->pad[0]; + size_t len = a1[0]; + int x; + if (len == a2[0]) { + x = -(memcmp(a1 + 1, a2 + 1, len) == 0); + } else { + x = 0; + } + T0_PUSH((uint32_t)x); + + } + break; + case 22: { + /* fail */ + + CTX->err = T0_POPi(); + T0_CO(); + + } + break; + case 23: { + /* get8 */ + + uint32_t addr = T0_POP(); + T0_PUSH(*((unsigned char *)CTX + addr)); + + } + break; + case 24: { + /* neg */ + + uint32_t a = T0_POP(); + T0_PUSH(-a); + + } + break; + case 25: { + /* over */ + T0_PUSH(T0_PEEK(1)); + } + break; + case 26: { + /* read-blob-inner */ + + uint32_t len = T0_POP(); + uint32_t addr = T0_POP(); + size_t clen = CTX->hlen; + if (clen > len) { + clen = (size_t)len; + } + if (addr != 0) { + memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); + } + CTX->hbuf += clen; + CTX->hlen -= clen; + T0_PUSH(addr + clen); + T0_PUSH(len - clen); + + } + break; + case 27: { + /* read8-low */ + + if (CTX->hlen == 0) { + T0_PUSHi(-1); + } else { + CTX->hlen --; + T0_PUSH(*CTX->hbuf ++); + } + + } + break; + case 28: { + /* rot */ + T0_ROT(); + } + break; + case 29: { + /* set-ec-key */ + + size_t xlen = T0_POP(); + uint32_t curve = T0_POP(); + CTX->key.ec.curve = curve; + CTX->key.ec.x = CTX->key_data; + CTX->key.ec.xlen = xlen; + + } + break; + case 30: { + /* set-rsa-key */ + + size_t iqlen = T0_POP(); + size_t dqlen = T0_POP(); + size_t dplen = T0_POP(); + size_t qlen = T0_POP(); + size_t plen = T0_POP(); + uint32_t n_bitlen = T0_POP(); + size_t off; + + CTX->key.rsa.n_bitlen = n_bitlen; + CTX->key.rsa.p = CTX->key_data; + CTX->key.rsa.plen = plen; + off = plen; + CTX->key.rsa.q = CTX->key_data + off; + CTX->key.rsa.qlen = qlen; + off += qlen; + CTX->key.rsa.dp = CTX->key_data + off; + CTX->key.rsa.dplen = dplen; + off += dplen; + CTX->key.rsa.dq = CTX->key_data + off; + CTX->key.rsa.dqlen = dqlen; + off += dqlen; + CTX->key.rsa.iq = CTX->key_data + off; + CTX->key.rsa.iqlen = iqlen; + + } + break; + case 31: { + /* set8 */ + + uint32_t addr = T0_POP(); + *((unsigned char *)CTX + addr) = (unsigned char)T0_POP(); + + } + break; + case 32: { + /* swap */ + T0_SWAP(); + } + break; + case 33: { + /* u>> */ + + int c = (int)T0_POPi(); + uint32_t x = T0_POP(); + T0_PUSH(x >> c); + + } + break; + } + + } else { + T0_ENTER(ip, rp, t0x); + } + } +t0_exit: + ((t0_context *)t0ctx)->dp = dp; + ((t0_context *)t0ctx)->rp = rp; + ((t0_context *)t0ctx)->ip = ip; +} diff --git a/BearSSL-OG/libbearssl/src/x509/skey_decoder.t0 b/BearSSL-OG/libbearssl/src/x509/skey_decoder.t0 new file mode 100644 index 0000000..f00e614 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/skey_decoder.t0 @@ -0,0 +1,373 @@ +\ Copyright (c) 2016 Thomas Pornin +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +\ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +\ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +\ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +\ SOFTWARE. + +preamble { + +#include "inner.h" + +#define CTX ((br_skey_decoder_context *)(void *)((unsigned char *)t0ctx - offsetof(br_skey_decoder_context, cpu))) +#define CONTEXT_NAME br_skey_decoder_context + +/* see bearssl_x509.h */ +void +br_skey_decoder_init(br_skey_decoder_context *ctx) +{ + memset(ctx, 0, sizeof *ctx); + ctx->cpu.dp = &ctx->dp_stack[0]; + ctx->cpu.rp = &ctx->rp_stack[0]; + br_skey_decoder_init_main(&ctx->cpu); + br_skey_decoder_run(&ctx->cpu); +} + +/* see bearssl_x509.h */ +void +br_skey_decoder_push(br_skey_decoder_context *ctx, + const void *data, size_t len) +{ + ctx->hbuf = data; + ctx->hlen = len; + br_skey_decoder_run(&ctx->cpu); +} + +} + +addr: key_type +addr: key_data + +cc: read8-low ( -- x ) { + if (CTX->hlen == 0) { + T0_PUSHi(-1); + } else { + CTX->hlen --; + T0_PUSH(*CTX->hbuf ++); + } +} + +cc: read-blob-inner ( addr len -- addr len ) { + uint32_t len = T0_POP(); + uint32_t addr = T0_POP(); + size_t clen = CTX->hlen; + if (clen > len) { + clen = (size_t)len; + } + if (addr != 0) { + memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); + } + CTX->hbuf += clen; + CTX->hlen -= clen; + T0_PUSH(addr + clen); + T0_PUSH(len - clen); +} + +\ Get the length of the key_data buffer. +: len-key_data + CX 0 8191 { 3 * BR_X509_BUFSIZE_SIG } ; + +\ Get the address and length for the key_data buffer. +: addr-len-key_data ( -- addr len ) + addr-key_data len-key_data ; + +\ Set the private key (RSA). +cc: set-rsa-key ( n_bitlen plen qlen dplen dqlen iqlen -- ) { + size_t iqlen = T0_POP(); + size_t dqlen = T0_POP(); + size_t dplen = T0_POP(); + size_t qlen = T0_POP(); + size_t plen = T0_POP(); + uint32_t n_bitlen = T0_POP(); + size_t off; + + CTX->key.rsa.n_bitlen = n_bitlen; + CTX->key.rsa.p = CTX->key_data; + CTX->key.rsa.plen = plen; + off = plen; + CTX->key.rsa.q = CTX->key_data + off; + CTX->key.rsa.qlen = qlen; + off += qlen; + CTX->key.rsa.dp = CTX->key_data + off; + CTX->key.rsa.dplen = dplen; + off += dplen; + CTX->key.rsa.dq = CTX->key_data + off; + CTX->key.rsa.dqlen = dqlen; + off += dqlen; + CTX->key.rsa.iq = CTX->key_data + off; + CTX->key.rsa.iqlen = iqlen; +} + +\ Set the private key (EC). +cc: set-ec-key ( curve xlen -- ) { + size_t xlen = T0_POP(); + uint32_t curve = T0_POP(); + CTX->key.ec.curve = curve; + CTX->key.ec.x = CTX->key_data; + CTX->key.ec.xlen = xlen; +} + +\ Get the bit length for an integer (unsigned). +: int-bit-length ( x -- bitlen ) + 0 swap + begin dup while 1 u>> swap 1+ swap repeat + drop ; + +\ Read an INTEGER into the key_data buffer, but then ignore it. +: read-integer-ignore ( lim -- lim ) + addr-len-key_data read-integer drop ; + +\ Read an INTEGER into the key_data buffer, at the provided offset. +\ Returned value is the integer length (in bytes). +: read-integer-off ( lim off -- lim dlen ) + dup addr-len-key_data rot - swap rot + swap read-integer ; + +\ Decode RSA key, starting with the SEQUENCE tag. +: decode-RSA ( lim -- lim ) + read-sequence-open + + \ Version should be 0. + read-tag 0x02 check-tag-primitive read-small-int-value if + ERR_X509_UNSUPPORTED fail + then + + \ Read tag for the modulus; should be INTEGER. Then use the + \ decode-RSA-next function for the remainder of the key. + read-tag 0x02 check-tag-primitive + decode-RSA-next + + \ Close the SEQUENCE. + close-elt ; + +\ Decode RSA key; the version, and the tag for the modulus, have been +\ read. +: decode-RSA-next ( lim -- lim ) + \ Modulus: we read it but we do not keep it; we merely gather + \ the modulus bit length. + addr-len-key_data read-integer-next + dup ifnot ERR_X509_UNEXPECTED fail then + 1- 3 << addr-key_data get8 int-bit-length + { n_bitlen } + + \ Public exponent: read but skip. + read-integer-ignore + + \ Private exponent: read but skip. + read-integer-ignore + + \ First prime factor. + addr-len-key_data read-integer dup dup { off plen } + + \ Second prime factor. + read-integer-off dup { qlen } off + dup >off + + \ First reduced private exponent. + read-integer-off dup { dplen } off + dup >off + + \ Second reduced private exponent. + read-integer-off dup { dqlen } off + dup >off + + \ CRT coefficient. + read-integer-off { iqlen } + + \ Set RSA key. + n_bitlen plen qlen dplen dqlen iqlen set-rsa-key + + \ The caller will close the sequence, thereby validating that there + \ is no extra field. + ; + +\ Decode an EC key, starting with the SEQUENCE tag. +: decode-EC ( lim curve -- lim ) + { curve } + read-sequence-open + + \ Version should be 1. + read-tag 0x02 check-tag-primitive read-small-int-value 1- if + ERR_X509_UNSUPPORTED fail + then + + \ Read tag for the private key; should be OCTET STRING. Then use the + \ decode-EC-next function for the remainder of the key. + read-tag 0x04 check-tag-primitive + curve decode-EC-next + + \ Close the SEQUENCE. + close-elt ; + +\ Decode an EC key; the version, and the tag for the OCTET STRING, have +\ already been read. The curve ID is provided (0 if unknown). +: decode-EC-next ( lim curve -- lim ) + { curve } + + \ Read the private key proper. + read-length-open-elt + dup dup { xlen } len-key_data > if ERR_X509_UNSUPPORTED fail then + addr-key_data read-blob + + \ Next element might be the curve identifier. + read-tag-or-end + case + + \ End of structure. + -1 of drop endof + + \ Curve parameters; we support only named curves. + 0x20 of + check-constructed read-length-open-elt + read-curve-ID + curve if + curve <> if ERR_X509_INVALID_VALUE fail then + else + >curve + then + close-elt + endof + + \ Public key. We ignore it. + 0x21 of check-constructed endof + + ERR_X509_UNSUPPORTED fail + endcase + skip-remaining + + \ The curve must have been defined one way or another. + curve ifnot ERR_X509_UNSUPPORTED fail then + + \ Set the EC key. + curve xlen set-ec-key + + \ The caller will close the sequence. + ; + +\ Decode a PKCS#8 object. The version and the tag for the AlgorithmIdentifier +\ structure have already been read. This function returns the key type. +: decode-PKCS8-next ( lim -- lim keytype ) + \ Decode the AlgorithmIdentifier. + read-length-open-elt + read-OID ifnot ERR_X509_UNSUPPORTED fail then + { ; is-rsa curve } + choice + rsaEncryption eqOID uf + \ RSA private key. We ignore the parameters. + skip-remaining -1 >is-rsa + enduf + id-ecPublicKey eqOID uf + \ EC private key. Parameters, if present, shall + \ identify the curve. + 0 >is-rsa + dup if read-curve-ID else 0 then >curve + enduf + + ERR_X509_UNSUPPORTED fail + endchoice + close-elt + + \ Open private key value and decode it. + read-tag 0x04 check-tag-primitive + read-length-open-elt + is-rsa if + decode-RSA + else + curve decode-EC + then + close-elt + + \ We ignore any extra field, i.e. attributes or public key. + skip-remaining + + \ Return the key type. + is-rsa if KEYTYPE_RSA else KEYTYPE_EC then + ; + +\ Decode a private key. +: main ( -- ! ) + \ RSA private key format is defined in PKCS#1 (RFC 3447): + \ RSAPrivateKey ::= SEQUENCE { + \ version INTEGER, -- 0 or 1 + \ n INTEGER, + \ e INTEGER, + \ d INTEGER, + \ p INTEGER, + \ q INTEGER, + \ dp INTEGER, + \ dq INTEGER, + \ iq INTEGER, + \ other OtherPrimeInfos OPTIONAL + \ } + \ We do not support keys with more than two primes (these have + \ version 1); thus, we expect the version field to be 0, and + \ the 'other' field to be absent. + \ + \ EC private key format is defined in RFC 5915: + \ ECPrivateKey ::= SEQUENCE { + \ version INTEGER, -- always 1 + \ privateKey OCTET STRING, + \ parameters [0] EXPLICIT OBJECT IDENTIFIER OPTIONAL, + \ publicKey [1] EXPLICIT BIT STRING OPTIONAL + \ } + \ The "parameters" might conceptually be a complex curve description + \ structure but we support only named curves. The private key + \ contents are the unsigned big-endian encoding of the key value, + \ which is exactly what we want. + \ + \ PKCS#8 (unencrypted) is: + \ OneAsymmetricKey ::= SEQUENCE { + \ version INTEGER, -- 0 or 1 + \ algorithm AlgorithmIdentifier, + \ privateKey OCTET STRING, + \ attributes [0] IMPLICIT Attributes OPTIONAL, + \ publicKey [1] IMPLICIT BIT STRING OPTIONAL + \ } + \ The 'publicKey' field is an add-on from RFC 5958 and may be + \ present only if the 'version' is v2 (i.e. has value 1). We + \ ignore it anyway. + + \ An arbitrary upper limit on the private key size. + 0xFFFFFF + + \ Open the outer SEQUENCE. + read-sequence-open + + \ All our schemas begin with a small INTEGER which is either 0 or + \ 1. We don't care which it is. + read-tag 0x02 check-tag-primitive read-small-int-value 1 > if + ERR_X509_UNSUPPORTED fail + then + + \ Get next tag: it should be either an INTEGER (RSA private key), + \ an OCTET STRING (EC private key), or a SEQUENCE (for an + \ AlgorithmIdentifier, in a PKCS#8 object). + read-tag + case + 0x02 of check-primitive decode-RSA-next KEYTYPE_RSA endof + 0x04 of check-primitive 0 decode-EC-next KEYTYPE_EC endof + 0x10 of check-constructed decode-PKCS8-next endof + ERR_X509_UNSUPPORTED fail + endcase + { key-type } + + \ Close the SEQUENCE. + close-elt + + \ Set the key type, which marks the decoding as a success. + key-type addr-key_type set8 + + \ Read one byte, then fail: if the read succeeds, then there is + \ some trailing byte. + read8-nc ERR_X509_EXTRA_ELEMENT fail + ; diff --git a/BearSSL-OG/libbearssl/src/x509/x509_decoder.c b/BearSSL-OG/libbearssl/src/x509/x509_decoder.c new file mode 100644 index 0000000..8dd970f --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/x509_decoder.c @@ -0,0 +1,773 @@ +/* Automatically generated code; do not modify directly. */ + +#include +#include + +typedef struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; +} t0_context; + +static uint32_t +t0_parse7E_unsigned(const unsigned char **p) +{ + uint32_t x; + + x = 0; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + return x; + } + } +} + +static int32_t +t0_parse7E_signed(const unsigned char **p) +{ + int neg; + uint32_t x; + + neg = ((**p) >> 6) & 1; + x = (uint32_t)-neg; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + if (neg) { + return -(int32_t)~x - 1; + } else { + return (int32_t)x; + } + } + } +} + +#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) +#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) +#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) +#define T0_INT1(x) T0_FBYTE(x, 0) +#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) + +/* static const unsigned char t0_datablock[]; */ + + +void br_x509_decoder_init_main(void *t0ctx); + +void br_x509_decoder_run(void *t0ctx); + + + +#include "inner.h" + + + + + +#include "inner.h" + +#define CTX ((br_x509_decoder_context *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_decoder_context, cpu))) +#define CONTEXT_NAME br_x509_decoder_context + +/* see bearssl_x509.h */ +void +br_x509_decoder_init(br_x509_decoder_context *ctx, + void (*append_dn)(void *ctx, const void *buf, size_t len), + void *append_dn_ctx) +{ + memset(ctx, 0, sizeof *ctx); + /* obsolete + ctx->err = 0; + ctx->hbuf = NULL; + ctx->hlen = 0; + */ + ctx->append_dn = append_dn; + ctx->append_dn_ctx = append_dn_ctx; + ctx->cpu.dp = &ctx->dp_stack[0]; + ctx->cpu.rp = &ctx->rp_stack[0]; + br_x509_decoder_init_main(&ctx->cpu); + br_x509_decoder_run(&ctx->cpu); +} + +/* see bearssl_x509.h */ +void +br_x509_decoder_push(br_x509_decoder_context *ctx, + const void *data, size_t len) +{ + ctx->hbuf = data; + ctx->hlen = len; + br_x509_decoder_run(&ctx->cpu); +} + + + +static const unsigned char t0_datablock[] = { + 0x00, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x01, 0x0C, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, + 0x0D, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x08, 0x2A, 0x86, + 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, + 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, + 0x04, 0x01, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01, 0x08, + 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x08, 0x2A, 0x86, 0x48, + 0xCE, 0x3D, 0x04, 0x03, 0x03, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, + 0x03, 0x04, 0x00, 0x1F, 0x03, 0xFC, 0x07, 0x7F, 0x0B, 0x5E, 0x0F, 0x1F, + 0x12, 0xFE, 0x16, 0xBF, 0x1A, 0x9F, 0x1E, 0x7E, 0x22, 0x3F, 0x26, 0x1E, + 0x29, 0xDF, 0x00, 0x1F, 0x03, 0xFD, 0x07, 0x9F, 0x0B, 0x7E, 0x0F, 0x3F, + 0x13, 0x1E, 0x16, 0xDF, 0x1A, 0xBF, 0x1E, 0x9E, 0x22, 0x5F, 0x26, 0x3E, + 0x29, 0xFF, 0x03, 0x55, 0x1D, 0x13 +}; + +static const unsigned char t0_codeblock[] = { + 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x01, + 0x01, 0x09, 0x00, 0x00, 0x01, 0x01, 0x0A, 0x00, 0x00, 0x1A, 0x1A, 0x00, + 0x00, 0x01, T0_INT1(BR_ERR_X509_BAD_BOOLEAN), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_BAD_TAG_CLASS), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_BAD_TAG_VALUE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_BAD_TIME), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_EXTRA_ELEMENT), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_INDEFINITE_LENGTH), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_INNER_TRUNC), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_NOT_CONSTRUCTED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_NOT_PRIMITIVE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_OVERFLOW), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_PARTIAL_BYTE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_UNEXPECTED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_UNSUPPORTED), 0x00, 0x00, 0x01, + T0_INT1(BR_KEYTYPE_EC), 0x00, 0x00, 0x01, T0_INT1(BR_KEYTYPE_RSA), + 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, copy_dn)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(CONTEXT_NAME, decoded)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, isCA)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_x509_decoder_context, pkey_data)), 0x01, + T0_INT2(BR_X509_BUFSIZE_KEY), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, notafter_days)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, notafter_seconds)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, notbefore_days)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, notbefore_seconds)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, pad)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, signer_hash_id)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, signer_key_type)), 0x00, 0x00, 0x01, + 0x80, 0x45, 0x00, 0x00, 0x01, 0x80, 0x4E, 0x00, 0x00, 0x01, 0x80, 0x54, + 0x00, 0x00, 0x01, 0x81, 0x36, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0x1B, + 0x02, 0x01, 0x13, 0x26, 0x02, 0x00, 0x0F, 0x15, 0x00, 0x00, 0x05, 0x02, + 0x34, 0x1D, 0x00, 0x00, 0x06, 0x02, 0x35, 0x1D, 0x00, 0x00, 0x01, 0x10, + 0x4F, 0x00, 0x00, 0x11, 0x05, 0x02, 0x38, 0x1D, 0x4C, 0x00, 0x00, 0x11, + 0x05, 0x02, 0x38, 0x1D, 0x4D, 0x00, 0x00, 0x06, 0x02, 0x30, 0x1D, 0x00, + 0x00, 0x1B, 0x19, 0x01, 0x08, 0x0E, 0x26, 0x29, 0x19, 0x09, 0x00, 0x00, + 0x01, 0x30, 0x0A, 0x1B, 0x01, 0x00, 0x01, 0x09, 0x4B, 0x05, 0x02, 0x2F, + 0x1D, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x01, 0x80, 0x5A, 0x00, 0x00, + 0x01, 0x80, 0x62, 0x00, 0x00, 0x01, 0x80, 0x6B, 0x00, 0x00, 0x01, 0x80, + 0x74, 0x00, 0x00, 0x01, 0x80, 0x7D, 0x00, 0x00, 0x01, 0x3D, 0x00, 0x00, + 0x20, 0x11, 0x06, 0x04, 0x2B, 0x6B, 0x7A, 0x71, 0x00, 0x04, 0x01, 0x00, + 0x3D, 0x25, 0x01, 0x00, 0x3C, 0x25, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x6D, + 0x6D, 0x70, 0x1B, 0x01, 0x20, 0x11, 0x06, 0x11, 0x1A, 0x4C, 0x6B, 0x70, + 0x01, 0x02, 0x50, 0x6E, 0x01, 0x02, 0x12, 0x06, 0x02, 0x39, 0x1D, 0x51, + 0x70, 0x01, 0x02, 0x50, 0x6C, 0x6D, 0x7A, 0x6D, 0x7A, 0x6D, 0x65, 0x43, + 0x24, 0x42, 0x24, 0x65, 0x41, 0x24, 0x40, 0x24, 0x51, 0x01, 0x01, 0x3C, + 0x25, 0x6D, 0x7A, 0x01, 0x00, 0x3C, 0x25, 0x6D, 0x6D, 0x60, 0x05, 0x02, + 0x39, 0x1D, 0x74, 0x1C, 0x06, 0x1C, 0x7A, 0x61, 0x6D, 0x3F, 0x68, 0x03, + 0x00, 0x3F, 0x26, 0x02, 0x00, 0x09, 0x26, 0x02, 0x00, 0x0A, 0x68, 0x03, + 0x01, 0x51, 0x51, 0x02, 0x00, 0x02, 0x01, 0x18, 0x04, 0x1E, 0x5A, 0x1C, + 0x06, 0x18, 0x64, 0x03, 0x02, 0x51, 0x61, 0x1B, 0x03, 0x03, 0x1B, 0x3F, + 0x23, 0x0D, 0x06, 0x02, 0x33, 0x1D, 0x62, 0x02, 0x02, 0x02, 0x03, 0x17, + 0x04, 0x02, 0x39, 0x1D, 0x51, 0x01, 0x00, 0x3E, 0x25, 0x71, 0x01, 0x21, + 0x5B, 0x01, 0x22, 0x5B, 0x1B, 0x01, 0x23, 0x11, 0x06, 0x28, 0x1A, 0x4C, + 0x6B, 0x6D, 0x1B, 0x06, 0x1D, 0x6D, 0x60, 0x1A, 0x70, 0x1B, 0x01, 0x01, + 0x11, 0x06, 0x03, 0x63, 0x1A, 0x70, 0x01, 0x04, 0x50, 0x6B, 0x4A, 0x1C, + 0x06, 0x03, 0x5F, 0x04, 0x01, 0x7B, 0x51, 0x51, 0x04, 0x60, 0x51, 0x51, + 0x04, 0x08, 0x01, 0x7F, 0x11, 0x05, 0x02, 0x38, 0x1D, 0x1A, 0x51, 0x6D, + 0x60, 0x06, 0x80, 0x63, 0x75, 0x1C, 0x06, 0x06, 0x01, 0x02, 0x3B, 0x04, + 0x80, 0x57, 0x76, 0x1C, 0x06, 0x06, 0x01, 0x03, 0x3B, 0x04, 0x80, 0x4D, + 0x77, 0x1C, 0x06, 0x06, 0x01, 0x04, 0x3B, 0x04, 0x80, 0x43, 0x78, 0x1C, + 0x06, 0x05, 0x01, 0x05, 0x3B, 0x04, 0x3A, 0x79, 0x1C, 0x06, 0x05, 0x01, + 0x06, 0x3B, 0x04, 0x31, 0x55, 0x1C, 0x06, 0x05, 0x01, 0x02, 0x3A, 0x04, + 0x28, 0x56, 0x1C, 0x06, 0x05, 0x01, 0x03, 0x3A, 0x04, 0x1F, 0x57, 0x1C, + 0x06, 0x05, 0x01, 0x04, 0x3A, 0x04, 0x16, 0x58, 0x1C, 0x06, 0x05, 0x01, + 0x05, 0x3A, 0x04, 0x0D, 0x59, 0x1C, 0x06, 0x05, 0x01, 0x06, 0x3A, 0x04, + 0x04, 0x01, 0x00, 0x01, 0x00, 0x04, 0x04, 0x01, 0x00, 0x01, 0x00, 0x46, + 0x25, 0x45, 0x25, 0x7A, 0x61, 0x7A, 0x51, 0x1A, 0x01, 0x01, 0x3D, 0x25, + 0x73, 0x30, 0x1D, 0x00, 0x00, 0x01, 0x81, 0x06, 0x00, 0x01, 0x54, 0x0D, + 0x06, 0x02, 0x32, 0x1D, 0x1B, 0x03, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x00, + 0x6D, 0x71, 0x1B, 0x01, 0x01, 0x11, 0x06, 0x08, 0x63, 0x01, 0x01, 0x15, + 0x3E, 0x25, 0x04, 0x01, 0x2B, 0x7A, 0x00, 0x00, 0x70, 0x01, 0x06, 0x50, + 0x6F, 0x00, 0x00, 0x70, 0x01, 0x03, 0x50, 0x6B, 0x72, 0x06, 0x02, 0x37, + 0x1D, 0x00, 0x00, 0x26, 0x1B, 0x06, 0x07, 0x21, 0x1B, 0x06, 0x01, 0x16, + 0x04, 0x76, 0x2B, 0x00, 0x00, 0x01, 0x01, 0x50, 0x6A, 0x01, 0x01, 0x10, + 0x06, 0x02, 0x2C, 0x1D, 0x72, 0x27, 0x00, 0x00, 0x60, 0x05, 0x02, 0x39, + 0x1D, 0x47, 0x1C, 0x06, 0x04, 0x01, 0x17, 0x04, 0x12, 0x48, 0x1C, 0x06, + 0x04, 0x01, 0x18, 0x04, 0x0A, 0x49, 0x1C, 0x06, 0x04, 0x01, 0x19, 0x04, + 0x02, 0x39, 0x1D, 0x00, 0x04, 0x70, 0x1B, 0x01, 0x17, 0x01, 0x18, 0x4B, + 0x05, 0x02, 0x2F, 0x1D, 0x01, 0x18, 0x11, 0x03, 0x00, 0x4D, 0x6B, 0x66, + 0x02, 0x00, 0x06, 0x0C, 0x01, 0x80, 0x64, 0x08, 0x03, 0x01, 0x66, 0x02, + 0x01, 0x09, 0x04, 0x0E, 0x1B, 0x01, 0x32, 0x0D, 0x06, 0x04, 0x01, 0x80, + 0x64, 0x09, 0x01, 0x8E, 0x6C, 0x09, 0x03, 0x01, 0x02, 0x01, 0x01, 0x82, + 0x6D, 0x08, 0x02, 0x01, 0x01, 0x03, 0x09, 0x01, 0x04, 0x0C, 0x09, 0x02, + 0x01, 0x01, 0x80, 0x63, 0x09, 0x01, 0x80, 0x64, 0x0C, 0x0A, 0x02, 0x01, + 0x01, 0x83, 0x0F, 0x09, 0x01, 0x83, 0x10, 0x0C, 0x09, 0x03, 0x03, 0x01, + 0x01, 0x01, 0x0C, 0x67, 0x2A, 0x01, 0x01, 0x0E, 0x02, 0x01, 0x01, 0x04, + 0x07, 0x28, 0x02, 0x01, 0x01, 0x80, 0x64, 0x07, 0x27, 0x02, 0x01, 0x01, + 0x83, 0x10, 0x07, 0x28, 0x1F, 0x15, 0x06, 0x03, 0x01, 0x18, 0x09, 0x5D, + 0x09, 0x52, 0x1B, 0x01, 0x05, 0x14, 0x02, 0x03, 0x09, 0x03, 0x03, 0x01, + 0x1F, 0x15, 0x01, 0x01, 0x26, 0x67, 0x02, 0x03, 0x09, 0x2A, 0x03, 0x03, + 0x01, 0x00, 0x01, 0x17, 0x67, 0x01, 0x9C, 0x10, 0x08, 0x03, 0x02, 0x01, + 0x00, 0x01, 0x3B, 0x67, 0x01, 0x3C, 0x08, 0x02, 0x02, 0x09, 0x03, 0x02, + 0x01, 0x00, 0x01, 0x3C, 0x67, 0x02, 0x02, 0x09, 0x03, 0x02, 0x72, 0x1B, + 0x01, 0x2E, 0x11, 0x06, 0x0D, 0x1A, 0x72, 0x1B, 0x01, 0x30, 0x01, 0x39, + 0x4B, 0x06, 0x03, 0x1A, 0x04, 0x74, 0x01, 0x80, 0x5A, 0x10, 0x06, 0x02, + 0x2F, 0x1D, 0x51, 0x02, 0x03, 0x02, 0x02, 0x00, 0x01, 0x72, 0x53, 0x01, + 0x0A, 0x08, 0x03, 0x00, 0x72, 0x53, 0x02, 0x00, 0x09, 0x00, 0x02, 0x03, + 0x00, 0x03, 0x01, 0x66, 0x1B, 0x02, 0x01, 0x02, 0x00, 0x4B, 0x05, 0x02, + 0x2F, 0x1D, 0x00, 0x00, 0x23, 0x70, 0x01, 0x02, 0x50, 0x0B, 0x69, 0x00, + 0x03, 0x1B, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0x6B, 0x72, 0x1B, 0x01, + 0x81, 0x00, 0x13, 0x06, 0x02, 0x36, 0x1D, 0x1B, 0x01, 0x00, 0x11, 0x06, + 0x0B, 0x1A, 0x1B, 0x05, 0x04, 0x1A, 0x01, 0x00, 0x00, 0x72, 0x04, 0x6F, + 0x02, 0x01, 0x1B, 0x05, 0x02, 0x33, 0x1D, 0x2A, 0x03, 0x01, 0x02, 0x02, + 0x25, 0x02, 0x02, 0x29, 0x03, 0x02, 0x1B, 0x06, 0x03, 0x72, 0x04, 0x68, + 0x1A, 0x02, 0x00, 0x02, 0x01, 0x0A, 0x00, 0x01, 0x72, 0x1B, 0x01, 0x81, + 0x00, 0x0D, 0x06, 0x01, 0x00, 0x01, 0x81, 0x00, 0x0A, 0x1B, 0x05, 0x02, + 0x31, 0x1D, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x12, 0x06, + 0x19, 0x02, 0x00, 0x2A, 0x03, 0x00, 0x1B, 0x01, 0x83, 0xFF, 0xFF, 0x7F, + 0x12, 0x06, 0x02, 0x32, 0x1D, 0x01, 0x08, 0x0E, 0x26, 0x72, 0x23, 0x09, + 0x04, 0x60, 0x00, 0x00, 0x6A, 0x5E, 0x00, 0x00, 0x6B, 0x7A, 0x00, 0x00, + 0x70, 0x4E, 0x6B, 0x00, 0x01, 0x6B, 0x1B, 0x05, 0x02, 0x36, 0x1D, 0x72, + 0x1B, 0x01, 0x81, 0x00, 0x13, 0x06, 0x02, 0x36, 0x1D, 0x03, 0x00, 0x1B, + 0x06, 0x16, 0x72, 0x02, 0x00, 0x1B, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x13, + 0x06, 0x02, 0x36, 0x1D, 0x01, 0x08, 0x0E, 0x09, 0x03, 0x00, 0x04, 0x67, + 0x1A, 0x02, 0x00, 0x00, 0x00, 0x6B, 0x1B, 0x01, 0x81, 0x7F, 0x12, 0x06, + 0x08, 0x7A, 0x01, 0x00, 0x44, 0x25, 0x01, 0x00, 0x00, 0x1B, 0x44, 0x25, + 0x44, 0x29, 0x62, 0x01, 0x7F, 0x00, 0x01, 0x72, 0x03, 0x00, 0x02, 0x00, + 0x01, 0x05, 0x14, 0x01, 0x01, 0x15, 0x1E, 0x02, 0x00, 0x01, 0x06, 0x14, + 0x1B, 0x01, 0x01, 0x15, 0x06, 0x02, 0x2D, 0x1D, 0x01, 0x04, 0x0E, 0x02, + 0x00, 0x01, 0x1F, 0x15, 0x1B, 0x01, 0x1F, 0x11, 0x06, 0x02, 0x2E, 0x1D, + 0x09, 0x00, 0x00, 0x1B, 0x05, 0x05, 0x01, 0x00, 0x01, 0x7F, 0x00, 0x70, + 0x00, 0x00, 0x1B, 0x05, 0x02, 0x32, 0x1D, 0x2A, 0x73, 0x00, 0x00, 0x22, + 0x1B, 0x01, 0x00, 0x13, 0x06, 0x01, 0x00, 0x1A, 0x16, 0x04, 0x74, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x00, 0x01, 0x15, 0x00, 0x00, + 0x01, 0x1F, 0x00, 0x00, 0x01, 0x29, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, + 0x7B, 0x1A, 0x00, 0x00, 0x1B, 0x06, 0x07, 0x7C, 0x1B, 0x06, 0x01, 0x16, + 0x04, 0x76, 0x00, 0x00, 0x01, 0x00, 0x20, 0x21, 0x0B, 0x2B, 0x00 +}; + +static const uint16_t t0_caddr[] = { + 0, + 5, + 10, + 15, + 20, + 24, + 28, + 32, + 36, + 40, + 44, + 48, + 52, + 56, + 60, + 64, + 68, + 72, + 76, + 80, + 84, + 88, + 93, + 98, + 103, + 111, + 116, + 121, + 126, + 131, + 136, + 141, + 146, + 151, + 156, + 161, + 166, + 181, + 187, + 193, + 198, + 206, + 214, + 220, + 231, + 246, + 250, + 255, + 260, + 265, + 270, + 275, + 279, + 289, + 620, + 625, + 639, + 659, + 666, + 678, + 692, + 707, + 740, + 960, + 974, + 991, + 1000, + 1067, + 1123, + 1127, + 1131, + 1136, + 1184, + 1210, + 1254, + 1265, + 1274, + 1287, + 1291, + 1295, + 1299, + 1303, + 1307, + 1311, + 1315, + 1327 +}; + +#define T0_INTERPRETED 39 + +#define T0_ENTER(ip, rp, slot) do { \ + const unsigned char *t0_newip; \ + uint32_t t0_lnum; \ + t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ + t0_lnum = t0_parse7E_unsigned(&t0_newip); \ + (rp) += t0_lnum; \ + *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ + (ip) = t0_newip; \ + } while (0) + +#define T0_DEFENTRY(name, slot) \ +void \ +name(void *ctx) \ +{ \ + t0_context *t0ctx = ctx; \ + t0ctx->ip = &t0_codeblock[0]; \ + T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ +} + +T0_DEFENTRY(br_x509_decoder_init_main, 92) + +#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) + +void +br_x509_decoder_run(void *t0ctx) +{ + uint32_t *dp, *rp; + const unsigned char *ip; + +#define T0_LOCAL(x) (*(rp - 2 - (x))) +#define T0_POP() (*-- dp) +#define T0_POPi() (*(int32_t *)(-- dp)) +#define T0_PEEK(x) (*(dp - 1 - (x))) +#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) +#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) +#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) +#define T0_RPOP() (*-- rp) +#define T0_RPOPi() (*(int32_t *)(-- rp)) +#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) +#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) +#define T0_ROLL(x) do { \ + size_t t0len = (size_t)(x); \ + uint32_t t0tmp = *(dp - 1 - t0len); \ + memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_SWAP() do { \ + uint32_t t0tmp = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_ROT() do { \ + uint32_t t0tmp = *(dp - 3); \ + *(dp - 3) = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_NROT() do { \ + uint32_t t0tmp = *(dp - 1); \ + *(dp - 1) = *(dp - 2); \ + *(dp - 2) = *(dp - 3); \ + *(dp - 3) = t0tmp; \ +} while (0) +#define T0_PICK(x) do { \ + uint32_t t0depth = (x); \ + T0_PUSH(T0_PEEK(t0depth)); \ +} while (0) +#define T0_CO() do { \ + goto t0_exit; \ +} while (0) +#define T0_RET() goto t0_next + + dp = ((t0_context *)t0ctx)->dp; + rp = ((t0_context *)t0ctx)->rp; + ip = ((t0_context *)t0ctx)->ip; + goto t0_next; + for (;;) { + uint32_t t0x; + + t0_next: + t0x = T0_NEXT(&ip); + if (t0x < T0_INTERPRETED) { + switch (t0x) { + int32_t t0off; + + case 0: /* ret */ + t0x = T0_RPOP(); + rp -= (t0x >> 16); + t0x &= 0xFFFF; + if (t0x == 0) { + ip = NULL; + goto t0_exit; + } + ip = &t0_codeblock[t0x]; + break; + case 1: /* literal constant */ + T0_PUSHi(t0_parse7E_signed(&ip)); + break; + case 2: /* read local */ + T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); + break; + case 3: /* write local */ + T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); + break; + case 4: /* jump */ + t0off = t0_parse7E_signed(&ip); + ip += t0off; + break; + case 5: /* jump if */ + t0off = t0_parse7E_signed(&ip); + if (T0_POP()) { + ip += t0off; + } + break; + case 6: /* jump if not */ + t0off = t0_parse7E_signed(&ip); + if (!T0_POP()) { + ip += t0off; + } + break; + case 7: { + /* %25 */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSHi(a % b); + + } + break; + case 8: { + /* * */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a * b); + + } + break; + case 9: { + /* + */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a + b); + + } + break; + case 10: { + /* - */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a - b); + + } + break; + case 11: { + /* -rot */ + T0_NROT(); + } + break; + case 12: { + /* / */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSHi(a / b); + + } + break; + case 13: { + /* < */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a < b)); + + } + break; + case 14: { + /* << */ + + int c = (int)T0_POPi(); + uint32_t x = T0_POP(); + T0_PUSH(x << c); + + } + break; + case 15: { + /* <= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a <= b)); + + } + break; + case 16: { + /* <> */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a != b)); + + } + break; + case 17: { + /* = */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a == b)); + + } + break; + case 18: { + /* > */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a > b)); + + } + break; + case 19: { + /* >= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a >= b)); + + } + break; + case 20: { + /* >> */ + + int c = (int)T0_POPi(); + int32_t x = T0_POPi(); + T0_PUSHi(x >> c); + + } + break; + case 21: { + /* and */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a & b); + + } + break; + case 22: { + /* co */ + T0_CO(); + } + break; + case 23: { + /* copy-ec-pkey */ + + size_t qlen = T0_POP(); + uint32_t curve = T0_POP(); + CTX->pkey.key_type = BR_KEYTYPE_EC; + CTX->pkey.key.ec.curve = curve; + CTX->pkey.key.ec.q = CTX->pkey_data; + CTX->pkey.key.ec.qlen = qlen; + + } + break; + case 24: { + /* copy-rsa-pkey */ + + size_t elen = T0_POP(); + size_t nlen = T0_POP(); + CTX->pkey.key_type = BR_KEYTYPE_RSA; + CTX->pkey.key.rsa.n = CTX->pkey_data; + CTX->pkey.key.rsa.nlen = nlen; + CTX->pkey.key.rsa.e = CTX->pkey_data + nlen; + CTX->pkey.key.rsa.elen = elen; + + } + break; + case 25: { + /* data-get8 */ + + size_t addr = T0_POP(); + T0_PUSH(t0_datablock[addr]); + + } + break; + case 26: { + /* drop */ + (void)T0_POP(); + } + break; + case 27: { + /* dup */ + T0_PUSH(T0_PEEK(0)); + } + break; + case 28: { + /* eqOID */ + + const unsigned char *a2 = &t0_datablock[T0_POP()]; + const unsigned char *a1 = &CTX->pad[0]; + size_t len = a1[0]; + int x; + if (len == a2[0]) { + x = -(memcmp(a1 + 1, a2 + 1, len) == 0); + } else { + x = 0; + } + T0_PUSH((uint32_t)x); + + } + break; + case 29: { + /* fail */ + + CTX->err = T0_POPi(); + T0_CO(); + + } + break; + case 30: { + /* neg */ + + uint32_t a = T0_POP(); + T0_PUSH(-a); + + } + break; + case 31: { + /* or */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a | b); + + } + break; + case 32: { + /* over */ + T0_PUSH(T0_PEEK(1)); + } + break; + case 33: { + /* read-blob-inner */ + + uint32_t len = T0_POP(); + uint32_t addr = T0_POP(); + size_t clen = CTX->hlen; + if (clen > len) { + clen = (size_t)len; + } + if (addr != 0) { + memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); + } + if (CTX->copy_dn && CTX->append_dn) { + CTX->append_dn(CTX->append_dn_ctx, CTX->hbuf, clen); + } + CTX->hbuf += clen; + CTX->hlen -= clen; + T0_PUSH(addr + clen); + T0_PUSH(len - clen); + + } + break; + case 34: { + /* read8-low */ + + if (CTX->hlen == 0) { + T0_PUSHi(-1); + } else { + unsigned char x = *CTX->hbuf ++; + if (CTX->copy_dn && CTX->append_dn) { + CTX->append_dn(CTX->append_dn_ctx, &x, 1); + } + CTX->hlen --; + T0_PUSH(x); + } + + } + break; + case 35: { + /* rot */ + T0_ROT(); + } + break; + case 36: { + /* set32 */ + + uint32_t addr = T0_POP(); + *(uint32_t *)(void *)((unsigned char *)CTX + addr) = T0_POP(); + + } + break; + case 37: { + /* set8 */ + + uint32_t addr = T0_POP(); + *((unsigned char *)CTX + addr) = (unsigned char)T0_POP(); + + } + break; + case 38: { + /* swap */ + T0_SWAP(); + } + break; + } + + } else { + T0_ENTER(ip, rp, t0x); + } + } +t0_exit: + ((t0_context *)t0ctx)->dp = dp; + ((t0_context *)t0ctx)->rp = rp; + ((t0_context *)t0ctx)->ip = ip; +} diff --git a/BearSSL-OG/libbearssl/src/x509/x509_decoder.t0 b/BearSSL-OG/libbearssl/src/x509/x509_decoder.t0 new file mode 100644 index 0000000..0bf276f --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/x509_decoder.t0 @@ -0,0 +1,321 @@ +\ Copyright (c) 2016 Thomas Pornin +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +\ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +\ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +\ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +\ SOFTWARE. + +preamble { + +#include "inner.h" + +#define CTX ((br_x509_decoder_context *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_decoder_context, cpu))) +#define CONTEXT_NAME br_x509_decoder_context + +/* see bearssl_x509.h */ +void +br_x509_decoder_init(br_x509_decoder_context *ctx, + void (*append_dn)(void *ctx, const void *buf, size_t len), + void *append_dn_ctx) +{ + memset(ctx, 0, sizeof *ctx); + /* obsolete + ctx->err = 0; + ctx->hbuf = NULL; + ctx->hlen = 0; + */ + ctx->append_dn = append_dn; + ctx->append_dn_ctx = append_dn_ctx; + ctx->cpu.dp = &ctx->dp_stack[0]; + ctx->cpu.rp = &ctx->rp_stack[0]; + br_x509_decoder_init_main(&ctx->cpu); + br_x509_decoder_run(&ctx->cpu); +} + +/* see bearssl_x509.h */ +void +br_x509_decoder_push(br_x509_decoder_context *ctx, + const void *data, size_t len) +{ + ctx->hbuf = data; + ctx->hlen = len; + br_x509_decoder_run(&ctx->cpu); +} + +} + +addr: decoded +addr: notbefore_days +addr: notbefore_seconds +addr: notafter_days +addr: notafter_seconds +addr: isCA +addr: copy_dn +addr: signer_key_type +addr: signer_hash_id + +cc: read8-low ( -- x ) { + if (CTX->hlen == 0) { + T0_PUSHi(-1); + } else { + unsigned char x = *CTX->hbuf ++; + if (CTX->copy_dn && CTX->append_dn) { + CTX->append_dn(CTX->append_dn_ctx, &x, 1); + } + CTX->hlen --; + T0_PUSH(x); + } +} + +cc: read-blob-inner ( addr len -- addr len ) { + uint32_t len = T0_POP(); + uint32_t addr = T0_POP(); + size_t clen = CTX->hlen; + if (clen > len) { + clen = (size_t)len; + } + if (addr != 0) { + memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); + } + if (CTX->copy_dn && CTX->append_dn) { + CTX->append_dn(CTX->append_dn_ctx, CTX->hbuf, clen); + } + CTX->hbuf += clen; + CTX->hlen -= clen; + T0_PUSH(addr + clen); + T0_PUSH(len - clen); +} + +\ Get the address and length for the pkey_data buffer. +: addr-len-pkey_data ( -- addr len ) + CX 0 8191 { offsetof(br_x509_decoder_context, pkey_data) } + CX 0 8191 { BR_X509_BUFSIZE_KEY } ; + +\ Copy the public key (RSA) to the permanent buffer. +cc: copy-rsa-pkey ( nlen elen -- ) { + size_t elen = T0_POP(); + size_t nlen = T0_POP(); + CTX->pkey.key_type = BR_KEYTYPE_RSA; + CTX->pkey.key.rsa.n = CTX->pkey_data; + CTX->pkey.key.rsa.nlen = nlen; + CTX->pkey.key.rsa.e = CTX->pkey_data + nlen; + CTX->pkey.key.rsa.elen = elen; +} + +\ Copy the public key (EC) to the permanent buffer. +cc: copy-ec-pkey ( curve qlen -- ) { + size_t qlen = T0_POP(); + uint32_t curve = T0_POP(); + CTX->pkey.key_type = BR_KEYTYPE_EC; + CTX->pkey.key.ec.curve = curve; + CTX->pkey.key.ec.q = CTX->pkey_data; + CTX->pkey.key.ec.qlen = qlen; +} + +\ Extensions with specific processing. +OID: basicConstraints 2.5.29.19 + +\ Process a Basic Constraints extension. We want the "CA" flag only. +: process-basicConstraints ( lim -- lim ) + read-sequence-open + read-tag-or-end dup 0x01 = if + read-boolean 1 and addr-isCA set8 + else + 2drop + then + skip-close-elt + ; + +\ Decode a certificate. +: main ( -- ! ) + + \ Initialise state flags. + 0 addr-decoded set8 + 0 addr-copy_dn set8 + + \ An arbitrary limit for the total certificate size. + 0xFFFFFF + + \ Open the outer SEQUENCE. + read-sequence-open + + \ TBS + read-sequence-open + + \ First element may be an explicit version. We accept only + \ versions 0 to 2 (certificates v1 to v3). + read-tag dup 0x20 = if + drop check-constructed read-length-open-elt + read-tag + 0x02 check-tag-primitive + read-small-int-value + 2 > if ERR_X509_UNSUPPORTED fail then + close-elt + read-tag + then + + \ Serial number. We just check that the tag is correct. + 0x02 check-tag-primitive read-length-skip + + \ Signature algorithm. + read-sequence-open skip-close-elt + + \ Issuer name. + read-sequence-open skip-close-elt + + \ Validity dates. + read-sequence-open + read-date addr-notbefore_seconds set32 addr-notbefore_days set32 + read-date addr-notafter_seconds set32 addr-notafter_days set32 + close-elt + + \ Subject name. + 1 addr-copy_dn set8 + read-sequence-open skip-close-elt + 0 addr-copy_dn set8 + + \ Public Key. + read-sequence-open + \ Algorithm Identifier. Right now we are only interested in the + \ OID, since we only support RSA keys. + \ TODO: support EC keys + read-sequence-open + read-OID ifnot ERR_X509_UNSUPPORTED fail then + choice + \ RSA public key. + rsaEncryption eqOID uf + skip-close-elt + \ Public key itself: the BIT STRING contains bytes + \ (no partial byte) and these bytes encode the + \ actual value. + read-bits-open + \ RSA public key is a SEQUENCE of two + \ INTEGER. We get both INTEGER values into + \ the pkey_data[] buffer, if they fit. + read-sequence-open + addr-len-pkey_data + read-integer { nlen } + addr-len-pkey_data swap nlen + swap nlen - + read-integer { elen } + close-elt + close-elt + nlen elen copy-rsa-pkey + enduf + + \ EC public key. + id-ecPublicKey eqOID uf + \ We support only named curves, for which the + \ "parameters" field in the AlgorithmIdentifier + \ field should be an OID. + read-curve-ID { curve } + close-elt + read-bits-open + dup { qlen } + dup addr-len-pkey_data rot < if + ERR_X509_LIMIT_EXCEEDED fail + then + read-blob + curve qlen copy-ec-pkey + enduf + ERR_X509_UNSUPPORTED fail + endchoice + close-elt + + \ This flag will be set to true if the Basic Constraints extension + \ is encountered. + 0 addr-isCA set8 + + \ Skip issuerUniqueID and subjectUniqueID, and process extensions + \ if present. Extensions are an explicit context tag of value 3 + \ around a SEQUENCE OF extensions. Each extension is a SEQUENCE + \ with an OID, an optional boolean, and a value; the value is + \ an OCTET STRING. + read-tag-or-end + 0x21 iftag-skip + 0x22 iftag-skip + dup 0x23 = if + drop + check-constructed read-length-open-elt + read-sequence-open + begin dup while + read-sequence-open + read-OID drop + read-tag dup 0x01 = if + read-boolean drop + read-tag + then + 0x04 check-tag-primitive read-length-open-elt + choice + \ Extensions with specific processing. + basicConstraints eqOID uf + process-basicConstraints + enduf + skip-remaining + endchoice + close-elt + close-elt + repeat + close-elt + close-elt + else + -1 = ifnot ERR_X509_UNEXPECTED fail then + drop + then + + close-elt + + \ signature algorithm + read-sequence-open + read-OID if + choice + sha1WithRSAEncryption eqOID uf 2 KEYTYPE_RSA enduf + sha224WithRSAEncryption eqOID uf 3 KEYTYPE_RSA enduf + sha256WithRSAEncryption eqOID uf 4 KEYTYPE_RSA enduf + sha384WithRSAEncryption eqOID uf 5 KEYTYPE_RSA enduf + sha512WithRSAEncryption eqOID uf 6 KEYTYPE_RSA enduf + + ecdsa-with-SHA1 eqOID uf 2 KEYTYPE_EC enduf + ecdsa-with-SHA224 eqOID uf 3 KEYTYPE_EC enduf + ecdsa-with-SHA256 eqOID uf 4 KEYTYPE_EC enduf + ecdsa-with-SHA384 eqOID uf 5 KEYTYPE_EC enduf + ecdsa-with-SHA512 eqOID uf 6 KEYTYPE_EC enduf + + 0 0 + endchoice + else + 0 0 + then + addr-signer_key_type set8 + addr-signer_hash_id set8 + skip-close-elt + \ read-sequence-open skip-close-elt + + \ signature value + read-bits-open skip-close-elt + + \ Close the outer SEQUENCE. + close-elt + drop + + \ Mark the decoding as successful. + 1 addr-decoded set8 + + \ Read one byte, then fail: if the read succeeds, then there is + \ some trailing byte. + read8-nc ERR_X509_EXTRA_ELEMENT fail + ; diff --git a/BearSSL-OG/libbearssl/src/x509/x509_knownkey.c b/BearSSL-OG/libbearssl/src/x509/x509_knownkey.c new file mode 100644 index 0000000..7674f3f --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/x509_knownkey.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_x509.h */ +void +br_x509_knownkey_init_rsa(br_x509_knownkey_context *ctx, + const br_rsa_public_key *pk, unsigned usages) +{ + ctx->vtable = &br_x509_knownkey_vtable; + ctx->pkey.key_type = BR_KEYTYPE_RSA; + ctx->pkey.key.rsa = *pk; + ctx->usages = usages; +} + +/* see bearssl_x509.h */ +void +br_x509_knownkey_init_ec(br_x509_knownkey_context *ctx, + const br_ec_public_key *pk, unsigned usages) +{ + ctx->vtable = &br_x509_knownkey_vtable; + ctx->pkey.key_type = BR_KEYTYPE_EC; + ctx->pkey.key.ec = *pk; + ctx->usages = usages; +} + +static void +kk_start_chain(const br_x509_class **ctx, const char *server_name) +{ + (void)ctx; + (void)server_name; +} + +static void +kk_start_cert(const br_x509_class **ctx, uint32_t length) +{ + (void)ctx; + (void)length; +} + +static void +kk_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) +{ + (void)ctx; + (void)buf; + (void)len; +} + +static void +kk_end_cert(const br_x509_class **ctx) +{ + (void)ctx; +} + +static unsigned +kk_end_chain(const br_x509_class **ctx) +{ + (void)ctx; + return 0; +} + +static const br_x509_pkey * +kk_get_pkey(const br_x509_class *const *ctx, unsigned *usages) +{ + const br_x509_knownkey_context *xc; + + xc = (const br_x509_knownkey_context *)ctx; + if (usages != NULL) { + *usages = xc->usages; + } + return &xc->pkey; +} + +/* see bearssl_x509.h */ +const br_x509_class br_x509_knownkey_vtable = { + sizeof(br_x509_knownkey_context), + kk_start_chain, + kk_start_cert, + kk_append, + kk_end_cert, + kk_end_chain, + kk_get_pkey +}; diff --git a/BearSSL-OG/libbearssl/src/x509/x509_minimal.c b/BearSSL-OG/libbearssl/src/x509/x509_minimal.c new file mode 100644 index 0000000..83d8af9 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/x509_minimal.c @@ -0,0 +1,1745 @@ +/* Automatically generated code; do not modify directly. */ + +#include +#include + +typedef struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; +} t0_context; + +static uint32_t +t0_parse7E_unsigned(const unsigned char **p) +{ + uint32_t x; + + x = 0; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + return x; + } + } +} + +static int32_t +t0_parse7E_signed(const unsigned char **p) +{ + int neg; + uint32_t x; + + neg = ((**p) >> 6) & 1; + x = (uint32_t)-neg; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + if (neg) { + return -(int32_t)~x - 1; + } else { + return (int32_t)x; + } + } + } +} + +#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) +#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) +#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) +#define T0_INT1(x) T0_FBYTE(x, 0) +#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) + +/* static const unsigned char t0_datablock[]; */ + + +void br_x509_minimal_init_main(void *t0ctx); + +void br_x509_minimal_run(void *t0ctx); + + + +#include "inner.h" + + + + + +#include "inner.h" + +/* + * Implementation Notes + * -------------------- + * + * The C code pushes the data by chunks; all decoding is done in the + * T0 code. The cert_length value is set to the certificate length when + * a new certificate is started; the T0 code picks it up as outer limit, + * and decoding functions use it to ensure that no attempt is made at + * reading past it. The T0 code also checks that once the certificate is + * decoded, there are no trailing bytes. + * + * The T0 code sets cert_length to 0 when the certificate is fully + * decoded. + * + * The C code must still perform two checks: + * + * -- If the certificate length is 0, then the T0 code will not be + * invoked at all. This invalid condition must thus be reported by the + * C code. + * + * -- When reaching the end of certificate, the C code must verify that + * the certificate length has been set to 0, thereby signaling that + * the T0 code properly decoded a certificate. + * + * Processing of a chain works in the following way: + * + * -- The error flag is set to a non-zero value when validation is + * finished. The value is either BR_ERR_X509_OK (validation is + * successful) or another non-zero error code. When a non-zero error + * code is obtained, the remaining bytes in the current certificate and + * the subsequent certificates (if any) are completely ignored. + * + * -- Each certificate is decoded in due course, with the following + * "interesting points": + * + * -- Start of the TBS: the multihash engine is reset and activated. + * + * -- Start of the issuer DN: the secondary hash engine is started, + * to process the encoded issuer DN. + * + * -- End of the issuer DN: the secondary hash engine is stopped. The + * resulting hash value is computed and then copied into the + * next_dn_hash[] buffer. + * + * -- Start of the subject DN: the secondary hash engine is started, + * to process the encoded subject DN. + * + * -- For the EE certificate only: the Common Name, if any, is matched + * against the expected server name. + * + * -- End of the subject DN: the secondary hash engine is stopped. The + * resulting hash value is computed into the pad. It is then processed: + * + * -- If this is the EE certificate, then the hash is ignored + * (except for direct trust processing, see later; the hash is + * simply left in current_dn_hash[]). + * + * -- Otherwise, the hashed subject DN is compared with the saved + * hash value (in saved_dn_hash[]). They must match. + * + * Either way, the next_dn_hash[] value is then copied into the + * saved_dn_hash[] value. Thus, at that point, saved_dn_hash[] + * contains the hash of the issuer DN for the current certificate, + * and current_dn_hash[] contains the hash of the subject DN for the + * current certificate. + * + * -- Public key: it is decoded into the cert_pkey[] buffer. Unknown + * key types are reported at that point. + * + * -- If this is the EE certificate, then the key type is compared + * with the expected key type (initialization parameter). The public + * key data is copied to ee_pkey_data[]. The key and hashed subject + * DN are also compared with the "direct trust" keys; if the key + * and DN are matched, then validation ends with a success. + * + * -- Otherwise, the saved signature (cert_sig[]) is verified + * against the saved TBS hash (tbs_hash[]) and that freshly + * decoded public key. Failure here ends validation with an error. + * + * -- Extensions: extension values are processed in due order. + * + * -- Basic Constraints: for all certificates except EE, must be + * present, indicate a CA, and have a path length compatible with + * the chain length so far. + * + * -- Key Usage: for the EE, if present, must allow signatures + * or encryption/key exchange, as required for the cipher suite. + * For non-EE, if present, must have the "certificate sign" bit. + * + * -- Subject Alt Name: for the EE, dNSName names are matched + * against the server name. Ignored for non-EE. + * + * -- Authority Key Identifier, Subject Key Identifier, Issuer + * Alt Name, Subject Directory Attributes, CRL Distribution Points + * Freshest CRL, Authority Info Access and Subject Info Access + * extensions are always ignored: they either contain only + * informative data, or they relate to revocation processing, which + * we explicitly do not support. + * + * -- All other extensions are ignored if non-critical. If a + * critical extension other than the ones above is encountered, + * then a failure is reported. + * + * -- End of the TBS: the multihash engine is stopped. + * + * -- Signature algorithm: the signature algorithm on the + * certificate is decoded. A failure is reported if that algorithm + * is unknown. The hashed TBS corresponding to the signature hash + * function is computed and stored in tbs_hash[] (if not supported, + * then a failure is reported). The hash OID and length are stored + * in cert_sig_hash_oid and cert_sig_hash_len. + * + * -- Signature value: the signature value is copied into the + * cert_sig[] array. + * + * -- Certificate end: the hashed issuer DN (saved_dn_hash[]) is + * looked up in the trust store (CA trust anchors only); for all + * that match, the signature (cert_sig[]) is verified against the + * anchor public key (hashed TBS is in tbs_hash[]). If one of these + * signatures is valid, then validation ends with a success. + * + * -- If the chain end is reached without obtaining a validation success, + * then validation is reported as failed. + */ + +#if BR_USE_UNIX_TIME +#include +#endif + +#if BR_USE_WIN32_TIME +#ifdef _XBOX +#include +/* + * KeQuerySystemTime is exported by the Xbox kernel (xboxkrnl.lib). + * It returns the current system time in 100-nanosecond intervals + * since January 1, 1601 (same format as FILETIME). + */ +#ifdef __cplusplus +extern "C" +#endif +void WINAPI KeQuerySystemTime(PLARGE_INTEGER CurrentTime); +#else +#include +#endif +#endif + +/* + * The T0 compiler will produce these prototypes declarations in the + * header. + * +void br_x509_minimal_init_main(void *ctx); +void br_x509_minimal_run(void *ctx); + */ + +/* see bearssl_x509.h */ +void +br_x509_minimal_init(br_x509_minimal_context *ctx, + const br_hash_class *dn_hash_impl, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) +{ + memset(ctx, 0, sizeof *ctx); + ctx->vtable = &br_x509_minimal_vtable; + ctx->dn_hash_impl = dn_hash_impl; + ctx->trust_anchors = trust_anchors; + ctx->trust_anchors_num = trust_anchors_num; +} + +static void +xm_start_chain(const br_x509_class **ctx, const char *server_name) +{ + br_x509_minimal_context *cc; + size_t u; + + cc = (br_x509_minimal_context *)(void *)ctx; + for (u = 0; u < cc->num_name_elts; u ++) { + cc->name_elts[u].status = 0; + cc->name_elts[u].buf[0] = 0; + } + memset(&cc->pkey, 0, sizeof cc->pkey); + cc->num_certs = 0; + cc->err = 0; + cc->cpu.dp = cc->dp_stack; + cc->cpu.rp = cc->rp_stack; + br_x509_minimal_init_main(&cc->cpu); + if (server_name == NULL || *server_name == 0) { + cc->server_name = NULL; + } else { + cc->server_name = server_name; + } +} + +static void +xm_start_cert(const br_x509_class **ctx, uint32_t length) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err != 0) { + return; + } + if (length == 0) { + cc->err = BR_ERR_X509_TRUNCATED; + return; + } + cc->cert_length = length; +} + +static void +xm_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err != 0) { + return; + } + cc->hbuf = buf; + cc->hlen = len; + br_x509_minimal_run(&cc->cpu); +} + +static void +xm_end_cert(const br_x509_class **ctx) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err == 0 && cc->cert_length != 0) { + cc->err = BR_ERR_X509_TRUNCATED; + } + cc->num_certs ++; +} + +static unsigned +xm_end_chain(const br_x509_class **ctx) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err == 0) { + if (cc->num_certs == 0) { + cc->err = BR_ERR_X509_EMPTY_CHAIN; + } else { + cc->err = BR_ERR_X509_NOT_TRUSTED; + } + } else if (cc->err == BR_ERR_X509_OK) { + return 0; + } + return (unsigned)cc->err; +} + +static const br_x509_pkey * +xm_get_pkey(const br_x509_class *const *ctx, unsigned *usages) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err == BR_ERR_X509_OK + || cc->err == BR_ERR_X509_NOT_TRUSTED) + { + if (usages != NULL) { + *usages = cc->key_usages; + } + return &((br_x509_minimal_context *)(void *)ctx)->pkey; + } else { + return NULL; + } +} + +/* see bearssl_x509.h */ +const br_x509_class br_x509_minimal_vtable = { + sizeof(br_x509_minimal_context), + xm_start_chain, + xm_start_cert, + xm_append, + xm_end_cert, + xm_end_chain, + xm_get_pkey +}; + +#define CTX ((br_x509_minimal_context *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_minimal_context, cpu))) +#define CONTEXT_NAME br_x509_minimal_context + +#define DNHASH_LEN ((CTX->dn_hash_impl->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK) + +/* + * Hash a DN (from a trust anchor) into the provided buffer. This uses the + * DN hash implementation and context structure from the X.509 engine + * context. + */ +static void +hash_dn(br_x509_minimal_context *ctx, const void *dn, size_t len, + unsigned char *out) +{ + ctx->dn_hash_impl->init(&ctx->dn_hash.vtable); + ctx->dn_hash_impl->update(&ctx->dn_hash.vtable, dn, len); + ctx->dn_hash_impl->out(&ctx->dn_hash.vtable, out); +} + +/* + * Compare two big integers for equality. The integers use unsigned big-endian + * encoding; extra leading bytes (of value 0) are allowed. + */ +static int +eqbigint(const unsigned char *b1, size_t len1, + const unsigned char *b2, size_t len2) +{ + while (len1 > 0 && *b1 == 0) { + b1 ++; + len1 --; + } + while (len2 > 0 && *b2 == 0) { + b2 ++; + len2 --; + } + if (len1 != len2) { + return 0; + } + return memcmp(b1, b2, len1) == 0; +} + +/* + * Compare two strings for equality, in a case-insensitive way. This + * function handles casing only for ASCII letters. + */ +static int +eqnocase(const void *s1, const void *s2, size_t len) +{ + const unsigned char *buf1, *buf2; + + buf1 = s1; + buf2 = s2; + while (len -- > 0) { + int x1, x2; + + x1 = *buf1 ++; + x2 = *buf2 ++; + if (x1 >= 'A' && x1 <= 'Z') { + x1 += 'a' - 'A'; + } + if (x2 >= 'A' && x2 <= 'Z') { + x2 += 'a' - 'A'; + } + if (x1 != x2) { + return 0; + } + } + return 1; +} + +static int verify_signature(br_x509_minimal_context *ctx, + const br_x509_pkey *pk); + + + +static const unsigned char t0_datablock[] = { + 0x00, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x01, 0x0C, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, + 0x0D, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x04, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x02, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x07, + 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x08, 0x2A, 0x86, 0x48, 0xCE, + 0x3D, 0x03, 0x01, 0x07, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x05, 0x2B, + 0x81, 0x04, 0x00, 0x23, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x01, + 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01, 0x08, 0x2A, 0x86, + 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, + 0x04, 0x03, 0x03, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04, + 0x03, 0x55, 0x04, 0x03, 0x00, 0x1F, 0x03, 0xFC, 0x07, 0x7F, 0x0B, 0x5E, + 0x0F, 0x1F, 0x12, 0xFE, 0x16, 0xBF, 0x1A, 0x9F, 0x1E, 0x7E, 0x22, 0x3F, + 0x26, 0x1E, 0x29, 0xDF, 0x00, 0x1F, 0x03, 0xFD, 0x07, 0x9F, 0x0B, 0x7E, + 0x0F, 0x3F, 0x13, 0x1E, 0x16, 0xDF, 0x1A, 0xBF, 0x1E, 0x9E, 0x22, 0x5F, + 0x26, 0x3E, 0x29, 0xFF, 0x03, 0x55, 0x1D, 0x13, 0x03, 0x55, 0x1D, 0x0F, + 0x03, 0x55, 0x1D, 0x11, 0x03, 0x55, 0x1D, 0x20, 0x08, 0x2B, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x02, 0x01, 0x03, 0x55, 0x1D, 0x23, 0x03, 0x55, 0x1D, + 0x0E, 0x03, 0x55, 0x1D, 0x12, 0x03, 0x55, 0x1D, 0x09, 0x03, 0x55, 0x1D, + 0x1F, 0x03, 0x55, 0x1D, 0x2E, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x01, 0x01, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0B +}; + +static const unsigned char t0_codeblock[] = { + 0x00, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, + 0x00, 0x11, 0x00, 0x00, 0x01, 0x01, 0x09, 0x00, 0x00, 0x01, 0x01, 0x0A, + 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_BAD_BOOLEAN), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_BAD_DN), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_BAD_SERVER_NAME), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_BAD_TAG_CLASS), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_BAD_TAG_VALUE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_BAD_TIME), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_CRITICAL_EXTENSION), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_DN_MISMATCH), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_EXPIRED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_EXTRA_ELEMENT), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_FORBIDDEN_KEY_USAGE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_INDEFINITE_LENGTH), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_INNER_TRUNC), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_NOT_CA), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_NOT_CONSTRUCTED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_NOT_PRIMITIVE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_OVERFLOW), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_PARTIAL_BYTE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_UNEXPECTED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_UNSUPPORTED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_WEAK_PUBLIC_KEY), 0x00, 0x00, 0x01, + T0_INT1(BR_KEYTYPE_EC), 0x00, 0x00, 0x01, T0_INT1(BR_KEYTYPE_RSA), + 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_length)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig_hash_len)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig_hash_oid)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(CONTEXT_NAME, cert_sig_len)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, cert_signer_key_type)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(CONTEXT_NAME, current_dn_hash)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(CONTEXT_NAME, key_usages)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_x509_minimal_context, pkey_data)), 0x01, + T0_INT2(BR_X509_BUFSIZE_KEY), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, min_rsa_size)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, next_dn_hash)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, num_certs)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, pad)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, saved_dn_hash)), 0x00, 0x00, 0x01, 0x80, + 0x73, 0x00, 0x00, 0x01, 0x80, 0x7C, 0x00, 0x00, 0x01, 0x81, 0x02, 0x00, + 0x00, 0x8F, 0x05, 0x05, 0x33, 0x41, 0x01, 0x00, 0x00, 0x33, 0x01, 0x0A, + 0x0E, 0x09, 0x01, 0x9A, 0xFF, 0xB8, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x82, + 0x19, 0x00, 0x00, 0x01, 0x82, 0x01, 0x00, 0x00, 0x01, 0x81, 0x68, 0x00, + 0x02, 0x03, 0x00, 0x03, 0x01, 0x26, 0x02, 0x01, 0x13, 0x3A, 0x02, 0x00, + 0x0F, 0x15, 0x00, 0x00, 0x01, 0x81, 0x74, 0x00, 0x00, 0x05, 0x02, 0x51, + 0x29, 0x00, 0x00, 0x06, 0x02, 0x52, 0x29, 0x00, 0x00, 0x01, 0x10, 0x74, + 0x00, 0x00, 0x11, 0x05, 0x02, 0x55, 0x29, 0x71, 0x00, 0x00, 0x11, 0x05, + 0x02, 0x55, 0x29, 0x72, 0x00, 0x00, 0x06, 0x02, 0x4B, 0x29, 0x00, 0x00, + 0x01, 0x82, 0x11, 0x00, 0x00, 0x26, 0x21, 0x01, 0x08, 0x0E, 0x3A, 0x3F, + 0x21, 0x09, 0x00, 0x0B, 0x03, 0x00, 0x5A, 0x2B, 0xAC, 0x38, 0xAC, 0xB0, + 0x26, 0x01, 0x20, 0x11, 0x06, 0x11, 0x25, 0x71, 0xAA, 0xB0, 0x01, 0x02, + 0x75, 0xAD, 0x01, 0x02, 0x12, 0x06, 0x02, 0x56, 0x29, 0x76, 0xB0, 0x01, + 0x02, 0x75, 0xAB, 0xAC, 0xBF, 0x99, 0x64, 0x60, 0x22, 0x16, 0xAC, 0xA4, + 0x03, 0x01, 0x03, 0x02, 0xA4, 0x02, 0x02, 0x02, 0x01, 0x19, 0x06, 0x02, + 0x4A, 0x29, 0x76, 0x02, 0x00, 0x06, 0x05, 0x9A, 0x03, 0x03, 0x04, 0x09, + 0x99, 0x60, 0x67, 0x22, 0x28, 0x05, 0x02, 0x49, 0x29, 0x67, 0x64, 0x22, + 0x16, 0xAC, 0xAC, 0x9B, 0x05, 0x02, 0x56, 0x29, 0xB9, 0x27, 0x06, 0x27, + 0xBF, 0xA1, 0xAC, 0x62, 0xA7, 0x03, 0x05, 0x62, 0x3A, 0x02, 0x05, 0x09, + 0x3A, 0x02, 0x05, 0x0A, 0xA7, 0x03, 0x06, 0x76, 0x63, 0x2A, 0x01, 0x81, + 0x00, 0x09, 0x02, 0x05, 0x12, 0x06, 0x02, 0x57, 0x29, 0x76, 0x59, 0x03, + 0x04, 0x04, 0x3A, 0x85, 0x27, 0x06, 0x34, 0x9B, 0x05, 0x02, 0x56, 0x29, + 0x68, 0x27, 0x06, 0x04, 0x01, 0x17, 0x04, 0x12, 0x69, 0x27, 0x06, 0x04, + 0x01, 0x18, 0x04, 0x0A, 0x6A, 0x27, 0x06, 0x04, 0x01, 0x19, 0x04, 0x02, + 0x56, 0x29, 0x03, 0x07, 0x76, 0xA1, 0x26, 0x03, 0x08, 0x26, 0x62, 0x33, + 0x0D, 0x06, 0x02, 0x4F, 0x29, 0xA2, 0x58, 0x03, 0x04, 0x04, 0x02, 0x56, + 0x29, 0x76, 0x02, 0x00, 0x06, 0x21, 0x02, 0x04, 0x59, 0x30, 0x11, 0x06, + 0x08, 0x25, 0x02, 0x05, 0x02, 0x06, 0x1E, 0x04, 0x10, 0x58, 0x30, 0x11, + 0x06, 0x08, 0x25, 0x02, 0x07, 0x02, 0x08, 0x1D, 0x04, 0x03, 0x56, 0x29, + 0x25, 0x04, 0x24, 0x02, 0x04, 0x59, 0x30, 0x11, 0x06, 0x08, 0x25, 0x02, + 0x05, 0x02, 0x06, 0x24, 0x04, 0x10, 0x58, 0x30, 0x11, 0x06, 0x08, 0x25, + 0x02, 0x07, 0x02, 0x08, 0x23, 0x04, 0x03, 0x56, 0x29, 0x25, 0x26, 0x06, + 0x01, 0x29, 0x25, 0x01, 0x00, 0x03, 0x09, 0xB1, 0x01, 0x21, 0x8C, 0x01, + 0x22, 0x8C, 0x26, 0x01, 0x23, 0x11, 0x06, 0x81, 0x26, 0x25, 0x71, 0xAA, + 0xAC, 0x26, 0x06, 0x81, 0x1A, 0x01, 0x00, 0x03, 0x0A, 0xAC, 0x9B, 0x25, + 0xB0, 0x26, 0x01, 0x01, 0x11, 0x06, 0x04, 0xA3, 0x03, 0x0A, 0xB0, 0x01, + 0x04, 0x75, 0xAA, 0x6E, 0x27, 0x06, 0x0F, 0x02, 0x00, 0x06, 0x03, 0xC0, + 0x04, 0x05, 0x96, 0x01, 0x7F, 0x03, 0x09, 0x04, 0x80, 0x6C, 0x8E, 0x27, + 0x06, 0x06, 0x02, 0x00, 0x98, 0x04, 0x80, 0x62, 0xC2, 0x27, 0x06, 0x11, + 0x02, 0x00, 0x06, 0x09, 0x01, 0x00, 0x03, 0x03, 0x95, 0x03, 0x03, 0x04, + 0x01, 0xC0, 0x04, 0x80, 0x4D, 0x70, 0x27, 0x06, 0x0A, 0x02, 0x0A, 0x06, + 0x03, 0x97, 0x04, 0x01, 0xC0, 0x04, 0x3F, 0x6D, 0x27, 0x06, 0x03, 0xC0, + 0x04, 0x38, 0xC5, 0x27, 0x06, 0x03, 0xC0, 0x04, 0x31, 0x8D, 0x27, 0x06, + 0x03, 0xC0, 0x04, 0x2A, 0xC3, 0x27, 0x06, 0x03, 0xC0, 0x04, 0x23, 0x77, + 0x27, 0x06, 0x03, 0xC0, 0x04, 0x1C, 0x82, 0x27, 0x06, 0x03, 0xC0, 0x04, + 0x15, 0x6C, 0x27, 0x06, 0x03, 0xC0, 0x04, 0x0E, 0xC4, 0x27, 0x06, 0x03, + 0xC0, 0x04, 0x07, 0x02, 0x0A, 0x06, 0x02, 0x48, 0x29, 0xC0, 0x76, 0x76, + 0x04, 0xFE, 0x62, 0x76, 0x76, 0x04, 0x08, 0x01, 0x7F, 0x11, 0x05, 0x02, + 0x55, 0x29, 0x25, 0x76, 0x39, 0x02, 0x00, 0x06, 0x08, 0x02, 0x03, 0x3B, + 0x2F, 0x05, 0x02, 0x44, 0x29, 0x02, 0x00, 0x06, 0x01, 0x17, 0x02, 0x00, + 0x02, 0x09, 0x2F, 0x05, 0x02, 0x50, 0x29, 0xB0, 0x73, 0xAA, 0x9B, 0x06, + 0x80, 0x77, 0xBA, 0x27, 0x06, 0x07, 0x01, 0x02, 0x59, 0x87, 0x04, 0x80, + 0x5E, 0xBB, 0x27, 0x06, 0x07, 0x01, 0x03, 0x59, 0x88, 0x04, 0x80, 0x53, + 0xBC, 0x27, 0x06, 0x07, 0x01, 0x04, 0x59, 0x89, 0x04, 0x80, 0x48, 0xBD, + 0x27, 0x06, 0x06, 0x01, 0x05, 0x59, 0x8A, 0x04, 0x3E, 0xBE, 0x27, 0x06, + 0x06, 0x01, 0x06, 0x59, 0x8B, 0x04, 0x34, 0x7C, 0x27, 0x06, 0x06, 0x01, + 0x02, 0x58, 0x87, 0x04, 0x2A, 0x7D, 0x27, 0x06, 0x06, 0x01, 0x03, 0x58, + 0x88, 0x04, 0x20, 0x7E, 0x27, 0x06, 0x06, 0x01, 0x04, 0x58, 0x89, 0x04, + 0x16, 0x7F, 0x27, 0x06, 0x06, 0x01, 0x05, 0x58, 0x8A, 0x04, 0x0C, 0x80, + 0x27, 0x06, 0x06, 0x01, 0x06, 0x58, 0x8B, 0x04, 0x02, 0x56, 0x29, 0x5D, + 0x34, 0x5F, 0x36, 0x1C, 0x26, 0x05, 0x02, 0x56, 0x29, 0x5C, 0x36, 0x04, + 0x02, 0x56, 0x29, 0xBF, 0xA1, 0x26, 0x01, T0_INT2(BR_X509_BUFSIZE_SIG), + 0x12, 0x06, 0x02, 0x4F, 0x29, 0x26, 0x5E, 0x34, 0x5B, 0xA2, 0x76, 0x76, + 0x01, 0x00, 0x5A, 0x35, 0x18, 0x00, 0x00, 0x01, 0x30, 0x0A, 0x26, 0x01, + 0x00, 0x01, 0x09, 0x6F, 0x05, 0x02, 0x47, 0x29, 0x00, 0x00, 0x30, 0x30, + 0x00, 0x00, 0x01, 0x81, 0x08, 0x00, 0x00, 0x01, 0x81, 0x10, 0x00, 0x00, + 0x01, 0x81, 0x19, 0x00, 0x00, 0x01, 0x81, 0x22, 0x00, 0x00, 0x01, 0x81, + 0x2B, 0x00, 0x01, 0x7B, 0x01, 0x01, 0x11, 0x3A, 0x01, 0x83, 0xFD, 0x7F, + 0x11, 0x15, 0x06, 0x03, 0x3A, 0x25, 0x00, 0x3A, 0x26, 0x03, 0x00, 0x26, + 0xC6, 0x05, 0x04, 0x41, 0x01, 0x00, 0x00, 0x26, 0x01, 0x81, 0x00, 0x0D, + 0x06, 0x04, 0x93, 0x04, 0x80, 0x49, 0x26, 0x01, 0x90, 0x00, 0x0D, 0x06, + 0x0F, 0x01, 0x06, 0x14, 0x01, 0x81, 0x40, 0x2F, 0x93, 0x02, 0x00, 0x01, + 0x00, 0x94, 0x04, 0x33, 0x26, 0x01, 0x83, 0xFF, 0x7F, 0x0D, 0x06, 0x14, + 0x01, 0x0C, 0x14, 0x01, 0x81, 0x60, 0x2F, 0x93, 0x02, 0x00, 0x01, 0x06, + 0x94, 0x02, 0x00, 0x01, 0x00, 0x94, 0x04, 0x17, 0x01, 0x12, 0x14, 0x01, + 0x81, 0x70, 0x2F, 0x93, 0x02, 0x00, 0x01, 0x0C, 0x94, 0x02, 0x00, 0x01, + 0x06, 0x94, 0x02, 0x00, 0x01, 0x00, 0x94, 0x00, 0x00, 0x01, 0x82, 0x15, + 0x00, 0x00, 0x26, 0x01, 0x83, 0xB0, 0x00, 0x01, 0x83, 0xB7, 0x7F, 0x6F, + 0x00, 0x00, 0x01, 0x81, 0x34, 0x00, 0x00, 0x01, 0x80, 0x6B, 0x00, 0x00, + 0x01, 0x81, 0x78, 0x00, 0x00, 0x01, 0x3D, 0x00, 0x00, 0x01, 0x80, 0x43, + 0x00, 0x00, 0x01, 0x80, 0x4D, 0x00, 0x00, 0x01, 0x80, 0x57, 0x00, 0x00, + 0x01, 0x80, 0x61, 0x00, 0x00, 0x30, 0x11, 0x06, 0x04, 0x41, 0xAA, 0xBF, + 0xB1, 0x00, 0x00, 0x01, 0x82, 0x09, 0x00, 0x00, 0x01, 0x81, 0x6C, 0x00, + 0x00, 0x26, 0x01, 0x83, 0xB8, 0x00, 0x01, 0x83, 0xBF, 0x7F, 0x6F, 0x00, + 0x00, 0x01, 0x30, 0x61, 0x36, 0x01, 0x7F, 0x79, 0x1A, 0x01, 0x00, 0x79, + 0x1A, 0x04, 0x7A, 0x00, 0x01, 0x81, 0x38, 0x00, 0x01, 0x7B, 0x0D, 0x06, + 0x02, 0x4E, 0x29, 0x26, 0x03, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x00, 0x30, + 0x26, 0x3E, 0x3A, 0x01, 0x82, 0x00, 0x13, 0x2F, 0x06, 0x04, 0x41, 0x01, + 0x00, 0x00, 0x30, 0x66, 0x09, 0x36, 0x3F, 0x00, 0x00, 0x14, 0x01, 0x3F, + 0x15, 0x01, 0x81, 0x00, 0x2F, 0x93, 0x00, 0x02, 0x01, 0x00, 0x03, 0x00, + 0xAC, 0x26, 0x06, 0x80, 0x59, 0xB0, 0x01, 0x20, 0x30, 0x11, 0x06, 0x17, + 0x25, 0x71, 0xAA, 0x9B, 0x25, 0x01, 0x7F, 0x2E, 0x03, 0x01, 0xB0, 0x01, + 0x20, 0x74, 0xAA, 0xAF, 0x02, 0x01, 0x20, 0x76, 0x76, 0x04, 0x38, 0x01, + 0x21, 0x30, 0x11, 0x06, 0x08, 0x25, 0x72, 0xB3, 0x01, 0x01, 0x1F, 0x04, + 0x2A, 0x01, 0x22, 0x30, 0x11, 0x06, 0x11, 0x25, 0x72, 0xB3, 0x26, 0x06, + 0x06, 0x2C, 0x02, 0x00, 0x2F, 0x03, 0x00, 0x01, 0x02, 0x1F, 0x04, 0x13, + 0x01, 0x26, 0x30, 0x11, 0x06, 0x08, 0x25, 0x72, 0xB3, 0x01, 0x06, 0x1F, + 0x04, 0x05, 0x41, 0xAB, 0x01, 0x00, 0x25, 0x04, 0xFF, 0x23, 0x76, 0x02, + 0x00, 0x00, 0x00, 0xAC, 0xB1, 0x26, 0x01, 0x01, 0x11, 0x06, 0x08, 0xA3, + 0x05, 0x02, 0x50, 0x29, 0xB1, 0x04, 0x02, 0x50, 0x29, 0x26, 0x01, 0x02, + 0x11, 0x06, 0x0C, 0x25, 0x72, 0xAD, 0x65, 0x2B, 0x40, 0x0D, 0x06, 0x02, + 0x50, 0x29, 0xB1, 0x01, 0x7F, 0x10, 0x06, 0x02, 0x55, 0x29, 0x25, 0x76, + 0x00, 0x00, 0xAC, 0x26, 0x06, 0x1A, 0xAC, 0x9B, 0x25, 0x26, 0x06, 0x11, + 0xAC, 0x26, 0x06, 0x0C, 0xAC, 0x9B, 0x25, 0x86, 0x27, 0x05, 0x02, 0x48, + 0x29, 0xBF, 0x04, 0x71, 0x76, 0x76, 0x04, 0x63, 0x76, 0x00, 0x02, 0x03, + 0x00, 0xB0, 0x01, 0x03, 0x75, 0xAA, 0xB7, 0x03, 0x01, 0x02, 0x01, 0x01, + 0x07, 0x12, 0x06, 0x02, 0x55, 0x29, 0x26, 0x01, 0x00, 0x30, 0x11, 0x06, + 0x05, 0x25, 0x4C, 0x29, 0x04, 0x15, 0x01, 0x01, 0x30, 0x11, 0x06, 0x0A, + 0x25, 0xB7, 0x02, 0x01, 0x14, 0x02, 0x01, 0x0E, 0x04, 0x05, 0x25, 0xB7, + 0x01, 0x00, 0x25, 0x02, 0x00, 0x06, 0x19, 0x01, 0x00, 0x30, 0x01, 0x38, + 0x15, 0x06, 0x03, 0x01, 0x10, 0x2F, 0x3A, 0x01, 0x81, 0x40, 0x15, 0x06, + 0x03, 0x01, 0x20, 0x2F, 0x61, 0x36, 0x04, 0x07, 0x01, 0x04, 0x15, 0x05, + 0x02, 0x4C, 0x29, 0xBF, 0x00, 0x00, 0x37, 0xAC, 0xBF, 0x1B, 0x00, 0x03, + 0x01, 0x00, 0x03, 0x00, 0x37, 0xAC, 0x26, 0x06, 0x30, 0xB0, 0x01, 0x11, + 0x74, 0xAA, 0x26, 0x05, 0x02, 0x43, 0x29, 0x26, 0x06, 0x20, 0xAC, 0x9B, + 0x25, 0x84, 0x27, 0x03, 0x01, 0x01, 0x00, 0x2E, 0x03, 0x02, 0xAF, 0x26, + 0x02, 0x01, 0x15, 0x06, 0x07, 0x2C, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x00, + 0x02, 0x02, 0x20, 0x76, 0x04, 0x5D, 0x76, 0x04, 0x4D, 0x76, 0x1B, 0x02, + 0x00, 0x00, 0x00, 0xB0, 0x01, 0x06, 0x75, 0xAE, 0x00, 0x00, 0xB5, 0x83, + 0x06, 0x0E, 0x3A, 0x26, 0x05, 0x06, 0x41, 0x01, 0x00, 0x01, 0x00, 0x00, + 0xB5, 0x6B, 0x04, 0x08, 0x8F, 0x06, 0x05, 0x25, 0x01, 0x00, 0x04, 0x00, + 0x00, 0x00, 0xB6, 0x83, 0x06, 0x0E, 0x3A, 0x26, 0x05, 0x06, 0x41, 0x01, + 0x00, 0x01, 0x00, 0x00, 0xB6, 0x6B, 0x04, 0x08, 0x8F, 0x06, 0x05, 0x25, + 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB7, 0x26, 0x01, 0x81, 0x00, 0x0D, + 0x06, 0x04, 0x00, 0x04, 0x80, 0x55, 0x26, 0x01, 0x81, 0x40, 0x0D, 0x06, + 0x07, 0x25, 0x01, 0x00, 0x00, 0x04, 0x80, 0x47, 0x26, 0x01, 0x81, 0x60, + 0x0D, 0x06, 0x0E, 0x01, 0x1F, 0x15, 0x01, 0x01, 0xA0, 0x01, 0x81, 0x00, + 0x01, 0x8F, 0x7F, 0x04, 0x32, 0x26, 0x01, 0x81, 0x70, 0x0D, 0x06, 0x0F, + 0x01, 0x0F, 0x15, 0x01, 0x02, 0xA0, 0x01, 0x90, 0x00, 0x01, 0x83, 0xFF, + 0x7F, 0x04, 0x1C, 0x26, 0x01, 0x81, 0x78, 0x0D, 0x06, 0x11, 0x01, 0x07, + 0x15, 0x01, 0x03, 0xA0, 0x01, 0x84, 0x80, 0x00, 0x01, 0x80, 0xC3, 0xFF, + 0x7F, 0x04, 0x04, 0x25, 0x01, 0x00, 0x00, 0x6F, 0x05, 0x03, 0x25, 0x01, + 0x00, 0x00, 0x00, 0x3A, 0x26, 0x05, 0x06, 0x41, 0x01, 0x00, 0x01, 0x7F, + 0x00, 0xB7, 0x33, 0x26, 0x3C, 0x06, 0x03, 0x3A, 0x25, 0x00, 0x01, 0x06, + 0x0E, 0x3A, 0x26, 0x01, 0x06, 0x14, 0x01, 0x02, 0x10, 0x06, 0x04, 0x41, + 0x01, 0x7F, 0x00, 0x01, 0x3F, 0x15, 0x09, 0x00, 0x00, 0x26, 0x06, 0x06, + 0x0B, 0x9F, 0x33, 0x40, 0x04, 0x77, 0x25, 0x26, 0x00, 0x00, 0xB0, 0x01, + 0x03, 0x75, 0xAA, 0xB7, 0x06, 0x02, 0x54, 0x29, 0x00, 0x00, 0x3A, 0x26, + 0x06, 0x07, 0x31, 0x26, 0x06, 0x01, 0x1A, 0x04, 0x76, 0x41, 0x00, 0x00, + 0x01, 0x01, 0x75, 0xA9, 0x01, 0x01, 0x10, 0x06, 0x02, 0x42, 0x29, 0xB7, + 0x3D, 0x00, 0x04, 0xB0, 0x26, 0x01, 0x17, 0x01, 0x18, 0x6F, 0x05, 0x02, + 0x47, 0x29, 0x01, 0x18, 0x11, 0x03, 0x00, 0x72, 0xAA, 0xA5, 0x02, 0x00, + 0x06, 0x0C, 0x01, 0x80, 0x64, 0x08, 0x03, 0x01, 0xA5, 0x02, 0x01, 0x09, + 0x04, 0x0E, 0x26, 0x01, 0x32, 0x0D, 0x06, 0x04, 0x01, 0x80, 0x64, 0x09, + 0x01, 0x8E, 0x6C, 0x09, 0x03, 0x01, 0x02, 0x01, 0x01, 0x82, 0x6D, 0x08, + 0x02, 0x01, 0x01, 0x03, 0x09, 0x01, 0x04, 0x0C, 0x09, 0x02, 0x01, 0x01, + 0x80, 0x63, 0x09, 0x01, 0x80, 0x64, 0x0C, 0x0A, 0x02, 0x01, 0x01, 0x83, + 0x0F, 0x09, 0x01, 0x83, 0x10, 0x0C, 0x09, 0x03, 0x03, 0x01, 0x01, 0x01, + 0x0C, 0xA6, 0x40, 0x01, 0x01, 0x0E, 0x02, 0x01, 0x01, 0x04, 0x07, 0x3E, + 0x02, 0x01, 0x01, 0x80, 0x64, 0x07, 0x3D, 0x02, 0x01, 0x01, 0x83, 0x10, + 0x07, 0x3E, 0x2F, 0x15, 0x06, 0x03, 0x01, 0x18, 0x09, 0x91, 0x09, 0x78, + 0x26, 0x01, 0x05, 0x14, 0x02, 0x03, 0x09, 0x03, 0x03, 0x01, 0x1F, 0x15, + 0x01, 0x01, 0x3A, 0xA6, 0x02, 0x03, 0x09, 0x40, 0x03, 0x03, 0x01, 0x00, + 0x01, 0x17, 0xA6, 0x01, 0x9C, 0x10, 0x08, 0x03, 0x02, 0x01, 0x00, 0x01, + 0x3B, 0xA6, 0x01, 0x3C, 0x08, 0x02, 0x02, 0x09, 0x03, 0x02, 0x01, 0x00, + 0x01, 0x3C, 0xA6, 0x02, 0x02, 0x09, 0x03, 0x02, 0xB7, 0x26, 0x01, 0x2E, + 0x11, 0x06, 0x0D, 0x25, 0xB7, 0x26, 0x01, 0x30, 0x01, 0x39, 0x6F, 0x06, + 0x03, 0x25, 0x04, 0x74, 0x01, 0x80, 0x5A, 0x10, 0x06, 0x02, 0x47, 0x29, + 0x76, 0x02, 0x03, 0x02, 0x02, 0x00, 0x01, 0xB7, 0x7A, 0x01, 0x0A, 0x08, + 0x03, 0x00, 0xB7, 0x7A, 0x02, 0x00, 0x09, 0x00, 0x02, 0x03, 0x00, 0x03, + 0x01, 0xA5, 0x26, 0x02, 0x01, 0x02, 0x00, 0x6F, 0x05, 0x02, 0x47, 0x29, + 0x00, 0x00, 0x33, 0xB0, 0x01, 0x02, 0x75, 0x0B, 0xA8, 0x00, 0x03, 0x26, + 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0xAA, 0xB7, 0x26, 0x01, 0x81, 0x00, + 0x13, 0x06, 0x02, 0x53, 0x29, 0x26, 0x01, 0x00, 0x11, 0x06, 0x0B, 0x25, + 0x26, 0x05, 0x04, 0x25, 0x01, 0x00, 0x00, 0xB7, 0x04, 0x6F, 0x02, 0x01, + 0x26, 0x05, 0x02, 0x4F, 0x29, 0x40, 0x03, 0x01, 0x02, 0x02, 0x36, 0x02, + 0x02, 0x3F, 0x03, 0x02, 0x26, 0x06, 0x03, 0xB7, 0x04, 0x68, 0x25, 0x02, + 0x00, 0x02, 0x01, 0x0A, 0x00, 0x01, 0xB7, 0x26, 0x01, 0x81, 0x00, 0x0D, + 0x06, 0x01, 0x00, 0x01, 0x81, 0x00, 0x0A, 0x26, 0x05, 0x02, 0x4D, 0x29, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x12, 0x06, 0x19, 0x02, + 0x00, 0x40, 0x03, 0x00, 0x26, 0x01, 0x83, 0xFF, 0xFF, 0x7F, 0x12, 0x06, + 0x02, 0x4E, 0x29, 0x01, 0x08, 0x0E, 0x3A, 0xB7, 0x33, 0x09, 0x04, 0x60, + 0x00, 0x00, 0xA9, 0x92, 0x00, 0x00, 0xAA, 0xBF, 0x00, 0x00, 0xB0, 0x73, + 0xAA, 0x00, 0x01, 0xAA, 0x26, 0x05, 0x02, 0x53, 0x29, 0xB7, 0x26, 0x01, + 0x81, 0x00, 0x13, 0x06, 0x02, 0x53, 0x29, 0x03, 0x00, 0x26, 0x06, 0x16, + 0xB7, 0x02, 0x00, 0x26, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x13, 0x06, 0x02, + 0x53, 0x29, 0x01, 0x08, 0x0E, 0x09, 0x03, 0x00, 0x04, 0x67, 0x25, 0x02, + 0x00, 0x00, 0x00, 0xAA, 0x26, 0x01, 0x81, 0x7F, 0x12, 0x06, 0x08, 0xBF, + 0x01, 0x00, 0x66, 0x36, 0x01, 0x00, 0x00, 0x26, 0x66, 0x36, 0x66, 0x3F, + 0xA2, 0x01, 0x7F, 0x00, 0x00, 0xB0, 0x01, 0x0C, 0x30, 0x11, 0x06, 0x05, + 0x25, 0x72, 0xB3, 0x04, 0x3E, 0x01, 0x12, 0x30, 0x11, 0x06, 0x05, 0x25, + 0x72, 0xB4, 0x04, 0x33, 0x01, 0x13, 0x30, 0x11, 0x06, 0x05, 0x25, 0x72, + 0xB4, 0x04, 0x28, 0x01, 0x14, 0x30, 0x11, 0x06, 0x05, 0x25, 0x72, 0xB4, + 0x04, 0x1D, 0x01, 0x16, 0x30, 0x11, 0x06, 0x05, 0x25, 0x72, 0xB4, 0x04, + 0x12, 0x01, 0x1E, 0x30, 0x11, 0x06, 0x05, 0x25, 0x72, 0xB2, 0x04, 0x07, + 0x41, 0xAB, 0x01, 0x00, 0x01, 0x00, 0x25, 0x00, 0x01, 0xB7, 0x03, 0x00, + 0x02, 0x00, 0x01, 0x05, 0x14, 0x01, 0x01, 0x15, 0x2D, 0x02, 0x00, 0x01, + 0x06, 0x14, 0x26, 0x01, 0x01, 0x15, 0x06, 0x02, 0x45, 0x29, 0x01, 0x04, + 0x0E, 0x02, 0x00, 0x01, 0x1F, 0x15, 0x26, 0x01, 0x1F, 0x11, 0x06, 0x02, + 0x46, 0x29, 0x09, 0x00, 0x00, 0x26, 0x05, 0x05, 0x01, 0x00, 0x01, 0x7F, + 0x00, 0xB0, 0x00, 0x01, 0xAA, 0x26, 0x05, 0x05, 0x66, 0x36, 0x01, 0x7F, + 0x00, 0x01, 0x01, 0x03, 0x00, 0x9C, 0x26, 0x01, 0x83, 0xFF, 0x7E, 0x11, + 0x06, 0x16, 0x25, 0x26, 0x06, 0x10, 0x9D, 0x26, 0x05, 0x05, 0x25, 0xBF, + 0x01, 0x00, 0x00, 0x02, 0x00, 0x81, 0x03, 0x00, 0x04, 0x6D, 0x04, 0x1B, + 0x26, 0x05, 0x05, 0x25, 0xBF, 0x01, 0x00, 0x00, 0x02, 0x00, 0x81, 0x03, + 0x00, 0x26, 0x06, 0x0B, 0x9C, 0x26, 0x05, 0x05, 0x25, 0xBF, 0x01, 0x00, + 0x00, 0x04, 0x6D, 0x25, 0x02, 0x00, 0x26, 0x05, 0x01, 0x00, 0x40, 0x66, + 0x36, 0x01, 0x7F, 0x00, 0x01, 0xAA, 0x01, 0x01, 0x03, 0x00, 0x26, 0x06, + 0x10, 0x9E, 0x26, 0x05, 0x05, 0x25, 0xBF, 0x01, 0x00, 0x00, 0x02, 0x00, + 0x81, 0x03, 0x00, 0x04, 0x6D, 0x25, 0x02, 0x00, 0x26, 0x05, 0x01, 0x00, + 0x40, 0x66, 0x36, 0x01, 0x7F, 0x00, 0x01, 0xAA, 0x01, 0x01, 0x03, 0x00, + 0x26, 0x06, 0x10, 0xB7, 0x26, 0x05, 0x05, 0x25, 0xBF, 0x01, 0x00, 0x00, + 0x02, 0x00, 0x81, 0x03, 0x00, 0x04, 0x6D, 0x25, 0x02, 0x00, 0x26, 0x05, + 0x01, 0x00, 0x40, 0x66, 0x36, 0x01, 0x7F, 0x00, 0x00, 0xB7, 0x01, 0x08, + 0x0E, 0x3A, 0xB7, 0x33, 0x09, 0x00, 0x00, 0xB7, 0x3A, 0xB7, 0x01, 0x08, + 0x0E, 0x33, 0x09, 0x00, 0x00, 0x26, 0x05, 0x02, 0x4E, 0x29, 0x40, 0xB8, + 0x00, 0x00, 0x32, 0x26, 0x01, 0x00, 0x13, 0x06, 0x01, 0x00, 0x25, 0x1A, + 0x04, 0x74, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x00, 0x01, + 0x15, 0x00, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x01, 0x29, 0x00, 0x00, 0x01, + 0x33, 0x00, 0x00, 0xC0, 0x25, 0x00, 0x00, 0x26, 0x06, 0x07, 0xC1, 0x26, + 0x06, 0x01, 0x1A, 0x04, 0x76, 0x00, 0x00, 0x01, 0x00, 0x30, 0x31, 0x0B, + 0x41, 0x00, 0x00, 0x01, 0x81, 0x70, 0x00, 0x00, 0x01, 0x82, 0x0D, 0x00, + 0x00, 0x01, 0x82, 0x22, 0x00, 0x00, 0x01, 0x82, 0x05, 0x00, 0x00, 0x26, + 0x01, 0x83, 0xFB, 0x50, 0x01, 0x83, 0xFB, 0x6F, 0x6F, 0x06, 0x04, 0x25, + 0x01, 0x00, 0x00, 0x26, 0x01, 0x83, 0xB0, 0x00, 0x01, 0x83, 0xBF, 0x7F, + 0x6F, 0x06, 0x04, 0x25, 0x01, 0x00, 0x00, 0x01, 0x83, 0xFF, 0x7F, 0x15, + 0x01, 0x83, 0xFF, 0x7E, 0x0D, 0x00 +}; + +static const uint16_t t0_caddr[] = { + 0, + 5, + 10, + 15, + 20, + 25, + 29, + 33, + 37, + 41, + 45, + 49, + 53, + 57, + 61, + 65, + 69, + 73, + 77, + 81, + 85, + 89, + 93, + 97, + 101, + 105, + 109, + 113, + 117, + 121, + 125, + 130, + 135, + 140, + 145, + 150, + 155, + 160, + 165, + 173, + 178, + 183, + 188, + 193, + 198, + 203, + 208, + 213, + 234, + 239, + 244, + 249, + 264, + 269, + 275, + 281, + 286, + 294, + 302, + 308, + 313, + 324, + 960, + 975, + 979, + 984, + 989, + 994, + 999, + 1004, + 1118, + 1123, + 1135, + 1140, + 1145, + 1150, + 1154, + 1159, + 1164, + 1169, + 1174, + 1184, + 1189, + 1194, + 1206, + 1221, + 1226, + 1240, + 1262, + 1273, + 1376, + 1423, + 1456, + 1547, + 1553, + 1616, + 1623, + 1651, + 1679, + 1784, + 1826, + 1839, + 1851, + 1865, + 1880, + 2100, + 2114, + 2131, + 2140, + 2207, + 2263, + 2267, + 2271, + 2276, + 2324, + 2350, + 2426, + 2470, + 2481, + 2566, + 2604, + 2642, + 2652, + 2662, + 2671, + 2684, + 2688, + 2692, + 2696, + 2700, + 2704, + 2708, + 2712, + 2724, + 2732, + 2737, + 2742, + 2747, + 2752 +}; + +#define T0_INTERPRETED 60 + +#define T0_ENTER(ip, rp, slot) do { \ + const unsigned char *t0_newip; \ + uint32_t t0_lnum; \ + t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ + t0_lnum = t0_parse7E_unsigned(&t0_newip); \ + (rp) += t0_lnum; \ + *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ + (ip) = t0_newip; \ + } while (0) + +#define T0_DEFENTRY(name, slot) \ +void \ +name(void *ctx) \ +{ \ + t0_context *t0ctx = ctx; \ + t0ctx->ip = &t0_codeblock[0]; \ + T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ +} + +T0_DEFENTRY(br_x509_minimal_init_main, 144) + +#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) + +void +br_x509_minimal_run(void *t0ctx) +{ + uint32_t *dp, *rp; + const unsigned char *ip; + +#define T0_LOCAL(x) (*(rp - 2 - (x))) +#define T0_POP() (*-- dp) +#define T0_POPi() (*(int32_t *)(-- dp)) +#define T0_PEEK(x) (*(dp - 1 - (x))) +#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) +#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) +#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) +#define T0_RPOP() (*-- rp) +#define T0_RPOPi() (*(int32_t *)(-- rp)) +#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) +#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) +#define T0_ROLL(x) do { \ + size_t t0len = (size_t)(x); \ + uint32_t t0tmp = *(dp - 1 - t0len); \ + memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_SWAP() do { \ + uint32_t t0tmp = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_ROT() do { \ + uint32_t t0tmp = *(dp - 3); \ + *(dp - 3) = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_NROT() do { \ + uint32_t t0tmp = *(dp - 1); \ + *(dp - 1) = *(dp - 2); \ + *(dp - 2) = *(dp - 3); \ + *(dp - 3) = t0tmp; \ +} while (0) +#define T0_PICK(x) do { \ + uint32_t t0depth = (x); \ + T0_PUSH(T0_PEEK(t0depth)); \ +} while (0) +#define T0_CO() do { \ + goto t0_exit; \ +} while (0) +#define T0_RET() goto t0_next + + dp = ((t0_context *)t0ctx)->dp; + rp = ((t0_context *)t0ctx)->rp; + ip = ((t0_context *)t0ctx)->ip; + goto t0_next; + for (;;) { + uint32_t t0x; + + t0_next: + t0x = T0_NEXT(&ip); + if (t0x < T0_INTERPRETED) { + switch (t0x) { + int32_t t0off; + + case 0: /* ret */ + t0x = T0_RPOP(); + rp -= (t0x >> 16); + t0x &= 0xFFFF; + if (t0x == 0) { + ip = NULL; + goto t0_exit; + } + ip = &t0_codeblock[t0x]; + break; + case 1: /* literal constant */ + T0_PUSHi(t0_parse7E_signed(&ip)); + break; + case 2: /* read local */ + T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); + break; + case 3: /* write local */ + T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); + break; + case 4: /* jump */ + t0off = t0_parse7E_signed(&ip); + ip += t0off; + break; + case 5: /* jump if */ + t0off = t0_parse7E_signed(&ip); + if (T0_POP()) { + ip += t0off; + } + break; + case 6: /* jump if not */ + t0off = t0_parse7E_signed(&ip); + if (!T0_POP()) { + ip += t0off; + } + break; + case 7: { + /* %25 */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSHi(a % b); + + } + break; + case 8: { + /* * */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a * b); + + } + break; + case 9: { + /* + */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a + b); + + } + break; + case 10: { + /* - */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a - b); + + } + break; + case 11: { + /* -rot */ + T0_NROT(); + } + break; + case 12: { + /* / */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSHi(a / b); + + } + break; + case 13: { + /* < */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a < b)); + + } + break; + case 14: { + /* << */ + + int c = (int)T0_POPi(); + uint32_t x = T0_POP(); + T0_PUSH(x << c); + + } + break; + case 15: { + /* <= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a <= b)); + + } + break; + case 16: { + /* <> */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a != b)); + + } + break; + case 17: { + /* = */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a == b)); + + } + break; + case 18: { + /* > */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a > b)); + + } + break; + case 19: { + /* >= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a >= b)); + + } + break; + case 20: { + /* >> */ + + int c = (int)T0_POPi(); + int32_t x = T0_POPi(); + T0_PUSHi(x >> c); + + } + break; + case 21: { + /* and */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a & b); + + } + break; + case 22: { + /* blobcopy */ + + size_t len = T0_POP(); + unsigned char *src = (unsigned char *)CTX + T0_POP(); + unsigned char *dst = (unsigned char *)CTX + T0_POP(); + memcpy(dst, src, len); + + } + break; + case 23: { + /* check-direct-trust */ + + size_t u; + + for (u = 0; u < CTX->trust_anchors_num; u ++) { + const br_x509_trust_anchor *ta; + unsigned char hashed_DN[64]; + int kt; + + ta = &CTX->trust_anchors[u]; + if (ta->flags & BR_X509_TA_CA) { + continue; + } + hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); + if (memcmp(hashed_DN, CTX->current_dn_hash, DNHASH_LEN)) { + continue; + } + kt = CTX->pkey.key_type; + if ((ta->pkey.key_type & 0x0F) != kt) { + continue; + } + switch (kt) { + + case BR_KEYTYPE_RSA: + if (!eqbigint(CTX->pkey.key.rsa.n, + CTX->pkey.key.rsa.nlen, + ta->pkey.key.rsa.n, + ta->pkey.key.rsa.nlen) + || !eqbigint(CTX->pkey.key.rsa.e, + CTX->pkey.key.rsa.elen, + ta->pkey.key.rsa.e, + ta->pkey.key.rsa.elen)) + { + continue; + } + break; + + case BR_KEYTYPE_EC: + if (CTX->pkey.key.ec.curve != ta->pkey.key.ec.curve + || CTX->pkey.key.ec.qlen != ta->pkey.key.ec.qlen + || memcmp(CTX->pkey.key.ec.q, + ta->pkey.key.ec.q, + ta->pkey.key.ec.qlen) != 0) + { + continue; + } + break; + + default: + continue; + } + + /* + * Direct trust match! + */ + CTX->err = BR_ERR_X509_OK; + T0_CO(); + } + + } + break; + case 24: { + /* check-trust-anchor-CA */ + + size_t u; + + for (u = 0; u < CTX->trust_anchors_num; u ++) { + const br_x509_trust_anchor *ta; + unsigned char hashed_DN[64]; + + ta = &CTX->trust_anchors[u]; + if (!(ta->flags & BR_X509_TA_CA)) { + continue; + } + hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); + if (memcmp(hashed_DN, CTX->saved_dn_hash, DNHASH_LEN)) { + continue; + } + if (verify_signature(CTX, &ta->pkey) == 0) { + CTX->err = BR_ERR_X509_OK; + T0_CO(); + } + } + + } + break; + case 25: { + /* check-validity-range */ + + uint32_t nbs = T0_POP(); + uint32_t nbd = T0_POP(); + uint32_t nas = T0_POP(); + uint32_t nad = T0_POP(); + int r; + if (CTX->itime != 0) { + r = CTX->itime(CTX->itime_ctx, nbd, nbs, nad, nas); + if (r < -1 || r > 1) { + CTX->err = BR_ERR_X509_TIME_UNKNOWN; + T0_CO(); + } + } else { + uint32_t vd = CTX->days; + uint32_t vs = CTX->seconds; + if (vd == 0 && vs == 0) { +#if BR_USE_UNIX_TIME + time_t x = time(NULL); + + vd = (uint32_t)(x / 86400) + 719528; + vs = (uint32_t)(x % 86400); +#elif BR_USE_WIN32_TIME + uint64_t x; +#ifdef _XBOX + /* + * Xbox uses KeQuerySystemTime from the kernel. + * This returns time in 100-nanosecond intervals + * since January 1, 1601 (same as FILETIME). + */ + LARGE_INTEGER system_time; + KeQuerySystemTime(&system_time); + x = (uint64_t)system_time.QuadPart; +#else + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + x = ((uint64_t)ft.dwHighDateTime << 32) + + (uint64_t)ft.dwLowDateTime; +#endif + x = (x / 10000000); + vd = (uint32_t)(x / 86400) + 584754; + vs = (uint32_t)(x % 86400); +#else + CTX->err = BR_ERR_X509_TIME_UNKNOWN; + T0_CO(); +#endif + } + if (vd < nbd || (vd == nbd && vs < nbs)) { + r = -1; + } else if (vd > nad || (vd == nad && vs > nas)) { + r = 1; + } else { + r = 0; + } + } + T0_PUSHi(r); + + } + break; + case 26: { + /* co */ + T0_CO(); + } + break; + case 27: { + /* compute-dn-hash */ + + CTX->dn_hash_impl->out(&CTX->dn_hash.vtable, CTX->current_dn_hash); + CTX->do_dn_hash = 0; + + } + break; + case 28: { + /* compute-tbs-hash */ + + int id = T0_POPi(); + size_t len; + len = br_multihash_out(&CTX->mhash, id, CTX->tbs_hash); + T0_PUSH(len); + + } + break; + case 29: { + /* copy-ee-ec-pkey */ + + size_t qlen = T0_POP(); + uint32_t curve = T0_POP(); + memcpy(CTX->ee_pkey_data, CTX->pkey_data, qlen); + CTX->pkey.key_type = BR_KEYTYPE_EC; + CTX->pkey.key.ec.curve = curve; + CTX->pkey.key.ec.q = CTX->ee_pkey_data; + CTX->pkey.key.ec.qlen = qlen; + + } + break; + case 30: { + /* copy-ee-rsa-pkey */ + + size_t elen = T0_POP(); + size_t nlen = T0_POP(); + memcpy(CTX->ee_pkey_data, CTX->pkey_data, nlen + elen); + CTX->pkey.key_type = BR_KEYTYPE_RSA; + CTX->pkey.key.rsa.n = CTX->ee_pkey_data; + CTX->pkey.key.rsa.nlen = nlen; + CTX->pkey.key.rsa.e = CTX->ee_pkey_data + nlen; + CTX->pkey.key.rsa.elen = elen; + + } + break; + case 31: { + /* copy-name-SAN */ + + unsigned tag = T0_POP(); + unsigned ok = T0_POP(); + size_t u, len; + + len = CTX->pad[0]; + for (u = 0; u < CTX->num_name_elts; u ++) { + br_name_element *ne; + + ne = &CTX->name_elts[u]; + if (ne->status == 0 && ne->oid[0] == 0 && ne->oid[1] == tag) { + if (ok && ne->len > len) { + memcpy(ne->buf, CTX->pad + 1, len); + ne->buf[len] = 0; + ne->status = 1; + } else { + ne->status = -1; + } + break; + } + } + + } + break; + case 32: { + /* copy-name-element */ + + size_t len; + int32_t off = T0_POPi(); + int ok = T0_POPi(); + + if (off >= 0) { + br_name_element *ne = &CTX->name_elts[off]; + + if (ok) { + len = CTX->pad[0]; + if (len < ne->len) { + memcpy(ne->buf, CTX->pad + 1, len); + ne->buf[len] = 0; + ne->status = 1; + } else { + ne->status = -1; + } + } else { + ne->status = -1; + } + } + + } + break; + case 33: { + /* data-get8 */ + + size_t addr = T0_POP(); + T0_PUSH(t0_datablock[addr]); + + } + break; + case 34: { + /* dn-hash-length */ + + T0_PUSH(DNHASH_LEN); + + } + break; + case 35: { + /* do-ecdsa-vrfy */ + + size_t qlen = T0_POP(); + int curve = T0_POP(); + br_x509_pkey pk; + + pk.key_type = BR_KEYTYPE_EC; + pk.key.ec.curve = curve; + pk.key.ec.q = CTX->pkey_data; + pk.key.ec.qlen = qlen; + T0_PUSH(verify_signature(CTX, &pk)); + + } + break; + case 36: { + /* do-rsa-vrfy */ + + size_t elen = T0_POP(); + size_t nlen = T0_POP(); + br_x509_pkey pk; + + pk.key_type = BR_KEYTYPE_RSA; + pk.key.rsa.n = CTX->pkey_data; + pk.key.rsa.nlen = nlen; + pk.key.rsa.e = CTX->pkey_data + nlen; + pk.key.rsa.elen = elen; + T0_PUSH(verify_signature(CTX, &pk)); + + } + break; + case 37: { + /* drop */ + (void)T0_POP(); + } + break; + case 38: { + /* dup */ + T0_PUSH(T0_PEEK(0)); + } + break; + case 39: { + /* eqOID */ + + const unsigned char *a2 = &t0_datablock[T0_POP()]; + const unsigned char *a1 = &CTX->pad[0]; + size_t len = a1[0]; + int x; + if (len == a2[0]) { + x = -(memcmp(a1 + 1, a2 + 1, len) == 0); + } else { + x = 0; + } + T0_PUSH((uint32_t)x); + + } + break; + case 40: { + /* eqblob */ + + size_t len = T0_POP(); + const unsigned char *a2 = (const unsigned char *)CTX + T0_POP(); + const unsigned char *a1 = (const unsigned char *)CTX + T0_POP(); + T0_PUSHi(-(memcmp(a1, a2, len) == 0)); + + } + break; + case 41: { + /* fail */ + + CTX->err = T0_POPi(); + T0_CO(); + + } + break; + case 42: { + /* get16 */ + + uint32_t addr = T0_POP(); + T0_PUSH(*(uint16_t *)(void *)((unsigned char *)CTX + addr)); + + } + break; + case 43: { + /* get32 */ + + uint32_t addr = T0_POP(); + T0_PUSH(*(uint32_t *)(void *)((unsigned char *)CTX + addr)); + + } + break; + case 44: { + /* match-server-name */ + + size_t n1, n2; + + if (CTX->server_name == NULL) { + T0_PUSH(0); + T0_RET(); + } + n1 = strlen(CTX->server_name); + n2 = CTX->pad[0]; + if (n1 == n2 && eqnocase(&CTX->pad[1], CTX->server_name, n1)) { + T0_PUSHi(-1); + T0_RET(); + } + if (n2 >= 2 && CTX->pad[1] == '*' && CTX->pad[2] == '.') { + size_t u; + + u = 0; + while (u < n1 && CTX->server_name[u] != '.') { + u ++; + } + u ++; + n1 -= u; + if ((n2 - 2) == n1 + && eqnocase(&CTX->pad[3], CTX->server_name + u, n1)) + { + T0_PUSHi(-1); + T0_RET(); + } + } + T0_PUSH(0); + + } + break; + case 45: { + /* neg */ + + uint32_t a = T0_POP(); + T0_PUSH(-a); + + } + break; + case 46: { + /* offset-name-element */ + + unsigned san = T0_POP(); + size_t u; + + for (u = 0; u < CTX->num_name_elts; u ++) { + if (CTX->name_elts[u].status == 0) { + const unsigned char *oid; + size_t len, off; + + oid = CTX->name_elts[u].oid; + if (san) { + if (oid[0] != 0 || oid[1] != 0) { + continue; + } + off = 2; + } else { + off = 0; + } + len = oid[off]; + if (len != 0 && len == CTX->pad[0] + && memcmp(oid + off + 1, + CTX->pad + 1, len) == 0) + { + T0_PUSH(u); + T0_RET(); + } + } + } + T0_PUSHi(-1); + + } + break; + case 47: { + /* or */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a | b); + + } + break; + case 48: { + /* over */ + T0_PUSH(T0_PEEK(1)); + } + break; + case 49: { + /* read-blob-inner */ + + uint32_t len = T0_POP(); + uint32_t addr = T0_POP(); + size_t clen = CTX->hlen; + if (clen > len) { + clen = (size_t)len; + } + if (addr != 0) { + memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); + } + if (CTX->do_mhash) { + br_multihash_update(&CTX->mhash, CTX->hbuf, clen); + } + if (CTX->do_dn_hash) { + CTX->dn_hash_impl->update( + &CTX->dn_hash.vtable, CTX->hbuf, clen); + } + CTX->hbuf += clen; + CTX->hlen -= clen; + T0_PUSH(addr + clen); + T0_PUSH(len - clen); + + } + break; + case 50: { + /* read8-low */ + + if (CTX->hlen == 0) { + T0_PUSHi(-1); + } else { + unsigned char x = *CTX->hbuf ++; + if (CTX->do_mhash) { + br_multihash_update(&CTX->mhash, &x, 1); + } + if (CTX->do_dn_hash) { + CTX->dn_hash_impl->update(&CTX->dn_hash.vtable, &x, 1); + } + CTX->hlen --; + T0_PUSH(x); + } + + } + break; + case 51: { + /* rot */ + T0_ROT(); + } + break; + case 52: { + /* set16 */ + + uint32_t addr = T0_POP(); + *(uint16_t *)(void *)((unsigned char *)CTX + addr) = T0_POP(); + + } + break; + case 53: { + /* set32 */ + + uint32_t addr = T0_POP(); + *(uint32_t *)(void *)((unsigned char *)CTX + addr) = T0_POP(); + + } + break; + case 54: { + /* set8 */ + + uint32_t addr = T0_POP(); + *((unsigned char *)CTX + addr) = (unsigned char)T0_POP(); + + } + break; + case 55: { + /* start-dn-hash */ + + CTX->dn_hash_impl->init(&CTX->dn_hash.vtable); + CTX->do_dn_hash = 1; + + } + break; + case 56: { + /* start-tbs-hash */ + + br_multihash_init(&CTX->mhash); + CTX->do_mhash = 1; + + } + break; + case 57: { + /* stop-tbs-hash */ + + CTX->do_mhash = 0; + + } + break; + case 58: { + /* swap */ + T0_SWAP(); + } + break; + case 59: { + /* zero-server-name */ + + T0_PUSHi(-(CTX->server_name == NULL)); + + } + break; + } + + } else { + T0_ENTER(ip, rp, t0x); + } + } +t0_exit: + ((t0_context *)t0ctx)->dp = dp; + ((t0_context *)t0ctx)->rp = rp; + ((t0_context *)t0ctx)->ip = ip; +} + + + +/* + * Verify the signature on the certificate with the provided public key. + * This function checks the public key type with regards to the expected + * type. Returned value is either 0 on success, or a non-zero error code. + */ +static int +verify_signature(br_x509_minimal_context *ctx, const br_x509_pkey *pk) +{ + int kt; + + kt = ctx->cert_signer_key_type; + if ((pk->key_type & 0x0F) != kt) { + return BR_ERR_X509_WRONG_KEY_TYPE; + } + switch (kt) { + unsigned char tmp[64]; + + case BR_KEYTYPE_RSA: + if (ctx->irsa == 0) { + return BR_ERR_X509_UNSUPPORTED; + } + if (!ctx->irsa(ctx->cert_sig, ctx->cert_sig_len, + &t0_datablock[ctx->cert_sig_hash_oid], + ctx->cert_sig_hash_len, &pk->key.rsa, tmp)) + { + return BR_ERR_X509_BAD_SIGNATURE; + } + if (memcmp(ctx->tbs_hash, tmp, ctx->cert_sig_hash_len) != 0) { + return BR_ERR_X509_BAD_SIGNATURE; + } + return 0; + + case BR_KEYTYPE_EC: + if (ctx->iecdsa == 0) { + return BR_ERR_X509_UNSUPPORTED; + } + if (!ctx->iecdsa(ctx->iec, ctx->tbs_hash, + ctx->cert_sig_hash_len, &pk->key.ec, + ctx->cert_sig, ctx->cert_sig_len)) + { + return BR_ERR_X509_BAD_SIGNATURE; + } + return 0; + + default: + return BR_ERR_X509_UNSUPPORTED; + } +} + + diff --git a/BearSSL-OG/libbearssl/src/x509/x509_minimal.t0 b/BearSSL-OG/libbearssl/src/x509/x509_minimal.t0 new file mode 100644 index 0000000..80a3701 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/x509_minimal.t0 @@ -0,0 +1,1526 @@ +\ Copyright (c) 2016 Thomas Pornin +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +\ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +\ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +\ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +\ SOFTWARE. + +preamble { + +#include "inner.h" + +/* + * Implementation Notes + * -------------------- + * + * The C code pushes the data by chunks; all decoding is done in the + * T0 code. The cert_length value is set to the certificate length when + * a new certificate is started; the T0 code picks it up as outer limit, + * and decoding functions use it to ensure that no attempt is made at + * reading past it. The T0 code also checks that once the certificate is + * decoded, there are no trailing bytes. + * + * The T0 code sets cert_length to 0 when the certificate is fully + * decoded. + * + * The C code must still perform two checks: + * + * -- If the certificate length is 0, then the T0 code will not be + * invoked at all. This invalid condition must thus be reported by the + * C code. + * + * -- When reaching the end of certificate, the C code must verify that + * the certificate length has been set to 0, thereby signaling that + * the T0 code properly decoded a certificate. + * + * Processing of a chain works in the following way: + * + * -- The error flag is set to a non-zero value when validation is + * finished. The value is either BR_ERR_X509_OK (validation is + * successful) or another non-zero error code. When a non-zero error + * code is obtained, the remaining bytes in the current certificate and + * the subsequent certificates (if any) are completely ignored. + * + * -- Each certificate is decoded in due course, with the following + * "interesting points": + * + * -- Start of the TBS: the multihash engine is reset and activated. + * + * -- Start of the issuer DN: the secondary hash engine is started, + * to process the encoded issuer DN. + * + * -- End of the issuer DN: the secondary hash engine is stopped. The + * resulting hash value is computed and then copied into the + * next_dn_hash[] buffer. + * + * -- Start of the subject DN: the secondary hash engine is started, + * to process the encoded subject DN. + * + * -- For the EE certificate only: the Common Name, if any, is matched + * against the expected server name. + * + * -- End of the subject DN: the secondary hash engine is stopped. The + * resulting hash value is computed into the pad. It is then processed: + * + * -- If this is the EE certificate, then the hash is ignored + * (except for direct trust processing, see later; the hash is + * simply left in current_dn_hash[]). + * + * -- Otherwise, the hashed subject DN is compared with the saved + * hash value (in saved_dn_hash[]). They must match. + * + * Either way, the next_dn_hash[] value is then copied into the + * saved_dn_hash[] value. Thus, at that point, saved_dn_hash[] + * contains the hash of the issuer DN for the current certificate, + * and current_dn_hash[] contains the hash of the subject DN for the + * current certificate. + * + * -- Public key: it is decoded into the cert_pkey[] buffer. Unknown + * key types are reported at that point. + * + * -- If this is the EE certificate, then the key type is compared + * with the expected key type (initialization parameter). The public + * key data is copied to ee_pkey_data[]. The key and hashed subject + * DN are also compared with the "direct trust" keys; if the key + * and DN are matched, then validation ends with a success. + * + * -- Otherwise, the saved signature (cert_sig[]) is verified + * against the saved TBS hash (tbs_hash[]) and that freshly + * decoded public key. Failure here ends validation with an error. + * + * -- Extensions: extension values are processed in due order. + * + * -- Basic Constraints: for all certificates except EE, must be + * present, indicate a CA, and have a path length compatible with + * the chain length so far. + * + * -- Key Usage: for the EE, if present, must allow signatures + * or encryption/key exchange, as required for the cipher suite. + * For non-EE, if present, must have the "certificate sign" bit. + * + * -- Subject Alt Name: for the EE, dNSName names are matched + * against the server name. Ignored for non-EE. + * + * -- Authority Key Identifier, Subject Key Identifier, Issuer + * Alt Name, Subject Directory Attributes, CRL Distribution Points + * Freshest CRL, Authority Info Access and Subject Info Access + * extensions are always ignored: they either contain only + * informative data, or they relate to revocation processing, which + * we explicitly do not support. + * + * -- All other extensions are ignored if non-critical. If a + * critical extension other than the ones above is encountered, + * then a failure is reported. + * + * -- End of the TBS: the multihash engine is stopped. + * + * -- Signature algorithm: the signature algorithm on the + * certificate is decoded. A failure is reported if that algorithm + * is unknown. The hashed TBS corresponding to the signature hash + * function is computed and stored in tbs_hash[] (if not supported, + * then a failure is reported). The hash OID and length are stored + * in cert_sig_hash_oid and cert_sig_hash_len. + * + * -- Signature value: the signature value is copied into the + * cert_sig[] array. + * + * -- Certificate end: the hashed issuer DN (saved_dn_hash[]) is + * looked up in the trust store (CA trust anchors only); for all + * that match, the signature (cert_sig[]) is verified against the + * anchor public key (hashed TBS is in tbs_hash[]). If one of these + * signatures is valid, then validation ends with a success. + * + * -- If the chain end is reached without obtaining a validation success, + * then validation is reported as failed. + */ + +#if BR_USE_UNIX_TIME +#include +#endif + +#if BR_USE_WIN32_TIME +#include +#endif + +/* + * The T0 compiler will produce these prototypes declarations in the + * header. + * +void br_x509_minimal_init_main(void *ctx); +void br_x509_minimal_run(void *ctx); + */ + +/* see bearssl_x509.h */ +void +br_x509_minimal_init(br_x509_minimal_context *ctx, + const br_hash_class *dn_hash_impl, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) +{ + memset(ctx, 0, sizeof *ctx); + ctx->vtable = &br_x509_minimal_vtable; + ctx->dn_hash_impl = dn_hash_impl; + ctx->trust_anchors = trust_anchors; + ctx->trust_anchors_num = trust_anchors_num; +} + +static void +xm_start_chain(const br_x509_class **ctx, const char *server_name) +{ + br_x509_minimal_context *cc; + size_t u; + + cc = (br_x509_minimal_context *)(void *)ctx; + for (u = 0; u < cc->num_name_elts; u ++) { + cc->name_elts[u].status = 0; + cc->name_elts[u].buf[0] = 0; + } + memset(&cc->pkey, 0, sizeof cc->pkey); + cc->num_certs = 0; + cc->err = 0; + cc->cpu.dp = cc->dp_stack; + cc->cpu.rp = cc->rp_stack; + br_x509_minimal_init_main(&cc->cpu); + if (server_name == NULL || *server_name == 0) { + cc->server_name = NULL; + } else { + cc->server_name = server_name; + } +} + +static void +xm_start_cert(const br_x509_class **ctx, uint32_t length) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err != 0) { + return; + } + if (length == 0) { + cc->err = BR_ERR_X509_TRUNCATED; + return; + } + cc->cert_length = length; +} + +static void +xm_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err != 0) { + return; + } + cc->hbuf = buf; + cc->hlen = len; + br_x509_minimal_run(&cc->cpu); +} + +static void +xm_end_cert(const br_x509_class **ctx) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err == 0 && cc->cert_length != 0) { + cc->err = BR_ERR_X509_TRUNCATED; + } + cc->num_certs ++; +} + +static unsigned +xm_end_chain(const br_x509_class **ctx) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err == 0) { + if (cc->num_certs == 0) { + cc->err = BR_ERR_X509_EMPTY_CHAIN; + } else { + cc->err = BR_ERR_X509_NOT_TRUSTED; + } + } else if (cc->err == BR_ERR_X509_OK) { + return 0; + } + return (unsigned)cc->err; +} + +static const br_x509_pkey * +xm_get_pkey(const br_x509_class *const *ctx, unsigned *usages) +{ + br_x509_minimal_context *cc; + + cc = (br_x509_minimal_context *)(void *)ctx; + if (cc->err == BR_ERR_X509_OK + || cc->err == BR_ERR_X509_NOT_TRUSTED) + { + if (usages != NULL) { + *usages = cc->key_usages; + } + return &((br_x509_minimal_context *)(void *)ctx)->pkey; + } else { + return NULL; + } +} + +/* see bearssl_x509.h */ +const br_x509_class br_x509_minimal_vtable = { + sizeof(br_x509_minimal_context), + xm_start_chain, + xm_start_cert, + xm_append, + xm_end_cert, + xm_end_chain, + xm_get_pkey +}; + +#define CTX ((br_x509_minimal_context *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_minimal_context, cpu))) +#define CONTEXT_NAME br_x509_minimal_context + +#define DNHASH_LEN ((CTX->dn_hash_impl->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK) + +/* + * Hash a DN (from a trust anchor) into the provided buffer. This uses the + * DN hash implementation and context structure from the X.509 engine + * context. + */ +static void +hash_dn(br_x509_minimal_context *ctx, const void *dn, size_t len, + unsigned char *out) +{ + ctx->dn_hash_impl->init(&ctx->dn_hash.vtable); + ctx->dn_hash_impl->update(&ctx->dn_hash.vtable, dn, len); + ctx->dn_hash_impl->out(&ctx->dn_hash.vtable, out); +} + +/* + * Compare two big integers for equality. The integers use unsigned big-endian + * encoding; extra leading bytes (of value 0) are allowed. + */ +static int +eqbigint(const unsigned char *b1, size_t len1, + const unsigned char *b2, size_t len2) +{ + while (len1 > 0 && *b1 == 0) { + b1 ++; + len1 --; + } + while (len2 > 0 && *b2 == 0) { + b2 ++; + len2 --; + } + if (len1 != len2) { + return 0; + } + return memcmp(b1, b2, len1) == 0; +} + +/* + * Compare two strings for equality, in a case-insensitive way. This + * function handles casing only for ASCII letters. + */ +static int +eqnocase(const void *s1, const void *s2, size_t len) +{ + const unsigned char *buf1, *buf2; + + buf1 = s1; + buf2 = s2; + while (len -- > 0) { + int x1, x2; + + x1 = *buf1 ++; + x2 = *buf2 ++; + if (x1 >= 'A' && x1 <= 'Z') { + x1 += 'a' - 'A'; + } + if (x2 >= 'A' && x2 <= 'Z') { + x2 += 'a' - 'A'; + } + if (x1 != x2) { + return 0; + } + } + return 1; +} + +static int verify_signature(br_x509_minimal_context *ctx, + const br_x509_pkey *pk); + +} + +postamble { + +/* + * Verify the signature on the certificate with the provided public key. + * This function checks the public key type with regards to the expected + * type. Returned value is either 0 on success, or a non-zero error code. + */ +static int +verify_signature(br_x509_minimal_context *ctx, const br_x509_pkey *pk) +{ + int kt; + + kt = ctx->cert_signer_key_type; + if ((pk->key_type & 0x0F) != kt) { + return BR_ERR_X509_WRONG_KEY_TYPE; + } + switch (kt) { + unsigned char tmp[64]; + + case BR_KEYTYPE_RSA: + if (ctx->irsa == 0) { + return BR_ERR_X509_UNSUPPORTED; + } + if (!ctx->irsa(ctx->cert_sig, ctx->cert_sig_len, + &t0_datablock[ctx->cert_sig_hash_oid], + ctx->cert_sig_hash_len, &pk->key.rsa, tmp)) + { + return BR_ERR_X509_BAD_SIGNATURE; + } + if (memcmp(ctx->tbs_hash, tmp, ctx->cert_sig_hash_len) != 0) { + return BR_ERR_X509_BAD_SIGNATURE; + } + return 0; + + case BR_KEYTYPE_EC: + if (ctx->iecdsa == 0) { + return BR_ERR_X509_UNSUPPORTED; + } + if (!ctx->iecdsa(ctx->iec, ctx->tbs_hash, + ctx->cert_sig_hash_len, &pk->key.ec, + ctx->cert_sig, ctx->cert_sig_len)) + { + return BR_ERR_X509_BAD_SIGNATURE; + } + return 0; + + default: + return BR_ERR_X509_UNSUPPORTED; + } +} + +} + +cc: read8-low ( -- x ) { + if (CTX->hlen == 0) { + T0_PUSHi(-1); + } else { + unsigned char x = *CTX->hbuf ++; + if (CTX->do_mhash) { + br_multihash_update(&CTX->mhash, &x, 1); + } + if (CTX->do_dn_hash) { + CTX->dn_hash_impl->update(&CTX->dn_hash.vtable, &x, 1); + } + CTX->hlen --; + T0_PUSH(x); + } +} + +addr: cert_length +addr: num_certs + +cc: read-blob-inner ( addr len -- addr len ) { + uint32_t len = T0_POP(); + uint32_t addr = T0_POP(); + size_t clen = CTX->hlen; + if (clen > len) { + clen = (size_t)len; + } + if (addr != 0) { + memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); + } + if (CTX->do_mhash) { + br_multihash_update(&CTX->mhash, CTX->hbuf, clen); + } + if (CTX->do_dn_hash) { + CTX->dn_hash_impl->update( + &CTX->dn_hash.vtable, CTX->hbuf, clen); + } + CTX->hbuf += clen; + CTX->hlen -= clen; + T0_PUSH(addr + clen); + T0_PUSH(len - clen); +} + +\ Compute the TBS hash, using the provided hash ID. The hash value is +\ written in the tbs_hash[] array, and the hash length is returned. If +\ the requested hash function is not supported, then 0 is returned. +cc: compute-tbs-hash ( id -- hashlen ) { + int id = T0_POPi(); + size_t len; + len = br_multihash_out(&CTX->mhash, id, CTX->tbs_hash); + T0_PUSH(len); +} + +\ Push true (-1) if no server name is expected in the EE certificate. +cc: zero-server-name ( -- bool ) { + T0_PUSHi(-(CTX->server_name == NULL)); +} + +addr: key_usages +addr: cert_sig +addr: cert_sig_len +addr: cert_signer_key_type +addr: cert_sig_hash_oid +addr: cert_sig_hash_len +addr: tbs_hash +addr: min_rsa_size + +\ Start TBS hash computation. The hash functions are reinitialised. +cc: start-tbs-hash ( -- ) { + br_multihash_init(&CTX->mhash); + CTX->do_mhash = 1; +} + +\ Stop TBS hash computation. +cc: stop-tbs-hash ( -- ) { + CTX->do_mhash = 0; +} + +\ Start DN hash computation. +cc: start-dn-hash ( -- ) { + CTX->dn_hash_impl->init(&CTX->dn_hash.vtable); + CTX->do_dn_hash = 1; +} + +\ Terminate DN hash computation and write the DN hash into the +\ current_dn_hash buffer. +cc: compute-dn-hash ( -- ) { + CTX->dn_hash_impl->out(&CTX->dn_hash.vtable, CTX->current_dn_hash); + CTX->do_dn_hash = 0; +} + +\ Get the length of hash values obtained with the DN hasher. +cc: dn-hash-length ( -- len ) { + T0_PUSH(DNHASH_LEN); +} + +\ Copy data between two areas in the context. +cc: blobcopy ( addr-dst addr-src len -- ) { + size_t len = T0_POP(); + unsigned char *src = (unsigned char *)CTX + T0_POP(); + unsigned char *dst = (unsigned char *)CTX + T0_POP(); + memcpy(dst, src, len); +} + +addr: current_dn_hash +addr: next_dn_hash +addr: saved_dn_hash + +\ Read a DN, hashing it into current_dn_hash. The DN contents are not +\ inspected (only the outer tag, for SEQUENCE, is checked). +: read-DN ( lim -- lim ) + start-dn-hash + read-sequence-open skip-close-elt + compute-dn-hash ; + +cc: offset-name-element ( san -- n ) { + unsigned san = T0_POP(); + size_t u; + + for (u = 0; u < CTX->num_name_elts; u ++) { + if (CTX->name_elts[u].status == 0) { + const unsigned char *oid; + size_t len, off; + + oid = CTX->name_elts[u].oid; + if (san) { + if (oid[0] != 0 || oid[1] != 0) { + continue; + } + off = 2; + } else { + off = 0; + } + len = oid[off]; + if (len != 0 && len == CTX->pad[0] + && memcmp(oid + off + 1, + CTX->pad + 1, len) == 0) + { + T0_PUSH(u); + T0_RET(); + } + } + } + T0_PUSHi(-1); +} + +cc: copy-name-element ( bool offbuf -- ) { + size_t len; + int32_t off = T0_POPi(); + int ok = T0_POPi(); + + if (off >= 0) { + br_name_element *ne = &CTX->name_elts[off]; + + if (ok) { + len = CTX->pad[0]; + if (len < ne->len) { + memcpy(ne->buf, CTX->pad + 1, len); + ne->buf[len] = 0; + ne->status = 1; + } else { + ne->status = -1; + } + } else { + ne->status = -1; + } + } +} + +cc: copy-name-SAN ( bool tag -- ) { + unsigned tag = T0_POP(); + unsigned ok = T0_POP(); + size_t u, len; + + len = CTX->pad[0]; + for (u = 0; u < CTX->num_name_elts; u ++) { + br_name_element *ne; + + ne = &CTX->name_elts[u]; + if (ne->status == 0 && ne->oid[0] == 0 && ne->oid[1] == tag) { + if (ok && ne->len > len) { + memcpy(ne->buf, CTX->pad + 1, len); + ne->buf[len] = 0; + ne->status = 1; + } else { + ne->status = -1; + } + break; + } + } +} + +\ Read a value, decoding string types. If the string type is recognised +\ and the value could be converted to UTF-8 into the pad, then true (-1) +\ is returned; in all other cases, false (0) is returned. Either way, the +\ object is consumed. +: read-string ( lim -- lim bool ) + read-tag case + \ UTF8String + 12 of check-primitive read-value-UTF8 endof + \ NumericString + 18 of check-primitive read-value-latin1 endof + \ PrintableString + 19 of check-primitive read-value-latin1 endof + \ TeletexString + 20 of check-primitive read-value-latin1 endof + \ IA5String + 22 of check-primitive read-value-latin1 endof + \ BMPString + 30 of check-primitive read-value-UTF16 endof + 2drop read-length-skip 0 0 + endcase ; + +\ Read a DN for the EE. The normalized DN hash is computed and stored in the +\ current_dn_hash. +\ Name elements are gathered. Also, the Common Name is matched against the +\ intended server name. +\ Returned value is true (-1) if the CN matches the intended server name, +\ false (0) otherwise. +: read-DN-EE ( lim -- lim bool ) + \ Flag will be set to true if there is a CN and it matches the + \ intended server name. + 0 { eename-matches } + + \ Activate DN hashing. + start-dn-hash + + \ Parse the DN structure: it is a SEQUENCE of SET of + \ AttributeTypeAndValue. Each AttributeTypeAndValue is a + \ SEQUENCE { OBJECT IDENTIFIER, ANY }. + read-sequence-open + begin + dup while + + read-tag 0x11 check-tag-constructed read-length-open-elt + dup ifnot ERR_X509_BAD_DN fail then + begin + dup while + + read-sequence-open + + \ Read the OID. If the OID could not be read (too + \ long) then the first pad byte will be 0. + read-OID drop + + \ If it is the Common Name then we'll need to + \ match it against the intended server name (if + \ applicable). + id-at-commonName eqOID { isCN } + + \ Get offset for reception buffer for that element + \ (or -1). + 0 offset-name-element { offbuf } + + \ Try to read the value as a string. + read-string + + \ If the value could be decoded as a string, + \ copy it and/or match it, as appropriate. + dup isCN and if + match-server-name if + -1 >eename-matches + then + then + offbuf copy-name-element + + \ Close the SEQUENCE + close-elt + + repeat + close-elt + repeat + close-elt + + \ Compute DN hash and deactivate DN hashing. + compute-dn-hash + + \ Return the CN match flag. + eename-matches ; + +\ Check the provided validity range against the current (or configured) +\ date and time ("na" = notAfter, "nb = notBefore). Returned value: +\ -1 current date/time is before the notBefore date +\ 0 current date/time is within the allowed range +\ +1 current date/time is after the notAfter range +\ If the current date/time is not available, then this function triggers a +\ failure and does not return. +cc: check-validity-range ( na-days na-seconds nb-days nb-seconds -- int ) { + uint32_t nbs = T0_POP(); + uint32_t nbd = T0_POP(); + uint32_t nas = T0_POP(); + uint32_t nad = T0_POP(); + int r; + if (CTX->itime != 0) { + r = CTX->itime(CTX->itime_ctx, nbd, nbs, nad, nas); + if (r < -1 || r > 1) { + CTX->err = BR_ERR_X509_TIME_UNKNOWN; + T0_CO(); + } + } else { + uint32_t vd = CTX->days; + uint32_t vs = CTX->seconds; + if (vd == 0 && vs == 0) { +#if BR_USE_UNIX_TIME + time_t x = time(NULL); + + vd = (uint32_t)(x / 86400) + 719528; + vs = (uint32_t)(x % 86400); +#elif BR_USE_WIN32_TIME + FILETIME ft; + uint64_t x; + + GetSystemTimeAsFileTime(&ft); + x = ((uint64_t)ft.dwHighDateTime << 32) + + (uint64_t)ft.dwLowDateTime; + x = (x / 10000000); + vd = (uint32_t)(x / 86400) + 584754; + vs = (uint32_t)(x % 86400); +#else + CTX->err = BR_ERR_X509_TIME_UNKNOWN; + T0_CO(); +#endif + } + if (vd < nbd || (vd == nbd && vs < nbs)) { + r = -1; + } else if (vd > nad || (vd == nad && vs > nas)) { + r = 1; + } else { + r = 0; + } + } + T0_PUSHi(r); +} + +\ Swap the top two elements with the two elements immediately below. +: swap2 ( a b c d -- c d a b ) + 3 roll 3 roll ; + +\ Match the name in the pad with the expected server name. Returned value +\ is true (-1) on match, false (0) otherwise. If there is no expected +\ server name, then 0 is returned. +\ Match conditions: either an exact match (case insensitive), or a +\ wildcard match, if the found name starts with "*.". We only match a +\ starting wildcard, and only against a complete DN name component. +cc: match-server-name ( -- bool ) { + size_t n1, n2; + + if (CTX->server_name == NULL) { + T0_PUSH(0); + T0_RET(); + } + n1 = strlen(CTX->server_name); + n2 = CTX->pad[0]; + if (n1 == n2 && eqnocase(&CTX->pad[1], CTX->server_name, n1)) { + T0_PUSHi(-1); + T0_RET(); + } + if (n2 >= 2 && CTX->pad[1] == '*' && CTX->pad[2] == '.') { + size_t u; + + u = 0; + while (u < n1 && CTX->server_name[u] != '.') { + u ++; + } + u ++; + n1 -= u; + if ((n2 - 2) == n1 + && eqnocase(&CTX->pad[3], CTX->server_name + u, n1)) + { + T0_PUSHi(-1); + T0_RET(); + } + } + T0_PUSH(0); +} + +\ Get the address and length for the pkey_data buffer. +: addr-len-pkey_data ( -- addr len ) + CX 0 8191 { offsetof(br_x509_minimal_context, pkey_data) } + CX 0 8191 { BR_X509_BUFSIZE_KEY } ; + +\ Copy the EE public key to the permanent buffer (RSA). +cc: copy-ee-rsa-pkey ( nlen elen -- ) { + size_t elen = T0_POP(); + size_t nlen = T0_POP(); + memcpy(CTX->ee_pkey_data, CTX->pkey_data, nlen + elen); + CTX->pkey.key_type = BR_KEYTYPE_RSA; + CTX->pkey.key.rsa.n = CTX->ee_pkey_data; + CTX->pkey.key.rsa.nlen = nlen; + CTX->pkey.key.rsa.e = CTX->ee_pkey_data + nlen; + CTX->pkey.key.rsa.elen = elen; +} + +\ Copy the EE public key to the permanent buffer (EC). +cc: copy-ee-ec-pkey ( curve qlen -- ) { + size_t qlen = T0_POP(); + uint32_t curve = T0_POP(); + memcpy(CTX->ee_pkey_data, CTX->pkey_data, qlen); + CTX->pkey.key_type = BR_KEYTYPE_EC; + CTX->pkey.key.ec.curve = curve; + CTX->pkey.key.ec.q = CTX->ee_pkey_data; + CTX->pkey.key.ec.qlen = qlen; +} + +\ Check whether the current certificate (EE) is directly trusted. +cc: check-direct-trust ( -- ) { + size_t u; + + for (u = 0; u < CTX->trust_anchors_num; u ++) { + const br_x509_trust_anchor *ta; + unsigned char hashed_DN[64]; + int kt; + + ta = &CTX->trust_anchors[u]; + if (ta->flags & BR_X509_TA_CA) { + continue; + } + hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); + if (memcmp(hashed_DN, CTX->current_dn_hash, DNHASH_LEN)) { + continue; + } + kt = CTX->pkey.key_type; + if ((ta->pkey.key_type & 0x0F) != kt) { + continue; + } + switch (kt) { + + case BR_KEYTYPE_RSA: + if (!eqbigint(CTX->pkey.key.rsa.n, + CTX->pkey.key.rsa.nlen, + ta->pkey.key.rsa.n, + ta->pkey.key.rsa.nlen) + || !eqbigint(CTX->pkey.key.rsa.e, + CTX->pkey.key.rsa.elen, + ta->pkey.key.rsa.e, + ta->pkey.key.rsa.elen)) + { + continue; + } + break; + + case BR_KEYTYPE_EC: + if (CTX->pkey.key.ec.curve != ta->pkey.key.ec.curve + || CTX->pkey.key.ec.qlen != ta->pkey.key.ec.qlen + || memcmp(CTX->pkey.key.ec.q, + ta->pkey.key.ec.q, + ta->pkey.key.ec.qlen) != 0) + { + continue; + } + break; + + default: + continue; + } + + /* + * Direct trust match! + */ + CTX->err = BR_ERR_X509_OK; + T0_CO(); + } +} + +\ Check the signature on the certificate with regards to all trusted CA. +\ We use the issuer hash (in saved_dn_hash[]) as CA identifier. +cc: check-trust-anchor-CA ( -- ) { + size_t u; + + for (u = 0; u < CTX->trust_anchors_num; u ++) { + const br_x509_trust_anchor *ta; + unsigned char hashed_DN[64]; + + ta = &CTX->trust_anchors[u]; + if (!(ta->flags & BR_X509_TA_CA)) { + continue; + } + hash_dn(CTX, ta->dn.data, ta->dn.len, hashed_DN); + if (memcmp(hashed_DN, CTX->saved_dn_hash, DNHASH_LEN)) { + continue; + } + if (verify_signature(CTX, &ta->pkey) == 0) { + CTX->err = BR_ERR_X509_OK; + T0_CO(); + } + } +} + +\ Verify RSA signature. This uses the public key that was just decoded +\ into CTX->pkey_data; the modulus and exponent length are provided as +\ parameters. The resulting hash value is compared with the one in +\ tbs_hash. Returned value is 0 on success, or a non-zero error code. +cc: do-rsa-vrfy ( nlen elen -- err ) { + size_t elen = T0_POP(); + size_t nlen = T0_POP(); + br_x509_pkey pk; + + pk.key_type = BR_KEYTYPE_RSA; + pk.key.rsa.n = CTX->pkey_data; + pk.key.rsa.nlen = nlen; + pk.key.rsa.e = CTX->pkey_data + nlen; + pk.key.rsa.elen = elen; + T0_PUSH(verify_signature(CTX, &pk)); +} + +\ Verify ECDSA signature. This uses the public key that was just decoded +\ into CTX->pkey_dayta; the curve ID and public point length are provided +\ as parameters. The hash value in tbs_hash is used. Returned value is 0 +\ on success, or non-zero error code. +cc: do-ecdsa-vrfy ( curve qlen -- err ) { + size_t qlen = T0_POP(); + int curve = T0_POP(); + br_x509_pkey pk; + + pk.key_type = BR_KEYTYPE_EC; + pk.key.ec.curve = curve; + pk.key.ec.q = CTX->pkey_data; + pk.key.ec.qlen = qlen; + T0_PUSH(verify_signature(CTX, &pk)); +} + +cc: print-bytes ( addr len -- ) { + extern int printf(const char *fmt, ...); + size_t len = T0_POP(); + unsigned char *buf = (unsigned char *)CTX + T0_POP(); + size_t u; + + for (u = 0; u < len; u ++) { + printf("%02X", buf[u]); + } +} + +cc: printOID ( -- ) { + extern int printf(const char *fmt, ...); + size_t u, len; + + len = CTX->pad[0]; + if (len == 0) { + printf("*"); + T0_RET(); + } + printf("%u.%u", CTX->pad[1] / 40, CTX->pad[1] % 40); + u = 2; + while (u <= len) { + unsigned long ul; + + ul = 0; + for (;;) { + int x; + + if (u > len) { + printf("BAD"); + T0_RET(); + } + x = CTX->pad[u ++]; + ul = (ul << 7) + (x & 0x7F); + if (!(x & 0x80)) { + break; + } + } + printf(".%lu", ul); + } +} + +\ Extensions with specific processing. +OID: basicConstraints 2.5.29.19 +OID: keyUsage 2.5.29.15 +OID: subjectAltName 2.5.29.17 +OID: certificatePolicies 2.5.29.32 + +\ Policy qualifier "pointer to CPS" +OID: id-qt-cps 1.3.6.1.5.5.7.2.1 + +\ Extensions which are ignored when encountered, even if critical. +OID: authorityKeyIdentifier 2.5.29.35 +OID: subjectKeyIdentifier 2.5.29.14 +OID: issuerAltName 2.5.29.18 +OID: subjectDirectoryAttributes 2.5.29.9 +OID: crlDistributionPoints 2.5.29.31 +OID: freshestCRL 2.5.29.46 +OID: authorityInfoAccess 1.3.6.1.5.5.7.1.1 +OID: subjectInfoAccess 1.3.6.1.5.5.7.1.11 + +\ Process a Basic Constraints extension. This should be called only if +\ the certificate is not the EE. We check that the extension contains +\ the "CA" flag, and that the path length, if specified, is compatible +\ with the current chain length. +: process-basicConstraints ( lim -- lim ) + read-sequence-open + read-tag-or-end + dup 0x01 = if + read-boolean ifnot ERR_X509_NOT_CA fail then + read-tag-or-end + else + ERR_X509_NOT_CA fail + then + dup 0x02 = if + drop check-primitive read-small-int-value + addr-num_certs get32 1- < if ERR_X509_NOT_CA fail then + read-tag-or-end + then + -1 <> if ERR_X509_UNEXPECTED fail then + drop + close-elt + ; + +\ Process a Key Usage extension. +\ For the EE certificate: +\ -- if the key usage contains keyEncipherment (2), dataEncipherment (3) +\ or keyAgreement (4), then the "key exchange" usage is allowed; +\ -- if the key usage contains digitalSignature (0) or nonRepudiation (1), +\ then the "signature" usage is allowed. +\ For CA certificates, the extension must contain keyCertSign (5). +: process-keyUsage ( lim ee -- lim ) + { ee } + + \ Read tag for the BIT STRING and open it. + read-tag 0x03 check-tag-primitive + read-length-open-elt + \ First byte indicates number of ignored bits in the last byte. It + \ must be between 0 and 7. + read8 { ign } + ign 7 > if ERR_X509_UNEXPECTED fail then + \ Depending on length, we have either 0, 1 or more bytes to read. + dup case + 0 of ERR_X509_FORBIDDEN_KEY_USAGE fail endof + 1 of read8 ign >> ign << endof + drop read8 0 + endcase + + \ Check bits. + ee if + \ EE: get usages. + 0 + over 0x38 and if 0x10 or then + swap 0xC0 and if 0x20 or then + addr-key_usages set8 + else + \ Not EE: keyCertSign must be set. + 0x04 and ifnot ERR_X509_FORBIDDEN_KEY_USAGE fail then + then + + \ We don't care about subsequent bytes. + skip-close-elt ; + +\ Process a Certificate Policies extension. +\ +\ Since we don't actually support full policies processing, this function +\ only checks that the extension contents can be safely ignored. Indeed, +\ we don't validate against a specific set of policies (in RFC 5280 +\ terminology, user-initial-policy-set only contains the special value +\ any-policy). Moreover, we don't support policy constraints (if a +\ critical Policy Constraints extension is encountered, the validation +\ will fail). Therefore, we can safely ignore the contents of this +\ extension, except if it is critical AND one of the policy OID has a +\ qualifier which is distinct from id-qt-cps (because id-qt-cps is +\ specially designated by RFC 5280 has having no mandated action). +\ +\ This function is called only if the extension is critical. +: process-certPolicies ( lim -- lim ) + \ Extension value is a SEQUENCE OF PolicyInformation. + read-sequence-open + begin dup while + \ PolicyInformation ::= SEQUENCE { + \ policyIdentifier OBJECT IDENTIFIER, + \ policyQualifiers SEQUENCE OF PolicyQualifierInfo OPTIONAL + \ } + read-sequence-open + read-OID drop + dup if + read-sequence-open + begin dup while + \ PolicyQualifierInfo ::= SEQUENCE { + \ policyQualifierId OBJECT IDENTIFIER, + \ qualifier ANY + \ } + read-sequence-open + read-OID drop id-qt-cps eqOID ifnot + ERR_X509_CRITICAL_EXTENSION fail + then + skip-close-elt + repeat + close-elt + then + close-elt + repeat + close-elt ; + +\ Process a Subject Alt Name extension. Returned value is a boolean set +\ to true if the expected server name was matched against a dNSName in +\ the extension. +: process-SAN ( lim -- lim bool ) + 0 { m } + read-sequence-open + begin dup while + \ Read the tag. If the tag is context-0, then parse an + \ 'otherName'. If the tag is context-2, then parse a + \ dNSName. If the tag is context-1 or context-6, + \ parse + read-tag case + \ OtherName + 0x20 of + \ OtherName ::= SEQUENCE { + \ type-id OBJECT IDENTIFIER, + \ value [0] EXPLICIT ANY + \ } + check-constructed read-length-open-elt + read-OID drop + -1 offset-name-element { offbuf } + read-tag 0x20 check-tag-constructed + read-length-open-elt + read-string offbuf copy-name-element + close-elt + close-elt + endof + \ rfc822Name (IA5String) + 0x21 of + check-primitive + read-value-UTF8 1 copy-name-SAN + endof + \ dNSName (IA5String) + 0x22 of + check-primitive + read-value-UTF8 + dup if match-server-name m or >m then + 2 copy-name-SAN + endof + \ uniformResourceIdentifier (IA5String) + 0x26 of + check-primitive + read-value-UTF8 6 copy-name-SAN + endof + 2drop read-length-skip 0 + endcase + + \ We check only names of type dNSName; they use IA5String, + \ which is basically ASCII. + \ read-tag 0x22 = if + \ check-primitive + \ read-small-value drop + \ match-server-name m or >m + \ else + \ drop read-length-skip + \ then + repeat + close-elt + m ; + +\ Decode a certificate. The "ee" boolean must be true for the EE. +: decode-certificate ( ee -- ) + { ee } + + \ Obtain the total certificate length. + addr-cert_length get32 + + \ Open the outer SEQUENCE. + read-sequence-open + + \ TBS + \ Activate hashing. + start-tbs-hash + read-sequence-open + + \ First element may be an explicit version. We accept only + \ versions 0 to 2 (certificates v1 to v3). + read-tag dup 0x20 = if + drop check-constructed read-length-open-elt + read-tag + 0x02 check-tag-primitive + read-small-int-value + 2 > if ERR_X509_UNSUPPORTED fail then + close-elt + read-tag + then + + \ Serial number. We just check that the tag is correct. + 0x02 check-tag-primitive + read-length-skip + + \ Signature algorithm. This structure is redundant with the one + \ on the outside; we just skip it. + read-sequence-open skip-close-elt + + \ Issuer name: hashed, then copied into next_dn_hash[]. + read-DN + addr-next_dn_hash addr-current_dn_hash dn-hash-length blobcopy + + \ Validity dates. + read-sequence-open + read-date { nbd nbs } read-date nbd nbs check-validity-range + if ERR_X509_EXPIRED fail then + close-elt + + \ Subject name. + ee if + \ For the EE, we must check whether the Common Name, if + \ any, matches the expected server name. + read-DN-EE { eename } + else + \ For a non-EE certificate, the hashed subject DN must match + \ the saved hashed issuer DN from the previous certificate. + read-DN + addr-current_dn_hash addr-saved_dn_hash dn-hash-length eqblob + ifnot ERR_X509_DN_MISMATCH fail then + then + \ Move the hashed issuer DN for this certificate into the + \ saved_dn_hash[] array. + addr-saved_dn_hash addr-next_dn_hash dn-hash-length blobcopy + + \ Public Key. + read-sequence-open + \ Algorithm Identifier. Right now we are only interested in the + \ OID, since we only support RSA keys. + read-sequence-open + read-OID ifnot ERR_X509_UNSUPPORTED fail then + { ; pkey-type } + choice + \ RSA public key. + rsaEncryption eqOID uf + skip-close-elt + \ Public key itself: the BIT STRING contains bytes + \ (no partial byte) and these bytes encode the + \ actual value. + read-bits-open + \ RSA public key is a SEQUENCE of two + \ INTEGER. We get both INTEGER values into + \ the pkey_data[] buffer, if they fit. + read-sequence-open + addr-len-pkey_data + read-integer { nlen } + addr-len-pkey_data swap nlen + swap nlen - + read-integer { elen } + close-elt + + \ Check that the public key fits our minimal + \ size requirements. Note that the integer + \ decoder already skipped the leading bytes + \ of value 0, so we are working on the true + \ modulus length here. + addr-min_rsa_size get16 128 + nlen > if + ERR_X509_WEAK_PUBLIC_KEY fail + then + close-elt + KEYTYPE_RSA >pkey-type + enduf + + \ EC public key. + id-ecPublicKey eqOID uf + \ We support only named curves, for which the + \ "parameters" field in the AlgorithmIdentifier + \ field should be an OID. + read-OID ifnot ERR_X509_UNSUPPORTED fail then + choice + ansix9p256r1 eqOID uf 23 enduf + ansix9p384r1 eqOID uf 24 enduf + ansix9p521r1 eqOID uf 25 enduf + ERR_X509_UNSUPPORTED fail + endchoice + { curve } + close-elt + read-bits-open + dup { qlen } + dup addr-len-pkey_data rot < if + ERR_X509_LIMIT_EXCEEDED fail + then + read-blob + KEYTYPE_EC >pkey-type + enduf + + \ Not a recognised public key type. + ERR_X509_UNSUPPORTED fail + endchoice + close-elt + + \ Process public key. + ee if + \ For the EE certificate, copy the key data to the + \ relevant buffer. + pkey-type case + KEYTYPE_RSA of nlen elen copy-ee-rsa-pkey endof + KEYTYPE_EC of curve qlen copy-ee-ec-pkey endof + ERR_X509_UNSUPPORTED fail + endcase + else + \ Verify signature on previous certificate. We invoke + \ the RSA implementation. + pkey-type case + KEYTYPE_RSA of nlen elen do-rsa-vrfy endof + KEYTYPE_EC of curve qlen do-ecdsa-vrfy endof + ERR_X509_UNSUPPORTED fail + endcase + dup if fail then + drop + then + + \ This flag will be set to true if the Basic Constraints extension + \ is encountered. + 0 { seenBC } + + \ Skip issuerUniqueID and subjectUniqueID, and process extensions + \ if present. Extensions are an explicit context tag of value 3 + \ around a SEQUENCE OF extensions. Each extension is a SEQUENCE + \ with an OID, an optional boolean, and a value; the value is + \ an OCTET STRING. + read-tag-or-end + 0x21 iftag-skip + 0x22 iftag-skip + dup 0x23 = if + drop + check-constructed read-length-open-elt + read-sequence-open + begin dup while + 0 { critical } + read-sequence-open + read-OID drop + read-tag dup 0x01 = if + read-boolean >critical + read-tag + then + 0x04 check-tag-primitive read-length-open-elt + choice + \ Extensions with specific processing. + basicConstraints eqOID uf + ee if + skip-remaining + else + process-basicConstraints + -1 >seenBC + then + enduf + keyUsage eqOID uf + ee process-keyUsage + enduf + subjectAltName eqOID uf + ee if + 0 >eename + process-SAN >eename + else + skip-remaining + then + enduf + + \ We don't implement full processing of + \ policies. The call below mostly checks + \ that the contents of the Certificate + \ Policies extension can be safely ignored. + certificatePolicies eqOID uf + critical if + process-certPolicies + else + skip-remaining + then + enduf + + \ Extensions which are always ignored, + \ even if critical. + authorityKeyIdentifier eqOID uf + skip-remaining + enduf + subjectKeyIdentifier eqOID uf + skip-remaining + enduf + issuerAltName eqOID uf + skip-remaining + enduf + subjectDirectoryAttributes eqOID uf + skip-remaining + enduf + crlDistributionPoints eqOID uf + skip-remaining + enduf + freshestCRL eqOID uf + skip-remaining + enduf + authorityInfoAccess eqOID uf + skip-remaining + enduf + subjectInfoAccess eqOID uf + skip-remaining + enduf + + \ Unrecognized extensions trigger a failure + \ if critical; otherwise, they are just + \ ignored. + critical if + ERR_X509_CRITICAL_EXTENSION fail + then + skip-remaining + endchoice + close-elt + close-elt + repeat + close-elt + close-elt + else + -1 = ifnot ERR_X509_UNEXPECTED fail then + drop + then + + close-elt + \ Terminate hashing. + stop-tbs-hash + + \ For the EE certificate, verify that the intended server name + \ was matched. + ee if + eename zero-server-name or ifnot + ERR_X509_BAD_SERVER_NAME fail + then + then + + \ If this is the EE certificate, then direct trust may apply. + \ Note: we do this at this point, not immediately after decoding + \ the public key, because even in case of direct trust we still + \ want to check the server name with regards to the SAN extension. + \ However, we want to check direct trust before trying to decode + \ the signature algorithm, because it should work even if that + \ algorithm is not supported. + ee if check-direct-trust then + + \ Non-EE certificates MUST have a Basic Constraints extension + \ (that marks them as being CA). + ee seenBC or ifnot ERR_X509_NOT_CA fail then + + \ signature algorithm + read-tag check-sequence read-length-open-elt + \ Read and understand the OID. Right now, we support only + \ RSA with PKCS#1 v1.5 padding, and hash functions SHA-1, + \ SHA-224, SHA-256, SHA-384 and SHA-512. We purposely do NOT + \ support MD5 here. + \ TODO: add support for RSA/PSS + read-OID if + \ Based on the signature OID, we get: + \ -- the signing key type + \ -- the hash function numeric identifier + \ -- the hash function OID + choice + sha1WithRSAEncryption eqOID + uf 2 KEYTYPE_RSA id-sha1 enduf + sha224WithRSAEncryption eqOID + uf 3 KEYTYPE_RSA id-sha224 enduf + sha256WithRSAEncryption eqOID + uf 4 KEYTYPE_RSA id-sha256 enduf + sha384WithRSAEncryption eqOID + uf 5 KEYTYPE_RSA id-sha384 enduf + sha512WithRSAEncryption eqOID + uf 6 KEYTYPE_RSA id-sha512 enduf + + ecdsa-with-SHA1 eqOID + uf 2 KEYTYPE_EC id-sha1 enduf + ecdsa-with-SHA224 eqOID + uf 3 KEYTYPE_EC id-sha224 enduf + ecdsa-with-SHA256 eqOID + uf 4 KEYTYPE_EC id-sha256 enduf + ecdsa-with-SHA384 eqOID + uf 5 KEYTYPE_EC id-sha384 enduf + ecdsa-with-SHA512 eqOID + uf 6 KEYTYPE_EC id-sha512 enduf + ERR_X509_UNSUPPORTED fail + endchoice + addr-cert_sig_hash_oid set16 + addr-cert_signer_key_type set8 + + \ Compute the TBS hash into tbs_hash. + compute-tbs-hash + dup ifnot ERR_X509_UNSUPPORTED fail then + addr-cert_sig_hash_len set8 + else + ERR_X509_UNSUPPORTED fail + then + \ We ignore the parameters, whether they are present or not, + \ because we got all the information from the OID. + skip-close-elt + + \ signature value + read-bits-open + dup CX 0 8191 { BR_X509_BUFSIZE_SIG } > if + ERR_X509_LIMIT_EXCEEDED fail + then + dup addr-cert_sig_len set16 + addr-cert_sig read-blob + + \ Close the outer SEQUENCE. + close-elt + + \ Close the advertised total certificate length. This checks that + \ there is no trailing garbage after the certificate. + close-elt + + \ Flag the certificate as fully processed. + 0 addr-cert_length set32 + + \ Check whether the issuer for the current certificate is known + \ as a trusted CA; in which case, verify the signature. + check-trust-anchor-CA ; + +: main + \ Unless restricted by a Key Usage extension, all usages are + \ deemed allowed. + 0x30 addr-key_usages set8 + -1 decode-certificate + co + begin + 0 decode-certificate co + again + ; diff --git a/BearSSL-OG/libbearssl/src/x509/x509_minimal_full.c b/BearSSL-OG/libbearssl/src/x509/x509_minimal_full.c new file mode 100644 index 0000000..2b54426 --- /dev/null +++ b/BearSSL-OG/libbearssl/src/x509/x509_minimal_full.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "inner.h" + +/* see bearssl_x509.h */ +void +br_x509_minimal_init_full(br_x509_minimal_context *xc, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) +{ + /* + * All hash functions are activated. + * Note: the X.509 validation engine will nonetheless refuse to + * validate signatures that use MD5 as hash function. + */ + static const br_hash_class *hashes[] = { + &br_md5_vtable, + &br_sha1_vtable, + &br_sha224_vtable, + &br_sha256_vtable, + &br_sha384_vtable, + &br_sha512_vtable + }; + + int id; + + br_x509_minimal_init(xc, &br_sha256_vtable, + trust_anchors, trust_anchors_num); + br_x509_minimal_set_rsa(xc, &br_rsa_i31_pkcs1_vrfy); + br_x509_minimal_set_ecdsa(xc, + &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1); + for (id = br_md5_ID; id <= br_sha512_ID; id ++) { + const br_hash_class *hc; + + hc = hashes[id - 1]; + br_x509_minimal_set_hash(xc, id, hc); + } +} diff --git a/BearSSL-OG/main.cpp b/BearSSL-OG/main.cpp new file mode 100644 index 0000000..4a51d8e --- /dev/null +++ b/BearSSL-OG/main.cpp @@ -0,0 +1,63 @@ +#include "stdafx.h" + +#include "network_utility.h" +#include "client.h" +#include "server.h" +#include "debug_utility.h" +#include "data_store.h" + +bool mount_e_drive() +{ + char* mountPoint = "\\??\\E:"; + char* systemPath = "\\Device\\Harddisk0\\Partition1"; + STRING sMountPoint = {(USHORT)strlen(mountPoint), (USHORT)strlen(mountPoint) + 1, mountPoint}; + STRING sSystemPath = {(USHORT)strlen(systemPath), (USHORT)strlen(systemPath) + 1, systemPath}; + int result = IoCreateSymbolicLink(&sMountPoint, &sSystemPath); + return result == 0; +} + +void __cdecl main() +{ + if (network_utility::init() == false) + { + return; + } + + if (network_utility::wait_ready() == false) + { + return; + } + + mount_e_drive(); + + uint16_t port = 443; + + //const char* url = "https://codeload.github.com/Team-Resurgent/PrometheOS-Firmware/archive/refs/tags/V1.5.0.zip"; + const char* url = "https://codeload.github.com/Team-Resurgent/PrometheOS-Firmware/zip/refs/tags/V1.5.0"; + const char* file_path = "E:\\testfile.bin"; + + //With Redirect + //const char* url = "https://github.com/Team-Resurgent/Modxo/releases/download/V1.0.8/modxo_official_pico.bin"; + //const char* file_path = "E:\\modxo_official_pico.bin"; + + //Chunked (saves as webp) + //const char* url = "https://www.etechnophiles.com/wp-content/uploads/2021/02/pinout_923x768.jpg"; + //const char* file_path = "E:\\pinout_923x768.webp"; + + //Non Chunked + //const char* url = "https://download.winamp.com/winamp/winamp_latest_full.exe"; + //const char* file_path = "E:\\winamp_latest_full.exe"; + + client* client_instance = new client(); + //client_instance->download_file(url, port, file_path); + + server* server_instance = new server(); + server_instance->start(443); + + while (true) + { + Sleep(100); + } +} + + diff --git a/BearSSL-OG/main_test.cpp b/BearSSL-OG/main_test.cpp new file mode 100644 index 0000000..85add61 --- /dev/null +++ b/BearSSL-OG/main_test.cpp @@ -0,0 +1,132 @@ +// main_test.cpp - Test runner for SSL enhancements +// +// This is an alternative main() that runs the SSL test suite instead of +// the normal server/client operations. To use: +// +// Option 1: Rename this to main.cpp (backup original first) +// Option 2: Add a #define RUN_SSL_TESTS before including this +// Option 3: Copy the test call into your existing main.cpp +// +// Example usage in existing main.cpp: +// +// #include "ssl_test.h" +// +// void __cdecl main() +// { +// // ... network init code ... +// +// // Run SSL tests +// int failures = ssl_test::run_all_tests(); +// +// if (failures > 0) { +// debug_utility::debug_print("SSL tests had %d failures\n", failures); +// } +// +// // ... rest of your code ... +// } + +#include "stdafx.h" + +#include "network_utility.h" +#include "client.h" +#include "server.h" +#include "debug_utility.h" +#include "ssl_test.h" +#include "ssl_debug.h" + +bool mount_e_drive() +{ + char* mountPoint = "\\??\\E:"; + char* systemPath = "\\Device\\Harddisk0\\Partition1"; + STRING sMountPoint = {(USHORT)strlen(mountPoint), (USHORT)strlen(mountPoint) + 1, mountPoint}; + STRING sSystemPath = {(USHORT)strlen(systemPath), (USHORT)strlen(systemPath) + 1, systemPath}; + int result = IoCreateSymbolicLink(&sMountPoint, &sSystemPath); + return result == 0; +} + +void __cdecl main() +{ + debug_utility::debug_print("BearSSL-OG Test Runner\n"); + debug_utility::debug_print("======================\n\n"); + + // Initialize network + debug_utility::debug_print("Initializing network...\n"); + if (network_utility::init() == false) + { + debug_utility::debug_print("ERROR: Network init failed\n"); + return; + } + + debug_utility::debug_print("Waiting for network ready...\n"); + if (network_utility::wait_ready() == false) + { + debug_utility::debug_print("ERROR: Network not ready\n"); + return; + } + + debug_utility::debug_print("Network ready!\n"); + + // Mount E: drive for test files + if (mount_e_drive()) + { + debug_utility::debug_print("E: drive mounted\n"); + } + else + { + debug_utility::debug_print("WARNING: E: drive mount failed\n"); + } + + // Set default debug level + ssl_debug::set_level(SSL_DEBUG_INFO); + + // ========================================================================= + // RUN SSL TEST SUITE + // ========================================================================= + int failures = ssl_test::run_all_tests(); + + // ========================================================================= + // OPTIONAL: Run individual tests + // ========================================================================= + // Uncomment any of these to run specific tests: + // + // ssl_test_result r1 = ssl_test::test_basic_https_connection(); + // ssl_test::print_result(r1); + // + // ssl_test_result r2 = ssl_test::test_large_file_download(); + // ssl_test::print_result(r2); + // + // ssl_test_result r3 = ssl_test::test_session_resumption(); + // ssl_test::print_result(r3); + + // ========================================================================= + // OPTIONAL: Quick single download test + // ========================================================================= + // If you just want to test a single download: + // + // client* c = new client(); + // int result = c->download_file( + // "https://raw.githubusercontent.com/AbanteAI/rawdog/main/README.md", + // 443, + // "E:\\test_download.txt" + // ); + // debug_utility::debug_print("Download result: %d\n", result); + // delete c; + + // Report final status + debug_utility::debug_print("\n\n"); + if (failures == 0) + { + debug_utility::debug_print("*** ALL SSL TESTS PASSED ***\n"); + } + else + { + debug_utility::debug_print("*** %d SSL TEST(S) FAILED ***\n", failures); + } + + // Keep alive so output can be read + debug_utility::debug_print("\nTest complete. System will idle.\n"); + while (true) + { + Sleep(1000); + } +} diff --git a/BearSSL-OG/missing/stdint.h b/BearSSL-OG/missing/stdint.h new file mode 100644 index 0000000..04c3d22 --- /dev/null +++ b/BearSSL-OG/missing/stdint.h @@ -0,0 +1,213 @@ +#pragma once + +/* + * C99 stdint.h implementation for Xbox XDK (Visual Studio 2003) + * The Xbox XDK doesn't include this standard header. + * Some types may already be defined by XDK headers, so we guard against redefinition. + */ + +/* Exact-width integer types */ +#ifndef _INT8_T_DEFINED +typedef signed char int8_t; +#define _INT8_T_DEFINED +#endif + +#ifndef _INT16_T_DEFINED +typedef short int16_t; +#define _INT16_T_DEFINED +#endif + +#ifndef _INT32_T_DEFINED +typedef long int32_t; +#define _INT32_T_DEFINED +#endif + +#ifndef _INT64_T_DEFINED +typedef long long int64_t; +#define _INT64_T_DEFINED +#endif + +#ifndef _UINT8_T_DEFINED +typedef unsigned char uint8_t; +#define _UINT8_T_DEFINED +#endif + +#ifndef _UINT16_T_DEFINED +typedef unsigned short uint16_t; +#define _UINT16_T_DEFINED +#endif + +#ifndef _UINT32_T_DEFINED +typedef unsigned long uint32_t; +#define _UINT32_T_DEFINED +#endif + +#ifndef _UINT64_T_DEFINED +typedef unsigned long long uint64_t; +#define _UINT64_T_DEFINED +#endif + +/* Minimum-width integer types */ +#ifndef _INT_LEAST8_T_DEFINED +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; +#define _INT_LEAST8_T_DEFINED +#endif + +/* Fastest minimum-width integer types */ +#ifndef _INT_FAST8_T_DEFINED +typedef int32_t int_fast8_t; +typedef int32_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint32_t uint_fast8_t; +typedef uint32_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; +#define _INT_FAST8_T_DEFINED +#endif + +/* Integer types capable of holding object pointers */ +#ifndef _INTPTR_T_DEFINED +typedef long intptr_t; +#define _INTPTR_T_DEFINED +#endif + +#ifndef _UINTPTR_T_DEFINED +typedef unsigned long uintptr_t; +#define _UINTPTR_T_DEFINED +#endif + +/* Greatest-width integer types */ +#ifndef _INTMAX_T_DEFINED +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; +#define _INTMAX_T_DEFINED +#endif + +/* Signed integer type for size differences */ +#ifndef _SSIZE_T_DEFINED +typedef long ssize_t; +#define _SSIZE_T_DEFINED +#endif + +/* Limits of exact-width integer types */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT8_MAX +#define INT8_MAX 127 +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32768) +#endif +#ifndef INT16_MAX +#define INT16_MAX 32767 +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647L - 1) +#endif +#ifndef INT32_MAX +#define INT32_MAX 2147483647L +#endif +#ifndef INT64_MIN +#define INT64_MIN (-9223372036854775807LL - 1) +#endif +#ifndef INT64_MAX +#define INT64_MAX 9223372036854775807LL +#endif + +#ifndef UINT8_MAX +#define UINT8_MAX 255 +#endif +#ifndef UINT16_MAX +#define UINT16_MAX 65535 +#endif +#ifndef UINT32_MAX +#define UINT32_MAX 4294967295UL +#endif +#ifndef UINT64_MAX +#define UINT64_MAX 18446744073709551615ULL +#endif + +/* Limits of minimum-width integer types */ +#ifndef INT_LEAST8_MIN +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX +#endif + +/* Limits of fastest minimum-width integer types */ +#ifndef INT_FAST8_MIN +#define INT_FAST8_MIN INT32_MIN +#define INT_FAST8_MAX INT32_MAX +#define INT_FAST16_MIN INT32_MIN +#define INT_FAST16_MAX INT32_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT32_MAX +#define UINT_FAST16_MAX UINT32_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX +#endif + +/* Limits of integer types capable of holding object pointers */ +#ifndef INTPTR_MIN +#define INTPTR_MIN INT32_MIN +#endif +#ifndef INTPTR_MAX +#define INTPTR_MAX INT32_MAX +#endif +#ifndef UINTPTR_MAX +#define UINTPTR_MAX UINT32_MAX +#endif + +/* Limits of greatest-width integer types */ +#ifndef INTMAX_MIN +#define INTMAX_MIN INT64_MIN +#endif +#ifndef INTMAX_MAX +#define INTMAX_MAX INT64_MAX +#endif +#ifndef UINTMAX_MAX +#define UINTMAX_MAX UINT64_MAX +#endif + +/* Limits of other integer types */ +#ifndef SIZE_MAX +#define SIZE_MAX UINT32_MAX +#endif +#ifndef SSIZE_MAX +#define SSIZE_MAX INT32_MAX +#endif + +/* Macros for integer constant expressions */ +#ifndef INT8_C +#define INT8_C(x) (x) +#define INT16_C(x) (x) +#define INT32_C(x) (x ## L) +#define INT64_C(x) (x ## LL) +#define UINT8_C(x) (x) +#define UINT16_C(x) (x) +#define UINT32_C(x) (x ## UL) +#define UINT64_C(x) (x ## ULL) +#define INTMAX_C(x) INT64_C(x) +#define UINTMAX_C(x) UINT64_C(x) +#endif \ No newline at end of file diff --git a/BearSSL-OG/network_utility.cpp b/BearSSL-OG/network_utility.cpp new file mode 100644 index 0000000..565e7e2 --- /dev/null +++ b/BearSSL-OG/network_utility.cpp @@ -0,0 +1,127 @@ +#include "network_utility.h" + +#include +#include +#include + +#define RECV_SOCKET_BUFFER_SIZE_IN_K 64 +#define RECV_SOCKET_BUFFER_SIZE RECV_SOCKET_BUFFER_SIZE_IN_K * 1024 +#define SEND_SOCKET_BUFFER_SIZE_IN_K 64 +#define SEND_SOCKET_BUFFER_SIZE SEND_SOCKET_BUFFER_SIZE_IN_K * 1024 + +static bool initialized = false; + +bool network_utility::init() +{ + if (initialized == true) + { + return false; + } + + XNetStartupParams xnsp; + memset(&xnsp, 0, sizeof(xnsp)); + xnsp.cfgSizeOfStruct = sizeof(XNetStartupParams); + xnsp.cfgFlags = XNET_STARTUP_BYPASS_SECURITY; + + xnsp.cfgPrivatePoolSizeInPages = 64; + xnsp.cfgEnetReceiveQueueLength = 16; + xnsp.cfgIpFragMaxSimultaneous = 16; + xnsp.cfgIpFragMaxPacketDiv256 = 32; + xnsp.cfgSockMaxSockets = 64; + + xnsp.cfgSockDefaultRecvBufsizeInK = RECV_SOCKET_BUFFER_SIZE_IN_K; + xnsp.cfgSockDefaultSendBufsizeInK = SEND_SOCKET_BUFFER_SIZE_IN_K; + + int xnet_result = XNetStartup(&xnsp); + if (xnet_result != 0) + { + return false; + } + + WSADATA wsaData; + int result = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (result != 0) + { + return false; + } + initialized = true; + return true; +} + +bool network_utility::is_ready() +{ + if (initialized == false) + { + return false; + } + XNADDR addr; + memset(&addr, 0, sizeof(addr)); + DWORD dwState = XNetGetTitleXnAddr(&addr); + return dwState != XNET_GET_XNADDR_PENDING; +} + +bool network_utility::wait_ready() +{ + if (initialized == false) + { + return false; + } + while (is_ready() == false) + { + Sleep(1000); + } + return true; +} + +uint32_t network_utility::resolve_host(const char* host) +{ + return resolve_host_with_timeout(host, DNS_TIMEOUT_MS); +} + +uint32_t network_utility::resolve_host_with_timeout(const char* host, uint32_t timeout_ms) +{ + uint32_t result = 0; /* Return 0 (INADDR_ANY/invalid) on failure */ + XNDNS* dns = NULL; + WSAEVENT event_handle = NULL; + + /* Validate input */ + if (host == NULL || host[0] == '\0') + { + return 0; + } + + /* Create event for async DNS notification */ + event_handle = WSACreateEvent(); + if (event_handle == NULL) + { + return 0; + } + + /* Initiate DNS lookup */ + int error = XNetDnsLookup(host, event_handle, &dns); + if (error != 0) + { + WSACloseEvent(event_handle); + return 0; + } + + /* Wait for DNS response with timeout */ + DWORD wait_result = WaitForSingleObject(event_handle, timeout_ms); + WSACloseEvent(event_handle); + + /* Check if we timed out */ + if (wait_result == WAIT_TIMEOUT) + { + XNetDnsRelease(dns); + return 0; + } + + /* Check result and extract address */ + if (dns->iStatus == 0 && dns->cina > 0) + { + result = dns->aina[0].S_un.S_addr; + } + + XNetDnsRelease(dns); + return result; +} \ No newline at end of file diff --git a/BearSSL-OG/network_utility.h b/BearSSL-OG/network_utility.h new file mode 100644 index 0000000..ab966d6 --- /dev/null +++ b/BearSSL-OG/network_utility.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +/* Default DNS timeout in milliseconds (30 seconds) */ +#define DNS_TIMEOUT_MS 30000 + +class network_utility +{ +public: + static bool init(); + static bool is_ready(); + static bool wait_ready(); + static uint32_t resolve_host(const char* host); + static uint32_t resolve_host_with_timeout(const char* host, uint32_t timeout_ms); +}; diff --git a/BearSSL-OG/pointer_vector.h b/BearSSL-OG/pointer_vector.h new file mode 100644 index 0000000..a8c5a5a --- /dev/null +++ b/BearSSL-OG/pointer_vector.h @@ -0,0 +1,132 @@ +#pragma once + +#include +#include + +#define VECTOR_SIZE_INCREMENT 1024 + +template +class pointer_vector +{ +public: + + pointer_vector(bool useDelete) + { + mUseDelete = useDelete; + mSize = 0; + mValueContainers = (valueContainer*)malloc(sizeof(valueContainer) * VECTOR_SIZE_INCREMENT); + if (mValueContainers == NULL) + { + mMaxSize = 0; + return; + } + mMaxSize = VECTOR_SIZE_INCREMENT; + } + + ~pointer_vector() + { + for (uint32_t i = 0; i < mSize; i++) + { + if (mUseDelete == true) + { + delete(mValueContainers[i].value); + } + else + { + free(mValueContainers[i].value); + } + } + free(mValueContainers); + } + + void add(T1 value) + { + if (mSize == mMaxSize) + { + valueContainer* reallocedValueContainers = (valueContainer*)realloc(mValueContainers, sizeof(valueContainer) * (mMaxSize + VECTOR_SIZE_INCREMENT)); + if (reallocedValueContainers == NULL) + { + return; + } + mMaxSize += VECTOR_SIZE_INCREMENT; + mValueContainers = reallocedValueContainers; + } + + mValueContainers[mSize].value = value; + mSize++; + } + + T1 get(uint32_t index) + { + if (index >= mSize) + { + return NULL; + } + return mValueContainers[index].value; + } + + void remove(uint32_t index) + { + if (index >= mSize) + { + return; + } + if (mUseDelete == true) + { + delete(mValueContainers[index].value); + } + else + { + free(mValueContainers[index].value); + } + for (uint32_t j = index; j < mSize - 1; j++) + { + mValueContainers[j].value = mValueContainers[j + 1].value; + } + mSize--; + } + + void swap(uint32_t index1, uint32_t index2) + { + if (index1 >= mSize || index2 >= mSize) + { + return; + } + T1 temp = mValueContainers[index1].value; + mValueContainers[index1].value = mValueContainers[index2].value; + mValueContainers[index2].value = temp; + } + + uint32_t count() + { + return mSize; + } + + void clear() + { + for (uint32_t i = 0; i < mSize; i++) + { + if (mUseDelete == true) + { + delete(mValueContainers[i].value); + } + else + { + free(mValueContainers[i].value); + } + } + mSize = 0; + } + +private: + + typedef struct valueContainer { + T1 value; + } valueContainer; + + valueContainer* mValueContainers; + bool mUseDelete; + uint32_t mSize; + uint32_t mMaxSize; +}; + diff --git a/BearSSL-OG/server.cpp b/BearSSL-OG/server.cpp new file mode 100644 index 0000000..16a80b5 --- /dev/null +++ b/BearSSL-OG/server.cpp @@ -0,0 +1,326 @@ +#include "server.h" +#include "debug_utility.h" +#include "socket_utility.h" + +#include +#include +#include +#include +#include +#include "ssl_config.h" +#include "ssl_debug.h" + +#if !(SERVER_RSA || SERVER_EC || SERVER_MIXED) +#define SERVER_RSA 1 +#define SERVER_EC 0 +#define SERVER_MIXED 0 +#endif + +#if SERVER_RSA +#include "chain-rsa.h" +#include "key-rsa.h" +#define SKEY RSA +#elif SERVER_EC +#include "chain-ec.h" +#include "key-ec.h" +#define SKEY EC +#elif SERVER_MIXED +#include "chain-ec+rsa.h" +#include "key-ec.h" +#define SKEY EC +#else +#error Must use one of RSA, EC or MIXED chains. +#endif + + +#define MAX_NUM_THREADS 5 + +typedef struct { + int client_socket; + int thread_complete; + uint16_t port; +} thread_info_t; + +typedef struct { + int active; + thread_info_t data; + HANDLE thread; +} pthread_info_t; + +static pthread_info_t threads[MAX_NUM_THREADS]; +static volatile bool server_running = false; +static int listen_socket_global = INVALID_SOCKET; + +// Server session cache +static br_ssl_session_cache_lru server_session_cache; +static unsigned char server_session_cache_store[4096]; +static bool server_cache_initialized = false; + +static const char *HTTP_RES = + "HTTP/1.1 200 OK\r\n" + "Cache-Control: no-store, no-cache, must-revalidate\r\n" + "Pragma: no-cache\r\n" + "Expires: 0\r\n" + //"Content-Length: 46\r\n" + "Connection: close\r\n" + "Content-Type: text/html; charset=iso-8859-1\r\n" + "\r\n" + "" + "\r\n" + "\r\n" + "

BearSSL Test by EqUiNoX

Play Doom
\r\n" + "\r\n" + "\r\n"; + +static void init_server_session_cache() +{ + if (server_cache_initialized) return; + + br_ssl_session_cache_lru_init(&server_session_cache, + server_session_cache_store, + sizeof(server_session_cache_store)); + server_cache_initialized = true; + ssl_debug::log_verbose("Server session cache initialized\n"); +} + +static void client_process(void* data) +{ + thread_info_t *thread_info = (thread_info_t*)data; + + unsigned char io_buffer[BR_SSL_BUFSIZE_BIDI]; + + br_ssl_server_context server_context; + +#if SERVER_RSA /* RSA */ +#if SERVER_PROFILE_MIN_FS +#if SERVER_CHACHA20 + br_ssl_server_init_mine2c(&server_context, CHAIN, CHAIN_LEN, &SKEY); +#else + br_ssl_server_init_mine2g(&server_context, CHAIN, CHAIN_LEN, &SKEY); +#endif +#elif SERVER_PROFILE_MIN_NOFS + br_ssl_server_init_minr2g(&server_context, CHAIN, CHAIN_LEN, &SKEY); +#else + br_ssl_server_init_full_rsa(&server_context, CHAIN, CHAIN_LEN, &SKEY); +#endif +#elif SERVER_EC /* EC */ +#if SERVER_PROFILE_MIN_FS +#if SERVER_CHACHA20 + br_ssl_server_init_minf2c(&server_context, CHAIN, CHAIN_LEN, &SKEY); +#else + br_ssl_server_init_minf2g(&server_context, CHAIN, CHAIN_LEN, &SKEY); +#endif +#elif SERVER_PROFILE_MIN_NOFS + br_ssl_server_init_minv2g(&server_context, CHAIN, CHAIN_LEN, &SKEY); +#else + br_ssl_server_init_full_ec(&server_context, CHAIN, CHAIN_LEN, BR_KEYTYPE_EC, &SKEY); +#endif +#else /* SERVER_MIXED */ +#if SERVER_PROFILE_MIN_FS +#if SERVER_CHACHA20 + br_ssl_server_init_minf2c(&server_context, CHAIN, CHAIN_LEN, &SKEY); +#else + br_ssl_server_init_minf2g(&server_context, CHAIN, CHAIN_LEN, &SKEY); +#endif +#elif SERVER_PROFILE_MIN_NOFS + br_ssl_server_init_minu2g(&server_context, CHAIN, CHAIN_LEN, &SKEY); +#else + br_ssl_server_init_full_ec(&server_context, CHAIN, CHAIN_LEN, BR_KEYTYPE_RSA, &SKEY); +#endif +#endif + + // Enable session cache + init_server_session_cache(); + br_ssl_server_set_cache(&server_context, &server_session_cache.vtable); + + br_ssl_engine_set_buffer(&server_context.eng, io_buffer, BR_SSL_BUFSIZE_BIDI, 1); + br_ssl_server_reset(&server_context); + + // Enforce TLS 1.2 minimum +#if SSL_ENFORCE_TLS12 + br_ssl_engine_set_versions(&server_context.eng, SSL_MIN_VERSION, SSL_MAX_VERSION); +#endif + + br_sslio_context io_context; + br_sslio_init(&io_context, &server_context.eng, socket_utility::socket_read, &thread_info->client_socket, socket_utility::socket_write, &thread_info->client_socket); + + bool client_dropped = false; + + int feed_count = 0; + while (true) + { + unsigned char current_char; + if (br_sslio_read(&io_context, ¤t_char, 1) < 0) + { + client_dropped = true; + break; + } + if (current_char == 0x0D) + { + continue; + } + if (current_char == 0x0A) + { + if (feed_count == 1) + { + break; + } + feed_count = 1; + } + else + { + feed_count = 0; + } + } + + if (client_dropped == false) + { + br_sslio_write_all(&io_context, HTTP_RES, strlen(HTTP_RES)); + } + + int error = br_ssl_engine_last_error(&server_context.eng); + if (error == 0) + { + ssl_debug::log_info("Client connection closed cleanly\n"); + ssl_debug::log_handshake_result(&server_context.eng); + } + else + { + ssl_debug::log_ssl_error(error); + } + + br_sslio_close(&io_context); + closesocket(thread_info->client_socket); + + thread_info->thread_complete = 1; +} + +static uint64_t WINAPI process(void* data) +{ + uint16_t port = (uint16_t)data; + + int listen_socket = socket_utility::host_bind(port); + if (listen_socket == INVALID_SOCKET) + { + server_running = false; + return EXIT_FAILURE; + } + + listen_socket_global = listen_socket; + + while (server_running) + { + int read_status = socket_utility::get_read_status(listen_socket); + if (read_status == SOCKET_ERROR) + { + break; + } + + int client_socket = INVALID_SOCKET; + if (read_status == 1) + { + client_socket = socket_utility::accept_client(listen_socket); + } + else + { + Sleep(50); + continue; + } + + if (client_socket == INVALID_SOCKET) + { + continue; + } + + int i; + for (i = 0; i < MAX_NUM_THREADS; i++) + { + if (threads[i].active == 0) + { + break; + } + if (threads[i].data.thread_complete == 1) + { + CloseHandle(threads[i].thread); + memset(&threads[i], 0, sizeof(pthread_info_t)); + break; + } + } + + if (i == MAX_NUM_THREADS) + { + closesocket(client_socket); + continue; + } + + threads[i].active = 1; + threads[i].data.client_socket = client_socket; + threads[i].data.port = port; + threads[i].thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)client_process, (void*)&threads[i].data, 0, NULL); + } + + closesocket(listen_socket); + listen_socket_global = INVALID_SOCKET; + + return 0; +} + + +server::server() + : thread(NULL), running(false) +{ +} + +void server::start(uint16_t port) +{ + memset(threads, 0, sizeof(threads)); + running = true; + server_running = true; + thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)process, (void*)port, 0, NULL); +} + +void server::stop() +{ + if (!running) + { + return; + } + + running = false; + server_running = false; + + // Close the listening socket to unblock accept + if (listen_socket_global != INVALID_SOCKET) + { + closesocket(listen_socket_global); + } + + // Wait for the main server thread to finish + if (thread != NULL) + { + WaitForSingleObject(thread, 5000); + CloseHandle(thread); + thread = NULL; + } + + // Wait for all client threads to complete + for (int i = 0; i < MAX_NUM_THREADS; i++) + { + if (threads[i].active && threads[i].thread != NULL) + { + WaitForSingleObject(threads[i].thread, 2000); + CloseHandle(threads[i].thread); + } + } + + memset(threads, 0, sizeof(threads)); +} + +bool server::is_running() +{ + return running; +} + + + + diff --git a/BearSSL-OG/server.h b/BearSSL-OG/server.h new file mode 100644 index 0000000..c90a3ba --- /dev/null +++ b/BearSSL-OG/server.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +class server +{ +public: + server(); + void start(uint16_t port); + void stop(); + bool is_running(); +private: + HANDLE thread; + volatile bool running; +}; diff --git a/BearSSL-OG/session_cache.cpp b/BearSSL-OG/session_cache.cpp new file mode 100644 index 0000000..2322495 --- /dev/null +++ b/BearSSL-OG/session_cache.cpp @@ -0,0 +1,153 @@ +#include "session_cache.h" +#include "ssl_debug.h" + +#include +#include + +// KeQuerySystemTime is exported by the Xbox kernel (xboxkrnl.lib) +#ifdef __cplusplus +extern "C" +#endif +void WINAPI KeQuerySystemTime(PLARGE_INTEGER CurrentTime); + +session_cache::session_entry session_cache::entries[SESSION_CACHE_SIZE]; +bool session_cache::initialized = false; + +void session_cache::initialize() +{ + if (initialized) return; + + memset(entries, 0, sizeof(entries)); + initialized = true; + ssl_debug::log_verbose("Session cache initialized (%d slots)\n", SESSION_CACHE_SIZE); +} + +void session_cache::shutdown() +{ + clear(); + initialized = false; +} + +uint32_t session_cache::get_current_time() +{ + LARGE_INTEGER system_time; + KeQuerySystemTime(&system_time); + // Convert 100-nanosecond intervals to seconds + return (uint32_t)(system_time.QuadPart / 10000000ULL); +} + +int session_cache::find_entry(const char* hostname) +{ + for (int i = 0; i < SESSION_CACHE_SIZE; i++) { + if (entries[i].valid && strcmp(entries[i].hostname, hostname) == 0) { + return i; + } + } + return -1; +} + +int session_cache::find_free_slot() +{ + uint32_t current_time = get_current_time(); + int oldest_idx = -1; + uint32_t oldest_time = 0xFFFFFFFF; + + for (int i = 0; i < SESSION_CACHE_SIZE; i++) { + // Free slot + if (!entries[i].valid) { + return i; + } + + // Expired entry - reuse it + if (current_time - entries[i].timestamp > SESSION_MAX_AGE_SECONDS) { + entries[i].valid = false; + return i; + } + + // Track oldest for LRU eviction + if (entries[i].timestamp < oldest_time) { + oldest_time = entries[i].timestamp; + oldest_idx = i; + } + } + + // Evict oldest entry + if (oldest_idx >= 0) { + ssl_debug::log_verbose("Session cache: evicting entry for %s\n", entries[oldest_idx].hostname); + entries[oldest_idx].valid = false; + return oldest_idx; + } + + return 0; // Fallback to first slot +} + +bool session_cache::get(const char* hostname, br_ssl_session_parameters* params) +{ + if (!initialized) initialize(); + + int idx = find_entry(hostname); + if (idx < 0) { + ssl_debug::log_verbose("Session cache: miss for %s\n", hostname); + return false; + } + + uint32_t current_time = get_current_time(); + if (current_time - entries[idx].timestamp > SESSION_MAX_AGE_SECONDS) { + ssl_debug::log_verbose("Session cache: expired entry for %s\n", hostname); + entries[idx].valid = false; + return false; + } + + /* Update timestamp on access for proper LRU eviction */ + entries[idx].timestamp = current_time; + memcpy(params, &entries[idx].params, sizeof(br_ssl_session_parameters)); + ssl_debug::log_info("Session cache: hit for %s\n", hostname); + return true; +} + +void session_cache::store(const char* hostname, const br_ssl_session_parameters* params) +{ + if (!initialized) initialize(); + + // Don't cache if no session ID and no session ticket + if (params->session_id_len == 0 && params->session_ticket_len == 0) { + return; + } + + int idx = find_entry(hostname); + if (idx < 0) { + idx = find_free_slot(); + } + + strncpy(entries[idx].hostname, hostname, 255); + entries[idx].hostname[255] = '\0'; + memcpy(&entries[idx].params, params, sizeof(br_ssl_session_parameters)); + entries[idx].timestamp = get_current_time(); + entries[idx].valid = true; + + ssl_debug::log_info("Session cache: stored session for %s\n", hostname); +} + +void session_cache::remove(const char* hostname) +{ + int idx = find_entry(hostname); + if (idx >= 0) { + entries[idx].valid = false; + ssl_debug::log_verbose("Session cache: removed entry for %s\n", hostname); + } +} + +void session_cache::clear() +{ + memset(entries, 0, sizeof(entries)); + ssl_debug::log_verbose("Session cache: cleared\n"); +} + +int session_cache::get_count() +{ + int count = 0; + for (int i = 0; i < SESSION_CACHE_SIZE; i++) { + if (entries[i].valid) count++; + } + return count; +} diff --git a/BearSSL-OG/session_cache.h b/BearSSL-OG/session_cache.h new file mode 100644 index 0000000..3411892 --- /dev/null +++ b/BearSSL-OG/session_cache.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +#define SESSION_CACHE_SIZE 8 +#define SESSION_MAX_AGE_SECONDS 3600 + +class session_cache +{ +public: + static void initialize(); + static void shutdown(); + + static bool get(const char* hostname, br_ssl_session_parameters* params); + static void store(const char* hostname, const br_ssl_session_parameters* params); + static void remove(const char* hostname); + static void clear(); + + static int get_count(); + +private: + struct session_entry { + char hostname[256]; + br_ssl_session_parameters params; + uint32_t timestamp; + bool valid; + }; + + static session_entry entries[SESSION_CACHE_SIZE]; + static bool initialized; + + static int find_entry(const char* hostname); + static int find_free_slot(); + static uint32_t get_current_time(); +}; diff --git a/BearSSL-OG/socket_utility.cpp b/BearSSL-OG/socket_utility.cpp new file mode 100644 index 0000000..1a4120f --- /dev/null +++ b/BearSSL-OG/socket_utility.cpp @@ -0,0 +1,160 @@ +#include "socket_utility.h" + +#include +#include +#include + +int socket_utility::connect_to_host(uint32_t host_ip, uint16_t port) +{ + sockaddr_in server_addr; + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + server_addr.sin_addr.S_un.S_addr = host_ip; + + int32_t connect_socket = socket(AF_INET, SOCK_STREAM, 0); + if (connect_socket == INVALID_SOCKET) + { + return -1; + } + + if (connect(connect_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) + { + closesocket(connect_socket); + return -1; + } + + return connect_socket; +} + +int socket_utility::host_bind(uint16_t port) +{ + int32_t bind_socket = socket(AF_INET, SOCK_STREAM, 0); + if (bind_socket == INVALID_SOCKET) + { + return -1; + } + + uint32_t reuse = 1; + if (setsockopt(bind_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse)) < 0) + { + closesocket(bind_socket); + return -1; + } + + uint32_t non_blocking = 1; + if (ioctlsocket((SOCKET)bind_socket, FIONBIO, &non_blocking) == SOCKET_ERROR) + { + closesocket(bind_socket); + return -1; + } + + SOCKADDR_IN address_in; + memset(&address_in, 0, sizeof(SOCKADDR_IN)); + address_in.sin_addr.s_addr = INADDR_ANY; + address_in.sin_family = AF_INET; + address_in.sin_port = htons(port); + + if (bind(bind_socket, (struct sockaddr *)&address_in, sizeof(address_in)) == SOCKET_ERROR) + { + closesocket(bind_socket); + return -1; + } + + if (listen(bind_socket, 5) < 0) + { + closesocket(bind_socket); + return -1; + } + + return bind_socket; +} + +int socket_utility::get_read_status(int socket) +{ + static const timeval instantSpeedPlease = { 0,0 }; + fd_set a = { 1, {(SOCKET)socket} }; + + int result = select(0, &a, 0, 0, &instantSpeedPlease); + if (result == SOCKET_ERROR) + { + result = WSAGetLastError(); + } + + if (result != 0 && result != 1) + { + return SOCKET_ERROR; + } + return result; +} + +int socket_utility::accept_client(int server_socket) +{ + sockaddr sock_addr; + int sock_addr_length = sizeof(sock_addr); + int32_t socket = accept(server_socket, &sock_addr, &sock_addr_length); + if (socket == INVALID_SOCKET) + { + return -1; + } + return socket; +} + +int socket_utility::socket_read(void *context, unsigned char *buffer, size_t length) +{ + int socket = *(int *)context; + + struct timeval tv; + fd_set read_fds; + + + while (true) + { + FD_ZERO(&read_fds ); + FD_SET(socket, &read_fds ); + + tv.tv_sec = 2; + tv.tv_usec = 0; + + int ret = select(socket, &read_fds, NULL, NULL, &tv ); + if( ret == 0 ) + { + return -1; + } + + int recv_len = (length > 0x7FFFFFFF) ? 0x7FFFFFFF : (int)length; + int bytes_read = recv(socket, (char *)buffer, recv_len, 0); + if (bytes_read == SOCKET_ERROR) + { + if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK) + { + continue; + } + return -1; + } + if (bytes_read == 0) + { + return 0; + } + return bytes_read; + } +} + +int socket_utility::socket_write(void *context, const unsigned char *buffer, size_t length) +{ + while (true) + { + int socket = *(int *)context; + int send_len = (length > 0x7FFFFFFF) ? 0x7FFFFFFF : (int)length; + int bytes_written = send(socket, (const char *)buffer, send_len, 0); + if (bytes_written == SOCKET_ERROR) + { + if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK) + { + continue; + } + return -1; + } + return bytes_written; + } +} \ No newline at end of file diff --git a/BearSSL-OG/socket_utility.h b/BearSSL-OG/socket_utility.h new file mode 100644 index 0000000..9f98652 --- /dev/null +++ b/BearSSL-OG/socket_utility.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +class socket_utility +{ +public: + static int connect_to_host(uint32_t host_ip, uint16_t port); + static int host_bind(uint16_t port); + static int get_read_status(int socket); + static int accept_client(int server_socket); + static int socket_read(void *context, unsigned char *buffer, size_t length); + static int socket_write(void *context, const unsigned char *buffer, size_t length); +}; diff --git a/BearSSL-OG/ssl_config.h b/BearSSL-OG/ssl_config.h new file mode 100644 index 0000000..8678c9b --- /dev/null +++ b/BearSSL-OG/ssl_config.h @@ -0,0 +1,30 @@ +#pragma once + +// TLS Version Configuration +#define SSL_MIN_VERSION BR_TLS12 +#define SSL_MAX_VERSION BR_TLS12 + +// Secure cipher suites (ECDHE + AEAD only) +static const uint16_t SSL_SECURE_SUITES[] = { + BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 +}; + +#define SSL_SECURE_SUITES_COUNT 6 + +// Feature flags +#define SSL_ENFORCE_TLS12 1 +#define SSL_RESTRICT_CIPHERS 1 +#define SSL_ENABLE_SESSION_CACHE 1 + +// Set to 1 to enable certificate pinning verification +#define SSL_ENABLE_CERT_PINNING 0 + +// Default CA bundle file path on Xbox HDD +// T:\ maps to E:\TDATA\\ (title-persistent storage) +// Place cacert.pem at E:\TDATA\\cacert.pem on the Xbox HDD +#define SSL_DEFAULT_CA_FILE "T:\\cacert.pem" diff --git a/BearSSL-OG/ssl_debug.cpp b/BearSSL-OG/ssl_debug.cpp new file mode 100644 index 0000000..569437d --- /dev/null +++ b/BearSSL-OG/ssl_debug.cpp @@ -0,0 +1,147 @@ +#include "ssl_debug.h" +#include "ssl_errors.h" +#include "debug_utility.h" + +#include +#include +#include + +ssl_debug_level ssl_debug::current_level = SSL_DEBUG_ERROR; + +void ssl_debug::set_level(ssl_debug_level level) +{ + current_level = level; +} + +ssl_debug_level ssl_debug::get_level() +{ + return current_level; +} + +void ssl_debug::log_error(const char* format, ...) +{ + if (current_level < SSL_DEBUG_ERROR) return; + + debug_utility::debug_print("[SSL ERROR] "); + va_list args; + va_start(args, format); + char buffer[256]; + _vsnprintf(buffer, sizeof(buffer) - 1, format, args); + buffer[sizeof(buffer) - 1] = '\0'; + va_end(args); + debug_utility::debug_print("%s", buffer); +} + +void ssl_debug::log_info(const char* format, ...) +{ + if (current_level < SSL_DEBUG_INFO) return; + + debug_utility::debug_print("[SSL] "); + va_list args; + va_start(args, format); + char buffer[256]; + _vsnprintf(buffer, sizeof(buffer) - 1, format, args); + buffer[sizeof(buffer) - 1] = '\0'; + va_end(args); + debug_utility::debug_print("%s", buffer); +} + +void ssl_debug::log_verbose(const char* format, ...) +{ + if (current_level < SSL_DEBUG_VERBOSE) return; + + debug_utility::debug_print("[SSL DEBUG] "); + va_list args; + va_start(args, format); + char buffer[256]; + _vsnprintf(buffer, sizeof(buffer) - 1, format, args); + buffer[sizeof(buffer) - 1] = '\0'; + va_end(args); + debug_utility::debug_print("%s", buffer); +} + +const char* ssl_debug::version_to_string(unsigned version) +{ + switch (version) { + case BR_TLS10: return "TLS 1.0"; + case BR_TLS11: return "TLS 1.1"; + case BR_TLS12: return "TLS 1.2"; + default: return "Unknown"; + } +} + +const char* ssl_debug::cipher_suite_to_string(uint16_t suite) +{ + switch (suite) { + case BR_TLS_RSA_WITH_AES_128_CBC_SHA: + return "RSA-AES128-CBC-SHA"; + case BR_TLS_RSA_WITH_AES_256_CBC_SHA: + return "RSA-AES256-CBC-SHA"; + case BR_TLS_RSA_WITH_AES_128_CBC_SHA256: + return "RSA-AES128-CBC-SHA256"; + case BR_TLS_RSA_WITH_AES_256_CBC_SHA256: + return "RSA-AES256-CBC-SHA256"; + case BR_TLS_RSA_WITH_AES_128_GCM_SHA256: + return "RSA-AES128-GCM-SHA256"; + case BR_TLS_RSA_WITH_AES_256_GCM_SHA384: + return "RSA-AES256-GCM-SHA384"; + case BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + return "ECDHE-RSA-AES128-CBC-SHA"; + case BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + return "ECDHE-RSA-AES256-CBC-SHA"; + case BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + return "ECDHE-RSA-AES128-CBC-SHA256"; + case BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + return "ECDHE-RSA-AES256-CBC-SHA384"; + case BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + return "ECDHE-RSA-AES128-GCM-SHA256"; + case BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + return "ECDHE-RSA-AES256-GCM-SHA384"; + case BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + return "ECDHE-RSA-CHACHA20-POLY1305"; + case BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + return "ECDHE-ECDSA-AES128-GCM-SHA256"; + case BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + return "ECDHE-ECDSA-AES256-GCM-SHA384"; + case BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + return "ECDHE-ECDSA-CHACHA20-POLY1305"; + default: + return "Unknown"; + } +} + +void ssl_debug::log_handshake_result(br_ssl_engine_context* engine) +{ + if (current_level < SSL_DEBUG_INFO) return; + + unsigned version = br_ssl_engine_get_version(engine); + log_info("Handshake complete\n"); + log_info(" Version: %s\n", version_to_string(version)); + + br_ssl_session_parameters params; + br_ssl_engine_get_session_parameters(engine, ¶ms); + log_info(" Cipher: %s\n", cipher_suite_to_string(params.cipher_suite)); + log_info(" Session resumed: %s\n", params.session_id_len > 0 ? "yes" : "no"); +} + +void ssl_debug::log_ssl_error(int error) +{ + if (error == 0) return; + + log_error("SSL error %d: %s\n", error, ssl_errors::error_to_string(error)); + + if (error >= 256 && error < 512) { + int alert = error - 256; + log_error(" Alert: %s\n", ssl_errors::alert_to_string(alert)); + } +} + +void ssl_debug::log_peer_certificate(br_ssl_engine_context* engine) +{ + // Note: BearSSL does not provide a direct API to retrieve the peer certificate + // chain after handshake completion. Certificate inspection would require + // custom X.509 callbacks during validation. This function is a placeholder. + if (current_level < SSL_DEBUG_VERBOSE) return; + log_verbose("Certificate inspection not available (requires X.509 callback)\n"); + (void)engine; // Suppress unused parameter warning +} diff --git a/BearSSL-OG/ssl_debug.h b/BearSSL-OG/ssl_debug.h new file mode 100644 index 0000000..a3541ac --- /dev/null +++ b/BearSSL-OG/ssl_debug.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +enum ssl_debug_level { + SSL_DEBUG_NONE = 0, + SSL_DEBUG_ERROR = 1, + SSL_DEBUG_INFO = 2, + SSL_DEBUG_VERBOSE = 3 +}; + +class ssl_debug +{ +public: + static void set_level(ssl_debug_level level); + static ssl_debug_level get_level(); + + static void log_error(const char* format, ...); + static void log_info(const char* format, ...); + static void log_verbose(const char* format, ...); + + static void log_handshake_result(br_ssl_engine_context* engine); + static void log_ssl_error(int error); + static void log_peer_certificate(br_ssl_engine_context* engine); + + static const char* version_to_string(unsigned version); + static const char* cipher_suite_to_string(uint16_t suite); + +private: + static ssl_debug_level current_level; +}; diff --git a/BearSSL-OG/ssl_errors.cpp b/BearSSL-OG/ssl_errors.cpp new file mode 100644 index 0000000..a72a52c --- /dev/null +++ b/BearSSL-OG/ssl_errors.cpp @@ -0,0 +1,73 @@ +#include "ssl_errors.h" +#include + +const char* ssl_errors::error_to_string(int error) +{ + switch (error) { + case BR_ERR_OK: return "Success"; + case BR_ERR_BAD_PARAM: return "Bad parameter"; + case BR_ERR_BAD_STATE: return "Invalid state"; + case BR_ERR_UNSUPPORTED_VERSION: return "Unsupported TLS version"; + case BR_ERR_BAD_VERSION: return "Bad TLS version"; + case BR_ERR_TOO_LARGE: return "Record too large"; + case BR_ERR_BAD_MAC: return "MAC verification failed"; + case BR_ERR_NO_RANDOM: return "No random seed"; + case BR_ERR_UNKNOWN_TYPE: return "Unknown record type"; + case BR_ERR_UNEXPECTED: return "Unexpected message"; + case BR_ERR_BAD_CCS: return "Bad ChangeCipherSpec"; + case BR_ERR_BAD_ALERT: return "Bad alert"; + case BR_ERR_BAD_HANDSHAKE: return "Bad handshake message"; + case BR_ERR_OVERSIZED_ID: return "Oversized ID"; + case BR_ERR_BAD_CIPHER_SUITE: return "Bad cipher suite"; + case BR_ERR_BAD_COMPRESSION: return "Bad compression"; + case BR_ERR_BAD_FRAGLEN: return "Bad fragment length"; + case BR_ERR_BAD_SECRENEG: return "Bad secure renegotiation"; + case BR_ERR_EXTRA_EXTENSION: return "Extra extension"; + case BR_ERR_BAD_SNI: return "Bad SNI"; + case BR_ERR_BAD_HELLO_DONE: return "Bad HelloDone"; + case BR_ERR_LIMIT_EXCEEDED: return "Limit exceeded"; + case BR_ERR_BAD_FINISHED: return "Bad Finished message"; + case BR_ERR_RESUME_MISMATCH: return "Session resume mismatch"; + case BR_ERR_INVALID_ALGORITHM: return "Invalid algorithm"; + case BR_ERR_BAD_SIGNATURE: return "Bad signature"; + case BR_ERR_WRONG_KEY_USAGE: return "Wrong key usage"; + case BR_ERR_NO_CLIENT_AUTH: return "No client auth"; + case BR_ERR_IO: return "I/O error"; + default: + if (error >= 256 && error < 512) + return "Received fatal alert from server"; + if (error >= 512) + return "Sent fatal alert to server"; + return "Unknown SSL error"; + } +} + +const char* ssl_errors::alert_to_string(int alert_code) +{ + switch (alert_code) { + case 0: return "close_notify"; + case 10: return "unexpected_message"; + case 20: return "bad_record_mac"; + case 21: return "decryption_failed"; + case 22: return "record_overflow"; + case 30: return "decompression_failure"; + case 40: return "handshake_failure"; + case 42: return "bad_certificate"; + case 43: return "unsupported_certificate"; + case 44: return "certificate_revoked"; + case 45: return "certificate_expired"; + case 46: return "certificate_unknown"; + case 47: return "illegal_parameter"; + case 48: return "unknown_ca"; + case 49: return "access_denied"; + case 50: return "decode_error"; + case 51: return "decrypt_error"; + case 70: return "protocol_version"; + case 71: return "insufficient_security"; + case 80: return "internal_error"; + case 90: return "user_canceled"; + case 100: return "no_renegotiation"; + case 110: return "unsupported_extension"; + default: return "unknown_alert"; + } +} diff --git a/BearSSL-OG/ssl_errors.h b/BearSSL-OG/ssl_errors.h new file mode 100644 index 0000000..d764b85 --- /dev/null +++ b/BearSSL-OG/ssl_errors.h @@ -0,0 +1,8 @@ +#pragma once + +class ssl_errors +{ +public: + static const char* error_to_string(int error); + static const char* alert_to_string(int alert_code); +}; diff --git a/BearSSL-OG/ssl_test.cpp b/BearSSL-OG/ssl_test.cpp new file mode 100644 index 0000000..a56e708 --- /dev/null +++ b/BearSSL-OG/ssl_test.cpp @@ -0,0 +1,574 @@ +#include "ssl_test.h" +#include "client.h" +#include "ssl_debug.h" +#include "session_cache.h" +#include "debug_utility.h" + +#include +#include +#include + +// KeQuerySystemTime is exported by the Xbox kernel (xboxkrnl.lib) +#ifdef __cplusplus +extern "C" +#endif +void WINAPI KeQuerySystemTime(PLARGE_INTEGER CurrentTime); + +// Test file paths on Xbox E: drive +#define TEST_FILE_SMALL "E:\\ssl_test_small.bin" +#define TEST_FILE_LARGE "E:\\ssl_test_large.bin" +#define TEST_FILE_REDIRECT "E:\\ssl_test_redirect.bin" +#define TEST_FILE_CHUNKED "E:\\ssl_test_chunked.bin" +#define TEST_FILE_RESUME "E:\\ssl_test_resume.bin" + +// Test URLs - using reliable public HTTPS endpoints +// Small file test - GitHub raw file +#define URL_SMALL "https://raw.githubusercontent.com/AbanteAI/rawdog/main/README.md" + +// Larger file test - Known firmware download +#define URL_LARGE "https://codeload.github.com/Team-Resurgent/PrometheOS-Firmware/zip/refs/tags/V1.5.0" + +// Redirect test - GitHub releases redirect +#define URL_REDIRECT "https://github.com/Team-Resurgent/Modxo/releases/download/V1.0.8/modxo_official_pico.bin" + +// Chunked transfer test - use httpbin which returns chunked encoding +#define URL_CHUNKED "https://httpbin.org/stream/5" + +// Alternate host test - non-GitHub server +#define URL_ALTERNATE "https://httpbin.org/get" +#define TEST_FILE_ALTERNATE "E:\\ssl_test_alternate.bin" + +uint32_t ssl_test::get_time_ms() +{ + LARGE_INTEGER system_time; + KeQuerySystemTime(&system_time); + return (uint32_t)(system_time.QuadPart / 10000ULL); +} + +bool ssl_test::file_exists(const char* path) +{ + FILE* f = fopen(path, "rb"); + if (f != NULL) { + fclose(f); + return true; + } + return false; +} + +int64_t ssl_test::get_file_size(const char* path) +{ + FILE* f = fopen(path, "rb"); + if (f == NULL) return -1; + + fseek(f, 0, SEEK_END); + int64_t size = ftell(f); + fclose(f); + return size; +} + +void ssl_test::delete_file(const char* path) +{ + DeleteFile(path); +} + +void ssl_test::print_result(const ssl_test_result& result) +{ + const char* status; + switch (result.result) { + case SSL_TEST_PASS: status = "PASS"; break; + case SSL_TEST_FAIL: status = "FAIL"; break; + case SSL_TEST_SKIP: status = "SKIP"; break; + default: status = "????"; break; + } + + debug_utility::debug_print("\n[%s] %s\n", status, result.test_name); + + if (result.message != NULL && result.message[0] != '\0') { + debug_utility::debug_print(" %s\n", result.message); + } + + if (result.bytes_downloaded > 0) { + debug_utility::debug_print(" Downloaded: %lld bytes\n", result.bytes_downloaded); + } + + if (result.time_ms > 0) { + debug_utility::debug_print(" Time: %u ms\n", result.time_ms); + } +} + +void ssl_test::print_summary(int passed, int failed, int skipped) +{ + debug_utility::debug_print("\n"); + debug_utility::debug_print("==========================================\n"); + debug_utility::debug_print("SSL TEST SUMMARY\n"); + debug_utility::debug_print("==========================================\n"); + debug_utility::debug_print("Passed: %d\n", passed); + debug_utility::debug_print("Failed: %d\n", failed); + debug_utility::debug_print("Skipped: %d\n", skipped); + debug_utility::debug_print("Total: %d\n", passed + failed + skipped); + debug_utility::debug_print("==========================================\n"); + + if (failed == 0) { + debug_utility::debug_print("ALL TESTS PASSED!\n"); + } else { + debug_utility::debug_print("SOME TESTS FAILED - check results above\n"); + } + debug_utility::debug_print("==========================================\n"); +} + +// ============================================================================= +// TEST: Basic HTTPS Connection +// ============================================================================= +ssl_test_result ssl_test::test_basic_https_connection() +{ + ssl_test_result result; + result.test_name = "Basic HTTPS Connection"; + result.message = ""; + result.bytes_downloaded = 0; + result.time_ms = 0; + + debug_utility::debug_print("\n--- Running: %s ---\n", result.test_name); + + // Clean up any previous test file + delete_file(TEST_FILE_SMALL); + + // Set debug level to see handshake info + ssl_debug::set_level(SSL_DEBUG_INFO); + + uint32_t start_time = get_time_ms(); + + client* c = new client(); + int ret = c->download_file(URL_SMALL, 443, TEST_FILE_SMALL); + delete c; + + result.time_ms = get_time_ms() - start_time; + + if (ret == 0) { + if (file_exists(TEST_FILE_SMALL)) { + result.bytes_downloaded = get_file_size(TEST_FILE_SMALL); + if (result.bytes_downloaded > 0) { + result.result = SSL_TEST_PASS; + result.message = "Successfully connected and downloaded file"; + } else { + result.result = SSL_TEST_FAIL; + result.message = "File created but empty"; + } + } else { + result.result = SSL_TEST_FAIL; + result.message = "Download returned success but file not found"; + } + } else { + result.result = SSL_TEST_FAIL; + result.message = "Download failed - check SSL debug output above"; + } + + // Clean up + delete_file(TEST_FILE_SMALL); + + return result; +} + +// ============================================================================= +// TEST: Large File Download +// ============================================================================= +ssl_test_result ssl_test::test_large_file_download() +{ + ssl_test_result result; + result.test_name = "Large File Download (PrometheOS zip)"; + result.message = ""; + result.bytes_downloaded = 0; + result.time_ms = 0; + + debug_utility::debug_print("\n--- Running: %s ---\n", result.test_name); + + delete_file(TEST_FILE_LARGE); + + ssl_debug::set_level(SSL_DEBUG_INFO); + + uint32_t start_time = get_time_ms(); + + client* c = new client(); + int ret = c->download_file(URL_LARGE, 443, TEST_FILE_LARGE); + delete c; + + result.time_ms = get_time_ms() - start_time; + + if (ret == 0) { + if (file_exists(TEST_FILE_LARGE)) { + result.bytes_downloaded = get_file_size(TEST_FILE_LARGE); + // PrometheOS zip should be at least 100KB + if (result.bytes_downloaded > 100000) { + result.result = SSL_TEST_PASS; + result.message = "Large file downloaded successfully"; + } else { + result.result = SSL_TEST_FAIL; + result.message = "File too small - possible incomplete download"; + } + } else { + result.result = SSL_TEST_FAIL; + result.message = "File not created"; + } + } else { + result.result = SSL_TEST_FAIL; + result.message = "Download failed"; + } + + delete_file(TEST_FILE_LARGE); + + return result; +} + +// ============================================================================= +// TEST: Redirect Handling +// ============================================================================= +ssl_test_result ssl_test::test_redirect_handling() +{ + ssl_test_result result; + result.test_name = "HTTP Redirect Handling"; + result.message = ""; + result.bytes_downloaded = 0; + result.time_ms = 0; + + debug_utility::debug_print("\n--- Running: %s ---\n", result.test_name); + + delete_file(TEST_FILE_REDIRECT); + + ssl_debug::set_level(SSL_DEBUG_INFO); + + uint32_t start_time = get_time_ms(); + + client* c = new client(); + int ret = c->download_file(URL_REDIRECT, 443, TEST_FILE_REDIRECT); + delete c; + + result.time_ms = get_time_ms() - start_time; + + if (ret == 0) { + if (file_exists(TEST_FILE_REDIRECT)) { + result.bytes_downloaded = get_file_size(TEST_FILE_REDIRECT); + if (result.bytes_downloaded > 0) { + result.result = SSL_TEST_PASS; + result.message = "Redirect followed and file downloaded"; + } else { + result.result = SSL_TEST_FAIL; + result.message = "File empty after redirect"; + } + } else { + result.result = SSL_TEST_FAIL; + result.message = "File not created after redirect"; + } + } else { + result.result = SSL_TEST_FAIL; + result.message = "Download with redirect failed"; + } + + delete_file(TEST_FILE_REDIRECT); + + return result; +} + +// ============================================================================= +// TEST: Chunked Transfer Encoding +// ============================================================================= +ssl_test_result ssl_test::test_chunked_transfer() +{ + ssl_test_result result; + result.test_name = "Chunked Transfer Encoding"; + result.message = ""; + result.bytes_downloaded = 0; + result.time_ms = 0; + + debug_utility::debug_print("\n--- Running: %s ---\n", result.test_name); + + delete_file(TEST_FILE_CHUNKED); + + ssl_debug::set_level(SSL_DEBUG_INFO); + + uint32_t start_time = get_time_ms(); + + client* c = new client(); + int ret = c->download_file(URL_CHUNKED, 443, TEST_FILE_CHUNKED); + delete c; + + result.time_ms = get_time_ms() - start_time; + + if (ret == 0) { + if (file_exists(TEST_FILE_CHUNKED)) { + result.bytes_downloaded = get_file_size(TEST_FILE_CHUNKED); + if (result.bytes_downloaded > 0) { + result.result = SSL_TEST_PASS; + result.message = "Chunked transfer handled correctly"; + } else { + result.result = SSL_TEST_FAIL; + result.message = "File empty"; + } + } else { + result.result = SSL_TEST_FAIL; + result.message = "File not created"; + } + } else { + // Chunked might fail gracefully with some servers + result.result = SSL_TEST_FAIL; + result.message = "Chunked download failed"; + } + + delete_file(TEST_FILE_CHUNKED); + + return result; +} + +// ============================================================================= +// TEST: Session Resumption +// ============================================================================= +ssl_test_result ssl_test::test_session_resumption() +{ + ssl_test_result result; + result.test_name = "TLS Session Resumption"; + result.message = ""; + result.bytes_downloaded = 0; + result.time_ms = 0; + + debug_utility::debug_print("\n--- Running: %s ---\n", result.test_name); + + // Clear session cache first + session_cache::clear(); + + ssl_debug::set_level(SSL_DEBUG_INFO); + + delete_file(TEST_FILE_RESUME); + + // First connection - should establish new session + debug_utility::debug_print("First connection (new session)...\n"); + uint32_t start1 = get_time_ms(); + + client* c1 = new client(); + int ret1 = c1->download_file(URL_SMALL, 443, TEST_FILE_RESUME); + delete c1; + + uint32_t time1 = get_time_ms() - start1; + + if (ret1 != 0) { + result.result = SSL_TEST_FAIL; + result.message = "First connection failed"; + return result; + } + + // Check if session was cached + int cache_count = session_cache::get_count(); + debug_utility::debug_print("Sessions in cache: %d\n", cache_count); + + delete_file(TEST_FILE_RESUME); + + // Second connection - should resume session + debug_utility::debug_print("Second connection (should resume)...\n"); + uint32_t start2 = get_time_ms(); + + client* c2 = new client(); + int ret2 = c2->download_file(URL_SMALL, 443, TEST_FILE_RESUME); + delete c2; + + uint32_t time2 = get_time_ms() - start2; + + result.time_ms = time1 + time2; + + if (ret2 == 0) { + result.bytes_downloaded = get_file_size(TEST_FILE_RESUME); + + // Session resumption should make second connection faster + // (though this is not guaranteed due to network variability) + debug_utility::debug_print("First connection: %u ms\n", time1); + debug_utility::debug_print("Second connection: %u ms\n", time2); + + if (cache_count > 0) { + result.result = SSL_TEST_PASS; + result.message = "Session cached and second connection succeeded"; + } else { + result.result = SSL_TEST_PASS; + result.message = "Connections succeeded (server may not support resumption)"; + } + } else { + result.result = SSL_TEST_FAIL; + result.message = "Second connection failed"; + } + + delete_file(TEST_FILE_RESUME); + + return result; +} + +// ============================================================================= +// TEST: Invalid Host (Error Handling) +// ============================================================================= +ssl_test_result ssl_test::test_invalid_host() +{ + ssl_test_result result; + result.test_name = "Invalid Host Error Handling"; + result.message = ""; + result.bytes_downloaded = 0; + result.time_ms = 0; + + debug_utility::debug_print("\n--- Running: %s ---\n", result.test_name); + + ssl_debug::set_level(SSL_DEBUG_ERROR); + + uint32_t start_time = get_time_ms(); + + // Try to connect to a non-existent host + client* c = new client(); + int ret = c->download_file("https://this-host-does-not-exist-12345.invalid/test.bin", 443, "E:\\invalid.bin"); + delete c; + + result.time_ms = get_time_ms() - start_time; + + // This SHOULD fail - that's what we're testing + if (ret != 0) { + result.result = SSL_TEST_PASS; + result.message = "Correctly failed on invalid host"; + } else { + result.result = SSL_TEST_FAIL; + result.message = "Should have failed but returned success"; + } + + delete_file("E:\\invalid.bin"); + + return result; +} + +// ============================================================================= +// TEST: TLS Version Enforcement +// ============================================================================= +ssl_test_result ssl_test::test_tls_version_enforcement() +{ + ssl_test_result result; + result.test_name = "TLS 1.2 Enforcement"; + result.message = ""; + result.bytes_downloaded = 0; + result.time_ms = 0; + + debug_utility::debug_print("\n--- Running: %s ---\n", result.test_name); + + // This test verifies that connections work with TLS 1.2 + // Most modern servers support TLS 1.2, so if our enforcement is correct, + // connections should succeed. If we had wrongly configured TLS 1.0 only, + // modern servers might reject us. + + ssl_debug::set_level(SSL_DEBUG_INFO); + + delete_file(TEST_FILE_SMALL); + + uint32_t start_time = get_time_ms(); + + client* c = new client(); + int ret = c->download_file(URL_SMALL, 443, TEST_FILE_SMALL); + delete c; + + result.time_ms = get_time_ms() - start_time; + + if (ret == 0 && file_exists(TEST_FILE_SMALL)) { + result.bytes_downloaded = get_file_size(TEST_FILE_SMALL); + result.result = SSL_TEST_PASS; + result.message = "TLS 1.2 connection successful (check log for version)"; + } else { + result.result = SSL_TEST_FAIL; + result.message = "TLS 1.2 connection failed - check cipher/version compatibility"; + } + + delete_file(TEST_FILE_SMALL); + + return result; +} + +// ============================================================================= +// TEST: Alternate Host Connection +// ============================================================================= +ssl_test_result ssl_test::test_alternate_host() +{ + ssl_test_result result; + result.test_name = "Alternate Host (httpbin.org)"; + result.message = ""; + result.bytes_downloaded = 0; + result.time_ms = 0; + + debug_utility::debug_print("\n--- Running: %s ---\n", result.test_name); + + delete_file(TEST_FILE_ALTERNATE); + + ssl_debug::set_level(SSL_DEBUG_INFO); + + uint32_t start_time = get_time_ms(); + + client* c = new client(); + int ret = c->download_file(URL_ALTERNATE, 443, TEST_FILE_ALTERNATE); + delete c; + + result.time_ms = get_time_ms() - start_time; + + if (ret == 0) { + if (file_exists(TEST_FILE_ALTERNATE)) { + result.bytes_downloaded = get_file_size(TEST_FILE_ALTERNATE); + if (result.bytes_downloaded > 0) { + result.result = SSL_TEST_PASS; + result.message = "Non-GitHub host connection successful"; + } else { + result.result = SSL_TEST_FAIL; + result.message = "File created but empty"; + } + } else { + result.result = SSL_TEST_FAIL; + result.message = "File not created"; + } + } else { + result.result = SSL_TEST_FAIL; + result.message = "Connection to alternate host failed"; + } + + delete_file(TEST_FILE_ALTERNATE); + + return result; +} + +// ============================================================================= +// RUN ALL TESTS +// ============================================================================= +int ssl_test::run_all_tests() +{ + debug_utility::debug_print("\n"); + debug_utility::debug_print("==========================================\n"); + debug_utility::debug_print("BearSSL-OG SSL/TLS TEST SUITE\n"); + debug_utility::debug_print("==========================================\n"); + debug_utility::debug_print("Testing HTTPS client functionality after\n"); + debug_utility::debug_print("SSL enhancements (TLS 1.2, ciphers, etc.)\n"); + debug_utility::debug_print("==========================================\n"); + + int passed = 0; + int failed = 0; + int skipped = 0; + + ssl_test_result results[8]; + + // Run all tests + results[0] = test_basic_https_connection(); + results[1] = test_tls_version_enforcement(); + results[2] = test_session_resumption(); + results[3] = test_redirect_handling(); + results[4] = test_chunked_transfer(); + results[5] = test_alternate_host(); + results[6] = test_invalid_host(); + results[7] = test_large_file_download(); + + // Print results and count + for (int i = 0; i < 8; i++) { + print_result(results[i]); + + switch (results[i].result) { + case SSL_TEST_PASS: passed++; break; + case SSL_TEST_FAIL: failed++; break; + case SSL_TEST_SKIP: skipped++; break; + } + } + + // Print summary + print_summary(passed, failed, skipped); + + return failed; +} diff --git a/BearSSL-OG/ssl_test.h b/BearSSL-OG/ssl_test.h new file mode 100644 index 0000000..4c22f3f --- /dev/null +++ b/BearSSL-OG/ssl_test.h @@ -0,0 +1,44 @@ +#pragma once + +#include + +// Test result codes +#define SSL_TEST_PASS 0 +#define SSL_TEST_FAIL 1 +#define SSL_TEST_SKIP 2 + +// Test result structure +struct ssl_test_result { + const char* test_name; + int result; + const char* message; + int64_t bytes_downloaded; + uint32_t time_ms; +}; + +class ssl_test +{ +public: + // Run all tests and print summary + static int run_all_tests(); + + // Individual tests + static ssl_test_result test_basic_https_connection(); + static ssl_test_result test_large_file_download(); + static ssl_test_result test_redirect_handling(); + static ssl_test_result test_chunked_transfer(); + static ssl_test_result test_session_resumption(); + static ssl_test_result test_invalid_host(); + static ssl_test_result test_tls_version_enforcement(); + static ssl_test_result test_alternate_host(); + + // Utility + static void print_result(const ssl_test_result& result); + static void print_summary(int passed, int failed, int skipped); + +private: + static uint32_t get_time_ms(); + static bool file_exists(const char* path); + static int64_t get_file_size(const char* path); + static void delete_file(const char* path); +}; diff --git a/BearSSL-OG/stdafx.cpp b/BearSSL-OG/stdafx.cpp new file mode 100644 index 0000000..e73396f --- /dev/null +++ b/BearSSL-OG/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// XboxOGBearSSL.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/BearSSL-OG/stdafx.h b/BearSSL-OG/stdafx.h new file mode 100644 index 0000000..0454862 --- /dev/null +++ b/BearSSL-OG/stdafx.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +typedef struct STRING { + uint16_t Length; + uint16_t MaximumLength; + char* Buffer; +} STRING; + +extern "C" +{ + LONG WINAPI IoCreateSymbolicLink(STRING*, STRING*); +} diff --git a/BearSSL-OG/string_utility.cpp b/BearSSL-OG/string_utility.cpp new file mode 100644 index 0000000..842e356 --- /dev/null +++ b/BearSSL-OG/string_utility.cpp @@ -0,0 +1,239 @@ +#include "string_utility.h" +#include "pointer_vector.h" + +#include +#include +#include + +/* MSVC 7.1 lacks va_copy. On x86, va_list is a char* passed by value, + so a plain assignment creates an independent copy. */ +#ifndef va_copy +#define va_copy(dest, src) ((dest) = (src)) +#endif + +char* string_utility::format_string(const char* format, ...) +{ + va_list args, args_copy; + va_start(args, format); + va_copy(args_copy, args); + + uint32_t length = _vsnprintf(NULL, 0, format, args_copy); + va_end(args_copy); + + char* result = (char*)malloc(length + 1); + if (result == NULL) + { + va_end(args); + return NULL; + } + _vsnprintf(result, length + 1, format, args); + result[length] = 0; + + va_end(args); + return result; +} + +char* string_utility::strtok_r(char* str, const char* delimiters, char** save_ptr) +{ + char* token; + + if (str == NULL) + { + str = *save_ptr; + } + + if (*str == '\0') + { + *save_ptr = str; + return NULL; + } + + str += strspn(str, delimiters); + + if (*str == '\0') + { + *save_ptr = str; + return NULL; + } + + token = str + strcspn(str, delimiters); + if (*token == '\0') + { + *save_ptr = token; + return str; + } + + *token = '\0'; + *save_ptr = token + 1; + return str; +} + +char* string_utility::left_trim(const char* value, const char trim_char) +{ + uint32_t offset = 0; + while(value[offset] == trim_char && value[offset] != 0) + { + offset++; + } + + uint32_t length = strlen(value) - offset; + + char* result = (char*)malloc(length + 1); + if (result == NULL) + { + return NULL; + } + + strncpy(result, value + offset, length); + result[length] = 0; + return result; +} + +char* string_utility::right_trim(const char* value, const char trim_char) +{ + if (value == NULL) return NULL; + + int32_t length = strlen(value); + + while(length > 0 && value[length - 1] == trim_char) + { + length--; + } + + char* result = (char*)malloc(length + 1); + if (result == NULL) + { + return NULL; + } + + strncpy(result, value, length); + result[length] = 0; + return result; +} + +char* string_utility::trim(const char* value, const char trim_char) +{ + char* leftTrimmed = left_trim(value, trim_char); + char* trimmed = right_trim(leftTrimmed, trim_char); + free(leftTrimmed); + return trimmed; +} + +pointer_vector* string_utility::split(const char* value, const char* delimiter, bool trim_values) +{ + pointer_vector* result = new pointer_vector(false); + + char* value_copy = strdup(value); + char* position = value_copy; + char* token = strtok_r(value_copy, delimiter, &position); + while (token != NULL) + { + char* value_to_add = trim_values == true ? trim(token, ' ') : strdup(token); + result->add(value_to_add); + token = strtok_r(NULL, delimiter, &position); + } + + free(value_copy); + return result; +} + +pointer_vector* string_utility::split_first(const char* value, const char* delimiter, bool trim_values) +{ + pointer_vector* result = new pointer_vector(false); + + char* str = new char[strlen(value) + 1]; + strcpy(str, value); + + char* save_ptr = NULL; + char* first_part = string_utility::strtok_r(str, delimiter, &save_ptr); + char* second_part = string_utility::strtok_r(NULL, "", &save_ptr); + + if (first_part != NULL) + { + result->add(trim_values ? trim(first_part, ' ') : strdup(first_part)); + } + + if (second_part != NULL) + { + result->add(trim_values ? trim(second_part, ' ') : strdup(second_part)); + } + + delete[] str; + + return result; +} + +int64_t string_utility::string_to_int64(const char* string) +{ + int64_t result = 0; + if (string == NULL) + { + return result; + } + + bool is_negative = false; + if (*string == '-') + { + is_negative = true; + string++; + } + + while (*string != '\0') + { + if (*string < '0' || *string > '9') + { + break; + } + result = result * 10 + (*string - '0'); + string++; + } + + return is_negative ? -result : result; +} + +int64_t string_utility::hex_to_int64(const char* hex) +{ + int64_t result = 0; + + while (*hex != '\0') + { + char c = *hex; + result *= 16; + + if (c >= '0' && c <= '9') + { + result += c - '0'; + } + else if (c >= 'A' && c <= 'F') + { + result += c - 'A' + 10; + } + else if (c >= 'a' && c <= 'f') + { + result += c - 'a' + 10; + } + else + { + return -1; + } + + ++hex; + } + return result; +} + +int string_utility::find_crlf(unsigned char* buffer, uint32_t length) +{ + if (buffer == NULL || length < 2) + { + return -1; + } + for (uint32_t i = 0; i < length - 1; ++i) + { + if (buffer[i] == '\r' && buffer[i + 1] == '\n') + { + return i; + } + } + return -1; +} diff --git a/BearSSL-OG/string_utility.h b/BearSSL-OG/string_utility.h new file mode 100644 index 0000000..8bb4e82 --- /dev/null +++ b/BearSSL-OG/string_utility.h @@ -0,0 +1,18 @@ +#pragma once + +#include "pointer_vector.h" + +class string_utility +{ +public: + static char* format_string(const char* format, ...); + static char* strtok_r(char* str, const char* delimiters, char** save_ptr); + static char* left_trim(const char* value, const char trim_char); + static char* right_trim(const char* value, const char trim_char); + static char* trim(const char* value, const char trim_char); + static pointer_vector* split(const char* value, const char* delimiter, bool trim_values); + static pointer_vector* split_first(const char* value, const char* delimiter, bool trim_values); + static int64_t string_to_int64(const char* string); + static int64_t hex_to_int64(const char* hex); + static int find_crlf(unsigned char* buffer, uint32_t length); +}; diff --git a/BearSSL-OG/trust_anchors.h b/BearSSL-OG/trust_anchors.h new file mode 100644 index 0000000..9ee13fb --- /dev/null +++ b/BearSSL-OG/trust_anchors.h @@ -0,0 +1,33591 @@ +#pragma once + +static const unsigned char TA0_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x36 +}; + +static const unsigned char TA0_RSA_N[] = { + 0xAC, 0xAC, 0x74, 0x32, 0xE8, 0xB3, 0x65, 0xE5, 0xBA, 0xED, 0x43, 0x26, + 0x1D, 0xA6, 0x89, 0x0D, 0x45, 0xBA, 0x29, 0x88, 0xB2, 0xA4, 0x1D, 0x63, + 0xDD, 0xD3, 0xC1, 0x2C, 0x09, 0x57, 0x89, 0x39, 0xA1, 0x55, 0xE9, 0x67, + 0x34, 0x77, 0x0C, 0x6E, 0xE4, 0x55, 0x1D, 0x52, 0x25, 0xD2, 0x13, 0x6B, + 0x5E, 0xE1, 0x1D, 0xA9, 0xB7, 0x7D, 0x89, 0x32, 0x5F, 0x0D, 0x9E, 0x9F, + 0x2C, 0x7A, 0x63, 0x60, 0x40, 0x1F, 0xA6, 0xB0, 0xB6, 0x78, 0x8F, 0x99, + 0x54, 0x96, 0x08, 0x58, 0xAE, 0xE4, 0x06, 0xBC, 0x62, 0x05, 0x02, 0x16, + 0xBF, 0xAF, 0xA8, 0x23, 0x03, 0xB6, 0x94, 0x0F, 0xBC, 0x6E, 0x6C, 0xC2, + 0xCB, 0xD5, 0xA6, 0xBB, 0x0C, 0xE9, 0xF6, 0xC1, 0x02, 0xFB, 0x21, 0xDE, + 0x66, 0xDD, 0x17, 0xAB, 0x74, 0x42, 0xEF, 0xF0, 0x74, 0x2F, 0x25, 0xF4, + 0xEA, 0x6B, 0x55, 0x5B, 0x90, 0xDB, 0x9D, 0xDF, 0x5E, 0x87, 0x0A, 0x40, + 0xFB, 0xAD, 0x19, 0x6B, 0xFB, 0xF7, 0xCA, 0x60, 0x88, 0xDE, 0xDA, 0xC1, + 0x8F, 0xD6, 0xAE, 0xD5, 0x7F, 0xD4, 0x3C, 0x83, 0xEE, 0xD7, 0x16, 0x4C, + 0x83, 0x45, 0x33, 0x6B, 0x27, 0xD0, 0x86, 0xD0, 0x1C, 0x2D, 0x6B, 0xF3, + 0xAB, 0x7D, 0xF1, 0x85, 0xA9, 0xF5, 0x28, 0xD2, 0xAD, 0xEF, 0xF3, 0x84, + 0x4B, 0x1C, 0x87, 0xFC, 0x13, 0xA3, 0x3A, 0x72, 0xA2, 0x5A, 0x11, 0x2B, + 0xD6, 0x27, 0x71, 0x27, 0xED, 0x81, 0x2D, 0x6D, 0x66, 0x81, 0x92, 0x87, + 0xB4, 0x1B, 0x58, 0x7A, 0xCC, 0x3F, 0x0A, 0xFA, 0x46, 0x4F, 0x4D, 0x78, + 0x5C, 0xF8, 0x2B, 0x48, 0xE3, 0x04, 0x84, 0xCB, 0x5D, 0xF6, 0xB4, 0x6A, + 0xB3, 0x65, 0xFC, 0x42, 0x9E, 0x51, 0x26, 0x23, 0x20, 0xCB, 0x3D, 0x14, + 0xF9, 0x81, 0xED, 0x65, 0x16, 0x00, 0x4F, 0x1A, 0x64, 0x97, 0x66, 0x08, + 0xCF, 0x8C, 0x7B, 0xE3, 0x2B, 0xC0, 0x9D, 0xF9, 0x14, 0xF2, 0x1B, 0xF1, + 0x56, 0x6A, 0x16, 0xBF, 0x2C, 0x85, 0x85, 0xCD, 0x78, 0x38, 0x9A, 0xEB, + 0x42, 0x6A, 0x02, 0x34, 0x18, 0x83, 0x17, 0x4E, 0x94, 0x56, 0xF8, 0xB6, + 0x82, 0xB5, 0xF3, 0x96, 0xDD, 0x3D, 0xF3, 0xBE, 0x7F, 0x20, 0x77, 0x3E, + 0x7B, 0x19, 0x23, 0x6B, 0x2C, 0xD4, 0x72, 0x73, 0x43, 0x57, 0x7D, 0xE0, + 0xF8, 0xD7, 0x69, 0x4F, 0x17, 0x36, 0x04, 0xF9, 0xC0, 0x90, 0x60, 0x37, + 0x45, 0xDE, 0xE6, 0x0C, 0xD8, 0x74, 0x8D, 0xAE, 0x9C, 0xA2, 0x6D, 0x74, + 0x5D, 0x42, 0xBE, 0x06, 0xF5, 0xD9, 0x64, 0x6E, 0x02, 0x10, 0xAC, 0x89, + 0xB0, 0x4C, 0x3B, 0x07, 0x4D, 0x40, 0x7E, 0x24, 0xC5, 0x8A, 0x98, 0x82, + 0x79, 0x8E, 0xA4, 0xA7, 0x82, 0x20, 0x8D, 0x23, 0xFA, 0x27, 0x71, 0xC9, + 0xDF, 0xC6, 0x41, 0x74, 0xA0, 0x4D, 0xF6, 0x91, 0x16, 0xDC, 0x46, 0x8C, + 0x5F, 0x29, 0x63, 0x31, 0x59, 0x71, 0x0C, 0xD8, 0x6F, 0xC2, 0xB6, 0x32, + 0x7D, 0xFB, 0xE6, 0x5D, 0x53, 0xA6, 0x7E, 0x15, 0xFC, 0xBB, 0x75, 0x7C, + 0x5D, 0xEC, 0xF8, 0xF6, 0x17, 0x1C, 0xEC, 0xC7, 0x6B, 0x19, 0xCB, 0xF3, + 0x7B, 0xF0, 0x2B, 0x07, 0xA5, 0xD9, 0x6C, 0x79, 0x54, 0x76, 0x6C, 0x9D, + 0x1C, 0xA6, 0x6E, 0x0E, 0xE9, 0x79, 0x0C, 0xA8, 0x23, 0x6A, 0xA3, 0xDF, + 0x1B, 0x30, 0x31, 0x9F, 0xB1, 0x54, 0x7B, 0xFE, 0x6A, 0xCB, 0x66, 0xAA, + 0xDC, 0x65, 0xD0, 0xA2, 0x9E, 0x4A, 0x9A, 0x07, 0x21, 0x6B, 0x81, 0x8F, + 0xDB, 0xC4, 0x59, 0xFA, 0xDE, 0x22, 0xC0, 0x04, 0x9C, 0xE3, 0xAA, 0x5B, + 0x36, 0x93, 0xE8, 0x3D, 0xBD, 0x7A, 0xA1, 0x9D, 0x0B, 0x76, 0xB1, 0x0B, + 0xC7, 0x9D, 0xFD, 0xCF, 0x98, 0xA8, 0x06, 0xC2, 0xF8, 0x2A, 0xA3, 0xA1, + 0x83, 0xA0, 0xB7, 0x25, 0x72, 0xA5, 0x02, 0xE3 +}; + +static const unsigned char TA0_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA1_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA1_EC_Q[] = { + 0x04, 0xD4, 0xBC, 0x3D, 0x02, 0x42, 0x75, 0x41, 0x13, 0x23, 0xCD, 0x80, + 0x04, 0x86, 0x02, 0x51, 0x2F, 0x6A, 0xA8, 0x81, 0x62, 0x0B, 0x65, 0xCC, + 0xF6, 0xCA, 0x9D, 0x1E, 0x6F, 0x4A, 0x66, 0x51, 0xA2, 0x03, 0xD9, 0x9D, + 0x91, 0xFA, 0xB6, 0x16, 0xB1, 0x8C, 0x6E, 0xDE, 0x7C, 0xCD, 0xDB, 0x79, + 0xA6, 0x2F, 0xCE, 0xBB, 0xCE, 0x71, 0x2F, 0xE5, 0xA5, 0xAB, 0x28, 0xEC, + 0x63, 0x04, 0x66, 0x99, 0xF8, 0xFA, 0xF2, 0x93, 0x10, 0x05, 0xE1, 0x81, + 0x28, 0x42, 0xE3, 0xC6, 0x68, 0xF4, 0xE6, 0x1B, 0x84, 0x60, 0x4A, 0x89, + 0xAF, 0xED, 0x79, 0x0F, 0x3B, 0xCE, 0xF1, 0xF6, 0x44, 0xF5, 0x01, 0x78, + 0xC0 +}; + +static const unsigned char TA2_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x31 +}; + +static const unsigned char TA2_RSA_N[] = { + 0xF1, 0x66, 0x08, 0xBD, 0xD9, 0xC5, 0x15, 0x61, 0xCB, 0x84, 0x04, 0x41, + 0xA5, 0x69, 0x37, 0x77, 0x1D, 0xC1, 0xB0, 0x7B, 0xFA, 0xC3, 0x77, 0x48, + 0x90, 0x13, 0x72, 0x64, 0xD1, 0xB8, 0x7C, 0x90, 0x35, 0x9D, 0x18, 0x79, + 0x88, 0xE3, 0x97, 0x01, 0x3C, 0x47, 0x81, 0xF2, 0x0E, 0xA2, 0x98, 0x0D, + 0x9E, 0x3F, 0x37, 0xE0, 0x19, 0xB2, 0x90, 0xF2, 0x46, 0x1C, 0x92, 0xB1, + 0x3A, 0x61, 0xCE, 0xFA, 0xB7, 0x46, 0x9E, 0x03, 0x86, 0xD7, 0x33, 0x6E, + 0xED, 0xF7, 0x45, 0x8C, 0x76, 0x37, 0xDE, 0x6E, 0x96, 0x91, 0xF7, 0xD7, + 0x7E, 0x2B, 0x87, 0x17, 0xD5, 0x8B, 0x35, 0xEE, 0x84, 0x91, 0x72, 0x57, + 0xDC, 0x60, 0xC3, 0xC3, 0xB9, 0xE7, 0xC7, 0x67, 0x24, 0x23, 0x4F, 0x63, + 0x0A, 0x63, 0xF6, 0x66, 0x7D, 0x4B, 0x55, 0xA7, 0x3F, 0x78, 0x64, 0x49, + 0x69, 0x12, 0x97, 0xE0, 0x4C, 0x0D, 0xD3, 0x09, 0xA0, 0x32, 0x30, 0x3A, + 0xFA, 0x9F, 0xC0, 0xF2, 0x9C, 0xC5, 0x12, 0x2A, 0x2E, 0x1C, 0xB5, 0x04, + 0x33, 0xDA, 0xA4, 0x38, 0x11, 0x6A, 0xDE, 0xC6, 0x18, 0xF6, 0x47, 0x3A, + 0x22, 0x41, 0x87, 0x22, 0xFC, 0xC4, 0x89, 0x28, 0x54, 0xD8, 0x8C, 0xA5, + 0x30, 0x0A, 0xF8, 0x17, 0x16, 0xCA, 0xAC, 0x37, 0xFD, 0x79, 0xA7, 0x91, + 0x17, 0x78, 0x38, 0x99, 0xAD, 0x58, 0xED, 0xB2, 0xDE, 0xCC, 0x89, 0x7D, + 0x03, 0x9C, 0xB3, 0x89, 0x65, 0xE7, 0xE3, 0x3B, 0xB1, 0x22, 0x86, 0x8F, + 0x06, 0x6D, 0x78, 0x07, 0xFD, 0x91, 0x12, 0x7F, 0xB0, 0x6B, 0x1C, 0x89, + 0x0D, 0xF9, 0xB8, 0xCB, 0x74, 0x5B, 0x07, 0xC2, 0xC8, 0xF4, 0x35, 0xD1, + 0x64, 0x63, 0x7A, 0xE9, 0x6E, 0x9A, 0x28, 0xD6, 0x30, 0xBD, 0xE6, 0x1B, + 0xDD, 0x15, 0xAF, 0x84, 0xEA, 0x9C, 0xC7, 0xCA, 0xF5, 0x0E, 0xEA, 0xF2, + 0x5D, 0x29, 0x87, 0x8F, 0x69, 0x73, 0x39, 0xBE, 0x2E, 0x24, 0x6F, 0x45, + 0x21, 0xAC, 0xC5, 0xD4, 0x69, 0x25, 0x06, 0x83, 0xAD, 0x7A, 0x48, 0x85, + 0x13, 0x2C, 0x0D, 0x06, 0xB8, 0x6C, 0x79, 0x56, 0xFC, 0xA3, 0x67, 0x32, + 0x81, 0xF5, 0x57, 0xA5, 0xCA, 0x57, 0x42, 0x69, 0xE9, 0x5C, 0x24, 0x61, + 0xEF, 0xE2, 0x30, 0x18, 0x4E, 0x44, 0x98, 0x55, 0x6F, 0x7A, 0xC2, 0x93, + 0xD8, 0x19, 0xB6, 0xDE, 0x7C, 0x47, 0x8A, 0x11, 0x4E, 0x49, 0x47, 0xDB, + 0x28, 0x94, 0x02, 0x0B, 0x94, 0x4A, 0x2C, 0xF9, 0x12, 0xD0, 0x4F, 0xE8, + 0x31, 0x7E, 0x6C, 0x7A, 0xBF, 0xA6, 0x3F, 0x9B, 0x39, 0x3D, 0x02, 0x16, + 0xA3, 0x18, 0xB3, 0x67, 0xAC, 0x5B, 0x3F, 0x2C, 0x83, 0x2B, 0x67, 0x39, + 0x81, 0x5C, 0xB9, 0x7E, 0x94, 0xD5, 0x64, 0xDD, 0x9E, 0x8F, 0x6E, 0xAE, + 0xE8, 0x7C, 0x5B, 0xB4, 0xD7, 0x6A, 0x47, 0x48, 0xD7, 0x7E, 0xB3, 0xD4, + 0x2D, 0x8E, 0x56, 0x76, 0x4E, 0xCF, 0x69, 0xF1, 0x6E, 0x44, 0x6C, 0xD4, + 0x24, 0xEA, 0x8D, 0x24, 0xA1, 0x18, 0xBF, 0xBD, 0x57, 0xFE, 0xA9, 0x99, + 0x35, 0xB5, 0xDB, 0x10, 0x77, 0xB8, 0x3D, 0x48, 0xBA, 0xD6, 0xC1, 0xE7, + 0xF1, 0x23, 0x3E, 0xD7, 0xDF, 0x85, 0x9D, 0x27, 0x3C, 0xD4, 0x40, 0xBD, + 0x0A, 0x0C, 0xBD, 0xF5, 0xE7, 0x8D, 0x25, 0xD6, 0x81, 0x74, 0x87, 0x46, + 0xD4, 0x29, 0x75, 0xA2, 0x42, 0x6C, 0xF7, 0x73, 0x89, 0xE7, 0x7D, 0xBF, + 0x7A, 0x4A, 0x1F, 0xD3, 0x22, 0xC9, 0x15, 0x55, 0xCF, 0xDF, 0x6F, 0x7C, + 0x55, 0xD0, 0xA4, 0x8B, 0x07, 0x11, 0x37, 0x5F, 0x83, 0xA6, 0x26, 0x57, + 0xA6, 0x01, 0x5B, 0x7E, 0xFE, 0x58, 0x68, 0x07, 0xA9, 0xE9, 0x7A, 0xD9, + 0xB9, 0xE8, 0xFF, 0x50, 0x1F, 0xAB, 0xC2, 0xB4, 0xC0, 0xCE, 0xE8, 0xEA, + 0xFD, 0x0F, 0xBD, 0x8D, 0x4D, 0xB8, 0xBC, 0x71 +}; + +static const unsigned char TA2_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA3_DN[] = { + 0x30, 0x81, 0xBE, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x32, 0x30, + 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, + 0x32 +}; + +static const unsigned char TA3_RSA_N[] = { + 0xBA, 0x84, 0xB6, 0x72, 0xDB, 0x9E, 0x0C, 0x6B, 0xE2, 0x99, 0xE9, 0x30, + 0x01, 0xA7, 0x76, 0xEA, 0x32, 0xB8, 0x95, 0x41, 0x1A, 0xC9, 0xDA, 0x61, + 0x4E, 0x58, 0x72, 0xCF, 0xFE, 0xF6, 0x82, 0x79, 0xBF, 0x73, 0x61, 0x06, + 0x0A, 0xA5, 0x27, 0xD8, 0xB3, 0x5F, 0xD3, 0x45, 0x4E, 0x1C, 0x72, 0xD6, + 0x4E, 0x32, 0xF2, 0x72, 0x8A, 0x0F, 0xF7, 0x83, 0x19, 0xD0, 0x6A, 0x80, + 0x80, 0x00, 0x45, 0x1E, 0xB0, 0xC7, 0xE7, 0x9A, 0xBF, 0x12, 0x57, 0x27, + 0x1C, 0xA3, 0x68, 0x2F, 0x0A, 0x87, 0xBD, 0x6A, 0x6B, 0x0E, 0x5E, 0x65, + 0xF3, 0x1C, 0x77, 0xD5, 0xD4, 0x85, 0x8D, 0x70, 0x21, 0xB4, 0xB3, 0x32, + 0xE7, 0x8B, 0xA2, 0xD5, 0x86, 0x39, 0x02, 0xB1, 0xB8, 0xD2, 0x47, 0xCE, + 0xE4, 0xC9, 0x49, 0xC4, 0x3B, 0xA7, 0xDE, 0xFB, 0x54, 0x7D, 0x57, 0xBE, + 0xF0, 0xE8, 0x6E, 0xC2, 0x79, 0xB2, 0x3A, 0x0B, 0x55, 0xE2, 0x50, 0x98, + 0x16, 0x32, 0x13, 0x5C, 0x2F, 0x78, 0x56, 0xC1, 0xC2, 0x94, 0xB3, 0xF2, + 0x5A, 0xE4, 0x27, 0x9A, 0x9F, 0x24, 0xD7, 0xC6, 0xEC, 0xD0, 0x9B, 0x25, + 0x82, 0xE3, 0xCC, 0xC2, 0xC4, 0x45, 0xC5, 0x8C, 0x97, 0x7A, 0x06, 0x6B, + 0x2A, 0x11, 0x9F, 0xA9, 0x0A, 0x6E, 0x48, 0x3B, 0x6F, 0xDB, 0xD4, 0x11, + 0x19, 0x42, 0xF7, 0x8F, 0x07, 0xBF, 0xF5, 0x53, 0x5F, 0x9C, 0x3E, 0xF4, + 0x17, 0x2C, 0xE6, 0x69, 0xAC, 0x4E, 0x32, 0x4C, 0x62, 0x77, 0xEA, 0xB7, + 0xE8, 0xE5, 0xBB, 0x34, 0xBC, 0x19, 0x8B, 0xAE, 0x9C, 0x51, 0xE7, 0xB7, + 0x7E, 0xB5, 0x53, 0xB1, 0x33, 0x22, 0xE5, 0x6D, 0xCF, 0x70, 0x3C, 0x1A, + 0xFA, 0xE2, 0x9B, 0x67, 0xB6, 0x83, 0xF4, 0x8D, 0xA5, 0xAF, 0x62, 0x4C, + 0x4D, 0xE0, 0x58, 0xAC, 0x64, 0x34, 0x12, 0x03, 0xF8, 0xB6, 0x8D, 0x94, + 0x63, 0x24, 0xA4, 0x71 +}; + +static const unsigned char TA3_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA4_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA4_EC_Q[] = { + 0x04, 0x1A, 0xAC, 0x54, 0x5A, 0xA9, 0xF9, 0x68, 0x23, 0xE7, 0x7A, 0xD5, + 0x24, 0x6F, 0x53, 0xC6, 0x5A, 0xD8, 0x4B, 0xAB, 0xC6, 0xD5, 0xB6, 0xD1, + 0xE6, 0x73, 0x71, 0xAE, 0xDD, 0x9C, 0xD6, 0x0C, 0x61, 0xFD, 0xDB, 0xA0, + 0x89, 0x03, 0xB8, 0x05, 0x14, 0xEC, 0x57, 0xCE, 0xEE, 0x5D, 0x3F, 0xE2, + 0x21, 0xB3, 0xCE, 0xF7, 0xD4, 0x8A, 0x79, 0xE0, 0xA3, 0x83, 0x7E, 0x2D, + 0x97, 0xD0, 0x61, 0xC4, 0xF1, 0x99, 0xDC, 0x25, 0x91, 0x63, 0xAB, 0x7F, + 0x30, 0xA3, 0xB4, 0x70, 0xE2, 0xC7, 0xA1, 0x33, 0x9C, 0xF3, 0xBF, 0x2E, + 0x5C, 0x53, 0xB1, 0x5F, 0xB3, 0x7D, 0x32, 0x7F, 0x8A, 0x34, 0xE3, 0x79, + 0x79 +}; + +static const unsigned char TA5_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x33, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA5_RSA_N[] = { + 0xCC, 0x25, 0x76, 0x90, 0x79, 0x06, 0x78, 0x22, 0x16, 0xF5, 0xC0, 0x83, + 0xB6, 0x84, 0xCA, 0x28, 0x9E, 0xFD, 0x05, 0x76, 0x11, 0xC5, 0xAD, 0x88, + 0x72, 0xFC, 0x46, 0x02, 0x43, 0xC7, 0xB2, 0x8A, 0x9D, 0x04, 0x5F, 0x24, + 0xCB, 0x2E, 0x4B, 0xE1, 0x60, 0x82, 0x46, 0xE1, 0x52, 0xAB, 0x0C, 0x81, + 0x47, 0x70, 0x6C, 0xDD, 0x64, 0xD1, 0xEB, 0xF5, 0x2C, 0xA3, 0x0F, 0x82, + 0x3D, 0x0C, 0x2B, 0xAE, 0x97, 0xD7, 0xB6, 0x14, 0x86, 0x10, 0x79, 0xBB, + 0x3B, 0x13, 0x80, 0x77, 0x8C, 0x08, 0xE1, 0x49, 0xD2, 0x6A, 0x62, 0x2F, + 0x1F, 0x5E, 0xFA, 0x96, 0x68, 0xDF, 0x89, 0x27, 0x95, 0x38, 0x9F, 0x06, + 0xD7, 0x3E, 0xC9, 0xCB, 0x26, 0x59, 0x0D, 0x73, 0xDE, 0xB0, 0xC8, 0xE9, + 0x26, 0x0E, 0x83, 0x15, 0xC6, 0xEF, 0x5B, 0x8B, 0xD2, 0x04, 0x60, 0xCA, + 0x49, 0xA6, 0x28, 0xF6, 0x69, 0x3B, 0xF6, 0xCB, 0xC8, 0x28, 0x91, 0xE5, + 0x9D, 0x8A, 0x61, 0x57, 0x37, 0xAC, 0x74, 0x14, 0xDC, 0x74, 0xE0, 0x3A, + 0xEE, 0x72, 0x2F, 0x2E, 0x9C, 0xFB, 0xD0, 0xBB, 0xBF, 0xF5, 0x3D, 0x00, + 0xE1, 0x06, 0x33, 0xE8, 0x82, 0x2B, 0xAE, 0x53, 0xA6, 0x3A, 0x16, 0x73, + 0x8C, 0xDD, 0x41, 0x0E, 0x20, 0x3A, 0xC0, 0xB4, 0xA7, 0xA1, 0xE9, 0xB2, + 0x4F, 0x90, 0x2E, 0x32, 0x60, 0xE9, 0x57, 0xCB, 0xB9, 0x04, 0x92, 0x68, + 0x68, 0xE5, 0x38, 0x26, 0x60, 0x75, 0xB2, 0x9F, 0x77, 0xFF, 0x91, 0x14, + 0xEF, 0xAE, 0x20, 0x49, 0xFC, 0xAD, 0x40, 0x15, 0x48, 0xD1, 0x02, 0x31, + 0x61, 0x19, 0x5E, 0xB8, 0x97, 0xEF, 0xAD, 0x77, 0xB7, 0x64, 0x9A, 0x7A, + 0xBF, 0x5F, 0xC1, 0x13, 0xEF, 0x9B, 0x62, 0xFB, 0x0D, 0x6C, 0xE0, 0x54, + 0x69, 0x16, 0xA9, 0x03, 0xDA, 0x6E, 0xE9, 0x83, 0x93, 0x71, 0x76, 0xC6, + 0x69, 0x85, 0x82, 0x17 +}; + +static const unsigned char TA5_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA6_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA6_RSA_N[] = { + 0xA1, 0xAE, 0x25, 0xB2, 0x01, 0x18, 0xDC, 0x57, 0x88, 0x3F, 0x46, 0xEB, + 0xF9, 0xAF, 0xE2, 0xEB, 0x23, 0x71, 0xE2, 0x9A, 0xD1, 0x61, 0x66, 0x21, + 0x5F, 0xAA, 0xAF, 0x27, 0x51, 0xE5, 0x6E, 0x1B, 0x16, 0xD4, 0x2D, 0x7D, + 0x50, 0xB0, 0x53, 0x77, 0xBD, 0x78, 0x3A, 0x60, 0xE2, 0x64, 0x02, 0x9B, + 0x7C, 0x86, 0x9B, 0xD6, 0x1A, 0x8E, 0xAD, 0xFF, 0x1F, 0x15, 0x7F, 0xD5, + 0x95, 0x1E, 0x12, 0xCB, 0xE6, 0x14, 0x84, 0x04, 0xC1, 0xDF, 0x36, 0xB3, + 0x16, 0x9F, 0x8A, 0xE3, 0xC9, 0xDB, 0x98, 0x34, 0xCE, 0xD8, 0x33, 0x17, + 0x28, 0x46, 0xFC, 0xA7, 0xC9, 0xF0, 0xD2, 0xB4, 0xD5, 0x4D, 0x09, 0x72, + 0x49, 0xF9, 0xF2, 0x87, 0xE3, 0xA9, 0xDA, 0x7D, 0xA1, 0x7D, 0x6B, 0xB2, + 0x3A, 0x25, 0xA9, 0x6D, 0x52, 0x44, 0xAC, 0xF8, 0xBE, 0x6E, 0xFB, 0xDC, + 0xA6, 0x73, 0x91, 0x90, 0x61, 0xA6, 0x03, 0x14, 0x20, 0xF2, 0xE7, 0x87, + 0xA3, 0x88, 0xAD, 0xAD, 0xA0, 0x8C, 0xFF, 0xA6, 0x0B, 0x25, 0x52, 0x25, + 0xE7, 0x16, 0x01, 0xD5, 0xCB, 0xB8, 0x35, 0x81, 0x0C, 0xA3, 0x3B, 0xF0, + 0xE1, 0xE1, 0xFC, 0x5A, 0x5D, 0xCE, 0x80, 0x71, 0x6D, 0xF8, 0x49, 0xAB, + 0x3E, 0x3B, 0xBA, 0xB8, 0xD7, 0x80, 0x01, 0xFB, 0xA5, 0xEB, 0x5B, 0xB3, + 0xC5, 0x5E, 0x60, 0x2A, 0x31, 0xA0, 0xAF, 0x37, 0xE8, 0x20, 0x3A, 0x9F, + 0xA8, 0x32, 0x2C, 0x0C, 0xCC, 0x09, 0x1D, 0xD3, 0x9E, 0x8E, 0x5D, 0xBC, + 0x4C, 0x98, 0xEE, 0xC5, 0x1A, 0x68, 0x7B, 0xEC, 0x53, 0xA6, 0xE9, 0x14, + 0x35, 0xA3, 0xDF, 0xCD, 0x80, 0x9F, 0x0C, 0x48, 0xFB, 0x1C, 0xF4, 0xF1, + 0xBF, 0x4A, 0xB8, 0xFA, 0xD5, 0x8C, 0x71, 0x4A, 0xC7, 0x1F, 0xAD, 0xFE, + 0x41, 0x9A, 0xB3, 0x83, 0x5D, 0xF2, 0x84, 0x56, 0xEF, 0xA5, 0x57, 0x43, + 0xCE, 0x29, 0xAD, 0x8C, 0xAB, 0x55, 0xBF, 0xC4, 0xFB, 0x5B, 0x01, 0xDD, + 0x23, 0x21, 0xA1, 0x58, 0x00, 0x8E, 0xC3, 0xD0, 0x6A, 0x13, 0xED, 0x13, + 0xE3, 0x12, 0x2B, 0x80, 0xDC, 0x67, 0xE6, 0x95, 0xB2, 0xCD, 0x1E, 0x22, + 0x6E, 0x2A, 0xF8, 0x41, 0xD4, 0xF2, 0xCA, 0x14, 0x07, 0x8D, 0x8A, 0x55, + 0x12, 0xC6, 0x69, 0xF5, 0xB8, 0x86, 0x68, 0x2F, 0x53, 0x5E, 0xB0, 0xD2, + 0xAA, 0x21, 0xC1, 0x98, 0xE6, 0x30, 0xE3, 0x67, 0x55, 0xC7, 0x9B, 0x6E, + 0xAC, 0x19, 0xA8, 0x55, 0xA6, 0x45, 0x06, 0xD0, 0x23, 0x3A, 0xDB, 0xEB, + 0x65, 0x5D, 0x2A, 0x11, 0x11, 0xF0, 0x3B, 0x4F, 0xCA, 0x6D, 0xF4, 0x34, + 0xC4, 0x71, 0xE4, 0xFF, 0x00, 0x5A, 0xF6, 0x5C, 0xAE, 0x23, 0x60, 0x85, + 0x73, 0xF1, 0xE4, 0x10, 0xB1, 0x25, 0xAE, 0xD5, 0x92, 0xBB, 0x13, 0xC1, + 0x0C, 0xE0, 0x39, 0xDA, 0xB4, 0x39, 0x57, 0xB5, 0xAB, 0x35, 0xAA, 0x72, + 0x21, 0x3B, 0x83, 0x35, 0xE7, 0x31, 0xDF, 0x7A, 0x21, 0x6E, 0xB8, 0x32, + 0x08, 0x7D, 0x1D, 0x32, 0x91, 0x15, 0x4A, 0x62, 0x72, 0xCF, 0xE3, 0x77, + 0xA1, 0xBC, 0xD5, 0x11, 0x1B, 0x76, 0x01, 0x67, 0x08, 0xE0, 0x41, 0x0B, + 0xC3, 0xEB, 0x15, 0x6E, 0xF8, 0xA4, 0x19, 0xD9, 0xA2, 0xAB, 0xAF, 0xE2, + 0x27, 0x52, 0x56, 0x2B, 0x02, 0x8A, 0x2C, 0x14, 0x24, 0xF9, 0xBF, 0x42, + 0x02, 0xBF, 0x26, 0xC8, 0xC6, 0x8F, 0xE0, 0x6E, 0x38, 0x7D, 0x53, 0x2D, + 0xE5, 0xED, 0x98, 0xB3, 0x95, 0x63, 0x68, 0x7F, 0xF9, 0x35, 0xF4, 0xDF, + 0x88, 0xC5, 0x60, 0x35, 0x92, 0xC0, 0x7C, 0x69, 0x1C, 0x61, 0x95, 0x16, + 0xD0, 0xEB, 0xDE, 0x0B, 0xAF, 0x3E, 0x04, 0x10, 0x45, 0x65, 0x58, 0x50, + 0x38, 0xAF, 0x48, 0xF2, 0x59, 0xB6, 0x16, 0xF2, 0x3C, 0x0D, 0x90, 0x02, + 0xC6, 0x70, 0x2E, 0x01, 0xAD, 0x3C, 0x15, 0xD7 +}; + +static const unsigned char TA6_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA7_DN[] = { + 0x30, 0x6E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x13, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, 0x6F, 0x66, 0x65, + 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x53, 0x41, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0F, 0x56, 0x41, 0x54, 0x45, + 0x53, 0x2D, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x46, 0x49, + 0x52, 0x4D, 0x41, 0x50, 0x52, 0x4F, 0x46, 0x45, 0x53, 0x49, 0x4F, 0x4E, + 0x41, 0x4C, 0x20, 0x43, 0x41, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x2D, 0x41, + 0x20, 0x57, 0x45, 0x42 +}; + +static const unsigned char TA7_EC_Q[] = { + 0x04, 0x47, 0x53, 0xEA, 0x2C, 0x11, 0xA4, 0x77, 0xC7, 0x2A, 0xEA, 0xF3, + 0xD6, 0x5F, 0x7B, 0xD3, 0x04, 0x91, 0x5C, 0xFA, 0x88, 0xC6, 0x22, 0xB9, + 0x83, 0x10, 0x62, 0x77, 0x84, 0x33, 0x2D, 0xE9, 0x03, 0x88, 0xD4, 0xE0, + 0x33, 0xF7, 0xED, 0x77, 0x2C, 0x4A, 0x60, 0xEA, 0xE4, 0x6F, 0xAD, 0x6D, + 0xB4, 0xF8, 0x4C, 0x8A, 0xA4, 0xE4, 0x1F, 0xCA, 0xEA, 0x4F, 0x38, 0x4A, + 0x2E, 0x82, 0x73, 0x2B, 0xC7, 0x66, 0x9B, 0x0A, 0x8C, 0x40, 0x9C, 0x7C, + 0x8A, 0xF6, 0xF2, 0x39, 0x60, 0xB2, 0xDE, 0xCB, 0xEC, 0xB8, 0xE4, 0x6F, + 0xEA, 0x9B, 0x5D, 0xB7, 0x53, 0x90, 0x18, 0x32, 0x55, 0xC5, 0x20, 0xB7, + 0x94 +}; + +static const unsigned char TA8_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, + 0x6F, 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x2E, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, + 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA8_RSA_N[] = { + 0x8F, 0x36, 0x65, 0x40, 0xE1, 0xD6, 0x4D, 0xC0, 0xD7, 0xB4, 0xE9, 0x46, + 0xDA, 0x6B, 0xEA, 0x33, 0x47, 0xCD, 0x4C, 0xF9, 0x7D, 0x7D, 0xBE, 0xBD, + 0x2D, 0x3D, 0xF0, 0xDB, 0x78, 0xE1, 0x86, 0xA5, 0xD9, 0xBA, 0x09, 0x57, + 0x68, 0xED, 0x57, 0x3E, 0xA0, 0xD0, 0x08, 0x41, 0x83, 0xE7, 0x28, 0x41, + 0x24, 0x1F, 0xE3, 0x72, 0x15, 0xD0, 0x01, 0x1A, 0xFB, 0x5E, 0x70, 0x23, + 0xB2, 0xCB, 0x9F, 0x39, 0xE3, 0xCF, 0xC5, 0x4E, 0xC6, 0x92, 0x6D, 0x26, + 0xC6, 0x7B, 0xBB, 0xB3, 0xDA, 0x27, 0x9D, 0x0A, 0x86, 0xE9, 0x81, 0x37, + 0x05, 0xFE, 0xF0, 0x71, 0x71, 0xEC, 0xC3, 0x1C, 0xE9, 0x63, 0xA2, 0x17, + 0x14, 0x9D, 0xEF, 0x1B, 0x67, 0xD3, 0x85, 0x55, 0x02, 0x02, 0xD6, 0x49, + 0xC9, 0xCC, 0x5A, 0xE1, 0xB1, 0xF7, 0x6F, 0x32, 0x9F, 0xC9, 0xD4, 0x3B, + 0x88, 0x41, 0xA8, 0x9C, 0xBD, 0xCB, 0xAB, 0xDB, 0x6D, 0x7B, 0x09, 0x1F, + 0xA2, 0x4C, 0x72, 0x90, 0xDA, 0x2B, 0x08, 0xFC, 0xCF, 0x3C, 0x54, 0xCE, + 0x67, 0x0F, 0xA8, 0xCF, 0x5D, 0x96, 0x19, 0x0B, 0xC4, 0xE3, 0x72, 0xEB, + 0xAD, 0xD1, 0x7D, 0x1D, 0x27, 0xEF, 0x92, 0xEB, 0x10, 0xBF, 0x5B, 0xEB, + 0x3B, 0xAF, 0xCF, 0x80, 0xDD, 0xC1, 0xD2, 0x96, 0x04, 0x5B, 0x7A, 0x7E, + 0xA4, 0xA9, 0x3C, 0x38, 0x76, 0xA4, 0x62, 0x8E, 0xA0, 0x39, 0x5E, 0xEA, + 0x77, 0xCF, 0x5D, 0x00, 0x59, 0x8F, 0x66, 0x2C, 0x3E, 0x07, 0xA2, 0xA3, + 0x05, 0x26, 0x11, 0x69, 0x97, 0xEA, 0x85, 0xB7, 0x0F, 0x96, 0x0B, 0x4B, + 0xC8, 0x40, 0xE1, 0x50, 0xBA, 0x2E, 0x8A, 0xCB, 0xF7, 0x0F, 0x9A, 0x22, + 0xE7, 0x7F, 0x9A, 0x37, 0x13, 0xCD, 0xF2, 0x4D, 0x13, 0x6B, 0x21, 0xD1, + 0xC0, 0xCC, 0x22, 0xF2, 0xA1, 0x46, 0xF6, 0x44, 0x69, 0x9C, 0xCA, 0x61, + 0x35, 0x07, 0x00, 0x6F, 0xD6, 0x61, 0x08, 0x11, 0xEA, 0xBA, 0xB8, 0xF6, + 0xE9, 0xB3, 0x60, 0xE5, 0x4D, 0xB9, 0xEC, 0x9F, 0x14, 0x66, 0xC9, 0x57, + 0x58, 0xDB, 0xCD, 0x87, 0x69, 0xF8, 0x8A, 0x86, 0x12, 0x03, 0x47, 0xBF, + 0x66, 0x13, 0x76, 0xAC, 0x77, 0x7D, 0x34, 0x24, 0x85, 0x83, 0xCD, 0xD7, + 0xAA, 0x9C, 0x90, 0x1A, 0x9F, 0x21, 0x2C, 0x7F, 0x78, 0xB7, 0x64, 0xB8, + 0xD8, 0xE8, 0xA6, 0xF4, 0x78, 0xB3, 0x55, 0xCB, 0x84, 0xD2, 0x32, 0xC4, + 0x78, 0xAE, 0xA3, 0x8F, 0x61, 0xDD, 0xCE, 0x08, 0x53, 0xAD, 0xEC, 0x88, + 0xFC, 0x15, 0xE4, 0x9A, 0x0D, 0xE6, 0x9F, 0x1A, 0x77, 0xCE, 0x4C, 0x8F, + 0xB8, 0x14, 0x15, 0x3D, 0x62, 0x9C, 0x86, 0x38, 0x06, 0x00, 0x66, 0x12, + 0xE4, 0x59, 0x76, 0x5A, 0x53, 0xC0, 0x02, 0x98, 0xA2, 0x10, 0x2B, 0x68, + 0x44, 0x7B, 0x8E, 0x79, 0xCE, 0x33, 0x4A, 0x76, 0xAA, 0x5B, 0x81, 0x16, + 0x1B, 0xB5, 0x8A, 0xD8, 0xD0, 0x00, 0x7B, 0x5E, 0x62, 0xB4, 0x09, 0xD6, + 0x86, 0x63, 0x0E, 0xA6, 0x05, 0x95, 0x49, 0xBA, 0x28, 0x8B, 0x88, 0x93, + 0xB2, 0x34, 0x1C, 0xD8, 0xA4, 0x55, 0x6E, 0xB7, 0x1C, 0xD0, 0xDE, 0x99, + 0x55, 0x3B, 0x23, 0xF4, 0x22, 0xE0, 0xF9, 0x29, 0x66, 0x26, 0xEC, 0x20, + 0x50, 0x77, 0xDB, 0x4A, 0x0B, 0x8F, 0xBE, 0xE5, 0x02, 0x60, 0x70, 0x41, + 0x5E, 0xD4, 0xAE, 0x50, 0x39, 0x22, 0x14, 0x26, 0xCB, 0xB2, 0x3B, 0x73, + 0x74, 0x55, 0x47, 0x07, 0x79, 0x81, 0x39, 0xA8, 0x30, 0x13, 0x44, 0xE5, + 0x04, 0x8A, 0xAE, 0x96, 0x13, 0x25, 0x42, 0x0F, 0xB9, 0x53, 0xC4, 0x9B, + 0xFC, 0xCD, 0xE4, 0x1C, 0xDE, 0x3C, 0xFA, 0xAB, 0xD6, 0x06, 0x4A, 0x1F, + 0x67, 0xA6, 0x98, 0x30, 0x1C, 0xDD, 0x2C, 0xDB, 0xDC, 0x18, 0x95, 0x57, + 0x66, 0xC6, 0xFF, 0x5C, 0x8B, 0x56, 0xF5, 0x77 +}; + +static const unsigned char TA8_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA9_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA9_EC_Q[] = { + 0x04, 0xF1, 0xB3, 0xCD, 0x38, 0xE4, 0x25, 0x43, 0xE5, 0xDE, 0x19, 0x09, + 0xBB, 0x81, 0x79, 0xA2, 0x15, 0x5F, 0x15, 0x63, 0x01, 0xDE, 0xC2, 0xAB, + 0xDD, 0xB3, 0xA6, 0x1B, 0x67, 0x4B, 0x80, 0x83, 0xAF, 0x99, 0xCB, 0xAC, + 0x17, 0xDB, 0x2B, 0x96, 0xCA, 0x7C, 0x52, 0x55, 0xE2, 0x1A, 0xE1, 0x3D, + 0x56, 0xF0, 0x2F, 0x16, 0x08, 0xFA, 0x15, 0xBC, 0x9B, 0xBB, 0x47, 0xE6, + 0x3F, 0xEE, 0xA8, 0xE1, 0x4C, 0x8C, 0xF5, 0xD3, 0x36, 0xF9, 0x38, 0x5D, + 0xAB, 0x70, 0x9A, 0x47, 0x0D, 0xE2, 0x81, 0x41, 0x06, 0xEB, 0x49, 0xF9, + 0xB0, 0x29, 0xDD, 0x33, 0xEC, 0x50, 0xA5, 0x7F, 0x79, 0x29, 0xB8, 0x20, + 0x98 +}; + +static const unsigned char TA10_DN[] = { + 0x30, 0x81, 0x98, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3B, + 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA10_RSA_N[] = { + 0xD5, 0x0C, 0x3A, 0xC4, 0x2A, 0xF9, 0x4E, 0xE2, 0xF5, 0xBE, 0x19, 0x97, + 0x5F, 0x8E, 0x88, 0x53, 0xB1, 0x1F, 0x3F, 0xCB, 0xCF, 0x9F, 0x20, 0x13, + 0x6D, 0x29, 0x3A, 0xC8, 0x0F, 0x7D, 0x3C, 0xF7, 0x6B, 0x76, 0x38, 0x63, + 0xD9, 0x36, 0x60, 0xA8, 0x9B, 0x5E, 0x5C, 0x00, 0x80, 0xB2, 0x2F, 0x59, + 0x7F, 0xF6, 0x87, 0xF9, 0x25, 0x43, 0x86, 0xE7, 0x69, 0x1B, 0x52, 0x9A, + 0x90, 0xE1, 0x71, 0xE3, 0xD8, 0x2D, 0x0D, 0x4E, 0x6F, 0xF6, 0xC8, 0x49, + 0xD9, 0xB6, 0xF3, 0x1A, 0x56, 0xAE, 0x2B, 0xB6, 0x74, 0x14, 0xEB, 0xCF, + 0xFB, 0x26, 0xE3, 0x1A, 0xBA, 0x1D, 0x96, 0x2E, 0x6A, 0x3B, 0x58, 0x94, + 0x89, 0x47, 0x56, 0xFF, 0x25, 0xA0, 0x93, 0x70, 0x53, 0x83, 0xDA, 0x84, + 0x74, 0x14, 0xC3, 0x67, 0x9E, 0x04, 0x68, 0x3A, 0xDF, 0x8E, 0x40, 0x5A, + 0x1D, 0x4A, 0x4E, 0xCF, 0x43, 0x91, 0x3B, 0xE7, 0x56, 0xD6, 0x00, 0x70, + 0xCB, 0x52, 0xEE, 0x7B, 0x7D, 0xAE, 0x3A, 0xE7, 0xBC, 0x31, 0xF9, 0x45, + 0xF6, 0xC2, 0x60, 0xCF, 0x13, 0x59, 0x02, 0x2B, 0x80, 0xCC, 0x34, 0x47, + 0xDF, 0xB9, 0xDE, 0x90, 0x65, 0x6D, 0x02, 0xCF, 0x2C, 0x91, 0xA6, 0xA6, + 0xE7, 0xDE, 0x85, 0x18, 0x49, 0x7C, 0x66, 0x4E, 0xA3, 0x3A, 0x6D, 0xA9, + 0xB5, 0xEE, 0x34, 0x2E, 0xBA, 0x0D, 0x03, 0xB8, 0x33, 0xDF, 0x47, 0xEB, + 0xB1, 0x6B, 0x8D, 0x25, 0xD9, 0x9B, 0xCE, 0x81, 0xD1, 0x45, 0x46, 0x32, + 0x96, 0x70, 0x87, 0xDE, 0x02, 0x0E, 0x49, 0x43, 0x85, 0xB6, 0x6C, 0x73, + 0xBB, 0x64, 0xEA, 0x61, 0x41, 0xAC, 0xC9, 0xD4, 0x54, 0xDF, 0x87, 0x2F, + 0xC7, 0x22, 0xB2, 0x26, 0xCC, 0x9F, 0x59, 0x54, 0x68, 0x9F, 0xFC, 0xBE, + 0x2A, 0x2F, 0xC4, 0x55, 0x1C, 0x75, 0x40, 0x60, 0x17, 0x85, 0x02, 0x55, + 0x39, 0x8B, 0x7F, 0x05 +}; + +static const unsigned char TA10_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA11_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x33 +}; + +static const unsigned char TA11_EC_Q[] = { + 0x04, 0x1F, 0x4F, 0x33, 0x87, 0x33, 0x29, 0x8A, 0xA1, 0x84, 0xDE, 0xCB, + 0xC7, 0x21, 0x58, 0x41, 0x89, 0xEA, 0x56, 0x9D, 0x2B, 0x4B, 0x85, 0xC6, + 0x1D, 0x4C, 0x27, 0xBC, 0x7F, 0x26, 0x51, 0x72, 0x6F, 0xE2, 0x9F, 0xD6, + 0xA3, 0xCA, 0xCC, 0x45, 0x14, 0x46, 0x8B, 0xAD, 0xEF, 0x7E, 0x86, 0x8C, + 0xEC, 0xB1, 0x7E, 0x2F, 0xFF, 0xA9, 0x71, 0x9D, 0x18, 0x84, 0x45, 0x04, + 0x41, 0x55, 0x6E, 0x2B, 0xEA, 0x26, 0x7F, 0xBB, 0x90, 0x01, 0xE3, 0x4B, + 0x19, 0xBA, 0xE4, 0x54, 0x96, 0x45, 0x09, 0xB1, 0xD5, 0x6C, 0x91, 0x44, + 0xAD, 0x84, 0x13, 0x8E, 0x9A, 0x8C, 0x0D, 0x80, 0x0C, 0x32, 0xF6, 0xE0, + 0x27 +}; + +static const unsigned char TA12_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x30, 0x30, 0x2E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x27, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x61, + 0x6E, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0C, 0x43, 0x46, 0x43, 0x41, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA12_RSA_N[] = { + 0xD7, 0x5D, 0x6B, 0xCD, 0x10, 0x3F, 0x1F, 0x05, 0x59, 0xD5, 0x05, 0x4D, + 0x37, 0xB1, 0x0E, 0xEC, 0x98, 0x2B, 0x8E, 0x15, 0x1D, 0xFA, 0x93, 0x4B, + 0x17, 0x82, 0x21, 0x71, 0x10, 0x52, 0xD7, 0x51, 0x64, 0x70, 0x16, 0xC2, + 0x55, 0x69, 0x4D, 0x8E, 0x15, 0x6D, 0x9F, 0xBF, 0x0C, 0x1B, 0xC2, 0xE0, + 0xA3, 0x67, 0xD6, 0x0C, 0xAC, 0xCF, 0x22, 0xAE, 0xAF, 0x77, 0x54, 0x2A, + 0x4B, 0x4C, 0x8A, 0x53, 0x52, 0x7A, 0xC3, 0xEE, 0x2E, 0xDE, 0xB3, 0x71, + 0x25, 0xC1, 0xE9, 0x5D, 0x3D, 0xEE, 0xA1, 0x2F, 0xA3, 0xF7, 0x2A, 0x3C, + 0xC9, 0x23, 0x1D, 0x6A, 0xAB, 0x1D, 0xA1, 0xA7, 0xF1, 0xF3, 0xEC, 0xA0, + 0xD5, 0x44, 0xCF, 0x15, 0xCF, 0x72, 0x2F, 0x1D, 0x63, 0x97, 0xE8, 0x99, + 0xF9, 0xFD, 0x93, 0xA4, 0x54, 0x80, 0x4C, 0x52, 0xD4, 0x52, 0xAB, 0x2E, + 0x49, 0xDF, 0x90, 0xCD, 0xB8, 0x5F, 0xBE, 0x3F, 0xDE, 0xA1, 0xCA, 0x4D, + 0x20, 0xD4, 0x25, 0xE8, 0x84, 0x29, 0x53, 0xB7, 0xB1, 0x88, 0x1F, 0xFF, + 0xFA, 0xDA, 0x90, 0x9F, 0x0A, 0xA9, 0x2D, 0x41, 0x3F, 0xB1, 0xF1, 0x18, + 0x29, 0xEE, 0x16, 0x59, 0x2C, 0x34, 0x49, 0x1A, 0xA8, 0x06, 0xD7, 0xA8, + 0x88, 0xD2, 0x03, 0x72, 0x7A, 0x32, 0xE2, 0xEA, 0x68, 0x4D, 0x6E, 0x2C, + 0x96, 0x65, 0x7B, 0xCA, 0x59, 0xFA, 0xF2, 0xE2, 0xDD, 0xEE, 0x30, 0x2C, + 0xFB, 0xCC, 0x46, 0xAC, 0xC4, 0x63, 0xEB, 0x6F, 0x7F, 0x36, 0x2B, 0x34, + 0x73, 0x12, 0x94, 0x7F, 0xDF, 0xCC, 0x26, 0x9E, 0xF1, 0x72, 0x5D, 0x50, + 0x65, 0x59, 0x8F, 0x69, 0xB3, 0x87, 0x5E, 0x32, 0x6F, 0xC3, 0x18, 0x8A, + 0xB5, 0x95, 0x8F, 0xB0, 0x7A, 0x37, 0xDE, 0x5A, 0x45, 0x3B, 0xC7, 0x36, + 0xE1, 0xEF, 0x67, 0xD1, 0x39, 0xD3, 0x97, 0x5B, 0x73, 0x62, 0x19, 0x48, + 0x2D, 0x87, 0x1C, 0x06, 0xFB, 0x74, 0x98, 0x20, 0x49, 0x73, 0xF0, 0x05, + 0xD2, 0x1B, 0xB1, 0xA0, 0xA3, 0xB7, 0x1B, 0x70, 0xD3, 0x88, 0x69, 0xB9, + 0x5A, 0xD6, 0x38, 0xF4, 0x62, 0xDC, 0x25, 0x8B, 0x78, 0xBF, 0xF8, 0xE8, + 0x7E, 0xB8, 0x5C, 0xC9, 0x95, 0x4F, 0x5F, 0xA7, 0x2D, 0xB9, 0x20, 0x6B, + 0xCF, 0x6B, 0xDD, 0xF5, 0x0D, 0xF4, 0x82, 0xB7, 0xF4, 0xB2, 0x66, 0x2E, + 0x10, 0x28, 0xF6, 0x97, 0x5A, 0x7B, 0x96, 0x16, 0x8F, 0x01, 0x19, 0x2D, + 0x6C, 0x6E, 0x7F, 0x39, 0x58, 0x06, 0x64, 0x83, 0x01, 0x83, 0x83, 0xC3, + 0x4D, 0x92, 0xDD, 0x32, 0xC6, 0x87, 0xA4, 0x37, 0xE9, 0x16, 0xCE, 0xAA, + 0x2D, 0x68, 0xAF, 0x0A, 0x81, 0x65, 0x3A, 0x70, 0xC1, 0x9B, 0xAD, 0x4D, + 0x6D, 0x54, 0xCA, 0x2A, 0x2D, 0x4B, 0x85, 0x1B, 0xB3, 0x80, 0xE6, 0x70, + 0x45, 0x0D, 0x6B, 0x5E, 0x35, 0xF0, 0x7F, 0x3B, 0xB8, 0x9C, 0xE4, 0x04, + 0x70, 0x89, 0x12, 0x25, 0x93, 0xDA, 0x0A, 0x99, 0x22, 0x60, 0x6A, 0x63, + 0x60, 0x4E, 0x76, 0x06, 0x98, 0x4E, 0xBD, 0x83, 0xAD, 0x1D, 0x58, 0x8A, + 0x25, 0x85, 0xD2, 0xC7, 0x65, 0x1E, 0x2D, 0x8E, 0xC6, 0xDF, 0xB6, 0xC6, + 0xE1, 0x7F, 0x8A, 0x04, 0x21, 0x15, 0x29, 0x74, 0xF0, 0x3E, 0x9C, 0x90, + 0x9D, 0x0C, 0x2E, 0xF1, 0x8A, 0x3E, 0x5A, 0xAA, 0x0C, 0x09, 0x1E, 0xC7, + 0xD5, 0x3C, 0xA3, 0xED, 0x97, 0xC3, 0x1E, 0x34, 0xFA, 0x38, 0xF9, 0x08, + 0x0E, 0xE3, 0xC0, 0x5D, 0x2B, 0x83, 0xD1, 0x56, 0x6A, 0xC9, 0xB6, 0xA8, + 0x54, 0x53, 0x2E, 0x78, 0x32, 0x67, 0x3D, 0x82, 0x7F, 0x74, 0xD0, 0xFB, + 0xE1, 0xB6, 0x05, 0x60, 0xB9, 0x70, 0xDB, 0x8E, 0x0B, 0xF9, 0x13, 0x58, + 0x6F, 0x71, 0x60, 0x10, 0x52, 0x10, 0xB9, 0xC1, 0x41, 0x09, 0xEF, 0x72, + 0x1F, 0x67, 0x31, 0x78, 0xFF, 0x96, 0x05, 0x8D +}; + +static const unsigned char TA12_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA13_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x32 +}; + +static const unsigned char TA13_EC_Q[] = { + 0x04, 0xCD, 0x9B, 0xD5, 0x9F, 0x80, 0x83, 0x0A, 0xEC, 0x09, 0x4A, 0xF3, + 0x16, 0x4A, 0x3E, 0x5C, 0xCF, 0x77, 0xAC, 0xDE, 0x67, 0x05, 0x0D, 0x1D, + 0x07, 0xB6, 0xDC, 0x16, 0xFB, 0x5A, 0x8B, 0x14, 0xDB, 0xE2, 0x71, 0x60, + 0xC4, 0xBA, 0x45, 0x95, 0x11, 0x89, 0x8E, 0xEA, 0x06, 0xDF, 0xF7, 0x2A, + 0x16, 0x1C, 0xA4, 0xB9, 0xC5, 0xC5, 0x32, 0xE0, 0x03, 0xE0, 0x1E, 0x82, + 0x18, 0x38, 0x8B, 0xD7, 0x45, 0xD8, 0x0A, 0x6A, 0x6E, 0xE6, 0x00, 0x77, + 0xFB, 0x02, 0x51, 0x7D, 0x22, 0xD8, 0x0A, 0x6E, 0x9A, 0x5B, 0x77, 0xDF, + 0xF0, 0xFA, 0x41, 0xEC, 0x39, 0xDC, 0x75, 0xCA, 0x68, 0x07, 0x0C, 0x1F, + 0xEA +}; + +static const unsigned char TA14_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA14_EC_Q[] = { + 0x04, 0x45, 0x6E, 0xA9, 0x50, 0xC4, 0xA6, 0x23, 0x36, 0x9E, 0x5F, 0x28, + 0x8D, 0x17, 0xCB, 0x96, 0x22, 0x64, 0x3F, 0xDC, 0x7A, 0x8E, 0x1D, 0xCC, + 0x08, 0xB3, 0xA2, 0x71, 0x24, 0xBA, 0x8E, 0x49, 0xB9, 0x04, 0x1B, 0x47, + 0x96, 0x58, 0xAB, 0x2D, 0x95, 0xC8, 0xED, 0x9E, 0x08, 0x35, 0xC8, 0x27, + 0xEB, 0x89, 0x8C, 0x53, 0x58, 0xEB, 0x62, 0x8A, 0xFE, 0xF0, 0x5B, 0x0F, + 0x6B, 0x31, 0x52, 0x63, 0x41, 0x3B, 0x89, 0xCD, 0xEC, 0xEC, 0xB6, 0x8D, + 0x19, 0xD3, 0x34, 0x07, 0xDC, 0xBB, 0xC6, 0x06, 0x7F, 0xC2, 0x45, 0x95, + 0xEC, 0xCB, 0x7F, 0xA8, 0x23, 0xE0, 0x09, 0xE9, 0x81, 0xFA, 0xF3, 0x47, + 0xD3 +}; + +static const unsigned char TA15_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x34, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA15_EC_Q[] = { + 0x04, 0xB8, 0xC6, 0x79, 0xD3, 0x8F, 0x6C, 0x25, 0x0E, 0x9F, 0x2E, 0x39, + 0x19, 0x1C, 0x03, 0xA4, 0xAE, 0x9A, 0xE5, 0x39, 0x07, 0x09, 0x16, 0xCA, + 0x63, 0xB1, 0xB9, 0x86, 0xF8, 0x8A, 0x57, 0xC1, 0x57, 0xCE, 0x42, 0xFA, + 0x73, 0xA1, 0xF7, 0x65, 0x42, 0xFF, 0x1E, 0xC1, 0x00, 0xB2, 0x6E, 0x73, + 0x0E, 0xFF, 0xC7, 0x21, 0xE5, 0x18, 0xA4, 0xAA, 0xD9, 0x71, 0x3F, 0xA8, + 0xD4, 0xB9, 0xCE, 0x8C, 0x1D +}; + +static const unsigned char TA16_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x55, 0x43, 0x41, + 0x20, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, + 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74 +}; + +static const unsigned char TA16_RSA_N[] = { + 0xA9, 0x09, 0x07, 0x28, 0x13, 0x02, 0xB0, 0x99, 0xE0, 0x64, 0xAA, 0x1E, + 0x43, 0x16, 0x7A, 0x73, 0xB1, 0x91, 0xA0, 0x75, 0x3E, 0xA8, 0xFA, 0xE3, + 0x38, 0x00, 0x7A, 0xEC, 0x89, 0x6A, 0x20, 0x0F, 0x8B, 0xC5, 0xB0, 0x9B, + 0x33, 0x03, 0x5A, 0x86, 0xC6, 0x58, 0x86, 0xD5, 0xC1, 0x85, 0xBB, 0x4F, + 0xC6, 0x9C, 0x40, 0x4D, 0xCA, 0xBE, 0xEE, 0x69, 0x96, 0xB8, 0xAD, 0x81, + 0x30, 0x9A, 0x7C, 0x92, 0x05, 0xEB, 0x05, 0x2B, 0x9A, 0x48, 0xD0, 0xB8, + 0x76, 0x3E, 0x96, 0xC8, 0x20, 0xBB, 0xD2, 0xB0, 0xF1, 0x8F, 0xD8, 0xAC, + 0x45, 0x46, 0xFF, 0xAA, 0x67, 0x60, 0xB4, 0x77, 0x7E, 0x6A, 0x1F, 0x3C, + 0x1A, 0x52, 0x7A, 0x04, 0x3D, 0x07, 0x3C, 0x85, 0x0D, 0x84, 0xD0, 0x1F, + 0x76, 0x0A, 0xF7, 0x6A, 0x14, 0xDF, 0x72, 0xE3, 0x34, 0x7C, 0x57, 0x4E, + 0x56, 0x01, 0x3E, 0x79, 0xF1, 0xAA, 0x29, 0x3B, 0x6C, 0xFA, 0xF8, 0x8F, + 0x6D, 0x4D, 0xC8, 0x35, 0xDF, 0xAE, 0xEB, 0xDC, 0x24, 0xEE, 0x79, 0x45, + 0xA7, 0x85, 0xB6, 0x05, 0x88, 0xDE, 0x88, 0x5D, 0x25, 0x7C, 0x97, 0x64, + 0x67, 0x09, 0xD9, 0xBF, 0x5A, 0x15, 0x05, 0x86, 0xF3, 0x09, 0x1E, 0xEC, + 0x58, 0x32, 0x33, 0x11, 0xF3, 0x77, 0x64, 0xB0, 0x76, 0x1F, 0xE4, 0x10, + 0x35, 0x17, 0x1B, 0xF2, 0x0E, 0xB1, 0x6C, 0xA4, 0x2A, 0xA3, 0x73, 0xFC, + 0x09, 0x1F, 0x1E, 0x32, 0x19, 0x53, 0x11, 0xE7, 0xD9, 0xB3, 0x2C, 0x2E, + 0x76, 0x2E, 0xA1, 0xA3, 0xDE, 0x7E, 0x6A, 0x88, 0x09, 0xE8, 0xF2, 0x07, + 0x8A, 0xF8, 0xB2, 0xCD, 0x10, 0xE7, 0xE2, 0x73, 0x40, 0x93, 0xBB, 0x08, + 0xD1, 0x3F, 0xE1, 0xFC, 0x0B, 0x94, 0xB3, 0x25, 0xEF, 0x7C, 0xA6, 0xD7, + 0xD1, 0xAF, 0x9F, 0xFF, 0x96, 0x9A, 0xF5, 0x91, 0x7B, 0x98, 0x0B, 0x77, + 0xD4, 0x7E, 0xE8, 0x07, 0xD2, 0x62, 0xB5, 0x95, 0x39, 0xE3, 0xF3, 0xF1, + 0x6D, 0x0F, 0x0E, 0x65, 0x84, 0x8A, 0x63, 0x54, 0xC5, 0x80, 0xB6, 0xE0, + 0x9E, 0x4B, 0x7D, 0x47, 0x26, 0xA7, 0x01, 0x08, 0x5D, 0xD1, 0x88, 0x9E, + 0xD7, 0xC3, 0x32, 0x44, 0xFA, 0x82, 0x4A, 0x0A, 0x68, 0x54, 0x7F, 0x38, + 0x53, 0x03, 0xCC, 0xA4, 0x00, 0x33, 0x64, 0x51, 0x59, 0x0B, 0xA3, 0x82, + 0x91, 0x7A, 0x5E, 0xEC, 0x16, 0xC2, 0xF3, 0x2A, 0xE6, 0x62, 0xDA, 0x2A, + 0xDB, 0x59, 0x62, 0x10, 0x25, 0x4A, 0x2A, 0x81, 0x0B, 0x47, 0x07, 0x43, + 0x06, 0x70, 0x87, 0xD2, 0xFA, 0x93, 0x11, 0x29, 0x7A, 0x48, 0x4D, 0xEB, + 0x94, 0xC7, 0x70, 0x4D, 0xAF, 0x67, 0xD5, 0x51, 0xB1, 0x80, 0x20, 0x01, + 0x01, 0xB4, 0x7A, 0x08, 0xA6, 0x90, 0x7F, 0x4E, 0xE0, 0xEF, 0x07, 0x41, + 0x87, 0xAF, 0x6A, 0xA5, 0x5E, 0x8B, 0xFB, 0xCF, 0x50, 0xB2, 0x9A, 0x54, + 0xAF, 0xC3, 0x89, 0xBA, 0x58, 0x2D, 0xF5, 0x30, 0x98, 0xB1, 0x36, 0x72, + 0x39, 0x7E, 0x49, 0x04, 0xFD, 0x29, 0xA7, 0x4C, 0x79, 0xE4, 0x05, 0x57, + 0xDB, 0x94, 0xB9, 0x16, 0x53, 0x8D, 0x46, 0xB3, 0x1D, 0x95, 0x61, 0x57, + 0x56, 0x7F, 0xAF, 0xF0, 0x16, 0x5B, 0x61, 0x58, 0x6F, 0x36, 0x50, 0x11, + 0x0B, 0xD8, 0xAC, 0x2B, 0x95, 0x16, 0x1A, 0x0E, 0x1F, 0x08, 0xCD, 0x36, + 0x34, 0x65, 0x10, 0x62, 0x66, 0xD5, 0x80, 0x5F, 0x14, 0x20, 0x5F, 0x2D, + 0x0C, 0xA0, 0x78, 0x0A, 0x68, 0xD6, 0x2C, 0xD7, 0xE9, 0x6F, 0x2B, 0xD2, + 0x4A, 0x05, 0x93, 0xFC, 0x9E, 0x6F, 0x6B, 0x67, 0xFF, 0x88, 0xF1, 0x4E, + 0xA5, 0x69, 0x4A, 0x52, 0x37, 0x05, 0xEA, 0xC6, 0x16, 0x8D, 0xD2, 0xC4, + 0x99, 0xD1, 0x82, 0x2B, 0x3B, 0xBA, 0x35, 0x75, 0xF7, 0x51, 0x51, 0x58, + 0xF3, 0xC8, 0x07, 0xDD, 0xE4, 0xB4, 0x03, 0x7F +}; + +static const unsigned char TA16_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA17_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x29, 0x47, 0x55, 0x41, 0x4E, 0x47, 0x20, 0x44, 0x4F, 0x4E, 0x47, + 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, + 0x20, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x20, 0x43, + 0x4F, 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x47, 0x44, 0x43, 0x41, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x41, 0x55, 0x54, 0x48, 0x20, 0x52, 0x35, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA17_RSA_N[] = { + 0xD9, 0xA3, 0x16, 0xF0, 0xC8, 0x74, 0x74, 0x77, 0x9B, 0xEF, 0x33, 0x0D, + 0x3B, 0x06, 0x7E, 0x55, 0xFC, 0xB5, 0x60, 0x8F, 0x76, 0x86, 0x12, 0x42, + 0x7D, 0x56, 0x66, 0x3E, 0x88, 0x82, 0xED, 0x72, 0x63, 0x0E, 0x9E, 0x8B, + 0xDD, 0x34, 0x2C, 0x02, 0x51, 0x51, 0xC3, 0x19, 0xFD, 0x59, 0x54, 0x84, + 0xC9, 0xF1, 0x6B, 0xB3, 0x4C, 0xB0, 0xE9, 0xE8, 0x46, 0x5D, 0x38, 0xC6, + 0xA2, 0xA7, 0x2E, 0x11, 0x57, 0xBA, 0x82, 0x15, 0xA2, 0x9C, 0x8F, 0x6D, + 0xB0, 0x99, 0x4A, 0x0A, 0xF2, 0xEB, 0x89, 0x70, 0x63, 0x4E, 0x79, 0xC4, + 0xB7, 0x5B, 0xBD, 0xA2, 0x5D, 0xB1, 0xF2, 0x41, 0x02, 0x2B, 0xAD, 0xA9, + 0x3A, 0xA3, 0xEC, 0x79, 0x0A, 0xEC, 0x5F, 0x3A, 0xE3, 0xFD, 0xEF, 0x80, + 0x3C, 0xAD, 0x34, 0x9B, 0x1A, 0xAB, 0x88, 0x26, 0x7B, 0x56, 0xA2, 0x82, + 0x86, 0x1F, 0xEB, 0x35, 0x89, 0x83, 0x7F, 0x5F, 0xAE, 0x29, 0x4E, 0x3D, + 0xB6, 0x6E, 0xEC, 0xAE, 0xC1, 0xF0, 0x27, 0x9B, 0xAE, 0xE3, 0xF4, 0xEC, + 0xEF, 0xAE, 0x7F, 0xF7, 0x86, 0x3D, 0x72, 0x7A, 0xEB, 0xA5, 0xFB, 0x59, + 0x4E, 0xA7, 0xEB, 0x95, 0x8C, 0x22, 0x39, 0x79, 0xE1, 0x2D, 0x08, 0x8F, + 0xCC, 0xBC, 0x91, 0xB8, 0x41, 0xF7, 0x14, 0xC1, 0x23, 0xA9, 0xC3, 0xAD, + 0x9A, 0x45, 0x44, 0xB3, 0xB2, 0xD7, 0x2C, 0xCD, 0xC6, 0x29, 0xE2, 0x50, + 0x10, 0xAE, 0x5C, 0xCB, 0x82, 0x8E, 0x17, 0x18, 0x36, 0x7D, 0x97, 0xE6, + 0x88, 0x9A, 0xB0, 0x4D, 0x34, 0x09, 0xF4, 0x2C, 0xB9, 0x5A, 0x66, 0x2A, + 0xB0, 0x17, 0x9B, 0x9E, 0x1E, 0x76, 0x9D, 0x4A, 0x66, 0x31, 0x41, 0xDF, + 0x3F, 0xFB, 0xC5, 0x06, 0xEF, 0x1B, 0xB6, 0x7E, 0x1A, 0x46, 0x36, 0xF7, + 0x64, 0x63, 0x3B, 0xE3, 0x39, 0x18, 0x23, 0xE7, 0x67, 0x75, 0x14, 0xD5, + 0x75, 0x57, 0x92, 0x37, 0xBD, 0xBE, 0x6A, 0x1B, 0x26, 0x50, 0xF2, 0x36, + 0x26, 0x06, 0x90, 0xC5, 0x70, 0x01, 0x64, 0x6D, 0x76, 0x66, 0xE1, 0x91, + 0xDB, 0x6E, 0x07, 0xC0, 0x61, 0x80, 0x2E, 0xB2, 0x2E, 0x2F, 0x8C, 0x70, + 0xA7, 0xD1, 0x3B, 0x3C, 0xB3, 0x91, 0xE4, 0x6E, 0xB6, 0xC4, 0x3B, 0x70, + 0xF2, 0x6C, 0x92, 0x97, 0x09, 0xCD, 0x47, 0x7D, 0x18, 0xC0, 0xF3, 0xBB, + 0x9E, 0x0F, 0xD6, 0x8B, 0xAE, 0x07, 0xB6, 0x5A, 0x0F, 0xCE, 0x0B, 0x0C, + 0x47, 0xA7, 0xE5, 0x3E, 0xB8, 0xBD, 0x7D, 0xC7, 0x9B, 0x35, 0xA0, 0x61, + 0x97, 0x3A, 0x41, 0x75, 0x17, 0xCC, 0x2B, 0x96, 0x77, 0x2A, 0x92, 0x21, + 0x1E, 0xD9, 0x95, 0x76, 0x20, 0x67, 0x68, 0xCF, 0x0D, 0xBD, 0xDF, 0xD6, + 0x1F, 0x09, 0x6A, 0x9A, 0xE2, 0xCC, 0x73, 0x71, 0xA4, 0x2F, 0x7D, 0x12, + 0x80, 0xB7, 0x53, 0x30, 0x46, 0x5E, 0x4B, 0x54, 0x99, 0x0F, 0x67, 0xC9, + 0xA5, 0xC8, 0xF2, 0x20, 0xC1, 0x82, 0xEC, 0x9D, 0x11, 0xDF, 0xC2, 0x02, + 0xFB, 0x1A, 0x3B, 0xD1, 0xED, 0x20, 0x9A, 0xEF, 0x65, 0x64, 0x92, 0x10, + 0x0D, 0x2A, 0xE2, 0xDE, 0x70, 0xF1, 0x18, 0x67, 0x82, 0x8C, 0x61, 0xDE, + 0xB8, 0xBC, 0xD1, 0x2F, 0x9C, 0xFB, 0x0F, 0xD0, 0x2B, 0xED, 0x1B, 0x76, + 0xB9, 0xE4, 0x39, 0x55, 0xF8, 0xF8, 0xA1, 0x1D, 0xB8, 0xAA, 0x80, 0x00, + 0x4C, 0x82, 0xE7, 0xB2, 0x7F, 0x09, 0xB8, 0xBC, 0x30, 0xA0, 0x2F, 0x0D, + 0xF5, 0x52, 0x9E, 0x8E, 0xF7, 0x92, 0xB3, 0x0A, 0x00, 0x1D, 0x00, 0x54, + 0x97, 0x06, 0xE0, 0xB1, 0x07, 0xD9, 0xC7, 0x0F, 0x5C, 0x65, 0x7D, 0x3C, + 0x6D, 0x59, 0x57, 0xE4, 0xED, 0xA5, 0x8D, 0xE9, 0x40, 0x53, 0x9F, 0x15, + 0x4B, 0xA0, 0x71, 0xF6, 0x1A, 0x21, 0xE3, 0xDA, 0x70, 0x06, 0x21, 0x58, + 0x14, 0x87, 0x85, 0x77, 0x79, 0xAA, 0x82, 0x79 +}; + +static const unsigned char TA17_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA18_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x31 +}; + +static const unsigned char TA18_RSA_N[] = { + 0xB6, 0x11, 0x02, 0x8B, 0x1E, 0xE3, 0xA1, 0x77, 0x9B, 0x3B, 0xDC, 0xBF, + 0x94, 0x3E, 0xB7, 0x95, 0xA7, 0x40, 0x3C, 0xA1, 0xFD, 0x82, 0xF9, 0x7D, + 0x32, 0x06, 0x82, 0x71, 0xF6, 0xF6, 0x8C, 0x7F, 0xFB, 0xE8, 0xDB, 0xBC, + 0x6A, 0x2E, 0x97, 0x97, 0xA3, 0x8C, 0x4B, 0xF9, 0x2B, 0xF6, 0xB1, 0xF9, + 0xCE, 0x84, 0x1D, 0xB1, 0xF9, 0xC5, 0x97, 0xDE, 0xEF, 0xB9, 0xF2, 0xA3, + 0xE9, 0xBC, 0x12, 0x89, 0x5E, 0xA7, 0xAA, 0x52, 0xAB, 0xF8, 0x23, 0x27, + 0xCB, 0xA4, 0xB1, 0x9C, 0x63, 0xDB, 0xD7, 0x99, 0x7E, 0xF0, 0x0A, 0x5E, + 0xEB, 0x68, 0xA6, 0xF4, 0xC6, 0x5A, 0x47, 0x0D, 0x4D, 0x10, 0x33, 0xE3, + 0x4E, 0xB1, 0x13, 0xA3, 0xC8, 0x18, 0x6C, 0x4B, 0xEC, 0xFC, 0x09, 0x90, + 0xDF, 0x9D, 0x64, 0x29, 0x25, 0x23, 0x07, 0xA1, 0xB4, 0xD2, 0x3D, 0x2E, + 0x60, 0xE0, 0xCF, 0xD2, 0x09, 0x87, 0xBB, 0xCD, 0x48, 0xF0, 0x4D, 0xC2, + 0xC2, 0x7A, 0x88, 0x8A, 0xBB, 0xBA, 0xCF, 0x59, 0x19, 0xD6, 0xAF, 0x8F, + 0xB0, 0x07, 0xB0, 0x9E, 0x31, 0xF1, 0x82, 0xC1, 0xC0, 0xDF, 0x2E, 0xA6, + 0x6D, 0x6C, 0x19, 0x0E, 0xB5, 0xD8, 0x7E, 0x26, 0x1A, 0x45, 0x03, 0x3D, + 0xB0, 0x79, 0xA4, 0x94, 0x28, 0xAD, 0x0F, 0x7F, 0x26, 0xE5, 0xA8, 0x08, + 0xFE, 0x96, 0xE8, 0x3C, 0x68, 0x94, 0x53, 0xEE, 0x83, 0x3A, 0x88, 0x2B, + 0x15, 0x96, 0x09, 0xB2, 0xE0, 0x7A, 0x8C, 0x2E, 0x75, 0xD6, 0x9C, 0xEB, + 0xA7, 0x56, 0x64, 0x8F, 0x96, 0x4F, 0x68, 0xAE, 0x3D, 0x97, 0xC2, 0x84, + 0x8F, 0xC0, 0xBC, 0x40, 0xC0, 0x0B, 0x5C, 0xBD, 0xF6, 0x87, 0xB3, 0x35, + 0x6C, 0xAC, 0x18, 0x50, 0x7F, 0x84, 0xE0, 0x4C, 0xCD, 0x92, 0xD3, 0x20, + 0xE9, 0x33, 0xBC, 0x52, 0x99, 0xAF, 0x32, 0xB5, 0x29, 0xB3, 0x25, 0x2A, + 0xB4, 0x48, 0xF9, 0x72, 0xE1, 0xCA, 0x64, 0xF7, 0xE6, 0x82, 0x10, 0x8D, + 0xE8, 0x9D, 0xC2, 0x8A, 0x88, 0xFA, 0x38, 0x66, 0x8A, 0xFC, 0x63, 0xF9, + 0x01, 0xF9, 0x78, 0xFD, 0x7B, 0x5C, 0x77, 0xFA, 0x76, 0x87, 0xFA, 0xEC, + 0xDF, 0xB1, 0x0E, 0x79, 0x95, 0x57, 0xB4, 0xBD, 0x26, 0xEF, 0xD6, 0x01, + 0xD1, 0xEB, 0x16, 0x0A, 0xBB, 0x8E, 0x0B, 0xB5, 0xC5, 0xC5, 0x8A, 0x55, + 0xAB, 0xD3, 0xAC, 0xEA, 0x91, 0x4B, 0x29, 0xCC, 0x19, 0xA4, 0x32, 0x25, + 0x4E, 0x2A, 0xF1, 0x65, 0x44, 0xD0, 0x02, 0xCE, 0xAA, 0xCE, 0x49, 0xB4, + 0xEA, 0x9F, 0x7C, 0x83, 0xB0, 0x40, 0x7B, 0xE7, 0x43, 0xAB, 0xA7, 0x6C, + 0xA3, 0x8F, 0x7D, 0x89, 0x81, 0xFA, 0x4C, 0xA5, 0xFF, 0xD5, 0x8E, 0xC3, + 0xCE, 0x4B, 0xE0, 0xB5, 0xD8, 0xB3, 0x8E, 0x45, 0xCF, 0x76, 0xC0, 0xED, + 0x40, 0x2B, 0xFD, 0x53, 0x0F, 0xB0, 0xA7, 0xD5, 0x3B, 0x0D, 0xB1, 0x8A, + 0xA2, 0x03, 0xDE, 0x31, 0xAD, 0xCC, 0x77, 0xEA, 0x6F, 0x7B, 0x3E, 0xD6, + 0xDF, 0x91, 0x22, 0x12, 0xE6, 0xBE, 0xFA, 0xD8, 0x32, 0xFC, 0x10, 0x63, + 0x14, 0x51, 0x72, 0xDE, 0x5D, 0xD6, 0x16, 0x93, 0xBD, 0x29, 0x68, 0x33, + 0xEF, 0x3A, 0x66, 0xEC, 0x07, 0x8A, 0x26, 0xDF, 0x13, 0xD7, 0x57, 0x65, + 0x78, 0x27, 0xDE, 0x5E, 0x49, 0x14, 0x00, 0xA2, 0x00, 0x7F, 0x9A, 0xA8, + 0x21, 0xB6, 0xA9, 0xB1, 0x95, 0xB0, 0xA5, 0xB9, 0x0D, 0x16, 0x11, 0xDA, + 0xC7, 0x6C, 0x48, 0x3C, 0x40, 0xE0, 0x7E, 0x0D, 0x5A, 0xCD, 0x56, 0x3C, + 0xD1, 0x97, 0x05, 0xB9, 0xCB, 0x4B, 0xED, 0x39, 0x4B, 0x9C, 0xC4, 0x3F, + 0xD2, 0x55, 0x13, 0x6E, 0x24, 0xB0, 0xD6, 0x71, 0xFA, 0xF4, 0xC1, 0xBA, + 0xCC, 0xED, 0x1B, 0xF5, 0xFE, 0x81, 0x41, 0xD8, 0x00, 0x98, 0x3D, 0x3A, + 0xC8, 0xAE, 0x7A, 0x98, 0x37, 0x18, 0x05, 0x95 +}; + +static const unsigned char TA18_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA19_DN[] = { + 0x30, 0x81, 0x98, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3B, + 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA19_RSA_N[] = { + 0xD5, 0x0C, 0x3A, 0xC4, 0x2A, 0xF9, 0x4E, 0xE2, 0xF5, 0xBE, 0x19, 0x97, + 0x5F, 0x8E, 0x88, 0x53, 0xB1, 0x1F, 0x3F, 0xCB, 0xCF, 0x9F, 0x20, 0x13, + 0x6D, 0x29, 0x3A, 0xC8, 0x0F, 0x7D, 0x3C, 0xF7, 0x6B, 0x76, 0x38, 0x63, + 0xD9, 0x36, 0x60, 0xA8, 0x9B, 0x5E, 0x5C, 0x00, 0x80, 0xB2, 0x2F, 0x59, + 0x7F, 0xF6, 0x87, 0xF9, 0x25, 0x43, 0x86, 0xE7, 0x69, 0x1B, 0x52, 0x9A, + 0x90, 0xE1, 0x71, 0xE3, 0xD8, 0x2D, 0x0D, 0x4E, 0x6F, 0xF6, 0xC8, 0x49, + 0xD9, 0xB6, 0xF3, 0x1A, 0x56, 0xAE, 0x2B, 0xB6, 0x74, 0x14, 0xEB, 0xCF, + 0xFB, 0x26, 0xE3, 0x1A, 0xBA, 0x1D, 0x96, 0x2E, 0x6A, 0x3B, 0x58, 0x94, + 0x89, 0x47, 0x56, 0xFF, 0x25, 0xA0, 0x93, 0x70, 0x53, 0x83, 0xDA, 0x84, + 0x74, 0x14, 0xC3, 0x67, 0x9E, 0x04, 0x68, 0x3A, 0xDF, 0x8E, 0x40, 0x5A, + 0x1D, 0x4A, 0x4E, 0xCF, 0x43, 0x91, 0x3B, 0xE7, 0x56, 0xD6, 0x00, 0x70, + 0xCB, 0x52, 0xEE, 0x7B, 0x7D, 0xAE, 0x3A, 0xE7, 0xBC, 0x31, 0xF9, 0x45, + 0xF6, 0xC2, 0x60, 0xCF, 0x13, 0x59, 0x02, 0x2B, 0x80, 0xCC, 0x34, 0x47, + 0xDF, 0xB9, 0xDE, 0x90, 0x65, 0x6D, 0x02, 0xCF, 0x2C, 0x91, 0xA6, 0xA6, + 0xE7, 0xDE, 0x85, 0x18, 0x49, 0x7C, 0x66, 0x4E, 0xA3, 0x3A, 0x6D, 0xA9, + 0xB5, 0xEE, 0x34, 0x2E, 0xBA, 0x0D, 0x03, 0xB8, 0x33, 0xDF, 0x47, 0xEB, + 0xB1, 0x6B, 0x8D, 0x25, 0xD9, 0x9B, 0xCE, 0x81, 0xD1, 0x45, 0x46, 0x32, + 0x96, 0x70, 0x87, 0xDE, 0x02, 0x0E, 0x49, 0x43, 0x85, 0xB6, 0x6C, 0x73, + 0xBB, 0x64, 0xEA, 0x61, 0x41, 0xAC, 0xC9, 0xD4, 0x54, 0xDF, 0x87, 0x2F, + 0xC7, 0x22, 0xB2, 0x26, 0xCC, 0x9F, 0x59, 0x54, 0x68, 0x9F, 0xFC, 0xBE, + 0x2A, 0x2F, 0xC4, 0x55, 0x1C, 0x75, 0x40, 0x60, 0x17, 0x85, 0x02, 0x55, + 0x39, 0x8B, 0x7F, 0x05 +}; + +static const unsigned char TA19_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA20_DN[] = { + 0x30, 0x81, 0xBF, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x33, 0x30, + 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x45, + 0x43, 0x31 +}; + +static const unsigned char TA20_EC_Q[] = { + 0x04, 0x84, 0x13, 0xC9, 0xD0, 0xBA, 0x6D, 0x41, 0x7B, 0xE2, 0x6C, 0xD0, + 0xEB, 0x55, 0x5F, 0x66, 0x02, 0x1A, 0x24, 0xF4, 0x5B, 0x89, 0x69, 0x47, + 0xE3, 0xB8, 0xC2, 0x7D, 0xF1, 0xF2, 0x02, 0xC5, 0x9F, 0xA0, 0xF6, 0x5B, + 0xD5, 0x8B, 0x06, 0x19, 0x86, 0x4F, 0x53, 0x10, 0x6D, 0x07, 0x24, 0x27, + 0xA1, 0xA0, 0xF8, 0xD5, 0x47, 0x19, 0x61, 0x4C, 0x7D, 0xCA, 0x93, 0x27, + 0xEA, 0x74, 0x0C, 0xEF, 0x6F, 0x96, 0x09, 0xFE, 0x63, 0xEC, 0x70, 0x5D, + 0x36, 0xAD, 0x67, 0x77, 0xAE, 0xC9, 0x9D, 0x7C, 0x55, 0x44, 0x3A, 0xA2, + 0x63, 0x51, 0x1F, 0xF5, 0xE3, 0x62, 0xD4, 0xA9, 0x47, 0x07, 0x3E, 0xCC, + 0x20 +}; + +static const unsigned char TA21_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA21_RSA_N[] = { + 0xB6, 0x80, 0x0E, 0xC4, 0x79, 0xBD, 0x05, 0x8C, 0x7D, 0xB0, 0xA3, 0x9D, + 0x4D, 0x22, 0x4D, 0xCB, 0xF0, 0x41, 0x97, 0x4D, 0x59, 0xE0, 0xD1, 0xFE, + 0x56, 0x8C, 0x97, 0xF2, 0xD7, 0xBD, 0x8F, 0x6C, 0xB7, 0x23, 0x8F, 0x5F, + 0xD5, 0xC4, 0xD8, 0x41, 0xCB, 0xF2, 0x02, 0x1E, 0x71, 0xE5, 0xE9, 0xF6, + 0x5E, 0xCB, 0x08, 0x2A, 0x5E, 0x30, 0xF2, 0x2D, 0x66, 0xC7, 0x84, 0x1B, + 0x64, 0x57, 0x38, 0x9D, 0x75, 0x2D, 0x56, 0xC6, 0x2F, 0x61, 0xEF, 0x96, + 0xFC, 0x20, 0x46, 0xBD, 0xEB, 0xD4, 0x7B, 0x3F, 0x3F, 0x7C, 0x47, 0x38, + 0x04, 0xA9, 0x1B, 0xAA, 0x52, 0xDF, 0x13, 0x37, 0xD3, 0x15, 0x15, 0x4E, + 0xBD, 0x5F, 0x7C, 0xAF, 0xAD, 0x63, 0xC7, 0x79, 0xDC, 0x08, 0x7B, 0xD5, + 0xA0, 0xE5, 0xF7, 0x5B, 0x75, 0xAC, 0x80, 0x55, 0x99, 0x92, 0x61, 0x9B, + 0xCD, 0x2A, 0x17, 0x7D, 0xDB, 0x8F, 0xF4, 0xB5, 0x6A, 0xEA, 0x17, 0x4A, + 0x64, 0x28, 0x66, 0x15, 0x29, 0x6C, 0x02, 0xF1, 0x6B, 0xD5, 0xBA, 0xA3, + 0x33, 0xDC, 0x5A, 0x67, 0xA7, 0x05, 0xE2, 0xBF, 0x65, 0xB6, 0x16, 0xB0, + 0x10, 0xED, 0xCD, 0x50, 0x33, 0xC9, 0x70, 0x50, 0xEC, 0x19, 0x8E, 0xB0, + 0xC7, 0xF2, 0x74, 0x5B, 0x6B, 0x44, 0xC6, 0x7D, 0x96, 0xB9, 0x98, 0x08, + 0x59, 0x66, 0xDE, 0x29, 0x01, 0x9B, 0xF4, 0x2A, 0x6D, 0xD3, 0x15, 0x3A, + 0x90, 0x6A, 0x67, 0xF1, 0xB4, 0x6B, 0x66, 0xD9, 0x21, 0xEB, 0xCA, 0xD9, + 0x62, 0x7C, 0x46, 0x10, 0x5C, 0xDE, 0x75, 0x49, 0x67, 0x9E, 0x42, 0xF9, + 0xFE, 0x75, 0xA9, 0xA3, 0xAD, 0xFF, 0x76, 0x0A, 0x67, 0x40, 0xE3, 0xC5, + 0xF7, 0x8D, 0xC7, 0x85, 0x9A, 0x59, 0x9E, 0x62, 0x9A, 0x6A, 0xED, 0x45, + 0x87, 0x98, 0x67, 0xB2, 0xD5, 0x4A, 0x3C, 0xD7, 0xB4, 0x3B, 0x00, 0x0D, + 0xC0, 0x8F, 0x1F, 0xE1, 0x40, 0xC4, 0xAE, 0x6C, 0x21, 0xDC, 0x49, 0x7E, + 0x7E, 0xCA, 0xB2, 0x8D, 0x6D, 0xB6, 0xBF, 0x93, 0x2F, 0xA1, 0x5C, 0x3E, + 0x8F, 0xCA, 0xED, 0x80, 0x8E, 0x58, 0xE1, 0xDB, 0x57, 0xCF, 0x85, 0x36, + 0x38, 0xB2, 0x71, 0xA4, 0x09, 0x8C, 0x92, 0x89, 0x08, 0x88, 0x48, 0xF1, + 0x40, 0x63, 0x18, 0xB2, 0x5B, 0x8C, 0x5A, 0xE3, 0xC3, 0xD3, 0x17, 0xAA, + 0xAB, 0x19, 0xA3, 0x2C, 0x1B, 0xE4, 0xD5, 0xC6, 0xE2, 0x66, 0x7A, 0xD7, + 0x82, 0x19, 0xA6, 0x3B, 0x16, 0x2C, 0x2F, 0x71, 0x87, 0x5F, 0x45, 0x9E, + 0x95, 0x73, 0x93, 0xC2, 0x42, 0x81, 0x21, 0x13, 0x96, 0xD7, 0x9D, 0xBB, + 0x93, 0x68, 0x15, 0xFA, 0x9D, 0xA4, 0x1D, 0x8C, 0xF2, 0x81, 0xE0, 0x58, + 0x06, 0xBD, 0xC9, 0xB6, 0xE3, 0xF6, 0x89, 0x5D, 0x89, 0xF9, 0xAC, 0x44, + 0xA1, 0xCB, 0x6B, 0xFA, 0x16, 0xF1, 0xC7, 0x50, 0x3D, 0x24, 0xDA, 0xF7, + 0xC3, 0xE4, 0x87, 0xD5, 0x56, 0xF1, 0x4F, 0x90, 0x30, 0xFA, 0x45, 0x09, + 0x59, 0xDA, 0x34, 0xCE, 0xE0, 0x13, 0x1C, 0x04, 0x7C, 0x00, 0xD4, 0x9B, + 0x86, 0xA4, 0x40, 0xBC, 0xD9, 0xDC, 0x4C, 0x57, 0x7E, 0xAE, 0xB7, 0x33, + 0xB6, 0x5E, 0x76, 0xE1, 0x65, 0x8B, 0x66, 0xDF, 0x8D, 0xCA, 0xD7, 0x98, + 0xAF, 0xCE, 0x36, 0x98, 0x8C, 0x9C, 0x83, 0x99, 0x03, 0x70, 0xF3, 0xAF, + 0x74, 0xED, 0xC6, 0x0E, 0x36, 0xE7, 0xBD, 0xEC, 0xC1, 0x73, 0xA7, 0x94, + 0x5A, 0xCB, 0x92, 0x64, 0x82, 0xA6, 0x00, 0xC1, 0x70, 0xA1, 0x6E, 0x2C, + 0x29, 0xE1, 0x58, 0x57, 0xEC, 0x5A, 0x7C, 0x99, 0x6B, 0x25, 0xA4, 0x90, + 0x3A, 0x80, 0xF4, 0x20, 0x9D, 0x9A, 0xCE, 0xC7, 0x2D, 0xF9, 0xB2, 0x4B, + 0x29, 0x95, 0x83, 0xE9, 0x35, 0x8D, 0xA7, 0x49, 0x48, 0xA7, 0x0F, 0x4C, + 0x19, 0x91, 0xD0, 0xF5, 0xBF, 0x10, 0xE0, 0x71 +}; + +static const unsigned char TA21_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA22_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x17, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, + 0x33 +}; + +static const unsigned char TA22_EC_Q[] = { + 0x04, 0x23, 0xA5, 0x0C, 0xB8, 0x2D, 0x12, 0xF5, 0x28, 0xF3, 0xB1, 0xB2, + 0xDD, 0xE2, 0x02, 0x12, 0x80, 0x9E, 0x39, 0x5F, 0x49, 0x4D, 0x9F, 0xC9, + 0x25, 0x34, 0x59, 0x74, 0xEC, 0xBB, 0x06, 0x1C, 0xE7, 0xC0, 0x72, 0xAF, + 0xE8, 0xAE, 0x2F, 0xE1, 0x41, 0x54, 0x87, 0x14, 0xA8, 0x4A, 0xB2, 0xE8, + 0x7C, 0x82, 0xE6, 0x5B, 0x6A, 0xB5, 0xDC, 0xB3, 0x75, 0xCE, 0x8B, 0x06, + 0xD0, 0x86, 0x23, 0xBF, 0x46, 0xD5, 0x8E, 0x0F, 0x3F, 0x04, 0xF4, 0xD7, + 0x1C, 0x92, 0x7E, 0xF6, 0xA5, 0x63, 0xC2, 0xF5, 0x5F, 0x8E, 0x2E, 0x4F, + 0xA1, 0x18, 0x19, 0x02, 0x2B, 0x32, 0x0A, 0x82, 0x64, 0x7D, 0x16, 0x93, + 0xD1 +}; + +static const unsigned char TA23_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x32, 0x35, 0x36, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA23_EC_Q[] = { + 0x04, 0x7E, 0xFB, 0x6C, 0xE6, 0x23, 0xE3, 0x73, 0x32, 0x08, 0xCA, 0x60, + 0xE6, 0x53, 0x9C, 0xBA, 0x74, 0x8D, 0x18, 0xB0, 0x78, 0x90, 0x52, 0x80, + 0xDD, 0x38, 0xC0, 0x4A, 0x1D, 0xD1, 0xA8, 0xCC, 0x93, 0xA4, 0x97, 0x06, + 0x38, 0xCA, 0x0D, 0x15, 0x62, 0xC6, 0x8E, 0x01, 0x2A, 0x65, 0x9D, 0xAA, + 0xDF, 0x34, 0x91, 0x2E, 0x81, 0xC1, 0xE4, 0x33, 0x92, 0x31, 0xC4, 0xFD, + 0x09, 0x3A, 0xA6, 0x3F, 0xAD +}; + +static const unsigned char TA24_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x36 +}; + +static const unsigned char TA24_RSA_N[] = { + 0xAC, 0xAC, 0x74, 0x32, 0xE8, 0xB3, 0x65, 0xE5, 0xBA, 0xED, 0x43, 0x26, + 0x1D, 0xA6, 0x89, 0x0D, 0x45, 0xBA, 0x29, 0x88, 0xB2, 0xA4, 0x1D, 0x63, + 0xDD, 0xD3, 0xC1, 0x2C, 0x09, 0x57, 0x89, 0x39, 0xA1, 0x55, 0xE9, 0x67, + 0x34, 0x77, 0x0C, 0x6E, 0xE4, 0x55, 0x1D, 0x52, 0x25, 0xD2, 0x13, 0x6B, + 0x5E, 0xE1, 0x1D, 0xA9, 0xB7, 0x7D, 0x89, 0x32, 0x5F, 0x0D, 0x9E, 0x9F, + 0x2C, 0x7A, 0x63, 0x60, 0x40, 0x1F, 0xA6, 0xB0, 0xB6, 0x78, 0x8F, 0x99, + 0x54, 0x96, 0x08, 0x58, 0xAE, 0xE4, 0x06, 0xBC, 0x62, 0x05, 0x02, 0x16, + 0xBF, 0xAF, 0xA8, 0x23, 0x03, 0xB6, 0x94, 0x0F, 0xBC, 0x6E, 0x6C, 0xC2, + 0xCB, 0xD5, 0xA6, 0xBB, 0x0C, 0xE9, 0xF6, 0xC1, 0x02, 0xFB, 0x21, 0xDE, + 0x66, 0xDD, 0x17, 0xAB, 0x74, 0x42, 0xEF, 0xF0, 0x74, 0x2F, 0x25, 0xF4, + 0xEA, 0x6B, 0x55, 0x5B, 0x90, 0xDB, 0x9D, 0xDF, 0x5E, 0x87, 0x0A, 0x40, + 0xFB, 0xAD, 0x19, 0x6B, 0xFB, 0xF7, 0xCA, 0x60, 0x88, 0xDE, 0xDA, 0xC1, + 0x8F, 0xD6, 0xAE, 0xD5, 0x7F, 0xD4, 0x3C, 0x83, 0xEE, 0xD7, 0x16, 0x4C, + 0x83, 0x45, 0x33, 0x6B, 0x27, 0xD0, 0x86, 0xD0, 0x1C, 0x2D, 0x6B, 0xF3, + 0xAB, 0x7D, 0xF1, 0x85, 0xA9, 0xF5, 0x28, 0xD2, 0xAD, 0xEF, 0xF3, 0x84, + 0x4B, 0x1C, 0x87, 0xFC, 0x13, 0xA3, 0x3A, 0x72, 0xA2, 0x5A, 0x11, 0x2B, + 0xD6, 0x27, 0x71, 0x27, 0xED, 0x81, 0x2D, 0x6D, 0x66, 0x81, 0x92, 0x87, + 0xB4, 0x1B, 0x58, 0x7A, 0xCC, 0x3F, 0x0A, 0xFA, 0x46, 0x4F, 0x4D, 0x78, + 0x5C, 0xF8, 0x2B, 0x48, 0xE3, 0x04, 0x84, 0xCB, 0x5D, 0xF6, 0xB4, 0x6A, + 0xB3, 0x65, 0xFC, 0x42, 0x9E, 0x51, 0x26, 0x23, 0x20, 0xCB, 0x3D, 0x14, + 0xF9, 0x81, 0xED, 0x65, 0x16, 0x00, 0x4F, 0x1A, 0x64, 0x97, 0x66, 0x08, + 0xCF, 0x8C, 0x7B, 0xE3, 0x2B, 0xC0, 0x9D, 0xF9, 0x14, 0xF2, 0x1B, 0xF1, + 0x56, 0x6A, 0x16, 0xBF, 0x2C, 0x85, 0x85, 0xCD, 0x78, 0x38, 0x9A, 0xEB, + 0x42, 0x6A, 0x02, 0x34, 0x18, 0x83, 0x17, 0x4E, 0x94, 0x56, 0xF8, 0xB6, + 0x82, 0xB5, 0xF3, 0x96, 0xDD, 0x3D, 0xF3, 0xBE, 0x7F, 0x20, 0x77, 0x3E, + 0x7B, 0x19, 0x23, 0x6B, 0x2C, 0xD4, 0x72, 0x73, 0x43, 0x57, 0x7D, 0xE0, + 0xF8, 0xD7, 0x69, 0x4F, 0x17, 0x36, 0x04, 0xF9, 0xC0, 0x90, 0x60, 0x37, + 0x45, 0xDE, 0xE6, 0x0C, 0xD8, 0x74, 0x8D, 0xAE, 0x9C, 0xA2, 0x6D, 0x74, + 0x5D, 0x42, 0xBE, 0x06, 0xF5, 0xD9, 0x64, 0x6E, 0x02, 0x10, 0xAC, 0x89, + 0xB0, 0x4C, 0x3B, 0x07, 0x4D, 0x40, 0x7E, 0x24, 0xC5, 0x8A, 0x98, 0x82, + 0x79, 0x8E, 0xA4, 0xA7, 0x82, 0x20, 0x8D, 0x23, 0xFA, 0x27, 0x71, 0xC9, + 0xDF, 0xC6, 0x41, 0x74, 0xA0, 0x4D, 0xF6, 0x91, 0x16, 0xDC, 0x46, 0x8C, + 0x5F, 0x29, 0x63, 0x31, 0x59, 0x71, 0x0C, 0xD8, 0x6F, 0xC2, 0xB6, 0x32, + 0x7D, 0xFB, 0xE6, 0x5D, 0x53, 0xA6, 0x7E, 0x15, 0xFC, 0xBB, 0x75, 0x7C, + 0x5D, 0xEC, 0xF8, 0xF6, 0x17, 0x1C, 0xEC, 0xC7, 0x6B, 0x19, 0xCB, 0xF3, + 0x7B, 0xF0, 0x2B, 0x07, 0xA5, 0xD9, 0x6C, 0x79, 0x54, 0x76, 0x6C, 0x9D, + 0x1C, 0xA6, 0x6E, 0x0E, 0xE9, 0x79, 0x0C, 0xA8, 0x23, 0x6A, 0xA3, 0xDF, + 0x1B, 0x30, 0x31, 0x9F, 0xB1, 0x54, 0x7B, 0xFE, 0x6A, 0xCB, 0x66, 0xAA, + 0xDC, 0x65, 0xD0, 0xA2, 0x9E, 0x4A, 0x9A, 0x07, 0x21, 0x6B, 0x81, 0x8F, + 0xDB, 0xC4, 0x59, 0xFA, 0xDE, 0x22, 0xC0, 0x04, 0x9C, 0xE3, 0xAA, 0x5B, + 0x36, 0x93, 0xE8, 0x3D, 0xBD, 0x7A, 0xA1, 0x9D, 0x0B, 0x76, 0xB1, 0x0B, + 0xC7, 0x9D, 0xFD, 0xCF, 0x98, 0xA8, 0x06, 0xC2, 0xF8, 0x2A, 0xA3, 0xA1, + 0x83, 0xA0, 0xB7, 0x25, 0x72, 0xA5, 0x02, 0xE3 +}; + +static const unsigned char TA24_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA25_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA25_EC_Q[] = { + 0x04, 0xF1, 0xB3, 0xCD, 0x38, 0xE4, 0x25, 0x43, 0xE5, 0xDE, 0x19, 0x09, + 0xBB, 0x81, 0x79, 0xA2, 0x15, 0x5F, 0x15, 0x63, 0x01, 0xDE, 0xC2, 0xAB, + 0xDD, 0xB3, 0xA6, 0x1B, 0x67, 0x4B, 0x80, 0x83, 0xAF, 0x99, 0xCB, 0xAC, + 0x17, 0xDB, 0x2B, 0x96, 0xCA, 0x7C, 0x52, 0x55, 0xE2, 0x1A, 0xE1, 0x3D, + 0x56, 0xF0, 0x2F, 0x16, 0x08, 0xFA, 0x15, 0xBC, 0x9B, 0xBB, 0x47, 0xE6, + 0x3F, 0xEE, 0xA8, 0xE1, 0x4C, 0x8C, 0xF5, 0xD3, 0x36, 0xF9, 0x38, 0x5D, + 0xAB, 0x70, 0x9A, 0x47, 0x0D, 0xE2, 0x81, 0x41, 0x06, 0xEB, 0x49, 0xF9, + 0xB0, 0x29, 0xDD, 0x33, 0xEC, 0x50, 0xA5, 0x7F, 0x79, 0x29, 0xB8, 0x20, + 0x98 +}; + +static const unsigned char TA26_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x35, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA26_EC_Q[] = { + 0x04, 0x47, 0x45, 0x0E, 0x96, 0xFB, 0x7D, 0x5D, 0xBF, 0xE9, 0x39, 0xD1, + 0x21, 0xF8, 0x9F, 0x0B, 0xB6, 0xD5, 0x7B, 0x1E, 0x92, 0x3A, 0x48, 0x59, + 0x1C, 0xF0, 0x62, 0x31, 0x2D, 0xC0, 0x7A, 0x28, 0xFE, 0x1A, 0xA7, 0x5C, + 0xB3, 0xB6, 0xCC, 0x97, 0xE7, 0x45, 0xD4, 0x58, 0xFA, 0xD1, 0x77, 0x6D, + 0x43, 0xA2, 0xC0, 0x87, 0x65, 0x34, 0x0A, 0x1F, 0x7A, 0xDD, 0xEB, 0x3C, + 0x33, 0xA1, 0xC5, 0x9D, 0x4D, 0xA4, 0x6F, 0x41, 0x95, 0x38, 0x7F, 0xC9, + 0x1E, 0x84, 0xEB, 0xD1, 0x9E, 0x49, 0x92, 0x87, 0x94, 0x87, 0x0C, 0x3A, + 0x85, 0x4A, 0x66, 0x9F, 0x9D, 0x59, 0x93, 0x4D, 0x97, 0x61, 0x06, 0x86, + 0x4A +}; + +static const unsigned char TA27_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x1E, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA27_RSA_N[] = { + 0xD3, 0xB2, 0x4A, 0xCF, 0x7A, 0x47, 0xEF, 0x75, 0x9B, 0x23, 0xFA, 0x3A, + 0x2F, 0xD6, 0x50, 0x45, 0x89, 0x35, 0x3A, 0xC6, 0x6B, 0xDB, 0xFE, 0xDB, + 0x00, 0x68, 0xA8, 0xE0, 0x03, 0x11, 0x1D, 0x37, 0x50, 0x08, 0x9F, 0x4D, + 0x4A, 0x68, 0x94, 0x35, 0xB3, 0x53, 0xD1, 0x94, 0x63, 0xA7, 0x20, 0x56, + 0xAF, 0xDE, 0x51, 0x78, 0xEC, 0x2A, 0x3D, 0xF3, 0x48, 0x48, 0x50, 0x3E, + 0x0A, 0xDF, 0x46, 0x55, 0x8B, 0x27, 0x6D, 0xC3, 0x10, 0x4D, 0x0D, 0x91, + 0x52, 0x43, 0xD8, 0x87, 0xE0, 0x5D, 0x4E, 0x36, 0xB5, 0x21, 0xCA, 0x5F, + 0x39, 0x40, 0x04, 0x5F, 0x5B, 0x7E, 0xCC, 0xA3, 0xC6, 0x2B, 0xA9, 0x40, + 0x1E, 0xD9, 0x36, 0x84, 0xD6, 0x48, 0xF3, 0x92, 0x1E, 0x34, 0x46, 0x20, + 0x24, 0xC1, 0xA4, 0x51, 0x8E, 0x4A, 0x1A, 0xEF, 0x50, 0x3F, 0x69, 0x5D, + 0x19, 0x7F, 0x45, 0xC3, 0xC7, 0x01, 0x8F, 0x51, 0xC9, 0x23, 0xE8, 0x72, + 0xAE, 0xB4, 0xBC, 0x56, 0x09, 0x7F, 0x12, 0xCB, 0x1C, 0xB1, 0xAF, 0x29, + 0x90, 0x0A, 0xC9, 0x55, 0xCC, 0x0F, 0xD3, 0xB4, 0x1A, 0xED, 0x47, 0x35, + 0x5A, 0x4A, 0xED, 0x9C, 0x73, 0x04, 0x21, 0xD0, 0xAA, 0xBD, 0x0C, 0x13, + 0xB5, 0x00, 0xCA, 0x26, 0x6C, 0xC4, 0x6B, 0x0C, 0x94, 0x5A, 0x95, 0x94, + 0xDA, 0x50, 0x9A, 0xF1, 0xFF, 0xA5, 0x2B, 0x66, 0x31, 0xA4, 0xC9, 0x38, + 0xA0, 0xDF, 0x1D, 0x1F, 0xB8, 0x09, 0x2E, 0xF3, 0xA7, 0xE8, 0x67, 0x52, + 0xAB, 0x95, 0x1F, 0xE0, 0x46, 0x3E, 0xD8, 0xA4, 0xC3, 0xCA, 0x5A, 0xC5, + 0x31, 0x80, 0xE8, 0x48, 0x9A, 0x9F, 0x94, 0x69, 0xFE, 0x19, 0xDD, 0xD8, + 0x73, 0x7C, 0x81, 0xCA, 0x96, 0xDE, 0x8E, 0xED, 0xB3, 0x32, 0x05, 0x65, + 0x84, 0x34, 0xE6, 0xE6, 0xFD, 0x57, 0x10, 0xB5, 0x5F, 0x76, 0xBF, 0x2F, + 0xB0, 0x10, 0x0D, 0xC5 +}; + +static const unsigned char TA27_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA28_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x53, 0x65, 0x63, 0x74, 0x6F, 0x72, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA28_RSA_N[] = { + 0xB6, 0x22, 0x94, 0xFC, 0xA4, 0x48, 0xAF, 0xE8, 0x47, 0x6B, 0x0A, 0xFB, + 0x27, 0x76, 0xE4, 0xF2, 0x3F, 0x8A, 0x3B, 0x7A, 0x4A, 0x2C, 0x31, 0x2A, + 0x8C, 0x8D, 0xB0, 0xA9, 0xC3, 0x31, 0x6B, 0xA8, 0x77, 0x76, 0x84, 0x26, + 0xB6, 0xAC, 0x81, 0x42, 0x0D, 0x08, 0xEB, 0x55, 0x58, 0xBB, 0x7A, 0xF8, + 0xBC, 0x65, 0x7D, 0xF2, 0xA0, 0x6D, 0x8B, 0xA8, 0x47, 0xE9, 0x62, 0x76, + 0x1E, 0x11, 0xEE, 0x08, 0x14, 0xD1, 0xB2, 0x44, 0x16, 0xF4, 0xEA, 0xD0, + 0xFA, 0x1E, 0x2F, 0x5E, 0xDB, 0xCB, 0x73, 0x41, 0xAE, 0xBC, 0x00, 0xB0, + 0x4A, 0x2B, 0x40, 0xB2, 0xAC, 0xE1, 0x3B, 0x4B, 0xC2, 0x2D, 0x9D, 0xE4, + 0xA1, 0x9B, 0xEC, 0x1A, 0x3A, 0x1E, 0xF0, 0x08, 0xB3, 0xD0, 0xE4, 0x24, + 0x35, 0x07, 0x9F, 0x9C, 0xB4, 0xC9, 0x52, 0x6D, 0xDB, 0x07, 0xCA, 0x8F, + 0xB5, 0x5B, 0xF0, 0x83, 0xF3, 0x4F, 0xC7, 0x2D, 0xA5, 0xC8, 0xAD, 0xCB, + 0x95, 0x20, 0xA4, 0x31, 0x28, 0x57, 0x58, 0x5A, 0xE4, 0x8D, 0x1B, 0x9A, + 0xAB, 0x9E, 0x0D, 0x0C, 0xF2, 0x0A, 0x33, 0x39, 0x22, 0x39, 0x0A, 0x97, + 0x2E, 0xF3, 0x53, 0x77, 0xB9, 0x44, 0x45, 0xFD, 0x84, 0xCB, 0x36, 0x20, + 0x81, 0x59, 0x2D, 0x9A, 0x6F, 0x6D, 0x48, 0x48, 0x61, 0xCA, 0x4C, 0xDF, + 0x53, 0xD1, 0xAF, 0x52, 0xBC, 0x44, 0x9F, 0xAB, 0x2F, 0x6B, 0x83, 0x72, + 0xEF, 0x75, 0x80, 0xDA, 0x06, 0x33, 0x1B, 0x5D, 0xC8, 0xDA, 0x63, 0xC6, + 0x4D, 0xCD, 0xAC, 0x66, 0x31, 0xCD, 0xD1, 0xDE, 0x3E, 0x87, 0x10, 0x36, + 0xE1, 0xB9, 0xA4, 0x7A, 0xEF, 0x60, 0x50, 0xB2, 0xCB, 0xCA, 0xA6, 0x56, + 0xE0, 0x37, 0xAF, 0xAB, 0x34, 0x13, 0x39, 0x25, 0xE8, 0x39, 0x66, 0xE4, + 0x98, 0x7A, 0xAA, 0x12, 0x98, 0x9C, 0x59, 0x66, 0x86, 0x3E, 0xAD, 0xF1, + 0xB0, 0xCA, 0x3E, 0x06, 0x0F, 0x7B, 0xF0, 0x11, 0x4B, 0x37, 0xA0, 0x44, + 0x6D, 0x7B, 0xCB, 0xA8, 0x8C, 0x71, 0xF4, 0xD5, 0xB5, 0x91, 0x36, 0xCC, + 0xF0, 0x15, 0xC6, 0x2B, 0xDE, 0x51, 0x17, 0xB1, 0x97, 0x4C, 0x50, 0x3D, + 0xB1, 0x95, 0x59, 0x7C, 0x05, 0x7D, 0x2D, 0x21, 0xD5, 0x00, 0xBF, 0x01, + 0x67, 0xA2, 0x5E, 0x7B, 0xA6, 0x5C, 0xF2, 0xF7, 0x22, 0xF1, 0x90, 0x0D, + 0x93, 0xDB, 0xAA, 0x44, 0x51, 0x66, 0xCC, 0x7D, 0x76, 0x03, 0xEB, 0x6A, + 0xA8, 0x2A, 0x38, 0x19, 0x97, 0x76, 0x0D, 0x6B, 0x8A, 0x61, 0xF9, 0xBC, + 0xF6, 0xEE, 0x76, 0xFD, 0x70, 0x2B, 0xDD, 0x29, 0x3C, 0xF8, 0x0A, 0x1E, + 0x5B, 0x42, 0x1C, 0x8B, 0x56, 0x2F, 0x55, 0x1B, 0x1C, 0xA1, 0x2E, 0xB5, + 0xC7, 0x16, 0xE6, 0xF8, 0xAA, 0x3C, 0x92, 0x8E, 0x69, 0xB6, 0x01, 0xC1, + 0xB5, 0x86, 0x9D, 0x89, 0x0F, 0x0B, 0x38, 0x94, 0x54, 0xE8, 0xEA, 0xDC, + 0x9E, 0x3D, 0x25, 0xBC, 0x53, 0x26, 0xED, 0xD5, 0xAB, 0x39, 0xAA, 0xC5, + 0x40, 0x4C, 0x54, 0xAB, 0xB2, 0xB4, 0xD9, 0xD9, 0xF8, 0xD7, 0x72, 0xDB, + 0x1C, 0xBC, 0x6D, 0xBD, 0x65, 0x5F, 0xEF, 0x88, 0x35, 0x2A, 0x66, 0x2F, + 0xEE, 0xF6, 0xB3, 0x65, 0xF0, 0x33, 0x8D, 0x7C, 0x98, 0x41, 0x69, 0x46, + 0x0F, 0x43, 0x1C, 0x69, 0xFA, 0x9B, 0xB5, 0xD0, 0x61, 0x6A, 0xCD, 0xCA, + 0x4B, 0xD9, 0x4C, 0x90, 0x46, 0xAB, 0x15, 0x59, 0xA1, 0x47, 0x54, 0x29, + 0x2E, 0x83, 0x28, 0x5F, 0x1C, 0xC2, 0xA2, 0xAB, 0x72, 0x17, 0x00, 0x06, + 0x8E, 0x45, 0xEC, 0x8B, 0xE2, 0x33, 0x3D, 0x7F, 0xDA, 0x19, 0x44, 0xE4, + 0x62, 0x72, 0xC3, 0xDF, 0x22, 0xC6, 0xF2, 0x56, 0xD4, 0xDD, 0x5F, 0x95, + 0x72, 0xED, 0x6D, 0x5F, 0xF7, 0x48, 0x03, 0x5B, 0xFD, 0xC5, 0x2A, 0xA0, + 0xF6, 0x73, 0x23, 0x84, 0x10, 0x1B, 0x01, 0xE7 +}; + +static const unsigned char TA28_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA29_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x32 +}; + +static const unsigned char TA29_RSA_N[] = { + 0xAA, 0x5F, 0xDA, 0x1B, 0x5F, 0xE8, 0x73, 0x91, 0xE5, 0xDA, 0x5C, 0xF4, + 0xA2, 0xE6, 0x47, 0xE5, 0xF3, 0x68, 0x55, 0x60, 0x05, 0x1D, 0x02, 0xA4, + 0xB3, 0x9B, 0x59, 0xF3, 0x1E, 0x8A, 0xAF, 0x34, 0xAD, 0xFC, 0x0D, 0xC2, + 0xD9, 0x48, 0x19, 0xEE, 0x69, 0x8F, 0xC9, 0x20, 0xFC, 0x21, 0xAA, 0x07, + 0x19, 0xED, 0xB0, 0x5C, 0xAC, 0x65, 0xC7, 0x5F, 0xED, 0x02, 0x7C, 0x7B, + 0x7C, 0x2D, 0x1B, 0xD6, 0xBA, 0xB9, 0x80, 0xC2, 0x18, 0x82, 0x16, 0x84, + 0xFA, 0x66, 0xB0, 0x08, 0xC6, 0x54, 0x23, 0x81, 0xE4, 0xCD, 0xB9, 0x49, + 0x3F, 0xF6, 0x4F, 0x6E, 0x37, 0x48, 0x28, 0x38, 0x0F, 0xC5, 0xBE, 0xE7, + 0x68, 0x70, 0xFD, 0x39, 0x97, 0x4D, 0xD2, 0xC7, 0x98, 0x91, 0x50, 0xAA, + 0xC4, 0x44, 0xB3, 0x23, 0x7D, 0x39, 0x47, 0xE9, 0x52, 0x62, 0xD6, 0x12, + 0x93, 0x5E, 0xB7, 0x31, 0x96, 0x42, 0x05, 0xFB, 0x76, 0xA7, 0x1E, 0xA3, + 0xF5, 0xC2, 0xFC, 0xE9, 0x7A, 0xC5, 0x6C, 0xA9, 0x71, 0x4F, 0xEA, 0xCB, + 0x78, 0xBC, 0x60, 0xAF, 0xC7, 0xDE, 0xF4, 0xD9, 0xCB, 0xBE, 0x7E, 0x33, + 0xA5, 0x6E, 0x94, 0x83, 0xF0, 0x34, 0xFA, 0x21, 0xAB, 0xEA, 0x8E, 0x72, + 0xA0, 0x3F, 0xA4, 0xDE, 0x30, 0x5B, 0xEF, 0x86, 0x4D, 0x6A, 0x95, 0x5B, + 0x43, 0x44, 0xA8, 0x10, 0x15, 0x1C, 0xE5, 0x01, 0x57, 0xC5, 0x98, 0xF1, + 0xE6, 0x06, 0x28, 0x91, 0xAA, 0x20, 0xC5, 0xB7, 0x53, 0x26, 0x51, 0x43, + 0xB2, 0x0B, 0x11, 0x95, 0x58, 0xE1, 0xC0, 0x0F, 0x76, 0xD9, 0xC0, 0x8D, + 0x7C, 0x81, 0xF3, 0x72, 0x70, 0x9E, 0x6F, 0xFE, 0x1A, 0x8E, 0xD9, 0x5F, + 0x35, 0xC6, 0xB2, 0x6F, 0x34, 0x7C, 0xBE, 0x48, 0x4F, 0xE2, 0x5A, 0x39, + 0xD7, 0xD8, 0x9D, 0x78, 0x9E, 0x9F, 0x86, 0x3E, 0x03, 0x5E, 0x19, 0x8B, + 0x44, 0xA2, 0xD5, 0xC7 +}; + +static const unsigned char TA29_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA30_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x33 +}; + +static const unsigned char TA30_RSA_N[] = { + 0xBD, 0x75, 0x93, 0xF0, 0x62, 0x22, 0x6F, 0x24, 0xAE, 0xE0, 0x7A, 0x76, + 0xAC, 0x7D, 0xBD, 0xD9, 0x24, 0xD5, 0xB8, 0xB7, 0xFC, 0xCD, 0xF0, 0x42, + 0xE0, 0xEB, 0x78, 0x88, 0x56, 0x5E, 0x9B, 0x9A, 0x54, 0x1D, 0x4D, 0x0C, + 0x8A, 0xF6, 0xD3, 0xCF, 0x70, 0xF4, 0x52, 0xB5, 0xD8, 0x93, 0x04, 0xE3, + 0x46, 0x86, 0x71, 0x41, 0x4A, 0x2B, 0xF0, 0x2A, 0x2C, 0x55, 0x03, 0xD6, + 0x48, 0xC3, 0xE0, 0x39, 0x38, 0xED, 0xF2, 0x5C, 0x3C, 0x3F, 0x44, 0xBC, + 0x93, 0x3D, 0x61, 0xAB, 0x4E, 0xCD, 0x0D, 0xBE, 0xF0, 0x20, 0x27, 0x58, + 0x0E, 0x44, 0x7F, 0x04, 0x1A, 0x87, 0xA5, 0xD7, 0x96, 0x14, 0x36, 0x90, + 0xD0, 0x49, 0x7B, 0xA1, 0x75, 0xFB, 0x1A, 0x6B, 0x73, 0xB1, 0xF8, 0xCE, + 0xA9, 0x09, 0x2C, 0xF2, 0x53, 0xD5, 0xC3, 0x14, 0x44, 0xB8, 0x86, 0xA5, + 0xF6, 0x8B, 0x2B, 0x39, 0xDA, 0xA3, 0x33, 0x54, 0xD9, 0xFA, 0x72, 0x1A, + 0xF7, 0x22, 0x15, 0x1C, 0x88, 0x91, 0x6B, 0x7F, 0x66, 0xE5, 0xC3, 0x6A, + 0x80, 0xB0, 0x24, 0xF3, 0xDF, 0x86, 0x45, 0x88, 0xFD, 0x19, 0x7F, 0x75, + 0x87, 0x1F, 0x1F, 0xB1, 0x1B, 0x0A, 0x73, 0x24, 0x5B, 0xB9, 0x65, 0xE0, + 0x2C, 0x54, 0xC8, 0x60, 0xD3, 0x66, 0x17, 0x3F, 0xE1, 0xCC, 0x54, 0x33, + 0x73, 0x91, 0x02, 0x3A, 0xA6, 0x7F, 0x7B, 0x76, 0x39, 0xA2, 0x1F, 0x96, + 0xB6, 0x38, 0xAE, 0xB5, 0xC8, 0x93, 0x74, 0x1D, 0x9E, 0xB9, 0xB4, 0xE5, + 0x60, 0x9D, 0x2F, 0x56, 0xD1, 0xE0, 0xEB, 0x5E, 0x5B, 0x4C, 0x12, 0x70, + 0x0C, 0x6C, 0x44, 0x20, 0xAB, 0x11, 0xD8, 0xF4, 0x19, 0xF6, 0xD2, 0x9C, + 0x52, 0x37, 0xE7, 0xFA, 0xB6, 0xC2, 0x31, 0x3B, 0x4A, 0xD4, 0x14, 0x99, + 0xAD, 0xC7, 0x1A, 0xF5, 0x5D, 0x5F, 0xFA, 0x07, 0xB8, 0x7C, 0x0D, 0x1F, + 0xD6, 0x83, 0x1E, 0xB3 +}; + +static const unsigned char TA30_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA31_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA31_RSA_N[] = { + 0xAE, 0xFF, 0x09, 0x59, 0x91, 0x80, 0x0A, 0x4A, 0x68, 0xE6, 0x24, 0x3F, + 0xB8, 0xA7, 0xE4, 0xC8, 0x3A, 0x0A, 0x3A, 0x16, 0xCD, 0xC9, 0x23, 0x61, + 0xA0, 0x93, 0x71, 0xF2, 0xAB, 0x8B, 0x73, 0x8F, 0xA0, 0x67, 0x65, 0x60, + 0xD2, 0x54, 0x6B, 0x63, 0x51, 0x6F, 0x49, 0x33, 0xE0, 0x72, 0x07, 0x13, + 0x7D, 0x38, 0xCD, 0x06, 0x92, 0x07, 0x29, 0x52, 0x6B, 0x4E, 0x77, 0x6C, + 0x04, 0xD3, 0x95, 0xFA, 0xDD, 0x4C, 0x8C, 0xD9, 0x5D, 0xC1, 0x61, 0x7D, + 0x4B, 0xE7, 0x28, 0xB3, 0x44, 0x81, 0x7B, 0x51, 0xAF, 0xDD, 0x33, 0xB1, + 0x68, 0x7C, 0xD6, 0x4E, 0x4C, 0xFE, 0x2B, 0x68, 0xB9, 0xCA, 0x66, 0x69, + 0xC4, 0xEC, 0x5E, 0x57, 0x7F, 0xF7, 0x0D, 0xC7, 0x9C, 0x36, 0x36, 0xE5, + 0x07, 0x60, 0xAC, 0xC0, 0x4C, 0xEA, 0x08, 0x6C, 0xEF, 0x06, 0x7C, 0x4F, + 0x5B, 0x28, 0x7A, 0x08, 0xFC, 0x93, 0x5D, 0x9B, 0xF6, 0x9C, 0xB4, 0x8B, + 0x86, 0xBA, 0x21, 0xB9, 0xF4, 0xF0, 0xE8, 0x59, 0x5A, 0x28, 0xA1, 0x34, + 0x84, 0x1A, 0x25, 0x91, 0xB6, 0xB5, 0x8F, 0xEF, 0xB2, 0xF9, 0x80, 0xFA, + 0xF9, 0x3D, 0x3C, 0x11, 0x72, 0xD8, 0xE3, 0x2F, 0x86, 0x76, 0xC5, 0x79, + 0x2C, 0xC1, 0xA9, 0x90, 0x93, 0x46, 0x98, 0x67, 0xCB, 0x83, 0x6A, 0xA0, + 0x50, 0x23, 0xA7, 0x3B, 0xF6, 0x81, 0x39, 0xE0, 0xED, 0xF0, 0xB9, 0xBF, + 0x65, 0xF1, 0xD8, 0xCB, 0x7A, 0xFB, 0xEF, 0x73, 0x03, 0xCE, 0x00, 0xF4, + 0x7D, 0xD7, 0xE0, 0x5D, 0x3B, 0x66, 0xB8, 0xDC, 0x8E, 0xBA, 0x83, 0xCB, + 0x87, 0x76, 0x03, 0xFC, 0x25, 0xD9, 0xE7, 0x23, 0x6F, 0x06, 0xFD, 0x67, + 0xF3, 0xE0, 0xFF, 0x84, 0xBC, 0x47, 0xBF, 0xB5, 0x16, 0x18, 0x46, 0x69, + 0x14, 0xCC, 0x05, 0xF7, 0xDB, 0xD3, 0x49, 0xAC, 0x6B, 0xCC, 0xAB, 0xE4, + 0xB5, 0x0B, 0x43, 0x24, 0x5E, 0x4B, 0x6B, 0x4D, 0x67, 0xDF, 0xD6, 0xB5, + 0x3E, 0x4F, 0x78, 0x1F, 0x94, 0x71, 0x24, 0xEA, 0xDE, 0x70, 0xFC, 0xF1, + 0x93, 0xFE, 0x9E, 0x93, 0x5A, 0xE4, 0x94, 0x5A, 0x97, 0x54, 0x0C, 0x35, + 0x7B, 0x5F, 0x6C, 0xEE, 0x00, 0x1F, 0x24, 0xEC, 0x03, 0xBA, 0x02, 0xF5, + 0x76, 0xF4, 0x9F, 0xD4, 0x9A, 0xED, 0x85, 0x2C, 0x38, 0x22, 0x2F, 0xC7, + 0xD8, 0x2F, 0x76, 0x11, 0x4F, 0xFD, 0x6C, 0x5C, 0xE8, 0xF5, 0x8E, 0x27, + 0x87, 0x7F, 0x19, 0x4A, 0x21, 0x47, 0x90, 0x1D, 0x79, 0x8D, 0x1C, 0x5B, + 0xF8, 0xCF, 0x4A, 0x85, 0xE4, 0xED, 0xB3, 0x5B, 0x8D, 0xBE, 0xC4, 0x64, + 0x28, 0x5D, 0x41, 0xC4, 0x6E, 0xAC, 0x38, 0x5A, 0x4F, 0x23, 0x74, 0x74, + 0xA9, 0x12, 0xC3, 0xF6, 0xD2, 0xB9, 0x11, 0x15, 0x33, 0x07, 0x91, 0xD8, + 0x3B, 0x37, 0x3A, 0x63, 0x30, 0x06, 0xD1, 0xC5, 0x22, 0x36, 0x28, 0x62, + 0x23, 0x10, 0xE0, 0x46, 0xCC, 0x97, 0xAC, 0xD6, 0x2B, 0x5D, 0x64, 0x24, + 0xD5, 0xEE, 0x1C, 0x0E, 0xDE, 0xFB, 0x08, 0x5A, 0x75, 0x2A, 0xF6, 0x63, + 0x6D, 0xCE, 0x0B, 0x42, 0xBE, 0xD1, 0xBA, 0x70, 0x1C, 0x9C, 0x21, 0xE5, + 0x0F, 0x31, 0x69, 0x17, 0xD7, 0xFC, 0x0A, 0xB4, 0xDE, 0xED, 0x80, 0x9C, + 0xCB, 0x92, 0xB4, 0x8B, 0xF5, 0xDE, 0x59, 0xA2, 0x58, 0x09, 0xA5, 0x63, + 0x47, 0x0B, 0xE1, 0x41, 0x32, 0x34, 0x41, 0xD9, 0x9A, 0xB1, 0xD9, 0xA8, + 0xB0, 0x1B, 0x5A, 0xDE, 0x0D, 0x0D, 0xF4, 0xE2, 0xB2, 0x5D, 0x35, 0x80, + 0xB9, 0x81, 0xD4, 0x84, 0x69, 0x91, 0x02, 0xCB, 0x75, 0xD0, 0x8D, 0xC5, + 0xB5, 0x3D, 0x09, 0x91, 0x09, 0x8F, 0x14, 0xA1, 0x14, 0x74, 0x79, 0x3E, + 0xD6, 0xC9, 0x15, 0x1D, 0xA4, 0x59, 0x59, 0x22, 0xDC, 0xF6, 0x8A, 0x45, + 0x3D, 0x3C, 0x12, 0xD6, 0x3E, 0x5D, 0x32, 0x2F +}; + +static const unsigned char TA31_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA32_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x33, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA32_RSA_N[] = { + 0xCC, 0x25, 0x76, 0x90, 0x79, 0x06, 0x78, 0x22, 0x16, 0xF5, 0xC0, 0x83, + 0xB6, 0x84, 0xCA, 0x28, 0x9E, 0xFD, 0x05, 0x76, 0x11, 0xC5, 0xAD, 0x88, + 0x72, 0xFC, 0x46, 0x02, 0x43, 0xC7, 0xB2, 0x8A, 0x9D, 0x04, 0x5F, 0x24, + 0xCB, 0x2E, 0x4B, 0xE1, 0x60, 0x82, 0x46, 0xE1, 0x52, 0xAB, 0x0C, 0x81, + 0x47, 0x70, 0x6C, 0xDD, 0x64, 0xD1, 0xEB, 0xF5, 0x2C, 0xA3, 0x0F, 0x82, + 0x3D, 0x0C, 0x2B, 0xAE, 0x97, 0xD7, 0xB6, 0x14, 0x86, 0x10, 0x79, 0xBB, + 0x3B, 0x13, 0x80, 0x77, 0x8C, 0x08, 0xE1, 0x49, 0xD2, 0x6A, 0x62, 0x2F, + 0x1F, 0x5E, 0xFA, 0x96, 0x68, 0xDF, 0x89, 0x27, 0x95, 0x38, 0x9F, 0x06, + 0xD7, 0x3E, 0xC9, 0xCB, 0x26, 0x59, 0x0D, 0x73, 0xDE, 0xB0, 0xC8, 0xE9, + 0x26, 0x0E, 0x83, 0x15, 0xC6, 0xEF, 0x5B, 0x8B, 0xD2, 0x04, 0x60, 0xCA, + 0x49, 0xA6, 0x28, 0xF6, 0x69, 0x3B, 0xF6, 0xCB, 0xC8, 0x28, 0x91, 0xE5, + 0x9D, 0x8A, 0x61, 0x57, 0x37, 0xAC, 0x74, 0x14, 0xDC, 0x74, 0xE0, 0x3A, + 0xEE, 0x72, 0x2F, 0x2E, 0x9C, 0xFB, 0xD0, 0xBB, 0xBF, 0xF5, 0x3D, 0x00, + 0xE1, 0x06, 0x33, 0xE8, 0x82, 0x2B, 0xAE, 0x53, 0xA6, 0x3A, 0x16, 0x73, + 0x8C, 0xDD, 0x41, 0x0E, 0x20, 0x3A, 0xC0, 0xB4, 0xA7, 0xA1, 0xE9, 0xB2, + 0x4F, 0x90, 0x2E, 0x32, 0x60, 0xE9, 0x57, 0xCB, 0xB9, 0x04, 0x92, 0x68, + 0x68, 0xE5, 0x38, 0x26, 0x60, 0x75, 0xB2, 0x9F, 0x77, 0xFF, 0x91, 0x14, + 0xEF, 0xAE, 0x20, 0x49, 0xFC, 0xAD, 0x40, 0x15, 0x48, 0xD1, 0x02, 0x31, + 0x61, 0x19, 0x5E, 0xB8, 0x97, 0xEF, 0xAD, 0x77, 0xB7, 0x64, 0x9A, 0x7A, + 0xBF, 0x5F, 0xC1, 0x13, 0xEF, 0x9B, 0x62, 0xFB, 0x0D, 0x6C, 0xE0, 0x54, + 0x69, 0x16, 0xA9, 0x03, 0xDA, 0x6E, 0xE9, 0x83, 0x93, 0x71, 0x76, 0xC6, + 0x69, 0x85, 0x82, 0x17 +}; + +static const unsigned char TA32_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA33_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x41, 0x54, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x65, 0x2D, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x65, + 0x20, 0x6D, 0x6F, 0x6E, 0x69, 0x74, 0x6F, 0x72, 0x69, 0x6E, 0x67, 0x20, + 0x47, 0x6D, 0x62, 0x48, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x10, 0x47, 0x4C, 0x4F, 0x42, 0x41, 0x4C, 0x54, 0x52, 0x55, + 0x53, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA33_RSA_N[] = { + 0xAE, 0x2E, 0x56, 0xAD, 0x1B, 0x1C, 0xEF, 0xF6, 0x95, 0x8F, 0xA0, 0x77, + 0x1B, 0x2B, 0xD3, 0x63, 0x8F, 0x84, 0x4D, 0x45, 0xA2, 0x0F, 0x9F, 0x5B, + 0x45, 0xAB, 0x59, 0x7B, 0x51, 0x34, 0xF9, 0xEC, 0x8B, 0x8A, 0x78, 0xC5, + 0xDD, 0x6B, 0xAF, 0xBD, 0xC4, 0xDF, 0x93, 0x45, 0x1E, 0xBF, 0x91, 0x38, + 0x0B, 0xAE, 0x0E, 0x16, 0xE7, 0x41, 0x73, 0xF8, 0xDB, 0xBB, 0xD1, 0xB8, + 0x51, 0xE0, 0xCB, 0x83, 0x3B, 0x73, 0x38, 0x6E, 0x77, 0x8A, 0x0F, 0x59, + 0x63, 0x26, 0xCD, 0xA7, 0x2A, 0xCE, 0x54, 0xFB, 0xB8, 0xE2, 0xC0, 0x7C, + 0x47, 0xCE, 0x60, 0x7C, 0x3F, 0xB2, 0x73, 0xF2, 0xC0, 0x19, 0xB6, 0x8A, + 0x92, 0x87, 0x35, 0x0D, 0x90, 0x28, 0xA2, 0xE4, 0x15, 0x04, 0x63, 0x3E, + 0xBA, 0xAF, 0xEE, 0x7C, 0x5E, 0xCC, 0xA6, 0x8B, 0x50, 0xB2, 0x38, 0xF7, + 0x41, 0x63, 0xCA, 0xCE, 0xFF, 0x69, 0x8F, 0x68, 0x0E, 0x95, 0x36, 0xE5, + 0xCC, 0xB9, 0x8C, 0x09, 0xCA, 0x4B, 0xDD, 0x31, 0x90, 0x96, 0xC8, 0xCC, + 0x1F, 0xFD, 0x56, 0x96, 0x34, 0xDB, 0x8E, 0x1C, 0xEA, 0x2C, 0xBE, 0x85, + 0x2E, 0x63, 0xDD, 0xAA, 0xA9, 0x95, 0xD3, 0xFD, 0x29, 0x95, 0x13, 0xF0, + 0xC8, 0x98, 0x93, 0xD9, 0x2D, 0x16, 0x47, 0x90, 0x11, 0x83, 0xA2, 0x3A, + 0x22, 0xA2, 0x28, 0x57, 0xA2, 0xEB, 0xFE, 0xC0, 0x8C, 0x28, 0xA0, 0xA6, + 0x7D, 0xE7, 0x2A, 0x42, 0x3B, 0x82, 0x80, 0x63, 0xA5, 0x63, 0x1F, 0x19, + 0xCC, 0x7C, 0xB2, 0x66, 0xA8, 0xC2, 0xD3, 0x6D, 0x37, 0x6F, 0xE2, 0x7E, + 0x06, 0x51, 0xD9, 0x45, 0x84, 0x1F, 0x12, 0xCE, 0x24, 0x52, 0x64, 0x85, + 0x0B, 0x48, 0x80, 0x4E, 0x87, 0xB1, 0x22, 0x22, 0x30, 0xAA, 0xEB, 0xAE, + 0xBE, 0xE0, 0x02, 0xE0, 0x40, 0xE8, 0xB0, 0x42, 0x80, 0x03, 0x51, 0xAA, + 0xB4, 0x7E, 0xAA, 0x44, 0xD7, 0x43, 0x61, 0xF3, 0xA2, 0x6B, 0x16, 0x89, + 0x49, 0xA4, 0xA3, 0xA4, 0x2B, 0x8A, 0x02, 0xC4, 0x78, 0xF4, 0x68, 0x8A, + 0xC1, 0xE4, 0x7A, 0x36, 0xB1, 0x6F, 0x1B, 0x96, 0x1B, 0x77, 0x49, 0x8D, + 0xD4, 0xC9, 0x06, 0x72, 0x8F, 0xCF, 0x53, 0xE3, 0xDC, 0x17, 0x85, 0x20, + 0x4A, 0xDC, 0x98, 0x27, 0xD3, 0x91, 0x26, 0x2B, 0x47, 0x1E, 0x69, 0x07, + 0xAF, 0xDE, 0xA2, 0xE4, 0xE4, 0xD4, 0x6B, 0x0B, 0xB3, 0x5E, 0x7C, 0xD4, + 0x24, 0x80, 0x47, 0x29, 0x69, 0x3B, 0x6E, 0xE8, 0xAC, 0xFD, 0x40, 0xEB, + 0xD8, 0xED, 0x71, 0x71, 0x2B, 0xF2, 0xE8, 0x58, 0x1D, 0xEB, 0x41, 0x97, + 0x22, 0xC5, 0x1F, 0xD4, 0x39, 0xD0, 0x27, 0x8F, 0x87, 0xE3, 0x18, 0xF4, + 0xE0, 0xA9, 0x46, 0x0D, 0xF5, 0x74, 0x3A, 0x82, 0x2E, 0xD0, 0x6E, 0x2C, + 0x91, 0xA3, 0x31, 0x5C, 0x3B, 0x46, 0xEA, 0x7B, 0x04, 0x10, 0x56, 0x5E, + 0x80, 0x1D, 0xF5, 0xA5, 0x65, 0xE8, 0x82, 0xFC, 0xE2, 0x07, 0x8C, 0x62, + 0x45, 0xF5, 0x20, 0xDE, 0x46, 0x70, 0x86, 0xA1, 0xBC, 0x93, 0xD3, 0x1E, + 0x74, 0xA6, 0x6C, 0xB0, 0x2C, 0xF7, 0x03, 0x0C, 0x88, 0x0C, 0xCB, 0xD4, + 0x72, 0x53, 0x86, 0xBC, 0x60, 0x46, 0xF3, 0x98, 0x6A, 0xC2, 0xF1, 0xBF, + 0x43, 0xF9, 0x70, 0x20, 0x77, 0xCA, 0x37, 0x41, 0x79, 0x55, 0x52, 0x63, + 0x8D, 0x5B, 0x12, 0x9F, 0xC5, 0x68, 0xC4, 0x88, 0x9D, 0xAC, 0xF2, 0x30, + 0xAB, 0xB7, 0xA3, 0x31, 0x97, 0x67, 0xAD, 0x8F, 0x17, 0x0F, 0x6C, 0xC7, + 0x73, 0xED, 0x24, 0x94, 0x6B, 0xC8, 0x83, 0x9A, 0xD0, 0x9A, 0x37, 0x49, + 0x04, 0xAB, 0xB1, 0x16, 0xC8, 0x6C, 0x49, 0x49, 0x2D, 0xAB, 0xA1, 0xD0, + 0x8C, 0x92, 0xF2, 0x41, 0x4A, 0x79, 0x21, 0x25, 0xDB, 0x63, 0xD7, 0xB6, + 0x9C, 0xA7, 0x7E, 0x42, 0x69, 0xFB, 0x3A, 0x63 +}; + +static const unsigned char TA33_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA34_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA34_RSA_N[] = { + 0xA1, 0xAE, 0x25, 0xB2, 0x01, 0x18, 0xDC, 0x57, 0x88, 0x3F, 0x46, 0xEB, + 0xF9, 0xAF, 0xE2, 0xEB, 0x23, 0x71, 0xE2, 0x9A, 0xD1, 0x61, 0x66, 0x21, + 0x5F, 0xAA, 0xAF, 0x27, 0x51, 0xE5, 0x6E, 0x1B, 0x16, 0xD4, 0x2D, 0x7D, + 0x50, 0xB0, 0x53, 0x77, 0xBD, 0x78, 0x3A, 0x60, 0xE2, 0x64, 0x02, 0x9B, + 0x7C, 0x86, 0x9B, 0xD6, 0x1A, 0x8E, 0xAD, 0xFF, 0x1F, 0x15, 0x7F, 0xD5, + 0x95, 0x1E, 0x12, 0xCB, 0xE6, 0x14, 0x84, 0x04, 0xC1, 0xDF, 0x36, 0xB3, + 0x16, 0x9F, 0x8A, 0xE3, 0xC9, 0xDB, 0x98, 0x34, 0xCE, 0xD8, 0x33, 0x17, + 0x28, 0x46, 0xFC, 0xA7, 0xC9, 0xF0, 0xD2, 0xB4, 0xD5, 0x4D, 0x09, 0x72, + 0x49, 0xF9, 0xF2, 0x87, 0xE3, 0xA9, 0xDA, 0x7D, 0xA1, 0x7D, 0x6B, 0xB2, + 0x3A, 0x25, 0xA9, 0x6D, 0x52, 0x44, 0xAC, 0xF8, 0xBE, 0x6E, 0xFB, 0xDC, + 0xA6, 0x73, 0x91, 0x90, 0x61, 0xA6, 0x03, 0x14, 0x20, 0xF2, 0xE7, 0x87, + 0xA3, 0x88, 0xAD, 0xAD, 0xA0, 0x8C, 0xFF, 0xA6, 0x0B, 0x25, 0x52, 0x25, + 0xE7, 0x16, 0x01, 0xD5, 0xCB, 0xB8, 0x35, 0x81, 0x0C, 0xA3, 0x3B, 0xF0, + 0xE1, 0xE1, 0xFC, 0x5A, 0x5D, 0xCE, 0x80, 0x71, 0x6D, 0xF8, 0x49, 0xAB, + 0x3E, 0x3B, 0xBA, 0xB8, 0xD7, 0x80, 0x01, 0xFB, 0xA5, 0xEB, 0x5B, 0xB3, + 0xC5, 0x5E, 0x60, 0x2A, 0x31, 0xA0, 0xAF, 0x37, 0xE8, 0x20, 0x3A, 0x9F, + 0xA8, 0x32, 0x2C, 0x0C, 0xCC, 0x09, 0x1D, 0xD3, 0x9E, 0x8E, 0x5D, 0xBC, + 0x4C, 0x98, 0xEE, 0xC5, 0x1A, 0x68, 0x7B, 0xEC, 0x53, 0xA6, 0xE9, 0x14, + 0x35, 0xA3, 0xDF, 0xCD, 0x80, 0x9F, 0x0C, 0x48, 0xFB, 0x1C, 0xF4, 0xF1, + 0xBF, 0x4A, 0xB8, 0xFA, 0xD5, 0x8C, 0x71, 0x4A, 0xC7, 0x1F, 0xAD, 0xFE, + 0x41, 0x9A, 0xB3, 0x83, 0x5D, 0xF2, 0x84, 0x56, 0xEF, 0xA5, 0x57, 0x43, + 0xCE, 0x29, 0xAD, 0x8C, 0xAB, 0x55, 0xBF, 0xC4, 0xFB, 0x5B, 0x01, 0xDD, + 0x23, 0x21, 0xA1, 0x58, 0x00, 0x8E, 0xC3, 0xD0, 0x6A, 0x13, 0xED, 0x13, + 0xE3, 0x12, 0x2B, 0x80, 0xDC, 0x67, 0xE6, 0x95, 0xB2, 0xCD, 0x1E, 0x22, + 0x6E, 0x2A, 0xF8, 0x41, 0xD4, 0xF2, 0xCA, 0x14, 0x07, 0x8D, 0x8A, 0x55, + 0x12, 0xC6, 0x69, 0xF5, 0xB8, 0x86, 0x68, 0x2F, 0x53, 0x5E, 0xB0, 0xD2, + 0xAA, 0x21, 0xC1, 0x98, 0xE6, 0x30, 0xE3, 0x67, 0x55, 0xC7, 0x9B, 0x6E, + 0xAC, 0x19, 0xA8, 0x55, 0xA6, 0x45, 0x06, 0xD0, 0x23, 0x3A, 0xDB, 0xEB, + 0x65, 0x5D, 0x2A, 0x11, 0x11, 0xF0, 0x3B, 0x4F, 0xCA, 0x6D, 0xF4, 0x34, + 0xC4, 0x71, 0xE4, 0xFF, 0x00, 0x5A, 0xF6, 0x5C, 0xAE, 0x23, 0x60, 0x85, + 0x73, 0xF1, 0xE4, 0x10, 0xB1, 0x25, 0xAE, 0xD5, 0x92, 0xBB, 0x13, 0xC1, + 0x0C, 0xE0, 0x39, 0xDA, 0xB4, 0x39, 0x57, 0xB5, 0xAB, 0x35, 0xAA, 0x72, + 0x21, 0x3B, 0x83, 0x35, 0xE7, 0x31, 0xDF, 0x7A, 0x21, 0x6E, 0xB8, 0x32, + 0x08, 0x7D, 0x1D, 0x32, 0x91, 0x15, 0x4A, 0x62, 0x72, 0xCF, 0xE3, 0x77, + 0xA1, 0xBC, 0xD5, 0x11, 0x1B, 0x76, 0x01, 0x67, 0x08, 0xE0, 0x41, 0x0B, + 0xC3, 0xEB, 0x15, 0x6E, 0xF8, 0xA4, 0x19, 0xD9, 0xA2, 0xAB, 0xAF, 0xE2, + 0x27, 0x52, 0x56, 0x2B, 0x02, 0x8A, 0x2C, 0x14, 0x24, 0xF9, 0xBF, 0x42, + 0x02, 0xBF, 0x26, 0xC8, 0xC6, 0x8F, 0xE0, 0x6E, 0x38, 0x7D, 0x53, 0x2D, + 0xE5, 0xED, 0x98, 0xB3, 0x95, 0x63, 0x68, 0x7F, 0xF9, 0x35, 0xF4, 0xDF, + 0x88, 0xC5, 0x60, 0x35, 0x92, 0xC0, 0x7C, 0x69, 0x1C, 0x61, 0x95, 0x16, + 0xD0, 0xEB, 0xDE, 0x0B, 0xAF, 0x3E, 0x04, 0x10, 0x45, 0x65, 0x58, 0x50, + 0x38, 0xAF, 0x48, 0xF2, 0x59, 0xB6, 0x16, 0xF2, 0x3C, 0x0D, 0x90, 0x02, + 0xC6, 0x70, 0x2E, 0x01, 0xAD, 0x3C, 0x15, 0xD7 +}; + +static const unsigned char TA34_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA35_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, + 0x64, 0x79, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x49, 0x6E, + 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x28, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6C, + 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA35_RSA_N[] = { + 0xDE, 0x9D, 0xD7, 0xEA, 0x57, 0x18, 0x49, 0xA1, 0x5B, 0xEB, 0xD7, 0x5F, + 0x48, 0x86, 0xEA, 0xBE, 0xDD, 0xFF, 0xE4, 0xEF, 0x67, 0x1C, 0xF4, 0x65, + 0x68, 0xB3, 0x57, 0x71, 0xA0, 0x5E, 0x77, 0xBB, 0xED, 0x9B, 0x49, 0xE9, + 0x70, 0x80, 0x3D, 0x56, 0x18, 0x63, 0x08, 0x6F, 0xDA, 0xF2, 0xCC, 0xD0, + 0x3F, 0x7F, 0x02, 0x54, 0x22, 0x54, 0x10, 0xD8, 0xB2, 0x81, 0xD4, 0xC0, + 0x75, 0x3D, 0x4B, 0x7F, 0xC7, 0x77, 0xC3, 0x3E, 0x78, 0xAB, 0x1A, 0x03, + 0xB5, 0x20, 0x6B, 0x2F, 0x6A, 0x2B, 0xB1, 0xC5, 0x88, 0x7E, 0xC4, 0xBB, + 0x1E, 0xB0, 0xC1, 0xD8, 0x45, 0x27, 0x6F, 0xAA, 0x37, 0x58, 0xF7, 0x87, + 0x26, 0xD7, 0xD8, 0x2D, 0xF6, 0xA9, 0x17, 0xB7, 0x1F, 0x72, 0x36, 0x4E, + 0xA6, 0x17, 0x3F, 0x65, 0x98, 0x92, 0xDB, 0x2A, 0x6E, 0x5D, 0xA2, 0xFE, + 0x88, 0xE0, 0x0B, 0xDE, 0x7F, 0xE5, 0x8D, 0x15, 0xE1, 0xEB, 0xCB, 0x3A, + 0xD5, 0xE2, 0x12, 0xA2, 0x13, 0x2D, 0xD8, 0x8E, 0xAF, 0x5F, 0x12, 0x3D, + 0xA0, 0x08, 0x05, 0x08, 0xB6, 0x5C, 0xA5, 0x65, 0x38, 0x04, 0x45, 0x99, + 0x1E, 0xA3, 0x60, 0x60, 0x74, 0xC5, 0x41, 0xA5, 0x72, 0x62, 0x1B, 0x62, + 0xC5, 0x1F, 0x6F, 0x5F, 0x1A, 0x42, 0xBE, 0x02, 0x51, 0x65, 0xA8, 0xAE, + 0x23, 0x18, 0x6A, 0xFC, 0x78, 0x03, 0xA9, 0x4D, 0x7F, 0x80, 0xC3, 0xFA, + 0xAB, 0x5A, 0xFC, 0xA1, 0x40, 0xA4, 0xCA, 0x19, 0x16, 0xFE, 0xB2, 0xC8, + 0xEF, 0x5E, 0x73, 0x0D, 0xEE, 0x77, 0xBD, 0x9A, 0xF6, 0x79, 0x98, 0xBC, + 0xB1, 0x07, 0x67, 0xA2, 0x15, 0x0D, 0xDD, 0xA0, 0x58, 0xC6, 0x44, 0x7B, + 0x0A, 0x3E, 0x62, 0x28, 0x5F, 0xBA, 0x41, 0x07, 0x53, 0x58, 0xCF, 0x11, + 0x7E, 0x38, 0x74, 0xC5, 0xF8, 0xFF, 0xB5, 0x69, 0x90, 0x8F, 0x84, 0x74, + 0xEA, 0x97, 0x1B, 0xAF +}; + +static const unsigned char TA35_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA36_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA36_EC_Q[] = { + 0x04, 0x4B, 0x36, 0xE9, 0xAE, 0x57, 0x5E, 0xA8, 0x70, 0xD7, 0xD0, 0x8F, + 0x74, 0x62, 0x77, 0xC3, 0x5E, 0x7A, 0xAA, 0xE5, 0xB6, 0xA2, 0xF1, 0x78, + 0xFD, 0x02, 0x7E, 0x57, 0xDD, 0x91, 0x79, 0x9C, 0x6C, 0xB9, 0x52, 0x88, + 0x54, 0xBC, 0x2F, 0x04, 0xBE, 0xB8, 0xCD, 0xF6, 0x10, 0xD1, 0x29, 0xEC, + 0xB5, 0xD0, 0xA0, 0xC3, 0xF0, 0x89, 0x70, 0x19, 0xBB, 0x51, 0x65, 0xC5, + 0x43, 0x9C, 0xC3, 0x9B, 0x63, 0x9D, 0x20, 0x83, 0x3E, 0x06, 0x0B, 0xA6, + 0x42, 0x44, 0x85, 0x11, 0xA7, 0x4A, 0x3A, 0x2D, 0xE9, 0xD6, 0x68, 0x2F, + 0x48, 0x4E, 0x53, 0x2B, 0x07, 0x3F, 0x4D, 0xBD, 0xB9, 0xAC, 0x77, 0x39, + 0x57 +}; + +static const unsigned char TA37_DN[] = { + 0x30, 0x68, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, + 0x6C, 0x64, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA37_RSA_N[] = { + 0xB7, 0x32, 0xC8, 0xFE, 0xE9, 0x71, 0xA6, 0x04, 0x85, 0xAD, 0x0C, 0x11, + 0x64, 0xDF, 0xCE, 0x4D, 0xEF, 0xC8, 0x03, 0x18, 0x87, 0x3F, 0xA1, 0xAB, + 0xFB, 0x3C, 0xA6, 0x9F, 0xF0, 0xC3, 0xA1, 0xDA, 0xD4, 0xD8, 0x6E, 0x2B, + 0x53, 0x90, 0xFB, 0x24, 0xA4, 0x3E, 0x84, 0xF0, 0x9E, 0xE8, 0x5F, 0xEC, + 0xE5, 0x27, 0x44, 0xF5, 0x28, 0xA6, 0x3F, 0x7B, 0xDE, 0xE0, 0x2A, 0xF0, + 0xC8, 0xAF, 0x53, 0x2F, 0x9E, 0xCA, 0x05, 0x01, 0x93, 0x1E, 0x8F, 0x66, + 0x1C, 0x39, 0xA7, 0x4D, 0xFA, 0x5A, 0xB6, 0x73, 0x04, 0x25, 0x66, 0xEB, + 0x77, 0x7F, 0xE7, 0x59, 0xC6, 0x4A, 0x99, 0x25, 0x14, 0x54, 0xEB, 0x26, + 0xC7, 0xF3, 0x7F, 0x19, 0xD5, 0x30, 0x70, 0x8F, 0xAF, 0xB0, 0x46, 0x2A, + 0xFF, 0xAD, 0xEB, 0x29, 0xED, 0xD7, 0x9F, 0xAA, 0x04, 0x87, 0xA3, 0xD4, + 0xF9, 0x89, 0xA5, 0x34, 0x5F, 0xDB, 0x43, 0x91, 0x82, 0x36, 0xD9, 0x66, + 0x3C, 0xB1, 0xB8, 0xB9, 0x82, 0xFD, 0x9C, 0x3A, 0x3E, 0x10, 0xC8, 0x3B, + 0xEF, 0x06, 0x65, 0x66, 0x7A, 0x9B, 0x19, 0x18, 0x3D, 0xFF, 0x71, 0x51, + 0x3C, 0x30, 0x2E, 0x5F, 0xBE, 0x3D, 0x77, 0x73, 0xB2, 0x5D, 0x06, 0x6C, + 0xC3, 0x23, 0x56, 0x9A, 0x2B, 0x85, 0x26, 0x92, 0x1C, 0xA7, 0x02, 0xB3, + 0xE4, 0x3F, 0x0D, 0xAF, 0x08, 0x79, 0x82, 0xB8, 0x36, 0x3D, 0xEA, 0x9C, + 0xD3, 0x35, 0xB3, 0xBC, 0x69, 0xCA, 0xF5, 0xCC, 0x9D, 0xE8, 0xFD, 0x64, + 0x8D, 0x17, 0x80, 0x33, 0x6E, 0x5E, 0x4A, 0x5D, 0x99, 0xC9, 0x1E, 0x87, + 0xB4, 0x9D, 0x1A, 0xC0, 0xD5, 0x6E, 0x13, 0x35, 0x23, 0x5E, 0xDF, 0x9B, + 0x5F, 0x3D, 0xEF, 0xD6, 0xF7, 0x76, 0xC2, 0xEA, 0x3E, 0xBB, 0x78, 0x0D, + 0x1C, 0x42, 0x67, 0x6B, 0x04, 0xD8, 0xF8, 0xD6, 0xDA, 0x6F, 0x8B, 0xF2, + 0x44, 0xA0, 0x01, 0xAB +}; + +static const unsigned char TA37_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA38_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, + 0x6E, 0x63, 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA38_RSA_N[] = { + 0xC6, 0xCC, 0xE5, 0x73, 0xE6, 0xFB, 0xD4, 0xBB, 0xE5, 0x2D, 0x2D, 0x32, + 0xA6, 0xDF, 0xE5, 0x81, 0x3F, 0xC9, 0xCD, 0x25, 0x49, 0xB6, 0x71, 0x2A, + 0xC3, 0xD5, 0x94, 0x34, 0x67, 0xA2, 0x0A, 0x1C, 0xB0, 0x5F, 0x69, 0xA6, + 0x40, 0xB1, 0xC4, 0xB7, 0xB2, 0x8F, 0xD0, 0x98, 0xA4, 0xA9, 0x41, 0x59, + 0x3A, 0xD3, 0xDC, 0x94, 0xD6, 0x3C, 0xDB, 0x74, 0x38, 0xA4, 0x4A, 0xCC, + 0x4D, 0x25, 0x82, 0xF7, 0x4A, 0xA5, 0x53, 0x12, 0x38, 0xEE, 0xF3, 0x49, + 0x6D, 0x71, 0x91, 0x7E, 0x63, 0xB6, 0xAB, 0xA6, 0x5F, 0xC3, 0xA4, 0x84, + 0xF8, 0x4F, 0x62, 0x51, 0xBE, 0xF8, 0xC5, 0xEC, 0xDB, 0x38, 0x92, 0xE3, + 0x06, 0xE5, 0x08, 0x91, 0x0C, 0xC4, 0x28, 0x41, 0x55, 0xFB, 0xCB, 0x5A, + 0x89, 0x15, 0x7E, 0x71, 0xE8, 0x35, 0xBF, 0x4D, 0x72, 0x09, 0x3D, 0xBE, + 0x3A, 0x38, 0x50, 0x5B, 0x77, 0x31, 0x1B, 0x8D, 0xB3, 0xC7, 0x24, 0x45, + 0x9A, 0xA7, 0xAC, 0x6D, 0x00, 0x14, 0x5A, 0x04, 0xB7, 0xBA, 0x13, 0xEB, + 0x51, 0x0A, 0x98, 0x41, 0x41, 0x22, 0x4E, 0x65, 0x61, 0x87, 0x81, 0x41, + 0x50, 0xA6, 0x79, 0x5C, 0x89, 0xDE, 0x19, 0x4A, 0x57, 0xD5, 0x2E, 0xE6, + 0x5D, 0x1C, 0x53, 0x2C, 0x7E, 0x98, 0xCD, 0x1A, 0x06, 0x16, 0xA4, 0x68, + 0x73, 0xD0, 0x34, 0x04, 0x13, 0x5C, 0xA1, 0x71, 0xD3, 0x5A, 0x7C, 0x55, + 0xDB, 0x5E, 0x64, 0xE1, 0x37, 0x87, 0x30, 0x56, 0x04, 0xE5, 0x11, 0xB4, + 0x29, 0x80, 0x12, 0xF1, 0x79, 0x39, 0x88, 0xA2, 0x02, 0x11, 0x7C, 0x27, + 0x66, 0xB7, 0x88, 0xB7, 0x78, 0xF2, 0xCA, 0x0A, 0xA8, 0x38, 0xAB, 0x0A, + 0x64, 0xC2, 0xBF, 0x66, 0x5D, 0x95, 0x84, 0xC1, 0xA1, 0x25, 0x1E, 0x87, + 0x5D, 0x1A, 0x50, 0x0B, 0x20, 0x12, 0xCC, 0x41, 0xBB, 0x6E, 0x0B, 0x51, + 0x38, 0xB8, 0x4B, 0xCB +}; + +static const unsigned char TA38_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA39_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1D, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x50, 0x33, 0x38, 0x34, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA39_EC_Q[] = { + 0x04, 0xC1, 0x44, 0xA1, 0xCF, 0x11, 0x97, 0x50, 0x9A, 0xDE, 0x23, 0x82, + 0x35, 0x07, 0xCD, 0xD0, 0xCB, 0x18, 0x9D, 0xD2, 0xF1, 0x7F, 0x77, 0x35, + 0x4F, 0x3B, 0xDD, 0x94, 0x72, 0x52, 0xED, 0xC2, 0x3B, 0xF8, 0xEC, 0xFA, + 0x7B, 0x6B, 0x58, 0x20, 0xEC, 0x99, 0xAE, 0xC9, 0xFC, 0x68, 0xB3, 0x75, + 0xB9, 0xDB, 0x09, 0xEC, 0xC8, 0x13, 0xF5, 0x4E, 0xC6, 0x0A, 0x1D, 0x66, + 0x30, 0x4C, 0xBB, 0x1F, 0x47, 0x0A, 0x3C, 0x61, 0x10, 0x42, 0x29, 0x7C, + 0xA5, 0x08, 0x0E, 0xE0, 0x22, 0xE9, 0xD3, 0x35, 0x68, 0xCE, 0x9B, 0x63, + 0x9F, 0x84, 0xB5, 0x99, 0x4D, 0x58, 0xA0, 0x8E, 0xF5, 0x54, 0xE7, 0x95, + 0xC9 +}; + +static const unsigned char TA40_DN[] = { + 0x30, 0x67, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x13, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA40_RSA_N[] = { + 0x93, 0x4B, 0xBB, 0xE9, 0x66, 0x8A, 0xEE, 0x9D, 0x5B, 0xD5, 0x34, 0x93, + 0xD0, 0x1B, 0x1E, 0xC3, 0xE7, 0x9E, 0xB8, 0x64, 0x33, 0x7F, 0x63, 0x78, + 0x68, 0xB4, 0xCD, 0x2E, 0x71, 0x75, 0xD7, 0x9B, 0x20, 0xC6, 0x4D, 0x29, + 0xBC, 0xB6, 0x68, 0x60, 0x8A, 0xF7, 0x21, 0x9A, 0x56, 0x35, 0x5A, 0xF3, + 0x76, 0xBD, 0xD8, 0xCD, 0x9A, 0xFF, 0x93, 0x56, 0x4B, 0xA5, 0x59, 0x06, + 0xA1, 0x93, 0x34, 0x29, 0xDD, 0x16, 0x34, 0x75, 0x4E, 0xF2, 0x81, 0xB4, + 0xC7, 0x96, 0x4E, 0xAD, 0x19, 0x15, 0x52, 0x4A, 0xFE, 0x3C, 0x70, 0x75, + 0x70, 0xCD, 0xAF, 0x2B, 0xAB, 0x15, 0x9A, 0x33, 0x3C, 0xAA, 0xB3, 0x8B, + 0xAA, 0xCD, 0x43, 0xFD, 0xF5, 0xEA, 0x70, 0xFF, 0xED, 0xCF, 0x11, 0x3B, + 0x94, 0xCE, 0x4E, 0x32, 0x16, 0xD3, 0x23, 0x40, 0x2A, 0x77, 0xB3, 0xAF, + 0x3C, 0x01, 0x2C, 0x6C, 0xED, 0x99, 0x2C, 0x8B, 0xD9, 0x4E, 0x69, 0x98, + 0xB2, 0xF7, 0x8F, 0x41, 0xB0, 0x32, 0x78, 0x61, 0xD6, 0x0D, 0x5F, 0xC3, + 0xFA, 0xA2, 0x40, 0x92, 0x1D, 0x5C, 0x17, 0xE6, 0x70, 0x3E, 0x35, 0xE7, + 0xA2, 0xB7, 0xC2, 0x62, 0xE2, 0xAB, 0xA4, 0x38, 0x4C, 0xB5, 0x39, 0x35, + 0x6F, 0xEA, 0x03, 0x69, 0xFA, 0x3A, 0x54, 0x68, 0x85, 0x6D, 0xD6, 0xF2, + 0x2F, 0x43, 0x55, 0x1E, 0x91, 0x0D, 0x0E, 0xD8, 0xD5, 0x6A, 0xA4, 0x96, + 0xD1, 0x13, 0x3C, 0x2C, 0x78, 0x50, 0xE8, 0x3A, 0x92, 0xD2, 0x17, 0x56, + 0xE5, 0x35, 0x1A, 0x40, 0x1C, 0x3E, 0x8D, 0x2C, 0xED, 0x39, 0xDF, 0x42, + 0xE0, 0x83, 0x41, 0x74, 0xDF, 0xA3, 0xCD, 0xC2, 0x86, 0x60, 0x48, 0x68, + 0xE3, 0x69, 0x0B, 0x54, 0x00, 0x8B, 0xE4, 0x76, 0x69, 0x21, 0x0D, 0x79, + 0x4E, 0x34, 0x08, 0x5E, 0x14, 0xC2, 0xCC, 0xB1, 0xB7, 0xAD, 0xD7, 0x7C, + 0x70, 0x8A, 0xC7, 0x85 +}; + +static const unsigned char TA40_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA41_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x35, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA41_EC_Q[] = { + 0x04, 0x47, 0x45, 0x0E, 0x96, 0xFB, 0x7D, 0x5D, 0xBF, 0xE9, 0x39, 0xD1, + 0x21, 0xF8, 0x9F, 0x0B, 0xB6, 0xD5, 0x7B, 0x1E, 0x92, 0x3A, 0x48, 0x59, + 0x1C, 0xF0, 0x62, 0x31, 0x2D, 0xC0, 0x7A, 0x28, 0xFE, 0x1A, 0xA7, 0x5C, + 0xB3, 0xB6, 0xCC, 0x97, 0xE7, 0x45, 0xD4, 0x58, 0xFA, 0xD1, 0x77, 0x6D, + 0x43, 0xA2, 0xC0, 0x87, 0x65, 0x34, 0x0A, 0x1F, 0x7A, 0xDD, 0xEB, 0x3C, + 0x33, 0xA1, 0xC5, 0x9D, 0x4D, 0xA4, 0x6F, 0x41, 0x95, 0x38, 0x7F, 0xC9, + 0x1E, 0x84, 0xEB, 0xD1, 0x9E, 0x49, 0x92, 0x87, 0x94, 0x87, 0x0C, 0x3A, + 0x85, 0x4A, 0x66, 0x9F, 0x9D, 0x59, 0x93, 0x4D, 0x97, 0x61, 0x06, 0x86, + 0x4A +}; + +static const unsigned char TA42_DN[] = { + 0x30, 0x52, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x53, 0x4B, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x0A, 0x42, 0x72, 0x61, 0x74, 0x69, 0x73, 0x6C, 0x61, 0x76, 0x61, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x61, 0x2E, 0x73, 0x2E, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x41, 0x20, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x32 +}; + +static const unsigned char TA42_RSA_N[] = { + 0xA2, 0xA3, 0xC4, 0x00, 0x09, 0xD6, 0x85, 0x5D, 0x2D, 0x6D, 0x14, 0xF6, + 0xC2, 0xC3, 0x73, 0x9E, 0x35, 0xC2, 0x71, 0x55, 0x7E, 0x81, 0xFB, 0xAB, + 0x46, 0x50, 0xE0, 0xC1, 0x7C, 0x49, 0x78, 0xE6, 0xAB, 0x79, 0x58, 0x3C, + 0xDA, 0xFF, 0x7C, 0x1C, 0x9F, 0xD8, 0x97, 0x02, 0x78, 0x3E, 0x6B, 0x41, + 0x04, 0xE9, 0x41, 0xBD, 0xBE, 0x03, 0x2C, 0x45, 0xF6, 0x2F, 0x64, 0xD4, + 0xAB, 0x5D, 0xA3, 0x47, 0x3D, 0x64, 0x9B, 0xE9, 0x68, 0x9A, 0xC6, 0xCC, + 0x1B, 0x3F, 0xBA, 0xBE, 0xB2, 0x8B, 0x34, 0x02, 0x2E, 0x98, 0x55, 0x19, + 0xFC, 0x8C, 0x6F, 0xAA, 0x5F, 0xDA, 0x4C, 0xCE, 0x4D, 0x03, 0x21, 0xA3, + 0xD8, 0xD2, 0x34, 0x93, 0x56, 0x96, 0xCB, 0x4C, 0x0C, 0x00, 0x16, 0x3C, + 0x5F, 0x1A, 0xCD, 0xC8, 0xC7, 0x6C, 0xA6, 0xAD, 0xD3, 0x31, 0xA7, 0xBC, + 0xE8, 0xE5, 0xE1, 0x66, 0xD6, 0xD2, 0xFB, 0x03, 0xB4, 0x41, 0x65, 0xC9, + 0x10, 0xAE, 0x0E, 0x05, 0x63, 0xC6, 0x80, 0x6A, 0x69, 0x30, 0xFD, 0xD2, + 0xEE, 0x90, 0xEF, 0x0D, 0x27, 0xDF, 0x9F, 0x95, 0x73, 0xF4, 0xE1, 0x25, + 0xDA, 0x6C, 0x16, 0xDE, 0x41, 0x38, 0x34, 0xEA, 0x8B, 0xFC, 0xD1, 0xE8, + 0x04, 0x14, 0x61, 0x2D, 0x41, 0x7E, 0xAC, 0xC7, 0x77, 0x4E, 0xCB, 0x51, + 0x54, 0xFB, 0x5E, 0x92, 0x18, 0x1B, 0x04, 0x5A, 0x68, 0xC6, 0xC9, 0xC4, + 0xFA, 0xB7, 0x13, 0xA0, 0x98, 0xB7, 0x11, 0x2B, 0xB7, 0xD6, 0x57, 0xCC, + 0x7C, 0x9E, 0x17, 0xD1, 0xCB, 0x25, 0xFE, 0x86, 0x4E, 0x24, 0x2E, 0x56, + 0x0C, 0x78, 0x4D, 0x9E, 0x01, 0x12, 0xA6, 0x2B, 0xA7, 0x01, 0x65, 0x6E, + 0x7C, 0x62, 0x1D, 0x84, 0x84, 0xDF, 0xEA, 0xC0, 0x6B, 0xB5, 0xA5, 0x2A, + 0x95, 0x83, 0xC3, 0x53, 0x11, 0x0C, 0x73, 0x1D, 0x0B, 0xB2, 0x46, 0x90, + 0xD1, 0x42, 0x3A, 0xCE, 0x40, 0x6E, 0x95, 0xAD, 0xFF, 0xC6, 0x94, 0xAD, + 0x6E, 0x97, 0x84, 0x8E, 0x7D, 0x6F, 0x9E, 0x8A, 0x80, 0x0D, 0x49, 0x6D, + 0x73, 0xE2, 0x7B, 0x92, 0x1E, 0xC3, 0xF3, 0xC1, 0xF3, 0xEB, 0x2E, 0x05, + 0x6F, 0xD9, 0x1B, 0xCF, 0x37, 0x76, 0x04, 0xC8, 0xB4, 0x5A, 0xE4, 0x17, + 0xA7, 0xCB, 0xDD, 0x76, 0x1F, 0xD0, 0x19, 0x76, 0xE8, 0x2C, 0x05, 0xB3, + 0xD6, 0x9C, 0x34, 0xD8, 0x96, 0xDC, 0x61, 0x87, 0x91, 0x05, 0xE4, 0x44, + 0x08, 0x33, 0xC1, 0xDA, 0xB9, 0x08, 0x65, 0xD4, 0xAE, 0xB2, 0x36, 0x0D, + 0xEB, 0xBA, 0x38, 0xBA, 0x0C, 0xE5, 0x9B, 0x9E, 0xEB, 0x8D, 0x66, 0xDD, + 0x99, 0xCF, 0xD6, 0x89, 0x41, 0xF6, 0x04, 0x92, 0x8A, 0x29, 0x29, 0x6D, + 0x6B, 0x3A, 0x1C, 0xE7, 0x75, 0x7D, 0x02, 0x71, 0x0E, 0xF3, 0xC0, 0xE7, + 0xBD, 0xCB, 0x19, 0xDD, 0x9D, 0x60, 0xB2, 0xC2, 0x66, 0x60, 0xB6, 0xB1, + 0x04, 0xEE, 0xC9, 0xE6, 0x86, 0xB9, 0x9A, 0x66, 0x40, 0xA8, 0xE7, 0x11, + 0xED, 0x81, 0x45, 0x03, 0x8B, 0xF6, 0x67, 0x59, 0xE8, 0xC1, 0x06, 0x11, + 0xBD, 0xDD, 0xCF, 0x80, 0x02, 0x4F, 0x65, 0x40, 0x78, 0x5C, 0x47, 0x50, + 0xC8, 0x9B, 0xE6, 0x1F, 0x81, 0x7B, 0xE4, 0x44, 0xA8, 0x5B, 0x85, 0x9A, + 0xE2, 0xDE, 0x5A, 0xD5, 0xC7, 0xF9, 0x3A, 0x44, 0x66, 0x4B, 0xE4, 0x32, + 0x54, 0x7C, 0xE4, 0x6C, 0x9C, 0xB3, 0x0E, 0x3D, 0x17, 0xA2, 0xB2, 0x34, + 0x12, 0xD6, 0x7E, 0xB2, 0xA8, 0x49, 0xBB, 0xD1, 0x7A, 0x28, 0x40, 0xBE, + 0xA2, 0x16, 0x1F, 0xDF, 0xE4, 0x37, 0x1F, 0x11, 0x73, 0xFB, 0x90, 0x0A, + 0x65, 0x43, 0xA2, 0x0D, 0x7C, 0xF8, 0x06, 0x01, 0x55, 0x33, 0x7D, 0xB0, + 0x0D, 0xB8, 0xF4, 0xF5, 0xAE, 0xA5, 0x42, 0x57, 0x7C, 0x36, 0x11, 0x8C, + 0x7B, 0x5E, 0xC4, 0x03, 0x9D, 0x8C, 0x79, 0x9D +}; + +static const unsigned char TA42_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA43_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C +}; + +static const unsigned char TA43_RSA_N[] = { + 0xF6, 0x1B, 0x4F, 0x67, 0x07, 0x2B, 0xA1, 0x15, 0xF5, 0x06, 0x22, 0xCB, + 0x1F, 0x01, 0xB2, 0xE3, 0x73, 0x45, 0x06, 0x44, 0x49, 0x2C, 0xBB, 0x49, + 0x25, 0x14, 0xD6, 0xCE, 0xC3, 0xB7, 0xAB, 0x2C, 0x4F, 0xC6, 0x41, 0x32, + 0x94, 0x57, 0xFA, 0x12, 0xA7, 0x5B, 0x0E, 0xE2, 0x8F, 0x1F, 0x1E, 0x86, + 0x19, 0xA7, 0xAA, 0xB5, 0x2D, 0xB9, 0x5F, 0x0D, 0x8A, 0xC2, 0xAF, 0x85, + 0x35, 0x79, 0x32, 0x2D, 0xBB, 0x1C, 0x62, 0x37, 0xF2, 0xB1, 0x5B, 0x4A, + 0x3D, 0xCA, 0xCD, 0x71, 0x5F, 0xE9, 0x42, 0xBE, 0x94, 0xE8, 0xC8, 0xDE, + 0xF9, 0x22, 0x48, 0x64, 0xC6, 0xE5, 0xAB, 0xC6, 0x2B, 0x6D, 0xAD, 0x05, + 0xF0, 0xFA, 0xD5, 0x0B, 0xCF, 0x9A, 0xE5, 0xF0, 0x50, 0xA4, 0x8B, 0x3B, + 0x47, 0xA5, 0x23, 0x5B, 0x7A, 0x7A, 0xF8, 0x33, 0x3F, 0xB8, 0xEF, 0x99, + 0x97, 0xE3, 0x20, 0xC1, 0xD6, 0x28, 0x89, 0xCF, 0x94, 0xFB, 0xB9, 0x45, + 0xED, 0xE3, 0x40, 0x17, 0x11, 0xD4, 0x74, 0xF0, 0x0B, 0x31, 0xE2, 0x2B, + 0x26, 0x6A, 0x9B, 0x4C, 0x57, 0xAE, 0xAC, 0x20, 0x3E, 0xBA, 0x45, 0x7A, + 0x05, 0xF3, 0xBD, 0x9B, 0x69, 0x15, 0xAE, 0x7D, 0x4E, 0x20, 0x63, 0xC4, + 0x35, 0x76, 0x3A, 0x07, 0x02, 0xC9, 0x37, 0xFD, 0xC7, 0x47, 0xEE, 0xE8, + 0xF1, 0x76, 0x1D, 0x73, 0x15, 0xF2, 0x97, 0xA4, 0xB5, 0xC8, 0x7A, 0x79, + 0xD9, 0x42, 0xAA, 0x2B, 0x7F, 0x5C, 0xFE, 0xCE, 0x26, 0x4F, 0xA3, 0x66, + 0x81, 0x35, 0xAF, 0x44, 0xBA, 0x54, 0x1E, 0x1C, 0x30, 0x32, 0x65, 0x9D, + 0xE6, 0x3C, 0x93, 0x5E, 0x50, 0x4E, 0x7A, 0xE3, 0x3A, 0xD4, 0x6E, 0xCC, + 0x1A, 0xFB, 0xF9, 0xD2, 0x37, 0xAE, 0x24, 0x2A, 0xAB, 0x57, 0x03, 0x22, + 0x28, 0x0D, 0x49, 0x75, 0x7F, 0xB7, 0x28, 0xDA, 0x75, 0xBF, 0x8E, 0xE3, + 0xDC, 0x0E, 0x79, 0x31 +}; + +static const unsigned char TA43_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA44_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA44_RSA_N[] = { + 0xD0, 0xA4, 0x09, 0x72, 0x4F, 0x40, 0x88, 0x12, 0x61, 0x3E, 0x35, 0x23, + 0x9E, 0xEE, 0xF6, 0x74, 0xCF, 0x2F, 0x7B, 0x58, 0x3D, 0xCE, 0x3C, 0x0D, + 0x10, 0x28, 0x90, 0x2F, 0x97, 0xF7, 0x8C, 0x48, 0xD8, 0xA0, 0xD8, 0x25, + 0xB1, 0x4C, 0xB0, 0x11, 0x4C, 0x17, 0x73, 0x50, 0xD0, 0x22, 0x4A, 0x63, + 0xBB, 0x81, 0xD3, 0x29, 0x6E, 0xD5, 0xB5, 0x09, 0x3E, 0x26, 0x18, 0x7F, + 0xB2, 0x12, 0x7F, 0x93, 0x98, 0xB7, 0xAF, 0xF0, 0x36, 0xBF, 0xF2, 0xEE, + 0x18, 0x9E, 0x9C, 0x3B, 0x52, 0xC5, 0x47, 0x19, 0x5D, 0x74, 0xF3, 0x64, + 0x66, 0xD5, 0x5D, 0xC7, 0x68, 0xB4, 0xBF, 0x1B, 0x1C, 0x06, 0xA3, 0xBC, + 0x8F, 0x40, 0x23, 0xB6, 0x1E, 0xC6, 0x84, 0xBD, 0x51, 0xC4, 0x1B, 0x39, + 0xC1, 0x95, 0xD2, 0x29, 0xEC, 0x4B, 0xAE, 0x7B, 0x2D, 0xBF, 0x39, 0xFD, + 0xB4, 0x62, 0xDE, 0x96, 0x7B, 0x41, 0xC6, 0x9C, 0xA0, 0xE0, 0x06, 0x72, + 0xFB, 0xF0, 0x07, 0x97, 0x09, 0x39, 0x81, 0x74, 0xAF, 0xF7, 0x34, 0x59, + 0x11, 0x57, 0x0A, 0xC2, 0x5B, 0xC1, 0x24, 0xF4, 0x31, 0x73, 0x30, 0x82, + 0xC6, 0x9D, 0xBA, 0x02, 0xF7, 0x3E, 0x7C, 0x44, 0x5F, 0x83, 0x0D, 0xF3, + 0xF1, 0xDD, 0x20, 0x69, 0x16, 0x09, 0x50, 0xE2, 0xD4, 0x55, 0xB6, 0xE0, + 0x80, 0x72, 0x76, 0x6E, 0x4C, 0x47, 0xB7, 0x75, 0x55, 0x59, 0xB4, 0x53, + 0x74, 0xD9, 0x94, 0xC6, 0x41, 0xAD, 0x58, 0x8A, 0x31, 0x66, 0x0F, 0x1E, + 0xA2, 0x1B, 0x29, 0x40, 0x4E, 0x2F, 0xDF, 0x7B, 0xE6, 0x16, 0x2C, 0x2D, + 0xFC, 0xBF, 0xEC, 0xF3, 0xB4, 0xFA, 0xBE, 0x18, 0xF6, 0x9B, 0x49, 0xD4, + 0xEE, 0x05, 0x6E, 0xD9, 0x34, 0xF3, 0x9C, 0xF1, 0xEC, 0x01, 0x8B, 0xD1, + 0x20, 0xC6, 0x0F, 0xA0, 0xB5, 0xBC, 0x17, 0x4E, 0x48, 0x7B, 0x51, 0xC2, + 0xFC, 0xE9, 0x5C, 0x69, 0x37, 0x47, 0x66, 0xB3, 0x68, 0xF8, 0x15, 0x28, + 0xF0, 0xB9, 0xD3, 0xA4, 0x15, 0xCC, 0x5A, 0x4F, 0xBA, 0x52, 0x70, 0xA3, + 0x12, 0x45, 0xDD, 0xC6, 0xBA, 0x4E, 0xFB, 0xC2, 0xD0, 0xF7, 0xA8, 0x52, + 0x27, 0x6D, 0x6E, 0x79, 0xB5, 0x8C, 0xFC, 0x7B, 0x8C, 0xC1, 0x16, 0x4C, + 0xEE, 0x80, 0x7F, 0xBE, 0xF0, 0x76, 0xBE, 0x41, 0x53, 0x12, 0x33, 0xAE, + 0x5A, 0x38, 0x42, 0xAB, 0xD7, 0x0F, 0x3E, 0x41, 0x8D, 0x76, 0x07, 0x32, + 0xD5, 0xAB, 0x89, 0xF6, 0x4E, 0x67, 0xD9, 0xB1, 0x42, 0x75, 0x23, 0x6E, + 0xF3, 0xCD, 0x42, 0xB2, 0xFC, 0x55, 0xF5, 0x53, 0x87, 0x17, 0x3B, 0xC0, + 0x33, 0x58, 0xF1, 0x52, 0xD2, 0xF9, 0x80, 0xA4, 0xF0, 0xE8, 0xF0, 0x3B, + 0x8B, 0x38, 0xCC, 0xA4, 0xC6, 0x90, 0x7F, 0x0F, 0x9C, 0xFD, 0x8B, 0xD1, + 0xA3, 0xCF, 0xDA, 0x83, 0xA7, 0x69, 0xC9, 0x50, 0x36, 0xD5, 0x5C, 0x05, + 0xD2, 0x0A, 0x41, 0x74, 0xDB, 0x63, 0x11, 0x37, 0xC1, 0xA5, 0xA0, 0x96, + 0x4B, 0x1E, 0x8C, 0x16, 0x12, 0x77, 0xAE, 0x94, 0x34, 0x7B, 0x1E, 0x7F, + 0xC2, 0x66, 0x00, 0xE4, 0xAA, 0x83, 0xEA, 0x8A, 0x90, 0xAD, 0xCE, 0x36, + 0x44, 0x4D, 0xD1, 0x51, 0xE9, 0xBC, 0x1F, 0xF3, 0x6A, 0x05, 0xFD, 0xC0, + 0x74, 0x1F, 0x25, 0x19, 0x40, 0x51, 0x6E, 0xEA, 0x82, 0x51, 0x40, 0xDF, + 0x9B, 0xB9, 0x08, 0x2A, 0x06, 0x02, 0xD5, 0x23, 0x1C, 0x13, 0xD6, 0xE9, + 0xDB, 0xDB, 0xC6, 0xB0, 0x7A, 0xCB, 0x7B, 0x27, 0x9B, 0xFB, 0xE0, 0xD5, + 0x46, 0x24, 0xED, 0x10, 0x4B, 0x63, 0x4B, 0xA5, 0x05, 0x8F, 0xBA, 0xB8, + 0x1D, 0x2B, 0xA6, 0xFA, 0x91, 0xE2, 0x92, 0x52, 0xBD, 0xEC, 0xEB, 0x67, + 0x97, 0x6D, 0x9A, 0x2D, 0x9F, 0x81, 0x32, 0x05, 0x67, 0x32, 0xFB, 0x48, + 0x08, 0x3F, 0xD9, 0x25, 0xB8, 0x04, 0x25, 0x2F +}; + +static const unsigned char TA44_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA45_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x45, 0x43, 0x43, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA45_EC_Q[] = { + 0x04, 0x96, 0x86, 0x58, 0x28, 0x37, 0x0A, 0x67, 0xD0, 0xA0, 0xDE, 0x24, + 0x19, 0x19, 0xE1, 0xE4, 0x05, 0x07, 0x1F, 0x97, 0xED, 0xE8, 0x64, 0x82, + 0xB9, 0xF6, 0xC4, 0x71, 0x50, 0xCE, 0x8A, 0x0C, 0xFF, 0xD7, 0xB5, 0x76, + 0xBB, 0xA1, 0x6C, 0x93, 0x6C, 0x83, 0xA2, 0x68, 0x6E, 0xA5, 0xD9, 0xBE, + 0x2C, 0x88, 0x95, 0x41, 0xCD, 0x5D, 0xDD, 0xB1, 0xCA, 0x83, 0x63, 0x83, + 0xCC, 0xC0, 0xBE, 0x74, 0xD9, 0xE0, 0x9D, 0xA4, 0xEE, 0x4A, 0x4E, 0x56, + 0xE0, 0x98, 0x29, 0x41, 0x93, 0x52, 0x10, 0xD5, 0x24, 0x38, 0x02, 0x32, + 0x67, 0xF1, 0x94, 0x12, 0x6F, 0xEF, 0xD7, 0xC5, 0xDE, 0x2E, 0xFD, 0x19, + 0x80 +}; + +static const unsigned char TA46_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA46_RSA_N[] = { + 0xA5, 0xDA, 0x0A, 0x95, 0x16, 0x50, 0xE3, 0x95, 0xF2, 0x5E, 0x9D, 0x76, + 0x31, 0x06, 0x32, 0x7A, 0x9B, 0xF1, 0x10, 0x76, 0xB8, 0x00, 0x9A, 0xB5, + 0x52, 0x36, 0xCD, 0x24, 0x47, 0xB0, 0x9F, 0x18, 0x64, 0xBC, 0x9A, 0xF6, + 0xFA, 0xD5, 0x79, 0xD8, 0x90, 0x62, 0x4C, 0x22, 0x2F, 0xDE, 0x38, 0x3D, + 0xD6, 0xE0, 0xA8, 0xE9, 0x1C, 0x2C, 0xDB, 0x78, 0x11, 0xE9, 0x8E, 0x68, + 0x51, 0x15, 0x72, 0xC7, 0xF3, 0x33, 0x87, 0xE4, 0xA0, 0x5D, 0x0B, 0x5C, + 0xE0, 0x57, 0x07, 0x2A, 0x30, 0xF5, 0xCD, 0xC4, 0x37, 0x77, 0x28, 0x4D, + 0x18, 0x91, 0xE6, 0xBF, 0xD5, 0x52, 0xFD, 0x71, 0x2D, 0x70, 0x3E, 0xE7, + 0xC6, 0xC4, 0x8A, 0xE3, 0xF0, 0x28, 0x0B, 0xF4, 0x76, 0x98, 0xA1, 0x8B, + 0x87, 0x55, 0xB2, 0x3A, 0x13, 0xFC, 0xB7, 0x3E, 0x27, 0x37, 0x8E, 0x22, + 0xE3, 0xA8, 0x4F, 0x2A, 0xEF, 0x60, 0xBB, 0x3D, 0xB7, 0x39, 0xC3, 0x0E, + 0x01, 0x47, 0x99, 0x5D, 0x12, 0x4F, 0xDB, 0x43, 0xFA, 0x57, 0xA1, 0xED, + 0xF9, 0x9D, 0xBE, 0x11, 0x47, 0x26, 0x5B, 0x13, 0x98, 0xAB, 0x5D, 0x16, + 0x8A, 0xB0, 0x37, 0x1C, 0x57, 0x9D, 0x45, 0xFF, 0x88, 0x96, 0x36, 0xBF, + 0xBB, 0xCA, 0x07, 0x7B, 0x6F, 0x87, 0x63, 0xD7, 0xD0, 0x32, 0x6A, 0xD6, + 0x5D, 0x6C, 0x0C, 0xF1, 0xB3, 0x6E, 0x39, 0xE2, 0x6B, 0x31, 0x2E, 0x39, + 0x00, 0x27, 0x14, 0xDE, 0x38, 0xC0, 0xEC, 0x19, 0x66, 0x86, 0x12, 0xE8, + 0x9D, 0x72, 0x16, 0x13, 0x64, 0x52, 0xC7, 0xA9, 0x37, 0x1C, 0xFD, 0x82, + 0x30, 0xED, 0x84, 0x18, 0x1D, 0xF4, 0xAE, 0x5C, 0xFF, 0x70, 0x13, 0x00, + 0xEB, 0xB1, 0xF5, 0x33, 0x7A, 0x4B, 0xD6, 0x55, 0xF8, 0x05, 0x8D, 0x4B, + 0x69, 0xB0, 0xF5, 0xB3, 0x28, 0x36, 0x5C, 0x14, 0xC4, 0x51, 0x73, 0x4D, + 0x6B, 0x0B, 0xF1, 0x34, 0x07, 0xDB, 0x17, 0x39, 0xD7, 0xDC, 0x28, 0x7B, + 0x6B, 0xF5, 0x9F, 0xF3, 0x2E, 0xC1, 0x4F, 0x17, 0x2A, 0x10, 0xF3, 0xCC, + 0xCA, 0xE8, 0xEB, 0xFD, 0x6B, 0xAB, 0x2E, 0x9A, 0x9F, 0x2D, 0x82, 0x6E, + 0x04, 0xD4, 0x52, 0x01, 0x93, 0x2D, 0x3D, 0x86, 0xFC, 0x7E, 0xFC, 0xDF, + 0xEF, 0x42, 0x1D, 0xA6, 0x6B, 0xEF, 0xB9, 0x20, 0xC6, 0xF7, 0xBD, 0xA0, + 0xA7, 0x95, 0xFD, 0xA7, 0xE6, 0x89, 0x24, 0xD8, 0xCC, 0x8C, 0x34, 0x6C, + 0xE2, 0x23, 0x2F, 0xD9, 0x12, 0x1A, 0x21, 0xB9, 0x55, 0x91, 0x6F, 0x0B, + 0x91, 0x79, 0x19, 0x0C, 0xAD, 0x40, 0x88, 0x0B, 0x70, 0xE2, 0x7A, 0xD2, + 0x0E, 0xD8, 0x68, 0x48, 0xBB, 0x82, 0x13, 0x39, 0x10, 0x58, 0xE9, 0xD8, + 0x2A, 0x07, 0xC6, 0x12, 0xDB, 0x58, 0xDB, 0xD2, 0x3B, 0x55, 0x10, 0x47, + 0x05, 0x15, 0x67, 0x62, 0x7E, 0x18, 0x63, 0xA6, 0x46, 0x3F, 0x09, 0x0E, + 0x54, 0x32, 0x5E, 0xBF, 0x0D, 0x62, 0x7A, 0x27, 0xEF, 0x80, 0xE8, 0xDB, + 0xD9, 0x4B, 0x06, 0x5A, 0x37, 0x5A, 0x25, 0xD0, 0x08, 0x12, 0x77, 0xD4, + 0x6F, 0x09, 0x50, 0x97, 0x3D, 0xC8, 0x1D, 0xC3, 0xDF, 0x8C, 0x45, 0x30, + 0x56, 0xC6, 0xD3, 0x64, 0xAB, 0x66, 0xF3, 0xC0, 0x5E, 0x96, 0x9C, 0xC3, + 0xC4, 0xEF, 0xC3, 0x7C, 0x6B, 0x8B, 0x3A, 0x79, 0x7F, 0xB3, 0x49, 0xCF, + 0x3D, 0xE2, 0x89, 0x9F, 0xA0, 0x30, 0x4B, 0x85, 0xB9, 0x9C, 0x94, 0x24, + 0x79, 0x8F, 0x7D, 0x6B, 0xA9, 0x45, 0x68, 0x0F, 0x2B, 0xD0, 0xF1, 0xDA, + 0x1C, 0xCB, 0x69, 0xB8, 0xCA, 0x49, 0x62, 0x6D, 0xC8, 0xD0, 0x63, 0x62, + 0xDD, 0x60, 0x0F, 0x58, 0xAA, 0x8F, 0xA1, 0xBC, 0x05, 0xA5, 0x66, 0xA2, + 0xCF, 0x1B, 0x76, 0xB2, 0x84, 0x64, 0xB1, 0x4C, 0x39, 0x52, 0xC0, 0x30, + 0xBA, 0xF0, 0x8C, 0x4B, 0x02, 0xB0, 0xB6, 0xB7 +}; + +static const unsigned char TA46_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA47_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x13, 0x30, 0x30, + 0x30, 0x32, 0x20, 0x34, 0x38, 0x31, 0x34, 0x36, 0x33, 0x30, 0x38, 0x31, + 0x30, 0x30, 0x30, 0x33, 0x36, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA47_RSA_N[] = { + 0xCD, 0x18, 0x39, 0x65, 0x1A, 0x59, 0xB1, 0xEA, 0x64, 0x16, 0x0E, 0x8C, + 0x94, 0x24, 0x95, 0x7C, 0x83, 0xD3, 0xC5, 0x39, 0x26, 0xDC, 0x0C, 0xEF, + 0x16, 0x57, 0x8D, 0xD7, 0xD8, 0xAC, 0xA3, 0x42, 0x7F, 0x82, 0xCA, 0xED, + 0xCD, 0x5B, 0xDB, 0x0E, 0xB7, 0x2D, 0xED, 0x45, 0x08, 0x17, 0xB2, 0xD9, + 0xB3, 0xCB, 0xD6, 0x17, 0x52, 0x72, 0x28, 0xDB, 0x8E, 0x4E, 0x9E, 0x8A, + 0xB6, 0x0B, 0xF9, 0x9E, 0x84, 0x9A, 0x4D, 0x76, 0xDE, 0x22, 0x29, 0x5C, + 0xD2, 0xB3, 0xD2, 0x06, 0x3E, 0x30, 0x39, 0xA9, 0x74, 0xA3, 0x92, 0x56, + 0x1C, 0xA1, 0x6F, 0x4C, 0x0A, 0x20, 0x6D, 0x9F, 0x23, 0x7A, 0xB4, 0xC6, + 0xDA, 0x2C, 0xE4, 0x1D, 0x2C, 0xDC, 0xB3, 0x28, 0xD0, 0x13, 0xF2, 0x4C, + 0x4E, 0x02, 0x49, 0xA1, 0x54, 0x40, 0x9E, 0xE6, 0xE5, 0x05, 0xA0, 0x2D, + 0x84, 0xC8, 0xFF, 0x98, 0x6C, 0xD0, 0xEB, 0x8A, 0x1A, 0x84, 0x08, 0x1E, + 0xB7, 0x68, 0x23, 0xEE, 0x23, 0xD5, 0x70, 0xCE, 0x6D, 0x51, 0x69, 0x10, + 0xEE, 0xA1, 0x7A, 0xC2, 0xD1, 0x22, 0x31, 0xC2, 0x82, 0x85, 0xD2, 0xF2, + 0x55, 0x76, 0x50, 0x7C, 0x25, 0x7A, 0xC9, 0x84, 0x5C, 0x0B, 0xAC, 0xDD, + 0x42, 0x4E, 0x2B, 0xE7, 0x82, 0xA2, 0x24, 0x89, 0xCB, 0x90, 0xB2, 0xD0, + 0xEE, 0x23, 0xBA, 0x66, 0x4C, 0xBB, 0x62, 0xA4, 0xF9, 0x53, 0x5A, 0x64, + 0x7B, 0x7C, 0x98, 0xFA, 0xA3, 0x48, 0x9E, 0x0F, 0x95, 0xAE, 0xA7, 0x18, + 0xF4, 0x6A, 0xEC, 0x2E, 0x03, 0x45, 0xAF, 0xF0, 0x74, 0xF8, 0x2A, 0xCD, + 0x7A, 0x5D, 0xD1, 0xBE, 0x44, 0x26, 0x32, 0x29, 0xF1, 0xF1, 0xF5, 0x6C, + 0xCC, 0x7E, 0x02, 0x21, 0x0B, 0x9F, 0x6F, 0xA4, 0x3F, 0xBE, 0x9D, 0x53, + 0xE2, 0xCF, 0x7D, 0xA9, 0x2C, 0x7C, 0x58, 0x1A, 0x97, 0xE1, 0x3D, 0x37, + 0x37, 0x18, 0x66, 0x28, 0xD2, 0x40, 0xC5, 0x51, 0x8A, 0x8C, 0xC3, 0x2D, + 0xCE, 0x53, 0x88, 0x24, 0x58, 0x64, 0x30, 0x16, 0xC5, 0xAA, 0xE0, 0xD6, + 0x0A, 0xA6, 0x40, 0xDF, 0x78, 0xF6, 0xF5, 0x04, 0x7C, 0x69, 0x13, 0x84, + 0xBC, 0xD1, 0xD1, 0xA7, 0x06, 0xCF, 0x01, 0xF7, 0x68, 0xC0, 0xA8, 0x57, + 0xBB, 0x3A, 0x61, 0xAD, 0x04, 0x8C, 0x93, 0xE3, 0xAD, 0xFC, 0xF0, 0xDB, + 0x44, 0x6D, 0x59, 0xDC, 0x49, 0x59, 0xAE, 0xAC, 0x9A, 0x99, 0x36, 0x30, + 0x41, 0x7B, 0x76, 0x33, 0x22, 0x87, 0xA3, 0xC2, 0x92, 0x86, 0x6E, 0xF9, + 0x70, 0xEE, 0xAE, 0x87, 0x87, 0x95, 0x1B, 0xC4, 0x7A, 0xBD, 0x31, 0xF3, + 0xD4, 0xD2, 0xE5, 0x99, 0xFF, 0xBE, 0x48, 0xEC, 0x75, 0xF5, 0x78, 0x16, + 0x1D, 0xA6, 0x70, 0xC1, 0x7F, 0x3C, 0x1B, 0xA1, 0x92, 0xFB, 0xCF, 0xC8, + 0x3C, 0xD6, 0xC5, 0x93, 0x0A, 0x8F, 0xF5, 0x55, 0x3A, 0x76, 0x95, 0xCE, + 0x59, 0x98, 0x8A, 0x09, 0x95, 0x77, 0x32, 0x9A, 0x83, 0xBA, 0x2C, 0x04, + 0x3A, 0x97, 0xBD, 0xD4, 0x2F, 0xBE, 0xD7, 0x6C, 0x9B, 0xA2, 0xCA, 0x7D, + 0x6D, 0x26, 0xC9, 0x55, 0xD5, 0xCF, 0xC3, 0x79, 0x52, 0x08, 0x09, 0x99, + 0x07, 0x24, 0x2D, 0x64, 0x25, 0x6B, 0xA6, 0x21, 0x69, 0x9B, 0x6A, 0xDD, + 0x74, 0x4D, 0x6B, 0x97, 0x7A, 0x41, 0xBD, 0xAB, 0x17, 0xF9, 0x90, 0x17, + 0x48, 0x8F, 0x36, 0xF9, 0x2D, 0xD5, 0xC5, 0xDB, 0xEE, 0xAA, 0x85, 0x45, + 0x41, 0xFA, 0xCD, 0x3A, 0x45, 0xB1, 0x68, 0xE6, 0x36, 0x4C, 0x9B, 0x90, + 0x57, 0xEC, 0x23, 0xB9, 0x87, 0x08, 0xC2, 0xC4, 0x09, 0xF1, 0x97, 0x86, + 0x2A, 0x28, 0x4D, 0xE2, 0x74, 0xC0, 0xDA, 0xC4, 0x8C, 0xDB, 0xDF, 0xE2, + 0xA1, 0x17, 0x59, 0xCE, 0x24, 0x59, 0x74, 0x31, 0xDA, 0x7F, 0xFD, 0x30, + 0x6D, 0xD9, 0xDC, 0xE1, 0x6A, 0xE1, 0xFC, 0x5F +}; + +static const unsigned char TA47_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA48_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x1B, + 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x55, 0x43, 0x41, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x47, 0x32, 0x20, 0x52, + 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA48_RSA_N[] = { + 0xC5, 0xE6, 0x2B, 0x6F, 0x7C, 0xEF, 0x26, 0x05, 0x27, 0xA3, 0x81, 0x24, + 0xDA, 0x6F, 0xCB, 0x01, 0xF9, 0x99, 0x9A, 0xA9, 0x32, 0xC2, 0x22, 0x87, + 0x61, 0x41, 0x91, 0x3B, 0xCB, 0xC3, 0x68, 0x1B, 0x06, 0xC5, 0x4C, 0xA9, + 0x2B, 0xC1, 0x67, 0x17, 0x22, 0x1D, 0x2B, 0xED, 0xF9, 0x29, 0x89, 0x93, + 0xA2, 0x78, 0xBD, 0x92, 0x6B, 0xA0, 0xA3, 0x0D, 0xA2, 0x7E, 0xCA, 0x93, + 0xB3, 0xA6, 0xD1, 0x8C, 0x35, 0xD5, 0x75, 0xF9, 0x17, 0xF6, 0xCF, 0x45, + 0xC5, 0xE5, 0x7A, 0xEC, 0x77, 0x93, 0xA0, 0x8F, 0x23, 0xAE, 0x0E, 0x1A, + 0x03, 0x7F, 0xBE, 0xD4, 0xD0, 0xED, 0x2E, 0x7B, 0xAB, 0x46, 0x23, 0x5B, + 0xFF, 0x2C, 0xE6, 0x54, 0x7A, 0x94, 0xC0, 0x2A, 0x15, 0xF0, 0xC9, 0x8D, + 0xB0, 0x7A, 0x3B, 0x24, 0xE1, 0xD7, 0x68, 0xE2, 0x31, 0x3C, 0x06, 0x33, + 0x46, 0xB6, 0x54, 0x11, 0xA6, 0xA5, 0x2F, 0x22, 0x54, 0x2A, 0x58, 0x0D, + 0x01, 0x02, 0xF1, 0xFA, 0x15, 0x51, 0x67, 0x6C, 0xC0, 0xFA, 0xD7, 0xB6, + 0x1B, 0x7F, 0xD1, 0x56, 0x88, 0x2F, 0x1A, 0x3A, 0x8D, 0x3B, 0xBB, 0x82, + 0x11, 0xE0, 0x47, 0x00, 0xD0, 0x52, 0x87, 0xAB, 0xFB, 0x86, 0x7E, 0x0F, + 0x24, 0x6B, 0x40, 0x9D, 0x34, 0x67, 0xBC, 0x8D, 0xC7, 0x2D, 0x86, 0x6F, + 0x79, 0x3E, 0x8E, 0xA9, 0x3C, 0x17, 0x4B, 0x7F, 0xB0, 0x99, 0xE3, 0xB0, + 0x71, 0x60, 0xDC, 0x0B, 0xF5, 0x64, 0xC3, 0xCE, 0x43, 0xBC, 0x6D, 0x71, + 0xB9, 0xD2, 0xDE, 0x27, 0x5B, 0x8A, 0xE8, 0xD8, 0xC6, 0xAE, 0xE1, 0x59, + 0x7D, 0xCF, 0x28, 0x2D, 0x35, 0xB8, 0x95, 0x56, 0x1A, 0xF1, 0xB2, 0x58, + 0x4B, 0xB7, 0x12, 0x37, 0xC8, 0x7C, 0xB3, 0xED, 0x4B, 0x80, 0xE1, 0x8D, + 0xFA, 0x32, 0x23, 0xB6, 0x6F, 0xB7, 0x48, 0x95, 0x08, 0xB1, 0x44, 0x4E, + 0x85, 0x8C, 0x3A, 0x02, 0x54, 0x20, 0x2F, 0xDF, 0xBF, 0x57, 0x4F, 0x3B, + 0x3A, 0x90, 0x21, 0xD7, 0xC1, 0x26, 0x35, 0x54, 0x20, 0xEC, 0xC7, 0x3F, + 0x47, 0xEC, 0xEF, 0x5A, 0xBF, 0x4B, 0x7A, 0xC1, 0xAD, 0x3B, 0x17, 0x50, + 0x5C, 0x62, 0xD8, 0x0F, 0x4B, 0x4A, 0xDC, 0x2B, 0xFA, 0x6E, 0xBC, 0x73, + 0x92, 0xCD, 0xEC, 0xC7, 0x50, 0xE8, 0x41, 0x96, 0xD7, 0xA9, 0x7E, 0x6D, + 0xD8, 0xE9, 0x1D, 0x8F, 0x8A, 0xB5, 0xB9, 0x58, 0x92, 0xBA, 0x4A, 0x92, + 0x2B, 0x0C, 0x56, 0xFD, 0x80, 0xEB, 0x08, 0xF0, 0x5E, 0x29, 0x6E, 0x1B, + 0x1C, 0x0C, 0xAF, 0x8F, 0x93, 0x89, 0xAD, 0xDB, 0xBD, 0xA3, 0x9E, 0x21, + 0xCA, 0x89, 0x19, 0xEC, 0xDF, 0xB5, 0xC3, 0x1A, 0xEB, 0x16, 0xFE, 0x78, + 0x36, 0x4C, 0xD6, 0x6E, 0xD0, 0x3E, 0x17, 0x1C, 0x90, 0x17, 0x6B, 0x26, + 0xBA, 0xFB, 0x7A, 0x2F, 0xBF, 0x11, 0x1C, 0x18, 0x0E, 0x2D, 0x73, 0x03, + 0x8F, 0xA0, 0xE5, 0x35, 0xA0, 0x5A, 0xE2, 0x4C, 0x75, 0x1D, 0x71, 0xE1, + 0x39, 0x38, 0x53, 0x78, 0x40, 0xCC, 0x83, 0x93, 0xD7, 0x0A, 0x9E, 0x9D, + 0x5B, 0x8F, 0x8A, 0xE4, 0xE5, 0xE0, 0x48, 0xE4, 0x48, 0xB2, 0x47, 0xCD, + 0x4E, 0x2A, 0x75, 0x2A, 0x7B, 0xF2, 0x22, 0xF6, 0xC9, 0xBE, 0x09, 0x91, + 0x96, 0x57, 0x7A, 0x88, 0x88, 0xAC, 0xEE, 0x70, 0xAC, 0xF9, 0xDC, 0x29, + 0xE3, 0x0C, 0x1C, 0x3B, 0x12, 0x4E, 0x44, 0xD6, 0xA7, 0x4E, 0xB0, 0x26, + 0xC8, 0xF3, 0xD9, 0x1A, 0x97, 0x91, 0x68, 0xEA, 0xEF, 0x8D, 0x46, 0x06, + 0xD2, 0x56, 0x45, 0x58, 0x9A, 0x3C, 0x0C, 0x0F, 0x83, 0xB8, 0x05, 0x25, + 0xC3, 0x39, 0xCF, 0x3B, 0xA4, 0x34, 0x89, 0xB7, 0x79, 0x12, 0x2F, 0x47, + 0xC5, 0xE7, 0xA9, 0x97, 0x69, 0xFC, 0xA6, 0x77, 0x67, 0xB5, 0xDF, 0x7B, + 0xF1, 0x7A, 0x65, 0x15, 0xE4, 0x61, 0x56, 0x65 +}; + +static const unsigned char TA48_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA49_DN[] = { + 0x30, 0x81, 0xD2, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x54, 0x52, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x0F, 0x47, 0x65, 0x62, 0x7A, 0x65, 0x20, 0x2D, 0x20, 0x4B, + 0x6F, 0x63, 0x61, 0x65, 0x6C, 0x69, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x13, 0x39, 0x54, 0x75, 0x72, 0x6B, 0x69, 0x79, 0x65, + 0x20, 0x42, 0x69, 0x6C, 0x69, 0x6D, 0x73, 0x65, 0x6C, 0x20, 0x76, 0x65, + 0x20, 0x54, 0x65, 0x6B, 0x6E, 0x6F, 0x6C, 0x6F, 0x6A, 0x69, 0x6B, 0x20, + 0x41, 0x72, 0x61, 0x73, 0x74, 0x69, 0x72, 0x6D, 0x61, 0x20, 0x4B, 0x75, + 0x72, 0x75, 0x6D, 0x75, 0x20, 0x2D, 0x20, 0x54, 0x55, 0x42, 0x49, 0x54, + 0x41, 0x4B, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x24, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x6B, 0x61, 0x73, 0x79, 0x6F, 0x6E, 0x20, 0x4D, 0x65, 0x72, 0x6B, + 0x65, 0x7A, 0x69, 0x20, 0x2D, 0x20, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, + 0x4D, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, + 0x54, 0x55, 0x42, 0x49, 0x54, 0x41, 0x4B, 0x20, 0x4B, 0x61, 0x6D, 0x75, + 0x20, 0x53, 0x4D, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x4B, 0x6F, 0x6B, 0x20, + 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6B, 0x61, 0x73, 0x69, 0x20, + 0x2D, 0x20, 0x53, 0x75, 0x72, 0x75, 0x6D, 0x20, 0x31 +}; + +static const unsigned char TA49_RSA_N[] = { + 0xAF, 0x75, 0x30, 0x33, 0xAA, 0xBB, 0x6B, 0xD3, 0x99, 0x2C, 0x12, 0x37, + 0x84, 0xD9, 0x8D, 0x7B, 0x97, 0x80, 0xD3, 0x6E, 0xE7, 0xFF, 0x9B, 0x50, + 0x95, 0x3E, 0x90, 0x95, 0x56, 0x42, 0xD7, 0x19, 0x7C, 0x26, 0x84, 0x8D, + 0x92, 0xFA, 0x01, 0x1D, 0x3A, 0x0F, 0xE2, 0x64, 0x38, 0xB7, 0x8C, 0xBC, + 0xE8, 0x88, 0xF9, 0x8B, 0x24, 0xAB, 0x2E, 0xA3, 0xF5, 0x37, 0xE4, 0x40, + 0x8E, 0x18, 0x25, 0x79, 0x83, 0x75, 0x1F, 0x3B, 0xFF, 0x6C, 0xA8, 0xC5, + 0xC6, 0x56, 0xF8, 0xB4, 0xED, 0x8A, 0x44, 0xA3, 0xAB, 0x6C, 0x4C, 0xFC, + 0x1D, 0xD0, 0xDC, 0xEF, 0x68, 0xBD, 0xCF, 0xE4, 0xAA, 0xCE, 0xF0, 0x55, + 0xF7, 0xA2, 0x34, 0xD4, 0x83, 0x6B, 0x37, 0x7C, 0x1C, 0xC2, 0xFE, 0xB5, + 0x03, 0xEC, 0x57, 0xCE, 0xBC, 0xB4, 0xB5, 0xC5, 0xED, 0x00, 0x0F, 0x53, + 0x37, 0x2A, 0x4D, 0xF4, 0x4F, 0x0C, 0x83, 0xFB, 0x86, 0xCF, 0xCB, 0xFE, + 0x8C, 0x4E, 0xBD, 0x87, 0xF9, 0xA7, 0x8B, 0x21, 0x57, 0x9C, 0x7A, 0xDF, + 0x03, 0x67, 0x89, 0x2C, 0x9D, 0x97, 0x61, 0xA7, 0x10, 0xB8, 0x55, 0x90, + 0x7F, 0x0E, 0x2D, 0x27, 0x38, 0x74, 0xDF, 0xE7, 0xFD, 0xDA, 0x4E, 0x12, + 0xE3, 0x4D, 0x15, 0x22, 0x02, 0xC8, 0xE0, 0xE0, 0xFC, 0x0F, 0xAD, 0x8A, + 0xD7, 0xC9, 0x54, 0x50, 0xCC, 0x3B, 0x0F, 0xCA, 0x16, 0x80, 0x84, 0xD0, + 0x51, 0x56, 0xC3, 0x8E, 0x56, 0x7F, 0x89, 0x22, 0x33, 0x2F, 0xE6, 0x85, + 0x0A, 0xBD, 0xA5, 0xA8, 0x1B, 0x36, 0xDE, 0xD3, 0xDC, 0x2C, 0x6D, 0x3B, + 0xC7, 0x13, 0xBD, 0x59, 0x23, 0x2C, 0xE6, 0xE5, 0xA4, 0xF7, 0xD8, 0x0B, + 0xED, 0xEA, 0x90, 0x40, 0x44, 0xA8, 0x95, 0xBB, 0x93, 0xD5, 0xD0, 0x80, + 0x34, 0xB6, 0x46, 0x78, 0x0E, 0x1F, 0x00, 0x93, 0x46, 0xE1, 0xEE, 0xE9, + 0xF9, 0xEC, 0x4F, 0x17 +}; + +static const unsigned char TA49_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA50_DN[] = { + 0x30, 0x81, 0xA6, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x40, 0x30, 0x3E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x37, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, + 0x35 +}; + +static const unsigned char TA50_RSA_N[] = { + 0xC2, 0xF8, 0xA9, 0x3F, 0x1B, 0x89, 0xFC, 0x3C, 0x3C, 0x04, 0x5D, 0x3D, + 0x90, 0x36, 0xB0, 0x91, 0x3A, 0x79, 0x3C, 0x66, 0x5A, 0xEF, 0x6D, 0x39, + 0x01, 0x49, 0x1A, 0xB4, 0xB7, 0xCF, 0x7F, 0x4D, 0x23, 0x53, 0xB7, 0x90, + 0x00, 0xE3, 0x13, 0x2A, 0x28, 0xA6, 0x31, 0xF1, 0x91, 0x00, 0xE3, 0x28, + 0xEC, 0xAE, 0x21, 0x41, 0xCE, 0x1F, 0xDA, 0xFD, 0x7D, 0x12, 0x5B, 0x01, + 0x83, 0x0F, 0xB9, 0xB0, 0x5F, 0x99, 0xE1, 0xF2, 0x12, 0x83, 0x80, 0x4D, + 0x06, 0x3E, 0xDF, 0xAC, 0xAF, 0xE7, 0xA1, 0x88, 0x6B, 0x31, 0xAF, 0xF0, + 0x8B, 0xD0, 0x18, 0x33, 0xB8, 0xDB, 0x45, 0x6A, 0x34, 0xF4, 0x02, 0x80, + 0x24, 0x28, 0x0A, 0x02, 0x15, 0x95, 0x5E, 0x76, 0x2A, 0x0D, 0x99, 0x3A, + 0x14, 0x5B, 0xF6, 0xCB, 0xCB, 0x53, 0xBC, 0x13, 0x4D, 0x01, 0x88, 0x37, + 0x94, 0x25, 0x1B, 0x42, 0xBC, 0x22, 0xD8, 0x8E, 0xA3, 0x96, 0x5E, 0x3A, + 0xD9, 0x32, 0xDB, 0x3E, 0xE8, 0xF0, 0x10, 0x65, 0xED, 0x74, 0xE1, 0x2F, + 0xA7, 0x7C, 0xAF, 0x27, 0x34, 0xBB, 0x29, 0x7D, 0x9B, 0xB6, 0xCF, 0x09, + 0xC8, 0xE5, 0xD3, 0x0A, 0xFC, 0x88, 0x65, 0x65, 0x74, 0x0A, 0xDC, 0x73, + 0x1C, 0x5C, 0xCD, 0x40, 0xB1, 0x1C, 0xD4, 0xB6, 0x84, 0x8C, 0x4C, 0x50, + 0xCF, 0x68, 0x8E, 0xA8, 0x59, 0xAE, 0xC2, 0x27, 0x4E, 0x82, 0xA2, 0x35, + 0xDD, 0x14, 0xF4, 0x1F, 0xFF, 0xB2, 0x77, 0xD5, 0x87, 0x2F, 0xAA, 0x6E, + 0x7D, 0x24, 0x27, 0xE7, 0xC6, 0xCB, 0x26, 0xE6, 0xE5, 0xFE, 0x67, 0x07, + 0x63, 0xD8, 0x45, 0x0D, 0xDD, 0x3A, 0x59, 0x65, 0x39, 0x58, 0x7A, 0x92, + 0x99, 0x72, 0x3D, 0x9C, 0x84, 0x5E, 0x88, 0x21, 0xB8, 0xD5, 0xF4, 0x2C, + 0xFC, 0xD9, 0x70, 0x52, 0x4F, 0x78, 0xB8, 0xBD, 0x3C, 0x2B, 0x8B, 0x95, + 0x98, 0xF5, 0xB3, 0xD1, 0x68, 0xCF, 0x20, 0x14, 0x7E, 0x4C, 0x5C, 0x5F, + 0xE7, 0x8B, 0xE5, 0xF5, 0x35, 0x81, 0x19, 0x37, 0xD7, 0x11, 0x08, 0xB7, + 0x66, 0xBE, 0xD3, 0x4A, 0xCE, 0x83, 0x57, 0x00, 0x3A, 0xC3, 0x81, 0xF8, + 0x17, 0xCB, 0x92, 0x36, 0x5D, 0xD1, 0xA3, 0xD8, 0x75, 0x1B, 0xE1, 0x8B, + 0x27, 0xEA, 0x7A, 0x48, 0x41, 0xFD, 0x45, 0x19, 0x06, 0xAD, 0x27, 0x99, + 0x4E, 0xC1, 0x70, 0x47, 0xDD, 0xB5, 0x9F, 0x81, 0x53, 0x12, 0xE5, 0xB1, + 0x8C, 0x48, 0x5D, 0x31, 0x43, 0x17, 0xE3, 0x8C, 0xC6, 0x7A, 0x63, 0x96, + 0x4B, 0x29, 0x30, 0x4E, 0x84, 0x4E, 0x62, 0x19, 0x5E, 0x3C, 0xCE, 0x97, + 0x90, 0xA5, 0x7F, 0x01, 0xEB, 0x9D, 0xE0, 0xF8, 0x8B, 0x89, 0xDD, 0x25, + 0x98, 0x3D, 0x92, 0xB6, 0x7E, 0xEF, 0xD9, 0xF1, 0x51, 0x51, 0x7D, 0x2D, + 0x26, 0xC8, 0x69, 0x59, 0x61, 0xE0, 0xAC, 0x6A, 0xB8, 0x2A, 0x36, 0x11, + 0x04, 0x7A, 0x50, 0xBD, 0x32, 0x84, 0xBE, 0x2F, 0xDC, 0x72, 0xD5, 0xD7, + 0x1D, 0x16, 0x47, 0xE4, 0x47, 0x66, 0x20, 0x3F, 0xF4, 0x96, 0xC5, 0xAF, + 0x8E, 0x01, 0x7A, 0xA5, 0x0F, 0x7A, 0x64, 0xF5, 0x0D, 0x18, 0x87, 0xD9, + 0xAE, 0x88, 0xD5, 0xFA, 0x84, 0xC1, 0x3A, 0xC0, 0x69, 0x28, 0x2D, 0xF2, + 0x0D, 0x68, 0x51, 0xAA, 0xE3, 0xA5, 0x77, 0xC6, 0xA4, 0x90, 0x0E, 0xA1, + 0x37, 0x8B, 0x31, 0x23, 0x47, 0xC1, 0x09, 0x08, 0xEB, 0x6E, 0xF7, 0x78, + 0x9B, 0xD7, 0x82, 0xFC, 0x84, 0x20, 0x99, 0x49, 0x19, 0xB6, 0x12, 0x46, + 0xB1, 0xFB, 0x45, 0x55, 0x16, 0xA9, 0xA3, 0x65, 0xAC, 0x9C, 0x07, 0x0F, + 0xEA, 0x6B, 0xDC, 0x1F, 0x2E, 0x06, 0x72, 0xEC, 0x86, 0x88, 0x12, 0xE4, + 0x2D, 0xDB, 0x5F, 0x05, 0x2F, 0xE4, 0xF0, 0x03, 0xD3, 0x26, 0x33, 0xE7, + 0x80, 0xC2, 0xCD, 0x42, 0xA1, 0x17, 0x34, 0x0B +}; + +static const unsigned char TA50_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA51_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x52, 0x53, 0x41 +}; + +static const unsigned char TA51_RSA_N[] = { + 0xF9, 0x0F, 0xDD, 0xA3, 0x2B, 0x7D, 0xCB, 0xD0, 0x2A, 0xFE, 0xEC, 0x67, + 0x85, 0xA6, 0xE7, 0x2E, 0x1B, 0xBA, 0x77, 0xE1, 0xE3, 0xF5, 0xAF, 0xA4, + 0xEC, 0xFA, 0x4A, 0x5D, 0x91, 0xC4, 0x57, 0x47, 0x6B, 0x18, 0x77, 0x6B, + 0x76, 0xF2, 0xFD, 0x93, 0xE4, 0x3D, 0x0F, 0xC2, 0x16, 0x9E, 0x0B, 0x66, + 0xC3, 0x56, 0x94, 0x9E, 0x17, 0x83, 0x85, 0xCE, 0x56, 0xEF, 0xF2, 0x16, + 0xFD, 0x00, 0x62, 0xF5, 0x22, 0x09, 0x54, 0xE8, 0x65, 0x17, 0x4E, 0x41, + 0xB9, 0xE0, 0x4F, 0x46, 0x97, 0xAA, 0x1B, 0xC8, 0xB8, 0x6E, 0x62, 0x5E, + 0x69, 0xB1, 0x5F, 0xDB, 0x2A, 0x02, 0x7E, 0xFC, 0x6C, 0xCA, 0xF3, 0x41, + 0xD8, 0xED, 0xD0, 0xE8, 0xFC, 0x3F, 0x61, 0x48, 0xED, 0xB0, 0x03, 0x14, + 0x1D, 0x10, 0x0E, 0x4B, 0x19, 0xE0, 0xBB, 0x4E, 0xEC, 0x86, 0x65, 0xFF, + 0x36, 0xF3, 0x5E, 0x67, 0x02, 0x0B, 0x9D, 0x86, 0x55, 0x61, 0xFD, 0x7A, + 0x38, 0xED, 0xFE, 0xE2, 0x19, 0x00, 0xB7, 0x6F, 0xA1, 0x50, 0x62, 0x75, + 0x74, 0x3C, 0xA0, 0xFA, 0xC8, 0x25, 0x92, 0xB4, 0x6E, 0x7A, 0x22, 0xC7, + 0xF8, 0x1E, 0xA1, 0xE3, 0xB2, 0xDD, 0x91, 0x31, 0xAB, 0x2B, 0x1D, 0x04, + 0xFF, 0xA5, 0x4A, 0x04, 0x37, 0xE9, 0x85, 0xA4, 0x33, 0x2B, 0xFD, 0xE2, + 0xD6, 0x55, 0x34, 0x7C, 0x19, 0xA4, 0x4A, 0x68, 0xC7, 0xB2, 0xA8, 0xD3, + 0xB7, 0xCA, 0xA1, 0x93, 0x88, 0xEB, 0xC1, 0x97, 0xBC, 0x8C, 0xF9, 0x1D, + 0xD9, 0x22, 0x84, 0x24, 0x74, 0xC7, 0x04, 0x3D, 0x6A, 0xA9, 0x29, 0x93, + 0xCC, 0xEB, 0xB8, 0x5B, 0xE1, 0xFE, 0x5F, 0x25, 0xAA, 0x34, 0x58, 0xC8, + 0xC1, 0x23, 0x54, 0x9D, 0x1B, 0x98, 0x11, 0xC3, 0x38, 0x9C, 0x7E, 0x3D, + 0x86, 0x6C, 0xA5, 0x0F, 0x40, 0x86, 0x7C, 0x02, 0xF4, 0x5C, 0x02, 0x4F, + 0x28, 0xCB, 0xAE, 0x71, 0x9F, 0x0F, 0x3A, 0xC8, 0x33, 0xFE, 0x11, 0x25, + 0x35, 0xEA, 0xFC, 0xBA, 0xC5, 0x60, 0x3D, 0xD9, 0x7C, 0x18, 0xD5, 0xB2, + 0xA9, 0xD3, 0x75, 0x78, 0x03, 0x72, 0x22, 0xCA, 0x3A, 0xC3, 0x1F, 0xEF, + 0x2C, 0xE5, 0x2E, 0xA9, 0xFA, 0x9E, 0x2C, 0xB6, 0x51, 0x46, 0xFD, 0xAF, + 0x03, 0xD6, 0xEA, 0x60, 0x68, 0xEA, 0x85, 0x16, 0x36, 0x6B, 0x85, 0xE9, + 0x1E, 0xC0, 0xB3, 0xDD, 0xC4, 0x24, 0xDC, 0x80, 0x2A, 0x81, 0x41, 0x6D, + 0x94, 0x3E, 0xC8, 0xE0, 0xC9, 0x81, 0x41, 0x00, 0x9E, 0x5E, 0xBF, 0x7F, + 0xC5, 0x08, 0x98, 0xA2, 0x18, 0x2C, 0x42, 0x40, 0xB3, 0xF9, 0x6F, 0x38, + 0x27, 0x4B, 0x4E, 0x80, 0xF4, 0x3D, 0x81, 0x47, 0xE0, 0x88, 0x7C, 0xEA, + 0x1C, 0xCE, 0xB5, 0x75, 0x5C, 0x51, 0x2E, 0x1C, 0x2B, 0x7F, 0x1A, 0x72, + 0x28, 0xE7, 0x00, 0xB5, 0xD1, 0x74, 0xC6, 0xD7, 0xE4, 0x9F, 0xAD, 0x07, + 0x93, 0xB6, 0x53, 0x35, 0x35, 0xFC, 0x37, 0xE4, 0xC3, 0xF6, 0x5D, 0x16, + 0xBE, 0x21, 0x73, 0xDE, 0x92, 0x0A, 0xF8, 0xA0, 0x63, 0x6A, 0xBC, 0x96, + 0x92, 0x6A, 0x3E, 0xF8, 0xBC, 0x65, 0x55, 0x9B, 0xDE, 0xF5, 0x0D, 0x89, + 0x26, 0x04, 0xFC, 0x25, 0x1A, 0xA6, 0x25, 0x69, 0xCB, 0xC2, 0x6D, 0xCA, + 0x7C, 0xE2, 0x59, 0x5F, 0x97, 0xAC, 0xEB, 0xEF, 0x2E, 0xC8, 0xBC, 0xD7, + 0x1B, 0x59, 0x3C, 0x2B, 0xCC, 0xF2, 0x19, 0xC8, 0x93, 0x6B, 0x27, 0x63, + 0x19, 0xCF, 0xFC, 0xE9, 0x26, 0xF8, 0xCA, 0x71, 0x9B, 0x7F, 0x93, 0xFE, + 0x34, 0x67, 0x84, 0x4E, 0x99, 0xEB, 0xFC, 0xB3, 0x78, 0x09, 0x33, 0x70, + 0xBA, 0x66, 0xA6, 0x76, 0xED, 0x1B, 0x73, 0xEB, 0x1A, 0xA5, 0x0D, 0xC4, + 0x22, 0x13, 0x20, 0x94, 0x56, 0x0A, 0x4E, 0x2C, 0x6C, 0x4E, 0xB1, 0xFD, + 0xCF, 0x9C, 0x09, 0xBA, 0xA2, 0x33, 0xED, 0x87 +}; + +static const unsigned char TA51_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA52_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA52_EC_Q[] = { + 0x04, 0x78, 0x30, 0x81, 0xE8, 0x63, 0x1E, 0xE5, 0xEB, 0x71, 0x51, 0x0F, + 0xF7, 0x07, 0x07, 0xCA, 0x39, 0x99, 0x7C, 0x4E, 0xD5, 0x0F, 0xCC, 0x30, + 0x30, 0x0B, 0x8F, 0x66, 0x93, 0x3E, 0xCF, 0xBD, 0xC5, 0x86, 0xBD, 0xF9, + 0xB1, 0xB7, 0xB4, 0x3E, 0xB4, 0x07, 0xC8, 0xF3, 0x96, 0x31, 0xF3, 0xED, + 0xA4, 0x4F, 0xF8, 0xA3, 0x4E, 0x8D, 0x29, 0x15, 0x58, 0xB8, 0xD5, 0x6F, + 0x7F, 0xEE, 0x6C, 0x22, 0xB5, 0xB0, 0xAF, 0x48, 0x45, 0x0A, 0xBD, 0xA8, + 0x49, 0x94, 0xBF, 0x84, 0x43, 0xB0, 0xDB, 0x84, 0x4A, 0x03, 0x23, 0x19, + 0x67, 0x6A, 0x6F, 0xC1, 0x6E, 0xBC, 0x06, 0x39, 0x37, 0xD1, 0x88, 0x22, + 0xF7 +}; + +static const unsigned char TA53_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA53_RSA_N[] = { + 0x80, 0x12, 0x65, 0x17, 0x36, 0x0E, 0xC3, 0xDB, 0x08, 0xB3, 0xD0, 0xAC, + 0x57, 0x0D, 0x76, 0xED, 0xCD, 0x27, 0xD3, 0x4C, 0xAD, 0x50, 0x83, 0x61, + 0xE2, 0xAA, 0x20, 0x4D, 0x09, 0x2D, 0x64, 0x09, 0xDC, 0xCE, 0x89, 0x9F, + 0xCC, 0x3D, 0xA9, 0xEC, 0xF6, 0xCF, 0xC1, 0xDC, 0xF1, 0xD3, 0xB1, 0xD6, + 0x7B, 0x37, 0x28, 0x11, 0x2B, 0x47, 0xDA, 0x39, 0xC6, 0xBC, 0x3A, 0x19, + 0xB4, 0x5F, 0xA6, 0xBD, 0x7D, 0x9D, 0xA3, 0x63, 0x42, 0xB6, 0x76, 0xF2, + 0xA9, 0x3B, 0x2B, 0x91, 0xF8, 0xE2, 0x6F, 0xD0, 0xEC, 0x16, 0x20, 0x90, + 0x09, 0x3E, 0xE2, 0xE8, 0x74, 0xC9, 0x18, 0xB4, 0x91, 0xD4, 0x62, 0x64, + 0xDB, 0x7F, 0xA3, 0x06, 0xF1, 0x88, 0x18, 0x6A, 0x90, 0x22, 0x3C, 0xBC, + 0xFE, 0x13, 0xF0, 0x87, 0x14, 0x7B, 0xF6, 0xE4, 0x1F, 0x8E, 0xD4, 0xE4, + 0x51, 0xC6, 0x11, 0x67, 0x46, 0x08, 0x51, 0xCB, 0x86, 0x14, 0x54, 0x3F, + 0xBC, 0x33, 0xFE, 0x7E, 0x6C, 0x9C, 0xFF, 0x16, 0x9D, 0x18, 0xBD, 0x51, + 0x8E, 0x35, 0xA6, 0xA7, 0x66, 0xC8, 0x72, 0x67, 0xDB, 0x21, 0x66, 0xB1, + 0xD4, 0x9B, 0x78, 0x03, 0xC0, 0x50, 0x3A, 0xE8, 0xCC, 0xF0, 0xDC, 0xBC, + 0x9E, 0x4C, 0xFE, 0xAF, 0x05, 0x96, 0x35, 0x1F, 0x57, 0x5A, 0xB7, 0xFF, + 0xCE, 0xF9, 0x3D, 0xB7, 0x2C, 0xB6, 0xF6, 0x54, 0xDD, 0xC8, 0xE7, 0x12, + 0x3A, 0x4D, 0xAE, 0x4C, 0x8A, 0xB7, 0x5C, 0x9A, 0xB4, 0xB7, 0x20, 0x3D, + 0xCA, 0x7F, 0x22, 0x34, 0xAE, 0x7E, 0x3B, 0x68, 0x66, 0x01, 0x44, 0xE7, + 0x01, 0x4E, 0x46, 0x53, 0x9B, 0x33, 0x60, 0xF7, 0x94, 0xBE, 0x53, 0x37, + 0x90, 0x73, 0x43, 0xF3, 0x32, 0xC3, 0x53, 0xEF, 0xDB, 0xAA, 0xFE, 0x74, + 0x4E, 0x69, 0xC7, 0x6B, 0x8C, 0x60, 0x93, 0xDE, 0xC4, 0xC7, 0x0C, 0xDF, + 0xE1, 0x32, 0xAE, 0xCC, 0x93, 0x3B, 0x51, 0x78, 0x95, 0x67, 0x8B, 0xEE, + 0x3D, 0x56, 0xFE, 0x0C, 0xD0, 0x69, 0x0F, 0x1B, 0x0F, 0xF3, 0x25, 0x26, + 0x6B, 0x33, 0x6D, 0xF7, 0x6E, 0x47, 0xFA, 0x73, 0x43, 0xE5, 0x7E, 0x0E, + 0xA5, 0x66, 0xB1, 0x29, 0x7C, 0x32, 0x84, 0x63, 0x55, 0x89, 0xC4, 0x0D, + 0xC1, 0x93, 0x54, 0x30, 0x19, 0x13, 0xAC, 0xD3, 0x7D, 0x37, 0xA7, 0xEB, + 0x5D, 0x3A, 0x6C, 0x35, 0x5C, 0xDB, 0x41, 0xD7, 0x12, 0xDA, 0xA9, 0x49, + 0x0B, 0xDF, 0xD8, 0x80, 0x8A, 0x09, 0x93, 0x62, 0x8E, 0xB5, 0x66, 0xCF, + 0x25, 0x88, 0xCD, 0x84, 0xB8, 0xB1, 0x3F, 0xA4, 0x39, 0x0F, 0xD9, 0x02, + 0x9E, 0xEB, 0x12, 0x4C, 0x95, 0x7C, 0xF3, 0x6B, 0x05, 0xA9, 0x5E, 0x16, + 0x83, 0xCC, 0xB8, 0x67, 0xE2, 0xE8, 0x13, 0x9D, 0xCC, 0x5B, 0x82, 0xD3, + 0x4C, 0xB3, 0xED, 0x5B, 0xFF, 0xDE, 0xE5, 0x73, 0xAC, 0x23, 0x3B, 0x2D, + 0x00, 0xBF, 0x35, 0x55, 0x74, 0x09, 0x49, 0xD8, 0x49, 0x58, 0x1A, 0x7F, + 0x92, 0x36, 0xE6, 0x51, 0x92, 0x0E, 0xF3, 0x26, 0x7D, 0x1C, 0x4D, 0x17, + 0xBC, 0xC9, 0xEC, 0x43, 0x26, 0xD0, 0xBF, 0x41, 0x5F, 0x40, 0xA9, 0x44, + 0x44, 0xF4, 0x99, 0xE7, 0x57, 0x87, 0x9E, 0x50, 0x1F, 0x57, 0x54, 0xA8, + 0x3E, 0xFD, 0x74, 0x63, 0x2F, 0xB1, 0x50, 0x65, 0x09, 0xE6, 0x58, 0x42, + 0x2E, 0x43, 0x1A, 0x4C, 0xB4, 0xF0, 0x25, 0x47, 0x59, 0xFA, 0x04, 0x1E, + 0x93, 0xD4, 0x26, 0x46, 0x4A, 0x50, 0x81, 0xB2, 0xDE, 0xBE, 0x78, 0xB7, + 0xFC, 0x67, 0x15, 0xE1, 0xC9, 0x57, 0x84, 0x1E, 0x0F, 0x63, 0xD6, 0xE9, + 0x62, 0xBA, 0xD6, 0x5F, 0x55, 0x2E, 0xEA, 0x5C, 0xC6, 0x28, 0x08, 0x04, + 0x25, 0x39, 0xB8, 0x0E, 0x2B, 0xA9, 0xF2, 0x4C, 0x97, 0x1C, 0x07, 0x3F, + 0x0D, 0x52, 0xF5, 0xED, 0xEF, 0x2F, 0x82, 0x0F +}; + +static const unsigned char TA53_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA54_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA54_RSA_N[] = { + 0xE2, 0x3B, 0xE1, 0x11, 0x72, 0xDE, 0xA8, 0xA4, 0xD3, 0xA3, 0x57, 0xAA, + 0x50, 0xA2, 0x8F, 0x0B, 0x77, 0x90, 0xC9, 0xA2, 0xA5, 0xEE, 0x12, 0xCE, + 0x96, 0x5B, 0x01, 0x09, 0x20, 0xCC, 0x01, 0x93, 0xA7, 0x4E, 0x30, 0xB7, + 0x53, 0xF7, 0x43, 0xC4, 0x69, 0x00, 0x57, 0x9D, 0xE2, 0x8D, 0x22, 0xDD, + 0x87, 0x06, 0x40, 0x00, 0x81, 0x09, 0xCE, 0xCE, 0x1B, 0x83, 0xBF, 0xDF, + 0xCD, 0x3B, 0x71, 0x46, 0xE2, 0xD6, 0x66, 0xC7, 0x05, 0xB3, 0x76, 0x27, + 0x16, 0x8F, 0x7B, 0x9E, 0x1E, 0x95, 0x7D, 0xEE, 0xB7, 0x48, 0xA3, 0x08, + 0xDA, 0xD6, 0xAF, 0x7A, 0x0C, 0x39, 0x06, 0x65, 0x7F, 0x4A, 0x5D, 0x1F, + 0xBC, 0x17, 0xF8, 0xAB, 0xBE, 0xEE, 0x28, 0xD7, 0x74, 0x7F, 0x7A, 0x78, + 0x99, 0x59, 0x85, 0x68, 0x6E, 0x5C, 0x23, 0x32, 0x4B, 0xBF, 0x4E, 0xC0, + 0xE8, 0x5A, 0x6D, 0xE3, 0x70, 0xBF, 0x77, 0x10, 0xBF, 0xFC, 0x01, 0xF6, + 0x85, 0xD9, 0xA8, 0x44, 0x10, 0x58, 0x32, 0xA9, 0x75, 0x18, 0xD5, 0xD1, + 0xA2, 0xBE, 0x47, 0xE2, 0x27, 0x6A, 0xF4, 0x9A, 0x33, 0xF8, 0x49, 0x08, + 0x60, 0x8B, 0xD4, 0x5F, 0xB4, 0x3A, 0x84, 0xBF, 0xA1, 0xAA, 0x4A, 0x4C, + 0x7D, 0x3E, 0xCF, 0x4F, 0x5F, 0x6C, 0x76, 0x5E, 0xA0, 0x4B, 0x37, 0x91, + 0x9E, 0xDC, 0x22, 0xE6, 0x6D, 0xCE, 0x14, 0x1A, 0x8E, 0x6A, 0xCB, 0xFE, + 0xCD, 0xB3, 0x14, 0x64, 0x17, 0xC7, 0x5B, 0x29, 0x9E, 0x32, 0xBF, 0xF2, + 0xEE, 0xFA, 0xD3, 0x0B, 0x42, 0xD4, 0xAB, 0xB7, 0x41, 0x32, 0xDA, 0x0C, + 0xD4, 0xEF, 0xF8, 0x81, 0xD5, 0xBB, 0x8D, 0x58, 0x3F, 0xB5, 0x1B, 0xE8, + 0x49, 0x28, 0xA2, 0x70, 0xDA, 0x31, 0x04, 0xDD, 0xF7, 0xB2, 0x16, 0xF2, + 0x4C, 0x0A, 0x4E, 0x07, 0xA8, 0xED, 0x4A, 0x3D, 0x5E, 0xB5, 0x7F, 0xA3, + 0x90, 0xC3, 0xAF, 0x27 +}; + +static const unsigned char TA54_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA55_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA55_RSA_N[] = { + 0xE2, 0x3B, 0xE1, 0x11, 0x72, 0xDE, 0xA8, 0xA4, 0xD3, 0xA3, 0x57, 0xAA, + 0x50, 0xA2, 0x8F, 0x0B, 0x77, 0x90, 0xC9, 0xA2, 0xA5, 0xEE, 0x12, 0xCE, + 0x96, 0x5B, 0x01, 0x09, 0x20, 0xCC, 0x01, 0x93, 0xA7, 0x4E, 0x30, 0xB7, + 0x53, 0xF7, 0x43, 0xC4, 0x69, 0x00, 0x57, 0x9D, 0xE2, 0x8D, 0x22, 0xDD, + 0x87, 0x06, 0x40, 0x00, 0x81, 0x09, 0xCE, 0xCE, 0x1B, 0x83, 0xBF, 0xDF, + 0xCD, 0x3B, 0x71, 0x46, 0xE2, 0xD6, 0x66, 0xC7, 0x05, 0xB3, 0x76, 0x27, + 0x16, 0x8F, 0x7B, 0x9E, 0x1E, 0x95, 0x7D, 0xEE, 0xB7, 0x48, 0xA3, 0x08, + 0xDA, 0xD6, 0xAF, 0x7A, 0x0C, 0x39, 0x06, 0x65, 0x7F, 0x4A, 0x5D, 0x1F, + 0xBC, 0x17, 0xF8, 0xAB, 0xBE, 0xEE, 0x28, 0xD7, 0x74, 0x7F, 0x7A, 0x78, + 0x99, 0x59, 0x85, 0x68, 0x6E, 0x5C, 0x23, 0x32, 0x4B, 0xBF, 0x4E, 0xC0, + 0xE8, 0x5A, 0x6D, 0xE3, 0x70, 0xBF, 0x77, 0x10, 0xBF, 0xFC, 0x01, 0xF6, + 0x85, 0xD9, 0xA8, 0x44, 0x10, 0x58, 0x32, 0xA9, 0x75, 0x18, 0xD5, 0xD1, + 0xA2, 0xBE, 0x47, 0xE2, 0x27, 0x6A, 0xF4, 0x9A, 0x33, 0xF8, 0x49, 0x08, + 0x60, 0x8B, 0xD4, 0x5F, 0xB4, 0x3A, 0x84, 0xBF, 0xA1, 0xAA, 0x4A, 0x4C, + 0x7D, 0x3E, 0xCF, 0x4F, 0x5F, 0x6C, 0x76, 0x5E, 0xA0, 0x4B, 0x37, 0x91, + 0x9E, 0xDC, 0x22, 0xE6, 0x6D, 0xCE, 0x14, 0x1A, 0x8E, 0x6A, 0xCB, 0xFE, + 0xCD, 0xB3, 0x14, 0x64, 0x17, 0xC7, 0x5B, 0x29, 0x9E, 0x32, 0xBF, 0xF2, + 0xEE, 0xFA, 0xD3, 0x0B, 0x42, 0xD4, 0xAB, 0xB7, 0x41, 0x32, 0xDA, 0x0C, + 0xD4, 0xEF, 0xF8, 0x81, 0xD5, 0xBB, 0x8D, 0x58, 0x3F, 0xB5, 0x1B, 0xE8, + 0x49, 0x28, 0xA2, 0x70, 0xDA, 0x31, 0x04, 0xDD, 0xF7, 0xB2, 0x16, 0xF2, + 0x4C, 0x0A, 0x4E, 0x07, 0xA8, 0xED, 0x4A, 0x3D, 0x5E, 0xB5, 0x7F, 0xA3, + 0x90, 0xC3, 0xAF, 0x27 +}; + +static const unsigned char TA55_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA56_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x42, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x6F, 0x72, 0x65, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, 0x43, 0x79, + 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6C, 0x74, 0x69, + 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA56_RSA_N[] = { + 0xA3, 0x04, 0xBB, 0x22, 0xAB, 0x98, 0x3D, 0x57, 0xE8, 0x26, 0x72, 0x9A, + 0xB5, 0x79, 0xD4, 0x29, 0xE2, 0xE1, 0xE8, 0x95, 0x80, 0xB1, 0xB0, 0xE3, + 0x5B, 0x8E, 0x2B, 0x29, 0x9A, 0x64, 0xDF, 0xA1, 0x5D, 0xED, 0xB0, 0x09, + 0x05, 0x6D, 0xDB, 0x28, 0x2E, 0xCE, 0x62, 0xA2, 0x62, 0xFE, 0xB4, 0x88, + 0xDA, 0x12, 0xEB, 0x38, 0xEB, 0x21, 0x9D, 0xC0, 0x41, 0x2B, 0x01, 0x52, + 0x7B, 0x88, 0x77, 0xD3, 0x1C, 0x8F, 0xC7, 0xBA, 0xB9, 0x88, 0xB5, 0x6A, + 0x09, 0xE7, 0x73, 0xE8, 0x11, 0x40, 0xA7, 0xD1, 0xCC, 0xCA, 0x62, 0x8D, + 0x2D, 0xE5, 0x8F, 0x0B, 0xA6, 0x50, 0xD2, 0xA8, 0x50, 0xC3, 0x28, 0xEA, + 0xF5, 0xAB, 0x25, 0x87, 0x8A, 0x9A, 0x96, 0x1C, 0xA9, 0x67, 0xB8, 0x3F, + 0x0C, 0xD5, 0xF7, 0xF9, 0x52, 0x13, 0x2F, 0xC2, 0x1B, 0xD5, 0x70, 0x70, + 0xF0, 0x8F, 0xC0, 0x12, 0xCA, 0x06, 0xCB, 0x9A, 0xE1, 0xD9, 0xCA, 0x33, + 0x7A, 0x77, 0xD6, 0xF8, 0xEC, 0xB9, 0xF1, 0x68, 0x44, 0x42, 0x48, 0x13, + 0xD2, 0xC0, 0xC2, 0xA4, 0xAE, 0x5E, 0x60, 0xFE, 0xB6, 0xA6, 0x05, 0xFC, + 0xB4, 0xDD, 0x07, 0x59, 0x02, 0xD4, 0x59, 0x18, 0x98, 0x63, 0xF5, 0xA5, + 0x63, 0xE0, 0x90, 0x0C, 0x7D, 0x5D, 0xB2, 0x06, 0x7A, 0xF3, 0x85, 0xEA, + 0xEB, 0xD4, 0x03, 0xAE, 0x5E, 0x84, 0x3E, 0x5F, 0xFF, 0x15, 0xED, 0x69, + 0xBC, 0xF9, 0x39, 0x36, 0x72, 0x75, 0xCF, 0x77, 0x52, 0x4D, 0xF3, 0xC9, + 0x90, 0x2C, 0xB9, 0x3D, 0xE5, 0xC9, 0x23, 0x53, 0x3F, 0x1F, 0x24, 0x98, + 0x21, 0x5C, 0x07, 0x99, 0x29, 0xBD, 0xC6, 0x3A, 0xEC, 0xE7, 0x6E, 0x86, + 0x3A, 0x6B, 0x97, 0x74, 0x63, 0x33, 0xBD, 0x68, 0x18, 0x31, 0xF0, 0x78, + 0x8D, 0x76, 0xBF, 0xFC, 0x9E, 0x8E, 0x5D, 0x2A, 0x86, 0xA7, 0x4D, 0x90, + 0xDC, 0x27, 0x1A, 0x39 +}; + +static const unsigned char TA56_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA57_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, + 0x36 +}; + +static const unsigned char TA57_EC_Q[] = { + 0x04, 0x76, 0xFA, 0x99, 0xA9, 0x6E, 0x20, 0xED, 0xF9, 0xD7, 0x77, 0xE3, + 0x07, 0x3B, 0xA8, 0xDB, 0x3D, 0x5F, 0x38, 0xE8, 0xAB, 0x55, 0xA6, 0x56, + 0x4F, 0xD6, 0x48, 0xEA, 0xEC, 0x7F, 0x2D, 0xAA, 0xC3, 0xB2, 0xC5, 0x79, + 0xEC, 0x99, 0x61, 0x7F, 0x10, 0x79, 0xC7, 0x02, 0x5A, 0xF9, 0x04, 0x37, + 0xF5, 0x34, 0x35, 0x2B, 0x77, 0xCE, 0x7F, 0x20, 0x8F, 0x52, 0xA3, 0x00, + 0x89, 0xEC, 0xD5, 0xA7, 0xA2, 0x6D, 0x5B, 0xE3, 0x4B, 0x92, 0x93, 0xA0, + 0x80, 0xF5, 0x01, 0x94, 0xDC, 0xF0, 0x68, 0x07, 0x1E, 0xCD, 0xEE, 0xFE, + 0x25, 0x52, 0xB5, 0x20, 0x43, 0x1C, 0x1B, 0xFE, 0xEB, 0x19, 0xCE, 0x43, + 0xA3 +}; + +static const unsigned char TA58_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x39, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, 0x20, + 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x63, 0x69, 0x6F, 0x6E, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, + 0x6F, 0x66, 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x43, 0x49, + 0x46, 0x20, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38 +}; + +static const unsigned char TA58_RSA_N[] = { + 0xCA, 0x96, 0x6B, 0x8E, 0xEA, 0xF8, 0xFB, 0xF1, 0xA2, 0x35, 0xE0, 0x7F, + 0x4C, 0xDA, 0xE0, 0xC3, 0x52, 0xD7, 0x7D, 0xB6, 0x10, 0xC8, 0x02, 0x5E, + 0xB3, 0x43, 0x2A, 0xC4, 0x4F, 0x6A, 0xB2, 0xCA, 0x1C, 0x5D, 0x28, 0x9A, + 0x78, 0x11, 0x1A, 0x69, 0x59, 0x57, 0xAF, 0xB5, 0x20, 0x42, 0xE4, 0x8B, + 0x0F, 0xE6, 0xDF, 0x5B, 0xA6, 0x03, 0x92, 0x2F, 0xF5, 0x11, 0xE4, 0x62, + 0xD7, 0x32, 0x71, 0x38, 0xD9, 0x04, 0x0C, 0x71, 0xAB, 0x3D, 0x51, 0x7E, + 0x0F, 0x07, 0xDF, 0x63, 0x05, 0x5C, 0xE9, 0xBF, 0x94, 0x6F, 0xC1, 0x29, + 0x82, 0xC0, 0xB4, 0xDA, 0x51, 0xB0, 0xC1, 0x3C, 0xBB, 0xAD, 0x37, 0x4A, + 0x5C, 0xCA, 0xF1, 0x4B, 0x36, 0x0E, 0x24, 0xAB, 0xBF, 0xC3, 0x84, 0x77, + 0xFD, 0xA8, 0x50, 0xF4, 0xB1, 0xE7, 0xC6, 0x2F, 0xD2, 0x2D, 0x59, 0x8D, + 0x7A, 0x0A, 0x4E, 0x96, 0x69, 0x52, 0x02, 0xAA, 0x36, 0x98, 0xEC, 0xFC, + 0xFA, 0x14, 0x83, 0x0C, 0x37, 0x1F, 0xC9, 0x92, 0x37, 0x7F, 0xD7, 0x81, + 0x2D, 0xE5, 0xC4, 0xB9, 0xE0, 0x3E, 0x34, 0xFE, 0x67, 0xF4, 0x3E, 0x66, + 0xD1, 0xD3, 0xF4, 0x40, 0xCF, 0x5E, 0x62, 0x34, 0x0F, 0x70, 0x06, 0x3E, + 0x20, 0x18, 0x5A, 0xCE, 0xF7, 0x72, 0x1B, 0x25, 0x6C, 0x93, 0x74, 0x14, + 0x93, 0xA3, 0x73, 0xB1, 0x0E, 0xAA, 0x87, 0x10, 0x23, 0x59, 0x5F, 0x20, + 0x05, 0x19, 0x47, 0xED, 0x68, 0x8E, 0x92, 0x12, 0xCA, 0x5D, 0xFC, 0xD6, + 0x2B, 0xB2, 0x92, 0x3C, 0x20, 0xCF, 0xE1, 0x5F, 0xAF, 0x20, 0xBE, 0xA0, + 0x76, 0x7F, 0x76, 0xE5, 0xEC, 0x1A, 0x86, 0x61, 0x33, 0x3E, 0xE7, 0x7B, + 0xB4, 0x3F, 0xA0, 0x0F, 0x8E, 0xA2, 0xB9, 0x6A, 0x6F, 0xB9, 0x87, 0x26, + 0x6F, 0x41, 0x6C, 0x88, 0xA6, 0x50, 0xFD, 0x6A, 0x63, 0x0B, 0xF5, 0x93, + 0x16, 0x1B, 0x19, 0x8F, 0xB2, 0xED, 0x9B, 0x9B, 0xC9, 0x90, 0xF5, 0x01, + 0x0C, 0xDF, 0x19, 0x3D, 0x0F, 0x3E, 0x38, 0x23, 0xC9, 0x2F, 0x8F, 0x0C, + 0xD1, 0x02, 0xFE, 0x1B, 0x55, 0xD6, 0x4E, 0xD0, 0x8D, 0x3C, 0xAF, 0x4F, + 0xA4, 0xF3, 0xFE, 0xAF, 0x2A, 0xD3, 0x05, 0x9D, 0x79, 0x08, 0xA1, 0xCB, + 0x57, 0x31, 0xB4, 0x9C, 0xC8, 0x90, 0xB2, 0x67, 0xF4, 0x18, 0x16, 0x93, + 0x3A, 0xFC, 0x47, 0xD8, 0xD1, 0x78, 0x96, 0x31, 0x1F, 0xBA, 0x2B, 0x0C, + 0x5F, 0x5D, 0x99, 0xAD, 0x63, 0x89, 0x5A, 0x24, 0x20, 0x76, 0xD8, 0xDF, + 0xFD, 0xAB, 0x4E, 0xA6, 0x22, 0xAA, 0x9D, 0x5E, 0xE6, 0x27, 0x8A, 0x7D, + 0x68, 0x29, 0xA3, 0xE7, 0x8A, 0xB8, 0xDA, 0x11, 0xBB, 0x17, 0x2D, 0x99, + 0x9D, 0x13, 0x24, 0x46, 0xF7, 0xC5, 0xE2, 0xD8, 0x9F, 0x8E, 0x7F, 0xC7, + 0x8F, 0x74, 0x6D, 0x5A, 0xB2, 0xE8, 0x72, 0xF5, 0xAC, 0xEE, 0x24, 0x10, + 0xAD, 0x2F, 0x14, 0xDA, 0xFF, 0x2D, 0x9A, 0x46, 0x71, 0x47, 0xBE, 0x42, + 0xDF, 0xBB, 0x01, 0xDB, 0xF4, 0x7F, 0xD3, 0x28, 0x8F, 0x31, 0x59, 0x5B, + 0xD3, 0xC9, 0x02, 0xA6, 0xB4, 0x52, 0xCA, 0x6E, 0x97, 0xFB, 0x43, 0xC5, + 0x08, 0x26, 0x6F, 0x8A, 0xF4, 0xBB, 0xFD, 0x9F, 0x28, 0xAA, 0x0D, 0xD5, + 0x45, 0xF3, 0x13, 0x3A, 0x1D, 0xD8, 0xC0, 0x78, 0x8F, 0x41, 0x67, 0x3C, + 0x1E, 0x94, 0x64, 0xAE, 0x7B, 0x0B, 0xC5, 0xE8, 0xD9, 0x01, 0x88, 0x39, + 0x1A, 0x97, 0x86, 0x64, 0x41, 0xD5, 0x3B, 0x87, 0x0C, 0x6E, 0xFA, 0x0F, + 0xC6, 0xBD, 0x48, 0x14, 0xBF, 0x39, 0x4D, 0xD4, 0x9E, 0x41, 0xB6, 0x8F, + 0x96, 0x1D, 0x63, 0x96, 0x93, 0xD9, 0x95, 0x06, 0x78, 0x31, 0x68, 0x9E, + 0x37, 0x06, 0x3B, 0x80, 0x89, 0x45, 0x61, 0x39, 0x23, 0xC7, 0x1B, 0x44, + 0xA3, 0x15, 0xE5, 0x1C, 0xF8, 0x92, 0x30, 0xBB +}; + +static const unsigned char TA58_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA59_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x41, 0x47, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x16, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, + 0x6F, 0x6C, 0x64, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA59_RSA_N[] = { + 0xAF, 0xE4, 0xEE, 0x7E, 0x8B, 0x24, 0x0E, 0x12, 0x6E, 0xA9, 0x50, 0x2D, + 0x16, 0x44, 0x3B, 0x92, 0x92, 0x5C, 0xCA, 0xB8, 0x5D, 0x84, 0x92, 0x42, + 0x13, 0x2A, 0xBC, 0x65, 0x57, 0x82, 0x40, 0x3E, 0x57, 0x24, 0xCD, 0x50, + 0x8B, 0x25, 0x2A, 0xB7, 0x6F, 0xFC, 0xEF, 0xA2, 0xD0, 0xC0, 0x1F, 0x02, + 0x24, 0x4A, 0x13, 0x96, 0x8F, 0x23, 0x13, 0xE6, 0x28, 0x58, 0x00, 0xA3, + 0x47, 0xC7, 0x06, 0xA7, 0x84, 0x23, 0x2B, 0xBB, 0xBD, 0x96, 0x2B, 0x7F, + 0x55, 0xCC, 0x8B, 0xC1, 0x57, 0x1F, 0x0E, 0x62, 0x65, 0x0F, 0xDD, 0x3D, + 0x56, 0x8A, 0x73, 0xDA, 0xAE, 0x7E, 0x6D, 0xBA, 0x81, 0x1C, 0x7E, 0x42, + 0x8C, 0x20, 0x35, 0xD9, 0x43, 0x4D, 0x84, 0xFA, 0x84, 0xDB, 0x52, 0x2C, + 0xF3, 0x0E, 0x27, 0x77, 0x0B, 0x6B, 0xBF, 0x11, 0x2F, 0x72, 0x78, 0x9F, + 0x2E, 0xD8, 0x3E, 0xE6, 0x18, 0x37, 0x5A, 0x2A, 0x72, 0xF9, 0xDA, 0x62, + 0x90, 0x92, 0x95, 0xCA, 0x1F, 0x9C, 0xE9, 0xB3, 0x3C, 0x2B, 0xCB, 0xF3, + 0x01, 0x13, 0xBF, 0x5A, 0xCF, 0xC1, 0xB5, 0x0A, 0x60, 0xBD, 0xDD, 0xB5, + 0x99, 0x64, 0x53, 0xB8, 0xA0, 0x96, 0xB3, 0x6F, 0xE2, 0x26, 0x77, 0x91, + 0x8C, 0xE0, 0x62, 0x10, 0x02, 0x9F, 0x34, 0x0F, 0xA4, 0xD5, 0x92, 0x33, + 0x51, 0xDE, 0xBE, 0x8D, 0xBA, 0x84, 0x7A, 0x60, 0x3C, 0x6A, 0xDB, 0x9F, + 0x2B, 0xEC, 0xDE, 0xDE, 0x01, 0x3F, 0x6E, 0x4D, 0xE5, 0x50, 0x86, 0xCB, + 0xB4, 0xAF, 0xED, 0x44, 0x40, 0xC5, 0xCA, 0x5A, 0x8C, 0xDA, 0xD2, 0x2B, + 0x7C, 0xA8, 0xEE, 0xBE, 0xA6, 0xE5, 0x0A, 0xAA, 0x0E, 0xA5, 0xDF, 0x05, + 0x52, 0xB7, 0x55, 0xC7, 0x22, 0x5D, 0x32, 0x6A, 0x97, 0x97, 0x63, 0x13, + 0xDB, 0xC9, 0xDB, 0x79, 0x36, 0x7B, 0x85, 0x3A, 0x4A, 0xC5, 0x52, 0x89, + 0xF9, 0x24, 0xE7, 0x9D, 0x77, 0xA9, 0x82, 0xFF, 0x55, 0x1C, 0xA5, 0x71, + 0x69, 0x2B, 0xD1, 0x02, 0x24, 0xF2, 0xB3, 0x26, 0xD4, 0x6B, 0xDA, 0x04, + 0x55, 0xE5, 0xC1, 0x0A, 0xC7, 0x6D, 0x30, 0x37, 0x90, 0x2A, 0xE4, 0x9E, + 0x14, 0x33, 0x5E, 0x16, 0x17, 0x55, 0xC5, 0x5B, 0xB5, 0xCB, 0x34, 0x89, + 0x92, 0xF1, 0x9D, 0x26, 0x8F, 0xA1, 0x07, 0xD4, 0xC6, 0xB2, 0x78, 0x50, + 0xDB, 0x0C, 0x0C, 0x0B, 0x7C, 0x0B, 0x8C, 0x41, 0xD7, 0xB9, 0xE9, 0xDD, + 0x8C, 0x88, 0xF7, 0xA3, 0x4D, 0xB2, 0x32, 0xCC, 0xD8, 0x17, 0xDA, 0xCD, + 0xB7, 0xCE, 0x66, 0x9D, 0xD4, 0xFD, 0x5E, 0xFF, 0xBD, 0x97, 0x3E, 0x29, + 0x75, 0xE7, 0x7E, 0xA7, 0x62, 0x58, 0xAF, 0x25, 0x34, 0xA5, 0x41, 0xC7, + 0x3D, 0xBC, 0x0D, 0x50, 0xCA, 0x03, 0x03, 0x0F, 0x08, 0x5A, 0x1F, 0x95, + 0x73, 0x78, 0x62, 0xBF, 0xAF, 0x72, 0x14, 0x69, 0x0E, 0xA5, 0xE5, 0x03, + 0x0E, 0x78, 0x8E, 0x26, 0x28, 0x42, 0xF0, 0x07, 0x0B, 0x62, 0x20, 0x10, + 0x67, 0x39, 0x46, 0xFA, 0xA9, 0x03, 0xCC, 0x04, 0x38, 0x7A, 0x66, 0xEF, + 0x20, 0x83, 0xB5, 0x8C, 0x4A, 0x56, 0x8E, 0x91, 0x00, 0xFC, 0x8E, 0x5C, + 0x82, 0xDE, 0x88, 0xA0, 0xC3, 0xE2, 0x68, 0x6E, 0x7D, 0x8D, 0xEF, 0x3C, + 0xDD, 0x65, 0xF4, 0x5D, 0xAC, 0x51, 0xEF, 0x24, 0x80, 0xAE, 0xAA, 0x56, + 0x97, 0x6F, 0xF9, 0xAD, 0x7D, 0xDA, 0x61, 0x3F, 0x98, 0x77, 0x3C, 0xA5, + 0x91, 0xB6, 0x1C, 0x8C, 0x26, 0xDA, 0x65, 0xA2, 0x09, 0x6D, 0xC1, 0xE2, + 0x54, 0xE3, 0xB9, 0xCA, 0x4C, 0x4C, 0x80, 0x8F, 0x77, 0x7B, 0x60, 0x9A, + 0x1E, 0xDF, 0xB6, 0xF2, 0x48, 0x1E, 0x0E, 0xBA, 0x4E, 0x54, 0x6D, 0x98, + 0xE0, 0xE1, 0xA2, 0x1A, 0xA2, 0x77, 0x50, 0xCF, 0xC4, 0x63, 0x92, 0xEC, + 0x47, 0x19, 0x9D, 0xEB, 0xE6, 0x6B, 0xCE, 0xC1 +}; + +static const unsigned char TA59_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA60_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x43, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA60_EC_Q[] = { + 0x04, 0x4C, 0xE9, 0x50, 0xC0, 0xC6, 0x0F, 0x72, 0x18, 0xBC, 0xD8, 0xF1, + 0xBA, 0xB3, 0x89, 0xE2, 0x79, 0x4A, 0xA3, 0x16, 0xA7, 0x6B, 0x54, 0x24, + 0xDB, 0x51, 0xFF, 0xEA, 0xF4, 0x09, 0x24, 0xC3, 0x0B, 0x22, 0x9F, 0xCB, + 0x6A, 0x27, 0x82, 0x81, 0x0D, 0xD2, 0xC0, 0xAF, 0x31, 0xE4, 0x74, 0x82, + 0x6E, 0xCA, 0x25, 0xD9, 0x8C, 0x75, 0x9D, 0xF1, 0xDB, 0xD0, 0x9A, 0xA2, + 0x4B, 0x21, 0x7E, 0x16, 0xA7, 0x63, 0x90, 0xD2, 0x39, 0xD4, 0xB1, 0x87, + 0x78, 0x5F, 0x18, 0x96, 0x0F, 0x50, 0x1B, 0x35, 0x37, 0x0F, 0x6A, 0xC6, + 0xDC, 0xD9, 0x13, 0x4D, 0xA4, 0x8E, 0x90, 0x37, 0xE6, 0xBD, 0x5B, 0x31, + 0x91 +}; + +static const unsigned char TA61_DN[] = { + 0x30, 0x42, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x09, 0x41, 0x43, 0x43, 0x56, 0x52, 0x41, 0x49, 0x5A, 0x31, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x50, 0x4B, 0x49, + 0x41, 0x43, 0x43, 0x56, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x04, 0x41, 0x43, 0x43, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53 +}; + +static const unsigned char TA61_RSA_N[] = { + 0x9B, 0xA9, 0xAB, 0xBF, 0x61, 0x4A, 0x97, 0xAF, 0x2F, 0x97, 0x66, 0x9A, + 0x74, 0x5F, 0xD0, 0xD9, 0x96, 0xFD, 0xCF, 0xE2, 0xE4, 0x66, 0xEF, 0x1F, + 0x1F, 0x47, 0x33, 0xC2, 0x44, 0xA3, 0xDF, 0x9A, 0xDE, 0x1F, 0xB5, 0x54, + 0xDD, 0x15, 0x7C, 0x69, 0x35, 0x11, 0x6F, 0xBB, 0xC8, 0x0C, 0x8E, 0x6A, + 0x18, 0x1E, 0xD8, 0x8F, 0xD9, 0x16, 0xBC, 0x10, 0x48, 0x36, 0x5C, 0xF0, + 0x63, 0xB3, 0x90, 0x5A, 0x5C, 0x24, 0x37, 0xD7, 0xA3, 0xD6, 0xCB, 0x09, + 0x71, 0xB9, 0xF1, 0x01, 0x72, 0x84, 0xB0, 0x7D, 0xDB, 0x4D, 0x80, 0xCD, + 0xFC, 0xD3, 0x6F, 0xC9, 0xF8, 0xDA, 0xB6, 0x0E, 0x82, 0xD2, 0x45, 0x85, + 0xA8, 0x1B, 0x68, 0xA8, 0x3D, 0xE8, 0xF4, 0x44, 0x6C, 0xBD, 0xA1, 0xC2, + 0xCB, 0x03, 0xBE, 0x8C, 0x3E, 0x13, 0x00, 0x84, 0xDF, 0x4A, 0x48, 0xC0, + 0xE3, 0x22, 0x0A, 0xE8, 0xE9, 0x37, 0xA7, 0x18, 0x4C, 0xB1, 0x09, 0x0D, + 0x23, 0x56, 0x7F, 0x04, 0x4D, 0xD9, 0x17, 0x84, 0x18, 0xA5, 0xC8, 0xDA, + 0x40, 0x94, 0x73, 0xEB, 0xCE, 0x0E, 0x57, 0x3C, 0x03, 0x81, 0x3A, 0x9D, + 0x0A, 0xA1, 0x57, 0x43, 0x69, 0xAC, 0x57, 0x6D, 0x79, 0x90, 0x78, 0xE5, + 0xB5, 0xB4, 0x3B, 0xD8, 0xBC, 0x4C, 0x8D, 0x28, 0xA1, 0xA7, 0xA3, 0xA7, + 0xBA, 0x02, 0x4E, 0x25, 0xD1, 0x2A, 0xAE, 0xED, 0xAE, 0x03, 0x22, 0xB8, + 0x6B, 0x20, 0x0F, 0x30, 0x28, 0x54, 0x95, 0x7F, 0xE0, 0xEE, 0xCE, 0x0A, + 0x66, 0x9D, 0xD1, 0x40, 0x2D, 0x6E, 0x22, 0xAF, 0x9D, 0x1A, 0xC1, 0x05, + 0x19, 0xD2, 0x6F, 0xC0, 0xF2, 0x9F, 0xF8, 0x7B, 0xB3, 0x02, 0x42, 0xFB, + 0x50, 0xA9, 0x1D, 0x2D, 0x93, 0x0F, 0x23, 0xAB, 0xC6, 0xC1, 0x0F, 0x92, + 0xFF, 0xD0, 0xA2, 0x15, 0xF5, 0x53, 0x09, 0x71, 0x1C, 0xFF, 0x45, 0x13, + 0x84, 0xE6, 0x26, 0x5E, 0xF8, 0xE0, 0x88, 0x1C, 0x0A, 0xFC, 0x16, 0xB6, + 0xA8, 0x73, 0x06, 0xB8, 0xF0, 0x63, 0x84, 0x02, 0xA0, 0xC6, 0x5A, 0xEC, + 0xE7, 0x74, 0xDF, 0x70, 0xAE, 0xA3, 0x83, 0x25, 0xEA, 0xD6, 0xC7, 0x97, + 0x87, 0x93, 0xA7, 0xC6, 0x8A, 0x8A, 0x33, 0x97, 0x60, 0x37, 0x10, 0x3E, + 0x97, 0x3E, 0x6E, 0x29, 0x15, 0xD6, 0xA1, 0x0F, 0xD1, 0x88, 0x2C, 0x12, + 0x9F, 0x6F, 0xAA, 0xA4, 0xC6, 0x42, 0xEB, 0x41, 0xA2, 0xE3, 0x95, 0x43, + 0xD3, 0x01, 0x85, 0x6D, 0x8E, 0xBB, 0x3B, 0xF3, 0x23, 0x36, 0xC7, 0xFE, + 0x3B, 0xE0, 0xA1, 0x25, 0x07, 0x48, 0xAB, 0xC9, 0x89, 0x74, 0xFF, 0x08, + 0x8F, 0x80, 0xBF, 0xC0, 0x96, 0x65, 0xF3, 0xEE, 0xEC, 0x4B, 0x68, 0xBD, + 0x9D, 0x88, 0xC3, 0x31, 0xB3, 0x40, 0xF1, 0xE8, 0xCF, 0xF6, 0x38, 0xBB, + 0x9C, 0xE4, 0xD1, 0x7F, 0xD4, 0xE5, 0x58, 0x9B, 0x7C, 0xFA, 0xD4, 0xF3, + 0x0E, 0x9B, 0x75, 0x91, 0xE4, 0xBA, 0x52, 0x2E, 0x19, 0x7E, 0xD1, 0xF5, + 0xCD, 0x5A, 0x19, 0xFC, 0xBA, 0x06, 0xF6, 0xFB, 0x52, 0xA8, 0x4B, 0x99, + 0x04, 0xDD, 0xF8, 0xF9, 0xB4, 0x8B, 0x50, 0xA3, 0x4E, 0x62, 0x89, 0xF0, + 0x87, 0x24, 0xFA, 0x83, 0x42, 0xC1, 0x87, 0xFA, 0xD5, 0x2D, 0x29, 0x2A, + 0x5A, 0x71, 0x7A, 0x64, 0x6A, 0xD7, 0x27, 0x60, 0x63, 0x0D, 0xDB, 0xCE, + 0x49, 0xF5, 0x8D, 0x1F, 0x90, 0x89, 0x32, 0x17, 0xF8, 0x73, 0x43, 0xB8, + 0xD2, 0x5A, 0x93, 0x86, 0x61, 0xD6, 0xE1, 0x75, 0x0A, 0xEA, 0x79, 0x66, + 0x76, 0x88, 0x4F, 0x71, 0xEB, 0x04, 0x25, 0xD6, 0x0A, 0x5A, 0x7A, 0x93, + 0xE5, 0xB9, 0x4B, 0x17, 0x40, 0x0F, 0xB1, 0xB6, 0xB9, 0xF5, 0xDE, 0x4F, + 0xDC, 0xE0, 0xB3, 0xAC, 0x3B, 0x11, 0x70, 0x60, 0x84, 0x4A, 0x43, 0x6E, + 0x99, 0x20, 0xC0, 0x29, 0x71, 0x0A, 0xC0, 0x65 +}; + +static const unsigned char TA61_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA62_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x32 +}; + +static const unsigned char TA62_EC_Q[] = { + 0x04, 0x9D, 0xCB, 0x80, 0x91, 0x8D, 0x53, 0x67, 0xB5, 0xB9, 0x50, 0xB1, + 0x03, 0xF8, 0xE5, 0x49, 0x1F, 0x41, 0x22, 0x09, 0xB0, 0x51, 0x52, 0x58, + 0xD6, 0x2B, 0x34, 0x8F, 0xC5, 0x12, 0x46, 0x14, 0xC5, 0x8B, 0x2F, 0x2C, + 0x84, 0xFF, 0x2C, 0x6E, 0xA8, 0xD5, 0xF1, 0x09, 0xE3, 0x03, 0x21, 0x14, + 0xC4, 0x43, 0x3D, 0x7C, 0xC1, 0x2C, 0xC4, 0x4B, 0x6A, 0x4A, 0xCD, 0xE9, + 0x87, 0xE0, 0x7D, 0xF6, 0x22, 0xBE, 0xFA, 0x4A, 0x51, 0xB8, 0x30, 0x8A, + 0xFD, 0xE1, 0xDE, 0x18, 0x12, 0x0A, 0xF6, 0x47, 0xB7, 0xE7, 0x17, 0xBF, + 0x27, 0x8A, 0xD4, 0x41, 0x4C, 0x96, 0x3C, 0x60, 0x96, 0xC1, 0xFD, 0x15, + 0x1C +}; + +static const unsigned char TA63_DN[] = { + 0x30, 0x81, 0xB4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, + 0x74, 0x31, 0x40, 0x30, 0x3E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x14, 0x37, + 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, + 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x5F, 0x32, 0x30, 0x34, 0x38, + 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x2E, 0x20, 0x62, 0x79, 0x20, + 0x72, 0x65, 0x66, 0x2E, 0x20, 0x28, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x73, + 0x20, 0x6C, 0x69, 0x61, 0x62, 0x2E, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1C, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, + 0x65, 0x74, 0x20, 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, + 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, + 0x34, 0x38, 0x29 +}; + +static const unsigned char TA63_RSA_N[] = { + 0xAD, 0x4D, 0x4B, 0xA9, 0x12, 0x86, 0xB2, 0xEA, 0xA3, 0x20, 0x07, 0x15, + 0x16, 0x64, 0x2A, 0x2B, 0x4B, 0xD1, 0xBF, 0x0B, 0x4A, 0x4D, 0x8E, 0xED, + 0x80, 0x76, 0xA5, 0x67, 0xB7, 0x78, 0x40, 0xC0, 0x73, 0x42, 0xC8, 0x68, + 0xC0, 0xDB, 0x53, 0x2B, 0xDD, 0x5E, 0xB8, 0x76, 0x98, 0x35, 0x93, 0x8B, + 0x1A, 0x9D, 0x7C, 0x13, 0x3A, 0x0E, 0x1F, 0x5B, 0xB7, 0x1E, 0xCF, 0xE5, + 0x24, 0x14, 0x1E, 0xB1, 0x81, 0xA9, 0x8D, 0x7D, 0xB8, 0xCC, 0x6B, 0x4B, + 0x03, 0xF1, 0x02, 0x0C, 0xDC, 0xAB, 0xA5, 0x40, 0x24, 0x00, 0x7F, 0x74, + 0x94, 0xA1, 0x9D, 0x08, 0x29, 0xB3, 0x88, 0x0B, 0xF5, 0x87, 0x77, 0x9D, + 0x55, 0xCD, 0xE4, 0xC3, 0x7E, 0xD7, 0x6A, 0x64, 0xAB, 0x85, 0x14, 0x86, + 0x95, 0x5B, 0x97, 0x32, 0x50, 0x6F, 0x3D, 0xC8, 0xBA, 0x66, 0x0C, 0xE3, + 0xFC, 0xBD, 0xB8, 0x49, 0xC1, 0x76, 0x89, 0x49, 0x19, 0xFD, 0xC0, 0xA8, + 0xBD, 0x89, 0xA3, 0x67, 0x2F, 0xC6, 0x9F, 0xBC, 0x71, 0x19, 0x60, 0xB8, + 0x2D, 0xE9, 0x2C, 0xC9, 0x90, 0x76, 0x66, 0x7B, 0x94, 0xE2, 0xAF, 0x78, + 0xD6, 0x65, 0x53, 0x5D, 0x3C, 0xD6, 0x9C, 0xB2, 0xCF, 0x29, 0x03, 0xF9, + 0x2F, 0xA4, 0x50, 0xB2, 0xD4, 0x48, 0xCE, 0x05, 0x32, 0x55, 0x8A, 0xFD, + 0xB2, 0x64, 0x4C, 0x0E, 0xE4, 0x98, 0x07, 0x75, 0xDB, 0x7F, 0xDF, 0xB9, + 0x08, 0x55, 0x60, 0x85, 0x30, 0x29, 0xF9, 0x7B, 0x48, 0xA4, 0x69, 0x86, + 0xE3, 0x35, 0x3F, 0x1E, 0x86, 0x5D, 0x7A, 0x7A, 0x15, 0xBD, 0xEF, 0x00, + 0x8E, 0x15, 0x22, 0x54, 0x17, 0x00, 0x90, 0x26, 0x93, 0xBC, 0x0E, 0x49, + 0x68, 0x91, 0xBF, 0xF8, 0x47, 0xD3, 0x9D, 0x95, 0x42, 0xC1, 0x0E, 0x4D, + 0xDF, 0x6F, 0x26, 0xCF, 0xC3, 0x18, 0x21, 0x62, 0x66, 0x43, 0x70, 0xD6, + 0xD5, 0xC0, 0x07, 0xE1 +}; + +static const unsigned char TA63_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA64_DN[] = { + 0x30, 0x69, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4B, 0x52, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, 0x42, 0x55, 0x53, 0x49, + 0x4E, 0x45, 0x53, 0x53, 0x20, 0x50, 0x4C, 0x41, 0x54, 0x46, 0x4F, 0x52, + 0x4D, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA64_RSA_N[] = { + 0xB6, 0xD4, 0xF1, 0x93, 0x5C, 0xB5, 0x40, 0x89, 0x0A, 0xAB, 0x0D, 0x90, + 0x5B, 0x50, 0x63, 0xAE, 0x90, 0x94, 0x74, 0x17, 0x45, 0x72, 0xD6, 0x7B, + 0x65, 0x5A, 0x29, 0x4B, 0xA7, 0x56, 0xA0, 0x4B, 0xB8, 0x2F, 0x42, 0x75, + 0xE9, 0xD9, 0x7B, 0x24, 0x5A, 0x31, 0x65, 0xAB, 0x17, 0x17, 0xD1, 0x33, + 0x3A, 0xD9, 0x11, 0xDC, 0x40, 0x36, 0x87, 0xDF, 0xC7, 0x6A, 0xE9, 0x26, + 0x5E, 0x59, 0x8A, 0x77, 0xE3, 0xE8, 0x48, 0x9C, 0x31, 0x16, 0xFA, 0x3E, + 0x91, 0xB1, 0xCA, 0xC9, 0xA3, 0xE2, 0x9F, 0xCE, 0x21, 0x53, 0xA3, 0x02, + 0x36, 0x30, 0xCB, 0x52, 0x02, 0xE5, 0xDA, 0x32, 0x5D, 0xC3, 0xC5, 0xE6, + 0xF9, 0xEE, 0x11, 0xC7, 0x8B, 0xC9, 0x44, 0x1E, 0x84, 0x93, 0x18, 0x4A, + 0xB4, 0x9F, 0xE5, 0x12, 0x64, 0x69, 0xD0, 0x26, 0x85, 0x62, 0x01, 0xB6, + 0xC9, 0x02, 0x1D, 0xBE, 0x83, 0x51, 0xBB, 0x5C, 0xDA, 0xF8, 0xAD, 0x15, + 0x6A, 0x99, 0xF7, 0x92, 0x54, 0xF7, 0x34, 0x5B, 0xE9, 0xBF, 0xEA, 0x29, + 0x81, 0x12, 0xD4, 0x53, 0x91, 0x96, 0xB3, 0x91, 0x5A, 0xDD, 0xFE, 0x90, + 0x73, 0x28, 0xFB, 0x30, 0x46, 0xB5, 0xCA, 0x08, 0x07, 0xC7, 0x71, 0x72, + 0xC9, 0x66, 0xD3, 0x34, 0x97, 0xF6, 0x8C, 0xF4, 0x18, 0x4A, 0xE1, 0xD0, + 0x3D, 0x5A, 0x45, 0xB6, 0x69, 0xA7, 0x29, 0xFB, 0x23, 0xCE, 0x88, 0xD8, + 0x12, 0x9C, 0x00, 0x48, 0xA8, 0xA6, 0x0F, 0xB3, 0x3B, 0x92, 0x8D, 0x71, + 0x0E, 0x74, 0xC5, 0x8B, 0xC8, 0x4C, 0xF9, 0xF4, 0x9B, 0x8E, 0xB8, 0x3C, + 0x69, 0xED, 0x6F, 0x3B, 0x50, 0x2F, 0x58, 0xED, 0xC4, 0xB0, 0xD0, 0x1C, + 0x1B, 0x6A, 0x0C, 0xE2, 0xBC, 0x44, 0xAA, 0xD8, 0xCD, 0x14, 0x5D, 0x94, + 0x78, 0x61, 0xBF, 0x0E, 0x6E, 0xDA, 0x2A, 0xBC, 0x2F, 0x0C, 0x0B, 0x71, + 0xA6, 0xB3, 0x16, 0x3F, 0x9C, 0xE6, 0xF9, 0xCC, 0x9F, 0x53, 0x35, 0xE2, + 0x03, 0xA0, 0xA0, 0x18, 0xBF, 0xBB, 0xF1, 0xBE, 0xF4, 0xD6, 0x8C, 0x87, + 0x0D, 0x42, 0xF7, 0x06, 0xB9, 0xF1, 0x6D, 0xED, 0x04, 0x94, 0xA8, 0xFE, + 0xB6, 0xD3, 0x06, 0xC6, 0x40, 0x61, 0xDF, 0x9D, 0x9D, 0xF3, 0x54, 0x76, + 0xCE, 0x53, 0x3A, 0x01, 0xA6, 0x92, 0x41, 0xEC, 0x04, 0xA3, 0x8F, 0x0D, + 0xA2, 0xD5, 0x09, 0xCA, 0xD6, 0xCB, 0x9A, 0xF1, 0xEF, 0x43, 0x5D, 0xC0, + 0xAB, 0xA5, 0x41, 0xCF, 0x5C, 0x53, 0x70, 0x70, 0xC9, 0x88, 0xA6, 0x2D, + 0xD4, 0x6B, 0x61, 0x73, 0x50, 0x26, 0x86, 0x61, 0x0E, 0x5F, 0x1B, 0xC2, + 0x2B, 0xE2, 0x8C, 0xD5, 0xBB, 0x9D, 0xC1, 0x03, 0x42, 0xBA, 0x94, 0xDA, + 0x5F, 0xA9, 0xB0, 0xCA, 0xCC, 0x4D, 0x0A, 0xEF, 0x47, 0x69, 0x03, 0x2F, + 0x22, 0xFB, 0xF1, 0x28, 0xCE, 0xBF, 0x5D, 0x50, 0x65, 0xA8, 0x90, 0x6D, + 0xB3, 0x74, 0xB0, 0x08, 0xC7, 0xAC, 0xA8, 0xD1, 0xEB, 0x3E, 0x9C, 0xFC, + 0x5D, 0x1A, 0x83, 0x2E, 0x2B, 0xCB, 0xB5, 0xF3, 0x44, 0x9D, 0x3A, 0xA7, + 0x17, 0x61, 0x96, 0xA2, 0x71, 0xD3, 0x70, 0x96, 0x15, 0x4D, 0xB7, 0x4C, + 0x73, 0xEE, 0x19, 0x5C, 0xC5, 0x5B, 0x3E, 0x41, 0xFE, 0xAC, 0x75, 0x60, + 0x3B, 0x1B, 0x63, 0xCE, 0x00, 0xDD, 0xDA, 0x08, 0x90, 0x62, 0xB4, 0xE5, + 0x2D, 0xEE, 0x48, 0xA7, 0x6B, 0x17, 0x99, 0x54, 0xBE, 0x87, 0x4A, 0xE3, + 0xA9, 0x5E, 0x04, 0x4C, 0xEB, 0x10, 0x6D, 0x54, 0xD6, 0xEF, 0xF1, 0xE8, + 0xF2, 0x62, 0x16, 0xCB, 0x80, 0x6B, 0xED, 0x3D, 0xED, 0xF5, 0x1F, 0x30, + 0xA5, 0xAE, 0x4B, 0xC9, 0x13, 0xED, 0x8A, 0x01, 0x01, 0xC9, 0xB8, 0x51, + 0x58, 0xC0, 0x66, 0x3A, 0xB1, 0x66, 0x4B, 0xC4, 0xD5, 0x31, 0x02, 0x62, + 0xE9, 0x74, 0x84, 0x0C, 0xDB, 0x4D, 0x46, 0x2D +}; + +static const unsigned char TA64_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA65_DN[] = { + 0x30, 0x81, 0x80, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, + 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x24, 0x30, + 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x43, 0x65, 0x72, 0x74, + 0x75, 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, + 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA65_RSA_N[] = { + 0xBD, 0xF9, 0x78, 0xF8, 0xE6, 0xD5, 0x80, 0x0C, 0x64, 0x9D, 0x86, 0x1B, + 0x96, 0x64, 0x67, 0x3F, 0x22, 0x3A, 0x1E, 0x75, 0x01, 0x7D, 0xEF, 0xFB, + 0x5C, 0x67, 0x8C, 0xC9, 0xCC, 0x5C, 0x6B, 0xA9, 0x91, 0xE6, 0xB9, 0x42, + 0xE5, 0x20, 0x4B, 0x9B, 0xDA, 0x9B, 0x7B, 0xB9, 0x99, 0x5D, 0xD9, 0x9B, + 0x80, 0x4B, 0xD7, 0x84, 0x40, 0x2B, 0x27, 0xD3, 0xE8, 0xBA, 0x30, 0xBB, + 0x3E, 0x09, 0x1A, 0xA7, 0x49, 0x95, 0xEF, 0x2B, 0x40, 0x24, 0xC2, 0x97, + 0xC7, 0xA7, 0xEE, 0x9B, 0x25, 0xEF, 0xA8, 0x0A, 0x00, 0x97, 0x85, 0x5A, + 0xAA, 0x9D, 0xDC, 0x29, 0xC9, 0xE2, 0x35, 0x07, 0xEB, 0x70, 0x4D, 0x4A, + 0xD6, 0xC1, 0xB3, 0x56, 0xB8, 0xA1, 0x41, 0x38, 0x9B, 0xD1, 0xFB, 0x31, + 0x7F, 0x8F, 0xE0, 0x5F, 0xE1, 0xB1, 0x3F, 0x0F, 0x8E, 0x16, 0x49, 0x60, + 0xD7, 0x06, 0x8D, 0x18, 0xF9, 0xAA, 0x26, 0x10, 0xAB, 0x2A, 0xD3, 0xD0, + 0xD1, 0x67, 0x8D, 0x1B, 0x46, 0xBE, 0x47, 0x30, 0xD5, 0x2E, 0x72, 0xD1, + 0xC5, 0x63, 0xDA, 0xE7, 0x63, 0x79, 0x44, 0x7E, 0x4B, 0x63, 0x24, 0x89, + 0x86, 0x2E, 0x34, 0x3F, 0x29, 0x4C, 0x52, 0x8B, 0x2A, 0xA7, 0xC0, 0xE2, + 0x91, 0x28, 0x89, 0xB9, 0xC0, 0x5B, 0xF9, 0x1D, 0xD9, 0xE7, 0x27, 0xAD, + 0xFF, 0x9A, 0x02, 0x97, 0xC1, 0xC6, 0x50, 0x92, 0x9B, 0x02, 0x2C, 0xBD, + 0xA9, 0xB9, 0x34, 0x59, 0x0A, 0xBF, 0x84, 0x4A, 0xFF, 0xDF, 0xFE, 0xB3, + 0x9F, 0xEB, 0xD9, 0x9E, 0xE0, 0x98, 0x23, 0xEC, 0xA6, 0x6B, 0x77, 0x16, + 0x2A, 0xDB, 0xCC, 0xAD, 0x3B, 0x1C, 0xA4, 0x87, 0xDC, 0x46, 0x73, 0x5E, + 0x19, 0x62, 0x68, 0x45, 0x57, 0xE4, 0x90, 0x82, 0x42, 0xBB, 0x42, 0xD6, + 0xF0, 0x61, 0xE0, 0xC1, 0xA3, 0x3D, 0x66, 0xA3, 0x5D, 0xF4, 0x18, 0xEE, + 0x88, 0xC9, 0x8D, 0x17, 0x45, 0x29, 0x99, 0x32, 0x75, 0x02, 0x31, 0xEE, + 0x29, 0x26, 0xC8, 0x6B, 0x02, 0xE6, 0xB5, 0x62, 0x45, 0x7F, 0x37, 0x15, + 0x5A, 0x23, 0x68, 0x89, 0xD4, 0x3E, 0xDE, 0x4E, 0x27, 0xB0, 0xF0, 0x40, + 0x0C, 0xBC, 0x4D, 0x17, 0xCB, 0x4D, 0xA2, 0xB3, 0x1E, 0xD0, 0x06, 0x5A, + 0xDD, 0xF6, 0x93, 0xCF, 0x57, 0x75, 0x99, 0xF5, 0xFA, 0x86, 0x1A, 0x67, + 0x78, 0xB3, 0xBF, 0x96, 0xFE, 0x34, 0xDC, 0xBD, 0xE7, 0x52, 0x56, 0xE5, + 0xB3, 0xE5, 0x75, 0x7B, 0xD7, 0x41, 0x91, 0x05, 0xDC, 0x5D, 0x69, 0xE3, + 0x95, 0x0D, 0x43, 0xB9, 0xFC, 0x83, 0x96, 0x39, 0x95, 0x7B, 0x6C, 0x80, + 0x5A, 0x4F, 0x13, 0x72, 0xC6, 0xD7, 0x7D, 0x29, 0x7A, 0x44, 0xBA, 0x52, + 0xA4, 0x2A, 0xD5, 0x41, 0x46, 0x09, 0x20, 0xFE, 0x22, 0xA0, 0xB6, 0x5B, + 0x30, 0x8D, 0xBC, 0x89, 0x0C, 0xD5, 0xD7, 0x70, 0xF8, 0x87, 0x52, 0xFD, + 0xDA, 0xEF, 0xAC, 0x51, 0x2E, 0x07, 0xB3, 0x4E, 0xFE, 0xD0, 0x09, 0xDA, + 0x70, 0xEF, 0x98, 0xFA, 0x56, 0xE6, 0x6D, 0xDB, 0xB5, 0x57, 0x4B, 0xDC, + 0xE5, 0x2C, 0x25, 0x15, 0xC8, 0x9E, 0x2E, 0x78, 0x4E, 0xF8, 0xDA, 0x9C, + 0x9E, 0x86, 0x2C, 0xCA, 0x57, 0xF3, 0x1A, 0xE5, 0xC8, 0x92, 0x8B, 0x1A, + 0x82, 0x96, 0x7A, 0xC3, 0xBC, 0x50, 0x12, 0x69, 0xD8, 0x0E, 0x5A, 0x46, + 0x8B, 0x3A, 0xEB, 0x26, 0xFA, 0x23, 0xC9, 0xB6, 0xB0, 0x81, 0xBE, 0x42, + 0x00, 0xA4, 0xF8, 0xD6, 0xFE, 0x30, 0x2E, 0xC7, 0xD2, 0x46, 0xF6, 0xE5, + 0x8E, 0x75, 0xFD, 0xF2, 0xCC, 0xB9, 0xD0, 0x87, 0x5B, 0xCC, 0x06, 0x10, + 0x60, 0xBB, 0x83, 0x35, 0xB7, 0x5E, 0x67, 0xDE, 0x47, 0xEC, 0x99, 0x48, + 0xF1, 0xA4, 0xA1, 0x15, 0xFE, 0xAD, 0x8C, 0x62, 0x8E, 0x39, 0x55, 0x4F, + 0x39, 0x16, 0xB9, 0xB1, 0x63, 0x9D, 0xFF, 0xB7 +}; + +static const unsigned char TA65_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA66_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x31 +}; + +static const unsigned char TA66_RSA_N[] = { + 0xAD, 0xE8, 0x24, 0x73, 0xF4, 0x14, 0x37, 0xF3, 0x9B, 0x9E, 0x2B, 0x57, + 0x28, 0x1C, 0x87, 0xBE, 0xDC, 0xB7, 0xDF, 0x38, 0x90, 0x8C, 0x6E, 0x3C, + 0xE6, 0x57, 0xA0, 0x78, 0xF7, 0x75, 0xC2, 0xA2, 0xFE, 0xF5, 0x6A, 0x6E, + 0xF6, 0x00, 0x4F, 0x28, 0xDB, 0xDE, 0x68, 0x86, 0x6C, 0x44, 0x93, 0xB6, + 0xB1, 0x63, 0xFD, 0x14, 0x12, 0x6B, 0xBF, 0x1F, 0xD2, 0xEA, 0x31, 0x9B, + 0x21, 0x7E, 0xD1, 0x33, 0x3C, 0xBA, 0x48, 0xF5, 0xDD, 0x79, 0xDF, 0xB3, + 0xB8, 0xFF, 0x12, 0xF1, 0x21, 0x9A, 0x4B, 0xC1, 0x8A, 0x86, 0x71, 0x69, + 0x4A, 0x66, 0x66, 0x6C, 0x8F, 0x7E, 0x3C, 0x70, 0xBF, 0xAD, 0x29, 0x22, + 0x06, 0xF3, 0xE4, 0xC0, 0xE6, 0x80, 0xAE, 0xE2, 0x4B, 0x8F, 0xB7, 0x99, + 0x7E, 0x94, 0x03, 0x9F, 0xD3, 0x47, 0x97, 0x7C, 0x99, 0x48, 0x23, 0x53, + 0xE8, 0x38, 0xAE, 0x4F, 0x0A, 0x6F, 0x83, 0x2E, 0xD1, 0x49, 0x57, 0x8C, + 0x80, 0x74, 0xB6, 0xDA, 0x2F, 0xD0, 0x38, 0x8D, 0x7B, 0x03, 0x70, 0x21, + 0x1B, 0x75, 0xF2, 0x30, 0x3C, 0xFA, 0x8F, 0xAE, 0xDD, 0xDA, 0x63, 0xAB, + 0xEB, 0x16, 0x4F, 0xC2, 0x8E, 0x11, 0x4B, 0x7E, 0xCF, 0x0B, 0xE8, 0xFF, + 0xB5, 0x77, 0x2E, 0xF4, 0xB2, 0x7B, 0x4A, 0xE0, 0x4C, 0x12, 0x25, 0x0C, + 0x70, 0x8D, 0x03, 0x29, 0xA0, 0xE1, 0x53, 0x24, 0xEC, 0x13, 0xD9, 0xEE, + 0x19, 0xBF, 0x10, 0xB3, 0x4A, 0x8C, 0x3F, 0x89, 0xA3, 0x61, 0x51, 0xDE, + 0xAC, 0x87, 0x07, 0x94, 0xF4, 0x63, 0x71, 0xEC, 0x2E, 0xE2, 0x6F, 0x5B, + 0x98, 0x81, 0xE1, 0x89, 0x5C, 0x34, 0x79, 0x6C, 0x76, 0xEF, 0x3B, 0x90, + 0x62, 0x79, 0xE6, 0xDB, 0xA4, 0x9A, 0x2F, 0x26, 0xC5, 0xD0, 0x10, 0xE1, + 0x0E, 0xDE, 0xD9, 0x10, 0x8E, 0x16, 0xFB, 0xB7, 0xF7, 0xA8, 0xF7, 0xC7, + 0xE5, 0x02, 0x07, 0x98, 0x8F, 0x36, 0x08, 0x95, 0xE7, 0xE2, 0x37, 0x96, + 0x0D, 0x36, 0x75, 0x9E, 0xFB, 0x0E, 0x72, 0xB1, 0x1D, 0x9B, 0xBC, 0x03, + 0xF9, 0x49, 0x05, 0xD8, 0x81, 0xDD, 0x05, 0xB4, 0x2A, 0xD6, 0x41, 0xE9, + 0xAC, 0x01, 0x76, 0x95, 0x0A, 0x0F, 0xD8, 0xDF, 0xD5, 0xBD, 0x12, 0x1F, + 0x35, 0x2F, 0x28, 0x17, 0x6C, 0xD2, 0x98, 0xC1, 0xA8, 0x09, 0x64, 0x77, + 0x6E, 0x47, 0x37, 0xBA, 0xCE, 0xAC, 0x59, 0x5E, 0x68, 0x9D, 0x7F, 0x72, + 0xD6, 0x89, 0xC5, 0x06, 0x41, 0x29, 0x3E, 0x59, 0x3E, 0xDD, 0x26, 0xF5, + 0x24, 0xC9, 0x11, 0xA7, 0x5A, 0xA3, 0x4C, 0x40, 0x1F, 0x46, 0xA1, 0x99, + 0xB5, 0xA7, 0x3A, 0x51, 0x6E, 0x86, 0x3B, 0x9E, 0x7D, 0x72, 0xA7, 0x12, + 0x05, 0x78, 0x59, 0xED, 0x3E, 0x51, 0x78, 0x15, 0x0B, 0x03, 0x8F, 0x8D, + 0xD0, 0x2F, 0x05, 0xB2, 0x3E, 0x7B, 0x4A, 0x1C, 0x4B, 0x73, 0x05, 0x12, + 0xFC, 0xC6, 0xEA, 0xE0, 0x50, 0x13, 0x7C, 0x43, 0x93, 0x74, 0xB3, 0xCA, + 0x74, 0xE7, 0x8E, 0x1F, 0x01, 0x08, 0xD0, 0x30, 0xD4, 0x5B, 0x71, 0x36, + 0xB4, 0x07, 0xBA, 0xC1, 0x30, 0x30, 0x5C, 0x48, 0xB7, 0x82, 0x3B, 0x98, + 0xA6, 0x7D, 0x60, 0x8A, 0xA2, 0xA3, 0x29, 0x82, 0xCC, 0xBA, 0xBD, 0x83, + 0x04, 0x1B, 0xA2, 0x83, 0x03, 0x41, 0xA1, 0xD6, 0x05, 0xF1, 0x1B, 0xC2, + 0xB6, 0xF0, 0xA8, 0x7C, 0x86, 0x3B, 0x46, 0xA8, 0x48, 0x2A, 0x88, 0xDC, + 0x76, 0x9A, 0x76, 0xBF, 0x1F, 0x6A, 0xA5, 0x3D, 0x19, 0x8F, 0xEB, 0x38, + 0xF3, 0x64, 0xDE, 0xC8, 0x2B, 0x0D, 0x0A, 0x28, 0xFF, 0xF7, 0xDB, 0xE2, + 0x15, 0x42, 0xD4, 0x22, 0xD0, 0x27, 0x5D, 0xE1, 0x79, 0xFE, 0x18, 0xE7, + 0x70, 0x88, 0xAD, 0x4E, 0xE6, 0xD9, 0x8B, 0x3A, 0xC6, 0xDD, 0x27, 0x51, + 0x6E, 0xFF, 0xBC, 0x64, 0xF5, 0x33, 0x43, 0x4F +}; + +static const unsigned char TA66_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA67_DN[] = { + 0x30, 0x81, 0x81, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA67_RSA_N[] = { + 0xD0, 0x40, 0x8B, 0x8B, 0x72, 0xE3, 0x91, 0x1B, 0xF7, 0x51, 0xC1, 0x1B, + 0x54, 0x04, 0x98, 0xD3, 0xA9, 0xBF, 0xC1, 0xE6, 0x8A, 0x5D, 0x3B, 0x87, + 0xFB, 0xBB, 0x88, 0xCE, 0x0D, 0xE3, 0x2F, 0x3F, 0x06, 0x96, 0xF0, 0xA2, + 0x29, 0x50, 0x99, 0xAE, 0xDB, 0x3B, 0xA1, 0x57, 0xB0, 0x74, 0x51, 0x71, + 0xCD, 0xED, 0x42, 0x91, 0x4D, 0x41, 0xFE, 0xA9, 0xC8, 0xD8, 0x6A, 0x86, + 0x77, 0x44, 0xBB, 0x59, 0x66, 0x97, 0x50, 0x5E, 0xB4, 0xD4, 0x2C, 0x70, + 0x44, 0xCF, 0xDA, 0x37, 0x95, 0x42, 0x69, 0x3C, 0x30, 0xC4, 0x71, 0xB3, + 0x52, 0xF0, 0x21, 0x4D, 0xA1, 0xD8, 0xBA, 0x39, 0x7C, 0x1C, 0x9E, 0xA3, + 0x24, 0x9D, 0xF2, 0x83, 0x16, 0x98, 0xAA, 0x16, 0x7C, 0x43, 0x9B, 0x15, + 0x5B, 0xB7, 0xAE, 0x34, 0x91, 0xFE, 0xD4, 0x62, 0x26, 0x18, 0x46, 0x9A, + 0x3F, 0xEB, 0xC1, 0xF9, 0xF1, 0x90, 0x57, 0xEB, 0xAC, 0x7A, 0x0D, 0x8B, + 0xDB, 0x72, 0x30, 0x6A, 0x66, 0xD5, 0xE0, 0x46, 0xA3, 0x70, 0xDC, 0x68, + 0xD9, 0xFF, 0x04, 0x48, 0x89, 0x77, 0xDE, 0xB5, 0xE9, 0xFB, 0x67, 0x6D, + 0x41, 0xE9, 0xBC, 0x39, 0xBD, 0x32, 0xD9, 0x62, 0x02, 0xF1, 0xB1, 0xA8, + 0x3D, 0x6E, 0x37, 0x9C, 0xE2, 0x2F, 0xE2, 0xD3, 0xA2, 0x26, 0x8B, 0xC6, + 0xB8, 0x55, 0x43, 0x88, 0xE1, 0x23, 0x3E, 0xA5, 0xD2, 0x24, 0x39, 0x6A, + 0x47, 0xAB, 0x00, 0xD4, 0xA1, 0xB3, 0xA9, 0x25, 0xFE, 0x0D, 0x3F, 0xA7, + 0x1D, 0xBA, 0xD3, 0x51, 0xC1, 0x0B, 0xA4, 0xDA, 0xAC, 0x38, 0xEF, 0x55, + 0x50, 0x24, 0x05, 0x65, 0x46, 0x93, 0x34, 0x4F, 0x2D, 0x8D, 0xAD, 0xC6, + 0xD4, 0x21, 0x19, 0xD2, 0x8E, 0xCA, 0x05, 0x61, 0x71, 0x07, 0x73, 0x47, + 0xE5, 0x8A, 0x19, 0x12, 0xBD, 0x04, 0x4D, 0xCE, 0x4E, 0x9C, 0xA5, 0x48, + 0xAC, 0xBB, 0x26, 0xF7 +}; + +static const unsigned char TA67_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA68_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x1C, + 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x43, 0x31 +}; + +static const unsigned char TA68_RSA_N[] = { + 0xCF, 0xEB, 0xA9, 0xB9, 0xF1, 0x99, 0x05, 0xCC, 0xD8, 0x28, 0x21, 0x4A, + 0xF3, 0x73, 0x34, 0x51, 0x84, 0x56, 0x10, 0xF5, 0xA0, 0x4F, 0x2C, 0x12, + 0xE3, 0xFA, 0x13, 0x9A, 0x27, 0xD0, 0xCF, 0xF9, 0x79, 0x1A, 0x74, 0x5F, + 0x1D, 0x79, 0x39, 0xFC, 0x5B, 0xF8, 0x70, 0x8E, 0xE0, 0x92, 0x52, 0xF7, + 0xE4, 0x25, 0xF9, 0x54, 0x83, 0xD9, 0x1D, 0xD3, 0xC8, 0x5A, 0x85, 0x3F, + 0x5E, 0xC7, 0xB6, 0x07, 0xEE, 0x3E, 0xC0, 0xCE, 0x9A, 0xAF, 0xAC, 0x56, + 0x42, 0x2A, 0x39, 0x25, 0x70, 0xD6, 0xBF, 0xB5, 0x7B, 0x36, 0xAD, 0xAC, + 0xF6, 0x73, 0xDC, 0xCD, 0xD7, 0x1D, 0x8A, 0x83, 0xA5, 0xFB, 0x2B, 0x90, + 0x15, 0x37, 0x6B, 0x1C, 0x26, 0x47, 0xDC, 0x3B, 0x29, 0x56, 0x93, 0x6A, + 0xB3, 0xC1, 0x6A, 0x3A, 0x9D, 0x3D, 0xF5, 0xC1, 0x97, 0x38, 0x58, 0x05, + 0x8B, 0x1C, 0x11, 0xE3, 0xE4, 0xB4, 0xB8, 0x5D, 0x85, 0x1D, 0x83, 0xFE, + 0x78, 0x5F, 0x0B, 0x45, 0x68, 0x18, 0x48, 0xA5, 0x46, 0x73, 0x34, 0x3B, + 0xFE, 0x0F, 0xC8, 0x76, 0xBB, 0xC7, 0x18, 0xF3, 0x05, 0xD1, 0x86, 0xF3, + 0x85, 0xED, 0xE7, 0xB9, 0xD9, 0x32, 0xAD, 0x55, 0x88, 0xCE, 0xA6, 0xB6, + 0x91, 0xB0, 0x4F, 0xAC, 0x7E, 0x15, 0x23, 0x96, 0xF6, 0x3F, 0xF0, 0x20, + 0x34, 0x16, 0xDE, 0x0A, 0xC6, 0xC4, 0x04, 0x45, 0x79, 0x7F, 0xA7, 0xFD, + 0xBE, 0xD2, 0xA9, 0xA5, 0xAF, 0x9C, 0xC5, 0x23, 0x2A, 0xF7, 0x3C, 0x21, + 0x6C, 0xBD, 0xAF, 0x8F, 0x4E, 0xC5, 0x3A, 0xB2, 0xF3, 0x34, 0x12, 0xFC, + 0xDF, 0x80, 0x1A, 0x49, 0xA4, 0xD4, 0xA9, 0x95, 0xF7, 0x9E, 0x89, 0x5E, + 0xA2, 0x89, 0xAC, 0x94, 0xCB, 0xA8, 0x68, 0x9B, 0xAF, 0x8A, 0x65, 0x27, + 0xCD, 0x89, 0xEE, 0xDD, 0x8C, 0xB5, 0x6B, 0x29, 0x70, 0x43, 0xA0, 0x69, + 0x0B, 0xE4, 0xB9, 0x0F +}; + +static const unsigned char TA68_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA69_DN[] = { + 0x30, 0x74, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x45, 0x43, 0x2D, 0x33, 0x38, 0x34, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA69_EC_Q[] = { + 0x04, 0xC4, 0x28, 0x8E, 0xAB, 0x18, 0x5B, 0x6A, 0xBE, 0x6E, 0x64, 0x37, + 0x63, 0xE4, 0xCD, 0xEC, 0xAB, 0x3A, 0xF7, 0xCC, 0xA1, 0xB8, 0x0E, 0x82, + 0x49, 0xD7, 0x86, 0x29, 0x9F, 0xA1, 0x94, 0xF2, 0xE3, 0x60, 0x78, 0x98, + 0x81, 0x78, 0x06, 0x4D, 0xF2, 0xEC, 0x9A, 0x0E, 0x57, 0x60, 0x83, 0x9F, + 0xB4, 0xE6, 0x17, 0x2F, 0x1A, 0xB3, 0x5D, 0x02, 0x5B, 0x89, 0x23, 0x3C, + 0xC2, 0x11, 0x05, 0x2A, 0xA7, 0x88, 0x13, 0x18, 0xF3, 0x50, 0x84, 0xD7, + 0xBD, 0x34, 0x2C, 0x27, 0x89, 0x55, 0xFF, 0xCE, 0x4C, 0xE7, 0xDF, 0xA6, + 0x1F, 0x28, 0xC4, 0xF0, 0x54, 0xC3, 0xB9, 0x7C, 0xB7, 0x53, 0xAD, 0xEB, + 0xC2 +}; + +static const unsigned char TA70_DN[] = { + 0x30, 0x81, 0xBE, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x32, 0x30, + 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, + 0x32 +}; + +static const unsigned char TA70_RSA_N[] = { + 0xBA, 0x84, 0xB6, 0x72, 0xDB, 0x9E, 0x0C, 0x6B, 0xE2, 0x99, 0xE9, 0x30, + 0x01, 0xA7, 0x76, 0xEA, 0x32, 0xB8, 0x95, 0x41, 0x1A, 0xC9, 0xDA, 0x61, + 0x4E, 0x58, 0x72, 0xCF, 0xFE, 0xF6, 0x82, 0x79, 0xBF, 0x73, 0x61, 0x06, + 0x0A, 0xA5, 0x27, 0xD8, 0xB3, 0x5F, 0xD3, 0x45, 0x4E, 0x1C, 0x72, 0xD6, + 0x4E, 0x32, 0xF2, 0x72, 0x8A, 0x0F, 0xF7, 0x83, 0x19, 0xD0, 0x6A, 0x80, + 0x80, 0x00, 0x45, 0x1E, 0xB0, 0xC7, 0xE7, 0x9A, 0xBF, 0x12, 0x57, 0x27, + 0x1C, 0xA3, 0x68, 0x2F, 0x0A, 0x87, 0xBD, 0x6A, 0x6B, 0x0E, 0x5E, 0x65, + 0xF3, 0x1C, 0x77, 0xD5, 0xD4, 0x85, 0x8D, 0x70, 0x21, 0xB4, 0xB3, 0x32, + 0xE7, 0x8B, 0xA2, 0xD5, 0x86, 0x39, 0x02, 0xB1, 0xB8, 0xD2, 0x47, 0xCE, + 0xE4, 0xC9, 0x49, 0xC4, 0x3B, 0xA7, 0xDE, 0xFB, 0x54, 0x7D, 0x57, 0xBE, + 0xF0, 0xE8, 0x6E, 0xC2, 0x79, 0xB2, 0x3A, 0x0B, 0x55, 0xE2, 0x50, 0x98, + 0x16, 0x32, 0x13, 0x5C, 0x2F, 0x78, 0x56, 0xC1, 0xC2, 0x94, 0xB3, 0xF2, + 0x5A, 0xE4, 0x27, 0x9A, 0x9F, 0x24, 0xD7, 0xC6, 0xEC, 0xD0, 0x9B, 0x25, + 0x82, 0xE3, 0xCC, 0xC2, 0xC4, 0x45, 0xC5, 0x8C, 0x97, 0x7A, 0x06, 0x6B, + 0x2A, 0x11, 0x9F, 0xA9, 0x0A, 0x6E, 0x48, 0x3B, 0x6F, 0xDB, 0xD4, 0x11, + 0x19, 0x42, 0xF7, 0x8F, 0x07, 0xBF, 0xF5, 0x53, 0x5F, 0x9C, 0x3E, 0xF4, + 0x17, 0x2C, 0xE6, 0x69, 0xAC, 0x4E, 0x32, 0x4C, 0x62, 0x77, 0xEA, 0xB7, + 0xE8, 0xE5, 0xBB, 0x34, 0xBC, 0x19, 0x8B, 0xAE, 0x9C, 0x51, 0xE7, 0xB7, + 0x7E, 0xB5, 0x53, 0xB1, 0x33, 0x22, 0xE5, 0x6D, 0xCF, 0x70, 0x3C, 0x1A, + 0xFA, 0xE2, 0x9B, 0x67, 0xB6, 0x83, 0xF4, 0x8D, 0xA5, 0xAF, 0x62, 0x4C, + 0x4D, 0xE0, 0x58, 0xAC, 0x64, 0x34, 0x12, 0x03, 0xF8, 0xB6, 0x8D, 0x94, + 0x63, 0x24, 0xA4, 0x71 +}; + +static const unsigned char TA70_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA71_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x54, 0x57, 0x43, 0x41, 0x20, 0x43, 0x59, 0x42, + 0x45, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA71_RSA_N[] = { + 0xC6, 0xF8, 0xCA, 0x1E, 0xD9, 0x09, 0x20, 0x7E, 0x1D, 0x6C, 0x4E, 0xCE, + 0x8F, 0xE3, 0x47, 0x33, 0x44, 0x9C, 0xC7, 0xC9, 0x69, 0xAA, 0x3A, 0x5B, + 0x78, 0xEE, 0x70, 0xD2, 0x92, 0xF8, 0x04, 0xB3, 0x52, 0x52, 0x1D, 0x67, + 0x72, 0x28, 0xA1, 0xDF, 0x8B, 0x5D, 0x95, 0x0A, 0xFE, 0xEA, 0xCD, 0xED, + 0xF7, 0x29, 0xCE, 0xF0, 0x6F, 0x7F, 0xAC, 0xCD, 0x3D, 0xEF, 0xB3, 0x1C, + 0x45, 0x6A, 0xF7, 0x28, 0x90, 0xF1, 0x61, 0x57, 0xC5, 0x0C, 0xC4, 0xA3, + 0x50, 0x5D, 0xDE, 0xD4, 0xB5, 0xCB, 0x19, 0xCA, 0x80, 0xB9, 0x75, 0xCE, + 0x29, 0xCE, 0xD2, 0x85, 0x22, 0xEC, 0x02, 0x63, 0xCC, 0x44, 0x30, 0x20, + 0xDA, 0xEA, 0x91, 0x5B, 0x56, 0xE6, 0x1D, 0x1C, 0xD5, 0x9D, 0x66, 0xC7, + 0x3F, 0xDF, 0x86, 0xCA, 0x4B, 0x53, 0xC4, 0xD9, 0x8D, 0xB2, 0x1D, 0xEA, + 0xF8, 0xDC, 0x27, 0x53, 0xA3, 0x47, 0xE1, 0x61, 0xCC, 0x7D, 0xB5, 0xB0, + 0xF8, 0xEE, 0x73, 0x91, 0xC5, 0xCE, 0x73, 0x6F, 0xCE, 0xEE, 0x10, 0x1F, + 0x1A, 0x06, 0xCF, 0xE9, 0x27, 0x60, 0xC5, 0x4F, 0x19, 0xE4, 0xEB, 0xCE, + 0x22, 0x26, 0x45, 0xD7, 0x60, 0x99, 0xDD, 0xCE, 0x4F, 0x37, 0xE0, 0x7F, + 0xE7, 0x63, 0xAD, 0xB0, 0xB8, 0x59, 0xB8, 0xD0, 0x06, 0x68, 0x35, 0x60, + 0xD3, 0x36, 0xAE, 0x71, 0x43, 0x04, 0xF1, 0x69, 0x65, 0x78, 0x7C, 0xF3, + 0x1F, 0xF3, 0xCA, 0x28, 0x9F, 0x5A, 0x20, 0x95, 0x66, 0xB4, 0xCD, 0xB7, + 0xEE, 0x8F, 0x78, 0xA4, 0x45, 0x18, 0xE9, 0x26, 0x2F, 0x8D, 0x9B, 0x29, + 0x28, 0xB1, 0xA4, 0xB7, 0x3A, 0x6D, 0xB9, 0xD4, 0x1C, 0x38, 0x72, 0x45, + 0x58, 0xB1, 0x5E, 0xEB, 0xF0, 0x28, 0x9B, 0xB7, 0x82, 0xCA, 0xFD, 0xCF, + 0xD6, 0x33, 0x0F, 0x9F, 0xFB, 0x97, 0x9E, 0xB1, 0x1C, 0x9C, 0x9E, 0xEA, + 0x5F, 0x5E, 0xDB, 0xAA, 0xDD, 0x54, 0xE9, 0x30, 0x21, 0x28, 0x6D, 0x8E, + 0x79, 0xF3, 0x75, 0x92, 0x8C, 0x26, 0xFE, 0xDC, 0xC5, 0xF6, 0xC3, 0xB0, + 0xDF, 0x44, 0x59, 0x43, 0xA3, 0xB6, 0x03, 0x28, 0xF6, 0x08, 0x30, 0xAA, + 0x0D, 0x33, 0xE1, 0xEF, 0x9C, 0xA9, 0x07, 0x22, 0xE3, 0x59, 0x5B, 0x40, + 0x8F, 0xDA, 0x88, 0xB7, 0x69, 0x08, 0xA8, 0xB7, 0x23, 0x2E, 0x44, 0x09, + 0x59, 0x37, 0x5B, 0xC7, 0xE3, 0x17, 0xF2, 0x22, 0xEB, 0x6E, 0x39, 0x52, + 0xC5, 0xDE, 0x54, 0xA7, 0x98, 0xC9, 0x4B, 0x20, 0x95, 0xDC, 0x46, 0x89, + 0x5F, 0xB4, 0x12, 0xF9, 0x85, 0x29, 0x8E, 0xEB, 0xC8, 0x27, 0x15, 0x20, + 0xC0, 0x4B, 0xD4, 0xCC, 0x7C, 0x0C, 0x6C, 0x34, 0x0C, 0x26, 0x9B, 0x26, + 0x31, 0xA6, 0x3C, 0xA7, 0xF6, 0xD9, 0xD0, 0x4B, 0xA2, 0x64, 0xFF, 0x3B, + 0x99, 0x41, 0x72, 0xC1, 0xE0, 0x70, 0x97, 0xF1, 0x24, 0xBB, 0x2B, 0xC4, + 0x74, 0x22, 0xB1, 0xAC, 0x6B, 0x22, 0x32, 0x24, 0xD3, 0x78, 0x2A, 0xC0, + 0xC0, 0xA1, 0x2F, 0xF1, 0x52, 0x05, 0xC9, 0x3F, 0xEF, 0x76, 0x66, 0xE2, + 0x45, 0xD8, 0x0D, 0x3D, 0xAD, 0x95, 0xC8, 0xC7, 0x89, 0x26, 0xC8, 0x0F, + 0xAE, 0xA7, 0x03, 0x2E, 0xFB, 0xC1, 0x5F, 0xFA, 0x20, 0xE1, 0x70, 0xAD, + 0xB0, 0x65, 0x20, 0x37, 0x33, 0x60, 0xB0, 0xD5, 0xAF, 0xD7, 0x0C, 0x1C, + 0xC2, 0x90, 0x70, 0xD7, 0x4A, 0x18, 0xBC, 0x7E, 0x01, 0xB0, 0xB0, 0xEB, + 0x15, 0x1E, 0x44, 0x06, 0xCD, 0xA4, 0x4F, 0xE8, 0x0C, 0xD1, 0xC3, 0x20, + 0x10, 0xE1, 0x54, 0x65, 0x9E, 0xB6, 0x51, 0xD0, 0x1A, 0x76, 0x6B, 0x42, + 0x5A, 0x58, 0x76, 0x34, 0xEA, 0xB7, 0x37, 0x19, 0xAE, 0x2E, 0x75, 0xF9, + 0x96, 0xE5, 0xC1, 0x59, 0xF7, 0x94, 0x57, 0x29, 0x25, 0x8D, 0x3A, 0x4C, + 0xAB, 0x4D, 0x9A, 0x41, 0xD0, 0x5F, 0x26, 0x03 +}; + +static const unsigned char TA71_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA72_DN[] = { + 0x30, 0x38, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x49, 0x5A, 0x45, 0x4E, 0x50, 0x45, 0x20, 0x53, 0x2E, 0x41, + 0x2E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0A, + 0x49, 0x7A, 0x65, 0x6E, 0x70, 0x65, 0x2E, 0x63, 0x6F, 0x6D +}; + +static const unsigned char TA72_RSA_N[] = { + 0xC9, 0xD3, 0x7A, 0xCA, 0x0F, 0x1E, 0xAC, 0xA7, 0x86, 0xE8, 0x16, 0x65, + 0x6A, 0xB1, 0xC2, 0x1B, 0x45, 0x32, 0x71, 0x95, 0xD9, 0xFE, 0x10, 0x5B, + 0xCC, 0xAF, 0xE7, 0xA5, 0x79, 0x01, 0x8F, 0x89, 0xC3, 0xCA, 0xF2, 0x55, + 0x71, 0xF7, 0x77, 0xBE, 0x77, 0x94, 0xF3, 0x72, 0xA4, 0x2C, 0x44, 0xD8, + 0x9E, 0x92, 0x9B, 0x14, 0x3A, 0xA1, 0xE7, 0x24, 0x90, 0x0A, 0x0A, 0x56, + 0x8E, 0xC5, 0xD8, 0x26, 0x94, 0xE1, 0xD9, 0x48, 0xE1, 0x2D, 0x3E, 0xDA, + 0x0A, 0x72, 0xDD, 0xA3, 0x99, 0x15, 0xDA, 0x81, 0xA2, 0x87, 0xF4, 0x7B, + 0x6E, 0x26, 0x77, 0x89, 0x58, 0xAD, 0xD6, 0xEB, 0x0C, 0xB2, 0x41, 0x7A, + 0x73, 0x6E, 0x6D, 0xDB, 0x7A, 0x78, 0x41, 0xE9, 0x08, 0x88, 0x12, 0x7E, + 0x87, 0x2E, 0x66, 0x11, 0x63, 0x6C, 0x54, 0xFB, 0x3C, 0x9D, 0x72, 0xC0, + 0xBC, 0x2E, 0xFF, 0xC2, 0xB7, 0xDD, 0x0D, 0x76, 0xE3, 0x3A, 0xD7, 0xF7, + 0xB4, 0x68, 0xBE, 0xA2, 0xF5, 0xE3, 0x81, 0x6E, 0xC1, 0x46, 0x6F, 0x5D, + 0x8D, 0xE0, 0x4D, 0xC6, 0x54, 0x55, 0x89, 0x1A, 0x33, 0x31, 0x0A, 0xB1, + 0x57, 0xB9, 0xA3, 0x8A, 0x98, 0xC3, 0xEC, 0x3B, 0x34, 0xC5, 0x95, 0x41, + 0x69, 0x7E, 0x75, 0xC2, 0x3C, 0x20, 0xC5, 0x61, 0xBA, 0x51, 0x47, 0xA0, + 0x20, 0x90, 0x93, 0xA1, 0x90, 0x4B, 0xF3, 0x4E, 0x7C, 0x85, 0x45, 0x54, + 0x9A, 0xD1, 0x05, 0x26, 0x41, 0xB0, 0xB5, 0x4D, 0x1D, 0x33, 0xBE, 0xC4, + 0x03, 0xC8, 0x25, 0x7C, 0xC1, 0x70, 0xDB, 0x3B, 0xF4, 0x09, 0x2D, 0x54, + 0x27, 0x48, 0xAC, 0x2F, 0xE1, 0xC4, 0xAC, 0x3E, 0xC8, 0xCB, 0x92, 0x4C, + 0x53, 0x39, 0x37, 0x23, 0xEC, 0xD3, 0x01, 0xF9, 0xE0, 0x09, 0x44, 0x4D, + 0x4D, 0x64, 0xC0, 0xE1, 0x0D, 0x5A, 0x87, 0x22, 0xBC, 0xAD, 0x1B, 0xA3, + 0xFE, 0x26, 0xB5, 0x15, 0xF3, 0xA7, 0xFC, 0x84, 0x19, 0xE9, 0xEC, 0xA1, + 0x88, 0xB4, 0x44, 0x69, 0x84, 0x83, 0xF3, 0x89, 0xD1, 0x74, 0x06, 0xA9, + 0xCC, 0x0B, 0xD6, 0xC2, 0xDE, 0x27, 0x85, 0x50, 0x26, 0xCA, 0x17, 0xB8, + 0xC9, 0x7A, 0x87, 0x56, 0x2C, 0x1A, 0x01, 0x1E, 0x6C, 0xBE, 0x13, 0xAD, + 0x10, 0xAC, 0xB5, 0x24, 0xF5, 0x38, 0x91, 0xA1, 0xD6, 0x4B, 0xDA, 0xF1, + 0xBB, 0xD2, 0xDE, 0x47, 0xB5, 0xF1, 0xBC, 0x81, 0xF6, 0x59, 0x6B, 0xCF, + 0x19, 0x53, 0xE9, 0x8D, 0x15, 0xCB, 0x4A, 0xCB, 0xA9, 0x6F, 0x44, 0xE5, + 0x1B, 0x41, 0xCF, 0xE1, 0x86, 0xA7, 0xCA, 0xD0, 0x6A, 0x9F, 0xBC, 0x4C, + 0x8D, 0x06, 0x33, 0x5A, 0xA2, 0x85, 0xE5, 0x90, 0x35, 0xA0, 0x62, 0x5C, + 0x16, 0x4E, 0xF0, 0xE3, 0xA2, 0xFA, 0x03, 0x1A, 0xB4, 0x2C, 0x71, 0xB3, + 0x58, 0x2C, 0xDE, 0x7B, 0x0B, 0xDB, 0x1A, 0x0F, 0xEB, 0xDE, 0x21, 0x1F, + 0x06, 0x77, 0x06, 0x03, 0xB0, 0xC9, 0xEF, 0x99, 0xFC, 0xC0, 0xB9, 0x4F, + 0x0B, 0x86, 0x28, 0xFE, 0xD2, 0xB9, 0xEA, 0xE3, 0xDA, 0xA5, 0xC3, 0x47, + 0x69, 0x12, 0xE0, 0xDB, 0xF0, 0xF6, 0x19, 0x8B, 0xED, 0x7B, 0x70, 0xD7, + 0x02, 0xD6, 0xED, 0x87, 0x18, 0x28, 0x2C, 0x04, 0x24, 0x4C, 0x77, 0xE4, + 0x48, 0x8A, 0x1A, 0xC6, 0x3B, 0x9A, 0xD4, 0x0F, 0xCA, 0xFA, 0x75, 0xD2, + 0x01, 0x40, 0x5A, 0x8D, 0x79, 0xBF, 0x8B, 0xCF, 0x4B, 0xCF, 0xAA, 0x16, + 0xC1, 0x95, 0xE4, 0xAD, 0x4C, 0x8A, 0x3E, 0x17, 0x91, 0xD4, 0xB1, 0x62, + 0xE5, 0x82, 0xE5, 0x80, 0x04, 0xA4, 0x03, 0x7E, 0x8D, 0xBF, 0xDA, 0x7F, + 0xA2, 0x0F, 0x97, 0x4F, 0x0C, 0xD3, 0x0D, 0xFB, 0xD7, 0xD1, 0xE5, 0x72, + 0x7E, 0x1C, 0xC8, 0x77, 0xFF, 0x5B, 0x9A, 0x0F, 0xB7, 0xAE, 0x05, 0x46, + 0xE5, 0xF1, 0xA8, 0x16, 0xEC, 0x47, 0xA4, 0x17 +}; + +static const unsigned char TA72_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA73_DN[] = { + 0x30, 0x7E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, 0x65, + 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, + 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, + 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, 0x65, + 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA73_RSA_N[] = { + 0xE3, 0xFB, 0x7D, 0xA3, 0x72, 0xBA, 0xC2, 0xF0, 0xC9, 0x14, 0x87, 0xF5, + 0x6B, 0x01, 0x4E, 0xE1, 0x6E, 0x40, 0x07, 0xBA, 0x6D, 0x27, 0x5D, 0x7F, + 0xF7, 0x5B, 0x2D, 0xB3, 0x5A, 0xC7, 0x51, 0x5F, 0xAB, 0xA4, 0x32, 0xA6, + 0x61, 0x87, 0xB6, 0x6E, 0x0F, 0x86, 0xD2, 0x30, 0x02, 0x97, 0xF8, 0xD7, + 0x69, 0x57, 0xA1, 0x18, 0x39, 0x5D, 0x6A, 0x64, 0x79, 0xC6, 0x01, 0x59, + 0xAC, 0x3C, 0x31, 0x4A, 0x38, 0x7C, 0xD2, 0x04, 0xD2, 0x4B, 0x28, 0xE8, + 0x20, 0x5F, 0x3B, 0x07, 0xA2, 0xCC, 0x4D, 0x73, 0xDB, 0xF3, 0xAE, 0x4F, + 0xC7, 0x56, 0xD5, 0x5A, 0xA7, 0x96, 0x89, 0xFA, 0xF3, 0xAB, 0x68, 0xD4, + 0x23, 0x86, 0x59, 0x27, 0xCF, 0x09, 0x27, 0xBC, 0xAC, 0x6E, 0x72, 0x83, + 0x1C, 0x30, 0x72, 0xDF, 0xE0, 0xA2, 0xE9, 0xD2, 0xE1, 0x74, 0x75, 0x19, + 0xBD, 0x2A, 0x9E, 0x7B, 0x15, 0x54, 0x04, 0x1B, 0xD7, 0x43, 0x39, 0xAD, + 0x55, 0x28, 0xC5, 0xE2, 0x1A, 0xBB, 0xF4, 0xC0, 0xE4, 0xAE, 0x38, 0x49, + 0x33, 0xCC, 0x76, 0x85, 0x9F, 0x39, 0x45, 0xD2, 0xA4, 0x9E, 0xF2, 0x12, + 0x8C, 0x51, 0xF8, 0x7C, 0xE4, 0x2D, 0x7F, 0xF5, 0xAC, 0x5F, 0xEB, 0x16, + 0x9F, 0xB1, 0x2D, 0xD1, 0xBA, 0xCC, 0x91, 0x42, 0x77, 0x4C, 0x25, 0xC9, + 0x90, 0x38, 0x6F, 0xDB, 0xF0, 0xCC, 0xFB, 0x8E, 0x1E, 0x97, 0x59, 0x3E, + 0xD5, 0x60, 0x4E, 0xE6, 0x05, 0x28, 0xED, 0x49, 0x79, 0x13, 0x4B, 0xBA, + 0x48, 0xDB, 0x2F, 0xF9, 0x72, 0xD3, 0x39, 0xCA, 0xFE, 0x1F, 0xD8, 0x34, + 0x72, 0xF5, 0xB4, 0x40, 0xCF, 0x31, 0x01, 0xC3, 0xEC, 0xDE, 0x11, 0x2D, + 0x17, 0x5D, 0x1F, 0xB8, 0x50, 0xD1, 0x5E, 0x19, 0xA7, 0x69, 0xDE, 0x07, + 0x33, 0x28, 0xCA, 0x50, 0x95, 0xF9, 0xA7, 0x54, 0xCB, 0x54, 0x86, 0x50, + 0x45, 0xA9, 0xF9, 0x49 +}; + +static const unsigned char TA73_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA74_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x43, 0x33 +}; + +static const unsigned char TA74_EC_Q[] = { + 0x04, 0xFD, 0xA5, 0x61, 0xAE, 0x7B, 0x26, 0x10, 0x1D, 0xE9, 0xB7, 0x22, + 0x30, 0xAE, 0x06, 0xF4, 0x81, 0xB3, 0xB1, 0x42, 0x71, 0x95, 0x39, 0xBC, + 0xD3, 0x52, 0xE3, 0xAF, 0xAF, 0xF9, 0xF2, 0x97, 0x35, 0x92, 0x36, 0x46, + 0x0E, 0x87, 0x95, 0x8D, 0xB9, 0x39, 0x5A, 0xE9, 0xBB, 0xDF, 0xD0, 0xFE, + 0xC8, 0x07, 0x41, 0x3C, 0xBB, 0x55, 0x6F, 0x83, 0xA3, 0x6A, 0xFB, 0x62, + 0xB0, 0x81, 0x89, 0x02, 0x70, 0x7D, 0x48, 0xC5, 0x4A, 0xE3, 0xE9, 0x22, + 0x54, 0x22, 0x4D, 0x93, 0xBB, 0x42, 0x0C, 0xAF, 0x77, 0x9C, 0x23, 0xA6, + 0x7D, 0xD7, 0x61, 0x11, 0xCE, 0x65, 0xC7, 0xF8, 0x7F, 0xFE, 0xF5, 0xF2, + 0xA9 +}; + +static const unsigned char TA75_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x53, 0x65, 0x63, 0x74, 0x6F, 0x72, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA75_RSA_N[] = { + 0xB6, 0x22, 0x94, 0xFC, 0xA4, 0x48, 0xAF, 0xE8, 0x47, 0x6B, 0x0A, 0xFB, + 0x27, 0x76, 0xE4, 0xF2, 0x3F, 0x8A, 0x3B, 0x7A, 0x4A, 0x2C, 0x31, 0x2A, + 0x8C, 0x8D, 0xB0, 0xA9, 0xC3, 0x31, 0x6B, 0xA8, 0x77, 0x76, 0x84, 0x26, + 0xB6, 0xAC, 0x81, 0x42, 0x0D, 0x08, 0xEB, 0x55, 0x58, 0xBB, 0x7A, 0xF8, + 0xBC, 0x65, 0x7D, 0xF2, 0xA0, 0x6D, 0x8B, 0xA8, 0x47, 0xE9, 0x62, 0x76, + 0x1E, 0x11, 0xEE, 0x08, 0x14, 0xD1, 0xB2, 0x44, 0x16, 0xF4, 0xEA, 0xD0, + 0xFA, 0x1E, 0x2F, 0x5E, 0xDB, 0xCB, 0x73, 0x41, 0xAE, 0xBC, 0x00, 0xB0, + 0x4A, 0x2B, 0x40, 0xB2, 0xAC, 0xE1, 0x3B, 0x4B, 0xC2, 0x2D, 0x9D, 0xE4, + 0xA1, 0x9B, 0xEC, 0x1A, 0x3A, 0x1E, 0xF0, 0x08, 0xB3, 0xD0, 0xE4, 0x24, + 0x35, 0x07, 0x9F, 0x9C, 0xB4, 0xC9, 0x52, 0x6D, 0xDB, 0x07, 0xCA, 0x8F, + 0xB5, 0x5B, 0xF0, 0x83, 0xF3, 0x4F, 0xC7, 0x2D, 0xA5, 0xC8, 0xAD, 0xCB, + 0x95, 0x20, 0xA4, 0x31, 0x28, 0x57, 0x58, 0x5A, 0xE4, 0x8D, 0x1B, 0x9A, + 0xAB, 0x9E, 0x0D, 0x0C, 0xF2, 0x0A, 0x33, 0x39, 0x22, 0x39, 0x0A, 0x97, + 0x2E, 0xF3, 0x53, 0x77, 0xB9, 0x44, 0x45, 0xFD, 0x84, 0xCB, 0x36, 0x20, + 0x81, 0x59, 0x2D, 0x9A, 0x6F, 0x6D, 0x48, 0x48, 0x61, 0xCA, 0x4C, 0xDF, + 0x53, 0xD1, 0xAF, 0x52, 0xBC, 0x44, 0x9F, 0xAB, 0x2F, 0x6B, 0x83, 0x72, + 0xEF, 0x75, 0x80, 0xDA, 0x06, 0x33, 0x1B, 0x5D, 0xC8, 0xDA, 0x63, 0xC6, + 0x4D, 0xCD, 0xAC, 0x66, 0x31, 0xCD, 0xD1, 0xDE, 0x3E, 0x87, 0x10, 0x36, + 0xE1, 0xB9, 0xA4, 0x7A, 0xEF, 0x60, 0x50, 0xB2, 0xCB, 0xCA, 0xA6, 0x56, + 0xE0, 0x37, 0xAF, 0xAB, 0x34, 0x13, 0x39, 0x25, 0xE8, 0x39, 0x66, 0xE4, + 0x98, 0x7A, 0xAA, 0x12, 0x98, 0x9C, 0x59, 0x66, 0x86, 0x3E, 0xAD, 0xF1, + 0xB0, 0xCA, 0x3E, 0x06, 0x0F, 0x7B, 0xF0, 0x11, 0x4B, 0x37, 0xA0, 0x44, + 0x6D, 0x7B, 0xCB, 0xA8, 0x8C, 0x71, 0xF4, 0xD5, 0xB5, 0x91, 0x36, 0xCC, + 0xF0, 0x15, 0xC6, 0x2B, 0xDE, 0x51, 0x17, 0xB1, 0x97, 0x4C, 0x50, 0x3D, + 0xB1, 0x95, 0x59, 0x7C, 0x05, 0x7D, 0x2D, 0x21, 0xD5, 0x00, 0xBF, 0x01, + 0x67, 0xA2, 0x5E, 0x7B, 0xA6, 0x5C, 0xF2, 0xF7, 0x22, 0xF1, 0x90, 0x0D, + 0x93, 0xDB, 0xAA, 0x44, 0x51, 0x66, 0xCC, 0x7D, 0x76, 0x03, 0xEB, 0x6A, + 0xA8, 0x2A, 0x38, 0x19, 0x97, 0x76, 0x0D, 0x6B, 0x8A, 0x61, 0xF9, 0xBC, + 0xF6, 0xEE, 0x76, 0xFD, 0x70, 0x2B, 0xDD, 0x29, 0x3C, 0xF8, 0x0A, 0x1E, + 0x5B, 0x42, 0x1C, 0x8B, 0x56, 0x2F, 0x55, 0x1B, 0x1C, 0xA1, 0x2E, 0xB5, + 0xC7, 0x16, 0xE6, 0xF8, 0xAA, 0x3C, 0x92, 0x8E, 0x69, 0xB6, 0x01, 0xC1, + 0xB5, 0x86, 0x9D, 0x89, 0x0F, 0x0B, 0x38, 0x94, 0x54, 0xE8, 0xEA, 0xDC, + 0x9E, 0x3D, 0x25, 0xBC, 0x53, 0x26, 0xED, 0xD5, 0xAB, 0x39, 0xAA, 0xC5, + 0x40, 0x4C, 0x54, 0xAB, 0xB2, 0xB4, 0xD9, 0xD9, 0xF8, 0xD7, 0x72, 0xDB, + 0x1C, 0xBC, 0x6D, 0xBD, 0x65, 0x5F, 0xEF, 0x88, 0x35, 0x2A, 0x66, 0x2F, + 0xEE, 0xF6, 0xB3, 0x65, 0xF0, 0x33, 0x8D, 0x7C, 0x98, 0x41, 0x69, 0x46, + 0x0F, 0x43, 0x1C, 0x69, 0xFA, 0x9B, 0xB5, 0xD0, 0x61, 0x6A, 0xCD, 0xCA, + 0x4B, 0xD9, 0x4C, 0x90, 0x46, 0xAB, 0x15, 0x59, 0xA1, 0x47, 0x54, 0x29, + 0x2E, 0x83, 0x28, 0x5F, 0x1C, 0xC2, 0xA2, 0xAB, 0x72, 0x17, 0x00, 0x06, + 0x8E, 0x45, 0xEC, 0x8B, 0xE2, 0x33, 0x3D, 0x7F, 0xDA, 0x19, 0x44, 0xE4, + 0x62, 0x72, 0xC3, 0xDF, 0x22, 0xC6, 0xF2, 0x56, 0xD4, 0xDD, 0x5F, 0x95, + 0x72, 0xED, 0x6D, 0x5F, 0xF7, 0x48, 0x03, 0x5B, 0xFD, 0xC5, 0x2A, 0xA0, + 0xF6, 0x73, 0x23, 0x84, 0x10, 0x1B, 0x01, 0xE7 +}; + +static const unsigned char TA75_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA76_DN[] = { + 0x30, 0x81, 0x8F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, + 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA76_RSA_N[] = { + 0xBD, 0xED, 0xC1, 0x03, 0xFC, 0xF6, 0x8F, 0xFC, 0x02, 0xB1, 0x6F, 0x5B, + 0x9F, 0x48, 0xD9, 0x9D, 0x79, 0xE2, 0xA2, 0xB7, 0x03, 0x61, 0x56, 0x18, + 0xC3, 0x47, 0xB6, 0xD7, 0xCA, 0x3D, 0x35, 0x2E, 0x89, 0x43, 0xF7, 0xA1, + 0x69, 0x9B, 0xDE, 0x8A, 0x1A, 0xFD, 0x13, 0x20, 0x9C, 0xB4, 0x49, 0x77, + 0x32, 0x29, 0x56, 0xFD, 0xB9, 0xEC, 0x8C, 0xDD, 0x22, 0xFA, 0x72, 0xDC, + 0x27, 0x61, 0x97, 0xEE, 0xF6, 0x5A, 0x84, 0xEC, 0x6E, 0x19, 0xB9, 0x89, + 0x2C, 0xDC, 0x84, 0x5B, 0xD5, 0x74, 0xFB, 0x6B, 0x5F, 0xC5, 0x89, 0xA5, + 0x10, 0x52, 0x89, 0x46, 0x55, 0xF4, 0xB8, 0x75, 0x1C, 0xE6, 0x7F, 0xE4, + 0x54, 0xAE, 0x4B, 0xF8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xF8, 0x17, 0x71, + 0x59, 0xEB, 0x1E, 0x28, 0x07, 0x74, 0xC5, 0x9D, 0x48, 0xBE, 0x6C, 0xB4, + 0xF4, 0xA4, 0xB0, 0xF3, 0x64, 0x37, 0x79, 0x92, 0xC0, 0xEC, 0x46, 0x5E, + 0x7F, 0xE1, 0x6D, 0x53, 0x4C, 0x62, 0xAF, 0xCD, 0x1F, 0x0B, 0x63, 0xBB, + 0x3A, 0x9D, 0xFB, 0xFC, 0x79, 0x00, 0x98, 0x61, 0x74, 0xCF, 0x26, 0x82, + 0x40, 0x63, 0xF3, 0xB2, 0x72, 0x6A, 0x19, 0x0D, 0x99, 0xCA, 0xD4, 0x0E, + 0x75, 0xCC, 0x37, 0xFB, 0x8B, 0x89, 0xC1, 0x59, 0xF1, 0x62, 0x7F, 0x5F, + 0xB3, 0x5F, 0x65, 0x30, 0xF8, 0xA7, 0xB7, 0x4D, 0x76, 0x5A, 0x1E, 0x76, + 0x5E, 0x34, 0xC0, 0xE8, 0x96, 0x56, 0x99, 0x8A, 0xB3, 0xF0, 0x7F, 0xA4, + 0xCD, 0xBD, 0xDC, 0x32, 0x31, 0x7C, 0x91, 0xCF, 0xE0, 0x5F, 0x11, 0xF8, + 0x6B, 0xAA, 0x49, 0x5C, 0xD1, 0x99, 0x94, 0xD1, 0xA2, 0xE3, 0x63, 0x5B, + 0x09, 0x76, 0xB5, 0x56, 0x62, 0xE1, 0x4B, 0x74, 0x1D, 0x96, 0xD4, 0x26, + 0xD4, 0x08, 0x04, 0x59, 0xD0, 0x98, 0x0E, 0x0E, 0xE6, 0xDE, 0xFC, 0xC3, + 0xEC, 0x1F, 0x90, 0xF1 +}; + +static const unsigned char TA76_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA77_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, + 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA77_EC_Q[] = { + 0x04, 0x38, 0x08, 0xFE, 0xB1, 0xA0, 0x96, 0xD2, 0x7A, 0xAC, 0xAF, 0x49, + 0x3A, 0xD0, 0xC0, 0xE0, 0xC3, 0x3B, 0x28, 0xAA, 0xF1, 0x72, 0x6D, 0x65, + 0x00, 0x47, 0x88, 0x84, 0xFC, 0x9A, 0x26, 0x6B, 0xAA, 0x4B, 0xBA, 0x6C, + 0x04, 0x0A, 0x88, 0x5E, 0x17, 0xF2, 0x55, 0x87, 0xFC, 0x30, 0xB0, 0x34, + 0xE2, 0x34, 0x58, 0x57, 0x1A, 0x84, 0x53, 0xE9, 0x30, 0xD9, 0xA9, 0xF2, + 0x96, 0x74, 0xC3, 0x51, 0x1F, 0x58, 0x49, 0x31, 0xCC, 0x98, 0x4E, 0x60, + 0x11, 0x87, 0x75, 0xD3, 0x72, 0x94, 0x90, 0x4F, 0x9B, 0x10, 0x25, 0x2A, + 0xA8, 0x78, 0x2D, 0xBE, 0x90, 0x41, 0x58, 0x90, 0x15, 0x72, 0xA7, 0xA1, + 0xB7 +}; + +static const unsigned char TA78_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x41, 0x47, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x16, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, + 0x6F, 0x6C, 0x64, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA78_RSA_N[] = { + 0xAF, 0xE4, 0xEE, 0x7E, 0x8B, 0x24, 0x0E, 0x12, 0x6E, 0xA9, 0x50, 0x2D, + 0x16, 0x44, 0x3B, 0x92, 0x92, 0x5C, 0xCA, 0xB8, 0x5D, 0x84, 0x92, 0x42, + 0x13, 0x2A, 0xBC, 0x65, 0x57, 0x82, 0x40, 0x3E, 0x57, 0x24, 0xCD, 0x50, + 0x8B, 0x25, 0x2A, 0xB7, 0x6F, 0xFC, 0xEF, 0xA2, 0xD0, 0xC0, 0x1F, 0x02, + 0x24, 0x4A, 0x13, 0x96, 0x8F, 0x23, 0x13, 0xE6, 0x28, 0x58, 0x00, 0xA3, + 0x47, 0xC7, 0x06, 0xA7, 0x84, 0x23, 0x2B, 0xBB, 0xBD, 0x96, 0x2B, 0x7F, + 0x55, 0xCC, 0x8B, 0xC1, 0x57, 0x1F, 0x0E, 0x62, 0x65, 0x0F, 0xDD, 0x3D, + 0x56, 0x8A, 0x73, 0xDA, 0xAE, 0x7E, 0x6D, 0xBA, 0x81, 0x1C, 0x7E, 0x42, + 0x8C, 0x20, 0x35, 0xD9, 0x43, 0x4D, 0x84, 0xFA, 0x84, 0xDB, 0x52, 0x2C, + 0xF3, 0x0E, 0x27, 0x77, 0x0B, 0x6B, 0xBF, 0x11, 0x2F, 0x72, 0x78, 0x9F, + 0x2E, 0xD8, 0x3E, 0xE6, 0x18, 0x37, 0x5A, 0x2A, 0x72, 0xF9, 0xDA, 0x62, + 0x90, 0x92, 0x95, 0xCA, 0x1F, 0x9C, 0xE9, 0xB3, 0x3C, 0x2B, 0xCB, 0xF3, + 0x01, 0x13, 0xBF, 0x5A, 0xCF, 0xC1, 0xB5, 0x0A, 0x60, 0xBD, 0xDD, 0xB5, + 0x99, 0x64, 0x53, 0xB8, 0xA0, 0x96, 0xB3, 0x6F, 0xE2, 0x26, 0x77, 0x91, + 0x8C, 0xE0, 0x62, 0x10, 0x02, 0x9F, 0x34, 0x0F, 0xA4, 0xD5, 0x92, 0x33, + 0x51, 0xDE, 0xBE, 0x8D, 0xBA, 0x84, 0x7A, 0x60, 0x3C, 0x6A, 0xDB, 0x9F, + 0x2B, 0xEC, 0xDE, 0xDE, 0x01, 0x3F, 0x6E, 0x4D, 0xE5, 0x50, 0x86, 0xCB, + 0xB4, 0xAF, 0xED, 0x44, 0x40, 0xC5, 0xCA, 0x5A, 0x8C, 0xDA, 0xD2, 0x2B, + 0x7C, 0xA8, 0xEE, 0xBE, 0xA6, 0xE5, 0x0A, 0xAA, 0x0E, 0xA5, 0xDF, 0x05, + 0x52, 0xB7, 0x55, 0xC7, 0x22, 0x5D, 0x32, 0x6A, 0x97, 0x97, 0x63, 0x13, + 0xDB, 0xC9, 0xDB, 0x79, 0x36, 0x7B, 0x85, 0x3A, 0x4A, 0xC5, 0x52, 0x89, + 0xF9, 0x24, 0xE7, 0x9D, 0x77, 0xA9, 0x82, 0xFF, 0x55, 0x1C, 0xA5, 0x71, + 0x69, 0x2B, 0xD1, 0x02, 0x24, 0xF2, 0xB3, 0x26, 0xD4, 0x6B, 0xDA, 0x04, + 0x55, 0xE5, 0xC1, 0x0A, 0xC7, 0x6D, 0x30, 0x37, 0x90, 0x2A, 0xE4, 0x9E, + 0x14, 0x33, 0x5E, 0x16, 0x17, 0x55, 0xC5, 0x5B, 0xB5, 0xCB, 0x34, 0x89, + 0x92, 0xF1, 0x9D, 0x26, 0x8F, 0xA1, 0x07, 0xD4, 0xC6, 0xB2, 0x78, 0x50, + 0xDB, 0x0C, 0x0C, 0x0B, 0x7C, 0x0B, 0x8C, 0x41, 0xD7, 0xB9, 0xE9, 0xDD, + 0x8C, 0x88, 0xF7, 0xA3, 0x4D, 0xB2, 0x32, 0xCC, 0xD8, 0x17, 0xDA, 0xCD, + 0xB7, 0xCE, 0x66, 0x9D, 0xD4, 0xFD, 0x5E, 0xFF, 0xBD, 0x97, 0x3E, 0x29, + 0x75, 0xE7, 0x7E, 0xA7, 0x62, 0x58, 0xAF, 0x25, 0x34, 0xA5, 0x41, 0xC7, + 0x3D, 0xBC, 0x0D, 0x50, 0xCA, 0x03, 0x03, 0x0F, 0x08, 0x5A, 0x1F, 0x95, + 0x73, 0x78, 0x62, 0xBF, 0xAF, 0x72, 0x14, 0x69, 0x0E, 0xA5, 0xE5, 0x03, + 0x0E, 0x78, 0x8E, 0x26, 0x28, 0x42, 0xF0, 0x07, 0x0B, 0x62, 0x20, 0x10, + 0x67, 0x39, 0x46, 0xFA, 0xA9, 0x03, 0xCC, 0x04, 0x38, 0x7A, 0x66, 0xEF, + 0x20, 0x83, 0xB5, 0x8C, 0x4A, 0x56, 0x8E, 0x91, 0x00, 0xFC, 0x8E, 0x5C, + 0x82, 0xDE, 0x88, 0xA0, 0xC3, 0xE2, 0x68, 0x6E, 0x7D, 0x8D, 0xEF, 0x3C, + 0xDD, 0x65, 0xF4, 0x5D, 0xAC, 0x51, 0xEF, 0x24, 0x80, 0xAE, 0xAA, 0x56, + 0x97, 0x6F, 0xF9, 0xAD, 0x7D, 0xDA, 0x61, 0x3F, 0x98, 0x77, 0x3C, 0xA5, + 0x91, 0xB6, 0x1C, 0x8C, 0x26, 0xDA, 0x65, 0xA2, 0x09, 0x6D, 0xC1, 0xE2, + 0x54, 0xE3, 0xB9, 0xCA, 0x4C, 0x4C, 0x80, 0x8F, 0x77, 0x7B, 0x60, 0x9A, + 0x1E, 0xDF, 0xB6, 0xF2, 0x48, 0x1E, 0x0E, 0xBA, 0x4E, 0x54, 0x6D, 0x98, + 0xE0, 0xE1, 0xA2, 0x1A, 0xA2, 0x77, 0x50, 0xCF, 0xC4, 0x63, 0x92, 0xEC, + 0x47, 0x19, 0x9D, 0xEB, 0xE6, 0x6B, 0xCE, 0xC1 +}; + +static const unsigned char TA78_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA79_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA79_RSA_N[] = { + 0xE1, 0xFA, 0x0E, 0xFB, 0x68, 0x00, 0x12, 0xC8, 0x4D, 0xD5, 0xAC, 0x22, + 0xC4, 0x35, 0x01, 0x3B, 0xC5, 0x54, 0xE5, 0x59, 0x76, 0x63, 0xA5, 0x7F, + 0xEB, 0xC1, 0xC4, 0x6A, 0x98, 0xBD, 0x32, 0x8D, 0x17, 0x80, 0xEB, 0x5D, + 0xBA, 0xD1, 0x62, 0x3D, 0x25, 0x23, 0x19, 0x35, 0x14, 0xE9, 0x7F, 0x89, + 0xA7, 0x1B, 0x62, 0x3C, 0xD6, 0x50, 0xE7, 0x34, 0x95, 0x03, 0x32, 0xB1, + 0xB4, 0x93, 0x22, 0x3D, 0xA7, 0xE2, 0xB1, 0xED, 0xE6, 0x7B, 0x4E, 0x2E, + 0x87, 0x9B, 0x0D, 0x33, 0x75, 0x0A, 0xDE, 0xAA, 0x35, 0xE7, 0x7E, 0xE5, + 0x36, 0x98, 0xA2, 0xAE, 0x25, 0x9E, 0x95, 0xB3, 0x32, 0x96, 0xA4, 0x2B, + 0x58, 0x1E, 0xEF, 0x3F, 0xFE, 0x62, 0x34, 0x48, 0x51, 0xD1, 0xB4, 0x8D, + 0x42, 0xAD, 0x60, 0xDA, 0x49, 0x6A, 0x95, 0x70, 0xDD, 0xD2, 0x00, 0xE2, + 0xCC, 0x57, 0x63, 0x02, 0x7B, 0x96, 0xDD, 0x49, 0x97, 0x5B, 0x92, 0x4E, + 0x95, 0xD3, 0xF9, 0xCB, 0x29, 0x1F, 0x18, 0x4A, 0xF8, 0x01, 0x2A, 0xD2, + 0x63, 0x09, 0x6E, 0x24, 0xE9, 0x89, 0xD2, 0xE5, 0xC7, 0x22, 0x4C, 0xDC, + 0x73, 0x86, 0x47, 0x00, 0xAA, 0x0D, 0x88, 0x8E, 0xAE, 0x85, 0x7D, 0x4A, + 0xE9, 0xBB, 0x33, 0x4F, 0x0E, 0x52, 0x70, 0x9D, 0x95, 0xE3, 0x7C, 0x6D, + 0x96, 0x5B, 0x2D, 0x3D, 0x5F, 0xA1, 0x83, 0x46, 0x5D, 0xB6, 0xE3, 0x25, + 0xB8, 0x7C, 0xA7, 0x19, 0x80, 0x1C, 0xEA, 0x65, 0x43, 0xDC, 0x91, 0x79, + 0x36, 0x2C, 0x74, 0x7C, 0xF2, 0x67, 0x06, 0xC9, 0x89, 0xC9, 0xDB, 0xBF, + 0xDA, 0x68, 0xBF, 0x23, 0xED, 0xDC, 0x6B, 0xAD, 0x28, 0x83, 0x79, 0x2F, + 0xEC, 0x38, 0xA5, 0x0D, 0x37, 0x01, 0x67, 0x27, 0x9A, 0xE9, 0x33, 0xD9, + 0x33, 0x5F, 0x37, 0xA1, 0xC5, 0xF0, 0xAB, 0x3D, 0xFA, 0x78, 0xB0, 0xE7, + 0x2C, 0x9F, 0xF6, 0x3E, 0x9F, 0x60, 0xE0, 0xEF, 0x48, 0xE9, 0x90, 0x45, + 0x1E, 0x05, 0x51, 0x78, 0x1A, 0x2C, 0x12, 0x2C, 0x5C, 0x28, 0xAC, 0x0D, + 0xA2, 0x23, 0x9E, 0x34, 0x8F, 0x05, 0xE6, 0xA2, 0x33, 0xCE, 0x11, 0x77, + 0x13, 0xD4, 0x0E, 0xA4, 0x1E, 0x42, 0x1F, 0x86, 0xCD, 0x70, 0xFE, 0xD9, + 0x2E, 0x15, 0x3D, 0x1D, 0xBB, 0xB8, 0xF2, 0x53, 0x57, 0xDB, 0xCC, 0xC6, + 0x74, 0x29, 0x9C, 0x18, 0xB3, 0x36, 0x75, 0x38, 0x2E, 0x0F, 0x54, 0xA1, + 0xF8, 0x92, 0x1F, 0x89, 0x96, 0x4F, 0xBB, 0xD4, 0xEE, 0x9D, 0xE9, 0x3B, + 0x36, 0x42, 0xB5, 0x0A, 0x3B, 0x2A, 0xD4, 0x64, 0x79, 0x36, 0x10, 0xE1, + 0xF9, 0x91, 0x03, 0x2B, 0x7B, 0x20, 0x54, 0xCD, 0x0D, 0x19, 0x1A, 0xC8, + 0x41, 0x32, 0x34, 0xD1, 0xB0, 0x99, 0xE1, 0x90, 0x1E, 0x01, 0x40, 0x36, + 0xB5, 0xB7, 0xFA, 0xA9, 0xE5, 0x77, 0x75, 0xA4, 0x22, 0x81, 0x5D, 0xB0, + 0x8B, 0xE4, 0x27, 0x12, 0x0F, 0x54, 0x88, 0xC6, 0xDB, 0x85, 0x74, 0xE6, + 0xB7, 0xC0, 0xD7, 0xA6, 0x29, 0xFA, 0xDB, 0xDE, 0xF3, 0x93, 0x97, 0x27, + 0x04, 0x55, 0x2F, 0x0A, 0x6F, 0x37, 0xC5, 0x3D, 0x13, 0xAF, 0x0A, 0x00, + 0xA9, 0x2C, 0x8B, 0x1C, 0x81, 0x28, 0xD7, 0xEF, 0x86, 0x31, 0xA9, 0xAE, + 0xF2, 0x6E, 0xB8, 0xCA, 0x6A, 0x2C, 0x54, 0x47, 0xD8, 0x2A, 0x88, 0x2E, + 0xAF, 0xC1, 0x07, 0x10, 0x78, 0xAC, 0x11, 0xA2, 0x2F, 0x42, 0xF0, 0x37, + 0xC5, 0xF2, 0xB8, 0x56, 0xDD, 0x0E, 0x62, 0x2D, 0xCE, 0x2D, 0x56, 0x7E, + 0x55, 0xF2, 0xA7, 0x44, 0xF6, 0x2B, 0x32, 0xF4, 0x23, 0xA8, 0x47, 0xE8, + 0xD4, 0x2A, 0x01, 0x78, 0xCF, 0x6A, 0xC3, 0x37, 0xA8, 0x9E, 0x65, 0xD2, + 0x2C, 0xE5, 0xFA, 0xBA, 0x33, 0xC1, 0x06, 0x44, 0xF6, 0xE6, 0xCF, 0xA5, + 0x0D, 0xA7, 0x66, 0x08, 0x34, 0x8A, 0x2C, 0xF3 +}; + +static const unsigned char TA79_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA80_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA80_RSA_N[] = { + 0xA0, 0xBE, 0x50, 0x10, 0x8E, 0xE9, 0xF2, 0x6C, 0x40, 0xB4, 0x04, 0x9C, + 0x85, 0xB9, 0x31, 0xCA, 0xDC, 0x2D, 0xE4, 0x11, 0xA9, 0x04, 0x3C, 0x1B, + 0x55, 0xC1, 0xE7, 0x58, 0x30, 0x1D, 0x24, 0xB4, 0xC3, 0xEF, 0x85, 0xDE, + 0x8C, 0x2C, 0xE1, 0xC1, 0x3D, 0xDF, 0x82, 0xE6, 0x4F, 0xAD, 0x47, 0x87, + 0x6C, 0xEC, 0x5B, 0x49, 0xC1, 0x4A, 0xD5, 0xBB, 0x8F, 0xEC, 0x87, 0xAC, + 0x7F, 0x82, 0x9A, 0x86, 0xEC, 0x3D, 0x03, 0x99, 0x52, 0x01, 0xD2, 0x35, + 0x9E, 0xAC, 0xDA, 0xF0, 0x53, 0xC9, 0x66, 0x3C, 0xD4, 0xAC, 0x02, 0x01, + 0xDA, 0x24, 0xD3, 0x3B, 0xA8, 0x02, 0x46, 0xAF, 0xA4, 0x1C, 0xE3, 0xF8, + 0x73, 0x58, 0x76, 0xB7, 0xF6, 0x0E, 0x90, 0x0D, 0xB5, 0xF0, 0xCF, 0xCC, + 0xFA, 0xF9, 0xC6, 0x4C, 0xE5, 0xC3, 0x86, 0x30, 0x0A, 0x8D, 0x17, 0x7E, + 0x35, 0xEB, 0xC5, 0xDF, 0xBB, 0x0E, 0x9C, 0xC0, 0x8D, 0x87, 0xE3, 0x88, + 0x38, 0x85, 0x67, 0xFA, 0x3E, 0xC7, 0xAB, 0xE0, 0x13, 0x9C, 0x05, 0x18, + 0x98, 0xCF, 0x93, 0xF5, 0xB1, 0x92, 0xB4, 0xFC, 0x23, 0xD3, 0xCF, 0xD5, + 0xC4, 0x27, 0x49, 0xE0, 0x9E, 0x3C, 0x9B, 0x08, 0xA3, 0x8B, 0x5D, 0x2A, + 0x21, 0xE0, 0xFC, 0x39, 0xAA, 0x53, 0xDA, 0x7D, 0x7E, 0xCF, 0x1A, 0x09, + 0x53, 0xBC, 0x5D, 0x05, 0x04, 0xCF, 0xA1, 0x4A, 0x8F, 0x8B, 0x76, 0x82, + 0x0D, 0xA1, 0xF8, 0xD2, 0xC7, 0x14, 0x77, 0x5B, 0x90, 0x36, 0x07, 0x81, + 0x9B, 0x3E, 0x06, 0xFA, 0x52, 0x5E, 0x63, 0xC5, 0xA6, 0x00, 0xFE, 0xA5, + 0xE9, 0x52, 0x1B, 0x52, 0xB5, 0x92, 0x39, 0x72, 0x03, 0x09, 0x62, 0xBD, + 0xB0, 0x60, 0x16, 0x6E, 0xA6, 0xDD, 0x25, 0xC2, 0x03, 0x66, 0xDD, 0xF3, + 0x04, 0xD1, 0x40, 0xE2, 0x4E, 0x8B, 0x86, 0xF4, 0x6F, 0xE5, 0x83, 0xA0, + 0x27, 0x84, 0x5E, 0x04, 0xC1, 0xF5, 0x90, 0xBD, 0x30, 0x3D, 0xC4, 0xEF, + 0xA8, 0x69, 0xBC, 0x38, 0x9B, 0xA4, 0xA4, 0x96, 0xD1, 0x62, 0xDA, 0x69, + 0xC0, 0x01, 0x96, 0xAE, 0xCB, 0xC4, 0x51, 0x34, 0xEA, 0x0C, 0xAA, 0xFF, + 0x21, 0x8E, 0x59, 0x8F, 0x4A, 0x5C, 0xE4, 0x61, 0x9A, 0xA7, 0xD2, 0xE9, + 0x2A, 0x78, 0x8D, 0x51, 0x3D, 0x3A, 0x15, 0xEE, 0xA2, 0x59, 0x8E, 0xA9, + 0x5C, 0xDE, 0xC5, 0xF9, 0x90, 0x22, 0xE5, 0x88, 0x45, 0x71, 0xDD, 0x91, + 0x99, 0x6C, 0x7A, 0x9F, 0x3D, 0x3D, 0x98, 0x7C, 0x5E, 0xF6, 0xBE, 0x16, + 0x68, 0xA0, 0x5E, 0xAE, 0x0B, 0x23, 0xFC, 0x5A, 0x0F, 0xAA, 0x22, 0x76, + 0x2D, 0xC9, 0xA1, 0x10, 0x1D, 0xE4, 0xD3, 0x44, 0x23, 0x90, 0x88, 0x9F, + 0xC6, 0x2A, 0xE6, 0xD7, 0xF5, 0x9A, 0xB3, 0x58, 0x1E, 0x2F, 0x30, 0x89, + 0x08, 0x1B, 0x54, 0xA2, 0xB5, 0x98, 0x23, 0xEC, 0x08, 0x77, 0x1C, 0x95, + 0x5D, 0x61, 0xD1, 0xCB, 0x89, 0x9C, 0x5F, 0xA2, 0x4A, 0x91, 0x9A, 0xEF, + 0x21, 0xAA, 0x49, 0x16, 0x08, 0xA8, 0xBD, 0x61, 0x28, 0x31, 0xC9, 0x74, + 0xAD, 0x85, 0xF6, 0xD9, 0xC5, 0xB1, 0x8B, 0xD1, 0xE5, 0x10, 0x32, 0x4D, + 0x5F, 0x8B, 0x20, 0x3A, 0x3C, 0x49, 0x1F, 0x33, 0x85, 0x59, 0x0D, 0xDB, + 0xCB, 0x09, 0x75, 0x43, 0x69, 0x73, 0xFB, 0x6B, 0x71, 0x7D, 0xF0, 0xDF, + 0xC4, 0x4C, 0x7D, 0xC6, 0xA3, 0x2E, 0xC8, 0x95, 0x79, 0xCB, 0x73, 0xA2, + 0x8E, 0x4E, 0x4D, 0x24, 0xFB, 0x5E, 0xE4, 0x04, 0xBE, 0x72, 0x1B, 0xA6, + 0x27, 0x2D, 0x49, 0x5A, 0x99, 0x7A, 0xD7, 0x5C, 0x09, 0x20, 0xB7, 0x7F, + 0x94, 0xB9, 0x4F, 0xF1, 0x0D, 0x1C, 0x5E, 0x88, 0x42, 0x1B, 0x11, 0xB7, + 0xE7, 0x91, 0xDB, 0x9E, 0x6C, 0xF4, 0x6A, 0xDF, 0x8C, 0x06, 0x98, 0x03, + 0xAD, 0xCC, 0x28, 0xEF, 0xA5, 0x47, 0xF3, 0x53 +}; + +static const unsigned char TA80_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA81_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x12, 0x48, 0x69, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA81_RSA_N[] = { + 0xF4, 0x1E, 0x7F, 0x52, 0x73, 0x32, 0x0C, 0x73, 0xE4, 0xBD, 0x13, 0x74, + 0xA3, 0xD4, 0x30, 0xA8, 0xD0, 0xAE, 0x4B, 0xD8, 0xB6, 0xDF, 0x75, 0x47, + 0x66, 0xF4, 0x7C, 0xE7, 0x39, 0x04, 0x1E, 0x6A, 0x70, 0x20, 0xD2, 0x5A, + 0x47, 0x72, 0x67, 0x55, 0xF4, 0xA5, 0xE8, 0x9D, 0xD5, 0x1E, 0x21, 0xA1, + 0xF0, 0x67, 0xBA, 0xCC, 0x21, 0x68, 0xBE, 0x44, 0x53, 0xBF, 0x8D, 0xF9, + 0xE2, 0xDC, 0x2F, 0x55, 0xC8, 0x37, 0x3F, 0x1F, 0xA4, 0xC0, 0x9C, 0xB3, + 0xE4, 0x77, 0x5C, 0xA0, 0x46, 0xFE, 0x77, 0xFA, 0x1A, 0xA0, 0x38, 0xEA, + 0xED, 0x9A, 0x72, 0xDE, 0x2B, 0xBD, 0x94, 0x57, 0x3A, 0xBA, 0xEC, 0x79, + 0xE7, 0x5F, 0x7D, 0x42, 0x64, 0x39, 0x7A, 0x26, 0x36, 0xF7, 0x24, 0xF0, + 0xD5, 0x2F, 0xBA, 0x95, 0x98, 0x11, 0x66, 0xAD, 0x97, 0x35, 0xD6, 0x75, + 0x01, 0x80, 0xE0, 0xAF, 0xF4, 0x84, 0x61, 0x8C, 0x0D, 0x1E, 0x5F, 0x7C, + 0x87, 0x96, 0x5E, 0x41, 0xAF, 0xEB, 0x87, 0xEA, 0xF8, 0x5D, 0xF1, 0x2E, + 0x88, 0x05, 0x3E, 0x4C, 0x22, 0xBB, 0xDA, 0x1F, 0x2A, 0xDD, 0x52, 0x46, + 0x64, 0x39, 0xF3, 0x42, 0xCE, 0xD9, 0x9E, 0x0C, 0xB3, 0xB0, 0x77, 0x97, + 0x64, 0x9C, 0xC0, 0xF4, 0xA3, 0x2E, 0x1F, 0x95, 0x07, 0xB0, 0x17, 0xDF, + 0x30, 0xDB, 0x00, 0x18, 0x96, 0x4C, 0xA1, 0x81, 0x4B, 0xDD, 0x04, 0x6D, + 0x53, 0xA3, 0x3D, 0xFC, 0x07, 0xAC, 0xD4, 0xC5, 0x37, 0x82, 0xEB, 0xE4, + 0x95, 0x08, 0x19, 0x28, 0x82, 0xD2, 0x42, 0x3A, 0xA3, 0xD8, 0x53, 0xEC, + 0x79, 0x89, 0x60, 0x48, 0x60, 0xC8, 0x72, 0x92, 0x50, 0xDC, 0x03, 0x8F, + 0x83, 0x3F, 0xB2, 0x42, 0x57, 0x5A, 0xDB, 0x6A, 0xE9, 0x11, 0x97, 0xDD, + 0x85, 0x28, 0xBC, 0x30, 0x4C, 0xAB, 0xE3, 0xC2, 0xB1, 0x45, 0x44, 0x47, + 0x1F, 0xE0, 0x8A, 0x16, 0x07, 0x96, 0xD2, 0x21, 0x0F, 0x53, 0xC0, 0xED, + 0xA9, 0x7E, 0xD4, 0x4E, 0xEC, 0x9B, 0x09, 0xEC, 0xAF, 0x42, 0xAC, 0x30, + 0xD6, 0xBF, 0xD1, 0x10, 0x45, 0xE0, 0xA6, 0x16, 0xB2, 0xA5, 0xC5, 0xD3, + 0x4F, 0x73, 0x94, 0x33, 0x71, 0x02, 0xA1, 0x6A, 0xA3, 0xD6, 0x33, 0x97, + 0x4F, 0x21, 0x63, 0x1E, 0x5B, 0x8F, 0xD9, 0xC1, 0x5E, 0x45, 0x71, 0x77, + 0x0F, 0x81, 0x5D, 0x5F, 0x21, 0x9A, 0xAD, 0x83, 0xCC, 0xFA, 0x5E, 0xD6, + 0x8D, 0x23, 0x5F, 0x1B, 0x3D, 0x41, 0xAF, 0x20, 0x75, 0x66, 0x5A, 0x4A, + 0xF6, 0x9F, 0xFB, 0xAB, 0x18, 0xF7, 0x71, 0xC0, 0xB6, 0x1D, 0x31, 0xEC, + 0x3B, 0x20, 0xEB, 0xCB, 0xE2, 0xB8, 0xF5, 0xAE, 0x92, 0xB2, 0xF7, 0xE1, + 0x84, 0x4B, 0xF2, 0xA2, 0xF2, 0x93, 0x9A, 0x22, 0x9E, 0xD3, 0x14, 0x6F, + 0x36, 0x54, 0xBD, 0x1F, 0x5E, 0x59, 0x15, 0xB9, 0x73, 0xA8, 0xC1, 0x7C, + 0x6F, 0x7B, 0x62, 0xE9, 0x16, 0x6C, 0x47, 0x5A, 0x65, 0xF3, 0x0E, 0x11, + 0x9B, 0x46, 0xD9, 0xFD, 0x6D, 0xDC, 0xD6, 0x9C, 0xC0, 0xB4, 0x7D, 0xA5, + 0xB0, 0xDD, 0x3F, 0x56, 0x6F, 0xA1, 0xF9, 0xF6, 0xE4, 0x12, 0x48, 0xFD, + 0x06, 0x7F, 0x12, 0x57, 0xB6, 0xA9, 0x23, 0x4F, 0x5B, 0x03, 0xC3, 0xE0, + 0x71, 0x2A, 0x23, 0xB7, 0xF7, 0xB0, 0xB1, 0x3B, 0xBC, 0x98, 0xBD, 0xD6, + 0x98, 0xA8, 0x0C, 0x6B, 0xF6, 0x8E, 0x12, 0x67, 0xA6, 0xF2, 0xB2, 0x58, + 0xE4, 0x02, 0x09, 0x13, 0x3C, 0xA9, 0xBB, 0x10, 0xB4, 0xD2, 0x30, 0x45, + 0xF1, 0xEC, 0xF7, 0x00, 0x11, 0xDF, 0x65, 0xF8, 0xDC, 0x2B, 0x43, 0x55, + 0xBF, 0x16, 0x97, 0xC4, 0x0F, 0xD5, 0x2C, 0x61, 0x84, 0xAA, 0x72, 0x86, + 0xFE, 0xE6, 0x3A, 0x7E, 0xC2, 0x3F, 0x7D, 0xEE, 0xFC, 0x2F, 0x14, 0x3E, + 0xE6, 0x85, 0xDD, 0x50, 0x6F, 0xB7, 0x49, 0xED +}; + +static const unsigned char TA81_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA82_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x33 +}; + +static const unsigned char TA82_RSA_N[] = { + 0xBD, 0x75, 0x93, 0xF0, 0x62, 0x22, 0x6F, 0x24, 0xAE, 0xE0, 0x7A, 0x76, + 0xAC, 0x7D, 0xBD, 0xD9, 0x24, 0xD5, 0xB8, 0xB7, 0xFC, 0xCD, 0xF0, 0x42, + 0xE0, 0xEB, 0x78, 0x88, 0x56, 0x5E, 0x9B, 0x9A, 0x54, 0x1D, 0x4D, 0x0C, + 0x8A, 0xF6, 0xD3, 0xCF, 0x70, 0xF4, 0x52, 0xB5, 0xD8, 0x93, 0x04, 0xE3, + 0x46, 0x86, 0x71, 0x41, 0x4A, 0x2B, 0xF0, 0x2A, 0x2C, 0x55, 0x03, 0xD6, + 0x48, 0xC3, 0xE0, 0x39, 0x38, 0xED, 0xF2, 0x5C, 0x3C, 0x3F, 0x44, 0xBC, + 0x93, 0x3D, 0x61, 0xAB, 0x4E, 0xCD, 0x0D, 0xBE, 0xF0, 0x20, 0x27, 0x58, + 0x0E, 0x44, 0x7F, 0x04, 0x1A, 0x87, 0xA5, 0xD7, 0x96, 0x14, 0x36, 0x90, + 0xD0, 0x49, 0x7B, 0xA1, 0x75, 0xFB, 0x1A, 0x6B, 0x73, 0xB1, 0xF8, 0xCE, + 0xA9, 0x09, 0x2C, 0xF2, 0x53, 0xD5, 0xC3, 0x14, 0x44, 0xB8, 0x86, 0xA5, + 0xF6, 0x8B, 0x2B, 0x39, 0xDA, 0xA3, 0x33, 0x54, 0xD9, 0xFA, 0x72, 0x1A, + 0xF7, 0x22, 0x15, 0x1C, 0x88, 0x91, 0x6B, 0x7F, 0x66, 0xE5, 0xC3, 0x6A, + 0x80, 0xB0, 0x24, 0xF3, 0xDF, 0x86, 0x45, 0x88, 0xFD, 0x19, 0x7F, 0x75, + 0x87, 0x1F, 0x1F, 0xB1, 0x1B, 0x0A, 0x73, 0x24, 0x5B, 0xB9, 0x65, 0xE0, + 0x2C, 0x54, 0xC8, 0x60, 0xD3, 0x66, 0x17, 0x3F, 0xE1, 0xCC, 0x54, 0x33, + 0x73, 0x91, 0x02, 0x3A, 0xA6, 0x7F, 0x7B, 0x76, 0x39, 0xA2, 0x1F, 0x96, + 0xB6, 0x38, 0xAE, 0xB5, 0xC8, 0x93, 0x74, 0x1D, 0x9E, 0xB9, 0xB4, 0xE5, + 0x60, 0x9D, 0x2F, 0x56, 0xD1, 0xE0, 0xEB, 0x5E, 0x5B, 0x4C, 0x12, 0x70, + 0x0C, 0x6C, 0x44, 0x20, 0xAB, 0x11, 0xD8, 0xF4, 0x19, 0xF6, 0xD2, 0x9C, + 0x52, 0x37, 0xE7, 0xFA, 0xB6, 0xC2, 0x31, 0x3B, 0x4A, 0xD4, 0x14, 0x99, + 0xAD, 0xC7, 0x1A, 0xF5, 0x5D, 0x5F, 0xFA, 0x07, 0xB8, 0x7C, 0x0D, 0x1F, + 0xD6, 0x83, 0x1E, 0xB3 +}; + +static const unsigned char TA82_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA83_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA83_RSA_N[] = { + 0xD7, 0xC7, 0x5E, 0xF7, 0xC1, 0x07, 0xD4, 0x77, 0xFB, 0x43, 0x21, 0xF4, + 0xF4, 0xF5, 0x69, 0xE4, 0xEE, 0x32, 0x01, 0xDB, 0xA3, 0x86, 0x1F, 0xE4, + 0x59, 0x0D, 0xBA, 0xE7, 0x75, 0x83, 0x52, 0xEB, 0xEA, 0x1C, 0x61, 0x15, + 0x48, 0xBB, 0x1D, 0x07, 0xCA, 0x8C, 0xAE, 0xB0, 0xDC, 0x96, 0x9D, 0xEA, + 0xC3, 0x60, 0x92, 0x86, 0x82, 0x28, 0x73, 0x9C, 0x56, 0x06, 0xFF, 0x4B, + 0x64, 0xF0, 0x0C, 0x2A, 0x37, 0x49, 0xB5, 0xE5, 0xCF, 0x0C, 0x7C, 0xEE, + 0xF1, 0x4A, 0xBB, 0x73, 0x30, 0x65, 0xF3, 0xD5, 0x2F, 0x83, 0xB6, 0x7E, + 0xE3, 0xE7, 0xF5, 0x9E, 0xAB, 0x60, 0xF9, 0xD3, 0xF1, 0x9D, 0x92, 0x74, + 0x8A, 0xE4, 0x1C, 0x96, 0xAC, 0x5B, 0x80, 0xE9, 0xB5, 0xF4, 0x31, 0x87, + 0xA3, 0x51, 0xFC, 0xC7, 0x7E, 0xA1, 0x6F, 0x8E, 0x53, 0x77, 0xD4, 0x97, + 0xC1, 0x55, 0x33, 0x92, 0x3E, 0x18, 0x2F, 0x75, 0xD4, 0xAD, 0x86, 0x49, + 0xCB, 0x95, 0xAF, 0x54, 0x06, 0x6C, 0xD8, 0x06, 0x13, 0x8D, 0x5B, 0xFF, + 0xE1, 0x26, 0x19, 0x59, 0xC0, 0x24, 0xBA, 0x81, 0x71, 0x79, 0x90, 0x44, + 0x50, 0x68, 0x24, 0x94, 0x5F, 0xB8, 0xB3, 0x11, 0xF1, 0x29, 0x41, 0x61, + 0xA3, 0x41, 0xCB, 0x23, 0x36, 0xD5, 0xC1, 0xF1, 0x32, 0x50, 0x10, 0x4E, + 0x7F, 0xF4, 0x86, 0x93, 0xEC, 0x84, 0xD3, 0x8E, 0xBC, 0x4B, 0xBF, 0x5C, + 0x01, 0x4E, 0x07, 0x3D, 0xDC, 0x14, 0x8A, 0x94, 0x0A, 0xA4, 0xEA, 0x73, + 0xFB, 0x0B, 0x51, 0xE8, 0x13, 0x07, 0x18, 0xFA, 0x0E, 0xF1, 0x2B, 0xD1, + 0x54, 0x15, 0x7D, 0x3C, 0xE1, 0xF7, 0xB4, 0x19, 0x42, 0x67, 0x62, 0x5E, + 0x77, 0xE0, 0xA2, 0x55, 0xEC, 0xB6, 0xD9, 0x69, 0x17, 0xD5, 0x3A, 0xAF, + 0x44, 0xED, 0x4A, 0xC5, 0x9E, 0xE4, 0x7A, 0x27, 0x7C, 0xE5, 0x75, 0xD7, + 0xAA, 0xCB, 0x25, 0xE7, 0xDF, 0x6B, 0x0A, 0xDB, 0x0F, 0x4D, 0x93, 0x4E, + 0xA8, 0xA0, 0xCD, 0x7B, 0x2E, 0xF2, 0x59, 0x01, 0x6A, 0xB7, 0x0D, 0xB8, + 0x07, 0x81, 0x7E, 0x8B, 0x38, 0x1B, 0x38, 0xE6, 0x0A, 0x57, 0x99, 0x3D, + 0xEE, 0x21, 0xE8, 0xA3, 0xF5, 0x0C, 0x16, 0xDD, 0x8B, 0xEC, 0x34, 0x8E, + 0x9C, 0x2A, 0x1C, 0x00, 0x15, 0x17, 0x8D, 0x68, 0x83, 0xD2, 0x70, 0x9F, + 0x18, 0x08, 0xCD, 0x11, 0x68, 0xD5, 0xC9, 0x6B, 0x52, 0xCD, 0xC4, 0x46, + 0x8F, 0xDC, 0xB5, 0xF3, 0xD8, 0x57, 0x73, 0x1E, 0xE9, 0x94, 0x39, 0x04, + 0xBF, 0xD3, 0xDE, 0x38, 0xDE, 0xB4, 0x53, 0xEC, 0x69, 0x1C, 0xA2, 0x7E, + 0xC4, 0x8F, 0xE4, 0x1B, 0x70, 0xAD, 0xF2, 0xA2, 0xF9, 0xFB, 0xF7, 0x16, + 0x64, 0x66, 0x69, 0x9F, 0x49, 0x51, 0xA2, 0xE2, 0x15, 0x18, 0x67, 0x06, + 0x4A, 0x7F, 0xD5, 0x6C, 0xB5, 0x4D, 0xB3, 0x33, 0xE0, 0x61, 0xEB, 0x5D, + 0xBE, 0xE9, 0x98, 0x0F, 0x32, 0xD7, 0x1D, 0x4B, 0x3C, 0x2E, 0x5A, 0x01, + 0x52, 0x91, 0x09, 0xF2, 0xDF, 0xEA, 0x8D, 0xD8, 0x06, 0x40, 0x63, 0xAA, + 0x11, 0xE4, 0xFE, 0xC3, 0x37, 0x9E, 0x14, 0x52, 0x3F, 0xF4, 0xE2, 0xCC, + 0xF2, 0x61, 0x93, 0xD1, 0xFD, 0x67, 0x6B, 0xD7, 0x52, 0xAE, 0xBF, 0x68, + 0xAB, 0x40, 0x43, 0xA0, 0x57, 0x35, 0x53, 0x78, 0xF0, 0x53, 0xF8, 0x61, + 0x42, 0x07, 0x64, 0xC6, 0xD7, 0x6F, 0x9B, 0x4C, 0x38, 0x0D, 0x63, 0xAC, + 0x62, 0xAF, 0x36, 0x8B, 0xA2, 0x73, 0x0A, 0x0D, 0xF5, 0x21, 0xBD, 0x74, + 0xAA, 0x4D, 0xEA, 0x72, 0x03, 0x49, 0xDB, 0xC7, 0x5F, 0x1D, 0x62, 0x63, + 0xC7, 0xFD, 0xDD, 0x91, 0xEC, 0x33, 0xEE, 0xF5, 0x6D, 0xB4, 0x6E, 0x30, + 0x68, 0xDE, 0xC8, 0xD6, 0x26, 0xB0, 0x75, 0x5E, 0x7B, 0xB4, 0x07, 0x20, + 0x98, 0xA1, 0x76, 0x32, 0xB8, 0x4D, 0x6C, 0x4F +}; + +static const unsigned char TA83_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA84_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, + 0x6F, 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x2E, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, + 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA84_RSA_N[] = { + 0x8F, 0x36, 0x65, 0x40, 0xE1, 0xD6, 0x4D, 0xC0, 0xD7, 0xB4, 0xE9, 0x46, + 0xDA, 0x6B, 0xEA, 0x33, 0x47, 0xCD, 0x4C, 0xF9, 0x7D, 0x7D, 0xBE, 0xBD, + 0x2D, 0x3D, 0xF0, 0xDB, 0x78, 0xE1, 0x86, 0xA5, 0xD9, 0xBA, 0x09, 0x57, + 0x68, 0xED, 0x57, 0x3E, 0xA0, 0xD0, 0x08, 0x41, 0x83, 0xE7, 0x28, 0x41, + 0x24, 0x1F, 0xE3, 0x72, 0x15, 0xD0, 0x01, 0x1A, 0xFB, 0x5E, 0x70, 0x23, + 0xB2, 0xCB, 0x9F, 0x39, 0xE3, 0xCF, 0xC5, 0x4E, 0xC6, 0x92, 0x6D, 0x26, + 0xC6, 0x7B, 0xBB, 0xB3, 0xDA, 0x27, 0x9D, 0x0A, 0x86, 0xE9, 0x81, 0x37, + 0x05, 0xFE, 0xF0, 0x71, 0x71, 0xEC, 0xC3, 0x1C, 0xE9, 0x63, 0xA2, 0x17, + 0x14, 0x9D, 0xEF, 0x1B, 0x67, 0xD3, 0x85, 0x55, 0x02, 0x02, 0xD6, 0x49, + 0xC9, 0xCC, 0x5A, 0xE1, 0xB1, 0xF7, 0x6F, 0x32, 0x9F, 0xC9, 0xD4, 0x3B, + 0x88, 0x41, 0xA8, 0x9C, 0xBD, 0xCB, 0xAB, 0xDB, 0x6D, 0x7B, 0x09, 0x1F, + 0xA2, 0x4C, 0x72, 0x90, 0xDA, 0x2B, 0x08, 0xFC, 0xCF, 0x3C, 0x54, 0xCE, + 0x67, 0x0F, 0xA8, 0xCF, 0x5D, 0x96, 0x19, 0x0B, 0xC4, 0xE3, 0x72, 0xEB, + 0xAD, 0xD1, 0x7D, 0x1D, 0x27, 0xEF, 0x92, 0xEB, 0x10, 0xBF, 0x5B, 0xEB, + 0x3B, 0xAF, 0xCF, 0x80, 0xDD, 0xC1, 0xD2, 0x96, 0x04, 0x5B, 0x7A, 0x7E, + 0xA4, 0xA9, 0x3C, 0x38, 0x76, 0xA4, 0x62, 0x8E, 0xA0, 0x39, 0x5E, 0xEA, + 0x77, 0xCF, 0x5D, 0x00, 0x59, 0x8F, 0x66, 0x2C, 0x3E, 0x07, 0xA2, 0xA3, + 0x05, 0x26, 0x11, 0x69, 0x97, 0xEA, 0x85, 0xB7, 0x0F, 0x96, 0x0B, 0x4B, + 0xC8, 0x40, 0xE1, 0x50, 0xBA, 0x2E, 0x8A, 0xCB, 0xF7, 0x0F, 0x9A, 0x22, + 0xE7, 0x7F, 0x9A, 0x37, 0x13, 0xCD, 0xF2, 0x4D, 0x13, 0x6B, 0x21, 0xD1, + 0xC0, 0xCC, 0x22, 0xF2, 0xA1, 0x46, 0xF6, 0x44, 0x69, 0x9C, 0xCA, 0x61, + 0x35, 0x07, 0x00, 0x6F, 0xD6, 0x61, 0x08, 0x11, 0xEA, 0xBA, 0xB8, 0xF6, + 0xE9, 0xB3, 0x60, 0xE5, 0x4D, 0xB9, 0xEC, 0x9F, 0x14, 0x66, 0xC9, 0x57, + 0x58, 0xDB, 0xCD, 0x87, 0x69, 0xF8, 0x8A, 0x86, 0x12, 0x03, 0x47, 0xBF, + 0x66, 0x13, 0x76, 0xAC, 0x77, 0x7D, 0x34, 0x24, 0x85, 0x83, 0xCD, 0xD7, + 0xAA, 0x9C, 0x90, 0x1A, 0x9F, 0x21, 0x2C, 0x7F, 0x78, 0xB7, 0x64, 0xB8, + 0xD8, 0xE8, 0xA6, 0xF4, 0x78, 0xB3, 0x55, 0xCB, 0x84, 0xD2, 0x32, 0xC4, + 0x78, 0xAE, 0xA3, 0x8F, 0x61, 0xDD, 0xCE, 0x08, 0x53, 0xAD, 0xEC, 0x88, + 0xFC, 0x15, 0xE4, 0x9A, 0x0D, 0xE6, 0x9F, 0x1A, 0x77, 0xCE, 0x4C, 0x8F, + 0xB8, 0x14, 0x15, 0x3D, 0x62, 0x9C, 0x86, 0x38, 0x06, 0x00, 0x66, 0x12, + 0xE4, 0x59, 0x76, 0x5A, 0x53, 0xC0, 0x02, 0x98, 0xA2, 0x10, 0x2B, 0x68, + 0x44, 0x7B, 0x8E, 0x79, 0xCE, 0x33, 0x4A, 0x76, 0xAA, 0x5B, 0x81, 0x16, + 0x1B, 0xB5, 0x8A, 0xD8, 0xD0, 0x00, 0x7B, 0x5E, 0x62, 0xB4, 0x09, 0xD6, + 0x86, 0x63, 0x0E, 0xA6, 0x05, 0x95, 0x49, 0xBA, 0x28, 0x8B, 0x88, 0x93, + 0xB2, 0x34, 0x1C, 0xD8, 0xA4, 0x55, 0x6E, 0xB7, 0x1C, 0xD0, 0xDE, 0x99, + 0x55, 0x3B, 0x23, 0xF4, 0x22, 0xE0, 0xF9, 0x29, 0x66, 0x26, 0xEC, 0x20, + 0x50, 0x77, 0xDB, 0x4A, 0x0B, 0x8F, 0xBE, 0xE5, 0x02, 0x60, 0x70, 0x41, + 0x5E, 0xD4, 0xAE, 0x50, 0x39, 0x22, 0x14, 0x26, 0xCB, 0xB2, 0x3B, 0x73, + 0x74, 0x55, 0x47, 0x07, 0x79, 0x81, 0x39, 0xA8, 0x30, 0x13, 0x44, 0xE5, + 0x04, 0x8A, 0xAE, 0x96, 0x13, 0x25, 0x42, 0x0F, 0xB9, 0x53, 0xC4, 0x9B, + 0xFC, 0xCD, 0xE4, 0x1C, 0xDE, 0x3C, 0xFA, 0xAB, 0xD6, 0x06, 0x4A, 0x1F, + 0x67, 0xA6, 0x98, 0x30, 0x1C, 0xDD, 0x2C, 0xDB, 0xDC, 0x18, 0x95, 0x57, + 0x66, 0xC6, 0xFF, 0x5C, 0x8B, 0x56, 0xF5, 0x77 +}; + +static const unsigned char TA84_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA85_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x43, 0x41, 0x31 +}; + +static const unsigned char TA85_EC_Q[] = { + 0x04, 0xA4, 0xA5, 0x6F, 0x60, 0x03, 0x03, 0xC3, 0xBD, 0x31, 0xF4, 0xD3, + 0x17, 0x9C, 0x2B, 0x84, 0x75, 0xAC, 0xE5, 0xFD, 0x3D, 0x57, 0x6E, 0xD7, + 0x63, 0xBF, 0xE6, 0x04, 0x89, 0x92, 0x8E, 0x81, 0x9C, 0xE3, 0xE9, 0x47, + 0x6E, 0xCA, 0x90, 0x12, 0xC8, 0x13, 0xE0, 0xA7, 0x9D, 0xF7, 0x65, 0x74, + 0x1F, 0x6C, 0x10, 0xB2, 0xE8, 0xE4, 0xE9, 0xEF, 0x6D, 0x85, 0x32, 0x99, + 0x44, 0xB1, 0x5E, 0xFD, 0xCC, 0x76, 0x10, 0xD8, 0x5B, 0xBD, 0xA2, 0xC6, + 0xF9, 0xD6, 0x42, 0xE4, 0x57, 0x76, 0xDC, 0x90, 0xC2, 0x35, 0xA9, 0x4B, + 0x88, 0x3C, 0x12, 0x47, 0x6D, 0x5C, 0xFF, 0x49, 0x4F, 0x1A, 0x4A, 0x50, + 0xB1 +}; + +static const unsigned char TA86_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA86_EC_Q[] = { + 0x04, 0xF1, 0x0B, 0xDD, 0x86, 0x43, 0x20, 0x19, 0xDF, 0x97, 0x85, 0xE8, + 0x22, 0x4A, 0x9B, 0xCF, 0x9D, 0x98, 0xBF, 0xB4, 0x05, 0x26, 0xC9, 0xCB, + 0xE3, 0xA6, 0xD2, 0x8F, 0xC5, 0x9E, 0x78, 0x7B, 0x31, 0x89, 0xA9, 0x89, + 0xAD, 0x27, 0x3C, 0x65, 0x10, 0x82, 0xFC, 0xDF, 0xC3, 0x9D, 0x4E, 0xF0, + 0x33, 0x23, 0xC4, 0xD2, 0x32, 0xF5, 0x1C, 0xB0, 0xDF, 0x33, 0x17, 0x5D, + 0xC5, 0xF0, 0xB1, 0x8A, 0xF9, 0xEF, 0xB9, 0xB7, 0x14, 0xCA, 0x29, 0x4A, + 0xC2, 0x0F, 0xA9, 0x7F, 0x75, 0x65, 0x49, 0x2A, 0x30, 0x67, 0xF4, 0x64, + 0xF7, 0xD6, 0x1A, 0x77, 0xDA, 0xC3, 0xC2, 0x97, 0x61, 0x42, 0x7B, 0x49, + 0xAD +}; + +static const unsigned char TA87_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA87_EC_Q[] = { + 0x04, 0x4B, 0x36, 0xE9, 0xAE, 0x57, 0x5E, 0xA8, 0x70, 0xD7, 0xD0, 0x8F, + 0x74, 0x62, 0x77, 0xC3, 0x5E, 0x7A, 0xAA, 0xE5, 0xB6, 0xA2, 0xF1, 0x78, + 0xFD, 0x02, 0x7E, 0x57, 0xDD, 0x91, 0x79, 0x9C, 0x6C, 0xB9, 0x52, 0x88, + 0x54, 0xBC, 0x2F, 0x04, 0xBE, 0xB8, 0xCD, 0xF6, 0x10, 0xD1, 0x29, 0xEC, + 0xB5, 0xD0, 0xA0, 0xC3, 0xF0, 0x89, 0x70, 0x19, 0xBB, 0x51, 0x65, 0xC5, + 0x43, 0x9C, 0xC3, 0x9B, 0x63, 0x9D, 0x20, 0x83, 0x3E, 0x06, 0x0B, 0xA6, + 0x42, 0x44, 0x85, 0x11, 0xA7, 0x4A, 0x3A, 0x2D, 0xE9, 0xD6, 0x68, 0x2F, + 0x48, 0x4E, 0x53, 0x2B, 0x07, 0x3F, 0x4D, 0xBD, 0xB9, 0xAC, 0x77, 0x39, + 0x57 +}; + +static const unsigned char TA88_DN[] = { + 0x30, 0x81, 0x81, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA88_RSA_N[] = { + 0xD0, 0x40, 0x8B, 0x8B, 0x72, 0xE3, 0x91, 0x1B, 0xF7, 0x51, 0xC1, 0x1B, + 0x54, 0x04, 0x98, 0xD3, 0xA9, 0xBF, 0xC1, 0xE6, 0x8A, 0x5D, 0x3B, 0x87, + 0xFB, 0xBB, 0x88, 0xCE, 0x0D, 0xE3, 0x2F, 0x3F, 0x06, 0x96, 0xF0, 0xA2, + 0x29, 0x50, 0x99, 0xAE, 0xDB, 0x3B, 0xA1, 0x57, 0xB0, 0x74, 0x51, 0x71, + 0xCD, 0xED, 0x42, 0x91, 0x4D, 0x41, 0xFE, 0xA9, 0xC8, 0xD8, 0x6A, 0x86, + 0x77, 0x44, 0xBB, 0x59, 0x66, 0x97, 0x50, 0x5E, 0xB4, 0xD4, 0x2C, 0x70, + 0x44, 0xCF, 0xDA, 0x37, 0x95, 0x42, 0x69, 0x3C, 0x30, 0xC4, 0x71, 0xB3, + 0x52, 0xF0, 0x21, 0x4D, 0xA1, 0xD8, 0xBA, 0x39, 0x7C, 0x1C, 0x9E, 0xA3, + 0x24, 0x9D, 0xF2, 0x83, 0x16, 0x98, 0xAA, 0x16, 0x7C, 0x43, 0x9B, 0x15, + 0x5B, 0xB7, 0xAE, 0x34, 0x91, 0xFE, 0xD4, 0x62, 0x26, 0x18, 0x46, 0x9A, + 0x3F, 0xEB, 0xC1, 0xF9, 0xF1, 0x90, 0x57, 0xEB, 0xAC, 0x7A, 0x0D, 0x8B, + 0xDB, 0x72, 0x30, 0x6A, 0x66, 0xD5, 0xE0, 0x46, 0xA3, 0x70, 0xDC, 0x68, + 0xD9, 0xFF, 0x04, 0x48, 0x89, 0x77, 0xDE, 0xB5, 0xE9, 0xFB, 0x67, 0x6D, + 0x41, 0xE9, 0xBC, 0x39, 0xBD, 0x32, 0xD9, 0x62, 0x02, 0xF1, 0xB1, 0xA8, + 0x3D, 0x6E, 0x37, 0x9C, 0xE2, 0x2F, 0xE2, 0xD3, 0xA2, 0x26, 0x8B, 0xC6, + 0xB8, 0x55, 0x43, 0x88, 0xE1, 0x23, 0x3E, 0xA5, 0xD2, 0x24, 0x39, 0x6A, + 0x47, 0xAB, 0x00, 0xD4, 0xA1, 0xB3, 0xA9, 0x25, 0xFE, 0x0D, 0x3F, 0xA7, + 0x1D, 0xBA, 0xD3, 0x51, 0xC1, 0x0B, 0xA4, 0xDA, 0xAC, 0x38, 0xEF, 0x55, + 0x50, 0x24, 0x05, 0x65, 0x46, 0x93, 0x34, 0x4F, 0x2D, 0x8D, 0xAD, 0xC6, + 0xD4, 0x21, 0x19, 0xD2, 0x8E, 0xCA, 0x05, 0x61, 0x71, 0x07, 0x73, 0x47, + 0xE5, 0x8A, 0x19, 0x12, 0xBD, 0x04, 0x4D, 0xCE, 0x4E, 0x9C, 0xA5, 0x48, + 0xAC, 0xBB, 0x26, 0xF7 +}; + +static const unsigned char TA88_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA89_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x34 +}; + +static const unsigned char TA89_EC_Q[] = { + 0x04, 0xF3, 0x74, 0x73, 0xA7, 0x68, 0x8B, 0x60, 0xAE, 0x43, 0xB8, 0x35, + 0xC5, 0x81, 0x30, 0x7B, 0x4B, 0x49, 0x9D, 0xFB, 0xC1, 0x61, 0xCE, 0xE6, + 0xDE, 0x46, 0xBD, 0x6B, 0xD5, 0x61, 0x18, 0x35, 0xAE, 0x40, 0xDD, 0x73, + 0xF7, 0x89, 0x91, 0x30, 0x5A, 0xEB, 0x3C, 0xEE, 0x85, 0x7C, 0xA2, 0x40, + 0x76, 0x3B, 0xA9, 0xC6, 0xB8, 0x47, 0xD8, 0x2A, 0xE7, 0x92, 0x91, 0x6A, + 0x73, 0xE9, 0xB1, 0x72, 0x39, 0x9F, 0x29, 0x9F, 0xA2, 0x98, 0xD3, 0x5F, + 0x5E, 0x58, 0x86, 0x65, 0x0F, 0xA1, 0x84, 0x65, 0x06, 0xD1, 0xDC, 0x8B, + 0xC9, 0xC7, 0x73, 0xC8, 0x8C, 0x6A, 0x2F, 0xE5, 0xC4, 0xAB, 0xD1, 0x1D, + 0x8A +}; + +static const unsigned char TA90_DN[] = { + 0x30, 0x57, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, + 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA90_RSA_N[] = { + 0xDA, 0x0E, 0xE6, 0x99, 0x8D, 0xCE, 0xA3, 0xE3, 0x4F, 0x8A, 0x7E, 0xFB, + 0xF1, 0x8B, 0x83, 0x25, 0x6B, 0xEA, 0x48, 0x1F, 0xF1, 0x2A, 0xB0, 0xB9, + 0x95, 0x11, 0x04, 0xBD, 0xF0, 0x63, 0xD1, 0xE2, 0x67, 0x66, 0xCF, 0x1C, + 0xDD, 0xCF, 0x1B, 0x48, 0x2B, 0xEE, 0x8D, 0x89, 0x8E, 0x9A, 0xAF, 0x29, + 0x80, 0x65, 0xAB, 0xE9, 0xC7, 0x2D, 0x12, 0xCB, 0xAB, 0x1C, 0x4C, 0x70, + 0x07, 0xA1, 0x3D, 0x0A, 0x30, 0xCD, 0x15, 0x8D, 0x4F, 0xF8, 0xDD, 0xD4, + 0x8C, 0x50, 0x15, 0x1C, 0xEF, 0x50, 0xEE, 0xC4, 0x2E, 0xF7, 0xFC, 0xE9, + 0x52, 0xF2, 0x91, 0x7D, 0xE0, 0x6D, 0xD5, 0x35, 0x30, 0x8E, 0x5E, 0x43, + 0x73, 0xF2, 0x41, 0xE9, 0xD5, 0x6A, 0xE3, 0xB2, 0x89, 0x3A, 0x56, 0x39, + 0x38, 0x6F, 0x06, 0x3C, 0x88, 0x69, 0x5B, 0x2A, 0x4D, 0xC5, 0xA7, 0x54, + 0xB8, 0x6C, 0x89, 0xCC, 0x9B, 0xF9, 0x3C, 0xCA, 0xE5, 0xFD, 0x89, 0xF5, + 0x12, 0x3C, 0x92, 0x78, 0x96, 0xD6, 0xDC, 0x74, 0x6E, 0x93, 0x44, 0x61, + 0xD1, 0x8D, 0xC7, 0x46, 0xB2, 0x75, 0x0E, 0x86, 0xE8, 0x19, 0x8A, 0xD5, + 0x6D, 0x6C, 0xD5, 0x78, 0x16, 0x95, 0xA2, 0xE9, 0xC8, 0x0A, 0x38, 0xEB, + 0xF2, 0x24, 0x13, 0x4F, 0x73, 0x54, 0x93, 0x13, 0x85, 0x3A, 0x1B, 0xBC, + 0x1E, 0x34, 0xB5, 0x8B, 0x05, 0x8C, 0xB9, 0x77, 0x8B, 0xB1, 0xDB, 0x1F, + 0x20, 0x91, 0xAB, 0x09, 0x53, 0x6E, 0x90, 0xCE, 0x7B, 0x37, 0x74, 0xB9, + 0x70, 0x47, 0x91, 0x22, 0x51, 0x63, 0x16, 0x79, 0xAE, 0xB1, 0xAE, 0x41, + 0x26, 0x08, 0xC8, 0x19, 0x2B, 0xD1, 0x46, 0xAA, 0x48, 0xD6, 0x64, 0x2A, + 0xD7, 0x83, 0x34, 0xFF, 0x2C, 0x2A, 0xC1, 0x6C, 0x19, 0x43, 0x4A, 0x07, + 0x85, 0xE7, 0xD3, 0x7C, 0xF6, 0x21, 0x68, 0xEF, 0xEA, 0xF2, 0x52, 0x9F, + 0x7F, 0x93, 0x90, 0xCF +}; + +static const unsigned char TA90_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA91_DN[] = { + 0x30, 0x37, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0B, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x54, + 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, 0x20, 0x52, + 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x31 +}; + +static const unsigned char TA91_RSA_N[] = { + 0xC2, 0xBE, 0xEB, 0x27, 0xF0, 0x21, 0xA3, 0xF3, 0x69, 0x26, 0x55, 0x7E, + 0x9D, 0xC5, 0x55, 0x16, 0x91, 0x5C, 0xFD, 0xEF, 0x21, 0xBF, 0x53, 0x80, + 0x7A, 0x2D, 0xD2, 0x91, 0x8C, 0x63, 0x31, 0xF0, 0xEC, 0x24, 0xF0, 0xC3, + 0xA5, 0xD2, 0x72, 0x7C, 0x10, 0x6D, 0xF4, 0x37, 0xB7, 0xE5, 0xE6, 0x7C, + 0x79, 0xEA, 0x8C, 0xB5, 0x82, 0x8B, 0xAE, 0x48, 0xB6, 0xAC, 0x00, 0xDC, + 0x65, 0x75, 0xEC, 0x2A, 0x4D, 0x5F, 0xC1, 0x87, 0xF5, 0x20, 0x65, 0x2B, + 0x81, 0xA8, 0x47, 0x3E, 0x89, 0x23, 0x95, 0x30, 0x16, 0x90, 0x7F, 0xE8, + 0x57, 0x07, 0x48, 0xE7, 0x19, 0xAE, 0xBF, 0x45, 0x67, 0xB1, 0x37, 0x1B, + 0x06, 0x2A, 0xFE, 0xDE, 0xF9, 0xAC, 0x7D, 0x83, 0xFB, 0x5E, 0xBA, 0xE4, + 0x8F, 0x97, 0x67, 0xBE, 0x4B, 0x8E, 0x8D, 0x64, 0x07, 0x57, 0x38, 0x55, + 0x69, 0x34, 0x36, 0x3D, 0x13, 0x48, 0xEF, 0x4F, 0xE2, 0xD3, 0x66, 0x1E, + 0xA4, 0xCF, 0x1A, 0xB7, 0x5E, 0x36, 0x33, 0xD4, 0xB4, 0x06, 0xBD, 0x18, + 0x01, 0xFD, 0x77, 0x84, 0x50, 0x00, 0x45, 0xF5, 0x8C, 0x5D, 0xE8, 0x23, + 0xBC, 0x7E, 0xFE, 0x35, 0xE1, 0xED, 0x50, 0x7B, 0xA9, 0x30, 0x8D, 0x19, + 0xD3, 0x09, 0x8E, 0x68, 0x67, 0x5D, 0xBF, 0x3C, 0x97, 0x18, 0x53, 0xBB, + 0x29, 0x62, 0xC5, 0xCA, 0x5E, 0x72, 0xC1, 0xC7, 0x96, 0xD4, 0xDB, 0x2D, + 0xA0, 0xB4, 0x1F, 0x69, 0x03, 0xEC, 0xEA, 0xE2, 0x50, 0xF1, 0x0C, 0x3C, + 0xF0, 0xAC, 0xF3, 0x53, 0x2D, 0xF0, 0x1C, 0xF5, 0xED, 0x6C, 0x39, 0x39, + 0x73, 0x80, 0x16, 0xC8, 0x52, 0xB0, 0x23, 0xCD, 0xE0, 0x3E, 0xDC, 0xDD, + 0x3C, 0x47, 0xA0, 0xBB, 0x35, 0x8A, 0xE2, 0x98, 0x68, 0x8B, 0xBE, 0xE5, + 0xBF, 0x72, 0xEE, 0xD2, 0xFA, 0xA5, 0xED, 0x12, 0xED, 0xFC, 0x98, 0x18, + 0xA9, 0x26, 0x76, 0xDC, 0x28, 0x4B, 0x10, 0x20, 0x1C, 0xD3, 0x7F, 0x16, + 0x77, 0x2D, 0xED, 0x6F, 0x80, 0xF7, 0x49, 0xBB, 0x53, 0x05, 0xBB, 0x5D, + 0x68, 0xC7, 0xD4, 0xC8, 0x75, 0x16, 0x3F, 0x89, 0x5A, 0x8B, 0xF7, 0x17, + 0x47, 0xD4, 0x4C, 0xF1, 0xD2, 0x89, 0x79, 0x3E, 0x4D, 0x3D, 0x98, 0xA8, + 0x61, 0xDE, 0x3A, 0x1E, 0xD2, 0xF8, 0x5E, 0x03, 0xE0, 0xC1, 0xC9, 0x1C, + 0x8C, 0xD3, 0x8D, 0x4D, 0xD3, 0x95, 0x36, 0xB3, 0x37, 0x5F, 0x63, 0x63, + 0x9B, 0x33, 0x14, 0xF0, 0x2D, 0x26, 0x6B, 0x53, 0x7C, 0x89, 0x8C, 0x32, + 0xC2, 0x6E, 0xEC, 0x3D, 0x21, 0x00, 0x39, 0xC9, 0xA1, 0x68, 0xE2, 0x50, + 0x83, 0x2E, 0xB0, 0x3A, 0x2B, 0xF3, 0x36, 0xA0, 0xAC, 0x2F, 0xE4, 0x6F, + 0x61, 0xC2, 0x51, 0x09, 0x39, 0x3E, 0x8B, 0x53, 0xB9, 0xBB, 0x67, 0xDA, + 0xDC, 0x53, 0xB9, 0x76, 0x59, 0x36, 0x9D, 0x43, 0xE5, 0x20, 0xE0, 0x3D, + 0x32, 0x60, 0x85, 0x22, 0x51, 0xB7, 0xC7, 0x33, 0xBB, 0xDD, 0x15, 0x2F, + 0xA4, 0x78, 0xA6, 0x07, 0x7B, 0x81, 0x46, 0x36, 0x04, 0x86, 0xDD, 0x79, + 0x35, 0xC7, 0x95, 0x2C, 0x3B, 0xB0, 0xA3, 0x17, 0x35, 0xE5, 0x73, 0x1F, + 0xB4, 0x5C, 0x59, 0xEF, 0xDA, 0xEA, 0x10, 0x65, 0x7B, 0x7A, 0xD0, 0x7F, + 0x9F, 0xB3, 0xB4, 0x2A, 0x37, 0x3B, 0x70, 0x8B, 0x9B, 0x5B, 0xB9, 0x2B, + 0xB7, 0xEC, 0xB2, 0x51, 0x12, 0x97, 0x53, 0x29, 0x5A, 0xD4, 0xF0, 0x12, + 0x10, 0xDC, 0x4F, 0x02, 0xBB, 0x12, 0x92, 0x2F, 0x62, 0xD4, 0x3F, 0x69, + 0x43, 0x7C, 0x0D, 0xD6, 0xFC, 0x58, 0x75, 0x01, 0x88, 0x9D, 0x58, 0x16, + 0x4B, 0xDE, 0xBA, 0x90, 0xFF, 0x47, 0x01, 0x89, 0x06, 0x6A, 0xF6, 0x5F, + 0xB2, 0x90, 0x6A, 0xB3, 0x02, 0xA6, 0x02, 0x88, 0xBF, 0xB3, 0x47, 0x7E, + 0x2A, 0xD9, 0xD5, 0xFA, 0x68, 0x78, 0x35, 0x4D +}; + +static const unsigned char TA91_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA92_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x32 +}; + +static const unsigned char TA92_RSA_N[] = { + 0xBA, 0x39, 0xC1, 0x37, 0x7A, 0x68, 0x45, 0x2B, 0x14, 0xB4, 0xEB, 0xE4, + 0x13, 0xEB, 0x57, 0x75, 0x23, 0x4D, 0x8F, 0x24, 0x2D, 0x16, 0xE8, 0xAE, + 0x8E, 0xC9, 0x7D, 0xA4, 0x57, 0x3B, 0x2A, 0x76, 0x25, 0x33, 0x83, 0x6C, + 0xEA, 0x32, 0x8A, 0x94, 0x9B, 0x4E, 0x3C, 0x96, 0xE4, 0xFD, 0x51, 0xBF, + 0x99, 0xC9, 0x93, 0x7E, 0xBF, 0xF9, 0xAD, 0xA7, 0xB2, 0x48, 0x2B, 0x07, + 0x1C, 0x27, 0xF5, 0x4C, 0xBC, 0x70, 0x12, 0x77, 0xA4, 0x85, 0x54, 0xB5, + 0xFD, 0x90, 0x7A, 0xE4, 0xA3, 0xE4, 0x51, 0x58, 0x03, 0xCD, 0x10, 0x79, + 0x79, 0xEE, 0x6B, 0x93, 0x1F, 0x64, 0x8E, 0x6B, 0x64, 0xAB, 0xA3, 0x13, + 0xE3, 0x71, 0xFE, 0x7D, 0xAB, 0x9C, 0xDD, 0x27, 0x53, 0x37, 0xB3, 0xAA, + 0x18, 0xC2, 0x59, 0x26, 0xEC, 0x5B, 0x1F, 0xD2, 0xE6, 0x65, 0x7C, 0xEF, + 0x93, 0xBD, 0xD8, 0x58, 0x5C, 0x0B, 0xC0, 0xE3, 0x65, 0x6F, 0x3C, 0xC7, + 0xCA, 0x59, 0xE3, 0xFE, 0x6E, 0x5F, 0xAC, 0x83, 0xBE, 0xFD, 0x5D, 0x25, + 0x4E, 0x2A, 0x29, 0x3B, 0xD6, 0x0B, 0xAB, 0x17, 0x32, 0x78, 0xA4, 0xE1, + 0x3E, 0x94, 0x46, 0xBE, 0x62, 0x6E, 0x9B, 0xDE, 0x46, 0xA8, 0xB1, 0x16, + 0xE7, 0x85, 0x6E, 0xF4, 0x08, 0x40, 0x45, 0x11, 0xA0, 0x9E, 0x54, 0x44, + 0x84, 0xF7, 0xD8, 0x36, 0xCE, 0xF5, 0x50, 0x47, 0xDC, 0x2C, 0x30, 0x9B, + 0xEE, 0xC0, 0xF5, 0x96, 0xD2, 0xFE, 0x09, 0x86, 0xC7, 0x06, 0x59, 0xAE, + 0x4F, 0xAE, 0x8E, 0x11, 0x98, 0x7B, 0xF3, 0x0B, 0x52, 0xAA, 0x62, 0x26, + 0xAA, 0x21, 0xDF, 0x8E, 0x25, 0x33, 0x79, 0x97, 0x16, 0x49, 0x8D, 0xF5, + 0x3E, 0xD5, 0x47, 0x9F, 0x37, 0x31, 0x49, 0x33, 0x72, 0x05, 0x4D, 0x0C, + 0xB6, 0x55, 0x8C, 0xF1, 0x57, 0x8F, 0x8A, 0x87, 0xD1, 0xAD, 0xC5, 0x11, + 0x12, 0x39, 0xA0, 0xAD +}; + +static const unsigned char TA92_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA93_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x13, 0x54, 0x57, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, + 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA93_RSA_N[] = { + 0xB0, 0x05, 0xDB, 0xC8, 0xEB, 0x8C, 0xC4, 0x6E, 0x8A, 0x21, 0xEF, 0x8E, + 0x4D, 0x9C, 0x71, 0x0A, 0x1F, 0x52, 0x70, 0xED, 0x6D, 0x82, 0x9C, 0x97, + 0xC5, 0xD7, 0x4C, 0x4E, 0x45, 0x49, 0xCB, 0x40, 0x42, 0xB5, 0x12, 0x34, + 0x6C, 0x19, 0xC2, 0x74, 0xA4, 0x31, 0x5F, 0x85, 0x02, 0x97, 0xEC, 0x43, + 0x33, 0x0A, 0x53, 0xD2, 0x9C, 0x8C, 0x8E, 0xB7, 0xB8, 0x79, 0xDB, 0x2B, + 0xD5, 0x6A, 0xF2, 0x8E, 0x66, 0xC4, 0xEE, 0x2B, 0x01, 0x07, 0x92, 0xD4, + 0xB3, 0xD0, 0x02, 0xDF, 0x50, 0xF6, 0x55, 0xAF, 0x66, 0x0E, 0xCB, 0xE0, + 0x47, 0x60, 0x2F, 0x2B, 0x32, 0x39, 0x35, 0x52, 0x3A, 0x28, 0x83, 0xF8, + 0x7B, 0x16, 0xC6, 0x18, 0xB8, 0x62, 0xD6, 0x47, 0x25, 0x91, 0xCE, 0xF0, + 0x19, 0x12, 0x4D, 0xAD, 0x63, 0xF5, 0xD3, 0x3F, 0x75, 0x5F, 0x29, 0xF0, + 0xA1, 0x30, 0x1C, 0x2A, 0xA0, 0x98, 0xA6, 0x15, 0xBD, 0xEE, 0xFD, 0x19, + 0x36, 0xF0, 0xE2, 0x91, 0x43, 0x8F, 0xFA, 0xCA, 0xD6, 0x10, 0x27, 0x49, + 0x4C, 0xEF, 0xDD, 0xC1, 0xF1, 0x85, 0x70, 0x9B, 0xCA, 0xEA, 0xA8, 0x5A, + 0x43, 0xFC, 0x6D, 0x86, 0x6F, 0x73, 0xE9, 0x37, 0x45, 0xA9, 0xF0, 0x36, + 0xC7, 0xCC, 0x88, 0x75, 0x1E, 0xBB, 0x6C, 0x06, 0xFF, 0x9B, 0x6B, 0x3E, + 0x17, 0xEC, 0x61, 0xAA, 0x71, 0x7C, 0xC6, 0x1D, 0xA2, 0xF7, 0x49, 0xE9, + 0x15, 0xB5, 0x3C, 0xD6, 0xA1, 0x61, 0xF5, 0x11, 0xF7, 0x05, 0x6F, 0x1D, + 0xFD, 0x11, 0xBE, 0xD0, 0x30, 0x07, 0xC2, 0x29, 0xB0, 0x09, 0x4E, 0x26, + 0xDC, 0xE3, 0xA2, 0xA8, 0x91, 0x6A, 0x1F, 0xC2, 0x91, 0x45, 0x88, 0x5C, + 0xE5, 0x98, 0xB8, 0x71, 0xA5, 0x15, 0x19, 0xC9, 0x7C, 0x75, 0x11, 0xCC, + 0x70, 0x74, 0x4F, 0x2D, 0x9B, 0x1D, 0x91, 0x44, 0xFD, 0x56, 0x28, 0xA0, + 0xFE, 0xBB, 0x86, 0x6A, 0xC8, 0xFA, 0x5C, 0x0B, 0x58, 0xDC, 0xC6, 0x4B, + 0x76, 0xC8, 0xAB, 0x22, 0xD9, 0x73, 0x0F, 0xA5, 0xF4, 0x5A, 0x02, 0x89, + 0x3F, 0x4F, 0x9E, 0x22, 0x82, 0xEE, 0xA2, 0x74, 0x53, 0x2A, 0x3D, 0x53, + 0x27, 0x69, 0x1D, 0x6C, 0x8E, 0x32, 0x2C, 0x64, 0x00, 0x26, 0x63, 0x61, + 0x36, 0x4E, 0xA3, 0x46, 0xB7, 0x3F, 0x7D, 0xB3, 0x2D, 0xAC, 0x6D, 0x90, + 0xA2, 0x95, 0xA2, 0xCE, 0xCF, 0xDA, 0x82, 0xE7, 0x07, 0x34, 0x19, 0x96, + 0xE9, 0xB8, 0x21, 0xAA, 0x29, 0x7E, 0xA6, 0x38, 0xBE, 0x8E, 0x29, 0x4A, + 0x21, 0x66, 0x79, 0x1F, 0xB3, 0xC3, 0xB5, 0x09, 0x67, 0xDE, 0xD6, 0xD4, + 0x07, 0x46, 0xF3, 0x2A, 0xDA, 0xE6, 0x22, 0x37, 0x60, 0xCB, 0x81, 0xB6, + 0x0F, 0xA0, 0x0F, 0xE9, 0xC8, 0x95, 0x7F, 0xBF, 0x55, 0x91, 0x05, 0x7A, + 0xCF, 0x3D, 0x15, 0xC0, 0x6F, 0xDE, 0x09, 0x94, 0x01, 0x83, 0xD7, 0x34, + 0x1B, 0xCC, 0x40, 0xA5, 0xF0, 0xB8, 0x9B, 0x67, 0xD5, 0x98, 0x91, 0x3B, + 0xA7, 0x84, 0x78, 0x95, 0x26, 0xA4, 0x5A, 0x08, 0xF8, 0x2B, 0x74, 0xB4, + 0x00, 0x04, 0x3C, 0xDF, 0xB8, 0x14, 0x8E, 0xE8, 0xDF, 0xA9, 0x8D, 0x6C, + 0x67, 0x92, 0x33, 0x1D, 0xC0, 0xB7, 0xD2, 0xEC, 0x92, 0xC8, 0xBE, 0x09, + 0xBF, 0x2C, 0x29, 0x05, 0x6F, 0x02, 0x6B, 0x9E, 0xEF, 0xBC, 0xBF, 0x2A, + 0xBC, 0x5B, 0xC0, 0x50, 0x8F, 0x41, 0x70, 0x71, 0x87, 0xB2, 0x4D, 0xB7, + 0x04, 0xA9, 0x84, 0xA3, 0x32, 0xAF, 0xAE, 0xEE, 0x6B, 0x17, 0x8B, 0xB2, + 0xB1, 0xFE, 0x6C, 0xE1, 0x90, 0x8C, 0x88, 0xA8, 0x97, 0x48, 0xCE, 0xC8, + 0x4D, 0xCB, 0xF3, 0x06, 0xCF, 0x5F, 0x6A, 0x0A, 0x42, 0xB1, 0x1E, 0x1E, + 0x77, 0x2F, 0x8E, 0xA0, 0xE6, 0x92, 0x0E, 0x06, 0xFC, 0x05, 0x22, 0xD2, + 0x26, 0xE1, 0x31, 0x51, 0x7D, 0x32, 0xDC, 0x0F +}; + +static const unsigned char TA93_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA94_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x54, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x05, 0x4D, 0x69, 0x6C, 0x61, 0x6E, 0x31, 0x23, 0x30, 0x21, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x1A, 0x41, 0x63, 0x74, 0x61, 0x6C, 0x69, + 0x73, 0x20, 0x53, 0x2E, 0x70, 0x2E, 0x41, 0x2E, 0x2F, 0x30, 0x33, 0x33, + 0x35, 0x38, 0x35, 0x32, 0x30, 0x39, 0x36, 0x37, 0x31, 0x27, 0x30, 0x25, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x41, 0x63, 0x74, 0x61, 0x6C, + 0x69, 0x73, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA94_RSA_N[] = { + 0xA7, 0xC6, 0xC4, 0xA5, 0x29, 0xA4, 0x2C, 0xEF, 0xE5, 0x18, 0xC5, 0xB0, + 0x50, 0xA3, 0x6F, 0x51, 0x3B, 0x9F, 0x0A, 0x5A, 0xC9, 0xC2, 0x48, 0x38, + 0x0A, 0xC2, 0x1C, 0xA0, 0x18, 0x7F, 0x91, 0xB5, 0x87, 0xB9, 0x40, 0x3F, + 0xDD, 0x1D, 0x68, 0x1F, 0x08, 0x83, 0xD5, 0x2D, 0x1E, 0x88, 0xA0, 0xF8, + 0x8F, 0x56, 0x8F, 0x6D, 0x99, 0x02, 0x92, 0x90, 0x16, 0xD5, 0x5F, 0x08, + 0x6C, 0x89, 0xD7, 0xE1, 0xAC, 0xBC, 0x20, 0xC2, 0xB1, 0xE0, 0x83, 0x51, + 0x8A, 0x69, 0x4D, 0x00, 0x96, 0x5A, 0x6F, 0x2F, 0xC0, 0x44, 0x7E, 0xA3, + 0x0E, 0xE4, 0x91, 0xCD, 0x58, 0xEE, 0xDC, 0xFB, 0xC7, 0x1E, 0x45, 0x47, + 0xDD, 0x27, 0xB9, 0x08, 0x01, 0x9F, 0xA6, 0x21, 0x1D, 0xF5, 0x41, 0x2D, + 0x2F, 0x4C, 0xFD, 0x28, 0xAD, 0xE0, 0x8A, 0xAD, 0x22, 0xB4, 0x56, 0x65, + 0x8E, 0x86, 0x54, 0x8F, 0x93, 0x43, 0x29, 0xDE, 0x39, 0x46, 0x78, 0xA3, + 0x30, 0x23, 0xBA, 0xCD, 0xF0, 0x7D, 0x13, 0x57, 0xC0, 0x5D, 0xD2, 0x83, + 0x6B, 0x48, 0x4C, 0xC4, 0xAB, 0x9F, 0x80, 0x5A, 0x5B, 0x3A, 0xBD, 0xC9, + 0xA7, 0x22, 0x3F, 0x80, 0x27, 0x33, 0x5B, 0x0E, 0xB7, 0x8A, 0x0C, 0x5D, + 0x07, 0x37, 0x08, 0xCB, 0x6C, 0xD2, 0x7A, 0x47, 0x22, 0x44, 0x35, 0xC5, + 0xCC, 0xCC, 0x2E, 0x8E, 0xDD, 0x2A, 0xED, 0xB7, 0x7D, 0x66, 0x0D, 0x5F, + 0x61, 0x51, 0x22, 0x55, 0x1B, 0xE3, 0x46, 0xE3, 0xE3, 0x3D, 0xD0, 0x35, + 0x62, 0x9A, 0xDB, 0xAF, 0x14, 0xC8, 0x5B, 0xA1, 0xCC, 0x89, 0x1B, 0xE1, + 0x30, 0x26, 0xFC, 0xA0, 0x9B, 0x1F, 0x81, 0xA7, 0x47, 0x1F, 0x04, 0xEB, + 0xA3, 0x39, 0x92, 0x06, 0x9F, 0x99, 0xD3, 0xBF, 0xD3, 0xEA, 0x4F, 0x50, + 0x9C, 0x19, 0xFE, 0x96, 0x87, 0x1E, 0x3C, 0x65, 0xF6, 0xA3, 0x18, 0x24, + 0x83, 0x86, 0x10, 0xE7, 0x54, 0x3E, 0xA8, 0x3A, 0x76, 0x24, 0x4F, 0x81, + 0x21, 0xC5, 0xE3, 0x0F, 0x02, 0xF8, 0x93, 0x94, 0x47, 0x20, 0xBB, 0xFE, + 0xD4, 0x0E, 0xD3, 0x68, 0xB9, 0xDD, 0xC4, 0x7A, 0x84, 0x82, 0xE3, 0x53, + 0x54, 0x79, 0xDD, 0xDB, 0x9C, 0xD2, 0xF2, 0x07, 0x9B, 0x2E, 0xB6, 0xBC, + 0x3E, 0xED, 0x85, 0x6D, 0xEF, 0x25, 0x11, 0xF2, 0x97, 0x1A, 0x42, 0x61, + 0xF7, 0x4A, 0x97, 0xE8, 0x8B, 0xB1, 0x10, 0x07, 0xFA, 0x65, 0x81, 0xB2, + 0xA2, 0x39, 0xCF, 0xF7, 0x3C, 0xFF, 0x18, 0xFB, 0xC6, 0xF1, 0x5A, 0x8B, + 0x59, 0xE2, 0x02, 0xAC, 0x7B, 0x92, 0xD0, 0x4E, 0x14, 0x4F, 0x59, 0x45, + 0xF6, 0x0C, 0x5E, 0x28, 0x5F, 0xB0, 0xE8, 0x3F, 0x45, 0xCF, 0xCF, 0xAF, + 0x9B, 0x6F, 0xFB, 0x84, 0xD3, 0x77, 0x5A, 0x95, 0x6F, 0xAC, 0x94, 0x84, + 0x9E, 0xEE, 0xBC, 0xC0, 0x4A, 0x8F, 0x4A, 0x93, 0xF8, 0x44, 0x21, 0xE2, + 0x31, 0x45, 0x61, 0x50, 0x4E, 0x10, 0xD8, 0xE3, 0x35, 0x7C, 0x4C, 0x19, + 0xB4, 0xDE, 0x05, 0xBF, 0xA3, 0x06, 0x9F, 0xC8, 0xB5, 0xCD, 0xE4, 0x1F, + 0xD7, 0x17, 0x06, 0x0D, 0x7A, 0x95, 0x74, 0x55, 0x0D, 0x68, 0x1A, 0xFC, + 0x10, 0x1B, 0x62, 0x64, 0x9D, 0x6D, 0xE0, 0x95, 0xA0, 0xC3, 0x94, 0x07, + 0x57, 0x0D, 0x14, 0xE6, 0xBD, 0x05, 0xFB, 0xB8, 0x9F, 0xE6, 0xDF, 0x8B, + 0xE2, 0xC6, 0xE7, 0x7E, 0x96, 0xF6, 0x53, 0xC5, 0x80, 0x34, 0x50, 0x28, + 0x58, 0xF0, 0x12, 0x50, 0x71, 0x17, 0x30, 0xBA, 0xE6, 0x78, 0x63, 0xBC, + 0xF4, 0xB2, 0xAD, 0x9B, 0x2B, 0xB2, 0xFE, 0xE1, 0x39, 0x8C, 0x5E, 0xBA, + 0x0B, 0x20, 0x94, 0xDE, 0x7B, 0x83, 0xB8, 0xFF, 0xE3, 0x56, 0x8D, 0xB7, + 0x11, 0xE9, 0x3B, 0x8C, 0xF2, 0xB1, 0xC1, 0x5D, 0x9D, 0xA4, 0x0B, 0x4C, + 0x2B, 0xD9, 0xB2, 0x18, 0xF5, 0xB5, 0x9F, 0x4B +}; + +static const unsigned char TA94_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA95_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x43, 0x45, 0x52, 0x54, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x53, + 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x13, + 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, + 0x54, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA95_RSA_N[] = { + 0xC0, 0xC5, 0x75, 0x19, 0x91, 0x7D, 0x44, 0x74, 0x74, 0x87, 0xFE, 0x0E, + 0x3B, 0x96, 0xDC, 0xD8, 0x01, 0x16, 0xCC, 0xEE, 0x63, 0x91, 0xE7, 0x0B, + 0x6F, 0xCE, 0x3B, 0x0A, 0x69, 0x1A, 0x7C, 0xC2, 0xE3, 0xAF, 0x82, 0x8E, + 0x86, 0xD7, 0x5E, 0x8F, 0x57, 0xEB, 0xD3, 0x21, 0x59, 0xFD, 0x39, 0x37, + 0x42, 0x30, 0xBE, 0x50, 0xEA, 0xB6, 0x0F, 0xA9, 0x88, 0xD8, 0x2E, 0x2D, + 0x69, 0x21, 0xE7, 0xD1, 0x37, 0x18, 0x4E, 0x7D, 0x91, 0xD5, 0x16, 0x5F, + 0x6B, 0x5B, 0x00, 0xC2, 0x39, 0x43, 0x0D, 0x36, 0x85, 0x52, 0xB9, 0x53, + 0x65, 0x0F, 0x1D, 0x42, 0xE5, 0x8F, 0xCF, 0x05, 0xD3, 0xEE, 0xDC, 0x0C, + 0x1A, 0xD9, 0xB8, 0x8B, 0x78, 0x22, 0x67, 0xE4, 0x69, 0xB0, 0x68, 0xC5, + 0x3C, 0xE4, 0x6C, 0x5A, 0x46, 0xE7, 0xCD, 0xC7, 0xFA, 0xEF, 0xC4, 0xEC, + 0x4B, 0xBD, 0x6A, 0xA4, 0xAC, 0xFD, 0xCC, 0x28, 0x51, 0xEF, 0x92, 0xB4, + 0x29, 0xAB, 0xAB, 0x35, 0x9A, 0x4C, 0xE4, 0xC4, 0x08, 0xC6, 0x26, 0xCC, + 0xF8, 0x69, 0x9F, 0xE4, 0x9C, 0xF0, 0x29, 0xD3, 0x5C, 0xF9, 0xC6, 0x16, + 0x25, 0x9E, 0x23, 0xC3, 0x20, 0xC1, 0x3D, 0x0F, 0x3F, 0x38, 0x40, 0xB0, + 0xFE, 0x82, 0x44, 0x38, 0xAA, 0x5A, 0x1A, 0x8A, 0x6B, 0x63, 0x58, 0x38, + 0xB4, 0x15, 0xD3, 0xB6, 0x11, 0x69, 0x7B, 0x1E, 0x54, 0xEE, 0x8C, 0x1A, + 0x22, 0xAC, 0x72, 0x97, 0x3F, 0x23, 0x59, 0x9B, 0xC9, 0x22, 0x84, 0xC1, + 0x07, 0x4F, 0xCC, 0x7F, 0xE2, 0x57, 0xCA, 0x12, 0x70, 0xBB, 0xA6, 0x65, + 0xF3, 0x69, 0x75, 0x63, 0xBD, 0x95, 0xFB, 0x1B, 0x97, 0xCD, 0xE4, 0xA8, + 0xAF, 0xF6, 0xD1, 0x4E, 0xA8, 0xD9, 0x8A, 0x71, 0x24, 0xCD, 0x36, 0x3D, + 0xBC, 0x96, 0xC4, 0xF1, 0x6C, 0xA9, 0xAE, 0xE5, 0xCF, 0x0D, 0x6E, 0x28, + 0x0D, 0xB0, 0x0E, 0xB5, 0xCA, 0x51, 0x7B, 0x78, 0x14, 0xC3, 0x20, 0x2F, + 0x7F, 0xFB, 0x14, 0x55, 0xE1, 0x11, 0x99, 0xFD, 0xD5, 0x0A, 0xA1, 0x9E, + 0x02, 0xE3, 0x62, 0x5F, 0xEB, 0x35, 0x4B, 0x2C, 0xB8, 0x72, 0xE8, 0x3E, + 0x3D, 0x4F, 0xAC, 0x2C, 0xBB, 0x2E, 0x86, 0xE2, 0xA3, 0x76, 0x8F, 0xE5, + 0x93, 0x2A, 0xCF, 0xA5, 0xAB, 0xC8, 0x5C, 0x8D, 0x4B, 0x06, 0xFF, 0x12, + 0x46, 0xAC, 0x78, 0xCB, 0x14, 0x07, 0x35, 0xE0, 0xA9, 0xDF, 0x8B, 0xE9, + 0xAF, 0x15, 0x4F, 0x16, 0x89, 0x5B, 0xBD, 0xF6, 0x8D, 0xC6, 0x59, 0xAE, + 0x88, 0x85, 0x0E, 0xC1, 0x89, 0xEB, 0x1F, 0x67, 0xC5, 0x45, 0x8E, 0xFF, + 0x6D, 0x37, 0x36, 0x2B, 0x78, 0x66, 0x83, 0x91, 0x51, 0x2B, 0x3D, 0xFF, + 0x51, 0x77, 0x76, 0x62, 0xA1, 0xEC, 0x67, 0x3E, 0x3E, 0x81, 0x83, 0xE0, + 0x56, 0xA9, 0x50, 0x1F, 0x1F, 0x7A, 0x99, 0xAB, 0x63, 0xBF, 0x84, 0x17, + 0x77, 0xF1, 0x0D, 0x3B, 0xDF, 0xF7, 0x9C, 0x61, 0xB3, 0x35, 0x98, 0x8A, + 0x3A, 0xB2, 0xEC, 0x3C, 0x1A, 0x37, 0x3F, 0x7E, 0x8F, 0x92, 0xCF, 0xD9, + 0x12, 0x14, 0x64, 0xDA, 0x10, 0x02, 0x15, 0x41, 0xFF, 0x4F, 0xC4, 0xEB, + 0x1C, 0xA3, 0xC9, 0xFA, 0x99, 0xF7, 0x46, 0xE9, 0xE1, 0x18, 0xD9, 0xB1, + 0xB8, 0x32, 0x2D, 0xCB, 0x14, 0x0C, 0x50, 0xD8, 0x83, 0x65, 0x83, 0xEE, + 0xB9, 0x5C, 0xCF, 0xCB, 0x05, 0x5A, 0x4C, 0xFA, 0x19, 0x97, 0x6B, 0xD6, + 0x5D, 0x13, 0xD3, 0xC2, 0x5C, 0x54, 0xBC, 0x32, 0x73, 0xA0, 0x78, 0xF5, + 0xF1, 0x6D, 0x1E, 0xCB, 0x9F, 0xA5, 0xA6, 0x9F, 0x22, 0xDC, 0xD1, 0x51, + 0x9E, 0x82, 0x79, 0x64, 0x60, 0x29, 0x13, 0x3E, 0xA3, 0xFD, 0x4F, 0x72, + 0x6A, 0xAB, 0xE2, 0xD4, 0xE5, 0xB8, 0x24, 0x55, 0x2C, 0x44, 0x4B, 0x8A, + 0x88, 0x44, 0x9C, 0xCA, 0x84, 0xD3, 0x2A, 0x3B +}; + +static const unsigned char TA95_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA96_DN[] = { + 0x30, 0x78, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x0E, + 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x05, 0x43, 0x65, 0x72, + 0x65, 0x73, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, + 0x0F, 0x56, 0x41, 0x54, 0x45, 0x53, 0x2D, 0x51, 0x32, 0x38, 0x32, 0x36, + 0x30, 0x30, 0x34, 0x4A, 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x23, 0x41, 0x43, 0x20, 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, + 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x20, 0x53, 0x45, 0x52, 0x56, + 0x49, 0x44, 0x4F, 0x52, 0x45, 0x53, 0x20, 0x53, 0x45, 0x47, 0x55, 0x52, + 0x4F, 0x53 +}; + +static const unsigned char TA96_EC_Q[] = { + 0x04, 0xF6, 0xBA, 0x57, 0x53, 0xC8, 0xCA, 0xAB, 0xDF, 0x36, 0x4A, 0x52, + 0x21, 0xE4, 0x97, 0xD2, 0x83, 0x67, 0x9E, 0xF0, 0x65, 0x51, 0xD0, 0x5E, + 0x87, 0xC7, 0x47, 0xB1, 0x59, 0xF2, 0x57, 0x47, 0x9B, 0x00, 0x02, 0x93, + 0x44, 0x17, 0x69, 0xDB, 0x42, 0xC7, 0xB1, 0xB2, 0x3A, 0x18, 0x0E, 0xB4, + 0x5D, 0x8C, 0xB3, 0x66, 0x5D, 0xA1, 0x34, 0xF9, 0x36, 0x2C, 0x49, 0xDB, + 0xF3, 0x46, 0xFC, 0xB3, 0x44, 0x69, 0x44, 0x13, 0x66, 0xFD, 0xD7, 0xC5, + 0xFD, 0xAF, 0x36, 0x4D, 0xCE, 0x03, 0x4D, 0x07, 0x71, 0xCF, 0xAF, 0x6A, + 0x05, 0xD2, 0xA2, 0x43, 0x5A, 0x0A, 0x52, 0x6F, 0x01, 0x03, 0x4E, 0x8E, + 0x8B +}; + +static const unsigned char TA97_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x45, 0x31 +}; + +static const unsigned char TA97_EC_Q[] = { + 0x04, 0xDE, 0x6F, 0xF8, 0x7F, 0x1C, 0xDF, 0xED, 0xF9, 0x47, 0x87, 0x86, + 0xB1, 0xA4, 0xC0, 0x8A, 0xF8, 0x82, 0x97, 0x80, 0xEA, 0x8F, 0xC8, 0x4A, + 0x5E, 0x2A, 0x7D, 0x88, 0x68, 0xA7, 0x01, 0x62, 0x14, 0x91, 0x24, 0x7A, + 0x5C, 0x9E, 0xA3, 0x17, 0x7D, 0x8A, 0x86, 0x21, 0x34, 0x18, 0x50, 0x1B, + 0x10, 0xDE, 0xD0, 0x37, 0x4B, 0x26, 0xC7, 0x19, 0x60, 0x80, 0xE9, 0x34, + 0xBD, 0x60, 0x19, 0x36, 0x40, 0xD6, 0x29, 0x87, 0x09, 0x3C, 0x91, 0x7A, + 0xF6, 0xBC, 0x13, 0x23, 0xDD, 0x59, 0x4E, 0x04, 0x5E, 0xCF, 0xC8, 0x02, + 0x1C, 0x18, 0x53, 0xC1, 0x31, 0xD8, 0xDA, 0x20, 0xE9, 0x44, 0x8D, 0xE4, + 0x76 +}; + +static const unsigned char TA98_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x32 +}; + +static const unsigned char TA98_RSA_N[] = { + 0xBB, 0x37, 0xCD, 0x34, 0xDC, 0x7B, 0x6B, 0xC9, 0xB2, 0x68, 0x90, 0xAD, + 0x4A, 0x75, 0xFF, 0x46, 0xBA, 0x21, 0x0A, 0x08, 0x8D, 0xF5, 0x19, 0x54, + 0xC9, 0xFB, 0x88, 0xDB, 0xF3, 0xAE, 0xF2, 0x3A, 0x89, 0x91, 0x3C, 0x7A, + 0xE6, 0xAB, 0x06, 0x1A, 0x6B, 0xCF, 0xAC, 0x2D, 0xE8, 0x5E, 0x09, 0x24, + 0x44, 0xBA, 0x62, 0x9A, 0x7E, 0xD6, 0xA3, 0xA8, 0x7E, 0xE0, 0x54, 0x75, + 0x20, 0x05, 0xAC, 0x50, 0xB7, 0x9C, 0x63, 0x1A, 0x6C, 0x30, 0xDC, 0xDA, + 0x1F, 0x19, 0xB1, 0xD7, 0x1E, 0xDE, 0xFD, 0xD7, 0xE0, 0xCB, 0x94, 0x83, + 0x37, 0xAE, 0xEC, 0x1F, 0x43, 0x4E, 0xDD, 0x7B, 0x2C, 0xD2, 0xBD, 0x2E, + 0xA5, 0x2F, 0xE4, 0xA9, 0xB8, 0xAD, 0x3A, 0xD4, 0x99, 0xA4, 0xB6, 0x25, + 0xE9, 0x9B, 0x6B, 0x00, 0x60, 0x92, 0x60, 0xFF, 0x4F, 0x21, 0x49, 0x18, + 0xF7, 0x67, 0x90, 0xAB, 0x61, 0x06, 0x9C, 0x8F, 0xF2, 0xBA, 0xE9, 0xB4, + 0xE9, 0x92, 0x32, 0x6B, 0xB5, 0xF3, 0x57, 0xE8, 0x5D, 0x1B, 0xCD, 0x8C, + 0x1D, 0xAB, 0x95, 0x04, 0x95, 0x49, 0xF3, 0x35, 0x2D, 0x96, 0xE3, 0x49, + 0x6D, 0xDD, 0x77, 0xE3, 0xFB, 0x49, 0x4B, 0xB4, 0xAC, 0x55, 0x07, 0xA9, + 0x8F, 0x95, 0xB3, 0xB4, 0x23, 0xBB, 0x4C, 0x6D, 0x45, 0xF0, 0xF6, 0xA9, + 0xB2, 0x95, 0x30, 0xB4, 0xFD, 0x4C, 0x55, 0x8C, 0x27, 0x4A, 0x57, 0x14, + 0x7C, 0x82, 0x9D, 0xCD, 0x73, 0x92, 0xD3, 0x16, 0x4A, 0x06, 0x0C, 0x8C, + 0x50, 0xD1, 0x8F, 0x1E, 0x09, 0xBE, 0x17, 0xA1, 0xE6, 0x21, 0xCA, 0xFD, + 0x83, 0xE5, 0x10, 0xBC, 0x83, 0xA5, 0x0A, 0xC4, 0x67, 0x28, 0xF6, 0x73, + 0x14, 0x14, 0x3D, 0x46, 0x76, 0xC3, 0x87, 0x14, 0x89, 0x21, 0x34, 0x4D, + 0xAF, 0x0F, 0x45, 0x0C, 0xA6, 0x49, 0xA1, 0xBA, 0xBB, 0x9C, 0xC5, 0xB1, + 0x33, 0x83, 0x29, 0x85 +}; + +static const unsigned char TA98_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA99_DN[] = { + 0x30, 0x81, 0xA7, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x4E, 0x65, + 0x74, 0x4C, 0x6F, 0x63, 0x6B, 0x20, 0x4B, 0x66, 0x74, 0x2E, 0x31, 0x37, + 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x2E, 0x54, 0x61, 0x6E, + 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, 0x6E, 0x79, 0x6B, + 0x69, 0x61, 0x64, 0xC3, 0xB3, 0x6B, 0x20, 0x28, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x29, 0x31, 0x35, 0x30, 0x33, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x2C, 0x4E, 0x65, 0x74, 0x4C, 0x6F, 0x63, + 0x6B, 0x20, 0x41, 0x72, 0x61, 0x6E, 0x79, 0x20, 0x28, 0x43, 0x6C, 0x61, + 0x73, 0x73, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x29, 0x20, 0x46, 0xC5, 0x91, + 0x74, 0x61, 0x6E, 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, + 0x6E, 0x79 +}; + +static const unsigned char TA99_RSA_N[] = { + 0xC4, 0x24, 0x5E, 0x73, 0xBE, 0x4B, 0x6D, 0x14, 0xC3, 0xA1, 0xF4, 0xE3, + 0x97, 0x90, 0x6E, 0xD2, 0x30, 0x45, 0x1E, 0x3C, 0xEE, 0x67, 0xD9, 0x64, + 0xE0, 0x1A, 0x8A, 0x7F, 0xCA, 0x30, 0xCA, 0x83, 0xE3, 0x20, 0xC1, 0xE3, + 0xF4, 0x3A, 0xD3, 0x94, 0x5F, 0x1A, 0x7C, 0x5B, 0x6D, 0xBF, 0x30, 0x4F, + 0x84, 0x27, 0xF6, 0x9F, 0x1F, 0x49, 0xBC, 0xC6, 0x99, 0x0A, 0x90, 0xF2, + 0x0F, 0xF5, 0x7F, 0x43, 0x84, 0x37, 0x63, 0x51, 0x8B, 0x7A, 0xA5, 0x70, + 0xFC, 0x7A, 0x58, 0xCD, 0x8E, 0x9B, 0xED, 0xC3, 0x46, 0x6C, 0x84, 0x70, + 0x5D, 0xDA, 0xF3, 0x01, 0x90, 0x23, 0xFC, 0x4E, 0x30, 0xA9, 0x7E, 0xE1, + 0x27, 0x63, 0xE7, 0xED, 0x64, 0x3C, 0xA0, 0xB8, 0xC9, 0x33, 0x63, 0xFE, + 0x16, 0x90, 0xFF, 0xB0, 0xB8, 0xFD, 0xD7, 0xA8, 0xC0, 0xC0, 0x94, 0x43, + 0x0B, 0xB6, 0xD5, 0x59, 0xA6, 0x9E, 0x56, 0xD0, 0x24, 0x1F, 0x70, 0x79, + 0xAF, 0xDB, 0x39, 0x54, 0x0D, 0x65, 0x75, 0xD9, 0x15, 0x41, 0x94, 0x01, + 0xAF, 0x5E, 0xEC, 0xF6, 0x8D, 0xF1, 0xFF, 0xAD, 0x64, 0xFE, 0x20, 0x9A, + 0xD7, 0x5C, 0xEB, 0xFE, 0xA6, 0x1F, 0x08, 0x64, 0xA3, 0x8B, 0x76, 0x55, + 0xAD, 0x1E, 0x3B, 0x28, 0x60, 0x2E, 0x87, 0x25, 0xE8, 0xAA, 0xAF, 0x1F, + 0xC6, 0x64, 0x46, 0x20, 0xB7, 0x70, 0x7F, 0x3C, 0xDE, 0x48, 0xDB, 0x96, + 0x53, 0xB7, 0x39, 0x77, 0xE4, 0x1A, 0xE2, 0xC7, 0x16, 0x84, 0x76, 0x97, + 0x5B, 0x2F, 0xBB, 0x19, 0x15, 0x85, 0xF8, 0x69, 0x85, 0xF5, 0x99, 0xA7, + 0xA9, 0xF2, 0x34, 0xA7, 0xA9, 0xB6, 0xA6, 0x03, 0xFC, 0x6F, 0x86, 0x3D, + 0x54, 0x7C, 0x76, 0x04, 0x9B, 0x6B, 0xF9, 0x40, 0x5D, 0x00, 0x34, 0xC7, + 0x2E, 0x99, 0x75, 0x9D, 0xE5, 0x88, 0x03, 0xAA, 0x4D, 0xF8, 0x03, 0xD2, + 0x42, 0x76, 0xC0, 0x1B +}; + +static const unsigned char TA99_RSA_E[] = { + 0xA8, 0x8B +}; + +static const unsigned char TA100_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x32 +}; + +static const unsigned char TA100_RSA_N[] = { + 0xBA, 0x39, 0xC1, 0x37, 0x7A, 0x68, 0x45, 0x2B, 0x14, 0xB4, 0xEB, 0xE4, + 0x13, 0xEB, 0x57, 0x75, 0x23, 0x4D, 0x8F, 0x24, 0x2D, 0x16, 0xE8, 0xAE, + 0x8E, 0xC9, 0x7D, 0xA4, 0x57, 0x3B, 0x2A, 0x76, 0x25, 0x33, 0x83, 0x6C, + 0xEA, 0x32, 0x8A, 0x94, 0x9B, 0x4E, 0x3C, 0x96, 0xE4, 0xFD, 0x51, 0xBF, + 0x99, 0xC9, 0x93, 0x7E, 0xBF, 0xF9, 0xAD, 0xA7, 0xB2, 0x48, 0x2B, 0x07, + 0x1C, 0x27, 0xF5, 0x4C, 0xBC, 0x70, 0x12, 0x77, 0xA4, 0x85, 0x54, 0xB5, + 0xFD, 0x90, 0x7A, 0xE4, 0xA3, 0xE4, 0x51, 0x58, 0x03, 0xCD, 0x10, 0x79, + 0x79, 0xEE, 0x6B, 0x93, 0x1F, 0x64, 0x8E, 0x6B, 0x64, 0xAB, 0xA3, 0x13, + 0xE3, 0x71, 0xFE, 0x7D, 0xAB, 0x9C, 0xDD, 0x27, 0x53, 0x37, 0xB3, 0xAA, + 0x18, 0xC2, 0x59, 0x26, 0xEC, 0x5B, 0x1F, 0xD2, 0xE6, 0x65, 0x7C, 0xEF, + 0x93, 0xBD, 0xD8, 0x58, 0x5C, 0x0B, 0xC0, 0xE3, 0x65, 0x6F, 0x3C, 0xC7, + 0xCA, 0x59, 0xE3, 0xFE, 0x6E, 0x5F, 0xAC, 0x83, 0xBE, 0xFD, 0x5D, 0x25, + 0x4E, 0x2A, 0x29, 0x3B, 0xD6, 0x0B, 0xAB, 0x17, 0x32, 0x78, 0xA4, 0xE1, + 0x3E, 0x94, 0x46, 0xBE, 0x62, 0x6E, 0x9B, 0xDE, 0x46, 0xA8, 0xB1, 0x16, + 0xE7, 0x85, 0x6E, 0xF4, 0x08, 0x40, 0x45, 0x11, 0xA0, 0x9E, 0x54, 0x44, + 0x84, 0xF7, 0xD8, 0x36, 0xCE, 0xF5, 0x50, 0x47, 0xDC, 0x2C, 0x30, 0x9B, + 0xEE, 0xC0, 0xF5, 0x96, 0xD2, 0xFE, 0x09, 0x86, 0xC7, 0x06, 0x59, 0xAE, + 0x4F, 0xAE, 0x8E, 0x11, 0x98, 0x7B, 0xF3, 0x0B, 0x52, 0xAA, 0x62, 0x26, + 0xAA, 0x21, 0xDF, 0x8E, 0x25, 0x33, 0x79, 0x97, 0x16, 0x49, 0x8D, 0xF5, + 0x3E, 0xD5, 0x47, 0x9F, 0x37, 0x31, 0x49, 0x33, 0x72, 0x05, 0x4D, 0x0C, + 0xB6, 0x55, 0x8C, 0xF1, 0x57, 0x8F, 0x8A, 0x87, 0xD1, 0xAD, 0xC5, 0x11, + 0x12, 0x39, 0xA0, 0xAD +}; + +static const unsigned char TA100_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA101_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x31 +}; + +static const unsigned char TA101_RSA_N[] = { + 0xAD, 0xE8, 0x24, 0x73, 0xF4, 0x14, 0x37, 0xF3, 0x9B, 0x9E, 0x2B, 0x57, + 0x28, 0x1C, 0x87, 0xBE, 0xDC, 0xB7, 0xDF, 0x38, 0x90, 0x8C, 0x6E, 0x3C, + 0xE6, 0x57, 0xA0, 0x78, 0xF7, 0x75, 0xC2, 0xA2, 0xFE, 0xF5, 0x6A, 0x6E, + 0xF6, 0x00, 0x4F, 0x28, 0xDB, 0xDE, 0x68, 0x86, 0x6C, 0x44, 0x93, 0xB6, + 0xB1, 0x63, 0xFD, 0x14, 0x12, 0x6B, 0xBF, 0x1F, 0xD2, 0xEA, 0x31, 0x9B, + 0x21, 0x7E, 0xD1, 0x33, 0x3C, 0xBA, 0x48, 0xF5, 0xDD, 0x79, 0xDF, 0xB3, + 0xB8, 0xFF, 0x12, 0xF1, 0x21, 0x9A, 0x4B, 0xC1, 0x8A, 0x86, 0x71, 0x69, + 0x4A, 0x66, 0x66, 0x6C, 0x8F, 0x7E, 0x3C, 0x70, 0xBF, 0xAD, 0x29, 0x22, + 0x06, 0xF3, 0xE4, 0xC0, 0xE6, 0x80, 0xAE, 0xE2, 0x4B, 0x8F, 0xB7, 0x99, + 0x7E, 0x94, 0x03, 0x9F, 0xD3, 0x47, 0x97, 0x7C, 0x99, 0x48, 0x23, 0x53, + 0xE8, 0x38, 0xAE, 0x4F, 0x0A, 0x6F, 0x83, 0x2E, 0xD1, 0x49, 0x57, 0x8C, + 0x80, 0x74, 0xB6, 0xDA, 0x2F, 0xD0, 0x38, 0x8D, 0x7B, 0x03, 0x70, 0x21, + 0x1B, 0x75, 0xF2, 0x30, 0x3C, 0xFA, 0x8F, 0xAE, 0xDD, 0xDA, 0x63, 0xAB, + 0xEB, 0x16, 0x4F, 0xC2, 0x8E, 0x11, 0x4B, 0x7E, 0xCF, 0x0B, 0xE8, 0xFF, + 0xB5, 0x77, 0x2E, 0xF4, 0xB2, 0x7B, 0x4A, 0xE0, 0x4C, 0x12, 0x25, 0x0C, + 0x70, 0x8D, 0x03, 0x29, 0xA0, 0xE1, 0x53, 0x24, 0xEC, 0x13, 0xD9, 0xEE, + 0x19, 0xBF, 0x10, 0xB3, 0x4A, 0x8C, 0x3F, 0x89, 0xA3, 0x61, 0x51, 0xDE, + 0xAC, 0x87, 0x07, 0x94, 0xF4, 0x63, 0x71, 0xEC, 0x2E, 0xE2, 0x6F, 0x5B, + 0x98, 0x81, 0xE1, 0x89, 0x5C, 0x34, 0x79, 0x6C, 0x76, 0xEF, 0x3B, 0x90, + 0x62, 0x79, 0xE6, 0xDB, 0xA4, 0x9A, 0x2F, 0x26, 0xC5, 0xD0, 0x10, 0xE1, + 0x0E, 0xDE, 0xD9, 0x10, 0x8E, 0x16, 0xFB, 0xB7, 0xF7, 0xA8, 0xF7, 0xC7, + 0xE5, 0x02, 0x07, 0x98, 0x8F, 0x36, 0x08, 0x95, 0xE7, 0xE2, 0x37, 0x96, + 0x0D, 0x36, 0x75, 0x9E, 0xFB, 0x0E, 0x72, 0xB1, 0x1D, 0x9B, 0xBC, 0x03, + 0xF9, 0x49, 0x05, 0xD8, 0x81, 0xDD, 0x05, 0xB4, 0x2A, 0xD6, 0x41, 0xE9, + 0xAC, 0x01, 0x76, 0x95, 0x0A, 0x0F, 0xD8, 0xDF, 0xD5, 0xBD, 0x12, 0x1F, + 0x35, 0x2F, 0x28, 0x17, 0x6C, 0xD2, 0x98, 0xC1, 0xA8, 0x09, 0x64, 0x77, + 0x6E, 0x47, 0x37, 0xBA, 0xCE, 0xAC, 0x59, 0x5E, 0x68, 0x9D, 0x7F, 0x72, + 0xD6, 0x89, 0xC5, 0x06, 0x41, 0x29, 0x3E, 0x59, 0x3E, 0xDD, 0x26, 0xF5, + 0x24, 0xC9, 0x11, 0xA7, 0x5A, 0xA3, 0x4C, 0x40, 0x1F, 0x46, 0xA1, 0x99, + 0xB5, 0xA7, 0x3A, 0x51, 0x6E, 0x86, 0x3B, 0x9E, 0x7D, 0x72, 0xA7, 0x12, + 0x05, 0x78, 0x59, 0xED, 0x3E, 0x51, 0x78, 0x15, 0x0B, 0x03, 0x8F, 0x8D, + 0xD0, 0x2F, 0x05, 0xB2, 0x3E, 0x7B, 0x4A, 0x1C, 0x4B, 0x73, 0x05, 0x12, + 0xFC, 0xC6, 0xEA, 0xE0, 0x50, 0x13, 0x7C, 0x43, 0x93, 0x74, 0xB3, 0xCA, + 0x74, 0xE7, 0x8E, 0x1F, 0x01, 0x08, 0xD0, 0x30, 0xD4, 0x5B, 0x71, 0x36, + 0xB4, 0x07, 0xBA, 0xC1, 0x30, 0x30, 0x5C, 0x48, 0xB7, 0x82, 0x3B, 0x98, + 0xA6, 0x7D, 0x60, 0x8A, 0xA2, 0xA3, 0x29, 0x82, 0xCC, 0xBA, 0xBD, 0x83, + 0x04, 0x1B, 0xA2, 0x83, 0x03, 0x41, 0xA1, 0xD6, 0x05, 0xF1, 0x1B, 0xC2, + 0xB6, 0xF0, 0xA8, 0x7C, 0x86, 0x3B, 0x46, 0xA8, 0x48, 0x2A, 0x88, 0xDC, + 0x76, 0x9A, 0x76, 0xBF, 0x1F, 0x6A, 0xA5, 0x3D, 0x19, 0x8F, 0xEB, 0x38, + 0xF3, 0x64, 0xDE, 0xC8, 0x2B, 0x0D, 0x0A, 0x28, 0xFF, 0xF7, 0xDB, 0xE2, + 0x15, 0x42, 0xD4, 0x22, 0xD0, 0x27, 0x5D, 0xE1, 0x79, 0xFE, 0x18, 0xE7, + 0x70, 0x88, 0xAD, 0x4E, 0xE6, 0xD9, 0x8B, 0x3A, 0xC6, 0xDD, 0x27, 0x51, + 0x6E, 0xFF, 0xBC, 0x64, 0xF5, 0x33, 0x43, 0x4F +}; + +static const unsigned char TA101_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA102_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA102_RSA_N[] = { + 0xCE, 0xDE, 0xFD, 0xA6, 0xFB, 0xEC, 0xEC, 0x14, 0x34, 0x3C, 0x07, 0x06, + 0x5A, 0x6C, 0x59, 0xF7, 0x19, 0x35, 0xDD, 0xF7, 0xC1, 0x9D, 0x55, 0xAA, + 0xD3, 0xCD, 0x3B, 0xA4, 0x93, 0x72, 0xEF, 0x0A, 0xFA, 0x6D, 0x9D, 0xF6, + 0xF0, 0x85, 0x80, 0x5B, 0xA1, 0x48, 0x52, 0x9F, 0x39, 0xC5, 0xB7, 0xEE, + 0x28, 0xAC, 0xEF, 0xCB, 0x76, 0x68, 0x14, 0xB9, 0xDF, 0xAD, 0x01, 0x6C, + 0x99, 0x1F, 0xC4, 0x22, 0x1D, 0x9F, 0xFE, 0x72, 0x77, 0xE0, 0x2C, 0x5B, + 0xAF, 0xE4, 0x04, 0xBF, 0x4F, 0x72, 0xA0, 0x1A, 0x34, 0x98, 0xE8, 0x39, + 0x68, 0xEC, 0x95, 0x25, 0x7B, 0x76, 0xA1, 0xE6, 0x69, 0xB9, 0x85, 0x19, + 0xBD, 0x89, 0x8C, 0xFE, 0xAD, 0xED, 0x36, 0xEA, 0x73, 0xBC, 0xFF, 0x83, + 0xE2, 0xCB, 0x7D, 0xC1, 0xD2, 0xCE, 0x4A, 0xB3, 0x8D, 0x05, 0x9E, 0x8B, + 0x49, 0x93, 0xDF, 0xC1, 0x5B, 0xD0, 0x6E, 0x5E, 0xF0, 0x2E, 0x30, 0x2E, + 0x82, 0xFC, 0xFA, 0xBC, 0xB4, 0x17, 0x0A, 0x48, 0xE5, 0x88, 0x9B, 0xC5, + 0x9B, 0x6B, 0xDE, 0xB0, 0xCA, 0xB4, 0x03, 0xF0, 0xDA, 0xF4, 0x90, 0xB8, + 0x65, 0x64, 0xF7, 0x5C, 0x4C, 0xAD, 0xE8, 0x7E, 0x66, 0x5E, 0x99, 0xD7, + 0xB8, 0xC2, 0x3E, 0xC8, 0xD0, 0x13, 0x9D, 0xAD, 0xEE, 0xE4, 0x45, 0x7B, + 0x89, 0x55, 0xF7, 0x8A, 0x1F, 0x62, 0x52, 0x84, 0x12, 0xB3, 0xC2, 0x40, + 0x97, 0xE3, 0x8A, 0x1F, 0x47, 0x91, 0xA6, 0x74, 0x5A, 0xD2, 0xF8, 0xB1, + 0x63, 0x28, 0x10, 0xB8, 0xB3, 0x09, 0xB8, 0x56, 0x77, 0x40, 0xA2, 0x26, + 0x98, 0x79, 0xC6, 0xFE, 0xDF, 0x25, 0xEE, 0x3E, 0xE5, 0xA0, 0x7F, 0xD4, + 0x61, 0x0F, 0x51, 0x4B, 0x3C, 0x3F, 0x8C, 0xDA, 0xE1, 0x70, 0x74, 0xD8, + 0xC2, 0x68, 0xA1, 0xF9, 0xC1, 0x0C, 0xE9, 0xA1, 0xE2, 0x7F, 0xBB, 0x55, + 0x3C, 0x76, 0x06, 0xEE, 0x6A, 0x4E, 0xCC, 0x92, 0x88, 0x30, 0x4D, 0x9A, + 0xBD, 0x4F, 0x0B, 0x48, 0x9A, 0x84, 0xB5, 0x98, 0xA3, 0xD5, 0xFB, 0x73, + 0xC1, 0x57, 0x61, 0xDD, 0x28, 0x56, 0x75, 0x13, 0xAE, 0x87, 0x8E, 0xE7, + 0x0C, 0x51, 0x09, 0x10, 0x75, 0x88, 0x4C, 0xBC, 0x8D, 0xF9, 0x7B, 0x3C, + 0xD4, 0x22, 0x48, 0x1F, 0x2A, 0xDC, 0xEB, 0x6B, 0xBB, 0x44, 0xB1, 0xCB, + 0x33, 0x71, 0x32, 0x46, 0xAF, 0xAD, 0x4A, 0xF1, 0x8C, 0xE8, 0x74, 0x3A, + 0xAC, 0xE7, 0x1A, 0x22, 0x73, 0x80, 0xD2, 0x30, 0xF7, 0x25, 0x42, 0xC7, + 0x22, 0x3B, 0x3B, 0x12, 0xAD, 0x96, 0x2E, 0xC6, 0xC3, 0x76, 0x07, 0xAA, + 0x20, 0xB7, 0x35, 0x49, 0x57, 0xE9, 0x92, 0x49, 0xE8, 0x76, 0x16, 0x72, + 0x31, 0x67, 0x2B, 0x96, 0x7E, 0x8A, 0xA3, 0xC7, 0x94, 0x56, 0x22, 0xBF, + 0x6A, 0x4B, 0x7E, 0x01, 0x21, 0xB2, 0x23, 0x32, 0xDF, 0xE4, 0x9A, 0x44, + 0x6D, 0x59, 0x5B, 0x5D, 0xF5, 0x00, 0xA0, 0x1C, 0x9B, 0xC6, 0x78, 0x97, + 0x8D, 0x90, 0xFF, 0x9B, 0xC8, 0xAA, 0xB4, 0xAF, 0x11, 0x51, 0x39, 0x5E, + 0xD9, 0xFB, 0x67, 0xAD, 0xD5, 0x5B, 0x11, 0x9D, 0x32, 0x9A, 0x1B, 0xBD, + 0xD5, 0xBA, 0x5B, 0xA5, 0xC9, 0xCB, 0x25, 0x69, 0x53, 0x55, 0x27, 0x5C, + 0xE0, 0xCA, 0x36, 0xCB, 0x88, 0x61, 0xFB, 0x1E, 0xB7, 0xD0, 0xCB, 0xEE, + 0x16, 0xFB, 0xD3, 0xA6, 0x4C, 0xDE, 0x92, 0xA5, 0xD4, 0xE2, 0xDF, 0xF5, + 0x06, 0x54, 0xDE, 0x2E, 0x9D, 0x4B, 0xB4, 0x93, 0x30, 0xAA, 0x81, 0xCE, + 0xDD, 0x1A, 0xDC, 0x51, 0x73, 0x0D, 0x4F, 0x70, 0xE9, 0xE5, 0xB6, 0x16, + 0x21, 0x19, 0x79, 0xB2, 0xE6, 0x89, 0x0B, 0x75, 0x64, 0xCA, 0xD5, 0xAB, + 0xBC, 0x09, 0xC1, 0x18, 0xA1, 0xFF, 0xD4, 0x54, 0xA1, 0x85, 0x3C, 0xFD, + 0x14, 0x24, 0x03, 0xB2, 0x87, 0xD3, 0xA4, 0xB7 +}; + +static const unsigned char TA102_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA103_DN[] = { + 0x30, 0x37, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0B, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x54, + 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, 0x20, 0x52, + 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x31 +}; + +static const unsigned char TA103_RSA_N[] = { + 0xC2, 0xBE, 0xEB, 0x27, 0xF0, 0x21, 0xA3, 0xF3, 0x69, 0x26, 0x55, 0x7E, + 0x9D, 0xC5, 0x55, 0x16, 0x91, 0x5C, 0xFD, 0xEF, 0x21, 0xBF, 0x53, 0x80, + 0x7A, 0x2D, 0xD2, 0x91, 0x8C, 0x63, 0x31, 0xF0, 0xEC, 0x24, 0xF0, 0xC3, + 0xA5, 0xD2, 0x72, 0x7C, 0x10, 0x6D, 0xF4, 0x37, 0xB7, 0xE5, 0xE6, 0x7C, + 0x79, 0xEA, 0x8C, 0xB5, 0x82, 0x8B, 0xAE, 0x48, 0xB6, 0xAC, 0x00, 0xDC, + 0x65, 0x75, 0xEC, 0x2A, 0x4D, 0x5F, 0xC1, 0x87, 0xF5, 0x20, 0x65, 0x2B, + 0x81, 0xA8, 0x47, 0x3E, 0x89, 0x23, 0x95, 0x30, 0x16, 0x90, 0x7F, 0xE8, + 0x57, 0x07, 0x48, 0xE7, 0x19, 0xAE, 0xBF, 0x45, 0x67, 0xB1, 0x37, 0x1B, + 0x06, 0x2A, 0xFE, 0xDE, 0xF9, 0xAC, 0x7D, 0x83, 0xFB, 0x5E, 0xBA, 0xE4, + 0x8F, 0x97, 0x67, 0xBE, 0x4B, 0x8E, 0x8D, 0x64, 0x07, 0x57, 0x38, 0x55, + 0x69, 0x34, 0x36, 0x3D, 0x13, 0x48, 0xEF, 0x4F, 0xE2, 0xD3, 0x66, 0x1E, + 0xA4, 0xCF, 0x1A, 0xB7, 0x5E, 0x36, 0x33, 0xD4, 0xB4, 0x06, 0xBD, 0x18, + 0x01, 0xFD, 0x77, 0x84, 0x50, 0x00, 0x45, 0xF5, 0x8C, 0x5D, 0xE8, 0x23, + 0xBC, 0x7E, 0xFE, 0x35, 0xE1, 0xED, 0x50, 0x7B, 0xA9, 0x30, 0x8D, 0x19, + 0xD3, 0x09, 0x8E, 0x68, 0x67, 0x5D, 0xBF, 0x3C, 0x97, 0x18, 0x53, 0xBB, + 0x29, 0x62, 0xC5, 0xCA, 0x5E, 0x72, 0xC1, 0xC7, 0x96, 0xD4, 0xDB, 0x2D, + 0xA0, 0xB4, 0x1F, 0x69, 0x03, 0xEC, 0xEA, 0xE2, 0x50, 0xF1, 0x0C, 0x3C, + 0xF0, 0xAC, 0xF3, 0x53, 0x2D, 0xF0, 0x1C, 0xF5, 0xED, 0x6C, 0x39, 0x39, + 0x73, 0x80, 0x16, 0xC8, 0x52, 0xB0, 0x23, 0xCD, 0xE0, 0x3E, 0xDC, 0xDD, + 0x3C, 0x47, 0xA0, 0xBB, 0x35, 0x8A, 0xE2, 0x98, 0x68, 0x8B, 0xBE, 0xE5, + 0xBF, 0x72, 0xEE, 0xD2, 0xFA, 0xA5, 0xED, 0x12, 0xED, 0xFC, 0x98, 0x18, + 0xA9, 0x26, 0x76, 0xDC, 0x28, 0x4B, 0x10, 0x20, 0x1C, 0xD3, 0x7F, 0x16, + 0x77, 0x2D, 0xED, 0x6F, 0x80, 0xF7, 0x49, 0xBB, 0x53, 0x05, 0xBB, 0x5D, + 0x68, 0xC7, 0xD4, 0xC8, 0x75, 0x16, 0x3F, 0x89, 0x5A, 0x8B, 0xF7, 0x17, + 0x47, 0xD4, 0x4C, 0xF1, 0xD2, 0x89, 0x79, 0x3E, 0x4D, 0x3D, 0x98, 0xA8, + 0x61, 0xDE, 0x3A, 0x1E, 0xD2, 0xF8, 0x5E, 0x03, 0xE0, 0xC1, 0xC9, 0x1C, + 0x8C, 0xD3, 0x8D, 0x4D, 0xD3, 0x95, 0x36, 0xB3, 0x37, 0x5F, 0x63, 0x63, + 0x9B, 0x33, 0x14, 0xF0, 0x2D, 0x26, 0x6B, 0x53, 0x7C, 0x89, 0x8C, 0x32, + 0xC2, 0x6E, 0xEC, 0x3D, 0x21, 0x00, 0x39, 0xC9, 0xA1, 0x68, 0xE2, 0x50, + 0x83, 0x2E, 0xB0, 0x3A, 0x2B, 0xF3, 0x36, 0xA0, 0xAC, 0x2F, 0xE4, 0x6F, + 0x61, 0xC2, 0x51, 0x09, 0x39, 0x3E, 0x8B, 0x53, 0xB9, 0xBB, 0x67, 0xDA, + 0xDC, 0x53, 0xB9, 0x76, 0x59, 0x36, 0x9D, 0x43, 0xE5, 0x20, 0xE0, 0x3D, + 0x32, 0x60, 0x85, 0x22, 0x51, 0xB7, 0xC7, 0x33, 0xBB, 0xDD, 0x15, 0x2F, + 0xA4, 0x78, 0xA6, 0x07, 0x7B, 0x81, 0x46, 0x36, 0x04, 0x86, 0xDD, 0x79, + 0x35, 0xC7, 0x95, 0x2C, 0x3B, 0xB0, 0xA3, 0x17, 0x35, 0xE5, 0x73, 0x1F, + 0xB4, 0x5C, 0x59, 0xEF, 0xDA, 0xEA, 0x10, 0x65, 0x7B, 0x7A, 0xD0, 0x7F, + 0x9F, 0xB3, 0xB4, 0x2A, 0x37, 0x3B, 0x70, 0x8B, 0x9B, 0x5B, 0xB9, 0x2B, + 0xB7, 0xEC, 0xB2, 0x51, 0x12, 0x97, 0x53, 0x29, 0x5A, 0xD4, 0xF0, 0x12, + 0x10, 0xDC, 0x4F, 0x02, 0xBB, 0x12, 0x92, 0x2F, 0x62, 0xD4, 0x3F, 0x69, + 0x43, 0x7C, 0x0D, 0xD6, 0xFC, 0x58, 0x75, 0x01, 0x88, 0x9D, 0x58, 0x16, + 0x4B, 0xDE, 0xBA, 0x90, 0xFF, 0x47, 0x01, 0x89, 0x06, 0x6A, 0xF6, 0x5F, + 0xB2, 0x90, 0x6A, 0xB3, 0x02, 0xA6, 0x02, 0x88, 0xBF, 0xB3, 0x47, 0x7E, + 0x2A, 0xD9, 0xD5, 0xFA, 0x68, 0x78, 0x35, 0x4D +}; + +static const unsigned char TA103_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA104_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x42, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x6F, 0x72, 0x65, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, 0x43, 0x79, + 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6C, 0x74, 0x69, + 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA104_RSA_N[] = { + 0xA3, 0x04, 0xBB, 0x22, 0xAB, 0x98, 0x3D, 0x57, 0xE8, 0x26, 0x72, 0x9A, + 0xB5, 0x79, 0xD4, 0x29, 0xE2, 0xE1, 0xE8, 0x95, 0x80, 0xB1, 0xB0, 0xE3, + 0x5B, 0x8E, 0x2B, 0x29, 0x9A, 0x64, 0xDF, 0xA1, 0x5D, 0xED, 0xB0, 0x09, + 0x05, 0x6D, 0xDB, 0x28, 0x2E, 0xCE, 0x62, 0xA2, 0x62, 0xFE, 0xB4, 0x88, + 0xDA, 0x12, 0xEB, 0x38, 0xEB, 0x21, 0x9D, 0xC0, 0x41, 0x2B, 0x01, 0x52, + 0x7B, 0x88, 0x77, 0xD3, 0x1C, 0x8F, 0xC7, 0xBA, 0xB9, 0x88, 0xB5, 0x6A, + 0x09, 0xE7, 0x73, 0xE8, 0x11, 0x40, 0xA7, 0xD1, 0xCC, 0xCA, 0x62, 0x8D, + 0x2D, 0xE5, 0x8F, 0x0B, 0xA6, 0x50, 0xD2, 0xA8, 0x50, 0xC3, 0x28, 0xEA, + 0xF5, 0xAB, 0x25, 0x87, 0x8A, 0x9A, 0x96, 0x1C, 0xA9, 0x67, 0xB8, 0x3F, + 0x0C, 0xD5, 0xF7, 0xF9, 0x52, 0x13, 0x2F, 0xC2, 0x1B, 0xD5, 0x70, 0x70, + 0xF0, 0x8F, 0xC0, 0x12, 0xCA, 0x06, 0xCB, 0x9A, 0xE1, 0xD9, 0xCA, 0x33, + 0x7A, 0x77, 0xD6, 0xF8, 0xEC, 0xB9, 0xF1, 0x68, 0x44, 0x42, 0x48, 0x13, + 0xD2, 0xC0, 0xC2, 0xA4, 0xAE, 0x5E, 0x60, 0xFE, 0xB6, 0xA6, 0x05, 0xFC, + 0xB4, 0xDD, 0x07, 0x59, 0x02, 0xD4, 0x59, 0x18, 0x98, 0x63, 0xF5, 0xA5, + 0x63, 0xE0, 0x90, 0x0C, 0x7D, 0x5D, 0xB2, 0x06, 0x7A, 0xF3, 0x85, 0xEA, + 0xEB, 0xD4, 0x03, 0xAE, 0x5E, 0x84, 0x3E, 0x5F, 0xFF, 0x15, 0xED, 0x69, + 0xBC, 0xF9, 0x39, 0x36, 0x72, 0x75, 0xCF, 0x77, 0x52, 0x4D, 0xF3, 0xC9, + 0x90, 0x2C, 0xB9, 0x3D, 0xE5, 0xC9, 0x23, 0x53, 0x3F, 0x1F, 0x24, 0x98, + 0x21, 0x5C, 0x07, 0x99, 0x29, 0xBD, 0xC6, 0x3A, 0xEC, 0xE7, 0x6E, 0x86, + 0x3A, 0x6B, 0x97, 0x74, 0x63, 0x33, 0xBD, 0x68, 0x18, 0x31, 0xF0, 0x78, + 0x8D, 0x76, 0xBF, 0xFC, 0x9E, 0x8E, 0x5D, 0x2A, 0x86, 0xA7, 0x4D, 0x90, + 0xDC, 0x27, 0x1A, 0x39 +}; + +static const unsigned char TA104_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA105_DN[] = { + 0x30, 0x6F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x4B, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x09, 0x48, 0x6F, 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x48, 0x6F, + 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA105_RSA_N[] = { + 0xB3, 0x88, 0xD7, 0xEA, 0xCE, 0x0F, 0x20, 0x4E, 0xBE, 0xE6, 0xD6, 0x03, + 0x6D, 0xEE, 0x59, 0xFC, 0xC2, 0x57, 0xDF, 0x29, 0x68, 0xA1, 0x83, 0x0E, + 0x3E, 0x68, 0xC7, 0x68, 0x58, 0x9C, 0x1C, 0x60, 0x4B, 0x89, 0x43, 0x0C, + 0xB9, 0xD4, 0x15, 0xB2, 0xEE, 0xC1, 0x4E, 0x75, 0xE9, 0xB5, 0xA7, 0xEF, + 0xE5, 0xE9, 0x35, 0x99, 0xE4, 0xCC, 0x1C, 0xE7, 0x4B, 0x5F, 0x8D, 0x33, + 0x30, 0x20, 0x33, 0x53, 0xD9, 0xA6, 0xBB, 0xD5, 0x3E, 0x13, 0x8E, 0xE9, + 0x1F, 0x87, 0x49, 0xAD, 0x50, 0x2D, 0x50, 0xCA, 0x18, 0xBE, 0x01, 0x58, + 0xA2, 0x13, 0x70, 0x96, 0xBB, 0x89, 0x88, 0x56, 0x80, 0x5C, 0xF8, 0xBD, + 0x2C, 0x3C, 0xE1, 0x4C, 0x57, 0x88, 0xBB, 0xD3, 0xB9, 0x95, 0xEF, 0xCB, + 0xC7, 0xF6, 0xDA, 0x31, 0x74, 0x28, 0xA6, 0xE6, 0x54, 0x89, 0xF5, 0x41, + 0x31, 0xCA, 0xE5, 0x26, 0x1A, 0xCD, 0x82, 0xE0, 0x70, 0xDA, 0x3B, 0x29, + 0xBB, 0xD5, 0x03, 0xF5, 0x99, 0xBA, 0x55, 0xF5, 0x64, 0xD1, 0x60, 0x0E, + 0xB3, 0x89, 0x49, 0xB8, 0x8A, 0x2F, 0x05, 0xD2, 0x84, 0x45, 0x28, 0x7C, + 0x8F, 0x68, 0x50, 0x12, 0x78, 0xFC, 0x0B, 0xB5, 0x53, 0xCB, 0xC2, 0x98, + 0x1C, 0x84, 0xA3, 0x9E, 0xB0, 0xBE, 0x23, 0xA4, 0xDA, 0xDC, 0xC8, 0x2B, + 0x1E, 0xDA, 0x6E, 0x45, 0x1E, 0x89, 0x98, 0xDA, 0xF9, 0x00, 0x2E, 0x06, + 0xE9, 0x0C, 0x3B, 0x70, 0xD5, 0x50, 0x25, 0x88, 0x99, 0xCB, 0xCD, 0x73, + 0x60, 0xF7, 0xD5, 0xFF, 0x35, 0x67, 0xC5, 0xA1, 0xBC, 0x5E, 0xAB, 0xCD, + 0x4A, 0xB8, 0x45, 0xEB, 0xC8, 0x68, 0x1E, 0x0D, 0x0D, 0x14, 0x46, 0x12, + 0xE3, 0xD2, 0x64, 0x62, 0x8A, 0x42, 0x98, 0xBC, 0xB4, 0xC6, 0x08, 0x08, + 0xF8, 0xFD, 0xA8, 0x4C, 0x64, 0x9C, 0x76, 0x01, 0xBD, 0x2F, 0xA9, 0x6C, + 0x33, 0x0F, 0xD8, 0x3F, 0x28, 0xB8, 0x3C, 0x69, 0x01, 0x42, 0x86, 0x7E, + 0x69, 0xC1, 0xC9, 0x06, 0xCA, 0xE5, 0x7A, 0x46, 0x65, 0xE9, 0xC2, 0xD6, + 0x50, 0x41, 0x2E, 0x3F, 0xB7, 0xE4, 0xED, 0x6C, 0xD7, 0xBF, 0x26, 0x01, + 0x11, 0xA2, 0x16, 0x29, 0x4A, 0x6B, 0x34, 0x06, 0x90, 0xEC, 0x13, 0xD2, + 0xB6, 0xFB, 0x6A, 0x76, 0xD2, 0x3C, 0xED, 0xF0, 0xD6, 0x2D, 0xDD, 0xE1, + 0x15, 0xEC, 0xA3, 0x9B, 0x2F, 0x2C, 0xC9, 0x3E, 0x2B, 0xE4, 0x69, 0x3B, + 0xFF, 0x72, 0x25, 0xB1, 0x36, 0x86, 0x5B, 0xC7, 0x7F, 0x6B, 0x8B, 0x55, + 0x1B, 0x4A, 0xC5, 0x20, 0x61, 0x3D, 0xAE, 0xCB, 0x50, 0xE1, 0x08, 0x3A, + 0xBE, 0xB0, 0x8F, 0x63, 0x41, 0x53, 0x30, 0x08, 0x59, 0x3C, 0x98, 0x1D, + 0x77, 0xBA, 0x63, 0x91, 0x7A, 0xCA, 0x10, 0x50, 0x60, 0xBF, 0xF0, 0xD7, + 0xBC, 0x95, 0x87, 0x8F, 0x97, 0xC5, 0xFE, 0x97, 0x6A, 0x01, 0x94, 0xA3, + 0x7C, 0x5B, 0x85, 0x1D, 0x2A, 0x39, 0x3A, 0xD0, 0x54, 0xA1, 0xD1, 0x39, + 0x71, 0x9D, 0xFD, 0x21, 0xF9, 0xB5, 0x7B, 0xF0, 0xE2, 0xE0, 0x02, 0x8F, + 0x6E, 0x96, 0x24, 0x25, 0x2C, 0xA0, 0x1E, 0x2C, 0xA8, 0xC4, 0x89, 0xA7, + 0xEF, 0xED, 0x99, 0x06, 0x2F, 0xB6, 0x0A, 0x4C, 0x4F, 0xDB, 0xA2, 0xCC, + 0x37, 0x1A, 0xAF, 0x47, 0x85, 0x2D, 0x8A, 0x5F, 0xC4, 0x34, 0x34, 0x4C, + 0x00, 0xFD, 0x18, 0x93, 0x67, 0x13, 0xD1, 0x37, 0xE6, 0x48, 0xB4, 0x8B, + 0x06, 0xC5, 0x57, 0x7B, 0x19, 0x86, 0x0A, 0x79, 0xCB, 0x00, 0xC9, 0x52, + 0xAF, 0x42, 0xFF, 0x37, 0x8F, 0xE1, 0xA3, 0x1E, 0x7A, 0x3D, 0x50, 0xAB, + 0x63, 0x06, 0xE7, 0x15, 0xB5, 0x3F, 0xB6, 0x45, 0x37, 0x94, 0x37, 0xB1, + 0x7E, 0xF2, 0x48, 0xC3, 0x7F, 0xC5, 0x75, 0xFE, 0x97, 0x8D, 0x45, 0x8F, + 0x1A, 0xA7, 0x1A, 0x72, 0x28, 0x1A, 0x40, 0x0F +}; + +static const unsigned char TA105_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA106_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA106_RSA_N[] = { + 0xAD, 0x0E, 0x15, 0xCE, 0xE4, 0x43, 0x80, 0x5C, 0xB1, 0x87, 0xF3, 0xB7, + 0x60, 0xF9, 0x71, 0x12, 0xA5, 0xAE, 0xDC, 0x26, 0x94, 0x88, 0xAA, 0xF4, + 0xCE, 0xF5, 0x20, 0x39, 0x28, 0x58, 0x60, 0x0C, 0xF8, 0x80, 0xDA, 0xA9, + 0x15, 0x95, 0x32, 0x61, 0x3C, 0xB5, 0xB1, 0x28, 0x84, 0x8A, 0x8A, 0xDC, + 0x9F, 0x0A, 0x0C, 0x83, 0x17, 0x7A, 0x8F, 0x90, 0xAC, 0x8A, 0xE7, 0x79, + 0x53, 0x5C, 0x31, 0x84, 0x2A, 0xF6, 0x0F, 0x98, 0x32, 0x36, 0x76, 0xCC, + 0xDE, 0xDD, 0x3C, 0xA8, 0xA2, 0xEF, 0x6A, 0xFB, 0x21, 0xF2, 0x52, 0x61, + 0xDF, 0x9F, 0x20, 0xD7, 0x1F, 0xE2, 0xB1, 0xD9, 0xFE, 0x18, 0x64, 0xD2, + 0x12, 0x5B, 0x5F, 0xF9, 0x58, 0x18, 0x35, 0xBC, 0x47, 0xCD, 0xA1, 0x36, + 0xF9, 0x6B, 0x7F, 0xD4, 0xB0, 0x38, 0x3E, 0xC1, 0x1B, 0xC3, 0x8C, 0x33, + 0xD9, 0xD8, 0x2F, 0x18, 0xFE, 0x28, 0x0F, 0xB3, 0xA7, 0x83, 0xD6, 0xC3, + 0x6E, 0x44, 0xC0, 0x61, 0x35, 0x96, 0x16, 0xFE, 0x59, 0x9C, 0x8B, 0x76, + 0x6D, 0xD7, 0xF1, 0xA2, 0x4B, 0x0D, 0x2B, 0xFF, 0x0B, 0x72, 0xDA, 0x9E, + 0x60, 0xD0, 0x8E, 0x90, 0x35, 0xC6, 0x78, 0x55, 0x87, 0x20, 0xA1, 0xCF, + 0xE5, 0x6D, 0x0A, 0xC8, 0x49, 0x7C, 0x31, 0x98, 0x33, 0x6C, 0x22, 0xE9, + 0x87, 0xD0, 0x32, 0x5A, 0xA2, 0xBA, 0x13, 0x82, 0x11, 0xED, 0x39, 0x17, + 0x9D, 0x99, 0x3A, 0x72, 0xA1, 0xE6, 0xFA, 0xA4, 0xD9, 0xD5, 0x17, 0x31, + 0x75, 0xAE, 0x85, 0x7D, 0x22, 0xAE, 0x3F, 0x01, 0x46, 0x86, 0xF6, 0x28, + 0x79, 0xC8, 0xB1, 0xDA, 0xE4, 0x57, 0x17, 0xC4, 0x7E, 0x1C, 0x0E, 0xB0, + 0xB4, 0x92, 0xA6, 0x56, 0xB3, 0xBD, 0xB2, 0x97, 0xED, 0xAA, 0xA7, 0xF0, + 0xB7, 0xC5, 0xA8, 0x3F, 0x95, 0x16, 0xD0, 0xFF, 0xA1, 0x96, 0xEB, 0x08, + 0x5F, 0x18, 0x77, 0x4F +}; + +static const unsigned char TA106_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA107_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x35 +}; + +static const unsigned char TA107_EC_Q[] = { + 0x04, 0x0B, 0x50, 0x74, 0x8D, 0x64, 0x32, 0x99, 0x99, 0xB3, 0xD2, 0x60, + 0x08, 0xB8, 0x22, 0x8E, 0x46, 0x74, 0x2C, 0x78, 0xC0, 0x2B, 0x44, 0x2D, + 0x6D, 0x5F, 0x1D, 0xC9, 0xAE, 0x4B, 0x52, 0x20, 0x83, 0x3D, 0xB8, 0x14, + 0x6D, 0x53, 0x87, 0x60, 0x9E, 0x5F, 0x6C, 0x85, 0xDB, 0x06, 0x14, 0x95, + 0xE0, 0xC7, 0x28, 0xFF, 0x9D, 0x5F, 0xE4, 0xAA, 0xF1, 0xB3, 0x8B, 0x6D, + 0xED, 0x4F, 0x2F, 0x4B, 0xC9, 0x4A, 0x94, 0x91, 0x64, 0x75, 0xFE, 0x01, + 0xEC, 0xC1, 0xD8, 0xEB, 0x7A, 0x94, 0x78, 0x56, 0x18, 0x43, 0x5F, 0x6B, + 0x81, 0xCB, 0xF6, 0xBC, 0xDA, 0xB4, 0x0C, 0xB6, 0x29, 0x93, 0x08, 0x69, + 0x8F +}; + +static const unsigned char TA108_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x33 +}; + +static const unsigned char TA108_EC_Q[] = { + 0x04, 0x1F, 0x4F, 0x33, 0x87, 0x33, 0x29, 0x8A, 0xA1, 0x84, 0xDE, 0xCB, + 0xC7, 0x21, 0x58, 0x41, 0x89, 0xEA, 0x56, 0x9D, 0x2B, 0x4B, 0x85, 0xC6, + 0x1D, 0x4C, 0x27, 0xBC, 0x7F, 0x26, 0x51, 0x72, 0x6F, 0xE2, 0x9F, 0xD6, + 0xA3, 0xCA, 0xCC, 0x45, 0x14, 0x46, 0x8B, 0xAD, 0xEF, 0x7E, 0x86, 0x8C, + 0xEC, 0xB1, 0x7E, 0x2F, 0xFF, 0xA9, 0x71, 0x9D, 0x18, 0x84, 0x45, 0x04, + 0x41, 0x55, 0x6E, 0x2B, 0xEA, 0x26, 0x7F, 0xBB, 0x90, 0x01, 0xE3, 0x4B, + 0x19, 0xBA, 0xE4, 0x54, 0x96, 0x45, 0x09, 0xB1, 0xD5, 0x6C, 0x91, 0x44, + 0xAD, 0x84, 0x13, 0x8E, 0x9A, 0x8C, 0x0D, 0x80, 0x0C, 0x32, 0xF6, 0xE0, + 0x27 +}; + +static const unsigned char TA109_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA109_EC_Q[] = { + 0x04, 0xCE, 0xBF, 0xFE, 0x57, 0xA8, 0xBF, 0xD5, 0xAA, 0xF7, 0x10, 0x9A, + 0xCD, 0xBC, 0xD1, 0x11, 0xA2, 0xBD, 0x67, 0x42, 0xCC, 0x90, 0xEB, 0x15, + 0x18, 0x90, 0xD9, 0xA2, 0xCD, 0x0C, 0x2A, 0x25, 0xEB, 0x3E, 0x4F, 0xCE, + 0xB5, 0xD2, 0x8F, 0x0F, 0xF3, 0x35, 0xDA, 0x43, 0x8B, 0x02, 0x80, 0xBE, + 0x6F, 0x51, 0x24, 0x1D, 0x0F, 0x6B, 0x2B, 0xCA, 0x9F, 0xC2, 0x6F, 0x50, + 0x32, 0xE5, 0x37, 0x20, 0xB6, 0x20, 0xFF, 0x88, 0x0D, 0x0F, 0x6D, 0x49, + 0xBB, 0xDB, 0x06, 0xA4, 0x87, 0x90, 0x92, 0x94, 0xF4, 0x09, 0xD0, 0xCF, + 0x7F, 0xC8, 0x80, 0x0B, 0xC1, 0x97, 0xB3, 0xBB, 0x35, 0x27, 0xC9, 0xC2, + 0x1B +}; + +static const unsigned char TA110_DN[] = { + 0x30, 0x81, 0xB0, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x30, 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x20, 0x69, + 0x73, 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6E, 0x63, 0x65, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x16, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, + 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA110_RSA_N[] = { + 0xB6, 0x95, 0xB6, 0x43, 0x42, 0xFA, 0xC6, 0x6D, 0x2A, 0x6F, 0x48, 0xDF, + 0x94, 0x4C, 0x39, 0x57, 0x05, 0xEE, 0xC3, 0x79, 0x11, 0x41, 0x68, 0x36, + 0xED, 0xEC, 0xFE, 0x9A, 0x01, 0x8F, 0xA1, 0x38, 0x28, 0xFC, 0xF7, 0x10, + 0x46, 0x66, 0x2E, 0x4D, 0x1E, 0x1A, 0xB1, 0x1A, 0x4E, 0xC6, 0xD1, 0xC0, + 0x95, 0x88, 0xB0, 0xC9, 0xFF, 0x31, 0x8B, 0x33, 0x03, 0xDB, 0xB7, 0x83, + 0x7B, 0x3E, 0x20, 0x84, 0x5E, 0xED, 0xB2, 0x56, 0x28, 0xA7, 0xF8, 0xE0, + 0xB9, 0x40, 0x71, 0x37, 0xC5, 0xCB, 0x47, 0x0E, 0x97, 0x2A, 0x68, 0xC0, + 0x22, 0x95, 0x62, 0x15, 0xDB, 0x47, 0xD9, 0xF5, 0xD0, 0x2B, 0xFF, 0x82, + 0x4B, 0xC9, 0xAD, 0x3E, 0xDE, 0x4C, 0xDB, 0x90, 0x80, 0x50, 0x3F, 0x09, + 0x8A, 0x84, 0x00, 0xEC, 0x30, 0x0A, 0x3D, 0x18, 0xCD, 0xFB, 0xFD, 0x2A, + 0x59, 0x9A, 0x23, 0x95, 0x17, 0x2C, 0x45, 0x9E, 0x1F, 0x6E, 0x43, 0x79, + 0x6D, 0x0C, 0x5C, 0x98, 0xFE, 0x48, 0xA7, 0xC5, 0x23, 0x47, 0x5C, 0x5E, + 0xFD, 0x6E, 0xE7, 0x1E, 0xB4, 0xF6, 0x68, 0x45, 0xD1, 0x86, 0x83, 0x5B, + 0xA2, 0x8A, 0x8D, 0xB1, 0xE3, 0x29, 0x80, 0xFE, 0x25, 0x71, 0x88, 0xAD, + 0xBE, 0xBC, 0x8F, 0xAC, 0x52, 0x96, 0x4B, 0xAA, 0x51, 0x8D, 0xE4, 0x13, + 0x31, 0x19, 0xE8, 0x4E, 0x4D, 0x9F, 0xDB, 0xAC, 0xB3, 0x6A, 0xD5, 0xBC, + 0x39, 0x54, 0x71, 0xCA, 0x7A, 0x7A, 0x7F, 0x90, 0xDD, 0x7D, 0x1D, 0x80, + 0xD9, 0x81, 0xBB, 0x59, 0x26, 0xC2, 0x11, 0xFE, 0xE6, 0x93, 0xE2, 0xF7, + 0x80, 0xE4, 0x65, 0xFB, 0x34, 0x37, 0x0E, 0x29, 0x80, 0x70, 0x4D, 0xAF, + 0x38, 0x86, 0x2E, 0x9E, 0x7F, 0x57, 0xAF, 0x9E, 0x17, 0xAE, 0xEB, 0x1C, + 0xCB, 0x28, 0x21, 0x5F, 0xB6, 0x1C, 0xD8, 0xE7, 0xA2, 0x04, 0x22, 0xF9, + 0xD3, 0xDA, 0xD8, 0xCB +}; + +static const unsigned char TA110_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA111_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA111_RSA_N[] = { + 0xD8, 0x8E, 0xA3, 0x89, 0x80, 0x0B, 0xB2, 0x57, 0x52, 0xDC, 0xA9, 0x53, + 0x4C, 0x37, 0xB9, 0x7F, 0x63, 0x17, 0x13, 0xEF, 0xA7, 0x5B, 0x23, 0x5B, + 0x69, 0x75, 0xB0, 0x99, 0x0A, 0x17, 0xC1, 0x8B, 0xC4, 0xDB, 0xA8, 0xE0, + 0xCC, 0x31, 0xBA, 0xC2, 0xF2, 0xCD, 0x5D, 0xE9, 0xB7, 0xF8, 0x1D, 0xAF, + 0x6A, 0xC4, 0x95, 0x87, 0xD7, 0x47, 0xC9, 0x95, 0xD8, 0x82, 0x04, 0x50, + 0x3D, 0x81, 0x08, 0xFF, 0xE4, 0x3D, 0xB3, 0xB1, 0xD6, 0xC5, 0xB2, 0xFD, + 0x88, 0x09, 0xDB, 0x9C, 0x84, 0xEC, 0x25, 0x17, 0x14, 0x87, 0x7F, 0x30, + 0x78, 0x9B, 0x6A, 0x58, 0xC9, 0xB6, 0x73, 0x28, 0x3C, 0x34, 0xF7, 0x99, + 0xF7, 0x7F, 0xD3, 0xA6, 0xF8, 0x1C, 0x45, 0x7C, 0xAD, 0x2C, 0x8C, 0x94, + 0x3F, 0xD8, 0x67, 0x10, 0x53, 0x7E, 0x22, 0xCD, 0x4E, 0x25, 0x51, 0xF0, + 0x25, 0x24, 0x35, 0x11, 0x5E, 0x10, 0xC6, 0xEC, 0x87, 0x66, 0x89, 0x81, + 0x68, 0xBA, 0xCC, 0x2B, 0x9D, 0x47, 0x73, 0x1F, 0xBD, 0xCD, 0x91, 0xA4, + 0x72, 0x6A, 0x9C, 0xA2, 0x1B, 0x18, 0xA0, 0x6F, 0xEC, 0x50, 0xF4, 0x7D, + 0x40, 0xC2, 0xA8, 0x30, 0xCF, 0xBD, 0x73, 0xC8, 0x13, 0x2B, 0x10, 0x13, + 0x1E, 0x8B, 0x9A, 0xA8, 0x3A, 0x94, 0x73, 0xD3, 0x18, 0x69, 0x0A, 0x4A, + 0xFF, 0xC1, 0x01, 0x03, 0xFF, 0x79, 0x7F, 0xB5, 0x48, 0x7F, 0x7B, 0xEE, + 0xE8, 0x29, 0x6F, 0x36, 0x4C, 0x95, 0x61, 0x86, 0xD8, 0xF9, 0xA2, 0x73, + 0x8A, 0xEE, 0xAE, 0x2F, 0x96, 0xEE, 0x68, 0xCD, 0x3D, 0x4D, 0x28, 0x42, + 0xF9, 0x45, 0x2B, 0x32, 0x1B, 0x46, 0x55, 0x16, 0x6A, 0xA6, 0x4B, 0x29, + 0xF9, 0xBB, 0x95, 0x56, 0xBF, 0x46, 0x1D, 0xEC, 0x1D, 0x93, 0x1D, 0xC0, + 0x65, 0xB2, 0x1F, 0xA1, 0x43, 0xAE, 0x56, 0x9E, 0xA0, 0xB1, 0x8F, 0x6B, + 0x12, 0xB7, 0x60, 0x6D, 0x78, 0x0B, 0xCA, 0x8A, 0x5C, 0xED, 0x1E, 0x96, + 0x0E, 0x83, 0xA6, 0x48, 0x95, 0x8D, 0x3B, 0xA3, 0x21, 0xC4, 0xAE, 0x58, + 0xC6, 0x00, 0xB2, 0x84, 0xB4, 0x23, 0xA4, 0x96, 0x86, 0x35, 0xB8, 0xD8, + 0x9E, 0xD8, 0xAC, 0x34, 0x49, 0x98, 0x63, 0x95, 0xC5, 0xCB, 0x6D, 0x48, + 0x47, 0xE2, 0xF2, 0x2E, 0x18, 0x1E, 0xD0, 0x31, 0xAB, 0xDD, 0x74, 0xEC, + 0xF9, 0xDC, 0x8C, 0xB8, 0x1C, 0x8E, 0x68, 0x23, 0xBA, 0xD0, 0xF3, 0x50, + 0xDC, 0xCF, 0x65, 0x8F, 0x73, 0x3A, 0x32, 0xC7, 0x7C, 0xFE, 0xCA, 0x82, + 0x22, 0x4F, 0xBE, 0x8E, 0x62, 0x47, 0x66, 0xE5, 0xCD, 0x87, 0xE2, 0xE8, + 0xD5, 0x0F, 0x18, 0x9F, 0xE5, 0x04, 0x72, 0x4B, 0x46, 0x3C, 0x10, 0xF2, + 0x44, 0xC2, 0x64, 0x56, 0x71, 0x4E, 0x75, 0xE8, 0x9C, 0xC9, 0x26, 0x74, + 0xC5, 0x7D, 0x59, 0xD1, 0x0A, 0x5B, 0x0F, 0x6D, 0xFE, 0x9E, 0x75, 0x1C, + 0x18, 0xC6, 0x1A, 0x3A, 0x7C, 0xD8, 0x0D, 0x04, 0xCC, 0xCD, 0xB7, 0x45, + 0x65, 0x7A, 0xB1, 0x8F, 0xB8, 0xAE, 0x84, 0x48, 0x3E, 0xB3, 0x7A, 0x4D, + 0xA8, 0x03, 0xE2, 0xE2, 0x7E, 0x01, 0x16, 0x59, 0x68, 0x18, 0x43, 0x33, + 0xB0, 0xD2, 0xDC, 0xB0, 0x1A, 0x43, 0x35, 0xEE, 0xA5, 0xDA, 0xA9, 0x46, + 0x5C, 0xAE, 0x86, 0x81, 0x41, 0x01, 0x4A, 0x74, 0x26, 0xEC, 0x9F, 0x06, + 0xBF, 0xC2, 0x05, 0x37, 0x64, 0x75, 0x78, 0x29, 0x68, 0xFD, 0xC5, 0xF5, + 0xEB, 0xFE, 0x47, 0xF9, 0xE4, 0x85, 0xB0, 0xE1, 0x7B, 0x31, 0x9D, 0xA6, + 0x7F, 0x72, 0xA3, 0xB9, 0xC4, 0x2C, 0x2E, 0xCC, 0x99, 0x57, 0x0E, 0x21, + 0x0C, 0x45, 0x01, 0x94, 0x65, 0xEB, 0x65, 0x09, 0xC6, 0x63, 0x22, 0x0B, + 0x33, 0x49, 0x92, 0x48, 0x3C, 0xFC, 0xCD, 0xCE, 0xB0, 0x3E, 0x8E, 0x9E, + 0x8B, 0xF8, 0xFE, 0x49, 0xC5, 0x35, 0x72, 0x47 +}; + +static const unsigned char TA111_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA112_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA112_RSA_N[] = { + 0xAD, 0x96, 0x9F, 0x2D, 0x9C, 0x4A, 0x4C, 0x4A, 0x81, 0x79, 0x51, 0x99, + 0xEC, 0x8A, 0xCB, 0x6B, 0x60, 0x51, 0x13, 0xBC, 0x4D, 0x6D, 0x06, 0xFC, + 0xB0, 0x08, 0x8D, 0xDD, 0x19, 0x10, 0x6A, 0xC7, 0x26, 0x0C, 0x35, 0xD8, + 0xC0, 0x6F, 0x20, 0x84, 0xE9, 0x94, 0xB1, 0x9B, 0x85, 0x03, 0xC3, 0x5B, + 0xDB, 0x4A, 0xE8, 0xC8, 0xF8, 0x90, 0x76, 0xD9, 0x5B, 0x4F, 0xE3, 0x4C, + 0xE8, 0x06, 0x36, 0x4D, 0xCC, 0x9A, 0xAC, 0x3D, 0x0C, 0x90, 0x2B, 0x92, + 0xD4, 0x06, 0x19, 0x60, 0xAC, 0x37, 0x44, 0x79, 0x85, 0x81, 0x82, 0xAD, + 0x5A, 0x37, 0xE0, 0x0D, 0xCC, 0x9D, 0xA6, 0x4C, 0x52, 0x76, 0xEA, 0x43, + 0x9D, 0xB7, 0x04, 0xD1, 0x50, 0xF6, 0x55, 0xE0, 0xD5, 0xD2, 0xA6, 0x49, + 0x85, 0xE9, 0x37, 0xE9, 0xCA, 0x7E, 0xAE, 0x5C, 0x95, 0x4D, 0x48, 0x9A, + 0x3F, 0xAE, 0x20, 0x5A, 0x6D, 0x88, 0x95, 0xD9, 0x34, 0xB8, 0x52, 0x1A, + 0x43, 0x90, 0xB0, 0xBF, 0x6C, 0x05, 0xB9, 0xB6, 0x78, 0xB7, 0xEA, 0xD0, + 0xE4, 0x3A, 0x3C, 0x12, 0x53, 0x62, 0xFF, 0x4A, 0xF2, 0x7B, 0xBE, 0x35, + 0x05, 0xA9, 0x12, 0x34, 0xE3, 0xF3, 0x64, 0x74, 0x62, 0x2C, 0x3D, 0x00, + 0x49, 0x5A, 0x28, 0xFE, 0x32, 0x44, 0xBB, 0x87, 0xDD, 0x65, 0x27, 0x02, + 0x71, 0x3B, 0xDA, 0x4A, 0xF7, 0x1F, 0xDA, 0xCD, 0xF7, 0x21, 0x55, 0x90, + 0x4F, 0x0F, 0xEC, 0xAE, 0x82, 0xE1, 0x9F, 0x6B, 0xD9, 0x45, 0xD3, 0xBB, + 0xF0, 0x5F, 0x87, 0xED, 0x3C, 0x2C, 0x39, 0x86, 0xDA, 0x3F, 0xDE, 0xEC, + 0x72, 0x55, 0xEB, 0x79, 0xA3, 0xAD, 0xDB, 0xDD, 0x7C, 0xB0, 0xBA, 0x1C, + 0xCE, 0xFC, 0xDE, 0x4F, 0x35, 0x76, 0xCF, 0x0F, 0xF8, 0x78, 0x1F, 0x6A, + 0x36, 0x51, 0x46, 0x27, 0x61, 0x5B, 0xE9, 0x9E, 0xCF, 0xF0, 0xA2, 0x55, + 0x7D, 0x7C, 0x25, 0x8A, 0x6F, 0x2F, 0xB4, 0xC5, 0xCF, 0x84, 0x2E, 0x2B, + 0xFD, 0x0D, 0x51, 0x10, 0x6C, 0xFB, 0x5F, 0x1B, 0xBC, 0x1B, 0x7E, 0xC5, + 0xAE, 0x3B, 0x98, 0x01, 0x31, 0x92, 0xFF, 0x0B, 0x57, 0xF4, 0x9A, 0xB2, + 0xB9, 0x57, 0xE9, 0xAB, 0xEF, 0x0D, 0x76, 0xD1, 0xF0, 0xEE, 0xF4, 0xCE, + 0x86, 0xA7, 0xE0, 0x6E, 0xE9, 0xB4, 0x69, 0xA1, 0xDF, 0x69, 0xF6, 0x33, + 0xC6, 0x69, 0x2E, 0x97, 0x13, 0x9E, 0xA5, 0x87, 0xB0, 0x57, 0x10, 0x81, + 0x37, 0xC9, 0x53, 0xB3, 0xBB, 0x7F, 0xF6, 0x92, 0xD1, 0x9C, 0xD0, 0x18, + 0xF4, 0x92, 0x6E, 0xDA, 0x83, 0x4F, 0xA6, 0x63, 0x99, 0x4C, 0xA5, 0xFB, + 0x5E, 0xEF, 0x21, 0x64, 0x7A, 0x20, 0x5F, 0x6C, 0x64, 0x85, 0x15, 0xCB, + 0x37, 0xE9, 0x62, 0x0C, 0x0B, 0x2A, 0x16, 0xDC, 0x01, 0x2E, 0x32, 0xDA, + 0x3E, 0x4B, 0xF5, 0x9E, 0x3A, 0xF6, 0x17, 0x40, 0x94, 0xEF, 0x9E, 0x91, + 0x08, 0x86, 0xFA, 0xBE, 0x63, 0xA8, 0x5A, 0x33, 0xEC, 0xCB, 0x74, 0x43, + 0x95, 0xF9, 0x6C, 0x69, 0x52, 0x36, 0xC7, 0x29, 0x6F, 0xFC, 0x55, 0x03, + 0x5C, 0x1F, 0xFB, 0x9F, 0xBD, 0x47, 0xEB, 0xE7, 0x49, 0x47, 0x95, 0x0B, + 0x4E, 0x89, 0x22, 0x09, 0x49, 0xE0, 0xF5, 0x61, 0x1E, 0xF1, 0xBF, 0x2E, + 0x8A, 0x72, 0x6E, 0x80, 0x59, 0xFF, 0x57, 0x3A, 0xF9, 0x75, 0x32, 0xA3, + 0x4E, 0x5F, 0xEC, 0xED, 0x28, 0x62, 0xD9, 0x4D, 0x73, 0xF2, 0xCC, 0x81, + 0x17, 0x60, 0xED, 0xCD, 0xEB, 0xDC, 0xDB, 0xA7, 0xCA, 0xC5, 0x7E, 0x02, + 0xBD, 0xF2, 0x54, 0x08, 0x54, 0xFD, 0xB4, 0x2D, 0x09, 0x2C, 0x17, 0x54, + 0x4A, 0x98, 0xD1, 0x54, 0xE1, 0x51, 0x67, 0x08, 0xD2, 0xED, 0x6E, 0x7E, + 0x6F, 0x3F, 0xD2, 0x2D, 0x81, 0x59, 0x29, 0x66, 0xCB, 0x90, 0x39, 0x95, + 0x11, 0x1E, 0x74, 0x27, 0xFE, 0xDD, 0xEB, 0xAF +}; + +static const unsigned char TA112_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA113_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x52, 0x53, 0x41 +}; + +static const unsigned char TA113_RSA_N[] = { + 0xF9, 0x0F, 0xDD, 0xA3, 0x2B, 0x7D, 0xCB, 0xD0, 0x2A, 0xFE, 0xEC, 0x67, + 0x85, 0xA6, 0xE7, 0x2E, 0x1B, 0xBA, 0x77, 0xE1, 0xE3, 0xF5, 0xAF, 0xA4, + 0xEC, 0xFA, 0x4A, 0x5D, 0x91, 0xC4, 0x57, 0x47, 0x6B, 0x18, 0x77, 0x6B, + 0x76, 0xF2, 0xFD, 0x93, 0xE4, 0x3D, 0x0F, 0xC2, 0x16, 0x9E, 0x0B, 0x66, + 0xC3, 0x56, 0x94, 0x9E, 0x17, 0x83, 0x85, 0xCE, 0x56, 0xEF, 0xF2, 0x16, + 0xFD, 0x00, 0x62, 0xF5, 0x22, 0x09, 0x54, 0xE8, 0x65, 0x17, 0x4E, 0x41, + 0xB9, 0xE0, 0x4F, 0x46, 0x97, 0xAA, 0x1B, 0xC8, 0xB8, 0x6E, 0x62, 0x5E, + 0x69, 0xB1, 0x5F, 0xDB, 0x2A, 0x02, 0x7E, 0xFC, 0x6C, 0xCA, 0xF3, 0x41, + 0xD8, 0xED, 0xD0, 0xE8, 0xFC, 0x3F, 0x61, 0x48, 0xED, 0xB0, 0x03, 0x14, + 0x1D, 0x10, 0x0E, 0x4B, 0x19, 0xE0, 0xBB, 0x4E, 0xEC, 0x86, 0x65, 0xFF, + 0x36, 0xF3, 0x5E, 0x67, 0x02, 0x0B, 0x9D, 0x86, 0x55, 0x61, 0xFD, 0x7A, + 0x38, 0xED, 0xFE, 0xE2, 0x19, 0x00, 0xB7, 0x6F, 0xA1, 0x50, 0x62, 0x75, + 0x74, 0x3C, 0xA0, 0xFA, 0xC8, 0x25, 0x92, 0xB4, 0x6E, 0x7A, 0x22, 0xC7, + 0xF8, 0x1E, 0xA1, 0xE3, 0xB2, 0xDD, 0x91, 0x31, 0xAB, 0x2B, 0x1D, 0x04, + 0xFF, 0xA5, 0x4A, 0x04, 0x37, 0xE9, 0x85, 0xA4, 0x33, 0x2B, 0xFD, 0xE2, + 0xD6, 0x55, 0x34, 0x7C, 0x19, 0xA4, 0x4A, 0x68, 0xC7, 0xB2, 0xA8, 0xD3, + 0xB7, 0xCA, 0xA1, 0x93, 0x88, 0xEB, 0xC1, 0x97, 0xBC, 0x8C, 0xF9, 0x1D, + 0xD9, 0x22, 0x84, 0x24, 0x74, 0xC7, 0x04, 0x3D, 0x6A, 0xA9, 0x29, 0x93, + 0xCC, 0xEB, 0xB8, 0x5B, 0xE1, 0xFE, 0x5F, 0x25, 0xAA, 0x34, 0x58, 0xC8, + 0xC1, 0x23, 0x54, 0x9D, 0x1B, 0x98, 0x11, 0xC3, 0x38, 0x9C, 0x7E, 0x3D, + 0x86, 0x6C, 0xA5, 0x0F, 0x40, 0x86, 0x7C, 0x02, 0xF4, 0x5C, 0x02, 0x4F, + 0x28, 0xCB, 0xAE, 0x71, 0x9F, 0x0F, 0x3A, 0xC8, 0x33, 0xFE, 0x11, 0x25, + 0x35, 0xEA, 0xFC, 0xBA, 0xC5, 0x60, 0x3D, 0xD9, 0x7C, 0x18, 0xD5, 0xB2, + 0xA9, 0xD3, 0x75, 0x78, 0x03, 0x72, 0x22, 0xCA, 0x3A, 0xC3, 0x1F, 0xEF, + 0x2C, 0xE5, 0x2E, 0xA9, 0xFA, 0x9E, 0x2C, 0xB6, 0x51, 0x46, 0xFD, 0xAF, + 0x03, 0xD6, 0xEA, 0x60, 0x68, 0xEA, 0x85, 0x16, 0x36, 0x6B, 0x85, 0xE9, + 0x1E, 0xC0, 0xB3, 0xDD, 0xC4, 0x24, 0xDC, 0x80, 0x2A, 0x81, 0x41, 0x6D, + 0x94, 0x3E, 0xC8, 0xE0, 0xC9, 0x81, 0x41, 0x00, 0x9E, 0x5E, 0xBF, 0x7F, + 0xC5, 0x08, 0x98, 0xA2, 0x18, 0x2C, 0x42, 0x40, 0xB3, 0xF9, 0x6F, 0x38, + 0x27, 0x4B, 0x4E, 0x80, 0xF4, 0x3D, 0x81, 0x47, 0xE0, 0x88, 0x7C, 0xEA, + 0x1C, 0xCE, 0xB5, 0x75, 0x5C, 0x51, 0x2E, 0x1C, 0x2B, 0x7F, 0x1A, 0x72, + 0x28, 0xE7, 0x00, 0xB5, 0xD1, 0x74, 0xC6, 0xD7, 0xE4, 0x9F, 0xAD, 0x07, + 0x93, 0xB6, 0x53, 0x35, 0x35, 0xFC, 0x37, 0xE4, 0xC3, 0xF6, 0x5D, 0x16, + 0xBE, 0x21, 0x73, 0xDE, 0x92, 0x0A, 0xF8, 0xA0, 0x63, 0x6A, 0xBC, 0x96, + 0x92, 0x6A, 0x3E, 0xF8, 0xBC, 0x65, 0x55, 0x9B, 0xDE, 0xF5, 0x0D, 0x89, + 0x26, 0x04, 0xFC, 0x25, 0x1A, 0xA6, 0x25, 0x69, 0xCB, 0xC2, 0x6D, 0xCA, + 0x7C, 0xE2, 0x59, 0x5F, 0x97, 0xAC, 0xEB, 0xEF, 0x2E, 0xC8, 0xBC, 0xD7, + 0x1B, 0x59, 0x3C, 0x2B, 0xCC, 0xF2, 0x19, 0xC8, 0x93, 0x6B, 0x27, 0x63, + 0x19, 0xCF, 0xFC, 0xE9, 0x26, 0xF8, 0xCA, 0x71, 0x9B, 0x7F, 0x93, 0xFE, + 0x34, 0x67, 0x84, 0x4E, 0x99, 0xEB, 0xFC, 0xB3, 0x78, 0x09, 0x33, 0x70, + 0xBA, 0x66, 0xA6, 0x76, 0xED, 0x1B, 0x73, 0xEB, 0x1A, 0xA5, 0x0D, 0xC4, + 0x22, 0x13, 0x20, 0x94, 0x56, 0x0A, 0x4E, 0x2C, 0x6C, 0x4E, 0xB1, 0xFD, + 0xCF, 0x9C, 0x09, 0xBA, 0xA2, 0x33, 0xED, 0x87 +}; + +static const unsigned char TA113_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA114_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x15, 0x77, 0x77, 0x77, 0x2E, 0x78, 0x72, 0x61, 0x6D, 0x70, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x58, + 0x52, 0x61, 0x6D, 0x70, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x24, 0x58, 0x52, 0x61, 0x6D, 0x70, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA114_RSA_N[] = { + 0x98, 0x24, 0x1E, 0xBD, 0x15, 0xB4, 0xBA, 0xDF, 0xC7, 0x8C, 0xA5, 0x27, + 0xB6, 0x38, 0x0B, 0x69, 0xF3, 0xB6, 0x4E, 0xA8, 0x2C, 0x2E, 0x21, 0x1D, + 0x5C, 0x44, 0xDF, 0x21, 0x5D, 0x7E, 0x23, 0x74, 0xFE, 0x5E, 0x7E, 0xB4, + 0x4A, 0xB7, 0xA6, 0xAD, 0x1F, 0xAE, 0xE0, 0x06, 0x16, 0xE2, 0x9B, 0x5B, + 0xD9, 0x67, 0x74, 0x6B, 0x5D, 0x80, 0x8F, 0x29, 0x9D, 0x86, 0x1B, 0xD9, + 0x9C, 0x0D, 0x98, 0x6D, 0x76, 0x10, 0x28, 0x58, 0xE4, 0x65, 0xB0, 0x7F, + 0x4A, 0x98, 0x79, 0x9F, 0xE0, 0xC3, 0x31, 0x7E, 0x80, 0x2B, 0xB5, 0x8C, + 0xC0, 0x40, 0x3B, 0x11, 0x86, 0xD0, 0xCB, 0xA2, 0x86, 0x36, 0x60, 0xA4, + 0xD5, 0x30, 0x82, 0x6D, 0xD9, 0x6E, 0xD0, 0x0F, 0x12, 0x04, 0x33, 0x97, + 0x5F, 0x4F, 0x61, 0x5A, 0xF0, 0xE4, 0xF9, 0x91, 0xAB, 0xE7, 0x1D, 0x3B, + 0xBC, 0xE8, 0xCF, 0xF4, 0x6B, 0x2D, 0x34, 0x7C, 0xE2, 0x48, 0x61, 0x1C, + 0x8E, 0xF3, 0x61, 0x44, 0xCC, 0x6F, 0xA0, 0x4A, 0xA9, 0x94, 0xB0, 0x4D, + 0xDA, 0xE7, 0xA9, 0x34, 0x7A, 0x72, 0x38, 0xA8, 0x41, 0xCC, 0x3C, 0x94, + 0x11, 0x7D, 0xEB, 0xC8, 0xA6, 0x8C, 0xB7, 0x86, 0xCB, 0xCA, 0x33, 0x3B, + 0xD9, 0x3D, 0x37, 0x8B, 0xFB, 0x7A, 0x3E, 0x86, 0x2C, 0xE7, 0x73, 0xD7, + 0x0A, 0x57, 0xAC, 0x64, 0x9B, 0x19, 0xEB, 0xF4, 0x0F, 0x04, 0x08, 0x8A, + 0xAC, 0x03, 0x17, 0x19, 0x64, 0xF4, 0x5A, 0x25, 0x22, 0x8D, 0x34, 0x2C, + 0xB2, 0xF6, 0x68, 0x1D, 0x12, 0x6D, 0xD3, 0x8A, 0x1E, 0x14, 0xDA, 0xC4, + 0x8F, 0xA6, 0xE2, 0x23, 0x85, 0xD5, 0x7A, 0x0D, 0xBD, 0x6A, 0xE0, 0xE9, + 0xEC, 0xEC, 0x17, 0xBB, 0x42, 0x1B, 0x67, 0xAA, 0x25, 0xED, 0x45, 0x83, + 0x21, 0xFC, 0xC1, 0xC9, 0x7C, 0xD5, 0x62, 0x3E, 0xFA, 0xF2, 0xC5, 0x2D, + 0xD3, 0xFD, 0xD4, 0x65 +}; + +static const unsigned char TA114_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA115_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA115_RSA_N[] = { + 0xA0, 0xBE, 0x50, 0x10, 0x8E, 0xE9, 0xF2, 0x6C, 0x40, 0xB4, 0x04, 0x9C, + 0x85, 0xB9, 0x31, 0xCA, 0xDC, 0x2D, 0xE4, 0x11, 0xA9, 0x04, 0x3C, 0x1B, + 0x55, 0xC1, 0xE7, 0x58, 0x30, 0x1D, 0x24, 0xB4, 0xC3, 0xEF, 0x85, 0xDE, + 0x8C, 0x2C, 0xE1, 0xC1, 0x3D, 0xDF, 0x82, 0xE6, 0x4F, 0xAD, 0x47, 0x87, + 0x6C, 0xEC, 0x5B, 0x49, 0xC1, 0x4A, 0xD5, 0xBB, 0x8F, 0xEC, 0x87, 0xAC, + 0x7F, 0x82, 0x9A, 0x86, 0xEC, 0x3D, 0x03, 0x99, 0x52, 0x01, 0xD2, 0x35, + 0x9E, 0xAC, 0xDA, 0xF0, 0x53, 0xC9, 0x66, 0x3C, 0xD4, 0xAC, 0x02, 0x01, + 0xDA, 0x24, 0xD3, 0x3B, 0xA8, 0x02, 0x46, 0xAF, 0xA4, 0x1C, 0xE3, 0xF8, + 0x73, 0x58, 0x76, 0xB7, 0xF6, 0x0E, 0x90, 0x0D, 0xB5, 0xF0, 0xCF, 0xCC, + 0xFA, 0xF9, 0xC6, 0x4C, 0xE5, 0xC3, 0x86, 0x30, 0x0A, 0x8D, 0x17, 0x7E, + 0x35, 0xEB, 0xC5, 0xDF, 0xBB, 0x0E, 0x9C, 0xC0, 0x8D, 0x87, 0xE3, 0x88, + 0x38, 0x85, 0x67, 0xFA, 0x3E, 0xC7, 0xAB, 0xE0, 0x13, 0x9C, 0x05, 0x18, + 0x98, 0xCF, 0x93, 0xF5, 0xB1, 0x92, 0xB4, 0xFC, 0x23, 0xD3, 0xCF, 0xD5, + 0xC4, 0x27, 0x49, 0xE0, 0x9E, 0x3C, 0x9B, 0x08, 0xA3, 0x8B, 0x5D, 0x2A, + 0x21, 0xE0, 0xFC, 0x39, 0xAA, 0x53, 0xDA, 0x7D, 0x7E, 0xCF, 0x1A, 0x09, + 0x53, 0xBC, 0x5D, 0x05, 0x04, 0xCF, 0xA1, 0x4A, 0x8F, 0x8B, 0x76, 0x82, + 0x0D, 0xA1, 0xF8, 0xD2, 0xC7, 0x14, 0x77, 0x5B, 0x90, 0x36, 0x07, 0x81, + 0x9B, 0x3E, 0x06, 0xFA, 0x52, 0x5E, 0x63, 0xC5, 0xA6, 0x00, 0xFE, 0xA5, + 0xE9, 0x52, 0x1B, 0x52, 0xB5, 0x92, 0x39, 0x72, 0x03, 0x09, 0x62, 0xBD, + 0xB0, 0x60, 0x16, 0x6E, 0xA6, 0xDD, 0x25, 0xC2, 0x03, 0x66, 0xDD, 0xF3, + 0x04, 0xD1, 0x40, 0xE2, 0x4E, 0x8B, 0x86, 0xF4, 0x6F, 0xE5, 0x83, 0xA0, + 0x27, 0x84, 0x5E, 0x04, 0xC1, 0xF5, 0x90, 0xBD, 0x30, 0x3D, 0xC4, 0xEF, + 0xA8, 0x69, 0xBC, 0x38, 0x9B, 0xA4, 0xA4, 0x96, 0xD1, 0x62, 0xDA, 0x69, + 0xC0, 0x01, 0x96, 0xAE, 0xCB, 0xC4, 0x51, 0x34, 0xEA, 0x0C, 0xAA, 0xFF, + 0x21, 0x8E, 0x59, 0x8F, 0x4A, 0x5C, 0xE4, 0x61, 0x9A, 0xA7, 0xD2, 0xE9, + 0x2A, 0x78, 0x8D, 0x51, 0x3D, 0x3A, 0x15, 0xEE, 0xA2, 0x59, 0x8E, 0xA9, + 0x5C, 0xDE, 0xC5, 0xF9, 0x90, 0x22, 0xE5, 0x88, 0x45, 0x71, 0xDD, 0x91, + 0x99, 0x6C, 0x7A, 0x9F, 0x3D, 0x3D, 0x98, 0x7C, 0x5E, 0xF6, 0xBE, 0x16, + 0x68, 0xA0, 0x5E, 0xAE, 0x0B, 0x23, 0xFC, 0x5A, 0x0F, 0xAA, 0x22, 0x76, + 0x2D, 0xC9, 0xA1, 0x10, 0x1D, 0xE4, 0xD3, 0x44, 0x23, 0x90, 0x88, 0x9F, + 0xC6, 0x2A, 0xE6, 0xD7, 0xF5, 0x9A, 0xB3, 0x58, 0x1E, 0x2F, 0x30, 0x89, + 0x08, 0x1B, 0x54, 0xA2, 0xB5, 0x98, 0x23, 0xEC, 0x08, 0x77, 0x1C, 0x95, + 0x5D, 0x61, 0xD1, 0xCB, 0x89, 0x9C, 0x5F, 0xA2, 0x4A, 0x91, 0x9A, 0xEF, + 0x21, 0xAA, 0x49, 0x16, 0x08, 0xA8, 0xBD, 0x61, 0x28, 0x31, 0xC9, 0x74, + 0xAD, 0x85, 0xF6, 0xD9, 0xC5, 0xB1, 0x8B, 0xD1, 0xE5, 0x10, 0x32, 0x4D, + 0x5F, 0x8B, 0x20, 0x3A, 0x3C, 0x49, 0x1F, 0x33, 0x85, 0x59, 0x0D, 0xDB, + 0xCB, 0x09, 0x75, 0x43, 0x69, 0x73, 0xFB, 0x6B, 0x71, 0x7D, 0xF0, 0xDF, + 0xC4, 0x4C, 0x7D, 0xC6, 0xA3, 0x2E, 0xC8, 0x95, 0x79, 0xCB, 0x73, 0xA2, + 0x8E, 0x4E, 0x4D, 0x24, 0xFB, 0x5E, 0xE4, 0x04, 0xBE, 0x72, 0x1B, 0xA6, + 0x27, 0x2D, 0x49, 0x5A, 0x99, 0x7A, 0xD7, 0x5C, 0x09, 0x20, 0xB7, 0x7F, + 0x94, 0xB9, 0x4F, 0xF1, 0x0D, 0x1C, 0x5E, 0x88, 0x42, 0x1B, 0x11, 0xB7, + 0xE7, 0x91, 0xDB, 0x9E, 0x6C, 0xF4, 0x6A, 0xDF, 0x8C, 0x06, 0x98, 0x03, + 0xAD, 0xCC, 0x28, 0xEF, 0xA5, 0x47, 0xF3, 0x53 +}; + +static const unsigned char TA115_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA116_DN[] = { + 0x30, 0x7B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, 0x61, + 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x53, 0x61, 0x6C, 0x66, 0x6F, + 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x11, 0x43, 0x6F, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x43, 0x41, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x18, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73 +}; + +static const unsigned char TA116_RSA_N[] = { + 0xBE, 0x40, 0x9D, 0xF4, 0x6E, 0xE1, 0xEA, 0x76, 0x87, 0x1C, 0x4D, 0x45, + 0x44, 0x8E, 0xBE, 0x46, 0xC8, 0x83, 0x06, 0x9D, 0xC1, 0x2A, 0xFE, 0x18, + 0x1F, 0x8E, 0xE4, 0x02, 0xFA, 0xF3, 0xAB, 0x5D, 0x50, 0x8A, 0x16, 0x31, + 0x0B, 0x9A, 0x06, 0xD0, 0xC5, 0x70, 0x22, 0xCD, 0x49, 0x2D, 0x54, 0x63, + 0xCC, 0xB6, 0x6E, 0x68, 0x46, 0x0B, 0x53, 0xEA, 0xCB, 0x4C, 0x24, 0xC0, + 0xBC, 0x72, 0x4E, 0xEA, 0xF1, 0x15, 0xAE, 0xF4, 0x54, 0x9A, 0x12, 0x0A, + 0xC3, 0x7A, 0xB2, 0x33, 0x60, 0xE2, 0xDA, 0x89, 0x55, 0xF3, 0x22, 0x58, + 0xF3, 0xDE, 0xDC, 0xCF, 0xEF, 0x83, 0x86, 0xA2, 0x8C, 0x94, 0x4F, 0x9F, + 0x68, 0xF2, 0x98, 0x90, 0x46, 0x84, 0x27, 0xC7, 0x76, 0xBF, 0xE3, 0xCC, + 0x35, 0x2C, 0x8B, 0x5E, 0x07, 0x64, 0x65, 0x82, 0xC0, 0x48, 0xB0, 0xA8, + 0x91, 0xF9, 0x61, 0x9F, 0x76, 0x20, 0x50, 0xA8, 0x91, 0xC7, 0x66, 0xB5, + 0xEB, 0x78, 0x62, 0x03, 0x56, 0xF0, 0x8A, 0x1A, 0x13, 0xEA, 0x31, 0xA3, + 0x1E, 0xA0, 0x99, 0xFD, 0x38, 0xF6, 0xF6, 0x27, 0x32, 0x58, 0x6F, 0x07, + 0xF5, 0x6B, 0xB8, 0xFB, 0x14, 0x2B, 0xAF, 0xB7, 0xAA, 0xCC, 0xD6, 0x63, + 0x5F, 0x73, 0x8C, 0xDA, 0x05, 0x99, 0xA8, 0x38, 0xA8, 0xCB, 0x17, 0x78, + 0x36, 0x51, 0xAC, 0xE9, 0x9E, 0xF4, 0x78, 0x3A, 0x8D, 0xCF, 0x0F, 0xD9, + 0x42, 0xE2, 0x98, 0x0C, 0xAB, 0x2F, 0x9F, 0x0E, 0x01, 0xDE, 0xEF, 0x9F, + 0x99, 0x49, 0xF1, 0x2D, 0xDF, 0xAC, 0x74, 0x4D, 0x1B, 0x98, 0xB5, 0x47, + 0xC5, 0xE5, 0x29, 0xD1, 0xF9, 0x90, 0x18, 0xC7, 0x62, 0x9C, 0xBE, 0x83, + 0xC7, 0x26, 0x7B, 0x3E, 0x8A, 0x25, 0xC7, 0xC0, 0xDD, 0x9D, 0xE6, 0x35, + 0x68, 0x10, 0x20, 0x9D, 0x8F, 0xD8, 0xDE, 0xD2, 0xC3, 0x84, 0x9C, 0x0D, + 0x5E, 0xE8, 0x2F, 0xC9 +}; + +static const unsigned char TA116_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA117_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x18, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA117_RSA_N[] = { + 0xBF, 0xE6, 0x90, 0x73, 0x68, 0xDE, 0xBB, 0xE4, 0x5D, 0x4A, 0x3C, 0x30, + 0x22, 0x30, 0x69, 0x33, 0xEC, 0xC2, 0xA7, 0x25, 0x2E, 0xC9, 0x21, 0x3D, + 0xF2, 0x8A, 0xD8, 0x59, 0xC2, 0xE1, 0x29, 0xA7, 0x3D, 0x58, 0xAB, 0x76, + 0x9A, 0xCD, 0xAE, 0x7B, 0x1B, 0x84, 0x0D, 0xC4, 0x30, 0x1F, 0xF3, 0x1B, + 0xA4, 0x38, 0x16, 0xEB, 0x56, 0xC6, 0x97, 0x6D, 0x1D, 0xAB, 0xB2, 0x79, + 0xF2, 0xCA, 0x11, 0xD2, 0xE4, 0x5F, 0xD6, 0x05, 0x3C, 0x52, 0x0F, 0x52, + 0x1F, 0xC6, 0x9E, 0x15, 0xA5, 0x7E, 0xBE, 0x9F, 0xA9, 0x57, 0x16, 0x59, + 0x55, 0x72, 0xAF, 0x68, 0x93, 0x70, 0xC2, 0xB2, 0xBA, 0x75, 0x99, 0x6A, + 0x73, 0x32, 0x94, 0xD1, 0x10, 0x44, 0x10, 0x2E, 0xDF, 0x82, 0xF3, 0x07, + 0x84, 0xE6, 0x74, 0x3B, 0x6D, 0x71, 0xE2, 0x2D, 0x0C, 0x1B, 0xEE, 0x20, + 0xD5, 0xC9, 0x20, 0x1D, 0x63, 0x29, 0x2D, 0xCE, 0xEC, 0x5E, 0x4E, 0xC8, + 0x93, 0xF8, 0x21, 0x61, 0x9B, 0x34, 0xEB, 0x05, 0xC6, 0x5E, 0xEC, 0x5B, + 0x1A, 0xBC, 0xEB, 0xC9, 0xCF, 0xCD, 0xAC, 0x34, 0x40, 0x5F, 0xB1, 0x7A, + 0x66, 0xEE, 0x77, 0xC8, 0x48, 0xA8, 0x66, 0x57, 0x57, 0x9F, 0x54, 0x58, + 0x8E, 0x0C, 0x2B, 0xB7, 0x4F, 0xA7, 0x30, 0xD9, 0x56, 0xEE, 0xCA, 0x7B, + 0x5D, 0xE3, 0xAD, 0xC9, 0x4F, 0x5E, 0xE5, 0x35, 0xE7, 0x31, 0xCB, 0xDA, + 0x93, 0x5E, 0xDC, 0x8E, 0x8F, 0x80, 0xDA, 0xB6, 0x91, 0x98, 0x40, 0x90, + 0x79, 0xC3, 0x78, 0xC7, 0xB6, 0xB1, 0xC4, 0xB5, 0x6A, 0x18, 0x38, 0x03, + 0x10, 0x8D, 0xD8, 0xD4, 0x37, 0xA4, 0x2E, 0x05, 0x7D, 0x88, 0xF5, 0x82, + 0x3E, 0x10, 0x91, 0x70, 0xAB, 0x55, 0x82, 0x41, 0x32, 0xD7, 0xDB, 0x04, + 0x73, 0x2A, 0x6E, 0x91, 0x01, 0x7C, 0x21, 0x4C, 0xD4, 0xBC, 0xAE, 0x1B, + 0x03, 0x75, 0x5D, 0x78, 0x66, 0xD9, 0x3A, 0x31, 0x44, 0x9A, 0x33, 0x40, + 0xBF, 0x08, 0xD7, 0x5A, 0x49, 0xA4, 0xC2, 0xE6, 0xA9, 0xA0, 0x67, 0xDD, + 0xA4, 0x27, 0xBC, 0xA1, 0x4F, 0x39, 0xB5, 0x11, 0x58, 0x17, 0xF7, 0x24, + 0x5C, 0x46, 0x8F, 0x64, 0xF7, 0xC1, 0x69, 0x88, 0x76, 0x98, 0x76, 0x3D, + 0x59, 0x5D, 0x42, 0x76, 0x87, 0x89, 0x97, 0x69, 0x7A, 0x48, 0xF0, 0xE0, + 0xA2, 0x12, 0x1B, 0x66, 0x9A, 0x74, 0xCA, 0xDE, 0x4B, 0x1E, 0xE7, 0x0E, + 0x63, 0xAE, 0xE6, 0xD4, 0xEF, 0x92, 0x92, 0x3A, 0x9E, 0x3D, 0xDC, 0x00, + 0xE4, 0x45, 0x25, 0x89, 0xB6, 0x9A, 0x44, 0x19, 0x2B, 0x7E, 0xC0, 0x94, + 0xB4, 0xD2, 0x61, 0x6D, 0xEB, 0x33, 0xD9, 0xC5, 0xDF, 0x4B, 0x04, 0x00, + 0xCC, 0x7D, 0x1C, 0x95, 0xC3, 0x8F, 0xF7, 0x21, 0xB2, 0xB2, 0x11, 0xB7, + 0xBB, 0x7F, 0xF2, 0xD5, 0x8C, 0x70, 0x2C, 0x41, 0x60, 0xAA, 0xB1, 0x63, + 0x18, 0x44, 0x95, 0x1A, 0x76, 0x62, 0x7E, 0xF6, 0x80, 0xB0, 0xFB, 0xE8, + 0x64, 0xA6, 0x33, 0xD1, 0x89, 0x07, 0xE1, 0xBD, 0xB7, 0xE6, 0x43, 0xA4, + 0x18, 0xB8, 0xA6, 0x77, 0x01, 0xE1, 0x0F, 0x94, 0x0C, 0x21, 0x1D, 0xB2, + 0x54, 0x29, 0x25, 0x89, 0x6C, 0xE5, 0x0E, 0x52, 0x51, 0x47, 0x74, 0xBE, + 0x26, 0xAC, 0xB6, 0x41, 0x75, 0xDE, 0x7A, 0xAC, 0x5F, 0x8D, 0x3F, 0xC9, + 0xBC, 0xD3, 0x41, 0x11, 0x12, 0x5B, 0xE5, 0x10, 0x50, 0xEB, 0x31, 0xC5, + 0xCA, 0x72, 0x16, 0x22, 0x09, 0xDF, 0x7C, 0x4C, 0x75, 0x3F, 0x63, 0xEC, + 0x21, 0x5F, 0xC4, 0x20, 0x51, 0x6B, 0x6F, 0xB1, 0xAB, 0x86, 0x8B, 0x4F, + 0xC2, 0xD6, 0x45, 0x5F, 0x9D, 0x20, 0xFC, 0xA1, 0x1E, 0xC5, 0xC0, 0x8F, + 0xA2, 0xB1, 0x7E, 0x0A, 0x26, 0x99, 0xF5, 0xE4, 0x69, 0x2F, 0x98, 0x1D, + 0x2D, 0xF5, 0xD9, 0xA9, 0xB2, 0x1D, 0xE5, 0x1B +}; + +static const unsigned char TA117_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA118_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x15, 0x77, 0x77, 0x77, 0x2E, 0x78, 0x72, 0x61, 0x6D, 0x70, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x58, + 0x52, 0x61, 0x6D, 0x70, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x24, 0x58, 0x52, 0x61, 0x6D, 0x70, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA118_RSA_N[] = { + 0x98, 0x24, 0x1E, 0xBD, 0x15, 0xB4, 0xBA, 0xDF, 0xC7, 0x8C, 0xA5, 0x27, + 0xB6, 0x38, 0x0B, 0x69, 0xF3, 0xB6, 0x4E, 0xA8, 0x2C, 0x2E, 0x21, 0x1D, + 0x5C, 0x44, 0xDF, 0x21, 0x5D, 0x7E, 0x23, 0x74, 0xFE, 0x5E, 0x7E, 0xB4, + 0x4A, 0xB7, 0xA6, 0xAD, 0x1F, 0xAE, 0xE0, 0x06, 0x16, 0xE2, 0x9B, 0x5B, + 0xD9, 0x67, 0x74, 0x6B, 0x5D, 0x80, 0x8F, 0x29, 0x9D, 0x86, 0x1B, 0xD9, + 0x9C, 0x0D, 0x98, 0x6D, 0x76, 0x10, 0x28, 0x58, 0xE4, 0x65, 0xB0, 0x7F, + 0x4A, 0x98, 0x79, 0x9F, 0xE0, 0xC3, 0x31, 0x7E, 0x80, 0x2B, 0xB5, 0x8C, + 0xC0, 0x40, 0x3B, 0x11, 0x86, 0xD0, 0xCB, 0xA2, 0x86, 0x36, 0x60, 0xA4, + 0xD5, 0x30, 0x82, 0x6D, 0xD9, 0x6E, 0xD0, 0x0F, 0x12, 0x04, 0x33, 0x97, + 0x5F, 0x4F, 0x61, 0x5A, 0xF0, 0xE4, 0xF9, 0x91, 0xAB, 0xE7, 0x1D, 0x3B, + 0xBC, 0xE8, 0xCF, 0xF4, 0x6B, 0x2D, 0x34, 0x7C, 0xE2, 0x48, 0x61, 0x1C, + 0x8E, 0xF3, 0x61, 0x44, 0xCC, 0x6F, 0xA0, 0x4A, 0xA9, 0x94, 0xB0, 0x4D, + 0xDA, 0xE7, 0xA9, 0x34, 0x7A, 0x72, 0x38, 0xA8, 0x41, 0xCC, 0x3C, 0x94, + 0x11, 0x7D, 0xEB, 0xC8, 0xA6, 0x8C, 0xB7, 0x86, 0xCB, 0xCA, 0x33, 0x3B, + 0xD9, 0x3D, 0x37, 0x8B, 0xFB, 0x7A, 0x3E, 0x86, 0x2C, 0xE7, 0x73, 0xD7, + 0x0A, 0x57, 0xAC, 0x64, 0x9B, 0x19, 0xEB, 0xF4, 0x0F, 0x04, 0x08, 0x8A, + 0xAC, 0x03, 0x17, 0x19, 0x64, 0xF4, 0x5A, 0x25, 0x22, 0x8D, 0x34, 0x2C, + 0xB2, 0xF6, 0x68, 0x1D, 0x12, 0x6D, 0xD3, 0x8A, 0x1E, 0x14, 0xDA, 0xC4, + 0x8F, 0xA6, 0xE2, 0x23, 0x85, 0xD5, 0x7A, 0x0D, 0xBD, 0x6A, 0xE0, 0xE9, + 0xEC, 0xEC, 0x17, 0xBB, 0x42, 0x1B, 0x67, 0xAA, 0x25, 0xED, 0x45, 0x83, + 0x21, 0xFC, 0xC1, 0xC9, 0x7C, 0xD5, 0x62, 0x3E, 0xFA, 0xF2, 0xC5, 0x2D, + 0xD3, 0xFD, 0xD4, 0x65 +}; + +static const unsigned char TA118_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA119_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA119_RSA_N[] = { + 0xCC, 0x57, 0x42, 0x16, 0x54, 0x9C, 0xE6, 0x98, 0xD3, 0xD3, 0x4D, 0xEE, + 0xFE, 0xED, 0xC7, 0x9F, 0x43, 0x39, 0x4A, 0x65, 0xB3, 0xE8, 0x16, 0x88, + 0x34, 0xDB, 0x0D, 0x59, 0x91, 0x74, 0xCF, 0x92, 0xB8, 0x04, 0x40, 0xAD, + 0x02, 0x4B, 0x31, 0xAB, 0xBC, 0x8D, 0x91, 0x68, 0xD8, 0x20, 0x0E, 0x1A, + 0x01, 0xE2, 0x1A, 0x7B, 0x4E, 0x17, 0x5D, 0xE2, 0x8A, 0xB7, 0x3F, 0x99, + 0x1A, 0xCD, 0xEB, 0x61, 0xAB, 0xC2, 0x65, 0xA6, 0x1F, 0xB7, 0xB7, 0xBD, + 0xB7, 0x8F, 0xFC, 0xFD, 0x70, 0x8F, 0x0B, 0xA0, 0x67, 0xBE, 0x01, 0xA2, + 0x59, 0xCF, 0x71, 0xE6, 0x0F, 0x29, 0x76, 0xFF, 0xB1, 0x56, 0x79, 0x45, + 0x2B, 0x1F, 0x9E, 0x7A, 0x54, 0xE8, 0xA3, 0x29, 0x35, 0x68, 0xA4, 0x01, + 0x4F, 0x0F, 0xA4, 0x2E, 0x37, 0xEF, 0x1B, 0xBF, 0xE3, 0x8F, 0x10, 0xA8, + 0x72, 0xAB, 0x58, 0x57, 0xE7, 0x54, 0x86, 0xC8, 0xC9, 0xF3, 0x5B, 0xDA, + 0x2C, 0xDA, 0x5D, 0x8E, 0x6E, 0x3C, 0xA3, 0x3E, 0xDA, 0xFB, 0x82, 0xE5, + 0xDD, 0xF2, 0x5C, 0xB2, 0x05, 0x33, 0x6F, 0x8A, 0x36, 0xCE, 0xD0, 0x13, + 0x4E, 0xFF, 0xBF, 0x4A, 0x0C, 0x34, 0x4C, 0xA6, 0xC3, 0x21, 0xBD, 0x50, + 0x04, 0x55, 0xEB, 0xB1, 0xBB, 0x9D, 0xFB, 0x45, 0x1E, 0x64, 0x15, 0xDE, + 0x55, 0x01, 0x8C, 0x02, 0x76, 0xB5, 0xCB, 0xA1, 0x3F, 0x42, 0x69, 0xBC, + 0x2F, 0xBD, 0x68, 0x43, 0x16, 0x56, 0x89, 0x2A, 0x37, 0x61, 0x91, 0xFD, + 0xA6, 0xAE, 0x4E, 0xC0, 0xCB, 0x14, 0x65, 0x94, 0x37, 0x4B, 0x92, 0x06, + 0xEF, 0x04, 0xD0, 0xC8, 0x9C, 0x88, 0xDB, 0x0B, 0x7B, 0x81, 0xAF, 0xB1, + 0x3D, 0x2A, 0xC4, 0x65, 0x3A, 0x78, 0xB6, 0xEE, 0xDC, 0x80, 0xB1, 0xD2, + 0xD3, 0x99, 0x9C, 0x3A, 0xEE, 0x6B, 0x5A, 0x6B, 0xB3, 0x8D, 0xB7, 0xD5, + 0xCE, 0x9C, 0xC2, 0xBE, 0xA5, 0x4B, 0x2F, 0x16, 0xB1, 0x9E, 0x68, 0x3B, + 0x06, 0x6F, 0xAE, 0x7D, 0x9F, 0xF8, 0xDE, 0xEC, 0xCC, 0x29, 0xA7, 0x98, + 0xA3, 0x25, 0x43, 0x2F, 0xEF, 0xF1, 0x5F, 0x26, 0xE1, 0x88, 0x4D, 0xF8, + 0x5E, 0x6E, 0xD7, 0xD9, 0x14, 0x6E, 0x19, 0x33, 0x69, 0xA7, 0x3B, 0x84, + 0x89, 0x93, 0xC4, 0x53, 0x55, 0x13, 0xA1, 0x51, 0x78, 0x40, 0xF8, 0xB8, + 0xC9, 0xA2, 0xEE, 0x7B, 0xBA, 0x52, 0x42, 0x83, 0x9E, 0x14, 0xED, 0x05, + 0x52, 0x5A, 0x59, 0x56, 0xA7, 0x97, 0xFC, 0x9D, 0x3F, 0x0A, 0x29, 0xD8, + 0xDC, 0x4F, 0x91, 0x0E, 0x13, 0xBC, 0xDE, 0x95, 0xA4, 0xDF, 0x8B, 0x99, + 0xBE, 0xAC, 0x9B, 0x33, 0x88, 0xEF, 0xB5, 0x81, 0xAF, 0x1B, 0xC6, 0x22, + 0x53, 0xC8, 0xF6, 0xC7, 0xEE, 0x97, 0x14, 0xB0, 0xC5, 0x7C, 0x78, 0x52, + 0xC8, 0xF0, 0xCE, 0x6E, 0x77, 0x60, 0x84, 0xA6, 0xE9, 0x2A, 0x76, 0x20, + 0xED, 0x58, 0x01, 0x17, 0x30, 0x93, 0xE9, 0x1A, 0x8B, 0xE0, 0x73, 0x63, + 0xD9, 0x6A, 0x92, 0x94, 0x49, 0x4E, 0xB4, 0xAD, 0x4A, 0x85, 0xC4, 0xA3, + 0x22, 0x30, 0xFC, 0x09, 0xED, 0x68, 0x22, 0x73, 0xA6, 0x88, 0x0C, 0x55, + 0x21, 0x58, 0xC5, 0xE1, 0x3A, 0x9F, 0x2A, 0xDD, 0xCA, 0xE1, 0x90, 0xE0, + 0xD9, 0x73, 0xAB, 0x6C, 0x80, 0xB8, 0xE8, 0x0B, 0x64, 0x93, 0xA0, 0x9C, + 0x8C, 0x19, 0xFF, 0xB3, 0xD2, 0x0C, 0xEC, 0x91, 0x26, 0x87, 0x8A, 0xB3, + 0xA2, 0xE1, 0x70, 0x8F, 0x2C, 0x0A, 0xE5, 0xCD, 0x6D, 0x68, 0x51, 0xEB, + 0xDA, 0x3F, 0x05, 0x7F, 0x8B, 0x32, 0xE6, 0x13, 0x5C, 0x6B, 0xFE, 0x5F, + 0x40, 0xE2, 0x22, 0xC8, 0xB4, 0xB4, 0x64, 0x4F, 0xD6, 0xBA, 0x7D, 0x48, + 0x3E, 0xA8, 0x69, 0x0C, 0xD7, 0xBB, 0x86, 0x71, 0xC9, 0x73, 0xB8, 0x3F, + 0x3B, 0x9D, 0x25, 0x4B, 0xDA, 0xFF, 0x40, 0xEB +}; + +static const unsigned char TA119_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA120_DN[] = { + 0x30, 0x81, 0xAA, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x44, 0x30, 0x42, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, + 0x20, 0x32, 0x30, 0x31, 0x35 +}; + +static const unsigned char TA120_EC_Q[] = { + 0x04, 0x92, 0xA0, 0x41, 0xE8, 0x4B, 0x82, 0x84, 0x5C, 0xE2, 0xF8, 0x31, + 0x11, 0x99, 0x86, 0x64, 0x4E, 0x09, 0x25, 0x2F, 0x9D, 0x41, 0x2F, 0x0A, + 0xAE, 0x35, 0x4F, 0x74, 0x95, 0xB2, 0x51, 0x64, 0x6B, 0x8D, 0x6B, 0xE6, + 0x3F, 0x70, 0x95, 0xF0, 0x05, 0x44, 0x47, 0xA6, 0x72, 0x38, 0x50, 0x76, + 0x95, 0x02, 0x5A, 0x8E, 0xAE, 0x28, 0x9E, 0xF9, 0x2D, 0x4E, 0x99, 0xEF, + 0x2C, 0x48, 0x6F, 0x4C, 0x25, 0x29, 0xE8, 0xD1, 0x71, 0x5B, 0xDF, 0x1D, + 0xC1, 0x75, 0x37, 0xB4, 0xD7, 0xFA, 0x7B, 0x7A, 0x42, 0x9C, 0x6A, 0x0A, + 0x56, 0x5A, 0x7C, 0x69, 0x0B, 0xAA, 0x80, 0x09, 0x24, 0x6C, 0x7E, 0xC1, + 0x46 +}; + +static const unsigned char TA121_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x43, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA121_EC_Q[] = { + 0x04, 0x4C, 0xE9, 0x50, 0xC0, 0xC6, 0x0F, 0x72, 0x18, 0xBC, 0xD8, 0xF1, + 0xBA, 0xB3, 0x89, 0xE2, 0x79, 0x4A, 0xA3, 0x16, 0xA7, 0x6B, 0x54, 0x24, + 0xDB, 0x51, 0xFF, 0xEA, 0xF4, 0x09, 0x24, 0xC3, 0x0B, 0x22, 0x9F, 0xCB, + 0x6A, 0x27, 0x82, 0x81, 0x0D, 0xD2, 0xC0, 0xAF, 0x31, 0xE4, 0x74, 0x82, + 0x6E, 0xCA, 0x25, 0xD9, 0x8C, 0x75, 0x9D, 0xF1, 0xDB, 0xD0, 0x9A, 0xA2, + 0x4B, 0x21, 0x7E, 0x16, 0xA7, 0x63, 0x90, 0xD2, 0x39, 0xD4, 0xB1, 0x87, + 0x78, 0x5F, 0x18, 0x96, 0x0F, 0x50, 0x1B, 0x35, 0x37, 0x0F, 0x6A, 0xC6, + 0xDC, 0xD9, 0x13, 0x4D, 0xA4, 0x8E, 0x90, 0x37, 0xE6, 0xBD, 0x5B, 0x31, + 0x91 +}; + +static const unsigned char TA122_DN[] = { + 0x30, 0x7F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x2B, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, 0x56, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA122_EC_Q[] = { + 0x04, 0xAA, 0x12, 0x47, 0x90, 0x98, 0x1B, 0xFB, 0xEF, 0xC3, 0x40, 0x07, + 0x83, 0x20, 0x4E, 0xF1, 0x30, 0x82, 0xA2, 0x06, 0xD1, 0xF2, 0x92, 0x86, + 0x61, 0xF2, 0xF6, 0x21, 0x68, 0xCA, 0x00, 0xC4, 0xC7, 0xEA, 0x43, 0x00, + 0x54, 0x86, 0xDC, 0xFD, 0x1F, 0xDF, 0x00, 0xB8, 0x41, 0x62, 0x5C, 0xDC, + 0x70, 0x16, 0x32, 0xDE, 0x1F, 0x99, 0xD4, 0xCC, 0xC5, 0x07, 0xC8, 0x08, + 0x1F, 0x61, 0x16, 0x07, 0x51, 0x3D, 0x7D, 0x5C, 0x07, 0x53, 0xE3, 0x35, + 0x38, 0x8C, 0xDF, 0xCD, 0x9F, 0xD9, 0x2E, 0x0D, 0x4A, 0xB6, 0x19, 0x2E, + 0x5A, 0x70, 0x5A, 0x06, 0xED, 0xBE, 0xF0, 0xA1, 0xB0, 0xCA, 0xD0, 0x09, + 0x29 +}; + +static const unsigned char TA123_DN[] = { + 0x30, 0x43, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, + 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0D, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA123_RSA_N[] = { + 0xBD, 0x55, 0x7C, 0x61, 0xD3, 0xB8, 0x1D, 0x04, 0x62, 0x05, 0xA0, 0xAE, + 0x6C, 0xB7, 0x70, 0xB4, 0x41, 0xEA, 0x4B, 0x03, 0x5E, 0x10, 0x3F, 0x90, + 0x5A, 0x1C, 0x8B, 0x3B, 0xB0, 0x66, 0x8B, 0x6C, 0x48, 0xA6, 0x1C, 0x22, + 0xBA, 0xD5, 0x40, 0x92, 0xEE, 0x33, 0xB2, 0x23, 0x59, 0xC9, 0x8E, 0xBC, + 0x58, 0xDA, 0x8B, 0x9E, 0xD0, 0x19, 0xF2, 0x2F, 0x59, 0xC6, 0x8C, 0x63, + 0x5A, 0xBA, 0x9F, 0xA3, 0x0B, 0xB0, 0xB3, 0x9A, 0x5C, 0xBA, 0x11, 0xB8, + 0x12, 0xE9, 0x0C, 0xBB, 0xCF, 0x6E, 0x6C, 0x80, 0x87, 0x29, 0x14, 0x03, + 0x2C, 0x8D, 0x24, 0x9A, 0xC8, 0x64, 0x83, 0xB5, 0x6A, 0xAC, 0x13, 0x2C, + 0x33, 0xF1, 0x9F, 0xDC, 0x2C, 0x61, 0x3C, 0x1A, 0x3F, 0x70, 0x55, 0x9B, + 0xAD, 0x00, 0x52, 0x7F, 0xCF, 0x04, 0xB9, 0xFE, 0x36, 0xFA, 0x9C, 0xC0, + 0x16, 0xAE, 0x62, 0xFE, 0x96, 0x4C, 0x43, 0x7E, 0x55, 0x14, 0xBE, 0x1A, + 0xB3, 0xD2, 0x6D, 0xC2, 0xAF, 0x76, 0x66, 0x95, 0x6B, 0x2A, 0xB0, 0x94, + 0x77, 0x85, 0x5E, 0x04, 0x0F, 0x62, 0x1D, 0x63, 0x75, 0xF7, 0x6B, 0xE7, + 0xCB, 0x5B, 0x9A, 0x70, 0xEC, 0x3E, 0x67, 0x05, 0xF0, 0xFE, 0x07, 0x08, + 0x80, 0xCF, 0x28, 0xDB, 0x05, 0xC6, 0x14, 0x27, 0x2F, 0x86, 0x7D, 0xF0, + 0x27, 0xDE, 0xFF, 0xE6, 0x7E, 0x33, 0x48, 0xE7, 0x0B, 0x1E, 0x58, 0xD1, + 0x27, 0x2B, 0x53, 0x0E, 0x57, 0x4A, 0x65, 0xD7, 0xFB, 0xA2, 0x80, 0x60, + 0xFC, 0x4C, 0xBC, 0x35, 0x53, 0x01, 0x6A, 0x97, 0x72, 0x82, 0xAF, 0xF1, + 0x1D, 0x70, 0xE8, 0x9C, 0xF5, 0xEF, 0x5E, 0xC2, 0x6C, 0xC7, 0x47, 0x7E, + 0x5A, 0x94, 0x85, 0x26, 0x4D, 0x3B, 0xBA, 0xEB, 0x4C, 0xE8, 0xB0, 0x09, + 0xC2, 0x65, 0xC2, 0x9D, 0x9D, 0x09, 0x9B, 0x4E, 0xB5, 0x97, 0x05, 0xAC, + 0xF5, 0x06, 0xA0, 0xF7, 0x36, 0x05, 0x7E, 0xF4, 0x90, 0xB2, 0x6B, 0xC4, + 0xB4, 0xF9, 0x64, 0xEA, 0xE9, 0x1A, 0x0A, 0xC8, 0x0D, 0xA8, 0xED, 0x27, + 0xC9, 0xD4, 0xE7, 0xB3, 0xB9, 0xAB, 0x82, 0x22, 0x90, 0x27, 0x3D, 0x2A, + 0xE8, 0x7C, 0x90, 0xEF, 0xBC, 0x4F, 0xFD, 0xE2, 0x0A, 0x24, 0xA7, 0xDE, + 0x65, 0x24, 0xA4, 0x5D, 0xEA, 0xC0, 0x76, 0x30, 0xD3, 0x77, 0x50, 0xF8, + 0x0D, 0x04, 0x9B, 0x94, 0x36, 0x01, 0x73, 0xCA, 0x06, 0x58, 0xA6, 0xD3, + 0x3B, 0xDC, 0xFA, 0x04, 0x46, 0x13, 0x55, 0x8A, 0xC9, 0x44, 0x47, 0xB8, + 0x51, 0x39, 0x1A, 0x2E, 0xE8, 0x34, 0xE2, 0x79, 0xCB, 0x59, 0x4A, 0x0A, + 0x7F, 0xBC, 0xA6, 0xEF, 0x1F, 0x03, 0x67, 0x6A, 0x59, 0x2B, 0x25, 0x62, + 0x93, 0xD9, 0x53, 0x19, 0x66, 0x3C, 0x27, 0x62, 0x29, 0x86, 0x4D, 0xA4, + 0x6B, 0xEE, 0xFF, 0xD4, 0x4E, 0xBA, 0xD5, 0xB4, 0xE2, 0x8E, 0x48, 0x5A, + 0x00, 0x19, 0x09, 0xF1, 0x05, 0xD9, 0xCE, 0x91, 0xB1, 0xF7, 0xEB, 0xE9, + 0x39, 0x4F, 0xF6, 0x6F, 0x04, 0x43, 0x9A, 0x55, 0xF5, 0x3E, 0x05, 0x14, + 0xBD, 0xBF, 0xB3, 0x59, 0xB4, 0xD8, 0x8E, 0x33, 0x84, 0xA3, 0x90, 0x52, + 0xAA, 0xB3, 0x02, 0x95, 0x60, 0xF9, 0x0C, 0x4C, 0x68, 0xF9, 0xEE, 0xD5, + 0x17, 0x0D, 0xF8, 0x71, 0x57, 0xB5, 0x25, 0xE4, 0x29, 0xEE, 0x65, 0x5D, + 0xAF, 0xD1, 0xEE, 0x3C, 0x17, 0x0B, 0x5A, 0x43, 0xC5, 0xA5, 0x86, 0xEA, + 0x24, 0x9E, 0xE2, 0x05, 0x07, 0xDC, 0x34, 0x42, 0x12, 0x91, 0xD6, 0x39, + 0x74, 0xAE, 0x4C, 0x41, 0x82, 0xDB, 0xF2, 0xA6, 0x48, 0xD1, 0xB3, 0x9B, + 0xF3, 0x33, 0xAA, 0xF3, 0xA6, 0xC0, 0xC5, 0x4E, 0xF5, 0xF4, 0x9D, 0x76, + 0x63, 0xE6, 0x02, 0xC6, 0x22, 0x4B, 0xC1, 0x95, 0x3F, 0x50, 0x64, 0x2C, + 0x54, 0xE5, 0xB6, 0xF0, 0x3C, 0x29, 0xCF, 0x57 +}; + +static const unsigned char TA123_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA124_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x52, 0x31 +}; + +static const unsigned char TA124_RSA_N[] = { + 0xD0, 0x36, 0xD4, 0x1F, 0xEA, 0xDD, 0xAB, 0xE4, 0xD1, 0xB6, 0xE6, 0xFB, + 0x22, 0xC0, 0xDD, 0x13, 0x0D, 0x6A, 0x7B, 0x22, 0x13, 0x1C, 0x97, 0x3C, + 0x68, 0x63, 0x66, 0x32, 0x9C, 0x03, 0xB5, 0x8D, 0xA4, 0x81, 0x83, 0xDA, + 0x78, 0x30, 0x11, 0xCF, 0xDC, 0xB2, 0x2B, 0xBE, 0x92, 0xBF, 0x8E, 0xE4, + 0xC4, 0x13, 0xBE, 0xA4, 0x68, 0x4C, 0xDA, 0x02, 0x68, 0x16, 0x74, 0xBE, + 0xB2, 0xDD, 0x04, 0xE4, 0x6B, 0x2A, 0xDD, 0x37, 0x1F, 0x60, 0x2C, 0xDB, + 0xF5, 0xF7, 0xA1, 0x7C, 0x95, 0xB7, 0x0C, 0x70, 0x86, 0x2E, 0xF1, 0x3A, + 0xEF, 0x52, 0xF7, 0xCC, 0xD3, 0x9B, 0xF9, 0x8B, 0xBE, 0x0E, 0xDF, 0x31, + 0xB7, 0x9D, 0x68, 0x5C, 0x92, 0xA6, 0xF5, 0xE5, 0xF3, 0x0A, 0x34, 0xB5, + 0xFF, 0x7B, 0xA2, 0xE4, 0x87, 0xA1, 0xC6, 0xAF, 0x17, 0x00, 0xEF, 0x03, + 0x91, 0xED, 0xA9, 0x1C, 0x4E, 0x71, 0x3D, 0xD2, 0x8B, 0x6C, 0x89, 0xF4, + 0x78, 0x86, 0xE6, 0x6A, 0x49, 0xA0, 0xCE, 0xB5, 0xD2, 0xB0, 0xAB, 0x9B, + 0xF6, 0xF4, 0xD4, 0x2E, 0xE3, 0x72, 0xF9, 0x36, 0xC6, 0xEB, 0x15, 0xB7, + 0x25, 0x8C, 0x3A, 0xFC, 0x25, 0x0D, 0xB3, 0x22, 0x73, 0x21, 0x74, 0xC8, + 0x4A, 0x96, 0x61, 0x92, 0xF5, 0x2F, 0x0B, 0x18, 0xA5, 0xF4, 0xAD, 0xE2, + 0xEE, 0x41, 0xBD, 0x01, 0x79, 0xFA, 0x96, 0x8C, 0x8D, 0x17, 0x02, 0x30, + 0xB4, 0xF9, 0xAF, 0x78, 0x1A, 0x8C, 0xB4, 0x36, 0x10, 0x10, 0x07, 0x05, + 0x70, 0xD0, 0xF4, 0x31, 0x90, 0x8A, 0x51, 0xC5, 0x86, 0x26, 0x79, 0xB2, + 0x11, 0x88, 0x5E, 0xC5, 0xF0, 0x0A, 0x54, 0xCD, 0x49, 0xA6, 0xBF, 0x02, + 0x9C, 0xD2, 0x44, 0xA7, 0xED, 0xE3, 0x78, 0xEF, 0x46, 0x5E, 0x6D, 0x71, + 0xD1, 0x79, 0x70, 0x1C, 0x46, 0x5F, 0x51, 0xE9, 0xC9, 0x37, 0xDC, 0x5F, + 0x7E, 0x69, 0x7B, 0x41, 0xDF, 0x34, 0x45, 0xE0, 0x3B, 0x84, 0xF4, 0xA1, + 0x8A, 0x0A, 0x36, 0x9E, 0x37, 0xCC, 0x62, 0x52, 0xE1, 0x89, 0x0D, 0x28, + 0xF9, 0x7A, 0x23, 0xB1, 0x0D, 0x3D, 0x3D, 0x9A, 0xFD, 0x9D, 0x81, 0xEF, + 0x2C, 0x90, 0xC0, 0x7B, 0x44, 0x4E, 0xBB, 0x49, 0xE0, 0x0E, 0x4A, 0x56, + 0x92, 0xBC, 0xCB, 0xB5, 0xDD, 0x79, 0x17, 0x89, 0x91, 0xDE, 0x61, 0x89, + 0x74, 0x92, 0xA8, 0xE3, 0x32, 0x85, 0xBE, 0x4E, 0x85, 0xA4, 0x4B, 0x59, + 0xCB, 0x2B, 0xC5, 0x78, 0x8E, 0x71, 0x54, 0xD0, 0x02, 0x37, 0x99, 0x8C, + 0xE5, 0x49, 0xEA, 0xE0, 0x54, 0x72, 0xA4, 0x11, 0x06, 0x2F, 0x0B, 0x8C, + 0xC1, 0x5B, 0xBE, 0xB5, 0xA1, 0xB0, 0x53, 0x6E, 0x9C, 0xB8, 0x60, 0x91, + 0x1F, 0x59, 0x6B, 0xF9, 0x2D, 0xF4, 0x94, 0x0A, 0x97, 0xB5, 0xEC, 0xC5, + 0x76, 0x03, 0x54, 0x1B, 0x65, 0x52, 0xBA, 0x4C, 0x92, 0x56, 0x51, 0x35, + 0xA0, 0x40, 0xD8, 0x29, 0xDB, 0xAE, 0x52, 0x76, 0x3B, 0x2D, 0x30, 0x40, + 0x9B, 0x8A, 0xD0, 0x42, 0x56, 0xB4, 0xB7, 0x88, 0x01, 0xA4, 0x87, 0x3B, + 0x53, 0x96, 0xCD, 0xA3, 0x16, 0x8F, 0xF3, 0x66, 0xAA, 0x17, 0xB1, 0xC7, + 0x60, 0xE0, 0xC1, 0x43, 0x05, 0x0C, 0xEE, 0x9B, 0x5B, 0x60, 0x6F, 0x06, + 0x5C, 0x87, 0x5B, 0x27, 0xF9, 0x40, 0x11, 0x9E, 0x9C, 0x33, 0xC1, 0xB7, + 0xE5, 0x35, 0x57, 0x05, 0x7F, 0x27, 0xCE, 0x17, 0x20, 0x8C, 0x1C, 0xFC, + 0xF1, 0xFB, 0xDA, 0x31, 0x29, 0x49, 0xED, 0xF5, 0x0B, 0x84, 0xA7, 0x4F, + 0xC1, 0xF6, 0x4E, 0xC2, 0x28, 0x9C, 0xFA, 0xEE, 0xE0, 0xAF, 0x07, 0xFB, + 0x33, 0x11, 0x7A, 0x21, 0x4F, 0x0B, 0x21, 0x10, 0xB6, 0x40, 0x3A, 0xAB, + 0x22, 0x3A, 0x04, 0x9C, 0x8B, 0x9B, 0x84, 0x86, 0x72, 0x9A, 0xD2, 0xA7, + 0xA5, 0xC4, 0xB4, 0x75, 0x91, 0xA9, 0x2B, 0x23 +}; + +static const unsigned char TA124_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA125_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA125_EC_Q[] = { + 0x04, 0x29, 0x97, 0xA7, 0xC6, 0x41, 0x7F, 0xC0, 0x0D, 0x9B, 0xE8, 0x01, + 0x1B, 0x56, 0xC6, 0xF2, 0x52, 0xA5, 0xBA, 0x2D, 0xB2, 0x12, 0xE8, 0xD2, + 0x2E, 0xD7, 0xFA, 0xC9, 0xC5, 0xD8, 0xAA, 0x6D, 0x1F, 0x73, 0x81, 0x3B, + 0x3B, 0x98, 0x6B, 0x39, 0x7C, 0x33, 0xA5, 0xC5, 0x4E, 0x86, 0x8E, 0x80, + 0x17, 0x68, 0x62, 0x45, 0x57, 0x7D, 0x44, 0x58, 0x1D, 0xB3, 0x37, 0xE5, + 0x67, 0x08, 0xEB, 0x66, 0xDE +}; + +static const unsigned char TA126_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA126_RSA_N[] = { + 0x9A, 0x18, 0xCA, 0x4B, 0x94, 0x0D, 0x00, 0x2D, 0xAF, 0x03, 0x29, 0x8A, + 0xF0, 0x0F, 0x81, 0xC8, 0xAE, 0x4C, 0x19, 0x85, 0x1D, 0x08, 0x9F, 0xAB, + 0x29, 0x44, 0x85, 0xF3, 0x2F, 0x81, 0xAD, 0x32, 0x1E, 0x90, 0x46, 0xBF, + 0xA3, 0x86, 0x26, 0x1A, 0x1E, 0xFE, 0x7E, 0x1C, 0x18, 0x3A, 0x5C, 0x9C, + 0x60, 0x17, 0x2A, 0x3A, 0x74, 0x83, 0x33, 0x30, 0x7D, 0x61, 0x54, 0x11, + 0xCB, 0xED, 0xAB, 0xE0, 0xE6, 0xD2, 0xA2, 0x7E, 0xF5, 0x6B, 0x6F, 0x18, + 0xB7, 0x0A, 0x0B, 0x2D, 0xFD, 0xE9, 0x3E, 0xEF, 0x0A, 0xC6, 0xB3, 0x10, + 0xE9, 0xDC, 0xC2, 0x46, 0x17, 0xF8, 0x5D, 0xFD, 0xA4, 0xDA, 0xFF, 0x9E, + 0x49, 0x5A, 0x9C, 0xE6, 0x33, 0xE6, 0x24, 0x96, 0xF7, 0x3F, 0xBA, 0x5B, + 0x2B, 0x1C, 0x7A, 0x35, 0xC2, 0xD6, 0x67, 0xFE, 0xAB, 0x66, 0x50, 0x8B, + 0x6D, 0x28, 0x60, 0x2B, 0xEF, 0xD7, 0x60, 0xC3, 0xC7, 0x93, 0xBC, 0x8D, + 0x36, 0x91, 0xF3, 0x7F, 0xF8, 0xDB, 0x11, 0x13, 0xC4, 0x9C, 0x77, 0x76, + 0xC1, 0xAE, 0xB7, 0x02, 0x6A, 0x81, 0x7A, 0xA9, 0x45, 0x83, 0xE2, 0x05, + 0xE6, 0xB9, 0x56, 0xC1, 0x94, 0x37, 0x8F, 0x48, 0x71, 0x63, 0x22, 0xEC, + 0x17, 0x65, 0x07, 0x95, 0x8A, 0x4B, 0xDF, 0x8F, 0xC6, 0x5A, 0x0A, 0xE5, + 0xB0, 0xE3, 0x5F, 0x5E, 0x6B, 0x11, 0xAB, 0x0C, 0xF9, 0x85, 0xEB, 0x44, + 0xE9, 0xF8, 0x04, 0x73, 0xF2, 0xE9, 0xFE, 0x5C, 0x98, 0x8C, 0xF5, 0x73, + 0xAF, 0x6B, 0xB4, 0x7E, 0xCD, 0xD4, 0x5C, 0x02, 0x2B, 0x4C, 0x39, 0xE1, + 0xB2, 0x95, 0x95, 0x2D, 0x42, 0x87, 0xD7, 0xD5, 0xB3, 0x90, 0x43, 0xB7, + 0x6C, 0x13, 0xF1, 0xDE, 0xDD, 0xF6, 0xC4, 0xF8, 0x89, 0x3F, 0xD1, 0x75, + 0xF5, 0x92, 0xC3, 0x91, 0xD5, 0x8A, 0x88, 0xD0, 0x90, 0xEC, 0xDC, 0x6D, + 0xDE, 0x89, 0xC2, 0x65, 0x71, 0x96, 0x8B, 0x0D, 0x03, 0xFD, 0x9C, 0xBF, + 0x5B, 0x16, 0xAC, 0x92, 0xDB, 0xEA, 0xFE, 0x79, 0x7C, 0xAD, 0xEB, 0xAF, + 0xF7, 0x16, 0xCB, 0xDB, 0xCD, 0x25, 0x2B, 0xE5, 0x1F, 0xFB, 0x9A, 0x9F, + 0xE2, 0x51, 0xCC, 0x3A, 0x53, 0x0C, 0x48, 0xE6, 0x0E, 0xBD, 0xC9, 0xB4, + 0x76, 0x06, 0x52, 0xE6, 0x11, 0x13, 0x85, 0x72, 0x63, 0x03, 0x04, 0xE0, + 0x04, 0x36, 0x2B, 0x20, 0x19, 0x02, 0xE8, 0x74, 0xA7, 0x1F, 0xB6, 0xC9, + 0x56, 0x66, 0xF0, 0x75, 0x25, 0xDC, 0x67, 0xC1, 0x0E, 0x61, 0x60, 0x88, + 0xB3, 0x3E, 0xD1, 0xA8, 0xFC, 0xA3, 0xDA, 0x1D, 0xB0, 0xD1, 0xB1, 0x23, + 0x54, 0xDF, 0x44, 0x76, 0x6D, 0xED, 0x41, 0xD8, 0xC1, 0xB2, 0x22, 0xB6, + 0x53, 0x1C, 0xDF, 0x35, 0x1D, 0xDC, 0xA1, 0x77, 0x2A, 0x31, 0xE4, 0x2D, + 0xF5, 0xE5, 0xE5, 0xDB, 0xC8, 0xE0, 0xFF, 0xE5, 0x80, 0xD7, 0x0B, 0x63, + 0xA0, 0xFF, 0x33, 0xA1, 0x0F, 0xBA, 0x2C, 0x15, 0x15, 0xEA, 0x97, 0xB3, + 0xD2, 0xA2, 0xB5, 0xBE, 0xF2, 0x8C, 0x96, 0x1E, 0x1A, 0x8F, 0x1D, 0x6C, + 0xA4, 0x61, 0x37, 0xB9, 0x86, 0x73, 0x33, 0xD7, 0x97, 0x96, 0x9E, 0x23, + 0x7D, 0x82, 0xA4, 0x4C, 0x81, 0xE2, 0xA1, 0xD1, 0xBA, 0x67, 0x5F, 0x95, + 0x07, 0xA3, 0x27, 0x11, 0xEE, 0x16, 0x10, 0x7B, 0xBC, 0x45, 0x4A, 0x4C, + 0xB2, 0x04, 0xD2, 0xAB, 0xEF, 0xD5, 0xFD, 0x0C, 0x51, 0xCE, 0x50, 0x6A, + 0x08, 0x31, 0xF9, 0x91, 0xDA, 0x0C, 0x8F, 0x64, 0x5C, 0x03, 0xC3, 0x3A, + 0x8B, 0x20, 0x3F, 0x6E, 0x8D, 0x67, 0x3D, 0x3A, 0xD6, 0xFE, 0x7D, 0x5B, + 0x88, 0xC9, 0x5E, 0xFB, 0xCC, 0x61, 0xDC, 0x8B, 0x33, 0x77, 0xD3, 0x44, + 0x32, 0x35, 0x09, 0x62, 0x04, 0x92, 0x16, 0x10, 0xD8, 0x9E, 0x27, 0x47, + 0xFB, 0x3B, 0x21, 0xE3, 0xF8, 0xEB, 0x1D, 0x5B +}; + +static const unsigned char TA126_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA127_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x32 +}; + +static const unsigned char TA127_EC_Q[] = { + 0x04, 0x9D, 0xCB, 0x80, 0x91, 0x8D, 0x53, 0x67, 0xB5, 0xB9, 0x50, 0xB1, + 0x03, 0xF8, 0xE5, 0x49, 0x1F, 0x41, 0x22, 0x09, 0xB0, 0x51, 0x52, 0x58, + 0xD6, 0x2B, 0x34, 0x8F, 0xC5, 0x12, 0x46, 0x14, 0xC5, 0x8B, 0x2F, 0x2C, + 0x84, 0xFF, 0x2C, 0x6E, 0xA8, 0xD5, 0xF1, 0x09, 0xE3, 0x03, 0x21, 0x14, + 0xC4, 0x43, 0x3D, 0x7C, 0xC1, 0x2C, 0xC4, 0x4B, 0x6A, 0x4A, 0xCD, 0xE9, + 0x87, 0xE0, 0x7D, 0xF6, 0x22, 0xBE, 0xFA, 0x4A, 0x51, 0xB8, 0x30, 0x8A, + 0xFD, 0xE1, 0xDE, 0x18, 0x12, 0x0A, 0xF6, 0x47, 0xB7, 0xE7, 0x17, 0xBF, + 0x27, 0x8A, 0xD4, 0x41, 0x4C, 0x96, 0x3C, 0x60, 0x96, 0xC1, 0xFD, 0x15, + 0x1C +}; + +static const unsigned char TA128_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA128_EC_Q[] = { + 0x04, 0x19, 0xE7, 0xBC, 0xAC, 0x44, 0x65, 0xED, 0xCD, 0xB8, 0x3F, 0x58, + 0xFB, 0x8D, 0xB1, 0x57, 0xA9, 0x44, 0x2D, 0x05, 0x15, 0xF2, 0xEF, 0x0B, + 0xFF, 0x10, 0x74, 0x9F, 0xB5, 0x62, 0x52, 0x5F, 0x66, 0x7E, 0x1F, 0xE5, + 0xDC, 0x1B, 0x45, 0x79, 0x0B, 0xCC, 0xC6, 0x53, 0x0A, 0x9D, 0x8D, 0x5D, + 0x02, 0xD9, 0xA9, 0x59, 0xDE, 0x02, 0x5A, 0xF6, 0x95, 0x2A, 0x0E, 0x8D, + 0x38, 0x4A, 0x8A, 0x49, 0xC6, 0xBC, 0xC6, 0x03, 0x38, 0x07, 0x5F, 0x55, + 0xDA, 0x7E, 0x09, 0x6E, 0xE2, 0x7F, 0x5E, 0xD0, 0x45, 0x20, 0x0F, 0x59, + 0x76, 0x10, 0xD6, 0xA0, 0x24, 0xF0, 0x2D, 0xDE, 0x36, 0xF2, 0x6C, 0x29, + 0x39 +}; + +static const unsigned char TA129_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x33 +}; + +static const unsigned char TA129_RSA_N[] = { + 0xED, 0x35, 0xA1, 0x81, 0x80, 0xF3, 0xCB, 0x4A, 0x69, 0x5B, 0xC2, 0xFB, + 0x51, 0x83, 0xAE, 0x26, 0xFD, 0xE1, 0x6E, 0xF3, 0x81, 0x12, 0x7D, 0x71, + 0x40, 0xFF, 0x87, 0x75, 0x42, 0x29, 0x21, 0xED, 0x81, 0x52, 0x2C, 0xDF, + 0x12, 0xC1, 0x19, 0x84, 0x89, 0xC1, 0xBD, 0xC5, 0x28, 0xD5, 0xD5, 0x4B, + 0x6C, 0x44, 0xD6, 0x4C, 0xDB, 0x07, 0x96, 0x4A, 0x55, 0x7A, 0xCA, 0x36, + 0x82, 0x04, 0x36, 0xA8, 0xA5, 0xFC, 0x27, 0xF6, 0x49, 0xF1, 0xD5, 0x72, + 0x9E, 0x91, 0xF9, 0x23, 0xD6, 0x70, 0x7B, 0xBB, 0xF5, 0x9B, 0xC1, 0xEC, + 0x93, 0xCF, 0x19, 0xEA, 0x65, 0x7E, 0x88, 0x70, 0xA0, 0x73, 0xFC, 0xF6, + 0xFF, 0xB5, 0x56, 0x62, 0xE1, 0x73, 0x6A, 0x34, 0x98, 0x3E, 0x82, 0xB8, + 0xAC, 0x95, 0x53, 0xF4, 0x01, 0xA0, 0x27, 0x07, 0x72, 0xA3, 0x00, 0x53, + 0xA0, 0xE4, 0xB2, 0xAB, 0x83, 0x38, 0x57, 0x33, 0x25, 0x94, 0x9F, 0xBE, + 0x48, 0x1D, 0x98, 0xE1, 0xA3, 0xBA, 0x9E, 0x5C, 0xCD, 0x04, 0x71, 0x51, + 0x7D, 0x75, 0x78, 0xAB, 0xF3, 0x59, 0xAA, 0xC4, 0xE0, 0x60, 0xBE, 0x8F, + 0x83, 0x52, 0xB8, 0x75, 0x1A, 0x41, 0x35, 0xED, 0xBC, 0xF3, 0x3A, 0x63, + 0xE9, 0xA9, 0x14, 0x45, 0xD7, 0xE6, 0x52, 0xD1, 0x6E, 0xD2, 0xDE, 0xBC, + 0xE3, 0xF5, 0x0B, 0x3B, 0xE6, 0xE0, 0xC4, 0xBD, 0x43, 0x64, 0x13, 0xA6, + 0xCE, 0xF4, 0x98, 0x37, 0x6C, 0x8A, 0x95, 0xA8, 0x97, 0xC8, 0x47, 0x0F, + 0xF0, 0x5E, 0x10, 0x8B, 0xE7, 0x1D, 0x1C, 0xFE, 0xB1, 0x3B, 0xA0, 0x05, + 0x33, 0x68, 0x05, 0x41, 0x82, 0xC1, 0x03, 0x2B, 0x01, 0xC8, 0xE7, 0x8F, + 0x4D, 0xAB, 0xE8, 0xB5, 0xF6, 0xCD, 0x6B, 0x44, 0xB5, 0xE7, 0xDD, 0x8B, + 0xEC, 0xEA, 0x25, 0xB4, 0x00, 0x22, 0x57, 0x4D, 0xB0, 0xB1, 0xB2, 0x31, + 0xC1, 0x16, 0xCE, 0xFF, 0xFD, 0x14, 0x84, 0xB7, 0x47, 0xFA, 0xB2, 0xF1, + 0x70, 0xDE, 0xDB, 0x8B, 0x6C, 0x36, 0x58, 0xA4, 0x7C, 0xB3, 0x11, 0xD1, + 0xC3, 0x77, 0x7F, 0x5F, 0xB6, 0x25, 0xE0, 0x0D, 0xC5, 0xD2, 0xB3, 0xF9, + 0xB8, 0xB8, 0x77, 0xDB, 0x37, 0x71, 0x71, 0x47, 0xE3, 0x60, 0x18, 0x4F, + 0x24, 0xB6, 0x75, 0x37, 0x78, 0xB9, 0xA3, 0x62, 0xAF, 0xBD, 0xC9, 0x72, + 0x8E, 0x2F, 0xCC, 0xBB, 0xAE, 0xDB, 0xE4, 0x15, 0x52, 0x19, 0x07, 0x33, + 0xFB, 0x6A, 0xB7, 0x2D, 0x4B, 0x90, 0x28, 0x82, 0x73, 0xFE, 0x18, 0x8B, + 0x35, 0x8D, 0xDB, 0xA7, 0x04, 0x6A, 0xBE, 0xEA, 0xC1, 0x4D, 0x36, 0x3B, + 0x16, 0x36, 0x91, 0x32, 0xEF, 0xB6, 0x40, 0x89, 0x91, 0x43, 0xE0, 0xF2, + 0xA2, 0xAB, 0x04, 0x2E, 0xE6, 0xF2, 0x4C, 0x0E, 0x16, 0x34, 0x20, 0xAC, + 0x87, 0xC1, 0x2D, 0x7E, 0xC9, 0x66, 0x47, 0x17, 0x14, 0x11, 0xA4, 0xF3, + 0xF7, 0xA1, 0x24, 0x89, 0xAB, 0xD8, 0x1A, 0xC8, 0xA1, 0x5C, 0xB1, 0xA3, + 0xF7, 0x8C, 0x6D, 0xC8, 0x01, 0xC9, 0x4F, 0xC9, 0xEC, 0xC4, 0xFC, 0xAC, + 0x51, 0x33, 0xD1, 0xC8, 0x83, 0xD1, 0xC9, 0x9F, 0x1D, 0xD4, 0x47, 0x34, + 0x29, 0x3E, 0xCB, 0xB0, 0x0E, 0xFA, 0x83, 0x0B, 0x28, 0x58, 0xE5, 0x29, + 0xDC, 0x3F, 0x7C, 0xA8, 0x9F, 0xC9, 0xB6, 0x0A, 0xBB, 0xA6, 0xE8, 0x46, + 0x16, 0x0F, 0x96, 0xE5, 0x7B, 0xE4, 0x6A, 0x7A, 0x48, 0x6D, 0x76, 0x98, + 0x05, 0xA5, 0xDC, 0x6D, 0x1E, 0x42, 0x1E, 0x42, 0xDA, 0x1A, 0xE0, 0x52, + 0xF7, 0xB5, 0x83, 0xC0, 0x1A, 0x7B, 0x78, 0x35, 0x2C, 0x38, 0xF5, 0x1F, + 0xFD, 0x49, 0xA3, 0x2E, 0xD2, 0x59, 0x63, 0xBF, 0x80, 0xB0, 0x8C, 0x93, + 0x73, 0xCB, 0x35, 0xA6, 0x99, 0x95, 0x22, 0x61, 0x65, 0x03, 0x60, 0xFB, + 0x2F, 0x93, 0x4B, 0xFA, 0x9A, 0x9C, 0x80, 0x3B +}; + +static const unsigned char TA129_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA130_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x65, 0x2D, 0x53, 0x7A, 0x69, + 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x32, 0x30, 0x30, 0x39, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x65, 0x2D, 0x73, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x2E, 0x68, + 0x75 +}; + +static const unsigned char TA130_RSA_N[] = { + 0xE9, 0xF8, 0x8F, 0xF3, 0x63, 0xAD, 0xDA, 0x86, 0xD8, 0xA7, 0xE0, 0x42, + 0xFB, 0xCF, 0x91, 0xDE, 0xA6, 0x26, 0xF8, 0x99, 0xA5, 0x63, 0x70, 0xAD, + 0x9B, 0xAE, 0xCA, 0x33, 0x40, 0x7D, 0x6D, 0x96, 0x6E, 0xA1, 0x0E, 0x44, + 0xEE, 0xE1, 0x13, 0x9D, 0x94, 0x42, 0x52, 0x9A, 0xBD, 0x75, 0x85, 0x74, + 0x2C, 0xA8, 0x0E, 0x1D, 0x93, 0xB6, 0x18, 0xB7, 0x8C, 0x2C, 0xA8, 0xCF, + 0xFB, 0x5C, 0x71, 0xB9, 0xDA, 0xEC, 0xFE, 0xE8, 0x7E, 0x8F, 0xE4, 0x2F, + 0x1D, 0xB2, 0xA8, 0x75, 0x87, 0xD8, 0xB7, 0xA1, 0xE5, 0x3B, 0xCF, 0x99, + 0x4A, 0x46, 0xD0, 0x83, 0x19, 0x7D, 0xC0, 0xA1, 0x12, 0x1C, 0x95, 0x6D, + 0x4A, 0xF4, 0xD8, 0xC7, 0xA5, 0x4D, 0x33, 0x2E, 0x85, 0x39, 0x40, 0x75, + 0x7E, 0x14, 0x7C, 0x80, 0x12, 0x98, 0x50, 0xC7, 0x41, 0x67, 0xB8, 0xA0, + 0x80, 0x61, 0x54, 0xA6, 0x6C, 0x4E, 0x1F, 0xE0, 0x9D, 0x0E, 0x07, 0xE9, + 0xC9, 0xBA, 0x33, 0xE7, 0xFE, 0xC0, 0x55, 0x28, 0x2C, 0x02, 0x80, 0xA7, + 0x19, 0xF5, 0x9E, 0xDC, 0x55, 0x53, 0x03, 0x97, 0x7B, 0x07, 0x48, 0xFF, + 0x99, 0xFB, 0x37, 0x8A, 0x24, 0xC4, 0x59, 0xCC, 0x50, 0x10, 0x63, 0x8E, + 0xAA, 0xA9, 0x1A, 0xB0, 0x84, 0x1A, 0x86, 0xF9, 0x5F, 0xBB, 0xB1, 0x50, + 0x6E, 0xA4, 0xD1, 0x0A, 0xCC, 0xD5, 0x71, 0x7E, 0x1F, 0xA7, 0x1B, 0x7C, + 0xF5, 0x53, 0x6E, 0x22, 0x5F, 0xCB, 0x2B, 0xE6, 0xD4, 0x7C, 0x5D, 0xAE, + 0xD6, 0xC2, 0xC6, 0x4C, 0xE5, 0x05, 0x01, 0xD9, 0xED, 0x57, 0xFC, 0xC1, + 0x23, 0x79, 0xFC, 0xFA, 0xC8, 0x24, 0x83, 0x95, 0xF3, 0xB5, 0x6A, 0x51, + 0x01, 0xD0, 0x77, 0xD6, 0xE9, 0x12, 0xA1, 0xF9, 0x1A, 0x83, 0xFB, 0x82, + 0x1B, 0xB9, 0xB0, 0x97, 0xF4, 0x76, 0x06, 0x33, 0x43, 0x49, 0xA0, 0xFF, + 0x0B, 0xB5, 0xFA, 0xB5 +}; + +static const unsigned char TA130_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA131_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, + 0x6E, 0x63, 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA131_RSA_N[] = { + 0xC6, 0xCC, 0xE5, 0x73, 0xE6, 0xFB, 0xD4, 0xBB, 0xE5, 0x2D, 0x2D, 0x32, + 0xA6, 0xDF, 0xE5, 0x81, 0x3F, 0xC9, 0xCD, 0x25, 0x49, 0xB6, 0x71, 0x2A, + 0xC3, 0xD5, 0x94, 0x34, 0x67, 0xA2, 0x0A, 0x1C, 0xB0, 0x5F, 0x69, 0xA6, + 0x40, 0xB1, 0xC4, 0xB7, 0xB2, 0x8F, 0xD0, 0x98, 0xA4, 0xA9, 0x41, 0x59, + 0x3A, 0xD3, 0xDC, 0x94, 0xD6, 0x3C, 0xDB, 0x74, 0x38, 0xA4, 0x4A, 0xCC, + 0x4D, 0x25, 0x82, 0xF7, 0x4A, 0xA5, 0x53, 0x12, 0x38, 0xEE, 0xF3, 0x49, + 0x6D, 0x71, 0x91, 0x7E, 0x63, 0xB6, 0xAB, 0xA6, 0x5F, 0xC3, 0xA4, 0x84, + 0xF8, 0x4F, 0x62, 0x51, 0xBE, 0xF8, 0xC5, 0xEC, 0xDB, 0x38, 0x92, 0xE3, + 0x06, 0xE5, 0x08, 0x91, 0x0C, 0xC4, 0x28, 0x41, 0x55, 0xFB, 0xCB, 0x5A, + 0x89, 0x15, 0x7E, 0x71, 0xE8, 0x35, 0xBF, 0x4D, 0x72, 0x09, 0x3D, 0xBE, + 0x3A, 0x38, 0x50, 0x5B, 0x77, 0x31, 0x1B, 0x8D, 0xB3, 0xC7, 0x24, 0x45, + 0x9A, 0xA7, 0xAC, 0x6D, 0x00, 0x14, 0x5A, 0x04, 0xB7, 0xBA, 0x13, 0xEB, + 0x51, 0x0A, 0x98, 0x41, 0x41, 0x22, 0x4E, 0x65, 0x61, 0x87, 0x81, 0x41, + 0x50, 0xA6, 0x79, 0x5C, 0x89, 0xDE, 0x19, 0x4A, 0x57, 0xD5, 0x2E, 0xE6, + 0x5D, 0x1C, 0x53, 0x2C, 0x7E, 0x98, 0xCD, 0x1A, 0x06, 0x16, 0xA4, 0x68, + 0x73, 0xD0, 0x34, 0x04, 0x13, 0x5C, 0xA1, 0x71, 0xD3, 0x5A, 0x7C, 0x55, + 0xDB, 0x5E, 0x64, 0xE1, 0x37, 0x87, 0x30, 0x56, 0x04, 0xE5, 0x11, 0xB4, + 0x29, 0x80, 0x12, 0xF1, 0x79, 0x39, 0x88, 0xA2, 0x02, 0x11, 0x7C, 0x27, + 0x66, 0xB7, 0x88, 0xB7, 0x78, 0xF2, 0xCA, 0x0A, 0xA8, 0x38, 0xAB, 0x0A, + 0x64, 0xC2, 0xBF, 0x66, 0x5D, 0x95, 0x84, 0xC1, 0xA1, 0x25, 0x1E, 0x87, + 0x5D, 0x1A, 0x50, 0x0B, 0x20, 0x12, 0xCC, 0x41, 0xBB, 0x6E, 0x0B, 0x51, + 0x38, 0xB8, 0x4B, 0xCB +}; + +static const unsigned char TA131_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA132_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA132_EC_Q[] = { + 0x04, 0x78, 0x30, 0x81, 0xE8, 0x63, 0x1E, 0xE5, 0xEB, 0x71, 0x51, 0x0F, + 0xF7, 0x07, 0x07, 0xCA, 0x39, 0x99, 0x7C, 0x4E, 0xD5, 0x0F, 0xCC, 0x30, + 0x30, 0x0B, 0x8F, 0x66, 0x93, 0x3E, 0xCF, 0xBD, 0xC5, 0x86, 0xBD, 0xF9, + 0xB1, 0xB7, 0xB4, 0x3E, 0xB4, 0x07, 0xC8, 0xF3, 0x96, 0x31, 0xF3, 0xED, + 0xA4, 0x4F, 0xF8, 0xA3, 0x4E, 0x8D, 0x29, 0x15, 0x58, 0xB8, 0xD5, 0x6F, + 0x7F, 0xEE, 0x6C, 0x22, 0xB5, 0xB0, 0xAF, 0x48, 0x45, 0x0A, 0xBD, 0xA8, + 0x49, 0x94, 0xBF, 0x84, 0x43, 0xB0, 0xDB, 0x84, 0x4A, 0x03, 0x23, 0x19, + 0x67, 0x6A, 0x6F, 0xC1, 0x6E, 0xBC, 0x06, 0x39, 0x37, 0xD1, 0x88, 0x22, + 0xF7 +}; + +static const unsigned char TA133_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA133_RSA_N[] = { + 0xD7, 0xC7, 0x5E, 0xF7, 0xC1, 0x07, 0xD4, 0x77, 0xFB, 0x43, 0x21, 0xF4, + 0xF4, 0xF5, 0x69, 0xE4, 0xEE, 0x32, 0x01, 0xDB, 0xA3, 0x86, 0x1F, 0xE4, + 0x59, 0x0D, 0xBA, 0xE7, 0x75, 0x83, 0x52, 0xEB, 0xEA, 0x1C, 0x61, 0x15, + 0x48, 0xBB, 0x1D, 0x07, 0xCA, 0x8C, 0xAE, 0xB0, 0xDC, 0x96, 0x9D, 0xEA, + 0xC3, 0x60, 0x92, 0x86, 0x82, 0x28, 0x73, 0x9C, 0x56, 0x06, 0xFF, 0x4B, + 0x64, 0xF0, 0x0C, 0x2A, 0x37, 0x49, 0xB5, 0xE5, 0xCF, 0x0C, 0x7C, 0xEE, + 0xF1, 0x4A, 0xBB, 0x73, 0x30, 0x65, 0xF3, 0xD5, 0x2F, 0x83, 0xB6, 0x7E, + 0xE3, 0xE7, 0xF5, 0x9E, 0xAB, 0x60, 0xF9, 0xD3, 0xF1, 0x9D, 0x92, 0x74, + 0x8A, 0xE4, 0x1C, 0x96, 0xAC, 0x5B, 0x80, 0xE9, 0xB5, 0xF4, 0x31, 0x87, + 0xA3, 0x51, 0xFC, 0xC7, 0x7E, 0xA1, 0x6F, 0x8E, 0x53, 0x77, 0xD4, 0x97, + 0xC1, 0x55, 0x33, 0x92, 0x3E, 0x18, 0x2F, 0x75, 0xD4, 0xAD, 0x86, 0x49, + 0xCB, 0x95, 0xAF, 0x54, 0x06, 0x6C, 0xD8, 0x06, 0x13, 0x8D, 0x5B, 0xFF, + 0xE1, 0x26, 0x19, 0x59, 0xC0, 0x24, 0xBA, 0x81, 0x71, 0x79, 0x90, 0x44, + 0x50, 0x68, 0x24, 0x94, 0x5F, 0xB8, 0xB3, 0x11, 0xF1, 0x29, 0x41, 0x61, + 0xA3, 0x41, 0xCB, 0x23, 0x36, 0xD5, 0xC1, 0xF1, 0x32, 0x50, 0x10, 0x4E, + 0x7F, 0xF4, 0x86, 0x93, 0xEC, 0x84, 0xD3, 0x8E, 0xBC, 0x4B, 0xBF, 0x5C, + 0x01, 0x4E, 0x07, 0x3D, 0xDC, 0x14, 0x8A, 0x94, 0x0A, 0xA4, 0xEA, 0x73, + 0xFB, 0x0B, 0x51, 0xE8, 0x13, 0x07, 0x18, 0xFA, 0x0E, 0xF1, 0x2B, 0xD1, + 0x54, 0x15, 0x7D, 0x3C, 0xE1, 0xF7, 0xB4, 0x19, 0x42, 0x67, 0x62, 0x5E, + 0x77, 0xE0, 0xA2, 0x55, 0xEC, 0xB6, 0xD9, 0x69, 0x17, 0xD5, 0x3A, 0xAF, + 0x44, 0xED, 0x4A, 0xC5, 0x9E, 0xE4, 0x7A, 0x27, 0x7C, 0xE5, 0x75, 0xD7, + 0xAA, 0xCB, 0x25, 0xE7, 0xDF, 0x6B, 0x0A, 0xDB, 0x0F, 0x4D, 0x93, 0x4E, + 0xA8, 0xA0, 0xCD, 0x7B, 0x2E, 0xF2, 0x59, 0x01, 0x6A, 0xB7, 0x0D, 0xB8, + 0x07, 0x81, 0x7E, 0x8B, 0x38, 0x1B, 0x38, 0xE6, 0x0A, 0x57, 0x99, 0x3D, + 0xEE, 0x21, 0xE8, 0xA3, 0xF5, 0x0C, 0x16, 0xDD, 0x8B, 0xEC, 0x34, 0x8E, + 0x9C, 0x2A, 0x1C, 0x00, 0x15, 0x17, 0x8D, 0x68, 0x83, 0xD2, 0x70, 0x9F, + 0x18, 0x08, 0xCD, 0x11, 0x68, 0xD5, 0xC9, 0x6B, 0x52, 0xCD, 0xC4, 0x46, + 0x8F, 0xDC, 0xB5, 0xF3, 0xD8, 0x57, 0x73, 0x1E, 0xE9, 0x94, 0x39, 0x04, + 0xBF, 0xD3, 0xDE, 0x38, 0xDE, 0xB4, 0x53, 0xEC, 0x69, 0x1C, 0xA2, 0x7E, + 0xC4, 0x8F, 0xE4, 0x1B, 0x70, 0xAD, 0xF2, 0xA2, 0xF9, 0xFB, 0xF7, 0x16, + 0x64, 0x66, 0x69, 0x9F, 0x49, 0x51, 0xA2, 0xE2, 0x15, 0x18, 0x67, 0x06, + 0x4A, 0x7F, 0xD5, 0x6C, 0xB5, 0x4D, 0xB3, 0x33, 0xE0, 0x61, 0xEB, 0x5D, + 0xBE, 0xE9, 0x98, 0x0F, 0x32, 0xD7, 0x1D, 0x4B, 0x3C, 0x2E, 0x5A, 0x01, + 0x52, 0x91, 0x09, 0xF2, 0xDF, 0xEA, 0x8D, 0xD8, 0x06, 0x40, 0x63, 0xAA, + 0x11, 0xE4, 0xFE, 0xC3, 0x37, 0x9E, 0x14, 0x52, 0x3F, 0xF4, 0xE2, 0xCC, + 0xF2, 0x61, 0x93, 0xD1, 0xFD, 0x67, 0x6B, 0xD7, 0x52, 0xAE, 0xBF, 0x68, + 0xAB, 0x40, 0x43, 0xA0, 0x57, 0x35, 0x53, 0x78, 0xF0, 0x53, 0xF8, 0x61, + 0x42, 0x07, 0x64, 0xC6, 0xD7, 0x6F, 0x9B, 0x4C, 0x38, 0x0D, 0x63, 0xAC, + 0x62, 0xAF, 0x36, 0x8B, 0xA2, 0x73, 0x0A, 0x0D, 0xF5, 0x21, 0xBD, 0x74, + 0xAA, 0x4D, 0xEA, 0x72, 0x03, 0x49, 0xDB, 0xC7, 0x5F, 0x1D, 0x62, 0x63, + 0xC7, 0xFD, 0xDD, 0x91, 0xEC, 0x33, 0xEE, 0xF5, 0x6D, 0xB4, 0x6E, 0x30, + 0x68, 0xDE, 0xC8, 0xD6, 0x26, 0xB0, 0x75, 0x5E, 0x7B, 0xB4, 0x07, 0x20, + 0x98, 0xA1, 0x76, 0x32, 0xB8, 0x4D, 0x6C, 0x4F +}; + +static const unsigned char TA133_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA134_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA134_RSA_N[] = { + 0xB0, 0x48, 0x65, 0xA3, 0x0D, 0x1D, 0x42, 0xE3, 0x91, 0x6D, 0x9D, 0x84, + 0xA4, 0x61, 0x96, 0x12, 0xC2, 0xED, 0xC3, 0xDA, 0x23, 0x34, 0x19, 0x76, + 0xF6, 0xEA, 0xFD, 0x55, 0x5A, 0xF6, 0x55, 0x01, 0x53, 0x0F, 0xF2, 0xCC, + 0x8C, 0x97, 0x4F, 0xB9, 0x50, 0xCB, 0xB3, 0x01, 0x44, 0x56, 0x96, 0xFD, + 0x9B, 0x28, 0xEC, 0x7B, 0x74, 0x0B, 0xE7, 0x42, 0x6B, 0x55, 0xCE, 0xC9, + 0x61, 0xB2, 0xE8, 0xAD, 0x40, 0x3C, 0xBA, 0xB9, 0x41, 0x0A, 0x05, 0x4F, + 0x1B, 0x26, 0x85, 0x8F, 0x43, 0xB5, 0x40, 0xB5, 0x85, 0xD1, 0xD4, 0x71, + 0xDC, 0x83, 0x41, 0xF3, 0xF6, 0x45, 0xC7, 0x80, 0xA2, 0x84, 0x50, 0x97, + 0x46, 0xCE, 0xA0, 0x0C, 0xC4, 0x60, 0x56, 0x04, 0x1D, 0x07, 0x5B, 0x46, + 0xA5, 0x0E, 0xB2, 0x4B, 0xA4, 0x0E, 0xA5, 0x7C, 0xEE, 0xF8, 0xD4, 0x62, + 0x03, 0xB9, 0x93, 0x6A, 0x8A, 0x14, 0xB8, 0x70, 0xF8, 0x2E, 0x82, 0x46, + 0x38, 0x23, 0x0E, 0x74, 0xC7, 0x6B, 0x41, 0xB7, 0xD0, 0x29, 0xA3, 0x9D, + 0x80, 0xB0, 0x7E, 0x77, 0x93, 0x63, 0x42, 0xFB, 0x34, 0x83, 0x3B, 0x73, + 0xA3, 0x5A, 0x21, 0x36, 0xEB, 0x47, 0xFA, 0x18, 0x17, 0xD9, 0xBA, 0x66, + 0xC2, 0x93, 0xA4, 0x8F, 0xFC, 0x5D, 0xA4, 0xAD, 0xFC, 0x50, 0x6A, 0x95, + 0xAC, 0xBC, 0x24, 0x33, 0xD1, 0xBD, 0x88, 0x7F, 0x86, 0xF5, 0xF5, 0xB2, + 0x73, 0x2A, 0x8F, 0x7C, 0xAF, 0x08, 0xF2, 0x1A, 0x98, 0x3F, 0xA9, 0x81, + 0x65, 0x3F, 0xC1, 0x8C, 0x89, 0xC5, 0x96, 0x30, 0x9A, 0x0A, 0xCF, 0xF4, + 0xD4, 0xC8, 0x34, 0xED, 0x9D, 0x2F, 0xBC, 0x8D, 0x38, 0x86, 0x53, 0xEE, + 0x97, 0x9F, 0xA9, 0xB2, 0x63, 0x94, 0x17, 0x8D, 0x0F, 0xDC, 0x66, 0x2A, + 0x7C, 0x52, 0x51, 0x75, 0xCB, 0x99, 0x8E, 0xE8, 0x3D, 0x5C, 0xBF, 0x9E, + 0x3B, 0x28, 0x8D, 0x83, 0x02, 0x0F, 0xA9, 0x9F, 0x72, 0xE2, 0x2C, 0x2B, + 0xB3, 0xDC, 0x66, 0x97, 0x00, 0x40, 0xD0, 0xA4, 0x54, 0x8E, 0x9B, 0x5D, + 0x7B, 0x45, 0x36, 0x26, 0xD6, 0x72, 0x43, 0xEB, 0xCF, 0xC0, 0xEA, 0x0D, + 0xDC, 0xCE, 0x12, 0xE6, 0x7D, 0x38, 0x9F, 0x05, 0x27, 0xA8, 0x97, 0x3E, + 0xE9, 0x51, 0xC6, 0x6C, 0x05, 0x28, 0xC1, 0x02, 0x0F, 0xE9, 0x18, 0x6D, + 0xEC, 0xBD, 0x9C, 0x06, 0xD4, 0xA7, 0x49, 0xF4, 0x54, 0x05, 0x6B, 0x6C, + 0x30, 0xF1, 0xEB, 0x03, 0xD5, 0xEA, 0x3D, 0x6A, 0x76, 0xC2, 0xCB, 0x1A, + 0x28, 0x49, 0x4D, 0x7F, 0x64, 0xE0, 0xFA, 0x2B, 0xDA, 0x73, 0x83, 0x81, + 0xFF, 0x91, 0x03, 0xBD, 0x94, 0xBB, 0xE4, 0xB8, 0x8E, 0x9C, 0x32, 0x63, + 0xCD, 0x9F, 0xBB, 0x68, 0x81, 0xB1, 0x84, 0x5B, 0xAF, 0x36, 0xBF, 0x77, + 0xEE, 0x1D, 0x7F, 0xF7, 0x49, 0x9B, 0x52, 0xEC, 0xD2, 0x77, 0x5A, 0x7D, + 0x91, 0x9D, 0x4D, 0xC2, 0x39, 0x2D, 0xE4, 0xBA, 0x82, 0xF8, 0x6F, 0xF2, + 0x4E, 0x1E, 0x0F, 0x4E, 0xE6, 0x3F, 0x59, 0xA5, 0x23, 0xDC, 0x3D, 0x87, + 0xA8, 0x28, 0x58, 0x28, 0xD1, 0xF1, 0x1B, 0x36, 0xDB, 0x4F, 0xC4, 0xFF, + 0xE1, 0x8C, 0x5B, 0x72, 0x8C, 0xC7, 0x26, 0x03, 0x27, 0xA3, 0x39, 0x0A, + 0x01, 0xAA, 0xC0, 0xB2, 0x31, 0x60, 0x83, 0x22, 0xA1, 0x4F, 0x12, 0x09, + 0x01, 0x11, 0xAF, 0x34, 0xD4, 0xCF, 0xD7, 0xAE, 0x62, 0xD3, 0x05, 0x07, + 0xB4, 0x31, 0x75, 0xE0, 0x0D, 0x6D, 0x57, 0x4F, 0x69, 0x87, 0xF9, 0x57, + 0xA9, 0xBA, 0x15, 0xF6, 0xC8, 0x52, 0x6D, 0xA1, 0xCB, 0x9C, 0x1F, 0xE5, + 0xFC, 0x78, 0xA8, 0x35, 0x9A, 0x9F, 0x41, 0x14, 0xCE, 0xA5, 0xB4, 0xCE, + 0x94, 0x08, 0x1C, 0x09, 0xAD, 0x56, 0xE5, 0xDA, 0xB6, 0x49, 0x9A, 0x4A, + 0xEA, 0x63, 0x18, 0x53, 0x9C, 0x2C, 0x2E, 0xC3 +}; + +static const unsigned char TA134_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA135_DN[] = { + 0x30, 0x71, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, 0x63, + 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0E, 0x56, 0x41, 0x54, + 0x48, 0x55, 0x2D, 0x32, 0x33, 0x35, 0x38, 0x34, 0x34, 0x39, 0x37, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x15, 0x65, 0x2D, + 0x53, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA135_EC_Q[] = { + 0x04, 0x96, 0xDC, 0x3D, 0x8A, 0xD8, 0xB0, 0x7B, 0x6F, 0xC6, 0x27, 0xBE, + 0x44, 0x90, 0xB1, 0xB3, 0x56, 0x15, 0x7B, 0x8E, 0x43, 0x24, 0x7D, 0x1A, + 0x84, 0x59, 0xEE, 0x63, 0x68, 0xB2, 0xC6, 0x5E, 0x87, 0xD0, 0x15, 0x48, + 0x1E, 0xA8, 0x90, 0xAD, 0xBD, 0x53, 0xA2, 0xDA, 0xDE, 0x3A, 0x90, 0xA6, + 0x60, 0x5F, 0x68, 0x32, 0xB5, 0x86, 0x41, 0xDF, 0x87, 0x5B, 0x2C, 0x7B, + 0xC5, 0xFE, 0x7C, 0x7A, 0xDA +}; + +static const unsigned char TA136_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x45, 0x31 +}; + +static const unsigned char TA136_EC_Q[] = { + 0x04, 0xDE, 0x6F, 0xF8, 0x7F, 0x1C, 0xDF, 0xED, 0xF9, 0x47, 0x87, 0x86, + 0xB1, 0xA4, 0xC0, 0x8A, 0xF8, 0x82, 0x97, 0x80, 0xEA, 0x8F, 0xC8, 0x4A, + 0x5E, 0x2A, 0x7D, 0x88, 0x68, 0xA7, 0x01, 0x62, 0x14, 0x91, 0x24, 0x7A, + 0x5C, 0x9E, 0xA3, 0x17, 0x7D, 0x8A, 0x86, 0x21, 0x34, 0x18, 0x50, 0x1B, + 0x10, 0xDE, 0xD0, 0x37, 0x4B, 0x26, 0xC7, 0x19, 0x60, 0x80, 0xE9, 0x34, + 0xBD, 0x60, 0x19, 0x36, 0x40, 0xD6, 0x29, 0x87, 0x09, 0x3C, 0x91, 0x7A, + 0xF6, 0xBC, 0x13, 0x23, 0xDD, 0x59, 0x4E, 0x04, 0x5E, 0xCF, 0xC8, 0x02, + 0x1C, 0x18, 0x53, 0xC1, 0x31, 0xD8, 0xDA, 0x20, 0xE9, 0x44, 0x8D, 0xE4, + 0x76 +}; + +static const unsigned char TA137_DN[] = { + 0x30, 0x81, 0x8F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, + 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA137_RSA_N[] = { + 0xBD, 0xED, 0xC1, 0x03, 0xFC, 0xF6, 0x8F, 0xFC, 0x02, 0xB1, 0x6F, 0x5B, + 0x9F, 0x48, 0xD9, 0x9D, 0x79, 0xE2, 0xA2, 0xB7, 0x03, 0x61, 0x56, 0x18, + 0xC3, 0x47, 0xB6, 0xD7, 0xCA, 0x3D, 0x35, 0x2E, 0x89, 0x43, 0xF7, 0xA1, + 0x69, 0x9B, 0xDE, 0x8A, 0x1A, 0xFD, 0x13, 0x20, 0x9C, 0xB4, 0x49, 0x77, + 0x32, 0x29, 0x56, 0xFD, 0xB9, 0xEC, 0x8C, 0xDD, 0x22, 0xFA, 0x72, 0xDC, + 0x27, 0x61, 0x97, 0xEE, 0xF6, 0x5A, 0x84, 0xEC, 0x6E, 0x19, 0xB9, 0x89, + 0x2C, 0xDC, 0x84, 0x5B, 0xD5, 0x74, 0xFB, 0x6B, 0x5F, 0xC5, 0x89, 0xA5, + 0x10, 0x52, 0x89, 0x46, 0x55, 0xF4, 0xB8, 0x75, 0x1C, 0xE6, 0x7F, 0xE4, + 0x54, 0xAE, 0x4B, 0xF8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xF8, 0x17, 0x71, + 0x59, 0xEB, 0x1E, 0x28, 0x07, 0x74, 0xC5, 0x9D, 0x48, 0xBE, 0x6C, 0xB4, + 0xF4, 0xA4, 0xB0, 0xF3, 0x64, 0x37, 0x79, 0x92, 0xC0, 0xEC, 0x46, 0x5E, + 0x7F, 0xE1, 0x6D, 0x53, 0x4C, 0x62, 0xAF, 0xCD, 0x1F, 0x0B, 0x63, 0xBB, + 0x3A, 0x9D, 0xFB, 0xFC, 0x79, 0x00, 0x98, 0x61, 0x74, 0xCF, 0x26, 0x82, + 0x40, 0x63, 0xF3, 0xB2, 0x72, 0x6A, 0x19, 0x0D, 0x99, 0xCA, 0xD4, 0x0E, + 0x75, 0xCC, 0x37, 0xFB, 0x8B, 0x89, 0xC1, 0x59, 0xF1, 0x62, 0x7F, 0x5F, + 0xB3, 0x5F, 0x65, 0x30, 0xF8, 0xA7, 0xB7, 0x4D, 0x76, 0x5A, 0x1E, 0x76, + 0x5E, 0x34, 0xC0, 0xE8, 0x96, 0x56, 0x99, 0x8A, 0xB3, 0xF0, 0x7F, 0xA4, + 0xCD, 0xBD, 0xDC, 0x32, 0x31, 0x7C, 0x91, 0xCF, 0xE0, 0x5F, 0x11, 0xF8, + 0x6B, 0xAA, 0x49, 0x5C, 0xD1, 0x99, 0x94, 0xD1, 0xA2, 0xE3, 0x63, 0x5B, + 0x09, 0x76, 0xB5, 0x56, 0x62, 0xE1, 0x4B, 0x74, 0x1D, 0x96, 0xD4, 0x26, + 0xD4, 0x08, 0x04, 0x59, 0xD0, 0x98, 0x0E, 0x0E, 0xE6, 0xDE, 0xFC, 0xC3, + 0xEC, 0x1F, 0x90, 0xF1 +}; + +static const unsigned char TA137_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA138_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, 0x67 +}; + +static const unsigned char TA138_RSA_N[] = { + 0xB4, 0x84, 0xCC, 0x33, 0x17, 0x2E, 0x6B, 0x94, 0x6C, 0x6B, 0x61, 0x52, + 0xA0, 0xEB, 0xA3, 0xCF, 0x79, 0x94, 0x4C, 0xE5, 0x94, 0x80, 0x99, 0xCB, + 0x55, 0x64, 0x44, 0x65, 0x8F, 0x67, 0x64, 0xE2, 0x06, 0xE3, 0x5C, 0x37, + 0x49, 0xF6, 0x2F, 0x9B, 0x84, 0x84, 0x1E, 0x2D, 0xF2, 0x60, 0x9D, 0x30, + 0x4E, 0xCC, 0x84, 0x85, 0xE2, 0x2C, 0xCF, 0x1E, 0x9E, 0xFE, 0x36, 0xAB, + 0x33, 0x77, 0x35, 0x44, 0xD8, 0x35, 0x96, 0x1A, 0x3D, 0x36, 0xE8, 0x7A, + 0x0E, 0xD8, 0xD5, 0x47, 0xA1, 0x6A, 0x69, 0x8B, 0xD9, 0xFC, 0xBB, 0x3A, + 0xAE, 0x79, 0x5A, 0xD5, 0xF4, 0xD6, 0x71, 0xBB, 0x9A, 0x90, 0x23, 0x6B, + 0x9A, 0xB7, 0x88, 0x74, 0x87, 0x0C, 0x1E, 0x5F, 0xB9, 0x9E, 0x2D, 0xFA, + 0xAB, 0x53, 0x2B, 0xDC, 0xBB, 0x76, 0x3E, 0x93, 0x4C, 0x08, 0x08, 0x8C, + 0x1E, 0xA2, 0x23, 0x1C, 0xD4, 0x6A, 0xAD, 0x22, 0xBA, 0x99, 0x01, 0x2E, + 0x6D, 0x65, 0xCB, 0xBE, 0x24, 0x66, 0x55, 0x24, 0x4B, 0x40, 0x44, 0xB1, + 0x1B, 0xD7, 0xE1, 0xC2, 0x85, 0xC0, 0xDE, 0x10, 0x3F, 0x3D, 0xED, 0xB8, + 0xFC, 0xF1, 0xF1, 0x23, 0x53, 0xDC, 0xBF, 0x65, 0x97, 0x6F, 0xD9, 0xF9, + 0x40, 0x71, 0x8D, 0x7D, 0xBD, 0x95, 0xD4, 0xCE, 0xBE, 0xA0, 0x5E, 0x27, + 0x23, 0xDE, 0xFD, 0xA6, 0xD0, 0x26, 0x0E, 0x00, 0x29, 0xEB, 0x3C, 0x46, + 0xF0, 0x3D, 0x60, 0xBF, 0x3F, 0x50, 0xD2, 0xDC, 0x26, 0x41, 0x51, 0x9E, + 0x14, 0x37, 0x42, 0x04, 0xA3, 0x70, 0x57, 0xA8, 0x1B, 0x87, 0xED, 0x2D, + 0xFA, 0x7B, 0xEE, 0x8C, 0x0A, 0xE3, 0xA9, 0x66, 0x89, 0x19, 0xCB, 0x41, + 0xF9, 0xDD, 0x44, 0x36, 0x61, 0xCF, 0xE2, 0x77, 0x46, 0xC8, 0x7D, 0xF6, + 0xF4, 0x92, 0x81, 0x36, 0xFD, 0xDB, 0x34, 0xF1, 0x72, 0x7E, 0xF3, 0x0C, + 0x16, 0xBD, 0xB4, 0x15 +}; + +static const unsigned char TA138_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA139_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA139_EC_Q[] = { + 0x04, 0x45, 0x29, 0x35, 0x73, 0xFA, 0xC2, 0xB8, 0x23, 0xCE, 0x14, 0x7D, + 0xA8, 0xB1, 0x4D, 0xA0, 0x5B, 0x36, 0xEE, 0x2A, 0x2C, 0x53, 0xC3, 0x60, + 0x09, 0x35, 0xB2, 0x24, 0x66, 0x26, 0x69, 0xC0, 0xB3, 0x95, 0xD6, 0x5D, + 0x92, 0x40, 0x19, 0x0E, 0xC6, 0xA5, 0x13, 0x70, 0xF4, 0xEF, 0x12, 0x51, + 0x28, 0x5D, 0xE7, 0xCC, 0xBD, 0xF9, 0x3C, 0x85, 0xC1, 0xCF, 0x94, 0x90, + 0xC9, 0x2B, 0xCE, 0x92, 0x42, 0x58, 0x59, 0x67, 0xFD, 0x94, 0x27, 0x10, + 0x64, 0x8C, 0x4F, 0x04, 0xB1, 0x4D, 0x49, 0xE4, 0x7B, 0x4F, 0x9B, 0xF5, + 0xE7, 0x08, 0xF8, 0x03, 0x88, 0xF7, 0xA7, 0xC3, 0x92, 0x4B, 0x19, 0x54, + 0x81 +}; + +static const unsigned char TA140_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x43, 0x33 +}; + +static const unsigned char TA140_EC_Q[] = { + 0x04, 0xFD, 0xA5, 0x61, 0xAE, 0x7B, 0x26, 0x10, 0x1D, 0xE9, 0xB7, 0x22, + 0x30, 0xAE, 0x06, 0xF4, 0x81, 0xB3, 0xB1, 0x42, 0x71, 0x95, 0x39, 0xBC, + 0xD3, 0x52, 0xE3, 0xAF, 0xAF, 0xF9, 0xF2, 0x97, 0x35, 0x92, 0x36, 0x46, + 0x0E, 0x87, 0x95, 0x8D, 0xB9, 0x39, 0x5A, 0xE9, 0xBB, 0xDF, 0xD0, 0xFE, + 0xC8, 0x07, 0x41, 0x3C, 0xBB, 0x55, 0x6F, 0x83, 0xA3, 0x6A, 0xFB, 0x62, + 0xB0, 0x81, 0x89, 0x02, 0x70, 0x7D, 0x48, 0xC5, 0x4A, 0xE3, 0xE9, 0x22, + 0x54, 0x22, 0x4D, 0x93, 0xBB, 0x42, 0x0C, 0xAF, 0x77, 0x9C, 0x23, 0xA6, + 0x7D, 0xD7, 0x61, 0x11, 0xCE, 0x65, 0xC7, 0xF8, 0x7F, 0xFE, 0xF5, 0xF2, + 0xA9 +}; + +static const unsigned char TA141_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x34 +}; + +static const unsigned char TA141_RSA_N[] = { + 0xC5, 0xD2, 0x7A, 0xA1, 0xD6, 0x8A, 0xBF, 0x16, 0x31, 0xD0, 0x98, 0xD1, + 0x3A, 0x94, 0xFC, 0x5A, 0xB8, 0x6E, 0x22, 0xC1, 0x62, 0xF7, 0xA7, 0x0A, + 0x27, 0xEF, 0x50, 0xF6, 0x2E, 0xB1, 0x9E, 0x68, 0x12, 0xF0, 0x6C, 0x24, + 0x63, 0x39, 0xF1, 0xF0, 0xDF, 0x10, 0xC6, 0xDE, 0xB7, 0x52, 0x20, 0xD5, + 0x52, 0x5B, 0x42, 0x99, 0x9E, 0xF3, 0xA0, 0xBE, 0x52, 0x1F, 0x5F, 0xCC, + 0x67, 0x6D, 0xA7, 0x2E, 0x50, 0xA2, 0xC1, 0x97, 0x8D, 0xB6, 0xF8, 0x95, + 0xF5, 0xB0, 0xBA, 0xDC, 0x9D, 0xE0, 0xBE, 0xCB, 0xDF, 0xF7, 0x38, 0xF2, + 0x47, 0xF5, 0xA6, 0x9A, 0x92, 0x95, 0x2A, 0x62, 0x59, 0x50, 0x0B, 0xA2, + 0xB1, 0x35, 0xE7, 0x65, 0xB2, 0x61, 0xB2, 0xEA, 0x92, 0x71, 0x69, 0xE4, + 0x29, 0xF0, 0x4F, 0x81, 0x81, 0x04, 0x3C, 0xB2, 0xA5, 0x5B, 0xD4, 0xC5, + 0xA8, 0x59, 0x67, 0x7B, 0x55, 0x1C, 0x49, 0xAB, 0x7A, 0x9D, 0xC2, 0xE7, + 0x73, 0x4D, 0xEF, 0xCD, 0x09, 0xC2, 0xC4, 0x57, 0x12, 0xDB, 0x01, 0x0E, + 0x23, 0x79, 0x09, 0x07, 0x3B, 0xA2, 0xE8, 0xFC, 0x8A, 0xCF, 0x8F, 0xC0, + 0x46, 0x24, 0x9C, 0x38, 0x27, 0xE0, 0x83, 0x9D, 0x1B, 0xA0, 0xBF, 0x78, + 0x15, 0x10, 0xEB, 0x86, 0x4E, 0x0A, 0x5A, 0xFD, 0xDF, 0xDA, 0x2C, 0x82, + 0x7E, 0xEE, 0xCA, 0xF6, 0x29, 0xE1, 0xFA, 0x71, 0xA1, 0xF7, 0x88, 0x68, + 0x9C, 0x9C, 0xF0, 0x8D, 0xBE, 0x0F, 0x49, 0x91, 0xD8, 0xEA, 0x3A, 0xF9, + 0xFD, 0xD0, 0x68, 0x71, 0xDB, 0xE9, 0xB5, 0x2B, 0x4E, 0x82, 0x92, 0x6F, + 0x66, 0x1F, 0xE0, 0xF0, 0xDC, 0x4C, 0xEC, 0xCA, 0xD1, 0xEA, 0xBA, 0x74, + 0x06, 0xF9, 0xB3, 0x84, 0x90, 0x94, 0xD1, 0x5F, 0x8E, 0x73, 0x19, 0x10, + 0x5D, 0x02, 0xE5, 0x70, 0xA5, 0xC0, 0x10, 0xD0, 0x10, 0x7C, 0x6F, 0xC5, + 0x58, 0x49, 0xB4, 0xB0, 0x6E, 0x9A, 0xDA, 0x7D, 0x95, 0xF5, 0xCC, 0xDA, + 0x02, 0xAF, 0xB8, 0x2C, 0x7D, 0x79, 0x8F, 0xBE, 0x43, 0xF1, 0xF9, 0x28, + 0x28, 0x8D, 0x09, 0x43, 0xF8, 0x08, 0xDD, 0x6B, 0xC8, 0x8B, 0x2C, 0x24, + 0xB1, 0x8D, 0x52, 0x07, 0xBD, 0x78, 0x9B, 0xCB, 0xCA, 0x68, 0xB2, 0xA4, + 0xDD, 0x0C, 0x4C, 0x79, 0x60, 0xC6, 0x99, 0xD1, 0x93, 0xF1, 0x30, 0x1A, + 0x07, 0xD3, 0xAE, 0x22, 0xC2, 0xEA, 0xCE, 0xF1, 0x84, 0x09, 0xCC, 0xE0, + 0x14, 0x6E, 0x7F, 0x3F, 0x7E, 0xD2, 0x82, 0x85, 0xAC, 0xDC, 0xA9, 0x16, + 0x4E, 0x85, 0xA0, 0x60, 0xCB, 0xF6, 0x9C, 0xD7, 0xC8, 0xB3, 0x8E, 0xED, + 0xC6, 0x9B, 0x98, 0x75, 0x0D, 0x55, 0xE8, 0x5F, 0xE5, 0x95, 0x8B, 0x02, + 0xA4, 0xAE, 0x43, 0x29, 0x28, 0x11, 0xA4, 0xE6, 0x12, 0x30, 0x01, 0x4B, + 0x75, 0x6B, 0x1E, 0x66, 0x9D, 0x79, 0x2F, 0xA5, 0x76, 0x2F, 0x1D, 0x40, + 0xB4, 0x6D, 0xC9, 0x7D, 0x79, 0x08, 0xEC, 0xD1, 0x6A, 0xB6, 0x5D, 0x2A, + 0xB2, 0xA5, 0x66, 0xBD, 0x6B, 0x85, 0xF4, 0x74, 0x56, 0xC3, 0xF5, 0xE7, + 0x75, 0x52, 0x28, 0x2C, 0xA5, 0xFF, 0x66, 0x47, 0xA5, 0xD4, 0xFE, 0xFE, + 0x9E, 0x54, 0xBF, 0x65, 0x7E, 0x01, 0xD6, 0x30, 0x8F, 0xA5, 0x36, 0x9C, + 0xA2, 0x50, 0x1C, 0xEE, 0x38, 0x80, 0x01, 0x48, 0xC6, 0xC7, 0x74, 0xF4, + 0xC6, 0xAC, 0xC3, 0x40, 0x49, 0x16, 0x61, 0x74, 0x2C, 0xAF, 0x8C, 0x6F, + 0x35, 0xED, 0x7B, 0x18, 0x00, 0x5B, 0x36, 0x3C, 0x9C, 0x50, 0x0D, 0xCA, + 0x92, 0x33, 0x10, 0xF1, 0x26, 0x49, 0x6D, 0xDF, 0x75, 0x24, 0x37, 0x82, + 0x22, 0xD7, 0xE8, 0x96, 0xFD, 0x15, 0x4B, 0x02, 0x96, 0x3E, 0x07, 0x72, + 0x95, 0x7E, 0xAB, 0x3D, 0x4C, 0x2E, 0xD7, 0xCA, 0xF0, 0xDF, 0xE0, 0x58, + 0x3F, 0x2D, 0x2F, 0x04, 0x9A, 0x38, 0xA3, 0x01 +}; + +static const unsigned char TA141_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA142_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x34 +}; + +static const unsigned char TA142_RSA_N[] = { + 0xC5, 0xD2, 0x7A, 0xA1, 0xD6, 0x8A, 0xBF, 0x16, 0x31, 0xD0, 0x98, 0xD1, + 0x3A, 0x94, 0xFC, 0x5A, 0xB8, 0x6E, 0x22, 0xC1, 0x62, 0xF7, 0xA7, 0x0A, + 0x27, 0xEF, 0x50, 0xF6, 0x2E, 0xB1, 0x9E, 0x68, 0x12, 0xF0, 0x6C, 0x24, + 0x63, 0x39, 0xF1, 0xF0, 0xDF, 0x10, 0xC6, 0xDE, 0xB7, 0x52, 0x20, 0xD5, + 0x52, 0x5B, 0x42, 0x99, 0x9E, 0xF3, 0xA0, 0xBE, 0x52, 0x1F, 0x5F, 0xCC, + 0x67, 0x6D, 0xA7, 0x2E, 0x50, 0xA2, 0xC1, 0x97, 0x8D, 0xB6, 0xF8, 0x95, + 0xF5, 0xB0, 0xBA, 0xDC, 0x9D, 0xE0, 0xBE, 0xCB, 0xDF, 0xF7, 0x38, 0xF2, + 0x47, 0xF5, 0xA6, 0x9A, 0x92, 0x95, 0x2A, 0x62, 0x59, 0x50, 0x0B, 0xA2, + 0xB1, 0x35, 0xE7, 0x65, 0xB2, 0x61, 0xB2, 0xEA, 0x92, 0x71, 0x69, 0xE4, + 0x29, 0xF0, 0x4F, 0x81, 0x81, 0x04, 0x3C, 0xB2, 0xA5, 0x5B, 0xD4, 0xC5, + 0xA8, 0x59, 0x67, 0x7B, 0x55, 0x1C, 0x49, 0xAB, 0x7A, 0x9D, 0xC2, 0xE7, + 0x73, 0x4D, 0xEF, 0xCD, 0x09, 0xC2, 0xC4, 0x57, 0x12, 0xDB, 0x01, 0x0E, + 0x23, 0x79, 0x09, 0x07, 0x3B, 0xA2, 0xE8, 0xFC, 0x8A, 0xCF, 0x8F, 0xC0, + 0x46, 0x24, 0x9C, 0x38, 0x27, 0xE0, 0x83, 0x9D, 0x1B, 0xA0, 0xBF, 0x78, + 0x15, 0x10, 0xEB, 0x86, 0x4E, 0x0A, 0x5A, 0xFD, 0xDF, 0xDA, 0x2C, 0x82, + 0x7E, 0xEE, 0xCA, 0xF6, 0x29, 0xE1, 0xFA, 0x71, 0xA1, 0xF7, 0x88, 0x68, + 0x9C, 0x9C, 0xF0, 0x8D, 0xBE, 0x0F, 0x49, 0x91, 0xD8, 0xEA, 0x3A, 0xF9, + 0xFD, 0xD0, 0x68, 0x71, 0xDB, 0xE9, 0xB5, 0x2B, 0x4E, 0x82, 0x92, 0x6F, + 0x66, 0x1F, 0xE0, 0xF0, 0xDC, 0x4C, 0xEC, 0xCA, 0xD1, 0xEA, 0xBA, 0x74, + 0x06, 0xF9, 0xB3, 0x84, 0x90, 0x94, 0xD1, 0x5F, 0x8E, 0x73, 0x19, 0x10, + 0x5D, 0x02, 0xE5, 0x70, 0xA5, 0xC0, 0x10, 0xD0, 0x10, 0x7C, 0x6F, 0xC5, + 0x58, 0x49, 0xB4, 0xB0, 0x6E, 0x9A, 0xDA, 0x7D, 0x95, 0xF5, 0xCC, 0xDA, + 0x02, 0xAF, 0xB8, 0x2C, 0x7D, 0x79, 0x8F, 0xBE, 0x43, 0xF1, 0xF9, 0x28, + 0x28, 0x8D, 0x09, 0x43, 0xF8, 0x08, 0xDD, 0x6B, 0xC8, 0x8B, 0x2C, 0x24, + 0xB1, 0x8D, 0x52, 0x07, 0xBD, 0x78, 0x9B, 0xCB, 0xCA, 0x68, 0xB2, 0xA4, + 0xDD, 0x0C, 0x4C, 0x79, 0x60, 0xC6, 0x99, 0xD1, 0x93, 0xF1, 0x30, 0x1A, + 0x07, 0xD3, 0xAE, 0x22, 0xC2, 0xEA, 0xCE, 0xF1, 0x84, 0x09, 0xCC, 0xE0, + 0x14, 0x6E, 0x7F, 0x3F, 0x7E, 0xD2, 0x82, 0x85, 0xAC, 0xDC, 0xA9, 0x16, + 0x4E, 0x85, 0xA0, 0x60, 0xCB, 0xF6, 0x9C, 0xD7, 0xC8, 0xB3, 0x8E, 0xED, + 0xC6, 0x9B, 0x98, 0x75, 0x0D, 0x55, 0xE8, 0x5F, 0xE5, 0x95, 0x8B, 0x02, + 0xA4, 0xAE, 0x43, 0x29, 0x28, 0x11, 0xA4, 0xE6, 0x12, 0x30, 0x01, 0x4B, + 0x75, 0x6B, 0x1E, 0x66, 0x9D, 0x79, 0x2F, 0xA5, 0x76, 0x2F, 0x1D, 0x40, + 0xB4, 0x6D, 0xC9, 0x7D, 0x79, 0x08, 0xEC, 0xD1, 0x6A, 0xB6, 0x5D, 0x2A, + 0xB2, 0xA5, 0x66, 0xBD, 0x6B, 0x85, 0xF4, 0x74, 0x56, 0xC3, 0xF5, 0xE7, + 0x75, 0x52, 0x28, 0x2C, 0xA5, 0xFF, 0x66, 0x47, 0xA5, 0xD4, 0xFE, 0xFE, + 0x9E, 0x54, 0xBF, 0x65, 0x7E, 0x01, 0xD6, 0x30, 0x8F, 0xA5, 0x36, 0x9C, + 0xA2, 0x50, 0x1C, 0xEE, 0x38, 0x80, 0x01, 0x48, 0xC6, 0xC7, 0x74, 0xF4, + 0xC6, 0xAC, 0xC3, 0x40, 0x49, 0x16, 0x61, 0x74, 0x2C, 0xAF, 0x8C, 0x6F, + 0x35, 0xED, 0x7B, 0x18, 0x00, 0x5B, 0x36, 0x3C, 0x9C, 0x50, 0x0D, 0xCA, + 0x92, 0x33, 0x10, 0xF1, 0x26, 0x49, 0x6D, 0xDF, 0x75, 0x24, 0x37, 0x82, + 0x22, 0xD7, 0xE8, 0x96, 0xFD, 0x15, 0x4B, 0x02, 0x96, 0x3E, 0x07, 0x72, + 0x95, 0x7E, 0xAB, 0x3D, 0x4C, 0x2E, 0xD7, 0xCA, 0xF0, 0xDF, 0xE0, 0x58, + 0x3F, 0x2D, 0x2F, 0x04, 0x9A, 0x38, 0xA3, 0x01 +}; + +static const unsigned char TA142_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA143_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x32 +}; + +static const unsigned char TA143_EC_Q[] = { + 0x04, 0xCD, 0x9B, 0xD5, 0x9F, 0x80, 0x83, 0x0A, 0xEC, 0x09, 0x4A, 0xF3, + 0x16, 0x4A, 0x3E, 0x5C, 0xCF, 0x77, 0xAC, 0xDE, 0x67, 0x05, 0x0D, 0x1D, + 0x07, 0xB6, 0xDC, 0x16, 0xFB, 0x5A, 0x8B, 0x14, 0xDB, 0xE2, 0x71, 0x60, + 0xC4, 0xBA, 0x45, 0x95, 0x11, 0x89, 0x8E, 0xEA, 0x06, 0xDF, 0xF7, 0x2A, + 0x16, 0x1C, 0xA4, 0xB9, 0xC5, 0xC5, 0x32, 0xE0, 0x03, 0xE0, 0x1E, 0x82, + 0x18, 0x38, 0x8B, 0xD7, 0x45, 0xD8, 0x0A, 0x6A, 0x6E, 0xE6, 0x00, 0x77, + 0xFB, 0x02, 0x51, 0x7D, 0x22, 0xD8, 0x0A, 0x6E, 0x9A, 0x5B, 0x77, 0xDF, + 0xF0, 0xFA, 0x41, 0xEC, 0x39, 0xDC, 0x75, 0xCA, 0x68, 0x07, 0x0C, 0x1F, + 0xEA +}; + +static const unsigned char TA144_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x08, 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x10, 0x63, 0x65, 0x72, + 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA144_RSA_N[] = { + 0xB7, 0x33, 0xB9, 0x7E, 0xC8, 0x25, 0x4A, 0x8E, 0xB5, 0xDB, 0xB4, 0x28, + 0x1B, 0xAA, 0x57, 0x90, 0xE8, 0xD1, 0x22, 0xD3, 0x64, 0xBA, 0xD3, 0x93, + 0xE8, 0xD4, 0xAC, 0x86, 0x61, 0x40, 0x6A, 0x60, 0x57, 0x68, 0x54, 0x84, + 0x4D, 0xBC, 0x6A, 0x54, 0x02, 0x05, 0xFF, 0xDF, 0x9B, 0x9A, 0x2A, 0xAE, + 0x5D, 0x07, 0x8F, 0x4A, 0xC3, 0x28, 0x7F, 0xEF, 0xFB, 0x2B, 0xFA, 0x79, + 0xF1, 0xC7, 0xAD, 0xF0, 0x10, 0x53, 0x24, 0x90, 0x8B, 0x66, 0xC9, 0xA8, + 0x88, 0xAB, 0xAF, 0x5A, 0xA3, 0x00, 0xE9, 0xBE, 0xBA, 0x46, 0xEE, 0x5B, + 0x73, 0x7B, 0x2C, 0x17, 0x82, 0x81, 0x5E, 0x62, 0x2C, 0xA1, 0x02, 0x65, + 0xB3, 0xBD, 0xC5, 0x2B, 0x00, 0x7E, 0xC4, 0xFC, 0x03, 0x33, 0x57, 0x0D, + 0xED, 0xE2, 0xFA, 0xCE, 0x5D, 0x45, 0xD6, 0x38, 0xCD, 0x35, 0xB6, 0xB2, + 0xC1, 0xD0, 0x9C, 0x81, 0x4A, 0xAA, 0xE4, 0xB2, 0x01, 0x5C, 0x1D, 0x8F, + 0x5F, 0x99, 0xC4, 0xB1, 0xAD, 0xDB, 0x88, 0x21, 0xEB, 0x90, 0x08, 0x82, + 0x80, 0xF3, 0x30, 0xA3, 0x43, 0xE6, 0x90, 0x82, 0xAE, 0x55, 0x28, 0x49, + 0xED, 0x5B, 0xD7, 0xA9, 0x10, 0x38, 0x0E, 0xFE, 0x8F, 0x4C, 0x5B, 0x9B, + 0x46, 0xEA, 0x41, 0xF5, 0xB0, 0x08, 0x74, 0xC3, 0xD0, 0x88, 0x33, 0xB6, + 0x7C, 0xD7, 0x74, 0xDF, 0xDC, 0x84, 0xD1, 0x43, 0x0E, 0x75, 0x39, 0xA1, + 0x25, 0x40, 0x28, 0xEA, 0x78, 0xCB, 0x0E, 0x2C, 0x2E, 0x39, 0x9D, 0x8C, + 0x8B, 0x6E, 0x16, 0x1C, 0x2F, 0x26, 0x82, 0x10, 0xE2, 0xE3, 0x65, 0x94, + 0x0A, 0x04, 0xC0, 0x5E, 0xF7, 0x5D, 0x5B, 0xF8, 0x10, 0xE2, 0xD0, 0xBA, + 0x7A, 0x4B, 0xFB, 0xDE, 0x37, 0x00, 0x00, 0x1A, 0x5B, 0x28, 0xE3, 0xD2, + 0x9C, 0x73, 0x3E, 0x32, 0x87, 0x98, 0xA1, 0xC9, 0x51, 0x2F, 0xD7, 0xDE, + 0xAC, 0x33, 0xB3, 0x4F +}; + +static const unsigned char TA144_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA145_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA145_EC_Q[] = { + 0x04, 0x45, 0x6E, 0xA9, 0x50, 0xC4, 0xA6, 0x23, 0x36, 0x9E, 0x5F, 0x28, + 0x8D, 0x17, 0xCB, 0x96, 0x22, 0x64, 0x3F, 0xDC, 0x7A, 0x8E, 0x1D, 0xCC, + 0x08, 0xB3, 0xA2, 0x71, 0x24, 0xBA, 0x8E, 0x49, 0xB9, 0x04, 0x1B, 0x47, + 0x96, 0x58, 0xAB, 0x2D, 0x95, 0xC8, 0xED, 0x9E, 0x08, 0x35, 0xC8, 0x27, + 0xEB, 0x89, 0x8C, 0x53, 0x58, 0xEB, 0x62, 0x8A, 0xFE, 0xF0, 0x5B, 0x0F, + 0x6B, 0x31, 0x52, 0x63, 0x41, 0x3B, 0x89, 0xCD, 0xEC, 0xEC, 0xB6, 0x8D, + 0x19, 0xD3, 0x34, 0x07, 0xDC, 0xBB, 0xC6, 0x06, 0x7F, 0xC2, 0x45, 0x95, + 0xEC, 0xCB, 0x7F, 0xA8, 0x23, 0xE0, 0x09, 0xE9, 0x81, 0xFA, 0xF3, 0x47, + 0xD3 +}; + +static const unsigned char TA146_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA146_EC_Q[] = { + 0x04, 0x03, 0x47, 0x7B, 0x2F, 0x75, 0xC9, 0x82, 0x15, 0x85, 0xFB, 0x75, + 0xE4, 0x91, 0x16, 0xD4, 0xAB, 0x62, 0x99, 0xF5, 0x3E, 0x52, 0x0B, 0x06, + 0xCE, 0x41, 0x00, 0x7F, 0x97, 0xE1, 0x0A, 0x24, 0x3C, 0x1D, 0x01, 0x04, + 0xEE, 0x3D, 0xD2, 0x8D, 0x09, 0x97, 0x0C, 0xE0, 0x75, 0xE4, 0xFA, 0xFB, + 0x77, 0x8A, 0x2A, 0xF5, 0x03, 0x60, 0x4B, 0x36, 0x8B, 0x16, 0x23, 0x16, + 0xAD, 0x09, 0x71, 0xF4, 0x4A, 0xF4, 0x28, 0x50, 0xB4, 0xFE, 0x88, 0x1C, + 0x6E, 0x3F, 0x6C, 0x2F, 0x2F, 0x09, 0x59, 0x5B, 0xA5, 0x5B, 0x0B, 0x33, + 0x99, 0xE2, 0xC3, 0x3D, 0x89, 0xF9, 0x6A, 0x2C, 0xEF, 0xB2, 0xD3, 0x06, + 0xE9 +}; + +static const unsigned char TA147_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA147_EC_Q[] = { + 0x04, 0x29, 0x97, 0xA7, 0xC6, 0x41, 0x7F, 0xC0, 0x0D, 0x9B, 0xE8, 0x01, + 0x1B, 0x56, 0xC6, 0xF2, 0x52, 0xA5, 0xBA, 0x2D, 0xB2, 0x12, 0xE8, 0xD2, + 0x2E, 0xD7, 0xFA, 0xC9, 0xC5, 0xD8, 0xAA, 0x6D, 0x1F, 0x73, 0x81, 0x3B, + 0x3B, 0x98, 0x6B, 0x39, 0x7C, 0x33, 0xA5, 0xC5, 0x4E, 0x86, 0x8E, 0x80, + 0x17, 0x68, 0x62, 0x45, 0x57, 0x7D, 0x44, 0x58, 0x1D, 0xB3, 0x37, 0xE5, + 0x67, 0x08, 0xEB, 0x66, 0xDE +}; + +static const unsigned char TA148_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA148_RSA_N[] = { + 0xB0, 0x48, 0x65, 0xA3, 0x0D, 0x1D, 0x42, 0xE3, 0x91, 0x6D, 0x9D, 0x84, + 0xA4, 0x61, 0x96, 0x12, 0xC2, 0xED, 0xC3, 0xDA, 0x23, 0x34, 0x19, 0x76, + 0xF6, 0xEA, 0xFD, 0x55, 0x5A, 0xF6, 0x55, 0x01, 0x53, 0x0F, 0xF2, 0xCC, + 0x8C, 0x97, 0x4F, 0xB9, 0x50, 0xCB, 0xB3, 0x01, 0x44, 0x56, 0x96, 0xFD, + 0x9B, 0x28, 0xEC, 0x7B, 0x74, 0x0B, 0xE7, 0x42, 0x6B, 0x55, 0xCE, 0xC9, + 0x61, 0xB2, 0xE8, 0xAD, 0x40, 0x3C, 0xBA, 0xB9, 0x41, 0x0A, 0x05, 0x4F, + 0x1B, 0x26, 0x85, 0x8F, 0x43, 0xB5, 0x40, 0xB5, 0x85, 0xD1, 0xD4, 0x71, + 0xDC, 0x83, 0x41, 0xF3, 0xF6, 0x45, 0xC7, 0x80, 0xA2, 0x84, 0x50, 0x97, + 0x46, 0xCE, 0xA0, 0x0C, 0xC4, 0x60, 0x56, 0x04, 0x1D, 0x07, 0x5B, 0x46, + 0xA5, 0x0E, 0xB2, 0x4B, 0xA4, 0x0E, 0xA5, 0x7C, 0xEE, 0xF8, 0xD4, 0x62, + 0x03, 0xB9, 0x93, 0x6A, 0x8A, 0x14, 0xB8, 0x70, 0xF8, 0x2E, 0x82, 0x46, + 0x38, 0x23, 0x0E, 0x74, 0xC7, 0x6B, 0x41, 0xB7, 0xD0, 0x29, 0xA3, 0x9D, + 0x80, 0xB0, 0x7E, 0x77, 0x93, 0x63, 0x42, 0xFB, 0x34, 0x83, 0x3B, 0x73, + 0xA3, 0x5A, 0x21, 0x36, 0xEB, 0x47, 0xFA, 0x18, 0x17, 0xD9, 0xBA, 0x66, + 0xC2, 0x93, 0xA4, 0x8F, 0xFC, 0x5D, 0xA4, 0xAD, 0xFC, 0x50, 0x6A, 0x95, + 0xAC, 0xBC, 0x24, 0x33, 0xD1, 0xBD, 0x88, 0x7F, 0x86, 0xF5, 0xF5, 0xB2, + 0x73, 0x2A, 0x8F, 0x7C, 0xAF, 0x08, 0xF2, 0x1A, 0x98, 0x3F, 0xA9, 0x81, + 0x65, 0x3F, 0xC1, 0x8C, 0x89, 0xC5, 0x96, 0x30, 0x9A, 0x0A, 0xCF, 0xF4, + 0xD4, 0xC8, 0x34, 0xED, 0x9D, 0x2F, 0xBC, 0x8D, 0x38, 0x86, 0x53, 0xEE, + 0x97, 0x9F, 0xA9, 0xB2, 0x63, 0x94, 0x17, 0x8D, 0x0F, 0xDC, 0x66, 0x2A, + 0x7C, 0x52, 0x51, 0x75, 0xCB, 0x99, 0x8E, 0xE8, 0x3D, 0x5C, 0xBF, 0x9E, + 0x3B, 0x28, 0x8D, 0x83, 0x02, 0x0F, 0xA9, 0x9F, 0x72, 0xE2, 0x2C, 0x2B, + 0xB3, 0xDC, 0x66, 0x97, 0x00, 0x40, 0xD0, 0xA4, 0x54, 0x8E, 0x9B, 0x5D, + 0x7B, 0x45, 0x36, 0x26, 0xD6, 0x72, 0x43, 0xEB, 0xCF, 0xC0, 0xEA, 0x0D, + 0xDC, 0xCE, 0x12, 0xE6, 0x7D, 0x38, 0x9F, 0x05, 0x27, 0xA8, 0x97, 0x3E, + 0xE9, 0x51, 0xC6, 0x6C, 0x05, 0x28, 0xC1, 0x02, 0x0F, 0xE9, 0x18, 0x6D, + 0xEC, 0xBD, 0x9C, 0x06, 0xD4, 0xA7, 0x49, 0xF4, 0x54, 0x05, 0x6B, 0x6C, + 0x30, 0xF1, 0xEB, 0x03, 0xD5, 0xEA, 0x3D, 0x6A, 0x76, 0xC2, 0xCB, 0x1A, + 0x28, 0x49, 0x4D, 0x7F, 0x64, 0xE0, 0xFA, 0x2B, 0xDA, 0x73, 0x83, 0x81, + 0xFF, 0x91, 0x03, 0xBD, 0x94, 0xBB, 0xE4, 0xB8, 0x8E, 0x9C, 0x32, 0x63, + 0xCD, 0x9F, 0xBB, 0x68, 0x81, 0xB1, 0x84, 0x5B, 0xAF, 0x36, 0xBF, 0x77, + 0xEE, 0x1D, 0x7F, 0xF7, 0x49, 0x9B, 0x52, 0xEC, 0xD2, 0x77, 0x5A, 0x7D, + 0x91, 0x9D, 0x4D, 0xC2, 0x39, 0x2D, 0xE4, 0xBA, 0x82, 0xF8, 0x6F, 0xF2, + 0x4E, 0x1E, 0x0F, 0x4E, 0xE6, 0x3F, 0x59, 0xA5, 0x23, 0xDC, 0x3D, 0x87, + 0xA8, 0x28, 0x58, 0x28, 0xD1, 0xF1, 0x1B, 0x36, 0xDB, 0x4F, 0xC4, 0xFF, + 0xE1, 0x8C, 0x5B, 0x72, 0x8C, 0xC7, 0x26, 0x03, 0x27, 0xA3, 0x39, 0x0A, + 0x01, 0xAA, 0xC0, 0xB2, 0x31, 0x60, 0x83, 0x22, 0xA1, 0x4F, 0x12, 0x09, + 0x01, 0x11, 0xAF, 0x34, 0xD4, 0xCF, 0xD7, 0xAE, 0x62, 0xD3, 0x05, 0x07, + 0xB4, 0x31, 0x75, 0xE0, 0x0D, 0x6D, 0x57, 0x4F, 0x69, 0x87, 0xF9, 0x57, + 0xA9, 0xBA, 0x15, 0xF6, 0xC8, 0x52, 0x6D, 0xA1, 0xCB, 0x9C, 0x1F, 0xE5, + 0xFC, 0x78, 0xA8, 0x35, 0x9A, 0x9F, 0x41, 0x14, 0xCE, 0xA5, 0xB4, 0xCE, + 0x94, 0x08, 0x1C, 0x09, 0xAD, 0x56, 0xE5, 0xDA, 0xB6, 0x49, 0x9A, 0x4A, + 0xEA, 0x63, 0x18, 0x53, 0x9C, 0x2C, 0x2E, 0xC3 +}; + +static const unsigned char TA148_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA149_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA149_RSA_N[] = { + 0xD9, 0xE7, 0x28, 0x2F, 0x52, 0x3F, 0x36, 0x72, 0x49, 0x88, 0x93, 0x34, + 0xF3, 0xF8, 0x6A, 0x1E, 0x31, 0x54, 0x80, 0x9F, 0xAD, 0x54, 0x41, 0xB5, + 0x47, 0xDF, 0x96, 0xA8, 0xD4, 0xAF, 0x80, 0x2D, 0xB9, 0x0A, 0xCF, 0x75, + 0xFD, 0x89, 0xA5, 0x7D, 0x24, 0xFA, 0xE3, 0x22, 0x0C, 0x2B, 0xBC, 0x95, + 0x17, 0x0B, 0x33, 0xBF, 0x19, 0x4D, 0x41, 0x06, 0x90, 0x00, 0xBD, 0x0C, + 0x4D, 0x10, 0xFE, 0x07, 0xB5, 0xE7, 0x1C, 0x6E, 0x22, 0x55, 0x31, 0x65, + 0x97, 0xBD, 0xD3, 0x17, 0xD2, 0x1E, 0x62, 0xF3, 0xDB, 0xEA, 0x6C, 0x50, + 0x8C, 0x3F, 0x84, 0x0C, 0x96, 0xCF, 0xB7, 0xCB, 0x03, 0xE0, 0xCA, 0x6D, + 0xA1, 0x14, 0x4C, 0x1B, 0x89, 0xDD, 0xED, 0x00, 0xB0, 0x52, 0x7C, 0xAF, + 0x91, 0x6C, 0xB1, 0x38, 0x13, 0xD1, 0xE9, 0x12, 0x08, 0xC0, 0x00, 0xB0, + 0x1C, 0x2B, 0x11, 0xDA, 0x77, 0x70, 0x36, 0x9B, 0xAE, 0xCE, 0x79, 0x87, + 0xDC, 0x82, 0x70, 0xE6, 0x09, 0x74, 0x70, 0x55, 0x69, 0xAF, 0xA3, 0x68, + 0x9F, 0xBF, 0xDD, 0xB6, 0x79, 0xB3, 0xF2, 0x9D, 0x70, 0x29, 0x55, 0xF4, + 0xAB, 0xFF, 0x95, 0x61, 0xF3, 0xC9, 0x40, 0x6F, 0x1D, 0xD1, 0xBE, 0x93, + 0xBB, 0xD3, 0x88, 0x2A, 0xBB, 0x9D, 0xBF, 0x72, 0x5A, 0x56, 0x71, 0x3B, + 0x3F, 0xD4, 0xF3, 0xD1, 0x0A, 0xFE, 0x28, 0xEF, 0xA3, 0xEE, 0xD9, 0x99, + 0xAF, 0x03, 0xD3, 0x8F, 0x60, 0xB7, 0xF2, 0x92, 0xA1, 0xB1, 0xBD, 0x89, + 0x89, 0x1F, 0x30, 0xCD, 0xC3, 0xA6, 0x2E, 0x62, 0x33, 0xAE, 0x16, 0x02, + 0x77, 0x44, 0x5A, 0xE7, 0x81, 0x0A, 0x3C, 0xA7, 0x44, 0x2E, 0x79, 0xB8, + 0x3F, 0x04, 0xBC, 0x5C, 0xA0, 0x87, 0xE1, 0x1B, 0xAF, 0x51, 0x8E, 0xCD, + 0xEC, 0x2C, 0xFA, 0xF8, 0xFE, 0x6D, 0xF0, 0x3A, 0x7C, 0xAA, 0x8B, 0xE4, + 0x67, 0x95, 0x31, 0x8D +}; + +static const unsigned char TA149_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA150_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x08, 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x10, 0x63, 0x65, 0x72, + 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA150_RSA_N[] = { + 0xB7, 0x33, 0xB9, 0x7E, 0xC8, 0x25, 0x4A, 0x8E, 0xB5, 0xDB, 0xB4, 0x28, + 0x1B, 0xAA, 0x57, 0x90, 0xE8, 0xD1, 0x22, 0xD3, 0x64, 0xBA, 0xD3, 0x93, + 0xE8, 0xD4, 0xAC, 0x86, 0x61, 0x40, 0x6A, 0x60, 0x57, 0x68, 0x54, 0x84, + 0x4D, 0xBC, 0x6A, 0x54, 0x02, 0x05, 0xFF, 0xDF, 0x9B, 0x9A, 0x2A, 0xAE, + 0x5D, 0x07, 0x8F, 0x4A, 0xC3, 0x28, 0x7F, 0xEF, 0xFB, 0x2B, 0xFA, 0x79, + 0xF1, 0xC7, 0xAD, 0xF0, 0x10, 0x53, 0x24, 0x90, 0x8B, 0x66, 0xC9, 0xA8, + 0x88, 0xAB, 0xAF, 0x5A, 0xA3, 0x00, 0xE9, 0xBE, 0xBA, 0x46, 0xEE, 0x5B, + 0x73, 0x7B, 0x2C, 0x17, 0x82, 0x81, 0x5E, 0x62, 0x2C, 0xA1, 0x02, 0x65, + 0xB3, 0xBD, 0xC5, 0x2B, 0x00, 0x7E, 0xC4, 0xFC, 0x03, 0x33, 0x57, 0x0D, + 0xED, 0xE2, 0xFA, 0xCE, 0x5D, 0x45, 0xD6, 0x38, 0xCD, 0x35, 0xB6, 0xB2, + 0xC1, 0xD0, 0x9C, 0x81, 0x4A, 0xAA, 0xE4, 0xB2, 0x01, 0x5C, 0x1D, 0x8F, + 0x5F, 0x99, 0xC4, 0xB1, 0xAD, 0xDB, 0x88, 0x21, 0xEB, 0x90, 0x08, 0x82, + 0x80, 0xF3, 0x30, 0xA3, 0x43, 0xE6, 0x90, 0x82, 0xAE, 0x55, 0x28, 0x49, + 0xED, 0x5B, 0xD7, 0xA9, 0x10, 0x38, 0x0E, 0xFE, 0x8F, 0x4C, 0x5B, 0x9B, + 0x46, 0xEA, 0x41, 0xF5, 0xB0, 0x08, 0x74, 0xC3, 0xD0, 0x88, 0x33, 0xB6, + 0x7C, 0xD7, 0x74, 0xDF, 0xDC, 0x84, 0xD1, 0x43, 0x0E, 0x75, 0x39, 0xA1, + 0x25, 0x40, 0x28, 0xEA, 0x78, 0xCB, 0x0E, 0x2C, 0x2E, 0x39, 0x9D, 0x8C, + 0x8B, 0x6E, 0x16, 0x1C, 0x2F, 0x26, 0x82, 0x10, 0xE2, 0xE3, 0x65, 0x94, + 0x0A, 0x04, 0xC0, 0x5E, 0xF7, 0x5D, 0x5B, 0xF8, 0x10, 0xE2, 0xD0, 0xBA, + 0x7A, 0x4B, 0xFB, 0xDE, 0x37, 0x00, 0x00, 0x1A, 0x5B, 0x28, 0xE3, 0xD2, + 0x9C, 0x73, 0x3E, 0x32, 0x87, 0x98, 0xA1, 0xC9, 0x51, 0x2F, 0xD7, 0xDE, + 0xAC, 0x33, 0xB3, 0x4F +}; + +static const unsigned char TA150_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA151_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA151_EC_Q[] = { + 0x04, 0xD4, 0xBC, 0x3D, 0x02, 0x42, 0x75, 0x41, 0x13, 0x23, 0xCD, 0x80, + 0x04, 0x86, 0x02, 0x51, 0x2F, 0x6A, 0xA8, 0x81, 0x62, 0x0B, 0x65, 0xCC, + 0xF6, 0xCA, 0x9D, 0x1E, 0x6F, 0x4A, 0x66, 0x51, 0xA2, 0x03, 0xD9, 0x9D, + 0x91, 0xFA, 0xB6, 0x16, 0xB1, 0x8C, 0x6E, 0xDE, 0x7C, 0xCD, 0xDB, 0x79, + 0xA6, 0x2F, 0xCE, 0xBB, 0xCE, 0x71, 0x2F, 0xE5, 0xA5, 0xAB, 0x28, 0xEC, + 0x63, 0x04, 0x66, 0x99, 0xF8, 0xFA, 0xF2, 0x93, 0x10, 0x05, 0xE1, 0x81, + 0x28, 0x42, 0xE3, 0xC6, 0x68, 0xF4, 0xE6, 0x1B, 0x84, 0x60, 0x4A, 0x89, + 0xAF, 0xED, 0x79, 0x0F, 0x3B, 0xCE, 0xF1, 0xF6, 0x44, 0xF5, 0x01, 0x78, + 0xC0 +}; + +static const unsigned char TA152_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x49, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x11, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x6C, + 0x61, 0x6E, 0x64, 0x20, 0x4F, 0x79, 0x6A, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x32 +}; + +static const unsigned char TA152_RSA_N[] = { + 0xB2, 0xD0, 0x3F, 0x07, 0xBC, 0xE2, 0x7B, 0xD0, 0x6B, 0x99, 0xF8, 0xE2, + 0x77, 0x69, 0xE7, 0xCE, 0x9D, 0xA4, 0x03, 0xBC, 0x82, 0x6D, 0xA1, 0xFE, + 0x81, 0x65, 0x1F, 0x4C, 0x27, 0xAC, 0x8E, 0x00, 0xBA, 0x16, 0x7B, 0xEB, + 0x30, 0x6A, 0x00, 0xC0, 0xB3, 0x74, 0x68, 0x7E, 0xB2, 0xAF, 0xC7, 0xD5, + 0x62, 0xB3, 0x7A, 0x3F, 0x50, 0xCA, 0x8C, 0x36, 0x44, 0x24, 0x63, 0xD2, + 0x36, 0xE9, 0x0C, 0x85, 0xF6, 0x43, 0x76, 0xD5, 0x4C, 0xA1, 0x60, 0x72, + 0x67, 0xE2, 0x28, 0x33, 0xA5, 0xCB, 0x31, 0xB8, 0x3A, 0x22, 0x23, 0x34, + 0xB8, 0x7D, 0xBD, 0x56, 0x22, 0x40, 0x9D, 0xEA, 0xF4, 0x7B, 0x03, 0xAD, + 0x68, 0xFC, 0xB2, 0x81, 0x4F, 0x98, 0xD0, 0x74, 0xEA, 0x8D, 0xE5, 0x7D, + 0xCD, 0x63, 0xC3, 0xA3, 0xF6, 0xDE, 0x92, 0xC2, 0x58, 0x19, 0xE0, 0x96, + 0xBB, 0xC5, 0xC4, 0xA9, 0x3D, 0xA5, 0x74, 0x96, 0xFE, 0xAF, 0xF9, 0x89, + 0xAA, 0xBD, 0x95, 0x17, 0x54, 0xD8, 0x78, 0x44, 0xF1, 0x0C, 0x77, 0x15, + 0x92, 0xE0, 0x98, 0x42, 0xA7, 0xA4, 0xD6, 0xAA, 0x20, 0x92, 0xCD, 0xC1, + 0xA0, 0xB3, 0x96, 0xB2, 0x3A, 0x84, 0x42, 0x8D, 0x7D, 0xD5, 0x95, 0xE4, + 0xD6, 0xDB, 0xE9, 0x62, 0xC4, 0x58, 0xB3, 0x79, 0xC5, 0x8C, 0xD3, 0x35, + 0x33, 0x83, 0x9F, 0x75, 0xA1, 0x52, 0x27, 0x61, 0x38, 0xF1, 0x59, 0x3D, + 0x8E, 0x50, 0xE0, 0xBD, 0x79, 0x3C, 0xE7, 0x6C, 0x96, 0xFE, 0x5E, 0xD9, + 0x02, 0x65, 0xB4, 0x8E, 0x5C, 0xD0, 0x11, 0x34, 0xDF, 0x5D, 0xBF, 0x52, + 0xA7, 0x81, 0x00, 0xC3, 0x7F, 0x99, 0x45, 0x99, 0x15, 0xD5, 0x17, 0xC8, + 0x0A, 0x53, 0xEC, 0x63, 0xF3, 0x99, 0x7D, 0xCC, 0x69, 0x12, 0x86, 0xC2, + 0x17, 0xF0, 0x01, 0x9E, 0xBF, 0x84, 0xBC, 0xD1, 0x52, 0xCB, 0x1B, 0x92, + 0x66, 0xCE, 0xA4, 0x53, 0xE5, 0xA1, 0xBF, 0xC4, 0xDB, 0x09, 0xD6, 0xE6, + 0x89, 0x56, 0x2B, 0xC8, 0xE3, 0x7C, 0xDE, 0xE3, 0xFF, 0x89, 0xE5, 0x35, + 0x6E, 0x28, 0xE8, 0x6C, 0x0B, 0x23, 0x51, 0xA9, 0x25, 0x05, 0xEB, 0x48, + 0xF8, 0xDD, 0xB1, 0xCA, 0xFA, 0x6C, 0x08, 0x51, 0xEF, 0xB7, 0x18, 0x6C, + 0x44, 0xCA, 0x26, 0xE1, 0x73, 0xC6, 0x89, 0x06, 0x81, 0xE5, 0x8A, 0xAC, + 0xB0, 0xE2, 0x29, 0xC6, 0xB9, 0x24, 0xB3, 0x6B, 0x44, 0x11, 0xF4, 0xA5, + 0x43, 0xC2, 0x4C, 0x43, 0xE5, 0x70, 0x36, 0x8C, 0xB6, 0x33, 0x57, 0x7A, + 0x95, 0x2E, 0x82, 0xA0, 0xF4, 0x5C, 0x10, 0xB3, 0x61, 0x83, 0xF6, 0x02, + 0x05, 0x86, 0x2E, 0x7C, 0x2D, 0x6C, 0xDC, 0x03, 0x46, 0x6E, 0x35, 0x93, + 0xD5, 0x7A, 0x95, 0x2F, 0xDE, 0x20, 0xD8, 0x5B, 0x7E, 0x94, 0x90, 0x04, + 0x6A, 0xBA, 0x59, 0x3D, 0x04, 0x05, 0x75, 0x9D, 0x37, 0xA2, 0x0E, 0x2E, + 0x3D, 0xEB, 0xC1, 0xA4, 0x52, 0x83, 0xFE, 0xD0, 0x6B, 0xD4, 0x66, 0x8E, + 0xDC, 0xC6, 0xE9, 0x12, 0x4E, 0x1D, 0x2A, 0x57, 0xAA, 0x10, 0xBC, 0x7C, + 0x5E, 0x82, 0x7D, 0xA6, 0xA6, 0xC9, 0xF2, 0x2D, 0xB9, 0xF5, 0x17, 0x27, + 0xAD, 0xD1, 0x0E, 0x89, 0x54, 0x2B, 0x95, 0xFA, 0xC0, 0xAD, 0x1D, 0x98, + 0x14, 0x78, 0x33, 0x42, 0x86, 0x0A, 0xA9, 0x73, 0xB5, 0xFB, 0x74, 0x0D, + 0xB7, 0x1B, 0x30, 0x19, 0xC4, 0x5A, 0x0E, 0x1C, 0x27, 0xB7, 0xDA, 0x18, + 0xD0, 0xFF, 0x8A, 0xC8, 0x05, 0xBA, 0xF1, 0xAA, 0x1C, 0xA2, 0x37, 0xB7, + 0xE6, 0x48, 0xA4, 0x46, 0x2C, 0x94, 0xEA, 0xA8, 0x76, 0x62, 0x47, 0x8B, + 0x10, 0x53, 0x07, 0x48, 0x57, 0x6C, 0xE2, 0x92, 0x4D, 0xB6, 0xAE, 0x05, + 0xCB, 0xDC, 0xC1, 0x4A, 0x5E, 0x8F, 0xAC, 0x3D, 0x19, 0x4E, 0xC2, 0xED, + 0x60, 0x75, 0x2B, 0xDB, 0xC1, 0xCA, 0x42, 0xD5 +}; + +static const unsigned char TA152_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA153_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x35 +}; + +static const unsigned char TA153_EC_Q[] = { + 0x04, 0x0B, 0x50, 0x74, 0x8D, 0x64, 0x32, 0x99, 0x99, 0xB3, 0xD2, 0x60, + 0x08, 0xB8, 0x22, 0x8E, 0x46, 0x74, 0x2C, 0x78, 0xC0, 0x2B, 0x44, 0x2D, + 0x6D, 0x5F, 0x1D, 0xC9, 0xAE, 0x4B, 0x52, 0x20, 0x83, 0x3D, 0xB8, 0x14, + 0x6D, 0x53, 0x87, 0x60, 0x9E, 0x5F, 0x6C, 0x85, 0xDB, 0x06, 0x14, 0x95, + 0xE0, 0xC7, 0x28, 0xFF, 0x9D, 0x5F, 0xE4, 0xAA, 0xF1, 0xB3, 0x8B, 0x6D, + 0xED, 0x4F, 0x2F, 0x4B, 0xC9, 0x4A, 0x94, 0x91, 0x64, 0x75, 0xFE, 0x01, + 0xEC, 0xC1, 0xD8, 0xEB, 0x7A, 0x94, 0x78, 0x56, 0x18, 0x43, 0x5F, 0x6B, + 0x81, 0xCB, 0xF6, 0xBC, 0xDA, 0xB4, 0x0C, 0xB6, 0x29, 0x93, 0x08, 0x69, + 0x8F +}; + +static const unsigned char TA154_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, + 0x36 +}; + +static const unsigned char TA154_RSA_N[] = { + 0x93, 0xBE, 0xD5, 0x36, 0x52, 0x75, 0xD8, 0x01, 0x23, 0xA0, 0x1C, 0x47, + 0x42, 0x49, 0xEE, 0x63, 0xB6, 0xB7, 0x21, 0xFD, 0xC4, 0x95, 0xD5, 0x48, + 0x2B, 0x26, 0x7C, 0x14, 0x53, 0x10, 0xDA, 0x79, 0xFD, 0x2B, 0xB7, 0x2D, + 0xA4, 0xD4, 0x2C, 0xFA, 0xEA, 0x32, 0xDD, 0x49, 0xC2, 0xB9, 0xBD, 0x0F, + 0x48, 0x3D, 0x7B, 0x5A, 0x98, 0x54, 0xAF, 0x9E, 0x5D, 0x31, 0x74, 0x4F, + 0x07, 0xFC, 0x50, 0x21, 0xDD, 0xA4, 0xCF, 0x68, 0x4F, 0x1B, 0x12, 0x63, + 0x6D, 0x25, 0x99, 0x4C, 0x2A, 0x99, 0xF3, 0x48, 0x30, 0x61, 0xFA, 0x81, + 0x7C, 0x1E, 0xA7, 0x08, 0x4A, 0xDC, 0x3E, 0x2B, 0x1C, 0x1F, 0x18, 0x4C, + 0x71, 0xAA, 0x35, 0x8C, 0xAD, 0xF8, 0x6E, 0xE8, 0x3B, 0x4A, 0xD9, 0xE5, + 0x94, 0x02, 0xD6, 0x89, 0x84, 0x13, 0xAA, 0x6D, 0xC8, 0x4F, 0x33, 0xCC, + 0x50, 0x96, 0x37, 0x92, 0x33, 0xDC, 0x5F, 0x88, 0xE7, 0x9F, 0x54, 0xD9, + 0x48, 0xF0, 0x98, 0x43, 0xD6, 0x66, 0xFD, 0x9F, 0x17, 0x38, 0x43, 0xC5, + 0x01, 0x51, 0x0B, 0xD7, 0xE3, 0x23, 0x0F, 0x14, 0x5D, 0x5B, 0x14, 0xE7, + 0x4B, 0xBE, 0xDD, 0xF4, 0xC8, 0xDA, 0x03, 0x37, 0xD1, 0xD6, 0x39, 0xA1, + 0x21, 0x51, 0x30, 0x83, 0xB0, 0x6D, 0xD7, 0x30, 0x4E, 0x96, 0x5B, 0x91, + 0xF0, 0x70, 0x24, 0xAB, 0xBF, 0x45, 0x81, 0x64, 0x43, 0x0D, 0xBD, 0x21, + 0x3A, 0x2F, 0x3C, 0xE9, 0x9E, 0x0D, 0xCB, 0x20, 0xB5, 0x42, 0x27, 0xCC, + 0xDA, 0x6F, 0x9B, 0xEE, 0x64, 0x30, 0x90, 0x39, 0xCD, 0x93, 0x65, 0x81, + 0x21, 0x31, 0xB5, 0x23, 0x50, 0x33, 0x37, 0x22, 0xE3, 0x38, 0xED, 0xF8, + 0x31, 0x30, 0xCC, 0x45, 0xFE, 0x62, 0xF9, 0xD1, 0x5D, 0x32, 0x79, 0x42, + 0x87, 0xDF, 0x6A, 0xCC, 0x56, 0x19, 0x40, 0x4D, 0xCE, 0xAA, 0xBB, 0xF9, + 0xB5, 0x76, 0x49, 0x94, 0xF1, 0x27, 0xF8, 0x91, 0xA5, 0x83, 0xE5, 0x06, + 0xB3, 0x63, 0x0E, 0x80, 0xDC, 0xE0, 0x12, 0x55, 0x80, 0xA6, 0x3B, 0x66, + 0xB4, 0x39, 0x87, 0x2D, 0xC8, 0xF0, 0xD0, 0xD1, 0x14, 0xE9, 0xE4, 0x0D, + 0x4D, 0x0E, 0xF6, 0x5D, 0x57, 0x72, 0xC5, 0x3B, 0x1C, 0x47, 0x56, 0x9D, + 0xE2, 0xD5, 0xFB, 0x81, 0x61, 0x8C, 0xCC, 0x4D, 0x80, 0x90, 0x34, 0x5B, + 0xB7, 0xD7, 0x14, 0x75, 0xDC, 0xD8, 0x04, 0x48, 0x9F, 0xC0, 0xC1, 0x28, + 0x88, 0xB4, 0xE9, 0x1C, 0xCA, 0xA7, 0xB1, 0xF1, 0x56, 0xB7, 0x7B, 0x49, + 0x4C, 0x59, 0xE5, 0x20, 0x15, 0xA8, 0x84, 0x02, 0x29, 0xFA, 0x38, 0x94, + 0x69, 0x9A, 0x49, 0x06, 0x8F, 0xCD, 0x1F, 0x79, 0x14, 0x17, 0x12, 0x0C, + 0x83, 0x7A, 0xDE, 0x1F, 0xB1, 0x97, 0xEE, 0xF9, 0x97, 0x78, 0x28, 0xA4, + 0xC8, 0x44, 0x92, 0xE9, 0x7D, 0x26, 0x05, 0xA6, 0x58, 0x72, 0x9B, 0x79, + 0x13, 0xD8, 0x11, 0x5F, 0xAE, 0xC5, 0x38, 0x62, 0x34, 0x68, 0xB2, 0x86, + 0x30, 0x8E, 0xF8, 0x90, 0x61, 0x9E, 0x32, 0x6C, 0xF5, 0x07, 0x36, 0xCD, + 0xA2, 0x4C, 0x6E, 0xEC, 0x8A, 0x36, 0xED, 0xF2, 0xE6, 0x99, 0x15, 0x44, + 0x70, 0xC3, 0x7C, 0xBC, 0x9C, 0x39, 0xC0, 0xB4, 0xE1, 0x6B, 0xF7, 0x83, + 0x25, 0x23, 0x57, 0xD9, 0x12, 0x80, 0xE5, 0x49, 0xF0, 0x75, 0x0F, 0xEF, + 0x8D, 0xEB, 0x1C, 0x9B, 0x54, 0x28, 0xB4, 0x21, 0x3C, 0xFC, 0x7C, 0x0A, + 0xFF, 0xEF, 0x7B, 0x6B, 0x75, 0xFF, 0x8B, 0x1D, 0xA0, 0x19, 0x05, 0xAB, + 0xFA, 0xF8, 0x2B, 0x81, 0x42, 0xE8, 0x38, 0xBA, 0xBB, 0xFB, 0xAA, 0xFD, + 0x3D, 0xE0, 0xF3, 0xCA, 0xDF, 0x4E, 0x97, 0x97, 0x29, 0xED, 0xF3, 0x18, + 0x56, 0xE9, 0xA5, 0x96, 0xAC, 0xBD, 0xC3, 0x90, 0x98, 0xB2, 0xE0, 0xF9, + 0xA2, 0xD4, 0xA6, 0x47, 0x43, 0x7C, 0x6D, 0xCF +}; + +static const unsigned char TA154_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA155_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x12, 0x48, 0x69, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA155_RSA_N[] = { + 0xF4, 0x1E, 0x7F, 0x52, 0x73, 0x32, 0x0C, 0x73, 0xE4, 0xBD, 0x13, 0x74, + 0xA3, 0xD4, 0x30, 0xA8, 0xD0, 0xAE, 0x4B, 0xD8, 0xB6, 0xDF, 0x75, 0x47, + 0x66, 0xF4, 0x7C, 0xE7, 0x39, 0x04, 0x1E, 0x6A, 0x70, 0x20, 0xD2, 0x5A, + 0x47, 0x72, 0x67, 0x55, 0xF4, 0xA5, 0xE8, 0x9D, 0xD5, 0x1E, 0x21, 0xA1, + 0xF0, 0x67, 0xBA, 0xCC, 0x21, 0x68, 0xBE, 0x44, 0x53, 0xBF, 0x8D, 0xF9, + 0xE2, 0xDC, 0x2F, 0x55, 0xC8, 0x37, 0x3F, 0x1F, 0xA4, 0xC0, 0x9C, 0xB3, + 0xE4, 0x77, 0x5C, 0xA0, 0x46, 0xFE, 0x77, 0xFA, 0x1A, 0xA0, 0x38, 0xEA, + 0xED, 0x9A, 0x72, 0xDE, 0x2B, 0xBD, 0x94, 0x57, 0x3A, 0xBA, 0xEC, 0x79, + 0xE7, 0x5F, 0x7D, 0x42, 0x64, 0x39, 0x7A, 0x26, 0x36, 0xF7, 0x24, 0xF0, + 0xD5, 0x2F, 0xBA, 0x95, 0x98, 0x11, 0x66, 0xAD, 0x97, 0x35, 0xD6, 0x75, + 0x01, 0x80, 0xE0, 0xAF, 0xF4, 0x84, 0x61, 0x8C, 0x0D, 0x1E, 0x5F, 0x7C, + 0x87, 0x96, 0x5E, 0x41, 0xAF, 0xEB, 0x87, 0xEA, 0xF8, 0x5D, 0xF1, 0x2E, + 0x88, 0x05, 0x3E, 0x4C, 0x22, 0xBB, 0xDA, 0x1F, 0x2A, 0xDD, 0x52, 0x46, + 0x64, 0x39, 0xF3, 0x42, 0xCE, 0xD9, 0x9E, 0x0C, 0xB3, 0xB0, 0x77, 0x97, + 0x64, 0x9C, 0xC0, 0xF4, 0xA3, 0x2E, 0x1F, 0x95, 0x07, 0xB0, 0x17, 0xDF, + 0x30, 0xDB, 0x00, 0x18, 0x96, 0x4C, 0xA1, 0x81, 0x4B, 0xDD, 0x04, 0x6D, + 0x53, 0xA3, 0x3D, 0xFC, 0x07, 0xAC, 0xD4, 0xC5, 0x37, 0x82, 0xEB, 0xE4, + 0x95, 0x08, 0x19, 0x28, 0x82, 0xD2, 0x42, 0x3A, 0xA3, 0xD8, 0x53, 0xEC, + 0x79, 0x89, 0x60, 0x48, 0x60, 0xC8, 0x72, 0x92, 0x50, 0xDC, 0x03, 0x8F, + 0x83, 0x3F, 0xB2, 0x42, 0x57, 0x5A, 0xDB, 0x6A, 0xE9, 0x11, 0x97, 0xDD, + 0x85, 0x28, 0xBC, 0x30, 0x4C, 0xAB, 0xE3, 0xC2, 0xB1, 0x45, 0x44, 0x47, + 0x1F, 0xE0, 0x8A, 0x16, 0x07, 0x96, 0xD2, 0x21, 0x0F, 0x53, 0xC0, 0xED, + 0xA9, 0x7E, 0xD4, 0x4E, 0xEC, 0x9B, 0x09, 0xEC, 0xAF, 0x42, 0xAC, 0x30, + 0xD6, 0xBF, 0xD1, 0x10, 0x45, 0xE0, 0xA6, 0x16, 0xB2, 0xA5, 0xC5, 0xD3, + 0x4F, 0x73, 0x94, 0x33, 0x71, 0x02, 0xA1, 0x6A, 0xA3, 0xD6, 0x33, 0x97, + 0x4F, 0x21, 0x63, 0x1E, 0x5B, 0x8F, 0xD9, 0xC1, 0x5E, 0x45, 0x71, 0x77, + 0x0F, 0x81, 0x5D, 0x5F, 0x21, 0x9A, 0xAD, 0x83, 0xCC, 0xFA, 0x5E, 0xD6, + 0x8D, 0x23, 0x5F, 0x1B, 0x3D, 0x41, 0xAF, 0x20, 0x75, 0x66, 0x5A, 0x4A, + 0xF6, 0x9F, 0xFB, 0xAB, 0x18, 0xF7, 0x71, 0xC0, 0xB6, 0x1D, 0x31, 0xEC, + 0x3B, 0x20, 0xEB, 0xCB, 0xE2, 0xB8, 0xF5, 0xAE, 0x92, 0xB2, 0xF7, 0xE1, + 0x84, 0x4B, 0xF2, 0xA2, 0xF2, 0x93, 0x9A, 0x22, 0x9E, 0xD3, 0x14, 0x6F, + 0x36, 0x54, 0xBD, 0x1F, 0x5E, 0x59, 0x15, 0xB9, 0x73, 0xA8, 0xC1, 0x7C, + 0x6F, 0x7B, 0x62, 0xE9, 0x16, 0x6C, 0x47, 0x5A, 0x65, 0xF3, 0x0E, 0x11, + 0x9B, 0x46, 0xD9, 0xFD, 0x6D, 0xDC, 0xD6, 0x9C, 0xC0, 0xB4, 0x7D, 0xA5, + 0xB0, 0xDD, 0x3F, 0x56, 0x6F, 0xA1, 0xF9, 0xF6, 0xE4, 0x12, 0x48, 0xFD, + 0x06, 0x7F, 0x12, 0x57, 0xB6, 0xA9, 0x23, 0x4F, 0x5B, 0x03, 0xC3, 0xE0, + 0x71, 0x2A, 0x23, 0xB7, 0xF7, 0xB0, 0xB1, 0x3B, 0xBC, 0x98, 0xBD, 0xD6, + 0x98, 0xA8, 0x0C, 0x6B, 0xF6, 0x8E, 0x12, 0x67, 0xA6, 0xF2, 0xB2, 0x58, + 0xE4, 0x02, 0x09, 0x13, 0x3C, 0xA9, 0xBB, 0x10, 0xB4, 0xD2, 0x30, 0x45, + 0xF1, 0xEC, 0xF7, 0x00, 0x11, 0xDF, 0x65, 0xF8, 0xDC, 0x2B, 0x43, 0x55, + 0xBF, 0x16, 0x97, 0xC4, 0x0F, 0xD5, 0x2C, 0x61, 0x84, 0xAA, 0x72, 0x86, + 0xFE, 0xE6, 0x3A, 0x7E, 0xC2, 0x3F, 0x7D, 0xEE, 0xFC, 0x2F, 0x14, 0x3E, + 0xE6, 0x85, 0xDD, 0x50, 0x6F, 0xB7, 0x49, 0xED +}; + +static const unsigned char TA155_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA156_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x30, 0x30, 0x2E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x27, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x61, + 0x6E, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0C, 0x43, 0x46, 0x43, 0x41, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA156_RSA_N[] = { + 0xD7, 0x5D, 0x6B, 0xCD, 0x10, 0x3F, 0x1F, 0x05, 0x59, 0xD5, 0x05, 0x4D, + 0x37, 0xB1, 0x0E, 0xEC, 0x98, 0x2B, 0x8E, 0x15, 0x1D, 0xFA, 0x93, 0x4B, + 0x17, 0x82, 0x21, 0x71, 0x10, 0x52, 0xD7, 0x51, 0x64, 0x70, 0x16, 0xC2, + 0x55, 0x69, 0x4D, 0x8E, 0x15, 0x6D, 0x9F, 0xBF, 0x0C, 0x1B, 0xC2, 0xE0, + 0xA3, 0x67, 0xD6, 0x0C, 0xAC, 0xCF, 0x22, 0xAE, 0xAF, 0x77, 0x54, 0x2A, + 0x4B, 0x4C, 0x8A, 0x53, 0x52, 0x7A, 0xC3, 0xEE, 0x2E, 0xDE, 0xB3, 0x71, + 0x25, 0xC1, 0xE9, 0x5D, 0x3D, 0xEE, 0xA1, 0x2F, 0xA3, 0xF7, 0x2A, 0x3C, + 0xC9, 0x23, 0x1D, 0x6A, 0xAB, 0x1D, 0xA1, 0xA7, 0xF1, 0xF3, 0xEC, 0xA0, + 0xD5, 0x44, 0xCF, 0x15, 0xCF, 0x72, 0x2F, 0x1D, 0x63, 0x97, 0xE8, 0x99, + 0xF9, 0xFD, 0x93, 0xA4, 0x54, 0x80, 0x4C, 0x52, 0xD4, 0x52, 0xAB, 0x2E, + 0x49, 0xDF, 0x90, 0xCD, 0xB8, 0x5F, 0xBE, 0x3F, 0xDE, 0xA1, 0xCA, 0x4D, + 0x20, 0xD4, 0x25, 0xE8, 0x84, 0x29, 0x53, 0xB7, 0xB1, 0x88, 0x1F, 0xFF, + 0xFA, 0xDA, 0x90, 0x9F, 0x0A, 0xA9, 0x2D, 0x41, 0x3F, 0xB1, 0xF1, 0x18, + 0x29, 0xEE, 0x16, 0x59, 0x2C, 0x34, 0x49, 0x1A, 0xA8, 0x06, 0xD7, 0xA8, + 0x88, 0xD2, 0x03, 0x72, 0x7A, 0x32, 0xE2, 0xEA, 0x68, 0x4D, 0x6E, 0x2C, + 0x96, 0x65, 0x7B, 0xCA, 0x59, 0xFA, 0xF2, 0xE2, 0xDD, 0xEE, 0x30, 0x2C, + 0xFB, 0xCC, 0x46, 0xAC, 0xC4, 0x63, 0xEB, 0x6F, 0x7F, 0x36, 0x2B, 0x34, + 0x73, 0x12, 0x94, 0x7F, 0xDF, 0xCC, 0x26, 0x9E, 0xF1, 0x72, 0x5D, 0x50, + 0x65, 0x59, 0x8F, 0x69, 0xB3, 0x87, 0x5E, 0x32, 0x6F, 0xC3, 0x18, 0x8A, + 0xB5, 0x95, 0x8F, 0xB0, 0x7A, 0x37, 0xDE, 0x5A, 0x45, 0x3B, 0xC7, 0x36, + 0xE1, 0xEF, 0x67, 0xD1, 0x39, 0xD3, 0x97, 0x5B, 0x73, 0x62, 0x19, 0x48, + 0x2D, 0x87, 0x1C, 0x06, 0xFB, 0x74, 0x98, 0x20, 0x49, 0x73, 0xF0, 0x05, + 0xD2, 0x1B, 0xB1, 0xA0, 0xA3, 0xB7, 0x1B, 0x70, 0xD3, 0x88, 0x69, 0xB9, + 0x5A, 0xD6, 0x38, 0xF4, 0x62, 0xDC, 0x25, 0x8B, 0x78, 0xBF, 0xF8, 0xE8, + 0x7E, 0xB8, 0x5C, 0xC9, 0x95, 0x4F, 0x5F, 0xA7, 0x2D, 0xB9, 0x20, 0x6B, + 0xCF, 0x6B, 0xDD, 0xF5, 0x0D, 0xF4, 0x82, 0xB7, 0xF4, 0xB2, 0x66, 0x2E, + 0x10, 0x28, 0xF6, 0x97, 0x5A, 0x7B, 0x96, 0x16, 0x8F, 0x01, 0x19, 0x2D, + 0x6C, 0x6E, 0x7F, 0x39, 0x58, 0x06, 0x64, 0x83, 0x01, 0x83, 0x83, 0xC3, + 0x4D, 0x92, 0xDD, 0x32, 0xC6, 0x87, 0xA4, 0x37, 0xE9, 0x16, 0xCE, 0xAA, + 0x2D, 0x68, 0xAF, 0x0A, 0x81, 0x65, 0x3A, 0x70, 0xC1, 0x9B, 0xAD, 0x4D, + 0x6D, 0x54, 0xCA, 0x2A, 0x2D, 0x4B, 0x85, 0x1B, 0xB3, 0x80, 0xE6, 0x70, + 0x45, 0x0D, 0x6B, 0x5E, 0x35, 0xF0, 0x7F, 0x3B, 0xB8, 0x9C, 0xE4, 0x04, + 0x70, 0x89, 0x12, 0x25, 0x93, 0xDA, 0x0A, 0x99, 0x22, 0x60, 0x6A, 0x63, + 0x60, 0x4E, 0x76, 0x06, 0x98, 0x4E, 0xBD, 0x83, 0xAD, 0x1D, 0x58, 0x8A, + 0x25, 0x85, 0xD2, 0xC7, 0x65, 0x1E, 0x2D, 0x8E, 0xC6, 0xDF, 0xB6, 0xC6, + 0xE1, 0x7F, 0x8A, 0x04, 0x21, 0x15, 0x29, 0x74, 0xF0, 0x3E, 0x9C, 0x90, + 0x9D, 0x0C, 0x2E, 0xF1, 0x8A, 0x3E, 0x5A, 0xAA, 0x0C, 0x09, 0x1E, 0xC7, + 0xD5, 0x3C, 0xA3, 0xED, 0x97, 0xC3, 0x1E, 0x34, 0xFA, 0x38, 0xF9, 0x08, + 0x0E, 0xE3, 0xC0, 0x5D, 0x2B, 0x83, 0xD1, 0x56, 0x6A, 0xC9, 0xB6, 0xA8, + 0x54, 0x53, 0x2E, 0x78, 0x32, 0x67, 0x3D, 0x82, 0x7F, 0x74, 0xD0, 0xFB, + 0xE1, 0xB6, 0x05, 0x60, 0xB9, 0x70, 0xDB, 0x8E, 0x0B, 0xF9, 0x13, 0x58, + 0x6F, 0x71, 0x60, 0x10, 0x52, 0x10, 0xB9, 0xC1, 0x41, 0x09, 0xEF, 0x72, + 0x1F, 0x67, 0x31, 0x78, 0xFF, 0x96, 0x05, 0x8D +}; + +static const unsigned char TA156_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA157_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x54, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x05, 0x4D, 0x69, 0x6C, 0x61, 0x6E, 0x31, 0x23, 0x30, 0x21, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x1A, 0x41, 0x63, 0x74, 0x61, 0x6C, 0x69, + 0x73, 0x20, 0x53, 0x2E, 0x70, 0x2E, 0x41, 0x2E, 0x2F, 0x30, 0x33, 0x33, + 0x35, 0x38, 0x35, 0x32, 0x30, 0x39, 0x36, 0x37, 0x31, 0x27, 0x30, 0x25, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x41, 0x63, 0x74, 0x61, 0x6C, + 0x69, 0x73, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA157_RSA_N[] = { + 0xA7, 0xC6, 0xC4, 0xA5, 0x29, 0xA4, 0x2C, 0xEF, 0xE5, 0x18, 0xC5, 0xB0, + 0x50, 0xA3, 0x6F, 0x51, 0x3B, 0x9F, 0x0A, 0x5A, 0xC9, 0xC2, 0x48, 0x38, + 0x0A, 0xC2, 0x1C, 0xA0, 0x18, 0x7F, 0x91, 0xB5, 0x87, 0xB9, 0x40, 0x3F, + 0xDD, 0x1D, 0x68, 0x1F, 0x08, 0x83, 0xD5, 0x2D, 0x1E, 0x88, 0xA0, 0xF8, + 0x8F, 0x56, 0x8F, 0x6D, 0x99, 0x02, 0x92, 0x90, 0x16, 0xD5, 0x5F, 0x08, + 0x6C, 0x89, 0xD7, 0xE1, 0xAC, 0xBC, 0x20, 0xC2, 0xB1, 0xE0, 0x83, 0x51, + 0x8A, 0x69, 0x4D, 0x00, 0x96, 0x5A, 0x6F, 0x2F, 0xC0, 0x44, 0x7E, 0xA3, + 0x0E, 0xE4, 0x91, 0xCD, 0x58, 0xEE, 0xDC, 0xFB, 0xC7, 0x1E, 0x45, 0x47, + 0xDD, 0x27, 0xB9, 0x08, 0x01, 0x9F, 0xA6, 0x21, 0x1D, 0xF5, 0x41, 0x2D, + 0x2F, 0x4C, 0xFD, 0x28, 0xAD, 0xE0, 0x8A, 0xAD, 0x22, 0xB4, 0x56, 0x65, + 0x8E, 0x86, 0x54, 0x8F, 0x93, 0x43, 0x29, 0xDE, 0x39, 0x46, 0x78, 0xA3, + 0x30, 0x23, 0xBA, 0xCD, 0xF0, 0x7D, 0x13, 0x57, 0xC0, 0x5D, 0xD2, 0x83, + 0x6B, 0x48, 0x4C, 0xC4, 0xAB, 0x9F, 0x80, 0x5A, 0x5B, 0x3A, 0xBD, 0xC9, + 0xA7, 0x22, 0x3F, 0x80, 0x27, 0x33, 0x5B, 0x0E, 0xB7, 0x8A, 0x0C, 0x5D, + 0x07, 0x37, 0x08, 0xCB, 0x6C, 0xD2, 0x7A, 0x47, 0x22, 0x44, 0x35, 0xC5, + 0xCC, 0xCC, 0x2E, 0x8E, 0xDD, 0x2A, 0xED, 0xB7, 0x7D, 0x66, 0x0D, 0x5F, + 0x61, 0x51, 0x22, 0x55, 0x1B, 0xE3, 0x46, 0xE3, 0xE3, 0x3D, 0xD0, 0x35, + 0x62, 0x9A, 0xDB, 0xAF, 0x14, 0xC8, 0x5B, 0xA1, 0xCC, 0x89, 0x1B, 0xE1, + 0x30, 0x26, 0xFC, 0xA0, 0x9B, 0x1F, 0x81, 0xA7, 0x47, 0x1F, 0x04, 0xEB, + 0xA3, 0x39, 0x92, 0x06, 0x9F, 0x99, 0xD3, 0xBF, 0xD3, 0xEA, 0x4F, 0x50, + 0x9C, 0x19, 0xFE, 0x96, 0x87, 0x1E, 0x3C, 0x65, 0xF6, 0xA3, 0x18, 0x24, + 0x83, 0x86, 0x10, 0xE7, 0x54, 0x3E, 0xA8, 0x3A, 0x76, 0x24, 0x4F, 0x81, + 0x21, 0xC5, 0xE3, 0x0F, 0x02, 0xF8, 0x93, 0x94, 0x47, 0x20, 0xBB, 0xFE, + 0xD4, 0x0E, 0xD3, 0x68, 0xB9, 0xDD, 0xC4, 0x7A, 0x84, 0x82, 0xE3, 0x53, + 0x54, 0x79, 0xDD, 0xDB, 0x9C, 0xD2, 0xF2, 0x07, 0x9B, 0x2E, 0xB6, 0xBC, + 0x3E, 0xED, 0x85, 0x6D, 0xEF, 0x25, 0x11, 0xF2, 0x97, 0x1A, 0x42, 0x61, + 0xF7, 0x4A, 0x97, 0xE8, 0x8B, 0xB1, 0x10, 0x07, 0xFA, 0x65, 0x81, 0xB2, + 0xA2, 0x39, 0xCF, 0xF7, 0x3C, 0xFF, 0x18, 0xFB, 0xC6, 0xF1, 0x5A, 0x8B, + 0x59, 0xE2, 0x02, 0xAC, 0x7B, 0x92, 0xD0, 0x4E, 0x14, 0x4F, 0x59, 0x45, + 0xF6, 0x0C, 0x5E, 0x28, 0x5F, 0xB0, 0xE8, 0x3F, 0x45, 0xCF, 0xCF, 0xAF, + 0x9B, 0x6F, 0xFB, 0x84, 0xD3, 0x77, 0x5A, 0x95, 0x6F, 0xAC, 0x94, 0x84, + 0x9E, 0xEE, 0xBC, 0xC0, 0x4A, 0x8F, 0x4A, 0x93, 0xF8, 0x44, 0x21, 0xE2, + 0x31, 0x45, 0x61, 0x50, 0x4E, 0x10, 0xD8, 0xE3, 0x35, 0x7C, 0x4C, 0x19, + 0xB4, 0xDE, 0x05, 0xBF, 0xA3, 0x06, 0x9F, 0xC8, 0xB5, 0xCD, 0xE4, 0x1F, + 0xD7, 0x17, 0x06, 0x0D, 0x7A, 0x95, 0x74, 0x55, 0x0D, 0x68, 0x1A, 0xFC, + 0x10, 0x1B, 0x62, 0x64, 0x9D, 0x6D, 0xE0, 0x95, 0xA0, 0xC3, 0x94, 0x07, + 0x57, 0x0D, 0x14, 0xE6, 0xBD, 0x05, 0xFB, 0xB8, 0x9F, 0xE6, 0xDF, 0x8B, + 0xE2, 0xC6, 0xE7, 0x7E, 0x96, 0xF6, 0x53, 0xC5, 0x80, 0x34, 0x50, 0x28, + 0x58, 0xF0, 0x12, 0x50, 0x71, 0x17, 0x30, 0xBA, 0xE6, 0x78, 0x63, 0xBC, + 0xF4, 0xB2, 0xAD, 0x9B, 0x2B, 0xB2, 0xFE, 0xE1, 0x39, 0x8C, 0x5E, 0xBA, + 0x0B, 0x20, 0x94, 0xDE, 0x7B, 0x83, 0xB8, 0xFF, 0xE3, 0x56, 0x8D, 0xB7, + 0x11, 0xE9, 0x3B, 0x8C, 0xF2, 0xB1, 0xC1, 0x5D, 0x9D, 0xA4, 0x0B, 0x4C, + 0x2B, 0xD9, 0xB2, 0x18, 0xF5, 0xB5, 0x9F, 0x4B +}; + +static const unsigned char TA157_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA158_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA158_RSA_N[] = { + 0xCC, 0x57, 0x42, 0x16, 0x54, 0x9C, 0xE6, 0x98, 0xD3, 0xD3, 0x4D, 0xEE, + 0xFE, 0xED, 0xC7, 0x9F, 0x43, 0x39, 0x4A, 0x65, 0xB3, 0xE8, 0x16, 0x88, + 0x34, 0xDB, 0x0D, 0x59, 0x91, 0x74, 0xCF, 0x92, 0xB8, 0x04, 0x40, 0xAD, + 0x02, 0x4B, 0x31, 0xAB, 0xBC, 0x8D, 0x91, 0x68, 0xD8, 0x20, 0x0E, 0x1A, + 0x01, 0xE2, 0x1A, 0x7B, 0x4E, 0x17, 0x5D, 0xE2, 0x8A, 0xB7, 0x3F, 0x99, + 0x1A, 0xCD, 0xEB, 0x61, 0xAB, 0xC2, 0x65, 0xA6, 0x1F, 0xB7, 0xB7, 0xBD, + 0xB7, 0x8F, 0xFC, 0xFD, 0x70, 0x8F, 0x0B, 0xA0, 0x67, 0xBE, 0x01, 0xA2, + 0x59, 0xCF, 0x71, 0xE6, 0x0F, 0x29, 0x76, 0xFF, 0xB1, 0x56, 0x79, 0x45, + 0x2B, 0x1F, 0x9E, 0x7A, 0x54, 0xE8, 0xA3, 0x29, 0x35, 0x68, 0xA4, 0x01, + 0x4F, 0x0F, 0xA4, 0x2E, 0x37, 0xEF, 0x1B, 0xBF, 0xE3, 0x8F, 0x10, 0xA8, + 0x72, 0xAB, 0x58, 0x57, 0xE7, 0x54, 0x86, 0xC8, 0xC9, 0xF3, 0x5B, 0xDA, + 0x2C, 0xDA, 0x5D, 0x8E, 0x6E, 0x3C, 0xA3, 0x3E, 0xDA, 0xFB, 0x82, 0xE5, + 0xDD, 0xF2, 0x5C, 0xB2, 0x05, 0x33, 0x6F, 0x8A, 0x36, 0xCE, 0xD0, 0x13, + 0x4E, 0xFF, 0xBF, 0x4A, 0x0C, 0x34, 0x4C, 0xA6, 0xC3, 0x21, 0xBD, 0x50, + 0x04, 0x55, 0xEB, 0xB1, 0xBB, 0x9D, 0xFB, 0x45, 0x1E, 0x64, 0x15, 0xDE, + 0x55, 0x01, 0x8C, 0x02, 0x76, 0xB5, 0xCB, 0xA1, 0x3F, 0x42, 0x69, 0xBC, + 0x2F, 0xBD, 0x68, 0x43, 0x16, 0x56, 0x89, 0x2A, 0x37, 0x61, 0x91, 0xFD, + 0xA6, 0xAE, 0x4E, 0xC0, 0xCB, 0x14, 0x65, 0x94, 0x37, 0x4B, 0x92, 0x06, + 0xEF, 0x04, 0xD0, 0xC8, 0x9C, 0x88, 0xDB, 0x0B, 0x7B, 0x81, 0xAF, 0xB1, + 0x3D, 0x2A, 0xC4, 0x65, 0x3A, 0x78, 0xB6, 0xEE, 0xDC, 0x80, 0xB1, 0xD2, + 0xD3, 0x99, 0x9C, 0x3A, 0xEE, 0x6B, 0x5A, 0x6B, 0xB3, 0x8D, 0xB7, 0xD5, + 0xCE, 0x9C, 0xC2, 0xBE, 0xA5, 0x4B, 0x2F, 0x16, 0xB1, 0x9E, 0x68, 0x3B, + 0x06, 0x6F, 0xAE, 0x7D, 0x9F, 0xF8, 0xDE, 0xEC, 0xCC, 0x29, 0xA7, 0x98, + 0xA3, 0x25, 0x43, 0x2F, 0xEF, 0xF1, 0x5F, 0x26, 0xE1, 0x88, 0x4D, 0xF8, + 0x5E, 0x6E, 0xD7, 0xD9, 0x14, 0x6E, 0x19, 0x33, 0x69, 0xA7, 0x3B, 0x84, + 0x89, 0x93, 0xC4, 0x53, 0x55, 0x13, 0xA1, 0x51, 0x78, 0x40, 0xF8, 0xB8, + 0xC9, 0xA2, 0xEE, 0x7B, 0xBA, 0x52, 0x42, 0x83, 0x9E, 0x14, 0xED, 0x05, + 0x52, 0x5A, 0x59, 0x56, 0xA7, 0x97, 0xFC, 0x9D, 0x3F, 0x0A, 0x29, 0xD8, + 0xDC, 0x4F, 0x91, 0x0E, 0x13, 0xBC, 0xDE, 0x95, 0xA4, 0xDF, 0x8B, 0x99, + 0xBE, 0xAC, 0x9B, 0x33, 0x88, 0xEF, 0xB5, 0x81, 0xAF, 0x1B, 0xC6, 0x22, + 0x53, 0xC8, 0xF6, 0xC7, 0xEE, 0x97, 0x14, 0xB0, 0xC5, 0x7C, 0x78, 0x52, + 0xC8, 0xF0, 0xCE, 0x6E, 0x77, 0x60, 0x84, 0xA6, 0xE9, 0x2A, 0x76, 0x20, + 0xED, 0x58, 0x01, 0x17, 0x30, 0x93, 0xE9, 0x1A, 0x8B, 0xE0, 0x73, 0x63, + 0xD9, 0x6A, 0x92, 0x94, 0x49, 0x4E, 0xB4, 0xAD, 0x4A, 0x85, 0xC4, 0xA3, + 0x22, 0x30, 0xFC, 0x09, 0xED, 0x68, 0x22, 0x73, 0xA6, 0x88, 0x0C, 0x55, + 0x21, 0x58, 0xC5, 0xE1, 0x3A, 0x9F, 0x2A, 0xDD, 0xCA, 0xE1, 0x90, 0xE0, + 0xD9, 0x73, 0xAB, 0x6C, 0x80, 0xB8, 0xE8, 0x0B, 0x64, 0x93, 0xA0, 0x9C, + 0x8C, 0x19, 0xFF, 0xB3, 0xD2, 0x0C, 0xEC, 0x91, 0x26, 0x87, 0x8A, 0xB3, + 0xA2, 0xE1, 0x70, 0x8F, 0x2C, 0x0A, 0xE5, 0xCD, 0x6D, 0x68, 0x51, 0xEB, + 0xDA, 0x3F, 0x05, 0x7F, 0x8B, 0x32, 0xE6, 0x13, 0x5C, 0x6B, 0xFE, 0x5F, + 0x40, 0xE2, 0x22, 0xC8, 0xB4, 0xB4, 0x64, 0x4F, 0xD6, 0xBA, 0x7D, 0x48, + 0x3E, 0xA8, 0x69, 0x0C, 0xD7, 0xBB, 0x86, 0x71, 0xC9, 0x73, 0xB8, 0x3F, + 0x3B, 0x9D, 0x25, 0x4B, 0xDA, 0xFF, 0x40, 0xEB +}; + +static const unsigned char TA158_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA159_DN[] = { + 0x30, 0x81, 0x84, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x05, + 0x13, 0x09, 0x47, 0x36, 0x33, 0x32, 0x38, 0x37, 0x35, 0x31, 0x30, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, + 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1E, 0x41, + 0x4E, 0x46, 0x20, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, + 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x63, 0x69, 0x6F, 0x6E, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x13, 0x0B, 0x41, 0x4E, 0x46, 0x20, 0x43, 0x41, 0x20, 0x52, + 0x61, 0x69, 0x7A, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x19, 0x41, 0x4E, 0x46, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA159_RSA_N[] = { + 0xDB, 0xEB, 0x6B, 0x2B, 0xE6, 0x64, 0x54, 0x95, 0x82, 0x90, 0xA3, 0x72, + 0xA4, 0x19, 0x01, 0x9D, 0x9C, 0x0B, 0x81, 0x5F, 0x73, 0x49, 0xBA, 0xA7, + 0xAC, 0xF3, 0x04, 0x4E, 0x7B, 0x96, 0x0B, 0xEC, 0x11, 0xE0, 0x5B, 0xA6, + 0x1C, 0xCE, 0x1B, 0xD2, 0x0D, 0x83, 0x1C, 0x2B, 0xB8, 0x9E, 0x1D, 0x7E, + 0x45, 0x32, 0x60, 0x0F, 0x07, 0xE9, 0x77, 0x58, 0x7E, 0x9F, 0x6A, 0xC8, + 0x61, 0x4E, 0xB6, 0x26, 0xC1, 0x4C, 0x8D, 0xFF, 0x4C, 0xEF, 0x34, 0xB2, + 0x1F, 0x65, 0xD8, 0xB9, 0x78, 0xF5, 0xAD, 0xA9, 0x71, 0xB9, 0xEF, 0x4F, + 0x58, 0x1D, 0xA5, 0xDE, 0x74, 0x20, 0x97, 0xA1, 0xED, 0x68, 0x4C, 0xDE, + 0x92, 0x17, 0x4B, 0xBC, 0xAB, 0xFF, 0x65, 0x9A, 0x9E, 0xFB, 0x47, 0xD9, + 0x57, 0x72, 0xF3, 0x09, 0xA1, 0xAE, 0x76, 0x44, 0x13, 0x6E, 0x9C, 0x2D, + 0x44, 0x39, 0xBC, 0xF9, 0xC7, 0x3B, 0xA4, 0x58, 0x3D, 0x41, 0xBD, 0xB4, + 0xC2, 0x49, 0xA3, 0xC8, 0x0D, 0xD2, 0x97, 0x2F, 0x07, 0x65, 0x52, 0x00, + 0xA7, 0x6E, 0xC8, 0xAF, 0x68, 0xEC, 0xF4, 0x14, 0x96, 0xB6, 0x57, 0x1F, + 0x56, 0xC3, 0x39, 0x9F, 0x2B, 0x6D, 0xE4, 0xF3, 0x3E, 0xF6, 0x35, 0x64, + 0xDA, 0x0C, 0x1C, 0xA1, 0x84, 0x4B, 0x2F, 0x4B, 0x4B, 0xE2, 0x2C, 0x24, + 0x9D, 0x6D, 0x93, 0x40, 0xEB, 0xB5, 0x23, 0x8E, 0x32, 0xCA, 0x6F, 0x45, + 0xD3, 0xA8, 0x89, 0x7B, 0x1E, 0xCF, 0x1E, 0xFA, 0x5B, 0x43, 0x8B, 0xCD, + 0xCD, 0xA8, 0x0F, 0x6A, 0xCA, 0x0C, 0x5E, 0xB9, 0x9E, 0x47, 0x8F, 0xF0, + 0xD9, 0xB6, 0x0A, 0x0B, 0x58, 0x65, 0x17, 0x33, 0xB9, 0x23, 0xE4, 0x77, + 0x19, 0x7D, 0xCB, 0x4A, 0x2E, 0x92, 0x7B, 0x4F, 0x2F, 0x10, 0x77, 0xB1, + 0x8D, 0x2F, 0x68, 0x9C, 0x62, 0xCC, 0xE0, 0x50, 0xF8, 0xEC, 0x91, 0xA7, + 0x54, 0x4C, 0x57, 0x09, 0xD5, 0x76, 0x63, 0xC5, 0xE8, 0x65, 0x1E, 0xEE, + 0x6D, 0x6A, 0xCF, 0x09, 0x9D, 0xFA, 0x7C, 0x4F, 0xAD, 0x60, 0x08, 0xFD, + 0x56, 0x99, 0x0F, 0x15, 0x2C, 0x7B, 0xA9, 0x80, 0xAB, 0x8C, 0x61, 0x8F, + 0x4A, 0x07, 0x76, 0x42, 0xDE, 0x3D, 0xF4, 0xDD, 0xB2, 0x24, 0x33, 0x5B, + 0xB8, 0xB5, 0xA3, 0x44, 0xC9, 0xAC, 0x7F, 0x77, 0x3C, 0x1D, 0x23, 0xEC, + 0x82, 0xA9, 0xA6, 0xE2, 0xC8, 0x06, 0x4C, 0x02, 0xFE, 0xAC, 0x5C, 0x99, + 0x99, 0x0B, 0x2F, 0x10, 0x8A, 0xA6, 0xF4, 0x7F, 0xD5, 0x87, 0x74, 0x0D, + 0x59, 0x49, 0x45, 0xF6, 0xF0, 0x71, 0x5C, 0x39, 0x29, 0xD6, 0xBF, 0x4A, + 0x23, 0x8B, 0xF5, 0x5F, 0x01, 0x63, 0xD2, 0x87, 0x73, 0x28, 0xB5, 0x4B, + 0x0A, 0xF5, 0xF8, 0xAB, 0x82, 0x2C, 0x7E, 0x73, 0x25, 0x32, 0x1D, 0x0B, + 0x63, 0x0A, 0x17, 0x81, 0x00, 0xFF, 0xB6, 0x76, 0x5E, 0xE7, 0xB4, 0xB1, + 0x40, 0xCA, 0x21, 0xBB, 0xD5, 0x80, 0x51, 0xE5, 0x48, 0x52, 0x67, 0x2C, + 0xD2, 0x61, 0x89, 0x07, 0x0D, 0x0F, 0xCE, 0x42, 0x77, 0xC0, 0x44, 0x73, + 0x9C, 0x44, 0x50, 0xA0, 0xDB, 0x10, 0x0A, 0x2D, 0x95, 0x1C, 0x81, 0xAF, + 0xE4, 0x1C, 0xE5, 0x14, 0x1E, 0xF1, 0x36, 0x41, 0x01, 0x02, 0x2F, 0x7D, + 0x73, 0xA7, 0xDE, 0x42, 0xCC, 0x4C, 0xE9, 0x89, 0x0D, 0x56, 0xF7, 0x9F, + 0x91, 0xD4, 0x03, 0xC6, 0x6C, 0xC9, 0x8F, 0xDB, 0xD8, 0x1C, 0xE0, 0x40, + 0x98, 0x5D, 0x66, 0x99, 0x98, 0x80, 0x6E, 0x2D, 0xFF, 0x01, 0xC5, 0xCE, + 0xCB, 0x46, 0x1F, 0xAC, 0x02, 0xC6, 0x43, 0xE6, 0xAE, 0xA2, 0x84, 0x3C, + 0xC5, 0x4E, 0x1E, 0x3D, 0x6D, 0xC9, 0x14, 0x4C, 0xE3, 0x2E, 0x41, 0xBB, + 0xCA, 0x39, 0xBF, 0x36, 0x3C, 0x2A, 0x19, 0xAA, 0x41, 0x87, 0x4E, 0xA5, + 0xCE, 0x4B, 0x32, 0x79, 0xDD, 0x90, 0x49, 0x7F +}; + +static const unsigned char TA159_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA160_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, 0x67 +}; + +static const unsigned char TA160_RSA_N[] = { + 0xB4, 0x84, 0xCC, 0x33, 0x17, 0x2E, 0x6B, 0x94, 0x6C, 0x6B, 0x61, 0x52, + 0xA0, 0xEB, 0xA3, 0xCF, 0x79, 0x94, 0x4C, 0xE5, 0x94, 0x80, 0x99, 0xCB, + 0x55, 0x64, 0x44, 0x65, 0x8F, 0x67, 0x64, 0xE2, 0x06, 0xE3, 0x5C, 0x37, + 0x49, 0xF6, 0x2F, 0x9B, 0x84, 0x84, 0x1E, 0x2D, 0xF2, 0x60, 0x9D, 0x30, + 0x4E, 0xCC, 0x84, 0x85, 0xE2, 0x2C, 0xCF, 0x1E, 0x9E, 0xFE, 0x36, 0xAB, + 0x33, 0x77, 0x35, 0x44, 0xD8, 0x35, 0x96, 0x1A, 0x3D, 0x36, 0xE8, 0x7A, + 0x0E, 0xD8, 0xD5, 0x47, 0xA1, 0x6A, 0x69, 0x8B, 0xD9, 0xFC, 0xBB, 0x3A, + 0xAE, 0x79, 0x5A, 0xD5, 0xF4, 0xD6, 0x71, 0xBB, 0x9A, 0x90, 0x23, 0x6B, + 0x9A, 0xB7, 0x88, 0x74, 0x87, 0x0C, 0x1E, 0x5F, 0xB9, 0x9E, 0x2D, 0xFA, + 0xAB, 0x53, 0x2B, 0xDC, 0xBB, 0x76, 0x3E, 0x93, 0x4C, 0x08, 0x08, 0x8C, + 0x1E, 0xA2, 0x23, 0x1C, 0xD4, 0x6A, 0xAD, 0x22, 0xBA, 0x99, 0x01, 0x2E, + 0x6D, 0x65, 0xCB, 0xBE, 0x24, 0x66, 0x55, 0x24, 0x4B, 0x40, 0x44, 0xB1, + 0x1B, 0xD7, 0xE1, 0xC2, 0x85, 0xC0, 0xDE, 0x10, 0x3F, 0x3D, 0xED, 0xB8, + 0xFC, 0xF1, 0xF1, 0x23, 0x53, 0xDC, 0xBF, 0x65, 0x97, 0x6F, 0xD9, 0xF9, + 0x40, 0x71, 0x8D, 0x7D, 0xBD, 0x95, 0xD4, 0xCE, 0xBE, 0xA0, 0x5E, 0x27, + 0x23, 0xDE, 0xFD, 0xA6, 0xD0, 0x26, 0x0E, 0x00, 0x29, 0xEB, 0x3C, 0x46, + 0xF0, 0x3D, 0x60, 0xBF, 0x3F, 0x50, 0xD2, 0xDC, 0x26, 0x41, 0x51, 0x9E, + 0x14, 0x37, 0x42, 0x04, 0xA3, 0x70, 0x57, 0xA8, 0x1B, 0x87, 0xED, 0x2D, + 0xFA, 0x7B, 0xEE, 0x8C, 0x0A, 0xE3, 0xA9, 0x66, 0x89, 0x19, 0xCB, 0x41, + 0xF9, 0xDD, 0x44, 0x36, 0x61, 0xCF, 0xE2, 0x77, 0x46, 0xC8, 0x7D, 0xF6, + 0xF4, 0x92, 0x81, 0x36, 0xFD, 0xDB, 0x34, 0xF1, 0x72, 0x7E, 0xF3, 0x0C, + 0x16, 0xBD, 0xB4, 0x15 +}; + +static const unsigned char TA160_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA161_DN[] = { + 0x30, 0x81, 0xAA, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x44, 0x30, 0x42, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, + 0x20, 0x32, 0x30, 0x31, 0x35 +}; + +static const unsigned char TA161_EC_Q[] = { + 0x04, 0x92, 0xA0, 0x41, 0xE8, 0x4B, 0x82, 0x84, 0x5C, 0xE2, 0xF8, 0x31, + 0x11, 0x99, 0x86, 0x64, 0x4E, 0x09, 0x25, 0x2F, 0x9D, 0x41, 0x2F, 0x0A, + 0xAE, 0x35, 0x4F, 0x74, 0x95, 0xB2, 0x51, 0x64, 0x6B, 0x8D, 0x6B, 0xE6, + 0x3F, 0x70, 0x95, 0xF0, 0x05, 0x44, 0x47, 0xA6, 0x72, 0x38, 0x50, 0x76, + 0x95, 0x02, 0x5A, 0x8E, 0xAE, 0x28, 0x9E, 0xF9, 0x2D, 0x4E, 0x99, 0xEF, + 0x2C, 0x48, 0x6F, 0x4C, 0x25, 0x29, 0xE8, 0xD1, 0x71, 0x5B, 0xDF, 0x1D, + 0xC1, 0x75, 0x37, 0xB4, 0xD7, 0xFA, 0x7B, 0x7A, 0x42, 0x9C, 0x6A, 0x0A, + 0x56, 0x5A, 0x7C, 0x69, 0x0B, 0xAA, 0x80, 0x09, 0x24, 0x6C, 0x7E, 0xC1, + 0x46 +}; + +static const unsigned char TA162_DN[] = { + 0x30, 0x74, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x45, 0x43, 0x2D, 0x33, 0x38, 0x34, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA162_EC_Q[] = { + 0x04, 0xC4, 0x28, 0x8E, 0xAB, 0x18, 0x5B, 0x6A, 0xBE, 0x6E, 0x64, 0x37, + 0x63, 0xE4, 0xCD, 0xEC, 0xAB, 0x3A, 0xF7, 0xCC, 0xA1, 0xB8, 0x0E, 0x82, + 0x49, 0xD7, 0x86, 0x29, 0x9F, 0xA1, 0x94, 0xF2, 0xE3, 0x60, 0x78, 0x98, + 0x81, 0x78, 0x06, 0x4D, 0xF2, 0xEC, 0x9A, 0x0E, 0x57, 0x60, 0x83, 0x9F, + 0xB4, 0xE6, 0x17, 0x2F, 0x1A, 0xB3, 0x5D, 0x02, 0x5B, 0x89, 0x23, 0x3C, + 0xC2, 0x11, 0x05, 0x2A, 0xA7, 0x88, 0x13, 0x18, 0xF3, 0x50, 0x84, 0xD7, + 0xBD, 0x34, 0x2C, 0x27, 0x89, 0x55, 0xFF, 0xCE, 0x4C, 0xE7, 0xDF, 0xA6, + 0x1F, 0x28, 0xC4, 0xF0, 0x54, 0xC3, 0xB9, 0x7C, 0xB7, 0x53, 0xAD, 0xEB, + 0xC2 +}; + +static const unsigned char TA163_DN[] = { + 0x30, 0x52, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x53, 0x4B, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x0A, 0x42, 0x72, 0x61, 0x74, 0x69, 0x73, 0x6C, 0x61, 0x76, 0x61, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x61, 0x2E, 0x73, 0x2E, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x41, 0x20, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x32 +}; + +static const unsigned char TA163_RSA_N[] = { + 0xA2, 0xA3, 0xC4, 0x00, 0x09, 0xD6, 0x85, 0x5D, 0x2D, 0x6D, 0x14, 0xF6, + 0xC2, 0xC3, 0x73, 0x9E, 0x35, 0xC2, 0x71, 0x55, 0x7E, 0x81, 0xFB, 0xAB, + 0x46, 0x50, 0xE0, 0xC1, 0x7C, 0x49, 0x78, 0xE6, 0xAB, 0x79, 0x58, 0x3C, + 0xDA, 0xFF, 0x7C, 0x1C, 0x9F, 0xD8, 0x97, 0x02, 0x78, 0x3E, 0x6B, 0x41, + 0x04, 0xE9, 0x41, 0xBD, 0xBE, 0x03, 0x2C, 0x45, 0xF6, 0x2F, 0x64, 0xD4, + 0xAB, 0x5D, 0xA3, 0x47, 0x3D, 0x64, 0x9B, 0xE9, 0x68, 0x9A, 0xC6, 0xCC, + 0x1B, 0x3F, 0xBA, 0xBE, 0xB2, 0x8B, 0x34, 0x02, 0x2E, 0x98, 0x55, 0x19, + 0xFC, 0x8C, 0x6F, 0xAA, 0x5F, 0xDA, 0x4C, 0xCE, 0x4D, 0x03, 0x21, 0xA3, + 0xD8, 0xD2, 0x34, 0x93, 0x56, 0x96, 0xCB, 0x4C, 0x0C, 0x00, 0x16, 0x3C, + 0x5F, 0x1A, 0xCD, 0xC8, 0xC7, 0x6C, 0xA6, 0xAD, 0xD3, 0x31, 0xA7, 0xBC, + 0xE8, 0xE5, 0xE1, 0x66, 0xD6, 0xD2, 0xFB, 0x03, 0xB4, 0x41, 0x65, 0xC9, + 0x10, 0xAE, 0x0E, 0x05, 0x63, 0xC6, 0x80, 0x6A, 0x69, 0x30, 0xFD, 0xD2, + 0xEE, 0x90, 0xEF, 0x0D, 0x27, 0xDF, 0x9F, 0x95, 0x73, 0xF4, 0xE1, 0x25, + 0xDA, 0x6C, 0x16, 0xDE, 0x41, 0x38, 0x34, 0xEA, 0x8B, 0xFC, 0xD1, 0xE8, + 0x04, 0x14, 0x61, 0x2D, 0x41, 0x7E, 0xAC, 0xC7, 0x77, 0x4E, 0xCB, 0x51, + 0x54, 0xFB, 0x5E, 0x92, 0x18, 0x1B, 0x04, 0x5A, 0x68, 0xC6, 0xC9, 0xC4, + 0xFA, 0xB7, 0x13, 0xA0, 0x98, 0xB7, 0x11, 0x2B, 0xB7, 0xD6, 0x57, 0xCC, + 0x7C, 0x9E, 0x17, 0xD1, 0xCB, 0x25, 0xFE, 0x86, 0x4E, 0x24, 0x2E, 0x56, + 0x0C, 0x78, 0x4D, 0x9E, 0x01, 0x12, 0xA6, 0x2B, 0xA7, 0x01, 0x65, 0x6E, + 0x7C, 0x62, 0x1D, 0x84, 0x84, 0xDF, 0xEA, 0xC0, 0x6B, 0xB5, 0xA5, 0x2A, + 0x95, 0x83, 0xC3, 0x53, 0x11, 0x0C, 0x73, 0x1D, 0x0B, 0xB2, 0x46, 0x90, + 0xD1, 0x42, 0x3A, 0xCE, 0x40, 0x6E, 0x95, 0xAD, 0xFF, 0xC6, 0x94, 0xAD, + 0x6E, 0x97, 0x84, 0x8E, 0x7D, 0x6F, 0x9E, 0x8A, 0x80, 0x0D, 0x49, 0x6D, + 0x73, 0xE2, 0x7B, 0x92, 0x1E, 0xC3, 0xF3, 0xC1, 0xF3, 0xEB, 0x2E, 0x05, + 0x6F, 0xD9, 0x1B, 0xCF, 0x37, 0x76, 0x04, 0xC8, 0xB4, 0x5A, 0xE4, 0x17, + 0xA7, 0xCB, 0xDD, 0x76, 0x1F, 0xD0, 0x19, 0x76, 0xE8, 0x2C, 0x05, 0xB3, + 0xD6, 0x9C, 0x34, 0xD8, 0x96, 0xDC, 0x61, 0x87, 0x91, 0x05, 0xE4, 0x44, + 0x08, 0x33, 0xC1, 0xDA, 0xB9, 0x08, 0x65, 0xD4, 0xAE, 0xB2, 0x36, 0x0D, + 0xEB, 0xBA, 0x38, 0xBA, 0x0C, 0xE5, 0x9B, 0x9E, 0xEB, 0x8D, 0x66, 0xDD, + 0x99, 0xCF, 0xD6, 0x89, 0x41, 0xF6, 0x04, 0x92, 0x8A, 0x29, 0x29, 0x6D, + 0x6B, 0x3A, 0x1C, 0xE7, 0x75, 0x7D, 0x02, 0x71, 0x0E, 0xF3, 0xC0, 0xE7, + 0xBD, 0xCB, 0x19, 0xDD, 0x9D, 0x60, 0xB2, 0xC2, 0x66, 0x60, 0xB6, 0xB1, + 0x04, 0xEE, 0xC9, 0xE6, 0x86, 0xB9, 0x9A, 0x66, 0x40, 0xA8, 0xE7, 0x11, + 0xED, 0x81, 0x45, 0x03, 0x8B, 0xF6, 0x67, 0x59, 0xE8, 0xC1, 0x06, 0x11, + 0xBD, 0xDD, 0xCF, 0x80, 0x02, 0x4F, 0x65, 0x40, 0x78, 0x5C, 0x47, 0x50, + 0xC8, 0x9B, 0xE6, 0x1F, 0x81, 0x7B, 0xE4, 0x44, 0xA8, 0x5B, 0x85, 0x9A, + 0xE2, 0xDE, 0x5A, 0xD5, 0xC7, 0xF9, 0x3A, 0x44, 0x66, 0x4B, 0xE4, 0x32, + 0x54, 0x7C, 0xE4, 0x6C, 0x9C, 0xB3, 0x0E, 0x3D, 0x17, 0xA2, 0xB2, 0x34, + 0x12, 0xD6, 0x7E, 0xB2, 0xA8, 0x49, 0xBB, 0xD1, 0x7A, 0x28, 0x40, 0xBE, + 0xA2, 0x16, 0x1F, 0xDF, 0xE4, 0x37, 0x1F, 0x11, 0x73, 0xFB, 0x90, 0x0A, + 0x65, 0x43, 0xA2, 0x0D, 0x7C, 0xF8, 0x06, 0x01, 0x55, 0x33, 0x7D, 0xB0, + 0x0D, 0xB8, 0xF4, 0xF5, 0xAE, 0xA5, 0x42, 0x57, 0x7C, 0x36, 0x11, 0x8C, + 0x7B, 0x5E, 0xC4, 0x03, 0x9D, 0x8C, 0x79, 0x9D +}; + +static const unsigned char TA163_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA164_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA164_RSA_N[] = { + 0xCA, 0x5B, 0xBE, 0x94, 0x33, 0x8C, 0x29, 0x95, 0x91, 0x16, 0x0A, 0x95, + 0xBD, 0x47, 0x62, 0xC1, 0x89, 0xF3, 0x99, 0x36, 0xDF, 0x46, 0x90, 0xC9, + 0xA5, 0xED, 0x78, 0x6A, 0x6F, 0x47, 0x91, 0x68, 0xF8, 0x27, 0x67, 0x50, + 0x33, 0x1D, 0xA1, 0xA6, 0xFB, 0xE0, 0xE5, 0x43, 0xA3, 0x84, 0x02, 0x57, + 0x01, 0x5D, 0x9C, 0x48, 0x40, 0x82, 0x53, 0x10, 0xBC, 0xBF, 0xC7, 0x3B, + 0x68, 0x90, 0xB6, 0x82, 0x2D, 0xE5, 0xF4, 0x65, 0xD0, 0xCC, 0x6D, 0x19, + 0xCC, 0x95, 0xF9, 0x7B, 0xAC, 0x4A, 0x94, 0xAD, 0x0E, 0xDE, 0x4B, 0x43, + 0x1D, 0x87, 0x07, 0x92, 0x13, 0x90, 0x80, 0x83, 0x64, 0x35, 0x39, 0x04, + 0xFC, 0xE5, 0xE9, 0x6C, 0xB3, 0xB6, 0x1F, 0x50, 0x94, 0x38, 0x65, 0x50, + 0x5C, 0x17, 0x46, 0xB9, 0xB6, 0x85, 0xB5, 0x1C, 0xB5, 0x17, 0xE8, 0xD6, + 0x45, 0x9D, 0xD8, 0xB2, 0x26, 0xB0, 0xCA, 0xC4, 0x70, 0x4A, 0xAE, 0x60, + 0xA4, 0xDD, 0xB3, 0xD9, 0xEC, 0xFC, 0x3B, 0xD5, 0x57, 0x72, 0xBC, 0x3F, + 0xC8, 0xC9, 0xB2, 0xDE, 0x4B, 0x6B, 0xF8, 0x23, 0x6C, 0x03, 0xC0, 0x05, + 0xBD, 0x95, 0xC7, 0xCD, 0x73, 0x3B, 0x66, 0x80, 0x64, 0xE3, 0x1A, 0xAC, + 0x2E, 0xF9, 0x47, 0x05, 0xF2, 0x06, 0xB6, 0x9B, 0x73, 0xF5, 0x78, 0x33, + 0x5B, 0xC7, 0xA1, 0xFB, 0x27, 0x2A, 0xA1, 0xB4, 0x9A, 0x91, 0x8C, 0x91, + 0xD3, 0x3A, 0x82, 0x3E, 0x76, 0x40, 0xB4, 0xCD, 0x52, 0x61, 0x51, 0x70, + 0x28, 0x3F, 0xC5, 0xC5, 0x5A, 0xF2, 0xC9, 0x8C, 0x49, 0xBB, 0x14, 0x5B, + 0x4D, 0xC8, 0xFF, 0x67, 0x4D, 0x4C, 0x12, 0x96, 0xAD, 0xF5, 0xFE, 0x78, + 0xA8, 0x97, 0x87, 0xD7, 0xFD, 0x5E, 0x20, 0x80, 0xDC, 0xA1, 0x4B, 0x22, + 0xFB, 0xD4, 0x89, 0xAD, 0xBA, 0xCE, 0x47, 0x97, 0x47, 0x55, 0x7B, 0x8F, + 0x45, 0xC8, 0x67, 0x28, 0x84, 0x95, 0x1C, 0x68, 0x30, 0xEF, 0xEF, 0x49, + 0xE0, 0x35, 0x7B, 0x64, 0xE7, 0x98, 0xB0, 0x94, 0xDA, 0x4D, 0x85, 0x3B, + 0x3E, 0x55, 0xC4, 0x28, 0xAF, 0x57, 0xF3, 0x9E, 0x13, 0xDB, 0x46, 0x27, + 0x9F, 0x1E, 0xA2, 0x5E, 0x44, 0x83, 0xA4, 0xA5, 0xCA, 0xD5, 0x13, 0xB3, + 0x4B, 0x3F, 0xC4, 0xE3, 0xC2, 0xE6, 0x86, 0x61, 0xA4, 0x52, 0x30, 0xB9, + 0x7A, 0x20, 0x4F, 0x6F, 0x0F, 0x38, 0x53, 0xCB, 0x33, 0x0C, 0x13, 0x2B, + 0x8F, 0xD6, 0x9A, 0xBD, 0x2A, 0xC8, 0x2D, 0xB1, 0x1C, 0x7D, 0x4B, 0x51, + 0xCA, 0x47, 0xD1, 0x48, 0x27, 0x72, 0x5D, 0x87, 0xEB, 0xD5, 0x45, 0xE6, + 0x48, 0x65, 0x9D, 0xAF, 0x52, 0x90, 0xBA, 0x5B, 0xA2, 0x18, 0x65, 0x57, + 0x12, 0x9F, 0x68, 0xB9, 0xD4, 0x15, 0x6B, 0x94, 0xC4, 0x69, 0x22, 0x98, + 0xF4, 0x33, 0xE0, 0xED, 0xF9, 0x51, 0x8E, 0x41, 0x50, 0xC9, 0x34, 0x4F, + 0x76, 0x90, 0xAC, 0xFC, 0x38, 0xC1, 0xD8, 0xE1, 0x7B, 0xB9, 0xE3, 0xE3, + 0x94, 0xE1, 0x46, 0x69, 0xCB, 0x0E, 0x0A, 0x50, 0x6B, 0x13, 0xBA, 0xAC, + 0x0F, 0x37, 0x5A, 0xB7, 0x12, 0xB5, 0x90, 0x81, 0x1E, 0x56, 0xAE, 0x57, + 0x22, 0x86, 0xD9, 0xC9, 0xD2, 0xD1, 0xD7, 0x51, 0xE3, 0xAB, 0x3B, 0xC6, + 0x55, 0xFD, 0x1E, 0x0E, 0xD3, 0x74, 0x0A, 0xD1, 0xDA, 0xAA, 0xEA, 0x69, + 0xB8, 0x97, 0x28, 0x8F, 0x48, 0xC4, 0x07, 0xF8, 0x52, 0x43, 0x3A, 0xF4, + 0xCA, 0x55, 0x35, 0x2C, 0xB0, 0xA6, 0x6A, 0xC0, 0x9C, 0xF9, 0xF2, 0x81, + 0xE1, 0x12, 0x6A, 0xC0, 0x45, 0xD9, 0x67, 0xB3, 0xCE, 0xFF, 0x23, 0xA2, + 0x89, 0x0A, 0x54, 0xD4, 0x14, 0xB9, 0x2A, 0xA8, 0xD7, 0xEC, 0xF9, 0xAB, + 0xCD, 0x25, 0x58, 0x32, 0x79, 0x8F, 0x90, 0x5B, 0x98, 0x39, 0xC4, 0x08, + 0x06, 0xC1, 0xAC, 0x7F, 0x0E, 0x3D, 0x00, 0xA5 +}; + +static const unsigned char TA164_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA165_DN[] = { + 0x30, 0x7E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, 0x65, + 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, + 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, + 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, 0x65, + 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA165_RSA_N[] = { + 0xE3, 0xFB, 0x7D, 0xA3, 0x72, 0xBA, 0xC2, 0xF0, 0xC9, 0x14, 0x87, 0xF5, + 0x6B, 0x01, 0x4E, 0xE1, 0x6E, 0x40, 0x07, 0xBA, 0x6D, 0x27, 0x5D, 0x7F, + 0xF7, 0x5B, 0x2D, 0xB3, 0x5A, 0xC7, 0x51, 0x5F, 0xAB, 0xA4, 0x32, 0xA6, + 0x61, 0x87, 0xB6, 0x6E, 0x0F, 0x86, 0xD2, 0x30, 0x02, 0x97, 0xF8, 0xD7, + 0x69, 0x57, 0xA1, 0x18, 0x39, 0x5D, 0x6A, 0x64, 0x79, 0xC6, 0x01, 0x59, + 0xAC, 0x3C, 0x31, 0x4A, 0x38, 0x7C, 0xD2, 0x04, 0xD2, 0x4B, 0x28, 0xE8, + 0x20, 0x5F, 0x3B, 0x07, 0xA2, 0xCC, 0x4D, 0x73, 0xDB, 0xF3, 0xAE, 0x4F, + 0xC7, 0x56, 0xD5, 0x5A, 0xA7, 0x96, 0x89, 0xFA, 0xF3, 0xAB, 0x68, 0xD4, + 0x23, 0x86, 0x59, 0x27, 0xCF, 0x09, 0x27, 0xBC, 0xAC, 0x6E, 0x72, 0x83, + 0x1C, 0x30, 0x72, 0xDF, 0xE0, 0xA2, 0xE9, 0xD2, 0xE1, 0x74, 0x75, 0x19, + 0xBD, 0x2A, 0x9E, 0x7B, 0x15, 0x54, 0x04, 0x1B, 0xD7, 0x43, 0x39, 0xAD, + 0x55, 0x28, 0xC5, 0xE2, 0x1A, 0xBB, 0xF4, 0xC0, 0xE4, 0xAE, 0x38, 0x49, + 0x33, 0xCC, 0x76, 0x85, 0x9F, 0x39, 0x45, 0xD2, 0xA4, 0x9E, 0xF2, 0x12, + 0x8C, 0x51, 0xF8, 0x7C, 0xE4, 0x2D, 0x7F, 0xF5, 0xAC, 0x5F, 0xEB, 0x16, + 0x9F, 0xB1, 0x2D, 0xD1, 0xBA, 0xCC, 0x91, 0x42, 0x77, 0x4C, 0x25, 0xC9, + 0x90, 0x38, 0x6F, 0xDB, 0xF0, 0xCC, 0xFB, 0x8E, 0x1E, 0x97, 0x59, 0x3E, + 0xD5, 0x60, 0x4E, 0xE6, 0x05, 0x28, 0xED, 0x49, 0x79, 0x13, 0x4B, 0xBA, + 0x48, 0xDB, 0x2F, 0xF9, 0x72, 0xD3, 0x39, 0xCA, 0xFE, 0x1F, 0xD8, 0x34, + 0x72, 0xF5, 0xB4, 0x40, 0xCF, 0x31, 0x01, 0xC3, 0xEC, 0xDE, 0x11, 0x2D, + 0x17, 0x5D, 0x1F, 0xB8, 0x50, 0xD1, 0x5E, 0x19, 0xA7, 0x69, 0xDE, 0x07, + 0x33, 0x28, 0xCA, 0x50, 0x95, 0xF9, 0xA7, 0x54, 0xCB, 0x54, 0x86, 0x50, + 0x45, 0xA9, 0xF9, 0x49 +}; + +static const unsigned char TA165_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA166_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1D, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x50, 0x33, 0x38, 0x34, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA166_EC_Q[] = { + 0x04, 0xC1, 0x44, 0xA1, 0xCF, 0x11, 0x97, 0x50, 0x9A, 0xDE, 0x23, 0x82, + 0x35, 0x07, 0xCD, 0xD0, 0xCB, 0x18, 0x9D, 0xD2, 0xF1, 0x7F, 0x77, 0x35, + 0x4F, 0x3B, 0xDD, 0x94, 0x72, 0x52, 0xED, 0xC2, 0x3B, 0xF8, 0xEC, 0xFA, + 0x7B, 0x6B, 0x58, 0x20, 0xEC, 0x99, 0xAE, 0xC9, 0xFC, 0x68, 0xB3, 0x75, + 0xB9, 0xDB, 0x09, 0xEC, 0xC8, 0x13, 0xF5, 0x4E, 0xC6, 0x0A, 0x1D, 0x66, + 0x30, 0x4C, 0xBB, 0x1F, 0x47, 0x0A, 0x3C, 0x61, 0x10, 0x42, 0x29, 0x7C, + 0xA5, 0x08, 0x0E, 0xE0, 0x22, 0xE9, 0xD3, 0x35, 0x68, 0xCE, 0x9B, 0x63, + 0x9F, 0x84, 0xB5, 0x99, 0x4D, 0x58, 0xA0, 0x8E, 0xF5, 0x54, 0xE7, 0x95, + 0xC9 +}; + +static const unsigned char TA167_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x36, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA167_RSA_N[] = { + 0x95, 0x07, 0xE8, 0x73, 0xCA, 0x66, 0xF9, 0xEC, 0x14, 0xCA, 0x7B, 0x3C, + 0xF7, 0x0D, 0x08, 0xF1, 0xB4, 0x45, 0x0B, 0x2C, 0x82, 0xB4, 0x48, 0xC6, + 0xEB, 0x5B, 0x3C, 0xAE, 0x83, 0xB8, 0x41, 0x92, 0x33, 0x14, 0xA4, 0x6F, + 0x7F, 0xE9, 0x2A, 0xCC, 0xC6, 0xB0, 0x88, 0x6B, 0xC5, 0xB6, 0x89, 0xD1, + 0xC6, 0xB2, 0xFF, 0x14, 0xCE, 0x51, 0x14, 0x21, 0xEC, 0x4A, 0xDD, 0x1B, + 0x5A, 0xC6, 0xD6, 0x87, 0xEE, 0x4D, 0x3A, 0x15, 0x06, 0xED, 0x64, 0x66, + 0x0B, 0x92, 0x80, 0xCA, 0x44, 0xDE, 0x73, 0x94, 0x4E, 0xF3, 0xA7, 0x89, + 0x7F, 0x4F, 0x78, 0x63, 0x08, 0xC8, 0x12, 0x50, 0x6D, 0x42, 0x66, 0x2F, + 0x4D, 0xB9, 0x79, 0x28, 0x4D, 0x52, 0x1A, 0x8A, 0x1A, 0x80, 0xB7, 0x19, + 0x81, 0x0E, 0x7E, 0xC4, 0x8A, 0xBC, 0x64, 0x4C, 0x21, 0x1C, 0x43, 0x68, + 0xD7, 0x3D, 0x3C, 0x8A, 0xC5, 0xB2, 0x66, 0xD5, 0x90, 0x9A, 0xB7, 0x31, + 0x06, 0xC5, 0xBE, 0xE2, 0x6D, 0x32, 0x06, 0xA6, 0x1E, 0xF9, 0xB9, 0xEB, + 0xAA, 0xA3, 0xB8, 0xBF, 0xBE, 0x82, 0x63, 0x50, 0xD0, 0xF0, 0x18, 0x89, + 0xDF, 0xE4, 0x0F, 0x79, 0xF5, 0xEA, 0xA2, 0x1F, 0x2A, 0xD2, 0x70, 0x2E, + 0x7B, 0xE7, 0xBC, 0x93, 0xBB, 0x6D, 0x53, 0xE2, 0x48, 0x7C, 0x8C, 0x10, + 0x07, 0x38, 0xFF, 0x66, 0xB2, 0x77, 0x61, 0x7E, 0xE0, 0xEA, 0x8C, 0x3C, + 0xAA, 0xB4, 0xA4, 0xF6, 0xF3, 0x95, 0x4A, 0x12, 0x07, 0x6D, 0xFD, 0x8C, + 0xB2, 0x89, 0xCF, 0xD0, 0xA0, 0x61, 0x77, 0xC8, 0x58, 0x74, 0xB0, 0xD4, + 0x23, 0x3A, 0xF7, 0x5D, 0x3A, 0xCA, 0xA2, 0xDB, 0x9D, 0x09, 0xDE, 0x5D, + 0x44, 0x2D, 0x90, 0xF1, 0x81, 0xCD, 0x57, 0x92, 0xFA, 0x7E, 0xBC, 0x50, + 0x04, 0x63, 0x34, 0xDF, 0x6B, 0x93, 0x18, 0xBE, 0x6B, 0x36, 0xB2, 0x39, + 0xE4, 0xAC, 0x24, 0x36, 0xB7, 0xF0, 0xEF, 0xB6, 0x1C, 0x13, 0x57, 0x93, + 0xB6, 0xDE, 0xB2, 0xF8, 0xE2, 0x85, 0xB7, 0x73, 0xA2, 0xB8, 0x35, 0xAA, + 0x45, 0xF2, 0xE0, 0x9D, 0x36, 0xA1, 0x6F, 0x54, 0x8A, 0xF1, 0x72, 0x56, + 0x6E, 0x2E, 0x88, 0xC5, 0x51, 0x42, 0x44, 0x15, 0x94, 0xEE, 0xA3, 0xC5, + 0x38, 0x96, 0x9B, 0x4E, 0x4E, 0x5A, 0x0B, 0x47, 0xF3, 0x06, 0x36, 0x49, + 0x77, 0x30, 0xBC, 0x71, 0x37, 0xE5, 0xA6, 0xEC, 0x21, 0x08, 0x75, 0xFC, + 0xE6, 0x61, 0x16, 0x3F, 0x77, 0xD5, 0xD9, 0x91, 0x97, 0x84, 0x0A, 0x6C, + 0xD4, 0x02, 0x4D, 0x74, 0xC0, 0x14, 0xED, 0xFD, 0x39, 0xFB, 0x83, 0xF2, + 0x5E, 0x14, 0xA1, 0x04, 0xB0, 0x0B, 0xE9, 0xFE, 0xEE, 0x8F, 0xE1, 0x6E, + 0x0B, 0xB2, 0x08, 0xB3, 0x61, 0x66, 0x09, 0x6A, 0xB1, 0x06, 0x3A, 0x65, + 0x96, 0x59, 0xC0, 0xF0, 0x35, 0xFD, 0xC9, 0xDA, 0x28, 0x8D, 0x1A, 0x11, + 0x87, 0x70, 0x81, 0x0A, 0xA8, 0x9A, 0x75, 0x1D, 0x9E, 0x3A, 0x86, 0x05, + 0x00, 0x9E, 0xDB, 0x80, 0xD6, 0x25, 0xF9, 0xDC, 0x05, 0x9E, 0x27, 0x59, + 0x4C, 0x76, 0x39, 0x5B, 0xEA, 0xF9, 0xA5, 0xA1, 0xD8, 0x83, 0x0F, 0xD1, + 0xFF, 0xDF, 0x30, 0x11, 0xF9, 0x85, 0xCF, 0x33, 0x48, 0xF5, 0xCA, 0x6D, + 0x64, 0x14, 0x2C, 0x7A, 0x58, 0x4F, 0xD3, 0x4B, 0x08, 0x49, 0xC5, 0x95, + 0x64, 0x1A, 0x63, 0x0E, 0x79, 0x3D, 0xF5, 0xB3, 0x8C, 0xCA, 0x58, 0xAD, + 0x9C, 0x42, 0x45, 0x79, 0x6E, 0x0E, 0x87, 0x19, 0x5C, 0x54, 0xB1, 0x65, + 0xB6, 0xBF, 0x8C, 0x9B, 0xDC, 0x13, 0xE9, 0x0D, 0x6F, 0xB8, 0x2E, 0xDC, + 0x67, 0x6E, 0xC9, 0x8B, 0x11, 0xB5, 0x84, 0x14, 0x8A, 0x00, 0x19, 0x70, + 0x83, 0x79, 0x91, 0x97, 0x91, 0xD4, 0x1A, 0x27, 0xBF, 0x37, 0x1E, 0x32, + 0x07, 0xD8, 0x14, 0x63, 0x3C, 0x28, 0x4C, 0xAF +}; + +static const unsigned char TA167_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA168_DN[] = { + 0x30, 0x81, 0xA7, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x4E, 0x65, + 0x74, 0x4C, 0x6F, 0x63, 0x6B, 0x20, 0x4B, 0x66, 0x74, 0x2E, 0x31, 0x37, + 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x2E, 0x54, 0x61, 0x6E, + 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, 0x6E, 0x79, 0x6B, + 0x69, 0x61, 0x64, 0xC3, 0xB3, 0x6B, 0x20, 0x28, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x29, 0x31, 0x35, 0x30, 0x33, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x2C, 0x4E, 0x65, 0x74, 0x4C, 0x6F, 0x63, + 0x6B, 0x20, 0x41, 0x72, 0x61, 0x6E, 0x79, 0x20, 0x28, 0x43, 0x6C, 0x61, + 0x73, 0x73, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x29, 0x20, 0x46, 0xC5, 0x91, + 0x74, 0x61, 0x6E, 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, + 0x6E, 0x79 +}; + +static const unsigned char TA168_RSA_N[] = { + 0xC4, 0x24, 0x5E, 0x73, 0xBE, 0x4B, 0x6D, 0x14, 0xC3, 0xA1, 0xF4, 0xE3, + 0x97, 0x90, 0x6E, 0xD2, 0x30, 0x45, 0x1E, 0x3C, 0xEE, 0x67, 0xD9, 0x64, + 0xE0, 0x1A, 0x8A, 0x7F, 0xCA, 0x30, 0xCA, 0x83, 0xE3, 0x20, 0xC1, 0xE3, + 0xF4, 0x3A, 0xD3, 0x94, 0x5F, 0x1A, 0x7C, 0x5B, 0x6D, 0xBF, 0x30, 0x4F, + 0x84, 0x27, 0xF6, 0x9F, 0x1F, 0x49, 0xBC, 0xC6, 0x99, 0x0A, 0x90, 0xF2, + 0x0F, 0xF5, 0x7F, 0x43, 0x84, 0x37, 0x63, 0x51, 0x8B, 0x7A, 0xA5, 0x70, + 0xFC, 0x7A, 0x58, 0xCD, 0x8E, 0x9B, 0xED, 0xC3, 0x46, 0x6C, 0x84, 0x70, + 0x5D, 0xDA, 0xF3, 0x01, 0x90, 0x23, 0xFC, 0x4E, 0x30, 0xA9, 0x7E, 0xE1, + 0x27, 0x63, 0xE7, 0xED, 0x64, 0x3C, 0xA0, 0xB8, 0xC9, 0x33, 0x63, 0xFE, + 0x16, 0x90, 0xFF, 0xB0, 0xB8, 0xFD, 0xD7, 0xA8, 0xC0, 0xC0, 0x94, 0x43, + 0x0B, 0xB6, 0xD5, 0x59, 0xA6, 0x9E, 0x56, 0xD0, 0x24, 0x1F, 0x70, 0x79, + 0xAF, 0xDB, 0x39, 0x54, 0x0D, 0x65, 0x75, 0xD9, 0x15, 0x41, 0x94, 0x01, + 0xAF, 0x5E, 0xEC, 0xF6, 0x8D, 0xF1, 0xFF, 0xAD, 0x64, 0xFE, 0x20, 0x9A, + 0xD7, 0x5C, 0xEB, 0xFE, 0xA6, 0x1F, 0x08, 0x64, 0xA3, 0x8B, 0x76, 0x55, + 0xAD, 0x1E, 0x3B, 0x28, 0x60, 0x2E, 0x87, 0x25, 0xE8, 0xAA, 0xAF, 0x1F, + 0xC6, 0x64, 0x46, 0x20, 0xB7, 0x70, 0x7F, 0x3C, 0xDE, 0x48, 0xDB, 0x96, + 0x53, 0xB7, 0x39, 0x77, 0xE4, 0x1A, 0xE2, 0xC7, 0x16, 0x84, 0x76, 0x97, + 0x5B, 0x2F, 0xBB, 0x19, 0x15, 0x85, 0xF8, 0x69, 0x85, 0xF5, 0x99, 0xA7, + 0xA9, 0xF2, 0x34, 0xA7, 0xA9, 0xB6, 0xA6, 0x03, 0xFC, 0x6F, 0x86, 0x3D, + 0x54, 0x7C, 0x76, 0x04, 0x9B, 0x6B, 0xF9, 0x40, 0x5D, 0x00, 0x34, 0xC7, + 0x2E, 0x99, 0x75, 0x9D, 0xE5, 0x88, 0x03, 0xAA, 0x4D, 0xF8, 0x03, 0xD2, + 0x42, 0x76, 0xC0, 0x1B +}; + +static const unsigned char TA168_RSA_E[] = { + 0xA8, 0x8B +}; + +static const unsigned char TA169_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA169_RSA_N[] = { + 0xC0, 0x31, 0x82, 0x61, 0x92, 0xE4, 0x94, 0x1B, 0x0A, 0x2A, 0x65, 0xD0, + 0xBE, 0x06, 0xA9, 0x87, 0x3B, 0x51, 0x12, 0xEA, 0x70, 0x41, 0xAE, 0xE2, + 0xFB, 0x74, 0xEA, 0x0A, 0x8D, 0xB9, 0xB3, 0x4C, 0xDC, 0x8F, 0xB7, 0x13, + 0x52, 0x4F, 0x54, 0x18, 0xE1, 0x2C, 0x73, 0x95, 0x91, 0xC5, 0x66, 0x3B, + 0x6A, 0xCF, 0xAC, 0x63, 0x6D, 0x87, 0x53, 0xF0, 0xF7, 0xF1, 0x39, 0xB7, + 0xA0, 0x43, 0x63, 0xB0, 0xC4, 0x03, 0x5D, 0x57, 0xA9, 0xE7, 0x44, 0xCE, + 0xC4, 0xA1, 0x83, 0x65, 0xF6, 0x50, 0x3E, 0xB1, 0x7E, 0x16, 0xB8, 0x3A, + 0x8A, 0x02, 0xD0, 0x96, 0x1F, 0x00, 0xCD, 0x05, 0x21, 0xEF, 0x06, 0x6D, + 0xDD, 0x21, 0x9C, 0x19, 0x43, 0x45, 0xA1, 0xC5, 0xE8, 0x80, 0xCA, 0xC2, + 0xAD, 0x40, 0x62, 0x17, 0x06, 0xC6, 0xAA, 0xBC, 0xF3, 0xD6, 0xE6, 0xFC, + 0x50, 0x7E, 0x66, 0x42, 0x1F, 0x3C, 0x8B, 0xA6, 0x79, 0x79, 0x86, 0x40, + 0x35, 0x9F, 0x20, 0xEF, 0x3F, 0xEB, 0x8B, 0x47, 0x1F, 0x8F, 0x8E, 0xC5, + 0xD4, 0x8E, 0xB6, 0x2C, 0xC9, 0x44, 0x04, 0xE3, 0xD4, 0x43, 0x75, 0x3F, + 0xD5, 0x3F, 0xAF, 0x1C, 0xCC, 0x7E, 0x46, 0x5F, 0xAC, 0xDF, 0x64, 0x10, + 0x8A, 0xEF, 0x46, 0xF0, 0x90, 0xF0, 0x0F, 0x2D, 0xF4, 0x88, 0x0B, 0xB1, + 0x29, 0xAA, 0xAF, 0x85, 0xAA, 0x49, 0x58, 0xA8, 0xBF, 0x63, 0xA0, 0x38, + 0x91, 0xE6, 0xB3, 0xE6, 0x77, 0x68, 0xC4, 0xF9, 0x2A, 0x19, 0x84, 0xBB, + 0x0E, 0xE1, 0xF5, 0xAF, 0x89, 0xEC, 0xA5, 0x2F, 0x50, 0x20, 0x74, 0x1E, + 0x12, 0x41, 0x73, 0x1E, 0x24, 0xD9, 0xCA, 0xCE, 0x2C, 0xA1, 0x59, 0x35, + 0xC0, 0xC8, 0x1D, 0x46, 0x27, 0x61, 0x5A, 0x8F, 0xF9, 0x4D, 0xD3, 0x72, + 0x79, 0x66, 0x1E, 0x9F, 0x15, 0x90, 0x21, 0x2D, 0xFD, 0xED, 0x8B, 0x56, + 0x70, 0x03, 0x4A, 0x49, 0x3E, 0x7F, 0x69, 0x31, 0x12, 0x69, 0xC7, 0x1E, + 0x5C, 0xCA, 0x7A, 0x13, 0x8B, 0xE8, 0xE6, 0xF5, 0x60, 0x0F, 0xCC, 0x93, + 0x2C, 0x84, 0x7F, 0xF1, 0xFC, 0x6A, 0xFC, 0x9B, 0x47, 0x9D, 0xDB, 0xAD, + 0x88, 0x3D, 0xF3, 0x76, 0x75, 0x33, 0xD7, 0x4B, 0xA4, 0xC8, 0x8B, 0xF9, + 0xF5, 0x43, 0x58, 0x4F, 0xCB, 0xC8, 0x03, 0x54, 0x8F, 0xA5, 0x85, 0x78, + 0x04, 0x1A, 0xF3, 0x73, 0xF2, 0xD7, 0x87, 0x1D, 0x41, 0x9F, 0xE7, 0xD8, + 0x17, 0xCE, 0x1A, 0x9C, 0x0F, 0x4A, 0xFC, 0xDC, 0x44, 0x68, 0x54, 0x68, + 0xE2, 0x41, 0x3C, 0xFE, 0x2C, 0x84, 0x86, 0x37, 0x3C, 0xCD, 0x3F, 0x2F, + 0xA2, 0xDB, 0xE7, 0xF7, 0x54, 0x03, 0x5F, 0x59, 0xD3, 0xF7, 0x91, 0x78, + 0xC7, 0x8B, 0x77, 0x6A, 0x16, 0xE5, 0x49, 0x85, 0x90, 0x45, 0x72, 0x70, + 0x2F, 0x91, 0x5D, 0xF8, 0x3E, 0x65, 0x40, 0x0B, 0x19, 0x99, 0xC9, 0x26, + 0x20, 0x5A, 0x68, 0xC1, 0x35, 0xBF, 0x4F, 0xA7, 0x51, 0xF1, 0xD8, 0x11, + 0x2B, 0x5B, 0xE0, 0x9A, 0x9E, 0x28, 0x3B, 0x0A, 0x3A, 0x0A, 0x1F, 0xC1, + 0x81, 0xE5, 0x2E, 0xF0, 0xA6, 0xB9, 0x69, 0xA5, 0x88, 0x94, 0xE6, 0x6B, + 0x13, 0x7F, 0xD1, 0x64, 0x3F, 0x3D, 0x9C, 0x70, 0x46, 0xE5, 0xA2, 0x85, + 0x7B, 0x58, 0x84, 0x27, 0xDC, 0xC4, 0x80, 0x3E, 0x67, 0x9A, 0x9A, 0xC7, + 0x9A, 0x31, 0x0E, 0x30, 0xEC, 0xE6, 0x17, 0x40, 0x95, 0xD9, 0x45, 0xED, + 0x01, 0x96, 0xAA, 0xBF, 0x0C, 0xF3, 0x4B, 0xD1, 0x63, 0xF7, 0x13, 0x58, + 0xC0, 0xB8, 0xF3, 0xFA, 0x67, 0xDD, 0x9B, 0x7D, 0x6D, 0x4A, 0xFF, 0x32, + 0x4C, 0xB5, 0x25, 0x3B, 0xFF, 0x1C, 0x67, 0x0F, 0x85, 0x22, 0x59, 0x05, + 0x91, 0x91, 0x41, 0x77, 0x81, 0xD0, 0x85, 0x4C, 0x87, 0x10, 0x71, 0xFF, + 0x9E, 0x43, 0x1B, 0xAE, 0x95, 0x75, 0x2D, 0x81 +}; + +static const unsigned char TA169_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA170_DN[] = { + 0x30, 0x43, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, + 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0D, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA170_RSA_N[] = { + 0xBD, 0x55, 0x7C, 0x61, 0xD3, 0xB8, 0x1D, 0x04, 0x62, 0x05, 0xA0, 0xAE, + 0x6C, 0xB7, 0x70, 0xB4, 0x41, 0xEA, 0x4B, 0x03, 0x5E, 0x10, 0x3F, 0x90, + 0x5A, 0x1C, 0x8B, 0x3B, 0xB0, 0x66, 0x8B, 0x6C, 0x48, 0xA6, 0x1C, 0x22, + 0xBA, 0xD5, 0x40, 0x92, 0xEE, 0x33, 0xB2, 0x23, 0x59, 0xC9, 0x8E, 0xBC, + 0x58, 0xDA, 0x8B, 0x9E, 0xD0, 0x19, 0xF2, 0x2F, 0x59, 0xC6, 0x8C, 0x63, + 0x5A, 0xBA, 0x9F, 0xA3, 0x0B, 0xB0, 0xB3, 0x9A, 0x5C, 0xBA, 0x11, 0xB8, + 0x12, 0xE9, 0x0C, 0xBB, 0xCF, 0x6E, 0x6C, 0x80, 0x87, 0x29, 0x14, 0x03, + 0x2C, 0x8D, 0x24, 0x9A, 0xC8, 0x64, 0x83, 0xB5, 0x6A, 0xAC, 0x13, 0x2C, + 0x33, 0xF1, 0x9F, 0xDC, 0x2C, 0x61, 0x3C, 0x1A, 0x3F, 0x70, 0x55, 0x9B, + 0xAD, 0x00, 0x52, 0x7F, 0xCF, 0x04, 0xB9, 0xFE, 0x36, 0xFA, 0x9C, 0xC0, + 0x16, 0xAE, 0x62, 0xFE, 0x96, 0x4C, 0x43, 0x7E, 0x55, 0x14, 0xBE, 0x1A, + 0xB3, 0xD2, 0x6D, 0xC2, 0xAF, 0x76, 0x66, 0x95, 0x6B, 0x2A, 0xB0, 0x94, + 0x77, 0x85, 0x5E, 0x04, 0x0F, 0x62, 0x1D, 0x63, 0x75, 0xF7, 0x6B, 0xE7, + 0xCB, 0x5B, 0x9A, 0x70, 0xEC, 0x3E, 0x67, 0x05, 0xF0, 0xFE, 0x07, 0x08, + 0x80, 0xCF, 0x28, 0xDB, 0x05, 0xC6, 0x14, 0x27, 0x2F, 0x86, 0x7D, 0xF0, + 0x27, 0xDE, 0xFF, 0xE6, 0x7E, 0x33, 0x48, 0xE7, 0x0B, 0x1E, 0x58, 0xD1, + 0x27, 0x2B, 0x53, 0x0E, 0x57, 0x4A, 0x65, 0xD7, 0xFB, 0xA2, 0x80, 0x60, + 0xFC, 0x4C, 0xBC, 0x35, 0x53, 0x01, 0x6A, 0x97, 0x72, 0x82, 0xAF, 0xF1, + 0x1D, 0x70, 0xE8, 0x9C, 0xF5, 0xEF, 0x5E, 0xC2, 0x6C, 0xC7, 0x47, 0x7E, + 0x5A, 0x94, 0x85, 0x26, 0x4D, 0x3B, 0xBA, 0xEB, 0x4C, 0xE8, 0xB0, 0x09, + 0xC2, 0x65, 0xC2, 0x9D, 0x9D, 0x09, 0x9B, 0x4E, 0xB5, 0x97, 0x05, 0xAC, + 0xF5, 0x06, 0xA0, 0xF7, 0x36, 0x05, 0x7E, 0xF4, 0x90, 0xB2, 0x6B, 0xC4, + 0xB4, 0xF9, 0x64, 0xEA, 0xE9, 0x1A, 0x0A, 0xC8, 0x0D, 0xA8, 0xED, 0x27, + 0xC9, 0xD4, 0xE7, 0xB3, 0xB9, 0xAB, 0x82, 0x22, 0x90, 0x27, 0x3D, 0x2A, + 0xE8, 0x7C, 0x90, 0xEF, 0xBC, 0x4F, 0xFD, 0xE2, 0x0A, 0x24, 0xA7, 0xDE, + 0x65, 0x24, 0xA4, 0x5D, 0xEA, 0xC0, 0x76, 0x30, 0xD3, 0x77, 0x50, 0xF8, + 0x0D, 0x04, 0x9B, 0x94, 0x36, 0x01, 0x73, 0xCA, 0x06, 0x58, 0xA6, 0xD3, + 0x3B, 0xDC, 0xFA, 0x04, 0x46, 0x13, 0x55, 0x8A, 0xC9, 0x44, 0x47, 0xB8, + 0x51, 0x39, 0x1A, 0x2E, 0xE8, 0x34, 0xE2, 0x79, 0xCB, 0x59, 0x4A, 0x0A, + 0x7F, 0xBC, 0xA6, 0xEF, 0x1F, 0x03, 0x67, 0x6A, 0x59, 0x2B, 0x25, 0x62, + 0x93, 0xD9, 0x53, 0x19, 0x66, 0x3C, 0x27, 0x62, 0x29, 0x86, 0x4D, 0xA4, + 0x6B, 0xEE, 0xFF, 0xD4, 0x4E, 0xBA, 0xD5, 0xB4, 0xE2, 0x8E, 0x48, 0x5A, + 0x00, 0x19, 0x09, 0xF1, 0x05, 0xD9, 0xCE, 0x91, 0xB1, 0xF7, 0xEB, 0xE9, + 0x39, 0x4F, 0xF6, 0x6F, 0x04, 0x43, 0x9A, 0x55, 0xF5, 0x3E, 0x05, 0x14, + 0xBD, 0xBF, 0xB3, 0x59, 0xB4, 0xD8, 0x8E, 0x33, 0x84, 0xA3, 0x90, 0x52, + 0xAA, 0xB3, 0x02, 0x95, 0x60, 0xF9, 0x0C, 0x4C, 0x68, 0xF9, 0xEE, 0xD5, + 0x17, 0x0D, 0xF8, 0x71, 0x57, 0xB5, 0x25, 0xE4, 0x29, 0xEE, 0x65, 0x5D, + 0xAF, 0xD1, 0xEE, 0x3C, 0x17, 0x0B, 0x5A, 0x43, 0xC5, 0xA5, 0x86, 0xEA, + 0x24, 0x9E, 0xE2, 0x05, 0x07, 0xDC, 0x34, 0x42, 0x12, 0x91, 0xD6, 0x39, + 0x74, 0xAE, 0x4C, 0x41, 0x82, 0xDB, 0xF2, 0xA6, 0x48, 0xD1, 0xB3, 0x9B, + 0xF3, 0x33, 0xAA, 0xF3, 0xA6, 0xC0, 0xC5, 0x4E, 0xF5, 0xF4, 0x9D, 0x76, + 0x63, 0xE6, 0x02, 0xC6, 0x22, 0x4B, 0xC1, 0x95, 0x3F, 0x50, 0x64, 0x2C, + 0x54, 0xE5, 0xB6, 0xF0, 0x3C, 0x29, 0xCF, 0x57 +}; + +static const unsigned char TA170_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA171_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA171_EC_Q[] = { + 0x04, 0x6B, 0xDA, 0x0D, 0x75, 0x35, 0x08, 0x31, 0x47, 0x05, 0xAE, 0x45, + 0x99, 0x55, 0xF1, 0x11, 0x13, 0x2E, 0x4A, 0xF8, 0x10, 0x31, 0x23, 0xA3, + 0x7E, 0x83, 0xD3, 0x7F, 0x28, 0x08, 0x3A, 0x26, 0x1A, 0x3A, 0xCF, 0x97, + 0x82, 0x1F, 0x80, 0xB7, 0x27, 0x09, 0x8F, 0xD1, 0x8E, 0x30, 0xC4, 0x0A, + 0x9B, 0x0E, 0xAC, 0x58, 0x04, 0xAB, 0xF7, 0x36, 0x7D, 0x94, 0x23, 0xA4, + 0x9B, 0x0A, 0x8A, 0x8B, 0xAB, 0xEB, 0xFD, 0x39, 0x25, 0x66, 0xF1, 0x5E, + 0xFE, 0x8C, 0xAE, 0x8D, 0x41, 0x79, 0x9D, 0x09, 0x60, 0xCE, 0x28, 0xA9, + 0xD3, 0x8A, 0x6D, 0xF3, 0xD6, 0x45, 0xD4, 0xF2, 0x98, 0x84, 0x38, 0x65, + 0xA0 +}; + +static const unsigned char TA172_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA172_RSA_N[] = { + 0xB6, 0x80, 0x0E, 0xC4, 0x79, 0xBD, 0x05, 0x8C, 0x7D, 0xB0, 0xA3, 0x9D, + 0x4D, 0x22, 0x4D, 0xCB, 0xF0, 0x41, 0x97, 0x4D, 0x59, 0xE0, 0xD1, 0xFE, + 0x56, 0x8C, 0x97, 0xF2, 0xD7, 0xBD, 0x8F, 0x6C, 0xB7, 0x23, 0x8F, 0x5F, + 0xD5, 0xC4, 0xD8, 0x41, 0xCB, 0xF2, 0x02, 0x1E, 0x71, 0xE5, 0xE9, 0xF6, + 0x5E, 0xCB, 0x08, 0x2A, 0x5E, 0x30, 0xF2, 0x2D, 0x66, 0xC7, 0x84, 0x1B, + 0x64, 0x57, 0x38, 0x9D, 0x75, 0x2D, 0x56, 0xC6, 0x2F, 0x61, 0xEF, 0x96, + 0xFC, 0x20, 0x46, 0xBD, 0xEB, 0xD4, 0x7B, 0x3F, 0x3F, 0x7C, 0x47, 0x38, + 0x04, 0xA9, 0x1B, 0xAA, 0x52, 0xDF, 0x13, 0x37, 0xD3, 0x15, 0x15, 0x4E, + 0xBD, 0x5F, 0x7C, 0xAF, 0xAD, 0x63, 0xC7, 0x79, 0xDC, 0x08, 0x7B, 0xD5, + 0xA0, 0xE5, 0xF7, 0x5B, 0x75, 0xAC, 0x80, 0x55, 0x99, 0x92, 0x61, 0x9B, + 0xCD, 0x2A, 0x17, 0x7D, 0xDB, 0x8F, 0xF4, 0xB5, 0x6A, 0xEA, 0x17, 0x4A, + 0x64, 0x28, 0x66, 0x15, 0x29, 0x6C, 0x02, 0xF1, 0x6B, 0xD5, 0xBA, 0xA3, + 0x33, 0xDC, 0x5A, 0x67, 0xA7, 0x05, 0xE2, 0xBF, 0x65, 0xB6, 0x16, 0xB0, + 0x10, 0xED, 0xCD, 0x50, 0x33, 0xC9, 0x70, 0x50, 0xEC, 0x19, 0x8E, 0xB0, + 0xC7, 0xF2, 0x74, 0x5B, 0x6B, 0x44, 0xC6, 0x7D, 0x96, 0xB9, 0x98, 0x08, + 0x59, 0x66, 0xDE, 0x29, 0x01, 0x9B, 0xF4, 0x2A, 0x6D, 0xD3, 0x15, 0x3A, + 0x90, 0x6A, 0x67, 0xF1, 0xB4, 0x6B, 0x66, 0xD9, 0x21, 0xEB, 0xCA, 0xD9, + 0x62, 0x7C, 0x46, 0x10, 0x5C, 0xDE, 0x75, 0x49, 0x67, 0x9E, 0x42, 0xF9, + 0xFE, 0x75, 0xA9, 0xA3, 0xAD, 0xFF, 0x76, 0x0A, 0x67, 0x40, 0xE3, 0xC5, + 0xF7, 0x8D, 0xC7, 0x85, 0x9A, 0x59, 0x9E, 0x62, 0x9A, 0x6A, 0xED, 0x45, + 0x87, 0x98, 0x67, 0xB2, 0xD5, 0x4A, 0x3C, 0xD7, 0xB4, 0x3B, 0x00, 0x0D, + 0xC0, 0x8F, 0x1F, 0xE1, 0x40, 0xC4, 0xAE, 0x6C, 0x21, 0xDC, 0x49, 0x7E, + 0x7E, 0xCA, 0xB2, 0x8D, 0x6D, 0xB6, 0xBF, 0x93, 0x2F, 0xA1, 0x5C, 0x3E, + 0x8F, 0xCA, 0xED, 0x80, 0x8E, 0x58, 0xE1, 0xDB, 0x57, 0xCF, 0x85, 0x36, + 0x38, 0xB2, 0x71, 0xA4, 0x09, 0x8C, 0x92, 0x89, 0x08, 0x88, 0x48, 0xF1, + 0x40, 0x63, 0x18, 0xB2, 0x5B, 0x8C, 0x5A, 0xE3, 0xC3, 0xD3, 0x17, 0xAA, + 0xAB, 0x19, 0xA3, 0x2C, 0x1B, 0xE4, 0xD5, 0xC6, 0xE2, 0x66, 0x7A, 0xD7, + 0x82, 0x19, 0xA6, 0x3B, 0x16, 0x2C, 0x2F, 0x71, 0x87, 0x5F, 0x45, 0x9E, + 0x95, 0x73, 0x93, 0xC2, 0x42, 0x81, 0x21, 0x13, 0x96, 0xD7, 0x9D, 0xBB, + 0x93, 0x68, 0x15, 0xFA, 0x9D, 0xA4, 0x1D, 0x8C, 0xF2, 0x81, 0xE0, 0x58, + 0x06, 0xBD, 0xC9, 0xB6, 0xE3, 0xF6, 0x89, 0x5D, 0x89, 0xF9, 0xAC, 0x44, + 0xA1, 0xCB, 0x6B, 0xFA, 0x16, 0xF1, 0xC7, 0x50, 0x3D, 0x24, 0xDA, 0xF7, + 0xC3, 0xE4, 0x87, 0xD5, 0x56, 0xF1, 0x4F, 0x90, 0x30, 0xFA, 0x45, 0x09, + 0x59, 0xDA, 0x34, 0xCE, 0xE0, 0x13, 0x1C, 0x04, 0x7C, 0x00, 0xD4, 0x9B, + 0x86, 0xA4, 0x40, 0xBC, 0xD9, 0xDC, 0x4C, 0x57, 0x7E, 0xAE, 0xB7, 0x33, + 0xB6, 0x5E, 0x76, 0xE1, 0x65, 0x8B, 0x66, 0xDF, 0x8D, 0xCA, 0xD7, 0x98, + 0xAF, 0xCE, 0x36, 0x98, 0x8C, 0x9C, 0x83, 0x99, 0x03, 0x70, 0xF3, 0xAF, + 0x74, 0xED, 0xC6, 0x0E, 0x36, 0xE7, 0xBD, 0xEC, 0xC1, 0x73, 0xA7, 0x94, + 0x5A, 0xCB, 0x92, 0x64, 0x82, 0xA6, 0x00, 0xC1, 0x70, 0xA1, 0x6E, 0x2C, + 0x29, 0xE1, 0x58, 0x57, 0xEC, 0x5A, 0x7C, 0x99, 0x6B, 0x25, 0xA4, 0x90, + 0x3A, 0x80, 0xF4, 0x20, 0x9D, 0x9A, 0xCE, 0xC7, 0x2D, 0xF9, 0xB2, 0x4B, + 0x29, 0x95, 0x83, 0xE9, 0x35, 0x8D, 0xA7, 0x49, 0x48, 0xA7, 0x0F, 0x4C, + 0x19, 0x91, 0xD0, 0xF5, 0xBF, 0x10, 0xE0, 0x71 +}; + +static const unsigned char TA172_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA173_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x32, 0x35, 0x36, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA173_EC_Q[] = { + 0x04, 0x7E, 0xFB, 0x6C, 0xE6, 0x23, 0xE3, 0x73, 0x32, 0x08, 0xCA, 0x60, + 0xE6, 0x53, 0x9C, 0xBA, 0x74, 0x8D, 0x18, 0xB0, 0x78, 0x90, 0x52, 0x80, + 0xDD, 0x38, 0xC0, 0x4A, 0x1D, 0xD1, 0xA8, 0xCC, 0x93, 0xA4, 0x97, 0x06, + 0x38, 0xCA, 0x0D, 0x15, 0x62, 0xC6, 0x8E, 0x01, 0x2A, 0x65, 0x9D, 0xAA, + 0xDF, 0x34, 0x91, 0x2E, 0x81, 0xC1, 0xE4, 0x33, 0x92, 0x31, 0xC4, 0xFD, + 0x09, 0x3A, 0xA6, 0x3F, 0xAD +}; + +static const unsigned char TA174_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA174_RSA_N[] = { + 0xC0, 0x31, 0x82, 0x61, 0x92, 0xE4, 0x94, 0x1B, 0x0A, 0x2A, 0x65, 0xD0, + 0xBE, 0x06, 0xA9, 0x87, 0x3B, 0x51, 0x12, 0xEA, 0x70, 0x41, 0xAE, 0xE2, + 0xFB, 0x74, 0xEA, 0x0A, 0x8D, 0xB9, 0xB3, 0x4C, 0xDC, 0x8F, 0xB7, 0x13, + 0x52, 0x4F, 0x54, 0x18, 0xE1, 0x2C, 0x73, 0x95, 0x91, 0xC5, 0x66, 0x3B, + 0x6A, 0xCF, 0xAC, 0x63, 0x6D, 0x87, 0x53, 0xF0, 0xF7, 0xF1, 0x39, 0xB7, + 0xA0, 0x43, 0x63, 0xB0, 0xC4, 0x03, 0x5D, 0x57, 0xA9, 0xE7, 0x44, 0xCE, + 0xC4, 0xA1, 0x83, 0x65, 0xF6, 0x50, 0x3E, 0xB1, 0x7E, 0x16, 0xB8, 0x3A, + 0x8A, 0x02, 0xD0, 0x96, 0x1F, 0x00, 0xCD, 0x05, 0x21, 0xEF, 0x06, 0x6D, + 0xDD, 0x21, 0x9C, 0x19, 0x43, 0x45, 0xA1, 0xC5, 0xE8, 0x80, 0xCA, 0xC2, + 0xAD, 0x40, 0x62, 0x17, 0x06, 0xC6, 0xAA, 0xBC, 0xF3, 0xD6, 0xE6, 0xFC, + 0x50, 0x7E, 0x66, 0x42, 0x1F, 0x3C, 0x8B, 0xA6, 0x79, 0x79, 0x86, 0x40, + 0x35, 0x9F, 0x20, 0xEF, 0x3F, 0xEB, 0x8B, 0x47, 0x1F, 0x8F, 0x8E, 0xC5, + 0xD4, 0x8E, 0xB6, 0x2C, 0xC9, 0x44, 0x04, 0xE3, 0xD4, 0x43, 0x75, 0x3F, + 0xD5, 0x3F, 0xAF, 0x1C, 0xCC, 0x7E, 0x46, 0x5F, 0xAC, 0xDF, 0x64, 0x10, + 0x8A, 0xEF, 0x46, 0xF0, 0x90, 0xF0, 0x0F, 0x2D, 0xF4, 0x88, 0x0B, 0xB1, + 0x29, 0xAA, 0xAF, 0x85, 0xAA, 0x49, 0x58, 0xA8, 0xBF, 0x63, 0xA0, 0x38, + 0x91, 0xE6, 0xB3, 0xE6, 0x77, 0x68, 0xC4, 0xF9, 0x2A, 0x19, 0x84, 0xBB, + 0x0E, 0xE1, 0xF5, 0xAF, 0x89, 0xEC, 0xA5, 0x2F, 0x50, 0x20, 0x74, 0x1E, + 0x12, 0x41, 0x73, 0x1E, 0x24, 0xD9, 0xCA, 0xCE, 0x2C, 0xA1, 0x59, 0x35, + 0xC0, 0xC8, 0x1D, 0x46, 0x27, 0x61, 0x5A, 0x8F, 0xF9, 0x4D, 0xD3, 0x72, + 0x79, 0x66, 0x1E, 0x9F, 0x15, 0x90, 0x21, 0x2D, 0xFD, 0xED, 0x8B, 0x56, + 0x70, 0x03, 0x4A, 0x49, 0x3E, 0x7F, 0x69, 0x31, 0x12, 0x69, 0xC7, 0x1E, + 0x5C, 0xCA, 0x7A, 0x13, 0x8B, 0xE8, 0xE6, 0xF5, 0x60, 0x0F, 0xCC, 0x93, + 0x2C, 0x84, 0x7F, 0xF1, 0xFC, 0x6A, 0xFC, 0x9B, 0x47, 0x9D, 0xDB, 0xAD, + 0x88, 0x3D, 0xF3, 0x76, 0x75, 0x33, 0xD7, 0x4B, 0xA4, 0xC8, 0x8B, 0xF9, + 0xF5, 0x43, 0x58, 0x4F, 0xCB, 0xC8, 0x03, 0x54, 0x8F, 0xA5, 0x85, 0x78, + 0x04, 0x1A, 0xF3, 0x73, 0xF2, 0xD7, 0x87, 0x1D, 0x41, 0x9F, 0xE7, 0xD8, + 0x17, 0xCE, 0x1A, 0x9C, 0x0F, 0x4A, 0xFC, 0xDC, 0x44, 0x68, 0x54, 0x68, + 0xE2, 0x41, 0x3C, 0xFE, 0x2C, 0x84, 0x86, 0x37, 0x3C, 0xCD, 0x3F, 0x2F, + 0xA2, 0xDB, 0xE7, 0xF7, 0x54, 0x03, 0x5F, 0x59, 0xD3, 0xF7, 0x91, 0x78, + 0xC7, 0x8B, 0x77, 0x6A, 0x16, 0xE5, 0x49, 0x85, 0x90, 0x45, 0x72, 0x70, + 0x2F, 0x91, 0x5D, 0xF8, 0x3E, 0x65, 0x40, 0x0B, 0x19, 0x99, 0xC9, 0x26, + 0x20, 0x5A, 0x68, 0xC1, 0x35, 0xBF, 0x4F, 0xA7, 0x51, 0xF1, 0xD8, 0x11, + 0x2B, 0x5B, 0xE0, 0x9A, 0x9E, 0x28, 0x3B, 0x0A, 0x3A, 0x0A, 0x1F, 0xC1, + 0x81, 0xE5, 0x2E, 0xF0, 0xA6, 0xB9, 0x69, 0xA5, 0x88, 0x94, 0xE6, 0x6B, + 0x13, 0x7F, 0xD1, 0x64, 0x3F, 0x3D, 0x9C, 0x70, 0x46, 0xE5, 0xA2, 0x85, + 0x7B, 0x58, 0x84, 0x27, 0xDC, 0xC4, 0x80, 0x3E, 0x67, 0x9A, 0x9A, 0xC7, + 0x9A, 0x31, 0x0E, 0x30, 0xEC, 0xE6, 0x17, 0x40, 0x95, 0xD9, 0x45, 0xED, + 0x01, 0x96, 0xAA, 0xBF, 0x0C, 0xF3, 0x4B, 0xD1, 0x63, 0xF7, 0x13, 0x58, + 0xC0, 0xB8, 0xF3, 0xFA, 0x67, 0xDD, 0x9B, 0x7D, 0x6D, 0x4A, 0xFF, 0x32, + 0x4C, 0xB5, 0x25, 0x3B, 0xFF, 0x1C, 0x67, 0x0F, 0x85, 0x22, 0x59, 0x05, + 0x91, 0x91, 0x41, 0x77, 0x81, 0xD0, 0x85, 0x4C, 0x87, 0x10, 0x71, 0xFF, + 0x9E, 0x43, 0x1B, 0xAE, 0x95, 0x75, 0x2D, 0x81 +}; + +static const unsigned char TA174_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA175_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA175_EC_Q[] = { + 0x04, 0x0D, 0x30, 0x5E, 0x1B, 0x15, 0x9D, 0x03, 0xD0, 0xA1, 0x79, 0x35, + 0xB7, 0x3A, 0x3C, 0x92, 0x7A, 0xCA, 0x15, 0x1C, 0xCD, 0x62, 0xF3, 0x9C, + 0x26, 0x5C, 0x07, 0x3D, 0xE5, 0x54, 0xFA, 0xA3, 0xD6, 0xCC, 0x12, 0xEA, + 0xF4, 0x14, 0x5F, 0xE8, 0x8E, 0x19, 0xAB, 0x2F, 0x2E, 0x48, 0xE6, 0xAC, + 0x18, 0x43, 0x78, 0xAC, 0xD0, 0x37, 0xC3, 0xBD, 0xB2, 0xCD, 0x2C, 0xE6, + 0x47, 0xE2, 0x1A, 0xE6, 0x63, 0xB8, 0x3D, 0x2E, 0x2F, 0x78, 0xC4, 0x4F, + 0xDB, 0xF4, 0x0F, 0xA4, 0x68, 0x4C, 0x55, 0x72, 0x6B, 0x95, 0x1D, 0x4E, + 0x18, 0x42, 0x95, 0x78, 0xCC, 0x37, 0x3C, 0x91, 0xE2, 0x9B, 0x65, 0x2B, + 0x29 +}; + +static const unsigned char TA176_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA176_RSA_N[] = { + 0xD9, 0xE7, 0x28, 0x2F, 0x52, 0x3F, 0x36, 0x72, 0x49, 0x88, 0x93, 0x34, + 0xF3, 0xF8, 0x6A, 0x1E, 0x31, 0x54, 0x80, 0x9F, 0xAD, 0x54, 0x41, 0xB5, + 0x47, 0xDF, 0x96, 0xA8, 0xD4, 0xAF, 0x80, 0x2D, 0xB9, 0x0A, 0xCF, 0x75, + 0xFD, 0x89, 0xA5, 0x7D, 0x24, 0xFA, 0xE3, 0x22, 0x0C, 0x2B, 0xBC, 0x95, + 0x17, 0x0B, 0x33, 0xBF, 0x19, 0x4D, 0x41, 0x06, 0x90, 0x00, 0xBD, 0x0C, + 0x4D, 0x10, 0xFE, 0x07, 0xB5, 0xE7, 0x1C, 0x6E, 0x22, 0x55, 0x31, 0x65, + 0x97, 0xBD, 0xD3, 0x17, 0xD2, 0x1E, 0x62, 0xF3, 0xDB, 0xEA, 0x6C, 0x50, + 0x8C, 0x3F, 0x84, 0x0C, 0x96, 0xCF, 0xB7, 0xCB, 0x03, 0xE0, 0xCA, 0x6D, + 0xA1, 0x14, 0x4C, 0x1B, 0x89, 0xDD, 0xED, 0x00, 0xB0, 0x52, 0x7C, 0xAF, + 0x91, 0x6C, 0xB1, 0x38, 0x13, 0xD1, 0xE9, 0x12, 0x08, 0xC0, 0x00, 0xB0, + 0x1C, 0x2B, 0x11, 0xDA, 0x77, 0x70, 0x36, 0x9B, 0xAE, 0xCE, 0x79, 0x87, + 0xDC, 0x82, 0x70, 0xE6, 0x09, 0x74, 0x70, 0x55, 0x69, 0xAF, 0xA3, 0x68, + 0x9F, 0xBF, 0xDD, 0xB6, 0x79, 0xB3, 0xF2, 0x9D, 0x70, 0x29, 0x55, 0xF4, + 0xAB, 0xFF, 0x95, 0x61, 0xF3, 0xC9, 0x40, 0x6F, 0x1D, 0xD1, 0xBE, 0x93, + 0xBB, 0xD3, 0x88, 0x2A, 0xBB, 0x9D, 0xBF, 0x72, 0x5A, 0x56, 0x71, 0x3B, + 0x3F, 0xD4, 0xF3, 0xD1, 0x0A, 0xFE, 0x28, 0xEF, 0xA3, 0xEE, 0xD9, 0x99, + 0xAF, 0x03, 0xD3, 0x8F, 0x60, 0xB7, 0xF2, 0x92, 0xA1, 0xB1, 0xBD, 0x89, + 0x89, 0x1F, 0x30, 0xCD, 0xC3, 0xA6, 0x2E, 0x62, 0x33, 0xAE, 0x16, 0x02, + 0x77, 0x44, 0x5A, 0xE7, 0x81, 0x0A, 0x3C, 0xA7, 0x44, 0x2E, 0x79, 0xB8, + 0x3F, 0x04, 0xBC, 0x5C, 0xA0, 0x87, 0xE1, 0x1B, 0xAF, 0x51, 0x8E, 0xCD, + 0xEC, 0x2C, 0xFA, 0xF8, 0xFE, 0x6D, 0xF0, 0x3A, 0x7C, 0xAA, 0x8B, 0xE4, + 0x67, 0x95, 0x31, 0x8D +}; + +static const unsigned char TA176_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA177_DN[] = { + 0x30, 0x5E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x21, 0x65, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA177_RSA_N[] = { + 0xE1, 0x25, 0x0F, 0xEE, 0x8D, 0xDB, 0x88, 0x33, 0x75, 0x67, 0xCD, 0xAD, + 0x1F, 0x7D, 0x3A, 0x4E, 0x6D, 0x9D, 0xD3, 0x2F, 0x14, 0xF3, 0x63, 0x74, + 0xCB, 0x01, 0x21, 0x6A, 0x37, 0xEA, 0x84, 0x50, 0x07, 0x4B, 0x26, 0x5B, + 0x09, 0x43, 0x6C, 0x21, 0x9E, 0x6A, 0xC8, 0xD5, 0x03, 0xF5, 0x60, 0x69, + 0x8F, 0xCC, 0xF0, 0x22, 0xE4, 0x1F, 0xE7, 0xF7, 0x6A, 0x22, 0x31, 0xB7, + 0x2C, 0x15, 0xF2, 0xE0, 0xFE, 0x00, 0x6A, 0x43, 0xFF, 0x87, 0x65, 0xC6, + 0xB5, 0x1A, 0xC1, 0xA7, 0x4C, 0x6D, 0x22, 0x70, 0x21, 0x8A, 0x31, 0xF2, + 0x97, 0x74, 0x89, 0x09, 0x12, 0x26, 0x1C, 0x9E, 0xCA, 0xD9, 0x12, 0xA2, + 0x95, 0x3C, 0xDA, 0xE9, 0x67, 0xBF, 0x08, 0xA0, 0x64, 0xE3, 0xD6, 0x42, + 0xB7, 0x45, 0xEF, 0x97, 0xF4, 0xF6, 0xF5, 0xD7, 0xB5, 0x4A, 0x15, 0x02, + 0x58, 0x7D, 0x98, 0x58, 0x4B, 0x60, 0xBC, 0xCD, 0xD7, 0x0D, 0x9A, 0x13, + 0x33, 0x53, 0xD1, 0x61, 0xF9, 0x7A, 0xD5, 0xD7, 0x78, 0xB3, 0x9A, 0x33, + 0xF7, 0x00, 0x86, 0xCE, 0x1D, 0x4D, 0x94, 0x38, 0xAF, 0xA8, 0xEC, 0x78, + 0x51, 0x70, 0x8A, 0x5C, 0x10, 0x83, 0x51, 0x21, 0xF7, 0x11, 0x3D, 0x34, + 0x86, 0x5E, 0xE5, 0x48, 0xCD, 0x97, 0x81, 0x82, 0x35, 0x4C, 0x19, 0xEC, + 0x65, 0xF6, 0x6B, 0xC5, 0x05, 0xA1, 0xEE, 0x47, 0x13, 0xD6, 0xB3, 0x21, + 0x27, 0x94, 0x10, 0x0A, 0xD9, 0x24, 0x3B, 0xBA, 0xBE, 0x44, 0x13, 0x46, + 0x30, 0x3F, 0x97, 0x3C, 0xD8, 0xD7, 0xD7, 0x6A, 0xEE, 0x3B, 0x38, 0xE3, + 0x2B, 0xD4, 0x97, 0x0E, 0xB9, 0x1B, 0xE7, 0x07, 0x49, 0x7F, 0x37, 0x2A, + 0xF9, 0x77, 0x78, 0xCF, 0x54, 0xED, 0x5B, 0x46, 0x9D, 0xA3, 0x80, 0x0E, + 0x91, 0x43, 0xC1, 0xD6, 0x5B, 0x5F, 0x14, 0xBA, 0x9F, 0xA6, 0x8D, 0x24, + 0x47, 0x40, 0x59, 0xBF, 0x72, 0x38, 0xB2, 0x36, 0x6C, 0x37, 0xFF, 0x99, + 0xD1, 0x5D, 0x0E, 0x59, 0x0A, 0xAB, 0x69, 0xF7, 0xC0, 0xB2, 0x04, 0x45, + 0x7A, 0x54, 0x00, 0xAE, 0xBE, 0x53, 0xF6, 0xB5, 0xE7, 0xE1, 0xF8, 0x3C, + 0xA3, 0x31, 0xD2, 0xA9, 0xFE, 0x21, 0x52, 0x64, 0xC5, 0xA6, 0x67, 0xF0, + 0x75, 0x07, 0x06, 0x94, 0x14, 0x81, 0x55, 0xC6, 0x27, 0xE4, 0x01, 0x8F, + 0x17, 0xC1, 0x6A, 0x71, 0xD7, 0xBE, 0x4B, 0xFB, 0x94, 0x58, 0x7D, 0x7E, + 0x11, 0x33, 0xB1, 0x42, 0xF7, 0x62, 0x6C, 0x18, 0xD6, 0xCF, 0x09, 0x68, + 0x3E, 0x7F, 0x6C, 0xF6, 0x1E, 0x8F, 0x62, 0xAD, 0xA5, 0x63, 0xDB, 0x09, + 0xA7, 0x1F, 0x22, 0x42, 0x41, 0x1E, 0x6F, 0x99, 0x8A, 0x3E, 0xD7, 0xF9, + 0x3F, 0x40, 0x7A, 0x79, 0xB0, 0xA5, 0x01, 0x92, 0xD2, 0x9D, 0x3D, 0x08, + 0x15, 0xA5, 0x10, 0x01, 0x2D, 0xB3, 0x32, 0x76, 0xA8, 0x95, 0x0D, 0xB3, + 0x7A, 0x9A, 0xFB, 0x07, 0x10, 0x78, 0x11, 0x6F, 0xE1, 0x8F, 0xC7, 0xBA, + 0x0F, 0x25, 0x1A, 0x74, 0x2A, 0xE5, 0x1C, 0x98, 0x41, 0x99, 0xDF, 0x21, + 0x87, 0xE8, 0x95, 0x06, 0x6A, 0x0A, 0xB3, 0x6A, 0x47, 0x76, 0x65, 0xF6, + 0x3A, 0xCF, 0x8F, 0x62, 0x17, 0x19, 0x7B, 0x0A, 0x28, 0xCD, 0x1A, 0xD2, + 0x83, 0x1E, 0x21, 0xC7, 0x2C, 0xBF, 0xBE, 0xFF, 0x61, 0x68, 0xB7, 0x67, + 0x1B, 0xBB, 0x78, 0x4D, 0x8D, 0xCE, 0x67, 0xE5, 0xE4, 0xC1, 0x8E, 0xB7, + 0x23, 0x66, 0xE2, 0x9D, 0x90, 0x75, 0x34, 0x98, 0xA9, 0x36, 0x2B, 0x8A, + 0x9A, 0x94, 0xB9, 0x9D, 0xEC, 0xCC, 0x8A, 0xB1, 0xF8, 0x25, 0x89, 0x5C, + 0x5A, 0xB6, 0x2F, 0x8C, 0x1F, 0x6D, 0x79, 0x24, 0xA7, 0x52, 0x68, 0xC3, + 0x84, 0x35, 0xE2, 0x66, 0x8D, 0x63, 0x0E, 0x25, 0x4D, 0xD5, 0x19, 0xB2, + 0xE6, 0x79, 0x37, 0xA7, 0x22, 0x9D, 0x54, 0x31 +}; + +static const unsigned char TA177_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA178_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA178_EC_Q[] = { + 0x04, 0xC6, 0xCB, 0xC7, 0x28, 0xD1, 0xFB, 0x84, 0xF5, 0x9A, 0xEF, 0x42, + 0x14, 0x20, 0xE1, 0x43, 0x6B, 0x6E, 0x75, 0xAD, 0xFC, 0x2B, 0x03, 0x84, + 0xD4, 0x76, 0x93, 0x25, 0xD7, 0x59, 0x3B, 0x41, 0x65, 0x6B, 0x1E, 0xE6, + 0x34, 0x2A, 0xBB, 0x74, 0xF6, 0x12, 0xCE, 0xE8, 0x6D, 0xE7, 0xAB, 0xE4, + 0x3C, 0x4E, 0x3F, 0x44, 0x08, 0x8B, 0xCD, 0x16, 0x71, 0xCB, 0xBF, 0x92, + 0x99, 0xF4, 0xA4, 0xD7, 0x3C, 0x50, 0x54, 0x52, 0x90, 0x85, 0x83, 0x78, + 0x94, 0x67, 0x67, 0xA3, 0x1C, 0x09, 0x19, 0x3D, 0x75, 0x34, 0x85, 0xDE, + 0xED, 0x60, 0x7D, 0xC7, 0x0C, 0xB4, 0x41, 0x52, 0xB9, 0x6E, 0xE5, 0xEE, + 0x42 +}; + +static const unsigned char TA179_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, + 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA179_RSA_N[] = { + 0x8B, 0xC2, 0xE7, 0xAF, 0x65, 0x9B, 0x05, 0x67, 0x96, 0xC9, 0x0D, 0x24, + 0xB9, 0xD0, 0x0E, 0x64, 0xFC, 0xCE, 0xE2, 0x24, 0x18, 0x2C, 0x84, 0x7F, + 0x77, 0x51, 0xCB, 0x04, 0x11, 0x36, 0xB8, 0x5E, 0xED, 0x69, 0x71, 0xA7, + 0x9E, 0xE4, 0x25, 0x09, 0x97, 0x67, 0xC1, 0x47, 0xC2, 0xCF, 0x91, 0x16, + 0x36, 0x62, 0x3D, 0x38, 0x04, 0xE1, 0x51, 0x82, 0xFF, 0xAC, 0xD2, 0xB4, + 0x69, 0xDD, 0x2E, 0xEC, 0x11, 0xA3, 0x45, 0xEE, 0x6B, 0x6B, 0x3B, 0x4C, + 0xBF, 0x8C, 0x8D, 0xA4, 0x1E, 0x9D, 0x11, 0xB9, 0xE9, 0x38, 0xF9, 0x7A, + 0x0E, 0x0C, 0x98, 0xE2, 0x23, 0x1D, 0xD1, 0x4E, 0x63, 0xD4, 0xE7, 0xB8, + 0x41, 0x44, 0xFB, 0x6B, 0xAF, 0x6B, 0xDA, 0x1F, 0xD3, 0xC5, 0x91, 0x88, + 0x5B, 0xA4, 0x89, 0x92, 0xD1, 0x81, 0xE6, 0x8C, 0x39, 0x58, 0xA0, 0xD6, + 0x69, 0x43, 0xA9, 0xAD, 0x98, 0x52, 0x58, 0x6E, 0xDB, 0x0A, 0xFB, 0x6B, + 0xCF, 0x68, 0xFA, 0xE3, 0xA4, 0x5E, 0x3A, 0x45, 0x73, 0x98, 0x07, 0xEA, + 0x5F, 0x02, 0x72, 0xDE, 0x0C, 0xA5, 0xB3, 0x9F, 0xAE, 0xA9, 0x1D, 0xB7, + 0x1D, 0xB3, 0xFC, 0x8A, 0x59, 0xE7, 0x6E, 0x72, 0x65, 0xAD, 0xF5, 0x30, + 0x94, 0x23, 0x07, 0xF3, 0x82, 0x16, 0x4B, 0x35, 0x98, 0x9C, 0x53, 0xBB, + 0x2F, 0xCA, 0xE4, 0x5A, 0xD9, 0xC7, 0x8D, 0x1D, 0xFC, 0x98, 0x99, 0xFB, + 0x2C, 0xA4, 0x82, 0x6B, 0xF0, 0x2A, 0x1F, 0x8E, 0x0B, 0x5F, 0x71, 0x5C, + 0x5C, 0xAE, 0x42, 0x7B, 0x29, 0x89, 0x81, 0xCB, 0x03, 0xA3, 0x99, 0xCA, + 0x88, 0x9E, 0x0B, 0x40, 0x09, 0x41, 0x33, 0xDB, 0xE6, 0x58, 0x7A, 0xFD, + 0xAE, 0x99, 0x70, 0xC0, 0x5A, 0x0F, 0xD6, 0x13, 0x86, 0x71, 0x2F, 0x76, + 0x69, 0xFC, 0x90, 0xDD, 0xDB, 0x2D, 0x6E, 0xD1, 0xF2, 0x9B, 0xF5, 0x1A, + 0x6B, 0x9E, 0x6F, 0x15, 0x8C, 0x7A, 0xF0, 0x4B, 0x28, 0xA0, 0x22, 0x38, + 0x80, 0x24, 0x6C, 0x36, 0xA4, 0x3B, 0xF2, 0x30, 0x91, 0xF3, 0x78, 0x13, + 0xCF, 0xC1, 0x3F, 0x35, 0xAB, 0xF1, 0x1D, 0x11, 0x23, 0xB5, 0x43, 0x22, + 0x9E, 0x01, 0x92, 0xB7, 0x18, 0x02, 0xE5, 0x11, 0xD1, 0x82, 0xDB, 0x15, + 0x00, 0xCC, 0x61, 0x37, 0xC1, 0x2A, 0x7C, 0x9A, 0xE1, 0xD0, 0xBA, 0xB3, + 0x50, 0x46, 0xEE, 0x82, 0xAC, 0x9D, 0x31, 0xF8, 0xFB, 0x23, 0xE2, 0x03, + 0x00, 0x48, 0x70, 0xA3, 0x09, 0x26, 0x79, 0x15, 0x53, 0x60, 0xF3, 0x38, + 0x5C, 0xAD, 0x38, 0xEA, 0x81, 0x00, 0x63, 0x14, 0xB9, 0x33, 0x5E, 0xDD, + 0x0B, 0xDB, 0xA0, 0x45, 0x07, 0x1A, 0x33, 0x09, 0xF8, 0x4D, 0xB4, 0xA7, + 0x02, 0xA6, 0x69, 0xF4, 0xC2, 0x59, 0x05, 0x88, 0x65, 0x85, 0x56, 0xAE, + 0x4B, 0xCB, 0xE0, 0xDE, 0x3C, 0x7D, 0x2D, 0x1A, 0xC8, 0xE9, 0xFB, 0x1F, + 0xA3, 0x61, 0x4A, 0xD6, 0x2A, 0x13, 0xAD, 0x77, 0x4C, 0x1A, 0x18, 0x9B, + 0x91, 0x0F, 0x58, 0xD8, 0x06, 0x54, 0xC5, 0x97, 0xF8, 0xAA, 0x3F, 0x20, + 0x8A, 0xA6, 0x85, 0xA6, 0x77, 0xF6, 0xA6, 0xFC, 0x1C, 0xE2, 0xEE, 0x6E, + 0x94, 0x33, 0x2A, 0x83, 0x50, 0x84, 0x0A, 0xE5, 0x4F, 0x86, 0xF8, 0x50, + 0x45, 0x78, 0x00, 0x81, 0xEB, 0x5B, 0x68, 0xE3, 0x26, 0x8D, 0xCC, 0x7B, + 0x5C, 0x51, 0xF4, 0x14, 0x2C, 0x40, 0xBE, 0x1A, 0x60, 0x1D, 0x7A, 0x72, + 0x61, 0x1D, 0x1F, 0x63, 0x2D, 0x88, 0xAA, 0xCE, 0xA2, 0x45, 0x90, 0x08, + 0xFC, 0x6B, 0xBE, 0xB3, 0x50, 0x2A, 0x5A, 0xFD, 0xA8, 0x48, 0x18, 0x46, + 0xD6, 0x90, 0x40, 0x92, 0x90, 0x0A, 0x84, 0x5E, 0x68, 0x31, 0xF8, 0xEB, + 0xED, 0x0D, 0xD3, 0x1D, 0xC6, 0x7D, 0x99, 0x18, 0x55, 0x56, 0x27, 0x65, + 0x2E, 0x8D, 0x45, 0xC5, 0x24, 0xEC, 0xCE, 0xE3 +}; + +static const unsigned char TA179_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA180_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA180_RSA_N[] = { + 0xD8, 0x8E, 0xA3, 0x89, 0x80, 0x0B, 0xB2, 0x57, 0x52, 0xDC, 0xA9, 0x53, + 0x4C, 0x37, 0xB9, 0x7F, 0x63, 0x17, 0x13, 0xEF, 0xA7, 0x5B, 0x23, 0x5B, + 0x69, 0x75, 0xB0, 0x99, 0x0A, 0x17, 0xC1, 0x8B, 0xC4, 0xDB, 0xA8, 0xE0, + 0xCC, 0x31, 0xBA, 0xC2, 0xF2, 0xCD, 0x5D, 0xE9, 0xB7, 0xF8, 0x1D, 0xAF, + 0x6A, 0xC4, 0x95, 0x87, 0xD7, 0x47, 0xC9, 0x95, 0xD8, 0x82, 0x04, 0x50, + 0x3D, 0x81, 0x08, 0xFF, 0xE4, 0x3D, 0xB3, 0xB1, 0xD6, 0xC5, 0xB2, 0xFD, + 0x88, 0x09, 0xDB, 0x9C, 0x84, 0xEC, 0x25, 0x17, 0x14, 0x87, 0x7F, 0x30, + 0x78, 0x9B, 0x6A, 0x58, 0xC9, 0xB6, 0x73, 0x28, 0x3C, 0x34, 0xF7, 0x99, + 0xF7, 0x7F, 0xD3, 0xA6, 0xF8, 0x1C, 0x45, 0x7C, 0xAD, 0x2C, 0x8C, 0x94, + 0x3F, 0xD8, 0x67, 0x10, 0x53, 0x7E, 0x22, 0xCD, 0x4E, 0x25, 0x51, 0xF0, + 0x25, 0x24, 0x35, 0x11, 0x5E, 0x10, 0xC6, 0xEC, 0x87, 0x66, 0x89, 0x81, + 0x68, 0xBA, 0xCC, 0x2B, 0x9D, 0x47, 0x73, 0x1F, 0xBD, 0xCD, 0x91, 0xA4, + 0x72, 0x6A, 0x9C, 0xA2, 0x1B, 0x18, 0xA0, 0x6F, 0xEC, 0x50, 0xF4, 0x7D, + 0x40, 0xC2, 0xA8, 0x30, 0xCF, 0xBD, 0x73, 0xC8, 0x13, 0x2B, 0x10, 0x13, + 0x1E, 0x8B, 0x9A, 0xA8, 0x3A, 0x94, 0x73, 0xD3, 0x18, 0x69, 0x0A, 0x4A, + 0xFF, 0xC1, 0x01, 0x03, 0xFF, 0x79, 0x7F, 0xB5, 0x48, 0x7F, 0x7B, 0xEE, + 0xE8, 0x29, 0x6F, 0x36, 0x4C, 0x95, 0x61, 0x86, 0xD8, 0xF9, 0xA2, 0x73, + 0x8A, 0xEE, 0xAE, 0x2F, 0x96, 0xEE, 0x68, 0xCD, 0x3D, 0x4D, 0x28, 0x42, + 0xF9, 0x45, 0x2B, 0x32, 0x1B, 0x46, 0x55, 0x16, 0x6A, 0xA6, 0x4B, 0x29, + 0xF9, 0xBB, 0x95, 0x56, 0xBF, 0x46, 0x1D, 0xEC, 0x1D, 0x93, 0x1D, 0xC0, + 0x65, 0xB2, 0x1F, 0xA1, 0x43, 0xAE, 0x56, 0x9E, 0xA0, 0xB1, 0x8F, 0x6B, + 0x12, 0xB7, 0x60, 0x6D, 0x78, 0x0B, 0xCA, 0x8A, 0x5C, 0xED, 0x1E, 0x96, + 0x0E, 0x83, 0xA6, 0x48, 0x95, 0x8D, 0x3B, 0xA3, 0x21, 0xC4, 0xAE, 0x58, + 0xC6, 0x00, 0xB2, 0x84, 0xB4, 0x23, 0xA4, 0x96, 0x86, 0x35, 0xB8, 0xD8, + 0x9E, 0xD8, 0xAC, 0x34, 0x49, 0x98, 0x63, 0x95, 0xC5, 0xCB, 0x6D, 0x48, + 0x47, 0xE2, 0xF2, 0x2E, 0x18, 0x1E, 0xD0, 0x31, 0xAB, 0xDD, 0x74, 0xEC, + 0xF9, 0xDC, 0x8C, 0xB8, 0x1C, 0x8E, 0x68, 0x23, 0xBA, 0xD0, 0xF3, 0x50, + 0xDC, 0xCF, 0x65, 0x8F, 0x73, 0x3A, 0x32, 0xC7, 0x7C, 0xFE, 0xCA, 0x82, + 0x22, 0x4F, 0xBE, 0x8E, 0x62, 0x47, 0x66, 0xE5, 0xCD, 0x87, 0xE2, 0xE8, + 0xD5, 0x0F, 0x18, 0x9F, 0xE5, 0x04, 0x72, 0x4B, 0x46, 0x3C, 0x10, 0xF2, + 0x44, 0xC2, 0x64, 0x56, 0x71, 0x4E, 0x75, 0xE8, 0x9C, 0xC9, 0x26, 0x74, + 0xC5, 0x7D, 0x59, 0xD1, 0x0A, 0x5B, 0x0F, 0x6D, 0xFE, 0x9E, 0x75, 0x1C, + 0x18, 0xC6, 0x1A, 0x3A, 0x7C, 0xD8, 0x0D, 0x04, 0xCC, 0xCD, 0xB7, 0x45, + 0x65, 0x7A, 0xB1, 0x8F, 0xB8, 0xAE, 0x84, 0x48, 0x3E, 0xB3, 0x7A, 0x4D, + 0xA8, 0x03, 0xE2, 0xE2, 0x7E, 0x01, 0x16, 0x59, 0x68, 0x18, 0x43, 0x33, + 0xB0, 0xD2, 0xDC, 0xB0, 0x1A, 0x43, 0x35, 0xEE, 0xA5, 0xDA, 0xA9, 0x46, + 0x5C, 0xAE, 0x86, 0x81, 0x41, 0x01, 0x4A, 0x74, 0x26, 0xEC, 0x9F, 0x06, + 0xBF, 0xC2, 0x05, 0x37, 0x64, 0x75, 0x78, 0x29, 0x68, 0xFD, 0xC5, 0xF5, + 0xEB, 0xFE, 0x47, 0xF9, 0xE4, 0x85, 0xB0, 0xE1, 0x7B, 0x31, 0x9D, 0xA6, + 0x7F, 0x72, 0xA3, 0xB9, 0xC4, 0x2C, 0x2E, 0xCC, 0x99, 0x57, 0x0E, 0x21, + 0x0C, 0x45, 0x01, 0x94, 0x65, 0xEB, 0x65, 0x09, 0xC6, 0x63, 0x22, 0x0B, + 0x33, 0x49, 0x92, 0x48, 0x3C, 0xFC, 0xCD, 0xCE, 0xB0, 0x3E, 0x8E, 0x9E, + 0x8B, 0xF8, 0xFE, 0x49, 0xC5, 0x35, 0x72, 0x47 +}; + +static const unsigned char TA180_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA181_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x18, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA181_RSA_N[] = { + 0xBF, 0xE6, 0x90, 0x73, 0x68, 0xDE, 0xBB, 0xE4, 0x5D, 0x4A, 0x3C, 0x30, + 0x22, 0x30, 0x69, 0x33, 0xEC, 0xC2, 0xA7, 0x25, 0x2E, 0xC9, 0x21, 0x3D, + 0xF2, 0x8A, 0xD8, 0x59, 0xC2, 0xE1, 0x29, 0xA7, 0x3D, 0x58, 0xAB, 0x76, + 0x9A, 0xCD, 0xAE, 0x7B, 0x1B, 0x84, 0x0D, 0xC4, 0x30, 0x1F, 0xF3, 0x1B, + 0xA4, 0x38, 0x16, 0xEB, 0x56, 0xC6, 0x97, 0x6D, 0x1D, 0xAB, 0xB2, 0x79, + 0xF2, 0xCA, 0x11, 0xD2, 0xE4, 0x5F, 0xD6, 0x05, 0x3C, 0x52, 0x0F, 0x52, + 0x1F, 0xC6, 0x9E, 0x15, 0xA5, 0x7E, 0xBE, 0x9F, 0xA9, 0x57, 0x16, 0x59, + 0x55, 0x72, 0xAF, 0x68, 0x93, 0x70, 0xC2, 0xB2, 0xBA, 0x75, 0x99, 0x6A, + 0x73, 0x32, 0x94, 0xD1, 0x10, 0x44, 0x10, 0x2E, 0xDF, 0x82, 0xF3, 0x07, + 0x84, 0xE6, 0x74, 0x3B, 0x6D, 0x71, 0xE2, 0x2D, 0x0C, 0x1B, 0xEE, 0x20, + 0xD5, 0xC9, 0x20, 0x1D, 0x63, 0x29, 0x2D, 0xCE, 0xEC, 0x5E, 0x4E, 0xC8, + 0x93, 0xF8, 0x21, 0x61, 0x9B, 0x34, 0xEB, 0x05, 0xC6, 0x5E, 0xEC, 0x5B, + 0x1A, 0xBC, 0xEB, 0xC9, 0xCF, 0xCD, 0xAC, 0x34, 0x40, 0x5F, 0xB1, 0x7A, + 0x66, 0xEE, 0x77, 0xC8, 0x48, 0xA8, 0x66, 0x57, 0x57, 0x9F, 0x54, 0x58, + 0x8E, 0x0C, 0x2B, 0xB7, 0x4F, 0xA7, 0x30, 0xD9, 0x56, 0xEE, 0xCA, 0x7B, + 0x5D, 0xE3, 0xAD, 0xC9, 0x4F, 0x5E, 0xE5, 0x35, 0xE7, 0x31, 0xCB, 0xDA, + 0x93, 0x5E, 0xDC, 0x8E, 0x8F, 0x80, 0xDA, 0xB6, 0x91, 0x98, 0x40, 0x90, + 0x79, 0xC3, 0x78, 0xC7, 0xB6, 0xB1, 0xC4, 0xB5, 0x6A, 0x18, 0x38, 0x03, + 0x10, 0x8D, 0xD8, 0xD4, 0x37, 0xA4, 0x2E, 0x05, 0x7D, 0x88, 0xF5, 0x82, + 0x3E, 0x10, 0x91, 0x70, 0xAB, 0x55, 0x82, 0x41, 0x32, 0xD7, 0xDB, 0x04, + 0x73, 0x2A, 0x6E, 0x91, 0x01, 0x7C, 0x21, 0x4C, 0xD4, 0xBC, 0xAE, 0x1B, + 0x03, 0x75, 0x5D, 0x78, 0x66, 0xD9, 0x3A, 0x31, 0x44, 0x9A, 0x33, 0x40, + 0xBF, 0x08, 0xD7, 0x5A, 0x49, 0xA4, 0xC2, 0xE6, 0xA9, 0xA0, 0x67, 0xDD, + 0xA4, 0x27, 0xBC, 0xA1, 0x4F, 0x39, 0xB5, 0x11, 0x58, 0x17, 0xF7, 0x24, + 0x5C, 0x46, 0x8F, 0x64, 0xF7, 0xC1, 0x69, 0x88, 0x76, 0x98, 0x76, 0x3D, + 0x59, 0x5D, 0x42, 0x76, 0x87, 0x89, 0x97, 0x69, 0x7A, 0x48, 0xF0, 0xE0, + 0xA2, 0x12, 0x1B, 0x66, 0x9A, 0x74, 0xCA, 0xDE, 0x4B, 0x1E, 0xE7, 0x0E, + 0x63, 0xAE, 0xE6, 0xD4, 0xEF, 0x92, 0x92, 0x3A, 0x9E, 0x3D, 0xDC, 0x00, + 0xE4, 0x45, 0x25, 0x89, 0xB6, 0x9A, 0x44, 0x19, 0x2B, 0x7E, 0xC0, 0x94, + 0xB4, 0xD2, 0x61, 0x6D, 0xEB, 0x33, 0xD9, 0xC5, 0xDF, 0x4B, 0x04, 0x00, + 0xCC, 0x7D, 0x1C, 0x95, 0xC3, 0x8F, 0xF7, 0x21, 0xB2, 0xB2, 0x11, 0xB7, + 0xBB, 0x7F, 0xF2, 0xD5, 0x8C, 0x70, 0x2C, 0x41, 0x60, 0xAA, 0xB1, 0x63, + 0x18, 0x44, 0x95, 0x1A, 0x76, 0x62, 0x7E, 0xF6, 0x80, 0xB0, 0xFB, 0xE8, + 0x64, 0xA6, 0x33, 0xD1, 0x89, 0x07, 0xE1, 0xBD, 0xB7, 0xE6, 0x43, 0xA4, + 0x18, 0xB8, 0xA6, 0x77, 0x01, 0xE1, 0x0F, 0x94, 0x0C, 0x21, 0x1D, 0xB2, + 0x54, 0x29, 0x25, 0x89, 0x6C, 0xE5, 0x0E, 0x52, 0x51, 0x47, 0x74, 0xBE, + 0x26, 0xAC, 0xB6, 0x41, 0x75, 0xDE, 0x7A, 0xAC, 0x5F, 0x8D, 0x3F, 0xC9, + 0xBC, 0xD3, 0x41, 0x11, 0x12, 0x5B, 0xE5, 0x10, 0x50, 0xEB, 0x31, 0xC5, + 0xCA, 0x72, 0x16, 0x22, 0x09, 0xDF, 0x7C, 0x4C, 0x75, 0x3F, 0x63, 0xEC, + 0x21, 0x5F, 0xC4, 0x20, 0x51, 0x6B, 0x6F, 0xB1, 0xAB, 0x86, 0x8B, 0x4F, + 0xC2, 0xD6, 0x45, 0x5F, 0x9D, 0x20, 0xFC, 0xA1, 0x1E, 0xC5, 0xC0, 0x8F, + 0xA2, 0xB1, 0x7E, 0x0A, 0x26, 0x99, 0xF5, 0xE4, 0x69, 0x2F, 0x98, 0x1D, + 0x2D, 0xF5, 0xD9, 0xA9, 0xB2, 0x1D, 0xE5, 0x1B +}; + +static const unsigned char TA181_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA182_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x34 +}; + +static const unsigned char TA182_EC_Q[] = { + 0x04, 0xF3, 0x74, 0x73, 0xA7, 0x68, 0x8B, 0x60, 0xAE, 0x43, 0xB8, 0x35, + 0xC5, 0x81, 0x30, 0x7B, 0x4B, 0x49, 0x9D, 0xFB, 0xC1, 0x61, 0xCE, 0xE6, + 0xDE, 0x46, 0xBD, 0x6B, 0xD5, 0x61, 0x18, 0x35, 0xAE, 0x40, 0xDD, 0x73, + 0xF7, 0x89, 0x91, 0x30, 0x5A, 0xEB, 0x3C, 0xEE, 0x85, 0x7C, 0xA2, 0x40, + 0x76, 0x3B, 0xA9, 0xC6, 0xB8, 0x47, 0xD8, 0x2A, 0xE7, 0x92, 0x91, 0x6A, + 0x73, 0xE9, 0xB1, 0x72, 0x39, 0x9F, 0x29, 0x9F, 0xA2, 0x98, 0xD3, 0x5F, + 0x5E, 0x58, 0x86, 0x65, 0x0F, 0xA1, 0x84, 0x65, 0x06, 0xD1, 0xDC, 0x8B, + 0xC9, 0xC7, 0x73, 0xC8, 0x8C, 0x6A, 0x2F, 0xE5, 0xC4, 0xAB, 0xD1, 0x1D, + 0x8A +}; + +static const unsigned char TA183_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA183_EC_Q[] = { + 0x04, 0xF1, 0x0B, 0xDD, 0x86, 0x43, 0x20, 0x19, 0xDF, 0x97, 0x85, 0xE8, + 0x22, 0x4A, 0x9B, 0xCF, 0x9D, 0x98, 0xBF, 0xB4, 0x05, 0x26, 0xC9, 0xCB, + 0xE3, 0xA6, 0xD2, 0x8F, 0xC5, 0x9E, 0x78, 0x7B, 0x31, 0x89, 0xA9, 0x89, + 0xAD, 0x27, 0x3C, 0x65, 0x10, 0x82, 0xFC, 0xDF, 0xC3, 0x9D, 0x4E, 0xF0, + 0x33, 0x23, 0xC4, 0xD2, 0x32, 0xF5, 0x1C, 0xB0, 0xDF, 0x33, 0x17, 0x5D, + 0xC5, 0xF0, 0xB1, 0x8A, 0xF9, 0xEF, 0xB9, 0xB7, 0x14, 0xCA, 0x29, 0x4A, + 0xC2, 0x0F, 0xA9, 0x7F, 0x75, 0x65, 0x49, 0x2A, 0x30, 0x67, 0xF4, 0x64, + 0xF7, 0xD6, 0x1A, 0x77, 0xDA, 0xC3, 0xC2, 0x97, 0x61, 0x42, 0x7B, 0x49, + 0xAD +}; + +static const unsigned char TA184_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1F, 0x4B, 0x72, 0x61, 0x6A, 0x6F, 0x77, 0x61, 0x20, 0x49, 0x7A, + 0x62, 0x61, 0x20, 0x52, 0x6F, 0x7A, 0x6C, 0x69, 0x63, 0x7A, 0x65, 0x6E, + 0x69, 0x6F, 0x77, 0x61, 0x20, 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x53, 0x5A, 0x41, 0x46, + 0x49, 0x52, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA184_RSA_N[] = { + 0xB7, 0xBC, 0x3E, 0x50, 0xA8, 0x4B, 0xCD, 0x40, 0xB5, 0xCE, 0x61, 0xE7, + 0x96, 0xCA, 0xB4, 0xA1, 0xDA, 0x0C, 0x22, 0xB0, 0xFA, 0xB5, 0x7B, 0x76, + 0x00, 0x77, 0x8C, 0x0B, 0xCF, 0x7D, 0xA8, 0x86, 0xCC, 0x26, 0x51, 0xE4, + 0x20, 0x3D, 0x85, 0x0C, 0xD6, 0x58, 0xE3, 0xE7, 0xF4, 0x2A, 0x18, 0x9D, + 0xDA, 0xD1, 0xAE, 0x26, 0xEE, 0xEB, 0x53, 0xDC, 0xF4, 0x90, 0xD6, 0x13, + 0x4A, 0x0C, 0x90, 0x3C, 0xC3, 0xF4, 0xDA, 0xD2, 0x8E, 0x0D, 0x92, 0x3A, + 0xDC, 0xB1, 0xB1, 0xFF, 0x38, 0xDE, 0xC3, 0xBA, 0x2D, 0x5F, 0x80, 0xB9, + 0x02, 0xBD, 0x4A, 0x9D, 0x1B, 0x0F, 0xB4, 0xC3, 0xC2, 0xC1, 0x67, 0x03, + 0xDD, 0xDC, 0x1B, 0x9C, 0x3D, 0xB3, 0xB0, 0xDE, 0x00, 0x1E, 0xA8, 0x34, + 0x47, 0xBB, 0x9A, 0xEB, 0xFE, 0x0B, 0x14, 0xBD, 0x36, 0x84, 0xDA, 0x0D, + 0x20, 0xBF, 0xFA, 0x5B, 0xCB, 0xA9, 0x16, 0x20, 0xAD, 0x39, 0x60, 0xEE, + 0x2F, 0x75, 0xB6, 0xE7, 0x97, 0x9C, 0xF9, 0x3E, 0xFD, 0x7E, 0x4D, 0x6F, + 0x4D, 0x2F, 0xEF, 0x88, 0x0D, 0x6A, 0xFA, 0xDD, 0xF1, 0x3D, 0x6E, 0x20, + 0xA5, 0xA0, 0x12, 0xB4, 0x4D, 0x70, 0xB9, 0xCE, 0xD7, 0x72, 0x3B, 0x89, + 0x93, 0xA7, 0x80, 0x84, 0x1C, 0x27, 0x49, 0x72, 0x49, 0xB5, 0xFF, 0x3B, + 0x95, 0x9E, 0xC1, 0xCC, 0xC8, 0x01, 0xEC, 0xE8, 0x0E, 0x8A, 0x0A, 0x96, + 0xE7, 0xB3, 0xA6, 0x87, 0xE5, 0xD6, 0xF9, 0x05, 0x2B, 0x0D, 0x97, 0x40, + 0x70, 0x3C, 0xBA, 0xAC, 0x75, 0x5A, 0x9C, 0xD5, 0x4D, 0x9D, 0x02, 0x0A, + 0xD2, 0x4B, 0x9B, 0x66, 0x4B, 0x46, 0x07, 0x17, 0x65, 0xAD, 0x9F, 0x6C, + 0x88, 0x00, 0xDC, 0x22, 0x89, 0xE0, 0xE1, 0x64, 0xD4, 0x67, 0xBC, 0x31, + 0x79, 0x61, 0x3C, 0xBB, 0xCA, 0x41, 0xCD, 0x5C, 0x6A, 0x00, 0xC8, 0x3C, + 0x38, 0x8E, 0x58, 0xAF +}; + +static const unsigned char TA184_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA185_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA185_RSA_N[] = { + 0xD0, 0xA4, 0x09, 0x72, 0x4F, 0x40, 0x88, 0x12, 0x61, 0x3E, 0x35, 0x23, + 0x9E, 0xEE, 0xF6, 0x74, 0xCF, 0x2F, 0x7B, 0x58, 0x3D, 0xCE, 0x3C, 0x0D, + 0x10, 0x28, 0x90, 0x2F, 0x97, 0xF7, 0x8C, 0x48, 0xD8, 0xA0, 0xD8, 0x25, + 0xB1, 0x4C, 0xB0, 0x11, 0x4C, 0x17, 0x73, 0x50, 0xD0, 0x22, 0x4A, 0x63, + 0xBB, 0x81, 0xD3, 0x29, 0x6E, 0xD5, 0xB5, 0x09, 0x3E, 0x26, 0x18, 0x7F, + 0xB2, 0x12, 0x7F, 0x93, 0x98, 0xB7, 0xAF, 0xF0, 0x36, 0xBF, 0xF2, 0xEE, + 0x18, 0x9E, 0x9C, 0x3B, 0x52, 0xC5, 0x47, 0x19, 0x5D, 0x74, 0xF3, 0x64, + 0x66, 0xD5, 0x5D, 0xC7, 0x68, 0xB4, 0xBF, 0x1B, 0x1C, 0x06, 0xA3, 0xBC, + 0x8F, 0x40, 0x23, 0xB6, 0x1E, 0xC6, 0x84, 0xBD, 0x51, 0xC4, 0x1B, 0x39, + 0xC1, 0x95, 0xD2, 0x29, 0xEC, 0x4B, 0xAE, 0x7B, 0x2D, 0xBF, 0x39, 0xFD, + 0xB4, 0x62, 0xDE, 0x96, 0x7B, 0x41, 0xC6, 0x9C, 0xA0, 0xE0, 0x06, 0x72, + 0xFB, 0xF0, 0x07, 0x97, 0x09, 0x39, 0x81, 0x74, 0xAF, 0xF7, 0x34, 0x59, + 0x11, 0x57, 0x0A, 0xC2, 0x5B, 0xC1, 0x24, 0xF4, 0x31, 0x73, 0x30, 0x82, + 0xC6, 0x9D, 0xBA, 0x02, 0xF7, 0x3E, 0x7C, 0x44, 0x5F, 0x83, 0x0D, 0xF3, + 0xF1, 0xDD, 0x20, 0x69, 0x16, 0x09, 0x50, 0xE2, 0xD4, 0x55, 0xB6, 0xE0, + 0x80, 0x72, 0x76, 0x6E, 0x4C, 0x47, 0xB7, 0x75, 0x55, 0x59, 0xB4, 0x53, + 0x74, 0xD9, 0x94, 0xC6, 0x41, 0xAD, 0x58, 0x8A, 0x31, 0x66, 0x0F, 0x1E, + 0xA2, 0x1B, 0x29, 0x40, 0x4E, 0x2F, 0xDF, 0x7B, 0xE6, 0x16, 0x2C, 0x2D, + 0xFC, 0xBF, 0xEC, 0xF3, 0xB4, 0xFA, 0xBE, 0x18, 0xF6, 0x9B, 0x49, 0xD4, + 0xEE, 0x05, 0x6E, 0xD9, 0x34, 0xF3, 0x9C, 0xF1, 0xEC, 0x01, 0x8B, 0xD1, + 0x20, 0xC6, 0x0F, 0xA0, 0xB5, 0xBC, 0x17, 0x4E, 0x48, 0x7B, 0x51, 0xC2, + 0xFC, 0xE9, 0x5C, 0x69, 0x37, 0x47, 0x66, 0xB3, 0x68, 0xF8, 0x15, 0x28, + 0xF0, 0xB9, 0xD3, 0xA4, 0x15, 0xCC, 0x5A, 0x4F, 0xBA, 0x52, 0x70, 0xA3, + 0x12, 0x45, 0xDD, 0xC6, 0xBA, 0x4E, 0xFB, 0xC2, 0xD0, 0xF7, 0xA8, 0x52, + 0x27, 0x6D, 0x6E, 0x79, 0xB5, 0x8C, 0xFC, 0x7B, 0x8C, 0xC1, 0x16, 0x4C, + 0xEE, 0x80, 0x7F, 0xBE, 0xF0, 0x76, 0xBE, 0x41, 0x53, 0x12, 0x33, 0xAE, + 0x5A, 0x38, 0x42, 0xAB, 0xD7, 0x0F, 0x3E, 0x41, 0x8D, 0x76, 0x07, 0x32, + 0xD5, 0xAB, 0x89, 0xF6, 0x4E, 0x67, 0xD9, 0xB1, 0x42, 0x75, 0x23, 0x6E, + 0xF3, 0xCD, 0x42, 0xB2, 0xFC, 0x55, 0xF5, 0x53, 0x87, 0x17, 0x3B, 0xC0, + 0x33, 0x58, 0xF1, 0x52, 0xD2, 0xF9, 0x80, 0xA4, 0xF0, 0xE8, 0xF0, 0x3B, + 0x8B, 0x38, 0xCC, 0xA4, 0xC6, 0x90, 0x7F, 0x0F, 0x9C, 0xFD, 0x8B, 0xD1, + 0xA3, 0xCF, 0xDA, 0x83, 0xA7, 0x69, 0xC9, 0x50, 0x36, 0xD5, 0x5C, 0x05, + 0xD2, 0x0A, 0x41, 0x74, 0xDB, 0x63, 0x11, 0x37, 0xC1, 0xA5, 0xA0, 0x96, + 0x4B, 0x1E, 0x8C, 0x16, 0x12, 0x77, 0xAE, 0x94, 0x34, 0x7B, 0x1E, 0x7F, + 0xC2, 0x66, 0x00, 0xE4, 0xAA, 0x83, 0xEA, 0x8A, 0x90, 0xAD, 0xCE, 0x36, + 0x44, 0x4D, 0xD1, 0x51, 0xE9, 0xBC, 0x1F, 0xF3, 0x6A, 0x05, 0xFD, 0xC0, + 0x74, 0x1F, 0x25, 0x19, 0x40, 0x51, 0x6E, 0xEA, 0x82, 0x51, 0x40, 0xDF, + 0x9B, 0xB9, 0x08, 0x2A, 0x06, 0x02, 0xD5, 0x23, 0x1C, 0x13, 0xD6, 0xE9, + 0xDB, 0xDB, 0xC6, 0xB0, 0x7A, 0xCB, 0x7B, 0x27, 0x9B, 0xFB, 0xE0, 0xD5, + 0x46, 0x24, 0xED, 0x10, 0x4B, 0x63, 0x4B, 0xA5, 0x05, 0x8F, 0xBA, 0xB8, + 0x1D, 0x2B, 0xA6, 0xFA, 0x91, 0xE2, 0x92, 0x52, 0xBD, 0xEC, 0xEB, 0x67, + 0x97, 0x6D, 0x9A, 0x2D, 0x9F, 0x81, 0x32, 0x05, 0x67, 0x32, 0xFB, 0x48, + 0x08, 0x3F, 0xD9, 0x25, 0xB8, 0x04, 0x25, 0x2F +}; + +static const unsigned char TA185_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA186_DN[] = { + 0x30, 0x42, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x09, 0x41, 0x43, 0x43, 0x56, 0x52, 0x41, 0x49, 0x5A, 0x31, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x50, 0x4B, 0x49, + 0x41, 0x43, 0x43, 0x56, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x04, 0x41, 0x43, 0x43, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53 +}; + +static const unsigned char TA186_RSA_N[] = { + 0x9B, 0xA9, 0xAB, 0xBF, 0x61, 0x4A, 0x97, 0xAF, 0x2F, 0x97, 0x66, 0x9A, + 0x74, 0x5F, 0xD0, 0xD9, 0x96, 0xFD, 0xCF, 0xE2, 0xE4, 0x66, 0xEF, 0x1F, + 0x1F, 0x47, 0x33, 0xC2, 0x44, 0xA3, 0xDF, 0x9A, 0xDE, 0x1F, 0xB5, 0x54, + 0xDD, 0x15, 0x7C, 0x69, 0x35, 0x11, 0x6F, 0xBB, 0xC8, 0x0C, 0x8E, 0x6A, + 0x18, 0x1E, 0xD8, 0x8F, 0xD9, 0x16, 0xBC, 0x10, 0x48, 0x36, 0x5C, 0xF0, + 0x63, 0xB3, 0x90, 0x5A, 0x5C, 0x24, 0x37, 0xD7, 0xA3, 0xD6, 0xCB, 0x09, + 0x71, 0xB9, 0xF1, 0x01, 0x72, 0x84, 0xB0, 0x7D, 0xDB, 0x4D, 0x80, 0xCD, + 0xFC, 0xD3, 0x6F, 0xC9, 0xF8, 0xDA, 0xB6, 0x0E, 0x82, 0xD2, 0x45, 0x85, + 0xA8, 0x1B, 0x68, 0xA8, 0x3D, 0xE8, 0xF4, 0x44, 0x6C, 0xBD, 0xA1, 0xC2, + 0xCB, 0x03, 0xBE, 0x8C, 0x3E, 0x13, 0x00, 0x84, 0xDF, 0x4A, 0x48, 0xC0, + 0xE3, 0x22, 0x0A, 0xE8, 0xE9, 0x37, 0xA7, 0x18, 0x4C, 0xB1, 0x09, 0x0D, + 0x23, 0x56, 0x7F, 0x04, 0x4D, 0xD9, 0x17, 0x84, 0x18, 0xA5, 0xC8, 0xDA, + 0x40, 0x94, 0x73, 0xEB, 0xCE, 0x0E, 0x57, 0x3C, 0x03, 0x81, 0x3A, 0x9D, + 0x0A, 0xA1, 0x57, 0x43, 0x69, 0xAC, 0x57, 0x6D, 0x79, 0x90, 0x78, 0xE5, + 0xB5, 0xB4, 0x3B, 0xD8, 0xBC, 0x4C, 0x8D, 0x28, 0xA1, 0xA7, 0xA3, 0xA7, + 0xBA, 0x02, 0x4E, 0x25, 0xD1, 0x2A, 0xAE, 0xED, 0xAE, 0x03, 0x22, 0xB8, + 0x6B, 0x20, 0x0F, 0x30, 0x28, 0x54, 0x95, 0x7F, 0xE0, 0xEE, 0xCE, 0x0A, + 0x66, 0x9D, 0xD1, 0x40, 0x2D, 0x6E, 0x22, 0xAF, 0x9D, 0x1A, 0xC1, 0x05, + 0x19, 0xD2, 0x6F, 0xC0, 0xF2, 0x9F, 0xF8, 0x7B, 0xB3, 0x02, 0x42, 0xFB, + 0x50, 0xA9, 0x1D, 0x2D, 0x93, 0x0F, 0x23, 0xAB, 0xC6, 0xC1, 0x0F, 0x92, + 0xFF, 0xD0, 0xA2, 0x15, 0xF5, 0x53, 0x09, 0x71, 0x1C, 0xFF, 0x45, 0x13, + 0x84, 0xE6, 0x26, 0x5E, 0xF8, 0xE0, 0x88, 0x1C, 0x0A, 0xFC, 0x16, 0xB6, + 0xA8, 0x73, 0x06, 0xB8, 0xF0, 0x63, 0x84, 0x02, 0xA0, 0xC6, 0x5A, 0xEC, + 0xE7, 0x74, 0xDF, 0x70, 0xAE, 0xA3, 0x83, 0x25, 0xEA, 0xD6, 0xC7, 0x97, + 0x87, 0x93, 0xA7, 0xC6, 0x8A, 0x8A, 0x33, 0x97, 0x60, 0x37, 0x10, 0x3E, + 0x97, 0x3E, 0x6E, 0x29, 0x15, 0xD6, 0xA1, 0x0F, 0xD1, 0x88, 0x2C, 0x12, + 0x9F, 0x6F, 0xAA, 0xA4, 0xC6, 0x42, 0xEB, 0x41, 0xA2, 0xE3, 0x95, 0x43, + 0xD3, 0x01, 0x85, 0x6D, 0x8E, 0xBB, 0x3B, 0xF3, 0x23, 0x36, 0xC7, 0xFE, + 0x3B, 0xE0, 0xA1, 0x25, 0x07, 0x48, 0xAB, 0xC9, 0x89, 0x74, 0xFF, 0x08, + 0x8F, 0x80, 0xBF, 0xC0, 0x96, 0x65, 0xF3, 0xEE, 0xEC, 0x4B, 0x68, 0xBD, + 0x9D, 0x88, 0xC3, 0x31, 0xB3, 0x40, 0xF1, 0xE8, 0xCF, 0xF6, 0x38, 0xBB, + 0x9C, 0xE4, 0xD1, 0x7F, 0xD4, 0xE5, 0x58, 0x9B, 0x7C, 0xFA, 0xD4, 0xF3, + 0x0E, 0x9B, 0x75, 0x91, 0xE4, 0xBA, 0x52, 0x2E, 0x19, 0x7E, 0xD1, 0xF5, + 0xCD, 0x5A, 0x19, 0xFC, 0xBA, 0x06, 0xF6, 0xFB, 0x52, 0xA8, 0x4B, 0x99, + 0x04, 0xDD, 0xF8, 0xF9, 0xB4, 0x8B, 0x50, 0xA3, 0x4E, 0x62, 0x89, 0xF0, + 0x87, 0x24, 0xFA, 0x83, 0x42, 0xC1, 0x87, 0xFA, 0xD5, 0x2D, 0x29, 0x2A, + 0x5A, 0x71, 0x7A, 0x64, 0x6A, 0xD7, 0x27, 0x60, 0x63, 0x0D, 0xDB, 0xCE, + 0x49, 0xF5, 0x8D, 0x1F, 0x90, 0x89, 0x32, 0x17, 0xF8, 0x73, 0x43, 0xB8, + 0xD2, 0x5A, 0x93, 0x86, 0x61, 0xD6, 0xE1, 0x75, 0x0A, 0xEA, 0x79, 0x66, + 0x76, 0x88, 0x4F, 0x71, 0xEB, 0x04, 0x25, 0xD6, 0x0A, 0x5A, 0x7A, 0x93, + 0xE5, 0xB9, 0x4B, 0x17, 0x40, 0x0F, 0xB1, 0xB6, 0xB9, 0xF5, 0xDE, 0x4F, + 0xDC, 0xE0, 0xB3, 0xAC, 0x3B, 0x11, 0x70, 0x60, 0x84, 0x4A, 0x43, 0x6E, + 0x99, 0x20, 0xC0, 0x29, 0x71, 0x0A, 0xC0, 0x65 +}; + +static const unsigned char TA186_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA187_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x43, 0x45, 0x52, 0x54, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x53, + 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x13, + 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, + 0x54, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA187_RSA_N[] = { + 0xC0, 0xC5, 0x75, 0x19, 0x91, 0x7D, 0x44, 0x74, 0x74, 0x87, 0xFE, 0x0E, + 0x3B, 0x96, 0xDC, 0xD8, 0x01, 0x16, 0xCC, 0xEE, 0x63, 0x91, 0xE7, 0x0B, + 0x6F, 0xCE, 0x3B, 0x0A, 0x69, 0x1A, 0x7C, 0xC2, 0xE3, 0xAF, 0x82, 0x8E, + 0x86, 0xD7, 0x5E, 0x8F, 0x57, 0xEB, 0xD3, 0x21, 0x59, 0xFD, 0x39, 0x37, + 0x42, 0x30, 0xBE, 0x50, 0xEA, 0xB6, 0x0F, 0xA9, 0x88, 0xD8, 0x2E, 0x2D, + 0x69, 0x21, 0xE7, 0xD1, 0x37, 0x18, 0x4E, 0x7D, 0x91, 0xD5, 0x16, 0x5F, + 0x6B, 0x5B, 0x00, 0xC2, 0x39, 0x43, 0x0D, 0x36, 0x85, 0x52, 0xB9, 0x53, + 0x65, 0x0F, 0x1D, 0x42, 0xE5, 0x8F, 0xCF, 0x05, 0xD3, 0xEE, 0xDC, 0x0C, + 0x1A, 0xD9, 0xB8, 0x8B, 0x78, 0x22, 0x67, 0xE4, 0x69, 0xB0, 0x68, 0xC5, + 0x3C, 0xE4, 0x6C, 0x5A, 0x46, 0xE7, 0xCD, 0xC7, 0xFA, 0xEF, 0xC4, 0xEC, + 0x4B, 0xBD, 0x6A, 0xA4, 0xAC, 0xFD, 0xCC, 0x28, 0x51, 0xEF, 0x92, 0xB4, + 0x29, 0xAB, 0xAB, 0x35, 0x9A, 0x4C, 0xE4, 0xC4, 0x08, 0xC6, 0x26, 0xCC, + 0xF8, 0x69, 0x9F, 0xE4, 0x9C, 0xF0, 0x29, 0xD3, 0x5C, 0xF9, 0xC6, 0x16, + 0x25, 0x9E, 0x23, 0xC3, 0x20, 0xC1, 0x3D, 0x0F, 0x3F, 0x38, 0x40, 0xB0, + 0xFE, 0x82, 0x44, 0x38, 0xAA, 0x5A, 0x1A, 0x8A, 0x6B, 0x63, 0x58, 0x38, + 0xB4, 0x15, 0xD3, 0xB6, 0x11, 0x69, 0x7B, 0x1E, 0x54, 0xEE, 0x8C, 0x1A, + 0x22, 0xAC, 0x72, 0x97, 0x3F, 0x23, 0x59, 0x9B, 0xC9, 0x22, 0x84, 0xC1, + 0x07, 0x4F, 0xCC, 0x7F, 0xE2, 0x57, 0xCA, 0x12, 0x70, 0xBB, 0xA6, 0x65, + 0xF3, 0x69, 0x75, 0x63, 0xBD, 0x95, 0xFB, 0x1B, 0x97, 0xCD, 0xE4, 0xA8, + 0xAF, 0xF6, 0xD1, 0x4E, 0xA8, 0xD9, 0x8A, 0x71, 0x24, 0xCD, 0x36, 0x3D, + 0xBC, 0x96, 0xC4, 0xF1, 0x6C, 0xA9, 0xAE, 0xE5, 0xCF, 0x0D, 0x6E, 0x28, + 0x0D, 0xB0, 0x0E, 0xB5, 0xCA, 0x51, 0x7B, 0x78, 0x14, 0xC3, 0x20, 0x2F, + 0x7F, 0xFB, 0x14, 0x55, 0xE1, 0x11, 0x99, 0xFD, 0xD5, 0x0A, 0xA1, 0x9E, + 0x02, 0xE3, 0x62, 0x5F, 0xEB, 0x35, 0x4B, 0x2C, 0xB8, 0x72, 0xE8, 0x3E, + 0x3D, 0x4F, 0xAC, 0x2C, 0xBB, 0x2E, 0x86, 0xE2, 0xA3, 0x76, 0x8F, 0xE5, + 0x93, 0x2A, 0xCF, 0xA5, 0xAB, 0xC8, 0x5C, 0x8D, 0x4B, 0x06, 0xFF, 0x12, + 0x46, 0xAC, 0x78, 0xCB, 0x14, 0x07, 0x35, 0xE0, 0xA9, 0xDF, 0x8B, 0xE9, + 0xAF, 0x15, 0x4F, 0x16, 0x89, 0x5B, 0xBD, 0xF6, 0x8D, 0xC6, 0x59, 0xAE, + 0x88, 0x85, 0x0E, 0xC1, 0x89, 0xEB, 0x1F, 0x67, 0xC5, 0x45, 0x8E, 0xFF, + 0x6D, 0x37, 0x36, 0x2B, 0x78, 0x66, 0x83, 0x91, 0x51, 0x2B, 0x3D, 0xFF, + 0x51, 0x77, 0x76, 0x62, 0xA1, 0xEC, 0x67, 0x3E, 0x3E, 0x81, 0x83, 0xE0, + 0x56, 0xA9, 0x50, 0x1F, 0x1F, 0x7A, 0x99, 0xAB, 0x63, 0xBF, 0x84, 0x17, + 0x77, 0xF1, 0x0D, 0x3B, 0xDF, 0xF7, 0x9C, 0x61, 0xB3, 0x35, 0x98, 0x8A, + 0x3A, 0xB2, 0xEC, 0x3C, 0x1A, 0x37, 0x3F, 0x7E, 0x8F, 0x92, 0xCF, 0xD9, + 0x12, 0x14, 0x64, 0xDA, 0x10, 0x02, 0x15, 0x41, 0xFF, 0x4F, 0xC4, 0xEB, + 0x1C, 0xA3, 0xC9, 0xFA, 0x99, 0xF7, 0x46, 0xE9, 0xE1, 0x18, 0xD9, 0xB1, + 0xB8, 0x32, 0x2D, 0xCB, 0x14, 0x0C, 0x50, 0xD8, 0x83, 0x65, 0x83, 0xEE, + 0xB9, 0x5C, 0xCF, 0xCB, 0x05, 0x5A, 0x4C, 0xFA, 0x19, 0x97, 0x6B, 0xD6, + 0x5D, 0x13, 0xD3, 0xC2, 0x5C, 0x54, 0xBC, 0x32, 0x73, 0xA0, 0x78, 0xF5, + 0xF1, 0x6D, 0x1E, 0xCB, 0x9F, 0xA5, 0xA6, 0x9F, 0x22, 0xDC, 0xD1, 0x51, + 0x9E, 0x82, 0x79, 0x64, 0x60, 0x29, 0x13, 0x3E, 0xA3, 0xFD, 0x4F, 0x72, + 0x6A, 0xAB, 0xE2, 0xD4, 0xE5, 0xB8, 0x24, 0x55, 0x2C, 0x44, 0x4B, 0x8A, + 0x88, 0x44, 0x9C, 0xCA, 0x84, 0xD3, 0x2A, 0x3B +}; + +static const unsigned char TA187_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA188_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x29, 0x47, 0x55, 0x41, 0x4E, 0x47, 0x20, 0x44, 0x4F, 0x4E, 0x47, + 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, + 0x20, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x20, 0x43, + 0x4F, 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x47, 0x44, 0x43, 0x41, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x41, 0x55, 0x54, 0x48, 0x20, 0x52, 0x35, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA188_RSA_N[] = { + 0xD9, 0xA3, 0x16, 0xF0, 0xC8, 0x74, 0x74, 0x77, 0x9B, 0xEF, 0x33, 0x0D, + 0x3B, 0x06, 0x7E, 0x55, 0xFC, 0xB5, 0x60, 0x8F, 0x76, 0x86, 0x12, 0x42, + 0x7D, 0x56, 0x66, 0x3E, 0x88, 0x82, 0xED, 0x72, 0x63, 0x0E, 0x9E, 0x8B, + 0xDD, 0x34, 0x2C, 0x02, 0x51, 0x51, 0xC3, 0x19, 0xFD, 0x59, 0x54, 0x84, + 0xC9, 0xF1, 0x6B, 0xB3, 0x4C, 0xB0, 0xE9, 0xE8, 0x46, 0x5D, 0x38, 0xC6, + 0xA2, 0xA7, 0x2E, 0x11, 0x57, 0xBA, 0x82, 0x15, 0xA2, 0x9C, 0x8F, 0x6D, + 0xB0, 0x99, 0x4A, 0x0A, 0xF2, 0xEB, 0x89, 0x70, 0x63, 0x4E, 0x79, 0xC4, + 0xB7, 0x5B, 0xBD, 0xA2, 0x5D, 0xB1, 0xF2, 0x41, 0x02, 0x2B, 0xAD, 0xA9, + 0x3A, 0xA3, 0xEC, 0x79, 0x0A, 0xEC, 0x5F, 0x3A, 0xE3, 0xFD, 0xEF, 0x80, + 0x3C, 0xAD, 0x34, 0x9B, 0x1A, 0xAB, 0x88, 0x26, 0x7B, 0x56, 0xA2, 0x82, + 0x86, 0x1F, 0xEB, 0x35, 0x89, 0x83, 0x7F, 0x5F, 0xAE, 0x29, 0x4E, 0x3D, + 0xB6, 0x6E, 0xEC, 0xAE, 0xC1, 0xF0, 0x27, 0x9B, 0xAE, 0xE3, 0xF4, 0xEC, + 0xEF, 0xAE, 0x7F, 0xF7, 0x86, 0x3D, 0x72, 0x7A, 0xEB, 0xA5, 0xFB, 0x59, + 0x4E, 0xA7, 0xEB, 0x95, 0x8C, 0x22, 0x39, 0x79, 0xE1, 0x2D, 0x08, 0x8F, + 0xCC, 0xBC, 0x91, 0xB8, 0x41, 0xF7, 0x14, 0xC1, 0x23, 0xA9, 0xC3, 0xAD, + 0x9A, 0x45, 0x44, 0xB3, 0xB2, 0xD7, 0x2C, 0xCD, 0xC6, 0x29, 0xE2, 0x50, + 0x10, 0xAE, 0x5C, 0xCB, 0x82, 0x8E, 0x17, 0x18, 0x36, 0x7D, 0x97, 0xE6, + 0x88, 0x9A, 0xB0, 0x4D, 0x34, 0x09, 0xF4, 0x2C, 0xB9, 0x5A, 0x66, 0x2A, + 0xB0, 0x17, 0x9B, 0x9E, 0x1E, 0x76, 0x9D, 0x4A, 0x66, 0x31, 0x41, 0xDF, + 0x3F, 0xFB, 0xC5, 0x06, 0xEF, 0x1B, 0xB6, 0x7E, 0x1A, 0x46, 0x36, 0xF7, + 0x64, 0x63, 0x3B, 0xE3, 0x39, 0x18, 0x23, 0xE7, 0x67, 0x75, 0x14, 0xD5, + 0x75, 0x57, 0x92, 0x37, 0xBD, 0xBE, 0x6A, 0x1B, 0x26, 0x50, 0xF2, 0x36, + 0x26, 0x06, 0x90, 0xC5, 0x70, 0x01, 0x64, 0x6D, 0x76, 0x66, 0xE1, 0x91, + 0xDB, 0x6E, 0x07, 0xC0, 0x61, 0x80, 0x2E, 0xB2, 0x2E, 0x2F, 0x8C, 0x70, + 0xA7, 0xD1, 0x3B, 0x3C, 0xB3, 0x91, 0xE4, 0x6E, 0xB6, 0xC4, 0x3B, 0x70, + 0xF2, 0x6C, 0x92, 0x97, 0x09, 0xCD, 0x47, 0x7D, 0x18, 0xC0, 0xF3, 0xBB, + 0x9E, 0x0F, 0xD6, 0x8B, 0xAE, 0x07, 0xB6, 0x5A, 0x0F, 0xCE, 0x0B, 0x0C, + 0x47, 0xA7, 0xE5, 0x3E, 0xB8, 0xBD, 0x7D, 0xC7, 0x9B, 0x35, 0xA0, 0x61, + 0x97, 0x3A, 0x41, 0x75, 0x17, 0xCC, 0x2B, 0x96, 0x77, 0x2A, 0x92, 0x21, + 0x1E, 0xD9, 0x95, 0x76, 0x20, 0x67, 0x68, 0xCF, 0x0D, 0xBD, 0xDF, 0xD6, + 0x1F, 0x09, 0x6A, 0x9A, 0xE2, 0xCC, 0x73, 0x71, 0xA4, 0x2F, 0x7D, 0x12, + 0x80, 0xB7, 0x53, 0x30, 0x46, 0x5E, 0x4B, 0x54, 0x99, 0x0F, 0x67, 0xC9, + 0xA5, 0xC8, 0xF2, 0x20, 0xC1, 0x82, 0xEC, 0x9D, 0x11, 0xDF, 0xC2, 0x02, + 0xFB, 0x1A, 0x3B, 0xD1, 0xED, 0x20, 0x9A, 0xEF, 0x65, 0x64, 0x92, 0x10, + 0x0D, 0x2A, 0xE2, 0xDE, 0x70, 0xF1, 0x18, 0x67, 0x82, 0x8C, 0x61, 0xDE, + 0xB8, 0xBC, 0xD1, 0x2F, 0x9C, 0xFB, 0x0F, 0xD0, 0x2B, 0xED, 0x1B, 0x76, + 0xB9, 0xE4, 0x39, 0x55, 0xF8, 0xF8, 0xA1, 0x1D, 0xB8, 0xAA, 0x80, 0x00, + 0x4C, 0x82, 0xE7, 0xB2, 0x7F, 0x09, 0xB8, 0xBC, 0x30, 0xA0, 0x2F, 0x0D, + 0xF5, 0x52, 0x9E, 0x8E, 0xF7, 0x92, 0xB3, 0x0A, 0x00, 0x1D, 0x00, 0x54, + 0x97, 0x06, 0xE0, 0xB1, 0x07, 0xD9, 0xC7, 0x0F, 0x5C, 0x65, 0x7D, 0x3C, + 0x6D, 0x59, 0x57, 0xE4, 0xED, 0xA5, 0x8D, 0xE9, 0x40, 0x53, 0x9F, 0x15, + 0x4B, 0xA0, 0x71, 0xF6, 0x1A, 0x21, 0xE3, 0xDA, 0x70, 0x06, 0x21, 0x58, + 0x14, 0x87, 0x85, 0x77, 0x79, 0xAA, 0x82, 0x79 +}; + +static const unsigned char TA188_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA189_DN[] = { + 0x30, 0x42, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x09, 0x41, 0x43, 0x43, 0x56, 0x52, 0x41, 0x49, 0x5A, 0x31, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x50, 0x4B, 0x49, + 0x41, 0x43, 0x43, 0x56, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x04, 0x41, 0x43, 0x43, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53 +}; + +static const unsigned char TA189_RSA_N[] = { + 0x9B, 0xA9, 0xAB, 0xBF, 0x61, 0x4A, 0x97, 0xAF, 0x2F, 0x97, 0x66, 0x9A, + 0x74, 0x5F, 0xD0, 0xD9, 0x96, 0xFD, 0xCF, 0xE2, 0xE4, 0x66, 0xEF, 0x1F, + 0x1F, 0x47, 0x33, 0xC2, 0x44, 0xA3, 0xDF, 0x9A, 0xDE, 0x1F, 0xB5, 0x54, + 0xDD, 0x15, 0x7C, 0x69, 0x35, 0x11, 0x6F, 0xBB, 0xC8, 0x0C, 0x8E, 0x6A, + 0x18, 0x1E, 0xD8, 0x8F, 0xD9, 0x16, 0xBC, 0x10, 0x48, 0x36, 0x5C, 0xF0, + 0x63, 0xB3, 0x90, 0x5A, 0x5C, 0x24, 0x37, 0xD7, 0xA3, 0xD6, 0xCB, 0x09, + 0x71, 0xB9, 0xF1, 0x01, 0x72, 0x84, 0xB0, 0x7D, 0xDB, 0x4D, 0x80, 0xCD, + 0xFC, 0xD3, 0x6F, 0xC9, 0xF8, 0xDA, 0xB6, 0x0E, 0x82, 0xD2, 0x45, 0x85, + 0xA8, 0x1B, 0x68, 0xA8, 0x3D, 0xE8, 0xF4, 0x44, 0x6C, 0xBD, 0xA1, 0xC2, + 0xCB, 0x03, 0xBE, 0x8C, 0x3E, 0x13, 0x00, 0x84, 0xDF, 0x4A, 0x48, 0xC0, + 0xE3, 0x22, 0x0A, 0xE8, 0xE9, 0x37, 0xA7, 0x18, 0x4C, 0xB1, 0x09, 0x0D, + 0x23, 0x56, 0x7F, 0x04, 0x4D, 0xD9, 0x17, 0x84, 0x18, 0xA5, 0xC8, 0xDA, + 0x40, 0x94, 0x73, 0xEB, 0xCE, 0x0E, 0x57, 0x3C, 0x03, 0x81, 0x3A, 0x9D, + 0x0A, 0xA1, 0x57, 0x43, 0x69, 0xAC, 0x57, 0x6D, 0x79, 0x90, 0x78, 0xE5, + 0xB5, 0xB4, 0x3B, 0xD8, 0xBC, 0x4C, 0x8D, 0x28, 0xA1, 0xA7, 0xA3, 0xA7, + 0xBA, 0x02, 0x4E, 0x25, 0xD1, 0x2A, 0xAE, 0xED, 0xAE, 0x03, 0x22, 0xB8, + 0x6B, 0x20, 0x0F, 0x30, 0x28, 0x54, 0x95, 0x7F, 0xE0, 0xEE, 0xCE, 0x0A, + 0x66, 0x9D, 0xD1, 0x40, 0x2D, 0x6E, 0x22, 0xAF, 0x9D, 0x1A, 0xC1, 0x05, + 0x19, 0xD2, 0x6F, 0xC0, 0xF2, 0x9F, 0xF8, 0x7B, 0xB3, 0x02, 0x42, 0xFB, + 0x50, 0xA9, 0x1D, 0x2D, 0x93, 0x0F, 0x23, 0xAB, 0xC6, 0xC1, 0x0F, 0x92, + 0xFF, 0xD0, 0xA2, 0x15, 0xF5, 0x53, 0x09, 0x71, 0x1C, 0xFF, 0x45, 0x13, + 0x84, 0xE6, 0x26, 0x5E, 0xF8, 0xE0, 0x88, 0x1C, 0x0A, 0xFC, 0x16, 0xB6, + 0xA8, 0x73, 0x06, 0xB8, 0xF0, 0x63, 0x84, 0x02, 0xA0, 0xC6, 0x5A, 0xEC, + 0xE7, 0x74, 0xDF, 0x70, 0xAE, 0xA3, 0x83, 0x25, 0xEA, 0xD6, 0xC7, 0x97, + 0x87, 0x93, 0xA7, 0xC6, 0x8A, 0x8A, 0x33, 0x97, 0x60, 0x37, 0x10, 0x3E, + 0x97, 0x3E, 0x6E, 0x29, 0x15, 0xD6, 0xA1, 0x0F, 0xD1, 0x88, 0x2C, 0x12, + 0x9F, 0x6F, 0xAA, 0xA4, 0xC6, 0x42, 0xEB, 0x41, 0xA2, 0xE3, 0x95, 0x43, + 0xD3, 0x01, 0x85, 0x6D, 0x8E, 0xBB, 0x3B, 0xF3, 0x23, 0x36, 0xC7, 0xFE, + 0x3B, 0xE0, 0xA1, 0x25, 0x07, 0x48, 0xAB, 0xC9, 0x89, 0x74, 0xFF, 0x08, + 0x8F, 0x80, 0xBF, 0xC0, 0x96, 0x65, 0xF3, 0xEE, 0xEC, 0x4B, 0x68, 0xBD, + 0x9D, 0x88, 0xC3, 0x31, 0xB3, 0x40, 0xF1, 0xE8, 0xCF, 0xF6, 0x38, 0xBB, + 0x9C, 0xE4, 0xD1, 0x7F, 0xD4, 0xE5, 0x58, 0x9B, 0x7C, 0xFA, 0xD4, 0xF3, + 0x0E, 0x9B, 0x75, 0x91, 0xE4, 0xBA, 0x52, 0x2E, 0x19, 0x7E, 0xD1, 0xF5, + 0xCD, 0x5A, 0x19, 0xFC, 0xBA, 0x06, 0xF6, 0xFB, 0x52, 0xA8, 0x4B, 0x99, + 0x04, 0xDD, 0xF8, 0xF9, 0xB4, 0x8B, 0x50, 0xA3, 0x4E, 0x62, 0x89, 0xF0, + 0x87, 0x24, 0xFA, 0x83, 0x42, 0xC1, 0x87, 0xFA, 0xD5, 0x2D, 0x29, 0x2A, + 0x5A, 0x71, 0x7A, 0x64, 0x6A, 0xD7, 0x27, 0x60, 0x63, 0x0D, 0xDB, 0xCE, + 0x49, 0xF5, 0x8D, 0x1F, 0x90, 0x89, 0x32, 0x17, 0xF8, 0x73, 0x43, 0xB8, + 0xD2, 0x5A, 0x93, 0x86, 0x61, 0xD6, 0xE1, 0x75, 0x0A, 0xEA, 0x79, 0x66, + 0x76, 0x88, 0x4F, 0x71, 0xEB, 0x04, 0x25, 0xD6, 0x0A, 0x5A, 0x7A, 0x93, + 0xE5, 0xB9, 0x4B, 0x17, 0x40, 0x0F, 0xB1, 0xB6, 0xB9, 0xF5, 0xDE, 0x4F, + 0xDC, 0xE0, 0xB3, 0xAC, 0x3B, 0x11, 0x70, 0x60, 0x84, 0x4A, 0x43, 0x6E, + 0x99, 0x20, 0xC0, 0x29, 0x71, 0x0A, 0xC0, 0x65 +}; + +static const unsigned char TA189_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA190_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x41, 0x43, 0x20, + 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, + 0x4D +}; + +static const unsigned char TA190_RSA_N[] = { + 0xBA, 0x71, 0x80, 0x7A, 0x4C, 0x86, 0x6E, 0x7F, 0xC8, 0x13, 0x6D, 0xC0, + 0xC6, 0x7D, 0x1C, 0x00, 0x97, 0x8F, 0x2C, 0x0C, 0x23, 0xBB, 0x10, 0x9A, + 0x40, 0xA9, 0x1A, 0xB7, 0x87, 0x88, 0xF8, 0x9B, 0x56, 0x6A, 0xFB, 0xE6, + 0x7B, 0x8E, 0x8B, 0x92, 0x8E, 0xA7, 0x25, 0x5D, 0x59, 0x11, 0xDB, 0x36, + 0x2E, 0xB7, 0x51, 0x17, 0x1F, 0xA9, 0x08, 0x1F, 0x04, 0x17, 0x24, 0x58, + 0xAA, 0x37, 0x4A, 0x18, 0xDF, 0xE5, 0x39, 0xD4, 0x57, 0xFD, 0xD7, 0xC1, + 0x2C, 0x91, 0x01, 0x91, 0xE2, 0x22, 0xD4, 0x03, 0xC0, 0x58, 0xFC, 0x77, + 0x47, 0xEC, 0x8F, 0x3E, 0x74, 0x43, 0xBA, 0xAC, 0x34, 0x8D, 0x4D, 0x38, + 0x76, 0x67, 0x8E, 0xB0, 0xC8, 0x6F, 0x30, 0x33, 0x58, 0x71, 0x5C, 0xB4, + 0xF5, 0x6B, 0x6E, 0xD4, 0x01, 0x50, 0xB8, 0x13, 0x7E, 0x6C, 0x4A, 0xA3, + 0x49, 0xD1, 0x20, 0x19, 0xEE, 0xBC, 0xC0, 0x29, 0x18, 0x65, 0xA7, 0xDE, + 0xFE, 0xEF, 0xDD, 0x0A, 0x90, 0x21, 0xE7, 0x1A, 0x67, 0x92, 0x42, 0x10, + 0x98, 0x5F, 0x4F, 0x30, 0xBC, 0x3E, 0x1C, 0x45, 0xB4, 0x10, 0xD7, 0x68, + 0x40, 0x14, 0xC0, 0x40, 0xFA, 0xE7, 0x77, 0x17, 0x7A, 0xE6, 0x0B, 0x8F, + 0x65, 0x5B, 0x3C, 0xD9, 0x9A, 0x52, 0xDB, 0xB5, 0xBD, 0x9E, 0x46, 0xCF, + 0x3D, 0xEB, 0x91, 0x05, 0x02, 0xC0, 0x96, 0xB2, 0x76, 0x4C, 0x4D, 0x10, + 0x96, 0x3B, 0x92, 0xFA, 0x9C, 0x7F, 0x0F, 0x99, 0xDF, 0xBE, 0x23, 0x35, + 0x45, 0x1E, 0x02, 0x5C, 0xFE, 0xB5, 0xA8, 0x9B, 0x99, 0x25, 0xDA, 0x5E, + 0xF3, 0x22, 0xC3, 0x39, 0xF5, 0xE4, 0x2A, 0x2E, 0xD3, 0xC6, 0x1F, 0xC4, + 0x6C, 0xAA, 0xC5, 0x1C, 0x6A, 0x01, 0x05, 0x4A, 0x2F, 0xD2, 0xC5, 0xC1, + 0xA8, 0x34, 0x26, 0x5D, 0x66, 0xA5, 0xD2, 0x02, 0x21, 0xF9, 0x18, 0xB7, + 0x06, 0xF5, 0x4E, 0x99, 0x6F, 0xA8, 0xAB, 0x4C, 0x51, 0xE8, 0xCF, 0x50, + 0x18, 0xC5, 0x77, 0xC8, 0x39, 0x09, 0x2C, 0x49, 0x92, 0x32, 0x99, 0xA8, + 0xBB, 0x17, 0x17, 0x79, 0xB0, 0x5A, 0xC5, 0xE6, 0xA3, 0xC4, 0x59, 0x65, + 0x47, 0x35, 0x83, 0x5E, 0xA9, 0xE8, 0x35, 0x0B, 0x99, 0xBB, 0xE4, 0xCD, + 0x20, 0xC6, 0x9B, 0x4A, 0x06, 0x39, 0xB5, 0x68, 0xFC, 0x22, 0xBA, 0xEE, + 0x55, 0x8C, 0x2B, 0x4E, 0xEA, 0xF3, 0xB1, 0xE3, 0xFC, 0xB6, 0x99, 0x9A, + 0xD5, 0x42, 0xFA, 0x71, 0x4D, 0x08, 0xCF, 0x87, 0x1E, 0x6A, 0x71, 0x7D, + 0xF9, 0xD3, 0xB4, 0xE9, 0xA5, 0x71, 0x81, 0x7B, 0xC2, 0x4E, 0x47, 0x96, + 0xA5, 0xF6, 0x76, 0x85, 0xA3, 0x28, 0x8F, 0xE9, 0x80, 0x6E, 0x81, 0x53, + 0xA5, 0x6D, 0x5F, 0xB8, 0x48, 0xF9, 0xC2, 0xF9, 0x36, 0xA6, 0x2E, 0x49, + 0xFF, 0xB8, 0x96, 0xC2, 0x8C, 0x07, 0xB3, 0x9B, 0x88, 0x58, 0xFC, 0xEB, + 0x1B, 0x1C, 0xDE, 0x2D, 0x70, 0xE2, 0x97, 0x92, 0x30, 0xA1, 0x89, 0xE3, + 0xBC, 0x55, 0xA8, 0x27, 0xD6, 0x4B, 0xED, 0x90, 0xAD, 0x8B, 0xFA, 0x63, + 0x25, 0x59, 0x2D, 0xA8, 0x35, 0xDD, 0xCA, 0x97, 0x33, 0xBC, 0xE5, 0xCD, + 0xC7, 0x9D, 0xD1, 0xEC, 0xEF, 0x5E, 0x0E, 0x4A, 0x90, 0x06, 0x26, 0x63, + 0xAD, 0xB9, 0xD9, 0x35, 0x2D, 0x07, 0xBA, 0x76, 0x65, 0x2C, 0xAC, 0x57, + 0x8F, 0x7D, 0xF4, 0x07, 0x94, 0xD7, 0x81, 0x02, 0x96, 0x5D, 0xA3, 0x07, + 0x49, 0xD5, 0x7A, 0xD0, 0x57, 0xF9, 0x1B, 0xE7, 0x53, 0x46, 0x75, 0xAA, + 0xB0, 0x79, 0x42, 0xCB, 0x68, 0x71, 0x08, 0xE9, 0x60, 0xBD, 0x39, 0x69, + 0xCE, 0xF4, 0xAF, 0xC3, 0x56, 0x40, 0xC7, 0xAD, 0x52, 0xA2, 0x09, 0xE4, + 0x6F, 0x86, 0x47, 0x8A, 0x1F, 0xEB, 0x28, 0x27, 0x5D, 0x83, 0x20, 0xAF, + 0x04, 0xC9, 0x6C, 0x56, 0x9A, 0x8B, 0x46, 0xF5 +}; + +static const unsigned char TA190_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA191_DN[] = { + 0x30, 0x78, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x0E, + 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x05, 0x43, 0x65, 0x72, + 0x65, 0x73, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, + 0x0F, 0x56, 0x41, 0x54, 0x45, 0x53, 0x2D, 0x51, 0x32, 0x38, 0x32, 0x36, + 0x30, 0x30, 0x34, 0x4A, 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x23, 0x41, 0x43, 0x20, 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, + 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x20, 0x53, 0x45, 0x52, 0x56, + 0x49, 0x44, 0x4F, 0x52, 0x45, 0x53, 0x20, 0x53, 0x45, 0x47, 0x55, 0x52, + 0x4F, 0x53 +}; + +static const unsigned char TA191_EC_Q[] = { + 0x04, 0xF6, 0xBA, 0x57, 0x53, 0xC8, 0xCA, 0xAB, 0xDF, 0x36, 0x4A, 0x52, + 0x21, 0xE4, 0x97, 0xD2, 0x83, 0x67, 0x9E, 0xF0, 0x65, 0x51, 0xD0, 0x5E, + 0x87, 0xC7, 0x47, 0xB1, 0x59, 0xF2, 0x57, 0x47, 0x9B, 0x00, 0x02, 0x93, + 0x44, 0x17, 0x69, 0xDB, 0x42, 0xC7, 0xB1, 0xB2, 0x3A, 0x18, 0x0E, 0xB4, + 0x5D, 0x8C, 0xB3, 0x66, 0x5D, 0xA1, 0x34, 0xF9, 0x36, 0x2C, 0x49, 0xDB, + 0xF3, 0x46, 0xFC, 0xB3, 0x44, 0x69, 0x44, 0x13, 0x66, 0xFD, 0xD7, 0xC5, + 0xFD, 0xAF, 0x36, 0x4D, 0xCE, 0x03, 0x4D, 0x07, 0x71, 0xCF, 0xAF, 0x6A, + 0x05, 0xD2, 0xA2, 0x43, 0x5A, 0x0A, 0x52, 0x6F, 0x01, 0x03, 0x4E, 0x8E, + 0x8B +}; + +static const unsigned char TA192_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x54, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x05, 0x4D, 0x69, 0x6C, 0x61, 0x6E, 0x31, 0x23, 0x30, 0x21, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x1A, 0x41, 0x63, 0x74, 0x61, 0x6C, 0x69, + 0x73, 0x20, 0x53, 0x2E, 0x70, 0x2E, 0x41, 0x2E, 0x2F, 0x30, 0x33, 0x33, + 0x35, 0x38, 0x35, 0x32, 0x30, 0x39, 0x36, 0x37, 0x31, 0x27, 0x30, 0x25, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x41, 0x63, 0x74, 0x61, 0x6C, + 0x69, 0x73, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA192_RSA_N[] = { + 0xA7, 0xC6, 0xC4, 0xA5, 0x29, 0xA4, 0x2C, 0xEF, 0xE5, 0x18, 0xC5, 0xB0, + 0x50, 0xA3, 0x6F, 0x51, 0x3B, 0x9F, 0x0A, 0x5A, 0xC9, 0xC2, 0x48, 0x38, + 0x0A, 0xC2, 0x1C, 0xA0, 0x18, 0x7F, 0x91, 0xB5, 0x87, 0xB9, 0x40, 0x3F, + 0xDD, 0x1D, 0x68, 0x1F, 0x08, 0x83, 0xD5, 0x2D, 0x1E, 0x88, 0xA0, 0xF8, + 0x8F, 0x56, 0x8F, 0x6D, 0x99, 0x02, 0x92, 0x90, 0x16, 0xD5, 0x5F, 0x08, + 0x6C, 0x89, 0xD7, 0xE1, 0xAC, 0xBC, 0x20, 0xC2, 0xB1, 0xE0, 0x83, 0x51, + 0x8A, 0x69, 0x4D, 0x00, 0x96, 0x5A, 0x6F, 0x2F, 0xC0, 0x44, 0x7E, 0xA3, + 0x0E, 0xE4, 0x91, 0xCD, 0x58, 0xEE, 0xDC, 0xFB, 0xC7, 0x1E, 0x45, 0x47, + 0xDD, 0x27, 0xB9, 0x08, 0x01, 0x9F, 0xA6, 0x21, 0x1D, 0xF5, 0x41, 0x2D, + 0x2F, 0x4C, 0xFD, 0x28, 0xAD, 0xE0, 0x8A, 0xAD, 0x22, 0xB4, 0x56, 0x65, + 0x8E, 0x86, 0x54, 0x8F, 0x93, 0x43, 0x29, 0xDE, 0x39, 0x46, 0x78, 0xA3, + 0x30, 0x23, 0xBA, 0xCD, 0xF0, 0x7D, 0x13, 0x57, 0xC0, 0x5D, 0xD2, 0x83, + 0x6B, 0x48, 0x4C, 0xC4, 0xAB, 0x9F, 0x80, 0x5A, 0x5B, 0x3A, 0xBD, 0xC9, + 0xA7, 0x22, 0x3F, 0x80, 0x27, 0x33, 0x5B, 0x0E, 0xB7, 0x8A, 0x0C, 0x5D, + 0x07, 0x37, 0x08, 0xCB, 0x6C, 0xD2, 0x7A, 0x47, 0x22, 0x44, 0x35, 0xC5, + 0xCC, 0xCC, 0x2E, 0x8E, 0xDD, 0x2A, 0xED, 0xB7, 0x7D, 0x66, 0x0D, 0x5F, + 0x61, 0x51, 0x22, 0x55, 0x1B, 0xE3, 0x46, 0xE3, 0xE3, 0x3D, 0xD0, 0x35, + 0x62, 0x9A, 0xDB, 0xAF, 0x14, 0xC8, 0x5B, 0xA1, 0xCC, 0x89, 0x1B, 0xE1, + 0x30, 0x26, 0xFC, 0xA0, 0x9B, 0x1F, 0x81, 0xA7, 0x47, 0x1F, 0x04, 0xEB, + 0xA3, 0x39, 0x92, 0x06, 0x9F, 0x99, 0xD3, 0xBF, 0xD3, 0xEA, 0x4F, 0x50, + 0x9C, 0x19, 0xFE, 0x96, 0x87, 0x1E, 0x3C, 0x65, 0xF6, 0xA3, 0x18, 0x24, + 0x83, 0x86, 0x10, 0xE7, 0x54, 0x3E, 0xA8, 0x3A, 0x76, 0x24, 0x4F, 0x81, + 0x21, 0xC5, 0xE3, 0x0F, 0x02, 0xF8, 0x93, 0x94, 0x47, 0x20, 0xBB, 0xFE, + 0xD4, 0x0E, 0xD3, 0x68, 0xB9, 0xDD, 0xC4, 0x7A, 0x84, 0x82, 0xE3, 0x53, + 0x54, 0x79, 0xDD, 0xDB, 0x9C, 0xD2, 0xF2, 0x07, 0x9B, 0x2E, 0xB6, 0xBC, + 0x3E, 0xED, 0x85, 0x6D, 0xEF, 0x25, 0x11, 0xF2, 0x97, 0x1A, 0x42, 0x61, + 0xF7, 0x4A, 0x97, 0xE8, 0x8B, 0xB1, 0x10, 0x07, 0xFA, 0x65, 0x81, 0xB2, + 0xA2, 0x39, 0xCF, 0xF7, 0x3C, 0xFF, 0x18, 0xFB, 0xC6, 0xF1, 0x5A, 0x8B, + 0x59, 0xE2, 0x02, 0xAC, 0x7B, 0x92, 0xD0, 0x4E, 0x14, 0x4F, 0x59, 0x45, + 0xF6, 0x0C, 0x5E, 0x28, 0x5F, 0xB0, 0xE8, 0x3F, 0x45, 0xCF, 0xCF, 0xAF, + 0x9B, 0x6F, 0xFB, 0x84, 0xD3, 0x77, 0x5A, 0x95, 0x6F, 0xAC, 0x94, 0x84, + 0x9E, 0xEE, 0xBC, 0xC0, 0x4A, 0x8F, 0x4A, 0x93, 0xF8, 0x44, 0x21, 0xE2, + 0x31, 0x45, 0x61, 0x50, 0x4E, 0x10, 0xD8, 0xE3, 0x35, 0x7C, 0x4C, 0x19, + 0xB4, 0xDE, 0x05, 0xBF, 0xA3, 0x06, 0x9F, 0xC8, 0xB5, 0xCD, 0xE4, 0x1F, + 0xD7, 0x17, 0x06, 0x0D, 0x7A, 0x95, 0x74, 0x55, 0x0D, 0x68, 0x1A, 0xFC, + 0x10, 0x1B, 0x62, 0x64, 0x9D, 0x6D, 0xE0, 0x95, 0xA0, 0xC3, 0x94, 0x07, + 0x57, 0x0D, 0x14, 0xE6, 0xBD, 0x05, 0xFB, 0xB8, 0x9F, 0xE6, 0xDF, 0x8B, + 0xE2, 0xC6, 0xE7, 0x7E, 0x96, 0xF6, 0x53, 0xC5, 0x80, 0x34, 0x50, 0x28, + 0x58, 0xF0, 0x12, 0x50, 0x71, 0x17, 0x30, 0xBA, 0xE6, 0x78, 0x63, 0xBC, + 0xF4, 0xB2, 0xAD, 0x9B, 0x2B, 0xB2, 0xFE, 0xE1, 0x39, 0x8C, 0x5E, 0xBA, + 0x0B, 0x20, 0x94, 0xDE, 0x7B, 0x83, 0xB8, 0xFF, 0xE3, 0x56, 0x8D, 0xB7, + 0x11, 0xE9, 0x3B, 0x8C, 0xF2, 0xB1, 0xC1, 0x5D, 0x9D, 0xA4, 0x0B, 0x4C, + 0x2B, 0xD9, 0xB2, 0x18, 0xF5, 0xB5, 0x9F, 0x4B +}; + +static const unsigned char TA192_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA193_DN[] = { + 0x30, 0x81, 0xB4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, + 0x74, 0x31, 0x40, 0x30, 0x3E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x14, 0x37, + 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, + 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x5F, 0x32, 0x30, 0x34, 0x38, + 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x2E, 0x20, 0x62, 0x79, 0x20, + 0x72, 0x65, 0x66, 0x2E, 0x20, 0x28, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x73, + 0x20, 0x6C, 0x69, 0x61, 0x62, 0x2E, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1C, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, + 0x65, 0x74, 0x20, 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, + 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, + 0x34, 0x38, 0x29 +}; + +static const unsigned char TA193_RSA_N[] = { + 0xAD, 0x4D, 0x4B, 0xA9, 0x12, 0x86, 0xB2, 0xEA, 0xA3, 0x20, 0x07, 0x15, + 0x16, 0x64, 0x2A, 0x2B, 0x4B, 0xD1, 0xBF, 0x0B, 0x4A, 0x4D, 0x8E, 0xED, + 0x80, 0x76, 0xA5, 0x67, 0xB7, 0x78, 0x40, 0xC0, 0x73, 0x42, 0xC8, 0x68, + 0xC0, 0xDB, 0x53, 0x2B, 0xDD, 0x5E, 0xB8, 0x76, 0x98, 0x35, 0x93, 0x8B, + 0x1A, 0x9D, 0x7C, 0x13, 0x3A, 0x0E, 0x1F, 0x5B, 0xB7, 0x1E, 0xCF, 0xE5, + 0x24, 0x14, 0x1E, 0xB1, 0x81, 0xA9, 0x8D, 0x7D, 0xB8, 0xCC, 0x6B, 0x4B, + 0x03, 0xF1, 0x02, 0x0C, 0xDC, 0xAB, 0xA5, 0x40, 0x24, 0x00, 0x7F, 0x74, + 0x94, 0xA1, 0x9D, 0x08, 0x29, 0xB3, 0x88, 0x0B, 0xF5, 0x87, 0x77, 0x9D, + 0x55, 0xCD, 0xE4, 0xC3, 0x7E, 0xD7, 0x6A, 0x64, 0xAB, 0x85, 0x14, 0x86, + 0x95, 0x5B, 0x97, 0x32, 0x50, 0x6F, 0x3D, 0xC8, 0xBA, 0x66, 0x0C, 0xE3, + 0xFC, 0xBD, 0xB8, 0x49, 0xC1, 0x76, 0x89, 0x49, 0x19, 0xFD, 0xC0, 0xA8, + 0xBD, 0x89, 0xA3, 0x67, 0x2F, 0xC6, 0x9F, 0xBC, 0x71, 0x19, 0x60, 0xB8, + 0x2D, 0xE9, 0x2C, 0xC9, 0x90, 0x76, 0x66, 0x7B, 0x94, 0xE2, 0xAF, 0x78, + 0xD6, 0x65, 0x53, 0x5D, 0x3C, 0xD6, 0x9C, 0xB2, 0xCF, 0x29, 0x03, 0xF9, + 0x2F, 0xA4, 0x50, 0xB2, 0xD4, 0x48, 0xCE, 0x05, 0x32, 0x55, 0x8A, 0xFD, + 0xB2, 0x64, 0x4C, 0x0E, 0xE4, 0x98, 0x07, 0x75, 0xDB, 0x7F, 0xDF, 0xB9, + 0x08, 0x55, 0x60, 0x85, 0x30, 0x29, 0xF9, 0x7B, 0x48, 0xA4, 0x69, 0x86, + 0xE3, 0x35, 0x3F, 0x1E, 0x86, 0x5D, 0x7A, 0x7A, 0x15, 0xBD, 0xEF, 0x00, + 0x8E, 0x15, 0x22, 0x54, 0x17, 0x00, 0x90, 0x26, 0x93, 0xBC, 0x0E, 0x49, + 0x68, 0x91, 0xBF, 0xF8, 0x47, 0xD3, 0x9D, 0x95, 0x42, 0xC1, 0x0E, 0x4D, + 0xDF, 0x6F, 0x26, 0xCF, 0xC3, 0x18, 0x21, 0x62, 0x66, 0x43, 0x70, 0xD6, + 0xD5, 0xC0, 0x07, 0xE1 +}; + +static const unsigned char TA193_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA194_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C +}; + +static const unsigned char TA194_RSA_N[] = { + 0xF6, 0x1B, 0x4F, 0x67, 0x07, 0x2B, 0xA1, 0x15, 0xF5, 0x06, 0x22, 0xCB, + 0x1F, 0x01, 0xB2, 0xE3, 0x73, 0x45, 0x06, 0x44, 0x49, 0x2C, 0xBB, 0x49, + 0x25, 0x14, 0xD6, 0xCE, 0xC3, 0xB7, 0xAB, 0x2C, 0x4F, 0xC6, 0x41, 0x32, + 0x94, 0x57, 0xFA, 0x12, 0xA7, 0x5B, 0x0E, 0xE2, 0x8F, 0x1F, 0x1E, 0x86, + 0x19, 0xA7, 0xAA, 0xB5, 0x2D, 0xB9, 0x5F, 0x0D, 0x8A, 0xC2, 0xAF, 0x85, + 0x35, 0x79, 0x32, 0x2D, 0xBB, 0x1C, 0x62, 0x37, 0xF2, 0xB1, 0x5B, 0x4A, + 0x3D, 0xCA, 0xCD, 0x71, 0x5F, 0xE9, 0x42, 0xBE, 0x94, 0xE8, 0xC8, 0xDE, + 0xF9, 0x22, 0x48, 0x64, 0xC6, 0xE5, 0xAB, 0xC6, 0x2B, 0x6D, 0xAD, 0x05, + 0xF0, 0xFA, 0xD5, 0x0B, 0xCF, 0x9A, 0xE5, 0xF0, 0x50, 0xA4, 0x8B, 0x3B, + 0x47, 0xA5, 0x23, 0x5B, 0x7A, 0x7A, 0xF8, 0x33, 0x3F, 0xB8, 0xEF, 0x99, + 0x97, 0xE3, 0x20, 0xC1, 0xD6, 0x28, 0x89, 0xCF, 0x94, 0xFB, 0xB9, 0x45, + 0xED, 0xE3, 0x40, 0x17, 0x11, 0xD4, 0x74, 0xF0, 0x0B, 0x31, 0xE2, 0x2B, + 0x26, 0x6A, 0x9B, 0x4C, 0x57, 0xAE, 0xAC, 0x20, 0x3E, 0xBA, 0x45, 0x7A, + 0x05, 0xF3, 0xBD, 0x9B, 0x69, 0x15, 0xAE, 0x7D, 0x4E, 0x20, 0x63, 0xC4, + 0x35, 0x76, 0x3A, 0x07, 0x02, 0xC9, 0x37, 0xFD, 0xC7, 0x47, 0xEE, 0xE8, + 0xF1, 0x76, 0x1D, 0x73, 0x15, 0xF2, 0x97, 0xA4, 0xB5, 0xC8, 0x7A, 0x79, + 0xD9, 0x42, 0xAA, 0x2B, 0x7F, 0x5C, 0xFE, 0xCE, 0x26, 0x4F, 0xA3, 0x66, + 0x81, 0x35, 0xAF, 0x44, 0xBA, 0x54, 0x1E, 0x1C, 0x30, 0x32, 0x65, 0x9D, + 0xE6, 0x3C, 0x93, 0x5E, 0x50, 0x4E, 0x7A, 0xE3, 0x3A, 0xD4, 0x6E, 0xCC, + 0x1A, 0xFB, 0xF9, 0xD2, 0x37, 0xAE, 0x24, 0x2A, 0xAB, 0x57, 0x03, 0x22, + 0x28, 0x0D, 0x49, 0x75, 0x7F, 0xB7, 0x28, 0xDA, 0x75, 0xBF, 0x8E, 0xE3, + 0xDC, 0x0E, 0x79, 0x31 +}; + +static const unsigned char TA194_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA195_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, 0x67 +}; + +static const unsigned char TA195_RSA_N[] = { + 0xB4, 0x84, 0xCC, 0x33, 0x17, 0x2E, 0x6B, 0x94, 0x6C, 0x6B, 0x61, 0x52, + 0xA0, 0xEB, 0xA3, 0xCF, 0x79, 0x94, 0x4C, 0xE5, 0x94, 0x80, 0x99, 0xCB, + 0x55, 0x64, 0x44, 0x65, 0x8F, 0x67, 0x64, 0xE2, 0x06, 0xE3, 0x5C, 0x37, + 0x49, 0xF6, 0x2F, 0x9B, 0x84, 0x84, 0x1E, 0x2D, 0xF2, 0x60, 0x9D, 0x30, + 0x4E, 0xCC, 0x84, 0x85, 0xE2, 0x2C, 0xCF, 0x1E, 0x9E, 0xFE, 0x36, 0xAB, + 0x33, 0x77, 0x35, 0x44, 0xD8, 0x35, 0x96, 0x1A, 0x3D, 0x36, 0xE8, 0x7A, + 0x0E, 0xD8, 0xD5, 0x47, 0xA1, 0x6A, 0x69, 0x8B, 0xD9, 0xFC, 0xBB, 0x3A, + 0xAE, 0x79, 0x5A, 0xD5, 0xF4, 0xD6, 0x71, 0xBB, 0x9A, 0x90, 0x23, 0x6B, + 0x9A, 0xB7, 0x88, 0x74, 0x87, 0x0C, 0x1E, 0x5F, 0xB9, 0x9E, 0x2D, 0xFA, + 0xAB, 0x53, 0x2B, 0xDC, 0xBB, 0x76, 0x3E, 0x93, 0x4C, 0x08, 0x08, 0x8C, + 0x1E, 0xA2, 0x23, 0x1C, 0xD4, 0x6A, 0xAD, 0x22, 0xBA, 0x99, 0x01, 0x2E, + 0x6D, 0x65, 0xCB, 0xBE, 0x24, 0x66, 0x55, 0x24, 0x4B, 0x40, 0x44, 0xB1, + 0x1B, 0xD7, 0xE1, 0xC2, 0x85, 0xC0, 0xDE, 0x10, 0x3F, 0x3D, 0xED, 0xB8, + 0xFC, 0xF1, 0xF1, 0x23, 0x53, 0xDC, 0xBF, 0x65, 0x97, 0x6F, 0xD9, 0xF9, + 0x40, 0x71, 0x8D, 0x7D, 0xBD, 0x95, 0xD4, 0xCE, 0xBE, 0xA0, 0x5E, 0x27, + 0x23, 0xDE, 0xFD, 0xA6, 0xD0, 0x26, 0x0E, 0x00, 0x29, 0xEB, 0x3C, 0x46, + 0xF0, 0x3D, 0x60, 0xBF, 0x3F, 0x50, 0xD2, 0xDC, 0x26, 0x41, 0x51, 0x9E, + 0x14, 0x37, 0x42, 0x04, 0xA3, 0x70, 0x57, 0xA8, 0x1B, 0x87, 0xED, 0x2D, + 0xFA, 0x7B, 0xEE, 0x8C, 0x0A, 0xE3, 0xA9, 0x66, 0x89, 0x19, 0xCB, 0x41, + 0xF9, 0xDD, 0x44, 0x36, 0x61, 0xCF, 0xE2, 0x77, 0x46, 0xC8, 0x7D, 0xF6, + 0xF4, 0x92, 0x81, 0x36, 0xFD, 0xDB, 0x34, 0xF1, 0x72, 0x7E, 0xF3, 0x0C, + 0x16, 0xBD, 0xB4, 0x15 +}; + +static const unsigned char TA195_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA196_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA196_EC_Q[] = { + 0x04, 0x0D, 0x30, 0x5E, 0x1B, 0x15, 0x9D, 0x03, 0xD0, 0xA1, 0x79, 0x35, + 0xB7, 0x3A, 0x3C, 0x92, 0x7A, 0xCA, 0x15, 0x1C, 0xCD, 0x62, 0xF3, 0x9C, + 0x26, 0x5C, 0x07, 0x3D, 0xE5, 0x54, 0xFA, 0xA3, 0xD6, 0xCC, 0x12, 0xEA, + 0xF4, 0x14, 0x5F, 0xE8, 0x8E, 0x19, 0xAB, 0x2F, 0x2E, 0x48, 0xE6, 0xAC, + 0x18, 0x43, 0x78, 0xAC, 0xD0, 0x37, 0xC3, 0xBD, 0xB2, 0xCD, 0x2C, 0xE6, + 0x47, 0xE2, 0x1A, 0xE6, 0x63, 0xB8, 0x3D, 0x2E, 0x2F, 0x78, 0xC4, 0x4F, + 0xDB, 0xF4, 0x0F, 0xA4, 0x68, 0x4C, 0x55, 0x72, 0x6B, 0x95, 0x1D, 0x4E, + 0x18, 0x42, 0x95, 0x78, 0xCC, 0x37, 0x3C, 0x91, 0xE2, 0x9B, 0x65, 0x2B, + 0x29 +}; + +static const unsigned char TA197_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x13, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D +}; + +static const unsigned char TA197_RSA_N[] = { + 0xC4, 0x12, 0xDF, 0xA9, 0x5F, 0xFE, 0x41, 0xDD, 0xDD, 0xF5, 0x9F, 0x8A, + 0xE3, 0xF6, 0xAC, 0xE1, 0x3C, 0x78, 0x9A, 0xBC, 0xD8, 0xF0, 0x7F, 0x7A, + 0xA0, 0x33, 0x2A, 0xDC, 0x8D, 0x20, 0x5B, 0xAE, 0x2D, 0x6F, 0xE7, 0x93, + 0xD9, 0x36, 0x70, 0x6A, 0x68, 0xCF, 0x8E, 0x51, 0xA3, 0x85, 0x5B, 0x67, + 0x04, 0xA0, 0x10, 0x24, 0x6F, 0x5D, 0x28, 0x82, 0xC1, 0x97, 0x57, 0xD8, + 0x48, 0x29, 0x13, 0xB6, 0xE1, 0xBE, 0x91, 0x4D, 0xDF, 0x85, 0x0C, 0x53, + 0x18, 0x9A, 0x1E, 0x24, 0xA2, 0x4F, 0x8F, 0xF0, 0xA2, 0x85, 0x0B, 0xCB, + 0xF4, 0x29, 0x7F, 0xD2, 0xA4, 0x58, 0xEE, 0x26, 0x4D, 0xC9, 0xAA, 0xA8, + 0x7B, 0x9A, 0xD9, 0xFA, 0x38, 0xDE, 0x44, 0x57, 0x15, 0xE5, 0xF8, 0x8C, + 0xC8, 0xD9, 0x48, 0xE2, 0x0D, 0x16, 0x27, 0x1D, 0x1E, 0xC8, 0x83, 0x85, + 0x25, 0xB7, 0xBA, 0xAA, 0x55, 0x41, 0xCC, 0x03, 0x22, 0x4B, 0x2D, 0x91, + 0x8D, 0x8B, 0xE6, 0x89, 0xAF, 0x66, 0xC7, 0xE9, 0xFF, 0x2B, 0xE9, 0x3C, + 0xAC, 0xDA, 0xD2, 0xB3, 0xC3, 0xE1, 0x68, 0x9C, 0x89, 0xF8, 0x7A, 0x00, + 0x56, 0xDE, 0xF4, 0x55, 0x95, 0x6C, 0xFB, 0xBA, 0x64, 0xDD, 0x62, 0x8B, + 0xDF, 0x0B, 0x77, 0x32, 0xEB, 0x62, 0xCC, 0x26, 0x9A, 0x9B, 0xBB, 0xAA, + 0x62, 0x83, 0x4C, 0xB4, 0x06, 0x7A, 0x30, 0xC8, 0x29, 0xBF, 0xED, 0x06, + 0x4D, 0x97, 0xB9, 0x1C, 0xC4, 0x31, 0x2B, 0xD5, 0x5F, 0xBC, 0x53, 0x12, + 0x17, 0x9C, 0x99, 0x57, 0x29, 0x66, 0x77, 0x61, 0x21, 0x31, 0x07, 0x2E, + 0x25, 0x49, 0x9D, 0x18, 0xF2, 0xEE, 0xF3, 0x2B, 0x71, 0x8C, 0xB5, 0xBA, + 0x39, 0x07, 0x49, 0x77, 0xFC, 0xEF, 0x2E, 0x92, 0x90, 0x05, 0x8D, 0x2D, + 0x2F, 0x77, 0x7B, 0xEF, 0x43, 0xBF, 0x35, 0xBB, 0x9A, 0xD8, 0xF9, 0x73, + 0xA7, 0x2C, 0xF2, 0xD0, 0x57, 0xEE, 0x28, 0x4E, 0x26, 0x5F, 0x8F, 0x90, + 0x68, 0x09, 0x2F, 0xB8, 0xF8, 0xDC, 0x06, 0xE9, 0x2E, 0x9A, 0x3E, 0x51, + 0xA7, 0xD1, 0x22, 0xC4, 0x0A, 0xA7, 0x38, 0x48, 0x6C, 0xB3, 0xF9, 0xFF, + 0x7D, 0xAB, 0x86, 0x57, 0xE3, 0xBA, 0xD6, 0x85, 0x78, 0x77, 0xBA, 0x43, + 0xEA, 0x48, 0x7F, 0xF6, 0xD8, 0xBE, 0x23, 0x6D, 0x1E, 0xBF, 0xD1, 0x36, + 0x6C, 0x58, 0x5C, 0xF1, 0xEE, 0xA4, 0x19, 0x54, 0x1A, 0xF5, 0x03, 0xD2, + 0x76, 0xE6, 0xE1, 0x8C, 0xBD, 0x3C, 0xB3, 0xD3, 0x48, 0x4B, 0xE2, 0xC8, + 0xF8, 0x7F, 0x92, 0xA8, 0x76, 0x46, 0x9C, 0x42, 0x65, 0x3E, 0xA4, 0x1E, + 0xC1, 0x07, 0x03, 0x5A, 0x46, 0x2D, 0xB8, 0x97, 0xF3, 0xB7, 0xD5, 0xB2, + 0x55, 0x21, 0xEF, 0xBA, 0xDC, 0x4C, 0x00, 0x97, 0xFB, 0x14, 0x95, 0x27, + 0x33, 0xBF, 0xE8, 0x43, 0x47, 0x46, 0xD2, 0x08, 0x99, 0x16, 0x60, 0x3B, + 0x9A, 0x7E, 0xD2, 0xE6, 0xED, 0x38, 0xEA, 0xEC, 0x01, 0x1E, 0x3C, 0x48, + 0x56, 0x49, 0x09, 0xC7, 0x4C, 0x37, 0x00, 0x9E, 0x88, 0x0E, 0xC0, 0x73, + 0xE1, 0x6F, 0x66, 0xE9, 0x72, 0x47, 0x30, 0x3E, 0x10, 0xE5, 0x0B, 0x03, + 0xC9, 0x9A, 0x42, 0x00, 0x6C, 0xC5, 0x94, 0x7E, 0x61, 0xC4, 0x8A, 0xDF, + 0x7F, 0x82, 0x1A, 0x0B, 0x59, 0xC4, 0x59, 0x32, 0x77, 0xB3, 0xBC, 0x60, + 0x69, 0x56, 0x39, 0xFD, 0xB4, 0x06, 0x7B, 0x2C, 0xD6, 0x64, 0x36, 0xD9, + 0xBD, 0x48, 0xED, 0x84, 0x1F, 0x7E, 0xA5, 0x22, 0x8F, 0x2A, 0xB8, 0x42, + 0xF4, 0x82, 0xB7, 0xD4, 0x53, 0x90, 0x78, 0x4E, 0x2D, 0x1A, 0xFD, 0x81, + 0x6F, 0x44, 0xD7, 0x3B, 0x01, 0x74, 0x96, 0x42, 0xE0, 0x00, 0xE2, 0x2E, + 0x6B, 0xEA, 0xC5, 0xEE, 0x72, 0xAC, 0xBB, 0xBF, 0xFE, 0xEA, 0xAA, 0xA8, + 0xF8, 0xDC, 0xF6, 0xB2, 0x79, 0x8A, 0xB6, 0x67 +}; + +static const unsigned char TA197_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA198_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA198_RSA_N[] = { + 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80, + 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7, + 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86, + 0xD3, 0xA0, 0x43, 0x7A, 0x4E, 0xB2, 0xA4, 0xD0, 0x36, 0xBA, 0x01, 0xBE, + 0x8D, 0xDB, 0x48, 0xC8, 0x07, 0x17, 0x36, 0x4C, 0xF4, 0xEE, 0x88, 0x23, + 0xC7, 0x3E, 0xEB, 0x37, 0xF5, 0xB5, 0x19, 0xF8, 0x49, 0x68, 0xB0, 0xDE, + 0xD7, 0xB9, 0x76, 0x38, 0x1D, 0x61, 0x9E, 0xA4, 0xFE, 0x82, 0x36, 0xA5, + 0xE5, 0x4A, 0x56, 0xE4, 0x45, 0xE1, 0xF9, 0xFD, 0xB4, 0x16, 0xFA, 0x74, + 0xDA, 0x9C, 0x9B, 0x35, 0x39, 0x2F, 0xFA, 0xB0, 0x20, 0x50, 0x06, 0x6C, + 0x7A, 0xD0, 0x80, 0xB2, 0xA6, 0xF9, 0xAF, 0xEC, 0x47, 0x19, 0x8F, 0x50, + 0x38, 0x07, 0xDC, 0xA2, 0x87, 0x39, 0x58, 0xF8, 0xBA, 0xD5, 0xA9, 0xF9, + 0x48, 0x67, 0x30, 0x96, 0xEE, 0x94, 0x78, 0x5E, 0x6F, 0x89, 0xA3, 0x51, + 0xC0, 0x30, 0x86, 0x66, 0xA1, 0x45, 0x66, 0xBA, 0x54, 0xEB, 0xA3, 0xC3, + 0x91, 0xF9, 0x48, 0xDC, 0xFF, 0xD1, 0xE8, 0x30, 0x2D, 0x7D, 0x2D, 0x74, + 0x70, 0x35, 0xD7, 0x88, 0x24, 0xF7, 0x9E, 0xC4, 0x59, 0x6E, 0xBB, 0x73, + 0x87, 0x17, 0xF2, 0x32, 0x46, 0x28, 0xB8, 0x43, 0xFA, 0xB7, 0x1D, 0xAA, + 0xCA, 0xB4, 0xF2, 0x9F, 0x24, 0x0E, 0x2D, 0x4B, 0xF7, 0x71, 0x5C, 0x5E, + 0x69, 0xFF, 0xEA, 0x95, 0x02, 0xCB, 0x38, 0x8A, 0xAE, 0x50, 0x38, 0x6F, + 0xDB, 0xFB, 0x2D, 0x62, 0x1B, 0xC5, 0xC7, 0x1E, 0x54, 0xE1, 0x77, 0xE0, + 0x67, 0xC8, 0x0F, 0x9C, 0x87, 0x23, 0xD6, 0x3F, 0x40, 0x20, 0x7F, 0x20, + 0x80, 0xC4, 0x80, 0x4C, 0x3E, 0x3B, 0x24, 0x26, 0x8E, 0x04, 0xAE, 0x6C, + 0x9A, 0xC8, 0xAA, 0x0D +}; + +static const unsigned char TA198_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA199_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA199_RSA_N[] = { + 0xAD, 0x96, 0x9F, 0x2D, 0x9C, 0x4A, 0x4C, 0x4A, 0x81, 0x79, 0x51, 0x99, + 0xEC, 0x8A, 0xCB, 0x6B, 0x60, 0x51, 0x13, 0xBC, 0x4D, 0x6D, 0x06, 0xFC, + 0xB0, 0x08, 0x8D, 0xDD, 0x19, 0x10, 0x6A, 0xC7, 0x26, 0x0C, 0x35, 0xD8, + 0xC0, 0x6F, 0x20, 0x84, 0xE9, 0x94, 0xB1, 0x9B, 0x85, 0x03, 0xC3, 0x5B, + 0xDB, 0x4A, 0xE8, 0xC8, 0xF8, 0x90, 0x76, 0xD9, 0x5B, 0x4F, 0xE3, 0x4C, + 0xE8, 0x06, 0x36, 0x4D, 0xCC, 0x9A, 0xAC, 0x3D, 0x0C, 0x90, 0x2B, 0x92, + 0xD4, 0x06, 0x19, 0x60, 0xAC, 0x37, 0x44, 0x79, 0x85, 0x81, 0x82, 0xAD, + 0x5A, 0x37, 0xE0, 0x0D, 0xCC, 0x9D, 0xA6, 0x4C, 0x52, 0x76, 0xEA, 0x43, + 0x9D, 0xB7, 0x04, 0xD1, 0x50, 0xF6, 0x55, 0xE0, 0xD5, 0xD2, 0xA6, 0x49, + 0x85, 0xE9, 0x37, 0xE9, 0xCA, 0x7E, 0xAE, 0x5C, 0x95, 0x4D, 0x48, 0x9A, + 0x3F, 0xAE, 0x20, 0x5A, 0x6D, 0x88, 0x95, 0xD9, 0x34, 0xB8, 0x52, 0x1A, + 0x43, 0x90, 0xB0, 0xBF, 0x6C, 0x05, 0xB9, 0xB6, 0x78, 0xB7, 0xEA, 0xD0, + 0xE4, 0x3A, 0x3C, 0x12, 0x53, 0x62, 0xFF, 0x4A, 0xF2, 0x7B, 0xBE, 0x35, + 0x05, 0xA9, 0x12, 0x34, 0xE3, 0xF3, 0x64, 0x74, 0x62, 0x2C, 0x3D, 0x00, + 0x49, 0x5A, 0x28, 0xFE, 0x32, 0x44, 0xBB, 0x87, 0xDD, 0x65, 0x27, 0x02, + 0x71, 0x3B, 0xDA, 0x4A, 0xF7, 0x1F, 0xDA, 0xCD, 0xF7, 0x21, 0x55, 0x90, + 0x4F, 0x0F, 0xEC, 0xAE, 0x82, 0xE1, 0x9F, 0x6B, 0xD9, 0x45, 0xD3, 0xBB, + 0xF0, 0x5F, 0x87, 0xED, 0x3C, 0x2C, 0x39, 0x86, 0xDA, 0x3F, 0xDE, 0xEC, + 0x72, 0x55, 0xEB, 0x79, 0xA3, 0xAD, 0xDB, 0xDD, 0x7C, 0xB0, 0xBA, 0x1C, + 0xCE, 0xFC, 0xDE, 0x4F, 0x35, 0x76, 0xCF, 0x0F, 0xF8, 0x78, 0x1F, 0x6A, + 0x36, 0x51, 0x46, 0x27, 0x61, 0x5B, 0xE9, 0x9E, 0xCF, 0xF0, 0xA2, 0x55, + 0x7D, 0x7C, 0x25, 0x8A, 0x6F, 0x2F, 0xB4, 0xC5, 0xCF, 0x84, 0x2E, 0x2B, + 0xFD, 0x0D, 0x51, 0x10, 0x6C, 0xFB, 0x5F, 0x1B, 0xBC, 0x1B, 0x7E, 0xC5, + 0xAE, 0x3B, 0x98, 0x01, 0x31, 0x92, 0xFF, 0x0B, 0x57, 0xF4, 0x9A, 0xB2, + 0xB9, 0x57, 0xE9, 0xAB, 0xEF, 0x0D, 0x76, 0xD1, 0xF0, 0xEE, 0xF4, 0xCE, + 0x86, 0xA7, 0xE0, 0x6E, 0xE9, 0xB4, 0x69, 0xA1, 0xDF, 0x69, 0xF6, 0x33, + 0xC6, 0x69, 0x2E, 0x97, 0x13, 0x9E, 0xA5, 0x87, 0xB0, 0x57, 0x10, 0x81, + 0x37, 0xC9, 0x53, 0xB3, 0xBB, 0x7F, 0xF6, 0x92, 0xD1, 0x9C, 0xD0, 0x18, + 0xF4, 0x92, 0x6E, 0xDA, 0x83, 0x4F, 0xA6, 0x63, 0x99, 0x4C, 0xA5, 0xFB, + 0x5E, 0xEF, 0x21, 0x64, 0x7A, 0x20, 0x5F, 0x6C, 0x64, 0x85, 0x15, 0xCB, + 0x37, 0xE9, 0x62, 0x0C, 0x0B, 0x2A, 0x16, 0xDC, 0x01, 0x2E, 0x32, 0xDA, + 0x3E, 0x4B, 0xF5, 0x9E, 0x3A, 0xF6, 0x17, 0x40, 0x94, 0xEF, 0x9E, 0x91, + 0x08, 0x86, 0xFA, 0xBE, 0x63, 0xA8, 0x5A, 0x33, 0xEC, 0xCB, 0x74, 0x43, + 0x95, 0xF9, 0x6C, 0x69, 0x52, 0x36, 0xC7, 0x29, 0x6F, 0xFC, 0x55, 0x03, + 0x5C, 0x1F, 0xFB, 0x9F, 0xBD, 0x47, 0xEB, 0xE7, 0x49, 0x47, 0x95, 0x0B, + 0x4E, 0x89, 0x22, 0x09, 0x49, 0xE0, 0xF5, 0x61, 0x1E, 0xF1, 0xBF, 0x2E, + 0x8A, 0x72, 0x6E, 0x80, 0x59, 0xFF, 0x57, 0x3A, 0xF9, 0x75, 0x32, 0xA3, + 0x4E, 0x5F, 0xEC, 0xED, 0x28, 0x62, 0xD9, 0x4D, 0x73, 0xF2, 0xCC, 0x81, + 0x17, 0x60, 0xED, 0xCD, 0xEB, 0xDC, 0xDB, 0xA7, 0xCA, 0xC5, 0x7E, 0x02, + 0xBD, 0xF2, 0x54, 0x08, 0x54, 0xFD, 0xB4, 0x2D, 0x09, 0x2C, 0x17, 0x54, + 0x4A, 0x98, 0xD1, 0x54, 0xE1, 0x51, 0x67, 0x08, 0xD2, 0xED, 0x6E, 0x7E, + 0x6F, 0x3F, 0xD2, 0x2D, 0x81, 0x59, 0x29, 0x66, 0xCB, 0x90, 0x39, 0x95, + 0x11, 0x1E, 0x74, 0x27, 0xFE, 0xDD, 0xEB, 0xAF +}; + +static const unsigned char TA199_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA200_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA200_EC_Q[] = { + 0x04, 0x29, 0x97, 0xA7, 0xC6, 0x41, 0x7F, 0xC0, 0x0D, 0x9B, 0xE8, 0x01, + 0x1B, 0x56, 0xC6, 0xF2, 0x52, 0xA5, 0xBA, 0x2D, 0xB2, 0x12, 0xE8, 0xD2, + 0x2E, 0xD7, 0xFA, 0xC9, 0xC5, 0xD8, 0xAA, 0x6D, 0x1F, 0x73, 0x81, 0x3B, + 0x3B, 0x98, 0x6B, 0x39, 0x7C, 0x33, 0xA5, 0xC5, 0x4E, 0x86, 0x8E, 0x80, + 0x17, 0x68, 0x62, 0x45, 0x57, 0x7D, 0x44, 0x58, 0x1D, 0xB3, 0x37, 0xE5, + 0x67, 0x08, 0xEB, 0x66, 0xDE +}; + +static const unsigned char TA201_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x34 +}; + +static const unsigned char TA201_EC_Q[] = { + 0x04, 0xD2, 0xAB, 0x8A, 0x37, 0x4F, 0xA3, 0x53, 0x0D, 0xFE, 0xC1, 0x8A, + 0x7B, 0x4B, 0xA8, 0x7B, 0x46, 0x4B, 0x63, 0xB0, 0x62, 0xF6, 0x2D, 0x1B, + 0xDB, 0x08, 0x71, 0x21, 0xD2, 0x00, 0xE8, 0x63, 0xBD, 0x9A, 0x27, 0xFB, + 0xF0, 0x39, 0x6E, 0x5D, 0xEA, 0x3D, 0xA5, 0xC9, 0x81, 0xAA, 0xA3, 0x5B, + 0x20, 0x98, 0x45, 0x5D, 0x16, 0xDB, 0xFD, 0xE8, 0x10, 0x6D, 0xE3, 0x9C, + 0xE0, 0xE3, 0xBD, 0x5F, 0x84, 0x62, 0xF3, 0x70, 0x64, 0x33, 0xA0, 0xCB, + 0x24, 0x2F, 0x70, 0xBA, 0x88, 0xA1, 0x2A, 0xA0, 0x75, 0xF8, 0x81, 0xAE, + 0x62, 0x06, 0xC4, 0x81, 0xDB, 0x39, 0x6E, 0x29, 0xB0, 0x1E, 0xFA, 0x2E, + 0x5C +}; + +static const unsigned char TA202_DN[] = { + 0x30, 0x81, 0x84, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x05, + 0x13, 0x09, 0x47, 0x36, 0x33, 0x32, 0x38, 0x37, 0x35, 0x31, 0x30, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, + 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1E, 0x41, + 0x4E, 0x46, 0x20, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, + 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x63, 0x69, 0x6F, 0x6E, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x13, 0x0B, 0x41, 0x4E, 0x46, 0x20, 0x43, 0x41, 0x20, 0x52, + 0x61, 0x69, 0x7A, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x19, 0x41, 0x4E, 0x46, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA202_RSA_N[] = { + 0xDB, 0xEB, 0x6B, 0x2B, 0xE6, 0x64, 0x54, 0x95, 0x82, 0x90, 0xA3, 0x72, + 0xA4, 0x19, 0x01, 0x9D, 0x9C, 0x0B, 0x81, 0x5F, 0x73, 0x49, 0xBA, 0xA7, + 0xAC, 0xF3, 0x04, 0x4E, 0x7B, 0x96, 0x0B, 0xEC, 0x11, 0xE0, 0x5B, 0xA6, + 0x1C, 0xCE, 0x1B, 0xD2, 0x0D, 0x83, 0x1C, 0x2B, 0xB8, 0x9E, 0x1D, 0x7E, + 0x45, 0x32, 0x60, 0x0F, 0x07, 0xE9, 0x77, 0x58, 0x7E, 0x9F, 0x6A, 0xC8, + 0x61, 0x4E, 0xB6, 0x26, 0xC1, 0x4C, 0x8D, 0xFF, 0x4C, 0xEF, 0x34, 0xB2, + 0x1F, 0x65, 0xD8, 0xB9, 0x78, 0xF5, 0xAD, 0xA9, 0x71, 0xB9, 0xEF, 0x4F, + 0x58, 0x1D, 0xA5, 0xDE, 0x74, 0x20, 0x97, 0xA1, 0xED, 0x68, 0x4C, 0xDE, + 0x92, 0x17, 0x4B, 0xBC, 0xAB, 0xFF, 0x65, 0x9A, 0x9E, 0xFB, 0x47, 0xD9, + 0x57, 0x72, 0xF3, 0x09, 0xA1, 0xAE, 0x76, 0x44, 0x13, 0x6E, 0x9C, 0x2D, + 0x44, 0x39, 0xBC, 0xF9, 0xC7, 0x3B, 0xA4, 0x58, 0x3D, 0x41, 0xBD, 0xB4, + 0xC2, 0x49, 0xA3, 0xC8, 0x0D, 0xD2, 0x97, 0x2F, 0x07, 0x65, 0x52, 0x00, + 0xA7, 0x6E, 0xC8, 0xAF, 0x68, 0xEC, 0xF4, 0x14, 0x96, 0xB6, 0x57, 0x1F, + 0x56, 0xC3, 0x39, 0x9F, 0x2B, 0x6D, 0xE4, 0xF3, 0x3E, 0xF6, 0x35, 0x64, + 0xDA, 0x0C, 0x1C, 0xA1, 0x84, 0x4B, 0x2F, 0x4B, 0x4B, 0xE2, 0x2C, 0x24, + 0x9D, 0x6D, 0x93, 0x40, 0xEB, 0xB5, 0x23, 0x8E, 0x32, 0xCA, 0x6F, 0x45, + 0xD3, 0xA8, 0x89, 0x7B, 0x1E, 0xCF, 0x1E, 0xFA, 0x5B, 0x43, 0x8B, 0xCD, + 0xCD, 0xA8, 0x0F, 0x6A, 0xCA, 0x0C, 0x5E, 0xB9, 0x9E, 0x47, 0x8F, 0xF0, + 0xD9, 0xB6, 0x0A, 0x0B, 0x58, 0x65, 0x17, 0x33, 0xB9, 0x23, 0xE4, 0x77, + 0x19, 0x7D, 0xCB, 0x4A, 0x2E, 0x92, 0x7B, 0x4F, 0x2F, 0x10, 0x77, 0xB1, + 0x8D, 0x2F, 0x68, 0x9C, 0x62, 0xCC, 0xE0, 0x50, 0xF8, 0xEC, 0x91, 0xA7, + 0x54, 0x4C, 0x57, 0x09, 0xD5, 0x76, 0x63, 0xC5, 0xE8, 0x65, 0x1E, 0xEE, + 0x6D, 0x6A, 0xCF, 0x09, 0x9D, 0xFA, 0x7C, 0x4F, 0xAD, 0x60, 0x08, 0xFD, + 0x56, 0x99, 0x0F, 0x15, 0x2C, 0x7B, 0xA9, 0x80, 0xAB, 0x8C, 0x61, 0x8F, + 0x4A, 0x07, 0x76, 0x42, 0xDE, 0x3D, 0xF4, 0xDD, 0xB2, 0x24, 0x33, 0x5B, + 0xB8, 0xB5, 0xA3, 0x44, 0xC9, 0xAC, 0x7F, 0x77, 0x3C, 0x1D, 0x23, 0xEC, + 0x82, 0xA9, 0xA6, 0xE2, 0xC8, 0x06, 0x4C, 0x02, 0xFE, 0xAC, 0x5C, 0x99, + 0x99, 0x0B, 0x2F, 0x10, 0x8A, 0xA6, 0xF4, 0x7F, 0xD5, 0x87, 0x74, 0x0D, + 0x59, 0x49, 0x45, 0xF6, 0xF0, 0x71, 0x5C, 0x39, 0x29, 0xD6, 0xBF, 0x4A, + 0x23, 0x8B, 0xF5, 0x5F, 0x01, 0x63, 0xD2, 0x87, 0x73, 0x28, 0xB5, 0x4B, + 0x0A, 0xF5, 0xF8, 0xAB, 0x82, 0x2C, 0x7E, 0x73, 0x25, 0x32, 0x1D, 0x0B, + 0x63, 0x0A, 0x17, 0x81, 0x00, 0xFF, 0xB6, 0x76, 0x5E, 0xE7, 0xB4, 0xB1, + 0x40, 0xCA, 0x21, 0xBB, 0xD5, 0x80, 0x51, 0xE5, 0x48, 0x52, 0x67, 0x2C, + 0xD2, 0x61, 0x89, 0x07, 0x0D, 0x0F, 0xCE, 0x42, 0x77, 0xC0, 0x44, 0x73, + 0x9C, 0x44, 0x50, 0xA0, 0xDB, 0x10, 0x0A, 0x2D, 0x95, 0x1C, 0x81, 0xAF, + 0xE4, 0x1C, 0xE5, 0x14, 0x1E, 0xF1, 0x36, 0x41, 0x01, 0x02, 0x2F, 0x7D, + 0x73, 0xA7, 0xDE, 0x42, 0xCC, 0x4C, 0xE9, 0x89, 0x0D, 0x56, 0xF7, 0x9F, + 0x91, 0xD4, 0x03, 0xC6, 0x6C, 0xC9, 0x8F, 0xDB, 0xD8, 0x1C, 0xE0, 0x40, + 0x98, 0x5D, 0x66, 0x99, 0x98, 0x80, 0x6E, 0x2D, 0xFF, 0x01, 0xC5, 0xCE, + 0xCB, 0x46, 0x1F, 0xAC, 0x02, 0xC6, 0x43, 0xE6, 0xAE, 0xA2, 0x84, 0x3C, + 0xC5, 0x4E, 0x1E, 0x3D, 0x6D, 0xC9, 0x14, 0x4C, 0xE3, 0x2E, 0x41, 0xBB, + 0xCA, 0x39, 0xBF, 0x36, 0x3C, 0x2A, 0x19, 0xAA, 0x41, 0x87, 0x4E, 0xA5, + 0xCE, 0x4B, 0x32, 0x79, 0xDD, 0x90, 0x49, 0x7F +}; + +static const unsigned char TA202_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA203_DN[] = { + 0x30, 0x3C, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x15, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x0D, + 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x04, 0x41, 0x74, 0x6F, + 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x44, 0x45 +}; + +static const unsigned char TA203_RSA_N[] = { + 0x95, 0x85, 0x3B, 0x97, 0x6F, 0x2A, 0x3B, 0x2E, 0x3B, 0xCF, 0xA6, 0xF3, + 0x29, 0x35, 0xBE, 0xCF, 0x18, 0xAC, 0x3E, 0xAA, 0xD9, 0xF8, 0x4D, 0xA0, + 0x3E, 0x1A, 0x47, 0xB9, 0xBC, 0x9A, 0xDF, 0xF2, 0xFE, 0xCC, 0x3E, 0x47, + 0xE8, 0x7A, 0x96, 0xC2, 0x24, 0x8E, 0x35, 0xF4, 0xA9, 0x0C, 0xFC, 0x82, + 0xFD, 0x6D, 0xC1, 0x72, 0x62, 0x27, 0xBD, 0xEA, 0x6B, 0xEB, 0xE7, 0x8A, + 0xCC, 0x54, 0x3E, 0x90, 0x50, 0xCF, 0x80, 0xD4, 0x95, 0xFB, 0xE8, 0xB5, + 0x82, 0xD4, 0x14, 0xC5, 0xB6, 0xA9, 0x55, 0x25, 0x57, 0xDB, 0xB1, 0x50, + 0xF6, 0xB0, 0x60, 0x64, 0x59, 0x7A, 0x69, 0xCF, 0x03, 0xB7, 0x6F, 0x0D, + 0xBE, 0xCA, 0x3E, 0x6F, 0x74, 0x72, 0xEA, 0xAA, 0x30, 0x2A, 0x73, 0x62, + 0xBE, 0x49, 0x91, 0x61, 0xC8, 0x11, 0xFE, 0x0E, 0x03, 0x2A, 0xF7, 0x6A, + 0x20, 0xDC, 0x02, 0x15, 0x0D, 0x5E, 0x15, 0x6A, 0xFC, 0xE3, 0x82, 0xC1, + 0xB5, 0xC5, 0x9D, 0x64, 0x09, 0x6C, 0xA3, 0x59, 0x98, 0x07, 0x27, 0xC7, + 0x1B, 0x96, 0x2B, 0x61, 0x74, 0x71, 0x6C, 0x43, 0xF1, 0xF7, 0x35, 0x89, + 0x10, 0xE0, 0x9E, 0xEC, 0x55, 0xA1, 0x37, 0x22, 0xA2, 0x87, 0x04, 0x05, + 0x2C, 0x47, 0x7D, 0xB4, 0x1C, 0xB9, 0x62, 0x29, 0x66, 0x28, 0xCA, 0xB7, + 0xE1, 0x93, 0xF5, 0xA4, 0x94, 0x03, 0x99, 0xB9, 0x70, 0x85, 0xB5, 0xE6, + 0x48, 0xEA, 0x8D, 0x50, 0xFC, 0xD9, 0xDE, 0xCC, 0x6F, 0x07, 0x0E, 0xDD, + 0x0B, 0x72, 0x9D, 0x80, 0x30, 0x16, 0x07, 0x95, 0x3F, 0x28, 0x0E, 0xFD, + 0xC5, 0x75, 0x4F, 0x53, 0xD6, 0x74, 0x9A, 0xB4, 0x24, 0x2E, 0x8E, 0x02, + 0x91, 0xCF, 0x76, 0xC5, 0x9B, 0x1E, 0x55, 0x74, 0x9C, 0x78, 0x21, 0xB1, + 0xF0, 0x2D, 0xF1, 0x0B, 0x9F, 0xC2, 0xD5, 0x96, 0x18, 0x1F, 0xF0, 0x54, + 0x22, 0x7A, 0x8C, 0x07 +}; + +static const unsigned char TA203_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA204_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x45, 0x43, 0x43, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA204_EC_Q[] = { + 0x04, 0x96, 0x86, 0x58, 0x28, 0x37, 0x0A, 0x67, 0xD0, 0xA0, 0xDE, 0x24, + 0x19, 0x19, 0xE1, 0xE4, 0x05, 0x07, 0x1F, 0x97, 0xED, 0xE8, 0x64, 0x82, + 0xB9, 0xF6, 0xC4, 0x71, 0x50, 0xCE, 0x8A, 0x0C, 0xFF, 0xD7, 0xB5, 0x76, + 0xBB, 0xA1, 0x6C, 0x93, 0x6C, 0x83, 0xA2, 0x68, 0x6E, 0xA5, 0xD9, 0xBE, + 0x2C, 0x88, 0x95, 0x41, 0xCD, 0x5D, 0xDD, 0xB1, 0xCA, 0x83, 0x63, 0x83, + 0xCC, 0xC0, 0xBE, 0x74, 0xD9, 0xE0, 0x9D, 0xA4, 0xEE, 0x4A, 0x4E, 0x56, + 0xE0, 0x98, 0x29, 0x41, 0x93, 0x52, 0x10, 0xD5, 0x24, 0x38, 0x02, 0x32, + 0x67, 0xF1, 0x94, 0x12, 0x6F, 0xEF, 0xD7, 0xC5, 0xDE, 0x2E, 0xFD, 0x19, + 0x80 +}; + +static const unsigned char TA205_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA205_RSA_N[] = { + 0xB6, 0x80, 0x0E, 0xC4, 0x79, 0xBD, 0x05, 0x8C, 0x7D, 0xB0, 0xA3, 0x9D, + 0x4D, 0x22, 0x4D, 0xCB, 0xF0, 0x41, 0x97, 0x4D, 0x59, 0xE0, 0xD1, 0xFE, + 0x56, 0x8C, 0x97, 0xF2, 0xD7, 0xBD, 0x8F, 0x6C, 0xB7, 0x23, 0x8F, 0x5F, + 0xD5, 0xC4, 0xD8, 0x41, 0xCB, 0xF2, 0x02, 0x1E, 0x71, 0xE5, 0xE9, 0xF6, + 0x5E, 0xCB, 0x08, 0x2A, 0x5E, 0x30, 0xF2, 0x2D, 0x66, 0xC7, 0x84, 0x1B, + 0x64, 0x57, 0x38, 0x9D, 0x75, 0x2D, 0x56, 0xC6, 0x2F, 0x61, 0xEF, 0x96, + 0xFC, 0x20, 0x46, 0xBD, 0xEB, 0xD4, 0x7B, 0x3F, 0x3F, 0x7C, 0x47, 0x38, + 0x04, 0xA9, 0x1B, 0xAA, 0x52, 0xDF, 0x13, 0x37, 0xD3, 0x15, 0x15, 0x4E, + 0xBD, 0x5F, 0x7C, 0xAF, 0xAD, 0x63, 0xC7, 0x79, 0xDC, 0x08, 0x7B, 0xD5, + 0xA0, 0xE5, 0xF7, 0x5B, 0x75, 0xAC, 0x80, 0x55, 0x99, 0x92, 0x61, 0x9B, + 0xCD, 0x2A, 0x17, 0x7D, 0xDB, 0x8F, 0xF4, 0xB5, 0x6A, 0xEA, 0x17, 0x4A, + 0x64, 0x28, 0x66, 0x15, 0x29, 0x6C, 0x02, 0xF1, 0x6B, 0xD5, 0xBA, 0xA3, + 0x33, 0xDC, 0x5A, 0x67, 0xA7, 0x05, 0xE2, 0xBF, 0x65, 0xB6, 0x16, 0xB0, + 0x10, 0xED, 0xCD, 0x50, 0x33, 0xC9, 0x70, 0x50, 0xEC, 0x19, 0x8E, 0xB0, + 0xC7, 0xF2, 0x74, 0x5B, 0x6B, 0x44, 0xC6, 0x7D, 0x96, 0xB9, 0x98, 0x08, + 0x59, 0x66, 0xDE, 0x29, 0x01, 0x9B, 0xF4, 0x2A, 0x6D, 0xD3, 0x15, 0x3A, + 0x90, 0x6A, 0x67, 0xF1, 0xB4, 0x6B, 0x66, 0xD9, 0x21, 0xEB, 0xCA, 0xD9, + 0x62, 0x7C, 0x46, 0x10, 0x5C, 0xDE, 0x75, 0x49, 0x67, 0x9E, 0x42, 0xF9, + 0xFE, 0x75, 0xA9, 0xA3, 0xAD, 0xFF, 0x76, 0x0A, 0x67, 0x40, 0xE3, 0xC5, + 0xF7, 0x8D, 0xC7, 0x85, 0x9A, 0x59, 0x9E, 0x62, 0x9A, 0x6A, 0xED, 0x45, + 0x87, 0x98, 0x67, 0xB2, 0xD5, 0x4A, 0x3C, 0xD7, 0xB4, 0x3B, 0x00, 0x0D, + 0xC0, 0x8F, 0x1F, 0xE1, 0x40, 0xC4, 0xAE, 0x6C, 0x21, 0xDC, 0x49, 0x7E, + 0x7E, 0xCA, 0xB2, 0x8D, 0x6D, 0xB6, 0xBF, 0x93, 0x2F, 0xA1, 0x5C, 0x3E, + 0x8F, 0xCA, 0xED, 0x80, 0x8E, 0x58, 0xE1, 0xDB, 0x57, 0xCF, 0x85, 0x36, + 0x38, 0xB2, 0x71, 0xA4, 0x09, 0x8C, 0x92, 0x89, 0x08, 0x88, 0x48, 0xF1, + 0x40, 0x63, 0x18, 0xB2, 0x5B, 0x8C, 0x5A, 0xE3, 0xC3, 0xD3, 0x17, 0xAA, + 0xAB, 0x19, 0xA3, 0x2C, 0x1B, 0xE4, 0xD5, 0xC6, 0xE2, 0x66, 0x7A, 0xD7, + 0x82, 0x19, 0xA6, 0x3B, 0x16, 0x2C, 0x2F, 0x71, 0x87, 0x5F, 0x45, 0x9E, + 0x95, 0x73, 0x93, 0xC2, 0x42, 0x81, 0x21, 0x13, 0x96, 0xD7, 0x9D, 0xBB, + 0x93, 0x68, 0x15, 0xFA, 0x9D, 0xA4, 0x1D, 0x8C, 0xF2, 0x81, 0xE0, 0x58, + 0x06, 0xBD, 0xC9, 0xB6, 0xE3, 0xF6, 0x89, 0x5D, 0x89, 0xF9, 0xAC, 0x44, + 0xA1, 0xCB, 0x6B, 0xFA, 0x16, 0xF1, 0xC7, 0x50, 0x3D, 0x24, 0xDA, 0xF7, + 0xC3, 0xE4, 0x87, 0xD5, 0x56, 0xF1, 0x4F, 0x90, 0x30, 0xFA, 0x45, 0x09, + 0x59, 0xDA, 0x34, 0xCE, 0xE0, 0x13, 0x1C, 0x04, 0x7C, 0x00, 0xD4, 0x9B, + 0x86, 0xA4, 0x40, 0xBC, 0xD9, 0xDC, 0x4C, 0x57, 0x7E, 0xAE, 0xB7, 0x33, + 0xB6, 0x5E, 0x76, 0xE1, 0x65, 0x8B, 0x66, 0xDF, 0x8D, 0xCA, 0xD7, 0x98, + 0xAF, 0xCE, 0x36, 0x98, 0x8C, 0x9C, 0x83, 0x99, 0x03, 0x70, 0xF3, 0xAF, + 0x74, 0xED, 0xC6, 0x0E, 0x36, 0xE7, 0xBD, 0xEC, 0xC1, 0x73, 0xA7, 0x94, + 0x5A, 0xCB, 0x92, 0x64, 0x82, 0xA6, 0x00, 0xC1, 0x70, 0xA1, 0x6E, 0x2C, + 0x29, 0xE1, 0x58, 0x57, 0xEC, 0x5A, 0x7C, 0x99, 0x6B, 0x25, 0xA4, 0x90, + 0x3A, 0x80, 0xF4, 0x20, 0x9D, 0x9A, 0xCE, 0xC7, 0x2D, 0xF9, 0xB2, 0x4B, + 0x29, 0x95, 0x83, 0xE9, 0x35, 0x8D, 0xA7, 0x49, 0x48, 0xA7, 0x0F, 0x4C, + 0x19, 0x91, 0xD0, 0xF5, 0xBF, 0x10, 0xE0, 0x71 +}; + +static const unsigned char TA205_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA206_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x39, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, 0x20, + 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x63, 0x69, 0x6F, 0x6E, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, + 0x6F, 0x66, 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x43, 0x49, + 0x46, 0x20, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38 +}; + +static const unsigned char TA206_RSA_N[] = { + 0xCA, 0x96, 0x6B, 0x8E, 0xEA, 0xF8, 0xFB, 0xF1, 0xA2, 0x35, 0xE0, 0x7F, + 0x4C, 0xDA, 0xE0, 0xC3, 0x52, 0xD7, 0x7D, 0xB6, 0x10, 0xC8, 0x02, 0x5E, + 0xB3, 0x43, 0x2A, 0xC4, 0x4F, 0x6A, 0xB2, 0xCA, 0x1C, 0x5D, 0x28, 0x9A, + 0x78, 0x11, 0x1A, 0x69, 0x59, 0x57, 0xAF, 0xB5, 0x20, 0x42, 0xE4, 0x8B, + 0x0F, 0xE6, 0xDF, 0x5B, 0xA6, 0x03, 0x92, 0x2F, 0xF5, 0x11, 0xE4, 0x62, + 0xD7, 0x32, 0x71, 0x38, 0xD9, 0x04, 0x0C, 0x71, 0xAB, 0x3D, 0x51, 0x7E, + 0x0F, 0x07, 0xDF, 0x63, 0x05, 0x5C, 0xE9, 0xBF, 0x94, 0x6F, 0xC1, 0x29, + 0x82, 0xC0, 0xB4, 0xDA, 0x51, 0xB0, 0xC1, 0x3C, 0xBB, 0xAD, 0x37, 0x4A, + 0x5C, 0xCA, 0xF1, 0x4B, 0x36, 0x0E, 0x24, 0xAB, 0xBF, 0xC3, 0x84, 0x77, + 0xFD, 0xA8, 0x50, 0xF4, 0xB1, 0xE7, 0xC6, 0x2F, 0xD2, 0x2D, 0x59, 0x8D, + 0x7A, 0x0A, 0x4E, 0x96, 0x69, 0x52, 0x02, 0xAA, 0x36, 0x98, 0xEC, 0xFC, + 0xFA, 0x14, 0x83, 0x0C, 0x37, 0x1F, 0xC9, 0x92, 0x37, 0x7F, 0xD7, 0x81, + 0x2D, 0xE5, 0xC4, 0xB9, 0xE0, 0x3E, 0x34, 0xFE, 0x67, 0xF4, 0x3E, 0x66, + 0xD1, 0xD3, 0xF4, 0x40, 0xCF, 0x5E, 0x62, 0x34, 0x0F, 0x70, 0x06, 0x3E, + 0x20, 0x18, 0x5A, 0xCE, 0xF7, 0x72, 0x1B, 0x25, 0x6C, 0x93, 0x74, 0x14, + 0x93, 0xA3, 0x73, 0xB1, 0x0E, 0xAA, 0x87, 0x10, 0x23, 0x59, 0x5F, 0x20, + 0x05, 0x19, 0x47, 0xED, 0x68, 0x8E, 0x92, 0x12, 0xCA, 0x5D, 0xFC, 0xD6, + 0x2B, 0xB2, 0x92, 0x3C, 0x20, 0xCF, 0xE1, 0x5F, 0xAF, 0x20, 0xBE, 0xA0, + 0x76, 0x7F, 0x76, 0xE5, 0xEC, 0x1A, 0x86, 0x61, 0x33, 0x3E, 0xE7, 0x7B, + 0xB4, 0x3F, 0xA0, 0x0F, 0x8E, 0xA2, 0xB9, 0x6A, 0x6F, 0xB9, 0x87, 0x26, + 0x6F, 0x41, 0x6C, 0x88, 0xA6, 0x50, 0xFD, 0x6A, 0x63, 0x0B, 0xF5, 0x93, + 0x16, 0x1B, 0x19, 0x8F, 0xB2, 0xED, 0x9B, 0x9B, 0xC9, 0x90, 0xF5, 0x01, + 0x0C, 0xDF, 0x19, 0x3D, 0x0F, 0x3E, 0x38, 0x23, 0xC9, 0x2F, 0x8F, 0x0C, + 0xD1, 0x02, 0xFE, 0x1B, 0x55, 0xD6, 0x4E, 0xD0, 0x8D, 0x3C, 0xAF, 0x4F, + 0xA4, 0xF3, 0xFE, 0xAF, 0x2A, 0xD3, 0x05, 0x9D, 0x79, 0x08, 0xA1, 0xCB, + 0x57, 0x31, 0xB4, 0x9C, 0xC8, 0x90, 0xB2, 0x67, 0xF4, 0x18, 0x16, 0x93, + 0x3A, 0xFC, 0x47, 0xD8, 0xD1, 0x78, 0x96, 0x31, 0x1F, 0xBA, 0x2B, 0x0C, + 0x5F, 0x5D, 0x99, 0xAD, 0x63, 0x89, 0x5A, 0x24, 0x20, 0x76, 0xD8, 0xDF, + 0xFD, 0xAB, 0x4E, 0xA6, 0x22, 0xAA, 0x9D, 0x5E, 0xE6, 0x27, 0x8A, 0x7D, + 0x68, 0x29, 0xA3, 0xE7, 0x8A, 0xB8, 0xDA, 0x11, 0xBB, 0x17, 0x2D, 0x99, + 0x9D, 0x13, 0x24, 0x46, 0xF7, 0xC5, 0xE2, 0xD8, 0x9F, 0x8E, 0x7F, 0xC7, + 0x8F, 0x74, 0x6D, 0x5A, 0xB2, 0xE8, 0x72, 0xF5, 0xAC, 0xEE, 0x24, 0x10, + 0xAD, 0x2F, 0x14, 0xDA, 0xFF, 0x2D, 0x9A, 0x46, 0x71, 0x47, 0xBE, 0x42, + 0xDF, 0xBB, 0x01, 0xDB, 0xF4, 0x7F, 0xD3, 0x28, 0x8F, 0x31, 0x59, 0x5B, + 0xD3, 0xC9, 0x02, 0xA6, 0xB4, 0x52, 0xCA, 0x6E, 0x97, 0xFB, 0x43, 0xC5, + 0x08, 0x26, 0x6F, 0x8A, 0xF4, 0xBB, 0xFD, 0x9F, 0x28, 0xAA, 0x0D, 0xD5, + 0x45, 0xF3, 0x13, 0x3A, 0x1D, 0xD8, 0xC0, 0x78, 0x8F, 0x41, 0x67, 0x3C, + 0x1E, 0x94, 0x64, 0xAE, 0x7B, 0x0B, 0xC5, 0xE8, 0xD9, 0x01, 0x88, 0x39, + 0x1A, 0x97, 0x86, 0x64, 0x41, 0xD5, 0x3B, 0x87, 0x0C, 0x6E, 0xFA, 0x0F, + 0xC6, 0xBD, 0x48, 0x14, 0xBF, 0x39, 0x4D, 0xD4, 0x9E, 0x41, 0xB6, 0x8F, + 0x96, 0x1D, 0x63, 0x96, 0x93, 0xD9, 0x95, 0x06, 0x78, 0x31, 0x68, 0x9E, + 0x37, 0x06, 0x3B, 0x80, 0x89, 0x45, 0x61, 0x39, 0x23, 0xC7, 0x1B, 0x44, + 0xA3, 0x15, 0xE5, 0x1C, 0xF8, 0x92, 0x30, 0xBB +}; + +static const unsigned char TA206_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA207_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x34, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA207_EC_Q[] = { + 0x04, 0xB8, 0xC6, 0x79, 0xD3, 0x8F, 0x6C, 0x25, 0x0E, 0x9F, 0x2E, 0x39, + 0x19, 0x1C, 0x03, 0xA4, 0xAE, 0x9A, 0xE5, 0x39, 0x07, 0x09, 0x16, 0xCA, + 0x63, 0xB1, 0xB9, 0x86, 0xF8, 0x8A, 0x57, 0xC1, 0x57, 0xCE, 0x42, 0xFA, + 0x73, 0xA1, 0xF7, 0x65, 0x42, 0xFF, 0x1E, 0xC1, 0x00, 0xB2, 0x6E, 0x73, + 0x0E, 0xFF, 0xC7, 0x21, 0xE5, 0x18, 0xA4, 0xAA, 0xD9, 0x71, 0x3F, 0xA8, + 0xD4, 0xB9, 0xCE, 0x8C, 0x1D +}; + +static const unsigned char TA208_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x13, 0x54, 0x57, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, + 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA208_RSA_N[] = { + 0xB0, 0x05, 0xDB, 0xC8, 0xEB, 0x8C, 0xC4, 0x6E, 0x8A, 0x21, 0xEF, 0x8E, + 0x4D, 0x9C, 0x71, 0x0A, 0x1F, 0x52, 0x70, 0xED, 0x6D, 0x82, 0x9C, 0x97, + 0xC5, 0xD7, 0x4C, 0x4E, 0x45, 0x49, 0xCB, 0x40, 0x42, 0xB5, 0x12, 0x34, + 0x6C, 0x19, 0xC2, 0x74, 0xA4, 0x31, 0x5F, 0x85, 0x02, 0x97, 0xEC, 0x43, + 0x33, 0x0A, 0x53, 0xD2, 0x9C, 0x8C, 0x8E, 0xB7, 0xB8, 0x79, 0xDB, 0x2B, + 0xD5, 0x6A, 0xF2, 0x8E, 0x66, 0xC4, 0xEE, 0x2B, 0x01, 0x07, 0x92, 0xD4, + 0xB3, 0xD0, 0x02, 0xDF, 0x50, 0xF6, 0x55, 0xAF, 0x66, 0x0E, 0xCB, 0xE0, + 0x47, 0x60, 0x2F, 0x2B, 0x32, 0x39, 0x35, 0x52, 0x3A, 0x28, 0x83, 0xF8, + 0x7B, 0x16, 0xC6, 0x18, 0xB8, 0x62, 0xD6, 0x47, 0x25, 0x91, 0xCE, 0xF0, + 0x19, 0x12, 0x4D, 0xAD, 0x63, 0xF5, 0xD3, 0x3F, 0x75, 0x5F, 0x29, 0xF0, + 0xA1, 0x30, 0x1C, 0x2A, 0xA0, 0x98, 0xA6, 0x15, 0xBD, 0xEE, 0xFD, 0x19, + 0x36, 0xF0, 0xE2, 0x91, 0x43, 0x8F, 0xFA, 0xCA, 0xD6, 0x10, 0x27, 0x49, + 0x4C, 0xEF, 0xDD, 0xC1, 0xF1, 0x85, 0x70, 0x9B, 0xCA, 0xEA, 0xA8, 0x5A, + 0x43, 0xFC, 0x6D, 0x86, 0x6F, 0x73, 0xE9, 0x37, 0x45, 0xA9, 0xF0, 0x36, + 0xC7, 0xCC, 0x88, 0x75, 0x1E, 0xBB, 0x6C, 0x06, 0xFF, 0x9B, 0x6B, 0x3E, + 0x17, 0xEC, 0x61, 0xAA, 0x71, 0x7C, 0xC6, 0x1D, 0xA2, 0xF7, 0x49, 0xE9, + 0x15, 0xB5, 0x3C, 0xD6, 0xA1, 0x61, 0xF5, 0x11, 0xF7, 0x05, 0x6F, 0x1D, + 0xFD, 0x11, 0xBE, 0xD0, 0x30, 0x07, 0xC2, 0x29, 0xB0, 0x09, 0x4E, 0x26, + 0xDC, 0xE3, 0xA2, 0xA8, 0x91, 0x6A, 0x1F, 0xC2, 0x91, 0x45, 0x88, 0x5C, + 0xE5, 0x98, 0xB8, 0x71, 0xA5, 0x15, 0x19, 0xC9, 0x7C, 0x75, 0x11, 0xCC, + 0x70, 0x74, 0x4F, 0x2D, 0x9B, 0x1D, 0x91, 0x44, 0xFD, 0x56, 0x28, 0xA0, + 0xFE, 0xBB, 0x86, 0x6A, 0xC8, 0xFA, 0x5C, 0x0B, 0x58, 0xDC, 0xC6, 0x4B, + 0x76, 0xC8, 0xAB, 0x22, 0xD9, 0x73, 0x0F, 0xA5, 0xF4, 0x5A, 0x02, 0x89, + 0x3F, 0x4F, 0x9E, 0x22, 0x82, 0xEE, 0xA2, 0x74, 0x53, 0x2A, 0x3D, 0x53, + 0x27, 0x69, 0x1D, 0x6C, 0x8E, 0x32, 0x2C, 0x64, 0x00, 0x26, 0x63, 0x61, + 0x36, 0x4E, 0xA3, 0x46, 0xB7, 0x3F, 0x7D, 0xB3, 0x2D, 0xAC, 0x6D, 0x90, + 0xA2, 0x95, 0xA2, 0xCE, 0xCF, 0xDA, 0x82, 0xE7, 0x07, 0x34, 0x19, 0x96, + 0xE9, 0xB8, 0x21, 0xAA, 0x29, 0x7E, 0xA6, 0x38, 0xBE, 0x8E, 0x29, 0x4A, + 0x21, 0x66, 0x79, 0x1F, 0xB3, 0xC3, 0xB5, 0x09, 0x67, 0xDE, 0xD6, 0xD4, + 0x07, 0x46, 0xF3, 0x2A, 0xDA, 0xE6, 0x22, 0x37, 0x60, 0xCB, 0x81, 0xB6, + 0x0F, 0xA0, 0x0F, 0xE9, 0xC8, 0x95, 0x7F, 0xBF, 0x55, 0x91, 0x05, 0x7A, + 0xCF, 0x3D, 0x15, 0xC0, 0x6F, 0xDE, 0x09, 0x94, 0x01, 0x83, 0xD7, 0x34, + 0x1B, 0xCC, 0x40, 0xA5, 0xF0, 0xB8, 0x9B, 0x67, 0xD5, 0x98, 0x91, 0x3B, + 0xA7, 0x84, 0x78, 0x95, 0x26, 0xA4, 0x5A, 0x08, 0xF8, 0x2B, 0x74, 0xB4, + 0x00, 0x04, 0x3C, 0xDF, 0xB8, 0x14, 0x8E, 0xE8, 0xDF, 0xA9, 0x8D, 0x6C, + 0x67, 0x92, 0x33, 0x1D, 0xC0, 0xB7, 0xD2, 0xEC, 0x92, 0xC8, 0xBE, 0x09, + 0xBF, 0x2C, 0x29, 0x05, 0x6F, 0x02, 0x6B, 0x9E, 0xEF, 0xBC, 0xBF, 0x2A, + 0xBC, 0x5B, 0xC0, 0x50, 0x8F, 0x41, 0x70, 0x71, 0x87, 0xB2, 0x4D, 0xB7, + 0x04, 0xA9, 0x84, 0xA3, 0x32, 0xAF, 0xAE, 0xEE, 0x6B, 0x17, 0x8B, 0xB2, + 0xB1, 0xFE, 0x6C, 0xE1, 0x90, 0x8C, 0x88, 0xA8, 0x97, 0x48, 0xCE, 0xC8, + 0x4D, 0xCB, 0xF3, 0x06, 0xCF, 0x5F, 0x6A, 0x0A, 0x42, 0xB1, 0x1E, 0x1E, + 0x77, 0x2F, 0x8E, 0xA0, 0xE6, 0x92, 0x0E, 0x06, 0xFC, 0x05, 0x22, 0xD2, + 0x26, 0xE1, 0x31, 0x51, 0x7D, 0x32, 0xDC, 0x0F +}; + +static const unsigned char TA208_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA209_DN[] = { + 0x30, 0x57, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, + 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA209_RSA_N[] = { + 0xDA, 0x0E, 0xE6, 0x99, 0x8D, 0xCE, 0xA3, 0xE3, 0x4F, 0x8A, 0x7E, 0xFB, + 0xF1, 0x8B, 0x83, 0x25, 0x6B, 0xEA, 0x48, 0x1F, 0xF1, 0x2A, 0xB0, 0xB9, + 0x95, 0x11, 0x04, 0xBD, 0xF0, 0x63, 0xD1, 0xE2, 0x67, 0x66, 0xCF, 0x1C, + 0xDD, 0xCF, 0x1B, 0x48, 0x2B, 0xEE, 0x8D, 0x89, 0x8E, 0x9A, 0xAF, 0x29, + 0x80, 0x65, 0xAB, 0xE9, 0xC7, 0x2D, 0x12, 0xCB, 0xAB, 0x1C, 0x4C, 0x70, + 0x07, 0xA1, 0x3D, 0x0A, 0x30, 0xCD, 0x15, 0x8D, 0x4F, 0xF8, 0xDD, 0xD4, + 0x8C, 0x50, 0x15, 0x1C, 0xEF, 0x50, 0xEE, 0xC4, 0x2E, 0xF7, 0xFC, 0xE9, + 0x52, 0xF2, 0x91, 0x7D, 0xE0, 0x6D, 0xD5, 0x35, 0x30, 0x8E, 0x5E, 0x43, + 0x73, 0xF2, 0x41, 0xE9, 0xD5, 0x6A, 0xE3, 0xB2, 0x89, 0x3A, 0x56, 0x39, + 0x38, 0x6F, 0x06, 0x3C, 0x88, 0x69, 0x5B, 0x2A, 0x4D, 0xC5, 0xA7, 0x54, + 0xB8, 0x6C, 0x89, 0xCC, 0x9B, 0xF9, 0x3C, 0xCA, 0xE5, 0xFD, 0x89, 0xF5, + 0x12, 0x3C, 0x92, 0x78, 0x96, 0xD6, 0xDC, 0x74, 0x6E, 0x93, 0x44, 0x61, + 0xD1, 0x8D, 0xC7, 0x46, 0xB2, 0x75, 0x0E, 0x86, 0xE8, 0x19, 0x8A, 0xD5, + 0x6D, 0x6C, 0xD5, 0x78, 0x16, 0x95, 0xA2, 0xE9, 0xC8, 0x0A, 0x38, 0xEB, + 0xF2, 0x24, 0x13, 0x4F, 0x73, 0x54, 0x93, 0x13, 0x85, 0x3A, 0x1B, 0xBC, + 0x1E, 0x34, 0xB5, 0x8B, 0x05, 0x8C, 0xB9, 0x77, 0x8B, 0xB1, 0xDB, 0x1F, + 0x20, 0x91, 0xAB, 0x09, 0x53, 0x6E, 0x90, 0xCE, 0x7B, 0x37, 0x74, 0xB9, + 0x70, 0x47, 0x91, 0x22, 0x51, 0x63, 0x16, 0x79, 0xAE, 0xB1, 0xAE, 0x41, + 0x26, 0x08, 0xC8, 0x19, 0x2B, 0xD1, 0x46, 0xAA, 0x48, 0xD6, 0x64, 0x2A, + 0xD7, 0x83, 0x34, 0xFF, 0x2C, 0x2A, 0xC1, 0x6C, 0x19, 0x43, 0x4A, 0x07, + 0x85, 0xE7, 0xD3, 0x7C, 0xF6, 0x21, 0x68, 0xEF, 0xEA, 0xF2, 0x52, 0x9F, + 0x7F, 0x93, 0x90, 0xCF +}; + +static const unsigned char TA209_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA210_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA210_RSA_N[] = { + 0xAD, 0x0E, 0x15, 0xCE, 0xE4, 0x43, 0x80, 0x5C, 0xB1, 0x87, 0xF3, 0xB7, + 0x60, 0xF9, 0x71, 0x12, 0xA5, 0xAE, 0xDC, 0x26, 0x94, 0x88, 0xAA, 0xF4, + 0xCE, 0xF5, 0x20, 0x39, 0x28, 0x58, 0x60, 0x0C, 0xF8, 0x80, 0xDA, 0xA9, + 0x15, 0x95, 0x32, 0x61, 0x3C, 0xB5, 0xB1, 0x28, 0x84, 0x8A, 0x8A, 0xDC, + 0x9F, 0x0A, 0x0C, 0x83, 0x17, 0x7A, 0x8F, 0x90, 0xAC, 0x8A, 0xE7, 0x79, + 0x53, 0x5C, 0x31, 0x84, 0x2A, 0xF6, 0x0F, 0x98, 0x32, 0x36, 0x76, 0xCC, + 0xDE, 0xDD, 0x3C, 0xA8, 0xA2, 0xEF, 0x6A, 0xFB, 0x21, 0xF2, 0x52, 0x61, + 0xDF, 0x9F, 0x20, 0xD7, 0x1F, 0xE2, 0xB1, 0xD9, 0xFE, 0x18, 0x64, 0xD2, + 0x12, 0x5B, 0x5F, 0xF9, 0x58, 0x18, 0x35, 0xBC, 0x47, 0xCD, 0xA1, 0x36, + 0xF9, 0x6B, 0x7F, 0xD4, 0xB0, 0x38, 0x3E, 0xC1, 0x1B, 0xC3, 0x8C, 0x33, + 0xD9, 0xD8, 0x2F, 0x18, 0xFE, 0x28, 0x0F, 0xB3, 0xA7, 0x83, 0xD6, 0xC3, + 0x6E, 0x44, 0xC0, 0x61, 0x35, 0x96, 0x16, 0xFE, 0x59, 0x9C, 0x8B, 0x76, + 0x6D, 0xD7, 0xF1, 0xA2, 0x4B, 0x0D, 0x2B, 0xFF, 0x0B, 0x72, 0xDA, 0x9E, + 0x60, 0xD0, 0x8E, 0x90, 0x35, 0xC6, 0x78, 0x55, 0x87, 0x20, 0xA1, 0xCF, + 0xE5, 0x6D, 0x0A, 0xC8, 0x49, 0x7C, 0x31, 0x98, 0x33, 0x6C, 0x22, 0xE9, + 0x87, 0xD0, 0x32, 0x5A, 0xA2, 0xBA, 0x13, 0x82, 0x11, 0xED, 0x39, 0x17, + 0x9D, 0x99, 0x3A, 0x72, 0xA1, 0xE6, 0xFA, 0xA4, 0xD9, 0xD5, 0x17, 0x31, + 0x75, 0xAE, 0x85, 0x7D, 0x22, 0xAE, 0x3F, 0x01, 0x46, 0x86, 0xF6, 0x28, + 0x79, 0xC8, 0xB1, 0xDA, 0xE4, 0x57, 0x17, 0xC4, 0x7E, 0x1C, 0x0E, 0xB0, + 0xB4, 0x92, 0xA6, 0x56, 0xB3, 0xBD, 0xB2, 0x97, 0xED, 0xAA, 0xA7, 0xF0, + 0xB7, 0xC5, 0xA8, 0x3F, 0x95, 0x16, 0xD0, 0xFF, 0xA1, 0x96, 0xEB, 0x08, + 0x5F, 0x18, 0x77, 0x4F +}; + +static const unsigned char TA210_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA211_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA211_EC_Q[] = { + 0x04, 0xC6, 0xCB, 0xC7, 0x28, 0xD1, 0xFB, 0x84, 0xF5, 0x9A, 0xEF, 0x42, + 0x14, 0x20, 0xE1, 0x43, 0x6B, 0x6E, 0x75, 0xAD, 0xFC, 0x2B, 0x03, 0x84, + 0xD4, 0x76, 0x93, 0x25, 0xD7, 0x59, 0x3B, 0x41, 0x65, 0x6B, 0x1E, 0xE6, + 0x34, 0x2A, 0xBB, 0x74, 0xF6, 0x12, 0xCE, 0xE8, 0x6D, 0xE7, 0xAB, 0xE4, + 0x3C, 0x4E, 0x3F, 0x44, 0x08, 0x8B, 0xCD, 0x16, 0x71, 0xCB, 0xBF, 0x92, + 0x99, 0xF4, 0xA4, 0xD7, 0x3C, 0x50, 0x54, 0x52, 0x90, 0x85, 0x83, 0x78, + 0x94, 0x67, 0x67, 0xA3, 0x1C, 0x09, 0x19, 0x3D, 0x75, 0x34, 0x85, 0xDE, + 0xED, 0x60, 0x7D, 0xC7, 0x0C, 0xB4, 0x41, 0x52, 0xB9, 0x6E, 0xE5, 0xEE, + 0x42 +}; + +static const unsigned char TA212_DN[] = { + 0x30, 0x81, 0xBF, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x33, 0x30, + 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x45, + 0x43, 0x31 +}; + +static const unsigned char TA212_EC_Q[] = { + 0x04, 0x84, 0x13, 0xC9, 0xD0, 0xBA, 0x6D, 0x41, 0x7B, 0xE2, 0x6C, 0xD0, + 0xEB, 0x55, 0x5F, 0x66, 0x02, 0x1A, 0x24, 0xF4, 0x5B, 0x89, 0x69, 0x47, + 0xE3, 0xB8, 0xC2, 0x7D, 0xF1, 0xF2, 0x02, 0xC5, 0x9F, 0xA0, 0xF6, 0x5B, + 0xD5, 0x8B, 0x06, 0x19, 0x86, 0x4F, 0x53, 0x10, 0x6D, 0x07, 0x24, 0x27, + 0xA1, 0xA0, 0xF8, 0xD5, 0x47, 0x19, 0x61, 0x4C, 0x7D, 0xCA, 0x93, 0x27, + 0xEA, 0x74, 0x0C, 0xEF, 0x6F, 0x96, 0x09, 0xFE, 0x63, 0xEC, 0x70, 0x5D, + 0x36, 0xAD, 0x67, 0x77, 0xAE, 0xC9, 0x9D, 0x7C, 0x55, 0x44, 0x3A, 0xA2, + 0x63, 0x51, 0x1F, 0xF5, 0xE3, 0x62, 0xD4, 0xA9, 0x47, 0x07, 0x3E, 0xCC, + 0x20 +}; + +static const unsigned char TA213_DN[] = { + 0x30, 0x81, 0x84, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x05, + 0x13, 0x09, 0x47, 0x36, 0x33, 0x32, 0x38, 0x37, 0x35, 0x31, 0x30, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, + 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1E, 0x41, + 0x4E, 0x46, 0x20, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, + 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x63, 0x69, 0x6F, 0x6E, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x13, 0x0B, 0x41, 0x4E, 0x46, 0x20, 0x43, 0x41, 0x20, 0x52, + 0x61, 0x69, 0x7A, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x19, 0x41, 0x4E, 0x46, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA213_RSA_N[] = { + 0xDB, 0xEB, 0x6B, 0x2B, 0xE6, 0x64, 0x54, 0x95, 0x82, 0x90, 0xA3, 0x72, + 0xA4, 0x19, 0x01, 0x9D, 0x9C, 0x0B, 0x81, 0x5F, 0x73, 0x49, 0xBA, 0xA7, + 0xAC, 0xF3, 0x04, 0x4E, 0x7B, 0x96, 0x0B, 0xEC, 0x11, 0xE0, 0x5B, 0xA6, + 0x1C, 0xCE, 0x1B, 0xD2, 0x0D, 0x83, 0x1C, 0x2B, 0xB8, 0x9E, 0x1D, 0x7E, + 0x45, 0x32, 0x60, 0x0F, 0x07, 0xE9, 0x77, 0x58, 0x7E, 0x9F, 0x6A, 0xC8, + 0x61, 0x4E, 0xB6, 0x26, 0xC1, 0x4C, 0x8D, 0xFF, 0x4C, 0xEF, 0x34, 0xB2, + 0x1F, 0x65, 0xD8, 0xB9, 0x78, 0xF5, 0xAD, 0xA9, 0x71, 0xB9, 0xEF, 0x4F, + 0x58, 0x1D, 0xA5, 0xDE, 0x74, 0x20, 0x97, 0xA1, 0xED, 0x68, 0x4C, 0xDE, + 0x92, 0x17, 0x4B, 0xBC, 0xAB, 0xFF, 0x65, 0x9A, 0x9E, 0xFB, 0x47, 0xD9, + 0x57, 0x72, 0xF3, 0x09, 0xA1, 0xAE, 0x76, 0x44, 0x13, 0x6E, 0x9C, 0x2D, + 0x44, 0x39, 0xBC, 0xF9, 0xC7, 0x3B, 0xA4, 0x58, 0x3D, 0x41, 0xBD, 0xB4, + 0xC2, 0x49, 0xA3, 0xC8, 0x0D, 0xD2, 0x97, 0x2F, 0x07, 0x65, 0x52, 0x00, + 0xA7, 0x6E, 0xC8, 0xAF, 0x68, 0xEC, 0xF4, 0x14, 0x96, 0xB6, 0x57, 0x1F, + 0x56, 0xC3, 0x39, 0x9F, 0x2B, 0x6D, 0xE4, 0xF3, 0x3E, 0xF6, 0x35, 0x64, + 0xDA, 0x0C, 0x1C, 0xA1, 0x84, 0x4B, 0x2F, 0x4B, 0x4B, 0xE2, 0x2C, 0x24, + 0x9D, 0x6D, 0x93, 0x40, 0xEB, 0xB5, 0x23, 0x8E, 0x32, 0xCA, 0x6F, 0x45, + 0xD3, 0xA8, 0x89, 0x7B, 0x1E, 0xCF, 0x1E, 0xFA, 0x5B, 0x43, 0x8B, 0xCD, + 0xCD, 0xA8, 0x0F, 0x6A, 0xCA, 0x0C, 0x5E, 0xB9, 0x9E, 0x47, 0x8F, 0xF0, + 0xD9, 0xB6, 0x0A, 0x0B, 0x58, 0x65, 0x17, 0x33, 0xB9, 0x23, 0xE4, 0x77, + 0x19, 0x7D, 0xCB, 0x4A, 0x2E, 0x92, 0x7B, 0x4F, 0x2F, 0x10, 0x77, 0xB1, + 0x8D, 0x2F, 0x68, 0x9C, 0x62, 0xCC, 0xE0, 0x50, 0xF8, 0xEC, 0x91, 0xA7, + 0x54, 0x4C, 0x57, 0x09, 0xD5, 0x76, 0x63, 0xC5, 0xE8, 0x65, 0x1E, 0xEE, + 0x6D, 0x6A, 0xCF, 0x09, 0x9D, 0xFA, 0x7C, 0x4F, 0xAD, 0x60, 0x08, 0xFD, + 0x56, 0x99, 0x0F, 0x15, 0x2C, 0x7B, 0xA9, 0x80, 0xAB, 0x8C, 0x61, 0x8F, + 0x4A, 0x07, 0x76, 0x42, 0xDE, 0x3D, 0xF4, 0xDD, 0xB2, 0x24, 0x33, 0x5B, + 0xB8, 0xB5, 0xA3, 0x44, 0xC9, 0xAC, 0x7F, 0x77, 0x3C, 0x1D, 0x23, 0xEC, + 0x82, 0xA9, 0xA6, 0xE2, 0xC8, 0x06, 0x4C, 0x02, 0xFE, 0xAC, 0x5C, 0x99, + 0x99, 0x0B, 0x2F, 0x10, 0x8A, 0xA6, 0xF4, 0x7F, 0xD5, 0x87, 0x74, 0x0D, + 0x59, 0x49, 0x45, 0xF6, 0xF0, 0x71, 0x5C, 0x39, 0x29, 0xD6, 0xBF, 0x4A, + 0x23, 0x8B, 0xF5, 0x5F, 0x01, 0x63, 0xD2, 0x87, 0x73, 0x28, 0xB5, 0x4B, + 0x0A, 0xF5, 0xF8, 0xAB, 0x82, 0x2C, 0x7E, 0x73, 0x25, 0x32, 0x1D, 0x0B, + 0x63, 0x0A, 0x17, 0x81, 0x00, 0xFF, 0xB6, 0x76, 0x5E, 0xE7, 0xB4, 0xB1, + 0x40, 0xCA, 0x21, 0xBB, 0xD5, 0x80, 0x51, 0xE5, 0x48, 0x52, 0x67, 0x2C, + 0xD2, 0x61, 0x89, 0x07, 0x0D, 0x0F, 0xCE, 0x42, 0x77, 0xC0, 0x44, 0x73, + 0x9C, 0x44, 0x50, 0xA0, 0xDB, 0x10, 0x0A, 0x2D, 0x95, 0x1C, 0x81, 0xAF, + 0xE4, 0x1C, 0xE5, 0x14, 0x1E, 0xF1, 0x36, 0x41, 0x01, 0x02, 0x2F, 0x7D, + 0x73, 0xA7, 0xDE, 0x42, 0xCC, 0x4C, 0xE9, 0x89, 0x0D, 0x56, 0xF7, 0x9F, + 0x91, 0xD4, 0x03, 0xC6, 0x6C, 0xC9, 0x8F, 0xDB, 0xD8, 0x1C, 0xE0, 0x40, + 0x98, 0x5D, 0x66, 0x99, 0x98, 0x80, 0x6E, 0x2D, 0xFF, 0x01, 0xC5, 0xCE, + 0xCB, 0x46, 0x1F, 0xAC, 0x02, 0xC6, 0x43, 0xE6, 0xAE, 0xA2, 0x84, 0x3C, + 0xC5, 0x4E, 0x1E, 0x3D, 0x6D, 0xC9, 0x14, 0x4C, 0xE3, 0x2E, 0x41, 0xBB, + 0xCA, 0x39, 0xBF, 0x36, 0x3C, 0x2A, 0x19, 0xAA, 0x41, 0x87, 0x4E, 0xA5, + 0xCE, 0x4B, 0x32, 0x79, 0xDD, 0x90, 0x49, 0x7F +}; + +static const unsigned char TA213_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA214_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA214_RSA_N[] = { + 0xAF, 0x35, 0x2E, 0xD8, 0xAC, 0x6C, 0x55, 0x69, 0x06, 0x71, 0xE5, 0x13, + 0x68, 0x24, 0xB3, 0x4F, 0xD8, 0xCC, 0x21, 0x47, 0xF8, 0xF1, 0x60, 0x38, + 0x89, 0x89, 0x03, 0xE9, 0xBD, 0xEA, 0x5E, 0x46, 0x53, 0x09, 0xDC, 0x5C, + 0xF5, 0x5A, 0xE8, 0xF7, 0x45, 0x2A, 0x02, 0xEB, 0x31, 0x61, 0xD7, 0x29, + 0x33, 0x4C, 0xCE, 0xC7, 0x7C, 0x0A, 0x37, 0x7E, 0x0F, 0xBA, 0x32, 0x98, + 0xE1, 0x1D, 0x97, 0xAF, 0x8F, 0xC7, 0xDC, 0xC9, 0x38, 0x96, 0xF3, 0xDB, + 0x1A, 0xFC, 0x51, 0xED, 0x68, 0xC6, 0xD0, 0x6E, 0xA4, 0x7C, 0x24, 0xD1, + 0xAE, 0x42, 0xC8, 0x96, 0x50, 0x63, 0x2E, 0xE0, 0xFE, 0x75, 0xFE, 0x98, + 0xA7, 0x5F, 0x49, 0x2E, 0x95, 0xE3, 0x39, 0x33, 0x64, 0x8E, 0x1E, 0xA4, + 0x5F, 0x90, 0xD2, 0x67, 0x3C, 0xB2, 0xD9, 0xFE, 0x41, 0xB9, 0x55, 0xA7, + 0x09, 0x8E, 0x72, 0x05, 0x1E, 0x8B, 0xDD, 0x44, 0x85, 0x82, 0x42, 0xD0, + 0x49, 0xC0, 0x1D, 0x60, 0xF0, 0xD1, 0x17, 0x2C, 0x95, 0xEB, 0xF6, 0xA5, + 0xC1, 0x92, 0xA3, 0xC5, 0xC2, 0xA7, 0x08, 0x60, 0x0D, 0x60, 0x04, 0x10, + 0x96, 0x79, 0x9E, 0x16, 0x34, 0xE6, 0xA9, 0xB6, 0xFA, 0x25, 0x45, 0x39, + 0xC8, 0x1E, 0x65, 0xF9, 0x93, 0xF5, 0xAA, 0xF1, 0x52, 0xDC, 0x99, 0x98, + 0x3D, 0xA5, 0x86, 0x1A, 0x0C, 0x35, 0x33, 0xFA, 0x4B, 0xA5, 0x04, 0x06, + 0x15, 0x1C, 0x31, 0x80, 0xEF, 0xAA, 0x18, 0x6B, 0xC2, 0x7B, 0xD7, 0xDA, + 0xCE, 0xF9, 0x33, 0x20, 0xD5, 0xF5, 0xBD, 0x6A, 0x33, 0x2D, 0x81, 0x04, + 0xFB, 0xB0, 0x5C, 0xD4, 0x9C, 0xA3, 0xE2, 0x5C, 0x1D, 0xE3, 0xA9, 0x42, + 0x75, 0x5E, 0x7B, 0xD4, 0x77, 0xEF, 0x39, 0x54, 0xBA, 0xC9, 0x0A, 0x18, + 0x1B, 0x12, 0x99, 0x49, 0x2F, 0x88, 0x4B, 0xFD, 0x50, 0x62, 0xD1, 0x73, + 0xE7, 0x8F, 0x7A, 0x43 +}; + +static const unsigned char TA214_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA215_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x13, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D +}; + +static const unsigned char TA215_RSA_N[] = { + 0xC4, 0x12, 0xDF, 0xA9, 0x5F, 0xFE, 0x41, 0xDD, 0xDD, 0xF5, 0x9F, 0x8A, + 0xE3, 0xF6, 0xAC, 0xE1, 0x3C, 0x78, 0x9A, 0xBC, 0xD8, 0xF0, 0x7F, 0x7A, + 0xA0, 0x33, 0x2A, 0xDC, 0x8D, 0x20, 0x5B, 0xAE, 0x2D, 0x6F, 0xE7, 0x93, + 0xD9, 0x36, 0x70, 0x6A, 0x68, 0xCF, 0x8E, 0x51, 0xA3, 0x85, 0x5B, 0x67, + 0x04, 0xA0, 0x10, 0x24, 0x6F, 0x5D, 0x28, 0x82, 0xC1, 0x97, 0x57, 0xD8, + 0x48, 0x29, 0x13, 0xB6, 0xE1, 0xBE, 0x91, 0x4D, 0xDF, 0x85, 0x0C, 0x53, + 0x18, 0x9A, 0x1E, 0x24, 0xA2, 0x4F, 0x8F, 0xF0, 0xA2, 0x85, 0x0B, 0xCB, + 0xF4, 0x29, 0x7F, 0xD2, 0xA4, 0x58, 0xEE, 0x26, 0x4D, 0xC9, 0xAA, 0xA8, + 0x7B, 0x9A, 0xD9, 0xFA, 0x38, 0xDE, 0x44, 0x57, 0x15, 0xE5, 0xF8, 0x8C, + 0xC8, 0xD9, 0x48, 0xE2, 0x0D, 0x16, 0x27, 0x1D, 0x1E, 0xC8, 0x83, 0x85, + 0x25, 0xB7, 0xBA, 0xAA, 0x55, 0x41, 0xCC, 0x03, 0x22, 0x4B, 0x2D, 0x91, + 0x8D, 0x8B, 0xE6, 0x89, 0xAF, 0x66, 0xC7, 0xE9, 0xFF, 0x2B, 0xE9, 0x3C, + 0xAC, 0xDA, 0xD2, 0xB3, 0xC3, 0xE1, 0x68, 0x9C, 0x89, 0xF8, 0x7A, 0x00, + 0x56, 0xDE, 0xF4, 0x55, 0x95, 0x6C, 0xFB, 0xBA, 0x64, 0xDD, 0x62, 0x8B, + 0xDF, 0x0B, 0x77, 0x32, 0xEB, 0x62, 0xCC, 0x26, 0x9A, 0x9B, 0xBB, 0xAA, + 0x62, 0x83, 0x4C, 0xB4, 0x06, 0x7A, 0x30, 0xC8, 0x29, 0xBF, 0xED, 0x06, + 0x4D, 0x97, 0xB9, 0x1C, 0xC4, 0x31, 0x2B, 0xD5, 0x5F, 0xBC, 0x53, 0x12, + 0x17, 0x9C, 0x99, 0x57, 0x29, 0x66, 0x77, 0x61, 0x21, 0x31, 0x07, 0x2E, + 0x25, 0x49, 0x9D, 0x18, 0xF2, 0xEE, 0xF3, 0x2B, 0x71, 0x8C, 0xB5, 0xBA, + 0x39, 0x07, 0x49, 0x77, 0xFC, 0xEF, 0x2E, 0x92, 0x90, 0x05, 0x8D, 0x2D, + 0x2F, 0x77, 0x7B, 0xEF, 0x43, 0xBF, 0x35, 0xBB, 0x9A, 0xD8, 0xF9, 0x73, + 0xA7, 0x2C, 0xF2, 0xD0, 0x57, 0xEE, 0x28, 0x4E, 0x26, 0x5F, 0x8F, 0x90, + 0x68, 0x09, 0x2F, 0xB8, 0xF8, 0xDC, 0x06, 0xE9, 0x2E, 0x9A, 0x3E, 0x51, + 0xA7, 0xD1, 0x22, 0xC4, 0x0A, 0xA7, 0x38, 0x48, 0x6C, 0xB3, 0xF9, 0xFF, + 0x7D, 0xAB, 0x86, 0x57, 0xE3, 0xBA, 0xD6, 0x85, 0x78, 0x77, 0xBA, 0x43, + 0xEA, 0x48, 0x7F, 0xF6, 0xD8, 0xBE, 0x23, 0x6D, 0x1E, 0xBF, 0xD1, 0x36, + 0x6C, 0x58, 0x5C, 0xF1, 0xEE, 0xA4, 0x19, 0x54, 0x1A, 0xF5, 0x03, 0xD2, + 0x76, 0xE6, 0xE1, 0x8C, 0xBD, 0x3C, 0xB3, 0xD3, 0x48, 0x4B, 0xE2, 0xC8, + 0xF8, 0x7F, 0x92, 0xA8, 0x76, 0x46, 0x9C, 0x42, 0x65, 0x3E, 0xA4, 0x1E, + 0xC1, 0x07, 0x03, 0x5A, 0x46, 0x2D, 0xB8, 0x97, 0xF3, 0xB7, 0xD5, 0xB2, + 0x55, 0x21, 0xEF, 0xBA, 0xDC, 0x4C, 0x00, 0x97, 0xFB, 0x14, 0x95, 0x27, + 0x33, 0xBF, 0xE8, 0x43, 0x47, 0x46, 0xD2, 0x08, 0x99, 0x16, 0x60, 0x3B, + 0x9A, 0x7E, 0xD2, 0xE6, 0xED, 0x38, 0xEA, 0xEC, 0x01, 0x1E, 0x3C, 0x48, + 0x56, 0x49, 0x09, 0xC7, 0x4C, 0x37, 0x00, 0x9E, 0x88, 0x0E, 0xC0, 0x73, + 0xE1, 0x6F, 0x66, 0xE9, 0x72, 0x47, 0x30, 0x3E, 0x10, 0xE5, 0x0B, 0x03, + 0xC9, 0x9A, 0x42, 0x00, 0x6C, 0xC5, 0x94, 0x7E, 0x61, 0xC4, 0x8A, 0xDF, + 0x7F, 0x82, 0x1A, 0x0B, 0x59, 0xC4, 0x59, 0x32, 0x77, 0xB3, 0xBC, 0x60, + 0x69, 0x56, 0x39, 0xFD, 0xB4, 0x06, 0x7B, 0x2C, 0xD6, 0x64, 0x36, 0xD9, + 0xBD, 0x48, 0xED, 0x84, 0x1F, 0x7E, 0xA5, 0x22, 0x8F, 0x2A, 0xB8, 0x42, + 0xF4, 0x82, 0xB7, 0xD4, 0x53, 0x90, 0x78, 0x4E, 0x2D, 0x1A, 0xFD, 0x81, + 0x6F, 0x44, 0xD7, 0x3B, 0x01, 0x74, 0x96, 0x42, 0xE0, 0x00, 0xE2, 0x2E, + 0x6B, 0xEA, 0xC5, 0xEE, 0x72, 0xAC, 0xBB, 0xBF, 0xFE, 0xEA, 0xAA, 0xA8, + 0xF8, 0xDC, 0xF6, 0xB2, 0x79, 0x8A, 0xB6, 0x67 +}; + +static const unsigned char TA215_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA216_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x17, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, + 0x33 +}; + +static const unsigned char TA216_EC_Q[] = { + 0x04, 0x23, 0xA5, 0x0C, 0xB8, 0x2D, 0x12, 0xF5, 0x28, 0xF3, 0xB1, 0xB2, + 0xDD, 0xE2, 0x02, 0x12, 0x80, 0x9E, 0x39, 0x5F, 0x49, 0x4D, 0x9F, 0xC9, + 0x25, 0x34, 0x59, 0x74, 0xEC, 0xBB, 0x06, 0x1C, 0xE7, 0xC0, 0x72, 0xAF, + 0xE8, 0xAE, 0x2F, 0xE1, 0x41, 0x54, 0x87, 0x14, 0xA8, 0x4A, 0xB2, 0xE8, + 0x7C, 0x82, 0xE6, 0x5B, 0x6A, 0xB5, 0xDC, 0xB3, 0x75, 0xCE, 0x8B, 0x06, + 0xD0, 0x86, 0x23, 0xBF, 0x46, 0xD5, 0x8E, 0x0F, 0x3F, 0x04, 0xF4, 0xD7, + 0x1C, 0x92, 0x7E, 0xF6, 0xA5, 0x63, 0xC2, 0xF5, 0x5F, 0x8E, 0x2E, 0x4F, + 0xA1, 0x18, 0x19, 0x02, 0x2B, 0x32, 0x0A, 0x82, 0x64, 0x7D, 0x16, 0x93, + 0xD1 +}; + +static const unsigned char TA217_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x21, 0x54, 0x57, 0x43, 0x41, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA217_RSA_N[] = { + 0xB0, 0x7E, 0x72, 0xB8, 0xA4, 0x03, 0x94, 0xE6, 0xA7, 0xDE, 0x09, 0x38, + 0x91, 0x4A, 0x11, 0x40, 0x87, 0xA7, 0x7C, 0x59, 0x64, 0x14, 0x7B, 0xB5, + 0x11, 0x10, 0xDD, 0xFE, 0xBF, 0xD5, 0xC0, 0xBB, 0x56, 0xE2, 0x85, 0x25, + 0xF4, 0x35, 0x72, 0x0F, 0xF8, 0x53, 0xD0, 0x41, 0xE1, 0x44, 0x01, 0xC2, + 0xB4, 0x1C, 0xC3, 0x31, 0x42, 0x16, 0x47, 0x85, 0x33, 0x22, 0x76, 0xB2, + 0x0A, 0x6F, 0x0F, 0xE5, 0x25, 0x50, 0x4F, 0x85, 0x86, 0xBE, 0xBF, 0x98, + 0x2E, 0x10, 0x67, 0x1E, 0xBE, 0x11, 0x05, 0x86, 0x05, 0x90, 0xC4, 0x59, + 0xD0, 0x7C, 0x78, 0x10, 0xB0, 0x80, 0x5C, 0xB7, 0xE1, 0xC7, 0x2B, 0x75, + 0xCB, 0x7C, 0x9F, 0xAE, 0xB5, 0xD1, 0x9D, 0x23, 0x37, 0x63, 0xA7, 0xDC, + 0x42, 0xA2, 0x2D, 0x92, 0x04, 0x1B, 0x50, 0xC1, 0x7B, 0xB8, 0x3E, 0x1B, + 0xC9, 0x56, 0x04, 0x8B, 0x2F, 0x52, 0x9B, 0xAD, 0xA9, 0x56, 0xE9, 0xC1, + 0xFF, 0xAD, 0xA9, 0x58, 0x87, 0x30, 0xB6, 0x81, 0xF7, 0x97, 0x45, 0xFC, + 0x19, 0x57, 0x3B, 0x2B, 0x6F, 0xE4, 0x47, 0xF4, 0x99, 0x45, 0xFE, 0x1D, + 0xF1, 0xF8, 0x97, 0xA3, 0x88, 0x1D, 0x37, 0x1C, 0x5C, 0x8F, 0xE0, 0x76, + 0x25, 0x9A, 0x50, 0xF8, 0xA0, 0x54, 0xFF, 0x44, 0x90, 0x76, 0x23, 0xD2, + 0x32, 0xC6, 0xC3, 0xAB, 0x06, 0xBF, 0xFC, 0xFB, 0xBF, 0xF3, 0xAD, 0x7D, + 0x92, 0x62, 0x02, 0x5B, 0x29, 0xD3, 0x35, 0xA3, 0x93, 0x9A, 0x43, 0x64, + 0x60, 0x5D, 0xB2, 0xFA, 0x32, 0xFF, 0x3B, 0x04, 0xAF, 0x4D, 0x40, 0x6A, + 0xF9, 0xC7, 0xE3, 0xEF, 0x23, 0xFD, 0x6B, 0xCB, 0xE5, 0x0F, 0x8B, 0x38, + 0x0D, 0xEE, 0x0A, 0xFC, 0xFE, 0x0F, 0x98, 0x9F, 0x30, 0x31, 0xDD, 0x6C, + 0x52, 0x65, 0xF9, 0x8B, 0x81, 0xBE, 0x22, 0xE1, 0x1C, 0x58, 0x03, 0xBA, + 0x91, 0x1B, 0x89, 0x07 +}; + +static const unsigned char TA217_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA218_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x21, 0x54, 0x57, 0x43, 0x41, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA218_RSA_N[] = { + 0xB0, 0x7E, 0x72, 0xB8, 0xA4, 0x03, 0x94, 0xE6, 0xA7, 0xDE, 0x09, 0x38, + 0x91, 0x4A, 0x11, 0x40, 0x87, 0xA7, 0x7C, 0x59, 0x64, 0x14, 0x7B, 0xB5, + 0x11, 0x10, 0xDD, 0xFE, 0xBF, 0xD5, 0xC0, 0xBB, 0x56, 0xE2, 0x85, 0x25, + 0xF4, 0x35, 0x72, 0x0F, 0xF8, 0x53, 0xD0, 0x41, 0xE1, 0x44, 0x01, 0xC2, + 0xB4, 0x1C, 0xC3, 0x31, 0x42, 0x16, 0x47, 0x85, 0x33, 0x22, 0x76, 0xB2, + 0x0A, 0x6F, 0x0F, 0xE5, 0x25, 0x50, 0x4F, 0x85, 0x86, 0xBE, 0xBF, 0x98, + 0x2E, 0x10, 0x67, 0x1E, 0xBE, 0x11, 0x05, 0x86, 0x05, 0x90, 0xC4, 0x59, + 0xD0, 0x7C, 0x78, 0x10, 0xB0, 0x80, 0x5C, 0xB7, 0xE1, 0xC7, 0x2B, 0x75, + 0xCB, 0x7C, 0x9F, 0xAE, 0xB5, 0xD1, 0x9D, 0x23, 0x37, 0x63, 0xA7, 0xDC, + 0x42, 0xA2, 0x2D, 0x92, 0x04, 0x1B, 0x50, 0xC1, 0x7B, 0xB8, 0x3E, 0x1B, + 0xC9, 0x56, 0x04, 0x8B, 0x2F, 0x52, 0x9B, 0xAD, 0xA9, 0x56, 0xE9, 0xC1, + 0xFF, 0xAD, 0xA9, 0x58, 0x87, 0x30, 0xB6, 0x81, 0xF7, 0x97, 0x45, 0xFC, + 0x19, 0x57, 0x3B, 0x2B, 0x6F, 0xE4, 0x47, 0xF4, 0x99, 0x45, 0xFE, 0x1D, + 0xF1, 0xF8, 0x97, 0xA3, 0x88, 0x1D, 0x37, 0x1C, 0x5C, 0x8F, 0xE0, 0x76, + 0x25, 0x9A, 0x50, 0xF8, 0xA0, 0x54, 0xFF, 0x44, 0x90, 0x76, 0x23, 0xD2, + 0x32, 0xC6, 0xC3, 0xAB, 0x06, 0xBF, 0xFC, 0xFB, 0xBF, 0xF3, 0xAD, 0x7D, + 0x92, 0x62, 0x02, 0x5B, 0x29, 0xD3, 0x35, 0xA3, 0x93, 0x9A, 0x43, 0x64, + 0x60, 0x5D, 0xB2, 0xFA, 0x32, 0xFF, 0x3B, 0x04, 0xAF, 0x4D, 0x40, 0x6A, + 0xF9, 0xC7, 0xE3, 0xEF, 0x23, 0xFD, 0x6B, 0xCB, 0xE5, 0x0F, 0x8B, 0x38, + 0x0D, 0xEE, 0x0A, 0xFC, 0xFE, 0x0F, 0x98, 0x9F, 0x30, 0x31, 0xDD, 0x6C, + 0x52, 0x65, 0xF9, 0x8B, 0x81, 0xBE, 0x22, 0xE1, 0x1C, 0x58, 0x03, 0xBA, + 0x91, 0x1B, 0x89, 0x07 +}; + +static const unsigned char TA218_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA219_DN[] = { + 0x30, 0x78, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x0E, + 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x05, 0x43, 0x65, 0x72, + 0x65, 0x73, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, + 0x0F, 0x56, 0x41, 0x54, 0x45, 0x53, 0x2D, 0x51, 0x32, 0x38, 0x32, 0x36, + 0x30, 0x30, 0x34, 0x4A, 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x23, 0x41, 0x43, 0x20, 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, + 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x20, 0x53, 0x45, 0x52, 0x56, + 0x49, 0x44, 0x4F, 0x52, 0x45, 0x53, 0x20, 0x53, 0x45, 0x47, 0x55, 0x52, + 0x4F, 0x53 +}; + +static const unsigned char TA219_EC_Q[] = { + 0x04, 0xF6, 0xBA, 0x57, 0x53, 0xC8, 0xCA, 0xAB, 0xDF, 0x36, 0x4A, 0x52, + 0x21, 0xE4, 0x97, 0xD2, 0x83, 0x67, 0x9E, 0xF0, 0x65, 0x51, 0xD0, 0x5E, + 0x87, 0xC7, 0x47, 0xB1, 0x59, 0xF2, 0x57, 0x47, 0x9B, 0x00, 0x02, 0x93, + 0x44, 0x17, 0x69, 0xDB, 0x42, 0xC7, 0xB1, 0xB2, 0x3A, 0x18, 0x0E, 0xB4, + 0x5D, 0x8C, 0xB3, 0x66, 0x5D, 0xA1, 0x34, 0xF9, 0x36, 0x2C, 0x49, 0xDB, + 0xF3, 0x46, 0xFC, 0xB3, 0x44, 0x69, 0x44, 0x13, 0x66, 0xFD, 0xD7, 0xC5, + 0xFD, 0xAF, 0x36, 0x4D, 0xCE, 0x03, 0x4D, 0x07, 0x71, 0xCF, 0xAF, 0x6A, + 0x05, 0xD2, 0xA2, 0x43, 0x5A, 0x0A, 0x52, 0x6F, 0x01, 0x03, 0x4E, 0x8E, + 0x8B +}; + +static const unsigned char TA220_DN[] = { + 0x30, 0x3C, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x15, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x0D, + 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x04, 0x41, 0x74, 0x6F, + 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x44, 0x45 +}; + +static const unsigned char TA220_RSA_N[] = { + 0x95, 0x85, 0x3B, 0x97, 0x6F, 0x2A, 0x3B, 0x2E, 0x3B, 0xCF, 0xA6, 0xF3, + 0x29, 0x35, 0xBE, 0xCF, 0x18, 0xAC, 0x3E, 0xAA, 0xD9, 0xF8, 0x4D, 0xA0, + 0x3E, 0x1A, 0x47, 0xB9, 0xBC, 0x9A, 0xDF, 0xF2, 0xFE, 0xCC, 0x3E, 0x47, + 0xE8, 0x7A, 0x96, 0xC2, 0x24, 0x8E, 0x35, 0xF4, 0xA9, 0x0C, 0xFC, 0x82, + 0xFD, 0x6D, 0xC1, 0x72, 0x62, 0x27, 0xBD, 0xEA, 0x6B, 0xEB, 0xE7, 0x8A, + 0xCC, 0x54, 0x3E, 0x90, 0x50, 0xCF, 0x80, 0xD4, 0x95, 0xFB, 0xE8, 0xB5, + 0x82, 0xD4, 0x14, 0xC5, 0xB6, 0xA9, 0x55, 0x25, 0x57, 0xDB, 0xB1, 0x50, + 0xF6, 0xB0, 0x60, 0x64, 0x59, 0x7A, 0x69, 0xCF, 0x03, 0xB7, 0x6F, 0x0D, + 0xBE, 0xCA, 0x3E, 0x6F, 0x74, 0x72, 0xEA, 0xAA, 0x30, 0x2A, 0x73, 0x62, + 0xBE, 0x49, 0x91, 0x61, 0xC8, 0x11, 0xFE, 0x0E, 0x03, 0x2A, 0xF7, 0x6A, + 0x20, 0xDC, 0x02, 0x15, 0x0D, 0x5E, 0x15, 0x6A, 0xFC, 0xE3, 0x82, 0xC1, + 0xB5, 0xC5, 0x9D, 0x64, 0x09, 0x6C, 0xA3, 0x59, 0x98, 0x07, 0x27, 0xC7, + 0x1B, 0x96, 0x2B, 0x61, 0x74, 0x71, 0x6C, 0x43, 0xF1, 0xF7, 0x35, 0x89, + 0x10, 0xE0, 0x9E, 0xEC, 0x55, 0xA1, 0x37, 0x22, 0xA2, 0x87, 0x04, 0x05, + 0x2C, 0x47, 0x7D, 0xB4, 0x1C, 0xB9, 0x62, 0x29, 0x66, 0x28, 0xCA, 0xB7, + 0xE1, 0x93, 0xF5, 0xA4, 0x94, 0x03, 0x99, 0xB9, 0x70, 0x85, 0xB5, 0xE6, + 0x48, 0xEA, 0x8D, 0x50, 0xFC, 0xD9, 0xDE, 0xCC, 0x6F, 0x07, 0x0E, 0xDD, + 0x0B, 0x72, 0x9D, 0x80, 0x30, 0x16, 0x07, 0x95, 0x3F, 0x28, 0x0E, 0xFD, + 0xC5, 0x75, 0x4F, 0x53, 0xD6, 0x74, 0x9A, 0xB4, 0x24, 0x2E, 0x8E, 0x02, + 0x91, 0xCF, 0x76, 0xC5, 0x9B, 0x1E, 0x55, 0x74, 0x9C, 0x78, 0x21, 0xB1, + 0xF0, 0x2D, 0xF1, 0x0B, 0x9F, 0xC2, 0xD5, 0x96, 0x18, 0x1F, 0xF0, 0x54, + 0x22, 0x7A, 0x8C, 0x07 +}; + +static const unsigned char TA220_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA221_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x54, 0x57, 0x43, 0x41, 0x20, 0x43, 0x59, 0x42, + 0x45, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA221_RSA_N[] = { + 0xC6, 0xF8, 0xCA, 0x1E, 0xD9, 0x09, 0x20, 0x7E, 0x1D, 0x6C, 0x4E, 0xCE, + 0x8F, 0xE3, 0x47, 0x33, 0x44, 0x9C, 0xC7, 0xC9, 0x69, 0xAA, 0x3A, 0x5B, + 0x78, 0xEE, 0x70, 0xD2, 0x92, 0xF8, 0x04, 0xB3, 0x52, 0x52, 0x1D, 0x67, + 0x72, 0x28, 0xA1, 0xDF, 0x8B, 0x5D, 0x95, 0x0A, 0xFE, 0xEA, 0xCD, 0xED, + 0xF7, 0x29, 0xCE, 0xF0, 0x6F, 0x7F, 0xAC, 0xCD, 0x3D, 0xEF, 0xB3, 0x1C, + 0x45, 0x6A, 0xF7, 0x28, 0x90, 0xF1, 0x61, 0x57, 0xC5, 0x0C, 0xC4, 0xA3, + 0x50, 0x5D, 0xDE, 0xD4, 0xB5, 0xCB, 0x19, 0xCA, 0x80, 0xB9, 0x75, 0xCE, + 0x29, 0xCE, 0xD2, 0x85, 0x22, 0xEC, 0x02, 0x63, 0xCC, 0x44, 0x30, 0x20, + 0xDA, 0xEA, 0x91, 0x5B, 0x56, 0xE6, 0x1D, 0x1C, 0xD5, 0x9D, 0x66, 0xC7, + 0x3F, 0xDF, 0x86, 0xCA, 0x4B, 0x53, 0xC4, 0xD9, 0x8D, 0xB2, 0x1D, 0xEA, + 0xF8, 0xDC, 0x27, 0x53, 0xA3, 0x47, 0xE1, 0x61, 0xCC, 0x7D, 0xB5, 0xB0, + 0xF8, 0xEE, 0x73, 0x91, 0xC5, 0xCE, 0x73, 0x6F, 0xCE, 0xEE, 0x10, 0x1F, + 0x1A, 0x06, 0xCF, 0xE9, 0x27, 0x60, 0xC5, 0x4F, 0x19, 0xE4, 0xEB, 0xCE, + 0x22, 0x26, 0x45, 0xD7, 0x60, 0x99, 0xDD, 0xCE, 0x4F, 0x37, 0xE0, 0x7F, + 0xE7, 0x63, 0xAD, 0xB0, 0xB8, 0x59, 0xB8, 0xD0, 0x06, 0x68, 0x35, 0x60, + 0xD3, 0x36, 0xAE, 0x71, 0x43, 0x04, 0xF1, 0x69, 0x65, 0x78, 0x7C, 0xF3, + 0x1F, 0xF3, 0xCA, 0x28, 0x9F, 0x5A, 0x20, 0x95, 0x66, 0xB4, 0xCD, 0xB7, + 0xEE, 0x8F, 0x78, 0xA4, 0x45, 0x18, 0xE9, 0x26, 0x2F, 0x8D, 0x9B, 0x29, + 0x28, 0xB1, 0xA4, 0xB7, 0x3A, 0x6D, 0xB9, 0xD4, 0x1C, 0x38, 0x72, 0x45, + 0x58, 0xB1, 0x5E, 0xEB, 0xF0, 0x28, 0x9B, 0xB7, 0x82, 0xCA, 0xFD, 0xCF, + 0xD6, 0x33, 0x0F, 0x9F, 0xFB, 0x97, 0x9E, 0xB1, 0x1C, 0x9C, 0x9E, 0xEA, + 0x5F, 0x5E, 0xDB, 0xAA, 0xDD, 0x54, 0xE9, 0x30, 0x21, 0x28, 0x6D, 0x8E, + 0x79, 0xF3, 0x75, 0x92, 0x8C, 0x26, 0xFE, 0xDC, 0xC5, 0xF6, 0xC3, 0xB0, + 0xDF, 0x44, 0x59, 0x43, 0xA3, 0xB6, 0x03, 0x28, 0xF6, 0x08, 0x30, 0xAA, + 0x0D, 0x33, 0xE1, 0xEF, 0x9C, 0xA9, 0x07, 0x22, 0xE3, 0x59, 0x5B, 0x40, + 0x8F, 0xDA, 0x88, 0xB7, 0x69, 0x08, 0xA8, 0xB7, 0x23, 0x2E, 0x44, 0x09, + 0x59, 0x37, 0x5B, 0xC7, 0xE3, 0x17, 0xF2, 0x22, 0xEB, 0x6E, 0x39, 0x52, + 0xC5, 0xDE, 0x54, 0xA7, 0x98, 0xC9, 0x4B, 0x20, 0x95, 0xDC, 0x46, 0x89, + 0x5F, 0xB4, 0x12, 0xF9, 0x85, 0x29, 0x8E, 0xEB, 0xC8, 0x27, 0x15, 0x20, + 0xC0, 0x4B, 0xD4, 0xCC, 0x7C, 0x0C, 0x6C, 0x34, 0x0C, 0x26, 0x9B, 0x26, + 0x31, 0xA6, 0x3C, 0xA7, 0xF6, 0xD9, 0xD0, 0x4B, 0xA2, 0x64, 0xFF, 0x3B, + 0x99, 0x41, 0x72, 0xC1, 0xE0, 0x70, 0x97, 0xF1, 0x24, 0xBB, 0x2B, 0xC4, + 0x74, 0x22, 0xB1, 0xAC, 0x6B, 0x22, 0x32, 0x24, 0xD3, 0x78, 0x2A, 0xC0, + 0xC0, 0xA1, 0x2F, 0xF1, 0x52, 0x05, 0xC9, 0x3F, 0xEF, 0x76, 0x66, 0xE2, + 0x45, 0xD8, 0x0D, 0x3D, 0xAD, 0x95, 0xC8, 0xC7, 0x89, 0x26, 0xC8, 0x0F, + 0xAE, 0xA7, 0x03, 0x2E, 0xFB, 0xC1, 0x5F, 0xFA, 0x20, 0xE1, 0x70, 0xAD, + 0xB0, 0x65, 0x20, 0x37, 0x33, 0x60, 0xB0, 0xD5, 0xAF, 0xD7, 0x0C, 0x1C, + 0xC2, 0x90, 0x70, 0xD7, 0x4A, 0x18, 0xBC, 0x7E, 0x01, 0xB0, 0xB0, 0xEB, + 0x15, 0x1E, 0x44, 0x06, 0xCD, 0xA4, 0x4F, 0xE8, 0x0C, 0xD1, 0xC3, 0x20, + 0x10, 0xE1, 0x54, 0x65, 0x9E, 0xB6, 0x51, 0xD0, 0x1A, 0x76, 0x6B, 0x42, + 0x5A, 0x58, 0x76, 0x34, 0xEA, 0xB7, 0x37, 0x19, 0xAE, 0x2E, 0x75, 0xF9, + 0x96, 0xE5, 0xC1, 0x59, 0xF7, 0x94, 0x57, 0x29, 0x25, 0x8D, 0x3A, 0x4C, + 0xAB, 0x4D, 0x9A, 0x41, 0xD0, 0x5F, 0x26, 0x03 +}; + +static const unsigned char TA221_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA222_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, + 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA222_RSA_N[] = { + 0x8B, 0xC2, 0xE7, 0xAF, 0x65, 0x9B, 0x05, 0x67, 0x96, 0xC9, 0x0D, 0x24, + 0xB9, 0xD0, 0x0E, 0x64, 0xFC, 0xCE, 0xE2, 0x24, 0x18, 0x2C, 0x84, 0x7F, + 0x77, 0x51, 0xCB, 0x04, 0x11, 0x36, 0xB8, 0x5E, 0xED, 0x69, 0x71, 0xA7, + 0x9E, 0xE4, 0x25, 0x09, 0x97, 0x67, 0xC1, 0x47, 0xC2, 0xCF, 0x91, 0x16, + 0x36, 0x62, 0x3D, 0x38, 0x04, 0xE1, 0x51, 0x82, 0xFF, 0xAC, 0xD2, 0xB4, + 0x69, 0xDD, 0x2E, 0xEC, 0x11, 0xA3, 0x45, 0xEE, 0x6B, 0x6B, 0x3B, 0x4C, + 0xBF, 0x8C, 0x8D, 0xA4, 0x1E, 0x9D, 0x11, 0xB9, 0xE9, 0x38, 0xF9, 0x7A, + 0x0E, 0x0C, 0x98, 0xE2, 0x23, 0x1D, 0xD1, 0x4E, 0x63, 0xD4, 0xE7, 0xB8, + 0x41, 0x44, 0xFB, 0x6B, 0xAF, 0x6B, 0xDA, 0x1F, 0xD3, 0xC5, 0x91, 0x88, + 0x5B, 0xA4, 0x89, 0x92, 0xD1, 0x81, 0xE6, 0x8C, 0x39, 0x58, 0xA0, 0xD6, + 0x69, 0x43, 0xA9, 0xAD, 0x98, 0x52, 0x58, 0x6E, 0xDB, 0x0A, 0xFB, 0x6B, + 0xCF, 0x68, 0xFA, 0xE3, 0xA4, 0x5E, 0x3A, 0x45, 0x73, 0x98, 0x07, 0xEA, + 0x5F, 0x02, 0x72, 0xDE, 0x0C, 0xA5, 0xB3, 0x9F, 0xAE, 0xA9, 0x1D, 0xB7, + 0x1D, 0xB3, 0xFC, 0x8A, 0x59, 0xE7, 0x6E, 0x72, 0x65, 0xAD, 0xF5, 0x30, + 0x94, 0x23, 0x07, 0xF3, 0x82, 0x16, 0x4B, 0x35, 0x98, 0x9C, 0x53, 0xBB, + 0x2F, 0xCA, 0xE4, 0x5A, 0xD9, 0xC7, 0x8D, 0x1D, 0xFC, 0x98, 0x99, 0xFB, + 0x2C, 0xA4, 0x82, 0x6B, 0xF0, 0x2A, 0x1F, 0x8E, 0x0B, 0x5F, 0x71, 0x5C, + 0x5C, 0xAE, 0x42, 0x7B, 0x29, 0x89, 0x81, 0xCB, 0x03, 0xA3, 0x99, 0xCA, + 0x88, 0x9E, 0x0B, 0x40, 0x09, 0x41, 0x33, 0xDB, 0xE6, 0x58, 0x7A, 0xFD, + 0xAE, 0x99, 0x70, 0xC0, 0x5A, 0x0F, 0xD6, 0x13, 0x86, 0x71, 0x2F, 0x76, + 0x69, 0xFC, 0x90, 0xDD, 0xDB, 0x2D, 0x6E, 0xD1, 0xF2, 0x9B, 0xF5, 0x1A, + 0x6B, 0x9E, 0x6F, 0x15, 0x8C, 0x7A, 0xF0, 0x4B, 0x28, 0xA0, 0x22, 0x38, + 0x80, 0x24, 0x6C, 0x36, 0xA4, 0x3B, 0xF2, 0x30, 0x91, 0xF3, 0x78, 0x13, + 0xCF, 0xC1, 0x3F, 0x35, 0xAB, 0xF1, 0x1D, 0x11, 0x23, 0xB5, 0x43, 0x22, + 0x9E, 0x01, 0x92, 0xB7, 0x18, 0x02, 0xE5, 0x11, 0xD1, 0x82, 0xDB, 0x15, + 0x00, 0xCC, 0x61, 0x37, 0xC1, 0x2A, 0x7C, 0x9A, 0xE1, 0xD0, 0xBA, 0xB3, + 0x50, 0x46, 0xEE, 0x82, 0xAC, 0x9D, 0x31, 0xF8, 0xFB, 0x23, 0xE2, 0x03, + 0x00, 0x48, 0x70, 0xA3, 0x09, 0x26, 0x79, 0x15, 0x53, 0x60, 0xF3, 0x38, + 0x5C, 0xAD, 0x38, 0xEA, 0x81, 0x00, 0x63, 0x14, 0xB9, 0x33, 0x5E, 0xDD, + 0x0B, 0xDB, 0xA0, 0x45, 0x07, 0x1A, 0x33, 0x09, 0xF8, 0x4D, 0xB4, 0xA7, + 0x02, 0xA6, 0x69, 0xF4, 0xC2, 0x59, 0x05, 0x88, 0x65, 0x85, 0x56, 0xAE, + 0x4B, 0xCB, 0xE0, 0xDE, 0x3C, 0x7D, 0x2D, 0x1A, 0xC8, 0xE9, 0xFB, 0x1F, + 0xA3, 0x61, 0x4A, 0xD6, 0x2A, 0x13, 0xAD, 0x77, 0x4C, 0x1A, 0x18, 0x9B, + 0x91, 0x0F, 0x58, 0xD8, 0x06, 0x54, 0xC5, 0x97, 0xF8, 0xAA, 0x3F, 0x20, + 0x8A, 0xA6, 0x85, 0xA6, 0x77, 0xF6, 0xA6, 0xFC, 0x1C, 0xE2, 0xEE, 0x6E, + 0x94, 0x33, 0x2A, 0x83, 0x50, 0x84, 0x0A, 0xE5, 0x4F, 0x86, 0xF8, 0x50, + 0x45, 0x78, 0x00, 0x81, 0xEB, 0x5B, 0x68, 0xE3, 0x26, 0x8D, 0xCC, 0x7B, + 0x5C, 0x51, 0xF4, 0x14, 0x2C, 0x40, 0xBE, 0x1A, 0x60, 0x1D, 0x7A, 0x72, + 0x61, 0x1D, 0x1F, 0x63, 0x2D, 0x88, 0xAA, 0xCE, 0xA2, 0x45, 0x90, 0x08, + 0xFC, 0x6B, 0xBE, 0xB3, 0x50, 0x2A, 0x5A, 0xFD, 0xA8, 0x48, 0x18, 0x46, + 0xD6, 0x90, 0x40, 0x92, 0x90, 0x0A, 0x84, 0x5E, 0x68, 0x31, 0xF8, 0xEB, + 0xED, 0x0D, 0xD3, 0x1D, 0xC6, 0x7D, 0x99, 0x18, 0x55, 0x56, 0x27, 0x65, + 0x2E, 0x8D, 0x45, 0xC5, 0x24, 0xEC, 0xCE, 0xE3 +}; + +static const unsigned char TA222_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA223_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x41, 0x43, 0x20, + 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, + 0x4D +}; + +static const unsigned char TA223_RSA_N[] = { + 0xBA, 0x71, 0x80, 0x7A, 0x4C, 0x86, 0x6E, 0x7F, 0xC8, 0x13, 0x6D, 0xC0, + 0xC6, 0x7D, 0x1C, 0x00, 0x97, 0x8F, 0x2C, 0x0C, 0x23, 0xBB, 0x10, 0x9A, + 0x40, 0xA9, 0x1A, 0xB7, 0x87, 0x88, 0xF8, 0x9B, 0x56, 0x6A, 0xFB, 0xE6, + 0x7B, 0x8E, 0x8B, 0x92, 0x8E, 0xA7, 0x25, 0x5D, 0x59, 0x11, 0xDB, 0x36, + 0x2E, 0xB7, 0x51, 0x17, 0x1F, 0xA9, 0x08, 0x1F, 0x04, 0x17, 0x24, 0x58, + 0xAA, 0x37, 0x4A, 0x18, 0xDF, 0xE5, 0x39, 0xD4, 0x57, 0xFD, 0xD7, 0xC1, + 0x2C, 0x91, 0x01, 0x91, 0xE2, 0x22, 0xD4, 0x03, 0xC0, 0x58, 0xFC, 0x77, + 0x47, 0xEC, 0x8F, 0x3E, 0x74, 0x43, 0xBA, 0xAC, 0x34, 0x8D, 0x4D, 0x38, + 0x76, 0x67, 0x8E, 0xB0, 0xC8, 0x6F, 0x30, 0x33, 0x58, 0x71, 0x5C, 0xB4, + 0xF5, 0x6B, 0x6E, 0xD4, 0x01, 0x50, 0xB8, 0x13, 0x7E, 0x6C, 0x4A, 0xA3, + 0x49, 0xD1, 0x20, 0x19, 0xEE, 0xBC, 0xC0, 0x29, 0x18, 0x65, 0xA7, 0xDE, + 0xFE, 0xEF, 0xDD, 0x0A, 0x90, 0x21, 0xE7, 0x1A, 0x67, 0x92, 0x42, 0x10, + 0x98, 0x5F, 0x4F, 0x30, 0xBC, 0x3E, 0x1C, 0x45, 0xB4, 0x10, 0xD7, 0x68, + 0x40, 0x14, 0xC0, 0x40, 0xFA, 0xE7, 0x77, 0x17, 0x7A, 0xE6, 0x0B, 0x8F, + 0x65, 0x5B, 0x3C, 0xD9, 0x9A, 0x52, 0xDB, 0xB5, 0xBD, 0x9E, 0x46, 0xCF, + 0x3D, 0xEB, 0x91, 0x05, 0x02, 0xC0, 0x96, 0xB2, 0x76, 0x4C, 0x4D, 0x10, + 0x96, 0x3B, 0x92, 0xFA, 0x9C, 0x7F, 0x0F, 0x99, 0xDF, 0xBE, 0x23, 0x35, + 0x45, 0x1E, 0x02, 0x5C, 0xFE, 0xB5, 0xA8, 0x9B, 0x99, 0x25, 0xDA, 0x5E, + 0xF3, 0x22, 0xC3, 0x39, 0xF5, 0xE4, 0x2A, 0x2E, 0xD3, 0xC6, 0x1F, 0xC4, + 0x6C, 0xAA, 0xC5, 0x1C, 0x6A, 0x01, 0x05, 0x4A, 0x2F, 0xD2, 0xC5, 0xC1, + 0xA8, 0x34, 0x26, 0x5D, 0x66, 0xA5, 0xD2, 0x02, 0x21, 0xF9, 0x18, 0xB7, + 0x06, 0xF5, 0x4E, 0x99, 0x6F, 0xA8, 0xAB, 0x4C, 0x51, 0xE8, 0xCF, 0x50, + 0x18, 0xC5, 0x77, 0xC8, 0x39, 0x09, 0x2C, 0x49, 0x92, 0x32, 0x99, 0xA8, + 0xBB, 0x17, 0x17, 0x79, 0xB0, 0x5A, 0xC5, 0xE6, 0xA3, 0xC4, 0x59, 0x65, + 0x47, 0x35, 0x83, 0x5E, 0xA9, 0xE8, 0x35, 0x0B, 0x99, 0xBB, 0xE4, 0xCD, + 0x20, 0xC6, 0x9B, 0x4A, 0x06, 0x39, 0xB5, 0x68, 0xFC, 0x22, 0xBA, 0xEE, + 0x55, 0x8C, 0x2B, 0x4E, 0xEA, 0xF3, 0xB1, 0xE3, 0xFC, 0xB6, 0x99, 0x9A, + 0xD5, 0x42, 0xFA, 0x71, 0x4D, 0x08, 0xCF, 0x87, 0x1E, 0x6A, 0x71, 0x7D, + 0xF9, 0xD3, 0xB4, 0xE9, 0xA5, 0x71, 0x81, 0x7B, 0xC2, 0x4E, 0x47, 0x96, + 0xA5, 0xF6, 0x76, 0x85, 0xA3, 0x28, 0x8F, 0xE9, 0x80, 0x6E, 0x81, 0x53, + 0xA5, 0x6D, 0x5F, 0xB8, 0x48, 0xF9, 0xC2, 0xF9, 0x36, 0xA6, 0x2E, 0x49, + 0xFF, 0xB8, 0x96, 0xC2, 0x8C, 0x07, 0xB3, 0x9B, 0x88, 0x58, 0xFC, 0xEB, + 0x1B, 0x1C, 0xDE, 0x2D, 0x70, 0xE2, 0x97, 0x92, 0x30, 0xA1, 0x89, 0xE3, + 0xBC, 0x55, 0xA8, 0x27, 0xD6, 0x4B, 0xED, 0x90, 0xAD, 0x8B, 0xFA, 0x63, + 0x25, 0x59, 0x2D, 0xA8, 0x35, 0xDD, 0xCA, 0x97, 0x33, 0xBC, 0xE5, 0xCD, + 0xC7, 0x9D, 0xD1, 0xEC, 0xEF, 0x5E, 0x0E, 0x4A, 0x90, 0x06, 0x26, 0x63, + 0xAD, 0xB9, 0xD9, 0x35, 0x2D, 0x07, 0xBA, 0x76, 0x65, 0x2C, 0xAC, 0x57, + 0x8F, 0x7D, 0xF4, 0x07, 0x94, 0xD7, 0x81, 0x02, 0x96, 0x5D, 0xA3, 0x07, + 0x49, 0xD5, 0x7A, 0xD0, 0x57, 0xF9, 0x1B, 0xE7, 0x53, 0x46, 0x75, 0xAA, + 0xB0, 0x79, 0x42, 0xCB, 0x68, 0x71, 0x08, 0xE9, 0x60, 0xBD, 0x39, 0x69, + 0xCE, 0xF4, 0xAF, 0xC3, 0x56, 0x40, 0xC7, 0xAD, 0x52, 0xA2, 0x09, 0xE4, + 0x6F, 0x86, 0x47, 0x8A, 0x1F, 0xEB, 0x28, 0x27, 0x5D, 0x83, 0x20, 0xAF, + 0x04, 0xC9, 0x6C, 0x56, 0x9A, 0x8B, 0x46, 0xF5 +}; + +static const unsigned char TA223_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA224_DN[] = { + 0x30, 0x6E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x13, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, 0x6F, 0x66, 0x65, + 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x53, 0x41, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0F, 0x56, 0x41, 0x54, 0x45, + 0x53, 0x2D, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x46, 0x49, + 0x52, 0x4D, 0x41, 0x50, 0x52, 0x4F, 0x46, 0x45, 0x53, 0x49, 0x4F, 0x4E, + 0x41, 0x4C, 0x20, 0x43, 0x41, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x2D, 0x41, + 0x20, 0x57, 0x45, 0x42 +}; + +static const unsigned char TA224_EC_Q[] = { + 0x04, 0x47, 0x53, 0xEA, 0x2C, 0x11, 0xA4, 0x77, 0xC7, 0x2A, 0xEA, 0xF3, + 0xD6, 0x5F, 0x7B, 0xD3, 0x04, 0x91, 0x5C, 0xFA, 0x88, 0xC6, 0x22, 0xB9, + 0x83, 0x10, 0x62, 0x77, 0x84, 0x33, 0x2D, 0xE9, 0x03, 0x88, 0xD4, 0xE0, + 0x33, 0xF7, 0xED, 0x77, 0x2C, 0x4A, 0x60, 0xEA, 0xE4, 0x6F, 0xAD, 0x6D, + 0xB4, 0xF8, 0x4C, 0x8A, 0xA4, 0xE4, 0x1F, 0xCA, 0xEA, 0x4F, 0x38, 0x4A, + 0x2E, 0x82, 0x73, 0x2B, 0xC7, 0x66, 0x9B, 0x0A, 0x8C, 0x40, 0x9C, 0x7C, + 0x8A, 0xF6, 0xF2, 0x39, 0x60, 0xB2, 0xDE, 0xCB, 0xEC, 0xB8, 0xE4, 0x6F, + 0xEA, 0x9B, 0x5D, 0xB7, 0x53, 0x90, 0x18, 0x32, 0x55, 0xC5, 0x20, 0xB7, + 0x94 +}; + +static const unsigned char TA225_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x42, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x6F, 0x72, 0x65, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, 0x43, 0x79, + 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6C, 0x74, 0x69, + 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA225_RSA_N[] = { + 0xA3, 0x04, 0xBB, 0x22, 0xAB, 0x98, 0x3D, 0x57, 0xE8, 0x26, 0x72, 0x9A, + 0xB5, 0x79, 0xD4, 0x29, 0xE2, 0xE1, 0xE8, 0x95, 0x80, 0xB1, 0xB0, 0xE3, + 0x5B, 0x8E, 0x2B, 0x29, 0x9A, 0x64, 0xDF, 0xA1, 0x5D, 0xED, 0xB0, 0x09, + 0x05, 0x6D, 0xDB, 0x28, 0x2E, 0xCE, 0x62, 0xA2, 0x62, 0xFE, 0xB4, 0x88, + 0xDA, 0x12, 0xEB, 0x38, 0xEB, 0x21, 0x9D, 0xC0, 0x41, 0x2B, 0x01, 0x52, + 0x7B, 0x88, 0x77, 0xD3, 0x1C, 0x8F, 0xC7, 0xBA, 0xB9, 0x88, 0xB5, 0x6A, + 0x09, 0xE7, 0x73, 0xE8, 0x11, 0x40, 0xA7, 0xD1, 0xCC, 0xCA, 0x62, 0x8D, + 0x2D, 0xE5, 0x8F, 0x0B, 0xA6, 0x50, 0xD2, 0xA8, 0x50, 0xC3, 0x28, 0xEA, + 0xF5, 0xAB, 0x25, 0x87, 0x8A, 0x9A, 0x96, 0x1C, 0xA9, 0x67, 0xB8, 0x3F, + 0x0C, 0xD5, 0xF7, 0xF9, 0x52, 0x13, 0x2F, 0xC2, 0x1B, 0xD5, 0x70, 0x70, + 0xF0, 0x8F, 0xC0, 0x12, 0xCA, 0x06, 0xCB, 0x9A, 0xE1, 0xD9, 0xCA, 0x33, + 0x7A, 0x77, 0xD6, 0xF8, 0xEC, 0xB9, 0xF1, 0x68, 0x44, 0x42, 0x48, 0x13, + 0xD2, 0xC0, 0xC2, 0xA4, 0xAE, 0x5E, 0x60, 0xFE, 0xB6, 0xA6, 0x05, 0xFC, + 0xB4, 0xDD, 0x07, 0x59, 0x02, 0xD4, 0x59, 0x18, 0x98, 0x63, 0xF5, 0xA5, + 0x63, 0xE0, 0x90, 0x0C, 0x7D, 0x5D, 0xB2, 0x06, 0x7A, 0xF3, 0x85, 0xEA, + 0xEB, 0xD4, 0x03, 0xAE, 0x5E, 0x84, 0x3E, 0x5F, 0xFF, 0x15, 0xED, 0x69, + 0xBC, 0xF9, 0x39, 0x36, 0x72, 0x75, 0xCF, 0x77, 0x52, 0x4D, 0xF3, 0xC9, + 0x90, 0x2C, 0xB9, 0x3D, 0xE5, 0xC9, 0x23, 0x53, 0x3F, 0x1F, 0x24, 0x98, + 0x21, 0x5C, 0x07, 0x99, 0x29, 0xBD, 0xC6, 0x3A, 0xEC, 0xE7, 0x6E, 0x86, + 0x3A, 0x6B, 0x97, 0x74, 0x63, 0x33, 0xBD, 0x68, 0x18, 0x31, 0xF0, 0x78, + 0x8D, 0x76, 0xBF, 0xFC, 0x9E, 0x8E, 0x5D, 0x2A, 0x86, 0xA7, 0x4D, 0x90, + 0xDC, 0x27, 0x1A, 0x39 +}; + +static const unsigned char TA225_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA226_DN[] = { + 0x30, 0x81, 0x83, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x1A, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, 0x47, 0x6F, 0x44, 0x61, 0x64, 0x64, + 0x79, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, + 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6F, + 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA226_RSA_N[] = { + 0xBF, 0x71, 0x62, 0x08, 0xF1, 0xFA, 0x59, 0x34, 0xF7, 0x1B, 0xC9, 0x18, + 0xA3, 0xF7, 0x80, 0x49, 0x58, 0xE9, 0x22, 0x83, 0x13, 0xA6, 0xC5, 0x20, + 0x43, 0x01, 0x3B, 0x84, 0xF1, 0xE6, 0x85, 0x49, 0x9F, 0x27, 0xEA, 0xF6, + 0x84, 0x1B, 0x4E, 0xA0, 0xB4, 0xDB, 0x70, 0x98, 0xC7, 0x32, 0x01, 0xB1, + 0x05, 0x3E, 0x07, 0x4E, 0xEE, 0xF4, 0xFA, 0x4F, 0x2F, 0x59, 0x30, 0x22, + 0xE7, 0xAB, 0x19, 0x56, 0x6B, 0xE2, 0x80, 0x07, 0xFC, 0xF3, 0x16, 0x75, + 0x80, 0x39, 0x51, 0x7B, 0xE5, 0xF9, 0x35, 0xB6, 0x74, 0x4E, 0xA9, 0x8D, + 0x82, 0x13, 0xE4, 0xB6, 0x3F, 0xA9, 0x03, 0x83, 0xFA, 0xA2, 0xBE, 0x8A, + 0x15, 0x6A, 0x7F, 0xDE, 0x0B, 0xC3, 0xB6, 0x19, 0x14, 0x05, 0xCA, 0xEA, + 0xC3, 0xA8, 0x04, 0x94, 0x3B, 0x46, 0x7C, 0x32, 0x0D, 0xF3, 0x00, 0x66, + 0x22, 0xC8, 0x8D, 0x69, 0x6D, 0x36, 0x8C, 0x11, 0x18, 0xB7, 0xD3, 0xB2, + 0x1C, 0x60, 0xB4, 0x38, 0xFA, 0x02, 0x8C, 0xCE, 0xD3, 0xDD, 0x46, 0x07, + 0xDE, 0x0A, 0x3E, 0xEB, 0x5D, 0x7C, 0xC8, 0x7C, 0xFB, 0xB0, 0x2B, 0x53, + 0xA4, 0x92, 0x62, 0x69, 0x51, 0x25, 0x05, 0x61, 0x1A, 0x44, 0x81, 0x8C, + 0x2C, 0xA9, 0x43, 0x96, 0x23, 0xDF, 0xAC, 0x3A, 0x81, 0x9A, 0x0E, 0x29, + 0xC5, 0x1C, 0xA9, 0xE9, 0x5D, 0x1E, 0xB6, 0x9E, 0x9E, 0x30, 0x0A, 0x39, + 0xCE, 0xF1, 0x88, 0x80, 0xFB, 0x4B, 0x5D, 0xCC, 0x32, 0xEC, 0x85, 0x62, + 0x43, 0x25, 0x34, 0x02, 0x56, 0x27, 0x01, 0x91, 0xB4, 0x3B, 0x70, 0x2A, + 0x3F, 0x6E, 0xB1, 0xE8, 0x9C, 0x88, 0x01, 0x7D, 0x9F, 0xD4, 0xF9, 0xDB, + 0x53, 0x6D, 0x60, 0x9D, 0xBF, 0x2C, 0xE7, 0x58, 0xAB, 0xB8, 0x5F, 0x46, + 0xFC, 0xCE, 0xC4, 0x1B, 0x03, 0x3C, 0x09, 0xEB, 0x49, 0x31, 0x5C, 0x69, + 0x46, 0xB3, 0xE0, 0x47 +}; + +static const unsigned char TA226_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA227_DN[] = { + 0x30, 0x6F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x4B, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x09, 0x48, 0x6F, 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x48, 0x6F, + 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA227_RSA_N[] = { + 0xB3, 0x88, 0xD7, 0xEA, 0xCE, 0x0F, 0x20, 0x4E, 0xBE, 0xE6, 0xD6, 0x03, + 0x6D, 0xEE, 0x59, 0xFC, 0xC2, 0x57, 0xDF, 0x29, 0x68, 0xA1, 0x83, 0x0E, + 0x3E, 0x68, 0xC7, 0x68, 0x58, 0x9C, 0x1C, 0x60, 0x4B, 0x89, 0x43, 0x0C, + 0xB9, 0xD4, 0x15, 0xB2, 0xEE, 0xC1, 0x4E, 0x75, 0xE9, 0xB5, 0xA7, 0xEF, + 0xE5, 0xE9, 0x35, 0x99, 0xE4, 0xCC, 0x1C, 0xE7, 0x4B, 0x5F, 0x8D, 0x33, + 0x30, 0x20, 0x33, 0x53, 0xD9, 0xA6, 0xBB, 0xD5, 0x3E, 0x13, 0x8E, 0xE9, + 0x1F, 0x87, 0x49, 0xAD, 0x50, 0x2D, 0x50, 0xCA, 0x18, 0xBE, 0x01, 0x58, + 0xA2, 0x13, 0x70, 0x96, 0xBB, 0x89, 0x88, 0x56, 0x80, 0x5C, 0xF8, 0xBD, + 0x2C, 0x3C, 0xE1, 0x4C, 0x57, 0x88, 0xBB, 0xD3, 0xB9, 0x95, 0xEF, 0xCB, + 0xC7, 0xF6, 0xDA, 0x31, 0x74, 0x28, 0xA6, 0xE6, 0x54, 0x89, 0xF5, 0x41, + 0x31, 0xCA, 0xE5, 0x26, 0x1A, 0xCD, 0x82, 0xE0, 0x70, 0xDA, 0x3B, 0x29, + 0xBB, 0xD5, 0x03, 0xF5, 0x99, 0xBA, 0x55, 0xF5, 0x64, 0xD1, 0x60, 0x0E, + 0xB3, 0x89, 0x49, 0xB8, 0x8A, 0x2F, 0x05, 0xD2, 0x84, 0x45, 0x28, 0x7C, + 0x8F, 0x68, 0x50, 0x12, 0x78, 0xFC, 0x0B, 0xB5, 0x53, 0xCB, 0xC2, 0x98, + 0x1C, 0x84, 0xA3, 0x9E, 0xB0, 0xBE, 0x23, 0xA4, 0xDA, 0xDC, 0xC8, 0x2B, + 0x1E, 0xDA, 0x6E, 0x45, 0x1E, 0x89, 0x98, 0xDA, 0xF9, 0x00, 0x2E, 0x06, + 0xE9, 0x0C, 0x3B, 0x70, 0xD5, 0x50, 0x25, 0x88, 0x99, 0xCB, 0xCD, 0x73, + 0x60, 0xF7, 0xD5, 0xFF, 0x35, 0x67, 0xC5, 0xA1, 0xBC, 0x5E, 0xAB, 0xCD, + 0x4A, 0xB8, 0x45, 0xEB, 0xC8, 0x68, 0x1E, 0x0D, 0x0D, 0x14, 0x46, 0x12, + 0xE3, 0xD2, 0x64, 0x62, 0x8A, 0x42, 0x98, 0xBC, 0xB4, 0xC6, 0x08, 0x08, + 0xF8, 0xFD, 0xA8, 0x4C, 0x64, 0x9C, 0x76, 0x01, 0xBD, 0x2F, 0xA9, 0x6C, + 0x33, 0x0F, 0xD8, 0x3F, 0x28, 0xB8, 0x3C, 0x69, 0x01, 0x42, 0x86, 0x7E, + 0x69, 0xC1, 0xC9, 0x06, 0xCA, 0xE5, 0x7A, 0x46, 0x65, 0xE9, 0xC2, 0xD6, + 0x50, 0x41, 0x2E, 0x3F, 0xB7, 0xE4, 0xED, 0x6C, 0xD7, 0xBF, 0x26, 0x01, + 0x11, 0xA2, 0x16, 0x29, 0x4A, 0x6B, 0x34, 0x06, 0x90, 0xEC, 0x13, 0xD2, + 0xB6, 0xFB, 0x6A, 0x76, 0xD2, 0x3C, 0xED, 0xF0, 0xD6, 0x2D, 0xDD, 0xE1, + 0x15, 0xEC, 0xA3, 0x9B, 0x2F, 0x2C, 0xC9, 0x3E, 0x2B, 0xE4, 0x69, 0x3B, + 0xFF, 0x72, 0x25, 0xB1, 0x36, 0x86, 0x5B, 0xC7, 0x7F, 0x6B, 0x8B, 0x55, + 0x1B, 0x4A, 0xC5, 0x20, 0x61, 0x3D, 0xAE, 0xCB, 0x50, 0xE1, 0x08, 0x3A, + 0xBE, 0xB0, 0x8F, 0x63, 0x41, 0x53, 0x30, 0x08, 0x59, 0x3C, 0x98, 0x1D, + 0x77, 0xBA, 0x63, 0x91, 0x7A, 0xCA, 0x10, 0x50, 0x60, 0xBF, 0xF0, 0xD7, + 0xBC, 0x95, 0x87, 0x8F, 0x97, 0xC5, 0xFE, 0x97, 0x6A, 0x01, 0x94, 0xA3, + 0x7C, 0x5B, 0x85, 0x1D, 0x2A, 0x39, 0x3A, 0xD0, 0x54, 0xA1, 0xD1, 0x39, + 0x71, 0x9D, 0xFD, 0x21, 0xF9, 0xB5, 0x7B, 0xF0, 0xE2, 0xE0, 0x02, 0x8F, + 0x6E, 0x96, 0x24, 0x25, 0x2C, 0xA0, 0x1E, 0x2C, 0xA8, 0xC4, 0x89, 0xA7, + 0xEF, 0xED, 0x99, 0x06, 0x2F, 0xB6, 0x0A, 0x4C, 0x4F, 0xDB, 0xA2, 0xCC, + 0x37, 0x1A, 0xAF, 0x47, 0x85, 0x2D, 0x8A, 0x5F, 0xC4, 0x34, 0x34, 0x4C, + 0x00, 0xFD, 0x18, 0x93, 0x67, 0x13, 0xD1, 0x37, 0xE6, 0x48, 0xB4, 0x8B, + 0x06, 0xC5, 0x57, 0x7B, 0x19, 0x86, 0x0A, 0x79, 0xCB, 0x00, 0xC9, 0x52, + 0xAF, 0x42, 0xFF, 0x37, 0x8F, 0xE1, 0xA3, 0x1E, 0x7A, 0x3D, 0x50, 0xAB, + 0x63, 0x06, 0xE7, 0x15, 0xB5, 0x3F, 0xB6, 0x45, 0x37, 0x94, 0x37, 0xB1, + 0x7E, 0xF2, 0x48, 0xC3, 0x7F, 0xC5, 0x75, 0xFE, 0x97, 0x8D, 0x45, 0x8F, + 0x1A, 0xA7, 0x1A, 0x72, 0x28, 0x1A, 0x40, 0x0F +}; + +static const unsigned char TA227_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA228_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA228_RSA_N[] = { + 0xAF, 0x35, 0x2E, 0xD8, 0xAC, 0x6C, 0x55, 0x69, 0x06, 0x71, 0xE5, 0x13, + 0x68, 0x24, 0xB3, 0x4F, 0xD8, 0xCC, 0x21, 0x47, 0xF8, 0xF1, 0x60, 0x38, + 0x89, 0x89, 0x03, 0xE9, 0xBD, 0xEA, 0x5E, 0x46, 0x53, 0x09, 0xDC, 0x5C, + 0xF5, 0x5A, 0xE8, 0xF7, 0x45, 0x2A, 0x02, 0xEB, 0x31, 0x61, 0xD7, 0x29, + 0x33, 0x4C, 0xCE, 0xC7, 0x7C, 0x0A, 0x37, 0x7E, 0x0F, 0xBA, 0x32, 0x98, + 0xE1, 0x1D, 0x97, 0xAF, 0x8F, 0xC7, 0xDC, 0xC9, 0x38, 0x96, 0xF3, 0xDB, + 0x1A, 0xFC, 0x51, 0xED, 0x68, 0xC6, 0xD0, 0x6E, 0xA4, 0x7C, 0x24, 0xD1, + 0xAE, 0x42, 0xC8, 0x96, 0x50, 0x63, 0x2E, 0xE0, 0xFE, 0x75, 0xFE, 0x98, + 0xA7, 0x5F, 0x49, 0x2E, 0x95, 0xE3, 0x39, 0x33, 0x64, 0x8E, 0x1E, 0xA4, + 0x5F, 0x90, 0xD2, 0x67, 0x3C, 0xB2, 0xD9, 0xFE, 0x41, 0xB9, 0x55, 0xA7, + 0x09, 0x8E, 0x72, 0x05, 0x1E, 0x8B, 0xDD, 0x44, 0x85, 0x82, 0x42, 0xD0, + 0x49, 0xC0, 0x1D, 0x60, 0xF0, 0xD1, 0x17, 0x2C, 0x95, 0xEB, 0xF6, 0xA5, + 0xC1, 0x92, 0xA3, 0xC5, 0xC2, 0xA7, 0x08, 0x60, 0x0D, 0x60, 0x04, 0x10, + 0x96, 0x79, 0x9E, 0x16, 0x34, 0xE6, 0xA9, 0xB6, 0xFA, 0x25, 0x45, 0x39, + 0xC8, 0x1E, 0x65, 0xF9, 0x93, 0xF5, 0xAA, 0xF1, 0x52, 0xDC, 0x99, 0x98, + 0x3D, 0xA5, 0x86, 0x1A, 0x0C, 0x35, 0x33, 0xFA, 0x4B, 0xA5, 0x04, 0x06, + 0x15, 0x1C, 0x31, 0x80, 0xEF, 0xAA, 0x18, 0x6B, 0xC2, 0x7B, 0xD7, 0xDA, + 0xCE, 0xF9, 0x33, 0x20, 0xD5, 0xF5, 0xBD, 0x6A, 0x33, 0x2D, 0x81, 0x04, + 0xFB, 0xB0, 0x5C, 0xD4, 0x9C, 0xA3, 0xE2, 0x5C, 0x1D, 0xE3, 0xA9, 0x42, + 0x75, 0x5E, 0x7B, 0xD4, 0x77, 0xEF, 0x39, 0x54, 0xBA, 0xC9, 0x0A, 0x18, + 0x1B, 0x12, 0x99, 0x49, 0x2F, 0x88, 0x4B, 0xFD, 0x50, 0x62, 0xD1, 0x73, + 0xE7, 0x8F, 0x7A, 0x43 +}; + +static const unsigned char TA228_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA229_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA229_RSA_N[] = { + 0xCA, 0x5B, 0xBE, 0x94, 0x33, 0x8C, 0x29, 0x95, 0x91, 0x16, 0x0A, 0x95, + 0xBD, 0x47, 0x62, 0xC1, 0x89, 0xF3, 0x99, 0x36, 0xDF, 0x46, 0x90, 0xC9, + 0xA5, 0xED, 0x78, 0x6A, 0x6F, 0x47, 0x91, 0x68, 0xF8, 0x27, 0x67, 0x50, + 0x33, 0x1D, 0xA1, 0xA6, 0xFB, 0xE0, 0xE5, 0x43, 0xA3, 0x84, 0x02, 0x57, + 0x01, 0x5D, 0x9C, 0x48, 0x40, 0x82, 0x53, 0x10, 0xBC, 0xBF, 0xC7, 0x3B, + 0x68, 0x90, 0xB6, 0x82, 0x2D, 0xE5, 0xF4, 0x65, 0xD0, 0xCC, 0x6D, 0x19, + 0xCC, 0x95, 0xF9, 0x7B, 0xAC, 0x4A, 0x94, 0xAD, 0x0E, 0xDE, 0x4B, 0x43, + 0x1D, 0x87, 0x07, 0x92, 0x13, 0x90, 0x80, 0x83, 0x64, 0x35, 0x39, 0x04, + 0xFC, 0xE5, 0xE9, 0x6C, 0xB3, 0xB6, 0x1F, 0x50, 0x94, 0x38, 0x65, 0x50, + 0x5C, 0x17, 0x46, 0xB9, 0xB6, 0x85, 0xB5, 0x1C, 0xB5, 0x17, 0xE8, 0xD6, + 0x45, 0x9D, 0xD8, 0xB2, 0x26, 0xB0, 0xCA, 0xC4, 0x70, 0x4A, 0xAE, 0x60, + 0xA4, 0xDD, 0xB3, 0xD9, 0xEC, 0xFC, 0x3B, 0xD5, 0x57, 0x72, 0xBC, 0x3F, + 0xC8, 0xC9, 0xB2, 0xDE, 0x4B, 0x6B, 0xF8, 0x23, 0x6C, 0x03, 0xC0, 0x05, + 0xBD, 0x95, 0xC7, 0xCD, 0x73, 0x3B, 0x66, 0x80, 0x64, 0xE3, 0x1A, 0xAC, + 0x2E, 0xF9, 0x47, 0x05, 0xF2, 0x06, 0xB6, 0x9B, 0x73, 0xF5, 0x78, 0x33, + 0x5B, 0xC7, 0xA1, 0xFB, 0x27, 0x2A, 0xA1, 0xB4, 0x9A, 0x91, 0x8C, 0x91, + 0xD3, 0x3A, 0x82, 0x3E, 0x76, 0x40, 0xB4, 0xCD, 0x52, 0x61, 0x51, 0x70, + 0x28, 0x3F, 0xC5, 0xC5, 0x5A, 0xF2, 0xC9, 0x8C, 0x49, 0xBB, 0x14, 0x5B, + 0x4D, 0xC8, 0xFF, 0x67, 0x4D, 0x4C, 0x12, 0x96, 0xAD, 0xF5, 0xFE, 0x78, + 0xA8, 0x97, 0x87, 0xD7, 0xFD, 0x5E, 0x20, 0x80, 0xDC, 0xA1, 0x4B, 0x22, + 0xFB, 0xD4, 0x89, 0xAD, 0xBA, 0xCE, 0x47, 0x97, 0x47, 0x55, 0x7B, 0x8F, + 0x45, 0xC8, 0x67, 0x28, 0x84, 0x95, 0x1C, 0x68, 0x30, 0xEF, 0xEF, 0x49, + 0xE0, 0x35, 0x7B, 0x64, 0xE7, 0x98, 0xB0, 0x94, 0xDA, 0x4D, 0x85, 0x3B, + 0x3E, 0x55, 0xC4, 0x28, 0xAF, 0x57, 0xF3, 0x9E, 0x13, 0xDB, 0x46, 0x27, + 0x9F, 0x1E, 0xA2, 0x5E, 0x44, 0x83, 0xA4, 0xA5, 0xCA, 0xD5, 0x13, 0xB3, + 0x4B, 0x3F, 0xC4, 0xE3, 0xC2, 0xE6, 0x86, 0x61, 0xA4, 0x52, 0x30, 0xB9, + 0x7A, 0x20, 0x4F, 0x6F, 0x0F, 0x38, 0x53, 0xCB, 0x33, 0x0C, 0x13, 0x2B, + 0x8F, 0xD6, 0x9A, 0xBD, 0x2A, 0xC8, 0x2D, 0xB1, 0x1C, 0x7D, 0x4B, 0x51, + 0xCA, 0x47, 0xD1, 0x48, 0x27, 0x72, 0x5D, 0x87, 0xEB, 0xD5, 0x45, 0xE6, + 0x48, 0x65, 0x9D, 0xAF, 0x52, 0x90, 0xBA, 0x5B, 0xA2, 0x18, 0x65, 0x57, + 0x12, 0x9F, 0x68, 0xB9, 0xD4, 0x15, 0x6B, 0x94, 0xC4, 0x69, 0x22, 0x98, + 0xF4, 0x33, 0xE0, 0xED, 0xF9, 0x51, 0x8E, 0x41, 0x50, 0xC9, 0x34, 0x4F, + 0x76, 0x90, 0xAC, 0xFC, 0x38, 0xC1, 0xD8, 0xE1, 0x7B, 0xB9, 0xE3, 0xE3, + 0x94, 0xE1, 0x46, 0x69, 0xCB, 0x0E, 0x0A, 0x50, 0x6B, 0x13, 0xBA, 0xAC, + 0x0F, 0x37, 0x5A, 0xB7, 0x12, 0xB5, 0x90, 0x81, 0x1E, 0x56, 0xAE, 0x57, + 0x22, 0x86, 0xD9, 0xC9, 0xD2, 0xD1, 0xD7, 0x51, 0xE3, 0xAB, 0x3B, 0xC6, + 0x55, 0xFD, 0x1E, 0x0E, 0xD3, 0x74, 0x0A, 0xD1, 0xDA, 0xAA, 0xEA, 0x69, + 0xB8, 0x97, 0x28, 0x8F, 0x48, 0xC4, 0x07, 0xF8, 0x52, 0x43, 0x3A, 0xF4, + 0xCA, 0x55, 0x35, 0x2C, 0xB0, 0xA6, 0x6A, 0xC0, 0x9C, 0xF9, 0xF2, 0x81, + 0xE1, 0x12, 0x6A, 0xC0, 0x45, 0xD9, 0x67, 0xB3, 0xCE, 0xFF, 0x23, 0xA2, + 0x89, 0x0A, 0x54, 0xD4, 0x14, 0xB9, 0x2A, 0xA8, 0xD7, 0xEC, 0xF9, 0xAB, + 0xCD, 0x25, 0x58, 0x32, 0x79, 0x8F, 0x90, 0x5B, 0x98, 0x39, 0xC4, 0x08, + 0x06, 0xC1, 0xAC, 0x7F, 0x0E, 0x3D, 0x00, 0xA5 +}; + +static const unsigned char TA229_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA230_DN[] = { + 0x30, 0x81, 0xB0, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x30, 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x20, 0x69, + 0x73, 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6E, 0x63, 0x65, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x16, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, + 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA230_RSA_N[] = { + 0xB6, 0x95, 0xB6, 0x43, 0x42, 0xFA, 0xC6, 0x6D, 0x2A, 0x6F, 0x48, 0xDF, + 0x94, 0x4C, 0x39, 0x57, 0x05, 0xEE, 0xC3, 0x79, 0x11, 0x41, 0x68, 0x36, + 0xED, 0xEC, 0xFE, 0x9A, 0x01, 0x8F, 0xA1, 0x38, 0x28, 0xFC, 0xF7, 0x10, + 0x46, 0x66, 0x2E, 0x4D, 0x1E, 0x1A, 0xB1, 0x1A, 0x4E, 0xC6, 0xD1, 0xC0, + 0x95, 0x88, 0xB0, 0xC9, 0xFF, 0x31, 0x8B, 0x33, 0x03, 0xDB, 0xB7, 0x83, + 0x7B, 0x3E, 0x20, 0x84, 0x5E, 0xED, 0xB2, 0x56, 0x28, 0xA7, 0xF8, 0xE0, + 0xB9, 0x40, 0x71, 0x37, 0xC5, 0xCB, 0x47, 0x0E, 0x97, 0x2A, 0x68, 0xC0, + 0x22, 0x95, 0x62, 0x15, 0xDB, 0x47, 0xD9, 0xF5, 0xD0, 0x2B, 0xFF, 0x82, + 0x4B, 0xC9, 0xAD, 0x3E, 0xDE, 0x4C, 0xDB, 0x90, 0x80, 0x50, 0x3F, 0x09, + 0x8A, 0x84, 0x00, 0xEC, 0x30, 0x0A, 0x3D, 0x18, 0xCD, 0xFB, 0xFD, 0x2A, + 0x59, 0x9A, 0x23, 0x95, 0x17, 0x2C, 0x45, 0x9E, 0x1F, 0x6E, 0x43, 0x79, + 0x6D, 0x0C, 0x5C, 0x98, 0xFE, 0x48, 0xA7, 0xC5, 0x23, 0x47, 0x5C, 0x5E, + 0xFD, 0x6E, 0xE7, 0x1E, 0xB4, 0xF6, 0x68, 0x45, 0xD1, 0x86, 0x83, 0x5B, + 0xA2, 0x8A, 0x8D, 0xB1, 0xE3, 0x29, 0x80, 0xFE, 0x25, 0x71, 0x88, 0xAD, + 0xBE, 0xBC, 0x8F, 0xAC, 0x52, 0x96, 0x4B, 0xAA, 0x51, 0x8D, 0xE4, 0x13, + 0x31, 0x19, 0xE8, 0x4E, 0x4D, 0x9F, 0xDB, 0xAC, 0xB3, 0x6A, 0xD5, 0xBC, + 0x39, 0x54, 0x71, 0xCA, 0x7A, 0x7A, 0x7F, 0x90, 0xDD, 0x7D, 0x1D, 0x80, + 0xD9, 0x81, 0xBB, 0x59, 0x26, 0xC2, 0x11, 0xFE, 0xE6, 0x93, 0xE2, 0xF7, + 0x80, 0xE4, 0x65, 0xFB, 0x34, 0x37, 0x0E, 0x29, 0x80, 0x70, 0x4D, 0xAF, + 0x38, 0x86, 0x2E, 0x9E, 0x7F, 0x57, 0xAF, 0x9E, 0x17, 0xAE, 0xEB, 0x1C, + 0xCB, 0x28, 0x21, 0x5F, 0xB6, 0x1C, 0xD8, 0xE7, 0xA2, 0x04, 0x22, 0xF9, + 0xD3, 0xDA, 0xD8, 0xCB +}; + +static const unsigned char TA230_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA231_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x31 +}; + +static const unsigned char TA231_RSA_N[] = { + 0xF1, 0x66, 0x08, 0xBD, 0xD9, 0xC5, 0x15, 0x61, 0xCB, 0x84, 0x04, 0x41, + 0xA5, 0x69, 0x37, 0x77, 0x1D, 0xC1, 0xB0, 0x7B, 0xFA, 0xC3, 0x77, 0x48, + 0x90, 0x13, 0x72, 0x64, 0xD1, 0xB8, 0x7C, 0x90, 0x35, 0x9D, 0x18, 0x79, + 0x88, 0xE3, 0x97, 0x01, 0x3C, 0x47, 0x81, 0xF2, 0x0E, 0xA2, 0x98, 0x0D, + 0x9E, 0x3F, 0x37, 0xE0, 0x19, 0xB2, 0x90, 0xF2, 0x46, 0x1C, 0x92, 0xB1, + 0x3A, 0x61, 0xCE, 0xFA, 0xB7, 0x46, 0x9E, 0x03, 0x86, 0xD7, 0x33, 0x6E, + 0xED, 0xF7, 0x45, 0x8C, 0x76, 0x37, 0xDE, 0x6E, 0x96, 0x91, 0xF7, 0xD7, + 0x7E, 0x2B, 0x87, 0x17, 0xD5, 0x8B, 0x35, 0xEE, 0x84, 0x91, 0x72, 0x57, + 0xDC, 0x60, 0xC3, 0xC3, 0xB9, 0xE7, 0xC7, 0x67, 0x24, 0x23, 0x4F, 0x63, + 0x0A, 0x63, 0xF6, 0x66, 0x7D, 0x4B, 0x55, 0xA7, 0x3F, 0x78, 0x64, 0x49, + 0x69, 0x12, 0x97, 0xE0, 0x4C, 0x0D, 0xD3, 0x09, 0xA0, 0x32, 0x30, 0x3A, + 0xFA, 0x9F, 0xC0, 0xF2, 0x9C, 0xC5, 0x12, 0x2A, 0x2E, 0x1C, 0xB5, 0x04, + 0x33, 0xDA, 0xA4, 0x38, 0x11, 0x6A, 0xDE, 0xC6, 0x18, 0xF6, 0x47, 0x3A, + 0x22, 0x41, 0x87, 0x22, 0xFC, 0xC4, 0x89, 0x28, 0x54, 0xD8, 0x8C, 0xA5, + 0x30, 0x0A, 0xF8, 0x17, 0x16, 0xCA, 0xAC, 0x37, 0xFD, 0x79, 0xA7, 0x91, + 0x17, 0x78, 0x38, 0x99, 0xAD, 0x58, 0xED, 0xB2, 0xDE, 0xCC, 0x89, 0x7D, + 0x03, 0x9C, 0xB3, 0x89, 0x65, 0xE7, 0xE3, 0x3B, 0xB1, 0x22, 0x86, 0x8F, + 0x06, 0x6D, 0x78, 0x07, 0xFD, 0x91, 0x12, 0x7F, 0xB0, 0x6B, 0x1C, 0x89, + 0x0D, 0xF9, 0xB8, 0xCB, 0x74, 0x5B, 0x07, 0xC2, 0xC8, 0xF4, 0x35, 0xD1, + 0x64, 0x63, 0x7A, 0xE9, 0x6E, 0x9A, 0x28, 0xD6, 0x30, 0xBD, 0xE6, 0x1B, + 0xDD, 0x15, 0xAF, 0x84, 0xEA, 0x9C, 0xC7, 0xCA, 0xF5, 0x0E, 0xEA, 0xF2, + 0x5D, 0x29, 0x87, 0x8F, 0x69, 0x73, 0x39, 0xBE, 0x2E, 0x24, 0x6F, 0x45, + 0x21, 0xAC, 0xC5, 0xD4, 0x69, 0x25, 0x06, 0x83, 0xAD, 0x7A, 0x48, 0x85, + 0x13, 0x2C, 0x0D, 0x06, 0xB8, 0x6C, 0x79, 0x56, 0xFC, 0xA3, 0x67, 0x32, + 0x81, 0xF5, 0x57, 0xA5, 0xCA, 0x57, 0x42, 0x69, 0xE9, 0x5C, 0x24, 0x61, + 0xEF, 0xE2, 0x30, 0x18, 0x4E, 0x44, 0x98, 0x55, 0x6F, 0x7A, 0xC2, 0x93, + 0xD8, 0x19, 0xB6, 0xDE, 0x7C, 0x47, 0x8A, 0x11, 0x4E, 0x49, 0x47, 0xDB, + 0x28, 0x94, 0x02, 0x0B, 0x94, 0x4A, 0x2C, 0xF9, 0x12, 0xD0, 0x4F, 0xE8, + 0x31, 0x7E, 0x6C, 0x7A, 0xBF, 0xA6, 0x3F, 0x9B, 0x39, 0x3D, 0x02, 0x16, + 0xA3, 0x18, 0xB3, 0x67, 0xAC, 0x5B, 0x3F, 0x2C, 0x83, 0x2B, 0x67, 0x39, + 0x81, 0x5C, 0xB9, 0x7E, 0x94, 0xD5, 0x64, 0xDD, 0x9E, 0x8F, 0x6E, 0xAE, + 0xE8, 0x7C, 0x5B, 0xB4, 0xD7, 0x6A, 0x47, 0x48, 0xD7, 0x7E, 0xB3, 0xD4, + 0x2D, 0x8E, 0x56, 0x76, 0x4E, 0xCF, 0x69, 0xF1, 0x6E, 0x44, 0x6C, 0xD4, + 0x24, 0xEA, 0x8D, 0x24, 0xA1, 0x18, 0xBF, 0xBD, 0x57, 0xFE, 0xA9, 0x99, + 0x35, 0xB5, 0xDB, 0x10, 0x77, 0xB8, 0x3D, 0x48, 0xBA, 0xD6, 0xC1, 0xE7, + 0xF1, 0x23, 0x3E, 0xD7, 0xDF, 0x85, 0x9D, 0x27, 0x3C, 0xD4, 0x40, 0xBD, + 0x0A, 0x0C, 0xBD, 0xF5, 0xE7, 0x8D, 0x25, 0xD6, 0x81, 0x74, 0x87, 0x46, + 0xD4, 0x29, 0x75, 0xA2, 0x42, 0x6C, 0xF7, 0x73, 0x89, 0xE7, 0x7D, 0xBF, + 0x7A, 0x4A, 0x1F, 0xD3, 0x22, 0xC9, 0x15, 0x55, 0xCF, 0xDF, 0x6F, 0x7C, + 0x55, 0xD0, 0xA4, 0x8B, 0x07, 0x11, 0x37, 0x5F, 0x83, 0xA6, 0x26, 0x57, + 0xA6, 0x01, 0x5B, 0x7E, 0xFE, 0x58, 0x68, 0x07, 0xA9, 0xE9, 0x7A, 0xD9, + 0xB9, 0xE8, 0xFF, 0x50, 0x1F, 0xAB, 0xC2, 0xB4, 0xC0, 0xCE, 0xE8, 0xEA, + 0xFD, 0x0F, 0xBD, 0x8D, 0x4D, 0xB8, 0xBC, 0x71 +}; + +static const unsigned char TA231_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA232_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x32 +}; + +static const unsigned char TA232_EC_Q[] = { + 0x04, 0x9D, 0xCB, 0x80, 0x91, 0x8D, 0x53, 0x67, 0xB5, 0xB9, 0x50, 0xB1, + 0x03, 0xF8, 0xE5, 0x49, 0x1F, 0x41, 0x22, 0x09, 0xB0, 0x51, 0x52, 0x58, + 0xD6, 0x2B, 0x34, 0x8F, 0xC5, 0x12, 0x46, 0x14, 0xC5, 0x8B, 0x2F, 0x2C, + 0x84, 0xFF, 0x2C, 0x6E, 0xA8, 0xD5, 0xF1, 0x09, 0xE3, 0x03, 0x21, 0x14, + 0xC4, 0x43, 0x3D, 0x7C, 0xC1, 0x2C, 0xC4, 0x4B, 0x6A, 0x4A, 0xCD, 0xE9, + 0x87, 0xE0, 0x7D, 0xF6, 0x22, 0xBE, 0xFA, 0x4A, 0x51, 0xB8, 0x30, 0x8A, + 0xFD, 0xE1, 0xDE, 0x18, 0x12, 0x0A, 0xF6, 0x47, 0xB7, 0xE7, 0x17, 0xBF, + 0x27, 0x8A, 0xD4, 0x41, 0x4C, 0x96, 0x3C, 0x60, 0x96, 0xC1, 0xFD, 0x15, + 0x1C +}; + +static const unsigned char TA233_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA233_RSA_N[] = { + 0xD7, 0xC7, 0x5E, 0xF7, 0xC1, 0x07, 0xD4, 0x77, 0xFB, 0x43, 0x21, 0xF4, + 0xF4, 0xF5, 0x69, 0xE4, 0xEE, 0x32, 0x01, 0xDB, 0xA3, 0x86, 0x1F, 0xE4, + 0x59, 0x0D, 0xBA, 0xE7, 0x75, 0x83, 0x52, 0xEB, 0xEA, 0x1C, 0x61, 0x15, + 0x48, 0xBB, 0x1D, 0x07, 0xCA, 0x8C, 0xAE, 0xB0, 0xDC, 0x96, 0x9D, 0xEA, + 0xC3, 0x60, 0x92, 0x86, 0x82, 0x28, 0x73, 0x9C, 0x56, 0x06, 0xFF, 0x4B, + 0x64, 0xF0, 0x0C, 0x2A, 0x37, 0x49, 0xB5, 0xE5, 0xCF, 0x0C, 0x7C, 0xEE, + 0xF1, 0x4A, 0xBB, 0x73, 0x30, 0x65, 0xF3, 0xD5, 0x2F, 0x83, 0xB6, 0x7E, + 0xE3, 0xE7, 0xF5, 0x9E, 0xAB, 0x60, 0xF9, 0xD3, 0xF1, 0x9D, 0x92, 0x74, + 0x8A, 0xE4, 0x1C, 0x96, 0xAC, 0x5B, 0x80, 0xE9, 0xB5, 0xF4, 0x31, 0x87, + 0xA3, 0x51, 0xFC, 0xC7, 0x7E, 0xA1, 0x6F, 0x8E, 0x53, 0x77, 0xD4, 0x97, + 0xC1, 0x55, 0x33, 0x92, 0x3E, 0x18, 0x2F, 0x75, 0xD4, 0xAD, 0x86, 0x49, + 0xCB, 0x95, 0xAF, 0x54, 0x06, 0x6C, 0xD8, 0x06, 0x13, 0x8D, 0x5B, 0xFF, + 0xE1, 0x26, 0x19, 0x59, 0xC0, 0x24, 0xBA, 0x81, 0x71, 0x79, 0x90, 0x44, + 0x50, 0x68, 0x24, 0x94, 0x5F, 0xB8, 0xB3, 0x11, 0xF1, 0x29, 0x41, 0x61, + 0xA3, 0x41, 0xCB, 0x23, 0x36, 0xD5, 0xC1, 0xF1, 0x32, 0x50, 0x10, 0x4E, + 0x7F, 0xF4, 0x86, 0x93, 0xEC, 0x84, 0xD3, 0x8E, 0xBC, 0x4B, 0xBF, 0x5C, + 0x01, 0x4E, 0x07, 0x3D, 0xDC, 0x14, 0x8A, 0x94, 0x0A, 0xA4, 0xEA, 0x73, + 0xFB, 0x0B, 0x51, 0xE8, 0x13, 0x07, 0x18, 0xFA, 0x0E, 0xF1, 0x2B, 0xD1, + 0x54, 0x15, 0x7D, 0x3C, 0xE1, 0xF7, 0xB4, 0x19, 0x42, 0x67, 0x62, 0x5E, + 0x77, 0xE0, 0xA2, 0x55, 0xEC, 0xB6, 0xD9, 0x69, 0x17, 0xD5, 0x3A, 0xAF, + 0x44, 0xED, 0x4A, 0xC5, 0x9E, 0xE4, 0x7A, 0x27, 0x7C, 0xE5, 0x75, 0xD7, + 0xAA, 0xCB, 0x25, 0xE7, 0xDF, 0x6B, 0x0A, 0xDB, 0x0F, 0x4D, 0x93, 0x4E, + 0xA8, 0xA0, 0xCD, 0x7B, 0x2E, 0xF2, 0x59, 0x01, 0x6A, 0xB7, 0x0D, 0xB8, + 0x07, 0x81, 0x7E, 0x8B, 0x38, 0x1B, 0x38, 0xE6, 0x0A, 0x57, 0x99, 0x3D, + 0xEE, 0x21, 0xE8, 0xA3, 0xF5, 0x0C, 0x16, 0xDD, 0x8B, 0xEC, 0x34, 0x8E, + 0x9C, 0x2A, 0x1C, 0x00, 0x15, 0x17, 0x8D, 0x68, 0x83, 0xD2, 0x70, 0x9F, + 0x18, 0x08, 0xCD, 0x11, 0x68, 0xD5, 0xC9, 0x6B, 0x52, 0xCD, 0xC4, 0x46, + 0x8F, 0xDC, 0xB5, 0xF3, 0xD8, 0x57, 0x73, 0x1E, 0xE9, 0x94, 0x39, 0x04, + 0xBF, 0xD3, 0xDE, 0x38, 0xDE, 0xB4, 0x53, 0xEC, 0x69, 0x1C, 0xA2, 0x7E, + 0xC4, 0x8F, 0xE4, 0x1B, 0x70, 0xAD, 0xF2, 0xA2, 0xF9, 0xFB, 0xF7, 0x16, + 0x64, 0x66, 0x69, 0x9F, 0x49, 0x51, 0xA2, 0xE2, 0x15, 0x18, 0x67, 0x06, + 0x4A, 0x7F, 0xD5, 0x6C, 0xB5, 0x4D, 0xB3, 0x33, 0xE0, 0x61, 0xEB, 0x5D, + 0xBE, 0xE9, 0x98, 0x0F, 0x32, 0xD7, 0x1D, 0x4B, 0x3C, 0x2E, 0x5A, 0x01, + 0x52, 0x91, 0x09, 0xF2, 0xDF, 0xEA, 0x8D, 0xD8, 0x06, 0x40, 0x63, 0xAA, + 0x11, 0xE4, 0xFE, 0xC3, 0x37, 0x9E, 0x14, 0x52, 0x3F, 0xF4, 0xE2, 0xCC, + 0xF2, 0x61, 0x93, 0xD1, 0xFD, 0x67, 0x6B, 0xD7, 0x52, 0xAE, 0xBF, 0x68, + 0xAB, 0x40, 0x43, 0xA0, 0x57, 0x35, 0x53, 0x78, 0xF0, 0x53, 0xF8, 0x61, + 0x42, 0x07, 0x64, 0xC6, 0xD7, 0x6F, 0x9B, 0x4C, 0x38, 0x0D, 0x63, 0xAC, + 0x62, 0xAF, 0x36, 0x8B, 0xA2, 0x73, 0x0A, 0x0D, 0xF5, 0x21, 0xBD, 0x74, + 0xAA, 0x4D, 0xEA, 0x72, 0x03, 0x49, 0xDB, 0xC7, 0x5F, 0x1D, 0x62, 0x63, + 0xC7, 0xFD, 0xDD, 0x91, 0xEC, 0x33, 0xEE, 0xF5, 0x6D, 0xB4, 0x6E, 0x30, + 0x68, 0xDE, 0xC8, 0xD6, 0x26, 0xB0, 0x75, 0x5E, 0x7B, 0xB4, 0x07, 0x20, + 0x98, 0xA1, 0x76, 0x32, 0xB8, 0x4D, 0x6C, 0x4F +}; + +static const unsigned char TA233_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA234_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA234_RSA_N[] = { + 0xA5, 0xDA, 0x0A, 0x95, 0x16, 0x50, 0xE3, 0x95, 0xF2, 0x5E, 0x9D, 0x76, + 0x31, 0x06, 0x32, 0x7A, 0x9B, 0xF1, 0x10, 0x76, 0xB8, 0x00, 0x9A, 0xB5, + 0x52, 0x36, 0xCD, 0x24, 0x47, 0xB0, 0x9F, 0x18, 0x64, 0xBC, 0x9A, 0xF6, + 0xFA, 0xD5, 0x79, 0xD8, 0x90, 0x62, 0x4C, 0x22, 0x2F, 0xDE, 0x38, 0x3D, + 0xD6, 0xE0, 0xA8, 0xE9, 0x1C, 0x2C, 0xDB, 0x78, 0x11, 0xE9, 0x8E, 0x68, + 0x51, 0x15, 0x72, 0xC7, 0xF3, 0x33, 0x87, 0xE4, 0xA0, 0x5D, 0x0B, 0x5C, + 0xE0, 0x57, 0x07, 0x2A, 0x30, 0xF5, 0xCD, 0xC4, 0x37, 0x77, 0x28, 0x4D, + 0x18, 0x91, 0xE6, 0xBF, 0xD5, 0x52, 0xFD, 0x71, 0x2D, 0x70, 0x3E, 0xE7, + 0xC6, 0xC4, 0x8A, 0xE3, 0xF0, 0x28, 0x0B, 0xF4, 0x76, 0x98, 0xA1, 0x8B, + 0x87, 0x55, 0xB2, 0x3A, 0x13, 0xFC, 0xB7, 0x3E, 0x27, 0x37, 0x8E, 0x22, + 0xE3, 0xA8, 0x4F, 0x2A, 0xEF, 0x60, 0xBB, 0x3D, 0xB7, 0x39, 0xC3, 0x0E, + 0x01, 0x47, 0x99, 0x5D, 0x12, 0x4F, 0xDB, 0x43, 0xFA, 0x57, 0xA1, 0xED, + 0xF9, 0x9D, 0xBE, 0x11, 0x47, 0x26, 0x5B, 0x13, 0x98, 0xAB, 0x5D, 0x16, + 0x8A, 0xB0, 0x37, 0x1C, 0x57, 0x9D, 0x45, 0xFF, 0x88, 0x96, 0x36, 0xBF, + 0xBB, 0xCA, 0x07, 0x7B, 0x6F, 0x87, 0x63, 0xD7, 0xD0, 0x32, 0x6A, 0xD6, + 0x5D, 0x6C, 0x0C, 0xF1, 0xB3, 0x6E, 0x39, 0xE2, 0x6B, 0x31, 0x2E, 0x39, + 0x00, 0x27, 0x14, 0xDE, 0x38, 0xC0, 0xEC, 0x19, 0x66, 0x86, 0x12, 0xE8, + 0x9D, 0x72, 0x16, 0x13, 0x64, 0x52, 0xC7, 0xA9, 0x37, 0x1C, 0xFD, 0x82, + 0x30, 0xED, 0x84, 0x18, 0x1D, 0xF4, 0xAE, 0x5C, 0xFF, 0x70, 0x13, 0x00, + 0xEB, 0xB1, 0xF5, 0x33, 0x7A, 0x4B, 0xD6, 0x55, 0xF8, 0x05, 0x8D, 0x4B, + 0x69, 0xB0, 0xF5, 0xB3, 0x28, 0x36, 0x5C, 0x14, 0xC4, 0x51, 0x73, 0x4D, + 0x6B, 0x0B, 0xF1, 0x34, 0x07, 0xDB, 0x17, 0x39, 0xD7, 0xDC, 0x28, 0x7B, + 0x6B, 0xF5, 0x9F, 0xF3, 0x2E, 0xC1, 0x4F, 0x17, 0x2A, 0x10, 0xF3, 0xCC, + 0xCA, 0xE8, 0xEB, 0xFD, 0x6B, 0xAB, 0x2E, 0x9A, 0x9F, 0x2D, 0x82, 0x6E, + 0x04, 0xD4, 0x52, 0x01, 0x93, 0x2D, 0x3D, 0x86, 0xFC, 0x7E, 0xFC, 0xDF, + 0xEF, 0x42, 0x1D, 0xA6, 0x6B, 0xEF, 0xB9, 0x20, 0xC6, 0xF7, 0xBD, 0xA0, + 0xA7, 0x95, 0xFD, 0xA7, 0xE6, 0x89, 0x24, 0xD8, 0xCC, 0x8C, 0x34, 0x6C, + 0xE2, 0x23, 0x2F, 0xD9, 0x12, 0x1A, 0x21, 0xB9, 0x55, 0x91, 0x6F, 0x0B, + 0x91, 0x79, 0x19, 0x0C, 0xAD, 0x40, 0x88, 0x0B, 0x70, 0xE2, 0x7A, 0xD2, + 0x0E, 0xD8, 0x68, 0x48, 0xBB, 0x82, 0x13, 0x39, 0x10, 0x58, 0xE9, 0xD8, + 0x2A, 0x07, 0xC6, 0x12, 0xDB, 0x58, 0xDB, 0xD2, 0x3B, 0x55, 0x10, 0x47, + 0x05, 0x15, 0x67, 0x62, 0x7E, 0x18, 0x63, 0xA6, 0x46, 0x3F, 0x09, 0x0E, + 0x54, 0x32, 0x5E, 0xBF, 0x0D, 0x62, 0x7A, 0x27, 0xEF, 0x80, 0xE8, 0xDB, + 0xD9, 0x4B, 0x06, 0x5A, 0x37, 0x5A, 0x25, 0xD0, 0x08, 0x12, 0x77, 0xD4, + 0x6F, 0x09, 0x50, 0x97, 0x3D, 0xC8, 0x1D, 0xC3, 0xDF, 0x8C, 0x45, 0x30, + 0x56, 0xC6, 0xD3, 0x64, 0xAB, 0x66, 0xF3, 0xC0, 0x5E, 0x96, 0x9C, 0xC3, + 0xC4, 0xEF, 0xC3, 0x7C, 0x6B, 0x8B, 0x3A, 0x79, 0x7F, 0xB3, 0x49, 0xCF, + 0x3D, 0xE2, 0x89, 0x9F, 0xA0, 0x30, 0x4B, 0x85, 0xB9, 0x9C, 0x94, 0x24, + 0x79, 0x8F, 0x7D, 0x6B, 0xA9, 0x45, 0x68, 0x0F, 0x2B, 0xD0, 0xF1, 0xDA, + 0x1C, 0xCB, 0x69, 0xB8, 0xCA, 0x49, 0x62, 0x6D, 0xC8, 0xD0, 0x63, 0x62, + 0xDD, 0x60, 0x0F, 0x58, 0xAA, 0x8F, 0xA1, 0xBC, 0x05, 0xA5, 0x66, 0xA2, + 0xCF, 0x1B, 0x76, 0xB2, 0x84, 0x64, 0xB1, 0x4C, 0x39, 0x52, 0xC0, 0x30, + 0xBA, 0xF0, 0x8C, 0x4B, 0x02, 0xB0, 0xB6, 0xB7 +}; + +static const unsigned char TA234_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA235_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x1B, + 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x55, 0x43, 0x41, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x47, 0x32, 0x20, 0x52, + 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA235_RSA_N[] = { + 0xC5, 0xE6, 0x2B, 0x6F, 0x7C, 0xEF, 0x26, 0x05, 0x27, 0xA3, 0x81, 0x24, + 0xDA, 0x6F, 0xCB, 0x01, 0xF9, 0x99, 0x9A, 0xA9, 0x32, 0xC2, 0x22, 0x87, + 0x61, 0x41, 0x91, 0x3B, 0xCB, 0xC3, 0x68, 0x1B, 0x06, 0xC5, 0x4C, 0xA9, + 0x2B, 0xC1, 0x67, 0x17, 0x22, 0x1D, 0x2B, 0xED, 0xF9, 0x29, 0x89, 0x93, + 0xA2, 0x78, 0xBD, 0x92, 0x6B, 0xA0, 0xA3, 0x0D, 0xA2, 0x7E, 0xCA, 0x93, + 0xB3, 0xA6, 0xD1, 0x8C, 0x35, 0xD5, 0x75, 0xF9, 0x17, 0xF6, 0xCF, 0x45, + 0xC5, 0xE5, 0x7A, 0xEC, 0x77, 0x93, 0xA0, 0x8F, 0x23, 0xAE, 0x0E, 0x1A, + 0x03, 0x7F, 0xBE, 0xD4, 0xD0, 0xED, 0x2E, 0x7B, 0xAB, 0x46, 0x23, 0x5B, + 0xFF, 0x2C, 0xE6, 0x54, 0x7A, 0x94, 0xC0, 0x2A, 0x15, 0xF0, 0xC9, 0x8D, + 0xB0, 0x7A, 0x3B, 0x24, 0xE1, 0xD7, 0x68, 0xE2, 0x31, 0x3C, 0x06, 0x33, + 0x46, 0xB6, 0x54, 0x11, 0xA6, 0xA5, 0x2F, 0x22, 0x54, 0x2A, 0x58, 0x0D, + 0x01, 0x02, 0xF1, 0xFA, 0x15, 0x51, 0x67, 0x6C, 0xC0, 0xFA, 0xD7, 0xB6, + 0x1B, 0x7F, 0xD1, 0x56, 0x88, 0x2F, 0x1A, 0x3A, 0x8D, 0x3B, 0xBB, 0x82, + 0x11, 0xE0, 0x47, 0x00, 0xD0, 0x52, 0x87, 0xAB, 0xFB, 0x86, 0x7E, 0x0F, + 0x24, 0x6B, 0x40, 0x9D, 0x34, 0x67, 0xBC, 0x8D, 0xC7, 0x2D, 0x86, 0x6F, + 0x79, 0x3E, 0x8E, 0xA9, 0x3C, 0x17, 0x4B, 0x7F, 0xB0, 0x99, 0xE3, 0xB0, + 0x71, 0x60, 0xDC, 0x0B, 0xF5, 0x64, 0xC3, 0xCE, 0x43, 0xBC, 0x6D, 0x71, + 0xB9, 0xD2, 0xDE, 0x27, 0x5B, 0x8A, 0xE8, 0xD8, 0xC6, 0xAE, 0xE1, 0x59, + 0x7D, 0xCF, 0x28, 0x2D, 0x35, 0xB8, 0x95, 0x56, 0x1A, 0xF1, 0xB2, 0x58, + 0x4B, 0xB7, 0x12, 0x37, 0xC8, 0x7C, 0xB3, 0xED, 0x4B, 0x80, 0xE1, 0x8D, + 0xFA, 0x32, 0x23, 0xB6, 0x6F, 0xB7, 0x48, 0x95, 0x08, 0xB1, 0x44, 0x4E, + 0x85, 0x8C, 0x3A, 0x02, 0x54, 0x20, 0x2F, 0xDF, 0xBF, 0x57, 0x4F, 0x3B, + 0x3A, 0x90, 0x21, 0xD7, 0xC1, 0x26, 0x35, 0x54, 0x20, 0xEC, 0xC7, 0x3F, + 0x47, 0xEC, 0xEF, 0x5A, 0xBF, 0x4B, 0x7A, 0xC1, 0xAD, 0x3B, 0x17, 0x50, + 0x5C, 0x62, 0xD8, 0x0F, 0x4B, 0x4A, 0xDC, 0x2B, 0xFA, 0x6E, 0xBC, 0x73, + 0x92, 0xCD, 0xEC, 0xC7, 0x50, 0xE8, 0x41, 0x96, 0xD7, 0xA9, 0x7E, 0x6D, + 0xD8, 0xE9, 0x1D, 0x8F, 0x8A, 0xB5, 0xB9, 0x58, 0x92, 0xBA, 0x4A, 0x92, + 0x2B, 0x0C, 0x56, 0xFD, 0x80, 0xEB, 0x08, 0xF0, 0x5E, 0x29, 0x6E, 0x1B, + 0x1C, 0x0C, 0xAF, 0x8F, 0x93, 0x89, 0xAD, 0xDB, 0xBD, 0xA3, 0x9E, 0x21, + 0xCA, 0x89, 0x19, 0xEC, 0xDF, 0xB5, 0xC3, 0x1A, 0xEB, 0x16, 0xFE, 0x78, + 0x36, 0x4C, 0xD6, 0x6E, 0xD0, 0x3E, 0x17, 0x1C, 0x90, 0x17, 0x6B, 0x26, + 0xBA, 0xFB, 0x7A, 0x2F, 0xBF, 0x11, 0x1C, 0x18, 0x0E, 0x2D, 0x73, 0x03, + 0x8F, 0xA0, 0xE5, 0x35, 0xA0, 0x5A, 0xE2, 0x4C, 0x75, 0x1D, 0x71, 0xE1, + 0x39, 0x38, 0x53, 0x78, 0x40, 0xCC, 0x83, 0x93, 0xD7, 0x0A, 0x9E, 0x9D, + 0x5B, 0x8F, 0x8A, 0xE4, 0xE5, 0xE0, 0x48, 0xE4, 0x48, 0xB2, 0x47, 0xCD, + 0x4E, 0x2A, 0x75, 0x2A, 0x7B, 0xF2, 0x22, 0xF6, 0xC9, 0xBE, 0x09, 0x91, + 0x96, 0x57, 0x7A, 0x88, 0x88, 0xAC, 0xEE, 0x70, 0xAC, 0xF9, 0xDC, 0x29, + 0xE3, 0x0C, 0x1C, 0x3B, 0x12, 0x4E, 0x44, 0xD6, 0xA7, 0x4E, 0xB0, 0x26, + 0xC8, 0xF3, 0xD9, 0x1A, 0x97, 0x91, 0x68, 0xEA, 0xEF, 0x8D, 0x46, 0x06, + 0xD2, 0x56, 0x45, 0x58, 0x9A, 0x3C, 0x0C, 0x0F, 0x83, 0xB8, 0x05, 0x25, + 0xC3, 0x39, 0xCF, 0x3B, 0xA4, 0x34, 0x89, 0xB7, 0x79, 0x12, 0x2F, 0x47, + 0xC5, 0xE7, 0xA9, 0x97, 0x69, 0xFC, 0xA6, 0x77, 0x67, 0xB5, 0xDF, 0x7B, + 0xF1, 0x7A, 0x65, 0x15, 0xE4, 0x61, 0x56, 0x65 +}; + +static const unsigned char TA235_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA236_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x1E, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA236_RSA_N[] = { + 0xD3, 0xB2, 0x4A, 0xCF, 0x7A, 0x47, 0xEF, 0x75, 0x9B, 0x23, 0xFA, 0x3A, + 0x2F, 0xD6, 0x50, 0x45, 0x89, 0x35, 0x3A, 0xC6, 0x6B, 0xDB, 0xFE, 0xDB, + 0x00, 0x68, 0xA8, 0xE0, 0x03, 0x11, 0x1D, 0x37, 0x50, 0x08, 0x9F, 0x4D, + 0x4A, 0x68, 0x94, 0x35, 0xB3, 0x53, 0xD1, 0x94, 0x63, 0xA7, 0x20, 0x56, + 0xAF, 0xDE, 0x51, 0x78, 0xEC, 0x2A, 0x3D, 0xF3, 0x48, 0x48, 0x50, 0x3E, + 0x0A, 0xDF, 0x46, 0x55, 0x8B, 0x27, 0x6D, 0xC3, 0x10, 0x4D, 0x0D, 0x91, + 0x52, 0x43, 0xD8, 0x87, 0xE0, 0x5D, 0x4E, 0x36, 0xB5, 0x21, 0xCA, 0x5F, + 0x39, 0x40, 0x04, 0x5F, 0x5B, 0x7E, 0xCC, 0xA3, 0xC6, 0x2B, 0xA9, 0x40, + 0x1E, 0xD9, 0x36, 0x84, 0xD6, 0x48, 0xF3, 0x92, 0x1E, 0x34, 0x46, 0x20, + 0x24, 0xC1, 0xA4, 0x51, 0x8E, 0x4A, 0x1A, 0xEF, 0x50, 0x3F, 0x69, 0x5D, + 0x19, 0x7F, 0x45, 0xC3, 0xC7, 0x01, 0x8F, 0x51, 0xC9, 0x23, 0xE8, 0x72, + 0xAE, 0xB4, 0xBC, 0x56, 0x09, 0x7F, 0x12, 0xCB, 0x1C, 0xB1, 0xAF, 0x29, + 0x90, 0x0A, 0xC9, 0x55, 0xCC, 0x0F, 0xD3, 0xB4, 0x1A, 0xED, 0x47, 0x35, + 0x5A, 0x4A, 0xED, 0x9C, 0x73, 0x04, 0x21, 0xD0, 0xAA, 0xBD, 0x0C, 0x13, + 0xB5, 0x00, 0xCA, 0x26, 0x6C, 0xC4, 0x6B, 0x0C, 0x94, 0x5A, 0x95, 0x94, + 0xDA, 0x50, 0x9A, 0xF1, 0xFF, 0xA5, 0x2B, 0x66, 0x31, 0xA4, 0xC9, 0x38, + 0xA0, 0xDF, 0x1D, 0x1F, 0xB8, 0x09, 0x2E, 0xF3, 0xA7, 0xE8, 0x67, 0x52, + 0xAB, 0x95, 0x1F, 0xE0, 0x46, 0x3E, 0xD8, 0xA4, 0xC3, 0xCA, 0x5A, 0xC5, + 0x31, 0x80, 0xE8, 0x48, 0x9A, 0x9F, 0x94, 0x69, 0xFE, 0x19, 0xDD, 0xD8, + 0x73, 0x7C, 0x81, 0xCA, 0x96, 0xDE, 0x8E, 0xED, 0xB3, 0x32, 0x05, 0x65, + 0x84, 0x34, 0xE6, 0xE6, 0xFD, 0x57, 0x10, 0xB5, 0x5F, 0x76, 0xBF, 0x2F, + 0xB0, 0x10, 0x0D, 0xC5 +}; + +static const unsigned char TA236_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA237_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x34, 0x30, 0x39, 0x36, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA237_RSA_N[] = { + 0xB3, 0xD0, 0xF4, 0xC9, 0x79, 0x11, 0x9D, 0xFD, 0xFC, 0x66, 0x81, 0xE7, + 0xCC, 0xD5, 0xE4, 0xBC, 0xEC, 0x81, 0x3E, 0x6A, 0x35, 0x8E, 0x2E, 0xB7, + 0xE7, 0xDE, 0xAF, 0xF9, 0x07, 0x4D, 0xCF, 0x30, 0x9D, 0xEA, 0x09, 0x0B, + 0x99, 0xBD, 0x6C, 0x57, 0xDA, 0x18, 0x4A, 0xB8, 0x78, 0xAC, 0x3A, 0x39, + 0xA8, 0xA6, 0x48, 0xAC, 0x2E, 0x72, 0xE5, 0xBD, 0xEB, 0xF1, 0x1A, 0xCD, + 0xE7, 0xA4, 0x03, 0xA9, 0x3F, 0x11, 0xB4, 0xD8, 0x2F, 0x89, 0x16, 0xFB, + 0x94, 0x01, 0x3D, 0xBB, 0x2F, 0xF8, 0x13, 0x05, 0xA1, 0x78, 0x1C, 0x8E, + 0x28, 0xE0, 0x45, 0xE0, 0x83, 0xF4, 0x59, 0x1B, 0x95, 0xB3, 0xAE, 0x7E, + 0x03, 0x45, 0xE5, 0xBE, 0xC2, 0x42, 0xFE, 0xEE, 0xF2, 0x3C, 0xB6, 0x85, + 0x13, 0x98, 0x32, 0x9D, 0x16, 0xA8, 0x29, 0xC2, 0x0B, 0x1C, 0x38, 0xDC, + 0x9F, 0x31, 0x77, 0x5C, 0xBF, 0x27, 0xA3, 0xFC, 0x27, 0xAC, 0xB7, 0x2B, + 0xBD, 0x74, 0x9B, 0x17, 0x2D, 0xF2, 0x81, 0xDA, 0x5D, 0xB0, 0xE1, 0x23, + 0x17, 0x3E, 0x88, 0x4A, 0x12, 0x23, 0xD0, 0xEA, 0xCF, 0x9D, 0xDE, 0x03, + 0x17, 0xB1, 0x42, 0x4A, 0xA0, 0x16, 0x4C, 0xA4, 0x6D, 0x93, 0xE9, 0x3F, + 0x3A, 0xEE, 0x3A, 0x7C, 0x9D, 0x58, 0x9D, 0xF4, 0x4E, 0x8F, 0xFC, 0x3B, + 0x23, 0xC8, 0x6D, 0xB8, 0xE2, 0x05, 0xDA, 0xCC, 0xEB, 0xEC, 0xC3, 0x31, + 0xF4, 0xD7, 0xA7, 0x29, 0x54, 0x80, 0xCF, 0x44, 0x5B, 0x4C, 0x6F, 0x30, + 0x9E, 0xF3, 0xCC, 0xDD, 0x1F, 0x94, 0x43, 0x9D, 0x4D, 0x7F, 0x70, 0x70, + 0x0D, 0xD4, 0x3A, 0xD1, 0x37, 0xF0, 0x6C, 0x9D, 0x9B, 0xC0, 0x14, 0x93, + 0x58, 0xEF, 0xCD, 0x41, 0x38, 0x75, 0xBC, 0x13, 0x03, 0x95, 0x7C, 0x7F, + 0xE3, 0x5C, 0xE9, 0xD5, 0x0D, 0xD5, 0xE2, 0x7C, 0x10, 0x62, 0xAA, 0x6B, + 0xF0, 0x3D, 0x76, 0xF3, 0x3F, 0xA3, 0xE8, 0xB0, 0xC1, 0xFD, 0xEF, 0xAA, + 0x57, 0x4D, 0xAC, 0x86, 0xA7, 0x18, 0xB4, 0x29, 0xC1, 0x2C, 0x0E, 0xBF, + 0x64, 0xBE, 0x29, 0x8C, 0xD8, 0x02, 0x2D, 0xCD, 0x5C, 0x2F, 0xF2, 0x7F, + 0xEF, 0x15, 0xF4, 0x0C, 0x15, 0xAC, 0x0A, 0xB0, 0xF1, 0xD3, 0x0D, 0x4F, + 0x6A, 0x4D, 0x77, 0x97, 0x01, 0xA0, 0xF1, 0x66, 0xB7, 0xB7, 0xCE, 0xEF, + 0xCE, 0xEC, 0xEC, 0xA5, 0x75, 0xCA, 0xAC, 0xE3, 0xE1, 0x63, 0xF7, 0xB8, + 0xA1, 0x04, 0xC8, 0xBC, 0x7B, 0x3F, 0x5D, 0x2D, 0x16, 0x22, 0x56, 0xED, + 0x48, 0x49, 0xFE, 0xA7, 0x2F, 0x79, 0x30, 0x25, 0x9B, 0xBA, 0x6B, 0x2D, + 0x3F, 0x9D, 0x3B, 0xC4, 0x17, 0xE7, 0x1D, 0x2E, 0xFB, 0xF2, 0xCF, 0xA6, + 0xFC, 0xE3, 0x14, 0x2C, 0x96, 0x98, 0x21, 0x8C, 0xB4, 0x91, 0xE9, 0x19, + 0x60, 0x83, 0xF2, 0x30, 0x2B, 0x06, 0x73, 0x50, 0xD5, 0x98, 0x3B, 0x06, + 0xE9, 0xC7, 0x8A, 0x0C, 0x60, 0x8C, 0x28, 0xF8, 0x52, 0x9B, 0x6E, 0xE1, + 0xF6, 0x4D, 0xBB, 0x06, 0x24, 0x9B, 0xD7, 0x2B, 0x26, 0x3F, 0xFD, 0x2A, + 0x2F, 0x71, 0xF5, 0xD6, 0x24, 0xBE, 0x7F, 0x31, 0x9E, 0x0F, 0x6D, 0xE8, + 0x8F, 0x4F, 0x4D, 0xA3, 0x3F, 0xFF, 0x35, 0xEA, 0xDF, 0x49, 0x5E, 0x41, + 0x8F, 0x86, 0xF9, 0xF1, 0x77, 0x79, 0x4B, 0x1B, 0xB4, 0xA3, 0x5E, 0x2F, + 0xFB, 0x46, 0x02, 0xD0, 0x66, 0x13, 0x5E, 0x5E, 0x85, 0x4F, 0xCE, 0xD8, + 0x70, 0x88, 0x7B, 0xCE, 0x01, 0xB5, 0x96, 0x97, 0xD7, 0xCD, 0x7D, 0xFD, + 0x82, 0xF8, 0xC2, 0x24, 0xC1, 0xCA, 0x01, 0x39, 0x4F, 0x8D, 0xA2, 0xC1, + 0x14, 0x40, 0x1F, 0x9C, 0x66, 0xD5, 0x0C, 0x09, 0x46, 0xD6, 0xF2, 0xD0, + 0xD1, 0x48, 0x76, 0x56, 0x3A, 0x43, 0xCB, 0xB6, 0x0A, 0x11, 0x39, 0xBA, + 0x8C, 0x13, 0x6C, 0x06, 0xB5, 0x9E, 0xCF, 0xEB +}; + +static const unsigned char TA237_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA238_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA238_EC_Q[] = { + 0x04, 0x19, 0xE7, 0xBC, 0xAC, 0x44, 0x65, 0xED, 0xCD, 0xB8, 0x3F, 0x58, + 0xFB, 0x8D, 0xB1, 0x57, 0xA9, 0x44, 0x2D, 0x05, 0x15, 0xF2, 0xEF, 0x0B, + 0xFF, 0x10, 0x74, 0x9F, 0xB5, 0x62, 0x52, 0x5F, 0x66, 0x7E, 0x1F, 0xE5, + 0xDC, 0x1B, 0x45, 0x79, 0x0B, 0xCC, 0xC6, 0x53, 0x0A, 0x9D, 0x8D, 0x5D, + 0x02, 0xD9, 0xA9, 0x59, 0xDE, 0x02, 0x5A, 0xF6, 0x95, 0x2A, 0x0E, 0x8D, + 0x38, 0x4A, 0x8A, 0x49, 0xC6, 0xBC, 0xC6, 0x03, 0x38, 0x07, 0x5F, 0x55, + 0xDA, 0x7E, 0x09, 0x6E, 0xE2, 0x7F, 0x5E, 0xD0, 0x45, 0x20, 0x0F, 0x59, + 0x76, 0x10, 0xD6, 0xA0, 0x24, 0xF0, 0x2D, 0xDE, 0x36, 0xF2, 0x6C, 0x29, + 0x39 +}; + +static const unsigned char TA239_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA239_RSA_N[] = { + 0xCE, 0xDE, 0xFD, 0xA6, 0xFB, 0xEC, 0xEC, 0x14, 0x34, 0x3C, 0x07, 0x06, + 0x5A, 0x6C, 0x59, 0xF7, 0x19, 0x35, 0xDD, 0xF7, 0xC1, 0x9D, 0x55, 0xAA, + 0xD3, 0xCD, 0x3B, 0xA4, 0x93, 0x72, 0xEF, 0x0A, 0xFA, 0x6D, 0x9D, 0xF6, + 0xF0, 0x85, 0x80, 0x5B, 0xA1, 0x48, 0x52, 0x9F, 0x39, 0xC5, 0xB7, 0xEE, + 0x28, 0xAC, 0xEF, 0xCB, 0x76, 0x68, 0x14, 0xB9, 0xDF, 0xAD, 0x01, 0x6C, + 0x99, 0x1F, 0xC4, 0x22, 0x1D, 0x9F, 0xFE, 0x72, 0x77, 0xE0, 0x2C, 0x5B, + 0xAF, 0xE4, 0x04, 0xBF, 0x4F, 0x72, 0xA0, 0x1A, 0x34, 0x98, 0xE8, 0x39, + 0x68, 0xEC, 0x95, 0x25, 0x7B, 0x76, 0xA1, 0xE6, 0x69, 0xB9, 0x85, 0x19, + 0xBD, 0x89, 0x8C, 0xFE, 0xAD, 0xED, 0x36, 0xEA, 0x73, 0xBC, 0xFF, 0x83, + 0xE2, 0xCB, 0x7D, 0xC1, 0xD2, 0xCE, 0x4A, 0xB3, 0x8D, 0x05, 0x9E, 0x8B, + 0x49, 0x93, 0xDF, 0xC1, 0x5B, 0xD0, 0x6E, 0x5E, 0xF0, 0x2E, 0x30, 0x2E, + 0x82, 0xFC, 0xFA, 0xBC, 0xB4, 0x17, 0x0A, 0x48, 0xE5, 0x88, 0x9B, 0xC5, + 0x9B, 0x6B, 0xDE, 0xB0, 0xCA, 0xB4, 0x03, 0xF0, 0xDA, 0xF4, 0x90, 0xB8, + 0x65, 0x64, 0xF7, 0x5C, 0x4C, 0xAD, 0xE8, 0x7E, 0x66, 0x5E, 0x99, 0xD7, + 0xB8, 0xC2, 0x3E, 0xC8, 0xD0, 0x13, 0x9D, 0xAD, 0xEE, 0xE4, 0x45, 0x7B, + 0x89, 0x55, 0xF7, 0x8A, 0x1F, 0x62, 0x52, 0x84, 0x12, 0xB3, 0xC2, 0x40, + 0x97, 0xE3, 0x8A, 0x1F, 0x47, 0x91, 0xA6, 0x74, 0x5A, 0xD2, 0xF8, 0xB1, + 0x63, 0x28, 0x10, 0xB8, 0xB3, 0x09, 0xB8, 0x56, 0x77, 0x40, 0xA2, 0x26, + 0x98, 0x79, 0xC6, 0xFE, 0xDF, 0x25, 0xEE, 0x3E, 0xE5, 0xA0, 0x7F, 0xD4, + 0x61, 0x0F, 0x51, 0x4B, 0x3C, 0x3F, 0x8C, 0xDA, 0xE1, 0x70, 0x74, 0xD8, + 0xC2, 0x68, 0xA1, 0xF9, 0xC1, 0x0C, 0xE9, 0xA1, 0xE2, 0x7F, 0xBB, 0x55, + 0x3C, 0x76, 0x06, 0xEE, 0x6A, 0x4E, 0xCC, 0x92, 0x88, 0x30, 0x4D, 0x9A, + 0xBD, 0x4F, 0x0B, 0x48, 0x9A, 0x84, 0xB5, 0x98, 0xA3, 0xD5, 0xFB, 0x73, + 0xC1, 0x57, 0x61, 0xDD, 0x28, 0x56, 0x75, 0x13, 0xAE, 0x87, 0x8E, 0xE7, + 0x0C, 0x51, 0x09, 0x10, 0x75, 0x88, 0x4C, 0xBC, 0x8D, 0xF9, 0x7B, 0x3C, + 0xD4, 0x22, 0x48, 0x1F, 0x2A, 0xDC, 0xEB, 0x6B, 0xBB, 0x44, 0xB1, 0xCB, + 0x33, 0x71, 0x32, 0x46, 0xAF, 0xAD, 0x4A, 0xF1, 0x8C, 0xE8, 0x74, 0x3A, + 0xAC, 0xE7, 0x1A, 0x22, 0x73, 0x80, 0xD2, 0x30, 0xF7, 0x25, 0x42, 0xC7, + 0x22, 0x3B, 0x3B, 0x12, 0xAD, 0x96, 0x2E, 0xC6, 0xC3, 0x76, 0x07, 0xAA, + 0x20, 0xB7, 0x35, 0x49, 0x57, 0xE9, 0x92, 0x49, 0xE8, 0x76, 0x16, 0x72, + 0x31, 0x67, 0x2B, 0x96, 0x7E, 0x8A, 0xA3, 0xC7, 0x94, 0x56, 0x22, 0xBF, + 0x6A, 0x4B, 0x7E, 0x01, 0x21, 0xB2, 0x23, 0x32, 0xDF, 0xE4, 0x9A, 0x44, + 0x6D, 0x59, 0x5B, 0x5D, 0xF5, 0x00, 0xA0, 0x1C, 0x9B, 0xC6, 0x78, 0x97, + 0x8D, 0x90, 0xFF, 0x9B, 0xC8, 0xAA, 0xB4, 0xAF, 0x11, 0x51, 0x39, 0x5E, + 0xD9, 0xFB, 0x67, 0xAD, 0xD5, 0x5B, 0x11, 0x9D, 0x32, 0x9A, 0x1B, 0xBD, + 0xD5, 0xBA, 0x5B, 0xA5, 0xC9, 0xCB, 0x25, 0x69, 0x53, 0x55, 0x27, 0x5C, + 0xE0, 0xCA, 0x36, 0xCB, 0x88, 0x61, 0xFB, 0x1E, 0xB7, 0xD0, 0xCB, 0xEE, + 0x16, 0xFB, 0xD3, 0xA6, 0x4C, 0xDE, 0x92, 0xA5, 0xD4, 0xE2, 0xDF, 0xF5, + 0x06, 0x54, 0xDE, 0x2E, 0x9D, 0x4B, 0xB4, 0x93, 0x30, 0xAA, 0x81, 0xCE, + 0xDD, 0x1A, 0xDC, 0x51, 0x73, 0x0D, 0x4F, 0x70, 0xE9, 0xE5, 0xB6, 0x16, + 0x21, 0x19, 0x79, 0xB2, 0xE6, 0x89, 0x0B, 0x75, 0x64, 0xCA, 0xD5, 0xAB, + 0xBC, 0x09, 0xC1, 0x18, 0xA1, 0xFF, 0xD4, 0x54, 0xA1, 0x85, 0x3C, 0xFD, + 0x14, 0x24, 0x03, 0xB2, 0x87, 0xD3, 0xA4, 0xB7 +}; + +static const unsigned char TA239_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA240_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x43, 0x41, 0x31 +}; + +static const unsigned char TA240_EC_Q[] = { + 0x04, 0xA4, 0xA5, 0x6F, 0x60, 0x03, 0x03, 0xC3, 0xBD, 0x31, 0xF4, 0xD3, + 0x17, 0x9C, 0x2B, 0x84, 0x75, 0xAC, 0xE5, 0xFD, 0x3D, 0x57, 0x6E, 0xD7, + 0x63, 0xBF, 0xE6, 0x04, 0x89, 0x92, 0x8E, 0x81, 0x9C, 0xE3, 0xE9, 0x47, + 0x6E, 0xCA, 0x90, 0x12, 0xC8, 0x13, 0xE0, 0xA7, 0x9D, 0xF7, 0x65, 0x74, + 0x1F, 0x6C, 0x10, 0xB2, 0xE8, 0xE4, 0xE9, 0xEF, 0x6D, 0x85, 0x32, 0x99, + 0x44, 0xB1, 0x5E, 0xFD, 0xCC, 0x76, 0x10, 0xD8, 0x5B, 0xBD, 0xA2, 0xC6, + 0xF9, 0xD6, 0x42, 0xE4, 0x57, 0x76, 0xDC, 0x90, 0xC2, 0x35, 0xA9, 0x4B, + 0x88, 0x3C, 0x12, 0x47, 0x6D, 0x5C, 0xFF, 0x49, 0x4F, 0x1A, 0x4A, 0x50, + 0xB1 +}; + +static const unsigned char TA241_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x32 +}; + +static const unsigned char TA241_RSA_N[] = { + 0xBB, 0x37, 0xCD, 0x34, 0xDC, 0x7B, 0x6B, 0xC9, 0xB2, 0x68, 0x90, 0xAD, + 0x4A, 0x75, 0xFF, 0x46, 0xBA, 0x21, 0x0A, 0x08, 0x8D, 0xF5, 0x19, 0x54, + 0xC9, 0xFB, 0x88, 0xDB, 0xF3, 0xAE, 0xF2, 0x3A, 0x89, 0x91, 0x3C, 0x7A, + 0xE6, 0xAB, 0x06, 0x1A, 0x6B, 0xCF, 0xAC, 0x2D, 0xE8, 0x5E, 0x09, 0x24, + 0x44, 0xBA, 0x62, 0x9A, 0x7E, 0xD6, 0xA3, 0xA8, 0x7E, 0xE0, 0x54, 0x75, + 0x20, 0x05, 0xAC, 0x50, 0xB7, 0x9C, 0x63, 0x1A, 0x6C, 0x30, 0xDC, 0xDA, + 0x1F, 0x19, 0xB1, 0xD7, 0x1E, 0xDE, 0xFD, 0xD7, 0xE0, 0xCB, 0x94, 0x83, + 0x37, 0xAE, 0xEC, 0x1F, 0x43, 0x4E, 0xDD, 0x7B, 0x2C, 0xD2, 0xBD, 0x2E, + 0xA5, 0x2F, 0xE4, 0xA9, 0xB8, 0xAD, 0x3A, 0xD4, 0x99, 0xA4, 0xB6, 0x25, + 0xE9, 0x9B, 0x6B, 0x00, 0x60, 0x92, 0x60, 0xFF, 0x4F, 0x21, 0x49, 0x18, + 0xF7, 0x67, 0x90, 0xAB, 0x61, 0x06, 0x9C, 0x8F, 0xF2, 0xBA, 0xE9, 0xB4, + 0xE9, 0x92, 0x32, 0x6B, 0xB5, 0xF3, 0x57, 0xE8, 0x5D, 0x1B, 0xCD, 0x8C, + 0x1D, 0xAB, 0x95, 0x04, 0x95, 0x49, 0xF3, 0x35, 0x2D, 0x96, 0xE3, 0x49, + 0x6D, 0xDD, 0x77, 0xE3, 0xFB, 0x49, 0x4B, 0xB4, 0xAC, 0x55, 0x07, 0xA9, + 0x8F, 0x95, 0xB3, 0xB4, 0x23, 0xBB, 0x4C, 0x6D, 0x45, 0xF0, 0xF6, 0xA9, + 0xB2, 0x95, 0x30, 0xB4, 0xFD, 0x4C, 0x55, 0x8C, 0x27, 0x4A, 0x57, 0x14, + 0x7C, 0x82, 0x9D, 0xCD, 0x73, 0x92, 0xD3, 0x16, 0x4A, 0x06, 0x0C, 0x8C, + 0x50, 0xD1, 0x8F, 0x1E, 0x09, 0xBE, 0x17, 0xA1, 0xE6, 0x21, 0xCA, 0xFD, + 0x83, 0xE5, 0x10, 0xBC, 0x83, 0xA5, 0x0A, 0xC4, 0x67, 0x28, 0xF6, 0x73, + 0x14, 0x14, 0x3D, 0x46, 0x76, 0xC3, 0x87, 0x14, 0x89, 0x21, 0x34, 0x4D, + 0xAF, 0x0F, 0x45, 0x0C, 0xA6, 0x49, 0xA1, 0xBA, 0xBB, 0x9C, 0xC5, 0xB1, + 0x33, 0x83, 0x29, 0x85 +}; + +static const unsigned char TA241_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA242_DN[] = { + 0x30, 0x5E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x21, 0x65, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA242_RSA_N[] = { + 0xE1, 0x25, 0x0F, 0xEE, 0x8D, 0xDB, 0x88, 0x33, 0x75, 0x67, 0xCD, 0xAD, + 0x1F, 0x7D, 0x3A, 0x4E, 0x6D, 0x9D, 0xD3, 0x2F, 0x14, 0xF3, 0x63, 0x74, + 0xCB, 0x01, 0x21, 0x6A, 0x37, 0xEA, 0x84, 0x50, 0x07, 0x4B, 0x26, 0x5B, + 0x09, 0x43, 0x6C, 0x21, 0x9E, 0x6A, 0xC8, 0xD5, 0x03, 0xF5, 0x60, 0x69, + 0x8F, 0xCC, 0xF0, 0x22, 0xE4, 0x1F, 0xE7, 0xF7, 0x6A, 0x22, 0x31, 0xB7, + 0x2C, 0x15, 0xF2, 0xE0, 0xFE, 0x00, 0x6A, 0x43, 0xFF, 0x87, 0x65, 0xC6, + 0xB5, 0x1A, 0xC1, 0xA7, 0x4C, 0x6D, 0x22, 0x70, 0x21, 0x8A, 0x31, 0xF2, + 0x97, 0x74, 0x89, 0x09, 0x12, 0x26, 0x1C, 0x9E, 0xCA, 0xD9, 0x12, 0xA2, + 0x95, 0x3C, 0xDA, 0xE9, 0x67, 0xBF, 0x08, 0xA0, 0x64, 0xE3, 0xD6, 0x42, + 0xB7, 0x45, 0xEF, 0x97, 0xF4, 0xF6, 0xF5, 0xD7, 0xB5, 0x4A, 0x15, 0x02, + 0x58, 0x7D, 0x98, 0x58, 0x4B, 0x60, 0xBC, 0xCD, 0xD7, 0x0D, 0x9A, 0x13, + 0x33, 0x53, 0xD1, 0x61, 0xF9, 0x7A, 0xD5, 0xD7, 0x78, 0xB3, 0x9A, 0x33, + 0xF7, 0x00, 0x86, 0xCE, 0x1D, 0x4D, 0x94, 0x38, 0xAF, 0xA8, 0xEC, 0x78, + 0x51, 0x70, 0x8A, 0x5C, 0x10, 0x83, 0x51, 0x21, 0xF7, 0x11, 0x3D, 0x34, + 0x86, 0x5E, 0xE5, 0x48, 0xCD, 0x97, 0x81, 0x82, 0x35, 0x4C, 0x19, 0xEC, + 0x65, 0xF6, 0x6B, 0xC5, 0x05, 0xA1, 0xEE, 0x47, 0x13, 0xD6, 0xB3, 0x21, + 0x27, 0x94, 0x10, 0x0A, 0xD9, 0x24, 0x3B, 0xBA, 0xBE, 0x44, 0x13, 0x46, + 0x30, 0x3F, 0x97, 0x3C, 0xD8, 0xD7, 0xD7, 0x6A, 0xEE, 0x3B, 0x38, 0xE3, + 0x2B, 0xD4, 0x97, 0x0E, 0xB9, 0x1B, 0xE7, 0x07, 0x49, 0x7F, 0x37, 0x2A, + 0xF9, 0x77, 0x78, 0xCF, 0x54, 0xED, 0x5B, 0x46, 0x9D, 0xA3, 0x80, 0x0E, + 0x91, 0x43, 0xC1, 0xD6, 0x5B, 0x5F, 0x14, 0xBA, 0x9F, 0xA6, 0x8D, 0x24, + 0x47, 0x40, 0x59, 0xBF, 0x72, 0x38, 0xB2, 0x36, 0x6C, 0x37, 0xFF, 0x99, + 0xD1, 0x5D, 0x0E, 0x59, 0x0A, 0xAB, 0x69, 0xF7, 0xC0, 0xB2, 0x04, 0x45, + 0x7A, 0x54, 0x00, 0xAE, 0xBE, 0x53, 0xF6, 0xB5, 0xE7, 0xE1, 0xF8, 0x3C, + 0xA3, 0x31, 0xD2, 0xA9, 0xFE, 0x21, 0x52, 0x64, 0xC5, 0xA6, 0x67, 0xF0, + 0x75, 0x07, 0x06, 0x94, 0x14, 0x81, 0x55, 0xC6, 0x27, 0xE4, 0x01, 0x8F, + 0x17, 0xC1, 0x6A, 0x71, 0xD7, 0xBE, 0x4B, 0xFB, 0x94, 0x58, 0x7D, 0x7E, + 0x11, 0x33, 0xB1, 0x42, 0xF7, 0x62, 0x6C, 0x18, 0xD6, 0xCF, 0x09, 0x68, + 0x3E, 0x7F, 0x6C, 0xF6, 0x1E, 0x8F, 0x62, 0xAD, 0xA5, 0x63, 0xDB, 0x09, + 0xA7, 0x1F, 0x22, 0x42, 0x41, 0x1E, 0x6F, 0x99, 0x8A, 0x3E, 0xD7, 0xF9, + 0x3F, 0x40, 0x7A, 0x79, 0xB0, 0xA5, 0x01, 0x92, 0xD2, 0x9D, 0x3D, 0x08, + 0x15, 0xA5, 0x10, 0x01, 0x2D, 0xB3, 0x32, 0x76, 0xA8, 0x95, 0x0D, 0xB3, + 0x7A, 0x9A, 0xFB, 0x07, 0x10, 0x78, 0x11, 0x6F, 0xE1, 0x8F, 0xC7, 0xBA, + 0x0F, 0x25, 0x1A, 0x74, 0x2A, 0xE5, 0x1C, 0x98, 0x41, 0x99, 0xDF, 0x21, + 0x87, 0xE8, 0x95, 0x06, 0x6A, 0x0A, 0xB3, 0x6A, 0x47, 0x76, 0x65, 0xF6, + 0x3A, 0xCF, 0x8F, 0x62, 0x17, 0x19, 0x7B, 0x0A, 0x28, 0xCD, 0x1A, 0xD2, + 0x83, 0x1E, 0x21, 0xC7, 0x2C, 0xBF, 0xBE, 0xFF, 0x61, 0x68, 0xB7, 0x67, + 0x1B, 0xBB, 0x78, 0x4D, 0x8D, 0xCE, 0x67, 0xE5, 0xE4, 0xC1, 0x8E, 0xB7, + 0x23, 0x66, 0xE2, 0x9D, 0x90, 0x75, 0x34, 0x98, 0xA9, 0x36, 0x2B, 0x8A, + 0x9A, 0x94, 0xB9, 0x9D, 0xEC, 0xCC, 0x8A, 0xB1, 0xF8, 0x25, 0x89, 0x5C, + 0x5A, 0xB6, 0x2F, 0x8C, 0x1F, 0x6D, 0x79, 0x24, 0xA7, 0x52, 0x68, 0xC3, + 0x84, 0x35, 0xE2, 0x66, 0x8D, 0x63, 0x0E, 0x25, 0x4D, 0xD5, 0x19, 0xB2, + 0xE6, 0x79, 0x37, 0xA7, 0x22, 0x9D, 0x54, 0x31 +}; + +static const unsigned char TA242_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA243_DN[] = { + 0x30, 0x42, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x09, 0x41, 0x43, 0x43, 0x56, 0x52, 0x41, 0x49, 0x5A, 0x31, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x50, 0x4B, 0x49, + 0x41, 0x43, 0x43, 0x56, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x04, 0x41, 0x43, 0x43, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53 +}; + +static const unsigned char TA243_RSA_N[] = { + 0x9B, 0xA9, 0xAB, 0xBF, 0x61, 0x4A, 0x97, 0xAF, 0x2F, 0x97, 0x66, 0x9A, + 0x74, 0x5F, 0xD0, 0xD9, 0x96, 0xFD, 0xCF, 0xE2, 0xE4, 0x66, 0xEF, 0x1F, + 0x1F, 0x47, 0x33, 0xC2, 0x44, 0xA3, 0xDF, 0x9A, 0xDE, 0x1F, 0xB5, 0x54, + 0xDD, 0x15, 0x7C, 0x69, 0x35, 0x11, 0x6F, 0xBB, 0xC8, 0x0C, 0x8E, 0x6A, + 0x18, 0x1E, 0xD8, 0x8F, 0xD9, 0x16, 0xBC, 0x10, 0x48, 0x36, 0x5C, 0xF0, + 0x63, 0xB3, 0x90, 0x5A, 0x5C, 0x24, 0x37, 0xD7, 0xA3, 0xD6, 0xCB, 0x09, + 0x71, 0xB9, 0xF1, 0x01, 0x72, 0x84, 0xB0, 0x7D, 0xDB, 0x4D, 0x80, 0xCD, + 0xFC, 0xD3, 0x6F, 0xC9, 0xF8, 0xDA, 0xB6, 0x0E, 0x82, 0xD2, 0x45, 0x85, + 0xA8, 0x1B, 0x68, 0xA8, 0x3D, 0xE8, 0xF4, 0x44, 0x6C, 0xBD, 0xA1, 0xC2, + 0xCB, 0x03, 0xBE, 0x8C, 0x3E, 0x13, 0x00, 0x84, 0xDF, 0x4A, 0x48, 0xC0, + 0xE3, 0x22, 0x0A, 0xE8, 0xE9, 0x37, 0xA7, 0x18, 0x4C, 0xB1, 0x09, 0x0D, + 0x23, 0x56, 0x7F, 0x04, 0x4D, 0xD9, 0x17, 0x84, 0x18, 0xA5, 0xC8, 0xDA, + 0x40, 0x94, 0x73, 0xEB, 0xCE, 0x0E, 0x57, 0x3C, 0x03, 0x81, 0x3A, 0x9D, + 0x0A, 0xA1, 0x57, 0x43, 0x69, 0xAC, 0x57, 0x6D, 0x79, 0x90, 0x78, 0xE5, + 0xB5, 0xB4, 0x3B, 0xD8, 0xBC, 0x4C, 0x8D, 0x28, 0xA1, 0xA7, 0xA3, 0xA7, + 0xBA, 0x02, 0x4E, 0x25, 0xD1, 0x2A, 0xAE, 0xED, 0xAE, 0x03, 0x22, 0xB8, + 0x6B, 0x20, 0x0F, 0x30, 0x28, 0x54, 0x95, 0x7F, 0xE0, 0xEE, 0xCE, 0x0A, + 0x66, 0x9D, 0xD1, 0x40, 0x2D, 0x6E, 0x22, 0xAF, 0x9D, 0x1A, 0xC1, 0x05, + 0x19, 0xD2, 0x6F, 0xC0, 0xF2, 0x9F, 0xF8, 0x7B, 0xB3, 0x02, 0x42, 0xFB, + 0x50, 0xA9, 0x1D, 0x2D, 0x93, 0x0F, 0x23, 0xAB, 0xC6, 0xC1, 0x0F, 0x92, + 0xFF, 0xD0, 0xA2, 0x15, 0xF5, 0x53, 0x09, 0x71, 0x1C, 0xFF, 0x45, 0x13, + 0x84, 0xE6, 0x26, 0x5E, 0xF8, 0xE0, 0x88, 0x1C, 0x0A, 0xFC, 0x16, 0xB6, + 0xA8, 0x73, 0x06, 0xB8, 0xF0, 0x63, 0x84, 0x02, 0xA0, 0xC6, 0x5A, 0xEC, + 0xE7, 0x74, 0xDF, 0x70, 0xAE, 0xA3, 0x83, 0x25, 0xEA, 0xD6, 0xC7, 0x97, + 0x87, 0x93, 0xA7, 0xC6, 0x8A, 0x8A, 0x33, 0x97, 0x60, 0x37, 0x10, 0x3E, + 0x97, 0x3E, 0x6E, 0x29, 0x15, 0xD6, 0xA1, 0x0F, 0xD1, 0x88, 0x2C, 0x12, + 0x9F, 0x6F, 0xAA, 0xA4, 0xC6, 0x42, 0xEB, 0x41, 0xA2, 0xE3, 0x95, 0x43, + 0xD3, 0x01, 0x85, 0x6D, 0x8E, 0xBB, 0x3B, 0xF3, 0x23, 0x36, 0xC7, 0xFE, + 0x3B, 0xE0, 0xA1, 0x25, 0x07, 0x48, 0xAB, 0xC9, 0x89, 0x74, 0xFF, 0x08, + 0x8F, 0x80, 0xBF, 0xC0, 0x96, 0x65, 0xF3, 0xEE, 0xEC, 0x4B, 0x68, 0xBD, + 0x9D, 0x88, 0xC3, 0x31, 0xB3, 0x40, 0xF1, 0xE8, 0xCF, 0xF6, 0x38, 0xBB, + 0x9C, 0xE4, 0xD1, 0x7F, 0xD4, 0xE5, 0x58, 0x9B, 0x7C, 0xFA, 0xD4, 0xF3, + 0x0E, 0x9B, 0x75, 0x91, 0xE4, 0xBA, 0x52, 0x2E, 0x19, 0x7E, 0xD1, 0xF5, + 0xCD, 0x5A, 0x19, 0xFC, 0xBA, 0x06, 0xF6, 0xFB, 0x52, 0xA8, 0x4B, 0x99, + 0x04, 0xDD, 0xF8, 0xF9, 0xB4, 0x8B, 0x50, 0xA3, 0x4E, 0x62, 0x89, 0xF0, + 0x87, 0x24, 0xFA, 0x83, 0x42, 0xC1, 0x87, 0xFA, 0xD5, 0x2D, 0x29, 0x2A, + 0x5A, 0x71, 0x7A, 0x64, 0x6A, 0xD7, 0x27, 0x60, 0x63, 0x0D, 0xDB, 0xCE, + 0x49, 0xF5, 0x8D, 0x1F, 0x90, 0x89, 0x32, 0x17, 0xF8, 0x73, 0x43, 0xB8, + 0xD2, 0x5A, 0x93, 0x86, 0x61, 0xD6, 0xE1, 0x75, 0x0A, 0xEA, 0x79, 0x66, + 0x76, 0x88, 0x4F, 0x71, 0xEB, 0x04, 0x25, 0xD6, 0x0A, 0x5A, 0x7A, 0x93, + 0xE5, 0xB9, 0x4B, 0x17, 0x40, 0x0F, 0xB1, 0xB6, 0xB9, 0xF5, 0xDE, 0x4F, + 0xDC, 0xE0, 0xB3, 0xAC, 0x3B, 0x11, 0x70, 0x60, 0x84, 0x4A, 0x43, 0x6E, + 0x99, 0x20, 0xC0, 0x29, 0x71, 0x0A, 0xC0, 0x65 +}; + +static const unsigned char TA243_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA244_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x41, 0x43, 0x20, + 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, + 0x4D +}; + +static const unsigned char TA244_RSA_N[] = { + 0xBA, 0x71, 0x80, 0x7A, 0x4C, 0x86, 0x6E, 0x7F, 0xC8, 0x13, 0x6D, 0xC0, + 0xC6, 0x7D, 0x1C, 0x00, 0x97, 0x8F, 0x2C, 0x0C, 0x23, 0xBB, 0x10, 0x9A, + 0x40, 0xA9, 0x1A, 0xB7, 0x87, 0x88, 0xF8, 0x9B, 0x56, 0x6A, 0xFB, 0xE6, + 0x7B, 0x8E, 0x8B, 0x92, 0x8E, 0xA7, 0x25, 0x5D, 0x59, 0x11, 0xDB, 0x36, + 0x2E, 0xB7, 0x51, 0x17, 0x1F, 0xA9, 0x08, 0x1F, 0x04, 0x17, 0x24, 0x58, + 0xAA, 0x37, 0x4A, 0x18, 0xDF, 0xE5, 0x39, 0xD4, 0x57, 0xFD, 0xD7, 0xC1, + 0x2C, 0x91, 0x01, 0x91, 0xE2, 0x22, 0xD4, 0x03, 0xC0, 0x58, 0xFC, 0x77, + 0x47, 0xEC, 0x8F, 0x3E, 0x74, 0x43, 0xBA, 0xAC, 0x34, 0x8D, 0x4D, 0x38, + 0x76, 0x67, 0x8E, 0xB0, 0xC8, 0x6F, 0x30, 0x33, 0x58, 0x71, 0x5C, 0xB4, + 0xF5, 0x6B, 0x6E, 0xD4, 0x01, 0x50, 0xB8, 0x13, 0x7E, 0x6C, 0x4A, 0xA3, + 0x49, 0xD1, 0x20, 0x19, 0xEE, 0xBC, 0xC0, 0x29, 0x18, 0x65, 0xA7, 0xDE, + 0xFE, 0xEF, 0xDD, 0x0A, 0x90, 0x21, 0xE7, 0x1A, 0x67, 0x92, 0x42, 0x10, + 0x98, 0x5F, 0x4F, 0x30, 0xBC, 0x3E, 0x1C, 0x45, 0xB4, 0x10, 0xD7, 0x68, + 0x40, 0x14, 0xC0, 0x40, 0xFA, 0xE7, 0x77, 0x17, 0x7A, 0xE6, 0x0B, 0x8F, + 0x65, 0x5B, 0x3C, 0xD9, 0x9A, 0x52, 0xDB, 0xB5, 0xBD, 0x9E, 0x46, 0xCF, + 0x3D, 0xEB, 0x91, 0x05, 0x02, 0xC0, 0x96, 0xB2, 0x76, 0x4C, 0x4D, 0x10, + 0x96, 0x3B, 0x92, 0xFA, 0x9C, 0x7F, 0x0F, 0x99, 0xDF, 0xBE, 0x23, 0x35, + 0x45, 0x1E, 0x02, 0x5C, 0xFE, 0xB5, 0xA8, 0x9B, 0x99, 0x25, 0xDA, 0x5E, + 0xF3, 0x22, 0xC3, 0x39, 0xF5, 0xE4, 0x2A, 0x2E, 0xD3, 0xC6, 0x1F, 0xC4, + 0x6C, 0xAA, 0xC5, 0x1C, 0x6A, 0x01, 0x05, 0x4A, 0x2F, 0xD2, 0xC5, 0xC1, + 0xA8, 0x34, 0x26, 0x5D, 0x66, 0xA5, 0xD2, 0x02, 0x21, 0xF9, 0x18, 0xB7, + 0x06, 0xF5, 0x4E, 0x99, 0x6F, 0xA8, 0xAB, 0x4C, 0x51, 0xE8, 0xCF, 0x50, + 0x18, 0xC5, 0x77, 0xC8, 0x39, 0x09, 0x2C, 0x49, 0x92, 0x32, 0x99, 0xA8, + 0xBB, 0x17, 0x17, 0x79, 0xB0, 0x5A, 0xC5, 0xE6, 0xA3, 0xC4, 0x59, 0x65, + 0x47, 0x35, 0x83, 0x5E, 0xA9, 0xE8, 0x35, 0x0B, 0x99, 0xBB, 0xE4, 0xCD, + 0x20, 0xC6, 0x9B, 0x4A, 0x06, 0x39, 0xB5, 0x68, 0xFC, 0x22, 0xBA, 0xEE, + 0x55, 0x8C, 0x2B, 0x4E, 0xEA, 0xF3, 0xB1, 0xE3, 0xFC, 0xB6, 0x99, 0x9A, + 0xD5, 0x42, 0xFA, 0x71, 0x4D, 0x08, 0xCF, 0x87, 0x1E, 0x6A, 0x71, 0x7D, + 0xF9, 0xD3, 0xB4, 0xE9, 0xA5, 0x71, 0x81, 0x7B, 0xC2, 0x4E, 0x47, 0x96, + 0xA5, 0xF6, 0x76, 0x85, 0xA3, 0x28, 0x8F, 0xE9, 0x80, 0x6E, 0x81, 0x53, + 0xA5, 0x6D, 0x5F, 0xB8, 0x48, 0xF9, 0xC2, 0xF9, 0x36, 0xA6, 0x2E, 0x49, + 0xFF, 0xB8, 0x96, 0xC2, 0x8C, 0x07, 0xB3, 0x9B, 0x88, 0x58, 0xFC, 0xEB, + 0x1B, 0x1C, 0xDE, 0x2D, 0x70, 0xE2, 0x97, 0x92, 0x30, 0xA1, 0x89, 0xE3, + 0xBC, 0x55, 0xA8, 0x27, 0xD6, 0x4B, 0xED, 0x90, 0xAD, 0x8B, 0xFA, 0x63, + 0x25, 0x59, 0x2D, 0xA8, 0x35, 0xDD, 0xCA, 0x97, 0x33, 0xBC, 0xE5, 0xCD, + 0xC7, 0x9D, 0xD1, 0xEC, 0xEF, 0x5E, 0x0E, 0x4A, 0x90, 0x06, 0x26, 0x63, + 0xAD, 0xB9, 0xD9, 0x35, 0x2D, 0x07, 0xBA, 0x76, 0x65, 0x2C, 0xAC, 0x57, + 0x8F, 0x7D, 0xF4, 0x07, 0x94, 0xD7, 0x81, 0x02, 0x96, 0x5D, 0xA3, 0x07, + 0x49, 0xD5, 0x7A, 0xD0, 0x57, 0xF9, 0x1B, 0xE7, 0x53, 0x46, 0x75, 0xAA, + 0xB0, 0x79, 0x42, 0xCB, 0x68, 0x71, 0x08, 0xE9, 0x60, 0xBD, 0x39, 0x69, + 0xCE, 0xF4, 0xAF, 0xC3, 0x56, 0x40, 0xC7, 0xAD, 0x52, 0xA2, 0x09, 0xE4, + 0x6F, 0x86, 0x47, 0x8A, 0x1F, 0xEB, 0x28, 0x27, 0x5D, 0x83, 0x20, 0xAF, + 0x04, 0xC9, 0x6C, 0x56, 0x9A, 0x8B, 0x46, 0xF5 +}; + +static const unsigned char TA244_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA245_DN[] = { + 0x30, 0x78, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x0E, + 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x05, 0x43, 0x65, 0x72, + 0x65, 0x73, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, + 0x0F, 0x56, 0x41, 0x54, 0x45, 0x53, 0x2D, 0x51, 0x32, 0x38, 0x32, 0x36, + 0x30, 0x30, 0x34, 0x4A, 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x23, 0x41, 0x43, 0x20, 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, + 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x20, 0x53, 0x45, 0x52, 0x56, + 0x49, 0x44, 0x4F, 0x52, 0x45, 0x53, 0x20, 0x53, 0x45, 0x47, 0x55, 0x52, + 0x4F, 0x53 +}; + +static const unsigned char TA245_EC_Q[] = { + 0x04, 0xF6, 0xBA, 0x57, 0x53, 0xC8, 0xCA, 0xAB, 0xDF, 0x36, 0x4A, 0x52, + 0x21, 0xE4, 0x97, 0xD2, 0x83, 0x67, 0x9E, 0xF0, 0x65, 0x51, 0xD0, 0x5E, + 0x87, 0xC7, 0x47, 0xB1, 0x59, 0xF2, 0x57, 0x47, 0x9B, 0x00, 0x02, 0x93, + 0x44, 0x17, 0x69, 0xDB, 0x42, 0xC7, 0xB1, 0xB2, 0x3A, 0x18, 0x0E, 0xB4, + 0x5D, 0x8C, 0xB3, 0x66, 0x5D, 0xA1, 0x34, 0xF9, 0x36, 0x2C, 0x49, 0xDB, + 0xF3, 0x46, 0xFC, 0xB3, 0x44, 0x69, 0x44, 0x13, 0x66, 0xFD, 0xD7, 0xC5, + 0xFD, 0xAF, 0x36, 0x4D, 0xCE, 0x03, 0x4D, 0x07, 0x71, 0xCF, 0xAF, 0x6A, + 0x05, 0xD2, 0xA2, 0x43, 0x5A, 0x0A, 0x52, 0x6F, 0x01, 0x03, 0x4E, 0x8E, + 0x8B +}; + +static const unsigned char TA246_DN[] = { + 0x30, 0x81, 0x84, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x05, + 0x13, 0x09, 0x47, 0x36, 0x33, 0x32, 0x38, 0x37, 0x35, 0x31, 0x30, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, + 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1E, 0x41, + 0x4E, 0x46, 0x20, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, + 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x63, 0x69, 0x6F, 0x6E, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x13, 0x0B, 0x41, 0x4E, 0x46, 0x20, 0x43, 0x41, 0x20, 0x52, + 0x61, 0x69, 0x7A, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x19, 0x41, 0x4E, 0x46, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA246_RSA_N[] = { + 0xDB, 0xEB, 0x6B, 0x2B, 0xE6, 0x64, 0x54, 0x95, 0x82, 0x90, 0xA3, 0x72, + 0xA4, 0x19, 0x01, 0x9D, 0x9C, 0x0B, 0x81, 0x5F, 0x73, 0x49, 0xBA, 0xA7, + 0xAC, 0xF3, 0x04, 0x4E, 0x7B, 0x96, 0x0B, 0xEC, 0x11, 0xE0, 0x5B, 0xA6, + 0x1C, 0xCE, 0x1B, 0xD2, 0x0D, 0x83, 0x1C, 0x2B, 0xB8, 0x9E, 0x1D, 0x7E, + 0x45, 0x32, 0x60, 0x0F, 0x07, 0xE9, 0x77, 0x58, 0x7E, 0x9F, 0x6A, 0xC8, + 0x61, 0x4E, 0xB6, 0x26, 0xC1, 0x4C, 0x8D, 0xFF, 0x4C, 0xEF, 0x34, 0xB2, + 0x1F, 0x65, 0xD8, 0xB9, 0x78, 0xF5, 0xAD, 0xA9, 0x71, 0xB9, 0xEF, 0x4F, + 0x58, 0x1D, 0xA5, 0xDE, 0x74, 0x20, 0x97, 0xA1, 0xED, 0x68, 0x4C, 0xDE, + 0x92, 0x17, 0x4B, 0xBC, 0xAB, 0xFF, 0x65, 0x9A, 0x9E, 0xFB, 0x47, 0xD9, + 0x57, 0x72, 0xF3, 0x09, 0xA1, 0xAE, 0x76, 0x44, 0x13, 0x6E, 0x9C, 0x2D, + 0x44, 0x39, 0xBC, 0xF9, 0xC7, 0x3B, 0xA4, 0x58, 0x3D, 0x41, 0xBD, 0xB4, + 0xC2, 0x49, 0xA3, 0xC8, 0x0D, 0xD2, 0x97, 0x2F, 0x07, 0x65, 0x52, 0x00, + 0xA7, 0x6E, 0xC8, 0xAF, 0x68, 0xEC, 0xF4, 0x14, 0x96, 0xB6, 0x57, 0x1F, + 0x56, 0xC3, 0x39, 0x9F, 0x2B, 0x6D, 0xE4, 0xF3, 0x3E, 0xF6, 0x35, 0x64, + 0xDA, 0x0C, 0x1C, 0xA1, 0x84, 0x4B, 0x2F, 0x4B, 0x4B, 0xE2, 0x2C, 0x24, + 0x9D, 0x6D, 0x93, 0x40, 0xEB, 0xB5, 0x23, 0x8E, 0x32, 0xCA, 0x6F, 0x45, + 0xD3, 0xA8, 0x89, 0x7B, 0x1E, 0xCF, 0x1E, 0xFA, 0x5B, 0x43, 0x8B, 0xCD, + 0xCD, 0xA8, 0x0F, 0x6A, 0xCA, 0x0C, 0x5E, 0xB9, 0x9E, 0x47, 0x8F, 0xF0, + 0xD9, 0xB6, 0x0A, 0x0B, 0x58, 0x65, 0x17, 0x33, 0xB9, 0x23, 0xE4, 0x77, + 0x19, 0x7D, 0xCB, 0x4A, 0x2E, 0x92, 0x7B, 0x4F, 0x2F, 0x10, 0x77, 0xB1, + 0x8D, 0x2F, 0x68, 0x9C, 0x62, 0xCC, 0xE0, 0x50, 0xF8, 0xEC, 0x91, 0xA7, + 0x54, 0x4C, 0x57, 0x09, 0xD5, 0x76, 0x63, 0xC5, 0xE8, 0x65, 0x1E, 0xEE, + 0x6D, 0x6A, 0xCF, 0x09, 0x9D, 0xFA, 0x7C, 0x4F, 0xAD, 0x60, 0x08, 0xFD, + 0x56, 0x99, 0x0F, 0x15, 0x2C, 0x7B, 0xA9, 0x80, 0xAB, 0x8C, 0x61, 0x8F, + 0x4A, 0x07, 0x76, 0x42, 0xDE, 0x3D, 0xF4, 0xDD, 0xB2, 0x24, 0x33, 0x5B, + 0xB8, 0xB5, 0xA3, 0x44, 0xC9, 0xAC, 0x7F, 0x77, 0x3C, 0x1D, 0x23, 0xEC, + 0x82, 0xA9, 0xA6, 0xE2, 0xC8, 0x06, 0x4C, 0x02, 0xFE, 0xAC, 0x5C, 0x99, + 0x99, 0x0B, 0x2F, 0x10, 0x8A, 0xA6, 0xF4, 0x7F, 0xD5, 0x87, 0x74, 0x0D, + 0x59, 0x49, 0x45, 0xF6, 0xF0, 0x71, 0x5C, 0x39, 0x29, 0xD6, 0xBF, 0x4A, + 0x23, 0x8B, 0xF5, 0x5F, 0x01, 0x63, 0xD2, 0x87, 0x73, 0x28, 0xB5, 0x4B, + 0x0A, 0xF5, 0xF8, 0xAB, 0x82, 0x2C, 0x7E, 0x73, 0x25, 0x32, 0x1D, 0x0B, + 0x63, 0x0A, 0x17, 0x81, 0x00, 0xFF, 0xB6, 0x76, 0x5E, 0xE7, 0xB4, 0xB1, + 0x40, 0xCA, 0x21, 0xBB, 0xD5, 0x80, 0x51, 0xE5, 0x48, 0x52, 0x67, 0x2C, + 0xD2, 0x61, 0x89, 0x07, 0x0D, 0x0F, 0xCE, 0x42, 0x77, 0xC0, 0x44, 0x73, + 0x9C, 0x44, 0x50, 0xA0, 0xDB, 0x10, 0x0A, 0x2D, 0x95, 0x1C, 0x81, 0xAF, + 0xE4, 0x1C, 0xE5, 0x14, 0x1E, 0xF1, 0x36, 0x41, 0x01, 0x02, 0x2F, 0x7D, + 0x73, 0xA7, 0xDE, 0x42, 0xCC, 0x4C, 0xE9, 0x89, 0x0D, 0x56, 0xF7, 0x9F, + 0x91, 0xD4, 0x03, 0xC6, 0x6C, 0xC9, 0x8F, 0xDB, 0xD8, 0x1C, 0xE0, 0x40, + 0x98, 0x5D, 0x66, 0x99, 0x98, 0x80, 0x6E, 0x2D, 0xFF, 0x01, 0xC5, 0xCE, + 0xCB, 0x46, 0x1F, 0xAC, 0x02, 0xC6, 0x43, 0xE6, 0xAE, 0xA2, 0x84, 0x3C, + 0xC5, 0x4E, 0x1E, 0x3D, 0x6D, 0xC9, 0x14, 0x4C, 0xE3, 0x2E, 0x41, 0xBB, + 0xCA, 0x39, 0xBF, 0x36, 0x3C, 0x2A, 0x19, 0xAA, 0x41, 0x87, 0x4E, 0xA5, + 0xCE, 0x4B, 0x32, 0x79, 0xDD, 0x90, 0x49, 0x7F +}; + +static const unsigned char TA246_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA247_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x54, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x05, 0x4D, 0x69, 0x6C, 0x61, 0x6E, 0x31, 0x23, 0x30, 0x21, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x1A, 0x41, 0x63, 0x74, 0x61, 0x6C, 0x69, + 0x73, 0x20, 0x53, 0x2E, 0x70, 0x2E, 0x41, 0x2E, 0x2F, 0x30, 0x33, 0x33, + 0x35, 0x38, 0x35, 0x32, 0x30, 0x39, 0x36, 0x37, 0x31, 0x27, 0x30, 0x25, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x41, 0x63, 0x74, 0x61, 0x6C, + 0x69, 0x73, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA247_RSA_N[] = { + 0xA7, 0xC6, 0xC4, 0xA5, 0x29, 0xA4, 0x2C, 0xEF, 0xE5, 0x18, 0xC5, 0xB0, + 0x50, 0xA3, 0x6F, 0x51, 0x3B, 0x9F, 0x0A, 0x5A, 0xC9, 0xC2, 0x48, 0x38, + 0x0A, 0xC2, 0x1C, 0xA0, 0x18, 0x7F, 0x91, 0xB5, 0x87, 0xB9, 0x40, 0x3F, + 0xDD, 0x1D, 0x68, 0x1F, 0x08, 0x83, 0xD5, 0x2D, 0x1E, 0x88, 0xA0, 0xF8, + 0x8F, 0x56, 0x8F, 0x6D, 0x99, 0x02, 0x92, 0x90, 0x16, 0xD5, 0x5F, 0x08, + 0x6C, 0x89, 0xD7, 0xE1, 0xAC, 0xBC, 0x20, 0xC2, 0xB1, 0xE0, 0x83, 0x51, + 0x8A, 0x69, 0x4D, 0x00, 0x96, 0x5A, 0x6F, 0x2F, 0xC0, 0x44, 0x7E, 0xA3, + 0x0E, 0xE4, 0x91, 0xCD, 0x58, 0xEE, 0xDC, 0xFB, 0xC7, 0x1E, 0x45, 0x47, + 0xDD, 0x27, 0xB9, 0x08, 0x01, 0x9F, 0xA6, 0x21, 0x1D, 0xF5, 0x41, 0x2D, + 0x2F, 0x4C, 0xFD, 0x28, 0xAD, 0xE0, 0x8A, 0xAD, 0x22, 0xB4, 0x56, 0x65, + 0x8E, 0x86, 0x54, 0x8F, 0x93, 0x43, 0x29, 0xDE, 0x39, 0x46, 0x78, 0xA3, + 0x30, 0x23, 0xBA, 0xCD, 0xF0, 0x7D, 0x13, 0x57, 0xC0, 0x5D, 0xD2, 0x83, + 0x6B, 0x48, 0x4C, 0xC4, 0xAB, 0x9F, 0x80, 0x5A, 0x5B, 0x3A, 0xBD, 0xC9, + 0xA7, 0x22, 0x3F, 0x80, 0x27, 0x33, 0x5B, 0x0E, 0xB7, 0x8A, 0x0C, 0x5D, + 0x07, 0x37, 0x08, 0xCB, 0x6C, 0xD2, 0x7A, 0x47, 0x22, 0x44, 0x35, 0xC5, + 0xCC, 0xCC, 0x2E, 0x8E, 0xDD, 0x2A, 0xED, 0xB7, 0x7D, 0x66, 0x0D, 0x5F, + 0x61, 0x51, 0x22, 0x55, 0x1B, 0xE3, 0x46, 0xE3, 0xE3, 0x3D, 0xD0, 0x35, + 0x62, 0x9A, 0xDB, 0xAF, 0x14, 0xC8, 0x5B, 0xA1, 0xCC, 0x89, 0x1B, 0xE1, + 0x30, 0x26, 0xFC, 0xA0, 0x9B, 0x1F, 0x81, 0xA7, 0x47, 0x1F, 0x04, 0xEB, + 0xA3, 0x39, 0x92, 0x06, 0x9F, 0x99, 0xD3, 0xBF, 0xD3, 0xEA, 0x4F, 0x50, + 0x9C, 0x19, 0xFE, 0x96, 0x87, 0x1E, 0x3C, 0x65, 0xF6, 0xA3, 0x18, 0x24, + 0x83, 0x86, 0x10, 0xE7, 0x54, 0x3E, 0xA8, 0x3A, 0x76, 0x24, 0x4F, 0x81, + 0x21, 0xC5, 0xE3, 0x0F, 0x02, 0xF8, 0x93, 0x94, 0x47, 0x20, 0xBB, 0xFE, + 0xD4, 0x0E, 0xD3, 0x68, 0xB9, 0xDD, 0xC4, 0x7A, 0x84, 0x82, 0xE3, 0x53, + 0x54, 0x79, 0xDD, 0xDB, 0x9C, 0xD2, 0xF2, 0x07, 0x9B, 0x2E, 0xB6, 0xBC, + 0x3E, 0xED, 0x85, 0x6D, 0xEF, 0x25, 0x11, 0xF2, 0x97, 0x1A, 0x42, 0x61, + 0xF7, 0x4A, 0x97, 0xE8, 0x8B, 0xB1, 0x10, 0x07, 0xFA, 0x65, 0x81, 0xB2, + 0xA2, 0x39, 0xCF, 0xF7, 0x3C, 0xFF, 0x18, 0xFB, 0xC6, 0xF1, 0x5A, 0x8B, + 0x59, 0xE2, 0x02, 0xAC, 0x7B, 0x92, 0xD0, 0x4E, 0x14, 0x4F, 0x59, 0x45, + 0xF6, 0x0C, 0x5E, 0x28, 0x5F, 0xB0, 0xE8, 0x3F, 0x45, 0xCF, 0xCF, 0xAF, + 0x9B, 0x6F, 0xFB, 0x84, 0xD3, 0x77, 0x5A, 0x95, 0x6F, 0xAC, 0x94, 0x84, + 0x9E, 0xEE, 0xBC, 0xC0, 0x4A, 0x8F, 0x4A, 0x93, 0xF8, 0x44, 0x21, 0xE2, + 0x31, 0x45, 0x61, 0x50, 0x4E, 0x10, 0xD8, 0xE3, 0x35, 0x7C, 0x4C, 0x19, + 0xB4, 0xDE, 0x05, 0xBF, 0xA3, 0x06, 0x9F, 0xC8, 0xB5, 0xCD, 0xE4, 0x1F, + 0xD7, 0x17, 0x06, 0x0D, 0x7A, 0x95, 0x74, 0x55, 0x0D, 0x68, 0x1A, 0xFC, + 0x10, 0x1B, 0x62, 0x64, 0x9D, 0x6D, 0xE0, 0x95, 0xA0, 0xC3, 0x94, 0x07, + 0x57, 0x0D, 0x14, 0xE6, 0xBD, 0x05, 0xFB, 0xB8, 0x9F, 0xE6, 0xDF, 0x8B, + 0xE2, 0xC6, 0xE7, 0x7E, 0x96, 0xF6, 0x53, 0xC5, 0x80, 0x34, 0x50, 0x28, + 0x58, 0xF0, 0x12, 0x50, 0x71, 0x17, 0x30, 0xBA, 0xE6, 0x78, 0x63, 0xBC, + 0xF4, 0xB2, 0xAD, 0x9B, 0x2B, 0xB2, 0xFE, 0xE1, 0x39, 0x8C, 0x5E, 0xBA, + 0x0B, 0x20, 0x94, 0xDE, 0x7B, 0x83, 0xB8, 0xFF, 0xE3, 0x56, 0x8D, 0xB7, + 0x11, 0xE9, 0x3B, 0x8C, 0xF2, 0xB1, 0xC1, 0x5D, 0x9D, 0xA4, 0x0B, 0x4C, + 0x2B, 0xD9, 0xB2, 0x18, 0xF5, 0xB5, 0x9F, 0x4B +}; + +static const unsigned char TA247_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA248_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C +}; + +static const unsigned char TA248_RSA_N[] = { + 0xF6, 0x1B, 0x4F, 0x67, 0x07, 0x2B, 0xA1, 0x15, 0xF5, 0x06, 0x22, 0xCB, + 0x1F, 0x01, 0xB2, 0xE3, 0x73, 0x45, 0x06, 0x44, 0x49, 0x2C, 0xBB, 0x49, + 0x25, 0x14, 0xD6, 0xCE, 0xC3, 0xB7, 0xAB, 0x2C, 0x4F, 0xC6, 0x41, 0x32, + 0x94, 0x57, 0xFA, 0x12, 0xA7, 0x5B, 0x0E, 0xE2, 0x8F, 0x1F, 0x1E, 0x86, + 0x19, 0xA7, 0xAA, 0xB5, 0x2D, 0xB9, 0x5F, 0x0D, 0x8A, 0xC2, 0xAF, 0x85, + 0x35, 0x79, 0x32, 0x2D, 0xBB, 0x1C, 0x62, 0x37, 0xF2, 0xB1, 0x5B, 0x4A, + 0x3D, 0xCA, 0xCD, 0x71, 0x5F, 0xE9, 0x42, 0xBE, 0x94, 0xE8, 0xC8, 0xDE, + 0xF9, 0x22, 0x48, 0x64, 0xC6, 0xE5, 0xAB, 0xC6, 0x2B, 0x6D, 0xAD, 0x05, + 0xF0, 0xFA, 0xD5, 0x0B, 0xCF, 0x9A, 0xE5, 0xF0, 0x50, 0xA4, 0x8B, 0x3B, + 0x47, 0xA5, 0x23, 0x5B, 0x7A, 0x7A, 0xF8, 0x33, 0x3F, 0xB8, 0xEF, 0x99, + 0x97, 0xE3, 0x20, 0xC1, 0xD6, 0x28, 0x89, 0xCF, 0x94, 0xFB, 0xB9, 0x45, + 0xED, 0xE3, 0x40, 0x17, 0x11, 0xD4, 0x74, 0xF0, 0x0B, 0x31, 0xE2, 0x2B, + 0x26, 0x6A, 0x9B, 0x4C, 0x57, 0xAE, 0xAC, 0x20, 0x3E, 0xBA, 0x45, 0x7A, + 0x05, 0xF3, 0xBD, 0x9B, 0x69, 0x15, 0xAE, 0x7D, 0x4E, 0x20, 0x63, 0xC4, + 0x35, 0x76, 0x3A, 0x07, 0x02, 0xC9, 0x37, 0xFD, 0xC7, 0x47, 0xEE, 0xE8, + 0xF1, 0x76, 0x1D, 0x73, 0x15, 0xF2, 0x97, 0xA4, 0xB5, 0xC8, 0x7A, 0x79, + 0xD9, 0x42, 0xAA, 0x2B, 0x7F, 0x5C, 0xFE, 0xCE, 0x26, 0x4F, 0xA3, 0x66, + 0x81, 0x35, 0xAF, 0x44, 0xBA, 0x54, 0x1E, 0x1C, 0x30, 0x32, 0x65, 0x9D, + 0xE6, 0x3C, 0x93, 0x5E, 0x50, 0x4E, 0x7A, 0xE3, 0x3A, 0xD4, 0x6E, 0xCC, + 0x1A, 0xFB, 0xF9, 0xD2, 0x37, 0xAE, 0x24, 0x2A, 0xAB, 0x57, 0x03, 0x22, + 0x28, 0x0D, 0x49, 0x75, 0x7F, 0xB7, 0x28, 0xDA, 0x75, 0xBF, 0x8E, 0xE3, + 0xDC, 0x0E, 0x79, 0x31 +}; + +static const unsigned char TA248_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA249_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, 0x67 +}; + +static const unsigned char TA249_RSA_N[] = { + 0xB4, 0x84, 0xCC, 0x33, 0x17, 0x2E, 0x6B, 0x94, 0x6C, 0x6B, 0x61, 0x52, + 0xA0, 0xEB, 0xA3, 0xCF, 0x79, 0x94, 0x4C, 0xE5, 0x94, 0x80, 0x99, 0xCB, + 0x55, 0x64, 0x44, 0x65, 0x8F, 0x67, 0x64, 0xE2, 0x06, 0xE3, 0x5C, 0x37, + 0x49, 0xF6, 0x2F, 0x9B, 0x84, 0x84, 0x1E, 0x2D, 0xF2, 0x60, 0x9D, 0x30, + 0x4E, 0xCC, 0x84, 0x85, 0xE2, 0x2C, 0xCF, 0x1E, 0x9E, 0xFE, 0x36, 0xAB, + 0x33, 0x77, 0x35, 0x44, 0xD8, 0x35, 0x96, 0x1A, 0x3D, 0x36, 0xE8, 0x7A, + 0x0E, 0xD8, 0xD5, 0x47, 0xA1, 0x6A, 0x69, 0x8B, 0xD9, 0xFC, 0xBB, 0x3A, + 0xAE, 0x79, 0x5A, 0xD5, 0xF4, 0xD6, 0x71, 0xBB, 0x9A, 0x90, 0x23, 0x6B, + 0x9A, 0xB7, 0x88, 0x74, 0x87, 0x0C, 0x1E, 0x5F, 0xB9, 0x9E, 0x2D, 0xFA, + 0xAB, 0x53, 0x2B, 0xDC, 0xBB, 0x76, 0x3E, 0x93, 0x4C, 0x08, 0x08, 0x8C, + 0x1E, 0xA2, 0x23, 0x1C, 0xD4, 0x6A, 0xAD, 0x22, 0xBA, 0x99, 0x01, 0x2E, + 0x6D, 0x65, 0xCB, 0xBE, 0x24, 0x66, 0x55, 0x24, 0x4B, 0x40, 0x44, 0xB1, + 0x1B, 0xD7, 0xE1, 0xC2, 0x85, 0xC0, 0xDE, 0x10, 0x3F, 0x3D, 0xED, 0xB8, + 0xFC, 0xF1, 0xF1, 0x23, 0x53, 0xDC, 0xBF, 0x65, 0x97, 0x6F, 0xD9, 0xF9, + 0x40, 0x71, 0x8D, 0x7D, 0xBD, 0x95, 0xD4, 0xCE, 0xBE, 0xA0, 0x5E, 0x27, + 0x23, 0xDE, 0xFD, 0xA6, 0xD0, 0x26, 0x0E, 0x00, 0x29, 0xEB, 0x3C, 0x46, + 0xF0, 0x3D, 0x60, 0xBF, 0x3F, 0x50, 0xD2, 0xDC, 0x26, 0x41, 0x51, 0x9E, + 0x14, 0x37, 0x42, 0x04, 0xA3, 0x70, 0x57, 0xA8, 0x1B, 0x87, 0xED, 0x2D, + 0xFA, 0x7B, 0xEE, 0x8C, 0x0A, 0xE3, 0xA9, 0x66, 0x89, 0x19, 0xCB, 0x41, + 0xF9, 0xDD, 0x44, 0x36, 0x61, 0xCF, 0xE2, 0x77, 0x46, 0xC8, 0x7D, 0xF6, + 0xF4, 0x92, 0x81, 0x36, 0xFD, 0xDB, 0x34, 0xF1, 0x72, 0x7E, 0xF3, 0x0C, + 0x16, 0xBD, 0xB4, 0x15 +}; + +static const unsigned char TA249_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA250_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x13, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D +}; + +static const unsigned char TA250_RSA_N[] = { + 0xC4, 0x12, 0xDF, 0xA9, 0x5F, 0xFE, 0x41, 0xDD, 0xDD, 0xF5, 0x9F, 0x8A, + 0xE3, 0xF6, 0xAC, 0xE1, 0x3C, 0x78, 0x9A, 0xBC, 0xD8, 0xF0, 0x7F, 0x7A, + 0xA0, 0x33, 0x2A, 0xDC, 0x8D, 0x20, 0x5B, 0xAE, 0x2D, 0x6F, 0xE7, 0x93, + 0xD9, 0x36, 0x70, 0x6A, 0x68, 0xCF, 0x8E, 0x51, 0xA3, 0x85, 0x5B, 0x67, + 0x04, 0xA0, 0x10, 0x24, 0x6F, 0x5D, 0x28, 0x82, 0xC1, 0x97, 0x57, 0xD8, + 0x48, 0x29, 0x13, 0xB6, 0xE1, 0xBE, 0x91, 0x4D, 0xDF, 0x85, 0x0C, 0x53, + 0x18, 0x9A, 0x1E, 0x24, 0xA2, 0x4F, 0x8F, 0xF0, 0xA2, 0x85, 0x0B, 0xCB, + 0xF4, 0x29, 0x7F, 0xD2, 0xA4, 0x58, 0xEE, 0x26, 0x4D, 0xC9, 0xAA, 0xA8, + 0x7B, 0x9A, 0xD9, 0xFA, 0x38, 0xDE, 0x44, 0x57, 0x15, 0xE5, 0xF8, 0x8C, + 0xC8, 0xD9, 0x48, 0xE2, 0x0D, 0x16, 0x27, 0x1D, 0x1E, 0xC8, 0x83, 0x85, + 0x25, 0xB7, 0xBA, 0xAA, 0x55, 0x41, 0xCC, 0x03, 0x22, 0x4B, 0x2D, 0x91, + 0x8D, 0x8B, 0xE6, 0x89, 0xAF, 0x66, 0xC7, 0xE9, 0xFF, 0x2B, 0xE9, 0x3C, + 0xAC, 0xDA, 0xD2, 0xB3, 0xC3, 0xE1, 0x68, 0x9C, 0x89, 0xF8, 0x7A, 0x00, + 0x56, 0xDE, 0xF4, 0x55, 0x95, 0x6C, 0xFB, 0xBA, 0x64, 0xDD, 0x62, 0x8B, + 0xDF, 0x0B, 0x77, 0x32, 0xEB, 0x62, 0xCC, 0x26, 0x9A, 0x9B, 0xBB, 0xAA, + 0x62, 0x83, 0x4C, 0xB4, 0x06, 0x7A, 0x30, 0xC8, 0x29, 0xBF, 0xED, 0x06, + 0x4D, 0x97, 0xB9, 0x1C, 0xC4, 0x31, 0x2B, 0xD5, 0x5F, 0xBC, 0x53, 0x12, + 0x17, 0x9C, 0x99, 0x57, 0x29, 0x66, 0x77, 0x61, 0x21, 0x31, 0x07, 0x2E, + 0x25, 0x49, 0x9D, 0x18, 0xF2, 0xEE, 0xF3, 0x2B, 0x71, 0x8C, 0xB5, 0xBA, + 0x39, 0x07, 0x49, 0x77, 0xFC, 0xEF, 0x2E, 0x92, 0x90, 0x05, 0x8D, 0x2D, + 0x2F, 0x77, 0x7B, 0xEF, 0x43, 0xBF, 0x35, 0xBB, 0x9A, 0xD8, 0xF9, 0x73, + 0xA7, 0x2C, 0xF2, 0xD0, 0x57, 0xEE, 0x28, 0x4E, 0x26, 0x5F, 0x8F, 0x90, + 0x68, 0x09, 0x2F, 0xB8, 0xF8, 0xDC, 0x06, 0xE9, 0x2E, 0x9A, 0x3E, 0x51, + 0xA7, 0xD1, 0x22, 0xC4, 0x0A, 0xA7, 0x38, 0x48, 0x6C, 0xB3, 0xF9, 0xFF, + 0x7D, 0xAB, 0x86, 0x57, 0xE3, 0xBA, 0xD6, 0x85, 0x78, 0x77, 0xBA, 0x43, + 0xEA, 0x48, 0x7F, 0xF6, 0xD8, 0xBE, 0x23, 0x6D, 0x1E, 0xBF, 0xD1, 0x36, + 0x6C, 0x58, 0x5C, 0xF1, 0xEE, 0xA4, 0x19, 0x54, 0x1A, 0xF5, 0x03, 0xD2, + 0x76, 0xE6, 0xE1, 0x8C, 0xBD, 0x3C, 0xB3, 0xD3, 0x48, 0x4B, 0xE2, 0xC8, + 0xF8, 0x7F, 0x92, 0xA8, 0x76, 0x46, 0x9C, 0x42, 0x65, 0x3E, 0xA4, 0x1E, + 0xC1, 0x07, 0x03, 0x5A, 0x46, 0x2D, 0xB8, 0x97, 0xF3, 0xB7, 0xD5, 0xB2, + 0x55, 0x21, 0xEF, 0xBA, 0xDC, 0x4C, 0x00, 0x97, 0xFB, 0x14, 0x95, 0x27, + 0x33, 0xBF, 0xE8, 0x43, 0x47, 0x46, 0xD2, 0x08, 0x99, 0x16, 0x60, 0x3B, + 0x9A, 0x7E, 0xD2, 0xE6, 0xED, 0x38, 0xEA, 0xEC, 0x01, 0x1E, 0x3C, 0x48, + 0x56, 0x49, 0x09, 0xC7, 0x4C, 0x37, 0x00, 0x9E, 0x88, 0x0E, 0xC0, 0x73, + 0xE1, 0x6F, 0x66, 0xE9, 0x72, 0x47, 0x30, 0x3E, 0x10, 0xE5, 0x0B, 0x03, + 0xC9, 0x9A, 0x42, 0x00, 0x6C, 0xC5, 0x94, 0x7E, 0x61, 0xC4, 0x8A, 0xDF, + 0x7F, 0x82, 0x1A, 0x0B, 0x59, 0xC4, 0x59, 0x32, 0x77, 0xB3, 0xBC, 0x60, + 0x69, 0x56, 0x39, 0xFD, 0xB4, 0x06, 0x7B, 0x2C, 0xD6, 0x64, 0x36, 0xD9, + 0xBD, 0x48, 0xED, 0x84, 0x1F, 0x7E, 0xA5, 0x22, 0x8F, 0x2A, 0xB8, 0x42, + 0xF4, 0x82, 0xB7, 0xD4, 0x53, 0x90, 0x78, 0x4E, 0x2D, 0x1A, 0xFD, 0x81, + 0x6F, 0x44, 0xD7, 0x3B, 0x01, 0x74, 0x96, 0x42, 0xE0, 0x00, 0xE2, 0x2E, + 0x6B, 0xEA, 0xC5, 0xEE, 0x72, 0xAC, 0xBB, 0xBF, 0xFE, 0xEA, 0xAA, 0xA8, + 0xF8, 0xDC, 0xF6, 0xB2, 0x79, 0x8A, 0xB6, 0x67 +}; + +static const unsigned char TA250_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA251_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA251_EC_Q[] = { + 0x04, 0x0D, 0x30, 0x5E, 0x1B, 0x15, 0x9D, 0x03, 0xD0, 0xA1, 0x79, 0x35, + 0xB7, 0x3A, 0x3C, 0x92, 0x7A, 0xCA, 0x15, 0x1C, 0xCD, 0x62, 0xF3, 0x9C, + 0x26, 0x5C, 0x07, 0x3D, 0xE5, 0x54, 0xFA, 0xA3, 0xD6, 0xCC, 0x12, 0xEA, + 0xF4, 0x14, 0x5F, 0xE8, 0x8E, 0x19, 0xAB, 0x2F, 0x2E, 0x48, 0xE6, 0xAC, + 0x18, 0x43, 0x78, 0xAC, 0xD0, 0x37, 0xC3, 0xBD, 0xB2, 0xCD, 0x2C, 0xE6, + 0x47, 0xE2, 0x1A, 0xE6, 0x63, 0xB8, 0x3D, 0x2E, 0x2F, 0x78, 0xC4, 0x4F, + 0xDB, 0xF4, 0x0F, 0xA4, 0x68, 0x4C, 0x55, 0x72, 0x6B, 0x95, 0x1D, 0x4E, + 0x18, 0x42, 0x95, 0x78, 0xCC, 0x37, 0x3C, 0x91, 0xE2, 0x9B, 0x65, 0x2B, + 0x29 +}; + +static const unsigned char TA252_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA252_RSA_N[] = { + 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80, + 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7, + 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86, + 0xD3, 0xA0, 0x43, 0x7A, 0x4E, 0xB2, 0xA4, 0xD0, 0x36, 0xBA, 0x01, 0xBE, + 0x8D, 0xDB, 0x48, 0xC8, 0x07, 0x17, 0x36, 0x4C, 0xF4, 0xEE, 0x88, 0x23, + 0xC7, 0x3E, 0xEB, 0x37, 0xF5, 0xB5, 0x19, 0xF8, 0x49, 0x68, 0xB0, 0xDE, + 0xD7, 0xB9, 0x76, 0x38, 0x1D, 0x61, 0x9E, 0xA4, 0xFE, 0x82, 0x36, 0xA5, + 0xE5, 0x4A, 0x56, 0xE4, 0x45, 0xE1, 0xF9, 0xFD, 0xB4, 0x16, 0xFA, 0x74, + 0xDA, 0x9C, 0x9B, 0x35, 0x39, 0x2F, 0xFA, 0xB0, 0x20, 0x50, 0x06, 0x6C, + 0x7A, 0xD0, 0x80, 0xB2, 0xA6, 0xF9, 0xAF, 0xEC, 0x47, 0x19, 0x8F, 0x50, + 0x38, 0x07, 0xDC, 0xA2, 0x87, 0x39, 0x58, 0xF8, 0xBA, 0xD5, 0xA9, 0xF9, + 0x48, 0x67, 0x30, 0x96, 0xEE, 0x94, 0x78, 0x5E, 0x6F, 0x89, 0xA3, 0x51, + 0xC0, 0x30, 0x86, 0x66, 0xA1, 0x45, 0x66, 0xBA, 0x54, 0xEB, 0xA3, 0xC3, + 0x91, 0xF9, 0x48, 0xDC, 0xFF, 0xD1, 0xE8, 0x30, 0x2D, 0x7D, 0x2D, 0x74, + 0x70, 0x35, 0xD7, 0x88, 0x24, 0xF7, 0x9E, 0xC4, 0x59, 0x6E, 0xBB, 0x73, + 0x87, 0x17, 0xF2, 0x32, 0x46, 0x28, 0xB8, 0x43, 0xFA, 0xB7, 0x1D, 0xAA, + 0xCA, 0xB4, 0xF2, 0x9F, 0x24, 0x0E, 0x2D, 0x4B, 0xF7, 0x71, 0x5C, 0x5E, + 0x69, 0xFF, 0xEA, 0x95, 0x02, 0xCB, 0x38, 0x8A, 0xAE, 0x50, 0x38, 0x6F, + 0xDB, 0xFB, 0x2D, 0x62, 0x1B, 0xC5, 0xC7, 0x1E, 0x54, 0xE1, 0x77, 0xE0, + 0x67, 0xC8, 0x0F, 0x9C, 0x87, 0x23, 0xD6, 0x3F, 0x40, 0x20, 0x7F, 0x20, + 0x80, 0xC4, 0x80, 0x4C, 0x3E, 0x3B, 0x24, 0x26, 0x8E, 0x04, 0xAE, 0x6C, + 0x9A, 0xC8, 0xAA, 0x0D +}; + +static const unsigned char TA252_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA253_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA253_RSA_N[] = { + 0xAD, 0x96, 0x9F, 0x2D, 0x9C, 0x4A, 0x4C, 0x4A, 0x81, 0x79, 0x51, 0x99, + 0xEC, 0x8A, 0xCB, 0x6B, 0x60, 0x51, 0x13, 0xBC, 0x4D, 0x6D, 0x06, 0xFC, + 0xB0, 0x08, 0x8D, 0xDD, 0x19, 0x10, 0x6A, 0xC7, 0x26, 0x0C, 0x35, 0xD8, + 0xC0, 0x6F, 0x20, 0x84, 0xE9, 0x94, 0xB1, 0x9B, 0x85, 0x03, 0xC3, 0x5B, + 0xDB, 0x4A, 0xE8, 0xC8, 0xF8, 0x90, 0x76, 0xD9, 0x5B, 0x4F, 0xE3, 0x4C, + 0xE8, 0x06, 0x36, 0x4D, 0xCC, 0x9A, 0xAC, 0x3D, 0x0C, 0x90, 0x2B, 0x92, + 0xD4, 0x06, 0x19, 0x60, 0xAC, 0x37, 0x44, 0x79, 0x85, 0x81, 0x82, 0xAD, + 0x5A, 0x37, 0xE0, 0x0D, 0xCC, 0x9D, 0xA6, 0x4C, 0x52, 0x76, 0xEA, 0x43, + 0x9D, 0xB7, 0x04, 0xD1, 0x50, 0xF6, 0x55, 0xE0, 0xD5, 0xD2, 0xA6, 0x49, + 0x85, 0xE9, 0x37, 0xE9, 0xCA, 0x7E, 0xAE, 0x5C, 0x95, 0x4D, 0x48, 0x9A, + 0x3F, 0xAE, 0x20, 0x5A, 0x6D, 0x88, 0x95, 0xD9, 0x34, 0xB8, 0x52, 0x1A, + 0x43, 0x90, 0xB0, 0xBF, 0x6C, 0x05, 0xB9, 0xB6, 0x78, 0xB7, 0xEA, 0xD0, + 0xE4, 0x3A, 0x3C, 0x12, 0x53, 0x62, 0xFF, 0x4A, 0xF2, 0x7B, 0xBE, 0x35, + 0x05, 0xA9, 0x12, 0x34, 0xE3, 0xF3, 0x64, 0x74, 0x62, 0x2C, 0x3D, 0x00, + 0x49, 0x5A, 0x28, 0xFE, 0x32, 0x44, 0xBB, 0x87, 0xDD, 0x65, 0x27, 0x02, + 0x71, 0x3B, 0xDA, 0x4A, 0xF7, 0x1F, 0xDA, 0xCD, 0xF7, 0x21, 0x55, 0x90, + 0x4F, 0x0F, 0xEC, 0xAE, 0x82, 0xE1, 0x9F, 0x6B, 0xD9, 0x45, 0xD3, 0xBB, + 0xF0, 0x5F, 0x87, 0xED, 0x3C, 0x2C, 0x39, 0x86, 0xDA, 0x3F, 0xDE, 0xEC, + 0x72, 0x55, 0xEB, 0x79, 0xA3, 0xAD, 0xDB, 0xDD, 0x7C, 0xB0, 0xBA, 0x1C, + 0xCE, 0xFC, 0xDE, 0x4F, 0x35, 0x76, 0xCF, 0x0F, 0xF8, 0x78, 0x1F, 0x6A, + 0x36, 0x51, 0x46, 0x27, 0x61, 0x5B, 0xE9, 0x9E, 0xCF, 0xF0, 0xA2, 0x55, + 0x7D, 0x7C, 0x25, 0x8A, 0x6F, 0x2F, 0xB4, 0xC5, 0xCF, 0x84, 0x2E, 0x2B, + 0xFD, 0x0D, 0x51, 0x10, 0x6C, 0xFB, 0x5F, 0x1B, 0xBC, 0x1B, 0x7E, 0xC5, + 0xAE, 0x3B, 0x98, 0x01, 0x31, 0x92, 0xFF, 0x0B, 0x57, 0xF4, 0x9A, 0xB2, + 0xB9, 0x57, 0xE9, 0xAB, 0xEF, 0x0D, 0x76, 0xD1, 0xF0, 0xEE, 0xF4, 0xCE, + 0x86, 0xA7, 0xE0, 0x6E, 0xE9, 0xB4, 0x69, 0xA1, 0xDF, 0x69, 0xF6, 0x33, + 0xC6, 0x69, 0x2E, 0x97, 0x13, 0x9E, 0xA5, 0x87, 0xB0, 0x57, 0x10, 0x81, + 0x37, 0xC9, 0x53, 0xB3, 0xBB, 0x7F, 0xF6, 0x92, 0xD1, 0x9C, 0xD0, 0x18, + 0xF4, 0x92, 0x6E, 0xDA, 0x83, 0x4F, 0xA6, 0x63, 0x99, 0x4C, 0xA5, 0xFB, + 0x5E, 0xEF, 0x21, 0x64, 0x7A, 0x20, 0x5F, 0x6C, 0x64, 0x85, 0x15, 0xCB, + 0x37, 0xE9, 0x62, 0x0C, 0x0B, 0x2A, 0x16, 0xDC, 0x01, 0x2E, 0x32, 0xDA, + 0x3E, 0x4B, 0xF5, 0x9E, 0x3A, 0xF6, 0x17, 0x40, 0x94, 0xEF, 0x9E, 0x91, + 0x08, 0x86, 0xFA, 0xBE, 0x63, 0xA8, 0x5A, 0x33, 0xEC, 0xCB, 0x74, 0x43, + 0x95, 0xF9, 0x6C, 0x69, 0x52, 0x36, 0xC7, 0x29, 0x6F, 0xFC, 0x55, 0x03, + 0x5C, 0x1F, 0xFB, 0x9F, 0xBD, 0x47, 0xEB, 0xE7, 0x49, 0x47, 0x95, 0x0B, + 0x4E, 0x89, 0x22, 0x09, 0x49, 0xE0, 0xF5, 0x61, 0x1E, 0xF1, 0xBF, 0x2E, + 0x8A, 0x72, 0x6E, 0x80, 0x59, 0xFF, 0x57, 0x3A, 0xF9, 0x75, 0x32, 0xA3, + 0x4E, 0x5F, 0xEC, 0xED, 0x28, 0x62, 0xD9, 0x4D, 0x73, 0xF2, 0xCC, 0x81, + 0x17, 0x60, 0xED, 0xCD, 0xEB, 0xDC, 0xDB, 0xA7, 0xCA, 0xC5, 0x7E, 0x02, + 0xBD, 0xF2, 0x54, 0x08, 0x54, 0xFD, 0xB4, 0x2D, 0x09, 0x2C, 0x17, 0x54, + 0x4A, 0x98, 0xD1, 0x54, 0xE1, 0x51, 0x67, 0x08, 0xD2, 0xED, 0x6E, 0x7E, + 0x6F, 0x3F, 0xD2, 0x2D, 0x81, 0x59, 0x29, 0x66, 0xCB, 0x90, 0x39, 0x95, + 0x11, 0x1E, 0x74, 0x27, 0xFE, 0xDD, 0xEB, 0xAF +}; + +static const unsigned char TA253_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA254_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA254_EC_Q[] = { + 0x04, 0x29, 0x97, 0xA7, 0xC6, 0x41, 0x7F, 0xC0, 0x0D, 0x9B, 0xE8, 0x01, + 0x1B, 0x56, 0xC6, 0xF2, 0x52, 0xA5, 0xBA, 0x2D, 0xB2, 0x12, 0xE8, 0xD2, + 0x2E, 0xD7, 0xFA, 0xC9, 0xC5, 0xD8, 0xAA, 0x6D, 0x1F, 0x73, 0x81, 0x3B, + 0x3B, 0x98, 0x6B, 0x39, 0x7C, 0x33, 0xA5, 0xC5, 0x4E, 0x86, 0x8E, 0x80, + 0x17, 0x68, 0x62, 0x45, 0x57, 0x7D, 0x44, 0x58, 0x1D, 0xB3, 0x37, 0xE5, + 0x67, 0x08, 0xEB, 0x66, 0xDE +}; + +static const unsigned char TA255_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x34 +}; + +static const unsigned char TA255_EC_Q[] = { + 0x04, 0xD2, 0xAB, 0x8A, 0x37, 0x4F, 0xA3, 0x53, 0x0D, 0xFE, 0xC1, 0x8A, + 0x7B, 0x4B, 0xA8, 0x7B, 0x46, 0x4B, 0x63, 0xB0, 0x62, 0xF6, 0x2D, 0x1B, + 0xDB, 0x08, 0x71, 0x21, 0xD2, 0x00, 0xE8, 0x63, 0xBD, 0x9A, 0x27, 0xFB, + 0xF0, 0x39, 0x6E, 0x5D, 0xEA, 0x3D, 0xA5, 0xC9, 0x81, 0xAA, 0xA3, 0x5B, + 0x20, 0x98, 0x45, 0x5D, 0x16, 0xDB, 0xFD, 0xE8, 0x10, 0x6D, 0xE3, 0x9C, + 0xE0, 0xE3, 0xBD, 0x5F, 0x84, 0x62, 0xF3, 0x70, 0x64, 0x33, 0xA0, 0xCB, + 0x24, 0x2F, 0x70, 0xBA, 0x88, 0xA1, 0x2A, 0xA0, 0x75, 0xF8, 0x81, 0xAE, + 0x62, 0x06, 0xC4, 0x81, 0xDB, 0x39, 0x6E, 0x29, 0xB0, 0x1E, 0xFA, 0x2E, + 0x5C +}; + +static const unsigned char TA256_DN[] = { + 0x30, 0x3C, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x15, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x0D, + 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x04, 0x41, 0x74, 0x6F, + 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x44, 0x45 +}; + +static const unsigned char TA256_RSA_N[] = { + 0x95, 0x85, 0x3B, 0x97, 0x6F, 0x2A, 0x3B, 0x2E, 0x3B, 0xCF, 0xA6, 0xF3, + 0x29, 0x35, 0xBE, 0xCF, 0x18, 0xAC, 0x3E, 0xAA, 0xD9, 0xF8, 0x4D, 0xA0, + 0x3E, 0x1A, 0x47, 0xB9, 0xBC, 0x9A, 0xDF, 0xF2, 0xFE, 0xCC, 0x3E, 0x47, + 0xE8, 0x7A, 0x96, 0xC2, 0x24, 0x8E, 0x35, 0xF4, 0xA9, 0x0C, 0xFC, 0x82, + 0xFD, 0x6D, 0xC1, 0x72, 0x62, 0x27, 0xBD, 0xEA, 0x6B, 0xEB, 0xE7, 0x8A, + 0xCC, 0x54, 0x3E, 0x90, 0x50, 0xCF, 0x80, 0xD4, 0x95, 0xFB, 0xE8, 0xB5, + 0x82, 0xD4, 0x14, 0xC5, 0xB6, 0xA9, 0x55, 0x25, 0x57, 0xDB, 0xB1, 0x50, + 0xF6, 0xB0, 0x60, 0x64, 0x59, 0x7A, 0x69, 0xCF, 0x03, 0xB7, 0x6F, 0x0D, + 0xBE, 0xCA, 0x3E, 0x6F, 0x74, 0x72, 0xEA, 0xAA, 0x30, 0x2A, 0x73, 0x62, + 0xBE, 0x49, 0x91, 0x61, 0xC8, 0x11, 0xFE, 0x0E, 0x03, 0x2A, 0xF7, 0x6A, + 0x20, 0xDC, 0x02, 0x15, 0x0D, 0x5E, 0x15, 0x6A, 0xFC, 0xE3, 0x82, 0xC1, + 0xB5, 0xC5, 0x9D, 0x64, 0x09, 0x6C, 0xA3, 0x59, 0x98, 0x07, 0x27, 0xC7, + 0x1B, 0x96, 0x2B, 0x61, 0x74, 0x71, 0x6C, 0x43, 0xF1, 0xF7, 0x35, 0x89, + 0x10, 0xE0, 0x9E, 0xEC, 0x55, 0xA1, 0x37, 0x22, 0xA2, 0x87, 0x04, 0x05, + 0x2C, 0x47, 0x7D, 0xB4, 0x1C, 0xB9, 0x62, 0x29, 0x66, 0x28, 0xCA, 0xB7, + 0xE1, 0x93, 0xF5, 0xA4, 0x94, 0x03, 0x99, 0xB9, 0x70, 0x85, 0xB5, 0xE6, + 0x48, 0xEA, 0x8D, 0x50, 0xFC, 0xD9, 0xDE, 0xCC, 0x6F, 0x07, 0x0E, 0xDD, + 0x0B, 0x72, 0x9D, 0x80, 0x30, 0x16, 0x07, 0x95, 0x3F, 0x28, 0x0E, 0xFD, + 0xC5, 0x75, 0x4F, 0x53, 0xD6, 0x74, 0x9A, 0xB4, 0x24, 0x2E, 0x8E, 0x02, + 0x91, 0xCF, 0x76, 0xC5, 0x9B, 0x1E, 0x55, 0x74, 0x9C, 0x78, 0x21, 0xB1, + 0xF0, 0x2D, 0xF1, 0x0B, 0x9F, 0xC2, 0xD5, 0x96, 0x18, 0x1F, 0xF0, 0x54, + 0x22, 0x7A, 0x8C, 0x07 +}; + +static const unsigned char TA256_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA257_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x45, 0x43, 0x43, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA257_EC_Q[] = { + 0x04, 0x96, 0x86, 0x58, 0x28, 0x37, 0x0A, 0x67, 0xD0, 0xA0, 0xDE, 0x24, + 0x19, 0x19, 0xE1, 0xE4, 0x05, 0x07, 0x1F, 0x97, 0xED, 0xE8, 0x64, 0x82, + 0xB9, 0xF6, 0xC4, 0x71, 0x50, 0xCE, 0x8A, 0x0C, 0xFF, 0xD7, 0xB5, 0x76, + 0xBB, 0xA1, 0x6C, 0x93, 0x6C, 0x83, 0xA2, 0x68, 0x6E, 0xA5, 0xD9, 0xBE, + 0x2C, 0x88, 0x95, 0x41, 0xCD, 0x5D, 0xDD, 0xB1, 0xCA, 0x83, 0x63, 0x83, + 0xCC, 0xC0, 0xBE, 0x74, 0xD9, 0xE0, 0x9D, 0xA4, 0xEE, 0x4A, 0x4E, 0x56, + 0xE0, 0x98, 0x29, 0x41, 0x93, 0x52, 0x10, 0xD5, 0x24, 0x38, 0x02, 0x32, + 0x67, 0xF1, 0x94, 0x12, 0x6F, 0xEF, 0xD7, 0xC5, 0xDE, 0x2E, 0xFD, 0x19, + 0x80 +}; + +static const unsigned char TA258_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA258_RSA_N[] = { + 0xB6, 0x80, 0x0E, 0xC4, 0x79, 0xBD, 0x05, 0x8C, 0x7D, 0xB0, 0xA3, 0x9D, + 0x4D, 0x22, 0x4D, 0xCB, 0xF0, 0x41, 0x97, 0x4D, 0x59, 0xE0, 0xD1, 0xFE, + 0x56, 0x8C, 0x97, 0xF2, 0xD7, 0xBD, 0x8F, 0x6C, 0xB7, 0x23, 0x8F, 0x5F, + 0xD5, 0xC4, 0xD8, 0x41, 0xCB, 0xF2, 0x02, 0x1E, 0x71, 0xE5, 0xE9, 0xF6, + 0x5E, 0xCB, 0x08, 0x2A, 0x5E, 0x30, 0xF2, 0x2D, 0x66, 0xC7, 0x84, 0x1B, + 0x64, 0x57, 0x38, 0x9D, 0x75, 0x2D, 0x56, 0xC6, 0x2F, 0x61, 0xEF, 0x96, + 0xFC, 0x20, 0x46, 0xBD, 0xEB, 0xD4, 0x7B, 0x3F, 0x3F, 0x7C, 0x47, 0x38, + 0x04, 0xA9, 0x1B, 0xAA, 0x52, 0xDF, 0x13, 0x37, 0xD3, 0x15, 0x15, 0x4E, + 0xBD, 0x5F, 0x7C, 0xAF, 0xAD, 0x63, 0xC7, 0x79, 0xDC, 0x08, 0x7B, 0xD5, + 0xA0, 0xE5, 0xF7, 0x5B, 0x75, 0xAC, 0x80, 0x55, 0x99, 0x92, 0x61, 0x9B, + 0xCD, 0x2A, 0x17, 0x7D, 0xDB, 0x8F, 0xF4, 0xB5, 0x6A, 0xEA, 0x17, 0x4A, + 0x64, 0x28, 0x66, 0x15, 0x29, 0x6C, 0x02, 0xF1, 0x6B, 0xD5, 0xBA, 0xA3, + 0x33, 0xDC, 0x5A, 0x67, 0xA7, 0x05, 0xE2, 0xBF, 0x65, 0xB6, 0x16, 0xB0, + 0x10, 0xED, 0xCD, 0x50, 0x33, 0xC9, 0x70, 0x50, 0xEC, 0x19, 0x8E, 0xB0, + 0xC7, 0xF2, 0x74, 0x5B, 0x6B, 0x44, 0xC6, 0x7D, 0x96, 0xB9, 0x98, 0x08, + 0x59, 0x66, 0xDE, 0x29, 0x01, 0x9B, 0xF4, 0x2A, 0x6D, 0xD3, 0x15, 0x3A, + 0x90, 0x6A, 0x67, 0xF1, 0xB4, 0x6B, 0x66, 0xD9, 0x21, 0xEB, 0xCA, 0xD9, + 0x62, 0x7C, 0x46, 0x10, 0x5C, 0xDE, 0x75, 0x49, 0x67, 0x9E, 0x42, 0xF9, + 0xFE, 0x75, 0xA9, 0xA3, 0xAD, 0xFF, 0x76, 0x0A, 0x67, 0x40, 0xE3, 0xC5, + 0xF7, 0x8D, 0xC7, 0x85, 0x9A, 0x59, 0x9E, 0x62, 0x9A, 0x6A, 0xED, 0x45, + 0x87, 0x98, 0x67, 0xB2, 0xD5, 0x4A, 0x3C, 0xD7, 0xB4, 0x3B, 0x00, 0x0D, + 0xC0, 0x8F, 0x1F, 0xE1, 0x40, 0xC4, 0xAE, 0x6C, 0x21, 0xDC, 0x49, 0x7E, + 0x7E, 0xCA, 0xB2, 0x8D, 0x6D, 0xB6, 0xBF, 0x93, 0x2F, 0xA1, 0x5C, 0x3E, + 0x8F, 0xCA, 0xED, 0x80, 0x8E, 0x58, 0xE1, 0xDB, 0x57, 0xCF, 0x85, 0x36, + 0x38, 0xB2, 0x71, 0xA4, 0x09, 0x8C, 0x92, 0x89, 0x08, 0x88, 0x48, 0xF1, + 0x40, 0x63, 0x18, 0xB2, 0x5B, 0x8C, 0x5A, 0xE3, 0xC3, 0xD3, 0x17, 0xAA, + 0xAB, 0x19, 0xA3, 0x2C, 0x1B, 0xE4, 0xD5, 0xC6, 0xE2, 0x66, 0x7A, 0xD7, + 0x82, 0x19, 0xA6, 0x3B, 0x16, 0x2C, 0x2F, 0x71, 0x87, 0x5F, 0x45, 0x9E, + 0x95, 0x73, 0x93, 0xC2, 0x42, 0x81, 0x21, 0x13, 0x96, 0xD7, 0x9D, 0xBB, + 0x93, 0x68, 0x15, 0xFA, 0x9D, 0xA4, 0x1D, 0x8C, 0xF2, 0x81, 0xE0, 0x58, + 0x06, 0xBD, 0xC9, 0xB6, 0xE3, 0xF6, 0x89, 0x5D, 0x89, 0xF9, 0xAC, 0x44, + 0xA1, 0xCB, 0x6B, 0xFA, 0x16, 0xF1, 0xC7, 0x50, 0x3D, 0x24, 0xDA, 0xF7, + 0xC3, 0xE4, 0x87, 0xD5, 0x56, 0xF1, 0x4F, 0x90, 0x30, 0xFA, 0x45, 0x09, + 0x59, 0xDA, 0x34, 0xCE, 0xE0, 0x13, 0x1C, 0x04, 0x7C, 0x00, 0xD4, 0x9B, + 0x86, 0xA4, 0x40, 0xBC, 0xD9, 0xDC, 0x4C, 0x57, 0x7E, 0xAE, 0xB7, 0x33, + 0xB6, 0x5E, 0x76, 0xE1, 0x65, 0x8B, 0x66, 0xDF, 0x8D, 0xCA, 0xD7, 0x98, + 0xAF, 0xCE, 0x36, 0x98, 0x8C, 0x9C, 0x83, 0x99, 0x03, 0x70, 0xF3, 0xAF, + 0x74, 0xED, 0xC6, 0x0E, 0x36, 0xE7, 0xBD, 0xEC, 0xC1, 0x73, 0xA7, 0x94, + 0x5A, 0xCB, 0x92, 0x64, 0x82, 0xA6, 0x00, 0xC1, 0x70, 0xA1, 0x6E, 0x2C, + 0x29, 0xE1, 0x58, 0x57, 0xEC, 0x5A, 0x7C, 0x99, 0x6B, 0x25, 0xA4, 0x90, + 0x3A, 0x80, 0xF4, 0x20, 0x9D, 0x9A, 0xCE, 0xC7, 0x2D, 0xF9, 0xB2, 0x4B, + 0x29, 0x95, 0x83, 0xE9, 0x35, 0x8D, 0xA7, 0x49, 0x48, 0xA7, 0x0F, 0x4C, + 0x19, 0x91, 0xD0, 0xF5, 0xBF, 0x10, 0xE0, 0x71 +}; + +static const unsigned char TA258_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA259_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x39, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, 0x20, + 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x63, 0x69, 0x6F, 0x6E, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, + 0x6F, 0x66, 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x43, 0x49, + 0x46, 0x20, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38 +}; + +static const unsigned char TA259_RSA_N[] = { + 0xCA, 0x96, 0x6B, 0x8E, 0xEA, 0xF8, 0xFB, 0xF1, 0xA2, 0x35, 0xE0, 0x7F, + 0x4C, 0xDA, 0xE0, 0xC3, 0x52, 0xD7, 0x7D, 0xB6, 0x10, 0xC8, 0x02, 0x5E, + 0xB3, 0x43, 0x2A, 0xC4, 0x4F, 0x6A, 0xB2, 0xCA, 0x1C, 0x5D, 0x28, 0x9A, + 0x78, 0x11, 0x1A, 0x69, 0x59, 0x57, 0xAF, 0xB5, 0x20, 0x42, 0xE4, 0x8B, + 0x0F, 0xE6, 0xDF, 0x5B, 0xA6, 0x03, 0x92, 0x2F, 0xF5, 0x11, 0xE4, 0x62, + 0xD7, 0x32, 0x71, 0x38, 0xD9, 0x04, 0x0C, 0x71, 0xAB, 0x3D, 0x51, 0x7E, + 0x0F, 0x07, 0xDF, 0x63, 0x05, 0x5C, 0xE9, 0xBF, 0x94, 0x6F, 0xC1, 0x29, + 0x82, 0xC0, 0xB4, 0xDA, 0x51, 0xB0, 0xC1, 0x3C, 0xBB, 0xAD, 0x37, 0x4A, + 0x5C, 0xCA, 0xF1, 0x4B, 0x36, 0x0E, 0x24, 0xAB, 0xBF, 0xC3, 0x84, 0x77, + 0xFD, 0xA8, 0x50, 0xF4, 0xB1, 0xE7, 0xC6, 0x2F, 0xD2, 0x2D, 0x59, 0x8D, + 0x7A, 0x0A, 0x4E, 0x96, 0x69, 0x52, 0x02, 0xAA, 0x36, 0x98, 0xEC, 0xFC, + 0xFA, 0x14, 0x83, 0x0C, 0x37, 0x1F, 0xC9, 0x92, 0x37, 0x7F, 0xD7, 0x81, + 0x2D, 0xE5, 0xC4, 0xB9, 0xE0, 0x3E, 0x34, 0xFE, 0x67, 0xF4, 0x3E, 0x66, + 0xD1, 0xD3, 0xF4, 0x40, 0xCF, 0x5E, 0x62, 0x34, 0x0F, 0x70, 0x06, 0x3E, + 0x20, 0x18, 0x5A, 0xCE, 0xF7, 0x72, 0x1B, 0x25, 0x6C, 0x93, 0x74, 0x14, + 0x93, 0xA3, 0x73, 0xB1, 0x0E, 0xAA, 0x87, 0x10, 0x23, 0x59, 0x5F, 0x20, + 0x05, 0x19, 0x47, 0xED, 0x68, 0x8E, 0x92, 0x12, 0xCA, 0x5D, 0xFC, 0xD6, + 0x2B, 0xB2, 0x92, 0x3C, 0x20, 0xCF, 0xE1, 0x5F, 0xAF, 0x20, 0xBE, 0xA0, + 0x76, 0x7F, 0x76, 0xE5, 0xEC, 0x1A, 0x86, 0x61, 0x33, 0x3E, 0xE7, 0x7B, + 0xB4, 0x3F, 0xA0, 0x0F, 0x8E, 0xA2, 0xB9, 0x6A, 0x6F, 0xB9, 0x87, 0x26, + 0x6F, 0x41, 0x6C, 0x88, 0xA6, 0x50, 0xFD, 0x6A, 0x63, 0x0B, 0xF5, 0x93, + 0x16, 0x1B, 0x19, 0x8F, 0xB2, 0xED, 0x9B, 0x9B, 0xC9, 0x90, 0xF5, 0x01, + 0x0C, 0xDF, 0x19, 0x3D, 0x0F, 0x3E, 0x38, 0x23, 0xC9, 0x2F, 0x8F, 0x0C, + 0xD1, 0x02, 0xFE, 0x1B, 0x55, 0xD6, 0x4E, 0xD0, 0x8D, 0x3C, 0xAF, 0x4F, + 0xA4, 0xF3, 0xFE, 0xAF, 0x2A, 0xD3, 0x05, 0x9D, 0x79, 0x08, 0xA1, 0xCB, + 0x57, 0x31, 0xB4, 0x9C, 0xC8, 0x90, 0xB2, 0x67, 0xF4, 0x18, 0x16, 0x93, + 0x3A, 0xFC, 0x47, 0xD8, 0xD1, 0x78, 0x96, 0x31, 0x1F, 0xBA, 0x2B, 0x0C, + 0x5F, 0x5D, 0x99, 0xAD, 0x63, 0x89, 0x5A, 0x24, 0x20, 0x76, 0xD8, 0xDF, + 0xFD, 0xAB, 0x4E, 0xA6, 0x22, 0xAA, 0x9D, 0x5E, 0xE6, 0x27, 0x8A, 0x7D, + 0x68, 0x29, 0xA3, 0xE7, 0x8A, 0xB8, 0xDA, 0x11, 0xBB, 0x17, 0x2D, 0x99, + 0x9D, 0x13, 0x24, 0x46, 0xF7, 0xC5, 0xE2, 0xD8, 0x9F, 0x8E, 0x7F, 0xC7, + 0x8F, 0x74, 0x6D, 0x5A, 0xB2, 0xE8, 0x72, 0xF5, 0xAC, 0xEE, 0x24, 0x10, + 0xAD, 0x2F, 0x14, 0xDA, 0xFF, 0x2D, 0x9A, 0x46, 0x71, 0x47, 0xBE, 0x42, + 0xDF, 0xBB, 0x01, 0xDB, 0xF4, 0x7F, 0xD3, 0x28, 0x8F, 0x31, 0x59, 0x5B, + 0xD3, 0xC9, 0x02, 0xA6, 0xB4, 0x52, 0xCA, 0x6E, 0x97, 0xFB, 0x43, 0xC5, + 0x08, 0x26, 0x6F, 0x8A, 0xF4, 0xBB, 0xFD, 0x9F, 0x28, 0xAA, 0x0D, 0xD5, + 0x45, 0xF3, 0x13, 0x3A, 0x1D, 0xD8, 0xC0, 0x78, 0x8F, 0x41, 0x67, 0x3C, + 0x1E, 0x94, 0x64, 0xAE, 0x7B, 0x0B, 0xC5, 0xE8, 0xD9, 0x01, 0x88, 0x39, + 0x1A, 0x97, 0x86, 0x64, 0x41, 0xD5, 0x3B, 0x87, 0x0C, 0x6E, 0xFA, 0x0F, + 0xC6, 0xBD, 0x48, 0x14, 0xBF, 0x39, 0x4D, 0xD4, 0x9E, 0x41, 0xB6, 0x8F, + 0x96, 0x1D, 0x63, 0x96, 0x93, 0xD9, 0x95, 0x06, 0x78, 0x31, 0x68, 0x9E, + 0x37, 0x06, 0x3B, 0x80, 0x89, 0x45, 0x61, 0x39, 0x23, 0xC7, 0x1B, 0x44, + 0xA3, 0x15, 0xE5, 0x1C, 0xF8, 0x92, 0x30, 0xBB +}; + +static const unsigned char TA259_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA260_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x31 +}; + +static const unsigned char TA260_RSA_N[] = { + 0xF1, 0x66, 0x08, 0xBD, 0xD9, 0xC5, 0x15, 0x61, 0xCB, 0x84, 0x04, 0x41, + 0xA5, 0x69, 0x37, 0x77, 0x1D, 0xC1, 0xB0, 0x7B, 0xFA, 0xC3, 0x77, 0x48, + 0x90, 0x13, 0x72, 0x64, 0xD1, 0xB8, 0x7C, 0x90, 0x35, 0x9D, 0x18, 0x79, + 0x88, 0xE3, 0x97, 0x01, 0x3C, 0x47, 0x81, 0xF2, 0x0E, 0xA2, 0x98, 0x0D, + 0x9E, 0x3F, 0x37, 0xE0, 0x19, 0xB2, 0x90, 0xF2, 0x46, 0x1C, 0x92, 0xB1, + 0x3A, 0x61, 0xCE, 0xFA, 0xB7, 0x46, 0x9E, 0x03, 0x86, 0xD7, 0x33, 0x6E, + 0xED, 0xF7, 0x45, 0x8C, 0x76, 0x37, 0xDE, 0x6E, 0x96, 0x91, 0xF7, 0xD7, + 0x7E, 0x2B, 0x87, 0x17, 0xD5, 0x8B, 0x35, 0xEE, 0x84, 0x91, 0x72, 0x57, + 0xDC, 0x60, 0xC3, 0xC3, 0xB9, 0xE7, 0xC7, 0x67, 0x24, 0x23, 0x4F, 0x63, + 0x0A, 0x63, 0xF6, 0x66, 0x7D, 0x4B, 0x55, 0xA7, 0x3F, 0x78, 0x64, 0x49, + 0x69, 0x12, 0x97, 0xE0, 0x4C, 0x0D, 0xD3, 0x09, 0xA0, 0x32, 0x30, 0x3A, + 0xFA, 0x9F, 0xC0, 0xF2, 0x9C, 0xC5, 0x12, 0x2A, 0x2E, 0x1C, 0xB5, 0x04, + 0x33, 0xDA, 0xA4, 0x38, 0x11, 0x6A, 0xDE, 0xC6, 0x18, 0xF6, 0x47, 0x3A, + 0x22, 0x41, 0x87, 0x22, 0xFC, 0xC4, 0x89, 0x28, 0x54, 0xD8, 0x8C, 0xA5, + 0x30, 0x0A, 0xF8, 0x17, 0x16, 0xCA, 0xAC, 0x37, 0xFD, 0x79, 0xA7, 0x91, + 0x17, 0x78, 0x38, 0x99, 0xAD, 0x58, 0xED, 0xB2, 0xDE, 0xCC, 0x89, 0x7D, + 0x03, 0x9C, 0xB3, 0x89, 0x65, 0xE7, 0xE3, 0x3B, 0xB1, 0x22, 0x86, 0x8F, + 0x06, 0x6D, 0x78, 0x07, 0xFD, 0x91, 0x12, 0x7F, 0xB0, 0x6B, 0x1C, 0x89, + 0x0D, 0xF9, 0xB8, 0xCB, 0x74, 0x5B, 0x07, 0xC2, 0xC8, 0xF4, 0x35, 0xD1, + 0x64, 0x63, 0x7A, 0xE9, 0x6E, 0x9A, 0x28, 0xD6, 0x30, 0xBD, 0xE6, 0x1B, + 0xDD, 0x15, 0xAF, 0x84, 0xEA, 0x9C, 0xC7, 0xCA, 0xF5, 0x0E, 0xEA, 0xF2, + 0x5D, 0x29, 0x87, 0x8F, 0x69, 0x73, 0x39, 0xBE, 0x2E, 0x24, 0x6F, 0x45, + 0x21, 0xAC, 0xC5, 0xD4, 0x69, 0x25, 0x06, 0x83, 0xAD, 0x7A, 0x48, 0x85, + 0x13, 0x2C, 0x0D, 0x06, 0xB8, 0x6C, 0x79, 0x56, 0xFC, 0xA3, 0x67, 0x32, + 0x81, 0xF5, 0x57, 0xA5, 0xCA, 0x57, 0x42, 0x69, 0xE9, 0x5C, 0x24, 0x61, + 0xEF, 0xE2, 0x30, 0x18, 0x4E, 0x44, 0x98, 0x55, 0x6F, 0x7A, 0xC2, 0x93, + 0xD8, 0x19, 0xB6, 0xDE, 0x7C, 0x47, 0x8A, 0x11, 0x4E, 0x49, 0x47, 0xDB, + 0x28, 0x94, 0x02, 0x0B, 0x94, 0x4A, 0x2C, 0xF9, 0x12, 0xD0, 0x4F, 0xE8, + 0x31, 0x7E, 0x6C, 0x7A, 0xBF, 0xA6, 0x3F, 0x9B, 0x39, 0x3D, 0x02, 0x16, + 0xA3, 0x18, 0xB3, 0x67, 0xAC, 0x5B, 0x3F, 0x2C, 0x83, 0x2B, 0x67, 0x39, + 0x81, 0x5C, 0xB9, 0x7E, 0x94, 0xD5, 0x64, 0xDD, 0x9E, 0x8F, 0x6E, 0xAE, + 0xE8, 0x7C, 0x5B, 0xB4, 0xD7, 0x6A, 0x47, 0x48, 0xD7, 0x7E, 0xB3, 0xD4, + 0x2D, 0x8E, 0x56, 0x76, 0x4E, 0xCF, 0x69, 0xF1, 0x6E, 0x44, 0x6C, 0xD4, + 0x24, 0xEA, 0x8D, 0x24, 0xA1, 0x18, 0xBF, 0xBD, 0x57, 0xFE, 0xA9, 0x99, + 0x35, 0xB5, 0xDB, 0x10, 0x77, 0xB8, 0x3D, 0x48, 0xBA, 0xD6, 0xC1, 0xE7, + 0xF1, 0x23, 0x3E, 0xD7, 0xDF, 0x85, 0x9D, 0x27, 0x3C, 0xD4, 0x40, 0xBD, + 0x0A, 0x0C, 0xBD, 0xF5, 0xE7, 0x8D, 0x25, 0xD6, 0x81, 0x74, 0x87, 0x46, + 0xD4, 0x29, 0x75, 0xA2, 0x42, 0x6C, 0xF7, 0x73, 0x89, 0xE7, 0x7D, 0xBF, + 0x7A, 0x4A, 0x1F, 0xD3, 0x22, 0xC9, 0x15, 0x55, 0xCF, 0xDF, 0x6F, 0x7C, + 0x55, 0xD0, 0xA4, 0x8B, 0x07, 0x11, 0x37, 0x5F, 0x83, 0xA6, 0x26, 0x57, + 0xA6, 0x01, 0x5B, 0x7E, 0xFE, 0x58, 0x68, 0x07, 0xA9, 0xE9, 0x7A, 0xD9, + 0xB9, 0xE8, 0xFF, 0x50, 0x1F, 0xAB, 0xC2, 0xB4, 0xC0, 0xCE, 0xE8, 0xEA, + 0xFD, 0x0F, 0xBD, 0x8D, 0x4D, 0xB8, 0xBC, 0x71 +}; + +static const unsigned char TA260_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA261_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x32 +}; + +static const unsigned char TA261_EC_Q[] = { + 0x04, 0x9D, 0xCB, 0x80, 0x91, 0x8D, 0x53, 0x67, 0xB5, 0xB9, 0x50, 0xB1, + 0x03, 0xF8, 0xE5, 0x49, 0x1F, 0x41, 0x22, 0x09, 0xB0, 0x51, 0x52, 0x58, + 0xD6, 0x2B, 0x34, 0x8F, 0xC5, 0x12, 0x46, 0x14, 0xC5, 0x8B, 0x2F, 0x2C, + 0x84, 0xFF, 0x2C, 0x6E, 0xA8, 0xD5, 0xF1, 0x09, 0xE3, 0x03, 0x21, 0x14, + 0xC4, 0x43, 0x3D, 0x7C, 0xC1, 0x2C, 0xC4, 0x4B, 0x6A, 0x4A, 0xCD, 0xE9, + 0x87, 0xE0, 0x7D, 0xF6, 0x22, 0xBE, 0xFA, 0x4A, 0x51, 0xB8, 0x30, 0x8A, + 0xFD, 0xE1, 0xDE, 0x18, 0x12, 0x0A, 0xF6, 0x47, 0xB7, 0xE7, 0x17, 0xBF, + 0x27, 0x8A, 0xD4, 0x41, 0x4C, 0x96, 0x3C, 0x60, 0x96, 0xC1, 0xFD, 0x15, + 0x1C +}; + +static const unsigned char TA262_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x42, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x6F, 0x72, 0x65, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, 0x43, 0x79, + 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6C, 0x74, 0x69, + 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA262_RSA_N[] = { + 0xA3, 0x04, 0xBB, 0x22, 0xAB, 0x98, 0x3D, 0x57, 0xE8, 0x26, 0x72, 0x9A, + 0xB5, 0x79, 0xD4, 0x29, 0xE2, 0xE1, 0xE8, 0x95, 0x80, 0xB1, 0xB0, 0xE3, + 0x5B, 0x8E, 0x2B, 0x29, 0x9A, 0x64, 0xDF, 0xA1, 0x5D, 0xED, 0xB0, 0x09, + 0x05, 0x6D, 0xDB, 0x28, 0x2E, 0xCE, 0x62, 0xA2, 0x62, 0xFE, 0xB4, 0x88, + 0xDA, 0x12, 0xEB, 0x38, 0xEB, 0x21, 0x9D, 0xC0, 0x41, 0x2B, 0x01, 0x52, + 0x7B, 0x88, 0x77, 0xD3, 0x1C, 0x8F, 0xC7, 0xBA, 0xB9, 0x88, 0xB5, 0x6A, + 0x09, 0xE7, 0x73, 0xE8, 0x11, 0x40, 0xA7, 0xD1, 0xCC, 0xCA, 0x62, 0x8D, + 0x2D, 0xE5, 0x8F, 0x0B, 0xA6, 0x50, 0xD2, 0xA8, 0x50, 0xC3, 0x28, 0xEA, + 0xF5, 0xAB, 0x25, 0x87, 0x8A, 0x9A, 0x96, 0x1C, 0xA9, 0x67, 0xB8, 0x3F, + 0x0C, 0xD5, 0xF7, 0xF9, 0x52, 0x13, 0x2F, 0xC2, 0x1B, 0xD5, 0x70, 0x70, + 0xF0, 0x8F, 0xC0, 0x12, 0xCA, 0x06, 0xCB, 0x9A, 0xE1, 0xD9, 0xCA, 0x33, + 0x7A, 0x77, 0xD6, 0xF8, 0xEC, 0xB9, 0xF1, 0x68, 0x44, 0x42, 0x48, 0x13, + 0xD2, 0xC0, 0xC2, 0xA4, 0xAE, 0x5E, 0x60, 0xFE, 0xB6, 0xA6, 0x05, 0xFC, + 0xB4, 0xDD, 0x07, 0x59, 0x02, 0xD4, 0x59, 0x18, 0x98, 0x63, 0xF5, 0xA5, + 0x63, 0xE0, 0x90, 0x0C, 0x7D, 0x5D, 0xB2, 0x06, 0x7A, 0xF3, 0x85, 0xEA, + 0xEB, 0xD4, 0x03, 0xAE, 0x5E, 0x84, 0x3E, 0x5F, 0xFF, 0x15, 0xED, 0x69, + 0xBC, 0xF9, 0x39, 0x36, 0x72, 0x75, 0xCF, 0x77, 0x52, 0x4D, 0xF3, 0xC9, + 0x90, 0x2C, 0xB9, 0x3D, 0xE5, 0xC9, 0x23, 0x53, 0x3F, 0x1F, 0x24, 0x98, + 0x21, 0x5C, 0x07, 0x99, 0x29, 0xBD, 0xC6, 0x3A, 0xEC, 0xE7, 0x6E, 0x86, + 0x3A, 0x6B, 0x97, 0x74, 0x63, 0x33, 0xBD, 0x68, 0x18, 0x31, 0xF0, 0x78, + 0x8D, 0x76, 0xBF, 0xFC, 0x9E, 0x8E, 0x5D, 0x2A, 0x86, 0xA7, 0x4D, 0x90, + 0xDC, 0x27, 0x1A, 0x39 +}; + +static const unsigned char TA262_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA263_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA263_RSA_N[] = { + 0xD7, 0xC7, 0x5E, 0xF7, 0xC1, 0x07, 0xD4, 0x77, 0xFB, 0x43, 0x21, 0xF4, + 0xF4, 0xF5, 0x69, 0xE4, 0xEE, 0x32, 0x01, 0xDB, 0xA3, 0x86, 0x1F, 0xE4, + 0x59, 0x0D, 0xBA, 0xE7, 0x75, 0x83, 0x52, 0xEB, 0xEA, 0x1C, 0x61, 0x15, + 0x48, 0xBB, 0x1D, 0x07, 0xCA, 0x8C, 0xAE, 0xB0, 0xDC, 0x96, 0x9D, 0xEA, + 0xC3, 0x60, 0x92, 0x86, 0x82, 0x28, 0x73, 0x9C, 0x56, 0x06, 0xFF, 0x4B, + 0x64, 0xF0, 0x0C, 0x2A, 0x37, 0x49, 0xB5, 0xE5, 0xCF, 0x0C, 0x7C, 0xEE, + 0xF1, 0x4A, 0xBB, 0x73, 0x30, 0x65, 0xF3, 0xD5, 0x2F, 0x83, 0xB6, 0x7E, + 0xE3, 0xE7, 0xF5, 0x9E, 0xAB, 0x60, 0xF9, 0xD3, 0xF1, 0x9D, 0x92, 0x74, + 0x8A, 0xE4, 0x1C, 0x96, 0xAC, 0x5B, 0x80, 0xE9, 0xB5, 0xF4, 0x31, 0x87, + 0xA3, 0x51, 0xFC, 0xC7, 0x7E, 0xA1, 0x6F, 0x8E, 0x53, 0x77, 0xD4, 0x97, + 0xC1, 0x55, 0x33, 0x92, 0x3E, 0x18, 0x2F, 0x75, 0xD4, 0xAD, 0x86, 0x49, + 0xCB, 0x95, 0xAF, 0x54, 0x06, 0x6C, 0xD8, 0x06, 0x13, 0x8D, 0x5B, 0xFF, + 0xE1, 0x26, 0x19, 0x59, 0xC0, 0x24, 0xBA, 0x81, 0x71, 0x79, 0x90, 0x44, + 0x50, 0x68, 0x24, 0x94, 0x5F, 0xB8, 0xB3, 0x11, 0xF1, 0x29, 0x41, 0x61, + 0xA3, 0x41, 0xCB, 0x23, 0x36, 0xD5, 0xC1, 0xF1, 0x32, 0x50, 0x10, 0x4E, + 0x7F, 0xF4, 0x86, 0x93, 0xEC, 0x84, 0xD3, 0x8E, 0xBC, 0x4B, 0xBF, 0x5C, + 0x01, 0x4E, 0x07, 0x3D, 0xDC, 0x14, 0x8A, 0x94, 0x0A, 0xA4, 0xEA, 0x73, + 0xFB, 0x0B, 0x51, 0xE8, 0x13, 0x07, 0x18, 0xFA, 0x0E, 0xF1, 0x2B, 0xD1, + 0x54, 0x15, 0x7D, 0x3C, 0xE1, 0xF7, 0xB4, 0x19, 0x42, 0x67, 0x62, 0x5E, + 0x77, 0xE0, 0xA2, 0x55, 0xEC, 0xB6, 0xD9, 0x69, 0x17, 0xD5, 0x3A, 0xAF, + 0x44, 0xED, 0x4A, 0xC5, 0x9E, 0xE4, 0x7A, 0x27, 0x7C, 0xE5, 0x75, 0xD7, + 0xAA, 0xCB, 0x25, 0xE7, 0xDF, 0x6B, 0x0A, 0xDB, 0x0F, 0x4D, 0x93, 0x4E, + 0xA8, 0xA0, 0xCD, 0x7B, 0x2E, 0xF2, 0x59, 0x01, 0x6A, 0xB7, 0x0D, 0xB8, + 0x07, 0x81, 0x7E, 0x8B, 0x38, 0x1B, 0x38, 0xE6, 0x0A, 0x57, 0x99, 0x3D, + 0xEE, 0x21, 0xE8, 0xA3, 0xF5, 0x0C, 0x16, 0xDD, 0x8B, 0xEC, 0x34, 0x8E, + 0x9C, 0x2A, 0x1C, 0x00, 0x15, 0x17, 0x8D, 0x68, 0x83, 0xD2, 0x70, 0x9F, + 0x18, 0x08, 0xCD, 0x11, 0x68, 0xD5, 0xC9, 0x6B, 0x52, 0xCD, 0xC4, 0x46, + 0x8F, 0xDC, 0xB5, 0xF3, 0xD8, 0x57, 0x73, 0x1E, 0xE9, 0x94, 0x39, 0x04, + 0xBF, 0xD3, 0xDE, 0x38, 0xDE, 0xB4, 0x53, 0xEC, 0x69, 0x1C, 0xA2, 0x7E, + 0xC4, 0x8F, 0xE4, 0x1B, 0x70, 0xAD, 0xF2, 0xA2, 0xF9, 0xFB, 0xF7, 0x16, + 0x64, 0x66, 0x69, 0x9F, 0x49, 0x51, 0xA2, 0xE2, 0x15, 0x18, 0x67, 0x06, + 0x4A, 0x7F, 0xD5, 0x6C, 0xB5, 0x4D, 0xB3, 0x33, 0xE0, 0x61, 0xEB, 0x5D, + 0xBE, 0xE9, 0x98, 0x0F, 0x32, 0xD7, 0x1D, 0x4B, 0x3C, 0x2E, 0x5A, 0x01, + 0x52, 0x91, 0x09, 0xF2, 0xDF, 0xEA, 0x8D, 0xD8, 0x06, 0x40, 0x63, 0xAA, + 0x11, 0xE4, 0xFE, 0xC3, 0x37, 0x9E, 0x14, 0x52, 0x3F, 0xF4, 0xE2, 0xCC, + 0xF2, 0x61, 0x93, 0xD1, 0xFD, 0x67, 0x6B, 0xD7, 0x52, 0xAE, 0xBF, 0x68, + 0xAB, 0x40, 0x43, 0xA0, 0x57, 0x35, 0x53, 0x78, 0xF0, 0x53, 0xF8, 0x61, + 0x42, 0x07, 0x64, 0xC6, 0xD7, 0x6F, 0x9B, 0x4C, 0x38, 0x0D, 0x63, 0xAC, + 0x62, 0xAF, 0x36, 0x8B, 0xA2, 0x73, 0x0A, 0x0D, 0xF5, 0x21, 0xBD, 0x74, + 0xAA, 0x4D, 0xEA, 0x72, 0x03, 0x49, 0xDB, 0xC7, 0x5F, 0x1D, 0x62, 0x63, + 0xC7, 0xFD, 0xDD, 0x91, 0xEC, 0x33, 0xEE, 0xF5, 0x6D, 0xB4, 0x6E, 0x30, + 0x68, 0xDE, 0xC8, 0xD6, 0x26, 0xB0, 0x75, 0x5E, 0x7B, 0xB4, 0x07, 0x20, + 0x98, 0xA1, 0x76, 0x32, 0xB8, 0x4D, 0x6C, 0x4F +}; + +static const unsigned char TA263_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA264_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA264_RSA_N[] = { + 0xA5, 0xDA, 0x0A, 0x95, 0x16, 0x50, 0xE3, 0x95, 0xF2, 0x5E, 0x9D, 0x76, + 0x31, 0x06, 0x32, 0x7A, 0x9B, 0xF1, 0x10, 0x76, 0xB8, 0x00, 0x9A, 0xB5, + 0x52, 0x36, 0xCD, 0x24, 0x47, 0xB0, 0x9F, 0x18, 0x64, 0xBC, 0x9A, 0xF6, + 0xFA, 0xD5, 0x79, 0xD8, 0x90, 0x62, 0x4C, 0x22, 0x2F, 0xDE, 0x38, 0x3D, + 0xD6, 0xE0, 0xA8, 0xE9, 0x1C, 0x2C, 0xDB, 0x78, 0x11, 0xE9, 0x8E, 0x68, + 0x51, 0x15, 0x72, 0xC7, 0xF3, 0x33, 0x87, 0xE4, 0xA0, 0x5D, 0x0B, 0x5C, + 0xE0, 0x57, 0x07, 0x2A, 0x30, 0xF5, 0xCD, 0xC4, 0x37, 0x77, 0x28, 0x4D, + 0x18, 0x91, 0xE6, 0xBF, 0xD5, 0x52, 0xFD, 0x71, 0x2D, 0x70, 0x3E, 0xE7, + 0xC6, 0xC4, 0x8A, 0xE3, 0xF0, 0x28, 0x0B, 0xF4, 0x76, 0x98, 0xA1, 0x8B, + 0x87, 0x55, 0xB2, 0x3A, 0x13, 0xFC, 0xB7, 0x3E, 0x27, 0x37, 0x8E, 0x22, + 0xE3, 0xA8, 0x4F, 0x2A, 0xEF, 0x60, 0xBB, 0x3D, 0xB7, 0x39, 0xC3, 0x0E, + 0x01, 0x47, 0x99, 0x5D, 0x12, 0x4F, 0xDB, 0x43, 0xFA, 0x57, 0xA1, 0xED, + 0xF9, 0x9D, 0xBE, 0x11, 0x47, 0x26, 0x5B, 0x13, 0x98, 0xAB, 0x5D, 0x16, + 0x8A, 0xB0, 0x37, 0x1C, 0x57, 0x9D, 0x45, 0xFF, 0x88, 0x96, 0x36, 0xBF, + 0xBB, 0xCA, 0x07, 0x7B, 0x6F, 0x87, 0x63, 0xD7, 0xD0, 0x32, 0x6A, 0xD6, + 0x5D, 0x6C, 0x0C, 0xF1, 0xB3, 0x6E, 0x39, 0xE2, 0x6B, 0x31, 0x2E, 0x39, + 0x00, 0x27, 0x14, 0xDE, 0x38, 0xC0, 0xEC, 0x19, 0x66, 0x86, 0x12, 0xE8, + 0x9D, 0x72, 0x16, 0x13, 0x64, 0x52, 0xC7, 0xA9, 0x37, 0x1C, 0xFD, 0x82, + 0x30, 0xED, 0x84, 0x18, 0x1D, 0xF4, 0xAE, 0x5C, 0xFF, 0x70, 0x13, 0x00, + 0xEB, 0xB1, 0xF5, 0x33, 0x7A, 0x4B, 0xD6, 0x55, 0xF8, 0x05, 0x8D, 0x4B, + 0x69, 0xB0, 0xF5, 0xB3, 0x28, 0x36, 0x5C, 0x14, 0xC4, 0x51, 0x73, 0x4D, + 0x6B, 0x0B, 0xF1, 0x34, 0x07, 0xDB, 0x17, 0x39, 0xD7, 0xDC, 0x28, 0x7B, + 0x6B, 0xF5, 0x9F, 0xF3, 0x2E, 0xC1, 0x4F, 0x17, 0x2A, 0x10, 0xF3, 0xCC, + 0xCA, 0xE8, 0xEB, 0xFD, 0x6B, 0xAB, 0x2E, 0x9A, 0x9F, 0x2D, 0x82, 0x6E, + 0x04, 0xD4, 0x52, 0x01, 0x93, 0x2D, 0x3D, 0x86, 0xFC, 0x7E, 0xFC, 0xDF, + 0xEF, 0x42, 0x1D, 0xA6, 0x6B, 0xEF, 0xB9, 0x20, 0xC6, 0xF7, 0xBD, 0xA0, + 0xA7, 0x95, 0xFD, 0xA7, 0xE6, 0x89, 0x24, 0xD8, 0xCC, 0x8C, 0x34, 0x6C, + 0xE2, 0x23, 0x2F, 0xD9, 0x12, 0x1A, 0x21, 0xB9, 0x55, 0x91, 0x6F, 0x0B, + 0x91, 0x79, 0x19, 0x0C, 0xAD, 0x40, 0x88, 0x0B, 0x70, 0xE2, 0x7A, 0xD2, + 0x0E, 0xD8, 0x68, 0x48, 0xBB, 0x82, 0x13, 0x39, 0x10, 0x58, 0xE9, 0xD8, + 0x2A, 0x07, 0xC6, 0x12, 0xDB, 0x58, 0xDB, 0xD2, 0x3B, 0x55, 0x10, 0x47, + 0x05, 0x15, 0x67, 0x62, 0x7E, 0x18, 0x63, 0xA6, 0x46, 0x3F, 0x09, 0x0E, + 0x54, 0x32, 0x5E, 0xBF, 0x0D, 0x62, 0x7A, 0x27, 0xEF, 0x80, 0xE8, 0xDB, + 0xD9, 0x4B, 0x06, 0x5A, 0x37, 0x5A, 0x25, 0xD0, 0x08, 0x12, 0x77, 0xD4, + 0x6F, 0x09, 0x50, 0x97, 0x3D, 0xC8, 0x1D, 0xC3, 0xDF, 0x8C, 0x45, 0x30, + 0x56, 0xC6, 0xD3, 0x64, 0xAB, 0x66, 0xF3, 0xC0, 0x5E, 0x96, 0x9C, 0xC3, + 0xC4, 0xEF, 0xC3, 0x7C, 0x6B, 0x8B, 0x3A, 0x79, 0x7F, 0xB3, 0x49, 0xCF, + 0x3D, 0xE2, 0x89, 0x9F, 0xA0, 0x30, 0x4B, 0x85, 0xB9, 0x9C, 0x94, 0x24, + 0x79, 0x8F, 0x7D, 0x6B, 0xA9, 0x45, 0x68, 0x0F, 0x2B, 0xD0, 0xF1, 0xDA, + 0x1C, 0xCB, 0x69, 0xB8, 0xCA, 0x49, 0x62, 0x6D, 0xC8, 0xD0, 0x63, 0x62, + 0xDD, 0x60, 0x0F, 0x58, 0xAA, 0x8F, 0xA1, 0xBC, 0x05, 0xA5, 0x66, 0xA2, + 0xCF, 0x1B, 0x76, 0xB2, 0x84, 0x64, 0xB1, 0x4C, 0x39, 0x52, 0xC0, 0x30, + 0xBA, 0xF0, 0x8C, 0x4B, 0x02, 0xB0, 0xB6, 0xB7 +}; + +static const unsigned char TA264_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA265_DN[] = { + 0x30, 0x52, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x53, 0x4B, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x0A, 0x42, 0x72, 0x61, 0x74, 0x69, 0x73, 0x6C, 0x61, 0x76, 0x61, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x61, 0x2E, 0x73, 0x2E, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x41, 0x20, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x32 +}; + +static const unsigned char TA265_RSA_N[] = { + 0xA2, 0xA3, 0xC4, 0x00, 0x09, 0xD6, 0x85, 0x5D, 0x2D, 0x6D, 0x14, 0xF6, + 0xC2, 0xC3, 0x73, 0x9E, 0x35, 0xC2, 0x71, 0x55, 0x7E, 0x81, 0xFB, 0xAB, + 0x46, 0x50, 0xE0, 0xC1, 0x7C, 0x49, 0x78, 0xE6, 0xAB, 0x79, 0x58, 0x3C, + 0xDA, 0xFF, 0x7C, 0x1C, 0x9F, 0xD8, 0x97, 0x02, 0x78, 0x3E, 0x6B, 0x41, + 0x04, 0xE9, 0x41, 0xBD, 0xBE, 0x03, 0x2C, 0x45, 0xF6, 0x2F, 0x64, 0xD4, + 0xAB, 0x5D, 0xA3, 0x47, 0x3D, 0x64, 0x9B, 0xE9, 0x68, 0x9A, 0xC6, 0xCC, + 0x1B, 0x3F, 0xBA, 0xBE, 0xB2, 0x8B, 0x34, 0x02, 0x2E, 0x98, 0x55, 0x19, + 0xFC, 0x8C, 0x6F, 0xAA, 0x5F, 0xDA, 0x4C, 0xCE, 0x4D, 0x03, 0x21, 0xA3, + 0xD8, 0xD2, 0x34, 0x93, 0x56, 0x96, 0xCB, 0x4C, 0x0C, 0x00, 0x16, 0x3C, + 0x5F, 0x1A, 0xCD, 0xC8, 0xC7, 0x6C, 0xA6, 0xAD, 0xD3, 0x31, 0xA7, 0xBC, + 0xE8, 0xE5, 0xE1, 0x66, 0xD6, 0xD2, 0xFB, 0x03, 0xB4, 0x41, 0x65, 0xC9, + 0x10, 0xAE, 0x0E, 0x05, 0x63, 0xC6, 0x80, 0x6A, 0x69, 0x30, 0xFD, 0xD2, + 0xEE, 0x90, 0xEF, 0x0D, 0x27, 0xDF, 0x9F, 0x95, 0x73, 0xF4, 0xE1, 0x25, + 0xDA, 0x6C, 0x16, 0xDE, 0x41, 0x38, 0x34, 0xEA, 0x8B, 0xFC, 0xD1, 0xE8, + 0x04, 0x14, 0x61, 0x2D, 0x41, 0x7E, 0xAC, 0xC7, 0x77, 0x4E, 0xCB, 0x51, + 0x54, 0xFB, 0x5E, 0x92, 0x18, 0x1B, 0x04, 0x5A, 0x68, 0xC6, 0xC9, 0xC4, + 0xFA, 0xB7, 0x13, 0xA0, 0x98, 0xB7, 0x11, 0x2B, 0xB7, 0xD6, 0x57, 0xCC, + 0x7C, 0x9E, 0x17, 0xD1, 0xCB, 0x25, 0xFE, 0x86, 0x4E, 0x24, 0x2E, 0x56, + 0x0C, 0x78, 0x4D, 0x9E, 0x01, 0x12, 0xA6, 0x2B, 0xA7, 0x01, 0x65, 0x6E, + 0x7C, 0x62, 0x1D, 0x84, 0x84, 0xDF, 0xEA, 0xC0, 0x6B, 0xB5, 0xA5, 0x2A, + 0x95, 0x83, 0xC3, 0x53, 0x11, 0x0C, 0x73, 0x1D, 0x0B, 0xB2, 0x46, 0x90, + 0xD1, 0x42, 0x3A, 0xCE, 0x40, 0x6E, 0x95, 0xAD, 0xFF, 0xC6, 0x94, 0xAD, + 0x6E, 0x97, 0x84, 0x8E, 0x7D, 0x6F, 0x9E, 0x8A, 0x80, 0x0D, 0x49, 0x6D, + 0x73, 0xE2, 0x7B, 0x92, 0x1E, 0xC3, 0xF3, 0xC1, 0xF3, 0xEB, 0x2E, 0x05, + 0x6F, 0xD9, 0x1B, 0xCF, 0x37, 0x76, 0x04, 0xC8, 0xB4, 0x5A, 0xE4, 0x17, + 0xA7, 0xCB, 0xDD, 0x76, 0x1F, 0xD0, 0x19, 0x76, 0xE8, 0x2C, 0x05, 0xB3, + 0xD6, 0x9C, 0x34, 0xD8, 0x96, 0xDC, 0x61, 0x87, 0x91, 0x05, 0xE4, 0x44, + 0x08, 0x33, 0xC1, 0xDA, 0xB9, 0x08, 0x65, 0xD4, 0xAE, 0xB2, 0x36, 0x0D, + 0xEB, 0xBA, 0x38, 0xBA, 0x0C, 0xE5, 0x9B, 0x9E, 0xEB, 0x8D, 0x66, 0xDD, + 0x99, 0xCF, 0xD6, 0x89, 0x41, 0xF6, 0x04, 0x92, 0x8A, 0x29, 0x29, 0x6D, + 0x6B, 0x3A, 0x1C, 0xE7, 0x75, 0x7D, 0x02, 0x71, 0x0E, 0xF3, 0xC0, 0xE7, + 0xBD, 0xCB, 0x19, 0xDD, 0x9D, 0x60, 0xB2, 0xC2, 0x66, 0x60, 0xB6, 0xB1, + 0x04, 0xEE, 0xC9, 0xE6, 0x86, 0xB9, 0x9A, 0x66, 0x40, 0xA8, 0xE7, 0x11, + 0xED, 0x81, 0x45, 0x03, 0x8B, 0xF6, 0x67, 0x59, 0xE8, 0xC1, 0x06, 0x11, + 0xBD, 0xDD, 0xCF, 0x80, 0x02, 0x4F, 0x65, 0x40, 0x78, 0x5C, 0x47, 0x50, + 0xC8, 0x9B, 0xE6, 0x1F, 0x81, 0x7B, 0xE4, 0x44, 0xA8, 0x5B, 0x85, 0x9A, + 0xE2, 0xDE, 0x5A, 0xD5, 0xC7, 0xF9, 0x3A, 0x44, 0x66, 0x4B, 0xE4, 0x32, + 0x54, 0x7C, 0xE4, 0x6C, 0x9C, 0xB3, 0x0E, 0x3D, 0x17, 0xA2, 0xB2, 0x34, + 0x12, 0xD6, 0x7E, 0xB2, 0xA8, 0x49, 0xBB, 0xD1, 0x7A, 0x28, 0x40, 0xBE, + 0xA2, 0x16, 0x1F, 0xDF, 0xE4, 0x37, 0x1F, 0x11, 0x73, 0xFB, 0x90, 0x0A, + 0x65, 0x43, 0xA2, 0x0D, 0x7C, 0xF8, 0x06, 0x01, 0x55, 0x33, 0x7D, 0xB0, + 0x0D, 0xB8, 0xF4, 0xF5, 0xAE, 0xA5, 0x42, 0x57, 0x7C, 0x36, 0x11, 0x8C, + 0x7B, 0x5E, 0xC4, 0x03, 0x9D, 0x8C, 0x79, 0x9D +}; + +static const unsigned char TA265_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA266_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x30, 0x30, 0x2E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x27, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x61, + 0x6E, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0C, 0x43, 0x46, 0x43, 0x41, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA266_RSA_N[] = { + 0xD7, 0x5D, 0x6B, 0xCD, 0x10, 0x3F, 0x1F, 0x05, 0x59, 0xD5, 0x05, 0x4D, + 0x37, 0xB1, 0x0E, 0xEC, 0x98, 0x2B, 0x8E, 0x15, 0x1D, 0xFA, 0x93, 0x4B, + 0x17, 0x82, 0x21, 0x71, 0x10, 0x52, 0xD7, 0x51, 0x64, 0x70, 0x16, 0xC2, + 0x55, 0x69, 0x4D, 0x8E, 0x15, 0x6D, 0x9F, 0xBF, 0x0C, 0x1B, 0xC2, 0xE0, + 0xA3, 0x67, 0xD6, 0x0C, 0xAC, 0xCF, 0x22, 0xAE, 0xAF, 0x77, 0x54, 0x2A, + 0x4B, 0x4C, 0x8A, 0x53, 0x52, 0x7A, 0xC3, 0xEE, 0x2E, 0xDE, 0xB3, 0x71, + 0x25, 0xC1, 0xE9, 0x5D, 0x3D, 0xEE, 0xA1, 0x2F, 0xA3, 0xF7, 0x2A, 0x3C, + 0xC9, 0x23, 0x1D, 0x6A, 0xAB, 0x1D, 0xA1, 0xA7, 0xF1, 0xF3, 0xEC, 0xA0, + 0xD5, 0x44, 0xCF, 0x15, 0xCF, 0x72, 0x2F, 0x1D, 0x63, 0x97, 0xE8, 0x99, + 0xF9, 0xFD, 0x93, 0xA4, 0x54, 0x80, 0x4C, 0x52, 0xD4, 0x52, 0xAB, 0x2E, + 0x49, 0xDF, 0x90, 0xCD, 0xB8, 0x5F, 0xBE, 0x3F, 0xDE, 0xA1, 0xCA, 0x4D, + 0x20, 0xD4, 0x25, 0xE8, 0x84, 0x29, 0x53, 0xB7, 0xB1, 0x88, 0x1F, 0xFF, + 0xFA, 0xDA, 0x90, 0x9F, 0x0A, 0xA9, 0x2D, 0x41, 0x3F, 0xB1, 0xF1, 0x18, + 0x29, 0xEE, 0x16, 0x59, 0x2C, 0x34, 0x49, 0x1A, 0xA8, 0x06, 0xD7, 0xA8, + 0x88, 0xD2, 0x03, 0x72, 0x7A, 0x32, 0xE2, 0xEA, 0x68, 0x4D, 0x6E, 0x2C, + 0x96, 0x65, 0x7B, 0xCA, 0x59, 0xFA, 0xF2, 0xE2, 0xDD, 0xEE, 0x30, 0x2C, + 0xFB, 0xCC, 0x46, 0xAC, 0xC4, 0x63, 0xEB, 0x6F, 0x7F, 0x36, 0x2B, 0x34, + 0x73, 0x12, 0x94, 0x7F, 0xDF, 0xCC, 0x26, 0x9E, 0xF1, 0x72, 0x5D, 0x50, + 0x65, 0x59, 0x8F, 0x69, 0xB3, 0x87, 0x5E, 0x32, 0x6F, 0xC3, 0x18, 0x8A, + 0xB5, 0x95, 0x8F, 0xB0, 0x7A, 0x37, 0xDE, 0x5A, 0x45, 0x3B, 0xC7, 0x36, + 0xE1, 0xEF, 0x67, 0xD1, 0x39, 0xD3, 0x97, 0x5B, 0x73, 0x62, 0x19, 0x48, + 0x2D, 0x87, 0x1C, 0x06, 0xFB, 0x74, 0x98, 0x20, 0x49, 0x73, 0xF0, 0x05, + 0xD2, 0x1B, 0xB1, 0xA0, 0xA3, 0xB7, 0x1B, 0x70, 0xD3, 0x88, 0x69, 0xB9, + 0x5A, 0xD6, 0x38, 0xF4, 0x62, 0xDC, 0x25, 0x8B, 0x78, 0xBF, 0xF8, 0xE8, + 0x7E, 0xB8, 0x5C, 0xC9, 0x95, 0x4F, 0x5F, 0xA7, 0x2D, 0xB9, 0x20, 0x6B, + 0xCF, 0x6B, 0xDD, 0xF5, 0x0D, 0xF4, 0x82, 0xB7, 0xF4, 0xB2, 0x66, 0x2E, + 0x10, 0x28, 0xF6, 0x97, 0x5A, 0x7B, 0x96, 0x16, 0x8F, 0x01, 0x19, 0x2D, + 0x6C, 0x6E, 0x7F, 0x39, 0x58, 0x06, 0x64, 0x83, 0x01, 0x83, 0x83, 0xC3, + 0x4D, 0x92, 0xDD, 0x32, 0xC6, 0x87, 0xA4, 0x37, 0xE9, 0x16, 0xCE, 0xAA, + 0x2D, 0x68, 0xAF, 0x0A, 0x81, 0x65, 0x3A, 0x70, 0xC1, 0x9B, 0xAD, 0x4D, + 0x6D, 0x54, 0xCA, 0x2A, 0x2D, 0x4B, 0x85, 0x1B, 0xB3, 0x80, 0xE6, 0x70, + 0x45, 0x0D, 0x6B, 0x5E, 0x35, 0xF0, 0x7F, 0x3B, 0xB8, 0x9C, 0xE4, 0x04, + 0x70, 0x89, 0x12, 0x25, 0x93, 0xDA, 0x0A, 0x99, 0x22, 0x60, 0x6A, 0x63, + 0x60, 0x4E, 0x76, 0x06, 0x98, 0x4E, 0xBD, 0x83, 0xAD, 0x1D, 0x58, 0x8A, + 0x25, 0x85, 0xD2, 0xC7, 0x65, 0x1E, 0x2D, 0x8E, 0xC6, 0xDF, 0xB6, 0xC6, + 0xE1, 0x7F, 0x8A, 0x04, 0x21, 0x15, 0x29, 0x74, 0xF0, 0x3E, 0x9C, 0x90, + 0x9D, 0x0C, 0x2E, 0xF1, 0x8A, 0x3E, 0x5A, 0xAA, 0x0C, 0x09, 0x1E, 0xC7, + 0xD5, 0x3C, 0xA3, 0xED, 0x97, 0xC3, 0x1E, 0x34, 0xFA, 0x38, 0xF9, 0x08, + 0x0E, 0xE3, 0xC0, 0x5D, 0x2B, 0x83, 0xD1, 0x56, 0x6A, 0xC9, 0xB6, 0xA8, + 0x54, 0x53, 0x2E, 0x78, 0x32, 0x67, 0x3D, 0x82, 0x7F, 0x74, 0xD0, 0xFB, + 0xE1, 0xB6, 0x05, 0x60, 0xB9, 0x70, 0xDB, 0x8E, 0x0B, 0xF9, 0x13, 0x58, + 0x6F, 0x71, 0x60, 0x10, 0x52, 0x10, 0xB9, 0xC1, 0x41, 0x09, 0xEF, 0x72, + 0x1F, 0x67, 0x31, 0x78, 0xFF, 0x96, 0x05, 0x8D +}; + +static const unsigned char TA266_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA267_DN[] = { + 0x30, 0x81, 0x81, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA267_RSA_N[] = { + 0xD0, 0x40, 0x8B, 0x8B, 0x72, 0xE3, 0x91, 0x1B, 0xF7, 0x51, 0xC1, 0x1B, + 0x54, 0x04, 0x98, 0xD3, 0xA9, 0xBF, 0xC1, 0xE6, 0x8A, 0x5D, 0x3B, 0x87, + 0xFB, 0xBB, 0x88, 0xCE, 0x0D, 0xE3, 0x2F, 0x3F, 0x06, 0x96, 0xF0, 0xA2, + 0x29, 0x50, 0x99, 0xAE, 0xDB, 0x3B, 0xA1, 0x57, 0xB0, 0x74, 0x51, 0x71, + 0xCD, 0xED, 0x42, 0x91, 0x4D, 0x41, 0xFE, 0xA9, 0xC8, 0xD8, 0x6A, 0x86, + 0x77, 0x44, 0xBB, 0x59, 0x66, 0x97, 0x50, 0x5E, 0xB4, 0xD4, 0x2C, 0x70, + 0x44, 0xCF, 0xDA, 0x37, 0x95, 0x42, 0x69, 0x3C, 0x30, 0xC4, 0x71, 0xB3, + 0x52, 0xF0, 0x21, 0x4D, 0xA1, 0xD8, 0xBA, 0x39, 0x7C, 0x1C, 0x9E, 0xA3, + 0x24, 0x9D, 0xF2, 0x83, 0x16, 0x98, 0xAA, 0x16, 0x7C, 0x43, 0x9B, 0x15, + 0x5B, 0xB7, 0xAE, 0x34, 0x91, 0xFE, 0xD4, 0x62, 0x26, 0x18, 0x46, 0x9A, + 0x3F, 0xEB, 0xC1, 0xF9, 0xF1, 0x90, 0x57, 0xEB, 0xAC, 0x7A, 0x0D, 0x8B, + 0xDB, 0x72, 0x30, 0x6A, 0x66, 0xD5, 0xE0, 0x46, 0xA3, 0x70, 0xDC, 0x68, + 0xD9, 0xFF, 0x04, 0x48, 0x89, 0x77, 0xDE, 0xB5, 0xE9, 0xFB, 0x67, 0x6D, + 0x41, 0xE9, 0xBC, 0x39, 0xBD, 0x32, 0xD9, 0x62, 0x02, 0xF1, 0xB1, 0xA8, + 0x3D, 0x6E, 0x37, 0x9C, 0xE2, 0x2F, 0xE2, 0xD3, 0xA2, 0x26, 0x8B, 0xC6, + 0xB8, 0x55, 0x43, 0x88, 0xE1, 0x23, 0x3E, 0xA5, 0xD2, 0x24, 0x39, 0x6A, + 0x47, 0xAB, 0x00, 0xD4, 0xA1, 0xB3, 0xA9, 0x25, 0xFE, 0x0D, 0x3F, 0xA7, + 0x1D, 0xBA, 0xD3, 0x51, 0xC1, 0x0B, 0xA4, 0xDA, 0xAC, 0x38, 0xEF, 0x55, + 0x50, 0x24, 0x05, 0x65, 0x46, 0x93, 0x34, 0x4F, 0x2D, 0x8D, 0xAD, 0xC6, + 0xD4, 0x21, 0x19, 0xD2, 0x8E, 0xCA, 0x05, 0x61, 0x71, 0x07, 0x73, 0x47, + 0xE5, 0x8A, 0x19, 0x12, 0xBD, 0x04, 0x4D, 0xCE, 0x4E, 0x9C, 0xA5, 0x48, + 0xAC, 0xBB, 0x26, 0xF7 +}; + +static const unsigned char TA267_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA268_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA268_EC_Q[] = { + 0x04, 0x03, 0x47, 0x7B, 0x2F, 0x75, 0xC9, 0x82, 0x15, 0x85, 0xFB, 0x75, + 0xE4, 0x91, 0x16, 0xD4, 0xAB, 0x62, 0x99, 0xF5, 0x3E, 0x52, 0x0B, 0x06, + 0xCE, 0x41, 0x00, 0x7F, 0x97, 0xE1, 0x0A, 0x24, 0x3C, 0x1D, 0x01, 0x04, + 0xEE, 0x3D, 0xD2, 0x8D, 0x09, 0x97, 0x0C, 0xE0, 0x75, 0xE4, 0xFA, 0xFB, + 0x77, 0x8A, 0x2A, 0xF5, 0x03, 0x60, 0x4B, 0x36, 0x8B, 0x16, 0x23, 0x16, + 0xAD, 0x09, 0x71, 0xF4, 0x4A, 0xF4, 0x28, 0x50, 0xB4, 0xFE, 0x88, 0x1C, + 0x6E, 0x3F, 0x6C, 0x2F, 0x2F, 0x09, 0x59, 0x5B, 0xA5, 0x5B, 0x0B, 0x33, + 0x99, 0xE2, 0xC3, 0x3D, 0x89, 0xF9, 0x6A, 0x2C, 0xEF, 0xB2, 0xD3, 0x06, + 0xE9 +}; + +static const unsigned char TA269_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA269_RSA_N[] = { + 0x91, 0xE8, 0x54, 0x92, 0xD2, 0x0A, 0x56, 0xB1, 0xAC, 0x0D, 0x24, 0xDD, + 0xC5, 0xCF, 0x44, 0x67, 0x74, 0x99, 0x2B, 0x37, 0xA3, 0x7D, 0x23, 0x70, + 0x00, 0x71, 0xBC, 0x53, 0xDF, 0xC4, 0xFA, 0x2A, 0x12, 0x8F, 0x4B, 0x7F, + 0x10, 0x56, 0xBD, 0x9F, 0x70, 0x72, 0xB7, 0x61, 0x7F, 0xC9, 0x4B, 0x0F, + 0x17, 0xA7, 0x3D, 0xE3, 0xB0, 0x04, 0x61, 0xEE, 0xFF, 0x11, 0x97, 0xC7, + 0xF4, 0x86, 0x3E, 0x0A, 0xFA, 0x3E, 0x5C, 0xF9, 0x93, 0xE6, 0x34, 0x7A, + 0xD9, 0x14, 0x6B, 0xE7, 0x9C, 0xB3, 0x85, 0xA0, 0x82, 0x7A, 0x76, 0xAF, + 0x71, 0x90, 0xD7, 0xEC, 0xFD, 0x0D, 0xFA, 0x9C, 0x6C, 0xFA, 0xDF, 0xB0, + 0x82, 0xF4, 0x14, 0x7E, 0xF9, 0xBE, 0xC4, 0xA6, 0x2F, 0x4F, 0x7F, 0x99, + 0x7F, 0xB5, 0xFC, 0x67, 0x43, 0x72, 0xBD, 0x0C, 0x00, 0xD6, 0x89, 0xEB, + 0x6B, 0x2C, 0xD3, 0xED, 0x8F, 0x98, 0x1C, 0x14, 0xAB, 0x7E, 0xE5, 0xE3, + 0x6E, 0xFC, 0xD8, 0xA8, 0xE4, 0x92, 0x24, 0xDA, 0x43, 0x6B, 0x62, 0xB8, + 0x55, 0xFD, 0xEA, 0xC1, 0xBC, 0x6C, 0xB6, 0x8B, 0xF3, 0x0E, 0x8D, 0x9A, + 0xE4, 0x9B, 0x6C, 0x69, 0x99, 0xF8, 0x78, 0x48, 0x30, 0x45, 0xD5, 0xAD, + 0xE1, 0x0D, 0x3C, 0x45, 0x60, 0xFC, 0x32, 0x96, 0x51, 0x27, 0xBC, 0x67, + 0xC3, 0xCA, 0x2E, 0xB6, 0x6B, 0xEA, 0x46, 0xC7, 0xC7, 0x20, 0xA0, 0xB1, + 0x1F, 0x65, 0xDE, 0x48, 0x08, 0xBA, 0xA4, 0x4E, 0xA9, 0xF2, 0x83, 0x46, + 0x37, 0x84, 0xEB, 0xE8, 0xCC, 0x81, 0x48, 0x43, 0x67, 0x4E, 0x72, 0x2A, + 0x9B, 0x5C, 0xBD, 0x4C, 0x1B, 0x28, 0x8A, 0x5C, 0x22, 0x7B, 0xB4, 0xAB, + 0x98, 0xD9, 0xEE, 0xE0, 0x51, 0x83, 0xC3, 0x09, 0x46, 0x4E, 0x6D, 0x3E, + 0x99, 0xFA, 0x95, 0x17, 0xDA, 0x7C, 0x33, 0x57, 0x41, 0x3C, 0x8D, 0x51, + 0xED, 0x0B, 0xB6, 0x5C, 0xAF, 0x2C, 0x63, 0x1A, 0xDF, 0x57, 0xC8, 0x3F, + 0xBC, 0xE9, 0x5D, 0xC4, 0x9B, 0xAF, 0x45, 0x99, 0xE2, 0xA3, 0x5A, 0x24, + 0xB4, 0xBA, 0xA9, 0x56, 0x3D, 0xCF, 0x6F, 0xAA, 0xFF, 0x49, 0x58, 0xBE, + 0xF0, 0xA8, 0xFF, 0xF4, 0xB8, 0xAD, 0xE9, 0x37, 0xFB, 0xBA, 0xB8, 0xF4, + 0x0B, 0x3A, 0xF9, 0xE8, 0x43, 0x42, 0x1E, 0x89, 0xD8, 0x84, 0xCB, 0x13, + 0xF1, 0xD9, 0xBB, 0xE1, 0x89, 0x60, 0xB8, 0x8C, 0x28, 0x56, 0xAC, 0x14, + 0x1D, 0x9C, 0x0A, 0xE7, 0x71, 0xEB, 0xCF, 0x0E, 0xDD, 0x3D, 0xA9, 0x96, + 0xA1, 0x48, 0xBD, 0x3C, 0xF7, 0xAF, 0xB5, 0x0D, 0x22, 0x4C, 0xC0, 0x11, + 0x81, 0xEC, 0x56, 0x3B, 0xF6, 0xD3, 0xA2, 0xE2, 0x5B, 0xB7, 0xB2, 0x04, + 0x22, 0x52, 0x95, 0x80, 0x93, 0x69, 0xE8, 0x8E, 0x4C, 0x65, 0xF1, 0x91, + 0x03, 0x2D, 0x70, 0x74, 0x02, 0xEA, 0x8B, 0x67, 0x15, 0x29, 0x69, 0x52, + 0x02, 0xBB, 0xD7, 0xDF, 0x50, 0x6A, 0x55, 0x46, 0xBF, 0xA0, 0xA3, 0x28, + 0x61, 0x7F, 0x70, 0xD0, 0xC3, 0xA2, 0xAA, 0x2C, 0x21, 0xAA, 0x47, 0xCE, + 0x28, 0x9C, 0x06, 0x45, 0x76, 0xBF, 0x82, 0x18, 0x27, 0xB4, 0xD5, 0xAE, + 0xB4, 0xCB, 0x50, 0xE6, 0x6B, 0xF4, 0x4C, 0x86, 0x71, 0x30, 0xE9, 0xA6, + 0xDF, 0x16, 0x86, 0xE0, 0xD8, 0xFF, 0x40, 0xDD, 0xFB, 0xD0, 0x42, 0x88, + 0x7F, 0xA3, 0x33, 0x3A, 0x2E, 0x5C, 0x1E, 0x41, 0x11, 0x81, 0x63, 0xCE, + 0x18, 0x71, 0x6B, 0x2B, 0xEC, 0xA6, 0x8A, 0xB7, 0x31, 0x5C, 0x3A, 0x6A, + 0x47, 0xE0, 0xC3, 0x79, 0x59, 0xD6, 0x20, 0x1A, 0xAF, 0xF2, 0x6A, 0x98, + 0xAA, 0x72, 0xBC, 0x57, 0x4A, 0xD2, 0x4B, 0x9D, 0xBB, 0x10, 0xFC, 0xB0, + 0x4C, 0x41, 0xE5, 0xED, 0x1D, 0x3D, 0x5E, 0x28, 0x9D, 0x9C, 0xCC, 0xBF, + 0xB3, 0x51, 0xDA, 0xA7, 0x47, 0xE5, 0x84, 0x53 +}; + +static const unsigned char TA269_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA270_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x45, 0x31 +}; + +static const unsigned char TA270_EC_Q[] = { + 0x04, 0xDE, 0x6F, 0xF8, 0x7F, 0x1C, 0xDF, 0xED, 0xF9, 0x47, 0x87, 0x86, + 0xB1, 0xA4, 0xC0, 0x8A, 0xF8, 0x82, 0x97, 0x80, 0xEA, 0x8F, 0xC8, 0x4A, + 0x5E, 0x2A, 0x7D, 0x88, 0x68, 0xA7, 0x01, 0x62, 0x14, 0x91, 0x24, 0x7A, + 0x5C, 0x9E, 0xA3, 0x17, 0x7D, 0x8A, 0x86, 0x21, 0x34, 0x18, 0x50, 0x1B, + 0x10, 0xDE, 0xD0, 0x37, 0x4B, 0x26, 0xC7, 0x19, 0x60, 0x80, 0xE9, 0x34, + 0xBD, 0x60, 0x19, 0x36, 0x40, 0xD6, 0x29, 0x87, 0x09, 0x3C, 0x91, 0x7A, + 0xF6, 0xBC, 0x13, 0x23, 0xDD, 0x59, 0x4E, 0x04, 0x5E, 0xCF, 0xC8, 0x02, + 0x1C, 0x18, 0x53, 0xC1, 0x31, 0xD8, 0xDA, 0x20, 0xE9, 0x44, 0x8D, 0xE4, + 0x76 +}; + +static const unsigned char TA271_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x52, 0x31 +}; + +static const unsigned char TA271_RSA_N[] = { + 0xD0, 0x36, 0xD4, 0x1F, 0xEA, 0xDD, 0xAB, 0xE4, 0xD1, 0xB6, 0xE6, 0xFB, + 0x22, 0xC0, 0xDD, 0x13, 0x0D, 0x6A, 0x7B, 0x22, 0x13, 0x1C, 0x97, 0x3C, + 0x68, 0x63, 0x66, 0x32, 0x9C, 0x03, 0xB5, 0x8D, 0xA4, 0x81, 0x83, 0xDA, + 0x78, 0x30, 0x11, 0xCF, 0xDC, 0xB2, 0x2B, 0xBE, 0x92, 0xBF, 0x8E, 0xE4, + 0xC4, 0x13, 0xBE, 0xA4, 0x68, 0x4C, 0xDA, 0x02, 0x68, 0x16, 0x74, 0xBE, + 0xB2, 0xDD, 0x04, 0xE4, 0x6B, 0x2A, 0xDD, 0x37, 0x1F, 0x60, 0x2C, 0xDB, + 0xF5, 0xF7, 0xA1, 0x7C, 0x95, 0xB7, 0x0C, 0x70, 0x86, 0x2E, 0xF1, 0x3A, + 0xEF, 0x52, 0xF7, 0xCC, 0xD3, 0x9B, 0xF9, 0x8B, 0xBE, 0x0E, 0xDF, 0x31, + 0xB7, 0x9D, 0x68, 0x5C, 0x92, 0xA6, 0xF5, 0xE5, 0xF3, 0x0A, 0x34, 0xB5, + 0xFF, 0x7B, 0xA2, 0xE4, 0x87, 0xA1, 0xC6, 0xAF, 0x17, 0x00, 0xEF, 0x03, + 0x91, 0xED, 0xA9, 0x1C, 0x4E, 0x71, 0x3D, 0xD2, 0x8B, 0x6C, 0x89, 0xF4, + 0x78, 0x86, 0xE6, 0x6A, 0x49, 0xA0, 0xCE, 0xB5, 0xD2, 0xB0, 0xAB, 0x9B, + 0xF6, 0xF4, 0xD4, 0x2E, 0xE3, 0x72, 0xF9, 0x36, 0xC6, 0xEB, 0x15, 0xB7, + 0x25, 0x8C, 0x3A, 0xFC, 0x25, 0x0D, 0xB3, 0x22, 0x73, 0x21, 0x74, 0xC8, + 0x4A, 0x96, 0x61, 0x92, 0xF5, 0x2F, 0x0B, 0x18, 0xA5, 0xF4, 0xAD, 0xE2, + 0xEE, 0x41, 0xBD, 0x01, 0x79, 0xFA, 0x96, 0x8C, 0x8D, 0x17, 0x02, 0x30, + 0xB4, 0xF9, 0xAF, 0x78, 0x1A, 0x8C, 0xB4, 0x36, 0x10, 0x10, 0x07, 0x05, + 0x70, 0xD0, 0xF4, 0x31, 0x90, 0x8A, 0x51, 0xC5, 0x86, 0x26, 0x79, 0xB2, + 0x11, 0x88, 0x5E, 0xC5, 0xF0, 0x0A, 0x54, 0xCD, 0x49, 0xA6, 0xBF, 0x02, + 0x9C, 0xD2, 0x44, 0xA7, 0xED, 0xE3, 0x78, 0xEF, 0x46, 0x5E, 0x6D, 0x71, + 0xD1, 0x79, 0x70, 0x1C, 0x46, 0x5F, 0x51, 0xE9, 0xC9, 0x37, 0xDC, 0x5F, + 0x7E, 0x69, 0x7B, 0x41, 0xDF, 0x34, 0x45, 0xE0, 0x3B, 0x84, 0xF4, 0xA1, + 0x8A, 0x0A, 0x36, 0x9E, 0x37, 0xCC, 0x62, 0x52, 0xE1, 0x89, 0x0D, 0x28, + 0xF9, 0x7A, 0x23, 0xB1, 0x0D, 0x3D, 0x3D, 0x9A, 0xFD, 0x9D, 0x81, 0xEF, + 0x2C, 0x90, 0xC0, 0x7B, 0x44, 0x4E, 0xBB, 0x49, 0xE0, 0x0E, 0x4A, 0x56, + 0x92, 0xBC, 0xCB, 0xB5, 0xDD, 0x79, 0x17, 0x89, 0x91, 0xDE, 0x61, 0x89, + 0x74, 0x92, 0xA8, 0xE3, 0x32, 0x85, 0xBE, 0x4E, 0x85, 0xA4, 0x4B, 0x59, + 0xCB, 0x2B, 0xC5, 0x78, 0x8E, 0x71, 0x54, 0xD0, 0x02, 0x37, 0x99, 0x8C, + 0xE5, 0x49, 0xEA, 0xE0, 0x54, 0x72, 0xA4, 0x11, 0x06, 0x2F, 0x0B, 0x8C, + 0xC1, 0x5B, 0xBE, 0xB5, 0xA1, 0xB0, 0x53, 0x6E, 0x9C, 0xB8, 0x60, 0x91, + 0x1F, 0x59, 0x6B, 0xF9, 0x2D, 0xF4, 0x94, 0x0A, 0x97, 0xB5, 0xEC, 0xC5, + 0x76, 0x03, 0x54, 0x1B, 0x65, 0x52, 0xBA, 0x4C, 0x92, 0x56, 0x51, 0x35, + 0xA0, 0x40, 0xD8, 0x29, 0xDB, 0xAE, 0x52, 0x76, 0x3B, 0x2D, 0x30, 0x40, + 0x9B, 0x8A, 0xD0, 0x42, 0x56, 0xB4, 0xB7, 0x88, 0x01, 0xA4, 0x87, 0x3B, + 0x53, 0x96, 0xCD, 0xA3, 0x16, 0x8F, 0xF3, 0x66, 0xAA, 0x17, 0xB1, 0xC7, + 0x60, 0xE0, 0xC1, 0x43, 0x05, 0x0C, 0xEE, 0x9B, 0x5B, 0x60, 0x6F, 0x06, + 0x5C, 0x87, 0x5B, 0x27, 0xF9, 0x40, 0x11, 0x9E, 0x9C, 0x33, 0xC1, 0xB7, + 0xE5, 0x35, 0x57, 0x05, 0x7F, 0x27, 0xCE, 0x17, 0x20, 0x8C, 0x1C, 0xFC, + 0xF1, 0xFB, 0xDA, 0x31, 0x29, 0x49, 0xED, 0xF5, 0x0B, 0x84, 0xA7, 0x4F, + 0xC1, 0xF6, 0x4E, 0xC2, 0x28, 0x9C, 0xFA, 0xEE, 0xE0, 0xAF, 0x07, 0xFB, + 0x33, 0x11, 0x7A, 0x21, 0x4F, 0x0B, 0x21, 0x10, 0xB6, 0x40, 0x3A, 0xAB, + 0x22, 0x3A, 0x04, 0x9C, 0x8B, 0x9B, 0x84, 0x86, 0x72, 0x9A, 0xD2, 0xA7, + 0xA5, 0xC4, 0xB4, 0x75, 0x91, 0xA9, 0x2B, 0x23 +}; + +static const unsigned char TA271_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA272_DN[] = { + 0x30, 0x34, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x08, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61 +}; + +static const unsigned char TA272_RSA_N[] = { + 0xC8, 0x68, 0xF1, 0xC9, 0xD6, 0xD6, 0xB3, 0x34, 0x75, 0x26, 0x82, 0x1E, + 0xEC, 0xB4, 0xBE, 0xEA, 0x5C, 0xE1, 0x26, 0xED, 0x11, 0x47, 0x61, 0xE1, + 0xA2, 0x7C, 0x16, 0x78, 0x40, 0x21, 0xE4, 0x60, 0x9E, 0x5A, 0xC8, 0x63, + 0xE1, 0xC4, 0xB1, 0x96, 0x92, 0xFF, 0x18, 0x6D, 0x69, 0x23, 0xE1, 0x2B, + 0x62, 0xF7, 0xDD, 0xE2, 0x36, 0x2F, 0x91, 0x07, 0xB9, 0x48, 0xCF, 0x0E, + 0xEC, 0x79, 0xB6, 0x2C, 0xE7, 0x34, 0x4B, 0x70, 0x08, 0x25, 0xA3, 0x3C, + 0x87, 0x1B, 0x19, 0xF2, 0x81, 0x07, 0x0F, 0x38, 0x90, 0x19, 0xD3, 0x11, + 0xFE, 0x86, 0xB4, 0xF2, 0xD1, 0x5E, 0x1E, 0x1E, 0x96, 0xCD, 0x80, 0x6C, + 0xCE, 0x3B, 0x31, 0x93, 0xB6, 0xF2, 0xA0, 0xD0, 0xA9, 0x95, 0x12, 0x7D, + 0xA5, 0x9A, 0xCC, 0x6B, 0xC8, 0x84, 0x56, 0x8A, 0x33, 0xA9, 0xE7, 0x22, + 0x15, 0x53, 0x16, 0xF0, 0xCC, 0x17, 0xEC, 0x57, 0x5F, 0xE9, 0xA2, 0x0A, + 0x98, 0x09, 0xDE, 0xE3, 0x5F, 0x9C, 0x6F, 0xDC, 0x48, 0xE3, 0x85, 0x0B, + 0x15, 0x5A, 0xA6, 0xBA, 0x9F, 0xAC, 0x48, 0xE3, 0x09, 0xB2, 0xF7, 0xF4, + 0x32, 0xDE, 0x5E, 0x34, 0xBE, 0x1C, 0x78, 0x5D, 0x42, 0x5B, 0xCE, 0x0E, + 0x22, 0x8F, 0x4D, 0x90, 0xD7, 0x7D, 0x32, 0x18, 0xB3, 0x0B, 0x2C, 0x6A, + 0xBF, 0x8E, 0x3F, 0x14, 0x11, 0x89, 0x20, 0x0E, 0x77, 0x14, 0xB5, 0x3D, + 0x94, 0x08, 0x87, 0xF7, 0x25, 0x1E, 0xD5, 0xB2, 0x60, 0x00, 0xEC, 0x6F, + 0x2A, 0x28, 0x25, 0x6E, 0x2A, 0x3E, 0x18, 0x63, 0x17, 0x25, 0x3F, 0x3E, + 0x44, 0x20, 0x16, 0xF6, 0x26, 0xC8, 0x25, 0xAE, 0x05, 0x4A, 0xB4, 0xE7, + 0x63, 0x2C, 0xF3, 0x8C, 0x16, 0x53, 0x7E, 0x5C, 0xFB, 0x11, 0x1A, 0x08, + 0xC1, 0x46, 0x62, 0x9F, 0x22, 0xB8, 0xF1, 0xC2, 0x8D, 0x69, 0xDC, 0xFA, + 0x3A, 0x58, 0x06, 0xDF +}; + +static const unsigned char TA272_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA273_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x13, 0x30, 0x30, + 0x30, 0x32, 0x20, 0x34, 0x38, 0x31, 0x34, 0x36, 0x33, 0x30, 0x38, 0x31, + 0x30, 0x30, 0x30, 0x33, 0x36, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA273_RSA_N[] = { + 0xCD, 0x18, 0x39, 0x65, 0x1A, 0x59, 0xB1, 0xEA, 0x64, 0x16, 0x0E, 0x8C, + 0x94, 0x24, 0x95, 0x7C, 0x83, 0xD3, 0xC5, 0x39, 0x26, 0xDC, 0x0C, 0xEF, + 0x16, 0x57, 0x8D, 0xD7, 0xD8, 0xAC, 0xA3, 0x42, 0x7F, 0x82, 0xCA, 0xED, + 0xCD, 0x5B, 0xDB, 0x0E, 0xB7, 0x2D, 0xED, 0x45, 0x08, 0x17, 0xB2, 0xD9, + 0xB3, 0xCB, 0xD6, 0x17, 0x52, 0x72, 0x28, 0xDB, 0x8E, 0x4E, 0x9E, 0x8A, + 0xB6, 0x0B, 0xF9, 0x9E, 0x84, 0x9A, 0x4D, 0x76, 0xDE, 0x22, 0x29, 0x5C, + 0xD2, 0xB3, 0xD2, 0x06, 0x3E, 0x30, 0x39, 0xA9, 0x74, 0xA3, 0x92, 0x56, + 0x1C, 0xA1, 0x6F, 0x4C, 0x0A, 0x20, 0x6D, 0x9F, 0x23, 0x7A, 0xB4, 0xC6, + 0xDA, 0x2C, 0xE4, 0x1D, 0x2C, 0xDC, 0xB3, 0x28, 0xD0, 0x13, 0xF2, 0x4C, + 0x4E, 0x02, 0x49, 0xA1, 0x54, 0x40, 0x9E, 0xE6, 0xE5, 0x05, 0xA0, 0x2D, + 0x84, 0xC8, 0xFF, 0x98, 0x6C, 0xD0, 0xEB, 0x8A, 0x1A, 0x84, 0x08, 0x1E, + 0xB7, 0x68, 0x23, 0xEE, 0x23, 0xD5, 0x70, 0xCE, 0x6D, 0x51, 0x69, 0x10, + 0xEE, 0xA1, 0x7A, 0xC2, 0xD1, 0x22, 0x31, 0xC2, 0x82, 0x85, 0xD2, 0xF2, + 0x55, 0x76, 0x50, 0x7C, 0x25, 0x7A, 0xC9, 0x84, 0x5C, 0x0B, 0xAC, 0xDD, + 0x42, 0x4E, 0x2B, 0xE7, 0x82, 0xA2, 0x24, 0x89, 0xCB, 0x90, 0xB2, 0xD0, + 0xEE, 0x23, 0xBA, 0x66, 0x4C, 0xBB, 0x62, 0xA4, 0xF9, 0x53, 0x5A, 0x64, + 0x7B, 0x7C, 0x98, 0xFA, 0xA3, 0x48, 0x9E, 0x0F, 0x95, 0xAE, 0xA7, 0x18, + 0xF4, 0x6A, 0xEC, 0x2E, 0x03, 0x45, 0xAF, 0xF0, 0x74, 0xF8, 0x2A, 0xCD, + 0x7A, 0x5D, 0xD1, 0xBE, 0x44, 0x26, 0x32, 0x29, 0xF1, 0xF1, 0xF5, 0x6C, + 0xCC, 0x7E, 0x02, 0x21, 0x0B, 0x9F, 0x6F, 0xA4, 0x3F, 0xBE, 0x9D, 0x53, + 0xE2, 0xCF, 0x7D, 0xA9, 0x2C, 0x7C, 0x58, 0x1A, 0x97, 0xE1, 0x3D, 0x37, + 0x37, 0x18, 0x66, 0x28, 0xD2, 0x40, 0xC5, 0x51, 0x8A, 0x8C, 0xC3, 0x2D, + 0xCE, 0x53, 0x88, 0x24, 0x58, 0x64, 0x30, 0x16, 0xC5, 0xAA, 0xE0, 0xD6, + 0x0A, 0xA6, 0x40, 0xDF, 0x78, 0xF6, 0xF5, 0x04, 0x7C, 0x69, 0x13, 0x84, + 0xBC, 0xD1, 0xD1, 0xA7, 0x06, 0xCF, 0x01, 0xF7, 0x68, 0xC0, 0xA8, 0x57, + 0xBB, 0x3A, 0x61, 0xAD, 0x04, 0x8C, 0x93, 0xE3, 0xAD, 0xFC, 0xF0, 0xDB, + 0x44, 0x6D, 0x59, 0xDC, 0x49, 0x59, 0xAE, 0xAC, 0x9A, 0x99, 0x36, 0x30, + 0x41, 0x7B, 0x76, 0x33, 0x22, 0x87, 0xA3, 0xC2, 0x92, 0x86, 0x6E, 0xF9, + 0x70, 0xEE, 0xAE, 0x87, 0x87, 0x95, 0x1B, 0xC4, 0x7A, 0xBD, 0x31, 0xF3, + 0xD4, 0xD2, 0xE5, 0x99, 0xFF, 0xBE, 0x48, 0xEC, 0x75, 0xF5, 0x78, 0x16, + 0x1D, 0xA6, 0x70, 0xC1, 0x7F, 0x3C, 0x1B, 0xA1, 0x92, 0xFB, 0xCF, 0xC8, + 0x3C, 0xD6, 0xC5, 0x93, 0x0A, 0x8F, 0xF5, 0x55, 0x3A, 0x76, 0x95, 0xCE, + 0x59, 0x98, 0x8A, 0x09, 0x95, 0x77, 0x32, 0x9A, 0x83, 0xBA, 0x2C, 0x04, + 0x3A, 0x97, 0xBD, 0xD4, 0x2F, 0xBE, 0xD7, 0x6C, 0x9B, 0xA2, 0xCA, 0x7D, + 0x6D, 0x26, 0xC9, 0x55, 0xD5, 0xCF, 0xC3, 0x79, 0x52, 0x08, 0x09, 0x99, + 0x07, 0x24, 0x2D, 0x64, 0x25, 0x6B, 0xA6, 0x21, 0x69, 0x9B, 0x6A, 0xDD, + 0x74, 0x4D, 0x6B, 0x97, 0x7A, 0x41, 0xBD, 0xAB, 0x17, 0xF9, 0x90, 0x17, + 0x48, 0x8F, 0x36, 0xF9, 0x2D, 0xD5, 0xC5, 0xDB, 0xEE, 0xAA, 0x85, 0x45, + 0x41, 0xFA, 0xCD, 0x3A, 0x45, 0xB1, 0x68, 0xE6, 0x36, 0x4C, 0x9B, 0x90, + 0x57, 0xEC, 0x23, 0xB9, 0x87, 0x08, 0xC2, 0xC4, 0x09, 0xF1, 0x97, 0x86, + 0x2A, 0x28, 0x4D, 0xE2, 0x74, 0xC0, 0xDA, 0xC4, 0x8C, 0xDB, 0xDF, 0xE2, + 0xA1, 0x17, 0x59, 0xCE, 0x24, 0x59, 0x74, 0x31, 0xDA, 0x7F, 0xFD, 0x30, + 0x6D, 0xD9, 0xDC, 0xE1, 0x6A, 0xE1, 0xFC, 0x5F +}; + +static const unsigned char TA273_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA274_DN[] = { + 0x30, 0x74, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x45, 0x43, 0x2D, 0x33, 0x38, 0x34, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA274_EC_Q[] = { + 0x04, 0xC4, 0x28, 0x8E, 0xAB, 0x18, 0x5B, 0x6A, 0xBE, 0x6E, 0x64, 0x37, + 0x63, 0xE4, 0xCD, 0xEC, 0xAB, 0x3A, 0xF7, 0xCC, 0xA1, 0xB8, 0x0E, 0x82, + 0x49, 0xD7, 0x86, 0x29, 0x9F, 0xA1, 0x94, 0xF2, 0xE3, 0x60, 0x78, 0x98, + 0x81, 0x78, 0x06, 0x4D, 0xF2, 0xEC, 0x9A, 0x0E, 0x57, 0x60, 0x83, 0x9F, + 0xB4, 0xE6, 0x17, 0x2F, 0x1A, 0xB3, 0x5D, 0x02, 0x5B, 0x89, 0x23, 0x3C, + 0xC2, 0x11, 0x05, 0x2A, 0xA7, 0x88, 0x13, 0x18, 0xF3, 0x50, 0x84, 0xD7, + 0xBD, 0x34, 0x2C, 0x27, 0x89, 0x55, 0xFF, 0xCE, 0x4C, 0xE7, 0xDF, 0xA6, + 0x1F, 0x28, 0xC4, 0xF0, 0x54, 0xC3, 0xB9, 0x7C, 0xB7, 0x53, 0xAD, 0xEB, + 0xC2 +}; + +static const unsigned char TA275_DN[] = { + 0x30, 0x7E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, 0x65, + 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, + 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, + 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, 0x65, + 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA275_RSA_N[] = { + 0xE3, 0xFB, 0x7D, 0xA3, 0x72, 0xBA, 0xC2, 0xF0, 0xC9, 0x14, 0x87, 0xF5, + 0x6B, 0x01, 0x4E, 0xE1, 0x6E, 0x40, 0x07, 0xBA, 0x6D, 0x27, 0x5D, 0x7F, + 0xF7, 0x5B, 0x2D, 0xB3, 0x5A, 0xC7, 0x51, 0x5F, 0xAB, 0xA4, 0x32, 0xA6, + 0x61, 0x87, 0xB6, 0x6E, 0x0F, 0x86, 0xD2, 0x30, 0x02, 0x97, 0xF8, 0xD7, + 0x69, 0x57, 0xA1, 0x18, 0x39, 0x5D, 0x6A, 0x64, 0x79, 0xC6, 0x01, 0x59, + 0xAC, 0x3C, 0x31, 0x4A, 0x38, 0x7C, 0xD2, 0x04, 0xD2, 0x4B, 0x28, 0xE8, + 0x20, 0x5F, 0x3B, 0x07, 0xA2, 0xCC, 0x4D, 0x73, 0xDB, 0xF3, 0xAE, 0x4F, + 0xC7, 0x56, 0xD5, 0x5A, 0xA7, 0x96, 0x89, 0xFA, 0xF3, 0xAB, 0x68, 0xD4, + 0x23, 0x86, 0x59, 0x27, 0xCF, 0x09, 0x27, 0xBC, 0xAC, 0x6E, 0x72, 0x83, + 0x1C, 0x30, 0x72, 0xDF, 0xE0, 0xA2, 0xE9, 0xD2, 0xE1, 0x74, 0x75, 0x19, + 0xBD, 0x2A, 0x9E, 0x7B, 0x15, 0x54, 0x04, 0x1B, 0xD7, 0x43, 0x39, 0xAD, + 0x55, 0x28, 0xC5, 0xE2, 0x1A, 0xBB, 0xF4, 0xC0, 0xE4, 0xAE, 0x38, 0x49, + 0x33, 0xCC, 0x76, 0x85, 0x9F, 0x39, 0x45, 0xD2, 0xA4, 0x9E, 0xF2, 0x12, + 0x8C, 0x51, 0xF8, 0x7C, 0xE4, 0x2D, 0x7F, 0xF5, 0xAC, 0x5F, 0xEB, 0x16, + 0x9F, 0xB1, 0x2D, 0xD1, 0xBA, 0xCC, 0x91, 0x42, 0x77, 0x4C, 0x25, 0xC9, + 0x90, 0x38, 0x6F, 0xDB, 0xF0, 0xCC, 0xFB, 0x8E, 0x1E, 0x97, 0x59, 0x3E, + 0xD5, 0x60, 0x4E, 0xE6, 0x05, 0x28, 0xED, 0x49, 0x79, 0x13, 0x4B, 0xBA, + 0x48, 0xDB, 0x2F, 0xF9, 0x72, 0xD3, 0x39, 0xCA, 0xFE, 0x1F, 0xD8, 0x34, + 0x72, 0xF5, 0xB4, 0x40, 0xCF, 0x31, 0x01, 0xC3, 0xEC, 0xDE, 0x11, 0x2D, + 0x17, 0x5D, 0x1F, 0xB8, 0x50, 0xD1, 0x5E, 0x19, 0xA7, 0x69, 0xDE, 0x07, + 0x33, 0x28, 0xCA, 0x50, 0x95, 0xF9, 0xA7, 0x54, 0xCB, 0x54, 0x86, 0x50, + 0x45, 0xA9, 0xF9, 0x49 +}; + +static const unsigned char TA275_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA276_DN[] = { + 0x30, 0x81, 0x80, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, + 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x24, 0x30, + 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x43, 0x65, 0x72, 0x74, + 0x75, 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, + 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA276_RSA_N[] = { + 0xBD, 0xF9, 0x78, 0xF8, 0xE6, 0xD5, 0x80, 0x0C, 0x64, 0x9D, 0x86, 0x1B, + 0x96, 0x64, 0x67, 0x3F, 0x22, 0x3A, 0x1E, 0x75, 0x01, 0x7D, 0xEF, 0xFB, + 0x5C, 0x67, 0x8C, 0xC9, 0xCC, 0x5C, 0x6B, 0xA9, 0x91, 0xE6, 0xB9, 0x42, + 0xE5, 0x20, 0x4B, 0x9B, 0xDA, 0x9B, 0x7B, 0xB9, 0x99, 0x5D, 0xD9, 0x9B, + 0x80, 0x4B, 0xD7, 0x84, 0x40, 0x2B, 0x27, 0xD3, 0xE8, 0xBA, 0x30, 0xBB, + 0x3E, 0x09, 0x1A, 0xA7, 0x49, 0x95, 0xEF, 0x2B, 0x40, 0x24, 0xC2, 0x97, + 0xC7, 0xA7, 0xEE, 0x9B, 0x25, 0xEF, 0xA8, 0x0A, 0x00, 0x97, 0x85, 0x5A, + 0xAA, 0x9D, 0xDC, 0x29, 0xC9, 0xE2, 0x35, 0x07, 0xEB, 0x70, 0x4D, 0x4A, + 0xD6, 0xC1, 0xB3, 0x56, 0xB8, 0xA1, 0x41, 0x38, 0x9B, 0xD1, 0xFB, 0x31, + 0x7F, 0x8F, 0xE0, 0x5F, 0xE1, 0xB1, 0x3F, 0x0F, 0x8E, 0x16, 0x49, 0x60, + 0xD7, 0x06, 0x8D, 0x18, 0xF9, 0xAA, 0x26, 0x10, 0xAB, 0x2A, 0xD3, 0xD0, + 0xD1, 0x67, 0x8D, 0x1B, 0x46, 0xBE, 0x47, 0x30, 0xD5, 0x2E, 0x72, 0xD1, + 0xC5, 0x63, 0xDA, 0xE7, 0x63, 0x79, 0x44, 0x7E, 0x4B, 0x63, 0x24, 0x89, + 0x86, 0x2E, 0x34, 0x3F, 0x29, 0x4C, 0x52, 0x8B, 0x2A, 0xA7, 0xC0, 0xE2, + 0x91, 0x28, 0x89, 0xB9, 0xC0, 0x5B, 0xF9, 0x1D, 0xD9, 0xE7, 0x27, 0xAD, + 0xFF, 0x9A, 0x02, 0x97, 0xC1, 0xC6, 0x50, 0x92, 0x9B, 0x02, 0x2C, 0xBD, + 0xA9, 0xB9, 0x34, 0x59, 0x0A, 0xBF, 0x84, 0x4A, 0xFF, 0xDF, 0xFE, 0xB3, + 0x9F, 0xEB, 0xD9, 0x9E, 0xE0, 0x98, 0x23, 0xEC, 0xA6, 0x6B, 0x77, 0x16, + 0x2A, 0xDB, 0xCC, 0xAD, 0x3B, 0x1C, 0xA4, 0x87, 0xDC, 0x46, 0x73, 0x5E, + 0x19, 0x62, 0x68, 0x45, 0x57, 0xE4, 0x90, 0x82, 0x42, 0xBB, 0x42, 0xD6, + 0xF0, 0x61, 0xE0, 0xC1, 0xA3, 0x3D, 0x66, 0xA3, 0x5D, 0xF4, 0x18, 0xEE, + 0x88, 0xC9, 0x8D, 0x17, 0x45, 0x29, 0x99, 0x32, 0x75, 0x02, 0x31, 0xEE, + 0x29, 0x26, 0xC8, 0x6B, 0x02, 0xE6, 0xB5, 0x62, 0x45, 0x7F, 0x37, 0x15, + 0x5A, 0x23, 0x68, 0x89, 0xD4, 0x3E, 0xDE, 0x4E, 0x27, 0xB0, 0xF0, 0x40, + 0x0C, 0xBC, 0x4D, 0x17, 0xCB, 0x4D, 0xA2, 0xB3, 0x1E, 0xD0, 0x06, 0x5A, + 0xDD, 0xF6, 0x93, 0xCF, 0x57, 0x75, 0x99, 0xF5, 0xFA, 0x86, 0x1A, 0x67, + 0x78, 0xB3, 0xBF, 0x96, 0xFE, 0x34, 0xDC, 0xBD, 0xE7, 0x52, 0x56, 0xE5, + 0xB3, 0xE5, 0x75, 0x7B, 0xD7, 0x41, 0x91, 0x05, 0xDC, 0x5D, 0x69, 0xE3, + 0x95, 0x0D, 0x43, 0xB9, 0xFC, 0x83, 0x96, 0x39, 0x95, 0x7B, 0x6C, 0x80, + 0x5A, 0x4F, 0x13, 0x72, 0xC6, 0xD7, 0x7D, 0x29, 0x7A, 0x44, 0xBA, 0x52, + 0xA4, 0x2A, 0xD5, 0x41, 0x46, 0x09, 0x20, 0xFE, 0x22, 0xA0, 0xB6, 0x5B, + 0x30, 0x8D, 0xBC, 0x89, 0x0C, 0xD5, 0xD7, 0x70, 0xF8, 0x87, 0x52, 0xFD, + 0xDA, 0xEF, 0xAC, 0x51, 0x2E, 0x07, 0xB3, 0x4E, 0xFE, 0xD0, 0x09, 0xDA, + 0x70, 0xEF, 0x98, 0xFA, 0x56, 0xE6, 0x6D, 0xDB, 0xB5, 0x57, 0x4B, 0xDC, + 0xE5, 0x2C, 0x25, 0x15, 0xC8, 0x9E, 0x2E, 0x78, 0x4E, 0xF8, 0xDA, 0x9C, + 0x9E, 0x86, 0x2C, 0xCA, 0x57, 0xF3, 0x1A, 0xE5, 0xC8, 0x92, 0x8B, 0x1A, + 0x82, 0x96, 0x7A, 0xC3, 0xBC, 0x50, 0x12, 0x69, 0xD8, 0x0E, 0x5A, 0x46, + 0x8B, 0x3A, 0xEB, 0x26, 0xFA, 0x23, 0xC9, 0xB6, 0xB0, 0x81, 0xBE, 0x42, + 0x00, 0xA4, 0xF8, 0xD6, 0xFE, 0x30, 0x2E, 0xC7, 0xD2, 0x46, 0xF6, 0xE5, + 0x8E, 0x75, 0xFD, 0xF2, 0xCC, 0xB9, 0xD0, 0x87, 0x5B, 0xCC, 0x06, 0x10, + 0x60, 0xBB, 0x83, 0x35, 0xB7, 0x5E, 0x67, 0xDE, 0x47, 0xEC, 0x99, 0x48, + 0xF1, 0xA4, 0xA1, 0x15, 0xFE, 0xAD, 0x8C, 0x62, 0x8E, 0x39, 0x55, 0x4F, + 0x39, 0x16, 0xB9, 0xB1, 0x63, 0x9D, 0xFF, 0xB7 +}; + +static const unsigned char TA276_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA277_DN[] = { + 0x30, 0x7A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA277_RSA_N[] = { + 0xD1, 0x2D, 0x8E, 0xBB, 0xB7, 0x36, 0xEA, 0x6D, 0x37, 0x91, 0x9F, 0x4E, + 0x93, 0xA7, 0x05, 0xE4, 0x29, 0x03, 0x25, 0xCE, 0x1C, 0x82, 0xF7, 0x7C, + 0x99, 0x9F, 0x41, 0x06, 0xCD, 0xED, 0xA3, 0xBA, 0xC0, 0xDB, 0x09, 0x2C, + 0xC1, 0x7C, 0xDF, 0x29, 0x7E, 0x4B, 0x65, 0x2F, 0x93, 0xA7, 0xD4, 0x01, + 0x6B, 0x03, 0x28, 0x18, 0xA3, 0xD8, 0x9D, 0x05, 0xC1, 0x2A, 0xD8, 0x45, + 0xF1, 0x91, 0xDE, 0xDF, 0x3B, 0xD0, 0x80, 0x02, 0x8C, 0xCF, 0x38, 0x0F, + 0xEA, 0xA7, 0x5C, 0x78, 0x11, 0xA4, 0xC1, 0xC8, 0x85, 0x5C, 0x25, 0xD3, + 0xD3, 0xB2, 0xE7, 0x25, 0xCF, 0x11, 0x54, 0x97, 0xAB, 0x35, 0xC0, 0x1E, + 0x76, 0x1C, 0xEF, 0x00, 0x53, 0x9F, 0x39, 0xDC, 0x14, 0xA5, 0x2C, 0x22, + 0x25, 0xB3, 0x72, 0x72, 0xFC, 0x8D, 0xB3, 0xE5, 0x3E, 0x08, 0x1E, 0x14, + 0x2A, 0x37, 0x0B, 0x88, 0x3C, 0xCA, 0xB0, 0xF4, 0xC8, 0xC2, 0xA1, 0xAE, + 0xBC, 0xC1, 0xBE, 0x29, 0x67, 0x55, 0xE2, 0xFC, 0xAD, 0x59, 0x5C, 0xFE, + 0xBD, 0x57, 0x2C, 0xB0, 0x90, 0x8D, 0xC2, 0xED, 0x37, 0xB6, 0x7C, 0x99, + 0x88, 0xB5, 0xD5, 0x03, 0x9A, 0x3D, 0x15, 0x0D, 0x3D, 0x3A, 0xA8, 0xA8, + 0x45, 0xF0, 0x95, 0x4E, 0x25, 0x59, 0x1D, 0xCD, 0x98, 0x69, 0xBB, 0xD3, + 0xCC, 0x32, 0xC9, 0x8D, 0xEF, 0x81, 0xFE, 0xAD, 0x7D, 0x89, 0xBB, 0xBA, + 0x60, 0x13, 0xCA, 0x65, 0x95, 0x67, 0xA0, 0xF3, 0x19, 0xF6, 0x03, 0x56, + 0xD4, 0x6A, 0xD3, 0x27, 0xE2, 0xA1, 0xAD, 0x83, 0xF0, 0x4A, 0x12, 0x22, + 0x77, 0x1C, 0x05, 0x73, 0xE2, 0x19, 0x71, 0x42, 0xC0, 0xEC, 0x75, 0x46, + 0x9A, 0x90, 0x58, 0xE0, 0x6A, 0x8E, 0x2B, 0xA5, 0x46, 0x30, 0x04, 0x8E, + 0x19, 0xB2, 0x17, 0xE3, 0xBE, 0xA9, 0xBA, 0x7F, 0x56, 0xF1, 0x24, 0x03, + 0xD7, 0xB2, 0x21, 0x28, 0x76, 0x0E, 0x36, 0x30, 0x4C, 0x79, 0xD5, 0x41, + 0x9A, 0x9A, 0xA8, 0xB8, 0x35, 0xBA, 0x0C, 0x3A, 0xF2, 0x44, 0x1B, 0x20, + 0x88, 0xF7, 0xC5, 0x25, 0xD7, 0x3D, 0xC6, 0xE3, 0x3E, 0x43, 0xDD, 0x87, + 0xFE, 0xC4, 0xEA, 0xF5, 0x53, 0x3E, 0x4C, 0x65, 0xFF, 0x3B, 0x4A, 0xCB, + 0x78, 0x5A, 0x6B, 0x17, 0x5F, 0x0D, 0xC7, 0xC3, 0x4F, 0x4E, 0x9A, 0x2A, + 0xA2, 0xED, 0x57, 0x4D, 0x22, 0xE2, 0x46, 0x9A, 0x3F, 0x0F, 0x91, 0x34, + 0x24, 0x7D, 0x55, 0xE3, 0x8C, 0x95, 0x37, 0xD3, 0x1A, 0xF0, 0x09, 0x2B, + 0x2C, 0xD2, 0xC9, 0x8D, 0xB4, 0x0D, 0x00, 0xAB, 0x67, 0x29, 0x28, 0xD8, + 0x01, 0xF5, 0x19, 0x04, 0xB6, 0x1D, 0xBE, 0x76, 0xFE, 0x72, 0x5C, 0xC4, + 0x85, 0xCA, 0xD2, 0x80, 0x41, 0xDF, 0x05, 0xA8, 0xA3, 0xD5, 0x84, 0x90, + 0x4F, 0x0B, 0xF3, 0xE0, 0x3F, 0x9B, 0x19, 0xD2, 0x37, 0x89, 0x3F, 0xF2, + 0x7B, 0x52, 0x1C, 0x8C, 0xF6, 0xE1, 0xF7, 0x3C, 0x07, 0x97, 0x8C, 0x0E, + 0xA2, 0x59, 0x81, 0x0C, 0xB2, 0x90, 0x3D, 0xD3, 0xE3, 0x59, 0x46, 0xED, + 0x0F, 0xA9, 0xA7, 0xDE, 0x80, 0x6B, 0x5A, 0xAA, 0x07, 0xB6, 0x19, 0xCB, + 0xBC, 0x57, 0xF3, 0x97, 0x21, 0x7A, 0x0C, 0xB1, 0x2B, 0x74, 0x3E, 0xEB, + 0xDA, 0xA7, 0x67, 0x2D, 0x4C, 0xC4, 0x98, 0x9E, 0x36, 0x09, 0x76, 0x66, + 0x66, 0xFC, 0x1A, 0x3F, 0xEA, 0x48, 0x54, 0x1C, 0xBE, 0x30, 0xBD, 0x80, + 0x50, 0xBF, 0x7C, 0xB5, 0xCE, 0x00, 0xF6, 0x0C, 0x61, 0xD9, 0xE7, 0x24, + 0x03, 0xE0, 0xE3, 0x01, 0x81, 0x0E, 0xBD, 0xD8, 0x85, 0x34, 0x88, 0xBD, + 0xB2, 0x36, 0xA8, 0x7B, 0x5C, 0x08, 0xE5, 0x44, 0x80, 0x8C, 0x6F, 0xF8, + 0x2F, 0xD5, 0x21, 0xCA, 0x1D, 0x1C, 0xD0, 0xFB, 0xC4, 0xB5, 0x87, 0xD1, + 0x3A, 0x4E, 0xC7, 0x76, 0xB5, 0x35, 0x48, 0xB5 +}; + +static const unsigned char TA277_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA278_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA278_EC_Q[] = { + 0x04, 0x4B, 0x36, 0xE9, 0xAE, 0x57, 0x5E, 0xA8, 0x70, 0xD7, 0xD0, 0x8F, + 0x74, 0x62, 0x77, 0xC3, 0x5E, 0x7A, 0xAA, 0xE5, 0xB6, 0xA2, 0xF1, 0x78, + 0xFD, 0x02, 0x7E, 0x57, 0xDD, 0x91, 0x79, 0x9C, 0x6C, 0xB9, 0x52, 0x88, + 0x54, 0xBC, 0x2F, 0x04, 0xBE, 0xB8, 0xCD, 0xF6, 0x10, 0xD1, 0x29, 0xEC, + 0xB5, 0xD0, 0xA0, 0xC3, 0xF0, 0x89, 0x70, 0x19, 0xBB, 0x51, 0x65, 0xC5, + 0x43, 0x9C, 0xC3, 0x9B, 0x63, 0x9D, 0x20, 0x83, 0x3E, 0x06, 0x0B, 0xA6, + 0x42, 0x44, 0x85, 0x11, 0xA7, 0x4A, 0x3A, 0x2D, 0xE9, 0xD6, 0x68, 0x2F, + 0x48, 0x4E, 0x53, 0x2B, 0x07, 0x3F, 0x4D, 0xBD, 0xB9, 0xAC, 0x77, 0x39, + 0x57 +}; + +static const unsigned char TA279_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA279_EC_Q[] = { + 0x04, 0x78, 0x30, 0x81, 0xE8, 0x63, 0x1E, 0xE5, 0xEB, 0x71, 0x51, 0x0F, + 0xF7, 0x07, 0x07, 0xCA, 0x39, 0x99, 0x7C, 0x4E, 0xD5, 0x0F, 0xCC, 0x30, + 0x30, 0x0B, 0x8F, 0x66, 0x93, 0x3E, 0xCF, 0xBD, 0xC5, 0x86, 0xBD, 0xF9, + 0xB1, 0xB7, 0xB4, 0x3E, 0xB4, 0x07, 0xC8, 0xF3, 0x96, 0x31, 0xF3, 0xED, + 0xA4, 0x4F, 0xF8, 0xA3, 0x4E, 0x8D, 0x29, 0x15, 0x58, 0xB8, 0xD5, 0x6F, + 0x7F, 0xEE, 0x6C, 0x22, 0xB5, 0xB0, 0xAF, 0x48, 0x45, 0x0A, 0xBD, 0xA8, + 0x49, 0x94, 0xBF, 0x84, 0x43, 0xB0, 0xDB, 0x84, 0x4A, 0x03, 0x23, 0x19, + 0x67, 0x6A, 0x6F, 0xC1, 0x6E, 0xBC, 0x06, 0x39, 0x37, 0xD1, 0x88, 0x22, + 0xF7 +}; + +static const unsigned char TA280_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA280_RSA_N[] = { + 0xB0, 0x48, 0x65, 0xA3, 0x0D, 0x1D, 0x42, 0xE3, 0x91, 0x6D, 0x9D, 0x84, + 0xA4, 0x61, 0x96, 0x12, 0xC2, 0xED, 0xC3, 0xDA, 0x23, 0x34, 0x19, 0x76, + 0xF6, 0xEA, 0xFD, 0x55, 0x5A, 0xF6, 0x55, 0x01, 0x53, 0x0F, 0xF2, 0xCC, + 0x8C, 0x97, 0x4F, 0xB9, 0x50, 0xCB, 0xB3, 0x01, 0x44, 0x56, 0x96, 0xFD, + 0x9B, 0x28, 0xEC, 0x7B, 0x74, 0x0B, 0xE7, 0x42, 0x6B, 0x55, 0xCE, 0xC9, + 0x61, 0xB2, 0xE8, 0xAD, 0x40, 0x3C, 0xBA, 0xB9, 0x41, 0x0A, 0x05, 0x4F, + 0x1B, 0x26, 0x85, 0x8F, 0x43, 0xB5, 0x40, 0xB5, 0x85, 0xD1, 0xD4, 0x71, + 0xDC, 0x83, 0x41, 0xF3, 0xF6, 0x45, 0xC7, 0x80, 0xA2, 0x84, 0x50, 0x97, + 0x46, 0xCE, 0xA0, 0x0C, 0xC4, 0x60, 0x56, 0x04, 0x1D, 0x07, 0x5B, 0x46, + 0xA5, 0x0E, 0xB2, 0x4B, 0xA4, 0x0E, 0xA5, 0x7C, 0xEE, 0xF8, 0xD4, 0x62, + 0x03, 0xB9, 0x93, 0x6A, 0x8A, 0x14, 0xB8, 0x70, 0xF8, 0x2E, 0x82, 0x46, + 0x38, 0x23, 0x0E, 0x74, 0xC7, 0x6B, 0x41, 0xB7, 0xD0, 0x29, 0xA3, 0x9D, + 0x80, 0xB0, 0x7E, 0x77, 0x93, 0x63, 0x42, 0xFB, 0x34, 0x83, 0x3B, 0x73, + 0xA3, 0x5A, 0x21, 0x36, 0xEB, 0x47, 0xFA, 0x18, 0x17, 0xD9, 0xBA, 0x66, + 0xC2, 0x93, 0xA4, 0x8F, 0xFC, 0x5D, 0xA4, 0xAD, 0xFC, 0x50, 0x6A, 0x95, + 0xAC, 0xBC, 0x24, 0x33, 0xD1, 0xBD, 0x88, 0x7F, 0x86, 0xF5, 0xF5, 0xB2, + 0x73, 0x2A, 0x8F, 0x7C, 0xAF, 0x08, 0xF2, 0x1A, 0x98, 0x3F, 0xA9, 0x81, + 0x65, 0x3F, 0xC1, 0x8C, 0x89, 0xC5, 0x96, 0x30, 0x9A, 0x0A, 0xCF, 0xF4, + 0xD4, 0xC8, 0x34, 0xED, 0x9D, 0x2F, 0xBC, 0x8D, 0x38, 0x86, 0x53, 0xEE, + 0x97, 0x9F, 0xA9, 0xB2, 0x63, 0x94, 0x17, 0x8D, 0x0F, 0xDC, 0x66, 0x2A, + 0x7C, 0x52, 0x51, 0x75, 0xCB, 0x99, 0x8E, 0xE8, 0x3D, 0x5C, 0xBF, 0x9E, + 0x3B, 0x28, 0x8D, 0x83, 0x02, 0x0F, 0xA9, 0x9F, 0x72, 0xE2, 0x2C, 0x2B, + 0xB3, 0xDC, 0x66, 0x97, 0x00, 0x40, 0xD0, 0xA4, 0x54, 0x8E, 0x9B, 0x5D, + 0x7B, 0x45, 0x36, 0x26, 0xD6, 0x72, 0x43, 0xEB, 0xCF, 0xC0, 0xEA, 0x0D, + 0xDC, 0xCE, 0x12, 0xE6, 0x7D, 0x38, 0x9F, 0x05, 0x27, 0xA8, 0x97, 0x3E, + 0xE9, 0x51, 0xC6, 0x6C, 0x05, 0x28, 0xC1, 0x02, 0x0F, 0xE9, 0x18, 0x6D, + 0xEC, 0xBD, 0x9C, 0x06, 0xD4, 0xA7, 0x49, 0xF4, 0x54, 0x05, 0x6B, 0x6C, + 0x30, 0xF1, 0xEB, 0x03, 0xD5, 0xEA, 0x3D, 0x6A, 0x76, 0xC2, 0xCB, 0x1A, + 0x28, 0x49, 0x4D, 0x7F, 0x64, 0xE0, 0xFA, 0x2B, 0xDA, 0x73, 0x83, 0x81, + 0xFF, 0x91, 0x03, 0xBD, 0x94, 0xBB, 0xE4, 0xB8, 0x8E, 0x9C, 0x32, 0x63, + 0xCD, 0x9F, 0xBB, 0x68, 0x81, 0xB1, 0x84, 0x5B, 0xAF, 0x36, 0xBF, 0x77, + 0xEE, 0x1D, 0x7F, 0xF7, 0x49, 0x9B, 0x52, 0xEC, 0xD2, 0x77, 0x5A, 0x7D, + 0x91, 0x9D, 0x4D, 0xC2, 0x39, 0x2D, 0xE4, 0xBA, 0x82, 0xF8, 0x6F, 0xF2, + 0x4E, 0x1E, 0x0F, 0x4E, 0xE6, 0x3F, 0x59, 0xA5, 0x23, 0xDC, 0x3D, 0x87, + 0xA8, 0x28, 0x58, 0x28, 0xD1, 0xF1, 0x1B, 0x36, 0xDB, 0x4F, 0xC4, 0xFF, + 0xE1, 0x8C, 0x5B, 0x72, 0x8C, 0xC7, 0x26, 0x03, 0x27, 0xA3, 0x39, 0x0A, + 0x01, 0xAA, 0xC0, 0xB2, 0x31, 0x60, 0x83, 0x22, 0xA1, 0x4F, 0x12, 0x09, + 0x01, 0x11, 0xAF, 0x34, 0xD4, 0xCF, 0xD7, 0xAE, 0x62, 0xD3, 0x05, 0x07, + 0xB4, 0x31, 0x75, 0xE0, 0x0D, 0x6D, 0x57, 0x4F, 0x69, 0x87, 0xF9, 0x57, + 0xA9, 0xBA, 0x15, 0xF6, 0xC8, 0x52, 0x6D, 0xA1, 0xCB, 0x9C, 0x1F, 0xE5, + 0xFC, 0x78, 0xA8, 0x35, 0x9A, 0x9F, 0x41, 0x14, 0xCE, 0xA5, 0xB4, 0xCE, + 0x94, 0x08, 0x1C, 0x09, 0xAD, 0x56, 0xE5, 0xDA, 0xB6, 0x49, 0x9A, 0x4A, + 0xEA, 0x63, 0x18, 0x53, 0x9C, 0x2C, 0x2E, 0xC3 +}; + +static const unsigned char TA280_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA281_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA281_RSA_N[] = { + 0xE1, 0xFA, 0x0E, 0xFB, 0x68, 0x00, 0x12, 0xC8, 0x4D, 0xD5, 0xAC, 0x22, + 0xC4, 0x35, 0x01, 0x3B, 0xC5, 0x54, 0xE5, 0x59, 0x76, 0x63, 0xA5, 0x7F, + 0xEB, 0xC1, 0xC4, 0x6A, 0x98, 0xBD, 0x32, 0x8D, 0x17, 0x80, 0xEB, 0x5D, + 0xBA, 0xD1, 0x62, 0x3D, 0x25, 0x23, 0x19, 0x35, 0x14, 0xE9, 0x7F, 0x89, + 0xA7, 0x1B, 0x62, 0x3C, 0xD6, 0x50, 0xE7, 0x34, 0x95, 0x03, 0x32, 0xB1, + 0xB4, 0x93, 0x22, 0x3D, 0xA7, 0xE2, 0xB1, 0xED, 0xE6, 0x7B, 0x4E, 0x2E, + 0x87, 0x9B, 0x0D, 0x33, 0x75, 0x0A, 0xDE, 0xAA, 0x35, 0xE7, 0x7E, 0xE5, + 0x36, 0x98, 0xA2, 0xAE, 0x25, 0x9E, 0x95, 0xB3, 0x32, 0x96, 0xA4, 0x2B, + 0x58, 0x1E, 0xEF, 0x3F, 0xFE, 0x62, 0x34, 0x48, 0x51, 0xD1, 0xB4, 0x8D, + 0x42, 0xAD, 0x60, 0xDA, 0x49, 0x6A, 0x95, 0x70, 0xDD, 0xD2, 0x00, 0xE2, + 0xCC, 0x57, 0x63, 0x02, 0x7B, 0x96, 0xDD, 0x49, 0x97, 0x5B, 0x92, 0x4E, + 0x95, 0xD3, 0xF9, 0xCB, 0x29, 0x1F, 0x18, 0x4A, 0xF8, 0x01, 0x2A, 0xD2, + 0x63, 0x09, 0x6E, 0x24, 0xE9, 0x89, 0xD2, 0xE5, 0xC7, 0x22, 0x4C, 0xDC, + 0x73, 0x86, 0x47, 0x00, 0xAA, 0x0D, 0x88, 0x8E, 0xAE, 0x85, 0x7D, 0x4A, + 0xE9, 0xBB, 0x33, 0x4F, 0x0E, 0x52, 0x70, 0x9D, 0x95, 0xE3, 0x7C, 0x6D, + 0x96, 0x5B, 0x2D, 0x3D, 0x5F, 0xA1, 0x83, 0x46, 0x5D, 0xB6, 0xE3, 0x25, + 0xB8, 0x7C, 0xA7, 0x19, 0x80, 0x1C, 0xEA, 0x65, 0x43, 0xDC, 0x91, 0x79, + 0x36, 0x2C, 0x74, 0x7C, 0xF2, 0x67, 0x06, 0xC9, 0x89, 0xC9, 0xDB, 0xBF, + 0xDA, 0x68, 0xBF, 0x23, 0xED, 0xDC, 0x6B, 0xAD, 0x28, 0x83, 0x79, 0x2F, + 0xEC, 0x38, 0xA5, 0x0D, 0x37, 0x01, 0x67, 0x27, 0x9A, 0xE9, 0x33, 0xD9, + 0x33, 0x5F, 0x37, 0xA1, 0xC5, 0xF0, 0xAB, 0x3D, 0xFA, 0x78, 0xB0, 0xE7, + 0x2C, 0x9F, 0xF6, 0x3E, 0x9F, 0x60, 0xE0, 0xEF, 0x48, 0xE9, 0x90, 0x45, + 0x1E, 0x05, 0x51, 0x78, 0x1A, 0x2C, 0x12, 0x2C, 0x5C, 0x28, 0xAC, 0x0D, + 0xA2, 0x23, 0x9E, 0x34, 0x8F, 0x05, 0xE6, 0xA2, 0x33, 0xCE, 0x11, 0x77, + 0x13, 0xD4, 0x0E, 0xA4, 0x1E, 0x42, 0x1F, 0x86, 0xCD, 0x70, 0xFE, 0xD9, + 0x2E, 0x15, 0x3D, 0x1D, 0xBB, 0xB8, 0xF2, 0x53, 0x57, 0xDB, 0xCC, 0xC6, + 0x74, 0x29, 0x9C, 0x18, 0xB3, 0x36, 0x75, 0x38, 0x2E, 0x0F, 0x54, 0xA1, + 0xF8, 0x92, 0x1F, 0x89, 0x96, 0x4F, 0xBB, 0xD4, 0xEE, 0x9D, 0xE9, 0x3B, + 0x36, 0x42, 0xB5, 0x0A, 0x3B, 0x2A, 0xD4, 0x64, 0x79, 0x36, 0x10, 0xE1, + 0xF9, 0x91, 0x03, 0x2B, 0x7B, 0x20, 0x54, 0xCD, 0x0D, 0x19, 0x1A, 0xC8, + 0x41, 0x32, 0x34, 0xD1, 0xB0, 0x99, 0xE1, 0x90, 0x1E, 0x01, 0x40, 0x36, + 0xB5, 0xB7, 0xFA, 0xA9, 0xE5, 0x77, 0x75, 0xA4, 0x22, 0x81, 0x5D, 0xB0, + 0x8B, 0xE4, 0x27, 0x12, 0x0F, 0x54, 0x88, 0xC6, 0xDB, 0x85, 0x74, 0xE6, + 0xB7, 0xC0, 0xD7, 0xA6, 0x29, 0xFA, 0xDB, 0xDE, 0xF3, 0x93, 0x97, 0x27, + 0x04, 0x55, 0x2F, 0x0A, 0x6F, 0x37, 0xC5, 0x3D, 0x13, 0xAF, 0x0A, 0x00, + 0xA9, 0x2C, 0x8B, 0x1C, 0x81, 0x28, 0xD7, 0xEF, 0x86, 0x31, 0xA9, 0xAE, + 0xF2, 0x6E, 0xB8, 0xCA, 0x6A, 0x2C, 0x54, 0x47, 0xD8, 0x2A, 0x88, 0x2E, + 0xAF, 0xC1, 0x07, 0x10, 0x78, 0xAC, 0x11, 0xA2, 0x2F, 0x42, 0xF0, 0x37, + 0xC5, 0xF2, 0xB8, 0x56, 0xDD, 0x0E, 0x62, 0x2D, 0xCE, 0x2D, 0x56, 0x7E, + 0x55, 0xF2, 0xA7, 0x44, 0xF6, 0x2B, 0x32, 0xF4, 0x23, 0xA8, 0x47, 0xE8, + 0xD4, 0x2A, 0x01, 0x78, 0xCF, 0x6A, 0xC3, 0x37, 0xA8, 0x9E, 0x65, 0xD2, + 0x2C, 0xE5, 0xFA, 0xBA, 0x33, 0xC1, 0x06, 0x44, 0xF6, 0xE6, 0xCF, 0xA5, + 0x0D, 0xA7, 0x66, 0x08, 0x34, 0x8A, 0x2C, 0xF3 +}; + +static const unsigned char TA281_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA282_DN[] = { + 0x30, 0x7B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, 0x61, + 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x53, 0x61, 0x6C, 0x66, 0x6F, + 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x11, 0x43, 0x6F, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x43, 0x41, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x18, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73 +}; + +static const unsigned char TA282_RSA_N[] = { + 0xBE, 0x40, 0x9D, 0xF4, 0x6E, 0xE1, 0xEA, 0x76, 0x87, 0x1C, 0x4D, 0x45, + 0x44, 0x8E, 0xBE, 0x46, 0xC8, 0x83, 0x06, 0x9D, 0xC1, 0x2A, 0xFE, 0x18, + 0x1F, 0x8E, 0xE4, 0x02, 0xFA, 0xF3, 0xAB, 0x5D, 0x50, 0x8A, 0x16, 0x31, + 0x0B, 0x9A, 0x06, 0xD0, 0xC5, 0x70, 0x22, 0xCD, 0x49, 0x2D, 0x54, 0x63, + 0xCC, 0xB6, 0x6E, 0x68, 0x46, 0x0B, 0x53, 0xEA, 0xCB, 0x4C, 0x24, 0xC0, + 0xBC, 0x72, 0x4E, 0xEA, 0xF1, 0x15, 0xAE, 0xF4, 0x54, 0x9A, 0x12, 0x0A, + 0xC3, 0x7A, 0xB2, 0x33, 0x60, 0xE2, 0xDA, 0x89, 0x55, 0xF3, 0x22, 0x58, + 0xF3, 0xDE, 0xDC, 0xCF, 0xEF, 0x83, 0x86, 0xA2, 0x8C, 0x94, 0x4F, 0x9F, + 0x68, 0xF2, 0x98, 0x90, 0x46, 0x84, 0x27, 0xC7, 0x76, 0xBF, 0xE3, 0xCC, + 0x35, 0x2C, 0x8B, 0x5E, 0x07, 0x64, 0x65, 0x82, 0xC0, 0x48, 0xB0, 0xA8, + 0x91, 0xF9, 0x61, 0x9F, 0x76, 0x20, 0x50, 0xA8, 0x91, 0xC7, 0x66, 0xB5, + 0xEB, 0x78, 0x62, 0x03, 0x56, 0xF0, 0x8A, 0x1A, 0x13, 0xEA, 0x31, 0xA3, + 0x1E, 0xA0, 0x99, 0xFD, 0x38, 0xF6, 0xF6, 0x27, 0x32, 0x58, 0x6F, 0x07, + 0xF5, 0x6B, 0xB8, 0xFB, 0x14, 0x2B, 0xAF, 0xB7, 0xAA, 0xCC, 0xD6, 0x63, + 0x5F, 0x73, 0x8C, 0xDA, 0x05, 0x99, 0xA8, 0x38, 0xA8, 0xCB, 0x17, 0x78, + 0x36, 0x51, 0xAC, 0xE9, 0x9E, 0xF4, 0x78, 0x3A, 0x8D, 0xCF, 0x0F, 0xD9, + 0x42, 0xE2, 0x98, 0x0C, 0xAB, 0x2F, 0x9F, 0x0E, 0x01, 0xDE, 0xEF, 0x9F, + 0x99, 0x49, 0xF1, 0x2D, 0xDF, 0xAC, 0x74, 0x4D, 0x1B, 0x98, 0xB5, 0x47, + 0xC5, 0xE5, 0x29, 0xD1, 0xF9, 0x90, 0x18, 0xC7, 0x62, 0x9C, 0xBE, 0x83, + 0xC7, 0x26, 0x7B, 0x3E, 0x8A, 0x25, 0xC7, 0xC0, 0xDD, 0x9D, 0xE6, 0x35, + 0x68, 0x10, 0x20, 0x9D, 0x8F, 0xD8, 0xDE, 0xD2, 0xC3, 0x84, 0x9C, 0x0D, + 0x5E, 0xE8, 0x2F, 0xC9 +}; + +static const unsigned char TA282_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA283_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA283_EC_Q[] = { + 0x04, 0xC6, 0xCB, 0xC7, 0x28, 0xD1, 0xFB, 0x84, 0xF5, 0x9A, 0xEF, 0x42, + 0x14, 0x20, 0xE1, 0x43, 0x6B, 0x6E, 0x75, 0xAD, 0xFC, 0x2B, 0x03, 0x84, + 0xD4, 0x76, 0x93, 0x25, 0xD7, 0x59, 0x3B, 0x41, 0x65, 0x6B, 0x1E, 0xE6, + 0x34, 0x2A, 0xBB, 0x74, 0xF6, 0x12, 0xCE, 0xE8, 0x6D, 0xE7, 0xAB, 0xE4, + 0x3C, 0x4E, 0x3F, 0x44, 0x08, 0x8B, 0xCD, 0x16, 0x71, 0xCB, 0xBF, 0x92, + 0x99, 0xF4, 0xA4, 0xD7, 0x3C, 0x50, 0x54, 0x52, 0x90, 0x85, 0x83, 0x78, + 0x94, 0x67, 0x67, 0xA3, 0x1C, 0x09, 0x19, 0x3D, 0x75, 0x34, 0x85, 0xDE, + 0xED, 0x60, 0x7D, 0xC7, 0x0C, 0xB4, 0x41, 0x52, 0xB9, 0x6E, 0xE5, 0xEE, + 0x42 +}; + +static const unsigned char TA284_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA284_RSA_N[] = { + 0xAE, 0xFF, 0x09, 0x59, 0x91, 0x80, 0x0A, 0x4A, 0x68, 0xE6, 0x24, 0x3F, + 0xB8, 0xA7, 0xE4, 0xC8, 0x3A, 0x0A, 0x3A, 0x16, 0xCD, 0xC9, 0x23, 0x61, + 0xA0, 0x93, 0x71, 0xF2, 0xAB, 0x8B, 0x73, 0x8F, 0xA0, 0x67, 0x65, 0x60, + 0xD2, 0x54, 0x6B, 0x63, 0x51, 0x6F, 0x49, 0x33, 0xE0, 0x72, 0x07, 0x13, + 0x7D, 0x38, 0xCD, 0x06, 0x92, 0x07, 0x29, 0x52, 0x6B, 0x4E, 0x77, 0x6C, + 0x04, 0xD3, 0x95, 0xFA, 0xDD, 0x4C, 0x8C, 0xD9, 0x5D, 0xC1, 0x61, 0x7D, + 0x4B, 0xE7, 0x28, 0xB3, 0x44, 0x81, 0x7B, 0x51, 0xAF, 0xDD, 0x33, 0xB1, + 0x68, 0x7C, 0xD6, 0x4E, 0x4C, 0xFE, 0x2B, 0x68, 0xB9, 0xCA, 0x66, 0x69, + 0xC4, 0xEC, 0x5E, 0x57, 0x7F, 0xF7, 0x0D, 0xC7, 0x9C, 0x36, 0x36, 0xE5, + 0x07, 0x60, 0xAC, 0xC0, 0x4C, 0xEA, 0x08, 0x6C, 0xEF, 0x06, 0x7C, 0x4F, + 0x5B, 0x28, 0x7A, 0x08, 0xFC, 0x93, 0x5D, 0x9B, 0xF6, 0x9C, 0xB4, 0x8B, + 0x86, 0xBA, 0x21, 0xB9, 0xF4, 0xF0, 0xE8, 0x59, 0x5A, 0x28, 0xA1, 0x34, + 0x84, 0x1A, 0x25, 0x91, 0xB6, 0xB5, 0x8F, 0xEF, 0xB2, 0xF9, 0x80, 0xFA, + 0xF9, 0x3D, 0x3C, 0x11, 0x72, 0xD8, 0xE3, 0x2F, 0x86, 0x76, 0xC5, 0x79, + 0x2C, 0xC1, 0xA9, 0x90, 0x93, 0x46, 0x98, 0x67, 0xCB, 0x83, 0x6A, 0xA0, + 0x50, 0x23, 0xA7, 0x3B, 0xF6, 0x81, 0x39, 0xE0, 0xED, 0xF0, 0xB9, 0xBF, + 0x65, 0xF1, 0xD8, 0xCB, 0x7A, 0xFB, 0xEF, 0x73, 0x03, 0xCE, 0x00, 0xF4, + 0x7D, 0xD7, 0xE0, 0x5D, 0x3B, 0x66, 0xB8, 0xDC, 0x8E, 0xBA, 0x83, 0xCB, + 0x87, 0x76, 0x03, 0xFC, 0x25, 0xD9, 0xE7, 0x23, 0x6F, 0x06, 0xFD, 0x67, + 0xF3, 0xE0, 0xFF, 0x84, 0xBC, 0x47, 0xBF, 0xB5, 0x16, 0x18, 0x46, 0x69, + 0x14, 0xCC, 0x05, 0xF7, 0xDB, 0xD3, 0x49, 0xAC, 0x6B, 0xCC, 0xAB, 0xE4, + 0xB5, 0x0B, 0x43, 0x24, 0x5E, 0x4B, 0x6B, 0x4D, 0x67, 0xDF, 0xD6, 0xB5, + 0x3E, 0x4F, 0x78, 0x1F, 0x94, 0x71, 0x24, 0xEA, 0xDE, 0x70, 0xFC, 0xF1, + 0x93, 0xFE, 0x9E, 0x93, 0x5A, 0xE4, 0x94, 0x5A, 0x97, 0x54, 0x0C, 0x35, + 0x7B, 0x5F, 0x6C, 0xEE, 0x00, 0x1F, 0x24, 0xEC, 0x03, 0xBA, 0x02, 0xF5, + 0x76, 0xF4, 0x9F, 0xD4, 0x9A, 0xED, 0x85, 0x2C, 0x38, 0x22, 0x2F, 0xC7, + 0xD8, 0x2F, 0x76, 0x11, 0x4F, 0xFD, 0x6C, 0x5C, 0xE8, 0xF5, 0x8E, 0x27, + 0x87, 0x7F, 0x19, 0x4A, 0x21, 0x47, 0x90, 0x1D, 0x79, 0x8D, 0x1C, 0x5B, + 0xF8, 0xCF, 0x4A, 0x85, 0xE4, 0xED, 0xB3, 0x5B, 0x8D, 0xBE, 0xC4, 0x64, + 0x28, 0x5D, 0x41, 0xC4, 0x6E, 0xAC, 0x38, 0x5A, 0x4F, 0x23, 0x74, 0x74, + 0xA9, 0x12, 0xC3, 0xF6, 0xD2, 0xB9, 0x11, 0x15, 0x33, 0x07, 0x91, 0xD8, + 0x3B, 0x37, 0x3A, 0x63, 0x30, 0x06, 0xD1, 0xC5, 0x22, 0x36, 0x28, 0x62, + 0x23, 0x10, 0xE0, 0x46, 0xCC, 0x97, 0xAC, 0xD6, 0x2B, 0x5D, 0x64, 0x24, + 0xD5, 0xEE, 0x1C, 0x0E, 0xDE, 0xFB, 0x08, 0x5A, 0x75, 0x2A, 0xF6, 0x63, + 0x6D, 0xCE, 0x0B, 0x42, 0xBE, 0xD1, 0xBA, 0x70, 0x1C, 0x9C, 0x21, 0xE5, + 0x0F, 0x31, 0x69, 0x17, 0xD7, 0xFC, 0x0A, 0xB4, 0xDE, 0xED, 0x80, 0x9C, + 0xCB, 0x92, 0xB4, 0x8B, 0xF5, 0xDE, 0x59, 0xA2, 0x58, 0x09, 0xA5, 0x63, + 0x47, 0x0B, 0xE1, 0x41, 0x32, 0x34, 0x41, 0xD9, 0x9A, 0xB1, 0xD9, 0xA8, + 0xB0, 0x1B, 0x5A, 0xDE, 0x0D, 0x0D, 0xF4, 0xE2, 0xB2, 0x5D, 0x35, 0x80, + 0xB9, 0x81, 0xD4, 0x84, 0x69, 0x91, 0x02, 0xCB, 0x75, 0xD0, 0x8D, 0xC5, + 0xB5, 0x3D, 0x09, 0x91, 0x09, 0x8F, 0x14, 0xA1, 0x14, 0x74, 0x79, 0x3E, + 0xD6, 0xC9, 0x15, 0x1D, 0xA4, 0x59, 0x59, 0x22, 0xDC, 0xF6, 0x8A, 0x45, + 0x3D, 0x3C, 0x12, 0xD6, 0x3E, 0x5D, 0x32, 0x2F +}; + +static const unsigned char TA284_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA285_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA285_EC_Q[] = { + 0x04, 0xF1, 0x0B, 0xDD, 0x86, 0x43, 0x20, 0x19, 0xDF, 0x97, 0x85, 0xE8, + 0x22, 0x4A, 0x9B, 0xCF, 0x9D, 0x98, 0xBF, 0xB4, 0x05, 0x26, 0xC9, 0xCB, + 0xE3, 0xA6, 0xD2, 0x8F, 0xC5, 0x9E, 0x78, 0x7B, 0x31, 0x89, 0xA9, 0x89, + 0xAD, 0x27, 0x3C, 0x65, 0x10, 0x82, 0xFC, 0xDF, 0xC3, 0x9D, 0x4E, 0xF0, + 0x33, 0x23, 0xC4, 0xD2, 0x32, 0xF5, 0x1C, 0xB0, 0xDF, 0x33, 0x17, 0x5D, + 0xC5, 0xF0, 0xB1, 0x8A, 0xF9, 0xEF, 0xB9, 0xB7, 0x14, 0xCA, 0x29, 0x4A, + 0xC2, 0x0F, 0xA9, 0x7F, 0x75, 0x65, 0x49, 0x2A, 0x30, 0x67, 0xF4, 0x64, + 0xF7, 0xD6, 0x1A, 0x77, 0xDA, 0xC3, 0xC2, 0x97, 0x61, 0x42, 0x7B, 0x49, + 0xAD +}; + +static const unsigned char TA286_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA286_RSA_N[] = { + 0xD8, 0x8E, 0xA3, 0x89, 0x80, 0x0B, 0xB2, 0x57, 0x52, 0xDC, 0xA9, 0x53, + 0x4C, 0x37, 0xB9, 0x7F, 0x63, 0x17, 0x13, 0xEF, 0xA7, 0x5B, 0x23, 0x5B, + 0x69, 0x75, 0xB0, 0x99, 0x0A, 0x17, 0xC1, 0x8B, 0xC4, 0xDB, 0xA8, 0xE0, + 0xCC, 0x31, 0xBA, 0xC2, 0xF2, 0xCD, 0x5D, 0xE9, 0xB7, 0xF8, 0x1D, 0xAF, + 0x6A, 0xC4, 0x95, 0x87, 0xD7, 0x47, 0xC9, 0x95, 0xD8, 0x82, 0x04, 0x50, + 0x3D, 0x81, 0x08, 0xFF, 0xE4, 0x3D, 0xB3, 0xB1, 0xD6, 0xC5, 0xB2, 0xFD, + 0x88, 0x09, 0xDB, 0x9C, 0x84, 0xEC, 0x25, 0x17, 0x14, 0x87, 0x7F, 0x30, + 0x78, 0x9B, 0x6A, 0x58, 0xC9, 0xB6, 0x73, 0x28, 0x3C, 0x34, 0xF7, 0x99, + 0xF7, 0x7F, 0xD3, 0xA6, 0xF8, 0x1C, 0x45, 0x7C, 0xAD, 0x2C, 0x8C, 0x94, + 0x3F, 0xD8, 0x67, 0x10, 0x53, 0x7E, 0x22, 0xCD, 0x4E, 0x25, 0x51, 0xF0, + 0x25, 0x24, 0x35, 0x11, 0x5E, 0x10, 0xC6, 0xEC, 0x87, 0x66, 0x89, 0x81, + 0x68, 0xBA, 0xCC, 0x2B, 0x9D, 0x47, 0x73, 0x1F, 0xBD, 0xCD, 0x91, 0xA4, + 0x72, 0x6A, 0x9C, 0xA2, 0x1B, 0x18, 0xA0, 0x6F, 0xEC, 0x50, 0xF4, 0x7D, + 0x40, 0xC2, 0xA8, 0x30, 0xCF, 0xBD, 0x73, 0xC8, 0x13, 0x2B, 0x10, 0x13, + 0x1E, 0x8B, 0x9A, 0xA8, 0x3A, 0x94, 0x73, 0xD3, 0x18, 0x69, 0x0A, 0x4A, + 0xFF, 0xC1, 0x01, 0x03, 0xFF, 0x79, 0x7F, 0xB5, 0x48, 0x7F, 0x7B, 0xEE, + 0xE8, 0x29, 0x6F, 0x36, 0x4C, 0x95, 0x61, 0x86, 0xD8, 0xF9, 0xA2, 0x73, + 0x8A, 0xEE, 0xAE, 0x2F, 0x96, 0xEE, 0x68, 0xCD, 0x3D, 0x4D, 0x28, 0x42, + 0xF9, 0x45, 0x2B, 0x32, 0x1B, 0x46, 0x55, 0x16, 0x6A, 0xA6, 0x4B, 0x29, + 0xF9, 0xBB, 0x95, 0x56, 0xBF, 0x46, 0x1D, 0xEC, 0x1D, 0x93, 0x1D, 0xC0, + 0x65, 0xB2, 0x1F, 0xA1, 0x43, 0xAE, 0x56, 0x9E, 0xA0, 0xB1, 0x8F, 0x6B, + 0x12, 0xB7, 0x60, 0x6D, 0x78, 0x0B, 0xCA, 0x8A, 0x5C, 0xED, 0x1E, 0x96, + 0x0E, 0x83, 0xA6, 0x48, 0x95, 0x8D, 0x3B, 0xA3, 0x21, 0xC4, 0xAE, 0x58, + 0xC6, 0x00, 0xB2, 0x84, 0xB4, 0x23, 0xA4, 0x96, 0x86, 0x35, 0xB8, 0xD8, + 0x9E, 0xD8, 0xAC, 0x34, 0x49, 0x98, 0x63, 0x95, 0xC5, 0xCB, 0x6D, 0x48, + 0x47, 0xE2, 0xF2, 0x2E, 0x18, 0x1E, 0xD0, 0x31, 0xAB, 0xDD, 0x74, 0xEC, + 0xF9, 0xDC, 0x8C, 0xB8, 0x1C, 0x8E, 0x68, 0x23, 0xBA, 0xD0, 0xF3, 0x50, + 0xDC, 0xCF, 0x65, 0x8F, 0x73, 0x3A, 0x32, 0xC7, 0x7C, 0xFE, 0xCA, 0x82, + 0x22, 0x4F, 0xBE, 0x8E, 0x62, 0x47, 0x66, 0xE5, 0xCD, 0x87, 0xE2, 0xE8, + 0xD5, 0x0F, 0x18, 0x9F, 0xE5, 0x04, 0x72, 0x4B, 0x46, 0x3C, 0x10, 0xF2, + 0x44, 0xC2, 0x64, 0x56, 0x71, 0x4E, 0x75, 0xE8, 0x9C, 0xC9, 0x26, 0x74, + 0xC5, 0x7D, 0x59, 0xD1, 0x0A, 0x5B, 0x0F, 0x6D, 0xFE, 0x9E, 0x75, 0x1C, + 0x18, 0xC6, 0x1A, 0x3A, 0x7C, 0xD8, 0x0D, 0x04, 0xCC, 0xCD, 0xB7, 0x45, + 0x65, 0x7A, 0xB1, 0x8F, 0xB8, 0xAE, 0x84, 0x48, 0x3E, 0xB3, 0x7A, 0x4D, + 0xA8, 0x03, 0xE2, 0xE2, 0x7E, 0x01, 0x16, 0x59, 0x68, 0x18, 0x43, 0x33, + 0xB0, 0xD2, 0xDC, 0xB0, 0x1A, 0x43, 0x35, 0xEE, 0xA5, 0xDA, 0xA9, 0x46, + 0x5C, 0xAE, 0x86, 0x81, 0x41, 0x01, 0x4A, 0x74, 0x26, 0xEC, 0x9F, 0x06, + 0xBF, 0xC2, 0x05, 0x37, 0x64, 0x75, 0x78, 0x29, 0x68, 0xFD, 0xC5, 0xF5, + 0xEB, 0xFE, 0x47, 0xF9, 0xE4, 0x85, 0xB0, 0xE1, 0x7B, 0x31, 0x9D, 0xA6, + 0x7F, 0x72, 0xA3, 0xB9, 0xC4, 0x2C, 0x2E, 0xCC, 0x99, 0x57, 0x0E, 0x21, + 0x0C, 0x45, 0x01, 0x94, 0x65, 0xEB, 0x65, 0x09, 0xC6, 0x63, 0x22, 0x0B, + 0x33, 0x49, 0x92, 0x48, 0x3C, 0xFC, 0xCD, 0xCE, 0xB0, 0x3E, 0x8E, 0x9E, + 0x8B, 0xF8, 0xFE, 0x49, 0xC5, 0x35, 0x72, 0x47 +}; + +static const unsigned char TA286_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA287_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x1E, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA287_RSA_N[] = { + 0xD3, 0xB2, 0x4A, 0xCF, 0x7A, 0x47, 0xEF, 0x75, 0x9B, 0x23, 0xFA, 0x3A, + 0x2F, 0xD6, 0x50, 0x45, 0x89, 0x35, 0x3A, 0xC6, 0x6B, 0xDB, 0xFE, 0xDB, + 0x00, 0x68, 0xA8, 0xE0, 0x03, 0x11, 0x1D, 0x37, 0x50, 0x08, 0x9F, 0x4D, + 0x4A, 0x68, 0x94, 0x35, 0xB3, 0x53, 0xD1, 0x94, 0x63, 0xA7, 0x20, 0x56, + 0xAF, 0xDE, 0x51, 0x78, 0xEC, 0x2A, 0x3D, 0xF3, 0x48, 0x48, 0x50, 0x3E, + 0x0A, 0xDF, 0x46, 0x55, 0x8B, 0x27, 0x6D, 0xC3, 0x10, 0x4D, 0x0D, 0x91, + 0x52, 0x43, 0xD8, 0x87, 0xE0, 0x5D, 0x4E, 0x36, 0xB5, 0x21, 0xCA, 0x5F, + 0x39, 0x40, 0x04, 0x5F, 0x5B, 0x7E, 0xCC, 0xA3, 0xC6, 0x2B, 0xA9, 0x40, + 0x1E, 0xD9, 0x36, 0x84, 0xD6, 0x48, 0xF3, 0x92, 0x1E, 0x34, 0x46, 0x20, + 0x24, 0xC1, 0xA4, 0x51, 0x8E, 0x4A, 0x1A, 0xEF, 0x50, 0x3F, 0x69, 0x5D, + 0x19, 0x7F, 0x45, 0xC3, 0xC7, 0x01, 0x8F, 0x51, 0xC9, 0x23, 0xE8, 0x72, + 0xAE, 0xB4, 0xBC, 0x56, 0x09, 0x7F, 0x12, 0xCB, 0x1C, 0xB1, 0xAF, 0x29, + 0x90, 0x0A, 0xC9, 0x55, 0xCC, 0x0F, 0xD3, 0xB4, 0x1A, 0xED, 0x47, 0x35, + 0x5A, 0x4A, 0xED, 0x9C, 0x73, 0x04, 0x21, 0xD0, 0xAA, 0xBD, 0x0C, 0x13, + 0xB5, 0x00, 0xCA, 0x26, 0x6C, 0xC4, 0x6B, 0x0C, 0x94, 0x5A, 0x95, 0x94, + 0xDA, 0x50, 0x9A, 0xF1, 0xFF, 0xA5, 0x2B, 0x66, 0x31, 0xA4, 0xC9, 0x38, + 0xA0, 0xDF, 0x1D, 0x1F, 0xB8, 0x09, 0x2E, 0xF3, 0xA7, 0xE8, 0x67, 0x52, + 0xAB, 0x95, 0x1F, 0xE0, 0x46, 0x3E, 0xD8, 0xA4, 0xC3, 0xCA, 0x5A, 0xC5, + 0x31, 0x80, 0xE8, 0x48, 0x9A, 0x9F, 0x94, 0x69, 0xFE, 0x19, 0xDD, 0xD8, + 0x73, 0x7C, 0x81, 0xCA, 0x96, 0xDE, 0x8E, 0xED, 0xB3, 0x32, 0x05, 0x65, + 0x84, 0x34, 0xE6, 0xE6, 0xFD, 0x57, 0x10, 0xB5, 0x5F, 0x76, 0xBF, 0x2F, + 0xB0, 0x10, 0x0D, 0xC5 +}; + +static const unsigned char TA287_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA288_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x21, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x45, 0x56, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA288_RSA_N[] = { + 0x99, 0xF1, 0x84, 0x34, 0x70, 0xBA, 0x2F, 0xB7, 0x30, 0xA0, 0x8E, 0xBD, + 0x7C, 0x04, 0xCF, 0xBE, 0x62, 0xBC, 0x99, 0xFD, 0x82, 0x97, 0xD2, 0x7A, + 0x0A, 0x67, 0x96, 0x38, 0x09, 0xF6, 0x10, 0x4E, 0x95, 0x22, 0x73, 0x99, + 0x8D, 0xDA, 0x15, 0x2D, 0xE7, 0x05, 0xFC, 0x19, 0x73, 0x22, 0xB7, 0x8E, + 0x98, 0x00, 0xBC, 0x3C, 0x3D, 0xAC, 0xA1, 0x6C, 0xFB, 0xD6, 0x79, 0x25, + 0x4B, 0xAD, 0xF0, 0xCC, 0x64, 0xDA, 0x88, 0x3E, 0x29, 0xB8, 0x0F, 0x09, + 0xD3, 0x34, 0xDD, 0x33, 0xF5, 0x62, 0xD1, 0xE1, 0xCD, 0x19, 0xE9, 0xEE, + 0x18, 0x4F, 0x4C, 0x58, 0xAE, 0xE2, 0x1E, 0xD6, 0x0C, 0x5B, 0x15, 0x5A, + 0xD8, 0x3A, 0xB8, 0xC4, 0x18, 0x64, 0x1E, 0xE3, 0x33, 0xB2, 0xB5, 0x89, + 0x77, 0x4E, 0x0C, 0xBF, 0xD9, 0x94, 0x6B, 0x13, 0x97, 0x6F, 0x12, 0xA3, + 0xFE, 0x99, 0xA9, 0x04, 0xCC, 0x15, 0xEC, 0x60, 0x68, 0x36, 0xED, 0x08, + 0x7B, 0xB7, 0xF5, 0xBF, 0x93, 0xED, 0x66, 0x31, 0x83, 0x8C, 0xC6, 0x71, + 0x34, 0x87, 0x4E, 0x17, 0xEA, 0xAF, 0x8B, 0x91, 0x8D, 0x1C, 0x56, 0x41, + 0xAE, 0x22, 0x37, 0x5E, 0x37, 0xF2, 0x1D, 0xD9, 0xD1, 0x2D, 0x0D, 0x2F, + 0x69, 0x51, 0xA7, 0xBE, 0x66, 0xA6, 0x8A, 0x3A, 0x2A, 0xBD, 0xC7, 0x1A, + 0xB1, 0xE1, 0x14, 0xF0, 0xBE, 0x3A, 0x1D, 0xB9, 0xCF, 0x5B, 0xB1, 0x6A, + 0xFE, 0xB4, 0xB1, 0x46, 0x20, 0xA2, 0xFB, 0x1E, 0x3B, 0x70, 0xEF, 0x93, + 0x98, 0x7D, 0x8C, 0x73, 0x96, 0xF2, 0xC5, 0xEF, 0x85, 0x70, 0xAD, 0x29, + 0x26, 0xFC, 0x1E, 0x04, 0x3E, 0x1C, 0xA0, 0xD8, 0x0F, 0xCB, 0x52, 0x83, + 0x62, 0x7C, 0xEE, 0x8B, 0x53, 0x95, 0x90, 0xA9, 0x57, 0xA2, 0xEA, 0x61, + 0x05, 0xD8, 0xF9, 0x4D, 0xC4, 0x27, 0xFA, 0x6E, 0xAD, 0xED, 0xF9, 0xD7, + 0x51, 0xF7, 0x6B, 0xA5 +}; + +static const unsigned char TA288_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA289_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA289_RSA_N[] = { + 0xAD, 0x0E, 0x15, 0xCE, 0xE4, 0x43, 0x80, 0x5C, 0xB1, 0x87, 0xF3, 0xB7, + 0x60, 0xF9, 0x71, 0x12, 0xA5, 0xAE, 0xDC, 0x26, 0x94, 0x88, 0xAA, 0xF4, + 0xCE, 0xF5, 0x20, 0x39, 0x28, 0x58, 0x60, 0x0C, 0xF8, 0x80, 0xDA, 0xA9, + 0x15, 0x95, 0x32, 0x61, 0x3C, 0xB5, 0xB1, 0x28, 0x84, 0x8A, 0x8A, 0xDC, + 0x9F, 0x0A, 0x0C, 0x83, 0x17, 0x7A, 0x8F, 0x90, 0xAC, 0x8A, 0xE7, 0x79, + 0x53, 0x5C, 0x31, 0x84, 0x2A, 0xF6, 0x0F, 0x98, 0x32, 0x36, 0x76, 0xCC, + 0xDE, 0xDD, 0x3C, 0xA8, 0xA2, 0xEF, 0x6A, 0xFB, 0x21, 0xF2, 0x52, 0x61, + 0xDF, 0x9F, 0x20, 0xD7, 0x1F, 0xE2, 0xB1, 0xD9, 0xFE, 0x18, 0x64, 0xD2, + 0x12, 0x5B, 0x5F, 0xF9, 0x58, 0x18, 0x35, 0xBC, 0x47, 0xCD, 0xA1, 0x36, + 0xF9, 0x6B, 0x7F, 0xD4, 0xB0, 0x38, 0x3E, 0xC1, 0x1B, 0xC3, 0x8C, 0x33, + 0xD9, 0xD8, 0x2F, 0x18, 0xFE, 0x28, 0x0F, 0xB3, 0xA7, 0x83, 0xD6, 0xC3, + 0x6E, 0x44, 0xC0, 0x61, 0x35, 0x96, 0x16, 0xFE, 0x59, 0x9C, 0x8B, 0x76, + 0x6D, 0xD7, 0xF1, 0xA2, 0x4B, 0x0D, 0x2B, 0xFF, 0x0B, 0x72, 0xDA, 0x9E, + 0x60, 0xD0, 0x8E, 0x90, 0x35, 0xC6, 0x78, 0x55, 0x87, 0x20, 0xA1, 0xCF, + 0xE5, 0x6D, 0x0A, 0xC8, 0x49, 0x7C, 0x31, 0x98, 0x33, 0x6C, 0x22, 0xE9, + 0x87, 0xD0, 0x32, 0x5A, 0xA2, 0xBA, 0x13, 0x82, 0x11, 0xED, 0x39, 0x17, + 0x9D, 0x99, 0x3A, 0x72, 0xA1, 0xE6, 0xFA, 0xA4, 0xD9, 0xD5, 0x17, 0x31, + 0x75, 0xAE, 0x85, 0x7D, 0x22, 0xAE, 0x3F, 0x01, 0x46, 0x86, 0xF6, 0x28, + 0x79, 0xC8, 0xB1, 0xDA, 0xE4, 0x57, 0x17, 0xC4, 0x7E, 0x1C, 0x0E, 0xB0, + 0xB4, 0x92, 0xA6, 0x56, 0xB3, 0xBD, 0xB2, 0x97, 0xED, 0xAA, 0xA7, 0xF0, + 0xB7, 0xC5, 0xA8, 0x3F, 0x95, 0x16, 0xD0, 0xFF, 0xA1, 0x96, 0xEB, 0x08, + 0x5F, 0x18, 0x77, 0x4F +}; + +static const unsigned char TA289_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA290_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA290_RSA_N[] = { + 0xD9, 0xE7, 0x28, 0x2F, 0x52, 0x3F, 0x36, 0x72, 0x49, 0x88, 0x93, 0x34, + 0xF3, 0xF8, 0x6A, 0x1E, 0x31, 0x54, 0x80, 0x9F, 0xAD, 0x54, 0x41, 0xB5, + 0x47, 0xDF, 0x96, 0xA8, 0xD4, 0xAF, 0x80, 0x2D, 0xB9, 0x0A, 0xCF, 0x75, + 0xFD, 0x89, 0xA5, 0x7D, 0x24, 0xFA, 0xE3, 0x22, 0x0C, 0x2B, 0xBC, 0x95, + 0x17, 0x0B, 0x33, 0xBF, 0x19, 0x4D, 0x41, 0x06, 0x90, 0x00, 0xBD, 0x0C, + 0x4D, 0x10, 0xFE, 0x07, 0xB5, 0xE7, 0x1C, 0x6E, 0x22, 0x55, 0x31, 0x65, + 0x97, 0xBD, 0xD3, 0x17, 0xD2, 0x1E, 0x62, 0xF3, 0xDB, 0xEA, 0x6C, 0x50, + 0x8C, 0x3F, 0x84, 0x0C, 0x96, 0xCF, 0xB7, 0xCB, 0x03, 0xE0, 0xCA, 0x6D, + 0xA1, 0x14, 0x4C, 0x1B, 0x89, 0xDD, 0xED, 0x00, 0xB0, 0x52, 0x7C, 0xAF, + 0x91, 0x6C, 0xB1, 0x38, 0x13, 0xD1, 0xE9, 0x12, 0x08, 0xC0, 0x00, 0xB0, + 0x1C, 0x2B, 0x11, 0xDA, 0x77, 0x70, 0x36, 0x9B, 0xAE, 0xCE, 0x79, 0x87, + 0xDC, 0x82, 0x70, 0xE6, 0x09, 0x74, 0x70, 0x55, 0x69, 0xAF, 0xA3, 0x68, + 0x9F, 0xBF, 0xDD, 0xB6, 0x79, 0xB3, 0xF2, 0x9D, 0x70, 0x29, 0x55, 0xF4, + 0xAB, 0xFF, 0x95, 0x61, 0xF3, 0xC9, 0x40, 0x6F, 0x1D, 0xD1, 0xBE, 0x93, + 0xBB, 0xD3, 0x88, 0x2A, 0xBB, 0x9D, 0xBF, 0x72, 0x5A, 0x56, 0x71, 0x3B, + 0x3F, 0xD4, 0xF3, 0xD1, 0x0A, 0xFE, 0x28, 0xEF, 0xA3, 0xEE, 0xD9, 0x99, + 0xAF, 0x03, 0xD3, 0x8F, 0x60, 0xB7, 0xF2, 0x92, 0xA1, 0xB1, 0xBD, 0x89, + 0x89, 0x1F, 0x30, 0xCD, 0xC3, 0xA6, 0x2E, 0x62, 0x33, 0xAE, 0x16, 0x02, + 0x77, 0x44, 0x5A, 0xE7, 0x81, 0x0A, 0x3C, 0xA7, 0x44, 0x2E, 0x79, 0xB8, + 0x3F, 0x04, 0xBC, 0x5C, 0xA0, 0x87, 0xE1, 0x1B, 0xAF, 0x51, 0x8E, 0xCD, + 0xEC, 0x2C, 0xFA, 0xF8, 0xFE, 0x6D, 0xF0, 0x3A, 0x7C, 0xAA, 0x8B, 0xE4, + 0x67, 0x95, 0x31, 0x8D +}; + +static const unsigned char TA290_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA291_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA291_EC_Q[] = { + 0x04, 0x19, 0xE7, 0xBC, 0xAC, 0x44, 0x65, 0xED, 0xCD, 0xB8, 0x3F, 0x58, + 0xFB, 0x8D, 0xB1, 0x57, 0xA9, 0x44, 0x2D, 0x05, 0x15, 0xF2, 0xEF, 0x0B, + 0xFF, 0x10, 0x74, 0x9F, 0xB5, 0x62, 0x52, 0x5F, 0x66, 0x7E, 0x1F, 0xE5, + 0xDC, 0x1B, 0x45, 0x79, 0x0B, 0xCC, 0xC6, 0x53, 0x0A, 0x9D, 0x8D, 0x5D, + 0x02, 0xD9, 0xA9, 0x59, 0xDE, 0x02, 0x5A, 0xF6, 0x95, 0x2A, 0x0E, 0x8D, + 0x38, 0x4A, 0x8A, 0x49, 0xC6, 0xBC, 0xC6, 0x03, 0x38, 0x07, 0x5F, 0x55, + 0xDA, 0x7E, 0x09, 0x6E, 0xE2, 0x7F, 0x5E, 0xD0, 0x45, 0x20, 0x0F, 0x59, + 0x76, 0x10, 0xD6, 0xA0, 0x24, 0xF0, 0x2D, 0xDE, 0x36, 0xF2, 0x6C, 0x29, + 0x39 +}; + +static const unsigned char TA292_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA292_RSA_N[] = { + 0xE2, 0x3B, 0xE1, 0x11, 0x72, 0xDE, 0xA8, 0xA4, 0xD3, 0xA3, 0x57, 0xAA, + 0x50, 0xA2, 0x8F, 0x0B, 0x77, 0x90, 0xC9, 0xA2, 0xA5, 0xEE, 0x12, 0xCE, + 0x96, 0x5B, 0x01, 0x09, 0x20, 0xCC, 0x01, 0x93, 0xA7, 0x4E, 0x30, 0xB7, + 0x53, 0xF7, 0x43, 0xC4, 0x69, 0x00, 0x57, 0x9D, 0xE2, 0x8D, 0x22, 0xDD, + 0x87, 0x06, 0x40, 0x00, 0x81, 0x09, 0xCE, 0xCE, 0x1B, 0x83, 0xBF, 0xDF, + 0xCD, 0x3B, 0x71, 0x46, 0xE2, 0xD6, 0x66, 0xC7, 0x05, 0xB3, 0x76, 0x27, + 0x16, 0x8F, 0x7B, 0x9E, 0x1E, 0x95, 0x7D, 0xEE, 0xB7, 0x48, 0xA3, 0x08, + 0xDA, 0xD6, 0xAF, 0x7A, 0x0C, 0x39, 0x06, 0x65, 0x7F, 0x4A, 0x5D, 0x1F, + 0xBC, 0x17, 0xF8, 0xAB, 0xBE, 0xEE, 0x28, 0xD7, 0x74, 0x7F, 0x7A, 0x78, + 0x99, 0x59, 0x85, 0x68, 0x6E, 0x5C, 0x23, 0x32, 0x4B, 0xBF, 0x4E, 0xC0, + 0xE8, 0x5A, 0x6D, 0xE3, 0x70, 0xBF, 0x77, 0x10, 0xBF, 0xFC, 0x01, 0xF6, + 0x85, 0xD9, 0xA8, 0x44, 0x10, 0x58, 0x32, 0xA9, 0x75, 0x18, 0xD5, 0xD1, + 0xA2, 0xBE, 0x47, 0xE2, 0x27, 0x6A, 0xF4, 0x9A, 0x33, 0xF8, 0x49, 0x08, + 0x60, 0x8B, 0xD4, 0x5F, 0xB4, 0x3A, 0x84, 0xBF, 0xA1, 0xAA, 0x4A, 0x4C, + 0x7D, 0x3E, 0xCF, 0x4F, 0x5F, 0x6C, 0x76, 0x5E, 0xA0, 0x4B, 0x37, 0x91, + 0x9E, 0xDC, 0x22, 0xE6, 0x6D, 0xCE, 0x14, 0x1A, 0x8E, 0x6A, 0xCB, 0xFE, + 0xCD, 0xB3, 0x14, 0x64, 0x17, 0xC7, 0x5B, 0x29, 0x9E, 0x32, 0xBF, 0xF2, + 0xEE, 0xFA, 0xD3, 0x0B, 0x42, 0xD4, 0xAB, 0xB7, 0x41, 0x32, 0xDA, 0x0C, + 0xD4, 0xEF, 0xF8, 0x81, 0xD5, 0xBB, 0x8D, 0x58, 0x3F, 0xB5, 0x1B, 0xE8, + 0x49, 0x28, 0xA2, 0x70, 0xDA, 0x31, 0x04, 0xDD, 0xF7, 0xB2, 0x16, 0xF2, + 0x4C, 0x0A, 0x4E, 0x07, 0xA8, 0xED, 0x4A, 0x3D, 0x5E, 0xB5, 0x7F, 0xA3, + 0x90, 0xC3, 0xAF, 0x27 +}; + +static const unsigned char TA292_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA293_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x32 +}; + +static const unsigned char TA293_RSA_N[] = { + 0xBB, 0x37, 0xCD, 0x34, 0xDC, 0x7B, 0x6B, 0xC9, 0xB2, 0x68, 0x90, 0xAD, + 0x4A, 0x75, 0xFF, 0x46, 0xBA, 0x21, 0x0A, 0x08, 0x8D, 0xF5, 0x19, 0x54, + 0xC9, 0xFB, 0x88, 0xDB, 0xF3, 0xAE, 0xF2, 0x3A, 0x89, 0x91, 0x3C, 0x7A, + 0xE6, 0xAB, 0x06, 0x1A, 0x6B, 0xCF, 0xAC, 0x2D, 0xE8, 0x5E, 0x09, 0x24, + 0x44, 0xBA, 0x62, 0x9A, 0x7E, 0xD6, 0xA3, 0xA8, 0x7E, 0xE0, 0x54, 0x75, + 0x20, 0x05, 0xAC, 0x50, 0xB7, 0x9C, 0x63, 0x1A, 0x6C, 0x30, 0xDC, 0xDA, + 0x1F, 0x19, 0xB1, 0xD7, 0x1E, 0xDE, 0xFD, 0xD7, 0xE0, 0xCB, 0x94, 0x83, + 0x37, 0xAE, 0xEC, 0x1F, 0x43, 0x4E, 0xDD, 0x7B, 0x2C, 0xD2, 0xBD, 0x2E, + 0xA5, 0x2F, 0xE4, 0xA9, 0xB8, 0xAD, 0x3A, 0xD4, 0x99, 0xA4, 0xB6, 0x25, + 0xE9, 0x9B, 0x6B, 0x00, 0x60, 0x92, 0x60, 0xFF, 0x4F, 0x21, 0x49, 0x18, + 0xF7, 0x67, 0x90, 0xAB, 0x61, 0x06, 0x9C, 0x8F, 0xF2, 0xBA, 0xE9, 0xB4, + 0xE9, 0x92, 0x32, 0x6B, 0xB5, 0xF3, 0x57, 0xE8, 0x5D, 0x1B, 0xCD, 0x8C, + 0x1D, 0xAB, 0x95, 0x04, 0x95, 0x49, 0xF3, 0x35, 0x2D, 0x96, 0xE3, 0x49, + 0x6D, 0xDD, 0x77, 0xE3, 0xFB, 0x49, 0x4B, 0xB4, 0xAC, 0x55, 0x07, 0xA9, + 0x8F, 0x95, 0xB3, 0xB4, 0x23, 0xBB, 0x4C, 0x6D, 0x45, 0xF0, 0xF6, 0xA9, + 0xB2, 0x95, 0x30, 0xB4, 0xFD, 0x4C, 0x55, 0x8C, 0x27, 0x4A, 0x57, 0x14, + 0x7C, 0x82, 0x9D, 0xCD, 0x73, 0x92, 0xD3, 0x16, 0x4A, 0x06, 0x0C, 0x8C, + 0x50, 0xD1, 0x8F, 0x1E, 0x09, 0xBE, 0x17, 0xA1, 0xE6, 0x21, 0xCA, 0xFD, + 0x83, 0xE5, 0x10, 0xBC, 0x83, 0xA5, 0x0A, 0xC4, 0x67, 0x28, 0xF6, 0x73, + 0x14, 0x14, 0x3D, 0x46, 0x76, 0xC3, 0x87, 0x14, 0x89, 0x21, 0x34, 0x4D, + 0xAF, 0x0F, 0x45, 0x0C, 0xA6, 0x49, 0xA1, 0xBA, 0xBB, 0x9C, 0xC5, 0xB1, + 0x33, 0x83, 0x29, 0x85 +}; + +static const unsigned char TA293_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA294_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x33 +}; + +static const unsigned char TA294_EC_Q[] = { + 0x04, 0xDD, 0xA7, 0xD9, 0xBB, 0x8A, 0xB8, 0x0B, 0xFB, 0x0B, 0x7F, 0x21, + 0xD2, 0xF0, 0xBE, 0xBE, 0x73, 0xF3, 0x33, 0x5D, 0x1A, 0xBC, 0x34, 0xEA, + 0xDE, 0xC6, 0x9B, 0xBC, 0xD0, 0x95, 0xF6, 0xF0, 0xCC, 0xD0, 0x0B, 0xBA, + 0x61, 0x5B, 0x51, 0x46, 0x7E, 0x9E, 0x2D, 0x9F, 0xEE, 0x8E, 0x63, 0x0C, + 0x17, 0xEC, 0x07, 0x70, 0xF5, 0xCF, 0x84, 0x2E, 0x40, 0x83, 0x9C, 0xE8, + 0x3F, 0x41, 0x6D, 0x3B, 0xAD, 0xD3, 0xA4, 0x14, 0x59, 0x36, 0x78, 0x9D, + 0x03, 0x43, 0xEE, 0x10, 0x13, 0x6C, 0x72, 0xDE, 0xAE, 0x88, 0xA7, 0xA1, + 0x6B, 0xB5, 0x43, 0xCE, 0x67, 0xDC, 0x23, 0xFF, 0x03, 0x1C, 0xA3, 0xE2, + 0x3E +}; + +static const unsigned char TA295_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, + 0x6E, 0x63, 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA295_RSA_N[] = { + 0xC6, 0xCC, 0xE5, 0x73, 0xE6, 0xFB, 0xD4, 0xBB, 0xE5, 0x2D, 0x2D, 0x32, + 0xA6, 0xDF, 0xE5, 0x81, 0x3F, 0xC9, 0xCD, 0x25, 0x49, 0xB6, 0x71, 0x2A, + 0xC3, 0xD5, 0x94, 0x34, 0x67, 0xA2, 0x0A, 0x1C, 0xB0, 0x5F, 0x69, 0xA6, + 0x40, 0xB1, 0xC4, 0xB7, 0xB2, 0x8F, 0xD0, 0x98, 0xA4, 0xA9, 0x41, 0x59, + 0x3A, 0xD3, 0xDC, 0x94, 0xD6, 0x3C, 0xDB, 0x74, 0x38, 0xA4, 0x4A, 0xCC, + 0x4D, 0x25, 0x82, 0xF7, 0x4A, 0xA5, 0x53, 0x12, 0x38, 0xEE, 0xF3, 0x49, + 0x6D, 0x71, 0x91, 0x7E, 0x63, 0xB6, 0xAB, 0xA6, 0x5F, 0xC3, 0xA4, 0x84, + 0xF8, 0x4F, 0x62, 0x51, 0xBE, 0xF8, 0xC5, 0xEC, 0xDB, 0x38, 0x92, 0xE3, + 0x06, 0xE5, 0x08, 0x91, 0x0C, 0xC4, 0x28, 0x41, 0x55, 0xFB, 0xCB, 0x5A, + 0x89, 0x15, 0x7E, 0x71, 0xE8, 0x35, 0xBF, 0x4D, 0x72, 0x09, 0x3D, 0xBE, + 0x3A, 0x38, 0x50, 0x5B, 0x77, 0x31, 0x1B, 0x8D, 0xB3, 0xC7, 0x24, 0x45, + 0x9A, 0xA7, 0xAC, 0x6D, 0x00, 0x14, 0x5A, 0x04, 0xB7, 0xBA, 0x13, 0xEB, + 0x51, 0x0A, 0x98, 0x41, 0x41, 0x22, 0x4E, 0x65, 0x61, 0x87, 0x81, 0x41, + 0x50, 0xA6, 0x79, 0x5C, 0x89, 0xDE, 0x19, 0x4A, 0x57, 0xD5, 0x2E, 0xE6, + 0x5D, 0x1C, 0x53, 0x2C, 0x7E, 0x98, 0xCD, 0x1A, 0x06, 0x16, 0xA4, 0x68, + 0x73, 0xD0, 0x34, 0x04, 0x13, 0x5C, 0xA1, 0x71, 0xD3, 0x5A, 0x7C, 0x55, + 0xDB, 0x5E, 0x64, 0xE1, 0x37, 0x87, 0x30, 0x56, 0x04, 0xE5, 0x11, 0xB4, + 0x29, 0x80, 0x12, 0xF1, 0x79, 0x39, 0x88, 0xA2, 0x02, 0x11, 0x7C, 0x27, + 0x66, 0xB7, 0x88, 0xB7, 0x78, 0xF2, 0xCA, 0x0A, 0xA8, 0x38, 0xAB, 0x0A, + 0x64, 0xC2, 0xBF, 0x66, 0x5D, 0x95, 0x84, 0xC1, 0xA1, 0x25, 0x1E, 0x87, + 0x5D, 0x1A, 0x50, 0x0B, 0x20, 0x12, 0xCC, 0x41, 0xBB, 0x6E, 0x0B, 0x51, + 0x38, 0xB8, 0x4B, 0xCB +}; + +static const unsigned char TA295_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA296_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1D, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x50, 0x33, 0x38, 0x34, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA296_EC_Q[] = { + 0x04, 0xC1, 0x44, 0xA1, 0xCF, 0x11, 0x97, 0x50, 0x9A, 0xDE, 0x23, 0x82, + 0x35, 0x07, 0xCD, 0xD0, 0xCB, 0x18, 0x9D, 0xD2, 0xF1, 0x7F, 0x77, 0x35, + 0x4F, 0x3B, 0xDD, 0x94, 0x72, 0x52, 0xED, 0xC2, 0x3B, 0xF8, 0xEC, 0xFA, + 0x7B, 0x6B, 0x58, 0x20, 0xEC, 0x99, 0xAE, 0xC9, 0xFC, 0x68, 0xB3, 0x75, + 0xB9, 0xDB, 0x09, 0xEC, 0xC8, 0x13, 0xF5, 0x4E, 0xC6, 0x0A, 0x1D, 0x66, + 0x30, 0x4C, 0xBB, 0x1F, 0x47, 0x0A, 0x3C, 0x61, 0x10, 0x42, 0x29, 0x7C, + 0xA5, 0x08, 0x0E, 0xE0, 0x22, 0xE9, 0xD3, 0x35, 0x68, 0xCE, 0x9B, 0x63, + 0x9F, 0x84, 0xB5, 0x99, 0x4D, 0x58, 0xA0, 0x8E, 0xF5, 0x54, 0xE7, 0x95, + 0xC9 +}; + +static const unsigned char TA297_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x34, 0x30, 0x39, 0x36, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA297_RSA_N[] = { + 0xB3, 0xD0, 0xF4, 0xC9, 0x79, 0x11, 0x9D, 0xFD, 0xFC, 0x66, 0x81, 0xE7, + 0xCC, 0xD5, 0xE4, 0xBC, 0xEC, 0x81, 0x3E, 0x6A, 0x35, 0x8E, 0x2E, 0xB7, + 0xE7, 0xDE, 0xAF, 0xF9, 0x07, 0x4D, 0xCF, 0x30, 0x9D, 0xEA, 0x09, 0x0B, + 0x99, 0xBD, 0x6C, 0x57, 0xDA, 0x18, 0x4A, 0xB8, 0x78, 0xAC, 0x3A, 0x39, + 0xA8, 0xA6, 0x48, 0xAC, 0x2E, 0x72, 0xE5, 0xBD, 0xEB, 0xF1, 0x1A, 0xCD, + 0xE7, 0xA4, 0x03, 0xA9, 0x3F, 0x11, 0xB4, 0xD8, 0x2F, 0x89, 0x16, 0xFB, + 0x94, 0x01, 0x3D, 0xBB, 0x2F, 0xF8, 0x13, 0x05, 0xA1, 0x78, 0x1C, 0x8E, + 0x28, 0xE0, 0x45, 0xE0, 0x83, 0xF4, 0x59, 0x1B, 0x95, 0xB3, 0xAE, 0x7E, + 0x03, 0x45, 0xE5, 0xBE, 0xC2, 0x42, 0xFE, 0xEE, 0xF2, 0x3C, 0xB6, 0x85, + 0x13, 0x98, 0x32, 0x9D, 0x16, 0xA8, 0x29, 0xC2, 0x0B, 0x1C, 0x38, 0xDC, + 0x9F, 0x31, 0x77, 0x5C, 0xBF, 0x27, 0xA3, 0xFC, 0x27, 0xAC, 0xB7, 0x2B, + 0xBD, 0x74, 0x9B, 0x17, 0x2D, 0xF2, 0x81, 0xDA, 0x5D, 0xB0, 0xE1, 0x23, + 0x17, 0x3E, 0x88, 0x4A, 0x12, 0x23, 0xD0, 0xEA, 0xCF, 0x9D, 0xDE, 0x03, + 0x17, 0xB1, 0x42, 0x4A, 0xA0, 0x16, 0x4C, 0xA4, 0x6D, 0x93, 0xE9, 0x3F, + 0x3A, 0xEE, 0x3A, 0x7C, 0x9D, 0x58, 0x9D, 0xF4, 0x4E, 0x8F, 0xFC, 0x3B, + 0x23, 0xC8, 0x6D, 0xB8, 0xE2, 0x05, 0xDA, 0xCC, 0xEB, 0xEC, 0xC3, 0x31, + 0xF4, 0xD7, 0xA7, 0x29, 0x54, 0x80, 0xCF, 0x44, 0x5B, 0x4C, 0x6F, 0x30, + 0x9E, 0xF3, 0xCC, 0xDD, 0x1F, 0x94, 0x43, 0x9D, 0x4D, 0x7F, 0x70, 0x70, + 0x0D, 0xD4, 0x3A, 0xD1, 0x37, 0xF0, 0x6C, 0x9D, 0x9B, 0xC0, 0x14, 0x93, + 0x58, 0xEF, 0xCD, 0x41, 0x38, 0x75, 0xBC, 0x13, 0x03, 0x95, 0x7C, 0x7F, + 0xE3, 0x5C, 0xE9, 0xD5, 0x0D, 0xD5, 0xE2, 0x7C, 0x10, 0x62, 0xAA, 0x6B, + 0xF0, 0x3D, 0x76, 0xF3, 0x3F, 0xA3, 0xE8, 0xB0, 0xC1, 0xFD, 0xEF, 0xAA, + 0x57, 0x4D, 0xAC, 0x86, 0xA7, 0x18, 0xB4, 0x29, 0xC1, 0x2C, 0x0E, 0xBF, + 0x64, 0xBE, 0x29, 0x8C, 0xD8, 0x02, 0x2D, 0xCD, 0x5C, 0x2F, 0xF2, 0x7F, + 0xEF, 0x15, 0xF4, 0x0C, 0x15, 0xAC, 0x0A, 0xB0, 0xF1, 0xD3, 0x0D, 0x4F, + 0x6A, 0x4D, 0x77, 0x97, 0x01, 0xA0, 0xF1, 0x66, 0xB7, 0xB7, 0xCE, 0xEF, + 0xCE, 0xEC, 0xEC, 0xA5, 0x75, 0xCA, 0xAC, 0xE3, 0xE1, 0x63, 0xF7, 0xB8, + 0xA1, 0x04, 0xC8, 0xBC, 0x7B, 0x3F, 0x5D, 0x2D, 0x16, 0x22, 0x56, 0xED, + 0x48, 0x49, 0xFE, 0xA7, 0x2F, 0x79, 0x30, 0x25, 0x9B, 0xBA, 0x6B, 0x2D, + 0x3F, 0x9D, 0x3B, 0xC4, 0x17, 0xE7, 0x1D, 0x2E, 0xFB, 0xF2, 0xCF, 0xA6, + 0xFC, 0xE3, 0x14, 0x2C, 0x96, 0x98, 0x21, 0x8C, 0xB4, 0x91, 0xE9, 0x19, + 0x60, 0x83, 0xF2, 0x30, 0x2B, 0x06, 0x73, 0x50, 0xD5, 0x98, 0x3B, 0x06, + 0xE9, 0xC7, 0x8A, 0x0C, 0x60, 0x8C, 0x28, 0xF8, 0x52, 0x9B, 0x6E, 0xE1, + 0xF6, 0x4D, 0xBB, 0x06, 0x24, 0x9B, 0xD7, 0x2B, 0x26, 0x3F, 0xFD, 0x2A, + 0x2F, 0x71, 0xF5, 0xD6, 0x24, 0xBE, 0x7F, 0x31, 0x9E, 0x0F, 0x6D, 0xE8, + 0x8F, 0x4F, 0x4D, 0xA3, 0x3F, 0xFF, 0x35, 0xEA, 0xDF, 0x49, 0x5E, 0x41, + 0x8F, 0x86, 0xF9, 0xF1, 0x77, 0x79, 0x4B, 0x1B, 0xB4, 0xA3, 0x5E, 0x2F, + 0xFB, 0x46, 0x02, 0xD0, 0x66, 0x13, 0x5E, 0x5E, 0x85, 0x4F, 0xCE, 0xD8, + 0x70, 0x88, 0x7B, 0xCE, 0x01, 0xB5, 0x96, 0x97, 0xD7, 0xCD, 0x7D, 0xFD, + 0x82, 0xF8, 0xC2, 0x24, 0xC1, 0xCA, 0x01, 0x39, 0x4F, 0x8D, 0xA2, 0xC1, + 0x14, 0x40, 0x1F, 0x9C, 0x66, 0xD5, 0x0C, 0x09, 0x46, 0xD6, 0xF2, 0xD0, + 0xD1, 0x48, 0x76, 0x56, 0x3A, 0x43, 0xCB, 0xB6, 0x0A, 0x11, 0x39, 0xBA, + 0x8C, 0x13, 0x6C, 0x06, 0xB5, 0x9E, 0xCF, 0xEB +}; + +static const unsigned char TA297_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA298_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x18, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA298_RSA_N[] = { + 0xBF, 0xE6, 0x90, 0x73, 0x68, 0xDE, 0xBB, 0xE4, 0x5D, 0x4A, 0x3C, 0x30, + 0x22, 0x30, 0x69, 0x33, 0xEC, 0xC2, 0xA7, 0x25, 0x2E, 0xC9, 0x21, 0x3D, + 0xF2, 0x8A, 0xD8, 0x59, 0xC2, 0xE1, 0x29, 0xA7, 0x3D, 0x58, 0xAB, 0x76, + 0x9A, 0xCD, 0xAE, 0x7B, 0x1B, 0x84, 0x0D, 0xC4, 0x30, 0x1F, 0xF3, 0x1B, + 0xA4, 0x38, 0x16, 0xEB, 0x56, 0xC6, 0x97, 0x6D, 0x1D, 0xAB, 0xB2, 0x79, + 0xF2, 0xCA, 0x11, 0xD2, 0xE4, 0x5F, 0xD6, 0x05, 0x3C, 0x52, 0x0F, 0x52, + 0x1F, 0xC6, 0x9E, 0x15, 0xA5, 0x7E, 0xBE, 0x9F, 0xA9, 0x57, 0x16, 0x59, + 0x55, 0x72, 0xAF, 0x68, 0x93, 0x70, 0xC2, 0xB2, 0xBA, 0x75, 0x99, 0x6A, + 0x73, 0x32, 0x94, 0xD1, 0x10, 0x44, 0x10, 0x2E, 0xDF, 0x82, 0xF3, 0x07, + 0x84, 0xE6, 0x74, 0x3B, 0x6D, 0x71, 0xE2, 0x2D, 0x0C, 0x1B, 0xEE, 0x20, + 0xD5, 0xC9, 0x20, 0x1D, 0x63, 0x29, 0x2D, 0xCE, 0xEC, 0x5E, 0x4E, 0xC8, + 0x93, 0xF8, 0x21, 0x61, 0x9B, 0x34, 0xEB, 0x05, 0xC6, 0x5E, 0xEC, 0x5B, + 0x1A, 0xBC, 0xEB, 0xC9, 0xCF, 0xCD, 0xAC, 0x34, 0x40, 0x5F, 0xB1, 0x7A, + 0x66, 0xEE, 0x77, 0xC8, 0x48, 0xA8, 0x66, 0x57, 0x57, 0x9F, 0x54, 0x58, + 0x8E, 0x0C, 0x2B, 0xB7, 0x4F, 0xA7, 0x30, 0xD9, 0x56, 0xEE, 0xCA, 0x7B, + 0x5D, 0xE3, 0xAD, 0xC9, 0x4F, 0x5E, 0xE5, 0x35, 0xE7, 0x31, 0xCB, 0xDA, + 0x93, 0x5E, 0xDC, 0x8E, 0x8F, 0x80, 0xDA, 0xB6, 0x91, 0x98, 0x40, 0x90, + 0x79, 0xC3, 0x78, 0xC7, 0xB6, 0xB1, 0xC4, 0xB5, 0x6A, 0x18, 0x38, 0x03, + 0x10, 0x8D, 0xD8, 0xD4, 0x37, 0xA4, 0x2E, 0x05, 0x7D, 0x88, 0xF5, 0x82, + 0x3E, 0x10, 0x91, 0x70, 0xAB, 0x55, 0x82, 0x41, 0x32, 0xD7, 0xDB, 0x04, + 0x73, 0x2A, 0x6E, 0x91, 0x01, 0x7C, 0x21, 0x4C, 0xD4, 0xBC, 0xAE, 0x1B, + 0x03, 0x75, 0x5D, 0x78, 0x66, 0xD9, 0x3A, 0x31, 0x44, 0x9A, 0x33, 0x40, + 0xBF, 0x08, 0xD7, 0x5A, 0x49, 0xA4, 0xC2, 0xE6, 0xA9, 0xA0, 0x67, 0xDD, + 0xA4, 0x27, 0xBC, 0xA1, 0x4F, 0x39, 0xB5, 0x11, 0x58, 0x17, 0xF7, 0x24, + 0x5C, 0x46, 0x8F, 0x64, 0xF7, 0xC1, 0x69, 0x88, 0x76, 0x98, 0x76, 0x3D, + 0x59, 0x5D, 0x42, 0x76, 0x87, 0x89, 0x97, 0x69, 0x7A, 0x48, 0xF0, 0xE0, + 0xA2, 0x12, 0x1B, 0x66, 0x9A, 0x74, 0xCA, 0xDE, 0x4B, 0x1E, 0xE7, 0x0E, + 0x63, 0xAE, 0xE6, 0xD4, 0xEF, 0x92, 0x92, 0x3A, 0x9E, 0x3D, 0xDC, 0x00, + 0xE4, 0x45, 0x25, 0x89, 0xB6, 0x9A, 0x44, 0x19, 0x2B, 0x7E, 0xC0, 0x94, + 0xB4, 0xD2, 0x61, 0x6D, 0xEB, 0x33, 0xD9, 0xC5, 0xDF, 0x4B, 0x04, 0x00, + 0xCC, 0x7D, 0x1C, 0x95, 0xC3, 0x8F, 0xF7, 0x21, 0xB2, 0xB2, 0x11, 0xB7, + 0xBB, 0x7F, 0xF2, 0xD5, 0x8C, 0x70, 0x2C, 0x41, 0x60, 0xAA, 0xB1, 0x63, + 0x18, 0x44, 0x95, 0x1A, 0x76, 0x62, 0x7E, 0xF6, 0x80, 0xB0, 0xFB, 0xE8, + 0x64, 0xA6, 0x33, 0xD1, 0x89, 0x07, 0xE1, 0xBD, 0xB7, 0xE6, 0x43, 0xA4, + 0x18, 0xB8, 0xA6, 0x77, 0x01, 0xE1, 0x0F, 0x94, 0x0C, 0x21, 0x1D, 0xB2, + 0x54, 0x29, 0x25, 0x89, 0x6C, 0xE5, 0x0E, 0x52, 0x51, 0x47, 0x74, 0xBE, + 0x26, 0xAC, 0xB6, 0x41, 0x75, 0xDE, 0x7A, 0xAC, 0x5F, 0x8D, 0x3F, 0xC9, + 0xBC, 0xD3, 0x41, 0x11, 0x12, 0x5B, 0xE5, 0x10, 0x50, 0xEB, 0x31, 0xC5, + 0xCA, 0x72, 0x16, 0x22, 0x09, 0xDF, 0x7C, 0x4C, 0x75, 0x3F, 0x63, 0xEC, + 0x21, 0x5F, 0xC4, 0x20, 0x51, 0x6B, 0x6F, 0xB1, 0xAB, 0x86, 0x8B, 0x4F, + 0xC2, 0xD6, 0x45, 0x5F, 0x9D, 0x20, 0xFC, 0xA1, 0x1E, 0xC5, 0xC0, 0x8F, + 0xA2, 0xB1, 0x7E, 0x0A, 0x26, 0x99, 0xF5, 0xE4, 0x69, 0x2F, 0x98, 0x1D, + 0x2D, 0xF5, 0xD9, 0xA9, 0xB2, 0x1D, 0xE5, 0x1B +}; + +static const unsigned char TA298_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA299_DN[] = { + 0x30, 0x81, 0xB4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, + 0x74, 0x31, 0x40, 0x30, 0x3E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x14, 0x37, + 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, + 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x5F, 0x32, 0x30, 0x34, 0x38, + 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x2E, 0x20, 0x62, 0x79, 0x20, + 0x72, 0x65, 0x66, 0x2E, 0x20, 0x28, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x73, + 0x20, 0x6C, 0x69, 0x61, 0x62, 0x2E, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1C, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, + 0x65, 0x74, 0x20, 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, + 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, + 0x34, 0x38, 0x29 +}; + +static const unsigned char TA299_RSA_N[] = { + 0xAD, 0x4D, 0x4B, 0xA9, 0x12, 0x86, 0xB2, 0xEA, 0xA3, 0x20, 0x07, 0x15, + 0x16, 0x64, 0x2A, 0x2B, 0x4B, 0xD1, 0xBF, 0x0B, 0x4A, 0x4D, 0x8E, 0xED, + 0x80, 0x76, 0xA5, 0x67, 0xB7, 0x78, 0x40, 0xC0, 0x73, 0x42, 0xC8, 0x68, + 0xC0, 0xDB, 0x53, 0x2B, 0xDD, 0x5E, 0xB8, 0x76, 0x98, 0x35, 0x93, 0x8B, + 0x1A, 0x9D, 0x7C, 0x13, 0x3A, 0x0E, 0x1F, 0x5B, 0xB7, 0x1E, 0xCF, 0xE5, + 0x24, 0x14, 0x1E, 0xB1, 0x81, 0xA9, 0x8D, 0x7D, 0xB8, 0xCC, 0x6B, 0x4B, + 0x03, 0xF1, 0x02, 0x0C, 0xDC, 0xAB, 0xA5, 0x40, 0x24, 0x00, 0x7F, 0x74, + 0x94, 0xA1, 0x9D, 0x08, 0x29, 0xB3, 0x88, 0x0B, 0xF5, 0x87, 0x77, 0x9D, + 0x55, 0xCD, 0xE4, 0xC3, 0x7E, 0xD7, 0x6A, 0x64, 0xAB, 0x85, 0x14, 0x86, + 0x95, 0x5B, 0x97, 0x32, 0x50, 0x6F, 0x3D, 0xC8, 0xBA, 0x66, 0x0C, 0xE3, + 0xFC, 0xBD, 0xB8, 0x49, 0xC1, 0x76, 0x89, 0x49, 0x19, 0xFD, 0xC0, 0xA8, + 0xBD, 0x89, 0xA3, 0x67, 0x2F, 0xC6, 0x9F, 0xBC, 0x71, 0x19, 0x60, 0xB8, + 0x2D, 0xE9, 0x2C, 0xC9, 0x90, 0x76, 0x66, 0x7B, 0x94, 0xE2, 0xAF, 0x78, + 0xD6, 0x65, 0x53, 0x5D, 0x3C, 0xD6, 0x9C, 0xB2, 0xCF, 0x29, 0x03, 0xF9, + 0x2F, 0xA4, 0x50, 0xB2, 0xD4, 0x48, 0xCE, 0x05, 0x32, 0x55, 0x8A, 0xFD, + 0xB2, 0x64, 0x4C, 0x0E, 0xE4, 0x98, 0x07, 0x75, 0xDB, 0x7F, 0xDF, 0xB9, + 0x08, 0x55, 0x60, 0x85, 0x30, 0x29, 0xF9, 0x7B, 0x48, 0xA4, 0x69, 0x86, + 0xE3, 0x35, 0x3F, 0x1E, 0x86, 0x5D, 0x7A, 0x7A, 0x15, 0xBD, 0xEF, 0x00, + 0x8E, 0x15, 0x22, 0x54, 0x17, 0x00, 0x90, 0x26, 0x93, 0xBC, 0x0E, 0x49, + 0x68, 0x91, 0xBF, 0xF8, 0x47, 0xD3, 0x9D, 0x95, 0x42, 0xC1, 0x0E, 0x4D, + 0xDF, 0x6F, 0x26, 0xCF, 0xC3, 0x18, 0x21, 0x62, 0x66, 0x43, 0x70, 0xD6, + 0xD5, 0xC0, 0x07, 0xE1 +}; + +static const unsigned char TA299_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA300_DN[] = { + 0x30, 0x81, 0xB0, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x30, 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x20, 0x69, + 0x73, 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6E, 0x63, 0x65, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x16, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, + 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA300_RSA_N[] = { + 0xB6, 0x95, 0xB6, 0x43, 0x42, 0xFA, 0xC6, 0x6D, 0x2A, 0x6F, 0x48, 0xDF, + 0x94, 0x4C, 0x39, 0x57, 0x05, 0xEE, 0xC3, 0x79, 0x11, 0x41, 0x68, 0x36, + 0xED, 0xEC, 0xFE, 0x9A, 0x01, 0x8F, 0xA1, 0x38, 0x28, 0xFC, 0xF7, 0x10, + 0x46, 0x66, 0x2E, 0x4D, 0x1E, 0x1A, 0xB1, 0x1A, 0x4E, 0xC6, 0xD1, 0xC0, + 0x95, 0x88, 0xB0, 0xC9, 0xFF, 0x31, 0x8B, 0x33, 0x03, 0xDB, 0xB7, 0x83, + 0x7B, 0x3E, 0x20, 0x84, 0x5E, 0xED, 0xB2, 0x56, 0x28, 0xA7, 0xF8, 0xE0, + 0xB9, 0x40, 0x71, 0x37, 0xC5, 0xCB, 0x47, 0x0E, 0x97, 0x2A, 0x68, 0xC0, + 0x22, 0x95, 0x62, 0x15, 0xDB, 0x47, 0xD9, 0xF5, 0xD0, 0x2B, 0xFF, 0x82, + 0x4B, 0xC9, 0xAD, 0x3E, 0xDE, 0x4C, 0xDB, 0x90, 0x80, 0x50, 0x3F, 0x09, + 0x8A, 0x84, 0x00, 0xEC, 0x30, 0x0A, 0x3D, 0x18, 0xCD, 0xFB, 0xFD, 0x2A, + 0x59, 0x9A, 0x23, 0x95, 0x17, 0x2C, 0x45, 0x9E, 0x1F, 0x6E, 0x43, 0x79, + 0x6D, 0x0C, 0x5C, 0x98, 0xFE, 0x48, 0xA7, 0xC5, 0x23, 0x47, 0x5C, 0x5E, + 0xFD, 0x6E, 0xE7, 0x1E, 0xB4, 0xF6, 0x68, 0x45, 0xD1, 0x86, 0x83, 0x5B, + 0xA2, 0x8A, 0x8D, 0xB1, 0xE3, 0x29, 0x80, 0xFE, 0x25, 0x71, 0x88, 0xAD, + 0xBE, 0xBC, 0x8F, 0xAC, 0x52, 0x96, 0x4B, 0xAA, 0x51, 0x8D, 0xE4, 0x13, + 0x31, 0x19, 0xE8, 0x4E, 0x4D, 0x9F, 0xDB, 0xAC, 0xB3, 0x6A, 0xD5, 0xBC, + 0x39, 0x54, 0x71, 0xCA, 0x7A, 0x7A, 0x7F, 0x90, 0xDD, 0x7D, 0x1D, 0x80, + 0xD9, 0x81, 0xBB, 0x59, 0x26, 0xC2, 0x11, 0xFE, 0xE6, 0x93, 0xE2, 0xF7, + 0x80, 0xE4, 0x65, 0xFB, 0x34, 0x37, 0x0E, 0x29, 0x80, 0x70, 0x4D, 0xAF, + 0x38, 0x86, 0x2E, 0x9E, 0x7F, 0x57, 0xAF, 0x9E, 0x17, 0xAE, 0xEB, 0x1C, + 0xCB, 0x28, 0x21, 0x5F, 0xB6, 0x1C, 0xD8, 0xE7, 0xA2, 0x04, 0x22, 0xF9, + 0xD3, 0xDA, 0xD8, 0xCB +}; + +static const unsigned char TA300_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA301_DN[] = { + 0x30, 0x81, 0xBF, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x33, 0x30, + 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x45, + 0x43, 0x31 +}; + +static const unsigned char TA301_EC_Q[] = { + 0x04, 0x84, 0x13, 0xC9, 0xD0, 0xBA, 0x6D, 0x41, 0x7B, 0xE2, 0x6C, 0xD0, + 0xEB, 0x55, 0x5F, 0x66, 0x02, 0x1A, 0x24, 0xF4, 0x5B, 0x89, 0x69, 0x47, + 0xE3, 0xB8, 0xC2, 0x7D, 0xF1, 0xF2, 0x02, 0xC5, 0x9F, 0xA0, 0xF6, 0x5B, + 0xD5, 0x8B, 0x06, 0x19, 0x86, 0x4F, 0x53, 0x10, 0x6D, 0x07, 0x24, 0x27, + 0xA1, 0xA0, 0xF8, 0xD5, 0x47, 0x19, 0x61, 0x4C, 0x7D, 0xCA, 0x93, 0x27, + 0xEA, 0x74, 0x0C, 0xEF, 0x6F, 0x96, 0x09, 0xFE, 0x63, 0xEC, 0x70, 0x5D, + 0x36, 0xAD, 0x67, 0x77, 0xAE, 0xC9, 0x9D, 0x7C, 0x55, 0x44, 0x3A, 0xA2, + 0x63, 0x51, 0x1F, 0xF5, 0xE3, 0x62, 0xD4, 0xA9, 0x47, 0x07, 0x3E, 0xCC, + 0x20 +}; + +static const unsigned char TA302_DN[] = { + 0x30, 0x81, 0xBE, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x32, 0x30, + 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, + 0x32 +}; + +static const unsigned char TA302_RSA_N[] = { + 0xBA, 0x84, 0xB6, 0x72, 0xDB, 0x9E, 0x0C, 0x6B, 0xE2, 0x99, 0xE9, 0x30, + 0x01, 0xA7, 0x76, 0xEA, 0x32, 0xB8, 0x95, 0x41, 0x1A, 0xC9, 0xDA, 0x61, + 0x4E, 0x58, 0x72, 0xCF, 0xFE, 0xF6, 0x82, 0x79, 0xBF, 0x73, 0x61, 0x06, + 0x0A, 0xA5, 0x27, 0xD8, 0xB3, 0x5F, 0xD3, 0x45, 0x4E, 0x1C, 0x72, 0xD6, + 0x4E, 0x32, 0xF2, 0x72, 0x8A, 0x0F, 0xF7, 0x83, 0x19, 0xD0, 0x6A, 0x80, + 0x80, 0x00, 0x45, 0x1E, 0xB0, 0xC7, 0xE7, 0x9A, 0xBF, 0x12, 0x57, 0x27, + 0x1C, 0xA3, 0x68, 0x2F, 0x0A, 0x87, 0xBD, 0x6A, 0x6B, 0x0E, 0x5E, 0x65, + 0xF3, 0x1C, 0x77, 0xD5, 0xD4, 0x85, 0x8D, 0x70, 0x21, 0xB4, 0xB3, 0x32, + 0xE7, 0x8B, 0xA2, 0xD5, 0x86, 0x39, 0x02, 0xB1, 0xB8, 0xD2, 0x47, 0xCE, + 0xE4, 0xC9, 0x49, 0xC4, 0x3B, 0xA7, 0xDE, 0xFB, 0x54, 0x7D, 0x57, 0xBE, + 0xF0, 0xE8, 0x6E, 0xC2, 0x79, 0xB2, 0x3A, 0x0B, 0x55, 0xE2, 0x50, 0x98, + 0x16, 0x32, 0x13, 0x5C, 0x2F, 0x78, 0x56, 0xC1, 0xC2, 0x94, 0xB3, 0xF2, + 0x5A, 0xE4, 0x27, 0x9A, 0x9F, 0x24, 0xD7, 0xC6, 0xEC, 0xD0, 0x9B, 0x25, + 0x82, 0xE3, 0xCC, 0xC2, 0xC4, 0x45, 0xC5, 0x8C, 0x97, 0x7A, 0x06, 0x6B, + 0x2A, 0x11, 0x9F, 0xA9, 0x0A, 0x6E, 0x48, 0x3B, 0x6F, 0xDB, 0xD4, 0x11, + 0x19, 0x42, 0xF7, 0x8F, 0x07, 0xBF, 0xF5, 0x53, 0x5F, 0x9C, 0x3E, 0xF4, + 0x17, 0x2C, 0xE6, 0x69, 0xAC, 0x4E, 0x32, 0x4C, 0x62, 0x77, 0xEA, 0xB7, + 0xE8, 0xE5, 0xBB, 0x34, 0xBC, 0x19, 0x8B, 0xAE, 0x9C, 0x51, 0xE7, 0xB7, + 0x7E, 0xB5, 0x53, 0xB1, 0x33, 0x22, 0xE5, 0x6D, 0xCF, 0x70, 0x3C, 0x1A, + 0xFA, 0xE2, 0x9B, 0x67, 0xB6, 0x83, 0xF4, 0x8D, 0xA5, 0xAF, 0x62, 0x4C, + 0x4D, 0xE0, 0x58, 0xAC, 0x64, 0x34, 0x12, 0x03, 0xF8, 0xB6, 0x8D, 0x94, + 0x63, 0x24, 0xA4, 0x71 +}; + +static const unsigned char TA302_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA303_DN[] = { + 0x30, 0x6E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x13, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, 0x6F, 0x66, 0x65, + 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x53, 0x41, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0F, 0x56, 0x41, 0x54, 0x45, + 0x53, 0x2D, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x46, 0x49, + 0x52, 0x4D, 0x41, 0x50, 0x52, 0x4F, 0x46, 0x45, 0x53, 0x49, 0x4F, 0x4E, + 0x41, 0x4C, 0x20, 0x43, 0x41, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x2D, 0x41, + 0x20, 0x57, 0x45, 0x42 +}; + +static const unsigned char TA303_EC_Q[] = { + 0x04, 0x47, 0x53, 0xEA, 0x2C, 0x11, 0xA4, 0x77, 0xC7, 0x2A, 0xEA, 0xF3, + 0xD6, 0x5F, 0x7B, 0xD3, 0x04, 0x91, 0x5C, 0xFA, 0x88, 0xC6, 0x22, 0xB9, + 0x83, 0x10, 0x62, 0x77, 0x84, 0x33, 0x2D, 0xE9, 0x03, 0x88, 0xD4, 0xE0, + 0x33, 0xF7, 0xED, 0x77, 0x2C, 0x4A, 0x60, 0xEA, 0xE4, 0x6F, 0xAD, 0x6D, + 0xB4, 0xF8, 0x4C, 0x8A, 0xA4, 0xE4, 0x1F, 0xCA, 0xEA, 0x4F, 0x38, 0x4A, + 0x2E, 0x82, 0x73, 0x2B, 0xC7, 0x66, 0x9B, 0x0A, 0x8C, 0x40, 0x9C, 0x7C, + 0x8A, 0xF6, 0xF2, 0x39, 0x60, 0xB2, 0xDE, 0xCB, 0xEC, 0xB8, 0xE4, 0x6F, + 0xEA, 0x9B, 0x5D, 0xB7, 0x53, 0x90, 0x18, 0x32, 0x55, 0xC5, 0x20, 0xB7, + 0x94 +}; + +static const unsigned char TA304_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x29, 0x47, 0x55, 0x41, 0x4E, 0x47, 0x20, 0x44, 0x4F, 0x4E, 0x47, + 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, + 0x20, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x20, 0x43, + 0x4F, 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x47, 0x44, 0x43, 0x41, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x41, 0x55, 0x54, 0x48, 0x20, 0x52, 0x35, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA304_RSA_N[] = { + 0xD9, 0xA3, 0x16, 0xF0, 0xC8, 0x74, 0x74, 0x77, 0x9B, 0xEF, 0x33, 0x0D, + 0x3B, 0x06, 0x7E, 0x55, 0xFC, 0xB5, 0x60, 0x8F, 0x76, 0x86, 0x12, 0x42, + 0x7D, 0x56, 0x66, 0x3E, 0x88, 0x82, 0xED, 0x72, 0x63, 0x0E, 0x9E, 0x8B, + 0xDD, 0x34, 0x2C, 0x02, 0x51, 0x51, 0xC3, 0x19, 0xFD, 0x59, 0x54, 0x84, + 0xC9, 0xF1, 0x6B, 0xB3, 0x4C, 0xB0, 0xE9, 0xE8, 0x46, 0x5D, 0x38, 0xC6, + 0xA2, 0xA7, 0x2E, 0x11, 0x57, 0xBA, 0x82, 0x15, 0xA2, 0x9C, 0x8F, 0x6D, + 0xB0, 0x99, 0x4A, 0x0A, 0xF2, 0xEB, 0x89, 0x70, 0x63, 0x4E, 0x79, 0xC4, + 0xB7, 0x5B, 0xBD, 0xA2, 0x5D, 0xB1, 0xF2, 0x41, 0x02, 0x2B, 0xAD, 0xA9, + 0x3A, 0xA3, 0xEC, 0x79, 0x0A, 0xEC, 0x5F, 0x3A, 0xE3, 0xFD, 0xEF, 0x80, + 0x3C, 0xAD, 0x34, 0x9B, 0x1A, 0xAB, 0x88, 0x26, 0x7B, 0x56, 0xA2, 0x82, + 0x86, 0x1F, 0xEB, 0x35, 0x89, 0x83, 0x7F, 0x5F, 0xAE, 0x29, 0x4E, 0x3D, + 0xB6, 0x6E, 0xEC, 0xAE, 0xC1, 0xF0, 0x27, 0x9B, 0xAE, 0xE3, 0xF4, 0xEC, + 0xEF, 0xAE, 0x7F, 0xF7, 0x86, 0x3D, 0x72, 0x7A, 0xEB, 0xA5, 0xFB, 0x59, + 0x4E, 0xA7, 0xEB, 0x95, 0x8C, 0x22, 0x39, 0x79, 0xE1, 0x2D, 0x08, 0x8F, + 0xCC, 0xBC, 0x91, 0xB8, 0x41, 0xF7, 0x14, 0xC1, 0x23, 0xA9, 0xC3, 0xAD, + 0x9A, 0x45, 0x44, 0xB3, 0xB2, 0xD7, 0x2C, 0xCD, 0xC6, 0x29, 0xE2, 0x50, + 0x10, 0xAE, 0x5C, 0xCB, 0x82, 0x8E, 0x17, 0x18, 0x36, 0x7D, 0x97, 0xE6, + 0x88, 0x9A, 0xB0, 0x4D, 0x34, 0x09, 0xF4, 0x2C, 0xB9, 0x5A, 0x66, 0x2A, + 0xB0, 0x17, 0x9B, 0x9E, 0x1E, 0x76, 0x9D, 0x4A, 0x66, 0x31, 0x41, 0xDF, + 0x3F, 0xFB, 0xC5, 0x06, 0xEF, 0x1B, 0xB6, 0x7E, 0x1A, 0x46, 0x36, 0xF7, + 0x64, 0x63, 0x3B, 0xE3, 0x39, 0x18, 0x23, 0xE7, 0x67, 0x75, 0x14, 0xD5, + 0x75, 0x57, 0x92, 0x37, 0xBD, 0xBE, 0x6A, 0x1B, 0x26, 0x50, 0xF2, 0x36, + 0x26, 0x06, 0x90, 0xC5, 0x70, 0x01, 0x64, 0x6D, 0x76, 0x66, 0xE1, 0x91, + 0xDB, 0x6E, 0x07, 0xC0, 0x61, 0x80, 0x2E, 0xB2, 0x2E, 0x2F, 0x8C, 0x70, + 0xA7, 0xD1, 0x3B, 0x3C, 0xB3, 0x91, 0xE4, 0x6E, 0xB6, 0xC4, 0x3B, 0x70, + 0xF2, 0x6C, 0x92, 0x97, 0x09, 0xCD, 0x47, 0x7D, 0x18, 0xC0, 0xF3, 0xBB, + 0x9E, 0x0F, 0xD6, 0x8B, 0xAE, 0x07, 0xB6, 0x5A, 0x0F, 0xCE, 0x0B, 0x0C, + 0x47, 0xA7, 0xE5, 0x3E, 0xB8, 0xBD, 0x7D, 0xC7, 0x9B, 0x35, 0xA0, 0x61, + 0x97, 0x3A, 0x41, 0x75, 0x17, 0xCC, 0x2B, 0x96, 0x77, 0x2A, 0x92, 0x21, + 0x1E, 0xD9, 0x95, 0x76, 0x20, 0x67, 0x68, 0xCF, 0x0D, 0xBD, 0xDF, 0xD6, + 0x1F, 0x09, 0x6A, 0x9A, 0xE2, 0xCC, 0x73, 0x71, 0xA4, 0x2F, 0x7D, 0x12, + 0x80, 0xB7, 0x53, 0x30, 0x46, 0x5E, 0x4B, 0x54, 0x99, 0x0F, 0x67, 0xC9, + 0xA5, 0xC8, 0xF2, 0x20, 0xC1, 0x82, 0xEC, 0x9D, 0x11, 0xDF, 0xC2, 0x02, + 0xFB, 0x1A, 0x3B, 0xD1, 0xED, 0x20, 0x9A, 0xEF, 0x65, 0x64, 0x92, 0x10, + 0x0D, 0x2A, 0xE2, 0xDE, 0x70, 0xF1, 0x18, 0x67, 0x82, 0x8C, 0x61, 0xDE, + 0xB8, 0xBC, 0xD1, 0x2F, 0x9C, 0xFB, 0x0F, 0xD0, 0x2B, 0xED, 0x1B, 0x76, + 0xB9, 0xE4, 0x39, 0x55, 0xF8, 0xF8, 0xA1, 0x1D, 0xB8, 0xAA, 0x80, 0x00, + 0x4C, 0x82, 0xE7, 0xB2, 0x7F, 0x09, 0xB8, 0xBC, 0x30, 0xA0, 0x2F, 0x0D, + 0xF5, 0x52, 0x9E, 0x8E, 0xF7, 0x92, 0xB3, 0x0A, 0x00, 0x1D, 0x00, 0x54, + 0x97, 0x06, 0xE0, 0xB1, 0x07, 0xD9, 0xC7, 0x0F, 0x5C, 0x65, 0x7D, 0x3C, + 0x6D, 0x59, 0x57, 0xE4, 0xED, 0xA5, 0x8D, 0xE9, 0x40, 0x53, 0x9F, 0x15, + 0x4B, 0xA0, 0x71, 0xF6, 0x1A, 0x21, 0xE3, 0xDA, 0x70, 0x06, 0x21, 0x58, + 0x14, 0x87, 0x85, 0x77, 0x79, 0xAA, 0x82, 0x79 +}; + +static const unsigned char TA304_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA305_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x41, 0x54, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x65, 0x2D, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x65, + 0x20, 0x6D, 0x6F, 0x6E, 0x69, 0x74, 0x6F, 0x72, 0x69, 0x6E, 0x67, 0x20, + 0x47, 0x6D, 0x62, 0x48, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x10, 0x47, 0x4C, 0x4F, 0x42, 0x41, 0x4C, 0x54, 0x52, 0x55, + 0x53, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA305_RSA_N[] = { + 0xAE, 0x2E, 0x56, 0xAD, 0x1B, 0x1C, 0xEF, 0xF6, 0x95, 0x8F, 0xA0, 0x77, + 0x1B, 0x2B, 0xD3, 0x63, 0x8F, 0x84, 0x4D, 0x45, 0xA2, 0x0F, 0x9F, 0x5B, + 0x45, 0xAB, 0x59, 0x7B, 0x51, 0x34, 0xF9, 0xEC, 0x8B, 0x8A, 0x78, 0xC5, + 0xDD, 0x6B, 0xAF, 0xBD, 0xC4, 0xDF, 0x93, 0x45, 0x1E, 0xBF, 0x91, 0x38, + 0x0B, 0xAE, 0x0E, 0x16, 0xE7, 0x41, 0x73, 0xF8, 0xDB, 0xBB, 0xD1, 0xB8, + 0x51, 0xE0, 0xCB, 0x83, 0x3B, 0x73, 0x38, 0x6E, 0x77, 0x8A, 0x0F, 0x59, + 0x63, 0x26, 0xCD, 0xA7, 0x2A, 0xCE, 0x54, 0xFB, 0xB8, 0xE2, 0xC0, 0x7C, + 0x47, 0xCE, 0x60, 0x7C, 0x3F, 0xB2, 0x73, 0xF2, 0xC0, 0x19, 0xB6, 0x8A, + 0x92, 0x87, 0x35, 0x0D, 0x90, 0x28, 0xA2, 0xE4, 0x15, 0x04, 0x63, 0x3E, + 0xBA, 0xAF, 0xEE, 0x7C, 0x5E, 0xCC, 0xA6, 0x8B, 0x50, 0xB2, 0x38, 0xF7, + 0x41, 0x63, 0xCA, 0xCE, 0xFF, 0x69, 0x8F, 0x68, 0x0E, 0x95, 0x36, 0xE5, + 0xCC, 0xB9, 0x8C, 0x09, 0xCA, 0x4B, 0xDD, 0x31, 0x90, 0x96, 0xC8, 0xCC, + 0x1F, 0xFD, 0x56, 0x96, 0x34, 0xDB, 0x8E, 0x1C, 0xEA, 0x2C, 0xBE, 0x85, + 0x2E, 0x63, 0xDD, 0xAA, 0xA9, 0x95, 0xD3, 0xFD, 0x29, 0x95, 0x13, 0xF0, + 0xC8, 0x98, 0x93, 0xD9, 0x2D, 0x16, 0x47, 0x90, 0x11, 0x83, 0xA2, 0x3A, + 0x22, 0xA2, 0x28, 0x57, 0xA2, 0xEB, 0xFE, 0xC0, 0x8C, 0x28, 0xA0, 0xA6, + 0x7D, 0xE7, 0x2A, 0x42, 0x3B, 0x82, 0x80, 0x63, 0xA5, 0x63, 0x1F, 0x19, + 0xCC, 0x7C, 0xB2, 0x66, 0xA8, 0xC2, 0xD3, 0x6D, 0x37, 0x6F, 0xE2, 0x7E, + 0x06, 0x51, 0xD9, 0x45, 0x84, 0x1F, 0x12, 0xCE, 0x24, 0x52, 0x64, 0x85, + 0x0B, 0x48, 0x80, 0x4E, 0x87, 0xB1, 0x22, 0x22, 0x30, 0xAA, 0xEB, 0xAE, + 0xBE, 0xE0, 0x02, 0xE0, 0x40, 0xE8, 0xB0, 0x42, 0x80, 0x03, 0x51, 0xAA, + 0xB4, 0x7E, 0xAA, 0x44, 0xD7, 0x43, 0x61, 0xF3, 0xA2, 0x6B, 0x16, 0x89, + 0x49, 0xA4, 0xA3, 0xA4, 0x2B, 0x8A, 0x02, 0xC4, 0x78, 0xF4, 0x68, 0x8A, + 0xC1, 0xE4, 0x7A, 0x36, 0xB1, 0x6F, 0x1B, 0x96, 0x1B, 0x77, 0x49, 0x8D, + 0xD4, 0xC9, 0x06, 0x72, 0x8F, 0xCF, 0x53, 0xE3, 0xDC, 0x17, 0x85, 0x20, + 0x4A, 0xDC, 0x98, 0x27, 0xD3, 0x91, 0x26, 0x2B, 0x47, 0x1E, 0x69, 0x07, + 0xAF, 0xDE, 0xA2, 0xE4, 0xE4, 0xD4, 0x6B, 0x0B, 0xB3, 0x5E, 0x7C, 0xD4, + 0x24, 0x80, 0x47, 0x29, 0x69, 0x3B, 0x6E, 0xE8, 0xAC, 0xFD, 0x40, 0xEB, + 0xD8, 0xED, 0x71, 0x71, 0x2B, 0xF2, 0xE8, 0x58, 0x1D, 0xEB, 0x41, 0x97, + 0x22, 0xC5, 0x1F, 0xD4, 0x39, 0xD0, 0x27, 0x8F, 0x87, 0xE3, 0x18, 0xF4, + 0xE0, 0xA9, 0x46, 0x0D, 0xF5, 0x74, 0x3A, 0x82, 0x2E, 0xD0, 0x6E, 0x2C, + 0x91, 0xA3, 0x31, 0x5C, 0x3B, 0x46, 0xEA, 0x7B, 0x04, 0x10, 0x56, 0x5E, + 0x80, 0x1D, 0xF5, 0xA5, 0x65, 0xE8, 0x82, 0xFC, 0xE2, 0x07, 0x8C, 0x62, + 0x45, 0xF5, 0x20, 0xDE, 0x46, 0x70, 0x86, 0xA1, 0xBC, 0x93, 0xD3, 0x1E, + 0x74, 0xA6, 0x6C, 0xB0, 0x2C, 0xF7, 0x03, 0x0C, 0x88, 0x0C, 0xCB, 0xD4, + 0x72, 0x53, 0x86, 0xBC, 0x60, 0x46, 0xF3, 0x98, 0x6A, 0xC2, 0xF1, 0xBF, + 0x43, 0xF9, 0x70, 0x20, 0x77, 0xCA, 0x37, 0x41, 0x79, 0x55, 0x52, 0x63, + 0x8D, 0x5B, 0x12, 0x9F, 0xC5, 0x68, 0xC4, 0x88, 0x9D, 0xAC, 0xF2, 0x30, + 0xAB, 0xB7, 0xA3, 0x31, 0x97, 0x67, 0xAD, 0x8F, 0x17, 0x0F, 0x6C, 0xC7, + 0x73, 0xED, 0x24, 0x94, 0x6B, 0xC8, 0x83, 0x9A, 0xD0, 0x9A, 0x37, 0x49, + 0x04, 0xAB, 0xB1, 0x16, 0xC8, 0x6C, 0x49, 0x49, 0x2D, 0xAB, 0xA1, 0xD0, + 0x8C, 0x92, 0xF2, 0x41, 0x4A, 0x79, 0x21, 0x25, 0xDB, 0x63, 0xD7, 0xB6, + 0x9C, 0xA7, 0x7E, 0x42, 0x69, 0xFB, 0x3A, 0x63 +}; + +static const unsigned char TA305_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA306_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x31 +}; + +static const unsigned char TA306_RSA_N[] = { + 0xB6, 0x11, 0x02, 0x8B, 0x1E, 0xE3, 0xA1, 0x77, 0x9B, 0x3B, 0xDC, 0xBF, + 0x94, 0x3E, 0xB7, 0x95, 0xA7, 0x40, 0x3C, 0xA1, 0xFD, 0x82, 0xF9, 0x7D, + 0x32, 0x06, 0x82, 0x71, 0xF6, 0xF6, 0x8C, 0x7F, 0xFB, 0xE8, 0xDB, 0xBC, + 0x6A, 0x2E, 0x97, 0x97, 0xA3, 0x8C, 0x4B, 0xF9, 0x2B, 0xF6, 0xB1, 0xF9, + 0xCE, 0x84, 0x1D, 0xB1, 0xF9, 0xC5, 0x97, 0xDE, 0xEF, 0xB9, 0xF2, 0xA3, + 0xE9, 0xBC, 0x12, 0x89, 0x5E, 0xA7, 0xAA, 0x52, 0xAB, 0xF8, 0x23, 0x27, + 0xCB, 0xA4, 0xB1, 0x9C, 0x63, 0xDB, 0xD7, 0x99, 0x7E, 0xF0, 0x0A, 0x5E, + 0xEB, 0x68, 0xA6, 0xF4, 0xC6, 0x5A, 0x47, 0x0D, 0x4D, 0x10, 0x33, 0xE3, + 0x4E, 0xB1, 0x13, 0xA3, 0xC8, 0x18, 0x6C, 0x4B, 0xEC, 0xFC, 0x09, 0x90, + 0xDF, 0x9D, 0x64, 0x29, 0x25, 0x23, 0x07, 0xA1, 0xB4, 0xD2, 0x3D, 0x2E, + 0x60, 0xE0, 0xCF, 0xD2, 0x09, 0x87, 0xBB, 0xCD, 0x48, 0xF0, 0x4D, 0xC2, + 0xC2, 0x7A, 0x88, 0x8A, 0xBB, 0xBA, 0xCF, 0x59, 0x19, 0xD6, 0xAF, 0x8F, + 0xB0, 0x07, 0xB0, 0x9E, 0x31, 0xF1, 0x82, 0xC1, 0xC0, 0xDF, 0x2E, 0xA6, + 0x6D, 0x6C, 0x19, 0x0E, 0xB5, 0xD8, 0x7E, 0x26, 0x1A, 0x45, 0x03, 0x3D, + 0xB0, 0x79, 0xA4, 0x94, 0x28, 0xAD, 0x0F, 0x7F, 0x26, 0xE5, 0xA8, 0x08, + 0xFE, 0x96, 0xE8, 0x3C, 0x68, 0x94, 0x53, 0xEE, 0x83, 0x3A, 0x88, 0x2B, + 0x15, 0x96, 0x09, 0xB2, 0xE0, 0x7A, 0x8C, 0x2E, 0x75, 0xD6, 0x9C, 0xEB, + 0xA7, 0x56, 0x64, 0x8F, 0x96, 0x4F, 0x68, 0xAE, 0x3D, 0x97, 0xC2, 0x84, + 0x8F, 0xC0, 0xBC, 0x40, 0xC0, 0x0B, 0x5C, 0xBD, 0xF6, 0x87, 0xB3, 0x35, + 0x6C, 0xAC, 0x18, 0x50, 0x7F, 0x84, 0xE0, 0x4C, 0xCD, 0x92, 0xD3, 0x20, + 0xE9, 0x33, 0xBC, 0x52, 0x99, 0xAF, 0x32, 0xB5, 0x29, 0xB3, 0x25, 0x2A, + 0xB4, 0x48, 0xF9, 0x72, 0xE1, 0xCA, 0x64, 0xF7, 0xE6, 0x82, 0x10, 0x8D, + 0xE8, 0x9D, 0xC2, 0x8A, 0x88, 0xFA, 0x38, 0x66, 0x8A, 0xFC, 0x63, 0xF9, + 0x01, 0xF9, 0x78, 0xFD, 0x7B, 0x5C, 0x77, 0xFA, 0x76, 0x87, 0xFA, 0xEC, + 0xDF, 0xB1, 0x0E, 0x79, 0x95, 0x57, 0xB4, 0xBD, 0x26, 0xEF, 0xD6, 0x01, + 0xD1, 0xEB, 0x16, 0x0A, 0xBB, 0x8E, 0x0B, 0xB5, 0xC5, 0xC5, 0x8A, 0x55, + 0xAB, 0xD3, 0xAC, 0xEA, 0x91, 0x4B, 0x29, 0xCC, 0x19, 0xA4, 0x32, 0x25, + 0x4E, 0x2A, 0xF1, 0x65, 0x44, 0xD0, 0x02, 0xCE, 0xAA, 0xCE, 0x49, 0xB4, + 0xEA, 0x9F, 0x7C, 0x83, 0xB0, 0x40, 0x7B, 0xE7, 0x43, 0xAB, 0xA7, 0x6C, + 0xA3, 0x8F, 0x7D, 0x89, 0x81, 0xFA, 0x4C, 0xA5, 0xFF, 0xD5, 0x8E, 0xC3, + 0xCE, 0x4B, 0xE0, 0xB5, 0xD8, 0xB3, 0x8E, 0x45, 0xCF, 0x76, 0xC0, 0xED, + 0x40, 0x2B, 0xFD, 0x53, 0x0F, 0xB0, 0xA7, 0xD5, 0x3B, 0x0D, 0xB1, 0x8A, + 0xA2, 0x03, 0xDE, 0x31, 0xAD, 0xCC, 0x77, 0xEA, 0x6F, 0x7B, 0x3E, 0xD6, + 0xDF, 0x91, 0x22, 0x12, 0xE6, 0xBE, 0xFA, 0xD8, 0x32, 0xFC, 0x10, 0x63, + 0x14, 0x51, 0x72, 0xDE, 0x5D, 0xD6, 0x16, 0x93, 0xBD, 0x29, 0x68, 0x33, + 0xEF, 0x3A, 0x66, 0xEC, 0x07, 0x8A, 0x26, 0xDF, 0x13, 0xD7, 0x57, 0x65, + 0x78, 0x27, 0xDE, 0x5E, 0x49, 0x14, 0x00, 0xA2, 0x00, 0x7F, 0x9A, 0xA8, + 0x21, 0xB6, 0xA9, 0xB1, 0x95, 0xB0, 0xA5, 0xB9, 0x0D, 0x16, 0x11, 0xDA, + 0xC7, 0x6C, 0x48, 0x3C, 0x40, 0xE0, 0x7E, 0x0D, 0x5A, 0xCD, 0x56, 0x3C, + 0xD1, 0x97, 0x05, 0xB9, 0xCB, 0x4B, 0xED, 0x39, 0x4B, 0x9C, 0xC4, 0x3F, + 0xD2, 0x55, 0x13, 0x6E, 0x24, 0xB0, 0xD6, 0x71, 0xFA, 0xF4, 0xC1, 0xBA, + 0xCC, 0xED, 0x1B, 0xF5, 0xFE, 0x81, 0x41, 0xD8, 0x00, 0x98, 0x3D, 0x3A, + 0xC8, 0xAE, 0x7A, 0x98, 0x37, 0x18, 0x05, 0x95 +}; + +static const unsigned char TA306_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA307_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA307_RSA_N[] = { + 0xCE, 0xDE, 0xFD, 0xA6, 0xFB, 0xEC, 0xEC, 0x14, 0x34, 0x3C, 0x07, 0x06, + 0x5A, 0x6C, 0x59, 0xF7, 0x19, 0x35, 0xDD, 0xF7, 0xC1, 0x9D, 0x55, 0xAA, + 0xD3, 0xCD, 0x3B, 0xA4, 0x93, 0x72, 0xEF, 0x0A, 0xFA, 0x6D, 0x9D, 0xF6, + 0xF0, 0x85, 0x80, 0x5B, 0xA1, 0x48, 0x52, 0x9F, 0x39, 0xC5, 0xB7, 0xEE, + 0x28, 0xAC, 0xEF, 0xCB, 0x76, 0x68, 0x14, 0xB9, 0xDF, 0xAD, 0x01, 0x6C, + 0x99, 0x1F, 0xC4, 0x22, 0x1D, 0x9F, 0xFE, 0x72, 0x77, 0xE0, 0x2C, 0x5B, + 0xAF, 0xE4, 0x04, 0xBF, 0x4F, 0x72, 0xA0, 0x1A, 0x34, 0x98, 0xE8, 0x39, + 0x68, 0xEC, 0x95, 0x25, 0x7B, 0x76, 0xA1, 0xE6, 0x69, 0xB9, 0x85, 0x19, + 0xBD, 0x89, 0x8C, 0xFE, 0xAD, 0xED, 0x36, 0xEA, 0x73, 0xBC, 0xFF, 0x83, + 0xE2, 0xCB, 0x7D, 0xC1, 0xD2, 0xCE, 0x4A, 0xB3, 0x8D, 0x05, 0x9E, 0x8B, + 0x49, 0x93, 0xDF, 0xC1, 0x5B, 0xD0, 0x6E, 0x5E, 0xF0, 0x2E, 0x30, 0x2E, + 0x82, 0xFC, 0xFA, 0xBC, 0xB4, 0x17, 0x0A, 0x48, 0xE5, 0x88, 0x9B, 0xC5, + 0x9B, 0x6B, 0xDE, 0xB0, 0xCA, 0xB4, 0x03, 0xF0, 0xDA, 0xF4, 0x90, 0xB8, + 0x65, 0x64, 0xF7, 0x5C, 0x4C, 0xAD, 0xE8, 0x7E, 0x66, 0x5E, 0x99, 0xD7, + 0xB8, 0xC2, 0x3E, 0xC8, 0xD0, 0x13, 0x9D, 0xAD, 0xEE, 0xE4, 0x45, 0x7B, + 0x89, 0x55, 0xF7, 0x8A, 0x1F, 0x62, 0x52, 0x84, 0x12, 0xB3, 0xC2, 0x40, + 0x97, 0xE3, 0x8A, 0x1F, 0x47, 0x91, 0xA6, 0x74, 0x5A, 0xD2, 0xF8, 0xB1, + 0x63, 0x28, 0x10, 0xB8, 0xB3, 0x09, 0xB8, 0x56, 0x77, 0x40, 0xA2, 0x26, + 0x98, 0x79, 0xC6, 0xFE, 0xDF, 0x25, 0xEE, 0x3E, 0xE5, 0xA0, 0x7F, 0xD4, + 0x61, 0x0F, 0x51, 0x4B, 0x3C, 0x3F, 0x8C, 0xDA, 0xE1, 0x70, 0x74, 0xD8, + 0xC2, 0x68, 0xA1, 0xF9, 0xC1, 0x0C, 0xE9, 0xA1, 0xE2, 0x7F, 0xBB, 0x55, + 0x3C, 0x76, 0x06, 0xEE, 0x6A, 0x4E, 0xCC, 0x92, 0x88, 0x30, 0x4D, 0x9A, + 0xBD, 0x4F, 0x0B, 0x48, 0x9A, 0x84, 0xB5, 0x98, 0xA3, 0xD5, 0xFB, 0x73, + 0xC1, 0x57, 0x61, 0xDD, 0x28, 0x56, 0x75, 0x13, 0xAE, 0x87, 0x8E, 0xE7, + 0x0C, 0x51, 0x09, 0x10, 0x75, 0x88, 0x4C, 0xBC, 0x8D, 0xF9, 0x7B, 0x3C, + 0xD4, 0x22, 0x48, 0x1F, 0x2A, 0xDC, 0xEB, 0x6B, 0xBB, 0x44, 0xB1, 0xCB, + 0x33, 0x71, 0x32, 0x46, 0xAF, 0xAD, 0x4A, 0xF1, 0x8C, 0xE8, 0x74, 0x3A, + 0xAC, 0xE7, 0x1A, 0x22, 0x73, 0x80, 0xD2, 0x30, 0xF7, 0x25, 0x42, 0xC7, + 0x22, 0x3B, 0x3B, 0x12, 0xAD, 0x96, 0x2E, 0xC6, 0xC3, 0x76, 0x07, 0xAA, + 0x20, 0xB7, 0x35, 0x49, 0x57, 0xE9, 0x92, 0x49, 0xE8, 0x76, 0x16, 0x72, + 0x31, 0x67, 0x2B, 0x96, 0x7E, 0x8A, 0xA3, 0xC7, 0x94, 0x56, 0x22, 0xBF, + 0x6A, 0x4B, 0x7E, 0x01, 0x21, 0xB2, 0x23, 0x32, 0xDF, 0xE4, 0x9A, 0x44, + 0x6D, 0x59, 0x5B, 0x5D, 0xF5, 0x00, 0xA0, 0x1C, 0x9B, 0xC6, 0x78, 0x97, + 0x8D, 0x90, 0xFF, 0x9B, 0xC8, 0xAA, 0xB4, 0xAF, 0x11, 0x51, 0x39, 0x5E, + 0xD9, 0xFB, 0x67, 0xAD, 0xD5, 0x5B, 0x11, 0x9D, 0x32, 0x9A, 0x1B, 0xBD, + 0xD5, 0xBA, 0x5B, 0xA5, 0xC9, 0xCB, 0x25, 0x69, 0x53, 0x55, 0x27, 0x5C, + 0xE0, 0xCA, 0x36, 0xCB, 0x88, 0x61, 0xFB, 0x1E, 0xB7, 0xD0, 0xCB, 0xEE, + 0x16, 0xFB, 0xD3, 0xA6, 0x4C, 0xDE, 0x92, 0xA5, 0xD4, 0xE2, 0xDF, 0xF5, + 0x06, 0x54, 0xDE, 0x2E, 0x9D, 0x4B, 0xB4, 0x93, 0x30, 0xAA, 0x81, 0xCE, + 0xDD, 0x1A, 0xDC, 0x51, 0x73, 0x0D, 0x4F, 0x70, 0xE9, 0xE5, 0xB6, 0x16, + 0x21, 0x19, 0x79, 0xB2, 0xE6, 0x89, 0x0B, 0x75, 0x64, 0xCA, 0xD5, 0xAB, + 0xBC, 0x09, 0xC1, 0x18, 0xA1, 0xFF, 0xD4, 0x54, 0xA1, 0x85, 0x3C, 0xFD, + 0x14, 0x24, 0x03, 0xB2, 0x87, 0xD3, 0xA4, 0xB7 +}; + +static const unsigned char TA307_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA308_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x33 +}; + +static const unsigned char TA308_EC_Q[] = { + 0x04, 0x1F, 0x4F, 0x33, 0x87, 0x33, 0x29, 0x8A, 0xA1, 0x84, 0xDE, 0xCB, + 0xC7, 0x21, 0x58, 0x41, 0x89, 0xEA, 0x56, 0x9D, 0x2B, 0x4B, 0x85, 0xC6, + 0x1D, 0x4C, 0x27, 0xBC, 0x7F, 0x26, 0x51, 0x72, 0x6F, 0xE2, 0x9F, 0xD6, + 0xA3, 0xCA, 0xCC, 0x45, 0x14, 0x46, 0x8B, 0xAD, 0xEF, 0x7E, 0x86, 0x8C, + 0xEC, 0xB1, 0x7E, 0x2F, 0xFF, 0xA9, 0x71, 0x9D, 0x18, 0x84, 0x45, 0x04, + 0x41, 0x55, 0x6E, 0x2B, 0xEA, 0x26, 0x7F, 0xBB, 0x90, 0x01, 0xE3, 0x4B, + 0x19, 0xBA, 0xE4, 0x54, 0x96, 0x45, 0x09, 0xB1, 0xD5, 0x6C, 0x91, 0x44, + 0xAD, 0x84, 0x13, 0x8E, 0x9A, 0x8C, 0x0D, 0x80, 0x0C, 0x32, 0xF6, 0xE0, + 0x27 +}; + +static const unsigned char TA309_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x34 +}; + +static const unsigned char TA309_EC_Q[] = { + 0x04, 0xF3, 0x74, 0x73, 0xA7, 0x68, 0x8B, 0x60, 0xAE, 0x43, 0xB8, 0x35, + 0xC5, 0x81, 0x30, 0x7B, 0x4B, 0x49, 0x9D, 0xFB, 0xC1, 0x61, 0xCE, 0xE6, + 0xDE, 0x46, 0xBD, 0x6B, 0xD5, 0x61, 0x18, 0x35, 0xAE, 0x40, 0xDD, 0x73, + 0xF7, 0x89, 0x91, 0x30, 0x5A, 0xEB, 0x3C, 0xEE, 0x85, 0x7C, 0xA2, 0x40, + 0x76, 0x3B, 0xA9, 0xC6, 0xB8, 0x47, 0xD8, 0x2A, 0xE7, 0x92, 0x91, 0x6A, + 0x73, 0xE9, 0xB1, 0x72, 0x39, 0x9F, 0x29, 0x9F, 0xA2, 0x98, 0xD3, 0x5F, + 0x5E, 0x58, 0x86, 0x65, 0x0F, 0xA1, 0x84, 0x65, 0x06, 0xD1, 0xDC, 0x8B, + 0xC9, 0xC7, 0x73, 0xC8, 0x8C, 0x6A, 0x2F, 0xE5, 0xC4, 0xAB, 0xD1, 0x1D, + 0x8A +}; + +static const unsigned char TA310_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x34, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA310_EC_Q[] = { + 0x04, 0xB8, 0xC6, 0x79, 0xD3, 0x8F, 0x6C, 0x25, 0x0E, 0x9F, 0x2E, 0x39, + 0x19, 0x1C, 0x03, 0xA4, 0xAE, 0x9A, 0xE5, 0x39, 0x07, 0x09, 0x16, 0xCA, + 0x63, 0xB1, 0xB9, 0x86, 0xF8, 0x8A, 0x57, 0xC1, 0x57, 0xCE, 0x42, 0xFA, + 0x73, 0xA1, 0xF7, 0x65, 0x42, 0xFF, 0x1E, 0xC1, 0x00, 0xB2, 0x6E, 0x73, + 0x0E, 0xFF, 0xC7, 0x21, 0xE5, 0x18, 0xA4, 0xAA, 0xD9, 0x71, 0x3F, 0xA8, + 0xD4, 0xB9, 0xCE, 0x8C, 0x1D +}; + +static const unsigned char TA311_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x35, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA311_EC_Q[] = { + 0x04, 0x47, 0x45, 0x0E, 0x96, 0xFB, 0x7D, 0x5D, 0xBF, 0xE9, 0x39, 0xD1, + 0x21, 0xF8, 0x9F, 0x0B, 0xB6, 0xD5, 0x7B, 0x1E, 0x92, 0x3A, 0x48, 0x59, + 0x1C, 0xF0, 0x62, 0x31, 0x2D, 0xC0, 0x7A, 0x28, 0xFE, 0x1A, 0xA7, 0x5C, + 0xB3, 0xB6, 0xCC, 0x97, 0xE7, 0x45, 0xD4, 0x58, 0xFA, 0xD1, 0x77, 0x6D, + 0x43, 0xA2, 0xC0, 0x87, 0x65, 0x34, 0x0A, 0x1F, 0x7A, 0xDD, 0xEB, 0x3C, + 0x33, 0xA1, 0xC5, 0x9D, 0x4D, 0xA4, 0x6F, 0x41, 0x95, 0x38, 0x7F, 0xC9, + 0x1E, 0x84, 0xEB, 0xD1, 0x9E, 0x49, 0x92, 0x87, 0x94, 0x87, 0x0C, 0x3A, + 0x85, 0x4A, 0x66, 0x9F, 0x9D, 0x59, 0x93, 0x4D, 0x97, 0x61, 0x06, 0x86, + 0x4A +}; + +static const unsigned char TA312_DN[] = { + 0x30, 0x57, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, + 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA312_RSA_N[] = { + 0xDA, 0x0E, 0xE6, 0x99, 0x8D, 0xCE, 0xA3, 0xE3, 0x4F, 0x8A, 0x7E, 0xFB, + 0xF1, 0x8B, 0x83, 0x25, 0x6B, 0xEA, 0x48, 0x1F, 0xF1, 0x2A, 0xB0, 0xB9, + 0x95, 0x11, 0x04, 0xBD, 0xF0, 0x63, 0xD1, 0xE2, 0x67, 0x66, 0xCF, 0x1C, + 0xDD, 0xCF, 0x1B, 0x48, 0x2B, 0xEE, 0x8D, 0x89, 0x8E, 0x9A, 0xAF, 0x29, + 0x80, 0x65, 0xAB, 0xE9, 0xC7, 0x2D, 0x12, 0xCB, 0xAB, 0x1C, 0x4C, 0x70, + 0x07, 0xA1, 0x3D, 0x0A, 0x30, 0xCD, 0x15, 0x8D, 0x4F, 0xF8, 0xDD, 0xD4, + 0x8C, 0x50, 0x15, 0x1C, 0xEF, 0x50, 0xEE, 0xC4, 0x2E, 0xF7, 0xFC, 0xE9, + 0x52, 0xF2, 0x91, 0x7D, 0xE0, 0x6D, 0xD5, 0x35, 0x30, 0x8E, 0x5E, 0x43, + 0x73, 0xF2, 0x41, 0xE9, 0xD5, 0x6A, 0xE3, 0xB2, 0x89, 0x3A, 0x56, 0x39, + 0x38, 0x6F, 0x06, 0x3C, 0x88, 0x69, 0x5B, 0x2A, 0x4D, 0xC5, 0xA7, 0x54, + 0xB8, 0x6C, 0x89, 0xCC, 0x9B, 0xF9, 0x3C, 0xCA, 0xE5, 0xFD, 0x89, 0xF5, + 0x12, 0x3C, 0x92, 0x78, 0x96, 0xD6, 0xDC, 0x74, 0x6E, 0x93, 0x44, 0x61, + 0xD1, 0x8D, 0xC7, 0x46, 0xB2, 0x75, 0x0E, 0x86, 0xE8, 0x19, 0x8A, 0xD5, + 0x6D, 0x6C, 0xD5, 0x78, 0x16, 0x95, 0xA2, 0xE9, 0xC8, 0x0A, 0x38, 0xEB, + 0xF2, 0x24, 0x13, 0x4F, 0x73, 0x54, 0x93, 0x13, 0x85, 0x3A, 0x1B, 0xBC, + 0x1E, 0x34, 0xB5, 0x8B, 0x05, 0x8C, 0xB9, 0x77, 0x8B, 0xB1, 0xDB, 0x1F, + 0x20, 0x91, 0xAB, 0x09, 0x53, 0x6E, 0x90, 0xCE, 0x7B, 0x37, 0x74, 0xB9, + 0x70, 0x47, 0x91, 0x22, 0x51, 0x63, 0x16, 0x79, 0xAE, 0xB1, 0xAE, 0x41, + 0x26, 0x08, 0xC8, 0x19, 0x2B, 0xD1, 0x46, 0xAA, 0x48, 0xD6, 0x64, 0x2A, + 0xD7, 0x83, 0x34, 0xFF, 0x2C, 0x2A, 0xC1, 0x6C, 0x19, 0x43, 0x4A, 0x07, + 0x85, 0xE7, 0xD3, 0x7C, 0xF6, 0x21, 0x68, 0xEF, 0xEA, 0xF2, 0x52, 0x9F, + 0x7F, 0x93, 0x90, 0xCF +}; + +static const unsigned char TA312_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA313_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x33, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA313_RSA_N[] = { + 0xCC, 0x25, 0x76, 0x90, 0x79, 0x06, 0x78, 0x22, 0x16, 0xF5, 0xC0, 0x83, + 0xB6, 0x84, 0xCA, 0x28, 0x9E, 0xFD, 0x05, 0x76, 0x11, 0xC5, 0xAD, 0x88, + 0x72, 0xFC, 0x46, 0x02, 0x43, 0xC7, 0xB2, 0x8A, 0x9D, 0x04, 0x5F, 0x24, + 0xCB, 0x2E, 0x4B, 0xE1, 0x60, 0x82, 0x46, 0xE1, 0x52, 0xAB, 0x0C, 0x81, + 0x47, 0x70, 0x6C, 0xDD, 0x64, 0xD1, 0xEB, 0xF5, 0x2C, 0xA3, 0x0F, 0x82, + 0x3D, 0x0C, 0x2B, 0xAE, 0x97, 0xD7, 0xB6, 0x14, 0x86, 0x10, 0x79, 0xBB, + 0x3B, 0x13, 0x80, 0x77, 0x8C, 0x08, 0xE1, 0x49, 0xD2, 0x6A, 0x62, 0x2F, + 0x1F, 0x5E, 0xFA, 0x96, 0x68, 0xDF, 0x89, 0x27, 0x95, 0x38, 0x9F, 0x06, + 0xD7, 0x3E, 0xC9, 0xCB, 0x26, 0x59, 0x0D, 0x73, 0xDE, 0xB0, 0xC8, 0xE9, + 0x26, 0x0E, 0x83, 0x15, 0xC6, 0xEF, 0x5B, 0x8B, 0xD2, 0x04, 0x60, 0xCA, + 0x49, 0xA6, 0x28, 0xF6, 0x69, 0x3B, 0xF6, 0xCB, 0xC8, 0x28, 0x91, 0xE5, + 0x9D, 0x8A, 0x61, 0x57, 0x37, 0xAC, 0x74, 0x14, 0xDC, 0x74, 0xE0, 0x3A, + 0xEE, 0x72, 0x2F, 0x2E, 0x9C, 0xFB, 0xD0, 0xBB, 0xBF, 0xF5, 0x3D, 0x00, + 0xE1, 0x06, 0x33, 0xE8, 0x82, 0x2B, 0xAE, 0x53, 0xA6, 0x3A, 0x16, 0x73, + 0x8C, 0xDD, 0x41, 0x0E, 0x20, 0x3A, 0xC0, 0xB4, 0xA7, 0xA1, 0xE9, 0xB2, + 0x4F, 0x90, 0x2E, 0x32, 0x60, 0xE9, 0x57, 0xCB, 0xB9, 0x04, 0x92, 0x68, + 0x68, 0xE5, 0x38, 0x26, 0x60, 0x75, 0xB2, 0x9F, 0x77, 0xFF, 0x91, 0x14, + 0xEF, 0xAE, 0x20, 0x49, 0xFC, 0xAD, 0x40, 0x15, 0x48, 0xD1, 0x02, 0x31, + 0x61, 0x19, 0x5E, 0xB8, 0x97, 0xEF, 0xAD, 0x77, 0xB7, 0x64, 0x9A, 0x7A, + 0xBF, 0x5F, 0xC1, 0x13, 0xEF, 0x9B, 0x62, 0xFB, 0x0D, 0x6C, 0xE0, 0x54, + 0x69, 0x16, 0xA9, 0x03, 0xDA, 0x6E, 0xE9, 0x83, 0x93, 0x71, 0x76, 0xC6, + 0x69, 0x85, 0x82, 0x17 +}; + +static const unsigned char TA313_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA314_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x36, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA314_RSA_N[] = { + 0x95, 0x07, 0xE8, 0x73, 0xCA, 0x66, 0xF9, 0xEC, 0x14, 0xCA, 0x7B, 0x3C, + 0xF7, 0x0D, 0x08, 0xF1, 0xB4, 0x45, 0x0B, 0x2C, 0x82, 0xB4, 0x48, 0xC6, + 0xEB, 0x5B, 0x3C, 0xAE, 0x83, 0xB8, 0x41, 0x92, 0x33, 0x14, 0xA4, 0x6F, + 0x7F, 0xE9, 0x2A, 0xCC, 0xC6, 0xB0, 0x88, 0x6B, 0xC5, 0xB6, 0x89, 0xD1, + 0xC6, 0xB2, 0xFF, 0x14, 0xCE, 0x51, 0x14, 0x21, 0xEC, 0x4A, 0xDD, 0x1B, + 0x5A, 0xC6, 0xD6, 0x87, 0xEE, 0x4D, 0x3A, 0x15, 0x06, 0xED, 0x64, 0x66, + 0x0B, 0x92, 0x80, 0xCA, 0x44, 0xDE, 0x73, 0x94, 0x4E, 0xF3, 0xA7, 0x89, + 0x7F, 0x4F, 0x78, 0x63, 0x08, 0xC8, 0x12, 0x50, 0x6D, 0x42, 0x66, 0x2F, + 0x4D, 0xB9, 0x79, 0x28, 0x4D, 0x52, 0x1A, 0x8A, 0x1A, 0x80, 0xB7, 0x19, + 0x81, 0x0E, 0x7E, 0xC4, 0x8A, 0xBC, 0x64, 0x4C, 0x21, 0x1C, 0x43, 0x68, + 0xD7, 0x3D, 0x3C, 0x8A, 0xC5, 0xB2, 0x66, 0xD5, 0x90, 0x9A, 0xB7, 0x31, + 0x06, 0xC5, 0xBE, 0xE2, 0x6D, 0x32, 0x06, 0xA6, 0x1E, 0xF9, 0xB9, 0xEB, + 0xAA, 0xA3, 0xB8, 0xBF, 0xBE, 0x82, 0x63, 0x50, 0xD0, 0xF0, 0x18, 0x89, + 0xDF, 0xE4, 0x0F, 0x79, 0xF5, 0xEA, 0xA2, 0x1F, 0x2A, 0xD2, 0x70, 0x2E, + 0x7B, 0xE7, 0xBC, 0x93, 0xBB, 0x6D, 0x53, 0xE2, 0x48, 0x7C, 0x8C, 0x10, + 0x07, 0x38, 0xFF, 0x66, 0xB2, 0x77, 0x61, 0x7E, 0xE0, 0xEA, 0x8C, 0x3C, + 0xAA, 0xB4, 0xA4, 0xF6, 0xF3, 0x95, 0x4A, 0x12, 0x07, 0x6D, 0xFD, 0x8C, + 0xB2, 0x89, 0xCF, 0xD0, 0xA0, 0x61, 0x77, 0xC8, 0x58, 0x74, 0xB0, 0xD4, + 0x23, 0x3A, 0xF7, 0x5D, 0x3A, 0xCA, 0xA2, 0xDB, 0x9D, 0x09, 0xDE, 0x5D, + 0x44, 0x2D, 0x90, 0xF1, 0x81, 0xCD, 0x57, 0x92, 0xFA, 0x7E, 0xBC, 0x50, + 0x04, 0x63, 0x34, 0xDF, 0x6B, 0x93, 0x18, 0xBE, 0x6B, 0x36, 0xB2, 0x39, + 0xE4, 0xAC, 0x24, 0x36, 0xB7, 0xF0, 0xEF, 0xB6, 0x1C, 0x13, 0x57, 0x93, + 0xB6, 0xDE, 0xB2, 0xF8, 0xE2, 0x85, 0xB7, 0x73, 0xA2, 0xB8, 0x35, 0xAA, + 0x45, 0xF2, 0xE0, 0x9D, 0x36, 0xA1, 0x6F, 0x54, 0x8A, 0xF1, 0x72, 0x56, + 0x6E, 0x2E, 0x88, 0xC5, 0x51, 0x42, 0x44, 0x15, 0x94, 0xEE, 0xA3, 0xC5, + 0x38, 0x96, 0x9B, 0x4E, 0x4E, 0x5A, 0x0B, 0x47, 0xF3, 0x06, 0x36, 0x49, + 0x77, 0x30, 0xBC, 0x71, 0x37, 0xE5, 0xA6, 0xEC, 0x21, 0x08, 0x75, 0xFC, + 0xE6, 0x61, 0x16, 0x3F, 0x77, 0xD5, 0xD9, 0x91, 0x97, 0x84, 0x0A, 0x6C, + 0xD4, 0x02, 0x4D, 0x74, 0xC0, 0x14, 0xED, 0xFD, 0x39, 0xFB, 0x83, 0xF2, + 0x5E, 0x14, 0xA1, 0x04, 0xB0, 0x0B, 0xE9, 0xFE, 0xEE, 0x8F, 0xE1, 0x6E, + 0x0B, 0xB2, 0x08, 0xB3, 0x61, 0x66, 0x09, 0x6A, 0xB1, 0x06, 0x3A, 0x65, + 0x96, 0x59, 0xC0, 0xF0, 0x35, 0xFD, 0xC9, 0xDA, 0x28, 0x8D, 0x1A, 0x11, + 0x87, 0x70, 0x81, 0x0A, 0xA8, 0x9A, 0x75, 0x1D, 0x9E, 0x3A, 0x86, 0x05, + 0x00, 0x9E, 0xDB, 0x80, 0xD6, 0x25, 0xF9, 0xDC, 0x05, 0x9E, 0x27, 0x59, + 0x4C, 0x76, 0x39, 0x5B, 0xEA, 0xF9, 0xA5, 0xA1, 0xD8, 0x83, 0x0F, 0xD1, + 0xFF, 0xDF, 0x30, 0x11, 0xF9, 0x85, 0xCF, 0x33, 0x48, 0xF5, 0xCA, 0x6D, + 0x64, 0x14, 0x2C, 0x7A, 0x58, 0x4F, 0xD3, 0x4B, 0x08, 0x49, 0xC5, 0x95, + 0x64, 0x1A, 0x63, 0x0E, 0x79, 0x3D, 0xF5, 0xB3, 0x8C, 0xCA, 0x58, 0xAD, + 0x9C, 0x42, 0x45, 0x79, 0x6E, 0x0E, 0x87, 0x19, 0x5C, 0x54, 0xB1, 0x65, + 0xB6, 0xBF, 0x8C, 0x9B, 0xDC, 0x13, 0xE9, 0x0D, 0x6F, 0xB8, 0x2E, 0xDC, + 0x67, 0x6E, 0xC9, 0x8B, 0x11, 0xB5, 0x84, 0x14, 0x8A, 0x00, 0x19, 0x70, + 0x83, 0x79, 0x91, 0x97, 0x91, 0xD4, 0x1A, 0x27, 0xBF, 0x37, 0x1E, 0x32, + 0x07, 0xD8, 0x14, 0x63, 0x3C, 0x28, 0x4C, 0xAF +}; + +static const unsigned char TA314_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA315_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, 0x36 +}; + +static const unsigned char TA315_EC_Q[] = { + 0x04, 0x9C, 0x0E, 0xB1, 0xCF, 0xB7, 0xE8, 0x9E, 0x52, 0x77, 0x75, 0x34, + 0xFA, 0xA5, 0x46, 0xA7, 0xAD, 0x32, 0x19, 0x32, 0xB4, 0x07, 0xA9, 0x27, + 0xCA, 0x94, 0xBB, 0x0C, 0xD2, 0x0A, 0x10, 0xC7, 0xDA, 0x89, 0xB0, 0x97, + 0x0C, 0x70, 0x13, 0x09, 0x01, 0x8E, 0xD8, 0xEA, 0x47, 0xEA, 0xBE, 0xB2, + 0x80, 0x2B, 0xCD, 0xFC, 0x28, 0x0D, 0xDB, 0xAC, 0xBC, 0xA4, 0x86, 0x37, + 0xED, 0x70, 0x08, 0x00, 0x75, 0xEA, 0x93, 0x0B, 0x7B, 0x2E, 0x52, 0x9C, + 0x23, 0x68, 0x23, 0x06, 0x43, 0xEC, 0x92, 0x2F, 0x53, 0x84, 0xDB, 0xFB, + 0x47, 0x14, 0x07, 0xE8, 0x5F, 0x94, 0x67, 0x5D, 0xC9, 0x7A, 0x81, 0x3C, + 0x20 +}; + +static const unsigned char TA316_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x36 +}; + +static const unsigned char TA316_RSA_N[] = { + 0xAC, 0xAC, 0x74, 0x32, 0xE8, 0xB3, 0x65, 0xE5, 0xBA, 0xED, 0x43, 0x26, + 0x1D, 0xA6, 0x89, 0x0D, 0x45, 0xBA, 0x29, 0x88, 0xB2, 0xA4, 0x1D, 0x63, + 0xDD, 0xD3, 0xC1, 0x2C, 0x09, 0x57, 0x89, 0x39, 0xA1, 0x55, 0xE9, 0x67, + 0x34, 0x77, 0x0C, 0x6E, 0xE4, 0x55, 0x1D, 0x52, 0x25, 0xD2, 0x13, 0x6B, + 0x5E, 0xE1, 0x1D, 0xA9, 0xB7, 0x7D, 0x89, 0x32, 0x5F, 0x0D, 0x9E, 0x9F, + 0x2C, 0x7A, 0x63, 0x60, 0x40, 0x1F, 0xA6, 0xB0, 0xB6, 0x78, 0x8F, 0x99, + 0x54, 0x96, 0x08, 0x58, 0xAE, 0xE4, 0x06, 0xBC, 0x62, 0x05, 0x02, 0x16, + 0xBF, 0xAF, 0xA8, 0x23, 0x03, 0xB6, 0x94, 0x0F, 0xBC, 0x6E, 0x6C, 0xC2, + 0xCB, 0xD5, 0xA6, 0xBB, 0x0C, 0xE9, 0xF6, 0xC1, 0x02, 0xFB, 0x21, 0xDE, + 0x66, 0xDD, 0x17, 0xAB, 0x74, 0x42, 0xEF, 0xF0, 0x74, 0x2F, 0x25, 0xF4, + 0xEA, 0x6B, 0x55, 0x5B, 0x90, 0xDB, 0x9D, 0xDF, 0x5E, 0x87, 0x0A, 0x40, + 0xFB, 0xAD, 0x19, 0x6B, 0xFB, 0xF7, 0xCA, 0x60, 0x88, 0xDE, 0xDA, 0xC1, + 0x8F, 0xD6, 0xAE, 0xD5, 0x7F, 0xD4, 0x3C, 0x83, 0xEE, 0xD7, 0x16, 0x4C, + 0x83, 0x45, 0x33, 0x6B, 0x27, 0xD0, 0x86, 0xD0, 0x1C, 0x2D, 0x6B, 0xF3, + 0xAB, 0x7D, 0xF1, 0x85, 0xA9, 0xF5, 0x28, 0xD2, 0xAD, 0xEF, 0xF3, 0x84, + 0x4B, 0x1C, 0x87, 0xFC, 0x13, 0xA3, 0x3A, 0x72, 0xA2, 0x5A, 0x11, 0x2B, + 0xD6, 0x27, 0x71, 0x27, 0xED, 0x81, 0x2D, 0x6D, 0x66, 0x81, 0x92, 0x87, + 0xB4, 0x1B, 0x58, 0x7A, 0xCC, 0x3F, 0x0A, 0xFA, 0x46, 0x4F, 0x4D, 0x78, + 0x5C, 0xF8, 0x2B, 0x48, 0xE3, 0x04, 0x84, 0xCB, 0x5D, 0xF6, 0xB4, 0x6A, + 0xB3, 0x65, 0xFC, 0x42, 0x9E, 0x51, 0x26, 0x23, 0x20, 0xCB, 0x3D, 0x14, + 0xF9, 0x81, 0xED, 0x65, 0x16, 0x00, 0x4F, 0x1A, 0x64, 0x97, 0x66, 0x08, + 0xCF, 0x8C, 0x7B, 0xE3, 0x2B, 0xC0, 0x9D, 0xF9, 0x14, 0xF2, 0x1B, 0xF1, + 0x56, 0x6A, 0x16, 0xBF, 0x2C, 0x85, 0x85, 0xCD, 0x78, 0x38, 0x9A, 0xEB, + 0x42, 0x6A, 0x02, 0x34, 0x18, 0x83, 0x17, 0x4E, 0x94, 0x56, 0xF8, 0xB6, + 0x82, 0xB5, 0xF3, 0x96, 0xDD, 0x3D, 0xF3, 0xBE, 0x7F, 0x20, 0x77, 0x3E, + 0x7B, 0x19, 0x23, 0x6B, 0x2C, 0xD4, 0x72, 0x73, 0x43, 0x57, 0x7D, 0xE0, + 0xF8, 0xD7, 0x69, 0x4F, 0x17, 0x36, 0x04, 0xF9, 0xC0, 0x90, 0x60, 0x37, + 0x45, 0xDE, 0xE6, 0x0C, 0xD8, 0x74, 0x8D, 0xAE, 0x9C, 0xA2, 0x6D, 0x74, + 0x5D, 0x42, 0xBE, 0x06, 0xF5, 0xD9, 0x64, 0x6E, 0x02, 0x10, 0xAC, 0x89, + 0xB0, 0x4C, 0x3B, 0x07, 0x4D, 0x40, 0x7E, 0x24, 0xC5, 0x8A, 0x98, 0x82, + 0x79, 0x8E, 0xA4, 0xA7, 0x82, 0x20, 0x8D, 0x23, 0xFA, 0x27, 0x71, 0xC9, + 0xDF, 0xC6, 0x41, 0x74, 0xA0, 0x4D, 0xF6, 0x91, 0x16, 0xDC, 0x46, 0x8C, + 0x5F, 0x29, 0x63, 0x31, 0x59, 0x71, 0x0C, 0xD8, 0x6F, 0xC2, 0xB6, 0x32, + 0x7D, 0xFB, 0xE6, 0x5D, 0x53, 0xA6, 0x7E, 0x15, 0xFC, 0xBB, 0x75, 0x7C, + 0x5D, 0xEC, 0xF8, 0xF6, 0x17, 0x1C, 0xEC, 0xC7, 0x6B, 0x19, 0xCB, 0xF3, + 0x7B, 0xF0, 0x2B, 0x07, 0xA5, 0xD9, 0x6C, 0x79, 0x54, 0x76, 0x6C, 0x9D, + 0x1C, 0xA6, 0x6E, 0x0E, 0xE9, 0x79, 0x0C, 0xA8, 0x23, 0x6A, 0xA3, 0xDF, + 0x1B, 0x30, 0x31, 0x9F, 0xB1, 0x54, 0x7B, 0xFE, 0x6A, 0xCB, 0x66, 0xAA, + 0xDC, 0x65, 0xD0, 0xA2, 0x9E, 0x4A, 0x9A, 0x07, 0x21, 0x6B, 0x81, 0x8F, + 0xDB, 0xC4, 0x59, 0xFA, 0xDE, 0x22, 0xC0, 0x04, 0x9C, 0xE3, 0xAA, 0x5B, + 0x36, 0x93, 0xE8, 0x3D, 0xBD, 0x7A, 0xA1, 0x9D, 0x0B, 0x76, 0xB1, 0x0B, + 0xC7, 0x9D, 0xFD, 0xCF, 0x98, 0xA8, 0x06, 0xC2, 0xF8, 0x2A, 0xA3, 0xA1, + 0x83, 0xA0, 0xB7, 0x25, 0x72, 0xA5, 0x02, 0xE3 +}; + +static const unsigned char TA316_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA317_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, + 0x64, 0x79, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x49, 0x6E, + 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x28, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6C, + 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA317_RSA_N[] = { + 0xDE, 0x9D, 0xD7, 0xEA, 0x57, 0x18, 0x49, 0xA1, 0x5B, 0xEB, 0xD7, 0x5F, + 0x48, 0x86, 0xEA, 0xBE, 0xDD, 0xFF, 0xE4, 0xEF, 0x67, 0x1C, 0xF4, 0x65, + 0x68, 0xB3, 0x57, 0x71, 0xA0, 0x5E, 0x77, 0xBB, 0xED, 0x9B, 0x49, 0xE9, + 0x70, 0x80, 0x3D, 0x56, 0x18, 0x63, 0x08, 0x6F, 0xDA, 0xF2, 0xCC, 0xD0, + 0x3F, 0x7F, 0x02, 0x54, 0x22, 0x54, 0x10, 0xD8, 0xB2, 0x81, 0xD4, 0xC0, + 0x75, 0x3D, 0x4B, 0x7F, 0xC7, 0x77, 0xC3, 0x3E, 0x78, 0xAB, 0x1A, 0x03, + 0xB5, 0x20, 0x6B, 0x2F, 0x6A, 0x2B, 0xB1, 0xC5, 0x88, 0x7E, 0xC4, 0xBB, + 0x1E, 0xB0, 0xC1, 0xD8, 0x45, 0x27, 0x6F, 0xAA, 0x37, 0x58, 0xF7, 0x87, + 0x26, 0xD7, 0xD8, 0x2D, 0xF6, 0xA9, 0x17, 0xB7, 0x1F, 0x72, 0x36, 0x4E, + 0xA6, 0x17, 0x3F, 0x65, 0x98, 0x92, 0xDB, 0x2A, 0x6E, 0x5D, 0xA2, 0xFE, + 0x88, 0xE0, 0x0B, 0xDE, 0x7F, 0xE5, 0x8D, 0x15, 0xE1, 0xEB, 0xCB, 0x3A, + 0xD5, 0xE2, 0x12, 0xA2, 0x13, 0x2D, 0xD8, 0x8E, 0xAF, 0x5F, 0x12, 0x3D, + 0xA0, 0x08, 0x05, 0x08, 0xB6, 0x5C, 0xA5, 0x65, 0x38, 0x04, 0x45, 0x99, + 0x1E, 0xA3, 0x60, 0x60, 0x74, 0xC5, 0x41, 0xA5, 0x72, 0x62, 0x1B, 0x62, + 0xC5, 0x1F, 0x6F, 0x5F, 0x1A, 0x42, 0xBE, 0x02, 0x51, 0x65, 0xA8, 0xAE, + 0x23, 0x18, 0x6A, 0xFC, 0x78, 0x03, 0xA9, 0x4D, 0x7F, 0x80, 0xC3, 0xFA, + 0xAB, 0x5A, 0xFC, 0xA1, 0x40, 0xA4, 0xCA, 0x19, 0x16, 0xFE, 0xB2, 0xC8, + 0xEF, 0x5E, 0x73, 0x0D, 0xEE, 0x77, 0xBD, 0x9A, 0xF6, 0x79, 0x98, 0xBC, + 0xB1, 0x07, 0x67, 0xA2, 0x15, 0x0D, 0xDD, 0xA0, 0x58, 0xC6, 0x44, 0x7B, + 0x0A, 0x3E, 0x62, 0x28, 0x5F, 0xBA, 0x41, 0x07, 0x53, 0x58, 0xCF, 0x11, + 0x7E, 0x38, 0x74, 0xC5, 0xF8, 0xFF, 0xB5, 0x69, 0x90, 0x8F, 0x84, 0x74, + 0xEA, 0x97, 0x1B, 0xAF +}; + +static const unsigned char TA317_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA318_DN[] = { + 0x30, 0x81, 0x83, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x1A, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, 0x47, 0x6F, 0x44, 0x61, 0x64, 0x64, + 0x79, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, + 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6F, + 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA318_RSA_N[] = { + 0xBF, 0x71, 0x62, 0x08, 0xF1, 0xFA, 0x59, 0x34, 0xF7, 0x1B, 0xC9, 0x18, + 0xA3, 0xF7, 0x80, 0x49, 0x58, 0xE9, 0x22, 0x83, 0x13, 0xA6, 0xC5, 0x20, + 0x43, 0x01, 0x3B, 0x84, 0xF1, 0xE6, 0x85, 0x49, 0x9F, 0x27, 0xEA, 0xF6, + 0x84, 0x1B, 0x4E, 0xA0, 0xB4, 0xDB, 0x70, 0x98, 0xC7, 0x32, 0x01, 0xB1, + 0x05, 0x3E, 0x07, 0x4E, 0xEE, 0xF4, 0xFA, 0x4F, 0x2F, 0x59, 0x30, 0x22, + 0xE7, 0xAB, 0x19, 0x56, 0x6B, 0xE2, 0x80, 0x07, 0xFC, 0xF3, 0x16, 0x75, + 0x80, 0x39, 0x51, 0x7B, 0xE5, 0xF9, 0x35, 0xB6, 0x74, 0x4E, 0xA9, 0x8D, + 0x82, 0x13, 0xE4, 0xB6, 0x3F, 0xA9, 0x03, 0x83, 0xFA, 0xA2, 0xBE, 0x8A, + 0x15, 0x6A, 0x7F, 0xDE, 0x0B, 0xC3, 0xB6, 0x19, 0x14, 0x05, 0xCA, 0xEA, + 0xC3, 0xA8, 0x04, 0x94, 0x3B, 0x46, 0x7C, 0x32, 0x0D, 0xF3, 0x00, 0x66, + 0x22, 0xC8, 0x8D, 0x69, 0x6D, 0x36, 0x8C, 0x11, 0x18, 0xB7, 0xD3, 0xB2, + 0x1C, 0x60, 0xB4, 0x38, 0xFA, 0x02, 0x8C, 0xCE, 0xD3, 0xDD, 0x46, 0x07, + 0xDE, 0x0A, 0x3E, 0xEB, 0x5D, 0x7C, 0xC8, 0x7C, 0xFB, 0xB0, 0x2B, 0x53, + 0xA4, 0x92, 0x62, 0x69, 0x51, 0x25, 0x05, 0x61, 0x1A, 0x44, 0x81, 0x8C, + 0x2C, 0xA9, 0x43, 0x96, 0x23, 0xDF, 0xAC, 0x3A, 0x81, 0x9A, 0x0E, 0x29, + 0xC5, 0x1C, 0xA9, 0xE9, 0x5D, 0x1E, 0xB6, 0x9E, 0x9E, 0x30, 0x0A, 0x39, + 0xCE, 0xF1, 0x88, 0x80, 0xFB, 0x4B, 0x5D, 0xCC, 0x32, 0xEC, 0x85, 0x62, + 0x43, 0x25, 0x34, 0x02, 0x56, 0x27, 0x01, 0x91, 0xB4, 0x3B, 0x70, 0x2A, + 0x3F, 0x6E, 0xB1, 0xE8, 0x9C, 0x88, 0x01, 0x7D, 0x9F, 0xD4, 0xF9, 0xDB, + 0x53, 0x6D, 0x60, 0x9D, 0xBF, 0x2C, 0xE7, 0x58, 0xAB, 0xB8, 0x5F, 0x46, + 0xFC, 0xCE, 0xC4, 0x1B, 0x03, 0x3C, 0x09, 0xEB, 0x49, 0x31, 0x5C, 0x69, + 0x46, 0xB3, 0xE0, 0x47 +}; + +static const unsigned char TA318_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA319_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, + 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA319_EC_Q[] = { + 0x04, 0x38, 0x08, 0xFE, 0xB1, 0xA0, 0x96, 0xD2, 0x7A, 0xAC, 0xAF, 0x49, + 0x3A, 0xD0, 0xC0, 0xE0, 0xC3, 0x3B, 0x28, 0xAA, 0xF1, 0x72, 0x6D, 0x65, + 0x00, 0x47, 0x88, 0x84, 0xFC, 0x9A, 0x26, 0x6B, 0xAA, 0x4B, 0xBA, 0x6C, + 0x04, 0x0A, 0x88, 0x5E, 0x17, 0xF2, 0x55, 0x87, 0xFC, 0x30, 0xB0, 0x34, + 0xE2, 0x34, 0x58, 0x57, 0x1A, 0x84, 0x53, 0xE9, 0x30, 0xD9, 0xA9, 0xF2, + 0x96, 0x74, 0xC3, 0x51, 0x1F, 0x58, 0x49, 0x31, 0xCC, 0x98, 0x4E, 0x60, + 0x11, 0x87, 0x75, 0xD3, 0x72, 0x94, 0x90, 0x4F, 0x9B, 0x10, 0x25, 0x2A, + 0xA8, 0x78, 0x2D, 0xBE, 0x90, 0x41, 0x58, 0x90, 0x15, 0x72, 0xA7, 0xA1, + 0xB7 +}; + +static const unsigned char TA320_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, + 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA320_RSA_N[] = { + 0x8B, 0xC2, 0xE7, 0xAF, 0x65, 0x9B, 0x05, 0x67, 0x96, 0xC9, 0x0D, 0x24, + 0xB9, 0xD0, 0x0E, 0x64, 0xFC, 0xCE, 0xE2, 0x24, 0x18, 0x2C, 0x84, 0x7F, + 0x77, 0x51, 0xCB, 0x04, 0x11, 0x36, 0xB8, 0x5E, 0xED, 0x69, 0x71, 0xA7, + 0x9E, 0xE4, 0x25, 0x09, 0x97, 0x67, 0xC1, 0x47, 0xC2, 0xCF, 0x91, 0x16, + 0x36, 0x62, 0x3D, 0x38, 0x04, 0xE1, 0x51, 0x82, 0xFF, 0xAC, 0xD2, 0xB4, + 0x69, 0xDD, 0x2E, 0xEC, 0x11, 0xA3, 0x45, 0xEE, 0x6B, 0x6B, 0x3B, 0x4C, + 0xBF, 0x8C, 0x8D, 0xA4, 0x1E, 0x9D, 0x11, 0xB9, 0xE9, 0x38, 0xF9, 0x7A, + 0x0E, 0x0C, 0x98, 0xE2, 0x23, 0x1D, 0xD1, 0x4E, 0x63, 0xD4, 0xE7, 0xB8, + 0x41, 0x44, 0xFB, 0x6B, 0xAF, 0x6B, 0xDA, 0x1F, 0xD3, 0xC5, 0x91, 0x88, + 0x5B, 0xA4, 0x89, 0x92, 0xD1, 0x81, 0xE6, 0x8C, 0x39, 0x58, 0xA0, 0xD6, + 0x69, 0x43, 0xA9, 0xAD, 0x98, 0x52, 0x58, 0x6E, 0xDB, 0x0A, 0xFB, 0x6B, + 0xCF, 0x68, 0xFA, 0xE3, 0xA4, 0x5E, 0x3A, 0x45, 0x73, 0x98, 0x07, 0xEA, + 0x5F, 0x02, 0x72, 0xDE, 0x0C, 0xA5, 0xB3, 0x9F, 0xAE, 0xA9, 0x1D, 0xB7, + 0x1D, 0xB3, 0xFC, 0x8A, 0x59, 0xE7, 0x6E, 0x72, 0x65, 0xAD, 0xF5, 0x30, + 0x94, 0x23, 0x07, 0xF3, 0x82, 0x16, 0x4B, 0x35, 0x98, 0x9C, 0x53, 0xBB, + 0x2F, 0xCA, 0xE4, 0x5A, 0xD9, 0xC7, 0x8D, 0x1D, 0xFC, 0x98, 0x99, 0xFB, + 0x2C, 0xA4, 0x82, 0x6B, 0xF0, 0x2A, 0x1F, 0x8E, 0x0B, 0x5F, 0x71, 0x5C, + 0x5C, 0xAE, 0x42, 0x7B, 0x29, 0x89, 0x81, 0xCB, 0x03, 0xA3, 0x99, 0xCA, + 0x88, 0x9E, 0x0B, 0x40, 0x09, 0x41, 0x33, 0xDB, 0xE6, 0x58, 0x7A, 0xFD, + 0xAE, 0x99, 0x70, 0xC0, 0x5A, 0x0F, 0xD6, 0x13, 0x86, 0x71, 0x2F, 0x76, + 0x69, 0xFC, 0x90, 0xDD, 0xDB, 0x2D, 0x6E, 0xD1, 0xF2, 0x9B, 0xF5, 0x1A, + 0x6B, 0x9E, 0x6F, 0x15, 0x8C, 0x7A, 0xF0, 0x4B, 0x28, 0xA0, 0x22, 0x38, + 0x80, 0x24, 0x6C, 0x36, 0xA4, 0x3B, 0xF2, 0x30, 0x91, 0xF3, 0x78, 0x13, + 0xCF, 0xC1, 0x3F, 0x35, 0xAB, 0xF1, 0x1D, 0x11, 0x23, 0xB5, 0x43, 0x22, + 0x9E, 0x01, 0x92, 0xB7, 0x18, 0x02, 0xE5, 0x11, 0xD1, 0x82, 0xDB, 0x15, + 0x00, 0xCC, 0x61, 0x37, 0xC1, 0x2A, 0x7C, 0x9A, 0xE1, 0xD0, 0xBA, 0xB3, + 0x50, 0x46, 0xEE, 0x82, 0xAC, 0x9D, 0x31, 0xF8, 0xFB, 0x23, 0xE2, 0x03, + 0x00, 0x48, 0x70, 0xA3, 0x09, 0x26, 0x79, 0x15, 0x53, 0x60, 0xF3, 0x38, + 0x5C, 0xAD, 0x38, 0xEA, 0x81, 0x00, 0x63, 0x14, 0xB9, 0x33, 0x5E, 0xDD, + 0x0B, 0xDB, 0xA0, 0x45, 0x07, 0x1A, 0x33, 0x09, 0xF8, 0x4D, 0xB4, 0xA7, + 0x02, 0xA6, 0x69, 0xF4, 0xC2, 0x59, 0x05, 0x88, 0x65, 0x85, 0x56, 0xAE, + 0x4B, 0xCB, 0xE0, 0xDE, 0x3C, 0x7D, 0x2D, 0x1A, 0xC8, 0xE9, 0xFB, 0x1F, + 0xA3, 0x61, 0x4A, 0xD6, 0x2A, 0x13, 0xAD, 0x77, 0x4C, 0x1A, 0x18, 0x9B, + 0x91, 0x0F, 0x58, 0xD8, 0x06, 0x54, 0xC5, 0x97, 0xF8, 0xAA, 0x3F, 0x20, + 0x8A, 0xA6, 0x85, 0xA6, 0x77, 0xF6, 0xA6, 0xFC, 0x1C, 0xE2, 0xEE, 0x6E, + 0x94, 0x33, 0x2A, 0x83, 0x50, 0x84, 0x0A, 0xE5, 0x4F, 0x86, 0xF8, 0x50, + 0x45, 0x78, 0x00, 0x81, 0xEB, 0x5B, 0x68, 0xE3, 0x26, 0x8D, 0xCC, 0x7B, + 0x5C, 0x51, 0xF4, 0x14, 0x2C, 0x40, 0xBE, 0x1A, 0x60, 0x1D, 0x7A, 0x72, + 0x61, 0x1D, 0x1F, 0x63, 0x2D, 0x88, 0xAA, 0xCE, 0xA2, 0x45, 0x90, 0x08, + 0xFC, 0x6B, 0xBE, 0xB3, 0x50, 0x2A, 0x5A, 0xFD, 0xA8, 0x48, 0x18, 0x46, + 0xD6, 0x90, 0x40, 0x92, 0x90, 0x0A, 0x84, 0x5E, 0x68, 0x31, 0xF8, 0xEB, + 0xED, 0x0D, 0xD3, 0x1D, 0xC6, 0x7D, 0x99, 0x18, 0x55, 0x56, 0x27, 0x65, + 0x2E, 0x8D, 0x45, 0xC5, 0x24, 0xEC, 0xCE, 0xE3 +}; + +static const unsigned char TA320_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA321_DN[] = { + 0x30, 0x81, 0xAA, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x44, 0x30, 0x42, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, + 0x20, 0x32, 0x30, 0x31, 0x35 +}; + +static const unsigned char TA321_EC_Q[] = { + 0x04, 0x92, 0xA0, 0x41, 0xE8, 0x4B, 0x82, 0x84, 0x5C, 0xE2, 0xF8, 0x31, + 0x11, 0x99, 0x86, 0x64, 0x4E, 0x09, 0x25, 0x2F, 0x9D, 0x41, 0x2F, 0x0A, + 0xAE, 0x35, 0x4F, 0x74, 0x95, 0xB2, 0x51, 0x64, 0x6B, 0x8D, 0x6B, 0xE6, + 0x3F, 0x70, 0x95, 0xF0, 0x05, 0x44, 0x47, 0xA6, 0x72, 0x38, 0x50, 0x76, + 0x95, 0x02, 0x5A, 0x8E, 0xAE, 0x28, 0x9E, 0xF9, 0x2D, 0x4E, 0x99, 0xEF, + 0x2C, 0x48, 0x6F, 0x4C, 0x25, 0x29, 0xE8, 0xD1, 0x71, 0x5B, 0xDF, 0x1D, + 0xC1, 0x75, 0x37, 0xB4, 0xD7, 0xFA, 0x7B, 0x7A, 0x42, 0x9C, 0x6A, 0x0A, + 0x56, 0x5A, 0x7C, 0x69, 0x0B, 0xAA, 0x80, 0x09, 0x24, 0x6C, 0x7E, 0xC1, + 0x46 +}; + +static const unsigned char TA322_DN[] = { + 0x30, 0x81, 0xA6, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x40, 0x30, 0x3E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x37, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, + 0x35 +}; + +static const unsigned char TA322_RSA_N[] = { + 0xC2, 0xF8, 0xA9, 0x3F, 0x1B, 0x89, 0xFC, 0x3C, 0x3C, 0x04, 0x5D, 0x3D, + 0x90, 0x36, 0xB0, 0x91, 0x3A, 0x79, 0x3C, 0x66, 0x5A, 0xEF, 0x6D, 0x39, + 0x01, 0x49, 0x1A, 0xB4, 0xB7, 0xCF, 0x7F, 0x4D, 0x23, 0x53, 0xB7, 0x90, + 0x00, 0xE3, 0x13, 0x2A, 0x28, 0xA6, 0x31, 0xF1, 0x91, 0x00, 0xE3, 0x28, + 0xEC, 0xAE, 0x21, 0x41, 0xCE, 0x1F, 0xDA, 0xFD, 0x7D, 0x12, 0x5B, 0x01, + 0x83, 0x0F, 0xB9, 0xB0, 0x5F, 0x99, 0xE1, 0xF2, 0x12, 0x83, 0x80, 0x4D, + 0x06, 0x3E, 0xDF, 0xAC, 0xAF, 0xE7, 0xA1, 0x88, 0x6B, 0x31, 0xAF, 0xF0, + 0x8B, 0xD0, 0x18, 0x33, 0xB8, 0xDB, 0x45, 0x6A, 0x34, 0xF4, 0x02, 0x80, + 0x24, 0x28, 0x0A, 0x02, 0x15, 0x95, 0x5E, 0x76, 0x2A, 0x0D, 0x99, 0x3A, + 0x14, 0x5B, 0xF6, 0xCB, 0xCB, 0x53, 0xBC, 0x13, 0x4D, 0x01, 0x88, 0x37, + 0x94, 0x25, 0x1B, 0x42, 0xBC, 0x22, 0xD8, 0x8E, 0xA3, 0x96, 0x5E, 0x3A, + 0xD9, 0x32, 0xDB, 0x3E, 0xE8, 0xF0, 0x10, 0x65, 0xED, 0x74, 0xE1, 0x2F, + 0xA7, 0x7C, 0xAF, 0x27, 0x34, 0xBB, 0x29, 0x7D, 0x9B, 0xB6, 0xCF, 0x09, + 0xC8, 0xE5, 0xD3, 0x0A, 0xFC, 0x88, 0x65, 0x65, 0x74, 0x0A, 0xDC, 0x73, + 0x1C, 0x5C, 0xCD, 0x40, 0xB1, 0x1C, 0xD4, 0xB6, 0x84, 0x8C, 0x4C, 0x50, + 0xCF, 0x68, 0x8E, 0xA8, 0x59, 0xAE, 0xC2, 0x27, 0x4E, 0x82, 0xA2, 0x35, + 0xDD, 0x14, 0xF4, 0x1F, 0xFF, 0xB2, 0x77, 0xD5, 0x87, 0x2F, 0xAA, 0x6E, + 0x7D, 0x24, 0x27, 0xE7, 0xC6, 0xCB, 0x26, 0xE6, 0xE5, 0xFE, 0x67, 0x07, + 0x63, 0xD8, 0x45, 0x0D, 0xDD, 0x3A, 0x59, 0x65, 0x39, 0x58, 0x7A, 0x92, + 0x99, 0x72, 0x3D, 0x9C, 0x84, 0x5E, 0x88, 0x21, 0xB8, 0xD5, 0xF4, 0x2C, + 0xFC, 0xD9, 0x70, 0x52, 0x4F, 0x78, 0xB8, 0xBD, 0x3C, 0x2B, 0x8B, 0x95, + 0x98, 0xF5, 0xB3, 0xD1, 0x68, 0xCF, 0x20, 0x14, 0x7E, 0x4C, 0x5C, 0x5F, + 0xE7, 0x8B, 0xE5, 0xF5, 0x35, 0x81, 0x19, 0x37, 0xD7, 0x11, 0x08, 0xB7, + 0x66, 0xBE, 0xD3, 0x4A, 0xCE, 0x83, 0x57, 0x00, 0x3A, 0xC3, 0x81, 0xF8, + 0x17, 0xCB, 0x92, 0x36, 0x5D, 0xD1, 0xA3, 0xD8, 0x75, 0x1B, 0xE1, 0x8B, + 0x27, 0xEA, 0x7A, 0x48, 0x41, 0xFD, 0x45, 0x19, 0x06, 0xAD, 0x27, 0x99, + 0x4E, 0xC1, 0x70, 0x47, 0xDD, 0xB5, 0x9F, 0x81, 0x53, 0x12, 0xE5, 0xB1, + 0x8C, 0x48, 0x5D, 0x31, 0x43, 0x17, 0xE3, 0x8C, 0xC6, 0x7A, 0x63, 0x96, + 0x4B, 0x29, 0x30, 0x4E, 0x84, 0x4E, 0x62, 0x19, 0x5E, 0x3C, 0xCE, 0x97, + 0x90, 0xA5, 0x7F, 0x01, 0xEB, 0x9D, 0xE0, 0xF8, 0x8B, 0x89, 0xDD, 0x25, + 0x98, 0x3D, 0x92, 0xB6, 0x7E, 0xEF, 0xD9, 0xF1, 0x51, 0x51, 0x7D, 0x2D, + 0x26, 0xC8, 0x69, 0x59, 0x61, 0xE0, 0xAC, 0x6A, 0xB8, 0x2A, 0x36, 0x11, + 0x04, 0x7A, 0x50, 0xBD, 0x32, 0x84, 0xBE, 0x2F, 0xDC, 0x72, 0xD5, 0xD7, + 0x1D, 0x16, 0x47, 0xE4, 0x47, 0x66, 0x20, 0x3F, 0xF4, 0x96, 0xC5, 0xAF, + 0x8E, 0x01, 0x7A, 0xA5, 0x0F, 0x7A, 0x64, 0xF5, 0x0D, 0x18, 0x87, 0xD9, + 0xAE, 0x88, 0xD5, 0xFA, 0x84, 0xC1, 0x3A, 0xC0, 0x69, 0x28, 0x2D, 0xF2, + 0x0D, 0x68, 0x51, 0xAA, 0xE3, 0xA5, 0x77, 0xC6, 0xA4, 0x90, 0x0E, 0xA1, + 0x37, 0x8B, 0x31, 0x23, 0x47, 0xC1, 0x09, 0x08, 0xEB, 0x6E, 0xF7, 0x78, + 0x9B, 0xD7, 0x82, 0xFC, 0x84, 0x20, 0x99, 0x49, 0x19, 0xB6, 0x12, 0x46, + 0xB1, 0xFB, 0x45, 0x55, 0x16, 0xA9, 0xA3, 0x65, 0xAC, 0x9C, 0x07, 0x0F, + 0xEA, 0x6B, 0xDC, 0x1F, 0x2E, 0x06, 0x72, 0xEC, 0x86, 0x88, 0x12, 0xE4, + 0x2D, 0xDB, 0x5F, 0x05, 0x2F, 0xE4, 0xF0, 0x03, 0xD3, 0x26, 0x33, 0xE7, + 0x80, 0xC2, 0xCD, 0x42, 0xA1, 0x17, 0x34, 0x0B +}; + +static const unsigned char TA322_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA323_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x12, 0x48, 0x69, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA323_RSA_N[] = { + 0xF4, 0x1E, 0x7F, 0x52, 0x73, 0x32, 0x0C, 0x73, 0xE4, 0xBD, 0x13, 0x74, + 0xA3, 0xD4, 0x30, 0xA8, 0xD0, 0xAE, 0x4B, 0xD8, 0xB6, 0xDF, 0x75, 0x47, + 0x66, 0xF4, 0x7C, 0xE7, 0x39, 0x04, 0x1E, 0x6A, 0x70, 0x20, 0xD2, 0x5A, + 0x47, 0x72, 0x67, 0x55, 0xF4, 0xA5, 0xE8, 0x9D, 0xD5, 0x1E, 0x21, 0xA1, + 0xF0, 0x67, 0xBA, 0xCC, 0x21, 0x68, 0xBE, 0x44, 0x53, 0xBF, 0x8D, 0xF9, + 0xE2, 0xDC, 0x2F, 0x55, 0xC8, 0x37, 0x3F, 0x1F, 0xA4, 0xC0, 0x9C, 0xB3, + 0xE4, 0x77, 0x5C, 0xA0, 0x46, 0xFE, 0x77, 0xFA, 0x1A, 0xA0, 0x38, 0xEA, + 0xED, 0x9A, 0x72, 0xDE, 0x2B, 0xBD, 0x94, 0x57, 0x3A, 0xBA, 0xEC, 0x79, + 0xE7, 0x5F, 0x7D, 0x42, 0x64, 0x39, 0x7A, 0x26, 0x36, 0xF7, 0x24, 0xF0, + 0xD5, 0x2F, 0xBA, 0x95, 0x98, 0x11, 0x66, 0xAD, 0x97, 0x35, 0xD6, 0x75, + 0x01, 0x80, 0xE0, 0xAF, 0xF4, 0x84, 0x61, 0x8C, 0x0D, 0x1E, 0x5F, 0x7C, + 0x87, 0x96, 0x5E, 0x41, 0xAF, 0xEB, 0x87, 0xEA, 0xF8, 0x5D, 0xF1, 0x2E, + 0x88, 0x05, 0x3E, 0x4C, 0x22, 0xBB, 0xDA, 0x1F, 0x2A, 0xDD, 0x52, 0x46, + 0x64, 0x39, 0xF3, 0x42, 0xCE, 0xD9, 0x9E, 0x0C, 0xB3, 0xB0, 0x77, 0x97, + 0x64, 0x9C, 0xC0, 0xF4, 0xA3, 0x2E, 0x1F, 0x95, 0x07, 0xB0, 0x17, 0xDF, + 0x30, 0xDB, 0x00, 0x18, 0x96, 0x4C, 0xA1, 0x81, 0x4B, 0xDD, 0x04, 0x6D, + 0x53, 0xA3, 0x3D, 0xFC, 0x07, 0xAC, 0xD4, 0xC5, 0x37, 0x82, 0xEB, 0xE4, + 0x95, 0x08, 0x19, 0x28, 0x82, 0xD2, 0x42, 0x3A, 0xA3, 0xD8, 0x53, 0xEC, + 0x79, 0x89, 0x60, 0x48, 0x60, 0xC8, 0x72, 0x92, 0x50, 0xDC, 0x03, 0x8F, + 0x83, 0x3F, 0xB2, 0x42, 0x57, 0x5A, 0xDB, 0x6A, 0xE9, 0x11, 0x97, 0xDD, + 0x85, 0x28, 0xBC, 0x30, 0x4C, 0xAB, 0xE3, 0xC2, 0xB1, 0x45, 0x44, 0x47, + 0x1F, 0xE0, 0x8A, 0x16, 0x07, 0x96, 0xD2, 0x21, 0x0F, 0x53, 0xC0, 0xED, + 0xA9, 0x7E, 0xD4, 0x4E, 0xEC, 0x9B, 0x09, 0xEC, 0xAF, 0x42, 0xAC, 0x30, + 0xD6, 0xBF, 0xD1, 0x10, 0x45, 0xE0, 0xA6, 0x16, 0xB2, 0xA5, 0xC5, 0xD3, + 0x4F, 0x73, 0x94, 0x33, 0x71, 0x02, 0xA1, 0x6A, 0xA3, 0xD6, 0x33, 0x97, + 0x4F, 0x21, 0x63, 0x1E, 0x5B, 0x8F, 0xD9, 0xC1, 0x5E, 0x45, 0x71, 0x77, + 0x0F, 0x81, 0x5D, 0x5F, 0x21, 0x9A, 0xAD, 0x83, 0xCC, 0xFA, 0x5E, 0xD6, + 0x8D, 0x23, 0x5F, 0x1B, 0x3D, 0x41, 0xAF, 0x20, 0x75, 0x66, 0x5A, 0x4A, + 0xF6, 0x9F, 0xFB, 0xAB, 0x18, 0xF7, 0x71, 0xC0, 0xB6, 0x1D, 0x31, 0xEC, + 0x3B, 0x20, 0xEB, 0xCB, 0xE2, 0xB8, 0xF5, 0xAE, 0x92, 0xB2, 0xF7, 0xE1, + 0x84, 0x4B, 0xF2, 0xA2, 0xF2, 0x93, 0x9A, 0x22, 0x9E, 0xD3, 0x14, 0x6F, + 0x36, 0x54, 0xBD, 0x1F, 0x5E, 0x59, 0x15, 0xB9, 0x73, 0xA8, 0xC1, 0x7C, + 0x6F, 0x7B, 0x62, 0xE9, 0x16, 0x6C, 0x47, 0x5A, 0x65, 0xF3, 0x0E, 0x11, + 0x9B, 0x46, 0xD9, 0xFD, 0x6D, 0xDC, 0xD6, 0x9C, 0xC0, 0xB4, 0x7D, 0xA5, + 0xB0, 0xDD, 0x3F, 0x56, 0x6F, 0xA1, 0xF9, 0xF6, 0xE4, 0x12, 0x48, 0xFD, + 0x06, 0x7F, 0x12, 0x57, 0xB6, 0xA9, 0x23, 0x4F, 0x5B, 0x03, 0xC3, 0xE0, + 0x71, 0x2A, 0x23, 0xB7, 0xF7, 0xB0, 0xB1, 0x3B, 0xBC, 0x98, 0xBD, 0xD6, + 0x98, 0xA8, 0x0C, 0x6B, 0xF6, 0x8E, 0x12, 0x67, 0xA6, 0xF2, 0xB2, 0x58, + 0xE4, 0x02, 0x09, 0x13, 0x3C, 0xA9, 0xBB, 0x10, 0xB4, 0xD2, 0x30, 0x45, + 0xF1, 0xEC, 0xF7, 0x00, 0x11, 0xDF, 0x65, 0xF8, 0xDC, 0x2B, 0x43, 0x55, + 0xBF, 0x16, 0x97, 0xC4, 0x0F, 0xD5, 0x2C, 0x61, 0x84, 0xAA, 0x72, 0x86, + 0xFE, 0xE6, 0x3A, 0x7E, 0xC2, 0x3F, 0x7D, 0xEE, 0xFC, 0x2F, 0x14, 0x3E, + 0xE6, 0x85, 0xDD, 0x50, 0x6F, 0xB7, 0x49, 0xED +}; + +static const unsigned char TA323_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA324_DN[] = { + 0x30, 0x6F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x4B, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x09, 0x48, 0x6F, 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x48, 0x6F, + 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA324_RSA_N[] = { + 0xB3, 0x88, 0xD7, 0xEA, 0xCE, 0x0F, 0x20, 0x4E, 0xBE, 0xE6, 0xD6, 0x03, + 0x6D, 0xEE, 0x59, 0xFC, 0xC2, 0x57, 0xDF, 0x29, 0x68, 0xA1, 0x83, 0x0E, + 0x3E, 0x68, 0xC7, 0x68, 0x58, 0x9C, 0x1C, 0x60, 0x4B, 0x89, 0x43, 0x0C, + 0xB9, 0xD4, 0x15, 0xB2, 0xEE, 0xC1, 0x4E, 0x75, 0xE9, 0xB5, 0xA7, 0xEF, + 0xE5, 0xE9, 0x35, 0x99, 0xE4, 0xCC, 0x1C, 0xE7, 0x4B, 0x5F, 0x8D, 0x33, + 0x30, 0x20, 0x33, 0x53, 0xD9, 0xA6, 0xBB, 0xD5, 0x3E, 0x13, 0x8E, 0xE9, + 0x1F, 0x87, 0x49, 0xAD, 0x50, 0x2D, 0x50, 0xCA, 0x18, 0xBE, 0x01, 0x58, + 0xA2, 0x13, 0x70, 0x96, 0xBB, 0x89, 0x88, 0x56, 0x80, 0x5C, 0xF8, 0xBD, + 0x2C, 0x3C, 0xE1, 0x4C, 0x57, 0x88, 0xBB, 0xD3, 0xB9, 0x95, 0xEF, 0xCB, + 0xC7, 0xF6, 0xDA, 0x31, 0x74, 0x28, 0xA6, 0xE6, 0x54, 0x89, 0xF5, 0x41, + 0x31, 0xCA, 0xE5, 0x26, 0x1A, 0xCD, 0x82, 0xE0, 0x70, 0xDA, 0x3B, 0x29, + 0xBB, 0xD5, 0x03, 0xF5, 0x99, 0xBA, 0x55, 0xF5, 0x64, 0xD1, 0x60, 0x0E, + 0xB3, 0x89, 0x49, 0xB8, 0x8A, 0x2F, 0x05, 0xD2, 0x84, 0x45, 0x28, 0x7C, + 0x8F, 0x68, 0x50, 0x12, 0x78, 0xFC, 0x0B, 0xB5, 0x53, 0xCB, 0xC2, 0x98, + 0x1C, 0x84, 0xA3, 0x9E, 0xB0, 0xBE, 0x23, 0xA4, 0xDA, 0xDC, 0xC8, 0x2B, + 0x1E, 0xDA, 0x6E, 0x45, 0x1E, 0x89, 0x98, 0xDA, 0xF9, 0x00, 0x2E, 0x06, + 0xE9, 0x0C, 0x3B, 0x70, 0xD5, 0x50, 0x25, 0x88, 0x99, 0xCB, 0xCD, 0x73, + 0x60, 0xF7, 0xD5, 0xFF, 0x35, 0x67, 0xC5, 0xA1, 0xBC, 0x5E, 0xAB, 0xCD, + 0x4A, 0xB8, 0x45, 0xEB, 0xC8, 0x68, 0x1E, 0x0D, 0x0D, 0x14, 0x46, 0x12, + 0xE3, 0xD2, 0x64, 0x62, 0x8A, 0x42, 0x98, 0xBC, 0xB4, 0xC6, 0x08, 0x08, + 0xF8, 0xFD, 0xA8, 0x4C, 0x64, 0x9C, 0x76, 0x01, 0xBD, 0x2F, 0xA9, 0x6C, + 0x33, 0x0F, 0xD8, 0x3F, 0x28, 0xB8, 0x3C, 0x69, 0x01, 0x42, 0x86, 0x7E, + 0x69, 0xC1, 0xC9, 0x06, 0xCA, 0xE5, 0x7A, 0x46, 0x65, 0xE9, 0xC2, 0xD6, + 0x50, 0x41, 0x2E, 0x3F, 0xB7, 0xE4, 0xED, 0x6C, 0xD7, 0xBF, 0x26, 0x01, + 0x11, 0xA2, 0x16, 0x29, 0x4A, 0x6B, 0x34, 0x06, 0x90, 0xEC, 0x13, 0xD2, + 0xB6, 0xFB, 0x6A, 0x76, 0xD2, 0x3C, 0xED, 0xF0, 0xD6, 0x2D, 0xDD, 0xE1, + 0x15, 0xEC, 0xA3, 0x9B, 0x2F, 0x2C, 0xC9, 0x3E, 0x2B, 0xE4, 0x69, 0x3B, + 0xFF, 0x72, 0x25, 0xB1, 0x36, 0x86, 0x5B, 0xC7, 0x7F, 0x6B, 0x8B, 0x55, + 0x1B, 0x4A, 0xC5, 0x20, 0x61, 0x3D, 0xAE, 0xCB, 0x50, 0xE1, 0x08, 0x3A, + 0xBE, 0xB0, 0x8F, 0x63, 0x41, 0x53, 0x30, 0x08, 0x59, 0x3C, 0x98, 0x1D, + 0x77, 0xBA, 0x63, 0x91, 0x7A, 0xCA, 0x10, 0x50, 0x60, 0xBF, 0xF0, 0xD7, + 0xBC, 0x95, 0x87, 0x8F, 0x97, 0xC5, 0xFE, 0x97, 0x6A, 0x01, 0x94, 0xA3, + 0x7C, 0x5B, 0x85, 0x1D, 0x2A, 0x39, 0x3A, 0xD0, 0x54, 0xA1, 0xD1, 0x39, + 0x71, 0x9D, 0xFD, 0x21, 0xF9, 0xB5, 0x7B, 0xF0, 0xE2, 0xE0, 0x02, 0x8F, + 0x6E, 0x96, 0x24, 0x25, 0x2C, 0xA0, 0x1E, 0x2C, 0xA8, 0xC4, 0x89, 0xA7, + 0xEF, 0xED, 0x99, 0x06, 0x2F, 0xB6, 0x0A, 0x4C, 0x4F, 0xDB, 0xA2, 0xCC, + 0x37, 0x1A, 0xAF, 0x47, 0x85, 0x2D, 0x8A, 0x5F, 0xC4, 0x34, 0x34, 0x4C, + 0x00, 0xFD, 0x18, 0x93, 0x67, 0x13, 0xD1, 0x37, 0xE6, 0x48, 0xB4, 0x8B, + 0x06, 0xC5, 0x57, 0x7B, 0x19, 0x86, 0x0A, 0x79, 0xCB, 0x00, 0xC9, 0x52, + 0xAF, 0x42, 0xFF, 0x37, 0x8F, 0xE1, 0xA3, 0x1E, 0x7A, 0x3D, 0x50, 0xAB, + 0x63, 0x06, 0xE7, 0x15, 0xB5, 0x3F, 0xB6, 0x45, 0x37, 0x94, 0x37, 0xB1, + 0x7E, 0xF2, 0x48, 0xC3, 0x7F, 0xC5, 0x75, 0xFE, 0x97, 0x8D, 0x45, 0x8F, + 0x1A, 0xA7, 0x1A, 0x72, 0x28, 0x1A, 0x40, 0x0F +}; + +static const unsigned char TA324_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA325_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x31 +}; + +static const unsigned char TA325_RSA_N[] = { + 0xAD, 0xE8, 0x24, 0x73, 0xF4, 0x14, 0x37, 0xF3, 0x9B, 0x9E, 0x2B, 0x57, + 0x28, 0x1C, 0x87, 0xBE, 0xDC, 0xB7, 0xDF, 0x38, 0x90, 0x8C, 0x6E, 0x3C, + 0xE6, 0x57, 0xA0, 0x78, 0xF7, 0x75, 0xC2, 0xA2, 0xFE, 0xF5, 0x6A, 0x6E, + 0xF6, 0x00, 0x4F, 0x28, 0xDB, 0xDE, 0x68, 0x86, 0x6C, 0x44, 0x93, 0xB6, + 0xB1, 0x63, 0xFD, 0x14, 0x12, 0x6B, 0xBF, 0x1F, 0xD2, 0xEA, 0x31, 0x9B, + 0x21, 0x7E, 0xD1, 0x33, 0x3C, 0xBA, 0x48, 0xF5, 0xDD, 0x79, 0xDF, 0xB3, + 0xB8, 0xFF, 0x12, 0xF1, 0x21, 0x9A, 0x4B, 0xC1, 0x8A, 0x86, 0x71, 0x69, + 0x4A, 0x66, 0x66, 0x6C, 0x8F, 0x7E, 0x3C, 0x70, 0xBF, 0xAD, 0x29, 0x22, + 0x06, 0xF3, 0xE4, 0xC0, 0xE6, 0x80, 0xAE, 0xE2, 0x4B, 0x8F, 0xB7, 0x99, + 0x7E, 0x94, 0x03, 0x9F, 0xD3, 0x47, 0x97, 0x7C, 0x99, 0x48, 0x23, 0x53, + 0xE8, 0x38, 0xAE, 0x4F, 0x0A, 0x6F, 0x83, 0x2E, 0xD1, 0x49, 0x57, 0x8C, + 0x80, 0x74, 0xB6, 0xDA, 0x2F, 0xD0, 0x38, 0x8D, 0x7B, 0x03, 0x70, 0x21, + 0x1B, 0x75, 0xF2, 0x30, 0x3C, 0xFA, 0x8F, 0xAE, 0xDD, 0xDA, 0x63, 0xAB, + 0xEB, 0x16, 0x4F, 0xC2, 0x8E, 0x11, 0x4B, 0x7E, 0xCF, 0x0B, 0xE8, 0xFF, + 0xB5, 0x77, 0x2E, 0xF4, 0xB2, 0x7B, 0x4A, 0xE0, 0x4C, 0x12, 0x25, 0x0C, + 0x70, 0x8D, 0x03, 0x29, 0xA0, 0xE1, 0x53, 0x24, 0xEC, 0x13, 0xD9, 0xEE, + 0x19, 0xBF, 0x10, 0xB3, 0x4A, 0x8C, 0x3F, 0x89, 0xA3, 0x61, 0x51, 0xDE, + 0xAC, 0x87, 0x07, 0x94, 0xF4, 0x63, 0x71, 0xEC, 0x2E, 0xE2, 0x6F, 0x5B, + 0x98, 0x81, 0xE1, 0x89, 0x5C, 0x34, 0x79, 0x6C, 0x76, 0xEF, 0x3B, 0x90, + 0x62, 0x79, 0xE6, 0xDB, 0xA4, 0x9A, 0x2F, 0x26, 0xC5, 0xD0, 0x10, 0xE1, + 0x0E, 0xDE, 0xD9, 0x10, 0x8E, 0x16, 0xFB, 0xB7, 0xF7, 0xA8, 0xF7, 0xC7, + 0xE5, 0x02, 0x07, 0x98, 0x8F, 0x36, 0x08, 0x95, 0xE7, 0xE2, 0x37, 0x96, + 0x0D, 0x36, 0x75, 0x9E, 0xFB, 0x0E, 0x72, 0xB1, 0x1D, 0x9B, 0xBC, 0x03, + 0xF9, 0x49, 0x05, 0xD8, 0x81, 0xDD, 0x05, 0xB4, 0x2A, 0xD6, 0x41, 0xE9, + 0xAC, 0x01, 0x76, 0x95, 0x0A, 0x0F, 0xD8, 0xDF, 0xD5, 0xBD, 0x12, 0x1F, + 0x35, 0x2F, 0x28, 0x17, 0x6C, 0xD2, 0x98, 0xC1, 0xA8, 0x09, 0x64, 0x77, + 0x6E, 0x47, 0x37, 0xBA, 0xCE, 0xAC, 0x59, 0x5E, 0x68, 0x9D, 0x7F, 0x72, + 0xD6, 0x89, 0xC5, 0x06, 0x41, 0x29, 0x3E, 0x59, 0x3E, 0xDD, 0x26, 0xF5, + 0x24, 0xC9, 0x11, 0xA7, 0x5A, 0xA3, 0x4C, 0x40, 0x1F, 0x46, 0xA1, 0x99, + 0xB5, 0xA7, 0x3A, 0x51, 0x6E, 0x86, 0x3B, 0x9E, 0x7D, 0x72, 0xA7, 0x12, + 0x05, 0x78, 0x59, 0xED, 0x3E, 0x51, 0x78, 0x15, 0x0B, 0x03, 0x8F, 0x8D, + 0xD0, 0x2F, 0x05, 0xB2, 0x3E, 0x7B, 0x4A, 0x1C, 0x4B, 0x73, 0x05, 0x12, + 0xFC, 0xC6, 0xEA, 0xE0, 0x50, 0x13, 0x7C, 0x43, 0x93, 0x74, 0xB3, 0xCA, + 0x74, 0xE7, 0x8E, 0x1F, 0x01, 0x08, 0xD0, 0x30, 0xD4, 0x5B, 0x71, 0x36, + 0xB4, 0x07, 0xBA, 0xC1, 0x30, 0x30, 0x5C, 0x48, 0xB7, 0x82, 0x3B, 0x98, + 0xA6, 0x7D, 0x60, 0x8A, 0xA2, 0xA3, 0x29, 0x82, 0xCC, 0xBA, 0xBD, 0x83, + 0x04, 0x1B, 0xA2, 0x83, 0x03, 0x41, 0xA1, 0xD6, 0x05, 0xF1, 0x1B, 0xC2, + 0xB6, 0xF0, 0xA8, 0x7C, 0x86, 0x3B, 0x46, 0xA8, 0x48, 0x2A, 0x88, 0xDC, + 0x76, 0x9A, 0x76, 0xBF, 0x1F, 0x6A, 0xA5, 0x3D, 0x19, 0x8F, 0xEB, 0x38, + 0xF3, 0x64, 0xDE, 0xC8, 0x2B, 0x0D, 0x0A, 0x28, 0xFF, 0xF7, 0xDB, 0xE2, + 0x15, 0x42, 0xD4, 0x22, 0xD0, 0x27, 0x5D, 0xE1, 0x79, 0xFE, 0x18, 0xE7, + 0x70, 0x88, 0xAD, 0x4E, 0xE6, 0xD9, 0x8B, 0x3A, 0xC6, 0xDD, 0x27, 0x51, + 0x6E, 0xFF, 0xBC, 0x64, 0xF5, 0x33, 0x43, 0x4F +}; + +static const unsigned char TA325_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA326_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x32 +}; + +static const unsigned char TA326_EC_Q[] = { + 0x04, 0xCD, 0x9B, 0xD5, 0x9F, 0x80, 0x83, 0x0A, 0xEC, 0x09, 0x4A, 0xF3, + 0x16, 0x4A, 0x3E, 0x5C, 0xCF, 0x77, 0xAC, 0xDE, 0x67, 0x05, 0x0D, 0x1D, + 0x07, 0xB6, 0xDC, 0x16, 0xFB, 0x5A, 0x8B, 0x14, 0xDB, 0xE2, 0x71, 0x60, + 0xC4, 0xBA, 0x45, 0x95, 0x11, 0x89, 0x8E, 0xEA, 0x06, 0xDF, 0xF7, 0x2A, + 0x16, 0x1C, 0xA4, 0xB9, 0xC5, 0xC5, 0x32, 0xE0, 0x03, 0xE0, 0x1E, 0x82, + 0x18, 0x38, 0x8B, 0xD7, 0x45, 0xD8, 0x0A, 0x6A, 0x6E, 0xE6, 0x00, 0x77, + 0xFB, 0x02, 0x51, 0x7D, 0x22, 0xD8, 0x0A, 0x6E, 0x9A, 0x5B, 0x77, 0xDF, + 0xF0, 0xFA, 0x41, 0xEC, 0x39, 0xDC, 0x75, 0xCA, 0x68, 0x07, 0x0C, 0x1F, + 0xEA +}; + +static const unsigned char TA327_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6F, 0x6D, 0x6D, + 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA327_RSA_N[] = { + 0xA7, 0x50, 0x19, 0xDE, 0x3F, 0x99, 0x3D, 0xD4, 0x33, 0x46, 0xF1, 0x6F, + 0x51, 0x61, 0x82, 0xB2, 0xA9, 0x4F, 0x8F, 0x67, 0x89, 0x5D, 0x84, 0xD9, + 0x53, 0xDD, 0x0C, 0x28, 0xD9, 0xD7, 0xF0, 0xFF, 0xAE, 0x95, 0x43, 0x72, + 0x99, 0xF9, 0xB5, 0x5D, 0x7C, 0x8A, 0xC1, 0x42, 0xE1, 0x31, 0x50, 0x74, + 0xD1, 0x81, 0x0D, 0x7C, 0xCD, 0x9B, 0x21, 0xAB, 0x43, 0xE2, 0xAC, 0xAD, + 0x5E, 0x86, 0x6E, 0xF3, 0x09, 0x8A, 0x1F, 0x5A, 0x32, 0xBD, 0xA2, 0xEB, + 0x94, 0xF9, 0xE8, 0x5C, 0x0A, 0xEC, 0xFF, 0x98, 0xD2, 0xAF, 0x71, 0xB3, + 0xB4, 0x53, 0x9F, 0x4E, 0x87, 0xEF, 0x92, 0xBC, 0xBD, 0xEC, 0x4F, 0x32, + 0x30, 0x88, 0x4B, 0x17, 0x5E, 0x57, 0xC4, 0x53, 0xC2, 0xF6, 0x02, 0x97, + 0x8D, 0xD9, 0x62, 0x2B, 0xBF, 0x24, 0x1F, 0x62, 0x8D, 0xDF, 0xC3, 0xB8, + 0x29, 0x4B, 0x49, 0x78, 0x3C, 0x93, 0x60, 0x88, 0x22, 0xFC, 0x99, 0xDA, + 0x36, 0xC8, 0xC2, 0xA2, 0xD4, 0x2C, 0x54, 0x00, 0x67, 0x35, 0x6E, 0x73, + 0xBF, 0x02, 0x58, 0xF0, 0xA4, 0xDD, 0xE5, 0xB0, 0xA2, 0x26, 0x7A, 0xCA, + 0xE0, 0x36, 0xA5, 0x19, 0x16, 0xF5, 0xFD, 0xB7, 0xEF, 0xAE, 0x3F, 0x40, + 0xF5, 0x6D, 0x5A, 0x04, 0xFD, 0xCE, 0x34, 0xCA, 0x24, 0xDC, 0x74, 0x23, + 0x1B, 0x5D, 0x33, 0x13, 0x12, 0x5D, 0xC4, 0x01, 0x25, 0xF6, 0x30, 0xDD, + 0x02, 0x5D, 0x9F, 0xE0, 0xD5, 0x47, 0xBD, 0xB4, 0xEB, 0x1B, 0xA1, 0xBB, + 0x49, 0x49, 0xD8, 0x9F, 0x5B, 0x02, 0xF3, 0x8A, 0xE4, 0x24, 0x90, 0xE4, + 0x62, 0x4F, 0x4F, 0xC1, 0xAF, 0x8B, 0x0E, 0x74, 0x17, 0xA8, 0xD1, 0x72, + 0x88, 0x6A, 0x7A, 0x01, 0x49, 0xCC, 0xB4, 0x46, 0x79, 0xC6, 0x17, 0xB1, + 0xDA, 0x98, 0x1E, 0x07, 0x59, 0xFA, 0x75, 0x21, 0x85, 0x65, 0xDD, 0x90, + 0x56, 0xCE, 0xFB, 0xAB, 0xA5, 0x60, 0x9D, 0xC4, 0x9D, 0xF9, 0x52, 0xB0, + 0x8B, 0xBD, 0x87, 0xF9, 0x8F, 0x2B, 0x23, 0x0A, 0x23, 0x76, 0x3B, 0xF7, + 0x33, 0xE1, 0xC9, 0x00, 0xF3, 0x69, 0xF9, 0x4B, 0xA2, 0xE0, 0x4E, 0xBC, + 0x7E, 0x93, 0x39, 0x84, 0x07, 0xF7, 0x44, 0x70, 0x7E, 0xFE, 0x07, 0x5A, + 0xE5, 0xB1, 0xAC, 0xD1, 0x18, 0xCC, 0xF2, 0x35, 0xE5, 0x49, 0x49, 0x08, + 0xCA, 0x56, 0xC9, 0x3D, 0xFB, 0x0F, 0x18, 0x7D, 0x8B, 0x3B, 0xC1, 0x13, + 0xC2, 0x4D, 0x8F, 0xC9, 0x4F, 0x0E, 0x37, 0xE9, 0x1F, 0xA1, 0x0E, 0x6A, + 0xDF, 0x62, 0x2E, 0xCB, 0x35, 0x06, 0x51, 0x79, 0x2C, 0xC8, 0x25, 0x38, + 0xF4, 0xFA, 0x4B, 0xA7, 0x89, 0x5C, 0x9C, 0xD2, 0xE3, 0x0D, 0x39, 0x86, + 0x4A, 0x74, 0x7C, 0xD5, 0x59, 0x87, 0xC2, 0x3F, 0x4E, 0x0C, 0x5C, 0x52, + 0xF4, 0x3D, 0xF7, 0x52, 0x82, 0xF1, 0xEA, 0xA3, 0xAC, 0xFD, 0x49, 0x34, + 0x1A, 0x28, 0xF3, 0x41, 0x88, 0x3A, 0x13, 0xEE, 0xE8, 0xDE, 0xFF, 0x99, + 0x1D, 0x5F, 0xBA, 0xCB, 0xE8, 0x1E, 0xF2, 0xB9, 0x50, 0x60, 0xC0, 0x31, + 0xD3, 0x73, 0xE5, 0xEF, 0xBE, 0xA0, 0xED, 0x33, 0x0B, 0x74, 0xBE, 0x20, + 0x20, 0xC4, 0x67, 0x6C, 0xF0, 0x08, 0x03, 0x7A, 0x55, 0x80, 0x7F, 0x46, + 0x4E, 0x96, 0xA7, 0xF4, 0x1E, 0x3E, 0xE1, 0xF6, 0xD8, 0x09, 0xE1, 0x33, + 0x64, 0x2B, 0x63, 0xD7, 0x32, 0x5E, 0x9F, 0xF9, 0xC0, 0x7B, 0x0F, 0x78, + 0x6F, 0x97, 0xBC, 0x93, 0x9A, 0xF9, 0x9C, 0x12, 0x90, 0x78, 0x7A, 0x80, + 0x87, 0x15, 0xD7, 0x72, 0x74, 0x9C, 0x55, 0x74, 0x78, 0xB1, 0xBA, 0xE1, + 0x6E, 0x70, 0x04, 0xBA, 0x4F, 0xA0, 0xBA, 0x68, 0xC3, 0x7B, 0xFF, 0x31, + 0xF0, 0x73, 0x3D, 0x3D, 0x94, 0x2A, 0xB1, 0x0B, 0x41, 0x0E, 0xA0, 0xFE, + 0x4D, 0x88, 0x65, 0x6B, 0x79, 0x33, 0xB4, 0xD7 +}; + +static const unsigned char TA327_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA328_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x53, 0x65, 0x63, 0x74, 0x6F, 0x72, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA328_RSA_N[] = { + 0xB6, 0x22, 0x94, 0xFC, 0xA4, 0x48, 0xAF, 0xE8, 0x47, 0x6B, 0x0A, 0xFB, + 0x27, 0x76, 0xE4, 0xF2, 0x3F, 0x8A, 0x3B, 0x7A, 0x4A, 0x2C, 0x31, 0x2A, + 0x8C, 0x8D, 0xB0, 0xA9, 0xC3, 0x31, 0x6B, 0xA8, 0x77, 0x76, 0x84, 0x26, + 0xB6, 0xAC, 0x81, 0x42, 0x0D, 0x08, 0xEB, 0x55, 0x58, 0xBB, 0x7A, 0xF8, + 0xBC, 0x65, 0x7D, 0xF2, 0xA0, 0x6D, 0x8B, 0xA8, 0x47, 0xE9, 0x62, 0x76, + 0x1E, 0x11, 0xEE, 0x08, 0x14, 0xD1, 0xB2, 0x44, 0x16, 0xF4, 0xEA, 0xD0, + 0xFA, 0x1E, 0x2F, 0x5E, 0xDB, 0xCB, 0x73, 0x41, 0xAE, 0xBC, 0x00, 0xB0, + 0x4A, 0x2B, 0x40, 0xB2, 0xAC, 0xE1, 0x3B, 0x4B, 0xC2, 0x2D, 0x9D, 0xE4, + 0xA1, 0x9B, 0xEC, 0x1A, 0x3A, 0x1E, 0xF0, 0x08, 0xB3, 0xD0, 0xE4, 0x24, + 0x35, 0x07, 0x9F, 0x9C, 0xB4, 0xC9, 0x52, 0x6D, 0xDB, 0x07, 0xCA, 0x8F, + 0xB5, 0x5B, 0xF0, 0x83, 0xF3, 0x4F, 0xC7, 0x2D, 0xA5, 0xC8, 0xAD, 0xCB, + 0x95, 0x20, 0xA4, 0x31, 0x28, 0x57, 0x58, 0x5A, 0xE4, 0x8D, 0x1B, 0x9A, + 0xAB, 0x9E, 0x0D, 0x0C, 0xF2, 0x0A, 0x33, 0x39, 0x22, 0x39, 0x0A, 0x97, + 0x2E, 0xF3, 0x53, 0x77, 0xB9, 0x44, 0x45, 0xFD, 0x84, 0xCB, 0x36, 0x20, + 0x81, 0x59, 0x2D, 0x9A, 0x6F, 0x6D, 0x48, 0x48, 0x61, 0xCA, 0x4C, 0xDF, + 0x53, 0xD1, 0xAF, 0x52, 0xBC, 0x44, 0x9F, 0xAB, 0x2F, 0x6B, 0x83, 0x72, + 0xEF, 0x75, 0x80, 0xDA, 0x06, 0x33, 0x1B, 0x5D, 0xC8, 0xDA, 0x63, 0xC6, + 0x4D, 0xCD, 0xAC, 0x66, 0x31, 0xCD, 0xD1, 0xDE, 0x3E, 0x87, 0x10, 0x36, + 0xE1, 0xB9, 0xA4, 0x7A, 0xEF, 0x60, 0x50, 0xB2, 0xCB, 0xCA, 0xA6, 0x56, + 0xE0, 0x37, 0xAF, 0xAB, 0x34, 0x13, 0x39, 0x25, 0xE8, 0x39, 0x66, 0xE4, + 0x98, 0x7A, 0xAA, 0x12, 0x98, 0x9C, 0x59, 0x66, 0x86, 0x3E, 0xAD, 0xF1, + 0xB0, 0xCA, 0x3E, 0x06, 0x0F, 0x7B, 0xF0, 0x11, 0x4B, 0x37, 0xA0, 0x44, + 0x6D, 0x7B, 0xCB, 0xA8, 0x8C, 0x71, 0xF4, 0xD5, 0xB5, 0x91, 0x36, 0xCC, + 0xF0, 0x15, 0xC6, 0x2B, 0xDE, 0x51, 0x17, 0xB1, 0x97, 0x4C, 0x50, 0x3D, + 0xB1, 0x95, 0x59, 0x7C, 0x05, 0x7D, 0x2D, 0x21, 0xD5, 0x00, 0xBF, 0x01, + 0x67, 0xA2, 0x5E, 0x7B, 0xA6, 0x5C, 0xF2, 0xF7, 0x22, 0xF1, 0x90, 0x0D, + 0x93, 0xDB, 0xAA, 0x44, 0x51, 0x66, 0xCC, 0x7D, 0x76, 0x03, 0xEB, 0x6A, + 0xA8, 0x2A, 0x38, 0x19, 0x97, 0x76, 0x0D, 0x6B, 0x8A, 0x61, 0xF9, 0xBC, + 0xF6, 0xEE, 0x76, 0xFD, 0x70, 0x2B, 0xDD, 0x29, 0x3C, 0xF8, 0x0A, 0x1E, + 0x5B, 0x42, 0x1C, 0x8B, 0x56, 0x2F, 0x55, 0x1B, 0x1C, 0xA1, 0x2E, 0xB5, + 0xC7, 0x16, 0xE6, 0xF8, 0xAA, 0x3C, 0x92, 0x8E, 0x69, 0xB6, 0x01, 0xC1, + 0xB5, 0x86, 0x9D, 0x89, 0x0F, 0x0B, 0x38, 0x94, 0x54, 0xE8, 0xEA, 0xDC, + 0x9E, 0x3D, 0x25, 0xBC, 0x53, 0x26, 0xED, 0xD5, 0xAB, 0x39, 0xAA, 0xC5, + 0x40, 0x4C, 0x54, 0xAB, 0xB2, 0xB4, 0xD9, 0xD9, 0xF8, 0xD7, 0x72, 0xDB, + 0x1C, 0xBC, 0x6D, 0xBD, 0x65, 0x5F, 0xEF, 0x88, 0x35, 0x2A, 0x66, 0x2F, + 0xEE, 0xF6, 0xB3, 0x65, 0xF0, 0x33, 0x8D, 0x7C, 0x98, 0x41, 0x69, 0x46, + 0x0F, 0x43, 0x1C, 0x69, 0xFA, 0x9B, 0xB5, 0xD0, 0x61, 0x6A, 0xCD, 0xCA, + 0x4B, 0xD9, 0x4C, 0x90, 0x46, 0xAB, 0x15, 0x59, 0xA1, 0x47, 0x54, 0x29, + 0x2E, 0x83, 0x28, 0x5F, 0x1C, 0xC2, 0xA2, 0xAB, 0x72, 0x17, 0x00, 0x06, + 0x8E, 0x45, 0xEC, 0x8B, 0xE2, 0x33, 0x3D, 0x7F, 0xDA, 0x19, 0x44, 0xE4, + 0x62, 0x72, 0xC3, 0xDF, 0x22, 0xC6, 0xF2, 0x56, 0xD4, 0xDD, 0x5F, 0x95, + 0x72, 0xED, 0x6D, 0x5F, 0xF7, 0x48, 0x03, 0x5B, 0xFD, 0xC5, 0x2A, 0xA0, + 0xF6, 0x73, 0x23, 0x84, 0x10, 0x1B, 0x01, 0xE7 +}; + +static const unsigned char TA328_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA329_DN[] = { + 0x30, 0x38, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x49, 0x5A, 0x45, 0x4E, 0x50, 0x45, 0x20, 0x53, 0x2E, 0x41, + 0x2E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0A, + 0x49, 0x7A, 0x65, 0x6E, 0x70, 0x65, 0x2E, 0x63, 0x6F, 0x6D +}; + +static const unsigned char TA329_RSA_N[] = { + 0xC9, 0xD3, 0x7A, 0xCA, 0x0F, 0x1E, 0xAC, 0xA7, 0x86, 0xE8, 0x16, 0x65, + 0x6A, 0xB1, 0xC2, 0x1B, 0x45, 0x32, 0x71, 0x95, 0xD9, 0xFE, 0x10, 0x5B, + 0xCC, 0xAF, 0xE7, 0xA5, 0x79, 0x01, 0x8F, 0x89, 0xC3, 0xCA, 0xF2, 0x55, + 0x71, 0xF7, 0x77, 0xBE, 0x77, 0x94, 0xF3, 0x72, 0xA4, 0x2C, 0x44, 0xD8, + 0x9E, 0x92, 0x9B, 0x14, 0x3A, 0xA1, 0xE7, 0x24, 0x90, 0x0A, 0x0A, 0x56, + 0x8E, 0xC5, 0xD8, 0x26, 0x94, 0xE1, 0xD9, 0x48, 0xE1, 0x2D, 0x3E, 0xDA, + 0x0A, 0x72, 0xDD, 0xA3, 0x99, 0x15, 0xDA, 0x81, 0xA2, 0x87, 0xF4, 0x7B, + 0x6E, 0x26, 0x77, 0x89, 0x58, 0xAD, 0xD6, 0xEB, 0x0C, 0xB2, 0x41, 0x7A, + 0x73, 0x6E, 0x6D, 0xDB, 0x7A, 0x78, 0x41, 0xE9, 0x08, 0x88, 0x12, 0x7E, + 0x87, 0x2E, 0x66, 0x11, 0x63, 0x6C, 0x54, 0xFB, 0x3C, 0x9D, 0x72, 0xC0, + 0xBC, 0x2E, 0xFF, 0xC2, 0xB7, 0xDD, 0x0D, 0x76, 0xE3, 0x3A, 0xD7, 0xF7, + 0xB4, 0x68, 0xBE, 0xA2, 0xF5, 0xE3, 0x81, 0x6E, 0xC1, 0x46, 0x6F, 0x5D, + 0x8D, 0xE0, 0x4D, 0xC6, 0x54, 0x55, 0x89, 0x1A, 0x33, 0x31, 0x0A, 0xB1, + 0x57, 0xB9, 0xA3, 0x8A, 0x98, 0xC3, 0xEC, 0x3B, 0x34, 0xC5, 0x95, 0x41, + 0x69, 0x7E, 0x75, 0xC2, 0x3C, 0x20, 0xC5, 0x61, 0xBA, 0x51, 0x47, 0xA0, + 0x20, 0x90, 0x93, 0xA1, 0x90, 0x4B, 0xF3, 0x4E, 0x7C, 0x85, 0x45, 0x54, + 0x9A, 0xD1, 0x05, 0x26, 0x41, 0xB0, 0xB5, 0x4D, 0x1D, 0x33, 0xBE, 0xC4, + 0x03, 0xC8, 0x25, 0x7C, 0xC1, 0x70, 0xDB, 0x3B, 0xF4, 0x09, 0x2D, 0x54, + 0x27, 0x48, 0xAC, 0x2F, 0xE1, 0xC4, 0xAC, 0x3E, 0xC8, 0xCB, 0x92, 0x4C, + 0x53, 0x39, 0x37, 0x23, 0xEC, 0xD3, 0x01, 0xF9, 0xE0, 0x09, 0x44, 0x4D, + 0x4D, 0x64, 0xC0, 0xE1, 0x0D, 0x5A, 0x87, 0x22, 0xBC, 0xAD, 0x1B, 0xA3, + 0xFE, 0x26, 0xB5, 0x15, 0xF3, 0xA7, 0xFC, 0x84, 0x19, 0xE9, 0xEC, 0xA1, + 0x88, 0xB4, 0x44, 0x69, 0x84, 0x83, 0xF3, 0x89, 0xD1, 0x74, 0x06, 0xA9, + 0xCC, 0x0B, 0xD6, 0xC2, 0xDE, 0x27, 0x85, 0x50, 0x26, 0xCA, 0x17, 0xB8, + 0xC9, 0x7A, 0x87, 0x56, 0x2C, 0x1A, 0x01, 0x1E, 0x6C, 0xBE, 0x13, 0xAD, + 0x10, 0xAC, 0xB5, 0x24, 0xF5, 0x38, 0x91, 0xA1, 0xD6, 0x4B, 0xDA, 0xF1, + 0xBB, 0xD2, 0xDE, 0x47, 0xB5, 0xF1, 0xBC, 0x81, 0xF6, 0x59, 0x6B, 0xCF, + 0x19, 0x53, 0xE9, 0x8D, 0x15, 0xCB, 0x4A, 0xCB, 0xA9, 0x6F, 0x44, 0xE5, + 0x1B, 0x41, 0xCF, 0xE1, 0x86, 0xA7, 0xCA, 0xD0, 0x6A, 0x9F, 0xBC, 0x4C, + 0x8D, 0x06, 0x33, 0x5A, 0xA2, 0x85, 0xE5, 0x90, 0x35, 0xA0, 0x62, 0x5C, + 0x16, 0x4E, 0xF0, 0xE3, 0xA2, 0xFA, 0x03, 0x1A, 0xB4, 0x2C, 0x71, 0xB3, + 0x58, 0x2C, 0xDE, 0x7B, 0x0B, 0xDB, 0x1A, 0x0F, 0xEB, 0xDE, 0x21, 0x1F, + 0x06, 0x77, 0x06, 0x03, 0xB0, 0xC9, 0xEF, 0x99, 0xFC, 0xC0, 0xB9, 0x4F, + 0x0B, 0x86, 0x28, 0xFE, 0xD2, 0xB9, 0xEA, 0xE3, 0xDA, 0xA5, 0xC3, 0x47, + 0x69, 0x12, 0xE0, 0xDB, 0xF0, 0xF6, 0x19, 0x8B, 0xED, 0x7B, 0x70, 0xD7, + 0x02, 0xD6, 0xED, 0x87, 0x18, 0x28, 0x2C, 0x04, 0x24, 0x4C, 0x77, 0xE4, + 0x48, 0x8A, 0x1A, 0xC6, 0x3B, 0x9A, 0xD4, 0x0F, 0xCA, 0xFA, 0x75, 0xD2, + 0x01, 0x40, 0x5A, 0x8D, 0x79, 0xBF, 0x8B, 0xCF, 0x4B, 0xCF, 0xAA, 0x16, + 0xC1, 0x95, 0xE4, 0xAD, 0x4C, 0x8A, 0x3E, 0x17, 0x91, 0xD4, 0xB1, 0x62, + 0xE5, 0x82, 0xE5, 0x80, 0x04, 0xA4, 0x03, 0x7E, 0x8D, 0xBF, 0xDA, 0x7F, + 0xA2, 0x0F, 0x97, 0x4F, 0x0C, 0xD3, 0x0D, 0xFB, 0xD7, 0xD1, 0xE5, 0x72, + 0x7E, 0x1C, 0xC8, 0x77, 0xFF, 0x5B, 0x9A, 0x0F, 0xB7, 0xAE, 0x05, 0x46, + 0xE5, 0xF1, 0xA8, 0x16, 0xEC, 0x47, 0xA4, 0x17 +}; + +static const unsigned char TA329_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA330_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x65, 0x2D, 0x53, 0x7A, 0x69, + 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x32, 0x30, 0x30, 0x39, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x65, 0x2D, 0x73, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x2E, 0x68, + 0x75 +}; + +static const unsigned char TA330_RSA_N[] = { + 0xE9, 0xF8, 0x8F, 0xF3, 0x63, 0xAD, 0xDA, 0x86, 0xD8, 0xA7, 0xE0, 0x42, + 0xFB, 0xCF, 0x91, 0xDE, 0xA6, 0x26, 0xF8, 0x99, 0xA5, 0x63, 0x70, 0xAD, + 0x9B, 0xAE, 0xCA, 0x33, 0x40, 0x7D, 0x6D, 0x96, 0x6E, 0xA1, 0x0E, 0x44, + 0xEE, 0xE1, 0x13, 0x9D, 0x94, 0x42, 0x52, 0x9A, 0xBD, 0x75, 0x85, 0x74, + 0x2C, 0xA8, 0x0E, 0x1D, 0x93, 0xB6, 0x18, 0xB7, 0x8C, 0x2C, 0xA8, 0xCF, + 0xFB, 0x5C, 0x71, 0xB9, 0xDA, 0xEC, 0xFE, 0xE8, 0x7E, 0x8F, 0xE4, 0x2F, + 0x1D, 0xB2, 0xA8, 0x75, 0x87, 0xD8, 0xB7, 0xA1, 0xE5, 0x3B, 0xCF, 0x99, + 0x4A, 0x46, 0xD0, 0x83, 0x19, 0x7D, 0xC0, 0xA1, 0x12, 0x1C, 0x95, 0x6D, + 0x4A, 0xF4, 0xD8, 0xC7, 0xA5, 0x4D, 0x33, 0x2E, 0x85, 0x39, 0x40, 0x75, + 0x7E, 0x14, 0x7C, 0x80, 0x12, 0x98, 0x50, 0xC7, 0x41, 0x67, 0xB8, 0xA0, + 0x80, 0x61, 0x54, 0xA6, 0x6C, 0x4E, 0x1F, 0xE0, 0x9D, 0x0E, 0x07, 0xE9, + 0xC9, 0xBA, 0x33, 0xE7, 0xFE, 0xC0, 0x55, 0x28, 0x2C, 0x02, 0x80, 0xA7, + 0x19, 0xF5, 0x9E, 0xDC, 0x55, 0x53, 0x03, 0x97, 0x7B, 0x07, 0x48, 0xFF, + 0x99, 0xFB, 0x37, 0x8A, 0x24, 0xC4, 0x59, 0xCC, 0x50, 0x10, 0x63, 0x8E, + 0xAA, 0xA9, 0x1A, 0xB0, 0x84, 0x1A, 0x86, 0xF9, 0x5F, 0xBB, 0xB1, 0x50, + 0x6E, 0xA4, 0xD1, 0x0A, 0xCC, 0xD5, 0x71, 0x7E, 0x1F, 0xA7, 0x1B, 0x7C, + 0xF5, 0x53, 0x6E, 0x22, 0x5F, 0xCB, 0x2B, 0xE6, 0xD4, 0x7C, 0x5D, 0xAE, + 0xD6, 0xC2, 0xC6, 0x4C, 0xE5, 0x05, 0x01, 0xD9, 0xED, 0x57, 0xFC, 0xC1, + 0x23, 0x79, 0xFC, 0xFA, 0xC8, 0x24, 0x83, 0x95, 0xF3, 0xB5, 0x6A, 0x51, + 0x01, 0xD0, 0x77, 0xD6, 0xE9, 0x12, 0xA1, 0xF9, 0x1A, 0x83, 0xFB, 0x82, + 0x1B, 0xB9, 0xB0, 0x97, 0xF4, 0x76, 0x06, 0x33, 0x43, 0x49, 0xA0, 0xFF, + 0x0B, 0xB5, 0xFA, 0xB5 +}; + +static const unsigned char TA330_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA331_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA331_EC_Q[] = { + 0x04, 0xD4, 0xBC, 0x3D, 0x02, 0x42, 0x75, 0x41, 0x13, 0x23, 0xCD, 0x80, + 0x04, 0x86, 0x02, 0x51, 0x2F, 0x6A, 0xA8, 0x81, 0x62, 0x0B, 0x65, 0xCC, + 0xF6, 0xCA, 0x9D, 0x1E, 0x6F, 0x4A, 0x66, 0x51, 0xA2, 0x03, 0xD9, 0x9D, + 0x91, 0xFA, 0xB6, 0x16, 0xB1, 0x8C, 0x6E, 0xDE, 0x7C, 0xCD, 0xDB, 0x79, + 0xA6, 0x2F, 0xCE, 0xBB, 0xCE, 0x71, 0x2F, 0xE5, 0xA5, 0xAB, 0x28, 0xEC, + 0x63, 0x04, 0x66, 0x99, 0xF8, 0xFA, 0xF2, 0x93, 0x10, 0x05, 0xE1, 0x81, + 0x28, 0x42, 0xE3, 0xC6, 0x68, 0xF4, 0xE6, 0x1B, 0x84, 0x60, 0x4A, 0x89, + 0xAF, 0xED, 0x79, 0x0F, 0x3B, 0xCE, 0xF1, 0xF6, 0x44, 0xF5, 0x01, 0x78, + 0xC0 +}; + +static const unsigned char TA332_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA332_RSA_N[] = { + 0xCA, 0x5B, 0xBE, 0x94, 0x33, 0x8C, 0x29, 0x95, 0x91, 0x16, 0x0A, 0x95, + 0xBD, 0x47, 0x62, 0xC1, 0x89, 0xF3, 0x99, 0x36, 0xDF, 0x46, 0x90, 0xC9, + 0xA5, 0xED, 0x78, 0x6A, 0x6F, 0x47, 0x91, 0x68, 0xF8, 0x27, 0x67, 0x50, + 0x33, 0x1D, 0xA1, 0xA6, 0xFB, 0xE0, 0xE5, 0x43, 0xA3, 0x84, 0x02, 0x57, + 0x01, 0x5D, 0x9C, 0x48, 0x40, 0x82, 0x53, 0x10, 0xBC, 0xBF, 0xC7, 0x3B, + 0x68, 0x90, 0xB6, 0x82, 0x2D, 0xE5, 0xF4, 0x65, 0xD0, 0xCC, 0x6D, 0x19, + 0xCC, 0x95, 0xF9, 0x7B, 0xAC, 0x4A, 0x94, 0xAD, 0x0E, 0xDE, 0x4B, 0x43, + 0x1D, 0x87, 0x07, 0x92, 0x13, 0x90, 0x80, 0x83, 0x64, 0x35, 0x39, 0x04, + 0xFC, 0xE5, 0xE9, 0x6C, 0xB3, 0xB6, 0x1F, 0x50, 0x94, 0x38, 0x65, 0x50, + 0x5C, 0x17, 0x46, 0xB9, 0xB6, 0x85, 0xB5, 0x1C, 0xB5, 0x17, 0xE8, 0xD6, + 0x45, 0x9D, 0xD8, 0xB2, 0x26, 0xB0, 0xCA, 0xC4, 0x70, 0x4A, 0xAE, 0x60, + 0xA4, 0xDD, 0xB3, 0xD9, 0xEC, 0xFC, 0x3B, 0xD5, 0x57, 0x72, 0xBC, 0x3F, + 0xC8, 0xC9, 0xB2, 0xDE, 0x4B, 0x6B, 0xF8, 0x23, 0x6C, 0x03, 0xC0, 0x05, + 0xBD, 0x95, 0xC7, 0xCD, 0x73, 0x3B, 0x66, 0x80, 0x64, 0xE3, 0x1A, 0xAC, + 0x2E, 0xF9, 0x47, 0x05, 0xF2, 0x06, 0xB6, 0x9B, 0x73, 0xF5, 0x78, 0x33, + 0x5B, 0xC7, 0xA1, 0xFB, 0x27, 0x2A, 0xA1, 0xB4, 0x9A, 0x91, 0x8C, 0x91, + 0xD3, 0x3A, 0x82, 0x3E, 0x76, 0x40, 0xB4, 0xCD, 0x52, 0x61, 0x51, 0x70, + 0x28, 0x3F, 0xC5, 0xC5, 0x5A, 0xF2, 0xC9, 0x8C, 0x49, 0xBB, 0x14, 0x5B, + 0x4D, 0xC8, 0xFF, 0x67, 0x4D, 0x4C, 0x12, 0x96, 0xAD, 0xF5, 0xFE, 0x78, + 0xA8, 0x97, 0x87, 0xD7, 0xFD, 0x5E, 0x20, 0x80, 0xDC, 0xA1, 0x4B, 0x22, + 0xFB, 0xD4, 0x89, 0xAD, 0xBA, 0xCE, 0x47, 0x97, 0x47, 0x55, 0x7B, 0x8F, + 0x45, 0xC8, 0x67, 0x28, 0x84, 0x95, 0x1C, 0x68, 0x30, 0xEF, 0xEF, 0x49, + 0xE0, 0x35, 0x7B, 0x64, 0xE7, 0x98, 0xB0, 0x94, 0xDA, 0x4D, 0x85, 0x3B, + 0x3E, 0x55, 0xC4, 0x28, 0xAF, 0x57, 0xF3, 0x9E, 0x13, 0xDB, 0x46, 0x27, + 0x9F, 0x1E, 0xA2, 0x5E, 0x44, 0x83, 0xA4, 0xA5, 0xCA, 0xD5, 0x13, 0xB3, + 0x4B, 0x3F, 0xC4, 0xE3, 0xC2, 0xE6, 0x86, 0x61, 0xA4, 0x52, 0x30, 0xB9, + 0x7A, 0x20, 0x4F, 0x6F, 0x0F, 0x38, 0x53, 0xCB, 0x33, 0x0C, 0x13, 0x2B, + 0x8F, 0xD6, 0x9A, 0xBD, 0x2A, 0xC8, 0x2D, 0xB1, 0x1C, 0x7D, 0x4B, 0x51, + 0xCA, 0x47, 0xD1, 0x48, 0x27, 0x72, 0x5D, 0x87, 0xEB, 0xD5, 0x45, 0xE6, + 0x48, 0x65, 0x9D, 0xAF, 0x52, 0x90, 0xBA, 0x5B, 0xA2, 0x18, 0x65, 0x57, + 0x12, 0x9F, 0x68, 0xB9, 0xD4, 0x15, 0x6B, 0x94, 0xC4, 0x69, 0x22, 0x98, + 0xF4, 0x33, 0xE0, 0xED, 0xF9, 0x51, 0x8E, 0x41, 0x50, 0xC9, 0x34, 0x4F, + 0x76, 0x90, 0xAC, 0xFC, 0x38, 0xC1, 0xD8, 0xE1, 0x7B, 0xB9, 0xE3, 0xE3, + 0x94, 0xE1, 0x46, 0x69, 0xCB, 0x0E, 0x0A, 0x50, 0x6B, 0x13, 0xBA, 0xAC, + 0x0F, 0x37, 0x5A, 0xB7, 0x12, 0xB5, 0x90, 0x81, 0x1E, 0x56, 0xAE, 0x57, + 0x22, 0x86, 0xD9, 0xC9, 0xD2, 0xD1, 0xD7, 0x51, 0xE3, 0xAB, 0x3B, 0xC6, + 0x55, 0xFD, 0x1E, 0x0E, 0xD3, 0x74, 0x0A, 0xD1, 0xDA, 0xAA, 0xEA, 0x69, + 0xB8, 0x97, 0x28, 0x8F, 0x48, 0xC4, 0x07, 0xF8, 0x52, 0x43, 0x3A, 0xF4, + 0xCA, 0x55, 0x35, 0x2C, 0xB0, 0xA6, 0x6A, 0xC0, 0x9C, 0xF9, 0xF2, 0x81, + 0xE1, 0x12, 0x6A, 0xC0, 0x45, 0xD9, 0x67, 0xB3, 0xCE, 0xFF, 0x23, 0xA2, + 0x89, 0x0A, 0x54, 0xD4, 0x14, 0xB9, 0x2A, 0xA8, 0xD7, 0xEC, 0xF9, 0xAB, + 0xCD, 0x25, 0x58, 0x32, 0x79, 0x8F, 0x90, 0x5B, 0x98, 0x39, 0xC4, 0x08, + 0x06, 0xC1, 0xAC, 0x7F, 0x0E, 0x3D, 0x00, 0xA5 +}; + +static const unsigned char TA332_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA333_DN[] = { + 0x30, 0x69, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4B, 0x52, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, 0x42, 0x55, 0x53, 0x49, + 0x4E, 0x45, 0x53, 0x53, 0x20, 0x50, 0x4C, 0x41, 0x54, 0x46, 0x4F, 0x52, + 0x4D, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA333_RSA_N[] = { + 0xB6, 0xD4, 0xF1, 0x93, 0x5C, 0xB5, 0x40, 0x89, 0x0A, 0xAB, 0x0D, 0x90, + 0x5B, 0x50, 0x63, 0xAE, 0x90, 0x94, 0x74, 0x17, 0x45, 0x72, 0xD6, 0x7B, + 0x65, 0x5A, 0x29, 0x4B, 0xA7, 0x56, 0xA0, 0x4B, 0xB8, 0x2F, 0x42, 0x75, + 0xE9, 0xD9, 0x7B, 0x24, 0x5A, 0x31, 0x65, 0xAB, 0x17, 0x17, 0xD1, 0x33, + 0x3A, 0xD9, 0x11, 0xDC, 0x40, 0x36, 0x87, 0xDF, 0xC7, 0x6A, 0xE9, 0x26, + 0x5E, 0x59, 0x8A, 0x77, 0xE3, 0xE8, 0x48, 0x9C, 0x31, 0x16, 0xFA, 0x3E, + 0x91, 0xB1, 0xCA, 0xC9, 0xA3, 0xE2, 0x9F, 0xCE, 0x21, 0x53, 0xA3, 0x02, + 0x36, 0x30, 0xCB, 0x52, 0x02, 0xE5, 0xDA, 0x32, 0x5D, 0xC3, 0xC5, 0xE6, + 0xF9, 0xEE, 0x11, 0xC7, 0x8B, 0xC9, 0x44, 0x1E, 0x84, 0x93, 0x18, 0x4A, + 0xB4, 0x9F, 0xE5, 0x12, 0x64, 0x69, 0xD0, 0x26, 0x85, 0x62, 0x01, 0xB6, + 0xC9, 0x02, 0x1D, 0xBE, 0x83, 0x51, 0xBB, 0x5C, 0xDA, 0xF8, 0xAD, 0x15, + 0x6A, 0x99, 0xF7, 0x92, 0x54, 0xF7, 0x34, 0x5B, 0xE9, 0xBF, 0xEA, 0x29, + 0x81, 0x12, 0xD4, 0x53, 0x91, 0x96, 0xB3, 0x91, 0x5A, 0xDD, 0xFE, 0x90, + 0x73, 0x28, 0xFB, 0x30, 0x46, 0xB5, 0xCA, 0x08, 0x07, 0xC7, 0x71, 0x72, + 0xC9, 0x66, 0xD3, 0x34, 0x97, 0xF6, 0x8C, 0xF4, 0x18, 0x4A, 0xE1, 0xD0, + 0x3D, 0x5A, 0x45, 0xB6, 0x69, 0xA7, 0x29, 0xFB, 0x23, 0xCE, 0x88, 0xD8, + 0x12, 0x9C, 0x00, 0x48, 0xA8, 0xA6, 0x0F, 0xB3, 0x3B, 0x92, 0x8D, 0x71, + 0x0E, 0x74, 0xC5, 0x8B, 0xC8, 0x4C, 0xF9, 0xF4, 0x9B, 0x8E, 0xB8, 0x3C, + 0x69, 0xED, 0x6F, 0x3B, 0x50, 0x2F, 0x58, 0xED, 0xC4, 0xB0, 0xD0, 0x1C, + 0x1B, 0x6A, 0x0C, 0xE2, 0xBC, 0x44, 0xAA, 0xD8, 0xCD, 0x14, 0x5D, 0x94, + 0x78, 0x61, 0xBF, 0x0E, 0x6E, 0xDA, 0x2A, 0xBC, 0x2F, 0x0C, 0x0B, 0x71, + 0xA6, 0xB3, 0x16, 0x3F, 0x9C, 0xE6, 0xF9, 0xCC, 0x9F, 0x53, 0x35, 0xE2, + 0x03, 0xA0, 0xA0, 0x18, 0xBF, 0xBB, 0xF1, 0xBE, 0xF4, 0xD6, 0x8C, 0x87, + 0x0D, 0x42, 0xF7, 0x06, 0xB9, 0xF1, 0x6D, 0xED, 0x04, 0x94, 0xA8, 0xFE, + 0xB6, 0xD3, 0x06, 0xC6, 0x40, 0x61, 0xDF, 0x9D, 0x9D, 0xF3, 0x54, 0x76, + 0xCE, 0x53, 0x3A, 0x01, 0xA6, 0x92, 0x41, 0xEC, 0x04, 0xA3, 0x8F, 0x0D, + 0xA2, 0xD5, 0x09, 0xCA, 0xD6, 0xCB, 0x9A, 0xF1, 0xEF, 0x43, 0x5D, 0xC0, + 0xAB, 0xA5, 0x41, 0xCF, 0x5C, 0x53, 0x70, 0x70, 0xC9, 0x88, 0xA6, 0x2D, + 0xD4, 0x6B, 0x61, 0x73, 0x50, 0x26, 0x86, 0x61, 0x0E, 0x5F, 0x1B, 0xC2, + 0x2B, 0xE2, 0x8C, 0xD5, 0xBB, 0x9D, 0xC1, 0x03, 0x42, 0xBA, 0x94, 0xDA, + 0x5F, 0xA9, 0xB0, 0xCA, 0xCC, 0x4D, 0x0A, 0xEF, 0x47, 0x69, 0x03, 0x2F, + 0x22, 0xFB, 0xF1, 0x28, 0xCE, 0xBF, 0x5D, 0x50, 0x65, 0xA8, 0x90, 0x6D, + 0xB3, 0x74, 0xB0, 0x08, 0xC7, 0xAC, 0xA8, 0xD1, 0xEB, 0x3E, 0x9C, 0xFC, + 0x5D, 0x1A, 0x83, 0x2E, 0x2B, 0xCB, 0xB5, 0xF3, 0x44, 0x9D, 0x3A, 0xA7, + 0x17, 0x61, 0x96, 0xA2, 0x71, 0xD3, 0x70, 0x96, 0x15, 0x4D, 0xB7, 0x4C, + 0x73, 0xEE, 0x19, 0x5C, 0xC5, 0x5B, 0x3E, 0x41, 0xFE, 0xAC, 0x75, 0x60, + 0x3B, 0x1B, 0x63, 0xCE, 0x00, 0xDD, 0xDA, 0x08, 0x90, 0x62, 0xB4, 0xE5, + 0x2D, 0xEE, 0x48, 0xA7, 0x6B, 0x17, 0x99, 0x54, 0xBE, 0x87, 0x4A, 0xE3, + 0xA9, 0x5E, 0x04, 0x4C, 0xEB, 0x10, 0x6D, 0x54, 0xD6, 0xEF, 0xF1, 0xE8, + 0xF2, 0x62, 0x16, 0xCB, 0x80, 0x6B, 0xED, 0x3D, 0xED, 0xF5, 0x1F, 0x30, + 0xA5, 0xAE, 0x4B, 0xC9, 0x13, 0xED, 0x8A, 0x01, 0x01, 0xC9, 0xB8, 0x51, + 0x58, 0xC0, 0x66, 0x3A, 0xB1, 0x66, 0x4B, 0xC4, 0xD5, 0x31, 0x02, 0x62, + 0xE9, 0x74, 0x84, 0x0C, 0xDB, 0x4D, 0x46, 0x2D +}; + +static const unsigned char TA333_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA334_DN[] = { + 0x30, 0x81, 0xA7, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x4E, 0x65, + 0x74, 0x4C, 0x6F, 0x63, 0x6B, 0x20, 0x4B, 0x66, 0x74, 0x2E, 0x31, 0x37, + 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x2E, 0x54, 0x61, 0x6E, + 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, 0x6E, 0x79, 0x6B, + 0x69, 0x61, 0x64, 0xC3, 0xB3, 0x6B, 0x20, 0x28, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x29, 0x31, 0x35, 0x30, 0x33, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x2C, 0x4E, 0x65, 0x74, 0x4C, 0x6F, 0x63, + 0x6B, 0x20, 0x41, 0x72, 0x61, 0x6E, 0x79, 0x20, 0x28, 0x43, 0x6C, 0x61, + 0x73, 0x73, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x29, 0x20, 0x46, 0xC5, 0x91, + 0x74, 0x61, 0x6E, 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, + 0x6E, 0x79 +}; + +static const unsigned char TA334_RSA_N[] = { + 0xC4, 0x24, 0x5E, 0x73, 0xBE, 0x4B, 0x6D, 0x14, 0xC3, 0xA1, 0xF4, 0xE3, + 0x97, 0x90, 0x6E, 0xD2, 0x30, 0x45, 0x1E, 0x3C, 0xEE, 0x67, 0xD9, 0x64, + 0xE0, 0x1A, 0x8A, 0x7F, 0xCA, 0x30, 0xCA, 0x83, 0xE3, 0x20, 0xC1, 0xE3, + 0xF4, 0x3A, 0xD3, 0x94, 0x5F, 0x1A, 0x7C, 0x5B, 0x6D, 0xBF, 0x30, 0x4F, + 0x84, 0x27, 0xF6, 0x9F, 0x1F, 0x49, 0xBC, 0xC6, 0x99, 0x0A, 0x90, 0xF2, + 0x0F, 0xF5, 0x7F, 0x43, 0x84, 0x37, 0x63, 0x51, 0x8B, 0x7A, 0xA5, 0x70, + 0xFC, 0x7A, 0x58, 0xCD, 0x8E, 0x9B, 0xED, 0xC3, 0x46, 0x6C, 0x84, 0x70, + 0x5D, 0xDA, 0xF3, 0x01, 0x90, 0x23, 0xFC, 0x4E, 0x30, 0xA9, 0x7E, 0xE1, + 0x27, 0x63, 0xE7, 0xED, 0x64, 0x3C, 0xA0, 0xB8, 0xC9, 0x33, 0x63, 0xFE, + 0x16, 0x90, 0xFF, 0xB0, 0xB8, 0xFD, 0xD7, 0xA8, 0xC0, 0xC0, 0x94, 0x43, + 0x0B, 0xB6, 0xD5, 0x59, 0xA6, 0x9E, 0x56, 0xD0, 0x24, 0x1F, 0x70, 0x79, + 0xAF, 0xDB, 0x39, 0x54, 0x0D, 0x65, 0x75, 0xD9, 0x15, 0x41, 0x94, 0x01, + 0xAF, 0x5E, 0xEC, 0xF6, 0x8D, 0xF1, 0xFF, 0xAD, 0x64, 0xFE, 0x20, 0x9A, + 0xD7, 0x5C, 0xEB, 0xFE, 0xA6, 0x1F, 0x08, 0x64, 0xA3, 0x8B, 0x76, 0x55, + 0xAD, 0x1E, 0x3B, 0x28, 0x60, 0x2E, 0x87, 0x25, 0xE8, 0xAA, 0xAF, 0x1F, + 0xC6, 0x64, 0x46, 0x20, 0xB7, 0x70, 0x7F, 0x3C, 0xDE, 0x48, 0xDB, 0x96, + 0x53, 0xB7, 0x39, 0x77, 0xE4, 0x1A, 0xE2, 0xC7, 0x16, 0x84, 0x76, 0x97, + 0x5B, 0x2F, 0xBB, 0x19, 0x15, 0x85, 0xF8, 0x69, 0x85, 0xF5, 0x99, 0xA7, + 0xA9, 0xF2, 0x34, 0xA7, 0xA9, 0xB6, 0xA6, 0x03, 0xFC, 0x6F, 0x86, 0x3D, + 0x54, 0x7C, 0x76, 0x04, 0x9B, 0x6B, 0xF9, 0x40, 0x5D, 0x00, 0x34, 0xC7, + 0x2E, 0x99, 0x75, 0x9D, 0xE5, 0x88, 0x03, 0xAA, 0x4D, 0xF8, 0x03, 0xD2, + 0x42, 0x76, 0xC0, 0x1B +}; + +static const unsigned char TA334_RSA_E[] = { + 0xA8, 0x8B +}; + +static const unsigned char TA335_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x42, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA335_RSA_N[] = { + 0xD8, 0x17, 0xB7, 0x1C, 0x4A, 0x24, 0x2A, 0xD6, 0x97, 0xB1, 0xCA, 0xE2, + 0x1E, 0xFB, 0x7D, 0x38, 0xEF, 0x98, 0xF5, 0xB2, 0x39, 0x98, 0x4E, 0x27, + 0xB8, 0x11, 0x5D, 0x7B, 0xD2, 0x25, 0x94, 0x88, 0x82, 0x15, 0x26, 0x6A, + 0x1B, 0x31, 0xBB, 0xA8, 0x5B, 0x21, 0x21, 0x2B, 0xD8, 0x0F, 0x4E, 0x9F, + 0x5A, 0xF1, 0xB1, 0x5A, 0xE4, 0x79, 0xD6, 0x32, 0x23, 0x2B, 0xE1, 0x53, + 0xCC, 0x99, 0x45, 0x5C, 0x7B, 0x4F, 0xAD, 0xBC, 0xBF, 0x87, 0x4A, 0x0B, + 0x4B, 0x97, 0x5A, 0xA8, 0xF6, 0x48, 0xEC, 0x7D, 0x7B, 0x0D, 0xCD, 0x21, + 0x06, 0xDF, 0x9E, 0x15, 0xFD, 0x41, 0x8A, 0x48, 0xB7, 0x20, 0xF4, 0xA1, + 0x7A, 0x1B, 0x57, 0xD4, 0x5D, 0x50, 0xFF, 0xBA, 0x67, 0xD8, 0x23, 0x99, + 0x1F, 0xC8, 0x3F, 0xE3, 0xDE, 0xFF, 0x6F, 0x5B, 0x77, 0xB1, 0x6B, 0x6E, + 0xB8, 0xC9, 0x64, 0xF7, 0xE1, 0xCA, 0x41, 0x46, 0x0E, 0x29, 0x71, 0xD0, + 0xB9, 0x23, 0xFC, 0xC9, 0x81, 0x5F, 0x4E, 0xF7, 0x6F, 0xDF, 0xBF, 0x84, + 0xAD, 0x73, 0x64, 0xBB, 0xB7, 0x42, 0x8E, 0x69, 0xF6, 0xD4, 0x76, 0x1D, + 0x7E, 0x9D, 0xA7, 0xB8, 0x57, 0x8A, 0x51, 0x67, 0x72, 0xD7, 0xD4, 0xA8, + 0xB8, 0x95, 0x54, 0x40, 0x73, 0x03, 0xF6, 0xEA, 0xF4, 0xEB, 0xFE, 0x28, + 0x42, 0x77, 0x3F, 0x9D, 0x23, 0x1B, 0xB2, 0xB6, 0x3D, 0x80, 0x14, 0x07, + 0x4C, 0x2E, 0x4F, 0xF7, 0xD5, 0x0A, 0x16, 0x0D, 0xBD, 0x66, 0x43, 0x37, + 0x7E, 0x23, 0x43, 0x79, 0xC3, 0x40, 0x86, 0xF5, 0x4C, 0x29, 0xDA, 0x8E, + 0x9A, 0xAD, 0x0D, 0xA5, 0x04, 0x87, 0x88, 0x1E, 0x85, 0xE3, 0xE9, 0x53, + 0xD5, 0x9B, 0xC8, 0x8B, 0x03, 0x63, 0x78, 0xEB, 0xE0, 0x19, 0x4A, 0x6E, + 0xBB, 0x2F, 0x6B, 0x33, 0x64, 0x58, 0x93, 0xAD, 0x69, 0xBF, 0x8F, 0x1B, + 0xEF, 0x82, 0x48, 0xC7 +}; + +static const unsigned char TA335_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA336_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x43, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA336_EC_Q[] = { + 0x04, 0x4C, 0xE9, 0x50, 0xC0, 0xC6, 0x0F, 0x72, 0x18, 0xBC, 0xD8, 0xF1, + 0xBA, 0xB3, 0x89, 0xE2, 0x79, 0x4A, 0xA3, 0x16, 0xA7, 0x6B, 0x54, 0x24, + 0xDB, 0x51, 0xFF, 0xEA, 0xF4, 0x09, 0x24, 0xC3, 0x0B, 0x22, 0x9F, 0xCB, + 0x6A, 0x27, 0x82, 0x81, 0x0D, 0xD2, 0xC0, 0xAF, 0x31, 0xE4, 0x74, 0x82, + 0x6E, 0xCA, 0x25, 0xD9, 0x8C, 0x75, 0x9D, 0xF1, 0xDB, 0xD0, 0x9A, 0xA2, + 0x4B, 0x21, 0x7E, 0x16, 0xA7, 0x63, 0x90, 0xD2, 0x39, 0xD4, 0xB1, 0x87, + 0x78, 0x5F, 0x18, 0x96, 0x0F, 0x50, 0x1B, 0x35, 0x37, 0x0F, 0x6A, 0xC6, + 0xDC, 0xD9, 0x13, 0x4D, 0xA4, 0x8E, 0x90, 0x37, 0xE6, 0xBD, 0x5B, 0x31, + 0x91 +}; + +static const unsigned char TA337_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA337_RSA_N[] = { + 0xA0, 0xBE, 0x50, 0x10, 0x8E, 0xE9, 0xF2, 0x6C, 0x40, 0xB4, 0x04, 0x9C, + 0x85, 0xB9, 0x31, 0xCA, 0xDC, 0x2D, 0xE4, 0x11, 0xA9, 0x04, 0x3C, 0x1B, + 0x55, 0xC1, 0xE7, 0x58, 0x30, 0x1D, 0x24, 0xB4, 0xC3, 0xEF, 0x85, 0xDE, + 0x8C, 0x2C, 0xE1, 0xC1, 0x3D, 0xDF, 0x82, 0xE6, 0x4F, 0xAD, 0x47, 0x87, + 0x6C, 0xEC, 0x5B, 0x49, 0xC1, 0x4A, 0xD5, 0xBB, 0x8F, 0xEC, 0x87, 0xAC, + 0x7F, 0x82, 0x9A, 0x86, 0xEC, 0x3D, 0x03, 0x99, 0x52, 0x01, 0xD2, 0x35, + 0x9E, 0xAC, 0xDA, 0xF0, 0x53, 0xC9, 0x66, 0x3C, 0xD4, 0xAC, 0x02, 0x01, + 0xDA, 0x24, 0xD3, 0x3B, 0xA8, 0x02, 0x46, 0xAF, 0xA4, 0x1C, 0xE3, 0xF8, + 0x73, 0x58, 0x76, 0xB7, 0xF6, 0x0E, 0x90, 0x0D, 0xB5, 0xF0, 0xCF, 0xCC, + 0xFA, 0xF9, 0xC6, 0x4C, 0xE5, 0xC3, 0x86, 0x30, 0x0A, 0x8D, 0x17, 0x7E, + 0x35, 0xEB, 0xC5, 0xDF, 0xBB, 0x0E, 0x9C, 0xC0, 0x8D, 0x87, 0xE3, 0x88, + 0x38, 0x85, 0x67, 0xFA, 0x3E, 0xC7, 0xAB, 0xE0, 0x13, 0x9C, 0x05, 0x18, + 0x98, 0xCF, 0x93, 0xF5, 0xB1, 0x92, 0xB4, 0xFC, 0x23, 0xD3, 0xCF, 0xD5, + 0xC4, 0x27, 0x49, 0xE0, 0x9E, 0x3C, 0x9B, 0x08, 0xA3, 0x8B, 0x5D, 0x2A, + 0x21, 0xE0, 0xFC, 0x39, 0xAA, 0x53, 0xDA, 0x7D, 0x7E, 0xCF, 0x1A, 0x09, + 0x53, 0xBC, 0x5D, 0x05, 0x04, 0xCF, 0xA1, 0x4A, 0x8F, 0x8B, 0x76, 0x82, + 0x0D, 0xA1, 0xF8, 0xD2, 0xC7, 0x14, 0x77, 0x5B, 0x90, 0x36, 0x07, 0x81, + 0x9B, 0x3E, 0x06, 0xFA, 0x52, 0x5E, 0x63, 0xC5, 0xA6, 0x00, 0xFE, 0xA5, + 0xE9, 0x52, 0x1B, 0x52, 0xB5, 0x92, 0x39, 0x72, 0x03, 0x09, 0x62, 0xBD, + 0xB0, 0x60, 0x16, 0x6E, 0xA6, 0xDD, 0x25, 0xC2, 0x03, 0x66, 0xDD, 0xF3, + 0x04, 0xD1, 0x40, 0xE2, 0x4E, 0x8B, 0x86, 0xF4, 0x6F, 0xE5, 0x83, 0xA0, + 0x27, 0x84, 0x5E, 0x04, 0xC1, 0xF5, 0x90, 0xBD, 0x30, 0x3D, 0xC4, 0xEF, + 0xA8, 0x69, 0xBC, 0x38, 0x9B, 0xA4, 0xA4, 0x96, 0xD1, 0x62, 0xDA, 0x69, + 0xC0, 0x01, 0x96, 0xAE, 0xCB, 0xC4, 0x51, 0x34, 0xEA, 0x0C, 0xAA, 0xFF, + 0x21, 0x8E, 0x59, 0x8F, 0x4A, 0x5C, 0xE4, 0x61, 0x9A, 0xA7, 0xD2, 0xE9, + 0x2A, 0x78, 0x8D, 0x51, 0x3D, 0x3A, 0x15, 0xEE, 0xA2, 0x59, 0x8E, 0xA9, + 0x5C, 0xDE, 0xC5, 0xF9, 0x90, 0x22, 0xE5, 0x88, 0x45, 0x71, 0xDD, 0x91, + 0x99, 0x6C, 0x7A, 0x9F, 0x3D, 0x3D, 0x98, 0x7C, 0x5E, 0xF6, 0xBE, 0x16, + 0x68, 0xA0, 0x5E, 0xAE, 0x0B, 0x23, 0xFC, 0x5A, 0x0F, 0xAA, 0x22, 0x76, + 0x2D, 0xC9, 0xA1, 0x10, 0x1D, 0xE4, 0xD3, 0x44, 0x23, 0x90, 0x88, 0x9F, + 0xC6, 0x2A, 0xE6, 0xD7, 0xF5, 0x9A, 0xB3, 0x58, 0x1E, 0x2F, 0x30, 0x89, + 0x08, 0x1B, 0x54, 0xA2, 0xB5, 0x98, 0x23, 0xEC, 0x08, 0x77, 0x1C, 0x95, + 0x5D, 0x61, 0xD1, 0xCB, 0x89, 0x9C, 0x5F, 0xA2, 0x4A, 0x91, 0x9A, 0xEF, + 0x21, 0xAA, 0x49, 0x16, 0x08, 0xA8, 0xBD, 0x61, 0x28, 0x31, 0xC9, 0x74, + 0xAD, 0x85, 0xF6, 0xD9, 0xC5, 0xB1, 0x8B, 0xD1, 0xE5, 0x10, 0x32, 0x4D, + 0x5F, 0x8B, 0x20, 0x3A, 0x3C, 0x49, 0x1F, 0x33, 0x85, 0x59, 0x0D, 0xDB, + 0xCB, 0x09, 0x75, 0x43, 0x69, 0x73, 0xFB, 0x6B, 0x71, 0x7D, 0xF0, 0xDF, + 0xC4, 0x4C, 0x7D, 0xC6, 0xA3, 0x2E, 0xC8, 0x95, 0x79, 0xCB, 0x73, 0xA2, + 0x8E, 0x4E, 0x4D, 0x24, 0xFB, 0x5E, 0xE4, 0x04, 0xBE, 0x72, 0x1B, 0xA6, + 0x27, 0x2D, 0x49, 0x5A, 0x99, 0x7A, 0xD7, 0x5C, 0x09, 0x20, 0xB7, 0x7F, + 0x94, 0xB9, 0x4F, 0xF1, 0x0D, 0x1C, 0x5E, 0x88, 0x42, 0x1B, 0x11, 0xB7, + 0xE7, 0x91, 0xDB, 0x9E, 0x6C, 0xF4, 0x6A, 0xDF, 0x8C, 0x06, 0x98, 0x03, + 0xAD, 0xCC, 0x28, 0xEF, 0xA5, 0x47, 0xF3, 0x53 +}; + +static const unsigned char TA337_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA338_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA338_RSA_N[] = { + 0x9A, 0x18, 0xCA, 0x4B, 0x94, 0x0D, 0x00, 0x2D, 0xAF, 0x03, 0x29, 0x8A, + 0xF0, 0x0F, 0x81, 0xC8, 0xAE, 0x4C, 0x19, 0x85, 0x1D, 0x08, 0x9F, 0xAB, + 0x29, 0x44, 0x85, 0xF3, 0x2F, 0x81, 0xAD, 0x32, 0x1E, 0x90, 0x46, 0xBF, + 0xA3, 0x86, 0x26, 0x1A, 0x1E, 0xFE, 0x7E, 0x1C, 0x18, 0x3A, 0x5C, 0x9C, + 0x60, 0x17, 0x2A, 0x3A, 0x74, 0x83, 0x33, 0x30, 0x7D, 0x61, 0x54, 0x11, + 0xCB, 0xED, 0xAB, 0xE0, 0xE6, 0xD2, 0xA2, 0x7E, 0xF5, 0x6B, 0x6F, 0x18, + 0xB7, 0x0A, 0x0B, 0x2D, 0xFD, 0xE9, 0x3E, 0xEF, 0x0A, 0xC6, 0xB3, 0x10, + 0xE9, 0xDC, 0xC2, 0x46, 0x17, 0xF8, 0x5D, 0xFD, 0xA4, 0xDA, 0xFF, 0x9E, + 0x49, 0x5A, 0x9C, 0xE6, 0x33, 0xE6, 0x24, 0x96, 0xF7, 0x3F, 0xBA, 0x5B, + 0x2B, 0x1C, 0x7A, 0x35, 0xC2, 0xD6, 0x67, 0xFE, 0xAB, 0x66, 0x50, 0x8B, + 0x6D, 0x28, 0x60, 0x2B, 0xEF, 0xD7, 0x60, 0xC3, 0xC7, 0x93, 0xBC, 0x8D, + 0x36, 0x91, 0xF3, 0x7F, 0xF8, 0xDB, 0x11, 0x13, 0xC4, 0x9C, 0x77, 0x76, + 0xC1, 0xAE, 0xB7, 0x02, 0x6A, 0x81, 0x7A, 0xA9, 0x45, 0x83, 0xE2, 0x05, + 0xE6, 0xB9, 0x56, 0xC1, 0x94, 0x37, 0x8F, 0x48, 0x71, 0x63, 0x22, 0xEC, + 0x17, 0x65, 0x07, 0x95, 0x8A, 0x4B, 0xDF, 0x8F, 0xC6, 0x5A, 0x0A, 0xE5, + 0xB0, 0xE3, 0x5F, 0x5E, 0x6B, 0x11, 0xAB, 0x0C, 0xF9, 0x85, 0xEB, 0x44, + 0xE9, 0xF8, 0x04, 0x73, 0xF2, 0xE9, 0xFE, 0x5C, 0x98, 0x8C, 0xF5, 0x73, + 0xAF, 0x6B, 0xB4, 0x7E, 0xCD, 0xD4, 0x5C, 0x02, 0x2B, 0x4C, 0x39, 0xE1, + 0xB2, 0x95, 0x95, 0x2D, 0x42, 0x87, 0xD7, 0xD5, 0xB3, 0x90, 0x43, 0xB7, + 0x6C, 0x13, 0xF1, 0xDE, 0xDD, 0xF6, 0xC4, 0xF8, 0x89, 0x3F, 0xD1, 0x75, + 0xF5, 0x92, 0xC3, 0x91, 0xD5, 0x8A, 0x88, 0xD0, 0x90, 0xEC, 0xDC, 0x6D, + 0xDE, 0x89, 0xC2, 0x65, 0x71, 0x96, 0x8B, 0x0D, 0x03, 0xFD, 0x9C, 0xBF, + 0x5B, 0x16, 0xAC, 0x92, 0xDB, 0xEA, 0xFE, 0x79, 0x7C, 0xAD, 0xEB, 0xAF, + 0xF7, 0x16, 0xCB, 0xDB, 0xCD, 0x25, 0x2B, 0xE5, 0x1F, 0xFB, 0x9A, 0x9F, + 0xE2, 0x51, 0xCC, 0x3A, 0x53, 0x0C, 0x48, 0xE6, 0x0E, 0xBD, 0xC9, 0xB4, + 0x76, 0x06, 0x52, 0xE6, 0x11, 0x13, 0x85, 0x72, 0x63, 0x03, 0x04, 0xE0, + 0x04, 0x36, 0x2B, 0x20, 0x19, 0x02, 0xE8, 0x74, 0xA7, 0x1F, 0xB6, 0xC9, + 0x56, 0x66, 0xF0, 0x75, 0x25, 0xDC, 0x67, 0xC1, 0x0E, 0x61, 0x60, 0x88, + 0xB3, 0x3E, 0xD1, 0xA8, 0xFC, 0xA3, 0xDA, 0x1D, 0xB0, 0xD1, 0xB1, 0x23, + 0x54, 0xDF, 0x44, 0x76, 0x6D, 0xED, 0x41, 0xD8, 0xC1, 0xB2, 0x22, 0xB6, + 0x53, 0x1C, 0xDF, 0x35, 0x1D, 0xDC, 0xA1, 0x77, 0x2A, 0x31, 0xE4, 0x2D, + 0xF5, 0xE5, 0xE5, 0xDB, 0xC8, 0xE0, 0xFF, 0xE5, 0x80, 0xD7, 0x0B, 0x63, + 0xA0, 0xFF, 0x33, 0xA1, 0x0F, 0xBA, 0x2C, 0x15, 0x15, 0xEA, 0x97, 0xB3, + 0xD2, 0xA2, 0xB5, 0xBE, 0xF2, 0x8C, 0x96, 0x1E, 0x1A, 0x8F, 0x1D, 0x6C, + 0xA4, 0x61, 0x37, 0xB9, 0x86, 0x73, 0x33, 0xD7, 0x97, 0x96, 0x9E, 0x23, + 0x7D, 0x82, 0xA4, 0x4C, 0x81, 0xE2, 0xA1, 0xD1, 0xBA, 0x67, 0x5F, 0x95, + 0x07, 0xA3, 0x27, 0x11, 0xEE, 0x16, 0x10, 0x7B, 0xBC, 0x45, 0x4A, 0x4C, + 0xB2, 0x04, 0xD2, 0xAB, 0xEF, 0xD5, 0xFD, 0x0C, 0x51, 0xCE, 0x50, 0x6A, + 0x08, 0x31, 0xF9, 0x91, 0xDA, 0x0C, 0x8F, 0x64, 0x5C, 0x03, 0xC3, 0x3A, + 0x8B, 0x20, 0x3F, 0x6E, 0x8D, 0x67, 0x3D, 0x3A, 0xD6, 0xFE, 0x7D, 0x5B, + 0x88, 0xC9, 0x5E, 0xFB, 0xCC, 0x61, 0xDC, 0x8B, 0x33, 0x77, 0xD3, 0x44, + 0x32, 0x35, 0x09, 0x62, 0x04, 0x92, 0x16, 0x10, 0xD8, 0x9E, 0x27, 0x47, + 0xFB, 0x3B, 0x21, 0xE3, 0xF8, 0xEB, 0x1D, 0x5B +}; + +static const unsigned char TA338_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA339_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA339_RSA_N[] = { + 0xA1, 0xAE, 0x25, 0xB2, 0x01, 0x18, 0xDC, 0x57, 0x88, 0x3F, 0x46, 0xEB, + 0xF9, 0xAF, 0xE2, 0xEB, 0x23, 0x71, 0xE2, 0x9A, 0xD1, 0x61, 0x66, 0x21, + 0x5F, 0xAA, 0xAF, 0x27, 0x51, 0xE5, 0x6E, 0x1B, 0x16, 0xD4, 0x2D, 0x7D, + 0x50, 0xB0, 0x53, 0x77, 0xBD, 0x78, 0x3A, 0x60, 0xE2, 0x64, 0x02, 0x9B, + 0x7C, 0x86, 0x9B, 0xD6, 0x1A, 0x8E, 0xAD, 0xFF, 0x1F, 0x15, 0x7F, 0xD5, + 0x95, 0x1E, 0x12, 0xCB, 0xE6, 0x14, 0x84, 0x04, 0xC1, 0xDF, 0x36, 0xB3, + 0x16, 0x9F, 0x8A, 0xE3, 0xC9, 0xDB, 0x98, 0x34, 0xCE, 0xD8, 0x33, 0x17, + 0x28, 0x46, 0xFC, 0xA7, 0xC9, 0xF0, 0xD2, 0xB4, 0xD5, 0x4D, 0x09, 0x72, + 0x49, 0xF9, 0xF2, 0x87, 0xE3, 0xA9, 0xDA, 0x7D, 0xA1, 0x7D, 0x6B, 0xB2, + 0x3A, 0x25, 0xA9, 0x6D, 0x52, 0x44, 0xAC, 0xF8, 0xBE, 0x6E, 0xFB, 0xDC, + 0xA6, 0x73, 0x91, 0x90, 0x61, 0xA6, 0x03, 0x14, 0x20, 0xF2, 0xE7, 0x87, + 0xA3, 0x88, 0xAD, 0xAD, 0xA0, 0x8C, 0xFF, 0xA6, 0x0B, 0x25, 0x52, 0x25, + 0xE7, 0x16, 0x01, 0xD5, 0xCB, 0xB8, 0x35, 0x81, 0x0C, 0xA3, 0x3B, 0xF0, + 0xE1, 0xE1, 0xFC, 0x5A, 0x5D, 0xCE, 0x80, 0x71, 0x6D, 0xF8, 0x49, 0xAB, + 0x3E, 0x3B, 0xBA, 0xB8, 0xD7, 0x80, 0x01, 0xFB, 0xA5, 0xEB, 0x5B, 0xB3, + 0xC5, 0x5E, 0x60, 0x2A, 0x31, 0xA0, 0xAF, 0x37, 0xE8, 0x20, 0x3A, 0x9F, + 0xA8, 0x32, 0x2C, 0x0C, 0xCC, 0x09, 0x1D, 0xD3, 0x9E, 0x8E, 0x5D, 0xBC, + 0x4C, 0x98, 0xEE, 0xC5, 0x1A, 0x68, 0x7B, 0xEC, 0x53, 0xA6, 0xE9, 0x14, + 0x35, 0xA3, 0xDF, 0xCD, 0x80, 0x9F, 0x0C, 0x48, 0xFB, 0x1C, 0xF4, 0xF1, + 0xBF, 0x4A, 0xB8, 0xFA, 0xD5, 0x8C, 0x71, 0x4A, 0xC7, 0x1F, 0xAD, 0xFE, + 0x41, 0x9A, 0xB3, 0x83, 0x5D, 0xF2, 0x84, 0x56, 0xEF, 0xA5, 0x57, 0x43, + 0xCE, 0x29, 0xAD, 0x8C, 0xAB, 0x55, 0xBF, 0xC4, 0xFB, 0x5B, 0x01, 0xDD, + 0x23, 0x21, 0xA1, 0x58, 0x00, 0x8E, 0xC3, 0xD0, 0x6A, 0x13, 0xED, 0x13, + 0xE3, 0x12, 0x2B, 0x80, 0xDC, 0x67, 0xE6, 0x95, 0xB2, 0xCD, 0x1E, 0x22, + 0x6E, 0x2A, 0xF8, 0x41, 0xD4, 0xF2, 0xCA, 0x14, 0x07, 0x8D, 0x8A, 0x55, + 0x12, 0xC6, 0x69, 0xF5, 0xB8, 0x86, 0x68, 0x2F, 0x53, 0x5E, 0xB0, 0xD2, + 0xAA, 0x21, 0xC1, 0x98, 0xE6, 0x30, 0xE3, 0x67, 0x55, 0xC7, 0x9B, 0x6E, + 0xAC, 0x19, 0xA8, 0x55, 0xA6, 0x45, 0x06, 0xD0, 0x23, 0x3A, 0xDB, 0xEB, + 0x65, 0x5D, 0x2A, 0x11, 0x11, 0xF0, 0x3B, 0x4F, 0xCA, 0x6D, 0xF4, 0x34, + 0xC4, 0x71, 0xE4, 0xFF, 0x00, 0x5A, 0xF6, 0x5C, 0xAE, 0x23, 0x60, 0x85, + 0x73, 0xF1, 0xE4, 0x10, 0xB1, 0x25, 0xAE, 0xD5, 0x92, 0xBB, 0x13, 0xC1, + 0x0C, 0xE0, 0x39, 0xDA, 0xB4, 0x39, 0x57, 0xB5, 0xAB, 0x35, 0xAA, 0x72, + 0x21, 0x3B, 0x83, 0x35, 0xE7, 0x31, 0xDF, 0x7A, 0x21, 0x6E, 0xB8, 0x32, + 0x08, 0x7D, 0x1D, 0x32, 0x91, 0x15, 0x4A, 0x62, 0x72, 0xCF, 0xE3, 0x77, + 0xA1, 0xBC, 0xD5, 0x11, 0x1B, 0x76, 0x01, 0x67, 0x08, 0xE0, 0x41, 0x0B, + 0xC3, 0xEB, 0x15, 0x6E, 0xF8, 0xA4, 0x19, 0xD9, 0xA2, 0xAB, 0xAF, 0xE2, + 0x27, 0x52, 0x56, 0x2B, 0x02, 0x8A, 0x2C, 0x14, 0x24, 0xF9, 0xBF, 0x42, + 0x02, 0xBF, 0x26, 0xC8, 0xC6, 0x8F, 0xE0, 0x6E, 0x38, 0x7D, 0x53, 0x2D, + 0xE5, 0xED, 0x98, 0xB3, 0x95, 0x63, 0x68, 0x7F, 0xF9, 0x35, 0xF4, 0xDF, + 0x88, 0xC5, 0x60, 0x35, 0x92, 0xC0, 0x7C, 0x69, 0x1C, 0x61, 0x95, 0x16, + 0xD0, 0xEB, 0xDE, 0x0B, 0xAF, 0x3E, 0x04, 0x10, 0x45, 0x65, 0x58, 0x50, + 0x38, 0xAF, 0x48, 0xF2, 0x59, 0xB6, 0x16, 0xF2, 0x3C, 0x0D, 0x90, 0x02, + 0xC6, 0x70, 0x2E, 0x01, 0xAD, 0x3C, 0x15, 0xD7 +}; + +static const unsigned char TA339_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA340_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA340_RSA_N[] = { + 0xCC, 0x57, 0x42, 0x16, 0x54, 0x9C, 0xE6, 0x98, 0xD3, 0xD3, 0x4D, 0xEE, + 0xFE, 0xED, 0xC7, 0x9F, 0x43, 0x39, 0x4A, 0x65, 0xB3, 0xE8, 0x16, 0x88, + 0x34, 0xDB, 0x0D, 0x59, 0x91, 0x74, 0xCF, 0x92, 0xB8, 0x04, 0x40, 0xAD, + 0x02, 0x4B, 0x31, 0xAB, 0xBC, 0x8D, 0x91, 0x68, 0xD8, 0x20, 0x0E, 0x1A, + 0x01, 0xE2, 0x1A, 0x7B, 0x4E, 0x17, 0x5D, 0xE2, 0x8A, 0xB7, 0x3F, 0x99, + 0x1A, 0xCD, 0xEB, 0x61, 0xAB, 0xC2, 0x65, 0xA6, 0x1F, 0xB7, 0xB7, 0xBD, + 0xB7, 0x8F, 0xFC, 0xFD, 0x70, 0x8F, 0x0B, 0xA0, 0x67, 0xBE, 0x01, 0xA2, + 0x59, 0xCF, 0x71, 0xE6, 0x0F, 0x29, 0x76, 0xFF, 0xB1, 0x56, 0x79, 0x45, + 0x2B, 0x1F, 0x9E, 0x7A, 0x54, 0xE8, 0xA3, 0x29, 0x35, 0x68, 0xA4, 0x01, + 0x4F, 0x0F, 0xA4, 0x2E, 0x37, 0xEF, 0x1B, 0xBF, 0xE3, 0x8F, 0x10, 0xA8, + 0x72, 0xAB, 0x58, 0x57, 0xE7, 0x54, 0x86, 0xC8, 0xC9, 0xF3, 0x5B, 0xDA, + 0x2C, 0xDA, 0x5D, 0x8E, 0x6E, 0x3C, 0xA3, 0x3E, 0xDA, 0xFB, 0x82, 0xE5, + 0xDD, 0xF2, 0x5C, 0xB2, 0x05, 0x33, 0x6F, 0x8A, 0x36, 0xCE, 0xD0, 0x13, + 0x4E, 0xFF, 0xBF, 0x4A, 0x0C, 0x34, 0x4C, 0xA6, 0xC3, 0x21, 0xBD, 0x50, + 0x04, 0x55, 0xEB, 0xB1, 0xBB, 0x9D, 0xFB, 0x45, 0x1E, 0x64, 0x15, 0xDE, + 0x55, 0x01, 0x8C, 0x02, 0x76, 0xB5, 0xCB, 0xA1, 0x3F, 0x42, 0x69, 0xBC, + 0x2F, 0xBD, 0x68, 0x43, 0x16, 0x56, 0x89, 0x2A, 0x37, 0x61, 0x91, 0xFD, + 0xA6, 0xAE, 0x4E, 0xC0, 0xCB, 0x14, 0x65, 0x94, 0x37, 0x4B, 0x92, 0x06, + 0xEF, 0x04, 0xD0, 0xC8, 0x9C, 0x88, 0xDB, 0x0B, 0x7B, 0x81, 0xAF, 0xB1, + 0x3D, 0x2A, 0xC4, 0x65, 0x3A, 0x78, 0xB6, 0xEE, 0xDC, 0x80, 0xB1, 0xD2, + 0xD3, 0x99, 0x9C, 0x3A, 0xEE, 0x6B, 0x5A, 0x6B, 0xB3, 0x8D, 0xB7, 0xD5, + 0xCE, 0x9C, 0xC2, 0xBE, 0xA5, 0x4B, 0x2F, 0x16, 0xB1, 0x9E, 0x68, 0x3B, + 0x06, 0x6F, 0xAE, 0x7D, 0x9F, 0xF8, 0xDE, 0xEC, 0xCC, 0x29, 0xA7, 0x98, + 0xA3, 0x25, 0x43, 0x2F, 0xEF, 0xF1, 0x5F, 0x26, 0xE1, 0x88, 0x4D, 0xF8, + 0x5E, 0x6E, 0xD7, 0xD9, 0x14, 0x6E, 0x19, 0x33, 0x69, 0xA7, 0x3B, 0x84, + 0x89, 0x93, 0xC4, 0x53, 0x55, 0x13, 0xA1, 0x51, 0x78, 0x40, 0xF8, 0xB8, + 0xC9, 0xA2, 0xEE, 0x7B, 0xBA, 0x52, 0x42, 0x83, 0x9E, 0x14, 0xED, 0x05, + 0x52, 0x5A, 0x59, 0x56, 0xA7, 0x97, 0xFC, 0x9D, 0x3F, 0x0A, 0x29, 0xD8, + 0xDC, 0x4F, 0x91, 0x0E, 0x13, 0xBC, 0xDE, 0x95, 0xA4, 0xDF, 0x8B, 0x99, + 0xBE, 0xAC, 0x9B, 0x33, 0x88, 0xEF, 0xB5, 0x81, 0xAF, 0x1B, 0xC6, 0x22, + 0x53, 0xC8, 0xF6, 0xC7, 0xEE, 0x97, 0x14, 0xB0, 0xC5, 0x7C, 0x78, 0x52, + 0xC8, 0xF0, 0xCE, 0x6E, 0x77, 0x60, 0x84, 0xA6, 0xE9, 0x2A, 0x76, 0x20, + 0xED, 0x58, 0x01, 0x17, 0x30, 0x93, 0xE9, 0x1A, 0x8B, 0xE0, 0x73, 0x63, + 0xD9, 0x6A, 0x92, 0x94, 0x49, 0x4E, 0xB4, 0xAD, 0x4A, 0x85, 0xC4, 0xA3, + 0x22, 0x30, 0xFC, 0x09, 0xED, 0x68, 0x22, 0x73, 0xA6, 0x88, 0x0C, 0x55, + 0x21, 0x58, 0xC5, 0xE1, 0x3A, 0x9F, 0x2A, 0xDD, 0xCA, 0xE1, 0x90, 0xE0, + 0xD9, 0x73, 0xAB, 0x6C, 0x80, 0xB8, 0xE8, 0x0B, 0x64, 0x93, 0xA0, 0x9C, + 0x8C, 0x19, 0xFF, 0xB3, 0xD2, 0x0C, 0xEC, 0x91, 0x26, 0x87, 0x8A, 0xB3, + 0xA2, 0xE1, 0x70, 0x8F, 0x2C, 0x0A, 0xE5, 0xCD, 0x6D, 0x68, 0x51, 0xEB, + 0xDA, 0x3F, 0x05, 0x7F, 0x8B, 0x32, 0xE6, 0x13, 0x5C, 0x6B, 0xFE, 0x5F, + 0x40, 0xE2, 0x22, 0xC8, 0xB4, 0xB4, 0x64, 0x4F, 0xD6, 0xBA, 0x7D, 0x48, + 0x3E, 0xA8, 0x69, 0x0C, 0xD7, 0xBB, 0x86, 0x71, 0xC9, 0x73, 0xB8, 0x3F, + 0x3B, 0x9D, 0x25, 0x4B, 0xDA, 0xFF, 0x40, 0xEB +}; + +static const unsigned char TA340_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA341_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA341_RSA_N[] = { + 0xB3, 0xCB, 0x0E, 0x10, 0x67, 0x8E, 0xEA, 0x14, 0x97, 0xA7, 0x32, 0x2A, + 0x0A, 0x56, 0x36, 0x7F, 0x68, 0x4C, 0xC7, 0xB3, 0x6F, 0x3A, 0x23, 0x14, + 0x91, 0xFF, 0x19, 0x7F, 0xA5, 0xCA, 0xAC, 0xEE, 0xB3, 0x76, 0x9D, 0x7A, + 0xE9, 0x8B, 0x1B, 0xAB, 0x6B, 0x31, 0xDB, 0xFA, 0x0B, 0x53, 0x4C, 0xAF, + 0xC5, 0xA5, 0x1A, 0x79, 0x3C, 0x8A, 0x4C, 0xFF, 0xAC, 0xDF, 0x25, 0xDE, + 0x4E, 0xD9, 0x82, 0x32, 0x0B, 0x44, 0xDE, 0xCA, 0xDB, 0x8C, 0xAC, 0xA3, + 0x6E, 0x16, 0x83, 0x3B, 0xA6, 0x64, 0x4B, 0x32, 0x89, 0xFB, 0x16, 0x16, + 0x38, 0x7E, 0xEB, 0x43, 0xE2, 0xD3, 0x74, 0x4A, 0xC2, 0x62, 0x0A, 0x73, + 0x0A, 0xDD, 0x49, 0xB3, 0x57, 0xD2, 0xB0, 0x0A, 0x85, 0x9D, 0x71, 0x3C, + 0xDE, 0xA3, 0xCB, 0xC0, 0x32, 0xF3, 0x01, 0x39, 0x20, 0x43, 0x1B, 0x35, + 0xD1, 0x53, 0xB3, 0xB1, 0xEE, 0xC5, 0x93, 0x69, 0x82, 0x3E, 0x16, 0xB5, + 0x28, 0x46, 0xA1, 0xDE, 0xEA, 0x89, 0x09, 0xED, 0x43, 0xB8, 0x05, 0x46, + 0x8A, 0x86, 0xF5, 0x59, 0x47, 0xBE, 0x1B, 0x6F, 0x01, 0x21, 0x10, 0xB9, + 0xFD, 0xA9, 0xD2, 0x28, 0xCA, 0x10, 0x39, 0x09, 0xCA, 0x13, 0x36, 0xCF, + 0x9C, 0xAD, 0xAD, 0x40, 0x74, 0x79, 0x2B, 0x02, 0x3F, 0x34, 0xFF, 0xFA, + 0x20, 0x69, 0x7D, 0xD3, 0xEE, 0x61, 0xF5, 0xBA, 0xB3, 0xE7, 0x30, 0xD0, + 0x37, 0x23, 0x86, 0x72, 0x61, 0x45, 0x29, 0x48, 0x59, 0x68, 0x6F, 0x77, + 0xA6, 0x2E, 0x81, 0xBE, 0x07, 0x4D, 0x6F, 0xAF, 0xCE, 0xC4, 0x45, 0x13, + 0x91, 0x14, 0x70, 0x06, 0x8F, 0x1F, 0x9F, 0xF8, 0x87, 0x69, 0xB1, 0x0E, + 0xEF, 0xC3, 0x89, 0x19, 0xEB, 0xEA, 0x1C, 0x61, 0xFC, 0x7A, 0x6C, 0x8A, + 0xDC, 0xD6, 0x03, 0x0B, 0x9E, 0x26, 0xBA, 0x12, 0xDD, 0xD4, 0x54, 0x39, + 0xAB, 0x26, 0xA3, 0x33, 0xEA, 0x75, 0x81, 0xDA, 0x2D, 0xCD, 0x0F, 0x4F, + 0xE4, 0x03, 0xD1, 0xEF, 0x15, 0x97, 0x1B, 0x6B, 0x90, 0xC5, 0x02, 0x90, + 0x93, 0x66, 0x02, 0x21, 0xB1, 0x47, 0xDE, 0x8B, 0x9A, 0x4A, 0x80, 0xB9, + 0x55, 0x8F, 0xB5, 0xA2, 0x2F, 0xC0, 0xD6, 0x33, 0x67, 0xDA, 0x7E, 0xC4, + 0xA7, 0xB4, 0x04, 0x44, 0xEB, 0x47, 0xFB, 0xE6, 0x58, 0xB9, 0xF7, 0x0C, + 0xF0, 0x7B, 0x2B, 0xB1, 0xC0, 0x70, 0x29, 0xC3, 0x40, 0x62, 0x2D, 0x3B, + 0x48, 0x69, 0xDC, 0x23, 0x3C, 0x48, 0xEB, 0x7B, 0x09, 0x79, 0xA9, 0x6D, + 0xDA, 0xA8, 0x30, 0x98, 0xCF, 0x80, 0x72, 0x03, 0x88, 0xA6, 0x5B, 0x46, + 0xAE, 0x72, 0x79, 0x7C, 0x08, 0x03, 0x21, 0x65, 0xAE, 0xB7, 0xE1, 0x1C, + 0xA5, 0xB1, 0x2A, 0xA2, 0x31, 0xDE, 0x66, 0x04, 0xF7, 0xC0, 0x74, 0xE8, + 0x71, 0xDE, 0xFF, 0x3D, 0x59, 0xCC, 0x96, 0x26, 0x12, 0x8B, 0x85, 0x95, + 0x57, 0x1A, 0xAB, 0x6B, 0x75, 0x0B, 0x44, 0x3D, 0x11, 0x28, 0x3C, 0x7B, + 0x61, 0xB7, 0xE2, 0x8F, 0x67, 0x4F, 0xE5, 0xEC, 0x3C, 0x4C, 0x60, 0x80, + 0x69, 0x57, 0x38, 0x1E, 0x01, 0x5B, 0x8D, 0x55, 0xE8, 0xC7, 0xDF, 0xC0, + 0xCC, 0x77, 0x23, 0x34, 0x49, 0x75, 0x7C, 0xF6, 0x98, 0x11, 0xEB, 0x2D, + 0xDE, 0xED, 0x41, 0x2E, 0x14, 0x05, 0x02, 0x7F, 0xE0, 0xFE, 0x20, 0xEB, + 0x35, 0xE7, 0x11, 0xAC, 0x22, 0xCE, 0x57, 0x3D, 0xDE, 0xC9, 0x30, 0x6D, + 0x10, 0x03, 0x85, 0xCD, 0xF1, 0xFF, 0x8C, 0x16, 0xB5, 0xC1, 0xB2, 0x3E, + 0x88, 0x6C, 0x60, 0x7F, 0x90, 0x4F, 0x95, 0xF7, 0xF6, 0x2D, 0xAD, 0x01, + 0x39, 0x07, 0x04, 0xFA, 0x75, 0x80, 0x7D, 0xBF, 0x49, 0x50, 0xED, 0xEF, + 0xC9, 0xC4, 0x7C, 0x1C, 0xEB, 0x80, 0x7E, 0xDB, 0xB6, 0xD0, 0xDD, 0x13, + 0xFE, 0xC9, 0xD3, 0x9C, 0xD7, 0xB2, 0x97, 0xA9 +}; + +static const unsigned char TA341_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA342_DN[] = { + 0x30, 0x7F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x2B, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, 0x56, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA342_EC_Q[] = { + 0x04, 0xAA, 0x12, 0x47, 0x90, 0x98, 0x1B, 0xFB, 0xEF, 0xC3, 0x40, 0x07, + 0x83, 0x20, 0x4E, 0xF1, 0x30, 0x82, 0xA2, 0x06, 0xD1, 0xF2, 0x92, 0x86, + 0x61, 0xF2, 0xF6, 0x21, 0x68, 0xCA, 0x00, 0xC4, 0xC7, 0xEA, 0x43, 0x00, + 0x54, 0x86, 0xDC, 0xFD, 0x1F, 0xDF, 0x00, 0xB8, 0x41, 0x62, 0x5C, 0xDC, + 0x70, 0x16, 0x32, 0xDE, 0x1F, 0x99, 0xD4, 0xCC, 0xC5, 0x07, 0xC8, 0x08, + 0x1F, 0x61, 0x16, 0x07, 0x51, 0x3D, 0x7D, 0x5C, 0x07, 0x53, 0xE3, 0x35, + 0x38, 0x8C, 0xDF, 0xCD, 0x9F, 0xD9, 0x2E, 0x0D, 0x4A, 0xB6, 0x19, 0x2E, + 0x5A, 0x70, 0x5A, 0x06, 0xED, 0xBE, 0xF0, 0xA1, 0xB0, 0xCA, 0xD0, 0x09, + 0x29 +}; + +static const unsigned char TA343_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, + 0x6F, 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x2E, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, + 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA343_RSA_N[] = { + 0x8F, 0x36, 0x65, 0x40, 0xE1, 0xD6, 0x4D, 0xC0, 0xD7, 0xB4, 0xE9, 0x46, + 0xDA, 0x6B, 0xEA, 0x33, 0x47, 0xCD, 0x4C, 0xF9, 0x7D, 0x7D, 0xBE, 0xBD, + 0x2D, 0x3D, 0xF0, 0xDB, 0x78, 0xE1, 0x86, 0xA5, 0xD9, 0xBA, 0x09, 0x57, + 0x68, 0xED, 0x57, 0x3E, 0xA0, 0xD0, 0x08, 0x41, 0x83, 0xE7, 0x28, 0x41, + 0x24, 0x1F, 0xE3, 0x72, 0x15, 0xD0, 0x01, 0x1A, 0xFB, 0x5E, 0x70, 0x23, + 0xB2, 0xCB, 0x9F, 0x39, 0xE3, 0xCF, 0xC5, 0x4E, 0xC6, 0x92, 0x6D, 0x26, + 0xC6, 0x7B, 0xBB, 0xB3, 0xDA, 0x27, 0x9D, 0x0A, 0x86, 0xE9, 0x81, 0x37, + 0x05, 0xFE, 0xF0, 0x71, 0x71, 0xEC, 0xC3, 0x1C, 0xE9, 0x63, 0xA2, 0x17, + 0x14, 0x9D, 0xEF, 0x1B, 0x67, 0xD3, 0x85, 0x55, 0x02, 0x02, 0xD6, 0x49, + 0xC9, 0xCC, 0x5A, 0xE1, 0xB1, 0xF7, 0x6F, 0x32, 0x9F, 0xC9, 0xD4, 0x3B, + 0x88, 0x41, 0xA8, 0x9C, 0xBD, 0xCB, 0xAB, 0xDB, 0x6D, 0x7B, 0x09, 0x1F, + 0xA2, 0x4C, 0x72, 0x90, 0xDA, 0x2B, 0x08, 0xFC, 0xCF, 0x3C, 0x54, 0xCE, + 0x67, 0x0F, 0xA8, 0xCF, 0x5D, 0x96, 0x19, 0x0B, 0xC4, 0xE3, 0x72, 0xEB, + 0xAD, 0xD1, 0x7D, 0x1D, 0x27, 0xEF, 0x92, 0xEB, 0x10, 0xBF, 0x5B, 0xEB, + 0x3B, 0xAF, 0xCF, 0x80, 0xDD, 0xC1, 0xD2, 0x96, 0x04, 0x5B, 0x7A, 0x7E, + 0xA4, 0xA9, 0x3C, 0x38, 0x76, 0xA4, 0x62, 0x8E, 0xA0, 0x39, 0x5E, 0xEA, + 0x77, 0xCF, 0x5D, 0x00, 0x59, 0x8F, 0x66, 0x2C, 0x3E, 0x07, 0xA2, 0xA3, + 0x05, 0x26, 0x11, 0x69, 0x97, 0xEA, 0x85, 0xB7, 0x0F, 0x96, 0x0B, 0x4B, + 0xC8, 0x40, 0xE1, 0x50, 0xBA, 0x2E, 0x8A, 0xCB, 0xF7, 0x0F, 0x9A, 0x22, + 0xE7, 0x7F, 0x9A, 0x37, 0x13, 0xCD, 0xF2, 0x4D, 0x13, 0x6B, 0x21, 0xD1, + 0xC0, 0xCC, 0x22, 0xF2, 0xA1, 0x46, 0xF6, 0x44, 0x69, 0x9C, 0xCA, 0x61, + 0x35, 0x07, 0x00, 0x6F, 0xD6, 0x61, 0x08, 0x11, 0xEA, 0xBA, 0xB8, 0xF6, + 0xE9, 0xB3, 0x60, 0xE5, 0x4D, 0xB9, 0xEC, 0x9F, 0x14, 0x66, 0xC9, 0x57, + 0x58, 0xDB, 0xCD, 0x87, 0x69, 0xF8, 0x8A, 0x86, 0x12, 0x03, 0x47, 0xBF, + 0x66, 0x13, 0x76, 0xAC, 0x77, 0x7D, 0x34, 0x24, 0x85, 0x83, 0xCD, 0xD7, + 0xAA, 0x9C, 0x90, 0x1A, 0x9F, 0x21, 0x2C, 0x7F, 0x78, 0xB7, 0x64, 0xB8, + 0xD8, 0xE8, 0xA6, 0xF4, 0x78, 0xB3, 0x55, 0xCB, 0x84, 0xD2, 0x32, 0xC4, + 0x78, 0xAE, 0xA3, 0x8F, 0x61, 0xDD, 0xCE, 0x08, 0x53, 0xAD, 0xEC, 0x88, + 0xFC, 0x15, 0xE4, 0x9A, 0x0D, 0xE6, 0x9F, 0x1A, 0x77, 0xCE, 0x4C, 0x8F, + 0xB8, 0x14, 0x15, 0x3D, 0x62, 0x9C, 0x86, 0x38, 0x06, 0x00, 0x66, 0x12, + 0xE4, 0x59, 0x76, 0x5A, 0x53, 0xC0, 0x02, 0x98, 0xA2, 0x10, 0x2B, 0x68, + 0x44, 0x7B, 0x8E, 0x79, 0xCE, 0x33, 0x4A, 0x76, 0xAA, 0x5B, 0x81, 0x16, + 0x1B, 0xB5, 0x8A, 0xD8, 0xD0, 0x00, 0x7B, 0x5E, 0x62, 0xB4, 0x09, 0xD6, + 0x86, 0x63, 0x0E, 0xA6, 0x05, 0x95, 0x49, 0xBA, 0x28, 0x8B, 0x88, 0x93, + 0xB2, 0x34, 0x1C, 0xD8, 0xA4, 0x55, 0x6E, 0xB7, 0x1C, 0xD0, 0xDE, 0x99, + 0x55, 0x3B, 0x23, 0xF4, 0x22, 0xE0, 0xF9, 0x29, 0x66, 0x26, 0xEC, 0x20, + 0x50, 0x77, 0xDB, 0x4A, 0x0B, 0x8F, 0xBE, 0xE5, 0x02, 0x60, 0x70, 0x41, + 0x5E, 0xD4, 0xAE, 0x50, 0x39, 0x22, 0x14, 0x26, 0xCB, 0xB2, 0x3B, 0x73, + 0x74, 0x55, 0x47, 0x07, 0x79, 0x81, 0x39, 0xA8, 0x30, 0x13, 0x44, 0xE5, + 0x04, 0x8A, 0xAE, 0x96, 0x13, 0x25, 0x42, 0x0F, 0xB9, 0x53, 0xC4, 0x9B, + 0xFC, 0xCD, 0xE4, 0x1C, 0xDE, 0x3C, 0xFA, 0xAB, 0xD6, 0x06, 0x4A, 0x1F, + 0x67, 0xA6, 0x98, 0x30, 0x1C, 0xDD, 0x2C, 0xDB, 0xDC, 0x18, 0x95, 0x57, + 0x66, 0xC6, 0xFF, 0x5C, 0x8B, 0x56, 0xF5, 0x77 +}; + +static const unsigned char TA343_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA344_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA344_EC_Q[] = { + 0x04, 0x45, 0x6E, 0xA9, 0x50, 0xC4, 0xA6, 0x23, 0x36, 0x9E, 0x5F, 0x28, + 0x8D, 0x17, 0xCB, 0x96, 0x22, 0x64, 0x3F, 0xDC, 0x7A, 0x8E, 0x1D, 0xCC, + 0x08, 0xB3, 0xA2, 0x71, 0x24, 0xBA, 0x8E, 0x49, 0xB9, 0x04, 0x1B, 0x47, + 0x96, 0x58, 0xAB, 0x2D, 0x95, 0xC8, 0xED, 0x9E, 0x08, 0x35, 0xC8, 0x27, + 0xEB, 0x89, 0x8C, 0x53, 0x58, 0xEB, 0x62, 0x8A, 0xFE, 0xF0, 0x5B, 0x0F, + 0x6B, 0x31, 0x52, 0x63, 0x41, 0x3B, 0x89, 0xCD, 0xEC, 0xEC, 0xB6, 0x8D, + 0x19, 0xD3, 0x34, 0x07, 0xDC, 0xBB, 0xC6, 0x06, 0x7F, 0xC2, 0x45, 0x95, + 0xEC, 0xCB, 0x7F, 0xA8, 0x23, 0xE0, 0x09, 0xE9, 0x81, 0xFA, 0xF3, 0x47, + 0xD3 +}; + +static const unsigned char TA345_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x52, 0x53, 0x41 +}; + +static const unsigned char TA345_RSA_N[] = { + 0xF9, 0x0F, 0xDD, 0xA3, 0x2B, 0x7D, 0xCB, 0xD0, 0x2A, 0xFE, 0xEC, 0x67, + 0x85, 0xA6, 0xE7, 0x2E, 0x1B, 0xBA, 0x77, 0xE1, 0xE3, 0xF5, 0xAF, 0xA4, + 0xEC, 0xFA, 0x4A, 0x5D, 0x91, 0xC4, 0x57, 0x47, 0x6B, 0x18, 0x77, 0x6B, + 0x76, 0xF2, 0xFD, 0x93, 0xE4, 0x3D, 0x0F, 0xC2, 0x16, 0x9E, 0x0B, 0x66, + 0xC3, 0x56, 0x94, 0x9E, 0x17, 0x83, 0x85, 0xCE, 0x56, 0xEF, 0xF2, 0x16, + 0xFD, 0x00, 0x62, 0xF5, 0x22, 0x09, 0x54, 0xE8, 0x65, 0x17, 0x4E, 0x41, + 0xB9, 0xE0, 0x4F, 0x46, 0x97, 0xAA, 0x1B, 0xC8, 0xB8, 0x6E, 0x62, 0x5E, + 0x69, 0xB1, 0x5F, 0xDB, 0x2A, 0x02, 0x7E, 0xFC, 0x6C, 0xCA, 0xF3, 0x41, + 0xD8, 0xED, 0xD0, 0xE8, 0xFC, 0x3F, 0x61, 0x48, 0xED, 0xB0, 0x03, 0x14, + 0x1D, 0x10, 0x0E, 0x4B, 0x19, 0xE0, 0xBB, 0x4E, 0xEC, 0x86, 0x65, 0xFF, + 0x36, 0xF3, 0x5E, 0x67, 0x02, 0x0B, 0x9D, 0x86, 0x55, 0x61, 0xFD, 0x7A, + 0x38, 0xED, 0xFE, 0xE2, 0x19, 0x00, 0xB7, 0x6F, 0xA1, 0x50, 0x62, 0x75, + 0x74, 0x3C, 0xA0, 0xFA, 0xC8, 0x25, 0x92, 0xB4, 0x6E, 0x7A, 0x22, 0xC7, + 0xF8, 0x1E, 0xA1, 0xE3, 0xB2, 0xDD, 0x91, 0x31, 0xAB, 0x2B, 0x1D, 0x04, + 0xFF, 0xA5, 0x4A, 0x04, 0x37, 0xE9, 0x85, 0xA4, 0x33, 0x2B, 0xFD, 0xE2, + 0xD6, 0x55, 0x34, 0x7C, 0x19, 0xA4, 0x4A, 0x68, 0xC7, 0xB2, 0xA8, 0xD3, + 0xB7, 0xCA, 0xA1, 0x93, 0x88, 0xEB, 0xC1, 0x97, 0xBC, 0x8C, 0xF9, 0x1D, + 0xD9, 0x22, 0x84, 0x24, 0x74, 0xC7, 0x04, 0x3D, 0x6A, 0xA9, 0x29, 0x93, + 0xCC, 0xEB, 0xB8, 0x5B, 0xE1, 0xFE, 0x5F, 0x25, 0xAA, 0x34, 0x58, 0xC8, + 0xC1, 0x23, 0x54, 0x9D, 0x1B, 0x98, 0x11, 0xC3, 0x38, 0x9C, 0x7E, 0x3D, + 0x86, 0x6C, 0xA5, 0x0F, 0x40, 0x86, 0x7C, 0x02, 0xF4, 0x5C, 0x02, 0x4F, + 0x28, 0xCB, 0xAE, 0x71, 0x9F, 0x0F, 0x3A, 0xC8, 0x33, 0xFE, 0x11, 0x25, + 0x35, 0xEA, 0xFC, 0xBA, 0xC5, 0x60, 0x3D, 0xD9, 0x7C, 0x18, 0xD5, 0xB2, + 0xA9, 0xD3, 0x75, 0x78, 0x03, 0x72, 0x22, 0xCA, 0x3A, 0xC3, 0x1F, 0xEF, + 0x2C, 0xE5, 0x2E, 0xA9, 0xFA, 0x9E, 0x2C, 0xB6, 0x51, 0x46, 0xFD, 0xAF, + 0x03, 0xD6, 0xEA, 0x60, 0x68, 0xEA, 0x85, 0x16, 0x36, 0x6B, 0x85, 0xE9, + 0x1E, 0xC0, 0xB3, 0xDD, 0xC4, 0x24, 0xDC, 0x80, 0x2A, 0x81, 0x41, 0x6D, + 0x94, 0x3E, 0xC8, 0xE0, 0xC9, 0x81, 0x41, 0x00, 0x9E, 0x5E, 0xBF, 0x7F, + 0xC5, 0x08, 0x98, 0xA2, 0x18, 0x2C, 0x42, 0x40, 0xB3, 0xF9, 0x6F, 0x38, + 0x27, 0x4B, 0x4E, 0x80, 0xF4, 0x3D, 0x81, 0x47, 0xE0, 0x88, 0x7C, 0xEA, + 0x1C, 0xCE, 0xB5, 0x75, 0x5C, 0x51, 0x2E, 0x1C, 0x2B, 0x7F, 0x1A, 0x72, + 0x28, 0xE7, 0x00, 0xB5, 0xD1, 0x74, 0xC6, 0xD7, 0xE4, 0x9F, 0xAD, 0x07, + 0x93, 0xB6, 0x53, 0x35, 0x35, 0xFC, 0x37, 0xE4, 0xC3, 0xF6, 0x5D, 0x16, + 0xBE, 0x21, 0x73, 0xDE, 0x92, 0x0A, 0xF8, 0xA0, 0x63, 0x6A, 0xBC, 0x96, + 0x92, 0x6A, 0x3E, 0xF8, 0xBC, 0x65, 0x55, 0x9B, 0xDE, 0xF5, 0x0D, 0x89, + 0x26, 0x04, 0xFC, 0x25, 0x1A, 0xA6, 0x25, 0x69, 0xCB, 0xC2, 0x6D, 0xCA, + 0x7C, 0xE2, 0x59, 0x5F, 0x97, 0xAC, 0xEB, 0xEF, 0x2E, 0xC8, 0xBC, 0xD7, + 0x1B, 0x59, 0x3C, 0x2B, 0xCC, 0xF2, 0x19, 0xC8, 0x93, 0x6B, 0x27, 0x63, + 0x19, 0xCF, 0xFC, 0xE9, 0x26, 0xF8, 0xCA, 0x71, 0x9B, 0x7F, 0x93, 0xFE, + 0x34, 0x67, 0x84, 0x4E, 0x99, 0xEB, 0xFC, 0xB3, 0x78, 0x09, 0x33, 0x70, + 0xBA, 0x66, 0xA6, 0x76, 0xED, 0x1B, 0x73, 0xEB, 0x1A, 0xA5, 0x0D, 0xC4, + 0x22, 0x13, 0x20, 0x94, 0x56, 0x0A, 0x4E, 0x2C, 0x6C, 0x4E, 0xB1, 0xFD, + 0xCF, 0x9C, 0x09, 0xBA, 0xA2, 0x33, 0xED, 0x87 +}; + +static const unsigned char TA345_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA346_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA346_EC_Q[] = { + 0x04, 0x45, 0x29, 0x35, 0x73, 0xFA, 0xC2, 0xB8, 0x23, 0xCE, 0x14, 0x7D, + 0xA8, 0xB1, 0x4D, 0xA0, 0x5B, 0x36, 0xEE, 0x2A, 0x2C, 0x53, 0xC3, 0x60, + 0x09, 0x35, 0xB2, 0x24, 0x66, 0x26, 0x69, 0xC0, 0xB3, 0x95, 0xD6, 0x5D, + 0x92, 0x40, 0x19, 0x0E, 0xC6, 0xA5, 0x13, 0x70, 0xF4, 0xEF, 0x12, 0x51, + 0x28, 0x5D, 0xE7, 0xCC, 0xBD, 0xF9, 0x3C, 0x85, 0xC1, 0xCF, 0x94, 0x90, + 0xC9, 0x2B, 0xCE, 0x92, 0x42, 0x58, 0x59, 0x67, 0xFD, 0x94, 0x27, 0x10, + 0x64, 0x8C, 0x4F, 0x04, 0xB1, 0x4D, 0x49, 0xE4, 0x7B, 0x4F, 0x9B, 0xF5, + 0xE7, 0x08, 0xF8, 0x03, 0x88, 0xF7, 0xA7, 0xC3, 0x92, 0x4B, 0x19, 0x54, + 0x81 +}; + +static const unsigned char TA347_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA347_RSA_N[] = { + 0xD0, 0xA4, 0x09, 0x72, 0x4F, 0x40, 0x88, 0x12, 0x61, 0x3E, 0x35, 0x23, + 0x9E, 0xEE, 0xF6, 0x74, 0xCF, 0x2F, 0x7B, 0x58, 0x3D, 0xCE, 0x3C, 0x0D, + 0x10, 0x28, 0x90, 0x2F, 0x97, 0xF7, 0x8C, 0x48, 0xD8, 0xA0, 0xD8, 0x25, + 0xB1, 0x4C, 0xB0, 0x11, 0x4C, 0x17, 0x73, 0x50, 0xD0, 0x22, 0x4A, 0x63, + 0xBB, 0x81, 0xD3, 0x29, 0x6E, 0xD5, 0xB5, 0x09, 0x3E, 0x26, 0x18, 0x7F, + 0xB2, 0x12, 0x7F, 0x93, 0x98, 0xB7, 0xAF, 0xF0, 0x36, 0xBF, 0xF2, 0xEE, + 0x18, 0x9E, 0x9C, 0x3B, 0x52, 0xC5, 0x47, 0x19, 0x5D, 0x74, 0xF3, 0x64, + 0x66, 0xD5, 0x5D, 0xC7, 0x68, 0xB4, 0xBF, 0x1B, 0x1C, 0x06, 0xA3, 0xBC, + 0x8F, 0x40, 0x23, 0xB6, 0x1E, 0xC6, 0x84, 0xBD, 0x51, 0xC4, 0x1B, 0x39, + 0xC1, 0x95, 0xD2, 0x29, 0xEC, 0x4B, 0xAE, 0x7B, 0x2D, 0xBF, 0x39, 0xFD, + 0xB4, 0x62, 0xDE, 0x96, 0x7B, 0x41, 0xC6, 0x9C, 0xA0, 0xE0, 0x06, 0x72, + 0xFB, 0xF0, 0x07, 0x97, 0x09, 0x39, 0x81, 0x74, 0xAF, 0xF7, 0x34, 0x59, + 0x11, 0x57, 0x0A, 0xC2, 0x5B, 0xC1, 0x24, 0xF4, 0x31, 0x73, 0x30, 0x82, + 0xC6, 0x9D, 0xBA, 0x02, 0xF7, 0x3E, 0x7C, 0x44, 0x5F, 0x83, 0x0D, 0xF3, + 0xF1, 0xDD, 0x20, 0x69, 0x16, 0x09, 0x50, 0xE2, 0xD4, 0x55, 0xB6, 0xE0, + 0x80, 0x72, 0x76, 0x6E, 0x4C, 0x47, 0xB7, 0x75, 0x55, 0x59, 0xB4, 0x53, + 0x74, 0xD9, 0x94, 0xC6, 0x41, 0xAD, 0x58, 0x8A, 0x31, 0x66, 0x0F, 0x1E, + 0xA2, 0x1B, 0x29, 0x40, 0x4E, 0x2F, 0xDF, 0x7B, 0xE6, 0x16, 0x2C, 0x2D, + 0xFC, 0xBF, 0xEC, 0xF3, 0xB4, 0xFA, 0xBE, 0x18, 0xF6, 0x9B, 0x49, 0xD4, + 0xEE, 0x05, 0x6E, 0xD9, 0x34, 0xF3, 0x9C, 0xF1, 0xEC, 0x01, 0x8B, 0xD1, + 0x20, 0xC6, 0x0F, 0xA0, 0xB5, 0xBC, 0x17, 0x4E, 0x48, 0x7B, 0x51, 0xC2, + 0xFC, 0xE9, 0x5C, 0x69, 0x37, 0x47, 0x66, 0xB3, 0x68, 0xF8, 0x15, 0x28, + 0xF0, 0xB9, 0xD3, 0xA4, 0x15, 0xCC, 0x5A, 0x4F, 0xBA, 0x52, 0x70, 0xA3, + 0x12, 0x45, 0xDD, 0xC6, 0xBA, 0x4E, 0xFB, 0xC2, 0xD0, 0xF7, 0xA8, 0x52, + 0x27, 0x6D, 0x6E, 0x79, 0xB5, 0x8C, 0xFC, 0x7B, 0x8C, 0xC1, 0x16, 0x4C, + 0xEE, 0x80, 0x7F, 0xBE, 0xF0, 0x76, 0xBE, 0x41, 0x53, 0x12, 0x33, 0xAE, + 0x5A, 0x38, 0x42, 0xAB, 0xD7, 0x0F, 0x3E, 0x41, 0x8D, 0x76, 0x07, 0x32, + 0xD5, 0xAB, 0x89, 0xF6, 0x4E, 0x67, 0xD9, 0xB1, 0x42, 0x75, 0x23, 0x6E, + 0xF3, 0xCD, 0x42, 0xB2, 0xFC, 0x55, 0xF5, 0x53, 0x87, 0x17, 0x3B, 0xC0, + 0x33, 0x58, 0xF1, 0x52, 0xD2, 0xF9, 0x80, 0xA4, 0xF0, 0xE8, 0xF0, 0x3B, + 0x8B, 0x38, 0xCC, 0xA4, 0xC6, 0x90, 0x7F, 0x0F, 0x9C, 0xFD, 0x8B, 0xD1, + 0xA3, 0xCF, 0xDA, 0x83, 0xA7, 0x69, 0xC9, 0x50, 0x36, 0xD5, 0x5C, 0x05, + 0xD2, 0x0A, 0x41, 0x74, 0xDB, 0x63, 0x11, 0x37, 0xC1, 0xA5, 0xA0, 0x96, + 0x4B, 0x1E, 0x8C, 0x16, 0x12, 0x77, 0xAE, 0x94, 0x34, 0x7B, 0x1E, 0x7F, + 0xC2, 0x66, 0x00, 0xE4, 0xAA, 0x83, 0xEA, 0x8A, 0x90, 0xAD, 0xCE, 0x36, + 0x44, 0x4D, 0xD1, 0x51, 0xE9, 0xBC, 0x1F, 0xF3, 0x6A, 0x05, 0xFD, 0xC0, + 0x74, 0x1F, 0x25, 0x19, 0x40, 0x51, 0x6E, 0xEA, 0x82, 0x51, 0x40, 0xDF, + 0x9B, 0xB9, 0x08, 0x2A, 0x06, 0x02, 0xD5, 0x23, 0x1C, 0x13, 0xD6, 0xE9, + 0xDB, 0xDB, 0xC6, 0xB0, 0x7A, 0xCB, 0x7B, 0x27, 0x9B, 0xFB, 0xE0, 0xD5, + 0x46, 0x24, 0xED, 0x10, 0x4B, 0x63, 0x4B, 0xA5, 0x05, 0x8F, 0xBA, 0xB8, + 0x1D, 0x2B, 0xA6, 0xFA, 0x91, 0xE2, 0x92, 0x52, 0xBD, 0xEC, 0xEB, 0x67, + 0x97, 0x6D, 0x9A, 0x2D, 0x9F, 0x81, 0x32, 0x05, 0x67, 0x32, 0xFB, 0x48, + 0x08, 0x3F, 0xD9, 0x25, 0xB8, 0x04, 0x25, 0x2F +}; + +static const unsigned char TA347_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA348_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1F, 0x4B, 0x72, 0x61, 0x6A, 0x6F, 0x77, 0x61, 0x20, 0x49, 0x7A, + 0x62, 0x61, 0x20, 0x52, 0x6F, 0x7A, 0x6C, 0x69, 0x63, 0x7A, 0x65, 0x6E, + 0x69, 0x6F, 0x77, 0x61, 0x20, 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x53, 0x5A, 0x41, 0x46, + 0x49, 0x52, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA348_RSA_N[] = { + 0xB7, 0xBC, 0x3E, 0x50, 0xA8, 0x4B, 0xCD, 0x40, 0xB5, 0xCE, 0x61, 0xE7, + 0x96, 0xCA, 0xB4, 0xA1, 0xDA, 0x0C, 0x22, 0xB0, 0xFA, 0xB5, 0x7B, 0x76, + 0x00, 0x77, 0x8C, 0x0B, 0xCF, 0x7D, 0xA8, 0x86, 0xCC, 0x26, 0x51, 0xE4, + 0x20, 0x3D, 0x85, 0x0C, 0xD6, 0x58, 0xE3, 0xE7, 0xF4, 0x2A, 0x18, 0x9D, + 0xDA, 0xD1, 0xAE, 0x26, 0xEE, 0xEB, 0x53, 0xDC, 0xF4, 0x90, 0xD6, 0x13, + 0x4A, 0x0C, 0x90, 0x3C, 0xC3, 0xF4, 0xDA, 0xD2, 0x8E, 0x0D, 0x92, 0x3A, + 0xDC, 0xB1, 0xB1, 0xFF, 0x38, 0xDE, 0xC3, 0xBA, 0x2D, 0x5F, 0x80, 0xB9, + 0x02, 0xBD, 0x4A, 0x9D, 0x1B, 0x0F, 0xB4, 0xC3, 0xC2, 0xC1, 0x67, 0x03, + 0xDD, 0xDC, 0x1B, 0x9C, 0x3D, 0xB3, 0xB0, 0xDE, 0x00, 0x1E, 0xA8, 0x34, + 0x47, 0xBB, 0x9A, 0xEB, 0xFE, 0x0B, 0x14, 0xBD, 0x36, 0x84, 0xDA, 0x0D, + 0x20, 0xBF, 0xFA, 0x5B, 0xCB, 0xA9, 0x16, 0x20, 0xAD, 0x39, 0x60, 0xEE, + 0x2F, 0x75, 0xB6, 0xE7, 0x97, 0x9C, 0xF9, 0x3E, 0xFD, 0x7E, 0x4D, 0x6F, + 0x4D, 0x2F, 0xEF, 0x88, 0x0D, 0x6A, 0xFA, 0xDD, 0xF1, 0x3D, 0x6E, 0x20, + 0xA5, 0xA0, 0x12, 0xB4, 0x4D, 0x70, 0xB9, 0xCE, 0xD7, 0x72, 0x3B, 0x89, + 0x93, 0xA7, 0x80, 0x84, 0x1C, 0x27, 0x49, 0x72, 0x49, 0xB5, 0xFF, 0x3B, + 0x95, 0x9E, 0xC1, 0xCC, 0xC8, 0x01, 0xEC, 0xE8, 0x0E, 0x8A, 0x0A, 0x96, + 0xE7, 0xB3, 0xA6, 0x87, 0xE5, 0xD6, 0xF9, 0x05, 0x2B, 0x0D, 0x97, 0x40, + 0x70, 0x3C, 0xBA, 0xAC, 0x75, 0x5A, 0x9C, 0xD5, 0x4D, 0x9D, 0x02, 0x0A, + 0xD2, 0x4B, 0x9B, 0x66, 0x4B, 0x46, 0x07, 0x17, 0x65, 0xAD, 0x9F, 0x6C, + 0x88, 0x00, 0xDC, 0x22, 0x89, 0xE0, 0xE1, 0x64, 0xD4, 0x67, 0xBC, 0x31, + 0x79, 0x61, 0x3C, 0xBB, 0xCA, 0x41, 0xCD, 0x5C, 0x6A, 0x00, 0xC8, 0x3C, + 0x38, 0x8E, 0x58, 0xAF +}; + +static const unsigned char TA348_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA349_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, + 0x36 +}; + +static const unsigned char TA349_EC_Q[] = { + 0x04, 0x76, 0xFA, 0x99, 0xA9, 0x6E, 0x20, 0xED, 0xF9, 0xD7, 0x77, 0xE3, + 0x07, 0x3B, 0xA8, 0xDB, 0x3D, 0x5F, 0x38, 0xE8, 0xAB, 0x55, 0xA6, 0x56, + 0x4F, 0xD6, 0x48, 0xEA, 0xEC, 0x7F, 0x2D, 0xAA, 0xC3, 0xB2, 0xC5, 0x79, + 0xEC, 0x99, 0x61, 0x7F, 0x10, 0x79, 0xC7, 0x02, 0x5A, 0xF9, 0x04, 0x37, + 0xF5, 0x34, 0x35, 0x2B, 0x77, 0xCE, 0x7F, 0x20, 0x8F, 0x52, 0xA3, 0x00, + 0x89, 0xEC, 0xD5, 0xA7, 0xA2, 0x6D, 0x5B, 0xE3, 0x4B, 0x92, 0x93, 0xA0, + 0x80, 0xF5, 0x01, 0x94, 0xDC, 0xF0, 0x68, 0x07, 0x1E, 0xCD, 0xEE, 0xFE, + 0x25, 0x52, 0xB5, 0x20, 0x43, 0x1C, 0x1B, 0xFE, 0xEB, 0x19, 0xCE, 0x43, + 0xA3 +}; + +static const unsigned char TA350_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, + 0x36 +}; + +static const unsigned char TA350_RSA_N[] = { + 0x93, 0xBE, 0xD5, 0x36, 0x52, 0x75, 0xD8, 0x01, 0x23, 0xA0, 0x1C, 0x47, + 0x42, 0x49, 0xEE, 0x63, 0xB6, 0xB7, 0x21, 0xFD, 0xC4, 0x95, 0xD5, 0x48, + 0x2B, 0x26, 0x7C, 0x14, 0x53, 0x10, 0xDA, 0x79, 0xFD, 0x2B, 0xB7, 0x2D, + 0xA4, 0xD4, 0x2C, 0xFA, 0xEA, 0x32, 0xDD, 0x49, 0xC2, 0xB9, 0xBD, 0x0F, + 0x48, 0x3D, 0x7B, 0x5A, 0x98, 0x54, 0xAF, 0x9E, 0x5D, 0x31, 0x74, 0x4F, + 0x07, 0xFC, 0x50, 0x21, 0xDD, 0xA4, 0xCF, 0x68, 0x4F, 0x1B, 0x12, 0x63, + 0x6D, 0x25, 0x99, 0x4C, 0x2A, 0x99, 0xF3, 0x48, 0x30, 0x61, 0xFA, 0x81, + 0x7C, 0x1E, 0xA7, 0x08, 0x4A, 0xDC, 0x3E, 0x2B, 0x1C, 0x1F, 0x18, 0x4C, + 0x71, 0xAA, 0x35, 0x8C, 0xAD, 0xF8, 0x6E, 0xE8, 0x3B, 0x4A, 0xD9, 0xE5, + 0x94, 0x02, 0xD6, 0x89, 0x84, 0x13, 0xAA, 0x6D, 0xC8, 0x4F, 0x33, 0xCC, + 0x50, 0x96, 0x37, 0x92, 0x33, 0xDC, 0x5F, 0x88, 0xE7, 0x9F, 0x54, 0xD9, + 0x48, 0xF0, 0x98, 0x43, 0xD6, 0x66, 0xFD, 0x9F, 0x17, 0x38, 0x43, 0xC5, + 0x01, 0x51, 0x0B, 0xD7, 0xE3, 0x23, 0x0F, 0x14, 0x5D, 0x5B, 0x14, 0xE7, + 0x4B, 0xBE, 0xDD, 0xF4, 0xC8, 0xDA, 0x03, 0x37, 0xD1, 0xD6, 0x39, 0xA1, + 0x21, 0x51, 0x30, 0x83, 0xB0, 0x6D, 0xD7, 0x30, 0x4E, 0x96, 0x5B, 0x91, + 0xF0, 0x70, 0x24, 0xAB, 0xBF, 0x45, 0x81, 0x64, 0x43, 0x0D, 0xBD, 0x21, + 0x3A, 0x2F, 0x3C, 0xE9, 0x9E, 0x0D, 0xCB, 0x20, 0xB5, 0x42, 0x27, 0xCC, + 0xDA, 0x6F, 0x9B, 0xEE, 0x64, 0x30, 0x90, 0x39, 0xCD, 0x93, 0x65, 0x81, + 0x21, 0x31, 0xB5, 0x23, 0x50, 0x33, 0x37, 0x22, 0xE3, 0x38, 0xED, 0xF8, + 0x31, 0x30, 0xCC, 0x45, 0xFE, 0x62, 0xF9, 0xD1, 0x5D, 0x32, 0x79, 0x42, + 0x87, 0xDF, 0x6A, 0xCC, 0x56, 0x19, 0x40, 0x4D, 0xCE, 0xAA, 0xBB, 0xF9, + 0xB5, 0x76, 0x49, 0x94, 0xF1, 0x27, 0xF8, 0x91, 0xA5, 0x83, 0xE5, 0x06, + 0xB3, 0x63, 0x0E, 0x80, 0xDC, 0xE0, 0x12, 0x55, 0x80, 0xA6, 0x3B, 0x66, + 0xB4, 0x39, 0x87, 0x2D, 0xC8, 0xF0, 0xD0, 0xD1, 0x14, 0xE9, 0xE4, 0x0D, + 0x4D, 0x0E, 0xF6, 0x5D, 0x57, 0x72, 0xC5, 0x3B, 0x1C, 0x47, 0x56, 0x9D, + 0xE2, 0xD5, 0xFB, 0x81, 0x61, 0x8C, 0xCC, 0x4D, 0x80, 0x90, 0x34, 0x5B, + 0xB7, 0xD7, 0x14, 0x75, 0xDC, 0xD8, 0x04, 0x48, 0x9F, 0xC0, 0xC1, 0x28, + 0x88, 0xB4, 0xE9, 0x1C, 0xCA, 0xA7, 0xB1, 0xF1, 0x56, 0xB7, 0x7B, 0x49, + 0x4C, 0x59, 0xE5, 0x20, 0x15, 0xA8, 0x84, 0x02, 0x29, 0xFA, 0x38, 0x94, + 0x69, 0x9A, 0x49, 0x06, 0x8F, 0xCD, 0x1F, 0x79, 0x14, 0x17, 0x12, 0x0C, + 0x83, 0x7A, 0xDE, 0x1F, 0xB1, 0x97, 0xEE, 0xF9, 0x97, 0x78, 0x28, 0xA4, + 0xC8, 0x44, 0x92, 0xE9, 0x7D, 0x26, 0x05, 0xA6, 0x58, 0x72, 0x9B, 0x79, + 0x13, 0xD8, 0x11, 0x5F, 0xAE, 0xC5, 0x38, 0x62, 0x34, 0x68, 0xB2, 0x86, + 0x30, 0x8E, 0xF8, 0x90, 0x61, 0x9E, 0x32, 0x6C, 0xF5, 0x07, 0x36, 0xCD, + 0xA2, 0x4C, 0x6E, 0xEC, 0x8A, 0x36, 0xED, 0xF2, 0xE6, 0x99, 0x15, 0x44, + 0x70, 0xC3, 0x7C, 0xBC, 0x9C, 0x39, 0xC0, 0xB4, 0xE1, 0x6B, 0xF7, 0x83, + 0x25, 0x23, 0x57, 0xD9, 0x12, 0x80, 0xE5, 0x49, 0xF0, 0x75, 0x0F, 0xEF, + 0x8D, 0xEB, 0x1C, 0x9B, 0x54, 0x28, 0xB4, 0x21, 0x3C, 0xFC, 0x7C, 0x0A, + 0xFF, 0xEF, 0x7B, 0x6B, 0x75, 0xFF, 0x8B, 0x1D, 0xA0, 0x19, 0x05, 0xAB, + 0xFA, 0xF8, 0x2B, 0x81, 0x42, 0xE8, 0x38, 0xBA, 0xBB, 0xFB, 0xAA, 0xFD, + 0x3D, 0xE0, 0xF3, 0xCA, 0xDF, 0x4E, 0x97, 0x97, 0x29, 0xED, 0xF3, 0x18, + 0x56, 0xE9, 0xA5, 0x96, 0xAC, 0xBD, 0xC3, 0x90, 0x98, 0xB2, 0xE0, 0xF9, + 0xA2, 0xD4, 0xA6, 0x47, 0x43, 0x7C, 0x6D, 0xCF +}; + +static const unsigned char TA350_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA351_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x32 +}; + +static const unsigned char TA351_RSA_N[] = { + 0xBA, 0x39, 0xC1, 0x37, 0x7A, 0x68, 0x45, 0x2B, 0x14, 0xB4, 0xEB, 0xE4, + 0x13, 0xEB, 0x57, 0x75, 0x23, 0x4D, 0x8F, 0x24, 0x2D, 0x16, 0xE8, 0xAE, + 0x8E, 0xC9, 0x7D, 0xA4, 0x57, 0x3B, 0x2A, 0x76, 0x25, 0x33, 0x83, 0x6C, + 0xEA, 0x32, 0x8A, 0x94, 0x9B, 0x4E, 0x3C, 0x96, 0xE4, 0xFD, 0x51, 0xBF, + 0x99, 0xC9, 0x93, 0x7E, 0xBF, 0xF9, 0xAD, 0xA7, 0xB2, 0x48, 0x2B, 0x07, + 0x1C, 0x27, 0xF5, 0x4C, 0xBC, 0x70, 0x12, 0x77, 0xA4, 0x85, 0x54, 0xB5, + 0xFD, 0x90, 0x7A, 0xE4, 0xA3, 0xE4, 0x51, 0x58, 0x03, 0xCD, 0x10, 0x79, + 0x79, 0xEE, 0x6B, 0x93, 0x1F, 0x64, 0x8E, 0x6B, 0x64, 0xAB, 0xA3, 0x13, + 0xE3, 0x71, 0xFE, 0x7D, 0xAB, 0x9C, 0xDD, 0x27, 0x53, 0x37, 0xB3, 0xAA, + 0x18, 0xC2, 0x59, 0x26, 0xEC, 0x5B, 0x1F, 0xD2, 0xE6, 0x65, 0x7C, 0xEF, + 0x93, 0xBD, 0xD8, 0x58, 0x5C, 0x0B, 0xC0, 0xE3, 0x65, 0x6F, 0x3C, 0xC7, + 0xCA, 0x59, 0xE3, 0xFE, 0x6E, 0x5F, 0xAC, 0x83, 0xBE, 0xFD, 0x5D, 0x25, + 0x4E, 0x2A, 0x29, 0x3B, 0xD6, 0x0B, 0xAB, 0x17, 0x32, 0x78, 0xA4, 0xE1, + 0x3E, 0x94, 0x46, 0xBE, 0x62, 0x6E, 0x9B, 0xDE, 0x46, 0xA8, 0xB1, 0x16, + 0xE7, 0x85, 0x6E, 0xF4, 0x08, 0x40, 0x45, 0x11, 0xA0, 0x9E, 0x54, 0x44, + 0x84, 0xF7, 0xD8, 0x36, 0xCE, 0xF5, 0x50, 0x47, 0xDC, 0x2C, 0x30, 0x9B, + 0xEE, 0xC0, 0xF5, 0x96, 0xD2, 0xFE, 0x09, 0x86, 0xC7, 0x06, 0x59, 0xAE, + 0x4F, 0xAE, 0x8E, 0x11, 0x98, 0x7B, 0xF3, 0x0B, 0x52, 0xAA, 0x62, 0x26, + 0xAA, 0x21, 0xDF, 0x8E, 0x25, 0x33, 0x79, 0x97, 0x16, 0x49, 0x8D, 0xF5, + 0x3E, 0xD5, 0x47, 0x9F, 0x37, 0x31, 0x49, 0x33, 0x72, 0x05, 0x4D, 0x0C, + 0xB6, 0x55, 0x8C, 0xF1, 0x57, 0x8F, 0x8A, 0x87, 0xD1, 0xAD, 0xC5, 0x11, + 0x12, 0x39, 0xA0, 0xAD +}; + +static const unsigned char TA351_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA352_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x34 +}; + +static const unsigned char TA352_RSA_N[] = { + 0xC5, 0xD2, 0x7A, 0xA1, 0xD6, 0x8A, 0xBF, 0x16, 0x31, 0xD0, 0x98, 0xD1, + 0x3A, 0x94, 0xFC, 0x5A, 0xB8, 0x6E, 0x22, 0xC1, 0x62, 0xF7, 0xA7, 0x0A, + 0x27, 0xEF, 0x50, 0xF6, 0x2E, 0xB1, 0x9E, 0x68, 0x12, 0xF0, 0x6C, 0x24, + 0x63, 0x39, 0xF1, 0xF0, 0xDF, 0x10, 0xC6, 0xDE, 0xB7, 0x52, 0x20, 0xD5, + 0x52, 0x5B, 0x42, 0x99, 0x9E, 0xF3, 0xA0, 0xBE, 0x52, 0x1F, 0x5F, 0xCC, + 0x67, 0x6D, 0xA7, 0x2E, 0x50, 0xA2, 0xC1, 0x97, 0x8D, 0xB6, 0xF8, 0x95, + 0xF5, 0xB0, 0xBA, 0xDC, 0x9D, 0xE0, 0xBE, 0xCB, 0xDF, 0xF7, 0x38, 0xF2, + 0x47, 0xF5, 0xA6, 0x9A, 0x92, 0x95, 0x2A, 0x62, 0x59, 0x50, 0x0B, 0xA2, + 0xB1, 0x35, 0xE7, 0x65, 0xB2, 0x61, 0xB2, 0xEA, 0x92, 0x71, 0x69, 0xE4, + 0x29, 0xF0, 0x4F, 0x81, 0x81, 0x04, 0x3C, 0xB2, 0xA5, 0x5B, 0xD4, 0xC5, + 0xA8, 0x59, 0x67, 0x7B, 0x55, 0x1C, 0x49, 0xAB, 0x7A, 0x9D, 0xC2, 0xE7, + 0x73, 0x4D, 0xEF, 0xCD, 0x09, 0xC2, 0xC4, 0x57, 0x12, 0xDB, 0x01, 0x0E, + 0x23, 0x79, 0x09, 0x07, 0x3B, 0xA2, 0xE8, 0xFC, 0x8A, 0xCF, 0x8F, 0xC0, + 0x46, 0x24, 0x9C, 0x38, 0x27, 0xE0, 0x83, 0x9D, 0x1B, 0xA0, 0xBF, 0x78, + 0x15, 0x10, 0xEB, 0x86, 0x4E, 0x0A, 0x5A, 0xFD, 0xDF, 0xDA, 0x2C, 0x82, + 0x7E, 0xEE, 0xCA, 0xF6, 0x29, 0xE1, 0xFA, 0x71, 0xA1, 0xF7, 0x88, 0x68, + 0x9C, 0x9C, 0xF0, 0x8D, 0xBE, 0x0F, 0x49, 0x91, 0xD8, 0xEA, 0x3A, 0xF9, + 0xFD, 0xD0, 0x68, 0x71, 0xDB, 0xE9, 0xB5, 0x2B, 0x4E, 0x82, 0x92, 0x6F, + 0x66, 0x1F, 0xE0, 0xF0, 0xDC, 0x4C, 0xEC, 0xCA, 0xD1, 0xEA, 0xBA, 0x74, + 0x06, 0xF9, 0xB3, 0x84, 0x90, 0x94, 0xD1, 0x5F, 0x8E, 0x73, 0x19, 0x10, + 0x5D, 0x02, 0xE5, 0x70, 0xA5, 0xC0, 0x10, 0xD0, 0x10, 0x7C, 0x6F, 0xC5, + 0x58, 0x49, 0xB4, 0xB0, 0x6E, 0x9A, 0xDA, 0x7D, 0x95, 0xF5, 0xCC, 0xDA, + 0x02, 0xAF, 0xB8, 0x2C, 0x7D, 0x79, 0x8F, 0xBE, 0x43, 0xF1, 0xF9, 0x28, + 0x28, 0x8D, 0x09, 0x43, 0xF8, 0x08, 0xDD, 0x6B, 0xC8, 0x8B, 0x2C, 0x24, + 0xB1, 0x8D, 0x52, 0x07, 0xBD, 0x78, 0x9B, 0xCB, 0xCA, 0x68, 0xB2, 0xA4, + 0xDD, 0x0C, 0x4C, 0x79, 0x60, 0xC6, 0x99, 0xD1, 0x93, 0xF1, 0x30, 0x1A, + 0x07, 0xD3, 0xAE, 0x22, 0xC2, 0xEA, 0xCE, 0xF1, 0x84, 0x09, 0xCC, 0xE0, + 0x14, 0x6E, 0x7F, 0x3F, 0x7E, 0xD2, 0x82, 0x85, 0xAC, 0xDC, 0xA9, 0x16, + 0x4E, 0x85, 0xA0, 0x60, 0xCB, 0xF6, 0x9C, 0xD7, 0xC8, 0xB3, 0x8E, 0xED, + 0xC6, 0x9B, 0x98, 0x75, 0x0D, 0x55, 0xE8, 0x5F, 0xE5, 0x95, 0x8B, 0x02, + 0xA4, 0xAE, 0x43, 0x29, 0x28, 0x11, 0xA4, 0xE6, 0x12, 0x30, 0x01, 0x4B, + 0x75, 0x6B, 0x1E, 0x66, 0x9D, 0x79, 0x2F, 0xA5, 0x76, 0x2F, 0x1D, 0x40, + 0xB4, 0x6D, 0xC9, 0x7D, 0x79, 0x08, 0xEC, 0xD1, 0x6A, 0xB6, 0x5D, 0x2A, + 0xB2, 0xA5, 0x66, 0xBD, 0x6B, 0x85, 0xF4, 0x74, 0x56, 0xC3, 0xF5, 0xE7, + 0x75, 0x52, 0x28, 0x2C, 0xA5, 0xFF, 0x66, 0x47, 0xA5, 0xD4, 0xFE, 0xFE, + 0x9E, 0x54, 0xBF, 0x65, 0x7E, 0x01, 0xD6, 0x30, 0x8F, 0xA5, 0x36, 0x9C, + 0xA2, 0x50, 0x1C, 0xEE, 0x38, 0x80, 0x01, 0x48, 0xC6, 0xC7, 0x74, 0xF4, + 0xC6, 0xAC, 0xC3, 0x40, 0x49, 0x16, 0x61, 0x74, 0x2C, 0xAF, 0x8C, 0x6F, + 0x35, 0xED, 0x7B, 0x18, 0x00, 0x5B, 0x36, 0x3C, 0x9C, 0x50, 0x0D, 0xCA, + 0x92, 0x33, 0x10, 0xF1, 0x26, 0x49, 0x6D, 0xDF, 0x75, 0x24, 0x37, 0x82, + 0x22, 0xD7, 0xE8, 0x96, 0xFD, 0x15, 0x4B, 0x02, 0x96, 0x3E, 0x07, 0x72, + 0x95, 0x7E, 0xAB, 0x3D, 0x4C, 0x2E, 0xD7, 0xCA, 0xF0, 0xDF, 0xE0, 0x58, + 0x3F, 0x2D, 0x2F, 0x04, 0x9A, 0x38, 0xA3, 0x01 +}; + +static const unsigned char TA352_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA353_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x35 +}; + +static const unsigned char TA353_EC_Q[] = { + 0x04, 0x0B, 0x50, 0x74, 0x8D, 0x64, 0x32, 0x99, 0x99, 0xB3, 0xD2, 0x60, + 0x08, 0xB8, 0x22, 0x8E, 0x46, 0x74, 0x2C, 0x78, 0xC0, 0x2B, 0x44, 0x2D, + 0x6D, 0x5F, 0x1D, 0xC9, 0xAE, 0x4B, 0x52, 0x20, 0x83, 0x3D, 0xB8, 0x14, + 0x6D, 0x53, 0x87, 0x60, 0x9E, 0x5F, 0x6C, 0x85, 0xDB, 0x06, 0x14, 0x95, + 0xE0, 0xC7, 0x28, 0xFF, 0x9D, 0x5F, 0xE4, 0xAA, 0xF1, 0xB3, 0x8B, 0x6D, + 0xED, 0x4F, 0x2F, 0x4B, 0xC9, 0x4A, 0x94, 0x91, 0x64, 0x75, 0xFE, 0x01, + 0xEC, 0xC1, 0xD8, 0xEB, 0x7A, 0x94, 0x78, 0x56, 0x18, 0x43, 0x5F, 0x6B, + 0x81, 0xCB, 0xF6, 0xBC, 0xDA, 0xB4, 0x0C, 0xB6, 0x29, 0x93, 0x08, 0x69, + 0x8F +}; + +static const unsigned char TA354_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0E, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA354_RSA_N[] = { + 0xAB, 0xA4, 0x81, 0xE5, 0x95, 0xCD, 0xF5, 0xF6, 0x14, 0x8E, 0xC2, 0x4F, + 0xCA, 0xD4, 0xE2, 0x78, 0x95, 0x58, 0x9C, 0x41, 0xE1, 0x0D, 0x99, 0x40, + 0x24, 0x17, 0x39, 0x91, 0x33, 0x66, 0xE9, 0xBE, 0xE1, 0x83, 0xAF, 0x62, + 0x5C, 0x89, 0xD1, 0xFC, 0x24, 0x5B, 0x61, 0xB3, 0xE0, 0x11, 0x11, 0x41, + 0x1C, 0x1D, 0x6E, 0xF0, 0xB8, 0xBB, 0xF8, 0xDE, 0xA7, 0x81, 0xBA, 0xA6, + 0x48, 0xC6, 0x9F, 0x1D, 0xBD, 0xBE, 0x8E, 0xA9, 0x41, 0x3E, 0xB8, 0x94, + 0xED, 0x29, 0x1A, 0xD4, 0x8E, 0xD2, 0x03, 0x1D, 0x03, 0xEF, 0x6D, 0x0D, + 0x67, 0x1C, 0x57, 0xD7, 0x06, 0xAD, 0xCA, 0xC8, 0xF5, 0xFE, 0x0E, 0xAF, + 0x66, 0x25, 0x48, 0x04, 0x96, 0x0B, 0x5D, 0xA3, 0xBA, 0x16, 0xC3, 0x08, + 0x4F, 0xD1, 0x46, 0xF8, 0x14, 0x5C, 0xF2, 0xC8, 0x5E, 0x01, 0x99, 0x6D, + 0xFD, 0x88, 0xCC, 0x86, 0xA8, 0xC1, 0x6F, 0x31, 0x42, 0x6C, 0x52, 0x3E, + 0x68, 0xCB, 0xF3, 0x19, 0x34, 0xDF, 0xBB, 0x87, 0x18, 0x56, 0x80, 0x26, + 0xC4, 0xD0, 0xDC, 0xC0, 0x6F, 0xDF, 0xDE, 0xA0, 0xC2, 0x91, 0x16, 0xA0, + 0x64, 0x11, 0x4B, 0x44, 0xBC, 0x1E, 0xF6, 0xE7, 0xFA, 0x63, 0xDE, 0x66, + 0xAC, 0x76, 0xA4, 0x71, 0xA3, 0xEC, 0x36, 0x94, 0x68, 0x7A, 0x77, 0xA4, + 0xB1, 0xE7, 0x0E, 0x2F, 0x81, 0x7A, 0xE2, 0xB5, 0x72, 0x86, 0xEF, 0xA2, + 0x6B, 0x8B, 0xF0, 0x0F, 0xDB, 0xD3, 0x59, 0x3F, 0xBA, 0x72, 0xBC, 0x44, + 0x24, 0x9C, 0xE3, 0x73, 0xB3, 0xF7, 0xAF, 0x57, 0x2F, 0x42, 0x26, 0x9D, + 0xA9, 0x74, 0xBA, 0x00, 0x52, 0xF2, 0x4B, 0xCD, 0x53, 0x7C, 0x47, 0x0B, + 0x36, 0x85, 0x0E, 0x66, 0xA9, 0x08, 0x97, 0x16, 0x34, 0x57, 0xC1, 0x66, + 0xF7, 0x80, 0xE3, 0xED, 0x70, 0x54, 0xC7, 0x93, 0xE0, 0x2E, 0x28, 0x15, + 0x59, 0x87, 0xBA, 0xBB +}; + +static const unsigned char TA354_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA355_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA355_RSA_N[] = { + 0xAF, 0x35, 0x2E, 0xD8, 0xAC, 0x6C, 0x55, 0x69, 0x06, 0x71, 0xE5, 0x13, + 0x68, 0x24, 0xB3, 0x4F, 0xD8, 0xCC, 0x21, 0x47, 0xF8, 0xF1, 0x60, 0x38, + 0x89, 0x89, 0x03, 0xE9, 0xBD, 0xEA, 0x5E, 0x46, 0x53, 0x09, 0xDC, 0x5C, + 0xF5, 0x5A, 0xE8, 0xF7, 0x45, 0x2A, 0x02, 0xEB, 0x31, 0x61, 0xD7, 0x29, + 0x33, 0x4C, 0xCE, 0xC7, 0x7C, 0x0A, 0x37, 0x7E, 0x0F, 0xBA, 0x32, 0x98, + 0xE1, 0x1D, 0x97, 0xAF, 0x8F, 0xC7, 0xDC, 0xC9, 0x38, 0x96, 0xF3, 0xDB, + 0x1A, 0xFC, 0x51, 0xED, 0x68, 0xC6, 0xD0, 0x6E, 0xA4, 0x7C, 0x24, 0xD1, + 0xAE, 0x42, 0xC8, 0x96, 0x50, 0x63, 0x2E, 0xE0, 0xFE, 0x75, 0xFE, 0x98, + 0xA7, 0x5F, 0x49, 0x2E, 0x95, 0xE3, 0x39, 0x33, 0x64, 0x8E, 0x1E, 0xA4, + 0x5F, 0x90, 0xD2, 0x67, 0x3C, 0xB2, 0xD9, 0xFE, 0x41, 0xB9, 0x55, 0xA7, + 0x09, 0x8E, 0x72, 0x05, 0x1E, 0x8B, 0xDD, 0x44, 0x85, 0x82, 0x42, 0xD0, + 0x49, 0xC0, 0x1D, 0x60, 0xF0, 0xD1, 0x17, 0x2C, 0x95, 0xEB, 0xF6, 0xA5, + 0xC1, 0x92, 0xA3, 0xC5, 0xC2, 0xA7, 0x08, 0x60, 0x0D, 0x60, 0x04, 0x10, + 0x96, 0x79, 0x9E, 0x16, 0x34, 0xE6, 0xA9, 0xB6, 0xFA, 0x25, 0x45, 0x39, + 0xC8, 0x1E, 0x65, 0xF9, 0x93, 0xF5, 0xAA, 0xF1, 0x52, 0xDC, 0x99, 0x98, + 0x3D, 0xA5, 0x86, 0x1A, 0x0C, 0x35, 0x33, 0xFA, 0x4B, 0xA5, 0x04, 0x06, + 0x15, 0x1C, 0x31, 0x80, 0xEF, 0xAA, 0x18, 0x6B, 0xC2, 0x7B, 0xD7, 0xDA, + 0xCE, 0xF9, 0x33, 0x20, 0xD5, 0xF5, 0xBD, 0x6A, 0x33, 0x2D, 0x81, 0x04, + 0xFB, 0xB0, 0x5C, 0xD4, 0x9C, 0xA3, 0xE2, 0x5C, 0x1D, 0xE3, 0xA9, 0x42, + 0x75, 0x5E, 0x7B, 0xD4, 0x77, 0xEF, 0x39, 0x54, 0xBA, 0xC9, 0x0A, 0x18, + 0x1B, 0x12, 0x99, 0x49, 0x2F, 0x88, 0x4B, 0xFD, 0x50, 0x62, 0xD1, 0x73, + 0xE7, 0x8F, 0x7A, 0x43 +}; + +static const unsigned char TA355_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA356_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x43, 0x41, 0x31 +}; + +static const unsigned char TA356_EC_Q[] = { + 0x04, 0xA4, 0xA5, 0x6F, 0x60, 0x03, 0x03, 0xC3, 0xBD, 0x31, 0xF4, 0xD3, + 0x17, 0x9C, 0x2B, 0x84, 0x75, 0xAC, 0xE5, 0xFD, 0x3D, 0x57, 0x6E, 0xD7, + 0x63, 0xBF, 0xE6, 0x04, 0x89, 0x92, 0x8E, 0x81, 0x9C, 0xE3, 0xE9, 0x47, + 0x6E, 0xCA, 0x90, 0x12, 0xC8, 0x13, 0xE0, 0xA7, 0x9D, 0xF7, 0x65, 0x74, + 0x1F, 0x6C, 0x10, 0xB2, 0xE8, 0xE4, 0xE9, 0xEF, 0x6D, 0x85, 0x32, 0x99, + 0x44, 0xB1, 0x5E, 0xFD, 0xCC, 0x76, 0x10, 0xD8, 0x5B, 0xBD, 0xA2, 0xC6, + 0xF9, 0xD6, 0x42, 0xE4, 0x57, 0x76, 0xDC, 0x90, 0xC2, 0x35, 0xA9, 0x4B, + 0x88, 0x3C, 0x12, 0x47, 0x6D, 0x5C, 0xFF, 0x49, 0x4F, 0x1A, 0x4A, 0x50, + 0xB1 +}; + +static const unsigned char TA357_DN[] = { + 0x30, 0x5D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x1E, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA357_RSA_N[] = { + 0xD0, 0x15, 0x39, 0x52, 0xB1, 0x52, 0xB3, 0xBA, 0xC5, 0x59, 0x82, 0xC4, + 0x5D, 0x52, 0xAE, 0x3A, 0x43, 0x65, 0x80, 0x4B, 0xC7, 0xF2, 0x96, 0xBC, + 0xDB, 0x36, 0x97, 0xD6, 0xA6, 0x64, 0x8C, 0xA8, 0x5E, 0xF0, 0xE3, 0x0A, + 0x1C, 0xF7, 0xDF, 0x97, 0x3D, 0x4B, 0xAE, 0xF6, 0x5D, 0xEC, 0x21, 0xB5, + 0x41, 0xAB, 0xCD, 0xB9, 0x7E, 0x76, 0x9F, 0xBE, 0xF9, 0x3E, 0x36, 0x34, + 0xA0, 0x3B, 0xC1, 0xF6, 0x31, 0x11, 0x45, 0x74, 0x93, 0x3D, 0x57, 0x80, + 0xC5, 0xF9, 0x89, 0x99, 0xCA, 0xE5, 0xAB, 0x6A, 0xD4, 0xB5, 0xDA, 0x41, + 0x90, 0x10, 0xC1, 0xD6, 0xD6, 0x42, 0x89, 0xC2, 0xBF, 0xF4, 0x38, 0x12, + 0x95, 0x4C, 0x54, 0x05, 0xF7, 0x36, 0xE4, 0x45, 0x83, 0x7B, 0x14, 0x65, + 0xD6, 0xDC, 0x0C, 0x4D, 0xD1, 0xDE, 0x7E, 0x0C, 0xAB, 0x3B, 0xC4, 0x15, + 0xBE, 0x3A, 0x56, 0xA6, 0x5A, 0x6F, 0x76, 0x69, 0x52, 0xA9, 0x7A, 0xB9, + 0xC8, 0xEB, 0x6A, 0x9A, 0x5D, 0x52, 0xD0, 0x2D, 0x0A, 0x6B, 0x35, 0x16, + 0x09, 0x10, 0x84, 0xD0, 0x6A, 0xCA, 0x3A, 0x06, 0x00, 0x37, 0x47, 0xE4, + 0x7E, 0x57, 0x4F, 0x3F, 0x8B, 0xEB, 0x67, 0xB8, 0x88, 0xAA, 0xC5, 0xBE, + 0x53, 0x55, 0xB2, 0x91, 0xC4, 0x7D, 0xB9, 0xB0, 0x85, 0x19, 0x06, 0x78, + 0x2E, 0xDB, 0x61, 0x1A, 0xFA, 0x85, 0xF5, 0x4A, 0x91, 0xA1, 0xE7, 0x16, + 0xD5, 0x8E, 0xA2, 0x39, 0xDF, 0x94, 0xB8, 0x70, 0x1F, 0x28, 0x3F, 0x8B, + 0xFC, 0x40, 0x5E, 0x63, 0x83, 0x3C, 0x83, 0x2A, 0x1A, 0x99, 0x6B, 0xCF, + 0xDE, 0x59, 0x6A, 0x3B, 0xFC, 0x6F, 0x16, 0xD7, 0x1F, 0xFD, 0x4A, 0x10, + 0xEB, 0x4E, 0x82, 0x16, 0x3A, 0xAC, 0x27, 0x0C, 0x53, 0xF1, 0xAD, 0xD5, + 0x24, 0xB0, 0x6B, 0x03, 0x50, 0xC1, 0x2D, 0x3C, 0x16, 0xDD, 0x44, 0x34, + 0x27, 0x1A, 0x75, 0xFB +}; + +static const unsigned char TA357_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA358_DN[] = { + 0x30, 0x68, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, + 0x6C, 0x64, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA358_RSA_N[] = { + 0xB7, 0x32, 0xC8, 0xFE, 0xE9, 0x71, 0xA6, 0x04, 0x85, 0xAD, 0x0C, 0x11, + 0x64, 0xDF, 0xCE, 0x4D, 0xEF, 0xC8, 0x03, 0x18, 0x87, 0x3F, 0xA1, 0xAB, + 0xFB, 0x3C, 0xA6, 0x9F, 0xF0, 0xC3, 0xA1, 0xDA, 0xD4, 0xD8, 0x6E, 0x2B, + 0x53, 0x90, 0xFB, 0x24, 0xA4, 0x3E, 0x84, 0xF0, 0x9E, 0xE8, 0x5F, 0xEC, + 0xE5, 0x27, 0x44, 0xF5, 0x28, 0xA6, 0x3F, 0x7B, 0xDE, 0xE0, 0x2A, 0xF0, + 0xC8, 0xAF, 0x53, 0x2F, 0x9E, 0xCA, 0x05, 0x01, 0x93, 0x1E, 0x8F, 0x66, + 0x1C, 0x39, 0xA7, 0x4D, 0xFA, 0x5A, 0xB6, 0x73, 0x04, 0x25, 0x66, 0xEB, + 0x77, 0x7F, 0xE7, 0x59, 0xC6, 0x4A, 0x99, 0x25, 0x14, 0x54, 0xEB, 0x26, + 0xC7, 0xF3, 0x7F, 0x19, 0xD5, 0x30, 0x70, 0x8F, 0xAF, 0xB0, 0x46, 0x2A, + 0xFF, 0xAD, 0xEB, 0x29, 0xED, 0xD7, 0x9F, 0xAA, 0x04, 0x87, 0xA3, 0xD4, + 0xF9, 0x89, 0xA5, 0x34, 0x5F, 0xDB, 0x43, 0x91, 0x82, 0x36, 0xD9, 0x66, + 0x3C, 0xB1, 0xB8, 0xB9, 0x82, 0xFD, 0x9C, 0x3A, 0x3E, 0x10, 0xC8, 0x3B, + 0xEF, 0x06, 0x65, 0x66, 0x7A, 0x9B, 0x19, 0x18, 0x3D, 0xFF, 0x71, 0x51, + 0x3C, 0x30, 0x2E, 0x5F, 0xBE, 0x3D, 0x77, 0x73, 0xB2, 0x5D, 0x06, 0x6C, + 0xC3, 0x23, 0x56, 0x9A, 0x2B, 0x85, 0x26, 0x92, 0x1C, 0xA7, 0x02, 0xB3, + 0xE4, 0x3F, 0x0D, 0xAF, 0x08, 0x79, 0x82, 0xB8, 0x36, 0x3D, 0xEA, 0x9C, + 0xD3, 0x35, 0xB3, 0xBC, 0x69, 0xCA, 0xF5, 0xCC, 0x9D, 0xE8, 0xFD, 0x64, + 0x8D, 0x17, 0x80, 0x33, 0x6E, 0x5E, 0x4A, 0x5D, 0x99, 0xC9, 0x1E, 0x87, + 0xB4, 0x9D, 0x1A, 0xC0, 0xD5, 0x6E, 0x13, 0x35, 0x23, 0x5E, 0xDF, 0x9B, + 0x5F, 0x3D, 0xEF, 0xD6, 0xF7, 0x76, 0xC2, 0xEA, 0x3E, 0xBB, 0x78, 0x0D, + 0x1C, 0x42, 0x67, 0x6B, 0x04, 0xD8, 0xF8, 0xD6, 0xDA, 0x6F, 0x8B, 0xF2, + 0x44, 0xA0, 0x01, 0xAB +}; + +static const unsigned char TA358_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA359_DN[] = { + 0x30, 0x81, 0x8F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, + 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA359_RSA_N[] = { + 0xBD, 0xED, 0xC1, 0x03, 0xFC, 0xF6, 0x8F, 0xFC, 0x02, 0xB1, 0x6F, 0x5B, + 0x9F, 0x48, 0xD9, 0x9D, 0x79, 0xE2, 0xA2, 0xB7, 0x03, 0x61, 0x56, 0x18, + 0xC3, 0x47, 0xB6, 0xD7, 0xCA, 0x3D, 0x35, 0x2E, 0x89, 0x43, 0xF7, 0xA1, + 0x69, 0x9B, 0xDE, 0x8A, 0x1A, 0xFD, 0x13, 0x20, 0x9C, 0xB4, 0x49, 0x77, + 0x32, 0x29, 0x56, 0xFD, 0xB9, 0xEC, 0x8C, 0xDD, 0x22, 0xFA, 0x72, 0xDC, + 0x27, 0x61, 0x97, 0xEE, 0xF6, 0x5A, 0x84, 0xEC, 0x6E, 0x19, 0xB9, 0x89, + 0x2C, 0xDC, 0x84, 0x5B, 0xD5, 0x74, 0xFB, 0x6B, 0x5F, 0xC5, 0x89, 0xA5, + 0x10, 0x52, 0x89, 0x46, 0x55, 0xF4, 0xB8, 0x75, 0x1C, 0xE6, 0x7F, 0xE4, + 0x54, 0xAE, 0x4B, 0xF8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xF8, 0x17, 0x71, + 0x59, 0xEB, 0x1E, 0x28, 0x07, 0x74, 0xC5, 0x9D, 0x48, 0xBE, 0x6C, 0xB4, + 0xF4, 0xA4, 0xB0, 0xF3, 0x64, 0x37, 0x79, 0x92, 0xC0, 0xEC, 0x46, 0x5E, + 0x7F, 0xE1, 0x6D, 0x53, 0x4C, 0x62, 0xAF, 0xCD, 0x1F, 0x0B, 0x63, 0xBB, + 0x3A, 0x9D, 0xFB, 0xFC, 0x79, 0x00, 0x98, 0x61, 0x74, 0xCF, 0x26, 0x82, + 0x40, 0x63, 0xF3, 0xB2, 0x72, 0x6A, 0x19, 0x0D, 0x99, 0xCA, 0xD4, 0x0E, + 0x75, 0xCC, 0x37, 0xFB, 0x8B, 0x89, 0xC1, 0x59, 0xF1, 0x62, 0x7F, 0x5F, + 0xB3, 0x5F, 0x65, 0x30, 0xF8, 0xA7, 0xB7, 0x4D, 0x76, 0x5A, 0x1E, 0x76, + 0x5E, 0x34, 0xC0, 0xE8, 0x96, 0x56, 0x99, 0x8A, 0xB3, 0xF0, 0x7F, 0xA4, + 0xCD, 0xBD, 0xDC, 0x32, 0x31, 0x7C, 0x91, 0xCF, 0xE0, 0x5F, 0x11, 0xF8, + 0x6B, 0xAA, 0x49, 0x5C, 0xD1, 0x99, 0x94, 0xD1, 0xA2, 0xE3, 0x63, 0x5B, + 0x09, 0x76, 0xB5, 0x56, 0x62, 0xE1, 0x4B, 0x74, 0x1D, 0x96, 0xD4, 0x26, + 0xD4, 0x08, 0x04, 0x59, 0xD0, 0x98, 0x0E, 0x0E, 0xE6, 0xDE, 0xFC, 0xC3, + 0xEC, 0x1F, 0x90, 0xF1 +}; + +static const unsigned char TA359_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA360_DN[] = { + 0x30, 0x81, 0x98, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3B, + 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA360_RSA_N[] = { + 0xD5, 0x0C, 0x3A, 0xC4, 0x2A, 0xF9, 0x4E, 0xE2, 0xF5, 0xBE, 0x19, 0x97, + 0x5F, 0x8E, 0x88, 0x53, 0xB1, 0x1F, 0x3F, 0xCB, 0xCF, 0x9F, 0x20, 0x13, + 0x6D, 0x29, 0x3A, 0xC8, 0x0F, 0x7D, 0x3C, 0xF7, 0x6B, 0x76, 0x38, 0x63, + 0xD9, 0x36, 0x60, 0xA8, 0x9B, 0x5E, 0x5C, 0x00, 0x80, 0xB2, 0x2F, 0x59, + 0x7F, 0xF6, 0x87, 0xF9, 0x25, 0x43, 0x86, 0xE7, 0x69, 0x1B, 0x52, 0x9A, + 0x90, 0xE1, 0x71, 0xE3, 0xD8, 0x2D, 0x0D, 0x4E, 0x6F, 0xF6, 0xC8, 0x49, + 0xD9, 0xB6, 0xF3, 0x1A, 0x56, 0xAE, 0x2B, 0xB6, 0x74, 0x14, 0xEB, 0xCF, + 0xFB, 0x26, 0xE3, 0x1A, 0xBA, 0x1D, 0x96, 0x2E, 0x6A, 0x3B, 0x58, 0x94, + 0x89, 0x47, 0x56, 0xFF, 0x25, 0xA0, 0x93, 0x70, 0x53, 0x83, 0xDA, 0x84, + 0x74, 0x14, 0xC3, 0x67, 0x9E, 0x04, 0x68, 0x3A, 0xDF, 0x8E, 0x40, 0x5A, + 0x1D, 0x4A, 0x4E, 0xCF, 0x43, 0x91, 0x3B, 0xE7, 0x56, 0xD6, 0x00, 0x70, + 0xCB, 0x52, 0xEE, 0x7B, 0x7D, 0xAE, 0x3A, 0xE7, 0xBC, 0x31, 0xF9, 0x45, + 0xF6, 0xC2, 0x60, 0xCF, 0x13, 0x59, 0x02, 0x2B, 0x80, 0xCC, 0x34, 0x47, + 0xDF, 0xB9, 0xDE, 0x90, 0x65, 0x6D, 0x02, 0xCF, 0x2C, 0x91, 0xA6, 0xA6, + 0xE7, 0xDE, 0x85, 0x18, 0x49, 0x7C, 0x66, 0x4E, 0xA3, 0x3A, 0x6D, 0xA9, + 0xB5, 0xEE, 0x34, 0x2E, 0xBA, 0x0D, 0x03, 0xB8, 0x33, 0xDF, 0x47, 0xEB, + 0xB1, 0x6B, 0x8D, 0x25, 0xD9, 0x9B, 0xCE, 0x81, 0xD1, 0x45, 0x46, 0x32, + 0x96, 0x70, 0x87, 0xDE, 0x02, 0x0E, 0x49, 0x43, 0x85, 0xB6, 0x6C, 0x73, + 0xBB, 0x64, 0xEA, 0x61, 0x41, 0xAC, 0xC9, 0xD4, 0x54, 0xDF, 0x87, 0x2F, + 0xC7, 0x22, 0xB2, 0x26, 0xCC, 0x9F, 0x59, 0x54, 0x68, 0x9F, 0xFC, 0xBE, + 0x2A, 0x2F, 0xC4, 0x55, 0x1C, 0x75, 0x40, 0x60, 0x17, 0x85, 0x02, 0x55, + 0x39, 0x8B, 0x7F, 0x05 +}; + +static const unsigned char TA360_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA361_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x41, 0x47, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x16, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, + 0x6F, 0x6C, 0x64, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA361_RSA_N[] = { + 0xAF, 0xE4, 0xEE, 0x7E, 0x8B, 0x24, 0x0E, 0x12, 0x6E, 0xA9, 0x50, 0x2D, + 0x16, 0x44, 0x3B, 0x92, 0x92, 0x5C, 0xCA, 0xB8, 0x5D, 0x84, 0x92, 0x42, + 0x13, 0x2A, 0xBC, 0x65, 0x57, 0x82, 0x40, 0x3E, 0x57, 0x24, 0xCD, 0x50, + 0x8B, 0x25, 0x2A, 0xB7, 0x6F, 0xFC, 0xEF, 0xA2, 0xD0, 0xC0, 0x1F, 0x02, + 0x24, 0x4A, 0x13, 0x96, 0x8F, 0x23, 0x13, 0xE6, 0x28, 0x58, 0x00, 0xA3, + 0x47, 0xC7, 0x06, 0xA7, 0x84, 0x23, 0x2B, 0xBB, 0xBD, 0x96, 0x2B, 0x7F, + 0x55, 0xCC, 0x8B, 0xC1, 0x57, 0x1F, 0x0E, 0x62, 0x65, 0x0F, 0xDD, 0x3D, + 0x56, 0x8A, 0x73, 0xDA, 0xAE, 0x7E, 0x6D, 0xBA, 0x81, 0x1C, 0x7E, 0x42, + 0x8C, 0x20, 0x35, 0xD9, 0x43, 0x4D, 0x84, 0xFA, 0x84, 0xDB, 0x52, 0x2C, + 0xF3, 0x0E, 0x27, 0x77, 0x0B, 0x6B, 0xBF, 0x11, 0x2F, 0x72, 0x78, 0x9F, + 0x2E, 0xD8, 0x3E, 0xE6, 0x18, 0x37, 0x5A, 0x2A, 0x72, 0xF9, 0xDA, 0x62, + 0x90, 0x92, 0x95, 0xCA, 0x1F, 0x9C, 0xE9, 0xB3, 0x3C, 0x2B, 0xCB, 0xF3, + 0x01, 0x13, 0xBF, 0x5A, 0xCF, 0xC1, 0xB5, 0x0A, 0x60, 0xBD, 0xDD, 0xB5, + 0x99, 0x64, 0x53, 0xB8, 0xA0, 0x96, 0xB3, 0x6F, 0xE2, 0x26, 0x77, 0x91, + 0x8C, 0xE0, 0x62, 0x10, 0x02, 0x9F, 0x34, 0x0F, 0xA4, 0xD5, 0x92, 0x33, + 0x51, 0xDE, 0xBE, 0x8D, 0xBA, 0x84, 0x7A, 0x60, 0x3C, 0x6A, 0xDB, 0x9F, + 0x2B, 0xEC, 0xDE, 0xDE, 0x01, 0x3F, 0x6E, 0x4D, 0xE5, 0x50, 0x86, 0xCB, + 0xB4, 0xAF, 0xED, 0x44, 0x40, 0xC5, 0xCA, 0x5A, 0x8C, 0xDA, 0xD2, 0x2B, + 0x7C, 0xA8, 0xEE, 0xBE, 0xA6, 0xE5, 0x0A, 0xAA, 0x0E, 0xA5, 0xDF, 0x05, + 0x52, 0xB7, 0x55, 0xC7, 0x22, 0x5D, 0x32, 0x6A, 0x97, 0x97, 0x63, 0x13, + 0xDB, 0xC9, 0xDB, 0x79, 0x36, 0x7B, 0x85, 0x3A, 0x4A, 0xC5, 0x52, 0x89, + 0xF9, 0x24, 0xE7, 0x9D, 0x77, 0xA9, 0x82, 0xFF, 0x55, 0x1C, 0xA5, 0x71, + 0x69, 0x2B, 0xD1, 0x02, 0x24, 0xF2, 0xB3, 0x26, 0xD4, 0x6B, 0xDA, 0x04, + 0x55, 0xE5, 0xC1, 0x0A, 0xC7, 0x6D, 0x30, 0x37, 0x90, 0x2A, 0xE4, 0x9E, + 0x14, 0x33, 0x5E, 0x16, 0x17, 0x55, 0xC5, 0x5B, 0xB5, 0xCB, 0x34, 0x89, + 0x92, 0xF1, 0x9D, 0x26, 0x8F, 0xA1, 0x07, 0xD4, 0xC6, 0xB2, 0x78, 0x50, + 0xDB, 0x0C, 0x0C, 0x0B, 0x7C, 0x0B, 0x8C, 0x41, 0xD7, 0xB9, 0xE9, 0xDD, + 0x8C, 0x88, 0xF7, 0xA3, 0x4D, 0xB2, 0x32, 0xCC, 0xD8, 0x17, 0xDA, 0xCD, + 0xB7, 0xCE, 0x66, 0x9D, 0xD4, 0xFD, 0x5E, 0xFF, 0xBD, 0x97, 0x3E, 0x29, + 0x75, 0xE7, 0x7E, 0xA7, 0x62, 0x58, 0xAF, 0x25, 0x34, 0xA5, 0x41, 0xC7, + 0x3D, 0xBC, 0x0D, 0x50, 0xCA, 0x03, 0x03, 0x0F, 0x08, 0x5A, 0x1F, 0x95, + 0x73, 0x78, 0x62, 0xBF, 0xAF, 0x72, 0x14, 0x69, 0x0E, 0xA5, 0xE5, 0x03, + 0x0E, 0x78, 0x8E, 0x26, 0x28, 0x42, 0xF0, 0x07, 0x0B, 0x62, 0x20, 0x10, + 0x67, 0x39, 0x46, 0xFA, 0xA9, 0x03, 0xCC, 0x04, 0x38, 0x7A, 0x66, 0xEF, + 0x20, 0x83, 0xB5, 0x8C, 0x4A, 0x56, 0x8E, 0x91, 0x00, 0xFC, 0x8E, 0x5C, + 0x82, 0xDE, 0x88, 0xA0, 0xC3, 0xE2, 0x68, 0x6E, 0x7D, 0x8D, 0xEF, 0x3C, + 0xDD, 0x65, 0xF4, 0x5D, 0xAC, 0x51, 0xEF, 0x24, 0x80, 0xAE, 0xAA, 0x56, + 0x97, 0x6F, 0xF9, 0xAD, 0x7D, 0xDA, 0x61, 0x3F, 0x98, 0x77, 0x3C, 0xA5, + 0x91, 0xB6, 0x1C, 0x8C, 0x26, 0xDA, 0x65, 0xA2, 0x09, 0x6D, 0xC1, 0xE2, + 0x54, 0xE3, 0xB9, 0xCA, 0x4C, 0x4C, 0x80, 0x8F, 0x77, 0x7B, 0x60, 0x9A, + 0x1E, 0xDF, 0xB6, 0xF2, 0x48, 0x1E, 0x0E, 0xBA, 0x4E, 0x54, 0x6D, 0x98, + 0xE0, 0xE1, 0xA2, 0x1A, 0xA2, 0x77, 0x50, 0xCF, 0xC4, 0x63, 0x92, 0xEC, + 0x47, 0x19, 0x9D, 0xEB, 0xE6, 0x6B, 0xCE, 0xC1 +}; + +static const unsigned char TA361_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA362_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x32 +}; + +static const unsigned char TA362_RSA_N[] = { + 0xAA, 0x5F, 0xDA, 0x1B, 0x5F, 0xE8, 0x73, 0x91, 0xE5, 0xDA, 0x5C, 0xF4, + 0xA2, 0xE6, 0x47, 0xE5, 0xF3, 0x68, 0x55, 0x60, 0x05, 0x1D, 0x02, 0xA4, + 0xB3, 0x9B, 0x59, 0xF3, 0x1E, 0x8A, 0xAF, 0x34, 0xAD, 0xFC, 0x0D, 0xC2, + 0xD9, 0x48, 0x19, 0xEE, 0x69, 0x8F, 0xC9, 0x20, 0xFC, 0x21, 0xAA, 0x07, + 0x19, 0xED, 0xB0, 0x5C, 0xAC, 0x65, 0xC7, 0x5F, 0xED, 0x02, 0x7C, 0x7B, + 0x7C, 0x2D, 0x1B, 0xD6, 0xBA, 0xB9, 0x80, 0xC2, 0x18, 0x82, 0x16, 0x84, + 0xFA, 0x66, 0xB0, 0x08, 0xC6, 0x54, 0x23, 0x81, 0xE4, 0xCD, 0xB9, 0x49, + 0x3F, 0xF6, 0x4F, 0x6E, 0x37, 0x48, 0x28, 0x38, 0x0F, 0xC5, 0xBE, 0xE7, + 0x68, 0x70, 0xFD, 0x39, 0x97, 0x4D, 0xD2, 0xC7, 0x98, 0x91, 0x50, 0xAA, + 0xC4, 0x44, 0xB3, 0x23, 0x7D, 0x39, 0x47, 0xE9, 0x52, 0x62, 0xD6, 0x12, + 0x93, 0x5E, 0xB7, 0x31, 0x96, 0x42, 0x05, 0xFB, 0x76, 0xA7, 0x1E, 0xA3, + 0xF5, 0xC2, 0xFC, 0xE9, 0x7A, 0xC5, 0x6C, 0xA9, 0x71, 0x4F, 0xEA, 0xCB, + 0x78, 0xBC, 0x60, 0xAF, 0xC7, 0xDE, 0xF4, 0xD9, 0xCB, 0xBE, 0x7E, 0x33, + 0xA5, 0x6E, 0x94, 0x83, 0xF0, 0x34, 0xFA, 0x21, 0xAB, 0xEA, 0x8E, 0x72, + 0xA0, 0x3F, 0xA4, 0xDE, 0x30, 0x5B, 0xEF, 0x86, 0x4D, 0x6A, 0x95, 0x5B, + 0x43, 0x44, 0xA8, 0x10, 0x15, 0x1C, 0xE5, 0x01, 0x57, 0xC5, 0x98, 0xF1, + 0xE6, 0x06, 0x28, 0x91, 0xAA, 0x20, 0xC5, 0xB7, 0x53, 0x26, 0x51, 0x43, + 0xB2, 0x0B, 0x11, 0x95, 0x58, 0xE1, 0xC0, 0x0F, 0x76, 0xD9, 0xC0, 0x8D, + 0x7C, 0x81, 0xF3, 0x72, 0x70, 0x9E, 0x6F, 0xFE, 0x1A, 0x8E, 0xD9, 0x5F, + 0x35, 0xC6, 0xB2, 0x6F, 0x34, 0x7C, 0xBE, 0x48, 0x4F, 0xE2, 0x5A, 0x39, + 0xD7, 0xD8, 0x9D, 0x78, 0x9E, 0x9F, 0x86, 0x3E, 0x03, 0x5E, 0x19, 0x8B, + 0x44, 0xA2, 0xD5, 0xC7 +}; + +static const unsigned char TA362_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA363_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x33 +}; + +static const unsigned char TA363_RSA_N[] = { + 0xBD, 0x75, 0x93, 0xF0, 0x62, 0x22, 0x6F, 0x24, 0xAE, 0xE0, 0x7A, 0x76, + 0xAC, 0x7D, 0xBD, 0xD9, 0x24, 0xD5, 0xB8, 0xB7, 0xFC, 0xCD, 0xF0, 0x42, + 0xE0, 0xEB, 0x78, 0x88, 0x56, 0x5E, 0x9B, 0x9A, 0x54, 0x1D, 0x4D, 0x0C, + 0x8A, 0xF6, 0xD3, 0xCF, 0x70, 0xF4, 0x52, 0xB5, 0xD8, 0x93, 0x04, 0xE3, + 0x46, 0x86, 0x71, 0x41, 0x4A, 0x2B, 0xF0, 0x2A, 0x2C, 0x55, 0x03, 0xD6, + 0x48, 0xC3, 0xE0, 0x39, 0x38, 0xED, 0xF2, 0x5C, 0x3C, 0x3F, 0x44, 0xBC, + 0x93, 0x3D, 0x61, 0xAB, 0x4E, 0xCD, 0x0D, 0xBE, 0xF0, 0x20, 0x27, 0x58, + 0x0E, 0x44, 0x7F, 0x04, 0x1A, 0x87, 0xA5, 0xD7, 0x96, 0x14, 0x36, 0x90, + 0xD0, 0x49, 0x7B, 0xA1, 0x75, 0xFB, 0x1A, 0x6B, 0x73, 0xB1, 0xF8, 0xCE, + 0xA9, 0x09, 0x2C, 0xF2, 0x53, 0xD5, 0xC3, 0x14, 0x44, 0xB8, 0x86, 0xA5, + 0xF6, 0x8B, 0x2B, 0x39, 0xDA, 0xA3, 0x33, 0x54, 0xD9, 0xFA, 0x72, 0x1A, + 0xF7, 0x22, 0x15, 0x1C, 0x88, 0x91, 0x6B, 0x7F, 0x66, 0xE5, 0xC3, 0x6A, + 0x80, 0xB0, 0x24, 0xF3, 0xDF, 0x86, 0x45, 0x88, 0xFD, 0x19, 0x7F, 0x75, + 0x87, 0x1F, 0x1F, 0xB1, 0x1B, 0x0A, 0x73, 0x24, 0x5B, 0xB9, 0x65, 0xE0, + 0x2C, 0x54, 0xC8, 0x60, 0xD3, 0x66, 0x17, 0x3F, 0xE1, 0xCC, 0x54, 0x33, + 0x73, 0x91, 0x02, 0x3A, 0xA6, 0x7F, 0x7B, 0x76, 0x39, 0xA2, 0x1F, 0x96, + 0xB6, 0x38, 0xAE, 0xB5, 0xC8, 0x93, 0x74, 0x1D, 0x9E, 0xB9, 0xB4, 0xE5, + 0x60, 0x9D, 0x2F, 0x56, 0xD1, 0xE0, 0xEB, 0x5E, 0x5B, 0x4C, 0x12, 0x70, + 0x0C, 0x6C, 0x44, 0x20, 0xAB, 0x11, 0xD8, 0xF4, 0x19, 0xF6, 0xD2, 0x9C, + 0x52, 0x37, 0xE7, 0xFA, 0xB6, 0xC2, 0x31, 0x3B, 0x4A, 0xD4, 0x14, 0x99, + 0xAD, 0xC7, 0x1A, 0xF5, 0x5D, 0x5F, 0xFA, 0x07, 0xB8, 0x7C, 0x0D, 0x1F, + 0xD6, 0x83, 0x1E, 0xB3 +}; + +static const unsigned char TA363_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA364_DN[] = { + 0x30, 0x81, 0xD2, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x54, 0x52, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x0F, 0x47, 0x65, 0x62, 0x7A, 0x65, 0x20, 0x2D, 0x20, 0x4B, + 0x6F, 0x63, 0x61, 0x65, 0x6C, 0x69, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x13, 0x39, 0x54, 0x75, 0x72, 0x6B, 0x69, 0x79, 0x65, + 0x20, 0x42, 0x69, 0x6C, 0x69, 0x6D, 0x73, 0x65, 0x6C, 0x20, 0x76, 0x65, + 0x20, 0x54, 0x65, 0x6B, 0x6E, 0x6F, 0x6C, 0x6F, 0x6A, 0x69, 0x6B, 0x20, + 0x41, 0x72, 0x61, 0x73, 0x74, 0x69, 0x72, 0x6D, 0x61, 0x20, 0x4B, 0x75, + 0x72, 0x75, 0x6D, 0x75, 0x20, 0x2D, 0x20, 0x54, 0x55, 0x42, 0x49, 0x54, + 0x41, 0x4B, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x24, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x6B, 0x61, 0x73, 0x79, 0x6F, 0x6E, 0x20, 0x4D, 0x65, 0x72, 0x6B, + 0x65, 0x7A, 0x69, 0x20, 0x2D, 0x20, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, + 0x4D, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, + 0x54, 0x55, 0x42, 0x49, 0x54, 0x41, 0x4B, 0x20, 0x4B, 0x61, 0x6D, 0x75, + 0x20, 0x53, 0x4D, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x4B, 0x6F, 0x6B, 0x20, + 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6B, 0x61, 0x73, 0x69, 0x20, + 0x2D, 0x20, 0x53, 0x75, 0x72, 0x75, 0x6D, 0x20, 0x31 +}; + +static const unsigned char TA364_RSA_N[] = { + 0xAF, 0x75, 0x30, 0x33, 0xAA, 0xBB, 0x6B, 0xD3, 0x99, 0x2C, 0x12, 0x37, + 0x84, 0xD9, 0x8D, 0x7B, 0x97, 0x80, 0xD3, 0x6E, 0xE7, 0xFF, 0x9B, 0x50, + 0x95, 0x3E, 0x90, 0x95, 0x56, 0x42, 0xD7, 0x19, 0x7C, 0x26, 0x84, 0x8D, + 0x92, 0xFA, 0x01, 0x1D, 0x3A, 0x0F, 0xE2, 0x64, 0x38, 0xB7, 0x8C, 0xBC, + 0xE8, 0x88, 0xF9, 0x8B, 0x24, 0xAB, 0x2E, 0xA3, 0xF5, 0x37, 0xE4, 0x40, + 0x8E, 0x18, 0x25, 0x79, 0x83, 0x75, 0x1F, 0x3B, 0xFF, 0x6C, 0xA8, 0xC5, + 0xC6, 0x56, 0xF8, 0xB4, 0xED, 0x8A, 0x44, 0xA3, 0xAB, 0x6C, 0x4C, 0xFC, + 0x1D, 0xD0, 0xDC, 0xEF, 0x68, 0xBD, 0xCF, 0xE4, 0xAA, 0xCE, 0xF0, 0x55, + 0xF7, 0xA2, 0x34, 0xD4, 0x83, 0x6B, 0x37, 0x7C, 0x1C, 0xC2, 0xFE, 0xB5, + 0x03, 0xEC, 0x57, 0xCE, 0xBC, 0xB4, 0xB5, 0xC5, 0xED, 0x00, 0x0F, 0x53, + 0x37, 0x2A, 0x4D, 0xF4, 0x4F, 0x0C, 0x83, 0xFB, 0x86, 0xCF, 0xCB, 0xFE, + 0x8C, 0x4E, 0xBD, 0x87, 0xF9, 0xA7, 0x8B, 0x21, 0x57, 0x9C, 0x7A, 0xDF, + 0x03, 0x67, 0x89, 0x2C, 0x9D, 0x97, 0x61, 0xA7, 0x10, 0xB8, 0x55, 0x90, + 0x7F, 0x0E, 0x2D, 0x27, 0x38, 0x74, 0xDF, 0xE7, 0xFD, 0xDA, 0x4E, 0x12, + 0xE3, 0x4D, 0x15, 0x22, 0x02, 0xC8, 0xE0, 0xE0, 0xFC, 0x0F, 0xAD, 0x8A, + 0xD7, 0xC9, 0x54, 0x50, 0xCC, 0x3B, 0x0F, 0xCA, 0x16, 0x80, 0x84, 0xD0, + 0x51, 0x56, 0xC3, 0x8E, 0x56, 0x7F, 0x89, 0x22, 0x33, 0x2F, 0xE6, 0x85, + 0x0A, 0xBD, 0xA5, 0xA8, 0x1B, 0x36, 0xDE, 0xD3, 0xDC, 0x2C, 0x6D, 0x3B, + 0xC7, 0x13, 0xBD, 0x59, 0x23, 0x2C, 0xE6, 0xE5, 0xA4, 0xF7, 0xD8, 0x0B, + 0xED, 0xEA, 0x90, 0x40, 0x44, 0xA8, 0x95, 0xBB, 0x93, 0xD5, 0xD0, 0x80, + 0x34, 0xB6, 0x46, 0x78, 0x0E, 0x1F, 0x00, 0x93, 0x46, 0xE1, 0xEE, 0xE9, + 0xF9, 0xEC, 0x4F, 0x17 +}; + +static const unsigned char TA364_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA365_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x54, 0x57, 0x43, 0x41, 0x20, 0x43, 0x59, 0x42, + 0x45, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA365_RSA_N[] = { + 0xC6, 0xF8, 0xCA, 0x1E, 0xD9, 0x09, 0x20, 0x7E, 0x1D, 0x6C, 0x4E, 0xCE, + 0x8F, 0xE3, 0x47, 0x33, 0x44, 0x9C, 0xC7, 0xC9, 0x69, 0xAA, 0x3A, 0x5B, + 0x78, 0xEE, 0x70, 0xD2, 0x92, 0xF8, 0x04, 0xB3, 0x52, 0x52, 0x1D, 0x67, + 0x72, 0x28, 0xA1, 0xDF, 0x8B, 0x5D, 0x95, 0x0A, 0xFE, 0xEA, 0xCD, 0xED, + 0xF7, 0x29, 0xCE, 0xF0, 0x6F, 0x7F, 0xAC, 0xCD, 0x3D, 0xEF, 0xB3, 0x1C, + 0x45, 0x6A, 0xF7, 0x28, 0x90, 0xF1, 0x61, 0x57, 0xC5, 0x0C, 0xC4, 0xA3, + 0x50, 0x5D, 0xDE, 0xD4, 0xB5, 0xCB, 0x19, 0xCA, 0x80, 0xB9, 0x75, 0xCE, + 0x29, 0xCE, 0xD2, 0x85, 0x22, 0xEC, 0x02, 0x63, 0xCC, 0x44, 0x30, 0x20, + 0xDA, 0xEA, 0x91, 0x5B, 0x56, 0xE6, 0x1D, 0x1C, 0xD5, 0x9D, 0x66, 0xC7, + 0x3F, 0xDF, 0x86, 0xCA, 0x4B, 0x53, 0xC4, 0xD9, 0x8D, 0xB2, 0x1D, 0xEA, + 0xF8, 0xDC, 0x27, 0x53, 0xA3, 0x47, 0xE1, 0x61, 0xCC, 0x7D, 0xB5, 0xB0, + 0xF8, 0xEE, 0x73, 0x91, 0xC5, 0xCE, 0x73, 0x6F, 0xCE, 0xEE, 0x10, 0x1F, + 0x1A, 0x06, 0xCF, 0xE9, 0x27, 0x60, 0xC5, 0x4F, 0x19, 0xE4, 0xEB, 0xCE, + 0x22, 0x26, 0x45, 0xD7, 0x60, 0x99, 0xDD, 0xCE, 0x4F, 0x37, 0xE0, 0x7F, + 0xE7, 0x63, 0xAD, 0xB0, 0xB8, 0x59, 0xB8, 0xD0, 0x06, 0x68, 0x35, 0x60, + 0xD3, 0x36, 0xAE, 0x71, 0x43, 0x04, 0xF1, 0x69, 0x65, 0x78, 0x7C, 0xF3, + 0x1F, 0xF3, 0xCA, 0x28, 0x9F, 0x5A, 0x20, 0x95, 0x66, 0xB4, 0xCD, 0xB7, + 0xEE, 0x8F, 0x78, 0xA4, 0x45, 0x18, 0xE9, 0x26, 0x2F, 0x8D, 0x9B, 0x29, + 0x28, 0xB1, 0xA4, 0xB7, 0x3A, 0x6D, 0xB9, 0xD4, 0x1C, 0x38, 0x72, 0x45, + 0x58, 0xB1, 0x5E, 0xEB, 0xF0, 0x28, 0x9B, 0xB7, 0x82, 0xCA, 0xFD, 0xCF, + 0xD6, 0x33, 0x0F, 0x9F, 0xFB, 0x97, 0x9E, 0xB1, 0x1C, 0x9C, 0x9E, 0xEA, + 0x5F, 0x5E, 0xDB, 0xAA, 0xDD, 0x54, 0xE9, 0x30, 0x21, 0x28, 0x6D, 0x8E, + 0x79, 0xF3, 0x75, 0x92, 0x8C, 0x26, 0xFE, 0xDC, 0xC5, 0xF6, 0xC3, 0xB0, + 0xDF, 0x44, 0x59, 0x43, 0xA3, 0xB6, 0x03, 0x28, 0xF6, 0x08, 0x30, 0xAA, + 0x0D, 0x33, 0xE1, 0xEF, 0x9C, 0xA9, 0x07, 0x22, 0xE3, 0x59, 0x5B, 0x40, + 0x8F, 0xDA, 0x88, 0xB7, 0x69, 0x08, 0xA8, 0xB7, 0x23, 0x2E, 0x44, 0x09, + 0x59, 0x37, 0x5B, 0xC7, 0xE3, 0x17, 0xF2, 0x22, 0xEB, 0x6E, 0x39, 0x52, + 0xC5, 0xDE, 0x54, 0xA7, 0x98, 0xC9, 0x4B, 0x20, 0x95, 0xDC, 0x46, 0x89, + 0x5F, 0xB4, 0x12, 0xF9, 0x85, 0x29, 0x8E, 0xEB, 0xC8, 0x27, 0x15, 0x20, + 0xC0, 0x4B, 0xD4, 0xCC, 0x7C, 0x0C, 0x6C, 0x34, 0x0C, 0x26, 0x9B, 0x26, + 0x31, 0xA6, 0x3C, 0xA7, 0xF6, 0xD9, 0xD0, 0x4B, 0xA2, 0x64, 0xFF, 0x3B, + 0x99, 0x41, 0x72, 0xC1, 0xE0, 0x70, 0x97, 0xF1, 0x24, 0xBB, 0x2B, 0xC4, + 0x74, 0x22, 0xB1, 0xAC, 0x6B, 0x22, 0x32, 0x24, 0xD3, 0x78, 0x2A, 0xC0, + 0xC0, 0xA1, 0x2F, 0xF1, 0x52, 0x05, 0xC9, 0x3F, 0xEF, 0x76, 0x66, 0xE2, + 0x45, 0xD8, 0x0D, 0x3D, 0xAD, 0x95, 0xC8, 0xC7, 0x89, 0x26, 0xC8, 0x0F, + 0xAE, 0xA7, 0x03, 0x2E, 0xFB, 0xC1, 0x5F, 0xFA, 0x20, 0xE1, 0x70, 0xAD, + 0xB0, 0x65, 0x20, 0x37, 0x33, 0x60, 0xB0, 0xD5, 0xAF, 0xD7, 0x0C, 0x1C, + 0xC2, 0x90, 0x70, 0xD7, 0x4A, 0x18, 0xBC, 0x7E, 0x01, 0xB0, 0xB0, 0xEB, + 0x15, 0x1E, 0x44, 0x06, 0xCD, 0xA4, 0x4F, 0xE8, 0x0C, 0xD1, 0xC3, 0x20, + 0x10, 0xE1, 0x54, 0x65, 0x9E, 0xB6, 0x51, 0xD0, 0x1A, 0x76, 0x6B, 0x42, + 0x5A, 0x58, 0x76, 0x34, 0xEA, 0xB7, 0x37, 0x19, 0xAE, 0x2E, 0x75, 0xF9, + 0x96, 0xE5, 0xC1, 0x59, 0xF7, 0x94, 0x57, 0x29, 0x25, 0x8D, 0x3A, 0x4C, + 0xAB, 0x4D, 0x9A, 0x41, 0xD0, 0x5F, 0x26, 0x03 +}; + +static const unsigned char TA365_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA366_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x13, 0x54, 0x57, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, + 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA366_RSA_N[] = { + 0xB0, 0x05, 0xDB, 0xC8, 0xEB, 0x8C, 0xC4, 0x6E, 0x8A, 0x21, 0xEF, 0x8E, + 0x4D, 0x9C, 0x71, 0x0A, 0x1F, 0x52, 0x70, 0xED, 0x6D, 0x82, 0x9C, 0x97, + 0xC5, 0xD7, 0x4C, 0x4E, 0x45, 0x49, 0xCB, 0x40, 0x42, 0xB5, 0x12, 0x34, + 0x6C, 0x19, 0xC2, 0x74, 0xA4, 0x31, 0x5F, 0x85, 0x02, 0x97, 0xEC, 0x43, + 0x33, 0x0A, 0x53, 0xD2, 0x9C, 0x8C, 0x8E, 0xB7, 0xB8, 0x79, 0xDB, 0x2B, + 0xD5, 0x6A, 0xF2, 0x8E, 0x66, 0xC4, 0xEE, 0x2B, 0x01, 0x07, 0x92, 0xD4, + 0xB3, 0xD0, 0x02, 0xDF, 0x50, 0xF6, 0x55, 0xAF, 0x66, 0x0E, 0xCB, 0xE0, + 0x47, 0x60, 0x2F, 0x2B, 0x32, 0x39, 0x35, 0x52, 0x3A, 0x28, 0x83, 0xF8, + 0x7B, 0x16, 0xC6, 0x18, 0xB8, 0x62, 0xD6, 0x47, 0x25, 0x91, 0xCE, 0xF0, + 0x19, 0x12, 0x4D, 0xAD, 0x63, 0xF5, 0xD3, 0x3F, 0x75, 0x5F, 0x29, 0xF0, + 0xA1, 0x30, 0x1C, 0x2A, 0xA0, 0x98, 0xA6, 0x15, 0xBD, 0xEE, 0xFD, 0x19, + 0x36, 0xF0, 0xE2, 0x91, 0x43, 0x8F, 0xFA, 0xCA, 0xD6, 0x10, 0x27, 0x49, + 0x4C, 0xEF, 0xDD, 0xC1, 0xF1, 0x85, 0x70, 0x9B, 0xCA, 0xEA, 0xA8, 0x5A, + 0x43, 0xFC, 0x6D, 0x86, 0x6F, 0x73, 0xE9, 0x37, 0x45, 0xA9, 0xF0, 0x36, + 0xC7, 0xCC, 0x88, 0x75, 0x1E, 0xBB, 0x6C, 0x06, 0xFF, 0x9B, 0x6B, 0x3E, + 0x17, 0xEC, 0x61, 0xAA, 0x71, 0x7C, 0xC6, 0x1D, 0xA2, 0xF7, 0x49, 0xE9, + 0x15, 0xB5, 0x3C, 0xD6, 0xA1, 0x61, 0xF5, 0x11, 0xF7, 0x05, 0x6F, 0x1D, + 0xFD, 0x11, 0xBE, 0xD0, 0x30, 0x07, 0xC2, 0x29, 0xB0, 0x09, 0x4E, 0x26, + 0xDC, 0xE3, 0xA2, 0xA8, 0x91, 0x6A, 0x1F, 0xC2, 0x91, 0x45, 0x88, 0x5C, + 0xE5, 0x98, 0xB8, 0x71, 0xA5, 0x15, 0x19, 0xC9, 0x7C, 0x75, 0x11, 0xCC, + 0x70, 0x74, 0x4F, 0x2D, 0x9B, 0x1D, 0x91, 0x44, 0xFD, 0x56, 0x28, 0xA0, + 0xFE, 0xBB, 0x86, 0x6A, 0xC8, 0xFA, 0x5C, 0x0B, 0x58, 0xDC, 0xC6, 0x4B, + 0x76, 0xC8, 0xAB, 0x22, 0xD9, 0x73, 0x0F, 0xA5, 0xF4, 0x5A, 0x02, 0x89, + 0x3F, 0x4F, 0x9E, 0x22, 0x82, 0xEE, 0xA2, 0x74, 0x53, 0x2A, 0x3D, 0x53, + 0x27, 0x69, 0x1D, 0x6C, 0x8E, 0x32, 0x2C, 0x64, 0x00, 0x26, 0x63, 0x61, + 0x36, 0x4E, 0xA3, 0x46, 0xB7, 0x3F, 0x7D, 0xB3, 0x2D, 0xAC, 0x6D, 0x90, + 0xA2, 0x95, 0xA2, 0xCE, 0xCF, 0xDA, 0x82, 0xE7, 0x07, 0x34, 0x19, 0x96, + 0xE9, 0xB8, 0x21, 0xAA, 0x29, 0x7E, 0xA6, 0x38, 0xBE, 0x8E, 0x29, 0x4A, + 0x21, 0x66, 0x79, 0x1F, 0xB3, 0xC3, 0xB5, 0x09, 0x67, 0xDE, 0xD6, 0xD4, + 0x07, 0x46, 0xF3, 0x2A, 0xDA, 0xE6, 0x22, 0x37, 0x60, 0xCB, 0x81, 0xB6, + 0x0F, 0xA0, 0x0F, 0xE9, 0xC8, 0x95, 0x7F, 0xBF, 0x55, 0x91, 0x05, 0x7A, + 0xCF, 0x3D, 0x15, 0xC0, 0x6F, 0xDE, 0x09, 0x94, 0x01, 0x83, 0xD7, 0x34, + 0x1B, 0xCC, 0x40, 0xA5, 0xF0, 0xB8, 0x9B, 0x67, 0xD5, 0x98, 0x91, 0x3B, + 0xA7, 0x84, 0x78, 0x95, 0x26, 0xA4, 0x5A, 0x08, 0xF8, 0x2B, 0x74, 0xB4, + 0x00, 0x04, 0x3C, 0xDF, 0xB8, 0x14, 0x8E, 0xE8, 0xDF, 0xA9, 0x8D, 0x6C, + 0x67, 0x92, 0x33, 0x1D, 0xC0, 0xB7, 0xD2, 0xEC, 0x92, 0xC8, 0xBE, 0x09, + 0xBF, 0x2C, 0x29, 0x05, 0x6F, 0x02, 0x6B, 0x9E, 0xEF, 0xBC, 0xBF, 0x2A, + 0xBC, 0x5B, 0xC0, 0x50, 0x8F, 0x41, 0x70, 0x71, 0x87, 0xB2, 0x4D, 0xB7, + 0x04, 0xA9, 0x84, 0xA3, 0x32, 0xAF, 0xAE, 0xEE, 0x6B, 0x17, 0x8B, 0xB2, + 0xB1, 0xFE, 0x6C, 0xE1, 0x90, 0x8C, 0x88, 0xA8, 0x97, 0x48, 0xCE, 0xC8, + 0x4D, 0xCB, 0xF3, 0x06, 0xCF, 0x5F, 0x6A, 0x0A, 0x42, 0xB1, 0x1E, 0x1E, + 0x77, 0x2F, 0x8E, 0xA0, 0xE6, 0x92, 0x0E, 0x06, 0xFC, 0x05, 0x22, 0xD2, + 0x26, 0xE1, 0x31, 0x51, 0x7D, 0x32, 0xDC, 0x0F +}; + +static const unsigned char TA366_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA367_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x21, 0x54, 0x57, 0x43, 0x41, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA367_RSA_N[] = { + 0xB0, 0x7E, 0x72, 0xB8, 0xA4, 0x03, 0x94, 0xE6, 0xA7, 0xDE, 0x09, 0x38, + 0x91, 0x4A, 0x11, 0x40, 0x87, 0xA7, 0x7C, 0x59, 0x64, 0x14, 0x7B, 0xB5, + 0x11, 0x10, 0xDD, 0xFE, 0xBF, 0xD5, 0xC0, 0xBB, 0x56, 0xE2, 0x85, 0x25, + 0xF4, 0x35, 0x72, 0x0F, 0xF8, 0x53, 0xD0, 0x41, 0xE1, 0x44, 0x01, 0xC2, + 0xB4, 0x1C, 0xC3, 0x31, 0x42, 0x16, 0x47, 0x85, 0x33, 0x22, 0x76, 0xB2, + 0x0A, 0x6F, 0x0F, 0xE5, 0x25, 0x50, 0x4F, 0x85, 0x86, 0xBE, 0xBF, 0x98, + 0x2E, 0x10, 0x67, 0x1E, 0xBE, 0x11, 0x05, 0x86, 0x05, 0x90, 0xC4, 0x59, + 0xD0, 0x7C, 0x78, 0x10, 0xB0, 0x80, 0x5C, 0xB7, 0xE1, 0xC7, 0x2B, 0x75, + 0xCB, 0x7C, 0x9F, 0xAE, 0xB5, 0xD1, 0x9D, 0x23, 0x37, 0x63, 0xA7, 0xDC, + 0x42, 0xA2, 0x2D, 0x92, 0x04, 0x1B, 0x50, 0xC1, 0x7B, 0xB8, 0x3E, 0x1B, + 0xC9, 0x56, 0x04, 0x8B, 0x2F, 0x52, 0x9B, 0xAD, 0xA9, 0x56, 0xE9, 0xC1, + 0xFF, 0xAD, 0xA9, 0x58, 0x87, 0x30, 0xB6, 0x81, 0xF7, 0x97, 0x45, 0xFC, + 0x19, 0x57, 0x3B, 0x2B, 0x6F, 0xE4, 0x47, 0xF4, 0x99, 0x45, 0xFE, 0x1D, + 0xF1, 0xF8, 0x97, 0xA3, 0x88, 0x1D, 0x37, 0x1C, 0x5C, 0x8F, 0xE0, 0x76, + 0x25, 0x9A, 0x50, 0xF8, 0xA0, 0x54, 0xFF, 0x44, 0x90, 0x76, 0x23, 0xD2, + 0x32, 0xC6, 0xC3, 0xAB, 0x06, 0xBF, 0xFC, 0xFB, 0xBF, 0xF3, 0xAD, 0x7D, + 0x92, 0x62, 0x02, 0x5B, 0x29, 0xD3, 0x35, 0xA3, 0x93, 0x9A, 0x43, 0x64, + 0x60, 0x5D, 0xB2, 0xFA, 0x32, 0xFF, 0x3B, 0x04, 0xAF, 0x4D, 0x40, 0x6A, + 0xF9, 0xC7, 0xE3, 0xEF, 0x23, 0xFD, 0x6B, 0xCB, 0xE5, 0x0F, 0x8B, 0x38, + 0x0D, 0xEE, 0x0A, 0xFC, 0xFE, 0x0F, 0x98, 0x9F, 0x30, 0x31, 0xDD, 0x6C, + 0x52, 0x65, 0xF9, 0x8B, 0x81, 0xBE, 0x22, 0xE1, 0x1C, 0x58, 0x03, 0xBA, + 0x91, 0x1B, 0x89, 0x07 +}; + +static const unsigned char TA367_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA368_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA368_EC_Q[] = { + 0x04, 0xCE, 0xBF, 0xFE, 0x57, 0xA8, 0xBF, 0xD5, 0xAA, 0xF7, 0x10, 0x9A, + 0xCD, 0xBC, 0xD1, 0x11, 0xA2, 0xBD, 0x67, 0x42, 0xCC, 0x90, 0xEB, 0x15, + 0x18, 0x90, 0xD9, 0xA2, 0xCD, 0x0C, 0x2A, 0x25, 0xEB, 0x3E, 0x4F, 0xCE, + 0xB5, 0xD2, 0x8F, 0x0F, 0xF3, 0x35, 0xDA, 0x43, 0x8B, 0x02, 0x80, 0xBE, + 0x6F, 0x51, 0x24, 0x1D, 0x0F, 0x6B, 0x2B, 0xCA, 0x9F, 0xC2, 0x6F, 0x50, + 0x32, 0xE5, 0x37, 0x20, 0xB6, 0x20, 0xFF, 0x88, 0x0D, 0x0F, 0x6D, 0x49, + 0xBB, 0xDB, 0x06, 0xA4, 0x87, 0x90, 0x92, 0x94, 0xF4, 0x09, 0xD0, 0xCF, + 0x7F, 0xC8, 0x80, 0x0B, 0xC1, 0x97, 0xB3, 0xBB, 0x35, 0x27, 0xC9, 0xC2, + 0x1B +}; + +static const unsigned char TA369_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x33 +}; + +static const unsigned char TA369_RSA_N[] = { + 0xED, 0x35, 0xA1, 0x81, 0x80, 0xF3, 0xCB, 0x4A, 0x69, 0x5B, 0xC2, 0xFB, + 0x51, 0x83, 0xAE, 0x26, 0xFD, 0xE1, 0x6E, 0xF3, 0x81, 0x12, 0x7D, 0x71, + 0x40, 0xFF, 0x87, 0x75, 0x42, 0x29, 0x21, 0xED, 0x81, 0x52, 0x2C, 0xDF, + 0x12, 0xC1, 0x19, 0x84, 0x89, 0xC1, 0xBD, 0xC5, 0x28, 0xD5, 0xD5, 0x4B, + 0x6C, 0x44, 0xD6, 0x4C, 0xDB, 0x07, 0x96, 0x4A, 0x55, 0x7A, 0xCA, 0x36, + 0x82, 0x04, 0x36, 0xA8, 0xA5, 0xFC, 0x27, 0xF6, 0x49, 0xF1, 0xD5, 0x72, + 0x9E, 0x91, 0xF9, 0x23, 0xD6, 0x70, 0x7B, 0xBB, 0xF5, 0x9B, 0xC1, 0xEC, + 0x93, 0xCF, 0x19, 0xEA, 0x65, 0x7E, 0x88, 0x70, 0xA0, 0x73, 0xFC, 0xF6, + 0xFF, 0xB5, 0x56, 0x62, 0xE1, 0x73, 0x6A, 0x34, 0x98, 0x3E, 0x82, 0xB8, + 0xAC, 0x95, 0x53, 0xF4, 0x01, 0xA0, 0x27, 0x07, 0x72, 0xA3, 0x00, 0x53, + 0xA0, 0xE4, 0xB2, 0xAB, 0x83, 0x38, 0x57, 0x33, 0x25, 0x94, 0x9F, 0xBE, + 0x48, 0x1D, 0x98, 0xE1, 0xA3, 0xBA, 0x9E, 0x5C, 0xCD, 0x04, 0x71, 0x51, + 0x7D, 0x75, 0x78, 0xAB, 0xF3, 0x59, 0xAA, 0xC4, 0xE0, 0x60, 0xBE, 0x8F, + 0x83, 0x52, 0xB8, 0x75, 0x1A, 0x41, 0x35, 0xED, 0xBC, 0xF3, 0x3A, 0x63, + 0xE9, 0xA9, 0x14, 0x45, 0xD7, 0xE6, 0x52, 0xD1, 0x6E, 0xD2, 0xDE, 0xBC, + 0xE3, 0xF5, 0x0B, 0x3B, 0xE6, 0xE0, 0xC4, 0xBD, 0x43, 0x64, 0x13, 0xA6, + 0xCE, 0xF4, 0x98, 0x37, 0x6C, 0x8A, 0x95, 0xA8, 0x97, 0xC8, 0x47, 0x0F, + 0xF0, 0x5E, 0x10, 0x8B, 0xE7, 0x1D, 0x1C, 0xFE, 0xB1, 0x3B, 0xA0, 0x05, + 0x33, 0x68, 0x05, 0x41, 0x82, 0xC1, 0x03, 0x2B, 0x01, 0xC8, 0xE7, 0x8F, + 0x4D, 0xAB, 0xE8, 0xB5, 0xF6, 0xCD, 0x6B, 0x44, 0xB5, 0xE7, 0xDD, 0x8B, + 0xEC, 0xEA, 0x25, 0xB4, 0x00, 0x22, 0x57, 0x4D, 0xB0, 0xB1, 0xB2, 0x31, + 0xC1, 0x16, 0xCE, 0xFF, 0xFD, 0x14, 0x84, 0xB7, 0x47, 0xFA, 0xB2, 0xF1, + 0x70, 0xDE, 0xDB, 0x8B, 0x6C, 0x36, 0x58, 0xA4, 0x7C, 0xB3, 0x11, 0xD1, + 0xC3, 0x77, 0x7F, 0x5F, 0xB6, 0x25, 0xE0, 0x0D, 0xC5, 0xD2, 0xB3, 0xF9, + 0xB8, 0xB8, 0x77, 0xDB, 0x37, 0x71, 0x71, 0x47, 0xE3, 0x60, 0x18, 0x4F, + 0x24, 0xB6, 0x75, 0x37, 0x78, 0xB9, 0xA3, 0x62, 0xAF, 0xBD, 0xC9, 0x72, + 0x8E, 0x2F, 0xCC, 0xBB, 0xAE, 0xDB, 0xE4, 0x15, 0x52, 0x19, 0x07, 0x33, + 0xFB, 0x6A, 0xB7, 0x2D, 0x4B, 0x90, 0x28, 0x82, 0x73, 0xFE, 0x18, 0x8B, + 0x35, 0x8D, 0xDB, 0xA7, 0x04, 0x6A, 0xBE, 0xEA, 0xC1, 0x4D, 0x36, 0x3B, + 0x16, 0x36, 0x91, 0x32, 0xEF, 0xB6, 0x40, 0x89, 0x91, 0x43, 0xE0, 0xF2, + 0xA2, 0xAB, 0x04, 0x2E, 0xE6, 0xF2, 0x4C, 0x0E, 0x16, 0x34, 0x20, 0xAC, + 0x87, 0xC1, 0x2D, 0x7E, 0xC9, 0x66, 0x47, 0x17, 0x14, 0x11, 0xA4, 0xF3, + 0xF7, 0xA1, 0x24, 0x89, 0xAB, 0xD8, 0x1A, 0xC8, 0xA1, 0x5C, 0xB1, 0xA3, + 0xF7, 0x8C, 0x6D, 0xC8, 0x01, 0xC9, 0x4F, 0xC9, 0xEC, 0xC4, 0xFC, 0xAC, + 0x51, 0x33, 0xD1, 0xC8, 0x83, 0xD1, 0xC9, 0x9F, 0x1D, 0xD4, 0x47, 0x34, + 0x29, 0x3E, 0xCB, 0xB0, 0x0E, 0xFA, 0x83, 0x0B, 0x28, 0x58, 0xE5, 0x29, + 0xDC, 0x3F, 0x7C, 0xA8, 0x9F, 0xC9, 0xB6, 0x0A, 0xBB, 0xA6, 0xE8, 0x46, + 0x16, 0x0F, 0x96, 0xE5, 0x7B, 0xE4, 0x6A, 0x7A, 0x48, 0x6D, 0x76, 0x98, + 0x05, 0xA5, 0xDC, 0x6D, 0x1E, 0x42, 0x1E, 0x42, 0xDA, 0x1A, 0xE0, 0x52, + 0xF7, 0xB5, 0x83, 0xC0, 0x1A, 0x7B, 0x78, 0x35, 0x2C, 0x38, 0xF5, 0x1F, + 0xFD, 0x49, 0xA3, 0x2E, 0xD2, 0x59, 0x63, 0xBF, 0x80, 0xB0, 0x8C, 0x93, + 0x73, 0xCB, 0x35, 0xA6, 0x99, 0x95, 0x22, 0x61, 0x65, 0x03, 0x60, 0xFB, + 0x2F, 0x93, 0x4B, 0xFA, 0x9A, 0x9C, 0x80, 0x3B +}; + +static const unsigned char TA369_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA370_DN[] = { + 0x30, 0x37, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0B, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x54, + 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, 0x20, 0x52, + 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x31 +}; + +static const unsigned char TA370_RSA_N[] = { + 0xC2, 0xBE, 0xEB, 0x27, 0xF0, 0x21, 0xA3, 0xF3, 0x69, 0x26, 0x55, 0x7E, + 0x9D, 0xC5, 0x55, 0x16, 0x91, 0x5C, 0xFD, 0xEF, 0x21, 0xBF, 0x53, 0x80, + 0x7A, 0x2D, 0xD2, 0x91, 0x8C, 0x63, 0x31, 0xF0, 0xEC, 0x24, 0xF0, 0xC3, + 0xA5, 0xD2, 0x72, 0x7C, 0x10, 0x6D, 0xF4, 0x37, 0xB7, 0xE5, 0xE6, 0x7C, + 0x79, 0xEA, 0x8C, 0xB5, 0x82, 0x8B, 0xAE, 0x48, 0xB6, 0xAC, 0x00, 0xDC, + 0x65, 0x75, 0xEC, 0x2A, 0x4D, 0x5F, 0xC1, 0x87, 0xF5, 0x20, 0x65, 0x2B, + 0x81, 0xA8, 0x47, 0x3E, 0x89, 0x23, 0x95, 0x30, 0x16, 0x90, 0x7F, 0xE8, + 0x57, 0x07, 0x48, 0xE7, 0x19, 0xAE, 0xBF, 0x45, 0x67, 0xB1, 0x37, 0x1B, + 0x06, 0x2A, 0xFE, 0xDE, 0xF9, 0xAC, 0x7D, 0x83, 0xFB, 0x5E, 0xBA, 0xE4, + 0x8F, 0x97, 0x67, 0xBE, 0x4B, 0x8E, 0x8D, 0x64, 0x07, 0x57, 0x38, 0x55, + 0x69, 0x34, 0x36, 0x3D, 0x13, 0x48, 0xEF, 0x4F, 0xE2, 0xD3, 0x66, 0x1E, + 0xA4, 0xCF, 0x1A, 0xB7, 0x5E, 0x36, 0x33, 0xD4, 0xB4, 0x06, 0xBD, 0x18, + 0x01, 0xFD, 0x77, 0x84, 0x50, 0x00, 0x45, 0xF5, 0x8C, 0x5D, 0xE8, 0x23, + 0xBC, 0x7E, 0xFE, 0x35, 0xE1, 0xED, 0x50, 0x7B, 0xA9, 0x30, 0x8D, 0x19, + 0xD3, 0x09, 0x8E, 0x68, 0x67, 0x5D, 0xBF, 0x3C, 0x97, 0x18, 0x53, 0xBB, + 0x29, 0x62, 0xC5, 0xCA, 0x5E, 0x72, 0xC1, 0xC7, 0x96, 0xD4, 0xDB, 0x2D, + 0xA0, 0xB4, 0x1F, 0x69, 0x03, 0xEC, 0xEA, 0xE2, 0x50, 0xF1, 0x0C, 0x3C, + 0xF0, 0xAC, 0xF3, 0x53, 0x2D, 0xF0, 0x1C, 0xF5, 0xED, 0x6C, 0x39, 0x39, + 0x73, 0x80, 0x16, 0xC8, 0x52, 0xB0, 0x23, 0xCD, 0xE0, 0x3E, 0xDC, 0xDD, + 0x3C, 0x47, 0xA0, 0xBB, 0x35, 0x8A, 0xE2, 0x98, 0x68, 0x8B, 0xBE, 0xE5, + 0xBF, 0x72, 0xEE, 0xD2, 0xFA, 0xA5, 0xED, 0x12, 0xED, 0xFC, 0x98, 0x18, + 0xA9, 0x26, 0x76, 0xDC, 0x28, 0x4B, 0x10, 0x20, 0x1C, 0xD3, 0x7F, 0x16, + 0x77, 0x2D, 0xED, 0x6F, 0x80, 0xF7, 0x49, 0xBB, 0x53, 0x05, 0xBB, 0x5D, + 0x68, 0xC7, 0xD4, 0xC8, 0x75, 0x16, 0x3F, 0x89, 0x5A, 0x8B, 0xF7, 0x17, + 0x47, 0xD4, 0x4C, 0xF1, 0xD2, 0x89, 0x79, 0x3E, 0x4D, 0x3D, 0x98, 0xA8, + 0x61, 0xDE, 0x3A, 0x1E, 0xD2, 0xF8, 0x5E, 0x03, 0xE0, 0xC1, 0xC9, 0x1C, + 0x8C, 0xD3, 0x8D, 0x4D, 0xD3, 0x95, 0x36, 0xB3, 0x37, 0x5F, 0x63, 0x63, + 0x9B, 0x33, 0x14, 0xF0, 0x2D, 0x26, 0x6B, 0x53, 0x7C, 0x89, 0x8C, 0x32, + 0xC2, 0x6E, 0xEC, 0x3D, 0x21, 0x00, 0x39, 0xC9, 0xA1, 0x68, 0xE2, 0x50, + 0x83, 0x2E, 0xB0, 0x3A, 0x2B, 0xF3, 0x36, 0xA0, 0xAC, 0x2F, 0xE4, 0x6F, + 0x61, 0xC2, 0x51, 0x09, 0x39, 0x3E, 0x8B, 0x53, 0xB9, 0xBB, 0x67, 0xDA, + 0xDC, 0x53, 0xB9, 0x76, 0x59, 0x36, 0x9D, 0x43, 0xE5, 0x20, 0xE0, 0x3D, + 0x32, 0x60, 0x85, 0x22, 0x51, 0xB7, 0xC7, 0x33, 0xBB, 0xDD, 0x15, 0x2F, + 0xA4, 0x78, 0xA6, 0x07, 0x7B, 0x81, 0x46, 0x36, 0x04, 0x86, 0xDD, 0x79, + 0x35, 0xC7, 0x95, 0x2C, 0x3B, 0xB0, 0xA3, 0x17, 0x35, 0xE5, 0x73, 0x1F, + 0xB4, 0x5C, 0x59, 0xEF, 0xDA, 0xEA, 0x10, 0x65, 0x7B, 0x7A, 0xD0, 0x7F, + 0x9F, 0xB3, 0xB4, 0x2A, 0x37, 0x3B, 0x70, 0x8B, 0x9B, 0x5B, 0xB9, 0x2B, + 0xB7, 0xEC, 0xB2, 0x51, 0x12, 0x97, 0x53, 0x29, 0x5A, 0xD4, 0xF0, 0x12, + 0x10, 0xDC, 0x4F, 0x02, 0xBB, 0x12, 0x92, 0x2F, 0x62, 0xD4, 0x3F, 0x69, + 0x43, 0x7C, 0x0D, 0xD6, 0xFC, 0x58, 0x75, 0x01, 0x88, 0x9D, 0x58, 0x16, + 0x4B, 0xDE, 0xBA, 0x90, 0xFF, 0x47, 0x01, 0x89, 0x06, 0x6A, 0xF6, 0x5F, + 0xB2, 0x90, 0x6A, 0xB3, 0x02, 0xA6, 0x02, 0x88, 0xBF, 0xB3, 0x47, 0x7E, + 0x2A, 0xD9, 0xD5, 0xFA, 0x68, 0x78, 0x35, 0x4D +}; + +static const unsigned char TA370_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA371_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x49, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x11, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x6C, + 0x61, 0x6E, 0x64, 0x20, 0x4F, 0x79, 0x6A, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x32 +}; + +static const unsigned char TA371_RSA_N[] = { + 0xB2, 0xD0, 0x3F, 0x07, 0xBC, 0xE2, 0x7B, 0xD0, 0x6B, 0x99, 0xF8, 0xE2, + 0x77, 0x69, 0xE7, 0xCE, 0x9D, 0xA4, 0x03, 0xBC, 0x82, 0x6D, 0xA1, 0xFE, + 0x81, 0x65, 0x1F, 0x4C, 0x27, 0xAC, 0x8E, 0x00, 0xBA, 0x16, 0x7B, 0xEB, + 0x30, 0x6A, 0x00, 0xC0, 0xB3, 0x74, 0x68, 0x7E, 0xB2, 0xAF, 0xC7, 0xD5, + 0x62, 0xB3, 0x7A, 0x3F, 0x50, 0xCA, 0x8C, 0x36, 0x44, 0x24, 0x63, 0xD2, + 0x36, 0xE9, 0x0C, 0x85, 0xF6, 0x43, 0x76, 0xD5, 0x4C, 0xA1, 0x60, 0x72, + 0x67, 0xE2, 0x28, 0x33, 0xA5, 0xCB, 0x31, 0xB8, 0x3A, 0x22, 0x23, 0x34, + 0xB8, 0x7D, 0xBD, 0x56, 0x22, 0x40, 0x9D, 0xEA, 0xF4, 0x7B, 0x03, 0xAD, + 0x68, 0xFC, 0xB2, 0x81, 0x4F, 0x98, 0xD0, 0x74, 0xEA, 0x8D, 0xE5, 0x7D, + 0xCD, 0x63, 0xC3, 0xA3, 0xF6, 0xDE, 0x92, 0xC2, 0x58, 0x19, 0xE0, 0x96, + 0xBB, 0xC5, 0xC4, 0xA9, 0x3D, 0xA5, 0x74, 0x96, 0xFE, 0xAF, 0xF9, 0x89, + 0xAA, 0xBD, 0x95, 0x17, 0x54, 0xD8, 0x78, 0x44, 0xF1, 0x0C, 0x77, 0x15, + 0x92, 0xE0, 0x98, 0x42, 0xA7, 0xA4, 0xD6, 0xAA, 0x20, 0x92, 0xCD, 0xC1, + 0xA0, 0xB3, 0x96, 0xB2, 0x3A, 0x84, 0x42, 0x8D, 0x7D, 0xD5, 0x95, 0xE4, + 0xD6, 0xDB, 0xE9, 0x62, 0xC4, 0x58, 0xB3, 0x79, 0xC5, 0x8C, 0xD3, 0x35, + 0x33, 0x83, 0x9F, 0x75, 0xA1, 0x52, 0x27, 0x61, 0x38, 0xF1, 0x59, 0x3D, + 0x8E, 0x50, 0xE0, 0xBD, 0x79, 0x3C, 0xE7, 0x6C, 0x96, 0xFE, 0x5E, 0xD9, + 0x02, 0x65, 0xB4, 0x8E, 0x5C, 0xD0, 0x11, 0x34, 0xDF, 0x5D, 0xBF, 0x52, + 0xA7, 0x81, 0x00, 0xC3, 0x7F, 0x99, 0x45, 0x99, 0x15, 0xD5, 0x17, 0xC8, + 0x0A, 0x53, 0xEC, 0x63, 0xF3, 0x99, 0x7D, 0xCC, 0x69, 0x12, 0x86, 0xC2, + 0x17, 0xF0, 0x01, 0x9E, 0xBF, 0x84, 0xBC, 0xD1, 0x52, 0xCB, 0x1B, 0x92, + 0x66, 0xCE, 0xA4, 0x53, 0xE5, 0xA1, 0xBF, 0xC4, 0xDB, 0x09, 0xD6, 0xE6, + 0x89, 0x56, 0x2B, 0xC8, 0xE3, 0x7C, 0xDE, 0xE3, 0xFF, 0x89, 0xE5, 0x35, + 0x6E, 0x28, 0xE8, 0x6C, 0x0B, 0x23, 0x51, 0xA9, 0x25, 0x05, 0xEB, 0x48, + 0xF8, 0xDD, 0xB1, 0xCA, 0xFA, 0x6C, 0x08, 0x51, 0xEF, 0xB7, 0x18, 0x6C, + 0x44, 0xCA, 0x26, 0xE1, 0x73, 0xC6, 0x89, 0x06, 0x81, 0xE5, 0x8A, 0xAC, + 0xB0, 0xE2, 0x29, 0xC6, 0xB9, 0x24, 0xB3, 0x6B, 0x44, 0x11, 0xF4, 0xA5, + 0x43, 0xC2, 0x4C, 0x43, 0xE5, 0x70, 0x36, 0x8C, 0xB6, 0x33, 0x57, 0x7A, + 0x95, 0x2E, 0x82, 0xA0, 0xF4, 0x5C, 0x10, 0xB3, 0x61, 0x83, 0xF6, 0x02, + 0x05, 0x86, 0x2E, 0x7C, 0x2D, 0x6C, 0xDC, 0x03, 0x46, 0x6E, 0x35, 0x93, + 0xD5, 0x7A, 0x95, 0x2F, 0xDE, 0x20, 0xD8, 0x5B, 0x7E, 0x94, 0x90, 0x04, + 0x6A, 0xBA, 0x59, 0x3D, 0x04, 0x05, 0x75, 0x9D, 0x37, 0xA2, 0x0E, 0x2E, + 0x3D, 0xEB, 0xC1, 0xA4, 0x52, 0x83, 0xFE, 0xD0, 0x6B, 0xD4, 0x66, 0x8E, + 0xDC, 0xC6, 0xE9, 0x12, 0x4E, 0x1D, 0x2A, 0x57, 0xAA, 0x10, 0xBC, 0x7C, + 0x5E, 0x82, 0x7D, 0xA6, 0xA6, 0xC9, 0xF2, 0x2D, 0xB9, 0xF5, 0x17, 0x27, + 0xAD, 0xD1, 0x0E, 0x89, 0x54, 0x2B, 0x95, 0xFA, 0xC0, 0xAD, 0x1D, 0x98, + 0x14, 0x78, 0x33, 0x42, 0x86, 0x0A, 0xA9, 0x73, 0xB5, 0xFB, 0x74, 0x0D, + 0xB7, 0x1B, 0x30, 0x19, 0xC4, 0x5A, 0x0E, 0x1C, 0x27, 0xB7, 0xDA, 0x18, + 0xD0, 0xFF, 0x8A, 0xC8, 0x05, 0xBA, 0xF1, 0xAA, 0x1C, 0xA2, 0x37, 0xB7, + 0xE6, 0x48, 0xA4, 0x46, 0x2C, 0x94, 0xEA, 0xA8, 0x76, 0x62, 0x47, 0x8B, + 0x10, 0x53, 0x07, 0x48, 0x57, 0x6C, 0xE2, 0x92, 0x4D, 0xB6, 0xAE, 0x05, + 0xCB, 0xDC, 0xC1, 0x4A, 0x5E, 0x8F, 0xAC, 0x3D, 0x19, 0x4E, 0xC2, 0xED, + 0x60, 0x75, 0x2B, 0xDB, 0xC1, 0xCA, 0x42, 0xD5 +}; + +static const unsigned char TA371_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA372_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA372_RSA_N[] = { + 0xC0, 0x31, 0x82, 0x61, 0x92, 0xE4, 0x94, 0x1B, 0x0A, 0x2A, 0x65, 0xD0, + 0xBE, 0x06, 0xA9, 0x87, 0x3B, 0x51, 0x12, 0xEA, 0x70, 0x41, 0xAE, 0xE2, + 0xFB, 0x74, 0xEA, 0x0A, 0x8D, 0xB9, 0xB3, 0x4C, 0xDC, 0x8F, 0xB7, 0x13, + 0x52, 0x4F, 0x54, 0x18, 0xE1, 0x2C, 0x73, 0x95, 0x91, 0xC5, 0x66, 0x3B, + 0x6A, 0xCF, 0xAC, 0x63, 0x6D, 0x87, 0x53, 0xF0, 0xF7, 0xF1, 0x39, 0xB7, + 0xA0, 0x43, 0x63, 0xB0, 0xC4, 0x03, 0x5D, 0x57, 0xA9, 0xE7, 0x44, 0xCE, + 0xC4, 0xA1, 0x83, 0x65, 0xF6, 0x50, 0x3E, 0xB1, 0x7E, 0x16, 0xB8, 0x3A, + 0x8A, 0x02, 0xD0, 0x96, 0x1F, 0x00, 0xCD, 0x05, 0x21, 0xEF, 0x06, 0x6D, + 0xDD, 0x21, 0x9C, 0x19, 0x43, 0x45, 0xA1, 0xC5, 0xE8, 0x80, 0xCA, 0xC2, + 0xAD, 0x40, 0x62, 0x17, 0x06, 0xC6, 0xAA, 0xBC, 0xF3, 0xD6, 0xE6, 0xFC, + 0x50, 0x7E, 0x66, 0x42, 0x1F, 0x3C, 0x8B, 0xA6, 0x79, 0x79, 0x86, 0x40, + 0x35, 0x9F, 0x20, 0xEF, 0x3F, 0xEB, 0x8B, 0x47, 0x1F, 0x8F, 0x8E, 0xC5, + 0xD4, 0x8E, 0xB6, 0x2C, 0xC9, 0x44, 0x04, 0xE3, 0xD4, 0x43, 0x75, 0x3F, + 0xD5, 0x3F, 0xAF, 0x1C, 0xCC, 0x7E, 0x46, 0x5F, 0xAC, 0xDF, 0x64, 0x10, + 0x8A, 0xEF, 0x46, 0xF0, 0x90, 0xF0, 0x0F, 0x2D, 0xF4, 0x88, 0x0B, 0xB1, + 0x29, 0xAA, 0xAF, 0x85, 0xAA, 0x49, 0x58, 0xA8, 0xBF, 0x63, 0xA0, 0x38, + 0x91, 0xE6, 0xB3, 0xE6, 0x77, 0x68, 0xC4, 0xF9, 0x2A, 0x19, 0x84, 0xBB, + 0x0E, 0xE1, 0xF5, 0xAF, 0x89, 0xEC, 0xA5, 0x2F, 0x50, 0x20, 0x74, 0x1E, + 0x12, 0x41, 0x73, 0x1E, 0x24, 0xD9, 0xCA, 0xCE, 0x2C, 0xA1, 0x59, 0x35, + 0xC0, 0xC8, 0x1D, 0x46, 0x27, 0x61, 0x5A, 0x8F, 0xF9, 0x4D, 0xD3, 0x72, + 0x79, 0x66, 0x1E, 0x9F, 0x15, 0x90, 0x21, 0x2D, 0xFD, 0xED, 0x8B, 0x56, + 0x70, 0x03, 0x4A, 0x49, 0x3E, 0x7F, 0x69, 0x31, 0x12, 0x69, 0xC7, 0x1E, + 0x5C, 0xCA, 0x7A, 0x13, 0x8B, 0xE8, 0xE6, 0xF5, 0x60, 0x0F, 0xCC, 0x93, + 0x2C, 0x84, 0x7F, 0xF1, 0xFC, 0x6A, 0xFC, 0x9B, 0x47, 0x9D, 0xDB, 0xAD, + 0x88, 0x3D, 0xF3, 0x76, 0x75, 0x33, 0xD7, 0x4B, 0xA4, 0xC8, 0x8B, 0xF9, + 0xF5, 0x43, 0x58, 0x4F, 0xCB, 0xC8, 0x03, 0x54, 0x8F, 0xA5, 0x85, 0x78, + 0x04, 0x1A, 0xF3, 0x73, 0xF2, 0xD7, 0x87, 0x1D, 0x41, 0x9F, 0xE7, 0xD8, + 0x17, 0xCE, 0x1A, 0x9C, 0x0F, 0x4A, 0xFC, 0xDC, 0x44, 0x68, 0x54, 0x68, + 0xE2, 0x41, 0x3C, 0xFE, 0x2C, 0x84, 0x86, 0x37, 0x3C, 0xCD, 0x3F, 0x2F, + 0xA2, 0xDB, 0xE7, 0xF7, 0x54, 0x03, 0x5F, 0x59, 0xD3, 0xF7, 0x91, 0x78, + 0xC7, 0x8B, 0x77, 0x6A, 0x16, 0xE5, 0x49, 0x85, 0x90, 0x45, 0x72, 0x70, + 0x2F, 0x91, 0x5D, 0xF8, 0x3E, 0x65, 0x40, 0x0B, 0x19, 0x99, 0xC9, 0x26, + 0x20, 0x5A, 0x68, 0xC1, 0x35, 0xBF, 0x4F, 0xA7, 0x51, 0xF1, 0xD8, 0x11, + 0x2B, 0x5B, 0xE0, 0x9A, 0x9E, 0x28, 0x3B, 0x0A, 0x3A, 0x0A, 0x1F, 0xC1, + 0x81, 0xE5, 0x2E, 0xF0, 0xA6, 0xB9, 0x69, 0xA5, 0x88, 0x94, 0xE6, 0x6B, + 0x13, 0x7F, 0xD1, 0x64, 0x3F, 0x3D, 0x9C, 0x70, 0x46, 0xE5, 0xA2, 0x85, + 0x7B, 0x58, 0x84, 0x27, 0xDC, 0xC4, 0x80, 0x3E, 0x67, 0x9A, 0x9A, 0xC7, + 0x9A, 0x31, 0x0E, 0x30, 0xEC, 0xE6, 0x17, 0x40, 0x95, 0xD9, 0x45, 0xED, + 0x01, 0x96, 0xAA, 0xBF, 0x0C, 0xF3, 0x4B, 0xD1, 0x63, 0xF7, 0x13, 0x58, + 0xC0, 0xB8, 0xF3, 0xFA, 0x67, 0xDD, 0x9B, 0x7D, 0x6D, 0x4A, 0xFF, 0x32, + 0x4C, 0xB5, 0x25, 0x3B, 0xFF, 0x1C, 0x67, 0x0F, 0x85, 0x22, 0x59, 0x05, + 0x91, 0x91, 0x41, 0x77, 0x81, 0xD0, 0x85, 0x4C, 0x87, 0x10, 0x71, 0xFF, + 0x9E, 0x43, 0x1B, 0xAE, 0x95, 0x75, 0x2D, 0x81 +}; + +static const unsigned char TA372_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA373_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA373_EC_Q[] = { + 0x04, 0xF1, 0xB3, 0xCD, 0x38, 0xE4, 0x25, 0x43, 0xE5, 0xDE, 0x19, 0x09, + 0xBB, 0x81, 0x79, 0xA2, 0x15, 0x5F, 0x15, 0x63, 0x01, 0xDE, 0xC2, 0xAB, + 0xDD, 0xB3, 0xA6, 0x1B, 0x67, 0x4B, 0x80, 0x83, 0xAF, 0x99, 0xCB, 0xAC, + 0x17, 0xDB, 0x2B, 0x96, 0xCA, 0x7C, 0x52, 0x55, 0xE2, 0x1A, 0xE1, 0x3D, + 0x56, 0xF0, 0x2F, 0x16, 0x08, 0xFA, 0x15, 0xBC, 0x9B, 0xBB, 0x47, 0xE6, + 0x3F, 0xEE, 0xA8, 0xE1, 0x4C, 0x8C, 0xF5, 0xD3, 0x36, 0xF9, 0x38, 0x5D, + 0xAB, 0x70, 0x9A, 0x47, 0x0D, 0xE2, 0x81, 0x41, 0x06, 0xEB, 0x49, 0xF9, + 0xB0, 0x29, 0xDD, 0x33, 0xEC, 0x50, 0xA5, 0x7F, 0x79, 0x29, 0xB8, 0x20, + 0x98 +}; + +static const unsigned char TA374_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x28, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA374_RSA_N[] = { + 0xB9, 0x5D, 0x51, 0x28, 0x4B, 0x3C, 0x37, 0x92, 0xD1, 0x82, 0xCE, 0xBD, + 0x1D, 0xBD, 0xCD, 0xDD, 0xB8, 0xAB, 0xCF, 0x0A, 0x3E, 0xE1, 0x5D, 0xE5, + 0xDC, 0xAA, 0x09, 0xB9, 0x57, 0x02, 0x3E, 0xE6, 0x63, 0x61, 0xDF, 0xF2, + 0x0F, 0x82, 0x63, 0xAE, 0xA3, 0xF7, 0xAC, 0x73, 0xD1, 0x7C, 0xE7, 0xB3, + 0x0B, 0xAF, 0x08, 0x00, 0x09, 0x59, 0x7F, 0xCD, 0x29, 0x2A, 0x88, 0x93, + 0x87, 0x17, 0x18, 0x80, 0xED, 0x88, 0xB2, 0xB4, 0xB6, 0x10, 0x1F, 0x2D, + 0xD6, 0x5F, 0x55, 0xA2, 0x13, 0x5D, 0xD1, 0xC6, 0xEB, 0x06, 0x56, 0x89, + 0x88, 0xFE, 0xAC, 0x32, 0x9D, 0xFD, 0x5C, 0xC3, 0x05, 0xC7, 0x6E, 0xEE, + 0x86, 0x89, 0xBA, 0x88, 0x03, 0x9D, 0x72, 0x21, 0x86, 0x90, 0xAE, 0x8F, + 0x03, 0xA5, 0xDC, 0x9F, 0x88, 0x28, 0xCB, 0xA3, 0x92, 0x49, 0x0F, 0xEC, + 0xD0, 0x0F, 0xE2, 0x6D, 0x44, 0x4F, 0x80, 0x6A, 0xB2, 0xD4, 0xE7, 0xA0, + 0x0A, 0x53, 0x01, 0xBA, 0x8E, 0x97, 0x91, 0x76, 0x6E, 0xBC, 0xFC, 0xD5, + 0x6B, 0x36, 0xE6, 0x40, 0x88, 0xD6, 0x7B, 0x2F, 0x5F, 0x05, 0xE8, 0x2C, + 0x6D, 0x11, 0xF3, 0xE7, 0xB2, 0xBE, 0x92, 0x44, 0x4C, 0xD2, 0x97, 0xA4, + 0xFE, 0xD2, 0x72, 0x81, 0x43, 0x07, 0x9C, 0xE9, 0x11, 0x3E, 0xF5, 0x8B, + 0x1A, 0x59, 0x7D, 0x1F, 0x68, 0x58, 0xDD, 0x04, 0x00, 0x2C, 0x96, 0xF3, + 0x43, 0xB3, 0x7E, 0x98, 0x19, 0x74, 0xD9, 0x9C, 0x73, 0xD9, 0x18, 0xBE, + 0x41, 0xC7, 0x34, 0x79, 0xD9, 0xF4, 0x62, 0xC2, 0x43, 0xB9, 0xB3, 0x27, + 0xB0, 0x22, 0xCB, 0xF9, 0x3D, 0x52, 0xC7, 0x30, 0x47, 0xB3, 0xC9, 0x3E, + 0xB8, 0x6A, 0xE2, 0xE7, 0xE8, 0x81, 0x70, 0x5E, 0x42, 0x8B, 0x4F, 0x26, + 0xA5, 0xFE, 0x3A, 0xC2, 0x20, 0x6E, 0xBB, 0xF8, 0x16, 0x8E, 0xCD, 0x0C, + 0xA9, 0xB4, 0x1B, 0x6C, 0x76, 0x10, 0xE1, 0x58, 0x79, 0x46, 0x3E, 0x54, + 0xCE, 0x80, 0xA8, 0x57, 0x09, 0x37, 0x29, 0x1B, 0x99, 0x13, 0x8F, 0x0C, + 0xC8, 0xD6, 0x2C, 0x1C, 0xFB, 0x05, 0xE8, 0x08, 0x95, 0x3D, 0x65, 0x46, + 0xDC, 0xEE, 0xCD, 0x69, 0xE2, 0x4D, 0x8F, 0x87, 0x28, 0x4E, 0x34, 0x0B, + 0x3E, 0xCF, 0x14, 0xD9, 0xBB, 0xDD, 0xB6, 0x50, 0x9A, 0xAD, 0x77, 0xD4, + 0x19, 0xD6, 0xDA, 0x1A, 0x88, 0xC8, 0x4E, 0x1B, 0x27, 0x75, 0xD8, 0xB2, + 0x08, 0xF1, 0xAE, 0x83, 0x30, 0xB9, 0x11, 0x0E, 0xCD, 0x87, 0xF0, 0x84, + 0x8D, 0x15, 0x72, 0x7C, 0xA1, 0xEF, 0xCC, 0xF2, 0x88, 0x61, 0xBA, 0xF4, + 0x69, 0xBB, 0x0C, 0x8C, 0x0B, 0x75, 0x57, 0x04, 0xB8, 0x4E, 0x2A, 0x14, + 0x2E, 0x3D, 0x0F, 0x1C, 0x1E, 0x32, 0xA6, 0x62, 0x36, 0xEE, 0x66, 0xE2, + 0x22, 0xB8, 0x05, 0x40, 0x63, 0x10, 0x22, 0xF3, 0x33, 0x1D, 0x74, 0x72, + 0x8A, 0x2C, 0xF5, 0x39, 0x29, 0xA0, 0xD3, 0xE7, 0x1B, 0x80, 0x84, 0x2D, + 0xC5, 0x3D, 0xE3, 0x4D, 0xB1, 0xFD, 0x1A, 0x6F, 0xBA, 0x65, 0x07, 0x3B, + 0x58, 0xEC, 0x42, 0x45, 0x26, 0xFB, 0xD8, 0xDA, 0x25, 0x72, 0xC4, 0xF6, + 0x00, 0xB1, 0x22, 0x79, 0xBD, 0xE3, 0x7C, 0x59, 0x62, 0x4A, 0x9C, 0x05, + 0x6F, 0x3D, 0xCE, 0xE6, 0xD6, 0x47, 0x63, 0x99, 0xC6, 0x24, 0x6F, 0x72, + 0x12, 0xC8, 0xAC, 0x7F, 0x90, 0xB4, 0x0B, 0x91, 0x70, 0xE8, 0xB7, 0xE6, + 0x16, 0x10, 0x71, 0x17, 0xCE, 0xDE, 0x06, 0x4F, 0x48, 0x41, 0x7D, 0x35, + 0x4A, 0xA3, 0x89, 0xF2, 0xC9, 0x4B, 0x7B, 0x41, 0x11, 0x6D, 0x67, 0xB7, + 0x08, 0x98, 0x4C, 0xE5, 0x11, 0x19, 0xAE, 0x42, 0x80, 0xDC, 0xFB, 0x90, + 0x05, 0xD4, 0xF8, 0x50, 0xCA, 0xBE, 0xE4, 0xAD, 0xC7, 0xC2, 0x94, 0xD7, + 0x16, 0x9D, 0xE6, 0x17, 0x8F, 0xAF, 0x36, 0xFB +}; + +static const unsigned char TA374_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA375_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x32, 0x35, 0x36, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA375_EC_Q[] = { + 0x04, 0x7E, 0xFB, 0x6C, 0xE6, 0x23, 0xE3, 0x73, 0x32, 0x08, 0xCA, 0x60, + 0xE6, 0x53, 0x9C, 0xBA, 0x74, 0x8D, 0x18, 0xB0, 0x78, 0x90, 0x52, 0x80, + 0xDD, 0x38, 0xC0, 0x4A, 0x1D, 0xD1, 0xA8, 0xCC, 0x93, 0xA4, 0x97, 0x06, + 0x38, 0xCA, 0x0D, 0x15, 0x62, 0xC6, 0x8E, 0x01, 0x2A, 0x65, 0x9D, 0xAA, + 0xDF, 0x34, 0x91, 0x2E, 0x81, 0xC1, 0xE4, 0x33, 0x92, 0x31, 0xC4, 0xFD, + 0x09, 0x3A, 0xA6, 0x3F, 0xAD +}; + +static const unsigned char TA376_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA376_EC_Q[] = { + 0x04, 0x6B, 0xDA, 0x0D, 0x75, 0x35, 0x08, 0x31, 0x47, 0x05, 0xAE, 0x45, + 0x99, 0x55, 0xF1, 0x11, 0x13, 0x2E, 0x4A, 0xF8, 0x10, 0x31, 0x23, 0xA3, + 0x7E, 0x83, 0xD3, 0x7F, 0x28, 0x08, 0x3A, 0x26, 0x1A, 0x3A, 0xCF, 0x97, + 0x82, 0x1F, 0x80, 0xB7, 0x27, 0x09, 0x8F, 0xD1, 0x8E, 0x30, 0xC4, 0x0A, + 0x9B, 0x0E, 0xAC, 0x58, 0x04, 0xAB, 0xF7, 0x36, 0x7D, 0x94, 0x23, 0xA4, + 0x9B, 0x0A, 0x8A, 0x8B, 0xAB, 0xEB, 0xFD, 0x39, 0x25, 0x66, 0xF1, 0x5E, + 0xFE, 0x8C, 0xAE, 0x8D, 0x41, 0x79, 0x9D, 0x09, 0x60, 0xCE, 0x28, 0xA9, + 0xD3, 0x8A, 0x6D, 0xF3, 0xD6, 0x45, 0xD4, 0xF2, 0x98, 0x84, 0x38, 0x65, + 0xA0 +}; + +static const unsigned char TA377_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x4E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4E, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x65, 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x71, 0x75, 0x65, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, + 0x75, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA377_RSA_N[] = { + 0xC3, 0xCD, 0xD3, 0xFC, 0xBD, 0x04, 0x53, 0xDD, 0x0C, 0x20, 0x3A, 0xD5, + 0x88, 0x2E, 0x05, 0x4B, 0x41, 0xF5, 0x83, 0x82, 0x7E, 0xF7, 0x59, 0x9F, + 0x9E, 0x9E, 0x63, 0xE8, 0x73, 0xDA, 0xF6, 0x06, 0xA9, 0x4F, 0x1F, 0xB4, + 0xF9, 0x0B, 0x1F, 0x39, 0x8C, 0x9A, 0x20, 0xD0, 0x7E, 0x06, 0xD4, 0xEC, + 0x34, 0xD9, 0x86, 0xBC, 0x75, 0x5B, 0x87, 0x88, 0xF0, 0xD2, 0xD9, 0xD4, + 0xA3, 0x0A, 0xB2, 0x6C, 0x1B, 0xEB, 0x49, 0x2C, 0x3E, 0xAC, 0x5D, 0xD8, + 0x94, 0x03, 0xA0, 0xEC, 0x34, 0xE5, 0x30, 0xC4, 0x35, 0x7D, 0xFB, 0x26, + 0x4D, 0x1B, 0x6E, 0x30, 0x54, 0xD8, 0xF5, 0x80, 0x45, 0x9C, 0x39, 0xAD, + 0x9C, 0xC9, 0x25, 0x04, 0x4D, 0x9A, 0x90, 0x3E, 0x4E, 0x40, 0x6E, 0x8A, + 0x6B, 0xCD, 0x29, 0x67, 0xC6, 0xCC, 0x2D, 0xE0, 0x74, 0xE8, 0x05, 0x57, + 0x0A, 0x48, 0x50, 0xFA, 0x7A, 0x43, 0xDA, 0x7E, 0xEC, 0x5B, 0x9A, 0x0E, + 0x62, 0x76, 0xFE, 0xEA, 0x9D, 0x1D, 0x85, 0x72, 0xEC, 0x11, 0xBB, 0x35, + 0xE8, 0x1F, 0x27, 0xBF, 0xC1, 0xA1, 0xC7, 0xBB, 0x48, 0x16, 0xDD, 0x56, + 0xD7, 0xCC, 0x4E, 0xA0, 0xE1, 0xB9, 0xAC, 0xDB, 0xD5, 0x83, 0x19, 0x1A, + 0x85, 0xD1, 0x94, 0x97, 0xD7, 0xCA, 0xA3, 0x65, 0x0B, 0xF3, 0x38, 0xF9, + 0x02, 0xAE, 0xDD, 0xF6, 0x67, 0xCF, 0xC9, 0x3F, 0xF5, 0x8A, 0x2C, 0x47, + 0x1A, 0x99, 0x6F, 0x05, 0x0D, 0xFD, 0xD0, 0x1D, 0x82, 0x31, 0xFC, 0x29, + 0xCC, 0x00, 0x58, 0x97, 0x91, 0x4C, 0x80, 0x00, 0x1C, 0x33, 0x85, 0x96, + 0x2F, 0xCB, 0x41, 0xC2, 0x8B, 0x10, 0x84, 0xC3, 0x09, 0x24, 0x89, 0x1F, + 0xB5, 0x0F, 0xD9, 0xD9, 0x77, 0x47, 0x18, 0x92, 0x94, 0x60, 0x5C, 0xC7, + 0x99, 0x03, 0x3C, 0xFE, 0xF7, 0x95, 0xA7, 0x7D, 0x50, 0xA1, 0x80, 0xC2, + 0xA9, 0x83, 0xAD, 0x58, 0x96, 0x55, 0x21, 0xDB, 0x86, 0x59, 0xD4, 0xAF, + 0xC6, 0xBC, 0xDD, 0x81, 0x6E, 0x07, 0xDB, 0x60, 0x62, 0xFE, 0xEC, 0x10, + 0x6E, 0xDA, 0x68, 0x01, 0xF4, 0x83, 0x1B, 0xA9, 0x3E, 0xA2, 0x5B, 0x23, + 0xD7, 0x64, 0xC6, 0xDF, 0xDC, 0xA2, 0x7D, 0xD8, 0x4B, 0xBA, 0x82, 0xD2, + 0x51, 0xF8, 0x66, 0xBF, 0x06, 0x46, 0xE4, 0x79, 0x2A, 0x26, 0x36, 0x79, + 0x8F, 0x1F, 0x4E, 0x99, 0x1D, 0xB2, 0x8F, 0x0C, 0x0E, 0x1C, 0xFF, 0xC9, + 0x5D, 0xC0, 0xFD, 0x90, 0x10, 0xA6, 0xB1, 0x37, 0xF3, 0xCD, 0x3A, 0x24, + 0x6E, 0xB4, 0x85, 0x90, 0xBF, 0x80, 0xB9, 0x0C, 0x8C, 0xD5, 0x9B, 0xD6, + 0xC8, 0xF1, 0x56, 0x3F, 0x1A, 0x80, 0x89, 0x7A, 0xA9, 0xE2, 0x1B, 0x32, + 0x51, 0x2C, 0x3E, 0xF2, 0xDF, 0x7B, 0xF6, 0x5D, 0x7A, 0x29, 0x19, 0x8E, + 0xE5, 0xC8, 0xBD, 0x36, 0x71, 0x8B, 0x5D, 0x4C, 0xC2, 0x1D, 0x3F, 0xAD, + 0x58, 0xA2, 0xCF, 0x3D, 0x70, 0x4D, 0xA6, 0x50, 0x98, 0x25, 0xDC, 0x23, + 0xF9, 0xB8, 0x58, 0x41, 0x08, 0x71, 0xBF, 0x4F, 0xB8, 0x84, 0xA0, 0x8F, + 0x00, 0x54, 0x15, 0xFC, 0x91, 0x6D, 0x58, 0xA7, 0x96, 0x3B, 0xEB, 0x4B, + 0x96, 0x27, 0xCD, 0x6B, 0xA2, 0xA1, 0x86, 0xAC, 0x0D, 0x7C, 0x54, 0xE6, + 0x66, 0x4C, 0x66, 0x5F, 0x90, 0xBE, 0x21, 0x9A, 0x02, 0x46, 0x2D, 0xE4, + 0x83, 0xC2, 0x80, 0xB9, 0xCF, 0x4B, 0x3E, 0xE8, 0x7F, 0x3C, 0x01, 0xEC, + 0x8F, 0x5E, 0xCD, 0x7F, 0xD2, 0x28, 0x42, 0x01, 0x95, 0x8A, 0xE2, 0x97, + 0x3D, 0x10, 0x21, 0x7D, 0xF6, 0x9D, 0x1C, 0xC5, 0x34, 0xA1, 0xEC, 0x2C, + 0x0E, 0x0A, 0x52, 0x2C, 0x12, 0x55, 0x70, 0x24, 0x3D, 0xCB, 0xC2, 0x14, + 0x35, 0x43, 0x5D, 0x27, 0x4E, 0xBE, 0xC0, 0xBD, 0xAA, 0x7C, 0x96, 0xE7, + 0xFC, 0x9E, 0x61, 0xAD, 0x44, 0xD3, 0x00, 0x97 +}; + +static const unsigned char TA377_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA378_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x55, 0x43, 0x41, + 0x20, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, + 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74 +}; + +static const unsigned char TA378_RSA_N[] = { + 0xA9, 0x09, 0x07, 0x28, 0x13, 0x02, 0xB0, 0x99, 0xE0, 0x64, 0xAA, 0x1E, + 0x43, 0x16, 0x7A, 0x73, 0xB1, 0x91, 0xA0, 0x75, 0x3E, 0xA8, 0xFA, 0xE3, + 0x38, 0x00, 0x7A, 0xEC, 0x89, 0x6A, 0x20, 0x0F, 0x8B, 0xC5, 0xB0, 0x9B, + 0x33, 0x03, 0x5A, 0x86, 0xC6, 0x58, 0x86, 0xD5, 0xC1, 0x85, 0xBB, 0x4F, + 0xC6, 0x9C, 0x40, 0x4D, 0xCA, 0xBE, 0xEE, 0x69, 0x96, 0xB8, 0xAD, 0x81, + 0x30, 0x9A, 0x7C, 0x92, 0x05, 0xEB, 0x05, 0x2B, 0x9A, 0x48, 0xD0, 0xB8, + 0x76, 0x3E, 0x96, 0xC8, 0x20, 0xBB, 0xD2, 0xB0, 0xF1, 0x8F, 0xD8, 0xAC, + 0x45, 0x46, 0xFF, 0xAA, 0x67, 0x60, 0xB4, 0x77, 0x7E, 0x6A, 0x1F, 0x3C, + 0x1A, 0x52, 0x7A, 0x04, 0x3D, 0x07, 0x3C, 0x85, 0x0D, 0x84, 0xD0, 0x1F, + 0x76, 0x0A, 0xF7, 0x6A, 0x14, 0xDF, 0x72, 0xE3, 0x34, 0x7C, 0x57, 0x4E, + 0x56, 0x01, 0x3E, 0x79, 0xF1, 0xAA, 0x29, 0x3B, 0x6C, 0xFA, 0xF8, 0x8F, + 0x6D, 0x4D, 0xC8, 0x35, 0xDF, 0xAE, 0xEB, 0xDC, 0x24, 0xEE, 0x79, 0x45, + 0xA7, 0x85, 0xB6, 0x05, 0x88, 0xDE, 0x88, 0x5D, 0x25, 0x7C, 0x97, 0x64, + 0x67, 0x09, 0xD9, 0xBF, 0x5A, 0x15, 0x05, 0x86, 0xF3, 0x09, 0x1E, 0xEC, + 0x58, 0x32, 0x33, 0x11, 0xF3, 0x77, 0x64, 0xB0, 0x76, 0x1F, 0xE4, 0x10, + 0x35, 0x17, 0x1B, 0xF2, 0x0E, 0xB1, 0x6C, 0xA4, 0x2A, 0xA3, 0x73, 0xFC, + 0x09, 0x1F, 0x1E, 0x32, 0x19, 0x53, 0x11, 0xE7, 0xD9, 0xB3, 0x2C, 0x2E, + 0x76, 0x2E, 0xA1, 0xA3, 0xDE, 0x7E, 0x6A, 0x88, 0x09, 0xE8, 0xF2, 0x07, + 0x8A, 0xF8, 0xB2, 0xCD, 0x10, 0xE7, 0xE2, 0x73, 0x40, 0x93, 0xBB, 0x08, + 0xD1, 0x3F, 0xE1, 0xFC, 0x0B, 0x94, 0xB3, 0x25, 0xEF, 0x7C, 0xA6, 0xD7, + 0xD1, 0xAF, 0x9F, 0xFF, 0x96, 0x9A, 0xF5, 0x91, 0x7B, 0x98, 0x0B, 0x77, + 0xD4, 0x7E, 0xE8, 0x07, 0xD2, 0x62, 0xB5, 0x95, 0x39, 0xE3, 0xF3, 0xF1, + 0x6D, 0x0F, 0x0E, 0x65, 0x84, 0x8A, 0x63, 0x54, 0xC5, 0x80, 0xB6, 0xE0, + 0x9E, 0x4B, 0x7D, 0x47, 0x26, 0xA7, 0x01, 0x08, 0x5D, 0xD1, 0x88, 0x9E, + 0xD7, 0xC3, 0x32, 0x44, 0xFA, 0x82, 0x4A, 0x0A, 0x68, 0x54, 0x7F, 0x38, + 0x53, 0x03, 0xCC, 0xA4, 0x00, 0x33, 0x64, 0x51, 0x59, 0x0B, 0xA3, 0x82, + 0x91, 0x7A, 0x5E, 0xEC, 0x16, 0xC2, 0xF3, 0x2A, 0xE6, 0x62, 0xDA, 0x2A, + 0xDB, 0x59, 0x62, 0x10, 0x25, 0x4A, 0x2A, 0x81, 0x0B, 0x47, 0x07, 0x43, + 0x06, 0x70, 0x87, 0xD2, 0xFA, 0x93, 0x11, 0x29, 0x7A, 0x48, 0x4D, 0xEB, + 0x94, 0xC7, 0x70, 0x4D, 0xAF, 0x67, 0xD5, 0x51, 0xB1, 0x80, 0x20, 0x01, + 0x01, 0xB4, 0x7A, 0x08, 0xA6, 0x90, 0x7F, 0x4E, 0xE0, 0xEF, 0x07, 0x41, + 0x87, 0xAF, 0x6A, 0xA5, 0x5E, 0x8B, 0xFB, 0xCF, 0x50, 0xB2, 0x9A, 0x54, + 0xAF, 0xC3, 0x89, 0xBA, 0x58, 0x2D, 0xF5, 0x30, 0x98, 0xB1, 0x36, 0x72, + 0x39, 0x7E, 0x49, 0x04, 0xFD, 0x29, 0xA7, 0x4C, 0x79, 0xE4, 0x05, 0x57, + 0xDB, 0x94, 0xB9, 0x16, 0x53, 0x8D, 0x46, 0xB3, 0x1D, 0x95, 0x61, 0x57, + 0x56, 0x7F, 0xAF, 0xF0, 0x16, 0x5B, 0x61, 0x58, 0x6F, 0x36, 0x50, 0x11, + 0x0B, 0xD8, 0xAC, 0x2B, 0x95, 0x16, 0x1A, 0x0E, 0x1F, 0x08, 0xCD, 0x36, + 0x34, 0x65, 0x10, 0x62, 0x66, 0xD5, 0x80, 0x5F, 0x14, 0x20, 0x5F, 0x2D, + 0x0C, 0xA0, 0x78, 0x0A, 0x68, 0xD6, 0x2C, 0xD7, 0xE9, 0x6F, 0x2B, 0xD2, + 0x4A, 0x05, 0x93, 0xFC, 0x9E, 0x6F, 0x6B, 0x67, 0xFF, 0x88, 0xF1, 0x4E, + 0xA5, 0x69, 0x4A, 0x52, 0x37, 0x05, 0xEA, 0xC6, 0x16, 0x8D, 0xD2, 0xC4, + 0x99, 0xD1, 0x82, 0x2B, 0x3B, 0xBA, 0x35, 0x75, 0xF7, 0x51, 0x51, 0x58, + 0xF3, 0xC8, 0x07, 0xDD, 0xE4, 0xB4, 0x03, 0x7F +}; + +static const unsigned char TA378_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA379_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x1B, + 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x55, 0x43, 0x41, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x47, 0x32, 0x20, 0x52, + 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA379_RSA_N[] = { + 0xC5, 0xE6, 0x2B, 0x6F, 0x7C, 0xEF, 0x26, 0x05, 0x27, 0xA3, 0x81, 0x24, + 0xDA, 0x6F, 0xCB, 0x01, 0xF9, 0x99, 0x9A, 0xA9, 0x32, 0xC2, 0x22, 0x87, + 0x61, 0x41, 0x91, 0x3B, 0xCB, 0xC3, 0x68, 0x1B, 0x06, 0xC5, 0x4C, 0xA9, + 0x2B, 0xC1, 0x67, 0x17, 0x22, 0x1D, 0x2B, 0xED, 0xF9, 0x29, 0x89, 0x93, + 0xA2, 0x78, 0xBD, 0x92, 0x6B, 0xA0, 0xA3, 0x0D, 0xA2, 0x7E, 0xCA, 0x93, + 0xB3, 0xA6, 0xD1, 0x8C, 0x35, 0xD5, 0x75, 0xF9, 0x17, 0xF6, 0xCF, 0x45, + 0xC5, 0xE5, 0x7A, 0xEC, 0x77, 0x93, 0xA0, 0x8F, 0x23, 0xAE, 0x0E, 0x1A, + 0x03, 0x7F, 0xBE, 0xD4, 0xD0, 0xED, 0x2E, 0x7B, 0xAB, 0x46, 0x23, 0x5B, + 0xFF, 0x2C, 0xE6, 0x54, 0x7A, 0x94, 0xC0, 0x2A, 0x15, 0xF0, 0xC9, 0x8D, + 0xB0, 0x7A, 0x3B, 0x24, 0xE1, 0xD7, 0x68, 0xE2, 0x31, 0x3C, 0x06, 0x33, + 0x46, 0xB6, 0x54, 0x11, 0xA6, 0xA5, 0x2F, 0x22, 0x54, 0x2A, 0x58, 0x0D, + 0x01, 0x02, 0xF1, 0xFA, 0x15, 0x51, 0x67, 0x6C, 0xC0, 0xFA, 0xD7, 0xB6, + 0x1B, 0x7F, 0xD1, 0x56, 0x88, 0x2F, 0x1A, 0x3A, 0x8D, 0x3B, 0xBB, 0x82, + 0x11, 0xE0, 0x47, 0x00, 0xD0, 0x52, 0x87, 0xAB, 0xFB, 0x86, 0x7E, 0x0F, + 0x24, 0x6B, 0x40, 0x9D, 0x34, 0x67, 0xBC, 0x8D, 0xC7, 0x2D, 0x86, 0x6F, + 0x79, 0x3E, 0x8E, 0xA9, 0x3C, 0x17, 0x4B, 0x7F, 0xB0, 0x99, 0xE3, 0xB0, + 0x71, 0x60, 0xDC, 0x0B, 0xF5, 0x64, 0xC3, 0xCE, 0x43, 0xBC, 0x6D, 0x71, + 0xB9, 0xD2, 0xDE, 0x27, 0x5B, 0x8A, 0xE8, 0xD8, 0xC6, 0xAE, 0xE1, 0x59, + 0x7D, 0xCF, 0x28, 0x2D, 0x35, 0xB8, 0x95, 0x56, 0x1A, 0xF1, 0xB2, 0x58, + 0x4B, 0xB7, 0x12, 0x37, 0xC8, 0x7C, 0xB3, 0xED, 0x4B, 0x80, 0xE1, 0x8D, + 0xFA, 0x32, 0x23, 0xB6, 0x6F, 0xB7, 0x48, 0x95, 0x08, 0xB1, 0x44, 0x4E, + 0x85, 0x8C, 0x3A, 0x02, 0x54, 0x20, 0x2F, 0xDF, 0xBF, 0x57, 0x4F, 0x3B, + 0x3A, 0x90, 0x21, 0xD7, 0xC1, 0x26, 0x35, 0x54, 0x20, 0xEC, 0xC7, 0x3F, + 0x47, 0xEC, 0xEF, 0x5A, 0xBF, 0x4B, 0x7A, 0xC1, 0xAD, 0x3B, 0x17, 0x50, + 0x5C, 0x62, 0xD8, 0x0F, 0x4B, 0x4A, 0xDC, 0x2B, 0xFA, 0x6E, 0xBC, 0x73, + 0x92, 0xCD, 0xEC, 0xC7, 0x50, 0xE8, 0x41, 0x96, 0xD7, 0xA9, 0x7E, 0x6D, + 0xD8, 0xE9, 0x1D, 0x8F, 0x8A, 0xB5, 0xB9, 0x58, 0x92, 0xBA, 0x4A, 0x92, + 0x2B, 0x0C, 0x56, 0xFD, 0x80, 0xEB, 0x08, 0xF0, 0x5E, 0x29, 0x6E, 0x1B, + 0x1C, 0x0C, 0xAF, 0x8F, 0x93, 0x89, 0xAD, 0xDB, 0xBD, 0xA3, 0x9E, 0x21, + 0xCA, 0x89, 0x19, 0xEC, 0xDF, 0xB5, 0xC3, 0x1A, 0xEB, 0x16, 0xFE, 0x78, + 0x36, 0x4C, 0xD6, 0x6E, 0xD0, 0x3E, 0x17, 0x1C, 0x90, 0x17, 0x6B, 0x26, + 0xBA, 0xFB, 0x7A, 0x2F, 0xBF, 0x11, 0x1C, 0x18, 0x0E, 0x2D, 0x73, 0x03, + 0x8F, 0xA0, 0xE5, 0x35, 0xA0, 0x5A, 0xE2, 0x4C, 0x75, 0x1D, 0x71, 0xE1, + 0x39, 0x38, 0x53, 0x78, 0x40, 0xCC, 0x83, 0x93, 0xD7, 0x0A, 0x9E, 0x9D, + 0x5B, 0x8F, 0x8A, 0xE4, 0xE5, 0xE0, 0x48, 0xE4, 0x48, 0xB2, 0x47, 0xCD, + 0x4E, 0x2A, 0x75, 0x2A, 0x7B, 0xF2, 0x22, 0xF6, 0xC9, 0xBE, 0x09, 0x91, + 0x96, 0x57, 0x7A, 0x88, 0x88, 0xAC, 0xEE, 0x70, 0xAC, 0xF9, 0xDC, 0x29, + 0xE3, 0x0C, 0x1C, 0x3B, 0x12, 0x4E, 0x44, 0xD6, 0xA7, 0x4E, 0xB0, 0x26, + 0xC8, 0xF3, 0xD9, 0x1A, 0x97, 0x91, 0x68, 0xEA, 0xEF, 0x8D, 0x46, 0x06, + 0xD2, 0x56, 0x45, 0x58, 0x9A, 0x3C, 0x0C, 0x0F, 0x83, 0xB8, 0x05, 0x25, + 0xC3, 0x39, 0xCF, 0x3B, 0xA4, 0x34, 0x89, 0xB7, 0x79, 0x12, 0x2F, 0x47, + 0xC5, 0xE7, 0xA9, 0x97, 0x69, 0xFC, 0xA6, 0x77, 0x67, 0xB5, 0xDF, 0x7B, + 0xF1, 0x7A, 0x65, 0x15, 0xE4, 0x61, 0x56, 0x65 +}; + +static const unsigned char TA379_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA380_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA380_EC_Q[] = { + 0x04, 0x1A, 0xAC, 0x54, 0x5A, 0xA9, 0xF9, 0x68, 0x23, 0xE7, 0x7A, 0xD5, + 0x24, 0x6F, 0x53, 0xC6, 0x5A, 0xD8, 0x4B, 0xAB, 0xC6, 0xD5, 0xB6, 0xD1, + 0xE6, 0x73, 0x71, 0xAE, 0xDD, 0x9C, 0xD6, 0x0C, 0x61, 0xFD, 0xDB, 0xA0, + 0x89, 0x03, 0xB8, 0x05, 0x14, 0xEC, 0x57, 0xCE, 0xEE, 0x5D, 0x3F, 0xE2, + 0x21, 0xB3, 0xCE, 0xF7, 0xD4, 0x8A, 0x79, 0xE0, 0xA3, 0x83, 0x7E, 0x2D, + 0x97, 0xD0, 0x61, 0xC4, 0xF1, 0x99, 0xDC, 0x25, 0x91, 0x63, 0xAB, 0x7F, + 0x30, 0xA3, 0xB4, 0x70, 0xE2, 0xC7, 0xA1, 0x33, 0x9C, 0xF3, 0xBF, 0x2E, + 0x5C, 0x53, 0xB1, 0x5F, 0xB3, 0x7D, 0x32, 0x7F, 0x8A, 0x34, 0xE3, 0x79, + 0x79 +}; + +static const unsigned char TA381_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA381_RSA_N[] = { + 0x80, 0x12, 0x65, 0x17, 0x36, 0x0E, 0xC3, 0xDB, 0x08, 0xB3, 0xD0, 0xAC, + 0x57, 0x0D, 0x76, 0xED, 0xCD, 0x27, 0xD3, 0x4C, 0xAD, 0x50, 0x83, 0x61, + 0xE2, 0xAA, 0x20, 0x4D, 0x09, 0x2D, 0x64, 0x09, 0xDC, 0xCE, 0x89, 0x9F, + 0xCC, 0x3D, 0xA9, 0xEC, 0xF6, 0xCF, 0xC1, 0xDC, 0xF1, 0xD3, 0xB1, 0xD6, + 0x7B, 0x37, 0x28, 0x11, 0x2B, 0x47, 0xDA, 0x39, 0xC6, 0xBC, 0x3A, 0x19, + 0xB4, 0x5F, 0xA6, 0xBD, 0x7D, 0x9D, 0xA3, 0x63, 0x42, 0xB6, 0x76, 0xF2, + 0xA9, 0x3B, 0x2B, 0x91, 0xF8, 0xE2, 0x6F, 0xD0, 0xEC, 0x16, 0x20, 0x90, + 0x09, 0x3E, 0xE2, 0xE8, 0x74, 0xC9, 0x18, 0xB4, 0x91, 0xD4, 0x62, 0x64, + 0xDB, 0x7F, 0xA3, 0x06, 0xF1, 0x88, 0x18, 0x6A, 0x90, 0x22, 0x3C, 0xBC, + 0xFE, 0x13, 0xF0, 0x87, 0x14, 0x7B, 0xF6, 0xE4, 0x1F, 0x8E, 0xD4, 0xE4, + 0x51, 0xC6, 0x11, 0x67, 0x46, 0x08, 0x51, 0xCB, 0x86, 0x14, 0x54, 0x3F, + 0xBC, 0x33, 0xFE, 0x7E, 0x6C, 0x9C, 0xFF, 0x16, 0x9D, 0x18, 0xBD, 0x51, + 0x8E, 0x35, 0xA6, 0xA7, 0x66, 0xC8, 0x72, 0x67, 0xDB, 0x21, 0x66, 0xB1, + 0xD4, 0x9B, 0x78, 0x03, 0xC0, 0x50, 0x3A, 0xE8, 0xCC, 0xF0, 0xDC, 0xBC, + 0x9E, 0x4C, 0xFE, 0xAF, 0x05, 0x96, 0x35, 0x1F, 0x57, 0x5A, 0xB7, 0xFF, + 0xCE, 0xF9, 0x3D, 0xB7, 0x2C, 0xB6, 0xF6, 0x54, 0xDD, 0xC8, 0xE7, 0x12, + 0x3A, 0x4D, 0xAE, 0x4C, 0x8A, 0xB7, 0x5C, 0x9A, 0xB4, 0xB7, 0x20, 0x3D, + 0xCA, 0x7F, 0x22, 0x34, 0xAE, 0x7E, 0x3B, 0x68, 0x66, 0x01, 0x44, 0xE7, + 0x01, 0x4E, 0x46, 0x53, 0x9B, 0x33, 0x60, 0xF7, 0x94, 0xBE, 0x53, 0x37, + 0x90, 0x73, 0x43, 0xF3, 0x32, 0xC3, 0x53, 0xEF, 0xDB, 0xAA, 0xFE, 0x74, + 0x4E, 0x69, 0xC7, 0x6B, 0x8C, 0x60, 0x93, 0xDE, 0xC4, 0xC7, 0x0C, 0xDF, + 0xE1, 0x32, 0xAE, 0xCC, 0x93, 0x3B, 0x51, 0x78, 0x95, 0x67, 0x8B, 0xEE, + 0x3D, 0x56, 0xFE, 0x0C, 0xD0, 0x69, 0x0F, 0x1B, 0x0F, 0xF3, 0x25, 0x26, + 0x6B, 0x33, 0x6D, 0xF7, 0x6E, 0x47, 0xFA, 0x73, 0x43, 0xE5, 0x7E, 0x0E, + 0xA5, 0x66, 0xB1, 0x29, 0x7C, 0x32, 0x84, 0x63, 0x55, 0x89, 0xC4, 0x0D, + 0xC1, 0x93, 0x54, 0x30, 0x19, 0x13, 0xAC, 0xD3, 0x7D, 0x37, 0xA7, 0xEB, + 0x5D, 0x3A, 0x6C, 0x35, 0x5C, 0xDB, 0x41, 0xD7, 0x12, 0xDA, 0xA9, 0x49, + 0x0B, 0xDF, 0xD8, 0x80, 0x8A, 0x09, 0x93, 0x62, 0x8E, 0xB5, 0x66, 0xCF, + 0x25, 0x88, 0xCD, 0x84, 0xB8, 0xB1, 0x3F, 0xA4, 0x39, 0x0F, 0xD9, 0x02, + 0x9E, 0xEB, 0x12, 0x4C, 0x95, 0x7C, 0xF3, 0x6B, 0x05, 0xA9, 0x5E, 0x16, + 0x83, 0xCC, 0xB8, 0x67, 0xE2, 0xE8, 0x13, 0x9D, 0xCC, 0x5B, 0x82, 0xD3, + 0x4C, 0xB3, 0xED, 0x5B, 0xFF, 0xDE, 0xE5, 0x73, 0xAC, 0x23, 0x3B, 0x2D, + 0x00, 0xBF, 0x35, 0x55, 0x74, 0x09, 0x49, 0xD8, 0x49, 0x58, 0x1A, 0x7F, + 0x92, 0x36, 0xE6, 0x51, 0x92, 0x0E, 0xF3, 0x26, 0x7D, 0x1C, 0x4D, 0x17, + 0xBC, 0xC9, 0xEC, 0x43, 0x26, 0xD0, 0xBF, 0x41, 0x5F, 0x40, 0xA9, 0x44, + 0x44, 0xF4, 0x99, 0xE7, 0x57, 0x87, 0x9E, 0x50, 0x1F, 0x57, 0x54, 0xA8, + 0x3E, 0xFD, 0x74, 0x63, 0x2F, 0xB1, 0x50, 0x65, 0x09, 0xE6, 0x58, 0x42, + 0x2E, 0x43, 0x1A, 0x4C, 0xB4, 0xF0, 0x25, 0x47, 0x59, 0xFA, 0x04, 0x1E, + 0x93, 0xD4, 0x26, 0x46, 0x4A, 0x50, 0x81, 0xB2, 0xDE, 0xBE, 0x78, 0xB7, + 0xFC, 0x67, 0x15, 0xE1, 0xC9, 0x57, 0x84, 0x1E, 0x0F, 0x63, 0xD6, 0xE9, + 0x62, 0xBA, 0xD6, 0x5F, 0x55, 0x2E, 0xEA, 0x5C, 0xC6, 0x28, 0x08, 0x04, + 0x25, 0x39, 0xB8, 0x0E, 0x2B, 0xA9, 0xF2, 0x4C, 0x97, 0x1C, 0x07, 0x3F, + 0x0D, 0x52, 0xF5, 0xED, 0xEF, 0x2F, 0x82, 0x0F +}; + +static const unsigned char TA381_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA382_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x15, 0x77, 0x77, 0x77, 0x2E, 0x78, 0x72, 0x61, 0x6D, 0x70, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x58, + 0x52, 0x61, 0x6D, 0x70, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x24, 0x58, 0x52, 0x61, 0x6D, 0x70, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA382_RSA_N[] = { + 0x98, 0x24, 0x1E, 0xBD, 0x15, 0xB4, 0xBA, 0xDF, 0xC7, 0x8C, 0xA5, 0x27, + 0xB6, 0x38, 0x0B, 0x69, 0xF3, 0xB6, 0x4E, 0xA8, 0x2C, 0x2E, 0x21, 0x1D, + 0x5C, 0x44, 0xDF, 0x21, 0x5D, 0x7E, 0x23, 0x74, 0xFE, 0x5E, 0x7E, 0xB4, + 0x4A, 0xB7, 0xA6, 0xAD, 0x1F, 0xAE, 0xE0, 0x06, 0x16, 0xE2, 0x9B, 0x5B, + 0xD9, 0x67, 0x74, 0x6B, 0x5D, 0x80, 0x8F, 0x29, 0x9D, 0x86, 0x1B, 0xD9, + 0x9C, 0x0D, 0x98, 0x6D, 0x76, 0x10, 0x28, 0x58, 0xE4, 0x65, 0xB0, 0x7F, + 0x4A, 0x98, 0x79, 0x9F, 0xE0, 0xC3, 0x31, 0x7E, 0x80, 0x2B, 0xB5, 0x8C, + 0xC0, 0x40, 0x3B, 0x11, 0x86, 0xD0, 0xCB, 0xA2, 0x86, 0x36, 0x60, 0xA4, + 0xD5, 0x30, 0x82, 0x6D, 0xD9, 0x6E, 0xD0, 0x0F, 0x12, 0x04, 0x33, 0x97, + 0x5F, 0x4F, 0x61, 0x5A, 0xF0, 0xE4, 0xF9, 0x91, 0xAB, 0xE7, 0x1D, 0x3B, + 0xBC, 0xE8, 0xCF, 0xF4, 0x6B, 0x2D, 0x34, 0x7C, 0xE2, 0x48, 0x61, 0x1C, + 0x8E, 0xF3, 0x61, 0x44, 0xCC, 0x6F, 0xA0, 0x4A, 0xA9, 0x94, 0xB0, 0x4D, + 0xDA, 0xE7, 0xA9, 0x34, 0x7A, 0x72, 0x38, 0xA8, 0x41, 0xCC, 0x3C, 0x94, + 0x11, 0x7D, 0xEB, 0xC8, 0xA6, 0x8C, 0xB7, 0x86, 0xCB, 0xCA, 0x33, 0x3B, + 0xD9, 0x3D, 0x37, 0x8B, 0xFB, 0x7A, 0x3E, 0x86, 0x2C, 0xE7, 0x73, 0xD7, + 0x0A, 0x57, 0xAC, 0x64, 0x9B, 0x19, 0xEB, 0xF4, 0x0F, 0x04, 0x08, 0x8A, + 0xAC, 0x03, 0x17, 0x19, 0x64, 0xF4, 0x5A, 0x25, 0x22, 0x8D, 0x34, 0x2C, + 0xB2, 0xF6, 0x68, 0x1D, 0x12, 0x6D, 0xD3, 0x8A, 0x1E, 0x14, 0xDA, 0xC4, + 0x8F, 0xA6, 0xE2, 0x23, 0x85, 0xD5, 0x7A, 0x0D, 0xBD, 0x6A, 0xE0, 0xE9, + 0xEC, 0xEC, 0x17, 0xBB, 0x42, 0x1B, 0x67, 0xAA, 0x25, 0xED, 0x45, 0x83, + 0x21, 0xFC, 0xC1, 0xC9, 0x7C, 0xD5, 0x62, 0x3E, 0xFA, 0xF2, 0xC5, 0x2D, + 0xD3, 0xFD, 0xD4, 0x65 +}; + +static const unsigned char TA382_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA383_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x08, 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x10, 0x63, 0x65, 0x72, + 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA383_RSA_N[] = { + 0xB7, 0x33, 0xB9, 0x7E, 0xC8, 0x25, 0x4A, 0x8E, 0xB5, 0xDB, 0xB4, 0x28, + 0x1B, 0xAA, 0x57, 0x90, 0xE8, 0xD1, 0x22, 0xD3, 0x64, 0xBA, 0xD3, 0x93, + 0xE8, 0xD4, 0xAC, 0x86, 0x61, 0x40, 0x6A, 0x60, 0x57, 0x68, 0x54, 0x84, + 0x4D, 0xBC, 0x6A, 0x54, 0x02, 0x05, 0xFF, 0xDF, 0x9B, 0x9A, 0x2A, 0xAE, + 0x5D, 0x07, 0x8F, 0x4A, 0xC3, 0x28, 0x7F, 0xEF, 0xFB, 0x2B, 0xFA, 0x79, + 0xF1, 0xC7, 0xAD, 0xF0, 0x10, 0x53, 0x24, 0x90, 0x8B, 0x66, 0xC9, 0xA8, + 0x88, 0xAB, 0xAF, 0x5A, 0xA3, 0x00, 0xE9, 0xBE, 0xBA, 0x46, 0xEE, 0x5B, + 0x73, 0x7B, 0x2C, 0x17, 0x82, 0x81, 0x5E, 0x62, 0x2C, 0xA1, 0x02, 0x65, + 0xB3, 0xBD, 0xC5, 0x2B, 0x00, 0x7E, 0xC4, 0xFC, 0x03, 0x33, 0x57, 0x0D, + 0xED, 0xE2, 0xFA, 0xCE, 0x5D, 0x45, 0xD6, 0x38, 0xCD, 0x35, 0xB6, 0xB2, + 0xC1, 0xD0, 0x9C, 0x81, 0x4A, 0xAA, 0xE4, 0xB2, 0x01, 0x5C, 0x1D, 0x8F, + 0x5F, 0x99, 0xC4, 0xB1, 0xAD, 0xDB, 0x88, 0x21, 0xEB, 0x90, 0x08, 0x82, + 0x80, 0xF3, 0x30, 0xA3, 0x43, 0xE6, 0x90, 0x82, 0xAE, 0x55, 0x28, 0x49, + 0xED, 0x5B, 0xD7, 0xA9, 0x10, 0x38, 0x0E, 0xFE, 0x8F, 0x4C, 0x5B, 0x9B, + 0x46, 0xEA, 0x41, 0xF5, 0xB0, 0x08, 0x74, 0xC3, 0xD0, 0x88, 0x33, 0xB6, + 0x7C, 0xD7, 0x74, 0xDF, 0xDC, 0x84, 0xD1, 0x43, 0x0E, 0x75, 0x39, 0xA1, + 0x25, 0x40, 0x28, 0xEA, 0x78, 0xCB, 0x0E, 0x2C, 0x2E, 0x39, 0x9D, 0x8C, + 0x8B, 0x6E, 0x16, 0x1C, 0x2F, 0x26, 0x82, 0x10, 0xE2, 0xE3, 0x65, 0x94, + 0x0A, 0x04, 0xC0, 0x5E, 0xF7, 0x5D, 0x5B, 0xF8, 0x10, 0xE2, 0xD0, 0xBA, + 0x7A, 0x4B, 0xFB, 0xDE, 0x37, 0x00, 0x00, 0x1A, 0x5B, 0x28, 0xE3, 0xD2, + 0x9C, 0x73, 0x3E, 0x32, 0x87, 0x98, 0xA1, 0xC9, 0x51, 0x2F, 0xD7, 0xDE, + 0xAC, 0x33, 0xB3, 0x4F +}; + +static const unsigned char TA383_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA384_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x43, 0x45, 0x52, 0x54, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x53, + 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x13, + 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, + 0x54, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA384_RSA_N[] = { + 0xC0, 0xC5, 0x75, 0x19, 0x91, 0x7D, 0x44, 0x74, 0x74, 0x87, 0xFE, 0x0E, + 0x3B, 0x96, 0xDC, 0xD8, 0x01, 0x16, 0xCC, 0xEE, 0x63, 0x91, 0xE7, 0x0B, + 0x6F, 0xCE, 0x3B, 0x0A, 0x69, 0x1A, 0x7C, 0xC2, 0xE3, 0xAF, 0x82, 0x8E, + 0x86, 0xD7, 0x5E, 0x8F, 0x57, 0xEB, 0xD3, 0x21, 0x59, 0xFD, 0x39, 0x37, + 0x42, 0x30, 0xBE, 0x50, 0xEA, 0xB6, 0x0F, 0xA9, 0x88, 0xD8, 0x2E, 0x2D, + 0x69, 0x21, 0xE7, 0xD1, 0x37, 0x18, 0x4E, 0x7D, 0x91, 0xD5, 0x16, 0x5F, + 0x6B, 0x5B, 0x00, 0xC2, 0x39, 0x43, 0x0D, 0x36, 0x85, 0x52, 0xB9, 0x53, + 0x65, 0x0F, 0x1D, 0x42, 0xE5, 0x8F, 0xCF, 0x05, 0xD3, 0xEE, 0xDC, 0x0C, + 0x1A, 0xD9, 0xB8, 0x8B, 0x78, 0x22, 0x67, 0xE4, 0x69, 0xB0, 0x68, 0xC5, + 0x3C, 0xE4, 0x6C, 0x5A, 0x46, 0xE7, 0xCD, 0xC7, 0xFA, 0xEF, 0xC4, 0xEC, + 0x4B, 0xBD, 0x6A, 0xA4, 0xAC, 0xFD, 0xCC, 0x28, 0x51, 0xEF, 0x92, 0xB4, + 0x29, 0xAB, 0xAB, 0x35, 0x9A, 0x4C, 0xE4, 0xC4, 0x08, 0xC6, 0x26, 0xCC, + 0xF8, 0x69, 0x9F, 0xE4, 0x9C, 0xF0, 0x29, 0xD3, 0x5C, 0xF9, 0xC6, 0x16, + 0x25, 0x9E, 0x23, 0xC3, 0x20, 0xC1, 0x3D, 0x0F, 0x3F, 0x38, 0x40, 0xB0, + 0xFE, 0x82, 0x44, 0x38, 0xAA, 0x5A, 0x1A, 0x8A, 0x6B, 0x63, 0x58, 0x38, + 0xB4, 0x15, 0xD3, 0xB6, 0x11, 0x69, 0x7B, 0x1E, 0x54, 0xEE, 0x8C, 0x1A, + 0x22, 0xAC, 0x72, 0x97, 0x3F, 0x23, 0x59, 0x9B, 0xC9, 0x22, 0x84, 0xC1, + 0x07, 0x4F, 0xCC, 0x7F, 0xE2, 0x57, 0xCA, 0x12, 0x70, 0xBB, 0xA6, 0x65, + 0xF3, 0x69, 0x75, 0x63, 0xBD, 0x95, 0xFB, 0x1B, 0x97, 0xCD, 0xE4, 0xA8, + 0xAF, 0xF6, 0xD1, 0x4E, 0xA8, 0xD9, 0x8A, 0x71, 0x24, 0xCD, 0x36, 0x3D, + 0xBC, 0x96, 0xC4, 0xF1, 0x6C, 0xA9, 0xAE, 0xE5, 0xCF, 0x0D, 0x6E, 0x28, + 0x0D, 0xB0, 0x0E, 0xB5, 0xCA, 0x51, 0x7B, 0x78, 0x14, 0xC3, 0x20, 0x2F, + 0x7F, 0xFB, 0x14, 0x55, 0xE1, 0x11, 0x99, 0xFD, 0xD5, 0x0A, 0xA1, 0x9E, + 0x02, 0xE3, 0x62, 0x5F, 0xEB, 0x35, 0x4B, 0x2C, 0xB8, 0x72, 0xE8, 0x3E, + 0x3D, 0x4F, 0xAC, 0x2C, 0xBB, 0x2E, 0x86, 0xE2, 0xA3, 0x76, 0x8F, 0xE5, + 0x93, 0x2A, 0xCF, 0xA5, 0xAB, 0xC8, 0x5C, 0x8D, 0x4B, 0x06, 0xFF, 0x12, + 0x46, 0xAC, 0x78, 0xCB, 0x14, 0x07, 0x35, 0xE0, 0xA9, 0xDF, 0x8B, 0xE9, + 0xAF, 0x15, 0x4F, 0x16, 0x89, 0x5B, 0xBD, 0xF6, 0x8D, 0xC6, 0x59, 0xAE, + 0x88, 0x85, 0x0E, 0xC1, 0x89, 0xEB, 0x1F, 0x67, 0xC5, 0x45, 0x8E, 0xFF, + 0x6D, 0x37, 0x36, 0x2B, 0x78, 0x66, 0x83, 0x91, 0x51, 0x2B, 0x3D, 0xFF, + 0x51, 0x77, 0x76, 0x62, 0xA1, 0xEC, 0x67, 0x3E, 0x3E, 0x81, 0x83, 0xE0, + 0x56, 0xA9, 0x50, 0x1F, 0x1F, 0x7A, 0x99, 0xAB, 0x63, 0xBF, 0x84, 0x17, + 0x77, 0xF1, 0x0D, 0x3B, 0xDF, 0xF7, 0x9C, 0x61, 0xB3, 0x35, 0x98, 0x8A, + 0x3A, 0xB2, 0xEC, 0x3C, 0x1A, 0x37, 0x3F, 0x7E, 0x8F, 0x92, 0xCF, 0xD9, + 0x12, 0x14, 0x64, 0xDA, 0x10, 0x02, 0x15, 0x41, 0xFF, 0x4F, 0xC4, 0xEB, + 0x1C, 0xA3, 0xC9, 0xFA, 0x99, 0xF7, 0x46, 0xE9, 0xE1, 0x18, 0xD9, 0xB1, + 0xB8, 0x32, 0x2D, 0xCB, 0x14, 0x0C, 0x50, 0xD8, 0x83, 0x65, 0x83, 0xEE, + 0xB9, 0x5C, 0xCF, 0xCB, 0x05, 0x5A, 0x4C, 0xFA, 0x19, 0x97, 0x6B, 0xD6, + 0x5D, 0x13, 0xD3, 0xC2, 0x5C, 0x54, 0xBC, 0x32, 0x73, 0xA0, 0x78, 0xF5, + 0xF1, 0x6D, 0x1E, 0xCB, 0x9F, 0xA5, 0xA6, 0x9F, 0x22, 0xDC, 0xD1, 0x51, + 0x9E, 0x82, 0x79, 0x64, 0x60, 0x29, 0x13, 0x3E, 0xA3, 0xFD, 0x4F, 0x72, + 0x6A, 0xAB, 0xE2, 0xD4, 0xE5, 0xB8, 0x24, 0x55, 0x2C, 0x44, 0x4B, 0x8A, + 0x88, 0x44, 0x9C, 0xCA, 0x84, 0xD3, 0x2A, 0x3B +}; + +static const unsigned char TA384_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA385_DN[] = { + 0x30, 0x71, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, 0x63, + 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0E, 0x56, 0x41, 0x54, + 0x48, 0x55, 0x2D, 0x32, 0x33, 0x35, 0x38, 0x34, 0x34, 0x39, 0x37, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x15, 0x65, 0x2D, + 0x53, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA385_EC_Q[] = { + 0x04, 0x96, 0xDC, 0x3D, 0x8A, 0xD8, 0xB0, 0x7B, 0x6F, 0xC6, 0x27, 0xBE, + 0x44, 0x90, 0xB1, 0xB3, 0x56, 0x15, 0x7B, 0x8E, 0x43, 0x24, 0x7D, 0x1A, + 0x84, 0x59, 0xEE, 0x63, 0x68, 0xB2, 0xC6, 0x5E, 0x87, 0xD0, 0x15, 0x48, + 0x1E, 0xA8, 0x90, 0xAD, 0xBD, 0x53, 0xA2, 0xDA, 0xDE, 0x3A, 0x90, 0xA6, + 0x60, 0x5F, 0x68, 0x32, 0xB5, 0x86, 0x41, 0xDF, 0x87, 0x5B, 0x2C, 0x7B, + 0xC5, 0xFE, 0x7C, 0x7A, 0xDA +}; + +static const unsigned char TA386_DN[] = { + 0x30, 0x5E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x21, 0x65, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA386_RSA_N[] = { + 0xE1, 0x25, 0x0F, 0xEE, 0x8D, 0xDB, 0x88, 0x33, 0x75, 0x67, 0xCD, 0xAD, + 0x1F, 0x7D, 0x3A, 0x4E, 0x6D, 0x9D, 0xD3, 0x2F, 0x14, 0xF3, 0x63, 0x74, + 0xCB, 0x01, 0x21, 0x6A, 0x37, 0xEA, 0x84, 0x50, 0x07, 0x4B, 0x26, 0x5B, + 0x09, 0x43, 0x6C, 0x21, 0x9E, 0x6A, 0xC8, 0xD5, 0x03, 0xF5, 0x60, 0x69, + 0x8F, 0xCC, 0xF0, 0x22, 0xE4, 0x1F, 0xE7, 0xF7, 0x6A, 0x22, 0x31, 0xB7, + 0x2C, 0x15, 0xF2, 0xE0, 0xFE, 0x00, 0x6A, 0x43, 0xFF, 0x87, 0x65, 0xC6, + 0xB5, 0x1A, 0xC1, 0xA7, 0x4C, 0x6D, 0x22, 0x70, 0x21, 0x8A, 0x31, 0xF2, + 0x97, 0x74, 0x89, 0x09, 0x12, 0x26, 0x1C, 0x9E, 0xCA, 0xD9, 0x12, 0xA2, + 0x95, 0x3C, 0xDA, 0xE9, 0x67, 0xBF, 0x08, 0xA0, 0x64, 0xE3, 0xD6, 0x42, + 0xB7, 0x45, 0xEF, 0x97, 0xF4, 0xF6, 0xF5, 0xD7, 0xB5, 0x4A, 0x15, 0x02, + 0x58, 0x7D, 0x98, 0x58, 0x4B, 0x60, 0xBC, 0xCD, 0xD7, 0x0D, 0x9A, 0x13, + 0x33, 0x53, 0xD1, 0x61, 0xF9, 0x7A, 0xD5, 0xD7, 0x78, 0xB3, 0x9A, 0x33, + 0xF7, 0x00, 0x86, 0xCE, 0x1D, 0x4D, 0x94, 0x38, 0xAF, 0xA8, 0xEC, 0x78, + 0x51, 0x70, 0x8A, 0x5C, 0x10, 0x83, 0x51, 0x21, 0xF7, 0x11, 0x3D, 0x34, + 0x86, 0x5E, 0xE5, 0x48, 0xCD, 0x97, 0x81, 0x82, 0x35, 0x4C, 0x19, 0xEC, + 0x65, 0xF6, 0x6B, 0xC5, 0x05, 0xA1, 0xEE, 0x47, 0x13, 0xD6, 0xB3, 0x21, + 0x27, 0x94, 0x10, 0x0A, 0xD9, 0x24, 0x3B, 0xBA, 0xBE, 0x44, 0x13, 0x46, + 0x30, 0x3F, 0x97, 0x3C, 0xD8, 0xD7, 0xD7, 0x6A, 0xEE, 0x3B, 0x38, 0xE3, + 0x2B, 0xD4, 0x97, 0x0E, 0xB9, 0x1B, 0xE7, 0x07, 0x49, 0x7F, 0x37, 0x2A, + 0xF9, 0x77, 0x78, 0xCF, 0x54, 0xED, 0x5B, 0x46, 0x9D, 0xA3, 0x80, 0x0E, + 0x91, 0x43, 0xC1, 0xD6, 0x5B, 0x5F, 0x14, 0xBA, 0x9F, 0xA6, 0x8D, 0x24, + 0x47, 0x40, 0x59, 0xBF, 0x72, 0x38, 0xB2, 0x36, 0x6C, 0x37, 0xFF, 0x99, + 0xD1, 0x5D, 0x0E, 0x59, 0x0A, 0xAB, 0x69, 0xF7, 0xC0, 0xB2, 0x04, 0x45, + 0x7A, 0x54, 0x00, 0xAE, 0xBE, 0x53, 0xF6, 0xB5, 0xE7, 0xE1, 0xF8, 0x3C, + 0xA3, 0x31, 0xD2, 0xA9, 0xFE, 0x21, 0x52, 0x64, 0xC5, 0xA6, 0x67, 0xF0, + 0x75, 0x07, 0x06, 0x94, 0x14, 0x81, 0x55, 0xC6, 0x27, 0xE4, 0x01, 0x8F, + 0x17, 0xC1, 0x6A, 0x71, 0xD7, 0xBE, 0x4B, 0xFB, 0x94, 0x58, 0x7D, 0x7E, + 0x11, 0x33, 0xB1, 0x42, 0xF7, 0x62, 0x6C, 0x18, 0xD6, 0xCF, 0x09, 0x68, + 0x3E, 0x7F, 0x6C, 0xF6, 0x1E, 0x8F, 0x62, 0xAD, 0xA5, 0x63, 0xDB, 0x09, + 0xA7, 0x1F, 0x22, 0x42, 0x41, 0x1E, 0x6F, 0x99, 0x8A, 0x3E, 0xD7, 0xF9, + 0x3F, 0x40, 0x7A, 0x79, 0xB0, 0xA5, 0x01, 0x92, 0xD2, 0x9D, 0x3D, 0x08, + 0x15, 0xA5, 0x10, 0x01, 0x2D, 0xB3, 0x32, 0x76, 0xA8, 0x95, 0x0D, 0xB3, + 0x7A, 0x9A, 0xFB, 0x07, 0x10, 0x78, 0x11, 0x6F, 0xE1, 0x8F, 0xC7, 0xBA, + 0x0F, 0x25, 0x1A, 0x74, 0x2A, 0xE5, 0x1C, 0x98, 0x41, 0x99, 0xDF, 0x21, + 0x87, 0xE8, 0x95, 0x06, 0x6A, 0x0A, 0xB3, 0x6A, 0x47, 0x76, 0x65, 0xF6, + 0x3A, 0xCF, 0x8F, 0x62, 0x17, 0x19, 0x7B, 0x0A, 0x28, 0xCD, 0x1A, 0xD2, + 0x83, 0x1E, 0x21, 0xC7, 0x2C, 0xBF, 0xBE, 0xFF, 0x61, 0x68, 0xB7, 0x67, + 0x1B, 0xBB, 0x78, 0x4D, 0x8D, 0xCE, 0x67, 0xE5, 0xE4, 0xC1, 0x8E, 0xB7, + 0x23, 0x66, 0xE2, 0x9D, 0x90, 0x75, 0x34, 0x98, 0xA9, 0x36, 0x2B, 0x8A, + 0x9A, 0x94, 0xB9, 0x9D, 0xEC, 0xCC, 0x8A, 0xB1, 0xF8, 0x25, 0x89, 0x5C, + 0x5A, 0xB6, 0x2F, 0x8C, 0x1F, 0x6D, 0x79, 0x24, 0xA7, 0x52, 0x68, 0xC3, + 0x84, 0x35, 0xE2, 0x66, 0x8D, 0x63, 0x0E, 0x25, 0x4D, 0xD5, 0x19, 0xB2, + 0xE6, 0x79, 0x37, 0xA7, 0x22, 0x9D, 0x54, 0x31 +}; + +static const unsigned char TA386_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA387_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x43, 0x33 +}; + +static const unsigned char TA387_EC_Q[] = { + 0x04, 0xFD, 0xA5, 0x61, 0xAE, 0x7B, 0x26, 0x10, 0x1D, 0xE9, 0xB7, 0x22, + 0x30, 0xAE, 0x06, 0xF4, 0x81, 0xB3, 0xB1, 0x42, 0x71, 0x95, 0x39, 0xBC, + 0xD3, 0x52, 0xE3, 0xAF, 0xAF, 0xF9, 0xF2, 0x97, 0x35, 0x92, 0x36, 0x46, + 0x0E, 0x87, 0x95, 0x8D, 0xB9, 0x39, 0x5A, 0xE9, 0xBB, 0xDF, 0xD0, 0xFE, + 0xC8, 0x07, 0x41, 0x3C, 0xBB, 0x55, 0x6F, 0x83, 0xA3, 0x6A, 0xFB, 0x62, + 0xB0, 0x81, 0x89, 0x02, 0x70, 0x7D, 0x48, 0xC5, 0x4A, 0xE3, 0xE9, 0x22, + 0x54, 0x22, 0x4D, 0x93, 0xBB, 0x42, 0x0C, 0xAF, 0x77, 0x9C, 0x23, 0xA6, + 0x7D, 0xD7, 0x61, 0x11, 0xCE, 0x65, 0xC7, 0xF8, 0x7F, 0xFE, 0xF5, 0xF2, + 0xA9 +}; + +static const unsigned char TA388_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x17, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, + 0x33 +}; + +static const unsigned char TA388_EC_Q[] = { + 0x04, 0x23, 0xA5, 0x0C, 0xB8, 0x2D, 0x12, 0xF5, 0x28, 0xF3, 0xB1, 0xB2, + 0xDD, 0xE2, 0x02, 0x12, 0x80, 0x9E, 0x39, 0x5F, 0x49, 0x4D, 0x9F, 0xC9, + 0x25, 0x34, 0x59, 0x74, 0xEC, 0xBB, 0x06, 0x1C, 0xE7, 0xC0, 0x72, 0xAF, + 0xE8, 0xAE, 0x2F, 0xE1, 0x41, 0x54, 0x87, 0x14, 0xA8, 0x4A, 0xB2, 0xE8, + 0x7C, 0x82, 0xE6, 0x5B, 0x6A, 0xB5, 0xDC, 0xB3, 0x75, 0xCE, 0x8B, 0x06, + 0xD0, 0x86, 0x23, 0xBF, 0x46, 0xD5, 0x8E, 0x0F, 0x3F, 0x04, 0xF4, 0xD7, + 0x1C, 0x92, 0x7E, 0xF6, 0xA5, 0x63, 0xC2, 0xF5, 0x5F, 0x8E, 0x2E, 0x4F, + 0xA1, 0x18, 0x19, 0x02, 0x2B, 0x32, 0x0A, 0x82, 0x64, 0x7D, 0x16, 0x93, + 0xD1 +}; + +static const unsigned char TA389_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x1C, + 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x43, 0x31 +}; + +static const unsigned char TA389_RSA_N[] = { + 0xCF, 0xEB, 0xA9, 0xB9, 0xF1, 0x99, 0x05, 0xCC, 0xD8, 0x28, 0x21, 0x4A, + 0xF3, 0x73, 0x34, 0x51, 0x84, 0x56, 0x10, 0xF5, 0xA0, 0x4F, 0x2C, 0x12, + 0xE3, 0xFA, 0x13, 0x9A, 0x27, 0xD0, 0xCF, 0xF9, 0x79, 0x1A, 0x74, 0x5F, + 0x1D, 0x79, 0x39, 0xFC, 0x5B, 0xF8, 0x70, 0x8E, 0xE0, 0x92, 0x52, 0xF7, + 0xE4, 0x25, 0xF9, 0x54, 0x83, 0xD9, 0x1D, 0xD3, 0xC8, 0x5A, 0x85, 0x3F, + 0x5E, 0xC7, 0xB6, 0x07, 0xEE, 0x3E, 0xC0, 0xCE, 0x9A, 0xAF, 0xAC, 0x56, + 0x42, 0x2A, 0x39, 0x25, 0x70, 0xD6, 0xBF, 0xB5, 0x7B, 0x36, 0xAD, 0xAC, + 0xF6, 0x73, 0xDC, 0xCD, 0xD7, 0x1D, 0x8A, 0x83, 0xA5, 0xFB, 0x2B, 0x90, + 0x15, 0x37, 0x6B, 0x1C, 0x26, 0x47, 0xDC, 0x3B, 0x29, 0x56, 0x93, 0x6A, + 0xB3, 0xC1, 0x6A, 0x3A, 0x9D, 0x3D, 0xF5, 0xC1, 0x97, 0x38, 0x58, 0x05, + 0x8B, 0x1C, 0x11, 0xE3, 0xE4, 0xB4, 0xB8, 0x5D, 0x85, 0x1D, 0x83, 0xFE, + 0x78, 0x5F, 0x0B, 0x45, 0x68, 0x18, 0x48, 0xA5, 0x46, 0x73, 0x34, 0x3B, + 0xFE, 0x0F, 0xC8, 0x76, 0xBB, 0xC7, 0x18, 0xF3, 0x05, 0xD1, 0x86, 0xF3, + 0x85, 0xED, 0xE7, 0xB9, 0xD9, 0x32, 0xAD, 0x55, 0x88, 0xCE, 0xA6, 0xB6, + 0x91, 0xB0, 0x4F, 0xAC, 0x7E, 0x15, 0x23, 0x96, 0xF6, 0x3F, 0xF0, 0x20, + 0x34, 0x16, 0xDE, 0x0A, 0xC6, 0xC4, 0x04, 0x45, 0x79, 0x7F, 0xA7, 0xFD, + 0xBE, 0xD2, 0xA9, 0xA5, 0xAF, 0x9C, 0xC5, 0x23, 0x2A, 0xF7, 0x3C, 0x21, + 0x6C, 0xBD, 0xAF, 0x8F, 0x4E, 0xC5, 0x3A, 0xB2, 0xF3, 0x34, 0x12, 0xFC, + 0xDF, 0x80, 0x1A, 0x49, 0xA4, 0xD4, 0xA9, 0x95, 0xF7, 0x9E, 0x89, 0x5E, + 0xA2, 0x89, 0xAC, 0x94, 0xCB, 0xA8, 0x68, 0x9B, 0xAF, 0x8A, 0x65, 0x27, + 0xCD, 0x89, 0xEE, 0xDD, 0x8C, 0xB5, 0x6B, 0x29, 0x70, 0x43, 0xA0, 0x69, + 0x0B, 0xE4, 0xB9, 0x0F +}; + +static const unsigned char TA389_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA390_DN[] = { + 0x30, 0x67, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x13, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA390_RSA_N[] = { + 0x93, 0x4B, 0xBB, 0xE9, 0x66, 0x8A, 0xEE, 0x9D, 0x5B, 0xD5, 0x34, 0x93, + 0xD0, 0x1B, 0x1E, 0xC3, 0xE7, 0x9E, 0xB8, 0x64, 0x33, 0x7F, 0x63, 0x78, + 0x68, 0xB4, 0xCD, 0x2E, 0x71, 0x75, 0xD7, 0x9B, 0x20, 0xC6, 0x4D, 0x29, + 0xBC, 0xB6, 0x68, 0x60, 0x8A, 0xF7, 0x21, 0x9A, 0x56, 0x35, 0x5A, 0xF3, + 0x76, 0xBD, 0xD8, 0xCD, 0x9A, 0xFF, 0x93, 0x56, 0x4B, 0xA5, 0x59, 0x06, + 0xA1, 0x93, 0x34, 0x29, 0xDD, 0x16, 0x34, 0x75, 0x4E, 0xF2, 0x81, 0xB4, + 0xC7, 0x96, 0x4E, 0xAD, 0x19, 0x15, 0x52, 0x4A, 0xFE, 0x3C, 0x70, 0x75, + 0x70, 0xCD, 0xAF, 0x2B, 0xAB, 0x15, 0x9A, 0x33, 0x3C, 0xAA, 0xB3, 0x8B, + 0xAA, 0xCD, 0x43, 0xFD, 0xF5, 0xEA, 0x70, 0xFF, 0xED, 0xCF, 0x11, 0x3B, + 0x94, 0xCE, 0x4E, 0x32, 0x16, 0xD3, 0x23, 0x40, 0x2A, 0x77, 0xB3, 0xAF, + 0x3C, 0x01, 0x2C, 0x6C, 0xED, 0x99, 0x2C, 0x8B, 0xD9, 0x4E, 0x69, 0x98, + 0xB2, 0xF7, 0x8F, 0x41, 0xB0, 0x32, 0x78, 0x61, 0xD6, 0x0D, 0x5F, 0xC3, + 0xFA, 0xA2, 0x40, 0x92, 0x1D, 0x5C, 0x17, 0xE6, 0x70, 0x3E, 0x35, 0xE7, + 0xA2, 0xB7, 0xC2, 0x62, 0xE2, 0xAB, 0xA4, 0x38, 0x4C, 0xB5, 0x39, 0x35, + 0x6F, 0xEA, 0x03, 0x69, 0xFA, 0x3A, 0x54, 0x68, 0x85, 0x6D, 0xD6, 0xF2, + 0x2F, 0x43, 0x55, 0x1E, 0x91, 0x0D, 0x0E, 0xD8, 0xD5, 0x6A, 0xA4, 0x96, + 0xD1, 0x13, 0x3C, 0x2C, 0x78, 0x50, 0xE8, 0x3A, 0x92, 0xD2, 0x17, 0x56, + 0xE5, 0x35, 0x1A, 0x40, 0x1C, 0x3E, 0x8D, 0x2C, 0xED, 0x39, 0xDF, 0x42, + 0xE0, 0x83, 0x41, 0x74, 0xDF, 0xA3, 0xCD, 0xC2, 0x86, 0x60, 0x48, 0x68, + 0xE3, 0x69, 0x0B, 0x54, 0x00, 0x8B, 0xE4, 0x76, 0x69, 0x21, 0x0D, 0x79, + 0x4E, 0x34, 0x08, 0x5E, 0x14, 0xC2, 0xCC, 0xB1, 0xB7, 0xAD, 0xD7, 0x7C, + 0x70, 0x8A, 0xC7, 0x85 +}; + +static const unsigned char TA390_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA391_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1A, 0x30, + 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA391_EC_Q[] = { + 0x04, 0x65, 0x50, 0x4A, 0xAE, 0x8C, 0x79, 0x96, 0x4A, 0xAA, 0x1C, 0x08, + 0xC3, 0xA3, 0xA2, 0xCD, 0xFE, 0x59, 0x56, 0x41, 0x77, 0xFD, 0x26, 0x94, + 0x42, 0xBB, 0x1D, 0xCD, 0x08, 0xDB, 0x73, 0xB2, 0x5B, 0x75, 0xF3, 0xCF, + 0x9C, 0x4E, 0x82, 0xF4, 0xBF, 0xF8, 0x61, 0x26, 0x85, 0x6C, 0xD6, 0x85, + 0x5B, 0x72, 0x70, 0xD2, 0xFD, 0xDB, 0x62, 0xB4, 0xDF, 0x53, 0x8B, 0xBD, + 0xB1, 0x44, 0x58, 0x62, 0x42, 0x09, 0xC7, 0xFA, 0x7F, 0x5B, 0x10, 0xE7, + 0xFE, 0x40, 0xFD, 0xC0, 0xD8, 0xC3, 0x2B, 0x32, 0xE7, 0x70, 0xA6, 0xB7, + 0xA6, 0x20, 0x55, 0x1D, 0x7B, 0x80, 0x5D, 0x4B, 0x8F, 0x67, 0x4C, 0xF1, + 0x10 +}; + +static const unsigned char TA392_DN[] = { + 0x30, 0x43, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, + 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0D, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA392_RSA_N[] = { + 0xBD, 0x55, 0x7C, 0x61, 0xD3, 0xB8, 0x1D, 0x04, 0x62, 0x05, 0xA0, 0xAE, + 0x6C, 0xB7, 0x70, 0xB4, 0x41, 0xEA, 0x4B, 0x03, 0x5E, 0x10, 0x3F, 0x90, + 0x5A, 0x1C, 0x8B, 0x3B, 0xB0, 0x66, 0x8B, 0x6C, 0x48, 0xA6, 0x1C, 0x22, + 0xBA, 0xD5, 0x40, 0x92, 0xEE, 0x33, 0xB2, 0x23, 0x59, 0xC9, 0x8E, 0xBC, + 0x58, 0xDA, 0x8B, 0x9E, 0xD0, 0x19, 0xF2, 0x2F, 0x59, 0xC6, 0x8C, 0x63, + 0x5A, 0xBA, 0x9F, 0xA3, 0x0B, 0xB0, 0xB3, 0x9A, 0x5C, 0xBA, 0x11, 0xB8, + 0x12, 0xE9, 0x0C, 0xBB, 0xCF, 0x6E, 0x6C, 0x80, 0x87, 0x29, 0x14, 0x03, + 0x2C, 0x8D, 0x24, 0x9A, 0xC8, 0x64, 0x83, 0xB5, 0x6A, 0xAC, 0x13, 0x2C, + 0x33, 0xF1, 0x9F, 0xDC, 0x2C, 0x61, 0x3C, 0x1A, 0x3F, 0x70, 0x55, 0x9B, + 0xAD, 0x00, 0x52, 0x7F, 0xCF, 0x04, 0xB9, 0xFE, 0x36, 0xFA, 0x9C, 0xC0, + 0x16, 0xAE, 0x62, 0xFE, 0x96, 0x4C, 0x43, 0x7E, 0x55, 0x14, 0xBE, 0x1A, + 0xB3, 0xD2, 0x6D, 0xC2, 0xAF, 0x76, 0x66, 0x95, 0x6B, 0x2A, 0xB0, 0x94, + 0x77, 0x85, 0x5E, 0x04, 0x0F, 0x62, 0x1D, 0x63, 0x75, 0xF7, 0x6B, 0xE7, + 0xCB, 0x5B, 0x9A, 0x70, 0xEC, 0x3E, 0x67, 0x05, 0xF0, 0xFE, 0x07, 0x08, + 0x80, 0xCF, 0x28, 0xDB, 0x05, 0xC6, 0x14, 0x27, 0x2F, 0x86, 0x7D, 0xF0, + 0x27, 0xDE, 0xFF, 0xE6, 0x7E, 0x33, 0x48, 0xE7, 0x0B, 0x1E, 0x58, 0xD1, + 0x27, 0x2B, 0x53, 0x0E, 0x57, 0x4A, 0x65, 0xD7, 0xFB, 0xA2, 0x80, 0x60, + 0xFC, 0x4C, 0xBC, 0x35, 0x53, 0x01, 0x6A, 0x97, 0x72, 0x82, 0xAF, 0xF1, + 0x1D, 0x70, 0xE8, 0x9C, 0xF5, 0xEF, 0x5E, 0xC2, 0x6C, 0xC7, 0x47, 0x7E, + 0x5A, 0x94, 0x85, 0x26, 0x4D, 0x3B, 0xBA, 0xEB, 0x4C, 0xE8, 0xB0, 0x09, + 0xC2, 0x65, 0xC2, 0x9D, 0x9D, 0x09, 0x9B, 0x4E, 0xB5, 0x97, 0x05, 0xAC, + 0xF5, 0x06, 0xA0, 0xF7, 0x36, 0x05, 0x7E, 0xF4, 0x90, 0xB2, 0x6B, 0xC4, + 0xB4, 0xF9, 0x64, 0xEA, 0xE9, 0x1A, 0x0A, 0xC8, 0x0D, 0xA8, 0xED, 0x27, + 0xC9, 0xD4, 0xE7, 0xB3, 0xB9, 0xAB, 0x82, 0x22, 0x90, 0x27, 0x3D, 0x2A, + 0xE8, 0x7C, 0x90, 0xEF, 0xBC, 0x4F, 0xFD, 0xE2, 0x0A, 0x24, 0xA7, 0xDE, + 0x65, 0x24, 0xA4, 0x5D, 0xEA, 0xC0, 0x76, 0x30, 0xD3, 0x77, 0x50, 0xF8, + 0x0D, 0x04, 0x9B, 0x94, 0x36, 0x01, 0x73, 0xCA, 0x06, 0x58, 0xA6, 0xD3, + 0x3B, 0xDC, 0xFA, 0x04, 0x46, 0x13, 0x55, 0x8A, 0xC9, 0x44, 0x47, 0xB8, + 0x51, 0x39, 0x1A, 0x2E, 0xE8, 0x34, 0xE2, 0x79, 0xCB, 0x59, 0x4A, 0x0A, + 0x7F, 0xBC, 0xA6, 0xEF, 0x1F, 0x03, 0x67, 0x6A, 0x59, 0x2B, 0x25, 0x62, + 0x93, 0xD9, 0x53, 0x19, 0x66, 0x3C, 0x27, 0x62, 0x29, 0x86, 0x4D, 0xA4, + 0x6B, 0xEE, 0xFF, 0xD4, 0x4E, 0xBA, 0xD5, 0xB4, 0xE2, 0x8E, 0x48, 0x5A, + 0x00, 0x19, 0x09, 0xF1, 0x05, 0xD9, 0xCE, 0x91, 0xB1, 0xF7, 0xEB, 0xE9, + 0x39, 0x4F, 0xF6, 0x6F, 0x04, 0x43, 0x9A, 0x55, 0xF5, 0x3E, 0x05, 0x14, + 0xBD, 0xBF, 0xB3, 0x59, 0xB4, 0xD8, 0x8E, 0x33, 0x84, 0xA3, 0x90, 0x52, + 0xAA, 0xB3, 0x02, 0x95, 0x60, 0xF9, 0x0C, 0x4C, 0x68, 0xF9, 0xEE, 0xD5, + 0x17, 0x0D, 0xF8, 0x71, 0x57, 0xB5, 0x25, 0xE4, 0x29, 0xEE, 0x65, 0x5D, + 0xAF, 0xD1, 0xEE, 0x3C, 0x17, 0x0B, 0x5A, 0x43, 0xC5, 0xA5, 0x86, 0xEA, + 0x24, 0x9E, 0xE2, 0x05, 0x07, 0xDC, 0x34, 0x42, 0x12, 0x91, 0xD6, 0x39, + 0x74, 0xAE, 0x4C, 0x41, 0x82, 0xDB, 0xF2, 0xA6, 0x48, 0xD1, 0xB3, 0x9B, + 0xF3, 0x33, 0xAA, 0xF3, 0xA6, 0xC0, 0xC5, 0x4E, 0xF5, 0xF4, 0x9D, 0x76, + 0x63, 0xE6, 0x02, 0xC6, 0x22, 0x4B, 0xC1, 0x95, 0x3F, 0x50, 0x64, 0x2C, + 0x54, 0xE5, 0xB6, 0xF0, 0x3C, 0x29, 0xCF, 0x57 +}; + +static const unsigned char TA392_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA393_DN[] = { + 0x30, 0x42, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x09, 0x41, 0x43, 0x43, 0x56, 0x52, 0x41, 0x49, 0x5A, 0x31, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x50, 0x4B, 0x49, + 0x41, 0x43, 0x43, 0x56, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x04, 0x41, 0x43, 0x43, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53 +}; + +static const unsigned char TA393_RSA_N[] = { + 0x9B, 0xA9, 0xAB, 0xBF, 0x61, 0x4A, 0x97, 0xAF, 0x2F, 0x97, 0x66, 0x9A, + 0x74, 0x5F, 0xD0, 0xD9, 0x96, 0xFD, 0xCF, 0xE2, 0xE4, 0x66, 0xEF, 0x1F, + 0x1F, 0x47, 0x33, 0xC2, 0x44, 0xA3, 0xDF, 0x9A, 0xDE, 0x1F, 0xB5, 0x54, + 0xDD, 0x15, 0x7C, 0x69, 0x35, 0x11, 0x6F, 0xBB, 0xC8, 0x0C, 0x8E, 0x6A, + 0x18, 0x1E, 0xD8, 0x8F, 0xD9, 0x16, 0xBC, 0x10, 0x48, 0x36, 0x5C, 0xF0, + 0x63, 0xB3, 0x90, 0x5A, 0x5C, 0x24, 0x37, 0xD7, 0xA3, 0xD6, 0xCB, 0x09, + 0x71, 0xB9, 0xF1, 0x01, 0x72, 0x84, 0xB0, 0x7D, 0xDB, 0x4D, 0x80, 0xCD, + 0xFC, 0xD3, 0x6F, 0xC9, 0xF8, 0xDA, 0xB6, 0x0E, 0x82, 0xD2, 0x45, 0x85, + 0xA8, 0x1B, 0x68, 0xA8, 0x3D, 0xE8, 0xF4, 0x44, 0x6C, 0xBD, 0xA1, 0xC2, + 0xCB, 0x03, 0xBE, 0x8C, 0x3E, 0x13, 0x00, 0x84, 0xDF, 0x4A, 0x48, 0xC0, + 0xE3, 0x22, 0x0A, 0xE8, 0xE9, 0x37, 0xA7, 0x18, 0x4C, 0xB1, 0x09, 0x0D, + 0x23, 0x56, 0x7F, 0x04, 0x4D, 0xD9, 0x17, 0x84, 0x18, 0xA5, 0xC8, 0xDA, + 0x40, 0x94, 0x73, 0xEB, 0xCE, 0x0E, 0x57, 0x3C, 0x03, 0x81, 0x3A, 0x9D, + 0x0A, 0xA1, 0x57, 0x43, 0x69, 0xAC, 0x57, 0x6D, 0x79, 0x90, 0x78, 0xE5, + 0xB5, 0xB4, 0x3B, 0xD8, 0xBC, 0x4C, 0x8D, 0x28, 0xA1, 0xA7, 0xA3, 0xA7, + 0xBA, 0x02, 0x4E, 0x25, 0xD1, 0x2A, 0xAE, 0xED, 0xAE, 0x03, 0x22, 0xB8, + 0x6B, 0x20, 0x0F, 0x30, 0x28, 0x54, 0x95, 0x7F, 0xE0, 0xEE, 0xCE, 0x0A, + 0x66, 0x9D, 0xD1, 0x40, 0x2D, 0x6E, 0x22, 0xAF, 0x9D, 0x1A, 0xC1, 0x05, + 0x19, 0xD2, 0x6F, 0xC0, 0xF2, 0x9F, 0xF8, 0x7B, 0xB3, 0x02, 0x42, 0xFB, + 0x50, 0xA9, 0x1D, 0x2D, 0x93, 0x0F, 0x23, 0xAB, 0xC6, 0xC1, 0x0F, 0x92, + 0xFF, 0xD0, 0xA2, 0x15, 0xF5, 0x53, 0x09, 0x71, 0x1C, 0xFF, 0x45, 0x13, + 0x84, 0xE6, 0x26, 0x5E, 0xF8, 0xE0, 0x88, 0x1C, 0x0A, 0xFC, 0x16, 0xB6, + 0xA8, 0x73, 0x06, 0xB8, 0xF0, 0x63, 0x84, 0x02, 0xA0, 0xC6, 0x5A, 0xEC, + 0xE7, 0x74, 0xDF, 0x70, 0xAE, 0xA3, 0x83, 0x25, 0xEA, 0xD6, 0xC7, 0x97, + 0x87, 0x93, 0xA7, 0xC6, 0x8A, 0x8A, 0x33, 0x97, 0x60, 0x37, 0x10, 0x3E, + 0x97, 0x3E, 0x6E, 0x29, 0x15, 0xD6, 0xA1, 0x0F, 0xD1, 0x88, 0x2C, 0x12, + 0x9F, 0x6F, 0xAA, 0xA4, 0xC6, 0x42, 0xEB, 0x41, 0xA2, 0xE3, 0x95, 0x43, + 0xD3, 0x01, 0x85, 0x6D, 0x8E, 0xBB, 0x3B, 0xF3, 0x23, 0x36, 0xC7, 0xFE, + 0x3B, 0xE0, 0xA1, 0x25, 0x07, 0x48, 0xAB, 0xC9, 0x89, 0x74, 0xFF, 0x08, + 0x8F, 0x80, 0xBF, 0xC0, 0x96, 0x65, 0xF3, 0xEE, 0xEC, 0x4B, 0x68, 0xBD, + 0x9D, 0x88, 0xC3, 0x31, 0xB3, 0x40, 0xF1, 0xE8, 0xCF, 0xF6, 0x38, 0xBB, + 0x9C, 0xE4, 0xD1, 0x7F, 0xD4, 0xE5, 0x58, 0x9B, 0x7C, 0xFA, 0xD4, 0xF3, + 0x0E, 0x9B, 0x75, 0x91, 0xE4, 0xBA, 0x52, 0x2E, 0x19, 0x7E, 0xD1, 0xF5, + 0xCD, 0x5A, 0x19, 0xFC, 0xBA, 0x06, 0xF6, 0xFB, 0x52, 0xA8, 0x4B, 0x99, + 0x04, 0xDD, 0xF8, 0xF9, 0xB4, 0x8B, 0x50, 0xA3, 0x4E, 0x62, 0x89, 0xF0, + 0x87, 0x24, 0xFA, 0x83, 0x42, 0xC1, 0x87, 0xFA, 0xD5, 0x2D, 0x29, 0x2A, + 0x5A, 0x71, 0x7A, 0x64, 0x6A, 0xD7, 0x27, 0x60, 0x63, 0x0D, 0xDB, 0xCE, + 0x49, 0xF5, 0x8D, 0x1F, 0x90, 0x89, 0x32, 0x17, 0xF8, 0x73, 0x43, 0xB8, + 0xD2, 0x5A, 0x93, 0x86, 0x61, 0xD6, 0xE1, 0x75, 0x0A, 0xEA, 0x79, 0x66, + 0x76, 0x88, 0x4F, 0x71, 0xEB, 0x04, 0x25, 0xD6, 0x0A, 0x5A, 0x7A, 0x93, + 0xE5, 0xB9, 0x4B, 0x17, 0x40, 0x0F, 0xB1, 0xB6, 0xB9, 0xF5, 0xDE, 0x4F, + 0xDC, 0xE0, 0xB3, 0xAC, 0x3B, 0x11, 0x70, 0x60, 0x84, 0x4A, 0x43, 0x6E, + 0x99, 0x20, 0xC0, 0x29, 0x71, 0x0A, 0xC0, 0x65 +}; + +static const unsigned char TA393_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA394_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x41, 0x43, 0x20, + 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, + 0x4D +}; + +static const unsigned char TA394_RSA_N[] = { + 0xBA, 0x71, 0x80, 0x7A, 0x4C, 0x86, 0x6E, 0x7F, 0xC8, 0x13, 0x6D, 0xC0, + 0xC6, 0x7D, 0x1C, 0x00, 0x97, 0x8F, 0x2C, 0x0C, 0x23, 0xBB, 0x10, 0x9A, + 0x40, 0xA9, 0x1A, 0xB7, 0x87, 0x88, 0xF8, 0x9B, 0x56, 0x6A, 0xFB, 0xE6, + 0x7B, 0x8E, 0x8B, 0x92, 0x8E, 0xA7, 0x25, 0x5D, 0x59, 0x11, 0xDB, 0x36, + 0x2E, 0xB7, 0x51, 0x17, 0x1F, 0xA9, 0x08, 0x1F, 0x04, 0x17, 0x24, 0x58, + 0xAA, 0x37, 0x4A, 0x18, 0xDF, 0xE5, 0x39, 0xD4, 0x57, 0xFD, 0xD7, 0xC1, + 0x2C, 0x91, 0x01, 0x91, 0xE2, 0x22, 0xD4, 0x03, 0xC0, 0x58, 0xFC, 0x77, + 0x47, 0xEC, 0x8F, 0x3E, 0x74, 0x43, 0xBA, 0xAC, 0x34, 0x8D, 0x4D, 0x38, + 0x76, 0x67, 0x8E, 0xB0, 0xC8, 0x6F, 0x30, 0x33, 0x58, 0x71, 0x5C, 0xB4, + 0xF5, 0x6B, 0x6E, 0xD4, 0x01, 0x50, 0xB8, 0x13, 0x7E, 0x6C, 0x4A, 0xA3, + 0x49, 0xD1, 0x20, 0x19, 0xEE, 0xBC, 0xC0, 0x29, 0x18, 0x65, 0xA7, 0xDE, + 0xFE, 0xEF, 0xDD, 0x0A, 0x90, 0x21, 0xE7, 0x1A, 0x67, 0x92, 0x42, 0x10, + 0x98, 0x5F, 0x4F, 0x30, 0xBC, 0x3E, 0x1C, 0x45, 0xB4, 0x10, 0xD7, 0x68, + 0x40, 0x14, 0xC0, 0x40, 0xFA, 0xE7, 0x77, 0x17, 0x7A, 0xE6, 0x0B, 0x8F, + 0x65, 0x5B, 0x3C, 0xD9, 0x9A, 0x52, 0xDB, 0xB5, 0xBD, 0x9E, 0x46, 0xCF, + 0x3D, 0xEB, 0x91, 0x05, 0x02, 0xC0, 0x96, 0xB2, 0x76, 0x4C, 0x4D, 0x10, + 0x96, 0x3B, 0x92, 0xFA, 0x9C, 0x7F, 0x0F, 0x99, 0xDF, 0xBE, 0x23, 0x35, + 0x45, 0x1E, 0x02, 0x5C, 0xFE, 0xB5, 0xA8, 0x9B, 0x99, 0x25, 0xDA, 0x5E, + 0xF3, 0x22, 0xC3, 0x39, 0xF5, 0xE4, 0x2A, 0x2E, 0xD3, 0xC6, 0x1F, 0xC4, + 0x6C, 0xAA, 0xC5, 0x1C, 0x6A, 0x01, 0x05, 0x4A, 0x2F, 0xD2, 0xC5, 0xC1, + 0xA8, 0x34, 0x26, 0x5D, 0x66, 0xA5, 0xD2, 0x02, 0x21, 0xF9, 0x18, 0xB7, + 0x06, 0xF5, 0x4E, 0x99, 0x6F, 0xA8, 0xAB, 0x4C, 0x51, 0xE8, 0xCF, 0x50, + 0x18, 0xC5, 0x77, 0xC8, 0x39, 0x09, 0x2C, 0x49, 0x92, 0x32, 0x99, 0xA8, + 0xBB, 0x17, 0x17, 0x79, 0xB0, 0x5A, 0xC5, 0xE6, 0xA3, 0xC4, 0x59, 0x65, + 0x47, 0x35, 0x83, 0x5E, 0xA9, 0xE8, 0x35, 0x0B, 0x99, 0xBB, 0xE4, 0xCD, + 0x20, 0xC6, 0x9B, 0x4A, 0x06, 0x39, 0xB5, 0x68, 0xFC, 0x22, 0xBA, 0xEE, + 0x55, 0x8C, 0x2B, 0x4E, 0xEA, 0xF3, 0xB1, 0xE3, 0xFC, 0xB6, 0x99, 0x9A, + 0xD5, 0x42, 0xFA, 0x71, 0x4D, 0x08, 0xCF, 0x87, 0x1E, 0x6A, 0x71, 0x7D, + 0xF9, 0xD3, 0xB4, 0xE9, 0xA5, 0x71, 0x81, 0x7B, 0xC2, 0x4E, 0x47, 0x96, + 0xA5, 0xF6, 0x76, 0x85, 0xA3, 0x28, 0x8F, 0xE9, 0x80, 0x6E, 0x81, 0x53, + 0xA5, 0x6D, 0x5F, 0xB8, 0x48, 0xF9, 0xC2, 0xF9, 0x36, 0xA6, 0x2E, 0x49, + 0xFF, 0xB8, 0x96, 0xC2, 0x8C, 0x07, 0xB3, 0x9B, 0x88, 0x58, 0xFC, 0xEB, + 0x1B, 0x1C, 0xDE, 0x2D, 0x70, 0xE2, 0x97, 0x92, 0x30, 0xA1, 0x89, 0xE3, + 0xBC, 0x55, 0xA8, 0x27, 0xD6, 0x4B, 0xED, 0x90, 0xAD, 0x8B, 0xFA, 0x63, + 0x25, 0x59, 0x2D, 0xA8, 0x35, 0xDD, 0xCA, 0x97, 0x33, 0xBC, 0xE5, 0xCD, + 0xC7, 0x9D, 0xD1, 0xEC, 0xEF, 0x5E, 0x0E, 0x4A, 0x90, 0x06, 0x26, 0x63, + 0xAD, 0xB9, 0xD9, 0x35, 0x2D, 0x07, 0xBA, 0x76, 0x65, 0x2C, 0xAC, 0x57, + 0x8F, 0x7D, 0xF4, 0x07, 0x94, 0xD7, 0x81, 0x02, 0x96, 0x5D, 0xA3, 0x07, + 0x49, 0xD5, 0x7A, 0xD0, 0x57, 0xF9, 0x1B, 0xE7, 0x53, 0x46, 0x75, 0xAA, + 0xB0, 0x79, 0x42, 0xCB, 0x68, 0x71, 0x08, 0xE9, 0x60, 0xBD, 0x39, 0x69, + 0xCE, 0xF4, 0xAF, 0xC3, 0x56, 0x40, 0xC7, 0xAD, 0x52, 0xA2, 0x09, 0xE4, + 0x6F, 0x86, 0x47, 0x8A, 0x1F, 0xEB, 0x28, 0x27, 0x5D, 0x83, 0x20, 0xAF, + 0x04, 0xC9, 0x6C, 0x56, 0x9A, 0x8B, 0x46, 0xF5 +}; + +static const unsigned char TA394_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA395_DN[] = { + 0x30, 0x78, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x0E, + 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x05, 0x43, 0x65, 0x72, + 0x65, 0x73, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, + 0x0F, 0x56, 0x41, 0x54, 0x45, 0x53, 0x2D, 0x51, 0x32, 0x38, 0x32, 0x36, + 0x30, 0x30, 0x34, 0x4A, 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x23, 0x41, 0x43, 0x20, 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, + 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x20, 0x53, 0x45, 0x52, 0x56, + 0x49, 0x44, 0x4F, 0x52, 0x45, 0x53, 0x20, 0x53, 0x45, 0x47, 0x55, 0x52, + 0x4F, 0x53 +}; + +static const unsigned char TA395_EC_Q[] = { + 0x04, 0xF6, 0xBA, 0x57, 0x53, 0xC8, 0xCA, 0xAB, 0xDF, 0x36, 0x4A, 0x52, + 0x21, 0xE4, 0x97, 0xD2, 0x83, 0x67, 0x9E, 0xF0, 0x65, 0x51, 0xD0, 0x5E, + 0x87, 0xC7, 0x47, 0xB1, 0x59, 0xF2, 0x57, 0x47, 0x9B, 0x00, 0x02, 0x93, + 0x44, 0x17, 0x69, 0xDB, 0x42, 0xC7, 0xB1, 0xB2, 0x3A, 0x18, 0x0E, 0xB4, + 0x5D, 0x8C, 0xB3, 0x66, 0x5D, 0xA1, 0x34, 0xF9, 0x36, 0x2C, 0x49, 0xDB, + 0xF3, 0x46, 0xFC, 0xB3, 0x44, 0x69, 0x44, 0x13, 0x66, 0xFD, 0xD7, 0xC5, + 0xFD, 0xAF, 0x36, 0x4D, 0xCE, 0x03, 0x4D, 0x07, 0x71, 0xCF, 0xAF, 0x6A, + 0x05, 0xD2, 0xA2, 0x43, 0x5A, 0x0A, 0x52, 0x6F, 0x01, 0x03, 0x4E, 0x8E, + 0x8B +}; + +static const unsigned char TA396_DN[] = { + 0x30, 0x81, 0x84, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x05, + 0x13, 0x09, 0x47, 0x36, 0x33, 0x32, 0x38, 0x37, 0x35, 0x31, 0x30, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, + 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1E, 0x41, + 0x4E, 0x46, 0x20, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, + 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x63, 0x69, 0x6F, 0x6E, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x13, 0x0B, 0x41, 0x4E, 0x46, 0x20, 0x43, 0x41, 0x20, 0x52, + 0x61, 0x69, 0x7A, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x19, 0x41, 0x4E, 0x46, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA396_RSA_N[] = { + 0xDB, 0xEB, 0x6B, 0x2B, 0xE6, 0x64, 0x54, 0x95, 0x82, 0x90, 0xA3, 0x72, + 0xA4, 0x19, 0x01, 0x9D, 0x9C, 0x0B, 0x81, 0x5F, 0x73, 0x49, 0xBA, 0xA7, + 0xAC, 0xF3, 0x04, 0x4E, 0x7B, 0x96, 0x0B, 0xEC, 0x11, 0xE0, 0x5B, 0xA6, + 0x1C, 0xCE, 0x1B, 0xD2, 0x0D, 0x83, 0x1C, 0x2B, 0xB8, 0x9E, 0x1D, 0x7E, + 0x45, 0x32, 0x60, 0x0F, 0x07, 0xE9, 0x77, 0x58, 0x7E, 0x9F, 0x6A, 0xC8, + 0x61, 0x4E, 0xB6, 0x26, 0xC1, 0x4C, 0x8D, 0xFF, 0x4C, 0xEF, 0x34, 0xB2, + 0x1F, 0x65, 0xD8, 0xB9, 0x78, 0xF5, 0xAD, 0xA9, 0x71, 0xB9, 0xEF, 0x4F, + 0x58, 0x1D, 0xA5, 0xDE, 0x74, 0x20, 0x97, 0xA1, 0xED, 0x68, 0x4C, 0xDE, + 0x92, 0x17, 0x4B, 0xBC, 0xAB, 0xFF, 0x65, 0x9A, 0x9E, 0xFB, 0x47, 0xD9, + 0x57, 0x72, 0xF3, 0x09, 0xA1, 0xAE, 0x76, 0x44, 0x13, 0x6E, 0x9C, 0x2D, + 0x44, 0x39, 0xBC, 0xF9, 0xC7, 0x3B, 0xA4, 0x58, 0x3D, 0x41, 0xBD, 0xB4, + 0xC2, 0x49, 0xA3, 0xC8, 0x0D, 0xD2, 0x97, 0x2F, 0x07, 0x65, 0x52, 0x00, + 0xA7, 0x6E, 0xC8, 0xAF, 0x68, 0xEC, 0xF4, 0x14, 0x96, 0xB6, 0x57, 0x1F, + 0x56, 0xC3, 0x39, 0x9F, 0x2B, 0x6D, 0xE4, 0xF3, 0x3E, 0xF6, 0x35, 0x64, + 0xDA, 0x0C, 0x1C, 0xA1, 0x84, 0x4B, 0x2F, 0x4B, 0x4B, 0xE2, 0x2C, 0x24, + 0x9D, 0x6D, 0x93, 0x40, 0xEB, 0xB5, 0x23, 0x8E, 0x32, 0xCA, 0x6F, 0x45, + 0xD3, 0xA8, 0x89, 0x7B, 0x1E, 0xCF, 0x1E, 0xFA, 0x5B, 0x43, 0x8B, 0xCD, + 0xCD, 0xA8, 0x0F, 0x6A, 0xCA, 0x0C, 0x5E, 0xB9, 0x9E, 0x47, 0x8F, 0xF0, + 0xD9, 0xB6, 0x0A, 0x0B, 0x58, 0x65, 0x17, 0x33, 0xB9, 0x23, 0xE4, 0x77, + 0x19, 0x7D, 0xCB, 0x4A, 0x2E, 0x92, 0x7B, 0x4F, 0x2F, 0x10, 0x77, 0xB1, + 0x8D, 0x2F, 0x68, 0x9C, 0x62, 0xCC, 0xE0, 0x50, 0xF8, 0xEC, 0x91, 0xA7, + 0x54, 0x4C, 0x57, 0x09, 0xD5, 0x76, 0x63, 0xC5, 0xE8, 0x65, 0x1E, 0xEE, + 0x6D, 0x6A, 0xCF, 0x09, 0x9D, 0xFA, 0x7C, 0x4F, 0xAD, 0x60, 0x08, 0xFD, + 0x56, 0x99, 0x0F, 0x15, 0x2C, 0x7B, 0xA9, 0x80, 0xAB, 0x8C, 0x61, 0x8F, + 0x4A, 0x07, 0x76, 0x42, 0xDE, 0x3D, 0xF4, 0xDD, 0xB2, 0x24, 0x33, 0x5B, + 0xB8, 0xB5, 0xA3, 0x44, 0xC9, 0xAC, 0x7F, 0x77, 0x3C, 0x1D, 0x23, 0xEC, + 0x82, 0xA9, 0xA6, 0xE2, 0xC8, 0x06, 0x4C, 0x02, 0xFE, 0xAC, 0x5C, 0x99, + 0x99, 0x0B, 0x2F, 0x10, 0x8A, 0xA6, 0xF4, 0x7F, 0xD5, 0x87, 0x74, 0x0D, + 0x59, 0x49, 0x45, 0xF6, 0xF0, 0x71, 0x5C, 0x39, 0x29, 0xD6, 0xBF, 0x4A, + 0x23, 0x8B, 0xF5, 0x5F, 0x01, 0x63, 0xD2, 0x87, 0x73, 0x28, 0xB5, 0x4B, + 0x0A, 0xF5, 0xF8, 0xAB, 0x82, 0x2C, 0x7E, 0x73, 0x25, 0x32, 0x1D, 0x0B, + 0x63, 0x0A, 0x17, 0x81, 0x00, 0xFF, 0xB6, 0x76, 0x5E, 0xE7, 0xB4, 0xB1, + 0x40, 0xCA, 0x21, 0xBB, 0xD5, 0x80, 0x51, 0xE5, 0x48, 0x52, 0x67, 0x2C, + 0xD2, 0x61, 0x89, 0x07, 0x0D, 0x0F, 0xCE, 0x42, 0x77, 0xC0, 0x44, 0x73, + 0x9C, 0x44, 0x50, 0xA0, 0xDB, 0x10, 0x0A, 0x2D, 0x95, 0x1C, 0x81, 0xAF, + 0xE4, 0x1C, 0xE5, 0x14, 0x1E, 0xF1, 0x36, 0x41, 0x01, 0x02, 0x2F, 0x7D, + 0x73, 0xA7, 0xDE, 0x42, 0xCC, 0x4C, 0xE9, 0x89, 0x0D, 0x56, 0xF7, 0x9F, + 0x91, 0xD4, 0x03, 0xC6, 0x6C, 0xC9, 0x8F, 0xDB, 0xD8, 0x1C, 0xE0, 0x40, + 0x98, 0x5D, 0x66, 0x99, 0x98, 0x80, 0x6E, 0x2D, 0xFF, 0x01, 0xC5, 0xCE, + 0xCB, 0x46, 0x1F, 0xAC, 0x02, 0xC6, 0x43, 0xE6, 0xAE, 0xA2, 0x84, 0x3C, + 0xC5, 0x4E, 0x1E, 0x3D, 0x6D, 0xC9, 0x14, 0x4C, 0xE3, 0x2E, 0x41, 0xBB, + 0xCA, 0x39, 0xBF, 0x36, 0x3C, 0x2A, 0x19, 0xAA, 0x41, 0x87, 0x4E, 0xA5, + 0xCE, 0x4B, 0x32, 0x79, 0xDD, 0x90, 0x49, 0x7F +}; + +static const unsigned char TA396_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA397_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x54, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x05, 0x4D, 0x69, 0x6C, 0x61, 0x6E, 0x31, 0x23, 0x30, 0x21, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x1A, 0x41, 0x63, 0x74, 0x61, 0x6C, 0x69, + 0x73, 0x20, 0x53, 0x2E, 0x70, 0x2E, 0x41, 0x2E, 0x2F, 0x30, 0x33, 0x33, + 0x35, 0x38, 0x35, 0x32, 0x30, 0x39, 0x36, 0x37, 0x31, 0x27, 0x30, 0x25, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x41, 0x63, 0x74, 0x61, 0x6C, + 0x69, 0x73, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA397_RSA_N[] = { + 0xA7, 0xC6, 0xC4, 0xA5, 0x29, 0xA4, 0x2C, 0xEF, 0xE5, 0x18, 0xC5, 0xB0, + 0x50, 0xA3, 0x6F, 0x51, 0x3B, 0x9F, 0x0A, 0x5A, 0xC9, 0xC2, 0x48, 0x38, + 0x0A, 0xC2, 0x1C, 0xA0, 0x18, 0x7F, 0x91, 0xB5, 0x87, 0xB9, 0x40, 0x3F, + 0xDD, 0x1D, 0x68, 0x1F, 0x08, 0x83, 0xD5, 0x2D, 0x1E, 0x88, 0xA0, 0xF8, + 0x8F, 0x56, 0x8F, 0x6D, 0x99, 0x02, 0x92, 0x90, 0x16, 0xD5, 0x5F, 0x08, + 0x6C, 0x89, 0xD7, 0xE1, 0xAC, 0xBC, 0x20, 0xC2, 0xB1, 0xE0, 0x83, 0x51, + 0x8A, 0x69, 0x4D, 0x00, 0x96, 0x5A, 0x6F, 0x2F, 0xC0, 0x44, 0x7E, 0xA3, + 0x0E, 0xE4, 0x91, 0xCD, 0x58, 0xEE, 0xDC, 0xFB, 0xC7, 0x1E, 0x45, 0x47, + 0xDD, 0x27, 0xB9, 0x08, 0x01, 0x9F, 0xA6, 0x21, 0x1D, 0xF5, 0x41, 0x2D, + 0x2F, 0x4C, 0xFD, 0x28, 0xAD, 0xE0, 0x8A, 0xAD, 0x22, 0xB4, 0x56, 0x65, + 0x8E, 0x86, 0x54, 0x8F, 0x93, 0x43, 0x29, 0xDE, 0x39, 0x46, 0x78, 0xA3, + 0x30, 0x23, 0xBA, 0xCD, 0xF0, 0x7D, 0x13, 0x57, 0xC0, 0x5D, 0xD2, 0x83, + 0x6B, 0x48, 0x4C, 0xC4, 0xAB, 0x9F, 0x80, 0x5A, 0x5B, 0x3A, 0xBD, 0xC9, + 0xA7, 0x22, 0x3F, 0x80, 0x27, 0x33, 0x5B, 0x0E, 0xB7, 0x8A, 0x0C, 0x5D, + 0x07, 0x37, 0x08, 0xCB, 0x6C, 0xD2, 0x7A, 0x47, 0x22, 0x44, 0x35, 0xC5, + 0xCC, 0xCC, 0x2E, 0x8E, 0xDD, 0x2A, 0xED, 0xB7, 0x7D, 0x66, 0x0D, 0x5F, + 0x61, 0x51, 0x22, 0x55, 0x1B, 0xE3, 0x46, 0xE3, 0xE3, 0x3D, 0xD0, 0x35, + 0x62, 0x9A, 0xDB, 0xAF, 0x14, 0xC8, 0x5B, 0xA1, 0xCC, 0x89, 0x1B, 0xE1, + 0x30, 0x26, 0xFC, 0xA0, 0x9B, 0x1F, 0x81, 0xA7, 0x47, 0x1F, 0x04, 0xEB, + 0xA3, 0x39, 0x92, 0x06, 0x9F, 0x99, 0xD3, 0xBF, 0xD3, 0xEA, 0x4F, 0x50, + 0x9C, 0x19, 0xFE, 0x96, 0x87, 0x1E, 0x3C, 0x65, 0xF6, 0xA3, 0x18, 0x24, + 0x83, 0x86, 0x10, 0xE7, 0x54, 0x3E, 0xA8, 0x3A, 0x76, 0x24, 0x4F, 0x81, + 0x21, 0xC5, 0xE3, 0x0F, 0x02, 0xF8, 0x93, 0x94, 0x47, 0x20, 0xBB, 0xFE, + 0xD4, 0x0E, 0xD3, 0x68, 0xB9, 0xDD, 0xC4, 0x7A, 0x84, 0x82, 0xE3, 0x53, + 0x54, 0x79, 0xDD, 0xDB, 0x9C, 0xD2, 0xF2, 0x07, 0x9B, 0x2E, 0xB6, 0xBC, + 0x3E, 0xED, 0x85, 0x6D, 0xEF, 0x25, 0x11, 0xF2, 0x97, 0x1A, 0x42, 0x61, + 0xF7, 0x4A, 0x97, 0xE8, 0x8B, 0xB1, 0x10, 0x07, 0xFA, 0x65, 0x81, 0xB2, + 0xA2, 0x39, 0xCF, 0xF7, 0x3C, 0xFF, 0x18, 0xFB, 0xC6, 0xF1, 0x5A, 0x8B, + 0x59, 0xE2, 0x02, 0xAC, 0x7B, 0x92, 0xD0, 0x4E, 0x14, 0x4F, 0x59, 0x45, + 0xF6, 0x0C, 0x5E, 0x28, 0x5F, 0xB0, 0xE8, 0x3F, 0x45, 0xCF, 0xCF, 0xAF, + 0x9B, 0x6F, 0xFB, 0x84, 0xD3, 0x77, 0x5A, 0x95, 0x6F, 0xAC, 0x94, 0x84, + 0x9E, 0xEE, 0xBC, 0xC0, 0x4A, 0x8F, 0x4A, 0x93, 0xF8, 0x44, 0x21, 0xE2, + 0x31, 0x45, 0x61, 0x50, 0x4E, 0x10, 0xD8, 0xE3, 0x35, 0x7C, 0x4C, 0x19, + 0xB4, 0xDE, 0x05, 0xBF, 0xA3, 0x06, 0x9F, 0xC8, 0xB5, 0xCD, 0xE4, 0x1F, + 0xD7, 0x17, 0x06, 0x0D, 0x7A, 0x95, 0x74, 0x55, 0x0D, 0x68, 0x1A, 0xFC, + 0x10, 0x1B, 0x62, 0x64, 0x9D, 0x6D, 0xE0, 0x95, 0xA0, 0xC3, 0x94, 0x07, + 0x57, 0x0D, 0x14, 0xE6, 0xBD, 0x05, 0xFB, 0xB8, 0x9F, 0xE6, 0xDF, 0x8B, + 0xE2, 0xC6, 0xE7, 0x7E, 0x96, 0xF6, 0x53, 0xC5, 0x80, 0x34, 0x50, 0x28, + 0x58, 0xF0, 0x12, 0x50, 0x71, 0x17, 0x30, 0xBA, 0xE6, 0x78, 0x63, 0xBC, + 0xF4, 0xB2, 0xAD, 0x9B, 0x2B, 0xB2, 0xFE, 0xE1, 0x39, 0x8C, 0x5E, 0xBA, + 0x0B, 0x20, 0x94, 0xDE, 0x7B, 0x83, 0xB8, 0xFF, 0xE3, 0x56, 0x8D, 0xB7, + 0x11, 0xE9, 0x3B, 0x8C, 0xF2, 0xB1, 0xC1, 0x5D, 0x9D, 0xA4, 0x0B, 0x4C, + 0x2B, 0xD9, 0xB2, 0x18, 0xF5, 0xB5, 0x9F, 0x4B +}; + +static const unsigned char TA397_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA398_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C +}; + +static const unsigned char TA398_RSA_N[] = { + 0xF6, 0x1B, 0x4F, 0x67, 0x07, 0x2B, 0xA1, 0x15, 0xF5, 0x06, 0x22, 0xCB, + 0x1F, 0x01, 0xB2, 0xE3, 0x73, 0x45, 0x06, 0x44, 0x49, 0x2C, 0xBB, 0x49, + 0x25, 0x14, 0xD6, 0xCE, 0xC3, 0xB7, 0xAB, 0x2C, 0x4F, 0xC6, 0x41, 0x32, + 0x94, 0x57, 0xFA, 0x12, 0xA7, 0x5B, 0x0E, 0xE2, 0x8F, 0x1F, 0x1E, 0x86, + 0x19, 0xA7, 0xAA, 0xB5, 0x2D, 0xB9, 0x5F, 0x0D, 0x8A, 0xC2, 0xAF, 0x85, + 0x35, 0x79, 0x32, 0x2D, 0xBB, 0x1C, 0x62, 0x37, 0xF2, 0xB1, 0x5B, 0x4A, + 0x3D, 0xCA, 0xCD, 0x71, 0x5F, 0xE9, 0x42, 0xBE, 0x94, 0xE8, 0xC8, 0xDE, + 0xF9, 0x22, 0x48, 0x64, 0xC6, 0xE5, 0xAB, 0xC6, 0x2B, 0x6D, 0xAD, 0x05, + 0xF0, 0xFA, 0xD5, 0x0B, 0xCF, 0x9A, 0xE5, 0xF0, 0x50, 0xA4, 0x8B, 0x3B, + 0x47, 0xA5, 0x23, 0x5B, 0x7A, 0x7A, 0xF8, 0x33, 0x3F, 0xB8, 0xEF, 0x99, + 0x97, 0xE3, 0x20, 0xC1, 0xD6, 0x28, 0x89, 0xCF, 0x94, 0xFB, 0xB9, 0x45, + 0xED, 0xE3, 0x40, 0x17, 0x11, 0xD4, 0x74, 0xF0, 0x0B, 0x31, 0xE2, 0x2B, + 0x26, 0x6A, 0x9B, 0x4C, 0x57, 0xAE, 0xAC, 0x20, 0x3E, 0xBA, 0x45, 0x7A, + 0x05, 0xF3, 0xBD, 0x9B, 0x69, 0x15, 0xAE, 0x7D, 0x4E, 0x20, 0x63, 0xC4, + 0x35, 0x76, 0x3A, 0x07, 0x02, 0xC9, 0x37, 0xFD, 0xC7, 0x47, 0xEE, 0xE8, + 0xF1, 0x76, 0x1D, 0x73, 0x15, 0xF2, 0x97, 0xA4, 0xB5, 0xC8, 0x7A, 0x79, + 0xD9, 0x42, 0xAA, 0x2B, 0x7F, 0x5C, 0xFE, 0xCE, 0x26, 0x4F, 0xA3, 0x66, + 0x81, 0x35, 0xAF, 0x44, 0xBA, 0x54, 0x1E, 0x1C, 0x30, 0x32, 0x65, 0x9D, + 0xE6, 0x3C, 0x93, 0x5E, 0x50, 0x4E, 0x7A, 0xE3, 0x3A, 0xD4, 0x6E, 0xCC, + 0x1A, 0xFB, 0xF9, 0xD2, 0x37, 0xAE, 0x24, 0x2A, 0xAB, 0x57, 0x03, 0x22, + 0x28, 0x0D, 0x49, 0x75, 0x7F, 0xB7, 0x28, 0xDA, 0x75, 0xBF, 0x8E, 0xE3, + 0xDC, 0x0E, 0x79, 0x31 +}; + +static const unsigned char TA398_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA399_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, 0x67 +}; + +static const unsigned char TA399_RSA_N[] = { + 0xB4, 0x84, 0xCC, 0x33, 0x17, 0x2E, 0x6B, 0x94, 0x6C, 0x6B, 0x61, 0x52, + 0xA0, 0xEB, 0xA3, 0xCF, 0x79, 0x94, 0x4C, 0xE5, 0x94, 0x80, 0x99, 0xCB, + 0x55, 0x64, 0x44, 0x65, 0x8F, 0x67, 0x64, 0xE2, 0x06, 0xE3, 0x5C, 0x37, + 0x49, 0xF6, 0x2F, 0x9B, 0x84, 0x84, 0x1E, 0x2D, 0xF2, 0x60, 0x9D, 0x30, + 0x4E, 0xCC, 0x84, 0x85, 0xE2, 0x2C, 0xCF, 0x1E, 0x9E, 0xFE, 0x36, 0xAB, + 0x33, 0x77, 0x35, 0x44, 0xD8, 0x35, 0x96, 0x1A, 0x3D, 0x36, 0xE8, 0x7A, + 0x0E, 0xD8, 0xD5, 0x47, 0xA1, 0x6A, 0x69, 0x8B, 0xD9, 0xFC, 0xBB, 0x3A, + 0xAE, 0x79, 0x5A, 0xD5, 0xF4, 0xD6, 0x71, 0xBB, 0x9A, 0x90, 0x23, 0x6B, + 0x9A, 0xB7, 0x88, 0x74, 0x87, 0x0C, 0x1E, 0x5F, 0xB9, 0x9E, 0x2D, 0xFA, + 0xAB, 0x53, 0x2B, 0xDC, 0xBB, 0x76, 0x3E, 0x93, 0x4C, 0x08, 0x08, 0x8C, + 0x1E, 0xA2, 0x23, 0x1C, 0xD4, 0x6A, 0xAD, 0x22, 0xBA, 0x99, 0x01, 0x2E, + 0x6D, 0x65, 0xCB, 0xBE, 0x24, 0x66, 0x55, 0x24, 0x4B, 0x40, 0x44, 0xB1, + 0x1B, 0xD7, 0xE1, 0xC2, 0x85, 0xC0, 0xDE, 0x10, 0x3F, 0x3D, 0xED, 0xB8, + 0xFC, 0xF1, 0xF1, 0x23, 0x53, 0xDC, 0xBF, 0x65, 0x97, 0x6F, 0xD9, 0xF9, + 0x40, 0x71, 0x8D, 0x7D, 0xBD, 0x95, 0xD4, 0xCE, 0xBE, 0xA0, 0x5E, 0x27, + 0x23, 0xDE, 0xFD, 0xA6, 0xD0, 0x26, 0x0E, 0x00, 0x29, 0xEB, 0x3C, 0x46, + 0xF0, 0x3D, 0x60, 0xBF, 0x3F, 0x50, 0xD2, 0xDC, 0x26, 0x41, 0x51, 0x9E, + 0x14, 0x37, 0x42, 0x04, 0xA3, 0x70, 0x57, 0xA8, 0x1B, 0x87, 0xED, 0x2D, + 0xFA, 0x7B, 0xEE, 0x8C, 0x0A, 0xE3, 0xA9, 0x66, 0x89, 0x19, 0xCB, 0x41, + 0xF9, 0xDD, 0x44, 0x36, 0x61, 0xCF, 0xE2, 0x77, 0x46, 0xC8, 0x7D, 0xF6, + 0xF4, 0x92, 0x81, 0x36, 0xFD, 0xDB, 0x34, 0xF1, 0x72, 0x7E, 0xF3, 0x0C, + 0x16, 0xBD, 0xB4, 0x15 +}; + +static const unsigned char TA399_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA400_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x13, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D +}; + +static const unsigned char TA400_RSA_N[] = { + 0xC4, 0x12, 0xDF, 0xA9, 0x5F, 0xFE, 0x41, 0xDD, 0xDD, 0xF5, 0x9F, 0x8A, + 0xE3, 0xF6, 0xAC, 0xE1, 0x3C, 0x78, 0x9A, 0xBC, 0xD8, 0xF0, 0x7F, 0x7A, + 0xA0, 0x33, 0x2A, 0xDC, 0x8D, 0x20, 0x5B, 0xAE, 0x2D, 0x6F, 0xE7, 0x93, + 0xD9, 0x36, 0x70, 0x6A, 0x68, 0xCF, 0x8E, 0x51, 0xA3, 0x85, 0x5B, 0x67, + 0x04, 0xA0, 0x10, 0x24, 0x6F, 0x5D, 0x28, 0x82, 0xC1, 0x97, 0x57, 0xD8, + 0x48, 0x29, 0x13, 0xB6, 0xE1, 0xBE, 0x91, 0x4D, 0xDF, 0x85, 0x0C, 0x53, + 0x18, 0x9A, 0x1E, 0x24, 0xA2, 0x4F, 0x8F, 0xF0, 0xA2, 0x85, 0x0B, 0xCB, + 0xF4, 0x29, 0x7F, 0xD2, 0xA4, 0x58, 0xEE, 0x26, 0x4D, 0xC9, 0xAA, 0xA8, + 0x7B, 0x9A, 0xD9, 0xFA, 0x38, 0xDE, 0x44, 0x57, 0x15, 0xE5, 0xF8, 0x8C, + 0xC8, 0xD9, 0x48, 0xE2, 0x0D, 0x16, 0x27, 0x1D, 0x1E, 0xC8, 0x83, 0x85, + 0x25, 0xB7, 0xBA, 0xAA, 0x55, 0x41, 0xCC, 0x03, 0x22, 0x4B, 0x2D, 0x91, + 0x8D, 0x8B, 0xE6, 0x89, 0xAF, 0x66, 0xC7, 0xE9, 0xFF, 0x2B, 0xE9, 0x3C, + 0xAC, 0xDA, 0xD2, 0xB3, 0xC3, 0xE1, 0x68, 0x9C, 0x89, 0xF8, 0x7A, 0x00, + 0x56, 0xDE, 0xF4, 0x55, 0x95, 0x6C, 0xFB, 0xBA, 0x64, 0xDD, 0x62, 0x8B, + 0xDF, 0x0B, 0x77, 0x32, 0xEB, 0x62, 0xCC, 0x26, 0x9A, 0x9B, 0xBB, 0xAA, + 0x62, 0x83, 0x4C, 0xB4, 0x06, 0x7A, 0x30, 0xC8, 0x29, 0xBF, 0xED, 0x06, + 0x4D, 0x97, 0xB9, 0x1C, 0xC4, 0x31, 0x2B, 0xD5, 0x5F, 0xBC, 0x53, 0x12, + 0x17, 0x9C, 0x99, 0x57, 0x29, 0x66, 0x77, 0x61, 0x21, 0x31, 0x07, 0x2E, + 0x25, 0x49, 0x9D, 0x18, 0xF2, 0xEE, 0xF3, 0x2B, 0x71, 0x8C, 0xB5, 0xBA, + 0x39, 0x07, 0x49, 0x77, 0xFC, 0xEF, 0x2E, 0x92, 0x90, 0x05, 0x8D, 0x2D, + 0x2F, 0x77, 0x7B, 0xEF, 0x43, 0xBF, 0x35, 0xBB, 0x9A, 0xD8, 0xF9, 0x73, + 0xA7, 0x2C, 0xF2, 0xD0, 0x57, 0xEE, 0x28, 0x4E, 0x26, 0x5F, 0x8F, 0x90, + 0x68, 0x09, 0x2F, 0xB8, 0xF8, 0xDC, 0x06, 0xE9, 0x2E, 0x9A, 0x3E, 0x51, + 0xA7, 0xD1, 0x22, 0xC4, 0x0A, 0xA7, 0x38, 0x48, 0x6C, 0xB3, 0xF9, 0xFF, + 0x7D, 0xAB, 0x86, 0x57, 0xE3, 0xBA, 0xD6, 0x85, 0x78, 0x77, 0xBA, 0x43, + 0xEA, 0x48, 0x7F, 0xF6, 0xD8, 0xBE, 0x23, 0x6D, 0x1E, 0xBF, 0xD1, 0x36, + 0x6C, 0x58, 0x5C, 0xF1, 0xEE, 0xA4, 0x19, 0x54, 0x1A, 0xF5, 0x03, 0xD2, + 0x76, 0xE6, 0xE1, 0x8C, 0xBD, 0x3C, 0xB3, 0xD3, 0x48, 0x4B, 0xE2, 0xC8, + 0xF8, 0x7F, 0x92, 0xA8, 0x76, 0x46, 0x9C, 0x42, 0x65, 0x3E, 0xA4, 0x1E, + 0xC1, 0x07, 0x03, 0x5A, 0x46, 0x2D, 0xB8, 0x97, 0xF3, 0xB7, 0xD5, 0xB2, + 0x55, 0x21, 0xEF, 0xBA, 0xDC, 0x4C, 0x00, 0x97, 0xFB, 0x14, 0x95, 0x27, + 0x33, 0xBF, 0xE8, 0x43, 0x47, 0x46, 0xD2, 0x08, 0x99, 0x16, 0x60, 0x3B, + 0x9A, 0x7E, 0xD2, 0xE6, 0xED, 0x38, 0xEA, 0xEC, 0x01, 0x1E, 0x3C, 0x48, + 0x56, 0x49, 0x09, 0xC7, 0x4C, 0x37, 0x00, 0x9E, 0x88, 0x0E, 0xC0, 0x73, + 0xE1, 0x6F, 0x66, 0xE9, 0x72, 0x47, 0x30, 0x3E, 0x10, 0xE5, 0x0B, 0x03, + 0xC9, 0x9A, 0x42, 0x00, 0x6C, 0xC5, 0x94, 0x7E, 0x61, 0xC4, 0x8A, 0xDF, + 0x7F, 0x82, 0x1A, 0x0B, 0x59, 0xC4, 0x59, 0x32, 0x77, 0xB3, 0xBC, 0x60, + 0x69, 0x56, 0x39, 0xFD, 0xB4, 0x06, 0x7B, 0x2C, 0xD6, 0x64, 0x36, 0xD9, + 0xBD, 0x48, 0xED, 0x84, 0x1F, 0x7E, 0xA5, 0x22, 0x8F, 0x2A, 0xB8, 0x42, + 0xF4, 0x82, 0xB7, 0xD4, 0x53, 0x90, 0x78, 0x4E, 0x2D, 0x1A, 0xFD, 0x81, + 0x6F, 0x44, 0xD7, 0x3B, 0x01, 0x74, 0x96, 0x42, 0xE0, 0x00, 0xE2, 0x2E, + 0x6B, 0xEA, 0xC5, 0xEE, 0x72, 0xAC, 0xBB, 0xBF, 0xFE, 0xEA, 0xAA, 0xA8, + 0xF8, 0xDC, 0xF6, 0xB2, 0x79, 0x8A, 0xB6, 0x67 +}; + +static const unsigned char TA400_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA401_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA401_EC_Q[] = { + 0x04, 0x0D, 0x30, 0x5E, 0x1B, 0x15, 0x9D, 0x03, 0xD0, 0xA1, 0x79, 0x35, + 0xB7, 0x3A, 0x3C, 0x92, 0x7A, 0xCA, 0x15, 0x1C, 0xCD, 0x62, 0xF3, 0x9C, + 0x26, 0x5C, 0x07, 0x3D, 0xE5, 0x54, 0xFA, 0xA3, 0xD6, 0xCC, 0x12, 0xEA, + 0xF4, 0x14, 0x5F, 0xE8, 0x8E, 0x19, 0xAB, 0x2F, 0x2E, 0x48, 0xE6, 0xAC, + 0x18, 0x43, 0x78, 0xAC, 0xD0, 0x37, 0xC3, 0xBD, 0xB2, 0xCD, 0x2C, 0xE6, + 0x47, 0xE2, 0x1A, 0xE6, 0x63, 0xB8, 0x3D, 0x2E, 0x2F, 0x78, 0xC4, 0x4F, + 0xDB, 0xF4, 0x0F, 0xA4, 0x68, 0x4C, 0x55, 0x72, 0x6B, 0x95, 0x1D, 0x4E, + 0x18, 0x42, 0x95, 0x78, 0xCC, 0x37, 0x3C, 0x91, 0xE2, 0x9B, 0x65, 0x2B, + 0x29 +}; + +static const unsigned char TA402_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA402_RSA_N[] = { + 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80, + 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7, + 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86, + 0xD3, 0xA0, 0x43, 0x7A, 0x4E, 0xB2, 0xA4, 0xD0, 0x36, 0xBA, 0x01, 0xBE, + 0x8D, 0xDB, 0x48, 0xC8, 0x07, 0x17, 0x36, 0x4C, 0xF4, 0xEE, 0x88, 0x23, + 0xC7, 0x3E, 0xEB, 0x37, 0xF5, 0xB5, 0x19, 0xF8, 0x49, 0x68, 0xB0, 0xDE, + 0xD7, 0xB9, 0x76, 0x38, 0x1D, 0x61, 0x9E, 0xA4, 0xFE, 0x82, 0x36, 0xA5, + 0xE5, 0x4A, 0x56, 0xE4, 0x45, 0xE1, 0xF9, 0xFD, 0xB4, 0x16, 0xFA, 0x74, + 0xDA, 0x9C, 0x9B, 0x35, 0x39, 0x2F, 0xFA, 0xB0, 0x20, 0x50, 0x06, 0x6C, + 0x7A, 0xD0, 0x80, 0xB2, 0xA6, 0xF9, 0xAF, 0xEC, 0x47, 0x19, 0x8F, 0x50, + 0x38, 0x07, 0xDC, 0xA2, 0x87, 0x39, 0x58, 0xF8, 0xBA, 0xD5, 0xA9, 0xF9, + 0x48, 0x67, 0x30, 0x96, 0xEE, 0x94, 0x78, 0x5E, 0x6F, 0x89, 0xA3, 0x51, + 0xC0, 0x30, 0x86, 0x66, 0xA1, 0x45, 0x66, 0xBA, 0x54, 0xEB, 0xA3, 0xC3, + 0x91, 0xF9, 0x48, 0xDC, 0xFF, 0xD1, 0xE8, 0x30, 0x2D, 0x7D, 0x2D, 0x74, + 0x70, 0x35, 0xD7, 0x88, 0x24, 0xF7, 0x9E, 0xC4, 0x59, 0x6E, 0xBB, 0x73, + 0x87, 0x17, 0xF2, 0x32, 0x46, 0x28, 0xB8, 0x43, 0xFA, 0xB7, 0x1D, 0xAA, + 0xCA, 0xB4, 0xF2, 0x9F, 0x24, 0x0E, 0x2D, 0x4B, 0xF7, 0x71, 0x5C, 0x5E, + 0x69, 0xFF, 0xEA, 0x95, 0x02, 0xCB, 0x38, 0x8A, 0xAE, 0x50, 0x38, 0x6F, + 0xDB, 0xFB, 0x2D, 0x62, 0x1B, 0xC5, 0xC7, 0x1E, 0x54, 0xE1, 0x77, 0xE0, + 0x67, 0xC8, 0x0F, 0x9C, 0x87, 0x23, 0xD6, 0x3F, 0x40, 0x20, 0x7F, 0x20, + 0x80, 0xC4, 0x80, 0x4C, 0x3E, 0x3B, 0x24, 0x26, 0x8E, 0x04, 0xAE, 0x6C, + 0x9A, 0xC8, 0xAA, 0x0D +}; + +static const unsigned char TA402_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA403_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA403_RSA_N[] = { + 0xAD, 0x96, 0x9F, 0x2D, 0x9C, 0x4A, 0x4C, 0x4A, 0x81, 0x79, 0x51, 0x99, + 0xEC, 0x8A, 0xCB, 0x6B, 0x60, 0x51, 0x13, 0xBC, 0x4D, 0x6D, 0x06, 0xFC, + 0xB0, 0x08, 0x8D, 0xDD, 0x19, 0x10, 0x6A, 0xC7, 0x26, 0x0C, 0x35, 0xD8, + 0xC0, 0x6F, 0x20, 0x84, 0xE9, 0x94, 0xB1, 0x9B, 0x85, 0x03, 0xC3, 0x5B, + 0xDB, 0x4A, 0xE8, 0xC8, 0xF8, 0x90, 0x76, 0xD9, 0x5B, 0x4F, 0xE3, 0x4C, + 0xE8, 0x06, 0x36, 0x4D, 0xCC, 0x9A, 0xAC, 0x3D, 0x0C, 0x90, 0x2B, 0x92, + 0xD4, 0x06, 0x19, 0x60, 0xAC, 0x37, 0x44, 0x79, 0x85, 0x81, 0x82, 0xAD, + 0x5A, 0x37, 0xE0, 0x0D, 0xCC, 0x9D, 0xA6, 0x4C, 0x52, 0x76, 0xEA, 0x43, + 0x9D, 0xB7, 0x04, 0xD1, 0x50, 0xF6, 0x55, 0xE0, 0xD5, 0xD2, 0xA6, 0x49, + 0x85, 0xE9, 0x37, 0xE9, 0xCA, 0x7E, 0xAE, 0x5C, 0x95, 0x4D, 0x48, 0x9A, + 0x3F, 0xAE, 0x20, 0x5A, 0x6D, 0x88, 0x95, 0xD9, 0x34, 0xB8, 0x52, 0x1A, + 0x43, 0x90, 0xB0, 0xBF, 0x6C, 0x05, 0xB9, 0xB6, 0x78, 0xB7, 0xEA, 0xD0, + 0xE4, 0x3A, 0x3C, 0x12, 0x53, 0x62, 0xFF, 0x4A, 0xF2, 0x7B, 0xBE, 0x35, + 0x05, 0xA9, 0x12, 0x34, 0xE3, 0xF3, 0x64, 0x74, 0x62, 0x2C, 0x3D, 0x00, + 0x49, 0x5A, 0x28, 0xFE, 0x32, 0x44, 0xBB, 0x87, 0xDD, 0x65, 0x27, 0x02, + 0x71, 0x3B, 0xDA, 0x4A, 0xF7, 0x1F, 0xDA, 0xCD, 0xF7, 0x21, 0x55, 0x90, + 0x4F, 0x0F, 0xEC, 0xAE, 0x82, 0xE1, 0x9F, 0x6B, 0xD9, 0x45, 0xD3, 0xBB, + 0xF0, 0x5F, 0x87, 0xED, 0x3C, 0x2C, 0x39, 0x86, 0xDA, 0x3F, 0xDE, 0xEC, + 0x72, 0x55, 0xEB, 0x79, 0xA3, 0xAD, 0xDB, 0xDD, 0x7C, 0xB0, 0xBA, 0x1C, + 0xCE, 0xFC, 0xDE, 0x4F, 0x35, 0x76, 0xCF, 0x0F, 0xF8, 0x78, 0x1F, 0x6A, + 0x36, 0x51, 0x46, 0x27, 0x61, 0x5B, 0xE9, 0x9E, 0xCF, 0xF0, 0xA2, 0x55, + 0x7D, 0x7C, 0x25, 0x8A, 0x6F, 0x2F, 0xB4, 0xC5, 0xCF, 0x84, 0x2E, 0x2B, + 0xFD, 0x0D, 0x51, 0x10, 0x6C, 0xFB, 0x5F, 0x1B, 0xBC, 0x1B, 0x7E, 0xC5, + 0xAE, 0x3B, 0x98, 0x01, 0x31, 0x92, 0xFF, 0x0B, 0x57, 0xF4, 0x9A, 0xB2, + 0xB9, 0x57, 0xE9, 0xAB, 0xEF, 0x0D, 0x76, 0xD1, 0xF0, 0xEE, 0xF4, 0xCE, + 0x86, 0xA7, 0xE0, 0x6E, 0xE9, 0xB4, 0x69, 0xA1, 0xDF, 0x69, 0xF6, 0x33, + 0xC6, 0x69, 0x2E, 0x97, 0x13, 0x9E, 0xA5, 0x87, 0xB0, 0x57, 0x10, 0x81, + 0x37, 0xC9, 0x53, 0xB3, 0xBB, 0x7F, 0xF6, 0x92, 0xD1, 0x9C, 0xD0, 0x18, + 0xF4, 0x92, 0x6E, 0xDA, 0x83, 0x4F, 0xA6, 0x63, 0x99, 0x4C, 0xA5, 0xFB, + 0x5E, 0xEF, 0x21, 0x64, 0x7A, 0x20, 0x5F, 0x6C, 0x64, 0x85, 0x15, 0xCB, + 0x37, 0xE9, 0x62, 0x0C, 0x0B, 0x2A, 0x16, 0xDC, 0x01, 0x2E, 0x32, 0xDA, + 0x3E, 0x4B, 0xF5, 0x9E, 0x3A, 0xF6, 0x17, 0x40, 0x94, 0xEF, 0x9E, 0x91, + 0x08, 0x86, 0xFA, 0xBE, 0x63, 0xA8, 0x5A, 0x33, 0xEC, 0xCB, 0x74, 0x43, + 0x95, 0xF9, 0x6C, 0x69, 0x52, 0x36, 0xC7, 0x29, 0x6F, 0xFC, 0x55, 0x03, + 0x5C, 0x1F, 0xFB, 0x9F, 0xBD, 0x47, 0xEB, 0xE7, 0x49, 0x47, 0x95, 0x0B, + 0x4E, 0x89, 0x22, 0x09, 0x49, 0xE0, 0xF5, 0x61, 0x1E, 0xF1, 0xBF, 0x2E, + 0x8A, 0x72, 0x6E, 0x80, 0x59, 0xFF, 0x57, 0x3A, 0xF9, 0x75, 0x32, 0xA3, + 0x4E, 0x5F, 0xEC, 0xED, 0x28, 0x62, 0xD9, 0x4D, 0x73, 0xF2, 0xCC, 0x81, + 0x17, 0x60, 0xED, 0xCD, 0xEB, 0xDC, 0xDB, 0xA7, 0xCA, 0xC5, 0x7E, 0x02, + 0xBD, 0xF2, 0x54, 0x08, 0x54, 0xFD, 0xB4, 0x2D, 0x09, 0x2C, 0x17, 0x54, + 0x4A, 0x98, 0xD1, 0x54, 0xE1, 0x51, 0x67, 0x08, 0xD2, 0xED, 0x6E, 0x7E, + 0x6F, 0x3F, 0xD2, 0x2D, 0x81, 0x59, 0x29, 0x66, 0xCB, 0x90, 0x39, 0x95, + 0x11, 0x1E, 0x74, 0x27, 0xFE, 0xDD, 0xEB, 0xAF +}; + +static const unsigned char TA403_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA404_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA404_EC_Q[] = { + 0x04, 0x29, 0x97, 0xA7, 0xC6, 0x41, 0x7F, 0xC0, 0x0D, 0x9B, 0xE8, 0x01, + 0x1B, 0x56, 0xC6, 0xF2, 0x52, 0xA5, 0xBA, 0x2D, 0xB2, 0x12, 0xE8, 0xD2, + 0x2E, 0xD7, 0xFA, 0xC9, 0xC5, 0xD8, 0xAA, 0x6D, 0x1F, 0x73, 0x81, 0x3B, + 0x3B, 0x98, 0x6B, 0x39, 0x7C, 0x33, 0xA5, 0xC5, 0x4E, 0x86, 0x8E, 0x80, + 0x17, 0x68, 0x62, 0x45, 0x57, 0x7D, 0x44, 0x58, 0x1D, 0xB3, 0x37, 0xE5, + 0x67, 0x08, 0xEB, 0x66, 0xDE +}; + +static const unsigned char TA405_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x34 +}; + +static const unsigned char TA405_EC_Q[] = { + 0x04, 0xD2, 0xAB, 0x8A, 0x37, 0x4F, 0xA3, 0x53, 0x0D, 0xFE, 0xC1, 0x8A, + 0x7B, 0x4B, 0xA8, 0x7B, 0x46, 0x4B, 0x63, 0xB0, 0x62, 0xF6, 0x2D, 0x1B, + 0xDB, 0x08, 0x71, 0x21, 0xD2, 0x00, 0xE8, 0x63, 0xBD, 0x9A, 0x27, 0xFB, + 0xF0, 0x39, 0x6E, 0x5D, 0xEA, 0x3D, 0xA5, 0xC9, 0x81, 0xAA, 0xA3, 0x5B, + 0x20, 0x98, 0x45, 0x5D, 0x16, 0xDB, 0xFD, 0xE8, 0x10, 0x6D, 0xE3, 0x9C, + 0xE0, 0xE3, 0xBD, 0x5F, 0x84, 0x62, 0xF3, 0x70, 0x64, 0x33, 0xA0, 0xCB, + 0x24, 0x2F, 0x70, 0xBA, 0x88, 0xA1, 0x2A, 0xA0, 0x75, 0xF8, 0x81, 0xAE, + 0x62, 0x06, 0xC4, 0x81, 0xDB, 0x39, 0x6E, 0x29, 0xB0, 0x1E, 0xFA, 0x2E, + 0x5C +}; + +static const unsigned char TA406_DN[] = { + 0x30, 0x3C, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x15, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x0D, + 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x04, 0x41, 0x74, 0x6F, + 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x44, 0x45 +}; + +static const unsigned char TA406_RSA_N[] = { + 0x95, 0x85, 0x3B, 0x97, 0x6F, 0x2A, 0x3B, 0x2E, 0x3B, 0xCF, 0xA6, 0xF3, + 0x29, 0x35, 0xBE, 0xCF, 0x18, 0xAC, 0x3E, 0xAA, 0xD9, 0xF8, 0x4D, 0xA0, + 0x3E, 0x1A, 0x47, 0xB9, 0xBC, 0x9A, 0xDF, 0xF2, 0xFE, 0xCC, 0x3E, 0x47, + 0xE8, 0x7A, 0x96, 0xC2, 0x24, 0x8E, 0x35, 0xF4, 0xA9, 0x0C, 0xFC, 0x82, + 0xFD, 0x6D, 0xC1, 0x72, 0x62, 0x27, 0xBD, 0xEA, 0x6B, 0xEB, 0xE7, 0x8A, + 0xCC, 0x54, 0x3E, 0x90, 0x50, 0xCF, 0x80, 0xD4, 0x95, 0xFB, 0xE8, 0xB5, + 0x82, 0xD4, 0x14, 0xC5, 0xB6, 0xA9, 0x55, 0x25, 0x57, 0xDB, 0xB1, 0x50, + 0xF6, 0xB0, 0x60, 0x64, 0x59, 0x7A, 0x69, 0xCF, 0x03, 0xB7, 0x6F, 0x0D, + 0xBE, 0xCA, 0x3E, 0x6F, 0x74, 0x72, 0xEA, 0xAA, 0x30, 0x2A, 0x73, 0x62, + 0xBE, 0x49, 0x91, 0x61, 0xC8, 0x11, 0xFE, 0x0E, 0x03, 0x2A, 0xF7, 0x6A, + 0x20, 0xDC, 0x02, 0x15, 0x0D, 0x5E, 0x15, 0x6A, 0xFC, 0xE3, 0x82, 0xC1, + 0xB5, 0xC5, 0x9D, 0x64, 0x09, 0x6C, 0xA3, 0x59, 0x98, 0x07, 0x27, 0xC7, + 0x1B, 0x96, 0x2B, 0x61, 0x74, 0x71, 0x6C, 0x43, 0xF1, 0xF7, 0x35, 0x89, + 0x10, 0xE0, 0x9E, 0xEC, 0x55, 0xA1, 0x37, 0x22, 0xA2, 0x87, 0x04, 0x05, + 0x2C, 0x47, 0x7D, 0xB4, 0x1C, 0xB9, 0x62, 0x29, 0x66, 0x28, 0xCA, 0xB7, + 0xE1, 0x93, 0xF5, 0xA4, 0x94, 0x03, 0x99, 0xB9, 0x70, 0x85, 0xB5, 0xE6, + 0x48, 0xEA, 0x8D, 0x50, 0xFC, 0xD9, 0xDE, 0xCC, 0x6F, 0x07, 0x0E, 0xDD, + 0x0B, 0x72, 0x9D, 0x80, 0x30, 0x16, 0x07, 0x95, 0x3F, 0x28, 0x0E, 0xFD, + 0xC5, 0x75, 0x4F, 0x53, 0xD6, 0x74, 0x9A, 0xB4, 0x24, 0x2E, 0x8E, 0x02, + 0x91, 0xCF, 0x76, 0xC5, 0x9B, 0x1E, 0x55, 0x74, 0x9C, 0x78, 0x21, 0xB1, + 0xF0, 0x2D, 0xF1, 0x0B, 0x9F, 0xC2, 0xD5, 0x96, 0x18, 0x1F, 0xF0, 0x54, + 0x22, 0x7A, 0x8C, 0x07 +}; + +static const unsigned char TA406_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA407_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x45, 0x43, 0x43, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA407_EC_Q[] = { + 0x04, 0x96, 0x86, 0x58, 0x28, 0x37, 0x0A, 0x67, 0xD0, 0xA0, 0xDE, 0x24, + 0x19, 0x19, 0xE1, 0xE4, 0x05, 0x07, 0x1F, 0x97, 0xED, 0xE8, 0x64, 0x82, + 0xB9, 0xF6, 0xC4, 0x71, 0x50, 0xCE, 0x8A, 0x0C, 0xFF, 0xD7, 0xB5, 0x76, + 0xBB, 0xA1, 0x6C, 0x93, 0x6C, 0x83, 0xA2, 0x68, 0x6E, 0xA5, 0xD9, 0xBE, + 0x2C, 0x88, 0x95, 0x41, 0xCD, 0x5D, 0xDD, 0xB1, 0xCA, 0x83, 0x63, 0x83, + 0xCC, 0xC0, 0xBE, 0x74, 0xD9, 0xE0, 0x9D, 0xA4, 0xEE, 0x4A, 0x4E, 0x56, + 0xE0, 0x98, 0x29, 0x41, 0x93, 0x52, 0x10, 0xD5, 0x24, 0x38, 0x02, 0x32, + 0x67, 0xF1, 0x94, 0x12, 0x6F, 0xEF, 0xD7, 0xC5, 0xDE, 0x2E, 0xFD, 0x19, + 0x80 +}; + +static const unsigned char TA408_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA408_RSA_N[] = { + 0xB6, 0x80, 0x0E, 0xC4, 0x79, 0xBD, 0x05, 0x8C, 0x7D, 0xB0, 0xA3, 0x9D, + 0x4D, 0x22, 0x4D, 0xCB, 0xF0, 0x41, 0x97, 0x4D, 0x59, 0xE0, 0xD1, 0xFE, + 0x56, 0x8C, 0x97, 0xF2, 0xD7, 0xBD, 0x8F, 0x6C, 0xB7, 0x23, 0x8F, 0x5F, + 0xD5, 0xC4, 0xD8, 0x41, 0xCB, 0xF2, 0x02, 0x1E, 0x71, 0xE5, 0xE9, 0xF6, + 0x5E, 0xCB, 0x08, 0x2A, 0x5E, 0x30, 0xF2, 0x2D, 0x66, 0xC7, 0x84, 0x1B, + 0x64, 0x57, 0x38, 0x9D, 0x75, 0x2D, 0x56, 0xC6, 0x2F, 0x61, 0xEF, 0x96, + 0xFC, 0x20, 0x46, 0xBD, 0xEB, 0xD4, 0x7B, 0x3F, 0x3F, 0x7C, 0x47, 0x38, + 0x04, 0xA9, 0x1B, 0xAA, 0x52, 0xDF, 0x13, 0x37, 0xD3, 0x15, 0x15, 0x4E, + 0xBD, 0x5F, 0x7C, 0xAF, 0xAD, 0x63, 0xC7, 0x79, 0xDC, 0x08, 0x7B, 0xD5, + 0xA0, 0xE5, 0xF7, 0x5B, 0x75, 0xAC, 0x80, 0x55, 0x99, 0x92, 0x61, 0x9B, + 0xCD, 0x2A, 0x17, 0x7D, 0xDB, 0x8F, 0xF4, 0xB5, 0x6A, 0xEA, 0x17, 0x4A, + 0x64, 0x28, 0x66, 0x15, 0x29, 0x6C, 0x02, 0xF1, 0x6B, 0xD5, 0xBA, 0xA3, + 0x33, 0xDC, 0x5A, 0x67, 0xA7, 0x05, 0xE2, 0xBF, 0x65, 0xB6, 0x16, 0xB0, + 0x10, 0xED, 0xCD, 0x50, 0x33, 0xC9, 0x70, 0x50, 0xEC, 0x19, 0x8E, 0xB0, + 0xC7, 0xF2, 0x74, 0x5B, 0x6B, 0x44, 0xC6, 0x7D, 0x96, 0xB9, 0x98, 0x08, + 0x59, 0x66, 0xDE, 0x29, 0x01, 0x9B, 0xF4, 0x2A, 0x6D, 0xD3, 0x15, 0x3A, + 0x90, 0x6A, 0x67, 0xF1, 0xB4, 0x6B, 0x66, 0xD9, 0x21, 0xEB, 0xCA, 0xD9, + 0x62, 0x7C, 0x46, 0x10, 0x5C, 0xDE, 0x75, 0x49, 0x67, 0x9E, 0x42, 0xF9, + 0xFE, 0x75, 0xA9, 0xA3, 0xAD, 0xFF, 0x76, 0x0A, 0x67, 0x40, 0xE3, 0xC5, + 0xF7, 0x8D, 0xC7, 0x85, 0x9A, 0x59, 0x9E, 0x62, 0x9A, 0x6A, 0xED, 0x45, + 0x87, 0x98, 0x67, 0xB2, 0xD5, 0x4A, 0x3C, 0xD7, 0xB4, 0x3B, 0x00, 0x0D, + 0xC0, 0x8F, 0x1F, 0xE1, 0x40, 0xC4, 0xAE, 0x6C, 0x21, 0xDC, 0x49, 0x7E, + 0x7E, 0xCA, 0xB2, 0x8D, 0x6D, 0xB6, 0xBF, 0x93, 0x2F, 0xA1, 0x5C, 0x3E, + 0x8F, 0xCA, 0xED, 0x80, 0x8E, 0x58, 0xE1, 0xDB, 0x57, 0xCF, 0x85, 0x36, + 0x38, 0xB2, 0x71, 0xA4, 0x09, 0x8C, 0x92, 0x89, 0x08, 0x88, 0x48, 0xF1, + 0x40, 0x63, 0x18, 0xB2, 0x5B, 0x8C, 0x5A, 0xE3, 0xC3, 0xD3, 0x17, 0xAA, + 0xAB, 0x19, 0xA3, 0x2C, 0x1B, 0xE4, 0xD5, 0xC6, 0xE2, 0x66, 0x7A, 0xD7, + 0x82, 0x19, 0xA6, 0x3B, 0x16, 0x2C, 0x2F, 0x71, 0x87, 0x5F, 0x45, 0x9E, + 0x95, 0x73, 0x93, 0xC2, 0x42, 0x81, 0x21, 0x13, 0x96, 0xD7, 0x9D, 0xBB, + 0x93, 0x68, 0x15, 0xFA, 0x9D, 0xA4, 0x1D, 0x8C, 0xF2, 0x81, 0xE0, 0x58, + 0x06, 0xBD, 0xC9, 0xB6, 0xE3, 0xF6, 0x89, 0x5D, 0x89, 0xF9, 0xAC, 0x44, + 0xA1, 0xCB, 0x6B, 0xFA, 0x16, 0xF1, 0xC7, 0x50, 0x3D, 0x24, 0xDA, 0xF7, + 0xC3, 0xE4, 0x87, 0xD5, 0x56, 0xF1, 0x4F, 0x90, 0x30, 0xFA, 0x45, 0x09, + 0x59, 0xDA, 0x34, 0xCE, 0xE0, 0x13, 0x1C, 0x04, 0x7C, 0x00, 0xD4, 0x9B, + 0x86, 0xA4, 0x40, 0xBC, 0xD9, 0xDC, 0x4C, 0x57, 0x7E, 0xAE, 0xB7, 0x33, + 0xB6, 0x5E, 0x76, 0xE1, 0x65, 0x8B, 0x66, 0xDF, 0x8D, 0xCA, 0xD7, 0x98, + 0xAF, 0xCE, 0x36, 0x98, 0x8C, 0x9C, 0x83, 0x99, 0x03, 0x70, 0xF3, 0xAF, + 0x74, 0xED, 0xC6, 0x0E, 0x36, 0xE7, 0xBD, 0xEC, 0xC1, 0x73, 0xA7, 0x94, + 0x5A, 0xCB, 0x92, 0x64, 0x82, 0xA6, 0x00, 0xC1, 0x70, 0xA1, 0x6E, 0x2C, + 0x29, 0xE1, 0x58, 0x57, 0xEC, 0x5A, 0x7C, 0x99, 0x6B, 0x25, 0xA4, 0x90, + 0x3A, 0x80, 0xF4, 0x20, 0x9D, 0x9A, 0xCE, 0xC7, 0x2D, 0xF9, 0xB2, 0x4B, + 0x29, 0x95, 0x83, 0xE9, 0x35, 0x8D, 0xA7, 0x49, 0x48, 0xA7, 0x0F, 0x4C, + 0x19, 0x91, 0xD0, 0xF5, 0xBF, 0x10, 0xE0, 0x71 +}; + +static const unsigned char TA408_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA409_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x39, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, 0x20, + 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x63, 0x69, 0x6F, 0x6E, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, + 0x6F, 0x66, 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x43, 0x49, + 0x46, 0x20, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38 +}; + +static const unsigned char TA409_RSA_N[] = { + 0xCA, 0x96, 0x6B, 0x8E, 0xEA, 0xF8, 0xFB, 0xF1, 0xA2, 0x35, 0xE0, 0x7F, + 0x4C, 0xDA, 0xE0, 0xC3, 0x52, 0xD7, 0x7D, 0xB6, 0x10, 0xC8, 0x02, 0x5E, + 0xB3, 0x43, 0x2A, 0xC4, 0x4F, 0x6A, 0xB2, 0xCA, 0x1C, 0x5D, 0x28, 0x9A, + 0x78, 0x11, 0x1A, 0x69, 0x59, 0x57, 0xAF, 0xB5, 0x20, 0x42, 0xE4, 0x8B, + 0x0F, 0xE6, 0xDF, 0x5B, 0xA6, 0x03, 0x92, 0x2F, 0xF5, 0x11, 0xE4, 0x62, + 0xD7, 0x32, 0x71, 0x38, 0xD9, 0x04, 0x0C, 0x71, 0xAB, 0x3D, 0x51, 0x7E, + 0x0F, 0x07, 0xDF, 0x63, 0x05, 0x5C, 0xE9, 0xBF, 0x94, 0x6F, 0xC1, 0x29, + 0x82, 0xC0, 0xB4, 0xDA, 0x51, 0xB0, 0xC1, 0x3C, 0xBB, 0xAD, 0x37, 0x4A, + 0x5C, 0xCA, 0xF1, 0x4B, 0x36, 0x0E, 0x24, 0xAB, 0xBF, 0xC3, 0x84, 0x77, + 0xFD, 0xA8, 0x50, 0xF4, 0xB1, 0xE7, 0xC6, 0x2F, 0xD2, 0x2D, 0x59, 0x8D, + 0x7A, 0x0A, 0x4E, 0x96, 0x69, 0x52, 0x02, 0xAA, 0x36, 0x98, 0xEC, 0xFC, + 0xFA, 0x14, 0x83, 0x0C, 0x37, 0x1F, 0xC9, 0x92, 0x37, 0x7F, 0xD7, 0x81, + 0x2D, 0xE5, 0xC4, 0xB9, 0xE0, 0x3E, 0x34, 0xFE, 0x67, 0xF4, 0x3E, 0x66, + 0xD1, 0xD3, 0xF4, 0x40, 0xCF, 0x5E, 0x62, 0x34, 0x0F, 0x70, 0x06, 0x3E, + 0x20, 0x18, 0x5A, 0xCE, 0xF7, 0x72, 0x1B, 0x25, 0x6C, 0x93, 0x74, 0x14, + 0x93, 0xA3, 0x73, 0xB1, 0x0E, 0xAA, 0x87, 0x10, 0x23, 0x59, 0x5F, 0x20, + 0x05, 0x19, 0x47, 0xED, 0x68, 0x8E, 0x92, 0x12, 0xCA, 0x5D, 0xFC, 0xD6, + 0x2B, 0xB2, 0x92, 0x3C, 0x20, 0xCF, 0xE1, 0x5F, 0xAF, 0x20, 0xBE, 0xA0, + 0x76, 0x7F, 0x76, 0xE5, 0xEC, 0x1A, 0x86, 0x61, 0x33, 0x3E, 0xE7, 0x7B, + 0xB4, 0x3F, 0xA0, 0x0F, 0x8E, 0xA2, 0xB9, 0x6A, 0x6F, 0xB9, 0x87, 0x26, + 0x6F, 0x41, 0x6C, 0x88, 0xA6, 0x50, 0xFD, 0x6A, 0x63, 0x0B, 0xF5, 0x93, + 0x16, 0x1B, 0x19, 0x8F, 0xB2, 0xED, 0x9B, 0x9B, 0xC9, 0x90, 0xF5, 0x01, + 0x0C, 0xDF, 0x19, 0x3D, 0x0F, 0x3E, 0x38, 0x23, 0xC9, 0x2F, 0x8F, 0x0C, + 0xD1, 0x02, 0xFE, 0x1B, 0x55, 0xD6, 0x4E, 0xD0, 0x8D, 0x3C, 0xAF, 0x4F, + 0xA4, 0xF3, 0xFE, 0xAF, 0x2A, 0xD3, 0x05, 0x9D, 0x79, 0x08, 0xA1, 0xCB, + 0x57, 0x31, 0xB4, 0x9C, 0xC8, 0x90, 0xB2, 0x67, 0xF4, 0x18, 0x16, 0x93, + 0x3A, 0xFC, 0x47, 0xD8, 0xD1, 0x78, 0x96, 0x31, 0x1F, 0xBA, 0x2B, 0x0C, + 0x5F, 0x5D, 0x99, 0xAD, 0x63, 0x89, 0x5A, 0x24, 0x20, 0x76, 0xD8, 0xDF, + 0xFD, 0xAB, 0x4E, 0xA6, 0x22, 0xAA, 0x9D, 0x5E, 0xE6, 0x27, 0x8A, 0x7D, + 0x68, 0x29, 0xA3, 0xE7, 0x8A, 0xB8, 0xDA, 0x11, 0xBB, 0x17, 0x2D, 0x99, + 0x9D, 0x13, 0x24, 0x46, 0xF7, 0xC5, 0xE2, 0xD8, 0x9F, 0x8E, 0x7F, 0xC7, + 0x8F, 0x74, 0x6D, 0x5A, 0xB2, 0xE8, 0x72, 0xF5, 0xAC, 0xEE, 0x24, 0x10, + 0xAD, 0x2F, 0x14, 0xDA, 0xFF, 0x2D, 0x9A, 0x46, 0x71, 0x47, 0xBE, 0x42, + 0xDF, 0xBB, 0x01, 0xDB, 0xF4, 0x7F, 0xD3, 0x28, 0x8F, 0x31, 0x59, 0x5B, + 0xD3, 0xC9, 0x02, 0xA6, 0xB4, 0x52, 0xCA, 0x6E, 0x97, 0xFB, 0x43, 0xC5, + 0x08, 0x26, 0x6F, 0x8A, 0xF4, 0xBB, 0xFD, 0x9F, 0x28, 0xAA, 0x0D, 0xD5, + 0x45, 0xF3, 0x13, 0x3A, 0x1D, 0xD8, 0xC0, 0x78, 0x8F, 0x41, 0x67, 0x3C, + 0x1E, 0x94, 0x64, 0xAE, 0x7B, 0x0B, 0xC5, 0xE8, 0xD9, 0x01, 0x88, 0x39, + 0x1A, 0x97, 0x86, 0x64, 0x41, 0xD5, 0x3B, 0x87, 0x0C, 0x6E, 0xFA, 0x0F, + 0xC6, 0xBD, 0x48, 0x14, 0xBF, 0x39, 0x4D, 0xD4, 0x9E, 0x41, 0xB6, 0x8F, + 0x96, 0x1D, 0x63, 0x96, 0x93, 0xD9, 0x95, 0x06, 0x78, 0x31, 0x68, 0x9E, + 0x37, 0x06, 0x3B, 0x80, 0x89, 0x45, 0x61, 0x39, 0x23, 0xC7, 0x1B, 0x44, + 0xA3, 0x15, 0xE5, 0x1C, 0xF8, 0x92, 0x30, 0xBB +}; + +static const unsigned char TA409_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA410_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x31 +}; + +static const unsigned char TA410_RSA_N[] = { + 0xF1, 0x66, 0x08, 0xBD, 0xD9, 0xC5, 0x15, 0x61, 0xCB, 0x84, 0x04, 0x41, + 0xA5, 0x69, 0x37, 0x77, 0x1D, 0xC1, 0xB0, 0x7B, 0xFA, 0xC3, 0x77, 0x48, + 0x90, 0x13, 0x72, 0x64, 0xD1, 0xB8, 0x7C, 0x90, 0x35, 0x9D, 0x18, 0x79, + 0x88, 0xE3, 0x97, 0x01, 0x3C, 0x47, 0x81, 0xF2, 0x0E, 0xA2, 0x98, 0x0D, + 0x9E, 0x3F, 0x37, 0xE0, 0x19, 0xB2, 0x90, 0xF2, 0x46, 0x1C, 0x92, 0xB1, + 0x3A, 0x61, 0xCE, 0xFA, 0xB7, 0x46, 0x9E, 0x03, 0x86, 0xD7, 0x33, 0x6E, + 0xED, 0xF7, 0x45, 0x8C, 0x76, 0x37, 0xDE, 0x6E, 0x96, 0x91, 0xF7, 0xD7, + 0x7E, 0x2B, 0x87, 0x17, 0xD5, 0x8B, 0x35, 0xEE, 0x84, 0x91, 0x72, 0x57, + 0xDC, 0x60, 0xC3, 0xC3, 0xB9, 0xE7, 0xC7, 0x67, 0x24, 0x23, 0x4F, 0x63, + 0x0A, 0x63, 0xF6, 0x66, 0x7D, 0x4B, 0x55, 0xA7, 0x3F, 0x78, 0x64, 0x49, + 0x69, 0x12, 0x97, 0xE0, 0x4C, 0x0D, 0xD3, 0x09, 0xA0, 0x32, 0x30, 0x3A, + 0xFA, 0x9F, 0xC0, 0xF2, 0x9C, 0xC5, 0x12, 0x2A, 0x2E, 0x1C, 0xB5, 0x04, + 0x33, 0xDA, 0xA4, 0x38, 0x11, 0x6A, 0xDE, 0xC6, 0x18, 0xF6, 0x47, 0x3A, + 0x22, 0x41, 0x87, 0x22, 0xFC, 0xC4, 0x89, 0x28, 0x54, 0xD8, 0x8C, 0xA5, + 0x30, 0x0A, 0xF8, 0x17, 0x16, 0xCA, 0xAC, 0x37, 0xFD, 0x79, 0xA7, 0x91, + 0x17, 0x78, 0x38, 0x99, 0xAD, 0x58, 0xED, 0xB2, 0xDE, 0xCC, 0x89, 0x7D, + 0x03, 0x9C, 0xB3, 0x89, 0x65, 0xE7, 0xE3, 0x3B, 0xB1, 0x22, 0x86, 0x8F, + 0x06, 0x6D, 0x78, 0x07, 0xFD, 0x91, 0x12, 0x7F, 0xB0, 0x6B, 0x1C, 0x89, + 0x0D, 0xF9, 0xB8, 0xCB, 0x74, 0x5B, 0x07, 0xC2, 0xC8, 0xF4, 0x35, 0xD1, + 0x64, 0x63, 0x7A, 0xE9, 0x6E, 0x9A, 0x28, 0xD6, 0x30, 0xBD, 0xE6, 0x1B, + 0xDD, 0x15, 0xAF, 0x84, 0xEA, 0x9C, 0xC7, 0xCA, 0xF5, 0x0E, 0xEA, 0xF2, + 0x5D, 0x29, 0x87, 0x8F, 0x69, 0x73, 0x39, 0xBE, 0x2E, 0x24, 0x6F, 0x45, + 0x21, 0xAC, 0xC5, 0xD4, 0x69, 0x25, 0x06, 0x83, 0xAD, 0x7A, 0x48, 0x85, + 0x13, 0x2C, 0x0D, 0x06, 0xB8, 0x6C, 0x79, 0x56, 0xFC, 0xA3, 0x67, 0x32, + 0x81, 0xF5, 0x57, 0xA5, 0xCA, 0x57, 0x42, 0x69, 0xE9, 0x5C, 0x24, 0x61, + 0xEF, 0xE2, 0x30, 0x18, 0x4E, 0x44, 0x98, 0x55, 0x6F, 0x7A, 0xC2, 0x93, + 0xD8, 0x19, 0xB6, 0xDE, 0x7C, 0x47, 0x8A, 0x11, 0x4E, 0x49, 0x47, 0xDB, + 0x28, 0x94, 0x02, 0x0B, 0x94, 0x4A, 0x2C, 0xF9, 0x12, 0xD0, 0x4F, 0xE8, + 0x31, 0x7E, 0x6C, 0x7A, 0xBF, 0xA6, 0x3F, 0x9B, 0x39, 0x3D, 0x02, 0x16, + 0xA3, 0x18, 0xB3, 0x67, 0xAC, 0x5B, 0x3F, 0x2C, 0x83, 0x2B, 0x67, 0x39, + 0x81, 0x5C, 0xB9, 0x7E, 0x94, 0xD5, 0x64, 0xDD, 0x9E, 0x8F, 0x6E, 0xAE, + 0xE8, 0x7C, 0x5B, 0xB4, 0xD7, 0x6A, 0x47, 0x48, 0xD7, 0x7E, 0xB3, 0xD4, + 0x2D, 0x8E, 0x56, 0x76, 0x4E, 0xCF, 0x69, 0xF1, 0x6E, 0x44, 0x6C, 0xD4, + 0x24, 0xEA, 0x8D, 0x24, 0xA1, 0x18, 0xBF, 0xBD, 0x57, 0xFE, 0xA9, 0x99, + 0x35, 0xB5, 0xDB, 0x10, 0x77, 0xB8, 0x3D, 0x48, 0xBA, 0xD6, 0xC1, 0xE7, + 0xF1, 0x23, 0x3E, 0xD7, 0xDF, 0x85, 0x9D, 0x27, 0x3C, 0xD4, 0x40, 0xBD, + 0x0A, 0x0C, 0xBD, 0xF5, 0xE7, 0x8D, 0x25, 0xD6, 0x81, 0x74, 0x87, 0x46, + 0xD4, 0x29, 0x75, 0xA2, 0x42, 0x6C, 0xF7, 0x73, 0x89, 0xE7, 0x7D, 0xBF, + 0x7A, 0x4A, 0x1F, 0xD3, 0x22, 0xC9, 0x15, 0x55, 0xCF, 0xDF, 0x6F, 0x7C, + 0x55, 0xD0, 0xA4, 0x8B, 0x07, 0x11, 0x37, 0x5F, 0x83, 0xA6, 0x26, 0x57, + 0xA6, 0x01, 0x5B, 0x7E, 0xFE, 0x58, 0x68, 0x07, 0xA9, 0xE9, 0x7A, 0xD9, + 0xB9, 0xE8, 0xFF, 0x50, 0x1F, 0xAB, 0xC2, 0xB4, 0xC0, 0xCE, 0xE8, 0xEA, + 0xFD, 0x0F, 0xBD, 0x8D, 0x4D, 0xB8, 0xBC, 0x71 +}; + +static const unsigned char TA410_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA411_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x32 +}; + +static const unsigned char TA411_EC_Q[] = { + 0x04, 0x9D, 0xCB, 0x80, 0x91, 0x8D, 0x53, 0x67, 0xB5, 0xB9, 0x50, 0xB1, + 0x03, 0xF8, 0xE5, 0x49, 0x1F, 0x41, 0x22, 0x09, 0xB0, 0x51, 0x52, 0x58, + 0xD6, 0x2B, 0x34, 0x8F, 0xC5, 0x12, 0x46, 0x14, 0xC5, 0x8B, 0x2F, 0x2C, + 0x84, 0xFF, 0x2C, 0x6E, 0xA8, 0xD5, 0xF1, 0x09, 0xE3, 0x03, 0x21, 0x14, + 0xC4, 0x43, 0x3D, 0x7C, 0xC1, 0x2C, 0xC4, 0x4B, 0x6A, 0x4A, 0xCD, 0xE9, + 0x87, 0xE0, 0x7D, 0xF6, 0x22, 0xBE, 0xFA, 0x4A, 0x51, 0xB8, 0x30, 0x8A, + 0xFD, 0xE1, 0xDE, 0x18, 0x12, 0x0A, 0xF6, 0x47, 0xB7, 0xE7, 0x17, 0xBF, + 0x27, 0x8A, 0xD4, 0x41, 0x4C, 0x96, 0x3C, 0x60, 0x96, 0xC1, 0xFD, 0x15, + 0x1C +}; + +static const unsigned char TA412_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x42, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x6F, 0x72, 0x65, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, 0x43, 0x79, + 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6C, 0x74, 0x69, + 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA412_RSA_N[] = { + 0xA3, 0x04, 0xBB, 0x22, 0xAB, 0x98, 0x3D, 0x57, 0xE8, 0x26, 0x72, 0x9A, + 0xB5, 0x79, 0xD4, 0x29, 0xE2, 0xE1, 0xE8, 0x95, 0x80, 0xB1, 0xB0, 0xE3, + 0x5B, 0x8E, 0x2B, 0x29, 0x9A, 0x64, 0xDF, 0xA1, 0x5D, 0xED, 0xB0, 0x09, + 0x05, 0x6D, 0xDB, 0x28, 0x2E, 0xCE, 0x62, 0xA2, 0x62, 0xFE, 0xB4, 0x88, + 0xDA, 0x12, 0xEB, 0x38, 0xEB, 0x21, 0x9D, 0xC0, 0x41, 0x2B, 0x01, 0x52, + 0x7B, 0x88, 0x77, 0xD3, 0x1C, 0x8F, 0xC7, 0xBA, 0xB9, 0x88, 0xB5, 0x6A, + 0x09, 0xE7, 0x73, 0xE8, 0x11, 0x40, 0xA7, 0xD1, 0xCC, 0xCA, 0x62, 0x8D, + 0x2D, 0xE5, 0x8F, 0x0B, 0xA6, 0x50, 0xD2, 0xA8, 0x50, 0xC3, 0x28, 0xEA, + 0xF5, 0xAB, 0x25, 0x87, 0x8A, 0x9A, 0x96, 0x1C, 0xA9, 0x67, 0xB8, 0x3F, + 0x0C, 0xD5, 0xF7, 0xF9, 0x52, 0x13, 0x2F, 0xC2, 0x1B, 0xD5, 0x70, 0x70, + 0xF0, 0x8F, 0xC0, 0x12, 0xCA, 0x06, 0xCB, 0x9A, 0xE1, 0xD9, 0xCA, 0x33, + 0x7A, 0x77, 0xD6, 0xF8, 0xEC, 0xB9, 0xF1, 0x68, 0x44, 0x42, 0x48, 0x13, + 0xD2, 0xC0, 0xC2, 0xA4, 0xAE, 0x5E, 0x60, 0xFE, 0xB6, 0xA6, 0x05, 0xFC, + 0xB4, 0xDD, 0x07, 0x59, 0x02, 0xD4, 0x59, 0x18, 0x98, 0x63, 0xF5, 0xA5, + 0x63, 0xE0, 0x90, 0x0C, 0x7D, 0x5D, 0xB2, 0x06, 0x7A, 0xF3, 0x85, 0xEA, + 0xEB, 0xD4, 0x03, 0xAE, 0x5E, 0x84, 0x3E, 0x5F, 0xFF, 0x15, 0xED, 0x69, + 0xBC, 0xF9, 0x39, 0x36, 0x72, 0x75, 0xCF, 0x77, 0x52, 0x4D, 0xF3, 0xC9, + 0x90, 0x2C, 0xB9, 0x3D, 0xE5, 0xC9, 0x23, 0x53, 0x3F, 0x1F, 0x24, 0x98, + 0x21, 0x5C, 0x07, 0x99, 0x29, 0xBD, 0xC6, 0x3A, 0xEC, 0xE7, 0x6E, 0x86, + 0x3A, 0x6B, 0x97, 0x74, 0x63, 0x33, 0xBD, 0x68, 0x18, 0x31, 0xF0, 0x78, + 0x8D, 0x76, 0xBF, 0xFC, 0x9E, 0x8E, 0x5D, 0x2A, 0x86, 0xA7, 0x4D, 0x90, + 0xDC, 0x27, 0x1A, 0x39 +}; + +static const unsigned char TA412_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA413_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA413_RSA_N[] = { + 0xD7, 0xC7, 0x5E, 0xF7, 0xC1, 0x07, 0xD4, 0x77, 0xFB, 0x43, 0x21, 0xF4, + 0xF4, 0xF5, 0x69, 0xE4, 0xEE, 0x32, 0x01, 0xDB, 0xA3, 0x86, 0x1F, 0xE4, + 0x59, 0x0D, 0xBA, 0xE7, 0x75, 0x83, 0x52, 0xEB, 0xEA, 0x1C, 0x61, 0x15, + 0x48, 0xBB, 0x1D, 0x07, 0xCA, 0x8C, 0xAE, 0xB0, 0xDC, 0x96, 0x9D, 0xEA, + 0xC3, 0x60, 0x92, 0x86, 0x82, 0x28, 0x73, 0x9C, 0x56, 0x06, 0xFF, 0x4B, + 0x64, 0xF0, 0x0C, 0x2A, 0x37, 0x49, 0xB5, 0xE5, 0xCF, 0x0C, 0x7C, 0xEE, + 0xF1, 0x4A, 0xBB, 0x73, 0x30, 0x65, 0xF3, 0xD5, 0x2F, 0x83, 0xB6, 0x7E, + 0xE3, 0xE7, 0xF5, 0x9E, 0xAB, 0x60, 0xF9, 0xD3, 0xF1, 0x9D, 0x92, 0x74, + 0x8A, 0xE4, 0x1C, 0x96, 0xAC, 0x5B, 0x80, 0xE9, 0xB5, 0xF4, 0x31, 0x87, + 0xA3, 0x51, 0xFC, 0xC7, 0x7E, 0xA1, 0x6F, 0x8E, 0x53, 0x77, 0xD4, 0x97, + 0xC1, 0x55, 0x33, 0x92, 0x3E, 0x18, 0x2F, 0x75, 0xD4, 0xAD, 0x86, 0x49, + 0xCB, 0x95, 0xAF, 0x54, 0x06, 0x6C, 0xD8, 0x06, 0x13, 0x8D, 0x5B, 0xFF, + 0xE1, 0x26, 0x19, 0x59, 0xC0, 0x24, 0xBA, 0x81, 0x71, 0x79, 0x90, 0x44, + 0x50, 0x68, 0x24, 0x94, 0x5F, 0xB8, 0xB3, 0x11, 0xF1, 0x29, 0x41, 0x61, + 0xA3, 0x41, 0xCB, 0x23, 0x36, 0xD5, 0xC1, 0xF1, 0x32, 0x50, 0x10, 0x4E, + 0x7F, 0xF4, 0x86, 0x93, 0xEC, 0x84, 0xD3, 0x8E, 0xBC, 0x4B, 0xBF, 0x5C, + 0x01, 0x4E, 0x07, 0x3D, 0xDC, 0x14, 0x8A, 0x94, 0x0A, 0xA4, 0xEA, 0x73, + 0xFB, 0x0B, 0x51, 0xE8, 0x13, 0x07, 0x18, 0xFA, 0x0E, 0xF1, 0x2B, 0xD1, + 0x54, 0x15, 0x7D, 0x3C, 0xE1, 0xF7, 0xB4, 0x19, 0x42, 0x67, 0x62, 0x5E, + 0x77, 0xE0, 0xA2, 0x55, 0xEC, 0xB6, 0xD9, 0x69, 0x17, 0xD5, 0x3A, 0xAF, + 0x44, 0xED, 0x4A, 0xC5, 0x9E, 0xE4, 0x7A, 0x27, 0x7C, 0xE5, 0x75, 0xD7, + 0xAA, 0xCB, 0x25, 0xE7, 0xDF, 0x6B, 0x0A, 0xDB, 0x0F, 0x4D, 0x93, 0x4E, + 0xA8, 0xA0, 0xCD, 0x7B, 0x2E, 0xF2, 0x59, 0x01, 0x6A, 0xB7, 0x0D, 0xB8, + 0x07, 0x81, 0x7E, 0x8B, 0x38, 0x1B, 0x38, 0xE6, 0x0A, 0x57, 0x99, 0x3D, + 0xEE, 0x21, 0xE8, 0xA3, 0xF5, 0x0C, 0x16, 0xDD, 0x8B, 0xEC, 0x34, 0x8E, + 0x9C, 0x2A, 0x1C, 0x00, 0x15, 0x17, 0x8D, 0x68, 0x83, 0xD2, 0x70, 0x9F, + 0x18, 0x08, 0xCD, 0x11, 0x68, 0xD5, 0xC9, 0x6B, 0x52, 0xCD, 0xC4, 0x46, + 0x8F, 0xDC, 0xB5, 0xF3, 0xD8, 0x57, 0x73, 0x1E, 0xE9, 0x94, 0x39, 0x04, + 0xBF, 0xD3, 0xDE, 0x38, 0xDE, 0xB4, 0x53, 0xEC, 0x69, 0x1C, 0xA2, 0x7E, + 0xC4, 0x8F, 0xE4, 0x1B, 0x70, 0xAD, 0xF2, 0xA2, 0xF9, 0xFB, 0xF7, 0x16, + 0x64, 0x66, 0x69, 0x9F, 0x49, 0x51, 0xA2, 0xE2, 0x15, 0x18, 0x67, 0x06, + 0x4A, 0x7F, 0xD5, 0x6C, 0xB5, 0x4D, 0xB3, 0x33, 0xE0, 0x61, 0xEB, 0x5D, + 0xBE, 0xE9, 0x98, 0x0F, 0x32, 0xD7, 0x1D, 0x4B, 0x3C, 0x2E, 0x5A, 0x01, + 0x52, 0x91, 0x09, 0xF2, 0xDF, 0xEA, 0x8D, 0xD8, 0x06, 0x40, 0x63, 0xAA, + 0x11, 0xE4, 0xFE, 0xC3, 0x37, 0x9E, 0x14, 0x52, 0x3F, 0xF4, 0xE2, 0xCC, + 0xF2, 0x61, 0x93, 0xD1, 0xFD, 0x67, 0x6B, 0xD7, 0x52, 0xAE, 0xBF, 0x68, + 0xAB, 0x40, 0x43, 0xA0, 0x57, 0x35, 0x53, 0x78, 0xF0, 0x53, 0xF8, 0x61, + 0x42, 0x07, 0x64, 0xC6, 0xD7, 0x6F, 0x9B, 0x4C, 0x38, 0x0D, 0x63, 0xAC, + 0x62, 0xAF, 0x36, 0x8B, 0xA2, 0x73, 0x0A, 0x0D, 0xF5, 0x21, 0xBD, 0x74, + 0xAA, 0x4D, 0xEA, 0x72, 0x03, 0x49, 0xDB, 0xC7, 0x5F, 0x1D, 0x62, 0x63, + 0xC7, 0xFD, 0xDD, 0x91, 0xEC, 0x33, 0xEE, 0xF5, 0x6D, 0xB4, 0x6E, 0x30, + 0x68, 0xDE, 0xC8, 0xD6, 0x26, 0xB0, 0x75, 0x5E, 0x7B, 0xB4, 0x07, 0x20, + 0x98, 0xA1, 0x76, 0x32, 0xB8, 0x4D, 0x6C, 0x4F +}; + +static const unsigned char TA413_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA414_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA414_RSA_N[] = { + 0xA5, 0xDA, 0x0A, 0x95, 0x16, 0x50, 0xE3, 0x95, 0xF2, 0x5E, 0x9D, 0x76, + 0x31, 0x06, 0x32, 0x7A, 0x9B, 0xF1, 0x10, 0x76, 0xB8, 0x00, 0x9A, 0xB5, + 0x52, 0x36, 0xCD, 0x24, 0x47, 0xB0, 0x9F, 0x18, 0x64, 0xBC, 0x9A, 0xF6, + 0xFA, 0xD5, 0x79, 0xD8, 0x90, 0x62, 0x4C, 0x22, 0x2F, 0xDE, 0x38, 0x3D, + 0xD6, 0xE0, 0xA8, 0xE9, 0x1C, 0x2C, 0xDB, 0x78, 0x11, 0xE9, 0x8E, 0x68, + 0x51, 0x15, 0x72, 0xC7, 0xF3, 0x33, 0x87, 0xE4, 0xA0, 0x5D, 0x0B, 0x5C, + 0xE0, 0x57, 0x07, 0x2A, 0x30, 0xF5, 0xCD, 0xC4, 0x37, 0x77, 0x28, 0x4D, + 0x18, 0x91, 0xE6, 0xBF, 0xD5, 0x52, 0xFD, 0x71, 0x2D, 0x70, 0x3E, 0xE7, + 0xC6, 0xC4, 0x8A, 0xE3, 0xF0, 0x28, 0x0B, 0xF4, 0x76, 0x98, 0xA1, 0x8B, + 0x87, 0x55, 0xB2, 0x3A, 0x13, 0xFC, 0xB7, 0x3E, 0x27, 0x37, 0x8E, 0x22, + 0xE3, 0xA8, 0x4F, 0x2A, 0xEF, 0x60, 0xBB, 0x3D, 0xB7, 0x39, 0xC3, 0x0E, + 0x01, 0x47, 0x99, 0x5D, 0x12, 0x4F, 0xDB, 0x43, 0xFA, 0x57, 0xA1, 0xED, + 0xF9, 0x9D, 0xBE, 0x11, 0x47, 0x26, 0x5B, 0x13, 0x98, 0xAB, 0x5D, 0x16, + 0x8A, 0xB0, 0x37, 0x1C, 0x57, 0x9D, 0x45, 0xFF, 0x88, 0x96, 0x36, 0xBF, + 0xBB, 0xCA, 0x07, 0x7B, 0x6F, 0x87, 0x63, 0xD7, 0xD0, 0x32, 0x6A, 0xD6, + 0x5D, 0x6C, 0x0C, 0xF1, 0xB3, 0x6E, 0x39, 0xE2, 0x6B, 0x31, 0x2E, 0x39, + 0x00, 0x27, 0x14, 0xDE, 0x38, 0xC0, 0xEC, 0x19, 0x66, 0x86, 0x12, 0xE8, + 0x9D, 0x72, 0x16, 0x13, 0x64, 0x52, 0xC7, 0xA9, 0x37, 0x1C, 0xFD, 0x82, + 0x30, 0xED, 0x84, 0x18, 0x1D, 0xF4, 0xAE, 0x5C, 0xFF, 0x70, 0x13, 0x00, + 0xEB, 0xB1, 0xF5, 0x33, 0x7A, 0x4B, 0xD6, 0x55, 0xF8, 0x05, 0x8D, 0x4B, + 0x69, 0xB0, 0xF5, 0xB3, 0x28, 0x36, 0x5C, 0x14, 0xC4, 0x51, 0x73, 0x4D, + 0x6B, 0x0B, 0xF1, 0x34, 0x07, 0xDB, 0x17, 0x39, 0xD7, 0xDC, 0x28, 0x7B, + 0x6B, 0xF5, 0x9F, 0xF3, 0x2E, 0xC1, 0x4F, 0x17, 0x2A, 0x10, 0xF3, 0xCC, + 0xCA, 0xE8, 0xEB, 0xFD, 0x6B, 0xAB, 0x2E, 0x9A, 0x9F, 0x2D, 0x82, 0x6E, + 0x04, 0xD4, 0x52, 0x01, 0x93, 0x2D, 0x3D, 0x86, 0xFC, 0x7E, 0xFC, 0xDF, + 0xEF, 0x42, 0x1D, 0xA6, 0x6B, 0xEF, 0xB9, 0x20, 0xC6, 0xF7, 0xBD, 0xA0, + 0xA7, 0x95, 0xFD, 0xA7, 0xE6, 0x89, 0x24, 0xD8, 0xCC, 0x8C, 0x34, 0x6C, + 0xE2, 0x23, 0x2F, 0xD9, 0x12, 0x1A, 0x21, 0xB9, 0x55, 0x91, 0x6F, 0x0B, + 0x91, 0x79, 0x19, 0x0C, 0xAD, 0x40, 0x88, 0x0B, 0x70, 0xE2, 0x7A, 0xD2, + 0x0E, 0xD8, 0x68, 0x48, 0xBB, 0x82, 0x13, 0x39, 0x10, 0x58, 0xE9, 0xD8, + 0x2A, 0x07, 0xC6, 0x12, 0xDB, 0x58, 0xDB, 0xD2, 0x3B, 0x55, 0x10, 0x47, + 0x05, 0x15, 0x67, 0x62, 0x7E, 0x18, 0x63, 0xA6, 0x46, 0x3F, 0x09, 0x0E, + 0x54, 0x32, 0x5E, 0xBF, 0x0D, 0x62, 0x7A, 0x27, 0xEF, 0x80, 0xE8, 0xDB, + 0xD9, 0x4B, 0x06, 0x5A, 0x37, 0x5A, 0x25, 0xD0, 0x08, 0x12, 0x77, 0xD4, + 0x6F, 0x09, 0x50, 0x97, 0x3D, 0xC8, 0x1D, 0xC3, 0xDF, 0x8C, 0x45, 0x30, + 0x56, 0xC6, 0xD3, 0x64, 0xAB, 0x66, 0xF3, 0xC0, 0x5E, 0x96, 0x9C, 0xC3, + 0xC4, 0xEF, 0xC3, 0x7C, 0x6B, 0x8B, 0x3A, 0x79, 0x7F, 0xB3, 0x49, 0xCF, + 0x3D, 0xE2, 0x89, 0x9F, 0xA0, 0x30, 0x4B, 0x85, 0xB9, 0x9C, 0x94, 0x24, + 0x79, 0x8F, 0x7D, 0x6B, 0xA9, 0x45, 0x68, 0x0F, 0x2B, 0xD0, 0xF1, 0xDA, + 0x1C, 0xCB, 0x69, 0xB8, 0xCA, 0x49, 0x62, 0x6D, 0xC8, 0xD0, 0x63, 0x62, + 0xDD, 0x60, 0x0F, 0x58, 0xAA, 0x8F, 0xA1, 0xBC, 0x05, 0xA5, 0x66, 0xA2, + 0xCF, 0x1B, 0x76, 0xB2, 0x84, 0x64, 0xB1, 0x4C, 0x39, 0x52, 0xC0, 0x30, + 0xBA, 0xF0, 0x8C, 0x4B, 0x02, 0xB0, 0xB6, 0xB7 +}; + +static const unsigned char TA414_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA415_DN[] = { + 0x30, 0x52, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x53, 0x4B, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x0A, 0x42, 0x72, 0x61, 0x74, 0x69, 0x73, 0x6C, 0x61, 0x76, 0x61, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x61, 0x2E, 0x73, 0x2E, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x41, 0x20, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x32 +}; + +static const unsigned char TA415_RSA_N[] = { + 0xA2, 0xA3, 0xC4, 0x00, 0x09, 0xD6, 0x85, 0x5D, 0x2D, 0x6D, 0x14, 0xF6, + 0xC2, 0xC3, 0x73, 0x9E, 0x35, 0xC2, 0x71, 0x55, 0x7E, 0x81, 0xFB, 0xAB, + 0x46, 0x50, 0xE0, 0xC1, 0x7C, 0x49, 0x78, 0xE6, 0xAB, 0x79, 0x58, 0x3C, + 0xDA, 0xFF, 0x7C, 0x1C, 0x9F, 0xD8, 0x97, 0x02, 0x78, 0x3E, 0x6B, 0x41, + 0x04, 0xE9, 0x41, 0xBD, 0xBE, 0x03, 0x2C, 0x45, 0xF6, 0x2F, 0x64, 0xD4, + 0xAB, 0x5D, 0xA3, 0x47, 0x3D, 0x64, 0x9B, 0xE9, 0x68, 0x9A, 0xC6, 0xCC, + 0x1B, 0x3F, 0xBA, 0xBE, 0xB2, 0x8B, 0x34, 0x02, 0x2E, 0x98, 0x55, 0x19, + 0xFC, 0x8C, 0x6F, 0xAA, 0x5F, 0xDA, 0x4C, 0xCE, 0x4D, 0x03, 0x21, 0xA3, + 0xD8, 0xD2, 0x34, 0x93, 0x56, 0x96, 0xCB, 0x4C, 0x0C, 0x00, 0x16, 0x3C, + 0x5F, 0x1A, 0xCD, 0xC8, 0xC7, 0x6C, 0xA6, 0xAD, 0xD3, 0x31, 0xA7, 0xBC, + 0xE8, 0xE5, 0xE1, 0x66, 0xD6, 0xD2, 0xFB, 0x03, 0xB4, 0x41, 0x65, 0xC9, + 0x10, 0xAE, 0x0E, 0x05, 0x63, 0xC6, 0x80, 0x6A, 0x69, 0x30, 0xFD, 0xD2, + 0xEE, 0x90, 0xEF, 0x0D, 0x27, 0xDF, 0x9F, 0x95, 0x73, 0xF4, 0xE1, 0x25, + 0xDA, 0x6C, 0x16, 0xDE, 0x41, 0x38, 0x34, 0xEA, 0x8B, 0xFC, 0xD1, 0xE8, + 0x04, 0x14, 0x61, 0x2D, 0x41, 0x7E, 0xAC, 0xC7, 0x77, 0x4E, 0xCB, 0x51, + 0x54, 0xFB, 0x5E, 0x92, 0x18, 0x1B, 0x04, 0x5A, 0x68, 0xC6, 0xC9, 0xC4, + 0xFA, 0xB7, 0x13, 0xA0, 0x98, 0xB7, 0x11, 0x2B, 0xB7, 0xD6, 0x57, 0xCC, + 0x7C, 0x9E, 0x17, 0xD1, 0xCB, 0x25, 0xFE, 0x86, 0x4E, 0x24, 0x2E, 0x56, + 0x0C, 0x78, 0x4D, 0x9E, 0x01, 0x12, 0xA6, 0x2B, 0xA7, 0x01, 0x65, 0x6E, + 0x7C, 0x62, 0x1D, 0x84, 0x84, 0xDF, 0xEA, 0xC0, 0x6B, 0xB5, 0xA5, 0x2A, + 0x95, 0x83, 0xC3, 0x53, 0x11, 0x0C, 0x73, 0x1D, 0x0B, 0xB2, 0x46, 0x90, + 0xD1, 0x42, 0x3A, 0xCE, 0x40, 0x6E, 0x95, 0xAD, 0xFF, 0xC6, 0x94, 0xAD, + 0x6E, 0x97, 0x84, 0x8E, 0x7D, 0x6F, 0x9E, 0x8A, 0x80, 0x0D, 0x49, 0x6D, + 0x73, 0xE2, 0x7B, 0x92, 0x1E, 0xC3, 0xF3, 0xC1, 0xF3, 0xEB, 0x2E, 0x05, + 0x6F, 0xD9, 0x1B, 0xCF, 0x37, 0x76, 0x04, 0xC8, 0xB4, 0x5A, 0xE4, 0x17, + 0xA7, 0xCB, 0xDD, 0x76, 0x1F, 0xD0, 0x19, 0x76, 0xE8, 0x2C, 0x05, 0xB3, + 0xD6, 0x9C, 0x34, 0xD8, 0x96, 0xDC, 0x61, 0x87, 0x91, 0x05, 0xE4, 0x44, + 0x08, 0x33, 0xC1, 0xDA, 0xB9, 0x08, 0x65, 0xD4, 0xAE, 0xB2, 0x36, 0x0D, + 0xEB, 0xBA, 0x38, 0xBA, 0x0C, 0xE5, 0x9B, 0x9E, 0xEB, 0x8D, 0x66, 0xDD, + 0x99, 0xCF, 0xD6, 0x89, 0x41, 0xF6, 0x04, 0x92, 0x8A, 0x29, 0x29, 0x6D, + 0x6B, 0x3A, 0x1C, 0xE7, 0x75, 0x7D, 0x02, 0x71, 0x0E, 0xF3, 0xC0, 0xE7, + 0xBD, 0xCB, 0x19, 0xDD, 0x9D, 0x60, 0xB2, 0xC2, 0x66, 0x60, 0xB6, 0xB1, + 0x04, 0xEE, 0xC9, 0xE6, 0x86, 0xB9, 0x9A, 0x66, 0x40, 0xA8, 0xE7, 0x11, + 0xED, 0x81, 0x45, 0x03, 0x8B, 0xF6, 0x67, 0x59, 0xE8, 0xC1, 0x06, 0x11, + 0xBD, 0xDD, 0xCF, 0x80, 0x02, 0x4F, 0x65, 0x40, 0x78, 0x5C, 0x47, 0x50, + 0xC8, 0x9B, 0xE6, 0x1F, 0x81, 0x7B, 0xE4, 0x44, 0xA8, 0x5B, 0x85, 0x9A, + 0xE2, 0xDE, 0x5A, 0xD5, 0xC7, 0xF9, 0x3A, 0x44, 0x66, 0x4B, 0xE4, 0x32, + 0x54, 0x7C, 0xE4, 0x6C, 0x9C, 0xB3, 0x0E, 0x3D, 0x17, 0xA2, 0xB2, 0x34, + 0x12, 0xD6, 0x7E, 0xB2, 0xA8, 0x49, 0xBB, 0xD1, 0x7A, 0x28, 0x40, 0xBE, + 0xA2, 0x16, 0x1F, 0xDF, 0xE4, 0x37, 0x1F, 0x11, 0x73, 0xFB, 0x90, 0x0A, + 0x65, 0x43, 0xA2, 0x0D, 0x7C, 0xF8, 0x06, 0x01, 0x55, 0x33, 0x7D, 0xB0, + 0x0D, 0xB8, 0xF4, 0xF5, 0xAE, 0xA5, 0x42, 0x57, 0x7C, 0x36, 0x11, 0x8C, + 0x7B, 0x5E, 0xC4, 0x03, 0x9D, 0x8C, 0x79, 0x9D +}; + +static const unsigned char TA415_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA416_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x30, 0x30, 0x2E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x27, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x61, + 0x6E, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0C, 0x43, 0x46, 0x43, 0x41, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA416_RSA_N[] = { + 0xD7, 0x5D, 0x6B, 0xCD, 0x10, 0x3F, 0x1F, 0x05, 0x59, 0xD5, 0x05, 0x4D, + 0x37, 0xB1, 0x0E, 0xEC, 0x98, 0x2B, 0x8E, 0x15, 0x1D, 0xFA, 0x93, 0x4B, + 0x17, 0x82, 0x21, 0x71, 0x10, 0x52, 0xD7, 0x51, 0x64, 0x70, 0x16, 0xC2, + 0x55, 0x69, 0x4D, 0x8E, 0x15, 0x6D, 0x9F, 0xBF, 0x0C, 0x1B, 0xC2, 0xE0, + 0xA3, 0x67, 0xD6, 0x0C, 0xAC, 0xCF, 0x22, 0xAE, 0xAF, 0x77, 0x54, 0x2A, + 0x4B, 0x4C, 0x8A, 0x53, 0x52, 0x7A, 0xC3, 0xEE, 0x2E, 0xDE, 0xB3, 0x71, + 0x25, 0xC1, 0xE9, 0x5D, 0x3D, 0xEE, 0xA1, 0x2F, 0xA3, 0xF7, 0x2A, 0x3C, + 0xC9, 0x23, 0x1D, 0x6A, 0xAB, 0x1D, 0xA1, 0xA7, 0xF1, 0xF3, 0xEC, 0xA0, + 0xD5, 0x44, 0xCF, 0x15, 0xCF, 0x72, 0x2F, 0x1D, 0x63, 0x97, 0xE8, 0x99, + 0xF9, 0xFD, 0x93, 0xA4, 0x54, 0x80, 0x4C, 0x52, 0xD4, 0x52, 0xAB, 0x2E, + 0x49, 0xDF, 0x90, 0xCD, 0xB8, 0x5F, 0xBE, 0x3F, 0xDE, 0xA1, 0xCA, 0x4D, + 0x20, 0xD4, 0x25, 0xE8, 0x84, 0x29, 0x53, 0xB7, 0xB1, 0x88, 0x1F, 0xFF, + 0xFA, 0xDA, 0x90, 0x9F, 0x0A, 0xA9, 0x2D, 0x41, 0x3F, 0xB1, 0xF1, 0x18, + 0x29, 0xEE, 0x16, 0x59, 0x2C, 0x34, 0x49, 0x1A, 0xA8, 0x06, 0xD7, 0xA8, + 0x88, 0xD2, 0x03, 0x72, 0x7A, 0x32, 0xE2, 0xEA, 0x68, 0x4D, 0x6E, 0x2C, + 0x96, 0x65, 0x7B, 0xCA, 0x59, 0xFA, 0xF2, 0xE2, 0xDD, 0xEE, 0x30, 0x2C, + 0xFB, 0xCC, 0x46, 0xAC, 0xC4, 0x63, 0xEB, 0x6F, 0x7F, 0x36, 0x2B, 0x34, + 0x73, 0x12, 0x94, 0x7F, 0xDF, 0xCC, 0x26, 0x9E, 0xF1, 0x72, 0x5D, 0x50, + 0x65, 0x59, 0x8F, 0x69, 0xB3, 0x87, 0x5E, 0x32, 0x6F, 0xC3, 0x18, 0x8A, + 0xB5, 0x95, 0x8F, 0xB0, 0x7A, 0x37, 0xDE, 0x5A, 0x45, 0x3B, 0xC7, 0x36, + 0xE1, 0xEF, 0x67, 0xD1, 0x39, 0xD3, 0x97, 0x5B, 0x73, 0x62, 0x19, 0x48, + 0x2D, 0x87, 0x1C, 0x06, 0xFB, 0x74, 0x98, 0x20, 0x49, 0x73, 0xF0, 0x05, + 0xD2, 0x1B, 0xB1, 0xA0, 0xA3, 0xB7, 0x1B, 0x70, 0xD3, 0x88, 0x69, 0xB9, + 0x5A, 0xD6, 0x38, 0xF4, 0x62, 0xDC, 0x25, 0x8B, 0x78, 0xBF, 0xF8, 0xE8, + 0x7E, 0xB8, 0x5C, 0xC9, 0x95, 0x4F, 0x5F, 0xA7, 0x2D, 0xB9, 0x20, 0x6B, + 0xCF, 0x6B, 0xDD, 0xF5, 0x0D, 0xF4, 0x82, 0xB7, 0xF4, 0xB2, 0x66, 0x2E, + 0x10, 0x28, 0xF6, 0x97, 0x5A, 0x7B, 0x96, 0x16, 0x8F, 0x01, 0x19, 0x2D, + 0x6C, 0x6E, 0x7F, 0x39, 0x58, 0x06, 0x64, 0x83, 0x01, 0x83, 0x83, 0xC3, + 0x4D, 0x92, 0xDD, 0x32, 0xC6, 0x87, 0xA4, 0x37, 0xE9, 0x16, 0xCE, 0xAA, + 0x2D, 0x68, 0xAF, 0x0A, 0x81, 0x65, 0x3A, 0x70, 0xC1, 0x9B, 0xAD, 0x4D, + 0x6D, 0x54, 0xCA, 0x2A, 0x2D, 0x4B, 0x85, 0x1B, 0xB3, 0x80, 0xE6, 0x70, + 0x45, 0x0D, 0x6B, 0x5E, 0x35, 0xF0, 0x7F, 0x3B, 0xB8, 0x9C, 0xE4, 0x04, + 0x70, 0x89, 0x12, 0x25, 0x93, 0xDA, 0x0A, 0x99, 0x22, 0x60, 0x6A, 0x63, + 0x60, 0x4E, 0x76, 0x06, 0x98, 0x4E, 0xBD, 0x83, 0xAD, 0x1D, 0x58, 0x8A, + 0x25, 0x85, 0xD2, 0xC7, 0x65, 0x1E, 0x2D, 0x8E, 0xC6, 0xDF, 0xB6, 0xC6, + 0xE1, 0x7F, 0x8A, 0x04, 0x21, 0x15, 0x29, 0x74, 0xF0, 0x3E, 0x9C, 0x90, + 0x9D, 0x0C, 0x2E, 0xF1, 0x8A, 0x3E, 0x5A, 0xAA, 0x0C, 0x09, 0x1E, 0xC7, + 0xD5, 0x3C, 0xA3, 0xED, 0x97, 0xC3, 0x1E, 0x34, 0xFA, 0x38, 0xF9, 0x08, + 0x0E, 0xE3, 0xC0, 0x5D, 0x2B, 0x83, 0xD1, 0x56, 0x6A, 0xC9, 0xB6, 0xA8, + 0x54, 0x53, 0x2E, 0x78, 0x32, 0x67, 0x3D, 0x82, 0x7F, 0x74, 0xD0, 0xFB, + 0xE1, 0xB6, 0x05, 0x60, 0xB9, 0x70, 0xDB, 0x8E, 0x0B, 0xF9, 0x13, 0x58, + 0x6F, 0x71, 0x60, 0x10, 0x52, 0x10, 0xB9, 0xC1, 0x41, 0x09, 0xEF, 0x72, + 0x1F, 0x67, 0x31, 0x78, 0xFF, 0x96, 0x05, 0x8D +}; + +static const unsigned char TA416_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA417_DN[] = { + 0x30, 0x81, 0x81, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA417_RSA_N[] = { + 0xD0, 0x40, 0x8B, 0x8B, 0x72, 0xE3, 0x91, 0x1B, 0xF7, 0x51, 0xC1, 0x1B, + 0x54, 0x04, 0x98, 0xD3, 0xA9, 0xBF, 0xC1, 0xE6, 0x8A, 0x5D, 0x3B, 0x87, + 0xFB, 0xBB, 0x88, 0xCE, 0x0D, 0xE3, 0x2F, 0x3F, 0x06, 0x96, 0xF0, 0xA2, + 0x29, 0x50, 0x99, 0xAE, 0xDB, 0x3B, 0xA1, 0x57, 0xB0, 0x74, 0x51, 0x71, + 0xCD, 0xED, 0x42, 0x91, 0x4D, 0x41, 0xFE, 0xA9, 0xC8, 0xD8, 0x6A, 0x86, + 0x77, 0x44, 0xBB, 0x59, 0x66, 0x97, 0x50, 0x5E, 0xB4, 0xD4, 0x2C, 0x70, + 0x44, 0xCF, 0xDA, 0x37, 0x95, 0x42, 0x69, 0x3C, 0x30, 0xC4, 0x71, 0xB3, + 0x52, 0xF0, 0x21, 0x4D, 0xA1, 0xD8, 0xBA, 0x39, 0x7C, 0x1C, 0x9E, 0xA3, + 0x24, 0x9D, 0xF2, 0x83, 0x16, 0x98, 0xAA, 0x16, 0x7C, 0x43, 0x9B, 0x15, + 0x5B, 0xB7, 0xAE, 0x34, 0x91, 0xFE, 0xD4, 0x62, 0x26, 0x18, 0x46, 0x9A, + 0x3F, 0xEB, 0xC1, 0xF9, 0xF1, 0x90, 0x57, 0xEB, 0xAC, 0x7A, 0x0D, 0x8B, + 0xDB, 0x72, 0x30, 0x6A, 0x66, 0xD5, 0xE0, 0x46, 0xA3, 0x70, 0xDC, 0x68, + 0xD9, 0xFF, 0x04, 0x48, 0x89, 0x77, 0xDE, 0xB5, 0xE9, 0xFB, 0x67, 0x6D, + 0x41, 0xE9, 0xBC, 0x39, 0xBD, 0x32, 0xD9, 0x62, 0x02, 0xF1, 0xB1, 0xA8, + 0x3D, 0x6E, 0x37, 0x9C, 0xE2, 0x2F, 0xE2, 0xD3, 0xA2, 0x26, 0x8B, 0xC6, + 0xB8, 0x55, 0x43, 0x88, 0xE1, 0x23, 0x3E, 0xA5, 0xD2, 0x24, 0x39, 0x6A, + 0x47, 0xAB, 0x00, 0xD4, 0xA1, 0xB3, 0xA9, 0x25, 0xFE, 0x0D, 0x3F, 0xA7, + 0x1D, 0xBA, 0xD3, 0x51, 0xC1, 0x0B, 0xA4, 0xDA, 0xAC, 0x38, 0xEF, 0x55, + 0x50, 0x24, 0x05, 0x65, 0x46, 0x93, 0x34, 0x4F, 0x2D, 0x8D, 0xAD, 0xC6, + 0xD4, 0x21, 0x19, 0xD2, 0x8E, 0xCA, 0x05, 0x61, 0x71, 0x07, 0x73, 0x47, + 0xE5, 0x8A, 0x19, 0x12, 0xBD, 0x04, 0x4D, 0xCE, 0x4E, 0x9C, 0xA5, 0x48, + 0xAC, 0xBB, 0x26, 0xF7 +}; + +static const unsigned char TA417_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA418_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA418_EC_Q[] = { + 0x04, 0x03, 0x47, 0x7B, 0x2F, 0x75, 0xC9, 0x82, 0x15, 0x85, 0xFB, 0x75, + 0xE4, 0x91, 0x16, 0xD4, 0xAB, 0x62, 0x99, 0xF5, 0x3E, 0x52, 0x0B, 0x06, + 0xCE, 0x41, 0x00, 0x7F, 0x97, 0xE1, 0x0A, 0x24, 0x3C, 0x1D, 0x01, 0x04, + 0xEE, 0x3D, 0xD2, 0x8D, 0x09, 0x97, 0x0C, 0xE0, 0x75, 0xE4, 0xFA, 0xFB, + 0x77, 0x8A, 0x2A, 0xF5, 0x03, 0x60, 0x4B, 0x36, 0x8B, 0x16, 0x23, 0x16, + 0xAD, 0x09, 0x71, 0xF4, 0x4A, 0xF4, 0x28, 0x50, 0xB4, 0xFE, 0x88, 0x1C, + 0x6E, 0x3F, 0x6C, 0x2F, 0x2F, 0x09, 0x59, 0x5B, 0xA5, 0x5B, 0x0B, 0x33, + 0x99, 0xE2, 0xC3, 0x3D, 0x89, 0xF9, 0x6A, 0x2C, 0xEF, 0xB2, 0xD3, 0x06, + 0xE9 +}; + +static const unsigned char TA419_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA419_RSA_N[] = { + 0x91, 0xE8, 0x54, 0x92, 0xD2, 0x0A, 0x56, 0xB1, 0xAC, 0x0D, 0x24, 0xDD, + 0xC5, 0xCF, 0x44, 0x67, 0x74, 0x99, 0x2B, 0x37, 0xA3, 0x7D, 0x23, 0x70, + 0x00, 0x71, 0xBC, 0x53, 0xDF, 0xC4, 0xFA, 0x2A, 0x12, 0x8F, 0x4B, 0x7F, + 0x10, 0x56, 0xBD, 0x9F, 0x70, 0x72, 0xB7, 0x61, 0x7F, 0xC9, 0x4B, 0x0F, + 0x17, 0xA7, 0x3D, 0xE3, 0xB0, 0x04, 0x61, 0xEE, 0xFF, 0x11, 0x97, 0xC7, + 0xF4, 0x86, 0x3E, 0x0A, 0xFA, 0x3E, 0x5C, 0xF9, 0x93, 0xE6, 0x34, 0x7A, + 0xD9, 0x14, 0x6B, 0xE7, 0x9C, 0xB3, 0x85, 0xA0, 0x82, 0x7A, 0x76, 0xAF, + 0x71, 0x90, 0xD7, 0xEC, 0xFD, 0x0D, 0xFA, 0x9C, 0x6C, 0xFA, 0xDF, 0xB0, + 0x82, 0xF4, 0x14, 0x7E, 0xF9, 0xBE, 0xC4, 0xA6, 0x2F, 0x4F, 0x7F, 0x99, + 0x7F, 0xB5, 0xFC, 0x67, 0x43, 0x72, 0xBD, 0x0C, 0x00, 0xD6, 0x89, 0xEB, + 0x6B, 0x2C, 0xD3, 0xED, 0x8F, 0x98, 0x1C, 0x14, 0xAB, 0x7E, 0xE5, 0xE3, + 0x6E, 0xFC, 0xD8, 0xA8, 0xE4, 0x92, 0x24, 0xDA, 0x43, 0x6B, 0x62, 0xB8, + 0x55, 0xFD, 0xEA, 0xC1, 0xBC, 0x6C, 0xB6, 0x8B, 0xF3, 0x0E, 0x8D, 0x9A, + 0xE4, 0x9B, 0x6C, 0x69, 0x99, 0xF8, 0x78, 0x48, 0x30, 0x45, 0xD5, 0xAD, + 0xE1, 0x0D, 0x3C, 0x45, 0x60, 0xFC, 0x32, 0x96, 0x51, 0x27, 0xBC, 0x67, + 0xC3, 0xCA, 0x2E, 0xB6, 0x6B, 0xEA, 0x46, 0xC7, 0xC7, 0x20, 0xA0, 0xB1, + 0x1F, 0x65, 0xDE, 0x48, 0x08, 0xBA, 0xA4, 0x4E, 0xA9, 0xF2, 0x83, 0x46, + 0x37, 0x84, 0xEB, 0xE8, 0xCC, 0x81, 0x48, 0x43, 0x67, 0x4E, 0x72, 0x2A, + 0x9B, 0x5C, 0xBD, 0x4C, 0x1B, 0x28, 0x8A, 0x5C, 0x22, 0x7B, 0xB4, 0xAB, + 0x98, 0xD9, 0xEE, 0xE0, 0x51, 0x83, 0xC3, 0x09, 0x46, 0x4E, 0x6D, 0x3E, + 0x99, 0xFA, 0x95, 0x17, 0xDA, 0x7C, 0x33, 0x57, 0x41, 0x3C, 0x8D, 0x51, + 0xED, 0x0B, 0xB6, 0x5C, 0xAF, 0x2C, 0x63, 0x1A, 0xDF, 0x57, 0xC8, 0x3F, + 0xBC, 0xE9, 0x5D, 0xC4, 0x9B, 0xAF, 0x45, 0x99, 0xE2, 0xA3, 0x5A, 0x24, + 0xB4, 0xBA, 0xA9, 0x56, 0x3D, 0xCF, 0x6F, 0xAA, 0xFF, 0x49, 0x58, 0xBE, + 0xF0, 0xA8, 0xFF, 0xF4, 0xB8, 0xAD, 0xE9, 0x37, 0xFB, 0xBA, 0xB8, 0xF4, + 0x0B, 0x3A, 0xF9, 0xE8, 0x43, 0x42, 0x1E, 0x89, 0xD8, 0x84, 0xCB, 0x13, + 0xF1, 0xD9, 0xBB, 0xE1, 0x89, 0x60, 0xB8, 0x8C, 0x28, 0x56, 0xAC, 0x14, + 0x1D, 0x9C, 0x0A, 0xE7, 0x71, 0xEB, 0xCF, 0x0E, 0xDD, 0x3D, 0xA9, 0x96, + 0xA1, 0x48, 0xBD, 0x3C, 0xF7, 0xAF, 0xB5, 0x0D, 0x22, 0x4C, 0xC0, 0x11, + 0x81, 0xEC, 0x56, 0x3B, 0xF6, 0xD3, 0xA2, 0xE2, 0x5B, 0xB7, 0xB2, 0x04, + 0x22, 0x52, 0x95, 0x80, 0x93, 0x69, 0xE8, 0x8E, 0x4C, 0x65, 0xF1, 0x91, + 0x03, 0x2D, 0x70, 0x74, 0x02, 0xEA, 0x8B, 0x67, 0x15, 0x29, 0x69, 0x52, + 0x02, 0xBB, 0xD7, 0xDF, 0x50, 0x6A, 0x55, 0x46, 0xBF, 0xA0, 0xA3, 0x28, + 0x61, 0x7F, 0x70, 0xD0, 0xC3, 0xA2, 0xAA, 0x2C, 0x21, 0xAA, 0x47, 0xCE, + 0x28, 0x9C, 0x06, 0x45, 0x76, 0xBF, 0x82, 0x18, 0x27, 0xB4, 0xD5, 0xAE, + 0xB4, 0xCB, 0x50, 0xE6, 0x6B, 0xF4, 0x4C, 0x86, 0x71, 0x30, 0xE9, 0xA6, + 0xDF, 0x16, 0x86, 0xE0, 0xD8, 0xFF, 0x40, 0xDD, 0xFB, 0xD0, 0x42, 0x88, + 0x7F, 0xA3, 0x33, 0x3A, 0x2E, 0x5C, 0x1E, 0x41, 0x11, 0x81, 0x63, 0xCE, + 0x18, 0x71, 0x6B, 0x2B, 0xEC, 0xA6, 0x8A, 0xB7, 0x31, 0x5C, 0x3A, 0x6A, + 0x47, 0xE0, 0xC3, 0x79, 0x59, 0xD6, 0x20, 0x1A, 0xAF, 0xF2, 0x6A, 0x98, + 0xAA, 0x72, 0xBC, 0x57, 0x4A, 0xD2, 0x4B, 0x9D, 0xBB, 0x10, 0xFC, 0xB0, + 0x4C, 0x41, 0xE5, 0xED, 0x1D, 0x3D, 0x5E, 0x28, 0x9D, 0x9C, 0xCC, 0xBF, + 0xB3, 0x51, 0xDA, 0xA7, 0x47, 0xE5, 0x84, 0x53 +}; + +static const unsigned char TA419_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA420_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x45, 0x31 +}; + +static const unsigned char TA420_EC_Q[] = { + 0x04, 0xDE, 0x6F, 0xF8, 0x7F, 0x1C, 0xDF, 0xED, 0xF9, 0x47, 0x87, 0x86, + 0xB1, 0xA4, 0xC0, 0x8A, 0xF8, 0x82, 0x97, 0x80, 0xEA, 0x8F, 0xC8, 0x4A, + 0x5E, 0x2A, 0x7D, 0x88, 0x68, 0xA7, 0x01, 0x62, 0x14, 0x91, 0x24, 0x7A, + 0x5C, 0x9E, 0xA3, 0x17, 0x7D, 0x8A, 0x86, 0x21, 0x34, 0x18, 0x50, 0x1B, + 0x10, 0xDE, 0xD0, 0x37, 0x4B, 0x26, 0xC7, 0x19, 0x60, 0x80, 0xE9, 0x34, + 0xBD, 0x60, 0x19, 0x36, 0x40, 0xD6, 0x29, 0x87, 0x09, 0x3C, 0x91, 0x7A, + 0xF6, 0xBC, 0x13, 0x23, 0xDD, 0x59, 0x4E, 0x04, 0x5E, 0xCF, 0xC8, 0x02, + 0x1C, 0x18, 0x53, 0xC1, 0x31, 0xD8, 0xDA, 0x20, 0xE9, 0x44, 0x8D, 0xE4, + 0x76 +}; + +static const unsigned char TA421_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x52, 0x31 +}; + +static const unsigned char TA421_RSA_N[] = { + 0xD0, 0x36, 0xD4, 0x1F, 0xEA, 0xDD, 0xAB, 0xE4, 0xD1, 0xB6, 0xE6, 0xFB, + 0x22, 0xC0, 0xDD, 0x13, 0x0D, 0x6A, 0x7B, 0x22, 0x13, 0x1C, 0x97, 0x3C, + 0x68, 0x63, 0x66, 0x32, 0x9C, 0x03, 0xB5, 0x8D, 0xA4, 0x81, 0x83, 0xDA, + 0x78, 0x30, 0x11, 0xCF, 0xDC, 0xB2, 0x2B, 0xBE, 0x92, 0xBF, 0x8E, 0xE4, + 0xC4, 0x13, 0xBE, 0xA4, 0x68, 0x4C, 0xDA, 0x02, 0x68, 0x16, 0x74, 0xBE, + 0xB2, 0xDD, 0x04, 0xE4, 0x6B, 0x2A, 0xDD, 0x37, 0x1F, 0x60, 0x2C, 0xDB, + 0xF5, 0xF7, 0xA1, 0x7C, 0x95, 0xB7, 0x0C, 0x70, 0x86, 0x2E, 0xF1, 0x3A, + 0xEF, 0x52, 0xF7, 0xCC, 0xD3, 0x9B, 0xF9, 0x8B, 0xBE, 0x0E, 0xDF, 0x31, + 0xB7, 0x9D, 0x68, 0x5C, 0x92, 0xA6, 0xF5, 0xE5, 0xF3, 0x0A, 0x34, 0xB5, + 0xFF, 0x7B, 0xA2, 0xE4, 0x87, 0xA1, 0xC6, 0xAF, 0x17, 0x00, 0xEF, 0x03, + 0x91, 0xED, 0xA9, 0x1C, 0x4E, 0x71, 0x3D, 0xD2, 0x8B, 0x6C, 0x89, 0xF4, + 0x78, 0x86, 0xE6, 0x6A, 0x49, 0xA0, 0xCE, 0xB5, 0xD2, 0xB0, 0xAB, 0x9B, + 0xF6, 0xF4, 0xD4, 0x2E, 0xE3, 0x72, 0xF9, 0x36, 0xC6, 0xEB, 0x15, 0xB7, + 0x25, 0x8C, 0x3A, 0xFC, 0x25, 0x0D, 0xB3, 0x22, 0x73, 0x21, 0x74, 0xC8, + 0x4A, 0x96, 0x61, 0x92, 0xF5, 0x2F, 0x0B, 0x18, 0xA5, 0xF4, 0xAD, 0xE2, + 0xEE, 0x41, 0xBD, 0x01, 0x79, 0xFA, 0x96, 0x8C, 0x8D, 0x17, 0x02, 0x30, + 0xB4, 0xF9, 0xAF, 0x78, 0x1A, 0x8C, 0xB4, 0x36, 0x10, 0x10, 0x07, 0x05, + 0x70, 0xD0, 0xF4, 0x31, 0x90, 0x8A, 0x51, 0xC5, 0x86, 0x26, 0x79, 0xB2, + 0x11, 0x88, 0x5E, 0xC5, 0xF0, 0x0A, 0x54, 0xCD, 0x49, 0xA6, 0xBF, 0x02, + 0x9C, 0xD2, 0x44, 0xA7, 0xED, 0xE3, 0x78, 0xEF, 0x46, 0x5E, 0x6D, 0x71, + 0xD1, 0x79, 0x70, 0x1C, 0x46, 0x5F, 0x51, 0xE9, 0xC9, 0x37, 0xDC, 0x5F, + 0x7E, 0x69, 0x7B, 0x41, 0xDF, 0x34, 0x45, 0xE0, 0x3B, 0x84, 0xF4, 0xA1, + 0x8A, 0x0A, 0x36, 0x9E, 0x37, 0xCC, 0x62, 0x52, 0xE1, 0x89, 0x0D, 0x28, + 0xF9, 0x7A, 0x23, 0xB1, 0x0D, 0x3D, 0x3D, 0x9A, 0xFD, 0x9D, 0x81, 0xEF, + 0x2C, 0x90, 0xC0, 0x7B, 0x44, 0x4E, 0xBB, 0x49, 0xE0, 0x0E, 0x4A, 0x56, + 0x92, 0xBC, 0xCB, 0xB5, 0xDD, 0x79, 0x17, 0x89, 0x91, 0xDE, 0x61, 0x89, + 0x74, 0x92, 0xA8, 0xE3, 0x32, 0x85, 0xBE, 0x4E, 0x85, 0xA4, 0x4B, 0x59, + 0xCB, 0x2B, 0xC5, 0x78, 0x8E, 0x71, 0x54, 0xD0, 0x02, 0x37, 0x99, 0x8C, + 0xE5, 0x49, 0xEA, 0xE0, 0x54, 0x72, 0xA4, 0x11, 0x06, 0x2F, 0x0B, 0x8C, + 0xC1, 0x5B, 0xBE, 0xB5, 0xA1, 0xB0, 0x53, 0x6E, 0x9C, 0xB8, 0x60, 0x91, + 0x1F, 0x59, 0x6B, 0xF9, 0x2D, 0xF4, 0x94, 0x0A, 0x97, 0xB5, 0xEC, 0xC5, + 0x76, 0x03, 0x54, 0x1B, 0x65, 0x52, 0xBA, 0x4C, 0x92, 0x56, 0x51, 0x35, + 0xA0, 0x40, 0xD8, 0x29, 0xDB, 0xAE, 0x52, 0x76, 0x3B, 0x2D, 0x30, 0x40, + 0x9B, 0x8A, 0xD0, 0x42, 0x56, 0xB4, 0xB7, 0x88, 0x01, 0xA4, 0x87, 0x3B, + 0x53, 0x96, 0xCD, 0xA3, 0x16, 0x8F, 0xF3, 0x66, 0xAA, 0x17, 0xB1, 0xC7, + 0x60, 0xE0, 0xC1, 0x43, 0x05, 0x0C, 0xEE, 0x9B, 0x5B, 0x60, 0x6F, 0x06, + 0x5C, 0x87, 0x5B, 0x27, 0xF9, 0x40, 0x11, 0x9E, 0x9C, 0x33, 0xC1, 0xB7, + 0xE5, 0x35, 0x57, 0x05, 0x7F, 0x27, 0xCE, 0x17, 0x20, 0x8C, 0x1C, 0xFC, + 0xF1, 0xFB, 0xDA, 0x31, 0x29, 0x49, 0xED, 0xF5, 0x0B, 0x84, 0xA7, 0x4F, + 0xC1, 0xF6, 0x4E, 0xC2, 0x28, 0x9C, 0xFA, 0xEE, 0xE0, 0xAF, 0x07, 0xFB, + 0x33, 0x11, 0x7A, 0x21, 0x4F, 0x0B, 0x21, 0x10, 0xB6, 0x40, 0x3A, 0xAB, + 0x22, 0x3A, 0x04, 0x9C, 0x8B, 0x9B, 0x84, 0x86, 0x72, 0x9A, 0xD2, 0xA7, + 0xA5, 0xC4, 0xB4, 0x75, 0x91, 0xA9, 0x2B, 0x23 +}; + +static const unsigned char TA421_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA422_DN[] = { + 0x30, 0x34, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x08, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61 +}; + +static const unsigned char TA422_RSA_N[] = { + 0xC8, 0x68, 0xF1, 0xC9, 0xD6, 0xD6, 0xB3, 0x34, 0x75, 0x26, 0x82, 0x1E, + 0xEC, 0xB4, 0xBE, 0xEA, 0x5C, 0xE1, 0x26, 0xED, 0x11, 0x47, 0x61, 0xE1, + 0xA2, 0x7C, 0x16, 0x78, 0x40, 0x21, 0xE4, 0x60, 0x9E, 0x5A, 0xC8, 0x63, + 0xE1, 0xC4, 0xB1, 0x96, 0x92, 0xFF, 0x18, 0x6D, 0x69, 0x23, 0xE1, 0x2B, + 0x62, 0xF7, 0xDD, 0xE2, 0x36, 0x2F, 0x91, 0x07, 0xB9, 0x48, 0xCF, 0x0E, + 0xEC, 0x79, 0xB6, 0x2C, 0xE7, 0x34, 0x4B, 0x70, 0x08, 0x25, 0xA3, 0x3C, + 0x87, 0x1B, 0x19, 0xF2, 0x81, 0x07, 0x0F, 0x38, 0x90, 0x19, 0xD3, 0x11, + 0xFE, 0x86, 0xB4, 0xF2, 0xD1, 0x5E, 0x1E, 0x1E, 0x96, 0xCD, 0x80, 0x6C, + 0xCE, 0x3B, 0x31, 0x93, 0xB6, 0xF2, 0xA0, 0xD0, 0xA9, 0x95, 0x12, 0x7D, + 0xA5, 0x9A, 0xCC, 0x6B, 0xC8, 0x84, 0x56, 0x8A, 0x33, 0xA9, 0xE7, 0x22, + 0x15, 0x53, 0x16, 0xF0, 0xCC, 0x17, 0xEC, 0x57, 0x5F, 0xE9, 0xA2, 0x0A, + 0x98, 0x09, 0xDE, 0xE3, 0x5F, 0x9C, 0x6F, 0xDC, 0x48, 0xE3, 0x85, 0x0B, + 0x15, 0x5A, 0xA6, 0xBA, 0x9F, 0xAC, 0x48, 0xE3, 0x09, 0xB2, 0xF7, 0xF4, + 0x32, 0xDE, 0x5E, 0x34, 0xBE, 0x1C, 0x78, 0x5D, 0x42, 0x5B, 0xCE, 0x0E, + 0x22, 0x8F, 0x4D, 0x90, 0xD7, 0x7D, 0x32, 0x18, 0xB3, 0x0B, 0x2C, 0x6A, + 0xBF, 0x8E, 0x3F, 0x14, 0x11, 0x89, 0x20, 0x0E, 0x77, 0x14, 0xB5, 0x3D, + 0x94, 0x08, 0x87, 0xF7, 0x25, 0x1E, 0xD5, 0xB2, 0x60, 0x00, 0xEC, 0x6F, + 0x2A, 0x28, 0x25, 0x6E, 0x2A, 0x3E, 0x18, 0x63, 0x17, 0x25, 0x3F, 0x3E, + 0x44, 0x20, 0x16, 0xF6, 0x26, 0xC8, 0x25, 0xAE, 0x05, 0x4A, 0xB4, 0xE7, + 0x63, 0x2C, 0xF3, 0x8C, 0x16, 0x53, 0x7E, 0x5C, 0xFB, 0x11, 0x1A, 0x08, + 0xC1, 0x46, 0x62, 0x9F, 0x22, 0xB8, 0xF1, 0xC2, 0x8D, 0x69, 0xDC, 0xFA, + 0x3A, 0x58, 0x06, 0xDF +}; + +static const unsigned char TA422_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA423_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x13, 0x30, 0x30, + 0x30, 0x32, 0x20, 0x34, 0x38, 0x31, 0x34, 0x36, 0x33, 0x30, 0x38, 0x31, + 0x30, 0x30, 0x30, 0x33, 0x36, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA423_RSA_N[] = { + 0xCD, 0x18, 0x39, 0x65, 0x1A, 0x59, 0xB1, 0xEA, 0x64, 0x16, 0x0E, 0x8C, + 0x94, 0x24, 0x95, 0x7C, 0x83, 0xD3, 0xC5, 0x39, 0x26, 0xDC, 0x0C, 0xEF, + 0x16, 0x57, 0x8D, 0xD7, 0xD8, 0xAC, 0xA3, 0x42, 0x7F, 0x82, 0xCA, 0xED, + 0xCD, 0x5B, 0xDB, 0x0E, 0xB7, 0x2D, 0xED, 0x45, 0x08, 0x17, 0xB2, 0xD9, + 0xB3, 0xCB, 0xD6, 0x17, 0x52, 0x72, 0x28, 0xDB, 0x8E, 0x4E, 0x9E, 0x8A, + 0xB6, 0x0B, 0xF9, 0x9E, 0x84, 0x9A, 0x4D, 0x76, 0xDE, 0x22, 0x29, 0x5C, + 0xD2, 0xB3, 0xD2, 0x06, 0x3E, 0x30, 0x39, 0xA9, 0x74, 0xA3, 0x92, 0x56, + 0x1C, 0xA1, 0x6F, 0x4C, 0x0A, 0x20, 0x6D, 0x9F, 0x23, 0x7A, 0xB4, 0xC6, + 0xDA, 0x2C, 0xE4, 0x1D, 0x2C, 0xDC, 0xB3, 0x28, 0xD0, 0x13, 0xF2, 0x4C, + 0x4E, 0x02, 0x49, 0xA1, 0x54, 0x40, 0x9E, 0xE6, 0xE5, 0x05, 0xA0, 0x2D, + 0x84, 0xC8, 0xFF, 0x98, 0x6C, 0xD0, 0xEB, 0x8A, 0x1A, 0x84, 0x08, 0x1E, + 0xB7, 0x68, 0x23, 0xEE, 0x23, 0xD5, 0x70, 0xCE, 0x6D, 0x51, 0x69, 0x10, + 0xEE, 0xA1, 0x7A, 0xC2, 0xD1, 0x22, 0x31, 0xC2, 0x82, 0x85, 0xD2, 0xF2, + 0x55, 0x76, 0x50, 0x7C, 0x25, 0x7A, 0xC9, 0x84, 0x5C, 0x0B, 0xAC, 0xDD, + 0x42, 0x4E, 0x2B, 0xE7, 0x82, 0xA2, 0x24, 0x89, 0xCB, 0x90, 0xB2, 0xD0, + 0xEE, 0x23, 0xBA, 0x66, 0x4C, 0xBB, 0x62, 0xA4, 0xF9, 0x53, 0x5A, 0x64, + 0x7B, 0x7C, 0x98, 0xFA, 0xA3, 0x48, 0x9E, 0x0F, 0x95, 0xAE, 0xA7, 0x18, + 0xF4, 0x6A, 0xEC, 0x2E, 0x03, 0x45, 0xAF, 0xF0, 0x74, 0xF8, 0x2A, 0xCD, + 0x7A, 0x5D, 0xD1, 0xBE, 0x44, 0x26, 0x32, 0x29, 0xF1, 0xF1, 0xF5, 0x6C, + 0xCC, 0x7E, 0x02, 0x21, 0x0B, 0x9F, 0x6F, 0xA4, 0x3F, 0xBE, 0x9D, 0x53, + 0xE2, 0xCF, 0x7D, 0xA9, 0x2C, 0x7C, 0x58, 0x1A, 0x97, 0xE1, 0x3D, 0x37, + 0x37, 0x18, 0x66, 0x28, 0xD2, 0x40, 0xC5, 0x51, 0x8A, 0x8C, 0xC3, 0x2D, + 0xCE, 0x53, 0x88, 0x24, 0x58, 0x64, 0x30, 0x16, 0xC5, 0xAA, 0xE0, 0xD6, + 0x0A, 0xA6, 0x40, 0xDF, 0x78, 0xF6, 0xF5, 0x04, 0x7C, 0x69, 0x13, 0x84, + 0xBC, 0xD1, 0xD1, 0xA7, 0x06, 0xCF, 0x01, 0xF7, 0x68, 0xC0, 0xA8, 0x57, + 0xBB, 0x3A, 0x61, 0xAD, 0x04, 0x8C, 0x93, 0xE3, 0xAD, 0xFC, 0xF0, 0xDB, + 0x44, 0x6D, 0x59, 0xDC, 0x49, 0x59, 0xAE, 0xAC, 0x9A, 0x99, 0x36, 0x30, + 0x41, 0x7B, 0x76, 0x33, 0x22, 0x87, 0xA3, 0xC2, 0x92, 0x86, 0x6E, 0xF9, + 0x70, 0xEE, 0xAE, 0x87, 0x87, 0x95, 0x1B, 0xC4, 0x7A, 0xBD, 0x31, 0xF3, + 0xD4, 0xD2, 0xE5, 0x99, 0xFF, 0xBE, 0x48, 0xEC, 0x75, 0xF5, 0x78, 0x16, + 0x1D, 0xA6, 0x70, 0xC1, 0x7F, 0x3C, 0x1B, 0xA1, 0x92, 0xFB, 0xCF, 0xC8, + 0x3C, 0xD6, 0xC5, 0x93, 0x0A, 0x8F, 0xF5, 0x55, 0x3A, 0x76, 0x95, 0xCE, + 0x59, 0x98, 0x8A, 0x09, 0x95, 0x77, 0x32, 0x9A, 0x83, 0xBA, 0x2C, 0x04, + 0x3A, 0x97, 0xBD, 0xD4, 0x2F, 0xBE, 0xD7, 0x6C, 0x9B, 0xA2, 0xCA, 0x7D, + 0x6D, 0x26, 0xC9, 0x55, 0xD5, 0xCF, 0xC3, 0x79, 0x52, 0x08, 0x09, 0x99, + 0x07, 0x24, 0x2D, 0x64, 0x25, 0x6B, 0xA6, 0x21, 0x69, 0x9B, 0x6A, 0xDD, + 0x74, 0x4D, 0x6B, 0x97, 0x7A, 0x41, 0xBD, 0xAB, 0x17, 0xF9, 0x90, 0x17, + 0x48, 0x8F, 0x36, 0xF9, 0x2D, 0xD5, 0xC5, 0xDB, 0xEE, 0xAA, 0x85, 0x45, + 0x41, 0xFA, 0xCD, 0x3A, 0x45, 0xB1, 0x68, 0xE6, 0x36, 0x4C, 0x9B, 0x90, + 0x57, 0xEC, 0x23, 0xB9, 0x87, 0x08, 0xC2, 0xC4, 0x09, 0xF1, 0x97, 0x86, + 0x2A, 0x28, 0x4D, 0xE2, 0x74, 0xC0, 0xDA, 0xC4, 0x8C, 0xDB, 0xDF, 0xE2, + 0xA1, 0x17, 0x59, 0xCE, 0x24, 0x59, 0x74, 0x31, 0xDA, 0x7F, 0xFD, 0x30, + 0x6D, 0xD9, 0xDC, 0xE1, 0x6A, 0xE1, 0xFC, 0x5F +}; + +static const unsigned char TA423_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA424_DN[] = { + 0x30, 0x74, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x45, 0x43, 0x2D, 0x33, 0x38, 0x34, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA424_EC_Q[] = { + 0x04, 0xC4, 0x28, 0x8E, 0xAB, 0x18, 0x5B, 0x6A, 0xBE, 0x6E, 0x64, 0x37, + 0x63, 0xE4, 0xCD, 0xEC, 0xAB, 0x3A, 0xF7, 0xCC, 0xA1, 0xB8, 0x0E, 0x82, + 0x49, 0xD7, 0x86, 0x29, 0x9F, 0xA1, 0x94, 0xF2, 0xE3, 0x60, 0x78, 0x98, + 0x81, 0x78, 0x06, 0x4D, 0xF2, 0xEC, 0x9A, 0x0E, 0x57, 0x60, 0x83, 0x9F, + 0xB4, 0xE6, 0x17, 0x2F, 0x1A, 0xB3, 0x5D, 0x02, 0x5B, 0x89, 0x23, 0x3C, + 0xC2, 0x11, 0x05, 0x2A, 0xA7, 0x88, 0x13, 0x18, 0xF3, 0x50, 0x84, 0xD7, + 0xBD, 0x34, 0x2C, 0x27, 0x89, 0x55, 0xFF, 0xCE, 0x4C, 0xE7, 0xDF, 0xA6, + 0x1F, 0x28, 0xC4, 0xF0, 0x54, 0xC3, 0xB9, 0x7C, 0xB7, 0x53, 0xAD, 0xEB, + 0xC2 +}; + +static const unsigned char TA425_DN[] = { + 0x30, 0x7E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, 0x65, + 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, + 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, + 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, 0x65, + 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA425_RSA_N[] = { + 0xE3, 0xFB, 0x7D, 0xA3, 0x72, 0xBA, 0xC2, 0xF0, 0xC9, 0x14, 0x87, 0xF5, + 0x6B, 0x01, 0x4E, 0xE1, 0x6E, 0x40, 0x07, 0xBA, 0x6D, 0x27, 0x5D, 0x7F, + 0xF7, 0x5B, 0x2D, 0xB3, 0x5A, 0xC7, 0x51, 0x5F, 0xAB, 0xA4, 0x32, 0xA6, + 0x61, 0x87, 0xB6, 0x6E, 0x0F, 0x86, 0xD2, 0x30, 0x02, 0x97, 0xF8, 0xD7, + 0x69, 0x57, 0xA1, 0x18, 0x39, 0x5D, 0x6A, 0x64, 0x79, 0xC6, 0x01, 0x59, + 0xAC, 0x3C, 0x31, 0x4A, 0x38, 0x7C, 0xD2, 0x04, 0xD2, 0x4B, 0x28, 0xE8, + 0x20, 0x5F, 0x3B, 0x07, 0xA2, 0xCC, 0x4D, 0x73, 0xDB, 0xF3, 0xAE, 0x4F, + 0xC7, 0x56, 0xD5, 0x5A, 0xA7, 0x96, 0x89, 0xFA, 0xF3, 0xAB, 0x68, 0xD4, + 0x23, 0x86, 0x59, 0x27, 0xCF, 0x09, 0x27, 0xBC, 0xAC, 0x6E, 0x72, 0x83, + 0x1C, 0x30, 0x72, 0xDF, 0xE0, 0xA2, 0xE9, 0xD2, 0xE1, 0x74, 0x75, 0x19, + 0xBD, 0x2A, 0x9E, 0x7B, 0x15, 0x54, 0x04, 0x1B, 0xD7, 0x43, 0x39, 0xAD, + 0x55, 0x28, 0xC5, 0xE2, 0x1A, 0xBB, 0xF4, 0xC0, 0xE4, 0xAE, 0x38, 0x49, + 0x33, 0xCC, 0x76, 0x85, 0x9F, 0x39, 0x45, 0xD2, 0xA4, 0x9E, 0xF2, 0x12, + 0x8C, 0x51, 0xF8, 0x7C, 0xE4, 0x2D, 0x7F, 0xF5, 0xAC, 0x5F, 0xEB, 0x16, + 0x9F, 0xB1, 0x2D, 0xD1, 0xBA, 0xCC, 0x91, 0x42, 0x77, 0x4C, 0x25, 0xC9, + 0x90, 0x38, 0x6F, 0xDB, 0xF0, 0xCC, 0xFB, 0x8E, 0x1E, 0x97, 0x59, 0x3E, + 0xD5, 0x60, 0x4E, 0xE6, 0x05, 0x28, 0xED, 0x49, 0x79, 0x13, 0x4B, 0xBA, + 0x48, 0xDB, 0x2F, 0xF9, 0x72, 0xD3, 0x39, 0xCA, 0xFE, 0x1F, 0xD8, 0x34, + 0x72, 0xF5, 0xB4, 0x40, 0xCF, 0x31, 0x01, 0xC3, 0xEC, 0xDE, 0x11, 0x2D, + 0x17, 0x5D, 0x1F, 0xB8, 0x50, 0xD1, 0x5E, 0x19, 0xA7, 0x69, 0xDE, 0x07, + 0x33, 0x28, 0xCA, 0x50, 0x95, 0xF9, 0xA7, 0x54, 0xCB, 0x54, 0x86, 0x50, + 0x45, 0xA9, 0xF9, 0x49 +}; + +static const unsigned char TA425_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA426_DN[] = { + 0x30, 0x81, 0x80, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, + 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x24, 0x30, + 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x43, 0x65, 0x72, 0x74, + 0x75, 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, + 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA426_RSA_N[] = { + 0xBD, 0xF9, 0x78, 0xF8, 0xE6, 0xD5, 0x80, 0x0C, 0x64, 0x9D, 0x86, 0x1B, + 0x96, 0x64, 0x67, 0x3F, 0x22, 0x3A, 0x1E, 0x75, 0x01, 0x7D, 0xEF, 0xFB, + 0x5C, 0x67, 0x8C, 0xC9, 0xCC, 0x5C, 0x6B, 0xA9, 0x91, 0xE6, 0xB9, 0x42, + 0xE5, 0x20, 0x4B, 0x9B, 0xDA, 0x9B, 0x7B, 0xB9, 0x99, 0x5D, 0xD9, 0x9B, + 0x80, 0x4B, 0xD7, 0x84, 0x40, 0x2B, 0x27, 0xD3, 0xE8, 0xBA, 0x30, 0xBB, + 0x3E, 0x09, 0x1A, 0xA7, 0x49, 0x95, 0xEF, 0x2B, 0x40, 0x24, 0xC2, 0x97, + 0xC7, 0xA7, 0xEE, 0x9B, 0x25, 0xEF, 0xA8, 0x0A, 0x00, 0x97, 0x85, 0x5A, + 0xAA, 0x9D, 0xDC, 0x29, 0xC9, 0xE2, 0x35, 0x07, 0xEB, 0x70, 0x4D, 0x4A, + 0xD6, 0xC1, 0xB3, 0x56, 0xB8, 0xA1, 0x41, 0x38, 0x9B, 0xD1, 0xFB, 0x31, + 0x7F, 0x8F, 0xE0, 0x5F, 0xE1, 0xB1, 0x3F, 0x0F, 0x8E, 0x16, 0x49, 0x60, + 0xD7, 0x06, 0x8D, 0x18, 0xF9, 0xAA, 0x26, 0x10, 0xAB, 0x2A, 0xD3, 0xD0, + 0xD1, 0x67, 0x8D, 0x1B, 0x46, 0xBE, 0x47, 0x30, 0xD5, 0x2E, 0x72, 0xD1, + 0xC5, 0x63, 0xDA, 0xE7, 0x63, 0x79, 0x44, 0x7E, 0x4B, 0x63, 0x24, 0x89, + 0x86, 0x2E, 0x34, 0x3F, 0x29, 0x4C, 0x52, 0x8B, 0x2A, 0xA7, 0xC0, 0xE2, + 0x91, 0x28, 0x89, 0xB9, 0xC0, 0x5B, 0xF9, 0x1D, 0xD9, 0xE7, 0x27, 0xAD, + 0xFF, 0x9A, 0x02, 0x97, 0xC1, 0xC6, 0x50, 0x92, 0x9B, 0x02, 0x2C, 0xBD, + 0xA9, 0xB9, 0x34, 0x59, 0x0A, 0xBF, 0x84, 0x4A, 0xFF, 0xDF, 0xFE, 0xB3, + 0x9F, 0xEB, 0xD9, 0x9E, 0xE0, 0x98, 0x23, 0xEC, 0xA6, 0x6B, 0x77, 0x16, + 0x2A, 0xDB, 0xCC, 0xAD, 0x3B, 0x1C, 0xA4, 0x87, 0xDC, 0x46, 0x73, 0x5E, + 0x19, 0x62, 0x68, 0x45, 0x57, 0xE4, 0x90, 0x82, 0x42, 0xBB, 0x42, 0xD6, + 0xF0, 0x61, 0xE0, 0xC1, 0xA3, 0x3D, 0x66, 0xA3, 0x5D, 0xF4, 0x18, 0xEE, + 0x88, 0xC9, 0x8D, 0x17, 0x45, 0x29, 0x99, 0x32, 0x75, 0x02, 0x31, 0xEE, + 0x29, 0x26, 0xC8, 0x6B, 0x02, 0xE6, 0xB5, 0x62, 0x45, 0x7F, 0x37, 0x15, + 0x5A, 0x23, 0x68, 0x89, 0xD4, 0x3E, 0xDE, 0x4E, 0x27, 0xB0, 0xF0, 0x40, + 0x0C, 0xBC, 0x4D, 0x17, 0xCB, 0x4D, 0xA2, 0xB3, 0x1E, 0xD0, 0x06, 0x5A, + 0xDD, 0xF6, 0x93, 0xCF, 0x57, 0x75, 0x99, 0xF5, 0xFA, 0x86, 0x1A, 0x67, + 0x78, 0xB3, 0xBF, 0x96, 0xFE, 0x34, 0xDC, 0xBD, 0xE7, 0x52, 0x56, 0xE5, + 0xB3, 0xE5, 0x75, 0x7B, 0xD7, 0x41, 0x91, 0x05, 0xDC, 0x5D, 0x69, 0xE3, + 0x95, 0x0D, 0x43, 0xB9, 0xFC, 0x83, 0x96, 0x39, 0x95, 0x7B, 0x6C, 0x80, + 0x5A, 0x4F, 0x13, 0x72, 0xC6, 0xD7, 0x7D, 0x29, 0x7A, 0x44, 0xBA, 0x52, + 0xA4, 0x2A, 0xD5, 0x41, 0x46, 0x09, 0x20, 0xFE, 0x22, 0xA0, 0xB6, 0x5B, + 0x30, 0x8D, 0xBC, 0x89, 0x0C, 0xD5, 0xD7, 0x70, 0xF8, 0x87, 0x52, 0xFD, + 0xDA, 0xEF, 0xAC, 0x51, 0x2E, 0x07, 0xB3, 0x4E, 0xFE, 0xD0, 0x09, 0xDA, + 0x70, 0xEF, 0x98, 0xFA, 0x56, 0xE6, 0x6D, 0xDB, 0xB5, 0x57, 0x4B, 0xDC, + 0xE5, 0x2C, 0x25, 0x15, 0xC8, 0x9E, 0x2E, 0x78, 0x4E, 0xF8, 0xDA, 0x9C, + 0x9E, 0x86, 0x2C, 0xCA, 0x57, 0xF3, 0x1A, 0xE5, 0xC8, 0x92, 0x8B, 0x1A, + 0x82, 0x96, 0x7A, 0xC3, 0xBC, 0x50, 0x12, 0x69, 0xD8, 0x0E, 0x5A, 0x46, + 0x8B, 0x3A, 0xEB, 0x26, 0xFA, 0x23, 0xC9, 0xB6, 0xB0, 0x81, 0xBE, 0x42, + 0x00, 0xA4, 0xF8, 0xD6, 0xFE, 0x30, 0x2E, 0xC7, 0xD2, 0x46, 0xF6, 0xE5, + 0x8E, 0x75, 0xFD, 0xF2, 0xCC, 0xB9, 0xD0, 0x87, 0x5B, 0xCC, 0x06, 0x10, + 0x60, 0xBB, 0x83, 0x35, 0xB7, 0x5E, 0x67, 0xDE, 0x47, 0xEC, 0x99, 0x48, + 0xF1, 0xA4, 0xA1, 0x15, 0xFE, 0xAD, 0x8C, 0x62, 0x8E, 0x39, 0x55, 0x4F, + 0x39, 0x16, 0xB9, 0xB1, 0x63, 0x9D, 0xFF, 0xB7 +}; + +static const unsigned char TA426_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA427_DN[] = { + 0x30, 0x7A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA427_RSA_N[] = { + 0xD1, 0x2D, 0x8E, 0xBB, 0xB7, 0x36, 0xEA, 0x6D, 0x37, 0x91, 0x9F, 0x4E, + 0x93, 0xA7, 0x05, 0xE4, 0x29, 0x03, 0x25, 0xCE, 0x1C, 0x82, 0xF7, 0x7C, + 0x99, 0x9F, 0x41, 0x06, 0xCD, 0xED, 0xA3, 0xBA, 0xC0, 0xDB, 0x09, 0x2C, + 0xC1, 0x7C, 0xDF, 0x29, 0x7E, 0x4B, 0x65, 0x2F, 0x93, 0xA7, 0xD4, 0x01, + 0x6B, 0x03, 0x28, 0x18, 0xA3, 0xD8, 0x9D, 0x05, 0xC1, 0x2A, 0xD8, 0x45, + 0xF1, 0x91, 0xDE, 0xDF, 0x3B, 0xD0, 0x80, 0x02, 0x8C, 0xCF, 0x38, 0x0F, + 0xEA, 0xA7, 0x5C, 0x78, 0x11, 0xA4, 0xC1, 0xC8, 0x85, 0x5C, 0x25, 0xD3, + 0xD3, 0xB2, 0xE7, 0x25, 0xCF, 0x11, 0x54, 0x97, 0xAB, 0x35, 0xC0, 0x1E, + 0x76, 0x1C, 0xEF, 0x00, 0x53, 0x9F, 0x39, 0xDC, 0x14, 0xA5, 0x2C, 0x22, + 0x25, 0xB3, 0x72, 0x72, 0xFC, 0x8D, 0xB3, 0xE5, 0x3E, 0x08, 0x1E, 0x14, + 0x2A, 0x37, 0x0B, 0x88, 0x3C, 0xCA, 0xB0, 0xF4, 0xC8, 0xC2, 0xA1, 0xAE, + 0xBC, 0xC1, 0xBE, 0x29, 0x67, 0x55, 0xE2, 0xFC, 0xAD, 0x59, 0x5C, 0xFE, + 0xBD, 0x57, 0x2C, 0xB0, 0x90, 0x8D, 0xC2, 0xED, 0x37, 0xB6, 0x7C, 0x99, + 0x88, 0xB5, 0xD5, 0x03, 0x9A, 0x3D, 0x15, 0x0D, 0x3D, 0x3A, 0xA8, 0xA8, + 0x45, 0xF0, 0x95, 0x4E, 0x25, 0x59, 0x1D, 0xCD, 0x98, 0x69, 0xBB, 0xD3, + 0xCC, 0x32, 0xC9, 0x8D, 0xEF, 0x81, 0xFE, 0xAD, 0x7D, 0x89, 0xBB, 0xBA, + 0x60, 0x13, 0xCA, 0x65, 0x95, 0x67, 0xA0, 0xF3, 0x19, 0xF6, 0x03, 0x56, + 0xD4, 0x6A, 0xD3, 0x27, 0xE2, 0xA1, 0xAD, 0x83, 0xF0, 0x4A, 0x12, 0x22, + 0x77, 0x1C, 0x05, 0x73, 0xE2, 0x19, 0x71, 0x42, 0xC0, 0xEC, 0x75, 0x46, + 0x9A, 0x90, 0x58, 0xE0, 0x6A, 0x8E, 0x2B, 0xA5, 0x46, 0x30, 0x04, 0x8E, + 0x19, 0xB2, 0x17, 0xE3, 0xBE, 0xA9, 0xBA, 0x7F, 0x56, 0xF1, 0x24, 0x03, + 0xD7, 0xB2, 0x21, 0x28, 0x76, 0x0E, 0x36, 0x30, 0x4C, 0x79, 0xD5, 0x41, + 0x9A, 0x9A, 0xA8, 0xB8, 0x35, 0xBA, 0x0C, 0x3A, 0xF2, 0x44, 0x1B, 0x20, + 0x88, 0xF7, 0xC5, 0x25, 0xD7, 0x3D, 0xC6, 0xE3, 0x3E, 0x43, 0xDD, 0x87, + 0xFE, 0xC4, 0xEA, 0xF5, 0x53, 0x3E, 0x4C, 0x65, 0xFF, 0x3B, 0x4A, 0xCB, + 0x78, 0x5A, 0x6B, 0x17, 0x5F, 0x0D, 0xC7, 0xC3, 0x4F, 0x4E, 0x9A, 0x2A, + 0xA2, 0xED, 0x57, 0x4D, 0x22, 0xE2, 0x46, 0x9A, 0x3F, 0x0F, 0x91, 0x34, + 0x24, 0x7D, 0x55, 0xE3, 0x8C, 0x95, 0x37, 0xD3, 0x1A, 0xF0, 0x09, 0x2B, + 0x2C, 0xD2, 0xC9, 0x8D, 0xB4, 0x0D, 0x00, 0xAB, 0x67, 0x29, 0x28, 0xD8, + 0x01, 0xF5, 0x19, 0x04, 0xB6, 0x1D, 0xBE, 0x76, 0xFE, 0x72, 0x5C, 0xC4, + 0x85, 0xCA, 0xD2, 0x80, 0x41, 0xDF, 0x05, 0xA8, 0xA3, 0xD5, 0x84, 0x90, + 0x4F, 0x0B, 0xF3, 0xE0, 0x3F, 0x9B, 0x19, 0xD2, 0x37, 0x89, 0x3F, 0xF2, + 0x7B, 0x52, 0x1C, 0x8C, 0xF6, 0xE1, 0xF7, 0x3C, 0x07, 0x97, 0x8C, 0x0E, + 0xA2, 0x59, 0x81, 0x0C, 0xB2, 0x90, 0x3D, 0xD3, 0xE3, 0x59, 0x46, 0xED, + 0x0F, 0xA9, 0xA7, 0xDE, 0x80, 0x6B, 0x5A, 0xAA, 0x07, 0xB6, 0x19, 0xCB, + 0xBC, 0x57, 0xF3, 0x97, 0x21, 0x7A, 0x0C, 0xB1, 0x2B, 0x74, 0x3E, 0xEB, + 0xDA, 0xA7, 0x67, 0x2D, 0x4C, 0xC4, 0x98, 0x9E, 0x36, 0x09, 0x76, 0x66, + 0x66, 0xFC, 0x1A, 0x3F, 0xEA, 0x48, 0x54, 0x1C, 0xBE, 0x30, 0xBD, 0x80, + 0x50, 0xBF, 0x7C, 0xB5, 0xCE, 0x00, 0xF6, 0x0C, 0x61, 0xD9, 0xE7, 0x24, + 0x03, 0xE0, 0xE3, 0x01, 0x81, 0x0E, 0xBD, 0xD8, 0x85, 0x34, 0x88, 0xBD, + 0xB2, 0x36, 0xA8, 0x7B, 0x5C, 0x08, 0xE5, 0x44, 0x80, 0x8C, 0x6F, 0xF8, + 0x2F, 0xD5, 0x21, 0xCA, 0x1D, 0x1C, 0xD0, 0xFB, 0xC4, 0xB5, 0x87, 0xD1, + 0x3A, 0x4E, 0xC7, 0x76, 0xB5, 0x35, 0x48, 0xB5 +}; + +static const unsigned char TA427_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA428_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA428_EC_Q[] = { + 0x04, 0x4B, 0x36, 0xE9, 0xAE, 0x57, 0x5E, 0xA8, 0x70, 0xD7, 0xD0, 0x8F, + 0x74, 0x62, 0x77, 0xC3, 0x5E, 0x7A, 0xAA, 0xE5, 0xB6, 0xA2, 0xF1, 0x78, + 0xFD, 0x02, 0x7E, 0x57, 0xDD, 0x91, 0x79, 0x9C, 0x6C, 0xB9, 0x52, 0x88, + 0x54, 0xBC, 0x2F, 0x04, 0xBE, 0xB8, 0xCD, 0xF6, 0x10, 0xD1, 0x29, 0xEC, + 0xB5, 0xD0, 0xA0, 0xC3, 0xF0, 0x89, 0x70, 0x19, 0xBB, 0x51, 0x65, 0xC5, + 0x43, 0x9C, 0xC3, 0x9B, 0x63, 0x9D, 0x20, 0x83, 0x3E, 0x06, 0x0B, 0xA6, + 0x42, 0x44, 0x85, 0x11, 0xA7, 0x4A, 0x3A, 0x2D, 0xE9, 0xD6, 0x68, 0x2F, + 0x48, 0x4E, 0x53, 0x2B, 0x07, 0x3F, 0x4D, 0xBD, 0xB9, 0xAC, 0x77, 0x39, + 0x57 +}; + +static const unsigned char TA429_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA429_EC_Q[] = { + 0x04, 0x78, 0x30, 0x81, 0xE8, 0x63, 0x1E, 0xE5, 0xEB, 0x71, 0x51, 0x0F, + 0xF7, 0x07, 0x07, 0xCA, 0x39, 0x99, 0x7C, 0x4E, 0xD5, 0x0F, 0xCC, 0x30, + 0x30, 0x0B, 0x8F, 0x66, 0x93, 0x3E, 0xCF, 0xBD, 0xC5, 0x86, 0xBD, 0xF9, + 0xB1, 0xB7, 0xB4, 0x3E, 0xB4, 0x07, 0xC8, 0xF3, 0x96, 0x31, 0xF3, 0xED, + 0xA4, 0x4F, 0xF8, 0xA3, 0x4E, 0x8D, 0x29, 0x15, 0x58, 0xB8, 0xD5, 0x6F, + 0x7F, 0xEE, 0x6C, 0x22, 0xB5, 0xB0, 0xAF, 0x48, 0x45, 0x0A, 0xBD, 0xA8, + 0x49, 0x94, 0xBF, 0x84, 0x43, 0xB0, 0xDB, 0x84, 0x4A, 0x03, 0x23, 0x19, + 0x67, 0x6A, 0x6F, 0xC1, 0x6E, 0xBC, 0x06, 0x39, 0x37, 0xD1, 0x88, 0x22, + 0xF7 +}; + +static const unsigned char TA430_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA430_RSA_N[] = { + 0xB0, 0x48, 0x65, 0xA3, 0x0D, 0x1D, 0x42, 0xE3, 0x91, 0x6D, 0x9D, 0x84, + 0xA4, 0x61, 0x96, 0x12, 0xC2, 0xED, 0xC3, 0xDA, 0x23, 0x34, 0x19, 0x76, + 0xF6, 0xEA, 0xFD, 0x55, 0x5A, 0xF6, 0x55, 0x01, 0x53, 0x0F, 0xF2, 0xCC, + 0x8C, 0x97, 0x4F, 0xB9, 0x50, 0xCB, 0xB3, 0x01, 0x44, 0x56, 0x96, 0xFD, + 0x9B, 0x28, 0xEC, 0x7B, 0x74, 0x0B, 0xE7, 0x42, 0x6B, 0x55, 0xCE, 0xC9, + 0x61, 0xB2, 0xE8, 0xAD, 0x40, 0x3C, 0xBA, 0xB9, 0x41, 0x0A, 0x05, 0x4F, + 0x1B, 0x26, 0x85, 0x8F, 0x43, 0xB5, 0x40, 0xB5, 0x85, 0xD1, 0xD4, 0x71, + 0xDC, 0x83, 0x41, 0xF3, 0xF6, 0x45, 0xC7, 0x80, 0xA2, 0x84, 0x50, 0x97, + 0x46, 0xCE, 0xA0, 0x0C, 0xC4, 0x60, 0x56, 0x04, 0x1D, 0x07, 0x5B, 0x46, + 0xA5, 0x0E, 0xB2, 0x4B, 0xA4, 0x0E, 0xA5, 0x7C, 0xEE, 0xF8, 0xD4, 0x62, + 0x03, 0xB9, 0x93, 0x6A, 0x8A, 0x14, 0xB8, 0x70, 0xF8, 0x2E, 0x82, 0x46, + 0x38, 0x23, 0x0E, 0x74, 0xC7, 0x6B, 0x41, 0xB7, 0xD0, 0x29, 0xA3, 0x9D, + 0x80, 0xB0, 0x7E, 0x77, 0x93, 0x63, 0x42, 0xFB, 0x34, 0x83, 0x3B, 0x73, + 0xA3, 0x5A, 0x21, 0x36, 0xEB, 0x47, 0xFA, 0x18, 0x17, 0xD9, 0xBA, 0x66, + 0xC2, 0x93, 0xA4, 0x8F, 0xFC, 0x5D, 0xA4, 0xAD, 0xFC, 0x50, 0x6A, 0x95, + 0xAC, 0xBC, 0x24, 0x33, 0xD1, 0xBD, 0x88, 0x7F, 0x86, 0xF5, 0xF5, 0xB2, + 0x73, 0x2A, 0x8F, 0x7C, 0xAF, 0x08, 0xF2, 0x1A, 0x98, 0x3F, 0xA9, 0x81, + 0x65, 0x3F, 0xC1, 0x8C, 0x89, 0xC5, 0x96, 0x30, 0x9A, 0x0A, 0xCF, 0xF4, + 0xD4, 0xC8, 0x34, 0xED, 0x9D, 0x2F, 0xBC, 0x8D, 0x38, 0x86, 0x53, 0xEE, + 0x97, 0x9F, 0xA9, 0xB2, 0x63, 0x94, 0x17, 0x8D, 0x0F, 0xDC, 0x66, 0x2A, + 0x7C, 0x52, 0x51, 0x75, 0xCB, 0x99, 0x8E, 0xE8, 0x3D, 0x5C, 0xBF, 0x9E, + 0x3B, 0x28, 0x8D, 0x83, 0x02, 0x0F, 0xA9, 0x9F, 0x72, 0xE2, 0x2C, 0x2B, + 0xB3, 0xDC, 0x66, 0x97, 0x00, 0x40, 0xD0, 0xA4, 0x54, 0x8E, 0x9B, 0x5D, + 0x7B, 0x45, 0x36, 0x26, 0xD6, 0x72, 0x43, 0xEB, 0xCF, 0xC0, 0xEA, 0x0D, + 0xDC, 0xCE, 0x12, 0xE6, 0x7D, 0x38, 0x9F, 0x05, 0x27, 0xA8, 0x97, 0x3E, + 0xE9, 0x51, 0xC6, 0x6C, 0x05, 0x28, 0xC1, 0x02, 0x0F, 0xE9, 0x18, 0x6D, + 0xEC, 0xBD, 0x9C, 0x06, 0xD4, 0xA7, 0x49, 0xF4, 0x54, 0x05, 0x6B, 0x6C, + 0x30, 0xF1, 0xEB, 0x03, 0xD5, 0xEA, 0x3D, 0x6A, 0x76, 0xC2, 0xCB, 0x1A, + 0x28, 0x49, 0x4D, 0x7F, 0x64, 0xE0, 0xFA, 0x2B, 0xDA, 0x73, 0x83, 0x81, + 0xFF, 0x91, 0x03, 0xBD, 0x94, 0xBB, 0xE4, 0xB8, 0x8E, 0x9C, 0x32, 0x63, + 0xCD, 0x9F, 0xBB, 0x68, 0x81, 0xB1, 0x84, 0x5B, 0xAF, 0x36, 0xBF, 0x77, + 0xEE, 0x1D, 0x7F, 0xF7, 0x49, 0x9B, 0x52, 0xEC, 0xD2, 0x77, 0x5A, 0x7D, + 0x91, 0x9D, 0x4D, 0xC2, 0x39, 0x2D, 0xE4, 0xBA, 0x82, 0xF8, 0x6F, 0xF2, + 0x4E, 0x1E, 0x0F, 0x4E, 0xE6, 0x3F, 0x59, 0xA5, 0x23, 0xDC, 0x3D, 0x87, + 0xA8, 0x28, 0x58, 0x28, 0xD1, 0xF1, 0x1B, 0x36, 0xDB, 0x4F, 0xC4, 0xFF, + 0xE1, 0x8C, 0x5B, 0x72, 0x8C, 0xC7, 0x26, 0x03, 0x27, 0xA3, 0x39, 0x0A, + 0x01, 0xAA, 0xC0, 0xB2, 0x31, 0x60, 0x83, 0x22, 0xA1, 0x4F, 0x12, 0x09, + 0x01, 0x11, 0xAF, 0x34, 0xD4, 0xCF, 0xD7, 0xAE, 0x62, 0xD3, 0x05, 0x07, + 0xB4, 0x31, 0x75, 0xE0, 0x0D, 0x6D, 0x57, 0x4F, 0x69, 0x87, 0xF9, 0x57, + 0xA9, 0xBA, 0x15, 0xF6, 0xC8, 0x52, 0x6D, 0xA1, 0xCB, 0x9C, 0x1F, 0xE5, + 0xFC, 0x78, 0xA8, 0x35, 0x9A, 0x9F, 0x41, 0x14, 0xCE, 0xA5, 0xB4, 0xCE, + 0x94, 0x08, 0x1C, 0x09, 0xAD, 0x56, 0xE5, 0xDA, 0xB6, 0x49, 0x9A, 0x4A, + 0xEA, 0x63, 0x18, 0x53, 0x9C, 0x2C, 0x2E, 0xC3 +}; + +static const unsigned char TA430_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA431_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA431_RSA_N[] = { + 0xE1, 0xFA, 0x0E, 0xFB, 0x68, 0x00, 0x12, 0xC8, 0x4D, 0xD5, 0xAC, 0x22, + 0xC4, 0x35, 0x01, 0x3B, 0xC5, 0x54, 0xE5, 0x59, 0x76, 0x63, 0xA5, 0x7F, + 0xEB, 0xC1, 0xC4, 0x6A, 0x98, 0xBD, 0x32, 0x8D, 0x17, 0x80, 0xEB, 0x5D, + 0xBA, 0xD1, 0x62, 0x3D, 0x25, 0x23, 0x19, 0x35, 0x14, 0xE9, 0x7F, 0x89, + 0xA7, 0x1B, 0x62, 0x3C, 0xD6, 0x50, 0xE7, 0x34, 0x95, 0x03, 0x32, 0xB1, + 0xB4, 0x93, 0x22, 0x3D, 0xA7, 0xE2, 0xB1, 0xED, 0xE6, 0x7B, 0x4E, 0x2E, + 0x87, 0x9B, 0x0D, 0x33, 0x75, 0x0A, 0xDE, 0xAA, 0x35, 0xE7, 0x7E, 0xE5, + 0x36, 0x98, 0xA2, 0xAE, 0x25, 0x9E, 0x95, 0xB3, 0x32, 0x96, 0xA4, 0x2B, + 0x58, 0x1E, 0xEF, 0x3F, 0xFE, 0x62, 0x34, 0x48, 0x51, 0xD1, 0xB4, 0x8D, + 0x42, 0xAD, 0x60, 0xDA, 0x49, 0x6A, 0x95, 0x70, 0xDD, 0xD2, 0x00, 0xE2, + 0xCC, 0x57, 0x63, 0x02, 0x7B, 0x96, 0xDD, 0x49, 0x97, 0x5B, 0x92, 0x4E, + 0x95, 0xD3, 0xF9, 0xCB, 0x29, 0x1F, 0x18, 0x4A, 0xF8, 0x01, 0x2A, 0xD2, + 0x63, 0x09, 0x6E, 0x24, 0xE9, 0x89, 0xD2, 0xE5, 0xC7, 0x22, 0x4C, 0xDC, + 0x73, 0x86, 0x47, 0x00, 0xAA, 0x0D, 0x88, 0x8E, 0xAE, 0x85, 0x7D, 0x4A, + 0xE9, 0xBB, 0x33, 0x4F, 0x0E, 0x52, 0x70, 0x9D, 0x95, 0xE3, 0x7C, 0x6D, + 0x96, 0x5B, 0x2D, 0x3D, 0x5F, 0xA1, 0x83, 0x46, 0x5D, 0xB6, 0xE3, 0x25, + 0xB8, 0x7C, 0xA7, 0x19, 0x80, 0x1C, 0xEA, 0x65, 0x43, 0xDC, 0x91, 0x79, + 0x36, 0x2C, 0x74, 0x7C, 0xF2, 0x67, 0x06, 0xC9, 0x89, 0xC9, 0xDB, 0xBF, + 0xDA, 0x68, 0xBF, 0x23, 0xED, 0xDC, 0x6B, 0xAD, 0x28, 0x83, 0x79, 0x2F, + 0xEC, 0x38, 0xA5, 0x0D, 0x37, 0x01, 0x67, 0x27, 0x9A, 0xE9, 0x33, 0xD9, + 0x33, 0x5F, 0x37, 0xA1, 0xC5, 0xF0, 0xAB, 0x3D, 0xFA, 0x78, 0xB0, 0xE7, + 0x2C, 0x9F, 0xF6, 0x3E, 0x9F, 0x60, 0xE0, 0xEF, 0x48, 0xE9, 0x90, 0x45, + 0x1E, 0x05, 0x51, 0x78, 0x1A, 0x2C, 0x12, 0x2C, 0x5C, 0x28, 0xAC, 0x0D, + 0xA2, 0x23, 0x9E, 0x34, 0x8F, 0x05, 0xE6, 0xA2, 0x33, 0xCE, 0x11, 0x77, + 0x13, 0xD4, 0x0E, 0xA4, 0x1E, 0x42, 0x1F, 0x86, 0xCD, 0x70, 0xFE, 0xD9, + 0x2E, 0x15, 0x3D, 0x1D, 0xBB, 0xB8, 0xF2, 0x53, 0x57, 0xDB, 0xCC, 0xC6, + 0x74, 0x29, 0x9C, 0x18, 0xB3, 0x36, 0x75, 0x38, 0x2E, 0x0F, 0x54, 0xA1, + 0xF8, 0x92, 0x1F, 0x89, 0x96, 0x4F, 0xBB, 0xD4, 0xEE, 0x9D, 0xE9, 0x3B, + 0x36, 0x42, 0xB5, 0x0A, 0x3B, 0x2A, 0xD4, 0x64, 0x79, 0x36, 0x10, 0xE1, + 0xF9, 0x91, 0x03, 0x2B, 0x7B, 0x20, 0x54, 0xCD, 0x0D, 0x19, 0x1A, 0xC8, + 0x41, 0x32, 0x34, 0xD1, 0xB0, 0x99, 0xE1, 0x90, 0x1E, 0x01, 0x40, 0x36, + 0xB5, 0xB7, 0xFA, 0xA9, 0xE5, 0x77, 0x75, 0xA4, 0x22, 0x81, 0x5D, 0xB0, + 0x8B, 0xE4, 0x27, 0x12, 0x0F, 0x54, 0x88, 0xC6, 0xDB, 0x85, 0x74, 0xE6, + 0xB7, 0xC0, 0xD7, 0xA6, 0x29, 0xFA, 0xDB, 0xDE, 0xF3, 0x93, 0x97, 0x27, + 0x04, 0x55, 0x2F, 0x0A, 0x6F, 0x37, 0xC5, 0x3D, 0x13, 0xAF, 0x0A, 0x00, + 0xA9, 0x2C, 0x8B, 0x1C, 0x81, 0x28, 0xD7, 0xEF, 0x86, 0x31, 0xA9, 0xAE, + 0xF2, 0x6E, 0xB8, 0xCA, 0x6A, 0x2C, 0x54, 0x47, 0xD8, 0x2A, 0x88, 0x2E, + 0xAF, 0xC1, 0x07, 0x10, 0x78, 0xAC, 0x11, 0xA2, 0x2F, 0x42, 0xF0, 0x37, + 0xC5, 0xF2, 0xB8, 0x56, 0xDD, 0x0E, 0x62, 0x2D, 0xCE, 0x2D, 0x56, 0x7E, + 0x55, 0xF2, 0xA7, 0x44, 0xF6, 0x2B, 0x32, 0xF4, 0x23, 0xA8, 0x47, 0xE8, + 0xD4, 0x2A, 0x01, 0x78, 0xCF, 0x6A, 0xC3, 0x37, 0xA8, 0x9E, 0x65, 0xD2, + 0x2C, 0xE5, 0xFA, 0xBA, 0x33, 0xC1, 0x06, 0x44, 0xF6, 0xE6, 0xCF, 0xA5, + 0x0D, 0xA7, 0x66, 0x08, 0x34, 0x8A, 0x2C, 0xF3 +}; + +static const unsigned char TA431_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA432_DN[] = { + 0x30, 0x7B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, 0x61, + 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x53, 0x61, 0x6C, 0x66, 0x6F, + 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x11, 0x43, 0x6F, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x43, 0x41, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x18, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73 +}; + +static const unsigned char TA432_RSA_N[] = { + 0xBE, 0x40, 0x9D, 0xF4, 0x6E, 0xE1, 0xEA, 0x76, 0x87, 0x1C, 0x4D, 0x45, + 0x44, 0x8E, 0xBE, 0x46, 0xC8, 0x83, 0x06, 0x9D, 0xC1, 0x2A, 0xFE, 0x18, + 0x1F, 0x8E, 0xE4, 0x02, 0xFA, 0xF3, 0xAB, 0x5D, 0x50, 0x8A, 0x16, 0x31, + 0x0B, 0x9A, 0x06, 0xD0, 0xC5, 0x70, 0x22, 0xCD, 0x49, 0x2D, 0x54, 0x63, + 0xCC, 0xB6, 0x6E, 0x68, 0x46, 0x0B, 0x53, 0xEA, 0xCB, 0x4C, 0x24, 0xC0, + 0xBC, 0x72, 0x4E, 0xEA, 0xF1, 0x15, 0xAE, 0xF4, 0x54, 0x9A, 0x12, 0x0A, + 0xC3, 0x7A, 0xB2, 0x33, 0x60, 0xE2, 0xDA, 0x89, 0x55, 0xF3, 0x22, 0x58, + 0xF3, 0xDE, 0xDC, 0xCF, 0xEF, 0x83, 0x86, 0xA2, 0x8C, 0x94, 0x4F, 0x9F, + 0x68, 0xF2, 0x98, 0x90, 0x46, 0x84, 0x27, 0xC7, 0x76, 0xBF, 0xE3, 0xCC, + 0x35, 0x2C, 0x8B, 0x5E, 0x07, 0x64, 0x65, 0x82, 0xC0, 0x48, 0xB0, 0xA8, + 0x91, 0xF9, 0x61, 0x9F, 0x76, 0x20, 0x50, 0xA8, 0x91, 0xC7, 0x66, 0xB5, + 0xEB, 0x78, 0x62, 0x03, 0x56, 0xF0, 0x8A, 0x1A, 0x13, 0xEA, 0x31, 0xA3, + 0x1E, 0xA0, 0x99, 0xFD, 0x38, 0xF6, 0xF6, 0x27, 0x32, 0x58, 0x6F, 0x07, + 0xF5, 0x6B, 0xB8, 0xFB, 0x14, 0x2B, 0xAF, 0xB7, 0xAA, 0xCC, 0xD6, 0x63, + 0x5F, 0x73, 0x8C, 0xDA, 0x05, 0x99, 0xA8, 0x38, 0xA8, 0xCB, 0x17, 0x78, + 0x36, 0x51, 0xAC, 0xE9, 0x9E, 0xF4, 0x78, 0x3A, 0x8D, 0xCF, 0x0F, 0xD9, + 0x42, 0xE2, 0x98, 0x0C, 0xAB, 0x2F, 0x9F, 0x0E, 0x01, 0xDE, 0xEF, 0x9F, + 0x99, 0x49, 0xF1, 0x2D, 0xDF, 0xAC, 0x74, 0x4D, 0x1B, 0x98, 0xB5, 0x47, + 0xC5, 0xE5, 0x29, 0xD1, 0xF9, 0x90, 0x18, 0xC7, 0x62, 0x9C, 0xBE, 0x83, + 0xC7, 0x26, 0x7B, 0x3E, 0x8A, 0x25, 0xC7, 0xC0, 0xDD, 0x9D, 0xE6, 0x35, + 0x68, 0x10, 0x20, 0x9D, 0x8F, 0xD8, 0xDE, 0xD2, 0xC3, 0x84, 0x9C, 0x0D, + 0x5E, 0xE8, 0x2F, 0xC9 +}; + +static const unsigned char TA432_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA433_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA433_EC_Q[] = { + 0x04, 0xC6, 0xCB, 0xC7, 0x28, 0xD1, 0xFB, 0x84, 0xF5, 0x9A, 0xEF, 0x42, + 0x14, 0x20, 0xE1, 0x43, 0x6B, 0x6E, 0x75, 0xAD, 0xFC, 0x2B, 0x03, 0x84, + 0xD4, 0x76, 0x93, 0x25, 0xD7, 0x59, 0x3B, 0x41, 0x65, 0x6B, 0x1E, 0xE6, + 0x34, 0x2A, 0xBB, 0x74, 0xF6, 0x12, 0xCE, 0xE8, 0x6D, 0xE7, 0xAB, 0xE4, + 0x3C, 0x4E, 0x3F, 0x44, 0x08, 0x8B, 0xCD, 0x16, 0x71, 0xCB, 0xBF, 0x92, + 0x99, 0xF4, 0xA4, 0xD7, 0x3C, 0x50, 0x54, 0x52, 0x90, 0x85, 0x83, 0x78, + 0x94, 0x67, 0x67, 0xA3, 0x1C, 0x09, 0x19, 0x3D, 0x75, 0x34, 0x85, 0xDE, + 0xED, 0x60, 0x7D, 0xC7, 0x0C, 0xB4, 0x41, 0x52, 0xB9, 0x6E, 0xE5, 0xEE, + 0x42 +}; + +static const unsigned char TA434_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA434_RSA_N[] = { + 0xAE, 0xFF, 0x09, 0x59, 0x91, 0x80, 0x0A, 0x4A, 0x68, 0xE6, 0x24, 0x3F, + 0xB8, 0xA7, 0xE4, 0xC8, 0x3A, 0x0A, 0x3A, 0x16, 0xCD, 0xC9, 0x23, 0x61, + 0xA0, 0x93, 0x71, 0xF2, 0xAB, 0x8B, 0x73, 0x8F, 0xA0, 0x67, 0x65, 0x60, + 0xD2, 0x54, 0x6B, 0x63, 0x51, 0x6F, 0x49, 0x33, 0xE0, 0x72, 0x07, 0x13, + 0x7D, 0x38, 0xCD, 0x06, 0x92, 0x07, 0x29, 0x52, 0x6B, 0x4E, 0x77, 0x6C, + 0x04, 0xD3, 0x95, 0xFA, 0xDD, 0x4C, 0x8C, 0xD9, 0x5D, 0xC1, 0x61, 0x7D, + 0x4B, 0xE7, 0x28, 0xB3, 0x44, 0x81, 0x7B, 0x51, 0xAF, 0xDD, 0x33, 0xB1, + 0x68, 0x7C, 0xD6, 0x4E, 0x4C, 0xFE, 0x2B, 0x68, 0xB9, 0xCA, 0x66, 0x69, + 0xC4, 0xEC, 0x5E, 0x57, 0x7F, 0xF7, 0x0D, 0xC7, 0x9C, 0x36, 0x36, 0xE5, + 0x07, 0x60, 0xAC, 0xC0, 0x4C, 0xEA, 0x08, 0x6C, 0xEF, 0x06, 0x7C, 0x4F, + 0x5B, 0x28, 0x7A, 0x08, 0xFC, 0x93, 0x5D, 0x9B, 0xF6, 0x9C, 0xB4, 0x8B, + 0x86, 0xBA, 0x21, 0xB9, 0xF4, 0xF0, 0xE8, 0x59, 0x5A, 0x28, 0xA1, 0x34, + 0x84, 0x1A, 0x25, 0x91, 0xB6, 0xB5, 0x8F, 0xEF, 0xB2, 0xF9, 0x80, 0xFA, + 0xF9, 0x3D, 0x3C, 0x11, 0x72, 0xD8, 0xE3, 0x2F, 0x86, 0x76, 0xC5, 0x79, + 0x2C, 0xC1, 0xA9, 0x90, 0x93, 0x46, 0x98, 0x67, 0xCB, 0x83, 0x6A, 0xA0, + 0x50, 0x23, 0xA7, 0x3B, 0xF6, 0x81, 0x39, 0xE0, 0xED, 0xF0, 0xB9, 0xBF, + 0x65, 0xF1, 0xD8, 0xCB, 0x7A, 0xFB, 0xEF, 0x73, 0x03, 0xCE, 0x00, 0xF4, + 0x7D, 0xD7, 0xE0, 0x5D, 0x3B, 0x66, 0xB8, 0xDC, 0x8E, 0xBA, 0x83, 0xCB, + 0x87, 0x76, 0x03, 0xFC, 0x25, 0xD9, 0xE7, 0x23, 0x6F, 0x06, 0xFD, 0x67, + 0xF3, 0xE0, 0xFF, 0x84, 0xBC, 0x47, 0xBF, 0xB5, 0x16, 0x18, 0x46, 0x69, + 0x14, 0xCC, 0x05, 0xF7, 0xDB, 0xD3, 0x49, 0xAC, 0x6B, 0xCC, 0xAB, 0xE4, + 0xB5, 0x0B, 0x43, 0x24, 0x5E, 0x4B, 0x6B, 0x4D, 0x67, 0xDF, 0xD6, 0xB5, + 0x3E, 0x4F, 0x78, 0x1F, 0x94, 0x71, 0x24, 0xEA, 0xDE, 0x70, 0xFC, 0xF1, + 0x93, 0xFE, 0x9E, 0x93, 0x5A, 0xE4, 0x94, 0x5A, 0x97, 0x54, 0x0C, 0x35, + 0x7B, 0x5F, 0x6C, 0xEE, 0x00, 0x1F, 0x24, 0xEC, 0x03, 0xBA, 0x02, 0xF5, + 0x76, 0xF4, 0x9F, 0xD4, 0x9A, 0xED, 0x85, 0x2C, 0x38, 0x22, 0x2F, 0xC7, + 0xD8, 0x2F, 0x76, 0x11, 0x4F, 0xFD, 0x6C, 0x5C, 0xE8, 0xF5, 0x8E, 0x27, + 0x87, 0x7F, 0x19, 0x4A, 0x21, 0x47, 0x90, 0x1D, 0x79, 0x8D, 0x1C, 0x5B, + 0xF8, 0xCF, 0x4A, 0x85, 0xE4, 0xED, 0xB3, 0x5B, 0x8D, 0xBE, 0xC4, 0x64, + 0x28, 0x5D, 0x41, 0xC4, 0x6E, 0xAC, 0x38, 0x5A, 0x4F, 0x23, 0x74, 0x74, + 0xA9, 0x12, 0xC3, 0xF6, 0xD2, 0xB9, 0x11, 0x15, 0x33, 0x07, 0x91, 0xD8, + 0x3B, 0x37, 0x3A, 0x63, 0x30, 0x06, 0xD1, 0xC5, 0x22, 0x36, 0x28, 0x62, + 0x23, 0x10, 0xE0, 0x46, 0xCC, 0x97, 0xAC, 0xD6, 0x2B, 0x5D, 0x64, 0x24, + 0xD5, 0xEE, 0x1C, 0x0E, 0xDE, 0xFB, 0x08, 0x5A, 0x75, 0x2A, 0xF6, 0x63, + 0x6D, 0xCE, 0x0B, 0x42, 0xBE, 0xD1, 0xBA, 0x70, 0x1C, 0x9C, 0x21, 0xE5, + 0x0F, 0x31, 0x69, 0x17, 0xD7, 0xFC, 0x0A, 0xB4, 0xDE, 0xED, 0x80, 0x9C, + 0xCB, 0x92, 0xB4, 0x8B, 0xF5, 0xDE, 0x59, 0xA2, 0x58, 0x09, 0xA5, 0x63, + 0x47, 0x0B, 0xE1, 0x41, 0x32, 0x34, 0x41, 0xD9, 0x9A, 0xB1, 0xD9, 0xA8, + 0xB0, 0x1B, 0x5A, 0xDE, 0x0D, 0x0D, 0xF4, 0xE2, 0xB2, 0x5D, 0x35, 0x80, + 0xB9, 0x81, 0xD4, 0x84, 0x69, 0x91, 0x02, 0xCB, 0x75, 0xD0, 0x8D, 0xC5, + 0xB5, 0x3D, 0x09, 0x91, 0x09, 0x8F, 0x14, 0xA1, 0x14, 0x74, 0x79, 0x3E, + 0xD6, 0xC9, 0x15, 0x1D, 0xA4, 0x59, 0x59, 0x22, 0xDC, 0xF6, 0x8A, 0x45, + 0x3D, 0x3C, 0x12, 0xD6, 0x3E, 0x5D, 0x32, 0x2F +}; + +static const unsigned char TA434_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA435_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA435_EC_Q[] = { + 0x04, 0xF1, 0x0B, 0xDD, 0x86, 0x43, 0x20, 0x19, 0xDF, 0x97, 0x85, 0xE8, + 0x22, 0x4A, 0x9B, 0xCF, 0x9D, 0x98, 0xBF, 0xB4, 0x05, 0x26, 0xC9, 0xCB, + 0xE3, 0xA6, 0xD2, 0x8F, 0xC5, 0x9E, 0x78, 0x7B, 0x31, 0x89, 0xA9, 0x89, + 0xAD, 0x27, 0x3C, 0x65, 0x10, 0x82, 0xFC, 0xDF, 0xC3, 0x9D, 0x4E, 0xF0, + 0x33, 0x23, 0xC4, 0xD2, 0x32, 0xF5, 0x1C, 0xB0, 0xDF, 0x33, 0x17, 0x5D, + 0xC5, 0xF0, 0xB1, 0x8A, 0xF9, 0xEF, 0xB9, 0xB7, 0x14, 0xCA, 0x29, 0x4A, + 0xC2, 0x0F, 0xA9, 0x7F, 0x75, 0x65, 0x49, 0x2A, 0x30, 0x67, 0xF4, 0x64, + 0xF7, 0xD6, 0x1A, 0x77, 0xDA, 0xC3, 0xC2, 0x97, 0x61, 0x42, 0x7B, 0x49, + 0xAD +}; + +static const unsigned char TA436_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA436_RSA_N[] = { + 0xD8, 0x8E, 0xA3, 0x89, 0x80, 0x0B, 0xB2, 0x57, 0x52, 0xDC, 0xA9, 0x53, + 0x4C, 0x37, 0xB9, 0x7F, 0x63, 0x17, 0x13, 0xEF, 0xA7, 0x5B, 0x23, 0x5B, + 0x69, 0x75, 0xB0, 0x99, 0x0A, 0x17, 0xC1, 0x8B, 0xC4, 0xDB, 0xA8, 0xE0, + 0xCC, 0x31, 0xBA, 0xC2, 0xF2, 0xCD, 0x5D, 0xE9, 0xB7, 0xF8, 0x1D, 0xAF, + 0x6A, 0xC4, 0x95, 0x87, 0xD7, 0x47, 0xC9, 0x95, 0xD8, 0x82, 0x04, 0x50, + 0x3D, 0x81, 0x08, 0xFF, 0xE4, 0x3D, 0xB3, 0xB1, 0xD6, 0xC5, 0xB2, 0xFD, + 0x88, 0x09, 0xDB, 0x9C, 0x84, 0xEC, 0x25, 0x17, 0x14, 0x87, 0x7F, 0x30, + 0x78, 0x9B, 0x6A, 0x58, 0xC9, 0xB6, 0x73, 0x28, 0x3C, 0x34, 0xF7, 0x99, + 0xF7, 0x7F, 0xD3, 0xA6, 0xF8, 0x1C, 0x45, 0x7C, 0xAD, 0x2C, 0x8C, 0x94, + 0x3F, 0xD8, 0x67, 0x10, 0x53, 0x7E, 0x22, 0xCD, 0x4E, 0x25, 0x51, 0xF0, + 0x25, 0x24, 0x35, 0x11, 0x5E, 0x10, 0xC6, 0xEC, 0x87, 0x66, 0x89, 0x81, + 0x68, 0xBA, 0xCC, 0x2B, 0x9D, 0x47, 0x73, 0x1F, 0xBD, 0xCD, 0x91, 0xA4, + 0x72, 0x6A, 0x9C, 0xA2, 0x1B, 0x18, 0xA0, 0x6F, 0xEC, 0x50, 0xF4, 0x7D, + 0x40, 0xC2, 0xA8, 0x30, 0xCF, 0xBD, 0x73, 0xC8, 0x13, 0x2B, 0x10, 0x13, + 0x1E, 0x8B, 0x9A, 0xA8, 0x3A, 0x94, 0x73, 0xD3, 0x18, 0x69, 0x0A, 0x4A, + 0xFF, 0xC1, 0x01, 0x03, 0xFF, 0x79, 0x7F, 0xB5, 0x48, 0x7F, 0x7B, 0xEE, + 0xE8, 0x29, 0x6F, 0x36, 0x4C, 0x95, 0x61, 0x86, 0xD8, 0xF9, 0xA2, 0x73, + 0x8A, 0xEE, 0xAE, 0x2F, 0x96, 0xEE, 0x68, 0xCD, 0x3D, 0x4D, 0x28, 0x42, + 0xF9, 0x45, 0x2B, 0x32, 0x1B, 0x46, 0x55, 0x16, 0x6A, 0xA6, 0x4B, 0x29, + 0xF9, 0xBB, 0x95, 0x56, 0xBF, 0x46, 0x1D, 0xEC, 0x1D, 0x93, 0x1D, 0xC0, + 0x65, 0xB2, 0x1F, 0xA1, 0x43, 0xAE, 0x56, 0x9E, 0xA0, 0xB1, 0x8F, 0x6B, + 0x12, 0xB7, 0x60, 0x6D, 0x78, 0x0B, 0xCA, 0x8A, 0x5C, 0xED, 0x1E, 0x96, + 0x0E, 0x83, 0xA6, 0x48, 0x95, 0x8D, 0x3B, 0xA3, 0x21, 0xC4, 0xAE, 0x58, + 0xC6, 0x00, 0xB2, 0x84, 0xB4, 0x23, 0xA4, 0x96, 0x86, 0x35, 0xB8, 0xD8, + 0x9E, 0xD8, 0xAC, 0x34, 0x49, 0x98, 0x63, 0x95, 0xC5, 0xCB, 0x6D, 0x48, + 0x47, 0xE2, 0xF2, 0x2E, 0x18, 0x1E, 0xD0, 0x31, 0xAB, 0xDD, 0x74, 0xEC, + 0xF9, 0xDC, 0x8C, 0xB8, 0x1C, 0x8E, 0x68, 0x23, 0xBA, 0xD0, 0xF3, 0x50, + 0xDC, 0xCF, 0x65, 0x8F, 0x73, 0x3A, 0x32, 0xC7, 0x7C, 0xFE, 0xCA, 0x82, + 0x22, 0x4F, 0xBE, 0x8E, 0x62, 0x47, 0x66, 0xE5, 0xCD, 0x87, 0xE2, 0xE8, + 0xD5, 0x0F, 0x18, 0x9F, 0xE5, 0x04, 0x72, 0x4B, 0x46, 0x3C, 0x10, 0xF2, + 0x44, 0xC2, 0x64, 0x56, 0x71, 0x4E, 0x75, 0xE8, 0x9C, 0xC9, 0x26, 0x74, + 0xC5, 0x7D, 0x59, 0xD1, 0x0A, 0x5B, 0x0F, 0x6D, 0xFE, 0x9E, 0x75, 0x1C, + 0x18, 0xC6, 0x1A, 0x3A, 0x7C, 0xD8, 0x0D, 0x04, 0xCC, 0xCD, 0xB7, 0x45, + 0x65, 0x7A, 0xB1, 0x8F, 0xB8, 0xAE, 0x84, 0x48, 0x3E, 0xB3, 0x7A, 0x4D, + 0xA8, 0x03, 0xE2, 0xE2, 0x7E, 0x01, 0x16, 0x59, 0x68, 0x18, 0x43, 0x33, + 0xB0, 0xD2, 0xDC, 0xB0, 0x1A, 0x43, 0x35, 0xEE, 0xA5, 0xDA, 0xA9, 0x46, + 0x5C, 0xAE, 0x86, 0x81, 0x41, 0x01, 0x4A, 0x74, 0x26, 0xEC, 0x9F, 0x06, + 0xBF, 0xC2, 0x05, 0x37, 0x64, 0x75, 0x78, 0x29, 0x68, 0xFD, 0xC5, 0xF5, + 0xEB, 0xFE, 0x47, 0xF9, 0xE4, 0x85, 0xB0, 0xE1, 0x7B, 0x31, 0x9D, 0xA6, + 0x7F, 0x72, 0xA3, 0xB9, 0xC4, 0x2C, 0x2E, 0xCC, 0x99, 0x57, 0x0E, 0x21, + 0x0C, 0x45, 0x01, 0x94, 0x65, 0xEB, 0x65, 0x09, 0xC6, 0x63, 0x22, 0x0B, + 0x33, 0x49, 0x92, 0x48, 0x3C, 0xFC, 0xCD, 0xCE, 0xB0, 0x3E, 0x8E, 0x9E, + 0x8B, 0xF8, 0xFE, 0x49, 0xC5, 0x35, 0x72, 0x47 +}; + +static const unsigned char TA436_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA437_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x1E, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA437_RSA_N[] = { + 0xD3, 0xB2, 0x4A, 0xCF, 0x7A, 0x47, 0xEF, 0x75, 0x9B, 0x23, 0xFA, 0x3A, + 0x2F, 0xD6, 0x50, 0x45, 0x89, 0x35, 0x3A, 0xC6, 0x6B, 0xDB, 0xFE, 0xDB, + 0x00, 0x68, 0xA8, 0xE0, 0x03, 0x11, 0x1D, 0x37, 0x50, 0x08, 0x9F, 0x4D, + 0x4A, 0x68, 0x94, 0x35, 0xB3, 0x53, 0xD1, 0x94, 0x63, 0xA7, 0x20, 0x56, + 0xAF, 0xDE, 0x51, 0x78, 0xEC, 0x2A, 0x3D, 0xF3, 0x48, 0x48, 0x50, 0x3E, + 0x0A, 0xDF, 0x46, 0x55, 0x8B, 0x27, 0x6D, 0xC3, 0x10, 0x4D, 0x0D, 0x91, + 0x52, 0x43, 0xD8, 0x87, 0xE0, 0x5D, 0x4E, 0x36, 0xB5, 0x21, 0xCA, 0x5F, + 0x39, 0x40, 0x04, 0x5F, 0x5B, 0x7E, 0xCC, 0xA3, 0xC6, 0x2B, 0xA9, 0x40, + 0x1E, 0xD9, 0x36, 0x84, 0xD6, 0x48, 0xF3, 0x92, 0x1E, 0x34, 0x46, 0x20, + 0x24, 0xC1, 0xA4, 0x51, 0x8E, 0x4A, 0x1A, 0xEF, 0x50, 0x3F, 0x69, 0x5D, + 0x19, 0x7F, 0x45, 0xC3, 0xC7, 0x01, 0x8F, 0x51, 0xC9, 0x23, 0xE8, 0x72, + 0xAE, 0xB4, 0xBC, 0x56, 0x09, 0x7F, 0x12, 0xCB, 0x1C, 0xB1, 0xAF, 0x29, + 0x90, 0x0A, 0xC9, 0x55, 0xCC, 0x0F, 0xD3, 0xB4, 0x1A, 0xED, 0x47, 0x35, + 0x5A, 0x4A, 0xED, 0x9C, 0x73, 0x04, 0x21, 0xD0, 0xAA, 0xBD, 0x0C, 0x13, + 0xB5, 0x00, 0xCA, 0x26, 0x6C, 0xC4, 0x6B, 0x0C, 0x94, 0x5A, 0x95, 0x94, + 0xDA, 0x50, 0x9A, 0xF1, 0xFF, 0xA5, 0x2B, 0x66, 0x31, 0xA4, 0xC9, 0x38, + 0xA0, 0xDF, 0x1D, 0x1F, 0xB8, 0x09, 0x2E, 0xF3, 0xA7, 0xE8, 0x67, 0x52, + 0xAB, 0x95, 0x1F, 0xE0, 0x46, 0x3E, 0xD8, 0xA4, 0xC3, 0xCA, 0x5A, 0xC5, + 0x31, 0x80, 0xE8, 0x48, 0x9A, 0x9F, 0x94, 0x69, 0xFE, 0x19, 0xDD, 0xD8, + 0x73, 0x7C, 0x81, 0xCA, 0x96, 0xDE, 0x8E, 0xED, 0xB3, 0x32, 0x05, 0x65, + 0x84, 0x34, 0xE6, 0xE6, 0xFD, 0x57, 0x10, 0xB5, 0x5F, 0x76, 0xBF, 0x2F, + 0xB0, 0x10, 0x0D, 0xC5 +}; + +static const unsigned char TA437_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA438_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x21, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x45, 0x56, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA438_RSA_N[] = { + 0x99, 0xF1, 0x84, 0x34, 0x70, 0xBA, 0x2F, 0xB7, 0x30, 0xA0, 0x8E, 0xBD, + 0x7C, 0x04, 0xCF, 0xBE, 0x62, 0xBC, 0x99, 0xFD, 0x82, 0x97, 0xD2, 0x7A, + 0x0A, 0x67, 0x96, 0x38, 0x09, 0xF6, 0x10, 0x4E, 0x95, 0x22, 0x73, 0x99, + 0x8D, 0xDA, 0x15, 0x2D, 0xE7, 0x05, 0xFC, 0x19, 0x73, 0x22, 0xB7, 0x8E, + 0x98, 0x00, 0xBC, 0x3C, 0x3D, 0xAC, 0xA1, 0x6C, 0xFB, 0xD6, 0x79, 0x25, + 0x4B, 0xAD, 0xF0, 0xCC, 0x64, 0xDA, 0x88, 0x3E, 0x29, 0xB8, 0x0F, 0x09, + 0xD3, 0x34, 0xDD, 0x33, 0xF5, 0x62, 0xD1, 0xE1, 0xCD, 0x19, 0xE9, 0xEE, + 0x18, 0x4F, 0x4C, 0x58, 0xAE, 0xE2, 0x1E, 0xD6, 0x0C, 0x5B, 0x15, 0x5A, + 0xD8, 0x3A, 0xB8, 0xC4, 0x18, 0x64, 0x1E, 0xE3, 0x33, 0xB2, 0xB5, 0x89, + 0x77, 0x4E, 0x0C, 0xBF, 0xD9, 0x94, 0x6B, 0x13, 0x97, 0x6F, 0x12, 0xA3, + 0xFE, 0x99, 0xA9, 0x04, 0xCC, 0x15, 0xEC, 0x60, 0x68, 0x36, 0xED, 0x08, + 0x7B, 0xB7, 0xF5, 0xBF, 0x93, 0xED, 0x66, 0x31, 0x83, 0x8C, 0xC6, 0x71, + 0x34, 0x87, 0x4E, 0x17, 0xEA, 0xAF, 0x8B, 0x91, 0x8D, 0x1C, 0x56, 0x41, + 0xAE, 0x22, 0x37, 0x5E, 0x37, 0xF2, 0x1D, 0xD9, 0xD1, 0x2D, 0x0D, 0x2F, + 0x69, 0x51, 0xA7, 0xBE, 0x66, 0xA6, 0x8A, 0x3A, 0x2A, 0xBD, 0xC7, 0x1A, + 0xB1, 0xE1, 0x14, 0xF0, 0xBE, 0x3A, 0x1D, 0xB9, 0xCF, 0x5B, 0xB1, 0x6A, + 0xFE, 0xB4, 0xB1, 0x46, 0x20, 0xA2, 0xFB, 0x1E, 0x3B, 0x70, 0xEF, 0x93, + 0x98, 0x7D, 0x8C, 0x73, 0x96, 0xF2, 0xC5, 0xEF, 0x85, 0x70, 0xAD, 0x29, + 0x26, 0xFC, 0x1E, 0x04, 0x3E, 0x1C, 0xA0, 0xD8, 0x0F, 0xCB, 0x52, 0x83, + 0x62, 0x7C, 0xEE, 0x8B, 0x53, 0x95, 0x90, 0xA9, 0x57, 0xA2, 0xEA, 0x61, + 0x05, 0xD8, 0xF9, 0x4D, 0xC4, 0x27, 0xFA, 0x6E, 0xAD, 0xED, 0xF9, 0xD7, + 0x51, 0xF7, 0x6B, 0xA5 +}; + +static const unsigned char TA438_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA439_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA439_RSA_N[] = { + 0xAD, 0x0E, 0x15, 0xCE, 0xE4, 0x43, 0x80, 0x5C, 0xB1, 0x87, 0xF3, 0xB7, + 0x60, 0xF9, 0x71, 0x12, 0xA5, 0xAE, 0xDC, 0x26, 0x94, 0x88, 0xAA, 0xF4, + 0xCE, 0xF5, 0x20, 0x39, 0x28, 0x58, 0x60, 0x0C, 0xF8, 0x80, 0xDA, 0xA9, + 0x15, 0x95, 0x32, 0x61, 0x3C, 0xB5, 0xB1, 0x28, 0x84, 0x8A, 0x8A, 0xDC, + 0x9F, 0x0A, 0x0C, 0x83, 0x17, 0x7A, 0x8F, 0x90, 0xAC, 0x8A, 0xE7, 0x79, + 0x53, 0x5C, 0x31, 0x84, 0x2A, 0xF6, 0x0F, 0x98, 0x32, 0x36, 0x76, 0xCC, + 0xDE, 0xDD, 0x3C, 0xA8, 0xA2, 0xEF, 0x6A, 0xFB, 0x21, 0xF2, 0x52, 0x61, + 0xDF, 0x9F, 0x20, 0xD7, 0x1F, 0xE2, 0xB1, 0xD9, 0xFE, 0x18, 0x64, 0xD2, + 0x12, 0x5B, 0x5F, 0xF9, 0x58, 0x18, 0x35, 0xBC, 0x47, 0xCD, 0xA1, 0x36, + 0xF9, 0x6B, 0x7F, 0xD4, 0xB0, 0x38, 0x3E, 0xC1, 0x1B, 0xC3, 0x8C, 0x33, + 0xD9, 0xD8, 0x2F, 0x18, 0xFE, 0x28, 0x0F, 0xB3, 0xA7, 0x83, 0xD6, 0xC3, + 0x6E, 0x44, 0xC0, 0x61, 0x35, 0x96, 0x16, 0xFE, 0x59, 0x9C, 0x8B, 0x76, + 0x6D, 0xD7, 0xF1, 0xA2, 0x4B, 0x0D, 0x2B, 0xFF, 0x0B, 0x72, 0xDA, 0x9E, + 0x60, 0xD0, 0x8E, 0x90, 0x35, 0xC6, 0x78, 0x55, 0x87, 0x20, 0xA1, 0xCF, + 0xE5, 0x6D, 0x0A, 0xC8, 0x49, 0x7C, 0x31, 0x98, 0x33, 0x6C, 0x22, 0xE9, + 0x87, 0xD0, 0x32, 0x5A, 0xA2, 0xBA, 0x13, 0x82, 0x11, 0xED, 0x39, 0x17, + 0x9D, 0x99, 0x3A, 0x72, 0xA1, 0xE6, 0xFA, 0xA4, 0xD9, 0xD5, 0x17, 0x31, + 0x75, 0xAE, 0x85, 0x7D, 0x22, 0xAE, 0x3F, 0x01, 0x46, 0x86, 0xF6, 0x28, + 0x79, 0xC8, 0xB1, 0xDA, 0xE4, 0x57, 0x17, 0xC4, 0x7E, 0x1C, 0x0E, 0xB0, + 0xB4, 0x92, 0xA6, 0x56, 0xB3, 0xBD, 0xB2, 0x97, 0xED, 0xAA, 0xA7, 0xF0, + 0xB7, 0xC5, 0xA8, 0x3F, 0x95, 0x16, 0xD0, 0xFF, 0xA1, 0x96, 0xEB, 0x08, + 0x5F, 0x18, 0x77, 0x4F +}; + +static const unsigned char TA439_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA440_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA440_RSA_N[] = { + 0xD9, 0xE7, 0x28, 0x2F, 0x52, 0x3F, 0x36, 0x72, 0x49, 0x88, 0x93, 0x34, + 0xF3, 0xF8, 0x6A, 0x1E, 0x31, 0x54, 0x80, 0x9F, 0xAD, 0x54, 0x41, 0xB5, + 0x47, 0xDF, 0x96, 0xA8, 0xD4, 0xAF, 0x80, 0x2D, 0xB9, 0x0A, 0xCF, 0x75, + 0xFD, 0x89, 0xA5, 0x7D, 0x24, 0xFA, 0xE3, 0x22, 0x0C, 0x2B, 0xBC, 0x95, + 0x17, 0x0B, 0x33, 0xBF, 0x19, 0x4D, 0x41, 0x06, 0x90, 0x00, 0xBD, 0x0C, + 0x4D, 0x10, 0xFE, 0x07, 0xB5, 0xE7, 0x1C, 0x6E, 0x22, 0x55, 0x31, 0x65, + 0x97, 0xBD, 0xD3, 0x17, 0xD2, 0x1E, 0x62, 0xF3, 0xDB, 0xEA, 0x6C, 0x50, + 0x8C, 0x3F, 0x84, 0x0C, 0x96, 0xCF, 0xB7, 0xCB, 0x03, 0xE0, 0xCA, 0x6D, + 0xA1, 0x14, 0x4C, 0x1B, 0x89, 0xDD, 0xED, 0x00, 0xB0, 0x52, 0x7C, 0xAF, + 0x91, 0x6C, 0xB1, 0x38, 0x13, 0xD1, 0xE9, 0x12, 0x08, 0xC0, 0x00, 0xB0, + 0x1C, 0x2B, 0x11, 0xDA, 0x77, 0x70, 0x36, 0x9B, 0xAE, 0xCE, 0x79, 0x87, + 0xDC, 0x82, 0x70, 0xE6, 0x09, 0x74, 0x70, 0x55, 0x69, 0xAF, 0xA3, 0x68, + 0x9F, 0xBF, 0xDD, 0xB6, 0x79, 0xB3, 0xF2, 0x9D, 0x70, 0x29, 0x55, 0xF4, + 0xAB, 0xFF, 0x95, 0x61, 0xF3, 0xC9, 0x40, 0x6F, 0x1D, 0xD1, 0xBE, 0x93, + 0xBB, 0xD3, 0x88, 0x2A, 0xBB, 0x9D, 0xBF, 0x72, 0x5A, 0x56, 0x71, 0x3B, + 0x3F, 0xD4, 0xF3, 0xD1, 0x0A, 0xFE, 0x28, 0xEF, 0xA3, 0xEE, 0xD9, 0x99, + 0xAF, 0x03, 0xD3, 0x8F, 0x60, 0xB7, 0xF2, 0x92, 0xA1, 0xB1, 0xBD, 0x89, + 0x89, 0x1F, 0x30, 0xCD, 0xC3, 0xA6, 0x2E, 0x62, 0x33, 0xAE, 0x16, 0x02, + 0x77, 0x44, 0x5A, 0xE7, 0x81, 0x0A, 0x3C, 0xA7, 0x44, 0x2E, 0x79, 0xB8, + 0x3F, 0x04, 0xBC, 0x5C, 0xA0, 0x87, 0xE1, 0x1B, 0xAF, 0x51, 0x8E, 0xCD, + 0xEC, 0x2C, 0xFA, 0xF8, 0xFE, 0x6D, 0xF0, 0x3A, 0x7C, 0xAA, 0x8B, 0xE4, + 0x67, 0x95, 0x31, 0x8D +}; + +static const unsigned char TA440_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA441_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA441_EC_Q[] = { + 0x04, 0x19, 0xE7, 0xBC, 0xAC, 0x44, 0x65, 0xED, 0xCD, 0xB8, 0x3F, 0x58, + 0xFB, 0x8D, 0xB1, 0x57, 0xA9, 0x44, 0x2D, 0x05, 0x15, 0xF2, 0xEF, 0x0B, + 0xFF, 0x10, 0x74, 0x9F, 0xB5, 0x62, 0x52, 0x5F, 0x66, 0x7E, 0x1F, 0xE5, + 0xDC, 0x1B, 0x45, 0x79, 0x0B, 0xCC, 0xC6, 0x53, 0x0A, 0x9D, 0x8D, 0x5D, + 0x02, 0xD9, 0xA9, 0x59, 0xDE, 0x02, 0x5A, 0xF6, 0x95, 0x2A, 0x0E, 0x8D, + 0x38, 0x4A, 0x8A, 0x49, 0xC6, 0xBC, 0xC6, 0x03, 0x38, 0x07, 0x5F, 0x55, + 0xDA, 0x7E, 0x09, 0x6E, 0xE2, 0x7F, 0x5E, 0xD0, 0x45, 0x20, 0x0F, 0x59, + 0x76, 0x10, 0xD6, 0xA0, 0x24, 0xF0, 0x2D, 0xDE, 0x36, 0xF2, 0x6C, 0x29, + 0x39 +}; + +static const unsigned char TA442_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA442_RSA_N[] = { + 0xE2, 0x3B, 0xE1, 0x11, 0x72, 0xDE, 0xA8, 0xA4, 0xD3, 0xA3, 0x57, 0xAA, + 0x50, 0xA2, 0x8F, 0x0B, 0x77, 0x90, 0xC9, 0xA2, 0xA5, 0xEE, 0x12, 0xCE, + 0x96, 0x5B, 0x01, 0x09, 0x20, 0xCC, 0x01, 0x93, 0xA7, 0x4E, 0x30, 0xB7, + 0x53, 0xF7, 0x43, 0xC4, 0x69, 0x00, 0x57, 0x9D, 0xE2, 0x8D, 0x22, 0xDD, + 0x87, 0x06, 0x40, 0x00, 0x81, 0x09, 0xCE, 0xCE, 0x1B, 0x83, 0xBF, 0xDF, + 0xCD, 0x3B, 0x71, 0x46, 0xE2, 0xD6, 0x66, 0xC7, 0x05, 0xB3, 0x76, 0x27, + 0x16, 0x8F, 0x7B, 0x9E, 0x1E, 0x95, 0x7D, 0xEE, 0xB7, 0x48, 0xA3, 0x08, + 0xDA, 0xD6, 0xAF, 0x7A, 0x0C, 0x39, 0x06, 0x65, 0x7F, 0x4A, 0x5D, 0x1F, + 0xBC, 0x17, 0xF8, 0xAB, 0xBE, 0xEE, 0x28, 0xD7, 0x74, 0x7F, 0x7A, 0x78, + 0x99, 0x59, 0x85, 0x68, 0x6E, 0x5C, 0x23, 0x32, 0x4B, 0xBF, 0x4E, 0xC0, + 0xE8, 0x5A, 0x6D, 0xE3, 0x70, 0xBF, 0x77, 0x10, 0xBF, 0xFC, 0x01, 0xF6, + 0x85, 0xD9, 0xA8, 0x44, 0x10, 0x58, 0x32, 0xA9, 0x75, 0x18, 0xD5, 0xD1, + 0xA2, 0xBE, 0x47, 0xE2, 0x27, 0x6A, 0xF4, 0x9A, 0x33, 0xF8, 0x49, 0x08, + 0x60, 0x8B, 0xD4, 0x5F, 0xB4, 0x3A, 0x84, 0xBF, 0xA1, 0xAA, 0x4A, 0x4C, + 0x7D, 0x3E, 0xCF, 0x4F, 0x5F, 0x6C, 0x76, 0x5E, 0xA0, 0x4B, 0x37, 0x91, + 0x9E, 0xDC, 0x22, 0xE6, 0x6D, 0xCE, 0x14, 0x1A, 0x8E, 0x6A, 0xCB, 0xFE, + 0xCD, 0xB3, 0x14, 0x64, 0x17, 0xC7, 0x5B, 0x29, 0x9E, 0x32, 0xBF, 0xF2, + 0xEE, 0xFA, 0xD3, 0x0B, 0x42, 0xD4, 0xAB, 0xB7, 0x41, 0x32, 0xDA, 0x0C, + 0xD4, 0xEF, 0xF8, 0x81, 0xD5, 0xBB, 0x8D, 0x58, 0x3F, 0xB5, 0x1B, 0xE8, + 0x49, 0x28, 0xA2, 0x70, 0xDA, 0x31, 0x04, 0xDD, 0xF7, 0xB2, 0x16, 0xF2, + 0x4C, 0x0A, 0x4E, 0x07, 0xA8, 0xED, 0x4A, 0x3D, 0x5E, 0xB5, 0x7F, 0xA3, + 0x90, 0xC3, 0xAF, 0x27 +}; + +static const unsigned char TA442_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA443_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x32 +}; + +static const unsigned char TA443_RSA_N[] = { + 0xBB, 0x37, 0xCD, 0x34, 0xDC, 0x7B, 0x6B, 0xC9, 0xB2, 0x68, 0x90, 0xAD, + 0x4A, 0x75, 0xFF, 0x46, 0xBA, 0x21, 0x0A, 0x08, 0x8D, 0xF5, 0x19, 0x54, + 0xC9, 0xFB, 0x88, 0xDB, 0xF3, 0xAE, 0xF2, 0x3A, 0x89, 0x91, 0x3C, 0x7A, + 0xE6, 0xAB, 0x06, 0x1A, 0x6B, 0xCF, 0xAC, 0x2D, 0xE8, 0x5E, 0x09, 0x24, + 0x44, 0xBA, 0x62, 0x9A, 0x7E, 0xD6, 0xA3, 0xA8, 0x7E, 0xE0, 0x54, 0x75, + 0x20, 0x05, 0xAC, 0x50, 0xB7, 0x9C, 0x63, 0x1A, 0x6C, 0x30, 0xDC, 0xDA, + 0x1F, 0x19, 0xB1, 0xD7, 0x1E, 0xDE, 0xFD, 0xD7, 0xE0, 0xCB, 0x94, 0x83, + 0x37, 0xAE, 0xEC, 0x1F, 0x43, 0x4E, 0xDD, 0x7B, 0x2C, 0xD2, 0xBD, 0x2E, + 0xA5, 0x2F, 0xE4, 0xA9, 0xB8, 0xAD, 0x3A, 0xD4, 0x99, 0xA4, 0xB6, 0x25, + 0xE9, 0x9B, 0x6B, 0x00, 0x60, 0x92, 0x60, 0xFF, 0x4F, 0x21, 0x49, 0x18, + 0xF7, 0x67, 0x90, 0xAB, 0x61, 0x06, 0x9C, 0x8F, 0xF2, 0xBA, 0xE9, 0xB4, + 0xE9, 0x92, 0x32, 0x6B, 0xB5, 0xF3, 0x57, 0xE8, 0x5D, 0x1B, 0xCD, 0x8C, + 0x1D, 0xAB, 0x95, 0x04, 0x95, 0x49, 0xF3, 0x35, 0x2D, 0x96, 0xE3, 0x49, + 0x6D, 0xDD, 0x77, 0xE3, 0xFB, 0x49, 0x4B, 0xB4, 0xAC, 0x55, 0x07, 0xA9, + 0x8F, 0x95, 0xB3, 0xB4, 0x23, 0xBB, 0x4C, 0x6D, 0x45, 0xF0, 0xF6, 0xA9, + 0xB2, 0x95, 0x30, 0xB4, 0xFD, 0x4C, 0x55, 0x8C, 0x27, 0x4A, 0x57, 0x14, + 0x7C, 0x82, 0x9D, 0xCD, 0x73, 0x92, 0xD3, 0x16, 0x4A, 0x06, 0x0C, 0x8C, + 0x50, 0xD1, 0x8F, 0x1E, 0x09, 0xBE, 0x17, 0xA1, 0xE6, 0x21, 0xCA, 0xFD, + 0x83, 0xE5, 0x10, 0xBC, 0x83, 0xA5, 0x0A, 0xC4, 0x67, 0x28, 0xF6, 0x73, + 0x14, 0x14, 0x3D, 0x46, 0x76, 0xC3, 0x87, 0x14, 0x89, 0x21, 0x34, 0x4D, + 0xAF, 0x0F, 0x45, 0x0C, 0xA6, 0x49, 0xA1, 0xBA, 0xBB, 0x9C, 0xC5, 0xB1, + 0x33, 0x83, 0x29, 0x85 +}; + +static const unsigned char TA443_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA444_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x33 +}; + +static const unsigned char TA444_EC_Q[] = { + 0x04, 0xDD, 0xA7, 0xD9, 0xBB, 0x8A, 0xB8, 0x0B, 0xFB, 0x0B, 0x7F, 0x21, + 0xD2, 0xF0, 0xBE, 0xBE, 0x73, 0xF3, 0x33, 0x5D, 0x1A, 0xBC, 0x34, 0xEA, + 0xDE, 0xC6, 0x9B, 0xBC, 0xD0, 0x95, 0xF6, 0xF0, 0xCC, 0xD0, 0x0B, 0xBA, + 0x61, 0x5B, 0x51, 0x46, 0x7E, 0x9E, 0x2D, 0x9F, 0xEE, 0x8E, 0x63, 0x0C, + 0x17, 0xEC, 0x07, 0x70, 0xF5, 0xCF, 0x84, 0x2E, 0x40, 0x83, 0x9C, 0xE8, + 0x3F, 0x41, 0x6D, 0x3B, 0xAD, 0xD3, 0xA4, 0x14, 0x59, 0x36, 0x78, 0x9D, + 0x03, 0x43, 0xEE, 0x10, 0x13, 0x6C, 0x72, 0xDE, 0xAE, 0x88, 0xA7, 0xA1, + 0x6B, 0xB5, 0x43, 0xCE, 0x67, 0xDC, 0x23, 0xFF, 0x03, 0x1C, 0xA3, 0xE2, + 0x3E +}; + +static const unsigned char TA445_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, + 0x6E, 0x63, 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA445_RSA_N[] = { + 0xC6, 0xCC, 0xE5, 0x73, 0xE6, 0xFB, 0xD4, 0xBB, 0xE5, 0x2D, 0x2D, 0x32, + 0xA6, 0xDF, 0xE5, 0x81, 0x3F, 0xC9, 0xCD, 0x25, 0x49, 0xB6, 0x71, 0x2A, + 0xC3, 0xD5, 0x94, 0x34, 0x67, 0xA2, 0x0A, 0x1C, 0xB0, 0x5F, 0x69, 0xA6, + 0x40, 0xB1, 0xC4, 0xB7, 0xB2, 0x8F, 0xD0, 0x98, 0xA4, 0xA9, 0x41, 0x59, + 0x3A, 0xD3, 0xDC, 0x94, 0xD6, 0x3C, 0xDB, 0x74, 0x38, 0xA4, 0x4A, 0xCC, + 0x4D, 0x25, 0x82, 0xF7, 0x4A, 0xA5, 0x53, 0x12, 0x38, 0xEE, 0xF3, 0x49, + 0x6D, 0x71, 0x91, 0x7E, 0x63, 0xB6, 0xAB, 0xA6, 0x5F, 0xC3, 0xA4, 0x84, + 0xF8, 0x4F, 0x62, 0x51, 0xBE, 0xF8, 0xC5, 0xEC, 0xDB, 0x38, 0x92, 0xE3, + 0x06, 0xE5, 0x08, 0x91, 0x0C, 0xC4, 0x28, 0x41, 0x55, 0xFB, 0xCB, 0x5A, + 0x89, 0x15, 0x7E, 0x71, 0xE8, 0x35, 0xBF, 0x4D, 0x72, 0x09, 0x3D, 0xBE, + 0x3A, 0x38, 0x50, 0x5B, 0x77, 0x31, 0x1B, 0x8D, 0xB3, 0xC7, 0x24, 0x45, + 0x9A, 0xA7, 0xAC, 0x6D, 0x00, 0x14, 0x5A, 0x04, 0xB7, 0xBA, 0x13, 0xEB, + 0x51, 0x0A, 0x98, 0x41, 0x41, 0x22, 0x4E, 0x65, 0x61, 0x87, 0x81, 0x41, + 0x50, 0xA6, 0x79, 0x5C, 0x89, 0xDE, 0x19, 0x4A, 0x57, 0xD5, 0x2E, 0xE6, + 0x5D, 0x1C, 0x53, 0x2C, 0x7E, 0x98, 0xCD, 0x1A, 0x06, 0x16, 0xA4, 0x68, + 0x73, 0xD0, 0x34, 0x04, 0x13, 0x5C, 0xA1, 0x71, 0xD3, 0x5A, 0x7C, 0x55, + 0xDB, 0x5E, 0x64, 0xE1, 0x37, 0x87, 0x30, 0x56, 0x04, 0xE5, 0x11, 0xB4, + 0x29, 0x80, 0x12, 0xF1, 0x79, 0x39, 0x88, 0xA2, 0x02, 0x11, 0x7C, 0x27, + 0x66, 0xB7, 0x88, 0xB7, 0x78, 0xF2, 0xCA, 0x0A, 0xA8, 0x38, 0xAB, 0x0A, + 0x64, 0xC2, 0xBF, 0x66, 0x5D, 0x95, 0x84, 0xC1, 0xA1, 0x25, 0x1E, 0x87, + 0x5D, 0x1A, 0x50, 0x0B, 0x20, 0x12, 0xCC, 0x41, 0xBB, 0x6E, 0x0B, 0x51, + 0x38, 0xB8, 0x4B, 0xCB +}; + +static const unsigned char TA445_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA446_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1D, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x50, 0x33, 0x38, 0x34, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA446_EC_Q[] = { + 0x04, 0xC1, 0x44, 0xA1, 0xCF, 0x11, 0x97, 0x50, 0x9A, 0xDE, 0x23, 0x82, + 0x35, 0x07, 0xCD, 0xD0, 0xCB, 0x18, 0x9D, 0xD2, 0xF1, 0x7F, 0x77, 0x35, + 0x4F, 0x3B, 0xDD, 0x94, 0x72, 0x52, 0xED, 0xC2, 0x3B, 0xF8, 0xEC, 0xFA, + 0x7B, 0x6B, 0x58, 0x20, 0xEC, 0x99, 0xAE, 0xC9, 0xFC, 0x68, 0xB3, 0x75, + 0xB9, 0xDB, 0x09, 0xEC, 0xC8, 0x13, 0xF5, 0x4E, 0xC6, 0x0A, 0x1D, 0x66, + 0x30, 0x4C, 0xBB, 0x1F, 0x47, 0x0A, 0x3C, 0x61, 0x10, 0x42, 0x29, 0x7C, + 0xA5, 0x08, 0x0E, 0xE0, 0x22, 0xE9, 0xD3, 0x35, 0x68, 0xCE, 0x9B, 0x63, + 0x9F, 0x84, 0xB5, 0x99, 0x4D, 0x58, 0xA0, 0x8E, 0xF5, 0x54, 0xE7, 0x95, + 0xC9 +}; + +static const unsigned char TA447_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x34, 0x30, 0x39, 0x36, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA447_RSA_N[] = { + 0xB3, 0xD0, 0xF4, 0xC9, 0x79, 0x11, 0x9D, 0xFD, 0xFC, 0x66, 0x81, 0xE7, + 0xCC, 0xD5, 0xE4, 0xBC, 0xEC, 0x81, 0x3E, 0x6A, 0x35, 0x8E, 0x2E, 0xB7, + 0xE7, 0xDE, 0xAF, 0xF9, 0x07, 0x4D, 0xCF, 0x30, 0x9D, 0xEA, 0x09, 0x0B, + 0x99, 0xBD, 0x6C, 0x57, 0xDA, 0x18, 0x4A, 0xB8, 0x78, 0xAC, 0x3A, 0x39, + 0xA8, 0xA6, 0x48, 0xAC, 0x2E, 0x72, 0xE5, 0xBD, 0xEB, 0xF1, 0x1A, 0xCD, + 0xE7, 0xA4, 0x03, 0xA9, 0x3F, 0x11, 0xB4, 0xD8, 0x2F, 0x89, 0x16, 0xFB, + 0x94, 0x01, 0x3D, 0xBB, 0x2F, 0xF8, 0x13, 0x05, 0xA1, 0x78, 0x1C, 0x8E, + 0x28, 0xE0, 0x45, 0xE0, 0x83, 0xF4, 0x59, 0x1B, 0x95, 0xB3, 0xAE, 0x7E, + 0x03, 0x45, 0xE5, 0xBE, 0xC2, 0x42, 0xFE, 0xEE, 0xF2, 0x3C, 0xB6, 0x85, + 0x13, 0x98, 0x32, 0x9D, 0x16, 0xA8, 0x29, 0xC2, 0x0B, 0x1C, 0x38, 0xDC, + 0x9F, 0x31, 0x77, 0x5C, 0xBF, 0x27, 0xA3, 0xFC, 0x27, 0xAC, 0xB7, 0x2B, + 0xBD, 0x74, 0x9B, 0x17, 0x2D, 0xF2, 0x81, 0xDA, 0x5D, 0xB0, 0xE1, 0x23, + 0x17, 0x3E, 0x88, 0x4A, 0x12, 0x23, 0xD0, 0xEA, 0xCF, 0x9D, 0xDE, 0x03, + 0x17, 0xB1, 0x42, 0x4A, 0xA0, 0x16, 0x4C, 0xA4, 0x6D, 0x93, 0xE9, 0x3F, + 0x3A, 0xEE, 0x3A, 0x7C, 0x9D, 0x58, 0x9D, 0xF4, 0x4E, 0x8F, 0xFC, 0x3B, + 0x23, 0xC8, 0x6D, 0xB8, 0xE2, 0x05, 0xDA, 0xCC, 0xEB, 0xEC, 0xC3, 0x31, + 0xF4, 0xD7, 0xA7, 0x29, 0x54, 0x80, 0xCF, 0x44, 0x5B, 0x4C, 0x6F, 0x30, + 0x9E, 0xF3, 0xCC, 0xDD, 0x1F, 0x94, 0x43, 0x9D, 0x4D, 0x7F, 0x70, 0x70, + 0x0D, 0xD4, 0x3A, 0xD1, 0x37, 0xF0, 0x6C, 0x9D, 0x9B, 0xC0, 0x14, 0x93, + 0x58, 0xEF, 0xCD, 0x41, 0x38, 0x75, 0xBC, 0x13, 0x03, 0x95, 0x7C, 0x7F, + 0xE3, 0x5C, 0xE9, 0xD5, 0x0D, 0xD5, 0xE2, 0x7C, 0x10, 0x62, 0xAA, 0x6B, + 0xF0, 0x3D, 0x76, 0xF3, 0x3F, 0xA3, 0xE8, 0xB0, 0xC1, 0xFD, 0xEF, 0xAA, + 0x57, 0x4D, 0xAC, 0x86, 0xA7, 0x18, 0xB4, 0x29, 0xC1, 0x2C, 0x0E, 0xBF, + 0x64, 0xBE, 0x29, 0x8C, 0xD8, 0x02, 0x2D, 0xCD, 0x5C, 0x2F, 0xF2, 0x7F, + 0xEF, 0x15, 0xF4, 0x0C, 0x15, 0xAC, 0x0A, 0xB0, 0xF1, 0xD3, 0x0D, 0x4F, + 0x6A, 0x4D, 0x77, 0x97, 0x01, 0xA0, 0xF1, 0x66, 0xB7, 0xB7, 0xCE, 0xEF, + 0xCE, 0xEC, 0xEC, 0xA5, 0x75, 0xCA, 0xAC, 0xE3, 0xE1, 0x63, 0xF7, 0xB8, + 0xA1, 0x04, 0xC8, 0xBC, 0x7B, 0x3F, 0x5D, 0x2D, 0x16, 0x22, 0x56, 0xED, + 0x48, 0x49, 0xFE, 0xA7, 0x2F, 0x79, 0x30, 0x25, 0x9B, 0xBA, 0x6B, 0x2D, + 0x3F, 0x9D, 0x3B, 0xC4, 0x17, 0xE7, 0x1D, 0x2E, 0xFB, 0xF2, 0xCF, 0xA6, + 0xFC, 0xE3, 0x14, 0x2C, 0x96, 0x98, 0x21, 0x8C, 0xB4, 0x91, 0xE9, 0x19, + 0x60, 0x83, 0xF2, 0x30, 0x2B, 0x06, 0x73, 0x50, 0xD5, 0x98, 0x3B, 0x06, + 0xE9, 0xC7, 0x8A, 0x0C, 0x60, 0x8C, 0x28, 0xF8, 0x52, 0x9B, 0x6E, 0xE1, + 0xF6, 0x4D, 0xBB, 0x06, 0x24, 0x9B, 0xD7, 0x2B, 0x26, 0x3F, 0xFD, 0x2A, + 0x2F, 0x71, 0xF5, 0xD6, 0x24, 0xBE, 0x7F, 0x31, 0x9E, 0x0F, 0x6D, 0xE8, + 0x8F, 0x4F, 0x4D, 0xA3, 0x3F, 0xFF, 0x35, 0xEA, 0xDF, 0x49, 0x5E, 0x41, + 0x8F, 0x86, 0xF9, 0xF1, 0x77, 0x79, 0x4B, 0x1B, 0xB4, 0xA3, 0x5E, 0x2F, + 0xFB, 0x46, 0x02, 0xD0, 0x66, 0x13, 0x5E, 0x5E, 0x85, 0x4F, 0xCE, 0xD8, + 0x70, 0x88, 0x7B, 0xCE, 0x01, 0xB5, 0x96, 0x97, 0xD7, 0xCD, 0x7D, 0xFD, + 0x82, 0xF8, 0xC2, 0x24, 0xC1, 0xCA, 0x01, 0x39, 0x4F, 0x8D, 0xA2, 0xC1, + 0x14, 0x40, 0x1F, 0x9C, 0x66, 0xD5, 0x0C, 0x09, 0x46, 0xD6, 0xF2, 0xD0, + 0xD1, 0x48, 0x76, 0x56, 0x3A, 0x43, 0xCB, 0xB6, 0x0A, 0x11, 0x39, 0xBA, + 0x8C, 0x13, 0x6C, 0x06, 0xB5, 0x9E, 0xCF, 0xEB +}; + +static const unsigned char TA447_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA448_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x18, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA448_RSA_N[] = { + 0xBF, 0xE6, 0x90, 0x73, 0x68, 0xDE, 0xBB, 0xE4, 0x5D, 0x4A, 0x3C, 0x30, + 0x22, 0x30, 0x69, 0x33, 0xEC, 0xC2, 0xA7, 0x25, 0x2E, 0xC9, 0x21, 0x3D, + 0xF2, 0x8A, 0xD8, 0x59, 0xC2, 0xE1, 0x29, 0xA7, 0x3D, 0x58, 0xAB, 0x76, + 0x9A, 0xCD, 0xAE, 0x7B, 0x1B, 0x84, 0x0D, 0xC4, 0x30, 0x1F, 0xF3, 0x1B, + 0xA4, 0x38, 0x16, 0xEB, 0x56, 0xC6, 0x97, 0x6D, 0x1D, 0xAB, 0xB2, 0x79, + 0xF2, 0xCA, 0x11, 0xD2, 0xE4, 0x5F, 0xD6, 0x05, 0x3C, 0x52, 0x0F, 0x52, + 0x1F, 0xC6, 0x9E, 0x15, 0xA5, 0x7E, 0xBE, 0x9F, 0xA9, 0x57, 0x16, 0x59, + 0x55, 0x72, 0xAF, 0x68, 0x93, 0x70, 0xC2, 0xB2, 0xBA, 0x75, 0x99, 0x6A, + 0x73, 0x32, 0x94, 0xD1, 0x10, 0x44, 0x10, 0x2E, 0xDF, 0x82, 0xF3, 0x07, + 0x84, 0xE6, 0x74, 0x3B, 0x6D, 0x71, 0xE2, 0x2D, 0x0C, 0x1B, 0xEE, 0x20, + 0xD5, 0xC9, 0x20, 0x1D, 0x63, 0x29, 0x2D, 0xCE, 0xEC, 0x5E, 0x4E, 0xC8, + 0x93, 0xF8, 0x21, 0x61, 0x9B, 0x34, 0xEB, 0x05, 0xC6, 0x5E, 0xEC, 0x5B, + 0x1A, 0xBC, 0xEB, 0xC9, 0xCF, 0xCD, 0xAC, 0x34, 0x40, 0x5F, 0xB1, 0x7A, + 0x66, 0xEE, 0x77, 0xC8, 0x48, 0xA8, 0x66, 0x57, 0x57, 0x9F, 0x54, 0x58, + 0x8E, 0x0C, 0x2B, 0xB7, 0x4F, 0xA7, 0x30, 0xD9, 0x56, 0xEE, 0xCA, 0x7B, + 0x5D, 0xE3, 0xAD, 0xC9, 0x4F, 0x5E, 0xE5, 0x35, 0xE7, 0x31, 0xCB, 0xDA, + 0x93, 0x5E, 0xDC, 0x8E, 0x8F, 0x80, 0xDA, 0xB6, 0x91, 0x98, 0x40, 0x90, + 0x79, 0xC3, 0x78, 0xC7, 0xB6, 0xB1, 0xC4, 0xB5, 0x6A, 0x18, 0x38, 0x03, + 0x10, 0x8D, 0xD8, 0xD4, 0x37, 0xA4, 0x2E, 0x05, 0x7D, 0x88, 0xF5, 0x82, + 0x3E, 0x10, 0x91, 0x70, 0xAB, 0x55, 0x82, 0x41, 0x32, 0xD7, 0xDB, 0x04, + 0x73, 0x2A, 0x6E, 0x91, 0x01, 0x7C, 0x21, 0x4C, 0xD4, 0xBC, 0xAE, 0x1B, + 0x03, 0x75, 0x5D, 0x78, 0x66, 0xD9, 0x3A, 0x31, 0x44, 0x9A, 0x33, 0x40, + 0xBF, 0x08, 0xD7, 0x5A, 0x49, 0xA4, 0xC2, 0xE6, 0xA9, 0xA0, 0x67, 0xDD, + 0xA4, 0x27, 0xBC, 0xA1, 0x4F, 0x39, 0xB5, 0x11, 0x58, 0x17, 0xF7, 0x24, + 0x5C, 0x46, 0x8F, 0x64, 0xF7, 0xC1, 0x69, 0x88, 0x76, 0x98, 0x76, 0x3D, + 0x59, 0x5D, 0x42, 0x76, 0x87, 0x89, 0x97, 0x69, 0x7A, 0x48, 0xF0, 0xE0, + 0xA2, 0x12, 0x1B, 0x66, 0x9A, 0x74, 0xCA, 0xDE, 0x4B, 0x1E, 0xE7, 0x0E, + 0x63, 0xAE, 0xE6, 0xD4, 0xEF, 0x92, 0x92, 0x3A, 0x9E, 0x3D, 0xDC, 0x00, + 0xE4, 0x45, 0x25, 0x89, 0xB6, 0x9A, 0x44, 0x19, 0x2B, 0x7E, 0xC0, 0x94, + 0xB4, 0xD2, 0x61, 0x6D, 0xEB, 0x33, 0xD9, 0xC5, 0xDF, 0x4B, 0x04, 0x00, + 0xCC, 0x7D, 0x1C, 0x95, 0xC3, 0x8F, 0xF7, 0x21, 0xB2, 0xB2, 0x11, 0xB7, + 0xBB, 0x7F, 0xF2, 0xD5, 0x8C, 0x70, 0x2C, 0x41, 0x60, 0xAA, 0xB1, 0x63, + 0x18, 0x44, 0x95, 0x1A, 0x76, 0x62, 0x7E, 0xF6, 0x80, 0xB0, 0xFB, 0xE8, + 0x64, 0xA6, 0x33, 0xD1, 0x89, 0x07, 0xE1, 0xBD, 0xB7, 0xE6, 0x43, 0xA4, + 0x18, 0xB8, 0xA6, 0x77, 0x01, 0xE1, 0x0F, 0x94, 0x0C, 0x21, 0x1D, 0xB2, + 0x54, 0x29, 0x25, 0x89, 0x6C, 0xE5, 0x0E, 0x52, 0x51, 0x47, 0x74, 0xBE, + 0x26, 0xAC, 0xB6, 0x41, 0x75, 0xDE, 0x7A, 0xAC, 0x5F, 0x8D, 0x3F, 0xC9, + 0xBC, 0xD3, 0x41, 0x11, 0x12, 0x5B, 0xE5, 0x10, 0x50, 0xEB, 0x31, 0xC5, + 0xCA, 0x72, 0x16, 0x22, 0x09, 0xDF, 0x7C, 0x4C, 0x75, 0x3F, 0x63, 0xEC, + 0x21, 0x5F, 0xC4, 0x20, 0x51, 0x6B, 0x6F, 0xB1, 0xAB, 0x86, 0x8B, 0x4F, + 0xC2, 0xD6, 0x45, 0x5F, 0x9D, 0x20, 0xFC, 0xA1, 0x1E, 0xC5, 0xC0, 0x8F, + 0xA2, 0xB1, 0x7E, 0x0A, 0x26, 0x99, 0xF5, 0xE4, 0x69, 0x2F, 0x98, 0x1D, + 0x2D, 0xF5, 0xD9, 0xA9, 0xB2, 0x1D, 0xE5, 0x1B +}; + +static const unsigned char TA448_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA449_DN[] = { + 0x30, 0x81, 0xB4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, + 0x74, 0x31, 0x40, 0x30, 0x3E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x14, 0x37, + 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, + 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x5F, 0x32, 0x30, 0x34, 0x38, + 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x2E, 0x20, 0x62, 0x79, 0x20, + 0x72, 0x65, 0x66, 0x2E, 0x20, 0x28, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x73, + 0x20, 0x6C, 0x69, 0x61, 0x62, 0x2E, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1C, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, + 0x65, 0x74, 0x20, 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, + 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, + 0x34, 0x38, 0x29 +}; + +static const unsigned char TA449_RSA_N[] = { + 0xAD, 0x4D, 0x4B, 0xA9, 0x12, 0x86, 0xB2, 0xEA, 0xA3, 0x20, 0x07, 0x15, + 0x16, 0x64, 0x2A, 0x2B, 0x4B, 0xD1, 0xBF, 0x0B, 0x4A, 0x4D, 0x8E, 0xED, + 0x80, 0x76, 0xA5, 0x67, 0xB7, 0x78, 0x40, 0xC0, 0x73, 0x42, 0xC8, 0x68, + 0xC0, 0xDB, 0x53, 0x2B, 0xDD, 0x5E, 0xB8, 0x76, 0x98, 0x35, 0x93, 0x8B, + 0x1A, 0x9D, 0x7C, 0x13, 0x3A, 0x0E, 0x1F, 0x5B, 0xB7, 0x1E, 0xCF, 0xE5, + 0x24, 0x14, 0x1E, 0xB1, 0x81, 0xA9, 0x8D, 0x7D, 0xB8, 0xCC, 0x6B, 0x4B, + 0x03, 0xF1, 0x02, 0x0C, 0xDC, 0xAB, 0xA5, 0x40, 0x24, 0x00, 0x7F, 0x74, + 0x94, 0xA1, 0x9D, 0x08, 0x29, 0xB3, 0x88, 0x0B, 0xF5, 0x87, 0x77, 0x9D, + 0x55, 0xCD, 0xE4, 0xC3, 0x7E, 0xD7, 0x6A, 0x64, 0xAB, 0x85, 0x14, 0x86, + 0x95, 0x5B, 0x97, 0x32, 0x50, 0x6F, 0x3D, 0xC8, 0xBA, 0x66, 0x0C, 0xE3, + 0xFC, 0xBD, 0xB8, 0x49, 0xC1, 0x76, 0x89, 0x49, 0x19, 0xFD, 0xC0, 0xA8, + 0xBD, 0x89, 0xA3, 0x67, 0x2F, 0xC6, 0x9F, 0xBC, 0x71, 0x19, 0x60, 0xB8, + 0x2D, 0xE9, 0x2C, 0xC9, 0x90, 0x76, 0x66, 0x7B, 0x94, 0xE2, 0xAF, 0x78, + 0xD6, 0x65, 0x53, 0x5D, 0x3C, 0xD6, 0x9C, 0xB2, 0xCF, 0x29, 0x03, 0xF9, + 0x2F, 0xA4, 0x50, 0xB2, 0xD4, 0x48, 0xCE, 0x05, 0x32, 0x55, 0x8A, 0xFD, + 0xB2, 0x64, 0x4C, 0x0E, 0xE4, 0x98, 0x07, 0x75, 0xDB, 0x7F, 0xDF, 0xB9, + 0x08, 0x55, 0x60, 0x85, 0x30, 0x29, 0xF9, 0x7B, 0x48, 0xA4, 0x69, 0x86, + 0xE3, 0x35, 0x3F, 0x1E, 0x86, 0x5D, 0x7A, 0x7A, 0x15, 0xBD, 0xEF, 0x00, + 0x8E, 0x15, 0x22, 0x54, 0x17, 0x00, 0x90, 0x26, 0x93, 0xBC, 0x0E, 0x49, + 0x68, 0x91, 0xBF, 0xF8, 0x47, 0xD3, 0x9D, 0x95, 0x42, 0xC1, 0x0E, 0x4D, + 0xDF, 0x6F, 0x26, 0xCF, 0xC3, 0x18, 0x21, 0x62, 0x66, 0x43, 0x70, 0xD6, + 0xD5, 0xC0, 0x07, 0xE1 +}; + +static const unsigned char TA449_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA450_DN[] = { + 0x30, 0x81, 0xB0, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x30, 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x20, 0x69, + 0x73, 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6E, 0x63, 0x65, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x16, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, + 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA450_RSA_N[] = { + 0xB6, 0x95, 0xB6, 0x43, 0x42, 0xFA, 0xC6, 0x6D, 0x2A, 0x6F, 0x48, 0xDF, + 0x94, 0x4C, 0x39, 0x57, 0x05, 0xEE, 0xC3, 0x79, 0x11, 0x41, 0x68, 0x36, + 0xED, 0xEC, 0xFE, 0x9A, 0x01, 0x8F, 0xA1, 0x38, 0x28, 0xFC, 0xF7, 0x10, + 0x46, 0x66, 0x2E, 0x4D, 0x1E, 0x1A, 0xB1, 0x1A, 0x4E, 0xC6, 0xD1, 0xC0, + 0x95, 0x88, 0xB0, 0xC9, 0xFF, 0x31, 0x8B, 0x33, 0x03, 0xDB, 0xB7, 0x83, + 0x7B, 0x3E, 0x20, 0x84, 0x5E, 0xED, 0xB2, 0x56, 0x28, 0xA7, 0xF8, 0xE0, + 0xB9, 0x40, 0x71, 0x37, 0xC5, 0xCB, 0x47, 0x0E, 0x97, 0x2A, 0x68, 0xC0, + 0x22, 0x95, 0x62, 0x15, 0xDB, 0x47, 0xD9, 0xF5, 0xD0, 0x2B, 0xFF, 0x82, + 0x4B, 0xC9, 0xAD, 0x3E, 0xDE, 0x4C, 0xDB, 0x90, 0x80, 0x50, 0x3F, 0x09, + 0x8A, 0x84, 0x00, 0xEC, 0x30, 0x0A, 0x3D, 0x18, 0xCD, 0xFB, 0xFD, 0x2A, + 0x59, 0x9A, 0x23, 0x95, 0x17, 0x2C, 0x45, 0x9E, 0x1F, 0x6E, 0x43, 0x79, + 0x6D, 0x0C, 0x5C, 0x98, 0xFE, 0x48, 0xA7, 0xC5, 0x23, 0x47, 0x5C, 0x5E, + 0xFD, 0x6E, 0xE7, 0x1E, 0xB4, 0xF6, 0x68, 0x45, 0xD1, 0x86, 0x83, 0x5B, + 0xA2, 0x8A, 0x8D, 0xB1, 0xE3, 0x29, 0x80, 0xFE, 0x25, 0x71, 0x88, 0xAD, + 0xBE, 0xBC, 0x8F, 0xAC, 0x52, 0x96, 0x4B, 0xAA, 0x51, 0x8D, 0xE4, 0x13, + 0x31, 0x19, 0xE8, 0x4E, 0x4D, 0x9F, 0xDB, 0xAC, 0xB3, 0x6A, 0xD5, 0xBC, + 0x39, 0x54, 0x71, 0xCA, 0x7A, 0x7A, 0x7F, 0x90, 0xDD, 0x7D, 0x1D, 0x80, + 0xD9, 0x81, 0xBB, 0x59, 0x26, 0xC2, 0x11, 0xFE, 0xE6, 0x93, 0xE2, 0xF7, + 0x80, 0xE4, 0x65, 0xFB, 0x34, 0x37, 0x0E, 0x29, 0x80, 0x70, 0x4D, 0xAF, + 0x38, 0x86, 0x2E, 0x9E, 0x7F, 0x57, 0xAF, 0x9E, 0x17, 0xAE, 0xEB, 0x1C, + 0xCB, 0x28, 0x21, 0x5F, 0xB6, 0x1C, 0xD8, 0xE7, 0xA2, 0x04, 0x22, 0xF9, + 0xD3, 0xDA, 0xD8, 0xCB +}; + +static const unsigned char TA450_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA451_DN[] = { + 0x30, 0x81, 0xBF, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x33, 0x30, + 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x45, + 0x43, 0x31 +}; + +static const unsigned char TA451_EC_Q[] = { + 0x04, 0x84, 0x13, 0xC9, 0xD0, 0xBA, 0x6D, 0x41, 0x7B, 0xE2, 0x6C, 0xD0, + 0xEB, 0x55, 0x5F, 0x66, 0x02, 0x1A, 0x24, 0xF4, 0x5B, 0x89, 0x69, 0x47, + 0xE3, 0xB8, 0xC2, 0x7D, 0xF1, 0xF2, 0x02, 0xC5, 0x9F, 0xA0, 0xF6, 0x5B, + 0xD5, 0x8B, 0x06, 0x19, 0x86, 0x4F, 0x53, 0x10, 0x6D, 0x07, 0x24, 0x27, + 0xA1, 0xA0, 0xF8, 0xD5, 0x47, 0x19, 0x61, 0x4C, 0x7D, 0xCA, 0x93, 0x27, + 0xEA, 0x74, 0x0C, 0xEF, 0x6F, 0x96, 0x09, 0xFE, 0x63, 0xEC, 0x70, 0x5D, + 0x36, 0xAD, 0x67, 0x77, 0xAE, 0xC9, 0x9D, 0x7C, 0x55, 0x44, 0x3A, 0xA2, + 0x63, 0x51, 0x1F, 0xF5, 0xE3, 0x62, 0xD4, 0xA9, 0x47, 0x07, 0x3E, 0xCC, + 0x20 +}; + +static const unsigned char TA452_DN[] = { + 0x30, 0x81, 0xBE, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x32, 0x30, + 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, + 0x32 +}; + +static const unsigned char TA452_RSA_N[] = { + 0xBA, 0x84, 0xB6, 0x72, 0xDB, 0x9E, 0x0C, 0x6B, 0xE2, 0x99, 0xE9, 0x30, + 0x01, 0xA7, 0x76, 0xEA, 0x32, 0xB8, 0x95, 0x41, 0x1A, 0xC9, 0xDA, 0x61, + 0x4E, 0x58, 0x72, 0xCF, 0xFE, 0xF6, 0x82, 0x79, 0xBF, 0x73, 0x61, 0x06, + 0x0A, 0xA5, 0x27, 0xD8, 0xB3, 0x5F, 0xD3, 0x45, 0x4E, 0x1C, 0x72, 0xD6, + 0x4E, 0x32, 0xF2, 0x72, 0x8A, 0x0F, 0xF7, 0x83, 0x19, 0xD0, 0x6A, 0x80, + 0x80, 0x00, 0x45, 0x1E, 0xB0, 0xC7, 0xE7, 0x9A, 0xBF, 0x12, 0x57, 0x27, + 0x1C, 0xA3, 0x68, 0x2F, 0x0A, 0x87, 0xBD, 0x6A, 0x6B, 0x0E, 0x5E, 0x65, + 0xF3, 0x1C, 0x77, 0xD5, 0xD4, 0x85, 0x8D, 0x70, 0x21, 0xB4, 0xB3, 0x32, + 0xE7, 0x8B, 0xA2, 0xD5, 0x86, 0x39, 0x02, 0xB1, 0xB8, 0xD2, 0x47, 0xCE, + 0xE4, 0xC9, 0x49, 0xC4, 0x3B, 0xA7, 0xDE, 0xFB, 0x54, 0x7D, 0x57, 0xBE, + 0xF0, 0xE8, 0x6E, 0xC2, 0x79, 0xB2, 0x3A, 0x0B, 0x55, 0xE2, 0x50, 0x98, + 0x16, 0x32, 0x13, 0x5C, 0x2F, 0x78, 0x56, 0xC1, 0xC2, 0x94, 0xB3, 0xF2, + 0x5A, 0xE4, 0x27, 0x9A, 0x9F, 0x24, 0xD7, 0xC6, 0xEC, 0xD0, 0x9B, 0x25, + 0x82, 0xE3, 0xCC, 0xC2, 0xC4, 0x45, 0xC5, 0x8C, 0x97, 0x7A, 0x06, 0x6B, + 0x2A, 0x11, 0x9F, 0xA9, 0x0A, 0x6E, 0x48, 0x3B, 0x6F, 0xDB, 0xD4, 0x11, + 0x19, 0x42, 0xF7, 0x8F, 0x07, 0xBF, 0xF5, 0x53, 0x5F, 0x9C, 0x3E, 0xF4, + 0x17, 0x2C, 0xE6, 0x69, 0xAC, 0x4E, 0x32, 0x4C, 0x62, 0x77, 0xEA, 0xB7, + 0xE8, 0xE5, 0xBB, 0x34, 0xBC, 0x19, 0x8B, 0xAE, 0x9C, 0x51, 0xE7, 0xB7, + 0x7E, 0xB5, 0x53, 0xB1, 0x33, 0x22, 0xE5, 0x6D, 0xCF, 0x70, 0x3C, 0x1A, + 0xFA, 0xE2, 0x9B, 0x67, 0xB6, 0x83, 0xF4, 0x8D, 0xA5, 0xAF, 0x62, 0x4C, + 0x4D, 0xE0, 0x58, 0xAC, 0x64, 0x34, 0x12, 0x03, 0xF8, 0xB6, 0x8D, 0x94, + 0x63, 0x24, 0xA4, 0x71 +}; + +static const unsigned char TA452_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA453_DN[] = { + 0x30, 0x6E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x13, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, 0x6F, 0x66, 0x65, + 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x53, 0x41, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0F, 0x56, 0x41, 0x54, 0x45, + 0x53, 0x2D, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x46, 0x49, + 0x52, 0x4D, 0x41, 0x50, 0x52, 0x4F, 0x46, 0x45, 0x53, 0x49, 0x4F, 0x4E, + 0x41, 0x4C, 0x20, 0x43, 0x41, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x2D, 0x41, + 0x20, 0x57, 0x45, 0x42 +}; + +static const unsigned char TA453_EC_Q[] = { + 0x04, 0x47, 0x53, 0xEA, 0x2C, 0x11, 0xA4, 0x77, 0xC7, 0x2A, 0xEA, 0xF3, + 0xD6, 0x5F, 0x7B, 0xD3, 0x04, 0x91, 0x5C, 0xFA, 0x88, 0xC6, 0x22, 0xB9, + 0x83, 0x10, 0x62, 0x77, 0x84, 0x33, 0x2D, 0xE9, 0x03, 0x88, 0xD4, 0xE0, + 0x33, 0xF7, 0xED, 0x77, 0x2C, 0x4A, 0x60, 0xEA, 0xE4, 0x6F, 0xAD, 0x6D, + 0xB4, 0xF8, 0x4C, 0x8A, 0xA4, 0xE4, 0x1F, 0xCA, 0xEA, 0x4F, 0x38, 0x4A, + 0x2E, 0x82, 0x73, 0x2B, 0xC7, 0x66, 0x9B, 0x0A, 0x8C, 0x40, 0x9C, 0x7C, + 0x8A, 0xF6, 0xF2, 0x39, 0x60, 0xB2, 0xDE, 0xCB, 0xEC, 0xB8, 0xE4, 0x6F, + 0xEA, 0x9B, 0x5D, 0xB7, 0x53, 0x90, 0x18, 0x32, 0x55, 0xC5, 0x20, 0xB7, + 0x94 +}; + +static const unsigned char TA454_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x29, 0x47, 0x55, 0x41, 0x4E, 0x47, 0x20, 0x44, 0x4F, 0x4E, 0x47, + 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, + 0x20, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x20, 0x43, + 0x4F, 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x47, 0x44, 0x43, 0x41, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x41, 0x55, 0x54, 0x48, 0x20, 0x52, 0x35, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA454_RSA_N[] = { + 0xD9, 0xA3, 0x16, 0xF0, 0xC8, 0x74, 0x74, 0x77, 0x9B, 0xEF, 0x33, 0x0D, + 0x3B, 0x06, 0x7E, 0x55, 0xFC, 0xB5, 0x60, 0x8F, 0x76, 0x86, 0x12, 0x42, + 0x7D, 0x56, 0x66, 0x3E, 0x88, 0x82, 0xED, 0x72, 0x63, 0x0E, 0x9E, 0x8B, + 0xDD, 0x34, 0x2C, 0x02, 0x51, 0x51, 0xC3, 0x19, 0xFD, 0x59, 0x54, 0x84, + 0xC9, 0xF1, 0x6B, 0xB3, 0x4C, 0xB0, 0xE9, 0xE8, 0x46, 0x5D, 0x38, 0xC6, + 0xA2, 0xA7, 0x2E, 0x11, 0x57, 0xBA, 0x82, 0x15, 0xA2, 0x9C, 0x8F, 0x6D, + 0xB0, 0x99, 0x4A, 0x0A, 0xF2, 0xEB, 0x89, 0x70, 0x63, 0x4E, 0x79, 0xC4, + 0xB7, 0x5B, 0xBD, 0xA2, 0x5D, 0xB1, 0xF2, 0x41, 0x02, 0x2B, 0xAD, 0xA9, + 0x3A, 0xA3, 0xEC, 0x79, 0x0A, 0xEC, 0x5F, 0x3A, 0xE3, 0xFD, 0xEF, 0x80, + 0x3C, 0xAD, 0x34, 0x9B, 0x1A, 0xAB, 0x88, 0x26, 0x7B, 0x56, 0xA2, 0x82, + 0x86, 0x1F, 0xEB, 0x35, 0x89, 0x83, 0x7F, 0x5F, 0xAE, 0x29, 0x4E, 0x3D, + 0xB6, 0x6E, 0xEC, 0xAE, 0xC1, 0xF0, 0x27, 0x9B, 0xAE, 0xE3, 0xF4, 0xEC, + 0xEF, 0xAE, 0x7F, 0xF7, 0x86, 0x3D, 0x72, 0x7A, 0xEB, 0xA5, 0xFB, 0x59, + 0x4E, 0xA7, 0xEB, 0x95, 0x8C, 0x22, 0x39, 0x79, 0xE1, 0x2D, 0x08, 0x8F, + 0xCC, 0xBC, 0x91, 0xB8, 0x41, 0xF7, 0x14, 0xC1, 0x23, 0xA9, 0xC3, 0xAD, + 0x9A, 0x45, 0x44, 0xB3, 0xB2, 0xD7, 0x2C, 0xCD, 0xC6, 0x29, 0xE2, 0x50, + 0x10, 0xAE, 0x5C, 0xCB, 0x82, 0x8E, 0x17, 0x18, 0x36, 0x7D, 0x97, 0xE6, + 0x88, 0x9A, 0xB0, 0x4D, 0x34, 0x09, 0xF4, 0x2C, 0xB9, 0x5A, 0x66, 0x2A, + 0xB0, 0x17, 0x9B, 0x9E, 0x1E, 0x76, 0x9D, 0x4A, 0x66, 0x31, 0x41, 0xDF, + 0x3F, 0xFB, 0xC5, 0x06, 0xEF, 0x1B, 0xB6, 0x7E, 0x1A, 0x46, 0x36, 0xF7, + 0x64, 0x63, 0x3B, 0xE3, 0x39, 0x18, 0x23, 0xE7, 0x67, 0x75, 0x14, 0xD5, + 0x75, 0x57, 0x92, 0x37, 0xBD, 0xBE, 0x6A, 0x1B, 0x26, 0x50, 0xF2, 0x36, + 0x26, 0x06, 0x90, 0xC5, 0x70, 0x01, 0x64, 0x6D, 0x76, 0x66, 0xE1, 0x91, + 0xDB, 0x6E, 0x07, 0xC0, 0x61, 0x80, 0x2E, 0xB2, 0x2E, 0x2F, 0x8C, 0x70, + 0xA7, 0xD1, 0x3B, 0x3C, 0xB3, 0x91, 0xE4, 0x6E, 0xB6, 0xC4, 0x3B, 0x70, + 0xF2, 0x6C, 0x92, 0x97, 0x09, 0xCD, 0x47, 0x7D, 0x18, 0xC0, 0xF3, 0xBB, + 0x9E, 0x0F, 0xD6, 0x8B, 0xAE, 0x07, 0xB6, 0x5A, 0x0F, 0xCE, 0x0B, 0x0C, + 0x47, 0xA7, 0xE5, 0x3E, 0xB8, 0xBD, 0x7D, 0xC7, 0x9B, 0x35, 0xA0, 0x61, + 0x97, 0x3A, 0x41, 0x75, 0x17, 0xCC, 0x2B, 0x96, 0x77, 0x2A, 0x92, 0x21, + 0x1E, 0xD9, 0x95, 0x76, 0x20, 0x67, 0x68, 0xCF, 0x0D, 0xBD, 0xDF, 0xD6, + 0x1F, 0x09, 0x6A, 0x9A, 0xE2, 0xCC, 0x73, 0x71, 0xA4, 0x2F, 0x7D, 0x12, + 0x80, 0xB7, 0x53, 0x30, 0x46, 0x5E, 0x4B, 0x54, 0x99, 0x0F, 0x67, 0xC9, + 0xA5, 0xC8, 0xF2, 0x20, 0xC1, 0x82, 0xEC, 0x9D, 0x11, 0xDF, 0xC2, 0x02, + 0xFB, 0x1A, 0x3B, 0xD1, 0xED, 0x20, 0x9A, 0xEF, 0x65, 0x64, 0x92, 0x10, + 0x0D, 0x2A, 0xE2, 0xDE, 0x70, 0xF1, 0x18, 0x67, 0x82, 0x8C, 0x61, 0xDE, + 0xB8, 0xBC, 0xD1, 0x2F, 0x9C, 0xFB, 0x0F, 0xD0, 0x2B, 0xED, 0x1B, 0x76, + 0xB9, 0xE4, 0x39, 0x55, 0xF8, 0xF8, 0xA1, 0x1D, 0xB8, 0xAA, 0x80, 0x00, + 0x4C, 0x82, 0xE7, 0xB2, 0x7F, 0x09, 0xB8, 0xBC, 0x30, 0xA0, 0x2F, 0x0D, + 0xF5, 0x52, 0x9E, 0x8E, 0xF7, 0x92, 0xB3, 0x0A, 0x00, 0x1D, 0x00, 0x54, + 0x97, 0x06, 0xE0, 0xB1, 0x07, 0xD9, 0xC7, 0x0F, 0x5C, 0x65, 0x7D, 0x3C, + 0x6D, 0x59, 0x57, 0xE4, 0xED, 0xA5, 0x8D, 0xE9, 0x40, 0x53, 0x9F, 0x15, + 0x4B, 0xA0, 0x71, 0xF6, 0x1A, 0x21, 0xE3, 0xDA, 0x70, 0x06, 0x21, 0x58, + 0x14, 0x87, 0x85, 0x77, 0x79, 0xAA, 0x82, 0x79 +}; + +static const unsigned char TA454_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA455_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x41, 0x54, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x65, 0x2D, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x65, + 0x20, 0x6D, 0x6F, 0x6E, 0x69, 0x74, 0x6F, 0x72, 0x69, 0x6E, 0x67, 0x20, + 0x47, 0x6D, 0x62, 0x48, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x10, 0x47, 0x4C, 0x4F, 0x42, 0x41, 0x4C, 0x54, 0x52, 0x55, + 0x53, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA455_RSA_N[] = { + 0xAE, 0x2E, 0x56, 0xAD, 0x1B, 0x1C, 0xEF, 0xF6, 0x95, 0x8F, 0xA0, 0x77, + 0x1B, 0x2B, 0xD3, 0x63, 0x8F, 0x84, 0x4D, 0x45, 0xA2, 0x0F, 0x9F, 0x5B, + 0x45, 0xAB, 0x59, 0x7B, 0x51, 0x34, 0xF9, 0xEC, 0x8B, 0x8A, 0x78, 0xC5, + 0xDD, 0x6B, 0xAF, 0xBD, 0xC4, 0xDF, 0x93, 0x45, 0x1E, 0xBF, 0x91, 0x38, + 0x0B, 0xAE, 0x0E, 0x16, 0xE7, 0x41, 0x73, 0xF8, 0xDB, 0xBB, 0xD1, 0xB8, + 0x51, 0xE0, 0xCB, 0x83, 0x3B, 0x73, 0x38, 0x6E, 0x77, 0x8A, 0x0F, 0x59, + 0x63, 0x26, 0xCD, 0xA7, 0x2A, 0xCE, 0x54, 0xFB, 0xB8, 0xE2, 0xC0, 0x7C, + 0x47, 0xCE, 0x60, 0x7C, 0x3F, 0xB2, 0x73, 0xF2, 0xC0, 0x19, 0xB6, 0x8A, + 0x92, 0x87, 0x35, 0x0D, 0x90, 0x28, 0xA2, 0xE4, 0x15, 0x04, 0x63, 0x3E, + 0xBA, 0xAF, 0xEE, 0x7C, 0x5E, 0xCC, 0xA6, 0x8B, 0x50, 0xB2, 0x38, 0xF7, + 0x41, 0x63, 0xCA, 0xCE, 0xFF, 0x69, 0x8F, 0x68, 0x0E, 0x95, 0x36, 0xE5, + 0xCC, 0xB9, 0x8C, 0x09, 0xCA, 0x4B, 0xDD, 0x31, 0x90, 0x96, 0xC8, 0xCC, + 0x1F, 0xFD, 0x56, 0x96, 0x34, 0xDB, 0x8E, 0x1C, 0xEA, 0x2C, 0xBE, 0x85, + 0x2E, 0x63, 0xDD, 0xAA, 0xA9, 0x95, 0xD3, 0xFD, 0x29, 0x95, 0x13, 0xF0, + 0xC8, 0x98, 0x93, 0xD9, 0x2D, 0x16, 0x47, 0x90, 0x11, 0x83, 0xA2, 0x3A, + 0x22, 0xA2, 0x28, 0x57, 0xA2, 0xEB, 0xFE, 0xC0, 0x8C, 0x28, 0xA0, 0xA6, + 0x7D, 0xE7, 0x2A, 0x42, 0x3B, 0x82, 0x80, 0x63, 0xA5, 0x63, 0x1F, 0x19, + 0xCC, 0x7C, 0xB2, 0x66, 0xA8, 0xC2, 0xD3, 0x6D, 0x37, 0x6F, 0xE2, 0x7E, + 0x06, 0x51, 0xD9, 0x45, 0x84, 0x1F, 0x12, 0xCE, 0x24, 0x52, 0x64, 0x85, + 0x0B, 0x48, 0x80, 0x4E, 0x87, 0xB1, 0x22, 0x22, 0x30, 0xAA, 0xEB, 0xAE, + 0xBE, 0xE0, 0x02, 0xE0, 0x40, 0xE8, 0xB0, 0x42, 0x80, 0x03, 0x51, 0xAA, + 0xB4, 0x7E, 0xAA, 0x44, 0xD7, 0x43, 0x61, 0xF3, 0xA2, 0x6B, 0x16, 0x89, + 0x49, 0xA4, 0xA3, 0xA4, 0x2B, 0x8A, 0x02, 0xC4, 0x78, 0xF4, 0x68, 0x8A, + 0xC1, 0xE4, 0x7A, 0x36, 0xB1, 0x6F, 0x1B, 0x96, 0x1B, 0x77, 0x49, 0x8D, + 0xD4, 0xC9, 0x06, 0x72, 0x8F, 0xCF, 0x53, 0xE3, 0xDC, 0x17, 0x85, 0x20, + 0x4A, 0xDC, 0x98, 0x27, 0xD3, 0x91, 0x26, 0x2B, 0x47, 0x1E, 0x69, 0x07, + 0xAF, 0xDE, 0xA2, 0xE4, 0xE4, 0xD4, 0x6B, 0x0B, 0xB3, 0x5E, 0x7C, 0xD4, + 0x24, 0x80, 0x47, 0x29, 0x69, 0x3B, 0x6E, 0xE8, 0xAC, 0xFD, 0x40, 0xEB, + 0xD8, 0xED, 0x71, 0x71, 0x2B, 0xF2, 0xE8, 0x58, 0x1D, 0xEB, 0x41, 0x97, + 0x22, 0xC5, 0x1F, 0xD4, 0x39, 0xD0, 0x27, 0x8F, 0x87, 0xE3, 0x18, 0xF4, + 0xE0, 0xA9, 0x46, 0x0D, 0xF5, 0x74, 0x3A, 0x82, 0x2E, 0xD0, 0x6E, 0x2C, + 0x91, 0xA3, 0x31, 0x5C, 0x3B, 0x46, 0xEA, 0x7B, 0x04, 0x10, 0x56, 0x5E, + 0x80, 0x1D, 0xF5, 0xA5, 0x65, 0xE8, 0x82, 0xFC, 0xE2, 0x07, 0x8C, 0x62, + 0x45, 0xF5, 0x20, 0xDE, 0x46, 0x70, 0x86, 0xA1, 0xBC, 0x93, 0xD3, 0x1E, + 0x74, 0xA6, 0x6C, 0xB0, 0x2C, 0xF7, 0x03, 0x0C, 0x88, 0x0C, 0xCB, 0xD4, + 0x72, 0x53, 0x86, 0xBC, 0x60, 0x46, 0xF3, 0x98, 0x6A, 0xC2, 0xF1, 0xBF, + 0x43, 0xF9, 0x70, 0x20, 0x77, 0xCA, 0x37, 0x41, 0x79, 0x55, 0x52, 0x63, + 0x8D, 0x5B, 0x12, 0x9F, 0xC5, 0x68, 0xC4, 0x88, 0x9D, 0xAC, 0xF2, 0x30, + 0xAB, 0xB7, 0xA3, 0x31, 0x97, 0x67, 0xAD, 0x8F, 0x17, 0x0F, 0x6C, 0xC7, + 0x73, 0xED, 0x24, 0x94, 0x6B, 0xC8, 0x83, 0x9A, 0xD0, 0x9A, 0x37, 0x49, + 0x04, 0xAB, 0xB1, 0x16, 0xC8, 0x6C, 0x49, 0x49, 0x2D, 0xAB, 0xA1, 0xD0, + 0x8C, 0x92, 0xF2, 0x41, 0x4A, 0x79, 0x21, 0x25, 0xDB, 0x63, 0xD7, 0xB6, + 0x9C, 0xA7, 0x7E, 0x42, 0x69, 0xFB, 0x3A, 0x63 +}; + +static const unsigned char TA455_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA456_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x31 +}; + +static const unsigned char TA456_RSA_N[] = { + 0xB6, 0x11, 0x02, 0x8B, 0x1E, 0xE3, 0xA1, 0x77, 0x9B, 0x3B, 0xDC, 0xBF, + 0x94, 0x3E, 0xB7, 0x95, 0xA7, 0x40, 0x3C, 0xA1, 0xFD, 0x82, 0xF9, 0x7D, + 0x32, 0x06, 0x82, 0x71, 0xF6, 0xF6, 0x8C, 0x7F, 0xFB, 0xE8, 0xDB, 0xBC, + 0x6A, 0x2E, 0x97, 0x97, 0xA3, 0x8C, 0x4B, 0xF9, 0x2B, 0xF6, 0xB1, 0xF9, + 0xCE, 0x84, 0x1D, 0xB1, 0xF9, 0xC5, 0x97, 0xDE, 0xEF, 0xB9, 0xF2, 0xA3, + 0xE9, 0xBC, 0x12, 0x89, 0x5E, 0xA7, 0xAA, 0x52, 0xAB, 0xF8, 0x23, 0x27, + 0xCB, 0xA4, 0xB1, 0x9C, 0x63, 0xDB, 0xD7, 0x99, 0x7E, 0xF0, 0x0A, 0x5E, + 0xEB, 0x68, 0xA6, 0xF4, 0xC6, 0x5A, 0x47, 0x0D, 0x4D, 0x10, 0x33, 0xE3, + 0x4E, 0xB1, 0x13, 0xA3, 0xC8, 0x18, 0x6C, 0x4B, 0xEC, 0xFC, 0x09, 0x90, + 0xDF, 0x9D, 0x64, 0x29, 0x25, 0x23, 0x07, 0xA1, 0xB4, 0xD2, 0x3D, 0x2E, + 0x60, 0xE0, 0xCF, 0xD2, 0x09, 0x87, 0xBB, 0xCD, 0x48, 0xF0, 0x4D, 0xC2, + 0xC2, 0x7A, 0x88, 0x8A, 0xBB, 0xBA, 0xCF, 0x59, 0x19, 0xD6, 0xAF, 0x8F, + 0xB0, 0x07, 0xB0, 0x9E, 0x31, 0xF1, 0x82, 0xC1, 0xC0, 0xDF, 0x2E, 0xA6, + 0x6D, 0x6C, 0x19, 0x0E, 0xB5, 0xD8, 0x7E, 0x26, 0x1A, 0x45, 0x03, 0x3D, + 0xB0, 0x79, 0xA4, 0x94, 0x28, 0xAD, 0x0F, 0x7F, 0x26, 0xE5, 0xA8, 0x08, + 0xFE, 0x96, 0xE8, 0x3C, 0x68, 0x94, 0x53, 0xEE, 0x83, 0x3A, 0x88, 0x2B, + 0x15, 0x96, 0x09, 0xB2, 0xE0, 0x7A, 0x8C, 0x2E, 0x75, 0xD6, 0x9C, 0xEB, + 0xA7, 0x56, 0x64, 0x8F, 0x96, 0x4F, 0x68, 0xAE, 0x3D, 0x97, 0xC2, 0x84, + 0x8F, 0xC0, 0xBC, 0x40, 0xC0, 0x0B, 0x5C, 0xBD, 0xF6, 0x87, 0xB3, 0x35, + 0x6C, 0xAC, 0x18, 0x50, 0x7F, 0x84, 0xE0, 0x4C, 0xCD, 0x92, 0xD3, 0x20, + 0xE9, 0x33, 0xBC, 0x52, 0x99, 0xAF, 0x32, 0xB5, 0x29, 0xB3, 0x25, 0x2A, + 0xB4, 0x48, 0xF9, 0x72, 0xE1, 0xCA, 0x64, 0xF7, 0xE6, 0x82, 0x10, 0x8D, + 0xE8, 0x9D, 0xC2, 0x8A, 0x88, 0xFA, 0x38, 0x66, 0x8A, 0xFC, 0x63, 0xF9, + 0x01, 0xF9, 0x78, 0xFD, 0x7B, 0x5C, 0x77, 0xFA, 0x76, 0x87, 0xFA, 0xEC, + 0xDF, 0xB1, 0x0E, 0x79, 0x95, 0x57, 0xB4, 0xBD, 0x26, 0xEF, 0xD6, 0x01, + 0xD1, 0xEB, 0x16, 0x0A, 0xBB, 0x8E, 0x0B, 0xB5, 0xC5, 0xC5, 0x8A, 0x55, + 0xAB, 0xD3, 0xAC, 0xEA, 0x91, 0x4B, 0x29, 0xCC, 0x19, 0xA4, 0x32, 0x25, + 0x4E, 0x2A, 0xF1, 0x65, 0x44, 0xD0, 0x02, 0xCE, 0xAA, 0xCE, 0x49, 0xB4, + 0xEA, 0x9F, 0x7C, 0x83, 0xB0, 0x40, 0x7B, 0xE7, 0x43, 0xAB, 0xA7, 0x6C, + 0xA3, 0x8F, 0x7D, 0x89, 0x81, 0xFA, 0x4C, 0xA5, 0xFF, 0xD5, 0x8E, 0xC3, + 0xCE, 0x4B, 0xE0, 0xB5, 0xD8, 0xB3, 0x8E, 0x45, 0xCF, 0x76, 0xC0, 0xED, + 0x40, 0x2B, 0xFD, 0x53, 0x0F, 0xB0, 0xA7, 0xD5, 0x3B, 0x0D, 0xB1, 0x8A, + 0xA2, 0x03, 0xDE, 0x31, 0xAD, 0xCC, 0x77, 0xEA, 0x6F, 0x7B, 0x3E, 0xD6, + 0xDF, 0x91, 0x22, 0x12, 0xE6, 0xBE, 0xFA, 0xD8, 0x32, 0xFC, 0x10, 0x63, + 0x14, 0x51, 0x72, 0xDE, 0x5D, 0xD6, 0x16, 0x93, 0xBD, 0x29, 0x68, 0x33, + 0xEF, 0x3A, 0x66, 0xEC, 0x07, 0x8A, 0x26, 0xDF, 0x13, 0xD7, 0x57, 0x65, + 0x78, 0x27, 0xDE, 0x5E, 0x49, 0x14, 0x00, 0xA2, 0x00, 0x7F, 0x9A, 0xA8, + 0x21, 0xB6, 0xA9, 0xB1, 0x95, 0xB0, 0xA5, 0xB9, 0x0D, 0x16, 0x11, 0xDA, + 0xC7, 0x6C, 0x48, 0x3C, 0x40, 0xE0, 0x7E, 0x0D, 0x5A, 0xCD, 0x56, 0x3C, + 0xD1, 0x97, 0x05, 0xB9, 0xCB, 0x4B, 0xED, 0x39, 0x4B, 0x9C, 0xC4, 0x3F, + 0xD2, 0x55, 0x13, 0x6E, 0x24, 0xB0, 0xD6, 0x71, 0xFA, 0xF4, 0xC1, 0xBA, + 0xCC, 0xED, 0x1B, 0xF5, 0xFE, 0x81, 0x41, 0xD8, 0x00, 0x98, 0x3D, 0x3A, + 0xC8, 0xAE, 0x7A, 0x98, 0x37, 0x18, 0x05, 0x95 +}; + +static const unsigned char TA456_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA457_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA457_RSA_N[] = { + 0xCE, 0xDE, 0xFD, 0xA6, 0xFB, 0xEC, 0xEC, 0x14, 0x34, 0x3C, 0x07, 0x06, + 0x5A, 0x6C, 0x59, 0xF7, 0x19, 0x35, 0xDD, 0xF7, 0xC1, 0x9D, 0x55, 0xAA, + 0xD3, 0xCD, 0x3B, 0xA4, 0x93, 0x72, 0xEF, 0x0A, 0xFA, 0x6D, 0x9D, 0xF6, + 0xF0, 0x85, 0x80, 0x5B, 0xA1, 0x48, 0x52, 0x9F, 0x39, 0xC5, 0xB7, 0xEE, + 0x28, 0xAC, 0xEF, 0xCB, 0x76, 0x68, 0x14, 0xB9, 0xDF, 0xAD, 0x01, 0x6C, + 0x99, 0x1F, 0xC4, 0x22, 0x1D, 0x9F, 0xFE, 0x72, 0x77, 0xE0, 0x2C, 0x5B, + 0xAF, 0xE4, 0x04, 0xBF, 0x4F, 0x72, 0xA0, 0x1A, 0x34, 0x98, 0xE8, 0x39, + 0x68, 0xEC, 0x95, 0x25, 0x7B, 0x76, 0xA1, 0xE6, 0x69, 0xB9, 0x85, 0x19, + 0xBD, 0x89, 0x8C, 0xFE, 0xAD, 0xED, 0x36, 0xEA, 0x73, 0xBC, 0xFF, 0x83, + 0xE2, 0xCB, 0x7D, 0xC1, 0xD2, 0xCE, 0x4A, 0xB3, 0x8D, 0x05, 0x9E, 0x8B, + 0x49, 0x93, 0xDF, 0xC1, 0x5B, 0xD0, 0x6E, 0x5E, 0xF0, 0x2E, 0x30, 0x2E, + 0x82, 0xFC, 0xFA, 0xBC, 0xB4, 0x17, 0x0A, 0x48, 0xE5, 0x88, 0x9B, 0xC5, + 0x9B, 0x6B, 0xDE, 0xB0, 0xCA, 0xB4, 0x03, 0xF0, 0xDA, 0xF4, 0x90, 0xB8, + 0x65, 0x64, 0xF7, 0x5C, 0x4C, 0xAD, 0xE8, 0x7E, 0x66, 0x5E, 0x99, 0xD7, + 0xB8, 0xC2, 0x3E, 0xC8, 0xD0, 0x13, 0x9D, 0xAD, 0xEE, 0xE4, 0x45, 0x7B, + 0x89, 0x55, 0xF7, 0x8A, 0x1F, 0x62, 0x52, 0x84, 0x12, 0xB3, 0xC2, 0x40, + 0x97, 0xE3, 0x8A, 0x1F, 0x47, 0x91, 0xA6, 0x74, 0x5A, 0xD2, 0xF8, 0xB1, + 0x63, 0x28, 0x10, 0xB8, 0xB3, 0x09, 0xB8, 0x56, 0x77, 0x40, 0xA2, 0x26, + 0x98, 0x79, 0xC6, 0xFE, 0xDF, 0x25, 0xEE, 0x3E, 0xE5, 0xA0, 0x7F, 0xD4, + 0x61, 0x0F, 0x51, 0x4B, 0x3C, 0x3F, 0x8C, 0xDA, 0xE1, 0x70, 0x74, 0xD8, + 0xC2, 0x68, 0xA1, 0xF9, 0xC1, 0x0C, 0xE9, 0xA1, 0xE2, 0x7F, 0xBB, 0x55, + 0x3C, 0x76, 0x06, 0xEE, 0x6A, 0x4E, 0xCC, 0x92, 0x88, 0x30, 0x4D, 0x9A, + 0xBD, 0x4F, 0x0B, 0x48, 0x9A, 0x84, 0xB5, 0x98, 0xA3, 0xD5, 0xFB, 0x73, + 0xC1, 0x57, 0x61, 0xDD, 0x28, 0x56, 0x75, 0x13, 0xAE, 0x87, 0x8E, 0xE7, + 0x0C, 0x51, 0x09, 0x10, 0x75, 0x88, 0x4C, 0xBC, 0x8D, 0xF9, 0x7B, 0x3C, + 0xD4, 0x22, 0x48, 0x1F, 0x2A, 0xDC, 0xEB, 0x6B, 0xBB, 0x44, 0xB1, 0xCB, + 0x33, 0x71, 0x32, 0x46, 0xAF, 0xAD, 0x4A, 0xF1, 0x8C, 0xE8, 0x74, 0x3A, + 0xAC, 0xE7, 0x1A, 0x22, 0x73, 0x80, 0xD2, 0x30, 0xF7, 0x25, 0x42, 0xC7, + 0x22, 0x3B, 0x3B, 0x12, 0xAD, 0x96, 0x2E, 0xC6, 0xC3, 0x76, 0x07, 0xAA, + 0x20, 0xB7, 0x35, 0x49, 0x57, 0xE9, 0x92, 0x49, 0xE8, 0x76, 0x16, 0x72, + 0x31, 0x67, 0x2B, 0x96, 0x7E, 0x8A, 0xA3, 0xC7, 0x94, 0x56, 0x22, 0xBF, + 0x6A, 0x4B, 0x7E, 0x01, 0x21, 0xB2, 0x23, 0x32, 0xDF, 0xE4, 0x9A, 0x44, + 0x6D, 0x59, 0x5B, 0x5D, 0xF5, 0x00, 0xA0, 0x1C, 0x9B, 0xC6, 0x78, 0x97, + 0x8D, 0x90, 0xFF, 0x9B, 0xC8, 0xAA, 0xB4, 0xAF, 0x11, 0x51, 0x39, 0x5E, + 0xD9, 0xFB, 0x67, 0xAD, 0xD5, 0x5B, 0x11, 0x9D, 0x32, 0x9A, 0x1B, 0xBD, + 0xD5, 0xBA, 0x5B, 0xA5, 0xC9, 0xCB, 0x25, 0x69, 0x53, 0x55, 0x27, 0x5C, + 0xE0, 0xCA, 0x36, 0xCB, 0x88, 0x61, 0xFB, 0x1E, 0xB7, 0xD0, 0xCB, 0xEE, + 0x16, 0xFB, 0xD3, 0xA6, 0x4C, 0xDE, 0x92, 0xA5, 0xD4, 0xE2, 0xDF, 0xF5, + 0x06, 0x54, 0xDE, 0x2E, 0x9D, 0x4B, 0xB4, 0x93, 0x30, 0xAA, 0x81, 0xCE, + 0xDD, 0x1A, 0xDC, 0x51, 0x73, 0x0D, 0x4F, 0x70, 0xE9, 0xE5, 0xB6, 0x16, + 0x21, 0x19, 0x79, 0xB2, 0xE6, 0x89, 0x0B, 0x75, 0x64, 0xCA, 0xD5, 0xAB, + 0xBC, 0x09, 0xC1, 0x18, 0xA1, 0xFF, 0xD4, 0x54, 0xA1, 0x85, 0x3C, 0xFD, + 0x14, 0x24, 0x03, 0xB2, 0x87, 0xD3, 0xA4, 0xB7 +}; + +static const unsigned char TA457_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA458_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x33 +}; + +static const unsigned char TA458_EC_Q[] = { + 0x04, 0x1F, 0x4F, 0x33, 0x87, 0x33, 0x29, 0x8A, 0xA1, 0x84, 0xDE, 0xCB, + 0xC7, 0x21, 0x58, 0x41, 0x89, 0xEA, 0x56, 0x9D, 0x2B, 0x4B, 0x85, 0xC6, + 0x1D, 0x4C, 0x27, 0xBC, 0x7F, 0x26, 0x51, 0x72, 0x6F, 0xE2, 0x9F, 0xD6, + 0xA3, 0xCA, 0xCC, 0x45, 0x14, 0x46, 0x8B, 0xAD, 0xEF, 0x7E, 0x86, 0x8C, + 0xEC, 0xB1, 0x7E, 0x2F, 0xFF, 0xA9, 0x71, 0x9D, 0x18, 0x84, 0x45, 0x04, + 0x41, 0x55, 0x6E, 0x2B, 0xEA, 0x26, 0x7F, 0xBB, 0x90, 0x01, 0xE3, 0x4B, + 0x19, 0xBA, 0xE4, 0x54, 0x96, 0x45, 0x09, 0xB1, 0xD5, 0x6C, 0x91, 0x44, + 0xAD, 0x84, 0x13, 0x8E, 0x9A, 0x8C, 0x0D, 0x80, 0x0C, 0x32, 0xF6, 0xE0, + 0x27 +}; + +static const unsigned char TA459_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x34 +}; + +static const unsigned char TA459_EC_Q[] = { + 0x04, 0xF3, 0x74, 0x73, 0xA7, 0x68, 0x8B, 0x60, 0xAE, 0x43, 0xB8, 0x35, + 0xC5, 0x81, 0x30, 0x7B, 0x4B, 0x49, 0x9D, 0xFB, 0xC1, 0x61, 0xCE, 0xE6, + 0xDE, 0x46, 0xBD, 0x6B, 0xD5, 0x61, 0x18, 0x35, 0xAE, 0x40, 0xDD, 0x73, + 0xF7, 0x89, 0x91, 0x30, 0x5A, 0xEB, 0x3C, 0xEE, 0x85, 0x7C, 0xA2, 0x40, + 0x76, 0x3B, 0xA9, 0xC6, 0xB8, 0x47, 0xD8, 0x2A, 0xE7, 0x92, 0x91, 0x6A, + 0x73, 0xE9, 0xB1, 0x72, 0x39, 0x9F, 0x29, 0x9F, 0xA2, 0x98, 0xD3, 0x5F, + 0x5E, 0x58, 0x86, 0x65, 0x0F, 0xA1, 0x84, 0x65, 0x06, 0xD1, 0xDC, 0x8B, + 0xC9, 0xC7, 0x73, 0xC8, 0x8C, 0x6A, 0x2F, 0xE5, 0xC4, 0xAB, 0xD1, 0x1D, + 0x8A +}; + +static const unsigned char TA460_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x34, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA460_EC_Q[] = { + 0x04, 0xB8, 0xC6, 0x79, 0xD3, 0x8F, 0x6C, 0x25, 0x0E, 0x9F, 0x2E, 0x39, + 0x19, 0x1C, 0x03, 0xA4, 0xAE, 0x9A, 0xE5, 0x39, 0x07, 0x09, 0x16, 0xCA, + 0x63, 0xB1, 0xB9, 0x86, 0xF8, 0x8A, 0x57, 0xC1, 0x57, 0xCE, 0x42, 0xFA, + 0x73, 0xA1, 0xF7, 0x65, 0x42, 0xFF, 0x1E, 0xC1, 0x00, 0xB2, 0x6E, 0x73, + 0x0E, 0xFF, 0xC7, 0x21, 0xE5, 0x18, 0xA4, 0xAA, 0xD9, 0x71, 0x3F, 0xA8, + 0xD4, 0xB9, 0xCE, 0x8C, 0x1D +}; + +static const unsigned char TA461_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x35, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA461_EC_Q[] = { + 0x04, 0x47, 0x45, 0x0E, 0x96, 0xFB, 0x7D, 0x5D, 0xBF, 0xE9, 0x39, 0xD1, + 0x21, 0xF8, 0x9F, 0x0B, 0xB6, 0xD5, 0x7B, 0x1E, 0x92, 0x3A, 0x48, 0x59, + 0x1C, 0xF0, 0x62, 0x31, 0x2D, 0xC0, 0x7A, 0x28, 0xFE, 0x1A, 0xA7, 0x5C, + 0xB3, 0xB6, 0xCC, 0x97, 0xE7, 0x45, 0xD4, 0x58, 0xFA, 0xD1, 0x77, 0x6D, + 0x43, 0xA2, 0xC0, 0x87, 0x65, 0x34, 0x0A, 0x1F, 0x7A, 0xDD, 0xEB, 0x3C, + 0x33, 0xA1, 0xC5, 0x9D, 0x4D, 0xA4, 0x6F, 0x41, 0x95, 0x38, 0x7F, 0xC9, + 0x1E, 0x84, 0xEB, 0xD1, 0x9E, 0x49, 0x92, 0x87, 0x94, 0x87, 0x0C, 0x3A, + 0x85, 0x4A, 0x66, 0x9F, 0x9D, 0x59, 0x93, 0x4D, 0x97, 0x61, 0x06, 0x86, + 0x4A +}; + +static const unsigned char TA462_DN[] = { + 0x30, 0x57, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, + 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA462_RSA_N[] = { + 0xDA, 0x0E, 0xE6, 0x99, 0x8D, 0xCE, 0xA3, 0xE3, 0x4F, 0x8A, 0x7E, 0xFB, + 0xF1, 0x8B, 0x83, 0x25, 0x6B, 0xEA, 0x48, 0x1F, 0xF1, 0x2A, 0xB0, 0xB9, + 0x95, 0x11, 0x04, 0xBD, 0xF0, 0x63, 0xD1, 0xE2, 0x67, 0x66, 0xCF, 0x1C, + 0xDD, 0xCF, 0x1B, 0x48, 0x2B, 0xEE, 0x8D, 0x89, 0x8E, 0x9A, 0xAF, 0x29, + 0x80, 0x65, 0xAB, 0xE9, 0xC7, 0x2D, 0x12, 0xCB, 0xAB, 0x1C, 0x4C, 0x70, + 0x07, 0xA1, 0x3D, 0x0A, 0x30, 0xCD, 0x15, 0x8D, 0x4F, 0xF8, 0xDD, 0xD4, + 0x8C, 0x50, 0x15, 0x1C, 0xEF, 0x50, 0xEE, 0xC4, 0x2E, 0xF7, 0xFC, 0xE9, + 0x52, 0xF2, 0x91, 0x7D, 0xE0, 0x6D, 0xD5, 0x35, 0x30, 0x8E, 0x5E, 0x43, + 0x73, 0xF2, 0x41, 0xE9, 0xD5, 0x6A, 0xE3, 0xB2, 0x89, 0x3A, 0x56, 0x39, + 0x38, 0x6F, 0x06, 0x3C, 0x88, 0x69, 0x5B, 0x2A, 0x4D, 0xC5, 0xA7, 0x54, + 0xB8, 0x6C, 0x89, 0xCC, 0x9B, 0xF9, 0x3C, 0xCA, 0xE5, 0xFD, 0x89, 0xF5, + 0x12, 0x3C, 0x92, 0x78, 0x96, 0xD6, 0xDC, 0x74, 0x6E, 0x93, 0x44, 0x61, + 0xD1, 0x8D, 0xC7, 0x46, 0xB2, 0x75, 0x0E, 0x86, 0xE8, 0x19, 0x8A, 0xD5, + 0x6D, 0x6C, 0xD5, 0x78, 0x16, 0x95, 0xA2, 0xE9, 0xC8, 0x0A, 0x38, 0xEB, + 0xF2, 0x24, 0x13, 0x4F, 0x73, 0x54, 0x93, 0x13, 0x85, 0x3A, 0x1B, 0xBC, + 0x1E, 0x34, 0xB5, 0x8B, 0x05, 0x8C, 0xB9, 0x77, 0x8B, 0xB1, 0xDB, 0x1F, + 0x20, 0x91, 0xAB, 0x09, 0x53, 0x6E, 0x90, 0xCE, 0x7B, 0x37, 0x74, 0xB9, + 0x70, 0x47, 0x91, 0x22, 0x51, 0x63, 0x16, 0x79, 0xAE, 0xB1, 0xAE, 0x41, + 0x26, 0x08, 0xC8, 0x19, 0x2B, 0xD1, 0x46, 0xAA, 0x48, 0xD6, 0x64, 0x2A, + 0xD7, 0x83, 0x34, 0xFF, 0x2C, 0x2A, 0xC1, 0x6C, 0x19, 0x43, 0x4A, 0x07, + 0x85, 0xE7, 0xD3, 0x7C, 0xF6, 0x21, 0x68, 0xEF, 0xEA, 0xF2, 0x52, 0x9F, + 0x7F, 0x93, 0x90, 0xCF +}; + +static const unsigned char TA462_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA463_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x33, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA463_RSA_N[] = { + 0xCC, 0x25, 0x76, 0x90, 0x79, 0x06, 0x78, 0x22, 0x16, 0xF5, 0xC0, 0x83, + 0xB6, 0x84, 0xCA, 0x28, 0x9E, 0xFD, 0x05, 0x76, 0x11, 0xC5, 0xAD, 0x88, + 0x72, 0xFC, 0x46, 0x02, 0x43, 0xC7, 0xB2, 0x8A, 0x9D, 0x04, 0x5F, 0x24, + 0xCB, 0x2E, 0x4B, 0xE1, 0x60, 0x82, 0x46, 0xE1, 0x52, 0xAB, 0x0C, 0x81, + 0x47, 0x70, 0x6C, 0xDD, 0x64, 0xD1, 0xEB, 0xF5, 0x2C, 0xA3, 0x0F, 0x82, + 0x3D, 0x0C, 0x2B, 0xAE, 0x97, 0xD7, 0xB6, 0x14, 0x86, 0x10, 0x79, 0xBB, + 0x3B, 0x13, 0x80, 0x77, 0x8C, 0x08, 0xE1, 0x49, 0xD2, 0x6A, 0x62, 0x2F, + 0x1F, 0x5E, 0xFA, 0x96, 0x68, 0xDF, 0x89, 0x27, 0x95, 0x38, 0x9F, 0x06, + 0xD7, 0x3E, 0xC9, 0xCB, 0x26, 0x59, 0x0D, 0x73, 0xDE, 0xB0, 0xC8, 0xE9, + 0x26, 0x0E, 0x83, 0x15, 0xC6, 0xEF, 0x5B, 0x8B, 0xD2, 0x04, 0x60, 0xCA, + 0x49, 0xA6, 0x28, 0xF6, 0x69, 0x3B, 0xF6, 0xCB, 0xC8, 0x28, 0x91, 0xE5, + 0x9D, 0x8A, 0x61, 0x57, 0x37, 0xAC, 0x74, 0x14, 0xDC, 0x74, 0xE0, 0x3A, + 0xEE, 0x72, 0x2F, 0x2E, 0x9C, 0xFB, 0xD0, 0xBB, 0xBF, 0xF5, 0x3D, 0x00, + 0xE1, 0x06, 0x33, 0xE8, 0x82, 0x2B, 0xAE, 0x53, 0xA6, 0x3A, 0x16, 0x73, + 0x8C, 0xDD, 0x41, 0x0E, 0x20, 0x3A, 0xC0, 0xB4, 0xA7, 0xA1, 0xE9, 0xB2, + 0x4F, 0x90, 0x2E, 0x32, 0x60, 0xE9, 0x57, 0xCB, 0xB9, 0x04, 0x92, 0x68, + 0x68, 0xE5, 0x38, 0x26, 0x60, 0x75, 0xB2, 0x9F, 0x77, 0xFF, 0x91, 0x14, + 0xEF, 0xAE, 0x20, 0x49, 0xFC, 0xAD, 0x40, 0x15, 0x48, 0xD1, 0x02, 0x31, + 0x61, 0x19, 0x5E, 0xB8, 0x97, 0xEF, 0xAD, 0x77, 0xB7, 0x64, 0x9A, 0x7A, + 0xBF, 0x5F, 0xC1, 0x13, 0xEF, 0x9B, 0x62, 0xFB, 0x0D, 0x6C, 0xE0, 0x54, + 0x69, 0x16, 0xA9, 0x03, 0xDA, 0x6E, 0xE9, 0x83, 0x93, 0x71, 0x76, 0xC6, + 0x69, 0x85, 0x82, 0x17 +}; + +static const unsigned char TA463_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA464_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x36, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA464_RSA_N[] = { + 0x95, 0x07, 0xE8, 0x73, 0xCA, 0x66, 0xF9, 0xEC, 0x14, 0xCA, 0x7B, 0x3C, + 0xF7, 0x0D, 0x08, 0xF1, 0xB4, 0x45, 0x0B, 0x2C, 0x82, 0xB4, 0x48, 0xC6, + 0xEB, 0x5B, 0x3C, 0xAE, 0x83, 0xB8, 0x41, 0x92, 0x33, 0x14, 0xA4, 0x6F, + 0x7F, 0xE9, 0x2A, 0xCC, 0xC6, 0xB0, 0x88, 0x6B, 0xC5, 0xB6, 0x89, 0xD1, + 0xC6, 0xB2, 0xFF, 0x14, 0xCE, 0x51, 0x14, 0x21, 0xEC, 0x4A, 0xDD, 0x1B, + 0x5A, 0xC6, 0xD6, 0x87, 0xEE, 0x4D, 0x3A, 0x15, 0x06, 0xED, 0x64, 0x66, + 0x0B, 0x92, 0x80, 0xCA, 0x44, 0xDE, 0x73, 0x94, 0x4E, 0xF3, 0xA7, 0x89, + 0x7F, 0x4F, 0x78, 0x63, 0x08, 0xC8, 0x12, 0x50, 0x6D, 0x42, 0x66, 0x2F, + 0x4D, 0xB9, 0x79, 0x28, 0x4D, 0x52, 0x1A, 0x8A, 0x1A, 0x80, 0xB7, 0x19, + 0x81, 0x0E, 0x7E, 0xC4, 0x8A, 0xBC, 0x64, 0x4C, 0x21, 0x1C, 0x43, 0x68, + 0xD7, 0x3D, 0x3C, 0x8A, 0xC5, 0xB2, 0x66, 0xD5, 0x90, 0x9A, 0xB7, 0x31, + 0x06, 0xC5, 0xBE, 0xE2, 0x6D, 0x32, 0x06, 0xA6, 0x1E, 0xF9, 0xB9, 0xEB, + 0xAA, 0xA3, 0xB8, 0xBF, 0xBE, 0x82, 0x63, 0x50, 0xD0, 0xF0, 0x18, 0x89, + 0xDF, 0xE4, 0x0F, 0x79, 0xF5, 0xEA, 0xA2, 0x1F, 0x2A, 0xD2, 0x70, 0x2E, + 0x7B, 0xE7, 0xBC, 0x93, 0xBB, 0x6D, 0x53, 0xE2, 0x48, 0x7C, 0x8C, 0x10, + 0x07, 0x38, 0xFF, 0x66, 0xB2, 0x77, 0x61, 0x7E, 0xE0, 0xEA, 0x8C, 0x3C, + 0xAA, 0xB4, 0xA4, 0xF6, 0xF3, 0x95, 0x4A, 0x12, 0x07, 0x6D, 0xFD, 0x8C, + 0xB2, 0x89, 0xCF, 0xD0, 0xA0, 0x61, 0x77, 0xC8, 0x58, 0x74, 0xB0, 0xD4, + 0x23, 0x3A, 0xF7, 0x5D, 0x3A, 0xCA, 0xA2, 0xDB, 0x9D, 0x09, 0xDE, 0x5D, + 0x44, 0x2D, 0x90, 0xF1, 0x81, 0xCD, 0x57, 0x92, 0xFA, 0x7E, 0xBC, 0x50, + 0x04, 0x63, 0x34, 0xDF, 0x6B, 0x93, 0x18, 0xBE, 0x6B, 0x36, 0xB2, 0x39, + 0xE4, 0xAC, 0x24, 0x36, 0xB7, 0xF0, 0xEF, 0xB6, 0x1C, 0x13, 0x57, 0x93, + 0xB6, 0xDE, 0xB2, 0xF8, 0xE2, 0x85, 0xB7, 0x73, 0xA2, 0xB8, 0x35, 0xAA, + 0x45, 0xF2, 0xE0, 0x9D, 0x36, 0xA1, 0x6F, 0x54, 0x8A, 0xF1, 0x72, 0x56, + 0x6E, 0x2E, 0x88, 0xC5, 0x51, 0x42, 0x44, 0x15, 0x94, 0xEE, 0xA3, 0xC5, + 0x38, 0x96, 0x9B, 0x4E, 0x4E, 0x5A, 0x0B, 0x47, 0xF3, 0x06, 0x36, 0x49, + 0x77, 0x30, 0xBC, 0x71, 0x37, 0xE5, 0xA6, 0xEC, 0x21, 0x08, 0x75, 0xFC, + 0xE6, 0x61, 0x16, 0x3F, 0x77, 0xD5, 0xD9, 0x91, 0x97, 0x84, 0x0A, 0x6C, + 0xD4, 0x02, 0x4D, 0x74, 0xC0, 0x14, 0xED, 0xFD, 0x39, 0xFB, 0x83, 0xF2, + 0x5E, 0x14, 0xA1, 0x04, 0xB0, 0x0B, 0xE9, 0xFE, 0xEE, 0x8F, 0xE1, 0x6E, + 0x0B, 0xB2, 0x08, 0xB3, 0x61, 0x66, 0x09, 0x6A, 0xB1, 0x06, 0x3A, 0x65, + 0x96, 0x59, 0xC0, 0xF0, 0x35, 0xFD, 0xC9, 0xDA, 0x28, 0x8D, 0x1A, 0x11, + 0x87, 0x70, 0x81, 0x0A, 0xA8, 0x9A, 0x75, 0x1D, 0x9E, 0x3A, 0x86, 0x05, + 0x00, 0x9E, 0xDB, 0x80, 0xD6, 0x25, 0xF9, 0xDC, 0x05, 0x9E, 0x27, 0x59, + 0x4C, 0x76, 0x39, 0x5B, 0xEA, 0xF9, 0xA5, 0xA1, 0xD8, 0x83, 0x0F, 0xD1, + 0xFF, 0xDF, 0x30, 0x11, 0xF9, 0x85, 0xCF, 0x33, 0x48, 0xF5, 0xCA, 0x6D, + 0x64, 0x14, 0x2C, 0x7A, 0x58, 0x4F, 0xD3, 0x4B, 0x08, 0x49, 0xC5, 0x95, + 0x64, 0x1A, 0x63, 0x0E, 0x79, 0x3D, 0xF5, 0xB3, 0x8C, 0xCA, 0x58, 0xAD, + 0x9C, 0x42, 0x45, 0x79, 0x6E, 0x0E, 0x87, 0x19, 0x5C, 0x54, 0xB1, 0x65, + 0xB6, 0xBF, 0x8C, 0x9B, 0xDC, 0x13, 0xE9, 0x0D, 0x6F, 0xB8, 0x2E, 0xDC, + 0x67, 0x6E, 0xC9, 0x8B, 0x11, 0xB5, 0x84, 0x14, 0x8A, 0x00, 0x19, 0x70, + 0x83, 0x79, 0x91, 0x97, 0x91, 0xD4, 0x1A, 0x27, 0xBF, 0x37, 0x1E, 0x32, + 0x07, 0xD8, 0x14, 0x63, 0x3C, 0x28, 0x4C, 0xAF +}; + +static const unsigned char TA464_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA465_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, 0x36 +}; + +static const unsigned char TA465_EC_Q[] = { + 0x04, 0x9C, 0x0E, 0xB1, 0xCF, 0xB7, 0xE8, 0x9E, 0x52, 0x77, 0x75, 0x34, + 0xFA, 0xA5, 0x46, 0xA7, 0xAD, 0x32, 0x19, 0x32, 0xB4, 0x07, 0xA9, 0x27, + 0xCA, 0x94, 0xBB, 0x0C, 0xD2, 0x0A, 0x10, 0xC7, 0xDA, 0x89, 0xB0, 0x97, + 0x0C, 0x70, 0x13, 0x09, 0x01, 0x8E, 0xD8, 0xEA, 0x47, 0xEA, 0xBE, 0xB2, + 0x80, 0x2B, 0xCD, 0xFC, 0x28, 0x0D, 0xDB, 0xAC, 0xBC, 0xA4, 0x86, 0x37, + 0xED, 0x70, 0x08, 0x00, 0x75, 0xEA, 0x93, 0x0B, 0x7B, 0x2E, 0x52, 0x9C, + 0x23, 0x68, 0x23, 0x06, 0x43, 0xEC, 0x92, 0x2F, 0x53, 0x84, 0xDB, 0xFB, + 0x47, 0x14, 0x07, 0xE8, 0x5F, 0x94, 0x67, 0x5D, 0xC9, 0x7A, 0x81, 0x3C, + 0x20 +}; + +static const unsigned char TA466_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x36 +}; + +static const unsigned char TA466_RSA_N[] = { + 0xAC, 0xAC, 0x74, 0x32, 0xE8, 0xB3, 0x65, 0xE5, 0xBA, 0xED, 0x43, 0x26, + 0x1D, 0xA6, 0x89, 0x0D, 0x45, 0xBA, 0x29, 0x88, 0xB2, 0xA4, 0x1D, 0x63, + 0xDD, 0xD3, 0xC1, 0x2C, 0x09, 0x57, 0x89, 0x39, 0xA1, 0x55, 0xE9, 0x67, + 0x34, 0x77, 0x0C, 0x6E, 0xE4, 0x55, 0x1D, 0x52, 0x25, 0xD2, 0x13, 0x6B, + 0x5E, 0xE1, 0x1D, 0xA9, 0xB7, 0x7D, 0x89, 0x32, 0x5F, 0x0D, 0x9E, 0x9F, + 0x2C, 0x7A, 0x63, 0x60, 0x40, 0x1F, 0xA6, 0xB0, 0xB6, 0x78, 0x8F, 0x99, + 0x54, 0x96, 0x08, 0x58, 0xAE, 0xE4, 0x06, 0xBC, 0x62, 0x05, 0x02, 0x16, + 0xBF, 0xAF, 0xA8, 0x23, 0x03, 0xB6, 0x94, 0x0F, 0xBC, 0x6E, 0x6C, 0xC2, + 0xCB, 0xD5, 0xA6, 0xBB, 0x0C, 0xE9, 0xF6, 0xC1, 0x02, 0xFB, 0x21, 0xDE, + 0x66, 0xDD, 0x17, 0xAB, 0x74, 0x42, 0xEF, 0xF0, 0x74, 0x2F, 0x25, 0xF4, + 0xEA, 0x6B, 0x55, 0x5B, 0x90, 0xDB, 0x9D, 0xDF, 0x5E, 0x87, 0x0A, 0x40, + 0xFB, 0xAD, 0x19, 0x6B, 0xFB, 0xF7, 0xCA, 0x60, 0x88, 0xDE, 0xDA, 0xC1, + 0x8F, 0xD6, 0xAE, 0xD5, 0x7F, 0xD4, 0x3C, 0x83, 0xEE, 0xD7, 0x16, 0x4C, + 0x83, 0x45, 0x33, 0x6B, 0x27, 0xD0, 0x86, 0xD0, 0x1C, 0x2D, 0x6B, 0xF3, + 0xAB, 0x7D, 0xF1, 0x85, 0xA9, 0xF5, 0x28, 0xD2, 0xAD, 0xEF, 0xF3, 0x84, + 0x4B, 0x1C, 0x87, 0xFC, 0x13, 0xA3, 0x3A, 0x72, 0xA2, 0x5A, 0x11, 0x2B, + 0xD6, 0x27, 0x71, 0x27, 0xED, 0x81, 0x2D, 0x6D, 0x66, 0x81, 0x92, 0x87, + 0xB4, 0x1B, 0x58, 0x7A, 0xCC, 0x3F, 0x0A, 0xFA, 0x46, 0x4F, 0x4D, 0x78, + 0x5C, 0xF8, 0x2B, 0x48, 0xE3, 0x04, 0x84, 0xCB, 0x5D, 0xF6, 0xB4, 0x6A, + 0xB3, 0x65, 0xFC, 0x42, 0x9E, 0x51, 0x26, 0x23, 0x20, 0xCB, 0x3D, 0x14, + 0xF9, 0x81, 0xED, 0x65, 0x16, 0x00, 0x4F, 0x1A, 0x64, 0x97, 0x66, 0x08, + 0xCF, 0x8C, 0x7B, 0xE3, 0x2B, 0xC0, 0x9D, 0xF9, 0x14, 0xF2, 0x1B, 0xF1, + 0x56, 0x6A, 0x16, 0xBF, 0x2C, 0x85, 0x85, 0xCD, 0x78, 0x38, 0x9A, 0xEB, + 0x42, 0x6A, 0x02, 0x34, 0x18, 0x83, 0x17, 0x4E, 0x94, 0x56, 0xF8, 0xB6, + 0x82, 0xB5, 0xF3, 0x96, 0xDD, 0x3D, 0xF3, 0xBE, 0x7F, 0x20, 0x77, 0x3E, + 0x7B, 0x19, 0x23, 0x6B, 0x2C, 0xD4, 0x72, 0x73, 0x43, 0x57, 0x7D, 0xE0, + 0xF8, 0xD7, 0x69, 0x4F, 0x17, 0x36, 0x04, 0xF9, 0xC0, 0x90, 0x60, 0x37, + 0x45, 0xDE, 0xE6, 0x0C, 0xD8, 0x74, 0x8D, 0xAE, 0x9C, 0xA2, 0x6D, 0x74, + 0x5D, 0x42, 0xBE, 0x06, 0xF5, 0xD9, 0x64, 0x6E, 0x02, 0x10, 0xAC, 0x89, + 0xB0, 0x4C, 0x3B, 0x07, 0x4D, 0x40, 0x7E, 0x24, 0xC5, 0x8A, 0x98, 0x82, + 0x79, 0x8E, 0xA4, 0xA7, 0x82, 0x20, 0x8D, 0x23, 0xFA, 0x27, 0x71, 0xC9, + 0xDF, 0xC6, 0x41, 0x74, 0xA0, 0x4D, 0xF6, 0x91, 0x16, 0xDC, 0x46, 0x8C, + 0x5F, 0x29, 0x63, 0x31, 0x59, 0x71, 0x0C, 0xD8, 0x6F, 0xC2, 0xB6, 0x32, + 0x7D, 0xFB, 0xE6, 0x5D, 0x53, 0xA6, 0x7E, 0x15, 0xFC, 0xBB, 0x75, 0x7C, + 0x5D, 0xEC, 0xF8, 0xF6, 0x17, 0x1C, 0xEC, 0xC7, 0x6B, 0x19, 0xCB, 0xF3, + 0x7B, 0xF0, 0x2B, 0x07, 0xA5, 0xD9, 0x6C, 0x79, 0x54, 0x76, 0x6C, 0x9D, + 0x1C, 0xA6, 0x6E, 0x0E, 0xE9, 0x79, 0x0C, 0xA8, 0x23, 0x6A, 0xA3, 0xDF, + 0x1B, 0x30, 0x31, 0x9F, 0xB1, 0x54, 0x7B, 0xFE, 0x6A, 0xCB, 0x66, 0xAA, + 0xDC, 0x65, 0xD0, 0xA2, 0x9E, 0x4A, 0x9A, 0x07, 0x21, 0x6B, 0x81, 0x8F, + 0xDB, 0xC4, 0x59, 0xFA, 0xDE, 0x22, 0xC0, 0x04, 0x9C, 0xE3, 0xAA, 0x5B, + 0x36, 0x93, 0xE8, 0x3D, 0xBD, 0x7A, 0xA1, 0x9D, 0x0B, 0x76, 0xB1, 0x0B, + 0xC7, 0x9D, 0xFD, 0xCF, 0x98, 0xA8, 0x06, 0xC2, 0xF8, 0x2A, 0xA3, 0xA1, + 0x83, 0xA0, 0xB7, 0x25, 0x72, 0xA5, 0x02, 0xE3 +}; + +static const unsigned char TA466_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA467_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, + 0x64, 0x79, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x49, 0x6E, + 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x28, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6C, + 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA467_RSA_N[] = { + 0xDE, 0x9D, 0xD7, 0xEA, 0x57, 0x18, 0x49, 0xA1, 0x5B, 0xEB, 0xD7, 0x5F, + 0x48, 0x86, 0xEA, 0xBE, 0xDD, 0xFF, 0xE4, 0xEF, 0x67, 0x1C, 0xF4, 0x65, + 0x68, 0xB3, 0x57, 0x71, 0xA0, 0x5E, 0x77, 0xBB, 0xED, 0x9B, 0x49, 0xE9, + 0x70, 0x80, 0x3D, 0x56, 0x18, 0x63, 0x08, 0x6F, 0xDA, 0xF2, 0xCC, 0xD0, + 0x3F, 0x7F, 0x02, 0x54, 0x22, 0x54, 0x10, 0xD8, 0xB2, 0x81, 0xD4, 0xC0, + 0x75, 0x3D, 0x4B, 0x7F, 0xC7, 0x77, 0xC3, 0x3E, 0x78, 0xAB, 0x1A, 0x03, + 0xB5, 0x20, 0x6B, 0x2F, 0x6A, 0x2B, 0xB1, 0xC5, 0x88, 0x7E, 0xC4, 0xBB, + 0x1E, 0xB0, 0xC1, 0xD8, 0x45, 0x27, 0x6F, 0xAA, 0x37, 0x58, 0xF7, 0x87, + 0x26, 0xD7, 0xD8, 0x2D, 0xF6, 0xA9, 0x17, 0xB7, 0x1F, 0x72, 0x36, 0x4E, + 0xA6, 0x17, 0x3F, 0x65, 0x98, 0x92, 0xDB, 0x2A, 0x6E, 0x5D, 0xA2, 0xFE, + 0x88, 0xE0, 0x0B, 0xDE, 0x7F, 0xE5, 0x8D, 0x15, 0xE1, 0xEB, 0xCB, 0x3A, + 0xD5, 0xE2, 0x12, 0xA2, 0x13, 0x2D, 0xD8, 0x8E, 0xAF, 0x5F, 0x12, 0x3D, + 0xA0, 0x08, 0x05, 0x08, 0xB6, 0x5C, 0xA5, 0x65, 0x38, 0x04, 0x45, 0x99, + 0x1E, 0xA3, 0x60, 0x60, 0x74, 0xC5, 0x41, 0xA5, 0x72, 0x62, 0x1B, 0x62, + 0xC5, 0x1F, 0x6F, 0x5F, 0x1A, 0x42, 0xBE, 0x02, 0x51, 0x65, 0xA8, 0xAE, + 0x23, 0x18, 0x6A, 0xFC, 0x78, 0x03, 0xA9, 0x4D, 0x7F, 0x80, 0xC3, 0xFA, + 0xAB, 0x5A, 0xFC, 0xA1, 0x40, 0xA4, 0xCA, 0x19, 0x16, 0xFE, 0xB2, 0xC8, + 0xEF, 0x5E, 0x73, 0x0D, 0xEE, 0x77, 0xBD, 0x9A, 0xF6, 0x79, 0x98, 0xBC, + 0xB1, 0x07, 0x67, 0xA2, 0x15, 0x0D, 0xDD, 0xA0, 0x58, 0xC6, 0x44, 0x7B, + 0x0A, 0x3E, 0x62, 0x28, 0x5F, 0xBA, 0x41, 0x07, 0x53, 0x58, 0xCF, 0x11, + 0x7E, 0x38, 0x74, 0xC5, 0xF8, 0xFF, 0xB5, 0x69, 0x90, 0x8F, 0x84, 0x74, + 0xEA, 0x97, 0x1B, 0xAF +}; + +static const unsigned char TA467_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA468_DN[] = { + 0x30, 0x81, 0x83, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x1A, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, 0x47, 0x6F, 0x44, 0x61, 0x64, 0x64, + 0x79, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, + 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6F, + 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA468_RSA_N[] = { + 0xBF, 0x71, 0x62, 0x08, 0xF1, 0xFA, 0x59, 0x34, 0xF7, 0x1B, 0xC9, 0x18, + 0xA3, 0xF7, 0x80, 0x49, 0x58, 0xE9, 0x22, 0x83, 0x13, 0xA6, 0xC5, 0x20, + 0x43, 0x01, 0x3B, 0x84, 0xF1, 0xE6, 0x85, 0x49, 0x9F, 0x27, 0xEA, 0xF6, + 0x84, 0x1B, 0x4E, 0xA0, 0xB4, 0xDB, 0x70, 0x98, 0xC7, 0x32, 0x01, 0xB1, + 0x05, 0x3E, 0x07, 0x4E, 0xEE, 0xF4, 0xFA, 0x4F, 0x2F, 0x59, 0x30, 0x22, + 0xE7, 0xAB, 0x19, 0x56, 0x6B, 0xE2, 0x80, 0x07, 0xFC, 0xF3, 0x16, 0x75, + 0x80, 0x39, 0x51, 0x7B, 0xE5, 0xF9, 0x35, 0xB6, 0x74, 0x4E, 0xA9, 0x8D, + 0x82, 0x13, 0xE4, 0xB6, 0x3F, 0xA9, 0x03, 0x83, 0xFA, 0xA2, 0xBE, 0x8A, + 0x15, 0x6A, 0x7F, 0xDE, 0x0B, 0xC3, 0xB6, 0x19, 0x14, 0x05, 0xCA, 0xEA, + 0xC3, 0xA8, 0x04, 0x94, 0x3B, 0x46, 0x7C, 0x32, 0x0D, 0xF3, 0x00, 0x66, + 0x22, 0xC8, 0x8D, 0x69, 0x6D, 0x36, 0x8C, 0x11, 0x18, 0xB7, 0xD3, 0xB2, + 0x1C, 0x60, 0xB4, 0x38, 0xFA, 0x02, 0x8C, 0xCE, 0xD3, 0xDD, 0x46, 0x07, + 0xDE, 0x0A, 0x3E, 0xEB, 0x5D, 0x7C, 0xC8, 0x7C, 0xFB, 0xB0, 0x2B, 0x53, + 0xA4, 0x92, 0x62, 0x69, 0x51, 0x25, 0x05, 0x61, 0x1A, 0x44, 0x81, 0x8C, + 0x2C, 0xA9, 0x43, 0x96, 0x23, 0xDF, 0xAC, 0x3A, 0x81, 0x9A, 0x0E, 0x29, + 0xC5, 0x1C, 0xA9, 0xE9, 0x5D, 0x1E, 0xB6, 0x9E, 0x9E, 0x30, 0x0A, 0x39, + 0xCE, 0xF1, 0x88, 0x80, 0xFB, 0x4B, 0x5D, 0xCC, 0x32, 0xEC, 0x85, 0x62, + 0x43, 0x25, 0x34, 0x02, 0x56, 0x27, 0x01, 0x91, 0xB4, 0x3B, 0x70, 0x2A, + 0x3F, 0x6E, 0xB1, 0xE8, 0x9C, 0x88, 0x01, 0x7D, 0x9F, 0xD4, 0xF9, 0xDB, + 0x53, 0x6D, 0x60, 0x9D, 0xBF, 0x2C, 0xE7, 0x58, 0xAB, 0xB8, 0x5F, 0x46, + 0xFC, 0xCE, 0xC4, 0x1B, 0x03, 0x3C, 0x09, 0xEB, 0x49, 0x31, 0x5C, 0x69, + 0x46, 0xB3, 0xE0, 0x47 +}; + +static const unsigned char TA468_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA469_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, + 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA469_EC_Q[] = { + 0x04, 0x38, 0x08, 0xFE, 0xB1, 0xA0, 0x96, 0xD2, 0x7A, 0xAC, 0xAF, 0x49, + 0x3A, 0xD0, 0xC0, 0xE0, 0xC3, 0x3B, 0x28, 0xAA, 0xF1, 0x72, 0x6D, 0x65, + 0x00, 0x47, 0x88, 0x84, 0xFC, 0x9A, 0x26, 0x6B, 0xAA, 0x4B, 0xBA, 0x6C, + 0x04, 0x0A, 0x88, 0x5E, 0x17, 0xF2, 0x55, 0x87, 0xFC, 0x30, 0xB0, 0x34, + 0xE2, 0x34, 0x58, 0x57, 0x1A, 0x84, 0x53, 0xE9, 0x30, 0xD9, 0xA9, 0xF2, + 0x96, 0x74, 0xC3, 0x51, 0x1F, 0x58, 0x49, 0x31, 0xCC, 0x98, 0x4E, 0x60, + 0x11, 0x87, 0x75, 0xD3, 0x72, 0x94, 0x90, 0x4F, 0x9B, 0x10, 0x25, 0x2A, + 0xA8, 0x78, 0x2D, 0xBE, 0x90, 0x41, 0x58, 0x90, 0x15, 0x72, 0xA7, 0xA1, + 0xB7 +}; + +static const unsigned char TA470_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, + 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA470_RSA_N[] = { + 0x8B, 0xC2, 0xE7, 0xAF, 0x65, 0x9B, 0x05, 0x67, 0x96, 0xC9, 0x0D, 0x24, + 0xB9, 0xD0, 0x0E, 0x64, 0xFC, 0xCE, 0xE2, 0x24, 0x18, 0x2C, 0x84, 0x7F, + 0x77, 0x51, 0xCB, 0x04, 0x11, 0x36, 0xB8, 0x5E, 0xED, 0x69, 0x71, 0xA7, + 0x9E, 0xE4, 0x25, 0x09, 0x97, 0x67, 0xC1, 0x47, 0xC2, 0xCF, 0x91, 0x16, + 0x36, 0x62, 0x3D, 0x38, 0x04, 0xE1, 0x51, 0x82, 0xFF, 0xAC, 0xD2, 0xB4, + 0x69, 0xDD, 0x2E, 0xEC, 0x11, 0xA3, 0x45, 0xEE, 0x6B, 0x6B, 0x3B, 0x4C, + 0xBF, 0x8C, 0x8D, 0xA4, 0x1E, 0x9D, 0x11, 0xB9, 0xE9, 0x38, 0xF9, 0x7A, + 0x0E, 0x0C, 0x98, 0xE2, 0x23, 0x1D, 0xD1, 0x4E, 0x63, 0xD4, 0xE7, 0xB8, + 0x41, 0x44, 0xFB, 0x6B, 0xAF, 0x6B, 0xDA, 0x1F, 0xD3, 0xC5, 0x91, 0x88, + 0x5B, 0xA4, 0x89, 0x92, 0xD1, 0x81, 0xE6, 0x8C, 0x39, 0x58, 0xA0, 0xD6, + 0x69, 0x43, 0xA9, 0xAD, 0x98, 0x52, 0x58, 0x6E, 0xDB, 0x0A, 0xFB, 0x6B, + 0xCF, 0x68, 0xFA, 0xE3, 0xA4, 0x5E, 0x3A, 0x45, 0x73, 0x98, 0x07, 0xEA, + 0x5F, 0x02, 0x72, 0xDE, 0x0C, 0xA5, 0xB3, 0x9F, 0xAE, 0xA9, 0x1D, 0xB7, + 0x1D, 0xB3, 0xFC, 0x8A, 0x59, 0xE7, 0x6E, 0x72, 0x65, 0xAD, 0xF5, 0x30, + 0x94, 0x23, 0x07, 0xF3, 0x82, 0x16, 0x4B, 0x35, 0x98, 0x9C, 0x53, 0xBB, + 0x2F, 0xCA, 0xE4, 0x5A, 0xD9, 0xC7, 0x8D, 0x1D, 0xFC, 0x98, 0x99, 0xFB, + 0x2C, 0xA4, 0x82, 0x6B, 0xF0, 0x2A, 0x1F, 0x8E, 0x0B, 0x5F, 0x71, 0x5C, + 0x5C, 0xAE, 0x42, 0x7B, 0x29, 0x89, 0x81, 0xCB, 0x03, 0xA3, 0x99, 0xCA, + 0x88, 0x9E, 0x0B, 0x40, 0x09, 0x41, 0x33, 0xDB, 0xE6, 0x58, 0x7A, 0xFD, + 0xAE, 0x99, 0x70, 0xC0, 0x5A, 0x0F, 0xD6, 0x13, 0x86, 0x71, 0x2F, 0x76, + 0x69, 0xFC, 0x90, 0xDD, 0xDB, 0x2D, 0x6E, 0xD1, 0xF2, 0x9B, 0xF5, 0x1A, + 0x6B, 0x9E, 0x6F, 0x15, 0x8C, 0x7A, 0xF0, 0x4B, 0x28, 0xA0, 0x22, 0x38, + 0x80, 0x24, 0x6C, 0x36, 0xA4, 0x3B, 0xF2, 0x30, 0x91, 0xF3, 0x78, 0x13, + 0xCF, 0xC1, 0x3F, 0x35, 0xAB, 0xF1, 0x1D, 0x11, 0x23, 0xB5, 0x43, 0x22, + 0x9E, 0x01, 0x92, 0xB7, 0x18, 0x02, 0xE5, 0x11, 0xD1, 0x82, 0xDB, 0x15, + 0x00, 0xCC, 0x61, 0x37, 0xC1, 0x2A, 0x7C, 0x9A, 0xE1, 0xD0, 0xBA, 0xB3, + 0x50, 0x46, 0xEE, 0x82, 0xAC, 0x9D, 0x31, 0xF8, 0xFB, 0x23, 0xE2, 0x03, + 0x00, 0x48, 0x70, 0xA3, 0x09, 0x26, 0x79, 0x15, 0x53, 0x60, 0xF3, 0x38, + 0x5C, 0xAD, 0x38, 0xEA, 0x81, 0x00, 0x63, 0x14, 0xB9, 0x33, 0x5E, 0xDD, + 0x0B, 0xDB, 0xA0, 0x45, 0x07, 0x1A, 0x33, 0x09, 0xF8, 0x4D, 0xB4, 0xA7, + 0x02, 0xA6, 0x69, 0xF4, 0xC2, 0x59, 0x05, 0x88, 0x65, 0x85, 0x56, 0xAE, + 0x4B, 0xCB, 0xE0, 0xDE, 0x3C, 0x7D, 0x2D, 0x1A, 0xC8, 0xE9, 0xFB, 0x1F, + 0xA3, 0x61, 0x4A, 0xD6, 0x2A, 0x13, 0xAD, 0x77, 0x4C, 0x1A, 0x18, 0x9B, + 0x91, 0x0F, 0x58, 0xD8, 0x06, 0x54, 0xC5, 0x97, 0xF8, 0xAA, 0x3F, 0x20, + 0x8A, 0xA6, 0x85, 0xA6, 0x77, 0xF6, 0xA6, 0xFC, 0x1C, 0xE2, 0xEE, 0x6E, + 0x94, 0x33, 0x2A, 0x83, 0x50, 0x84, 0x0A, 0xE5, 0x4F, 0x86, 0xF8, 0x50, + 0x45, 0x78, 0x00, 0x81, 0xEB, 0x5B, 0x68, 0xE3, 0x26, 0x8D, 0xCC, 0x7B, + 0x5C, 0x51, 0xF4, 0x14, 0x2C, 0x40, 0xBE, 0x1A, 0x60, 0x1D, 0x7A, 0x72, + 0x61, 0x1D, 0x1F, 0x63, 0x2D, 0x88, 0xAA, 0xCE, 0xA2, 0x45, 0x90, 0x08, + 0xFC, 0x6B, 0xBE, 0xB3, 0x50, 0x2A, 0x5A, 0xFD, 0xA8, 0x48, 0x18, 0x46, + 0xD6, 0x90, 0x40, 0x92, 0x90, 0x0A, 0x84, 0x5E, 0x68, 0x31, 0xF8, 0xEB, + 0xED, 0x0D, 0xD3, 0x1D, 0xC6, 0x7D, 0x99, 0x18, 0x55, 0x56, 0x27, 0x65, + 0x2E, 0x8D, 0x45, 0xC5, 0x24, 0xEC, 0xCE, 0xE3 +}; + +static const unsigned char TA470_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA471_DN[] = { + 0x30, 0x81, 0xAA, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x44, 0x30, 0x42, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, + 0x20, 0x32, 0x30, 0x31, 0x35 +}; + +static const unsigned char TA471_EC_Q[] = { + 0x04, 0x92, 0xA0, 0x41, 0xE8, 0x4B, 0x82, 0x84, 0x5C, 0xE2, 0xF8, 0x31, + 0x11, 0x99, 0x86, 0x64, 0x4E, 0x09, 0x25, 0x2F, 0x9D, 0x41, 0x2F, 0x0A, + 0xAE, 0x35, 0x4F, 0x74, 0x95, 0xB2, 0x51, 0x64, 0x6B, 0x8D, 0x6B, 0xE6, + 0x3F, 0x70, 0x95, 0xF0, 0x05, 0x44, 0x47, 0xA6, 0x72, 0x38, 0x50, 0x76, + 0x95, 0x02, 0x5A, 0x8E, 0xAE, 0x28, 0x9E, 0xF9, 0x2D, 0x4E, 0x99, 0xEF, + 0x2C, 0x48, 0x6F, 0x4C, 0x25, 0x29, 0xE8, 0xD1, 0x71, 0x5B, 0xDF, 0x1D, + 0xC1, 0x75, 0x37, 0xB4, 0xD7, 0xFA, 0x7B, 0x7A, 0x42, 0x9C, 0x6A, 0x0A, + 0x56, 0x5A, 0x7C, 0x69, 0x0B, 0xAA, 0x80, 0x09, 0x24, 0x6C, 0x7E, 0xC1, + 0x46 +}; + +static const unsigned char TA472_DN[] = { + 0x30, 0x81, 0xA6, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x40, 0x30, 0x3E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x37, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, + 0x35 +}; + +static const unsigned char TA472_RSA_N[] = { + 0xC2, 0xF8, 0xA9, 0x3F, 0x1B, 0x89, 0xFC, 0x3C, 0x3C, 0x04, 0x5D, 0x3D, + 0x90, 0x36, 0xB0, 0x91, 0x3A, 0x79, 0x3C, 0x66, 0x5A, 0xEF, 0x6D, 0x39, + 0x01, 0x49, 0x1A, 0xB4, 0xB7, 0xCF, 0x7F, 0x4D, 0x23, 0x53, 0xB7, 0x90, + 0x00, 0xE3, 0x13, 0x2A, 0x28, 0xA6, 0x31, 0xF1, 0x91, 0x00, 0xE3, 0x28, + 0xEC, 0xAE, 0x21, 0x41, 0xCE, 0x1F, 0xDA, 0xFD, 0x7D, 0x12, 0x5B, 0x01, + 0x83, 0x0F, 0xB9, 0xB0, 0x5F, 0x99, 0xE1, 0xF2, 0x12, 0x83, 0x80, 0x4D, + 0x06, 0x3E, 0xDF, 0xAC, 0xAF, 0xE7, 0xA1, 0x88, 0x6B, 0x31, 0xAF, 0xF0, + 0x8B, 0xD0, 0x18, 0x33, 0xB8, 0xDB, 0x45, 0x6A, 0x34, 0xF4, 0x02, 0x80, + 0x24, 0x28, 0x0A, 0x02, 0x15, 0x95, 0x5E, 0x76, 0x2A, 0x0D, 0x99, 0x3A, + 0x14, 0x5B, 0xF6, 0xCB, 0xCB, 0x53, 0xBC, 0x13, 0x4D, 0x01, 0x88, 0x37, + 0x94, 0x25, 0x1B, 0x42, 0xBC, 0x22, 0xD8, 0x8E, 0xA3, 0x96, 0x5E, 0x3A, + 0xD9, 0x32, 0xDB, 0x3E, 0xE8, 0xF0, 0x10, 0x65, 0xED, 0x74, 0xE1, 0x2F, + 0xA7, 0x7C, 0xAF, 0x27, 0x34, 0xBB, 0x29, 0x7D, 0x9B, 0xB6, 0xCF, 0x09, + 0xC8, 0xE5, 0xD3, 0x0A, 0xFC, 0x88, 0x65, 0x65, 0x74, 0x0A, 0xDC, 0x73, + 0x1C, 0x5C, 0xCD, 0x40, 0xB1, 0x1C, 0xD4, 0xB6, 0x84, 0x8C, 0x4C, 0x50, + 0xCF, 0x68, 0x8E, 0xA8, 0x59, 0xAE, 0xC2, 0x27, 0x4E, 0x82, 0xA2, 0x35, + 0xDD, 0x14, 0xF4, 0x1F, 0xFF, 0xB2, 0x77, 0xD5, 0x87, 0x2F, 0xAA, 0x6E, + 0x7D, 0x24, 0x27, 0xE7, 0xC6, 0xCB, 0x26, 0xE6, 0xE5, 0xFE, 0x67, 0x07, + 0x63, 0xD8, 0x45, 0x0D, 0xDD, 0x3A, 0x59, 0x65, 0x39, 0x58, 0x7A, 0x92, + 0x99, 0x72, 0x3D, 0x9C, 0x84, 0x5E, 0x88, 0x21, 0xB8, 0xD5, 0xF4, 0x2C, + 0xFC, 0xD9, 0x70, 0x52, 0x4F, 0x78, 0xB8, 0xBD, 0x3C, 0x2B, 0x8B, 0x95, + 0x98, 0xF5, 0xB3, 0xD1, 0x68, 0xCF, 0x20, 0x14, 0x7E, 0x4C, 0x5C, 0x5F, + 0xE7, 0x8B, 0xE5, 0xF5, 0x35, 0x81, 0x19, 0x37, 0xD7, 0x11, 0x08, 0xB7, + 0x66, 0xBE, 0xD3, 0x4A, 0xCE, 0x83, 0x57, 0x00, 0x3A, 0xC3, 0x81, 0xF8, + 0x17, 0xCB, 0x92, 0x36, 0x5D, 0xD1, 0xA3, 0xD8, 0x75, 0x1B, 0xE1, 0x8B, + 0x27, 0xEA, 0x7A, 0x48, 0x41, 0xFD, 0x45, 0x19, 0x06, 0xAD, 0x27, 0x99, + 0x4E, 0xC1, 0x70, 0x47, 0xDD, 0xB5, 0x9F, 0x81, 0x53, 0x12, 0xE5, 0xB1, + 0x8C, 0x48, 0x5D, 0x31, 0x43, 0x17, 0xE3, 0x8C, 0xC6, 0x7A, 0x63, 0x96, + 0x4B, 0x29, 0x30, 0x4E, 0x84, 0x4E, 0x62, 0x19, 0x5E, 0x3C, 0xCE, 0x97, + 0x90, 0xA5, 0x7F, 0x01, 0xEB, 0x9D, 0xE0, 0xF8, 0x8B, 0x89, 0xDD, 0x25, + 0x98, 0x3D, 0x92, 0xB6, 0x7E, 0xEF, 0xD9, 0xF1, 0x51, 0x51, 0x7D, 0x2D, + 0x26, 0xC8, 0x69, 0x59, 0x61, 0xE0, 0xAC, 0x6A, 0xB8, 0x2A, 0x36, 0x11, + 0x04, 0x7A, 0x50, 0xBD, 0x32, 0x84, 0xBE, 0x2F, 0xDC, 0x72, 0xD5, 0xD7, + 0x1D, 0x16, 0x47, 0xE4, 0x47, 0x66, 0x20, 0x3F, 0xF4, 0x96, 0xC5, 0xAF, + 0x8E, 0x01, 0x7A, 0xA5, 0x0F, 0x7A, 0x64, 0xF5, 0x0D, 0x18, 0x87, 0xD9, + 0xAE, 0x88, 0xD5, 0xFA, 0x84, 0xC1, 0x3A, 0xC0, 0x69, 0x28, 0x2D, 0xF2, + 0x0D, 0x68, 0x51, 0xAA, 0xE3, 0xA5, 0x77, 0xC6, 0xA4, 0x90, 0x0E, 0xA1, + 0x37, 0x8B, 0x31, 0x23, 0x47, 0xC1, 0x09, 0x08, 0xEB, 0x6E, 0xF7, 0x78, + 0x9B, 0xD7, 0x82, 0xFC, 0x84, 0x20, 0x99, 0x49, 0x19, 0xB6, 0x12, 0x46, + 0xB1, 0xFB, 0x45, 0x55, 0x16, 0xA9, 0xA3, 0x65, 0xAC, 0x9C, 0x07, 0x0F, + 0xEA, 0x6B, 0xDC, 0x1F, 0x2E, 0x06, 0x72, 0xEC, 0x86, 0x88, 0x12, 0xE4, + 0x2D, 0xDB, 0x5F, 0x05, 0x2F, 0xE4, 0xF0, 0x03, 0xD3, 0x26, 0x33, 0xE7, + 0x80, 0xC2, 0xCD, 0x42, 0xA1, 0x17, 0x34, 0x0B +}; + +static const unsigned char TA472_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA473_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x12, 0x48, 0x69, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA473_RSA_N[] = { + 0xF4, 0x1E, 0x7F, 0x52, 0x73, 0x32, 0x0C, 0x73, 0xE4, 0xBD, 0x13, 0x74, + 0xA3, 0xD4, 0x30, 0xA8, 0xD0, 0xAE, 0x4B, 0xD8, 0xB6, 0xDF, 0x75, 0x47, + 0x66, 0xF4, 0x7C, 0xE7, 0x39, 0x04, 0x1E, 0x6A, 0x70, 0x20, 0xD2, 0x5A, + 0x47, 0x72, 0x67, 0x55, 0xF4, 0xA5, 0xE8, 0x9D, 0xD5, 0x1E, 0x21, 0xA1, + 0xF0, 0x67, 0xBA, 0xCC, 0x21, 0x68, 0xBE, 0x44, 0x53, 0xBF, 0x8D, 0xF9, + 0xE2, 0xDC, 0x2F, 0x55, 0xC8, 0x37, 0x3F, 0x1F, 0xA4, 0xC0, 0x9C, 0xB3, + 0xE4, 0x77, 0x5C, 0xA0, 0x46, 0xFE, 0x77, 0xFA, 0x1A, 0xA0, 0x38, 0xEA, + 0xED, 0x9A, 0x72, 0xDE, 0x2B, 0xBD, 0x94, 0x57, 0x3A, 0xBA, 0xEC, 0x79, + 0xE7, 0x5F, 0x7D, 0x42, 0x64, 0x39, 0x7A, 0x26, 0x36, 0xF7, 0x24, 0xF0, + 0xD5, 0x2F, 0xBA, 0x95, 0x98, 0x11, 0x66, 0xAD, 0x97, 0x35, 0xD6, 0x75, + 0x01, 0x80, 0xE0, 0xAF, 0xF4, 0x84, 0x61, 0x8C, 0x0D, 0x1E, 0x5F, 0x7C, + 0x87, 0x96, 0x5E, 0x41, 0xAF, 0xEB, 0x87, 0xEA, 0xF8, 0x5D, 0xF1, 0x2E, + 0x88, 0x05, 0x3E, 0x4C, 0x22, 0xBB, 0xDA, 0x1F, 0x2A, 0xDD, 0x52, 0x46, + 0x64, 0x39, 0xF3, 0x42, 0xCE, 0xD9, 0x9E, 0x0C, 0xB3, 0xB0, 0x77, 0x97, + 0x64, 0x9C, 0xC0, 0xF4, 0xA3, 0x2E, 0x1F, 0x95, 0x07, 0xB0, 0x17, 0xDF, + 0x30, 0xDB, 0x00, 0x18, 0x96, 0x4C, 0xA1, 0x81, 0x4B, 0xDD, 0x04, 0x6D, + 0x53, 0xA3, 0x3D, 0xFC, 0x07, 0xAC, 0xD4, 0xC5, 0x37, 0x82, 0xEB, 0xE4, + 0x95, 0x08, 0x19, 0x28, 0x82, 0xD2, 0x42, 0x3A, 0xA3, 0xD8, 0x53, 0xEC, + 0x79, 0x89, 0x60, 0x48, 0x60, 0xC8, 0x72, 0x92, 0x50, 0xDC, 0x03, 0x8F, + 0x83, 0x3F, 0xB2, 0x42, 0x57, 0x5A, 0xDB, 0x6A, 0xE9, 0x11, 0x97, 0xDD, + 0x85, 0x28, 0xBC, 0x30, 0x4C, 0xAB, 0xE3, 0xC2, 0xB1, 0x45, 0x44, 0x47, + 0x1F, 0xE0, 0x8A, 0x16, 0x07, 0x96, 0xD2, 0x21, 0x0F, 0x53, 0xC0, 0xED, + 0xA9, 0x7E, 0xD4, 0x4E, 0xEC, 0x9B, 0x09, 0xEC, 0xAF, 0x42, 0xAC, 0x30, + 0xD6, 0xBF, 0xD1, 0x10, 0x45, 0xE0, 0xA6, 0x16, 0xB2, 0xA5, 0xC5, 0xD3, + 0x4F, 0x73, 0x94, 0x33, 0x71, 0x02, 0xA1, 0x6A, 0xA3, 0xD6, 0x33, 0x97, + 0x4F, 0x21, 0x63, 0x1E, 0x5B, 0x8F, 0xD9, 0xC1, 0x5E, 0x45, 0x71, 0x77, + 0x0F, 0x81, 0x5D, 0x5F, 0x21, 0x9A, 0xAD, 0x83, 0xCC, 0xFA, 0x5E, 0xD6, + 0x8D, 0x23, 0x5F, 0x1B, 0x3D, 0x41, 0xAF, 0x20, 0x75, 0x66, 0x5A, 0x4A, + 0xF6, 0x9F, 0xFB, 0xAB, 0x18, 0xF7, 0x71, 0xC0, 0xB6, 0x1D, 0x31, 0xEC, + 0x3B, 0x20, 0xEB, 0xCB, 0xE2, 0xB8, 0xF5, 0xAE, 0x92, 0xB2, 0xF7, 0xE1, + 0x84, 0x4B, 0xF2, 0xA2, 0xF2, 0x93, 0x9A, 0x22, 0x9E, 0xD3, 0x14, 0x6F, + 0x36, 0x54, 0xBD, 0x1F, 0x5E, 0x59, 0x15, 0xB9, 0x73, 0xA8, 0xC1, 0x7C, + 0x6F, 0x7B, 0x62, 0xE9, 0x16, 0x6C, 0x47, 0x5A, 0x65, 0xF3, 0x0E, 0x11, + 0x9B, 0x46, 0xD9, 0xFD, 0x6D, 0xDC, 0xD6, 0x9C, 0xC0, 0xB4, 0x7D, 0xA5, + 0xB0, 0xDD, 0x3F, 0x56, 0x6F, 0xA1, 0xF9, 0xF6, 0xE4, 0x12, 0x48, 0xFD, + 0x06, 0x7F, 0x12, 0x57, 0xB6, 0xA9, 0x23, 0x4F, 0x5B, 0x03, 0xC3, 0xE0, + 0x71, 0x2A, 0x23, 0xB7, 0xF7, 0xB0, 0xB1, 0x3B, 0xBC, 0x98, 0xBD, 0xD6, + 0x98, 0xA8, 0x0C, 0x6B, 0xF6, 0x8E, 0x12, 0x67, 0xA6, 0xF2, 0xB2, 0x58, + 0xE4, 0x02, 0x09, 0x13, 0x3C, 0xA9, 0xBB, 0x10, 0xB4, 0xD2, 0x30, 0x45, + 0xF1, 0xEC, 0xF7, 0x00, 0x11, 0xDF, 0x65, 0xF8, 0xDC, 0x2B, 0x43, 0x55, + 0xBF, 0x16, 0x97, 0xC4, 0x0F, 0xD5, 0x2C, 0x61, 0x84, 0xAA, 0x72, 0x86, + 0xFE, 0xE6, 0x3A, 0x7E, 0xC2, 0x3F, 0x7D, 0xEE, 0xFC, 0x2F, 0x14, 0x3E, + 0xE6, 0x85, 0xDD, 0x50, 0x6F, 0xB7, 0x49, 0xED +}; + +static const unsigned char TA473_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA474_DN[] = { + 0x30, 0x6F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x4B, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x09, 0x48, 0x6F, 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x48, 0x6F, + 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA474_RSA_N[] = { + 0xB3, 0x88, 0xD7, 0xEA, 0xCE, 0x0F, 0x20, 0x4E, 0xBE, 0xE6, 0xD6, 0x03, + 0x6D, 0xEE, 0x59, 0xFC, 0xC2, 0x57, 0xDF, 0x29, 0x68, 0xA1, 0x83, 0x0E, + 0x3E, 0x68, 0xC7, 0x68, 0x58, 0x9C, 0x1C, 0x60, 0x4B, 0x89, 0x43, 0x0C, + 0xB9, 0xD4, 0x15, 0xB2, 0xEE, 0xC1, 0x4E, 0x75, 0xE9, 0xB5, 0xA7, 0xEF, + 0xE5, 0xE9, 0x35, 0x99, 0xE4, 0xCC, 0x1C, 0xE7, 0x4B, 0x5F, 0x8D, 0x33, + 0x30, 0x20, 0x33, 0x53, 0xD9, 0xA6, 0xBB, 0xD5, 0x3E, 0x13, 0x8E, 0xE9, + 0x1F, 0x87, 0x49, 0xAD, 0x50, 0x2D, 0x50, 0xCA, 0x18, 0xBE, 0x01, 0x58, + 0xA2, 0x13, 0x70, 0x96, 0xBB, 0x89, 0x88, 0x56, 0x80, 0x5C, 0xF8, 0xBD, + 0x2C, 0x3C, 0xE1, 0x4C, 0x57, 0x88, 0xBB, 0xD3, 0xB9, 0x95, 0xEF, 0xCB, + 0xC7, 0xF6, 0xDA, 0x31, 0x74, 0x28, 0xA6, 0xE6, 0x54, 0x89, 0xF5, 0x41, + 0x31, 0xCA, 0xE5, 0x26, 0x1A, 0xCD, 0x82, 0xE0, 0x70, 0xDA, 0x3B, 0x29, + 0xBB, 0xD5, 0x03, 0xF5, 0x99, 0xBA, 0x55, 0xF5, 0x64, 0xD1, 0x60, 0x0E, + 0xB3, 0x89, 0x49, 0xB8, 0x8A, 0x2F, 0x05, 0xD2, 0x84, 0x45, 0x28, 0x7C, + 0x8F, 0x68, 0x50, 0x12, 0x78, 0xFC, 0x0B, 0xB5, 0x53, 0xCB, 0xC2, 0x98, + 0x1C, 0x84, 0xA3, 0x9E, 0xB0, 0xBE, 0x23, 0xA4, 0xDA, 0xDC, 0xC8, 0x2B, + 0x1E, 0xDA, 0x6E, 0x45, 0x1E, 0x89, 0x98, 0xDA, 0xF9, 0x00, 0x2E, 0x06, + 0xE9, 0x0C, 0x3B, 0x70, 0xD5, 0x50, 0x25, 0x88, 0x99, 0xCB, 0xCD, 0x73, + 0x60, 0xF7, 0xD5, 0xFF, 0x35, 0x67, 0xC5, 0xA1, 0xBC, 0x5E, 0xAB, 0xCD, + 0x4A, 0xB8, 0x45, 0xEB, 0xC8, 0x68, 0x1E, 0x0D, 0x0D, 0x14, 0x46, 0x12, + 0xE3, 0xD2, 0x64, 0x62, 0x8A, 0x42, 0x98, 0xBC, 0xB4, 0xC6, 0x08, 0x08, + 0xF8, 0xFD, 0xA8, 0x4C, 0x64, 0x9C, 0x76, 0x01, 0xBD, 0x2F, 0xA9, 0x6C, + 0x33, 0x0F, 0xD8, 0x3F, 0x28, 0xB8, 0x3C, 0x69, 0x01, 0x42, 0x86, 0x7E, + 0x69, 0xC1, 0xC9, 0x06, 0xCA, 0xE5, 0x7A, 0x46, 0x65, 0xE9, 0xC2, 0xD6, + 0x50, 0x41, 0x2E, 0x3F, 0xB7, 0xE4, 0xED, 0x6C, 0xD7, 0xBF, 0x26, 0x01, + 0x11, 0xA2, 0x16, 0x29, 0x4A, 0x6B, 0x34, 0x06, 0x90, 0xEC, 0x13, 0xD2, + 0xB6, 0xFB, 0x6A, 0x76, 0xD2, 0x3C, 0xED, 0xF0, 0xD6, 0x2D, 0xDD, 0xE1, + 0x15, 0xEC, 0xA3, 0x9B, 0x2F, 0x2C, 0xC9, 0x3E, 0x2B, 0xE4, 0x69, 0x3B, + 0xFF, 0x72, 0x25, 0xB1, 0x36, 0x86, 0x5B, 0xC7, 0x7F, 0x6B, 0x8B, 0x55, + 0x1B, 0x4A, 0xC5, 0x20, 0x61, 0x3D, 0xAE, 0xCB, 0x50, 0xE1, 0x08, 0x3A, + 0xBE, 0xB0, 0x8F, 0x63, 0x41, 0x53, 0x30, 0x08, 0x59, 0x3C, 0x98, 0x1D, + 0x77, 0xBA, 0x63, 0x91, 0x7A, 0xCA, 0x10, 0x50, 0x60, 0xBF, 0xF0, 0xD7, + 0xBC, 0x95, 0x87, 0x8F, 0x97, 0xC5, 0xFE, 0x97, 0x6A, 0x01, 0x94, 0xA3, + 0x7C, 0x5B, 0x85, 0x1D, 0x2A, 0x39, 0x3A, 0xD0, 0x54, 0xA1, 0xD1, 0x39, + 0x71, 0x9D, 0xFD, 0x21, 0xF9, 0xB5, 0x7B, 0xF0, 0xE2, 0xE0, 0x02, 0x8F, + 0x6E, 0x96, 0x24, 0x25, 0x2C, 0xA0, 0x1E, 0x2C, 0xA8, 0xC4, 0x89, 0xA7, + 0xEF, 0xED, 0x99, 0x06, 0x2F, 0xB6, 0x0A, 0x4C, 0x4F, 0xDB, 0xA2, 0xCC, + 0x37, 0x1A, 0xAF, 0x47, 0x85, 0x2D, 0x8A, 0x5F, 0xC4, 0x34, 0x34, 0x4C, + 0x00, 0xFD, 0x18, 0x93, 0x67, 0x13, 0xD1, 0x37, 0xE6, 0x48, 0xB4, 0x8B, + 0x06, 0xC5, 0x57, 0x7B, 0x19, 0x86, 0x0A, 0x79, 0xCB, 0x00, 0xC9, 0x52, + 0xAF, 0x42, 0xFF, 0x37, 0x8F, 0xE1, 0xA3, 0x1E, 0x7A, 0x3D, 0x50, 0xAB, + 0x63, 0x06, 0xE7, 0x15, 0xB5, 0x3F, 0xB6, 0x45, 0x37, 0x94, 0x37, 0xB1, + 0x7E, 0xF2, 0x48, 0xC3, 0x7F, 0xC5, 0x75, 0xFE, 0x97, 0x8D, 0x45, 0x8F, + 0x1A, 0xA7, 0x1A, 0x72, 0x28, 0x1A, 0x40, 0x0F +}; + +static const unsigned char TA474_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA475_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x31 +}; + +static const unsigned char TA475_RSA_N[] = { + 0xAD, 0xE8, 0x24, 0x73, 0xF4, 0x14, 0x37, 0xF3, 0x9B, 0x9E, 0x2B, 0x57, + 0x28, 0x1C, 0x87, 0xBE, 0xDC, 0xB7, 0xDF, 0x38, 0x90, 0x8C, 0x6E, 0x3C, + 0xE6, 0x57, 0xA0, 0x78, 0xF7, 0x75, 0xC2, 0xA2, 0xFE, 0xF5, 0x6A, 0x6E, + 0xF6, 0x00, 0x4F, 0x28, 0xDB, 0xDE, 0x68, 0x86, 0x6C, 0x44, 0x93, 0xB6, + 0xB1, 0x63, 0xFD, 0x14, 0x12, 0x6B, 0xBF, 0x1F, 0xD2, 0xEA, 0x31, 0x9B, + 0x21, 0x7E, 0xD1, 0x33, 0x3C, 0xBA, 0x48, 0xF5, 0xDD, 0x79, 0xDF, 0xB3, + 0xB8, 0xFF, 0x12, 0xF1, 0x21, 0x9A, 0x4B, 0xC1, 0x8A, 0x86, 0x71, 0x69, + 0x4A, 0x66, 0x66, 0x6C, 0x8F, 0x7E, 0x3C, 0x70, 0xBF, 0xAD, 0x29, 0x22, + 0x06, 0xF3, 0xE4, 0xC0, 0xE6, 0x80, 0xAE, 0xE2, 0x4B, 0x8F, 0xB7, 0x99, + 0x7E, 0x94, 0x03, 0x9F, 0xD3, 0x47, 0x97, 0x7C, 0x99, 0x48, 0x23, 0x53, + 0xE8, 0x38, 0xAE, 0x4F, 0x0A, 0x6F, 0x83, 0x2E, 0xD1, 0x49, 0x57, 0x8C, + 0x80, 0x74, 0xB6, 0xDA, 0x2F, 0xD0, 0x38, 0x8D, 0x7B, 0x03, 0x70, 0x21, + 0x1B, 0x75, 0xF2, 0x30, 0x3C, 0xFA, 0x8F, 0xAE, 0xDD, 0xDA, 0x63, 0xAB, + 0xEB, 0x16, 0x4F, 0xC2, 0x8E, 0x11, 0x4B, 0x7E, 0xCF, 0x0B, 0xE8, 0xFF, + 0xB5, 0x77, 0x2E, 0xF4, 0xB2, 0x7B, 0x4A, 0xE0, 0x4C, 0x12, 0x25, 0x0C, + 0x70, 0x8D, 0x03, 0x29, 0xA0, 0xE1, 0x53, 0x24, 0xEC, 0x13, 0xD9, 0xEE, + 0x19, 0xBF, 0x10, 0xB3, 0x4A, 0x8C, 0x3F, 0x89, 0xA3, 0x61, 0x51, 0xDE, + 0xAC, 0x87, 0x07, 0x94, 0xF4, 0x63, 0x71, 0xEC, 0x2E, 0xE2, 0x6F, 0x5B, + 0x98, 0x81, 0xE1, 0x89, 0x5C, 0x34, 0x79, 0x6C, 0x76, 0xEF, 0x3B, 0x90, + 0x62, 0x79, 0xE6, 0xDB, 0xA4, 0x9A, 0x2F, 0x26, 0xC5, 0xD0, 0x10, 0xE1, + 0x0E, 0xDE, 0xD9, 0x10, 0x8E, 0x16, 0xFB, 0xB7, 0xF7, 0xA8, 0xF7, 0xC7, + 0xE5, 0x02, 0x07, 0x98, 0x8F, 0x36, 0x08, 0x95, 0xE7, 0xE2, 0x37, 0x96, + 0x0D, 0x36, 0x75, 0x9E, 0xFB, 0x0E, 0x72, 0xB1, 0x1D, 0x9B, 0xBC, 0x03, + 0xF9, 0x49, 0x05, 0xD8, 0x81, 0xDD, 0x05, 0xB4, 0x2A, 0xD6, 0x41, 0xE9, + 0xAC, 0x01, 0x76, 0x95, 0x0A, 0x0F, 0xD8, 0xDF, 0xD5, 0xBD, 0x12, 0x1F, + 0x35, 0x2F, 0x28, 0x17, 0x6C, 0xD2, 0x98, 0xC1, 0xA8, 0x09, 0x64, 0x77, + 0x6E, 0x47, 0x37, 0xBA, 0xCE, 0xAC, 0x59, 0x5E, 0x68, 0x9D, 0x7F, 0x72, + 0xD6, 0x89, 0xC5, 0x06, 0x41, 0x29, 0x3E, 0x59, 0x3E, 0xDD, 0x26, 0xF5, + 0x24, 0xC9, 0x11, 0xA7, 0x5A, 0xA3, 0x4C, 0x40, 0x1F, 0x46, 0xA1, 0x99, + 0xB5, 0xA7, 0x3A, 0x51, 0x6E, 0x86, 0x3B, 0x9E, 0x7D, 0x72, 0xA7, 0x12, + 0x05, 0x78, 0x59, 0xED, 0x3E, 0x51, 0x78, 0x15, 0x0B, 0x03, 0x8F, 0x8D, + 0xD0, 0x2F, 0x05, 0xB2, 0x3E, 0x7B, 0x4A, 0x1C, 0x4B, 0x73, 0x05, 0x12, + 0xFC, 0xC6, 0xEA, 0xE0, 0x50, 0x13, 0x7C, 0x43, 0x93, 0x74, 0xB3, 0xCA, + 0x74, 0xE7, 0x8E, 0x1F, 0x01, 0x08, 0xD0, 0x30, 0xD4, 0x5B, 0x71, 0x36, + 0xB4, 0x07, 0xBA, 0xC1, 0x30, 0x30, 0x5C, 0x48, 0xB7, 0x82, 0x3B, 0x98, + 0xA6, 0x7D, 0x60, 0x8A, 0xA2, 0xA3, 0x29, 0x82, 0xCC, 0xBA, 0xBD, 0x83, + 0x04, 0x1B, 0xA2, 0x83, 0x03, 0x41, 0xA1, 0xD6, 0x05, 0xF1, 0x1B, 0xC2, + 0xB6, 0xF0, 0xA8, 0x7C, 0x86, 0x3B, 0x46, 0xA8, 0x48, 0x2A, 0x88, 0xDC, + 0x76, 0x9A, 0x76, 0xBF, 0x1F, 0x6A, 0xA5, 0x3D, 0x19, 0x8F, 0xEB, 0x38, + 0xF3, 0x64, 0xDE, 0xC8, 0x2B, 0x0D, 0x0A, 0x28, 0xFF, 0xF7, 0xDB, 0xE2, + 0x15, 0x42, 0xD4, 0x22, 0xD0, 0x27, 0x5D, 0xE1, 0x79, 0xFE, 0x18, 0xE7, + 0x70, 0x88, 0xAD, 0x4E, 0xE6, 0xD9, 0x8B, 0x3A, 0xC6, 0xDD, 0x27, 0x51, + 0x6E, 0xFF, 0xBC, 0x64, 0xF5, 0x33, 0x43, 0x4F +}; + +static const unsigned char TA475_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA476_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x32 +}; + +static const unsigned char TA476_EC_Q[] = { + 0x04, 0xCD, 0x9B, 0xD5, 0x9F, 0x80, 0x83, 0x0A, 0xEC, 0x09, 0x4A, 0xF3, + 0x16, 0x4A, 0x3E, 0x5C, 0xCF, 0x77, 0xAC, 0xDE, 0x67, 0x05, 0x0D, 0x1D, + 0x07, 0xB6, 0xDC, 0x16, 0xFB, 0x5A, 0x8B, 0x14, 0xDB, 0xE2, 0x71, 0x60, + 0xC4, 0xBA, 0x45, 0x95, 0x11, 0x89, 0x8E, 0xEA, 0x06, 0xDF, 0xF7, 0x2A, + 0x16, 0x1C, 0xA4, 0xB9, 0xC5, 0xC5, 0x32, 0xE0, 0x03, 0xE0, 0x1E, 0x82, + 0x18, 0x38, 0x8B, 0xD7, 0x45, 0xD8, 0x0A, 0x6A, 0x6E, 0xE6, 0x00, 0x77, + 0xFB, 0x02, 0x51, 0x7D, 0x22, 0xD8, 0x0A, 0x6E, 0x9A, 0x5B, 0x77, 0xDF, + 0xF0, 0xFA, 0x41, 0xEC, 0x39, 0xDC, 0x75, 0xCA, 0x68, 0x07, 0x0C, 0x1F, + 0xEA +}; + +static const unsigned char TA477_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6F, 0x6D, 0x6D, + 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA477_RSA_N[] = { + 0xA7, 0x50, 0x19, 0xDE, 0x3F, 0x99, 0x3D, 0xD4, 0x33, 0x46, 0xF1, 0x6F, + 0x51, 0x61, 0x82, 0xB2, 0xA9, 0x4F, 0x8F, 0x67, 0x89, 0x5D, 0x84, 0xD9, + 0x53, 0xDD, 0x0C, 0x28, 0xD9, 0xD7, 0xF0, 0xFF, 0xAE, 0x95, 0x43, 0x72, + 0x99, 0xF9, 0xB5, 0x5D, 0x7C, 0x8A, 0xC1, 0x42, 0xE1, 0x31, 0x50, 0x74, + 0xD1, 0x81, 0x0D, 0x7C, 0xCD, 0x9B, 0x21, 0xAB, 0x43, 0xE2, 0xAC, 0xAD, + 0x5E, 0x86, 0x6E, 0xF3, 0x09, 0x8A, 0x1F, 0x5A, 0x32, 0xBD, 0xA2, 0xEB, + 0x94, 0xF9, 0xE8, 0x5C, 0x0A, 0xEC, 0xFF, 0x98, 0xD2, 0xAF, 0x71, 0xB3, + 0xB4, 0x53, 0x9F, 0x4E, 0x87, 0xEF, 0x92, 0xBC, 0xBD, 0xEC, 0x4F, 0x32, + 0x30, 0x88, 0x4B, 0x17, 0x5E, 0x57, 0xC4, 0x53, 0xC2, 0xF6, 0x02, 0x97, + 0x8D, 0xD9, 0x62, 0x2B, 0xBF, 0x24, 0x1F, 0x62, 0x8D, 0xDF, 0xC3, 0xB8, + 0x29, 0x4B, 0x49, 0x78, 0x3C, 0x93, 0x60, 0x88, 0x22, 0xFC, 0x99, 0xDA, + 0x36, 0xC8, 0xC2, 0xA2, 0xD4, 0x2C, 0x54, 0x00, 0x67, 0x35, 0x6E, 0x73, + 0xBF, 0x02, 0x58, 0xF0, 0xA4, 0xDD, 0xE5, 0xB0, 0xA2, 0x26, 0x7A, 0xCA, + 0xE0, 0x36, 0xA5, 0x19, 0x16, 0xF5, 0xFD, 0xB7, 0xEF, 0xAE, 0x3F, 0x40, + 0xF5, 0x6D, 0x5A, 0x04, 0xFD, 0xCE, 0x34, 0xCA, 0x24, 0xDC, 0x74, 0x23, + 0x1B, 0x5D, 0x33, 0x13, 0x12, 0x5D, 0xC4, 0x01, 0x25, 0xF6, 0x30, 0xDD, + 0x02, 0x5D, 0x9F, 0xE0, 0xD5, 0x47, 0xBD, 0xB4, 0xEB, 0x1B, 0xA1, 0xBB, + 0x49, 0x49, 0xD8, 0x9F, 0x5B, 0x02, 0xF3, 0x8A, 0xE4, 0x24, 0x90, 0xE4, + 0x62, 0x4F, 0x4F, 0xC1, 0xAF, 0x8B, 0x0E, 0x74, 0x17, 0xA8, 0xD1, 0x72, + 0x88, 0x6A, 0x7A, 0x01, 0x49, 0xCC, 0xB4, 0x46, 0x79, 0xC6, 0x17, 0xB1, + 0xDA, 0x98, 0x1E, 0x07, 0x59, 0xFA, 0x75, 0x21, 0x85, 0x65, 0xDD, 0x90, + 0x56, 0xCE, 0xFB, 0xAB, 0xA5, 0x60, 0x9D, 0xC4, 0x9D, 0xF9, 0x52, 0xB0, + 0x8B, 0xBD, 0x87, 0xF9, 0x8F, 0x2B, 0x23, 0x0A, 0x23, 0x76, 0x3B, 0xF7, + 0x33, 0xE1, 0xC9, 0x00, 0xF3, 0x69, 0xF9, 0x4B, 0xA2, 0xE0, 0x4E, 0xBC, + 0x7E, 0x93, 0x39, 0x84, 0x07, 0xF7, 0x44, 0x70, 0x7E, 0xFE, 0x07, 0x5A, + 0xE5, 0xB1, 0xAC, 0xD1, 0x18, 0xCC, 0xF2, 0x35, 0xE5, 0x49, 0x49, 0x08, + 0xCA, 0x56, 0xC9, 0x3D, 0xFB, 0x0F, 0x18, 0x7D, 0x8B, 0x3B, 0xC1, 0x13, + 0xC2, 0x4D, 0x8F, 0xC9, 0x4F, 0x0E, 0x37, 0xE9, 0x1F, 0xA1, 0x0E, 0x6A, + 0xDF, 0x62, 0x2E, 0xCB, 0x35, 0x06, 0x51, 0x79, 0x2C, 0xC8, 0x25, 0x38, + 0xF4, 0xFA, 0x4B, 0xA7, 0x89, 0x5C, 0x9C, 0xD2, 0xE3, 0x0D, 0x39, 0x86, + 0x4A, 0x74, 0x7C, 0xD5, 0x59, 0x87, 0xC2, 0x3F, 0x4E, 0x0C, 0x5C, 0x52, + 0xF4, 0x3D, 0xF7, 0x52, 0x82, 0xF1, 0xEA, 0xA3, 0xAC, 0xFD, 0x49, 0x34, + 0x1A, 0x28, 0xF3, 0x41, 0x88, 0x3A, 0x13, 0xEE, 0xE8, 0xDE, 0xFF, 0x99, + 0x1D, 0x5F, 0xBA, 0xCB, 0xE8, 0x1E, 0xF2, 0xB9, 0x50, 0x60, 0xC0, 0x31, + 0xD3, 0x73, 0xE5, 0xEF, 0xBE, 0xA0, 0xED, 0x33, 0x0B, 0x74, 0xBE, 0x20, + 0x20, 0xC4, 0x67, 0x6C, 0xF0, 0x08, 0x03, 0x7A, 0x55, 0x80, 0x7F, 0x46, + 0x4E, 0x96, 0xA7, 0xF4, 0x1E, 0x3E, 0xE1, 0xF6, 0xD8, 0x09, 0xE1, 0x33, + 0x64, 0x2B, 0x63, 0xD7, 0x32, 0x5E, 0x9F, 0xF9, 0xC0, 0x7B, 0x0F, 0x78, + 0x6F, 0x97, 0xBC, 0x93, 0x9A, 0xF9, 0x9C, 0x12, 0x90, 0x78, 0x7A, 0x80, + 0x87, 0x15, 0xD7, 0x72, 0x74, 0x9C, 0x55, 0x74, 0x78, 0xB1, 0xBA, 0xE1, + 0x6E, 0x70, 0x04, 0xBA, 0x4F, 0xA0, 0xBA, 0x68, 0xC3, 0x7B, 0xFF, 0x31, + 0xF0, 0x73, 0x3D, 0x3D, 0x94, 0x2A, 0xB1, 0x0B, 0x41, 0x0E, 0xA0, 0xFE, + 0x4D, 0x88, 0x65, 0x6B, 0x79, 0x33, 0xB4, 0xD7 +}; + +static const unsigned char TA477_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA478_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x53, 0x65, 0x63, 0x74, 0x6F, 0x72, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA478_RSA_N[] = { + 0xB6, 0x22, 0x94, 0xFC, 0xA4, 0x48, 0xAF, 0xE8, 0x47, 0x6B, 0x0A, 0xFB, + 0x27, 0x76, 0xE4, 0xF2, 0x3F, 0x8A, 0x3B, 0x7A, 0x4A, 0x2C, 0x31, 0x2A, + 0x8C, 0x8D, 0xB0, 0xA9, 0xC3, 0x31, 0x6B, 0xA8, 0x77, 0x76, 0x84, 0x26, + 0xB6, 0xAC, 0x81, 0x42, 0x0D, 0x08, 0xEB, 0x55, 0x58, 0xBB, 0x7A, 0xF8, + 0xBC, 0x65, 0x7D, 0xF2, 0xA0, 0x6D, 0x8B, 0xA8, 0x47, 0xE9, 0x62, 0x76, + 0x1E, 0x11, 0xEE, 0x08, 0x14, 0xD1, 0xB2, 0x44, 0x16, 0xF4, 0xEA, 0xD0, + 0xFA, 0x1E, 0x2F, 0x5E, 0xDB, 0xCB, 0x73, 0x41, 0xAE, 0xBC, 0x00, 0xB0, + 0x4A, 0x2B, 0x40, 0xB2, 0xAC, 0xE1, 0x3B, 0x4B, 0xC2, 0x2D, 0x9D, 0xE4, + 0xA1, 0x9B, 0xEC, 0x1A, 0x3A, 0x1E, 0xF0, 0x08, 0xB3, 0xD0, 0xE4, 0x24, + 0x35, 0x07, 0x9F, 0x9C, 0xB4, 0xC9, 0x52, 0x6D, 0xDB, 0x07, 0xCA, 0x8F, + 0xB5, 0x5B, 0xF0, 0x83, 0xF3, 0x4F, 0xC7, 0x2D, 0xA5, 0xC8, 0xAD, 0xCB, + 0x95, 0x20, 0xA4, 0x31, 0x28, 0x57, 0x58, 0x5A, 0xE4, 0x8D, 0x1B, 0x9A, + 0xAB, 0x9E, 0x0D, 0x0C, 0xF2, 0x0A, 0x33, 0x39, 0x22, 0x39, 0x0A, 0x97, + 0x2E, 0xF3, 0x53, 0x77, 0xB9, 0x44, 0x45, 0xFD, 0x84, 0xCB, 0x36, 0x20, + 0x81, 0x59, 0x2D, 0x9A, 0x6F, 0x6D, 0x48, 0x48, 0x61, 0xCA, 0x4C, 0xDF, + 0x53, 0xD1, 0xAF, 0x52, 0xBC, 0x44, 0x9F, 0xAB, 0x2F, 0x6B, 0x83, 0x72, + 0xEF, 0x75, 0x80, 0xDA, 0x06, 0x33, 0x1B, 0x5D, 0xC8, 0xDA, 0x63, 0xC6, + 0x4D, 0xCD, 0xAC, 0x66, 0x31, 0xCD, 0xD1, 0xDE, 0x3E, 0x87, 0x10, 0x36, + 0xE1, 0xB9, 0xA4, 0x7A, 0xEF, 0x60, 0x50, 0xB2, 0xCB, 0xCA, 0xA6, 0x56, + 0xE0, 0x37, 0xAF, 0xAB, 0x34, 0x13, 0x39, 0x25, 0xE8, 0x39, 0x66, 0xE4, + 0x98, 0x7A, 0xAA, 0x12, 0x98, 0x9C, 0x59, 0x66, 0x86, 0x3E, 0xAD, 0xF1, + 0xB0, 0xCA, 0x3E, 0x06, 0x0F, 0x7B, 0xF0, 0x11, 0x4B, 0x37, 0xA0, 0x44, + 0x6D, 0x7B, 0xCB, 0xA8, 0x8C, 0x71, 0xF4, 0xD5, 0xB5, 0x91, 0x36, 0xCC, + 0xF0, 0x15, 0xC6, 0x2B, 0xDE, 0x51, 0x17, 0xB1, 0x97, 0x4C, 0x50, 0x3D, + 0xB1, 0x95, 0x59, 0x7C, 0x05, 0x7D, 0x2D, 0x21, 0xD5, 0x00, 0xBF, 0x01, + 0x67, 0xA2, 0x5E, 0x7B, 0xA6, 0x5C, 0xF2, 0xF7, 0x22, 0xF1, 0x90, 0x0D, + 0x93, 0xDB, 0xAA, 0x44, 0x51, 0x66, 0xCC, 0x7D, 0x76, 0x03, 0xEB, 0x6A, + 0xA8, 0x2A, 0x38, 0x19, 0x97, 0x76, 0x0D, 0x6B, 0x8A, 0x61, 0xF9, 0xBC, + 0xF6, 0xEE, 0x76, 0xFD, 0x70, 0x2B, 0xDD, 0x29, 0x3C, 0xF8, 0x0A, 0x1E, + 0x5B, 0x42, 0x1C, 0x8B, 0x56, 0x2F, 0x55, 0x1B, 0x1C, 0xA1, 0x2E, 0xB5, + 0xC7, 0x16, 0xE6, 0xF8, 0xAA, 0x3C, 0x92, 0x8E, 0x69, 0xB6, 0x01, 0xC1, + 0xB5, 0x86, 0x9D, 0x89, 0x0F, 0x0B, 0x38, 0x94, 0x54, 0xE8, 0xEA, 0xDC, + 0x9E, 0x3D, 0x25, 0xBC, 0x53, 0x26, 0xED, 0xD5, 0xAB, 0x39, 0xAA, 0xC5, + 0x40, 0x4C, 0x54, 0xAB, 0xB2, 0xB4, 0xD9, 0xD9, 0xF8, 0xD7, 0x72, 0xDB, + 0x1C, 0xBC, 0x6D, 0xBD, 0x65, 0x5F, 0xEF, 0x88, 0x35, 0x2A, 0x66, 0x2F, + 0xEE, 0xF6, 0xB3, 0x65, 0xF0, 0x33, 0x8D, 0x7C, 0x98, 0x41, 0x69, 0x46, + 0x0F, 0x43, 0x1C, 0x69, 0xFA, 0x9B, 0xB5, 0xD0, 0x61, 0x6A, 0xCD, 0xCA, + 0x4B, 0xD9, 0x4C, 0x90, 0x46, 0xAB, 0x15, 0x59, 0xA1, 0x47, 0x54, 0x29, + 0x2E, 0x83, 0x28, 0x5F, 0x1C, 0xC2, 0xA2, 0xAB, 0x72, 0x17, 0x00, 0x06, + 0x8E, 0x45, 0xEC, 0x8B, 0xE2, 0x33, 0x3D, 0x7F, 0xDA, 0x19, 0x44, 0xE4, + 0x62, 0x72, 0xC3, 0xDF, 0x22, 0xC6, 0xF2, 0x56, 0xD4, 0xDD, 0x5F, 0x95, + 0x72, 0xED, 0x6D, 0x5F, 0xF7, 0x48, 0x03, 0x5B, 0xFD, 0xC5, 0x2A, 0xA0, + 0xF6, 0x73, 0x23, 0x84, 0x10, 0x1B, 0x01, 0xE7 +}; + +static const unsigned char TA478_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA479_DN[] = { + 0x30, 0x38, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x49, 0x5A, 0x45, 0x4E, 0x50, 0x45, 0x20, 0x53, 0x2E, 0x41, + 0x2E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0A, + 0x49, 0x7A, 0x65, 0x6E, 0x70, 0x65, 0x2E, 0x63, 0x6F, 0x6D +}; + +static const unsigned char TA479_RSA_N[] = { + 0xC9, 0xD3, 0x7A, 0xCA, 0x0F, 0x1E, 0xAC, 0xA7, 0x86, 0xE8, 0x16, 0x65, + 0x6A, 0xB1, 0xC2, 0x1B, 0x45, 0x32, 0x71, 0x95, 0xD9, 0xFE, 0x10, 0x5B, + 0xCC, 0xAF, 0xE7, 0xA5, 0x79, 0x01, 0x8F, 0x89, 0xC3, 0xCA, 0xF2, 0x55, + 0x71, 0xF7, 0x77, 0xBE, 0x77, 0x94, 0xF3, 0x72, 0xA4, 0x2C, 0x44, 0xD8, + 0x9E, 0x92, 0x9B, 0x14, 0x3A, 0xA1, 0xE7, 0x24, 0x90, 0x0A, 0x0A, 0x56, + 0x8E, 0xC5, 0xD8, 0x26, 0x94, 0xE1, 0xD9, 0x48, 0xE1, 0x2D, 0x3E, 0xDA, + 0x0A, 0x72, 0xDD, 0xA3, 0x99, 0x15, 0xDA, 0x81, 0xA2, 0x87, 0xF4, 0x7B, + 0x6E, 0x26, 0x77, 0x89, 0x58, 0xAD, 0xD6, 0xEB, 0x0C, 0xB2, 0x41, 0x7A, + 0x73, 0x6E, 0x6D, 0xDB, 0x7A, 0x78, 0x41, 0xE9, 0x08, 0x88, 0x12, 0x7E, + 0x87, 0x2E, 0x66, 0x11, 0x63, 0x6C, 0x54, 0xFB, 0x3C, 0x9D, 0x72, 0xC0, + 0xBC, 0x2E, 0xFF, 0xC2, 0xB7, 0xDD, 0x0D, 0x76, 0xE3, 0x3A, 0xD7, 0xF7, + 0xB4, 0x68, 0xBE, 0xA2, 0xF5, 0xE3, 0x81, 0x6E, 0xC1, 0x46, 0x6F, 0x5D, + 0x8D, 0xE0, 0x4D, 0xC6, 0x54, 0x55, 0x89, 0x1A, 0x33, 0x31, 0x0A, 0xB1, + 0x57, 0xB9, 0xA3, 0x8A, 0x98, 0xC3, 0xEC, 0x3B, 0x34, 0xC5, 0x95, 0x41, + 0x69, 0x7E, 0x75, 0xC2, 0x3C, 0x20, 0xC5, 0x61, 0xBA, 0x51, 0x47, 0xA0, + 0x20, 0x90, 0x93, 0xA1, 0x90, 0x4B, 0xF3, 0x4E, 0x7C, 0x85, 0x45, 0x54, + 0x9A, 0xD1, 0x05, 0x26, 0x41, 0xB0, 0xB5, 0x4D, 0x1D, 0x33, 0xBE, 0xC4, + 0x03, 0xC8, 0x25, 0x7C, 0xC1, 0x70, 0xDB, 0x3B, 0xF4, 0x09, 0x2D, 0x54, + 0x27, 0x48, 0xAC, 0x2F, 0xE1, 0xC4, 0xAC, 0x3E, 0xC8, 0xCB, 0x92, 0x4C, + 0x53, 0x39, 0x37, 0x23, 0xEC, 0xD3, 0x01, 0xF9, 0xE0, 0x09, 0x44, 0x4D, + 0x4D, 0x64, 0xC0, 0xE1, 0x0D, 0x5A, 0x87, 0x22, 0xBC, 0xAD, 0x1B, 0xA3, + 0xFE, 0x26, 0xB5, 0x15, 0xF3, 0xA7, 0xFC, 0x84, 0x19, 0xE9, 0xEC, 0xA1, + 0x88, 0xB4, 0x44, 0x69, 0x84, 0x83, 0xF3, 0x89, 0xD1, 0x74, 0x06, 0xA9, + 0xCC, 0x0B, 0xD6, 0xC2, 0xDE, 0x27, 0x85, 0x50, 0x26, 0xCA, 0x17, 0xB8, + 0xC9, 0x7A, 0x87, 0x56, 0x2C, 0x1A, 0x01, 0x1E, 0x6C, 0xBE, 0x13, 0xAD, + 0x10, 0xAC, 0xB5, 0x24, 0xF5, 0x38, 0x91, 0xA1, 0xD6, 0x4B, 0xDA, 0xF1, + 0xBB, 0xD2, 0xDE, 0x47, 0xB5, 0xF1, 0xBC, 0x81, 0xF6, 0x59, 0x6B, 0xCF, + 0x19, 0x53, 0xE9, 0x8D, 0x15, 0xCB, 0x4A, 0xCB, 0xA9, 0x6F, 0x44, 0xE5, + 0x1B, 0x41, 0xCF, 0xE1, 0x86, 0xA7, 0xCA, 0xD0, 0x6A, 0x9F, 0xBC, 0x4C, + 0x8D, 0x06, 0x33, 0x5A, 0xA2, 0x85, 0xE5, 0x90, 0x35, 0xA0, 0x62, 0x5C, + 0x16, 0x4E, 0xF0, 0xE3, 0xA2, 0xFA, 0x03, 0x1A, 0xB4, 0x2C, 0x71, 0xB3, + 0x58, 0x2C, 0xDE, 0x7B, 0x0B, 0xDB, 0x1A, 0x0F, 0xEB, 0xDE, 0x21, 0x1F, + 0x06, 0x77, 0x06, 0x03, 0xB0, 0xC9, 0xEF, 0x99, 0xFC, 0xC0, 0xB9, 0x4F, + 0x0B, 0x86, 0x28, 0xFE, 0xD2, 0xB9, 0xEA, 0xE3, 0xDA, 0xA5, 0xC3, 0x47, + 0x69, 0x12, 0xE0, 0xDB, 0xF0, 0xF6, 0x19, 0x8B, 0xED, 0x7B, 0x70, 0xD7, + 0x02, 0xD6, 0xED, 0x87, 0x18, 0x28, 0x2C, 0x04, 0x24, 0x4C, 0x77, 0xE4, + 0x48, 0x8A, 0x1A, 0xC6, 0x3B, 0x9A, 0xD4, 0x0F, 0xCA, 0xFA, 0x75, 0xD2, + 0x01, 0x40, 0x5A, 0x8D, 0x79, 0xBF, 0x8B, 0xCF, 0x4B, 0xCF, 0xAA, 0x16, + 0xC1, 0x95, 0xE4, 0xAD, 0x4C, 0x8A, 0x3E, 0x17, 0x91, 0xD4, 0xB1, 0x62, + 0xE5, 0x82, 0xE5, 0x80, 0x04, 0xA4, 0x03, 0x7E, 0x8D, 0xBF, 0xDA, 0x7F, + 0xA2, 0x0F, 0x97, 0x4F, 0x0C, 0xD3, 0x0D, 0xFB, 0xD7, 0xD1, 0xE5, 0x72, + 0x7E, 0x1C, 0xC8, 0x77, 0xFF, 0x5B, 0x9A, 0x0F, 0xB7, 0xAE, 0x05, 0x46, + 0xE5, 0xF1, 0xA8, 0x16, 0xEC, 0x47, 0xA4, 0x17 +}; + +static const unsigned char TA479_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA480_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x65, 0x2D, 0x53, 0x7A, 0x69, + 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x32, 0x30, 0x30, 0x39, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x65, 0x2D, 0x73, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x2E, 0x68, + 0x75 +}; + +static const unsigned char TA480_RSA_N[] = { + 0xE9, 0xF8, 0x8F, 0xF3, 0x63, 0xAD, 0xDA, 0x86, 0xD8, 0xA7, 0xE0, 0x42, + 0xFB, 0xCF, 0x91, 0xDE, 0xA6, 0x26, 0xF8, 0x99, 0xA5, 0x63, 0x70, 0xAD, + 0x9B, 0xAE, 0xCA, 0x33, 0x40, 0x7D, 0x6D, 0x96, 0x6E, 0xA1, 0x0E, 0x44, + 0xEE, 0xE1, 0x13, 0x9D, 0x94, 0x42, 0x52, 0x9A, 0xBD, 0x75, 0x85, 0x74, + 0x2C, 0xA8, 0x0E, 0x1D, 0x93, 0xB6, 0x18, 0xB7, 0x8C, 0x2C, 0xA8, 0xCF, + 0xFB, 0x5C, 0x71, 0xB9, 0xDA, 0xEC, 0xFE, 0xE8, 0x7E, 0x8F, 0xE4, 0x2F, + 0x1D, 0xB2, 0xA8, 0x75, 0x87, 0xD8, 0xB7, 0xA1, 0xE5, 0x3B, 0xCF, 0x99, + 0x4A, 0x46, 0xD0, 0x83, 0x19, 0x7D, 0xC0, 0xA1, 0x12, 0x1C, 0x95, 0x6D, + 0x4A, 0xF4, 0xD8, 0xC7, 0xA5, 0x4D, 0x33, 0x2E, 0x85, 0x39, 0x40, 0x75, + 0x7E, 0x14, 0x7C, 0x80, 0x12, 0x98, 0x50, 0xC7, 0x41, 0x67, 0xB8, 0xA0, + 0x80, 0x61, 0x54, 0xA6, 0x6C, 0x4E, 0x1F, 0xE0, 0x9D, 0x0E, 0x07, 0xE9, + 0xC9, 0xBA, 0x33, 0xE7, 0xFE, 0xC0, 0x55, 0x28, 0x2C, 0x02, 0x80, 0xA7, + 0x19, 0xF5, 0x9E, 0xDC, 0x55, 0x53, 0x03, 0x97, 0x7B, 0x07, 0x48, 0xFF, + 0x99, 0xFB, 0x37, 0x8A, 0x24, 0xC4, 0x59, 0xCC, 0x50, 0x10, 0x63, 0x8E, + 0xAA, 0xA9, 0x1A, 0xB0, 0x84, 0x1A, 0x86, 0xF9, 0x5F, 0xBB, 0xB1, 0x50, + 0x6E, 0xA4, 0xD1, 0x0A, 0xCC, 0xD5, 0x71, 0x7E, 0x1F, 0xA7, 0x1B, 0x7C, + 0xF5, 0x53, 0x6E, 0x22, 0x5F, 0xCB, 0x2B, 0xE6, 0xD4, 0x7C, 0x5D, 0xAE, + 0xD6, 0xC2, 0xC6, 0x4C, 0xE5, 0x05, 0x01, 0xD9, 0xED, 0x57, 0xFC, 0xC1, + 0x23, 0x79, 0xFC, 0xFA, 0xC8, 0x24, 0x83, 0x95, 0xF3, 0xB5, 0x6A, 0x51, + 0x01, 0xD0, 0x77, 0xD6, 0xE9, 0x12, 0xA1, 0xF9, 0x1A, 0x83, 0xFB, 0x82, + 0x1B, 0xB9, 0xB0, 0x97, 0xF4, 0x76, 0x06, 0x33, 0x43, 0x49, 0xA0, 0xFF, + 0x0B, 0xB5, 0xFA, 0xB5 +}; + +static const unsigned char TA480_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA481_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA481_EC_Q[] = { + 0x04, 0xD4, 0xBC, 0x3D, 0x02, 0x42, 0x75, 0x41, 0x13, 0x23, 0xCD, 0x80, + 0x04, 0x86, 0x02, 0x51, 0x2F, 0x6A, 0xA8, 0x81, 0x62, 0x0B, 0x65, 0xCC, + 0xF6, 0xCA, 0x9D, 0x1E, 0x6F, 0x4A, 0x66, 0x51, 0xA2, 0x03, 0xD9, 0x9D, + 0x91, 0xFA, 0xB6, 0x16, 0xB1, 0x8C, 0x6E, 0xDE, 0x7C, 0xCD, 0xDB, 0x79, + 0xA6, 0x2F, 0xCE, 0xBB, 0xCE, 0x71, 0x2F, 0xE5, 0xA5, 0xAB, 0x28, 0xEC, + 0x63, 0x04, 0x66, 0x99, 0xF8, 0xFA, 0xF2, 0x93, 0x10, 0x05, 0xE1, 0x81, + 0x28, 0x42, 0xE3, 0xC6, 0x68, 0xF4, 0xE6, 0x1B, 0x84, 0x60, 0x4A, 0x89, + 0xAF, 0xED, 0x79, 0x0F, 0x3B, 0xCE, 0xF1, 0xF6, 0x44, 0xF5, 0x01, 0x78, + 0xC0 +}; + +static const unsigned char TA482_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA482_RSA_N[] = { + 0xCA, 0x5B, 0xBE, 0x94, 0x33, 0x8C, 0x29, 0x95, 0x91, 0x16, 0x0A, 0x95, + 0xBD, 0x47, 0x62, 0xC1, 0x89, 0xF3, 0x99, 0x36, 0xDF, 0x46, 0x90, 0xC9, + 0xA5, 0xED, 0x78, 0x6A, 0x6F, 0x47, 0x91, 0x68, 0xF8, 0x27, 0x67, 0x50, + 0x33, 0x1D, 0xA1, 0xA6, 0xFB, 0xE0, 0xE5, 0x43, 0xA3, 0x84, 0x02, 0x57, + 0x01, 0x5D, 0x9C, 0x48, 0x40, 0x82, 0x53, 0x10, 0xBC, 0xBF, 0xC7, 0x3B, + 0x68, 0x90, 0xB6, 0x82, 0x2D, 0xE5, 0xF4, 0x65, 0xD0, 0xCC, 0x6D, 0x19, + 0xCC, 0x95, 0xF9, 0x7B, 0xAC, 0x4A, 0x94, 0xAD, 0x0E, 0xDE, 0x4B, 0x43, + 0x1D, 0x87, 0x07, 0x92, 0x13, 0x90, 0x80, 0x83, 0x64, 0x35, 0x39, 0x04, + 0xFC, 0xE5, 0xE9, 0x6C, 0xB3, 0xB6, 0x1F, 0x50, 0x94, 0x38, 0x65, 0x50, + 0x5C, 0x17, 0x46, 0xB9, 0xB6, 0x85, 0xB5, 0x1C, 0xB5, 0x17, 0xE8, 0xD6, + 0x45, 0x9D, 0xD8, 0xB2, 0x26, 0xB0, 0xCA, 0xC4, 0x70, 0x4A, 0xAE, 0x60, + 0xA4, 0xDD, 0xB3, 0xD9, 0xEC, 0xFC, 0x3B, 0xD5, 0x57, 0x72, 0xBC, 0x3F, + 0xC8, 0xC9, 0xB2, 0xDE, 0x4B, 0x6B, 0xF8, 0x23, 0x6C, 0x03, 0xC0, 0x05, + 0xBD, 0x95, 0xC7, 0xCD, 0x73, 0x3B, 0x66, 0x80, 0x64, 0xE3, 0x1A, 0xAC, + 0x2E, 0xF9, 0x47, 0x05, 0xF2, 0x06, 0xB6, 0x9B, 0x73, 0xF5, 0x78, 0x33, + 0x5B, 0xC7, 0xA1, 0xFB, 0x27, 0x2A, 0xA1, 0xB4, 0x9A, 0x91, 0x8C, 0x91, + 0xD3, 0x3A, 0x82, 0x3E, 0x76, 0x40, 0xB4, 0xCD, 0x52, 0x61, 0x51, 0x70, + 0x28, 0x3F, 0xC5, 0xC5, 0x5A, 0xF2, 0xC9, 0x8C, 0x49, 0xBB, 0x14, 0x5B, + 0x4D, 0xC8, 0xFF, 0x67, 0x4D, 0x4C, 0x12, 0x96, 0xAD, 0xF5, 0xFE, 0x78, + 0xA8, 0x97, 0x87, 0xD7, 0xFD, 0x5E, 0x20, 0x80, 0xDC, 0xA1, 0x4B, 0x22, + 0xFB, 0xD4, 0x89, 0xAD, 0xBA, 0xCE, 0x47, 0x97, 0x47, 0x55, 0x7B, 0x8F, + 0x45, 0xC8, 0x67, 0x28, 0x84, 0x95, 0x1C, 0x68, 0x30, 0xEF, 0xEF, 0x49, + 0xE0, 0x35, 0x7B, 0x64, 0xE7, 0x98, 0xB0, 0x94, 0xDA, 0x4D, 0x85, 0x3B, + 0x3E, 0x55, 0xC4, 0x28, 0xAF, 0x57, 0xF3, 0x9E, 0x13, 0xDB, 0x46, 0x27, + 0x9F, 0x1E, 0xA2, 0x5E, 0x44, 0x83, 0xA4, 0xA5, 0xCA, 0xD5, 0x13, 0xB3, + 0x4B, 0x3F, 0xC4, 0xE3, 0xC2, 0xE6, 0x86, 0x61, 0xA4, 0x52, 0x30, 0xB9, + 0x7A, 0x20, 0x4F, 0x6F, 0x0F, 0x38, 0x53, 0xCB, 0x33, 0x0C, 0x13, 0x2B, + 0x8F, 0xD6, 0x9A, 0xBD, 0x2A, 0xC8, 0x2D, 0xB1, 0x1C, 0x7D, 0x4B, 0x51, + 0xCA, 0x47, 0xD1, 0x48, 0x27, 0x72, 0x5D, 0x87, 0xEB, 0xD5, 0x45, 0xE6, + 0x48, 0x65, 0x9D, 0xAF, 0x52, 0x90, 0xBA, 0x5B, 0xA2, 0x18, 0x65, 0x57, + 0x12, 0x9F, 0x68, 0xB9, 0xD4, 0x15, 0x6B, 0x94, 0xC4, 0x69, 0x22, 0x98, + 0xF4, 0x33, 0xE0, 0xED, 0xF9, 0x51, 0x8E, 0x41, 0x50, 0xC9, 0x34, 0x4F, + 0x76, 0x90, 0xAC, 0xFC, 0x38, 0xC1, 0xD8, 0xE1, 0x7B, 0xB9, 0xE3, 0xE3, + 0x94, 0xE1, 0x46, 0x69, 0xCB, 0x0E, 0x0A, 0x50, 0x6B, 0x13, 0xBA, 0xAC, + 0x0F, 0x37, 0x5A, 0xB7, 0x12, 0xB5, 0x90, 0x81, 0x1E, 0x56, 0xAE, 0x57, + 0x22, 0x86, 0xD9, 0xC9, 0xD2, 0xD1, 0xD7, 0x51, 0xE3, 0xAB, 0x3B, 0xC6, + 0x55, 0xFD, 0x1E, 0x0E, 0xD3, 0x74, 0x0A, 0xD1, 0xDA, 0xAA, 0xEA, 0x69, + 0xB8, 0x97, 0x28, 0x8F, 0x48, 0xC4, 0x07, 0xF8, 0x52, 0x43, 0x3A, 0xF4, + 0xCA, 0x55, 0x35, 0x2C, 0xB0, 0xA6, 0x6A, 0xC0, 0x9C, 0xF9, 0xF2, 0x81, + 0xE1, 0x12, 0x6A, 0xC0, 0x45, 0xD9, 0x67, 0xB3, 0xCE, 0xFF, 0x23, 0xA2, + 0x89, 0x0A, 0x54, 0xD4, 0x14, 0xB9, 0x2A, 0xA8, 0xD7, 0xEC, 0xF9, 0xAB, + 0xCD, 0x25, 0x58, 0x32, 0x79, 0x8F, 0x90, 0x5B, 0x98, 0x39, 0xC4, 0x08, + 0x06, 0xC1, 0xAC, 0x7F, 0x0E, 0x3D, 0x00, 0xA5 +}; + +static const unsigned char TA482_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA483_DN[] = { + 0x30, 0x69, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4B, 0x52, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, 0x42, 0x55, 0x53, 0x49, + 0x4E, 0x45, 0x53, 0x53, 0x20, 0x50, 0x4C, 0x41, 0x54, 0x46, 0x4F, 0x52, + 0x4D, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA483_RSA_N[] = { + 0xB6, 0xD4, 0xF1, 0x93, 0x5C, 0xB5, 0x40, 0x89, 0x0A, 0xAB, 0x0D, 0x90, + 0x5B, 0x50, 0x63, 0xAE, 0x90, 0x94, 0x74, 0x17, 0x45, 0x72, 0xD6, 0x7B, + 0x65, 0x5A, 0x29, 0x4B, 0xA7, 0x56, 0xA0, 0x4B, 0xB8, 0x2F, 0x42, 0x75, + 0xE9, 0xD9, 0x7B, 0x24, 0x5A, 0x31, 0x65, 0xAB, 0x17, 0x17, 0xD1, 0x33, + 0x3A, 0xD9, 0x11, 0xDC, 0x40, 0x36, 0x87, 0xDF, 0xC7, 0x6A, 0xE9, 0x26, + 0x5E, 0x59, 0x8A, 0x77, 0xE3, 0xE8, 0x48, 0x9C, 0x31, 0x16, 0xFA, 0x3E, + 0x91, 0xB1, 0xCA, 0xC9, 0xA3, 0xE2, 0x9F, 0xCE, 0x21, 0x53, 0xA3, 0x02, + 0x36, 0x30, 0xCB, 0x52, 0x02, 0xE5, 0xDA, 0x32, 0x5D, 0xC3, 0xC5, 0xE6, + 0xF9, 0xEE, 0x11, 0xC7, 0x8B, 0xC9, 0x44, 0x1E, 0x84, 0x93, 0x18, 0x4A, + 0xB4, 0x9F, 0xE5, 0x12, 0x64, 0x69, 0xD0, 0x26, 0x85, 0x62, 0x01, 0xB6, + 0xC9, 0x02, 0x1D, 0xBE, 0x83, 0x51, 0xBB, 0x5C, 0xDA, 0xF8, 0xAD, 0x15, + 0x6A, 0x99, 0xF7, 0x92, 0x54, 0xF7, 0x34, 0x5B, 0xE9, 0xBF, 0xEA, 0x29, + 0x81, 0x12, 0xD4, 0x53, 0x91, 0x96, 0xB3, 0x91, 0x5A, 0xDD, 0xFE, 0x90, + 0x73, 0x28, 0xFB, 0x30, 0x46, 0xB5, 0xCA, 0x08, 0x07, 0xC7, 0x71, 0x72, + 0xC9, 0x66, 0xD3, 0x34, 0x97, 0xF6, 0x8C, 0xF4, 0x18, 0x4A, 0xE1, 0xD0, + 0x3D, 0x5A, 0x45, 0xB6, 0x69, 0xA7, 0x29, 0xFB, 0x23, 0xCE, 0x88, 0xD8, + 0x12, 0x9C, 0x00, 0x48, 0xA8, 0xA6, 0x0F, 0xB3, 0x3B, 0x92, 0x8D, 0x71, + 0x0E, 0x74, 0xC5, 0x8B, 0xC8, 0x4C, 0xF9, 0xF4, 0x9B, 0x8E, 0xB8, 0x3C, + 0x69, 0xED, 0x6F, 0x3B, 0x50, 0x2F, 0x58, 0xED, 0xC4, 0xB0, 0xD0, 0x1C, + 0x1B, 0x6A, 0x0C, 0xE2, 0xBC, 0x44, 0xAA, 0xD8, 0xCD, 0x14, 0x5D, 0x94, + 0x78, 0x61, 0xBF, 0x0E, 0x6E, 0xDA, 0x2A, 0xBC, 0x2F, 0x0C, 0x0B, 0x71, + 0xA6, 0xB3, 0x16, 0x3F, 0x9C, 0xE6, 0xF9, 0xCC, 0x9F, 0x53, 0x35, 0xE2, + 0x03, 0xA0, 0xA0, 0x18, 0xBF, 0xBB, 0xF1, 0xBE, 0xF4, 0xD6, 0x8C, 0x87, + 0x0D, 0x42, 0xF7, 0x06, 0xB9, 0xF1, 0x6D, 0xED, 0x04, 0x94, 0xA8, 0xFE, + 0xB6, 0xD3, 0x06, 0xC6, 0x40, 0x61, 0xDF, 0x9D, 0x9D, 0xF3, 0x54, 0x76, + 0xCE, 0x53, 0x3A, 0x01, 0xA6, 0x92, 0x41, 0xEC, 0x04, 0xA3, 0x8F, 0x0D, + 0xA2, 0xD5, 0x09, 0xCA, 0xD6, 0xCB, 0x9A, 0xF1, 0xEF, 0x43, 0x5D, 0xC0, + 0xAB, 0xA5, 0x41, 0xCF, 0x5C, 0x53, 0x70, 0x70, 0xC9, 0x88, 0xA6, 0x2D, + 0xD4, 0x6B, 0x61, 0x73, 0x50, 0x26, 0x86, 0x61, 0x0E, 0x5F, 0x1B, 0xC2, + 0x2B, 0xE2, 0x8C, 0xD5, 0xBB, 0x9D, 0xC1, 0x03, 0x42, 0xBA, 0x94, 0xDA, + 0x5F, 0xA9, 0xB0, 0xCA, 0xCC, 0x4D, 0x0A, 0xEF, 0x47, 0x69, 0x03, 0x2F, + 0x22, 0xFB, 0xF1, 0x28, 0xCE, 0xBF, 0x5D, 0x50, 0x65, 0xA8, 0x90, 0x6D, + 0xB3, 0x74, 0xB0, 0x08, 0xC7, 0xAC, 0xA8, 0xD1, 0xEB, 0x3E, 0x9C, 0xFC, + 0x5D, 0x1A, 0x83, 0x2E, 0x2B, 0xCB, 0xB5, 0xF3, 0x44, 0x9D, 0x3A, 0xA7, + 0x17, 0x61, 0x96, 0xA2, 0x71, 0xD3, 0x70, 0x96, 0x15, 0x4D, 0xB7, 0x4C, + 0x73, 0xEE, 0x19, 0x5C, 0xC5, 0x5B, 0x3E, 0x41, 0xFE, 0xAC, 0x75, 0x60, + 0x3B, 0x1B, 0x63, 0xCE, 0x00, 0xDD, 0xDA, 0x08, 0x90, 0x62, 0xB4, 0xE5, + 0x2D, 0xEE, 0x48, 0xA7, 0x6B, 0x17, 0x99, 0x54, 0xBE, 0x87, 0x4A, 0xE3, + 0xA9, 0x5E, 0x04, 0x4C, 0xEB, 0x10, 0x6D, 0x54, 0xD6, 0xEF, 0xF1, 0xE8, + 0xF2, 0x62, 0x16, 0xCB, 0x80, 0x6B, 0xED, 0x3D, 0xED, 0xF5, 0x1F, 0x30, + 0xA5, 0xAE, 0x4B, 0xC9, 0x13, 0xED, 0x8A, 0x01, 0x01, 0xC9, 0xB8, 0x51, + 0x58, 0xC0, 0x66, 0x3A, 0xB1, 0x66, 0x4B, 0xC4, 0xD5, 0x31, 0x02, 0x62, + 0xE9, 0x74, 0x84, 0x0C, 0xDB, 0x4D, 0x46, 0x2D +}; + +static const unsigned char TA483_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA484_DN[] = { + 0x30, 0x81, 0xA7, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x4E, 0x65, + 0x74, 0x4C, 0x6F, 0x63, 0x6B, 0x20, 0x4B, 0x66, 0x74, 0x2E, 0x31, 0x37, + 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x2E, 0x54, 0x61, 0x6E, + 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, 0x6E, 0x79, 0x6B, + 0x69, 0x61, 0x64, 0xC3, 0xB3, 0x6B, 0x20, 0x28, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x29, 0x31, 0x35, 0x30, 0x33, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x2C, 0x4E, 0x65, 0x74, 0x4C, 0x6F, 0x63, + 0x6B, 0x20, 0x41, 0x72, 0x61, 0x6E, 0x79, 0x20, 0x28, 0x43, 0x6C, 0x61, + 0x73, 0x73, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x29, 0x20, 0x46, 0xC5, 0x91, + 0x74, 0x61, 0x6E, 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, + 0x6E, 0x79 +}; + +static const unsigned char TA484_RSA_N[] = { + 0xC4, 0x24, 0x5E, 0x73, 0xBE, 0x4B, 0x6D, 0x14, 0xC3, 0xA1, 0xF4, 0xE3, + 0x97, 0x90, 0x6E, 0xD2, 0x30, 0x45, 0x1E, 0x3C, 0xEE, 0x67, 0xD9, 0x64, + 0xE0, 0x1A, 0x8A, 0x7F, 0xCA, 0x30, 0xCA, 0x83, 0xE3, 0x20, 0xC1, 0xE3, + 0xF4, 0x3A, 0xD3, 0x94, 0x5F, 0x1A, 0x7C, 0x5B, 0x6D, 0xBF, 0x30, 0x4F, + 0x84, 0x27, 0xF6, 0x9F, 0x1F, 0x49, 0xBC, 0xC6, 0x99, 0x0A, 0x90, 0xF2, + 0x0F, 0xF5, 0x7F, 0x43, 0x84, 0x37, 0x63, 0x51, 0x8B, 0x7A, 0xA5, 0x70, + 0xFC, 0x7A, 0x58, 0xCD, 0x8E, 0x9B, 0xED, 0xC3, 0x46, 0x6C, 0x84, 0x70, + 0x5D, 0xDA, 0xF3, 0x01, 0x90, 0x23, 0xFC, 0x4E, 0x30, 0xA9, 0x7E, 0xE1, + 0x27, 0x63, 0xE7, 0xED, 0x64, 0x3C, 0xA0, 0xB8, 0xC9, 0x33, 0x63, 0xFE, + 0x16, 0x90, 0xFF, 0xB0, 0xB8, 0xFD, 0xD7, 0xA8, 0xC0, 0xC0, 0x94, 0x43, + 0x0B, 0xB6, 0xD5, 0x59, 0xA6, 0x9E, 0x56, 0xD0, 0x24, 0x1F, 0x70, 0x79, + 0xAF, 0xDB, 0x39, 0x54, 0x0D, 0x65, 0x75, 0xD9, 0x15, 0x41, 0x94, 0x01, + 0xAF, 0x5E, 0xEC, 0xF6, 0x8D, 0xF1, 0xFF, 0xAD, 0x64, 0xFE, 0x20, 0x9A, + 0xD7, 0x5C, 0xEB, 0xFE, 0xA6, 0x1F, 0x08, 0x64, 0xA3, 0x8B, 0x76, 0x55, + 0xAD, 0x1E, 0x3B, 0x28, 0x60, 0x2E, 0x87, 0x25, 0xE8, 0xAA, 0xAF, 0x1F, + 0xC6, 0x64, 0x46, 0x20, 0xB7, 0x70, 0x7F, 0x3C, 0xDE, 0x48, 0xDB, 0x96, + 0x53, 0xB7, 0x39, 0x77, 0xE4, 0x1A, 0xE2, 0xC7, 0x16, 0x84, 0x76, 0x97, + 0x5B, 0x2F, 0xBB, 0x19, 0x15, 0x85, 0xF8, 0x69, 0x85, 0xF5, 0x99, 0xA7, + 0xA9, 0xF2, 0x34, 0xA7, 0xA9, 0xB6, 0xA6, 0x03, 0xFC, 0x6F, 0x86, 0x3D, + 0x54, 0x7C, 0x76, 0x04, 0x9B, 0x6B, 0xF9, 0x40, 0x5D, 0x00, 0x34, 0xC7, + 0x2E, 0x99, 0x75, 0x9D, 0xE5, 0x88, 0x03, 0xAA, 0x4D, 0xF8, 0x03, 0xD2, + 0x42, 0x76, 0xC0, 0x1B +}; + +static const unsigned char TA484_RSA_E[] = { + 0xA8, 0x8B +}; + +static const unsigned char TA485_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x42, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA485_RSA_N[] = { + 0xD8, 0x17, 0xB7, 0x1C, 0x4A, 0x24, 0x2A, 0xD6, 0x97, 0xB1, 0xCA, 0xE2, + 0x1E, 0xFB, 0x7D, 0x38, 0xEF, 0x98, 0xF5, 0xB2, 0x39, 0x98, 0x4E, 0x27, + 0xB8, 0x11, 0x5D, 0x7B, 0xD2, 0x25, 0x94, 0x88, 0x82, 0x15, 0x26, 0x6A, + 0x1B, 0x31, 0xBB, 0xA8, 0x5B, 0x21, 0x21, 0x2B, 0xD8, 0x0F, 0x4E, 0x9F, + 0x5A, 0xF1, 0xB1, 0x5A, 0xE4, 0x79, 0xD6, 0x32, 0x23, 0x2B, 0xE1, 0x53, + 0xCC, 0x99, 0x45, 0x5C, 0x7B, 0x4F, 0xAD, 0xBC, 0xBF, 0x87, 0x4A, 0x0B, + 0x4B, 0x97, 0x5A, 0xA8, 0xF6, 0x48, 0xEC, 0x7D, 0x7B, 0x0D, 0xCD, 0x21, + 0x06, 0xDF, 0x9E, 0x15, 0xFD, 0x41, 0x8A, 0x48, 0xB7, 0x20, 0xF4, 0xA1, + 0x7A, 0x1B, 0x57, 0xD4, 0x5D, 0x50, 0xFF, 0xBA, 0x67, 0xD8, 0x23, 0x99, + 0x1F, 0xC8, 0x3F, 0xE3, 0xDE, 0xFF, 0x6F, 0x5B, 0x77, 0xB1, 0x6B, 0x6E, + 0xB8, 0xC9, 0x64, 0xF7, 0xE1, 0xCA, 0x41, 0x46, 0x0E, 0x29, 0x71, 0xD0, + 0xB9, 0x23, 0xFC, 0xC9, 0x81, 0x5F, 0x4E, 0xF7, 0x6F, 0xDF, 0xBF, 0x84, + 0xAD, 0x73, 0x64, 0xBB, 0xB7, 0x42, 0x8E, 0x69, 0xF6, 0xD4, 0x76, 0x1D, + 0x7E, 0x9D, 0xA7, 0xB8, 0x57, 0x8A, 0x51, 0x67, 0x72, 0xD7, 0xD4, 0xA8, + 0xB8, 0x95, 0x54, 0x40, 0x73, 0x03, 0xF6, 0xEA, 0xF4, 0xEB, 0xFE, 0x28, + 0x42, 0x77, 0x3F, 0x9D, 0x23, 0x1B, 0xB2, 0xB6, 0x3D, 0x80, 0x14, 0x07, + 0x4C, 0x2E, 0x4F, 0xF7, 0xD5, 0x0A, 0x16, 0x0D, 0xBD, 0x66, 0x43, 0x37, + 0x7E, 0x23, 0x43, 0x79, 0xC3, 0x40, 0x86, 0xF5, 0x4C, 0x29, 0xDA, 0x8E, + 0x9A, 0xAD, 0x0D, 0xA5, 0x04, 0x87, 0x88, 0x1E, 0x85, 0xE3, 0xE9, 0x53, + 0xD5, 0x9B, 0xC8, 0x8B, 0x03, 0x63, 0x78, 0xEB, 0xE0, 0x19, 0x4A, 0x6E, + 0xBB, 0x2F, 0x6B, 0x33, 0x64, 0x58, 0x93, 0xAD, 0x69, 0xBF, 0x8F, 0x1B, + 0xEF, 0x82, 0x48, 0xC7 +}; + +static const unsigned char TA485_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA486_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x43, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA486_EC_Q[] = { + 0x04, 0x4C, 0xE9, 0x50, 0xC0, 0xC6, 0x0F, 0x72, 0x18, 0xBC, 0xD8, 0xF1, + 0xBA, 0xB3, 0x89, 0xE2, 0x79, 0x4A, 0xA3, 0x16, 0xA7, 0x6B, 0x54, 0x24, + 0xDB, 0x51, 0xFF, 0xEA, 0xF4, 0x09, 0x24, 0xC3, 0x0B, 0x22, 0x9F, 0xCB, + 0x6A, 0x27, 0x82, 0x81, 0x0D, 0xD2, 0xC0, 0xAF, 0x31, 0xE4, 0x74, 0x82, + 0x6E, 0xCA, 0x25, 0xD9, 0x8C, 0x75, 0x9D, 0xF1, 0xDB, 0xD0, 0x9A, 0xA2, + 0x4B, 0x21, 0x7E, 0x16, 0xA7, 0x63, 0x90, 0xD2, 0x39, 0xD4, 0xB1, 0x87, + 0x78, 0x5F, 0x18, 0x96, 0x0F, 0x50, 0x1B, 0x35, 0x37, 0x0F, 0x6A, 0xC6, + 0xDC, 0xD9, 0x13, 0x4D, 0xA4, 0x8E, 0x90, 0x37, 0xE6, 0xBD, 0x5B, 0x31, + 0x91 +}; + +static const unsigned char TA487_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA487_RSA_N[] = { + 0xA0, 0xBE, 0x50, 0x10, 0x8E, 0xE9, 0xF2, 0x6C, 0x40, 0xB4, 0x04, 0x9C, + 0x85, 0xB9, 0x31, 0xCA, 0xDC, 0x2D, 0xE4, 0x11, 0xA9, 0x04, 0x3C, 0x1B, + 0x55, 0xC1, 0xE7, 0x58, 0x30, 0x1D, 0x24, 0xB4, 0xC3, 0xEF, 0x85, 0xDE, + 0x8C, 0x2C, 0xE1, 0xC1, 0x3D, 0xDF, 0x82, 0xE6, 0x4F, 0xAD, 0x47, 0x87, + 0x6C, 0xEC, 0x5B, 0x49, 0xC1, 0x4A, 0xD5, 0xBB, 0x8F, 0xEC, 0x87, 0xAC, + 0x7F, 0x82, 0x9A, 0x86, 0xEC, 0x3D, 0x03, 0x99, 0x52, 0x01, 0xD2, 0x35, + 0x9E, 0xAC, 0xDA, 0xF0, 0x53, 0xC9, 0x66, 0x3C, 0xD4, 0xAC, 0x02, 0x01, + 0xDA, 0x24, 0xD3, 0x3B, 0xA8, 0x02, 0x46, 0xAF, 0xA4, 0x1C, 0xE3, 0xF8, + 0x73, 0x58, 0x76, 0xB7, 0xF6, 0x0E, 0x90, 0x0D, 0xB5, 0xF0, 0xCF, 0xCC, + 0xFA, 0xF9, 0xC6, 0x4C, 0xE5, 0xC3, 0x86, 0x30, 0x0A, 0x8D, 0x17, 0x7E, + 0x35, 0xEB, 0xC5, 0xDF, 0xBB, 0x0E, 0x9C, 0xC0, 0x8D, 0x87, 0xE3, 0x88, + 0x38, 0x85, 0x67, 0xFA, 0x3E, 0xC7, 0xAB, 0xE0, 0x13, 0x9C, 0x05, 0x18, + 0x98, 0xCF, 0x93, 0xF5, 0xB1, 0x92, 0xB4, 0xFC, 0x23, 0xD3, 0xCF, 0xD5, + 0xC4, 0x27, 0x49, 0xE0, 0x9E, 0x3C, 0x9B, 0x08, 0xA3, 0x8B, 0x5D, 0x2A, + 0x21, 0xE0, 0xFC, 0x39, 0xAA, 0x53, 0xDA, 0x7D, 0x7E, 0xCF, 0x1A, 0x09, + 0x53, 0xBC, 0x5D, 0x05, 0x04, 0xCF, 0xA1, 0x4A, 0x8F, 0x8B, 0x76, 0x82, + 0x0D, 0xA1, 0xF8, 0xD2, 0xC7, 0x14, 0x77, 0x5B, 0x90, 0x36, 0x07, 0x81, + 0x9B, 0x3E, 0x06, 0xFA, 0x52, 0x5E, 0x63, 0xC5, 0xA6, 0x00, 0xFE, 0xA5, + 0xE9, 0x52, 0x1B, 0x52, 0xB5, 0x92, 0x39, 0x72, 0x03, 0x09, 0x62, 0xBD, + 0xB0, 0x60, 0x16, 0x6E, 0xA6, 0xDD, 0x25, 0xC2, 0x03, 0x66, 0xDD, 0xF3, + 0x04, 0xD1, 0x40, 0xE2, 0x4E, 0x8B, 0x86, 0xF4, 0x6F, 0xE5, 0x83, 0xA0, + 0x27, 0x84, 0x5E, 0x04, 0xC1, 0xF5, 0x90, 0xBD, 0x30, 0x3D, 0xC4, 0xEF, + 0xA8, 0x69, 0xBC, 0x38, 0x9B, 0xA4, 0xA4, 0x96, 0xD1, 0x62, 0xDA, 0x69, + 0xC0, 0x01, 0x96, 0xAE, 0xCB, 0xC4, 0x51, 0x34, 0xEA, 0x0C, 0xAA, 0xFF, + 0x21, 0x8E, 0x59, 0x8F, 0x4A, 0x5C, 0xE4, 0x61, 0x9A, 0xA7, 0xD2, 0xE9, + 0x2A, 0x78, 0x8D, 0x51, 0x3D, 0x3A, 0x15, 0xEE, 0xA2, 0x59, 0x8E, 0xA9, + 0x5C, 0xDE, 0xC5, 0xF9, 0x90, 0x22, 0xE5, 0x88, 0x45, 0x71, 0xDD, 0x91, + 0x99, 0x6C, 0x7A, 0x9F, 0x3D, 0x3D, 0x98, 0x7C, 0x5E, 0xF6, 0xBE, 0x16, + 0x68, 0xA0, 0x5E, 0xAE, 0x0B, 0x23, 0xFC, 0x5A, 0x0F, 0xAA, 0x22, 0x76, + 0x2D, 0xC9, 0xA1, 0x10, 0x1D, 0xE4, 0xD3, 0x44, 0x23, 0x90, 0x88, 0x9F, + 0xC6, 0x2A, 0xE6, 0xD7, 0xF5, 0x9A, 0xB3, 0x58, 0x1E, 0x2F, 0x30, 0x89, + 0x08, 0x1B, 0x54, 0xA2, 0xB5, 0x98, 0x23, 0xEC, 0x08, 0x77, 0x1C, 0x95, + 0x5D, 0x61, 0xD1, 0xCB, 0x89, 0x9C, 0x5F, 0xA2, 0x4A, 0x91, 0x9A, 0xEF, + 0x21, 0xAA, 0x49, 0x16, 0x08, 0xA8, 0xBD, 0x61, 0x28, 0x31, 0xC9, 0x74, + 0xAD, 0x85, 0xF6, 0xD9, 0xC5, 0xB1, 0x8B, 0xD1, 0xE5, 0x10, 0x32, 0x4D, + 0x5F, 0x8B, 0x20, 0x3A, 0x3C, 0x49, 0x1F, 0x33, 0x85, 0x59, 0x0D, 0xDB, + 0xCB, 0x09, 0x75, 0x43, 0x69, 0x73, 0xFB, 0x6B, 0x71, 0x7D, 0xF0, 0xDF, + 0xC4, 0x4C, 0x7D, 0xC6, 0xA3, 0x2E, 0xC8, 0x95, 0x79, 0xCB, 0x73, 0xA2, + 0x8E, 0x4E, 0x4D, 0x24, 0xFB, 0x5E, 0xE4, 0x04, 0xBE, 0x72, 0x1B, 0xA6, + 0x27, 0x2D, 0x49, 0x5A, 0x99, 0x7A, 0xD7, 0x5C, 0x09, 0x20, 0xB7, 0x7F, + 0x94, 0xB9, 0x4F, 0xF1, 0x0D, 0x1C, 0x5E, 0x88, 0x42, 0x1B, 0x11, 0xB7, + 0xE7, 0x91, 0xDB, 0x9E, 0x6C, 0xF4, 0x6A, 0xDF, 0x8C, 0x06, 0x98, 0x03, + 0xAD, 0xCC, 0x28, 0xEF, 0xA5, 0x47, 0xF3, 0x53 +}; + +static const unsigned char TA487_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA488_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA488_RSA_N[] = { + 0x9A, 0x18, 0xCA, 0x4B, 0x94, 0x0D, 0x00, 0x2D, 0xAF, 0x03, 0x29, 0x8A, + 0xF0, 0x0F, 0x81, 0xC8, 0xAE, 0x4C, 0x19, 0x85, 0x1D, 0x08, 0x9F, 0xAB, + 0x29, 0x44, 0x85, 0xF3, 0x2F, 0x81, 0xAD, 0x32, 0x1E, 0x90, 0x46, 0xBF, + 0xA3, 0x86, 0x26, 0x1A, 0x1E, 0xFE, 0x7E, 0x1C, 0x18, 0x3A, 0x5C, 0x9C, + 0x60, 0x17, 0x2A, 0x3A, 0x74, 0x83, 0x33, 0x30, 0x7D, 0x61, 0x54, 0x11, + 0xCB, 0xED, 0xAB, 0xE0, 0xE6, 0xD2, 0xA2, 0x7E, 0xF5, 0x6B, 0x6F, 0x18, + 0xB7, 0x0A, 0x0B, 0x2D, 0xFD, 0xE9, 0x3E, 0xEF, 0x0A, 0xC6, 0xB3, 0x10, + 0xE9, 0xDC, 0xC2, 0x46, 0x17, 0xF8, 0x5D, 0xFD, 0xA4, 0xDA, 0xFF, 0x9E, + 0x49, 0x5A, 0x9C, 0xE6, 0x33, 0xE6, 0x24, 0x96, 0xF7, 0x3F, 0xBA, 0x5B, + 0x2B, 0x1C, 0x7A, 0x35, 0xC2, 0xD6, 0x67, 0xFE, 0xAB, 0x66, 0x50, 0x8B, + 0x6D, 0x28, 0x60, 0x2B, 0xEF, 0xD7, 0x60, 0xC3, 0xC7, 0x93, 0xBC, 0x8D, + 0x36, 0x91, 0xF3, 0x7F, 0xF8, 0xDB, 0x11, 0x13, 0xC4, 0x9C, 0x77, 0x76, + 0xC1, 0xAE, 0xB7, 0x02, 0x6A, 0x81, 0x7A, 0xA9, 0x45, 0x83, 0xE2, 0x05, + 0xE6, 0xB9, 0x56, 0xC1, 0x94, 0x37, 0x8F, 0x48, 0x71, 0x63, 0x22, 0xEC, + 0x17, 0x65, 0x07, 0x95, 0x8A, 0x4B, 0xDF, 0x8F, 0xC6, 0x5A, 0x0A, 0xE5, + 0xB0, 0xE3, 0x5F, 0x5E, 0x6B, 0x11, 0xAB, 0x0C, 0xF9, 0x85, 0xEB, 0x44, + 0xE9, 0xF8, 0x04, 0x73, 0xF2, 0xE9, 0xFE, 0x5C, 0x98, 0x8C, 0xF5, 0x73, + 0xAF, 0x6B, 0xB4, 0x7E, 0xCD, 0xD4, 0x5C, 0x02, 0x2B, 0x4C, 0x39, 0xE1, + 0xB2, 0x95, 0x95, 0x2D, 0x42, 0x87, 0xD7, 0xD5, 0xB3, 0x90, 0x43, 0xB7, + 0x6C, 0x13, 0xF1, 0xDE, 0xDD, 0xF6, 0xC4, 0xF8, 0x89, 0x3F, 0xD1, 0x75, + 0xF5, 0x92, 0xC3, 0x91, 0xD5, 0x8A, 0x88, 0xD0, 0x90, 0xEC, 0xDC, 0x6D, + 0xDE, 0x89, 0xC2, 0x65, 0x71, 0x96, 0x8B, 0x0D, 0x03, 0xFD, 0x9C, 0xBF, + 0x5B, 0x16, 0xAC, 0x92, 0xDB, 0xEA, 0xFE, 0x79, 0x7C, 0xAD, 0xEB, 0xAF, + 0xF7, 0x16, 0xCB, 0xDB, 0xCD, 0x25, 0x2B, 0xE5, 0x1F, 0xFB, 0x9A, 0x9F, + 0xE2, 0x51, 0xCC, 0x3A, 0x53, 0x0C, 0x48, 0xE6, 0x0E, 0xBD, 0xC9, 0xB4, + 0x76, 0x06, 0x52, 0xE6, 0x11, 0x13, 0x85, 0x72, 0x63, 0x03, 0x04, 0xE0, + 0x04, 0x36, 0x2B, 0x20, 0x19, 0x02, 0xE8, 0x74, 0xA7, 0x1F, 0xB6, 0xC9, + 0x56, 0x66, 0xF0, 0x75, 0x25, 0xDC, 0x67, 0xC1, 0x0E, 0x61, 0x60, 0x88, + 0xB3, 0x3E, 0xD1, 0xA8, 0xFC, 0xA3, 0xDA, 0x1D, 0xB0, 0xD1, 0xB1, 0x23, + 0x54, 0xDF, 0x44, 0x76, 0x6D, 0xED, 0x41, 0xD8, 0xC1, 0xB2, 0x22, 0xB6, + 0x53, 0x1C, 0xDF, 0x35, 0x1D, 0xDC, 0xA1, 0x77, 0x2A, 0x31, 0xE4, 0x2D, + 0xF5, 0xE5, 0xE5, 0xDB, 0xC8, 0xE0, 0xFF, 0xE5, 0x80, 0xD7, 0x0B, 0x63, + 0xA0, 0xFF, 0x33, 0xA1, 0x0F, 0xBA, 0x2C, 0x15, 0x15, 0xEA, 0x97, 0xB3, + 0xD2, 0xA2, 0xB5, 0xBE, 0xF2, 0x8C, 0x96, 0x1E, 0x1A, 0x8F, 0x1D, 0x6C, + 0xA4, 0x61, 0x37, 0xB9, 0x86, 0x73, 0x33, 0xD7, 0x97, 0x96, 0x9E, 0x23, + 0x7D, 0x82, 0xA4, 0x4C, 0x81, 0xE2, 0xA1, 0xD1, 0xBA, 0x67, 0x5F, 0x95, + 0x07, 0xA3, 0x27, 0x11, 0xEE, 0x16, 0x10, 0x7B, 0xBC, 0x45, 0x4A, 0x4C, + 0xB2, 0x04, 0xD2, 0xAB, 0xEF, 0xD5, 0xFD, 0x0C, 0x51, 0xCE, 0x50, 0x6A, + 0x08, 0x31, 0xF9, 0x91, 0xDA, 0x0C, 0x8F, 0x64, 0x5C, 0x03, 0xC3, 0x3A, + 0x8B, 0x20, 0x3F, 0x6E, 0x8D, 0x67, 0x3D, 0x3A, 0xD6, 0xFE, 0x7D, 0x5B, + 0x88, 0xC9, 0x5E, 0xFB, 0xCC, 0x61, 0xDC, 0x8B, 0x33, 0x77, 0xD3, 0x44, + 0x32, 0x35, 0x09, 0x62, 0x04, 0x92, 0x16, 0x10, 0xD8, 0x9E, 0x27, 0x47, + 0xFB, 0x3B, 0x21, 0xE3, 0xF8, 0xEB, 0x1D, 0x5B +}; + +static const unsigned char TA488_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA489_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA489_RSA_N[] = { + 0xA1, 0xAE, 0x25, 0xB2, 0x01, 0x18, 0xDC, 0x57, 0x88, 0x3F, 0x46, 0xEB, + 0xF9, 0xAF, 0xE2, 0xEB, 0x23, 0x71, 0xE2, 0x9A, 0xD1, 0x61, 0x66, 0x21, + 0x5F, 0xAA, 0xAF, 0x27, 0x51, 0xE5, 0x6E, 0x1B, 0x16, 0xD4, 0x2D, 0x7D, + 0x50, 0xB0, 0x53, 0x77, 0xBD, 0x78, 0x3A, 0x60, 0xE2, 0x64, 0x02, 0x9B, + 0x7C, 0x86, 0x9B, 0xD6, 0x1A, 0x8E, 0xAD, 0xFF, 0x1F, 0x15, 0x7F, 0xD5, + 0x95, 0x1E, 0x12, 0xCB, 0xE6, 0x14, 0x84, 0x04, 0xC1, 0xDF, 0x36, 0xB3, + 0x16, 0x9F, 0x8A, 0xE3, 0xC9, 0xDB, 0x98, 0x34, 0xCE, 0xD8, 0x33, 0x17, + 0x28, 0x46, 0xFC, 0xA7, 0xC9, 0xF0, 0xD2, 0xB4, 0xD5, 0x4D, 0x09, 0x72, + 0x49, 0xF9, 0xF2, 0x87, 0xE3, 0xA9, 0xDA, 0x7D, 0xA1, 0x7D, 0x6B, 0xB2, + 0x3A, 0x25, 0xA9, 0x6D, 0x52, 0x44, 0xAC, 0xF8, 0xBE, 0x6E, 0xFB, 0xDC, + 0xA6, 0x73, 0x91, 0x90, 0x61, 0xA6, 0x03, 0x14, 0x20, 0xF2, 0xE7, 0x87, + 0xA3, 0x88, 0xAD, 0xAD, 0xA0, 0x8C, 0xFF, 0xA6, 0x0B, 0x25, 0x52, 0x25, + 0xE7, 0x16, 0x01, 0xD5, 0xCB, 0xB8, 0x35, 0x81, 0x0C, 0xA3, 0x3B, 0xF0, + 0xE1, 0xE1, 0xFC, 0x5A, 0x5D, 0xCE, 0x80, 0x71, 0x6D, 0xF8, 0x49, 0xAB, + 0x3E, 0x3B, 0xBA, 0xB8, 0xD7, 0x80, 0x01, 0xFB, 0xA5, 0xEB, 0x5B, 0xB3, + 0xC5, 0x5E, 0x60, 0x2A, 0x31, 0xA0, 0xAF, 0x37, 0xE8, 0x20, 0x3A, 0x9F, + 0xA8, 0x32, 0x2C, 0x0C, 0xCC, 0x09, 0x1D, 0xD3, 0x9E, 0x8E, 0x5D, 0xBC, + 0x4C, 0x98, 0xEE, 0xC5, 0x1A, 0x68, 0x7B, 0xEC, 0x53, 0xA6, 0xE9, 0x14, + 0x35, 0xA3, 0xDF, 0xCD, 0x80, 0x9F, 0x0C, 0x48, 0xFB, 0x1C, 0xF4, 0xF1, + 0xBF, 0x4A, 0xB8, 0xFA, 0xD5, 0x8C, 0x71, 0x4A, 0xC7, 0x1F, 0xAD, 0xFE, + 0x41, 0x9A, 0xB3, 0x83, 0x5D, 0xF2, 0x84, 0x56, 0xEF, 0xA5, 0x57, 0x43, + 0xCE, 0x29, 0xAD, 0x8C, 0xAB, 0x55, 0xBF, 0xC4, 0xFB, 0x5B, 0x01, 0xDD, + 0x23, 0x21, 0xA1, 0x58, 0x00, 0x8E, 0xC3, 0xD0, 0x6A, 0x13, 0xED, 0x13, + 0xE3, 0x12, 0x2B, 0x80, 0xDC, 0x67, 0xE6, 0x95, 0xB2, 0xCD, 0x1E, 0x22, + 0x6E, 0x2A, 0xF8, 0x41, 0xD4, 0xF2, 0xCA, 0x14, 0x07, 0x8D, 0x8A, 0x55, + 0x12, 0xC6, 0x69, 0xF5, 0xB8, 0x86, 0x68, 0x2F, 0x53, 0x5E, 0xB0, 0xD2, + 0xAA, 0x21, 0xC1, 0x98, 0xE6, 0x30, 0xE3, 0x67, 0x55, 0xC7, 0x9B, 0x6E, + 0xAC, 0x19, 0xA8, 0x55, 0xA6, 0x45, 0x06, 0xD0, 0x23, 0x3A, 0xDB, 0xEB, + 0x65, 0x5D, 0x2A, 0x11, 0x11, 0xF0, 0x3B, 0x4F, 0xCA, 0x6D, 0xF4, 0x34, + 0xC4, 0x71, 0xE4, 0xFF, 0x00, 0x5A, 0xF6, 0x5C, 0xAE, 0x23, 0x60, 0x85, + 0x73, 0xF1, 0xE4, 0x10, 0xB1, 0x25, 0xAE, 0xD5, 0x92, 0xBB, 0x13, 0xC1, + 0x0C, 0xE0, 0x39, 0xDA, 0xB4, 0x39, 0x57, 0xB5, 0xAB, 0x35, 0xAA, 0x72, + 0x21, 0x3B, 0x83, 0x35, 0xE7, 0x31, 0xDF, 0x7A, 0x21, 0x6E, 0xB8, 0x32, + 0x08, 0x7D, 0x1D, 0x32, 0x91, 0x15, 0x4A, 0x62, 0x72, 0xCF, 0xE3, 0x77, + 0xA1, 0xBC, 0xD5, 0x11, 0x1B, 0x76, 0x01, 0x67, 0x08, 0xE0, 0x41, 0x0B, + 0xC3, 0xEB, 0x15, 0x6E, 0xF8, 0xA4, 0x19, 0xD9, 0xA2, 0xAB, 0xAF, 0xE2, + 0x27, 0x52, 0x56, 0x2B, 0x02, 0x8A, 0x2C, 0x14, 0x24, 0xF9, 0xBF, 0x42, + 0x02, 0xBF, 0x26, 0xC8, 0xC6, 0x8F, 0xE0, 0x6E, 0x38, 0x7D, 0x53, 0x2D, + 0xE5, 0xED, 0x98, 0xB3, 0x95, 0x63, 0x68, 0x7F, 0xF9, 0x35, 0xF4, 0xDF, + 0x88, 0xC5, 0x60, 0x35, 0x92, 0xC0, 0x7C, 0x69, 0x1C, 0x61, 0x95, 0x16, + 0xD0, 0xEB, 0xDE, 0x0B, 0xAF, 0x3E, 0x04, 0x10, 0x45, 0x65, 0x58, 0x50, + 0x38, 0xAF, 0x48, 0xF2, 0x59, 0xB6, 0x16, 0xF2, 0x3C, 0x0D, 0x90, 0x02, + 0xC6, 0x70, 0x2E, 0x01, 0xAD, 0x3C, 0x15, 0xD7 +}; + +static const unsigned char TA489_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA490_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA490_RSA_N[] = { + 0xCC, 0x57, 0x42, 0x16, 0x54, 0x9C, 0xE6, 0x98, 0xD3, 0xD3, 0x4D, 0xEE, + 0xFE, 0xED, 0xC7, 0x9F, 0x43, 0x39, 0x4A, 0x65, 0xB3, 0xE8, 0x16, 0x88, + 0x34, 0xDB, 0x0D, 0x59, 0x91, 0x74, 0xCF, 0x92, 0xB8, 0x04, 0x40, 0xAD, + 0x02, 0x4B, 0x31, 0xAB, 0xBC, 0x8D, 0x91, 0x68, 0xD8, 0x20, 0x0E, 0x1A, + 0x01, 0xE2, 0x1A, 0x7B, 0x4E, 0x17, 0x5D, 0xE2, 0x8A, 0xB7, 0x3F, 0x99, + 0x1A, 0xCD, 0xEB, 0x61, 0xAB, 0xC2, 0x65, 0xA6, 0x1F, 0xB7, 0xB7, 0xBD, + 0xB7, 0x8F, 0xFC, 0xFD, 0x70, 0x8F, 0x0B, 0xA0, 0x67, 0xBE, 0x01, 0xA2, + 0x59, 0xCF, 0x71, 0xE6, 0x0F, 0x29, 0x76, 0xFF, 0xB1, 0x56, 0x79, 0x45, + 0x2B, 0x1F, 0x9E, 0x7A, 0x54, 0xE8, 0xA3, 0x29, 0x35, 0x68, 0xA4, 0x01, + 0x4F, 0x0F, 0xA4, 0x2E, 0x37, 0xEF, 0x1B, 0xBF, 0xE3, 0x8F, 0x10, 0xA8, + 0x72, 0xAB, 0x58, 0x57, 0xE7, 0x54, 0x86, 0xC8, 0xC9, 0xF3, 0x5B, 0xDA, + 0x2C, 0xDA, 0x5D, 0x8E, 0x6E, 0x3C, 0xA3, 0x3E, 0xDA, 0xFB, 0x82, 0xE5, + 0xDD, 0xF2, 0x5C, 0xB2, 0x05, 0x33, 0x6F, 0x8A, 0x36, 0xCE, 0xD0, 0x13, + 0x4E, 0xFF, 0xBF, 0x4A, 0x0C, 0x34, 0x4C, 0xA6, 0xC3, 0x21, 0xBD, 0x50, + 0x04, 0x55, 0xEB, 0xB1, 0xBB, 0x9D, 0xFB, 0x45, 0x1E, 0x64, 0x15, 0xDE, + 0x55, 0x01, 0x8C, 0x02, 0x76, 0xB5, 0xCB, 0xA1, 0x3F, 0x42, 0x69, 0xBC, + 0x2F, 0xBD, 0x68, 0x43, 0x16, 0x56, 0x89, 0x2A, 0x37, 0x61, 0x91, 0xFD, + 0xA6, 0xAE, 0x4E, 0xC0, 0xCB, 0x14, 0x65, 0x94, 0x37, 0x4B, 0x92, 0x06, + 0xEF, 0x04, 0xD0, 0xC8, 0x9C, 0x88, 0xDB, 0x0B, 0x7B, 0x81, 0xAF, 0xB1, + 0x3D, 0x2A, 0xC4, 0x65, 0x3A, 0x78, 0xB6, 0xEE, 0xDC, 0x80, 0xB1, 0xD2, + 0xD3, 0x99, 0x9C, 0x3A, 0xEE, 0x6B, 0x5A, 0x6B, 0xB3, 0x8D, 0xB7, 0xD5, + 0xCE, 0x9C, 0xC2, 0xBE, 0xA5, 0x4B, 0x2F, 0x16, 0xB1, 0x9E, 0x68, 0x3B, + 0x06, 0x6F, 0xAE, 0x7D, 0x9F, 0xF8, 0xDE, 0xEC, 0xCC, 0x29, 0xA7, 0x98, + 0xA3, 0x25, 0x43, 0x2F, 0xEF, 0xF1, 0x5F, 0x26, 0xE1, 0x88, 0x4D, 0xF8, + 0x5E, 0x6E, 0xD7, 0xD9, 0x14, 0x6E, 0x19, 0x33, 0x69, 0xA7, 0x3B, 0x84, + 0x89, 0x93, 0xC4, 0x53, 0x55, 0x13, 0xA1, 0x51, 0x78, 0x40, 0xF8, 0xB8, + 0xC9, 0xA2, 0xEE, 0x7B, 0xBA, 0x52, 0x42, 0x83, 0x9E, 0x14, 0xED, 0x05, + 0x52, 0x5A, 0x59, 0x56, 0xA7, 0x97, 0xFC, 0x9D, 0x3F, 0x0A, 0x29, 0xD8, + 0xDC, 0x4F, 0x91, 0x0E, 0x13, 0xBC, 0xDE, 0x95, 0xA4, 0xDF, 0x8B, 0x99, + 0xBE, 0xAC, 0x9B, 0x33, 0x88, 0xEF, 0xB5, 0x81, 0xAF, 0x1B, 0xC6, 0x22, + 0x53, 0xC8, 0xF6, 0xC7, 0xEE, 0x97, 0x14, 0xB0, 0xC5, 0x7C, 0x78, 0x52, + 0xC8, 0xF0, 0xCE, 0x6E, 0x77, 0x60, 0x84, 0xA6, 0xE9, 0x2A, 0x76, 0x20, + 0xED, 0x58, 0x01, 0x17, 0x30, 0x93, 0xE9, 0x1A, 0x8B, 0xE0, 0x73, 0x63, + 0xD9, 0x6A, 0x92, 0x94, 0x49, 0x4E, 0xB4, 0xAD, 0x4A, 0x85, 0xC4, 0xA3, + 0x22, 0x30, 0xFC, 0x09, 0xED, 0x68, 0x22, 0x73, 0xA6, 0x88, 0x0C, 0x55, + 0x21, 0x58, 0xC5, 0xE1, 0x3A, 0x9F, 0x2A, 0xDD, 0xCA, 0xE1, 0x90, 0xE0, + 0xD9, 0x73, 0xAB, 0x6C, 0x80, 0xB8, 0xE8, 0x0B, 0x64, 0x93, 0xA0, 0x9C, + 0x8C, 0x19, 0xFF, 0xB3, 0xD2, 0x0C, 0xEC, 0x91, 0x26, 0x87, 0x8A, 0xB3, + 0xA2, 0xE1, 0x70, 0x8F, 0x2C, 0x0A, 0xE5, 0xCD, 0x6D, 0x68, 0x51, 0xEB, + 0xDA, 0x3F, 0x05, 0x7F, 0x8B, 0x32, 0xE6, 0x13, 0x5C, 0x6B, 0xFE, 0x5F, + 0x40, 0xE2, 0x22, 0xC8, 0xB4, 0xB4, 0x64, 0x4F, 0xD6, 0xBA, 0x7D, 0x48, + 0x3E, 0xA8, 0x69, 0x0C, 0xD7, 0xBB, 0x86, 0x71, 0xC9, 0x73, 0xB8, 0x3F, + 0x3B, 0x9D, 0x25, 0x4B, 0xDA, 0xFF, 0x40, 0xEB +}; + +static const unsigned char TA490_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA491_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA491_RSA_N[] = { + 0xB3, 0xCB, 0x0E, 0x10, 0x67, 0x8E, 0xEA, 0x14, 0x97, 0xA7, 0x32, 0x2A, + 0x0A, 0x56, 0x36, 0x7F, 0x68, 0x4C, 0xC7, 0xB3, 0x6F, 0x3A, 0x23, 0x14, + 0x91, 0xFF, 0x19, 0x7F, 0xA5, 0xCA, 0xAC, 0xEE, 0xB3, 0x76, 0x9D, 0x7A, + 0xE9, 0x8B, 0x1B, 0xAB, 0x6B, 0x31, 0xDB, 0xFA, 0x0B, 0x53, 0x4C, 0xAF, + 0xC5, 0xA5, 0x1A, 0x79, 0x3C, 0x8A, 0x4C, 0xFF, 0xAC, 0xDF, 0x25, 0xDE, + 0x4E, 0xD9, 0x82, 0x32, 0x0B, 0x44, 0xDE, 0xCA, 0xDB, 0x8C, 0xAC, 0xA3, + 0x6E, 0x16, 0x83, 0x3B, 0xA6, 0x64, 0x4B, 0x32, 0x89, 0xFB, 0x16, 0x16, + 0x38, 0x7E, 0xEB, 0x43, 0xE2, 0xD3, 0x74, 0x4A, 0xC2, 0x62, 0x0A, 0x73, + 0x0A, 0xDD, 0x49, 0xB3, 0x57, 0xD2, 0xB0, 0x0A, 0x85, 0x9D, 0x71, 0x3C, + 0xDE, 0xA3, 0xCB, 0xC0, 0x32, 0xF3, 0x01, 0x39, 0x20, 0x43, 0x1B, 0x35, + 0xD1, 0x53, 0xB3, 0xB1, 0xEE, 0xC5, 0x93, 0x69, 0x82, 0x3E, 0x16, 0xB5, + 0x28, 0x46, 0xA1, 0xDE, 0xEA, 0x89, 0x09, 0xED, 0x43, 0xB8, 0x05, 0x46, + 0x8A, 0x86, 0xF5, 0x59, 0x47, 0xBE, 0x1B, 0x6F, 0x01, 0x21, 0x10, 0xB9, + 0xFD, 0xA9, 0xD2, 0x28, 0xCA, 0x10, 0x39, 0x09, 0xCA, 0x13, 0x36, 0xCF, + 0x9C, 0xAD, 0xAD, 0x40, 0x74, 0x79, 0x2B, 0x02, 0x3F, 0x34, 0xFF, 0xFA, + 0x20, 0x69, 0x7D, 0xD3, 0xEE, 0x61, 0xF5, 0xBA, 0xB3, 0xE7, 0x30, 0xD0, + 0x37, 0x23, 0x86, 0x72, 0x61, 0x45, 0x29, 0x48, 0x59, 0x68, 0x6F, 0x77, + 0xA6, 0x2E, 0x81, 0xBE, 0x07, 0x4D, 0x6F, 0xAF, 0xCE, 0xC4, 0x45, 0x13, + 0x91, 0x14, 0x70, 0x06, 0x8F, 0x1F, 0x9F, 0xF8, 0x87, 0x69, 0xB1, 0x0E, + 0xEF, 0xC3, 0x89, 0x19, 0xEB, 0xEA, 0x1C, 0x61, 0xFC, 0x7A, 0x6C, 0x8A, + 0xDC, 0xD6, 0x03, 0x0B, 0x9E, 0x26, 0xBA, 0x12, 0xDD, 0xD4, 0x54, 0x39, + 0xAB, 0x26, 0xA3, 0x33, 0xEA, 0x75, 0x81, 0xDA, 0x2D, 0xCD, 0x0F, 0x4F, + 0xE4, 0x03, 0xD1, 0xEF, 0x15, 0x97, 0x1B, 0x6B, 0x90, 0xC5, 0x02, 0x90, + 0x93, 0x66, 0x02, 0x21, 0xB1, 0x47, 0xDE, 0x8B, 0x9A, 0x4A, 0x80, 0xB9, + 0x55, 0x8F, 0xB5, 0xA2, 0x2F, 0xC0, 0xD6, 0x33, 0x67, 0xDA, 0x7E, 0xC4, + 0xA7, 0xB4, 0x04, 0x44, 0xEB, 0x47, 0xFB, 0xE6, 0x58, 0xB9, 0xF7, 0x0C, + 0xF0, 0x7B, 0x2B, 0xB1, 0xC0, 0x70, 0x29, 0xC3, 0x40, 0x62, 0x2D, 0x3B, + 0x48, 0x69, 0xDC, 0x23, 0x3C, 0x48, 0xEB, 0x7B, 0x09, 0x79, 0xA9, 0x6D, + 0xDA, 0xA8, 0x30, 0x98, 0xCF, 0x80, 0x72, 0x03, 0x88, 0xA6, 0x5B, 0x46, + 0xAE, 0x72, 0x79, 0x7C, 0x08, 0x03, 0x21, 0x65, 0xAE, 0xB7, 0xE1, 0x1C, + 0xA5, 0xB1, 0x2A, 0xA2, 0x31, 0xDE, 0x66, 0x04, 0xF7, 0xC0, 0x74, 0xE8, + 0x71, 0xDE, 0xFF, 0x3D, 0x59, 0xCC, 0x96, 0x26, 0x12, 0x8B, 0x85, 0x95, + 0x57, 0x1A, 0xAB, 0x6B, 0x75, 0x0B, 0x44, 0x3D, 0x11, 0x28, 0x3C, 0x7B, + 0x61, 0xB7, 0xE2, 0x8F, 0x67, 0x4F, 0xE5, 0xEC, 0x3C, 0x4C, 0x60, 0x80, + 0x69, 0x57, 0x38, 0x1E, 0x01, 0x5B, 0x8D, 0x55, 0xE8, 0xC7, 0xDF, 0xC0, + 0xCC, 0x77, 0x23, 0x34, 0x49, 0x75, 0x7C, 0xF6, 0x98, 0x11, 0xEB, 0x2D, + 0xDE, 0xED, 0x41, 0x2E, 0x14, 0x05, 0x02, 0x7F, 0xE0, 0xFE, 0x20, 0xEB, + 0x35, 0xE7, 0x11, 0xAC, 0x22, 0xCE, 0x57, 0x3D, 0xDE, 0xC9, 0x30, 0x6D, + 0x10, 0x03, 0x85, 0xCD, 0xF1, 0xFF, 0x8C, 0x16, 0xB5, 0xC1, 0xB2, 0x3E, + 0x88, 0x6C, 0x60, 0x7F, 0x90, 0x4F, 0x95, 0xF7, 0xF6, 0x2D, 0xAD, 0x01, + 0x39, 0x07, 0x04, 0xFA, 0x75, 0x80, 0x7D, 0xBF, 0x49, 0x50, 0xED, 0xEF, + 0xC9, 0xC4, 0x7C, 0x1C, 0xEB, 0x80, 0x7E, 0xDB, 0xB6, 0xD0, 0xDD, 0x13, + 0xFE, 0xC9, 0xD3, 0x9C, 0xD7, 0xB2, 0x97, 0xA9 +}; + +static const unsigned char TA491_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA492_DN[] = { + 0x30, 0x7F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x2B, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, 0x56, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA492_EC_Q[] = { + 0x04, 0xAA, 0x12, 0x47, 0x90, 0x98, 0x1B, 0xFB, 0xEF, 0xC3, 0x40, 0x07, + 0x83, 0x20, 0x4E, 0xF1, 0x30, 0x82, 0xA2, 0x06, 0xD1, 0xF2, 0x92, 0x86, + 0x61, 0xF2, 0xF6, 0x21, 0x68, 0xCA, 0x00, 0xC4, 0xC7, 0xEA, 0x43, 0x00, + 0x54, 0x86, 0xDC, 0xFD, 0x1F, 0xDF, 0x00, 0xB8, 0x41, 0x62, 0x5C, 0xDC, + 0x70, 0x16, 0x32, 0xDE, 0x1F, 0x99, 0xD4, 0xCC, 0xC5, 0x07, 0xC8, 0x08, + 0x1F, 0x61, 0x16, 0x07, 0x51, 0x3D, 0x7D, 0x5C, 0x07, 0x53, 0xE3, 0x35, + 0x38, 0x8C, 0xDF, 0xCD, 0x9F, 0xD9, 0x2E, 0x0D, 0x4A, 0xB6, 0x19, 0x2E, + 0x5A, 0x70, 0x5A, 0x06, 0xED, 0xBE, 0xF0, 0xA1, 0xB0, 0xCA, 0xD0, 0x09, + 0x29 +}; + +static const unsigned char TA493_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, + 0x6F, 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x2E, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, + 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA493_RSA_N[] = { + 0x8F, 0x36, 0x65, 0x40, 0xE1, 0xD6, 0x4D, 0xC0, 0xD7, 0xB4, 0xE9, 0x46, + 0xDA, 0x6B, 0xEA, 0x33, 0x47, 0xCD, 0x4C, 0xF9, 0x7D, 0x7D, 0xBE, 0xBD, + 0x2D, 0x3D, 0xF0, 0xDB, 0x78, 0xE1, 0x86, 0xA5, 0xD9, 0xBA, 0x09, 0x57, + 0x68, 0xED, 0x57, 0x3E, 0xA0, 0xD0, 0x08, 0x41, 0x83, 0xE7, 0x28, 0x41, + 0x24, 0x1F, 0xE3, 0x72, 0x15, 0xD0, 0x01, 0x1A, 0xFB, 0x5E, 0x70, 0x23, + 0xB2, 0xCB, 0x9F, 0x39, 0xE3, 0xCF, 0xC5, 0x4E, 0xC6, 0x92, 0x6D, 0x26, + 0xC6, 0x7B, 0xBB, 0xB3, 0xDA, 0x27, 0x9D, 0x0A, 0x86, 0xE9, 0x81, 0x37, + 0x05, 0xFE, 0xF0, 0x71, 0x71, 0xEC, 0xC3, 0x1C, 0xE9, 0x63, 0xA2, 0x17, + 0x14, 0x9D, 0xEF, 0x1B, 0x67, 0xD3, 0x85, 0x55, 0x02, 0x02, 0xD6, 0x49, + 0xC9, 0xCC, 0x5A, 0xE1, 0xB1, 0xF7, 0x6F, 0x32, 0x9F, 0xC9, 0xD4, 0x3B, + 0x88, 0x41, 0xA8, 0x9C, 0xBD, 0xCB, 0xAB, 0xDB, 0x6D, 0x7B, 0x09, 0x1F, + 0xA2, 0x4C, 0x72, 0x90, 0xDA, 0x2B, 0x08, 0xFC, 0xCF, 0x3C, 0x54, 0xCE, + 0x67, 0x0F, 0xA8, 0xCF, 0x5D, 0x96, 0x19, 0x0B, 0xC4, 0xE3, 0x72, 0xEB, + 0xAD, 0xD1, 0x7D, 0x1D, 0x27, 0xEF, 0x92, 0xEB, 0x10, 0xBF, 0x5B, 0xEB, + 0x3B, 0xAF, 0xCF, 0x80, 0xDD, 0xC1, 0xD2, 0x96, 0x04, 0x5B, 0x7A, 0x7E, + 0xA4, 0xA9, 0x3C, 0x38, 0x76, 0xA4, 0x62, 0x8E, 0xA0, 0x39, 0x5E, 0xEA, + 0x77, 0xCF, 0x5D, 0x00, 0x59, 0x8F, 0x66, 0x2C, 0x3E, 0x07, 0xA2, 0xA3, + 0x05, 0x26, 0x11, 0x69, 0x97, 0xEA, 0x85, 0xB7, 0x0F, 0x96, 0x0B, 0x4B, + 0xC8, 0x40, 0xE1, 0x50, 0xBA, 0x2E, 0x8A, 0xCB, 0xF7, 0x0F, 0x9A, 0x22, + 0xE7, 0x7F, 0x9A, 0x37, 0x13, 0xCD, 0xF2, 0x4D, 0x13, 0x6B, 0x21, 0xD1, + 0xC0, 0xCC, 0x22, 0xF2, 0xA1, 0x46, 0xF6, 0x44, 0x69, 0x9C, 0xCA, 0x61, + 0x35, 0x07, 0x00, 0x6F, 0xD6, 0x61, 0x08, 0x11, 0xEA, 0xBA, 0xB8, 0xF6, + 0xE9, 0xB3, 0x60, 0xE5, 0x4D, 0xB9, 0xEC, 0x9F, 0x14, 0x66, 0xC9, 0x57, + 0x58, 0xDB, 0xCD, 0x87, 0x69, 0xF8, 0x8A, 0x86, 0x12, 0x03, 0x47, 0xBF, + 0x66, 0x13, 0x76, 0xAC, 0x77, 0x7D, 0x34, 0x24, 0x85, 0x83, 0xCD, 0xD7, + 0xAA, 0x9C, 0x90, 0x1A, 0x9F, 0x21, 0x2C, 0x7F, 0x78, 0xB7, 0x64, 0xB8, + 0xD8, 0xE8, 0xA6, 0xF4, 0x78, 0xB3, 0x55, 0xCB, 0x84, 0xD2, 0x32, 0xC4, + 0x78, 0xAE, 0xA3, 0x8F, 0x61, 0xDD, 0xCE, 0x08, 0x53, 0xAD, 0xEC, 0x88, + 0xFC, 0x15, 0xE4, 0x9A, 0x0D, 0xE6, 0x9F, 0x1A, 0x77, 0xCE, 0x4C, 0x8F, + 0xB8, 0x14, 0x15, 0x3D, 0x62, 0x9C, 0x86, 0x38, 0x06, 0x00, 0x66, 0x12, + 0xE4, 0x59, 0x76, 0x5A, 0x53, 0xC0, 0x02, 0x98, 0xA2, 0x10, 0x2B, 0x68, + 0x44, 0x7B, 0x8E, 0x79, 0xCE, 0x33, 0x4A, 0x76, 0xAA, 0x5B, 0x81, 0x16, + 0x1B, 0xB5, 0x8A, 0xD8, 0xD0, 0x00, 0x7B, 0x5E, 0x62, 0xB4, 0x09, 0xD6, + 0x86, 0x63, 0x0E, 0xA6, 0x05, 0x95, 0x49, 0xBA, 0x28, 0x8B, 0x88, 0x93, + 0xB2, 0x34, 0x1C, 0xD8, 0xA4, 0x55, 0x6E, 0xB7, 0x1C, 0xD0, 0xDE, 0x99, + 0x55, 0x3B, 0x23, 0xF4, 0x22, 0xE0, 0xF9, 0x29, 0x66, 0x26, 0xEC, 0x20, + 0x50, 0x77, 0xDB, 0x4A, 0x0B, 0x8F, 0xBE, 0xE5, 0x02, 0x60, 0x70, 0x41, + 0x5E, 0xD4, 0xAE, 0x50, 0x39, 0x22, 0x14, 0x26, 0xCB, 0xB2, 0x3B, 0x73, + 0x74, 0x55, 0x47, 0x07, 0x79, 0x81, 0x39, 0xA8, 0x30, 0x13, 0x44, 0xE5, + 0x04, 0x8A, 0xAE, 0x96, 0x13, 0x25, 0x42, 0x0F, 0xB9, 0x53, 0xC4, 0x9B, + 0xFC, 0xCD, 0xE4, 0x1C, 0xDE, 0x3C, 0xFA, 0xAB, 0xD6, 0x06, 0x4A, 0x1F, + 0x67, 0xA6, 0x98, 0x30, 0x1C, 0xDD, 0x2C, 0xDB, 0xDC, 0x18, 0x95, 0x57, + 0x66, 0xC6, 0xFF, 0x5C, 0x8B, 0x56, 0xF5, 0x77 +}; + +static const unsigned char TA493_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA494_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA494_EC_Q[] = { + 0x04, 0x45, 0x6E, 0xA9, 0x50, 0xC4, 0xA6, 0x23, 0x36, 0x9E, 0x5F, 0x28, + 0x8D, 0x17, 0xCB, 0x96, 0x22, 0x64, 0x3F, 0xDC, 0x7A, 0x8E, 0x1D, 0xCC, + 0x08, 0xB3, 0xA2, 0x71, 0x24, 0xBA, 0x8E, 0x49, 0xB9, 0x04, 0x1B, 0x47, + 0x96, 0x58, 0xAB, 0x2D, 0x95, 0xC8, 0xED, 0x9E, 0x08, 0x35, 0xC8, 0x27, + 0xEB, 0x89, 0x8C, 0x53, 0x58, 0xEB, 0x62, 0x8A, 0xFE, 0xF0, 0x5B, 0x0F, + 0x6B, 0x31, 0x52, 0x63, 0x41, 0x3B, 0x89, 0xCD, 0xEC, 0xEC, 0xB6, 0x8D, + 0x19, 0xD3, 0x34, 0x07, 0xDC, 0xBB, 0xC6, 0x06, 0x7F, 0xC2, 0x45, 0x95, + 0xEC, 0xCB, 0x7F, 0xA8, 0x23, 0xE0, 0x09, 0xE9, 0x81, 0xFA, 0xF3, 0x47, + 0xD3 +}; + +static const unsigned char TA495_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x52, 0x53, 0x41 +}; + +static const unsigned char TA495_RSA_N[] = { + 0xF9, 0x0F, 0xDD, 0xA3, 0x2B, 0x7D, 0xCB, 0xD0, 0x2A, 0xFE, 0xEC, 0x67, + 0x85, 0xA6, 0xE7, 0x2E, 0x1B, 0xBA, 0x77, 0xE1, 0xE3, 0xF5, 0xAF, 0xA4, + 0xEC, 0xFA, 0x4A, 0x5D, 0x91, 0xC4, 0x57, 0x47, 0x6B, 0x18, 0x77, 0x6B, + 0x76, 0xF2, 0xFD, 0x93, 0xE4, 0x3D, 0x0F, 0xC2, 0x16, 0x9E, 0x0B, 0x66, + 0xC3, 0x56, 0x94, 0x9E, 0x17, 0x83, 0x85, 0xCE, 0x56, 0xEF, 0xF2, 0x16, + 0xFD, 0x00, 0x62, 0xF5, 0x22, 0x09, 0x54, 0xE8, 0x65, 0x17, 0x4E, 0x41, + 0xB9, 0xE0, 0x4F, 0x46, 0x97, 0xAA, 0x1B, 0xC8, 0xB8, 0x6E, 0x62, 0x5E, + 0x69, 0xB1, 0x5F, 0xDB, 0x2A, 0x02, 0x7E, 0xFC, 0x6C, 0xCA, 0xF3, 0x41, + 0xD8, 0xED, 0xD0, 0xE8, 0xFC, 0x3F, 0x61, 0x48, 0xED, 0xB0, 0x03, 0x14, + 0x1D, 0x10, 0x0E, 0x4B, 0x19, 0xE0, 0xBB, 0x4E, 0xEC, 0x86, 0x65, 0xFF, + 0x36, 0xF3, 0x5E, 0x67, 0x02, 0x0B, 0x9D, 0x86, 0x55, 0x61, 0xFD, 0x7A, + 0x38, 0xED, 0xFE, 0xE2, 0x19, 0x00, 0xB7, 0x6F, 0xA1, 0x50, 0x62, 0x75, + 0x74, 0x3C, 0xA0, 0xFA, 0xC8, 0x25, 0x92, 0xB4, 0x6E, 0x7A, 0x22, 0xC7, + 0xF8, 0x1E, 0xA1, 0xE3, 0xB2, 0xDD, 0x91, 0x31, 0xAB, 0x2B, 0x1D, 0x04, + 0xFF, 0xA5, 0x4A, 0x04, 0x37, 0xE9, 0x85, 0xA4, 0x33, 0x2B, 0xFD, 0xE2, + 0xD6, 0x55, 0x34, 0x7C, 0x19, 0xA4, 0x4A, 0x68, 0xC7, 0xB2, 0xA8, 0xD3, + 0xB7, 0xCA, 0xA1, 0x93, 0x88, 0xEB, 0xC1, 0x97, 0xBC, 0x8C, 0xF9, 0x1D, + 0xD9, 0x22, 0x84, 0x24, 0x74, 0xC7, 0x04, 0x3D, 0x6A, 0xA9, 0x29, 0x93, + 0xCC, 0xEB, 0xB8, 0x5B, 0xE1, 0xFE, 0x5F, 0x25, 0xAA, 0x34, 0x58, 0xC8, + 0xC1, 0x23, 0x54, 0x9D, 0x1B, 0x98, 0x11, 0xC3, 0x38, 0x9C, 0x7E, 0x3D, + 0x86, 0x6C, 0xA5, 0x0F, 0x40, 0x86, 0x7C, 0x02, 0xF4, 0x5C, 0x02, 0x4F, + 0x28, 0xCB, 0xAE, 0x71, 0x9F, 0x0F, 0x3A, 0xC8, 0x33, 0xFE, 0x11, 0x25, + 0x35, 0xEA, 0xFC, 0xBA, 0xC5, 0x60, 0x3D, 0xD9, 0x7C, 0x18, 0xD5, 0xB2, + 0xA9, 0xD3, 0x75, 0x78, 0x03, 0x72, 0x22, 0xCA, 0x3A, 0xC3, 0x1F, 0xEF, + 0x2C, 0xE5, 0x2E, 0xA9, 0xFA, 0x9E, 0x2C, 0xB6, 0x51, 0x46, 0xFD, 0xAF, + 0x03, 0xD6, 0xEA, 0x60, 0x68, 0xEA, 0x85, 0x16, 0x36, 0x6B, 0x85, 0xE9, + 0x1E, 0xC0, 0xB3, 0xDD, 0xC4, 0x24, 0xDC, 0x80, 0x2A, 0x81, 0x41, 0x6D, + 0x94, 0x3E, 0xC8, 0xE0, 0xC9, 0x81, 0x41, 0x00, 0x9E, 0x5E, 0xBF, 0x7F, + 0xC5, 0x08, 0x98, 0xA2, 0x18, 0x2C, 0x42, 0x40, 0xB3, 0xF9, 0x6F, 0x38, + 0x27, 0x4B, 0x4E, 0x80, 0xF4, 0x3D, 0x81, 0x47, 0xE0, 0x88, 0x7C, 0xEA, + 0x1C, 0xCE, 0xB5, 0x75, 0x5C, 0x51, 0x2E, 0x1C, 0x2B, 0x7F, 0x1A, 0x72, + 0x28, 0xE7, 0x00, 0xB5, 0xD1, 0x74, 0xC6, 0xD7, 0xE4, 0x9F, 0xAD, 0x07, + 0x93, 0xB6, 0x53, 0x35, 0x35, 0xFC, 0x37, 0xE4, 0xC3, 0xF6, 0x5D, 0x16, + 0xBE, 0x21, 0x73, 0xDE, 0x92, 0x0A, 0xF8, 0xA0, 0x63, 0x6A, 0xBC, 0x96, + 0x92, 0x6A, 0x3E, 0xF8, 0xBC, 0x65, 0x55, 0x9B, 0xDE, 0xF5, 0x0D, 0x89, + 0x26, 0x04, 0xFC, 0x25, 0x1A, 0xA6, 0x25, 0x69, 0xCB, 0xC2, 0x6D, 0xCA, + 0x7C, 0xE2, 0x59, 0x5F, 0x97, 0xAC, 0xEB, 0xEF, 0x2E, 0xC8, 0xBC, 0xD7, + 0x1B, 0x59, 0x3C, 0x2B, 0xCC, 0xF2, 0x19, 0xC8, 0x93, 0x6B, 0x27, 0x63, + 0x19, 0xCF, 0xFC, 0xE9, 0x26, 0xF8, 0xCA, 0x71, 0x9B, 0x7F, 0x93, 0xFE, + 0x34, 0x67, 0x84, 0x4E, 0x99, 0xEB, 0xFC, 0xB3, 0x78, 0x09, 0x33, 0x70, + 0xBA, 0x66, 0xA6, 0x76, 0xED, 0x1B, 0x73, 0xEB, 0x1A, 0xA5, 0x0D, 0xC4, + 0x22, 0x13, 0x20, 0x94, 0x56, 0x0A, 0x4E, 0x2C, 0x6C, 0x4E, 0xB1, 0xFD, + 0xCF, 0x9C, 0x09, 0xBA, 0xA2, 0x33, 0xED, 0x87 +}; + +static const unsigned char TA495_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA496_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA496_EC_Q[] = { + 0x04, 0x45, 0x29, 0x35, 0x73, 0xFA, 0xC2, 0xB8, 0x23, 0xCE, 0x14, 0x7D, + 0xA8, 0xB1, 0x4D, 0xA0, 0x5B, 0x36, 0xEE, 0x2A, 0x2C, 0x53, 0xC3, 0x60, + 0x09, 0x35, 0xB2, 0x24, 0x66, 0x26, 0x69, 0xC0, 0xB3, 0x95, 0xD6, 0x5D, + 0x92, 0x40, 0x19, 0x0E, 0xC6, 0xA5, 0x13, 0x70, 0xF4, 0xEF, 0x12, 0x51, + 0x28, 0x5D, 0xE7, 0xCC, 0xBD, 0xF9, 0x3C, 0x85, 0xC1, 0xCF, 0x94, 0x90, + 0xC9, 0x2B, 0xCE, 0x92, 0x42, 0x58, 0x59, 0x67, 0xFD, 0x94, 0x27, 0x10, + 0x64, 0x8C, 0x4F, 0x04, 0xB1, 0x4D, 0x49, 0xE4, 0x7B, 0x4F, 0x9B, 0xF5, + 0xE7, 0x08, 0xF8, 0x03, 0x88, 0xF7, 0xA7, 0xC3, 0x92, 0x4B, 0x19, 0x54, + 0x81 +}; + +static const unsigned char TA497_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA497_RSA_N[] = { + 0xD0, 0xA4, 0x09, 0x72, 0x4F, 0x40, 0x88, 0x12, 0x61, 0x3E, 0x35, 0x23, + 0x9E, 0xEE, 0xF6, 0x74, 0xCF, 0x2F, 0x7B, 0x58, 0x3D, 0xCE, 0x3C, 0x0D, + 0x10, 0x28, 0x90, 0x2F, 0x97, 0xF7, 0x8C, 0x48, 0xD8, 0xA0, 0xD8, 0x25, + 0xB1, 0x4C, 0xB0, 0x11, 0x4C, 0x17, 0x73, 0x50, 0xD0, 0x22, 0x4A, 0x63, + 0xBB, 0x81, 0xD3, 0x29, 0x6E, 0xD5, 0xB5, 0x09, 0x3E, 0x26, 0x18, 0x7F, + 0xB2, 0x12, 0x7F, 0x93, 0x98, 0xB7, 0xAF, 0xF0, 0x36, 0xBF, 0xF2, 0xEE, + 0x18, 0x9E, 0x9C, 0x3B, 0x52, 0xC5, 0x47, 0x19, 0x5D, 0x74, 0xF3, 0x64, + 0x66, 0xD5, 0x5D, 0xC7, 0x68, 0xB4, 0xBF, 0x1B, 0x1C, 0x06, 0xA3, 0xBC, + 0x8F, 0x40, 0x23, 0xB6, 0x1E, 0xC6, 0x84, 0xBD, 0x51, 0xC4, 0x1B, 0x39, + 0xC1, 0x95, 0xD2, 0x29, 0xEC, 0x4B, 0xAE, 0x7B, 0x2D, 0xBF, 0x39, 0xFD, + 0xB4, 0x62, 0xDE, 0x96, 0x7B, 0x41, 0xC6, 0x9C, 0xA0, 0xE0, 0x06, 0x72, + 0xFB, 0xF0, 0x07, 0x97, 0x09, 0x39, 0x81, 0x74, 0xAF, 0xF7, 0x34, 0x59, + 0x11, 0x57, 0x0A, 0xC2, 0x5B, 0xC1, 0x24, 0xF4, 0x31, 0x73, 0x30, 0x82, + 0xC6, 0x9D, 0xBA, 0x02, 0xF7, 0x3E, 0x7C, 0x44, 0x5F, 0x83, 0x0D, 0xF3, + 0xF1, 0xDD, 0x20, 0x69, 0x16, 0x09, 0x50, 0xE2, 0xD4, 0x55, 0xB6, 0xE0, + 0x80, 0x72, 0x76, 0x6E, 0x4C, 0x47, 0xB7, 0x75, 0x55, 0x59, 0xB4, 0x53, + 0x74, 0xD9, 0x94, 0xC6, 0x41, 0xAD, 0x58, 0x8A, 0x31, 0x66, 0x0F, 0x1E, + 0xA2, 0x1B, 0x29, 0x40, 0x4E, 0x2F, 0xDF, 0x7B, 0xE6, 0x16, 0x2C, 0x2D, + 0xFC, 0xBF, 0xEC, 0xF3, 0xB4, 0xFA, 0xBE, 0x18, 0xF6, 0x9B, 0x49, 0xD4, + 0xEE, 0x05, 0x6E, 0xD9, 0x34, 0xF3, 0x9C, 0xF1, 0xEC, 0x01, 0x8B, 0xD1, + 0x20, 0xC6, 0x0F, 0xA0, 0xB5, 0xBC, 0x17, 0x4E, 0x48, 0x7B, 0x51, 0xC2, + 0xFC, 0xE9, 0x5C, 0x69, 0x37, 0x47, 0x66, 0xB3, 0x68, 0xF8, 0x15, 0x28, + 0xF0, 0xB9, 0xD3, 0xA4, 0x15, 0xCC, 0x5A, 0x4F, 0xBA, 0x52, 0x70, 0xA3, + 0x12, 0x45, 0xDD, 0xC6, 0xBA, 0x4E, 0xFB, 0xC2, 0xD0, 0xF7, 0xA8, 0x52, + 0x27, 0x6D, 0x6E, 0x79, 0xB5, 0x8C, 0xFC, 0x7B, 0x8C, 0xC1, 0x16, 0x4C, + 0xEE, 0x80, 0x7F, 0xBE, 0xF0, 0x76, 0xBE, 0x41, 0x53, 0x12, 0x33, 0xAE, + 0x5A, 0x38, 0x42, 0xAB, 0xD7, 0x0F, 0x3E, 0x41, 0x8D, 0x76, 0x07, 0x32, + 0xD5, 0xAB, 0x89, 0xF6, 0x4E, 0x67, 0xD9, 0xB1, 0x42, 0x75, 0x23, 0x6E, + 0xF3, 0xCD, 0x42, 0xB2, 0xFC, 0x55, 0xF5, 0x53, 0x87, 0x17, 0x3B, 0xC0, + 0x33, 0x58, 0xF1, 0x52, 0xD2, 0xF9, 0x80, 0xA4, 0xF0, 0xE8, 0xF0, 0x3B, + 0x8B, 0x38, 0xCC, 0xA4, 0xC6, 0x90, 0x7F, 0x0F, 0x9C, 0xFD, 0x8B, 0xD1, + 0xA3, 0xCF, 0xDA, 0x83, 0xA7, 0x69, 0xC9, 0x50, 0x36, 0xD5, 0x5C, 0x05, + 0xD2, 0x0A, 0x41, 0x74, 0xDB, 0x63, 0x11, 0x37, 0xC1, 0xA5, 0xA0, 0x96, + 0x4B, 0x1E, 0x8C, 0x16, 0x12, 0x77, 0xAE, 0x94, 0x34, 0x7B, 0x1E, 0x7F, + 0xC2, 0x66, 0x00, 0xE4, 0xAA, 0x83, 0xEA, 0x8A, 0x90, 0xAD, 0xCE, 0x36, + 0x44, 0x4D, 0xD1, 0x51, 0xE9, 0xBC, 0x1F, 0xF3, 0x6A, 0x05, 0xFD, 0xC0, + 0x74, 0x1F, 0x25, 0x19, 0x40, 0x51, 0x6E, 0xEA, 0x82, 0x51, 0x40, 0xDF, + 0x9B, 0xB9, 0x08, 0x2A, 0x06, 0x02, 0xD5, 0x23, 0x1C, 0x13, 0xD6, 0xE9, + 0xDB, 0xDB, 0xC6, 0xB0, 0x7A, 0xCB, 0x7B, 0x27, 0x9B, 0xFB, 0xE0, 0xD5, + 0x46, 0x24, 0xED, 0x10, 0x4B, 0x63, 0x4B, 0xA5, 0x05, 0x8F, 0xBA, 0xB8, + 0x1D, 0x2B, 0xA6, 0xFA, 0x91, 0xE2, 0x92, 0x52, 0xBD, 0xEC, 0xEB, 0x67, + 0x97, 0x6D, 0x9A, 0x2D, 0x9F, 0x81, 0x32, 0x05, 0x67, 0x32, 0xFB, 0x48, + 0x08, 0x3F, 0xD9, 0x25, 0xB8, 0x04, 0x25, 0x2F +}; + +static const unsigned char TA497_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA498_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1F, 0x4B, 0x72, 0x61, 0x6A, 0x6F, 0x77, 0x61, 0x20, 0x49, 0x7A, + 0x62, 0x61, 0x20, 0x52, 0x6F, 0x7A, 0x6C, 0x69, 0x63, 0x7A, 0x65, 0x6E, + 0x69, 0x6F, 0x77, 0x61, 0x20, 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x53, 0x5A, 0x41, 0x46, + 0x49, 0x52, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA498_RSA_N[] = { + 0xB7, 0xBC, 0x3E, 0x50, 0xA8, 0x4B, 0xCD, 0x40, 0xB5, 0xCE, 0x61, 0xE7, + 0x96, 0xCA, 0xB4, 0xA1, 0xDA, 0x0C, 0x22, 0xB0, 0xFA, 0xB5, 0x7B, 0x76, + 0x00, 0x77, 0x8C, 0x0B, 0xCF, 0x7D, 0xA8, 0x86, 0xCC, 0x26, 0x51, 0xE4, + 0x20, 0x3D, 0x85, 0x0C, 0xD6, 0x58, 0xE3, 0xE7, 0xF4, 0x2A, 0x18, 0x9D, + 0xDA, 0xD1, 0xAE, 0x26, 0xEE, 0xEB, 0x53, 0xDC, 0xF4, 0x90, 0xD6, 0x13, + 0x4A, 0x0C, 0x90, 0x3C, 0xC3, 0xF4, 0xDA, 0xD2, 0x8E, 0x0D, 0x92, 0x3A, + 0xDC, 0xB1, 0xB1, 0xFF, 0x38, 0xDE, 0xC3, 0xBA, 0x2D, 0x5F, 0x80, 0xB9, + 0x02, 0xBD, 0x4A, 0x9D, 0x1B, 0x0F, 0xB4, 0xC3, 0xC2, 0xC1, 0x67, 0x03, + 0xDD, 0xDC, 0x1B, 0x9C, 0x3D, 0xB3, 0xB0, 0xDE, 0x00, 0x1E, 0xA8, 0x34, + 0x47, 0xBB, 0x9A, 0xEB, 0xFE, 0x0B, 0x14, 0xBD, 0x36, 0x84, 0xDA, 0x0D, + 0x20, 0xBF, 0xFA, 0x5B, 0xCB, 0xA9, 0x16, 0x20, 0xAD, 0x39, 0x60, 0xEE, + 0x2F, 0x75, 0xB6, 0xE7, 0x97, 0x9C, 0xF9, 0x3E, 0xFD, 0x7E, 0x4D, 0x6F, + 0x4D, 0x2F, 0xEF, 0x88, 0x0D, 0x6A, 0xFA, 0xDD, 0xF1, 0x3D, 0x6E, 0x20, + 0xA5, 0xA0, 0x12, 0xB4, 0x4D, 0x70, 0xB9, 0xCE, 0xD7, 0x72, 0x3B, 0x89, + 0x93, 0xA7, 0x80, 0x84, 0x1C, 0x27, 0x49, 0x72, 0x49, 0xB5, 0xFF, 0x3B, + 0x95, 0x9E, 0xC1, 0xCC, 0xC8, 0x01, 0xEC, 0xE8, 0x0E, 0x8A, 0x0A, 0x96, + 0xE7, 0xB3, 0xA6, 0x87, 0xE5, 0xD6, 0xF9, 0x05, 0x2B, 0x0D, 0x97, 0x40, + 0x70, 0x3C, 0xBA, 0xAC, 0x75, 0x5A, 0x9C, 0xD5, 0x4D, 0x9D, 0x02, 0x0A, + 0xD2, 0x4B, 0x9B, 0x66, 0x4B, 0x46, 0x07, 0x17, 0x65, 0xAD, 0x9F, 0x6C, + 0x88, 0x00, 0xDC, 0x22, 0x89, 0xE0, 0xE1, 0x64, 0xD4, 0x67, 0xBC, 0x31, + 0x79, 0x61, 0x3C, 0xBB, 0xCA, 0x41, 0xCD, 0x5C, 0x6A, 0x00, 0xC8, 0x3C, + 0x38, 0x8E, 0x58, 0xAF +}; + +static const unsigned char TA498_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA499_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, + 0x36 +}; + +static const unsigned char TA499_EC_Q[] = { + 0x04, 0x76, 0xFA, 0x99, 0xA9, 0x6E, 0x20, 0xED, 0xF9, 0xD7, 0x77, 0xE3, + 0x07, 0x3B, 0xA8, 0xDB, 0x3D, 0x5F, 0x38, 0xE8, 0xAB, 0x55, 0xA6, 0x56, + 0x4F, 0xD6, 0x48, 0xEA, 0xEC, 0x7F, 0x2D, 0xAA, 0xC3, 0xB2, 0xC5, 0x79, + 0xEC, 0x99, 0x61, 0x7F, 0x10, 0x79, 0xC7, 0x02, 0x5A, 0xF9, 0x04, 0x37, + 0xF5, 0x34, 0x35, 0x2B, 0x77, 0xCE, 0x7F, 0x20, 0x8F, 0x52, 0xA3, 0x00, + 0x89, 0xEC, 0xD5, 0xA7, 0xA2, 0x6D, 0x5B, 0xE3, 0x4B, 0x92, 0x93, 0xA0, + 0x80, 0xF5, 0x01, 0x94, 0xDC, 0xF0, 0x68, 0x07, 0x1E, 0xCD, 0xEE, 0xFE, + 0x25, 0x52, 0xB5, 0x20, 0x43, 0x1C, 0x1B, 0xFE, 0xEB, 0x19, 0xCE, 0x43, + 0xA3 +}; + +static const unsigned char TA500_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, + 0x36 +}; + +static const unsigned char TA500_RSA_N[] = { + 0x93, 0xBE, 0xD5, 0x36, 0x52, 0x75, 0xD8, 0x01, 0x23, 0xA0, 0x1C, 0x47, + 0x42, 0x49, 0xEE, 0x63, 0xB6, 0xB7, 0x21, 0xFD, 0xC4, 0x95, 0xD5, 0x48, + 0x2B, 0x26, 0x7C, 0x14, 0x53, 0x10, 0xDA, 0x79, 0xFD, 0x2B, 0xB7, 0x2D, + 0xA4, 0xD4, 0x2C, 0xFA, 0xEA, 0x32, 0xDD, 0x49, 0xC2, 0xB9, 0xBD, 0x0F, + 0x48, 0x3D, 0x7B, 0x5A, 0x98, 0x54, 0xAF, 0x9E, 0x5D, 0x31, 0x74, 0x4F, + 0x07, 0xFC, 0x50, 0x21, 0xDD, 0xA4, 0xCF, 0x68, 0x4F, 0x1B, 0x12, 0x63, + 0x6D, 0x25, 0x99, 0x4C, 0x2A, 0x99, 0xF3, 0x48, 0x30, 0x61, 0xFA, 0x81, + 0x7C, 0x1E, 0xA7, 0x08, 0x4A, 0xDC, 0x3E, 0x2B, 0x1C, 0x1F, 0x18, 0x4C, + 0x71, 0xAA, 0x35, 0x8C, 0xAD, 0xF8, 0x6E, 0xE8, 0x3B, 0x4A, 0xD9, 0xE5, + 0x94, 0x02, 0xD6, 0x89, 0x84, 0x13, 0xAA, 0x6D, 0xC8, 0x4F, 0x33, 0xCC, + 0x50, 0x96, 0x37, 0x92, 0x33, 0xDC, 0x5F, 0x88, 0xE7, 0x9F, 0x54, 0xD9, + 0x48, 0xF0, 0x98, 0x43, 0xD6, 0x66, 0xFD, 0x9F, 0x17, 0x38, 0x43, 0xC5, + 0x01, 0x51, 0x0B, 0xD7, 0xE3, 0x23, 0x0F, 0x14, 0x5D, 0x5B, 0x14, 0xE7, + 0x4B, 0xBE, 0xDD, 0xF4, 0xC8, 0xDA, 0x03, 0x37, 0xD1, 0xD6, 0x39, 0xA1, + 0x21, 0x51, 0x30, 0x83, 0xB0, 0x6D, 0xD7, 0x30, 0x4E, 0x96, 0x5B, 0x91, + 0xF0, 0x70, 0x24, 0xAB, 0xBF, 0x45, 0x81, 0x64, 0x43, 0x0D, 0xBD, 0x21, + 0x3A, 0x2F, 0x3C, 0xE9, 0x9E, 0x0D, 0xCB, 0x20, 0xB5, 0x42, 0x27, 0xCC, + 0xDA, 0x6F, 0x9B, 0xEE, 0x64, 0x30, 0x90, 0x39, 0xCD, 0x93, 0x65, 0x81, + 0x21, 0x31, 0xB5, 0x23, 0x50, 0x33, 0x37, 0x22, 0xE3, 0x38, 0xED, 0xF8, + 0x31, 0x30, 0xCC, 0x45, 0xFE, 0x62, 0xF9, 0xD1, 0x5D, 0x32, 0x79, 0x42, + 0x87, 0xDF, 0x6A, 0xCC, 0x56, 0x19, 0x40, 0x4D, 0xCE, 0xAA, 0xBB, 0xF9, + 0xB5, 0x76, 0x49, 0x94, 0xF1, 0x27, 0xF8, 0x91, 0xA5, 0x83, 0xE5, 0x06, + 0xB3, 0x63, 0x0E, 0x80, 0xDC, 0xE0, 0x12, 0x55, 0x80, 0xA6, 0x3B, 0x66, + 0xB4, 0x39, 0x87, 0x2D, 0xC8, 0xF0, 0xD0, 0xD1, 0x14, 0xE9, 0xE4, 0x0D, + 0x4D, 0x0E, 0xF6, 0x5D, 0x57, 0x72, 0xC5, 0x3B, 0x1C, 0x47, 0x56, 0x9D, + 0xE2, 0xD5, 0xFB, 0x81, 0x61, 0x8C, 0xCC, 0x4D, 0x80, 0x90, 0x34, 0x5B, + 0xB7, 0xD7, 0x14, 0x75, 0xDC, 0xD8, 0x04, 0x48, 0x9F, 0xC0, 0xC1, 0x28, + 0x88, 0xB4, 0xE9, 0x1C, 0xCA, 0xA7, 0xB1, 0xF1, 0x56, 0xB7, 0x7B, 0x49, + 0x4C, 0x59, 0xE5, 0x20, 0x15, 0xA8, 0x84, 0x02, 0x29, 0xFA, 0x38, 0x94, + 0x69, 0x9A, 0x49, 0x06, 0x8F, 0xCD, 0x1F, 0x79, 0x14, 0x17, 0x12, 0x0C, + 0x83, 0x7A, 0xDE, 0x1F, 0xB1, 0x97, 0xEE, 0xF9, 0x97, 0x78, 0x28, 0xA4, + 0xC8, 0x44, 0x92, 0xE9, 0x7D, 0x26, 0x05, 0xA6, 0x58, 0x72, 0x9B, 0x79, + 0x13, 0xD8, 0x11, 0x5F, 0xAE, 0xC5, 0x38, 0x62, 0x34, 0x68, 0xB2, 0x86, + 0x30, 0x8E, 0xF8, 0x90, 0x61, 0x9E, 0x32, 0x6C, 0xF5, 0x07, 0x36, 0xCD, + 0xA2, 0x4C, 0x6E, 0xEC, 0x8A, 0x36, 0xED, 0xF2, 0xE6, 0x99, 0x15, 0x44, + 0x70, 0xC3, 0x7C, 0xBC, 0x9C, 0x39, 0xC0, 0xB4, 0xE1, 0x6B, 0xF7, 0x83, + 0x25, 0x23, 0x57, 0xD9, 0x12, 0x80, 0xE5, 0x49, 0xF0, 0x75, 0x0F, 0xEF, + 0x8D, 0xEB, 0x1C, 0x9B, 0x54, 0x28, 0xB4, 0x21, 0x3C, 0xFC, 0x7C, 0x0A, + 0xFF, 0xEF, 0x7B, 0x6B, 0x75, 0xFF, 0x8B, 0x1D, 0xA0, 0x19, 0x05, 0xAB, + 0xFA, 0xF8, 0x2B, 0x81, 0x42, 0xE8, 0x38, 0xBA, 0xBB, 0xFB, 0xAA, 0xFD, + 0x3D, 0xE0, 0xF3, 0xCA, 0xDF, 0x4E, 0x97, 0x97, 0x29, 0xED, 0xF3, 0x18, + 0x56, 0xE9, 0xA5, 0x96, 0xAC, 0xBD, 0xC3, 0x90, 0x98, 0xB2, 0xE0, 0xF9, + 0xA2, 0xD4, 0xA6, 0x47, 0x43, 0x7C, 0x6D, 0xCF +}; + +static const unsigned char TA500_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA501_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x32 +}; + +static const unsigned char TA501_RSA_N[] = { + 0xBA, 0x39, 0xC1, 0x37, 0x7A, 0x68, 0x45, 0x2B, 0x14, 0xB4, 0xEB, 0xE4, + 0x13, 0xEB, 0x57, 0x75, 0x23, 0x4D, 0x8F, 0x24, 0x2D, 0x16, 0xE8, 0xAE, + 0x8E, 0xC9, 0x7D, 0xA4, 0x57, 0x3B, 0x2A, 0x76, 0x25, 0x33, 0x83, 0x6C, + 0xEA, 0x32, 0x8A, 0x94, 0x9B, 0x4E, 0x3C, 0x96, 0xE4, 0xFD, 0x51, 0xBF, + 0x99, 0xC9, 0x93, 0x7E, 0xBF, 0xF9, 0xAD, 0xA7, 0xB2, 0x48, 0x2B, 0x07, + 0x1C, 0x27, 0xF5, 0x4C, 0xBC, 0x70, 0x12, 0x77, 0xA4, 0x85, 0x54, 0xB5, + 0xFD, 0x90, 0x7A, 0xE4, 0xA3, 0xE4, 0x51, 0x58, 0x03, 0xCD, 0x10, 0x79, + 0x79, 0xEE, 0x6B, 0x93, 0x1F, 0x64, 0x8E, 0x6B, 0x64, 0xAB, 0xA3, 0x13, + 0xE3, 0x71, 0xFE, 0x7D, 0xAB, 0x9C, 0xDD, 0x27, 0x53, 0x37, 0xB3, 0xAA, + 0x18, 0xC2, 0x59, 0x26, 0xEC, 0x5B, 0x1F, 0xD2, 0xE6, 0x65, 0x7C, 0xEF, + 0x93, 0xBD, 0xD8, 0x58, 0x5C, 0x0B, 0xC0, 0xE3, 0x65, 0x6F, 0x3C, 0xC7, + 0xCA, 0x59, 0xE3, 0xFE, 0x6E, 0x5F, 0xAC, 0x83, 0xBE, 0xFD, 0x5D, 0x25, + 0x4E, 0x2A, 0x29, 0x3B, 0xD6, 0x0B, 0xAB, 0x17, 0x32, 0x78, 0xA4, 0xE1, + 0x3E, 0x94, 0x46, 0xBE, 0x62, 0x6E, 0x9B, 0xDE, 0x46, 0xA8, 0xB1, 0x16, + 0xE7, 0x85, 0x6E, 0xF4, 0x08, 0x40, 0x45, 0x11, 0xA0, 0x9E, 0x54, 0x44, + 0x84, 0xF7, 0xD8, 0x36, 0xCE, 0xF5, 0x50, 0x47, 0xDC, 0x2C, 0x30, 0x9B, + 0xEE, 0xC0, 0xF5, 0x96, 0xD2, 0xFE, 0x09, 0x86, 0xC7, 0x06, 0x59, 0xAE, + 0x4F, 0xAE, 0x8E, 0x11, 0x98, 0x7B, 0xF3, 0x0B, 0x52, 0xAA, 0x62, 0x26, + 0xAA, 0x21, 0xDF, 0x8E, 0x25, 0x33, 0x79, 0x97, 0x16, 0x49, 0x8D, 0xF5, + 0x3E, 0xD5, 0x47, 0x9F, 0x37, 0x31, 0x49, 0x33, 0x72, 0x05, 0x4D, 0x0C, + 0xB6, 0x55, 0x8C, 0xF1, 0x57, 0x8F, 0x8A, 0x87, 0xD1, 0xAD, 0xC5, 0x11, + 0x12, 0x39, 0xA0, 0xAD +}; + +static const unsigned char TA501_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA502_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x34 +}; + +static const unsigned char TA502_RSA_N[] = { + 0xC5, 0xD2, 0x7A, 0xA1, 0xD6, 0x8A, 0xBF, 0x16, 0x31, 0xD0, 0x98, 0xD1, + 0x3A, 0x94, 0xFC, 0x5A, 0xB8, 0x6E, 0x22, 0xC1, 0x62, 0xF7, 0xA7, 0x0A, + 0x27, 0xEF, 0x50, 0xF6, 0x2E, 0xB1, 0x9E, 0x68, 0x12, 0xF0, 0x6C, 0x24, + 0x63, 0x39, 0xF1, 0xF0, 0xDF, 0x10, 0xC6, 0xDE, 0xB7, 0x52, 0x20, 0xD5, + 0x52, 0x5B, 0x42, 0x99, 0x9E, 0xF3, 0xA0, 0xBE, 0x52, 0x1F, 0x5F, 0xCC, + 0x67, 0x6D, 0xA7, 0x2E, 0x50, 0xA2, 0xC1, 0x97, 0x8D, 0xB6, 0xF8, 0x95, + 0xF5, 0xB0, 0xBA, 0xDC, 0x9D, 0xE0, 0xBE, 0xCB, 0xDF, 0xF7, 0x38, 0xF2, + 0x47, 0xF5, 0xA6, 0x9A, 0x92, 0x95, 0x2A, 0x62, 0x59, 0x50, 0x0B, 0xA2, + 0xB1, 0x35, 0xE7, 0x65, 0xB2, 0x61, 0xB2, 0xEA, 0x92, 0x71, 0x69, 0xE4, + 0x29, 0xF0, 0x4F, 0x81, 0x81, 0x04, 0x3C, 0xB2, 0xA5, 0x5B, 0xD4, 0xC5, + 0xA8, 0x59, 0x67, 0x7B, 0x55, 0x1C, 0x49, 0xAB, 0x7A, 0x9D, 0xC2, 0xE7, + 0x73, 0x4D, 0xEF, 0xCD, 0x09, 0xC2, 0xC4, 0x57, 0x12, 0xDB, 0x01, 0x0E, + 0x23, 0x79, 0x09, 0x07, 0x3B, 0xA2, 0xE8, 0xFC, 0x8A, 0xCF, 0x8F, 0xC0, + 0x46, 0x24, 0x9C, 0x38, 0x27, 0xE0, 0x83, 0x9D, 0x1B, 0xA0, 0xBF, 0x78, + 0x15, 0x10, 0xEB, 0x86, 0x4E, 0x0A, 0x5A, 0xFD, 0xDF, 0xDA, 0x2C, 0x82, + 0x7E, 0xEE, 0xCA, 0xF6, 0x29, 0xE1, 0xFA, 0x71, 0xA1, 0xF7, 0x88, 0x68, + 0x9C, 0x9C, 0xF0, 0x8D, 0xBE, 0x0F, 0x49, 0x91, 0xD8, 0xEA, 0x3A, 0xF9, + 0xFD, 0xD0, 0x68, 0x71, 0xDB, 0xE9, 0xB5, 0x2B, 0x4E, 0x82, 0x92, 0x6F, + 0x66, 0x1F, 0xE0, 0xF0, 0xDC, 0x4C, 0xEC, 0xCA, 0xD1, 0xEA, 0xBA, 0x74, + 0x06, 0xF9, 0xB3, 0x84, 0x90, 0x94, 0xD1, 0x5F, 0x8E, 0x73, 0x19, 0x10, + 0x5D, 0x02, 0xE5, 0x70, 0xA5, 0xC0, 0x10, 0xD0, 0x10, 0x7C, 0x6F, 0xC5, + 0x58, 0x49, 0xB4, 0xB0, 0x6E, 0x9A, 0xDA, 0x7D, 0x95, 0xF5, 0xCC, 0xDA, + 0x02, 0xAF, 0xB8, 0x2C, 0x7D, 0x79, 0x8F, 0xBE, 0x43, 0xF1, 0xF9, 0x28, + 0x28, 0x8D, 0x09, 0x43, 0xF8, 0x08, 0xDD, 0x6B, 0xC8, 0x8B, 0x2C, 0x24, + 0xB1, 0x8D, 0x52, 0x07, 0xBD, 0x78, 0x9B, 0xCB, 0xCA, 0x68, 0xB2, 0xA4, + 0xDD, 0x0C, 0x4C, 0x79, 0x60, 0xC6, 0x99, 0xD1, 0x93, 0xF1, 0x30, 0x1A, + 0x07, 0xD3, 0xAE, 0x22, 0xC2, 0xEA, 0xCE, 0xF1, 0x84, 0x09, 0xCC, 0xE0, + 0x14, 0x6E, 0x7F, 0x3F, 0x7E, 0xD2, 0x82, 0x85, 0xAC, 0xDC, 0xA9, 0x16, + 0x4E, 0x85, 0xA0, 0x60, 0xCB, 0xF6, 0x9C, 0xD7, 0xC8, 0xB3, 0x8E, 0xED, + 0xC6, 0x9B, 0x98, 0x75, 0x0D, 0x55, 0xE8, 0x5F, 0xE5, 0x95, 0x8B, 0x02, + 0xA4, 0xAE, 0x43, 0x29, 0x28, 0x11, 0xA4, 0xE6, 0x12, 0x30, 0x01, 0x4B, + 0x75, 0x6B, 0x1E, 0x66, 0x9D, 0x79, 0x2F, 0xA5, 0x76, 0x2F, 0x1D, 0x40, + 0xB4, 0x6D, 0xC9, 0x7D, 0x79, 0x08, 0xEC, 0xD1, 0x6A, 0xB6, 0x5D, 0x2A, + 0xB2, 0xA5, 0x66, 0xBD, 0x6B, 0x85, 0xF4, 0x74, 0x56, 0xC3, 0xF5, 0xE7, + 0x75, 0x52, 0x28, 0x2C, 0xA5, 0xFF, 0x66, 0x47, 0xA5, 0xD4, 0xFE, 0xFE, + 0x9E, 0x54, 0xBF, 0x65, 0x7E, 0x01, 0xD6, 0x30, 0x8F, 0xA5, 0x36, 0x9C, + 0xA2, 0x50, 0x1C, 0xEE, 0x38, 0x80, 0x01, 0x48, 0xC6, 0xC7, 0x74, 0xF4, + 0xC6, 0xAC, 0xC3, 0x40, 0x49, 0x16, 0x61, 0x74, 0x2C, 0xAF, 0x8C, 0x6F, + 0x35, 0xED, 0x7B, 0x18, 0x00, 0x5B, 0x36, 0x3C, 0x9C, 0x50, 0x0D, 0xCA, + 0x92, 0x33, 0x10, 0xF1, 0x26, 0x49, 0x6D, 0xDF, 0x75, 0x24, 0x37, 0x82, + 0x22, 0xD7, 0xE8, 0x96, 0xFD, 0x15, 0x4B, 0x02, 0x96, 0x3E, 0x07, 0x72, + 0x95, 0x7E, 0xAB, 0x3D, 0x4C, 0x2E, 0xD7, 0xCA, 0xF0, 0xDF, 0xE0, 0x58, + 0x3F, 0x2D, 0x2F, 0x04, 0x9A, 0x38, 0xA3, 0x01 +}; + +static const unsigned char TA502_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA503_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x35 +}; + +static const unsigned char TA503_EC_Q[] = { + 0x04, 0x0B, 0x50, 0x74, 0x8D, 0x64, 0x32, 0x99, 0x99, 0xB3, 0xD2, 0x60, + 0x08, 0xB8, 0x22, 0x8E, 0x46, 0x74, 0x2C, 0x78, 0xC0, 0x2B, 0x44, 0x2D, + 0x6D, 0x5F, 0x1D, 0xC9, 0xAE, 0x4B, 0x52, 0x20, 0x83, 0x3D, 0xB8, 0x14, + 0x6D, 0x53, 0x87, 0x60, 0x9E, 0x5F, 0x6C, 0x85, 0xDB, 0x06, 0x14, 0x95, + 0xE0, 0xC7, 0x28, 0xFF, 0x9D, 0x5F, 0xE4, 0xAA, 0xF1, 0xB3, 0x8B, 0x6D, + 0xED, 0x4F, 0x2F, 0x4B, 0xC9, 0x4A, 0x94, 0x91, 0x64, 0x75, 0xFE, 0x01, + 0xEC, 0xC1, 0xD8, 0xEB, 0x7A, 0x94, 0x78, 0x56, 0x18, 0x43, 0x5F, 0x6B, + 0x81, 0xCB, 0xF6, 0xBC, 0xDA, 0xB4, 0x0C, 0xB6, 0x29, 0x93, 0x08, 0x69, + 0x8F +}; + +static const unsigned char TA504_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0E, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA504_RSA_N[] = { + 0xAB, 0xA4, 0x81, 0xE5, 0x95, 0xCD, 0xF5, 0xF6, 0x14, 0x8E, 0xC2, 0x4F, + 0xCA, 0xD4, 0xE2, 0x78, 0x95, 0x58, 0x9C, 0x41, 0xE1, 0x0D, 0x99, 0x40, + 0x24, 0x17, 0x39, 0x91, 0x33, 0x66, 0xE9, 0xBE, 0xE1, 0x83, 0xAF, 0x62, + 0x5C, 0x89, 0xD1, 0xFC, 0x24, 0x5B, 0x61, 0xB3, 0xE0, 0x11, 0x11, 0x41, + 0x1C, 0x1D, 0x6E, 0xF0, 0xB8, 0xBB, 0xF8, 0xDE, 0xA7, 0x81, 0xBA, 0xA6, + 0x48, 0xC6, 0x9F, 0x1D, 0xBD, 0xBE, 0x8E, 0xA9, 0x41, 0x3E, 0xB8, 0x94, + 0xED, 0x29, 0x1A, 0xD4, 0x8E, 0xD2, 0x03, 0x1D, 0x03, 0xEF, 0x6D, 0x0D, + 0x67, 0x1C, 0x57, 0xD7, 0x06, 0xAD, 0xCA, 0xC8, 0xF5, 0xFE, 0x0E, 0xAF, + 0x66, 0x25, 0x48, 0x04, 0x96, 0x0B, 0x5D, 0xA3, 0xBA, 0x16, 0xC3, 0x08, + 0x4F, 0xD1, 0x46, 0xF8, 0x14, 0x5C, 0xF2, 0xC8, 0x5E, 0x01, 0x99, 0x6D, + 0xFD, 0x88, 0xCC, 0x86, 0xA8, 0xC1, 0x6F, 0x31, 0x42, 0x6C, 0x52, 0x3E, + 0x68, 0xCB, 0xF3, 0x19, 0x34, 0xDF, 0xBB, 0x87, 0x18, 0x56, 0x80, 0x26, + 0xC4, 0xD0, 0xDC, 0xC0, 0x6F, 0xDF, 0xDE, 0xA0, 0xC2, 0x91, 0x16, 0xA0, + 0x64, 0x11, 0x4B, 0x44, 0xBC, 0x1E, 0xF6, 0xE7, 0xFA, 0x63, 0xDE, 0x66, + 0xAC, 0x76, 0xA4, 0x71, 0xA3, 0xEC, 0x36, 0x94, 0x68, 0x7A, 0x77, 0xA4, + 0xB1, 0xE7, 0x0E, 0x2F, 0x81, 0x7A, 0xE2, 0xB5, 0x72, 0x86, 0xEF, 0xA2, + 0x6B, 0x8B, 0xF0, 0x0F, 0xDB, 0xD3, 0x59, 0x3F, 0xBA, 0x72, 0xBC, 0x44, + 0x24, 0x9C, 0xE3, 0x73, 0xB3, 0xF7, 0xAF, 0x57, 0x2F, 0x42, 0x26, 0x9D, + 0xA9, 0x74, 0xBA, 0x00, 0x52, 0xF2, 0x4B, 0xCD, 0x53, 0x7C, 0x47, 0x0B, + 0x36, 0x85, 0x0E, 0x66, 0xA9, 0x08, 0x97, 0x16, 0x34, 0x57, 0xC1, 0x66, + 0xF7, 0x80, 0xE3, 0xED, 0x70, 0x54, 0xC7, 0x93, 0xE0, 0x2E, 0x28, 0x15, + 0x59, 0x87, 0xBA, 0xBB +}; + +static const unsigned char TA504_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA505_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA505_RSA_N[] = { + 0xAF, 0x35, 0x2E, 0xD8, 0xAC, 0x6C, 0x55, 0x69, 0x06, 0x71, 0xE5, 0x13, + 0x68, 0x24, 0xB3, 0x4F, 0xD8, 0xCC, 0x21, 0x47, 0xF8, 0xF1, 0x60, 0x38, + 0x89, 0x89, 0x03, 0xE9, 0xBD, 0xEA, 0x5E, 0x46, 0x53, 0x09, 0xDC, 0x5C, + 0xF5, 0x5A, 0xE8, 0xF7, 0x45, 0x2A, 0x02, 0xEB, 0x31, 0x61, 0xD7, 0x29, + 0x33, 0x4C, 0xCE, 0xC7, 0x7C, 0x0A, 0x37, 0x7E, 0x0F, 0xBA, 0x32, 0x98, + 0xE1, 0x1D, 0x97, 0xAF, 0x8F, 0xC7, 0xDC, 0xC9, 0x38, 0x96, 0xF3, 0xDB, + 0x1A, 0xFC, 0x51, 0xED, 0x68, 0xC6, 0xD0, 0x6E, 0xA4, 0x7C, 0x24, 0xD1, + 0xAE, 0x42, 0xC8, 0x96, 0x50, 0x63, 0x2E, 0xE0, 0xFE, 0x75, 0xFE, 0x98, + 0xA7, 0x5F, 0x49, 0x2E, 0x95, 0xE3, 0x39, 0x33, 0x64, 0x8E, 0x1E, 0xA4, + 0x5F, 0x90, 0xD2, 0x67, 0x3C, 0xB2, 0xD9, 0xFE, 0x41, 0xB9, 0x55, 0xA7, + 0x09, 0x8E, 0x72, 0x05, 0x1E, 0x8B, 0xDD, 0x44, 0x85, 0x82, 0x42, 0xD0, + 0x49, 0xC0, 0x1D, 0x60, 0xF0, 0xD1, 0x17, 0x2C, 0x95, 0xEB, 0xF6, 0xA5, + 0xC1, 0x92, 0xA3, 0xC5, 0xC2, 0xA7, 0x08, 0x60, 0x0D, 0x60, 0x04, 0x10, + 0x96, 0x79, 0x9E, 0x16, 0x34, 0xE6, 0xA9, 0xB6, 0xFA, 0x25, 0x45, 0x39, + 0xC8, 0x1E, 0x65, 0xF9, 0x93, 0xF5, 0xAA, 0xF1, 0x52, 0xDC, 0x99, 0x98, + 0x3D, 0xA5, 0x86, 0x1A, 0x0C, 0x35, 0x33, 0xFA, 0x4B, 0xA5, 0x04, 0x06, + 0x15, 0x1C, 0x31, 0x80, 0xEF, 0xAA, 0x18, 0x6B, 0xC2, 0x7B, 0xD7, 0xDA, + 0xCE, 0xF9, 0x33, 0x20, 0xD5, 0xF5, 0xBD, 0x6A, 0x33, 0x2D, 0x81, 0x04, + 0xFB, 0xB0, 0x5C, 0xD4, 0x9C, 0xA3, 0xE2, 0x5C, 0x1D, 0xE3, 0xA9, 0x42, + 0x75, 0x5E, 0x7B, 0xD4, 0x77, 0xEF, 0x39, 0x54, 0xBA, 0xC9, 0x0A, 0x18, + 0x1B, 0x12, 0x99, 0x49, 0x2F, 0x88, 0x4B, 0xFD, 0x50, 0x62, 0xD1, 0x73, + 0xE7, 0x8F, 0x7A, 0x43 +}; + +static const unsigned char TA505_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA506_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x43, 0x41, 0x31 +}; + +static const unsigned char TA506_EC_Q[] = { + 0x04, 0xA4, 0xA5, 0x6F, 0x60, 0x03, 0x03, 0xC3, 0xBD, 0x31, 0xF4, 0xD3, + 0x17, 0x9C, 0x2B, 0x84, 0x75, 0xAC, 0xE5, 0xFD, 0x3D, 0x57, 0x6E, 0xD7, + 0x63, 0xBF, 0xE6, 0x04, 0x89, 0x92, 0x8E, 0x81, 0x9C, 0xE3, 0xE9, 0x47, + 0x6E, 0xCA, 0x90, 0x12, 0xC8, 0x13, 0xE0, 0xA7, 0x9D, 0xF7, 0x65, 0x74, + 0x1F, 0x6C, 0x10, 0xB2, 0xE8, 0xE4, 0xE9, 0xEF, 0x6D, 0x85, 0x32, 0x99, + 0x44, 0xB1, 0x5E, 0xFD, 0xCC, 0x76, 0x10, 0xD8, 0x5B, 0xBD, 0xA2, 0xC6, + 0xF9, 0xD6, 0x42, 0xE4, 0x57, 0x76, 0xDC, 0x90, 0xC2, 0x35, 0xA9, 0x4B, + 0x88, 0x3C, 0x12, 0x47, 0x6D, 0x5C, 0xFF, 0x49, 0x4F, 0x1A, 0x4A, 0x50, + 0xB1 +}; + +static const unsigned char TA507_DN[] = { + 0x30, 0x5D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x1E, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA507_RSA_N[] = { + 0xD0, 0x15, 0x39, 0x52, 0xB1, 0x52, 0xB3, 0xBA, 0xC5, 0x59, 0x82, 0xC4, + 0x5D, 0x52, 0xAE, 0x3A, 0x43, 0x65, 0x80, 0x4B, 0xC7, 0xF2, 0x96, 0xBC, + 0xDB, 0x36, 0x97, 0xD6, 0xA6, 0x64, 0x8C, 0xA8, 0x5E, 0xF0, 0xE3, 0x0A, + 0x1C, 0xF7, 0xDF, 0x97, 0x3D, 0x4B, 0xAE, 0xF6, 0x5D, 0xEC, 0x21, 0xB5, + 0x41, 0xAB, 0xCD, 0xB9, 0x7E, 0x76, 0x9F, 0xBE, 0xF9, 0x3E, 0x36, 0x34, + 0xA0, 0x3B, 0xC1, 0xF6, 0x31, 0x11, 0x45, 0x74, 0x93, 0x3D, 0x57, 0x80, + 0xC5, 0xF9, 0x89, 0x99, 0xCA, 0xE5, 0xAB, 0x6A, 0xD4, 0xB5, 0xDA, 0x41, + 0x90, 0x10, 0xC1, 0xD6, 0xD6, 0x42, 0x89, 0xC2, 0xBF, 0xF4, 0x38, 0x12, + 0x95, 0x4C, 0x54, 0x05, 0xF7, 0x36, 0xE4, 0x45, 0x83, 0x7B, 0x14, 0x65, + 0xD6, 0xDC, 0x0C, 0x4D, 0xD1, 0xDE, 0x7E, 0x0C, 0xAB, 0x3B, 0xC4, 0x15, + 0xBE, 0x3A, 0x56, 0xA6, 0x5A, 0x6F, 0x76, 0x69, 0x52, 0xA9, 0x7A, 0xB9, + 0xC8, 0xEB, 0x6A, 0x9A, 0x5D, 0x52, 0xD0, 0x2D, 0x0A, 0x6B, 0x35, 0x16, + 0x09, 0x10, 0x84, 0xD0, 0x6A, 0xCA, 0x3A, 0x06, 0x00, 0x37, 0x47, 0xE4, + 0x7E, 0x57, 0x4F, 0x3F, 0x8B, 0xEB, 0x67, 0xB8, 0x88, 0xAA, 0xC5, 0xBE, + 0x53, 0x55, 0xB2, 0x91, 0xC4, 0x7D, 0xB9, 0xB0, 0x85, 0x19, 0x06, 0x78, + 0x2E, 0xDB, 0x61, 0x1A, 0xFA, 0x85, 0xF5, 0x4A, 0x91, 0xA1, 0xE7, 0x16, + 0xD5, 0x8E, 0xA2, 0x39, 0xDF, 0x94, 0xB8, 0x70, 0x1F, 0x28, 0x3F, 0x8B, + 0xFC, 0x40, 0x5E, 0x63, 0x83, 0x3C, 0x83, 0x2A, 0x1A, 0x99, 0x6B, 0xCF, + 0xDE, 0x59, 0x6A, 0x3B, 0xFC, 0x6F, 0x16, 0xD7, 0x1F, 0xFD, 0x4A, 0x10, + 0xEB, 0x4E, 0x82, 0x16, 0x3A, 0xAC, 0x27, 0x0C, 0x53, 0xF1, 0xAD, 0xD5, + 0x24, 0xB0, 0x6B, 0x03, 0x50, 0xC1, 0x2D, 0x3C, 0x16, 0xDD, 0x44, 0x34, + 0x27, 0x1A, 0x75, 0xFB +}; + +static const unsigned char TA507_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA508_DN[] = { + 0x30, 0x68, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, + 0x6C, 0x64, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA508_RSA_N[] = { + 0xB7, 0x32, 0xC8, 0xFE, 0xE9, 0x71, 0xA6, 0x04, 0x85, 0xAD, 0x0C, 0x11, + 0x64, 0xDF, 0xCE, 0x4D, 0xEF, 0xC8, 0x03, 0x18, 0x87, 0x3F, 0xA1, 0xAB, + 0xFB, 0x3C, 0xA6, 0x9F, 0xF0, 0xC3, 0xA1, 0xDA, 0xD4, 0xD8, 0x6E, 0x2B, + 0x53, 0x90, 0xFB, 0x24, 0xA4, 0x3E, 0x84, 0xF0, 0x9E, 0xE8, 0x5F, 0xEC, + 0xE5, 0x27, 0x44, 0xF5, 0x28, 0xA6, 0x3F, 0x7B, 0xDE, 0xE0, 0x2A, 0xF0, + 0xC8, 0xAF, 0x53, 0x2F, 0x9E, 0xCA, 0x05, 0x01, 0x93, 0x1E, 0x8F, 0x66, + 0x1C, 0x39, 0xA7, 0x4D, 0xFA, 0x5A, 0xB6, 0x73, 0x04, 0x25, 0x66, 0xEB, + 0x77, 0x7F, 0xE7, 0x59, 0xC6, 0x4A, 0x99, 0x25, 0x14, 0x54, 0xEB, 0x26, + 0xC7, 0xF3, 0x7F, 0x19, 0xD5, 0x30, 0x70, 0x8F, 0xAF, 0xB0, 0x46, 0x2A, + 0xFF, 0xAD, 0xEB, 0x29, 0xED, 0xD7, 0x9F, 0xAA, 0x04, 0x87, 0xA3, 0xD4, + 0xF9, 0x89, 0xA5, 0x34, 0x5F, 0xDB, 0x43, 0x91, 0x82, 0x36, 0xD9, 0x66, + 0x3C, 0xB1, 0xB8, 0xB9, 0x82, 0xFD, 0x9C, 0x3A, 0x3E, 0x10, 0xC8, 0x3B, + 0xEF, 0x06, 0x65, 0x66, 0x7A, 0x9B, 0x19, 0x18, 0x3D, 0xFF, 0x71, 0x51, + 0x3C, 0x30, 0x2E, 0x5F, 0xBE, 0x3D, 0x77, 0x73, 0xB2, 0x5D, 0x06, 0x6C, + 0xC3, 0x23, 0x56, 0x9A, 0x2B, 0x85, 0x26, 0x92, 0x1C, 0xA7, 0x02, 0xB3, + 0xE4, 0x3F, 0x0D, 0xAF, 0x08, 0x79, 0x82, 0xB8, 0x36, 0x3D, 0xEA, 0x9C, + 0xD3, 0x35, 0xB3, 0xBC, 0x69, 0xCA, 0xF5, 0xCC, 0x9D, 0xE8, 0xFD, 0x64, + 0x8D, 0x17, 0x80, 0x33, 0x6E, 0x5E, 0x4A, 0x5D, 0x99, 0xC9, 0x1E, 0x87, + 0xB4, 0x9D, 0x1A, 0xC0, 0xD5, 0x6E, 0x13, 0x35, 0x23, 0x5E, 0xDF, 0x9B, + 0x5F, 0x3D, 0xEF, 0xD6, 0xF7, 0x76, 0xC2, 0xEA, 0x3E, 0xBB, 0x78, 0x0D, + 0x1C, 0x42, 0x67, 0x6B, 0x04, 0xD8, 0xF8, 0xD6, 0xDA, 0x6F, 0x8B, 0xF2, + 0x44, 0xA0, 0x01, 0xAB +}; + +static const unsigned char TA508_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA509_DN[] = { + 0x30, 0x81, 0x8F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, + 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA509_RSA_N[] = { + 0xBD, 0xED, 0xC1, 0x03, 0xFC, 0xF6, 0x8F, 0xFC, 0x02, 0xB1, 0x6F, 0x5B, + 0x9F, 0x48, 0xD9, 0x9D, 0x79, 0xE2, 0xA2, 0xB7, 0x03, 0x61, 0x56, 0x18, + 0xC3, 0x47, 0xB6, 0xD7, 0xCA, 0x3D, 0x35, 0x2E, 0x89, 0x43, 0xF7, 0xA1, + 0x69, 0x9B, 0xDE, 0x8A, 0x1A, 0xFD, 0x13, 0x20, 0x9C, 0xB4, 0x49, 0x77, + 0x32, 0x29, 0x56, 0xFD, 0xB9, 0xEC, 0x8C, 0xDD, 0x22, 0xFA, 0x72, 0xDC, + 0x27, 0x61, 0x97, 0xEE, 0xF6, 0x5A, 0x84, 0xEC, 0x6E, 0x19, 0xB9, 0x89, + 0x2C, 0xDC, 0x84, 0x5B, 0xD5, 0x74, 0xFB, 0x6B, 0x5F, 0xC5, 0x89, 0xA5, + 0x10, 0x52, 0x89, 0x46, 0x55, 0xF4, 0xB8, 0x75, 0x1C, 0xE6, 0x7F, 0xE4, + 0x54, 0xAE, 0x4B, 0xF8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xF8, 0x17, 0x71, + 0x59, 0xEB, 0x1E, 0x28, 0x07, 0x74, 0xC5, 0x9D, 0x48, 0xBE, 0x6C, 0xB4, + 0xF4, 0xA4, 0xB0, 0xF3, 0x64, 0x37, 0x79, 0x92, 0xC0, 0xEC, 0x46, 0x5E, + 0x7F, 0xE1, 0x6D, 0x53, 0x4C, 0x62, 0xAF, 0xCD, 0x1F, 0x0B, 0x63, 0xBB, + 0x3A, 0x9D, 0xFB, 0xFC, 0x79, 0x00, 0x98, 0x61, 0x74, 0xCF, 0x26, 0x82, + 0x40, 0x63, 0xF3, 0xB2, 0x72, 0x6A, 0x19, 0x0D, 0x99, 0xCA, 0xD4, 0x0E, + 0x75, 0xCC, 0x37, 0xFB, 0x8B, 0x89, 0xC1, 0x59, 0xF1, 0x62, 0x7F, 0x5F, + 0xB3, 0x5F, 0x65, 0x30, 0xF8, 0xA7, 0xB7, 0x4D, 0x76, 0x5A, 0x1E, 0x76, + 0x5E, 0x34, 0xC0, 0xE8, 0x96, 0x56, 0x99, 0x8A, 0xB3, 0xF0, 0x7F, 0xA4, + 0xCD, 0xBD, 0xDC, 0x32, 0x31, 0x7C, 0x91, 0xCF, 0xE0, 0x5F, 0x11, 0xF8, + 0x6B, 0xAA, 0x49, 0x5C, 0xD1, 0x99, 0x94, 0xD1, 0xA2, 0xE3, 0x63, 0x5B, + 0x09, 0x76, 0xB5, 0x56, 0x62, 0xE1, 0x4B, 0x74, 0x1D, 0x96, 0xD4, 0x26, + 0xD4, 0x08, 0x04, 0x59, 0xD0, 0x98, 0x0E, 0x0E, 0xE6, 0xDE, 0xFC, 0xC3, + 0xEC, 0x1F, 0x90, 0xF1 +}; + +static const unsigned char TA509_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA510_DN[] = { + 0x30, 0x81, 0x98, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3B, + 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA510_RSA_N[] = { + 0xD5, 0x0C, 0x3A, 0xC4, 0x2A, 0xF9, 0x4E, 0xE2, 0xF5, 0xBE, 0x19, 0x97, + 0x5F, 0x8E, 0x88, 0x53, 0xB1, 0x1F, 0x3F, 0xCB, 0xCF, 0x9F, 0x20, 0x13, + 0x6D, 0x29, 0x3A, 0xC8, 0x0F, 0x7D, 0x3C, 0xF7, 0x6B, 0x76, 0x38, 0x63, + 0xD9, 0x36, 0x60, 0xA8, 0x9B, 0x5E, 0x5C, 0x00, 0x80, 0xB2, 0x2F, 0x59, + 0x7F, 0xF6, 0x87, 0xF9, 0x25, 0x43, 0x86, 0xE7, 0x69, 0x1B, 0x52, 0x9A, + 0x90, 0xE1, 0x71, 0xE3, 0xD8, 0x2D, 0x0D, 0x4E, 0x6F, 0xF6, 0xC8, 0x49, + 0xD9, 0xB6, 0xF3, 0x1A, 0x56, 0xAE, 0x2B, 0xB6, 0x74, 0x14, 0xEB, 0xCF, + 0xFB, 0x26, 0xE3, 0x1A, 0xBA, 0x1D, 0x96, 0x2E, 0x6A, 0x3B, 0x58, 0x94, + 0x89, 0x47, 0x56, 0xFF, 0x25, 0xA0, 0x93, 0x70, 0x53, 0x83, 0xDA, 0x84, + 0x74, 0x14, 0xC3, 0x67, 0x9E, 0x04, 0x68, 0x3A, 0xDF, 0x8E, 0x40, 0x5A, + 0x1D, 0x4A, 0x4E, 0xCF, 0x43, 0x91, 0x3B, 0xE7, 0x56, 0xD6, 0x00, 0x70, + 0xCB, 0x52, 0xEE, 0x7B, 0x7D, 0xAE, 0x3A, 0xE7, 0xBC, 0x31, 0xF9, 0x45, + 0xF6, 0xC2, 0x60, 0xCF, 0x13, 0x59, 0x02, 0x2B, 0x80, 0xCC, 0x34, 0x47, + 0xDF, 0xB9, 0xDE, 0x90, 0x65, 0x6D, 0x02, 0xCF, 0x2C, 0x91, 0xA6, 0xA6, + 0xE7, 0xDE, 0x85, 0x18, 0x49, 0x7C, 0x66, 0x4E, 0xA3, 0x3A, 0x6D, 0xA9, + 0xB5, 0xEE, 0x34, 0x2E, 0xBA, 0x0D, 0x03, 0xB8, 0x33, 0xDF, 0x47, 0xEB, + 0xB1, 0x6B, 0x8D, 0x25, 0xD9, 0x9B, 0xCE, 0x81, 0xD1, 0x45, 0x46, 0x32, + 0x96, 0x70, 0x87, 0xDE, 0x02, 0x0E, 0x49, 0x43, 0x85, 0xB6, 0x6C, 0x73, + 0xBB, 0x64, 0xEA, 0x61, 0x41, 0xAC, 0xC9, 0xD4, 0x54, 0xDF, 0x87, 0x2F, + 0xC7, 0x22, 0xB2, 0x26, 0xCC, 0x9F, 0x59, 0x54, 0x68, 0x9F, 0xFC, 0xBE, + 0x2A, 0x2F, 0xC4, 0x55, 0x1C, 0x75, 0x40, 0x60, 0x17, 0x85, 0x02, 0x55, + 0x39, 0x8B, 0x7F, 0x05 +}; + +static const unsigned char TA510_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA511_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x41, 0x47, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x16, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, + 0x6F, 0x6C, 0x64, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA511_RSA_N[] = { + 0xAF, 0xE4, 0xEE, 0x7E, 0x8B, 0x24, 0x0E, 0x12, 0x6E, 0xA9, 0x50, 0x2D, + 0x16, 0x44, 0x3B, 0x92, 0x92, 0x5C, 0xCA, 0xB8, 0x5D, 0x84, 0x92, 0x42, + 0x13, 0x2A, 0xBC, 0x65, 0x57, 0x82, 0x40, 0x3E, 0x57, 0x24, 0xCD, 0x50, + 0x8B, 0x25, 0x2A, 0xB7, 0x6F, 0xFC, 0xEF, 0xA2, 0xD0, 0xC0, 0x1F, 0x02, + 0x24, 0x4A, 0x13, 0x96, 0x8F, 0x23, 0x13, 0xE6, 0x28, 0x58, 0x00, 0xA3, + 0x47, 0xC7, 0x06, 0xA7, 0x84, 0x23, 0x2B, 0xBB, 0xBD, 0x96, 0x2B, 0x7F, + 0x55, 0xCC, 0x8B, 0xC1, 0x57, 0x1F, 0x0E, 0x62, 0x65, 0x0F, 0xDD, 0x3D, + 0x56, 0x8A, 0x73, 0xDA, 0xAE, 0x7E, 0x6D, 0xBA, 0x81, 0x1C, 0x7E, 0x42, + 0x8C, 0x20, 0x35, 0xD9, 0x43, 0x4D, 0x84, 0xFA, 0x84, 0xDB, 0x52, 0x2C, + 0xF3, 0x0E, 0x27, 0x77, 0x0B, 0x6B, 0xBF, 0x11, 0x2F, 0x72, 0x78, 0x9F, + 0x2E, 0xD8, 0x3E, 0xE6, 0x18, 0x37, 0x5A, 0x2A, 0x72, 0xF9, 0xDA, 0x62, + 0x90, 0x92, 0x95, 0xCA, 0x1F, 0x9C, 0xE9, 0xB3, 0x3C, 0x2B, 0xCB, 0xF3, + 0x01, 0x13, 0xBF, 0x5A, 0xCF, 0xC1, 0xB5, 0x0A, 0x60, 0xBD, 0xDD, 0xB5, + 0x99, 0x64, 0x53, 0xB8, 0xA0, 0x96, 0xB3, 0x6F, 0xE2, 0x26, 0x77, 0x91, + 0x8C, 0xE0, 0x62, 0x10, 0x02, 0x9F, 0x34, 0x0F, 0xA4, 0xD5, 0x92, 0x33, + 0x51, 0xDE, 0xBE, 0x8D, 0xBA, 0x84, 0x7A, 0x60, 0x3C, 0x6A, 0xDB, 0x9F, + 0x2B, 0xEC, 0xDE, 0xDE, 0x01, 0x3F, 0x6E, 0x4D, 0xE5, 0x50, 0x86, 0xCB, + 0xB4, 0xAF, 0xED, 0x44, 0x40, 0xC5, 0xCA, 0x5A, 0x8C, 0xDA, 0xD2, 0x2B, + 0x7C, 0xA8, 0xEE, 0xBE, 0xA6, 0xE5, 0x0A, 0xAA, 0x0E, 0xA5, 0xDF, 0x05, + 0x52, 0xB7, 0x55, 0xC7, 0x22, 0x5D, 0x32, 0x6A, 0x97, 0x97, 0x63, 0x13, + 0xDB, 0xC9, 0xDB, 0x79, 0x36, 0x7B, 0x85, 0x3A, 0x4A, 0xC5, 0x52, 0x89, + 0xF9, 0x24, 0xE7, 0x9D, 0x77, 0xA9, 0x82, 0xFF, 0x55, 0x1C, 0xA5, 0x71, + 0x69, 0x2B, 0xD1, 0x02, 0x24, 0xF2, 0xB3, 0x26, 0xD4, 0x6B, 0xDA, 0x04, + 0x55, 0xE5, 0xC1, 0x0A, 0xC7, 0x6D, 0x30, 0x37, 0x90, 0x2A, 0xE4, 0x9E, + 0x14, 0x33, 0x5E, 0x16, 0x17, 0x55, 0xC5, 0x5B, 0xB5, 0xCB, 0x34, 0x89, + 0x92, 0xF1, 0x9D, 0x26, 0x8F, 0xA1, 0x07, 0xD4, 0xC6, 0xB2, 0x78, 0x50, + 0xDB, 0x0C, 0x0C, 0x0B, 0x7C, 0x0B, 0x8C, 0x41, 0xD7, 0xB9, 0xE9, 0xDD, + 0x8C, 0x88, 0xF7, 0xA3, 0x4D, 0xB2, 0x32, 0xCC, 0xD8, 0x17, 0xDA, 0xCD, + 0xB7, 0xCE, 0x66, 0x9D, 0xD4, 0xFD, 0x5E, 0xFF, 0xBD, 0x97, 0x3E, 0x29, + 0x75, 0xE7, 0x7E, 0xA7, 0x62, 0x58, 0xAF, 0x25, 0x34, 0xA5, 0x41, 0xC7, + 0x3D, 0xBC, 0x0D, 0x50, 0xCA, 0x03, 0x03, 0x0F, 0x08, 0x5A, 0x1F, 0x95, + 0x73, 0x78, 0x62, 0xBF, 0xAF, 0x72, 0x14, 0x69, 0x0E, 0xA5, 0xE5, 0x03, + 0x0E, 0x78, 0x8E, 0x26, 0x28, 0x42, 0xF0, 0x07, 0x0B, 0x62, 0x20, 0x10, + 0x67, 0x39, 0x46, 0xFA, 0xA9, 0x03, 0xCC, 0x04, 0x38, 0x7A, 0x66, 0xEF, + 0x20, 0x83, 0xB5, 0x8C, 0x4A, 0x56, 0x8E, 0x91, 0x00, 0xFC, 0x8E, 0x5C, + 0x82, 0xDE, 0x88, 0xA0, 0xC3, 0xE2, 0x68, 0x6E, 0x7D, 0x8D, 0xEF, 0x3C, + 0xDD, 0x65, 0xF4, 0x5D, 0xAC, 0x51, 0xEF, 0x24, 0x80, 0xAE, 0xAA, 0x56, + 0x97, 0x6F, 0xF9, 0xAD, 0x7D, 0xDA, 0x61, 0x3F, 0x98, 0x77, 0x3C, 0xA5, + 0x91, 0xB6, 0x1C, 0x8C, 0x26, 0xDA, 0x65, 0xA2, 0x09, 0x6D, 0xC1, 0xE2, + 0x54, 0xE3, 0xB9, 0xCA, 0x4C, 0x4C, 0x80, 0x8F, 0x77, 0x7B, 0x60, 0x9A, + 0x1E, 0xDF, 0xB6, 0xF2, 0x48, 0x1E, 0x0E, 0xBA, 0x4E, 0x54, 0x6D, 0x98, + 0xE0, 0xE1, 0xA2, 0x1A, 0xA2, 0x77, 0x50, 0xCF, 0xC4, 0x63, 0x92, 0xEC, + 0x47, 0x19, 0x9D, 0xEB, 0xE6, 0x6B, 0xCE, 0xC1 +}; + +static const unsigned char TA511_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA512_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x32 +}; + +static const unsigned char TA512_RSA_N[] = { + 0xAA, 0x5F, 0xDA, 0x1B, 0x5F, 0xE8, 0x73, 0x91, 0xE5, 0xDA, 0x5C, 0xF4, + 0xA2, 0xE6, 0x47, 0xE5, 0xF3, 0x68, 0x55, 0x60, 0x05, 0x1D, 0x02, 0xA4, + 0xB3, 0x9B, 0x59, 0xF3, 0x1E, 0x8A, 0xAF, 0x34, 0xAD, 0xFC, 0x0D, 0xC2, + 0xD9, 0x48, 0x19, 0xEE, 0x69, 0x8F, 0xC9, 0x20, 0xFC, 0x21, 0xAA, 0x07, + 0x19, 0xED, 0xB0, 0x5C, 0xAC, 0x65, 0xC7, 0x5F, 0xED, 0x02, 0x7C, 0x7B, + 0x7C, 0x2D, 0x1B, 0xD6, 0xBA, 0xB9, 0x80, 0xC2, 0x18, 0x82, 0x16, 0x84, + 0xFA, 0x66, 0xB0, 0x08, 0xC6, 0x54, 0x23, 0x81, 0xE4, 0xCD, 0xB9, 0x49, + 0x3F, 0xF6, 0x4F, 0x6E, 0x37, 0x48, 0x28, 0x38, 0x0F, 0xC5, 0xBE, 0xE7, + 0x68, 0x70, 0xFD, 0x39, 0x97, 0x4D, 0xD2, 0xC7, 0x98, 0x91, 0x50, 0xAA, + 0xC4, 0x44, 0xB3, 0x23, 0x7D, 0x39, 0x47, 0xE9, 0x52, 0x62, 0xD6, 0x12, + 0x93, 0x5E, 0xB7, 0x31, 0x96, 0x42, 0x05, 0xFB, 0x76, 0xA7, 0x1E, 0xA3, + 0xF5, 0xC2, 0xFC, 0xE9, 0x7A, 0xC5, 0x6C, 0xA9, 0x71, 0x4F, 0xEA, 0xCB, + 0x78, 0xBC, 0x60, 0xAF, 0xC7, 0xDE, 0xF4, 0xD9, 0xCB, 0xBE, 0x7E, 0x33, + 0xA5, 0x6E, 0x94, 0x83, 0xF0, 0x34, 0xFA, 0x21, 0xAB, 0xEA, 0x8E, 0x72, + 0xA0, 0x3F, 0xA4, 0xDE, 0x30, 0x5B, 0xEF, 0x86, 0x4D, 0x6A, 0x95, 0x5B, + 0x43, 0x44, 0xA8, 0x10, 0x15, 0x1C, 0xE5, 0x01, 0x57, 0xC5, 0x98, 0xF1, + 0xE6, 0x06, 0x28, 0x91, 0xAA, 0x20, 0xC5, 0xB7, 0x53, 0x26, 0x51, 0x43, + 0xB2, 0x0B, 0x11, 0x95, 0x58, 0xE1, 0xC0, 0x0F, 0x76, 0xD9, 0xC0, 0x8D, + 0x7C, 0x81, 0xF3, 0x72, 0x70, 0x9E, 0x6F, 0xFE, 0x1A, 0x8E, 0xD9, 0x5F, + 0x35, 0xC6, 0xB2, 0x6F, 0x34, 0x7C, 0xBE, 0x48, 0x4F, 0xE2, 0x5A, 0x39, + 0xD7, 0xD8, 0x9D, 0x78, 0x9E, 0x9F, 0x86, 0x3E, 0x03, 0x5E, 0x19, 0x8B, + 0x44, 0xA2, 0xD5, 0xC7 +}; + +static const unsigned char TA512_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA513_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x33 +}; + +static const unsigned char TA513_RSA_N[] = { + 0xBD, 0x75, 0x93, 0xF0, 0x62, 0x22, 0x6F, 0x24, 0xAE, 0xE0, 0x7A, 0x76, + 0xAC, 0x7D, 0xBD, 0xD9, 0x24, 0xD5, 0xB8, 0xB7, 0xFC, 0xCD, 0xF0, 0x42, + 0xE0, 0xEB, 0x78, 0x88, 0x56, 0x5E, 0x9B, 0x9A, 0x54, 0x1D, 0x4D, 0x0C, + 0x8A, 0xF6, 0xD3, 0xCF, 0x70, 0xF4, 0x52, 0xB5, 0xD8, 0x93, 0x04, 0xE3, + 0x46, 0x86, 0x71, 0x41, 0x4A, 0x2B, 0xF0, 0x2A, 0x2C, 0x55, 0x03, 0xD6, + 0x48, 0xC3, 0xE0, 0x39, 0x38, 0xED, 0xF2, 0x5C, 0x3C, 0x3F, 0x44, 0xBC, + 0x93, 0x3D, 0x61, 0xAB, 0x4E, 0xCD, 0x0D, 0xBE, 0xF0, 0x20, 0x27, 0x58, + 0x0E, 0x44, 0x7F, 0x04, 0x1A, 0x87, 0xA5, 0xD7, 0x96, 0x14, 0x36, 0x90, + 0xD0, 0x49, 0x7B, 0xA1, 0x75, 0xFB, 0x1A, 0x6B, 0x73, 0xB1, 0xF8, 0xCE, + 0xA9, 0x09, 0x2C, 0xF2, 0x53, 0xD5, 0xC3, 0x14, 0x44, 0xB8, 0x86, 0xA5, + 0xF6, 0x8B, 0x2B, 0x39, 0xDA, 0xA3, 0x33, 0x54, 0xD9, 0xFA, 0x72, 0x1A, + 0xF7, 0x22, 0x15, 0x1C, 0x88, 0x91, 0x6B, 0x7F, 0x66, 0xE5, 0xC3, 0x6A, + 0x80, 0xB0, 0x24, 0xF3, 0xDF, 0x86, 0x45, 0x88, 0xFD, 0x19, 0x7F, 0x75, + 0x87, 0x1F, 0x1F, 0xB1, 0x1B, 0x0A, 0x73, 0x24, 0x5B, 0xB9, 0x65, 0xE0, + 0x2C, 0x54, 0xC8, 0x60, 0xD3, 0x66, 0x17, 0x3F, 0xE1, 0xCC, 0x54, 0x33, + 0x73, 0x91, 0x02, 0x3A, 0xA6, 0x7F, 0x7B, 0x76, 0x39, 0xA2, 0x1F, 0x96, + 0xB6, 0x38, 0xAE, 0xB5, 0xC8, 0x93, 0x74, 0x1D, 0x9E, 0xB9, 0xB4, 0xE5, + 0x60, 0x9D, 0x2F, 0x56, 0xD1, 0xE0, 0xEB, 0x5E, 0x5B, 0x4C, 0x12, 0x70, + 0x0C, 0x6C, 0x44, 0x20, 0xAB, 0x11, 0xD8, 0xF4, 0x19, 0xF6, 0xD2, 0x9C, + 0x52, 0x37, 0xE7, 0xFA, 0xB6, 0xC2, 0x31, 0x3B, 0x4A, 0xD4, 0x14, 0x99, + 0xAD, 0xC7, 0x1A, 0xF5, 0x5D, 0x5F, 0xFA, 0x07, 0xB8, 0x7C, 0x0D, 0x1F, + 0xD6, 0x83, 0x1E, 0xB3 +}; + +static const unsigned char TA513_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA514_DN[] = { + 0x30, 0x81, 0xD2, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x54, 0x52, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x0F, 0x47, 0x65, 0x62, 0x7A, 0x65, 0x20, 0x2D, 0x20, 0x4B, + 0x6F, 0x63, 0x61, 0x65, 0x6C, 0x69, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x13, 0x39, 0x54, 0x75, 0x72, 0x6B, 0x69, 0x79, 0x65, + 0x20, 0x42, 0x69, 0x6C, 0x69, 0x6D, 0x73, 0x65, 0x6C, 0x20, 0x76, 0x65, + 0x20, 0x54, 0x65, 0x6B, 0x6E, 0x6F, 0x6C, 0x6F, 0x6A, 0x69, 0x6B, 0x20, + 0x41, 0x72, 0x61, 0x73, 0x74, 0x69, 0x72, 0x6D, 0x61, 0x20, 0x4B, 0x75, + 0x72, 0x75, 0x6D, 0x75, 0x20, 0x2D, 0x20, 0x54, 0x55, 0x42, 0x49, 0x54, + 0x41, 0x4B, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x24, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x6B, 0x61, 0x73, 0x79, 0x6F, 0x6E, 0x20, 0x4D, 0x65, 0x72, 0x6B, + 0x65, 0x7A, 0x69, 0x20, 0x2D, 0x20, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, + 0x4D, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, + 0x54, 0x55, 0x42, 0x49, 0x54, 0x41, 0x4B, 0x20, 0x4B, 0x61, 0x6D, 0x75, + 0x20, 0x53, 0x4D, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x4B, 0x6F, 0x6B, 0x20, + 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6B, 0x61, 0x73, 0x69, 0x20, + 0x2D, 0x20, 0x53, 0x75, 0x72, 0x75, 0x6D, 0x20, 0x31 +}; + +static const unsigned char TA514_RSA_N[] = { + 0xAF, 0x75, 0x30, 0x33, 0xAA, 0xBB, 0x6B, 0xD3, 0x99, 0x2C, 0x12, 0x37, + 0x84, 0xD9, 0x8D, 0x7B, 0x97, 0x80, 0xD3, 0x6E, 0xE7, 0xFF, 0x9B, 0x50, + 0x95, 0x3E, 0x90, 0x95, 0x56, 0x42, 0xD7, 0x19, 0x7C, 0x26, 0x84, 0x8D, + 0x92, 0xFA, 0x01, 0x1D, 0x3A, 0x0F, 0xE2, 0x64, 0x38, 0xB7, 0x8C, 0xBC, + 0xE8, 0x88, 0xF9, 0x8B, 0x24, 0xAB, 0x2E, 0xA3, 0xF5, 0x37, 0xE4, 0x40, + 0x8E, 0x18, 0x25, 0x79, 0x83, 0x75, 0x1F, 0x3B, 0xFF, 0x6C, 0xA8, 0xC5, + 0xC6, 0x56, 0xF8, 0xB4, 0xED, 0x8A, 0x44, 0xA3, 0xAB, 0x6C, 0x4C, 0xFC, + 0x1D, 0xD0, 0xDC, 0xEF, 0x68, 0xBD, 0xCF, 0xE4, 0xAA, 0xCE, 0xF0, 0x55, + 0xF7, 0xA2, 0x34, 0xD4, 0x83, 0x6B, 0x37, 0x7C, 0x1C, 0xC2, 0xFE, 0xB5, + 0x03, 0xEC, 0x57, 0xCE, 0xBC, 0xB4, 0xB5, 0xC5, 0xED, 0x00, 0x0F, 0x53, + 0x37, 0x2A, 0x4D, 0xF4, 0x4F, 0x0C, 0x83, 0xFB, 0x86, 0xCF, 0xCB, 0xFE, + 0x8C, 0x4E, 0xBD, 0x87, 0xF9, 0xA7, 0x8B, 0x21, 0x57, 0x9C, 0x7A, 0xDF, + 0x03, 0x67, 0x89, 0x2C, 0x9D, 0x97, 0x61, 0xA7, 0x10, 0xB8, 0x55, 0x90, + 0x7F, 0x0E, 0x2D, 0x27, 0x38, 0x74, 0xDF, 0xE7, 0xFD, 0xDA, 0x4E, 0x12, + 0xE3, 0x4D, 0x15, 0x22, 0x02, 0xC8, 0xE0, 0xE0, 0xFC, 0x0F, 0xAD, 0x8A, + 0xD7, 0xC9, 0x54, 0x50, 0xCC, 0x3B, 0x0F, 0xCA, 0x16, 0x80, 0x84, 0xD0, + 0x51, 0x56, 0xC3, 0x8E, 0x56, 0x7F, 0x89, 0x22, 0x33, 0x2F, 0xE6, 0x85, + 0x0A, 0xBD, 0xA5, 0xA8, 0x1B, 0x36, 0xDE, 0xD3, 0xDC, 0x2C, 0x6D, 0x3B, + 0xC7, 0x13, 0xBD, 0x59, 0x23, 0x2C, 0xE6, 0xE5, 0xA4, 0xF7, 0xD8, 0x0B, + 0xED, 0xEA, 0x90, 0x40, 0x44, 0xA8, 0x95, 0xBB, 0x93, 0xD5, 0xD0, 0x80, + 0x34, 0xB6, 0x46, 0x78, 0x0E, 0x1F, 0x00, 0x93, 0x46, 0xE1, 0xEE, 0xE9, + 0xF9, 0xEC, 0x4F, 0x17 +}; + +static const unsigned char TA514_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA515_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x54, 0x57, 0x43, 0x41, 0x20, 0x43, 0x59, 0x42, + 0x45, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA515_RSA_N[] = { + 0xC6, 0xF8, 0xCA, 0x1E, 0xD9, 0x09, 0x20, 0x7E, 0x1D, 0x6C, 0x4E, 0xCE, + 0x8F, 0xE3, 0x47, 0x33, 0x44, 0x9C, 0xC7, 0xC9, 0x69, 0xAA, 0x3A, 0x5B, + 0x78, 0xEE, 0x70, 0xD2, 0x92, 0xF8, 0x04, 0xB3, 0x52, 0x52, 0x1D, 0x67, + 0x72, 0x28, 0xA1, 0xDF, 0x8B, 0x5D, 0x95, 0x0A, 0xFE, 0xEA, 0xCD, 0xED, + 0xF7, 0x29, 0xCE, 0xF0, 0x6F, 0x7F, 0xAC, 0xCD, 0x3D, 0xEF, 0xB3, 0x1C, + 0x45, 0x6A, 0xF7, 0x28, 0x90, 0xF1, 0x61, 0x57, 0xC5, 0x0C, 0xC4, 0xA3, + 0x50, 0x5D, 0xDE, 0xD4, 0xB5, 0xCB, 0x19, 0xCA, 0x80, 0xB9, 0x75, 0xCE, + 0x29, 0xCE, 0xD2, 0x85, 0x22, 0xEC, 0x02, 0x63, 0xCC, 0x44, 0x30, 0x20, + 0xDA, 0xEA, 0x91, 0x5B, 0x56, 0xE6, 0x1D, 0x1C, 0xD5, 0x9D, 0x66, 0xC7, + 0x3F, 0xDF, 0x86, 0xCA, 0x4B, 0x53, 0xC4, 0xD9, 0x8D, 0xB2, 0x1D, 0xEA, + 0xF8, 0xDC, 0x27, 0x53, 0xA3, 0x47, 0xE1, 0x61, 0xCC, 0x7D, 0xB5, 0xB0, + 0xF8, 0xEE, 0x73, 0x91, 0xC5, 0xCE, 0x73, 0x6F, 0xCE, 0xEE, 0x10, 0x1F, + 0x1A, 0x06, 0xCF, 0xE9, 0x27, 0x60, 0xC5, 0x4F, 0x19, 0xE4, 0xEB, 0xCE, + 0x22, 0x26, 0x45, 0xD7, 0x60, 0x99, 0xDD, 0xCE, 0x4F, 0x37, 0xE0, 0x7F, + 0xE7, 0x63, 0xAD, 0xB0, 0xB8, 0x59, 0xB8, 0xD0, 0x06, 0x68, 0x35, 0x60, + 0xD3, 0x36, 0xAE, 0x71, 0x43, 0x04, 0xF1, 0x69, 0x65, 0x78, 0x7C, 0xF3, + 0x1F, 0xF3, 0xCA, 0x28, 0x9F, 0x5A, 0x20, 0x95, 0x66, 0xB4, 0xCD, 0xB7, + 0xEE, 0x8F, 0x78, 0xA4, 0x45, 0x18, 0xE9, 0x26, 0x2F, 0x8D, 0x9B, 0x29, + 0x28, 0xB1, 0xA4, 0xB7, 0x3A, 0x6D, 0xB9, 0xD4, 0x1C, 0x38, 0x72, 0x45, + 0x58, 0xB1, 0x5E, 0xEB, 0xF0, 0x28, 0x9B, 0xB7, 0x82, 0xCA, 0xFD, 0xCF, + 0xD6, 0x33, 0x0F, 0x9F, 0xFB, 0x97, 0x9E, 0xB1, 0x1C, 0x9C, 0x9E, 0xEA, + 0x5F, 0x5E, 0xDB, 0xAA, 0xDD, 0x54, 0xE9, 0x30, 0x21, 0x28, 0x6D, 0x8E, + 0x79, 0xF3, 0x75, 0x92, 0x8C, 0x26, 0xFE, 0xDC, 0xC5, 0xF6, 0xC3, 0xB0, + 0xDF, 0x44, 0x59, 0x43, 0xA3, 0xB6, 0x03, 0x28, 0xF6, 0x08, 0x30, 0xAA, + 0x0D, 0x33, 0xE1, 0xEF, 0x9C, 0xA9, 0x07, 0x22, 0xE3, 0x59, 0x5B, 0x40, + 0x8F, 0xDA, 0x88, 0xB7, 0x69, 0x08, 0xA8, 0xB7, 0x23, 0x2E, 0x44, 0x09, + 0x59, 0x37, 0x5B, 0xC7, 0xE3, 0x17, 0xF2, 0x22, 0xEB, 0x6E, 0x39, 0x52, + 0xC5, 0xDE, 0x54, 0xA7, 0x98, 0xC9, 0x4B, 0x20, 0x95, 0xDC, 0x46, 0x89, + 0x5F, 0xB4, 0x12, 0xF9, 0x85, 0x29, 0x8E, 0xEB, 0xC8, 0x27, 0x15, 0x20, + 0xC0, 0x4B, 0xD4, 0xCC, 0x7C, 0x0C, 0x6C, 0x34, 0x0C, 0x26, 0x9B, 0x26, + 0x31, 0xA6, 0x3C, 0xA7, 0xF6, 0xD9, 0xD0, 0x4B, 0xA2, 0x64, 0xFF, 0x3B, + 0x99, 0x41, 0x72, 0xC1, 0xE0, 0x70, 0x97, 0xF1, 0x24, 0xBB, 0x2B, 0xC4, + 0x74, 0x22, 0xB1, 0xAC, 0x6B, 0x22, 0x32, 0x24, 0xD3, 0x78, 0x2A, 0xC0, + 0xC0, 0xA1, 0x2F, 0xF1, 0x52, 0x05, 0xC9, 0x3F, 0xEF, 0x76, 0x66, 0xE2, + 0x45, 0xD8, 0x0D, 0x3D, 0xAD, 0x95, 0xC8, 0xC7, 0x89, 0x26, 0xC8, 0x0F, + 0xAE, 0xA7, 0x03, 0x2E, 0xFB, 0xC1, 0x5F, 0xFA, 0x20, 0xE1, 0x70, 0xAD, + 0xB0, 0x65, 0x20, 0x37, 0x33, 0x60, 0xB0, 0xD5, 0xAF, 0xD7, 0x0C, 0x1C, + 0xC2, 0x90, 0x70, 0xD7, 0x4A, 0x18, 0xBC, 0x7E, 0x01, 0xB0, 0xB0, 0xEB, + 0x15, 0x1E, 0x44, 0x06, 0xCD, 0xA4, 0x4F, 0xE8, 0x0C, 0xD1, 0xC3, 0x20, + 0x10, 0xE1, 0x54, 0x65, 0x9E, 0xB6, 0x51, 0xD0, 0x1A, 0x76, 0x6B, 0x42, + 0x5A, 0x58, 0x76, 0x34, 0xEA, 0xB7, 0x37, 0x19, 0xAE, 0x2E, 0x75, 0xF9, + 0x96, 0xE5, 0xC1, 0x59, 0xF7, 0x94, 0x57, 0x29, 0x25, 0x8D, 0x3A, 0x4C, + 0xAB, 0x4D, 0x9A, 0x41, 0xD0, 0x5F, 0x26, 0x03 +}; + +static const unsigned char TA515_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA516_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x13, 0x54, 0x57, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, + 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA516_RSA_N[] = { + 0xB0, 0x05, 0xDB, 0xC8, 0xEB, 0x8C, 0xC4, 0x6E, 0x8A, 0x21, 0xEF, 0x8E, + 0x4D, 0x9C, 0x71, 0x0A, 0x1F, 0x52, 0x70, 0xED, 0x6D, 0x82, 0x9C, 0x97, + 0xC5, 0xD7, 0x4C, 0x4E, 0x45, 0x49, 0xCB, 0x40, 0x42, 0xB5, 0x12, 0x34, + 0x6C, 0x19, 0xC2, 0x74, 0xA4, 0x31, 0x5F, 0x85, 0x02, 0x97, 0xEC, 0x43, + 0x33, 0x0A, 0x53, 0xD2, 0x9C, 0x8C, 0x8E, 0xB7, 0xB8, 0x79, 0xDB, 0x2B, + 0xD5, 0x6A, 0xF2, 0x8E, 0x66, 0xC4, 0xEE, 0x2B, 0x01, 0x07, 0x92, 0xD4, + 0xB3, 0xD0, 0x02, 0xDF, 0x50, 0xF6, 0x55, 0xAF, 0x66, 0x0E, 0xCB, 0xE0, + 0x47, 0x60, 0x2F, 0x2B, 0x32, 0x39, 0x35, 0x52, 0x3A, 0x28, 0x83, 0xF8, + 0x7B, 0x16, 0xC6, 0x18, 0xB8, 0x62, 0xD6, 0x47, 0x25, 0x91, 0xCE, 0xF0, + 0x19, 0x12, 0x4D, 0xAD, 0x63, 0xF5, 0xD3, 0x3F, 0x75, 0x5F, 0x29, 0xF0, + 0xA1, 0x30, 0x1C, 0x2A, 0xA0, 0x98, 0xA6, 0x15, 0xBD, 0xEE, 0xFD, 0x19, + 0x36, 0xF0, 0xE2, 0x91, 0x43, 0x8F, 0xFA, 0xCA, 0xD6, 0x10, 0x27, 0x49, + 0x4C, 0xEF, 0xDD, 0xC1, 0xF1, 0x85, 0x70, 0x9B, 0xCA, 0xEA, 0xA8, 0x5A, + 0x43, 0xFC, 0x6D, 0x86, 0x6F, 0x73, 0xE9, 0x37, 0x45, 0xA9, 0xF0, 0x36, + 0xC7, 0xCC, 0x88, 0x75, 0x1E, 0xBB, 0x6C, 0x06, 0xFF, 0x9B, 0x6B, 0x3E, + 0x17, 0xEC, 0x61, 0xAA, 0x71, 0x7C, 0xC6, 0x1D, 0xA2, 0xF7, 0x49, 0xE9, + 0x15, 0xB5, 0x3C, 0xD6, 0xA1, 0x61, 0xF5, 0x11, 0xF7, 0x05, 0x6F, 0x1D, + 0xFD, 0x11, 0xBE, 0xD0, 0x30, 0x07, 0xC2, 0x29, 0xB0, 0x09, 0x4E, 0x26, + 0xDC, 0xE3, 0xA2, 0xA8, 0x91, 0x6A, 0x1F, 0xC2, 0x91, 0x45, 0x88, 0x5C, + 0xE5, 0x98, 0xB8, 0x71, 0xA5, 0x15, 0x19, 0xC9, 0x7C, 0x75, 0x11, 0xCC, + 0x70, 0x74, 0x4F, 0x2D, 0x9B, 0x1D, 0x91, 0x44, 0xFD, 0x56, 0x28, 0xA0, + 0xFE, 0xBB, 0x86, 0x6A, 0xC8, 0xFA, 0x5C, 0x0B, 0x58, 0xDC, 0xC6, 0x4B, + 0x76, 0xC8, 0xAB, 0x22, 0xD9, 0x73, 0x0F, 0xA5, 0xF4, 0x5A, 0x02, 0x89, + 0x3F, 0x4F, 0x9E, 0x22, 0x82, 0xEE, 0xA2, 0x74, 0x53, 0x2A, 0x3D, 0x53, + 0x27, 0x69, 0x1D, 0x6C, 0x8E, 0x32, 0x2C, 0x64, 0x00, 0x26, 0x63, 0x61, + 0x36, 0x4E, 0xA3, 0x46, 0xB7, 0x3F, 0x7D, 0xB3, 0x2D, 0xAC, 0x6D, 0x90, + 0xA2, 0x95, 0xA2, 0xCE, 0xCF, 0xDA, 0x82, 0xE7, 0x07, 0x34, 0x19, 0x96, + 0xE9, 0xB8, 0x21, 0xAA, 0x29, 0x7E, 0xA6, 0x38, 0xBE, 0x8E, 0x29, 0x4A, + 0x21, 0x66, 0x79, 0x1F, 0xB3, 0xC3, 0xB5, 0x09, 0x67, 0xDE, 0xD6, 0xD4, + 0x07, 0x46, 0xF3, 0x2A, 0xDA, 0xE6, 0x22, 0x37, 0x60, 0xCB, 0x81, 0xB6, + 0x0F, 0xA0, 0x0F, 0xE9, 0xC8, 0x95, 0x7F, 0xBF, 0x55, 0x91, 0x05, 0x7A, + 0xCF, 0x3D, 0x15, 0xC0, 0x6F, 0xDE, 0x09, 0x94, 0x01, 0x83, 0xD7, 0x34, + 0x1B, 0xCC, 0x40, 0xA5, 0xF0, 0xB8, 0x9B, 0x67, 0xD5, 0x98, 0x91, 0x3B, + 0xA7, 0x84, 0x78, 0x95, 0x26, 0xA4, 0x5A, 0x08, 0xF8, 0x2B, 0x74, 0xB4, + 0x00, 0x04, 0x3C, 0xDF, 0xB8, 0x14, 0x8E, 0xE8, 0xDF, 0xA9, 0x8D, 0x6C, + 0x67, 0x92, 0x33, 0x1D, 0xC0, 0xB7, 0xD2, 0xEC, 0x92, 0xC8, 0xBE, 0x09, + 0xBF, 0x2C, 0x29, 0x05, 0x6F, 0x02, 0x6B, 0x9E, 0xEF, 0xBC, 0xBF, 0x2A, + 0xBC, 0x5B, 0xC0, 0x50, 0x8F, 0x41, 0x70, 0x71, 0x87, 0xB2, 0x4D, 0xB7, + 0x04, 0xA9, 0x84, 0xA3, 0x32, 0xAF, 0xAE, 0xEE, 0x6B, 0x17, 0x8B, 0xB2, + 0xB1, 0xFE, 0x6C, 0xE1, 0x90, 0x8C, 0x88, 0xA8, 0x97, 0x48, 0xCE, 0xC8, + 0x4D, 0xCB, 0xF3, 0x06, 0xCF, 0x5F, 0x6A, 0x0A, 0x42, 0xB1, 0x1E, 0x1E, + 0x77, 0x2F, 0x8E, 0xA0, 0xE6, 0x92, 0x0E, 0x06, 0xFC, 0x05, 0x22, 0xD2, + 0x26, 0xE1, 0x31, 0x51, 0x7D, 0x32, 0xDC, 0x0F +}; + +static const unsigned char TA516_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA517_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x21, 0x54, 0x57, 0x43, 0x41, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA517_RSA_N[] = { + 0xB0, 0x7E, 0x72, 0xB8, 0xA4, 0x03, 0x94, 0xE6, 0xA7, 0xDE, 0x09, 0x38, + 0x91, 0x4A, 0x11, 0x40, 0x87, 0xA7, 0x7C, 0x59, 0x64, 0x14, 0x7B, 0xB5, + 0x11, 0x10, 0xDD, 0xFE, 0xBF, 0xD5, 0xC0, 0xBB, 0x56, 0xE2, 0x85, 0x25, + 0xF4, 0x35, 0x72, 0x0F, 0xF8, 0x53, 0xD0, 0x41, 0xE1, 0x44, 0x01, 0xC2, + 0xB4, 0x1C, 0xC3, 0x31, 0x42, 0x16, 0x47, 0x85, 0x33, 0x22, 0x76, 0xB2, + 0x0A, 0x6F, 0x0F, 0xE5, 0x25, 0x50, 0x4F, 0x85, 0x86, 0xBE, 0xBF, 0x98, + 0x2E, 0x10, 0x67, 0x1E, 0xBE, 0x11, 0x05, 0x86, 0x05, 0x90, 0xC4, 0x59, + 0xD0, 0x7C, 0x78, 0x10, 0xB0, 0x80, 0x5C, 0xB7, 0xE1, 0xC7, 0x2B, 0x75, + 0xCB, 0x7C, 0x9F, 0xAE, 0xB5, 0xD1, 0x9D, 0x23, 0x37, 0x63, 0xA7, 0xDC, + 0x42, 0xA2, 0x2D, 0x92, 0x04, 0x1B, 0x50, 0xC1, 0x7B, 0xB8, 0x3E, 0x1B, + 0xC9, 0x56, 0x04, 0x8B, 0x2F, 0x52, 0x9B, 0xAD, 0xA9, 0x56, 0xE9, 0xC1, + 0xFF, 0xAD, 0xA9, 0x58, 0x87, 0x30, 0xB6, 0x81, 0xF7, 0x97, 0x45, 0xFC, + 0x19, 0x57, 0x3B, 0x2B, 0x6F, 0xE4, 0x47, 0xF4, 0x99, 0x45, 0xFE, 0x1D, + 0xF1, 0xF8, 0x97, 0xA3, 0x88, 0x1D, 0x37, 0x1C, 0x5C, 0x8F, 0xE0, 0x76, + 0x25, 0x9A, 0x50, 0xF8, 0xA0, 0x54, 0xFF, 0x44, 0x90, 0x76, 0x23, 0xD2, + 0x32, 0xC6, 0xC3, 0xAB, 0x06, 0xBF, 0xFC, 0xFB, 0xBF, 0xF3, 0xAD, 0x7D, + 0x92, 0x62, 0x02, 0x5B, 0x29, 0xD3, 0x35, 0xA3, 0x93, 0x9A, 0x43, 0x64, + 0x60, 0x5D, 0xB2, 0xFA, 0x32, 0xFF, 0x3B, 0x04, 0xAF, 0x4D, 0x40, 0x6A, + 0xF9, 0xC7, 0xE3, 0xEF, 0x23, 0xFD, 0x6B, 0xCB, 0xE5, 0x0F, 0x8B, 0x38, + 0x0D, 0xEE, 0x0A, 0xFC, 0xFE, 0x0F, 0x98, 0x9F, 0x30, 0x31, 0xDD, 0x6C, + 0x52, 0x65, 0xF9, 0x8B, 0x81, 0xBE, 0x22, 0xE1, 0x1C, 0x58, 0x03, 0xBA, + 0x91, 0x1B, 0x89, 0x07 +}; + +static const unsigned char TA517_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA518_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA518_EC_Q[] = { + 0x04, 0xCE, 0xBF, 0xFE, 0x57, 0xA8, 0xBF, 0xD5, 0xAA, 0xF7, 0x10, 0x9A, + 0xCD, 0xBC, 0xD1, 0x11, 0xA2, 0xBD, 0x67, 0x42, 0xCC, 0x90, 0xEB, 0x15, + 0x18, 0x90, 0xD9, 0xA2, 0xCD, 0x0C, 0x2A, 0x25, 0xEB, 0x3E, 0x4F, 0xCE, + 0xB5, 0xD2, 0x8F, 0x0F, 0xF3, 0x35, 0xDA, 0x43, 0x8B, 0x02, 0x80, 0xBE, + 0x6F, 0x51, 0x24, 0x1D, 0x0F, 0x6B, 0x2B, 0xCA, 0x9F, 0xC2, 0x6F, 0x50, + 0x32, 0xE5, 0x37, 0x20, 0xB6, 0x20, 0xFF, 0x88, 0x0D, 0x0F, 0x6D, 0x49, + 0xBB, 0xDB, 0x06, 0xA4, 0x87, 0x90, 0x92, 0x94, 0xF4, 0x09, 0xD0, 0xCF, + 0x7F, 0xC8, 0x80, 0x0B, 0xC1, 0x97, 0xB3, 0xBB, 0x35, 0x27, 0xC9, 0xC2, + 0x1B +}; + +static const unsigned char TA519_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x33 +}; + +static const unsigned char TA519_RSA_N[] = { + 0xED, 0x35, 0xA1, 0x81, 0x80, 0xF3, 0xCB, 0x4A, 0x69, 0x5B, 0xC2, 0xFB, + 0x51, 0x83, 0xAE, 0x26, 0xFD, 0xE1, 0x6E, 0xF3, 0x81, 0x12, 0x7D, 0x71, + 0x40, 0xFF, 0x87, 0x75, 0x42, 0x29, 0x21, 0xED, 0x81, 0x52, 0x2C, 0xDF, + 0x12, 0xC1, 0x19, 0x84, 0x89, 0xC1, 0xBD, 0xC5, 0x28, 0xD5, 0xD5, 0x4B, + 0x6C, 0x44, 0xD6, 0x4C, 0xDB, 0x07, 0x96, 0x4A, 0x55, 0x7A, 0xCA, 0x36, + 0x82, 0x04, 0x36, 0xA8, 0xA5, 0xFC, 0x27, 0xF6, 0x49, 0xF1, 0xD5, 0x72, + 0x9E, 0x91, 0xF9, 0x23, 0xD6, 0x70, 0x7B, 0xBB, 0xF5, 0x9B, 0xC1, 0xEC, + 0x93, 0xCF, 0x19, 0xEA, 0x65, 0x7E, 0x88, 0x70, 0xA0, 0x73, 0xFC, 0xF6, + 0xFF, 0xB5, 0x56, 0x62, 0xE1, 0x73, 0x6A, 0x34, 0x98, 0x3E, 0x82, 0xB8, + 0xAC, 0x95, 0x53, 0xF4, 0x01, 0xA0, 0x27, 0x07, 0x72, 0xA3, 0x00, 0x53, + 0xA0, 0xE4, 0xB2, 0xAB, 0x83, 0x38, 0x57, 0x33, 0x25, 0x94, 0x9F, 0xBE, + 0x48, 0x1D, 0x98, 0xE1, 0xA3, 0xBA, 0x9E, 0x5C, 0xCD, 0x04, 0x71, 0x51, + 0x7D, 0x75, 0x78, 0xAB, 0xF3, 0x59, 0xAA, 0xC4, 0xE0, 0x60, 0xBE, 0x8F, + 0x83, 0x52, 0xB8, 0x75, 0x1A, 0x41, 0x35, 0xED, 0xBC, 0xF3, 0x3A, 0x63, + 0xE9, 0xA9, 0x14, 0x45, 0xD7, 0xE6, 0x52, 0xD1, 0x6E, 0xD2, 0xDE, 0xBC, + 0xE3, 0xF5, 0x0B, 0x3B, 0xE6, 0xE0, 0xC4, 0xBD, 0x43, 0x64, 0x13, 0xA6, + 0xCE, 0xF4, 0x98, 0x37, 0x6C, 0x8A, 0x95, 0xA8, 0x97, 0xC8, 0x47, 0x0F, + 0xF0, 0x5E, 0x10, 0x8B, 0xE7, 0x1D, 0x1C, 0xFE, 0xB1, 0x3B, 0xA0, 0x05, + 0x33, 0x68, 0x05, 0x41, 0x82, 0xC1, 0x03, 0x2B, 0x01, 0xC8, 0xE7, 0x8F, + 0x4D, 0xAB, 0xE8, 0xB5, 0xF6, 0xCD, 0x6B, 0x44, 0xB5, 0xE7, 0xDD, 0x8B, + 0xEC, 0xEA, 0x25, 0xB4, 0x00, 0x22, 0x57, 0x4D, 0xB0, 0xB1, 0xB2, 0x31, + 0xC1, 0x16, 0xCE, 0xFF, 0xFD, 0x14, 0x84, 0xB7, 0x47, 0xFA, 0xB2, 0xF1, + 0x70, 0xDE, 0xDB, 0x8B, 0x6C, 0x36, 0x58, 0xA4, 0x7C, 0xB3, 0x11, 0xD1, + 0xC3, 0x77, 0x7F, 0x5F, 0xB6, 0x25, 0xE0, 0x0D, 0xC5, 0xD2, 0xB3, 0xF9, + 0xB8, 0xB8, 0x77, 0xDB, 0x37, 0x71, 0x71, 0x47, 0xE3, 0x60, 0x18, 0x4F, + 0x24, 0xB6, 0x75, 0x37, 0x78, 0xB9, 0xA3, 0x62, 0xAF, 0xBD, 0xC9, 0x72, + 0x8E, 0x2F, 0xCC, 0xBB, 0xAE, 0xDB, 0xE4, 0x15, 0x52, 0x19, 0x07, 0x33, + 0xFB, 0x6A, 0xB7, 0x2D, 0x4B, 0x90, 0x28, 0x82, 0x73, 0xFE, 0x18, 0x8B, + 0x35, 0x8D, 0xDB, 0xA7, 0x04, 0x6A, 0xBE, 0xEA, 0xC1, 0x4D, 0x36, 0x3B, + 0x16, 0x36, 0x91, 0x32, 0xEF, 0xB6, 0x40, 0x89, 0x91, 0x43, 0xE0, 0xF2, + 0xA2, 0xAB, 0x04, 0x2E, 0xE6, 0xF2, 0x4C, 0x0E, 0x16, 0x34, 0x20, 0xAC, + 0x87, 0xC1, 0x2D, 0x7E, 0xC9, 0x66, 0x47, 0x17, 0x14, 0x11, 0xA4, 0xF3, + 0xF7, 0xA1, 0x24, 0x89, 0xAB, 0xD8, 0x1A, 0xC8, 0xA1, 0x5C, 0xB1, 0xA3, + 0xF7, 0x8C, 0x6D, 0xC8, 0x01, 0xC9, 0x4F, 0xC9, 0xEC, 0xC4, 0xFC, 0xAC, + 0x51, 0x33, 0xD1, 0xC8, 0x83, 0xD1, 0xC9, 0x9F, 0x1D, 0xD4, 0x47, 0x34, + 0x29, 0x3E, 0xCB, 0xB0, 0x0E, 0xFA, 0x83, 0x0B, 0x28, 0x58, 0xE5, 0x29, + 0xDC, 0x3F, 0x7C, 0xA8, 0x9F, 0xC9, 0xB6, 0x0A, 0xBB, 0xA6, 0xE8, 0x46, + 0x16, 0x0F, 0x96, 0xE5, 0x7B, 0xE4, 0x6A, 0x7A, 0x48, 0x6D, 0x76, 0x98, + 0x05, 0xA5, 0xDC, 0x6D, 0x1E, 0x42, 0x1E, 0x42, 0xDA, 0x1A, 0xE0, 0x52, + 0xF7, 0xB5, 0x83, 0xC0, 0x1A, 0x7B, 0x78, 0x35, 0x2C, 0x38, 0xF5, 0x1F, + 0xFD, 0x49, 0xA3, 0x2E, 0xD2, 0x59, 0x63, 0xBF, 0x80, 0xB0, 0x8C, 0x93, + 0x73, 0xCB, 0x35, 0xA6, 0x99, 0x95, 0x22, 0x61, 0x65, 0x03, 0x60, 0xFB, + 0x2F, 0x93, 0x4B, 0xFA, 0x9A, 0x9C, 0x80, 0x3B +}; + +static const unsigned char TA519_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA520_DN[] = { + 0x30, 0x37, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0B, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x54, + 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, 0x20, 0x52, + 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x31 +}; + +static const unsigned char TA520_RSA_N[] = { + 0xC2, 0xBE, 0xEB, 0x27, 0xF0, 0x21, 0xA3, 0xF3, 0x69, 0x26, 0x55, 0x7E, + 0x9D, 0xC5, 0x55, 0x16, 0x91, 0x5C, 0xFD, 0xEF, 0x21, 0xBF, 0x53, 0x80, + 0x7A, 0x2D, 0xD2, 0x91, 0x8C, 0x63, 0x31, 0xF0, 0xEC, 0x24, 0xF0, 0xC3, + 0xA5, 0xD2, 0x72, 0x7C, 0x10, 0x6D, 0xF4, 0x37, 0xB7, 0xE5, 0xE6, 0x7C, + 0x79, 0xEA, 0x8C, 0xB5, 0x82, 0x8B, 0xAE, 0x48, 0xB6, 0xAC, 0x00, 0xDC, + 0x65, 0x75, 0xEC, 0x2A, 0x4D, 0x5F, 0xC1, 0x87, 0xF5, 0x20, 0x65, 0x2B, + 0x81, 0xA8, 0x47, 0x3E, 0x89, 0x23, 0x95, 0x30, 0x16, 0x90, 0x7F, 0xE8, + 0x57, 0x07, 0x48, 0xE7, 0x19, 0xAE, 0xBF, 0x45, 0x67, 0xB1, 0x37, 0x1B, + 0x06, 0x2A, 0xFE, 0xDE, 0xF9, 0xAC, 0x7D, 0x83, 0xFB, 0x5E, 0xBA, 0xE4, + 0x8F, 0x97, 0x67, 0xBE, 0x4B, 0x8E, 0x8D, 0x64, 0x07, 0x57, 0x38, 0x55, + 0x69, 0x34, 0x36, 0x3D, 0x13, 0x48, 0xEF, 0x4F, 0xE2, 0xD3, 0x66, 0x1E, + 0xA4, 0xCF, 0x1A, 0xB7, 0x5E, 0x36, 0x33, 0xD4, 0xB4, 0x06, 0xBD, 0x18, + 0x01, 0xFD, 0x77, 0x84, 0x50, 0x00, 0x45, 0xF5, 0x8C, 0x5D, 0xE8, 0x23, + 0xBC, 0x7E, 0xFE, 0x35, 0xE1, 0xED, 0x50, 0x7B, 0xA9, 0x30, 0x8D, 0x19, + 0xD3, 0x09, 0x8E, 0x68, 0x67, 0x5D, 0xBF, 0x3C, 0x97, 0x18, 0x53, 0xBB, + 0x29, 0x62, 0xC5, 0xCA, 0x5E, 0x72, 0xC1, 0xC7, 0x96, 0xD4, 0xDB, 0x2D, + 0xA0, 0xB4, 0x1F, 0x69, 0x03, 0xEC, 0xEA, 0xE2, 0x50, 0xF1, 0x0C, 0x3C, + 0xF0, 0xAC, 0xF3, 0x53, 0x2D, 0xF0, 0x1C, 0xF5, 0xED, 0x6C, 0x39, 0x39, + 0x73, 0x80, 0x16, 0xC8, 0x52, 0xB0, 0x23, 0xCD, 0xE0, 0x3E, 0xDC, 0xDD, + 0x3C, 0x47, 0xA0, 0xBB, 0x35, 0x8A, 0xE2, 0x98, 0x68, 0x8B, 0xBE, 0xE5, + 0xBF, 0x72, 0xEE, 0xD2, 0xFA, 0xA5, 0xED, 0x12, 0xED, 0xFC, 0x98, 0x18, + 0xA9, 0x26, 0x76, 0xDC, 0x28, 0x4B, 0x10, 0x20, 0x1C, 0xD3, 0x7F, 0x16, + 0x77, 0x2D, 0xED, 0x6F, 0x80, 0xF7, 0x49, 0xBB, 0x53, 0x05, 0xBB, 0x5D, + 0x68, 0xC7, 0xD4, 0xC8, 0x75, 0x16, 0x3F, 0x89, 0x5A, 0x8B, 0xF7, 0x17, + 0x47, 0xD4, 0x4C, 0xF1, 0xD2, 0x89, 0x79, 0x3E, 0x4D, 0x3D, 0x98, 0xA8, + 0x61, 0xDE, 0x3A, 0x1E, 0xD2, 0xF8, 0x5E, 0x03, 0xE0, 0xC1, 0xC9, 0x1C, + 0x8C, 0xD3, 0x8D, 0x4D, 0xD3, 0x95, 0x36, 0xB3, 0x37, 0x5F, 0x63, 0x63, + 0x9B, 0x33, 0x14, 0xF0, 0x2D, 0x26, 0x6B, 0x53, 0x7C, 0x89, 0x8C, 0x32, + 0xC2, 0x6E, 0xEC, 0x3D, 0x21, 0x00, 0x39, 0xC9, 0xA1, 0x68, 0xE2, 0x50, + 0x83, 0x2E, 0xB0, 0x3A, 0x2B, 0xF3, 0x36, 0xA0, 0xAC, 0x2F, 0xE4, 0x6F, + 0x61, 0xC2, 0x51, 0x09, 0x39, 0x3E, 0x8B, 0x53, 0xB9, 0xBB, 0x67, 0xDA, + 0xDC, 0x53, 0xB9, 0x76, 0x59, 0x36, 0x9D, 0x43, 0xE5, 0x20, 0xE0, 0x3D, + 0x32, 0x60, 0x85, 0x22, 0x51, 0xB7, 0xC7, 0x33, 0xBB, 0xDD, 0x15, 0x2F, + 0xA4, 0x78, 0xA6, 0x07, 0x7B, 0x81, 0x46, 0x36, 0x04, 0x86, 0xDD, 0x79, + 0x35, 0xC7, 0x95, 0x2C, 0x3B, 0xB0, 0xA3, 0x17, 0x35, 0xE5, 0x73, 0x1F, + 0xB4, 0x5C, 0x59, 0xEF, 0xDA, 0xEA, 0x10, 0x65, 0x7B, 0x7A, 0xD0, 0x7F, + 0x9F, 0xB3, 0xB4, 0x2A, 0x37, 0x3B, 0x70, 0x8B, 0x9B, 0x5B, 0xB9, 0x2B, + 0xB7, 0xEC, 0xB2, 0x51, 0x12, 0x97, 0x53, 0x29, 0x5A, 0xD4, 0xF0, 0x12, + 0x10, 0xDC, 0x4F, 0x02, 0xBB, 0x12, 0x92, 0x2F, 0x62, 0xD4, 0x3F, 0x69, + 0x43, 0x7C, 0x0D, 0xD6, 0xFC, 0x58, 0x75, 0x01, 0x88, 0x9D, 0x58, 0x16, + 0x4B, 0xDE, 0xBA, 0x90, 0xFF, 0x47, 0x01, 0x89, 0x06, 0x6A, 0xF6, 0x5F, + 0xB2, 0x90, 0x6A, 0xB3, 0x02, 0xA6, 0x02, 0x88, 0xBF, 0xB3, 0x47, 0x7E, + 0x2A, 0xD9, 0xD5, 0xFA, 0x68, 0x78, 0x35, 0x4D +}; + +static const unsigned char TA520_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA521_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x49, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x11, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x6C, + 0x61, 0x6E, 0x64, 0x20, 0x4F, 0x79, 0x6A, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x32 +}; + +static const unsigned char TA521_RSA_N[] = { + 0xB2, 0xD0, 0x3F, 0x07, 0xBC, 0xE2, 0x7B, 0xD0, 0x6B, 0x99, 0xF8, 0xE2, + 0x77, 0x69, 0xE7, 0xCE, 0x9D, 0xA4, 0x03, 0xBC, 0x82, 0x6D, 0xA1, 0xFE, + 0x81, 0x65, 0x1F, 0x4C, 0x27, 0xAC, 0x8E, 0x00, 0xBA, 0x16, 0x7B, 0xEB, + 0x30, 0x6A, 0x00, 0xC0, 0xB3, 0x74, 0x68, 0x7E, 0xB2, 0xAF, 0xC7, 0xD5, + 0x62, 0xB3, 0x7A, 0x3F, 0x50, 0xCA, 0x8C, 0x36, 0x44, 0x24, 0x63, 0xD2, + 0x36, 0xE9, 0x0C, 0x85, 0xF6, 0x43, 0x76, 0xD5, 0x4C, 0xA1, 0x60, 0x72, + 0x67, 0xE2, 0x28, 0x33, 0xA5, 0xCB, 0x31, 0xB8, 0x3A, 0x22, 0x23, 0x34, + 0xB8, 0x7D, 0xBD, 0x56, 0x22, 0x40, 0x9D, 0xEA, 0xF4, 0x7B, 0x03, 0xAD, + 0x68, 0xFC, 0xB2, 0x81, 0x4F, 0x98, 0xD0, 0x74, 0xEA, 0x8D, 0xE5, 0x7D, + 0xCD, 0x63, 0xC3, 0xA3, 0xF6, 0xDE, 0x92, 0xC2, 0x58, 0x19, 0xE0, 0x96, + 0xBB, 0xC5, 0xC4, 0xA9, 0x3D, 0xA5, 0x74, 0x96, 0xFE, 0xAF, 0xF9, 0x89, + 0xAA, 0xBD, 0x95, 0x17, 0x54, 0xD8, 0x78, 0x44, 0xF1, 0x0C, 0x77, 0x15, + 0x92, 0xE0, 0x98, 0x42, 0xA7, 0xA4, 0xD6, 0xAA, 0x20, 0x92, 0xCD, 0xC1, + 0xA0, 0xB3, 0x96, 0xB2, 0x3A, 0x84, 0x42, 0x8D, 0x7D, 0xD5, 0x95, 0xE4, + 0xD6, 0xDB, 0xE9, 0x62, 0xC4, 0x58, 0xB3, 0x79, 0xC5, 0x8C, 0xD3, 0x35, + 0x33, 0x83, 0x9F, 0x75, 0xA1, 0x52, 0x27, 0x61, 0x38, 0xF1, 0x59, 0x3D, + 0x8E, 0x50, 0xE0, 0xBD, 0x79, 0x3C, 0xE7, 0x6C, 0x96, 0xFE, 0x5E, 0xD9, + 0x02, 0x65, 0xB4, 0x8E, 0x5C, 0xD0, 0x11, 0x34, 0xDF, 0x5D, 0xBF, 0x52, + 0xA7, 0x81, 0x00, 0xC3, 0x7F, 0x99, 0x45, 0x99, 0x15, 0xD5, 0x17, 0xC8, + 0x0A, 0x53, 0xEC, 0x63, 0xF3, 0x99, 0x7D, 0xCC, 0x69, 0x12, 0x86, 0xC2, + 0x17, 0xF0, 0x01, 0x9E, 0xBF, 0x84, 0xBC, 0xD1, 0x52, 0xCB, 0x1B, 0x92, + 0x66, 0xCE, 0xA4, 0x53, 0xE5, 0xA1, 0xBF, 0xC4, 0xDB, 0x09, 0xD6, 0xE6, + 0x89, 0x56, 0x2B, 0xC8, 0xE3, 0x7C, 0xDE, 0xE3, 0xFF, 0x89, 0xE5, 0x35, + 0x6E, 0x28, 0xE8, 0x6C, 0x0B, 0x23, 0x51, 0xA9, 0x25, 0x05, 0xEB, 0x48, + 0xF8, 0xDD, 0xB1, 0xCA, 0xFA, 0x6C, 0x08, 0x51, 0xEF, 0xB7, 0x18, 0x6C, + 0x44, 0xCA, 0x26, 0xE1, 0x73, 0xC6, 0x89, 0x06, 0x81, 0xE5, 0x8A, 0xAC, + 0xB0, 0xE2, 0x29, 0xC6, 0xB9, 0x24, 0xB3, 0x6B, 0x44, 0x11, 0xF4, 0xA5, + 0x43, 0xC2, 0x4C, 0x43, 0xE5, 0x70, 0x36, 0x8C, 0xB6, 0x33, 0x57, 0x7A, + 0x95, 0x2E, 0x82, 0xA0, 0xF4, 0x5C, 0x10, 0xB3, 0x61, 0x83, 0xF6, 0x02, + 0x05, 0x86, 0x2E, 0x7C, 0x2D, 0x6C, 0xDC, 0x03, 0x46, 0x6E, 0x35, 0x93, + 0xD5, 0x7A, 0x95, 0x2F, 0xDE, 0x20, 0xD8, 0x5B, 0x7E, 0x94, 0x90, 0x04, + 0x6A, 0xBA, 0x59, 0x3D, 0x04, 0x05, 0x75, 0x9D, 0x37, 0xA2, 0x0E, 0x2E, + 0x3D, 0xEB, 0xC1, 0xA4, 0x52, 0x83, 0xFE, 0xD0, 0x6B, 0xD4, 0x66, 0x8E, + 0xDC, 0xC6, 0xE9, 0x12, 0x4E, 0x1D, 0x2A, 0x57, 0xAA, 0x10, 0xBC, 0x7C, + 0x5E, 0x82, 0x7D, 0xA6, 0xA6, 0xC9, 0xF2, 0x2D, 0xB9, 0xF5, 0x17, 0x27, + 0xAD, 0xD1, 0x0E, 0x89, 0x54, 0x2B, 0x95, 0xFA, 0xC0, 0xAD, 0x1D, 0x98, + 0x14, 0x78, 0x33, 0x42, 0x86, 0x0A, 0xA9, 0x73, 0xB5, 0xFB, 0x74, 0x0D, + 0xB7, 0x1B, 0x30, 0x19, 0xC4, 0x5A, 0x0E, 0x1C, 0x27, 0xB7, 0xDA, 0x18, + 0xD0, 0xFF, 0x8A, 0xC8, 0x05, 0xBA, 0xF1, 0xAA, 0x1C, 0xA2, 0x37, 0xB7, + 0xE6, 0x48, 0xA4, 0x46, 0x2C, 0x94, 0xEA, 0xA8, 0x76, 0x62, 0x47, 0x8B, + 0x10, 0x53, 0x07, 0x48, 0x57, 0x6C, 0xE2, 0x92, 0x4D, 0xB6, 0xAE, 0x05, + 0xCB, 0xDC, 0xC1, 0x4A, 0x5E, 0x8F, 0xAC, 0x3D, 0x19, 0x4E, 0xC2, 0xED, + 0x60, 0x75, 0x2B, 0xDB, 0xC1, 0xCA, 0x42, 0xD5 +}; + +static const unsigned char TA521_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA522_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA522_RSA_N[] = { + 0xC0, 0x31, 0x82, 0x61, 0x92, 0xE4, 0x94, 0x1B, 0x0A, 0x2A, 0x65, 0xD0, + 0xBE, 0x06, 0xA9, 0x87, 0x3B, 0x51, 0x12, 0xEA, 0x70, 0x41, 0xAE, 0xE2, + 0xFB, 0x74, 0xEA, 0x0A, 0x8D, 0xB9, 0xB3, 0x4C, 0xDC, 0x8F, 0xB7, 0x13, + 0x52, 0x4F, 0x54, 0x18, 0xE1, 0x2C, 0x73, 0x95, 0x91, 0xC5, 0x66, 0x3B, + 0x6A, 0xCF, 0xAC, 0x63, 0x6D, 0x87, 0x53, 0xF0, 0xF7, 0xF1, 0x39, 0xB7, + 0xA0, 0x43, 0x63, 0xB0, 0xC4, 0x03, 0x5D, 0x57, 0xA9, 0xE7, 0x44, 0xCE, + 0xC4, 0xA1, 0x83, 0x65, 0xF6, 0x50, 0x3E, 0xB1, 0x7E, 0x16, 0xB8, 0x3A, + 0x8A, 0x02, 0xD0, 0x96, 0x1F, 0x00, 0xCD, 0x05, 0x21, 0xEF, 0x06, 0x6D, + 0xDD, 0x21, 0x9C, 0x19, 0x43, 0x45, 0xA1, 0xC5, 0xE8, 0x80, 0xCA, 0xC2, + 0xAD, 0x40, 0x62, 0x17, 0x06, 0xC6, 0xAA, 0xBC, 0xF3, 0xD6, 0xE6, 0xFC, + 0x50, 0x7E, 0x66, 0x42, 0x1F, 0x3C, 0x8B, 0xA6, 0x79, 0x79, 0x86, 0x40, + 0x35, 0x9F, 0x20, 0xEF, 0x3F, 0xEB, 0x8B, 0x47, 0x1F, 0x8F, 0x8E, 0xC5, + 0xD4, 0x8E, 0xB6, 0x2C, 0xC9, 0x44, 0x04, 0xE3, 0xD4, 0x43, 0x75, 0x3F, + 0xD5, 0x3F, 0xAF, 0x1C, 0xCC, 0x7E, 0x46, 0x5F, 0xAC, 0xDF, 0x64, 0x10, + 0x8A, 0xEF, 0x46, 0xF0, 0x90, 0xF0, 0x0F, 0x2D, 0xF4, 0x88, 0x0B, 0xB1, + 0x29, 0xAA, 0xAF, 0x85, 0xAA, 0x49, 0x58, 0xA8, 0xBF, 0x63, 0xA0, 0x38, + 0x91, 0xE6, 0xB3, 0xE6, 0x77, 0x68, 0xC4, 0xF9, 0x2A, 0x19, 0x84, 0xBB, + 0x0E, 0xE1, 0xF5, 0xAF, 0x89, 0xEC, 0xA5, 0x2F, 0x50, 0x20, 0x74, 0x1E, + 0x12, 0x41, 0x73, 0x1E, 0x24, 0xD9, 0xCA, 0xCE, 0x2C, 0xA1, 0x59, 0x35, + 0xC0, 0xC8, 0x1D, 0x46, 0x27, 0x61, 0x5A, 0x8F, 0xF9, 0x4D, 0xD3, 0x72, + 0x79, 0x66, 0x1E, 0x9F, 0x15, 0x90, 0x21, 0x2D, 0xFD, 0xED, 0x8B, 0x56, + 0x70, 0x03, 0x4A, 0x49, 0x3E, 0x7F, 0x69, 0x31, 0x12, 0x69, 0xC7, 0x1E, + 0x5C, 0xCA, 0x7A, 0x13, 0x8B, 0xE8, 0xE6, 0xF5, 0x60, 0x0F, 0xCC, 0x93, + 0x2C, 0x84, 0x7F, 0xF1, 0xFC, 0x6A, 0xFC, 0x9B, 0x47, 0x9D, 0xDB, 0xAD, + 0x88, 0x3D, 0xF3, 0x76, 0x75, 0x33, 0xD7, 0x4B, 0xA4, 0xC8, 0x8B, 0xF9, + 0xF5, 0x43, 0x58, 0x4F, 0xCB, 0xC8, 0x03, 0x54, 0x8F, 0xA5, 0x85, 0x78, + 0x04, 0x1A, 0xF3, 0x73, 0xF2, 0xD7, 0x87, 0x1D, 0x41, 0x9F, 0xE7, 0xD8, + 0x17, 0xCE, 0x1A, 0x9C, 0x0F, 0x4A, 0xFC, 0xDC, 0x44, 0x68, 0x54, 0x68, + 0xE2, 0x41, 0x3C, 0xFE, 0x2C, 0x84, 0x86, 0x37, 0x3C, 0xCD, 0x3F, 0x2F, + 0xA2, 0xDB, 0xE7, 0xF7, 0x54, 0x03, 0x5F, 0x59, 0xD3, 0xF7, 0x91, 0x78, + 0xC7, 0x8B, 0x77, 0x6A, 0x16, 0xE5, 0x49, 0x85, 0x90, 0x45, 0x72, 0x70, + 0x2F, 0x91, 0x5D, 0xF8, 0x3E, 0x65, 0x40, 0x0B, 0x19, 0x99, 0xC9, 0x26, + 0x20, 0x5A, 0x68, 0xC1, 0x35, 0xBF, 0x4F, 0xA7, 0x51, 0xF1, 0xD8, 0x11, + 0x2B, 0x5B, 0xE0, 0x9A, 0x9E, 0x28, 0x3B, 0x0A, 0x3A, 0x0A, 0x1F, 0xC1, + 0x81, 0xE5, 0x2E, 0xF0, 0xA6, 0xB9, 0x69, 0xA5, 0x88, 0x94, 0xE6, 0x6B, + 0x13, 0x7F, 0xD1, 0x64, 0x3F, 0x3D, 0x9C, 0x70, 0x46, 0xE5, 0xA2, 0x85, + 0x7B, 0x58, 0x84, 0x27, 0xDC, 0xC4, 0x80, 0x3E, 0x67, 0x9A, 0x9A, 0xC7, + 0x9A, 0x31, 0x0E, 0x30, 0xEC, 0xE6, 0x17, 0x40, 0x95, 0xD9, 0x45, 0xED, + 0x01, 0x96, 0xAA, 0xBF, 0x0C, 0xF3, 0x4B, 0xD1, 0x63, 0xF7, 0x13, 0x58, + 0xC0, 0xB8, 0xF3, 0xFA, 0x67, 0xDD, 0x9B, 0x7D, 0x6D, 0x4A, 0xFF, 0x32, + 0x4C, 0xB5, 0x25, 0x3B, 0xFF, 0x1C, 0x67, 0x0F, 0x85, 0x22, 0x59, 0x05, + 0x91, 0x91, 0x41, 0x77, 0x81, 0xD0, 0x85, 0x4C, 0x87, 0x10, 0x71, 0xFF, + 0x9E, 0x43, 0x1B, 0xAE, 0x95, 0x75, 0x2D, 0x81 +}; + +static const unsigned char TA522_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA523_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA523_EC_Q[] = { + 0x04, 0xF1, 0xB3, 0xCD, 0x38, 0xE4, 0x25, 0x43, 0xE5, 0xDE, 0x19, 0x09, + 0xBB, 0x81, 0x79, 0xA2, 0x15, 0x5F, 0x15, 0x63, 0x01, 0xDE, 0xC2, 0xAB, + 0xDD, 0xB3, 0xA6, 0x1B, 0x67, 0x4B, 0x80, 0x83, 0xAF, 0x99, 0xCB, 0xAC, + 0x17, 0xDB, 0x2B, 0x96, 0xCA, 0x7C, 0x52, 0x55, 0xE2, 0x1A, 0xE1, 0x3D, + 0x56, 0xF0, 0x2F, 0x16, 0x08, 0xFA, 0x15, 0xBC, 0x9B, 0xBB, 0x47, 0xE6, + 0x3F, 0xEE, 0xA8, 0xE1, 0x4C, 0x8C, 0xF5, 0xD3, 0x36, 0xF9, 0x38, 0x5D, + 0xAB, 0x70, 0x9A, 0x47, 0x0D, 0xE2, 0x81, 0x41, 0x06, 0xEB, 0x49, 0xF9, + 0xB0, 0x29, 0xDD, 0x33, 0xEC, 0x50, 0xA5, 0x7F, 0x79, 0x29, 0xB8, 0x20, + 0x98 +}; + +static const unsigned char TA524_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x28, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA524_RSA_N[] = { + 0xB9, 0x5D, 0x51, 0x28, 0x4B, 0x3C, 0x37, 0x92, 0xD1, 0x82, 0xCE, 0xBD, + 0x1D, 0xBD, 0xCD, 0xDD, 0xB8, 0xAB, 0xCF, 0x0A, 0x3E, 0xE1, 0x5D, 0xE5, + 0xDC, 0xAA, 0x09, 0xB9, 0x57, 0x02, 0x3E, 0xE6, 0x63, 0x61, 0xDF, 0xF2, + 0x0F, 0x82, 0x63, 0xAE, 0xA3, 0xF7, 0xAC, 0x73, 0xD1, 0x7C, 0xE7, 0xB3, + 0x0B, 0xAF, 0x08, 0x00, 0x09, 0x59, 0x7F, 0xCD, 0x29, 0x2A, 0x88, 0x93, + 0x87, 0x17, 0x18, 0x80, 0xED, 0x88, 0xB2, 0xB4, 0xB6, 0x10, 0x1F, 0x2D, + 0xD6, 0x5F, 0x55, 0xA2, 0x13, 0x5D, 0xD1, 0xC6, 0xEB, 0x06, 0x56, 0x89, + 0x88, 0xFE, 0xAC, 0x32, 0x9D, 0xFD, 0x5C, 0xC3, 0x05, 0xC7, 0x6E, 0xEE, + 0x86, 0x89, 0xBA, 0x88, 0x03, 0x9D, 0x72, 0x21, 0x86, 0x90, 0xAE, 0x8F, + 0x03, 0xA5, 0xDC, 0x9F, 0x88, 0x28, 0xCB, 0xA3, 0x92, 0x49, 0x0F, 0xEC, + 0xD0, 0x0F, 0xE2, 0x6D, 0x44, 0x4F, 0x80, 0x6A, 0xB2, 0xD4, 0xE7, 0xA0, + 0x0A, 0x53, 0x01, 0xBA, 0x8E, 0x97, 0x91, 0x76, 0x6E, 0xBC, 0xFC, 0xD5, + 0x6B, 0x36, 0xE6, 0x40, 0x88, 0xD6, 0x7B, 0x2F, 0x5F, 0x05, 0xE8, 0x2C, + 0x6D, 0x11, 0xF3, 0xE7, 0xB2, 0xBE, 0x92, 0x44, 0x4C, 0xD2, 0x97, 0xA4, + 0xFE, 0xD2, 0x72, 0x81, 0x43, 0x07, 0x9C, 0xE9, 0x11, 0x3E, 0xF5, 0x8B, + 0x1A, 0x59, 0x7D, 0x1F, 0x68, 0x58, 0xDD, 0x04, 0x00, 0x2C, 0x96, 0xF3, + 0x43, 0xB3, 0x7E, 0x98, 0x19, 0x74, 0xD9, 0x9C, 0x73, 0xD9, 0x18, 0xBE, + 0x41, 0xC7, 0x34, 0x79, 0xD9, 0xF4, 0x62, 0xC2, 0x43, 0xB9, 0xB3, 0x27, + 0xB0, 0x22, 0xCB, 0xF9, 0x3D, 0x52, 0xC7, 0x30, 0x47, 0xB3, 0xC9, 0x3E, + 0xB8, 0x6A, 0xE2, 0xE7, 0xE8, 0x81, 0x70, 0x5E, 0x42, 0x8B, 0x4F, 0x26, + 0xA5, 0xFE, 0x3A, 0xC2, 0x20, 0x6E, 0xBB, 0xF8, 0x16, 0x8E, 0xCD, 0x0C, + 0xA9, 0xB4, 0x1B, 0x6C, 0x76, 0x10, 0xE1, 0x58, 0x79, 0x46, 0x3E, 0x54, + 0xCE, 0x80, 0xA8, 0x57, 0x09, 0x37, 0x29, 0x1B, 0x99, 0x13, 0x8F, 0x0C, + 0xC8, 0xD6, 0x2C, 0x1C, 0xFB, 0x05, 0xE8, 0x08, 0x95, 0x3D, 0x65, 0x46, + 0xDC, 0xEE, 0xCD, 0x69, 0xE2, 0x4D, 0x8F, 0x87, 0x28, 0x4E, 0x34, 0x0B, + 0x3E, 0xCF, 0x14, 0xD9, 0xBB, 0xDD, 0xB6, 0x50, 0x9A, 0xAD, 0x77, 0xD4, + 0x19, 0xD6, 0xDA, 0x1A, 0x88, 0xC8, 0x4E, 0x1B, 0x27, 0x75, 0xD8, 0xB2, + 0x08, 0xF1, 0xAE, 0x83, 0x30, 0xB9, 0x11, 0x0E, 0xCD, 0x87, 0xF0, 0x84, + 0x8D, 0x15, 0x72, 0x7C, 0xA1, 0xEF, 0xCC, 0xF2, 0x88, 0x61, 0xBA, 0xF4, + 0x69, 0xBB, 0x0C, 0x8C, 0x0B, 0x75, 0x57, 0x04, 0xB8, 0x4E, 0x2A, 0x14, + 0x2E, 0x3D, 0x0F, 0x1C, 0x1E, 0x32, 0xA6, 0x62, 0x36, 0xEE, 0x66, 0xE2, + 0x22, 0xB8, 0x05, 0x40, 0x63, 0x10, 0x22, 0xF3, 0x33, 0x1D, 0x74, 0x72, + 0x8A, 0x2C, 0xF5, 0x39, 0x29, 0xA0, 0xD3, 0xE7, 0x1B, 0x80, 0x84, 0x2D, + 0xC5, 0x3D, 0xE3, 0x4D, 0xB1, 0xFD, 0x1A, 0x6F, 0xBA, 0x65, 0x07, 0x3B, + 0x58, 0xEC, 0x42, 0x45, 0x26, 0xFB, 0xD8, 0xDA, 0x25, 0x72, 0xC4, 0xF6, + 0x00, 0xB1, 0x22, 0x79, 0xBD, 0xE3, 0x7C, 0x59, 0x62, 0x4A, 0x9C, 0x05, + 0x6F, 0x3D, 0xCE, 0xE6, 0xD6, 0x47, 0x63, 0x99, 0xC6, 0x24, 0x6F, 0x72, + 0x12, 0xC8, 0xAC, 0x7F, 0x90, 0xB4, 0x0B, 0x91, 0x70, 0xE8, 0xB7, 0xE6, + 0x16, 0x10, 0x71, 0x17, 0xCE, 0xDE, 0x06, 0x4F, 0x48, 0x41, 0x7D, 0x35, + 0x4A, 0xA3, 0x89, 0xF2, 0xC9, 0x4B, 0x7B, 0x41, 0x11, 0x6D, 0x67, 0xB7, + 0x08, 0x98, 0x4C, 0xE5, 0x11, 0x19, 0xAE, 0x42, 0x80, 0xDC, 0xFB, 0x90, + 0x05, 0xD4, 0xF8, 0x50, 0xCA, 0xBE, 0xE4, 0xAD, 0xC7, 0xC2, 0x94, 0xD7, + 0x16, 0x9D, 0xE6, 0x17, 0x8F, 0xAF, 0x36, 0xFB +}; + +static const unsigned char TA524_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA525_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x32, 0x35, 0x36, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA525_EC_Q[] = { + 0x04, 0x7E, 0xFB, 0x6C, 0xE6, 0x23, 0xE3, 0x73, 0x32, 0x08, 0xCA, 0x60, + 0xE6, 0x53, 0x9C, 0xBA, 0x74, 0x8D, 0x18, 0xB0, 0x78, 0x90, 0x52, 0x80, + 0xDD, 0x38, 0xC0, 0x4A, 0x1D, 0xD1, 0xA8, 0xCC, 0x93, 0xA4, 0x97, 0x06, + 0x38, 0xCA, 0x0D, 0x15, 0x62, 0xC6, 0x8E, 0x01, 0x2A, 0x65, 0x9D, 0xAA, + 0xDF, 0x34, 0x91, 0x2E, 0x81, 0xC1, 0xE4, 0x33, 0x92, 0x31, 0xC4, 0xFD, + 0x09, 0x3A, 0xA6, 0x3F, 0xAD +}; + +static const unsigned char TA526_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA526_EC_Q[] = { + 0x04, 0x6B, 0xDA, 0x0D, 0x75, 0x35, 0x08, 0x31, 0x47, 0x05, 0xAE, 0x45, + 0x99, 0x55, 0xF1, 0x11, 0x13, 0x2E, 0x4A, 0xF8, 0x10, 0x31, 0x23, 0xA3, + 0x7E, 0x83, 0xD3, 0x7F, 0x28, 0x08, 0x3A, 0x26, 0x1A, 0x3A, 0xCF, 0x97, + 0x82, 0x1F, 0x80, 0xB7, 0x27, 0x09, 0x8F, 0xD1, 0x8E, 0x30, 0xC4, 0x0A, + 0x9B, 0x0E, 0xAC, 0x58, 0x04, 0xAB, 0xF7, 0x36, 0x7D, 0x94, 0x23, 0xA4, + 0x9B, 0x0A, 0x8A, 0x8B, 0xAB, 0xEB, 0xFD, 0x39, 0x25, 0x66, 0xF1, 0x5E, + 0xFE, 0x8C, 0xAE, 0x8D, 0x41, 0x79, 0x9D, 0x09, 0x60, 0xCE, 0x28, 0xA9, + 0xD3, 0x8A, 0x6D, 0xF3, 0xD6, 0x45, 0xD4, 0xF2, 0x98, 0x84, 0x38, 0x65, + 0xA0 +}; + +static const unsigned char TA527_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x4E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4E, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x65, 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x71, 0x75, 0x65, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, + 0x75, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA527_RSA_N[] = { + 0xC3, 0xCD, 0xD3, 0xFC, 0xBD, 0x04, 0x53, 0xDD, 0x0C, 0x20, 0x3A, 0xD5, + 0x88, 0x2E, 0x05, 0x4B, 0x41, 0xF5, 0x83, 0x82, 0x7E, 0xF7, 0x59, 0x9F, + 0x9E, 0x9E, 0x63, 0xE8, 0x73, 0xDA, 0xF6, 0x06, 0xA9, 0x4F, 0x1F, 0xB4, + 0xF9, 0x0B, 0x1F, 0x39, 0x8C, 0x9A, 0x20, 0xD0, 0x7E, 0x06, 0xD4, 0xEC, + 0x34, 0xD9, 0x86, 0xBC, 0x75, 0x5B, 0x87, 0x88, 0xF0, 0xD2, 0xD9, 0xD4, + 0xA3, 0x0A, 0xB2, 0x6C, 0x1B, 0xEB, 0x49, 0x2C, 0x3E, 0xAC, 0x5D, 0xD8, + 0x94, 0x03, 0xA0, 0xEC, 0x34, 0xE5, 0x30, 0xC4, 0x35, 0x7D, 0xFB, 0x26, + 0x4D, 0x1B, 0x6E, 0x30, 0x54, 0xD8, 0xF5, 0x80, 0x45, 0x9C, 0x39, 0xAD, + 0x9C, 0xC9, 0x25, 0x04, 0x4D, 0x9A, 0x90, 0x3E, 0x4E, 0x40, 0x6E, 0x8A, + 0x6B, 0xCD, 0x29, 0x67, 0xC6, 0xCC, 0x2D, 0xE0, 0x74, 0xE8, 0x05, 0x57, + 0x0A, 0x48, 0x50, 0xFA, 0x7A, 0x43, 0xDA, 0x7E, 0xEC, 0x5B, 0x9A, 0x0E, + 0x62, 0x76, 0xFE, 0xEA, 0x9D, 0x1D, 0x85, 0x72, 0xEC, 0x11, 0xBB, 0x35, + 0xE8, 0x1F, 0x27, 0xBF, 0xC1, 0xA1, 0xC7, 0xBB, 0x48, 0x16, 0xDD, 0x56, + 0xD7, 0xCC, 0x4E, 0xA0, 0xE1, 0xB9, 0xAC, 0xDB, 0xD5, 0x83, 0x19, 0x1A, + 0x85, 0xD1, 0x94, 0x97, 0xD7, 0xCA, 0xA3, 0x65, 0x0B, 0xF3, 0x38, 0xF9, + 0x02, 0xAE, 0xDD, 0xF6, 0x67, 0xCF, 0xC9, 0x3F, 0xF5, 0x8A, 0x2C, 0x47, + 0x1A, 0x99, 0x6F, 0x05, 0x0D, 0xFD, 0xD0, 0x1D, 0x82, 0x31, 0xFC, 0x29, + 0xCC, 0x00, 0x58, 0x97, 0x91, 0x4C, 0x80, 0x00, 0x1C, 0x33, 0x85, 0x96, + 0x2F, 0xCB, 0x41, 0xC2, 0x8B, 0x10, 0x84, 0xC3, 0x09, 0x24, 0x89, 0x1F, + 0xB5, 0x0F, 0xD9, 0xD9, 0x77, 0x47, 0x18, 0x92, 0x94, 0x60, 0x5C, 0xC7, + 0x99, 0x03, 0x3C, 0xFE, 0xF7, 0x95, 0xA7, 0x7D, 0x50, 0xA1, 0x80, 0xC2, + 0xA9, 0x83, 0xAD, 0x58, 0x96, 0x55, 0x21, 0xDB, 0x86, 0x59, 0xD4, 0xAF, + 0xC6, 0xBC, 0xDD, 0x81, 0x6E, 0x07, 0xDB, 0x60, 0x62, 0xFE, 0xEC, 0x10, + 0x6E, 0xDA, 0x68, 0x01, 0xF4, 0x83, 0x1B, 0xA9, 0x3E, 0xA2, 0x5B, 0x23, + 0xD7, 0x64, 0xC6, 0xDF, 0xDC, 0xA2, 0x7D, 0xD8, 0x4B, 0xBA, 0x82, 0xD2, + 0x51, 0xF8, 0x66, 0xBF, 0x06, 0x46, 0xE4, 0x79, 0x2A, 0x26, 0x36, 0x79, + 0x8F, 0x1F, 0x4E, 0x99, 0x1D, 0xB2, 0x8F, 0x0C, 0x0E, 0x1C, 0xFF, 0xC9, + 0x5D, 0xC0, 0xFD, 0x90, 0x10, 0xA6, 0xB1, 0x37, 0xF3, 0xCD, 0x3A, 0x24, + 0x6E, 0xB4, 0x85, 0x90, 0xBF, 0x80, 0xB9, 0x0C, 0x8C, 0xD5, 0x9B, 0xD6, + 0xC8, 0xF1, 0x56, 0x3F, 0x1A, 0x80, 0x89, 0x7A, 0xA9, 0xE2, 0x1B, 0x32, + 0x51, 0x2C, 0x3E, 0xF2, 0xDF, 0x7B, 0xF6, 0x5D, 0x7A, 0x29, 0x19, 0x8E, + 0xE5, 0xC8, 0xBD, 0x36, 0x71, 0x8B, 0x5D, 0x4C, 0xC2, 0x1D, 0x3F, 0xAD, + 0x58, 0xA2, 0xCF, 0x3D, 0x70, 0x4D, 0xA6, 0x50, 0x98, 0x25, 0xDC, 0x23, + 0xF9, 0xB8, 0x58, 0x41, 0x08, 0x71, 0xBF, 0x4F, 0xB8, 0x84, 0xA0, 0x8F, + 0x00, 0x54, 0x15, 0xFC, 0x91, 0x6D, 0x58, 0xA7, 0x96, 0x3B, 0xEB, 0x4B, + 0x96, 0x27, 0xCD, 0x6B, 0xA2, 0xA1, 0x86, 0xAC, 0x0D, 0x7C, 0x54, 0xE6, + 0x66, 0x4C, 0x66, 0x5F, 0x90, 0xBE, 0x21, 0x9A, 0x02, 0x46, 0x2D, 0xE4, + 0x83, 0xC2, 0x80, 0xB9, 0xCF, 0x4B, 0x3E, 0xE8, 0x7F, 0x3C, 0x01, 0xEC, + 0x8F, 0x5E, 0xCD, 0x7F, 0xD2, 0x28, 0x42, 0x01, 0x95, 0x8A, 0xE2, 0x97, + 0x3D, 0x10, 0x21, 0x7D, 0xF6, 0x9D, 0x1C, 0xC5, 0x34, 0xA1, 0xEC, 0x2C, + 0x0E, 0x0A, 0x52, 0x2C, 0x12, 0x55, 0x70, 0x24, 0x3D, 0xCB, 0xC2, 0x14, + 0x35, 0x43, 0x5D, 0x27, 0x4E, 0xBE, 0xC0, 0xBD, 0xAA, 0x7C, 0x96, 0xE7, + 0xFC, 0x9E, 0x61, 0xAD, 0x44, 0xD3, 0x00, 0x97 +}; + +static const unsigned char TA527_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA528_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x55, 0x43, 0x41, + 0x20, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, + 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74 +}; + +static const unsigned char TA528_RSA_N[] = { + 0xA9, 0x09, 0x07, 0x28, 0x13, 0x02, 0xB0, 0x99, 0xE0, 0x64, 0xAA, 0x1E, + 0x43, 0x16, 0x7A, 0x73, 0xB1, 0x91, 0xA0, 0x75, 0x3E, 0xA8, 0xFA, 0xE3, + 0x38, 0x00, 0x7A, 0xEC, 0x89, 0x6A, 0x20, 0x0F, 0x8B, 0xC5, 0xB0, 0x9B, + 0x33, 0x03, 0x5A, 0x86, 0xC6, 0x58, 0x86, 0xD5, 0xC1, 0x85, 0xBB, 0x4F, + 0xC6, 0x9C, 0x40, 0x4D, 0xCA, 0xBE, 0xEE, 0x69, 0x96, 0xB8, 0xAD, 0x81, + 0x30, 0x9A, 0x7C, 0x92, 0x05, 0xEB, 0x05, 0x2B, 0x9A, 0x48, 0xD0, 0xB8, + 0x76, 0x3E, 0x96, 0xC8, 0x20, 0xBB, 0xD2, 0xB0, 0xF1, 0x8F, 0xD8, 0xAC, + 0x45, 0x46, 0xFF, 0xAA, 0x67, 0x60, 0xB4, 0x77, 0x7E, 0x6A, 0x1F, 0x3C, + 0x1A, 0x52, 0x7A, 0x04, 0x3D, 0x07, 0x3C, 0x85, 0x0D, 0x84, 0xD0, 0x1F, + 0x76, 0x0A, 0xF7, 0x6A, 0x14, 0xDF, 0x72, 0xE3, 0x34, 0x7C, 0x57, 0x4E, + 0x56, 0x01, 0x3E, 0x79, 0xF1, 0xAA, 0x29, 0x3B, 0x6C, 0xFA, 0xF8, 0x8F, + 0x6D, 0x4D, 0xC8, 0x35, 0xDF, 0xAE, 0xEB, 0xDC, 0x24, 0xEE, 0x79, 0x45, + 0xA7, 0x85, 0xB6, 0x05, 0x88, 0xDE, 0x88, 0x5D, 0x25, 0x7C, 0x97, 0x64, + 0x67, 0x09, 0xD9, 0xBF, 0x5A, 0x15, 0x05, 0x86, 0xF3, 0x09, 0x1E, 0xEC, + 0x58, 0x32, 0x33, 0x11, 0xF3, 0x77, 0x64, 0xB0, 0x76, 0x1F, 0xE4, 0x10, + 0x35, 0x17, 0x1B, 0xF2, 0x0E, 0xB1, 0x6C, 0xA4, 0x2A, 0xA3, 0x73, 0xFC, + 0x09, 0x1F, 0x1E, 0x32, 0x19, 0x53, 0x11, 0xE7, 0xD9, 0xB3, 0x2C, 0x2E, + 0x76, 0x2E, 0xA1, 0xA3, 0xDE, 0x7E, 0x6A, 0x88, 0x09, 0xE8, 0xF2, 0x07, + 0x8A, 0xF8, 0xB2, 0xCD, 0x10, 0xE7, 0xE2, 0x73, 0x40, 0x93, 0xBB, 0x08, + 0xD1, 0x3F, 0xE1, 0xFC, 0x0B, 0x94, 0xB3, 0x25, 0xEF, 0x7C, 0xA6, 0xD7, + 0xD1, 0xAF, 0x9F, 0xFF, 0x96, 0x9A, 0xF5, 0x91, 0x7B, 0x98, 0x0B, 0x77, + 0xD4, 0x7E, 0xE8, 0x07, 0xD2, 0x62, 0xB5, 0x95, 0x39, 0xE3, 0xF3, 0xF1, + 0x6D, 0x0F, 0x0E, 0x65, 0x84, 0x8A, 0x63, 0x54, 0xC5, 0x80, 0xB6, 0xE0, + 0x9E, 0x4B, 0x7D, 0x47, 0x26, 0xA7, 0x01, 0x08, 0x5D, 0xD1, 0x88, 0x9E, + 0xD7, 0xC3, 0x32, 0x44, 0xFA, 0x82, 0x4A, 0x0A, 0x68, 0x54, 0x7F, 0x38, + 0x53, 0x03, 0xCC, 0xA4, 0x00, 0x33, 0x64, 0x51, 0x59, 0x0B, 0xA3, 0x82, + 0x91, 0x7A, 0x5E, 0xEC, 0x16, 0xC2, 0xF3, 0x2A, 0xE6, 0x62, 0xDA, 0x2A, + 0xDB, 0x59, 0x62, 0x10, 0x25, 0x4A, 0x2A, 0x81, 0x0B, 0x47, 0x07, 0x43, + 0x06, 0x70, 0x87, 0xD2, 0xFA, 0x93, 0x11, 0x29, 0x7A, 0x48, 0x4D, 0xEB, + 0x94, 0xC7, 0x70, 0x4D, 0xAF, 0x67, 0xD5, 0x51, 0xB1, 0x80, 0x20, 0x01, + 0x01, 0xB4, 0x7A, 0x08, 0xA6, 0x90, 0x7F, 0x4E, 0xE0, 0xEF, 0x07, 0x41, + 0x87, 0xAF, 0x6A, 0xA5, 0x5E, 0x8B, 0xFB, 0xCF, 0x50, 0xB2, 0x9A, 0x54, + 0xAF, 0xC3, 0x89, 0xBA, 0x58, 0x2D, 0xF5, 0x30, 0x98, 0xB1, 0x36, 0x72, + 0x39, 0x7E, 0x49, 0x04, 0xFD, 0x29, 0xA7, 0x4C, 0x79, 0xE4, 0x05, 0x57, + 0xDB, 0x94, 0xB9, 0x16, 0x53, 0x8D, 0x46, 0xB3, 0x1D, 0x95, 0x61, 0x57, + 0x56, 0x7F, 0xAF, 0xF0, 0x16, 0x5B, 0x61, 0x58, 0x6F, 0x36, 0x50, 0x11, + 0x0B, 0xD8, 0xAC, 0x2B, 0x95, 0x16, 0x1A, 0x0E, 0x1F, 0x08, 0xCD, 0x36, + 0x34, 0x65, 0x10, 0x62, 0x66, 0xD5, 0x80, 0x5F, 0x14, 0x20, 0x5F, 0x2D, + 0x0C, 0xA0, 0x78, 0x0A, 0x68, 0xD6, 0x2C, 0xD7, 0xE9, 0x6F, 0x2B, 0xD2, + 0x4A, 0x05, 0x93, 0xFC, 0x9E, 0x6F, 0x6B, 0x67, 0xFF, 0x88, 0xF1, 0x4E, + 0xA5, 0x69, 0x4A, 0x52, 0x37, 0x05, 0xEA, 0xC6, 0x16, 0x8D, 0xD2, 0xC4, + 0x99, 0xD1, 0x82, 0x2B, 0x3B, 0xBA, 0x35, 0x75, 0xF7, 0x51, 0x51, 0x58, + 0xF3, 0xC8, 0x07, 0xDD, 0xE4, 0xB4, 0x03, 0x7F +}; + +static const unsigned char TA528_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA529_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x1B, + 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x55, 0x43, 0x41, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x47, 0x32, 0x20, 0x52, + 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA529_RSA_N[] = { + 0xC5, 0xE6, 0x2B, 0x6F, 0x7C, 0xEF, 0x26, 0x05, 0x27, 0xA3, 0x81, 0x24, + 0xDA, 0x6F, 0xCB, 0x01, 0xF9, 0x99, 0x9A, 0xA9, 0x32, 0xC2, 0x22, 0x87, + 0x61, 0x41, 0x91, 0x3B, 0xCB, 0xC3, 0x68, 0x1B, 0x06, 0xC5, 0x4C, 0xA9, + 0x2B, 0xC1, 0x67, 0x17, 0x22, 0x1D, 0x2B, 0xED, 0xF9, 0x29, 0x89, 0x93, + 0xA2, 0x78, 0xBD, 0x92, 0x6B, 0xA0, 0xA3, 0x0D, 0xA2, 0x7E, 0xCA, 0x93, + 0xB3, 0xA6, 0xD1, 0x8C, 0x35, 0xD5, 0x75, 0xF9, 0x17, 0xF6, 0xCF, 0x45, + 0xC5, 0xE5, 0x7A, 0xEC, 0x77, 0x93, 0xA0, 0x8F, 0x23, 0xAE, 0x0E, 0x1A, + 0x03, 0x7F, 0xBE, 0xD4, 0xD0, 0xED, 0x2E, 0x7B, 0xAB, 0x46, 0x23, 0x5B, + 0xFF, 0x2C, 0xE6, 0x54, 0x7A, 0x94, 0xC0, 0x2A, 0x15, 0xF0, 0xC9, 0x8D, + 0xB0, 0x7A, 0x3B, 0x24, 0xE1, 0xD7, 0x68, 0xE2, 0x31, 0x3C, 0x06, 0x33, + 0x46, 0xB6, 0x54, 0x11, 0xA6, 0xA5, 0x2F, 0x22, 0x54, 0x2A, 0x58, 0x0D, + 0x01, 0x02, 0xF1, 0xFA, 0x15, 0x51, 0x67, 0x6C, 0xC0, 0xFA, 0xD7, 0xB6, + 0x1B, 0x7F, 0xD1, 0x56, 0x88, 0x2F, 0x1A, 0x3A, 0x8D, 0x3B, 0xBB, 0x82, + 0x11, 0xE0, 0x47, 0x00, 0xD0, 0x52, 0x87, 0xAB, 0xFB, 0x86, 0x7E, 0x0F, + 0x24, 0x6B, 0x40, 0x9D, 0x34, 0x67, 0xBC, 0x8D, 0xC7, 0x2D, 0x86, 0x6F, + 0x79, 0x3E, 0x8E, 0xA9, 0x3C, 0x17, 0x4B, 0x7F, 0xB0, 0x99, 0xE3, 0xB0, + 0x71, 0x60, 0xDC, 0x0B, 0xF5, 0x64, 0xC3, 0xCE, 0x43, 0xBC, 0x6D, 0x71, + 0xB9, 0xD2, 0xDE, 0x27, 0x5B, 0x8A, 0xE8, 0xD8, 0xC6, 0xAE, 0xE1, 0x59, + 0x7D, 0xCF, 0x28, 0x2D, 0x35, 0xB8, 0x95, 0x56, 0x1A, 0xF1, 0xB2, 0x58, + 0x4B, 0xB7, 0x12, 0x37, 0xC8, 0x7C, 0xB3, 0xED, 0x4B, 0x80, 0xE1, 0x8D, + 0xFA, 0x32, 0x23, 0xB6, 0x6F, 0xB7, 0x48, 0x95, 0x08, 0xB1, 0x44, 0x4E, + 0x85, 0x8C, 0x3A, 0x02, 0x54, 0x20, 0x2F, 0xDF, 0xBF, 0x57, 0x4F, 0x3B, + 0x3A, 0x90, 0x21, 0xD7, 0xC1, 0x26, 0x35, 0x54, 0x20, 0xEC, 0xC7, 0x3F, + 0x47, 0xEC, 0xEF, 0x5A, 0xBF, 0x4B, 0x7A, 0xC1, 0xAD, 0x3B, 0x17, 0x50, + 0x5C, 0x62, 0xD8, 0x0F, 0x4B, 0x4A, 0xDC, 0x2B, 0xFA, 0x6E, 0xBC, 0x73, + 0x92, 0xCD, 0xEC, 0xC7, 0x50, 0xE8, 0x41, 0x96, 0xD7, 0xA9, 0x7E, 0x6D, + 0xD8, 0xE9, 0x1D, 0x8F, 0x8A, 0xB5, 0xB9, 0x58, 0x92, 0xBA, 0x4A, 0x92, + 0x2B, 0x0C, 0x56, 0xFD, 0x80, 0xEB, 0x08, 0xF0, 0x5E, 0x29, 0x6E, 0x1B, + 0x1C, 0x0C, 0xAF, 0x8F, 0x93, 0x89, 0xAD, 0xDB, 0xBD, 0xA3, 0x9E, 0x21, + 0xCA, 0x89, 0x19, 0xEC, 0xDF, 0xB5, 0xC3, 0x1A, 0xEB, 0x16, 0xFE, 0x78, + 0x36, 0x4C, 0xD6, 0x6E, 0xD0, 0x3E, 0x17, 0x1C, 0x90, 0x17, 0x6B, 0x26, + 0xBA, 0xFB, 0x7A, 0x2F, 0xBF, 0x11, 0x1C, 0x18, 0x0E, 0x2D, 0x73, 0x03, + 0x8F, 0xA0, 0xE5, 0x35, 0xA0, 0x5A, 0xE2, 0x4C, 0x75, 0x1D, 0x71, 0xE1, + 0x39, 0x38, 0x53, 0x78, 0x40, 0xCC, 0x83, 0x93, 0xD7, 0x0A, 0x9E, 0x9D, + 0x5B, 0x8F, 0x8A, 0xE4, 0xE5, 0xE0, 0x48, 0xE4, 0x48, 0xB2, 0x47, 0xCD, + 0x4E, 0x2A, 0x75, 0x2A, 0x7B, 0xF2, 0x22, 0xF6, 0xC9, 0xBE, 0x09, 0x91, + 0x96, 0x57, 0x7A, 0x88, 0x88, 0xAC, 0xEE, 0x70, 0xAC, 0xF9, 0xDC, 0x29, + 0xE3, 0x0C, 0x1C, 0x3B, 0x12, 0x4E, 0x44, 0xD6, 0xA7, 0x4E, 0xB0, 0x26, + 0xC8, 0xF3, 0xD9, 0x1A, 0x97, 0x91, 0x68, 0xEA, 0xEF, 0x8D, 0x46, 0x06, + 0xD2, 0x56, 0x45, 0x58, 0x9A, 0x3C, 0x0C, 0x0F, 0x83, 0xB8, 0x05, 0x25, + 0xC3, 0x39, 0xCF, 0x3B, 0xA4, 0x34, 0x89, 0xB7, 0x79, 0x12, 0x2F, 0x47, + 0xC5, 0xE7, 0xA9, 0x97, 0x69, 0xFC, 0xA6, 0x77, 0x67, 0xB5, 0xDF, 0x7B, + 0xF1, 0x7A, 0x65, 0x15, 0xE4, 0x61, 0x56, 0x65 +}; + +static const unsigned char TA529_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA530_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA530_EC_Q[] = { + 0x04, 0x1A, 0xAC, 0x54, 0x5A, 0xA9, 0xF9, 0x68, 0x23, 0xE7, 0x7A, 0xD5, + 0x24, 0x6F, 0x53, 0xC6, 0x5A, 0xD8, 0x4B, 0xAB, 0xC6, 0xD5, 0xB6, 0xD1, + 0xE6, 0x73, 0x71, 0xAE, 0xDD, 0x9C, 0xD6, 0x0C, 0x61, 0xFD, 0xDB, 0xA0, + 0x89, 0x03, 0xB8, 0x05, 0x14, 0xEC, 0x57, 0xCE, 0xEE, 0x5D, 0x3F, 0xE2, + 0x21, 0xB3, 0xCE, 0xF7, 0xD4, 0x8A, 0x79, 0xE0, 0xA3, 0x83, 0x7E, 0x2D, + 0x97, 0xD0, 0x61, 0xC4, 0xF1, 0x99, 0xDC, 0x25, 0x91, 0x63, 0xAB, 0x7F, + 0x30, 0xA3, 0xB4, 0x70, 0xE2, 0xC7, 0xA1, 0x33, 0x9C, 0xF3, 0xBF, 0x2E, + 0x5C, 0x53, 0xB1, 0x5F, 0xB3, 0x7D, 0x32, 0x7F, 0x8A, 0x34, 0xE3, 0x79, + 0x79 +}; + +static const unsigned char TA531_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA531_RSA_N[] = { + 0x80, 0x12, 0x65, 0x17, 0x36, 0x0E, 0xC3, 0xDB, 0x08, 0xB3, 0xD0, 0xAC, + 0x57, 0x0D, 0x76, 0xED, 0xCD, 0x27, 0xD3, 0x4C, 0xAD, 0x50, 0x83, 0x61, + 0xE2, 0xAA, 0x20, 0x4D, 0x09, 0x2D, 0x64, 0x09, 0xDC, 0xCE, 0x89, 0x9F, + 0xCC, 0x3D, 0xA9, 0xEC, 0xF6, 0xCF, 0xC1, 0xDC, 0xF1, 0xD3, 0xB1, 0xD6, + 0x7B, 0x37, 0x28, 0x11, 0x2B, 0x47, 0xDA, 0x39, 0xC6, 0xBC, 0x3A, 0x19, + 0xB4, 0x5F, 0xA6, 0xBD, 0x7D, 0x9D, 0xA3, 0x63, 0x42, 0xB6, 0x76, 0xF2, + 0xA9, 0x3B, 0x2B, 0x91, 0xF8, 0xE2, 0x6F, 0xD0, 0xEC, 0x16, 0x20, 0x90, + 0x09, 0x3E, 0xE2, 0xE8, 0x74, 0xC9, 0x18, 0xB4, 0x91, 0xD4, 0x62, 0x64, + 0xDB, 0x7F, 0xA3, 0x06, 0xF1, 0x88, 0x18, 0x6A, 0x90, 0x22, 0x3C, 0xBC, + 0xFE, 0x13, 0xF0, 0x87, 0x14, 0x7B, 0xF6, 0xE4, 0x1F, 0x8E, 0xD4, 0xE4, + 0x51, 0xC6, 0x11, 0x67, 0x46, 0x08, 0x51, 0xCB, 0x86, 0x14, 0x54, 0x3F, + 0xBC, 0x33, 0xFE, 0x7E, 0x6C, 0x9C, 0xFF, 0x16, 0x9D, 0x18, 0xBD, 0x51, + 0x8E, 0x35, 0xA6, 0xA7, 0x66, 0xC8, 0x72, 0x67, 0xDB, 0x21, 0x66, 0xB1, + 0xD4, 0x9B, 0x78, 0x03, 0xC0, 0x50, 0x3A, 0xE8, 0xCC, 0xF0, 0xDC, 0xBC, + 0x9E, 0x4C, 0xFE, 0xAF, 0x05, 0x96, 0x35, 0x1F, 0x57, 0x5A, 0xB7, 0xFF, + 0xCE, 0xF9, 0x3D, 0xB7, 0x2C, 0xB6, 0xF6, 0x54, 0xDD, 0xC8, 0xE7, 0x12, + 0x3A, 0x4D, 0xAE, 0x4C, 0x8A, 0xB7, 0x5C, 0x9A, 0xB4, 0xB7, 0x20, 0x3D, + 0xCA, 0x7F, 0x22, 0x34, 0xAE, 0x7E, 0x3B, 0x68, 0x66, 0x01, 0x44, 0xE7, + 0x01, 0x4E, 0x46, 0x53, 0x9B, 0x33, 0x60, 0xF7, 0x94, 0xBE, 0x53, 0x37, + 0x90, 0x73, 0x43, 0xF3, 0x32, 0xC3, 0x53, 0xEF, 0xDB, 0xAA, 0xFE, 0x74, + 0x4E, 0x69, 0xC7, 0x6B, 0x8C, 0x60, 0x93, 0xDE, 0xC4, 0xC7, 0x0C, 0xDF, + 0xE1, 0x32, 0xAE, 0xCC, 0x93, 0x3B, 0x51, 0x78, 0x95, 0x67, 0x8B, 0xEE, + 0x3D, 0x56, 0xFE, 0x0C, 0xD0, 0x69, 0x0F, 0x1B, 0x0F, 0xF3, 0x25, 0x26, + 0x6B, 0x33, 0x6D, 0xF7, 0x6E, 0x47, 0xFA, 0x73, 0x43, 0xE5, 0x7E, 0x0E, + 0xA5, 0x66, 0xB1, 0x29, 0x7C, 0x32, 0x84, 0x63, 0x55, 0x89, 0xC4, 0x0D, + 0xC1, 0x93, 0x54, 0x30, 0x19, 0x13, 0xAC, 0xD3, 0x7D, 0x37, 0xA7, 0xEB, + 0x5D, 0x3A, 0x6C, 0x35, 0x5C, 0xDB, 0x41, 0xD7, 0x12, 0xDA, 0xA9, 0x49, + 0x0B, 0xDF, 0xD8, 0x80, 0x8A, 0x09, 0x93, 0x62, 0x8E, 0xB5, 0x66, 0xCF, + 0x25, 0x88, 0xCD, 0x84, 0xB8, 0xB1, 0x3F, 0xA4, 0x39, 0x0F, 0xD9, 0x02, + 0x9E, 0xEB, 0x12, 0x4C, 0x95, 0x7C, 0xF3, 0x6B, 0x05, 0xA9, 0x5E, 0x16, + 0x83, 0xCC, 0xB8, 0x67, 0xE2, 0xE8, 0x13, 0x9D, 0xCC, 0x5B, 0x82, 0xD3, + 0x4C, 0xB3, 0xED, 0x5B, 0xFF, 0xDE, 0xE5, 0x73, 0xAC, 0x23, 0x3B, 0x2D, + 0x00, 0xBF, 0x35, 0x55, 0x74, 0x09, 0x49, 0xD8, 0x49, 0x58, 0x1A, 0x7F, + 0x92, 0x36, 0xE6, 0x51, 0x92, 0x0E, 0xF3, 0x26, 0x7D, 0x1C, 0x4D, 0x17, + 0xBC, 0xC9, 0xEC, 0x43, 0x26, 0xD0, 0xBF, 0x41, 0x5F, 0x40, 0xA9, 0x44, + 0x44, 0xF4, 0x99, 0xE7, 0x57, 0x87, 0x9E, 0x50, 0x1F, 0x57, 0x54, 0xA8, + 0x3E, 0xFD, 0x74, 0x63, 0x2F, 0xB1, 0x50, 0x65, 0x09, 0xE6, 0x58, 0x42, + 0x2E, 0x43, 0x1A, 0x4C, 0xB4, 0xF0, 0x25, 0x47, 0x59, 0xFA, 0x04, 0x1E, + 0x93, 0xD4, 0x26, 0x46, 0x4A, 0x50, 0x81, 0xB2, 0xDE, 0xBE, 0x78, 0xB7, + 0xFC, 0x67, 0x15, 0xE1, 0xC9, 0x57, 0x84, 0x1E, 0x0F, 0x63, 0xD6, 0xE9, + 0x62, 0xBA, 0xD6, 0x5F, 0x55, 0x2E, 0xEA, 0x5C, 0xC6, 0x28, 0x08, 0x04, + 0x25, 0x39, 0xB8, 0x0E, 0x2B, 0xA9, 0xF2, 0x4C, 0x97, 0x1C, 0x07, 0x3F, + 0x0D, 0x52, 0xF5, 0xED, 0xEF, 0x2F, 0x82, 0x0F +}; + +static const unsigned char TA531_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA532_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x15, 0x77, 0x77, 0x77, 0x2E, 0x78, 0x72, 0x61, 0x6D, 0x70, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x58, + 0x52, 0x61, 0x6D, 0x70, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x24, 0x58, 0x52, 0x61, 0x6D, 0x70, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA532_RSA_N[] = { + 0x98, 0x24, 0x1E, 0xBD, 0x15, 0xB4, 0xBA, 0xDF, 0xC7, 0x8C, 0xA5, 0x27, + 0xB6, 0x38, 0x0B, 0x69, 0xF3, 0xB6, 0x4E, 0xA8, 0x2C, 0x2E, 0x21, 0x1D, + 0x5C, 0x44, 0xDF, 0x21, 0x5D, 0x7E, 0x23, 0x74, 0xFE, 0x5E, 0x7E, 0xB4, + 0x4A, 0xB7, 0xA6, 0xAD, 0x1F, 0xAE, 0xE0, 0x06, 0x16, 0xE2, 0x9B, 0x5B, + 0xD9, 0x67, 0x74, 0x6B, 0x5D, 0x80, 0x8F, 0x29, 0x9D, 0x86, 0x1B, 0xD9, + 0x9C, 0x0D, 0x98, 0x6D, 0x76, 0x10, 0x28, 0x58, 0xE4, 0x65, 0xB0, 0x7F, + 0x4A, 0x98, 0x79, 0x9F, 0xE0, 0xC3, 0x31, 0x7E, 0x80, 0x2B, 0xB5, 0x8C, + 0xC0, 0x40, 0x3B, 0x11, 0x86, 0xD0, 0xCB, 0xA2, 0x86, 0x36, 0x60, 0xA4, + 0xD5, 0x30, 0x82, 0x6D, 0xD9, 0x6E, 0xD0, 0x0F, 0x12, 0x04, 0x33, 0x97, + 0x5F, 0x4F, 0x61, 0x5A, 0xF0, 0xE4, 0xF9, 0x91, 0xAB, 0xE7, 0x1D, 0x3B, + 0xBC, 0xE8, 0xCF, 0xF4, 0x6B, 0x2D, 0x34, 0x7C, 0xE2, 0x48, 0x61, 0x1C, + 0x8E, 0xF3, 0x61, 0x44, 0xCC, 0x6F, 0xA0, 0x4A, 0xA9, 0x94, 0xB0, 0x4D, + 0xDA, 0xE7, 0xA9, 0x34, 0x7A, 0x72, 0x38, 0xA8, 0x41, 0xCC, 0x3C, 0x94, + 0x11, 0x7D, 0xEB, 0xC8, 0xA6, 0x8C, 0xB7, 0x86, 0xCB, 0xCA, 0x33, 0x3B, + 0xD9, 0x3D, 0x37, 0x8B, 0xFB, 0x7A, 0x3E, 0x86, 0x2C, 0xE7, 0x73, 0xD7, + 0x0A, 0x57, 0xAC, 0x64, 0x9B, 0x19, 0xEB, 0xF4, 0x0F, 0x04, 0x08, 0x8A, + 0xAC, 0x03, 0x17, 0x19, 0x64, 0xF4, 0x5A, 0x25, 0x22, 0x8D, 0x34, 0x2C, + 0xB2, 0xF6, 0x68, 0x1D, 0x12, 0x6D, 0xD3, 0x8A, 0x1E, 0x14, 0xDA, 0xC4, + 0x8F, 0xA6, 0xE2, 0x23, 0x85, 0xD5, 0x7A, 0x0D, 0xBD, 0x6A, 0xE0, 0xE9, + 0xEC, 0xEC, 0x17, 0xBB, 0x42, 0x1B, 0x67, 0xAA, 0x25, 0xED, 0x45, 0x83, + 0x21, 0xFC, 0xC1, 0xC9, 0x7C, 0xD5, 0x62, 0x3E, 0xFA, 0xF2, 0xC5, 0x2D, + 0xD3, 0xFD, 0xD4, 0x65 +}; + +static const unsigned char TA532_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA533_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x08, 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x10, 0x63, 0x65, 0x72, + 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA533_RSA_N[] = { + 0xB7, 0x33, 0xB9, 0x7E, 0xC8, 0x25, 0x4A, 0x8E, 0xB5, 0xDB, 0xB4, 0x28, + 0x1B, 0xAA, 0x57, 0x90, 0xE8, 0xD1, 0x22, 0xD3, 0x64, 0xBA, 0xD3, 0x93, + 0xE8, 0xD4, 0xAC, 0x86, 0x61, 0x40, 0x6A, 0x60, 0x57, 0x68, 0x54, 0x84, + 0x4D, 0xBC, 0x6A, 0x54, 0x02, 0x05, 0xFF, 0xDF, 0x9B, 0x9A, 0x2A, 0xAE, + 0x5D, 0x07, 0x8F, 0x4A, 0xC3, 0x28, 0x7F, 0xEF, 0xFB, 0x2B, 0xFA, 0x79, + 0xF1, 0xC7, 0xAD, 0xF0, 0x10, 0x53, 0x24, 0x90, 0x8B, 0x66, 0xC9, 0xA8, + 0x88, 0xAB, 0xAF, 0x5A, 0xA3, 0x00, 0xE9, 0xBE, 0xBA, 0x46, 0xEE, 0x5B, + 0x73, 0x7B, 0x2C, 0x17, 0x82, 0x81, 0x5E, 0x62, 0x2C, 0xA1, 0x02, 0x65, + 0xB3, 0xBD, 0xC5, 0x2B, 0x00, 0x7E, 0xC4, 0xFC, 0x03, 0x33, 0x57, 0x0D, + 0xED, 0xE2, 0xFA, 0xCE, 0x5D, 0x45, 0xD6, 0x38, 0xCD, 0x35, 0xB6, 0xB2, + 0xC1, 0xD0, 0x9C, 0x81, 0x4A, 0xAA, 0xE4, 0xB2, 0x01, 0x5C, 0x1D, 0x8F, + 0x5F, 0x99, 0xC4, 0xB1, 0xAD, 0xDB, 0x88, 0x21, 0xEB, 0x90, 0x08, 0x82, + 0x80, 0xF3, 0x30, 0xA3, 0x43, 0xE6, 0x90, 0x82, 0xAE, 0x55, 0x28, 0x49, + 0xED, 0x5B, 0xD7, 0xA9, 0x10, 0x38, 0x0E, 0xFE, 0x8F, 0x4C, 0x5B, 0x9B, + 0x46, 0xEA, 0x41, 0xF5, 0xB0, 0x08, 0x74, 0xC3, 0xD0, 0x88, 0x33, 0xB6, + 0x7C, 0xD7, 0x74, 0xDF, 0xDC, 0x84, 0xD1, 0x43, 0x0E, 0x75, 0x39, 0xA1, + 0x25, 0x40, 0x28, 0xEA, 0x78, 0xCB, 0x0E, 0x2C, 0x2E, 0x39, 0x9D, 0x8C, + 0x8B, 0x6E, 0x16, 0x1C, 0x2F, 0x26, 0x82, 0x10, 0xE2, 0xE3, 0x65, 0x94, + 0x0A, 0x04, 0xC0, 0x5E, 0xF7, 0x5D, 0x5B, 0xF8, 0x10, 0xE2, 0xD0, 0xBA, + 0x7A, 0x4B, 0xFB, 0xDE, 0x37, 0x00, 0x00, 0x1A, 0x5B, 0x28, 0xE3, 0xD2, + 0x9C, 0x73, 0x3E, 0x32, 0x87, 0x98, 0xA1, 0xC9, 0x51, 0x2F, 0xD7, 0xDE, + 0xAC, 0x33, 0xB3, 0x4F +}; + +static const unsigned char TA533_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA534_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x43, 0x45, 0x52, 0x54, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x53, + 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x13, + 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, + 0x54, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA534_RSA_N[] = { + 0xC0, 0xC5, 0x75, 0x19, 0x91, 0x7D, 0x44, 0x74, 0x74, 0x87, 0xFE, 0x0E, + 0x3B, 0x96, 0xDC, 0xD8, 0x01, 0x16, 0xCC, 0xEE, 0x63, 0x91, 0xE7, 0x0B, + 0x6F, 0xCE, 0x3B, 0x0A, 0x69, 0x1A, 0x7C, 0xC2, 0xE3, 0xAF, 0x82, 0x8E, + 0x86, 0xD7, 0x5E, 0x8F, 0x57, 0xEB, 0xD3, 0x21, 0x59, 0xFD, 0x39, 0x37, + 0x42, 0x30, 0xBE, 0x50, 0xEA, 0xB6, 0x0F, 0xA9, 0x88, 0xD8, 0x2E, 0x2D, + 0x69, 0x21, 0xE7, 0xD1, 0x37, 0x18, 0x4E, 0x7D, 0x91, 0xD5, 0x16, 0x5F, + 0x6B, 0x5B, 0x00, 0xC2, 0x39, 0x43, 0x0D, 0x36, 0x85, 0x52, 0xB9, 0x53, + 0x65, 0x0F, 0x1D, 0x42, 0xE5, 0x8F, 0xCF, 0x05, 0xD3, 0xEE, 0xDC, 0x0C, + 0x1A, 0xD9, 0xB8, 0x8B, 0x78, 0x22, 0x67, 0xE4, 0x69, 0xB0, 0x68, 0xC5, + 0x3C, 0xE4, 0x6C, 0x5A, 0x46, 0xE7, 0xCD, 0xC7, 0xFA, 0xEF, 0xC4, 0xEC, + 0x4B, 0xBD, 0x6A, 0xA4, 0xAC, 0xFD, 0xCC, 0x28, 0x51, 0xEF, 0x92, 0xB4, + 0x29, 0xAB, 0xAB, 0x35, 0x9A, 0x4C, 0xE4, 0xC4, 0x08, 0xC6, 0x26, 0xCC, + 0xF8, 0x69, 0x9F, 0xE4, 0x9C, 0xF0, 0x29, 0xD3, 0x5C, 0xF9, 0xC6, 0x16, + 0x25, 0x9E, 0x23, 0xC3, 0x20, 0xC1, 0x3D, 0x0F, 0x3F, 0x38, 0x40, 0xB0, + 0xFE, 0x82, 0x44, 0x38, 0xAA, 0x5A, 0x1A, 0x8A, 0x6B, 0x63, 0x58, 0x38, + 0xB4, 0x15, 0xD3, 0xB6, 0x11, 0x69, 0x7B, 0x1E, 0x54, 0xEE, 0x8C, 0x1A, + 0x22, 0xAC, 0x72, 0x97, 0x3F, 0x23, 0x59, 0x9B, 0xC9, 0x22, 0x84, 0xC1, + 0x07, 0x4F, 0xCC, 0x7F, 0xE2, 0x57, 0xCA, 0x12, 0x70, 0xBB, 0xA6, 0x65, + 0xF3, 0x69, 0x75, 0x63, 0xBD, 0x95, 0xFB, 0x1B, 0x97, 0xCD, 0xE4, 0xA8, + 0xAF, 0xF6, 0xD1, 0x4E, 0xA8, 0xD9, 0x8A, 0x71, 0x24, 0xCD, 0x36, 0x3D, + 0xBC, 0x96, 0xC4, 0xF1, 0x6C, 0xA9, 0xAE, 0xE5, 0xCF, 0x0D, 0x6E, 0x28, + 0x0D, 0xB0, 0x0E, 0xB5, 0xCA, 0x51, 0x7B, 0x78, 0x14, 0xC3, 0x20, 0x2F, + 0x7F, 0xFB, 0x14, 0x55, 0xE1, 0x11, 0x99, 0xFD, 0xD5, 0x0A, 0xA1, 0x9E, + 0x02, 0xE3, 0x62, 0x5F, 0xEB, 0x35, 0x4B, 0x2C, 0xB8, 0x72, 0xE8, 0x3E, + 0x3D, 0x4F, 0xAC, 0x2C, 0xBB, 0x2E, 0x86, 0xE2, 0xA3, 0x76, 0x8F, 0xE5, + 0x93, 0x2A, 0xCF, 0xA5, 0xAB, 0xC8, 0x5C, 0x8D, 0x4B, 0x06, 0xFF, 0x12, + 0x46, 0xAC, 0x78, 0xCB, 0x14, 0x07, 0x35, 0xE0, 0xA9, 0xDF, 0x8B, 0xE9, + 0xAF, 0x15, 0x4F, 0x16, 0x89, 0x5B, 0xBD, 0xF6, 0x8D, 0xC6, 0x59, 0xAE, + 0x88, 0x85, 0x0E, 0xC1, 0x89, 0xEB, 0x1F, 0x67, 0xC5, 0x45, 0x8E, 0xFF, + 0x6D, 0x37, 0x36, 0x2B, 0x78, 0x66, 0x83, 0x91, 0x51, 0x2B, 0x3D, 0xFF, + 0x51, 0x77, 0x76, 0x62, 0xA1, 0xEC, 0x67, 0x3E, 0x3E, 0x81, 0x83, 0xE0, + 0x56, 0xA9, 0x50, 0x1F, 0x1F, 0x7A, 0x99, 0xAB, 0x63, 0xBF, 0x84, 0x17, + 0x77, 0xF1, 0x0D, 0x3B, 0xDF, 0xF7, 0x9C, 0x61, 0xB3, 0x35, 0x98, 0x8A, + 0x3A, 0xB2, 0xEC, 0x3C, 0x1A, 0x37, 0x3F, 0x7E, 0x8F, 0x92, 0xCF, 0xD9, + 0x12, 0x14, 0x64, 0xDA, 0x10, 0x02, 0x15, 0x41, 0xFF, 0x4F, 0xC4, 0xEB, + 0x1C, 0xA3, 0xC9, 0xFA, 0x99, 0xF7, 0x46, 0xE9, 0xE1, 0x18, 0xD9, 0xB1, + 0xB8, 0x32, 0x2D, 0xCB, 0x14, 0x0C, 0x50, 0xD8, 0x83, 0x65, 0x83, 0xEE, + 0xB9, 0x5C, 0xCF, 0xCB, 0x05, 0x5A, 0x4C, 0xFA, 0x19, 0x97, 0x6B, 0xD6, + 0x5D, 0x13, 0xD3, 0xC2, 0x5C, 0x54, 0xBC, 0x32, 0x73, 0xA0, 0x78, 0xF5, + 0xF1, 0x6D, 0x1E, 0xCB, 0x9F, 0xA5, 0xA6, 0x9F, 0x22, 0xDC, 0xD1, 0x51, + 0x9E, 0x82, 0x79, 0x64, 0x60, 0x29, 0x13, 0x3E, 0xA3, 0xFD, 0x4F, 0x72, + 0x6A, 0xAB, 0xE2, 0xD4, 0xE5, 0xB8, 0x24, 0x55, 0x2C, 0x44, 0x4B, 0x8A, + 0x88, 0x44, 0x9C, 0xCA, 0x84, 0xD3, 0x2A, 0x3B +}; + +static const unsigned char TA534_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA535_DN[] = { + 0x30, 0x71, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, 0x63, + 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0E, 0x56, 0x41, 0x54, + 0x48, 0x55, 0x2D, 0x32, 0x33, 0x35, 0x38, 0x34, 0x34, 0x39, 0x37, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x15, 0x65, 0x2D, + 0x53, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA535_EC_Q[] = { + 0x04, 0x96, 0xDC, 0x3D, 0x8A, 0xD8, 0xB0, 0x7B, 0x6F, 0xC6, 0x27, 0xBE, + 0x44, 0x90, 0xB1, 0xB3, 0x56, 0x15, 0x7B, 0x8E, 0x43, 0x24, 0x7D, 0x1A, + 0x84, 0x59, 0xEE, 0x63, 0x68, 0xB2, 0xC6, 0x5E, 0x87, 0xD0, 0x15, 0x48, + 0x1E, 0xA8, 0x90, 0xAD, 0xBD, 0x53, 0xA2, 0xDA, 0xDE, 0x3A, 0x90, 0xA6, + 0x60, 0x5F, 0x68, 0x32, 0xB5, 0x86, 0x41, 0xDF, 0x87, 0x5B, 0x2C, 0x7B, + 0xC5, 0xFE, 0x7C, 0x7A, 0xDA +}; + +static const unsigned char TA536_DN[] = { + 0x30, 0x5E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x21, 0x65, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA536_RSA_N[] = { + 0xE1, 0x25, 0x0F, 0xEE, 0x8D, 0xDB, 0x88, 0x33, 0x75, 0x67, 0xCD, 0xAD, + 0x1F, 0x7D, 0x3A, 0x4E, 0x6D, 0x9D, 0xD3, 0x2F, 0x14, 0xF3, 0x63, 0x74, + 0xCB, 0x01, 0x21, 0x6A, 0x37, 0xEA, 0x84, 0x50, 0x07, 0x4B, 0x26, 0x5B, + 0x09, 0x43, 0x6C, 0x21, 0x9E, 0x6A, 0xC8, 0xD5, 0x03, 0xF5, 0x60, 0x69, + 0x8F, 0xCC, 0xF0, 0x22, 0xE4, 0x1F, 0xE7, 0xF7, 0x6A, 0x22, 0x31, 0xB7, + 0x2C, 0x15, 0xF2, 0xE0, 0xFE, 0x00, 0x6A, 0x43, 0xFF, 0x87, 0x65, 0xC6, + 0xB5, 0x1A, 0xC1, 0xA7, 0x4C, 0x6D, 0x22, 0x70, 0x21, 0x8A, 0x31, 0xF2, + 0x97, 0x74, 0x89, 0x09, 0x12, 0x26, 0x1C, 0x9E, 0xCA, 0xD9, 0x12, 0xA2, + 0x95, 0x3C, 0xDA, 0xE9, 0x67, 0xBF, 0x08, 0xA0, 0x64, 0xE3, 0xD6, 0x42, + 0xB7, 0x45, 0xEF, 0x97, 0xF4, 0xF6, 0xF5, 0xD7, 0xB5, 0x4A, 0x15, 0x02, + 0x58, 0x7D, 0x98, 0x58, 0x4B, 0x60, 0xBC, 0xCD, 0xD7, 0x0D, 0x9A, 0x13, + 0x33, 0x53, 0xD1, 0x61, 0xF9, 0x7A, 0xD5, 0xD7, 0x78, 0xB3, 0x9A, 0x33, + 0xF7, 0x00, 0x86, 0xCE, 0x1D, 0x4D, 0x94, 0x38, 0xAF, 0xA8, 0xEC, 0x78, + 0x51, 0x70, 0x8A, 0x5C, 0x10, 0x83, 0x51, 0x21, 0xF7, 0x11, 0x3D, 0x34, + 0x86, 0x5E, 0xE5, 0x48, 0xCD, 0x97, 0x81, 0x82, 0x35, 0x4C, 0x19, 0xEC, + 0x65, 0xF6, 0x6B, 0xC5, 0x05, 0xA1, 0xEE, 0x47, 0x13, 0xD6, 0xB3, 0x21, + 0x27, 0x94, 0x10, 0x0A, 0xD9, 0x24, 0x3B, 0xBA, 0xBE, 0x44, 0x13, 0x46, + 0x30, 0x3F, 0x97, 0x3C, 0xD8, 0xD7, 0xD7, 0x6A, 0xEE, 0x3B, 0x38, 0xE3, + 0x2B, 0xD4, 0x97, 0x0E, 0xB9, 0x1B, 0xE7, 0x07, 0x49, 0x7F, 0x37, 0x2A, + 0xF9, 0x77, 0x78, 0xCF, 0x54, 0xED, 0x5B, 0x46, 0x9D, 0xA3, 0x80, 0x0E, + 0x91, 0x43, 0xC1, 0xD6, 0x5B, 0x5F, 0x14, 0xBA, 0x9F, 0xA6, 0x8D, 0x24, + 0x47, 0x40, 0x59, 0xBF, 0x72, 0x38, 0xB2, 0x36, 0x6C, 0x37, 0xFF, 0x99, + 0xD1, 0x5D, 0x0E, 0x59, 0x0A, 0xAB, 0x69, 0xF7, 0xC0, 0xB2, 0x04, 0x45, + 0x7A, 0x54, 0x00, 0xAE, 0xBE, 0x53, 0xF6, 0xB5, 0xE7, 0xE1, 0xF8, 0x3C, + 0xA3, 0x31, 0xD2, 0xA9, 0xFE, 0x21, 0x52, 0x64, 0xC5, 0xA6, 0x67, 0xF0, + 0x75, 0x07, 0x06, 0x94, 0x14, 0x81, 0x55, 0xC6, 0x27, 0xE4, 0x01, 0x8F, + 0x17, 0xC1, 0x6A, 0x71, 0xD7, 0xBE, 0x4B, 0xFB, 0x94, 0x58, 0x7D, 0x7E, + 0x11, 0x33, 0xB1, 0x42, 0xF7, 0x62, 0x6C, 0x18, 0xD6, 0xCF, 0x09, 0x68, + 0x3E, 0x7F, 0x6C, 0xF6, 0x1E, 0x8F, 0x62, 0xAD, 0xA5, 0x63, 0xDB, 0x09, + 0xA7, 0x1F, 0x22, 0x42, 0x41, 0x1E, 0x6F, 0x99, 0x8A, 0x3E, 0xD7, 0xF9, + 0x3F, 0x40, 0x7A, 0x79, 0xB0, 0xA5, 0x01, 0x92, 0xD2, 0x9D, 0x3D, 0x08, + 0x15, 0xA5, 0x10, 0x01, 0x2D, 0xB3, 0x32, 0x76, 0xA8, 0x95, 0x0D, 0xB3, + 0x7A, 0x9A, 0xFB, 0x07, 0x10, 0x78, 0x11, 0x6F, 0xE1, 0x8F, 0xC7, 0xBA, + 0x0F, 0x25, 0x1A, 0x74, 0x2A, 0xE5, 0x1C, 0x98, 0x41, 0x99, 0xDF, 0x21, + 0x87, 0xE8, 0x95, 0x06, 0x6A, 0x0A, 0xB3, 0x6A, 0x47, 0x76, 0x65, 0xF6, + 0x3A, 0xCF, 0x8F, 0x62, 0x17, 0x19, 0x7B, 0x0A, 0x28, 0xCD, 0x1A, 0xD2, + 0x83, 0x1E, 0x21, 0xC7, 0x2C, 0xBF, 0xBE, 0xFF, 0x61, 0x68, 0xB7, 0x67, + 0x1B, 0xBB, 0x78, 0x4D, 0x8D, 0xCE, 0x67, 0xE5, 0xE4, 0xC1, 0x8E, 0xB7, + 0x23, 0x66, 0xE2, 0x9D, 0x90, 0x75, 0x34, 0x98, 0xA9, 0x36, 0x2B, 0x8A, + 0x9A, 0x94, 0xB9, 0x9D, 0xEC, 0xCC, 0x8A, 0xB1, 0xF8, 0x25, 0x89, 0x5C, + 0x5A, 0xB6, 0x2F, 0x8C, 0x1F, 0x6D, 0x79, 0x24, 0xA7, 0x52, 0x68, 0xC3, + 0x84, 0x35, 0xE2, 0x66, 0x8D, 0x63, 0x0E, 0x25, 0x4D, 0xD5, 0x19, 0xB2, + 0xE6, 0x79, 0x37, 0xA7, 0x22, 0x9D, 0x54, 0x31 +}; + +static const unsigned char TA536_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA537_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x43, 0x33 +}; + +static const unsigned char TA537_EC_Q[] = { + 0x04, 0xFD, 0xA5, 0x61, 0xAE, 0x7B, 0x26, 0x10, 0x1D, 0xE9, 0xB7, 0x22, + 0x30, 0xAE, 0x06, 0xF4, 0x81, 0xB3, 0xB1, 0x42, 0x71, 0x95, 0x39, 0xBC, + 0xD3, 0x52, 0xE3, 0xAF, 0xAF, 0xF9, 0xF2, 0x97, 0x35, 0x92, 0x36, 0x46, + 0x0E, 0x87, 0x95, 0x8D, 0xB9, 0x39, 0x5A, 0xE9, 0xBB, 0xDF, 0xD0, 0xFE, + 0xC8, 0x07, 0x41, 0x3C, 0xBB, 0x55, 0x6F, 0x83, 0xA3, 0x6A, 0xFB, 0x62, + 0xB0, 0x81, 0x89, 0x02, 0x70, 0x7D, 0x48, 0xC5, 0x4A, 0xE3, 0xE9, 0x22, + 0x54, 0x22, 0x4D, 0x93, 0xBB, 0x42, 0x0C, 0xAF, 0x77, 0x9C, 0x23, 0xA6, + 0x7D, 0xD7, 0x61, 0x11, 0xCE, 0x65, 0xC7, 0xF8, 0x7F, 0xFE, 0xF5, 0xF2, + 0xA9 +}; + +static const unsigned char TA538_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x17, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, + 0x33 +}; + +static const unsigned char TA538_EC_Q[] = { + 0x04, 0x23, 0xA5, 0x0C, 0xB8, 0x2D, 0x12, 0xF5, 0x28, 0xF3, 0xB1, 0xB2, + 0xDD, 0xE2, 0x02, 0x12, 0x80, 0x9E, 0x39, 0x5F, 0x49, 0x4D, 0x9F, 0xC9, + 0x25, 0x34, 0x59, 0x74, 0xEC, 0xBB, 0x06, 0x1C, 0xE7, 0xC0, 0x72, 0xAF, + 0xE8, 0xAE, 0x2F, 0xE1, 0x41, 0x54, 0x87, 0x14, 0xA8, 0x4A, 0xB2, 0xE8, + 0x7C, 0x82, 0xE6, 0x5B, 0x6A, 0xB5, 0xDC, 0xB3, 0x75, 0xCE, 0x8B, 0x06, + 0xD0, 0x86, 0x23, 0xBF, 0x46, 0xD5, 0x8E, 0x0F, 0x3F, 0x04, 0xF4, 0xD7, + 0x1C, 0x92, 0x7E, 0xF6, 0xA5, 0x63, 0xC2, 0xF5, 0x5F, 0x8E, 0x2E, 0x4F, + 0xA1, 0x18, 0x19, 0x02, 0x2B, 0x32, 0x0A, 0x82, 0x64, 0x7D, 0x16, 0x93, + 0xD1 +}; + +static const unsigned char TA539_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x1C, + 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x43, 0x31 +}; + +static const unsigned char TA539_RSA_N[] = { + 0xCF, 0xEB, 0xA9, 0xB9, 0xF1, 0x99, 0x05, 0xCC, 0xD8, 0x28, 0x21, 0x4A, + 0xF3, 0x73, 0x34, 0x51, 0x84, 0x56, 0x10, 0xF5, 0xA0, 0x4F, 0x2C, 0x12, + 0xE3, 0xFA, 0x13, 0x9A, 0x27, 0xD0, 0xCF, 0xF9, 0x79, 0x1A, 0x74, 0x5F, + 0x1D, 0x79, 0x39, 0xFC, 0x5B, 0xF8, 0x70, 0x8E, 0xE0, 0x92, 0x52, 0xF7, + 0xE4, 0x25, 0xF9, 0x54, 0x83, 0xD9, 0x1D, 0xD3, 0xC8, 0x5A, 0x85, 0x3F, + 0x5E, 0xC7, 0xB6, 0x07, 0xEE, 0x3E, 0xC0, 0xCE, 0x9A, 0xAF, 0xAC, 0x56, + 0x42, 0x2A, 0x39, 0x25, 0x70, 0xD6, 0xBF, 0xB5, 0x7B, 0x36, 0xAD, 0xAC, + 0xF6, 0x73, 0xDC, 0xCD, 0xD7, 0x1D, 0x8A, 0x83, 0xA5, 0xFB, 0x2B, 0x90, + 0x15, 0x37, 0x6B, 0x1C, 0x26, 0x47, 0xDC, 0x3B, 0x29, 0x56, 0x93, 0x6A, + 0xB3, 0xC1, 0x6A, 0x3A, 0x9D, 0x3D, 0xF5, 0xC1, 0x97, 0x38, 0x58, 0x05, + 0x8B, 0x1C, 0x11, 0xE3, 0xE4, 0xB4, 0xB8, 0x5D, 0x85, 0x1D, 0x83, 0xFE, + 0x78, 0x5F, 0x0B, 0x45, 0x68, 0x18, 0x48, 0xA5, 0x46, 0x73, 0x34, 0x3B, + 0xFE, 0x0F, 0xC8, 0x76, 0xBB, 0xC7, 0x18, 0xF3, 0x05, 0xD1, 0x86, 0xF3, + 0x85, 0xED, 0xE7, 0xB9, 0xD9, 0x32, 0xAD, 0x55, 0x88, 0xCE, 0xA6, 0xB6, + 0x91, 0xB0, 0x4F, 0xAC, 0x7E, 0x15, 0x23, 0x96, 0xF6, 0x3F, 0xF0, 0x20, + 0x34, 0x16, 0xDE, 0x0A, 0xC6, 0xC4, 0x04, 0x45, 0x79, 0x7F, 0xA7, 0xFD, + 0xBE, 0xD2, 0xA9, 0xA5, 0xAF, 0x9C, 0xC5, 0x23, 0x2A, 0xF7, 0x3C, 0x21, + 0x6C, 0xBD, 0xAF, 0x8F, 0x4E, 0xC5, 0x3A, 0xB2, 0xF3, 0x34, 0x12, 0xFC, + 0xDF, 0x80, 0x1A, 0x49, 0xA4, 0xD4, 0xA9, 0x95, 0xF7, 0x9E, 0x89, 0x5E, + 0xA2, 0x89, 0xAC, 0x94, 0xCB, 0xA8, 0x68, 0x9B, 0xAF, 0x8A, 0x65, 0x27, + 0xCD, 0x89, 0xEE, 0xDD, 0x8C, 0xB5, 0x6B, 0x29, 0x70, 0x43, 0xA0, 0x69, + 0x0B, 0xE4, 0xB9, 0x0F +}; + +static const unsigned char TA539_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA540_DN[] = { + 0x30, 0x67, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x13, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA540_RSA_N[] = { + 0x93, 0x4B, 0xBB, 0xE9, 0x66, 0x8A, 0xEE, 0x9D, 0x5B, 0xD5, 0x34, 0x93, + 0xD0, 0x1B, 0x1E, 0xC3, 0xE7, 0x9E, 0xB8, 0x64, 0x33, 0x7F, 0x63, 0x78, + 0x68, 0xB4, 0xCD, 0x2E, 0x71, 0x75, 0xD7, 0x9B, 0x20, 0xC6, 0x4D, 0x29, + 0xBC, 0xB6, 0x68, 0x60, 0x8A, 0xF7, 0x21, 0x9A, 0x56, 0x35, 0x5A, 0xF3, + 0x76, 0xBD, 0xD8, 0xCD, 0x9A, 0xFF, 0x93, 0x56, 0x4B, 0xA5, 0x59, 0x06, + 0xA1, 0x93, 0x34, 0x29, 0xDD, 0x16, 0x34, 0x75, 0x4E, 0xF2, 0x81, 0xB4, + 0xC7, 0x96, 0x4E, 0xAD, 0x19, 0x15, 0x52, 0x4A, 0xFE, 0x3C, 0x70, 0x75, + 0x70, 0xCD, 0xAF, 0x2B, 0xAB, 0x15, 0x9A, 0x33, 0x3C, 0xAA, 0xB3, 0x8B, + 0xAA, 0xCD, 0x43, 0xFD, 0xF5, 0xEA, 0x70, 0xFF, 0xED, 0xCF, 0x11, 0x3B, + 0x94, 0xCE, 0x4E, 0x32, 0x16, 0xD3, 0x23, 0x40, 0x2A, 0x77, 0xB3, 0xAF, + 0x3C, 0x01, 0x2C, 0x6C, 0xED, 0x99, 0x2C, 0x8B, 0xD9, 0x4E, 0x69, 0x98, + 0xB2, 0xF7, 0x8F, 0x41, 0xB0, 0x32, 0x78, 0x61, 0xD6, 0x0D, 0x5F, 0xC3, + 0xFA, 0xA2, 0x40, 0x92, 0x1D, 0x5C, 0x17, 0xE6, 0x70, 0x3E, 0x35, 0xE7, + 0xA2, 0xB7, 0xC2, 0x62, 0xE2, 0xAB, 0xA4, 0x38, 0x4C, 0xB5, 0x39, 0x35, + 0x6F, 0xEA, 0x03, 0x69, 0xFA, 0x3A, 0x54, 0x68, 0x85, 0x6D, 0xD6, 0xF2, + 0x2F, 0x43, 0x55, 0x1E, 0x91, 0x0D, 0x0E, 0xD8, 0xD5, 0x6A, 0xA4, 0x96, + 0xD1, 0x13, 0x3C, 0x2C, 0x78, 0x50, 0xE8, 0x3A, 0x92, 0xD2, 0x17, 0x56, + 0xE5, 0x35, 0x1A, 0x40, 0x1C, 0x3E, 0x8D, 0x2C, 0xED, 0x39, 0xDF, 0x42, + 0xE0, 0x83, 0x41, 0x74, 0xDF, 0xA3, 0xCD, 0xC2, 0x86, 0x60, 0x48, 0x68, + 0xE3, 0x69, 0x0B, 0x54, 0x00, 0x8B, 0xE4, 0x76, 0x69, 0x21, 0x0D, 0x79, + 0x4E, 0x34, 0x08, 0x5E, 0x14, 0xC2, 0xCC, 0xB1, 0xB7, 0xAD, 0xD7, 0x7C, + 0x70, 0x8A, 0xC7, 0x85 +}; + +static const unsigned char TA540_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA541_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1A, 0x30, + 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA541_EC_Q[] = { + 0x04, 0x65, 0x50, 0x4A, 0xAE, 0x8C, 0x79, 0x96, 0x4A, 0xAA, 0x1C, 0x08, + 0xC3, 0xA3, 0xA2, 0xCD, 0xFE, 0x59, 0x56, 0x41, 0x77, 0xFD, 0x26, 0x94, + 0x42, 0xBB, 0x1D, 0xCD, 0x08, 0xDB, 0x73, 0xB2, 0x5B, 0x75, 0xF3, 0xCF, + 0x9C, 0x4E, 0x82, 0xF4, 0xBF, 0xF8, 0x61, 0x26, 0x85, 0x6C, 0xD6, 0x85, + 0x5B, 0x72, 0x70, 0xD2, 0xFD, 0xDB, 0x62, 0xB4, 0xDF, 0x53, 0x8B, 0xBD, + 0xB1, 0x44, 0x58, 0x62, 0x42, 0x09, 0xC7, 0xFA, 0x7F, 0x5B, 0x10, 0xE7, + 0xFE, 0x40, 0xFD, 0xC0, 0xD8, 0xC3, 0x2B, 0x32, 0xE7, 0x70, 0xA6, 0xB7, + 0xA6, 0x20, 0x55, 0x1D, 0x7B, 0x80, 0x5D, 0x4B, 0x8F, 0x67, 0x4C, 0xF1, + 0x10 +}; + +static const unsigned char TA542_DN[] = { + 0x30, 0x43, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, + 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0D, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA542_RSA_N[] = { + 0xBD, 0x55, 0x7C, 0x61, 0xD3, 0xB8, 0x1D, 0x04, 0x62, 0x05, 0xA0, 0xAE, + 0x6C, 0xB7, 0x70, 0xB4, 0x41, 0xEA, 0x4B, 0x03, 0x5E, 0x10, 0x3F, 0x90, + 0x5A, 0x1C, 0x8B, 0x3B, 0xB0, 0x66, 0x8B, 0x6C, 0x48, 0xA6, 0x1C, 0x22, + 0xBA, 0xD5, 0x40, 0x92, 0xEE, 0x33, 0xB2, 0x23, 0x59, 0xC9, 0x8E, 0xBC, + 0x58, 0xDA, 0x8B, 0x9E, 0xD0, 0x19, 0xF2, 0x2F, 0x59, 0xC6, 0x8C, 0x63, + 0x5A, 0xBA, 0x9F, 0xA3, 0x0B, 0xB0, 0xB3, 0x9A, 0x5C, 0xBA, 0x11, 0xB8, + 0x12, 0xE9, 0x0C, 0xBB, 0xCF, 0x6E, 0x6C, 0x80, 0x87, 0x29, 0x14, 0x03, + 0x2C, 0x8D, 0x24, 0x9A, 0xC8, 0x64, 0x83, 0xB5, 0x6A, 0xAC, 0x13, 0x2C, + 0x33, 0xF1, 0x9F, 0xDC, 0x2C, 0x61, 0x3C, 0x1A, 0x3F, 0x70, 0x55, 0x9B, + 0xAD, 0x00, 0x52, 0x7F, 0xCF, 0x04, 0xB9, 0xFE, 0x36, 0xFA, 0x9C, 0xC0, + 0x16, 0xAE, 0x62, 0xFE, 0x96, 0x4C, 0x43, 0x7E, 0x55, 0x14, 0xBE, 0x1A, + 0xB3, 0xD2, 0x6D, 0xC2, 0xAF, 0x76, 0x66, 0x95, 0x6B, 0x2A, 0xB0, 0x94, + 0x77, 0x85, 0x5E, 0x04, 0x0F, 0x62, 0x1D, 0x63, 0x75, 0xF7, 0x6B, 0xE7, + 0xCB, 0x5B, 0x9A, 0x70, 0xEC, 0x3E, 0x67, 0x05, 0xF0, 0xFE, 0x07, 0x08, + 0x80, 0xCF, 0x28, 0xDB, 0x05, 0xC6, 0x14, 0x27, 0x2F, 0x86, 0x7D, 0xF0, + 0x27, 0xDE, 0xFF, 0xE6, 0x7E, 0x33, 0x48, 0xE7, 0x0B, 0x1E, 0x58, 0xD1, + 0x27, 0x2B, 0x53, 0x0E, 0x57, 0x4A, 0x65, 0xD7, 0xFB, 0xA2, 0x80, 0x60, + 0xFC, 0x4C, 0xBC, 0x35, 0x53, 0x01, 0x6A, 0x97, 0x72, 0x82, 0xAF, 0xF1, + 0x1D, 0x70, 0xE8, 0x9C, 0xF5, 0xEF, 0x5E, 0xC2, 0x6C, 0xC7, 0x47, 0x7E, + 0x5A, 0x94, 0x85, 0x26, 0x4D, 0x3B, 0xBA, 0xEB, 0x4C, 0xE8, 0xB0, 0x09, + 0xC2, 0x65, 0xC2, 0x9D, 0x9D, 0x09, 0x9B, 0x4E, 0xB5, 0x97, 0x05, 0xAC, + 0xF5, 0x06, 0xA0, 0xF7, 0x36, 0x05, 0x7E, 0xF4, 0x90, 0xB2, 0x6B, 0xC4, + 0xB4, 0xF9, 0x64, 0xEA, 0xE9, 0x1A, 0x0A, 0xC8, 0x0D, 0xA8, 0xED, 0x27, + 0xC9, 0xD4, 0xE7, 0xB3, 0xB9, 0xAB, 0x82, 0x22, 0x90, 0x27, 0x3D, 0x2A, + 0xE8, 0x7C, 0x90, 0xEF, 0xBC, 0x4F, 0xFD, 0xE2, 0x0A, 0x24, 0xA7, 0xDE, + 0x65, 0x24, 0xA4, 0x5D, 0xEA, 0xC0, 0x76, 0x30, 0xD3, 0x77, 0x50, 0xF8, + 0x0D, 0x04, 0x9B, 0x94, 0x36, 0x01, 0x73, 0xCA, 0x06, 0x58, 0xA6, 0xD3, + 0x3B, 0xDC, 0xFA, 0x04, 0x46, 0x13, 0x55, 0x8A, 0xC9, 0x44, 0x47, 0xB8, + 0x51, 0x39, 0x1A, 0x2E, 0xE8, 0x34, 0xE2, 0x79, 0xCB, 0x59, 0x4A, 0x0A, + 0x7F, 0xBC, 0xA6, 0xEF, 0x1F, 0x03, 0x67, 0x6A, 0x59, 0x2B, 0x25, 0x62, + 0x93, 0xD9, 0x53, 0x19, 0x66, 0x3C, 0x27, 0x62, 0x29, 0x86, 0x4D, 0xA4, + 0x6B, 0xEE, 0xFF, 0xD4, 0x4E, 0xBA, 0xD5, 0xB4, 0xE2, 0x8E, 0x48, 0x5A, + 0x00, 0x19, 0x09, 0xF1, 0x05, 0xD9, 0xCE, 0x91, 0xB1, 0xF7, 0xEB, 0xE9, + 0x39, 0x4F, 0xF6, 0x6F, 0x04, 0x43, 0x9A, 0x55, 0xF5, 0x3E, 0x05, 0x14, + 0xBD, 0xBF, 0xB3, 0x59, 0xB4, 0xD8, 0x8E, 0x33, 0x84, 0xA3, 0x90, 0x52, + 0xAA, 0xB3, 0x02, 0x95, 0x60, 0xF9, 0x0C, 0x4C, 0x68, 0xF9, 0xEE, 0xD5, + 0x17, 0x0D, 0xF8, 0x71, 0x57, 0xB5, 0x25, 0xE4, 0x29, 0xEE, 0x65, 0x5D, + 0xAF, 0xD1, 0xEE, 0x3C, 0x17, 0x0B, 0x5A, 0x43, 0xC5, 0xA5, 0x86, 0xEA, + 0x24, 0x9E, 0xE2, 0x05, 0x07, 0xDC, 0x34, 0x42, 0x12, 0x91, 0xD6, 0x39, + 0x74, 0xAE, 0x4C, 0x41, 0x82, 0xDB, 0xF2, 0xA6, 0x48, 0xD1, 0xB3, 0x9B, + 0xF3, 0x33, 0xAA, 0xF3, 0xA6, 0xC0, 0xC5, 0x4E, 0xF5, 0xF4, 0x9D, 0x76, + 0x63, 0xE6, 0x02, 0xC6, 0x22, 0x4B, 0xC1, 0x95, 0x3F, 0x50, 0x64, 0x2C, + 0x54, 0xE5, 0xB6, 0xF0, 0x3C, 0x29, 0xCF, 0x57 +}; + +static const unsigned char TA542_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA543_DN[] = { + 0x30, 0x52, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x53, 0x4B, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x0A, 0x42, 0x72, 0x61, 0x74, 0x69, 0x73, 0x6C, 0x61, 0x76, 0x61, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x61, 0x2E, 0x73, 0x2E, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x41, 0x20, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x32 +}; + +static const unsigned char TA543_RSA_N[] = { + 0xA2, 0xA3, 0xC4, 0x00, 0x09, 0xD6, 0x85, 0x5D, 0x2D, 0x6D, 0x14, 0xF6, + 0xC2, 0xC3, 0x73, 0x9E, 0x35, 0xC2, 0x71, 0x55, 0x7E, 0x81, 0xFB, 0xAB, + 0x46, 0x50, 0xE0, 0xC1, 0x7C, 0x49, 0x78, 0xE6, 0xAB, 0x79, 0x58, 0x3C, + 0xDA, 0xFF, 0x7C, 0x1C, 0x9F, 0xD8, 0x97, 0x02, 0x78, 0x3E, 0x6B, 0x41, + 0x04, 0xE9, 0x41, 0xBD, 0xBE, 0x03, 0x2C, 0x45, 0xF6, 0x2F, 0x64, 0xD4, + 0xAB, 0x5D, 0xA3, 0x47, 0x3D, 0x64, 0x9B, 0xE9, 0x68, 0x9A, 0xC6, 0xCC, + 0x1B, 0x3F, 0xBA, 0xBE, 0xB2, 0x8B, 0x34, 0x02, 0x2E, 0x98, 0x55, 0x19, + 0xFC, 0x8C, 0x6F, 0xAA, 0x5F, 0xDA, 0x4C, 0xCE, 0x4D, 0x03, 0x21, 0xA3, + 0xD8, 0xD2, 0x34, 0x93, 0x56, 0x96, 0xCB, 0x4C, 0x0C, 0x00, 0x16, 0x3C, + 0x5F, 0x1A, 0xCD, 0xC8, 0xC7, 0x6C, 0xA6, 0xAD, 0xD3, 0x31, 0xA7, 0xBC, + 0xE8, 0xE5, 0xE1, 0x66, 0xD6, 0xD2, 0xFB, 0x03, 0xB4, 0x41, 0x65, 0xC9, + 0x10, 0xAE, 0x0E, 0x05, 0x63, 0xC6, 0x80, 0x6A, 0x69, 0x30, 0xFD, 0xD2, + 0xEE, 0x90, 0xEF, 0x0D, 0x27, 0xDF, 0x9F, 0x95, 0x73, 0xF4, 0xE1, 0x25, + 0xDA, 0x6C, 0x16, 0xDE, 0x41, 0x38, 0x34, 0xEA, 0x8B, 0xFC, 0xD1, 0xE8, + 0x04, 0x14, 0x61, 0x2D, 0x41, 0x7E, 0xAC, 0xC7, 0x77, 0x4E, 0xCB, 0x51, + 0x54, 0xFB, 0x5E, 0x92, 0x18, 0x1B, 0x04, 0x5A, 0x68, 0xC6, 0xC9, 0xC4, + 0xFA, 0xB7, 0x13, 0xA0, 0x98, 0xB7, 0x11, 0x2B, 0xB7, 0xD6, 0x57, 0xCC, + 0x7C, 0x9E, 0x17, 0xD1, 0xCB, 0x25, 0xFE, 0x86, 0x4E, 0x24, 0x2E, 0x56, + 0x0C, 0x78, 0x4D, 0x9E, 0x01, 0x12, 0xA6, 0x2B, 0xA7, 0x01, 0x65, 0x6E, + 0x7C, 0x62, 0x1D, 0x84, 0x84, 0xDF, 0xEA, 0xC0, 0x6B, 0xB5, 0xA5, 0x2A, + 0x95, 0x83, 0xC3, 0x53, 0x11, 0x0C, 0x73, 0x1D, 0x0B, 0xB2, 0x46, 0x90, + 0xD1, 0x42, 0x3A, 0xCE, 0x40, 0x6E, 0x95, 0xAD, 0xFF, 0xC6, 0x94, 0xAD, + 0x6E, 0x97, 0x84, 0x8E, 0x7D, 0x6F, 0x9E, 0x8A, 0x80, 0x0D, 0x49, 0x6D, + 0x73, 0xE2, 0x7B, 0x92, 0x1E, 0xC3, 0xF3, 0xC1, 0xF3, 0xEB, 0x2E, 0x05, + 0x6F, 0xD9, 0x1B, 0xCF, 0x37, 0x76, 0x04, 0xC8, 0xB4, 0x5A, 0xE4, 0x17, + 0xA7, 0xCB, 0xDD, 0x76, 0x1F, 0xD0, 0x19, 0x76, 0xE8, 0x2C, 0x05, 0xB3, + 0xD6, 0x9C, 0x34, 0xD8, 0x96, 0xDC, 0x61, 0x87, 0x91, 0x05, 0xE4, 0x44, + 0x08, 0x33, 0xC1, 0xDA, 0xB9, 0x08, 0x65, 0xD4, 0xAE, 0xB2, 0x36, 0x0D, + 0xEB, 0xBA, 0x38, 0xBA, 0x0C, 0xE5, 0x9B, 0x9E, 0xEB, 0x8D, 0x66, 0xDD, + 0x99, 0xCF, 0xD6, 0x89, 0x41, 0xF6, 0x04, 0x92, 0x8A, 0x29, 0x29, 0x6D, + 0x6B, 0x3A, 0x1C, 0xE7, 0x75, 0x7D, 0x02, 0x71, 0x0E, 0xF3, 0xC0, 0xE7, + 0xBD, 0xCB, 0x19, 0xDD, 0x9D, 0x60, 0xB2, 0xC2, 0x66, 0x60, 0xB6, 0xB1, + 0x04, 0xEE, 0xC9, 0xE6, 0x86, 0xB9, 0x9A, 0x66, 0x40, 0xA8, 0xE7, 0x11, + 0xED, 0x81, 0x45, 0x03, 0x8B, 0xF6, 0x67, 0x59, 0xE8, 0xC1, 0x06, 0x11, + 0xBD, 0xDD, 0xCF, 0x80, 0x02, 0x4F, 0x65, 0x40, 0x78, 0x5C, 0x47, 0x50, + 0xC8, 0x9B, 0xE6, 0x1F, 0x81, 0x7B, 0xE4, 0x44, 0xA8, 0x5B, 0x85, 0x9A, + 0xE2, 0xDE, 0x5A, 0xD5, 0xC7, 0xF9, 0x3A, 0x44, 0x66, 0x4B, 0xE4, 0x32, + 0x54, 0x7C, 0xE4, 0x6C, 0x9C, 0xB3, 0x0E, 0x3D, 0x17, 0xA2, 0xB2, 0x34, + 0x12, 0xD6, 0x7E, 0xB2, 0xA8, 0x49, 0xBB, 0xD1, 0x7A, 0x28, 0x40, 0xBE, + 0xA2, 0x16, 0x1F, 0xDF, 0xE4, 0x37, 0x1F, 0x11, 0x73, 0xFB, 0x90, 0x0A, + 0x65, 0x43, 0xA2, 0x0D, 0x7C, 0xF8, 0x06, 0x01, 0x55, 0x33, 0x7D, 0xB0, + 0x0D, 0xB8, 0xF4, 0xF5, 0xAE, 0xA5, 0x42, 0x57, 0x7C, 0x36, 0x11, 0x8C, + 0x7B, 0x5E, 0xC4, 0x03, 0x9D, 0x8C, 0x79, 0x9D +}; + +static const unsigned char TA543_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA544_DN[] = { + 0x30, 0x81, 0x80, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, + 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x24, 0x30, + 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x43, 0x65, 0x72, 0x74, + 0x75, 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, + 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA544_RSA_N[] = { + 0xBD, 0xF9, 0x78, 0xF8, 0xE6, 0xD5, 0x80, 0x0C, 0x64, 0x9D, 0x86, 0x1B, + 0x96, 0x64, 0x67, 0x3F, 0x22, 0x3A, 0x1E, 0x75, 0x01, 0x7D, 0xEF, 0xFB, + 0x5C, 0x67, 0x8C, 0xC9, 0xCC, 0x5C, 0x6B, 0xA9, 0x91, 0xE6, 0xB9, 0x42, + 0xE5, 0x20, 0x4B, 0x9B, 0xDA, 0x9B, 0x7B, 0xB9, 0x99, 0x5D, 0xD9, 0x9B, + 0x80, 0x4B, 0xD7, 0x84, 0x40, 0x2B, 0x27, 0xD3, 0xE8, 0xBA, 0x30, 0xBB, + 0x3E, 0x09, 0x1A, 0xA7, 0x49, 0x95, 0xEF, 0x2B, 0x40, 0x24, 0xC2, 0x97, + 0xC7, 0xA7, 0xEE, 0x9B, 0x25, 0xEF, 0xA8, 0x0A, 0x00, 0x97, 0x85, 0x5A, + 0xAA, 0x9D, 0xDC, 0x29, 0xC9, 0xE2, 0x35, 0x07, 0xEB, 0x70, 0x4D, 0x4A, + 0xD6, 0xC1, 0xB3, 0x56, 0xB8, 0xA1, 0x41, 0x38, 0x9B, 0xD1, 0xFB, 0x31, + 0x7F, 0x8F, 0xE0, 0x5F, 0xE1, 0xB1, 0x3F, 0x0F, 0x8E, 0x16, 0x49, 0x60, + 0xD7, 0x06, 0x8D, 0x18, 0xF9, 0xAA, 0x26, 0x10, 0xAB, 0x2A, 0xD3, 0xD0, + 0xD1, 0x67, 0x8D, 0x1B, 0x46, 0xBE, 0x47, 0x30, 0xD5, 0x2E, 0x72, 0xD1, + 0xC5, 0x63, 0xDA, 0xE7, 0x63, 0x79, 0x44, 0x7E, 0x4B, 0x63, 0x24, 0x89, + 0x86, 0x2E, 0x34, 0x3F, 0x29, 0x4C, 0x52, 0x8B, 0x2A, 0xA7, 0xC0, 0xE2, + 0x91, 0x28, 0x89, 0xB9, 0xC0, 0x5B, 0xF9, 0x1D, 0xD9, 0xE7, 0x27, 0xAD, + 0xFF, 0x9A, 0x02, 0x97, 0xC1, 0xC6, 0x50, 0x92, 0x9B, 0x02, 0x2C, 0xBD, + 0xA9, 0xB9, 0x34, 0x59, 0x0A, 0xBF, 0x84, 0x4A, 0xFF, 0xDF, 0xFE, 0xB3, + 0x9F, 0xEB, 0xD9, 0x9E, 0xE0, 0x98, 0x23, 0xEC, 0xA6, 0x6B, 0x77, 0x16, + 0x2A, 0xDB, 0xCC, 0xAD, 0x3B, 0x1C, 0xA4, 0x87, 0xDC, 0x46, 0x73, 0x5E, + 0x19, 0x62, 0x68, 0x45, 0x57, 0xE4, 0x90, 0x82, 0x42, 0xBB, 0x42, 0xD6, + 0xF0, 0x61, 0xE0, 0xC1, 0xA3, 0x3D, 0x66, 0xA3, 0x5D, 0xF4, 0x18, 0xEE, + 0x88, 0xC9, 0x8D, 0x17, 0x45, 0x29, 0x99, 0x32, 0x75, 0x02, 0x31, 0xEE, + 0x29, 0x26, 0xC8, 0x6B, 0x02, 0xE6, 0xB5, 0x62, 0x45, 0x7F, 0x37, 0x15, + 0x5A, 0x23, 0x68, 0x89, 0xD4, 0x3E, 0xDE, 0x4E, 0x27, 0xB0, 0xF0, 0x40, + 0x0C, 0xBC, 0x4D, 0x17, 0xCB, 0x4D, 0xA2, 0xB3, 0x1E, 0xD0, 0x06, 0x5A, + 0xDD, 0xF6, 0x93, 0xCF, 0x57, 0x75, 0x99, 0xF5, 0xFA, 0x86, 0x1A, 0x67, + 0x78, 0xB3, 0xBF, 0x96, 0xFE, 0x34, 0xDC, 0xBD, 0xE7, 0x52, 0x56, 0xE5, + 0xB3, 0xE5, 0x75, 0x7B, 0xD7, 0x41, 0x91, 0x05, 0xDC, 0x5D, 0x69, 0xE3, + 0x95, 0x0D, 0x43, 0xB9, 0xFC, 0x83, 0x96, 0x39, 0x95, 0x7B, 0x6C, 0x80, + 0x5A, 0x4F, 0x13, 0x72, 0xC6, 0xD7, 0x7D, 0x29, 0x7A, 0x44, 0xBA, 0x52, + 0xA4, 0x2A, 0xD5, 0x41, 0x46, 0x09, 0x20, 0xFE, 0x22, 0xA0, 0xB6, 0x5B, + 0x30, 0x8D, 0xBC, 0x89, 0x0C, 0xD5, 0xD7, 0x70, 0xF8, 0x87, 0x52, 0xFD, + 0xDA, 0xEF, 0xAC, 0x51, 0x2E, 0x07, 0xB3, 0x4E, 0xFE, 0xD0, 0x09, 0xDA, + 0x70, 0xEF, 0x98, 0xFA, 0x56, 0xE6, 0x6D, 0xDB, 0xB5, 0x57, 0x4B, 0xDC, + 0xE5, 0x2C, 0x25, 0x15, 0xC8, 0x9E, 0x2E, 0x78, 0x4E, 0xF8, 0xDA, 0x9C, + 0x9E, 0x86, 0x2C, 0xCA, 0x57, 0xF3, 0x1A, 0xE5, 0xC8, 0x92, 0x8B, 0x1A, + 0x82, 0x96, 0x7A, 0xC3, 0xBC, 0x50, 0x12, 0x69, 0xD8, 0x0E, 0x5A, 0x46, + 0x8B, 0x3A, 0xEB, 0x26, 0xFA, 0x23, 0xC9, 0xB6, 0xB0, 0x81, 0xBE, 0x42, + 0x00, 0xA4, 0xF8, 0xD6, 0xFE, 0x30, 0x2E, 0xC7, 0xD2, 0x46, 0xF6, 0xE5, + 0x8E, 0x75, 0xFD, 0xF2, 0xCC, 0xB9, 0xD0, 0x87, 0x5B, 0xCC, 0x06, 0x10, + 0x60, 0xBB, 0x83, 0x35, 0xB7, 0x5E, 0x67, 0xDE, 0x47, 0xEC, 0x99, 0x48, + 0xF1, 0xA4, 0xA1, 0x15, 0xFE, 0xAD, 0x8C, 0x62, 0x8E, 0x39, 0x55, 0x4F, + 0x39, 0x16, 0xB9, 0xB1, 0x63, 0x9D, 0xFF, 0xB7 +}; + +static const unsigned char TA544_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA545_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA545_EC_Q[] = { + 0x04, 0x45, 0x29, 0x35, 0x73, 0xFA, 0xC2, 0xB8, 0x23, 0xCE, 0x14, 0x7D, + 0xA8, 0xB1, 0x4D, 0xA0, 0x5B, 0x36, 0xEE, 0x2A, 0x2C, 0x53, 0xC3, 0x60, + 0x09, 0x35, 0xB2, 0x24, 0x66, 0x26, 0x69, 0xC0, 0xB3, 0x95, 0xD6, 0x5D, + 0x92, 0x40, 0x19, 0x0E, 0xC6, 0xA5, 0x13, 0x70, 0xF4, 0xEF, 0x12, 0x51, + 0x28, 0x5D, 0xE7, 0xCC, 0xBD, 0xF9, 0x3C, 0x85, 0xC1, 0xCF, 0x94, 0x90, + 0xC9, 0x2B, 0xCE, 0x92, 0x42, 0x58, 0x59, 0x67, 0xFD, 0x94, 0x27, 0x10, + 0x64, 0x8C, 0x4F, 0x04, 0xB1, 0x4D, 0x49, 0xE4, 0x7B, 0x4F, 0x9B, 0xF5, + 0xE7, 0x08, 0xF8, 0x03, 0x88, 0xF7, 0xA7, 0xC3, 0x92, 0x4B, 0x19, 0x54, + 0x81 +}; + +static const unsigned char TA546_DN[] = { + 0x30, 0x81, 0x83, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x1A, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, 0x47, 0x6F, 0x44, 0x61, 0x64, 0x64, + 0x79, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, + 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6F, + 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA546_RSA_N[] = { + 0xBF, 0x71, 0x62, 0x08, 0xF1, 0xFA, 0x59, 0x34, 0xF7, 0x1B, 0xC9, 0x18, + 0xA3, 0xF7, 0x80, 0x49, 0x58, 0xE9, 0x22, 0x83, 0x13, 0xA6, 0xC5, 0x20, + 0x43, 0x01, 0x3B, 0x84, 0xF1, 0xE6, 0x85, 0x49, 0x9F, 0x27, 0xEA, 0xF6, + 0x84, 0x1B, 0x4E, 0xA0, 0xB4, 0xDB, 0x70, 0x98, 0xC7, 0x32, 0x01, 0xB1, + 0x05, 0x3E, 0x07, 0x4E, 0xEE, 0xF4, 0xFA, 0x4F, 0x2F, 0x59, 0x30, 0x22, + 0xE7, 0xAB, 0x19, 0x56, 0x6B, 0xE2, 0x80, 0x07, 0xFC, 0xF3, 0x16, 0x75, + 0x80, 0x39, 0x51, 0x7B, 0xE5, 0xF9, 0x35, 0xB6, 0x74, 0x4E, 0xA9, 0x8D, + 0x82, 0x13, 0xE4, 0xB6, 0x3F, 0xA9, 0x03, 0x83, 0xFA, 0xA2, 0xBE, 0x8A, + 0x15, 0x6A, 0x7F, 0xDE, 0x0B, 0xC3, 0xB6, 0x19, 0x14, 0x05, 0xCA, 0xEA, + 0xC3, 0xA8, 0x04, 0x94, 0x3B, 0x46, 0x7C, 0x32, 0x0D, 0xF3, 0x00, 0x66, + 0x22, 0xC8, 0x8D, 0x69, 0x6D, 0x36, 0x8C, 0x11, 0x18, 0xB7, 0xD3, 0xB2, + 0x1C, 0x60, 0xB4, 0x38, 0xFA, 0x02, 0x8C, 0xCE, 0xD3, 0xDD, 0x46, 0x07, + 0xDE, 0x0A, 0x3E, 0xEB, 0x5D, 0x7C, 0xC8, 0x7C, 0xFB, 0xB0, 0x2B, 0x53, + 0xA4, 0x92, 0x62, 0x69, 0x51, 0x25, 0x05, 0x61, 0x1A, 0x44, 0x81, 0x8C, + 0x2C, 0xA9, 0x43, 0x96, 0x23, 0xDF, 0xAC, 0x3A, 0x81, 0x9A, 0x0E, 0x29, + 0xC5, 0x1C, 0xA9, 0xE9, 0x5D, 0x1E, 0xB6, 0x9E, 0x9E, 0x30, 0x0A, 0x39, + 0xCE, 0xF1, 0x88, 0x80, 0xFB, 0x4B, 0x5D, 0xCC, 0x32, 0xEC, 0x85, 0x62, + 0x43, 0x25, 0x34, 0x02, 0x56, 0x27, 0x01, 0x91, 0xB4, 0x3B, 0x70, 0x2A, + 0x3F, 0x6E, 0xB1, 0xE8, 0x9C, 0x88, 0x01, 0x7D, 0x9F, 0xD4, 0xF9, 0xDB, + 0x53, 0x6D, 0x60, 0x9D, 0xBF, 0x2C, 0xE7, 0x58, 0xAB, 0xB8, 0x5F, 0x46, + 0xFC, 0xCE, 0xC4, 0x1B, 0x03, 0x3C, 0x09, 0xEB, 0x49, 0x31, 0x5C, 0x69, + 0x46, 0xB3, 0xE0, 0x47 +}; + +static const unsigned char TA546_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA547_DN[] = { + 0x30, 0x38, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x49, 0x5A, 0x45, 0x4E, 0x50, 0x45, 0x20, 0x53, 0x2E, 0x41, + 0x2E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0A, + 0x49, 0x7A, 0x65, 0x6E, 0x70, 0x65, 0x2E, 0x63, 0x6F, 0x6D +}; + +static const unsigned char TA547_RSA_N[] = { + 0xC9, 0xD3, 0x7A, 0xCA, 0x0F, 0x1E, 0xAC, 0xA7, 0x86, 0xE8, 0x16, 0x65, + 0x6A, 0xB1, 0xC2, 0x1B, 0x45, 0x32, 0x71, 0x95, 0xD9, 0xFE, 0x10, 0x5B, + 0xCC, 0xAF, 0xE7, 0xA5, 0x79, 0x01, 0x8F, 0x89, 0xC3, 0xCA, 0xF2, 0x55, + 0x71, 0xF7, 0x77, 0xBE, 0x77, 0x94, 0xF3, 0x72, 0xA4, 0x2C, 0x44, 0xD8, + 0x9E, 0x92, 0x9B, 0x14, 0x3A, 0xA1, 0xE7, 0x24, 0x90, 0x0A, 0x0A, 0x56, + 0x8E, 0xC5, 0xD8, 0x26, 0x94, 0xE1, 0xD9, 0x48, 0xE1, 0x2D, 0x3E, 0xDA, + 0x0A, 0x72, 0xDD, 0xA3, 0x99, 0x15, 0xDA, 0x81, 0xA2, 0x87, 0xF4, 0x7B, + 0x6E, 0x26, 0x77, 0x89, 0x58, 0xAD, 0xD6, 0xEB, 0x0C, 0xB2, 0x41, 0x7A, + 0x73, 0x6E, 0x6D, 0xDB, 0x7A, 0x78, 0x41, 0xE9, 0x08, 0x88, 0x12, 0x7E, + 0x87, 0x2E, 0x66, 0x11, 0x63, 0x6C, 0x54, 0xFB, 0x3C, 0x9D, 0x72, 0xC0, + 0xBC, 0x2E, 0xFF, 0xC2, 0xB7, 0xDD, 0x0D, 0x76, 0xE3, 0x3A, 0xD7, 0xF7, + 0xB4, 0x68, 0xBE, 0xA2, 0xF5, 0xE3, 0x81, 0x6E, 0xC1, 0x46, 0x6F, 0x5D, + 0x8D, 0xE0, 0x4D, 0xC6, 0x54, 0x55, 0x89, 0x1A, 0x33, 0x31, 0x0A, 0xB1, + 0x57, 0xB9, 0xA3, 0x8A, 0x98, 0xC3, 0xEC, 0x3B, 0x34, 0xC5, 0x95, 0x41, + 0x69, 0x7E, 0x75, 0xC2, 0x3C, 0x20, 0xC5, 0x61, 0xBA, 0x51, 0x47, 0xA0, + 0x20, 0x90, 0x93, 0xA1, 0x90, 0x4B, 0xF3, 0x4E, 0x7C, 0x85, 0x45, 0x54, + 0x9A, 0xD1, 0x05, 0x26, 0x41, 0xB0, 0xB5, 0x4D, 0x1D, 0x33, 0xBE, 0xC4, + 0x03, 0xC8, 0x25, 0x7C, 0xC1, 0x70, 0xDB, 0x3B, 0xF4, 0x09, 0x2D, 0x54, + 0x27, 0x48, 0xAC, 0x2F, 0xE1, 0xC4, 0xAC, 0x3E, 0xC8, 0xCB, 0x92, 0x4C, + 0x53, 0x39, 0x37, 0x23, 0xEC, 0xD3, 0x01, 0xF9, 0xE0, 0x09, 0x44, 0x4D, + 0x4D, 0x64, 0xC0, 0xE1, 0x0D, 0x5A, 0x87, 0x22, 0xBC, 0xAD, 0x1B, 0xA3, + 0xFE, 0x26, 0xB5, 0x15, 0xF3, 0xA7, 0xFC, 0x84, 0x19, 0xE9, 0xEC, 0xA1, + 0x88, 0xB4, 0x44, 0x69, 0x84, 0x83, 0xF3, 0x89, 0xD1, 0x74, 0x06, 0xA9, + 0xCC, 0x0B, 0xD6, 0xC2, 0xDE, 0x27, 0x85, 0x50, 0x26, 0xCA, 0x17, 0xB8, + 0xC9, 0x7A, 0x87, 0x56, 0x2C, 0x1A, 0x01, 0x1E, 0x6C, 0xBE, 0x13, 0xAD, + 0x10, 0xAC, 0xB5, 0x24, 0xF5, 0x38, 0x91, 0xA1, 0xD6, 0x4B, 0xDA, 0xF1, + 0xBB, 0xD2, 0xDE, 0x47, 0xB5, 0xF1, 0xBC, 0x81, 0xF6, 0x59, 0x6B, 0xCF, + 0x19, 0x53, 0xE9, 0x8D, 0x15, 0xCB, 0x4A, 0xCB, 0xA9, 0x6F, 0x44, 0xE5, + 0x1B, 0x41, 0xCF, 0xE1, 0x86, 0xA7, 0xCA, 0xD0, 0x6A, 0x9F, 0xBC, 0x4C, + 0x8D, 0x06, 0x33, 0x5A, 0xA2, 0x85, 0xE5, 0x90, 0x35, 0xA0, 0x62, 0x5C, + 0x16, 0x4E, 0xF0, 0xE3, 0xA2, 0xFA, 0x03, 0x1A, 0xB4, 0x2C, 0x71, 0xB3, + 0x58, 0x2C, 0xDE, 0x7B, 0x0B, 0xDB, 0x1A, 0x0F, 0xEB, 0xDE, 0x21, 0x1F, + 0x06, 0x77, 0x06, 0x03, 0xB0, 0xC9, 0xEF, 0x99, 0xFC, 0xC0, 0xB9, 0x4F, + 0x0B, 0x86, 0x28, 0xFE, 0xD2, 0xB9, 0xEA, 0xE3, 0xDA, 0xA5, 0xC3, 0x47, + 0x69, 0x12, 0xE0, 0xDB, 0xF0, 0xF6, 0x19, 0x8B, 0xED, 0x7B, 0x70, 0xD7, + 0x02, 0xD6, 0xED, 0x87, 0x18, 0x28, 0x2C, 0x04, 0x24, 0x4C, 0x77, 0xE4, + 0x48, 0x8A, 0x1A, 0xC6, 0x3B, 0x9A, 0xD4, 0x0F, 0xCA, 0xFA, 0x75, 0xD2, + 0x01, 0x40, 0x5A, 0x8D, 0x79, 0xBF, 0x8B, 0xCF, 0x4B, 0xCF, 0xAA, 0x16, + 0xC1, 0x95, 0xE4, 0xAD, 0x4C, 0x8A, 0x3E, 0x17, 0x91, 0xD4, 0xB1, 0x62, + 0xE5, 0x82, 0xE5, 0x80, 0x04, 0xA4, 0x03, 0x7E, 0x8D, 0xBF, 0xDA, 0x7F, + 0xA2, 0x0F, 0x97, 0x4F, 0x0C, 0xD3, 0x0D, 0xFB, 0xD7, 0xD1, 0xE5, 0x72, + 0x7E, 0x1C, 0xC8, 0x77, 0xFF, 0x5B, 0x9A, 0x0F, 0xB7, 0xAE, 0x05, 0x46, + 0xE5, 0xF1, 0xA8, 0x16, 0xEC, 0x47, 0xA4, 0x17 +}; + +static const unsigned char TA547_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA548_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA548_EC_Q[] = { + 0x04, 0x0D, 0x30, 0x5E, 0x1B, 0x15, 0x9D, 0x03, 0xD0, 0xA1, 0x79, 0x35, + 0xB7, 0x3A, 0x3C, 0x92, 0x7A, 0xCA, 0x15, 0x1C, 0xCD, 0x62, 0xF3, 0x9C, + 0x26, 0x5C, 0x07, 0x3D, 0xE5, 0x54, 0xFA, 0xA3, 0xD6, 0xCC, 0x12, 0xEA, + 0xF4, 0x14, 0x5F, 0xE8, 0x8E, 0x19, 0xAB, 0x2F, 0x2E, 0x48, 0xE6, 0xAC, + 0x18, 0x43, 0x78, 0xAC, 0xD0, 0x37, 0xC3, 0xBD, 0xB2, 0xCD, 0x2C, 0xE6, + 0x47, 0xE2, 0x1A, 0xE6, 0x63, 0xB8, 0x3D, 0x2E, 0x2F, 0x78, 0xC4, 0x4F, + 0xDB, 0xF4, 0x0F, 0xA4, 0x68, 0x4C, 0x55, 0x72, 0x6B, 0x95, 0x1D, 0x4E, + 0x18, 0x42, 0x95, 0x78, 0xCC, 0x37, 0x3C, 0x91, 0xE2, 0x9B, 0x65, 0x2B, + 0x29 +}; + +static const unsigned char TA549_DN[] = { + 0x30, 0x5D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x1E, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA549_RSA_N[] = { + 0xD0, 0x15, 0x39, 0x52, 0xB1, 0x52, 0xB3, 0xBA, 0xC5, 0x59, 0x82, 0xC4, + 0x5D, 0x52, 0xAE, 0x3A, 0x43, 0x65, 0x80, 0x4B, 0xC7, 0xF2, 0x96, 0xBC, + 0xDB, 0x36, 0x97, 0xD6, 0xA6, 0x64, 0x8C, 0xA8, 0x5E, 0xF0, 0xE3, 0x0A, + 0x1C, 0xF7, 0xDF, 0x97, 0x3D, 0x4B, 0xAE, 0xF6, 0x5D, 0xEC, 0x21, 0xB5, + 0x41, 0xAB, 0xCD, 0xB9, 0x7E, 0x76, 0x9F, 0xBE, 0xF9, 0x3E, 0x36, 0x34, + 0xA0, 0x3B, 0xC1, 0xF6, 0x31, 0x11, 0x45, 0x74, 0x93, 0x3D, 0x57, 0x80, + 0xC5, 0xF9, 0x89, 0x99, 0xCA, 0xE5, 0xAB, 0x6A, 0xD4, 0xB5, 0xDA, 0x41, + 0x90, 0x10, 0xC1, 0xD6, 0xD6, 0x42, 0x89, 0xC2, 0xBF, 0xF4, 0x38, 0x12, + 0x95, 0x4C, 0x54, 0x05, 0xF7, 0x36, 0xE4, 0x45, 0x83, 0x7B, 0x14, 0x65, + 0xD6, 0xDC, 0x0C, 0x4D, 0xD1, 0xDE, 0x7E, 0x0C, 0xAB, 0x3B, 0xC4, 0x15, + 0xBE, 0x3A, 0x56, 0xA6, 0x5A, 0x6F, 0x76, 0x69, 0x52, 0xA9, 0x7A, 0xB9, + 0xC8, 0xEB, 0x6A, 0x9A, 0x5D, 0x52, 0xD0, 0x2D, 0x0A, 0x6B, 0x35, 0x16, + 0x09, 0x10, 0x84, 0xD0, 0x6A, 0xCA, 0x3A, 0x06, 0x00, 0x37, 0x47, 0xE4, + 0x7E, 0x57, 0x4F, 0x3F, 0x8B, 0xEB, 0x67, 0xB8, 0x88, 0xAA, 0xC5, 0xBE, + 0x53, 0x55, 0xB2, 0x91, 0xC4, 0x7D, 0xB9, 0xB0, 0x85, 0x19, 0x06, 0x78, + 0x2E, 0xDB, 0x61, 0x1A, 0xFA, 0x85, 0xF5, 0x4A, 0x91, 0xA1, 0xE7, 0x16, + 0xD5, 0x8E, 0xA2, 0x39, 0xDF, 0x94, 0xB8, 0x70, 0x1F, 0x28, 0x3F, 0x8B, + 0xFC, 0x40, 0x5E, 0x63, 0x83, 0x3C, 0x83, 0x2A, 0x1A, 0x99, 0x6B, 0xCF, + 0xDE, 0x59, 0x6A, 0x3B, 0xFC, 0x6F, 0x16, 0xD7, 0x1F, 0xFD, 0x4A, 0x10, + 0xEB, 0x4E, 0x82, 0x16, 0x3A, 0xAC, 0x27, 0x0C, 0x53, 0xF1, 0xAD, 0xD5, + 0x24, 0xB0, 0x6B, 0x03, 0x50, 0xC1, 0x2D, 0x3C, 0x16, 0xDD, 0x44, 0x34, + 0x27, 0x1A, 0x75, 0xFB +}; + +static const unsigned char TA549_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA550_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x41, 0x43, 0x20, + 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, + 0x4D +}; + +static const unsigned char TA550_RSA_N[] = { + 0xBA, 0x71, 0x80, 0x7A, 0x4C, 0x86, 0x6E, 0x7F, 0xC8, 0x13, 0x6D, 0xC0, + 0xC6, 0x7D, 0x1C, 0x00, 0x97, 0x8F, 0x2C, 0x0C, 0x23, 0xBB, 0x10, 0x9A, + 0x40, 0xA9, 0x1A, 0xB7, 0x87, 0x88, 0xF8, 0x9B, 0x56, 0x6A, 0xFB, 0xE6, + 0x7B, 0x8E, 0x8B, 0x92, 0x8E, 0xA7, 0x25, 0x5D, 0x59, 0x11, 0xDB, 0x36, + 0x2E, 0xB7, 0x51, 0x17, 0x1F, 0xA9, 0x08, 0x1F, 0x04, 0x17, 0x24, 0x58, + 0xAA, 0x37, 0x4A, 0x18, 0xDF, 0xE5, 0x39, 0xD4, 0x57, 0xFD, 0xD7, 0xC1, + 0x2C, 0x91, 0x01, 0x91, 0xE2, 0x22, 0xD4, 0x03, 0xC0, 0x58, 0xFC, 0x77, + 0x47, 0xEC, 0x8F, 0x3E, 0x74, 0x43, 0xBA, 0xAC, 0x34, 0x8D, 0x4D, 0x38, + 0x76, 0x67, 0x8E, 0xB0, 0xC8, 0x6F, 0x30, 0x33, 0x58, 0x71, 0x5C, 0xB4, + 0xF5, 0x6B, 0x6E, 0xD4, 0x01, 0x50, 0xB8, 0x13, 0x7E, 0x6C, 0x4A, 0xA3, + 0x49, 0xD1, 0x20, 0x19, 0xEE, 0xBC, 0xC0, 0x29, 0x18, 0x65, 0xA7, 0xDE, + 0xFE, 0xEF, 0xDD, 0x0A, 0x90, 0x21, 0xE7, 0x1A, 0x67, 0x92, 0x42, 0x10, + 0x98, 0x5F, 0x4F, 0x30, 0xBC, 0x3E, 0x1C, 0x45, 0xB4, 0x10, 0xD7, 0x68, + 0x40, 0x14, 0xC0, 0x40, 0xFA, 0xE7, 0x77, 0x17, 0x7A, 0xE6, 0x0B, 0x8F, + 0x65, 0x5B, 0x3C, 0xD9, 0x9A, 0x52, 0xDB, 0xB5, 0xBD, 0x9E, 0x46, 0xCF, + 0x3D, 0xEB, 0x91, 0x05, 0x02, 0xC0, 0x96, 0xB2, 0x76, 0x4C, 0x4D, 0x10, + 0x96, 0x3B, 0x92, 0xFA, 0x9C, 0x7F, 0x0F, 0x99, 0xDF, 0xBE, 0x23, 0x35, + 0x45, 0x1E, 0x02, 0x5C, 0xFE, 0xB5, 0xA8, 0x9B, 0x99, 0x25, 0xDA, 0x5E, + 0xF3, 0x22, 0xC3, 0x39, 0xF5, 0xE4, 0x2A, 0x2E, 0xD3, 0xC6, 0x1F, 0xC4, + 0x6C, 0xAA, 0xC5, 0x1C, 0x6A, 0x01, 0x05, 0x4A, 0x2F, 0xD2, 0xC5, 0xC1, + 0xA8, 0x34, 0x26, 0x5D, 0x66, 0xA5, 0xD2, 0x02, 0x21, 0xF9, 0x18, 0xB7, + 0x06, 0xF5, 0x4E, 0x99, 0x6F, 0xA8, 0xAB, 0x4C, 0x51, 0xE8, 0xCF, 0x50, + 0x18, 0xC5, 0x77, 0xC8, 0x39, 0x09, 0x2C, 0x49, 0x92, 0x32, 0x99, 0xA8, + 0xBB, 0x17, 0x17, 0x79, 0xB0, 0x5A, 0xC5, 0xE6, 0xA3, 0xC4, 0x59, 0x65, + 0x47, 0x35, 0x83, 0x5E, 0xA9, 0xE8, 0x35, 0x0B, 0x99, 0xBB, 0xE4, 0xCD, + 0x20, 0xC6, 0x9B, 0x4A, 0x06, 0x39, 0xB5, 0x68, 0xFC, 0x22, 0xBA, 0xEE, + 0x55, 0x8C, 0x2B, 0x4E, 0xEA, 0xF3, 0xB1, 0xE3, 0xFC, 0xB6, 0x99, 0x9A, + 0xD5, 0x42, 0xFA, 0x71, 0x4D, 0x08, 0xCF, 0x87, 0x1E, 0x6A, 0x71, 0x7D, + 0xF9, 0xD3, 0xB4, 0xE9, 0xA5, 0x71, 0x81, 0x7B, 0xC2, 0x4E, 0x47, 0x96, + 0xA5, 0xF6, 0x76, 0x85, 0xA3, 0x28, 0x8F, 0xE9, 0x80, 0x6E, 0x81, 0x53, + 0xA5, 0x6D, 0x5F, 0xB8, 0x48, 0xF9, 0xC2, 0xF9, 0x36, 0xA6, 0x2E, 0x49, + 0xFF, 0xB8, 0x96, 0xC2, 0x8C, 0x07, 0xB3, 0x9B, 0x88, 0x58, 0xFC, 0xEB, + 0x1B, 0x1C, 0xDE, 0x2D, 0x70, 0xE2, 0x97, 0x92, 0x30, 0xA1, 0x89, 0xE3, + 0xBC, 0x55, 0xA8, 0x27, 0xD6, 0x4B, 0xED, 0x90, 0xAD, 0x8B, 0xFA, 0x63, + 0x25, 0x59, 0x2D, 0xA8, 0x35, 0xDD, 0xCA, 0x97, 0x33, 0xBC, 0xE5, 0xCD, + 0xC7, 0x9D, 0xD1, 0xEC, 0xEF, 0x5E, 0x0E, 0x4A, 0x90, 0x06, 0x26, 0x63, + 0xAD, 0xB9, 0xD9, 0x35, 0x2D, 0x07, 0xBA, 0x76, 0x65, 0x2C, 0xAC, 0x57, + 0x8F, 0x7D, 0xF4, 0x07, 0x94, 0xD7, 0x81, 0x02, 0x96, 0x5D, 0xA3, 0x07, + 0x49, 0xD5, 0x7A, 0xD0, 0x57, 0xF9, 0x1B, 0xE7, 0x53, 0x46, 0x75, 0xAA, + 0xB0, 0x79, 0x42, 0xCB, 0x68, 0x71, 0x08, 0xE9, 0x60, 0xBD, 0x39, 0x69, + 0xCE, 0xF4, 0xAF, 0xC3, 0x56, 0x40, 0xC7, 0xAD, 0x52, 0xA2, 0x09, 0xE4, + 0x6F, 0x86, 0x47, 0x8A, 0x1F, 0xEB, 0x28, 0x27, 0x5D, 0x83, 0x20, 0xAF, + 0x04, 0xC9, 0x6C, 0x56, 0x9A, 0x8B, 0x46, 0xF5 +}; + +static const unsigned char TA550_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA551_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA551_RSA_N[] = { + 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80, + 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7, + 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86, + 0xD3, 0xA0, 0x43, 0x7A, 0x4E, 0xB2, 0xA4, 0xD0, 0x36, 0xBA, 0x01, 0xBE, + 0x8D, 0xDB, 0x48, 0xC8, 0x07, 0x17, 0x36, 0x4C, 0xF4, 0xEE, 0x88, 0x23, + 0xC7, 0x3E, 0xEB, 0x37, 0xF5, 0xB5, 0x19, 0xF8, 0x49, 0x68, 0xB0, 0xDE, + 0xD7, 0xB9, 0x76, 0x38, 0x1D, 0x61, 0x9E, 0xA4, 0xFE, 0x82, 0x36, 0xA5, + 0xE5, 0x4A, 0x56, 0xE4, 0x45, 0xE1, 0xF9, 0xFD, 0xB4, 0x16, 0xFA, 0x74, + 0xDA, 0x9C, 0x9B, 0x35, 0x39, 0x2F, 0xFA, 0xB0, 0x20, 0x50, 0x06, 0x6C, + 0x7A, 0xD0, 0x80, 0xB2, 0xA6, 0xF9, 0xAF, 0xEC, 0x47, 0x19, 0x8F, 0x50, + 0x38, 0x07, 0xDC, 0xA2, 0x87, 0x39, 0x58, 0xF8, 0xBA, 0xD5, 0xA9, 0xF9, + 0x48, 0x67, 0x30, 0x96, 0xEE, 0x94, 0x78, 0x5E, 0x6F, 0x89, 0xA3, 0x51, + 0xC0, 0x30, 0x86, 0x66, 0xA1, 0x45, 0x66, 0xBA, 0x54, 0xEB, 0xA3, 0xC3, + 0x91, 0xF9, 0x48, 0xDC, 0xFF, 0xD1, 0xE8, 0x30, 0x2D, 0x7D, 0x2D, 0x74, + 0x70, 0x35, 0xD7, 0x88, 0x24, 0xF7, 0x9E, 0xC4, 0x59, 0x6E, 0xBB, 0x73, + 0x87, 0x17, 0xF2, 0x32, 0x46, 0x28, 0xB8, 0x43, 0xFA, 0xB7, 0x1D, 0xAA, + 0xCA, 0xB4, 0xF2, 0x9F, 0x24, 0x0E, 0x2D, 0x4B, 0xF7, 0x71, 0x5C, 0x5E, + 0x69, 0xFF, 0xEA, 0x95, 0x02, 0xCB, 0x38, 0x8A, 0xAE, 0x50, 0x38, 0x6F, + 0xDB, 0xFB, 0x2D, 0x62, 0x1B, 0xC5, 0xC7, 0x1E, 0x54, 0xE1, 0x77, 0xE0, + 0x67, 0xC8, 0x0F, 0x9C, 0x87, 0x23, 0xD6, 0x3F, 0x40, 0x20, 0x7F, 0x20, + 0x80, 0xC4, 0x80, 0x4C, 0x3E, 0x3B, 0x24, 0x26, 0x8E, 0x04, 0xAE, 0x6C, + 0x9A, 0xC8, 0xAA, 0x0D +}; + +static const unsigned char TA551_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA552_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x45, 0x31 +}; + +static const unsigned char TA552_EC_Q[] = { + 0x04, 0xDE, 0x6F, 0xF8, 0x7F, 0x1C, 0xDF, 0xED, 0xF9, 0x47, 0x87, 0x86, + 0xB1, 0xA4, 0xC0, 0x8A, 0xF8, 0x82, 0x97, 0x80, 0xEA, 0x8F, 0xC8, 0x4A, + 0x5E, 0x2A, 0x7D, 0x88, 0x68, 0xA7, 0x01, 0x62, 0x14, 0x91, 0x24, 0x7A, + 0x5C, 0x9E, 0xA3, 0x17, 0x7D, 0x8A, 0x86, 0x21, 0x34, 0x18, 0x50, 0x1B, + 0x10, 0xDE, 0xD0, 0x37, 0x4B, 0x26, 0xC7, 0x19, 0x60, 0x80, 0xE9, 0x34, + 0xBD, 0x60, 0x19, 0x36, 0x40, 0xD6, 0x29, 0x87, 0x09, 0x3C, 0x91, 0x7A, + 0xF6, 0xBC, 0x13, 0x23, 0xDD, 0x59, 0x4E, 0x04, 0x5E, 0xCF, 0xC8, 0x02, + 0x1C, 0x18, 0x53, 0xC1, 0x31, 0xD8, 0xDA, 0x20, 0xE9, 0x44, 0x8D, 0xE4, + 0x76 +}; + +static const unsigned char TA553_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x52, 0x31 +}; + +static const unsigned char TA553_RSA_N[] = { + 0xD0, 0x36, 0xD4, 0x1F, 0xEA, 0xDD, 0xAB, 0xE4, 0xD1, 0xB6, 0xE6, 0xFB, + 0x22, 0xC0, 0xDD, 0x13, 0x0D, 0x6A, 0x7B, 0x22, 0x13, 0x1C, 0x97, 0x3C, + 0x68, 0x63, 0x66, 0x32, 0x9C, 0x03, 0xB5, 0x8D, 0xA4, 0x81, 0x83, 0xDA, + 0x78, 0x30, 0x11, 0xCF, 0xDC, 0xB2, 0x2B, 0xBE, 0x92, 0xBF, 0x8E, 0xE4, + 0xC4, 0x13, 0xBE, 0xA4, 0x68, 0x4C, 0xDA, 0x02, 0x68, 0x16, 0x74, 0xBE, + 0xB2, 0xDD, 0x04, 0xE4, 0x6B, 0x2A, 0xDD, 0x37, 0x1F, 0x60, 0x2C, 0xDB, + 0xF5, 0xF7, 0xA1, 0x7C, 0x95, 0xB7, 0x0C, 0x70, 0x86, 0x2E, 0xF1, 0x3A, + 0xEF, 0x52, 0xF7, 0xCC, 0xD3, 0x9B, 0xF9, 0x8B, 0xBE, 0x0E, 0xDF, 0x31, + 0xB7, 0x9D, 0x68, 0x5C, 0x92, 0xA6, 0xF5, 0xE5, 0xF3, 0x0A, 0x34, 0xB5, + 0xFF, 0x7B, 0xA2, 0xE4, 0x87, 0xA1, 0xC6, 0xAF, 0x17, 0x00, 0xEF, 0x03, + 0x91, 0xED, 0xA9, 0x1C, 0x4E, 0x71, 0x3D, 0xD2, 0x8B, 0x6C, 0x89, 0xF4, + 0x78, 0x86, 0xE6, 0x6A, 0x49, 0xA0, 0xCE, 0xB5, 0xD2, 0xB0, 0xAB, 0x9B, + 0xF6, 0xF4, 0xD4, 0x2E, 0xE3, 0x72, 0xF9, 0x36, 0xC6, 0xEB, 0x15, 0xB7, + 0x25, 0x8C, 0x3A, 0xFC, 0x25, 0x0D, 0xB3, 0x22, 0x73, 0x21, 0x74, 0xC8, + 0x4A, 0x96, 0x61, 0x92, 0xF5, 0x2F, 0x0B, 0x18, 0xA5, 0xF4, 0xAD, 0xE2, + 0xEE, 0x41, 0xBD, 0x01, 0x79, 0xFA, 0x96, 0x8C, 0x8D, 0x17, 0x02, 0x30, + 0xB4, 0xF9, 0xAF, 0x78, 0x1A, 0x8C, 0xB4, 0x36, 0x10, 0x10, 0x07, 0x05, + 0x70, 0xD0, 0xF4, 0x31, 0x90, 0x8A, 0x51, 0xC5, 0x86, 0x26, 0x79, 0xB2, + 0x11, 0x88, 0x5E, 0xC5, 0xF0, 0x0A, 0x54, 0xCD, 0x49, 0xA6, 0xBF, 0x02, + 0x9C, 0xD2, 0x44, 0xA7, 0xED, 0xE3, 0x78, 0xEF, 0x46, 0x5E, 0x6D, 0x71, + 0xD1, 0x79, 0x70, 0x1C, 0x46, 0x5F, 0x51, 0xE9, 0xC9, 0x37, 0xDC, 0x5F, + 0x7E, 0x69, 0x7B, 0x41, 0xDF, 0x34, 0x45, 0xE0, 0x3B, 0x84, 0xF4, 0xA1, + 0x8A, 0x0A, 0x36, 0x9E, 0x37, 0xCC, 0x62, 0x52, 0xE1, 0x89, 0x0D, 0x28, + 0xF9, 0x7A, 0x23, 0xB1, 0x0D, 0x3D, 0x3D, 0x9A, 0xFD, 0x9D, 0x81, 0xEF, + 0x2C, 0x90, 0xC0, 0x7B, 0x44, 0x4E, 0xBB, 0x49, 0xE0, 0x0E, 0x4A, 0x56, + 0x92, 0xBC, 0xCB, 0xB5, 0xDD, 0x79, 0x17, 0x89, 0x91, 0xDE, 0x61, 0x89, + 0x74, 0x92, 0xA8, 0xE3, 0x32, 0x85, 0xBE, 0x4E, 0x85, 0xA4, 0x4B, 0x59, + 0xCB, 0x2B, 0xC5, 0x78, 0x8E, 0x71, 0x54, 0xD0, 0x02, 0x37, 0x99, 0x8C, + 0xE5, 0x49, 0xEA, 0xE0, 0x54, 0x72, 0xA4, 0x11, 0x06, 0x2F, 0x0B, 0x8C, + 0xC1, 0x5B, 0xBE, 0xB5, 0xA1, 0xB0, 0x53, 0x6E, 0x9C, 0xB8, 0x60, 0x91, + 0x1F, 0x59, 0x6B, 0xF9, 0x2D, 0xF4, 0x94, 0x0A, 0x97, 0xB5, 0xEC, 0xC5, + 0x76, 0x03, 0x54, 0x1B, 0x65, 0x52, 0xBA, 0x4C, 0x92, 0x56, 0x51, 0x35, + 0xA0, 0x40, 0xD8, 0x29, 0xDB, 0xAE, 0x52, 0x76, 0x3B, 0x2D, 0x30, 0x40, + 0x9B, 0x8A, 0xD0, 0x42, 0x56, 0xB4, 0xB7, 0x88, 0x01, 0xA4, 0x87, 0x3B, + 0x53, 0x96, 0xCD, 0xA3, 0x16, 0x8F, 0xF3, 0x66, 0xAA, 0x17, 0xB1, 0xC7, + 0x60, 0xE0, 0xC1, 0x43, 0x05, 0x0C, 0xEE, 0x9B, 0x5B, 0x60, 0x6F, 0x06, + 0x5C, 0x87, 0x5B, 0x27, 0xF9, 0x40, 0x11, 0x9E, 0x9C, 0x33, 0xC1, 0xB7, + 0xE5, 0x35, 0x57, 0x05, 0x7F, 0x27, 0xCE, 0x17, 0x20, 0x8C, 0x1C, 0xFC, + 0xF1, 0xFB, 0xDA, 0x31, 0x29, 0x49, 0xED, 0xF5, 0x0B, 0x84, 0xA7, 0x4F, + 0xC1, 0xF6, 0x4E, 0xC2, 0x28, 0x9C, 0xFA, 0xEE, 0xE0, 0xAF, 0x07, 0xFB, + 0x33, 0x11, 0x7A, 0x21, 0x4F, 0x0B, 0x21, 0x10, 0xB6, 0x40, 0x3A, 0xAB, + 0x22, 0x3A, 0x04, 0x9C, 0x8B, 0x9B, 0x84, 0x86, 0x72, 0x9A, 0xD2, 0xA7, + 0xA5, 0xC4, 0xB4, 0x75, 0x91, 0xA9, 0x2B, 0x23 +}; + +static const unsigned char TA553_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA554_DN[] = { + 0x30, 0x34, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x08, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61 +}; + +static const unsigned char TA554_RSA_N[] = { + 0xC8, 0x68, 0xF1, 0xC9, 0xD6, 0xD6, 0xB3, 0x34, 0x75, 0x26, 0x82, 0x1E, + 0xEC, 0xB4, 0xBE, 0xEA, 0x5C, 0xE1, 0x26, 0xED, 0x11, 0x47, 0x61, 0xE1, + 0xA2, 0x7C, 0x16, 0x78, 0x40, 0x21, 0xE4, 0x60, 0x9E, 0x5A, 0xC8, 0x63, + 0xE1, 0xC4, 0xB1, 0x96, 0x92, 0xFF, 0x18, 0x6D, 0x69, 0x23, 0xE1, 0x2B, + 0x62, 0xF7, 0xDD, 0xE2, 0x36, 0x2F, 0x91, 0x07, 0xB9, 0x48, 0xCF, 0x0E, + 0xEC, 0x79, 0xB6, 0x2C, 0xE7, 0x34, 0x4B, 0x70, 0x08, 0x25, 0xA3, 0x3C, + 0x87, 0x1B, 0x19, 0xF2, 0x81, 0x07, 0x0F, 0x38, 0x90, 0x19, 0xD3, 0x11, + 0xFE, 0x86, 0xB4, 0xF2, 0xD1, 0x5E, 0x1E, 0x1E, 0x96, 0xCD, 0x80, 0x6C, + 0xCE, 0x3B, 0x31, 0x93, 0xB6, 0xF2, 0xA0, 0xD0, 0xA9, 0x95, 0x12, 0x7D, + 0xA5, 0x9A, 0xCC, 0x6B, 0xC8, 0x84, 0x56, 0x8A, 0x33, 0xA9, 0xE7, 0x22, + 0x15, 0x53, 0x16, 0xF0, 0xCC, 0x17, 0xEC, 0x57, 0x5F, 0xE9, 0xA2, 0x0A, + 0x98, 0x09, 0xDE, 0xE3, 0x5F, 0x9C, 0x6F, 0xDC, 0x48, 0xE3, 0x85, 0x0B, + 0x15, 0x5A, 0xA6, 0xBA, 0x9F, 0xAC, 0x48, 0xE3, 0x09, 0xB2, 0xF7, 0xF4, + 0x32, 0xDE, 0x5E, 0x34, 0xBE, 0x1C, 0x78, 0x5D, 0x42, 0x5B, 0xCE, 0x0E, + 0x22, 0x8F, 0x4D, 0x90, 0xD7, 0x7D, 0x32, 0x18, 0xB3, 0x0B, 0x2C, 0x6A, + 0xBF, 0x8E, 0x3F, 0x14, 0x11, 0x89, 0x20, 0x0E, 0x77, 0x14, 0xB5, 0x3D, + 0x94, 0x08, 0x87, 0xF7, 0x25, 0x1E, 0xD5, 0xB2, 0x60, 0x00, 0xEC, 0x6F, + 0x2A, 0x28, 0x25, 0x6E, 0x2A, 0x3E, 0x18, 0x63, 0x17, 0x25, 0x3F, 0x3E, + 0x44, 0x20, 0x16, 0xF6, 0x26, 0xC8, 0x25, 0xAE, 0x05, 0x4A, 0xB4, 0xE7, + 0x63, 0x2C, 0xF3, 0x8C, 0x16, 0x53, 0x7E, 0x5C, 0xFB, 0x11, 0x1A, 0x08, + 0xC1, 0x46, 0x62, 0x9F, 0x22, 0xB8, 0xF1, 0xC2, 0x8D, 0x69, 0xDC, 0xFA, + 0x3A, 0x58, 0x06, 0xDF +}; + +static const unsigned char TA554_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA555_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x13, 0x30, 0x30, + 0x30, 0x32, 0x20, 0x34, 0x38, 0x31, 0x34, 0x36, 0x33, 0x30, 0x38, 0x31, + 0x30, 0x30, 0x30, 0x33, 0x36, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA555_RSA_N[] = { + 0xCD, 0x18, 0x39, 0x65, 0x1A, 0x59, 0xB1, 0xEA, 0x64, 0x16, 0x0E, 0x8C, + 0x94, 0x24, 0x95, 0x7C, 0x83, 0xD3, 0xC5, 0x39, 0x26, 0xDC, 0x0C, 0xEF, + 0x16, 0x57, 0x8D, 0xD7, 0xD8, 0xAC, 0xA3, 0x42, 0x7F, 0x82, 0xCA, 0xED, + 0xCD, 0x5B, 0xDB, 0x0E, 0xB7, 0x2D, 0xED, 0x45, 0x08, 0x17, 0xB2, 0xD9, + 0xB3, 0xCB, 0xD6, 0x17, 0x52, 0x72, 0x28, 0xDB, 0x8E, 0x4E, 0x9E, 0x8A, + 0xB6, 0x0B, 0xF9, 0x9E, 0x84, 0x9A, 0x4D, 0x76, 0xDE, 0x22, 0x29, 0x5C, + 0xD2, 0xB3, 0xD2, 0x06, 0x3E, 0x30, 0x39, 0xA9, 0x74, 0xA3, 0x92, 0x56, + 0x1C, 0xA1, 0x6F, 0x4C, 0x0A, 0x20, 0x6D, 0x9F, 0x23, 0x7A, 0xB4, 0xC6, + 0xDA, 0x2C, 0xE4, 0x1D, 0x2C, 0xDC, 0xB3, 0x28, 0xD0, 0x13, 0xF2, 0x4C, + 0x4E, 0x02, 0x49, 0xA1, 0x54, 0x40, 0x9E, 0xE6, 0xE5, 0x05, 0xA0, 0x2D, + 0x84, 0xC8, 0xFF, 0x98, 0x6C, 0xD0, 0xEB, 0x8A, 0x1A, 0x84, 0x08, 0x1E, + 0xB7, 0x68, 0x23, 0xEE, 0x23, 0xD5, 0x70, 0xCE, 0x6D, 0x51, 0x69, 0x10, + 0xEE, 0xA1, 0x7A, 0xC2, 0xD1, 0x22, 0x31, 0xC2, 0x82, 0x85, 0xD2, 0xF2, + 0x55, 0x76, 0x50, 0x7C, 0x25, 0x7A, 0xC9, 0x84, 0x5C, 0x0B, 0xAC, 0xDD, + 0x42, 0x4E, 0x2B, 0xE7, 0x82, 0xA2, 0x24, 0x89, 0xCB, 0x90, 0xB2, 0xD0, + 0xEE, 0x23, 0xBA, 0x66, 0x4C, 0xBB, 0x62, 0xA4, 0xF9, 0x53, 0x5A, 0x64, + 0x7B, 0x7C, 0x98, 0xFA, 0xA3, 0x48, 0x9E, 0x0F, 0x95, 0xAE, 0xA7, 0x18, + 0xF4, 0x6A, 0xEC, 0x2E, 0x03, 0x45, 0xAF, 0xF0, 0x74, 0xF8, 0x2A, 0xCD, + 0x7A, 0x5D, 0xD1, 0xBE, 0x44, 0x26, 0x32, 0x29, 0xF1, 0xF1, 0xF5, 0x6C, + 0xCC, 0x7E, 0x02, 0x21, 0x0B, 0x9F, 0x6F, 0xA4, 0x3F, 0xBE, 0x9D, 0x53, + 0xE2, 0xCF, 0x7D, 0xA9, 0x2C, 0x7C, 0x58, 0x1A, 0x97, 0xE1, 0x3D, 0x37, + 0x37, 0x18, 0x66, 0x28, 0xD2, 0x40, 0xC5, 0x51, 0x8A, 0x8C, 0xC3, 0x2D, + 0xCE, 0x53, 0x88, 0x24, 0x58, 0x64, 0x30, 0x16, 0xC5, 0xAA, 0xE0, 0xD6, + 0x0A, 0xA6, 0x40, 0xDF, 0x78, 0xF6, 0xF5, 0x04, 0x7C, 0x69, 0x13, 0x84, + 0xBC, 0xD1, 0xD1, 0xA7, 0x06, 0xCF, 0x01, 0xF7, 0x68, 0xC0, 0xA8, 0x57, + 0xBB, 0x3A, 0x61, 0xAD, 0x04, 0x8C, 0x93, 0xE3, 0xAD, 0xFC, 0xF0, 0xDB, + 0x44, 0x6D, 0x59, 0xDC, 0x49, 0x59, 0xAE, 0xAC, 0x9A, 0x99, 0x36, 0x30, + 0x41, 0x7B, 0x76, 0x33, 0x22, 0x87, 0xA3, 0xC2, 0x92, 0x86, 0x6E, 0xF9, + 0x70, 0xEE, 0xAE, 0x87, 0x87, 0x95, 0x1B, 0xC4, 0x7A, 0xBD, 0x31, 0xF3, + 0xD4, 0xD2, 0xE5, 0x99, 0xFF, 0xBE, 0x48, 0xEC, 0x75, 0xF5, 0x78, 0x16, + 0x1D, 0xA6, 0x70, 0xC1, 0x7F, 0x3C, 0x1B, 0xA1, 0x92, 0xFB, 0xCF, 0xC8, + 0x3C, 0xD6, 0xC5, 0x93, 0x0A, 0x8F, 0xF5, 0x55, 0x3A, 0x76, 0x95, 0xCE, + 0x59, 0x98, 0x8A, 0x09, 0x95, 0x77, 0x32, 0x9A, 0x83, 0xBA, 0x2C, 0x04, + 0x3A, 0x97, 0xBD, 0xD4, 0x2F, 0xBE, 0xD7, 0x6C, 0x9B, 0xA2, 0xCA, 0x7D, + 0x6D, 0x26, 0xC9, 0x55, 0xD5, 0xCF, 0xC3, 0x79, 0x52, 0x08, 0x09, 0x99, + 0x07, 0x24, 0x2D, 0x64, 0x25, 0x6B, 0xA6, 0x21, 0x69, 0x9B, 0x6A, 0xDD, + 0x74, 0x4D, 0x6B, 0x97, 0x7A, 0x41, 0xBD, 0xAB, 0x17, 0xF9, 0x90, 0x17, + 0x48, 0x8F, 0x36, 0xF9, 0x2D, 0xD5, 0xC5, 0xDB, 0xEE, 0xAA, 0x85, 0x45, + 0x41, 0xFA, 0xCD, 0x3A, 0x45, 0xB1, 0x68, 0xE6, 0x36, 0x4C, 0x9B, 0x90, + 0x57, 0xEC, 0x23, 0xB9, 0x87, 0x08, 0xC2, 0xC4, 0x09, 0xF1, 0x97, 0x86, + 0x2A, 0x28, 0x4D, 0xE2, 0x74, 0xC0, 0xDA, 0xC4, 0x8C, 0xDB, 0xDF, 0xE2, + 0xA1, 0x17, 0x59, 0xCE, 0x24, 0x59, 0x74, 0x31, 0xDA, 0x7F, 0xFD, 0x30, + 0x6D, 0xD9, 0xDC, 0xE1, 0x6A, 0xE1, 0xFC, 0x5F +}; + +static const unsigned char TA555_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA556_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x43, 0x45, 0x52, 0x54, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x53, + 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x13, + 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, + 0x54, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA556_RSA_N[] = { + 0xC0, 0xC5, 0x75, 0x19, 0x91, 0x7D, 0x44, 0x74, 0x74, 0x87, 0xFE, 0x0E, + 0x3B, 0x96, 0xDC, 0xD8, 0x01, 0x16, 0xCC, 0xEE, 0x63, 0x91, 0xE7, 0x0B, + 0x6F, 0xCE, 0x3B, 0x0A, 0x69, 0x1A, 0x7C, 0xC2, 0xE3, 0xAF, 0x82, 0x8E, + 0x86, 0xD7, 0x5E, 0x8F, 0x57, 0xEB, 0xD3, 0x21, 0x59, 0xFD, 0x39, 0x37, + 0x42, 0x30, 0xBE, 0x50, 0xEA, 0xB6, 0x0F, 0xA9, 0x88, 0xD8, 0x2E, 0x2D, + 0x69, 0x21, 0xE7, 0xD1, 0x37, 0x18, 0x4E, 0x7D, 0x91, 0xD5, 0x16, 0x5F, + 0x6B, 0x5B, 0x00, 0xC2, 0x39, 0x43, 0x0D, 0x36, 0x85, 0x52, 0xB9, 0x53, + 0x65, 0x0F, 0x1D, 0x42, 0xE5, 0x8F, 0xCF, 0x05, 0xD3, 0xEE, 0xDC, 0x0C, + 0x1A, 0xD9, 0xB8, 0x8B, 0x78, 0x22, 0x67, 0xE4, 0x69, 0xB0, 0x68, 0xC5, + 0x3C, 0xE4, 0x6C, 0x5A, 0x46, 0xE7, 0xCD, 0xC7, 0xFA, 0xEF, 0xC4, 0xEC, + 0x4B, 0xBD, 0x6A, 0xA4, 0xAC, 0xFD, 0xCC, 0x28, 0x51, 0xEF, 0x92, 0xB4, + 0x29, 0xAB, 0xAB, 0x35, 0x9A, 0x4C, 0xE4, 0xC4, 0x08, 0xC6, 0x26, 0xCC, + 0xF8, 0x69, 0x9F, 0xE4, 0x9C, 0xF0, 0x29, 0xD3, 0x5C, 0xF9, 0xC6, 0x16, + 0x25, 0x9E, 0x23, 0xC3, 0x20, 0xC1, 0x3D, 0x0F, 0x3F, 0x38, 0x40, 0xB0, + 0xFE, 0x82, 0x44, 0x38, 0xAA, 0x5A, 0x1A, 0x8A, 0x6B, 0x63, 0x58, 0x38, + 0xB4, 0x15, 0xD3, 0xB6, 0x11, 0x69, 0x7B, 0x1E, 0x54, 0xEE, 0x8C, 0x1A, + 0x22, 0xAC, 0x72, 0x97, 0x3F, 0x23, 0x59, 0x9B, 0xC9, 0x22, 0x84, 0xC1, + 0x07, 0x4F, 0xCC, 0x7F, 0xE2, 0x57, 0xCA, 0x12, 0x70, 0xBB, 0xA6, 0x65, + 0xF3, 0x69, 0x75, 0x63, 0xBD, 0x95, 0xFB, 0x1B, 0x97, 0xCD, 0xE4, 0xA8, + 0xAF, 0xF6, 0xD1, 0x4E, 0xA8, 0xD9, 0x8A, 0x71, 0x24, 0xCD, 0x36, 0x3D, + 0xBC, 0x96, 0xC4, 0xF1, 0x6C, 0xA9, 0xAE, 0xE5, 0xCF, 0x0D, 0x6E, 0x28, + 0x0D, 0xB0, 0x0E, 0xB5, 0xCA, 0x51, 0x7B, 0x78, 0x14, 0xC3, 0x20, 0x2F, + 0x7F, 0xFB, 0x14, 0x55, 0xE1, 0x11, 0x99, 0xFD, 0xD5, 0x0A, 0xA1, 0x9E, + 0x02, 0xE3, 0x62, 0x5F, 0xEB, 0x35, 0x4B, 0x2C, 0xB8, 0x72, 0xE8, 0x3E, + 0x3D, 0x4F, 0xAC, 0x2C, 0xBB, 0x2E, 0x86, 0xE2, 0xA3, 0x76, 0x8F, 0xE5, + 0x93, 0x2A, 0xCF, 0xA5, 0xAB, 0xC8, 0x5C, 0x8D, 0x4B, 0x06, 0xFF, 0x12, + 0x46, 0xAC, 0x78, 0xCB, 0x14, 0x07, 0x35, 0xE0, 0xA9, 0xDF, 0x8B, 0xE9, + 0xAF, 0x15, 0x4F, 0x16, 0x89, 0x5B, 0xBD, 0xF6, 0x8D, 0xC6, 0x59, 0xAE, + 0x88, 0x85, 0x0E, 0xC1, 0x89, 0xEB, 0x1F, 0x67, 0xC5, 0x45, 0x8E, 0xFF, + 0x6D, 0x37, 0x36, 0x2B, 0x78, 0x66, 0x83, 0x91, 0x51, 0x2B, 0x3D, 0xFF, + 0x51, 0x77, 0x76, 0x62, 0xA1, 0xEC, 0x67, 0x3E, 0x3E, 0x81, 0x83, 0xE0, + 0x56, 0xA9, 0x50, 0x1F, 0x1F, 0x7A, 0x99, 0xAB, 0x63, 0xBF, 0x84, 0x17, + 0x77, 0xF1, 0x0D, 0x3B, 0xDF, 0xF7, 0x9C, 0x61, 0xB3, 0x35, 0x98, 0x8A, + 0x3A, 0xB2, 0xEC, 0x3C, 0x1A, 0x37, 0x3F, 0x7E, 0x8F, 0x92, 0xCF, 0xD9, + 0x12, 0x14, 0x64, 0xDA, 0x10, 0x02, 0x15, 0x41, 0xFF, 0x4F, 0xC4, 0xEB, + 0x1C, 0xA3, 0xC9, 0xFA, 0x99, 0xF7, 0x46, 0xE9, 0xE1, 0x18, 0xD9, 0xB1, + 0xB8, 0x32, 0x2D, 0xCB, 0x14, 0x0C, 0x50, 0xD8, 0x83, 0x65, 0x83, 0xEE, + 0xB9, 0x5C, 0xCF, 0xCB, 0x05, 0x5A, 0x4C, 0xFA, 0x19, 0x97, 0x6B, 0xD6, + 0x5D, 0x13, 0xD3, 0xC2, 0x5C, 0x54, 0xBC, 0x32, 0x73, 0xA0, 0x78, 0xF5, + 0xF1, 0x6D, 0x1E, 0xCB, 0x9F, 0xA5, 0xA6, 0x9F, 0x22, 0xDC, 0xD1, 0x51, + 0x9E, 0x82, 0x79, 0x64, 0x60, 0x29, 0x13, 0x3E, 0xA3, 0xFD, 0x4F, 0x72, + 0x6A, 0xAB, 0xE2, 0xD4, 0xE5, 0xB8, 0x24, 0x55, 0x2C, 0x44, 0x4B, 0x8A, + 0x88, 0x44, 0x9C, 0xCA, 0x84, 0xD3, 0x2A, 0x3B +}; + +static const unsigned char TA556_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA557_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x08, 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x10, 0x63, 0x65, 0x72, + 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA557_RSA_N[] = { + 0xB7, 0x33, 0xB9, 0x7E, 0xC8, 0x25, 0x4A, 0x8E, 0xB5, 0xDB, 0xB4, 0x28, + 0x1B, 0xAA, 0x57, 0x90, 0xE8, 0xD1, 0x22, 0xD3, 0x64, 0xBA, 0xD3, 0x93, + 0xE8, 0xD4, 0xAC, 0x86, 0x61, 0x40, 0x6A, 0x60, 0x57, 0x68, 0x54, 0x84, + 0x4D, 0xBC, 0x6A, 0x54, 0x02, 0x05, 0xFF, 0xDF, 0x9B, 0x9A, 0x2A, 0xAE, + 0x5D, 0x07, 0x8F, 0x4A, 0xC3, 0x28, 0x7F, 0xEF, 0xFB, 0x2B, 0xFA, 0x79, + 0xF1, 0xC7, 0xAD, 0xF0, 0x10, 0x53, 0x24, 0x90, 0x8B, 0x66, 0xC9, 0xA8, + 0x88, 0xAB, 0xAF, 0x5A, 0xA3, 0x00, 0xE9, 0xBE, 0xBA, 0x46, 0xEE, 0x5B, + 0x73, 0x7B, 0x2C, 0x17, 0x82, 0x81, 0x5E, 0x62, 0x2C, 0xA1, 0x02, 0x65, + 0xB3, 0xBD, 0xC5, 0x2B, 0x00, 0x7E, 0xC4, 0xFC, 0x03, 0x33, 0x57, 0x0D, + 0xED, 0xE2, 0xFA, 0xCE, 0x5D, 0x45, 0xD6, 0x38, 0xCD, 0x35, 0xB6, 0xB2, + 0xC1, 0xD0, 0x9C, 0x81, 0x4A, 0xAA, 0xE4, 0xB2, 0x01, 0x5C, 0x1D, 0x8F, + 0x5F, 0x99, 0xC4, 0xB1, 0xAD, 0xDB, 0x88, 0x21, 0xEB, 0x90, 0x08, 0x82, + 0x80, 0xF3, 0x30, 0xA3, 0x43, 0xE6, 0x90, 0x82, 0xAE, 0x55, 0x28, 0x49, + 0xED, 0x5B, 0xD7, 0xA9, 0x10, 0x38, 0x0E, 0xFE, 0x8F, 0x4C, 0x5B, 0x9B, + 0x46, 0xEA, 0x41, 0xF5, 0xB0, 0x08, 0x74, 0xC3, 0xD0, 0x88, 0x33, 0xB6, + 0x7C, 0xD7, 0x74, 0xDF, 0xDC, 0x84, 0xD1, 0x43, 0x0E, 0x75, 0x39, 0xA1, + 0x25, 0x40, 0x28, 0xEA, 0x78, 0xCB, 0x0E, 0x2C, 0x2E, 0x39, 0x9D, 0x8C, + 0x8B, 0x6E, 0x16, 0x1C, 0x2F, 0x26, 0x82, 0x10, 0xE2, 0xE3, 0x65, 0x94, + 0x0A, 0x04, 0xC0, 0x5E, 0xF7, 0x5D, 0x5B, 0xF8, 0x10, 0xE2, 0xD0, 0xBA, + 0x7A, 0x4B, 0xFB, 0xDE, 0x37, 0x00, 0x00, 0x1A, 0x5B, 0x28, 0xE3, 0xD2, + 0x9C, 0x73, 0x3E, 0x32, 0x87, 0x98, 0xA1, 0xC9, 0x51, 0x2F, 0xD7, 0xDE, + 0xAC, 0x33, 0xB3, 0x4F +}; + +static const unsigned char TA557_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA558_DN[] = { + 0x30, 0x74, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x45, 0x43, 0x2D, 0x33, 0x38, 0x34, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA558_EC_Q[] = { + 0x04, 0xC4, 0x28, 0x8E, 0xAB, 0x18, 0x5B, 0x6A, 0xBE, 0x6E, 0x64, 0x37, + 0x63, 0xE4, 0xCD, 0xEC, 0xAB, 0x3A, 0xF7, 0xCC, 0xA1, 0xB8, 0x0E, 0x82, + 0x49, 0xD7, 0x86, 0x29, 0x9F, 0xA1, 0x94, 0xF2, 0xE3, 0x60, 0x78, 0x98, + 0x81, 0x78, 0x06, 0x4D, 0xF2, 0xEC, 0x9A, 0x0E, 0x57, 0x60, 0x83, 0x9F, + 0xB4, 0xE6, 0x17, 0x2F, 0x1A, 0xB3, 0x5D, 0x02, 0x5B, 0x89, 0x23, 0x3C, + 0xC2, 0x11, 0x05, 0x2A, 0xA7, 0x88, 0x13, 0x18, 0xF3, 0x50, 0x84, 0xD7, + 0xBD, 0x34, 0x2C, 0x27, 0x89, 0x55, 0xFF, 0xCE, 0x4C, 0xE7, 0xDF, 0xA6, + 0x1F, 0x28, 0xC4, 0xF0, 0x54, 0xC3, 0xB9, 0x7C, 0xB7, 0x53, 0xAD, 0xEB, + 0xC2 +}; + +static const unsigned char TA559_DN[] = { + 0x30, 0x81, 0x80, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, + 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x24, 0x30, + 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x43, 0x65, 0x72, 0x74, + 0x75, 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, + 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA559_RSA_N[] = { + 0xBD, 0xF9, 0x78, 0xF8, 0xE6, 0xD5, 0x80, 0x0C, 0x64, 0x9D, 0x86, 0x1B, + 0x96, 0x64, 0x67, 0x3F, 0x22, 0x3A, 0x1E, 0x75, 0x01, 0x7D, 0xEF, 0xFB, + 0x5C, 0x67, 0x8C, 0xC9, 0xCC, 0x5C, 0x6B, 0xA9, 0x91, 0xE6, 0xB9, 0x42, + 0xE5, 0x20, 0x4B, 0x9B, 0xDA, 0x9B, 0x7B, 0xB9, 0x99, 0x5D, 0xD9, 0x9B, + 0x80, 0x4B, 0xD7, 0x84, 0x40, 0x2B, 0x27, 0xD3, 0xE8, 0xBA, 0x30, 0xBB, + 0x3E, 0x09, 0x1A, 0xA7, 0x49, 0x95, 0xEF, 0x2B, 0x40, 0x24, 0xC2, 0x97, + 0xC7, 0xA7, 0xEE, 0x9B, 0x25, 0xEF, 0xA8, 0x0A, 0x00, 0x97, 0x85, 0x5A, + 0xAA, 0x9D, 0xDC, 0x29, 0xC9, 0xE2, 0x35, 0x07, 0xEB, 0x70, 0x4D, 0x4A, + 0xD6, 0xC1, 0xB3, 0x56, 0xB8, 0xA1, 0x41, 0x38, 0x9B, 0xD1, 0xFB, 0x31, + 0x7F, 0x8F, 0xE0, 0x5F, 0xE1, 0xB1, 0x3F, 0x0F, 0x8E, 0x16, 0x49, 0x60, + 0xD7, 0x06, 0x8D, 0x18, 0xF9, 0xAA, 0x26, 0x10, 0xAB, 0x2A, 0xD3, 0xD0, + 0xD1, 0x67, 0x8D, 0x1B, 0x46, 0xBE, 0x47, 0x30, 0xD5, 0x2E, 0x72, 0xD1, + 0xC5, 0x63, 0xDA, 0xE7, 0x63, 0x79, 0x44, 0x7E, 0x4B, 0x63, 0x24, 0x89, + 0x86, 0x2E, 0x34, 0x3F, 0x29, 0x4C, 0x52, 0x8B, 0x2A, 0xA7, 0xC0, 0xE2, + 0x91, 0x28, 0x89, 0xB9, 0xC0, 0x5B, 0xF9, 0x1D, 0xD9, 0xE7, 0x27, 0xAD, + 0xFF, 0x9A, 0x02, 0x97, 0xC1, 0xC6, 0x50, 0x92, 0x9B, 0x02, 0x2C, 0xBD, + 0xA9, 0xB9, 0x34, 0x59, 0x0A, 0xBF, 0x84, 0x4A, 0xFF, 0xDF, 0xFE, 0xB3, + 0x9F, 0xEB, 0xD9, 0x9E, 0xE0, 0x98, 0x23, 0xEC, 0xA6, 0x6B, 0x77, 0x16, + 0x2A, 0xDB, 0xCC, 0xAD, 0x3B, 0x1C, 0xA4, 0x87, 0xDC, 0x46, 0x73, 0x5E, + 0x19, 0x62, 0x68, 0x45, 0x57, 0xE4, 0x90, 0x82, 0x42, 0xBB, 0x42, 0xD6, + 0xF0, 0x61, 0xE0, 0xC1, 0xA3, 0x3D, 0x66, 0xA3, 0x5D, 0xF4, 0x18, 0xEE, + 0x88, 0xC9, 0x8D, 0x17, 0x45, 0x29, 0x99, 0x32, 0x75, 0x02, 0x31, 0xEE, + 0x29, 0x26, 0xC8, 0x6B, 0x02, 0xE6, 0xB5, 0x62, 0x45, 0x7F, 0x37, 0x15, + 0x5A, 0x23, 0x68, 0x89, 0xD4, 0x3E, 0xDE, 0x4E, 0x27, 0xB0, 0xF0, 0x40, + 0x0C, 0xBC, 0x4D, 0x17, 0xCB, 0x4D, 0xA2, 0xB3, 0x1E, 0xD0, 0x06, 0x5A, + 0xDD, 0xF6, 0x93, 0xCF, 0x57, 0x75, 0x99, 0xF5, 0xFA, 0x86, 0x1A, 0x67, + 0x78, 0xB3, 0xBF, 0x96, 0xFE, 0x34, 0xDC, 0xBD, 0xE7, 0x52, 0x56, 0xE5, + 0xB3, 0xE5, 0x75, 0x7B, 0xD7, 0x41, 0x91, 0x05, 0xDC, 0x5D, 0x69, 0xE3, + 0x95, 0x0D, 0x43, 0xB9, 0xFC, 0x83, 0x96, 0x39, 0x95, 0x7B, 0x6C, 0x80, + 0x5A, 0x4F, 0x13, 0x72, 0xC6, 0xD7, 0x7D, 0x29, 0x7A, 0x44, 0xBA, 0x52, + 0xA4, 0x2A, 0xD5, 0x41, 0x46, 0x09, 0x20, 0xFE, 0x22, 0xA0, 0xB6, 0x5B, + 0x30, 0x8D, 0xBC, 0x89, 0x0C, 0xD5, 0xD7, 0x70, 0xF8, 0x87, 0x52, 0xFD, + 0xDA, 0xEF, 0xAC, 0x51, 0x2E, 0x07, 0xB3, 0x4E, 0xFE, 0xD0, 0x09, 0xDA, + 0x70, 0xEF, 0x98, 0xFA, 0x56, 0xE6, 0x6D, 0xDB, 0xB5, 0x57, 0x4B, 0xDC, + 0xE5, 0x2C, 0x25, 0x15, 0xC8, 0x9E, 0x2E, 0x78, 0x4E, 0xF8, 0xDA, 0x9C, + 0x9E, 0x86, 0x2C, 0xCA, 0x57, 0xF3, 0x1A, 0xE5, 0xC8, 0x92, 0x8B, 0x1A, + 0x82, 0x96, 0x7A, 0xC3, 0xBC, 0x50, 0x12, 0x69, 0xD8, 0x0E, 0x5A, 0x46, + 0x8B, 0x3A, 0xEB, 0x26, 0xFA, 0x23, 0xC9, 0xB6, 0xB0, 0x81, 0xBE, 0x42, + 0x00, 0xA4, 0xF8, 0xD6, 0xFE, 0x30, 0x2E, 0xC7, 0xD2, 0x46, 0xF6, 0xE5, + 0x8E, 0x75, 0xFD, 0xF2, 0xCC, 0xB9, 0xD0, 0x87, 0x5B, 0xCC, 0x06, 0x10, + 0x60, 0xBB, 0x83, 0x35, 0xB7, 0x5E, 0x67, 0xDE, 0x47, 0xEC, 0x99, 0x48, + 0xF1, 0xA4, 0xA1, 0x15, 0xFE, 0xAD, 0x8C, 0x62, 0x8E, 0x39, 0x55, 0x4F, + 0x39, 0x16, 0xB9, 0xB1, 0x63, 0x9D, 0xFF, 0xB7 +}; + +static const unsigned char TA559_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA560_DN[] = { + 0x30, 0x7E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, 0x65, + 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, + 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, + 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, 0x65, + 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA560_RSA_N[] = { + 0xE3, 0xFB, 0x7D, 0xA3, 0x72, 0xBA, 0xC2, 0xF0, 0xC9, 0x14, 0x87, 0xF5, + 0x6B, 0x01, 0x4E, 0xE1, 0x6E, 0x40, 0x07, 0xBA, 0x6D, 0x27, 0x5D, 0x7F, + 0xF7, 0x5B, 0x2D, 0xB3, 0x5A, 0xC7, 0x51, 0x5F, 0xAB, 0xA4, 0x32, 0xA6, + 0x61, 0x87, 0xB6, 0x6E, 0x0F, 0x86, 0xD2, 0x30, 0x02, 0x97, 0xF8, 0xD7, + 0x69, 0x57, 0xA1, 0x18, 0x39, 0x5D, 0x6A, 0x64, 0x79, 0xC6, 0x01, 0x59, + 0xAC, 0x3C, 0x31, 0x4A, 0x38, 0x7C, 0xD2, 0x04, 0xD2, 0x4B, 0x28, 0xE8, + 0x20, 0x5F, 0x3B, 0x07, 0xA2, 0xCC, 0x4D, 0x73, 0xDB, 0xF3, 0xAE, 0x4F, + 0xC7, 0x56, 0xD5, 0x5A, 0xA7, 0x96, 0x89, 0xFA, 0xF3, 0xAB, 0x68, 0xD4, + 0x23, 0x86, 0x59, 0x27, 0xCF, 0x09, 0x27, 0xBC, 0xAC, 0x6E, 0x72, 0x83, + 0x1C, 0x30, 0x72, 0xDF, 0xE0, 0xA2, 0xE9, 0xD2, 0xE1, 0x74, 0x75, 0x19, + 0xBD, 0x2A, 0x9E, 0x7B, 0x15, 0x54, 0x04, 0x1B, 0xD7, 0x43, 0x39, 0xAD, + 0x55, 0x28, 0xC5, 0xE2, 0x1A, 0xBB, 0xF4, 0xC0, 0xE4, 0xAE, 0x38, 0x49, + 0x33, 0xCC, 0x76, 0x85, 0x9F, 0x39, 0x45, 0xD2, 0xA4, 0x9E, 0xF2, 0x12, + 0x8C, 0x51, 0xF8, 0x7C, 0xE4, 0x2D, 0x7F, 0xF5, 0xAC, 0x5F, 0xEB, 0x16, + 0x9F, 0xB1, 0x2D, 0xD1, 0xBA, 0xCC, 0x91, 0x42, 0x77, 0x4C, 0x25, 0xC9, + 0x90, 0x38, 0x6F, 0xDB, 0xF0, 0xCC, 0xFB, 0x8E, 0x1E, 0x97, 0x59, 0x3E, + 0xD5, 0x60, 0x4E, 0xE6, 0x05, 0x28, 0xED, 0x49, 0x79, 0x13, 0x4B, 0xBA, + 0x48, 0xDB, 0x2F, 0xF9, 0x72, 0xD3, 0x39, 0xCA, 0xFE, 0x1F, 0xD8, 0x34, + 0x72, 0xF5, 0xB4, 0x40, 0xCF, 0x31, 0x01, 0xC3, 0xEC, 0xDE, 0x11, 0x2D, + 0x17, 0x5D, 0x1F, 0xB8, 0x50, 0xD1, 0x5E, 0x19, 0xA7, 0x69, 0xDE, 0x07, + 0x33, 0x28, 0xCA, 0x50, 0x95, 0xF9, 0xA7, 0x54, 0xCB, 0x54, 0x86, 0x50, + 0x45, 0xA9, 0xF9, 0x49 +}; + +static const unsigned char TA560_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA561_DN[] = { + 0x30, 0x7A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA561_RSA_N[] = { + 0xD1, 0x2D, 0x8E, 0xBB, 0xB7, 0x36, 0xEA, 0x6D, 0x37, 0x91, 0x9F, 0x4E, + 0x93, 0xA7, 0x05, 0xE4, 0x29, 0x03, 0x25, 0xCE, 0x1C, 0x82, 0xF7, 0x7C, + 0x99, 0x9F, 0x41, 0x06, 0xCD, 0xED, 0xA3, 0xBA, 0xC0, 0xDB, 0x09, 0x2C, + 0xC1, 0x7C, 0xDF, 0x29, 0x7E, 0x4B, 0x65, 0x2F, 0x93, 0xA7, 0xD4, 0x01, + 0x6B, 0x03, 0x28, 0x18, 0xA3, 0xD8, 0x9D, 0x05, 0xC1, 0x2A, 0xD8, 0x45, + 0xF1, 0x91, 0xDE, 0xDF, 0x3B, 0xD0, 0x80, 0x02, 0x8C, 0xCF, 0x38, 0x0F, + 0xEA, 0xA7, 0x5C, 0x78, 0x11, 0xA4, 0xC1, 0xC8, 0x85, 0x5C, 0x25, 0xD3, + 0xD3, 0xB2, 0xE7, 0x25, 0xCF, 0x11, 0x54, 0x97, 0xAB, 0x35, 0xC0, 0x1E, + 0x76, 0x1C, 0xEF, 0x00, 0x53, 0x9F, 0x39, 0xDC, 0x14, 0xA5, 0x2C, 0x22, + 0x25, 0xB3, 0x72, 0x72, 0xFC, 0x8D, 0xB3, 0xE5, 0x3E, 0x08, 0x1E, 0x14, + 0x2A, 0x37, 0x0B, 0x88, 0x3C, 0xCA, 0xB0, 0xF4, 0xC8, 0xC2, 0xA1, 0xAE, + 0xBC, 0xC1, 0xBE, 0x29, 0x67, 0x55, 0xE2, 0xFC, 0xAD, 0x59, 0x5C, 0xFE, + 0xBD, 0x57, 0x2C, 0xB0, 0x90, 0x8D, 0xC2, 0xED, 0x37, 0xB6, 0x7C, 0x99, + 0x88, 0xB5, 0xD5, 0x03, 0x9A, 0x3D, 0x15, 0x0D, 0x3D, 0x3A, 0xA8, 0xA8, + 0x45, 0xF0, 0x95, 0x4E, 0x25, 0x59, 0x1D, 0xCD, 0x98, 0x69, 0xBB, 0xD3, + 0xCC, 0x32, 0xC9, 0x8D, 0xEF, 0x81, 0xFE, 0xAD, 0x7D, 0x89, 0xBB, 0xBA, + 0x60, 0x13, 0xCA, 0x65, 0x95, 0x67, 0xA0, 0xF3, 0x19, 0xF6, 0x03, 0x56, + 0xD4, 0x6A, 0xD3, 0x27, 0xE2, 0xA1, 0xAD, 0x83, 0xF0, 0x4A, 0x12, 0x22, + 0x77, 0x1C, 0x05, 0x73, 0xE2, 0x19, 0x71, 0x42, 0xC0, 0xEC, 0x75, 0x46, + 0x9A, 0x90, 0x58, 0xE0, 0x6A, 0x8E, 0x2B, 0xA5, 0x46, 0x30, 0x04, 0x8E, + 0x19, 0xB2, 0x17, 0xE3, 0xBE, 0xA9, 0xBA, 0x7F, 0x56, 0xF1, 0x24, 0x03, + 0xD7, 0xB2, 0x21, 0x28, 0x76, 0x0E, 0x36, 0x30, 0x4C, 0x79, 0xD5, 0x41, + 0x9A, 0x9A, 0xA8, 0xB8, 0x35, 0xBA, 0x0C, 0x3A, 0xF2, 0x44, 0x1B, 0x20, + 0x88, 0xF7, 0xC5, 0x25, 0xD7, 0x3D, 0xC6, 0xE3, 0x3E, 0x43, 0xDD, 0x87, + 0xFE, 0xC4, 0xEA, 0xF5, 0x53, 0x3E, 0x4C, 0x65, 0xFF, 0x3B, 0x4A, 0xCB, + 0x78, 0x5A, 0x6B, 0x17, 0x5F, 0x0D, 0xC7, 0xC3, 0x4F, 0x4E, 0x9A, 0x2A, + 0xA2, 0xED, 0x57, 0x4D, 0x22, 0xE2, 0x46, 0x9A, 0x3F, 0x0F, 0x91, 0x34, + 0x24, 0x7D, 0x55, 0xE3, 0x8C, 0x95, 0x37, 0xD3, 0x1A, 0xF0, 0x09, 0x2B, + 0x2C, 0xD2, 0xC9, 0x8D, 0xB4, 0x0D, 0x00, 0xAB, 0x67, 0x29, 0x28, 0xD8, + 0x01, 0xF5, 0x19, 0x04, 0xB6, 0x1D, 0xBE, 0x76, 0xFE, 0x72, 0x5C, 0xC4, + 0x85, 0xCA, 0xD2, 0x80, 0x41, 0xDF, 0x05, 0xA8, 0xA3, 0xD5, 0x84, 0x90, + 0x4F, 0x0B, 0xF3, 0xE0, 0x3F, 0x9B, 0x19, 0xD2, 0x37, 0x89, 0x3F, 0xF2, + 0x7B, 0x52, 0x1C, 0x8C, 0xF6, 0xE1, 0xF7, 0x3C, 0x07, 0x97, 0x8C, 0x0E, + 0xA2, 0x59, 0x81, 0x0C, 0xB2, 0x90, 0x3D, 0xD3, 0xE3, 0x59, 0x46, 0xED, + 0x0F, 0xA9, 0xA7, 0xDE, 0x80, 0x6B, 0x5A, 0xAA, 0x07, 0xB6, 0x19, 0xCB, + 0xBC, 0x57, 0xF3, 0x97, 0x21, 0x7A, 0x0C, 0xB1, 0x2B, 0x74, 0x3E, 0xEB, + 0xDA, 0xA7, 0x67, 0x2D, 0x4C, 0xC4, 0x98, 0x9E, 0x36, 0x09, 0x76, 0x66, + 0x66, 0xFC, 0x1A, 0x3F, 0xEA, 0x48, 0x54, 0x1C, 0xBE, 0x30, 0xBD, 0x80, + 0x50, 0xBF, 0x7C, 0xB5, 0xCE, 0x00, 0xF6, 0x0C, 0x61, 0xD9, 0xE7, 0x24, + 0x03, 0xE0, 0xE3, 0x01, 0x81, 0x0E, 0xBD, 0xD8, 0x85, 0x34, 0x88, 0xBD, + 0xB2, 0x36, 0xA8, 0x7B, 0x5C, 0x08, 0xE5, 0x44, 0x80, 0x8C, 0x6F, 0xF8, + 0x2F, 0xD5, 0x21, 0xCA, 0x1D, 0x1C, 0xD0, 0xFB, 0xC4, 0xB5, 0x87, 0xD1, + 0x3A, 0x4E, 0xC7, 0x76, 0xB5, 0x35, 0x48, 0xB5 +}; + +static const unsigned char TA561_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA562_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0E, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA562_RSA_N[] = { + 0xAB, 0xA4, 0x81, 0xE5, 0x95, 0xCD, 0xF5, 0xF6, 0x14, 0x8E, 0xC2, 0x4F, + 0xCA, 0xD4, 0xE2, 0x78, 0x95, 0x58, 0x9C, 0x41, 0xE1, 0x0D, 0x99, 0x40, + 0x24, 0x17, 0x39, 0x91, 0x33, 0x66, 0xE9, 0xBE, 0xE1, 0x83, 0xAF, 0x62, + 0x5C, 0x89, 0xD1, 0xFC, 0x24, 0x5B, 0x61, 0xB3, 0xE0, 0x11, 0x11, 0x41, + 0x1C, 0x1D, 0x6E, 0xF0, 0xB8, 0xBB, 0xF8, 0xDE, 0xA7, 0x81, 0xBA, 0xA6, + 0x48, 0xC6, 0x9F, 0x1D, 0xBD, 0xBE, 0x8E, 0xA9, 0x41, 0x3E, 0xB8, 0x94, + 0xED, 0x29, 0x1A, 0xD4, 0x8E, 0xD2, 0x03, 0x1D, 0x03, 0xEF, 0x6D, 0x0D, + 0x67, 0x1C, 0x57, 0xD7, 0x06, 0xAD, 0xCA, 0xC8, 0xF5, 0xFE, 0x0E, 0xAF, + 0x66, 0x25, 0x48, 0x04, 0x96, 0x0B, 0x5D, 0xA3, 0xBA, 0x16, 0xC3, 0x08, + 0x4F, 0xD1, 0x46, 0xF8, 0x14, 0x5C, 0xF2, 0xC8, 0x5E, 0x01, 0x99, 0x6D, + 0xFD, 0x88, 0xCC, 0x86, 0xA8, 0xC1, 0x6F, 0x31, 0x42, 0x6C, 0x52, 0x3E, + 0x68, 0xCB, 0xF3, 0x19, 0x34, 0xDF, 0xBB, 0x87, 0x18, 0x56, 0x80, 0x26, + 0xC4, 0xD0, 0xDC, 0xC0, 0x6F, 0xDF, 0xDE, 0xA0, 0xC2, 0x91, 0x16, 0xA0, + 0x64, 0x11, 0x4B, 0x44, 0xBC, 0x1E, 0xF6, 0xE7, 0xFA, 0x63, 0xDE, 0x66, + 0xAC, 0x76, 0xA4, 0x71, 0xA3, 0xEC, 0x36, 0x94, 0x68, 0x7A, 0x77, 0xA4, + 0xB1, 0xE7, 0x0E, 0x2F, 0x81, 0x7A, 0xE2, 0xB5, 0x72, 0x86, 0xEF, 0xA2, + 0x6B, 0x8B, 0xF0, 0x0F, 0xDB, 0xD3, 0x59, 0x3F, 0xBA, 0x72, 0xBC, 0x44, + 0x24, 0x9C, 0xE3, 0x73, 0xB3, 0xF7, 0xAF, 0x57, 0x2F, 0x42, 0x26, 0x9D, + 0xA9, 0x74, 0xBA, 0x00, 0x52, 0xF2, 0x4B, 0xCD, 0x53, 0x7C, 0x47, 0x0B, + 0x36, 0x85, 0x0E, 0x66, 0xA9, 0x08, 0x97, 0x16, 0x34, 0x57, 0xC1, 0x66, + 0xF7, 0x80, 0xE3, 0xED, 0x70, 0x54, 0xC7, 0x93, 0xE0, 0x2E, 0x28, 0x15, + 0x59, 0x87, 0xBA, 0xBB +}; + +static const unsigned char TA562_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA563_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x30, 0x30, 0x2E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x27, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x61, + 0x6E, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0C, 0x43, 0x46, 0x43, 0x41, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA563_RSA_N[] = { + 0xD7, 0x5D, 0x6B, 0xCD, 0x10, 0x3F, 0x1F, 0x05, 0x59, 0xD5, 0x05, 0x4D, + 0x37, 0xB1, 0x0E, 0xEC, 0x98, 0x2B, 0x8E, 0x15, 0x1D, 0xFA, 0x93, 0x4B, + 0x17, 0x82, 0x21, 0x71, 0x10, 0x52, 0xD7, 0x51, 0x64, 0x70, 0x16, 0xC2, + 0x55, 0x69, 0x4D, 0x8E, 0x15, 0x6D, 0x9F, 0xBF, 0x0C, 0x1B, 0xC2, 0xE0, + 0xA3, 0x67, 0xD6, 0x0C, 0xAC, 0xCF, 0x22, 0xAE, 0xAF, 0x77, 0x54, 0x2A, + 0x4B, 0x4C, 0x8A, 0x53, 0x52, 0x7A, 0xC3, 0xEE, 0x2E, 0xDE, 0xB3, 0x71, + 0x25, 0xC1, 0xE9, 0x5D, 0x3D, 0xEE, 0xA1, 0x2F, 0xA3, 0xF7, 0x2A, 0x3C, + 0xC9, 0x23, 0x1D, 0x6A, 0xAB, 0x1D, 0xA1, 0xA7, 0xF1, 0xF3, 0xEC, 0xA0, + 0xD5, 0x44, 0xCF, 0x15, 0xCF, 0x72, 0x2F, 0x1D, 0x63, 0x97, 0xE8, 0x99, + 0xF9, 0xFD, 0x93, 0xA4, 0x54, 0x80, 0x4C, 0x52, 0xD4, 0x52, 0xAB, 0x2E, + 0x49, 0xDF, 0x90, 0xCD, 0xB8, 0x5F, 0xBE, 0x3F, 0xDE, 0xA1, 0xCA, 0x4D, + 0x20, 0xD4, 0x25, 0xE8, 0x84, 0x29, 0x53, 0xB7, 0xB1, 0x88, 0x1F, 0xFF, + 0xFA, 0xDA, 0x90, 0x9F, 0x0A, 0xA9, 0x2D, 0x41, 0x3F, 0xB1, 0xF1, 0x18, + 0x29, 0xEE, 0x16, 0x59, 0x2C, 0x34, 0x49, 0x1A, 0xA8, 0x06, 0xD7, 0xA8, + 0x88, 0xD2, 0x03, 0x72, 0x7A, 0x32, 0xE2, 0xEA, 0x68, 0x4D, 0x6E, 0x2C, + 0x96, 0x65, 0x7B, 0xCA, 0x59, 0xFA, 0xF2, 0xE2, 0xDD, 0xEE, 0x30, 0x2C, + 0xFB, 0xCC, 0x46, 0xAC, 0xC4, 0x63, 0xEB, 0x6F, 0x7F, 0x36, 0x2B, 0x34, + 0x73, 0x12, 0x94, 0x7F, 0xDF, 0xCC, 0x26, 0x9E, 0xF1, 0x72, 0x5D, 0x50, + 0x65, 0x59, 0x8F, 0x69, 0xB3, 0x87, 0x5E, 0x32, 0x6F, 0xC3, 0x18, 0x8A, + 0xB5, 0x95, 0x8F, 0xB0, 0x7A, 0x37, 0xDE, 0x5A, 0x45, 0x3B, 0xC7, 0x36, + 0xE1, 0xEF, 0x67, 0xD1, 0x39, 0xD3, 0x97, 0x5B, 0x73, 0x62, 0x19, 0x48, + 0x2D, 0x87, 0x1C, 0x06, 0xFB, 0x74, 0x98, 0x20, 0x49, 0x73, 0xF0, 0x05, + 0xD2, 0x1B, 0xB1, 0xA0, 0xA3, 0xB7, 0x1B, 0x70, 0xD3, 0x88, 0x69, 0xB9, + 0x5A, 0xD6, 0x38, 0xF4, 0x62, 0xDC, 0x25, 0x8B, 0x78, 0xBF, 0xF8, 0xE8, + 0x7E, 0xB8, 0x5C, 0xC9, 0x95, 0x4F, 0x5F, 0xA7, 0x2D, 0xB9, 0x20, 0x6B, + 0xCF, 0x6B, 0xDD, 0xF5, 0x0D, 0xF4, 0x82, 0xB7, 0xF4, 0xB2, 0x66, 0x2E, + 0x10, 0x28, 0xF6, 0x97, 0x5A, 0x7B, 0x96, 0x16, 0x8F, 0x01, 0x19, 0x2D, + 0x6C, 0x6E, 0x7F, 0x39, 0x58, 0x06, 0x64, 0x83, 0x01, 0x83, 0x83, 0xC3, + 0x4D, 0x92, 0xDD, 0x32, 0xC6, 0x87, 0xA4, 0x37, 0xE9, 0x16, 0xCE, 0xAA, + 0x2D, 0x68, 0xAF, 0x0A, 0x81, 0x65, 0x3A, 0x70, 0xC1, 0x9B, 0xAD, 0x4D, + 0x6D, 0x54, 0xCA, 0x2A, 0x2D, 0x4B, 0x85, 0x1B, 0xB3, 0x80, 0xE6, 0x70, + 0x45, 0x0D, 0x6B, 0x5E, 0x35, 0xF0, 0x7F, 0x3B, 0xB8, 0x9C, 0xE4, 0x04, + 0x70, 0x89, 0x12, 0x25, 0x93, 0xDA, 0x0A, 0x99, 0x22, 0x60, 0x6A, 0x63, + 0x60, 0x4E, 0x76, 0x06, 0x98, 0x4E, 0xBD, 0x83, 0xAD, 0x1D, 0x58, 0x8A, + 0x25, 0x85, 0xD2, 0xC7, 0x65, 0x1E, 0x2D, 0x8E, 0xC6, 0xDF, 0xB6, 0xC6, + 0xE1, 0x7F, 0x8A, 0x04, 0x21, 0x15, 0x29, 0x74, 0xF0, 0x3E, 0x9C, 0x90, + 0x9D, 0x0C, 0x2E, 0xF1, 0x8A, 0x3E, 0x5A, 0xAA, 0x0C, 0x09, 0x1E, 0xC7, + 0xD5, 0x3C, 0xA3, 0xED, 0x97, 0xC3, 0x1E, 0x34, 0xFA, 0x38, 0xF9, 0x08, + 0x0E, 0xE3, 0xC0, 0x5D, 0x2B, 0x83, 0xD1, 0x56, 0x6A, 0xC9, 0xB6, 0xA8, + 0x54, 0x53, 0x2E, 0x78, 0x32, 0x67, 0x3D, 0x82, 0x7F, 0x74, 0xD0, 0xFB, + 0xE1, 0xB6, 0x05, 0x60, 0xB9, 0x70, 0xDB, 0x8E, 0x0B, 0xF9, 0x13, 0x58, + 0x6F, 0x71, 0x60, 0x10, 0x52, 0x10, 0xB9, 0xC1, 0x41, 0x09, 0xEF, 0x72, + 0x1F, 0x67, 0x31, 0x78, 0xFF, 0x96, 0x05, 0x8D +}; + +static const unsigned char TA563_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA564_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA564_EC_Q[] = { + 0x04, 0x4B, 0x36, 0xE9, 0xAE, 0x57, 0x5E, 0xA8, 0x70, 0xD7, 0xD0, 0x8F, + 0x74, 0x62, 0x77, 0xC3, 0x5E, 0x7A, 0xAA, 0xE5, 0xB6, 0xA2, 0xF1, 0x78, + 0xFD, 0x02, 0x7E, 0x57, 0xDD, 0x91, 0x79, 0x9C, 0x6C, 0xB9, 0x52, 0x88, + 0x54, 0xBC, 0x2F, 0x04, 0xBE, 0xB8, 0xCD, 0xF6, 0x10, 0xD1, 0x29, 0xEC, + 0xB5, 0xD0, 0xA0, 0xC3, 0xF0, 0x89, 0x70, 0x19, 0xBB, 0x51, 0x65, 0xC5, + 0x43, 0x9C, 0xC3, 0x9B, 0x63, 0x9D, 0x20, 0x83, 0x3E, 0x06, 0x0B, 0xA6, + 0x42, 0x44, 0x85, 0x11, 0xA7, 0x4A, 0x3A, 0x2D, 0xE9, 0xD6, 0x68, 0x2F, + 0x48, 0x4E, 0x53, 0x2B, 0x07, 0x3F, 0x4D, 0xBD, 0xB9, 0xAC, 0x77, 0x39, + 0x57 +}; + +static const unsigned char TA565_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA565_EC_Q[] = { + 0x04, 0x78, 0x30, 0x81, 0xE8, 0x63, 0x1E, 0xE5, 0xEB, 0x71, 0x51, 0x0F, + 0xF7, 0x07, 0x07, 0xCA, 0x39, 0x99, 0x7C, 0x4E, 0xD5, 0x0F, 0xCC, 0x30, + 0x30, 0x0B, 0x8F, 0x66, 0x93, 0x3E, 0xCF, 0xBD, 0xC5, 0x86, 0xBD, 0xF9, + 0xB1, 0xB7, 0xB4, 0x3E, 0xB4, 0x07, 0xC8, 0xF3, 0x96, 0x31, 0xF3, 0xED, + 0xA4, 0x4F, 0xF8, 0xA3, 0x4E, 0x8D, 0x29, 0x15, 0x58, 0xB8, 0xD5, 0x6F, + 0x7F, 0xEE, 0x6C, 0x22, 0xB5, 0xB0, 0xAF, 0x48, 0x45, 0x0A, 0xBD, 0xA8, + 0x49, 0x94, 0xBF, 0x84, 0x43, 0xB0, 0xDB, 0x84, 0x4A, 0x03, 0x23, 0x19, + 0x67, 0x6A, 0x6F, 0xC1, 0x6E, 0xBC, 0x06, 0x39, 0x37, 0xD1, 0x88, 0x22, + 0xF7 +}; + +static const unsigned char TA566_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA566_RSA_N[] = { + 0xB0, 0x48, 0x65, 0xA3, 0x0D, 0x1D, 0x42, 0xE3, 0x91, 0x6D, 0x9D, 0x84, + 0xA4, 0x61, 0x96, 0x12, 0xC2, 0xED, 0xC3, 0xDA, 0x23, 0x34, 0x19, 0x76, + 0xF6, 0xEA, 0xFD, 0x55, 0x5A, 0xF6, 0x55, 0x01, 0x53, 0x0F, 0xF2, 0xCC, + 0x8C, 0x97, 0x4F, 0xB9, 0x50, 0xCB, 0xB3, 0x01, 0x44, 0x56, 0x96, 0xFD, + 0x9B, 0x28, 0xEC, 0x7B, 0x74, 0x0B, 0xE7, 0x42, 0x6B, 0x55, 0xCE, 0xC9, + 0x61, 0xB2, 0xE8, 0xAD, 0x40, 0x3C, 0xBA, 0xB9, 0x41, 0x0A, 0x05, 0x4F, + 0x1B, 0x26, 0x85, 0x8F, 0x43, 0xB5, 0x40, 0xB5, 0x85, 0xD1, 0xD4, 0x71, + 0xDC, 0x83, 0x41, 0xF3, 0xF6, 0x45, 0xC7, 0x80, 0xA2, 0x84, 0x50, 0x97, + 0x46, 0xCE, 0xA0, 0x0C, 0xC4, 0x60, 0x56, 0x04, 0x1D, 0x07, 0x5B, 0x46, + 0xA5, 0x0E, 0xB2, 0x4B, 0xA4, 0x0E, 0xA5, 0x7C, 0xEE, 0xF8, 0xD4, 0x62, + 0x03, 0xB9, 0x93, 0x6A, 0x8A, 0x14, 0xB8, 0x70, 0xF8, 0x2E, 0x82, 0x46, + 0x38, 0x23, 0x0E, 0x74, 0xC7, 0x6B, 0x41, 0xB7, 0xD0, 0x29, 0xA3, 0x9D, + 0x80, 0xB0, 0x7E, 0x77, 0x93, 0x63, 0x42, 0xFB, 0x34, 0x83, 0x3B, 0x73, + 0xA3, 0x5A, 0x21, 0x36, 0xEB, 0x47, 0xFA, 0x18, 0x17, 0xD9, 0xBA, 0x66, + 0xC2, 0x93, 0xA4, 0x8F, 0xFC, 0x5D, 0xA4, 0xAD, 0xFC, 0x50, 0x6A, 0x95, + 0xAC, 0xBC, 0x24, 0x33, 0xD1, 0xBD, 0x88, 0x7F, 0x86, 0xF5, 0xF5, 0xB2, + 0x73, 0x2A, 0x8F, 0x7C, 0xAF, 0x08, 0xF2, 0x1A, 0x98, 0x3F, 0xA9, 0x81, + 0x65, 0x3F, 0xC1, 0x8C, 0x89, 0xC5, 0x96, 0x30, 0x9A, 0x0A, 0xCF, 0xF4, + 0xD4, 0xC8, 0x34, 0xED, 0x9D, 0x2F, 0xBC, 0x8D, 0x38, 0x86, 0x53, 0xEE, + 0x97, 0x9F, 0xA9, 0xB2, 0x63, 0x94, 0x17, 0x8D, 0x0F, 0xDC, 0x66, 0x2A, + 0x7C, 0x52, 0x51, 0x75, 0xCB, 0x99, 0x8E, 0xE8, 0x3D, 0x5C, 0xBF, 0x9E, + 0x3B, 0x28, 0x8D, 0x83, 0x02, 0x0F, 0xA9, 0x9F, 0x72, 0xE2, 0x2C, 0x2B, + 0xB3, 0xDC, 0x66, 0x97, 0x00, 0x40, 0xD0, 0xA4, 0x54, 0x8E, 0x9B, 0x5D, + 0x7B, 0x45, 0x36, 0x26, 0xD6, 0x72, 0x43, 0xEB, 0xCF, 0xC0, 0xEA, 0x0D, + 0xDC, 0xCE, 0x12, 0xE6, 0x7D, 0x38, 0x9F, 0x05, 0x27, 0xA8, 0x97, 0x3E, + 0xE9, 0x51, 0xC6, 0x6C, 0x05, 0x28, 0xC1, 0x02, 0x0F, 0xE9, 0x18, 0x6D, + 0xEC, 0xBD, 0x9C, 0x06, 0xD4, 0xA7, 0x49, 0xF4, 0x54, 0x05, 0x6B, 0x6C, + 0x30, 0xF1, 0xEB, 0x03, 0xD5, 0xEA, 0x3D, 0x6A, 0x76, 0xC2, 0xCB, 0x1A, + 0x28, 0x49, 0x4D, 0x7F, 0x64, 0xE0, 0xFA, 0x2B, 0xDA, 0x73, 0x83, 0x81, + 0xFF, 0x91, 0x03, 0xBD, 0x94, 0xBB, 0xE4, 0xB8, 0x8E, 0x9C, 0x32, 0x63, + 0xCD, 0x9F, 0xBB, 0x68, 0x81, 0xB1, 0x84, 0x5B, 0xAF, 0x36, 0xBF, 0x77, + 0xEE, 0x1D, 0x7F, 0xF7, 0x49, 0x9B, 0x52, 0xEC, 0xD2, 0x77, 0x5A, 0x7D, + 0x91, 0x9D, 0x4D, 0xC2, 0x39, 0x2D, 0xE4, 0xBA, 0x82, 0xF8, 0x6F, 0xF2, + 0x4E, 0x1E, 0x0F, 0x4E, 0xE6, 0x3F, 0x59, 0xA5, 0x23, 0xDC, 0x3D, 0x87, + 0xA8, 0x28, 0x58, 0x28, 0xD1, 0xF1, 0x1B, 0x36, 0xDB, 0x4F, 0xC4, 0xFF, + 0xE1, 0x8C, 0x5B, 0x72, 0x8C, 0xC7, 0x26, 0x03, 0x27, 0xA3, 0x39, 0x0A, + 0x01, 0xAA, 0xC0, 0xB2, 0x31, 0x60, 0x83, 0x22, 0xA1, 0x4F, 0x12, 0x09, + 0x01, 0x11, 0xAF, 0x34, 0xD4, 0xCF, 0xD7, 0xAE, 0x62, 0xD3, 0x05, 0x07, + 0xB4, 0x31, 0x75, 0xE0, 0x0D, 0x6D, 0x57, 0x4F, 0x69, 0x87, 0xF9, 0x57, + 0xA9, 0xBA, 0x15, 0xF6, 0xC8, 0x52, 0x6D, 0xA1, 0xCB, 0x9C, 0x1F, 0xE5, + 0xFC, 0x78, 0xA8, 0x35, 0x9A, 0x9F, 0x41, 0x14, 0xCE, 0xA5, 0xB4, 0xCE, + 0x94, 0x08, 0x1C, 0x09, 0xAD, 0x56, 0xE5, 0xDA, 0xB6, 0x49, 0x9A, 0x4A, + 0xEA, 0x63, 0x18, 0x53, 0x9C, 0x2C, 0x2E, 0xC3 +}; + +static const unsigned char TA566_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA567_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA567_RSA_N[] = { + 0xE1, 0xFA, 0x0E, 0xFB, 0x68, 0x00, 0x12, 0xC8, 0x4D, 0xD5, 0xAC, 0x22, + 0xC4, 0x35, 0x01, 0x3B, 0xC5, 0x54, 0xE5, 0x59, 0x76, 0x63, 0xA5, 0x7F, + 0xEB, 0xC1, 0xC4, 0x6A, 0x98, 0xBD, 0x32, 0x8D, 0x17, 0x80, 0xEB, 0x5D, + 0xBA, 0xD1, 0x62, 0x3D, 0x25, 0x23, 0x19, 0x35, 0x14, 0xE9, 0x7F, 0x89, + 0xA7, 0x1B, 0x62, 0x3C, 0xD6, 0x50, 0xE7, 0x34, 0x95, 0x03, 0x32, 0xB1, + 0xB4, 0x93, 0x22, 0x3D, 0xA7, 0xE2, 0xB1, 0xED, 0xE6, 0x7B, 0x4E, 0x2E, + 0x87, 0x9B, 0x0D, 0x33, 0x75, 0x0A, 0xDE, 0xAA, 0x35, 0xE7, 0x7E, 0xE5, + 0x36, 0x98, 0xA2, 0xAE, 0x25, 0x9E, 0x95, 0xB3, 0x32, 0x96, 0xA4, 0x2B, + 0x58, 0x1E, 0xEF, 0x3F, 0xFE, 0x62, 0x34, 0x48, 0x51, 0xD1, 0xB4, 0x8D, + 0x42, 0xAD, 0x60, 0xDA, 0x49, 0x6A, 0x95, 0x70, 0xDD, 0xD2, 0x00, 0xE2, + 0xCC, 0x57, 0x63, 0x02, 0x7B, 0x96, 0xDD, 0x49, 0x97, 0x5B, 0x92, 0x4E, + 0x95, 0xD3, 0xF9, 0xCB, 0x29, 0x1F, 0x18, 0x4A, 0xF8, 0x01, 0x2A, 0xD2, + 0x63, 0x09, 0x6E, 0x24, 0xE9, 0x89, 0xD2, 0xE5, 0xC7, 0x22, 0x4C, 0xDC, + 0x73, 0x86, 0x47, 0x00, 0xAA, 0x0D, 0x88, 0x8E, 0xAE, 0x85, 0x7D, 0x4A, + 0xE9, 0xBB, 0x33, 0x4F, 0x0E, 0x52, 0x70, 0x9D, 0x95, 0xE3, 0x7C, 0x6D, + 0x96, 0x5B, 0x2D, 0x3D, 0x5F, 0xA1, 0x83, 0x46, 0x5D, 0xB6, 0xE3, 0x25, + 0xB8, 0x7C, 0xA7, 0x19, 0x80, 0x1C, 0xEA, 0x65, 0x43, 0xDC, 0x91, 0x79, + 0x36, 0x2C, 0x74, 0x7C, 0xF2, 0x67, 0x06, 0xC9, 0x89, 0xC9, 0xDB, 0xBF, + 0xDA, 0x68, 0xBF, 0x23, 0xED, 0xDC, 0x6B, 0xAD, 0x28, 0x83, 0x79, 0x2F, + 0xEC, 0x38, 0xA5, 0x0D, 0x37, 0x01, 0x67, 0x27, 0x9A, 0xE9, 0x33, 0xD9, + 0x33, 0x5F, 0x37, 0xA1, 0xC5, 0xF0, 0xAB, 0x3D, 0xFA, 0x78, 0xB0, 0xE7, + 0x2C, 0x9F, 0xF6, 0x3E, 0x9F, 0x60, 0xE0, 0xEF, 0x48, 0xE9, 0x90, 0x45, + 0x1E, 0x05, 0x51, 0x78, 0x1A, 0x2C, 0x12, 0x2C, 0x5C, 0x28, 0xAC, 0x0D, + 0xA2, 0x23, 0x9E, 0x34, 0x8F, 0x05, 0xE6, 0xA2, 0x33, 0xCE, 0x11, 0x77, + 0x13, 0xD4, 0x0E, 0xA4, 0x1E, 0x42, 0x1F, 0x86, 0xCD, 0x70, 0xFE, 0xD9, + 0x2E, 0x15, 0x3D, 0x1D, 0xBB, 0xB8, 0xF2, 0x53, 0x57, 0xDB, 0xCC, 0xC6, + 0x74, 0x29, 0x9C, 0x18, 0xB3, 0x36, 0x75, 0x38, 0x2E, 0x0F, 0x54, 0xA1, + 0xF8, 0x92, 0x1F, 0x89, 0x96, 0x4F, 0xBB, 0xD4, 0xEE, 0x9D, 0xE9, 0x3B, + 0x36, 0x42, 0xB5, 0x0A, 0x3B, 0x2A, 0xD4, 0x64, 0x79, 0x36, 0x10, 0xE1, + 0xF9, 0x91, 0x03, 0x2B, 0x7B, 0x20, 0x54, 0xCD, 0x0D, 0x19, 0x1A, 0xC8, + 0x41, 0x32, 0x34, 0xD1, 0xB0, 0x99, 0xE1, 0x90, 0x1E, 0x01, 0x40, 0x36, + 0xB5, 0xB7, 0xFA, 0xA9, 0xE5, 0x77, 0x75, 0xA4, 0x22, 0x81, 0x5D, 0xB0, + 0x8B, 0xE4, 0x27, 0x12, 0x0F, 0x54, 0x88, 0xC6, 0xDB, 0x85, 0x74, 0xE6, + 0xB7, 0xC0, 0xD7, 0xA6, 0x29, 0xFA, 0xDB, 0xDE, 0xF3, 0x93, 0x97, 0x27, + 0x04, 0x55, 0x2F, 0x0A, 0x6F, 0x37, 0xC5, 0x3D, 0x13, 0xAF, 0x0A, 0x00, + 0xA9, 0x2C, 0x8B, 0x1C, 0x81, 0x28, 0xD7, 0xEF, 0x86, 0x31, 0xA9, 0xAE, + 0xF2, 0x6E, 0xB8, 0xCA, 0x6A, 0x2C, 0x54, 0x47, 0xD8, 0x2A, 0x88, 0x2E, + 0xAF, 0xC1, 0x07, 0x10, 0x78, 0xAC, 0x11, 0xA2, 0x2F, 0x42, 0xF0, 0x37, + 0xC5, 0xF2, 0xB8, 0x56, 0xDD, 0x0E, 0x62, 0x2D, 0xCE, 0x2D, 0x56, 0x7E, + 0x55, 0xF2, 0xA7, 0x44, 0xF6, 0x2B, 0x32, 0xF4, 0x23, 0xA8, 0x47, 0xE8, + 0xD4, 0x2A, 0x01, 0x78, 0xCF, 0x6A, 0xC3, 0x37, 0xA8, 0x9E, 0x65, 0xD2, + 0x2C, 0xE5, 0xFA, 0xBA, 0x33, 0xC1, 0x06, 0x44, 0xF6, 0xE6, 0xCF, 0xA5, + 0x0D, 0xA7, 0x66, 0x08, 0x34, 0x8A, 0x2C, 0xF3 +}; + +static const unsigned char TA567_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA568_DN[] = { + 0x30, 0x7B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, 0x61, + 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x53, 0x61, 0x6C, 0x66, 0x6F, + 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x11, 0x43, 0x6F, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x43, 0x41, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x18, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73 +}; + +static const unsigned char TA568_RSA_N[] = { + 0xBE, 0x40, 0x9D, 0xF4, 0x6E, 0xE1, 0xEA, 0x76, 0x87, 0x1C, 0x4D, 0x45, + 0x44, 0x8E, 0xBE, 0x46, 0xC8, 0x83, 0x06, 0x9D, 0xC1, 0x2A, 0xFE, 0x18, + 0x1F, 0x8E, 0xE4, 0x02, 0xFA, 0xF3, 0xAB, 0x5D, 0x50, 0x8A, 0x16, 0x31, + 0x0B, 0x9A, 0x06, 0xD0, 0xC5, 0x70, 0x22, 0xCD, 0x49, 0x2D, 0x54, 0x63, + 0xCC, 0xB6, 0x6E, 0x68, 0x46, 0x0B, 0x53, 0xEA, 0xCB, 0x4C, 0x24, 0xC0, + 0xBC, 0x72, 0x4E, 0xEA, 0xF1, 0x15, 0xAE, 0xF4, 0x54, 0x9A, 0x12, 0x0A, + 0xC3, 0x7A, 0xB2, 0x33, 0x60, 0xE2, 0xDA, 0x89, 0x55, 0xF3, 0x22, 0x58, + 0xF3, 0xDE, 0xDC, 0xCF, 0xEF, 0x83, 0x86, 0xA2, 0x8C, 0x94, 0x4F, 0x9F, + 0x68, 0xF2, 0x98, 0x90, 0x46, 0x84, 0x27, 0xC7, 0x76, 0xBF, 0xE3, 0xCC, + 0x35, 0x2C, 0x8B, 0x5E, 0x07, 0x64, 0x65, 0x82, 0xC0, 0x48, 0xB0, 0xA8, + 0x91, 0xF9, 0x61, 0x9F, 0x76, 0x20, 0x50, 0xA8, 0x91, 0xC7, 0x66, 0xB5, + 0xEB, 0x78, 0x62, 0x03, 0x56, 0xF0, 0x8A, 0x1A, 0x13, 0xEA, 0x31, 0xA3, + 0x1E, 0xA0, 0x99, 0xFD, 0x38, 0xF6, 0xF6, 0x27, 0x32, 0x58, 0x6F, 0x07, + 0xF5, 0x6B, 0xB8, 0xFB, 0x14, 0x2B, 0xAF, 0xB7, 0xAA, 0xCC, 0xD6, 0x63, + 0x5F, 0x73, 0x8C, 0xDA, 0x05, 0x99, 0xA8, 0x38, 0xA8, 0xCB, 0x17, 0x78, + 0x36, 0x51, 0xAC, 0xE9, 0x9E, 0xF4, 0x78, 0x3A, 0x8D, 0xCF, 0x0F, 0xD9, + 0x42, 0xE2, 0x98, 0x0C, 0xAB, 0x2F, 0x9F, 0x0E, 0x01, 0xDE, 0xEF, 0x9F, + 0x99, 0x49, 0xF1, 0x2D, 0xDF, 0xAC, 0x74, 0x4D, 0x1B, 0x98, 0xB5, 0x47, + 0xC5, 0xE5, 0x29, 0xD1, 0xF9, 0x90, 0x18, 0xC7, 0x62, 0x9C, 0xBE, 0x83, + 0xC7, 0x26, 0x7B, 0x3E, 0x8A, 0x25, 0xC7, 0xC0, 0xDD, 0x9D, 0xE6, 0x35, + 0x68, 0x10, 0x20, 0x9D, 0x8F, 0xD8, 0xDE, 0xD2, 0xC3, 0x84, 0x9C, 0x0D, + 0x5E, 0xE8, 0x2F, 0xC9 +}; + +static const unsigned char TA568_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA569_DN[] = { + 0x30, 0x81, 0x81, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA569_RSA_N[] = { + 0xD0, 0x40, 0x8B, 0x8B, 0x72, 0xE3, 0x91, 0x1B, 0xF7, 0x51, 0xC1, 0x1B, + 0x54, 0x04, 0x98, 0xD3, 0xA9, 0xBF, 0xC1, 0xE6, 0x8A, 0x5D, 0x3B, 0x87, + 0xFB, 0xBB, 0x88, 0xCE, 0x0D, 0xE3, 0x2F, 0x3F, 0x06, 0x96, 0xF0, 0xA2, + 0x29, 0x50, 0x99, 0xAE, 0xDB, 0x3B, 0xA1, 0x57, 0xB0, 0x74, 0x51, 0x71, + 0xCD, 0xED, 0x42, 0x91, 0x4D, 0x41, 0xFE, 0xA9, 0xC8, 0xD8, 0x6A, 0x86, + 0x77, 0x44, 0xBB, 0x59, 0x66, 0x97, 0x50, 0x5E, 0xB4, 0xD4, 0x2C, 0x70, + 0x44, 0xCF, 0xDA, 0x37, 0x95, 0x42, 0x69, 0x3C, 0x30, 0xC4, 0x71, 0xB3, + 0x52, 0xF0, 0x21, 0x4D, 0xA1, 0xD8, 0xBA, 0x39, 0x7C, 0x1C, 0x9E, 0xA3, + 0x24, 0x9D, 0xF2, 0x83, 0x16, 0x98, 0xAA, 0x16, 0x7C, 0x43, 0x9B, 0x15, + 0x5B, 0xB7, 0xAE, 0x34, 0x91, 0xFE, 0xD4, 0x62, 0x26, 0x18, 0x46, 0x9A, + 0x3F, 0xEB, 0xC1, 0xF9, 0xF1, 0x90, 0x57, 0xEB, 0xAC, 0x7A, 0x0D, 0x8B, + 0xDB, 0x72, 0x30, 0x6A, 0x66, 0xD5, 0xE0, 0x46, 0xA3, 0x70, 0xDC, 0x68, + 0xD9, 0xFF, 0x04, 0x48, 0x89, 0x77, 0xDE, 0xB5, 0xE9, 0xFB, 0x67, 0x6D, + 0x41, 0xE9, 0xBC, 0x39, 0xBD, 0x32, 0xD9, 0x62, 0x02, 0xF1, 0xB1, 0xA8, + 0x3D, 0x6E, 0x37, 0x9C, 0xE2, 0x2F, 0xE2, 0xD3, 0xA2, 0x26, 0x8B, 0xC6, + 0xB8, 0x55, 0x43, 0x88, 0xE1, 0x23, 0x3E, 0xA5, 0xD2, 0x24, 0x39, 0x6A, + 0x47, 0xAB, 0x00, 0xD4, 0xA1, 0xB3, 0xA9, 0x25, 0xFE, 0x0D, 0x3F, 0xA7, + 0x1D, 0xBA, 0xD3, 0x51, 0xC1, 0x0B, 0xA4, 0xDA, 0xAC, 0x38, 0xEF, 0x55, + 0x50, 0x24, 0x05, 0x65, 0x46, 0x93, 0x34, 0x4F, 0x2D, 0x8D, 0xAD, 0xC6, + 0xD4, 0x21, 0x19, 0xD2, 0x8E, 0xCA, 0x05, 0x61, 0x71, 0x07, 0x73, 0x47, + 0xE5, 0x8A, 0x19, 0x12, 0xBD, 0x04, 0x4D, 0xCE, 0x4E, 0x9C, 0xA5, 0x48, + 0xAC, 0xBB, 0x26, 0xF7 +}; + +static const unsigned char TA569_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA570_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA570_EC_Q[] = { + 0x04, 0x03, 0x47, 0x7B, 0x2F, 0x75, 0xC9, 0x82, 0x15, 0x85, 0xFB, 0x75, + 0xE4, 0x91, 0x16, 0xD4, 0xAB, 0x62, 0x99, 0xF5, 0x3E, 0x52, 0x0B, 0x06, + 0xCE, 0x41, 0x00, 0x7F, 0x97, 0xE1, 0x0A, 0x24, 0x3C, 0x1D, 0x01, 0x04, + 0xEE, 0x3D, 0xD2, 0x8D, 0x09, 0x97, 0x0C, 0xE0, 0x75, 0xE4, 0xFA, 0xFB, + 0x77, 0x8A, 0x2A, 0xF5, 0x03, 0x60, 0x4B, 0x36, 0x8B, 0x16, 0x23, 0x16, + 0xAD, 0x09, 0x71, 0xF4, 0x4A, 0xF4, 0x28, 0x50, 0xB4, 0xFE, 0x88, 0x1C, + 0x6E, 0x3F, 0x6C, 0x2F, 0x2F, 0x09, 0x59, 0x5B, 0xA5, 0x5B, 0x0B, 0x33, + 0x99, 0xE2, 0xC3, 0x3D, 0x89, 0xF9, 0x6A, 0x2C, 0xEF, 0xB2, 0xD3, 0x06, + 0xE9 +}; + +static const unsigned char TA571_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA571_RSA_N[] = { + 0x91, 0xE8, 0x54, 0x92, 0xD2, 0x0A, 0x56, 0xB1, 0xAC, 0x0D, 0x24, 0xDD, + 0xC5, 0xCF, 0x44, 0x67, 0x74, 0x99, 0x2B, 0x37, 0xA3, 0x7D, 0x23, 0x70, + 0x00, 0x71, 0xBC, 0x53, 0xDF, 0xC4, 0xFA, 0x2A, 0x12, 0x8F, 0x4B, 0x7F, + 0x10, 0x56, 0xBD, 0x9F, 0x70, 0x72, 0xB7, 0x61, 0x7F, 0xC9, 0x4B, 0x0F, + 0x17, 0xA7, 0x3D, 0xE3, 0xB0, 0x04, 0x61, 0xEE, 0xFF, 0x11, 0x97, 0xC7, + 0xF4, 0x86, 0x3E, 0x0A, 0xFA, 0x3E, 0x5C, 0xF9, 0x93, 0xE6, 0x34, 0x7A, + 0xD9, 0x14, 0x6B, 0xE7, 0x9C, 0xB3, 0x85, 0xA0, 0x82, 0x7A, 0x76, 0xAF, + 0x71, 0x90, 0xD7, 0xEC, 0xFD, 0x0D, 0xFA, 0x9C, 0x6C, 0xFA, 0xDF, 0xB0, + 0x82, 0xF4, 0x14, 0x7E, 0xF9, 0xBE, 0xC4, 0xA6, 0x2F, 0x4F, 0x7F, 0x99, + 0x7F, 0xB5, 0xFC, 0x67, 0x43, 0x72, 0xBD, 0x0C, 0x00, 0xD6, 0x89, 0xEB, + 0x6B, 0x2C, 0xD3, 0xED, 0x8F, 0x98, 0x1C, 0x14, 0xAB, 0x7E, 0xE5, 0xE3, + 0x6E, 0xFC, 0xD8, 0xA8, 0xE4, 0x92, 0x24, 0xDA, 0x43, 0x6B, 0x62, 0xB8, + 0x55, 0xFD, 0xEA, 0xC1, 0xBC, 0x6C, 0xB6, 0x8B, 0xF3, 0x0E, 0x8D, 0x9A, + 0xE4, 0x9B, 0x6C, 0x69, 0x99, 0xF8, 0x78, 0x48, 0x30, 0x45, 0xD5, 0xAD, + 0xE1, 0x0D, 0x3C, 0x45, 0x60, 0xFC, 0x32, 0x96, 0x51, 0x27, 0xBC, 0x67, + 0xC3, 0xCA, 0x2E, 0xB6, 0x6B, 0xEA, 0x46, 0xC7, 0xC7, 0x20, 0xA0, 0xB1, + 0x1F, 0x65, 0xDE, 0x48, 0x08, 0xBA, 0xA4, 0x4E, 0xA9, 0xF2, 0x83, 0x46, + 0x37, 0x84, 0xEB, 0xE8, 0xCC, 0x81, 0x48, 0x43, 0x67, 0x4E, 0x72, 0x2A, + 0x9B, 0x5C, 0xBD, 0x4C, 0x1B, 0x28, 0x8A, 0x5C, 0x22, 0x7B, 0xB4, 0xAB, + 0x98, 0xD9, 0xEE, 0xE0, 0x51, 0x83, 0xC3, 0x09, 0x46, 0x4E, 0x6D, 0x3E, + 0x99, 0xFA, 0x95, 0x17, 0xDA, 0x7C, 0x33, 0x57, 0x41, 0x3C, 0x8D, 0x51, + 0xED, 0x0B, 0xB6, 0x5C, 0xAF, 0x2C, 0x63, 0x1A, 0xDF, 0x57, 0xC8, 0x3F, + 0xBC, 0xE9, 0x5D, 0xC4, 0x9B, 0xAF, 0x45, 0x99, 0xE2, 0xA3, 0x5A, 0x24, + 0xB4, 0xBA, 0xA9, 0x56, 0x3D, 0xCF, 0x6F, 0xAA, 0xFF, 0x49, 0x58, 0xBE, + 0xF0, 0xA8, 0xFF, 0xF4, 0xB8, 0xAD, 0xE9, 0x37, 0xFB, 0xBA, 0xB8, 0xF4, + 0x0B, 0x3A, 0xF9, 0xE8, 0x43, 0x42, 0x1E, 0x89, 0xD8, 0x84, 0xCB, 0x13, + 0xF1, 0xD9, 0xBB, 0xE1, 0x89, 0x60, 0xB8, 0x8C, 0x28, 0x56, 0xAC, 0x14, + 0x1D, 0x9C, 0x0A, 0xE7, 0x71, 0xEB, 0xCF, 0x0E, 0xDD, 0x3D, 0xA9, 0x96, + 0xA1, 0x48, 0xBD, 0x3C, 0xF7, 0xAF, 0xB5, 0x0D, 0x22, 0x4C, 0xC0, 0x11, + 0x81, 0xEC, 0x56, 0x3B, 0xF6, 0xD3, 0xA2, 0xE2, 0x5B, 0xB7, 0xB2, 0x04, + 0x22, 0x52, 0x95, 0x80, 0x93, 0x69, 0xE8, 0x8E, 0x4C, 0x65, 0xF1, 0x91, + 0x03, 0x2D, 0x70, 0x74, 0x02, 0xEA, 0x8B, 0x67, 0x15, 0x29, 0x69, 0x52, + 0x02, 0xBB, 0xD7, 0xDF, 0x50, 0x6A, 0x55, 0x46, 0xBF, 0xA0, 0xA3, 0x28, + 0x61, 0x7F, 0x70, 0xD0, 0xC3, 0xA2, 0xAA, 0x2C, 0x21, 0xAA, 0x47, 0xCE, + 0x28, 0x9C, 0x06, 0x45, 0x76, 0xBF, 0x82, 0x18, 0x27, 0xB4, 0xD5, 0xAE, + 0xB4, 0xCB, 0x50, 0xE6, 0x6B, 0xF4, 0x4C, 0x86, 0x71, 0x30, 0xE9, 0xA6, + 0xDF, 0x16, 0x86, 0xE0, 0xD8, 0xFF, 0x40, 0xDD, 0xFB, 0xD0, 0x42, 0x88, + 0x7F, 0xA3, 0x33, 0x3A, 0x2E, 0x5C, 0x1E, 0x41, 0x11, 0x81, 0x63, 0xCE, + 0x18, 0x71, 0x6B, 0x2B, 0xEC, 0xA6, 0x8A, 0xB7, 0x31, 0x5C, 0x3A, 0x6A, + 0x47, 0xE0, 0xC3, 0x79, 0x59, 0xD6, 0x20, 0x1A, 0xAF, 0xF2, 0x6A, 0x98, + 0xAA, 0x72, 0xBC, 0x57, 0x4A, 0xD2, 0x4B, 0x9D, 0xBB, 0x10, 0xFC, 0xB0, + 0x4C, 0x41, 0xE5, 0xED, 0x1D, 0x3D, 0x5E, 0x28, 0x9D, 0x9C, 0xCC, 0xBF, + 0xB3, 0x51, 0xDA, 0xA7, 0x47, 0xE5, 0x84, 0x53 +}; + +static const unsigned char TA571_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA572_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x32 +}; + +static const unsigned char TA572_RSA_N[] = { + 0xAA, 0x5F, 0xDA, 0x1B, 0x5F, 0xE8, 0x73, 0x91, 0xE5, 0xDA, 0x5C, 0xF4, + 0xA2, 0xE6, 0x47, 0xE5, 0xF3, 0x68, 0x55, 0x60, 0x05, 0x1D, 0x02, 0xA4, + 0xB3, 0x9B, 0x59, 0xF3, 0x1E, 0x8A, 0xAF, 0x34, 0xAD, 0xFC, 0x0D, 0xC2, + 0xD9, 0x48, 0x19, 0xEE, 0x69, 0x8F, 0xC9, 0x20, 0xFC, 0x21, 0xAA, 0x07, + 0x19, 0xED, 0xB0, 0x5C, 0xAC, 0x65, 0xC7, 0x5F, 0xED, 0x02, 0x7C, 0x7B, + 0x7C, 0x2D, 0x1B, 0xD6, 0xBA, 0xB9, 0x80, 0xC2, 0x18, 0x82, 0x16, 0x84, + 0xFA, 0x66, 0xB0, 0x08, 0xC6, 0x54, 0x23, 0x81, 0xE4, 0xCD, 0xB9, 0x49, + 0x3F, 0xF6, 0x4F, 0x6E, 0x37, 0x48, 0x28, 0x38, 0x0F, 0xC5, 0xBE, 0xE7, + 0x68, 0x70, 0xFD, 0x39, 0x97, 0x4D, 0xD2, 0xC7, 0x98, 0x91, 0x50, 0xAA, + 0xC4, 0x44, 0xB3, 0x23, 0x7D, 0x39, 0x47, 0xE9, 0x52, 0x62, 0xD6, 0x12, + 0x93, 0x5E, 0xB7, 0x31, 0x96, 0x42, 0x05, 0xFB, 0x76, 0xA7, 0x1E, 0xA3, + 0xF5, 0xC2, 0xFC, 0xE9, 0x7A, 0xC5, 0x6C, 0xA9, 0x71, 0x4F, 0xEA, 0xCB, + 0x78, 0xBC, 0x60, 0xAF, 0xC7, 0xDE, 0xF4, 0xD9, 0xCB, 0xBE, 0x7E, 0x33, + 0xA5, 0x6E, 0x94, 0x83, 0xF0, 0x34, 0xFA, 0x21, 0xAB, 0xEA, 0x8E, 0x72, + 0xA0, 0x3F, 0xA4, 0xDE, 0x30, 0x5B, 0xEF, 0x86, 0x4D, 0x6A, 0x95, 0x5B, + 0x43, 0x44, 0xA8, 0x10, 0x15, 0x1C, 0xE5, 0x01, 0x57, 0xC5, 0x98, 0xF1, + 0xE6, 0x06, 0x28, 0x91, 0xAA, 0x20, 0xC5, 0xB7, 0x53, 0x26, 0x51, 0x43, + 0xB2, 0x0B, 0x11, 0x95, 0x58, 0xE1, 0xC0, 0x0F, 0x76, 0xD9, 0xC0, 0x8D, + 0x7C, 0x81, 0xF3, 0x72, 0x70, 0x9E, 0x6F, 0xFE, 0x1A, 0x8E, 0xD9, 0x5F, + 0x35, 0xC6, 0xB2, 0x6F, 0x34, 0x7C, 0xBE, 0x48, 0x4F, 0xE2, 0x5A, 0x39, + 0xD7, 0xD8, 0x9D, 0x78, 0x9E, 0x9F, 0x86, 0x3E, 0x03, 0x5E, 0x19, 0x8B, + 0x44, 0xA2, 0xD5, 0xC7 +}; + +static const unsigned char TA572_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA573_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x39, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, 0x20, + 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x63, 0x69, 0x6F, 0x6E, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, + 0x6F, 0x66, 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x43, 0x49, + 0x46, 0x20, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38 +}; + +static const unsigned char TA573_RSA_N[] = { + 0xCA, 0x96, 0x6B, 0x8E, 0xEA, 0xF8, 0xFB, 0xF1, 0xA2, 0x35, 0xE0, 0x7F, + 0x4C, 0xDA, 0xE0, 0xC3, 0x52, 0xD7, 0x7D, 0xB6, 0x10, 0xC8, 0x02, 0x5E, + 0xB3, 0x43, 0x2A, 0xC4, 0x4F, 0x6A, 0xB2, 0xCA, 0x1C, 0x5D, 0x28, 0x9A, + 0x78, 0x11, 0x1A, 0x69, 0x59, 0x57, 0xAF, 0xB5, 0x20, 0x42, 0xE4, 0x8B, + 0x0F, 0xE6, 0xDF, 0x5B, 0xA6, 0x03, 0x92, 0x2F, 0xF5, 0x11, 0xE4, 0x62, + 0xD7, 0x32, 0x71, 0x38, 0xD9, 0x04, 0x0C, 0x71, 0xAB, 0x3D, 0x51, 0x7E, + 0x0F, 0x07, 0xDF, 0x63, 0x05, 0x5C, 0xE9, 0xBF, 0x94, 0x6F, 0xC1, 0x29, + 0x82, 0xC0, 0xB4, 0xDA, 0x51, 0xB0, 0xC1, 0x3C, 0xBB, 0xAD, 0x37, 0x4A, + 0x5C, 0xCA, 0xF1, 0x4B, 0x36, 0x0E, 0x24, 0xAB, 0xBF, 0xC3, 0x84, 0x77, + 0xFD, 0xA8, 0x50, 0xF4, 0xB1, 0xE7, 0xC6, 0x2F, 0xD2, 0x2D, 0x59, 0x8D, + 0x7A, 0x0A, 0x4E, 0x96, 0x69, 0x52, 0x02, 0xAA, 0x36, 0x98, 0xEC, 0xFC, + 0xFA, 0x14, 0x83, 0x0C, 0x37, 0x1F, 0xC9, 0x92, 0x37, 0x7F, 0xD7, 0x81, + 0x2D, 0xE5, 0xC4, 0xB9, 0xE0, 0x3E, 0x34, 0xFE, 0x67, 0xF4, 0x3E, 0x66, + 0xD1, 0xD3, 0xF4, 0x40, 0xCF, 0x5E, 0x62, 0x34, 0x0F, 0x70, 0x06, 0x3E, + 0x20, 0x18, 0x5A, 0xCE, 0xF7, 0x72, 0x1B, 0x25, 0x6C, 0x93, 0x74, 0x14, + 0x93, 0xA3, 0x73, 0xB1, 0x0E, 0xAA, 0x87, 0x10, 0x23, 0x59, 0x5F, 0x20, + 0x05, 0x19, 0x47, 0xED, 0x68, 0x8E, 0x92, 0x12, 0xCA, 0x5D, 0xFC, 0xD6, + 0x2B, 0xB2, 0x92, 0x3C, 0x20, 0xCF, 0xE1, 0x5F, 0xAF, 0x20, 0xBE, 0xA0, + 0x76, 0x7F, 0x76, 0xE5, 0xEC, 0x1A, 0x86, 0x61, 0x33, 0x3E, 0xE7, 0x7B, + 0xB4, 0x3F, 0xA0, 0x0F, 0x8E, 0xA2, 0xB9, 0x6A, 0x6F, 0xB9, 0x87, 0x26, + 0x6F, 0x41, 0x6C, 0x88, 0xA6, 0x50, 0xFD, 0x6A, 0x63, 0x0B, 0xF5, 0x93, + 0x16, 0x1B, 0x19, 0x8F, 0xB2, 0xED, 0x9B, 0x9B, 0xC9, 0x90, 0xF5, 0x01, + 0x0C, 0xDF, 0x19, 0x3D, 0x0F, 0x3E, 0x38, 0x23, 0xC9, 0x2F, 0x8F, 0x0C, + 0xD1, 0x02, 0xFE, 0x1B, 0x55, 0xD6, 0x4E, 0xD0, 0x8D, 0x3C, 0xAF, 0x4F, + 0xA4, 0xF3, 0xFE, 0xAF, 0x2A, 0xD3, 0x05, 0x9D, 0x79, 0x08, 0xA1, 0xCB, + 0x57, 0x31, 0xB4, 0x9C, 0xC8, 0x90, 0xB2, 0x67, 0xF4, 0x18, 0x16, 0x93, + 0x3A, 0xFC, 0x47, 0xD8, 0xD1, 0x78, 0x96, 0x31, 0x1F, 0xBA, 0x2B, 0x0C, + 0x5F, 0x5D, 0x99, 0xAD, 0x63, 0x89, 0x5A, 0x24, 0x20, 0x76, 0xD8, 0xDF, + 0xFD, 0xAB, 0x4E, 0xA6, 0x22, 0xAA, 0x9D, 0x5E, 0xE6, 0x27, 0x8A, 0x7D, + 0x68, 0x29, 0xA3, 0xE7, 0x8A, 0xB8, 0xDA, 0x11, 0xBB, 0x17, 0x2D, 0x99, + 0x9D, 0x13, 0x24, 0x46, 0xF7, 0xC5, 0xE2, 0xD8, 0x9F, 0x8E, 0x7F, 0xC7, + 0x8F, 0x74, 0x6D, 0x5A, 0xB2, 0xE8, 0x72, 0xF5, 0xAC, 0xEE, 0x24, 0x10, + 0xAD, 0x2F, 0x14, 0xDA, 0xFF, 0x2D, 0x9A, 0x46, 0x71, 0x47, 0xBE, 0x42, + 0xDF, 0xBB, 0x01, 0xDB, 0xF4, 0x7F, 0xD3, 0x28, 0x8F, 0x31, 0x59, 0x5B, + 0xD3, 0xC9, 0x02, 0xA6, 0xB4, 0x52, 0xCA, 0x6E, 0x97, 0xFB, 0x43, 0xC5, + 0x08, 0x26, 0x6F, 0x8A, 0xF4, 0xBB, 0xFD, 0x9F, 0x28, 0xAA, 0x0D, 0xD5, + 0x45, 0xF3, 0x13, 0x3A, 0x1D, 0xD8, 0xC0, 0x78, 0x8F, 0x41, 0x67, 0x3C, + 0x1E, 0x94, 0x64, 0xAE, 0x7B, 0x0B, 0xC5, 0xE8, 0xD9, 0x01, 0x88, 0x39, + 0x1A, 0x97, 0x86, 0x64, 0x41, 0xD5, 0x3B, 0x87, 0x0C, 0x6E, 0xFA, 0x0F, + 0xC6, 0xBD, 0x48, 0x14, 0xBF, 0x39, 0x4D, 0xD4, 0x9E, 0x41, 0xB6, 0x8F, + 0x96, 0x1D, 0x63, 0x96, 0x93, 0xD9, 0x95, 0x06, 0x78, 0x31, 0x68, 0x9E, + 0x37, 0x06, 0x3B, 0x80, 0x89, 0x45, 0x61, 0x39, 0x23, 0xC7, 0x1B, 0x44, + 0xA3, 0x15, 0xE5, 0x1C, 0xF8, 0x92, 0x30, 0xBB +}; + +static const unsigned char TA573_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA574_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6F, 0x6D, 0x6D, + 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA574_RSA_N[] = { + 0xA7, 0x50, 0x19, 0xDE, 0x3F, 0x99, 0x3D, 0xD4, 0x33, 0x46, 0xF1, 0x6F, + 0x51, 0x61, 0x82, 0xB2, 0xA9, 0x4F, 0x8F, 0x67, 0x89, 0x5D, 0x84, 0xD9, + 0x53, 0xDD, 0x0C, 0x28, 0xD9, 0xD7, 0xF0, 0xFF, 0xAE, 0x95, 0x43, 0x72, + 0x99, 0xF9, 0xB5, 0x5D, 0x7C, 0x8A, 0xC1, 0x42, 0xE1, 0x31, 0x50, 0x74, + 0xD1, 0x81, 0x0D, 0x7C, 0xCD, 0x9B, 0x21, 0xAB, 0x43, 0xE2, 0xAC, 0xAD, + 0x5E, 0x86, 0x6E, 0xF3, 0x09, 0x8A, 0x1F, 0x5A, 0x32, 0xBD, 0xA2, 0xEB, + 0x94, 0xF9, 0xE8, 0x5C, 0x0A, 0xEC, 0xFF, 0x98, 0xD2, 0xAF, 0x71, 0xB3, + 0xB4, 0x53, 0x9F, 0x4E, 0x87, 0xEF, 0x92, 0xBC, 0xBD, 0xEC, 0x4F, 0x32, + 0x30, 0x88, 0x4B, 0x17, 0x5E, 0x57, 0xC4, 0x53, 0xC2, 0xF6, 0x02, 0x97, + 0x8D, 0xD9, 0x62, 0x2B, 0xBF, 0x24, 0x1F, 0x62, 0x8D, 0xDF, 0xC3, 0xB8, + 0x29, 0x4B, 0x49, 0x78, 0x3C, 0x93, 0x60, 0x88, 0x22, 0xFC, 0x99, 0xDA, + 0x36, 0xC8, 0xC2, 0xA2, 0xD4, 0x2C, 0x54, 0x00, 0x67, 0x35, 0x6E, 0x73, + 0xBF, 0x02, 0x58, 0xF0, 0xA4, 0xDD, 0xE5, 0xB0, 0xA2, 0x26, 0x7A, 0xCA, + 0xE0, 0x36, 0xA5, 0x19, 0x16, 0xF5, 0xFD, 0xB7, 0xEF, 0xAE, 0x3F, 0x40, + 0xF5, 0x6D, 0x5A, 0x04, 0xFD, 0xCE, 0x34, 0xCA, 0x24, 0xDC, 0x74, 0x23, + 0x1B, 0x5D, 0x33, 0x13, 0x12, 0x5D, 0xC4, 0x01, 0x25, 0xF6, 0x30, 0xDD, + 0x02, 0x5D, 0x9F, 0xE0, 0xD5, 0x47, 0xBD, 0xB4, 0xEB, 0x1B, 0xA1, 0xBB, + 0x49, 0x49, 0xD8, 0x9F, 0x5B, 0x02, 0xF3, 0x8A, 0xE4, 0x24, 0x90, 0xE4, + 0x62, 0x4F, 0x4F, 0xC1, 0xAF, 0x8B, 0x0E, 0x74, 0x17, 0xA8, 0xD1, 0x72, + 0x88, 0x6A, 0x7A, 0x01, 0x49, 0xCC, 0xB4, 0x46, 0x79, 0xC6, 0x17, 0xB1, + 0xDA, 0x98, 0x1E, 0x07, 0x59, 0xFA, 0x75, 0x21, 0x85, 0x65, 0xDD, 0x90, + 0x56, 0xCE, 0xFB, 0xAB, 0xA5, 0x60, 0x9D, 0xC4, 0x9D, 0xF9, 0x52, 0xB0, + 0x8B, 0xBD, 0x87, 0xF9, 0x8F, 0x2B, 0x23, 0x0A, 0x23, 0x76, 0x3B, 0xF7, + 0x33, 0xE1, 0xC9, 0x00, 0xF3, 0x69, 0xF9, 0x4B, 0xA2, 0xE0, 0x4E, 0xBC, + 0x7E, 0x93, 0x39, 0x84, 0x07, 0xF7, 0x44, 0x70, 0x7E, 0xFE, 0x07, 0x5A, + 0xE5, 0xB1, 0xAC, 0xD1, 0x18, 0xCC, 0xF2, 0x35, 0xE5, 0x49, 0x49, 0x08, + 0xCA, 0x56, 0xC9, 0x3D, 0xFB, 0x0F, 0x18, 0x7D, 0x8B, 0x3B, 0xC1, 0x13, + 0xC2, 0x4D, 0x8F, 0xC9, 0x4F, 0x0E, 0x37, 0xE9, 0x1F, 0xA1, 0x0E, 0x6A, + 0xDF, 0x62, 0x2E, 0xCB, 0x35, 0x06, 0x51, 0x79, 0x2C, 0xC8, 0x25, 0x38, + 0xF4, 0xFA, 0x4B, 0xA7, 0x89, 0x5C, 0x9C, 0xD2, 0xE3, 0x0D, 0x39, 0x86, + 0x4A, 0x74, 0x7C, 0xD5, 0x59, 0x87, 0xC2, 0x3F, 0x4E, 0x0C, 0x5C, 0x52, + 0xF4, 0x3D, 0xF7, 0x52, 0x82, 0xF1, 0xEA, 0xA3, 0xAC, 0xFD, 0x49, 0x34, + 0x1A, 0x28, 0xF3, 0x41, 0x88, 0x3A, 0x13, 0xEE, 0xE8, 0xDE, 0xFF, 0x99, + 0x1D, 0x5F, 0xBA, 0xCB, 0xE8, 0x1E, 0xF2, 0xB9, 0x50, 0x60, 0xC0, 0x31, + 0xD3, 0x73, 0xE5, 0xEF, 0xBE, 0xA0, 0xED, 0x33, 0x0B, 0x74, 0xBE, 0x20, + 0x20, 0xC4, 0x67, 0x6C, 0xF0, 0x08, 0x03, 0x7A, 0x55, 0x80, 0x7F, 0x46, + 0x4E, 0x96, 0xA7, 0xF4, 0x1E, 0x3E, 0xE1, 0xF6, 0xD8, 0x09, 0xE1, 0x33, + 0x64, 0x2B, 0x63, 0xD7, 0x32, 0x5E, 0x9F, 0xF9, 0xC0, 0x7B, 0x0F, 0x78, + 0x6F, 0x97, 0xBC, 0x93, 0x9A, 0xF9, 0x9C, 0x12, 0x90, 0x78, 0x7A, 0x80, + 0x87, 0x15, 0xD7, 0x72, 0x74, 0x9C, 0x55, 0x74, 0x78, 0xB1, 0xBA, 0xE1, + 0x6E, 0x70, 0x04, 0xBA, 0x4F, 0xA0, 0xBA, 0x68, 0xC3, 0x7B, 0xFF, 0x31, + 0xF0, 0x73, 0x3D, 0x3D, 0x94, 0x2A, 0xB1, 0x0B, 0x41, 0x0E, 0xA0, 0xFE, + 0x4D, 0x88, 0x65, 0x6B, 0x79, 0x33, 0xB4, 0xD7 +}; + +static const unsigned char TA574_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA575_DN[] = { + 0x30, 0x69, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4B, 0x52, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, 0x42, 0x55, 0x53, 0x49, + 0x4E, 0x45, 0x53, 0x53, 0x20, 0x50, 0x4C, 0x41, 0x54, 0x46, 0x4F, 0x52, + 0x4D, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA575_RSA_N[] = { + 0xB6, 0xD4, 0xF1, 0x93, 0x5C, 0xB5, 0x40, 0x89, 0x0A, 0xAB, 0x0D, 0x90, + 0x5B, 0x50, 0x63, 0xAE, 0x90, 0x94, 0x74, 0x17, 0x45, 0x72, 0xD6, 0x7B, + 0x65, 0x5A, 0x29, 0x4B, 0xA7, 0x56, 0xA0, 0x4B, 0xB8, 0x2F, 0x42, 0x75, + 0xE9, 0xD9, 0x7B, 0x24, 0x5A, 0x31, 0x65, 0xAB, 0x17, 0x17, 0xD1, 0x33, + 0x3A, 0xD9, 0x11, 0xDC, 0x40, 0x36, 0x87, 0xDF, 0xC7, 0x6A, 0xE9, 0x26, + 0x5E, 0x59, 0x8A, 0x77, 0xE3, 0xE8, 0x48, 0x9C, 0x31, 0x16, 0xFA, 0x3E, + 0x91, 0xB1, 0xCA, 0xC9, 0xA3, 0xE2, 0x9F, 0xCE, 0x21, 0x53, 0xA3, 0x02, + 0x36, 0x30, 0xCB, 0x52, 0x02, 0xE5, 0xDA, 0x32, 0x5D, 0xC3, 0xC5, 0xE6, + 0xF9, 0xEE, 0x11, 0xC7, 0x8B, 0xC9, 0x44, 0x1E, 0x84, 0x93, 0x18, 0x4A, + 0xB4, 0x9F, 0xE5, 0x12, 0x64, 0x69, 0xD0, 0x26, 0x85, 0x62, 0x01, 0xB6, + 0xC9, 0x02, 0x1D, 0xBE, 0x83, 0x51, 0xBB, 0x5C, 0xDA, 0xF8, 0xAD, 0x15, + 0x6A, 0x99, 0xF7, 0x92, 0x54, 0xF7, 0x34, 0x5B, 0xE9, 0xBF, 0xEA, 0x29, + 0x81, 0x12, 0xD4, 0x53, 0x91, 0x96, 0xB3, 0x91, 0x5A, 0xDD, 0xFE, 0x90, + 0x73, 0x28, 0xFB, 0x30, 0x46, 0xB5, 0xCA, 0x08, 0x07, 0xC7, 0x71, 0x72, + 0xC9, 0x66, 0xD3, 0x34, 0x97, 0xF6, 0x8C, 0xF4, 0x18, 0x4A, 0xE1, 0xD0, + 0x3D, 0x5A, 0x45, 0xB6, 0x69, 0xA7, 0x29, 0xFB, 0x23, 0xCE, 0x88, 0xD8, + 0x12, 0x9C, 0x00, 0x48, 0xA8, 0xA6, 0x0F, 0xB3, 0x3B, 0x92, 0x8D, 0x71, + 0x0E, 0x74, 0xC5, 0x8B, 0xC8, 0x4C, 0xF9, 0xF4, 0x9B, 0x8E, 0xB8, 0x3C, + 0x69, 0xED, 0x6F, 0x3B, 0x50, 0x2F, 0x58, 0xED, 0xC4, 0xB0, 0xD0, 0x1C, + 0x1B, 0x6A, 0x0C, 0xE2, 0xBC, 0x44, 0xAA, 0xD8, 0xCD, 0x14, 0x5D, 0x94, + 0x78, 0x61, 0xBF, 0x0E, 0x6E, 0xDA, 0x2A, 0xBC, 0x2F, 0x0C, 0x0B, 0x71, + 0xA6, 0xB3, 0x16, 0x3F, 0x9C, 0xE6, 0xF9, 0xCC, 0x9F, 0x53, 0x35, 0xE2, + 0x03, 0xA0, 0xA0, 0x18, 0xBF, 0xBB, 0xF1, 0xBE, 0xF4, 0xD6, 0x8C, 0x87, + 0x0D, 0x42, 0xF7, 0x06, 0xB9, 0xF1, 0x6D, 0xED, 0x04, 0x94, 0xA8, 0xFE, + 0xB6, 0xD3, 0x06, 0xC6, 0x40, 0x61, 0xDF, 0x9D, 0x9D, 0xF3, 0x54, 0x76, + 0xCE, 0x53, 0x3A, 0x01, 0xA6, 0x92, 0x41, 0xEC, 0x04, 0xA3, 0x8F, 0x0D, + 0xA2, 0xD5, 0x09, 0xCA, 0xD6, 0xCB, 0x9A, 0xF1, 0xEF, 0x43, 0x5D, 0xC0, + 0xAB, 0xA5, 0x41, 0xCF, 0x5C, 0x53, 0x70, 0x70, 0xC9, 0x88, 0xA6, 0x2D, + 0xD4, 0x6B, 0x61, 0x73, 0x50, 0x26, 0x86, 0x61, 0x0E, 0x5F, 0x1B, 0xC2, + 0x2B, 0xE2, 0x8C, 0xD5, 0xBB, 0x9D, 0xC1, 0x03, 0x42, 0xBA, 0x94, 0xDA, + 0x5F, 0xA9, 0xB0, 0xCA, 0xCC, 0x4D, 0x0A, 0xEF, 0x47, 0x69, 0x03, 0x2F, + 0x22, 0xFB, 0xF1, 0x28, 0xCE, 0xBF, 0x5D, 0x50, 0x65, 0xA8, 0x90, 0x6D, + 0xB3, 0x74, 0xB0, 0x08, 0xC7, 0xAC, 0xA8, 0xD1, 0xEB, 0x3E, 0x9C, 0xFC, + 0x5D, 0x1A, 0x83, 0x2E, 0x2B, 0xCB, 0xB5, 0xF3, 0x44, 0x9D, 0x3A, 0xA7, + 0x17, 0x61, 0x96, 0xA2, 0x71, 0xD3, 0x70, 0x96, 0x15, 0x4D, 0xB7, 0x4C, + 0x73, 0xEE, 0x19, 0x5C, 0xC5, 0x5B, 0x3E, 0x41, 0xFE, 0xAC, 0x75, 0x60, + 0x3B, 0x1B, 0x63, 0xCE, 0x00, 0xDD, 0xDA, 0x08, 0x90, 0x62, 0xB4, 0xE5, + 0x2D, 0xEE, 0x48, 0xA7, 0x6B, 0x17, 0x99, 0x54, 0xBE, 0x87, 0x4A, 0xE3, + 0xA9, 0x5E, 0x04, 0x4C, 0xEB, 0x10, 0x6D, 0x54, 0xD6, 0xEF, 0xF1, 0xE8, + 0xF2, 0x62, 0x16, 0xCB, 0x80, 0x6B, 0xED, 0x3D, 0xED, 0xF5, 0x1F, 0x30, + 0xA5, 0xAE, 0x4B, 0xC9, 0x13, 0xED, 0x8A, 0x01, 0x01, 0xC9, 0xB8, 0x51, + 0x58, 0xC0, 0x66, 0x3A, 0xB1, 0x66, 0x4B, 0xC4, 0xD5, 0x31, 0x02, 0x62, + 0xE9, 0x74, 0x84, 0x0C, 0xDB, 0x4D, 0x46, 0x2D +}; + +static const unsigned char TA575_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA576_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x34 +}; + +static const unsigned char TA576_EC_Q[] = { + 0x04, 0xD2, 0xAB, 0x8A, 0x37, 0x4F, 0xA3, 0x53, 0x0D, 0xFE, 0xC1, 0x8A, + 0x7B, 0x4B, 0xA8, 0x7B, 0x46, 0x4B, 0x63, 0xB0, 0x62, 0xF6, 0x2D, 0x1B, + 0xDB, 0x08, 0x71, 0x21, 0xD2, 0x00, 0xE8, 0x63, 0xBD, 0x9A, 0x27, 0xFB, + 0xF0, 0x39, 0x6E, 0x5D, 0xEA, 0x3D, 0xA5, 0xC9, 0x81, 0xAA, 0xA3, 0x5B, + 0x20, 0x98, 0x45, 0x5D, 0x16, 0xDB, 0xFD, 0xE8, 0x10, 0x6D, 0xE3, 0x9C, + 0xE0, 0xE3, 0xBD, 0x5F, 0x84, 0x62, 0xF3, 0x70, 0x64, 0x33, 0xA0, 0xCB, + 0x24, 0x2F, 0x70, 0xBA, 0x88, 0xA1, 0x2A, 0xA0, 0x75, 0xF8, 0x81, 0xAE, + 0x62, 0x06, 0xC4, 0x81, 0xDB, 0x39, 0x6E, 0x29, 0xB0, 0x1E, 0xFA, 0x2E, + 0x5C +}; + +static const unsigned char TA577_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA577_RSA_N[] = { + 0x91, 0xE8, 0x54, 0x92, 0xD2, 0x0A, 0x56, 0xB1, 0xAC, 0x0D, 0x24, 0xDD, + 0xC5, 0xCF, 0x44, 0x67, 0x74, 0x99, 0x2B, 0x37, 0xA3, 0x7D, 0x23, 0x70, + 0x00, 0x71, 0xBC, 0x53, 0xDF, 0xC4, 0xFA, 0x2A, 0x12, 0x8F, 0x4B, 0x7F, + 0x10, 0x56, 0xBD, 0x9F, 0x70, 0x72, 0xB7, 0x61, 0x7F, 0xC9, 0x4B, 0x0F, + 0x17, 0xA7, 0x3D, 0xE3, 0xB0, 0x04, 0x61, 0xEE, 0xFF, 0x11, 0x97, 0xC7, + 0xF4, 0x86, 0x3E, 0x0A, 0xFA, 0x3E, 0x5C, 0xF9, 0x93, 0xE6, 0x34, 0x7A, + 0xD9, 0x14, 0x6B, 0xE7, 0x9C, 0xB3, 0x85, 0xA0, 0x82, 0x7A, 0x76, 0xAF, + 0x71, 0x90, 0xD7, 0xEC, 0xFD, 0x0D, 0xFA, 0x9C, 0x6C, 0xFA, 0xDF, 0xB0, + 0x82, 0xF4, 0x14, 0x7E, 0xF9, 0xBE, 0xC4, 0xA6, 0x2F, 0x4F, 0x7F, 0x99, + 0x7F, 0xB5, 0xFC, 0x67, 0x43, 0x72, 0xBD, 0x0C, 0x00, 0xD6, 0x89, 0xEB, + 0x6B, 0x2C, 0xD3, 0xED, 0x8F, 0x98, 0x1C, 0x14, 0xAB, 0x7E, 0xE5, 0xE3, + 0x6E, 0xFC, 0xD8, 0xA8, 0xE4, 0x92, 0x24, 0xDA, 0x43, 0x6B, 0x62, 0xB8, + 0x55, 0xFD, 0xEA, 0xC1, 0xBC, 0x6C, 0xB6, 0x8B, 0xF3, 0x0E, 0x8D, 0x9A, + 0xE4, 0x9B, 0x6C, 0x69, 0x99, 0xF8, 0x78, 0x48, 0x30, 0x45, 0xD5, 0xAD, + 0xE1, 0x0D, 0x3C, 0x45, 0x60, 0xFC, 0x32, 0x96, 0x51, 0x27, 0xBC, 0x67, + 0xC3, 0xCA, 0x2E, 0xB6, 0x6B, 0xEA, 0x46, 0xC7, 0xC7, 0x20, 0xA0, 0xB1, + 0x1F, 0x65, 0xDE, 0x48, 0x08, 0xBA, 0xA4, 0x4E, 0xA9, 0xF2, 0x83, 0x46, + 0x37, 0x84, 0xEB, 0xE8, 0xCC, 0x81, 0x48, 0x43, 0x67, 0x4E, 0x72, 0x2A, + 0x9B, 0x5C, 0xBD, 0x4C, 0x1B, 0x28, 0x8A, 0x5C, 0x22, 0x7B, 0xB4, 0xAB, + 0x98, 0xD9, 0xEE, 0xE0, 0x51, 0x83, 0xC3, 0x09, 0x46, 0x4E, 0x6D, 0x3E, + 0x99, 0xFA, 0x95, 0x17, 0xDA, 0x7C, 0x33, 0x57, 0x41, 0x3C, 0x8D, 0x51, + 0xED, 0x0B, 0xB6, 0x5C, 0xAF, 0x2C, 0x63, 0x1A, 0xDF, 0x57, 0xC8, 0x3F, + 0xBC, 0xE9, 0x5D, 0xC4, 0x9B, 0xAF, 0x45, 0x99, 0xE2, 0xA3, 0x5A, 0x24, + 0xB4, 0xBA, 0xA9, 0x56, 0x3D, 0xCF, 0x6F, 0xAA, 0xFF, 0x49, 0x58, 0xBE, + 0xF0, 0xA8, 0xFF, 0xF4, 0xB8, 0xAD, 0xE9, 0x37, 0xFB, 0xBA, 0xB8, 0xF4, + 0x0B, 0x3A, 0xF9, 0xE8, 0x43, 0x42, 0x1E, 0x89, 0xD8, 0x84, 0xCB, 0x13, + 0xF1, 0xD9, 0xBB, 0xE1, 0x89, 0x60, 0xB8, 0x8C, 0x28, 0x56, 0xAC, 0x14, + 0x1D, 0x9C, 0x0A, 0xE7, 0x71, 0xEB, 0xCF, 0x0E, 0xDD, 0x3D, 0xA9, 0x96, + 0xA1, 0x48, 0xBD, 0x3C, 0xF7, 0xAF, 0xB5, 0x0D, 0x22, 0x4C, 0xC0, 0x11, + 0x81, 0xEC, 0x56, 0x3B, 0xF6, 0xD3, 0xA2, 0xE2, 0x5B, 0xB7, 0xB2, 0x04, + 0x22, 0x52, 0x95, 0x80, 0x93, 0x69, 0xE8, 0x8E, 0x4C, 0x65, 0xF1, 0x91, + 0x03, 0x2D, 0x70, 0x74, 0x02, 0xEA, 0x8B, 0x67, 0x15, 0x29, 0x69, 0x52, + 0x02, 0xBB, 0xD7, 0xDF, 0x50, 0x6A, 0x55, 0x46, 0xBF, 0xA0, 0xA3, 0x28, + 0x61, 0x7F, 0x70, 0xD0, 0xC3, 0xA2, 0xAA, 0x2C, 0x21, 0xAA, 0x47, 0xCE, + 0x28, 0x9C, 0x06, 0x45, 0x76, 0xBF, 0x82, 0x18, 0x27, 0xB4, 0xD5, 0xAE, + 0xB4, 0xCB, 0x50, 0xE6, 0x6B, 0xF4, 0x4C, 0x86, 0x71, 0x30, 0xE9, 0xA6, + 0xDF, 0x16, 0x86, 0xE0, 0xD8, 0xFF, 0x40, 0xDD, 0xFB, 0xD0, 0x42, 0x88, + 0x7F, 0xA3, 0x33, 0x3A, 0x2E, 0x5C, 0x1E, 0x41, 0x11, 0x81, 0x63, 0xCE, + 0x18, 0x71, 0x6B, 0x2B, 0xEC, 0xA6, 0x8A, 0xB7, 0x31, 0x5C, 0x3A, 0x6A, + 0x47, 0xE0, 0xC3, 0x79, 0x59, 0xD6, 0x20, 0x1A, 0xAF, 0xF2, 0x6A, 0x98, + 0xAA, 0x72, 0xBC, 0x57, 0x4A, 0xD2, 0x4B, 0x9D, 0xBB, 0x10, 0xFC, 0xB0, + 0x4C, 0x41, 0xE5, 0xED, 0x1D, 0x3D, 0x5E, 0x28, 0x9D, 0x9C, 0xCC, 0xBF, + 0xB3, 0x51, 0xDA, 0xA7, 0x47, 0xE5, 0x84, 0x53 +}; + +static const unsigned char TA577_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA578_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x21, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x45, 0x56, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA578_RSA_N[] = { + 0x99, 0xF1, 0x84, 0x34, 0x70, 0xBA, 0x2F, 0xB7, 0x30, 0xA0, 0x8E, 0xBD, + 0x7C, 0x04, 0xCF, 0xBE, 0x62, 0xBC, 0x99, 0xFD, 0x82, 0x97, 0xD2, 0x7A, + 0x0A, 0x67, 0x96, 0x38, 0x09, 0xF6, 0x10, 0x4E, 0x95, 0x22, 0x73, 0x99, + 0x8D, 0xDA, 0x15, 0x2D, 0xE7, 0x05, 0xFC, 0x19, 0x73, 0x22, 0xB7, 0x8E, + 0x98, 0x00, 0xBC, 0x3C, 0x3D, 0xAC, 0xA1, 0x6C, 0xFB, 0xD6, 0x79, 0x25, + 0x4B, 0xAD, 0xF0, 0xCC, 0x64, 0xDA, 0x88, 0x3E, 0x29, 0xB8, 0x0F, 0x09, + 0xD3, 0x34, 0xDD, 0x33, 0xF5, 0x62, 0xD1, 0xE1, 0xCD, 0x19, 0xE9, 0xEE, + 0x18, 0x4F, 0x4C, 0x58, 0xAE, 0xE2, 0x1E, 0xD6, 0x0C, 0x5B, 0x15, 0x5A, + 0xD8, 0x3A, 0xB8, 0xC4, 0x18, 0x64, 0x1E, 0xE3, 0x33, 0xB2, 0xB5, 0x89, + 0x77, 0x4E, 0x0C, 0xBF, 0xD9, 0x94, 0x6B, 0x13, 0x97, 0x6F, 0x12, 0xA3, + 0xFE, 0x99, 0xA9, 0x04, 0xCC, 0x15, 0xEC, 0x60, 0x68, 0x36, 0xED, 0x08, + 0x7B, 0xB7, 0xF5, 0xBF, 0x93, 0xED, 0x66, 0x31, 0x83, 0x8C, 0xC6, 0x71, + 0x34, 0x87, 0x4E, 0x17, 0xEA, 0xAF, 0x8B, 0x91, 0x8D, 0x1C, 0x56, 0x41, + 0xAE, 0x22, 0x37, 0x5E, 0x37, 0xF2, 0x1D, 0xD9, 0xD1, 0x2D, 0x0D, 0x2F, + 0x69, 0x51, 0xA7, 0xBE, 0x66, 0xA6, 0x8A, 0x3A, 0x2A, 0xBD, 0xC7, 0x1A, + 0xB1, 0xE1, 0x14, 0xF0, 0xBE, 0x3A, 0x1D, 0xB9, 0xCF, 0x5B, 0xB1, 0x6A, + 0xFE, 0xB4, 0xB1, 0x46, 0x20, 0xA2, 0xFB, 0x1E, 0x3B, 0x70, 0xEF, 0x93, + 0x98, 0x7D, 0x8C, 0x73, 0x96, 0xF2, 0xC5, 0xEF, 0x85, 0x70, 0xAD, 0x29, + 0x26, 0xFC, 0x1E, 0x04, 0x3E, 0x1C, 0xA0, 0xD8, 0x0F, 0xCB, 0x52, 0x83, + 0x62, 0x7C, 0xEE, 0x8B, 0x53, 0x95, 0x90, 0xA9, 0x57, 0xA2, 0xEA, 0x61, + 0x05, 0xD8, 0xF9, 0x4D, 0xC4, 0x27, 0xFA, 0x6E, 0xAD, 0xED, 0xF9, 0xD7, + 0x51, 0xF7, 0x6B, 0xA5 +}; + +static const unsigned char TA578_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA579_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x34, 0x30, 0x39, 0x36, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA579_RSA_N[] = { + 0xB3, 0xD0, 0xF4, 0xC9, 0x79, 0x11, 0x9D, 0xFD, 0xFC, 0x66, 0x81, 0xE7, + 0xCC, 0xD5, 0xE4, 0xBC, 0xEC, 0x81, 0x3E, 0x6A, 0x35, 0x8E, 0x2E, 0xB7, + 0xE7, 0xDE, 0xAF, 0xF9, 0x07, 0x4D, 0xCF, 0x30, 0x9D, 0xEA, 0x09, 0x0B, + 0x99, 0xBD, 0x6C, 0x57, 0xDA, 0x18, 0x4A, 0xB8, 0x78, 0xAC, 0x3A, 0x39, + 0xA8, 0xA6, 0x48, 0xAC, 0x2E, 0x72, 0xE5, 0xBD, 0xEB, 0xF1, 0x1A, 0xCD, + 0xE7, 0xA4, 0x03, 0xA9, 0x3F, 0x11, 0xB4, 0xD8, 0x2F, 0x89, 0x16, 0xFB, + 0x94, 0x01, 0x3D, 0xBB, 0x2F, 0xF8, 0x13, 0x05, 0xA1, 0x78, 0x1C, 0x8E, + 0x28, 0xE0, 0x45, 0xE0, 0x83, 0xF4, 0x59, 0x1B, 0x95, 0xB3, 0xAE, 0x7E, + 0x03, 0x45, 0xE5, 0xBE, 0xC2, 0x42, 0xFE, 0xEE, 0xF2, 0x3C, 0xB6, 0x85, + 0x13, 0x98, 0x32, 0x9D, 0x16, 0xA8, 0x29, 0xC2, 0x0B, 0x1C, 0x38, 0xDC, + 0x9F, 0x31, 0x77, 0x5C, 0xBF, 0x27, 0xA3, 0xFC, 0x27, 0xAC, 0xB7, 0x2B, + 0xBD, 0x74, 0x9B, 0x17, 0x2D, 0xF2, 0x81, 0xDA, 0x5D, 0xB0, 0xE1, 0x23, + 0x17, 0x3E, 0x88, 0x4A, 0x12, 0x23, 0xD0, 0xEA, 0xCF, 0x9D, 0xDE, 0x03, + 0x17, 0xB1, 0x42, 0x4A, 0xA0, 0x16, 0x4C, 0xA4, 0x6D, 0x93, 0xE9, 0x3F, + 0x3A, 0xEE, 0x3A, 0x7C, 0x9D, 0x58, 0x9D, 0xF4, 0x4E, 0x8F, 0xFC, 0x3B, + 0x23, 0xC8, 0x6D, 0xB8, 0xE2, 0x05, 0xDA, 0xCC, 0xEB, 0xEC, 0xC3, 0x31, + 0xF4, 0xD7, 0xA7, 0x29, 0x54, 0x80, 0xCF, 0x44, 0x5B, 0x4C, 0x6F, 0x30, + 0x9E, 0xF3, 0xCC, 0xDD, 0x1F, 0x94, 0x43, 0x9D, 0x4D, 0x7F, 0x70, 0x70, + 0x0D, 0xD4, 0x3A, 0xD1, 0x37, 0xF0, 0x6C, 0x9D, 0x9B, 0xC0, 0x14, 0x93, + 0x58, 0xEF, 0xCD, 0x41, 0x38, 0x75, 0xBC, 0x13, 0x03, 0x95, 0x7C, 0x7F, + 0xE3, 0x5C, 0xE9, 0xD5, 0x0D, 0xD5, 0xE2, 0x7C, 0x10, 0x62, 0xAA, 0x6B, + 0xF0, 0x3D, 0x76, 0xF3, 0x3F, 0xA3, 0xE8, 0xB0, 0xC1, 0xFD, 0xEF, 0xAA, + 0x57, 0x4D, 0xAC, 0x86, 0xA7, 0x18, 0xB4, 0x29, 0xC1, 0x2C, 0x0E, 0xBF, + 0x64, 0xBE, 0x29, 0x8C, 0xD8, 0x02, 0x2D, 0xCD, 0x5C, 0x2F, 0xF2, 0x7F, + 0xEF, 0x15, 0xF4, 0x0C, 0x15, 0xAC, 0x0A, 0xB0, 0xF1, 0xD3, 0x0D, 0x4F, + 0x6A, 0x4D, 0x77, 0x97, 0x01, 0xA0, 0xF1, 0x66, 0xB7, 0xB7, 0xCE, 0xEF, + 0xCE, 0xEC, 0xEC, 0xA5, 0x75, 0xCA, 0xAC, 0xE3, 0xE1, 0x63, 0xF7, 0xB8, + 0xA1, 0x04, 0xC8, 0xBC, 0x7B, 0x3F, 0x5D, 0x2D, 0x16, 0x22, 0x56, 0xED, + 0x48, 0x49, 0xFE, 0xA7, 0x2F, 0x79, 0x30, 0x25, 0x9B, 0xBA, 0x6B, 0x2D, + 0x3F, 0x9D, 0x3B, 0xC4, 0x17, 0xE7, 0x1D, 0x2E, 0xFB, 0xF2, 0xCF, 0xA6, + 0xFC, 0xE3, 0x14, 0x2C, 0x96, 0x98, 0x21, 0x8C, 0xB4, 0x91, 0xE9, 0x19, + 0x60, 0x83, 0xF2, 0x30, 0x2B, 0x06, 0x73, 0x50, 0xD5, 0x98, 0x3B, 0x06, + 0xE9, 0xC7, 0x8A, 0x0C, 0x60, 0x8C, 0x28, 0xF8, 0x52, 0x9B, 0x6E, 0xE1, + 0xF6, 0x4D, 0xBB, 0x06, 0x24, 0x9B, 0xD7, 0x2B, 0x26, 0x3F, 0xFD, 0x2A, + 0x2F, 0x71, 0xF5, 0xD6, 0x24, 0xBE, 0x7F, 0x31, 0x9E, 0x0F, 0x6D, 0xE8, + 0x8F, 0x4F, 0x4D, 0xA3, 0x3F, 0xFF, 0x35, 0xEA, 0xDF, 0x49, 0x5E, 0x41, + 0x8F, 0x86, 0xF9, 0xF1, 0x77, 0x79, 0x4B, 0x1B, 0xB4, 0xA3, 0x5E, 0x2F, + 0xFB, 0x46, 0x02, 0xD0, 0x66, 0x13, 0x5E, 0x5E, 0x85, 0x4F, 0xCE, 0xD8, + 0x70, 0x88, 0x7B, 0xCE, 0x01, 0xB5, 0x96, 0x97, 0xD7, 0xCD, 0x7D, 0xFD, + 0x82, 0xF8, 0xC2, 0x24, 0xC1, 0xCA, 0x01, 0x39, 0x4F, 0x8D, 0xA2, 0xC1, + 0x14, 0x40, 0x1F, 0x9C, 0x66, 0xD5, 0x0C, 0x09, 0x46, 0xD6, 0xF2, 0xD0, + 0xD1, 0x48, 0x76, 0x56, 0x3A, 0x43, 0xCB, 0xB6, 0x0A, 0x11, 0x39, 0xBA, + 0x8C, 0x13, 0x6C, 0x06, 0xB5, 0x9E, 0xCF, 0xEB +}; + +static const unsigned char TA579_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA580_DN[] = { + 0x30, 0x5D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x1E, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA580_RSA_N[] = { + 0xD0, 0x15, 0x39, 0x52, 0xB1, 0x52, 0xB3, 0xBA, 0xC5, 0x59, 0x82, 0xC4, + 0x5D, 0x52, 0xAE, 0x3A, 0x43, 0x65, 0x80, 0x4B, 0xC7, 0xF2, 0x96, 0xBC, + 0xDB, 0x36, 0x97, 0xD6, 0xA6, 0x64, 0x8C, 0xA8, 0x5E, 0xF0, 0xE3, 0x0A, + 0x1C, 0xF7, 0xDF, 0x97, 0x3D, 0x4B, 0xAE, 0xF6, 0x5D, 0xEC, 0x21, 0xB5, + 0x41, 0xAB, 0xCD, 0xB9, 0x7E, 0x76, 0x9F, 0xBE, 0xF9, 0x3E, 0x36, 0x34, + 0xA0, 0x3B, 0xC1, 0xF6, 0x31, 0x11, 0x45, 0x74, 0x93, 0x3D, 0x57, 0x80, + 0xC5, 0xF9, 0x89, 0x99, 0xCA, 0xE5, 0xAB, 0x6A, 0xD4, 0xB5, 0xDA, 0x41, + 0x90, 0x10, 0xC1, 0xD6, 0xD6, 0x42, 0x89, 0xC2, 0xBF, 0xF4, 0x38, 0x12, + 0x95, 0x4C, 0x54, 0x05, 0xF7, 0x36, 0xE4, 0x45, 0x83, 0x7B, 0x14, 0x65, + 0xD6, 0xDC, 0x0C, 0x4D, 0xD1, 0xDE, 0x7E, 0x0C, 0xAB, 0x3B, 0xC4, 0x15, + 0xBE, 0x3A, 0x56, 0xA6, 0x5A, 0x6F, 0x76, 0x69, 0x52, 0xA9, 0x7A, 0xB9, + 0xC8, 0xEB, 0x6A, 0x9A, 0x5D, 0x52, 0xD0, 0x2D, 0x0A, 0x6B, 0x35, 0x16, + 0x09, 0x10, 0x84, 0xD0, 0x6A, 0xCA, 0x3A, 0x06, 0x00, 0x37, 0x47, 0xE4, + 0x7E, 0x57, 0x4F, 0x3F, 0x8B, 0xEB, 0x67, 0xB8, 0x88, 0xAA, 0xC5, 0xBE, + 0x53, 0x55, 0xB2, 0x91, 0xC4, 0x7D, 0xB9, 0xB0, 0x85, 0x19, 0x06, 0x78, + 0x2E, 0xDB, 0x61, 0x1A, 0xFA, 0x85, 0xF5, 0x4A, 0x91, 0xA1, 0xE7, 0x16, + 0xD5, 0x8E, 0xA2, 0x39, 0xDF, 0x94, 0xB8, 0x70, 0x1F, 0x28, 0x3F, 0x8B, + 0xFC, 0x40, 0x5E, 0x63, 0x83, 0x3C, 0x83, 0x2A, 0x1A, 0x99, 0x6B, 0xCF, + 0xDE, 0x59, 0x6A, 0x3B, 0xFC, 0x6F, 0x16, 0xD7, 0x1F, 0xFD, 0x4A, 0x10, + 0xEB, 0x4E, 0x82, 0x16, 0x3A, 0xAC, 0x27, 0x0C, 0x53, 0xF1, 0xAD, 0xD5, + 0x24, 0xB0, 0x6B, 0x03, 0x50, 0xC1, 0x2D, 0x3C, 0x16, 0xDD, 0x44, 0x34, + 0x27, 0x1A, 0x75, 0xFB +}; + +static const unsigned char TA580_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA581_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA581_RSA_N[] = { + 0x91, 0xE8, 0x54, 0x92, 0xD2, 0x0A, 0x56, 0xB1, 0xAC, 0x0D, 0x24, 0xDD, + 0xC5, 0xCF, 0x44, 0x67, 0x74, 0x99, 0x2B, 0x37, 0xA3, 0x7D, 0x23, 0x70, + 0x00, 0x71, 0xBC, 0x53, 0xDF, 0xC4, 0xFA, 0x2A, 0x12, 0x8F, 0x4B, 0x7F, + 0x10, 0x56, 0xBD, 0x9F, 0x70, 0x72, 0xB7, 0x61, 0x7F, 0xC9, 0x4B, 0x0F, + 0x17, 0xA7, 0x3D, 0xE3, 0xB0, 0x04, 0x61, 0xEE, 0xFF, 0x11, 0x97, 0xC7, + 0xF4, 0x86, 0x3E, 0x0A, 0xFA, 0x3E, 0x5C, 0xF9, 0x93, 0xE6, 0x34, 0x7A, + 0xD9, 0x14, 0x6B, 0xE7, 0x9C, 0xB3, 0x85, 0xA0, 0x82, 0x7A, 0x76, 0xAF, + 0x71, 0x90, 0xD7, 0xEC, 0xFD, 0x0D, 0xFA, 0x9C, 0x6C, 0xFA, 0xDF, 0xB0, + 0x82, 0xF4, 0x14, 0x7E, 0xF9, 0xBE, 0xC4, 0xA6, 0x2F, 0x4F, 0x7F, 0x99, + 0x7F, 0xB5, 0xFC, 0x67, 0x43, 0x72, 0xBD, 0x0C, 0x00, 0xD6, 0x89, 0xEB, + 0x6B, 0x2C, 0xD3, 0xED, 0x8F, 0x98, 0x1C, 0x14, 0xAB, 0x7E, 0xE5, 0xE3, + 0x6E, 0xFC, 0xD8, 0xA8, 0xE4, 0x92, 0x24, 0xDA, 0x43, 0x6B, 0x62, 0xB8, + 0x55, 0xFD, 0xEA, 0xC1, 0xBC, 0x6C, 0xB6, 0x8B, 0xF3, 0x0E, 0x8D, 0x9A, + 0xE4, 0x9B, 0x6C, 0x69, 0x99, 0xF8, 0x78, 0x48, 0x30, 0x45, 0xD5, 0xAD, + 0xE1, 0x0D, 0x3C, 0x45, 0x60, 0xFC, 0x32, 0x96, 0x51, 0x27, 0xBC, 0x67, + 0xC3, 0xCA, 0x2E, 0xB6, 0x6B, 0xEA, 0x46, 0xC7, 0xC7, 0x20, 0xA0, 0xB1, + 0x1F, 0x65, 0xDE, 0x48, 0x08, 0xBA, 0xA4, 0x4E, 0xA9, 0xF2, 0x83, 0x46, + 0x37, 0x84, 0xEB, 0xE8, 0xCC, 0x81, 0x48, 0x43, 0x67, 0x4E, 0x72, 0x2A, + 0x9B, 0x5C, 0xBD, 0x4C, 0x1B, 0x28, 0x8A, 0x5C, 0x22, 0x7B, 0xB4, 0xAB, + 0x98, 0xD9, 0xEE, 0xE0, 0x51, 0x83, 0xC3, 0x09, 0x46, 0x4E, 0x6D, 0x3E, + 0x99, 0xFA, 0x95, 0x17, 0xDA, 0x7C, 0x33, 0x57, 0x41, 0x3C, 0x8D, 0x51, + 0xED, 0x0B, 0xB6, 0x5C, 0xAF, 0x2C, 0x63, 0x1A, 0xDF, 0x57, 0xC8, 0x3F, + 0xBC, 0xE9, 0x5D, 0xC4, 0x9B, 0xAF, 0x45, 0x99, 0xE2, 0xA3, 0x5A, 0x24, + 0xB4, 0xBA, 0xA9, 0x56, 0x3D, 0xCF, 0x6F, 0xAA, 0xFF, 0x49, 0x58, 0xBE, + 0xF0, 0xA8, 0xFF, 0xF4, 0xB8, 0xAD, 0xE9, 0x37, 0xFB, 0xBA, 0xB8, 0xF4, + 0x0B, 0x3A, 0xF9, 0xE8, 0x43, 0x42, 0x1E, 0x89, 0xD8, 0x84, 0xCB, 0x13, + 0xF1, 0xD9, 0xBB, 0xE1, 0x89, 0x60, 0xB8, 0x8C, 0x28, 0x56, 0xAC, 0x14, + 0x1D, 0x9C, 0x0A, 0xE7, 0x71, 0xEB, 0xCF, 0x0E, 0xDD, 0x3D, 0xA9, 0x96, + 0xA1, 0x48, 0xBD, 0x3C, 0xF7, 0xAF, 0xB5, 0x0D, 0x22, 0x4C, 0xC0, 0x11, + 0x81, 0xEC, 0x56, 0x3B, 0xF6, 0xD3, 0xA2, 0xE2, 0x5B, 0xB7, 0xB2, 0x04, + 0x22, 0x52, 0x95, 0x80, 0x93, 0x69, 0xE8, 0x8E, 0x4C, 0x65, 0xF1, 0x91, + 0x03, 0x2D, 0x70, 0x74, 0x02, 0xEA, 0x8B, 0x67, 0x15, 0x29, 0x69, 0x52, + 0x02, 0xBB, 0xD7, 0xDF, 0x50, 0x6A, 0x55, 0x46, 0xBF, 0xA0, 0xA3, 0x28, + 0x61, 0x7F, 0x70, 0xD0, 0xC3, 0xA2, 0xAA, 0x2C, 0x21, 0xAA, 0x47, 0xCE, + 0x28, 0x9C, 0x06, 0x45, 0x76, 0xBF, 0x82, 0x18, 0x27, 0xB4, 0xD5, 0xAE, + 0xB4, 0xCB, 0x50, 0xE6, 0x6B, 0xF4, 0x4C, 0x86, 0x71, 0x30, 0xE9, 0xA6, + 0xDF, 0x16, 0x86, 0xE0, 0xD8, 0xFF, 0x40, 0xDD, 0xFB, 0xD0, 0x42, 0x88, + 0x7F, 0xA3, 0x33, 0x3A, 0x2E, 0x5C, 0x1E, 0x41, 0x11, 0x81, 0x63, 0xCE, + 0x18, 0x71, 0x6B, 0x2B, 0xEC, 0xA6, 0x8A, 0xB7, 0x31, 0x5C, 0x3A, 0x6A, + 0x47, 0xE0, 0xC3, 0x79, 0x59, 0xD6, 0x20, 0x1A, 0xAF, 0xF2, 0x6A, 0x98, + 0xAA, 0x72, 0xBC, 0x57, 0x4A, 0xD2, 0x4B, 0x9D, 0xBB, 0x10, 0xFC, 0xB0, + 0x4C, 0x41, 0xE5, 0xED, 0x1D, 0x3D, 0x5E, 0x28, 0x9D, 0x9C, 0xCC, 0xBF, + 0xB3, 0x51, 0xDA, 0xA7, 0x47, 0xE5, 0x84, 0x53 +}; + +static const unsigned char TA581_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA582_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x21, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x45, 0x56, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA582_RSA_N[] = { + 0x99, 0xF1, 0x84, 0x34, 0x70, 0xBA, 0x2F, 0xB7, 0x30, 0xA0, 0x8E, 0xBD, + 0x7C, 0x04, 0xCF, 0xBE, 0x62, 0xBC, 0x99, 0xFD, 0x82, 0x97, 0xD2, 0x7A, + 0x0A, 0x67, 0x96, 0x38, 0x09, 0xF6, 0x10, 0x4E, 0x95, 0x22, 0x73, 0x99, + 0x8D, 0xDA, 0x15, 0x2D, 0xE7, 0x05, 0xFC, 0x19, 0x73, 0x22, 0xB7, 0x8E, + 0x98, 0x00, 0xBC, 0x3C, 0x3D, 0xAC, 0xA1, 0x6C, 0xFB, 0xD6, 0x79, 0x25, + 0x4B, 0xAD, 0xF0, 0xCC, 0x64, 0xDA, 0x88, 0x3E, 0x29, 0xB8, 0x0F, 0x09, + 0xD3, 0x34, 0xDD, 0x33, 0xF5, 0x62, 0xD1, 0xE1, 0xCD, 0x19, 0xE9, 0xEE, + 0x18, 0x4F, 0x4C, 0x58, 0xAE, 0xE2, 0x1E, 0xD6, 0x0C, 0x5B, 0x15, 0x5A, + 0xD8, 0x3A, 0xB8, 0xC4, 0x18, 0x64, 0x1E, 0xE3, 0x33, 0xB2, 0xB5, 0x89, + 0x77, 0x4E, 0x0C, 0xBF, 0xD9, 0x94, 0x6B, 0x13, 0x97, 0x6F, 0x12, 0xA3, + 0xFE, 0x99, 0xA9, 0x04, 0xCC, 0x15, 0xEC, 0x60, 0x68, 0x36, 0xED, 0x08, + 0x7B, 0xB7, 0xF5, 0xBF, 0x93, 0xED, 0x66, 0x31, 0x83, 0x8C, 0xC6, 0x71, + 0x34, 0x87, 0x4E, 0x17, 0xEA, 0xAF, 0x8B, 0x91, 0x8D, 0x1C, 0x56, 0x41, + 0xAE, 0x22, 0x37, 0x5E, 0x37, 0xF2, 0x1D, 0xD9, 0xD1, 0x2D, 0x0D, 0x2F, + 0x69, 0x51, 0xA7, 0xBE, 0x66, 0xA6, 0x8A, 0x3A, 0x2A, 0xBD, 0xC7, 0x1A, + 0xB1, 0xE1, 0x14, 0xF0, 0xBE, 0x3A, 0x1D, 0xB9, 0xCF, 0x5B, 0xB1, 0x6A, + 0xFE, 0xB4, 0xB1, 0x46, 0x20, 0xA2, 0xFB, 0x1E, 0x3B, 0x70, 0xEF, 0x93, + 0x98, 0x7D, 0x8C, 0x73, 0x96, 0xF2, 0xC5, 0xEF, 0x85, 0x70, 0xAD, 0x29, + 0x26, 0xFC, 0x1E, 0x04, 0x3E, 0x1C, 0xA0, 0xD8, 0x0F, 0xCB, 0x52, 0x83, + 0x62, 0x7C, 0xEE, 0x8B, 0x53, 0x95, 0x90, 0xA9, 0x57, 0xA2, 0xEA, 0x61, + 0x05, 0xD8, 0xF9, 0x4D, 0xC4, 0x27, 0xFA, 0x6E, 0xAD, 0xED, 0xF9, 0xD7, + 0x51, 0xF7, 0x6B, 0xA5 +}; + +static const unsigned char TA582_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA583_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA583_RSA_N[] = { + 0x9A, 0x18, 0xCA, 0x4B, 0x94, 0x0D, 0x00, 0x2D, 0xAF, 0x03, 0x29, 0x8A, + 0xF0, 0x0F, 0x81, 0xC8, 0xAE, 0x4C, 0x19, 0x85, 0x1D, 0x08, 0x9F, 0xAB, + 0x29, 0x44, 0x85, 0xF3, 0x2F, 0x81, 0xAD, 0x32, 0x1E, 0x90, 0x46, 0xBF, + 0xA3, 0x86, 0x26, 0x1A, 0x1E, 0xFE, 0x7E, 0x1C, 0x18, 0x3A, 0x5C, 0x9C, + 0x60, 0x17, 0x2A, 0x3A, 0x74, 0x83, 0x33, 0x30, 0x7D, 0x61, 0x54, 0x11, + 0xCB, 0xED, 0xAB, 0xE0, 0xE6, 0xD2, 0xA2, 0x7E, 0xF5, 0x6B, 0x6F, 0x18, + 0xB7, 0x0A, 0x0B, 0x2D, 0xFD, 0xE9, 0x3E, 0xEF, 0x0A, 0xC6, 0xB3, 0x10, + 0xE9, 0xDC, 0xC2, 0x46, 0x17, 0xF8, 0x5D, 0xFD, 0xA4, 0xDA, 0xFF, 0x9E, + 0x49, 0x5A, 0x9C, 0xE6, 0x33, 0xE6, 0x24, 0x96, 0xF7, 0x3F, 0xBA, 0x5B, + 0x2B, 0x1C, 0x7A, 0x35, 0xC2, 0xD6, 0x67, 0xFE, 0xAB, 0x66, 0x50, 0x8B, + 0x6D, 0x28, 0x60, 0x2B, 0xEF, 0xD7, 0x60, 0xC3, 0xC7, 0x93, 0xBC, 0x8D, + 0x36, 0x91, 0xF3, 0x7F, 0xF8, 0xDB, 0x11, 0x13, 0xC4, 0x9C, 0x77, 0x76, + 0xC1, 0xAE, 0xB7, 0x02, 0x6A, 0x81, 0x7A, 0xA9, 0x45, 0x83, 0xE2, 0x05, + 0xE6, 0xB9, 0x56, 0xC1, 0x94, 0x37, 0x8F, 0x48, 0x71, 0x63, 0x22, 0xEC, + 0x17, 0x65, 0x07, 0x95, 0x8A, 0x4B, 0xDF, 0x8F, 0xC6, 0x5A, 0x0A, 0xE5, + 0xB0, 0xE3, 0x5F, 0x5E, 0x6B, 0x11, 0xAB, 0x0C, 0xF9, 0x85, 0xEB, 0x44, + 0xE9, 0xF8, 0x04, 0x73, 0xF2, 0xE9, 0xFE, 0x5C, 0x98, 0x8C, 0xF5, 0x73, + 0xAF, 0x6B, 0xB4, 0x7E, 0xCD, 0xD4, 0x5C, 0x02, 0x2B, 0x4C, 0x39, 0xE1, + 0xB2, 0x95, 0x95, 0x2D, 0x42, 0x87, 0xD7, 0xD5, 0xB3, 0x90, 0x43, 0xB7, + 0x6C, 0x13, 0xF1, 0xDE, 0xDD, 0xF6, 0xC4, 0xF8, 0x89, 0x3F, 0xD1, 0x75, + 0xF5, 0x92, 0xC3, 0x91, 0xD5, 0x8A, 0x88, 0xD0, 0x90, 0xEC, 0xDC, 0x6D, + 0xDE, 0x89, 0xC2, 0x65, 0x71, 0x96, 0x8B, 0x0D, 0x03, 0xFD, 0x9C, 0xBF, + 0x5B, 0x16, 0xAC, 0x92, 0xDB, 0xEA, 0xFE, 0x79, 0x7C, 0xAD, 0xEB, 0xAF, + 0xF7, 0x16, 0xCB, 0xDB, 0xCD, 0x25, 0x2B, 0xE5, 0x1F, 0xFB, 0x9A, 0x9F, + 0xE2, 0x51, 0xCC, 0x3A, 0x53, 0x0C, 0x48, 0xE6, 0x0E, 0xBD, 0xC9, 0xB4, + 0x76, 0x06, 0x52, 0xE6, 0x11, 0x13, 0x85, 0x72, 0x63, 0x03, 0x04, 0xE0, + 0x04, 0x36, 0x2B, 0x20, 0x19, 0x02, 0xE8, 0x74, 0xA7, 0x1F, 0xB6, 0xC9, + 0x56, 0x66, 0xF0, 0x75, 0x25, 0xDC, 0x67, 0xC1, 0x0E, 0x61, 0x60, 0x88, + 0xB3, 0x3E, 0xD1, 0xA8, 0xFC, 0xA3, 0xDA, 0x1D, 0xB0, 0xD1, 0xB1, 0x23, + 0x54, 0xDF, 0x44, 0x76, 0x6D, 0xED, 0x41, 0xD8, 0xC1, 0xB2, 0x22, 0xB6, + 0x53, 0x1C, 0xDF, 0x35, 0x1D, 0xDC, 0xA1, 0x77, 0x2A, 0x31, 0xE4, 0x2D, + 0xF5, 0xE5, 0xE5, 0xDB, 0xC8, 0xE0, 0xFF, 0xE5, 0x80, 0xD7, 0x0B, 0x63, + 0xA0, 0xFF, 0x33, 0xA1, 0x0F, 0xBA, 0x2C, 0x15, 0x15, 0xEA, 0x97, 0xB3, + 0xD2, 0xA2, 0xB5, 0xBE, 0xF2, 0x8C, 0x96, 0x1E, 0x1A, 0x8F, 0x1D, 0x6C, + 0xA4, 0x61, 0x37, 0xB9, 0x86, 0x73, 0x33, 0xD7, 0x97, 0x96, 0x9E, 0x23, + 0x7D, 0x82, 0xA4, 0x4C, 0x81, 0xE2, 0xA1, 0xD1, 0xBA, 0x67, 0x5F, 0x95, + 0x07, 0xA3, 0x27, 0x11, 0xEE, 0x16, 0x10, 0x7B, 0xBC, 0x45, 0x4A, 0x4C, + 0xB2, 0x04, 0xD2, 0xAB, 0xEF, 0xD5, 0xFD, 0x0C, 0x51, 0xCE, 0x50, 0x6A, + 0x08, 0x31, 0xF9, 0x91, 0xDA, 0x0C, 0x8F, 0x64, 0x5C, 0x03, 0xC3, 0x3A, + 0x8B, 0x20, 0x3F, 0x6E, 0x8D, 0x67, 0x3D, 0x3A, 0xD6, 0xFE, 0x7D, 0x5B, + 0x88, 0xC9, 0x5E, 0xFB, 0xCC, 0x61, 0xDC, 0x8B, 0x33, 0x77, 0xD3, 0x44, + 0x32, 0x35, 0x09, 0x62, 0x04, 0x92, 0x16, 0x10, 0xD8, 0x9E, 0x27, 0x47, + 0xFB, 0x3B, 0x21, 0xE3, 0xF8, 0xEB, 0x1D, 0x5B +}; + +static const unsigned char TA583_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA584_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA584_EC_Q[] = { + 0x04, 0x6B, 0xDA, 0x0D, 0x75, 0x35, 0x08, 0x31, 0x47, 0x05, 0xAE, 0x45, + 0x99, 0x55, 0xF1, 0x11, 0x13, 0x2E, 0x4A, 0xF8, 0x10, 0x31, 0x23, 0xA3, + 0x7E, 0x83, 0xD3, 0x7F, 0x28, 0x08, 0x3A, 0x26, 0x1A, 0x3A, 0xCF, 0x97, + 0x82, 0x1F, 0x80, 0xB7, 0x27, 0x09, 0x8F, 0xD1, 0x8E, 0x30, 0xC4, 0x0A, + 0x9B, 0x0E, 0xAC, 0x58, 0x04, 0xAB, 0xF7, 0x36, 0x7D, 0x94, 0x23, 0xA4, + 0x9B, 0x0A, 0x8A, 0x8B, 0xAB, 0xEB, 0xFD, 0x39, 0x25, 0x66, 0xF1, 0x5E, + 0xFE, 0x8C, 0xAE, 0x8D, 0x41, 0x79, 0x9D, 0x09, 0x60, 0xCE, 0x28, 0xA9, + 0xD3, 0x8A, 0x6D, 0xF3, 0xD6, 0x45, 0xD4, 0xF2, 0x98, 0x84, 0x38, 0x65, + 0xA0 +}; + +static const unsigned char TA585_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x52, 0x31 +}; + +static const unsigned char TA585_RSA_N[] = { + 0xD0, 0x36, 0xD4, 0x1F, 0xEA, 0xDD, 0xAB, 0xE4, 0xD1, 0xB6, 0xE6, 0xFB, + 0x22, 0xC0, 0xDD, 0x13, 0x0D, 0x6A, 0x7B, 0x22, 0x13, 0x1C, 0x97, 0x3C, + 0x68, 0x63, 0x66, 0x32, 0x9C, 0x03, 0xB5, 0x8D, 0xA4, 0x81, 0x83, 0xDA, + 0x78, 0x30, 0x11, 0xCF, 0xDC, 0xB2, 0x2B, 0xBE, 0x92, 0xBF, 0x8E, 0xE4, + 0xC4, 0x13, 0xBE, 0xA4, 0x68, 0x4C, 0xDA, 0x02, 0x68, 0x16, 0x74, 0xBE, + 0xB2, 0xDD, 0x04, 0xE4, 0x6B, 0x2A, 0xDD, 0x37, 0x1F, 0x60, 0x2C, 0xDB, + 0xF5, 0xF7, 0xA1, 0x7C, 0x95, 0xB7, 0x0C, 0x70, 0x86, 0x2E, 0xF1, 0x3A, + 0xEF, 0x52, 0xF7, 0xCC, 0xD3, 0x9B, 0xF9, 0x8B, 0xBE, 0x0E, 0xDF, 0x31, + 0xB7, 0x9D, 0x68, 0x5C, 0x92, 0xA6, 0xF5, 0xE5, 0xF3, 0x0A, 0x34, 0xB5, + 0xFF, 0x7B, 0xA2, 0xE4, 0x87, 0xA1, 0xC6, 0xAF, 0x17, 0x00, 0xEF, 0x03, + 0x91, 0xED, 0xA9, 0x1C, 0x4E, 0x71, 0x3D, 0xD2, 0x8B, 0x6C, 0x89, 0xF4, + 0x78, 0x86, 0xE6, 0x6A, 0x49, 0xA0, 0xCE, 0xB5, 0xD2, 0xB0, 0xAB, 0x9B, + 0xF6, 0xF4, 0xD4, 0x2E, 0xE3, 0x72, 0xF9, 0x36, 0xC6, 0xEB, 0x15, 0xB7, + 0x25, 0x8C, 0x3A, 0xFC, 0x25, 0x0D, 0xB3, 0x22, 0x73, 0x21, 0x74, 0xC8, + 0x4A, 0x96, 0x61, 0x92, 0xF5, 0x2F, 0x0B, 0x18, 0xA5, 0xF4, 0xAD, 0xE2, + 0xEE, 0x41, 0xBD, 0x01, 0x79, 0xFA, 0x96, 0x8C, 0x8D, 0x17, 0x02, 0x30, + 0xB4, 0xF9, 0xAF, 0x78, 0x1A, 0x8C, 0xB4, 0x36, 0x10, 0x10, 0x07, 0x05, + 0x70, 0xD0, 0xF4, 0x31, 0x90, 0x8A, 0x51, 0xC5, 0x86, 0x26, 0x79, 0xB2, + 0x11, 0x88, 0x5E, 0xC5, 0xF0, 0x0A, 0x54, 0xCD, 0x49, 0xA6, 0xBF, 0x02, + 0x9C, 0xD2, 0x44, 0xA7, 0xED, 0xE3, 0x78, 0xEF, 0x46, 0x5E, 0x6D, 0x71, + 0xD1, 0x79, 0x70, 0x1C, 0x46, 0x5F, 0x51, 0xE9, 0xC9, 0x37, 0xDC, 0x5F, + 0x7E, 0x69, 0x7B, 0x41, 0xDF, 0x34, 0x45, 0xE0, 0x3B, 0x84, 0xF4, 0xA1, + 0x8A, 0x0A, 0x36, 0x9E, 0x37, 0xCC, 0x62, 0x52, 0xE1, 0x89, 0x0D, 0x28, + 0xF9, 0x7A, 0x23, 0xB1, 0x0D, 0x3D, 0x3D, 0x9A, 0xFD, 0x9D, 0x81, 0xEF, + 0x2C, 0x90, 0xC0, 0x7B, 0x44, 0x4E, 0xBB, 0x49, 0xE0, 0x0E, 0x4A, 0x56, + 0x92, 0xBC, 0xCB, 0xB5, 0xDD, 0x79, 0x17, 0x89, 0x91, 0xDE, 0x61, 0x89, + 0x74, 0x92, 0xA8, 0xE3, 0x32, 0x85, 0xBE, 0x4E, 0x85, 0xA4, 0x4B, 0x59, + 0xCB, 0x2B, 0xC5, 0x78, 0x8E, 0x71, 0x54, 0xD0, 0x02, 0x37, 0x99, 0x8C, + 0xE5, 0x49, 0xEA, 0xE0, 0x54, 0x72, 0xA4, 0x11, 0x06, 0x2F, 0x0B, 0x8C, + 0xC1, 0x5B, 0xBE, 0xB5, 0xA1, 0xB0, 0x53, 0x6E, 0x9C, 0xB8, 0x60, 0x91, + 0x1F, 0x59, 0x6B, 0xF9, 0x2D, 0xF4, 0x94, 0x0A, 0x97, 0xB5, 0xEC, 0xC5, + 0x76, 0x03, 0x54, 0x1B, 0x65, 0x52, 0xBA, 0x4C, 0x92, 0x56, 0x51, 0x35, + 0xA0, 0x40, 0xD8, 0x29, 0xDB, 0xAE, 0x52, 0x76, 0x3B, 0x2D, 0x30, 0x40, + 0x9B, 0x8A, 0xD0, 0x42, 0x56, 0xB4, 0xB7, 0x88, 0x01, 0xA4, 0x87, 0x3B, + 0x53, 0x96, 0xCD, 0xA3, 0x16, 0x8F, 0xF3, 0x66, 0xAA, 0x17, 0xB1, 0xC7, + 0x60, 0xE0, 0xC1, 0x43, 0x05, 0x0C, 0xEE, 0x9B, 0x5B, 0x60, 0x6F, 0x06, + 0x5C, 0x87, 0x5B, 0x27, 0xF9, 0x40, 0x11, 0x9E, 0x9C, 0x33, 0xC1, 0xB7, + 0xE5, 0x35, 0x57, 0x05, 0x7F, 0x27, 0xCE, 0x17, 0x20, 0x8C, 0x1C, 0xFC, + 0xF1, 0xFB, 0xDA, 0x31, 0x29, 0x49, 0xED, 0xF5, 0x0B, 0x84, 0xA7, 0x4F, + 0xC1, 0xF6, 0x4E, 0xC2, 0x28, 0x9C, 0xFA, 0xEE, 0xE0, 0xAF, 0x07, 0xFB, + 0x33, 0x11, 0x7A, 0x21, 0x4F, 0x0B, 0x21, 0x10, 0xB6, 0x40, 0x3A, 0xAB, + 0x22, 0x3A, 0x04, 0x9C, 0x8B, 0x9B, 0x84, 0x86, 0x72, 0x9A, 0xD2, 0xA7, + 0xA5, 0xC4, 0xB4, 0x75, 0x91, 0xA9, 0x2B, 0x23 +}; + +static const unsigned char TA585_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA586_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, + 0x36 +}; + +static const unsigned char TA586_EC_Q[] = { + 0x04, 0x76, 0xFA, 0x99, 0xA9, 0x6E, 0x20, 0xED, 0xF9, 0xD7, 0x77, 0xE3, + 0x07, 0x3B, 0xA8, 0xDB, 0x3D, 0x5F, 0x38, 0xE8, 0xAB, 0x55, 0xA6, 0x56, + 0x4F, 0xD6, 0x48, 0xEA, 0xEC, 0x7F, 0x2D, 0xAA, 0xC3, 0xB2, 0xC5, 0x79, + 0xEC, 0x99, 0x61, 0x7F, 0x10, 0x79, 0xC7, 0x02, 0x5A, 0xF9, 0x04, 0x37, + 0xF5, 0x34, 0x35, 0x2B, 0x77, 0xCE, 0x7F, 0x20, 0x8F, 0x52, 0xA3, 0x00, + 0x89, 0xEC, 0xD5, 0xA7, 0xA2, 0x6D, 0x5B, 0xE3, 0x4B, 0x92, 0x93, 0xA0, + 0x80, 0xF5, 0x01, 0x94, 0xDC, 0xF0, 0x68, 0x07, 0x1E, 0xCD, 0xEE, 0xFE, + 0x25, 0x52, 0xB5, 0x20, 0x43, 0x1C, 0x1B, 0xFE, 0xEB, 0x19, 0xCE, 0x43, + 0xA3 +}; + +static const unsigned char TA587_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x55, 0x43, 0x41, + 0x20, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, + 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74 +}; + +static const unsigned char TA587_RSA_N[] = { + 0xA9, 0x09, 0x07, 0x28, 0x13, 0x02, 0xB0, 0x99, 0xE0, 0x64, 0xAA, 0x1E, + 0x43, 0x16, 0x7A, 0x73, 0xB1, 0x91, 0xA0, 0x75, 0x3E, 0xA8, 0xFA, 0xE3, + 0x38, 0x00, 0x7A, 0xEC, 0x89, 0x6A, 0x20, 0x0F, 0x8B, 0xC5, 0xB0, 0x9B, + 0x33, 0x03, 0x5A, 0x86, 0xC6, 0x58, 0x86, 0xD5, 0xC1, 0x85, 0xBB, 0x4F, + 0xC6, 0x9C, 0x40, 0x4D, 0xCA, 0xBE, 0xEE, 0x69, 0x96, 0xB8, 0xAD, 0x81, + 0x30, 0x9A, 0x7C, 0x92, 0x05, 0xEB, 0x05, 0x2B, 0x9A, 0x48, 0xD0, 0xB8, + 0x76, 0x3E, 0x96, 0xC8, 0x20, 0xBB, 0xD2, 0xB0, 0xF1, 0x8F, 0xD8, 0xAC, + 0x45, 0x46, 0xFF, 0xAA, 0x67, 0x60, 0xB4, 0x77, 0x7E, 0x6A, 0x1F, 0x3C, + 0x1A, 0x52, 0x7A, 0x04, 0x3D, 0x07, 0x3C, 0x85, 0x0D, 0x84, 0xD0, 0x1F, + 0x76, 0x0A, 0xF7, 0x6A, 0x14, 0xDF, 0x72, 0xE3, 0x34, 0x7C, 0x57, 0x4E, + 0x56, 0x01, 0x3E, 0x79, 0xF1, 0xAA, 0x29, 0x3B, 0x6C, 0xFA, 0xF8, 0x8F, + 0x6D, 0x4D, 0xC8, 0x35, 0xDF, 0xAE, 0xEB, 0xDC, 0x24, 0xEE, 0x79, 0x45, + 0xA7, 0x85, 0xB6, 0x05, 0x88, 0xDE, 0x88, 0x5D, 0x25, 0x7C, 0x97, 0x64, + 0x67, 0x09, 0xD9, 0xBF, 0x5A, 0x15, 0x05, 0x86, 0xF3, 0x09, 0x1E, 0xEC, + 0x58, 0x32, 0x33, 0x11, 0xF3, 0x77, 0x64, 0xB0, 0x76, 0x1F, 0xE4, 0x10, + 0x35, 0x17, 0x1B, 0xF2, 0x0E, 0xB1, 0x6C, 0xA4, 0x2A, 0xA3, 0x73, 0xFC, + 0x09, 0x1F, 0x1E, 0x32, 0x19, 0x53, 0x11, 0xE7, 0xD9, 0xB3, 0x2C, 0x2E, + 0x76, 0x2E, 0xA1, 0xA3, 0xDE, 0x7E, 0x6A, 0x88, 0x09, 0xE8, 0xF2, 0x07, + 0x8A, 0xF8, 0xB2, 0xCD, 0x10, 0xE7, 0xE2, 0x73, 0x40, 0x93, 0xBB, 0x08, + 0xD1, 0x3F, 0xE1, 0xFC, 0x0B, 0x94, 0xB3, 0x25, 0xEF, 0x7C, 0xA6, 0xD7, + 0xD1, 0xAF, 0x9F, 0xFF, 0x96, 0x9A, 0xF5, 0x91, 0x7B, 0x98, 0x0B, 0x77, + 0xD4, 0x7E, 0xE8, 0x07, 0xD2, 0x62, 0xB5, 0x95, 0x39, 0xE3, 0xF3, 0xF1, + 0x6D, 0x0F, 0x0E, 0x65, 0x84, 0x8A, 0x63, 0x54, 0xC5, 0x80, 0xB6, 0xE0, + 0x9E, 0x4B, 0x7D, 0x47, 0x26, 0xA7, 0x01, 0x08, 0x5D, 0xD1, 0x88, 0x9E, + 0xD7, 0xC3, 0x32, 0x44, 0xFA, 0x82, 0x4A, 0x0A, 0x68, 0x54, 0x7F, 0x38, + 0x53, 0x03, 0xCC, 0xA4, 0x00, 0x33, 0x64, 0x51, 0x59, 0x0B, 0xA3, 0x82, + 0x91, 0x7A, 0x5E, 0xEC, 0x16, 0xC2, 0xF3, 0x2A, 0xE6, 0x62, 0xDA, 0x2A, + 0xDB, 0x59, 0x62, 0x10, 0x25, 0x4A, 0x2A, 0x81, 0x0B, 0x47, 0x07, 0x43, + 0x06, 0x70, 0x87, 0xD2, 0xFA, 0x93, 0x11, 0x29, 0x7A, 0x48, 0x4D, 0xEB, + 0x94, 0xC7, 0x70, 0x4D, 0xAF, 0x67, 0xD5, 0x51, 0xB1, 0x80, 0x20, 0x01, + 0x01, 0xB4, 0x7A, 0x08, 0xA6, 0x90, 0x7F, 0x4E, 0xE0, 0xEF, 0x07, 0x41, + 0x87, 0xAF, 0x6A, 0xA5, 0x5E, 0x8B, 0xFB, 0xCF, 0x50, 0xB2, 0x9A, 0x54, + 0xAF, 0xC3, 0x89, 0xBA, 0x58, 0x2D, 0xF5, 0x30, 0x98, 0xB1, 0x36, 0x72, + 0x39, 0x7E, 0x49, 0x04, 0xFD, 0x29, 0xA7, 0x4C, 0x79, 0xE4, 0x05, 0x57, + 0xDB, 0x94, 0xB9, 0x16, 0x53, 0x8D, 0x46, 0xB3, 0x1D, 0x95, 0x61, 0x57, + 0x56, 0x7F, 0xAF, 0xF0, 0x16, 0x5B, 0x61, 0x58, 0x6F, 0x36, 0x50, 0x11, + 0x0B, 0xD8, 0xAC, 0x2B, 0x95, 0x16, 0x1A, 0x0E, 0x1F, 0x08, 0xCD, 0x36, + 0x34, 0x65, 0x10, 0x62, 0x66, 0xD5, 0x80, 0x5F, 0x14, 0x20, 0x5F, 0x2D, + 0x0C, 0xA0, 0x78, 0x0A, 0x68, 0xD6, 0x2C, 0xD7, 0xE9, 0x6F, 0x2B, 0xD2, + 0x4A, 0x05, 0x93, 0xFC, 0x9E, 0x6F, 0x6B, 0x67, 0xFF, 0x88, 0xF1, 0x4E, + 0xA5, 0x69, 0x4A, 0x52, 0x37, 0x05, 0xEA, 0xC6, 0x16, 0x8D, 0xD2, 0xC4, + 0x99, 0xD1, 0x82, 0x2B, 0x3B, 0xBA, 0x35, 0x75, 0xF7, 0x51, 0x51, 0x58, + 0xF3, 0xC8, 0x07, 0xDD, 0xE4, 0xB4, 0x03, 0x7F +}; + +static const unsigned char TA587_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA588_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x13, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D +}; + +static const unsigned char TA588_RSA_N[] = { + 0xC4, 0x12, 0xDF, 0xA9, 0x5F, 0xFE, 0x41, 0xDD, 0xDD, 0xF5, 0x9F, 0x8A, + 0xE3, 0xF6, 0xAC, 0xE1, 0x3C, 0x78, 0x9A, 0xBC, 0xD8, 0xF0, 0x7F, 0x7A, + 0xA0, 0x33, 0x2A, 0xDC, 0x8D, 0x20, 0x5B, 0xAE, 0x2D, 0x6F, 0xE7, 0x93, + 0xD9, 0x36, 0x70, 0x6A, 0x68, 0xCF, 0x8E, 0x51, 0xA3, 0x85, 0x5B, 0x67, + 0x04, 0xA0, 0x10, 0x24, 0x6F, 0x5D, 0x28, 0x82, 0xC1, 0x97, 0x57, 0xD8, + 0x48, 0x29, 0x13, 0xB6, 0xE1, 0xBE, 0x91, 0x4D, 0xDF, 0x85, 0x0C, 0x53, + 0x18, 0x9A, 0x1E, 0x24, 0xA2, 0x4F, 0x8F, 0xF0, 0xA2, 0x85, 0x0B, 0xCB, + 0xF4, 0x29, 0x7F, 0xD2, 0xA4, 0x58, 0xEE, 0x26, 0x4D, 0xC9, 0xAA, 0xA8, + 0x7B, 0x9A, 0xD9, 0xFA, 0x38, 0xDE, 0x44, 0x57, 0x15, 0xE5, 0xF8, 0x8C, + 0xC8, 0xD9, 0x48, 0xE2, 0x0D, 0x16, 0x27, 0x1D, 0x1E, 0xC8, 0x83, 0x85, + 0x25, 0xB7, 0xBA, 0xAA, 0x55, 0x41, 0xCC, 0x03, 0x22, 0x4B, 0x2D, 0x91, + 0x8D, 0x8B, 0xE6, 0x89, 0xAF, 0x66, 0xC7, 0xE9, 0xFF, 0x2B, 0xE9, 0x3C, + 0xAC, 0xDA, 0xD2, 0xB3, 0xC3, 0xE1, 0x68, 0x9C, 0x89, 0xF8, 0x7A, 0x00, + 0x56, 0xDE, 0xF4, 0x55, 0x95, 0x6C, 0xFB, 0xBA, 0x64, 0xDD, 0x62, 0x8B, + 0xDF, 0x0B, 0x77, 0x32, 0xEB, 0x62, 0xCC, 0x26, 0x9A, 0x9B, 0xBB, 0xAA, + 0x62, 0x83, 0x4C, 0xB4, 0x06, 0x7A, 0x30, 0xC8, 0x29, 0xBF, 0xED, 0x06, + 0x4D, 0x97, 0xB9, 0x1C, 0xC4, 0x31, 0x2B, 0xD5, 0x5F, 0xBC, 0x53, 0x12, + 0x17, 0x9C, 0x99, 0x57, 0x29, 0x66, 0x77, 0x61, 0x21, 0x31, 0x07, 0x2E, + 0x25, 0x49, 0x9D, 0x18, 0xF2, 0xEE, 0xF3, 0x2B, 0x71, 0x8C, 0xB5, 0xBA, + 0x39, 0x07, 0x49, 0x77, 0xFC, 0xEF, 0x2E, 0x92, 0x90, 0x05, 0x8D, 0x2D, + 0x2F, 0x77, 0x7B, 0xEF, 0x43, 0xBF, 0x35, 0xBB, 0x9A, 0xD8, 0xF9, 0x73, + 0xA7, 0x2C, 0xF2, 0xD0, 0x57, 0xEE, 0x28, 0x4E, 0x26, 0x5F, 0x8F, 0x90, + 0x68, 0x09, 0x2F, 0xB8, 0xF8, 0xDC, 0x06, 0xE9, 0x2E, 0x9A, 0x3E, 0x51, + 0xA7, 0xD1, 0x22, 0xC4, 0x0A, 0xA7, 0x38, 0x48, 0x6C, 0xB3, 0xF9, 0xFF, + 0x7D, 0xAB, 0x86, 0x57, 0xE3, 0xBA, 0xD6, 0x85, 0x78, 0x77, 0xBA, 0x43, + 0xEA, 0x48, 0x7F, 0xF6, 0xD8, 0xBE, 0x23, 0x6D, 0x1E, 0xBF, 0xD1, 0x36, + 0x6C, 0x58, 0x5C, 0xF1, 0xEE, 0xA4, 0x19, 0x54, 0x1A, 0xF5, 0x03, 0xD2, + 0x76, 0xE6, 0xE1, 0x8C, 0xBD, 0x3C, 0xB3, 0xD3, 0x48, 0x4B, 0xE2, 0xC8, + 0xF8, 0x7F, 0x92, 0xA8, 0x76, 0x46, 0x9C, 0x42, 0x65, 0x3E, 0xA4, 0x1E, + 0xC1, 0x07, 0x03, 0x5A, 0x46, 0x2D, 0xB8, 0x97, 0xF3, 0xB7, 0xD5, 0xB2, + 0x55, 0x21, 0xEF, 0xBA, 0xDC, 0x4C, 0x00, 0x97, 0xFB, 0x14, 0x95, 0x27, + 0x33, 0xBF, 0xE8, 0x43, 0x47, 0x46, 0xD2, 0x08, 0x99, 0x16, 0x60, 0x3B, + 0x9A, 0x7E, 0xD2, 0xE6, 0xED, 0x38, 0xEA, 0xEC, 0x01, 0x1E, 0x3C, 0x48, + 0x56, 0x49, 0x09, 0xC7, 0x4C, 0x37, 0x00, 0x9E, 0x88, 0x0E, 0xC0, 0x73, + 0xE1, 0x6F, 0x66, 0xE9, 0x72, 0x47, 0x30, 0x3E, 0x10, 0xE5, 0x0B, 0x03, + 0xC9, 0x9A, 0x42, 0x00, 0x6C, 0xC5, 0x94, 0x7E, 0x61, 0xC4, 0x8A, 0xDF, + 0x7F, 0x82, 0x1A, 0x0B, 0x59, 0xC4, 0x59, 0x32, 0x77, 0xB3, 0xBC, 0x60, + 0x69, 0x56, 0x39, 0xFD, 0xB4, 0x06, 0x7B, 0x2C, 0xD6, 0x64, 0x36, 0xD9, + 0xBD, 0x48, 0xED, 0x84, 0x1F, 0x7E, 0xA5, 0x22, 0x8F, 0x2A, 0xB8, 0x42, + 0xF4, 0x82, 0xB7, 0xD4, 0x53, 0x90, 0x78, 0x4E, 0x2D, 0x1A, 0xFD, 0x81, + 0x6F, 0x44, 0xD7, 0x3B, 0x01, 0x74, 0x96, 0x42, 0xE0, 0x00, 0xE2, 0x2E, + 0x6B, 0xEA, 0xC5, 0xEE, 0x72, 0xAC, 0xBB, 0xBF, 0xFE, 0xEA, 0xAA, 0xA8, + 0xF8, 0xDC, 0xF6, 0xB2, 0x79, 0x8A, 0xB6, 0x67 +}; + +static const unsigned char TA588_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA589_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x1C, + 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x43, 0x31 +}; + +static const unsigned char TA589_RSA_N[] = { + 0xCF, 0xEB, 0xA9, 0xB9, 0xF1, 0x99, 0x05, 0xCC, 0xD8, 0x28, 0x21, 0x4A, + 0xF3, 0x73, 0x34, 0x51, 0x84, 0x56, 0x10, 0xF5, 0xA0, 0x4F, 0x2C, 0x12, + 0xE3, 0xFA, 0x13, 0x9A, 0x27, 0xD0, 0xCF, 0xF9, 0x79, 0x1A, 0x74, 0x5F, + 0x1D, 0x79, 0x39, 0xFC, 0x5B, 0xF8, 0x70, 0x8E, 0xE0, 0x92, 0x52, 0xF7, + 0xE4, 0x25, 0xF9, 0x54, 0x83, 0xD9, 0x1D, 0xD3, 0xC8, 0x5A, 0x85, 0x3F, + 0x5E, 0xC7, 0xB6, 0x07, 0xEE, 0x3E, 0xC0, 0xCE, 0x9A, 0xAF, 0xAC, 0x56, + 0x42, 0x2A, 0x39, 0x25, 0x70, 0xD6, 0xBF, 0xB5, 0x7B, 0x36, 0xAD, 0xAC, + 0xF6, 0x73, 0xDC, 0xCD, 0xD7, 0x1D, 0x8A, 0x83, 0xA5, 0xFB, 0x2B, 0x90, + 0x15, 0x37, 0x6B, 0x1C, 0x26, 0x47, 0xDC, 0x3B, 0x29, 0x56, 0x93, 0x6A, + 0xB3, 0xC1, 0x6A, 0x3A, 0x9D, 0x3D, 0xF5, 0xC1, 0x97, 0x38, 0x58, 0x05, + 0x8B, 0x1C, 0x11, 0xE3, 0xE4, 0xB4, 0xB8, 0x5D, 0x85, 0x1D, 0x83, 0xFE, + 0x78, 0x5F, 0x0B, 0x45, 0x68, 0x18, 0x48, 0xA5, 0x46, 0x73, 0x34, 0x3B, + 0xFE, 0x0F, 0xC8, 0x76, 0xBB, 0xC7, 0x18, 0xF3, 0x05, 0xD1, 0x86, 0xF3, + 0x85, 0xED, 0xE7, 0xB9, 0xD9, 0x32, 0xAD, 0x55, 0x88, 0xCE, 0xA6, 0xB6, + 0x91, 0xB0, 0x4F, 0xAC, 0x7E, 0x15, 0x23, 0x96, 0xF6, 0x3F, 0xF0, 0x20, + 0x34, 0x16, 0xDE, 0x0A, 0xC6, 0xC4, 0x04, 0x45, 0x79, 0x7F, 0xA7, 0xFD, + 0xBE, 0xD2, 0xA9, 0xA5, 0xAF, 0x9C, 0xC5, 0x23, 0x2A, 0xF7, 0x3C, 0x21, + 0x6C, 0xBD, 0xAF, 0x8F, 0x4E, 0xC5, 0x3A, 0xB2, 0xF3, 0x34, 0x12, 0xFC, + 0xDF, 0x80, 0x1A, 0x49, 0xA4, 0xD4, 0xA9, 0x95, 0xF7, 0x9E, 0x89, 0x5E, + 0xA2, 0x89, 0xAC, 0x94, 0xCB, 0xA8, 0x68, 0x9B, 0xAF, 0x8A, 0x65, 0x27, + 0xCD, 0x89, 0xEE, 0xDD, 0x8C, 0xB5, 0x6B, 0x29, 0x70, 0x43, 0xA0, 0x69, + 0x0B, 0xE4, 0xB9, 0x0F +}; + +static const unsigned char TA589_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA590_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x36, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA590_RSA_N[] = { + 0x95, 0x07, 0xE8, 0x73, 0xCA, 0x66, 0xF9, 0xEC, 0x14, 0xCA, 0x7B, 0x3C, + 0xF7, 0x0D, 0x08, 0xF1, 0xB4, 0x45, 0x0B, 0x2C, 0x82, 0xB4, 0x48, 0xC6, + 0xEB, 0x5B, 0x3C, 0xAE, 0x83, 0xB8, 0x41, 0x92, 0x33, 0x14, 0xA4, 0x6F, + 0x7F, 0xE9, 0x2A, 0xCC, 0xC6, 0xB0, 0x88, 0x6B, 0xC5, 0xB6, 0x89, 0xD1, + 0xC6, 0xB2, 0xFF, 0x14, 0xCE, 0x51, 0x14, 0x21, 0xEC, 0x4A, 0xDD, 0x1B, + 0x5A, 0xC6, 0xD6, 0x87, 0xEE, 0x4D, 0x3A, 0x15, 0x06, 0xED, 0x64, 0x66, + 0x0B, 0x92, 0x80, 0xCA, 0x44, 0xDE, 0x73, 0x94, 0x4E, 0xF3, 0xA7, 0x89, + 0x7F, 0x4F, 0x78, 0x63, 0x08, 0xC8, 0x12, 0x50, 0x6D, 0x42, 0x66, 0x2F, + 0x4D, 0xB9, 0x79, 0x28, 0x4D, 0x52, 0x1A, 0x8A, 0x1A, 0x80, 0xB7, 0x19, + 0x81, 0x0E, 0x7E, 0xC4, 0x8A, 0xBC, 0x64, 0x4C, 0x21, 0x1C, 0x43, 0x68, + 0xD7, 0x3D, 0x3C, 0x8A, 0xC5, 0xB2, 0x66, 0xD5, 0x90, 0x9A, 0xB7, 0x31, + 0x06, 0xC5, 0xBE, 0xE2, 0x6D, 0x32, 0x06, 0xA6, 0x1E, 0xF9, 0xB9, 0xEB, + 0xAA, 0xA3, 0xB8, 0xBF, 0xBE, 0x82, 0x63, 0x50, 0xD0, 0xF0, 0x18, 0x89, + 0xDF, 0xE4, 0x0F, 0x79, 0xF5, 0xEA, 0xA2, 0x1F, 0x2A, 0xD2, 0x70, 0x2E, + 0x7B, 0xE7, 0xBC, 0x93, 0xBB, 0x6D, 0x53, 0xE2, 0x48, 0x7C, 0x8C, 0x10, + 0x07, 0x38, 0xFF, 0x66, 0xB2, 0x77, 0x61, 0x7E, 0xE0, 0xEA, 0x8C, 0x3C, + 0xAA, 0xB4, 0xA4, 0xF6, 0xF3, 0x95, 0x4A, 0x12, 0x07, 0x6D, 0xFD, 0x8C, + 0xB2, 0x89, 0xCF, 0xD0, 0xA0, 0x61, 0x77, 0xC8, 0x58, 0x74, 0xB0, 0xD4, + 0x23, 0x3A, 0xF7, 0x5D, 0x3A, 0xCA, 0xA2, 0xDB, 0x9D, 0x09, 0xDE, 0x5D, + 0x44, 0x2D, 0x90, 0xF1, 0x81, 0xCD, 0x57, 0x92, 0xFA, 0x7E, 0xBC, 0x50, + 0x04, 0x63, 0x34, 0xDF, 0x6B, 0x93, 0x18, 0xBE, 0x6B, 0x36, 0xB2, 0x39, + 0xE4, 0xAC, 0x24, 0x36, 0xB7, 0xF0, 0xEF, 0xB6, 0x1C, 0x13, 0x57, 0x93, + 0xB6, 0xDE, 0xB2, 0xF8, 0xE2, 0x85, 0xB7, 0x73, 0xA2, 0xB8, 0x35, 0xAA, + 0x45, 0xF2, 0xE0, 0x9D, 0x36, 0xA1, 0x6F, 0x54, 0x8A, 0xF1, 0x72, 0x56, + 0x6E, 0x2E, 0x88, 0xC5, 0x51, 0x42, 0x44, 0x15, 0x94, 0xEE, 0xA3, 0xC5, + 0x38, 0x96, 0x9B, 0x4E, 0x4E, 0x5A, 0x0B, 0x47, 0xF3, 0x06, 0x36, 0x49, + 0x77, 0x30, 0xBC, 0x71, 0x37, 0xE5, 0xA6, 0xEC, 0x21, 0x08, 0x75, 0xFC, + 0xE6, 0x61, 0x16, 0x3F, 0x77, 0xD5, 0xD9, 0x91, 0x97, 0x84, 0x0A, 0x6C, + 0xD4, 0x02, 0x4D, 0x74, 0xC0, 0x14, 0xED, 0xFD, 0x39, 0xFB, 0x83, 0xF2, + 0x5E, 0x14, 0xA1, 0x04, 0xB0, 0x0B, 0xE9, 0xFE, 0xEE, 0x8F, 0xE1, 0x6E, + 0x0B, 0xB2, 0x08, 0xB3, 0x61, 0x66, 0x09, 0x6A, 0xB1, 0x06, 0x3A, 0x65, + 0x96, 0x59, 0xC0, 0xF0, 0x35, 0xFD, 0xC9, 0xDA, 0x28, 0x8D, 0x1A, 0x11, + 0x87, 0x70, 0x81, 0x0A, 0xA8, 0x9A, 0x75, 0x1D, 0x9E, 0x3A, 0x86, 0x05, + 0x00, 0x9E, 0xDB, 0x80, 0xD6, 0x25, 0xF9, 0xDC, 0x05, 0x9E, 0x27, 0x59, + 0x4C, 0x76, 0x39, 0x5B, 0xEA, 0xF9, 0xA5, 0xA1, 0xD8, 0x83, 0x0F, 0xD1, + 0xFF, 0xDF, 0x30, 0x11, 0xF9, 0x85, 0xCF, 0x33, 0x48, 0xF5, 0xCA, 0x6D, + 0x64, 0x14, 0x2C, 0x7A, 0x58, 0x4F, 0xD3, 0x4B, 0x08, 0x49, 0xC5, 0x95, + 0x64, 0x1A, 0x63, 0x0E, 0x79, 0x3D, 0xF5, 0xB3, 0x8C, 0xCA, 0x58, 0xAD, + 0x9C, 0x42, 0x45, 0x79, 0x6E, 0x0E, 0x87, 0x19, 0x5C, 0x54, 0xB1, 0x65, + 0xB6, 0xBF, 0x8C, 0x9B, 0xDC, 0x13, 0xE9, 0x0D, 0x6F, 0xB8, 0x2E, 0xDC, + 0x67, 0x6E, 0xC9, 0x8B, 0x11, 0xB5, 0x84, 0x14, 0x8A, 0x00, 0x19, 0x70, + 0x83, 0x79, 0x91, 0x97, 0x91, 0xD4, 0x1A, 0x27, 0xBF, 0x37, 0x1E, 0x32, + 0x07, 0xD8, 0x14, 0x63, 0x3C, 0x28, 0x4C, 0xAF +}; + +static const unsigned char TA590_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA591_DN[] = { + 0x30, 0x81, 0xA6, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x40, 0x30, 0x3E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x37, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, + 0x35 +}; + +static const unsigned char TA591_RSA_N[] = { + 0xC2, 0xF8, 0xA9, 0x3F, 0x1B, 0x89, 0xFC, 0x3C, 0x3C, 0x04, 0x5D, 0x3D, + 0x90, 0x36, 0xB0, 0x91, 0x3A, 0x79, 0x3C, 0x66, 0x5A, 0xEF, 0x6D, 0x39, + 0x01, 0x49, 0x1A, 0xB4, 0xB7, 0xCF, 0x7F, 0x4D, 0x23, 0x53, 0xB7, 0x90, + 0x00, 0xE3, 0x13, 0x2A, 0x28, 0xA6, 0x31, 0xF1, 0x91, 0x00, 0xE3, 0x28, + 0xEC, 0xAE, 0x21, 0x41, 0xCE, 0x1F, 0xDA, 0xFD, 0x7D, 0x12, 0x5B, 0x01, + 0x83, 0x0F, 0xB9, 0xB0, 0x5F, 0x99, 0xE1, 0xF2, 0x12, 0x83, 0x80, 0x4D, + 0x06, 0x3E, 0xDF, 0xAC, 0xAF, 0xE7, 0xA1, 0x88, 0x6B, 0x31, 0xAF, 0xF0, + 0x8B, 0xD0, 0x18, 0x33, 0xB8, 0xDB, 0x45, 0x6A, 0x34, 0xF4, 0x02, 0x80, + 0x24, 0x28, 0x0A, 0x02, 0x15, 0x95, 0x5E, 0x76, 0x2A, 0x0D, 0x99, 0x3A, + 0x14, 0x5B, 0xF6, 0xCB, 0xCB, 0x53, 0xBC, 0x13, 0x4D, 0x01, 0x88, 0x37, + 0x94, 0x25, 0x1B, 0x42, 0xBC, 0x22, 0xD8, 0x8E, 0xA3, 0x96, 0x5E, 0x3A, + 0xD9, 0x32, 0xDB, 0x3E, 0xE8, 0xF0, 0x10, 0x65, 0xED, 0x74, 0xE1, 0x2F, + 0xA7, 0x7C, 0xAF, 0x27, 0x34, 0xBB, 0x29, 0x7D, 0x9B, 0xB6, 0xCF, 0x09, + 0xC8, 0xE5, 0xD3, 0x0A, 0xFC, 0x88, 0x65, 0x65, 0x74, 0x0A, 0xDC, 0x73, + 0x1C, 0x5C, 0xCD, 0x40, 0xB1, 0x1C, 0xD4, 0xB6, 0x84, 0x8C, 0x4C, 0x50, + 0xCF, 0x68, 0x8E, 0xA8, 0x59, 0xAE, 0xC2, 0x27, 0x4E, 0x82, 0xA2, 0x35, + 0xDD, 0x14, 0xF4, 0x1F, 0xFF, 0xB2, 0x77, 0xD5, 0x87, 0x2F, 0xAA, 0x6E, + 0x7D, 0x24, 0x27, 0xE7, 0xC6, 0xCB, 0x26, 0xE6, 0xE5, 0xFE, 0x67, 0x07, + 0x63, 0xD8, 0x45, 0x0D, 0xDD, 0x3A, 0x59, 0x65, 0x39, 0x58, 0x7A, 0x92, + 0x99, 0x72, 0x3D, 0x9C, 0x84, 0x5E, 0x88, 0x21, 0xB8, 0xD5, 0xF4, 0x2C, + 0xFC, 0xD9, 0x70, 0x52, 0x4F, 0x78, 0xB8, 0xBD, 0x3C, 0x2B, 0x8B, 0x95, + 0x98, 0xF5, 0xB3, 0xD1, 0x68, 0xCF, 0x20, 0x14, 0x7E, 0x4C, 0x5C, 0x5F, + 0xE7, 0x8B, 0xE5, 0xF5, 0x35, 0x81, 0x19, 0x37, 0xD7, 0x11, 0x08, 0xB7, + 0x66, 0xBE, 0xD3, 0x4A, 0xCE, 0x83, 0x57, 0x00, 0x3A, 0xC3, 0x81, 0xF8, + 0x17, 0xCB, 0x92, 0x36, 0x5D, 0xD1, 0xA3, 0xD8, 0x75, 0x1B, 0xE1, 0x8B, + 0x27, 0xEA, 0x7A, 0x48, 0x41, 0xFD, 0x45, 0x19, 0x06, 0xAD, 0x27, 0x99, + 0x4E, 0xC1, 0x70, 0x47, 0xDD, 0xB5, 0x9F, 0x81, 0x53, 0x12, 0xE5, 0xB1, + 0x8C, 0x48, 0x5D, 0x31, 0x43, 0x17, 0xE3, 0x8C, 0xC6, 0x7A, 0x63, 0x96, + 0x4B, 0x29, 0x30, 0x4E, 0x84, 0x4E, 0x62, 0x19, 0x5E, 0x3C, 0xCE, 0x97, + 0x90, 0xA5, 0x7F, 0x01, 0xEB, 0x9D, 0xE0, 0xF8, 0x8B, 0x89, 0xDD, 0x25, + 0x98, 0x3D, 0x92, 0xB6, 0x7E, 0xEF, 0xD9, 0xF1, 0x51, 0x51, 0x7D, 0x2D, + 0x26, 0xC8, 0x69, 0x59, 0x61, 0xE0, 0xAC, 0x6A, 0xB8, 0x2A, 0x36, 0x11, + 0x04, 0x7A, 0x50, 0xBD, 0x32, 0x84, 0xBE, 0x2F, 0xDC, 0x72, 0xD5, 0xD7, + 0x1D, 0x16, 0x47, 0xE4, 0x47, 0x66, 0x20, 0x3F, 0xF4, 0x96, 0xC5, 0xAF, + 0x8E, 0x01, 0x7A, 0xA5, 0x0F, 0x7A, 0x64, 0xF5, 0x0D, 0x18, 0x87, 0xD9, + 0xAE, 0x88, 0xD5, 0xFA, 0x84, 0xC1, 0x3A, 0xC0, 0x69, 0x28, 0x2D, 0xF2, + 0x0D, 0x68, 0x51, 0xAA, 0xE3, 0xA5, 0x77, 0xC6, 0xA4, 0x90, 0x0E, 0xA1, + 0x37, 0x8B, 0x31, 0x23, 0x47, 0xC1, 0x09, 0x08, 0xEB, 0x6E, 0xF7, 0x78, + 0x9B, 0xD7, 0x82, 0xFC, 0x84, 0x20, 0x99, 0x49, 0x19, 0xB6, 0x12, 0x46, + 0xB1, 0xFB, 0x45, 0x55, 0x16, 0xA9, 0xA3, 0x65, 0xAC, 0x9C, 0x07, 0x0F, + 0xEA, 0x6B, 0xDC, 0x1F, 0x2E, 0x06, 0x72, 0xEC, 0x86, 0x88, 0x12, 0xE4, + 0x2D, 0xDB, 0x5F, 0x05, 0x2F, 0xE4, 0xF0, 0x03, 0xD3, 0x26, 0x33, 0xE7, + 0x80, 0xC2, 0xCD, 0x42, 0xA1, 0x17, 0x34, 0x0B +}; + +static const unsigned char TA591_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA592_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x33 +}; + +static const unsigned char TA592_EC_Q[] = { + 0x04, 0xDD, 0xA7, 0xD9, 0xBB, 0x8A, 0xB8, 0x0B, 0xFB, 0x0B, 0x7F, 0x21, + 0xD2, 0xF0, 0xBE, 0xBE, 0x73, 0xF3, 0x33, 0x5D, 0x1A, 0xBC, 0x34, 0xEA, + 0xDE, 0xC6, 0x9B, 0xBC, 0xD0, 0x95, 0xF6, 0xF0, 0xCC, 0xD0, 0x0B, 0xBA, + 0x61, 0x5B, 0x51, 0x46, 0x7E, 0x9E, 0x2D, 0x9F, 0xEE, 0x8E, 0x63, 0x0C, + 0x17, 0xEC, 0x07, 0x70, 0xF5, 0xCF, 0x84, 0x2E, 0x40, 0x83, 0x9C, 0xE8, + 0x3F, 0x41, 0x6D, 0x3B, 0xAD, 0xD3, 0xA4, 0x14, 0x59, 0x36, 0x78, 0x9D, + 0x03, 0x43, 0xEE, 0x10, 0x13, 0x6C, 0x72, 0xDE, 0xAE, 0x88, 0xA7, 0xA1, + 0x6B, 0xB5, 0x43, 0xCE, 0x67, 0xDC, 0x23, 0xFF, 0x03, 0x1C, 0xA3, 0xE2, + 0x3E +}; + +static const unsigned char TA593_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA593_EC_Q[] = { + 0x04, 0xCE, 0xBF, 0xFE, 0x57, 0xA8, 0xBF, 0xD5, 0xAA, 0xF7, 0x10, 0x9A, + 0xCD, 0xBC, 0xD1, 0x11, 0xA2, 0xBD, 0x67, 0x42, 0xCC, 0x90, 0xEB, 0x15, + 0x18, 0x90, 0xD9, 0xA2, 0xCD, 0x0C, 0x2A, 0x25, 0xEB, 0x3E, 0x4F, 0xCE, + 0xB5, 0xD2, 0x8F, 0x0F, 0xF3, 0x35, 0xDA, 0x43, 0x8B, 0x02, 0x80, 0xBE, + 0x6F, 0x51, 0x24, 0x1D, 0x0F, 0x6B, 0x2B, 0xCA, 0x9F, 0xC2, 0x6F, 0x50, + 0x32, 0xE5, 0x37, 0x20, 0xB6, 0x20, 0xFF, 0x88, 0x0D, 0x0F, 0x6D, 0x49, + 0xBB, 0xDB, 0x06, 0xA4, 0x87, 0x90, 0x92, 0x94, 0xF4, 0x09, 0xD0, 0xCF, + 0x7F, 0xC8, 0x80, 0x0B, 0xC1, 0x97, 0xB3, 0xBB, 0x35, 0x27, 0xC9, 0xC2, + 0x1B +}; + +static const unsigned char TA594_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x34 +}; + +static const unsigned char TA594_EC_Q[] = { + 0x04, 0xD2, 0xAB, 0x8A, 0x37, 0x4F, 0xA3, 0x53, 0x0D, 0xFE, 0xC1, 0x8A, + 0x7B, 0x4B, 0xA8, 0x7B, 0x46, 0x4B, 0x63, 0xB0, 0x62, 0xF6, 0x2D, 0x1B, + 0xDB, 0x08, 0x71, 0x21, 0xD2, 0x00, 0xE8, 0x63, 0xBD, 0x9A, 0x27, 0xFB, + 0xF0, 0x39, 0x6E, 0x5D, 0xEA, 0x3D, 0xA5, 0xC9, 0x81, 0xAA, 0xA3, 0x5B, + 0x20, 0x98, 0x45, 0x5D, 0x16, 0xDB, 0xFD, 0xE8, 0x10, 0x6D, 0xE3, 0x9C, + 0xE0, 0xE3, 0xBD, 0x5F, 0x84, 0x62, 0xF3, 0x70, 0x64, 0x33, 0xA0, 0xCB, + 0x24, 0x2F, 0x70, 0xBA, 0x88, 0xA1, 0x2A, 0xA0, 0x75, 0xF8, 0x81, 0xAE, + 0x62, 0x06, 0xC4, 0x81, 0xDB, 0x39, 0x6E, 0x29, 0xB0, 0x1E, 0xFA, 0x2E, + 0x5C +}; + +static const unsigned char TA595_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x42, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA595_RSA_N[] = { + 0xD8, 0x17, 0xB7, 0x1C, 0x4A, 0x24, 0x2A, 0xD6, 0x97, 0xB1, 0xCA, 0xE2, + 0x1E, 0xFB, 0x7D, 0x38, 0xEF, 0x98, 0xF5, 0xB2, 0x39, 0x98, 0x4E, 0x27, + 0xB8, 0x11, 0x5D, 0x7B, 0xD2, 0x25, 0x94, 0x88, 0x82, 0x15, 0x26, 0x6A, + 0x1B, 0x31, 0xBB, 0xA8, 0x5B, 0x21, 0x21, 0x2B, 0xD8, 0x0F, 0x4E, 0x9F, + 0x5A, 0xF1, 0xB1, 0x5A, 0xE4, 0x79, 0xD6, 0x32, 0x23, 0x2B, 0xE1, 0x53, + 0xCC, 0x99, 0x45, 0x5C, 0x7B, 0x4F, 0xAD, 0xBC, 0xBF, 0x87, 0x4A, 0x0B, + 0x4B, 0x97, 0x5A, 0xA8, 0xF6, 0x48, 0xEC, 0x7D, 0x7B, 0x0D, 0xCD, 0x21, + 0x06, 0xDF, 0x9E, 0x15, 0xFD, 0x41, 0x8A, 0x48, 0xB7, 0x20, 0xF4, 0xA1, + 0x7A, 0x1B, 0x57, 0xD4, 0x5D, 0x50, 0xFF, 0xBA, 0x67, 0xD8, 0x23, 0x99, + 0x1F, 0xC8, 0x3F, 0xE3, 0xDE, 0xFF, 0x6F, 0x5B, 0x77, 0xB1, 0x6B, 0x6E, + 0xB8, 0xC9, 0x64, 0xF7, 0xE1, 0xCA, 0x41, 0x46, 0x0E, 0x29, 0x71, 0xD0, + 0xB9, 0x23, 0xFC, 0xC9, 0x81, 0x5F, 0x4E, 0xF7, 0x6F, 0xDF, 0xBF, 0x84, + 0xAD, 0x73, 0x64, 0xBB, 0xB7, 0x42, 0x8E, 0x69, 0xF6, 0xD4, 0x76, 0x1D, + 0x7E, 0x9D, 0xA7, 0xB8, 0x57, 0x8A, 0x51, 0x67, 0x72, 0xD7, 0xD4, 0xA8, + 0xB8, 0x95, 0x54, 0x40, 0x73, 0x03, 0xF6, 0xEA, 0xF4, 0xEB, 0xFE, 0x28, + 0x42, 0x77, 0x3F, 0x9D, 0x23, 0x1B, 0xB2, 0xB6, 0x3D, 0x80, 0x14, 0x07, + 0x4C, 0x2E, 0x4F, 0xF7, 0xD5, 0x0A, 0x16, 0x0D, 0xBD, 0x66, 0x43, 0x37, + 0x7E, 0x23, 0x43, 0x79, 0xC3, 0x40, 0x86, 0xF5, 0x4C, 0x29, 0xDA, 0x8E, + 0x9A, 0xAD, 0x0D, 0xA5, 0x04, 0x87, 0x88, 0x1E, 0x85, 0xE3, 0xE9, 0x53, + 0xD5, 0x9B, 0xC8, 0x8B, 0x03, 0x63, 0x78, 0xEB, 0xE0, 0x19, 0x4A, 0x6E, + 0xBB, 0x2F, 0x6B, 0x33, 0x64, 0x58, 0x93, 0xAD, 0x69, 0xBF, 0x8F, 0x1B, + 0xEF, 0x82, 0x48, 0xC7 +}; + +static const unsigned char TA595_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA596_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA596_RSA_N[] = { + 0xAD, 0x0E, 0x15, 0xCE, 0xE4, 0x43, 0x80, 0x5C, 0xB1, 0x87, 0xF3, 0xB7, + 0x60, 0xF9, 0x71, 0x12, 0xA5, 0xAE, 0xDC, 0x26, 0x94, 0x88, 0xAA, 0xF4, + 0xCE, 0xF5, 0x20, 0x39, 0x28, 0x58, 0x60, 0x0C, 0xF8, 0x80, 0xDA, 0xA9, + 0x15, 0x95, 0x32, 0x61, 0x3C, 0xB5, 0xB1, 0x28, 0x84, 0x8A, 0x8A, 0xDC, + 0x9F, 0x0A, 0x0C, 0x83, 0x17, 0x7A, 0x8F, 0x90, 0xAC, 0x8A, 0xE7, 0x79, + 0x53, 0x5C, 0x31, 0x84, 0x2A, 0xF6, 0x0F, 0x98, 0x32, 0x36, 0x76, 0xCC, + 0xDE, 0xDD, 0x3C, 0xA8, 0xA2, 0xEF, 0x6A, 0xFB, 0x21, 0xF2, 0x52, 0x61, + 0xDF, 0x9F, 0x20, 0xD7, 0x1F, 0xE2, 0xB1, 0xD9, 0xFE, 0x18, 0x64, 0xD2, + 0x12, 0x5B, 0x5F, 0xF9, 0x58, 0x18, 0x35, 0xBC, 0x47, 0xCD, 0xA1, 0x36, + 0xF9, 0x6B, 0x7F, 0xD4, 0xB0, 0x38, 0x3E, 0xC1, 0x1B, 0xC3, 0x8C, 0x33, + 0xD9, 0xD8, 0x2F, 0x18, 0xFE, 0x28, 0x0F, 0xB3, 0xA7, 0x83, 0xD6, 0xC3, + 0x6E, 0x44, 0xC0, 0x61, 0x35, 0x96, 0x16, 0xFE, 0x59, 0x9C, 0x8B, 0x76, + 0x6D, 0xD7, 0xF1, 0xA2, 0x4B, 0x0D, 0x2B, 0xFF, 0x0B, 0x72, 0xDA, 0x9E, + 0x60, 0xD0, 0x8E, 0x90, 0x35, 0xC6, 0x78, 0x55, 0x87, 0x20, 0xA1, 0xCF, + 0xE5, 0x6D, 0x0A, 0xC8, 0x49, 0x7C, 0x31, 0x98, 0x33, 0x6C, 0x22, 0xE9, + 0x87, 0xD0, 0x32, 0x5A, 0xA2, 0xBA, 0x13, 0x82, 0x11, 0xED, 0x39, 0x17, + 0x9D, 0x99, 0x3A, 0x72, 0xA1, 0xE6, 0xFA, 0xA4, 0xD9, 0xD5, 0x17, 0x31, + 0x75, 0xAE, 0x85, 0x7D, 0x22, 0xAE, 0x3F, 0x01, 0x46, 0x86, 0xF6, 0x28, + 0x79, 0xC8, 0xB1, 0xDA, 0xE4, 0x57, 0x17, 0xC4, 0x7E, 0x1C, 0x0E, 0xB0, + 0xB4, 0x92, 0xA6, 0x56, 0xB3, 0xBD, 0xB2, 0x97, 0xED, 0xAA, 0xA7, 0xF0, + 0xB7, 0xC5, 0xA8, 0x3F, 0x95, 0x16, 0xD0, 0xFF, 0xA1, 0x96, 0xEB, 0x08, + 0x5F, 0x18, 0x77, 0x4F +}; + +static const unsigned char TA596_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA597_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA597_RSA_N[] = { + 0xD9, 0xE7, 0x28, 0x2F, 0x52, 0x3F, 0x36, 0x72, 0x49, 0x88, 0x93, 0x34, + 0xF3, 0xF8, 0x6A, 0x1E, 0x31, 0x54, 0x80, 0x9F, 0xAD, 0x54, 0x41, 0xB5, + 0x47, 0xDF, 0x96, 0xA8, 0xD4, 0xAF, 0x80, 0x2D, 0xB9, 0x0A, 0xCF, 0x75, + 0xFD, 0x89, 0xA5, 0x7D, 0x24, 0xFA, 0xE3, 0x22, 0x0C, 0x2B, 0xBC, 0x95, + 0x17, 0x0B, 0x33, 0xBF, 0x19, 0x4D, 0x41, 0x06, 0x90, 0x00, 0xBD, 0x0C, + 0x4D, 0x10, 0xFE, 0x07, 0xB5, 0xE7, 0x1C, 0x6E, 0x22, 0x55, 0x31, 0x65, + 0x97, 0xBD, 0xD3, 0x17, 0xD2, 0x1E, 0x62, 0xF3, 0xDB, 0xEA, 0x6C, 0x50, + 0x8C, 0x3F, 0x84, 0x0C, 0x96, 0xCF, 0xB7, 0xCB, 0x03, 0xE0, 0xCA, 0x6D, + 0xA1, 0x14, 0x4C, 0x1B, 0x89, 0xDD, 0xED, 0x00, 0xB0, 0x52, 0x7C, 0xAF, + 0x91, 0x6C, 0xB1, 0x38, 0x13, 0xD1, 0xE9, 0x12, 0x08, 0xC0, 0x00, 0xB0, + 0x1C, 0x2B, 0x11, 0xDA, 0x77, 0x70, 0x36, 0x9B, 0xAE, 0xCE, 0x79, 0x87, + 0xDC, 0x82, 0x70, 0xE6, 0x09, 0x74, 0x70, 0x55, 0x69, 0xAF, 0xA3, 0x68, + 0x9F, 0xBF, 0xDD, 0xB6, 0x79, 0xB3, 0xF2, 0x9D, 0x70, 0x29, 0x55, 0xF4, + 0xAB, 0xFF, 0x95, 0x61, 0xF3, 0xC9, 0x40, 0x6F, 0x1D, 0xD1, 0xBE, 0x93, + 0xBB, 0xD3, 0x88, 0x2A, 0xBB, 0x9D, 0xBF, 0x72, 0x5A, 0x56, 0x71, 0x3B, + 0x3F, 0xD4, 0xF3, 0xD1, 0x0A, 0xFE, 0x28, 0xEF, 0xA3, 0xEE, 0xD9, 0x99, + 0xAF, 0x03, 0xD3, 0x8F, 0x60, 0xB7, 0xF2, 0x92, 0xA1, 0xB1, 0xBD, 0x89, + 0x89, 0x1F, 0x30, 0xCD, 0xC3, 0xA6, 0x2E, 0x62, 0x33, 0xAE, 0x16, 0x02, + 0x77, 0x44, 0x5A, 0xE7, 0x81, 0x0A, 0x3C, 0xA7, 0x44, 0x2E, 0x79, 0xB8, + 0x3F, 0x04, 0xBC, 0x5C, 0xA0, 0x87, 0xE1, 0x1B, 0xAF, 0x51, 0x8E, 0xCD, + 0xEC, 0x2C, 0xFA, 0xF8, 0xFE, 0x6D, 0xF0, 0x3A, 0x7C, 0xAA, 0x8B, 0xE4, + 0x67, 0x95, 0x31, 0x8D +}; + +static const unsigned char TA597_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA598_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA598_EC_Q[] = { + 0x04, 0x19, 0xE7, 0xBC, 0xAC, 0x44, 0x65, 0xED, 0xCD, 0xB8, 0x3F, 0x58, + 0xFB, 0x8D, 0xB1, 0x57, 0xA9, 0x44, 0x2D, 0x05, 0x15, 0xF2, 0xEF, 0x0B, + 0xFF, 0x10, 0x74, 0x9F, 0xB5, 0x62, 0x52, 0x5F, 0x66, 0x7E, 0x1F, 0xE5, + 0xDC, 0x1B, 0x45, 0x79, 0x0B, 0xCC, 0xC6, 0x53, 0x0A, 0x9D, 0x8D, 0x5D, + 0x02, 0xD9, 0xA9, 0x59, 0xDE, 0x02, 0x5A, 0xF6, 0x95, 0x2A, 0x0E, 0x8D, + 0x38, 0x4A, 0x8A, 0x49, 0xC6, 0xBC, 0xC6, 0x03, 0x38, 0x07, 0x5F, 0x55, + 0xDA, 0x7E, 0x09, 0x6E, 0xE2, 0x7F, 0x5E, 0xD0, 0x45, 0x20, 0x0F, 0x59, + 0x76, 0x10, 0xD6, 0xA0, 0x24, 0xF0, 0x2D, 0xDE, 0x36, 0xF2, 0x6C, 0x29, + 0x39 +}; + +static const unsigned char TA599_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA599_RSA_N[] = { + 0xE2, 0x3B, 0xE1, 0x11, 0x72, 0xDE, 0xA8, 0xA4, 0xD3, 0xA3, 0x57, 0xAA, + 0x50, 0xA2, 0x8F, 0x0B, 0x77, 0x90, 0xC9, 0xA2, 0xA5, 0xEE, 0x12, 0xCE, + 0x96, 0x5B, 0x01, 0x09, 0x20, 0xCC, 0x01, 0x93, 0xA7, 0x4E, 0x30, 0xB7, + 0x53, 0xF7, 0x43, 0xC4, 0x69, 0x00, 0x57, 0x9D, 0xE2, 0x8D, 0x22, 0xDD, + 0x87, 0x06, 0x40, 0x00, 0x81, 0x09, 0xCE, 0xCE, 0x1B, 0x83, 0xBF, 0xDF, + 0xCD, 0x3B, 0x71, 0x46, 0xE2, 0xD6, 0x66, 0xC7, 0x05, 0xB3, 0x76, 0x27, + 0x16, 0x8F, 0x7B, 0x9E, 0x1E, 0x95, 0x7D, 0xEE, 0xB7, 0x48, 0xA3, 0x08, + 0xDA, 0xD6, 0xAF, 0x7A, 0x0C, 0x39, 0x06, 0x65, 0x7F, 0x4A, 0x5D, 0x1F, + 0xBC, 0x17, 0xF8, 0xAB, 0xBE, 0xEE, 0x28, 0xD7, 0x74, 0x7F, 0x7A, 0x78, + 0x99, 0x59, 0x85, 0x68, 0x6E, 0x5C, 0x23, 0x32, 0x4B, 0xBF, 0x4E, 0xC0, + 0xE8, 0x5A, 0x6D, 0xE3, 0x70, 0xBF, 0x77, 0x10, 0xBF, 0xFC, 0x01, 0xF6, + 0x85, 0xD9, 0xA8, 0x44, 0x10, 0x58, 0x32, 0xA9, 0x75, 0x18, 0xD5, 0xD1, + 0xA2, 0xBE, 0x47, 0xE2, 0x27, 0x6A, 0xF4, 0x9A, 0x33, 0xF8, 0x49, 0x08, + 0x60, 0x8B, 0xD4, 0x5F, 0xB4, 0x3A, 0x84, 0xBF, 0xA1, 0xAA, 0x4A, 0x4C, + 0x7D, 0x3E, 0xCF, 0x4F, 0x5F, 0x6C, 0x76, 0x5E, 0xA0, 0x4B, 0x37, 0x91, + 0x9E, 0xDC, 0x22, 0xE6, 0x6D, 0xCE, 0x14, 0x1A, 0x8E, 0x6A, 0xCB, 0xFE, + 0xCD, 0xB3, 0x14, 0x64, 0x17, 0xC7, 0x5B, 0x29, 0x9E, 0x32, 0xBF, 0xF2, + 0xEE, 0xFA, 0xD3, 0x0B, 0x42, 0xD4, 0xAB, 0xB7, 0x41, 0x32, 0xDA, 0x0C, + 0xD4, 0xEF, 0xF8, 0x81, 0xD5, 0xBB, 0x8D, 0x58, 0x3F, 0xB5, 0x1B, 0xE8, + 0x49, 0x28, 0xA2, 0x70, 0xDA, 0x31, 0x04, 0xDD, 0xF7, 0xB2, 0x16, 0xF2, + 0x4C, 0x0A, 0x4E, 0x07, 0xA8, 0xED, 0x4A, 0x3D, 0x5E, 0xB5, 0x7F, 0xA3, + 0x90, 0xC3, 0xAF, 0x27 +}; + +static const unsigned char TA599_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA600_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x32 +}; + +static const unsigned char TA600_RSA_N[] = { + 0xBB, 0x37, 0xCD, 0x34, 0xDC, 0x7B, 0x6B, 0xC9, 0xB2, 0x68, 0x90, 0xAD, + 0x4A, 0x75, 0xFF, 0x46, 0xBA, 0x21, 0x0A, 0x08, 0x8D, 0xF5, 0x19, 0x54, + 0xC9, 0xFB, 0x88, 0xDB, 0xF3, 0xAE, 0xF2, 0x3A, 0x89, 0x91, 0x3C, 0x7A, + 0xE6, 0xAB, 0x06, 0x1A, 0x6B, 0xCF, 0xAC, 0x2D, 0xE8, 0x5E, 0x09, 0x24, + 0x44, 0xBA, 0x62, 0x9A, 0x7E, 0xD6, 0xA3, 0xA8, 0x7E, 0xE0, 0x54, 0x75, + 0x20, 0x05, 0xAC, 0x50, 0xB7, 0x9C, 0x63, 0x1A, 0x6C, 0x30, 0xDC, 0xDA, + 0x1F, 0x19, 0xB1, 0xD7, 0x1E, 0xDE, 0xFD, 0xD7, 0xE0, 0xCB, 0x94, 0x83, + 0x37, 0xAE, 0xEC, 0x1F, 0x43, 0x4E, 0xDD, 0x7B, 0x2C, 0xD2, 0xBD, 0x2E, + 0xA5, 0x2F, 0xE4, 0xA9, 0xB8, 0xAD, 0x3A, 0xD4, 0x99, 0xA4, 0xB6, 0x25, + 0xE9, 0x9B, 0x6B, 0x00, 0x60, 0x92, 0x60, 0xFF, 0x4F, 0x21, 0x49, 0x18, + 0xF7, 0x67, 0x90, 0xAB, 0x61, 0x06, 0x9C, 0x8F, 0xF2, 0xBA, 0xE9, 0xB4, + 0xE9, 0x92, 0x32, 0x6B, 0xB5, 0xF3, 0x57, 0xE8, 0x5D, 0x1B, 0xCD, 0x8C, + 0x1D, 0xAB, 0x95, 0x04, 0x95, 0x49, 0xF3, 0x35, 0x2D, 0x96, 0xE3, 0x49, + 0x6D, 0xDD, 0x77, 0xE3, 0xFB, 0x49, 0x4B, 0xB4, 0xAC, 0x55, 0x07, 0xA9, + 0x8F, 0x95, 0xB3, 0xB4, 0x23, 0xBB, 0x4C, 0x6D, 0x45, 0xF0, 0xF6, 0xA9, + 0xB2, 0x95, 0x30, 0xB4, 0xFD, 0x4C, 0x55, 0x8C, 0x27, 0x4A, 0x57, 0x14, + 0x7C, 0x82, 0x9D, 0xCD, 0x73, 0x92, 0xD3, 0x16, 0x4A, 0x06, 0x0C, 0x8C, + 0x50, 0xD1, 0x8F, 0x1E, 0x09, 0xBE, 0x17, 0xA1, 0xE6, 0x21, 0xCA, 0xFD, + 0x83, 0xE5, 0x10, 0xBC, 0x83, 0xA5, 0x0A, 0xC4, 0x67, 0x28, 0xF6, 0x73, + 0x14, 0x14, 0x3D, 0x46, 0x76, 0xC3, 0x87, 0x14, 0x89, 0x21, 0x34, 0x4D, + 0xAF, 0x0F, 0x45, 0x0C, 0xA6, 0x49, 0xA1, 0xBA, 0xBB, 0x9C, 0xC5, 0xB1, + 0x33, 0x83, 0x29, 0x85 +}; + +static const unsigned char TA600_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA601_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x33 +}; + +static const unsigned char TA601_EC_Q[] = { + 0x04, 0xDD, 0xA7, 0xD9, 0xBB, 0x8A, 0xB8, 0x0B, 0xFB, 0x0B, 0x7F, 0x21, + 0xD2, 0xF0, 0xBE, 0xBE, 0x73, 0xF3, 0x33, 0x5D, 0x1A, 0xBC, 0x34, 0xEA, + 0xDE, 0xC6, 0x9B, 0xBC, 0xD0, 0x95, 0xF6, 0xF0, 0xCC, 0xD0, 0x0B, 0xBA, + 0x61, 0x5B, 0x51, 0x46, 0x7E, 0x9E, 0x2D, 0x9F, 0xEE, 0x8E, 0x63, 0x0C, + 0x17, 0xEC, 0x07, 0x70, 0xF5, 0xCF, 0x84, 0x2E, 0x40, 0x83, 0x9C, 0xE8, + 0x3F, 0x41, 0x6D, 0x3B, 0xAD, 0xD3, 0xA4, 0x14, 0x59, 0x36, 0x78, 0x9D, + 0x03, 0x43, 0xEE, 0x10, 0x13, 0x6C, 0x72, 0xDE, 0xAE, 0x88, 0xA7, 0xA1, + 0x6B, 0xB5, 0x43, 0xCE, 0x67, 0xDC, 0x23, 0xFF, 0x03, 0x1C, 0xA3, 0xE2, + 0x3E +}; + +static const unsigned char TA602_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, + 0x6E, 0x63, 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA602_RSA_N[] = { + 0xC6, 0xCC, 0xE5, 0x73, 0xE6, 0xFB, 0xD4, 0xBB, 0xE5, 0x2D, 0x2D, 0x32, + 0xA6, 0xDF, 0xE5, 0x81, 0x3F, 0xC9, 0xCD, 0x25, 0x49, 0xB6, 0x71, 0x2A, + 0xC3, 0xD5, 0x94, 0x34, 0x67, 0xA2, 0x0A, 0x1C, 0xB0, 0x5F, 0x69, 0xA6, + 0x40, 0xB1, 0xC4, 0xB7, 0xB2, 0x8F, 0xD0, 0x98, 0xA4, 0xA9, 0x41, 0x59, + 0x3A, 0xD3, 0xDC, 0x94, 0xD6, 0x3C, 0xDB, 0x74, 0x38, 0xA4, 0x4A, 0xCC, + 0x4D, 0x25, 0x82, 0xF7, 0x4A, 0xA5, 0x53, 0x12, 0x38, 0xEE, 0xF3, 0x49, + 0x6D, 0x71, 0x91, 0x7E, 0x63, 0xB6, 0xAB, 0xA6, 0x5F, 0xC3, 0xA4, 0x84, + 0xF8, 0x4F, 0x62, 0x51, 0xBE, 0xF8, 0xC5, 0xEC, 0xDB, 0x38, 0x92, 0xE3, + 0x06, 0xE5, 0x08, 0x91, 0x0C, 0xC4, 0x28, 0x41, 0x55, 0xFB, 0xCB, 0x5A, + 0x89, 0x15, 0x7E, 0x71, 0xE8, 0x35, 0xBF, 0x4D, 0x72, 0x09, 0x3D, 0xBE, + 0x3A, 0x38, 0x50, 0x5B, 0x77, 0x31, 0x1B, 0x8D, 0xB3, 0xC7, 0x24, 0x45, + 0x9A, 0xA7, 0xAC, 0x6D, 0x00, 0x14, 0x5A, 0x04, 0xB7, 0xBA, 0x13, 0xEB, + 0x51, 0x0A, 0x98, 0x41, 0x41, 0x22, 0x4E, 0x65, 0x61, 0x87, 0x81, 0x41, + 0x50, 0xA6, 0x79, 0x5C, 0x89, 0xDE, 0x19, 0x4A, 0x57, 0xD5, 0x2E, 0xE6, + 0x5D, 0x1C, 0x53, 0x2C, 0x7E, 0x98, 0xCD, 0x1A, 0x06, 0x16, 0xA4, 0x68, + 0x73, 0xD0, 0x34, 0x04, 0x13, 0x5C, 0xA1, 0x71, 0xD3, 0x5A, 0x7C, 0x55, + 0xDB, 0x5E, 0x64, 0xE1, 0x37, 0x87, 0x30, 0x56, 0x04, 0xE5, 0x11, 0xB4, + 0x29, 0x80, 0x12, 0xF1, 0x79, 0x39, 0x88, 0xA2, 0x02, 0x11, 0x7C, 0x27, + 0x66, 0xB7, 0x88, 0xB7, 0x78, 0xF2, 0xCA, 0x0A, 0xA8, 0x38, 0xAB, 0x0A, + 0x64, 0xC2, 0xBF, 0x66, 0x5D, 0x95, 0x84, 0xC1, 0xA1, 0x25, 0x1E, 0x87, + 0x5D, 0x1A, 0x50, 0x0B, 0x20, 0x12, 0xCC, 0x41, 0xBB, 0x6E, 0x0B, 0x51, + 0x38, 0xB8, 0x4B, 0xCB +}; + +static const unsigned char TA602_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA603_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1D, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x50, 0x33, 0x38, 0x34, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA603_EC_Q[] = { + 0x04, 0xC1, 0x44, 0xA1, 0xCF, 0x11, 0x97, 0x50, 0x9A, 0xDE, 0x23, 0x82, + 0x35, 0x07, 0xCD, 0xD0, 0xCB, 0x18, 0x9D, 0xD2, 0xF1, 0x7F, 0x77, 0x35, + 0x4F, 0x3B, 0xDD, 0x94, 0x72, 0x52, 0xED, 0xC2, 0x3B, 0xF8, 0xEC, 0xFA, + 0x7B, 0x6B, 0x58, 0x20, 0xEC, 0x99, 0xAE, 0xC9, 0xFC, 0x68, 0xB3, 0x75, + 0xB9, 0xDB, 0x09, 0xEC, 0xC8, 0x13, 0xF5, 0x4E, 0xC6, 0x0A, 0x1D, 0x66, + 0x30, 0x4C, 0xBB, 0x1F, 0x47, 0x0A, 0x3C, 0x61, 0x10, 0x42, 0x29, 0x7C, + 0xA5, 0x08, 0x0E, 0xE0, 0x22, 0xE9, 0xD3, 0x35, 0x68, 0xCE, 0x9B, 0x63, + 0x9F, 0x84, 0xB5, 0x99, 0x4D, 0x58, 0xA0, 0x8E, 0xF5, 0x54, 0xE7, 0x95, + 0xC9 +}; + +static const unsigned char TA604_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x34, 0x30, 0x39, 0x36, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA604_RSA_N[] = { + 0xB3, 0xD0, 0xF4, 0xC9, 0x79, 0x11, 0x9D, 0xFD, 0xFC, 0x66, 0x81, 0xE7, + 0xCC, 0xD5, 0xE4, 0xBC, 0xEC, 0x81, 0x3E, 0x6A, 0x35, 0x8E, 0x2E, 0xB7, + 0xE7, 0xDE, 0xAF, 0xF9, 0x07, 0x4D, 0xCF, 0x30, 0x9D, 0xEA, 0x09, 0x0B, + 0x99, 0xBD, 0x6C, 0x57, 0xDA, 0x18, 0x4A, 0xB8, 0x78, 0xAC, 0x3A, 0x39, + 0xA8, 0xA6, 0x48, 0xAC, 0x2E, 0x72, 0xE5, 0xBD, 0xEB, 0xF1, 0x1A, 0xCD, + 0xE7, 0xA4, 0x03, 0xA9, 0x3F, 0x11, 0xB4, 0xD8, 0x2F, 0x89, 0x16, 0xFB, + 0x94, 0x01, 0x3D, 0xBB, 0x2F, 0xF8, 0x13, 0x05, 0xA1, 0x78, 0x1C, 0x8E, + 0x28, 0xE0, 0x45, 0xE0, 0x83, 0xF4, 0x59, 0x1B, 0x95, 0xB3, 0xAE, 0x7E, + 0x03, 0x45, 0xE5, 0xBE, 0xC2, 0x42, 0xFE, 0xEE, 0xF2, 0x3C, 0xB6, 0x85, + 0x13, 0x98, 0x32, 0x9D, 0x16, 0xA8, 0x29, 0xC2, 0x0B, 0x1C, 0x38, 0xDC, + 0x9F, 0x31, 0x77, 0x5C, 0xBF, 0x27, 0xA3, 0xFC, 0x27, 0xAC, 0xB7, 0x2B, + 0xBD, 0x74, 0x9B, 0x17, 0x2D, 0xF2, 0x81, 0xDA, 0x5D, 0xB0, 0xE1, 0x23, + 0x17, 0x3E, 0x88, 0x4A, 0x12, 0x23, 0xD0, 0xEA, 0xCF, 0x9D, 0xDE, 0x03, + 0x17, 0xB1, 0x42, 0x4A, 0xA0, 0x16, 0x4C, 0xA4, 0x6D, 0x93, 0xE9, 0x3F, + 0x3A, 0xEE, 0x3A, 0x7C, 0x9D, 0x58, 0x9D, 0xF4, 0x4E, 0x8F, 0xFC, 0x3B, + 0x23, 0xC8, 0x6D, 0xB8, 0xE2, 0x05, 0xDA, 0xCC, 0xEB, 0xEC, 0xC3, 0x31, + 0xF4, 0xD7, 0xA7, 0x29, 0x54, 0x80, 0xCF, 0x44, 0x5B, 0x4C, 0x6F, 0x30, + 0x9E, 0xF3, 0xCC, 0xDD, 0x1F, 0x94, 0x43, 0x9D, 0x4D, 0x7F, 0x70, 0x70, + 0x0D, 0xD4, 0x3A, 0xD1, 0x37, 0xF0, 0x6C, 0x9D, 0x9B, 0xC0, 0x14, 0x93, + 0x58, 0xEF, 0xCD, 0x41, 0x38, 0x75, 0xBC, 0x13, 0x03, 0x95, 0x7C, 0x7F, + 0xE3, 0x5C, 0xE9, 0xD5, 0x0D, 0xD5, 0xE2, 0x7C, 0x10, 0x62, 0xAA, 0x6B, + 0xF0, 0x3D, 0x76, 0xF3, 0x3F, 0xA3, 0xE8, 0xB0, 0xC1, 0xFD, 0xEF, 0xAA, + 0x57, 0x4D, 0xAC, 0x86, 0xA7, 0x18, 0xB4, 0x29, 0xC1, 0x2C, 0x0E, 0xBF, + 0x64, 0xBE, 0x29, 0x8C, 0xD8, 0x02, 0x2D, 0xCD, 0x5C, 0x2F, 0xF2, 0x7F, + 0xEF, 0x15, 0xF4, 0x0C, 0x15, 0xAC, 0x0A, 0xB0, 0xF1, 0xD3, 0x0D, 0x4F, + 0x6A, 0x4D, 0x77, 0x97, 0x01, 0xA0, 0xF1, 0x66, 0xB7, 0xB7, 0xCE, 0xEF, + 0xCE, 0xEC, 0xEC, 0xA5, 0x75, 0xCA, 0xAC, 0xE3, 0xE1, 0x63, 0xF7, 0xB8, + 0xA1, 0x04, 0xC8, 0xBC, 0x7B, 0x3F, 0x5D, 0x2D, 0x16, 0x22, 0x56, 0xED, + 0x48, 0x49, 0xFE, 0xA7, 0x2F, 0x79, 0x30, 0x25, 0x9B, 0xBA, 0x6B, 0x2D, + 0x3F, 0x9D, 0x3B, 0xC4, 0x17, 0xE7, 0x1D, 0x2E, 0xFB, 0xF2, 0xCF, 0xA6, + 0xFC, 0xE3, 0x14, 0x2C, 0x96, 0x98, 0x21, 0x8C, 0xB4, 0x91, 0xE9, 0x19, + 0x60, 0x83, 0xF2, 0x30, 0x2B, 0x06, 0x73, 0x50, 0xD5, 0x98, 0x3B, 0x06, + 0xE9, 0xC7, 0x8A, 0x0C, 0x60, 0x8C, 0x28, 0xF8, 0x52, 0x9B, 0x6E, 0xE1, + 0xF6, 0x4D, 0xBB, 0x06, 0x24, 0x9B, 0xD7, 0x2B, 0x26, 0x3F, 0xFD, 0x2A, + 0x2F, 0x71, 0xF5, 0xD6, 0x24, 0xBE, 0x7F, 0x31, 0x9E, 0x0F, 0x6D, 0xE8, + 0x8F, 0x4F, 0x4D, 0xA3, 0x3F, 0xFF, 0x35, 0xEA, 0xDF, 0x49, 0x5E, 0x41, + 0x8F, 0x86, 0xF9, 0xF1, 0x77, 0x79, 0x4B, 0x1B, 0xB4, 0xA3, 0x5E, 0x2F, + 0xFB, 0x46, 0x02, 0xD0, 0x66, 0x13, 0x5E, 0x5E, 0x85, 0x4F, 0xCE, 0xD8, + 0x70, 0x88, 0x7B, 0xCE, 0x01, 0xB5, 0x96, 0x97, 0xD7, 0xCD, 0x7D, 0xFD, + 0x82, 0xF8, 0xC2, 0x24, 0xC1, 0xCA, 0x01, 0x39, 0x4F, 0x8D, 0xA2, 0xC1, + 0x14, 0x40, 0x1F, 0x9C, 0x66, 0xD5, 0x0C, 0x09, 0x46, 0xD6, 0xF2, 0xD0, + 0xD1, 0x48, 0x76, 0x56, 0x3A, 0x43, 0xCB, 0xB6, 0x0A, 0x11, 0x39, 0xBA, + 0x8C, 0x13, 0x6C, 0x06, 0xB5, 0x9E, 0xCF, 0xEB +}; + +static const unsigned char TA604_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA605_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x18, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA605_RSA_N[] = { + 0xBF, 0xE6, 0x90, 0x73, 0x68, 0xDE, 0xBB, 0xE4, 0x5D, 0x4A, 0x3C, 0x30, + 0x22, 0x30, 0x69, 0x33, 0xEC, 0xC2, 0xA7, 0x25, 0x2E, 0xC9, 0x21, 0x3D, + 0xF2, 0x8A, 0xD8, 0x59, 0xC2, 0xE1, 0x29, 0xA7, 0x3D, 0x58, 0xAB, 0x76, + 0x9A, 0xCD, 0xAE, 0x7B, 0x1B, 0x84, 0x0D, 0xC4, 0x30, 0x1F, 0xF3, 0x1B, + 0xA4, 0x38, 0x16, 0xEB, 0x56, 0xC6, 0x97, 0x6D, 0x1D, 0xAB, 0xB2, 0x79, + 0xF2, 0xCA, 0x11, 0xD2, 0xE4, 0x5F, 0xD6, 0x05, 0x3C, 0x52, 0x0F, 0x52, + 0x1F, 0xC6, 0x9E, 0x15, 0xA5, 0x7E, 0xBE, 0x9F, 0xA9, 0x57, 0x16, 0x59, + 0x55, 0x72, 0xAF, 0x68, 0x93, 0x70, 0xC2, 0xB2, 0xBA, 0x75, 0x99, 0x6A, + 0x73, 0x32, 0x94, 0xD1, 0x10, 0x44, 0x10, 0x2E, 0xDF, 0x82, 0xF3, 0x07, + 0x84, 0xE6, 0x74, 0x3B, 0x6D, 0x71, 0xE2, 0x2D, 0x0C, 0x1B, 0xEE, 0x20, + 0xD5, 0xC9, 0x20, 0x1D, 0x63, 0x29, 0x2D, 0xCE, 0xEC, 0x5E, 0x4E, 0xC8, + 0x93, 0xF8, 0x21, 0x61, 0x9B, 0x34, 0xEB, 0x05, 0xC6, 0x5E, 0xEC, 0x5B, + 0x1A, 0xBC, 0xEB, 0xC9, 0xCF, 0xCD, 0xAC, 0x34, 0x40, 0x5F, 0xB1, 0x7A, + 0x66, 0xEE, 0x77, 0xC8, 0x48, 0xA8, 0x66, 0x57, 0x57, 0x9F, 0x54, 0x58, + 0x8E, 0x0C, 0x2B, 0xB7, 0x4F, 0xA7, 0x30, 0xD9, 0x56, 0xEE, 0xCA, 0x7B, + 0x5D, 0xE3, 0xAD, 0xC9, 0x4F, 0x5E, 0xE5, 0x35, 0xE7, 0x31, 0xCB, 0xDA, + 0x93, 0x5E, 0xDC, 0x8E, 0x8F, 0x80, 0xDA, 0xB6, 0x91, 0x98, 0x40, 0x90, + 0x79, 0xC3, 0x78, 0xC7, 0xB6, 0xB1, 0xC4, 0xB5, 0x6A, 0x18, 0x38, 0x03, + 0x10, 0x8D, 0xD8, 0xD4, 0x37, 0xA4, 0x2E, 0x05, 0x7D, 0x88, 0xF5, 0x82, + 0x3E, 0x10, 0x91, 0x70, 0xAB, 0x55, 0x82, 0x41, 0x32, 0xD7, 0xDB, 0x04, + 0x73, 0x2A, 0x6E, 0x91, 0x01, 0x7C, 0x21, 0x4C, 0xD4, 0xBC, 0xAE, 0x1B, + 0x03, 0x75, 0x5D, 0x78, 0x66, 0xD9, 0x3A, 0x31, 0x44, 0x9A, 0x33, 0x40, + 0xBF, 0x08, 0xD7, 0x5A, 0x49, 0xA4, 0xC2, 0xE6, 0xA9, 0xA0, 0x67, 0xDD, + 0xA4, 0x27, 0xBC, 0xA1, 0x4F, 0x39, 0xB5, 0x11, 0x58, 0x17, 0xF7, 0x24, + 0x5C, 0x46, 0x8F, 0x64, 0xF7, 0xC1, 0x69, 0x88, 0x76, 0x98, 0x76, 0x3D, + 0x59, 0x5D, 0x42, 0x76, 0x87, 0x89, 0x97, 0x69, 0x7A, 0x48, 0xF0, 0xE0, + 0xA2, 0x12, 0x1B, 0x66, 0x9A, 0x74, 0xCA, 0xDE, 0x4B, 0x1E, 0xE7, 0x0E, + 0x63, 0xAE, 0xE6, 0xD4, 0xEF, 0x92, 0x92, 0x3A, 0x9E, 0x3D, 0xDC, 0x00, + 0xE4, 0x45, 0x25, 0x89, 0xB6, 0x9A, 0x44, 0x19, 0x2B, 0x7E, 0xC0, 0x94, + 0xB4, 0xD2, 0x61, 0x6D, 0xEB, 0x33, 0xD9, 0xC5, 0xDF, 0x4B, 0x04, 0x00, + 0xCC, 0x7D, 0x1C, 0x95, 0xC3, 0x8F, 0xF7, 0x21, 0xB2, 0xB2, 0x11, 0xB7, + 0xBB, 0x7F, 0xF2, 0xD5, 0x8C, 0x70, 0x2C, 0x41, 0x60, 0xAA, 0xB1, 0x63, + 0x18, 0x44, 0x95, 0x1A, 0x76, 0x62, 0x7E, 0xF6, 0x80, 0xB0, 0xFB, 0xE8, + 0x64, 0xA6, 0x33, 0xD1, 0x89, 0x07, 0xE1, 0xBD, 0xB7, 0xE6, 0x43, 0xA4, + 0x18, 0xB8, 0xA6, 0x77, 0x01, 0xE1, 0x0F, 0x94, 0x0C, 0x21, 0x1D, 0xB2, + 0x54, 0x29, 0x25, 0x89, 0x6C, 0xE5, 0x0E, 0x52, 0x51, 0x47, 0x74, 0xBE, + 0x26, 0xAC, 0xB6, 0x41, 0x75, 0xDE, 0x7A, 0xAC, 0x5F, 0x8D, 0x3F, 0xC9, + 0xBC, 0xD3, 0x41, 0x11, 0x12, 0x5B, 0xE5, 0x10, 0x50, 0xEB, 0x31, 0xC5, + 0xCA, 0x72, 0x16, 0x22, 0x09, 0xDF, 0x7C, 0x4C, 0x75, 0x3F, 0x63, 0xEC, + 0x21, 0x5F, 0xC4, 0x20, 0x51, 0x6B, 0x6F, 0xB1, 0xAB, 0x86, 0x8B, 0x4F, + 0xC2, 0xD6, 0x45, 0x5F, 0x9D, 0x20, 0xFC, 0xA1, 0x1E, 0xC5, 0xC0, 0x8F, + 0xA2, 0xB1, 0x7E, 0x0A, 0x26, 0x99, 0xF5, 0xE4, 0x69, 0x2F, 0x98, 0x1D, + 0x2D, 0xF5, 0xD9, 0xA9, 0xB2, 0x1D, 0xE5, 0x1B +}; + +static const unsigned char TA605_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA606_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA606_EC_Q[] = { + 0x04, 0xC6, 0xCB, 0xC7, 0x28, 0xD1, 0xFB, 0x84, 0xF5, 0x9A, 0xEF, 0x42, + 0x14, 0x20, 0xE1, 0x43, 0x6B, 0x6E, 0x75, 0xAD, 0xFC, 0x2B, 0x03, 0x84, + 0xD4, 0x76, 0x93, 0x25, 0xD7, 0x59, 0x3B, 0x41, 0x65, 0x6B, 0x1E, 0xE6, + 0x34, 0x2A, 0xBB, 0x74, 0xF6, 0x12, 0xCE, 0xE8, 0x6D, 0xE7, 0xAB, 0xE4, + 0x3C, 0x4E, 0x3F, 0x44, 0x08, 0x8B, 0xCD, 0x16, 0x71, 0xCB, 0xBF, 0x92, + 0x99, 0xF4, 0xA4, 0xD7, 0x3C, 0x50, 0x54, 0x52, 0x90, 0x85, 0x83, 0x78, + 0x94, 0x67, 0x67, 0xA3, 0x1C, 0x09, 0x19, 0x3D, 0x75, 0x34, 0x85, 0xDE, + 0xED, 0x60, 0x7D, 0xC7, 0x0C, 0xB4, 0x41, 0x52, 0xB9, 0x6E, 0xE5, 0xEE, + 0x42 +}; + +static const unsigned char TA607_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA607_RSA_N[] = { + 0xAE, 0xFF, 0x09, 0x59, 0x91, 0x80, 0x0A, 0x4A, 0x68, 0xE6, 0x24, 0x3F, + 0xB8, 0xA7, 0xE4, 0xC8, 0x3A, 0x0A, 0x3A, 0x16, 0xCD, 0xC9, 0x23, 0x61, + 0xA0, 0x93, 0x71, 0xF2, 0xAB, 0x8B, 0x73, 0x8F, 0xA0, 0x67, 0x65, 0x60, + 0xD2, 0x54, 0x6B, 0x63, 0x51, 0x6F, 0x49, 0x33, 0xE0, 0x72, 0x07, 0x13, + 0x7D, 0x38, 0xCD, 0x06, 0x92, 0x07, 0x29, 0x52, 0x6B, 0x4E, 0x77, 0x6C, + 0x04, 0xD3, 0x95, 0xFA, 0xDD, 0x4C, 0x8C, 0xD9, 0x5D, 0xC1, 0x61, 0x7D, + 0x4B, 0xE7, 0x28, 0xB3, 0x44, 0x81, 0x7B, 0x51, 0xAF, 0xDD, 0x33, 0xB1, + 0x68, 0x7C, 0xD6, 0x4E, 0x4C, 0xFE, 0x2B, 0x68, 0xB9, 0xCA, 0x66, 0x69, + 0xC4, 0xEC, 0x5E, 0x57, 0x7F, 0xF7, 0x0D, 0xC7, 0x9C, 0x36, 0x36, 0xE5, + 0x07, 0x60, 0xAC, 0xC0, 0x4C, 0xEA, 0x08, 0x6C, 0xEF, 0x06, 0x7C, 0x4F, + 0x5B, 0x28, 0x7A, 0x08, 0xFC, 0x93, 0x5D, 0x9B, 0xF6, 0x9C, 0xB4, 0x8B, + 0x86, 0xBA, 0x21, 0xB9, 0xF4, 0xF0, 0xE8, 0x59, 0x5A, 0x28, 0xA1, 0x34, + 0x84, 0x1A, 0x25, 0x91, 0xB6, 0xB5, 0x8F, 0xEF, 0xB2, 0xF9, 0x80, 0xFA, + 0xF9, 0x3D, 0x3C, 0x11, 0x72, 0xD8, 0xE3, 0x2F, 0x86, 0x76, 0xC5, 0x79, + 0x2C, 0xC1, 0xA9, 0x90, 0x93, 0x46, 0x98, 0x67, 0xCB, 0x83, 0x6A, 0xA0, + 0x50, 0x23, 0xA7, 0x3B, 0xF6, 0x81, 0x39, 0xE0, 0xED, 0xF0, 0xB9, 0xBF, + 0x65, 0xF1, 0xD8, 0xCB, 0x7A, 0xFB, 0xEF, 0x73, 0x03, 0xCE, 0x00, 0xF4, + 0x7D, 0xD7, 0xE0, 0x5D, 0x3B, 0x66, 0xB8, 0xDC, 0x8E, 0xBA, 0x83, 0xCB, + 0x87, 0x76, 0x03, 0xFC, 0x25, 0xD9, 0xE7, 0x23, 0x6F, 0x06, 0xFD, 0x67, + 0xF3, 0xE0, 0xFF, 0x84, 0xBC, 0x47, 0xBF, 0xB5, 0x16, 0x18, 0x46, 0x69, + 0x14, 0xCC, 0x05, 0xF7, 0xDB, 0xD3, 0x49, 0xAC, 0x6B, 0xCC, 0xAB, 0xE4, + 0xB5, 0x0B, 0x43, 0x24, 0x5E, 0x4B, 0x6B, 0x4D, 0x67, 0xDF, 0xD6, 0xB5, + 0x3E, 0x4F, 0x78, 0x1F, 0x94, 0x71, 0x24, 0xEA, 0xDE, 0x70, 0xFC, 0xF1, + 0x93, 0xFE, 0x9E, 0x93, 0x5A, 0xE4, 0x94, 0x5A, 0x97, 0x54, 0x0C, 0x35, + 0x7B, 0x5F, 0x6C, 0xEE, 0x00, 0x1F, 0x24, 0xEC, 0x03, 0xBA, 0x02, 0xF5, + 0x76, 0xF4, 0x9F, 0xD4, 0x9A, 0xED, 0x85, 0x2C, 0x38, 0x22, 0x2F, 0xC7, + 0xD8, 0x2F, 0x76, 0x11, 0x4F, 0xFD, 0x6C, 0x5C, 0xE8, 0xF5, 0x8E, 0x27, + 0x87, 0x7F, 0x19, 0x4A, 0x21, 0x47, 0x90, 0x1D, 0x79, 0x8D, 0x1C, 0x5B, + 0xF8, 0xCF, 0x4A, 0x85, 0xE4, 0xED, 0xB3, 0x5B, 0x8D, 0xBE, 0xC4, 0x64, + 0x28, 0x5D, 0x41, 0xC4, 0x6E, 0xAC, 0x38, 0x5A, 0x4F, 0x23, 0x74, 0x74, + 0xA9, 0x12, 0xC3, 0xF6, 0xD2, 0xB9, 0x11, 0x15, 0x33, 0x07, 0x91, 0xD8, + 0x3B, 0x37, 0x3A, 0x63, 0x30, 0x06, 0xD1, 0xC5, 0x22, 0x36, 0x28, 0x62, + 0x23, 0x10, 0xE0, 0x46, 0xCC, 0x97, 0xAC, 0xD6, 0x2B, 0x5D, 0x64, 0x24, + 0xD5, 0xEE, 0x1C, 0x0E, 0xDE, 0xFB, 0x08, 0x5A, 0x75, 0x2A, 0xF6, 0x63, + 0x6D, 0xCE, 0x0B, 0x42, 0xBE, 0xD1, 0xBA, 0x70, 0x1C, 0x9C, 0x21, 0xE5, + 0x0F, 0x31, 0x69, 0x17, 0xD7, 0xFC, 0x0A, 0xB4, 0xDE, 0xED, 0x80, 0x9C, + 0xCB, 0x92, 0xB4, 0x8B, 0xF5, 0xDE, 0x59, 0xA2, 0x58, 0x09, 0xA5, 0x63, + 0x47, 0x0B, 0xE1, 0x41, 0x32, 0x34, 0x41, 0xD9, 0x9A, 0xB1, 0xD9, 0xA8, + 0xB0, 0x1B, 0x5A, 0xDE, 0x0D, 0x0D, 0xF4, 0xE2, 0xB2, 0x5D, 0x35, 0x80, + 0xB9, 0x81, 0xD4, 0x84, 0x69, 0x91, 0x02, 0xCB, 0x75, 0xD0, 0x8D, 0xC5, + 0xB5, 0x3D, 0x09, 0x91, 0x09, 0x8F, 0x14, 0xA1, 0x14, 0x74, 0x79, 0x3E, + 0xD6, 0xC9, 0x15, 0x1D, 0xA4, 0x59, 0x59, 0x22, 0xDC, 0xF6, 0x8A, 0x45, + 0x3D, 0x3C, 0x12, 0xD6, 0x3E, 0x5D, 0x32, 0x2F +}; + +static const unsigned char TA607_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA608_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA608_EC_Q[] = { + 0x04, 0xF1, 0x0B, 0xDD, 0x86, 0x43, 0x20, 0x19, 0xDF, 0x97, 0x85, 0xE8, + 0x22, 0x4A, 0x9B, 0xCF, 0x9D, 0x98, 0xBF, 0xB4, 0x05, 0x26, 0xC9, 0xCB, + 0xE3, 0xA6, 0xD2, 0x8F, 0xC5, 0x9E, 0x78, 0x7B, 0x31, 0x89, 0xA9, 0x89, + 0xAD, 0x27, 0x3C, 0x65, 0x10, 0x82, 0xFC, 0xDF, 0xC3, 0x9D, 0x4E, 0xF0, + 0x33, 0x23, 0xC4, 0xD2, 0x32, 0xF5, 0x1C, 0xB0, 0xDF, 0x33, 0x17, 0x5D, + 0xC5, 0xF0, 0xB1, 0x8A, 0xF9, 0xEF, 0xB9, 0xB7, 0x14, 0xCA, 0x29, 0x4A, + 0xC2, 0x0F, 0xA9, 0x7F, 0x75, 0x65, 0x49, 0x2A, 0x30, 0x67, 0xF4, 0x64, + 0xF7, 0xD6, 0x1A, 0x77, 0xDA, 0xC3, 0xC2, 0x97, 0x61, 0x42, 0x7B, 0x49, + 0xAD +}; + +static const unsigned char TA609_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA609_RSA_N[] = { + 0xD8, 0x8E, 0xA3, 0x89, 0x80, 0x0B, 0xB2, 0x57, 0x52, 0xDC, 0xA9, 0x53, + 0x4C, 0x37, 0xB9, 0x7F, 0x63, 0x17, 0x13, 0xEF, 0xA7, 0x5B, 0x23, 0x5B, + 0x69, 0x75, 0xB0, 0x99, 0x0A, 0x17, 0xC1, 0x8B, 0xC4, 0xDB, 0xA8, 0xE0, + 0xCC, 0x31, 0xBA, 0xC2, 0xF2, 0xCD, 0x5D, 0xE9, 0xB7, 0xF8, 0x1D, 0xAF, + 0x6A, 0xC4, 0x95, 0x87, 0xD7, 0x47, 0xC9, 0x95, 0xD8, 0x82, 0x04, 0x50, + 0x3D, 0x81, 0x08, 0xFF, 0xE4, 0x3D, 0xB3, 0xB1, 0xD6, 0xC5, 0xB2, 0xFD, + 0x88, 0x09, 0xDB, 0x9C, 0x84, 0xEC, 0x25, 0x17, 0x14, 0x87, 0x7F, 0x30, + 0x78, 0x9B, 0x6A, 0x58, 0xC9, 0xB6, 0x73, 0x28, 0x3C, 0x34, 0xF7, 0x99, + 0xF7, 0x7F, 0xD3, 0xA6, 0xF8, 0x1C, 0x45, 0x7C, 0xAD, 0x2C, 0x8C, 0x94, + 0x3F, 0xD8, 0x67, 0x10, 0x53, 0x7E, 0x22, 0xCD, 0x4E, 0x25, 0x51, 0xF0, + 0x25, 0x24, 0x35, 0x11, 0x5E, 0x10, 0xC6, 0xEC, 0x87, 0x66, 0x89, 0x81, + 0x68, 0xBA, 0xCC, 0x2B, 0x9D, 0x47, 0x73, 0x1F, 0xBD, 0xCD, 0x91, 0xA4, + 0x72, 0x6A, 0x9C, 0xA2, 0x1B, 0x18, 0xA0, 0x6F, 0xEC, 0x50, 0xF4, 0x7D, + 0x40, 0xC2, 0xA8, 0x30, 0xCF, 0xBD, 0x73, 0xC8, 0x13, 0x2B, 0x10, 0x13, + 0x1E, 0x8B, 0x9A, 0xA8, 0x3A, 0x94, 0x73, 0xD3, 0x18, 0x69, 0x0A, 0x4A, + 0xFF, 0xC1, 0x01, 0x03, 0xFF, 0x79, 0x7F, 0xB5, 0x48, 0x7F, 0x7B, 0xEE, + 0xE8, 0x29, 0x6F, 0x36, 0x4C, 0x95, 0x61, 0x86, 0xD8, 0xF9, 0xA2, 0x73, + 0x8A, 0xEE, 0xAE, 0x2F, 0x96, 0xEE, 0x68, 0xCD, 0x3D, 0x4D, 0x28, 0x42, + 0xF9, 0x45, 0x2B, 0x32, 0x1B, 0x46, 0x55, 0x16, 0x6A, 0xA6, 0x4B, 0x29, + 0xF9, 0xBB, 0x95, 0x56, 0xBF, 0x46, 0x1D, 0xEC, 0x1D, 0x93, 0x1D, 0xC0, + 0x65, 0xB2, 0x1F, 0xA1, 0x43, 0xAE, 0x56, 0x9E, 0xA0, 0xB1, 0x8F, 0x6B, + 0x12, 0xB7, 0x60, 0x6D, 0x78, 0x0B, 0xCA, 0x8A, 0x5C, 0xED, 0x1E, 0x96, + 0x0E, 0x83, 0xA6, 0x48, 0x95, 0x8D, 0x3B, 0xA3, 0x21, 0xC4, 0xAE, 0x58, + 0xC6, 0x00, 0xB2, 0x84, 0xB4, 0x23, 0xA4, 0x96, 0x86, 0x35, 0xB8, 0xD8, + 0x9E, 0xD8, 0xAC, 0x34, 0x49, 0x98, 0x63, 0x95, 0xC5, 0xCB, 0x6D, 0x48, + 0x47, 0xE2, 0xF2, 0x2E, 0x18, 0x1E, 0xD0, 0x31, 0xAB, 0xDD, 0x74, 0xEC, + 0xF9, 0xDC, 0x8C, 0xB8, 0x1C, 0x8E, 0x68, 0x23, 0xBA, 0xD0, 0xF3, 0x50, + 0xDC, 0xCF, 0x65, 0x8F, 0x73, 0x3A, 0x32, 0xC7, 0x7C, 0xFE, 0xCA, 0x82, + 0x22, 0x4F, 0xBE, 0x8E, 0x62, 0x47, 0x66, 0xE5, 0xCD, 0x87, 0xE2, 0xE8, + 0xD5, 0x0F, 0x18, 0x9F, 0xE5, 0x04, 0x72, 0x4B, 0x46, 0x3C, 0x10, 0xF2, + 0x44, 0xC2, 0x64, 0x56, 0x71, 0x4E, 0x75, 0xE8, 0x9C, 0xC9, 0x26, 0x74, + 0xC5, 0x7D, 0x59, 0xD1, 0x0A, 0x5B, 0x0F, 0x6D, 0xFE, 0x9E, 0x75, 0x1C, + 0x18, 0xC6, 0x1A, 0x3A, 0x7C, 0xD8, 0x0D, 0x04, 0xCC, 0xCD, 0xB7, 0x45, + 0x65, 0x7A, 0xB1, 0x8F, 0xB8, 0xAE, 0x84, 0x48, 0x3E, 0xB3, 0x7A, 0x4D, + 0xA8, 0x03, 0xE2, 0xE2, 0x7E, 0x01, 0x16, 0x59, 0x68, 0x18, 0x43, 0x33, + 0xB0, 0xD2, 0xDC, 0xB0, 0x1A, 0x43, 0x35, 0xEE, 0xA5, 0xDA, 0xA9, 0x46, + 0x5C, 0xAE, 0x86, 0x81, 0x41, 0x01, 0x4A, 0x74, 0x26, 0xEC, 0x9F, 0x06, + 0xBF, 0xC2, 0x05, 0x37, 0x64, 0x75, 0x78, 0x29, 0x68, 0xFD, 0xC5, 0xF5, + 0xEB, 0xFE, 0x47, 0xF9, 0xE4, 0x85, 0xB0, 0xE1, 0x7B, 0x31, 0x9D, 0xA6, + 0x7F, 0x72, 0xA3, 0xB9, 0xC4, 0x2C, 0x2E, 0xCC, 0x99, 0x57, 0x0E, 0x21, + 0x0C, 0x45, 0x01, 0x94, 0x65, 0xEB, 0x65, 0x09, 0xC6, 0x63, 0x22, 0x0B, + 0x33, 0x49, 0x92, 0x48, 0x3C, 0xFC, 0xCD, 0xCE, 0xB0, 0x3E, 0x8E, 0x9E, + 0x8B, 0xF8, 0xFE, 0x49, 0xC5, 0x35, 0x72, 0x47 +}; + +static const unsigned char TA609_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA610_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x1E, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA610_RSA_N[] = { + 0xD3, 0xB2, 0x4A, 0xCF, 0x7A, 0x47, 0xEF, 0x75, 0x9B, 0x23, 0xFA, 0x3A, + 0x2F, 0xD6, 0x50, 0x45, 0x89, 0x35, 0x3A, 0xC6, 0x6B, 0xDB, 0xFE, 0xDB, + 0x00, 0x68, 0xA8, 0xE0, 0x03, 0x11, 0x1D, 0x37, 0x50, 0x08, 0x9F, 0x4D, + 0x4A, 0x68, 0x94, 0x35, 0xB3, 0x53, 0xD1, 0x94, 0x63, 0xA7, 0x20, 0x56, + 0xAF, 0xDE, 0x51, 0x78, 0xEC, 0x2A, 0x3D, 0xF3, 0x48, 0x48, 0x50, 0x3E, + 0x0A, 0xDF, 0x46, 0x55, 0x8B, 0x27, 0x6D, 0xC3, 0x10, 0x4D, 0x0D, 0x91, + 0x52, 0x43, 0xD8, 0x87, 0xE0, 0x5D, 0x4E, 0x36, 0xB5, 0x21, 0xCA, 0x5F, + 0x39, 0x40, 0x04, 0x5F, 0x5B, 0x7E, 0xCC, 0xA3, 0xC6, 0x2B, 0xA9, 0x40, + 0x1E, 0xD9, 0x36, 0x84, 0xD6, 0x48, 0xF3, 0x92, 0x1E, 0x34, 0x46, 0x20, + 0x24, 0xC1, 0xA4, 0x51, 0x8E, 0x4A, 0x1A, 0xEF, 0x50, 0x3F, 0x69, 0x5D, + 0x19, 0x7F, 0x45, 0xC3, 0xC7, 0x01, 0x8F, 0x51, 0xC9, 0x23, 0xE8, 0x72, + 0xAE, 0xB4, 0xBC, 0x56, 0x09, 0x7F, 0x12, 0xCB, 0x1C, 0xB1, 0xAF, 0x29, + 0x90, 0x0A, 0xC9, 0x55, 0xCC, 0x0F, 0xD3, 0xB4, 0x1A, 0xED, 0x47, 0x35, + 0x5A, 0x4A, 0xED, 0x9C, 0x73, 0x04, 0x21, 0xD0, 0xAA, 0xBD, 0x0C, 0x13, + 0xB5, 0x00, 0xCA, 0x26, 0x6C, 0xC4, 0x6B, 0x0C, 0x94, 0x5A, 0x95, 0x94, + 0xDA, 0x50, 0x9A, 0xF1, 0xFF, 0xA5, 0x2B, 0x66, 0x31, 0xA4, 0xC9, 0x38, + 0xA0, 0xDF, 0x1D, 0x1F, 0xB8, 0x09, 0x2E, 0xF3, 0xA7, 0xE8, 0x67, 0x52, + 0xAB, 0x95, 0x1F, 0xE0, 0x46, 0x3E, 0xD8, 0xA4, 0xC3, 0xCA, 0x5A, 0xC5, + 0x31, 0x80, 0xE8, 0x48, 0x9A, 0x9F, 0x94, 0x69, 0xFE, 0x19, 0xDD, 0xD8, + 0x73, 0x7C, 0x81, 0xCA, 0x96, 0xDE, 0x8E, 0xED, 0xB3, 0x32, 0x05, 0x65, + 0x84, 0x34, 0xE6, 0xE6, 0xFD, 0x57, 0x10, 0xB5, 0x5F, 0x76, 0xBF, 0x2F, + 0xB0, 0x10, 0x0D, 0xC5 +}; + +static const unsigned char TA610_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA611_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x21, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x45, 0x56, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA611_RSA_N[] = { + 0x99, 0xF1, 0x84, 0x34, 0x70, 0xBA, 0x2F, 0xB7, 0x30, 0xA0, 0x8E, 0xBD, + 0x7C, 0x04, 0xCF, 0xBE, 0x62, 0xBC, 0x99, 0xFD, 0x82, 0x97, 0xD2, 0x7A, + 0x0A, 0x67, 0x96, 0x38, 0x09, 0xF6, 0x10, 0x4E, 0x95, 0x22, 0x73, 0x99, + 0x8D, 0xDA, 0x15, 0x2D, 0xE7, 0x05, 0xFC, 0x19, 0x73, 0x22, 0xB7, 0x8E, + 0x98, 0x00, 0xBC, 0x3C, 0x3D, 0xAC, 0xA1, 0x6C, 0xFB, 0xD6, 0x79, 0x25, + 0x4B, 0xAD, 0xF0, 0xCC, 0x64, 0xDA, 0x88, 0x3E, 0x29, 0xB8, 0x0F, 0x09, + 0xD3, 0x34, 0xDD, 0x33, 0xF5, 0x62, 0xD1, 0xE1, 0xCD, 0x19, 0xE9, 0xEE, + 0x18, 0x4F, 0x4C, 0x58, 0xAE, 0xE2, 0x1E, 0xD6, 0x0C, 0x5B, 0x15, 0x5A, + 0xD8, 0x3A, 0xB8, 0xC4, 0x18, 0x64, 0x1E, 0xE3, 0x33, 0xB2, 0xB5, 0x89, + 0x77, 0x4E, 0x0C, 0xBF, 0xD9, 0x94, 0x6B, 0x13, 0x97, 0x6F, 0x12, 0xA3, + 0xFE, 0x99, 0xA9, 0x04, 0xCC, 0x15, 0xEC, 0x60, 0x68, 0x36, 0xED, 0x08, + 0x7B, 0xB7, 0xF5, 0xBF, 0x93, 0xED, 0x66, 0x31, 0x83, 0x8C, 0xC6, 0x71, + 0x34, 0x87, 0x4E, 0x17, 0xEA, 0xAF, 0x8B, 0x91, 0x8D, 0x1C, 0x56, 0x41, + 0xAE, 0x22, 0x37, 0x5E, 0x37, 0xF2, 0x1D, 0xD9, 0xD1, 0x2D, 0x0D, 0x2F, + 0x69, 0x51, 0xA7, 0xBE, 0x66, 0xA6, 0x8A, 0x3A, 0x2A, 0xBD, 0xC7, 0x1A, + 0xB1, 0xE1, 0x14, 0xF0, 0xBE, 0x3A, 0x1D, 0xB9, 0xCF, 0x5B, 0xB1, 0x6A, + 0xFE, 0xB4, 0xB1, 0x46, 0x20, 0xA2, 0xFB, 0x1E, 0x3B, 0x70, 0xEF, 0x93, + 0x98, 0x7D, 0x8C, 0x73, 0x96, 0xF2, 0xC5, 0xEF, 0x85, 0x70, 0xAD, 0x29, + 0x26, 0xFC, 0x1E, 0x04, 0x3E, 0x1C, 0xA0, 0xD8, 0x0F, 0xCB, 0x52, 0x83, + 0x62, 0x7C, 0xEE, 0x8B, 0x53, 0x95, 0x90, 0xA9, 0x57, 0xA2, 0xEA, 0x61, + 0x05, 0xD8, 0xF9, 0x4D, 0xC4, 0x27, 0xFA, 0x6E, 0xAD, 0xED, 0xF9, 0xD7, + 0x51, 0xF7, 0x6B, 0xA5 +}; + +static const unsigned char TA611_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA612_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, + 0x36 +}; + +static const unsigned char TA612_RSA_N[] = { + 0x93, 0xBE, 0xD5, 0x36, 0x52, 0x75, 0xD8, 0x01, 0x23, 0xA0, 0x1C, 0x47, + 0x42, 0x49, 0xEE, 0x63, 0xB6, 0xB7, 0x21, 0xFD, 0xC4, 0x95, 0xD5, 0x48, + 0x2B, 0x26, 0x7C, 0x14, 0x53, 0x10, 0xDA, 0x79, 0xFD, 0x2B, 0xB7, 0x2D, + 0xA4, 0xD4, 0x2C, 0xFA, 0xEA, 0x32, 0xDD, 0x49, 0xC2, 0xB9, 0xBD, 0x0F, + 0x48, 0x3D, 0x7B, 0x5A, 0x98, 0x54, 0xAF, 0x9E, 0x5D, 0x31, 0x74, 0x4F, + 0x07, 0xFC, 0x50, 0x21, 0xDD, 0xA4, 0xCF, 0x68, 0x4F, 0x1B, 0x12, 0x63, + 0x6D, 0x25, 0x99, 0x4C, 0x2A, 0x99, 0xF3, 0x48, 0x30, 0x61, 0xFA, 0x81, + 0x7C, 0x1E, 0xA7, 0x08, 0x4A, 0xDC, 0x3E, 0x2B, 0x1C, 0x1F, 0x18, 0x4C, + 0x71, 0xAA, 0x35, 0x8C, 0xAD, 0xF8, 0x6E, 0xE8, 0x3B, 0x4A, 0xD9, 0xE5, + 0x94, 0x02, 0xD6, 0x89, 0x84, 0x13, 0xAA, 0x6D, 0xC8, 0x4F, 0x33, 0xCC, + 0x50, 0x96, 0x37, 0x92, 0x33, 0xDC, 0x5F, 0x88, 0xE7, 0x9F, 0x54, 0xD9, + 0x48, 0xF0, 0x98, 0x43, 0xD6, 0x66, 0xFD, 0x9F, 0x17, 0x38, 0x43, 0xC5, + 0x01, 0x51, 0x0B, 0xD7, 0xE3, 0x23, 0x0F, 0x14, 0x5D, 0x5B, 0x14, 0xE7, + 0x4B, 0xBE, 0xDD, 0xF4, 0xC8, 0xDA, 0x03, 0x37, 0xD1, 0xD6, 0x39, 0xA1, + 0x21, 0x51, 0x30, 0x83, 0xB0, 0x6D, 0xD7, 0x30, 0x4E, 0x96, 0x5B, 0x91, + 0xF0, 0x70, 0x24, 0xAB, 0xBF, 0x45, 0x81, 0x64, 0x43, 0x0D, 0xBD, 0x21, + 0x3A, 0x2F, 0x3C, 0xE9, 0x9E, 0x0D, 0xCB, 0x20, 0xB5, 0x42, 0x27, 0xCC, + 0xDA, 0x6F, 0x9B, 0xEE, 0x64, 0x30, 0x90, 0x39, 0xCD, 0x93, 0x65, 0x81, + 0x21, 0x31, 0xB5, 0x23, 0x50, 0x33, 0x37, 0x22, 0xE3, 0x38, 0xED, 0xF8, + 0x31, 0x30, 0xCC, 0x45, 0xFE, 0x62, 0xF9, 0xD1, 0x5D, 0x32, 0x79, 0x42, + 0x87, 0xDF, 0x6A, 0xCC, 0x56, 0x19, 0x40, 0x4D, 0xCE, 0xAA, 0xBB, 0xF9, + 0xB5, 0x76, 0x49, 0x94, 0xF1, 0x27, 0xF8, 0x91, 0xA5, 0x83, 0xE5, 0x06, + 0xB3, 0x63, 0x0E, 0x80, 0xDC, 0xE0, 0x12, 0x55, 0x80, 0xA6, 0x3B, 0x66, + 0xB4, 0x39, 0x87, 0x2D, 0xC8, 0xF0, 0xD0, 0xD1, 0x14, 0xE9, 0xE4, 0x0D, + 0x4D, 0x0E, 0xF6, 0x5D, 0x57, 0x72, 0xC5, 0x3B, 0x1C, 0x47, 0x56, 0x9D, + 0xE2, 0xD5, 0xFB, 0x81, 0x61, 0x8C, 0xCC, 0x4D, 0x80, 0x90, 0x34, 0x5B, + 0xB7, 0xD7, 0x14, 0x75, 0xDC, 0xD8, 0x04, 0x48, 0x9F, 0xC0, 0xC1, 0x28, + 0x88, 0xB4, 0xE9, 0x1C, 0xCA, 0xA7, 0xB1, 0xF1, 0x56, 0xB7, 0x7B, 0x49, + 0x4C, 0x59, 0xE5, 0x20, 0x15, 0xA8, 0x84, 0x02, 0x29, 0xFA, 0x38, 0x94, + 0x69, 0x9A, 0x49, 0x06, 0x8F, 0xCD, 0x1F, 0x79, 0x14, 0x17, 0x12, 0x0C, + 0x83, 0x7A, 0xDE, 0x1F, 0xB1, 0x97, 0xEE, 0xF9, 0x97, 0x78, 0x28, 0xA4, + 0xC8, 0x44, 0x92, 0xE9, 0x7D, 0x26, 0x05, 0xA6, 0x58, 0x72, 0x9B, 0x79, + 0x13, 0xD8, 0x11, 0x5F, 0xAE, 0xC5, 0x38, 0x62, 0x34, 0x68, 0xB2, 0x86, + 0x30, 0x8E, 0xF8, 0x90, 0x61, 0x9E, 0x32, 0x6C, 0xF5, 0x07, 0x36, 0xCD, + 0xA2, 0x4C, 0x6E, 0xEC, 0x8A, 0x36, 0xED, 0xF2, 0xE6, 0x99, 0x15, 0x44, + 0x70, 0xC3, 0x7C, 0xBC, 0x9C, 0x39, 0xC0, 0xB4, 0xE1, 0x6B, 0xF7, 0x83, + 0x25, 0x23, 0x57, 0xD9, 0x12, 0x80, 0xE5, 0x49, 0xF0, 0x75, 0x0F, 0xEF, + 0x8D, 0xEB, 0x1C, 0x9B, 0x54, 0x28, 0xB4, 0x21, 0x3C, 0xFC, 0x7C, 0x0A, + 0xFF, 0xEF, 0x7B, 0x6B, 0x75, 0xFF, 0x8B, 0x1D, 0xA0, 0x19, 0x05, 0xAB, + 0xFA, 0xF8, 0x2B, 0x81, 0x42, 0xE8, 0x38, 0xBA, 0xBB, 0xFB, 0xAA, 0xFD, + 0x3D, 0xE0, 0xF3, 0xCA, 0xDF, 0x4E, 0x97, 0x97, 0x29, 0xED, 0xF3, 0x18, + 0x56, 0xE9, 0xA5, 0x96, 0xAC, 0xBD, 0xC3, 0x90, 0x98, 0xB2, 0xE0, 0xF9, + 0xA2, 0xD4, 0xA6, 0x47, 0x43, 0x7C, 0x6D, 0xCF +}; + +static const unsigned char TA612_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA613_DN[] = { + 0x30, 0x34, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x08, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61 +}; + +static const unsigned char TA613_RSA_N[] = { + 0xC8, 0x68, 0xF1, 0xC9, 0xD6, 0xD6, 0xB3, 0x34, 0x75, 0x26, 0x82, 0x1E, + 0xEC, 0xB4, 0xBE, 0xEA, 0x5C, 0xE1, 0x26, 0xED, 0x11, 0x47, 0x61, 0xE1, + 0xA2, 0x7C, 0x16, 0x78, 0x40, 0x21, 0xE4, 0x60, 0x9E, 0x5A, 0xC8, 0x63, + 0xE1, 0xC4, 0xB1, 0x96, 0x92, 0xFF, 0x18, 0x6D, 0x69, 0x23, 0xE1, 0x2B, + 0x62, 0xF7, 0xDD, 0xE2, 0x36, 0x2F, 0x91, 0x07, 0xB9, 0x48, 0xCF, 0x0E, + 0xEC, 0x79, 0xB6, 0x2C, 0xE7, 0x34, 0x4B, 0x70, 0x08, 0x25, 0xA3, 0x3C, + 0x87, 0x1B, 0x19, 0xF2, 0x81, 0x07, 0x0F, 0x38, 0x90, 0x19, 0xD3, 0x11, + 0xFE, 0x86, 0xB4, 0xF2, 0xD1, 0x5E, 0x1E, 0x1E, 0x96, 0xCD, 0x80, 0x6C, + 0xCE, 0x3B, 0x31, 0x93, 0xB6, 0xF2, 0xA0, 0xD0, 0xA9, 0x95, 0x12, 0x7D, + 0xA5, 0x9A, 0xCC, 0x6B, 0xC8, 0x84, 0x56, 0x8A, 0x33, 0xA9, 0xE7, 0x22, + 0x15, 0x53, 0x16, 0xF0, 0xCC, 0x17, 0xEC, 0x57, 0x5F, 0xE9, 0xA2, 0x0A, + 0x98, 0x09, 0xDE, 0xE3, 0x5F, 0x9C, 0x6F, 0xDC, 0x48, 0xE3, 0x85, 0x0B, + 0x15, 0x5A, 0xA6, 0xBA, 0x9F, 0xAC, 0x48, 0xE3, 0x09, 0xB2, 0xF7, 0xF4, + 0x32, 0xDE, 0x5E, 0x34, 0xBE, 0x1C, 0x78, 0x5D, 0x42, 0x5B, 0xCE, 0x0E, + 0x22, 0x8F, 0x4D, 0x90, 0xD7, 0x7D, 0x32, 0x18, 0xB3, 0x0B, 0x2C, 0x6A, + 0xBF, 0x8E, 0x3F, 0x14, 0x11, 0x89, 0x20, 0x0E, 0x77, 0x14, 0xB5, 0x3D, + 0x94, 0x08, 0x87, 0xF7, 0x25, 0x1E, 0xD5, 0xB2, 0x60, 0x00, 0xEC, 0x6F, + 0x2A, 0x28, 0x25, 0x6E, 0x2A, 0x3E, 0x18, 0x63, 0x17, 0x25, 0x3F, 0x3E, + 0x44, 0x20, 0x16, 0xF6, 0x26, 0xC8, 0x25, 0xAE, 0x05, 0x4A, 0xB4, 0xE7, + 0x63, 0x2C, 0xF3, 0x8C, 0x16, 0x53, 0x7E, 0x5C, 0xFB, 0x11, 0x1A, 0x08, + 0xC1, 0x46, 0x62, 0x9F, 0x22, 0xB8, 0xF1, 0xC2, 0x8D, 0x69, 0xDC, 0xFA, + 0x3A, 0x58, 0x06, 0xDF +}; + +static const unsigned char TA613_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA614_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x4E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4E, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x65, 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x71, 0x75, 0x65, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, + 0x75, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA614_RSA_N[] = { + 0xC3, 0xCD, 0xD3, 0xFC, 0xBD, 0x04, 0x53, 0xDD, 0x0C, 0x20, 0x3A, 0xD5, + 0x88, 0x2E, 0x05, 0x4B, 0x41, 0xF5, 0x83, 0x82, 0x7E, 0xF7, 0x59, 0x9F, + 0x9E, 0x9E, 0x63, 0xE8, 0x73, 0xDA, 0xF6, 0x06, 0xA9, 0x4F, 0x1F, 0xB4, + 0xF9, 0x0B, 0x1F, 0x39, 0x8C, 0x9A, 0x20, 0xD0, 0x7E, 0x06, 0xD4, 0xEC, + 0x34, 0xD9, 0x86, 0xBC, 0x75, 0x5B, 0x87, 0x88, 0xF0, 0xD2, 0xD9, 0xD4, + 0xA3, 0x0A, 0xB2, 0x6C, 0x1B, 0xEB, 0x49, 0x2C, 0x3E, 0xAC, 0x5D, 0xD8, + 0x94, 0x03, 0xA0, 0xEC, 0x34, 0xE5, 0x30, 0xC4, 0x35, 0x7D, 0xFB, 0x26, + 0x4D, 0x1B, 0x6E, 0x30, 0x54, 0xD8, 0xF5, 0x80, 0x45, 0x9C, 0x39, 0xAD, + 0x9C, 0xC9, 0x25, 0x04, 0x4D, 0x9A, 0x90, 0x3E, 0x4E, 0x40, 0x6E, 0x8A, + 0x6B, 0xCD, 0x29, 0x67, 0xC6, 0xCC, 0x2D, 0xE0, 0x74, 0xE8, 0x05, 0x57, + 0x0A, 0x48, 0x50, 0xFA, 0x7A, 0x43, 0xDA, 0x7E, 0xEC, 0x5B, 0x9A, 0x0E, + 0x62, 0x76, 0xFE, 0xEA, 0x9D, 0x1D, 0x85, 0x72, 0xEC, 0x11, 0xBB, 0x35, + 0xE8, 0x1F, 0x27, 0xBF, 0xC1, 0xA1, 0xC7, 0xBB, 0x48, 0x16, 0xDD, 0x56, + 0xD7, 0xCC, 0x4E, 0xA0, 0xE1, 0xB9, 0xAC, 0xDB, 0xD5, 0x83, 0x19, 0x1A, + 0x85, 0xD1, 0x94, 0x97, 0xD7, 0xCA, 0xA3, 0x65, 0x0B, 0xF3, 0x38, 0xF9, + 0x02, 0xAE, 0xDD, 0xF6, 0x67, 0xCF, 0xC9, 0x3F, 0xF5, 0x8A, 0x2C, 0x47, + 0x1A, 0x99, 0x6F, 0x05, 0x0D, 0xFD, 0xD0, 0x1D, 0x82, 0x31, 0xFC, 0x29, + 0xCC, 0x00, 0x58, 0x97, 0x91, 0x4C, 0x80, 0x00, 0x1C, 0x33, 0x85, 0x96, + 0x2F, 0xCB, 0x41, 0xC2, 0x8B, 0x10, 0x84, 0xC3, 0x09, 0x24, 0x89, 0x1F, + 0xB5, 0x0F, 0xD9, 0xD9, 0x77, 0x47, 0x18, 0x92, 0x94, 0x60, 0x5C, 0xC7, + 0x99, 0x03, 0x3C, 0xFE, 0xF7, 0x95, 0xA7, 0x7D, 0x50, 0xA1, 0x80, 0xC2, + 0xA9, 0x83, 0xAD, 0x58, 0x96, 0x55, 0x21, 0xDB, 0x86, 0x59, 0xD4, 0xAF, + 0xC6, 0xBC, 0xDD, 0x81, 0x6E, 0x07, 0xDB, 0x60, 0x62, 0xFE, 0xEC, 0x10, + 0x6E, 0xDA, 0x68, 0x01, 0xF4, 0x83, 0x1B, 0xA9, 0x3E, 0xA2, 0x5B, 0x23, + 0xD7, 0x64, 0xC6, 0xDF, 0xDC, 0xA2, 0x7D, 0xD8, 0x4B, 0xBA, 0x82, 0xD2, + 0x51, 0xF8, 0x66, 0xBF, 0x06, 0x46, 0xE4, 0x79, 0x2A, 0x26, 0x36, 0x79, + 0x8F, 0x1F, 0x4E, 0x99, 0x1D, 0xB2, 0x8F, 0x0C, 0x0E, 0x1C, 0xFF, 0xC9, + 0x5D, 0xC0, 0xFD, 0x90, 0x10, 0xA6, 0xB1, 0x37, 0xF3, 0xCD, 0x3A, 0x24, + 0x6E, 0xB4, 0x85, 0x90, 0xBF, 0x80, 0xB9, 0x0C, 0x8C, 0xD5, 0x9B, 0xD6, + 0xC8, 0xF1, 0x56, 0x3F, 0x1A, 0x80, 0x89, 0x7A, 0xA9, 0xE2, 0x1B, 0x32, + 0x51, 0x2C, 0x3E, 0xF2, 0xDF, 0x7B, 0xF6, 0x5D, 0x7A, 0x29, 0x19, 0x8E, + 0xE5, 0xC8, 0xBD, 0x36, 0x71, 0x8B, 0x5D, 0x4C, 0xC2, 0x1D, 0x3F, 0xAD, + 0x58, 0xA2, 0xCF, 0x3D, 0x70, 0x4D, 0xA6, 0x50, 0x98, 0x25, 0xDC, 0x23, + 0xF9, 0xB8, 0x58, 0x41, 0x08, 0x71, 0xBF, 0x4F, 0xB8, 0x84, 0xA0, 0x8F, + 0x00, 0x54, 0x15, 0xFC, 0x91, 0x6D, 0x58, 0xA7, 0x96, 0x3B, 0xEB, 0x4B, + 0x96, 0x27, 0xCD, 0x6B, 0xA2, 0xA1, 0x86, 0xAC, 0x0D, 0x7C, 0x54, 0xE6, + 0x66, 0x4C, 0x66, 0x5F, 0x90, 0xBE, 0x21, 0x9A, 0x02, 0x46, 0x2D, 0xE4, + 0x83, 0xC2, 0x80, 0xB9, 0xCF, 0x4B, 0x3E, 0xE8, 0x7F, 0x3C, 0x01, 0xEC, + 0x8F, 0x5E, 0xCD, 0x7F, 0xD2, 0x28, 0x42, 0x01, 0x95, 0x8A, 0xE2, 0x97, + 0x3D, 0x10, 0x21, 0x7D, 0xF6, 0x9D, 0x1C, 0xC5, 0x34, 0xA1, 0xEC, 0x2C, + 0x0E, 0x0A, 0x52, 0x2C, 0x12, 0x55, 0x70, 0x24, 0x3D, 0xCB, 0xC2, 0x14, + 0x35, 0x43, 0x5D, 0x27, 0x4E, 0xBE, 0xC0, 0xBD, 0xAA, 0x7C, 0x96, 0xE7, + 0xFC, 0x9E, 0x61, 0xAD, 0x44, 0xD3, 0x00, 0x97 +}; + +static const unsigned char TA614_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA615_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA615_RSA_N[] = { + 0xB3, 0xCB, 0x0E, 0x10, 0x67, 0x8E, 0xEA, 0x14, 0x97, 0xA7, 0x32, 0x2A, + 0x0A, 0x56, 0x36, 0x7F, 0x68, 0x4C, 0xC7, 0xB3, 0x6F, 0x3A, 0x23, 0x14, + 0x91, 0xFF, 0x19, 0x7F, 0xA5, 0xCA, 0xAC, 0xEE, 0xB3, 0x76, 0x9D, 0x7A, + 0xE9, 0x8B, 0x1B, 0xAB, 0x6B, 0x31, 0xDB, 0xFA, 0x0B, 0x53, 0x4C, 0xAF, + 0xC5, 0xA5, 0x1A, 0x79, 0x3C, 0x8A, 0x4C, 0xFF, 0xAC, 0xDF, 0x25, 0xDE, + 0x4E, 0xD9, 0x82, 0x32, 0x0B, 0x44, 0xDE, 0xCA, 0xDB, 0x8C, 0xAC, 0xA3, + 0x6E, 0x16, 0x83, 0x3B, 0xA6, 0x64, 0x4B, 0x32, 0x89, 0xFB, 0x16, 0x16, + 0x38, 0x7E, 0xEB, 0x43, 0xE2, 0xD3, 0x74, 0x4A, 0xC2, 0x62, 0x0A, 0x73, + 0x0A, 0xDD, 0x49, 0xB3, 0x57, 0xD2, 0xB0, 0x0A, 0x85, 0x9D, 0x71, 0x3C, + 0xDE, 0xA3, 0xCB, 0xC0, 0x32, 0xF3, 0x01, 0x39, 0x20, 0x43, 0x1B, 0x35, + 0xD1, 0x53, 0xB3, 0xB1, 0xEE, 0xC5, 0x93, 0x69, 0x82, 0x3E, 0x16, 0xB5, + 0x28, 0x46, 0xA1, 0xDE, 0xEA, 0x89, 0x09, 0xED, 0x43, 0xB8, 0x05, 0x46, + 0x8A, 0x86, 0xF5, 0x59, 0x47, 0xBE, 0x1B, 0x6F, 0x01, 0x21, 0x10, 0xB9, + 0xFD, 0xA9, 0xD2, 0x28, 0xCA, 0x10, 0x39, 0x09, 0xCA, 0x13, 0x36, 0xCF, + 0x9C, 0xAD, 0xAD, 0x40, 0x74, 0x79, 0x2B, 0x02, 0x3F, 0x34, 0xFF, 0xFA, + 0x20, 0x69, 0x7D, 0xD3, 0xEE, 0x61, 0xF5, 0xBA, 0xB3, 0xE7, 0x30, 0xD0, + 0x37, 0x23, 0x86, 0x72, 0x61, 0x45, 0x29, 0x48, 0x59, 0x68, 0x6F, 0x77, + 0xA6, 0x2E, 0x81, 0xBE, 0x07, 0x4D, 0x6F, 0xAF, 0xCE, 0xC4, 0x45, 0x13, + 0x91, 0x14, 0x70, 0x06, 0x8F, 0x1F, 0x9F, 0xF8, 0x87, 0x69, 0xB1, 0x0E, + 0xEF, 0xC3, 0x89, 0x19, 0xEB, 0xEA, 0x1C, 0x61, 0xFC, 0x7A, 0x6C, 0x8A, + 0xDC, 0xD6, 0x03, 0x0B, 0x9E, 0x26, 0xBA, 0x12, 0xDD, 0xD4, 0x54, 0x39, + 0xAB, 0x26, 0xA3, 0x33, 0xEA, 0x75, 0x81, 0xDA, 0x2D, 0xCD, 0x0F, 0x4F, + 0xE4, 0x03, 0xD1, 0xEF, 0x15, 0x97, 0x1B, 0x6B, 0x90, 0xC5, 0x02, 0x90, + 0x93, 0x66, 0x02, 0x21, 0xB1, 0x47, 0xDE, 0x8B, 0x9A, 0x4A, 0x80, 0xB9, + 0x55, 0x8F, 0xB5, 0xA2, 0x2F, 0xC0, 0xD6, 0x33, 0x67, 0xDA, 0x7E, 0xC4, + 0xA7, 0xB4, 0x04, 0x44, 0xEB, 0x47, 0xFB, 0xE6, 0x58, 0xB9, 0xF7, 0x0C, + 0xF0, 0x7B, 0x2B, 0xB1, 0xC0, 0x70, 0x29, 0xC3, 0x40, 0x62, 0x2D, 0x3B, + 0x48, 0x69, 0xDC, 0x23, 0x3C, 0x48, 0xEB, 0x7B, 0x09, 0x79, 0xA9, 0x6D, + 0xDA, 0xA8, 0x30, 0x98, 0xCF, 0x80, 0x72, 0x03, 0x88, 0xA6, 0x5B, 0x46, + 0xAE, 0x72, 0x79, 0x7C, 0x08, 0x03, 0x21, 0x65, 0xAE, 0xB7, 0xE1, 0x1C, + 0xA5, 0xB1, 0x2A, 0xA2, 0x31, 0xDE, 0x66, 0x04, 0xF7, 0xC0, 0x74, 0xE8, + 0x71, 0xDE, 0xFF, 0x3D, 0x59, 0xCC, 0x96, 0x26, 0x12, 0x8B, 0x85, 0x95, + 0x57, 0x1A, 0xAB, 0x6B, 0x75, 0x0B, 0x44, 0x3D, 0x11, 0x28, 0x3C, 0x7B, + 0x61, 0xB7, 0xE2, 0x8F, 0x67, 0x4F, 0xE5, 0xEC, 0x3C, 0x4C, 0x60, 0x80, + 0x69, 0x57, 0x38, 0x1E, 0x01, 0x5B, 0x8D, 0x55, 0xE8, 0xC7, 0xDF, 0xC0, + 0xCC, 0x77, 0x23, 0x34, 0x49, 0x75, 0x7C, 0xF6, 0x98, 0x11, 0xEB, 0x2D, + 0xDE, 0xED, 0x41, 0x2E, 0x14, 0x05, 0x02, 0x7F, 0xE0, 0xFE, 0x20, 0xEB, + 0x35, 0xE7, 0x11, 0xAC, 0x22, 0xCE, 0x57, 0x3D, 0xDE, 0xC9, 0x30, 0x6D, + 0x10, 0x03, 0x85, 0xCD, 0xF1, 0xFF, 0x8C, 0x16, 0xB5, 0xC1, 0xB2, 0x3E, + 0x88, 0x6C, 0x60, 0x7F, 0x90, 0x4F, 0x95, 0xF7, 0xF6, 0x2D, 0xAD, 0x01, + 0x39, 0x07, 0x04, 0xFA, 0x75, 0x80, 0x7D, 0xBF, 0x49, 0x50, 0xED, 0xEF, + 0xC9, 0xC4, 0x7C, 0x1C, 0xEB, 0x80, 0x7E, 0xDB, 0xB6, 0xD0, 0xDD, 0x13, + 0xFE, 0xC9, 0xD3, 0x9C, 0xD7, 0xB2, 0x97, 0xA9 +}; + +static const unsigned char TA615_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA616_DN[] = { + 0x30, 0x7A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA616_RSA_N[] = { + 0xD1, 0x2D, 0x8E, 0xBB, 0xB7, 0x36, 0xEA, 0x6D, 0x37, 0x91, 0x9F, 0x4E, + 0x93, 0xA7, 0x05, 0xE4, 0x29, 0x03, 0x25, 0xCE, 0x1C, 0x82, 0xF7, 0x7C, + 0x99, 0x9F, 0x41, 0x06, 0xCD, 0xED, 0xA3, 0xBA, 0xC0, 0xDB, 0x09, 0x2C, + 0xC1, 0x7C, 0xDF, 0x29, 0x7E, 0x4B, 0x65, 0x2F, 0x93, 0xA7, 0xD4, 0x01, + 0x6B, 0x03, 0x28, 0x18, 0xA3, 0xD8, 0x9D, 0x05, 0xC1, 0x2A, 0xD8, 0x45, + 0xF1, 0x91, 0xDE, 0xDF, 0x3B, 0xD0, 0x80, 0x02, 0x8C, 0xCF, 0x38, 0x0F, + 0xEA, 0xA7, 0x5C, 0x78, 0x11, 0xA4, 0xC1, 0xC8, 0x85, 0x5C, 0x25, 0xD3, + 0xD3, 0xB2, 0xE7, 0x25, 0xCF, 0x11, 0x54, 0x97, 0xAB, 0x35, 0xC0, 0x1E, + 0x76, 0x1C, 0xEF, 0x00, 0x53, 0x9F, 0x39, 0xDC, 0x14, 0xA5, 0x2C, 0x22, + 0x25, 0xB3, 0x72, 0x72, 0xFC, 0x8D, 0xB3, 0xE5, 0x3E, 0x08, 0x1E, 0x14, + 0x2A, 0x37, 0x0B, 0x88, 0x3C, 0xCA, 0xB0, 0xF4, 0xC8, 0xC2, 0xA1, 0xAE, + 0xBC, 0xC1, 0xBE, 0x29, 0x67, 0x55, 0xE2, 0xFC, 0xAD, 0x59, 0x5C, 0xFE, + 0xBD, 0x57, 0x2C, 0xB0, 0x90, 0x8D, 0xC2, 0xED, 0x37, 0xB6, 0x7C, 0x99, + 0x88, 0xB5, 0xD5, 0x03, 0x9A, 0x3D, 0x15, 0x0D, 0x3D, 0x3A, 0xA8, 0xA8, + 0x45, 0xF0, 0x95, 0x4E, 0x25, 0x59, 0x1D, 0xCD, 0x98, 0x69, 0xBB, 0xD3, + 0xCC, 0x32, 0xC9, 0x8D, 0xEF, 0x81, 0xFE, 0xAD, 0x7D, 0x89, 0xBB, 0xBA, + 0x60, 0x13, 0xCA, 0x65, 0x95, 0x67, 0xA0, 0xF3, 0x19, 0xF6, 0x03, 0x56, + 0xD4, 0x6A, 0xD3, 0x27, 0xE2, 0xA1, 0xAD, 0x83, 0xF0, 0x4A, 0x12, 0x22, + 0x77, 0x1C, 0x05, 0x73, 0xE2, 0x19, 0x71, 0x42, 0xC0, 0xEC, 0x75, 0x46, + 0x9A, 0x90, 0x58, 0xE0, 0x6A, 0x8E, 0x2B, 0xA5, 0x46, 0x30, 0x04, 0x8E, + 0x19, 0xB2, 0x17, 0xE3, 0xBE, 0xA9, 0xBA, 0x7F, 0x56, 0xF1, 0x24, 0x03, + 0xD7, 0xB2, 0x21, 0x28, 0x76, 0x0E, 0x36, 0x30, 0x4C, 0x79, 0xD5, 0x41, + 0x9A, 0x9A, 0xA8, 0xB8, 0x35, 0xBA, 0x0C, 0x3A, 0xF2, 0x44, 0x1B, 0x20, + 0x88, 0xF7, 0xC5, 0x25, 0xD7, 0x3D, 0xC6, 0xE3, 0x3E, 0x43, 0xDD, 0x87, + 0xFE, 0xC4, 0xEA, 0xF5, 0x53, 0x3E, 0x4C, 0x65, 0xFF, 0x3B, 0x4A, 0xCB, + 0x78, 0x5A, 0x6B, 0x17, 0x5F, 0x0D, 0xC7, 0xC3, 0x4F, 0x4E, 0x9A, 0x2A, + 0xA2, 0xED, 0x57, 0x4D, 0x22, 0xE2, 0x46, 0x9A, 0x3F, 0x0F, 0x91, 0x34, + 0x24, 0x7D, 0x55, 0xE3, 0x8C, 0x95, 0x37, 0xD3, 0x1A, 0xF0, 0x09, 0x2B, + 0x2C, 0xD2, 0xC9, 0x8D, 0xB4, 0x0D, 0x00, 0xAB, 0x67, 0x29, 0x28, 0xD8, + 0x01, 0xF5, 0x19, 0x04, 0xB6, 0x1D, 0xBE, 0x76, 0xFE, 0x72, 0x5C, 0xC4, + 0x85, 0xCA, 0xD2, 0x80, 0x41, 0xDF, 0x05, 0xA8, 0xA3, 0xD5, 0x84, 0x90, + 0x4F, 0x0B, 0xF3, 0xE0, 0x3F, 0x9B, 0x19, 0xD2, 0x37, 0x89, 0x3F, 0xF2, + 0x7B, 0x52, 0x1C, 0x8C, 0xF6, 0xE1, 0xF7, 0x3C, 0x07, 0x97, 0x8C, 0x0E, + 0xA2, 0x59, 0x81, 0x0C, 0xB2, 0x90, 0x3D, 0xD3, 0xE3, 0x59, 0x46, 0xED, + 0x0F, 0xA9, 0xA7, 0xDE, 0x80, 0x6B, 0x5A, 0xAA, 0x07, 0xB6, 0x19, 0xCB, + 0xBC, 0x57, 0xF3, 0x97, 0x21, 0x7A, 0x0C, 0xB1, 0x2B, 0x74, 0x3E, 0xEB, + 0xDA, 0xA7, 0x67, 0x2D, 0x4C, 0xC4, 0x98, 0x9E, 0x36, 0x09, 0x76, 0x66, + 0x66, 0xFC, 0x1A, 0x3F, 0xEA, 0x48, 0x54, 0x1C, 0xBE, 0x30, 0xBD, 0x80, + 0x50, 0xBF, 0x7C, 0xB5, 0xCE, 0x00, 0xF6, 0x0C, 0x61, 0xD9, 0xE7, 0x24, + 0x03, 0xE0, 0xE3, 0x01, 0x81, 0x0E, 0xBD, 0xD8, 0x85, 0x34, 0x88, 0xBD, + 0xB2, 0x36, 0xA8, 0x7B, 0x5C, 0x08, 0xE5, 0x44, 0x80, 0x8C, 0x6F, 0xF8, + 0x2F, 0xD5, 0x21, 0xCA, 0x1D, 0x1C, 0xD0, 0xFB, 0xC4, 0xB5, 0x87, 0xD1, + 0x3A, 0x4E, 0xC7, 0x76, 0xB5, 0x35, 0x48, 0xB5 +}; + +static const unsigned char TA616_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA617_DN[] = { + 0x30, 0x3C, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x15, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x0D, + 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x04, 0x41, 0x74, 0x6F, + 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x44, 0x45 +}; + +static const unsigned char TA617_RSA_N[] = { + 0x95, 0x85, 0x3B, 0x97, 0x6F, 0x2A, 0x3B, 0x2E, 0x3B, 0xCF, 0xA6, 0xF3, + 0x29, 0x35, 0xBE, 0xCF, 0x18, 0xAC, 0x3E, 0xAA, 0xD9, 0xF8, 0x4D, 0xA0, + 0x3E, 0x1A, 0x47, 0xB9, 0xBC, 0x9A, 0xDF, 0xF2, 0xFE, 0xCC, 0x3E, 0x47, + 0xE8, 0x7A, 0x96, 0xC2, 0x24, 0x8E, 0x35, 0xF4, 0xA9, 0x0C, 0xFC, 0x82, + 0xFD, 0x6D, 0xC1, 0x72, 0x62, 0x27, 0xBD, 0xEA, 0x6B, 0xEB, 0xE7, 0x8A, + 0xCC, 0x54, 0x3E, 0x90, 0x50, 0xCF, 0x80, 0xD4, 0x95, 0xFB, 0xE8, 0xB5, + 0x82, 0xD4, 0x14, 0xC5, 0xB6, 0xA9, 0x55, 0x25, 0x57, 0xDB, 0xB1, 0x50, + 0xF6, 0xB0, 0x60, 0x64, 0x59, 0x7A, 0x69, 0xCF, 0x03, 0xB7, 0x6F, 0x0D, + 0xBE, 0xCA, 0x3E, 0x6F, 0x74, 0x72, 0xEA, 0xAA, 0x30, 0x2A, 0x73, 0x62, + 0xBE, 0x49, 0x91, 0x61, 0xC8, 0x11, 0xFE, 0x0E, 0x03, 0x2A, 0xF7, 0x6A, + 0x20, 0xDC, 0x02, 0x15, 0x0D, 0x5E, 0x15, 0x6A, 0xFC, 0xE3, 0x82, 0xC1, + 0xB5, 0xC5, 0x9D, 0x64, 0x09, 0x6C, 0xA3, 0x59, 0x98, 0x07, 0x27, 0xC7, + 0x1B, 0x96, 0x2B, 0x61, 0x74, 0x71, 0x6C, 0x43, 0xF1, 0xF7, 0x35, 0x89, + 0x10, 0xE0, 0x9E, 0xEC, 0x55, 0xA1, 0x37, 0x22, 0xA2, 0x87, 0x04, 0x05, + 0x2C, 0x47, 0x7D, 0xB4, 0x1C, 0xB9, 0x62, 0x29, 0x66, 0x28, 0xCA, 0xB7, + 0xE1, 0x93, 0xF5, 0xA4, 0x94, 0x03, 0x99, 0xB9, 0x70, 0x85, 0xB5, 0xE6, + 0x48, 0xEA, 0x8D, 0x50, 0xFC, 0xD9, 0xDE, 0xCC, 0x6F, 0x07, 0x0E, 0xDD, + 0x0B, 0x72, 0x9D, 0x80, 0x30, 0x16, 0x07, 0x95, 0x3F, 0x28, 0x0E, 0xFD, + 0xC5, 0x75, 0x4F, 0x53, 0xD6, 0x74, 0x9A, 0xB4, 0x24, 0x2E, 0x8E, 0x02, + 0x91, 0xCF, 0x76, 0xC5, 0x9B, 0x1E, 0x55, 0x74, 0x9C, 0x78, 0x21, 0xB1, + 0xF0, 0x2D, 0xF1, 0x0B, 0x9F, 0xC2, 0xD5, 0x96, 0x18, 0x1F, 0xF0, 0x54, + 0x22, 0x7A, 0x8C, 0x07 +}; + +static const unsigned char TA617_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA618_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA618_RSA_N[] = { + 0xB3, 0xCB, 0x0E, 0x10, 0x67, 0x8E, 0xEA, 0x14, 0x97, 0xA7, 0x32, 0x2A, + 0x0A, 0x56, 0x36, 0x7F, 0x68, 0x4C, 0xC7, 0xB3, 0x6F, 0x3A, 0x23, 0x14, + 0x91, 0xFF, 0x19, 0x7F, 0xA5, 0xCA, 0xAC, 0xEE, 0xB3, 0x76, 0x9D, 0x7A, + 0xE9, 0x8B, 0x1B, 0xAB, 0x6B, 0x31, 0xDB, 0xFA, 0x0B, 0x53, 0x4C, 0xAF, + 0xC5, 0xA5, 0x1A, 0x79, 0x3C, 0x8A, 0x4C, 0xFF, 0xAC, 0xDF, 0x25, 0xDE, + 0x4E, 0xD9, 0x82, 0x32, 0x0B, 0x44, 0xDE, 0xCA, 0xDB, 0x8C, 0xAC, 0xA3, + 0x6E, 0x16, 0x83, 0x3B, 0xA6, 0x64, 0x4B, 0x32, 0x89, 0xFB, 0x16, 0x16, + 0x38, 0x7E, 0xEB, 0x43, 0xE2, 0xD3, 0x74, 0x4A, 0xC2, 0x62, 0x0A, 0x73, + 0x0A, 0xDD, 0x49, 0xB3, 0x57, 0xD2, 0xB0, 0x0A, 0x85, 0x9D, 0x71, 0x3C, + 0xDE, 0xA3, 0xCB, 0xC0, 0x32, 0xF3, 0x01, 0x39, 0x20, 0x43, 0x1B, 0x35, + 0xD1, 0x53, 0xB3, 0xB1, 0xEE, 0xC5, 0x93, 0x69, 0x82, 0x3E, 0x16, 0xB5, + 0x28, 0x46, 0xA1, 0xDE, 0xEA, 0x89, 0x09, 0xED, 0x43, 0xB8, 0x05, 0x46, + 0x8A, 0x86, 0xF5, 0x59, 0x47, 0xBE, 0x1B, 0x6F, 0x01, 0x21, 0x10, 0xB9, + 0xFD, 0xA9, 0xD2, 0x28, 0xCA, 0x10, 0x39, 0x09, 0xCA, 0x13, 0x36, 0xCF, + 0x9C, 0xAD, 0xAD, 0x40, 0x74, 0x79, 0x2B, 0x02, 0x3F, 0x34, 0xFF, 0xFA, + 0x20, 0x69, 0x7D, 0xD3, 0xEE, 0x61, 0xF5, 0xBA, 0xB3, 0xE7, 0x30, 0xD0, + 0x37, 0x23, 0x86, 0x72, 0x61, 0x45, 0x29, 0x48, 0x59, 0x68, 0x6F, 0x77, + 0xA6, 0x2E, 0x81, 0xBE, 0x07, 0x4D, 0x6F, 0xAF, 0xCE, 0xC4, 0x45, 0x13, + 0x91, 0x14, 0x70, 0x06, 0x8F, 0x1F, 0x9F, 0xF8, 0x87, 0x69, 0xB1, 0x0E, + 0xEF, 0xC3, 0x89, 0x19, 0xEB, 0xEA, 0x1C, 0x61, 0xFC, 0x7A, 0x6C, 0x8A, + 0xDC, 0xD6, 0x03, 0x0B, 0x9E, 0x26, 0xBA, 0x12, 0xDD, 0xD4, 0x54, 0x39, + 0xAB, 0x26, 0xA3, 0x33, 0xEA, 0x75, 0x81, 0xDA, 0x2D, 0xCD, 0x0F, 0x4F, + 0xE4, 0x03, 0xD1, 0xEF, 0x15, 0x97, 0x1B, 0x6B, 0x90, 0xC5, 0x02, 0x90, + 0x93, 0x66, 0x02, 0x21, 0xB1, 0x47, 0xDE, 0x8B, 0x9A, 0x4A, 0x80, 0xB9, + 0x55, 0x8F, 0xB5, 0xA2, 0x2F, 0xC0, 0xD6, 0x33, 0x67, 0xDA, 0x7E, 0xC4, + 0xA7, 0xB4, 0x04, 0x44, 0xEB, 0x47, 0xFB, 0xE6, 0x58, 0xB9, 0xF7, 0x0C, + 0xF0, 0x7B, 0x2B, 0xB1, 0xC0, 0x70, 0x29, 0xC3, 0x40, 0x62, 0x2D, 0x3B, + 0x48, 0x69, 0xDC, 0x23, 0x3C, 0x48, 0xEB, 0x7B, 0x09, 0x79, 0xA9, 0x6D, + 0xDA, 0xA8, 0x30, 0x98, 0xCF, 0x80, 0x72, 0x03, 0x88, 0xA6, 0x5B, 0x46, + 0xAE, 0x72, 0x79, 0x7C, 0x08, 0x03, 0x21, 0x65, 0xAE, 0xB7, 0xE1, 0x1C, + 0xA5, 0xB1, 0x2A, 0xA2, 0x31, 0xDE, 0x66, 0x04, 0xF7, 0xC0, 0x74, 0xE8, + 0x71, 0xDE, 0xFF, 0x3D, 0x59, 0xCC, 0x96, 0x26, 0x12, 0x8B, 0x85, 0x95, + 0x57, 0x1A, 0xAB, 0x6B, 0x75, 0x0B, 0x44, 0x3D, 0x11, 0x28, 0x3C, 0x7B, + 0x61, 0xB7, 0xE2, 0x8F, 0x67, 0x4F, 0xE5, 0xEC, 0x3C, 0x4C, 0x60, 0x80, + 0x69, 0x57, 0x38, 0x1E, 0x01, 0x5B, 0x8D, 0x55, 0xE8, 0xC7, 0xDF, 0xC0, + 0xCC, 0x77, 0x23, 0x34, 0x49, 0x75, 0x7C, 0xF6, 0x98, 0x11, 0xEB, 0x2D, + 0xDE, 0xED, 0x41, 0x2E, 0x14, 0x05, 0x02, 0x7F, 0xE0, 0xFE, 0x20, 0xEB, + 0x35, 0xE7, 0x11, 0xAC, 0x22, 0xCE, 0x57, 0x3D, 0xDE, 0xC9, 0x30, 0x6D, + 0x10, 0x03, 0x85, 0xCD, 0xF1, 0xFF, 0x8C, 0x16, 0xB5, 0xC1, 0xB2, 0x3E, + 0x88, 0x6C, 0x60, 0x7F, 0x90, 0x4F, 0x95, 0xF7, 0xF6, 0x2D, 0xAD, 0x01, + 0x39, 0x07, 0x04, 0xFA, 0x75, 0x80, 0x7D, 0xBF, 0x49, 0x50, 0xED, 0xEF, + 0xC9, 0xC4, 0x7C, 0x1C, 0xEB, 0x80, 0x7E, 0xDB, 0xB6, 0xD0, 0xDD, 0x13, + 0xFE, 0xC9, 0xD3, 0x9C, 0xD7, 0xB2, 0x97, 0xA9 +}; + +static const unsigned char TA618_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA619_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C +}; + +static const unsigned char TA619_RSA_N[] = { + 0xF6, 0x1B, 0x4F, 0x67, 0x07, 0x2B, 0xA1, 0x15, 0xF5, 0x06, 0x22, 0xCB, + 0x1F, 0x01, 0xB2, 0xE3, 0x73, 0x45, 0x06, 0x44, 0x49, 0x2C, 0xBB, 0x49, + 0x25, 0x14, 0xD6, 0xCE, 0xC3, 0xB7, 0xAB, 0x2C, 0x4F, 0xC6, 0x41, 0x32, + 0x94, 0x57, 0xFA, 0x12, 0xA7, 0x5B, 0x0E, 0xE2, 0x8F, 0x1F, 0x1E, 0x86, + 0x19, 0xA7, 0xAA, 0xB5, 0x2D, 0xB9, 0x5F, 0x0D, 0x8A, 0xC2, 0xAF, 0x85, + 0x35, 0x79, 0x32, 0x2D, 0xBB, 0x1C, 0x62, 0x37, 0xF2, 0xB1, 0x5B, 0x4A, + 0x3D, 0xCA, 0xCD, 0x71, 0x5F, 0xE9, 0x42, 0xBE, 0x94, 0xE8, 0xC8, 0xDE, + 0xF9, 0x22, 0x48, 0x64, 0xC6, 0xE5, 0xAB, 0xC6, 0x2B, 0x6D, 0xAD, 0x05, + 0xF0, 0xFA, 0xD5, 0x0B, 0xCF, 0x9A, 0xE5, 0xF0, 0x50, 0xA4, 0x8B, 0x3B, + 0x47, 0xA5, 0x23, 0x5B, 0x7A, 0x7A, 0xF8, 0x33, 0x3F, 0xB8, 0xEF, 0x99, + 0x97, 0xE3, 0x20, 0xC1, 0xD6, 0x28, 0x89, 0xCF, 0x94, 0xFB, 0xB9, 0x45, + 0xED, 0xE3, 0x40, 0x17, 0x11, 0xD4, 0x74, 0xF0, 0x0B, 0x31, 0xE2, 0x2B, + 0x26, 0x6A, 0x9B, 0x4C, 0x57, 0xAE, 0xAC, 0x20, 0x3E, 0xBA, 0x45, 0x7A, + 0x05, 0xF3, 0xBD, 0x9B, 0x69, 0x15, 0xAE, 0x7D, 0x4E, 0x20, 0x63, 0xC4, + 0x35, 0x76, 0x3A, 0x07, 0x02, 0xC9, 0x37, 0xFD, 0xC7, 0x47, 0xEE, 0xE8, + 0xF1, 0x76, 0x1D, 0x73, 0x15, 0xF2, 0x97, 0xA4, 0xB5, 0xC8, 0x7A, 0x79, + 0xD9, 0x42, 0xAA, 0x2B, 0x7F, 0x5C, 0xFE, 0xCE, 0x26, 0x4F, 0xA3, 0x66, + 0x81, 0x35, 0xAF, 0x44, 0xBA, 0x54, 0x1E, 0x1C, 0x30, 0x32, 0x65, 0x9D, + 0xE6, 0x3C, 0x93, 0x5E, 0x50, 0x4E, 0x7A, 0xE3, 0x3A, 0xD4, 0x6E, 0xCC, + 0x1A, 0xFB, 0xF9, 0xD2, 0x37, 0xAE, 0x24, 0x2A, 0xAB, 0x57, 0x03, 0x22, + 0x28, 0x0D, 0x49, 0x75, 0x7F, 0xB7, 0x28, 0xDA, 0x75, 0xBF, 0x8E, 0xE3, + 0xDC, 0x0E, 0x79, 0x31 +}; + +static const unsigned char TA619_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA620_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x42, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA620_RSA_N[] = { + 0xD8, 0x17, 0xB7, 0x1C, 0x4A, 0x24, 0x2A, 0xD6, 0x97, 0xB1, 0xCA, 0xE2, + 0x1E, 0xFB, 0x7D, 0x38, 0xEF, 0x98, 0xF5, 0xB2, 0x39, 0x98, 0x4E, 0x27, + 0xB8, 0x11, 0x5D, 0x7B, 0xD2, 0x25, 0x94, 0x88, 0x82, 0x15, 0x26, 0x6A, + 0x1B, 0x31, 0xBB, 0xA8, 0x5B, 0x21, 0x21, 0x2B, 0xD8, 0x0F, 0x4E, 0x9F, + 0x5A, 0xF1, 0xB1, 0x5A, 0xE4, 0x79, 0xD6, 0x32, 0x23, 0x2B, 0xE1, 0x53, + 0xCC, 0x99, 0x45, 0x5C, 0x7B, 0x4F, 0xAD, 0xBC, 0xBF, 0x87, 0x4A, 0x0B, + 0x4B, 0x97, 0x5A, 0xA8, 0xF6, 0x48, 0xEC, 0x7D, 0x7B, 0x0D, 0xCD, 0x21, + 0x06, 0xDF, 0x9E, 0x15, 0xFD, 0x41, 0x8A, 0x48, 0xB7, 0x20, 0xF4, 0xA1, + 0x7A, 0x1B, 0x57, 0xD4, 0x5D, 0x50, 0xFF, 0xBA, 0x67, 0xD8, 0x23, 0x99, + 0x1F, 0xC8, 0x3F, 0xE3, 0xDE, 0xFF, 0x6F, 0x5B, 0x77, 0xB1, 0x6B, 0x6E, + 0xB8, 0xC9, 0x64, 0xF7, 0xE1, 0xCA, 0x41, 0x46, 0x0E, 0x29, 0x71, 0xD0, + 0xB9, 0x23, 0xFC, 0xC9, 0x81, 0x5F, 0x4E, 0xF7, 0x6F, 0xDF, 0xBF, 0x84, + 0xAD, 0x73, 0x64, 0xBB, 0xB7, 0x42, 0x8E, 0x69, 0xF6, 0xD4, 0x76, 0x1D, + 0x7E, 0x9D, 0xA7, 0xB8, 0x57, 0x8A, 0x51, 0x67, 0x72, 0xD7, 0xD4, 0xA8, + 0xB8, 0x95, 0x54, 0x40, 0x73, 0x03, 0xF6, 0xEA, 0xF4, 0xEB, 0xFE, 0x28, + 0x42, 0x77, 0x3F, 0x9D, 0x23, 0x1B, 0xB2, 0xB6, 0x3D, 0x80, 0x14, 0x07, + 0x4C, 0x2E, 0x4F, 0xF7, 0xD5, 0x0A, 0x16, 0x0D, 0xBD, 0x66, 0x43, 0x37, + 0x7E, 0x23, 0x43, 0x79, 0xC3, 0x40, 0x86, 0xF5, 0x4C, 0x29, 0xDA, 0x8E, + 0x9A, 0xAD, 0x0D, 0xA5, 0x04, 0x87, 0x88, 0x1E, 0x85, 0xE3, 0xE9, 0x53, + 0xD5, 0x9B, 0xC8, 0x8B, 0x03, 0x63, 0x78, 0xEB, 0xE0, 0x19, 0x4A, 0x6E, + 0xBB, 0x2F, 0x6B, 0x33, 0x64, 0x58, 0x93, 0xAD, 0x69, 0xBF, 0x8F, 0x1B, + 0xEF, 0x82, 0x48, 0xC7 +}; + +static const unsigned char TA620_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA621_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, 0x36 +}; + +static const unsigned char TA621_EC_Q[] = { + 0x04, 0x9C, 0x0E, 0xB1, 0xCF, 0xB7, 0xE8, 0x9E, 0x52, 0x77, 0x75, 0x34, + 0xFA, 0xA5, 0x46, 0xA7, 0xAD, 0x32, 0x19, 0x32, 0xB4, 0x07, 0xA9, 0x27, + 0xCA, 0x94, 0xBB, 0x0C, 0xD2, 0x0A, 0x10, 0xC7, 0xDA, 0x89, 0xB0, 0x97, + 0x0C, 0x70, 0x13, 0x09, 0x01, 0x8E, 0xD8, 0xEA, 0x47, 0xEA, 0xBE, 0xB2, + 0x80, 0x2B, 0xCD, 0xFC, 0x28, 0x0D, 0xDB, 0xAC, 0xBC, 0xA4, 0x86, 0x37, + 0xED, 0x70, 0x08, 0x00, 0x75, 0xEA, 0x93, 0x0B, 0x7B, 0x2E, 0x52, 0x9C, + 0x23, 0x68, 0x23, 0x06, 0x43, 0xEC, 0x92, 0x2F, 0x53, 0x84, 0xDB, 0xFB, + 0x47, 0x14, 0x07, 0xE8, 0x5F, 0x94, 0x67, 0x5D, 0xC9, 0x7A, 0x81, 0x3C, + 0x20 +}; + +static const unsigned char TA622_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA622_RSA_N[] = { + 0xE1, 0xFA, 0x0E, 0xFB, 0x68, 0x00, 0x12, 0xC8, 0x4D, 0xD5, 0xAC, 0x22, + 0xC4, 0x35, 0x01, 0x3B, 0xC5, 0x54, 0xE5, 0x59, 0x76, 0x63, 0xA5, 0x7F, + 0xEB, 0xC1, 0xC4, 0x6A, 0x98, 0xBD, 0x32, 0x8D, 0x17, 0x80, 0xEB, 0x5D, + 0xBA, 0xD1, 0x62, 0x3D, 0x25, 0x23, 0x19, 0x35, 0x14, 0xE9, 0x7F, 0x89, + 0xA7, 0x1B, 0x62, 0x3C, 0xD6, 0x50, 0xE7, 0x34, 0x95, 0x03, 0x32, 0xB1, + 0xB4, 0x93, 0x22, 0x3D, 0xA7, 0xE2, 0xB1, 0xED, 0xE6, 0x7B, 0x4E, 0x2E, + 0x87, 0x9B, 0x0D, 0x33, 0x75, 0x0A, 0xDE, 0xAA, 0x35, 0xE7, 0x7E, 0xE5, + 0x36, 0x98, 0xA2, 0xAE, 0x25, 0x9E, 0x95, 0xB3, 0x32, 0x96, 0xA4, 0x2B, + 0x58, 0x1E, 0xEF, 0x3F, 0xFE, 0x62, 0x34, 0x48, 0x51, 0xD1, 0xB4, 0x8D, + 0x42, 0xAD, 0x60, 0xDA, 0x49, 0x6A, 0x95, 0x70, 0xDD, 0xD2, 0x00, 0xE2, + 0xCC, 0x57, 0x63, 0x02, 0x7B, 0x96, 0xDD, 0x49, 0x97, 0x5B, 0x92, 0x4E, + 0x95, 0xD3, 0xF9, 0xCB, 0x29, 0x1F, 0x18, 0x4A, 0xF8, 0x01, 0x2A, 0xD2, + 0x63, 0x09, 0x6E, 0x24, 0xE9, 0x89, 0xD2, 0xE5, 0xC7, 0x22, 0x4C, 0xDC, + 0x73, 0x86, 0x47, 0x00, 0xAA, 0x0D, 0x88, 0x8E, 0xAE, 0x85, 0x7D, 0x4A, + 0xE9, 0xBB, 0x33, 0x4F, 0x0E, 0x52, 0x70, 0x9D, 0x95, 0xE3, 0x7C, 0x6D, + 0x96, 0x5B, 0x2D, 0x3D, 0x5F, 0xA1, 0x83, 0x46, 0x5D, 0xB6, 0xE3, 0x25, + 0xB8, 0x7C, 0xA7, 0x19, 0x80, 0x1C, 0xEA, 0x65, 0x43, 0xDC, 0x91, 0x79, + 0x36, 0x2C, 0x74, 0x7C, 0xF2, 0x67, 0x06, 0xC9, 0x89, 0xC9, 0xDB, 0xBF, + 0xDA, 0x68, 0xBF, 0x23, 0xED, 0xDC, 0x6B, 0xAD, 0x28, 0x83, 0x79, 0x2F, + 0xEC, 0x38, 0xA5, 0x0D, 0x37, 0x01, 0x67, 0x27, 0x9A, 0xE9, 0x33, 0xD9, + 0x33, 0x5F, 0x37, 0xA1, 0xC5, 0xF0, 0xAB, 0x3D, 0xFA, 0x78, 0xB0, 0xE7, + 0x2C, 0x9F, 0xF6, 0x3E, 0x9F, 0x60, 0xE0, 0xEF, 0x48, 0xE9, 0x90, 0x45, + 0x1E, 0x05, 0x51, 0x78, 0x1A, 0x2C, 0x12, 0x2C, 0x5C, 0x28, 0xAC, 0x0D, + 0xA2, 0x23, 0x9E, 0x34, 0x8F, 0x05, 0xE6, 0xA2, 0x33, 0xCE, 0x11, 0x77, + 0x13, 0xD4, 0x0E, 0xA4, 0x1E, 0x42, 0x1F, 0x86, 0xCD, 0x70, 0xFE, 0xD9, + 0x2E, 0x15, 0x3D, 0x1D, 0xBB, 0xB8, 0xF2, 0x53, 0x57, 0xDB, 0xCC, 0xC6, + 0x74, 0x29, 0x9C, 0x18, 0xB3, 0x36, 0x75, 0x38, 0x2E, 0x0F, 0x54, 0xA1, + 0xF8, 0x92, 0x1F, 0x89, 0x96, 0x4F, 0xBB, 0xD4, 0xEE, 0x9D, 0xE9, 0x3B, + 0x36, 0x42, 0xB5, 0x0A, 0x3B, 0x2A, 0xD4, 0x64, 0x79, 0x36, 0x10, 0xE1, + 0xF9, 0x91, 0x03, 0x2B, 0x7B, 0x20, 0x54, 0xCD, 0x0D, 0x19, 0x1A, 0xC8, + 0x41, 0x32, 0x34, 0xD1, 0xB0, 0x99, 0xE1, 0x90, 0x1E, 0x01, 0x40, 0x36, + 0xB5, 0xB7, 0xFA, 0xA9, 0xE5, 0x77, 0x75, 0xA4, 0x22, 0x81, 0x5D, 0xB0, + 0x8B, 0xE4, 0x27, 0x12, 0x0F, 0x54, 0x88, 0xC6, 0xDB, 0x85, 0x74, 0xE6, + 0xB7, 0xC0, 0xD7, 0xA6, 0x29, 0xFA, 0xDB, 0xDE, 0xF3, 0x93, 0x97, 0x27, + 0x04, 0x55, 0x2F, 0x0A, 0x6F, 0x37, 0xC5, 0x3D, 0x13, 0xAF, 0x0A, 0x00, + 0xA9, 0x2C, 0x8B, 0x1C, 0x81, 0x28, 0xD7, 0xEF, 0x86, 0x31, 0xA9, 0xAE, + 0xF2, 0x6E, 0xB8, 0xCA, 0x6A, 0x2C, 0x54, 0x47, 0xD8, 0x2A, 0x88, 0x2E, + 0xAF, 0xC1, 0x07, 0x10, 0x78, 0xAC, 0x11, 0xA2, 0x2F, 0x42, 0xF0, 0x37, + 0xC5, 0xF2, 0xB8, 0x56, 0xDD, 0x0E, 0x62, 0x2D, 0xCE, 0x2D, 0x56, 0x7E, + 0x55, 0xF2, 0xA7, 0x44, 0xF6, 0x2B, 0x32, 0xF4, 0x23, 0xA8, 0x47, 0xE8, + 0xD4, 0x2A, 0x01, 0x78, 0xCF, 0x6A, 0xC3, 0x37, 0xA8, 0x9E, 0x65, 0xD2, + 0x2C, 0xE5, 0xFA, 0xBA, 0x33, 0xC1, 0x06, 0x44, 0xF6, 0xE6, 0xCF, 0xA5, + 0x0D, 0xA7, 0x66, 0x08, 0x34, 0x8A, 0x2C, 0xF3 +}; + +static const unsigned char TA622_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA623_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x65, 0x2D, 0x53, 0x7A, 0x69, + 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x32, 0x30, 0x30, 0x39, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x65, 0x2D, 0x73, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x2E, 0x68, + 0x75 +}; + +static const unsigned char TA623_RSA_N[] = { + 0xE9, 0xF8, 0x8F, 0xF3, 0x63, 0xAD, 0xDA, 0x86, 0xD8, 0xA7, 0xE0, 0x42, + 0xFB, 0xCF, 0x91, 0xDE, 0xA6, 0x26, 0xF8, 0x99, 0xA5, 0x63, 0x70, 0xAD, + 0x9B, 0xAE, 0xCA, 0x33, 0x40, 0x7D, 0x6D, 0x96, 0x6E, 0xA1, 0x0E, 0x44, + 0xEE, 0xE1, 0x13, 0x9D, 0x94, 0x42, 0x52, 0x9A, 0xBD, 0x75, 0x85, 0x74, + 0x2C, 0xA8, 0x0E, 0x1D, 0x93, 0xB6, 0x18, 0xB7, 0x8C, 0x2C, 0xA8, 0xCF, + 0xFB, 0x5C, 0x71, 0xB9, 0xDA, 0xEC, 0xFE, 0xE8, 0x7E, 0x8F, 0xE4, 0x2F, + 0x1D, 0xB2, 0xA8, 0x75, 0x87, 0xD8, 0xB7, 0xA1, 0xE5, 0x3B, 0xCF, 0x99, + 0x4A, 0x46, 0xD0, 0x83, 0x19, 0x7D, 0xC0, 0xA1, 0x12, 0x1C, 0x95, 0x6D, + 0x4A, 0xF4, 0xD8, 0xC7, 0xA5, 0x4D, 0x33, 0x2E, 0x85, 0x39, 0x40, 0x75, + 0x7E, 0x14, 0x7C, 0x80, 0x12, 0x98, 0x50, 0xC7, 0x41, 0x67, 0xB8, 0xA0, + 0x80, 0x61, 0x54, 0xA6, 0x6C, 0x4E, 0x1F, 0xE0, 0x9D, 0x0E, 0x07, 0xE9, + 0xC9, 0xBA, 0x33, 0xE7, 0xFE, 0xC0, 0x55, 0x28, 0x2C, 0x02, 0x80, 0xA7, + 0x19, 0xF5, 0x9E, 0xDC, 0x55, 0x53, 0x03, 0x97, 0x7B, 0x07, 0x48, 0xFF, + 0x99, 0xFB, 0x37, 0x8A, 0x24, 0xC4, 0x59, 0xCC, 0x50, 0x10, 0x63, 0x8E, + 0xAA, 0xA9, 0x1A, 0xB0, 0x84, 0x1A, 0x86, 0xF9, 0x5F, 0xBB, 0xB1, 0x50, + 0x6E, 0xA4, 0xD1, 0x0A, 0xCC, 0xD5, 0x71, 0x7E, 0x1F, 0xA7, 0x1B, 0x7C, + 0xF5, 0x53, 0x6E, 0x22, 0x5F, 0xCB, 0x2B, 0xE6, 0xD4, 0x7C, 0x5D, 0xAE, + 0xD6, 0xC2, 0xC6, 0x4C, 0xE5, 0x05, 0x01, 0xD9, 0xED, 0x57, 0xFC, 0xC1, + 0x23, 0x79, 0xFC, 0xFA, 0xC8, 0x24, 0x83, 0x95, 0xF3, 0xB5, 0x6A, 0x51, + 0x01, 0xD0, 0x77, 0xD6, 0xE9, 0x12, 0xA1, 0xF9, 0x1A, 0x83, 0xFB, 0x82, + 0x1B, 0xB9, 0xB0, 0x97, 0xF4, 0x76, 0x06, 0x33, 0x43, 0x49, 0xA0, 0xFF, + 0x0B, 0xB5, 0xFA, 0xB5 +}; + +static const unsigned char TA623_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA624_DN[] = { + 0x30, 0x71, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, 0x63, + 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0E, 0x56, 0x41, 0x54, + 0x48, 0x55, 0x2D, 0x32, 0x33, 0x35, 0x38, 0x34, 0x34, 0x39, 0x37, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x15, 0x65, 0x2D, + 0x53, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA624_EC_Q[] = { + 0x04, 0x96, 0xDC, 0x3D, 0x8A, 0xD8, 0xB0, 0x7B, 0x6F, 0xC6, 0x27, 0xBE, + 0x44, 0x90, 0xB1, 0xB3, 0x56, 0x15, 0x7B, 0x8E, 0x43, 0x24, 0x7D, 0x1A, + 0x84, 0x59, 0xEE, 0x63, 0x68, 0xB2, 0xC6, 0x5E, 0x87, 0xD0, 0x15, 0x48, + 0x1E, 0xA8, 0x90, 0xAD, 0xBD, 0x53, 0xA2, 0xDA, 0xDE, 0x3A, 0x90, 0xA6, + 0x60, 0x5F, 0x68, 0x32, 0xB5, 0x86, 0x41, 0xDF, 0x87, 0x5B, 0x2C, 0x7B, + 0xC5, 0xFE, 0x7C, 0x7A, 0xDA +}; + +static const unsigned char TA625_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA625_RSA_N[] = { + 0xA5, 0xDA, 0x0A, 0x95, 0x16, 0x50, 0xE3, 0x95, 0xF2, 0x5E, 0x9D, 0x76, + 0x31, 0x06, 0x32, 0x7A, 0x9B, 0xF1, 0x10, 0x76, 0xB8, 0x00, 0x9A, 0xB5, + 0x52, 0x36, 0xCD, 0x24, 0x47, 0xB0, 0x9F, 0x18, 0x64, 0xBC, 0x9A, 0xF6, + 0xFA, 0xD5, 0x79, 0xD8, 0x90, 0x62, 0x4C, 0x22, 0x2F, 0xDE, 0x38, 0x3D, + 0xD6, 0xE0, 0xA8, 0xE9, 0x1C, 0x2C, 0xDB, 0x78, 0x11, 0xE9, 0x8E, 0x68, + 0x51, 0x15, 0x72, 0xC7, 0xF3, 0x33, 0x87, 0xE4, 0xA0, 0x5D, 0x0B, 0x5C, + 0xE0, 0x57, 0x07, 0x2A, 0x30, 0xF5, 0xCD, 0xC4, 0x37, 0x77, 0x28, 0x4D, + 0x18, 0x91, 0xE6, 0xBF, 0xD5, 0x52, 0xFD, 0x71, 0x2D, 0x70, 0x3E, 0xE7, + 0xC6, 0xC4, 0x8A, 0xE3, 0xF0, 0x28, 0x0B, 0xF4, 0x76, 0x98, 0xA1, 0x8B, + 0x87, 0x55, 0xB2, 0x3A, 0x13, 0xFC, 0xB7, 0x3E, 0x27, 0x37, 0x8E, 0x22, + 0xE3, 0xA8, 0x4F, 0x2A, 0xEF, 0x60, 0xBB, 0x3D, 0xB7, 0x39, 0xC3, 0x0E, + 0x01, 0x47, 0x99, 0x5D, 0x12, 0x4F, 0xDB, 0x43, 0xFA, 0x57, 0xA1, 0xED, + 0xF9, 0x9D, 0xBE, 0x11, 0x47, 0x26, 0x5B, 0x13, 0x98, 0xAB, 0x5D, 0x16, + 0x8A, 0xB0, 0x37, 0x1C, 0x57, 0x9D, 0x45, 0xFF, 0x88, 0x96, 0x36, 0xBF, + 0xBB, 0xCA, 0x07, 0x7B, 0x6F, 0x87, 0x63, 0xD7, 0xD0, 0x32, 0x6A, 0xD6, + 0x5D, 0x6C, 0x0C, 0xF1, 0xB3, 0x6E, 0x39, 0xE2, 0x6B, 0x31, 0x2E, 0x39, + 0x00, 0x27, 0x14, 0xDE, 0x38, 0xC0, 0xEC, 0x19, 0x66, 0x86, 0x12, 0xE8, + 0x9D, 0x72, 0x16, 0x13, 0x64, 0x52, 0xC7, 0xA9, 0x37, 0x1C, 0xFD, 0x82, + 0x30, 0xED, 0x84, 0x18, 0x1D, 0xF4, 0xAE, 0x5C, 0xFF, 0x70, 0x13, 0x00, + 0xEB, 0xB1, 0xF5, 0x33, 0x7A, 0x4B, 0xD6, 0x55, 0xF8, 0x05, 0x8D, 0x4B, + 0x69, 0xB0, 0xF5, 0xB3, 0x28, 0x36, 0x5C, 0x14, 0xC4, 0x51, 0x73, 0x4D, + 0x6B, 0x0B, 0xF1, 0x34, 0x07, 0xDB, 0x17, 0x39, 0xD7, 0xDC, 0x28, 0x7B, + 0x6B, 0xF5, 0x9F, 0xF3, 0x2E, 0xC1, 0x4F, 0x17, 0x2A, 0x10, 0xF3, 0xCC, + 0xCA, 0xE8, 0xEB, 0xFD, 0x6B, 0xAB, 0x2E, 0x9A, 0x9F, 0x2D, 0x82, 0x6E, + 0x04, 0xD4, 0x52, 0x01, 0x93, 0x2D, 0x3D, 0x86, 0xFC, 0x7E, 0xFC, 0xDF, + 0xEF, 0x42, 0x1D, 0xA6, 0x6B, 0xEF, 0xB9, 0x20, 0xC6, 0xF7, 0xBD, 0xA0, + 0xA7, 0x95, 0xFD, 0xA7, 0xE6, 0x89, 0x24, 0xD8, 0xCC, 0x8C, 0x34, 0x6C, + 0xE2, 0x23, 0x2F, 0xD9, 0x12, 0x1A, 0x21, 0xB9, 0x55, 0x91, 0x6F, 0x0B, + 0x91, 0x79, 0x19, 0x0C, 0xAD, 0x40, 0x88, 0x0B, 0x70, 0xE2, 0x7A, 0xD2, + 0x0E, 0xD8, 0x68, 0x48, 0xBB, 0x82, 0x13, 0x39, 0x10, 0x58, 0xE9, 0xD8, + 0x2A, 0x07, 0xC6, 0x12, 0xDB, 0x58, 0xDB, 0xD2, 0x3B, 0x55, 0x10, 0x47, + 0x05, 0x15, 0x67, 0x62, 0x7E, 0x18, 0x63, 0xA6, 0x46, 0x3F, 0x09, 0x0E, + 0x54, 0x32, 0x5E, 0xBF, 0x0D, 0x62, 0x7A, 0x27, 0xEF, 0x80, 0xE8, 0xDB, + 0xD9, 0x4B, 0x06, 0x5A, 0x37, 0x5A, 0x25, 0xD0, 0x08, 0x12, 0x77, 0xD4, + 0x6F, 0x09, 0x50, 0x97, 0x3D, 0xC8, 0x1D, 0xC3, 0xDF, 0x8C, 0x45, 0x30, + 0x56, 0xC6, 0xD3, 0x64, 0xAB, 0x66, 0xF3, 0xC0, 0x5E, 0x96, 0x9C, 0xC3, + 0xC4, 0xEF, 0xC3, 0x7C, 0x6B, 0x8B, 0x3A, 0x79, 0x7F, 0xB3, 0x49, 0xCF, + 0x3D, 0xE2, 0x89, 0x9F, 0xA0, 0x30, 0x4B, 0x85, 0xB9, 0x9C, 0x94, 0x24, + 0x79, 0x8F, 0x7D, 0x6B, 0xA9, 0x45, 0x68, 0x0F, 0x2B, 0xD0, 0xF1, 0xDA, + 0x1C, 0xCB, 0x69, 0xB8, 0xCA, 0x49, 0x62, 0x6D, 0xC8, 0xD0, 0x63, 0x62, + 0xDD, 0x60, 0x0F, 0x58, 0xAA, 0x8F, 0xA1, 0xBC, 0x05, 0xA5, 0x66, 0xA2, + 0xCF, 0x1B, 0x76, 0xB2, 0x84, 0x64, 0xB1, 0x4C, 0x39, 0x52, 0xC0, 0x30, + 0xBA, 0xF0, 0x8C, 0x4B, 0x02, 0xB0, 0xB6, 0xB7 +}; + +static const unsigned char TA625_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA626_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, + 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA626_EC_Q[] = { + 0x04, 0x38, 0x08, 0xFE, 0xB1, 0xA0, 0x96, 0xD2, 0x7A, 0xAC, 0xAF, 0x49, + 0x3A, 0xD0, 0xC0, 0xE0, 0xC3, 0x3B, 0x28, 0xAA, 0xF1, 0x72, 0x6D, 0x65, + 0x00, 0x47, 0x88, 0x84, 0xFC, 0x9A, 0x26, 0x6B, 0xAA, 0x4B, 0xBA, 0x6C, + 0x04, 0x0A, 0x88, 0x5E, 0x17, 0xF2, 0x55, 0x87, 0xFC, 0x30, 0xB0, 0x34, + 0xE2, 0x34, 0x58, 0x57, 0x1A, 0x84, 0x53, 0xE9, 0x30, 0xD9, 0xA9, 0xF2, + 0x96, 0x74, 0xC3, 0x51, 0x1F, 0x58, 0x49, 0x31, 0xCC, 0x98, 0x4E, 0x60, + 0x11, 0x87, 0x75, 0xD3, 0x72, 0x94, 0x90, 0x4F, 0x9B, 0x10, 0x25, 0x2A, + 0xA8, 0x78, 0x2D, 0xBE, 0x90, 0x41, 0x58, 0x90, 0x15, 0x72, 0xA7, 0xA1, + 0xB7 +}; + +static const unsigned char TA627_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x33 +}; + +static const unsigned char TA627_EC_Q[] = { + 0x04, 0xDD, 0xA7, 0xD9, 0xBB, 0x8A, 0xB8, 0x0B, 0xFB, 0x0B, 0x7F, 0x21, + 0xD2, 0xF0, 0xBE, 0xBE, 0x73, 0xF3, 0x33, 0x5D, 0x1A, 0xBC, 0x34, 0xEA, + 0xDE, 0xC6, 0x9B, 0xBC, 0xD0, 0x95, 0xF6, 0xF0, 0xCC, 0xD0, 0x0B, 0xBA, + 0x61, 0x5B, 0x51, 0x46, 0x7E, 0x9E, 0x2D, 0x9F, 0xEE, 0x8E, 0x63, 0x0C, + 0x17, 0xEC, 0x07, 0x70, 0xF5, 0xCF, 0x84, 0x2E, 0x40, 0x83, 0x9C, 0xE8, + 0x3F, 0x41, 0x6D, 0x3B, 0xAD, 0xD3, 0xA4, 0x14, 0x59, 0x36, 0x78, 0x9D, + 0x03, 0x43, 0xEE, 0x10, 0x13, 0x6C, 0x72, 0xDE, 0xAE, 0x88, 0xA7, 0xA1, + 0x6B, 0xB5, 0x43, 0xCE, 0x67, 0xDC, 0x23, 0xFF, 0x03, 0x1C, 0xA3, 0xE2, + 0x3E +}; + +static const unsigned char TA628_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1A, 0x30, + 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA628_EC_Q[] = { + 0x04, 0x65, 0x50, 0x4A, 0xAE, 0x8C, 0x79, 0x96, 0x4A, 0xAA, 0x1C, 0x08, + 0xC3, 0xA3, 0xA2, 0xCD, 0xFE, 0x59, 0x56, 0x41, 0x77, 0xFD, 0x26, 0x94, + 0x42, 0xBB, 0x1D, 0xCD, 0x08, 0xDB, 0x73, 0xB2, 0x5B, 0x75, 0xF3, 0xCF, + 0x9C, 0x4E, 0x82, 0xF4, 0xBF, 0xF8, 0x61, 0x26, 0x85, 0x6C, 0xD6, 0x85, + 0x5B, 0x72, 0x70, 0xD2, 0xFD, 0xDB, 0x62, 0xB4, 0xDF, 0x53, 0x8B, 0xBD, + 0xB1, 0x44, 0x58, 0x62, 0x42, 0x09, 0xC7, 0xFA, 0x7F, 0x5B, 0x10, 0xE7, + 0xFE, 0x40, 0xFD, 0xC0, 0xD8, 0xC3, 0x2B, 0x32, 0xE7, 0x70, 0xA6, 0xB7, + 0xA6, 0x20, 0x55, 0x1D, 0x7B, 0x80, 0x5D, 0x4B, 0x8F, 0x67, 0x4C, 0xF1, + 0x10 +}; + +static const unsigned char TA629_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x28, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA629_RSA_N[] = { + 0xB9, 0x5D, 0x51, 0x28, 0x4B, 0x3C, 0x37, 0x92, 0xD1, 0x82, 0xCE, 0xBD, + 0x1D, 0xBD, 0xCD, 0xDD, 0xB8, 0xAB, 0xCF, 0x0A, 0x3E, 0xE1, 0x5D, 0xE5, + 0xDC, 0xAA, 0x09, 0xB9, 0x57, 0x02, 0x3E, 0xE6, 0x63, 0x61, 0xDF, 0xF2, + 0x0F, 0x82, 0x63, 0xAE, 0xA3, 0xF7, 0xAC, 0x73, 0xD1, 0x7C, 0xE7, 0xB3, + 0x0B, 0xAF, 0x08, 0x00, 0x09, 0x59, 0x7F, 0xCD, 0x29, 0x2A, 0x88, 0x93, + 0x87, 0x17, 0x18, 0x80, 0xED, 0x88, 0xB2, 0xB4, 0xB6, 0x10, 0x1F, 0x2D, + 0xD6, 0x5F, 0x55, 0xA2, 0x13, 0x5D, 0xD1, 0xC6, 0xEB, 0x06, 0x56, 0x89, + 0x88, 0xFE, 0xAC, 0x32, 0x9D, 0xFD, 0x5C, 0xC3, 0x05, 0xC7, 0x6E, 0xEE, + 0x86, 0x89, 0xBA, 0x88, 0x03, 0x9D, 0x72, 0x21, 0x86, 0x90, 0xAE, 0x8F, + 0x03, 0xA5, 0xDC, 0x9F, 0x88, 0x28, 0xCB, 0xA3, 0x92, 0x49, 0x0F, 0xEC, + 0xD0, 0x0F, 0xE2, 0x6D, 0x44, 0x4F, 0x80, 0x6A, 0xB2, 0xD4, 0xE7, 0xA0, + 0x0A, 0x53, 0x01, 0xBA, 0x8E, 0x97, 0x91, 0x76, 0x6E, 0xBC, 0xFC, 0xD5, + 0x6B, 0x36, 0xE6, 0x40, 0x88, 0xD6, 0x7B, 0x2F, 0x5F, 0x05, 0xE8, 0x2C, + 0x6D, 0x11, 0xF3, 0xE7, 0xB2, 0xBE, 0x92, 0x44, 0x4C, 0xD2, 0x97, 0xA4, + 0xFE, 0xD2, 0x72, 0x81, 0x43, 0x07, 0x9C, 0xE9, 0x11, 0x3E, 0xF5, 0x8B, + 0x1A, 0x59, 0x7D, 0x1F, 0x68, 0x58, 0xDD, 0x04, 0x00, 0x2C, 0x96, 0xF3, + 0x43, 0xB3, 0x7E, 0x98, 0x19, 0x74, 0xD9, 0x9C, 0x73, 0xD9, 0x18, 0xBE, + 0x41, 0xC7, 0x34, 0x79, 0xD9, 0xF4, 0x62, 0xC2, 0x43, 0xB9, 0xB3, 0x27, + 0xB0, 0x22, 0xCB, 0xF9, 0x3D, 0x52, 0xC7, 0x30, 0x47, 0xB3, 0xC9, 0x3E, + 0xB8, 0x6A, 0xE2, 0xE7, 0xE8, 0x81, 0x70, 0x5E, 0x42, 0x8B, 0x4F, 0x26, + 0xA5, 0xFE, 0x3A, 0xC2, 0x20, 0x6E, 0xBB, 0xF8, 0x16, 0x8E, 0xCD, 0x0C, + 0xA9, 0xB4, 0x1B, 0x6C, 0x76, 0x10, 0xE1, 0x58, 0x79, 0x46, 0x3E, 0x54, + 0xCE, 0x80, 0xA8, 0x57, 0x09, 0x37, 0x29, 0x1B, 0x99, 0x13, 0x8F, 0x0C, + 0xC8, 0xD6, 0x2C, 0x1C, 0xFB, 0x05, 0xE8, 0x08, 0x95, 0x3D, 0x65, 0x46, + 0xDC, 0xEE, 0xCD, 0x69, 0xE2, 0x4D, 0x8F, 0x87, 0x28, 0x4E, 0x34, 0x0B, + 0x3E, 0xCF, 0x14, 0xD9, 0xBB, 0xDD, 0xB6, 0x50, 0x9A, 0xAD, 0x77, 0xD4, + 0x19, 0xD6, 0xDA, 0x1A, 0x88, 0xC8, 0x4E, 0x1B, 0x27, 0x75, 0xD8, 0xB2, + 0x08, 0xF1, 0xAE, 0x83, 0x30, 0xB9, 0x11, 0x0E, 0xCD, 0x87, 0xF0, 0x84, + 0x8D, 0x15, 0x72, 0x7C, 0xA1, 0xEF, 0xCC, 0xF2, 0x88, 0x61, 0xBA, 0xF4, + 0x69, 0xBB, 0x0C, 0x8C, 0x0B, 0x75, 0x57, 0x04, 0xB8, 0x4E, 0x2A, 0x14, + 0x2E, 0x3D, 0x0F, 0x1C, 0x1E, 0x32, 0xA6, 0x62, 0x36, 0xEE, 0x66, 0xE2, + 0x22, 0xB8, 0x05, 0x40, 0x63, 0x10, 0x22, 0xF3, 0x33, 0x1D, 0x74, 0x72, + 0x8A, 0x2C, 0xF5, 0x39, 0x29, 0xA0, 0xD3, 0xE7, 0x1B, 0x80, 0x84, 0x2D, + 0xC5, 0x3D, 0xE3, 0x4D, 0xB1, 0xFD, 0x1A, 0x6F, 0xBA, 0x65, 0x07, 0x3B, + 0x58, 0xEC, 0x42, 0x45, 0x26, 0xFB, 0xD8, 0xDA, 0x25, 0x72, 0xC4, 0xF6, + 0x00, 0xB1, 0x22, 0x79, 0xBD, 0xE3, 0x7C, 0x59, 0x62, 0x4A, 0x9C, 0x05, + 0x6F, 0x3D, 0xCE, 0xE6, 0xD6, 0x47, 0x63, 0x99, 0xC6, 0x24, 0x6F, 0x72, + 0x12, 0xC8, 0xAC, 0x7F, 0x90, 0xB4, 0x0B, 0x91, 0x70, 0xE8, 0xB7, 0xE6, + 0x16, 0x10, 0x71, 0x17, 0xCE, 0xDE, 0x06, 0x4F, 0x48, 0x41, 0x7D, 0x35, + 0x4A, 0xA3, 0x89, 0xF2, 0xC9, 0x4B, 0x7B, 0x41, 0x11, 0x6D, 0x67, 0xB7, + 0x08, 0x98, 0x4C, 0xE5, 0x11, 0x19, 0xAE, 0x42, 0x80, 0xDC, 0xFB, 0x90, + 0x05, 0xD4, 0xF8, 0x50, 0xCA, 0xBE, 0xE4, 0xAD, 0xC7, 0xC2, 0x94, 0xD7, + 0x16, 0x9D, 0xE6, 0x17, 0x8F, 0xAF, 0x36, 0xFB +}; + +static const unsigned char TA629_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA630_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x33 +}; + +static const unsigned char TA630_RSA_N[] = { + 0xED, 0x35, 0xA1, 0x81, 0x80, 0xF3, 0xCB, 0x4A, 0x69, 0x5B, 0xC2, 0xFB, + 0x51, 0x83, 0xAE, 0x26, 0xFD, 0xE1, 0x6E, 0xF3, 0x81, 0x12, 0x7D, 0x71, + 0x40, 0xFF, 0x87, 0x75, 0x42, 0x29, 0x21, 0xED, 0x81, 0x52, 0x2C, 0xDF, + 0x12, 0xC1, 0x19, 0x84, 0x89, 0xC1, 0xBD, 0xC5, 0x28, 0xD5, 0xD5, 0x4B, + 0x6C, 0x44, 0xD6, 0x4C, 0xDB, 0x07, 0x96, 0x4A, 0x55, 0x7A, 0xCA, 0x36, + 0x82, 0x04, 0x36, 0xA8, 0xA5, 0xFC, 0x27, 0xF6, 0x49, 0xF1, 0xD5, 0x72, + 0x9E, 0x91, 0xF9, 0x23, 0xD6, 0x70, 0x7B, 0xBB, 0xF5, 0x9B, 0xC1, 0xEC, + 0x93, 0xCF, 0x19, 0xEA, 0x65, 0x7E, 0x88, 0x70, 0xA0, 0x73, 0xFC, 0xF6, + 0xFF, 0xB5, 0x56, 0x62, 0xE1, 0x73, 0x6A, 0x34, 0x98, 0x3E, 0x82, 0xB8, + 0xAC, 0x95, 0x53, 0xF4, 0x01, 0xA0, 0x27, 0x07, 0x72, 0xA3, 0x00, 0x53, + 0xA0, 0xE4, 0xB2, 0xAB, 0x83, 0x38, 0x57, 0x33, 0x25, 0x94, 0x9F, 0xBE, + 0x48, 0x1D, 0x98, 0xE1, 0xA3, 0xBA, 0x9E, 0x5C, 0xCD, 0x04, 0x71, 0x51, + 0x7D, 0x75, 0x78, 0xAB, 0xF3, 0x59, 0xAA, 0xC4, 0xE0, 0x60, 0xBE, 0x8F, + 0x83, 0x52, 0xB8, 0x75, 0x1A, 0x41, 0x35, 0xED, 0xBC, 0xF3, 0x3A, 0x63, + 0xE9, 0xA9, 0x14, 0x45, 0xD7, 0xE6, 0x52, 0xD1, 0x6E, 0xD2, 0xDE, 0xBC, + 0xE3, 0xF5, 0x0B, 0x3B, 0xE6, 0xE0, 0xC4, 0xBD, 0x43, 0x64, 0x13, 0xA6, + 0xCE, 0xF4, 0x98, 0x37, 0x6C, 0x8A, 0x95, 0xA8, 0x97, 0xC8, 0x47, 0x0F, + 0xF0, 0x5E, 0x10, 0x8B, 0xE7, 0x1D, 0x1C, 0xFE, 0xB1, 0x3B, 0xA0, 0x05, + 0x33, 0x68, 0x05, 0x41, 0x82, 0xC1, 0x03, 0x2B, 0x01, 0xC8, 0xE7, 0x8F, + 0x4D, 0xAB, 0xE8, 0xB5, 0xF6, 0xCD, 0x6B, 0x44, 0xB5, 0xE7, 0xDD, 0x8B, + 0xEC, 0xEA, 0x25, 0xB4, 0x00, 0x22, 0x57, 0x4D, 0xB0, 0xB1, 0xB2, 0x31, + 0xC1, 0x16, 0xCE, 0xFF, 0xFD, 0x14, 0x84, 0xB7, 0x47, 0xFA, 0xB2, 0xF1, + 0x70, 0xDE, 0xDB, 0x8B, 0x6C, 0x36, 0x58, 0xA4, 0x7C, 0xB3, 0x11, 0xD1, + 0xC3, 0x77, 0x7F, 0x5F, 0xB6, 0x25, 0xE0, 0x0D, 0xC5, 0xD2, 0xB3, 0xF9, + 0xB8, 0xB8, 0x77, 0xDB, 0x37, 0x71, 0x71, 0x47, 0xE3, 0x60, 0x18, 0x4F, + 0x24, 0xB6, 0x75, 0x37, 0x78, 0xB9, 0xA3, 0x62, 0xAF, 0xBD, 0xC9, 0x72, + 0x8E, 0x2F, 0xCC, 0xBB, 0xAE, 0xDB, 0xE4, 0x15, 0x52, 0x19, 0x07, 0x33, + 0xFB, 0x6A, 0xB7, 0x2D, 0x4B, 0x90, 0x28, 0x82, 0x73, 0xFE, 0x18, 0x8B, + 0x35, 0x8D, 0xDB, 0xA7, 0x04, 0x6A, 0xBE, 0xEA, 0xC1, 0x4D, 0x36, 0x3B, + 0x16, 0x36, 0x91, 0x32, 0xEF, 0xB6, 0x40, 0x89, 0x91, 0x43, 0xE0, 0xF2, + 0xA2, 0xAB, 0x04, 0x2E, 0xE6, 0xF2, 0x4C, 0x0E, 0x16, 0x34, 0x20, 0xAC, + 0x87, 0xC1, 0x2D, 0x7E, 0xC9, 0x66, 0x47, 0x17, 0x14, 0x11, 0xA4, 0xF3, + 0xF7, 0xA1, 0x24, 0x89, 0xAB, 0xD8, 0x1A, 0xC8, 0xA1, 0x5C, 0xB1, 0xA3, + 0xF7, 0x8C, 0x6D, 0xC8, 0x01, 0xC9, 0x4F, 0xC9, 0xEC, 0xC4, 0xFC, 0xAC, + 0x51, 0x33, 0xD1, 0xC8, 0x83, 0xD1, 0xC9, 0x9F, 0x1D, 0xD4, 0x47, 0x34, + 0x29, 0x3E, 0xCB, 0xB0, 0x0E, 0xFA, 0x83, 0x0B, 0x28, 0x58, 0xE5, 0x29, + 0xDC, 0x3F, 0x7C, 0xA8, 0x9F, 0xC9, 0xB6, 0x0A, 0xBB, 0xA6, 0xE8, 0x46, + 0x16, 0x0F, 0x96, 0xE5, 0x7B, 0xE4, 0x6A, 0x7A, 0x48, 0x6D, 0x76, 0x98, + 0x05, 0xA5, 0xDC, 0x6D, 0x1E, 0x42, 0x1E, 0x42, 0xDA, 0x1A, 0xE0, 0x52, + 0xF7, 0xB5, 0x83, 0xC0, 0x1A, 0x7B, 0x78, 0x35, 0x2C, 0x38, 0xF5, 0x1F, + 0xFD, 0x49, 0xA3, 0x2E, 0xD2, 0x59, 0x63, 0xBF, 0x80, 0xB0, 0x8C, 0x93, + 0x73, 0xCB, 0x35, 0xA6, 0x99, 0x95, 0x22, 0x61, 0x65, 0x03, 0x60, 0xFB, + 0x2F, 0x93, 0x4B, 0xFA, 0x9A, 0x9C, 0x80, 0x3B +}; + +static const unsigned char TA630_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA631_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1A, 0x30, + 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA631_EC_Q[] = { + 0x04, 0x65, 0x50, 0x4A, 0xAE, 0x8C, 0x79, 0x96, 0x4A, 0xAA, 0x1C, 0x08, + 0xC3, 0xA3, 0xA2, 0xCD, 0xFE, 0x59, 0x56, 0x41, 0x77, 0xFD, 0x26, 0x94, + 0x42, 0xBB, 0x1D, 0xCD, 0x08, 0xDB, 0x73, 0xB2, 0x5B, 0x75, 0xF3, 0xCF, + 0x9C, 0x4E, 0x82, 0xF4, 0xBF, 0xF8, 0x61, 0x26, 0x85, 0x6C, 0xD6, 0x85, + 0x5B, 0x72, 0x70, 0xD2, 0xFD, 0xDB, 0x62, 0xB4, 0xDF, 0x53, 0x8B, 0xBD, + 0xB1, 0x44, 0x58, 0x62, 0x42, 0x09, 0xC7, 0xFA, 0x7F, 0x5B, 0x10, 0xE7, + 0xFE, 0x40, 0xFD, 0xC0, 0xD8, 0xC3, 0x2B, 0x32, 0xE7, 0x70, 0xA6, 0xB7, + 0xA6, 0x20, 0x55, 0x1D, 0x7B, 0x80, 0x5D, 0x4B, 0x8F, 0x67, 0x4C, 0xF1, + 0x10 +}; + +static const unsigned char TA632_DN[] = { + 0x30, 0x7B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, 0x61, + 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x53, 0x61, 0x6C, 0x66, 0x6F, + 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x11, 0x43, 0x6F, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x43, 0x41, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x18, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73 +}; + +static const unsigned char TA632_RSA_N[] = { + 0xBE, 0x40, 0x9D, 0xF4, 0x6E, 0xE1, 0xEA, 0x76, 0x87, 0x1C, 0x4D, 0x45, + 0x44, 0x8E, 0xBE, 0x46, 0xC8, 0x83, 0x06, 0x9D, 0xC1, 0x2A, 0xFE, 0x18, + 0x1F, 0x8E, 0xE4, 0x02, 0xFA, 0xF3, 0xAB, 0x5D, 0x50, 0x8A, 0x16, 0x31, + 0x0B, 0x9A, 0x06, 0xD0, 0xC5, 0x70, 0x22, 0xCD, 0x49, 0x2D, 0x54, 0x63, + 0xCC, 0xB6, 0x6E, 0x68, 0x46, 0x0B, 0x53, 0xEA, 0xCB, 0x4C, 0x24, 0xC0, + 0xBC, 0x72, 0x4E, 0xEA, 0xF1, 0x15, 0xAE, 0xF4, 0x54, 0x9A, 0x12, 0x0A, + 0xC3, 0x7A, 0xB2, 0x33, 0x60, 0xE2, 0xDA, 0x89, 0x55, 0xF3, 0x22, 0x58, + 0xF3, 0xDE, 0xDC, 0xCF, 0xEF, 0x83, 0x86, 0xA2, 0x8C, 0x94, 0x4F, 0x9F, + 0x68, 0xF2, 0x98, 0x90, 0x46, 0x84, 0x27, 0xC7, 0x76, 0xBF, 0xE3, 0xCC, + 0x35, 0x2C, 0x8B, 0x5E, 0x07, 0x64, 0x65, 0x82, 0xC0, 0x48, 0xB0, 0xA8, + 0x91, 0xF9, 0x61, 0x9F, 0x76, 0x20, 0x50, 0xA8, 0x91, 0xC7, 0x66, 0xB5, + 0xEB, 0x78, 0x62, 0x03, 0x56, 0xF0, 0x8A, 0x1A, 0x13, 0xEA, 0x31, 0xA3, + 0x1E, 0xA0, 0x99, 0xFD, 0x38, 0xF6, 0xF6, 0x27, 0x32, 0x58, 0x6F, 0x07, + 0xF5, 0x6B, 0xB8, 0xFB, 0x14, 0x2B, 0xAF, 0xB7, 0xAA, 0xCC, 0xD6, 0x63, + 0x5F, 0x73, 0x8C, 0xDA, 0x05, 0x99, 0xA8, 0x38, 0xA8, 0xCB, 0x17, 0x78, + 0x36, 0x51, 0xAC, 0xE9, 0x9E, 0xF4, 0x78, 0x3A, 0x8D, 0xCF, 0x0F, 0xD9, + 0x42, 0xE2, 0x98, 0x0C, 0xAB, 0x2F, 0x9F, 0x0E, 0x01, 0xDE, 0xEF, 0x9F, + 0x99, 0x49, 0xF1, 0x2D, 0xDF, 0xAC, 0x74, 0x4D, 0x1B, 0x98, 0xB5, 0x47, + 0xC5, 0xE5, 0x29, 0xD1, 0xF9, 0x90, 0x18, 0xC7, 0x62, 0x9C, 0xBE, 0x83, + 0xC7, 0x26, 0x7B, 0x3E, 0x8A, 0x25, 0xC7, 0xC0, 0xDD, 0x9D, 0xE6, 0x35, + 0x68, 0x10, 0x20, 0x9D, 0x8F, 0xD8, 0xDE, 0xD2, 0xC3, 0x84, 0x9C, 0x0D, + 0x5E, 0xE8, 0x2F, 0xC9 +}; + +static const unsigned char TA632_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA633_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA633_EC_Q[] = { + 0x04, 0x03, 0x47, 0x7B, 0x2F, 0x75, 0xC9, 0x82, 0x15, 0x85, 0xFB, 0x75, + 0xE4, 0x91, 0x16, 0xD4, 0xAB, 0x62, 0x99, 0xF5, 0x3E, 0x52, 0x0B, 0x06, + 0xCE, 0x41, 0x00, 0x7F, 0x97, 0xE1, 0x0A, 0x24, 0x3C, 0x1D, 0x01, 0x04, + 0xEE, 0x3D, 0xD2, 0x8D, 0x09, 0x97, 0x0C, 0xE0, 0x75, 0xE4, 0xFA, 0xFB, + 0x77, 0x8A, 0x2A, 0xF5, 0x03, 0x60, 0x4B, 0x36, 0x8B, 0x16, 0x23, 0x16, + 0xAD, 0x09, 0x71, 0xF4, 0x4A, 0xF4, 0x28, 0x50, 0xB4, 0xFE, 0x88, 0x1C, + 0x6E, 0x3F, 0x6C, 0x2F, 0x2F, 0x09, 0x59, 0x5B, 0xA5, 0x5B, 0x0B, 0x33, + 0x99, 0xE2, 0xC3, 0x3D, 0x89, 0xF9, 0x6A, 0x2C, 0xEF, 0xB2, 0xD3, 0x06, + 0xE9 +}; + +static const unsigned char TA634_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6F, 0x6D, 0x6D, + 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA634_RSA_N[] = { + 0xA7, 0x50, 0x19, 0xDE, 0x3F, 0x99, 0x3D, 0xD4, 0x33, 0x46, 0xF1, 0x6F, + 0x51, 0x61, 0x82, 0xB2, 0xA9, 0x4F, 0x8F, 0x67, 0x89, 0x5D, 0x84, 0xD9, + 0x53, 0xDD, 0x0C, 0x28, 0xD9, 0xD7, 0xF0, 0xFF, 0xAE, 0x95, 0x43, 0x72, + 0x99, 0xF9, 0xB5, 0x5D, 0x7C, 0x8A, 0xC1, 0x42, 0xE1, 0x31, 0x50, 0x74, + 0xD1, 0x81, 0x0D, 0x7C, 0xCD, 0x9B, 0x21, 0xAB, 0x43, 0xE2, 0xAC, 0xAD, + 0x5E, 0x86, 0x6E, 0xF3, 0x09, 0x8A, 0x1F, 0x5A, 0x32, 0xBD, 0xA2, 0xEB, + 0x94, 0xF9, 0xE8, 0x5C, 0x0A, 0xEC, 0xFF, 0x98, 0xD2, 0xAF, 0x71, 0xB3, + 0xB4, 0x53, 0x9F, 0x4E, 0x87, 0xEF, 0x92, 0xBC, 0xBD, 0xEC, 0x4F, 0x32, + 0x30, 0x88, 0x4B, 0x17, 0x5E, 0x57, 0xC4, 0x53, 0xC2, 0xF6, 0x02, 0x97, + 0x8D, 0xD9, 0x62, 0x2B, 0xBF, 0x24, 0x1F, 0x62, 0x8D, 0xDF, 0xC3, 0xB8, + 0x29, 0x4B, 0x49, 0x78, 0x3C, 0x93, 0x60, 0x88, 0x22, 0xFC, 0x99, 0xDA, + 0x36, 0xC8, 0xC2, 0xA2, 0xD4, 0x2C, 0x54, 0x00, 0x67, 0x35, 0x6E, 0x73, + 0xBF, 0x02, 0x58, 0xF0, 0xA4, 0xDD, 0xE5, 0xB0, 0xA2, 0x26, 0x7A, 0xCA, + 0xE0, 0x36, 0xA5, 0x19, 0x16, 0xF5, 0xFD, 0xB7, 0xEF, 0xAE, 0x3F, 0x40, + 0xF5, 0x6D, 0x5A, 0x04, 0xFD, 0xCE, 0x34, 0xCA, 0x24, 0xDC, 0x74, 0x23, + 0x1B, 0x5D, 0x33, 0x13, 0x12, 0x5D, 0xC4, 0x01, 0x25, 0xF6, 0x30, 0xDD, + 0x02, 0x5D, 0x9F, 0xE0, 0xD5, 0x47, 0xBD, 0xB4, 0xEB, 0x1B, 0xA1, 0xBB, + 0x49, 0x49, 0xD8, 0x9F, 0x5B, 0x02, 0xF3, 0x8A, 0xE4, 0x24, 0x90, 0xE4, + 0x62, 0x4F, 0x4F, 0xC1, 0xAF, 0x8B, 0x0E, 0x74, 0x17, 0xA8, 0xD1, 0x72, + 0x88, 0x6A, 0x7A, 0x01, 0x49, 0xCC, 0xB4, 0x46, 0x79, 0xC6, 0x17, 0xB1, + 0xDA, 0x98, 0x1E, 0x07, 0x59, 0xFA, 0x75, 0x21, 0x85, 0x65, 0xDD, 0x90, + 0x56, 0xCE, 0xFB, 0xAB, 0xA5, 0x60, 0x9D, 0xC4, 0x9D, 0xF9, 0x52, 0xB0, + 0x8B, 0xBD, 0x87, 0xF9, 0x8F, 0x2B, 0x23, 0x0A, 0x23, 0x76, 0x3B, 0xF7, + 0x33, 0xE1, 0xC9, 0x00, 0xF3, 0x69, 0xF9, 0x4B, 0xA2, 0xE0, 0x4E, 0xBC, + 0x7E, 0x93, 0x39, 0x84, 0x07, 0xF7, 0x44, 0x70, 0x7E, 0xFE, 0x07, 0x5A, + 0xE5, 0xB1, 0xAC, 0xD1, 0x18, 0xCC, 0xF2, 0x35, 0xE5, 0x49, 0x49, 0x08, + 0xCA, 0x56, 0xC9, 0x3D, 0xFB, 0x0F, 0x18, 0x7D, 0x8B, 0x3B, 0xC1, 0x13, + 0xC2, 0x4D, 0x8F, 0xC9, 0x4F, 0x0E, 0x37, 0xE9, 0x1F, 0xA1, 0x0E, 0x6A, + 0xDF, 0x62, 0x2E, 0xCB, 0x35, 0x06, 0x51, 0x79, 0x2C, 0xC8, 0x25, 0x38, + 0xF4, 0xFA, 0x4B, 0xA7, 0x89, 0x5C, 0x9C, 0xD2, 0xE3, 0x0D, 0x39, 0x86, + 0x4A, 0x74, 0x7C, 0xD5, 0x59, 0x87, 0xC2, 0x3F, 0x4E, 0x0C, 0x5C, 0x52, + 0xF4, 0x3D, 0xF7, 0x52, 0x82, 0xF1, 0xEA, 0xA3, 0xAC, 0xFD, 0x49, 0x34, + 0x1A, 0x28, 0xF3, 0x41, 0x88, 0x3A, 0x13, 0xEE, 0xE8, 0xDE, 0xFF, 0x99, + 0x1D, 0x5F, 0xBA, 0xCB, 0xE8, 0x1E, 0xF2, 0xB9, 0x50, 0x60, 0xC0, 0x31, + 0xD3, 0x73, 0xE5, 0xEF, 0xBE, 0xA0, 0xED, 0x33, 0x0B, 0x74, 0xBE, 0x20, + 0x20, 0xC4, 0x67, 0x6C, 0xF0, 0x08, 0x03, 0x7A, 0x55, 0x80, 0x7F, 0x46, + 0x4E, 0x96, 0xA7, 0xF4, 0x1E, 0x3E, 0xE1, 0xF6, 0xD8, 0x09, 0xE1, 0x33, + 0x64, 0x2B, 0x63, 0xD7, 0x32, 0x5E, 0x9F, 0xF9, 0xC0, 0x7B, 0x0F, 0x78, + 0x6F, 0x97, 0xBC, 0x93, 0x9A, 0xF9, 0x9C, 0x12, 0x90, 0x78, 0x7A, 0x80, + 0x87, 0x15, 0xD7, 0x72, 0x74, 0x9C, 0x55, 0x74, 0x78, 0xB1, 0xBA, 0xE1, + 0x6E, 0x70, 0x04, 0xBA, 0x4F, 0xA0, 0xBA, 0x68, 0xC3, 0x7B, 0xFF, 0x31, + 0xF0, 0x73, 0x3D, 0x3D, 0x94, 0x2A, 0xB1, 0x0B, 0x41, 0x0E, 0xA0, 0xFE, + 0x4D, 0x88, 0x65, 0x6B, 0x79, 0x33, 0xB4, 0xD7 +}; + +static const unsigned char TA634_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA635_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x43, 0x33 +}; + +static const unsigned char TA635_EC_Q[] = { + 0x04, 0xFD, 0xA5, 0x61, 0xAE, 0x7B, 0x26, 0x10, 0x1D, 0xE9, 0xB7, 0x22, + 0x30, 0xAE, 0x06, 0xF4, 0x81, 0xB3, 0xB1, 0x42, 0x71, 0x95, 0x39, 0xBC, + 0xD3, 0x52, 0xE3, 0xAF, 0xAF, 0xF9, 0xF2, 0x97, 0x35, 0x92, 0x36, 0x46, + 0x0E, 0x87, 0x95, 0x8D, 0xB9, 0x39, 0x5A, 0xE9, 0xBB, 0xDF, 0xD0, 0xFE, + 0xC8, 0x07, 0x41, 0x3C, 0xBB, 0x55, 0x6F, 0x83, 0xA3, 0x6A, 0xFB, 0x62, + 0xB0, 0x81, 0x89, 0x02, 0x70, 0x7D, 0x48, 0xC5, 0x4A, 0xE3, 0xE9, 0x22, + 0x54, 0x22, 0x4D, 0x93, 0xBB, 0x42, 0x0C, 0xAF, 0x77, 0x9C, 0x23, 0xA6, + 0x7D, 0xD7, 0x61, 0x11, 0xCE, 0x65, 0xC7, 0xF8, 0x7F, 0xFE, 0xF5, 0xF2, + 0xA9 +}; + +static const unsigned char TA636_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x17, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, + 0x33 +}; + +static const unsigned char TA636_EC_Q[] = { + 0x04, 0x23, 0xA5, 0x0C, 0xB8, 0x2D, 0x12, 0xF5, 0x28, 0xF3, 0xB1, 0xB2, + 0xDD, 0xE2, 0x02, 0x12, 0x80, 0x9E, 0x39, 0x5F, 0x49, 0x4D, 0x9F, 0xC9, + 0x25, 0x34, 0x59, 0x74, 0xEC, 0xBB, 0x06, 0x1C, 0xE7, 0xC0, 0x72, 0xAF, + 0xE8, 0xAE, 0x2F, 0xE1, 0x41, 0x54, 0x87, 0x14, 0xA8, 0x4A, 0xB2, 0xE8, + 0x7C, 0x82, 0xE6, 0x5B, 0x6A, 0xB5, 0xDC, 0xB3, 0x75, 0xCE, 0x8B, 0x06, + 0xD0, 0x86, 0x23, 0xBF, 0x46, 0xD5, 0x8E, 0x0F, 0x3F, 0x04, 0xF4, 0xD7, + 0x1C, 0x92, 0x7E, 0xF6, 0xA5, 0x63, 0xC2, 0xF5, 0x5F, 0x8E, 0x2E, 0x4F, + 0xA1, 0x18, 0x19, 0x02, 0x2B, 0x32, 0x0A, 0x82, 0x64, 0x7D, 0x16, 0x93, + 0xD1 +}; + +static const unsigned char TA637_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x1C, + 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x43, 0x31 +}; + +static const unsigned char TA637_RSA_N[] = { + 0xCF, 0xEB, 0xA9, 0xB9, 0xF1, 0x99, 0x05, 0xCC, 0xD8, 0x28, 0x21, 0x4A, + 0xF3, 0x73, 0x34, 0x51, 0x84, 0x56, 0x10, 0xF5, 0xA0, 0x4F, 0x2C, 0x12, + 0xE3, 0xFA, 0x13, 0x9A, 0x27, 0xD0, 0xCF, 0xF9, 0x79, 0x1A, 0x74, 0x5F, + 0x1D, 0x79, 0x39, 0xFC, 0x5B, 0xF8, 0x70, 0x8E, 0xE0, 0x92, 0x52, 0xF7, + 0xE4, 0x25, 0xF9, 0x54, 0x83, 0xD9, 0x1D, 0xD3, 0xC8, 0x5A, 0x85, 0x3F, + 0x5E, 0xC7, 0xB6, 0x07, 0xEE, 0x3E, 0xC0, 0xCE, 0x9A, 0xAF, 0xAC, 0x56, + 0x42, 0x2A, 0x39, 0x25, 0x70, 0xD6, 0xBF, 0xB5, 0x7B, 0x36, 0xAD, 0xAC, + 0xF6, 0x73, 0xDC, 0xCD, 0xD7, 0x1D, 0x8A, 0x83, 0xA5, 0xFB, 0x2B, 0x90, + 0x15, 0x37, 0x6B, 0x1C, 0x26, 0x47, 0xDC, 0x3B, 0x29, 0x56, 0x93, 0x6A, + 0xB3, 0xC1, 0x6A, 0x3A, 0x9D, 0x3D, 0xF5, 0xC1, 0x97, 0x38, 0x58, 0x05, + 0x8B, 0x1C, 0x11, 0xE3, 0xE4, 0xB4, 0xB8, 0x5D, 0x85, 0x1D, 0x83, 0xFE, + 0x78, 0x5F, 0x0B, 0x45, 0x68, 0x18, 0x48, 0xA5, 0x46, 0x73, 0x34, 0x3B, + 0xFE, 0x0F, 0xC8, 0x76, 0xBB, 0xC7, 0x18, 0xF3, 0x05, 0xD1, 0x86, 0xF3, + 0x85, 0xED, 0xE7, 0xB9, 0xD9, 0x32, 0xAD, 0x55, 0x88, 0xCE, 0xA6, 0xB6, + 0x91, 0xB0, 0x4F, 0xAC, 0x7E, 0x15, 0x23, 0x96, 0xF6, 0x3F, 0xF0, 0x20, + 0x34, 0x16, 0xDE, 0x0A, 0xC6, 0xC4, 0x04, 0x45, 0x79, 0x7F, 0xA7, 0xFD, + 0xBE, 0xD2, 0xA9, 0xA5, 0xAF, 0x9C, 0xC5, 0x23, 0x2A, 0xF7, 0x3C, 0x21, + 0x6C, 0xBD, 0xAF, 0x8F, 0x4E, 0xC5, 0x3A, 0xB2, 0xF3, 0x34, 0x12, 0xFC, + 0xDF, 0x80, 0x1A, 0x49, 0xA4, 0xD4, 0xA9, 0x95, 0xF7, 0x9E, 0x89, 0x5E, + 0xA2, 0x89, 0xAC, 0x94, 0xCB, 0xA8, 0x68, 0x9B, 0xAF, 0x8A, 0x65, 0x27, + 0xCD, 0x89, 0xEE, 0xDD, 0x8C, 0xB5, 0x6B, 0x29, 0x70, 0x43, 0xA0, 0x69, + 0x0B, 0xE4, 0xB9, 0x0F +}; + +static const unsigned char TA637_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA638_DN[] = { + 0x30, 0x67, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x13, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA638_RSA_N[] = { + 0x93, 0x4B, 0xBB, 0xE9, 0x66, 0x8A, 0xEE, 0x9D, 0x5B, 0xD5, 0x34, 0x93, + 0xD0, 0x1B, 0x1E, 0xC3, 0xE7, 0x9E, 0xB8, 0x64, 0x33, 0x7F, 0x63, 0x78, + 0x68, 0xB4, 0xCD, 0x2E, 0x71, 0x75, 0xD7, 0x9B, 0x20, 0xC6, 0x4D, 0x29, + 0xBC, 0xB6, 0x68, 0x60, 0x8A, 0xF7, 0x21, 0x9A, 0x56, 0x35, 0x5A, 0xF3, + 0x76, 0xBD, 0xD8, 0xCD, 0x9A, 0xFF, 0x93, 0x56, 0x4B, 0xA5, 0x59, 0x06, + 0xA1, 0x93, 0x34, 0x29, 0xDD, 0x16, 0x34, 0x75, 0x4E, 0xF2, 0x81, 0xB4, + 0xC7, 0x96, 0x4E, 0xAD, 0x19, 0x15, 0x52, 0x4A, 0xFE, 0x3C, 0x70, 0x75, + 0x70, 0xCD, 0xAF, 0x2B, 0xAB, 0x15, 0x9A, 0x33, 0x3C, 0xAA, 0xB3, 0x8B, + 0xAA, 0xCD, 0x43, 0xFD, 0xF5, 0xEA, 0x70, 0xFF, 0xED, 0xCF, 0x11, 0x3B, + 0x94, 0xCE, 0x4E, 0x32, 0x16, 0xD3, 0x23, 0x40, 0x2A, 0x77, 0xB3, 0xAF, + 0x3C, 0x01, 0x2C, 0x6C, 0xED, 0x99, 0x2C, 0x8B, 0xD9, 0x4E, 0x69, 0x98, + 0xB2, 0xF7, 0x8F, 0x41, 0xB0, 0x32, 0x78, 0x61, 0xD6, 0x0D, 0x5F, 0xC3, + 0xFA, 0xA2, 0x40, 0x92, 0x1D, 0x5C, 0x17, 0xE6, 0x70, 0x3E, 0x35, 0xE7, + 0xA2, 0xB7, 0xC2, 0x62, 0xE2, 0xAB, 0xA4, 0x38, 0x4C, 0xB5, 0x39, 0x35, + 0x6F, 0xEA, 0x03, 0x69, 0xFA, 0x3A, 0x54, 0x68, 0x85, 0x6D, 0xD6, 0xF2, + 0x2F, 0x43, 0x55, 0x1E, 0x91, 0x0D, 0x0E, 0xD8, 0xD5, 0x6A, 0xA4, 0x96, + 0xD1, 0x13, 0x3C, 0x2C, 0x78, 0x50, 0xE8, 0x3A, 0x92, 0xD2, 0x17, 0x56, + 0xE5, 0x35, 0x1A, 0x40, 0x1C, 0x3E, 0x8D, 0x2C, 0xED, 0x39, 0xDF, 0x42, + 0xE0, 0x83, 0x41, 0x74, 0xDF, 0xA3, 0xCD, 0xC2, 0x86, 0x60, 0x48, 0x68, + 0xE3, 0x69, 0x0B, 0x54, 0x00, 0x8B, 0xE4, 0x76, 0x69, 0x21, 0x0D, 0x79, + 0x4E, 0x34, 0x08, 0x5E, 0x14, 0xC2, 0xCC, 0xB1, 0xB7, 0xAD, 0xD7, 0x7C, + 0x70, 0x8A, 0xC7, 0x85 +}; + +static const unsigned char TA638_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA639_DN[] = { + 0x30, 0x81, 0xB4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, + 0x74, 0x31, 0x40, 0x30, 0x3E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x14, 0x37, + 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, + 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x5F, 0x32, 0x30, 0x34, 0x38, + 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x2E, 0x20, 0x62, 0x79, 0x20, + 0x72, 0x65, 0x66, 0x2E, 0x20, 0x28, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x73, + 0x20, 0x6C, 0x69, 0x61, 0x62, 0x2E, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1C, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, + 0x65, 0x74, 0x20, 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, + 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, + 0x34, 0x38, 0x29 +}; + +static const unsigned char TA639_RSA_N[] = { + 0xAD, 0x4D, 0x4B, 0xA9, 0x12, 0x86, 0xB2, 0xEA, 0xA3, 0x20, 0x07, 0x15, + 0x16, 0x64, 0x2A, 0x2B, 0x4B, 0xD1, 0xBF, 0x0B, 0x4A, 0x4D, 0x8E, 0xED, + 0x80, 0x76, 0xA5, 0x67, 0xB7, 0x78, 0x40, 0xC0, 0x73, 0x42, 0xC8, 0x68, + 0xC0, 0xDB, 0x53, 0x2B, 0xDD, 0x5E, 0xB8, 0x76, 0x98, 0x35, 0x93, 0x8B, + 0x1A, 0x9D, 0x7C, 0x13, 0x3A, 0x0E, 0x1F, 0x5B, 0xB7, 0x1E, 0xCF, 0xE5, + 0x24, 0x14, 0x1E, 0xB1, 0x81, 0xA9, 0x8D, 0x7D, 0xB8, 0xCC, 0x6B, 0x4B, + 0x03, 0xF1, 0x02, 0x0C, 0xDC, 0xAB, 0xA5, 0x40, 0x24, 0x00, 0x7F, 0x74, + 0x94, 0xA1, 0x9D, 0x08, 0x29, 0xB3, 0x88, 0x0B, 0xF5, 0x87, 0x77, 0x9D, + 0x55, 0xCD, 0xE4, 0xC3, 0x7E, 0xD7, 0x6A, 0x64, 0xAB, 0x85, 0x14, 0x86, + 0x95, 0x5B, 0x97, 0x32, 0x50, 0x6F, 0x3D, 0xC8, 0xBA, 0x66, 0x0C, 0xE3, + 0xFC, 0xBD, 0xB8, 0x49, 0xC1, 0x76, 0x89, 0x49, 0x19, 0xFD, 0xC0, 0xA8, + 0xBD, 0x89, 0xA3, 0x67, 0x2F, 0xC6, 0x9F, 0xBC, 0x71, 0x19, 0x60, 0xB8, + 0x2D, 0xE9, 0x2C, 0xC9, 0x90, 0x76, 0x66, 0x7B, 0x94, 0xE2, 0xAF, 0x78, + 0xD6, 0x65, 0x53, 0x5D, 0x3C, 0xD6, 0x9C, 0xB2, 0xCF, 0x29, 0x03, 0xF9, + 0x2F, 0xA4, 0x50, 0xB2, 0xD4, 0x48, 0xCE, 0x05, 0x32, 0x55, 0x8A, 0xFD, + 0xB2, 0x64, 0x4C, 0x0E, 0xE4, 0x98, 0x07, 0x75, 0xDB, 0x7F, 0xDF, 0xB9, + 0x08, 0x55, 0x60, 0x85, 0x30, 0x29, 0xF9, 0x7B, 0x48, 0xA4, 0x69, 0x86, + 0xE3, 0x35, 0x3F, 0x1E, 0x86, 0x5D, 0x7A, 0x7A, 0x15, 0xBD, 0xEF, 0x00, + 0x8E, 0x15, 0x22, 0x54, 0x17, 0x00, 0x90, 0x26, 0x93, 0xBC, 0x0E, 0x49, + 0x68, 0x91, 0xBF, 0xF8, 0x47, 0xD3, 0x9D, 0x95, 0x42, 0xC1, 0x0E, 0x4D, + 0xDF, 0x6F, 0x26, 0xCF, 0xC3, 0x18, 0x21, 0x62, 0x66, 0x43, 0x70, 0xD6, + 0xD5, 0xC0, 0x07, 0xE1 +}; + +static const unsigned char TA639_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA640_DN[] = { + 0x30, 0x81, 0xBF, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x33, 0x30, + 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x45, + 0x43, 0x31 +}; + +static const unsigned char TA640_EC_Q[] = { + 0x04, 0x84, 0x13, 0xC9, 0xD0, 0xBA, 0x6D, 0x41, 0x7B, 0xE2, 0x6C, 0xD0, + 0xEB, 0x55, 0x5F, 0x66, 0x02, 0x1A, 0x24, 0xF4, 0x5B, 0x89, 0x69, 0x47, + 0xE3, 0xB8, 0xC2, 0x7D, 0xF1, 0xF2, 0x02, 0xC5, 0x9F, 0xA0, 0xF6, 0x5B, + 0xD5, 0x8B, 0x06, 0x19, 0x86, 0x4F, 0x53, 0x10, 0x6D, 0x07, 0x24, 0x27, + 0xA1, 0xA0, 0xF8, 0xD5, 0x47, 0x19, 0x61, 0x4C, 0x7D, 0xCA, 0x93, 0x27, + 0xEA, 0x74, 0x0C, 0xEF, 0x6F, 0x96, 0x09, 0xFE, 0x63, 0xEC, 0x70, 0x5D, + 0x36, 0xAD, 0x67, 0x77, 0xAE, 0xC9, 0x9D, 0x7C, 0x55, 0x44, 0x3A, 0xA2, + 0x63, 0x51, 0x1F, 0xF5, 0xE3, 0x62, 0xD4, 0xA9, 0x47, 0x07, 0x3E, 0xCC, + 0x20 +}; + +static const unsigned char TA641_DN[] = { + 0x30, 0x81, 0xBE, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x32, 0x30, + 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, + 0x32 +}; + +static const unsigned char TA641_RSA_N[] = { + 0xBA, 0x84, 0xB6, 0x72, 0xDB, 0x9E, 0x0C, 0x6B, 0xE2, 0x99, 0xE9, 0x30, + 0x01, 0xA7, 0x76, 0xEA, 0x32, 0xB8, 0x95, 0x41, 0x1A, 0xC9, 0xDA, 0x61, + 0x4E, 0x58, 0x72, 0xCF, 0xFE, 0xF6, 0x82, 0x79, 0xBF, 0x73, 0x61, 0x06, + 0x0A, 0xA5, 0x27, 0xD8, 0xB3, 0x5F, 0xD3, 0x45, 0x4E, 0x1C, 0x72, 0xD6, + 0x4E, 0x32, 0xF2, 0x72, 0x8A, 0x0F, 0xF7, 0x83, 0x19, 0xD0, 0x6A, 0x80, + 0x80, 0x00, 0x45, 0x1E, 0xB0, 0xC7, 0xE7, 0x9A, 0xBF, 0x12, 0x57, 0x27, + 0x1C, 0xA3, 0x68, 0x2F, 0x0A, 0x87, 0xBD, 0x6A, 0x6B, 0x0E, 0x5E, 0x65, + 0xF3, 0x1C, 0x77, 0xD5, 0xD4, 0x85, 0x8D, 0x70, 0x21, 0xB4, 0xB3, 0x32, + 0xE7, 0x8B, 0xA2, 0xD5, 0x86, 0x39, 0x02, 0xB1, 0xB8, 0xD2, 0x47, 0xCE, + 0xE4, 0xC9, 0x49, 0xC4, 0x3B, 0xA7, 0xDE, 0xFB, 0x54, 0x7D, 0x57, 0xBE, + 0xF0, 0xE8, 0x6E, 0xC2, 0x79, 0xB2, 0x3A, 0x0B, 0x55, 0xE2, 0x50, 0x98, + 0x16, 0x32, 0x13, 0x5C, 0x2F, 0x78, 0x56, 0xC1, 0xC2, 0x94, 0xB3, 0xF2, + 0x5A, 0xE4, 0x27, 0x9A, 0x9F, 0x24, 0xD7, 0xC6, 0xEC, 0xD0, 0x9B, 0x25, + 0x82, 0xE3, 0xCC, 0xC2, 0xC4, 0x45, 0xC5, 0x8C, 0x97, 0x7A, 0x06, 0x6B, + 0x2A, 0x11, 0x9F, 0xA9, 0x0A, 0x6E, 0x48, 0x3B, 0x6F, 0xDB, 0xD4, 0x11, + 0x19, 0x42, 0xF7, 0x8F, 0x07, 0xBF, 0xF5, 0x53, 0x5F, 0x9C, 0x3E, 0xF4, + 0x17, 0x2C, 0xE6, 0x69, 0xAC, 0x4E, 0x32, 0x4C, 0x62, 0x77, 0xEA, 0xB7, + 0xE8, 0xE5, 0xBB, 0x34, 0xBC, 0x19, 0x8B, 0xAE, 0x9C, 0x51, 0xE7, 0xB7, + 0x7E, 0xB5, 0x53, 0xB1, 0x33, 0x22, 0xE5, 0x6D, 0xCF, 0x70, 0x3C, 0x1A, + 0xFA, 0xE2, 0x9B, 0x67, 0xB6, 0x83, 0xF4, 0x8D, 0xA5, 0xAF, 0x62, 0x4C, + 0x4D, 0xE0, 0x58, 0xAC, 0x64, 0x34, 0x12, 0x03, 0xF8, 0xB6, 0x8D, 0x94, + 0x63, 0x24, 0xA4, 0x71 +}; + +static const unsigned char TA641_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA642_DN[] = { + 0x30, 0x81, 0xB0, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x30, 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x20, 0x69, + 0x73, 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6E, 0x63, 0x65, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x16, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, + 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA642_RSA_N[] = { + 0xB6, 0x95, 0xB6, 0x43, 0x42, 0xFA, 0xC6, 0x6D, 0x2A, 0x6F, 0x48, 0xDF, + 0x94, 0x4C, 0x39, 0x57, 0x05, 0xEE, 0xC3, 0x79, 0x11, 0x41, 0x68, 0x36, + 0xED, 0xEC, 0xFE, 0x9A, 0x01, 0x8F, 0xA1, 0x38, 0x28, 0xFC, 0xF7, 0x10, + 0x46, 0x66, 0x2E, 0x4D, 0x1E, 0x1A, 0xB1, 0x1A, 0x4E, 0xC6, 0xD1, 0xC0, + 0x95, 0x88, 0xB0, 0xC9, 0xFF, 0x31, 0x8B, 0x33, 0x03, 0xDB, 0xB7, 0x83, + 0x7B, 0x3E, 0x20, 0x84, 0x5E, 0xED, 0xB2, 0x56, 0x28, 0xA7, 0xF8, 0xE0, + 0xB9, 0x40, 0x71, 0x37, 0xC5, 0xCB, 0x47, 0x0E, 0x97, 0x2A, 0x68, 0xC0, + 0x22, 0x95, 0x62, 0x15, 0xDB, 0x47, 0xD9, 0xF5, 0xD0, 0x2B, 0xFF, 0x82, + 0x4B, 0xC9, 0xAD, 0x3E, 0xDE, 0x4C, 0xDB, 0x90, 0x80, 0x50, 0x3F, 0x09, + 0x8A, 0x84, 0x00, 0xEC, 0x30, 0x0A, 0x3D, 0x18, 0xCD, 0xFB, 0xFD, 0x2A, + 0x59, 0x9A, 0x23, 0x95, 0x17, 0x2C, 0x45, 0x9E, 0x1F, 0x6E, 0x43, 0x79, + 0x6D, 0x0C, 0x5C, 0x98, 0xFE, 0x48, 0xA7, 0xC5, 0x23, 0x47, 0x5C, 0x5E, + 0xFD, 0x6E, 0xE7, 0x1E, 0xB4, 0xF6, 0x68, 0x45, 0xD1, 0x86, 0x83, 0x5B, + 0xA2, 0x8A, 0x8D, 0xB1, 0xE3, 0x29, 0x80, 0xFE, 0x25, 0x71, 0x88, 0xAD, + 0xBE, 0xBC, 0x8F, 0xAC, 0x52, 0x96, 0x4B, 0xAA, 0x51, 0x8D, 0xE4, 0x13, + 0x31, 0x19, 0xE8, 0x4E, 0x4D, 0x9F, 0xDB, 0xAC, 0xB3, 0x6A, 0xD5, 0xBC, + 0x39, 0x54, 0x71, 0xCA, 0x7A, 0x7A, 0x7F, 0x90, 0xDD, 0x7D, 0x1D, 0x80, + 0xD9, 0x81, 0xBB, 0x59, 0x26, 0xC2, 0x11, 0xFE, 0xE6, 0x93, 0xE2, 0xF7, + 0x80, 0xE4, 0x65, 0xFB, 0x34, 0x37, 0x0E, 0x29, 0x80, 0x70, 0x4D, 0xAF, + 0x38, 0x86, 0x2E, 0x9E, 0x7F, 0x57, 0xAF, 0x9E, 0x17, 0xAE, 0xEB, 0x1C, + 0xCB, 0x28, 0x21, 0x5F, 0xB6, 0x1C, 0xD8, 0xE7, 0xA2, 0x04, 0x22, 0xF9, + 0xD3, 0xDA, 0xD8, 0xCB +}; + +static const unsigned char TA642_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA643_DN[] = { + 0x30, 0x5E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x21, 0x65, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA643_RSA_N[] = { + 0xE1, 0x25, 0x0F, 0xEE, 0x8D, 0xDB, 0x88, 0x33, 0x75, 0x67, 0xCD, 0xAD, + 0x1F, 0x7D, 0x3A, 0x4E, 0x6D, 0x9D, 0xD3, 0x2F, 0x14, 0xF3, 0x63, 0x74, + 0xCB, 0x01, 0x21, 0x6A, 0x37, 0xEA, 0x84, 0x50, 0x07, 0x4B, 0x26, 0x5B, + 0x09, 0x43, 0x6C, 0x21, 0x9E, 0x6A, 0xC8, 0xD5, 0x03, 0xF5, 0x60, 0x69, + 0x8F, 0xCC, 0xF0, 0x22, 0xE4, 0x1F, 0xE7, 0xF7, 0x6A, 0x22, 0x31, 0xB7, + 0x2C, 0x15, 0xF2, 0xE0, 0xFE, 0x00, 0x6A, 0x43, 0xFF, 0x87, 0x65, 0xC6, + 0xB5, 0x1A, 0xC1, 0xA7, 0x4C, 0x6D, 0x22, 0x70, 0x21, 0x8A, 0x31, 0xF2, + 0x97, 0x74, 0x89, 0x09, 0x12, 0x26, 0x1C, 0x9E, 0xCA, 0xD9, 0x12, 0xA2, + 0x95, 0x3C, 0xDA, 0xE9, 0x67, 0xBF, 0x08, 0xA0, 0x64, 0xE3, 0xD6, 0x42, + 0xB7, 0x45, 0xEF, 0x97, 0xF4, 0xF6, 0xF5, 0xD7, 0xB5, 0x4A, 0x15, 0x02, + 0x58, 0x7D, 0x98, 0x58, 0x4B, 0x60, 0xBC, 0xCD, 0xD7, 0x0D, 0x9A, 0x13, + 0x33, 0x53, 0xD1, 0x61, 0xF9, 0x7A, 0xD5, 0xD7, 0x78, 0xB3, 0x9A, 0x33, + 0xF7, 0x00, 0x86, 0xCE, 0x1D, 0x4D, 0x94, 0x38, 0xAF, 0xA8, 0xEC, 0x78, + 0x51, 0x70, 0x8A, 0x5C, 0x10, 0x83, 0x51, 0x21, 0xF7, 0x11, 0x3D, 0x34, + 0x86, 0x5E, 0xE5, 0x48, 0xCD, 0x97, 0x81, 0x82, 0x35, 0x4C, 0x19, 0xEC, + 0x65, 0xF6, 0x6B, 0xC5, 0x05, 0xA1, 0xEE, 0x47, 0x13, 0xD6, 0xB3, 0x21, + 0x27, 0x94, 0x10, 0x0A, 0xD9, 0x24, 0x3B, 0xBA, 0xBE, 0x44, 0x13, 0x46, + 0x30, 0x3F, 0x97, 0x3C, 0xD8, 0xD7, 0xD7, 0x6A, 0xEE, 0x3B, 0x38, 0xE3, + 0x2B, 0xD4, 0x97, 0x0E, 0xB9, 0x1B, 0xE7, 0x07, 0x49, 0x7F, 0x37, 0x2A, + 0xF9, 0x77, 0x78, 0xCF, 0x54, 0xED, 0x5B, 0x46, 0x9D, 0xA3, 0x80, 0x0E, + 0x91, 0x43, 0xC1, 0xD6, 0x5B, 0x5F, 0x14, 0xBA, 0x9F, 0xA6, 0x8D, 0x24, + 0x47, 0x40, 0x59, 0xBF, 0x72, 0x38, 0xB2, 0x36, 0x6C, 0x37, 0xFF, 0x99, + 0xD1, 0x5D, 0x0E, 0x59, 0x0A, 0xAB, 0x69, 0xF7, 0xC0, 0xB2, 0x04, 0x45, + 0x7A, 0x54, 0x00, 0xAE, 0xBE, 0x53, 0xF6, 0xB5, 0xE7, 0xE1, 0xF8, 0x3C, + 0xA3, 0x31, 0xD2, 0xA9, 0xFE, 0x21, 0x52, 0x64, 0xC5, 0xA6, 0x67, 0xF0, + 0x75, 0x07, 0x06, 0x94, 0x14, 0x81, 0x55, 0xC6, 0x27, 0xE4, 0x01, 0x8F, + 0x17, 0xC1, 0x6A, 0x71, 0xD7, 0xBE, 0x4B, 0xFB, 0x94, 0x58, 0x7D, 0x7E, + 0x11, 0x33, 0xB1, 0x42, 0xF7, 0x62, 0x6C, 0x18, 0xD6, 0xCF, 0x09, 0x68, + 0x3E, 0x7F, 0x6C, 0xF6, 0x1E, 0x8F, 0x62, 0xAD, 0xA5, 0x63, 0xDB, 0x09, + 0xA7, 0x1F, 0x22, 0x42, 0x41, 0x1E, 0x6F, 0x99, 0x8A, 0x3E, 0xD7, 0xF9, + 0x3F, 0x40, 0x7A, 0x79, 0xB0, 0xA5, 0x01, 0x92, 0xD2, 0x9D, 0x3D, 0x08, + 0x15, 0xA5, 0x10, 0x01, 0x2D, 0xB3, 0x32, 0x76, 0xA8, 0x95, 0x0D, 0xB3, + 0x7A, 0x9A, 0xFB, 0x07, 0x10, 0x78, 0x11, 0x6F, 0xE1, 0x8F, 0xC7, 0xBA, + 0x0F, 0x25, 0x1A, 0x74, 0x2A, 0xE5, 0x1C, 0x98, 0x41, 0x99, 0xDF, 0x21, + 0x87, 0xE8, 0x95, 0x06, 0x6A, 0x0A, 0xB3, 0x6A, 0x47, 0x76, 0x65, 0xF6, + 0x3A, 0xCF, 0x8F, 0x62, 0x17, 0x19, 0x7B, 0x0A, 0x28, 0xCD, 0x1A, 0xD2, + 0x83, 0x1E, 0x21, 0xC7, 0x2C, 0xBF, 0xBE, 0xFF, 0x61, 0x68, 0xB7, 0x67, + 0x1B, 0xBB, 0x78, 0x4D, 0x8D, 0xCE, 0x67, 0xE5, 0xE4, 0xC1, 0x8E, 0xB7, + 0x23, 0x66, 0xE2, 0x9D, 0x90, 0x75, 0x34, 0x98, 0xA9, 0x36, 0x2B, 0x8A, + 0x9A, 0x94, 0xB9, 0x9D, 0xEC, 0xCC, 0x8A, 0xB1, 0xF8, 0x25, 0x89, 0x5C, + 0x5A, 0xB6, 0x2F, 0x8C, 0x1F, 0x6D, 0x79, 0x24, 0xA7, 0x52, 0x68, 0xC3, + 0x84, 0x35, 0xE2, 0x66, 0x8D, 0x63, 0x0E, 0x25, 0x4D, 0xD5, 0x19, 0xB2, + 0xE6, 0x79, 0x37, 0xA7, 0x22, 0x9D, 0x54, 0x31 +}; + +static const unsigned char TA643_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA644_DN[] = { + 0x30, 0x71, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, 0x63, + 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0E, 0x56, 0x41, 0x54, + 0x48, 0x55, 0x2D, 0x32, 0x33, 0x35, 0x38, 0x34, 0x34, 0x39, 0x37, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x15, 0x65, 0x2D, + 0x53, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA644_EC_Q[] = { + 0x04, 0x96, 0xDC, 0x3D, 0x8A, 0xD8, 0xB0, 0x7B, 0x6F, 0xC6, 0x27, 0xBE, + 0x44, 0x90, 0xB1, 0xB3, 0x56, 0x15, 0x7B, 0x8E, 0x43, 0x24, 0x7D, 0x1A, + 0x84, 0x59, 0xEE, 0x63, 0x68, 0xB2, 0xC6, 0x5E, 0x87, 0xD0, 0x15, 0x48, + 0x1E, 0xA8, 0x90, 0xAD, 0xBD, 0x53, 0xA2, 0xDA, 0xDE, 0x3A, 0x90, 0xA6, + 0x60, 0x5F, 0x68, 0x32, 0xB5, 0x86, 0x41, 0xDF, 0x87, 0x5B, 0x2C, 0x7B, + 0xC5, 0xFE, 0x7C, 0x7A, 0xDA +}; + +static const unsigned char TA645_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x31 +}; + +static const unsigned char TA645_RSA_N[] = { + 0xB6, 0x11, 0x02, 0x8B, 0x1E, 0xE3, 0xA1, 0x77, 0x9B, 0x3B, 0xDC, 0xBF, + 0x94, 0x3E, 0xB7, 0x95, 0xA7, 0x40, 0x3C, 0xA1, 0xFD, 0x82, 0xF9, 0x7D, + 0x32, 0x06, 0x82, 0x71, 0xF6, 0xF6, 0x8C, 0x7F, 0xFB, 0xE8, 0xDB, 0xBC, + 0x6A, 0x2E, 0x97, 0x97, 0xA3, 0x8C, 0x4B, 0xF9, 0x2B, 0xF6, 0xB1, 0xF9, + 0xCE, 0x84, 0x1D, 0xB1, 0xF9, 0xC5, 0x97, 0xDE, 0xEF, 0xB9, 0xF2, 0xA3, + 0xE9, 0xBC, 0x12, 0x89, 0x5E, 0xA7, 0xAA, 0x52, 0xAB, 0xF8, 0x23, 0x27, + 0xCB, 0xA4, 0xB1, 0x9C, 0x63, 0xDB, 0xD7, 0x99, 0x7E, 0xF0, 0x0A, 0x5E, + 0xEB, 0x68, 0xA6, 0xF4, 0xC6, 0x5A, 0x47, 0x0D, 0x4D, 0x10, 0x33, 0xE3, + 0x4E, 0xB1, 0x13, 0xA3, 0xC8, 0x18, 0x6C, 0x4B, 0xEC, 0xFC, 0x09, 0x90, + 0xDF, 0x9D, 0x64, 0x29, 0x25, 0x23, 0x07, 0xA1, 0xB4, 0xD2, 0x3D, 0x2E, + 0x60, 0xE0, 0xCF, 0xD2, 0x09, 0x87, 0xBB, 0xCD, 0x48, 0xF0, 0x4D, 0xC2, + 0xC2, 0x7A, 0x88, 0x8A, 0xBB, 0xBA, 0xCF, 0x59, 0x19, 0xD6, 0xAF, 0x8F, + 0xB0, 0x07, 0xB0, 0x9E, 0x31, 0xF1, 0x82, 0xC1, 0xC0, 0xDF, 0x2E, 0xA6, + 0x6D, 0x6C, 0x19, 0x0E, 0xB5, 0xD8, 0x7E, 0x26, 0x1A, 0x45, 0x03, 0x3D, + 0xB0, 0x79, 0xA4, 0x94, 0x28, 0xAD, 0x0F, 0x7F, 0x26, 0xE5, 0xA8, 0x08, + 0xFE, 0x96, 0xE8, 0x3C, 0x68, 0x94, 0x53, 0xEE, 0x83, 0x3A, 0x88, 0x2B, + 0x15, 0x96, 0x09, 0xB2, 0xE0, 0x7A, 0x8C, 0x2E, 0x75, 0xD6, 0x9C, 0xEB, + 0xA7, 0x56, 0x64, 0x8F, 0x96, 0x4F, 0x68, 0xAE, 0x3D, 0x97, 0xC2, 0x84, + 0x8F, 0xC0, 0xBC, 0x40, 0xC0, 0x0B, 0x5C, 0xBD, 0xF6, 0x87, 0xB3, 0x35, + 0x6C, 0xAC, 0x18, 0x50, 0x7F, 0x84, 0xE0, 0x4C, 0xCD, 0x92, 0xD3, 0x20, + 0xE9, 0x33, 0xBC, 0x52, 0x99, 0xAF, 0x32, 0xB5, 0x29, 0xB3, 0x25, 0x2A, + 0xB4, 0x48, 0xF9, 0x72, 0xE1, 0xCA, 0x64, 0xF7, 0xE6, 0x82, 0x10, 0x8D, + 0xE8, 0x9D, 0xC2, 0x8A, 0x88, 0xFA, 0x38, 0x66, 0x8A, 0xFC, 0x63, 0xF9, + 0x01, 0xF9, 0x78, 0xFD, 0x7B, 0x5C, 0x77, 0xFA, 0x76, 0x87, 0xFA, 0xEC, + 0xDF, 0xB1, 0x0E, 0x79, 0x95, 0x57, 0xB4, 0xBD, 0x26, 0xEF, 0xD6, 0x01, + 0xD1, 0xEB, 0x16, 0x0A, 0xBB, 0x8E, 0x0B, 0xB5, 0xC5, 0xC5, 0x8A, 0x55, + 0xAB, 0xD3, 0xAC, 0xEA, 0x91, 0x4B, 0x29, 0xCC, 0x19, 0xA4, 0x32, 0x25, + 0x4E, 0x2A, 0xF1, 0x65, 0x44, 0xD0, 0x02, 0xCE, 0xAA, 0xCE, 0x49, 0xB4, + 0xEA, 0x9F, 0x7C, 0x83, 0xB0, 0x40, 0x7B, 0xE7, 0x43, 0xAB, 0xA7, 0x6C, + 0xA3, 0x8F, 0x7D, 0x89, 0x81, 0xFA, 0x4C, 0xA5, 0xFF, 0xD5, 0x8E, 0xC3, + 0xCE, 0x4B, 0xE0, 0xB5, 0xD8, 0xB3, 0x8E, 0x45, 0xCF, 0x76, 0xC0, 0xED, + 0x40, 0x2B, 0xFD, 0x53, 0x0F, 0xB0, 0xA7, 0xD5, 0x3B, 0x0D, 0xB1, 0x8A, + 0xA2, 0x03, 0xDE, 0x31, 0xAD, 0xCC, 0x77, 0xEA, 0x6F, 0x7B, 0x3E, 0xD6, + 0xDF, 0x91, 0x22, 0x12, 0xE6, 0xBE, 0xFA, 0xD8, 0x32, 0xFC, 0x10, 0x63, + 0x14, 0x51, 0x72, 0xDE, 0x5D, 0xD6, 0x16, 0x93, 0xBD, 0x29, 0x68, 0x33, + 0xEF, 0x3A, 0x66, 0xEC, 0x07, 0x8A, 0x26, 0xDF, 0x13, 0xD7, 0x57, 0x65, + 0x78, 0x27, 0xDE, 0x5E, 0x49, 0x14, 0x00, 0xA2, 0x00, 0x7F, 0x9A, 0xA8, + 0x21, 0xB6, 0xA9, 0xB1, 0x95, 0xB0, 0xA5, 0xB9, 0x0D, 0x16, 0x11, 0xDA, + 0xC7, 0x6C, 0x48, 0x3C, 0x40, 0xE0, 0x7E, 0x0D, 0x5A, 0xCD, 0x56, 0x3C, + 0xD1, 0x97, 0x05, 0xB9, 0xCB, 0x4B, 0xED, 0x39, 0x4B, 0x9C, 0xC4, 0x3F, + 0xD2, 0x55, 0x13, 0x6E, 0x24, 0xB0, 0xD6, 0x71, 0xFA, 0xF4, 0xC1, 0xBA, + 0xCC, 0xED, 0x1B, 0xF5, 0xFE, 0x81, 0x41, 0xD8, 0x00, 0x98, 0x3D, 0x3A, + 0xC8, 0xAE, 0x7A, 0x98, 0x37, 0x18, 0x05, 0x95 +}; + +static const unsigned char TA645_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA646_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x49, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x11, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x6C, + 0x61, 0x6E, 0x64, 0x20, 0x4F, 0x79, 0x6A, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x32 +}; + +static const unsigned char TA646_RSA_N[] = { + 0xB2, 0xD0, 0x3F, 0x07, 0xBC, 0xE2, 0x7B, 0xD0, 0x6B, 0x99, 0xF8, 0xE2, + 0x77, 0x69, 0xE7, 0xCE, 0x9D, 0xA4, 0x03, 0xBC, 0x82, 0x6D, 0xA1, 0xFE, + 0x81, 0x65, 0x1F, 0x4C, 0x27, 0xAC, 0x8E, 0x00, 0xBA, 0x16, 0x7B, 0xEB, + 0x30, 0x6A, 0x00, 0xC0, 0xB3, 0x74, 0x68, 0x7E, 0xB2, 0xAF, 0xC7, 0xD5, + 0x62, 0xB3, 0x7A, 0x3F, 0x50, 0xCA, 0x8C, 0x36, 0x44, 0x24, 0x63, 0xD2, + 0x36, 0xE9, 0x0C, 0x85, 0xF6, 0x43, 0x76, 0xD5, 0x4C, 0xA1, 0x60, 0x72, + 0x67, 0xE2, 0x28, 0x33, 0xA5, 0xCB, 0x31, 0xB8, 0x3A, 0x22, 0x23, 0x34, + 0xB8, 0x7D, 0xBD, 0x56, 0x22, 0x40, 0x9D, 0xEA, 0xF4, 0x7B, 0x03, 0xAD, + 0x68, 0xFC, 0xB2, 0x81, 0x4F, 0x98, 0xD0, 0x74, 0xEA, 0x8D, 0xE5, 0x7D, + 0xCD, 0x63, 0xC3, 0xA3, 0xF6, 0xDE, 0x92, 0xC2, 0x58, 0x19, 0xE0, 0x96, + 0xBB, 0xC5, 0xC4, 0xA9, 0x3D, 0xA5, 0x74, 0x96, 0xFE, 0xAF, 0xF9, 0x89, + 0xAA, 0xBD, 0x95, 0x17, 0x54, 0xD8, 0x78, 0x44, 0xF1, 0x0C, 0x77, 0x15, + 0x92, 0xE0, 0x98, 0x42, 0xA7, 0xA4, 0xD6, 0xAA, 0x20, 0x92, 0xCD, 0xC1, + 0xA0, 0xB3, 0x96, 0xB2, 0x3A, 0x84, 0x42, 0x8D, 0x7D, 0xD5, 0x95, 0xE4, + 0xD6, 0xDB, 0xE9, 0x62, 0xC4, 0x58, 0xB3, 0x79, 0xC5, 0x8C, 0xD3, 0x35, + 0x33, 0x83, 0x9F, 0x75, 0xA1, 0x52, 0x27, 0x61, 0x38, 0xF1, 0x59, 0x3D, + 0x8E, 0x50, 0xE0, 0xBD, 0x79, 0x3C, 0xE7, 0x6C, 0x96, 0xFE, 0x5E, 0xD9, + 0x02, 0x65, 0xB4, 0x8E, 0x5C, 0xD0, 0x11, 0x34, 0xDF, 0x5D, 0xBF, 0x52, + 0xA7, 0x81, 0x00, 0xC3, 0x7F, 0x99, 0x45, 0x99, 0x15, 0xD5, 0x17, 0xC8, + 0x0A, 0x53, 0xEC, 0x63, 0xF3, 0x99, 0x7D, 0xCC, 0x69, 0x12, 0x86, 0xC2, + 0x17, 0xF0, 0x01, 0x9E, 0xBF, 0x84, 0xBC, 0xD1, 0x52, 0xCB, 0x1B, 0x92, + 0x66, 0xCE, 0xA4, 0x53, 0xE5, 0xA1, 0xBF, 0xC4, 0xDB, 0x09, 0xD6, 0xE6, + 0x89, 0x56, 0x2B, 0xC8, 0xE3, 0x7C, 0xDE, 0xE3, 0xFF, 0x89, 0xE5, 0x35, + 0x6E, 0x28, 0xE8, 0x6C, 0x0B, 0x23, 0x51, 0xA9, 0x25, 0x05, 0xEB, 0x48, + 0xF8, 0xDD, 0xB1, 0xCA, 0xFA, 0x6C, 0x08, 0x51, 0xEF, 0xB7, 0x18, 0x6C, + 0x44, 0xCA, 0x26, 0xE1, 0x73, 0xC6, 0x89, 0x06, 0x81, 0xE5, 0x8A, 0xAC, + 0xB0, 0xE2, 0x29, 0xC6, 0xB9, 0x24, 0xB3, 0x6B, 0x44, 0x11, 0xF4, 0xA5, + 0x43, 0xC2, 0x4C, 0x43, 0xE5, 0x70, 0x36, 0x8C, 0xB6, 0x33, 0x57, 0x7A, + 0x95, 0x2E, 0x82, 0xA0, 0xF4, 0x5C, 0x10, 0xB3, 0x61, 0x83, 0xF6, 0x02, + 0x05, 0x86, 0x2E, 0x7C, 0x2D, 0x6C, 0xDC, 0x03, 0x46, 0x6E, 0x35, 0x93, + 0xD5, 0x7A, 0x95, 0x2F, 0xDE, 0x20, 0xD8, 0x5B, 0x7E, 0x94, 0x90, 0x04, + 0x6A, 0xBA, 0x59, 0x3D, 0x04, 0x05, 0x75, 0x9D, 0x37, 0xA2, 0x0E, 0x2E, + 0x3D, 0xEB, 0xC1, 0xA4, 0x52, 0x83, 0xFE, 0xD0, 0x6B, 0xD4, 0x66, 0x8E, + 0xDC, 0xC6, 0xE9, 0x12, 0x4E, 0x1D, 0x2A, 0x57, 0xAA, 0x10, 0xBC, 0x7C, + 0x5E, 0x82, 0x7D, 0xA6, 0xA6, 0xC9, 0xF2, 0x2D, 0xB9, 0xF5, 0x17, 0x27, + 0xAD, 0xD1, 0x0E, 0x89, 0x54, 0x2B, 0x95, 0xFA, 0xC0, 0xAD, 0x1D, 0x98, + 0x14, 0x78, 0x33, 0x42, 0x86, 0x0A, 0xA9, 0x73, 0xB5, 0xFB, 0x74, 0x0D, + 0xB7, 0x1B, 0x30, 0x19, 0xC4, 0x5A, 0x0E, 0x1C, 0x27, 0xB7, 0xDA, 0x18, + 0xD0, 0xFF, 0x8A, 0xC8, 0x05, 0xBA, 0xF1, 0xAA, 0x1C, 0xA2, 0x37, 0xB7, + 0xE6, 0x48, 0xA4, 0x46, 0x2C, 0x94, 0xEA, 0xA8, 0x76, 0x62, 0x47, 0x8B, + 0x10, 0x53, 0x07, 0x48, 0x57, 0x6C, 0xE2, 0x92, 0x4D, 0xB6, 0xAE, 0x05, + 0xCB, 0xDC, 0xC1, 0x4A, 0x5E, 0x8F, 0xAC, 0x3D, 0x19, 0x4E, 0xC2, 0xED, + 0x60, 0x75, 0x2B, 0xDB, 0xC1, 0xCA, 0x42, 0xD5 +}; + +static const unsigned char TA646_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA647_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, + 0x64, 0x79, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x49, 0x6E, + 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x28, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6C, + 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA647_RSA_N[] = { + 0xDE, 0x9D, 0xD7, 0xEA, 0x57, 0x18, 0x49, 0xA1, 0x5B, 0xEB, 0xD7, 0x5F, + 0x48, 0x86, 0xEA, 0xBE, 0xDD, 0xFF, 0xE4, 0xEF, 0x67, 0x1C, 0xF4, 0x65, + 0x68, 0xB3, 0x57, 0x71, 0xA0, 0x5E, 0x77, 0xBB, 0xED, 0x9B, 0x49, 0xE9, + 0x70, 0x80, 0x3D, 0x56, 0x18, 0x63, 0x08, 0x6F, 0xDA, 0xF2, 0xCC, 0xD0, + 0x3F, 0x7F, 0x02, 0x54, 0x22, 0x54, 0x10, 0xD8, 0xB2, 0x81, 0xD4, 0xC0, + 0x75, 0x3D, 0x4B, 0x7F, 0xC7, 0x77, 0xC3, 0x3E, 0x78, 0xAB, 0x1A, 0x03, + 0xB5, 0x20, 0x6B, 0x2F, 0x6A, 0x2B, 0xB1, 0xC5, 0x88, 0x7E, 0xC4, 0xBB, + 0x1E, 0xB0, 0xC1, 0xD8, 0x45, 0x27, 0x6F, 0xAA, 0x37, 0x58, 0xF7, 0x87, + 0x26, 0xD7, 0xD8, 0x2D, 0xF6, 0xA9, 0x17, 0xB7, 0x1F, 0x72, 0x36, 0x4E, + 0xA6, 0x17, 0x3F, 0x65, 0x98, 0x92, 0xDB, 0x2A, 0x6E, 0x5D, 0xA2, 0xFE, + 0x88, 0xE0, 0x0B, 0xDE, 0x7F, 0xE5, 0x8D, 0x15, 0xE1, 0xEB, 0xCB, 0x3A, + 0xD5, 0xE2, 0x12, 0xA2, 0x13, 0x2D, 0xD8, 0x8E, 0xAF, 0x5F, 0x12, 0x3D, + 0xA0, 0x08, 0x05, 0x08, 0xB6, 0x5C, 0xA5, 0x65, 0x38, 0x04, 0x45, 0x99, + 0x1E, 0xA3, 0x60, 0x60, 0x74, 0xC5, 0x41, 0xA5, 0x72, 0x62, 0x1B, 0x62, + 0xC5, 0x1F, 0x6F, 0x5F, 0x1A, 0x42, 0xBE, 0x02, 0x51, 0x65, 0xA8, 0xAE, + 0x23, 0x18, 0x6A, 0xFC, 0x78, 0x03, 0xA9, 0x4D, 0x7F, 0x80, 0xC3, 0xFA, + 0xAB, 0x5A, 0xFC, 0xA1, 0x40, 0xA4, 0xCA, 0x19, 0x16, 0xFE, 0xB2, 0xC8, + 0xEF, 0x5E, 0x73, 0x0D, 0xEE, 0x77, 0xBD, 0x9A, 0xF6, 0x79, 0x98, 0xBC, + 0xB1, 0x07, 0x67, 0xA2, 0x15, 0x0D, 0xDD, 0xA0, 0x58, 0xC6, 0x44, 0x7B, + 0x0A, 0x3E, 0x62, 0x28, 0x5F, 0xBA, 0x41, 0x07, 0x53, 0x58, 0xCF, 0x11, + 0x7E, 0x38, 0x74, 0xC5, 0xF8, 0xFF, 0xB5, 0x69, 0x90, 0x8F, 0x84, 0x74, + 0xEA, 0x97, 0x1B, 0xAF +}; + +static const unsigned char TA647_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA648_DN[] = { + 0x30, 0x7F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x2B, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, 0x56, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA648_EC_Q[] = { + 0x04, 0xAA, 0x12, 0x47, 0x90, 0x98, 0x1B, 0xFB, 0xEF, 0xC3, 0x40, 0x07, + 0x83, 0x20, 0x4E, 0xF1, 0x30, 0x82, 0xA2, 0x06, 0xD1, 0xF2, 0x92, 0x86, + 0x61, 0xF2, 0xF6, 0x21, 0x68, 0xCA, 0x00, 0xC4, 0xC7, 0xEA, 0x43, 0x00, + 0x54, 0x86, 0xDC, 0xFD, 0x1F, 0xDF, 0x00, 0xB8, 0x41, 0x62, 0x5C, 0xDC, + 0x70, 0x16, 0x32, 0xDE, 0x1F, 0x99, 0xD4, 0xCC, 0xC5, 0x07, 0xC8, 0x08, + 0x1F, 0x61, 0x16, 0x07, 0x51, 0x3D, 0x7D, 0x5C, 0x07, 0x53, 0xE3, 0x35, + 0x38, 0x8C, 0xDF, 0xCD, 0x9F, 0xD9, 0x2E, 0x0D, 0x4A, 0xB6, 0x19, 0x2E, + 0x5A, 0x70, 0x5A, 0x06, 0xED, 0xBE, 0xF0, 0xA1, 0xB0, 0xCA, 0xD0, 0x09, + 0x29 +}; + +static const unsigned char TA649_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x28, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA649_RSA_N[] = { + 0xB9, 0x5D, 0x51, 0x28, 0x4B, 0x3C, 0x37, 0x92, 0xD1, 0x82, 0xCE, 0xBD, + 0x1D, 0xBD, 0xCD, 0xDD, 0xB8, 0xAB, 0xCF, 0x0A, 0x3E, 0xE1, 0x5D, 0xE5, + 0xDC, 0xAA, 0x09, 0xB9, 0x57, 0x02, 0x3E, 0xE6, 0x63, 0x61, 0xDF, 0xF2, + 0x0F, 0x82, 0x63, 0xAE, 0xA3, 0xF7, 0xAC, 0x73, 0xD1, 0x7C, 0xE7, 0xB3, + 0x0B, 0xAF, 0x08, 0x00, 0x09, 0x59, 0x7F, 0xCD, 0x29, 0x2A, 0x88, 0x93, + 0x87, 0x17, 0x18, 0x80, 0xED, 0x88, 0xB2, 0xB4, 0xB6, 0x10, 0x1F, 0x2D, + 0xD6, 0x5F, 0x55, 0xA2, 0x13, 0x5D, 0xD1, 0xC6, 0xEB, 0x06, 0x56, 0x89, + 0x88, 0xFE, 0xAC, 0x32, 0x9D, 0xFD, 0x5C, 0xC3, 0x05, 0xC7, 0x6E, 0xEE, + 0x86, 0x89, 0xBA, 0x88, 0x03, 0x9D, 0x72, 0x21, 0x86, 0x90, 0xAE, 0x8F, + 0x03, 0xA5, 0xDC, 0x9F, 0x88, 0x28, 0xCB, 0xA3, 0x92, 0x49, 0x0F, 0xEC, + 0xD0, 0x0F, 0xE2, 0x6D, 0x44, 0x4F, 0x80, 0x6A, 0xB2, 0xD4, 0xE7, 0xA0, + 0x0A, 0x53, 0x01, 0xBA, 0x8E, 0x97, 0x91, 0x76, 0x6E, 0xBC, 0xFC, 0xD5, + 0x6B, 0x36, 0xE6, 0x40, 0x88, 0xD6, 0x7B, 0x2F, 0x5F, 0x05, 0xE8, 0x2C, + 0x6D, 0x11, 0xF3, 0xE7, 0xB2, 0xBE, 0x92, 0x44, 0x4C, 0xD2, 0x97, 0xA4, + 0xFE, 0xD2, 0x72, 0x81, 0x43, 0x07, 0x9C, 0xE9, 0x11, 0x3E, 0xF5, 0x8B, + 0x1A, 0x59, 0x7D, 0x1F, 0x68, 0x58, 0xDD, 0x04, 0x00, 0x2C, 0x96, 0xF3, + 0x43, 0xB3, 0x7E, 0x98, 0x19, 0x74, 0xD9, 0x9C, 0x73, 0xD9, 0x18, 0xBE, + 0x41, 0xC7, 0x34, 0x79, 0xD9, 0xF4, 0x62, 0xC2, 0x43, 0xB9, 0xB3, 0x27, + 0xB0, 0x22, 0xCB, 0xF9, 0x3D, 0x52, 0xC7, 0x30, 0x47, 0xB3, 0xC9, 0x3E, + 0xB8, 0x6A, 0xE2, 0xE7, 0xE8, 0x81, 0x70, 0x5E, 0x42, 0x8B, 0x4F, 0x26, + 0xA5, 0xFE, 0x3A, 0xC2, 0x20, 0x6E, 0xBB, 0xF8, 0x16, 0x8E, 0xCD, 0x0C, + 0xA9, 0xB4, 0x1B, 0x6C, 0x76, 0x10, 0xE1, 0x58, 0x79, 0x46, 0x3E, 0x54, + 0xCE, 0x80, 0xA8, 0x57, 0x09, 0x37, 0x29, 0x1B, 0x99, 0x13, 0x8F, 0x0C, + 0xC8, 0xD6, 0x2C, 0x1C, 0xFB, 0x05, 0xE8, 0x08, 0x95, 0x3D, 0x65, 0x46, + 0xDC, 0xEE, 0xCD, 0x69, 0xE2, 0x4D, 0x8F, 0x87, 0x28, 0x4E, 0x34, 0x0B, + 0x3E, 0xCF, 0x14, 0xD9, 0xBB, 0xDD, 0xB6, 0x50, 0x9A, 0xAD, 0x77, 0xD4, + 0x19, 0xD6, 0xDA, 0x1A, 0x88, 0xC8, 0x4E, 0x1B, 0x27, 0x75, 0xD8, 0xB2, + 0x08, 0xF1, 0xAE, 0x83, 0x30, 0xB9, 0x11, 0x0E, 0xCD, 0x87, 0xF0, 0x84, + 0x8D, 0x15, 0x72, 0x7C, 0xA1, 0xEF, 0xCC, 0xF2, 0x88, 0x61, 0xBA, 0xF4, + 0x69, 0xBB, 0x0C, 0x8C, 0x0B, 0x75, 0x57, 0x04, 0xB8, 0x4E, 0x2A, 0x14, + 0x2E, 0x3D, 0x0F, 0x1C, 0x1E, 0x32, 0xA6, 0x62, 0x36, 0xEE, 0x66, 0xE2, + 0x22, 0xB8, 0x05, 0x40, 0x63, 0x10, 0x22, 0xF3, 0x33, 0x1D, 0x74, 0x72, + 0x8A, 0x2C, 0xF5, 0x39, 0x29, 0xA0, 0xD3, 0xE7, 0x1B, 0x80, 0x84, 0x2D, + 0xC5, 0x3D, 0xE3, 0x4D, 0xB1, 0xFD, 0x1A, 0x6F, 0xBA, 0x65, 0x07, 0x3B, + 0x58, 0xEC, 0x42, 0x45, 0x26, 0xFB, 0xD8, 0xDA, 0x25, 0x72, 0xC4, 0xF6, + 0x00, 0xB1, 0x22, 0x79, 0xBD, 0xE3, 0x7C, 0x59, 0x62, 0x4A, 0x9C, 0x05, + 0x6F, 0x3D, 0xCE, 0xE6, 0xD6, 0x47, 0x63, 0x99, 0xC6, 0x24, 0x6F, 0x72, + 0x12, 0xC8, 0xAC, 0x7F, 0x90, 0xB4, 0x0B, 0x91, 0x70, 0xE8, 0xB7, 0xE6, + 0x16, 0x10, 0x71, 0x17, 0xCE, 0xDE, 0x06, 0x4F, 0x48, 0x41, 0x7D, 0x35, + 0x4A, 0xA3, 0x89, 0xF2, 0xC9, 0x4B, 0x7B, 0x41, 0x11, 0x6D, 0x67, 0xB7, + 0x08, 0x98, 0x4C, 0xE5, 0x11, 0x19, 0xAE, 0x42, 0x80, 0xDC, 0xFB, 0x90, + 0x05, 0xD4, 0xF8, 0x50, 0xCA, 0xBE, 0xE4, 0xAD, 0xC7, 0xC2, 0x94, 0xD7, + 0x16, 0x9D, 0xE6, 0x17, 0x8F, 0xAF, 0x36, 0xFB +}; + +static const unsigned char TA649_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA650_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA650_EC_Q[] = { + 0x04, 0x1A, 0xAC, 0x54, 0x5A, 0xA9, 0xF9, 0x68, 0x23, 0xE7, 0x7A, 0xD5, + 0x24, 0x6F, 0x53, 0xC6, 0x5A, 0xD8, 0x4B, 0xAB, 0xC6, 0xD5, 0xB6, 0xD1, + 0xE6, 0x73, 0x71, 0xAE, 0xDD, 0x9C, 0xD6, 0x0C, 0x61, 0xFD, 0xDB, 0xA0, + 0x89, 0x03, 0xB8, 0x05, 0x14, 0xEC, 0x57, 0xCE, 0xEE, 0x5D, 0x3F, 0xE2, + 0x21, 0xB3, 0xCE, 0xF7, 0xD4, 0x8A, 0x79, 0xE0, 0xA3, 0x83, 0x7E, 0x2D, + 0x97, 0xD0, 0x61, 0xC4, 0xF1, 0x99, 0xDC, 0x25, 0x91, 0x63, 0xAB, 0x7F, + 0x30, 0xA3, 0xB4, 0x70, 0xE2, 0xC7, 0xA1, 0x33, 0x9C, 0xF3, 0xBF, 0x2E, + 0x5C, 0x53, 0xB1, 0x5F, 0xB3, 0x7D, 0x32, 0x7F, 0x8A, 0x34, 0xE3, 0x79, + 0x79 +}; + +static const unsigned char TA651_DN[] = { + 0x30, 0x68, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, + 0x6C, 0x64, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA651_RSA_N[] = { + 0xB7, 0x32, 0xC8, 0xFE, 0xE9, 0x71, 0xA6, 0x04, 0x85, 0xAD, 0x0C, 0x11, + 0x64, 0xDF, 0xCE, 0x4D, 0xEF, 0xC8, 0x03, 0x18, 0x87, 0x3F, 0xA1, 0xAB, + 0xFB, 0x3C, 0xA6, 0x9F, 0xF0, 0xC3, 0xA1, 0xDA, 0xD4, 0xD8, 0x6E, 0x2B, + 0x53, 0x90, 0xFB, 0x24, 0xA4, 0x3E, 0x84, 0xF0, 0x9E, 0xE8, 0x5F, 0xEC, + 0xE5, 0x27, 0x44, 0xF5, 0x28, 0xA6, 0x3F, 0x7B, 0xDE, 0xE0, 0x2A, 0xF0, + 0xC8, 0xAF, 0x53, 0x2F, 0x9E, 0xCA, 0x05, 0x01, 0x93, 0x1E, 0x8F, 0x66, + 0x1C, 0x39, 0xA7, 0x4D, 0xFA, 0x5A, 0xB6, 0x73, 0x04, 0x25, 0x66, 0xEB, + 0x77, 0x7F, 0xE7, 0x59, 0xC6, 0x4A, 0x99, 0x25, 0x14, 0x54, 0xEB, 0x26, + 0xC7, 0xF3, 0x7F, 0x19, 0xD5, 0x30, 0x70, 0x8F, 0xAF, 0xB0, 0x46, 0x2A, + 0xFF, 0xAD, 0xEB, 0x29, 0xED, 0xD7, 0x9F, 0xAA, 0x04, 0x87, 0xA3, 0xD4, + 0xF9, 0x89, 0xA5, 0x34, 0x5F, 0xDB, 0x43, 0x91, 0x82, 0x36, 0xD9, 0x66, + 0x3C, 0xB1, 0xB8, 0xB9, 0x82, 0xFD, 0x9C, 0x3A, 0x3E, 0x10, 0xC8, 0x3B, + 0xEF, 0x06, 0x65, 0x66, 0x7A, 0x9B, 0x19, 0x18, 0x3D, 0xFF, 0x71, 0x51, + 0x3C, 0x30, 0x2E, 0x5F, 0xBE, 0x3D, 0x77, 0x73, 0xB2, 0x5D, 0x06, 0x6C, + 0xC3, 0x23, 0x56, 0x9A, 0x2B, 0x85, 0x26, 0x92, 0x1C, 0xA7, 0x02, 0xB3, + 0xE4, 0x3F, 0x0D, 0xAF, 0x08, 0x79, 0x82, 0xB8, 0x36, 0x3D, 0xEA, 0x9C, + 0xD3, 0x35, 0xB3, 0xBC, 0x69, 0xCA, 0xF5, 0xCC, 0x9D, 0xE8, 0xFD, 0x64, + 0x8D, 0x17, 0x80, 0x33, 0x6E, 0x5E, 0x4A, 0x5D, 0x99, 0xC9, 0x1E, 0x87, + 0xB4, 0x9D, 0x1A, 0xC0, 0xD5, 0x6E, 0x13, 0x35, 0x23, 0x5E, 0xDF, 0x9B, + 0x5F, 0x3D, 0xEF, 0xD6, 0xF7, 0x76, 0xC2, 0xEA, 0x3E, 0xBB, 0x78, 0x0D, + 0x1C, 0x42, 0x67, 0x6B, 0x04, 0xD8, 0xF8, 0xD6, 0xDA, 0x6F, 0x8B, 0xF2, + 0x44, 0xA0, 0x01, 0xAB +}; + +static const unsigned char TA651_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA652_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0E, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA652_RSA_N[] = { + 0xAB, 0xA4, 0x81, 0xE5, 0x95, 0xCD, 0xF5, 0xF6, 0x14, 0x8E, 0xC2, 0x4F, + 0xCA, 0xD4, 0xE2, 0x78, 0x95, 0x58, 0x9C, 0x41, 0xE1, 0x0D, 0x99, 0x40, + 0x24, 0x17, 0x39, 0x91, 0x33, 0x66, 0xE9, 0xBE, 0xE1, 0x83, 0xAF, 0x62, + 0x5C, 0x89, 0xD1, 0xFC, 0x24, 0x5B, 0x61, 0xB3, 0xE0, 0x11, 0x11, 0x41, + 0x1C, 0x1D, 0x6E, 0xF0, 0xB8, 0xBB, 0xF8, 0xDE, 0xA7, 0x81, 0xBA, 0xA6, + 0x48, 0xC6, 0x9F, 0x1D, 0xBD, 0xBE, 0x8E, 0xA9, 0x41, 0x3E, 0xB8, 0x94, + 0xED, 0x29, 0x1A, 0xD4, 0x8E, 0xD2, 0x03, 0x1D, 0x03, 0xEF, 0x6D, 0x0D, + 0x67, 0x1C, 0x57, 0xD7, 0x06, 0xAD, 0xCA, 0xC8, 0xF5, 0xFE, 0x0E, 0xAF, + 0x66, 0x25, 0x48, 0x04, 0x96, 0x0B, 0x5D, 0xA3, 0xBA, 0x16, 0xC3, 0x08, + 0x4F, 0xD1, 0x46, 0xF8, 0x14, 0x5C, 0xF2, 0xC8, 0x5E, 0x01, 0x99, 0x6D, + 0xFD, 0x88, 0xCC, 0x86, 0xA8, 0xC1, 0x6F, 0x31, 0x42, 0x6C, 0x52, 0x3E, + 0x68, 0xCB, 0xF3, 0x19, 0x34, 0xDF, 0xBB, 0x87, 0x18, 0x56, 0x80, 0x26, + 0xC4, 0xD0, 0xDC, 0xC0, 0x6F, 0xDF, 0xDE, 0xA0, 0xC2, 0x91, 0x16, 0xA0, + 0x64, 0x11, 0x4B, 0x44, 0xBC, 0x1E, 0xF6, 0xE7, 0xFA, 0x63, 0xDE, 0x66, + 0xAC, 0x76, 0xA4, 0x71, 0xA3, 0xEC, 0x36, 0x94, 0x68, 0x7A, 0x77, 0xA4, + 0xB1, 0xE7, 0x0E, 0x2F, 0x81, 0x7A, 0xE2, 0xB5, 0x72, 0x86, 0xEF, 0xA2, + 0x6B, 0x8B, 0xF0, 0x0F, 0xDB, 0xD3, 0x59, 0x3F, 0xBA, 0x72, 0xBC, 0x44, + 0x24, 0x9C, 0xE3, 0x73, 0xB3, 0xF7, 0xAF, 0x57, 0x2F, 0x42, 0x26, 0x9D, + 0xA9, 0x74, 0xBA, 0x00, 0x52, 0xF2, 0x4B, 0xCD, 0x53, 0x7C, 0x47, 0x0B, + 0x36, 0x85, 0x0E, 0x66, 0xA9, 0x08, 0x97, 0x16, 0x34, 0x57, 0xC1, 0x66, + 0xF7, 0x80, 0xE3, 0xED, 0x70, 0x54, 0xC7, 0x93, 0xE0, 0x2E, 0x28, 0x15, + 0x59, 0x87, 0xBA, 0xBB +}; + +static const unsigned char TA652_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA653_DN[] = { + 0x30, 0x67, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x13, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA653_RSA_N[] = { + 0x93, 0x4B, 0xBB, 0xE9, 0x66, 0x8A, 0xEE, 0x9D, 0x5B, 0xD5, 0x34, 0x93, + 0xD0, 0x1B, 0x1E, 0xC3, 0xE7, 0x9E, 0xB8, 0x64, 0x33, 0x7F, 0x63, 0x78, + 0x68, 0xB4, 0xCD, 0x2E, 0x71, 0x75, 0xD7, 0x9B, 0x20, 0xC6, 0x4D, 0x29, + 0xBC, 0xB6, 0x68, 0x60, 0x8A, 0xF7, 0x21, 0x9A, 0x56, 0x35, 0x5A, 0xF3, + 0x76, 0xBD, 0xD8, 0xCD, 0x9A, 0xFF, 0x93, 0x56, 0x4B, 0xA5, 0x59, 0x06, + 0xA1, 0x93, 0x34, 0x29, 0xDD, 0x16, 0x34, 0x75, 0x4E, 0xF2, 0x81, 0xB4, + 0xC7, 0x96, 0x4E, 0xAD, 0x19, 0x15, 0x52, 0x4A, 0xFE, 0x3C, 0x70, 0x75, + 0x70, 0xCD, 0xAF, 0x2B, 0xAB, 0x15, 0x9A, 0x33, 0x3C, 0xAA, 0xB3, 0x8B, + 0xAA, 0xCD, 0x43, 0xFD, 0xF5, 0xEA, 0x70, 0xFF, 0xED, 0xCF, 0x11, 0x3B, + 0x94, 0xCE, 0x4E, 0x32, 0x16, 0xD3, 0x23, 0x40, 0x2A, 0x77, 0xB3, 0xAF, + 0x3C, 0x01, 0x2C, 0x6C, 0xED, 0x99, 0x2C, 0x8B, 0xD9, 0x4E, 0x69, 0x98, + 0xB2, 0xF7, 0x8F, 0x41, 0xB0, 0x32, 0x78, 0x61, 0xD6, 0x0D, 0x5F, 0xC3, + 0xFA, 0xA2, 0x40, 0x92, 0x1D, 0x5C, 0x17, 0xE6, 0x70, 0x3E, 0x35, 0xE7, + 0xA2, 0xB7, 0xC2, 0x62, 0xE2, 0xAB, 0xA4, 0x38, 0x4C, 0xB5, 0x39, 0x35, + 0x6F, 0xEA, 0x03, 0x69, 0xFA, 0x3A, 0x54, 0x68, 0x85, 0x6D, 0xD6, 0xF2, + 0x2F, 0x43, 0x55, 0x1E, 0x91, 0x0D, 0x0E, 0xD8, 0xD5, 0x6A, 0xA4, 0x96, + 0xD1, 0x13, 0x3C, 0x2C, 0x78, 0x50, 0xE8, 0x3A, 0x92, 0xD2, 0x17, 0x56, + 0xE5, 0x35, 0x1A, 0x40, 0x1C, 0x3E, 0x8D, 0x2C, 0xED, 0x39, 0xDF, 0x42, + 0xE0, 0x83, 0x41, 0x74, 0xDF, 0xA3, 0xCD, 0xC2, 0x86, 0x60, 0x48, 0x68, + 0xE3, 0x69, 0x0B, 0x54, 0x00, 0x8B, 0xE4, 0x76, 0x69, 0x21, 0x0D, 0x79, + 0x4E, 0x34, 0x08, 0x5E, 0x14, 0xC2, 0xCC, 0xB1, 0xB7, 0xAD, 0xD7, 0x7C, + 0x70, 0x8A, 0xC7, 0x85 +}; + +static const unsigned char TA653_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA654_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x13, 0x30, 0x30, + 0x30, 0x32, 0x20, 0x34, 0x38, 0x31, 0x34, 0x36, 0x33, 0x30, 0x38, 0x31, + 0x30, 0x30, 0x30, 0x33, 0x36, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA654_RSA_N[] = { + 0xCD, 0x18, 0x39, 0x65, 0x1A, 0x59, 0xB1, 0xEA, 0x64, 0x16, 0x0E, 0x8C, + 0x94, 0x24, 0x95, 0x7C, 0x83, 0xD3, 0xC5, 0x39, 0x26, 0xDC, 0x0C, 0xEF, + 0x16, 0x57, 0x8D, 0xD7, 0xD8, 0xAC, 0xA3, 0x42, 0x7F, 0x82, 0xCA, 0xED, + 0xCD, 0x5B, 0xDB, 0x0E, 0xB7, 0x2D, 0xED, 0x45, 0x08, 0x17, 0xB2, 0xD9, + 0xB3, 0xCB, 0xD6, 0x17, 0x52, 0x72, 0x28, 0xDB, 0x8E, 0x4E, 0x9E, 0x8A, + 0xB6, 0x0B, 0xF9, 0x9E, 0x84, 0x9A, 0x4D, 0x76, 0xDE, 0x22, 0x29, 0x5C, + 0xD2, 0xB3, 0xD2, 0x06, 0x3E, 0x30, 0x39, 0xA9, 0x74, 0xA3, 0x92, 0x56, + 0x1C, 0xA1, 0x6F, 0x4C, 0x0A, 0x20, 0x6D, 0x9F, 0x23, 0x7A, 0xB4, 0xC6, + 0xDA, 0x2C, 0xE4, 0x1D, 0x2C, 0xDC, 0xB3, 0x28, 0xD0, 0x13, 0xF2, 0x4C, + 0x4E, 0x02, 0x49, 0xA1, 0x54, 0x40, 0x9E, 0xE6, 0xE5, 0x05, 0xA0, 0x2D, + 0x84, 0xC8, 0xFF, 0x98, 0x6C, 0xD0, 0xEB, 0x8A, 0x1A, 0x84, 0x08, 0x1E, + 0xB7, 0x68, 0x23, 0xEE, 0x23, 0xD5, 0x70, 0xCE, 0x6D, 0x51, 0x69, 0x10, + 0xEE, 0xA1, 0x7A, 0xC2, 0xD1, 0x22, 0x31, 0xC2, 0x82, 0x85, 0xD2, 0xF2, + 0x55, 0x76, 0x50, 0x7C, 0x25, 0x7A, 0xC9, 0x84, 0x5C, 0x0B, 0xAC, 0xDD, + 0x42, 0x4E, 0x2B, 0xE7, 0x82, 0xA2, 0x24, 0x89, 0xCB, 0x90, 0xB2, 0xD0, + 0xEE, 0x23, 0xBA, 0x66, 0x4C, 0xBB, 0x62, 0xA4, 0xF9, 0x53, 0x5A, 0x64, + 0x7B, 0x7C, 0x98, 0xFA, 0xA3, 0x48, 0x9E, 0x0F, 0x95, 0xAE, 0xA7, 0x18, + 0xF4, 0x6A, 0xEC, 0x2E, 0x03, 0x45, 0xAF, 0xF0, 0x74, 0xF8, 0x2A, 0xCD, + 0x7A, 0x5D, 0xD1, 0xBE, 0x44, 0x26, 0x32, 0x29, 0xF1, 0xF1, 0xF5, 0x6C, + 0xCC, 0x7E, 0x02, 0x21, 0x0B, 0x9F, 0x6F, 0xA4, 0x3F, 0xBE, 0x9D, 0x53, + 0xE2, 0xCF, 0x7D, 0xA9, 0x2C, 0x7C, 0x58, 0x1A, 0x97, 0xE1, 0x3D, 0x37, + 0x37, 0x18, 0x66, 0x28, 0xD2, 0x40, 0xC5, 0x51, 0x8A, 0x8C, 0xC3, 0x2D, + 0xCE, 0x53, 0x88, 0x24, 0x58, 0x64, 0x30, 0x16, 0xC5, 0xAA, 0xE0, 0xD6, + 0x0A, 0xA6, 0x40, 0xDF, 0x78, 0xF6, 0xF5, 0x04, 0x7C, 0x69, 0x13, 0x84, + 0xBC, 0xD1, 0xD1, 0xA7, 0x06, 0xCF, 0x01, 0xF7, 0x68, 0xC0, 0xA8, 0x57, + 0xBB, 0x3A, 0x61, 0xAD, 0x04, 0x8C, 0x93, 0xE3, 0xAD, 0xFC, 0xF0, 0xDB, + 0x44, 0x6D, 0x59, 0xDC, 0x49, 0x59, 0xAE, 0xAC, 0x9A, 0x99, 0x36, 0x30, + 0x41, 0x7B, 0x76, 0x33, 0x22, 0x87, 0xA3, 0xC2, 0x92, 0x86, 0x6E, 0xF9, + 0x70, 0xEE, 0xAE, 0x87, 0x87, 0x95, 0x1B, 0xC4, 0x7A, 0xBD, 0x31, 0xF3, + 0xD4, 0xD2, 0xE5, 0x99, 0xFF, 0xBE, 0x48, 0xEC, 0x75, 0xF5, 0x78, 0x16, + 0x1D, 0xA6, 0x70, 0xC1, 0x7F, 0x3C, 0x1B, 0xA1, 0x92, 0xFB, 0xCF, 0xC8, + 0x3C, 0xD6, 0xC5, 0x93, 0x0A, 0x8F, 0xF5, 0x55, 0x3A, 0x76, 0x95, 0xCE, + 0x59, 0x98, 0x8A, 0x09, 0x95, 0x77, 0x32, 0x9A, 0x83, 0xBA, 0x2C, 0x04, + 0x3A, 0x97, 0xBD, 0xD4, 0x2F, 0xBE, 0xD7, 0x6C, 0x9B, 0xA2, 0xCA, 0x7D, + 0x6D, 0x26, 0xC9, 0x55, 0xD5, 0xCF, 0xC3, 0x79, 0x52, 0x08, 0x09, 0x99, + 0x07, 0x24, 0x2D, 0x64, 0x25, 0x6B, 0xA6, 0x21, 0x69, 0x9B, 0x6A, 0xDD, + 0x74, 0x4D, 0x6B, 0x97, 0x7A, 0x41, 0xBD, 0xAB, 0x17, 0xF9, 0x90, 0x17, + 0x48, 0x8F, 0x36, 0xF9, 0x2D, 0xD5, 0xC5, 0xDB, 0xEE, 0xAA, 0x85, 0x45, + 0x41, 0xFA, 0xCD, 0x3A, 0x45, 0xB1, 0x68, 0xE6, 0x36, 0x4C, 0x9B, 0x90, + 0x57, 0xEC, 0x23, 0xB9, 0x87, 0x08, 0xC2, 0xC4, 0x09, 0xF1, 0x97, 0x86, + 0x2A, 0x28, 0x4D, 0xE2, 0x74, 0xC0, 0xDA, 0xC4, 0x8C, 0xDB, 0xDF, 0xE2, + 0xA1, 0x17, 0x59, 0xCE, 0x24, 0x59, 0x74, 0x31, 0xDA, 0x7F, 0xFD, 0x30, + 0x6D, 0xD9, 0xDC, 0xE1, 0x6A, 0xE1, 0xFC, 0x5F +}; + +static const unsigned char TA654_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA655_DN[] = { + 0x30, 0x7A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA655_RSA_N[] = { + 0xD1, 0x2D, 0x8E, 0xBB, 0xB7, 0x36, 0xEA, 0x6D, 0x37, 0x91, 0x9F, 0x4E, + 0x93, 0xA7, 0x05, 0xE4, 0x29, 0x03, 0x25, 0xCE, 0x1C, 0x82, 0xF7, 0x7C, + 0x99, 0x9F, 0x41, 0x06, 0xCD, 0xED, 0xA3, 0xBA, 0xC0, 0xDB, 0x09, 0x2C, + 0xC1, 0x7C, 0xDF, 0x29, 0x7E, 0x4B, 0x65, 0x2F, 0x93, 0xA7, 0xD4, 0x01, + 0x6B, 0x03, 0x28, 0x18, 0xA3, 0xD8, 0x9D, 0x05, 0xC1, 0x2A, 0xD8, 0x45, + 0xF1, 0x91, 0xDE, 0xDF, 0x3B, 0xD0, 0x80, 0x02, 0x8C, 0xCF, 0x38, 0x0F, + 0xEA, 0xA7, 0x5C, 0x78, 0x11, 0xA4, 0xC1, 0xC8, 0x85, 0x5C, 0x25, 0xD3, + 0xD3, 0xB2, 0xE7, 0x25, 0xCF, 0x11, 0x54, 0x97, 0xAB, 0x35, 0xC0, 0x1E, + 0x76, 0x1C, 0xEF, 0x00, 0x53, 0x9F, 0x39, 0xDC, 0x14, 0xA5, 0x2C, 0x22, + 0x25, 0xB3, 0x72, 0x72, 0xFC, 0x8D, 0xB3, 0xE5, 0x3E, 0x08, 0x1E, 0x14, + 0x2A, 0x37, 0x0B, 0x88, 0x3C, 0xCA, 0xB0, 0xF4, 0xC8, 0xC2, 0xA1, 0xAE, + 0xBC, 0xC1, 0xBE, 0x29, 0x67, 0x55, 0xE2, 0xFC, 0xAD, 0x59, 0x5C, 0xFE, + 0xBD, 0x57, 0x2C, 0xB0, 0x90, 0x8D, 0xC2, 0xED, 0x37, 0xB6, 0x7C, 0x99, + 0x88, 0xB5, 0xD5, 0x03, 0x9A, 0x3D, 0x15, 0x0D, 0x3D, 0x3A, 0xA8, 0xA8, + 0x45, 0xF0, 0x95, 0x4E, 0x25, 0x59, 0x1D, 0xCD, 0x98, 0x69, 0xBB, 0xD3, + 0xCC, 0x32, 0xC9, 0x8D, 0xEF, 0x81, 0xFE, 0xAD, 0x7D, 0x89, 0xBB, 0xBA, + 0x60, 0x13, 0xCA, 0x65, 0x95, 0x67, 0xA0, 0xF3, 0x19, 0xF6, 0x03, 0x56, + 0xD4, 0x6A, 0xD3, 0x27, 0xE2, 0xA1, 0xAD, 0x83, 0xF0, 0x4A, 0x12, 0x22, + 0x77, 0x1C, 0x05, 0x73, 0xE2, 0x19, 0x71, 0x42, 0xC0, 0xEC, 0x75, 0x46, + 0x9A, 0x90, 0x58, 0xE0, 0x6A, 0x8E, 0x2B, 0xA5, 0x46, 0x30, 0x04, 0x8E, + 0x19, 0xB2, 0x17, 0xE3, 0xBE, 0xA9, 0xBA, 0x7F, 0x56, 0xF1, 0x24, 0x03, + 0xD7, 0xB2, 0x21, 0x28, 0x76, 0x0E, 0x36, 0x30, 0x4C, 0x79, 0xD5, 0x41, + 0x9A, 0x9A, 0xA8, 0xB8, 0x35, 0xBA, 0x0C, 0x3A, 0xF2, 0x44, 0x1B, 0x20, + 0x88, 0xF7, 0xC5, 0x25, 0xD7, 0x3D, 0xC6, 0xE3, 0x3E, 0x43, 0xDD, 0x87, + 0xFE, 0xC4, 0xEA, 0xF5, 0x53, 0x3E, 0x4C, 0x65, 0xFF, 0x3B, 0x4A, 0xCB, + 0x78, 0x5A, 0x6B, 0x17, 0x5F, 0x0D, 0xC7, 0xC3, 0x4F, 0x4E, 0x9A, 0x2A, + 0xA2, 0xED, 0x57, 0x4D, 0x22, 0xE2, 0x46, 0x9A, 0x3F, 0x0F, 0x91, 0x34, + 0x24, 0x7D, 0x55, 0xE3, 0x8C, 0x95, 0x37, 0xD3, 0x1A, 0xF0, 0x09, 0x2B, + 0x2C, 0xD2, 0xC9, 0x8D, 0xB4, 0x0D, 0x00, 0xAB, 0x67, 0x29, 0x28, 0xD8, + 0x01, 0xF5, 0x19, 0x04, 0xB6, 0x1D, 0xBE, 0x76, 0xFE, 0x72, 0x5C, 0xC4, + 0x85, 0xCA, 0xD2, 0x80, 0x41, 0xDF, 0x05, 0xA8, 0xA3, 0xD5, 0x84, 0x90, + 0x4F, 0x0B, 0xF3, 0xE0, 0x3F, 0x9B, 0x19, 0xD2, 0x37, 0x89, 0x3F, 0xF2, + 0x7B, 0x52, 0x1C, 0x8C, 0xF6, 0xE1, 0xF7, 0x3C, 0x07, 0x97, 0x8C, 0x0E, + 0xA2, 0x59, 0x81, 0x0C, 0xB2, 0x90, 0x3D, 0xD3, 0xE3, 0x59, 0x46, 0xED, + 0x0F, 0xA9, 0xA7, 0xDE, 0x80, 0x6B, 0x5A, 0xAA, 0x07, 0xB6, 0x19, 0xCB, + 0xBC, 0x57, 0xF3, 0x97, 0x21, 0x7A, 0x0C, 0xB1, 0x2B, 0x74, 0x3E, 0xEB, + 0xDA, 0xA7, 0x67, 0x2D, 0x4C, 0xC4, 0x98, 0x9E, 0x36, 0x09, 0x76, 0x66, + 0x66, 0xFC, 0x1A, 0x3F, 0xEA, 0x48, 0x54, 0x1C, 0xBE, 0x30, 0xBD, 0x80, + 0x50, 0xBF, 0x7C, 0xB5, 0xCE, 0x00, 0xF6, 0x0C, 0x61, 0xD9, 0xE7, 0x24, + 0x03, 0xE0, 0xE3, 0x01, 0x81, 0x0E, 0xBD, 0xD8, 0x85, 0x34, 0x88, 0xBD, + 0xB2, 0x36, 0xA8, 0x7B, 0x5C, 0x08, 0xE5, 0x44, 0x80, 0x8C, 0x6F, 0xF8, + 0x2F, 0xD5, 0x21, 0xCA, 0x1D, 0x1C, 0xD0, 0xFB, 0xC4, 0xB5, 0x87, 0xD1, + 0x3A, 0x4E, 0xC7, 0x76, 0xB5, 0x35, 0x48, 0xB5 +}; + +static const unsigned char TA655_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA656_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x41, 0x54, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x65, 0x2D, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x65, + 0x20, 0x6D, 0x6F, 0x6E, 0x69, 0x74, 0x6F, 0x72, 0x69, 0x6E, 0x67, 0x20, + 0x47, 0x6D, 0x62, 0x48, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x10, 0x47, 0x4C, 0x4F, 0x42, 0x41, 0x4C, 0x54, 0x52, 0x55, + 0x53, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA656_RSA_N[] = { + 0xAE, 0x2E, 0x56, 0xAD, 0x1B, 0x1C, 0xEF, 0xF6, 0x95, 0x8F, 0xA0, 0x77, + 0x1B, 0x2B, 0xD3, 0x63, 0x8F, 0x84, 0x4D, 0x45, 0xA2, 0x0F, 0x9F, 0x5B, + 0x45, 0xAB, 0x59, 0x7B, 0x51, 0x34, 0xF9, 0xEC, 0x8B, 0x8A, 0x78, 0xC5, + 0xDD, 0x6B, 0xAF, 0xBD, 0xC4, 0xDF, 0x93, 0x45, 0x1E, 0xBF, 0x91, 0x38, + 0x0B, 0xAE, 0x0E, 0x16, 0xE7, 0x41, 0x73, 0xF8, 0xDB, 0xBB, 0xD1, 0xB8, + 0x51, 0xE0, 0xCB, 0x83, 0x3B, 0x73, 0x38, 0x6E, 0x77, 0x8A, 0x0F, 0x59, + 0x63, 0x26, 0xCD, 0xA7, 0x2A, 0xCE, 0x54, 0xFB, 0xB8, 0xE2, 0xC0, 0x7C, + 0x47, 0xCE, 0x60, 0x7C, 0x3F, 0xB2, 0x73, 0xF2, 0xC0, 0x19, 0xB6, 0x8A, + 0x92, 0x87, 0x35, 0x0D, 0x90, 0x28, 0xA2, 0xE4, 0x15, 0x04, 0x63, 0x3E, + 0xBA, 0xAF, 0xEE, 0x7C, 0x5E, 0xCC, 0xA6, 0x8B, 0x50, 0xB2, 0x38, 0xF7, + 0x41, 0x63, 0xCA, 0xCE, 0xFF, 0x69, 0x8F, 0x68, 0x0E, 0x95, 0x36, 0xE5, + 0xCC, 0xB9, 0x8C, 0x09, 0xCA, 0x4B, 0xDD, 0x31, 0x90, 0x96, 0xC8, 0xCC, + 0x1F, 0xFD, 0x56, 0x96, 0x34, 0xDB, 0x8E, 0x1C, 0xEA, 0x2C, 0xBE, 0x85, + 0x2E, 0x63, 0xDD, 0xAA, 0xA9, 0x95, 0xD3, 0xFD, 0x29, 0x95, 0x13, 0xF0, + 0xC8, 0x98, 0x93, 0xD9, 0x2D, 0x16, 0x47, 0x90, 0x11, 0x83, 0xA2, 0x3A, + 0x22, 0xA2, 0x28, 0x57, 0xA2, 0xEB, 0xFE, 0xC0, 0x8C, 0x28, 0xA0, 0xA6, + 0x7D, 0xE7, 0x2A, 0x42, 0x3B, 0x82, 0x80, 0x63, 0xA5, 0x63, 0x1F, 0x19, + 0xCC, 0x7C, 0xB2, 0x66, 0xA8, 0xC2, 0xD3, 0x6D, 0x37, 0x6F, 0xE2, 0x7E, + 0x06, 0x51, 0xD9, 0x45, 0x84, 0x1F, 0x12, 0xCE, 0x24, 0x52, 0x64, 0x85, + 0x0B, 0x48, 0x80, 0x4E, 0x87, 0xB1, 0x22, 0x22, 0x30, 0xAA, 0xEB, 0xAE, + 0xBE, 0xE0, 0x02, 0xE0, 0x40, 0xE8, 0xB0, 0x42, 0x80, 0x03, 0x51, 0xAA, + 0xB4, 0x7E, 0xAA, 0x44, 0xD7, 0x43, 0x61, 0xF3, 0xA2, 0x6B, 0x16, 0x89, + 0x49, 0xA4, 0xA3, 0xA4, 0x2B, 0x8A, 0x02, 0xC4, 0x78, 0xF4, 0x68, 0x8A, + 0xC1, 0xE4, 0x7A, 0x36, 0xB1, 0x6F, 0x1B, 0x96, 0x1B, 0x77, 0x49, 0x8D, + 0xD4, 0xC9, 0x06, 0x72, 0x8F, 0xCF, 0x53, 0xE3, 0xDC, 0x17, 0x85, 0x20, + 0x4A, 0xDC, 0x98, 0x27, 0xD3, 0x91, 0x26, 0x2B, 0x47, 0x1E, 0x69, 0x07, + 0xAF, 0xDE, 0xA2, 0xE4, 0xE4, 0xD4, 0x6B, 0x0B, 0xB3, 0x5E, 0x7C, 0xD4, + 0x24, 0x80, 0x47, 0x29, 0x69, 0x3B, 0x6E, 0xE8, 0xAC, 0xFD, 0x40, 0xEB, + 0xD8, 0xED, 0x71, 0x71, 0x2B, 0xF2, 0xE8, 0x58, 0x1D, 0xEB, 0x41, 0x97, + 0x22, 0xC5, 0x1F, 0xD4, 0x39, 0xD0, 0x27, 0x8F, 0x87, 0xE3, 0x18, 0xF4, + 0xE0, 0xA9, 0x46, 0x0D, 0xF5, 0x74, 0x3A, 0x82, 0x2E, 0xD0, 0x6E, 0x2C, + 0x91, 0xA3, 0x31, 0x5C, 0x3B, 0x46, 0xEA, 0x7B, 0x04, 0x10, 0x56, 0x5E, + 0x80, 0x1D, 0xF5, 0xA5, 0x65, 0xE8, 0x82, 0xFC, 0xE2, 0x07, 0x8C, 0x62, + 0x45, 0xF5, 0x20, 0xDE, 0x46, 0x70, 0x86, 0xA1, 0xBC, 0x93, 0xD3, 0x1E, + 0x74, 0xA6, 0x6C, 0xB0, 0x2C, 0xF7, 0x03, 0x0C, 0x88, 0x0C, 0xCB, 0xD4, + 0x72, 0x53, 0x86, 0xBC, 0x60, 0x46, 0xF3, 0x98, 0x6A, 0xC2, 0xF1, 0xBF, + 0x43, 0xF9, 0x70, 0x20, 0x77, 0xCA, 0x37, 0x41, 0x79, 0x55, 0x52, 0x63, + 0x8D, 0x5B, 0x12, 0x9F, 0xC5, 0x68, 0xC4, 0x88, 0x9D, 0xAC, 0xF2, 0x30, + 0xAB, 0xB7, 0xA3, 0x31, 0x97, 0x67, 0xAD, 0x8F, 0x17, 0x0F, 0x6C, 0xC7, + 0x73, 0xED, 0x24, 0x94, 0x6B, 0xC8, 0x83, 0x9A, 0xD0, 0x9A, 0x37, 0x49, + 0x04, 0xAB, 0xB1, 0x16, 0xC8, 0x6C, 0x49, 0x49, 0x2D, 0xAB, 0xA1, 0xD0, + 0x8C, 0x92, 0xF2, 0x41, 0x4A, 0x79, 0x21, 0x25, 0xDB, 0x63, 0xD7, 0xB6, + 0x9C, 0xA7, 0x7E, 0x42, 0x69, 0xFB, 0x3A, 0x63 +}; + +static const unsigned char TA656_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA657_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA657_RSA_N[] = { + 0xAD, 0x96, 0x9F, 0x2D, 0x9C, 0x4A, 0x4C, 0x4A, 0x81, 0x79, 0x51, 0x99, + 0xEC, 0x8A, 0xCB, 0x6B, 0x60, 0x51, 0x13, 0xBC, 0x4D, 0x6D, 0x06, 0xFC, + 0xB0, 0x08, 0x8D, 0xDD, 0x19, 0x10, 0x6A, 0xC7, 0x26, 0x0C, 0x35, 0xD8, + 0xC0, 0x6F, 0x20, 0x84, 0xE9, 0x94, 0xB1, 0x9B, 0x85, 0x03, 0xC3, 0x5B, + 0xDB, 0x4A, 0xE8, 0xC8, 0xF8, 0x90, 0x76, 0xD9, 0x5B, 0x4F, 0xE3, 0x4C, + 0xE8, 0x06, 0x36, 0x4D, 0xCC, 0x9A, 0xAC, 0x3D, 0x0C, 0x90, 0x2B, 0x92, + 0xD4, 0x06, 0x19, 0x60, 0xAC, 0x37, 0x44, 0x79, 0x85, 0x81, 0x82, 0xAD, + 0x5A, 0x37, 0xE0, 0x0D, 0xCC, 0x9D, 0xA6, 0x4C, 0x52, 0x76, 0xEA, 0x43, + 0x9D, 0xB7, 0x04, 0xD1, 0x50, 0xF6, 0x55, 0xE0, 0xD5, 0xD2, 0xA6, 0x49, + 0x85, 0xE9, 0x37, 0xE9, 0xCA, 0x7E, 0xAE, 0x5C, 0x95, 0x4D, 0x48, 0x9A, + 0x3F, 0xAE, 0x20, 0x5A, 0x6D, 0x88, 0x95, 0xD9, 0x34, 0xB8, 0x52, 0x1A, + 0x43, 0x90, 0xB0, 0xBF, 0x6C, 0x05, 0xB9, 0xB6, 0x78, 0xB7, 0xEA, 0xD0, + 0xE4, 0x3A, 0x3C, 0x12, 0x53, 0x62, 0xFF, 0x4A, 0xF2, 0x7B, 0xBE, 0x35, + 0x05, 0xA9, 0x12, 0x34, 0xE3, 0xF3, 0x64, 0x74, 0x62, 0x2C, 0x3D, 0x00, + 0x49, 0x5A, 0x28, 0xFE, 0x32, 0x44, 0xBB, 0x87, 0xDD, 0x65, 0x27, 0x02, + 0x71, 0x3B, 0xDA, 0x4A, 0xF7, 0x1F, 0xDA, 0xCD, 0xF7, 0x21, 0x55, 0x90, + 0x4F, 0x0F, 0xEC, 0xAE, 0x82, 0xE1, 0x9F, 0x6B, 0xD9, 0x45, 0xD3, 0xBB, + 0xF0, 0x5F, 0x87, 0xED, 0x3C, 0x2C, 0x39, 0x86, 0xDA, 0x3F, 0xDE, 0xEC, + 0x72, 0x55, 0xEB, 0x79, 0xA3, 0xAD, 0xDB, 0xDD, 0x7C, 0xB0, 0xBA, 0x1C, + 0xCE, 0xFC, 0xDE, 0x4F, 0x35, 0x76, 0xCF, 0x0F, 0xF8, 0x78, 0x1F, 0x6A, + 0x36, 0x51, 0x46, 0x27, 0x61, 0x5B, 0xE9, 0x9E, 0xCF, 0xF0, 0xA2, 0x55, + 0x7D, 0x7C, 0x25, 0x8A, 0x6F, 0x2F, 0xB4, 0xC5, 0xCF, 0x84, 0x2E, 0x2B, + 0xFD, 0x0D, 0x51, 0x10, 0x6C, 0xFB, 0x5F, 0x1B, 0xBC, 0x1B, 0x7E, 0xC5, + 0xAE, 0x3B, 0x98, 0x01, 0x31, 0x92, 0xFF, 0x0B, 0x57, 0xF4, 0x9A, 0xB2, + 0xB9, 0x57, 0xE9, 0xAB, 0xEF, 0x0D, 0x76, 0xD1, 0xF0, 0xEE, 0xF4, 0xCE, + 0x86, 0xA7, 0xE0, 0x6E, 0xE9, 0xB4, 0x69, 0xA1, 0xDF, 0x69, 0xF6, 0x33, + 0xC6, 0x69, 0x2E, 0x97, 0x13, 0x9E, 0xA5, 0x87, 0xB0, 0x57, 0x10, 0x81, + 0x37, 0xC9, 0x53, 0xB3, 0xBB, 0x7F, 0xF6, 0x92, 0xD1, 0x9C, 0xD0, 0x18, + 0xF4, 0x92, 0x6E, 0xDA, 0x83, 0x4F, 0xA6, 0x63, 0x99, 0x4C, 0xA5, 0xFB, + 0x5E, 0xEF, 0x21, 0x64, 0x7A, 0x20, 0x5F, 0x6C, 0x64, 0x85, 0x15, 0xCB, + 0x37, 0xE9, 0x62, 0x0C, 0x0B, 0x2A, 0x16, 0xDC, 0x01, 0x2E, 0x32, 0xDA, + 0x3E, 0x4B, 0xF5, 0x9E, 0x3A, 0xF6, 0x17, 0x40, 0x94, 0xEF, 0x9E, 0x91, + 0x08, 0x86, 0xFA, 0xBE, 0x63, 0xA8, 0x5A, 0x33, 0xEC, 0xCB, 0x74, 0x43, + 0x95, 0xF9, 0x6C, 0x69, 0x52, 0x36, 0xC7, 0x29, 0x6F, 0xFC, 0x55, 0x03, + 0x5C, 0x1F, 0xFB, 0x9F, 0xBD, 0x47, 0xEB, 0xE7, 0x49, 0x47, 0x95, 0x0B, + 0x4E, 0x89, 0x22, 0x09, 0x49, 0xE0, 0xF5, 0x61, 0x1E, 0xF1, 0xBF, 0x2E, + 0x8A, 0x72, 0x6E, 0x80, 0x59, 0xFF, 0x57, 0x3A, 0xF9, 0x75, 0x32, 0xA3, + 0x4E, 0x5F, 0xEC, 0xED, 0x28, 0x62, 0xD9, 0x4D, 0x73, 0xF2, 0xCC, 0x81, + 0x17, 0x60, 0xED, 0xCD, 0xEB, 0xDC, 0xDB, 0xA7, 0xCA, 0xC5, 0x7E, 0x02, + 0xBD, 0xF2, 0x54, 0x08, 0x54, 0xFD, 0xB4, 0x2D, 0x09, 0x2C, 0x17, 0x54, + 0x4A, 0x98, 0xD1, 0x54, 0xE1, 0x51, 0x67, 0x08, 0xD2, 0xED, 0x6E, 0x7E, + 0x6F, 0x3F, 0xD2, 0x2D, 0x81, 0x59, 0x29, 0x66, 0xCB, 0x90, 0x39, 0x95, + 0x11, 0x1E, 0x74, 0x27, 0xFE, 0xDD, 0xEB, 0xAF +}; + +static const unsigned char TA657_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA658_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x45, 0x43, 0x43, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA658_EC_Q[] = { + 0x04, 0x96, 0x86, 0x58, 0x28, 0x37, 0x0A, 0x67, 0xD0, 0xA0, 0xDE, 0x24, + 0x19, 0x19, 0xE1, 0xE4, 0x05, 0x07, 0x1F, 0x97, 0xED, 0xE8, 0x64, 0x82, + 0xB9, 0xF6, 0xC4, 0x71, 0x50, 0xCE, 0x8A, 0x0C, 0xFF, 0xD7, 0xB5, 0x76, + 0xBB, 0xA1, 0x6C, 0x93, 0x6C, 0x83, 0xA2, 0x68, 0x6E, 0xA5, 0xD9, 0xBE, + 0x2C, 0x88, 0x95, 0x41, 0xCD, 0x5D, 0xDD, 0xB1, 0xCA, 0x83, 0x63, 0x83, + 0xCC, 0xC0, 0xBE, 0x74, 0xD9, 0xE0, 0x9D, 0xA4, 0xEE, 0x4A, 0x4E, 0x56, + 0xE0, 0x98, 0x29, 0x41, 0x93, 0x52, 0x10, 0xD5, 0x24, 0x38, 0x02, 0x32, + 0x67, 0xF1, 0x94, 0x12, 0x6F, 0xEF, 0xD7, 0xC5, 0xDE, 0x2E, 0xFD, 0x19, + 0x80 +}; + +static const unsigned char TA659_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA659_RSA_N[] = { + 0x80, 0x12, 0x65, 0x17, 0x36, 0x0E, 0xC3, 0xDB, 0x08, 0xB3, 0xD0, 0xAC, + 0x57, 0x0D, 0x76, 0xED, 0xCD, 0x27, 0xD3, 0x4C, 0xAD, 0x50, 0x83, 0x61, + 0xE2, 0xAA, 0x20, 0x4D, 0x09, 0x2D, 0x64, 0x09, 0xDC, 0xCE, 0x89, 0x9F, + 0xCC, 0x3D, 0xA9, 0xEC, 0xF6, 0xCF, 0xC1, 0xDC, 0xF1, 0xD3, 0xB1, 0xD6, + 0x7B, 0x37, 0x28, 0x11, 0x2B, 0x47, 0xDA, 0x39, 0xC6, 0xBC, 0x3A, 0x19, + 0xB4, 0x5F, 0xA6, 0xBD, 0x7D, 0x9D, 0xA3, 0x63, 0x42, 0xB6, 0x76, 0xF2, + 0xA9, 0x3B, 0x2B, 0x91, 0xF8, 0xE2, 0x6F, 0xD0, 0xEC, 0x16, 0x20, 0x90, + 0x09, 0x3E, 0xE2, 0xE8, 0x74, 0xC9, 0x18, 0xB4, 0x91, 0xD4, 0x62, 0x64, + 0xDB, 0x7F, 0xA3, 0x06, 0xF1, 0x88, 0x18, 0x6A, 0x90, 0x22, 0x3C, 0xBC, + 0xFE, 0x13, 0xF0, 0x87, 0x14, 0x7B, 0xF6, 0xE4, 0x1F, 0x8E, 0xD4, 0xE4, + 0x51, 0xC6, 0x11, 0x67, 0x46, 0x08, 0x51, 0xCB, 0x86, 0x14, 0x54, 0x3F, + 0xBC, 0x33, 0xFE, 0x7E, 0x6C, 0x9C, 0xFF, 0x16, 0x9D, 0x18, 0xBD, 0x51, + 0x8E, 0x35, 0xA6, 0xA7, 0x66, 0xC8, 0x72, 0x67, 0xDB, 0x21, 0x66, 0xB1, + 0xD4, 0x9B, 0x78, 0x03, 0xC0, 0x50, 0x3A, 0xE8, 0xCC, 0xF0, 0xDC, 0xBC, + 0x9E, 0x4C, 0xFE, 0xAF, 0x05, 0x96, 0x35, 0x1F, 0x57, 0x5A, 0xB7, 0xFF, + 0xCE, 0xF9, 0x3D, 0xB7, 0x2C, 0xB6, 0xF6, 0x54, 0xDD, 0xC8, 0xE7, 0x12, + 0x3A, 0x4D, 0xAE, 0x4C, 0x8A, 0xB7, 0x5C, 0x9A, 0xB4, 0xB7, 0x20, 0x3D, + 0xCA, 0x7F, 0x22, 0x34, 0xAE, 0x7E, 0x3B, 0x68, 0x66, 0x01, 0x44, 0xE7, + 0x01, 0x4E, 0x46, 0x53, 0x9B, 0x33, 0x60, 0xF7, 0x94, 0xBE, 0x53, 0x37, + 0x90, 0x73, 0x43, 0xF3, 0x32, 0xC3, 0x53, 0xEF, 0xDB, 0xAA, 0xFE, 0x74, + 0x4E, 0x69, 0xC7, 0x6B, 0x8C, 0x60, 0x93, 0xDE, 0xC4, 0xC7, 0x0C, 0xDF, + 0xE1, 0x32, 0xAE, 0xCC, 0x93, 0x3B, 0x51, 0x78, 0x95, 0x67, 0x8B, 0xEE, + 0x3D, 0x56, 0xFE, 0x0C, 0xD0, 0x69, 0x0F, 0x1B, 0x0F, 0xF3, 0x25, 0x26, + 0x6B, 0x33, 0x6D, 0xF7, 0x6E, 0x47, 0xFA, 0x73, 0x43, 0xE5, 0x7E, 0x0E, + 0xA5, 0x66, 0xB1, 0x29, 0x7C, 0x32, 0x84, 0x63, 0x55, 0x89, 0xC4, 0x0D, + 0xC1, 0x93, 0x54, 0x30, 0x19, 0x13, 0xAC, 0xD3, 0x7D, 0x37, 0xA7, 0xEB, + 0x5D, 0x3A, 0x6C, 0x35, 0x5C, 0xDB, 0x41, 0xD7, 0x12, 0xDA, 0xA9, 0x49, + 0x0B, 0xDF, 0xD8, 0x80, 0x8A, 0x09, 0x93, 0x62, 0x8E, 0xB5, 0x66, 0xCF, + 0x25, 0x88, 0xCD, 0x84, 0xB8, 0xB1, 0x3F, 0xA4, 0x39, 0x0F, 0xD9, 0x02, + 0x9E, 0xEB, 0x12, 0x4C, 0x95, 0x7C, 0xF3, 0x6B, 0x05, 0xA9, 0x5E, 0x16, + 0x83, 0xCC, 0xB8, 0x67, 0xE2, 0xE8, 0x13, 0x9D, 0xCC, 0x5B, 0x82, 0xD3, + 0x4C, 0xB3, 0xED, 0x5B, 0xFF, 0xDE, 0xE5, 0x73, 0xAC, 0x23, 0x3B, 0x2D, + 0x00, 0xBF, 0x35, 0x55, 0x74, 0x09, 0x49, 0xD8, 0x49, 0x58, 0x1A, 0x7F, + 0x92, 0x36, 0xE6, 0x51, 0x92, 0x0E, 0xF3, 0x26, 0x7D, 0x1C, 0x4D, 0x17, + 0xBC, 0xC9, 0xEC, 0x43, 0x26, 0xD0, 0xBF, 0x41, 0x5F, 0x40, 0xA9, 0x44, + 0x44, 0xF4, 0x99, 0xE7, 0x57, 0x87, 0x9E, 0x50, 0x1F, 0x57, 0x54, 0xA8, + 0x3E, 0xFD, 0x74, 0x63, 0x2F, 0xB1, 0x50, 0x65, 0x09, 0xE6, 0x58, 0x42, + 0x2E, 0x43, 0x1A, 0x4C, 0xB4, 0xF0, 0x25, 0x47, 0x59, 0xFA, 0x04, 0x1E, + 0x93, 0xD4, 0x26, 0x46, 0x4A, 0x50, 0x81, 0xB2, 0xDE, 0xBE, 0x78, 0xB7, + 0xFC, 0x67, 0x15, 0xE1, 0xC9, 0x57, 0x84, 0x1E, 0x0F, 0x63, 0xD6, 0xE9, + 0x62, 0xBA, 0xD6, 0x5F, 0x55, 0x2E, 0xEA, 0x5C, 0xC6, 0x28, 0x08, 0x04, + 0x25, 0x39, 0xB8, 0x0E, 0x2B, 0xA9, 0xF2, 0x4C, 0x97, 0x1C, 0x07, 0x3F, + 0x0D, 0x52, 0xF5, 0xED, 0xEF, 0x2F, 0x82, 0x0F +}; + +static const unsigned char TA659_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA660_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA660_RSA_N[] = { + 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80, + 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7, + 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86, + 0xD3, 0xA0, 0x43, 0x7A, 0x4E, 0xB2, 0xA4, 0xD0, 0x36, 0xBA, 0x01, 0xBE, + 0x8D, 0xDB, 0x48, 0xC8, 0x07, 0x17, 0x36, 0x4C, 0xF4, 0xEE, 0x88, 0x23, + 0xC7, 0x3E, 0xEB, 0x37, 0xF5, 0xB5, 0x19, 0xF8, 0x49, 0x68, 0xB0, 0xDE, + 0xD7, 0xB9, 0x76, 0x38, 0x1D, 0x61, 0x9E, 0xA4, 0xFE, 0x82, 0x36, 0xA5, + 0xE5, 0x4A, 0x56, 0xE4, 0x45, 0xE1, 0xF9, 0xFD, 0xB4, 0x16, 0xFA, 0x74, + 0xDA, 0x9C, 0x9B, 0x35, 0x39, 0x2F, 0xFA, 0xB0, 0x20, 0x50, 0x06, 0x6C, + 0x7A, 0xD0, 0x80, 0xB2, 0xA6, 0xF9, 0xAF, 0xEC, 0x47, 0x19, 0x8F, 0x50, + 0x38, 0x07, 0xDC, 0xA2, 0x87, 0x39, 0x58, 0xF8, 0xBA, 0xD5, 0xA9, 0xF9, + 0x48, 0x67, 0x30, 0x96, 0xEE, 0x94, 0x78, 0x5E, 0x6F, 0x89, 0xA3, 0x51, + 0xC0, 0x30, 0x86, 0x66, 0xA1, 0x45, 0x66, 0xBA, 0x54, 0xEB, 0xA3, 0xC3, + 0x91, 0xF9, 0x48, 0xDC, 0xFF, 0xD1, 0xE8, 0x30, 0x2D, 0x7D, 0x2D, 0x74, + 0x70, 0x35, 0xD7, 0x88, 0x24, 0xF7, 0x9E, 0xC4, 0x59, 0x6E, 0xBB, 0x73, + 0x87, 0x17, 0xF2, 0x32, 0x46, 0x28, 0xB8, 0x43, 0xFA, 0xB7, 0x1D, 0xAA, + 0xCA, 0xB4, 0xF2, 0x9F, 0x24, 0x0E, 0x2D, 0x4B, 0xF7, 0x71, 0x5C, 0x5E, + 0x69, 0xFF, 0xEA, 0x95, 0x02, 0xCB, 0x38, 0x8A, 0xAE, 0x50, 0x38, 0x6F, + 0xDB, 0xFB, 0x2D, 0x62, 0x1B, 0xC5, 0xC7, 0x1E, 0x54, 0xE1, 0x77, 0xE0, + 0x67, 0xC8, 0x0F, 0x9C, 0x87, 0x23, 0xD6, 0x3F, 0x40, 0x20, 0x7F, 0x20, + 0x80, 0xC4, 0x80, 0x4C, 0x3E, 0x3B, 0x24, 0x26, 0x8E, 0x04, 0xAE, 0x6C, + 0x9A, 0xC8, 0xAA, 0x0D +}; + +static const unsigned char TA660_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA661_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x4E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4E, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x65, 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x71, 0x75, 0x65, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, + 0x75, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA661_RSA_N[] = { + 0xC3, 0xCD, 0xD3, 0xFC, 0xBD, 0x04, 0x53, 0xDD, 0x0C, 0x20, 0x3A, 0xD5, + 0x88, 0x2E, 0x05, 0x4B, 0x41, 0xF5, 0x83, 0x82, 0x7E, 0xF7, 0x59, 0x9F, + 0x9E, 0x9E, 0x63, 0xE8, 0x73, 0xDA, 0xF6, 0x06, 0xA9, 0x4F, 0x1F, 0xB4, + 0xF9, 0x0B, 0x1F, 0x39, 0x8C, 0x9A, 0x20, 0xD0, 0x7E, 0x06, 0xD4, 0xEC, + 0x34, 0xD9, 0x86, 0xBC, 0x75, 0x5B, 0x87, 0x88, 0xF0, 0xD2, 0xD9, 0xD4, + 0xA3, 0x0A, 0xB2, 0x6C, 0x1B, 0xEB, 0x49, 0x2C, 0x3E, 0xAC, 0x5D, 0xD8, + 0x94, 0x03, 0xA0, 0xEC, 0x34, 0xE5, 0x30, 0xC4, 0x35, 0x7D, 0xFB, 0x26, + 0x4D, 0x1B, 0x6E, 0x30, 0x54, 0xD8, 0xF5, 0x80, 0x45, 0x9C, 0x39, 0xAD, + 0x9C, 0xC9, 0x25, 0x04, 0x4D, 0x9A, 0x90, 0x3E, 0x4E, 0x40, 0x6E, 0x8A, + 0x6B, 0xCD, 0x29, 0x67, 0xC6, 0xCC, 0x2D, 0xE0, 0x74, 0xE8, 0x05, 0x57, + 0x0A, 0x48, 0x50, 0xFA, 0x7A, 0x43, 0xDA, 0x7E, 0xEC, 0x5B, 0x9A, 0x0E, + 0x62, 0x76, 0xFE, 0xEA, 0x9D, 0x1D, 0x85, 0x72, 0xEC, 0x11, 0xBB, 0x35, + 0xE8, 0x1F, 0x27, 0xBF, 0xC1, 0xA1, 0xC7, 0xBB, 0x48, 0x16, 0xDD, 0x56, + 0xD7, 0xCC, 0x4E, 0xA0, 0xE1, 0xB9, 0xAC, 0xDB, 0xD5, 0x83, 0x19, 0x1A, + 0x85, 0xD1, 0x94, 0x97, 0xD7, 0xCA, 0xA3, 0x65, 0x0B, 0xF3, 0x38, 0xF9, + 0x02, 0xAE, 0xDD, 0xF6, 0x67, 0xCF, 0xC9, 0x3F, 0xF5, 0x8A, 0x2C, 0x47, + 0x1A, 0x99, 0x6F, 0x05, 0x0D, 0xFD, 0xD0, 0x1D, 0x82, 0x31, 0xFC, 0x29, + 0xCC, 0x00, 0x58, 0x97, 0x91, 0x4C, 0x80, 0x00, 0x1C, 0x33, 0x85, 0x96, + 0x2F, 0xCB, 0x41, 0xC2, 0x8B, 0x10, 0x84, 0xC3, 0x09, 0x24, 0x89, 0x1F, + 0xB5, 0x0F, 0xD9, 0xD9, 0x77, 0x47, 0x18, 0x92, 0x94, 0x60, 0x5C, 0xC7, + 0x99, 0x03, 0x3C, 0xFE, 0xF7, 0x95, 0xA7, 0x7D, 0x50, 0xA1, 0x80, 0xC2, + 0xA9, 0x83, 0xAD, 0x58, 0x96, 0x55, 0x21, 0xDB, 0x86, 0x59, 0xD4, 0xAF, + 0xC6, 0xBC, 0xDD, 0x81, 0x6E, 0x07, 0xDB, 0x60, 0x62, 0xFE, 0xEC, 0x10, + 0x6E, 0xDA, 0x68, 0x01, 0xF4, 0x83, 0x1B, 0xA9, 0x3E, 0xA2, 0x5B, 0x23, + 0xD7, 0x64, 0xC6, 0xDF, 0xDC, 0xA2, 0x7D, 0xD8, 0x4B, 0xBA, 0x82, 0xD2, + 0x51, 0xF8, 0x66, 0xBF, 0x06, 0x46, 0xE4, 0x79, 0x2A, 0x26, 0x36, 0x79, + 0x8F, 0x1F, 0x4E, 0x99, 0x1D, 0xB2, 0x8F, 0x0C, 0x0E, 0x1C, 0xFF, 0xC9, + 0x5D, 0xC0, 0xFD, 0x90, 0x10, 0xA6, 0xB1, 0x37, 0xF3, 0xCD, 0x3A, 0x24, + 0x6E, 0xB4, 0x85, 0x90, 0xBF, 0x80, 0xB9, 0x0C, 0x8C, 0xD5, 0x9B, 0xD6, + 0xC8, 0xF1, 0x56, 0x3F, 0x1A, 0x80, 0x89, 0x7A, 0xA9, 0xE2, 0x1B, 0x32, + 0x51, 0x2C, 0x3E, 0xF2, 0xDF, 0x7B, 0xF6, 0x5D, 0x7A, 0x29, 0x19, 0x8E, + 0xE5, 0xC8, 0xBD, 0x36, 0x71, 0x8B, 0x5D, 0x4C, 0xC2, 0x1D, 0x3F, 0xAD, + 0x58, 0xA2, 0xCF, 0x3D, 0x70, 0x4D, 0xA6, 0x50, 0x98, 0x25, 0xDC, 0x23, + 0xF9, 0xB8, 0x58, 0x41, 0x08, 0x71, 0xBF, 0x4F, 0xB8, 0x84, 0xA0, 0x8F, + 0x00, 0x54, 0x15, 0xFC, 0x91, 0x6D, 0x58, 0xA7, 0x96, 0x3B, 0xEB, 0x4B, + 0x96, 0x27, 0xCD, 0x6B, 0xA2, 0xA1, 0x86, 0xAC, 0x0D, 0x7C, 0x54, 0xE6, + 0x66, 0x4C, 0x66, 0x5F, 0x90, 0xBE, 0x21, 0x9A, 0x02, 0x46, 0x2D, 0xE4, + 0x83, 0xC2, 0x80, 0xB9, 0xCF, 0x4B, 0x3E, 0xE8, 0x7F, 0x3C, 0x01, 0xEC, + 0x8F, 0x5E, 0xCD, 0x7F, 0xD2, 0x28, 0x42, 0x01, 0x95, 0x8A, 0xE2, 0x97, + 0x3D, 0x10, 0x21, 0x7D, 0xF6, 0x9D, 0x1C, 0xC5, 0x34, 0xA1, 0xEC, 0x2C, + 0x0E, 0x0A, 0x52, 0x2C, 0x12, 0x55, 0x70, 0x24, 0x3D, 0xCB, 0xC2, 0x14, + 0x35, 0x43, 0x5D, 0x27, 0x4E, 0xBE, 0xC0, 0xBD, 0xAA, 0x7C, 0x96, 0xE7, + 0xFC, 0x9E, 0x61, 0xAD, 0x44, 0xD3, 0x00, 0x97 +}; + +static const unsigned char TA661_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA662_DN[] = { + 0x30, 0x34, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x08, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61 +}; + +static const unsigned char TA662_RSA_N[] = { + 0xC8, 0x68, 0xF1, 0xC9, 0xD6, 0xD6, 0xB3, 0x34, 0x75, 0x26, 0x82, 0x1E, + 0xEC, 0xB4, 0xBE, 0xEA, 0x5C, 0xE1, 0x26, 0xED, 0x11, 0x47, 0x61, 0xE1, + 0xA2, 0x7C, 0x16, 0x78, 0x40, 0x21, 0xE4, 0x60, 0x9E, 0x5A, 0xC8, 0x63, + 0xE1, 0xC4, 0xB1, 0x96, 0x92, 0xFF, 0x18, 0x6D, 0x69, 0x23, 0xE1, 0x2B, + 0x62, 0xF7, 0xDD, 0xE2, 0x36, 0x2F, 0x91, 0x07, 0xB9, 0x48, 0xCF, 0x0E, + 0xEC, 0x79, 0xB6, 0x2C, 0xE7, 0x34, 0x4B, 0x70, 0x08, 0x25, 0xA3, 0x3C, + 0x87, 0x1B, 0x19, 0xF2, 0x81, 0x07, 0x0F, 0x38, 0x90, 0x19, 0xD3, 0x11, + 0xFE, 0x86, 0xB4, 0xF2, 0xD1, 0x5E, 0x1E, 0x1E, 0x96, 0xCD, 0x80, 0x6C, + 0xCE, 0x3B, 0x31, 0x93, 0xB6, 0xF2, 0xA0, 0xD0, 0xA9, 0x95, 0x12, 0x7D, + 0xA5, 0x9A, 0xCC, 0x6B, 0xC8, 0x84, 0x56, 0x8A, 0x33, 0xA9, 0xE7, 0x22, + 0x15, 0x53, 0x16, 0xF0, 0xCC, 0x17, 0xEC, 0x57, 0x5F, 0xE9, 0xA2, 0x0A, + 0x98, 0x09, 0xDE, 0xE3, 0x5F, 0x9C, 0x6F, 0xDC, 0x48, 0xE3, 0x85, 0x0B, + 0x15, 0x5A, 0xA6, 0xBA, 0x9F, 0xAC, 0x48, 0xE3, 0x09, 0xB2, 0xF7, 0xF4, + 0x32, 0xDE, 0x5E, 0x34, 0xBE, 0x1C, 0x78, 0x5D, 0x42, 0x5B, 0xCE, 0x0E, + 0x22, 0x8F, 0x4D, 0x90, 0xD7, 0x7D, 0x32, 0x18, 0xB3, 0x0B, 0x2C, 0x6A, + 0xBF, 0x8E, 0x3F, 0x14, 0x11, 0x89, 0x20, 0x0E, 0x77, 0x14, 0xB5, 0x3D, + 0x94, 0x08, 0x87, 0xF7, 0x25, 0x1E, 0xD5, 0xB2, 0x60, 0x00, 0xEC, 0x6F, + 0x2A, 0x28, 0x25, 0x6E, 0x2A, 0x3E, 0x18, 0x63, 0x17, 0x25, 0x3F, 0x3E, + 0x44, 0x20, 0x16, 0xF6, 0x26, 0xC8, 0x25, 0xAE, 0x05, 0x4A, 0xB4, 0xE7, + 0x63, 0x2C, 0xF3, 0x8C, 0x16, 0x53, 0x7E, 0x5C, 0xFB, 0x11, 0x1A, 0x08, + 0xC1, 0x46, 0x62, 0x9F, 0x22, 0xB8, 0xF1, 0xC2, 0x8D, 0x69, 0xDC, 0xFA, + 0x3A, 0x58, 0x06, 0xDF +}; + +static const unsigned char TA662_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA663_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1F, 0x4B, 0x72, 0x61, 0x6A, 0x6F, 0x77, 0x61, 0x20, 0x49, 0x7A, + 0x62, 0x61, 0x20, 0x52, 0x6F, 0x7A, 0x6C, 0x69, 0x63, 0x7A, 0x65, 0x6E, + 0x69, 0x6F, 0x77, 0x61, 0x20, 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x53, 0x5A, 0x41, 0x46, + 0x49, 0x52, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA663_RSA_N[] = { + 0xB7, 0xBC, 0x3E, 0x50, 0xA8, 0x4B, 0xCD, 0x40, 0xB5, 0xCE, 0x61, 0xE7, + 0x96, 0xCA, 0xB4, 0xA1, 0xDA, 0x0C, 0x22, 0xB0, 0xFA, 0xB5, 0x7B, 0x76, + 0x00, 0x77, 0x8C, 0x0B, 0xCF, 0x7D, 0xA8, 0x86, 0xCC, 0x26, 0x51, 0xE4, + 0x20, 0x3D, 0x85, 0x0C, 0xD6, 0x58, 0xE3, 0xE7, 0xF4, 0x2A, 0x18, 0x9D, + 0xDA, 0xD1, 0xAE, 0x26, 0xEE, 0xEB, 0x53, 0xDC, 0xF4, 0x90, 0xD6, 0x13, + 0x4A, 0x0C, 0x90, 0x3C, 0xC3, 0xF4, 0xDA, 0xD2, 0x8E, 0x0D, 0x92, 0x3A, + 0xDC, 0xB1, 0xB1, 0xFF, 0x38, 0xDE, 0xC3, 0xBA, 0x2D, 0x5F, 0x80, 0xB9, + 0x02, 0xBD, 0x4A, 0x9D, 0x1B, 0x0F, 0xB4, 0xC3, 0xC2, 0xC1, 0x67, 0x03, + 0xDD, 0xDC, 0x1B, 0x9C, 0x3D, 0xB3, 0xB0, 0xDE, 0x00, 0x1E, 0xA8, 0x34, + 0x47, 0xBB, 0x9A, 0xEB, 0xFE, 0x0B, 0x14, 0xBD, 0x36, 0x84, 0xDA, 0x0D, + 0x20, 0xBF, 0xFA, 0x5B, 0xCB, 0xA9, 0x16, 0x20, 0xAD, 0x39, 0x60, 0xEE, + 0x2F, 0x75, 0xB6, 0xE7, 0x97, 0x9C, 0xF9, 0x3E, 0xFD, 0x7E, 0x4D, 0x6F, + 0x4D, 0x2F, 0xEF, 0x88, 0x0D, 0x6A, 0xFA, 0xDD, 0xF1, 0x3D, 0x6E, 0x20, + 0xA5, 0xA0, 0x12, 0xB4, 0x4D, 0x70, 0xB9, 0xCE, 0xD7, 0x72, 0x3B, 0x89, + 0x93, 0xA7, 0x80, 0x84, 0x1C, 0x27, 0x49, 0x72, 0x49, 0xB5, 0xFF, 0x3B, + 0x95, 0x9E, 0xC1, 0xCC, 0xC8, 0x01, 0xEC, 0xE8, 0x0E, 0x8A, 0x0A, 0x96, + 0xE7, 0xB3, 0xA6, 0x87, 0xE5, 0xD6, 0xF9, 0x05, 0x2B, 0x0D, 0x97, 0x40, + 0x70, 0x3C, 0xBA, 0xAC, 0x75, 0x5A, 0x9C, 0xD5, 0x4D, 0x9D, 0x02, 0x0A, + 0xD2, 0x4B, 0x9B, 0x66, 0x4B, 0x46, 0x07, 0x17, 0x65, 0xAD, 0x9F, 0x6C, + 0x88, 0x00, 0xDC, 0x22, 0x89, 0xE0, 0xE1, 0x64, 0xD4, 0x67, 0xBC, 0x31, + 0x79, 0x61, 0x3C, 0xBB, 0xCA, 0x41, 0xCD, 0x5C, 0x6A, 0x00, 0xC8, 0x3C, + 0x38, 0x8E, 0x58, 0xAF +}; + +static const unsigned char TA663_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA664_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, 0x36 +}; + +static const unsigned char TA664_EC_Q[] = { + 0x04, 0x9C, 0x0E, 0xB1, 0xCF, 0xB7, 0xE8, 0x9E, 0x52, 0x77, 0x75, 0x34, + 0xFA, 0xA5, 0x46, 0xA7, 0xAD, 0x32, 0x19, 0x32, 0xB4, 0x07, 0xA9, 0x27, + 0xCA, 0x94, 0xBB, 0x0C, 0xD2, 0x0A, 0x10, 0xC7, 0xDA, 0x89, 0xB0, 0x97, + 0x0C, 0x70, 0x13, 0x09, 0x01, 0x8E, 0xD8, 0xEA, 0x47, 0xEA, 0xBE, 0xB2, + 0x80, 0x2B, 0xCD, 0xFC, 0x28, 0x0D, 0xDB, 0xAC, 0xBC, 0xA4, 0x86, 0x37, + 0xED, 0x70, 0x08, 0x00, 0x75, 0xEA, 0x93, 0x0B, 0x7B, 0x2E, 0x52, 0x9C, + 0x23, 0x68, 0x23, 0x06, 0x43, 0xEC, 0x92, 0x2F, 0x53, 0x84, 0xDB, 0xFB, + 0x47, 0x14, 0x07, 0xE8, 0x5F, 0x94, 0x67, 0x5D, 0xC9, 0x7A, 0x81, 0x3C, + 0x20 +}; + +static const unsigned char TA665_DN[] = { + 0x30, 0x81, 0xD2, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x54, 0x52, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x0F, 0x47, 0x65, 0x62, 0x7A, 0x65, 0x20, 0x2D, 0x20, 0x4B, + 0x6F, 0x63, 0x61, 0x65, 0x6C, 0x69, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x13, 0x39, 0x54, 0x75, 0x72, 0x6B, 0x69, 0x79, 0x65, + 0x20, 0x42, 0x69, 0x6C, 0x69, 0x6D, 0x73, 0x65, 0x6C, 0x20, 0x76, 0x65, + 0x20, 0x54, 0x65, 0x6B, 0x6E, 0x6F, 0x6C, 0x6F, 0x6A, 0x69, 0x6B, 0x20, + 0x41, 0x72, 0x61, 0x73, 0x74, 0x69, 0x72, 0x6D, 0x61, 0x20, 0x4B, 0x75, + 0x72, 0x75, 0x6D, 0x75, 0x20, 0x2D, 0x20, 0x54, 0x55, 0x42, 0x49, 0x54, + 0x41, 0x4B, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x24, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x6B, 0x61, 0x73, 0x79, 0x6F, 0x6E, 0x20, 0x4D, 0x65, 0x72, 0x6B, + 0x65, 0x7A, 0x69, 0x20, 0x2D, 0x20, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, + 0x4D, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, + 0x54, 0x55, 0x42, 0x49, 0x54, 0x41, 0x4B, 0x20, 0x4B, 0x61, 0x6D, 0x75, + 0x20, 0x53, 0x4D, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x4B, 0x6F, 0x6B, 0x20, + 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6B, 0x61, 0x73, 0x69, 0x20, + 0x2D, 0x20, 0x53, 0x75, 0x72, 0x75, 0x6D, 0x20, 0x31 +}; + +static const unsigned char TA665_RSA_N[] = { + 0xAF, 0x75, 0x30, 0x33, 0xAA, 0xBB, 0x6B, 0xD3, 0x99, 0x2C, 0x12, 0x37, + 0x84, 0xD9, 0x8D, 0x7B, 0x97, 0x80, 0xD3, 0x6E, 0xE7, 0xFF, 0x9B, 0x50, + 0x95, 0x3E, 0x90, 0x95, 0x56, 0x42, 0xD7, 0x19, 0x7C, 0x26, 0x84, 0x8D, + 0x92, 0xFA, 0x01, 0x1D, 0x3A, 0x0F, 0xE2, 0x64, 0x38, 0xB7, 0x8C, 0xBC, + 0xE8, 0x88, 0xF9, 0x8B, 0x24, 0xAB, 0x2E, 0xA3, 0xF5, 0x37, 0xE4, 0x40, + 0x8E, 0x18, 0x25, 0x79, 0x83, 0x75, 0x1F, 0x3B, 0xFF, 0x6C, 0xA8, 0xC5, + 0xC6, 0x56, 0xF8, 0xB4, 0xED, 0x8A, 0x44, 0xA3, 0xAB, 0x6C, 0x4C, 0xFC, + 0x1D, 0xD0, 0xDC, 0xEF, 0x68, 0xBD, 0xCF, 0xE4, 0xAA, 0xCE, 0xF0, 0x55, + 0xF7, 0xA2, 0x34, 0xD4, 0x83, 0x6B, 0x37, 0x7C, 0x1C, 0xC2, 0xFE, 0xB5, + 0x03, 0xEC, 0x57, 0xCE, 0xBC, 0xB4, 0xB5, 0xC5, 0xED, 0x00, 0x0F, 0x53, + 0x37, 0x2A, 0x4D, 0xF4, 0x4F, 0x0C, 0x83, 0xFB, 0x86, 0xCF, 0xCB, 0xFE, + 0x8C, 0x4E, 0xBD, 0x87, 0xF9, 0xA7, 0x8B, 0x21, 0x57, 0x9C, 0x7A, 0xDF, + 0x03, 0x67, 0x89, 0x2C, 0x9D, 0x97, 0x61, 0xA7, 0x10, 0xB8, 0x55, 0x90, + 0x7F, 0x0E, 0x2D, 0x27, 0x38, 0x74, 0xDF, 0xE7, 0xFD, 0xDA, 0x4E, 0x12, + 0xE3, 0x4D, 0x15, 0x22, 0x02, 0xC8, 0xE0, 0xE0, 0xFC, 0x0F, 0xAD, 0x8A, + 0xD7, 0xC9, 0x54, 0x50, 0xCC, 0x3B, 0x0F, 0xCA, 0x16, 0x80, 0x84, 0xD0, + 0x51, 0x56, 0xC3, 0x8E, 0x56, 0x7F, 0x89, 0x22, 0x33, 0x2F, 0xE6, 0x85, + 0x0A, 0xBD, 0xA5, 0xA8, 0x1B, 0x36, 0xDE, 0xD3, 0xDC, 0x2C, 0x6D, 0x3B, + 0xC7, 0x13, 0xBD, 0x59, 0x23, 0x2C, 0xE6, 0xE5, 0xA4, 0xF7, 0xD8, 0x0B, + 0xED, 0xEA, 0x90, 0x40, 0x44, 0xA8, 0x95, 0xBB, 0x93, 0xD5, 0xD0, 0x80, + 0x34, 0xB6, 0x46, 0x78, 0x0E, 0x1F, 0x00, 0x93, 0x46, 0xE1, 0xEE, 0xE9, + 0xF9, 0xEC, 0x4F, 0x17 +}; + +static const unsigned char TA665_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA666_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x31 +}; + +static const unsigned char TA666_RSA_N[] = { + 0xF1, 0x66, 0x08, 0xBD, 0xD9, 0xC5, 0x15, 0x61, 0xCB, 0x84, 0x04, 0x41, + 0xA5, 0x69, 0x37, 0x77, 0x1D, 0xC1, 0xB0, 0x7B, 0xFA, 0xC3, 0x77, 0x48, + 0x90, 0x13, 0x72, 0x64, 0xD1, 0xB8, 0x7C, 0x90, 0x35, 0x9D, 0x18, 0x79, + 0x88, 0xE3, 0x97, 0x01, 0x3C, 0x47, 0x81, 0xF2, 0x0E, 0xA2, 0x98, 0x0D, + 0x9E, 0x3F, 0x37, 0xE0, 0x19, 0xB2, 0x90, 0xF2, 0x46, 0x1C, 0x92, 0xB1, + 0x3A, 0x61, 0xCE, 0xFA, 0xB7, 0x46, 0x9E, 0x03, 0x86, 0xD7, 0x33, 0x6E, + 0xED, 0xF7, 0x45, 0x8C, 0x76, 0x37, 0xDE, 0x6E, 0x96, 0x91, 0xF7, 0xD7, + 0x7E, 0x2B, 0x87, 0x17, 0xD5, 0x8B, 0x35, 0xEE, 0x84, 0x91, 0x72, 0x57, + 0xDC, 0x60, 0xC3, 0xC3, 0xB9, 0xE7, 0xC7, 0x67, 0x24, 0x23, 0x4F, 0x63, + 0x0A, 0x63, 0xF6, 0x66, 0x7D, 0x4B, 0x55, 0xA7, 0x3F, 0x78, 0x64, 0x49, + 0x69, 0x12, 0x97, 0xE0, 0x4C, 0x0D, 0xD3, 0x09, 0xA0, 0x32, 0x30, 0x3A, + 0xFA, 0x9F, 0xC0, 0xF2, 0x9C, 0xC5, 0x12, 0x2A, 0x2E, 0x1C, 0xB5, 0x04, + 0x33, 0xDA, 0xA4, 0x38, 0x11, 0x6A, 0xDE, 0xC6, 0x18, 0xF6, 0x47, 0x3A, + 0x22, 0x41, 0x87, 0x22, 0xFC, 0xC4, 0x89, 0x28, 0x54, 0xD8, 0x8C, 0xA5, + 0x30, 0x0A, 0xF8, 0x17, 0x16, 0xCA, 0xAC, 0x37, 0xFD, 0x79, 0xA7, 0x91, + 0x17, 0x78, 0x38, 0x99, 0xAD, 0x58, 0xED, 0xB2, 0xDE, 0xCC, 0x89, 0x7D, + 0x03, 0x9C, 0xB3, 0x89, 0x65, 0xE7, 0xE3, 0x3B, 0xB1, 0x22, 0x86, 0x8F, + 0x06, 0x6D, 0x78, 0x07, 0xFD, 0x91, 0x12, 0x7F, 0xB0, 0x6B, 0x1C, 0x89, + 0x0D, 0xF9, 0xB8, 0xCB, 0x74, 0x5B, 0x07, 0xC2, 0xC8, 0xF4, 0x35, 0xD1, + 0x64, 0x63, 0x7A, 0xE9, 0x6E, 0x9A, 0x28, 0xD6, 0x30, 0xBD, 0xE6, 0x1B, + 0xDD, 0x15, 0xAF, 0x84, 0xEA, 0x9C, 0xC7, 0xCA, 0xF5, 0x0E, 0xEA, 0xF2, + 0x5D, 0x29, 0x87, 0x8F, 0x69, 0x73, 0x39, 0xBE, 0x2E, 0x24, 0x6F, 0x45, + 0x21, 0xAC, 0xC5, 0xD4, 0x69, 0x25, 0x06, 0x83, 0xAD, 0x7A, 0x48, 0x85, + 0x13, 0x2C, 0x0D, 0x06, 0xB8, 0x6C, 0x79, 0x56, 0xFC, 0xA3, 0x67, 0x32, + 0x81, 0xF5, 0x57, 0xA5, 0xCA, 0x57, 0x42, 0x69, 0xE9, 0x5C, 0x24, 0x61, + 0xEF, 0xE2, 0x30, 0x18, 0x4E, 0x44, 0x98, 0x55, 0x6F, 0x7A, 0xC2, 0x93, + 0xD8, 0x19, 0xB6, 0xDE, 0x7C, 0x47, 0x8A, 0x11, 0x4E, 0x49, 0x47, 0xDB, + 0x28, 0x94, 0x02, 0x0B, 0x94, 0x4A, 0x2C, 0xF9, 0x12, 0xD0, 0x4F, 0xE8, + 0x31, 0x7E, 0x6C, 0x7A, 0xBF, 0xA6, 0x3F, 0x9B, 0x39, 0x3D, 0x02, 0x16, + 0xA3, 0x18, 0xB3, 0x67, 0xAC, 0x5B, 0x3F, 0x2C, 0x83, 0x2B, 0x67, 0x39, + 0x81, 0x5C, 0xB9, 0x7E, 0x94, 0xD5, 0x64, 0xDD, 0x9E, 0x8F, 0x6E, 0xAE, + 0xE8, 0x7C, 0x5B, 0xB4, 0xD7, 0x6A, 0x47, 0x48, 0xD7, 0x7E, 0xB3, 0xD4, + 0x2D, 0x8E, 0x56, 0x76, 0x4E, 0xCF, 0x69, 0xF1, 0x6E, 0x44, 0x6C, 0xD4, + 0x24, 0xEA, 0x8D, 0x24, 0xA1, 0x18, 0xBF, 0xBD, 0x57, 0xFE, 0xA9, 0x99, + 0x35, 0xB5, 0xDB, 0x10, 0x77, 0xB8, 0x3D, 0x48, 0xBA, 0xD6, 0xC1, 0xE7, + 0xF1, 0x23, 0x3E, 0xD7, 0xDF, 0x85, 0x9D, 0x27, 0x3C, 0xD4, 0x40, 0xBD, + 0x0A, 0x0C, 0xBD, 0xF5, 0xE7, 0x8D, 0x25, 0xD6, 0x81, 0x74, 0x87, 0x46, + 0xD4, 0x29, 0x75, 0xA2, 0x42, 0x6C, 0xF7, 0x73, 0x89, 0xE7, 0x7D, 0xBF, + 0x7A, 0x4A, 0x1F, 0xD3, 0x22, 0xC9, 0x15, 0x55, 0xCF, 0xDF, 0x6F, 0x7C, + 0x55, 0xD0, 0xA4, 0x8B, 0x07, 0x11, 0x37, 0x5F, 0x83, 0xA6, 0x26, 0x57, + 0xA6, 0x01, 0x5B, 0x7E, 0xFE, 0x58, 0x68, 0x07, 0xA9, 0xE9, 0x7A, 0xD9, + 0xB9, 0xE8, 0xFF, 0x50, 0x1F, 0xAB, 0xC2, 0xB4, 0xC0, 0xCE, 0xE8, 0xEA, + 0xFD, 0x0F, 0xBD, 0x8D, 0x4D, 0xB8, 0xBC, 0x71 +}; + +static const unsigned char TA666_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA667_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA667_RSA_N[] = { + 0xAE, 0xFF, 0x09, 0x59, 0x91, 0x80, 0x0A, 0x4A, 0x68, 0xE6, 0x24, 0x3F, + 0xB8, 0xA7, 0xE4, 0xC8, 0x3A, 0x0A, 0x3A, 0x16, 0xCD, 0xC9, 0x23, 0x61, + 0xA0, 0x93, 0x71, 0xF2, 0xAB, 0x8B, 0x73, 0x8F, 0xA0, 0x67, 0x65, 0x60, + 0xD2, 0x54, 0x6B, 0x63, 0x51, 0x6F, 0x49, 0x33, 0xE0, 0x72, 0x07, 0x13, + 0x7D, 0x38, 0xCD, 0x06, 0x92, 0x07, 0x29, 0x52, 0x6B, 0x4E, 0x77, 0x6C, + 0x04, 0xD3, 0x95, 0xFA, 0xDD, 0x4C, 0x8C, 0xD9, 0x5D, 0xC1, 0x61, 0x7D, + 0x4B, 0xE7, 0x28, 0xB3, 0x44, 0x81, 0x7B, 0x51, 0xAF, 0xDD, 0x33, 0xB1, + 0x68, 0x7C, 0xD6, 0x4E, 0x4C, 0xFE, 0x2B, 0x68, 0xB9, 0xCA, 0x66, 0x69, + 0xC4, 0xEC, 0x5E, 0x57, 0x7F, 0xF7, 0x0D, 0xC7, 0x9C, 0x36, 0x36, 0xE5, + 0x07, 0x60, 0xAC, 0xC0, 0x4C, 0xEA, 0x08, 0x6C, 0xEF, 0x06, 0x7C, 0x4F, + 0x5B, 0x28, 0x7A, 0x08, 0xFC, 0x93, 0x5D, 0x9B, 0xF6, 0x9C, 0xB4, 0x8B, + 0x86, 0xBA, 0x21, 0xB9, 0xF4, 0xF0, 0xE8, 0x59, 0x5A, 0x28, 0xA1, 0x34, + 0x84, 0x1A, 0x25, 0x91, 0xB6, 0xB5, 0x8F, 0xEF, 0xB2, 0xF9, 0x80, 0xFA, + 0xF9, 0x3D, 0x3C, 0x11, 0x72, 0xD8, 0xE3, 0x2F, 0x86, 0x76, 0xC5, 0x79, + 0x2C, 0xC1, 0xA9, 0x90, 0x93, 0x46, 0x98, 0x67, 0xCB, 0x83, 0x6A, 0xA0, + 0x50, 0x23, 0xA7, 0x3B, 0xF6, 0x81, 0x39, 0xE0, 0xED, 0xF0, 0xB9, 0xBF, + 0x65, 0xF1, 0xD8, 0xCB, 0x7A, 0xFB, 0xEF, 0x73, 0x03, 0xCE, 0x00, 0xF4, + 0x7D, 0xD7, 0xE0, 0x5D, 0x3B, 0x66, 0xB8, 0xDC, 0x8E, 0xBA, 0x83, 0xCB, + 0x87, 0x76, 0x03, 0xFC, 0x25, 0xD9, 0xE7, 0x23, 0x6F, 0x06, 0xFD, 0x67, + 0xF3, 0xE0, 0xFF, 0x84, 0xBC, 0x47, 0xBF, 0xB5, 0x16, 0x18, 0x46, 0x69, + 0x14, 0xCC, 0x05, 0xF7, 0xDB, 0xD3, 0x49, 0xAC, 0x6B, 0xCC, 0xAB, 0xE4, + 0xB5, 0x0B, 0x43, 0x24, 0x5E, 0x4B, 0x6B, 0x4D, 0x67, 0xDF, 0xD6, 0xB5, + 0x3E, 0x4F, 0x78, 0x1F, 0x94, 0x71, 0x24, 0xEA, 0xDE, 0x70, 0xFC, 0xF1, + 0x93, 0xFE, 0x9E, 0x93, 0x5A, 0xE4, 0x94, 0x5A, 0x97, 0x54, 0x0C, 0x35, + 0x7B, 0x5F, 0x6C, 0xEE, 0x00, 0x1F, 0x24, 0xEC, 0x03, 0xBA, 0x02, 0xF5, + 0x76, 0xF4, 0x9F, 0xD4, 0x9A, 0xED, 0x85, 0x2C, 0x38, 0x22, 0x2F, 0xC7, + 0xD8, 0x2F, 0x76, 0x11, 0x4F, 0xFD, 0x6C, 0x5C, 0xE8, 0xF5, 0x8E, 0x27, + 0x87, 0x7F, 0x19, 0x4A, 0x21, 0x47, 0x90, 0x1D, 0x79, 0x8D, 0x1C, 0x5B, + 0xF8, 0xCF, 0x4A, 0x85, 0xE4, 0xED, 0xB3, 0x5B, 0x8D, 0xBE, 0xC4, 0x64, + 0x28, 0x5D, 0x41, 0xC4, 0x6E, 0xAC, 0x38, 0x5A, 0x4F, 0x23, 0x74, 0x74, + 0xA9, 0x12, 0xC3, 0xF6, 0xD2, 0xB9, 0x11, 0x15, 0x33, 0x07, 0x91, 0xD8, + 0x3B, 0x37, 0x3A, 0x63, 0x30, 0x06, 0xD1, 0xC5, 0x22, 0x36, 0x28, 0x62, + 0x23, 0x10, 0xE0, 0x46, 0xCC, 0x97, 0xAC, 0xD6, 0x2B, 0x5D, 0x64, 0x24, + 0xD5, 0xEE, 0x1C, 0x0E, 0xDE, 0xFB, 0x08, 0x5A, 0x75, 0x2A, 0xF6, 0x63, + 0x6D, 0xCE, 0x0B, 0x42, 0xBE, 0xD1, 0xBA, 0x70, 0x1C, 0x9C, 0x21, 0xE5, + 0x0F, 0x31, 0x69, 0x17, 0xD7, 0xFC, 0x0A, 0xB4, 0xDE, 0xED, 0x80, 0x9C, + 0xCB, 0x92, 0xB4, 0x8B, 0xF5, 0xDE, 0x59, 0xA2, 0x58, 0x09, 0xA5, 0x63, + 0x47, 0x0B, 0xE1, 0x41, 0x32, 0x34, 0x41, 0xD9, 0x9A, 0xB1, 0xD9, 0xA8, + 0xB0, 0x1B, 0x5A, 0xDE, 0x0D, 0x0D, 0xF4, 0xE2, 0xB2, 0x5D, 0x35, 0x80, + 0xB9, 0x81, 0xD4, 0x84, 0x69, 0x91, 0x02, 0xCB, 0x75, 0xD0, 0x8D, 0xC5, + 0xB5, 0x3D, 0x09, 0x91, 0x09, 0x8F, 0x14, 0xA1, 0x14, 0x74, 0x79, 0x3E, + 0xD6, 0xC9, 0x15, 0x1D, 0xA4, 0x59, 0x59, 0x22, 0xDC, 0xF6, 0x8A, 0x45, + 0x3D, 0x3C, 0x12, 0xD6, 0x3E, 0x5D, 0x32, 0x2F +}; + +static const unsigned char TA667_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA668_DN[] = { + 0x30, 0x6E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x13, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, 0x6F, 0x66, 0x65, + 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x53, 0x41, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0F, 0x56, 0x41, 0x54, 0x45, + 0x53, 0x2D, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x46, 0x49, + 0x52, 0x4D, 0x41, 0x50, 0x52, 0x4F, 0x46, 0x45, 0x53, 0x49, 0x4F, 0x4E, + 0x41, 0x4C, 0x20, 0x43, 0x41, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x2D, 0x41, + 0x20, 0x57, 0x45, 0x42 +}; + +static const unsigned char TA668_EC_Q[] = { + 0x04, 0x47, 0x53, 0xEA, 0x2C, 0x11, 0xA4, 0x77, 0xC7, 0x2A, 0xEA, 0xF3, + 0xD6, 0x5F, 0x7B, 0xD3, 0x04, 0x91, 0x5C, 0xFA, 0x88, 0xC6, 0x22, 0xB9, + 0x83, 0x10, 0x62, 0x77, 0x84, 0x33, 0x2D, 0xE9, 0x03, 0x88, 0xD4, 0xE0, + 0x33, 0xF7, 0xED, 0x77, 0x2C, 0x4A, 0x60, 0xEA, 0xE4, 0x6F, 0xAD, 0x6D, + 0xB4, 0xF8, 0x4C, 0x8A, 0xA4, 0xE4, 0x1F, 0xCA, 0xEA, 0x4F, 0x38, 0x4A, + 0x2E, 0x82, 0x73, 0x2B, 0xC7, 0x66, 0x9B, 0x0A, 0x8C, 0x40, 0x9C, 0x7C, + 0x8A, 0xF6, 0xF2, 0x39, 0x60, 0xB2, 0xDE, 0xCB, 0xEC, 0xB8, 0xE4, 0x6F, + 0xEA, 0x9B, 0x5D, 0xB7, 0x53, 0x90, 0x18, 0x32, 0x55, 0xC5, 0x20, 0xB7, + 0x94 +}; + +static const unsigned char TA669_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x29, 0x47, 0x55, 0x41, 0x4E, 0x47, 0x20, 0x44, 0x4F, 0x4E, 0x47, + 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, + 0x20, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x20, 0x43, + 0x4F, 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x47, 0x44, 0x43, 0x41, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x41, 0x55, 0x54, 0x48, 0x20, 0x52, 0x35, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA669_RSA_N[] = { + 0xD9, 0xA3, 0x16, 0xF0, 0xC8, 0x74, 0x74, 0x77, 0x9B, 0xEF, 0x33, 0x0D, + 0x3B, 0x06, 0x7E, 0x55, 0xFC, 0xB5, 0x60, 0x8F, 0x76, 0x86, 0x12, 0x42, + 0x7D, 0x56, 0x66, 0x3E, 0x88, 0x82, 0xED, 0x72, 0x63, 0x0E, 0x9E, 0x8B, + 0xDD, 0x34, 0x2C, 0x02, 0x51, 0x51, 0xC3, 0x19, 0xFD, 0x59, 0x54, 0x84, + 0xC9, 0xF1, 0x6B, 0xB3, 0x4C, 0xB0, 0xE9, 0xE8, 0x46, 0x5D, 0x38, 0xC6, + 0xA2, 0xA7, 0x2E, 0x11, 0x57, 0xBA, 0x82, 0x15, 0xA2, 0x9C, 0x8F, 0x6D, + 0xB0, 0x99, 0x4A, 0x0A, 0xF2, 0xEB, 0x89, 0x70, 0x63, 0x4E, 0x79, 0xC4, + 0xB7, 0x5B, 0xBD, 0xA2, 0x5D, 0xB1, 0xF2, 0x41, 0x02, 0x2B, 0xAD, 0xA9, + 0x3A, 0xA3, 0xEC, 0x79, 0x0A, 0xEC, 0x5F, 0x3A, 0xE3, 0xFD, 0xEF, 0x80, + 0x3C, 0xAD, 0x34, 0x9B, 0x1A, 0xAB, 0x88, 0x26, 0x7B, 0x56, 0xA2, 0x82, + 0x86, 0x1F, 0xEB, 0x35, 0x89, 0x83, 0x7F, 0x5F, 0xAE, 0x29, 0x4E, 0x3D, + 0xB6, 0x6E, 0xEC, 0xAE, 0xC1, 0xF0, 0x27, 0x9B, 0xAE, 0xE3, 0xF4, 0xEC, + 0xEF, 0xAE, 0x7F, 0xF7, 0x86, 0x3D, 0x72, 0x7A, 0xEB, 0xA5, 0xFB, 0x59, + 0x4E, 0xA7, 0xEB, 0x95, 0x8C, 0x22, 0x39, 0x79, 0xE1, 0x2D, 0x08, 0x8F, + 0xCC, 0xBC, 0x91, 0xB8, 0x41, 0xF7, 0x14, 0xC1, 0x23, 0xA9, 0xC3, 0xAD, + 0x9A, 0x45, 0x44, 0xB3, 0xB2, 0xD7, 0x2C, 0xCD, 0xC6, 0x29, 0xE2, 0x50, + 0x10, 0xAE, 0x5C, 0xCB, 0x82, 0x8E, 0x17, 0x18, 0x36, 0x7D, 0x97, 0xE6, + 0x88, 0x9A, 0xB0, 0x4D, 0x34, 0x09, 0xF4, 0x2C, 0xB9, 0x5A, 0x66, 0x2A, + 0xB0, 0x17, 0x9B, 0x9E, 0x1E, 0x76, 0x9D, 0x4A, 0x66, 0x31, 0x41, 0xDF, + 0x3F, 0xFB, 0xC5, 0x06, 0xEF, 0x1B, 0xB6, 0x7E, 0x1A, 0x46, 0x36, 0xF7, + 0x64, 0x63, 0x3B, 0xE3, 0x39, 0x18, 0x23, 0xE7, 0x67, 0x75, 0x14, 0xD5, + 0x75, 0x57, 0x92, 0x37, 0xBD, 0xBE, 0x6A, 0x1B, 0x26, 0x50, 0xF2, 0x36, + 0x26, 0x06, 0x90, 0xC5, 0x70, 0x01, 0x64, 0x6D, 0x76, 0x66, 0xE1, 0x91, + 0xDB, 0x6E, 0x07, 0xC0, 0x61, 0x80, 0x2E, 0xB2, 0x2E, 0x2F, 0x8C, 0x70, + 0xA7, 0xD1, 0x3B, 0x3C, 0xB3, 0x91, 0xE4, 0x6E, 0xB6, 0xC4, 0x3B, 0x70, + 0xF2, 0x6C, 0x92, 0x97, 0x09, 0xCD, 0x47, 0x7D, 0x18, 0xC0, 0xF3, 0xBB, + 0x9E, 0x0F, 0xD6, 0x8B, 0xAE, 0x07, 0xB6, 0x5A, 0x0F, 0xCE, 0x0B, 0x0C, + 0x47, 0xA7, 0xE5, 0x3E, 0xB8, 0xBD, 0x7D, 0xC7, 0x9B, 0x35, 0xA0, 0x61, + 0x97, 0x3A, 0x41, 0x75, 0x17, 0xCC, 0x2B, 0x96, 0x77, 0x2A, 0x92, 0x21, + 0x1E, 0xD9, 0x95, 0x76, 0x20, 0x67, 0x68, 0xCF, 0x0D, 0xBD, 0xDF, 0xD6, + 0x1F, 0x09, 0x6A, 0x9A, 0xE2, 0xCC, 0x73, 0x71, 0xA4, 0x2F, 0x7D, 0x12, + 0x80, 0xB7, 0x53, 0x30, 0x46, 0x5E, 0x4B, 0x54, 0x99, 0x0F, 0x67, 0xC9, + 0xA5, 0xC8, 0xF2, 0x20, 0xC1, 0x82, 0xEC, 0x9D, 0x11, 0xDF, 0xC2, 0x02, + 0xFB, 0x1A, 0x3B, 0xD1, 0xED, 0x20, 0x9A, 0xEF, 0x65, 0x64, 0x92, 0x10, + 0x0D, 0x2A, 0xE2, 0xDE, 0x70, 0xF1, 0x18, 0x67, 0x82, 0x8C, 0x61, 0xDE, + 0xB8, 0xBC, 0xD1, 0x2F, 0x9C, 0xFB, 0x0F, 0xD0, 0x2B, 0xED, 0x1B, 0x76, + 0xB9, 0xE4, 0x39, 0x55, 0xF8, 0xF8, 0xA1, 0x1D, 0xB8, 0xAA, 0x80, 0x00, + 0x4C, 0x82, 0xE7, 0xB2, 0x7F, 0x09, 0xB8, 0xBC, 0x30, 0xA0, 0x2F, 0x0D, + 0xF5, 0x52, 0x9E, 0x8E, 0xF7, 0x92, 0xB3, 0x0A, 0x00, 0x1D, 0x00, 0x54, + 0x97, 0x06, 0xE0, 0xB1, 0x07, 0xD9, 0xC7, 0x0F, 0x5C, 0x65, 0x7D, 0x3C, + 0x6D, 0x59, 0x57, 0xE4, 0xED, 0xA5, 0x8D, 0xE9, 0x40, 0x53, 0x9F, 0x15, + 0x4B, 0xA0, 0x71, 0xF6, 0x1A, 0x21, 0xE3, 0xDA, 0x70, 0x06, 0x21, 0x58, + 0x14, 0x87, 0x85, 0x77, 0x79, 0xAA, 0x82, 0x79 +}; + +static const unsigned char TA669_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA670_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x34, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA670_EC_Q[] = { + 0x04, 0xB8, 0xC6, 0x79, 0xD3, 0x8F, 0x6C, 0x25, 0x0E, 0x9F, 0x2E, 0x39, + 0x19, 0x1C, 0x03, 0xA4, 0xAE, 0x9A, 0xE5, 0x39, 0x07, 0x09, 0x16, 0xCA, + 0x63, 0xB1, 0xB9, 0x86, 0xF8, 0x8A, 0x57, 0xC1, 0x57, 0xCE, 0x42, 0xFA, + 0x73, 0xA1, 0xF7, 0x65, 0x42, 0xFF, 0x1E, 0xC1, 0x00, 0xB2, 0x6E, 0x73, + 0x0E, 0xFF, 0xC7, 0x21, 0xE5, 0x18, 0xA4, 0xAA, 0xD9, 0x71, 0x3F, 0xA8, + 0xD4, 0xB9, 0xCE, 0x8C, 0x1D +}; + +static const unsigned char TA671_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x35, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA671_EC_Q[] = { + 0x04, 0x47, 0x45, 0x0E, 0x96, 0xFB, 0x7D, 0x5D, 0xBF, 0xE9, 0x39, 0xD1, + 0x21, 0xF8, 0x9F, 0x0B, 0xB6, 0xD5, 0x7B, 0x1E, 0x92, 0x3A, 0x48, 0x59, + 0x1C, 0xF0, 0x62, 0x31, 0x2D, 0xC0, 0x7A, 0x28, 0xFE, 0x1A, 0xA7, 0x5C, + 0xB3, 0xB6, 0xCC, 0x97, 0xE7, 0x45, 0xD4, 0x58, 0xFA, 0xD1, 0x77, 0x6D, + 0x43, 0xA2, 0xC0, 0x87, 0x65, 0x34, 0x0A, 0x1F, 0x7A, 0xDD, 0xEB, 0x3C, + 0x33, 0xA1, 0xC5, 0x9D, 0x4D, 0xA4, 0x6F, 0x41, 0x95, 0x38, 0x7F, 0xC9, + 0x1E, 0x84, 0xEB, 0xD1, 0x9E, 0x49, 0x92, 0x87, 0x94, 0x87, 0x0C, 0x3A, + 0x85, 0x4A, 0x66, 0x9F, 0x9D, 0x59, 0x93, 0x4D, 0x97, 0x61, 0x06, 0x86, + 0x4A +}; + +static const unsigned char TA672_DN[] = { + 0x30, 0x57, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, + 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA672_RSA_N[] = { + 0xDA, 0x0E, 0xE6, 0x99, 0x8D, 0xCE, 0xA3, 0xE3, 0x4F, 0x8A, 0x7E, 0xFB, + 0xF1, 0x8B, 0x83, 0x25, 0x6B, 0xEA, 0x48, 0x1F, 0xF1, 0x2A, 0xB0, 0xB9, + 0x95, 0x11, 0x04, 0xBD, 0xF0, 0x63, 0xD1, 0xE2, 0x67, 0x66, 0xCF, 0x1C, + 0xDD, 0xCF, 0x1B, 0x48, 0x2B, 0xEE, 0x8D, 0x89, 0x8E, 0x9A, 0xAF, 0x29, + 0x80, 0x65, 0xAB, 0xE9, 0xC7, 0x2D, 0x12, 0xCB, 0xAB, 0x1C, 0x4C, 0x70, + 0x07, 0xA1, 0x3D, 0x0A, 0x30, 0xCD, 0x15, 0x8D, 0x4F, 0xF8, 0xDD, 0xD4, + 0x8C, 0x50, 0x15, 0x1C, 0xEF, 0x50, 0xEE, 0xC4, 0x2E, 0xF7, 0xFC, 0xE9, + 0x52, 0xF2, 0x91, 0x7D, 0xE0, 0x6D, 0xD5, 0x35, 0x30, 0x8E, 0x5E, 0x43, + 0x73, 0xF2, 0x41, 0xE9, 0xD5, 0x6A, 0xE3, 0xB2, 0x89, 0x3A, 0x56, 0x39, + 0x38, 0x6F, 0x06, 0x3C, 0x88, 0x69, 0x5B, 0x2A, 0x4D, 0xC5, 0xA7, 0x54, + 0xB8, 0x6C, 0x89, 0xCC, 0x9B, 0xF9, 0x3C, 0xCA, 0xE5, 0xFD, 0x89, 0xF5, + 0x12, 0x3C, 0x92, 0x78, 0x96, 0xD6, 0xDC, 0x74, 0x6E, 0x93, 0x44, 0x61, + 0xD1, 0x8D, 0xC7, 0x46, 0xB2, 0x75, 0x0E, 0x86, 0xE8, 0x19, 0x8A, 0xD5, + 0x6D, 0x6C, 0xD5, 0x78, 0x16, 0x95, 0xA2, 0xE9, 0xC8, 0x0A, 0x38, 0xEB, + 0xF2, 0x24, 0x13, 0x4F, 0x73, 0x54, 0x93, 0x13, 0x85, 0x3A, 0x1B, 0xBC, + 0x1E, 0x34, 0xB5, 0x8B, 0x05, 0x8C, 0xB9, 0x77, 0x8B, 0xB1, 0xDB, 0x1F, + 0x20, 0x91, 0xAB, 0x09, 0x53, 0x6E, 0x90, 0xCE, 0x7B, 0x37, 0x74, 0xB9, + 0x70, 0x47, 0x91, 0x22, 0x51, 0x63, 0x16, 0x79, 0xAE, 0xB1, 0xAE, 0x41, + 0x26, 0x08, 0xC8, 0x19, 0x2B, 0xD1, 0x46, 0xAA, 0x48, 0xD6, 0x64, 0x2A, + 0xD7, 0x83, 0x34, 0xFF, 0x2C, 0x2A, 0xC1, 0x6C, 0x19, 0x43, 0x4A, 0x07, + 0x85, 0xE7, 0xD3, 0x7C, 0xF6, 0x21, 0x68, 0xEF, 0xEA, 0xF2, 0x52, 0x9F, + 0x7F, 0x93, 0x90, 0xCF +}; + +static const unsigned char TA672_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA673_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x33, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA673_RSA_N[] = { + 0xCC, 0x25, 0x76, 0x90, 0x79, 0x06, 0x78, 0x22, 0x16, 0xF5, 0xC0, 0x83, + 0xB6, 0x84, 0xCA, 0x28, 0x9E, 0xFD, 0x05, 0x76, 0x11, 0xC5, 0xAD, 0x88, + 0x72, 0xFC, 0x46, 0x02, 0x43, 0xC7, 0xB2, 0x8A, 0x9D, 0x04, 0x5F, 0x24, + 0xCB, 0x2E, 0x4B, 0xE1, 0x60, 0x82, 0x46, 0xE1, 0x52, 0xAB, 0x0C, 0x81, + 0x47, 0x70, 0x6C, 0xDD, 0x64, 0xD1, 0xEB, 0xF5, 0x2C, 0xA3, 0x0F, 0x82, + 0x3D, 0x0C, 0x2B, 0xAE, 0x97, 0xD7, 0xB6, 0x14, 0x86, 0x10, 0x79, 0xBB, + 0x3B, 0x13, 0x80, 0x77, 0x8C, 0x08, 0xE1, 0x49, 0xD2, 0x6A, 0x62, 0x2F, + 0x1F, 0x5E, 0xFA, 0x96, 0x68, 0xDF, 0x89, 0x27, 0x95, 0x38, 0x9F, 0x06, + 0xD7, 0x3E, 0xC9, 0xCB, 0x26, 0x59, 0x0D, 0x73, 0xDE, 0xB0, 0xC8, 0xE9, + 0x26, 0x0E, 0x83, 0x15, 0xC6, 0xEF, 0x5B, 0x8B, 0xD2, 0x04, 0x60, 0xCA, + 0x49, 0xA6, 0x28, 0xF6, 0x69, 0x3B, 0xF6, 0xCB, 0xC8, 0x28, 0x91, 0xE5, + 0x9D, 0x8A, 0x61, 0x57, 0x37, 0xAC, 0x74, 0x14, 0xDC, 0x74, 0xE0, 0x3A, + 0xEE, 0x72, 0x2F, 0x2E, 0x9C, 0xFB, 0xD0, 0xBB, 0xBF, 0xF5, 0x3D, 0x00, + 0xE1, 0x06, 0x33, 0xE8, 0x82, 0x2B, 0xAE, 0x53, 0xA6, 0x3A, 0x16, 0x73, + 0x8C, 0xDD, 0x41, 0x0E, 0x20, 0x3A, 0xC0, 0xB4, 0xA7, 0xA1, 0xE9, 0xB2, + 0x4F, 0x90, 0x2E, 0x32, 0x60, 0xE9, 0x57, 0xCB, 0xB9, 0x04, 0x92, 0x68, + 0x68, 0xE5, 0x38, 0x26, 0x60, 0x75, 0xB2, 0x9F, 0x77, 0xFF, 0x91, 0x14, + 0xEF, 0xAE, 0x20, 0x49, 0xFC, 0xAD, 0x40, 0x15, 0x48, 0xD1, 0x02, 0x31, + 0x61, 0x19, 0x5E, 0xB8, 0x97, 0xEF, 0xAD, 0x77, 0xB7, 0x64, 0x9A, 0x7A, + 0xBF, 0x5F, 0xC1, 0x13, 0xEF, 0x9B, 0x62, 0xFB, 0x0D, 0x6C, 0xE0, 0x54, + 0x69, 0x16, 0xA9, 0x03, 0xDA, 0x6E, 0xE9, 0x83, 0x93, 0x71, 0x76, 0xC6, + 0x69, 0x85, 0x82, 0x17 +}; + +static const unsigned char TA673_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA674_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x36, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA674_RSA_N[] = { + 0x95, 0x07, 0xE8, 0x73, 0xCA, 0x66, 0xF9, 0xEC, 0x14, 0xCA, 0x7B, 0x3C, + 0xF7, 0x0D, 0x08, 0xF1, 0xB4, 0x45, 0x0B, 0x2C, 0x82, 0xB4, 0x48, 0xC6, + 0xEB, 0x5B, 0x3C, 0xAE, 0x83, 0xB8, 0x41, 0x92, 0x33, 0x14, 0xA4, 0x6F, + 0x7F, 0xE9, 0x2A, 0xCC, 0xC6, 0xB0, 0x88, 0x6B, 0xC5, 0xB6, 0x89, 0xD1, + 0xC6, 0xB2, 0xFF, 0x14, 0xCE, 0x51, 0x14, 0x21, 0xEC, 0x4A, 0xDD, 0x1B, + 0x5A, 0xC6, 0xD6, 0x87, 0xEE, 0x4D, 0x3A, 0x15, 0x06, 0xED, 0x64, 0x66, + 0x0B, 0x92, 0x80, 0xCA, 0x44, 0xDE, 0x73, 0x94, 0x4E, 0xF3, 0xA7, 0x89, + 0x7F, 0x4F, 0x78, 0x63, 0x08, 0xC8, 0x12, 0x50, 0x6D, 0x42, 0x66, 0x2F, + 0x4D, 0xB9, 0x79, 0x28, 0x4D, 0x52, 0x1A, 0x8A, 0x1A, 0x80, 0xB7, 0x19, + 0x81, 0x0E, 0x7E, 0xC4, 0x8A, 0xBC, 0x64, 0x4C, 0x21, 0x1C, 0x43, 0x68, + 0xD7, 0x3D, 0x3C, 0x8A, 0xC5, 0xB2, 0x66, 0xD5, 0x90, 0x9A, 0xB7, 0x31, + 0x06, 0xC5, 0xBE, 0xE2, 0x6D, 0x32, 0x06, 0xA6, 0x1E, 0xF9, 0xB9, 0xEB, + 0xAA, 0xA3, 0xB8, 0xBF, 0xBE, 0x82, 0x63, 0x50, 0xD0, 0xF0, 0x18, 0x89, + 0xDF, 0xE4, 0x0F, 0x79, 0xF5, 0xEA, 0xA2, 0x1F, 0x2A, 0xD2, 0x70, 0x2E, + 0x7B, 0xE7, 0xBC, 0x93, 0xBB, 0x6D, 0x53, 0xE2, 0x48, 0x7C, 0x8C, 0x10, + 0x07, 0x38, 0xFF, 0x66, 0xB2, 0x77, 0x61, 0x7E, 0xE0, 0xEA, 0x8C, 0x3C, + 0xAA, 0xB4, 0xA4, 0xF6, 0xF3, 0x95, 0x4A, 0x12, 0x07, 0x6D, 0xFD, 0x8C, + 0xB2, 0x89, 0xCF, 0xD0, 0xA0, 0x61, 0x77, 0xC8, 0x58, 0x74, 0xB0, 0xD4, + 0x23, 0x3A, 0xF7, 0x5D, 0x3A, 0xCA, 0xA2, 0xDB, 0x9D, 0x09, 0xDE, 0x5D, + 0x44, 0x2D, 0x90, 0xF1, 0x81, 0xCD, 0x57, 0x92, 0xFA, 0x7E, 0xBC, 0x50, + 0x04, 0x63, 0x34, 0xDF, 0x6B, 0x93, 0x18, 0xBE, 0x6B, 0x36, 0xB2, 0x39, + 0xE4, 0xAC, 0x24, 0x36, 0xB7, 0xF0, 0xEF, 0xB6, 0x1C, 0x13, 0x57, 0x93, + 0xB6, 0xDE, 0xB2, 0xF8, 0xE2, 0x85, 0xB7, 0x73, 0xA2, 0xB8, 0x35, 0xAA, + 0x45, 0xF2, 0xE0, 0x9D, 0x36, 0xA1, 0x6F, 0x54, 0x8A, 0xF1, 0x72, 0x56, + 0x6E, 0x2E, 0x88, 0xC5, 0x51, 0x42, 0x44, 0x15, 0x94, 0xEE, 0xA3, 0xC5, + 0x38, 0x96, 0x9B, 0x4E, 0x4E, 0x5A, 0x0B, 0x47, 0xF3, 0x06, 0x36, 0x49, + 0x77, 0x30, 0xBC, 0x71, 0x37, 0xE5, 0xA6, 0xEC, 0x21, 0x08, 0x75, 0xFC, + 0xE6, 0x61, 0x16, 0x3F, 0x77, 0xD5, 0xD9, 0x91, 0x97, 0x84, 0x0A, 0x6C, + 0xD4, 0x02, 0x4D, 0x74, 0xC0, 0x14, 0xED, 0xFD, 0x39, 0xFB, 0x83, 0xF2, + 0x5E, 0x14, 0xA1, 0x04, 0xB0, 0x0B, 0xE9, 0xFE, 0xEE, 0x8F, 0xE1, 0x6E, + 0x0B, 0xB2, 0x08, 0xB3, 0x61, 0x66, 0x09, 0x6A, 0xB1, 0x06, 0x3A, 0x65, + 0x96, 0x59, 0xC0, 0xF0, 0x35, 0xFD, 0xC9, 0xDA, 0x28, 0x8D, 0x1A, 0x11, + 0x87, 0x70, 0x81, 0x0A, 0xA8, 0x9A, 0x75, 0x1D, 0x9E, 0x3A, 0x86, 0x05, + 0x00, 0x9E, 0xDB, 0x80, 0xD6, 0x25, 0xF9, 0xDC, 0x05, 0x9E, 0x27, 0x59, + 0x4C, 0x76, 0x39, 0x5B, 0xEA, 0xF9, 0xA5, 0xA1, 0xD8, 0x83, 0x0F, 0xD1, + 0xFF, 0xDF, 0x30, 0x11, 0xF9, 0x85, 0xCF, 0x33, 0x48, 0xF5, 0xCA, 0x6D, + 0x64, 0x14, 0x2C, 0x7A, 0x58, 0x4F, 0xD3, 0x4B, 0x08, 0x49, 0xC5, 0x95, + 0x64, 0x1A, 0x63, 0x0E, 0x79, 0x3D, 0xF5, 0xB3, 0x8C, 0xCA, 0x58, 0xAD, + 0x9C, 0x42, 0x45, 0x79, 0x6E, 0x0E, 0x87, 0x19, 0x5C, 0x54, 0xB1, 0x65, + 0xB6, 0xBF, 0x8C, 0x9B, 0xDC, 0x13, 0xE9, 0x0D, 0x6F, 0xB8, 0x2E, 0xDC, + 0x67, 0x6E, 0xC9, 0x8B, 0x11, 0xB5, 0x84, 0x14, 0x8A, 0x00, 0x19, 0x70, + 0x83, 0x79, 0x91, 0x97, 0x91, 0xD4, 0x1A, 0x27, 0xBF, 0x37, 0x1E, 0x32, + 0x07, 0xD8, 0x14, 0x63, 0x3C, 0x28, 0x4C, 0xAF +}; + +static const unsigned char TA674_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA675_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, 0x36 +}; + +static const unsigned char TA675_EC_Q[] = { + 0x04, 0x9C, 0x0E, 0xB1, 0xCF, 0xB7, 0xE8, 0x9E, 0x52, 0x77, 0x75, 0x34, + 0xFA, 0xA5, 0x46, 0xA7, 0xAD, 0x32, 0x19, 0x32, 0xB4, 0x07, 0xA9, 0x27, + 0xCA, 0x94, 0xBB, 0x0C, 0xD2, 0x0A, 0x10, 0xC7, 0xDA, 0x89, 0xB0, 0x97, + 0x0C, 0x70, 0x13, 0x09, 0x01, 0x8E, 0xD8, 0xEA, 0x47, 0xEA, 0xBE, 0xB2, + 0x80, 0x2B, 0xCD, 0xFC, 0x28, 0x0D, 0xDB, 0xAC, 0xBC, 0xA4, 0x86, 0x37, + 0xED, 0x70, 0x08, 0x00, 0x75, 0xEA, 0x93, 0x0B, 0x7B, 0x2E, 0x52, 0x9C, + 0x23, 0x68, 0x23, 0x06, 0x43, 0xEC, 0x92, 0x2F, 0x53, 0x84, 0xDB, 0xFB, + 0x47, 0x14, 0x07, 0xE8, 0x5F, 0x94, 0x67, 0x5D, 0xC9, 0x7A, 0x81, 0x3C, + 0x20 +}; + +static const unsigned char TA676_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x36 +}; + +static const unsigned char TA676_RSA_N[] = { + 0xAC, 0xAC, 0x74, 0x32, 0xE8, 0xB3, 0x65, 0xE5, 0xBA, 0xED, 0x43, 0x26, + 0x1D, 0xA6, 0x89, 0x0D, 0x45, 0xBA, 0x29, 0x88, 0xB2, 0xA4, 0x1D, 0x63, + 0xDD, 0xD3, 0xC1, 0x2C, 0x09, 0x57, 0x89, 0x39, 0xA1, 0x55, 0xE9, 0x67, + 0x34, 0x77, 0x0C, 0x6E, 0xE4, 0x55, 0x1D, 0x52, 0x25, 0xD2, 0x13, 0x6B, + 0x5E, 0xE1, 0x1D, 0xA9, 0xB7, 0x7D, 0x89, 0x32, 0x5F, 0x0D, 0x9E, 0x9F, + 0x2C, 0x7A, 0x63, 0x60, 0x40, 0x1F, 0xA6, 0xB0, 0xB6, 0x78, 0x8F, 0x99, + 0x54, 0x96, 0x08, 0x58, 0xAE, 0xE4, 0x06, 0xBC, 0x62, 0x05, 0x02, 0x16, + 0xBF, 0xAF, 0xA8, 0x23, 0x03, 0xB6, 0x94, 0x0F, 0xBC, 0x6E, 0x6C, 0xC2, + 0xCB, 0xD5, 0xA6, 0xBB, 0x0C, 0xE9, 0xF6, 0xC1, 0x02, 0xFB, 0x21, 0xDE, + 0x66, 0xDD, 0x17, 0xAB, 0x74, 0x42, 0xEF, 0xF0, 0x74, 0x2F, 0x25, 0xF4, + 0xEA, 0x6B, 0x55, 0x5B, 0x90, 0xDB, 0x9D, 0xDF, 0x5E, 0x87, 0x0A, 0x40, + 0xFB, 0xAD, 0x19, 0x6B, 0xFB, 0xF7, 0xCA, 0x60, 0x88, 0xDE, 0xDA, 0xC1, + 0x8F, 0xD6, 0xAE, 0xD5, 0x7F, 0xD4, 0x3C, 0x83, 0xEE, 0xD7, 0x16, 0x4C, + 0x83, 0x45, 0x33, 0x6B, 0x27, 0xD0, 0x86, 0xD0, 0x1C, 0x2D, 0x6B, 0xF3, + 0xAB, 0x7D, 0xF1, 0x85, 0xA9, 0xF5, 0x28, 0xD2, 0xAD, 0xEF, 0xF3, 0x84, + 0x4B, 0x1C, 0x87, 0xFC, 0x13, 0xA3, 0x3A, 0x72, 0xA2, 0x5A, 0x11, 0x2B, + 0xD6, 0x27, 0x71, 0x27, 0xED, 0x81, 0x2D, 0x6D, 0x66, 0x81, 0x92, 0x87, + 0xB4, 0x1B, 0x58, 0x7A, 0xCC, 0x3F, 0x0A, 0xFA, 0x46, 0x4F, 0x4D, 0x78, + 0x5C, 0xF8, 0x2B, 0x48, 0xE3, 0x04, 0x84, 0xCB, 0x5D, 0xF6, 0xB4, 0x6A, + 0xB3, 0x65, 0xFC, 0x42, 0x9E, 0x51, 0x26, 0x23, 0x20, 0xCB, 0x3D, 0x14, + 0xF9, 0x81, 0xED, 0x65, 0x16, 0x00, 0x4F, 0x1A, 0x64, 0x97, 0x66, 0x08, + 0xCF, 0x8C, 0x7B, 0xE3, 0x2B, 0xC0, 0x9D, 0xF9, 0x14, 0xF2, 0x1B, 0xF1, + 0x56, 0x6A, 0x16, 0xBF, 0x2C, 0x85, 0x85, 0xCD, 0x78, 0x38, 0x9A, 0xEB, + 0x42, 0x6A, 0x02, 0x34, 0x18, 0x83, 0x17, 0x4E, 0x94, 0x56, 0xF8, 0xB6, + 0x82, 0xB5, 0xF3, 0x96, 0xDD, 0x3D, 0xF3, 0xBE, 0x7F, 0x20, 0x77, 0x3E, + 0x7B, 0x19, 0x23, 0x6B, 0x2C, 0xD4, 0x72, 0x73, 0x43, 0x57, 0x7D, 0xE0, + 0xF8, 0xD7, 0x69, 0x4F, 0x17, 0x36, 0x04, 0xF9, 0xC0, 0x90, 0x60, 0x37, + 0x45, 0xDE, 0xE6, 0x0C, 0xD8, 0x74, 0x8D, 0xAE, 0x9C, 0xA2, 0x6D, 0x74, + 0x5D, 0x42, 0xBE, 0x06, 0xF5, 0xD9, 0x64, 0x6E, 0x02, 0x10, 0xAC, 0x89, + 0xB0, 0x4C, 0x3B, 0x07, 0x4D, 0x40, 0x7E, 0x24, 0xC5, 0x8A, 0x98, 0x82, + 0x79, 0x8E, 0xA4, 0xA7, 0x82, 0x20, 0x8D, 0x23, 0xFA, 0x27, 0x71, 0xC9, + 0xDF, 0xC6, 0x41, 0x74, 0xA0, 0x4D, 0xF6, 0x91, 0x16, 0xDC, 0x46, 0x8C, + 0x5F, 0x29, 0x63, 0x31, 0x59, 0x71, 0x0C, 0xD8, 0x6F, 0xC2, 0xB6, 0x32, + 0x7D, 0xFB, 0xE6, 0x5D, 0x53, 0xA6, 0x7E, 0x15, 0xFC, 0xBB, 0x75, 0x7C, + 0x5D, 0xEC, 0xF8, 0xF6, 0x17, 0x1C, 0xEC, 0xC7, 0x6B, 0x19, 0xCB, 0xF3, + 0x7B, 0xF0, 0x2B, 0x07, 0xA5, 0xD9, 0x6C, 0x79, 0x54, 0x76, 0x6C, 0x9D, + 0x1C, 0xA6, 0x6E, 0x0E, 0xE9, 0x79, 0x0C, 0xA8, 0x23, 0x6A, 0xA3, 0xDF, + 0x1B, 0x30, 0x31, 0x9F, 0xB1, 0x54, 0x7B, 0xFE, 0x6A, 0xCB, 0x66, 0xAA, + 0xDC, 0x65, 0xD0, 0xA2, 0x9E, 0x4A, 0x9A, 0x07, 0x21, 0x6B, 0x81, 0x8F, + 0xDB, 0xC4, 0x59, 0xFA, 0xDE, 0x22, 0xC0, 0x04, 0x9C, 0xE3, 0xAA, 0x5B, + 0x36, 0x93, 0xE8, 0x3D, 0xBD, 0x7A, 0xA1, 0x9D, 0x0B, 0x76, 0xB1, 0x0B, + 0xC7, 0x9D, 0xFD, 0xCF, 0x98, 0xA8, 0x06, 0xC2, 0xF8, 0x2A, 0xA3, 0xA1, + 0x83, 0xA0, 0xB7, 0x25, 0x72, 0xA5, 0x02, 0xE3 +}; + +static const unsigned char TA676_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA677_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x41, 0x54, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x65, 0x2D, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x65, + 0x20, 0x6D, 0x6F, 0x6E, 0x69, 0x74, 0x6F, 0x72, 0x69, 0x6E, 0x67, 0x20, + 0x47, 0x6D, 0x62, 0x48, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x10, 0x47, 0x4C, 0x4F, 0x42, 0x41, 0x4C, 0x54, 0x52, 0x55, + 0x53, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA677_RSA_N[] = { + 0xAE, 0x2E, 0x56, 0xAD, 0x1B, 0x1C, 0xEF, 0xF6, 0x95, 0x8F, 0xA0, 0x77, + 0x1B, 0x2B, 0xD3, 0x63, 0x8F, 0x84, 0x4D, 0x45, 0xA2, 0x0F, 0x9F, 0x5B, + 0x45, 0xAB, 0x59, 0x7B, 0x51, 0x34, 0xF9, 0xEC, 0x8B, 0x8A, 0x78, 0xC5, + 0xDD, 0x6B, 0xAF, 0xBD, 0xC4, 0xDF, 0x93, 0x45, 0x1E, 0xBF, 0x91, 0x38, + 0x0B, 0xAE, 0x0E, 0x16, 0xE7, 0x41, 0x73, 0xF8, 0xDB, 0xBB, 0xD1, 0xB8, + 0x51, 0xE0, 0xCB, 0x83, 0x3B, 0x73, 0x38, 0x6E, 0x77, 0x8A, 0x0F, 0x59, + 0x63, 0x26, 0xCD, 0xA7, 0x2A, 0xCE, 0x54, 0xFB, 0xB8, 0xE2, 0xC0, 0x7C, + 0x47, 0xCE, 0x60, 0x7C, 0x3F, 0xB2, 0x73, 0xF2, 0xC0, 0x19, 0xB6, 0x8A, + 0x92, 0x87, 0x35, 0x0D, 0x90, 0x28, 0xA2, 0xE4, 0x15, 0x04, 0x63, 0x3E, + 0xBA, 0xAF, 0xEE, 0x7C, 0x5E, 0xCC, 0xA6, 0x8B, 0x50, 0xB2, 0x38, 0xF7, + 0x41, 0x63, 0xCA, 0xCE, 0xFF, 0x69, 0x8F, 0x68, 0x0E, 0x95, 0x36, 0xE5, + 0xCC, 0xB9, 0x8C, 0x09, 0xCA, 0x4B, 0xDD, 0x31, 0x90, 0x96, 0xC8, 0xCC, + 0x1F, 0xFD, 0x56, 0x96, 0x34, 0xDB, 0x8E, 0x1C, 0xEA, 0x2C, 0xBE, 0x85, + 0x2E, 0x63, 0xDD, 0xAA, 0xA9, 0x95, 0xD3, 0xFD, 0x29, 0x95, 0x13, 0xF0, + 0xC8, 0x98, 0x93, 0xD9, 0x2D, 0x16, 0x47, 0x90, 0x11, 0x83, 0xA2, 0x3A, + 0x22, 0xA2, 0x28, 0x57, 0xA2, 0xEB, 0xFE, 0xC0, 0x8C, 0x28, 0xA0, 0xA6, + 0x7D, 0xE7, 0x2A, 0x42, 0x3B, 0x82, 0x80, 0x63, 0xA5, 0x63, 0x1F, 0x19, + 0xCC, 0x7C, 0xB2, 0x66, 0xA8, 0xC2, 0xD3, 0x6D, 0x37, 0x6F, 0xE2, 0x7E, + 0x06, 0x51, 0xD9, 0x45, 0x84, 0x1F, 0x12, 0xCE, 0x24, 0x52, 0x64, 0x85, + 0x0B, 0x48, 0x80, 0x4E, 0x87, 0xB1, 0x22, 0x22, 0x30, 0xAA, 0xEB, 0xAE, + 0xBE, 0xE0, 0x02, 0xE0, 0x40, 0xE8, 0xB0, 0x42, 0x80, 0x03, 0x51, 0xAA, + 0xB4, 0x7E, 0xAA, 0x44, 0xD7, 0x43, 0x61, 0xF3, 0xA2, 0x6B, 0x16, 0x89, + 0x49, 0xA4, 0xA3, 0xA4, 0x2B, 0x8A, 0x02, 0xC4, 0x78, 0xF4, 0x68, 0x8A, + 0xC1, 0xE4, 0x7A, 0x36, 0xB1, 0x6F, 0x1B, 0x96, 0x1B, 0x77, 0x49, 0x8D, + 0xD4, 0xC9, 0x06, 0x72, 0x8F, 0xCF, 0x53, 0xE3, 0xDC, 0x17, 0x85, 0x20, + 0x4A, 0xDC, 0x98, 0x27, 0xD3, 0x91, 0x26, 0x2B, 0x47, 0x1E, 0x69, 0x07, + 0xAF, 0xDE, 0xA2, 0xE4, 0xE4, 0xD4, 0x6B, 0x0B, 0xB3, 0x5E, 0x7C, 0xD4, + 0x24, 0x80, 0x47, 0x29, 0x69, 0x3B, 0x6E, 0xE8, 0xAC, 0xFD, 0x40, 0xEB, + 0xD8, 0xED, 0x71, 0x71, 0x2B, 0xF2, 0xE8, 0x58, 0x1D, 0xEB, 0x41, 0x97, + 0x22, 0xC5, 0x1F, 0xD4, 0x39, 0xD0, 0x27, 0x8F, 0x87, 0xE3, 0x18, 0xF4, + 0xE0, 0xA9, 0x46, 0x0D, 0xF5, 0x74, 0x3A, 0x82, 0x2E, 0xD0, 0x6E, 0x2C, + 0x91, 0xA3, 0x31, 0x5C, 0x3B, 0x46, 0xEA, 0x7B, 0x04, 0x10, 0x56, 0x5E, + 0x80, 0x1D, 0xF5, 0xA5, 0x65, 0xE8, 0x82, 0xFC, 0xE2, 0x07, 0x8C, 0x62, + 0x45, 0xF5, 0x20, 0xDE, 0x46, 0x70, 0x86, 0xA1, 0xBC, 0x93, 0xD3, 0x1E, + 0x74, 0xA6, 0x6C, 0xB0, 0x2C, 0xF7, 0x03, 0x0C, 0x88, 0x0C, 0xCB, 0xD4, + 0x72, 0x53, 0x86, 0xBC, 0x60, 0x46, 0xF3, 0x98, 0x6A, 0xC2, 0xF1, 0xBF, + 0x43, 0xF9, 0x70, 0x20, 0x77, 0xCA, 0x37, 0x41, 0x79, 0x55, 0x52, 0x63, + 0x8D, 0x5B, 0x12, 0x9F, 0xC5, 0x68, 0xC4, 0x88, 0x9D, 0xAC, 0xF2, 0x30, + 0xAB, 0xB7, 0xA3, 0x31, 0x97, 0x67, 0xAD, 0x8F, 0x17, 0x0F, 0x6C, 0xC7, + 0x73, 0xED, 0x24, 0x94, 0x6B, 0xC8, 0x83, 0x9A, 0xD0, 0x9A, 0x37, 0x49, + 0x04, 0xAB, 0xB1, 0x16, 0xC8, 0x6C, 0x49, 0x49, 0x2D, 0xAB, 0xA1, 0xD0, + 0x8C, 0x92, 0xF2, 0x41, 0x4A, 0x79, 0x21, 0x25, 0xDB, 0x63, 0xD7, 0xB6, + 0x9C, 0xA7, 0x7E, 0x42, 0x69, 0xFB, 0x3A, 0x63 +}; + +static const unsigned char TA677_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA678_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, + 0x64, 0x79, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x49, 0x6E, + 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x28, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6C, + 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA678_RSA_N[] = { + 0xDE, 0x9D, 0xD7, 0xEA, 0x57, 0x18, 0x49, 0xA1, 0x5B, 0xEB, 0xD7, 0x5F, + 0x48, 0x86, 0xEA, 0xBE, 0xDD, 0xFF, 0xE4, 0xEF, 0x67, 0x1C, 0xF4, 0x65, + 0x68, 0xB3, 0x57, 0x71, 0xA0, 0x5E, 0x77, 0xBB, 0xED, 0x9B, 0x49, 0xE9, + 0x70, 0x80, 0x3D, 0x56, 0x18, 0x63, 0x08, 0x6F, 0xDA, 0xF2, 0xCC, 0xD0, + 0x3F, 0x7F, 0x02, 0x54, 0x22, 0x54, 0x10, 0xD8, 0xB2, 0x81, 0xD4, 0xC0, + 0x75, 0x3D, 0x4B, 0x7F, 0xC7, 0x77, 0xC3, 0x3E, 0x78, 0xAB, 0x1A, 0x03, + 0xB5, 0x20, 0x6B, 0x2F, 0x6A, 0x2B, 0xB1, 0xC5, 0x88, 0x7E, 0xC4, 0xBB, + 0x1E, 0xB0, 0xC1, 0xD8, 0x45, 0x27, 0x6F, 0xAA, 0x37, 0x58, 0xF7, 0x87, + 0x26, 0xD7, 0xD8, 0x2D, 0xF6, 0xA9, 0x17, 0xB7, 0x1F, 0x72, 0x36, 0x4E, + 0xA6, 0x17, 0x3F, 0x65, 0x98, 0x92, 0xDB, 0x2A, 0x6E, 0x5D, 0xA2, 0xFE, + 0x88, 0xE0, 0x0B, 0xDE, 0x7F, 0xE5, 0x8D, 0x15, 0xE1, 0xEB, 0xCB, 0x3A, + 0xD5, 0xE2, 0x12, 0xA2, 0x13, 0x2D, 0xD8, 0x8E, 0xAF, 0x5F, 0x12, 0x3D, + 0xA0, 0x08, 0x05, 0x08, 0xB6, 0x5C, 0xA5, 0x65, 0x38, 0x04, 0x45, 0x99, + 0x1E, 0xA3, 0x60, 0x60, 0x74, 0xC5, 0x41, 0xA5, 0x72, 0x62, 0x1B, 0x62, + 0xC5, 0x1F, 0x6F, 0x5F, 0x1A, 0x42, 0xBE, 0x02, 0x51, 0x65, 0xA8, 0xAE, + 0x23, 0x18, 0x6A, 0xFC, 0x78, 0x03, 0xA9, 0x4D, 0x7F, 0x80, 0xC3, 0xFA, + 0xAB, 0x5A, 0xFC, 0xA1, 0x40, 0xA4, 0xCA, 0x19, 0x16, 0xFE, 0xB2, 0xC8, + 0xEF, 0x5E, 0x73, 0x0D, 0xEE, 0x77, 0xBD, 0x9A, 0xF6, 0x79, 0x98, 0xBC, + 0xB1, 0x07, 0x67, 0xA2, 0x15, 0x0D, 0xDD, 0xA0, 0x58, 0xC6, 0x44, 0x7B, + 0x0A, 0x3E, 0x62, 0x28, 0x5F, 0xBA, 0x41, 0x07, 0x53, 0x58, 0xCF, 0x11, + 0x7E, 0x38, 0x74, 0xC5, 0xF8, 0xFF, 0xB5, 0x69, 0x90, 0x8F, 0x84, 0x74, + 0xEA, 0x97, 0x1B, 0xAF +}; + +static const unsigned char TA678_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA679_DN[] = { + 0x30, 0x81, 0x83, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x1A, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, 0x47, 0x6F, 0x44, 0x61, 0x64, 0x64, + 0x79, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, + 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6F, + 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA679_RSA_N[] = { + 0xBF, 0x71, 0x62, 0x08, 0xF1, 0xFA, 0x59, 0x34, 0xF7, 0x1B, 0xC9, 0x18, + 0xA3, 0xF7, 0x80, 0x49, 0x58, 0xE9, 0x22, 0x83, 0x13, 0xA6, 0xC5, 0x20, + 0x43, 0x01, 0x3B, 0x84, 0xF1, 0xE6, 0x85, 0x49, 0x9F, 0x27, 0xEA, 0xF6, + 0x84, 0x1B, 0x4E, 0xA0, 0xB4, 0xDB, 0x70, 0x98, 0xC7, 0x32, 0x01, 0xB1, + 0x05, 0x3E, 0x07, 0x4E, 0xEE, 0xF4, 0xFA, 0x4F, 0x2F, 0x59, 0x30, 0x22, + 0xE7, 0xAB, 0x19, 0x56, 0x6B, 0xE2, 0x80, 0x07, 0xFC, 0xF3, 0x16, 0x75, + 0x80, 0x39, 0x51, 0x7B, 0xE5, 0xF9, 0x35, 0xB6, 0x74, 0x4E, 0xA9, 0x8D, + 0x82, 0x13, 0xE4, 0xB6, 0x3F, 0xA9, 0x03, 0x83, 0xFA, 0xA2, 0xBE, 0x8A, + 0x15, 0x6A, 0x7F, 0xDE, 0x0B, 0xC3, 0xB6, 0x19, 0x14, 0x05, 0xCA, 0xEA, + 0xC3, 0xA8, 0x04, 0x94, 0x3B, 0x46, 0x7C, 0x32, 0x0D, 0xF3, 0x00, 0x66, + 0x22, 0xC8, 0x8D, 0x69, 0x6D, 0x36, 0x8C, 0x11, 0x18, 0xB7, 0xD3, 0xB2, + 0x1C, 0x60, 0xB4, 0x38, 0xFA, 0x02, 0x8C, 0xCE, 0xD3, 0xDD, 0x46, 0x07, + 0xDE, 0x0A, 0x3E, 0xEB, 0x5D, 0x7C, 0xC8, 0x7C, 0xFB, 0xB0, 0x2B, 0x53, + 0xA4, 0x92, 0x62, 0x69, 0x51, 0x25, 0x05, 0x61, 0x1A, 0x44, 0x81, 0x8C, + 0x2C, 0xA9, 0x43, 0x96, 0x23, 0xDF, 0xAC, 0x3A, 0x81, 0x9A, 0x0E, 0x29, + 0xC5, 0x1C, 0xA9, 0xE9, 0x5D, 0x1E, 0xB6, 0x9E, 0x9E, 0x30, 0x0A, 0x39, + 0xCE, 0xF1, 0x88, 0x80, 0xFB, 0x4B, 0x5D, 0xCC, 0x32, 0xEC, 0x85, 0x62, + 0x43, 0x25, 0x34, 0x02, 0x56, 0x27, 0x01, 0x91, 0xB4, 0x3B, 0x70, 0x2A, + 0x3F, 0x6E, 0xB1, 0xE8, 0x9C, 0x88, 0x01, 0x7D, 0x9F, 0xD4, 0xF9, 0xDB, + 0x53, 0x6D, 0x60, 0x9D, 0xBF, 0x2C, 0xE7, 0x58, 0xAB, 0xB8, 0x5F, 0x46, + 0xFC, 0xCE, 0xC4, 0x1B, 0x03, 0x3C, 0x09, 0xEB, 0x49, 0x31, 0x5C, 0x69, + 0x46, 0xB3, 0xE0, 0x47 +}; + +static const unsigned char TA679_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA680_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x31 +}; + +static const unsigned char TA680_RSA_N[] = { + 0xB6, 0x11, 0x02, 0x8B, 0x1E, 0xE3, 0xA1, 0x77, 0x9B, 0x3B, 0xDC, 0xBF, + 0x94, 0x3E, 0xB7, 0x95, 0xA7, 0x40, 0x3C, 0xA1, 0xFD, 0x82, 0xF9, 0x7D, + 0x32, 0x06, 0x82, 0x71, 0xF6, 0xF6, 0x8C, 0x7F, 0xFB, 0xE8, 0xDB, 0xBC, + 0x6A, 0x2E, 0x97, 0x97, 0xA3, 0x8C, 0x4B, 0xF9, 0x2B, 0xF6, 0xB1, 0xF9, + 0xCE, 0x84, 0x1D, 0xB1, 0xF9, 0xC5, 0x97, 0xDE, 0xEF, 0xB9, 0xF2, 0xA3, + 0xE9, 0xBC, 0x12, 0x89, 0x5E, 0xA7, 0xAA, 0x52, 0xAB, 0xF8, 0x23, 0x27, + 0xCB, 0xA4, 0xB1, 0x9C, 0x63, 0xDB, 0xD7, 0x99, 0x7E, 0xF0, 0x0A, 0x5E, + 0xEB, 0x68, 0xA6, 0xF4, 0xC6, 0x5A, 0x47, 0x0D, 0x4D, 0x10, 0x33, 0xE3, + 0x4E, 0xB1, 0x13, 0xA3, 0xC8, 0x18, 0x6C, 0x4B, 0xEC, 0xFC, 0x09, 0x90, + 0xDF, 0x9D, 0x64, 0x29, 0x25, 0x23, 0x07, 0xA1, 0xB4, 0xD2, 0x3D, 0x2E, + 0x60, 0xE0, 0xCF, 0xD2, 0x09, 0x87, 0xBB, 0xCD, 0x48, 0xF0, 0x4D, 0xC2, + 0xC2, 0x7A, 0x88, 0x8A, 0xBB, 0xBA, 0xCF, 0x59, 0x19, 0xD6, 0xAF, 0x8F, + 0xB0, 0x07, 0xB0, 0x9E, 0x31, 0xF1, 0x82, 0xC1, 0xC0, 0xDF, 0x2E, 0xA6, + 0x6D, 0x6C, 0x19, 0x0E, 0xB5, 0xD8, 0x7E, 0x26, 0x1A, 0x45, 0x03, 0x3D, + 0xB0, 0x79, 0xA4, 0x94, 0x28, 0xAD, 0x0F, 0x7F, 0x26, 0xE5, 0xA8, 0x08, + 0xFE, 0x96, 0xE8, 0x3C, 0x68, 0x94, 0x53, 0xEE, 0x83, 0x3A, 0x88, 0x2B, + 0x15, 0x96, 0x09, 0xB2, 0xE0, 0x7A, 0x8C, 0x2E, 0x75, 0xD6, 0x9C, 0xEB, + 0xA7, 0x56, 0x64, 0x8F, 0x96, 0x4F, 0x68, 0xAE, 0x3D, 0x97, 0xC2, 0x84, + 0x8F, 0xC0, 0xBC, 0x40, 0xC0, 0x0B, 0x5C, 0xBD, 0xF6, 0x87, 0xB3, 0x35, + 0x6C, 0xAC, 0x18, 0x50, 0x7F, 0x84, 0xE0, 0x4C, 0xCD, 0x92, 0xD3, 0x20, + 0xE9, 0x33, 0xBC, 0x52, 0x99, 0xAF, 0x32, 0xB5, 0x29, 0xB3, 0x25, 0x2A, + 0xB4, 0x48, 0xF9, 0x72, 0xE1, 0xCA, 0x64, 0xF7, 0xE6, 0x82, 0x10, 0x8D, + 0xE8, 0x9D, 0xC2, 0x8A, 0x88, 0xFA, 0x38, 0x66, 0x8A, 0xFC, 0x63, 0xF9, + 0x01, 0xF9, 0x78, 0xFD, 0x7B, 0x5C, 0x77, 0xFA, 0x76, 0x87, 0xFA, 0xEC, + 0xDF, 0xB1, 0x0E, 0x79, 0x95, 0x57, 0xB4, 0xBD, 0x26, 0xEF, 0xD6, 0x01, + 0xD1, 0xEB, 0x16, 0x0A, 0xBB, 0x8E, 0x0B, 0xB5, 0xC5, 0xC5, 0x8A, 0x55, + 0xAB, 0xD3, 0xAC, 0xEA, 0x91, 0x4B, 0x29, 0xCC, 0x19, 0xA4, 0x32, 0x25, + 0x4E, 0x2A, 0xF1, 0x65, 0x44, 0xD0, 0x02, 0xCE, 0xAA, 0xCE, 0x49, 0xB4, + 0xEA, 0x9F, 0x7C, 0x83, 0xB0, 0x40, 0x7B, 0xE7, 0x43, 0xAB, 0xA7, 0x6C, + 0xA3, 0x8F, 0x7D, 0x89, 0x81, 0xFA, 0x4C, 0xA5, 0xFF, 0xD5, 0x8E, 0xC3, + 0xCE, 0x4B, 0xE0, 0xB5, 0xD8, 0xB3, 0x8E, 0x45, 0xCF, 0x76, 0xC0, 0xED, + 0x40, 0x2B, 0xFD, 0x53, 0x0F, 0xB0, 0xA7, 0xD5, 0x3B, 0x0D, 0xB1, 0x8A, + 0xA2, 0x03, 0xDE, 0x31, 0xAD, 0xCC, 0x77, 0xEA, 0x6F, 0x7B, 0x3E, 0xD6, + 0xDF, 0x91, 0x22, 0x12, 0xE6, 0xBE, 0xFA, 0xD8, 0x32, 0xFC, 0x10, 0x63, + 0x14, 0x51, 0x72, 0xDE, 0x5D, 0xD6, 0x16, 0x93, 0xBD, 0x29, 0x68, 0x33, + 0xEF, 0x3A, 0x66, 0xEC, 0x07, 0x8A, 0x26, 0xDF, 0x13, 0xD7, 0x57, 0x65, + 0x78, 0x27, 0xDE, 0x5E, 0x49, 0x14, 0x00, 0xA2, 0x00, 0x7F, 0x9A, 0xA8, + 0x21, 0xB6, 0xA9, 0xB1, 0x95, 0xB0, 0xA5, 0xB9, 0x0D, 0x16, 0x11, 0xDA, + 0xC7, 0x6C, 0x48, 0x3C, 0x40, 0xE0, 0x7E, 0x0D, 0x5A, 0xCD, 0x56, 0x3C, + 0xD1, 0x97, 0x05, 0xB9, 0xCB, 0x4B, 0xED, 0x39, 0x4B, 0x9C, 0xC4, 0x3F, + 0xD2, 0x55, 0x13, 0x6E, 0x24, 0xB0, 0xD6, 0x71, 0xFA, 0xF4, 0xC1, 0xBA, + 0xCC, 0xED, 0x1B, 0xF5, 0xFE, 0x81, 0x41, 0xD8, 0x00, 0x98, 0x3D, 0x3A, + 0xC8, 0xAE, 0x7A, 0x98, 0x37, 0x18, 0x05, 0x95 +}; + +static const unsigned char TA680_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA681_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA681_RSA_N[] = { + 0xCE, 0xDE, 0xFD, 0xA6, 0xFB, 0xEC, 0xEC, 0x14, 0x34, 0x3C, 0x07, 0x06, + 0x5A, 0x6C, 0x59, 0xF7, 0x19, 0x35, 0xDD, 0xF7, 0xC1, 0x9D, 0x55, 0xAA, + 0xD3, 0xCD, 0x3B, 0xA4, 0x93, 0x72, 0xEF, 0x0A, 0xFA, 0x6D, 0x9D, 0xF6, + 0xF0, 0x85, 0x80, 0x5B, 0xA1, 0x48, 0x52, 0x9F, 0x39, 0xC5, 0xB7, 0xEE, + 0x28, 0xAC, 0xEF, 0xCB, 0x76, 0x68, 0x14, 0xB9, 0xDF, 0xAD, 0x01, 0x6C, + 0x99, 0x1F, 0xC4, 0x22, 0x1D, 0x9F, 0xFE, 0x72, 0x77, 0xE0, 0x2C, 0x5B, + 0xAF, 0xE4, 0x04, 0xBF, 0x4F, 0x72, 0xA0, 0x1A, 0x34, 0x98, 0xE8, 0x39, + 0x68, 0xEC, 0x95, 0x25, 0x7B, 0x76, 0xA1, 0xE6, 0x69, 0xB9, 0x85, 0x19, + 0xBD, 0x89, 0x8C, 0xFE, 0xAD, 0xED, 0x36, 0xEA, 0x73, 0xBC, 0xFF, 0x83, + 0xE2, 0xCB, 0x7D, 0xC1, 0xD2, 0xCE, 0x4A, 0xB3, 0x8D, 0x05, 0x9E, 0x8B, + 0x49, 0x93, 0xDF, 0xC1, 0x5B, 0xD0, 0x6E, 0x5E, 0xF0, 0x2E, 0x30, 0x2E, + 0x82, 0xFC, 0xFA, 0xBC, 0xB4, 0x17, 0x0A, 0x48, 0xE5, 0x88, 0x9B, 0xC5, + 0x9B, 0x6B, 0xDE, 0xB0, 0xCA, 0xB4, 0x03, 0xF0, 0xDA, 0xF4, 0x90, 0xB8, + 0x65, 0x64, 0xF7, 0x5C, 0x4C, 0xAD, 0xE8, 0x7E, 0x66, 0x5E, 0x99, 0xD7, + 0xB8, 0xC2, 0x3E, 0xC8, 0xD0, 0x13, 0x9D, 0xAD, 0xEE, 0xE4, 0x45, 0x7B, + 0x89, 0x55, 0xF7, 0x8A, 0x1F, 0x62, 0x52, 0x84, 0x12, 0xB3, 0xC2, 0x40, + 0x97, 0xE3, 0x8A, 0x1F, 0x47, 0x91, 0xA6, 0x74, 0x5A, 0xD2, 0xF8, 0xB1, + 0x63, 0x28, 0x10, 0xB8, 0xB3, 0x09, 0xB8, 0x56, 0x77, 0x40, 0xA2, 0x26, + 0x98, 0x79, 0xC6, 0xFE, 0xDF, 0x25, 0xEE, 0x3E, 0xE5, 0xA0, 0x7F, 0xD4, + 0x61, 0x0F, 0x51, 0x4B, 0x3C, 0x3F, 0x8C, 0xDA, 0xE1, 0x70, 0x74, 0xD8, + 0xC2, 0x68, 0xA1, 0xF9, 0xC1, 0x0C, 0xE9, 0xA1, 0xE2, 0x7F, 0xBB, 0x55, + 0x3C, 0x76, 0x06, 0xEE, 0x6A, 0x4E, 0xCC, 0x92, 0x88, 0x30, 0x4D, 0x9A, + 0xBD, 0x4F, 0x0B, 0x48, 0x9A, 0x84, 0xB5, 0x98, 0xA3, 0xD5, 0xFB, 0x73, + 0xC1, 0x57, 0x61, 0xDD, 0x28, 0x56, 0x75, 0x13, 0xAE, 0x87, 0x8E, 0xE7, + 0x0C, 0x51, 0x09, 0x10, 0x75, 0x88, 0x4C, 0xBC, 0x8D, 0xF9, 0x7B, 0x3C, + 0xD4, 0x22, 0x48, 0x1F, 0x2A, 0xDC, 0xEB, 0x6B, 0xBB, 0x44, 0xB1, 0xCB, + 0x33, 0x71, 0x32, 0x46, 0xAF, 0xAD, 0x4A, 0xF1, 0x8C, 0xE8, 0x74, 0x3A, + 0xAC, 0xE7, 0x1A, 0x22, 0x73, 0x80, 0xD2, 0x30, 0xF7, 0x25, 0x42, 0xC7, + 0x22, 0x3B, 0x3B, 0x12, 0xAD, 0x96, 0x2E, 0xC6, 0xC3, 0x76, 0x07, 0xAA, + 0x20, 0xB7, 0x35, 0x49, 0x57, 0xE9, 0x92, 0x49, 0xE8, 0x76, 0x16, 0x72, + 0x31, 0x67, 0x2B, 0x96, 0x7E, 0x8A, 0xA3, 0xC7, 0x94, 0x56, 0x22, 0xBF, + 0x6A, 0x4B, 0x7E, 0x01, 0x21, 0xB2, 0x23, 0x32, 0xDF, 0xE4, 0x9A, 0x44, + 0x6D, 0x59, 0x5B, 0x5D, 0xF5, 0x00, 0xA0, 0x1C, 0x9B, 0xC6, 0x78, 0x97, + 0x8D, 0x90, 0xFF, 0x9B, 0xC8, 0xAA, 0xB4, 0xAF, 0x11, 0x51, 0x39, 0x5E, + 0xD9, 0xFB, 0x67, 0xAD, 0xD5, 0x5B, 0x11, 0x9D, 0x32, 0x9A, 0x1B, 0xBD, + 0xD5, 0xBA, 0x5B, 0xA5, 0xC9, 0xCB, 0x25, 0x69, 0x53, 0x55, 0x27, 0x5C, + 0xE0, 0xCA, 0x36, 0xCB, 0x88, 0x61, 0xFB, 0x1E, 0xB7, 0xD0, 0xCB, 0xEE, + 0x16, 0xFB, 0xD3, 0xA6, 0x4C, 0xDE, 0x92, 0xA5, 0xD4, 0xE2, 0xDF, 0xF5, + 0x06, 0x54, 0xDE, 0x2E, 0x9D, 0x4B, 0xB4, 0x93, 0x30, 0xAA, 0x81, 0xCE, + 0xDD, 0x1A, 0xDC, 0x51, 0x73, 0x0D, 0x4F, 0x70, 0xE9, 0xE5, 0xB6, 0x16, + 0x21, 0x19, 0x79, 0xB2, 0xE6, 0x89, 0x0B, 0x75, 0x64, 0xCA, 0xD5, 0xAB, + 0xBC, 0x09, 0xC1, 0x18, 0xA1, 0xFF, 0xD4, 0x54, 0xA1, 0x85, 0x3C, 0xFD, + 0x14, 0x24, 0x03, 0xB2, 0x87, 0xD3, 0xA4, 0xB7 +}; + +static const unsigned char TA681_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA682_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x33 +}; + +static const unsigned char TA682_EC_Q[] = { + 0x04, 0x1F, 0x4F, 0x33, 0x87, 0x33, 0x29, 0x8A, 0xA1, 0x84, 0xDE, 0xCB, + 0xC7, 0x21, 0x58, 0x41, 0x89, 0xEA, 0x56, 0x9D, 0x2B, 0x4B, 0x85, 0xC6, + 0x1D, 0x4C, 0x27, 0xBC, 0x7F, 0x26, 0x51, 0x72, 0x6F, 0xE2, 0x9F, 0xD6, + 0xA3, 0xCA, 0xCC, 0x45, 0x14, 0x46, 0x8B, 0xAD, 0xEF, 0x7E, 0x86, 0x8C, + 0xEC, 0xB1, 0x7E, 0x2F, 0xFF, 0xA9, 0x71, 0x9D, 0x18, 0x84, 0x45, 0x04, + 0x41, 0x55, 0x6E, 0x2B, 0xEA, 0x26, 0x7F, 0xBB, 0x90, 0x01, 0xE3, 0x4B, + 0x19, 0xBA, 0xE4, 0x54, 0x96, 0x45, 0x09, 0xB1, 0xD5, 0x6C, 0x91, 0x44, + 0xAD, 0x84, 0x13, 0x8E, 0x9A, 0x8C, 0x0D, 0x80, 0x0C, 0x32, 0xF6, 0xE0, + 0x27 +}; + +static const unsigned char TA683_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x34 +}; + +static const unsigned char TA683_EC_Q[] = { + 0x04, 0xF3, 0x74, 0x73, 0xA7, 0x68, 0x8B, 0x60, 0xAE, 0x43, 0xB8, 0x35, + 0xC5, 0x81, 0x30, 0x7B, 0x4B, 0x49, 0x9D, 0xFB, 0xC1, 0x61, 0xCE, 0xE6, + 0xDE, 0x46, 0xBD, 0x6B, 0xD5, 0x61, 0x18, 0x35, 0xAE, 0x40, 0xDD, 0x73, + 0xF7, 0x89, 0x91, 0x30, 0x5A, 0xEB, 0x3C, 0xEE, 0x85, 0x7C, 0xA2, 0x40, + 0x76, 0x3B, 0xA9, 0xC6, 0xB8, 0x47, 0xD8, 0x2A, 0xE7, 0x92, 0x91, 0x6A, + 0x73, 0xE9, 0xB1, 0x72, 0x39, 0x9F, 0x29, 0x9F, 0xA2, 0x98, 0xD3, 0x5F, + 0x5E, 0x58, 0x86, 0x65, 0x0F, 0xA1, 0x84, 0x65, 0x06, 0xD1, 0xDC, 0x8B, + 0xC9, 0xC7, 0x73, 0xC8, 0x8C, 0x6A, 0x2F, 0xE5, 0xC4, 0xAB, 0xD1, 0x1D, + 0x8A +}; + +static const unsigned char TA684_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, + 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA684_EC_Q[] = { + 0x04, 0x38, 0x08, 0xFE, 0xB1, 0xA0, 0x96, 0xD2, 0x7A, 0xAC, 0xAF, 0x49, + 0x3A, 0xD0, 0xC0, 0xE0, 0xC3, 0x3B, 0x28, 0xAA, 0xF1, 0x72, 0x6D, 0x65, + 0x00, 0x47, 0x88, 0x84, 0xFC, 0x9A, 0x26, 0x6B, 0xAA, 0x4B, 0xBA, 0x6C, + 0x04, 0x0A, 0x88, 0x5E, 0x17, 0xF2, 0x55, 0x87, 0xFC, 0x30, 0xB0, 0x34, + 0xE2, 0x34, 0x58, 0x57, 0x1A, 0x84, 0x53, 0xE9, 0x30, 0xD9, 0xA9, 0xF2, + 0x96, 0x74, 0xC3, 0x51, 0x1F, 0x58, 0x49, 0x31, 0xCC, 0x98, 0x4E, 0x60, + 0x11, 0x87, 0x75, 0xD3, 0x72, 0x94, 0x90, 0x4F, 0x9B, 0x10, 0x25, 0x2A, + 0xA8, 0x78, 0x2D, 0xBE, 0x90, 0x41, 0x58, 0x90, 0x15, 0x72, 0xA7, 0xA1, + 0xB7 +}; + +static const unsigned char TA685_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, + 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA685_RSA_N[] = { + 0x8B, 0xC2, 0xE7, 0xAF, 0x65, 0x9B, 0x05, 0x67, 0x96, 0xC9, 0x0D, 0x24, + 0xB9, 0xD0, 0x0E, 0x64, 0xFC, 0xCE, 0xE2, 0x24, 0x18, 0x2C, 0x84, 0x7F, + 0x77, 0x51, 0xCB, 0x04, 0x11, 0x36, 0xB8, 0x5E, 0xED, 0x69, 0x71, 0xA7, + 0x9E, 0xE4, 0x25, 0x09, 0x97, 0x67, 0xC1, 0x47, 0xC2, 0xCF, 0x91, 0x16, + 0x36, 0x62, 0x3D, 0x38, 0x04, 0xE1, 0x51, 0x82, 0xFF, 0xAC, 0xD2, 0xB4, + 0x69, 0xDD, 0x2E, 0xEC, 0x11, 0xA3, 0x45, 0xEE, 0x6B, 0x6B, 0x3B, 0x4C, + 0xBF, 0x8C, 0x8D, 0xA4, 0x1E, 0x9D, 0x11, 0xB9, 0xE9, 0x38, 0xF9, 0x7A, + 0x0E, 0x0C, 0x98, 0xE2, 0x23, 0x1D, 0xD1, 0x4E, 0x63, 0xD4, 0xE7, 0xB8, + 0x41, 0x44, 0xFB, 0x6B, 0xAF, 0x6B, 0xDA, 0x1F, 0xD3, 0xC5, 0x91, 0x88, + 0x5B, 0xA4, 0x89, 0x92, 0xD1, 0x81, 0xE6, 0x8C, 0x39, 0x58, 0xA0, 0xD6, + 0x69, 0x43, 0xA9, 0xAD, 0x98, 0x52, 0x58, 0x6E, 0xDB, 0x0A, 0xFB, 0x6B, + 0xCF, 0x68, 0xFA, 0xE3, 0xA4, 0x5E, 0x3A, 0x45, 0x73, 0x98, 0x07, 0xEA, + 0x5F, 0x02, 0x72, 0xDE, 0x0C, 0xA5, 0xB3, 0x9F, 0xAE, 0xA9, 0x1D, 0xB7, + 0x1D, 0xB3, 0xFC, 0x8A, 0x59, 0xE7, 0x6E, 0x72, 0x65, 0xAD, 0xF5, 0x30, + 0x94, 0x23, 0x07, 0xF3, 0x82, 0x16, 0x4B, 0x35, 0x98, 0x9C, 0x53, 0xBB, + 0x2F, 0xCA, 0xE4, 0x5A, 0xD9, 0xC7, 0x8D, 0x1D, 0xFC, 0x98, 0x99, 0xFB, + 0x2C, 0xA4, 0x82, 0x6B, 0xF0, 0x2A, 0x1F, 0x8E, 0x0B, 0x5F, 0x71, 0x5C, + 0x5C, 0xAE, 0x42, 0x7B, 0x29, 0x89, 0x81, 0xCB, 0x03, 0xA3, 0x99, 0xCA, + 0x88, 0x9E, 0x0B, 0x40, 0x09, 0x41, 0x33, 0xDB, 0xE6, 0x58, 0x7A, 0xFD, + 0xAE, 0x99, 0x70, 0xC0, 0x5A, 0x0F, 0xD6, 0x13, 0x86, 0x71, 0x2F, 0x76, + 0x69, 0xFC, 0x90, 0xDD, 0xDB, 0x2D, 0x6E, 0xD1, 0xF2, 0x9B, 0xF5, 0x1A, + 0x6B, 0x9E, 0x6F, 0x15, 0x8C, 0x7A, 0xF0, 0x4B, 0x28, 0xA0, 0x22, 0x38, + 0x80, 0x24, 0x6C, 0x36, 0xA4, 0x3B, 0xF2, 0x30, 0x91, 0xF3, 0x78, 0x13, + 0xCF, 0xC1, 0x3F, 0x35, 0xAB, 0xF1, 0x1D, 0x11, 0x23, 0xB5, 0x43, 0x22, + 0x9E, 0x01, 0x92, 0xB7, 0x18, 0x02, 0xE5, 0x11, 0xD1, 0x82, 0xDB, 0x15, + 0x00, 0xCC, 0x61, 0x37, 0xC1, 0x2A, 0x7C, 0x9A, 0xE1, 0xD0, 0xBA, 0xB3, + 0x50, 0x46, 0xEE, 0x82, 0xAC, 0x9D, 0x31, 0xF8, 0xFB, 0x23, 0xE2, 0x03, + 0x00, 0x48, 0x70, 0xA3, 0x09, 0x26, 0x79, 0x15, 0x53, 0x60, 0xF3, 0x38, + 0x5C, 0xAD, 0x38, 0xEA, 0x81, 0x00, 0x63, 0x14, 0xB9, 0x33, 0x5E, 0xDD, + 0x0B, 0xDB, 0xA0, 0x45, 0x07, 0x1A, 0x33, 0x09, 0xF8, 0x4D, 0xB4, 0xA7, + 0x02, 0xA6, 0x69, 0xF4, 0xC2, 0x59, 0x05, 0x88, 0x65, 0x85, 0x56, 0xAE, + 0x4B, 0xCB, 0xE0, 0xDE, 0x3C, 0x7D, 0x2D, 0x1A, 0xC8, 0xE9, 0xFB, 0x1F, + 0xA3, 0x61, 0x4A, 0xD6, 0x2A, 0x13, 0xAD, 0x77, 0x4C, 0x1A, 0x18, 0x9B, + 0x91, 0x0F, 0x58, 0xD8, 0x06, 0x54, 0xC5, 0x97, 0xF8, 0xAA, 0x3F, 0x20, + 0x8A, 0xA6, 0x85, 0xA6, 0x77, 0xF6, 0xA6, 0xFC, 0x1C, 0xE2, 0xEE, 0x6E, + 0x94, 0x33, 0x2A, 0x83, 0x50, 0x84, 0x0A, 0xE5, 0x4F, 0x86, 0xF8, 0x50, + 0x45, 0x78, 0x00, 0x81, 0xEB, 0x5B, 0x68, 0xE3, 0x26, 0x8D, 0xCC, 0x7B, + 0x5C, 0x51, 0xF4, 0x14, 0x2C, 0x40, 0xBE, 0x1A, 0x60, 0x1D, 0x7A, 0x72, + 0x61, 0x1D, 0x1F, 0x63, 0x2D, 0x88, 0xAA, 0xCE, 0xA2, 0x45, 0x90, 0x08, + 0xFC, 0x6B, 0xBE, 0xB3, 0x50, 0x2A, 0x5A, 0xFD, 0xA8, 0x48, 0x18, 0x46, + 0xD6, 0x90, 0x40, 0x92, 0x90, 0x0A, 0x84, 0x5E, 0x68, 0x31, 0xF8, 0xEB, + 0xED, 0x0D, 0xD3, 0x1D, 0xC6, 0x7D, 0x99, 0x18, 0x55, 0x56, 0x27, 0x65, + 0x2E, 0x8D, 0x45, 0xC5, 0x24, 0xEC, 0xCE, 0xE3 +}; + +static const unsigned char TA685_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA686_DN[] = { + 0x30, 0x81, 0xAA, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x44, 0x30, 0x42, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, + 0x20, 0x32, 0x30, 0x31, 0x35 +}; + +static const unsigned char TA686_EC_Q[] = { + 0x04, 0x92, 0xA0, 0x41, 0xE8, 0x4B, 0x82, 0x84, 0x5C, 0xE2, 0xF8, 0x31, + 0x11, 0x99, 0x86, 0x64, 0x4E, 0x09, 0x25, 0x2F, 0x9D, 0x41, 0x2F, 0x0A, + 0xAE, 0x35, 0x4F, 0x74, 0x95, 0xB2, 0x51, 0x64, 0x6B, 0x8D, 0x6B, 0xE6, + 0x3F, 0x70, 0x95, 0xF0, 0x05, 0x44, 0x47, 0xA6, 0x72, 0x38, 0x50, 0x76, + 0x95, 0x02, 0x5A, 0x8E, 0xAE, 0x28, 0x9E, 0xF9, 0x2D, 0x4E, 0x99, 0xEF, + 0x2C, 0x48, 0x6F, 0x4C, 0x25, 0x29, 0xE8, 0xD1, 0x71, 0x5B, 0xDF, 0x1D, + 0xC1, 0x75, 0x37, 0xB4, 0xD7, 0xFA, 0x7B, 0x7A, 0x42, 0x9C, 0x6A, 0x0A, + 0x56, 0x5A, 0x7C, 0x69, 0x0B, 0xAA, 0x80, 0x09, 0x24, 0x6C, 0x7E, 0xC1, + 0x46 +}; + +static const unsigned char TA687_DN[] = { + 0x30, 0x81, 0xA6, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x40, 0x30, 0x3E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x37, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, + 0x35 +}; + +static const unsigned char TA687_RSA_N[] = { + 0xC2, 0xF8, 0xA9, 0x3F, 0x1B, 0x89, 0xFC, 0x3C, 0x3C, 0x04, 0x5D, 0x3D, + 0x90, 0x36, 0xB0, 0x91, 0x3A, 0x79, 0x3C, 0x66, 0x5A, 0xEF, 0x6D, 0x39, + 0x01, 0x49, 0x1A, 0xB4, 0xB7, 0xCF, 0x7F, 0x4D, 0x23, 0x53, 0xB7, 0x90, + 0x00, 0xE3, 0x13, 0x2A, 0x28, 0xA6, 0x31, 0xF1, 0x91, 0x00, 0xE3, 0x28, + 0xEC, 0xAE, 0x21, 0x41, 0xCE, 0x1F, 0xDA, 0xFD, 0x7D, 0x12, 0x5B, 0x01, + 0x83, 0x0F, 0xB9, 0xB0, 0x5F, 0x99, 0xE1, 0xF2, 0x12, 0x83, 0x80, 0x4D, + 0x06, 0x3E, 0xDF, 0xAC, 0xAF, 0xE7, 0xA1, 0x88, 0x6B, 0x31, 0xAF, 0xF0, + 0x8B, 0xD0, 0x18, 0x33, 0xB8, 0xDB, 0x45, 0x6A, 0x34, 0xF4, 0x02, 0x80, + 0x24, 0x28, 0x0A, 0x02, 0x15, 0x95, 0x5E, 0x76, 0x2A, 0x0D, 0x99, 0x3A, + 0x14, 0x5B, 0xF6, 0xCB, 0xCB, 0x53, 0xBC, 0x13, 0x4D, 0x01, 0x88, 0x37, + 0x94, 0x25, 0x1B, 0x42, 0xBC, 0x22, 0xD8, 0x8E, 0xA3, 0x96, 0x5E, 0x3A, + 0xD9, 0x32, 0xDB, 0x3E, 0xE8, 0xF0, 0x10, 0x65, 0xED, 0x74, 0xE1, 0x2F, + 0xA7, 0x7C, 0xAF, 0x27, 0x34, 0xBB, 0x29, 0x7D, 0x9B, 0xB6, 0xCF, 0x09, + 0xC8, 0xE5, 0xD3, 0x0A, 0xFC, 0x88, 0x65, 0x65, 0x74, 0x0A, 0xDC, 0x73, + 0x1C, 0x5C, 0xCD, 0x40, 0xB1, 0x1C, 0xD4, 0xB6, 0x84, 0x8C, 0x4C, 0x50, + 0xCF, 0x68, 0x8E, 0xA8, 0x59, 0xAE, 0xC2, 0x27, 0x4E, 0x82, 0xA2, 0x35, + 0xDD, 0x14, 0xF4, 0x1F, 0xFF, 0xB2, 0x77, 0xD5, 0x87, 0x2F, 0xAA, 0x6E, + 0x7D, 0x24, 0x27, 0xE7, 0xC6, 0xCB, 0x26, 0xE6, 0xE5, 0xFE, 0x67, 0x07, + 0x63, 0xD8, 0x45, 0x0D, 0xDD, 0x3A, 0x59, 0x65, 0x39, 0x58, 0x7A, 0x92, + 0x99, 0x72, 0x3D, 0x9C, 0x84, 0x5E, 0x88, 0x21, 0xB8, 0xD5, 0xF4, 0x2C, + 0xFC, 0xD9, 0x70, 0x52, 0x4F, 0x78, 0xB8, 0xBD, 0x3C, 0x2B, 0x8B, 0x95, + 0x98, 0xF5, 0xB3, 0xD1, 0x68, 0xCF, 0x20, 0x14, 0x7E, 0x4C, 0x5C, 0x5F, + 0xE7, 0x8B, 0xE5, 0xF5, 0x35, 0x81, 0x19, 0x37, 0xD7, 0x11, 0x08, 0xB7, + 0x66, 0xBE, 0xD3, 0x4A, 0xCE, 0x83, 0x57, 0x00, 0x3A, 0xC3, 0x81, 0xF8, + 0x17, 0xCB, 0x92, 0x36, 0x5D, 0xD1, 0xA3, 0xD8, 0x75, 0x1B, 0xE1, 0x8B, + 0x27, 0xEA, 0x7A, 0x48, 0x41, 0xFD, 0x45, 0x19, 0x06, 0xAD, 0x27, 0x99, + 0x4E, 0xC1, 0x70, 0x47, 0xDD, 0xB5, 0x9F, 0x81, 0x53, 0x12, 0xE5, 0xB1, + 0x8C, 0x48, 0x5D, 0x31, 0x43, 0x17, 0xE3, 0x8C, 0xC6, 0x7A, 0x63, 0x96, + 0x4B, 0x29, 0x30, 0x4E, 0x84, 0x4E, 0x62, 0x19, 0x5E, 0x3C, 0xCE, 0x97, + 0x90, 0xA5, 0x7F, 0x01, 0xEB, 0x9D, 0xE0, 0xF8, 0x8B, 0x89, 0xDD, 0x25, + 0x98, 0x3D, 0x92, 0xB6, 0x7E, 0xEF, 0xD9, 0xF1, 0x51, 0x51, 0x7D, 0x2D, + 0x26, 0xC8, 0x69, 0x59, 0x61, 0xE0, 0xAC, 0x6A, 0xB8, 0x2A, 0x36, 0x11, + 0x04, 0x7A, 0x50, 0xBD, 0x32, 0x84, 0xBE, 0x2F, 0xDC, 0x72, 0xD5, 0xD7, + 0x1D, 0x16, 0x47, 0xE4, 0x47, 0x66, 0x20, 0x3F, 0xF4, 0x96, 0xC5, 0xAF, + 0x8E, 0x01, 0x7A, 0xA5, 0x0F, 0x7A, 0x64, 0xF5, 0x0D, 0x18, 0x87, 0xD9, + 0xAE, 0x88, 0xD5, 0xFA, 0x84, 0xC1, 0x3A, 0xC0, 0x69, 0x28, 0x2D, 0xF2, + 0x0D, 0x68, 0x51, 0xAA, 0xE3, 0xA5, 0x77, 0xC6, 0xA4, 0x90, 0x0E, 0xA1, + 0x37, 0x8B, 0x31, 0x23, 0x47, 0xC1, 0x09, 0x08, 0xEB, 0x6E, 0xF7, 0x78, + 0x9B, 0xD7, 0x82, 0xFC, 0x84, 0x20, 0x99, 0x49, 0x19, 0xB6, 0x12, 0x46, + 0xB1, 0xFB, 0x45, 0x55, 0x16, 0xA9, 0xA3, 0x65, 0xAC, 0x9C, 0x07, 0x0F, + 0xEA, 0x6B, 0xDC, 0x1F, 0x2E, 0x06, 0x72, 0xEC, 0x86, 0x88, 0x12, 0xE4, + 0x2D, 0xDB, 0x5F, 0x05, 0x2F, 0xE4, 0xF0, 0x03, 0xD3, 0x26, 0x33, 0xE7, + 0x80, 0xC2, 0xCD, 0x42, 0xA1, 0x17, 0x34, 0x0B +}; + +static const unsigned char TA687_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA688_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x12, 0x48, 0x69, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA688_RSA_N[] = { + 0xF4, 0x1E, 0x7F, 0x52, 0x73, 0x32, 0x0C, 0x73, 0xE4, 0xBD, 0x13, 0x74, + 0xA3, 0xD4, 0x30, 0xA8, 0xD0, 0xAE, 0x4B, 0xD8, 0xB6, 0xDF, 0x75, 0x47, + 0x66, 0xF4, 0x7C, 0xE7, 0x39, 0x04, 0x1E, 0x6A, 0x70, 0x20, 0xD2, 0x5A, + 0x47, 0x72, 0x67, 0x55, 0xF4, 0xA5, 0xE8, 0x9D, 0xD5, 0x1E, 0x21, 0xA1, + 0xF0, 0x67, 0xBA, 0xCC, 0x21, 0x68, 0xBE, 0x44, 0x53, 0xBF, 0x8D, 0xF9, + 0xE2, 0xDC, 0x2F, 0x55, 0xC8, 0x37, 0x3F, 0x1F, 0xA4, 0xC0, 0x9C, 0xB3, + 0xE4, 0x77, 0x5C, 0xA0, 0x46, 0xFE, 0x77, 0xFA, 0x1A, 0xA0, 0x38, 0xEA, + 0xED, 0x9A, 0x72, 0xDE, 0x2B, 0xBD, 0x94, 0x57, 0x3A, 0xBA, 0xEC, 0x79, + 0xE7, 0x5F, 0x7D, 0x42, 0x64, 0x39, 0x7A, 0x26, 0x36, 0xF7, 0x24, 0xF0, + 0xD5, 0x2F, 0xBA, 0x95, 0x98, 0x11, 0x66, 0xAD, 0x97, 0x35, 0xD6, 0x75, + 0x01, 0x80, 0xE0, 0xAF, 0xF4, 0x84, 0x61, 0x8C, 0x0D, 0x1E, 0x5F, 0x7C, + 0x87, 0x96, 0x5E, 0x41, 0xAF, 0xEB, 0x87, 0xEA, 0xF8, 0x5D, 0xF1, 0x2E, + 0x88, 0x05, 0x3E, 0x4C, 0x22, 0xBB, 0xDA, 0x1F, 0x2A, 0xDD, 0x52, 0x46, + 0x64, 0x39, 0xF3, 0x42, 0xCE, 0xD9, 0x9E, 0x0C, 0xB3, 0xB0, 0x77, 0x97, + 0x64, 0x9C, 0xC0, 0xF4, 0xA3, 0x2E, 0x1F, 0x95, 0x07, 0xB0, 0x17, 0xDF, + 0x30, 0xDB, 0x00, 0x18, 0x96, 0x4C, 0xA1, 0x81, 0x4B, 0xDD, 0x04, 0x6D, + 0x53, 0xA3, 0x3D, 0xFC, 0x07, 0xAC, 0xD4, 0xC5, 0x37, 0x82, 0xEB, 0xE4, + 0x95, 0x08, 0x19, 0x28, 0x82, 0xD2, 0x42, 0x3A, 0xA3, 0xD8, 0x53, 0xEC, + 0x79, 0x89, 0x60, 0x48, 0x60, 0xC8, 0x72, 0x92, 0x50, 0xDC, 0x03, 0x8F, + 0x83, 0x3F, 0xB2, 0x42, 0x57, 0x5A, 0xDB, 0x6A, 0xE9, 0x11, 0x97, 0xDD, + 0x85, 0x28, 0xBC, 0x30, 0x4C, 0xAB, 0xE3, 0xC2, 0xB1, 0x45, 0x44, 0x47, + 0x1F, 0xE0, 0x8A, 0x16, 0x07, 0x96, 0xD2, 0x21, 0x0F, 0x53, 0xC0, 0xED, + 0xA9, 0x7E, 0xD4, 0x4E, 0xEC, 0x9B, 0x09, 0xEC, 0xAF, 0x42, 0xAC, 0x30, + 0xD6, 0xBF, 0xD1, 0x10, 0x45, 0xE0, 0xA6, 0x16, 0xB2, 0xA5, 0xC5, 0xD3, + 0x4F, 0x73, 0x94, 0x33, 0x71, 0x02, 0xA1, 0x6A, 0xA3, 0xD6, 0x33, 0x97, + 0x4F, 0x21, 0x63, 0x1E, 0x5B, 0x8F, 0xD9, 0xC1, 0x5E, 0x45, 0x71, 0x77, + 0x0F, 0x81, 0x5D, 0x5F, 0x21, 0x9A, 0xAD, 0x83, 0xCC, 0xFA, 0x5E, 0xD6, + 0x8D, 0x23, 0x5F, 0x1B, 0x3D, 0x41, 0xAF, 0x20, 0x75, 0x66, 0x5A, 0x4A, + 0xF6, 0x9F, 0xFB, 0xAB, 0x18, 0xF7, 0x71, 0xC0, 0xB6, 0x1D, 0x31, 0xEC, + 0x3B, 0x20, 0xEB, 0xCB, 0xE2, 0xB8, 0xF5, 0xAE, 0x92, 0xB2, 0xF7, 0xE1, + 0x84, 0x4B, 0xF2, 0xA2, 0xF2, 0x93, 0x9A, 0x22, 0x9E, 0xD3, 0x14, 0x6F, + 0x36, 0x54, 0xBD, 0x1F, 0x5E, 0x59, 0x15, 0xB9, 0x73, 0xA8, 0xC1, 0x7C, + 0x6F, 0x7B, 0x62, 0xE9, 0x16, 0x6C, 0x47, 0x5A, 0x65, 0xF3, 0x0E, 0x11, + 0x9B, 0x46, 0xD9, 0xFD, 0x6D, 0xDC, 0xD6, 0x9C, 0xC0, 0xB4, 0x7D, 0xA5, + 0xB0, 0xDD, 0x3F, 0x56, 0x6F, 0xA1, 0xF9, 0xF6, 0xE4, 0x12, 0x48, 0xFD, + 0x06, 0x7F, 0x12, 0x57, 0xB6, 0xA9, 0x23, 0x4F, 0x5B, 0x03, 0xC3, 0xE0, + 0x71, 0x2A, 0x23, 0xB7, 0xF7, 0xB0, 0xB1, 0x3B, 0xBC, 0x98, 0xBD, 0xD6, + 0x98, 0xA8, 0x0C, 0x6B, 0xF6, 0x8E, 0x12, 0x67, 0xA6, 0xF2, 0xB2, 0x58, + 0xE4, 0x02, 0x09, 0x13, 0x3C, 0xA9, 0xBB, 0x10, 0xB4, 0xD2, 0x30, 0x45, + 0xF1, 0xEC, 0xF7, 0x00, 0x11, 0xDF, 0x65, 0xF8, 0xDC, 0x2B, 0x43, 0x55, + 0xBF, 0x16, 0x97, 0xC4, 0x0F, 0xD5, 0x2C, 0x61, 0x84, 0xAA, 0x72, 0x86, + 0xFE, 0xE6, 0x3A, 0x7E, 0xC2, 0x3F, 0x7D, 0xEE, 0xFC, 0x2F, 0x14, 0x3E, + 0xE6, 0x85, 0xDD, 0x50, 0x6F, 0xB7, 0x49, 0xED +}; + +static const unsigned char TA688_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA689_DN[] = { + 0x30, 0x6F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x4B, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x09, 0x48, 0x6F, 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x48, 0x6F, + 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA689_RSA_N[] = { + 0xB3, 0x88, 0xD7, 0xEA, 0xCE, 0x0F, 0x20, 0x4E, 0xBE, 0xE6, 0xD6, 0x03, + 0x6D, 0xEE, 0x59, 0xFC, 0xC2, 0x57, 0xDF, 0x29, 0x68, 0xA1, 0x83, 0x0E, + 0x3E, 0x68, 0xC7, 0x68, 0x58, 0x9C, 0x1C, 0x60, 0x4B, 0x89, 0x43, 0x0C, + 0xB9, 0xD4, 0x15, 0xB2, 0xEE, 0xC1, 0x4E, 0x75, 0xE9, 0xB5, 0xA7, 0xEF, + 0xE5, 0xE9, 0x35, 0x99, 0xE4, 0xCC, 0x1C, 0xE7, 0x4B, 0x5F, 0x8D, 0x33, + 0x30, 0x20, 0x33, 0x53, 0xD9, 0xA6, 0xBB, 0xD5, 0x3E, 0x13, 0x8E, 0xE9, + 0x1F, 0x87, 0x49, 0xAD, 0x50, 0x2D, 0x50, 0xCA, 0x18, 0xBE, 0x01, 0x58, + 0xA2, 0x13, 0x70, 0x96, 0xBB, 0x89, 0x88, 0x56, 0x80, 0x5C, 0xF8, 0xBD, + 0x2C, 0x3C, 0xE1, 0x4C, 0x57, 0x88, 0xBB, 0xD3, 0xB9, 0x95, 0xEF, 0xCB, + 0xC7, 0xF6, 0xDA, 0x31, 0x74, 0x28, 0xA6, 0xE6, 0x54, 0x89, 0xF5, 0x41, + 0x31, 0xCA, 0xE5, 0x26, 0x1A, 0xCD, 0x82, 0xE0, 0x70, 0xDA, 0x3B, 0x29, + 0xBB, 0xD5, 0x03, 0xF5, 0x99, 0xBA, 0x55, 0xF5, 0x64, 0xD1, 0x60, 0x0E, + 0xB3, 0x89, 0x49, 0xB8, 0x8A, 0x2F, 0x05, 0xD2, 0x84, 0x45, 0x28, 0x7C, + 0x8F, 0x68, 0x50, 0x12, 0x78, 0xFC, 0x0B, 0xB5, 0x53, 0xCB, 0xC2, 0x98, + 0x1C, 0x84, 0xA3, 0x9E, 0xB0, 0xBE, 0x23, 0xA4, 0xDA, 0xDC, 0xC8, 0x2B, + 0x1E, 0xDA, 0x6E, 0x45, 0x1E, 0x89, 0x98, 0xDA, 0xF9, 0x00, 0x2E, 0x06, + 0xE9, 0x0C, 0x3B, 0x70, 0xD5, 0x50, 0x25, 0x88, 0x99, 0xCB, 0xCD, 0x73, + 0x60, 0xF7, 0xD5, 0xFF, 0x35, 0x67, 0xC5, 0xA1, 0xBC, 0x5E, 0xAB, 0xCD, + 0x4A, 0xB8, 0x45, 0xEB, 0xC8, 0x68, 0x1E, 0x0D, 0x0D, 0x14, 0x46, 0x12, + 0xE3, 0xD2, 0x64, 0x62, 0x8A, 0x42, 0x98, 0xBC, 0xB4, 0xC6, 0x08, 0x08, + 0xF8, 0xFD, 0xA8, 0x4C, 0x64, 0x9C, 0x76, 0x01, 0xBD, 0x2F, 0xA9, 0x6C, + 0x33, 0x0F, 0xD8, 0x3F, 0x28, 0xB8, 0x3C, 0x69, 0x01, 0x42, 0x86, 0x7E, + 0x69, 0xC1, 0xC9, 0x06, 0xCA, 0xE5, 0x7A, 0x46, 0x65, 0xE9, 0xC2, 0xD6, + 0x50, 0x41, 0x2E, 0x3F, 0xB7, 0xE4, 0xED, 0x6C, 0xD7, 0xBF, 0x26, 0x01, + 0x11, 0xA2, 0x16, 0x29, 0x4A, 0x6B, 0x34, 0x06, 0x90, 0xEC, 0x13, 0xD2, + 0xB6, 0xFB, 0x6A, 0x76, 0xD2, 0x3C, 0xED, 0xF0, 0xD6, 0x2D, 0xDD, 0xE1, + 0x15, 0xEC, 0xA3, 0x9B, 0x2F, 0x2C, 0xC9, 0x3E, 0x2B, 0xE4, 0x69, 0x3B, + 0xFF, 0x72, 0x25, 0xB1, 0x36, 0x86, 0x5B, 0xC7, 0x7F, 0x6B, 0x8B, 0x55, + 0x1B, 0x4A, 0xC5, 0x20, 0x61, 0x3D, 0xAE, 0xCB, 0x50, 0xE1, 0x08, 0x3A, + 0xBE, 0xB0, 0x8F, 0x63, 0x41, 0x53, 0x30, 0x08, 0x59, 0x3C, 0x98, 0x1D, + 0x77, 0xBA, 0x63, 0x91, 0x7A, 0xCA, 0x10, 0x50, 0x60, 0xBF, 0xF0, 0xD7, + 0xBC, 0x95, 0x87, 0x8F, 0x97, 0xC5, 0xFE, 0x97, 0x6A, 0x01, 0x94, 0xA3, + 0x7C, 0x5B, 0x85, 0x1D, 0x2A, 0x39, 0x3A, 0xD0, 0x54, 0xA1, 0xD1, 0x39, + 0x71, 0x9D, 0xFD, 0x21, 0xF9, 0xB5, 0x7B, 0xF0, 0xE2, 0xE0, 0x02, 0x8F, + 0x6E, 0x96, 0x24, 0x25, 0x2C, 0xA0, 0x1E, 0x2C, 0xA8, 0xC4, 0x89, 0xA7, + 0xEF, 0xED, 0x99, 0x06, 0x2F, 0xB6, 0x0A, 0x4C, 0x4F, 0xDB, 0xA2, 0xCC, + 0x37, 0x1A, 0xAF, 0x47, 0x85, 0x2D, 0x8A, 0x5F, 0xC4, 0x34, 0x34, 0x4C, + 0x00, 0xFD, 0x18, 0x93, 0x67, 0x13, 0xD1, 0x37, 0xE6, 0x48, 0xB4, 0x8B, + 0x06, 0xC5, 0x57, 0x7B, 0x19, 0x86, 0x0A, 0x79, 0xCB, 0x00, 0xC9, 0x52, + 0xAF, 0x42, 0xFF, 0x37, 0x8F, 0xE1, 0xA3, 0x1E, 0x7A, 0x3D, 0x50, 0xAB, + 0x63, 0x06, 0xE7, 0x15, 0xB5, 0x3F, 0xB6, 0x45, 0x37, 0x94, 0x37, 0xB1, + 0x7E, 0xF2, 0x48, 0xC3, 0x7F, 0xC5, 0x75, 0xFE, 0x97, 0x8D, 0x45, 0x8F, + 0x1A, 0xA7, 0x1A, 0x72, 0x28, 0x1A, 0x40, 0x0F +}; + +static const unsigned char TA689_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA690_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6F, 0x6D, 0x6D, + 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA690_RSA_N[] = { + 0xA7, 0x50, 0x19, 0xDE, 0x3F, 0x99, 0x3D, 0xD4, 0x33, 0x46, 0xF1, 0x6F, + 0x51, 0x61, 0x82, 0xB2, 0xA9, 0x4F, 0x8F, 0x67, 0x89, 0x5D, 0x84, 0xD9, + 0x53, 0xDD, 0x0C, 0x28, 0xD9, 0xD7, 0xF0, 0xFF, 0xAE, 0x95, 0x43, 0x72, + 0x99, 0xF9, 0xB5, 0x5D, 0x7C, 0x8A, 0xC1, 0x42, 0xE1, 0x31, 0x50, 0x74, + 0xD1, 0x81, 0x0D, 0x7C, 0xCD, 0x9B, 0x21, 0xAB, 0x43, 0xE2, 0xAC, 0xAD, + 0x5E, 0x86, 0x6E, 0xF3, 0x09, 0x8A, 0x1F, 0x5A, 0x32, 0xBD, 0xA2, 0xEB, + 0x94, 0xF9, 0xE8, 0x5C, 0x0A, 0xEC, 0xFF, 0x98, 0xD2, 0xAF, 0x71, 0xB3, + 0xB4, 0x53, 0x9F, 0x4E, 0x87, 0xEF, 0x92, 0xBC, 0xBD, 0xEC, 0x4F, 0x32, + 0x30, 0x88, 0x4B, 0x17, 0x5E, 0x57, 0xC4, 0x53, 0xC2, 0xF6, 0x02, 0x97, + 0x8D, 0xD9, 0x62, 0x2B, 0xBF, 0x24, 0x1F, 0x62, 0x8D, 0xDF, 0xC3, 0xB8, + 0x29, 0x4B, 0x49, 0x78, 0x3C, 0x93, 0x60, 0x88, 0x22, 0xFC, 0x99, 0xDA, + 0x36, 0xC8, 0xC2, 0xA2, 0xD4, 0x2C, 0x54, 0x00, 0x67, 0x35, 0x6E, 0x73, + 0xBF, 0x02, 0x58, 0xF0, 0xA4, 0xDD, 0xE5, 0xB0, 0xA2, 0x26, 0x7A, 0xCA, + 0xE0, 0x36, 0xA5, 0x19, 0x16, 0xF5, 0xFD, 0xB7, 0xEF, 0xAE, 0x3F, 0x40, + 0xF5, 0x6D, 0x5A, 0x04, 0xFD, 0xCE, 0x34, 0xCA, 0x24, 0xDC, 0x74, 0x23, + 0x1B, 0x5D, 0x33, 0x13, 0x12, 0x5D, 0xC4, 0x01, 0x25, 0xF6, 0x30, 0xDD, + 0x02, 0x5D, 0x9F, 0xE0, 0xD5, 0x47, 0xBD, 0xB4, 0xEB, 0x1B, 0xA1, 0xBB, + 0x49, 0x49, 0xD8, 0x9F, 0x5B, 0x02, 0xF3, 0x8A, 0xE4, 0x24, 0x90, 0xE4, + 0x62, 0x4F, 0x4F, 0xC1, 0xAF, 0x8B, 0x0E, 0x74, 0x17, 0xA8, 0xD1, 0x72, + 0x88, 0x6A, 0x7A, 0x01, 0x49, 0xCC, 0xB4, 0x46, 0x79, 0xC6, 0x17, 0xB1, + 0xDA, 0x98, 0x1E, 0x07, 0x59, 0xFA, 0x75, 0x21, 0x85, 0x65, 0xDD, 0x90, + 0x56, 0xCE, 0xFB, 0xAB, 0xA5, 0x60, 0x9D, 0xC4, 0x9D, 0xF9, 0x52, 0xB0, + 0x8B, 0xBD, 0x87, 0xF9, 0x8F, 0x2B, 0x23, 0x0A, 0x23, 0x76, 0x3B, 0xF7, + 0x33, 0xE1, 0xC9, 0x00, 0xF3, 0x69, 0xF9, 0x4B, 0xA2, 0xE0, 0x4E, 0xBC, + 0x7E, 0x93, 0x39, 0x84, 0x07, 0xF7, 0x44, 0x70, 0x7E, 0xFE, 0x07, 0x5A, + 0xE5, 0xB1, 0xAC, 0xD1, 0x18, 0xCC, 0xF2, 0x35, 0xE5, 0x49, 0x49, 0x08, + 0xCA, 0x56, 0xC9, 0x3D, 0xFB, 0x0F, 0x18, 0x7D, 0x8B, 0x3B, 0xC1, 0x13, + 0xC2, 0x4D, 0x8F, 0xC9, 0x4F, 0x0E, 0x37, 0xE9, 0x1F, 0xA1, 0x0E, 0x6A, + 0xDF, 0x62, 0x2E, 0xCB, 0x35, 0x06, 0x51, 0x79, 0x2C, 0xC8, 0x25, 0x38, + 0xF4, 0xFA, 0x4B, 0xA7, 0x89, 0x5C, 0x9C, 0xD2, 0xE3, 0x0D, 0x39, 0x86, + 0x4A, 0x74, 0x7C, 0xD5, 0x59, 0x87, 0xC2, 0x3F, 0x4E, 0x0C, 0x5C, 0x52, + 0xF4, 0x3D, 0xF7, 0x52, 0x82, 0xF1, 0xEA, 0xA3, 0xAC, 0xFD, 0x49, 0x34, + 0x1A, 0x28, 0xF3, 0x41, 0x88, 0x3A, 0x13, 0xEE, 0xE8, 0xDE, 0xFF, 0x99, + 0x1D, 0x5F, 0xBA, 0xCB, 0xE8, 0x1E, 0xF2, 0xB9, 0x50, 0x60, 0xC0, 0x31, + 0xD3, 0x73, 0xE5, 0xEF, 0xBE, 0xA0, 0xED, 0x33, 0x0B, 0x74, 0xBE, 0x20, + 0x20, 0xC4, 0x67, 0x6C, 0xF0, 0x08, 0x03, 0x7A, 0x55, 0x80, 0x7F, 0x46, + 0x4E, 0x96, 0xA7, 0xF4, 0x1E, 0x3E, 0xE1, 0xF6, 0xD8, 0x09, 0xE1, 0x33, + 0x64, 0x2B, 0x63, 0xD7, 0x32, 0x5E, 0x9F, 0xF9, 0xC0, 0x7B, 0x0F, 0x78, + 0x6F, 0x97, 0xBC, 0x93, 0x9A, 0xF9, 0x9C, 0x12, 0x90, 0x78, 0x7A, 0x80, + 0x87, 0x15, 0xD7, 0x72, 0x74, 0x9C, 0x55, 0x74, 0x78, 0xB1, 0xBA, 0xE1, + 0x6E, 0x70, 0x04, 0xBA, 0x4F, 0xA0, 0xBA, 0x68, 0xC3, 0x7B, 0xFF, 0x31, + 0xF0, 0x73, 0x3D, 0x3D, 0x94, 0x2A, 0xB1, 0x0B, 0x41, 0x0E, 0xA0, 0xFE, + 0x4D, 0x88, 0x65, 0x6B, 0x79, 0x33, 0xB4, 0xD7 +}; + +static const unsigned char TA690_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA691_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x53, 0x65, 0x63, 0x74, 0x6F, 0x72, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA691_RSA_N[] = { + 0xB6, 0x22, 0x94, 0xFC, 0xA4, 0x48, 0xAF, 0xE8, 0x47, 0x6B, 0x0A, 0xFB, + 0x27, 0x76, 0xE4, 0xF2, 0x3F, 0x8A, 0x3B, 0x7A, 0x4A, 0x2C, 0x31, 0x2A, + 0x8C, 0x8D, 0xB0, 0xA9, 0xC3, 0x31, 0x6B, 0xA8, 0x77, 0x76, 0x84, 0x26, + 0xB6, 0xAC, 0x81, 0x42, 0x0D, 0x08, 0xEB, 0x55, 0x58, 0xBB, 0x7A, 0xF8, + 0xBC, 0x65, 0x7D, 0xF2, 0xA0, 0x6D, 0x8B, 0xA8, 0x47, 0xE9, 0x62, 0x76, + 0x1E, 0x11, 0xEE, 0x08, 0x14, 0xD1, 0xB2, 0x44, 0x16, 0xF4, 0xEA, 0xD0, + 0xFA, 0x1E, 0x2F, 0x5E, 0xDB, 0xCB, 0x73, 0x41, 0xAE, 0xBC, 0x00, 0xB0, + 0x4A, 0x2B, 0x40, 0xB2, 0xAC, 0xE1, 0x3B, 0x4B, 0xC2, 0x2D, 0x9D, 0xE4, + 0xA1, 0x9B, 0xEC, 0x1A, 0x3A, 0x1E, 0xF0, 0x08, 0xB3, 0xD0, 0xE4, 0x24, + 0x35, 0x07, 0x9F, 0x9C, 0xB4, 0xC9, 0x52, 0x6D, 0xDB, 0x07, 0xCA, 0x8F, + 0xB5, 0x5B, 0xF0, 0x83, 0xF3, 0x4F, 0xC7, 0x2D, 0xA5, 0xC8, 0xAD, 0xCB, + 0x95, 0x20, 0xA4, 0x31, 0x28, 0x57, 0x58, 0x5A, 0xE4, 0x8D, 0x1B, 0x9A, + 0xAB, 0x9E, 0x0D, 0x0C, 0xF2, 0x0A, 0x33, 0x39, 0x22, 0x39, 0x0A, 0x97, + 0x2E, 0xF3, 0x53, 0x77, 0xB9, 0x44, 0x45, 0xFD, 0x84, 0xCB, 0x36, 0x20, + 0x81, 0x59, 0x2D, 0x9A, 0x6F, 0x6D, 0x48, 0x48, 0x61, 0xCA, 0x4C, 0xDF, + 0x53, 0xD1, 0xAF, 0x52, 0xBC, 0x44, 0x9F, 0xAB, 0x2F, 0x6B, 0x83, 0x72, + 0xEF, 0x75, 0x80, 0xDA, 0x06, 0x33, 0x1B, 0x5D, 0xC8, 0xDA, 0x63, 0xC6, + 0x4D, 0xCD, 0xAC, 0x66, 0x31, 0xCD, 0xD1, 0xDE, 0x3E, 0x87, 0x10, 0x36, + 0xE1, 0xB9, 0xA4, 0x7A, 0xEF, 0x60, 0x50, 0xB2, 0xCB, 0xCA, 0xA6, 0x56, + 0xE0, 0x37, 0xAF, 0xAB, 0x34, 0x13, 0x39, 0x25, 0xE8, 0x39, 0x66, 0xE4, + 0x98, 0x7A, 0xAA, 0x12, 0x98, 0x9C, 0x59, 0x66, 0x86, 0x3E, 0xAD, 0xF1, + 0xB0, 0xCA, 0x3E, 0x06, 0x0F, 0x7B, 0xF0, 0x11, 0x4B, 0x37, 0xA0, 0x44, + 0x6D, 0x7B, 0xCB, 0xA8, 0x8C, 0x71, 0xF4, 0xD5, 0xB5, 0x91, 0x36, 0xCC, + 0xF0, 0x15, 0xC6, 0x2B, 0xDE, 0x51, 0x17, 0xB1, 0x97, 0x4C, 0x50, 0x3D, + 0xB1, 0x95, 0x59, 0x7C, 0x05, 0x7D, 0x2D, 0x21, 0xD5, 0x00, 0xBF, 0x01, + 0x67, 0xA2, 0x5E, 0x7B, 0xA6, 0x5C, 0xF2, 0xF7, 0x22, 0xF1, 0x90, 0x0D, + 0x93, 0xDB, 0xAA, 0x44, 0x51, 0x66, 0xCC, 0x7D, 0x76, 0x03, 0xEB, 0x6A, + 0xA8, 0x2A, 0x38, 0x19, 0x97, 0x76, 0x0D, 0x6B, 0x8A, 0x61, 0xF9, 0xBC, + 0xF6, 0xEE, 0x76, 0xFD, 0x70, 0x2B, 0xDD, 0x29, 0x3C, 0xF8, 0x0A, 0x1E, + 0x5B, 0x42, 0x1C, 0x8B, 0x56, 0x2F, 0x55, 0x1B, 0x1C, 0xA1, 0x2E, 0xB5, + 0xC7, 0x16, 0xE6, 0xF8, 0xAA, 0x3C, 0x92, 0x8E, 0x69, 0xB6, 0x01, 0xC1, + 0xB5, 0x86, 0x9D, 0x89, 0x0F, 0x0B, 0x38, 0x94, 0x54, 0xE8, 0xEA, 0xDC, + 0x9E, 0x3D, 0x25, 0xBC, 0x53, 0x26, 0xED, 0xD5, 0xAB, 0x39, 0xAA, 0xC5, + 0x40, 0x4C, 0x54, 0xAB, 0xB2, 0xB4, 0xD9, 0xD9, 0xF8, 0xD7, 0x72, 0xDB, + 0x1C, 0xBC, 0x6D, 0xBD, 0x65, 0x5F, 0xEF, 0x88, 0x35, 0x2A, 0x66, 0x2F, + 0xEE, 0xF6, 0xB3, 0x65, 0xF0, 0x33, 0x8D, 0x7C, 0x98, 0x41, 0x69, 0x46, + 0x0F, 0x43, 0x1C, 0x69, 0xFA, 0x9B, 0xB5, 0xD0, 0x61, 0x6A, 0xCD, 0xCA, + 0x4B, 0xD9, 0x4C, 0x90, 0x46, 0xAB, 0x15, 0x59, 0xA1, 0x47, 0x54, 0x29, + 0x2E, 0x83, 0x28, 0x5F, 0x1C, 0xC2, 0xA2, 0xAB, 0x72, 0x17, 0x00, 0x06, + 0x8E, 0x45, 0xEC, 0x8B, 0xE2, 0x33, 0x3D, 0x7F, 0xDA, 0x19, 0x44, 0xE4, + 0x62, 0x72, 0xC3, 0xDF, 0x22, 0xC6, 0xF2, 0x56, 0xD4, 0xDD, 0x5F, 0x95, + 0x72, 0xED, 0x6D, 0x5F, 0xF7, 0x48, 0x03, 0x5B, 0xFD, 0xC5, 0x2A, 0xA0, + 0xF6, 0x73, 0x23, 0x84, 0x10, 0x1B, 0x01, 0xE7 +}; + +static const unsigned char TA691_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA692_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x31 +}; + +static const unsigned char TA692_RSA_N[] = { + 0xAD, 0xE8, 0x24, 0x73, 0xF4, 0x14, 0x37, 0xF3, 0x9B, 0x9E, 0x2B, 0x57, + 0x28, 0x1C, 0x87, 0xBE, 0xDC, 0xB7, 0xDF, 0x38, 0x90, 0x8C, 0x6E, 0x3C, + 0xE6, 0x57, 0xA0, 0x78, 0xF7, 0x75, 0xC2, 0xA2, 0xFE, 0xF5, 0x6A, 0x6E, + 0xF6, 0x00, 0x4F, 0x28, 0xDB, 0xDE, 0x68, 0x86, 0x6C, 0x44, 0x93, 0xB6, + 0xB1, 0x63, 0xFD, 0x14, 0x12, 0x6B, 0xBF, 0x1F, 0xD2, 0xEA, 0x31, 0x9B, + 0x21, 0x7E, 0xD1, 0x33, 0x3C, 0xBA, 0x48, 0xF5, 0xDD, 0x79, 0xDF, 0xB3, + 0xB8, 0xFF, 0x12, 0xF1, 0x21, 0x9A, 0x4B, 0xC1, 0x8A, 0x86, 0x71, 0x69, + 0x4A, 0x66, 0x66, 0x6C, 0x8F, 0x7E, 0x3C, 0x70, 0xBF, 0xAD, 0x29, 0x22, + 0x06, 0xF3, 0xE4, 0xC0, 0xE6, 0x80, 0xAE, 0xE2, 0x4B, 0x8F, 0xB7, 0x99, + 0x7E, 0x94, 0x03, 0x9F, 0xD3, 0x47, 0x97, 0x7C, 0x99, 0x48, 0x23, 0x53, + 0xE8, 0x38, 0xAE, 0x4F, 0x0A, 0x6F, 0x83, 0x2E, 0xD1, 0x49, 0x57, 0x8C, + 0x80, 0x74, 0xB6, 0xDA, 0x2F, 0xD0, 0x38, 0x8D, 0x7B, 0x03, 0x70, 0x21, + 0x1B, 0x75, 0xF2, 0x30, 0x3C, 0xFA, 0x8F, 0xAE, 0xDD, 0xDA, 0x63, 0xAB, + 0xEB, 0x16, 0x4F, 0xC2, 0x8E, 0x11, 0x4B, 0x7E, 0xCF, 0x0B, 0xE8, 0xFF, + 0xB5, 0x77, 0x2E, 0xF4, 0xB2, 0x7B, 0x4A, 0xE0, 0x4C, 0x12, 0x25, 0x0C, + 0x70, 0x8D, 0x03, 0x29, 0xA0, 0xE1, 0x53, 0x24, 0xEC, 0x13, 0xD9, 0xEE, + 0x19, 0xBF, 0x10, 0xB3, 0x4A, 0x8C, 0x3F, 0x89, 0xA3, 0x61, 0x51, 0xDE, + 0xAC, 0x87, 0x07, 0x94, 0xF4, 0x63, 0x71, 0xEC, 0x2E, 0xE2, 0x6F, 0x5B, + 0x98, 0x81, 0xE1, 0x89, 0x5C, 0x34, 0x79, 0x6C, 0x76, 0xEF, 0x3B, 0x90, + 0x62, 0x79, 0xE6, 0xDB, 0xA4, 0x9A, 0x2F, 0x26, 0xC5, 0xD0, 0x10, 0xE1, + 0x0E, 0xDE, 0xD9, 0x10, 0x8E, 0x16, 0xFB, 0xB7, 0xF7, 0xA8, 0xF7, 0xC7, + 0xE5, 0x02, 0x07, 0x98, 0x8F, 0x36, 0x08, 0x95, 0xE7, 0xE2, 0x37, 0x96, + 0x0D, 0x36, 0x75, 0x9E, 0xFB, 0x0E, 0x72, 0xB1, 0x1D, 0x9B, 0xBC, 0x03, + 0xF9, 0x49, 0x05, 0xD8, 0x81, 0xDD, 0x05, 0xB4, 0x2A, 0xD6, 0x41, 0xE9, + 0xAC, 0x01, 0x76, 0x95, 0x0A, 0x0F, 0xD8, 0xDF, 0xD5, 0xBD, 0x12, 0x1F, + 0x35, 0x2F, 0x28, 0x17, 0x6C, 0xD2, 0x98, 0xC1, 0xA8, 0x09, 0x64, 0x77, + 0x6E, 0x47, 0x37, 0xBA, 0xCE, 0xAC, 0x59, 0x5E, 0x68, 0x9D, 0x7F, 0x72, + 0xD6, 0x89, 0xC5, 0x06, 0x41, 0x29, 0x3E, 0x59, 0x3E, 0xDD, 0x26, 0xF5, + 0x24, 0xC9, 0x11, 0xA7, 0x5A, 0xA3, 0x4C, 0x40, 0x1F, 0x46, 0xA1, 0x99, + 0xB5, 0xA7, 0x3A, 0x51, 0x6E, 0x86, 0x3B, 0x9E, 0x7D, 0x72, 0xA7, 0x12, + 0x05, 0x78, 0x59, 0xED, 0x3E, 0x51, 0x78, 0x15, 0x0B, 0x03, 0x8F, 0x8D, + 0xD0, 0x2F, 0x05, 0xB2, 0x3E, 0x7B, 0x4A, 0x1C, 0x4B, 0x73, 0x05, 0x12, + 0xFC, 0xC6, 0xEA, 0xE0, 0x50, 0x13, 0x7C, 0x43, 0x93, 0x74, 0xB3, 0xCA, + 0x74, 0xE7, 0x8E, 0x1F, 0x01, 0x08, 0xD0, 0x30, 0xD4, 0x5B, 0x71, 0x36, + 0xB4, 0x07, 0xBA, 0xC1, 0x30, 0x30, 0x5C, 0x48, 0xB7, 0x82, 0x3B, 0x98, + 0xA6, 0x7D, 0x60, 0x8A, 0xA2, 0xA3, 0x29, 0x82, 0xCC, 0xBA, 0xBD, 0x83, + 0x04, 0x1B, 0xA2, 0x83, 0x03, 0x41, 0xA1, 0xD6, 0x05, 0xF1, 0x1B, 0xC2, + 0xB6, 0xF0, 0xA8, 0x7C, 0x86, 0x3B, 0x46, 0xA8, 0x48, 0x2A, 0x88, 0xDC, + 0x76, 0x9A, 0x76, 0xBF, 0x1F, 0x6A, 0xA5, 0x3D, 0x19, 0x8F, 0xEB, 0x38, + 0xF3, 0x64, 0xDE, 0xC8, 0x2B, 0x0D, 0x0A, 0x28, 0xFF, 0xF7, 0xDB, 0xE2, + 0x15, 0x42, 0xD4, 0x22, 0xD0, 0x27, 0x5D, 0xE1, 0x79, 0xFE, 0x18, 0xE7, + 0x70, 0x88, 0xAD, 0x4E, 0xE6, 0xD9, 0x8B, 0x3A, 0xC6, 0xDD, 0x27, 0x51, + 0x6E, 0xFF, 0xBC, 0x64, 0xF5, 0x33, 0x43, 0x4F +}; + +static const unsigned char TA692_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA693_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x32 +}; + +static const unsigned char TA693_EC_Q[] = { + 0x04, 0xCD, 0x9B, 0xD5, 0x9F, 0x80, 0x83, 0x0A, 0xEC, 0x09, 0x4A, 0xF3, + 0x16, 0x4A, 0x3E, 0x5C, 0xCF, 0x77, 0xAC, 0xDE, 0x67, 0x05, 0x0D, 0x1D, + 0x07, 0xB6, 0xDC, 0x16, 0xFB, 0x5A, 0x8B, 0x14, 0xDB, 0xE2, 0x71, 0x60, + 0xC4, 0xBA, 0x45, 0x95, 0x11, 0x89, 0x8E, 0xEA, 0x06, 0xDF, 0xF7, 0x2A, + 0x16, 0x1C, 0xA4, 0xB9, 0xC5, 0xC5, 0x32, 0xE0, 0x03, 0xE0, 0x1E, 0x82, + 0x18, 0x38, 0x8B, 0xD7, 0x45, 0xD8, 0x0A, 0x6A, 0x6E, 0xE6, 0x00, 0x77, + 0xFB, 0x02, 0x51, 0x7D, 0x22, 0xD8, 0x0A, 0x6E, 0x9A, 0x5B, 0x77, 0xDF, + 0xF0, 0xFA, 0x41, 0xEC, 0x39, 0xDC, 0x75, 0xCA, 0x68, 0x07, 0x0C, 0x1F, + 0xEA +}; + +static const unsigned char TA694_DN[] = { + 0x30, 0x38, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x49, 0x5A, 0x45, 0x4E, 0x50, 0x45, 0x20, 0x53, 0x2E, 0x41, + 0x2E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0A, + 0x49, 0x7A, 0x65, 0x6E, 0x70, 0x65, 0x2E, 0x63, 0x6F, 0x6D +}; + +static const unsigned char TA694_RSA_N[] = { + 0xC9, 0xD3, 0x7A, 0xCA, 0x0F, 0x1E, 0xAC, 0xA7, 0x86, 0xE8, 0x16, 0x65, + 0x6A, 0xB1, 0xC2, 0x1B, 0x45, 0x32, 0x71, 0x95, 0xD9, 0xFE, 0x10, 0x5B, + 0xCC, 0xAF, 0xE7, 0xA5, 0x79, 0x01, 0x8F, 0x89, 0xC3, 0xCA, 0xF2, 0x55, + 0x71, 0xF7, 0x77, 0xBE, 0x77, 0x94, 0xF3, 0x72, 0xA4, 0x2C, 0x44, 0xD8, + 0x9E, 0x92, 0x9B, 0x14, 0x3A, 0xA1, 0xE7, 0x24, 0x90, 0x0A, 0x0A, 0x56, + 0x8E, 0xC5, 0xD8, 0x26, 0x94, 0xE1, 0xD9, 0x48, 0xE1, 0x2D, 0x3E, 0xDA, + 0x0A, 0x72, 0xDD, 0xA3, 0x99, 0x15, 0xDA, 0x81, 0xA2, 0x87, 0xF4, 0x7B, + 0x6E, 0x26, 0x77, 0x89, 0x58, 0xAD, 0xD6, 0xEB, 0x0C, 0xB2, 0x41, 0x7A, + 0x73, 0x6E, 0x6D, 0xDB, 0x7A, 0x78, 0x41, 0xE9, 0x08, 0x88, 0x12, 0x7E, + 0x87, 0x2E, 0x66, 0x11, 0x63, 0x6C, 0x54, 0xFB, 0x3C, 0x9D, 0x72, 0xC0, + 0xBC, 0x2E, 0xFF, 0xC2, 0xB7, 0xDD, 0x0D, 0x76, 0xE3, 0x3A, 0xD7, 0xF7, + 0xB4, 0x68, 0xBE, 0xA2, 0xF5, 0xE3, 0x81, 0x6E, 0xC1, 0x46, 0x6F, 0x5D, + 0x8D, 0xE0, 0x4D, 0xC6, 0x54, 0x55, 0x89, 0x1A, 0x33, 0x31, 0x0A, 0xB1, + 0x57, 0xB9, 0xA3, 0x8A, 0x98, 0xC3, 0xEC, 0x3B, 0x34, 0xC5, 0x95, 0x41, + 0x69, 0x7E, 0x75, 0xC2, 0x3C, 0x20, 0xC5, 0x61, 0xBA, 0x51, 0x47, 0xA0, + 0x20, 0x90, 0x93, 0xA1, 0x90, 0x4B, 0xF3, 0x4E, 0x7C, 0x85, 0x45, 0x54, + 0x9A, 0xD1, 0x05, 0x26, 0x41, 0xB0, 0xB5, 0x4D, 0x1D, 0x33, 0xBE, 0xC4, + 0x03, 0xC8, 0x25, 0x7C, 0xC1, 0x70, 0xDB, 0x3B, 0xF4, 0x09, 0x2D, 0x54, + 0x27, 0x48, 0xAC, 0x2F, 0xE1, 0xC4, 0xAC, 0x3E, 0xC8, 0xCB, 0x92, 0x4C, + 0x53, 0x39, 0x37, 0x23, 0xEC, 0xD3, 0x01, 0xF9, 0xE0, 0x09, 0x44, 0x4D, + 0x4D, 0x64, 0xC0, 0xE1, 0x0D, 0x5A, 0x87, 0x22, 0xBC, 0xAD, 0x1B, 0xA3, + 0xFE, 0x26, 0xB5, 0x15, 0xF3, 0xA7, 0xFC, 0x84, 0x19, 0xE9, 0xEC, 0xA1, + 0x88, 0xB4, 0x44, 0x69, 0x84, 0x83, 0xF3, 0x89, 0xD1, 0x74, 0x06, 0xA9, + 0xCC, 0x0B, 0xD6, 0xC2, 0xDE, 0x27, 0x85, 0x50, 0x26, 0xCA, 0x17, 0xB8, + 0xC9, 0x7A, 0x87, 0x56, 0x2C, 0x1A, 0x01, 0x1E, 0x6C, 0xBE, 0x13, 0xAD, + 0x10, 0xAC, 0xB5, 0x24, 0xF5, 0x38, 0x91, 0xA1, 0xD6, 0x4B, 0xDA, 0xF1, + 0xBB, 0xD2, 0xDE, 0x47, 0xB5, 0xF1, 0xBC, 0x81, 0xF6, 0x59, 0x6B, 0xCF, + 0x19, 0x53, 0xE9, 0x8D, 0x15, 0xCB, 0x4A, 0xCB, 0xA9, 0x6F, 0x44, 0xE5, + 0x1B, 0x41, 0xCF, 0xE1, 0x86, 0xA7, 0xCA, 0xD0, 0x6A, 0x9F, 0xBC, 0x4C, + 0x8D, 0x06, 0x33, 0x5A, 0xA2, 0x85, 0xE5, 0x90, 0x35, 0xA0, 0x62, 0x5C, + 0x16, 0x4E, 0xF0, 0xE3, 0xA2, 0xFA, 0x03, 0x1A, 0xB4, 0x2C, 0x71, 0xB3, + 0x58, 0x2C, 0xDE, 0x7B, 0x0B, 0xDB, 0x1A, 0x0F, 0xEB, 0xDE, 0x21, 0x1F, + 0x06, 0x77, 0x06, 0x03, 0xB0, 0xC9, 0xEF, 0x99, 0xFC, 0xC0, 0xB9, 0x4F, + 0x0B, 0x86, 0x28, 0xFE, 0xD2, 0xB9, 0xEA, 0xE3, 0xDA, 0xA5, 0xC3, 0x47, + 0x69, 0x12, 0xE0, 0xDB, 0xF0, 0xF6, 0x19, 0x8B, 0xED, 0x7B, 0x70, 0xD7, + 0x02, 0xD6, 0xED, 0x87, 0x18, 0x28, 0x2C, 0x04, 0x24, 0x4C, 0x77, 0xE4, + 0x48, 0x8A, 0x1A, 0xC6, 0x3B, 0x9A, 0xD4, 0x0F, 0xCA, 0xFA, 0x75, 0xD2, + 0x01, 0x40, 0x5A, 0x8D, 0x79, 0xBF, 0x8B, 0xCF, 0x4B, 0xCF, 0xAA, 0x16, + 0xC1, 0x95, 0xE4, 0xAD, 0x4C, 0x8A, 0x3E, 0x17, 0x91, 0xD4, 0xB1, 0x62, + 0xE5, 0x82, 0xE5, 0x80, 0x04, 0xA4, 0x03, 0x7E, 0x8D, 0xBF, 0xDA, 0x7F, + 0xA2, 0x0F, 0x97, 0x4F, 0x0C, 0xD3, 0x0D, 0xFB, 0xD7, 0xD1, 0xE5, 0x72, + 0x7E, 0x1C, 0xC8, 0x77, 0xFF, 0x5B, 0x9A, 0x0F, 0xB7, 0xAE, 0x05, 0x46, + 0xE5, 0xF1, 0xA8, 0x16, 0xEC, 0x47, 0xA4, 0x17 +}; + +static const unsigned char TA694_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA695_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x65, 0x2D, 0x53, 0x7A, 0x69, + 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x32, 0x30, 0x30, 0x39, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x65, 0x2D, 0x73, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x2E, 0x68, + 0x75 +}; + +static const unsigned char TA695_RSA_N[] = { + 0xE9, 0xF8, 0x8F, 0xF3, 0x63, 0xAD, 0xDA, 0x86, 0xD8, 0xA7, 0xE0, 0x42, + 0xFB, 0xCF, 0x91, 0xDE, 0xA6, 0x26, 0xF8, 0x99, 0xA5, 0x63, 0x70, 0xAD, + 0x9B, 0xAE, 0xCA, 0x33, 0x40, 0x7D, 0x6D, 0x96, 0x6E, 0xA1, 0x0E, 0x44, + 0xEE, 0xE1, 0x13, 0x9D, 0x94, 0x42, 0x52, 0x9A, 0xBD, 0x75, 0x85, 0x74, + 0x2C, 0xA8, 0x0E, 0x1D, 0x93, 0xB6, 0x18, 0xB7, 0x8C, 0x2C, 0xA8, 0xCF, + 0xFB, 0x5C, 0x71, 0xB9, 0xDA, 0xEC, 0xFE, 0xE8, 0x7E, 0x8F, 0xE4, 0x2F, + 0x1D, 0xB2, 0xA8, 0x75, 0x87, 0xD8, 0xB7, 0xA1, 0xE5, 0x3B, 0xCF, 0x99, + 0x4A, 0x46, 0xD0, 0x83, 0x19, 0x7D, 0xC0, 0xA1, 0x12, 0x1C, 0x95, 0x6D, + 0x4A, 0xF4, 0xD8, 0xC7, 0xA5, 0x4D, 0x33, 0x2E, 0x85, 0x39, 0x40, 0x75, + 0x7E, 0x14, 0x7C, 0x80, 0x12, 0x98, 0x50, 0xC7, 0x41, 0x67, 0xB8, 0xA0, + 0x80, 0x61, 0x54, 0xA6, 0x6C, 0x4E, 0x1F, 0xE0, 0x9D, 0x0E, 0x07, 0xE9, + 0xC9, 0xBA, 0x33, 0xE7, 0xFE, 0xC0, 0x55, 0x28, 0x2C, 0x02, 0x80, 0xA7, + 0x19, 0xF5, 0x9E, 0xDC, 0x55, 0x53, 0x03, 0x97, 0x7B, 0x07, 0x48, 0xFF, + 0x99, 0xFB, 0x37, 0x8A, 0x24, 0xC4, 0x59, 0xCC, 0x50, 0x10, 0x63, 0x8E, + 0xAA, 0xA9, 0x1A, 0xB0, 0x84, 0x1A, 0x86, 0xF9, 0x5F, 0xBB, 0xB1, 0x50, + 0x6E, 0xA4, 0xD1, 0x0A, 0xCC, 0xD5, 0x71, 0x7E, 0x1F, 0xA7, 0x1B, 0x7C, + 0xF5, 0x53, 0x6E, 0x22, 0x5F, 0xCB, 0x2B, 0xE6, 0xD4, 0x7C, 0x5D, 0xAE, + 0xD6, 0xC2, 0xC6, 0x4C, 0xE5, 0x05, 0x01, 0xD9, 0xED, 0x57, 0xFC, 0xC1, + 0x23, 0x79, 0xFC, 0xFA, 0xC8, 0x24, 0x83, 0x95, 0xF3, 0xB5, 0x6A, 0x51, + 0x01, 0xD0, 0x77, 0xD6, 0xE9, 0x12, 0xA1, 0xF9, 0x1A, 0x83, 0xFB, 0x82, + 0x1B, 0xB9, 0xB0, 0x97, 0xF4, 0x76, 0x06, 0x33, 0x43, 0x49, 0xA0, 0xFF, + 0x0B, 0xB5, 0xFA, 0xB5 +}; + +static const unsigned char TA695_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA696_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA696_EC_Q[] = { + 0x04, 0xD4, 0xBC, 0x3D, 0x02, 0x42, 0x75, 0x41, 0x13, 0x23, 0xCD, 0x80, + 0x04, 0x86, 0x02, 0x51, 0x2F, 0x6A, 0xA8, 0x81, 0x62, 0x0B, 0x65, 0xCC, + 0xF6, 0xCA, 0x9D, 0x1E, 0x6F, 0x4A, 0x66, 0x51, 0xA2, 0x03, 0xD9, 0x9D, + 0x91, 0xFA, 0xB6, 0x16, 0xB1, 0x8C, 0x6E, 0xDE, 0x7C, 0xCD, 0xDB, 0x79, + 0xA6, 0x2F, 0xCE, 0xBB, 0xCE, 0x71, 0x2F, 0xE5, 0xA5, 0xAB, 0x28, 0xEC, + 0x63, 0x04, 0x66, 0x99, 0xF8, 0xFA, 0xF2, 0x93, 0x10, 0x05, 0xE1, 0x81, + 0x28, 0x42, 0xE3, 0xC6, 0x68, 0xF4, 0xE6, 0x1B, 0x84, 0x60, 0x4A, 0x89, + 0xAF, 0xED, 0x79, 0x0F, 0x3B, 0xCE, 0xF1, 0xF6, 0x44, 0xF5, 0x01, 0x78, + 0xC0 +}; + +static const unsigned char TA697_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA697_RSA_N[] = { + 0xCA, 0x5B, 0xBE, 0x94, 0x33, 0x8C, 0x29, 0x95, 0x91, 0x16, 0x0A, 0x95, + 0xBD, 0x47, 0x62, 0xC1, 0x89, 0xF3, 0x99, 0x36, 0xDF, 0x46, 0x90, 0xC9, + 0xA5, 0xED, 0x78, 0x6A, 0x6F, 0x47, 0x91, 0x68, 0xF8, 0x27, 0x67, 0x50, + 0x33, 0x1D, 0xA1, 0xA6, 0xFB, 0xE0, 0xE5, 0x43, 0xA3, 0x84, 0x02, 0x57, + 0x01, 0x5D, 0x9C, 0x48, 0x40, 0x82, 0x53, 0x10, 0xBC, 0xBF, 0xC7, 0x3B, + 0x68, 0x90, 0xB6, 0x82, 0x2D, 0xE5, 0xF4, 0x65, 0xD0, 0xCC, 0x6D, 0x19, + 0xCC, 0x95, 0xF9, 0x7B, 0xAC, 0x4A, 0x94, 0xAD, 0x0E, 0xDE, 0x4B, 0x43, + 0x1D, 0x87, 0x07, 0x92, 0x13, 0x90, 0x80, 0x83, 0x64, 0x35, 0x39, 0x04, + 0xFC, 0xE5, 0xE9, 0x6C, 0xB3, 0xB6, 0x1F, 0x50, 0x94, 0x38, 0x65, 0x50, + 0x5C, 0x17, 0x46, 0xB9, 0xB6, 0x85, 0xB5, 0x1C, 0xB5, 0x17, 0xE8, 0xD6, + 0x45, 0x9D, 0xD8, 0xB2, 0x26, 0xB0, 0xCA, 0xC4, 0x70, 0x4A, 0xAE, 0x60, + 0xA4, 0xDD, 0xB3, 0xD9, 0xEC, 0xFC, 0x3B, 0xD5, 0x57, 0x72, 0xBC, 0x3F, + 0xC8, 0xC9, 0xB2, 0xDE, 0x4B, 0x6B, 0xF8, 0x23, 0x6C, 0x03, 0xC0, 0x05, + 0xBD, 0x95, 0xC7, 0xCD, 0x73, 0x3B, 0x66, 0x80, 0x64, 0xE3, 0x1A, 0xAC, + 0x2E, 0xF9, 0x47, 0x05, 0xF2, 0x06, 0xB6, 0x9B, 0x73, 0xF5, 0x78, 0x33, + 0x5B, 0xC7, 0xA1, 0xFB, 0x27, 0x2A, 0xA1, 0xB4, 0x9A, 0x91, 0x8C, 0x91, + 0xD3, 0x3A, 0x82, 0x3E, 0x76, 0x40, 0xB4, 0xCD, 0x52, 0x61, 0x51, 0x70, + 0x28, 0x3F, 0xC5, 0xC5, 0x5A, 0xF2, 0xC9, 0x8C, 0x49, 0xBB, 0x14, 0x5B, + 0x4D, 0xC8, 0xFF, 0x67, 0x4D, 0x4C, 0x12, 0x96, 0xAD, 0xF5, 0xFE, 0x78, + 0xA8, 0x97, 0x87, 0xD7, 0xFD, 0x5E, 0x20, 0x80, 0xDC, 0xA1, 0x4B, 0x22, + 0xFB, 0xD4, 0x89, 0xAD, 0xBA, 0xCE, 0x47, 0x97, 0x47, 0x55, 0x7B, 0x8F, + 0x45, 0xC8, 0x67, 0x28, 0x84, 0x95, 0x1C, 0x68, 0x30, 0xEF, 0xEF, 0x49, + 0xE0, 0x35, 0x7B, 0x64, 0xE7, 0x98, 0xB0, 0x94, 0xDA, 0x4D, 0x85, 0x3B, + 0x3E, 0x55, 0xC4, 0x28, 0xAF, 0x57, 0xF3, 0x9E, 0x13, 0xDB, 0x46, 0x27, + 0x9F, 0x1E, 0xA2, 0x5E, 0x44, 0x83, 0xA4, 0xA5, 0xCA, 0xD5, 0x13, 0xB3, + 0x4B, 0x3F, 0xC4, 0xE3, 0xC2, 0xE6, 0x86, 0x61, 0xA4, 0x52, 0x30, 0xB9, + 0x7A, 0x20, 0x4F, 0x6F, 0x0F, 0x38, 0x53, 0xCB, 0x33, 0x0C, 0x13, 0x2B, + 0x8F, 0xD6, 0x9A, 0xBD, 0x2A, 0xC8, 0x2D, 0xB1, 0x1C, 0x7D, 0x4B, 0x51, + 0xCA, 0x47, 0xD1, 0x48, 0x27, 0x72, 0x5D, 0x87, 0xEB, 0xD5, 0x45, 0xE6, + 0x48, 0x65, 0x9D, 0xAF, 0x52, 0x90, 0xBA, 0x5B, 0xA2, 0x18, 0x65, 0x57, + 0x12, 0x9F, 0x68, 0xB9, 0xD4, 0x15, 0x6B, 0x94, 0xC4, 0x69, 0x22, 0x98, + 0xF4, 0x33, 0xE0, 0xED, 0xF9, 0x51, 0x8E, 0x41, 0x50, 0xC9, 0x34, 0x4F, + 0x76, 0x90, 0xAC, 0xFC, 0x38, 0xC1, 0xD8, 0xE1, 0x7B, 0xB9, 0xE3, 0xE3, + 0x94, 0xE1, 0x46, 0x69, 0xCB, 0x0E, 0x0A, 0x50, 0x6B, 0x13, 0xBA, 0xAC, + 0x0F, 0x37, 0x5A, 0xB7, 0x12, 0xB5, 0x90, 0x81, 0x1E, 0x56, 0xAE, 0x57, + 0x22, 0x86, 0xD9, 0xC9, 0xD2, 0xD1, 0xD7, 0x51, 0xE3, 0xAB, 0x3B, 0xC6, + 0x55, 0xFD, 0x1E, 0x0E, 0xD3, 0x74, 0x0A, 0xD1, 0xDA, 0xAA, 0xEA, 0x69, + 0xB8, 0x97, 0x28, 0x8F, 0x48, 0xC4, 0x07, 0xF8, 0x52, 0x43, 0x3A, 0xF4, + 0xCA, 0x55, 0x35, 0x2C, 0xB0, 0xA6, 0x6A, 0xC0, 0x9C, 0xF9, 0xF2, 0x81, + 0xE1, 0x12, 0x6A, 0xC0, 0x45, 0xD9, 0x67, 0xB3, 0xCE, 0xFF, 0x23, 0xA2, + 0x89, 0x0A, 0x54, 0xD4, 0x14, 0xB9, 0x2A, 0xA8, 0xD7, 0xEC, 0xF9, 0xAB, + 0xCD, 0x25, 0x58, 0x32, 0x79, 0x8F, 0x90, 0x5B, 0x98, 0x39, 0xC4, 0x08, + 0x06, 0xC1, 0xAC, 0x7F, 0x0E, 0x3D, 0x00, 0xA5 +}; + +static const unsigned char TA697_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA698_DN[] = { + 0x30, 0x69, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4B, 0x52, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, 0x42, 0x55, 0x53, 0x49, + 0x4E, 0x45, 0x53, 0x53, 0x20, 0x50, 0x4C, 0x41, 0x54, 0x46, 0x4F, 0x52, + 0x4D, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA698_RSA_N[] = { + 0xB6, 0xD4, 0xF1, 0x93, 0x5C, 0xB5, 0x40, 0x89, 0x0A, 0xAB, 0x0D, 0x90, + 0x5B, 0x50, 0x63, 0xAE, 0x90, 0x94, 0x74, 0x17, 0x45, 0x72, 0xD6, 0x7B, + 0x65, 0x5A, 0x29, 0x4B, 0xA7, 0x56, 0xA0, 0x4B, 0xB8, 0x2F, 0x42, 0x75, + 0xE9, 0xD9, 0x7B, 0x24, 0x5A, 0x31, 0x65, 0xAB, 0x17, 0x17, 0xD1, 0x33, + 0x3A, 0xD9, 0x11, 0xDC, 0x40, 0x36, 0x87, 0xDF, 0xC7, 0x6A, 0xE9, 0x26, + 0x5E, 0x59, 0x8A, 0x77, 0xE3, 0xE8, 0x48, 0x9C, 0x31, 0x16, 0xFA, 0x3E, + 0x91, 0xB1, 0xCA, 0xC9, 0xA3, 0xE2, 0x9F, 0xCE, 0x21, 0x53, 0xA3, 0x02, + 0x36, 0x30, 0xCB, 0x52, 0x02, 0xE5, 0xDA, 0x32, 0x5D, 0xC3, 0xC5, 0xE6, + 0xF9, 0xEE, 0x11, 0xC7, 0x8B, 0xC9, 0x44, 0x1E, 0x84, 0x93, 0x18, 0x4A, + 0xB4, 0x9F, 0xE5, 0x12, 0x64, 0x69, 0xD0, 0x26, 0x85, 0x62, 0x01, 0xB6, + 0xC9, 0x02, 0x1D, 0xBE, 0x83, 0x51, 0xBB, 0x5C, 0xDA, 0xF8, 0xAD, 0x15, + 0x6A, 0x99, 0xF7, 0x92, 0x54, 0xF7, 0x34, 0x5B, 0xE9, 0xBF, 0xEA, 0x29, + 0x81, 0x12, 0xD4, 0x53, 0x91, 0x96, 0xB3, 0x91, 0x5A, 0xDD, 0xFE, 0x90, + 0x73, 0x28, 0xFB, 0x30, 0x46, 0xB5, 0xCA, 0x08, 0x07, 0xC7, 0x71, 0x72, + 0xC9, 0x66, 0xD3, 0x34, 0x97, 0xF6, 0x8C, 0xF4, 0x18, 0x4A, 0xE1, 0xD0, + 0x3D, 0x5A, 0x45, 0xB6, 0x69, 0xA7, 0x29, 0xFB, 0x23, 0xCE, 0x88, 0xD8, + 0x12, 0x9C, 0x00, 0x48, 0xA8, 0xA6, 0x0F, 0xB3, 0x3B, 0x92, 0x8D, 0x71, + 0x0E, 0x74, 0xC5, 0x8B, 0xC8, 0x4C, 0xF9, 0xF4, 0x9B, 0x8E, 0xB8, 0x3C, + 0x69, 0xED, 0x6F, 0x3B, 0x50, 0x2F, 0x58, 0xED, 0xC4, 0xB0, 0xD0, 0x1C, + 0x1B, 0x6A, 0x0C, 0xE2, 0xBC, 0x44, 0xAA, 0xD8, 0xCD, 0x14, 0x5D, 0x94, + 0x78, 0x61, 0xBF, 0x0E, 0x6E, 0xDA, 0x2A, 0xBC, 0x2F, 0x0C, 0x0B, 0x71, + 0xA6, 0xB3, 0x16, 0x3F, 0x9C, 0xE6, 0xF9, 0xCC, 0x9F, 0x53, 0x35, 0xE2, + 0x03, 0xA0, 0xA0, 0x18, 0xBF, 0xBB, 0xF1, 0xBE, 0xF4, 0xD6, 0x8C, 0x87, + 0x0D, 0x42, 0xF7, 0x06, 0xB9, 0xF1, 0x6D, 0xED, 0x04, 0x94, 0xA8, 0xFE, + 0xB6, 0xD3, 0x06, 0xC6, 0x40, 0x61, 0xDF, 0x9D, 0x9D, 0xF3, 0x54, 0x76, + 0xCE, 0x53, 0x3A, 0x01, 0xA6, 0x92, 0x41, 0xEC, 0x04, 0xA3, 0x8F, 0x0D, + 0xA2, 0xD5, 0x09, 0xCA, 0xD6, 0xCB, 0x9A, 0xF1, 0xEF, 0x43, 0x5D, 0xC0, + 0xAB, 0xA5, 0x41, 0xCF, 0x5C, 0x53, 0x70, 0x70, 0xC9, 0x88, 0xA6, 0x2D, + 0xD4, 0x6B, 0x61, 0x73, 0x50, 0x26, 0x86, 0x61, 0x0E, 0x5F, 0x1B, 0xC2, + 0x2B, 0xE2, 0x8C, 0xD5, 0xBB, 0x9D, 0xC1, 0x03, 0x42, 0xBA, 0x94, 0xDA, + 0x5F, 0xA9, 0xB0, 0xCA, 0xCC, 0x4D, 0x0A, 0xEF, 0x47, 0x69, 0x03, 0x2F, + 0x22, 0xFB, 0xF1, 0x28, 0xCE, 0xBF, 0x5D, 0x50, 0x65, 0xA8, 0x90, 0x6D, + 0xB3, 0x74, 0xB0, 0x08, 0xC7, 0xAC, 0xA8, 0xD1, 0xEB, 0x3E, 0x9C, 0xFC, + 0x5D, 0x1A, 0x83, 0x2E, 0x2B, 0xCB, 0xB5, 0xF3, 0x44, 0x9D, 0x3A, 0xA7, + 0x17, 0x61, 0x96, 0xA2, 0x71, 0xD3, 0x70, 0x96, 0x15, 0x4D, 0xB7, 0x4C, + 0x73, 0xEE, 0x19, 0x5C, 0xC5, 0x5B, 0x3E, 0x41, 0xFE, 0xAC, 0x75, 0x60, + 0x3B, 0x1B, 0x63, 0xCE, 0x00, 0xDD, 0xDA, 0x08, 0x90, 0x62, 0xB4, 0xE5, + 0x2D, 0xEE, 0x48, 0xA7, 0x6B, 0x17, 0x99, 0x54, 0xBE, 0x87, 0x4A, 0xE3, + 0xA9, 0x5E, 0x04, 0x4C, 0xEB, 0x10, 0x6D, 0x54, 0xD6, 0xEF, 0xF1, 0xE8, + 0xF2, 0x62, 0x16, 0xCB, 0x80, 0x6B, 0xED, 0x3D, 0xED, 0xF5, 0x1F, 0x30, + 0xA5, 0xAE, 0x4B, 0xC9, 0x13, 0xED, 0x8A, 0x01, 0x01, 0xC9, 0xB8, 0x51, + 0x58, 0xC0, 0x66, 0x3A, 0xB1, 0x66, 0x4B, 0xC4, 0xD5, 0x31, 0x02, 0x62, + 0xE9, 0x74, 0x84, 0x0C, 0xDB, 0x4D, 0x46, 0x2D +}; + +static const unsigned char TA698_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA699_DN[] = { + 0x30, 0x81, 0xA7, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x4E, 0x65, + 0x74, 0x4C, 0x6F, 0x63, 0x6B, 0x20, 0x4B, 0x66, 0x74, 0x2E, 0x31, 0x37, + 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x2E, 0x54, 0x61, 0x6E, + 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, 0x6E, 0x79, 0x6B, + 0x69, 0x61, 0x64, 0xC3, 0xB3, 0x6B, 0x20, 0x28, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x29, 0x31, 0x35, 0x30, 0x33, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x2C, 0x4E, 0x65, 0x74, 0x4C, 0x6F, 0x63, + 0x6B, 0x20, 0x41, 0x72, 0x61, 0x6E, 0x79, 0x20, 0x28, 0x43, 0x6C, 0x61, + 0x73, 0x73, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x29, 0x20, 0x46, 0xC5, 0x91, + 0x74, 0x61, 0x6E, 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, + 0x6E, 0x79 +}; + +static const unsigned char TA699_RSA_N[] = { + 0xC4, 0x24, 0x5E, 0x73, 0xBE, 0x4B, 0x6D, 0x14, 0xC3, 0xA1, 0xF4, 0xE3, + 0x97, 0x90, 0x6E, 0xD2, 0x30, 0x45, 0x1E, 0x3C, 0xEE, 0x67, 0xD9, 0x64, + 0xE0, 0x1A, 0x8A, 0x7F, 0xCA, 0x30, 0xCA, 0x83, 0xE3, 0x20, 0xC1, 0xE3, + 0xF4, 0x3A, 0xD3, 0x94, 0x5F, 0x1A, 0x7C, 0x5B, 0x6D, 0xBF, 0x30, 0x4F, + 0x84, 0x27, 0xF6, 0x9F, 0x1F, 0x49, 0xBC, 0xC6, 0x99, 0x0A, 0x90, 0xF2, + 0x0F, 0xF5, 0x7F, 0x43, 0x84, 0x37, 0x63, 0x51, 0x8B, 0x7A, 0xA5, 0x70, + 0xFC, 0x7A, 0x58, 0xCD, 0x8E, 0x9B, 0xED, 0xC3, 0x46, 0x6C, 0x84, 0x70, + 0x5D, 0xDA, 0xF3, 0x01, 0x90, 0x23, 0xFC, 0x4E, 0x30, 0xA9, 0x7E, 0xE1, + 0x27, 0x63, 0xE7, 0xED, 0x64, 0x3C, 0xA0, 0xB8, 0xC9, 0x33, 0x63, 0xFE, + 0x16, 0x90, 0xFF, 0xB0, 0xB8, 0xFD, 0xD7, 0xA8, 0xC0, 0xC0, 0x94, 0x43, + 0x0B, 0xB6, 0xD5, 0x59, 0xA6, 0x9E, 0x56, 0xD0, 0x24, 0x1F, 0x70, 0x79, + 0xAF, 0xDB, 0x39, 0x54, 0x0D, 0x65, 0x75, 0xD9, 0x15, 0x41, 0x94, 0x01, + 0xAF, 0x5E, 0xEC, 0xF6, 0x8D, 0xF1, 0xFF, 0xAD, 0x64, 0xFE, 0x20, 0x9A, + 0xD7, 0x5C, 0xEB, 0xFE, 0xA6, 0x1F, 0x08, 0x64, 0xA3, 0x8B, 0x76, 0x55, + 0xAD, 0x1E, 0x3B, 0x28, 0x60, 0x2E, 0x87, 0x25, 0xE8, 0xAA, 0xAF, 0x1F, + 0xC6, 0x64, 0x46, 0x20, 0xB7, 0x70, 0x7F, 0x3C, 0xDE, 0x48, 0xDB, 0x96, + 0x53, 0xB7, 0x39, 0x77, 0xE4, 0x1A, 0xE2, 0xC7, 0x16, 0x84, 0x76, 0x97, + 0x5B, 0x2F, 0xBB, 0x19, 0x15, 0x85, 0xF8, 0x69, 0x85, 0xF5, 0x99, 0xA7, + 0xA9, 0xF2, 0x34, 0xA7, 0xA9, 0xB6, 0xA6, 0x03, 0xFC, 0x6F, 0x86, 0x3D, + 0x54, 0x7C, 0x76, 0x04, 0x9B, 0x6B, 0xF9, 0x40, 0x5D, 0x00, 0x34, 0xC7, + 0x2E, 0x99, 0x75, 0x9D, 0xE5, 0x88, 0x03, 0xAA, 0x4D, 0xF8, 0x03, 0xD2, + 0x42, 0x76, 0xC0, 0x1B +}; + +static const unsigned char TA699_RSA_E[] = { + 0xA8, 0x8B +}; + +static const unsigned char TA700_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x42, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA700_RSA_N[] = { + 0xD8, 0x17, 0xB7, 0x1C, 0x4A, 0x24, 0x2A, 0xD6, 0x97, 0xB1, 0xCA, 0xE2, + 0x1E, 0xFB, 0x7D, 0x38, 0xEF, 0x98, 0xF5, 0xB2, 0x39, 0x98, 0x4E, 0x27, + 0xB8, 0x11, 0x5D, 0x7B, 0xD2, 0x25, 0x94, 0x88, 0x82, 0x15, 0x26, 0x6A, + 0x1B, 0x31, 0xBB, 0xA8, 0x5B, 0x21, 0x21, 0x2B, 0xD8, 0x0F, 0x4E, 0x9F, + 0x5A, 0xF1, 0xB1, 0x5A, 0xE4, 0x79, 0xD6, 0x32, 0x23, 0x2B, 0xE1, 0x53, + 0xCC, 0x99, 0x45, 0x5C, 0x7B, 0x4F, 0xAD, 0xBC, 0xBF, 0x87, 0x4A, 0x0B, + 0x4B, 0x97, 0x5A, 0xA8, 0xF6, 0x48, 0xEC, 0x7D, 0x7B, 0x0D, 0xCD, 0x21, + 0x06, 0xDF, 0x9E, 0x15, 0xFD, 0x41, 0x8A, 0x48, 0xB7, 0x20, 0xF4, 0xA1, + 0x7A, 0x1B, 0x57, 0xD4, 0x5D, 0x50, 0xFF, 0xBA, 0x67, 0xD8, 0x23, 0x99, + 0x1F, 0xC8, 0x3F, 0xE3, 0xDE, 0xFF, 0x6F, 0x5B, 0x77, 0xB1, 0x6B, 0x6E, + 0xB8, 0xC9, 0x64, 0xF7, 0xE1, 0xCA, 0x41, 0x46, 0x0E, 0x29, 0x71, 0xD0, + 0xB9, 0x23, 0xFC, 0xC9, 0x81, 0x5F, 0x4E, 0xF7, 0x6F, 0xDF, 0xBF, 0x84, + 0xAD, 0x73, 0x64, 0xBB, 0xB7, 0x42, 0x8E, 0x69, 0xF6, 0xD4, 0x76, 0x1D, + 0x7E, 0x9D, 0xA7, 0xB8, 0x57, 0x8A, 0x51, 0x67, 0x72, 0xD7, 0xD4, 0xA8, + 0xB8, 0x95, 0x54, 0x40, 0x73, 0x03, 0xF6, 0xEA, 0xF4, 0xEB, 0xFE, 0x28, + 0x42, 0x77, 0x3F, 0x9D, 0x23, 0x1B, 0xB2, 0xB6, 0x3D, 0x80, 0x14, 0x07, + 0x4C, 0x2E, 0x4F, 0xF7, 0xD5, 0x0A, 0x16, 0x0D, 0xBD, 0x66, 0x43, 0x37, + 0x7E, 0x23, 0x43, 0x79, 0xC3, 0x40, 0x86, 0xF5, 0x4C, 0x29, 0xDA, 0x8E, + 0x9A, 0xAD, 0x0D, 0xA5, 0x04, 0x87, 0x88, 0x1E, 0x85, 0xE3, 0xE9, 0x53, + 0xD5, 0x9B, 0xC8, 0x8B, 0x03, 0x63, 0x78, 0xEB, 0xE0, 0x19, 0x4A, 0x6E, + 0xBB, 0x2F, 0x6B, 0x33, 0x64, 0x58, 0x93, 0xAD, 0x69, 0xBF, 0x8F, 0x1B, + 0xEF, 0x82, 0x48, 0xC7 +}; + +static const unsigned char TA700_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA701_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x43, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA701_EC_Q[] = { + 0x04, 0x4C, 0xE9, 0x50, 0xC0, 0xC6, 0x0F, 0x72, 0x18, 0xBC, 0xD8, 0xF1, + 0xBA, 0xB3, 0x89, 0xE2, 0x79, 0x4A, 0xA3, 0x16, 0xA7, 0x6B, 0x54, 0x24, + 0xDB, 0x51, 0xFF, 0xEA, 0xF4, 0x09, 0x24, 0xC3, 0x0B, 0x22, 0x9F, 0xCB, + 0x6A, 0x27, 0x82, 0x81, 0x0D, 0xD2, 0xC0, 0xAF, 0x31, 0xE4, 0x74, 0x82, + 0x6E, 0xCA, 0x25, 0xD9, 0x8C, 0x75, 0x9D, 0xF1, 0xDB, 0xD0, 0x9A, 0xA2, + 0x4B, 0x21, 0x7E, 0x16, 0xA7, 0x63, 0x90, 0xD2, 0x39, 0xD4, 0xB1, 0x87, + 0x78, 0x5F, 0x18, 0x96, 0x0F, 0x50, 0x1B, 0x35, 0x37, 0x0F, 0x6A, 0xC6, + 0xDC, 0xD9, 0x13, 0x4D, 0xA4, 0x8E, 0x90, 0x37, 0xE6, 0xBD, 0x5B, 0x31, + 0x91 +}; + +static const unsigned char TA702_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA702_RSA_N[] = { + 0xA0, 0xBE, 0x50, 0x10, 0x8E, 0xE9, 0xF2, 0x6C, 0x40, 0xB4, 0x04, 0x9C, + 0x85, 0xB9, 0x31, 0xCA, 0xDC, 0x2D, 0xE4, 0x11, 0xA9, 0x04, 0x3C, 0x1B, + 0x55, 0xC1, 0xE7, 0x58, 0x30, 0x1D, 0x24, 0xB4, 0xC3, 0xEF, 0x85, 0xDE, + 0x8C, 0x2C, 0xE1, 0xC1, 0x3D, 0xDF, 0x82, 0xE6, 0x4F, 0xAD, 0x47, 0x87, + 0x6C, 0xEC, 0x5B, 0x49, 0xC1, 0x4A, 0xD5, 0xBB, 0x8F, 0xEC, 0x87, 0xAC, + 0x7F, 0x82, 0x9A, 0x86, 0xEC, 0x3D, 0x03, 0x99, 0x52, 0x01, 0xD2, 0x35, + 0x9E, 0xAC, 0xDA, 0xF0, 0x53, 0xC9, 0x66, 0x3C, 0xD4, 0xAC, 0x02, 0x01, + 0xDA, 0x24, 0xD3, 0x3B, 0xA8, 0x02, 0x46, 0xAF, 0xA4, 0x1C, 0xE3, 0xF8, + 0x73, 0x58, 0x76, 0xB7, 0xF6, 0x0E, 0x90, 0x0D, 0xB5, 0xF0, 0xCF, 0xCC, + 0xFA, 0xF9, 0xC6, 0x4C, 0xE5, 0xC3, 0x86, 0x30, 0x0A, 0x8D, 0x17, 0x7E, + 0x35, 0xEB, 0xC5, 0xDF, 0xBB, 0x0E, 0x9C, 0xC0, 0x8D, 0x87, 0xE3, 0x88, + 0x38, 0x85, 0x67, 0xFA, 0x3E, 0xC7, 0xAB, 0xE0, 0x13, 0x9C, 0x05, 0x18, + 0x98, 0xCF, 0x93, 0xF5, 0xB1, 0x92, 0xB4, 0xFC, 0x23, 0xD3, 0xCF, 0xD5, + 0xC4, 0x27, 0x49, 0xE0, 0x9E, 0x3C, 0x9B, 0x08, 0xA3, 0x8B, 0x5D, 0x2A, + 0x21, 0xE0, 0xFC, 0x39, 0xAA, 0x53, 0xDA, 0x7D, 0x7E, 0xCF, 0x1A, 0x09, + 0x53, 0xBC, 0x5D, 0x05, 0x04, 0xCF, 0xA1, 0x4A, 0x8F, 0x8B, 0x76, 0x82, + 0x0D, 0xA1, 0xF8, 0xD2, 0xC7, 0x14, 0x77, 0x5B, 0x90, 0x36, 0x07, 0x81, + 0x9B, 0x3E, 0x06, 0xFA, 0x52, 0x5E, 0x63, 0xC5, 0xA6, 0x00, 0xFE, 0xA5, + 0xE9, 0x52, 0x1B, 0x52, 0xB5, 0x92, 0x39, 0x72, 0x03, 0x09, 0x62, 0xBD, + 0xB0, 0x60, 0x16, 0x6E, 0xA6, 0xDD, 0x25, 0xC2, 0x03, 0x66, 0xDD, 0xF3, + 0x04, 0xD1, 0x40, 0xE2, 0x4E, 0x8B, 0x86, 0xF4, 0x6F, 0xE5, 0x83, 0xA0, + 0x27, 0x84, 0x5E, 0x04, 0xC1, 0xF5, 0x90, 0xBD, 0x30, 0x3D, 0xC4, 0xEF, + 0xA8, 0x69, 0xBC, 0x38, 0x9B, 0xA4, 0xA4, 0x96, 0xD1, 0x62, 0xDA, 0x69, + 0xC0, 0x01, 0x96, 0xAE, 0xCB, 0xC4, 0x51, 0x34, 0xEA, 0x0C, 0xAA, 0xFF, + 0x21, 0x8E, 0x59, 0x8F, 0x4A, 0x5C, 0xE4, 0x61, 0x9A, 0xA7, 0xD2, 0xE9, + 0x2A, 0x78, 0x8D, 0x51, 0x3D, 0x3A, 0x15, 0xEE, 0xA2, 0x59, 0x8E, 0xA9, + 0x5C, 0xDE, 0xC5, 0xF9, 0x90, 0x22, 0xE5, 0x88, 0x45, 0x71, 0xDD, 0x91, + 0x99, 0x6C, 0x7A, 0x9F, 0x3D, 0x3D, 0x98, 0x7C, 0x5E, 0xF6, 0xBE, 0x16, + 0x68, 0xA0, 0x5E, 0xAE, 0x0B, 0x23, 0xFC, 0x5A, 0x0F, 0xAA, 0x22, 0x76, + 0x2D, 0xC9, 0xA1, 0x10, 0x1D, 0xE4, 0xD3, 0x44, 0x23, 0x90, 0x88, 0x9F, + 0xC6, 0x2A, 0xE6, 0xD7, 0xF5, 0x9A, 0xB3, 0x58, 0x1E, 0x2F, 0x30, 0x89, + 0x08, 0x1B, 0x54, 0xA2, 0xB5, 0x98, 0x23, 0xEC, 0x08, 0x77, 0x1C, 0x95, + 0x5D, 0x61, 0xD1, 0xCB, 0x89, 0x9C, 0x5F, 0xA2, 0x4A, 0x91, 0x9A, 0xEF, + 0x21, 0xAA, 0x49, 0x16, 0x08, 0xA8, 0xBD, 0x61, 0x28, 0x31, 0xC9, 0x74, + 0xAD, 0x85, 0xF6, 0xD9, 0xC5, 0xB1, 0x8B, 0xD1, 0xE5, 0x10, 0x32, 0x4D, + 0x5F, 0x8B, 0x20, 0x3A, 0x3C, 0x49, 0x1F, 0x33, 0x85, 0x59, 0x0D, 0xDB, + 0xCB, 0x09, 0x75, 0x43, 0x69, 0x73, 0xFB, 0x6B, 0x71, 0x7D, 0xF0, 0xDF, + 0xC4, 0x4C, 0x7D, 0xC6, 0xA3, 0x2E, 0xC8, 0x95, 0x79, 0xCB, 0x73, 0xA2, + 0x8E, 0x4E, 0x4D, 0x24, 0xFB, 0x5E, 0xE4, 0x04, 0xBE, 0x72, 0x1B, 0xA6, + 0x27, 0x2D, 0x49, 0x5A, 0x99, 0x7A, 0xD7, 0x5C, 0x09, 0x20, 0xB7, 0x7F, + 0x94, 0xB9, 0x4F, 0xF1, 0x0D, 0x1C, 0x5E, 0x88, 0x42, 0x1B, 0x11, 0xB7, + 0xE7, 0x91, 0xDB, 0x9E, 0x6C, 0xF4, 0x6A, 0xDF, 0x8C, 0x06, 0x98, 0x03, + 0xAD, 0xCC, 0x28, 0xEF, 0xA5, 0x47, 0xF3, 0x53 +}; + +static const unsigned char TA702_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA703_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA703_RSA_N[] = { + 0xA1, 0xAE, 0x25, 0xB2, 0x01, 0x18, 0xDC, 0x57, 0x88, 0x3F, 0x46, 0xEB, + 0xF9, 0xAF, 0xE2, 0xEB, 0x23, 0x71, 0xE2, 0x9A, 0xD1, 0x61, 0x66, 0x21, + 0x5F, 0xAA, 0xAF, 0x27, 0x51, 0xE5, 0x6E, 0x1B, 0x16, 0xD4, 0x2D, 0x7D, + 0x50, 0xB0, 0x53, 0x77, 0xBD, 0x78, 0x3A, 0x60, 0xE2, 0x64, 0x02, 0x9B, + 0x7C, 0x86, 0x9B, 0xD6, 0x1A, 0x8E, 0xAD, 0xFF, 0x1F, 0x15, 0x7F, 0xD5, + 0x95, 0x1E, 0x12, 0xCB, 0xE6, 0x14, 0x84, 0x04, 0xC1, 0xDF, 0x36, 0xB3, + 0x16, 0x9F, 0x8A, 0xE3, 0xC9, 0xDB, 0x98, 0x34, 0xCE, 0xD8, 0x33, 0x17, + 0x28, 0x46, 0xFC, 0xA7, 0xC9, 0xF0, 0xD2, 0xB4, 0xD5, 0x4D, 0x09, 0x72, + 0x49, 0xF9, 0xF2, 0x87, 0xE3, 0xA9, 0xDA, 0x7D, 0xA1, 0x7D, 0x6B, 0xB2, + 0x3A, 0x25, 0xA9, 0x6D, 0x52, 0x44, 0xAC, 0xF8, 0xBE, 0x6E, 0xFB, 0xDC, + 0xA6, 0x73, 0x91, 0x90, 0x61, 0xA6, 0x03, 0x14, 0x20, 0xF2, 0xE7, 0x87, + 0xA3, 0x88, 0xAD, 0xAD, 0xA0, 0x8C, 0xFF, 0xA6, 0x0B, 0x25, 0x52, 0x25, + 0xE7, 0x16, 0x01, 0xD5, 0xCB, 0xB8, 0x35, 0x81, 0x0C, 0xA3, 0x3B, 0xF0, + 0xE1, 0xE1, 0xFC, 0x5A, 0x5D, 0xCE, 0x80, 0x71, 0x6D, 0xF8, 0x49, 0xAB, + 0x3E, 0x3B, 0xBA, 0xB8, 0xD7, 0x80, 0x01, 0xFB, 0xA5, 0xEB, 0x5B, 0xB3, + 0xC5, 0x5E, 0x60, 0x2A, 0x31, 0xA0, 0xAF, 0x37, 0xE8, 0x20, 0x3A, 0x9F, + 0xA8, 0x32, 0x2C, 0x0C, 0xCC, 0x09, 0x1D, 0xD3, 0x9E, 0x8E, 0x5D, 0xBC, + 0x4C, 0x98, 0xEE, 0xC5, 0x1A, 0x68, 0x7B, 0xEC, 0x53, 0xA6, 0xE9, 0x14, + 0x35, 0xA3, 0xDF, 0xCD, 0x80, 0x9F, 0x0C, 0x48, 0xFB, 0x1C, 0xF4, 0xF1, + 0xBF, 0x4A, 0xB8, 0xFA, 0xD5, 0x8C, 0x71, 0x4A, 0xC7, 0x1F, 0xAD, 0xFE, + 0x41, 0x9A, 0xB3, 0x83, 0x5D, 0xF2, 0x84, 0x56, 0xEF, 0xA5, 0x57, 0x43, + 0xCE, 0x29, 0xAD, 0x8C, 0xAB, 0x55, 0xBF, 0xC4, 0xFB, 0x5B, 0x01, 0xDD, + 0x23, 0x21, 0xA1, 0x58, 0x00, 0x8E, 0xC3, 0xD0, 0x6A, 0x13, 0xED, 0x13, + 0xE3, 0x12, 0x2B, 0x80, 0xDC, 0x67, 0xE6, 0x95, 0xB2, 0xCD, 0x1E, 0x22, + 0x6E, 0x2A, 0xF8, 0x41, 0xD4, 0xF2, 0xCA, 0x14, 0x07, 0x8D, 0x8A, 0x55, + 0x12, 0xC6, 0x69, 0xF5, 0xB8, 0x86, 0x68, 0x2F, 0x53, 0x5E, 0xB0, 0xD2, + 0xAA, 0x21, 0xC1, 0x98, 0xE6, 0x30, 0xE3, 0x67, 0x55, 0xC7, 0x9B, 0x6E, + 0xAC, 0x19, 0xA8, 0x55, 0xA6, 0x45, 0x06, 0xD0, 0x23, 0x3A, 0xDB, 0xEB, + 0x65, 0x5D, 0x2A, 0x11, 0x11, 0xF0, 0x3B, 0x4F, 0xCA, 0x6D, 0xF4, 0x34, + 0xC4, 0x71, 0xE4, 0xFF, 0x00, 0x5A, 0xF6, 0x5C, 0xAE, 0x23, 0x60, 0x85, + 0x73, 0xF1, 0xE4, 0x10, 0xB1, 0x25, 0xAE, 0xD5, 0x92, 0xBB, 0x13, 0xC1, + 0x0C, 0xE0, 0x39, 0xDA, 0xB4, 0x39, 0x57, 0xB5, 0xAB, 0x35, 0xAA, 0x72, + 0x21, 0x3B, 0x83, 0x35, 0xE7, 0x31, 0xDF, 0x7A, 0x21, 0x6E, 0xB8, 0x32, + 0x08, 0x7D, 0x1D, 0x32, 0x91, 0x15, 0x4A, 0x62, 0x72, 0xCF, 0xE3, 0x77, + 0xA1, 0xBC, 0xD5, 0x11, 0x1B, 0x76, 0x01, 0x67, 0x08, 0xE0, 0x41, 0x0B, + 0xC3, 0xEB, 0x15, 0x6E, 0xF8, 0xA4, 0x19, 0xD9, 0xA2, 0xAB, 0xAF, 0xE2, + 0x27, 0x52, 0x56, 0x2B, 0x02, 0x8A, 0x2C, 0x14, 0x24, 0xF9, 0xBF, 0x42, + 0x02, 0xBF, 0x26, 0xC8, 0xC6, 0x8F, 0xE0, 0x6E, 0x38, 0x7D, 0x53, 0x2D, + 0xE5, 0xED, 0x98, 0xB3, 0x95, 0x63, 0x68, 0x7F, 0xF9, 0x35, 0xF4, 0xDF, + 0x88, 0xC5, 0x60, 0x35, 0x92, 0xC0, 0x7C, 0x69, 0x1C, 0x61, 0x95, 0x16, + 0xD0, 0xEB, 0xDE, 0x0B, 0xAF, 0x3E, 0x04, 0x10, 0x45, 0x65, 0x58, 0x50, + 0x38, 0xAF, 0x48, 0xF2, 0x59, 0xB6, 0x16, 0xF2, 0x3C, 0x0D, 0x90, 0x02, + 0xC6, 0x70, 0x2E, 0x01, 0xAD, 0x3C, 0x15, 0xD7 +}; + +static const unsigned char TA703_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA704_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA704_RSA_N[] = { + 0x9A, 0x18, 0xCA, 0x4B, 0x94, 0x0D, 0x00, 0x2D, 0xAF, 0x03, 0x29, 0x8A, + 0xF0, 0x0F, 0x81, 0xC8, 0xAE, 0x4C, 0x19, 0x85, 0x1D, 0x08, 0x9F, 0xAB, + 0x29, 0x44, 0x85, 0xF3, 0x2F, 0x81, 0xAD, 0x32, 0x1E, 0x90, 0x46, 0xBF, + 0xA3, 0x86, 0x26, 0x1A, 0x1E, 0xFE, 0x7E, 0x1C, 0x18, 0x3A, 0x5C, 0x9C, + 0x60, 0x17, 0x2A, 0x3A, 0x74, 0x83, 0x33, 0x30, 0x7D, 0x61, 0x54, 0x11, + 0xCB, 0xED, 0xAB, 0xE0, 0xE6, 0xD2, 0xA2, 0x7E, 0xF5, 0x6B, 0x6F, 0x18, + 0xB7, 0x0A, 0x0B, 0x2D, 0xFD, 0xE9, 0x3E, 0xEF, 0x0A, 0xC6, 0xB3, 0x10, + 0xE9, 0xDC, 0xC2, 0x46, 0x17, 0xF8, 0x5D, 0xFD, 0xA4, 0xDA, 0xFF, 0x9E, + 0x49, 0x5A, 0x9C, 0xE6, 0x33, 0xE6, 0x24, 0x96, 0xF7, 0x3F, 0xBA, 0x5B, + 0x2B, 0x1C, 0x7A, 0x35, 0xC2, 0xD6, 0x67, 0xFE, 0xAB, 0x66, 0x50, 0x8B, + 0x6D, 0x28, 0x60, 0x2B, 0xEF, 0xD7, 0x60, 0xC3, 0xC7, 0x93, 0xBC, 0x8D, + 0x36, 0x91, 0xF3, 0x7F, 0xF8, 0xDB, 0x11, 0x13, 0xC4, 0x9C, 0x77, 0x76, + 0xC1, 0xAE, 0xB7, 0x02, 0x6A, 0x81, 0x7A, 0xA9, 0x45, 0x83, 0xE2, 0x05, + 0xE6, 0xB9, 0x56, 0xC1, 0x94, 0x37, 0x8F, 0x48, 0x71, 0x63, 0x22, 0xEC, + 0x17, 0x65, 0x07, 0x95, 0x8A, 0x4B, 0xDF, 0x8F, 0xC6, 0x5A, 0x0A, 0xE5, + 0xB0, 0xE3, 0x5F, 0x5E, 0x6B, 0x11, 0xAB, 0x0C, 0xF9, 0x85, 0xEB, 0x44, + 0xE9, 0xF8, 0x04, 0x73, 0xF2, 0xE9, 0xFE, 0x5C, 0x98, 0x8C, 0xF5, 0x73, + 0xAF, 0x6B, 0xB4, 0x7E, 0xCD, 0xD4, 0x5C, 0x02, 0x2B, 0x4C, 0x39, 0xE1, + 0xB2, 0x95, 0x95, 0x2D, 0x42, 0x87, 0xD7, 0xD5, 0xB3, 0x90, 0x43, 0xB7, + 0x6C, 0x13, 0xF1, 0xDE, 0xDD, 0xF6, 0xC4, 0xF8, 0x89, 0x3F, 0xD1, 0x75, + 0xF5, 0x92, 0xC3, 0x91, 0xD5, 0x8A, 0x88, 0xD0, 0x90, 0xEC, 0xDC, 0x6D, + 0xDE, 0x89, 0xC2, 0x65, 0x71, 0x96, 0x8B, 0x0D, 0x03, 0xFD, 0x9C, 0xBF, + 0x5B, 0x16, 0xAC, 0x92, 0xDB, 0xEA, 0xFE, 0x79, 0x7C, 0xAD, 0xEB, 0xAF, + 0xF7, 0x16, 0xCB, 0xDB, 0xCD, 0x25, 0x2B, 0xE5, 0x1F, 0xFB, 0x9A, 0x9F, + 0xE2, 0x51, 0xCC, 0x3A, 0x53, 0x0C, 0x48, 0xE6, 0x0E, 0xBD, 0xC9, 0xB4, + 0x76, 0x06, 0x52, 0xE6, 0x11, 0x13, 0x85, 0x72, 0x63, 0x03, 0x04, 0xE0, + 0x04, 0x36, 0x2B, 0x20, 0x19, 0x02, 0xE8, 0x74, 0xA7, 0x1F, 0xB6, 0xC9, + 0x56, 0x66, 0xF0, 0x75, 0x25, 0xDC, 0x67, 0xC1, 0x0E, 0x61, 0x60, 0x88, + 0xB3, 0x3E, 0xD1, 0xA8, 0xFC, 0xA3, 0xDA, 0x1D, 0xB0, 0xD1, 0xB1, 0x23, + 0x54, 0xDF, 0x44, 0x76, 0x6D, 0xED, 0x41, 0xD8, 0xC1, 0xB2, 0x22, 0xB6, + 0x53, 0x1C, 0xDF, 0x35, 0x1D, 0xDC, 0xA1, 0x77, 0x2A, 0x31, 0xE4, 0x2D, + 0xF5, 0xE5, 0xE5, 0xDB, 0xC8, 0xE0, 0xFF, 0xE5, 0x80, 0xD7, 0x0B, 0x63, + 0xA0, 0xFF, 0x33, 0xA1, 0x0F, 0xBA, 0x2C, 0x15, 0x15, 0xEA, 0x97, 0xB3, + 0xD2, 0xA2, 0xB5, 0xBE, 0xF2, 0x8C, 0x96, 0x1E, 0x1A, 0x8F, 0x1D, 0x6C, + 0xA4, 0x61, 0x37, 0xB9, 0x86, 0x73, 0x33, 0xD7, 0x97, 0x96, 0x9E, 0x23, + 0x7D, 0x82, 0xA4, 0x4C, 0x81, 0xE2, 0xA1, 0xD1, 0xBA, 0x67, 0x5F, 0x95, + 0x07, 0xA3, 0x27, 0x11, 0xEE, 0x16, 0x10, 0x7B, 0xBC, 0x45, 0x4A, 0x4C, + 0xB2, 0x04, 0xD2, 0xAB, 0xEF, 0xD5, 0xFD, 0x0C, 0x51, 0xCE, 0x50, 0x6A, + 0x08, 0x31, 0xF9, 0x91, 0xDA, 0x0C, 0x8F, 0x64, 0x5C, 0x03, 0xC3, 0x3A, + 0x8B, 0x20, 0x3F, 0x6E, 0x8D, 0x67, 0x3D, 0x3A, 0xD6, 0xFE, 0x7D, 0x5B, + 0x88, 0xC9, 0x5E, 0xFB, 0xCC, 0x61, 0xDC, 0x8B, 0x33, 0x77, 0xD3, 0x44, + 0x32, 0x35, 0x09, 0x62, 0x04, 0x92, 0x16, 0x10, 0xD8, 0x9E, 0x27, 0x47, + 0xFB, 0x3B, 0x21, 0xE3, 0xF8, 0xEB, 0x1D, 0x5B +}; + +static const unsigned char TA704_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA705_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA705_RSA_N[] = { + 0xB3, 0xCB, 0x0E, 0x10, 0x67, 0x8E, 0xEA, 0x14, 0x97, 0xA7, 0x32, 0x2A, + 0x0A, 0x56, 0x36, 0x7F, 0x68, 0x4C, 0xC7, 0xB3, 0x6F, 0x3A, 0x23, 0x14, + 0x91, 0xFF, 0x19, 0x7F, 0xA5, 0xCA, 0xAC, 0xEE, 0xB3, 0x76, 0x9D, 0x7A, + 0xE9, 0x8B, 0x1B, 0xAB, 0x6B, 0x31, 0xDB, 0xFA, 0x0B, 0x53, 0x4C, 0xAF, + 0xC5, 0xA5, 0x1A, 0x79, 0x3C, 0x8A, 0x4C, 0xFF, 0xAC, 0xDF, 0x25, 0xDE, + 0x4E, 0xD9, 0x82, 0x32, 0x0B, 0x44, 0xDE, 0xCA, 0xDB, 0x8C, 0xAC, 0xA3, + 0x6E, 0x16, 0x83, 0x3B, 0xA6, 0x64, 0x4B, 0x32, 0x89, 0xFB, 0x16, 0x16, + 0x38, 0x7E, 0xEB, 0x43, 0xE2, 0xD3, 0x74, 0x4A, 0xC2, 0x62, 0x0A, 0x73, + 0x0A, 0xDD, 0x49, 0xB3, 0x57, 0xD2, 0xB0, 0x0A, 0x85, 0x9D, 0x71, 0x3C, + 0xDE, 0xA3, 0xCB, 0xC0, 0x32, 0xF3, 0x01, 0x39, 0x20, 0x43, 0x1B, 0x35, + 0xD1, 0x53, 0xB3, 0xB1, 0xEE, 0xC5, 0x93, 0x69, 0x82, 0x3E, 0x16, 0xB5, + 0x28, 0x46, 0xA1, 0xDE, 0xEA, 0x89, 0x09, 0xED, 0x43, 0xB8, 0x05, 0x46, + 0x8A, 0x86, 0xF5, 0x59, 0x47, 0xBE, 0x1B, 0x6F, 0x01, 0x21, 0x10, 0xB9, + 0xFD, 0xA9, 0xD2, 0x28, 0xCA, 0x10, 0x39, 0x09, 0xCA, 0x13, 0x36, 0xCF, + 0x9C, 0xAD, 0xAD, 0x40, 0x74, 0x79, 0x2B, 0x02, 0x3F, 0x34, 0xFF, 0xFA, + 0x20, 0x69, 0x7D, 0xD3, 0xEE, 0x61, 0xF5, 0xBA, 0xB3, 0xE7, 0x30, 0xD0, + 0x37, 0x23, 0x86, 0x72, 0x61, 0x45, 0x29, 0x48, 0x59, 0x68, 0x6F, 0x77, + 0xA6, 0x2E, 0x81, 0xBE, 0x07, 0x4D, 0x6F, 0xAF, 0xCE, 0xC4, 0x45, 0x13, + 0x91, 0x14, 0x70, 0x06, 0x8F, 0x1F, 0x9F, 0xF8, 0x87, 0x69, 0xB1, 0x0E, + 0xEF, 0xC3, 0x89, 0x19, 0xEB, 0xEA, 0x1C, 0x61, 0xFC, 0x7A, 0x6C, 0x8A, + 0xDC, 0xD6, 0x03, 0x0B, 0x9E, 0x26, 0xBA, 0x12, 0xDD, 0xD4, 0x54, 0x39, + 0xAB, 0x26, 0xA3, 0x33, 0xEA, 0x75, 0x81, 0xDA, 0x2D, 0xCD, 0x0F, 0x4F, + 0xE4, 0x03, 0xD1, 0xEF, 0x15, 0x97, 0x1B, 0x6B, 0x90, 0xC5, 0x02, 0x90, + 0x93, 0x66, 0x02, 0x21, 0xB1, 0x47, 0xDE, 0x8B, 0x9A, 0x4A, 0x80, 0xB9, + 0x55, 0x8F, 0xB5, 0xA2, 0x2F, 0xC0, 0xD6, 0x33, 0x67, 0xDA, 0x7E, 0xC4, + 0xA7, 0xB4, 0x04, 0x44, 0xEB, 0x47, 0xFB, 0xE6, 0x58, 0xB9, 0xF7, 0x0C, + 0xF0, 0x7B, 0x2B, 0xB1, 0xC0, 0x70, 0x29, 0xC3, 0x40, 0x62, 0x2D, 0x3B, + 0x48, 0x69, 0xDC, 0x23, 0x3C, 0x48, 0xEB, 0x7B, 0x09, 0x79, 0xA9, 0x6D, + 0xDA, 0xA8, 0x30, 0x98, 0xCF, 0x80, 0x72, 0x03, 0x88, 0xA6, 0x5B, 0x46, + 0xAE, 0x72, 0x79, 0x7C, 0x08, 0x03, 0x21, 0x65, 0xAE, 0xB7, 0xE1, 0x1C, + 0xA5, 0xB1, 0x2A, 0xA2, 0x31, 0xDE, 0x66, 0x04, 0xF7, 0xC0, 0x74, 0xE8, + 0x71, 0xDE, 0xFF, 0x3D, 0x59, 0xCC, 0x96, 0x26, 0x12, 0x8B, 0x85, 0x95, + 0x57, 0x1A, 0xAB, 0x6B, 0x75, 0x0B, 0x44, 0x3D, 0x11, 0x28, 0x3C, 0x7B, + 0x61, 0xB7, 0xE2, 0x8F, 0x67, 0x4F, 0xE5, 0xEC, 0x3C, 0x4C, 0x60, 0x80, + 0x69, 0x57, 0x38, 0x1E, 0x01, 0x5B, 0x8D, 0x55, 0xE8, 0xC7, 0xDF, 0xC0, + 0xCC, 0x77, 0x23, 0x34, 0x49, 0x75, 0x7C, 0xF6, 0x98, 0x11, 0xEB, 0x2D, + 0xDE, 0xED, 0x41, 0x2E, 0x14, 0x05, 0x02, 0x7F, 0xE0, 0xFE, 0x20, 0xEB, + 0x35, 0xE7, 0x11, 0xAC, 0x22, 0xCE, 0x57, 0x3D, 0xDE, 0xC9, 0x30, 0x6D, + 0x10, 0x03, 0x85, 0xCD, 0xF1, 0xFF, 0x8C, 0x16, 0xB5, 0xC1, 0xB2, 0x3E, + 0x88, 0x6C, 0x60, 0x7F, 0x90, 0x4F, 0x95, 0xF7, 0xF6, 0x2D, 0xAD, 0x01, + 0x39, 0x07, 0x04, 0xFA, 0x75, 0x80, 0x7D, 0xBF, 0x49, 0x50, 0xED, 0xEF, + 0xC9, 0xC4, 0x7C, 0x1C, 0xEB, 0x80, 0x7E, 0xDB, 0xB6, 0xD0, 0xDD, 0x13, + 0xFE, 0xC9, 0xD3, 0x9C, 0xD7, 0xB2, 0x97, 0xA9 +}; + +static const unsigned char TA705_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA706_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA706_RSA_N[] = { + 0xCC, 0x57, 0x42, 0x16, 0x54, 0x9C, 0xE6, 0x98, 0xD3, 0xD3, 0x4D, 0xEE, + 0xFE, 0xED, 0xC7, 0x9F, 0x43, 0x39, 0x4A, 0x65, 0xB3, 0xE8, 0x16, 0x88, + 0x34, 0xDB, 0x0D, 0x59, 0x91, 0x74, 0xCF, 0x92, 0xB8, 0x04, 0x40, 0xAD, + 0x02, 0x4B, 0x31, 0xAB, 0xBC, 0x8D, 0x91, 0x68, 0xD8, 0x20, 0x0E, 0x1A, + 0x01, 0xE2, 0x1A, 0x7B, 0x4E, 0x17, 0x5D, 0xE2, 0x8A, 0xB7, 0x3F, 0x99, + 0x1A, 0xCD, 0xEB, 0x61, 0xAB, 0xC2, 0x65, 0xA6, 0x1F, 0xB7, 0xB7, 0xBD, + 0xB7, 0x8F, 0xFC, 0xFD, 0x70, 0x8F, 0x0B, 0xA0, 0x67, 0xBE, 0x01, 0xA2, + 0x59, 0xCF, 0x71, 0xE6, 0x0F, 0x29, 0x76, 0xFF, 0xB1, 0x56, 0x79, 0x45, + 0x2B, 0x1F, 0x9E, 0x7A, 0x54, 0xE8, 0xA3, 0x29, 0x35, 0x68, 0xA4, 0x01, + 0x4F, 0x0F, 0xA4, 0x2E, 0x37, 0xEF, 0x1B, 0xBF, 0xE3, 0x8F, 0x10, 0xA8, + 0x72, 0xAB, 0x58, 0x57, 0xE7, 0x54, 0x86, 0xC8, 0xC9, 0xF3, 0x5B, 0xDA, + 0x2C, 0xDA, 0x5D, 0x8E, 0x6E, 0x3C, 0xA3, 0x3E, 0xDA, 0xFB, 0x82, 0xE5, + 0xDD, 0xF2, 0x5C, 0xB2, 0x05, 0x33, 0x6F, 0x8A, 0x36, 0xCE, 0xD0, 0x13, + 0x4E, 0xFF, 0xBF, 0x4A, 0x0C, 0x34, 0x4C, 0xA6, 0xC3, 0x21, 0xBD, 0x50, + 0x04, 0x55, 0xEB, 0xB1, 0xBB, 0x9D, 0xFB, 0x45, 0x1E, 0x64, 0x15, 0xDE, + 0x55, 0x01, 0x8C, 0x02, 0x76, 0xB5, 0xCB, 0xA1, 0x3F, 0x42, 0x69, 0xBC, + 0x2F, 0xBD, 0x68, 0x43, 0x16, 0x56, 0x89, 0x2A, 0x37, 0x61, 0x91, 0xFD, + 0xA6, 0xAE, 0x4E, 0xC0, 0xCB, 0x14, 0x65, 0x94, 0x37, 0x4B, 0x92, 0x06, + 0xEF, 0x04, 0xD0, 0xC8, 0x9C, 0x88, 0xDB, 0x0B, 0x7B, 0x81, 0xAF, 0xB1, + 0x3D, 0x2A, 0xC4, 0x65, 0x3A, 0x78, 0xB6, 0xEE, 0xDC, 0x80, 0xB1, 0xD2, + 0xD3, 0x99, 0x9C, 0x3A, 0xEE, 0x6B, 0x5A, 0x6B, 0xB3, 0x8D, 0xB7, 0xD5, + 0xCE, 0x9C, 0xC2, 0xBE, 0xA5, 0x4B, 0x2F, 0x16, 0xB1, 0x9E, 0x68, 0x3B, + 0x06, 0x6F, 0xAE, 0x7D, 0x9F, 0xF8, 0xDE, 0xEC, 0xCC, 0x29, 0xA7, 0x98, + 0xA3, 0x25, 0x43, 0x2F, 0xEF, 0xF1, 0x5F, 0x26, 0xE1, 0x88, 0x4D, 0xF8, + 0x5E, 0x6E, 0xD7, 0xD9, 0x14, 0x6E, 0x19, 0x33, 0x69, 0xA7, 0x3B, 0x84, + 0x89, 0x93, 0xC4, 0x53, 0x55, 0x13, 0xA1, 0x51, 0x78, 0x40, 0xF8, 0xB8, + 0xC9, 0xA2, 0xEE, 0x7B, 0xBA, 0x52, 0x42, 0x83, 0x9E, 0x14, 0xED, 0x05, + 0x52, 0x5A, 0x59, 0x56, 0xA7, 0x97, 0xFC, 0x9D, 0x3F, 0x0A, 0x29, 0xD8, + 0xDC, 0x4F, 0x91, 0x0E, 0x13, 0xBC, 0xDE, 0x95, 0xA4, 0xDF, 0x8B, 0x99, + 0xBE, 0xAC, 0x9B, 0x33, 0x88, 0xEF, 0xB5, 0x81, 0xAF, 0x1B, 0xC6, 0x22, + 0x53, 0xC8, 0xF6, 0xC7, 0xEE, 0x97, 0x14, 0xB0, 0xC5, 0x7C, 0x78, 0x52, + 0xC8, 0xF0, 0xCE, 0x6E, 0x77, 0x60, 0x84, 0xA6, 0xE9, 0x2A, 0x76, 0x20, + 0xED, 0x58, 0x01, 0x17, 0x30, 0x93, 0xE9, 0x1A, 0x8B, 0xE0, 0x73, 0x63, + 0xD9, 0x6A, 0x92, 0x94, 0x49, 0x4E, 0xB4, 0xAD, 0x4A, 0x85, 0xC4, 0xA3, + 0x22, 0x30, 0xFC, 0x09, 0xED, 0x68, 0x22, 0x73, 0xA6, 0x88, 0x0C, 0x55, + 0x21, 0x58, 0xC5, 0xE1, 0x3A, 0x9F, 0x2A, 0xDD, 0xCA, 0xE1, 0x90, 0xE0, + 0xD9, 0x73, 0xAB, 0x6C, 0x80, 0xB8, 0xE8, 0x0B, 0x64, 0x93, 0xA0, 0x9C, + 0x8C, 0x19, 0xFF, 0xB3, 0xD2, 0x0C, 0xEC, 0x91, 0x26, 0x87, 0x8A, 0xB3, + 0xA2, 0xE1, 0x70, 0x8F, 0x2C, 0x0A, 0xE5, 0xCD, 0x6D, 0x68, 0x51, 0xEB, + 0xDA, 0x3F, 0x05, 0x7F, 0x8B, 0x32, 0xE6, 0x13, 0x5C, 0x6B, 0xFE, 0x5F, + 0x40, 0xE2, 0x22, 0xC8, 0xB4, 0xB4, 0x64, 0x4F, 0xD6, 0xBA, 0x7D, 0x48, + 0x3E, 0xA8, 0x69, 0x0C, 0xD7, 0xBB, 0x86, 0x71, 0xC9, 0x73, 0xB8, 0x3F, + 0x3B, 0x9D, 0x25, 0x4B, 0xDA, 0xFF, 0x40, 0xEB +}; + +static const unsigned char TA706_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA707_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, + 0x36 +}; + +static const unsigned char TA707_EC_Q[] = { + 0x04, 0x76, 0xFA, 0x99, 0xA9, 0x6E, 0x20, 0xED, 0xF9, 0xD7, 0x77, 0xE3, + 0x07, 0x3B, 0xA8, 0xDB, 0x3D, 0x5F, 0x38, 0xE8, 0xAB, 0x55, 0xA6, 0x56, + 0x4F, 0xD6, 0x48, 0xEA, 0xEC, 0x7F, 0x2D, 0xAA, 0xC3, 0xB2, 0xC5, 0x79, + 0xEC, 0x99, 0x61, 0x7F, 0x10, 0x79, 0xC7, 0x02, 0x5A, 0xF9, 0x04, 0x37, + 0xF5, 0x34, 0x35, 0x2B, 0x77, 0xCE, 0x7F, 0x20, 0x8F, 0x52, 0xA3, 0x00, + 0x89, 0xEC, 0xD5, 0xA7, 0xA2, 0x6D, 0x5B, 0xE3, 0x4B, 0x92, 0x93, 0xA0, + 0x80, 0xF5, 0x01, 0x94, 0xDC, 0xF0, 0x68, 0x07, 0x1E, 0xCD, 0xEE, 0xFE, + 0x25, 0x52, 0xB5, 0x20, 0x43, 0x1C, 0x1B, 0xFE, 0xEB, 0x19, 0xCE, 0x43, + 0xA3 +}; + +static const unsigned char TA708_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, + 0x36 +}; + +static const unsigned char TA708_RSA_N[] = { + 0x93, 0xBE, 0xD5, 0x36, 0x52, 0x75, 0xD8, 0x01, 0x23, 0xA0, 0x1C, 0x47, + 0x42, 0x49, 0xEE, 0x63, 0xB6, 0xB7, 0x21, 0xFD, 0xC4, 0x95, 0xD5, 0x48, + 0x2B, 0x26, 0x7C, 0x14, 0x53, 0x10, 0xDA, 0x79, 0xFD, 0x2B, 0xB7, 0x2D, + 0xA4, 0xD4, 0x2C, 0xFA, 0xEA, 0x32, 0xDD, 0x49, 0xC2, 0xB9, 0xBD, 0x0F, + 0x48, 0x3D, 0x7B, 0x5A, 0x98, 0x54, 0xAF, 0x9E, 0x5D, 0x31, 0x74, 0x4F, + 0x07, 0xFC, 0x50, 0x21, 0xDD, 0xA4, 0xCF, 0x68, 0x4F, 0x1B, 0x12, 0x63, + 0x6D, 0x25, 0x99, 0x4C, 0x2A, 0x99, 0xF3, 0x48, 0x30, 0x61, 0xFA, 0x81, + 0x7C, 0x1E, 0xA7, 0x08, 0x4A, 0xDC, 0x3E, 0x2B, 0x1C, 0x1F, 0x18, 0x4C, + 0x71, 0xAA, 0x35, 0x8C, 0xAD, 0xF8, 0x6E, 0xE8, 0x3B, 0x4A, 0xD9, 0xE5, + 0x94, 0x02, 0xD6, 0x89, 0x84, 0x13, 0xAA, 0x6D, 0xC8, 0x4F, 0x33, 0xCC, + 0x50, 0x96, 0x37, 0x92, 0x33, 0xDC, 0x5F, 0x88, 0xE7, 0x9F, 0x54, 0xD9, + 0x48, 0xF0, 0x98, 0x43, 0xD6, 0x66, 0xFD, 0x9F, 0x17, 0x38, 0x43, 0xC5, + 0x01, 0x51, 0x0B, 0xD7, 0xE3, 0x23, 0x0F, 0x14, 0x5D, 0x5B, 0x14, 0xE7, + 0x4B, 0xBE, 0xDD, 0xF4, 0xC8, 0xDA, 0x03, 0x37, 0xD1, 0xD6, 0x39, 0xA1, + 0x21, 0x51, 0x30, 0x83, 0xB0, 0x6D, 0xD7, 0x30, 0x4E, 0x96, 0x5B, 0x91, + 0xF0, 0x70, 0x24, 0xAB, 0xBF, 0x45, 0x81, 0x64, 0x43, 0x0D, 0xBD, 0x21, + 0x3A, 0x2F, 0x3C, 0xE9, 0x9E, 0x0D, 0xCB, 0x20, 0xB5, 0x42, 0x27, 0xCC, + 0xDA, 0x6F, 0x9B, 0xEE, 0x64, 0x30, 0x90, 0x39, 0xCD, 0x93, 0x65, 0x81, + 0x21, 0x31, 0xB5, 0x23, 0x50, 0x33, 0x37, 0x22, 0xE3, 0x38, 0xED, 0xF8, + 0x31, 0x30, 0xCC, 0x45, 0xFE, 0x62, 0xF9, 0xD1, 0x5D, 0x32, 0x79, 0x42, + 0x87, 0xDF, 0x6A, 0xCC, 0x56, 0x19, 0x40, 0x4D, 0xCE, 0xAA, 0xBB, 0xF9, + 0xB5, 0x76, 0x49, 0x94, 0xF1, 0x27, 0xF8, 0x91, 0xA5, 0x83, 0xE5, 0x06, + 0xB3, 0x63, 0x0E, 0x80, 0xDC, 0xE0, 0x12, 0x55, 0x80, 0xA6, 0x3B, 0x66, + 0xB4, 0x39, 0x87, 0x2D, 0xC8, 0xF0, 0xD0, 0xD1, 0x14, 0xE9, 0xE4, 0x0D, + 0x4D, 0x0E, 0xF6, 0x5D, 0x57, 0x72, 0xC5, 0x3B, 0x1C, 0x47, 0x56, 0x9D, + 0xE2, 0xD5, 0xFB, 0x81, 0x61, 0x8C, 0xCC, 0x4D, 0x80, 0x90, 0x34, 0x5B, + 0xB7, 0xD7, 0x14, 0x75, 0xDC, 0xD8, 0x04, 0x48, 0x9F, 0xC0, 0xC1, 0x28, + 0x88, 0xB4, 0xE9, 0x1C, 0xCA, 0xA7, 0xB1, 0xF1, 0x56, 0xB7, 0x7B, 0x49, + 0x4C, 0x59, 0xE5, 0x20, 0x15, 0xA8, 0x84, 0x02, 0x29, 0xFA, 0x38, 0x94, + 0x69, 0x9A, 0x49, 0x06, 0x8F, 0xCD, 0x1F, 0x79, 0x14, 0x17, 0x12, 0x0C, + 0x83, 0x7A, 0xDE, 0x1F, 0xB1, 0x97, 0xEE, 0xF9, 0x97, 0x78, 0x28, 0xA4, + 0xC8, 0x44, 0x92, 0xE9, 0x7D, 0x26, 0x05, 0xA6, 0x58, 0x72, 0x9B, 0x79, + 0x13, 0xD8, 0x11, 0x5F, 0xAE, 0xC5, 0x38, 0x62, 0x34, 0x68, 0xB2, 0x86, + 0x30, 0x8E, 0xF8, 0x90, 0x61, 0x9E, 0x32, 0x6C, 0xF5, 0x07, 0x36, 0xCD, + 0xA2, 0x4C, 0x6E, 0xEC, 0x8A, 0x36, 0xED, 0xF2, 0xE6, 0x99, 0x15, 0x44, + 0x70, 0xC3, 0x7C, 0xBC, 0x9C, 0x39, 0xC0, 0xB4, 0xE1, 0x6B, 0xF7, 0x83, + 0x25, 0x23, 0x57, 0xD9, 0x12, 0x80, 0xE5, 0x49, 0xF0, 0x75, 0x0F, 0xEF, + 0x8D, 0xEB, 0x1C, 0x9B, 0x54, 0x28, 0xB4, 0x21, 0x3C, 0xFC, 0x7C, 0x0A, + 0xFF, 0xEF, 0x7B, 0x6B, 0x75, 0xFF, 0x8B, 0x1D, 0xA0, 0x19, 0x05, 0xAB, + 0xFA, 0xF8, 0x2B, 0x81, 0x42, 0xE8, 0x38, 0xBA, 0xBB, 0xFB, 0xAA, 0xFD, + 0x3D, 0xE0, 0xF3, 0xCA, 0xDF, 0x4E, 0x97, 0x97, 0x29, 0xED, 0xF3, 0x18, + 0x56, 0xE9, 0xA5, 0x96, 0xAC, 0xBD, 0xC3, 0x90, 0x98, 0xB2, 0xE0, 0xF9, + 0xA2, 0xD4, 0xA6, 0x47, 0x43, 0x7C, 0x6D, 0xCF +}; + +static const unsigned char TA708_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA709_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA709_RSA_N[] = { + 0xAF, 0x35, 0x2E, 0xD8, 0xAC, 0x6C, 0x55, 0x69, 0x06, 0x71, 0xE5, 0x13, + 0x68, 0x24, 0xB3, 0x4F, 0xD8, 0xCC, 0x21, 0x47, 0xF8, 0xF1, 0x60, 0x38, + 0x89, 0x89, 0x03, 0xE9, 0xBD, 0xEA, 0x5E, 0x46, 0x53, 0x09, 0xDC, 0x5C, + 0xF5, 0x5A, 0xE8, 0xF7, 0x45, 0x2A, 0x02, 0xEB, 0x31, 0x61, 0xD7, 0x29, + 0x33, 0x4C, 0xCE, 0xC7, 0x7C, 0x0A, 0x37, 0x7E, 0x0F, 0xBA, 0x32, 0x98, + 0xE1, 0x1D, 0x97, 0xAF, 0x8F, 0xC7, 0xDC, 0xC9, 0x38, 0x96, 0xF3, 0xDB, + 0x1A, 0xFC, 0x51, 0xED, 0x68, 0xC6, 0xD0, 0x6E, 0xA4, 0x7C, 0x24, 0xD1, + 0xAE, 0x42, 0xC8, 0x96, 0x50, 0x63, 0x2E, 0xE0, 0xFE, 0x75, 0xFE, 0x98, + 0xA7, 0x5F, 0x49, 0x2E, 0x95, 0xE3, 0x39, 0x33, 0x64, 0x8E, 0x1E, 0xA4, + 0x5F, 0x90, 0xD2, 0x67, 0x3C, 0xB2, 0xD9, 0xFE, 0x41, 0xB9, 0x55, 0xA7, + 0x09, 0x8E, 0x72, 0x05, 0x1E, 0x8B, 0xDD, 0x44, 0x85, 0x82, 0x42, 0xD0, + 0x49, 0xC0, 0x1D, 0x60, 0xF0, 0xD1, 0x17, 0x2C, 0x95, 0xEB, 0xF6, 0xA5, + 0xC1, 0x92, 0xA3, 0xC5, 0xC2, 0xA7, 0x08, 0x60, 0x0D, 0x60, 0x04, 0x10, + 0x96, 0x79, 0x9E, 0x16, 0x34, 0xE6, 0xA9, 0xB6, 0xFA, 0x25, 0x45, 0x39, + 0xC8, 0x1E, 0x65, 0xF9, 0x93, 0xF5, 0xAA, 0xF1, 0x52, 0xDC, 0x99, 0x98, + 0x3D, 0xA5, 0x86, 0x1A, 0x0C, 0x35, 0x33, 0xFA, 0x4B, 0xA5, 0x04, 0x06, + 0x15, 0x1C, 0x31, 0x80, 0xEF, 0xAA, 0x18, 0x6B, 0xC2, 0x7B, 0xD7, 0xDA, + 0xCE, 0xF9, 0x33, 0x20, 0xD5, 0xF5, 0xBD, 0x6A, 0x33, 0x2D, 0x81, 0x04, + 0xFB, 0xB0, 0x5C, 0xD4, 0x9C, 0xA3, 0xE2, 0x5C, 0x1D, 0xE3, 0xA9, 0x42, + 0x75, 0x5E, 0x7B, 0xD4, 0x77, 0xEF, 0x39, 0x54, 0xBA, 0xC9, 0x0A, 0x18, + 0x1B, 0x12, 0x99, 0x49, 0x2F, 0x88, 0x4B, 0xFD, 0x50, 0x62, 0xD1, 0x73, + 0xE7, 0x8F, 0x7A, 0x43 +}; + +static const unsigned char TA709_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA710_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x32 +}; + +static const unsigned char TA710_RSA_N[] = { + 0xBA, 0x39, 0xC1, 0x37, 0x7A, 0x68, 0x45, 0x2B, 0x14, 0xB4, 0xEB, 0xE4, + 0x13, 0xEB, 0x57, 0x75, 0x23, 0x4D, 0x8F, 0x24, 0x2D, 0x16, 0xE8, 0xAE, + 0x8E, 0xC9, 0x7D, 0xA4, 0x57, 0x3B, 0x2A, 0x76, 0x25, 0x33, 0x83, 0x6C, + 0xEA, 0x32, 0x8A, 0x94, 0x9B, 0x4E, 0x3C, 0x96, 0xE4, 0xFD, 0x51, 0xBF, + 0x99, 0xC9, 0x93, 0x7E, 0xBF, 0xF9, 0xAD, 0xA7, 0xB2, 0x48, 0x2B, 0x07, + 0x1C, 0x27, 0xF5, 0x4C, 0xBC, 0x70, 0x12, 0x77, 0xA4, 0x85, 0x54, 0xB5, + 0xFD, 0x90, 0x7A, 0xE4, 0xA3, 0xE4, 0x51, 0x58, 0x03, 0xCD, 0x10, 0x79, + 0x79, 0xEE, 0x6B, 0x93, 0x1F, 0x64, 0x8E, 0x6B, 0x64, 0xAB, 0xA3, 0x13, + 0xE3, 0x71, 0xFE, 0x7D, 0xAB, 0x9C, 0xDD, 0x27, 0x53, 0x37, 0xB3, 0xAA, + 0x18, 0xC2, 0x59, 0x26, 0xEC, 0x5B, 0x1F, 0xD2, 0xE6, 0x65, 0x7C, 0xEF, + 0x93, 0xBD, 0xD8, 0x58, 0x5C, 0x0B, 0xC0, 0xE3, 0x65, 0x6F, 0x3C, 0xC7, + 0xCA, 0x59, 0xE3, 0xFE, 0x6E, 0x5F, 0xAC, 0x83, 0xBE, 0xFD, 0x5D, 0x25, + 0x4E, 0x2A, 0x29, 0x3B, 0xD6, 0x0B, 0xAB, 0x17, 0x32, 0x78, 0xA4, 0xE1, + 0x3E, 0x94, 0x46, 0xBE, 0x62, 0x6E, 0x9B, 0xDE, 0x46, 0xA8, 0xB1, 0x16, + 0xE7, 0x85, 0x6E, 0xF4, 0x08, 0x40, 0x45, 0x11, 0xA0, 0x9E, 0x54, 0x44, + 0x84, 0xF7, 0xD8, 0x36, 0xCE, 0xF5, 0x50, 0x47, 0xDC, 0x2C, 0x30, 0x9B, + 0xEE, 0xC0, 0xF5, 0x96, 0xD2, 0xFE, 0x09, 0x86, 0xC7, 0x06, 0x59, 0xAE, + 0x4F, 0xAE, 0x8E, 0x11, 0x98, 0x7B, 0xF3, 0x0B, 0x52, 0xAA, 0x62, 0x26, + 0xAA, 0x21, 0xDF, 0x8E, 0x25, 0x33, 0x79, 0x97, 0x16, 0x49, 0x8D, 0xF5, + 0x3E, 0xD5, 0x47, 0x9F, 0x37, 0x31, 0x49, 0x33, 0x72, 0x05, 0x4D, 0x0C, + 0xB6, 0x55, 0x8C, 0xF1, 0x57, 0x8F, 0x8A, 0x87, 0xD1, 0xAD, 0xC5, 0x11, + 0x12, 0x39, 0xA0, 0xAD +}; + +static const unsigned char TA710_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA711_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x34 +}; + +static const unsigned char TA711_RSA_N[] = { + 0xC5, 0xD2, 0x7A, 0xA1, 0xD6, 0x8A, 0xBF, 0x16, 0x31, 0xD0, 0x98, 0xD1, + 0x3A, 0x94, 0xFC, 0x5A, 0xB8, 0x6E, 0x22, 0xC1, 0x62, 0xF7, 0xA7, 0x0A, + 0x27, 0xEF, 0x50, 0xF6, 0x2E, 0xB1, 0x9E, 0x68, 0x12, 0xF0, 0x6C, 0x24, + 0x63, 0x39, 0xF1, 0xF0, 0xDF, 0x10, 0xC6, 0xDE, 0xB7, 0x52, 0x20, 0xD5, + 0x52, 0x5B, 0x42, 0x99, 0x9E, 0xF3, 0xA0, 0xBE, 0x52, 0x1F, 0x5F, 0xCC, + 0x67, 0x6D, 0xA7, 0x2E, 0x50, 0xA2, 0xC1, 0x97, 0x8D, 0xB6, 0xF8, 0x95, + 0xF5, 0xB0, 0xBA, 0xDC, 0x9D, 0xE0, 0xBE, 0xCB, 0xDF, 0xF7, 0x38, 0xF2, + 0x47, 0xF5, 0xA6, 0x9A, 0x92, 0x95, 0x2A, 0x62, 0x59, 0x50, 0x0B, 0xA2, + 0xB1, 0x35, 0xE7, 0x65, 0xB2, 0x61, 0xB2, 0xEA, 0x92, 0x71, 0x69, 0xE4, + 0x29, 0xF0, 0x4F, 0x81, 0x81, 0x04, 0x3C, 0xB2, 0xA5, 0x5B, 0xD4, 0xC5, + 0xA8, 0x59, 0x67, 0x7B, 0x55, 0x1C, 0x49, 0xAB, 0x7A, 0x9D, 0xC2, 0xE7, + 0x73, 0x4D, 0xEF, 0xCD, 0x09, 0xC2, 0xC4, 0x57, 0x12, 0xDB, 0x01, 0x0E, + 0x23, 0x79, 0x09, 0x07, 0x3B, 0xA2, 0xE8, 0xFC, 0x8A, 0xCF, 0x8F, 0xC0, + 0x46, 0x24, 0x9C, 0x38, 0x27, 0xE0, 0x83, 0x9D, 0x1B, 0xA0, 0xBF, 0x78, + 0x15, 0x10, 0xEB, 0x86, 0x4E, 0x0A, 0x5A, 0xFD, 0xDF, 0xDA, 0x2C, 0x82, + 0x7E, 0xEE, 0xCA, 0xF6, 0x29, 0xE1, 0xFA, 0x71, 0xA1, 0xF7, 0x88, 0x68, + 0x9C, 0x9C, 0xF0, 0x8D, 0xBE, 0x0F, 0x49, 0x91, 0xD8, 0xEA, 0x3A, 0xF9, + 0xFD, 0xD0, 0x68, 0x71, 0xDB, 0xE9, 0xB5, 0x2B, 0x4E, 0x82, 0x92, 0x6F, + 0x66, 0x1F, 0xE0, 0xF0, 0xDC, 0x4C, 0xEC, 0xCA, 0xD1, 0xEA, 0xBA, 0x74, + 0x06, 0xF9, 0xB3, 0x84, 0x90, 0x94, 0xD1, 0x5F, 0x8E, 0x73, 0x19, 0x10, + 0x5D, 0x02, 0xE5, 0x70, 0xA5, 0xC0, 0x10, 0xD0, 0x10, 0x7C, 0x6F, 0xC5, + 0x58, 0x49, 0xB4, 0xB0, 0x6E, 0x9A, 0xDA, 0x7D, 0x95, 0xF5, 0xCC, 0xDA, + 0x02, 0xAF, 0xB8, 0x2C, 0x7D, 0x79, 0x8F, 0xBE, 0x43, 0xF1, 0xF9, 0x28, + 0x28, 0x8D, 0x09, 0x43, 0xF8, 0x08, 0xDD, 0x6B, 0xC8, 0x8B, 0x2C, 0x24, + 0xB1, 0x8D, 0x52, 0x07, 0xBD, 0x78, 0x9B, 0xCB, 0xCA, 0x68, 0xB2, 0xA4, + 0xDD, 0x0C, 0x4C, 0x79, 0x60, 0xC6, 0x99, 0xD1, 0x93, 0xF1, 0x30, 0x1A, + 0x07, 0xD3, 0xAE, 0x22, 0xC2, 0xEA, 0xCE, 0xF1, 0x84, 0x09, 0xCC, 0xE0, + 0x14, 0x6E, 0x7F, 0x3F, 0x7E, 0xD2, 0x82, 0x85, 0xAC, 0xDC, 0xA9, 0x16, + 0x4E, 0x85, 0xA0, 0x60, 0xCB, 0xF6, 0x9C, 0xD7, 0xC8, 0xB3, 0x8E, 0xED, + 0xC6, 0x9B, 0x98, 0x75, 0x0D, 0x55, 0xE8, 0x5F, 0xE5, 0x95, 0x8B, 0x02, + 0xA4, 0xAE, 0x43, 0x29, 0x28, 0x11, 0xA4, 0xE6, 0x12, 0x30, 0x01, 0x4B, + 0x75, 0x6B, 0x1E, 0x66, 0x9D, 0x79, 0x2F, 0xA5, 0x76, 0x2F, 0x1D, 0x40, + 0xB4, 0x6D, 0xC9, 0x7D, 0x79, 0x08, 0xEC, 0xD1, 0x6A, 0xB6, 0x5D, 0x2A, + 0xB2, 0xA5, 0x66, 0xBD, 0x6B, 0x85, 0xF4, 0x74, 0x56, 0xC3, 0xF5, 0xE7, + 0x75, 0x52, 0x28, 0x2C, 0xA5, 0xFF, 0x66, 0x47, 0xA5, 0xD4, 0xFE, 0xFE, + 0x9E, 0x54, 0xBF, 0x65, 0x7E, 0x01, 0xD6, 0x30, 0x8F, 0xA5, 0x36, 0x9C, + 0xA2, 0x50, 0x1C, 0xEE, 0x38, 0x80, 0x01, 0x48, 0xC6, 0xC7, 0x74, 0xF4, + 0xC6, 0xAC, 0xC3, 0x40, 0x49, 0x16, 0x61, 0x74, 0x2C, 0xAF, 0x8C, 0x6F, + 0x35, 0xED, 0x7B, 0x18, 0x00, 0x5B, 0x36, 0x3C, 0x9C, 0x50, 0x0D, 0xCA, + 0x92, 0x33, 0x10, 0xF1, 0x26, 0x49, 0x6D, 0xDF, 0x75, 0x24, 0x37, 0x82, + 0x22, 0xD7, 0xE8, 0x96, 0xFD, 0x15, 0x4B, 0x02, 0x96, 0x3E, 0x07, 0x72, + 0x95, 0x7E, 0xAB, 0x3D, 0x4C, 0x2E, 0xD7, 0xCA, 0xF0, 0xDF, 0xE0, 0x58, + 0x3F, 0x2D, 0x2F, 0x04, 0x9A, 0x38, 0xA3, 0x01 +}; + +static const unsigned char TA711_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA712_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x35 +}; + +static const unsigned char TA712_EC_Q[] = { + 0x04, 0x0B, 0x50, 0x74, 0x8D, 0x64, 0x32, 0x99, 0x99, 0xB3, 0xD2, 0x60, + 0x08, 0xB8, 0x22, 0x8E, 0x46, 0x74, 0x2C, 0x78, 0xC0, 0x2B, 0x44, 0x2D, + 0x6D, 0x5F, 0x1D, 0xC9, 0xAE, 0x4B, 0x52, 0x20, 0x83, 0x3D, 0xB8, 0x14, + 0x6D, 0x53, 0x87, 0x60, 0x9E, 0x5F, 0x6C, 0x85, 0xDB, 0x06, 0x14, 0x95, + 0xE0, 0xC7, 0x28, 0xFF, 0x9D, 0x5F, 0xE4, 0xAA, 0xF1, 0xB3, 0x8B, 0x6D, + 0xED, 0x4F, 0x2F, 0x4B, 0xC9, 0x4A, 0x94, 0x91, 0x64, 0x75, 0xFE, 0x01, + 0xEC, 0xC1, 0xD8, 0xEB, 0x7A, 0x94, 0x78, 0x56, 0x18, 0x43, 0x5F, 0x6B, + 0x81, 0xCB, 0xF6, 0xBC, 0xDA, 0xB4, 0x0C, 0xB6, 0x29, 0x93, 0x08, 0x69, + 0x8F +}; + +static const unsigned char TA713_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0E, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA713_RSA_N[] = { + 0xAB, 0xA4, 0x81, 0xE5, 0x95, 0xCD, 0xF5, 0xF6, 0x14, 0x8E, 0xC2, 0x4F, + 0xCA, 0xD4, 0xE2, 0x78, 0x95, 0x58, 0x9C, 0x41, 0xE1, 0x0D, 0x99, 0x40, + 0x24, 0x17, 0x39, 0x91, 0x33, 0x66, 0xE9, 0xBE, 0xE1, 0x83, 0xAF, 0x62, + 0x5C, 0x89, 0xD1, 0xFC, 0x24, 0x5B, 0x61, 0xB3, 0xE0, 0x11, 0x11, 0x41, + 0x1C, 0x1D, 0x6E, 0xF0, 0xB8, 0xBB, 0xF8, 0xDE, 0xA7, 0x81, 0xBA, 0xA6, + 0x48, 0xC6, 0x9F, 0x1D, 0xBD, 0xBE, 0x8E, 0xA9, 0x41, 0x3E, 0xB8, 0x94, + 0xED, 0x29, 0x1A, 0xD4, 0x8E, 0xD2, 0x03, 0x1D, 0x03, 0xEF, 0x6D, 0x0D, + 0x67, 0x1C, 0x57, 0xD7, 0x06, 0xAD, 0xCA, 0xC8, 0xF5, 0xFE, 0x0E, 0xAF, + 0x66, 0x25, 0x48, 0x04, 0x96, 0x0B, 0x5D, 0xA3, 0xBA, 0x16, 0xC3, 0x08, + 0x4F, 0xD1, 0x46, 0xF8, 0x14, 0x5C, 0xF2, 0xC8, 0x5E, 0x01, 0x99, 0x6D, + 0xFD, 0x88, 0xCC, 0x86, 0xA8, 0xC1, 0x6F, 0x31, 0x42, 0x6C, 0x52, 0x3E, + 0x68, 0xCB, 0xF3, 0x19, 0x34, 0xDF, 0xBB, 0x87, 0x18, 0x56, 0x80, 0x26, + 0xC4, 0xD0, 0xDC, 0xC0, 0x6F, 0xDF, 0xDE, 0xA0, 0xC2, 0x91, 0x16, 0xA0, + 0x64, 0x11, 0x4B, 0x44, 0xBC, 0x1E, 0xF6, 0xE7, 0xFA, 0x63, 0xDE, 0x66, + 0xAC, 0x76, 0xA4, 0x71, 0xA3, 0xEC, 0x36, 0x94, 0x68, 0x7A, 0x77, 0xA4, + 0xB1, 0xE7, 0x0E, 0x2F, 0x81, 0x7A, 0xE2, 0xB5, 0x72, 0x86, 0xEF, 0xA2, + 0x6B, 0x8B, 0xF0, 0x0F, 0xDB, 0xD3, 0x59, 0x3F, 0xBA, 0x72, 0xBC, 0x44, + 0x24, 0x9C, 0xE3, 0x73, 0xB3, 0xF7, 0xAF, 0x57, 0x2F, 0x42, 0x26, 0x9D, + 0xA9, 0x74, 0xBA, 0x00, 0x52, 0xF2, 0x4B, 0xCD, 0x53, 0x7C, 0x47, 0x0B, + 0x36, 0x85, 0x0E, 0x66, 0xA9, 0x08, 0x97, 0x16, 0x34, 0x57, 0xC1, 0x66, + 0xF7, 0x80, 0xE3, 0xED, 0x70, 0x54, 0xC7, 0x93, 0xE0, 0x2E, 0x28, 0x15, + 0x59, 0x87, 0xBA, 0xBB +}; + +static const unsigned char TA713_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA714_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x43, 0x41, 0x31 +}; + +static const unsigned char TA714_EC_Q[] = { + 0x04, 0xA4, 0xA5, 0x6F, 0x60, 0x03, 0x03, 0xC3, 0xBD, 0x31, 0xF4, 0xD3, + 0x17, 0x9C, 0x2B, 0x84, 0x75, 0xAC, 0xE5, 0xFD, 0x3D, 0x57, 0x6E, 0xD7, + 0x63, 0xBF, 0xE6, 0x04, 0x89, 0x92, 0x8E, 0x81, 0x9C, 0xE3, 0xE9, 0x47, + 0x6E, 0xCA, 0x90, 0x12, 0xC8, 0x13, 0xE0, 0xA7, 0x9D, 0xF7, 0x65, 0x74, + 0x1F, 0x6C, 0x10, 0xB2, 0xE8, 0xE4, 0xE9, 0xEF, 0x6D, 0x85, 0x32, 0x99, + 0x44, 0xB1, 0x5E, 0xFD, 0xCC, 0x76, 0x10, 0xD8, 0x5B, 0xBD, 0xA2, 0xC6, + 0xF9, 0xD6, 0x42, 0xE4, 0x57, 0x76, 0xDC, 0x90, 0xC2, 0x35, 0xA9, 0x4B, + 0x88, 0x3C, 0x12, 0x47, 0x6D, 0x5C, 0xFF, 0x49, 0x4F, 0x1A, 0x4A, 0x50, + 0xB1 +}; + +static const unsigned char TA715_DN[] = { + 0x30, 0x5D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x1E, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA715_RSA_N[] = { + 0xD0, 0x15, 0x39, 0x52, 0xB1, 0x52, 0xB3, 0xBA, 0xC5, 0x59, 0x82, 0xC4, + 0x5D, 0x52, 0xAE, 0x3A, 0x43, 0x65, 0x80, 0x4B, 0xC7, 0xF2, 0x96, 0xBC, + 0xDB, 0x36, 0x97, 0xD6, 0xA6, 0x64, 0x8C, 0xA8, 0x5E, 0xF0, 0xE3, 0x0A, + 0x1C, 0xF7, 0xDF, 0x97, 0x3D, 0x4B, 0xAE, 0xF6, 0x5D, 0xEC, 0x21, 0xB5, + 0x41, 0xAB, 0xCD, 0xB9, 0x7E, 0x76, 0x9F, 0xBE, 0xF9, 0x3E, 0x36, 0x34, + 0xA0, 0x3B, 0xC1, 0xF6, 0x31, 0x11, 0x45, 0x74, 0x93, 0x3D, 0x57, 0x80, + 0xC5, 0xF9, 0x89, 0x99, 0xCA, 0xE5, 0xAB, 0x6A, 0xD4, 0xB5, 0xDA, 0x41, + 0x90, 0x10, 0xC1, 0xD6, 0xD6, 0x42, 0x89, 0xC2, 0xBF, 0xF4, 0x38, 0x12, + 0x95, 0x4C, 0x54, 0x05, 0xF7, 0x36, 0xE4, 0x45, 0x83, 0x7B, 0x14, 0x65, + 0xD6, 0xDC, 0x0C, 0x4D, 0xD1, 0xDE, 0x7E, 0x0C, 0xAB, 0x3B, 0xC4, 0x15, + 0xBE, 0x3A, 0x56, 0xA6, 0x5A, 0x6F, 0x76, 0x69, 0x52, 0xA9, 0x7A, 0xB9, + 0xC8, 0xEB, 0x6A, 0x9A, 0x5D, 0x52, 0xD0, 0x2D, 0x0A, 0x6B, 0x35, 0x16, + 0x09, 0x10, 0x84, 0xD0, 0x6A, 0xCA, 0x3A, 0x06, 0x00, 0x37, 0x47, 0xE4, + 0x7E, 0x57, 0x4F, 0x3F, 0x8B, 0xEB, 0x67, 0xB8, 0x88, 0xAA, 0xC5, 0xBE, + 0x53, 0x55, 0xB2, 0x91, 0xC4, 0x7D, 0xB9, 0xB0, 0x85, 0x19, 0x06, 0x78, + 0x2E, 0xDB, 0x61, 0x1A, 0xFA, 0x85, 0xF5, 0x4A, 0x91, 0xA1, 0xE7, 0x16, + 0xD5, 0x8E, 0xA2, 0x39, 0xDF, 0x94, 0xB8, 0x70, 0x1F, 0x28, 0x3F, 0x8B, + 0xFC, 0x40, 0x5E, 0x63, 0x83, 0x3C, 0x83, 0x2A, 0x1A, 0x99, 0x6B, 0xCF, + 0xDE, 0x59, 0x6A, 0x3B, 0xFC, 0x6F, 0x16, 0xD7, 0x1F, 0xFD, 0x4A, 0x10, + 0xEB, 0x4E, 0x82, 0x16, 0x3A, 0xAC, 0x27, 0x0C, 0x53, 0xF1, 0xAD, 0xD5, + 0x24, 0xB0, 0x6B, 0x03, 0x50, 0xC1, 0x2D, 0x3C, 0x16, 0xDD, 0x44, 0x34, + 0x27, 0x1A, 0x75, 0xFB +}; + +static const unsigned char TA715_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA716_DN[] = { + 0x30, 0x7F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x2B, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, 0x56, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA716_EC_Q[] = { + 0x04, 0xAA, 0x12, 0x47, 0x90, 0x98, 0x1B, 0xFB, 0xEF, 0xC3, 0x40, 0x07, + 0x83, 0x20, 0x4E, 0xF1, 0x30, 0x82, 0xA2, 0x06, 0xD1, 0xF2, 0x92, 0x86, + 0x61, 0xF2, 0xF6, 0x21, 0x68, 0xCA, 0x00, 0xC4, 0xC7, 0xEA, 0x43, 0x00, + 0x54, 0x86, 0xDC, 0xFD, 0x1F, 0xDF, 0x00, 0xB8, 0x41, 0x62, 0x5C, 0xDC, + 0x70, 0x16, 0x32, 0xDE, 0x1F, 0x99, 0xD4, 0xCC, 0xC5, 0x07, 0xC8, 0x08, + 0x1F, 0x61, 0x16, 0x07, 0x51, 0x3D, 0x7D, 0x5C, 0x07, 0x53, 0xE3, 0x35, + 0x38, 0x8C, 0xDF, 0xCD, 0x9F, 0xD9, 0x2E, 0x0D, 0x4A, 0xB6, 0x19, 0x2E, + 0x5A, 0x70, 0x5A, 0x06, 0xED, 0xBE, 0xF0, 0xA1, 0xB0, 0xCA, 0xD0, 0x09, + 0x29 +}; + +static const unsigned char TA717_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, + 0x6F, 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x2E, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, + 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA717_RSA_N[] = { + 0x8F, 0x36, 0x65, 0x40, 0xE1, 0xD6, 0x4D, 0xC0, 0xD7, 0xB4, 0xE9, 0x46, + 0xDA, 0x6B, 0xEA, 0x33, 0x47, 0xCD, 0x4C, 0xF9, 0x7D, 0x7D, 0xBE, 0xBD, + 0x2D, 0x3D, 0xF0, 0xDB, 0x78, 0xE1, 0x86, 0xA5, 0xD9, 0xBA, 0x09, 0x57, + 0x68, 0xED, 0x57, 0x3E, 0xA0, 0xD0, 0x08, 0x41, 0x83, 0xE7, 0x28, 0x41, + 0x24, 0x1F, 0xE3, 0x72, 0x15, 0xD0, 0x01, 0x1A, 0xFB, 0x5E, 0x70, 0x23, + 0xB2, 0xCB, 0x9F, 0x39, 0xE3, 0xCF, 0xC5, 0x4E, 0xC6, 0x92, 0x6D, 0x26, + 0xC6, 0x7B, 0xBB, 0xB3, 0xDA, 0x27, 0x9D, 0x0A, 0x86, 0xE9, 0x81, 0x37, + 0x05, 0xFE, 0xF0, 0x71, 0x71, 0xEC, 0xC3, 0x1C, 0xE9, 0x63, 0xA2, 0x17, + 0x14, 0x9D, 0xEF, 0x1B, 0x67, 0xD3, 0x85, 0x55, 0x02, 0x02, 0xD6, 0x49, + 0xC9, 0xCC, 0x5A, 0xE1, 0xB1, 0xF7, 0x6F, 0x32, 0x9F, 0xC9, 0xD4, 0x3B, + 0x88, 0x41, 0xA8, 0x9C, 0xBD, 0xCB, 0xAB, 0xDB, 0x6D, 0x7B, 0x09, 0x1F, + 0xA2, 0x4C, 0x72, 0x90, 0xDA, 0x2B, 0x08, 0xFC, 0xCF, 0x3C, 0x54, 0xCE, + 0x67, 0x0F, 0xA8, 0xCF, 0x5D, 0x96, 0x19, 0x0B, 0xC4, 0xE3, 0x72, 0xEB, + 0xAD, 0xD1, 0x7D, 0x1D, 0x27, 0xEF, 0x92, 0xEB, 0x10, 0xBF, 0x5B, 0xEB, + 0x3B, 0xAF, 0xCF, 0x80, 0xDD, 0xC1, 0xD2, 0x96, 0x04, 0x5B, 0x7A, 0x7E, + 0xA4, 0xA9, 0x3C, 0x38, 0x76, 0xA4, 0x62, 0x8E, 0xA0, 0x39, 0x5E, 0xEA, + 0x77, 0xCF, 0x5D, 0x00, 0x59, 0x8F, 0x66, 0x2C, 0x3E, 0x07, 0xA2, 0xA3, + 0x05, 0x26, 0x11, 0x69, 0x97, 0xEA, 0x85, 0xB7, 0x0F, 0x96, 0x0B, 0x4B, + 0xC8, 0x40, 0xE1, 0x50, 0xBA, 0x2E, 0x8A, 0xCB, 0xF7, 0x0F, 0x9A, 0x22, + 0xE7, 0x7F, 0x9A, 0x37, 0x13, 0xCD, 0xF2, 0x4D, 0x13, 0x6B, 0x21, 0xD1, + 0xC0, 0xCC, 0x22, 0xF2, 0xA1, 0x46, 0xF6, 0x44, 0x69, 0x9C, 0xCA, 0x61, + 0x35, 0x07, 0x00, 0x6F, 0xD6, 0x61, 0x08, 0x11, 0xEA, 0xBA, 0xB8, 0xF6, + 0xE9, 0xB3, 0x60, 0xE5, 0x4D, 0xB9, 0xEC, 0x9F, 0x14, 0x66, 0xC9, 0x57, + 0x58, 0xDB, 0xCD, 0x87, 0x69, 0xF8, 0x8A, 0x86, 0x12, 0x03, 0x47, 0xBF, + 0x66, 0x13, 0x76, 0xAC, 0x77, 0x7D, 0x34, 0x24, 0x85, 0x83, 0xCD, 0xD7, + 0xAA, 0x9C, 0x90, 0x1A, 0x9F, 0x21, 0x2C, 0x7F, 0x78, 0xB7, 0x64, 0xB8, + 0xD8, 0xE8, 0xA6, 0xF4, 0x78, 0xB3, 0x55, 0xCB, 0x84, 0xD2, 0x32, 0xC4, + 0x78, 0xAE, 0xA3, 0x8F, 0x61, 0xDD, 0xCE, 0x08, 0x53, 0xAD, 0xEC, 0x88, + 0xFC, 0x15, 0xE4, 0x9A, 0x0D, 0xE6, 0x9F, 0x1A, 0x77, 0xCE, 0x4C, 0x8F, + 0xB8, 0x14, 0x15, 0x3D, 0x62, 0x9C, 0x86, 0x38, 0x06, 0x00, 0x66, 0x12, + 0xE4, 0x59, 0x76, 0x5A, 0x53, 0xC0, 0x02, 0x98, 0xA2, 0x10, 0x2B, 0x68, + 0x44, 0x7B, 0x8E, 0x79, 0xCE, 0x33, 0x4A, 0x76, 0xAA, 0x5B, 0x81, 0x16, + 0x1B, 0xB5, 0x8A, 0xD8, 0xD0, 0x00, 0x7B, 0x5E, 0x62, 0xB4, 0x09, 0xD6, + 0x86, 0x63, 0x0E, 0xA6, 0x05, 0x95, 0x49, 0xBA, 0x28, 0x8B, 0x88, 0x93, + 0xB2, 0x34, 0x1C, 0xD8, 0xA4, 0x55, 0x6E, 0xB7, 0x1C, 0xD0, 0xDE, 0x99, + 0x55, 0x3B, 0x23, 0xF4, 0x22, 0xE0, 0xF9, 0x29, 0x66, 0x26, 0xEC, 0x20, + 0x50, 0x77, 0xDB, 0x4A, 0x0B, 0x8F, 0xBE, 0xE5, 0x02, 0x60, 0x70, 0x41, + 0x5E, 0xD4, 0xAE, 0x50, 0x39, 0x22, 0x14, 0x26, 0xCB, 0xB2, 0x3B, 0x73, + 0x74, 0x55, 0x47, 0x07, 0x79, 0x81, 0x39, 0xA8, 0x30, 0x13, 0x44, 0xE5, + 0x04, 0x8A, 0xAE, 0x96, 0x13, 0x25, 0x42, 0x0F, 0xB9, 0x53, 0xC4, 0x9B, + 0xFC, 0xCD, 0xE4, 0x1C, 0xDE, 0x3C, 0xFA, 0xAB, 0xD6, 0x06, 0x4A, 0x1F, + 0x67, 0xA6, 0x98, 0x30, 0x1C, 0xDD, 0x2C, 0xDB, 0xDC, 0x18, 0x95, 0x57, + 0x66, 0xC6, 0xFF, 0x5C, 0x8B, 0x56, 0xF5, 0x77 +}; + +static const unsigned char TA717_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA718_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA718_EC_Q[] = { + 0x04, 0x45, 0x6E, 0xA9, 0x50, 0xC4, 0xA6, 0x23, 0x36, 0x9E, 0x5F, 0x28, + 0x8D, 0x17, 0xCB, 0x96, 0x22, 0x64, 0x3F, 0xDC, 0x7A, 0x8E, 0x1D, 0xCC, + 0x08, 0xB3, 0xA2, 0x71, 0x24, 0xBA, 0x8E, 0x49, 0xB9, 0x04, 0x1B, 0x47, + 0x96, 0x58, 0xAB, 0x2D, 0x95, 0xC8, 0xED, 0x9E, 0x08, 0x35, 0xC8, 0x27, + 0xEB, 0x89, 0x8C, 0x53, 0x58, 0xEB, 0x62, 0x8A, 0xFE, 0xF0, 0x5B, 0x0F, + 0x6B, 0x31, 0x52, 0x63, 0x41, 0x3B, 0x89, 0xCD, 0xEC, 0xEC, 0xB6, 0x8D, + 0x19, 0xD3, 0x34, 0x07, 0xDC, 0xBB, 0xC6, 0x06, 0x7F, 0xC2, 0x45, 0x95, + 0xEC, 0xCB, 0x7F, 0xA8, 0x23, 0xE0, 0x09, 0xE9, 0x81, 0xFA, 0xF3, 0x47, + 0xD3 +}; + +static const unsigned char TA719_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x52, 0x53, 0x41 +}; + +static const unsigned char TA719_RSA_N[] = { + 0xF9, 0x0F, 0xDD, 0xA3, 0x2B, 0x7D, 0xCB, 0xD0, 0x2A, 0xFE, 0xEC, 0x67, + 0x85, 0xA6, 0xE7, 0x2E, 0x1B, 0xBA, 0x77, 0xE1, 0xE3, 0xF5, 0xAF, 0xA4, + 0xEC, 0xFA, 0x4A, 0x5D, 0x91, 0xC4, 0x57, 0x47, 0x6B, 0x18, 0x77, 0x6B, + 0x76, 0xF2, 0xFD, 0x93, 0xE4, 0x3D, 0x0F, 0xC2, 0x16, 0x9E, 0x0B, 0x66, + 0xC3, 0x56, 0x94, 0x9E, 0x17, 0x83, 0x85, 0xCE, 0x56, 0xEF, 0xF2, 0x16, + 0xFD, 0x00, 0x62, 0xF5, 0x22, 0x09, 0x54, 0xE8, 0x65, 0x17, 0x4E, 0x41, + 0xB9, 0xE0, 0x4F, 0x46, 0x97, 0xAA, 0x1B, 0xC8, 0xB8, 0x6E, 0x62, 0x5E, + 0x69, 0xB1, 0x5F, 0xDB, 0x2A, 0x02, 0x7E, 0xFC, 0x6C, 0xCA, 0xF3, 0x41, + 0xD8, 0xED, 0xD0, 0xE8, 0xFC, 0x3F, 0x61, 0x48, 0xED, 0xB0, 0x03, 0x14, + 0x1D, 0x10, 0x0E, 0x4B, 0x19, 0xE0, 0xBB, 0x4E, 0xEC, 0x86, 0x65, 0xFF, + 0x36, 0xF3, 0x5E, 0x67, 0x02, 0x0B, 0x9D, 0x86, 0x55, 0x61, 0xFD, 0x7A, + 0x38, 0xED, 0xFE, 0xE2, 0x19, 0x00, 0xB7, 0x6F, 0xA1, 0x50, 0x62, 0x75, + 0x74, 0x3C, 0xA0, 0xFA, 0xC8, 0x25, 0x92, 0xB4, 0x6E, 0x7A, 0x22, 0xC7, + 0xF8, 0x1E, 0xA1, 0xE3, 0xB2, 0xDD, 0x91, 0x31, 0xAB, 0x2B, 0x1D, 0x04, + 0xFF, 0xA5, 0x4A, 0x04, 0x37, 0xE9, 0x85, 0xA4, 0x33, 0x2B, 0xFD, 0xE2, + 0xD6, 0x55, 0x34, 0x7C, 0x19, 0xA4, 0x4A, 0x68, 0xC7, 0xB2, 0xA8, 0xD3, + 0xB7, 0xCA, 0xA1, 0x93, 0x88, 0xEB, 0xC1, 0x97, 0xBC, 0x8C, 0xF9, 0x1D, + 0xD9, 0x22, 0x84, 0x24, 0x74, 0xC7, 0x04, 0x3D, 0x6A, 0xA9, 0x29, 0x93, + 0xCC, 0xEB, 0xB8, 0x5B, 0xE1, 0xFE, 0x5F, 0x25, 0xAA, 0x34, 0x58, 0xC8, + 0xC1, 0x23, 0x54, 0x9D, 0x1B, 0x98, 0x11, 0xC3, 0x38, 0x9C, 0x7E, 0x3D, + 0x86, 0x6C, 0xA5, 0x0F, 0x40, 0x86, 0x7C, 0x02, 0xF4, 0x5C, 0x02, 0x4F, + 0x28, 0xCB, 0xAE, 0x71, 0x9F, 0x0F, 0x3A, 0xC8, 0x33, 0xFE, 0x11, 0x25, + 0x35, 0xEA, 0xFC, 0xBA, 0xC5, 0x60, 0x3D, 0xD9, 0x7C, 0x18, 0xD5, 0xB2, + 0xA9, 0xD3, 0x75, 0x78, 0x03, 0x72, 0x22, 0xCA, 0x3A, 0xC3, 0x1F, 0xEF, + 0x2C, 0xE5, 0x2E, 0xA9, 0xFA, 0x9E, 0x2C, 0xB6, 0x51, 0x46, 0xFD, 0xAF, + 0x03, 0xD6, 0xEA, 0x60, 0x68, 0xEA, 0x85, 0x16, 0x36, 0x6B, 0x85, 0xE9, + 0x1E, 0xC0, 0xB3, 0xDD, 0xC4, 0x24, 0xDC, 0x80, 0x2A, 0x81, 0x41, 0x6D, + 0x94, 0x3E, 0xC8, 0xE0, 0xC9, 0x81, 0x41, 0x00, 0x9E, 0x5E, 0xBF, 0x7F, + 0xC5, 0x08, 0x98, 0xA2, 0x18, 0x2C, 0x42, 0x40, 0xB3, 0xF9, 0x6F, 0x38, + 0x27, 0x4B, 0x4E, 0x80, 0xF4, 0x3D, 0x81, 0x47, 0xE0, 0x88, 0x7C, 0xEA, + 0x1C, 0xCE, 0xB5, 0x75, 0x5C, 0x51, 0x2E, 0x1C, 0x2B, 0x7F, 0x1A, 0x72, + 0x28, 0xE7, 0x00, 0xB5, 0xD1, 0x74, 0xC6, 0xD7, 0xE4, 0x9F, 0xAD, 0x07, + 0x93, 0xB6, 0x53, 0x35, 0x35, 0xFC, 0x37, 0xE4, 0xC3, 0xF6, 0x5D, 0x16, + 0xBE, 0x21, 0x73, 0xDE, 0x92, 0x0A, 0xF8, 0xA0, 0x63, 0x6A, 0xBC, 0x96, + 0x92, 0x6A, 0x3E, 0xF8, 0xBC, 0x65, 0x55, 0x9B, 0xDE, 0xF5, 0x0D, 0x89, + 0x26, 0x04, 0xFC, 0x25, 0x1A, 0xA6, 0x25, 0x69, 0xCB, 0xC2, 0x6D, 0xCA, + 0x7C, 0xE2, 0x59, 0x5F, 0x97, 0xAC, 0xEB, 0xEF, 0x2E, 0xC8, 0xBC, 0xD7, + 0x1B, 0x59, 0x3C, 0x2B, 0xCC, 0xF2, 0x19, 0xC8, 0x93, 0x6B, 0x27, 0x63, + 0x19, 0xCF, 0xFC, 0xE9, 0x26, 0xF8, 0xCA, 0x71, 0x9B, 0x7F, 0x93, 0xFE, + 0x34, 0x67, 0x84, 0x4E, 0x99, 0xEB, 0xFC, 0xB3, 0x78, 0x09, 0x33, 0x70, + 0xBA, 0x66, 0xA6, 0x76, 0xED, 0x1B, 0x73, 0xEB, 0x1A, 0xA5, 0x0D, 0xC4, + 0x22, 0x13, 0x20, 0x94, 0x56, 0x0A, 0x4E, 0x2C, 0x6C, 0x4E, 0xB1, 0xFD, + 0xCF, 0x9C, 0x09, 0xBA, 0xA2, 0x33, 0xED, 0x87 +}; + +static const unsigned char TA719_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA720_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA720_EC_Q[] = { + 0x04, 0x45, 0x29, 0x35, 0x73, 0xFA, 0xC2, 0xB8, 0x23, 0xCE, 0x14, 0x7D, + 0xA8, 0xB1, 0x4D, 0xA0, 0x5B, 0x36, 0xEE, 0x2A, 0x2C, 0x53, 0xC3, 0x60, + 0x09, 0x35, 0xB2, 0x24, 0x66, 0x26, 0x69, 0xC0, 0xB3, 0x95, 0xD6, 0x5D, + 0x92, 0x40, 0x19, 0x0E, 0xC6, 0xA5, 0x13, 0x70, 0xF4, 0xEF, 0x12, 0x51, + 0x28, 0x5D, 0xE7, 0xCC, 0xBD, 0xF9, 0x3C, 0x85, 0xC1, 0xCF, 0x94, 0x90, + 0xC9, 0x2B, 0xCE, 0x92, 0x42, 0x58, 0x59, 0x67, 0xFD, 0x94, 0x27, 0x10, + 0x64, 0x8C, 0x4F, 0x04, 0xB1, 0x4D, 0x49, 0xE4, 0x7B, 0x4F, 0x9B, 0xF5, + 0xE7, 0x08, 0xF8, 0x03, 0x88, 0xF7, 0xA7, 0xC3, 0x92, 0x4B, 0x19, 0x54, + 0x81 +}; + +static const unsigned char TA721_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA721_RSA_N[] = { + 0xD0, 0xA4, 0x09, 0x72, 0x4F, 0x40, 0x88, 0x12, 0x61, 0x3E, 0x35, 0x23, + 0x9E, 0xEE, 0xF6, 0x74, 0xCF, 0x2F, 0x7B, 0x58, 0x3D, 0xCE, 0x3C, 0x0D, + 0x10, 0x28, 0x90, 0x2F, 0x97, 0xF7, 0x8C, 0x48, 0xD8, 0xA0, 0xD8, 0x25, + 0xB1, 0x4C, 0xB0, 0x11, 0x4C, 0x17, 0x73, 0x50, 0xD0, 0x22, 0x4A, 0x63, + 0xBB, 0x81, 0xD3, 0x29, 0x6E, 0xD5, 0xB5, 0x09, 0x3E, 0x26, 0x18, 0x7F, + 0xB2, 0x12, 0x7F, 0x93, 0x98, 0xB7, 0xAF, 0xF0, 0x36, 0xBF, 0xF2, 0xEE, + 0x18, 0x9E, 0x9C, 0x3B, 0x52, 0xC5, 0x47, 0x19, 0x5D, 0x74, 0xF3, 0x64, + 0x66, 0xD5, 0x5D, 0xC7, 0x68, 0xB4, 0xBF, 0x1B, 0x1C, 0x06, 0xA3, 0xBC, + 0x8F, 0x40, 0x23, 0xB6, 0x1E, 0xC6, 0x84, 0xBD, 0x51, 0xC4, 0x1B, 0x39, + 0xC1, 0x95, 0xD2, 0x29, 0xEC, 0x4B, 0xAE, 0x7B, 0x2D, 0xBF, 0x39, 0xFD, + 0xB4, 0x62, 0xDE, 0x96, 0x7B, 0x41, 0xC6, 0x9C, 0xA0, 0xE0, 0x06, 0x72, + 0xFB, 0xF0, 0x07, 0x97, 0x09, 0x39, 0x81, 0x74, 0xAF, 0xF7, 0x34, 0x59, + 0x11, 0x57, 0x0A, 0xC2, 0x5B, 0xC1, 0x24, 0xF4, 0x31, 0x73, 0x30, 0x82, + 0xC6, 0x9D, 0xBA, 0x02, 0xF7, 0x3E, 0x7C, 0x44, 0x5F, 0x83, 0x0D, 0xF3, + 0xF1, 0xDD, 0x20, 0x69, 0x16, 0x09, 0x50, 0xE2, 0xD4, 0x55, 0xB6, 0xE0, + 0x80, 0x72, 0x76, 0x6E, 0x4C, 0x47, 0xB7, 0x75, 0x55, 0x59, 0xB4, 0x53, + 0x74, 0xD9, 0x94, 0xC6, 0x41, 0xAD, 0x58, 0x8A, 0x31, 0x66, 0x0F, 0x1E, + 0xA2, 0x1B, 0x29, 0x40, 0x4E, 0x2F, 0xDF, 0x7B, 0xE6, 0x16, 0x2C, 0x2D, + 0xFC, 0xBF, 0xEC, 0xF3, 0xB4, 0xFA, 0xBE, 0x18, 0xF6, 0x9B, 0x49, 0xD4, + 0xEE, 0x05, 0x6E, 0xD9, 0x34, 0xF3, 0x9C, 0xF1, 0xEC, 0x01, 0x8B, 0xD1, + 0x20, 0xC6, 0x0F, 0xA0, 0xB5, 0xBC, 0x17, 0x4E, 0x48, 0x7B, 0x51, 0xC2, + 0xFC, 0xE9, 0x5C, 0x69, 0x37, 0x47, 0x66, 0xB3, 0x68, 0xF8, 0x15, 0x28, + 0xF0, 0xB9, 0xD3, 0xA4, 0x15, 0xCC, 0x5A, 0x4F, 0xBA, 0x52, 0x70, 0xA3, + 0x12, 0x45, 0xDD, 0xC6, 0xBA, 0x4E, 0xFB, 0xC2, 0xD0, 0xF7, 0xA8, 0x52, + 0x27, 0x6D, 0x6E, 0x79, 0xB5, 0x8C, 0xFC, 0x7B, 0x8C, 0xC1, 0x16, 0x4C, + 0xEE, 0x80, 0x7F, 0xBE, 0xF0, 0x76, 0xBE, 0x41, 0x53, 0x12, 0x33, 0xAE, + 0x5A, 0x38, 0x42, 0xAB, 0xD7, 0x0F, 0x3E, 0x41, 0x8D, 0x76, 0x07, 0x32, + 0xD5, 0xAB, 0x89, 0xF6, 0x4E, 0x67, 0xD9, 0xB1, 0x42, 0x75, 0x23, 0x6E, + 0xF3, 0xCD, 0x42, 0xB2, 0xFC, 0x55, 0xF5, 0x53, 0x87, 0x17, 0x3B, 0xC0, + 0x33, 0x58, 0xF1, 0x52, 0xD2, 0xF9, 0x80, 0xA4, 0xF0, 0xE8, 0xF0, 0x3B, + 0x8B, 0x38, 0xCC, 0xA4, 0xC6, 0x90, 0x7F, 0x0F, 0x9C, 0xFD, 0x8B, 0xD1, + 0xA3, 0xCF, 0xDA, 0x83, 0xA7, 0x69, 0xC9, 0x50, 0x36, 0xD5, 0x5C, 0x05, + 0xD2, 0x0A, 0x41, 0x74, 0xDB, 0x63, 0x11, 0x37, 0xC1, 0xA5, 0xA0, 0x96, + 0x4B, 0x1E, 0x8C, 0x16, 0x12, 0x77, 0xAE, 0x94, 0x34, 0x7B, 0x1E, 0x7F, + 0xC2, 0x66, 0x00, 0xE4, 0xAA, 0x83, 0xEA, 0x8A, 0x90, 0xAD, 0xCE, 0x36, + 0x44, 0x4D, 0xD1, 0x51, 0xE9, 0xBC, 0x1F, 0xF3, 0x6A, 0x05, 0xFD, 0xC0, + 0x74, 0x1F, 0x25, 0x19, 0x40, 0x51, 0x6E, 0xEA, 0x82, 0x51, 0x40, 0xDF, + 0x9B, 0xB9, 0x08, 0x2A, 0x06, 0x02, 0xD5, 0x23, 0x1C, 0x13, 0xD6, 0xE9, + 0xDB, 0xDB, 0xC6, 0xB0, 0x7A, 0xCB, 0x7B, 0x27, 0x9B, 0xFB, 0xE0, 0xD5, + 0x46, 0x24, 0xED, 0x10, 0x4B, 0x63, 0x4B, 0xA5, 0x05, 0x8F, 0xBA, 0xB8, + 0x1D, 0x2B, 0xA6, 0xFA, 0x91, 0xE2, 0x92, 0x52, 0xBD, 0xEC, 0xEB, 0x67, + 0x97, 0x6D, 0x9A, 0x2D, 0x9F, 0x81, 0x32, 0x05, 0x67, 0x32, 0xFB, 0x48, + 0x08, 0x3F, 0xD9, 0x25, 0xB8, 0x04, 0x25, 0x2F +}; + +static const unsigned char TA721_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA722_DN[] = { + 0x30, 0x68, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, + 0x6C, 0x64, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA722_RSA_N[] = { + 0xB7, 0x32, 0xC8, 0xFE, 0xE9, 0x71, 0xA6, 0x04, 0x85, 0xAD, 0x0C, 0x11, + 0x64, 0xDF, 0xCE, 0x4D, 0xEF, 0xC8, 0x03, 0x18, 0x87, 0x3F, 0xA1, 0xAB, + 0xFB, 0x3C, 0xA6, 0x9F, 0xF0, 0xC3, 0xA1, 0xDA, 0xD4, 0xD8, 0x6E, 0x2B, + 0x53, 0x90, 0xFB, 0x24, 0xA4, 0x3E, 0x84, 0xF0, 0x9E, 0xE8, 0x5F, 0xEC, + 0xE5, 0x27, 0x44, 0xF5, 0x28, 0xA6, 0x3F, 0x7B, 0xDE, 0xE0, 0x2A, 0xF0, + 0xC8, 0xAF, 0x53, 0x2F, 0x9E, 0xCA, 0x05, 0x01, 0x93, 0x1E, 0x8F, 0x66, + 0x1C, 0x39, 0xA7, 0x4D, 0xFA, 0x5A, 0xB6, 0x73, 0x04, 0x25, 0x66, 0xEB, + 0x77, 0x7F, 0xE7, 0x59, 0xC6, 0x4A, 0x99, 0x25, 0x14, 0x54, 0xEB, 0x26, + 0xC7, 0xF3, 0x7F, 0x19, 0xD5, 0x30, 0x70, 0x8F, 0xAF, 0xB0, 0x46, 0x2A, + 0xFF, 0xAD, 0xEB, 0x29, 0xED, 0xD7, 0x9F, 0xAA, 0x04, 0x87, 0xA3, 0xD4, + 0xF9, 0x89, 0xA5, 0x34, 0x5F, 0xDB, 0x43, 0x91, 0x82, 0x36, 0xD9, 0x66, + 0x3C, 0xB1, 0xB8, 0xB9, 0x82, 0xFD, 0x9C, 0x3A, 0x3E, 0x10, 0xC8, 0x3B, + 0xEF, 0x06, 0x65, 0x66, 0x7A, 0x9B, 0x19, 0x18, 0x3D, 0xFF, 0x71, 0x51, + 0x3C, 0x30, 0x2E, 0x5F, 0xBE, 0x3D, 0x77, 0x73, 0xB2, 0x5D, 0x06, 0x6C, + 0xC3, 0x23, 0x56, 0x9A, 0x2B, 0x85, 0x26, 0x92, 0x1C, 0xA7, 0x02, 0xB3, + 0xE4, 0x3F, 0x0D, 0xAF, 0x08, 0x79, 0x82, 0xB8, 0x36, 0x3D, 0xEA, 0x9C, + 0xD3, 0x35, 0xB3, 0xBC, 0x69, 0xCA, 0xF5, 0xCC, 0x9D, 0xE8, 0xFD, 0x64, + 0x8D, 0x17, 0x80, 0x33, 0x6E, 0x5E, 0x4A, 0x5D, 0x99, 0xC9, 0x1E, 0x87, + 0xB4, 0x9D, 0x1A, 0xC0, 0xD5, 0x6E, 0x13, 0x35, 0x23, 0x5E, 0xDF, 0x9B, + 0x5F, 0x3D, 0xEF, 0xD6, 0xF7, 0x76, 0xC2, 0xEA, 0x3E, 0xBB, 0x78, 0x0D, + 0x1C, 0x42, 0x67, 0x6B, 0x04, 0xD8, 0xF8, 0xD6, 0xDA, 0x6F, 0x8B, 0xF2, + 0x44, 0xA0, 0x01, 0xAB +}; + +static const unsigned char TA722_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA723_DN[] = { + 0x30, 0x81, 0x8F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, + 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA723_RSA_N[] = { + 0xBD, 0xED, 0xC1, 0x03, 0xFC, 0xF6, 0x8F, 0xFC, 0x02, 0xB1, 0x6F, 0x5B, + 0x9F, 0x48, 0xD9, 0x9D, 0x79, 0xE2, 0xA2, 0xB7, 0x03, 0x61, 0x56, 0x18, + 0xC3, 0x47, 0xB6, 0xD7, 0xCA, 0x3D, 0x35, 0x2E, 0x89, 0x43, 0xF7, 0xA1, + 0x69, 0x9B, 0xDE, 0x8A, 0x1A, 0xFD, 0x13, 0x20, 0x9C, 0xB4, 0x49, 0x77, + 0x32, 0x29, 0x56, 0xFD, 0xB9, 0xEC, 0x8C, 0xDD, 0x22, 0xFA, 0x72, 0xDC, + 0x27, 0x61, 0x97, 0xEE, 0xF6, 0x5A, 0x84, 0xEC, 0x6E, 0x19, 0xB9, 0x89, + 0x2C, 0xDC, 0x84, 0x5B, 0xD5, 0x74, 0xFB, 0x6B, 0x5F, 0xC5, 0x89, 0xA5, + 0x10, 0x52, 0x89, 0x46, 0x55, 0xF4, 0xB8, 0x75, 0x1C, 0xE6, 0x7F, 0xE4, + 0x54, 0xAE, 0x4B, 0xF8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xF8, 0x17, 0x71, + 0x59, 0xEB, 0x1E, 0x28, 0x07, 0x74, 0xC5, 0x9D, 0x48, 0xBE, 0x6C, 0xB4, + 0xF4, 0xA4, 0xB0, 0xF3, 0x64, 0x37, 0x79, 0x92, 0xC0, 0xEC, 0x46, 0x5E, + 0x7F, 0xE1, 0x6D, 0x53, 0x4C, 0x62, 0xAF, 0xCD, 0x1F, 0x0B, 0x63, 0xBB, + 0x3A, 0x9D, 0xFB, 0xFC, 0x79, 0x00, 0x98, 0x61, 0x74, 0xCF, 0x26, 0x82, + 0x40, 0x63, 0xF3, 0xB2, 0x72, 0x6A, 0x19, 0x0D, 0x99, 0xCA, 0xD4, 0x0E, + 0x75, 0xCC, 0x37, 0xFB, 0x8B, 0x89, 0xC1, 0x59, 0xF1, 0x62, 0x7F, 0x5F, + 0xB3, 0x5F, 0x65, 0x30, 0xF8, 0xA7, 0xB7, 0x4D, 0x76, 0x5A, 0x1E, 0x76, + 0x5E, 0x34, 0xC0, 0xE8, 0x96, 0x56, 0x99, 0x8A, 0xB3, 0xF0, 0x7F, 0xA4, + 0xCD, 0xBD, 0xDC, 0x32, 0x31, 0x7C, 0x91, 0xCF, 0xE0, 0x5F, 0x11, 0xF8, + 0x6B, 0xAA, 0x49, 0x5C, 0xD1, 0x99, 0x94, 0xD1, 0xA2, 0xE3, 0x63, 0x5B, + 0x09, 0x76, 0xB5, 0x56, 0x62, 0xE1, 0x4B, 0x74, 0x1D, 0x96, 0xD4, 0x26, + 0xD4, 0x08, 0x04, 0x59, 0xD0, 0x98, 0x0E, 0x0E, 0xE6, 0xDE, 0xFC, 0xC3, + 0xEC, 0x1F, 0x90, 0xF1 +}; + +static const unsigned char TA723_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA724_DN[] = { + 0x30, 0x81, 0x98, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3B, + 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA724_RSA_N[] = { + 0xD5, 0x0C, 0x3A, 0xC4, 0x2A, 0xF9, 0x4E, 0xE2, 0xF5, 0xBE, 0x19, 0x97, + 0x5F, 0x8E, 0x88, 0x53, 0xB1, 0x1F, 0x3F, 0xCB, 0xCF, 0x9F, 0x20, 0x13, + 0x6D, 0x29, 0x3A, 0xC8, 0x0F, 0x7D, 0x3C, 0xF7, 0x6B, 0x76, 0x38, 0x63, + 0xD9, 0x36, 0x60, 0xA8, 0x9B, 0x5E, 0x5C, 0x00, 0x80, 0xB2, 0x2F, 0x59, + 0x7F, 0xF6, 0x87, 0xF9, 0x25, 0x43, 0x86, 0xE7, 0x69, 0x1B, 0x52, 0x9A, + 0x90, 0xE1, 0x71, 0xE3, 0xD8, 0x2D, 0x0D, 0x4E, 0x6F, 0xF6, 0xC8, 0x49, + 0xD9, 0xB6, 0xF3, 0x1A, 0x56, 0xAE, 0x2B, 0xB6, 0x74, 0x14, 0xEB, 0xCF, + 0xFB, 0x26, 0xE3, 0x1A, 0xBA, 0x1D, 0x96, 0x2E, 0x6A, 0x3B, 0x58, 0x94, + 0x89, 0x47, 0x56, 0xFF, 0x25, 0xA0, 0x93, 0x70, 0x53, 0x83, 0xDA, 0x84, + 0x74, 0x14, 0xC3, 0x67, 0x9E, 0x04, 0x68, 0x3A, 0xDF, 0x8E, 0x40, 0x5A, + 0x1D, 0x4A, 0x4E, 0xCF, 0x43, 0x91, 0x3B, 0xE7, 0x56, 0xD6, 0x00, 0x70, + 0xCB, 0x52, 0xEE, 0x7B, 0x7D, 0xAE, 0x3A, 0xE7, 0xBC, 0x31, 0xF9, 0x45, + 0xF6, 0xC2, 0x60, 0xCF, 0x13, 0x59, 0x02, 0x2B, 0x80, 0xCC, 0x34, 0x47, + 0xDF, 0xB9, 0xDE, 0x90, 0x65, 0x6D, 0x02, 0xCF, 0x2C, 0x91, 0xA6, 0xA6, + 0xE7, 0xDE, 0x85, 0x18, 0x49, 0x7C, 0x66, 0x4E, 0xA3, 0x3A, 0x6D, 0xA9, + 0xB5, 0xEE, 0x34, 0x2E, 0xBA, 0x0D, 0x03, 0xB8, 0x33, 0xDF, 0x47, 0xEB, + 0xB1, 0x6B, 0x8D, 0x25, 0xD9, 0x9B, 0xCE, 0x81, 0xD1, 0x45, 0x46, 0x32, + 0x96, 0x70, 0x87, 0xDE, 0x02, 0x0E, 0x49, 0x43, 0x85, 0xB6, 0x6C, 0x73, + 0xBB, 0x64, 0xEA, 0x61, 0x41, 0xAC, 0xC9, 0xD4, 0x54, 0xDF, 0x87, 0x2F, + 0xC7, 0x22, 0xB2, 0x26, 0xCC, 0x9F, 0x59, 0x54, 0x68, 0x9F, 0xFC, 0xBE, + 0x2A, 0x2F, 0xC4, 0x55, 0x1C, 0x75, 0x40, 0x60, 0x17, 0x85, 0x02, 0x55, + 0x39, 0x8B, 0x7F, 0x05 +}; + +static const unsigned char TA724_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA725_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x41, 0x47, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x16, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, + 0x6F, 0x6C, 0x64, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA725_RSA_N[] = { + 0xAF, 0xE4, 0xEE, 0x7E, 0x8B, 0x24, 0x0E, 0x12, 0x6E, 0xA9, 0x50, 0x2D, + 0x16, 0x44, 0x3B, 0x92, 0x92, 0x5C, 0xCA, 0xB8, 0x5D, 0x84, 0x92, 0x42, + 0x13, 0x2A, 0xBC, 0x65, 0x57, 0x82, 0x40, 0x3E, 0x57, 0x24, 0xCD, 0x50, + 0x8B, 0x25, 0x2A, 0xB7, 0x6F, 0xFC, 0xEF, 0xA2, 0xD0, 0xC0, 0x1F, 0x02, + 0x24, 0x4A, 0x13, 0x96, 0x8F, 0x23, 0x13, 0xE6, 0x28, 0x58, 0x00, 0xA3, + 0x47, 0xC7, 0x06, 0xA7, 0x84, 0x23, 0x2B, 0xBB, 0xBD, 0x96, 0x2B, 0x7F, + 0x55, 0xCC, 0x8B, 0xC1, 0x57, 0x1F, 0x0E, 0x62, 0x65, 0x0F, 0xDD, 0x3D, + 0x56, 0x8A, 0x73, 0xDA, 0xAE, 0x7E, 0x6D, 0xBA, 0x81, 0x1C, 0x7E, 0x42, + 0x8C, 0x20, 0x35, 0xD9, 0x43, 0x4D, 0x84, 0xFA, 0x84, 0xDB, 0x52, 0x2C, + 0xF3, 0x0E, 0x27, 0x77, 0x0B, 0x6B, 0xBF, 0x11, 0x2F, 0x72, 0x78, 0x9F, + 0x2E, 0xD8, 0x3E, 0xE6, 0x18, 0x37, 0x5A, 0x2A, 0x72, 0xF9, 0xDA, 0x62, + 0x90, 0x92, 0x95, 0xCA, 0x1F, 0x9C, 0xE9, 0xB3, 0x3C, 0x2B, 0xCB, 0xF3, + 0x01, 0x13, 0xBF, 0x5A, 0xCF, 0xC1, 0xB5, 0x0A, 0x60, 0xBD, 0xDD, 0xB5, + 0x99, 0x64, 0x53, 0xB8, 0xA0, 0x96, 0xB3, 0x6F, 0xE2, 0x26, 0x77, 0x91, + 0x8C, 0xE0, 0x62, 0x10, 0x02, 0x9F, 0x34, 0x0F, 0xA4, 0xD5, 0x92, 0x33, + 0x51, 0xDE, 0xBE, 0x8D, 0xBA, 0x84, 0x7A, 0x60, 0x3C, 0x6A, 0xDB, 0x9F, + 0x2B, 0xEC, 0xDE, 0xDE, 0x01, 0x3F, 0x6E, 0x4D, 0xE5, 0x50, 0x86, 0xCB, + 0xB4, 0xAF, 0xED, 0x44, 0x40, 0xC5, 0xCA, 0x5A, 0x8C, 0xDA, 0xD2, 0x2B, + 0x7C, 0xA8, 0xEE, 0xBE, 0xA6, 0xE5, 0x0A, 0xAA, 0x0E, 0xA5, 0xDF, 0x05, + 0x52, 0xB7, 0x55, 0xC7, 0x22, 0x5D, 0x32, 0x6A, 0x97, 0x97, 0x63, 0x13, + 0xDB, 0xC9, 0xDB, 0x79, 0x36, 0x7B, 0x85, 0x3A, 0x4A, 0xC5, 0x52, 0x89, + 0xF9, 0x24, 0xE7, 0x9D, 0x77, 0xA9, 0x82, 0xFF, 0x55, 0x1C, 0xA5, 0x71, + 0x69, 0x2B, 0xD1, 0x02, 0x24, 0xF2, 0xB3, 0x26, 0xD4, 0x6B, 0xDA, 0x04, + 0x55, 0xE5, 0xC1, 0x0A, 0xC7, 0x6D, 0x30, 0x37, 0x90, 0x2A, 0xE4, 0x9E, + 0x14, 0x33, 0x5E, 0x16, 0x17, 0x55, 0xC5, 0x5B, 0xB5, 0xCB, 0x34, 0x89, + 0x92, 0xF1, 0x9D, 0x26, 0x8F, 0xA1, 0x07, 0xD4, 0xC6, 0xB2, 0x78, 0x50, + 0xDB, 0x0C, 0x0C, 0x0B, 0x7C, 0x0B, 0x8C, 0x41, 0xD7, 0xB9, 0xE9, 0xDD, + 0x8C, 0x88, 0xF7, 0xA3, 0x4D, 0xB2, 0x32, 0xCC, 0xD8, 0x17, 0xDA, 0xCD, + 0xB7, 0xCE, 0x66, 0x9D, 0xD4, 0xFD, 0x5E, 0xFF, 0xBD, 0x97, 0x3E, 0x29, + 0x75, 0xE7, 0x7E, 0xA7, 0x62, 0x58, 0xAF, 0x25, 0x34, 0xA5, 0x41, 0xC7, + 0x3D, 0xBC, 0x0D, 0x50, 0xCA, 0x03, 0x03, 0x0F, 0x08, 0x5A, 0x1F, 0x95, + 0x73, 0x78, 0x62, 0xBF, 0xAF, 0x72, 0x14, 0x69, 0x0E, 0xA5, 0xE5, 0x03, + 0x0E, 0x78, 0x8E, 0x26, 0x28, 0x42, 0xF0, 0x07, 0x0B, 0x62, 0x20, 0x10, + 0x67, 0x39, 0x46, 0xFA, 0xA9, 0x03, 0xCC, 0x04, 0x38, 0x7A, 0x66, 0xEF, + 0x20, 0x83, 0xB5, 0x8C, 0x4A, 0x56, 0x8E, 0x91, 0x00, 0xFC, 0x8E, 0x5C, + 0x82, 0xDE, 0x88, 0xA0, 0xC3, 0xE2, 0x68, 0x6E, 0x7D, 0x8D, 0xEF, 0x3C, + 0xDD, 0x65, 0xF4, 0x5D, 0xAC, 0x51, 0xEF, 0x24, 0x80, 0xAE, 0xAA, 0x56, + 0x97, 0x6F, 0xF9, 0xAD, 0x7D, 0xDA, 0x61, 0x3F, 0x98, 0x77, 0x3C, 0xA5, + 0x91, 0xB6, 0x1C, 0x8C, 0x26, 0xDA, 0x65, 0xA2, 0x09, 0x6D, 0xC1, 0xE2, + 0x54, 0xE3, 0xB9, 0xCA, 0x4C, 0x4C, 0x80, 0x8F, 0x77, 0x7B, 0x60, 0x9A, + 0x1E, 0xDF, 0xB6, 0xF2, 0x48, 0x1E, 0x0E, 0xBA, 0x4E, 0x54, 0x6D, 0x98, + 0xE0, 0xE1, 0xA2, 0x1A, 0xA2, 0x77, 0x50, 0xCF, 0xC4, 0x63, 0x92, 0xEC, + 0x47, 0x19, 0x9D, 0xEB, 0xE6, 0x6B, 0xCE, 0xC1 +}; + +static const unsigned char TA725_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA726_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1F, 0x4B, 0x72, 0x61, 0x6A, 0x6F, 0x77, 0x61, 0x20, 0x49, 0x7A, + 0x62, 0x61, 0x20, 0x52, 0x6F, 0x7A, 0x6C, 0x69, 0x63, 0x7A, 0x65, 0x6E, + 0x69, 0x6F, 0x77, 0x61, 0x20, 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x53, 0x5A, 0x41, 0x46, + 0x49, 0x52, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA726_RSA_N[] = { + 0xB7, 0xBC, 0x3E, 0x50, 0xA8, 0x4B, 0xCD, 0x40, 0xB5, 0xCE, 0x61, 0xE7, + 0x96, 0xCA, 0xB4, 0xA1, 0xDA, 0x0C, 0x22, 0xB0, 0xFA, 0xB5, 0x7B, 0x76, + 0x00, 0x77, 0x8C, 0x0B, 0xCF, 0x7D, 0xA8, 0x86, 0xCC, 0x26, 0x51, 0xE4, + 0x20, 0x3D, 0x85, 0x0C, 0xD6, 0x58, 0xE3, 0xE7, 0xF4, 0x2A, 0x18, 0x9D, + 0xDA, 0xD1, 0xAE, 0x26, 0xEE, 0xEB, 0x53, 0xDC, 0xF4, 0x90, 0xD6, 0x13, + 0x4A, 0x0C, 0x90, 0x3C, 0xC3, 0xF4, 0xDA, 0xD2, 0x8E, 0x0D, 0x92, 0x3A, + 0xDC, 0xB1, 0xB1, 0xFF, 0x38, 0xDE, 0xC3, 0xBA, 0x2D, 0x5F, 0x80, 0xB9, + 0x02, 0xBD, 0x4A, 0x9D, 0x1B, 0x0F, 0xB4, 0xC3, 0xC2, 0xC1, 0x67, 0x03, + 0xDD, 0xDC, 0x1B, 0x9C, 0x3D, 0xB3, 0xB0, 0xDE, 0x00, 0x1E, 0xA8, 0x34, + 0x47, 0xBB, 0x9A, 0xEB, 0xFE, 0x0B, 0x14, 0xBD, 0x36, 0x84, 0xDA, 0x0D, + 0x20, 0xBF, 0xFA, 0x5B, 0xCB, 0xA9, 0x16, 0x20, 0xAD, 0x39, 0x60, 0xEE, + 0x2F, 0x75, 0xB6, 0xE7, 0x97, 0x9C, 0xF9, 0x3E, 0xFD, 0x7E, 0x4D, 0x6F, + 0x4D, 0x2F, 0xEF, 0x88, 0x0D, 0x6A, 0xFA, 0xDD, 0xF1, 0x3D, 0x6E, 0x20, + 0xA5, 0xA0, 0x12, 0xB4, 0x4D, 0x70, 0xB9, 0xCE, 0xD7, 0x72, 0x3B, 0x89, + 0x93, 0xA7, 0x80, 0x84, 0x1C, 0x27, 0x49, 0x72, 0x49, 0xB5, 0xFF, 0x3B, + 0x95, 0x9E, 0xC1, 0xCC, 0xC8, 0x01, 0xEC, 0xE8, 0x0E, 0x8A, 0x0A, 0x96, + 0xE7, 0xB3, 0xA6, 0x87, 0xE5, 0xD6, 0xF9, 0x05, 0x2B, 0x0D, 0x97, 0x40, + 0x70, 0x3C, 0xBA, 0xAC, 0x75, 0x5A, 0x9C, 0xD5, 0x4D, 0x9D, 0x02, 0x0A, + 0xD2, 0x4B, 0x9B, 0x66, 0x4B, 0x46, 0x07, 0x17, 0x65, 0xAD, 0x9F, 0x6C, + 0x88, 0x00, 0xDC, 0x22, 0x89, 0xE0, 0xE1, 0x64, 0xD4, 0x67, 0xBC, 0x31, + 0x79, 0x61, 0x3C, 0xBB, 0xCA, 0x41, 0xCD, 0x5C, 0x6A, 0x00, 0xC8, 0x3C, + 0x38, 0x8E, 0x58, 0xAF +}; + +static const unsigned char TA726_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA727_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA727_EC_Q[] = { + 0x04, 0xCE, 0xBF, 0xFE, 0x57, 0xA8, 0xBF, 0xD5, 0xAA, 0xF7, 0x10, 0x9A, + 0xCD, 0xBC, 0xD1, 0x11, 0xA2, 0xBD, 0x67, 0x42, 0xCC, 0x90, 0xEB, 0x15, + 0x18, 0x90, 0xD9, 0xA2, 0xCD, 0x0C, 0x2A, 0x25, 0xEB, 0x3E, 0x4F, 0xCE, + 0xB5, 0xD2, 0x8F, 0x0F, 0xF3, 0x35, 0xDA, 0x43, 0x8B, 0x02, 0x80, 0xBE, + 0x6F, 0x51, 0x24, 0x1D, 0x0F, 0x6B, 0x2B, 0xCA, 0x9F, 0xC2, 0x6F, 0x50, + 0x32, 0xE5, 0x37, 0x20, 0xB6, 0x20, 0xFF, 0x88, 0x0D, 0x0F, 0x6D, 0x49, + 0xBB, 0xDB, 0x06, 0xA4, 0x87, 0x90, 0x92, 0x94, 0xF4, 0x09, 0xD0, 0xCF, + 0x7F, 0xC8, 0x80, 0x0B, 0xC1, 0x97, 0xB3, 0xBB, 0x35, 0x27, 0xC9, 0xC2, + 0x1B +}; + +static const unsigned char TA728_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x33 +}; + +static const unsigned char TA728_RSA_N[] = { + 0xED, 0x35, 0xA1, 0x81, 0x80, 0xF3, 0xCB, 0x4A, 0x69, 0x5B, 0xC2, 0xFB, + 0x51, 0x83, 0xAE, 0x26, 0xFD, 0xE1, 0x6E, 0xF3, 0x81, 0x12, 0x7D, 0x71, + 0x40, 0xFF, 0x87, 0x75, 0x42, 0x29, 0x21, 0xED, 0x81, 0x52, 0x2C, 0xDF, + 0x12, 0xC1, 0x19, 0x84, 0x89, 0xC1, 0xBD, 0xC5, 0x28, 0xD5, 0xD5, 0x4B, + 0x6C, 0x44, 0xD6, 0x4C, 0xDB, 0x07, 0x96, 0x4A, 0x55, 0x7A, 0xCA, 0x36, + 0x82, 0x04, 0x36, 0xA8, 0xA5, 0xFC, 0x27, 0xF6, 0x49, 0xF1, 0xD5, 0x72, + 0x9E, 0x91, 0xF9, 0x23, 0xD6, 0x70, 0x7B, 0xBB, 0xF5, 0x9B, 0xC1, 0xEC, + 0x93, 0xCF, 0x19, 0xEA, 0x65, 0x7E, 0x88, 0x70, 0xA0, 0x73, 0xFC, 0xF6, + 0xFF, 0xB5, 0x56, 0x62, 0xE1, 0x73, 0x6A, 0x34, 0x98, 0x3E, 0x82, 0xB8, + 0xAC, 0x95, 0x53, 0xF4, 0x01, 0xA0, 0x27, 0x07, 0x72, 0xA3, 0x00, 0x53, + 0xA0, 0xE4, 0xB2, 0xAB, 0x83, 0x38, 0x57, 0x33, 0x25, 0x94, 0x9F, 0xBE, + 0x48, 0x1D, 0x98, 0xE1, 0xA3, 0xBA, 0x9E, 0x5C, 0xCD, 0x04, 0x71, 0x51, + 0x7D, 0x75, 0x78, 0xAB, 0xF3, 0x59, 0xAA, 0xC4, 0xE0, 0x60, 0xBE, 0x8F, + 0x83, 0x52, 0xB8, 0x75, 0x1A, 0x41, 0x35, 0xED, 0xBC, 0xF3, 0x3A, 0x63, + 0xE9, 0xA9, 0x14, 0x45, 0xD7, 0xE6, 0x52, 0xD1, 0x6E, 0xD2, 0xDE, 0xBC, + 0xE3, 0xF5, 0x0B, 0x3B, 0xE6, 0xE0, 0xC4, 0xBD, 0x43, 0x64, 0x13, 0xA6, + 0xCE, 0xF4, 0x98, 0x37, 0x6C, 0x8A, 0x95, 0xA8, 0x97, 0xC8, 0x47, 0x0F, + 0xF0, 0x5E, 0x10, 0x8B, 0xE7, 0x1D, 0x1C, 0xFE, 0xB1, 0x3B, 0xA0, 0x05, + 0x33, 0x68, 0x05, 0x41, 0x82, 0xC1, 0x03, 0x2B, 0x01, 0xC8, 0xE7, 0x8F, + 0x4D, 0xAB, 0xE8, 0xB5, 0xF6, 0xCD, 0x6B, 0x44, 0xB5, 0xE7, 0xDD, 0x8B, + 0xEC, 0xEA, 0x25, 0xB4, 0x00, 0x22, 0x57, 0x4D, 0xB0, 0xB1, 0xB2, 0x31, + 0xC1, 0x16, 0xCE, 0xFF, 0xFD, 0x14, 0x84, 0xB7, 0x47, 0xFA, 0xB2, 0xF1, + 0x70, 0xDE, 0xDB, 0x8B, 0x6C, 0x36, 0x58, 0xA4, 0x7C, 0xB3, 0x11, 0xD1, + 0xC3, 0x77, 0x7F, 0x5F, 0xB6, 0x25, 0xE0, 0x0D, 0xC5, 0xD2, 0xB3, 0xF9, + 0xB8, 0xB8, 0x77, 0xDB, 0x37, 0x71, 0x71, 0x47, 0xE3, 0x60, 0x18, 0x4F, + 0x24, 0xB6, 0x75, 0x37, 0x78, 0xB9, 0xA3, 0x62, 0xAF, 0xBD, 0xC9, 0x72, + 0x8E, 0x2F, 0xCC, 0xBB, 0xAE, 0xDB, 0xE4, 0x15, 0x52, 0x19, 0x07, 0x33, + 0xFB, 0x6A, 0xB7, 0x2D, 0x4B, 0x90, 0x28, 0x82, 0x73, 0xFE, 0x18, 0x8B, + 0x35, 0x8D, 0xDB, 0xA7, 0x04, 0x6A, 0xBE, 0xEA, 0xC1, 0x4D, 0x36, 0x3B, + 0x16, 0x36, 0x91, 0x32, 0xEF, 0xB6, 0x40, 0x89, 0x91, 0x43, 0xE0, 0xF2, + 0xA2, 0xAB, 0x04, 0x2E, 0xE6, 0xF2, 0x4C, 0x0E, 0x16, 0x34, 0x20, 0xAC, + 0x87, 0xC1, 0x2D, 0x7E, 0xC9, 0x66, 0x47, 0x17, 0x14, 0x11, 0xA4, 0xF3, + 0xF7, 0xA1, 0x24, 0x89, 0xAB, 0xD8, 0x1A, 0xC8, 0xA1, 0x5C, 0xB1, 0xA3, + 0xF7, 0x8C, 0x6D, 0xC8, 0x01, 0xC9, 0x4F, 0xC9, 0xEC, 0xC4, 0xFC, 0xAC, + 0x51, 0x33, 0xD1, 0xC8, 0x83, 0xD1, 0xC9, 0x9F, 0x1D, 0xD4, 0x47, 0x34, + 0x29, 0x3E, 0xCB, 0xB0, 0x0E, 0xFA, 0x83, 0x0B, 0x28, 0x58, 0xE5, 0x29, + 0xDC, 0x3F, 0x7C, 0xA8, 0x9F, 0xC9, 0xB6, 0x0A, 0xBB, 0xA6, 0xE8, 0x46, + 0x16, 0x0F, 0x96, 0xE5, 0x7B, 0xE4, 0x6A, 0x7A, 0x48, 0x6D, 0x76, 0x98, + 0x05, 0xA5, 0xDC, 0x6D, 0x1E, 0x42, 0x1E, 0x42, 0xDA, 0x1A, 0xE0, 0x52, + 0xF7, 0xB5, 0x83, 0xC0, 0x1A, 0x7B, 0x78, 0x35, 0x2C, 0x38, 0xF5, 0x1F, + 0xFD, 0x49, 0xA3, 0x2E, 0xD2, 0x59, 0x63, 0xBF, 0x80, 0xB0, 0x8C, 0x93, + 0x73, 0xCB, 0x35, 0xA6, 0x99, 0x95, 0x22, 0x61, 0x65, 0x03, 0x60, 0xFB, + 0x2F, 0x93, 0x4B, 0xFA, 0x9A, 0x9C, 0x80, 0x3B +}; + +static const unsigned char TA728_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA729_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x49, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x11, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x6C, + 0x61, 0x6E, 0x64, 0x20, 0x4F, 0x79, 0x6A, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x32 +}; + +static const unsigned char TA729_RSA_N[] = { + 0xB2, 0xD0, 0x3F, 0x07, 0xBC, 0xE2, 0x7B, 0xD0, 0x6B, 0x99, 0xF8, 0xE2, + 0x77, 0x69, 0xE7, 0xCE, 0x9D, 0xA4, 0x03, 0xBC, 0x82, 0x6D, 0xA1, 0xFE, + 0x81, 0x65, 0x1F, 0x4C, 0x27, 0xAC, 0x8E, 0x00, 0xBA, 0x16, 0x7B, 0xEB, + 0x30, 0x6A, 0x00, 0xC0, 0xB3, 0x74, 0x68, 0x7E, 0xB2, 0xAF, 0xC7, 0xD5, + 0x62, 0xB3, 0x7A, 0x3F, 0x50, 0xCA, 0x8C, 0x36, 0x44, 0x24, 0x63, 0xD2, + 0x36, 0xE9, 0x0C, 0x85, 0xF6, 0x43, 0x76, 0xD5, 0x4C, 0xA1, 0x60, 0x72, + 0x67, 0xE2, 0x28, 0x33, 0xA5, 0xCB, 0x31, 0xB8, 0x3A, 0x22, 0x23, 0x34, + 0xB8, 0x7D, 0xBD, 0x56, 0x22, 0x40, 0x9D, 0xEA, 0xF4, 0x7B, 0x03, 0xAD, + 0x68, 0xFC, 0xB2, 0x81, 0x4F, 0x98, 0xD0, 0x74, 0xEA, 0x8D, 0xE5, 0x7D, + 0xCD, 0x63, 0xC3, 0xA3, 0xF6, 0xDE, 0x92, 0xC2, 0x58, 0x19, 0xE0, 0x96, + 0xBB, 0xC5, 0xC4, 0xA9, 0x3D, 0xA5, 0x74, 0x96, 0xFE, 0xAF, 0xF9, 0x89, + 0xAA, 0xBD, 0x95, 0x17, 0x54, 0xD8, 0x78, 0x44, 0xF1, 0x0C, 0x77, 0x15, + 0x92, 0xE0, 0x98, 0x42, 0xA7, 0xA4, 0xD6, 0xAA, 0x20, 0x92, 0xCD, 0xC1, + 0xA0, 0xB3, 0x96, 0xB2, 0x3A, 0x84, 0x42, 0x8D, 0x7D, 0xD5, 0x95, 0xE4, + 0xD6, 0xDB, 0xE9, 0x62, 0xC4, 0x58, 0xB3, 0x79, 0xC5, 0x8C, 0xD3, 0x35, + 0x33, 0x83, 0x9F, 0x75, 0xA1, 0x52, 0x27, 0x61, 0x38, 0xF1, 0x59, 0x3D, + 0x8E, 0x50, 0xE0, 0xBD, 0x79, 0x3C, 0xE7, 0x6C, 0x96, 0xFE, 0x5E, 0xD9, + 0x02, 0x65, 0xB4, 0x8E, 0x5C, 0xD0, 0x11, 0x34, 0xDF, 0x5D, 0xBF, 0x52, + 0xA7, 0x81, 0x00, 0xC3, 0x7F, 0x99, 0x45, 0x99, 0x15, 0xD5, 0x17, 0xC8, + 0x0A, 0x53, 0xEC, 0x63, 0xF3, 0x99, 0x7D, 0xCC, 0x69, 0x12, 0x86, 0xC2, + 0x17, 0xF0, 0x01, 0x9E, 0xBF, 0x84, 0xBC, 0xD1, 0x52, 0xCB, 0x1B, 0x92, + 0x66, 0xCE, 0xA4, 0x53, 0xE5, 0xA1, 0xBF, 0xC4, 0xDB, 0x09, 0xD6, 0xE6, + 0x89, 0x56, 0x2B, 0xC8, 0xE3, 0x7C, 0xDE, 0xE3, 0xFF, 0x89, 0xE5, 0x35, + 0x6E, 0x28, 0xE8, 0x6C, 0x0B, 0x23, 0x51, 0xA9, 0x25, 0x05, 0xEB, 0x48, + 0xF8, 0xDD, 0xB1, 0xCA, 0xFA, 0x6C, 0x08, 0x51, 0xEF, 0xB7, 0x18, 0x6C, + 0x44, 0xCA, 0x26, 0xE1, 0x73, 0xC6, 0x89, 0x06, 0x81, 0xE5, 0x8A, 0xAC, + 0xB0, 0xE2, 0x29, 0xC6, 0xB9, 0x24, 0xB3, 0x6B, 0x44, 0x11, 0xF4, 0xA5, + 0x43, 0xC2, 0x4C, 0x43, 0xE5, 0x70, 0x36, 0x8C, 0xB6, 0x33, 0x57, 0x7A, + 0x95, 0x2E, 0x82, 0xA0, 0xF4, 0x5C, 0x10, 0xB3, 0x61, 0x83, 0xF6, 0x02, + 0x05, 0x86, 0x2E, 0x7C, 0x2D, 0x6C, 0xDC, 0x03, 0x46, 0x6E, 0x35, 0x93, + 0xD5, 0x7A, 0x95, 0x2F, 0xDE, 0x20, 0xD8, 0x5B, 0x7E, 0x94, 0x90, 0x04, + 0x6A, 0xBA, 0x59, 0x3D, 0x04, 0x05, 0x75, 0x9D, 0x37, 0xA2, 0x0E, 0x2E, + 0x3D, 0xEB, 0xC1, 0xA4, 0x52, 0x83, 0xFE, 0xD0, 0x6B, 0xD4, 0x66, 0x8E, + 0xDC, 0xC6, 0xE9, 0x12, 0x4E, 0x1D, 0x2A, 0x57, 0xAA, 0x10, 0xBC, 0x7C, + 0x5E, 0x82, 0x7D, 0xA6, 0xA6, 0xC9, 0xF2, 0x2D, 0xB9, 0xF5, 0x17, 0x27, + 0xAD, 0xD1, 0x0E, 0x89, 0x54, 0x2B, 0x95, 0xFA, 0xC0, 0xAD, 0x1D, 0x98, + 0x14, 0x78, 0x33, 0x42, 0x86, 0x0A, 0xA9, 0x73, 0xB5, 0xFB, 0x74, 0x0D, + 0xB7, 0x1B, 0x30, 0x19, 0xC4, 0x5A, 0x0E, 0x1C, 0x27, 0xB7, 0xDA, 0x18, + 0xD0, 0xFF, 0x8A, 0xC8, 0x05, 0xBA, 0xF1, 0xAA, 0x1C, 0xA2, 0x37, 0xB7, + 0xE6, 0x48, 0xA4, 0x46, 0x2C, 0x94, 0xEA, 0xA8, 0x76, 0x62, 0x47, 0x8B, + 0x10, 0x53, 0x07, 0x48, 0x57, 0x6C, 0xE2, 0x92, 0x4D, 0xB6, 0xAE, 0x05, + 0xCB, 0xDC, 0xC1, 0x4A, 0x5E, 0x8F, 0xAC, 0x3D, 0x19, 0x4E, 0xC2, 0xED, + 0x60, 0x75, 0x2B, 0xDB, 0xC1, 0xCA, 0x42, 0xD5 +}; + +static const unsigned char TA729_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA730_DN[] = { + 0x30, 0x37, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0B, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x54, + 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, 0x20, 0x52, + 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x31 +}; + +static const unsigned char TA730_RSA_N[] = { + 0xC2, 0xBE, 0xEB, 0x27, 0xF0, 0x21, 0xA3, 0xF3, 0x69, 0x26, 0x55, 0x7E, + 0x9D, 0xC5, 0x55, 0x16, 0x91, 0x5C, 0xFD, 0xEF, 0x21, 0xBF, 0x53, 0x80, + 0x7A, 0x2D, 0xD2, 0x91, 0x8C, 0x63, 0x31, 0xF0, 0xEC, 0x24, 0xF0, 0xC3, + 0xA5, 0xD2, 0x72, 0x7C, 0x10, 0x6D, 0xF4, 0x37, 0xB7, 0xE5, 0xE6, 0x7C, + 0x79, 0xEA, 0x8C, 0xB5, 0x82, 0x8B, 0xAE, 0x48, 0xB6, 0xAC, 0x00, 0xDC, + 0x65, 0x75, 0xEC, 0x2A, 0x4D, 0x5F, 0xC1, 0x87, 0xF5, 0x20, 0x65, 0x2B, + 0x81, 0xA8, 0x47, 0x3E, 0x89, 0x23, 0x95, 0x30, 0x16, 0x90, 0x7F, 0xE8, + 0x57, 0x07, 0x48, 0xE7, 0x19, 0xAE, 0xBF, 0x45, 0x67, 0xB1, 0x37, 0x1B, + 0x06, 0x2A, 0xFE, 0xDE, 0xF9, 0xAC, 0x7D, 0x83, 0xFB, 0x5E, 0xBA, 0xE4, + 0x8F, 0x97, 0x67, 0xBE, 0x4B, 0x8E, 0x8D, 0x64, 0x07, 0x57, 0x38, 0x55, + 0x69, 0x34, 0x36, 0x3D, 0x13, 0x48, 0xEF, 0x4F, 0xE2, 0xD3, 0x66, 0x1E, + 0xA4, 0xCF, 0x1A, 0xB7, 0x5E, 0x36, 0x33, 0xD4, 0xB4, 0x06, 0xBD, 0x18, + 0x01, 0xFD, 0x77, 0x84, 0x50, 0x00, 0x45, 0xF5, 0x8C, 0x5D, 0xE8, 0x23, + 0xBC, 0x7E, 0xFE, 0x35, 0xE1, 0xED, 0x50, 0x7B, 0xA9, 0x30, 0x8D, 0x19, + 0xD3, 0x09, 0x8E, 0x68, 0x67, 0x5D, 0xBF, 0x3C, 0x97, 0x18, 0x53, 0xBB, + 0x29, 0x62, 0xC5, 0xCA, 0x5E, 0x72, 0xC1, 0xC7, 0x96, 0xD4, 0xDB, 0x2D, + 0xA0, 0xB4, 0x1F, 0x69, 0x03, 0xEC, 0xEA, 0xE2, 0x50, 0xF1, 0x0C, 0x3C, + 0xF0, 0xAC, 0xF3, 0x53, 0x2D, 0xF0, 0x1C, 0xF5, 0xED, 0x6C, 0x39, 0x39, + 0x73, 0x80, 0x16, 0xC8, 0x52, 0xB0, 0x23, 0xCD, 0xE0, 0x3E, 0xDC, 0xDD, + 0x3C, 0x47, 0xA0, 0xBB, 0x35, 0x8A, 0xE2, 0x98, 0x68, 0x8B, 0xBE, 0xE5, + 0xBF, 0x72, 0xEE, 0xD2, 0xFA, 0xA5, 0xED, 0x12, 0xED, 0xFC, 0x98, 0x18, + 0xA9, 0x26, 0x76, 0xDC, 0x28, 0x4B, 0x10, 0x20, 0x1C, 0xD3, 0x7F, 0x16, + 0x77, 0x2D, 0xED, 0x6F, 0x80, 0xF7, 0x49, 0xBB, 0x53, 0x05, 0xBB, 0x5D, + 0x68, 0xC7, 0xD4, 0xC8, 0x75, 0x16, 0x3F, 0x89, 0x5A, 0x8B, 0xF7, 0x17, + 0x47, 0xD4, 0x4C, 0xF1, 0xD2, 0x89, 0x79, 0x3E, 0x4D, 0x3D, 0x98, 0xA8, + 0x61, 0xDE, 0x3A, 0x1E, 0xD2, 0xF8, 0x5E, 0x03, 0xE0, 0xC1, 0xC9, 0x1C, + 0x8C, 0xD3, 0x8D, 0x4D, 0xD3, 0x95, 0x36, 0xB3, 0x37, 0x5F, 0x63, 0x63, + 0x9B, 0x33, 0x14, 0xF0, 0x2D, 0x26, 0x6B, 0x53, 0x7C, 0x89, 0x8C, 0x32, + 0xC2, 0x6E, 0xEC, 0x3D, 0x21, 0x00, 0x39, 0xC9, 0xA1, 0x68, 0xE2, 0x50, + 0x83, 0x2E, 0xB0, 0x3A, 0x2B, 0xF3, 0x36, 0xA0, 0xAC, 0x2F, 0xE4, 0x6F, + 0x61, 0xC2, 0x51, 0x09, 0x39, 0x3E, 0x8B, 0x53, 0xB9, 0xBB, 0x67, 0xDA, + 0xDC, 0x53, 0xB9, 0x76, 0x59, 0x36, 0x9D, 0x43, 0xE5, 0x20, 0xE0, 0x3D, + 0x32, 0x60, 0x85, 0x22, 0x51, 0xB7, 0xC7, 0x33, 0xBB, 0xDD, 0x15, 0x2F, + 0xA4, 0x78, 0xA6, 0x07, 0x7B, 0x81, 0x46, 0x36, 0x04, 0x86, 0xDD, 0x79, + 0x35, 0xC7, 0x95, 0x2C, 0x3B, 0xB0, 0xA3, 0x17, 0x35, 0xE5, 0x73, 0x1F, + 0xB4, 0x5C, 0x59, 0xEF, 0xDA, 0xEA, 0x10, 0x65, 0x7B, 0x7A, 0xD0, 0x7F, + 0x9F, 0xB3, 0xB4, 0x2A, 0x37, 0x3B, 0x70, 0x8B, 0x9B, 0x5B, 0xB9, 0x2B, + 0xB7, 0xEC, 0xB2, 0x51, 0x12, 0x97, 0x53, 0x29, 0x5A, 0xD4, 0xF0, 0x12, + 0x10, 0xDC, 0x4F, 0x02, 0xBB, 0x12, 0x92, 0x2F, 0x62, 0xD4, 0x3F, 0x69, + 0x43, 0x7C, 0x0D, 0xD6, 0xFC, 0x58, 0x75, 0x01, 0x88, 0x9D, 0x58, 0x16, + 0x4B, 0xDE, 0xBA, 0x90, 0xFF, 0x47, 0x01, 0x89, 0x06, 0x6A, 0xF6, 0x5F, + 0xB2, 0x90, 0x6A, 0xB3, 0x02, 0xA6, 0x02, 0x88, 0xBF, 0xB3, 0x47, 0x7E, + 0x2A, 0xD9, 0xD5, 0xFA, 0x68, 0x78, 0x35, 0x4D +}; + +static const unsigned char TA730_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA731_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA731_RSA_N[] = { + 0xC0, 0x31, 0x82, 0x61, 0x92, 0xE4, 0x94, 0x1B, 0x0A, 0x2A, 0x65, 0xD0, + 0xBE, 0x06, 0xA9, 0x87, 0x3B, 0x51, 0x12, 0xEA, 0x70, 0x41, 0xAE, 0xE2, + 0xFB, 0x74, 0xEA, 0x0A, 0x8D, 0xB9, 0xB3, 0x4C, 0xDC, 0x8F, 0xB7, 0x13, + 0x52, 0x4F, 0x54, 0x18, 0xE1, 0x2C, 0x73, 0x95, 0x91, 0xC5, 0x66, 0x3B, + 0x6A, 0xCF, 0xAC, 0x63, 0x6D, 0x87, 0x53, 0xF0, 0xF7, 0xF1, 0x39, 0xB7, + 0xA0, 0x43, 0x63, 0xB0, 0xC4, 0x03, 0x5D, 0x57, 0xA9, 0xE7, 0x44, 0xCE, + 0xC4, 0xA1, 0x83, 0x65, 0xF6, 0x50, 0x3E, 0xB1, 0x7E, 0x16, 0xB8, 0x3A, + 0x8A, 0x02, 0xD0, 0x96, 0x1F, 0x00, 0xCD, 0x05, 0x21, 0xEF, 0x06, 0x6D, + 0xDD, 0x21, 0x9C, 0x19, 0x43, 0x45, 0xA1, 0xC5, 0xE8, 0x80, 0xCA, 0xC2, + 0xAD, 0x40, 0x62, 0x17, 0x06, 0xC6, 0xAA, 0xBC, 0xF3, 0xD6, 0xE6, 0xFC, + 0x50, 0x7E, 0x66, 0x42, 0x1F, 0x3C, 0x8B, 0xA6, 0x79, 0x79, 0x86, 0x40, + 0x35, 0x9F, 0x20, 0xEF, 0x3F, 0xEB, 0x8B, 0x47, 0x1F, 0x8F, 0x8E, 0xC5, + 0xD4, 0x8E, 0xB6, 0x2C, 0xC9, 0x44, 0x04, 0xE3, 0xD4, 0x43, 0x75, 0x3F, + 0xD5, 0x3F, 0xAF, 0x1C, 0xCC, 0x7E, 0x46, 0x5F, 0xAC, 0xDF, 0x64, 0x10, + 0x8A, 0xEF, 0x46, 0xF0, 0x90, 0xF0, 0x0F, 0x2D, 0xF4, 0x88, 0x0B, 0xB1, + 0x29, 0xAA, 0xAF, 0x85, 0xAA, 0x49, 0x58, 0xA8, 0xBF, 0x63, 0xA0, 0x38, + 0x91, 0xE6, 0xB3, 0xE6, 0x77, 0x68, 0xC4, 0xF9, 0x2A, 0x19, 0x84, 0xBB, + 0x0E, 0xE1, 0xF5, 0xAF, 0x89, 0xEC, 0xA5, 0x2F, 0x50, 0x20, 0x74, 0x1E, + 0x12, 0x41, 0x73, 0x1E, 0x24, 0xD9, 0xCA, 0xCE, 0x2C, 0xA1, 0x59, 0x35, + 0xC0, 0xC8, 0x1D, 0x46, 0x27, 0x61, 0x5A, 0x8F, 0xF9, 0x4D, 0xD3, 0x72, + 0x79, 0x66, 0x1E, 0x9F, 0x15, 0x90, 0x21, 0x2D, 0xFD, 0xED, 0x8B, 0x56, + 0x70, 0x03, 0x4A, 0x49, 0x3E, 0x7F, 0x69, 0x31, 0x12, 0x69, 0xC7, 0x1E, + 0x5C, 0xCA, 0x7A, 0x13, 0x8B, 0xE8, 0xE6, 0xF5, 0x60, 0x0F, 0xCC, 0x93, + 0x2C, 0x84, 0x7F, 0xF1, 0xFC, 0x6A, 0xFC, 0x9B, 0x47, 0x9D, 0xDB, 0xAD, + 0x88, 0x3D, 0xF3, 0x76, 0x75, 0x33, 0xD7, 0x4B, 0xA4, 0xC8, 0x8B, 0xF9, + 0xF5, 0x43, 0x58, 0x4F, 0xCB, 0xC8, 0x03, 0x54, 0x8F, 0xA5, 0x85, 0x78, + 0x04, 0x1A, 0xF3, 0x73, 0xF2, 0xD7, 0x87, 0x1D, 0x41, 0x9F, 0xE7, 0xD8, + 0x17, 0xCE, 0x1A, 0x9C, 0x0F, 0x4A, 0xFC, 0xDC, 0x44, 0x68, 0x54, 0x68, + 0xE2, 0x41, 0x3C, 0xFE, 0x2C, 0x84, 0x86, 0x37, 0x3C, 0xCD, 0x3F, 0x2F, + 0xA2, 0xDB, 0xE7, 0xF7, 0x54, 0x03, 0x5F, 0x59, 0xD3, 0xF7, 0x91, 0x78, + 0xC7, 0x8B, 0x77, 0x6A, 0x16, 0xE5, 0x49, 0x85, 0x90, 0x45, 0x72, 0x70, + 0x2F, 0x91, 0x5D, 0xF8, 0x3E, 0x65, 0x40, 0x0B, 0x19, 0x99, 0xC9, 0x26, + 0x20, 0x5A, 0x68, 0xC1, 0x35, 0xBF, 0x4F, 0xA7, 0x51, 0xF1, 0xD8, 0x11, + 0x2B, 0x5B, 0xE0, 0x9A, 0x9E, 0x28, 0x3B, 0x0A, 0x3A, 0x0A, 0x1F, 0xC1, + 0x81, 0xE5, 0x2E, 0xF0, 0xA6, 0xB9, 0x69, 0xA5, 0x88, 0x94, 0xE6, 0x6B, + 0x13, 0x7F, 0xD1, 0x64, 0x3F, 0x3D, 0x9C, 0x70, 0x46, 0xE5, 0xA2, 0x85, + 0x7B, 0x58, 0x84, 0x27, 0xDC, 0xC4, 0x80, 0x3E, 0x67, 0x9A, 0x9A, 0xC7, + 0x9A, 0x31, 0x0E, 0x30, 0xEC, 0xE6, 0x17, 0x40, 0x95, 0xD9, 0x45, 0xED, + 0x01, 0x96, 0xAA, 0xBF, 0x0C, 0xF3, 0x4B, 0xD1, 0x63, 0xF7, 0x13, 0x58, + 0xC0, 0xB8, 0xF3, 0xFA, 0x67, 0xDD, 0x9B, 0x7D, 0x6D, 0x4A, 0xFF, 0x32, + 0x4C, 0xB5, 0x25, 0x3B, 0xFF, 0x1C, 0x67, 0x0F, 0x85, 0x22, 0x59, 0x05, + 0x91, 0x91, 0x41, 0x77, 0x81, 0xD0, 0x85, 0x4C, 0x87, 0x10, 0x71, 0xFF, + 0x9E, 0x43, 0x1B, 0xAE, 0x95, 0x75, 0x2D, 0x81 +}; + +static const unsigned char TA731_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA732_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA732_EC_Q[] = { + 0x04, 0xF1, 0xB3, 0xCD, 0x38, 0xE4, 0x25, 0x43, 0xE5, 0xDE, 0x19, 0x09, + 0xBB, 0x81, 0x79, 0xA2, 0x15, 0x5F, 0x15, 0x63, 0x01, 0xDE, 0xC2, 0xAB, + 0xDD, 0xB3, 0xA6, 0x1B, 0x67, 0x4B, 0x80, 0x83, 0xAF, 0x99, 0xCB, 0xAC, + 0x17, 0xDB, 0x2B, 0x96, 0xCA, 0x7C, 0x52, 0x55, 0xE2, 0x1A, 0xE1, 0x3D, + 0x56, 0xF0, 0x2F, 0x16, 0x08, 0xFA, 0x15, 0xBC, 0x9B, 0xBB, 0x47, 0xE6, + 0x3F, 0xEE, 0xA8, 0xE1, 0x4C, 0x8C, 0xF5, 0xD3, 0x36, 0xF9, 0x38, 0x5D, + 0xAB, 0x70, 0x9A, 0x47, 0x0D, 0xE2, 0x81, 0x41, 0x06, 0xEB, 0x49, 0xF9, + 0xB0, 0x29, 0xDD, 0x33, 0xEC, 0x50, 0xA5, 0x7F, 0x79, 0x29, 0xB8, 0x20, + 0x98 +}; + +static const unsigned char TA733_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x28, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA733_RSA_N[] = { + 0xB9, 0x5D, 0x51, 0x28, 0x4B, 0x3C, 0x37, 0x92, 0xD1, 0x82, 0xCE, 0xBD, + 0x1D, 0xBD, 0xCD, 0xDD, 0xB8, 0xAB, 0xCF, 0x0A, 0x3E, 0xE1, 0x5D, 0xE5, + 0xDC, 0xAA, 0x09, 0xB9, 0x57, 0x02, 0x3E, 0xE6, 0x63, 0x61, 0xDF, 0xF2, + 0x0F, 0x82, 0x63, 0xAE, 0xA3, 0xF7, 0xAC, 0x73, 0xD1, 0x7C, 0xE7, 0xB3, + 0x0B, 0xAF, 0x08, 0x00, 0x09, 0x59, 0x7F, 0xCD, 0x29, 0x2A, 0x88, 0x93, + 0x87, 0x17, 0x18, 0x80, 0xED, 0x88, 0xB2, 0xB4, 0xB6, 0x10, 0x1F, 0x2D, + 0xD6, 0x5F, 0x55, 0xA2, 0x13, 0x5D, 0xD1, 0xC6, 0xEB, 0x06, 0x56, 0x89, + 0x88, 0xFE, 0xAC, 0x32, 0x9D, 0xFD, 0x5C, 0xC3, 0x05, 0xC7, 0x6E, 0xEE, + 0x86, 0x89, 0xBA, 0x88, 0x03, 0x9D, 0x72, 0x21, 0x86, 0x90, 0xAE, 0x8F, + 0x03, 0xA5, 0xDC, 0x9F, 0x88, 0x28, 0xCB, 0xA3, 0x92, 0x49, 0x0F, 0xEC, + 0xD0, 0x0F, 0xE2, 0x6D, 0x44, 0x4F, 0x80, 0x6A, 0xB2, 0xD4, 0xE7, 0xA0, + 0x0A, 0x53, 0x01, 0xBA, 0x8E, 0x97, 0x91, 0x76, 0x6E, 0xBC, 0xFC, 0xD5, + 0x6B, 0x36, 0xE6, 0x40, 0x88, 0xD6, 0x7B, 0x2F, 0x5F, 0x05, 0xE8, 0x2C, + 0x6D, 0x11, 0xF3, 0xE7, 0xB2, 0xBE, 0x92, 0x44, 0x4C, 0xD2, 0x97, 0xA4, + 0xFE, 0xD2, 0x72, 0x81, 0x43, 0x07, 0x9C, 0xE9, 0x11, 0x3E, 0xF5, 0x8B, + 0x1A, 0x59, 0x7D, 0x1F, 0x68, 0x58, 0xDD, 0x04, 0x00, 0x2C, 0x96, 0xF3, + 0x43, 0xB3, 0x7E, 0x98, 0x19, 0x74, 0xD9, 0x9C, 0x73, 0xD9, 0x18, 0xBE, + 0x41, 0xC7, 0x34, 0x79, 0xD9, 0xF4, 0x62, 0xC2, 0x43, 0xB9, 0xB3, 0x27, + 0xB0, 0x22, 0xCB, 0xF9, 0x3D, 0x52, 0xC7, 0x30, 0x47, 0xB3, 0xC9, 0x3E, + 0xB8, 0x6A, 0xE2, 0xE7, 0xE8, 0x81, 0x70, 0x5E, 0x42, 0x8B, 0x4F, 0x26, + 0xA5, 0xFE, 0x3A, 0xC2, 0x20, 0x6E, 0xBB, 0xF8, 0x16, 0x8E, 0xCD, 0x0C, + 0xA9, 0xB4, 0x1B, 0x6C, 0x76, 0x10, 0xE1, 0x58, 0x79, 0x46, 0x3E, 0x54, + 0xCE, 0x80, 0xA8, 0x57, 0x09, 0x37, 0x29, 0x1B, 0x99, 0x13, 0x8F, 0x0C, + 0xC8, 0xD6, 0x2C, 0x1C, 0xFB, 0x05, 0xE8, 0x08, 0x95, 0x3D, 0x65, 0x46, + 0xDC, 0xEE, 0xCD, 0x69, 0xE2, 0x4D, 0x8F, 0x87, 0x28, 0x4E, 0x34, 0x0B, + 0x3E, 0xCF, 0x14, 0xD9, 0xBB, 0xDD, 0xB6, 0x50, 0x9A, 0xAD, 0x77, 0xD4, + 0x19, 0xD6, 0xDA, 0x1A, 0x88, 0xC8, 0x4E, 0x1B, 0x27, 0x75, 0xD8, 0xB2, + 0x08, 0xF1, 0xAE, 0x83, 0x30, 0xB9, 0x11, 0x0E, 0xCD, 0x87, 0xF0, 0x84, + 0x8D, 0x15, 0x72, 0x7C, 0xA1, 0xEF, 0xCC, 0xF2, 0x88, 0x61, 0xBA, 0xF4, + 0x69, 0xBB, 0x0C, 0x8C, 0x0B, 0x75, 0x57, 0x04, 0xB8, 0x4E, 0x2A, 0x14, + 0x2E, 0x3D, 0x0F, 0x1C, 0x1E, 0x32, 0xA6, 0x62, 0x36, 0xEE, 0x66, 0xE2, + 0x22, 0xB8, 0x05, 0x40, 0x63, 0x10, 0x22, 0xF3, 0x33, 0x1D, 0x74, 0x72, + 0x8A, 0x2C, 0xF5, 0x39, 0x29, 0xA0, 0xD3, 0xE7, 0x1B, 0x80, 0x84, 0x2D, + 0xC5, 0x3D, 0xE3, 0x4D, 0xB1, 0xFD, 0x1A, 0x6F, 0xBA, 0x65, 0x07, 0x3B, + 0x58, 0xEC, 0x42, 0x45, 0x26, 0xFB, 0xD8, 0xDA, 0x25, 0x72, 0xC4, 0xF6, + 0x00, 0xB1, 0x22, 0x79, 0xBD, 0xE3, 0x7C, 0x59, 0x62, 0x4A, 0x9C, 0x05, + 0x6F, 0x3D, 0xCE, 0xE6, 0xD6, 0x47, 0x63, 0x99, 0xC6, 0x24, 0x6F, 0x72, + 0x12, 0xC8, 0xAC, 0x7F, 0x90, 0xB4, 0x0B, 0x91, 0x70, 0xE8, 0xB7, 0xE6, + 0x16, 0x10, 0x71, 0x17, 0xCE, 0xDE, 0x06, 0x4F, 0x48, 0x41, 0x7D, 0x35, + 0x4A, 0xA3, 0x89, 0xF2, 0xC9, 0x4B, 0x7B, 0x41, 0x11, 0x6D, 0x67, 0xB7, + 0x08, 0x98, 0x4C, 0xE5, 0x11, 0x19, 0xAE, 0x42, 0x80, 0xDC, 0xFB, 0x90, + 0x05, 0xD4, 0xF8, 0x50, 0xCA, 0xBE, 0xE4, 0xAD, 0xC7, 0xC2, 0x94, 0xD7, + 0x16, 0x9D, 0xE6, 0x17, 0x8F, 0xAF, 0x36, 0xFB +}; + +static const unsigned char TA733_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA734_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x32, 0x35, 0x36, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA734_EC_Q[] = { + 0x04, 0x7E, 0xFB, 0x6C, 0xE6, 0x23, 0xE3, 0x73, 0x32, 0x08, 0xCA, 0x60, + 0xE6, 0x53, 0x9C, 0xBA, 0x74, 0x8D, 0x18, 0xB0, 0x78, 0x90, 0x52, 0x80, + 0xDD, 0x38, 0xC0, 0x4A, 0x1D, 0xD1, 0xA8, 0xCC, 0x93, 0xA4, 0x97, 0x06, + 0x38, 0xCA, 0x0D, 0x15, 0x62, 0xC6, 0x8E, 0x01, 0x2A, 0x65, 0x9D, 0xAA, + 0xDF, 0x34, 0x91, 0x2E, 0x81, 0xC1, 0xE4, 0x33, 0x92, 0x31, 0xC4, 0xFD, + 0x09, 0x3A, 0xA6, 0x3F, 0xAD +}; + +static const unsigned char TA735_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA735_EC_Q[] = { + 0x04, 0x6B, 0xDA, 0x0D, 0x75, 0x35, 0x08, 0x31, 0x47, 0x05, 0xAE, 0x45, + 0x99, 0x55, 0xF1, 0x11, 0x13, 0x2E, 0x4A, 0xF8, 0x10, 0x31, 0x23, 0xA3, + 0x7E, 0x83, 0xD3, 0x7F, 0x28, 0x08, 0x3A, 0x26, 0x1A, 0x3A, 0xCF, 0x97, + 0x82, 0x1F, 0x80, 0xB7, 0x27, 0x09, 0x8F, 0xD1, 0x8E, 0x30, 0xC4, 0x0A, + 0x9B, 0x0E, 0xAC, 0x58, 0x04, 0xAB, 0xF7, 0x36, 0x7D, 0x94, 0x23, 0xA4, + 0x9B, 0x0A, 0x8A, 0x8B, 0xAB, 0xEB, 0xFD, 0x39, 0x25, 0x66, 0xF1, 0x5E, + 0xFE, 0x8C, 0xAE, 0x8D, 0x41, 0x79, 0x9D, 0x09, 0x60, 0xCE, 0x28, 0xA9, + 0xD3, 0x8A, 0x6D, 0xF3, 0xD6, 0x45, 0xD4, 0xF2, 0x98, 0x84, 0x38, 0x65, + 0xA0 +}; + +static const unsigned char TA736_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x32 +}; + +static const unsigned char TA736_RSA_N[] = { + 0xAA, 0x5F, 0xDA, 0x1B, 0x5F, 0xE8, 0x73, 0x91, 0xE5, 0xDA, 0x5C, 0xF4, + 0xA2, 0xE6, 0x47, 0xE5, 0xF3, 0x68, 0x55, 0x60, 0x05, 0x1D, 0x02, 0xA4, + 0xB3, 0x9B, 0x59, 0xF3, 0x1E, 0x8A, 0xAF, 0x34, 0xAD, 0xFC, 0x0D, 0xC2, + 0xD9, 0x48, 0x19, 0xEE, 0x69, 0x8F, 0xC9, 0x20, 0xFC, 0x21, 0xAA, 0x07, + 0x19, 0xED, 0xB0, 0x5C, 0xAC, 0x65, 0xC7, 0x5F, 0xED, 0x02, 0x7C, 0x7B, + 0x7C, 0x2D, 0x1B, 0xD6, 0xBA, 0xB9, 0x80, 0xC2, 0x18, 0x82, 0x16, 0x84, + 0xFA, 0x66, 0xB0, 0x08, 0xC6, 0x54, 0x23, 0x81, 0xE4, 0xCD, 0xB9, 0x49, + 0x3F, 0xF6, 0x4F, 0x6E, 0x37, 0x48, 0x28, 0x38, 0x0F, 0xC5, 0xBE, 0xE7, + 0x68, 0x70, 0xFD, 0x39, 0x97, 0x4D, 0xD2, 0xC7, 0x98, 0x91, 0x50, 0xAA, + 0xC4, 0x44, 0xB3, 0x23, 0x7D, 0x39, 0x47, 0xE9, 0x52, 0x62, 0xD6, 0x12, + 0x93, 0x5E, 0xB7, 0x31, 0x96, 0x42, 0x05, 0xFB, 0x76, 0xA7, 0x1E, 0xA3, + 0xF5, 0xC2, 0xFC, 0xE9, 0x7A, 0xC5, 0x6C, 0xA9, 0x71, 0x4F, 0xEA, 0xCB, + 0x78, 0xBC, 0x60, 0xAF, 0xC7, 0xDE, 0xF4, 0xD9, 0xCB, 0xBE, 0x7E, 0x33, + 0xA5, 0x6E, 0x94, 0x83, 0xF0, 0x34, 0xFA, 0x21, 0xAB, 0xEA, 0x8E, 0x72, + 0xA0, 0x3F, 0xA4, 0xDE, 0x30, 0x5B, 0xEF, 0x86, 0x4D, 0x6A, 0x95, 0x5B, + 0x43, 0x44, 0xA8, 0x10, 0x15, 0x1C, 0xE5, 0x01, 0x57, 0xC5, 0x98, 0xF1, + 0xE6, 0x06, 0x28, 0x91, 0xAA, 0x20, 0xC5, 0xB7, 0x53, 0x26, 0x51, 0x43, + 0xB2, 0x0B, 0x11, 0x95, 0x58, 0xE1, 0xC0, 0x0F, 0x76, 0xD9, 0xC0, 0x8D, + 0x7C, 0x81, 0xF3, 0x72, 0x70, 0x9E, 0x6F, 0xFE, 0x1A, 0x8E, 0xD9, 0x5F, + 0x35, 0xC6, 0xB2, 0x6F, 0x34, 0x7C, 0xBE, 0x48, 0x4F, 0xE2, 0x5A, 0x39, + 0xD7, 0xD8, 0x9D, 0x78, 0x9E, 0x9F, 0x86, 0x3E, 0x03, 0x5E, 0x19, 0x8B, + 0x44, 0xA2, 0xD5, 0xC7 +}; + +static const unsigned char TA736_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA737_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x33 +}; + +static const unsigned char TA737_RSA_N[] = { + 0xBD, 0x75, 0x93, 0xF0, 0x62, 0x22, 0x6F, 0x24, 0xAE, 0xE0, 0x7A, 0x76, + 0xAC, 0x7D, 0xBD, 0xD9, 0x24, 0xD5, 0xB8, 0xB7, 0xFC, 0xCD, 0xF0, 0x42, + 0xE0, 0xEB, 0x78, 0x88, 0x56, 0x5E, 0x9B, 0x9A, 0x54, 0x1D, 0x4D, 0x0C, + 0x8A, 0xF6, 0xD3, 0xCF, 0x70, 0xF4, 0x52, 0xB5, 0xD8, 0x93, 0x04, 0xE3, + 0x46, 0x86, 0x71, 0x41, 0x4A, 0x2B, 0xF0, 0x2A, 0x2C, 0x55, 0x03, 0xD6, + 0x48, 0xC3, 0xE0, 0x39, 0x38, 0xED, 0xF2, 0x5C, 0x3C, 0x3F, 0x44, 0xBC, + 0x93, 0x3D, 0x61, 0xAB, 0x4E, 0xCD, 0x0D, 0xBE, 0xF0, 0x20, 0x27, 0x58, + 0x0E, 0x44, 0x7F, 0x04, 0x1A, 0x87, 0xA5, 0xD7, 0x96, 0x14, 0x36, 0x90, + 0xD0, 0x49, 0x7B, 0xA1, 0x75, 0xFB, 0x1A, 0x6B, 0x73, 0xB1, 0xF8, 0xCE, + 0xA9, 0x09, 0x2C, 0xF2, 0x53, 0xD5, 0xC3, 0x14, 0x44, 0xB8, 0x86, 0xA5, + 0xF6, 0x8B, 0x2B, 0x39, 0xDA, 0xA3, 0x33, 0x54, 0xD9, 0xFA, 0x72, 0x1A, + 0xF7, 0x22, 0x15, 0x1C, 0x88, 0x91, 0x6B, 0x7F, 0x66, 0xE5, 0xC3, 0x6A, + 0x80, 0xB0, 0x24, 0xF3, 0xDF, 0x86, 0x45, 0x88, 0xFD, 0x19, 0x7F, 0x75, + 0x87, 0x1F, 0x1F, 0xB1, 0x1B, 0x0A, 0x73, 0x24, 0x5B, 0xB9, 0x65, 0xE0, + 0x2C, 0x54, 0xC8, 0x60, 0xD3, 0x66, 0x17, 0x3F, 0xE1, 0xCC, 0x54, 0x33, + 0x73, 0x91, 0x02, 0x3A, 0xA6, 0x7F, 0x7B, 0x76, 0x39, 0xA2, 0x1F, 0x96, + 0xB6, 0x38, 0xAE, 0xB5, 0xC8, 0x93, 0x74, 0x1D, 0x9E, 0xB9, 0xB4, 0xE5, + 0x60, 0x9D, 0x2F, 0x56, 0xD1, 0xE0, 0xEB, 0x5E, 0x5B, 0x4C, 0x12, 0x70, + 0x0C, 0x6C, 0x44, 0x20, 0xAB, 0x11, 0xD8, 0xF4, 0x19, 0xF6, 0xD2, 0x9C, + 0x52, 0x37, 0xE7, 0xFA, 0xB6, 0xC2, 0x31, 0x3B, 0x4A, 0xD4, 0x14, 0x99, + 0xAD, 0xC7, 0x1A, 0xF5, 0x5D, 0x5F, 0xFA, 0x07, 0xB8, 0x7C, 0x0D, 0x1F, + 0xD6, 0x83, 0x1E, 0xB3 +}; + +static const unsigned char TA737_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA738_DN[] = { + 0x30, 0x81, 0xD2, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x54, 0x52, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x0F, 0x47, 0x65, 0x62, 0x7A, 0x65, 0x20, 0x2D, 0x20, 0x4B, + 0x6F, 0x63, 0x61, 0x65, 0x6C, 0x69, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x13, 0x39, 0x54, 0x75, 0x72, 0x6B, 0x69, 0x79, 0x65, + 0x20, 0x42, 0x69, 0x6C, 0x69, 0x6D, 0x73, 0x65, 0x6C, 0x20, 0x76, 0x65, + 0x20, 0x54, 0x65, 0x6B, 0x6E, 0x6F, 0x6C, 0x6F, 0x6A, 0x69, 0x6B, 0x20, + 0x41, 0x72, 0x61, 0x73, 0x74, 0x69, 0x72, 0x6D, 0x61, 0x20, 0x4B, 0x75, + 0x72, 0x75, 0x6D, 0x75, 0x20, 0x2D, 0x20, 0x54, 0x55, 0x42, 0x49, 0x54, + 0x41, 0x4B, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x24, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x6B, 0x61, 0x73, 0x79, 0x6F, 0x6E, 0x20, 0x4D, 0x65, 0x72, 0x6B, + 0x65, 0x7A, 0x69, 0x20, 0x2D, 0x20, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, + 0x4D, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, + 0x54, 0x55, 0x42, 0x49, 0x54, 0x41, 0x4B, 0x20, 0x4B, 0x61, 0x6D, 0x75, + 0x20, 0x53, 0x4D, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x4B, 0x6F, 0x6B, 0x20, + 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6B, 0x61, 0x73, 0x69, 0x20, + 0x2D, 0x20, 0x53, 0x75, 0x72, 0x75, 0x6D, 0x20, 0x31 +}; + +static const unsigned char TA738_RSA_N[] = { + 0xAF, 0x75, 0x30, 0x33, 0xAA, 0xBB, 0x6B, 0xD3, 0x99, 0x2C, 0x12, 0x37, + 0x84, 0xD9, 0x8D, 0x7B, 0x97, 0x80, 0xD3, 0x6E, 0xE7, 0xFF, 0x9B, 0x50, + 0x95, 0x3E, 0x90, 0x95, 0x56, 0x42, 0xD7, 0x19, 0x7C, 0x26, 0x84, 0x8D, + 0x92, 0xFA, 0x01, 0x1D, 0x3A, 0x0F, 0xE2, 0x64, 0x38, 0xB7, 0x8C, 0xBC, + 0xE8, 0x88, 0xF9, 0x8B, 0x24, 0xAB, 0x2E, 0xA3, 0xF5, 0x37, 0xE4, 0x40, + 0x8E, 0x18, 0x25, 0x79, 0x83, 0x75, 0x1F, 0x3B, 0xFF, 0x6C, 0xA8, 0xC5, + 0xC6, 0x56, 0xF8, 0xB4, 0xED, 0x8A, 0x44, 0xA3, 0xAB, 0x6C, 0x4C, 0xFC, + 0x1D, 0xD0, 0xDC, 0xEF, 0x68, 0xBD, 0xCF, 0xE4, 0xAA, 0xCE, 0xF0, 0x55, + 0xF7, 0xA2, 0x34, 0xD4, 0x83, 0x6B, 0x37, 0x7C, 0x1C, 0xC2, 0xFE, 0xB5, + 0x03, 0xEC, 0x57, 0xCE, 0xBC, 0xB4, 0xB5, 0xC5, 0xED, 0x00, 0x0F, 0x53, + 0x37, 0x2A, 0x4D, 0xF4, 0x4F, 0x0C, 0x83, 0xFB, 0x86, 0xCF, 0xCB, 0xFE, + 0x8C, 0x4E, 0xBD, 0x87, 0xF9, 0xA7, 0x8B, 0x21, 0x57, 0x9C, 0x7A, 0xDF, + 0x03, 0x67, 0x89, 0x2C, 0x9D, 0x97, 0x61, 0xA7, 0x10, 0xB8, 0x55, 0x90, + 0x7F, 0x0E, 0x2D, 0x27, 0x38, 0x74, 0xDF, 0xE7, 0xFD, 0xDA, 0x4E, 0x12, + 0xE3, 0x4D, 0x15, 0x22, 0x02, 0xC8, 0xE0, 0xE0, 0xFC, 0x0F, 0xAD, 0x8A, + 0xD7, 0xC9, 0x54, 0x50, 0xCC, 0x3B, 0x0F, 0xCA, 0x16, 0x80, 0x84, 0xD0, + 0x51, 0x56, 0xC3, 0x8E, 0x56, 0x7F, 0x89, 0x22, 0x33, 0x2F, 0xE6, 0x85, + 0x0A, 0xBD, 0xA5, 0xA8, 0x1B, 0x36, 0xDE, 0xD3, 0xDC, 0x2C, 0x6D, 0x3B, + 0xC7, 0x13, 0xBD, 0x59, 0x23, 0x2C, 0xE6, 0xE5, 0xA4, 0xF7, 0xD8, 0x0B, + 0xED, 0xEA, 0x90, 0x40, 0x44, 0xA8, 0x95, 0xBB, 0x93, 0xD5, 0xD0, 0x80, + 0x34, 0xB6, 0x46, 0x78, 0x0E, 0x1F, 0x00, 0x93, 0x46, 0xE1, 0xEE, 0xE9, + 0xF9, 0xEC, 0x4F, 0x17 +}; + +static const unsigned char TA738_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA739_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x4E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4E, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x65, 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x71, 0x75, 0x65, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, + 0x75, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA739_RSA_N[] = { + 0xC3, 0xCD, 0xD3, 0xFC, 0xBD, 0x04, 0x53, 0xDD, 0x0C, 0x20, 0x3A, 0xD5, + 0x88, 0x2E, 0x05, 0x4B, 0x41, 0xF5, 0x83, 0x82, 0x7E, 0xF7, 0x59, 0x9F, + 0x9E, 0x9E, 0x63, 0xE8, 0x73, 0xDA, 0xF6, 0x06, 0xA9, 0x4F, 0x1F, 0xB4, + 0xF9, 0x0B, 0x1F, 0x39, 0x8C, 0x9A, 0x20, 0xD0, 0x7E, 0x06, 0xD4, 0xEC, + 0x34, 0xD9, 0x86, 0xBC, 0x75, 0x5B, 0x87, 0x88, 0xF0, 0xD2, 0xD9, 0xD4, + 0xA3, 0x0A, 0xB2, 0x6C, 0x1B, 0xEB, 0x49, 0x2C, 0x3E, 0xAC, 0x5D, 0xD8, + 0x94, 0x03, 0xA0, 0xEC, 0x34, 0xE5, 0x30, 0xC4, 0x35, 0x7D, 0xFB, 0x26, + 0x4D, 0x1B, 0x6E, 0x30, 0x54, 0xD8, 0xF5, 0x80, 0x45, 0x9C, 0x39, 0xAD, + 0x9C, 0xC9, 0x25, 0x04, 0x4D, 0x9A, 0x90, 0x3E, 0x4E, 0x40, 0x6E, 0x8A, + 0x6B, 0xCD, 0x29, 0x67, 0xC6, 0xCC, 0x2D, 0xE0, 0x74, 0xE8, 0x05, 0x57, + 0x0A, 0x48, 0x50, 0xFA, 0x7A, 0x43, 0xDA, 0x7E, 0xEC, 0x5B, 0x9A, 0x0E, + 0x62, 0x76, 0xFE, 0xEA, 0x9D, 0x1D, 0x85, 0x72, 0xEC, 0x11, 0xBB, 0x35, + 0xE8, 0x1F, 0x27, 0xBF, 0xC1, 0xA1, 0xC7, 0xBB, 0x48, 0x16, 0xDD, 0x56, + 0xD7, 0xCC, 0x4E, 0xA0, 0xE1, 0xB9, 0xAC, 0xDB, 0xD5, 0x83, 0x19, 0x1A, + 0x85, 0xD1, 0x94, 0x97, 0xD7, 0xCA, 0xA3, 0x65, 0x0B, 0xF3, 0x38, 0xF9, + 0x02, 0xAE, 0xDD, 0xF6, 0x67, 0xCF, 0xC9, 0x3F, 0xF5, 0x8A, 0x2C, 0x47, + 0x1A, 0x99, 0x6F, 0x05, 0x0D, 0xFD, 0xD0, 0x1D, 0x82, 0x31, 0xFC, 0x29, + 0xCC, 0x00, 0x58, 0x97, 0x91, 0x4C, 0x80, 0x00, 0x1C, 0x33, 0x85, 0x96, + 0x2F, 0xCB, 0x41, 0xC2, 0x8B, 0x10, 0x84, 0xC3, 0x09, 0x24, 0x89, 0x1F, + 0xB5, 0x0F, 0xD9, 0xD9, 0x77, 0x47, 0x18, 0x92, 0x94, 0x60, 0x5C, 0xC7, + 0x99, 0x03, 0x3C, 0xFE, 0xF7, 0x95, 0xA7, 0x7D, 0x50, 0xA1, 0x80, 0xC2, + 0xA9, 0x83, 0xAD, 0x58, 0x96, 0x55, 0x21, 0xDB, 0x86, 0x59, 0xD4, 0xAF, + 0xC6, 0xBC, 0xDD, 0x81, 0x6E, 0x07, 0xDB, 0x60, 0x62, 0xFE, 0xEC, 0x10, + 0x6E, 0xDA, 0x68, 0x01, 0xF4, 0x83, 0x1B, 0xA9, 0x3E, 0xA2, 0x5B, 0x23, + 0xD7, 0x64, 0xC6, 0xDF, 0xDC, 0xA2, 0x7D, 0xD8, 0x4B, 0xBA, 0x82, 0xD2, + 0x51, 0xF8, 0x66, 0xBF, 0x06, 0x46, 0xE4, 0x79, 0x2A, 0x26, 0x36, 0x79, + 0x8F, 0x1F, 0x4E, 0x99, 0x1D, 0xB2, 0x8F, 0x0C, 0x0E, 0x1C, 0xFF, 0xC9, + 0x5D, 0xC0, 0xFD, 0x90, 0x10, 0xA6, 0xB1, 0x37, 0xF3, 0xCD, 0x3A, 0x24, + 0x6E, 0xB4, 0x85, 0x90, 0xBF, 0x80, 0xB9, 0x0C, 0x8C, 0xD5, 0x9B, 0xD6, + 0xC8, 0xF1, 0x56, 0x3F, 0x1A, 0x80, 0x89, 0x7A, 0xA9, 0xE2, 0x1B, 0x32, + 0x51, 0x2C, 0x3E, 0xF2, 0xDF, 0x7B, 0xF6, 0x5D, 0x7A, 0x29, 0x19, 0x8E, + 0xE5, 0xC8, 0xBD, 0x36, 0x71, 0x8B, 0x5D, 0x4C, 0xC2, 0x1D, 0x3F, 0xAD, + 0x58, 0xA2, 0xCF, 0x3D, 0x70, 0x4D, 0xA6, 0x50, 0x98, 0x25, 0xDC, 0x23, + 0xF9, 0xB8, 0x58, 0x41, 0x08, 0x71, 0xBF, 0x4F, 0xB8, 0x84, 0xA0, 0x8F, + 0x00, 0x54, 0x15, 0xFC, 0x91, 0x6D, 0x58, 0xA7, 0x96, 0x3B, 0xEB, 0x4B, + 0x96, 0x27, 0xCD, 0x6B, 0xA2, 0xA1, 0x86, 0xAC, 0x0D, 0x7C, 0x54, 0xE6, + 0x66, 0x4C, 0x66, 0x5F, 0x90, 0xBE, 0x21, 0x9A, 0x02, 0x46, 0x2D, 0xE4, + 0x83, 0xC2, 0x80, 0xB9, 0xCF, 0x4B, 0x3E, 0xE8, 0x7F, 0x3C, 0x01, 0xEC, + 0x8F, 0x5E, 0xCD, 0x7F, 0xD2, 0x28, 0x42, 0x01, 0x95, 0x8A, 0xE2, 0x97, + 0x3D, 0x10, 0x21, 0x7D, 0xF6, 0x9D, 0x1C, 0xC5, 0x34, 0xA1, 0xEC, 0x2C, + 0x0E, 0x0A, 0x52, 0x2C, 0x12, 0x55, 0x70, 0x24, 0x3D, 0xCB, 0xC2, 0x14, + 0x35, 0x43, 0x5D, 0x27, 0x4E, 0xBE, 0xC0, 0xBD, 0xAA, 0x7C, 0x96, 0xE7, + 0xFC, 0x9E, 0x61, 0xAD, 0x44, 0xD3, 0x00, 0x97 +}; + +static const unsigned char TA739_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA740_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x54, 0x57, 0x43, 0x41, 0x20, 0x43, 0x59, 0x42, + 0x45, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA740_RSA_N[] = { + 0xC6, 0xF8, 0xCA, 0x1E, 0xD9, 0x09, 0x20, 0x7E, 0x1D, 0x6C, 0x4E, 0xCE, + 0x8F, 0xE3, 0x47, 0x33, 0x44, 0x9C, 0xC7, 0xC9, 0x69, 0xAA, 0x3A, 0x5B, + 0x78, 0xEE, 0x70, 0xD2, 0x92, 0xF8, 0x04, 0xB3, 0x52, 0x52, 0x1D, 0x67, + 0x72, 0x28, 0xA1, 0xDF, 0x8B, 0x5D, 0x95, 0x0A, 0xFE, 0xEA, 0xCD, 0xED, + 0xF7, 0x29, 0xCE, 0xF0, 0x6F, 0x7F, 0xAC, 0xCD, 0x3D, 0xEF, 0xB3, 0x1C, + 0x45, 0x6A, 0xF7, 0x28, 0x90, 0xF1, 0x61, 0x57, 0xC5, 0x0C, 0xC4, 0xA3, + 0x50, 0x5D, 0xDE, 0xD4, 0xB5, 0xCB, 0x19, 0xCA, 0x80, 0xB9, 0x75, 0xCE, + 0x29, 0xCE, 0xD2, 0x85, 0x22, 0xEC, 0x02, 0x63, 0xCC, 0x44, 0x30, 0x20, + 0xDA, 0xEA, 0x91, 0x5B, 0x56, 0xE6, 0x1D, 0x1C, 0xD5, 0x9D, 0x66, 0xC7, + 0x3F, 0xDF, 0x86, 0xCA, 0x4B, 0x53, 0xC4, 0xD9, 0x8D, 0xB2, 0x1D, 0xEA, + 0xF8, 0xDC, 0x27, 0x53, 0xA3, 0x47, 0xE1, 0x61, 0xCC, 0x7D, 0xB5, 0xB0, + 0xF8, 0xEE, 0x73, 0x91, 0xC5, 0xCE, 0x73, 0x6F, 0xCE, 0xEE, 0x10, 0x1F, + 0x1A, 0x06, 0xCF, 0xE9, 0x27, 0x60, 0xC5, 0x4F, 0x19, 0xE4, 0xEB, 0xCE, + 0x22, 0x26, 0x45, 0xD7, 0x60, 0x99, 0xDD, 0xCE, 0x4F, 0x37, 0xE0, 0x7F, + 0xE7, 0x63, 0xAD, 0xB0, 0xB8, 0x59, 0xB8, 0xD0, 0x06, 0x68, 0x35, 0x60, + 0xD3, 0x36, 0xAE, 0x71, 0x43, 0x04, 0xF1, 0x69, 0x65, 0x78, 0x7C, 0xF3, + 0x1F, 0xF3, 0xCA, 0x28, 0x9F, 0x5A, 0x20, 0x95, 0x66, 0xB4, 0xCD, 0xB7, + 0xEE, 0x8F, 0x78, 0xA4, 0x45, 0x18, 0xE9, 0x26, 0x2F, 0x8D, 0x9B, 0x29, + 0x28, 0xB1, 0xA4, 0xB7, 0x3A, 0x6D, 0xB9, 0xD4, 0x1C, 0x38, 0x72, 0x45, + 0x58, 0xB1, 0x5E, 0xEB, 0xF0, 0x28, 0x9B, 0xB7, 0x82, 0xCA, 0xFD, 0xCF, + 0xD6, 0x33, 0x0F, 0x9F, 0xFB, 0x97, 0x9E, 0xB1, 0x1C, 0x9C, 0x9E, 0xEA, + 0x5F, 0x5E, 0xDB, 0xAA, 0xDD, 0x54, 0xE9, 0x30, 0x21, 0x28, 0x6D, 0x8E, + 0x79, 0xF3, 0x75, 0x92, 0x8C, 0x26, 0xFE, 0xDC, 0xC5, 0xF6, 0xC3, 0xB0, + 0xDF, 0x44, 0x59, 0x43, 0xA3, 0xB6, 0x03, 0x28, 0xF6, 0x08, 0x30, 0xAA, + 0x0D, 0x33, 0xE1, 0xEF, 0x9C, 0xA9, 0x07, 0x22, 0xE3, 0x59, 0x5B, 0x40, + 0x8F, 0xDA, 0x88, 0xB7, 0x69, 0x08, 0xA8, 0xB7, 0x23, 0x2E, 0x44, 0x09, + 0x59, 0x37, 0x5B, 0xC7, 0xE3, 0x17, 0xF2, 0x22, 0xEB, 0x6E, 0x39, 0x52, + 0xC5, 0xDE, 0x54, 0xA7, 0x98, 0xC9, 0x4B, 0x20, 0x95, 0xDC, 0x46, 0x89, + 0x5F, 0xB4, 0x12, 0xF9, 0x85, 0x29, 0x8E, 0xEB, 0xC8, 0x27, 0x15, 0x20, + 0xC0, 0x4B, 0xD4, 0xCC, 0x7C, 0x0C, 0x6C, 0x34, 0x0C, 0x26, 0x9B, 0x26, + 0x31, 0xA6, 0x3C, 0xA7, 0xF6, 0xD9, 0xD0, 0x4B, 0xA2, 0x64, 0xFF, 0x3B, + 0x99, 0x41, 0x72, 0xC1, 0xE0, 0x70, 0x97, 0xF1, 0x24, 0xBB, 0x2B, 0xC4, + 0x74, 0x22, 0xB1, 0xAC, 0x6B, 0x22, 0x32, 0x24, 0xD3, 0x78, 0x2A, 0xC0, + 0xC0, 0xA1, 0x2F, 0xF1, 0x52, 0x05, 0xC9, 0x3F, 0xEF, 0x76, 0x66, 0xE2, + 0x45, 0xD8, 0x0D, 0x3D, 0xAD, 0x95, 0xC8, 0xC7, 0x89, 0x26, 0xC8, 0x0F, + 0xAE, 0xA7, 0x03, 0x2E, 0xFB, 0xC1, 0x5F, 0xFA, 0x20, 0xE1, 0x70, 0xAD, + 0xB0, 0x65, 0x20, 0x37, 0x33, 0x60, 0xB0, 0xD5, 0xAF, 0xD7, 0x0C, 0x1C, + 0xC2, 0x90, 0x70, 0xD7, 0x4A, 0x18, 0xBC, 0x7E, 0x01, 0xB0, 0xB0, 0xEB, + 0x15, 0x1E, 0x44, 0x06, 0xCD, 0xA4, 0x4F, 0xE8, 0x0C, 0xD1, 0xC3, 0x20, + 0x10, 0xE1, 0x54, 0x65, 0x9E, 0xB6, 0x51, 0xD0, 0x1A, 0x76, 0x6B, 0x42, + 0x5A, 0x58, 0x76, 0x34, 0xEA, 0xB7, 0x37, 0x19, 0xAE, 0x2E, 0x75, 0xF9, + 0x96, 0xE5, 0xC1, 0x59, 0xF7, 0x94, 0x57, 0x29, 0x25, 0x8D, 0x3A, 0x4C, + 0xAB, 0x4D, 0x9A, 0x41, 0xD0, 0x5F, 0x26, 0x03 +}; + +static const unsigned char TA740_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA741_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x13, 0x54, 0x57, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, + 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA741_RSA_N[] = { + 0xB0, 0x05, 0xDB, 0xC8, 0xEB, 0x8C, 0xC4, 0x6E, 0x8A, 0x21, 0xEF, 0x8E, + 0x4D, 0x9C, 0x71, 0x0A, 0x1F, 0x52, 0x70, 0xED, 0x6D, 0x82, 0x9C, 0x97, + 0xC5, 0xD7, 0x4C, 0x4E, 0x45, 0x49, 0xCB, 0x40, 0x42, 0xB5, 0x12, 0x34, + 0x6C, 0x19, 0xC2, 0x74, 0xA4, 0x31, 0x5F, 0x85, 0x02, 0x97, 0xEC, 0x43, + 0x33, 0x0A, 0x53, 0xD2, 0x9C, 0x8C, 0x8E, 0xB7, 0xB8, 0x79, 0xDB, 0x2B, + 0xD5, 0x6A, 0xF2, 0x8E, 0x66, 0xC4, 0xEE, 0x2B, 0x01, 0x07, 0x92, 0xD4, + 0xB3, 0xD0, 0x02, 0xDF, 0x50, 0xF6, 0x55, 0xAF, 0x66, 0x0E, 0xCB, 0xE0, + 0x47, 0x60, 0x2F, 0x2B, 0x32, 0x39, 0x35, 0x52, 0x3A, 0x28, 0x83, 0xF8, + 0x7B, 0x16, 0xC6, 0x18, 0xB8, 0x62, 0xD6, 0x47, 0x25, 0x91, 0xCE, 0xF0, + 0x19, 0x12, 0x4D, 0xAD, 0x63, 0xF5, 0xD3, 0x3F, 0x75, 0x5F, 0x29, 0xF0, + 0xA1, 0x30, 0x1C, 0x2A, 0xA0, 0x98, 0xA6, 0x15, 0xBD, 0xEE, 0xFD, 0x19, + 0x36, 0xF0, 0xE2, 0x91, 0x43, 0x8F, 0xFA, 0xCA, 0xD6, 0x10, 0x27, 0x49, + 0x4C, 0xEF, 0xDD, 0xC1, 0xF1, 0x85, 0x70, 0x9B, 0xCA, 0xEA, 0xA8, 0x5A, + 0x43, 0xFC, 0x6D, 0x86, 0x6F, 0x73, 0xE9, 0x37, 0x45, 0xA9, 0xF0, 0x36, + 0xC7, 0xCC, 0x88, 0x75, 0x1E, 0xBB, 0x6C, 0x06, 0xFF, 0x9B, 0x6B, 0x3E, + 0x17, 0xEC, 0x61, 0xAA, 0x71, 0x7C, 0xC6, 0x1D, 0xA2, 0xF7, 0x49, 0xE9, + 0x15, 0xB5, 0x3C, 0xD6, 0xA1, 0x61, 0xF5, 0x11, 0xF7, 0x05, 0x6F, 0x1D, + 0xFD, 0x11, 0xBE, 0xD0, 0x30, 0x07, 0xC2, 0x29, 0xB0, 0x09, 0x4E, 0x26, + 0xDC, 0xE3, 0xA2, 0xA8, 0x91, 0x6A, 0x1F, 0xC2, 0x91, 0x45, 0x88, 0x5C, + 0xE5, 0x98, 0xB8, 0x71, 0xA5, 0x15, 0x19, 0xC9, 0x7C, 0x75, 0x11, 0xCC, + 0x70, 0x74, 0x4F, 0x2D, 0x9B, 0x1D, 0x91, 0x44, 0xFD, 0x56, 0x28, 0xA0, + 0xFE, 0xBB, 0x86, 0x6A, 0xC8, 0xFA, 0x5C, 0x0B, 0x58, 0xDC, 0xC6, 0x4B, + 0x76, 0xC8, 0xAB, 0x22, 0xD9, 0x73, 0x0F, 0xA5, 0xF4, 0x5A, 0x02, 0x89, + 0x3F, 0x4F, 0x9E, 0x22, 0x82, 0xEE, 0xA2, 0x74, 0x53, 0x2A, 0x3D, 0x53, + 0x27, 0x69, 0x1D, 0x6C, 0x8E, 0x32, 0x2C, 0x64, 0x00, 0x26, 0x63, 0x61, + 0x36, 0x4E, 0xA3, 0x46, 0xB7, 0x3F, 0x7D, 0xB3, 0x2D, 0xAC, 0x6D, 0x90, + 0xA2, 0x95, 0xA2, 0xCE, 0xCF, 0xDA, 0x82, 0xE7, 0x07, 0x34, 0x19, 0x96, + 0xE9, 0xB8, 0x21, 0xAA, 0x29, 0x7E, 0xA6, 0x38, 0xBE, 0x8E, 0x29, 0x4A, + 0x21, 0x66, 0x79, 0x1F, 0xB3, 0xC3, 0xB5, 0x09, 0x67, 0xDE, 0xD6, 0xD4, + 0x07, 0x46, 0xF3, 0x2A, 0xDA, 0xE6, 0x22, 0x37, 0x60, 0xCB, 0x81, 0xB6, + 0x0F, 0xA0, 0x0F, 0xE9, 0xC8, 0x95, 0x7F, 0xBF, 0x55, 0x91, 0x05, 0x7A, + 0xCF, 0x3D, 0x15, 0xC0, 0x6F, 0xDE, 0x09, 0x94, 0x01, 0x83, 0xD7, 0x34, + 0x1B, 0xCC, 0x40, 0xA5, 0xF0, 0xB8, 0x9B, 0x67, 0xD5, 0x98, 0x91, 0x3B, + 0xA7, 0x84, 0x78, 0x95, 0x26, 0xA4, 0x5A, 0x08, 0xF8, 0x2B, 0x74, 0xB4, + 0x00, 0x04, 0x3C, 0xDF, 0xB8, 0x14, 0x8E, 0xE8, 0xDF, 0xA9, 0x8D, 0x6C, + 0x67, 0x92, 0x33, 0x1D, 0xC0, 0xB7, 0xD2, 0xEC, 0x92, 0xC8, 0xBE, 0x09, + 0xBF, 0x2C, 0x29, 0x05, 0x6F, 0x02, 0x6B, 0x9E, 0xEF, 0xBC, 0xBF, 0x2A, + 0xBC, 0x5B, 0xC0, 0x50, 0x8F, 0x41, 0x70, 0x71, 0x87, 0xB2, 0x4D, 0xB7, + 0x04, 0xA9, 0x84, 0xA3, 0x32, 0xAF, 0xAE, 0xEE, 0x6B, 0x17, 0x8B, 0xB2, + 0xB1, 0xFE, 0x6C, 0xE1, 0x90, 0x8C, 0x88, 0xA8, 0x97, 0x48, 0xCE, 0xC8, + 0x4D, 0xCB, 0xF3, 0x06, 0xCF, 0x5F, 0x6A, 0x0A, 0x42, 0xB1, 0x1E, 0x1E, + 0x77, 0x2F, 0x8E, 0xA0, 0xE6, 0x92, 0x0E, 0x06, 0xFC, 0x05, 0x22, 0xD2, + 0x26, 0xE1, 0x31, 0x51, 0x7D, 0x32, 0xDC, 0x0F +}; + +static const unsigned char TA741_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA742_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x21, 0x54, 0x57, 0x43, 0x41, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA742_RSA_N[] = { + 0xB0, 0x7E, 0x72, 0xB8, 0xA4, 0x03, 0x94, 0xE6, 0xA7, 0xDE, 0x09, 0x38, + 0x91, 0x4A, 0x11, 0x40, 0x87, 0xA7, 0x7C, 0x59, 0x64, 0x14, 0x7B, 0xB5, + 0x11, 0x10, 0xDD, 0xFE, 0xBF, 0xD5, 0xC0, 0xBB, 0x56, 0xE2, 0x85, 0x25, + 0xF4, 0x35, 0x72, 0x0F, 0xF8, 0x53, 0xD0, 0x41, 0xE1, 0x44, 0x01, 0xC2, + 0xB4, 0x1C, 0xC3, 0x31, 0x42, 0x16, 0x47, 0x85, 0x33, 0x22, 0x76, 0xB2, + 0x0A, 0x6F, 0x0F, 0xE5, 0x25, 0x50, 0x4F, 0x85, 0x86, 0xBE, 0xBF, 0x98, + 0x2E, 0x10, 0x67, 0x1E, 0xBE, 0x11, 0x05, 0x86, 0x05, 0x90, 0xC4, 0x59, + 0xD0, 0x7C, 0x78, 0x10, 0xB0, 0x80, 0x5C, 0xB7, 0xE1, 0xC7, 0x2B, 0x75, + 0xCB, 0x7C, 0x9F, 0xAE, 0xB5, 0xD1, 0x9D, 0x23, 0x37, 0x63, 0xA7, 0xDC, + 0x42, 0xA2, 0x2D, 0x92, 0x04, 0x1B, 0x50, 0xC1, 0x7B, 0xB8, 0x3E, 0x1B, + 0xC9, 0x56, 0x04, 0x8B, 0x2F, 0x52, 0x9B, 0xAD, 0xA9, 0x56, 0xE9, 0xC1, + 0xFF, 0xAD, 0xA9, 0x58, 0x87, 0x30, 0xB6, 0x81, 0xF7, 0x97, 0x45, 0xFC, + 0x19, 0x57, 0x3B, 0x2B, 0x6F, 0xE4, 0x47, 0xF4, 0x99, 0x45, 0xFE, 0x1D, + 0xF1, 0xF8, 0x97, 0xA3, 0x88, 0x1D, 0x37, 0x1C, 0x5C, 0x8F, 0xE0, 0x76, + 0x25, 0x9A, 0x50, 0xF8, 0xA0, 0x54, 0xFF, 0x44, 0x90, 0x76, 0x23, 0xD2, + 0x32, 0xC6, 0xC3, 0xAB, 0x06, 0xBF, 0xFC, 0xFB, 0xBF, 0xF3, 0xAD, 0x7D, + 0x92, 0x62, 0x02, 0x5B, 0x29, 0xD3, 0x35, 0xA3, 0x93, 0x9A, 0x43, 0x64, + 0x60, 0x5D, 0xB2, 0xFA, 0x32, 0xFF, 0x3B, 0x04, 0xAF, 0x4D, 0x40, 0x6A, + 0xF9, 0xC7, 0xE3, 0xEF, 0x23, 0xFD, 0x6B, 0xCB, 0xE5, 0x0F, 0x8B, 0x38, + 0x0D, 0xEE, 0x0A, 0xFC, 0xFE, 0x0F, 0x98, 0x9F, 0x30, 0x31, 0xDD, 0x6C, + 0x52, 0x65, 0xF9, 0x8B, 0x81, 0xBE, 0x22, 0xE1, 0x1C, 0x58, 0x03, 0xBA, + 0x91, 0x1B, 0x89, 0x07 +}; + +static const unsigned char TA742_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA743_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x55, 0x43, 0x41, + 0x20, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, + 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74 +}; + +static const unsigned char TA743_RSA_N[] = { + 0xA9, 0x09, 0x07, 0x28, 0x13, 0x02, 0xB0, 0x99, 0xE0, 0x64, 0xAA, 0x1E, + 0x43, 0x16, 0x7A, 0x73, 0xB1, 0x91, 0xA0, 0x75, 0x3E, 0xA8, 0xFA, 0xE3, + 0x38, 0x00, 0x7A, 0xEC, 0x89, 0x6A, 0x20, 0x0F, 0x8B, 0xC5, 0xB0, 0x9B, + 0x33, 0x03, 0x5A, 0x86, 0xC6, 0x58, 0x86, 0xD5, 0xC1, 0x85, 0xBB, 0x4F, + 0xC6, 0x9C, 0x40, 0x4D, 0xCA, 0xBE, 0xEE, 0x69, 0x96, 0xB8, 0xAD, 0x81, + 0x30, 0x9A, 0x7C, 0x92, 0x05, 0xEB, 0x05, 0x2B, 0x9A, 0x48, 0xD0, 0xB8, + 0x76, 0x3E, 0x96, 0xC8, 0x20, 0xBB, 0xD2, 0xB0, 0xF1, 0x8F, 0xD8, 0xAC, + 0x45, 0x46, 0xFF, 0xAA, 0x67, 0x60, 0xB4, 0x77, 0x7E, 0x6A, 0x1F, 0x3C, + 0x1A, 0x52, 0x7A, 0x04, 0x3D, 0x07, 0x3C, 0x85, 0x0D, 0x84, 0xD0, 0x1F, + 0x76, 0x0A, 0xF7, 0x6A, 0x14, 0xDF, 0x72, 0xE3, 0x34, 0x7C, 0x57, 0x4E, + 0x56, 0x01, 0x3E, 0x79, 0xF1, 0xAA, 0x29, 0x3B, 0x6C, 0xFA, 0xF8, 0x8F, + 0x6D, 0x4D, 0xC8, 0x35, 0xDF, 0xAE, 0xEB, 0xDC, 0x24, 0xEE, 0x79, 0x45, + 0xA7, 0x85, 0xB6, 0x05, 0x88, 0xDE, 0x88, 0x5D, 0x25, 0x7C, 0x97, 0x64, + 0x67, 0x09, 0xD9, 0xBF, 0x5A, 0x15, 0x05, 0x86, 0xF3, 0x09, 0x1E, 0xEC, + 0x58, 0x32, 0x33, 0x11, 0xF3, 0x77, 0x64, 0xB0, 0x76, 0x1F, 0xE4, 0x10, + 0x35, 0x17, 0x1B, 0xF2, 0x0E, 0xB1, 0x6C, 0xA4, 0x2A, 0xA3, 0x73, 0xFC, + 0x09, 0x1F, 0x1E, 0x32, 0x19, 0x53, 0x11, 0xE7, 0xD9, 0xB3, 0x2C, 0x2E, + 0x76, 0x2E, 0xA1, 0xA3, 0xDE, 0x7E, 0x6A, 0x88, 0x09, 0xE8, 0xF2, 0x07, + 0x8A, 0xF8, 0xB2, 0xCD, 0x10, 0xE7, 0xE2, 0x73, 0x40, 0x93, 0xBB, 0x08, + 0xD1, 0x3F, 0xE1, 0xFC, 0x0B, 0x94, 0xB3, 0x25, 0xEF, 0x7C, 0xA6, 0xD7, + 0xD1, 0xAF, 0x9F, 0xFF, 0x96, 0x9A, 0xF5, 0x91, 0x7B, 0x98, 0x0B, 0x77, + 0xD4, 0x7E, 0xE8, 0x07, 0xD2, 0x62, 0xB5, 0x95, 0x39, 0xE3, 0xF3, 0xF1, + 0x6D, 0x0F, 0x0E, 0x65, 0x84, 0x8A, 0x63, 0x54, 0xC5, 0x80, 0xB6, 0xE0, + 0x9E, 0x4B, 0x7D, 0x47, 0x26, 0xA7, 0x01, 0x08, 0x5D, 0xD1, 0x88, 0x9E, + 0xD7, 0xC3, 0x32, 0x44, 0xFA, 0x82, 0x4A, 0x0A, 0x68, 0x54, 0x7F, 0x38, + 0x53, 0x03, 0xCC, 0xA4, 0x00, 0x33, 0x64, 0x51, 0x59, 0x0B, 0xA3, 0x82, + 0x91, 0x7A, 0x5E, 0xEC, 0x16, 0xC2, 0xF3, 0x2A, 0xE6, 0x62, 0xDA, 0x2A, + 0xDB, 0x59, 0x62, 0x10, 0x25, 0x4A, 0x2A, 0x81, 0x0B, 0x47, 0x07, 0x43, + 0x06, 0x70, 0x87, 0xD2, 0xFA, 0x93, 0x11, 0x29, 0x7A, 0x48, 0x4D, 0xEB, + 0x94, 0xC7, 0x70, 0x4D, 0xAF, 0x67, 0xD5, 0x51, 0xB1, 0x80, 0x20, 0x01, + 0x01, 0xB4, 0x7A, 0x08, 0xA6, 0x90, 0x7F, 0x4E, 0xE0, 0xEF, 0x07, 0x41, + 0x87, 0xAF, 0x6A, 0xA5, 0x5E, 0x8B, 0xFB, 0xCF, 0x50, 0xB2, 0x9A, 0x54, + 0xAF, 0xC3, 0x89, 0xBA, 0x58, 0x2D, 0xF5, 0x30, 0x98, 0xB1, 0x36, 0x72, + 0x39, 0x7E, 0x49, 0x04, 0xFD, 0x29, 0xA7, 0x4C, 0x79, 0xE4, 0x05, 0x57, + 0xDB, 0x94, 0xB9, 0x16, 0x53, 0x8D, 0x46, 0xB3, 0x1D, 0x95, 0x61, 0x57, + 0x56, 0x7F, 0xAF, 0xF0, 0x16, 0x5B, 0x61, 0x58, 0x6F, 0x36, 0x50, 0x11, + 0x0B, 0xD8, 0xAC, 0x2B, 0x95, 0x16, 0x1A, 0x0E, 0x1F, 0x08, 0xCD, 0x36, + 0x34, 0x65, 0x10, 0x62, 0x66, 0xD5, 0x80, 0x5F, 0x14, 0x20, 0x5F, 0x2D, + 0x0C, 0xA0, 0x78, 0x0A, 0x68, 0xD6, 0x2C, 0xD7, 0xE9, 0x6F, 0x2B, 0xD2, + 0x4A, 0x05, 0x93, 0xFC, 0x9E, 0x6F, 0x6B, 0x67, 0xFF, 0x88, 0xF1, 0x4E, + 0xA5, 0x69, 0x4A, 0x52, 0x37, 0x05, 0xEA, 0xC6, 0x16, 0x8D, 0xD2, 0xC4, + 0x99, 0xD1, 0x82, 0x2B, 0x3B, 0xBA, 0x35, 0x75, 0xF7, 0x51, 0x51, 0x58, + 0xF3, 0xC8, 0x07, 0xDD, 0xE4, 0xB4, 0x03, 0x7F +}; + +static const unsigned char TA743_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA744_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x1B, + 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x55, 0x43, 0x41, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x47, 0x32, 0x20, 0x52, + 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA744_RSA_N[] = { + 0xC5, 0xE6, 0x2B, 0x6F, 0x7C, 0xEF, 0x26, 0x05, 0x27, 0xA3, 0x81, 0x24, + 0xDA, 0x6F, 0xCB, 0x01, 0xF9, 0x99, 0x9A, 0xA9, 0x32, 0xC2, 0x22, 0x87, + 0x61, 0x41, 0x91, 0x3B, 0xCB, 0xC3, 0x68, 0x1B, 0x06, 0xC5, 0x4C, 0xA9, + 0x2B, 0xC1, 0x67, 0x17, 0x22, 0x1D, 0x2B, 0xED, 0xF9, 0x29, 0x89, 0x93, + 0xA2, 0x78, 0xBD, 0x92, 0x6B, 0xA0, 0xA3, 0x0D, 0xA2, 0x7E, 0xCA, 0x93, + 0xB3, 0xA6, 0xD1, 0x8C, 0x35, 0xD5, 0x75, 0xF9, 0x17, 0xF6, 0xCF, 0x45, + 0xC5, 0xE5, 0x7A, 0xEC, 0x77, 0x93, 0xA0, 0x8F, 0x23, 0xAE, 0x0E, 0x1A, + 0x03, 0x7F, 0xBE, 0xD4, 0xD0, 0xED, 0x2E, 0x7B, 0xAB, 0x46, 0x23, 0x5B, + 0xFF, 0x2C, 0xE6, 0x54, 0x7A, 0x94, 0xC0, 0x2A, 0x15, 0xF0, 0xC9, 0x8D, + 0xB0, 0x7A, 0x3B, 0x24, 0xE1, 0xD7, 0x68, 0xE2, 0x31, 0x3C, 0x06, 0x33, + 0x46, 0xB6, 0x54, 0x11, 0xA6, 0xA5, 0x2F, 0x22, 0x54, 0x2A, 0x58, 0x0D, + 0x01, 0x02, 0xF1, 0xFA, 0x15, 0x51, 0x67, 0x6C, 0xC0, 0xFA, 0xD7, 0xB6, + 0x1B, 0x7F, 0xD1, 0x56, 0x88, 0x2F, 0x1A, 0x3A, 0x8D, 0x3B, 0xBB, 0x82, + 0x11, 0xE0, 0x47, 0x00, 0xD0, 0x52, 0x87, 0xAB, 0xFB, 0x86, 0x7E, 0x0F, + 0x24, 0x6B, 0x40, 0x9D, 0x34, 0x67, 0xBC, 0x8D, 0xC7, 0x2D, 0x86, 0x6F, + 0x79, 0x3E, 0x8E, 0xA9, 0x3C, 0x17, 0x4B, 0x7F, 0xB0, 0x99, 0xE3, 0xB0, + 0x71, 0x60, 0xDC, 0x0B, 0xF5, 0x64, 0xC3, 0xCE, 0x43, 0xBC, 0x6D, 0x71, + 0xB9, 0xD2, 0xDE, 0x27, 0x5B, 0x8A, 0xE8, 0xD8, 0xC6, 0xAE, 0xE1, 0x59, + 0x7D, 0xCF, 0x28, 0x2D, 0x35, 0xB8, 0x95, 0x56, 0x1A, 0xF1, 0xB2, 0x58, + 0x4B, 0xB7, 0x12, 0x37, 0xC8, 0x7C, 0xB3, 0xED, 0x4B, 0x80, 0xE1, 0x8D, + 0xFA, 0x32, 0x23, 0xB6, 0x6F, 0xB7, 0x48, 0x95, 0x08, 0xB1, 0x44, 0x4E, + 0x85, 0x8C, 0x3A, 0x02, 0x54, 0x20, 0x2F, 0xDF, 0xBF, 0x57, 0x4F, 0x3B, + 0x3A, 0x90, 0x21, 0xD7, 0xC1, 0x26, 0x35, 0x54, 0x20, 0xEC, 0xC7, 0x3F, + 0x47, 0xEC, 0xEF, 0x5A, 0xBF, 0x4B, 0x7A, 0xC1, 0xAD, 0x3B, 0x17, 0x50, + 0x5C, 0x62, 0xD8, 0x0F, 0x4B, 0x4A, 0xDC, 0x2B, 0xFA, 0x6E, 0xBC, 0x73, + 0x92, 0xCD, 0xEC, 0xC7, 0x50, 0xE8, 0x41, 0x96, 0xD7, 0xA9, 0x7E, 0x6D, + 0xD8, 0xE9, 0x1D, 0x8F, 0x8A, 0xB5, 0xB9, 0x58, 0x92, 0xBA, 0x4A, 0x92, + 0x2B, 0x0C, 0x56, 0xFD, 0x80, 0xEB, 0x08, 0xF0, 0x5E, 0x29, 0x6E, 0x1B, + 0x1C, 0x0C, 0xAF, 0x8F, 0x93, 0x89, 0xAD, 0xDB, 0xBD, 0xA3, 0x9E, 0x21, + 0xCA, 0x89, 0x19, 0xEC, 0xDF, 0xB5, 0xC3, 0x1A, 0xEB, 0x16, 0xFE, 0x78, + 0x36, 0x4C, 0xD6, 0x6E, 0xD0, 0x3E, 0x17, 0x1C, 0x90, 0x17, 0x6B, 0x26, + 0xBA, 0xFB, 0x7A, 0x2F, 0xBF, 0x11, 0x1C, 0x18, 0x0E, 0x2D, 0x73, 0x03, + 0x8F, 0xA0, 0xE5, 0x35, 0xA0, 0x5A, 0xE2, 0x4C, 0x75, 0x1D, 0x71, 0xE1, + 0x39, 0x38, 0x53, 0x78, 0x40, 0xCC, 0x83, 0x93, 0xD7, 0x0A, 0x9E, 0x9D, + 0x5B, 0x8F, 0x8A, 0xE4, 0xE5, 0xE0, 0x48, 0xE4, 0x48, 0xB2, 0x47, 0xCD, + 0x4E, 0x2A, 0x75, 0x2A, 0x7B, 0xF2, 0x22, 0xF6, 0xC9, 0xBE, 0x09, 0x91, + 0x96, 0x57, 0x7A, 0x88, 0x88, 0xAC, 0xEE, 0x70, 0xAC, 0xF9, 0xDC, 0x29, + 0xE3, 0x0C, 0x1C, 0x3B, 0x12, 0x4E, 0x44, 0xD6, 0xA7, 0x4E, 0xB0, 0x26, + 0xC8, 0xF3, 0xD9, 0x1A, 0x97, 0x91, 0x68, 0xEA, 0xEF, 0x8D, 0x46, 0x06, + 0xD2, 0x56, 0x45, 0x58, 0x9A, 0x3C, 0x0C, 0x0F, 0x83, 0xB8, 0x05, 0x25, + 0xC3, 0x39, 0xCF, 0x3B, 0xA4, 0x34, 0x89, 0xB7, 0x79, 0x12, 0x2F, 0x47, + 0xC5, 0xE7, 0xA9, 0x97, 0x69, 0xFC, 0xA6, 0x77, 0x67, 0xB5, 0xDF, 0x7B, + 0xF1, 0x7A, 0x65, 0x15, 0xE4, 0x61, 0x56, 0x65 +}; + +static const unsigned char TA744_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA745_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA745_EC_Q[] = { + 0x04, 0x1A, 0xAC, 0x54, 0x5A, 0xA9, 0xF9, 0x68, 0x23, 0xE7, 0x7A, 0xD5, + 0x24, 0x6F, 0x53, 0xC6, 0x5A, 0xD8, 0x4B, 0xAB, 0xC6, 0xD5, 0xB6, 0xD1, + 0xE6, 0x73, 0x71, 0xAE, 0xDD, 0x9C, 0xD6, 0x0C, 0x61, 0xFD, 0xDB, 0xA0, + 0x89, 0x03, 0xB8, 0x05, 0x14, 0xEC, 0x57, 0xCE, 0xEE, 0x5D, 0x3F, 0xE2, + 0x21, 0xB3, 0xCE, 0xF7, 0xD4, 0x8A, 0x79, 0xE0, 0xA3, 0x83, 0x7E, 0x2D, + 0x97, 0xD0, 0x61, 0xC4, 0xF1, 0x99, 0xDC, 0x25, 0x91, 0x63, 0xAB, 0x7F, + 0x30, 0xA3, 0xB4, 0x70, 0xE2, 0xC7, 0xA1, 0x33, 0x9C, 0xF3, 0xBF, 0x2E, + 0x5C, 0x53, 0xB1, 0x5F, 0xB3, 0x7D, 0x32, 0x7F, 0x8A, 0x34, 0xE3, 0x79, + 0x79 +}; + +static const unsigned char TA746_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA746_RSA_N[] = { + 0x80, 0x12, 0x65, 0x17, 0x36, 0x0E, 0xC3, 0xDB, 0x08, 0xB3, 0xD0, 0xAC, + 0x57, 0x0D, 0x76, 0xED, 0xCD, 0x27, 0xD3, 0x4C, 0xAD, 0x50, 0x83, 0x61, + 0xE2, 0xAA, 0x20, 0x4D, 0x09, 0x2D, 0x64, 0x09, 0xDC, 0xCE, 0x89, 0x9F, + 0xCC, 0x3D, 0xA9, 0xEC, 0xF6, 0xCF, 0xC1, 0xDC, 0xF1, 0xD3, 0xB1, 0xD6, + 0x7B, 0x37, 0x28, 0x11, 0x2B, 0x47, 0xDA, 0x39, 0xC6, 0xBC, 0x3A, 0x19, + 0xB4, 0x5F, 0xA6, 0xBD, 0x7D, 0x9D, 0xA3, 0x63, 0x42, 0xB6, 0x76, 0xF2, + 0xA9, 0x3B, 0x2B, 0x91, 0xF8, 0xE2, 0x6F, 0xD0, 0xEC, 0x16, 0x20, 0x90, + 0x09, 0x3E, 0xE2, 0xE8, 0x74, 0xC9, 0x18, 0xB4, 0x91, 0xD4, 0x62, 0x64, + 0xDB, 0x7F, 0xA3, 0x06, 0xF1, 0x88, 0x18, 0x6A, 0x90, 0x22, 0x3C, 0xBC, + 0xFE, 0x13, 0xF0, 0x87, 0x14, 0x7B, 0xF6, 0xE4, 0x1F, 0x8E, 0xD4, 0xE4, + 0x51, 0xC6, 0x11, 0x67, 0x46, 0x08, 0x51, 0xCB, 0x86, 0x14, 0x54, 0x3F, + 0xBC, 0x33, 0xFE, 0x7E, 0x6C, 0x9C, 0xFF, 0x16, 0x9D, 0x18, 0xBD, 0x51, + 0x8E, 0x35, 0xA6, 0xA7, 0x66, 0xC8, 0x72, 0x67, 0xDB, 0x21, 0x66, 0xB1, + 0xD4, 0x9B, 0x78, 0x03, 0xC0, 0x50, 0x3A, 0xE8, 0xCC, 0xF0, 0xDC, 0xBC, + 0x9E, 0x4C, 0xFE, 0xAF, 0x05, 0x96, 0x35, 0x1F, 0x57, 0x5A, 0xB7, 0xFF, + 0xCE, 0xF9, 0x3D, 0xB7, 0x2C, 0xB6, 0xF6, 0x54, 0xDD, 0xC8, 0xE7, 0x12, + 0x3A, 0x4D, 0xAE, 0x4C, 0x8A, 0xB7, 0x5C, 0x9A, 0xB4, 0xB7, 0x20, 0x3D, + 0xCA, 0x7F, 0x22, 0x34, 0xAE, 0x7E, 0x3B, 0x68, 0x66, 0x01, 0x44, 0xE7, + 0x01, 0x4E, 0x46, 0x53, 0x9B, 0x33, 0x60, 0xF7, 0x94, 0xBE, 0x53, 0x37, + 0x90, 0x73, 0x43, 0xF3, 0x32, 0xC3, 0x53, 0xEF, 0xDB, 0xAA, 0xFE, 0x74, + 0x4E, 0x69, 0xC7, 0x6B, 0x8C, 0x60, 0x93, 0xDE, 0xC4, 0xC7, 0x0C, 0xDF, + 0xE1, 0x32, 0xAE, 0xCC, 0x93, 0x3B, 0x51, 0x78, 0x95, 0x67, 0x8B, 0xEE, + 0x3D, 0x56, 0xFE, 0x0C, 0xD0, 0x69, 0x0F, 0x1B, 0x0F, 0xF3, 0x25, 0x26, + 0x6B, 0x33, 0x6D, 0xF7, 0x6E, 0x47, 0xFA, 0x73, 0x43, 0xE5, 0x7E, 0x0E, + 0xA5, 0x66, 0xB1, 0x29, 0x7C, 0x32, 0x84, 0x63, 0x55, 0x89, 0xC4, 0x0D, + 0xC1, 0x93, 0x54, 0x30, 0x19, 0x13, 0xAC, 0xD3, 0x7D, 0x37, 0xA7, 0xEB, + 0x5D, 0x3A, 0x6C, 0x35, 0x5C, 0xDB, 0x41, 0xD7, 0x12, 0xDA, 0xA9, 0x49, + 0x0B, 0xDF, 0xD8, 0x80, 0x8A, 0x09, 0x93, 0x62, 0x8E, 0xB5, 0x66, 0xCF, + 0x25, 0x88, 0xCD, 0x84, 0xB8, 0xB1, 0x3F, 0xA4, 0x39, 0x0F, 0xD9, 0x02, + 0x9E, 0xEB, 0x12, 0x4C, 0x95, 0x7C, 0xF3, 0x6B, 0x05, 0xA9, 0x5E, 0x16, + 0x83, 0xCC, 0xB8, 0x67, 0xE2, 0xE8, 0x13, 0x9D, 0xCC, 0x5B, 0x82, 0xD3, + 0x4C, 0xB3, 0xED, 0x5B, 0xFF, 0xDE, 0xE5, 0x73, 0xAC, 0x23, 0x3B, 0x2D, + 0x00, 0xBF, 0x35, 0x55, 0x74, 0x09, 0x49, 0xD8, 0x49, 0x58, 0x1A, 0x7F, + 0x92, 0x36, 0xE6, 0x51, 0x92, 0x0E, 0xF3, 0x26, 0x7D, 0x1C, 0x4D, 0x17, + 0xBC, 0xC9, 0xEC, 0x43, 0x26, 0xD0, 0xBF, 0x41, 0x5F, 0x40, 0xA9, 0x44, + 0x44, 0xF4, 0x99, 0xE7, 0x57, 0x87, 0x9E, 0x50, 0x1F, 0x57, 0x54, 0xA8, + 0x3E, 0xFD, 0x74, 0x63, 0x2F, 0xB1, 0x50, 0x65, 0x09, 0xE6, 0x58, 0x42, + 0x2E, 0x43, 0x1A, 0x4C, 0xB4, 0xF0, 0x25, 0x47, 0x59, 0xFA, 0x04, 0x1E, + 0x93, 0xD4, 0x26, 0x46, 0x4A, 0x50, 0x81, 0xB2, 0xDE, 0xBE, 0x78, 0xB7, + 0xFC, 0x67, 0x15, 0xE1, 0xC9, 0x57, 0x84, 0x1E, 0x0F, 0x63, 0xD6, 0xE9, + 0x62, 0xBA, 0xD6, 0x5F, 0x55, 0x2E, 0xEA, 0x5C, 0xC6, 0x28, 0x08, 0x04, + 0x25, 0x39, 0xB8, 0x0E, 0x2B, 0xA9, 0xF2, 0x4C, 0x97, 0x1C, 0x07, 0x3F, + 0x0D, 0x52, 0xF5, 0xED, 0xEF, 0x2F, 0x82, 0x0F +}; + +static const unsigned char TA746_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA747_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1A, 0x30, + 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA747_EC_Q[] = { + 0x04, 0x65, 0x50, 0x4A, 0xAE, 0x8C, 0x79, 0x96, 0x4A, 0xAA, 0x1C, 0x08, + 0xC3, 0xA3, 0xA2, 0xCD, 0xFE, 0x59, 0x56, 0x41, 0x77, 0xFD, 0x26, 0x94, + 0x42, 0xBB, 0x1D, 0xCD, 0x08, 0xDB, 0x73, 0xB2, 0x5B, 0x75, 0xF3, 0xCF, + 0x9C, 0x4E, 0x82, 0xF4, 0xBF, 0xF8, 0x61, 0x26, 0x85, 0x6C, 0xD6, 0x85, + 0x5B, 0x72, 0x70, 0xD2, 0xFD, 0xDB, 0x62, 0xB4, 0xDF, 0x53, 0x8B, 0xBD, + 0xB1, 0x44, 0x58, 0x62, 0x42, 0x09, 0xC7, 0xFA, 0x7F, 0x5B, 0x10, 0xE7, + 0xFE, 0x40, 0xFD, 0xC0, 0xD8, 0xC3, 0x2B, 0x32, 0xE7, 0x70, 0xA6, 0xB7, + 0xA6, 0x20, 0x55, 0x1D, 0x7B, 0x80, 0x5D, 0x4B, 0x8F, 0x67, 0x4C, 0xF1, + 0x10 +}; + +static const unsigned char TA748_DN[] = { + 0x30, 0x43, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, + 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0D, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA748_RSA_N[] = { + 0xBD, 0x55, 0x7C, 0x61, 0xD3, 0xB8, 0x1D, 0x04, 0x62, 0x05, 0xA0, 0xAE, + 0x6C, 0xB7, 0x70, 0xB4, 0x41, 0xEA, 0x4B, 0x03, 0x5E, 0x10, 0x3F, 0x90, + 0x5A, 0x1C, 0x8B, 0x3B, 0xB0, 0x66, 0x8B, 0x6C, 0x48, 0xA6, 0x1C, 0x22, + 0xBA, 0xD5, 0x40, 0x92, 0xEE, 0x33, 0xB2, 0x23, 0x59, 0xC9, 0x8E, 0xBC, + 0x58, 0xDA, 0x8B, 0x9E, 0xD0, 0x19, 0xF2, 0x2F, 0x59, 0xC6, 0x8C, 0x63, + 0x5A, 0xBA, 0x9F, 0xA3, 0x0B, 0xB0, 0xB3, 0x9A, 0x5C, 0xBA, 0x11, 0xB8, + 0x12, 0xE9, 0x0C, 0xBB, 0xCF, 0x6E, 0x6C, 0x80, 0x87, 0x29, 0x14, 0x03, + 0x2C, 0x8D, 0x24, 0x9A, 0xC8, 0x64, 0x83, 0xB5, 0x6A, 0xAC, 0x13, 0x2C, + 0x33, 0xF1, 0x9F, 0xDC, 0x2C, 0x61, 0x3C, 0x1A, 0x3F, 0x70, 0x55, 0x9B, + 0xAD, 0x00, 0x52, 0x7F, 0xCF, 0x04, 0xB9, 0xFE, 0x36, 0xFA, 0x9C, 0xC0, + 0x16, 0xAE, 0x62, 0xFE, 0x96, 0x4C, 0x43, 0x7E, 0x55, 0x14, 0xBE, 0x1A, + 0xB3, 0xD2, 0x6D, 0xC2, 0xAF, 0x76, 0x66, 0x95, 0x6B, 0x2A, 0xB0, 0x94, + 0x77, 0x85, 0x5E, 0x04, 0x0F, 0x62, 0x1D, 0x63, 0x75, 0xF7, 0x6B, 0xE7, + 0xCB, 0x5B, 0x9A, 0x70, 0xEC, 0x3E, 0x67, 0x05, 0xF0, 0xFE, 0x07, 0x08, + 0x80, 0xCF, 0x28, 0xDB, 0x05, 0xC6, 0x14, 0x27, 0x2F, 0x86, 0x7D, 0xF0, + 0x27, 0xDE, 0xFF, 0xE6, 0x7E, 0x33, 0x48, 0xE7, 0x0B, 0x1E, 0x58, 0xD1, + 0x27, 0x2B, 0x53, 0x0E, 0x57, 0x4A, 0x65, 0xD7, 0xFB, 0xA2, 0x80, 0x60, + 0xFC, 0x4C, 0xBC, 0x35, 0x53, 0x01, 0x6A, 0x97, 0x72, 0x82, 0xAF, 0xF1, + 0x1D, 0x70, 0xE8, 0x9C, 0xF5, 0xEF, 0x5E, 0xC2, 0x6C, 0xC7, 0x47, 0x7E, + 0x5A, 0x94, 0x85, 0x26, 0x4D, 0x3B, 0xBA, 0xEB, 0x4C, 0xE8, 0xB0, 0x09, + 0xC2, 0x65, 0xC2, 0x9D, 0x9D, 0x09, 0x9B, 0x4E, 0xB5, 0x97, 0x05, 0xAC, + 0xF5, 0x06, 0xA0, 0xF7, 0x36, 0x05, 0x7E, 0xF4, 0x90, 0xB2, 0x6B, 0xC4, + 0xB4, 0xF9, 0x64, 0xEA, 0xE9, 0x1A, 0x0A, 0xC8, 0x0D, 0xA8, 0xED, 0x27, + 0xC9, 0xD4, 0xE7, 0xB3, 0xB9, 0xAB, 0x82, 0x22, 0x90, 0x27, 0x3D, 0x2A, + 0xE8, 0x7C, 0x90, 0xEF, 0xBC, 0x4F, 0xFD, 0xE2, 0x0A, 0x24, 0xA7, 0xDE, + 0x65, 0x24, 0xA4, 0x5D, 0xEA, 0xC0, 0x76, 0x30, 0xD3, 0x77, 0x50, 0xF8, + 0x0D, 0x04, 0x9B, 0x94, 0x36, 0x01, 0x73, 0xCA, 0x06, 0x58, 0xA6, 0xD3, + 0x3B, 0xDC, 0xFA, 0x04, 0x46, 0x13, 0x55, 0x8A, 0xC9, 0x44, 0x47, 0xB8, + 0x51, 0x39, 0x1A, 0x2E, 0xE8, 0x34, 0xE2, 0x79, 0xCB, 0x59, 0x4A, 0x0A, + 0x7F, 0xBC, 0xA6, 0xEF, 0x1F, 0x03, 0x67, 0x6A, 0x59, 0x2B, 0x25, 0x62, + 0x93, 0xD9, 0x53, 0x19, 0x66, 0x3C, 0x27, 0x62, 0x29, 0x86, 0x4D, 0xA4, + 0x6B, 0xEE, 0xFF, 0xD4, 0x4E, 0xBA, 0xD5, 0xB4, 0xE2, 0x8E, 0x48, 0x5A, + 0x00, 0x19, 0x09, 0xF1, 0x05, 0xD9, 0xCE, 0x91, 0xB1, 0xF7, 0xEB, 0xE9, + 0x39, 0x4F, 0xF6, 0x6F, 0x04, 0x43, 0x9A, 0x55, 0xF5, 0x3E, 0x05, 0x14, + 0xBD, 0xBF, 0xB3, 0x59, 0xB4, 0xD8, 0x8E, 0x33, 0x84, 0xA3, 0x90, 0x52, + 0xAA, 0xB3, 0x02, 0x95, 0x60, 0xF9, 0x0C, 0x4C, 0x68, 0xF9, 0xEE, 0xD5, + 0x17, 0x0D, 0xF8, 0x71, 0x57, 0xB5, 0x25, 0xE4, 0x29, 0xEE, 0x65, 0x5D, + 0xAF, 0xD1, 0xEE, 0x3C, 0x17, 0x0B, 0x5A, 0x43, 0xC5, 0xA5, 0x86, 0xEA, + 0x24, 0x9E, 0xE2, 0x05, 0x07, 0xDC, 0x34, 0x42, 0x12, 0x91, 0xD6, 0x39, + 0x74, 0xAE, 0x4C, 0x41, 0x82, 0xDB, 0xF2, 0xA6, 0x48, 0xD1, 0xB3, 0x9B, + 0xF3, 0x33, 0xAA, 0xF3, 0xA6, 0xC0, 0xC5, 0x4E, 0xF5, 0xF4, 0x9D, 0x76, + 0x63, 0xE6, 0x02, 0xC6, 0x22, 0x4B, 0xC1, 0x95, 0x3F, 0x50, 0x64, 0x2C, + 0x54, 0xE5, 0xB6, 0xF0, 0x3C, 0x29, 0xCF, 0x57 +}; + +static const unsigned char TA748_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA749_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x15, 0x77, 0x77, 0x77, 0x2E, 0x78, 0x72, 0x61, 0x6D, 0x70, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x58, + 0x52, 0x61, 0x6D, 0x70, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x24, 0x58, 0x52, 0x61, 0x6D, 0x70, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA749_RSA_N[] = { + 0x98, 0x24, 0x1E, 0xBD, 0x15, 0xB4, 0xBA, 0xDF, 0xC7, 0x8C, 0xA5, 0x27, + 0xB6, 0x38, 0x0B, 0x69, 0xF3, 0xB6, 0x4E, 0xA8, 0x2C, 0x2E, 0x21, 0x1D, + 0x5C, 0x44, 0xDF, 0x21, 0x5D, 0x7E, 0x23, 0x74, 0xFE, 0x5E, 0x7E, 0xB4, + 0x4A, 0xB7, 0xA6, 0xAD, 0x1F, 0xAE, 0xE0, 0x06, 0x16, 0xE2, 0x9B, 0x5B, + 0xD9, 0x67, 0x74, 0x6B, 0x5D, 0x80, 0x8F, 0x29, 0x9D, 0x86, 0x1B, 0xD9, + 0x9C, 0x0D, 0x98, 0x6D, 0x76, 0x10, 0x28, 0x58, 0xE4, 0x65, 0xB0, 0x7F, + 0x4A, 0x98, 0x79, 0x9F, 0xE0, 0xC3, 0x31, 0x7E, 0x80, 0x2B, 0xB5, 0x8C, + 0xC0, 0x40, 0x3B, 0x11, 0x86, 0xD0, 0xCB, 0xA2, 0x86, 0x36, 0x60, 0xA4, + 0xD5, 0x30, 0x82, 0x6D, 0xD9, 0x6E, 0xD0, 0x0F, 0x12, 0x04, 0x33, 0x97, + 0x5F, 0x4F, 0x61, 0x5A, 0xF0, 0xE4, 0xF9, 0x91, 0xAB, 0xE7, 0x1D, 0x3B, + 0xBC, 0xE8, 0xCF, 0xF4, 0x6B, 0x2D, 0x34, 0x7C, 0xE2, 0x48, 0x61, 0x1C, + 0x8E, 0xF3, 0x61, 0x44, 0xCC, 0x6F, 0xA0, 0x4A, 0xA9, 0x94, 0xB0, 0x4D, + 0xDA, 0xE7, 0xA9, 0x34, 0x7A, 0x72, 0x38, 0xA8, 0x41, 0xCC, 0x3C, 0x94, + 0x11, 0x7D, 0xEB, 0xC8, 0xA6, 0x8C, 0xB7, 0x86, 0xCB, 0xCA, 0x33, 0x3B, + 0xD9, 0x3D, 0x37, 0x8B, 0xFB, 0x7A, 0x3E, 0x86, 0x2C, 0xE7, 0x73, 0xD7, + 0x0A, 0x57, 0xAC, 0x64, 0x9B, 0x19, 0xEB, 0xF4, 0x0F, 0x04, 0x08, 0x8A, + 0xAC, 0x03, 0x17, 0x19, 0x64, 0xF4, 0x5A, 0x25, 0x22, 0x8D, 0x34, 0x2C, + 0xB2, 0xF6, 0x68, 0x1D, 0x12, 0x6D, 0xD3, 0x8A, 0x1E, 0x14, 0xDA, 0xC4, + 0x8F, 0xA6, 0xE2, 0x23, 0x85, 0xD5, 0x7A, 0x0D, 0xBD, 0x6A, 0xE0, 0xE9, + 0xEC, 0xEC, 0x17, 0xBB, 0x42, 0x1B, 0x67, 0xAA, 0x25, 0xED, 0x45, 0x83, + 0x21, 0xFC, 0xC1, 0xC9, 0x7C, 0xD5, 0x62, 0x3E, 0xFA, 0xF2, 0xC5, 0x2D, + 0xD3, 0xFD, 0xD4, 0x65 +}; + +static const unsigned char TA749_RSA_E[] = { + 0x01, 0x00, 0x01 +}; diff --git a/BearSSL-OG/url_utility.cpp b/BearSSL-OG/url_utility.cpp new file mode 100644 index 0000000..6f31b86 --- /dev/null +++ b/BearSSL-OG/url_utility.cpp @@ -0,0 +1,36 @@ +#include "url_utility.h" +#include "pointer_vector.h" +#include "string_utility.h" + +bool url_utility::parse_url(const char* url, char** host, char** path) +{ + bool result = false; + + pointer_vector* url_parts = string_utility::split_first(url, "://", true); + if (url_parts->count() == 2) + { + pointer_vector* domain_parts = string_utility::split_first(url_parts->get(1), "/", true); + if (domain_parts->count() == 2) + { + *host = strdup(domain_parts->get(0)); + *path = string_utility::format_string("/%s", domain_parts->get(1)); + if (*host != NULL && *path != NULL) + { + result = true; + } + else + { + /* Allocation failed — clean up partial results */ + free(*host); + free(*path); + *host = NULL; + *path = NULL; + } + } + delete(domain_parts); + } + delete(url_parts); + + return result; +} + diff --git a/BearSSL-OG/url_utility.h b/BearSSL-OG/url_utility.h new file mode 100644 index 0000000..53dcb55 --- /dev/null +++ b/BearSSL-OG/url_utility.h @@ -0,0 +1,7 @@ +#pragma once + +class url_utility +{ +public: + static bool parse_url(const char* url, char** host, char** path); +}; diff --git a/XboxCurl.sln b/XboxCurl.sln new file mode 100644 index 0000000..8a7095a --- /dev/null +++ b/XboxCurl.sln @@ -0,0 +1,47 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbearssl", "BearSSL-OG\libbearssl.vcproj", "{A1B2C3D4-1234-5678-9ABC-DEF012345678}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "libcurl\libcurl.vcproj", "{C3127A20-19DD-4483-AC21-D35386AC0E7C}" + ProjectSection(ProjectDependencies) = postProject + {A1B2C3D4-1234-5678-9ABC-DEF012345678} = {A1B2C3D4-1234-5678-9ABC-DEF012345678} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcproj", "{12345678-TEST-TEST-TEST-123456789ABC}" + ProjectSection(ProjectDependencies) = postProject + {A1B2C3D4-1234-5678-9ABC-DEF012345678} = {A1B2C3D4-1234-5678-9ABC-DEF012345678} + {C3127A20-19DD-4483-AC21-D35386AC0E7C} = {C3127A20-19DD-4483-AC21-D35386AC0E7C} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_minimal", "test\test_minimal.vcproj", "{12345678-TMIN-TMIN-TMIN-123456789ABC}" + ProjectSection(ProjectDependencies) = postProject + {C3127A20-19DD-4483-AC21-D35386AC0E7C} = {C3127A20-19DD-4483-AC21-D35386AC0E7C} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {A1B2C3D4-1234-5678-9ABC-DEF012345678}.Debug.ActiveCfg = Debug|Xbox + {A1B2C3D4-1234-5678-9ABC-DEF012345678}.Debug.Build.0 = Debug|Xbox + {A1B2C3D4-1234-5678-9ABC-DEF012345678}.Release.ActiveCfg = Release|Xbox + {A1B2C3D4-1234-5678-9ABC-DEF012345678}.Release.Build.0 = Release|Xbox + {C3127A20-19DD-4483-AC21-D35386AC0E7C}.Debug.ActiveCfg = Debug|Xbox + {C3127A20-19DD-4483-AC21-D35386AC0E7C}.Debug.Build.0 = Debug|Xbox + {C3127A20-19DD-4483-AC21-D35386AC0E7C}.Release.ActiveCfg = Release|Xbox + {C3127A20-19DD-4483-AC21-D35386AC0E7C}.Release.Build.0 = Release|Xbox + {12345678-TEST-TEST-TEST-123456789ABC}.Debug.ActiveCfg = Debug|Xbox + {12345678-TEST-TEST-TEST-123456789ABC}.Debug.Build.0 = Debug|Xbox + {12345678-TEST-TEST-TEST-123456789ABC}.Release.ActiveCfg = Release|Xbox + {12345678-TEST-TEST-TEST-123456789ABC}.Release.Build.0 = Release|Xbox + {12345678-TMIN-TMIN-TMIN-123456789ABC}.Debug.ActiveCfg = Debug|Xbox + {12345678-TMIN-TMIN-TMIN-123456789ABC}.Debug.Build.0 = Debug|Xbox + {12345678-TMIN-TMIN-TMIN-123456789ABC}.Release.ActiveCfg = Release|Xbox + {12345678-TMIN-TMIN-TMIN-123456789ABC}.Release.Build.0 = Release|Xbox + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/libcurl/include/Makefile.am b/libcurl/include/Makefile.am new file mode 100644 index 0000000..3b24860 --- /dev/null +++ b/libcurl/include/Makefile.am @@ -0,0 +1,5 @@ +SUBDIRS = curl + +EXTRA_DIST = README + +AUTOMAKE_OPTIONS = foreign no-dependencies diff --git a/libcurl/include/Makefile.in b/libcurl/include/Makefile.in new file mode 100644 index 0000000..d7a1094 --- /dev/null +++ b/libcurl/include/Makefile.in @@ -0,0 +1,720 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compile_check_sizeof.m4 \ + $(top_srcdir)/m4/curl-compilers.m4 \ + $(top_srcdir)/m4/curl-confopts.m4 \ + $(top_srcdir)/m4/curl-functions.m4 \ + $(top_srcdir)/m4/curl-openssl.m4 \ + $(top_srcdir)/m4/curl-override.m4 \ + $(top_srcdir)/m4/curl-reentrant.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/xc-am-iface.m4 \ + $(top_srcdir)/m4/xc-cc-check.m4 \ + $(top_srcdir)/m4/xc-lt-iface.m4 \ + $(top_srcdir)/m4/xc-translit.m4 \ + $(top_srcdir)/m4/xc-val-flgs.m4 \ + $(top_srcdir)/m4/zz40-xc-ovr.m4 \ + $(top_srcdir)/m4/zz50-xc-ovr.m4 \ + $(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/lib/curl_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +depcomp = +am__maybe_remake_depfiles = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AR_FLAGS = @AR_FLAGS@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLANK_AT_MAKETIME = @BLANK_AT_MAKETIME@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ +CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ +CURLVERSION = @CURLVERSION@ +CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ +CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ +CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ +CURL_DISABLE_FTP = @CURL_DISABLE_FTP@ +CURL_DISABLE_GOPHER = @CURL_DISABLE_GOPHER@ +CURL_DISABLE_HTTP = @CURL_DISABLE_HTTP@ +CURL_DISABLE_IMAP = @CURL_DISABLE_IMAP@ +CURL_DISABLE_LDAP = @CURL_DISABLE_LDAP@ +CURL_DISABLE_LDAPS = @CURL_DISABLE_LDAPS@ +CURL_DISABLE_POP3 = @CURL_DISABLE_POP3@ +CURL_DISABLE_PROXY = @CURL_DISABLE_PROXY@ +CURL_DISABLE_RTSP = @CURL_DISABLE_RTSP@ +CURL_DISABLE_SMB = @CURL_DISABLE_SMB@ +CURL_DISABLE_SMTP = @CURL_DISABLE_SMTP@ +CURL_DISABLE_TELNET = @CURL_DISABLE_TELNET@ +CURL_DISABLE_TFTP = @CURL_DISABLE_TFTP@ +CURL_LT_SHLIB_VERSIONED_FLAVOUR = @CURL_LT_SHLIB_VERSIONED_FLAVOUR@ +CURL_NETWORK_AND_TIME_LIBS = @CURL_NETWORK_AND_TIME_LIBS@ +CURL_NETWORK_LIBS = @CURL_NETWORK_LIBS@ +CURL_WITH_MULTI_SSL = @CURL_WITH_MULTI_SSL@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_SSL_BACKEND = @DEFAULT_SSL_BACKEND@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_SHARED = @ENABLE_SHARED@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FISH_FUNCTIONS_DIR = @FISH_FUNCTIONS_DIR@ +GCOV = @GCOV@ +GREP = @GREP@ +HAVE_BROTLI = @HAVE_BROTLI@ +HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ +HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ +HAVE_LIBZ = @HAVE_LIBZ@ +HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ +HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ +IDN_ENABLED = @IDN_ENABLED@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IPV6_ENABLED = @IPV6_ENABLED@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCURL_LIBS = @LIBCURL_LIBS@ +LIBMETALINK_CPPFLAGS = @LIBMETALINK_CPPFLAGS@ +LIBMETALINK_LDFLAGS = @LIBMETALINK_LDFLAGS@ +LIBMETALINK_LIBS = @LIBMETALINK_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MANOPT = @MANOPT@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NROFF = @NROFF@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKGADD_NAME = @PKGADD_NAME@ +PKGADD_PKG = @PKGADD_PKG@ +PKGADD_VENDOR = @PKGADD_VENDOR@ +PKGCONFIG = @PKGCONFIG@ +RANDOM_FILE = @RANDOM_FILE@ +RANLIB = @RANLIB@ +REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SSL_BACKENDS = @SSL_BACKENDS@ +SSL_ENABLED = @SSL_ENABLED@ +SSL_LIBS = @SSL_LIBS@ +STRIP = @STRIP@ +SUPPORT_FEATURES = @SUPPORT_FEATURES@ +SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ +USE_ARES = @USE_ARES@ +USE_GNUTLS = @USE_GNUTLS@ +USE_GNUTLS_NETTLE = @USE_GNUTLS_NETTLE@ +USE_LIBRTMP = @USE_LIBRTMP@ +USE_LIBSSH = @USE_LIBSSH@ +USE_LIBSSH2 = @USE_LIBSSH2@ +USE_MBEDTLS = @USE_MBEDTLS@ +USE_MESALINK = @USE_MESALINK@ +USE_NGHTTP2 = @USE_NGHTTP2@ +USE_NSS = @USE_NSS@ +USE_OPENLDAP = @USE_OPENLDAP@ +USE_SCHANNEL = @USE_SCHANNEL@ +USE_SECTRANSP = @USE_SECTRANSP@ +USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@ +USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@ +USE_WOLFSSL = @USE_WOLFSSL@ +VERSION = @VERSION@ +VERSIONNUM = @VERSIONNUM@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSH_FUNCTIONS_DIR = @ZSH_FUNCTIONS_DIR@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libext = @libext@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = curl +EXTRA_DIST = README +AUTOMAKE_OPTIONS = foreign no-dependencies +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libcurl/include/README b/libcurl/include/README new file mode 100644 index 0000000..091ef76 --- /dev/null +++ b/libcurl/include/README @@ -0,0 +1,18 @@ + _ _ ____ _ + ___| | | | _ \| | + / __| | | | |_) | | + | (__| |_| | _ <| |___ + \___|\___/|_| \_\_____| + +Include files for libcurl, external users. + +They're all placed in the curl subdirectory here for better fit in any kind +of environment. You must include files from here using... + + #include + +... style and point the compiler's include path to the directory holding the +curl subdirectory. It makes it more likely to survive future modifications. + +The public curl include files can be shared freely between different platforms +and different architectures. diff --git a/libcurl/include/curl/Makefile.am b/libcurl/include/curl/Makefile.am new file mode 100644 index 0000000..a31f61b --- /dev/null +++ b/libcurl/include/curl/Makefile.am @@ -0,0 +1,39 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### +pkginclude_HEADERS = \ + curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \ + typecheck-gcc.h system.h urlapi.h + +pkgincludedir= $(includedir)/curl + +CHECKSRC = $(CS_$(V)) +CS_0 = @echo " RUN " $@; +CS_1 = +CS_ = $(CS_0) + +checksrc: + $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl -D$(top_srcdir)/include/curl $(pkginclude_HEADERS) + +if CURLDEBUG +# for debug builds, we scan the sources on all regular make invokes +all-local: checksrc +endif diff --git a/libcurl/include/curl/Makefile.in b/libcurl/include/curl/Makefile.in new file mode 100644 index 0000000..220d294 --- /dev/null +++ b/libcurl/include/curl/Makefile.in @@ -0,0 +1,693 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/curl +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compile_check_sizeof.m4 \ + $(top_srcdir)/m4/curl-compilers.m4 \ + $(top_srcdir)/m4/curl-confopts.m4 \ + $(top_srcdir)/m4/curl-functions.m4 \ + $(top_srcdir)/m4/curl-openssl.m4 \ + $(top_srcdir)/m4/curl-override.m4 \ + $(top_srcdir)/m4/curl-reentrant.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/xc-am-iface.m4 \ + $(top_srcdir)/m4/xc-cc-check.m4 \ + $(top_srcdir)/m4/xc-lt-iface.m4 \ + $(top_srcdir)/m4/xc-translit.m4 \ + $(top_srcdir)/m4/xc-val-flgs.m4 \ + $(top_srcdir)/m4/zz40-xc-ovr.m4 \ + $(top_srcdir)/m4/zz50-xc-ovr.m4 \ + $(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/lib/curl_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgincludedir)" +HEADERS = $(pkginclude_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +pkgincludedir = $(includedir)/curl +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AR_FLAGS = @AR_FLAGS@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLANK_AT_MAKETIME = @BLANK_AT_MAKETIME@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ +CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ +CURLVERSION = @CURLVERSION@ +CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ +CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ +CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ +CURL_DISABLE_FTP = @CURL_DISABLE_FTP@ +CURL_DISABLE_GOPHER = @CURL_DISABLE_GOPHER@ +CURL_DISABLE_HTTP = @CURL_DISABLE_HTTP@ +CURL_DISABLE_IMAP = @CURL_DISABLE_IMAP@ +CURL_DISABLE_LDAP = @CURL_DISABLE_LDAP@ +CURL_DISABLE_LDAPS = @CURL_DISABLE_LDAPS@ +CURL_DISABLE_POP3 = @CURL_DISABLE_POP3@ +CURL_DISABLE_PROXY = @CURL_DISABLE_PROXY@ +CURL_DISABLE_RTSP = @CURL_DISABLE_RTSP@ +CURL_DISABLE_SMB = @CURL_DISABLE_SMB@ +CURL_DISABLE_SMTP = @CURL_DISABLE_SMTP@ +CURL_DISABLE_TELNET = @CURL_DISABLE_TELNET@ +CURL_DISABLE_TFTP = @CURL_DISABLE_TFTP@ +CURL_LT_SHLIB_VERSIONED_FLAVOUR = @CURL_LT_SHLIB_VERSIONED_FLAVOUR@ +CURL_NETWORK_AND_TIME_LIBS = @CURL_NETWORK_AND_TIME_LIBS@ +CURL_NETWORK_LIBS = @CURL_NETWORK_LIBS@ +CURL_WITH_MULTI_SSL = @CURL_WITH_MULTI_SSL@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_SSL_BACKEND = @DEFAULT_SSL_BACKEND@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_SHARED = @ENABLE_SHARED@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FISH_FUNCTIONS_DIR = @FISH_FUNCTIONS_DIR@ +GCOV = @GCOV@ +GREP = @GREP@ +HAVE_BROTLI = @HAVE_BROTLI@ +HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ +HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ +HAVE_LIBZ = @HAVE_LIBZ@ +HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ +HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ +IDN_ENABLED = @IDN_ENABLED@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IPV6_ENABLED = @IPV6_ENABLED@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCURL_LIBS = @LIBCURL_LIBS@ +LIBMETALINK_CPPFLAGS = @LIBMETALINK_CPPFLAGS@ +LIBMETALINK_LDFLAGS = @LIBMETALINK_LDFLAGS@ +LIBMETALINK_LIBS = @LIBMETALINK_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MANOPT = @MANOPT@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NROFF = @NROFF@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKGADD_NAME = @PKGADD_NAME@ +PKGADD_PKG = @PKGADD_PKG@ +PKGADD_VENDOR = @PKGADD_VENDOR@ +PKGCONFIG = @PKGCONFIG@ +RANDOM_FILE = @RANDOM_FILE@ +RANLIB = @RANLIB@ +REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SSL_BACKENDS = @SSL_BACKENDS@ +SSL_ENABLED = @SSL_ENABLED@ +SSL_LIBS = @SSL_LIBS@ +STRIP = @STRIP@ +SUPPORT_FEATURES = @SUPPORT_FEATURES@ +SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ +USE_ARES = @USE_ARES@ +USE_GNUTLS = @USE_GNUTLS@ +USE_GNUTLS_NETTLE = @USE_GNUTLS_NETTLE@ +USE_LIBRTMP = @USE_LIBRTMP@ +USE_LIBSSH = @USE_LIBSSH@ +USE_LIBSSH2 = @USE_LIBSSH2@ +USE_MBEDTLS = @USE_MBEDTLS@ +USE_MESALINK = @USE_MESALINK@ +USE_NGHTTP2 = @USE_NGHTTP2@ +USE_NSS = @USE_NSS@ +USE_OPENLDAP = @USE_OPENLDAP@ +USE_SCHANNEL = @USE_SCHANNEL@ +USE_SECTRANSP = @USE_SECTRANSP@ +USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@ +USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@ +USE_WOLFSSL = @USE_WOLFSSL@ +VERSION = @VERSION@ +VERSIONNUM = @VERSIONNUM@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSH_FUNCTIONS_DIR = @ZSH_FUNCTIONS_DIR@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libext = @libext@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### +pkginclude_HEADERS = \ + curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \ + typecheck-gcc.h system.h urlapi.h + +CHECKSRC = $(CS_$(V)) +CS_0 = @echo " RUN " $@; +CS_1 = +CS_ = $(CS_0) +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/curl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu include/curl/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +@CURLDEBUG_FALSE@all-local: +all-am: Makefile $(HEADERS) all-local +installdirs: + for dir in "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pkgincludeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkgincludeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am all-local check check-am clean \ + clean-generic clean-libtool cscopelist-am ctags ctags-am \ + distclean distclean-generic distclean-libtool distclean-tags \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-pkgincludeHEADERS \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkgincludeHEADERS + +.PRECIOUS: Makefile + + +checksrc: + $(CHECKSRC)@PERL@ $(top_srcdir)/lib/checksrc.pl -D$(top_srcdir)/include/curl $(pkginclude_HEADERS) + +# for debug builds, we scan the sources on all regular make invokes +@CURLDEBUG_TRUE@all-local: checksrc + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libcurl/include/curl/curl.h b/libcurl/include/curl/curl.h new file mode 100644 index 0000000..014fb56 --- /dev/null +++ b/libcurl/include/curl/curl.h @@ -0,0 +1,2873 @@ +#ifndef __CURL_CURL_H +#define __CURL_CURL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * If you have libcurl problems, all docs and details are found here: + * https://curl.haxx.se/libcurl/ + * + * curl-library mailing list subscription and unsubscription web interface: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + */ + +#include +#ifdef CURL_NO_OLDIES +#define CURL_STRICTER +#endif + +#include "curlver.h" /* libcurl version defines */ +#include "system.h" /* determine things run-time */ + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && \ + !defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#include +#include + +#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) +/* Needed for __FreeBSD_version symbol definition */ +#include +#endif + +/* The include stuff here below is mainly for time_t! */ +#include +#include + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ + defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +//#include +//#include +#endif +#endif + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on systems that are known to + require it! */ +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ + defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ + defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ + defined(__CYGWIN__) || \ + (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) +#include +#endif + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif + +#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) +#include +#endif + +#ifdef __BEOS__ +#include +#endif + +/* Compatibility for non-Clang compilers */ +#ifndef __has_declspec_attribute +# define __has_declspec_attribute(x) 0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_easy CURL; +typedef struct Curl_share CURLSH; +#else +typedef void CURL; +typedef void CURLSH; +#endif + +/* + * libcurl external API function linkage decorations. + */ + +#ifdef CURL_STATICLIB +# define CURL_EXTERN +#elif defined(WIN32) || defined(__SYMBIAN32__) || \ + (__has_declspec_attribute(dllexport) && \ + __has_declspec_attribute(dllimport)) +# if defined(BUILDING_LIBCURL) +# define CURL_EXTERN __declspec(dllexport) +# else +# define CURL_EXTERN __declspec(dllimport) +# endif +#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) +# define CURL_EXTERN CURL_EXTERN_SYMBOL +#else +# define CURL_EXTERN +#endif + +#ifndef curl_socket_typedef +/* socket typedef */ +#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) +typedef SOCKET curl_socket_t; +#define CURL_SOCKET_BAD INVALID_SOCKET +#else +typedef int curl_socket_t; +#define CURL_SOCKET_BAD -1 +#endif +#define curl_socket_typedef +#endif /* curl_socket_typedef */ + +/* enum for the different supported SSL backends */ +typedef enum { + CURLSSLBACKEND_NONE = 0, + CURLSSLBACKEND_OPENSSL = 1, + CURLSSLBACKEND_GNUTLS = 2, + CURLSSLBACKEND_NSS = 3, + CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ + CURLSSLBACKEND_GSKIT = 5, + CURLSSLBACKEND_POLARSSL = 6, + CURLSSLBACKEND_WOLFSSL = 7, + CURLSSLBACKEND_SCHANNEL = 8, + CURLSSLBACKEND_SECURETRANSPORT = 9, + CURLSSLBACKEND_AXTLS = 10, /* never used since 7.63.0 */ + CURLSSLBACKEND_MBEDTLS = 11, + CURLSSLBACKEND_MESALINK = 12, + CURLSSLBACKEND_BEARSSL = 13 +} curl_sslbackend; + +/* aliases for library clones and renames */ +#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL +#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL + +/* deprecated names: */ +#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL +#define CURLSSLBACKEND_DARWINSSL CURLSSLBACKEND_SECURETRANSPORT + +struct curl_httppost { + struct curl_httppost *next; /* next entry in the list */ + char *name; /* pointer to allocated name */ + long namelength; /* length of name length */ + char *contents; /* pointer to allocated data contents */ + long contentslength; /* length of contents field, see also + CURL_HTTPPOST_LARGE */ + char *buffer; /* pointer to allocated buffer contents */ + long bufferlength; /* length of buffer field */ + char *contenttype; /* Content-Type */ + struct curl_slist *contentheader; /* list of extra headers for this form */ + struct curl_httppost *more; /* if one field name has more than one + file, this link should link to following + files */ + long flags; /* as defined below */ + +/* specified content is a file name */ +#define CURL_HTTPPOST_FILENAME (1<<0) +/* specified content is a file name */ +#define CURL_HTTPPOST_READFILE (1<<1) +/* name is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRNAME (1<<2) +/* contents is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRCONTENTS (1<<3) +/* upload file from buffer */ +#define CURL_HTTPPOST_BUFFER (1<<4) +/* upload file from pointer contents */ +#define CURL_HTTPPOST_PTRBUFFER (1<<5) +/* upload file contents by using the regular read callback to get the data and + pass the given pointer as custom pointer */ +#define CURL_HTTPPOST_CALLBACK (1<<6) +/* use size in 'contentlen', added in 7.46.0 */ +#define CURL_HTTPPOST_LARGE (1<<7) + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ + void *userp; /* custom pointer used for + HTTPPOST_CALLBACK posts */ + curl_off_t contentlen; /* alternative length of contents + field. Used if CURL_HTTPPOST_LARGE is + set. Added in 7.46.0 */ +}; + +/* This is the CURLOPT_PROGRESSFUNCTION callback prototype. It is now + considered deprecated but was the only choice up until 7.31.0 */ +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + +/* This is the CURLOPT_XFERINFOFUNCTION callback prototype. It was introduced + in 7.32.0, avoids the use of floating point numbers and provides more + detailed information. */ +typedef int (*curl_xferinfo_callback)(void *clientp, + curl_off_t dltotal, + curl_off_t dlnow, + curl_off_t ultotal, + curl_off_t ulnow); + +#ifndef CURL_MAX_READ_SIZE + /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */ +#define CURL_MAX_READ_SIZE 524288 +#endif + +#ifndef CURL_MAX_WRITE_SIZE + /* Tests have proven that 20K is a very bad buffer size for uploads on + Windows, while 16K for some odd reason performed a lot better. + We do the ifndef check to allow this value to easier be changed at build + time for those who feel adventurous. The practical minimum is about + 400 bytes since libcurl uses a buffer of this size as a scratch area + (unrelated to network send operations). */ +#define CURL_MAX_WRITE_SIZE 16384 +#endif + +#ifndef CURL_MAX_HTTP_HEADER +/* The only reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a never-ending header that will cause reallocs + infinitely */ +#define CURL_MAX_HTTP_HEADER (100*1024) +#endif + +/* This is a magic return code for the write callback that, when returned, + will signal libcurl to pause receiving on the current transfer. */ +#define CURL_WRITEFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + +/* This callback will be called when a new resolver request is made */ +typedef int (*curl_resolver_start_callback)(void *resolver_state, + void *reserved, void *userdata); + +/* enumeration of file types */ +typedef enum { + CURLFILETYPE_FILE = 0, + CURLFILETYPE_DIRECTORY, + CURLFILETYPE_SYMLINK, + CURLFILETYPE_DEVICE_BLOCK, + CURLFILETYPE_DEVICE_CHAR, + CURLFILETYPE_NAMEDPIPE, + CURLFILETYPE_SOCKET, + CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ + + CURLFILETYPE_UNKNOWN /* should never occur */ +} curlfiletype; + +#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) +#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) +#define CURLFINFOFLAG_KNOWN_TIME (1<<2) +#define CURLFINFOFLAG_KNOWN_PERM (1<<3) +#define CURLFINFOFLAG_KNOWN_UID (1<<4) +#define CURLFINFOFLAG_KNOWN_GID (1<<5) +#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) +#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) + +/* Content of this structure depends on information which is known and is + achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man + page for callbacks returning this structure -- some fields are mandatory, + some others are optional. The FLAG field has special meaning. */ +struct curl_fileinfo { + char *filename; + curlfiletype filetype; + time_t time; /* always zero! */ + unsigned int perm; + int uid; + int gid; + curl_off_t size; + long int hardlinks; + + struct { + /* If some of these fields is not NULL, it is a pointer to b_data. */ + char *time; + char *perm; + char *user; + char *group; + char *target; /* pointer to the target filename of a symlink */ + } strings; + + unsigned int flags; + + /* used internally */ + char *b_data; + size_t b_size; + size_t b_used; +}; + +/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ +#define CURL_CHUNK_BGN_FUNC_OK 0 +#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ +#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ + +/* if splitting of data transfer is enabled, this callback is called before + download of an individual chunk started. Note that parameter "remains" works + only for FTP wildcard downloading (for now), otherwise is not used */ +typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, + void *ptr, + int remains); + +/* return codes for CURLOPT_CHUNK_END_FUNCTION */ +#define CURL_CHUNK_END_FUNC_OK 0 +#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ + +/* If splitting of data transfer is enabled this callback is called after + download of an individual chunk finished. + Note! After this callback was set then it have to be called FOR ALL chunks. + Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. + This is the reason why we don't need "transfer_info" parameter in this + callback and we are not interested in "remains" parameter too. */ +typedef long (*curl_chunk_end_callback)(void *ptr); + +/* return codes for FNMATCHFUNCTION */ +#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ +#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ +#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ + +/* callback type for wildcard downloading pattern matching. If the + string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ +typedef int (*curl_fnmatch_callback)(void *ptr, + const char *pattern, + const char *string); + +/* These are the return codes for the seek callbacks */ +#define CURL_SEEKFUNC_OK 0 +#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ +#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so + libcurl might try other means instead */ +typedef int (*curl_seek_callback)(void *instream, + curl_off_t offset, + int origin); /* 'whence' */ + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +/* This is a return code for the read callback that, when returned, will + signal libcurl to pause sending data on the current transfer. */ +#define CURL_READFUNC_PAUSE 0x10000001 + +/* Return code for when the trailing headers' callback has terminated + without any errors*/ +#define CURL_TRAILERFUNC_OK 0 +/* Return code for when was an error in the trailing header's list and we + want to abort the request */ +#define CURL_TRAILERFUNC_ABORT 1 + +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + +typedef int (*curl_trailer_callback)(struct curl_slist **list, + void *userdata); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ + CURLSOCKTYPE_LAST /* never use */ +} curlsocktype; + +/* The return code from the sockopt_callback can signal information back + to libcurl: */ +#define CURL_SOCKOPT_OK 0 +#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return + CURLE_ABORTED_BY_CALLBACK */ +#define CURL_SOCKOPT_ALREADY_CONNECTED 2 + +typedef int (*curl_sockopt_callback)(void *clientp, + curl_socket_t curlfd, + curlsocktype purpose); + +struct curl_sockaddr { + int family; + int socktype; + int protocol; + unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it + turned really ugly and painful on the systems that + lack this type */ + struct sockaddr addr; +}; + +typedef curl_socket_t +(*curl_opensocket_callback)(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address); + +typedef int +(*curl_closesocket_callback)(void *clientp, curl_socket_t item); + +typedef enum { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} curlioerr; + +typedef enum { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} curliocmd; + +typedef curlioerr (*curl_ioctl_callback)(CURL *handle, + int cmd, + void *clientp); + +#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS +/* + * The following typedef's are signatures of malloc, free, realloc, strdup and + * calloc respectively. Function pointers of these types can be passed to the + * curl_global_init_mem() function to set user defined memory management + * callback routines. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); + +#define CURL_DID_MEMORY_FUNC_TYPEDEFS +#endif + +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userptr); /* whatever the user please */ + +/* All possible error codes from all sorts of curl functions. Future versions + may return other values, stay prepared. + + Always add new return codes last. Never *EVER* remove any. The return + codes must remain the same! + */ + +typedef enum { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for + 7.17.0, reused in April 2011 for 7.21.5] */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for + 7.15.4, reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server + [was obsoleted in August 2007 for 7.17.0, + reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. + [was obsoleted in August 2007 for 7.17.0, + reused in July 2014 for 7.38.0] */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ + CURLE_OBSOLETE51, /* 51 - NOT USED */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ + CURLE_PEER_FAILED_VERIFICATION, /* 60 - peer's certificate or fingerprint + wasn't verified fine */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURLE_AGAIN, /* 81 - socket is not ready for send/recv, + wait till it's ready and try again (Added + in 7.18.2) */ + CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or + wrong format (Added in 7.19.0) */ + CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in + 7.19.0) */ + CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ + CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ + CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ + CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ + CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ + CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the + session will be queued */ + CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not + match */ + CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ + CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer + */ + CURLE_RECURSIVE_API_CALL, /* 93 - an api function was called from + inside a callback */ + CURL_LAST /* never use! */ +} CURLcode; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Previously obsolete error code re-used in 7.38.0 */ +#define CURLE_OBSOLETE16 CURLE_HTTP2 + +/* Previously obsolete error codes re-used in 7.24.0 */ +#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED +#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT + +/* compatibility with older names */ +#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING +#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY + +/* The following were added in 7.62.0 */ +#define CURLE_SSL_CACERT CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.21.5, April 2011 */ +#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION + +/* The following were added in 7.17.1 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.17.0 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 +#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN + +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED + +/* The following were added earlier */ + +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT + +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED + +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME + +/* This was the error code 50 in 7.7.3 and a few earlier versions, this + is no longer used by libcurl but is instead #defined here only to not + make programs break */ +#define CURLE_ALREADY_COMPLETE 99999 + +/* Provide defines for really old option names */ +#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ +#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ +#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA + +/* Since long deprecated options with no code in the lib that does anything + with them. */ +#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 +#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 + +#endif /*!CURL_NO_OLDIES*/ + +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ + void *ssl_ctx, /* actually an OpenSSL + or WolfSSL SSL_CTX, + or an mbedTLS + mbedtls_ssl_config */ + void *userptr); + +typedef enum { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_HTTPS = 2, /* added in 7.52.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already + in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} curl_proxytype; /* this enum was added in 7.10 */ + +/* + * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: + * + * CURLAUTH_NONE - No HTTP authentication + * CURLAUTH_BASIC - HTTP Basic authentication (default) + * CURLAUTH_DIGEST - HTTP Digest authentication + * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication + * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) + * CURLAUTH_NTLM - HTTP NTLM authentication + * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour + * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper + * CURLAUTH_BEARER - HTTP Bearer token authentication + * CURLAUTH_ONLY - Use together with a single other type to force no + * authentication or just that single type + * CURLAUTH_ANY - All fine types set + * CURLAUTH_ANYSAFE - All fine types except Basic + */ + +#define CURLAUTH_NONE ((unsigned long)0) +#define CURLAUTH_BASIC (((unsigned long)1)<<0) +#define CURLAUTH_DIGEST (((unsigned long)1)<<1) +#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) +/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ +#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE +/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */ +#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE +#define CURLAUTH_NTLM (((unsigned long)1)<<3) +#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) +#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) +#define CURLAUTH_BEARER (((unsigned long)1)<<6) +#define CURLAUTH_ONLY (((unsigned long)1)<<31) +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ +#define CURLSSH_AUTH_GSSAPI (1<<5) /* gssapi (kerberos, ...) */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ +#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ +#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ + +#define CURL_ERROR_SIZE 256 + +enum curl_khtype { + CURLKHTYPE_UNKNOWN, + CURLKHTYPE_RSA1, + CURLKHTYPE_RSA, + CURLKHTYPE_DSS, + CURLKHTYPE_ECDSA, + CURLKHTYPE_ED25519 +}; + +struct curl_khkey { + const char *key; /* points to a zero-terminated string encoded with base64 + if len is zero, otherwise to the "raw" data */ + size_t len; + enum curl_khtype keytype; +}; + +/* this is the set of return values expected from the curl_sshkeycallback + callback */ +enum curl_khstat { + CURLKHSTAT_FINE_ADD_TO_FILE, + CURLKHSTAT_FINE, + CURLKHSTAT_REJECT, /* reject the connection, return an error */ + CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so + this causes a CURLE_DEFER error but otherwise the + connection will be left intact etc */ + CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ +}; + +/* this is the set of status codes pass in to the callback */ +enum curl_khmatch { + CURLKHMATCH_OK, /* match */ + CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ + CURLKHMATCH_MISSING, /* no matching host/key found */ + CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ +}; + +typedef int + (*curl_sshkeycallback) (CURL *easy, /* easy handle */ + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch, /* libcurl's view on the keys */ + void *clientp); /* custom pointer passed from app */ + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ + +/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the + name of improving interoperability with older servers. Some SSL libraries + have introduced work-arounds for this flaw but those work-arounds sometimes + make the SSL communication fail. To regain functionality with those broken + servers, a user can this way allow the vulnerability back. */ +#define CURLSSLOPT_ALLOW_BEAST (1<<0) + +/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those + SSL backends where such behavior is present. */ +#define CURLSSLOPT_NO_REVOKE (1<<1) + +/* The default connection attempt delay in milliseconds for happy eyeballs. + CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document + this value, keep them in sync. */ +#define CURL_HET_DEFAULT 200L + +/* The default connection upkeep interval in milliseconds. */ +#define CURL_UPKEEP_INTERVAL_DEFAULT 60000L + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +#define CURLFTPSSL_NONE CURLUSESSL_NONE +#define CURLFTPSSL_TRY CURLUSESSL_TRY +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL +#define CURLFTPSSL_ALL CURLUSESSL_ALL +#define CURLFTPSSL_LAST CURLUSESSL_LAST +#define curl_ftpssl curl_usessl +#endif /*!CURL_NO_OLDIES*/ + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +typedef enum { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} curl_ftpccc; + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +typedef enum { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} curl_ftpauth; + +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +typedef enum { + CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ + CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD + again if MKD succeeded, for SFTP this does + similar magic */ + CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD + again even if MKD failed! */ + CURLFTP_CREATE_DIR_LAST /* not an option, never use */ +} curl_ftpcreatedir; + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +typedef enum { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} curl_ftpmethod; + +/* bitmask defines for CURLOPT_HEADEROPT */ +#define CURLHEADER_UNIFIED 0 +#define CURLHEADER_SEPARATE (1<<0) + +/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */ +#define CURLALTSVC_IMMEDIATELY (1<<0) +#define CURLALTSVC_ALTUSED (1<<1) +#define CURLALTSVC_READONLYFILE (1<<2) +#define CURLALTSVC_H1 (1<<3) +#define CURLALTSVC_H2 (1<<4) +#define CURLALTSVC_H3 (1<<5) + +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +#define CURLPROTO_HTTP (1<<0) +#define CURLPROTO_HTTPS (1<<1) +#define CURLPROTO_FTP (1<<2) +#define CURLPROTO_FTPS (1<<3) +#define CURLPROTO_SCP (1<<4) +#define CURLPROTO_SFTP (1<<5) +#define CURLPROTO_TELNET (1<<6) +#define CURLPROTO_LDAP (1<<7) +#define CURLPROTO_LDAPS (1<<8) +#define CURLPROTO_DICT (1<<9) +#define CURLPROTO_FILE (1<<10) +#define CURLPROTO_TFTP (1<<11) +#define CURLPROTO_IMAP (1<<12) +#define CURLPROTO_IMAPS (1<<13) +#define CURLPROTO_POP3 (1<<14) +#define CURLPROTO_POP3S (1<<15) +#define CURLPROTO_SMTP (1<<16) +#define CURLPROTO_SMTPS (1<<17) +#define CURLPROTO_RTSP (1<<18) +#define CURLPROTO_RTMP (1<<19) +#define CURLPROTO_RTMPT (1<<20) +#define CURLPROTO_RTMPE (1<<21) +#define CURLPROTO_RTMPTE (1<<22) +#define CURLPROTO_RTMPS (1<<23) +#define CURLPROTO_RTMPTS (1<<24) +#define CURLPROTO_GOPHER (1<<25) +#define CURLPROTO_SMB (1<<26) +#define CURLPROTO_SMBS (1<<27) +#define CURLPROTO_ALL (~0) /* enable everything */ + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the + string options from the header file */ + +/* name is uppercase CURLOPT_, + type is one of the defined CURLOPTTYPE_ + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif + +#ifdef CURL_ISOCPP +#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLOPT_/**/name = type + number +#endif + +/* handy aliases that make no run-time difference */ +#define CURLOPTTYPE_STRINGPOINT CURLOPTTYPE_OBJECTPOINT +#define CURLOPTTYPE_SLISTPOINT CURLOPTTYPE_OBJECTPOINT + +/* + * This macro-mania below setups the CURLOPT_[what] enum, to be used with + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] + * word. + */ + +typedef enum { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(WRITEDATA, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, STRINGPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, STRINGPOINT, 4), + + /* "user:password;options" to use when fetching. */ + CINIT(USERPWD, STRINGPOINT, 5), + + /* "user:password" to use with proxy. */ + CINIT(PROXYUSERPWD, STRINGPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, STRINGPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(READDATA, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was successful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referrer page (needed by some CGIs) */ + CINIT(REFERER, STRINGPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, STRINGPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, STRINGPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, STRINGPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind. This + list is also used for RTSP (in spite of its name) */ + CINIT(HTTPHEADER, SLISTPOINT, 23), + + /* This points to a linked list of post entries, struct curl_httppost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, STRINGPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, STRINGPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, SLISTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(HEADERDATA, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, STRINGPOINT, 31), + + /* What version to specifically try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, STRINGPOINT, 36), + + /* FILE handle to use instead of stderr */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, SLISTPOINT, 39), + + CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */ + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* DEPRECATED + * Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION + callbacks */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), +#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA + + /* We want the referrer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, STRINGPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, STRINGPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, STRINGPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, SLISTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */ + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, STRINGPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, STRINGPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects are + OK within this time, then fine... This only aborts the connect phase. */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, STRINGPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specifically switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, STRINGPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, STRINGPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, STRINGPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, STRINGPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands */ + CINIT(PREQUOTE, SLISTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, STRINGPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and + CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. Before 7.21.6, this was known as + CURLOPT_ENCODING */ + CINIT(ACCEPT_ENCODING, STRINGPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, SLISTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentially send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specifically switch on or off the FTP engine's use of the EPRT command ( + it also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL or + WolfSSL ssl_ctx, or mbedTLS mbedtls_ssl_config in the second argument. + The function must match the curl_ssl_ctx_callback prototype. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server. + In 7.19.4 we introduced the convenience enums for this option using the + CURLFTP_CREATE_DIR prefix. + */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), +#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, STRINGPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLUSESSL_TRY - try using SSL, proceed anyway otherwise + CURLUSESSL_CONTROL - SSL for the control connection or fail + CURLUSESSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, STRINGPOINT, 134), + + /* feed cookie into cookie engine */ + CINIT(COOKIELIST, STRINGPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the application even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Set the behaviour of POST when redirecting. Values must be set to one + of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ + CINIT(POSTREDIR, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ + CINIT(PROXY_TRANSFER_MODE, LONG, 166), + + /* Callback function for seeking in the input stream */ + CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), + CINIT(SEEKDATA, OBJECTPOINT, 168), + + /* CRL file */ + CINIT(CRLFILE, STRINGPOINT, 169), + + /* Issuer certificate */ + CINIT(ISSUERCERT, STRINGPOINT, 170), + + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + + /* Collect certificate chain info and allow it to get retrievable with + CURLINFO_CERTINFO after the transfer is complete. */ + CINIT(CERTINFO, LONG, 172), + + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, STRINGPOINT, 173), + CINIT(PASSWORD, STRINGPOINT, 174), + + /* "name" and "pwd" to use with Proxy when fetching. */ + CINIT(PROXYUSERNAME, STRINGPOINT, 175), + CINIT(PROXYPASSWORD, STRINGPOINT, 176), + + /* Comma separated list of hostnames defining no-proxy zones. These should + match both hostnames directly, and hostnames within a domain. For + example, local.com will match local.com and www.local.com, but NOT + notlocal.com or www.notlocal.com. For compatibility with other + implementations of this, .local.com will be considered to be the same as + local.com. A single * is the only valid wildcard, and effectively + disables the use of proxy. */ + CINIT(NOPROXY, STRINGPOINT, 177), + + /* block size for TFTP transfers */ + CINIT(TFTP_BLKSIZE, LONG, 178), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */ + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + CINIT(PROTOCOLS, LONG, 181), + + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. */ + CINIT(REDIR_PROTOCOLS, LONG, 182), + + /* set the SSH knownhost file name to use */ + CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183), + + /* set the SSH host key callback, must point to a curl_sshkeycallback + function */ + CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + + /* set the SSH host key callback custom pointer */ + CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + + /* set the SMTP mail originator */ + CINIT(MAIL_FROM, STRINGPOINT, 186), + + /* set the list of SMTP mail receiver(s) */ + CINIT(MAIL_RCPT, SLISTPOINT, 187), + + /* FTP: send PRET before PASV */ + CINIT(FTP_USE_PRET, LONG, 188), + + /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ + CINIT(RTSP_REQUEST, LONG, 189), + + /* The RTSP session identifier */ + CINIT(RTSP_SESSION_ID, STRINGPOINT, 190), + + /* The RTSP stream URI */ + CINIT(RTSP_STREAM_URI, STRINGPOINT, 191), + + /* The Transport: header to use in RTSP requests */ + CINIT(RTSP_TRANSPORT, STRINGPOINT, 192), + + /* Manually initialize the client RTSP CSeq for this handle */ + CINIT(RTSP_CLIENT_CSEQ, LONG, 193), + + /* Manually initialize the server RTSP CSeq for this handle */ + CINIT(RTSP_SERVER_CSEQ, LONG, 194), + + /* The stream to pass to INTERLEAVEFUNCTION. */ + CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), + + /* Let the application define a custom write method for RTP data */ + CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), + + /* Turn on wildcard matching */ + CINIT(WILDCARDMATCH, LONG, 197), + + /* Directory matching callback called before downloading of an + individual file (chunk) started */ + CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), + + /* Directory matching callback called after the file (chunk) + was downloaded, or skipped */ + CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), + + /* Change match (fnmatch-like) callback for wildcard matching */ + CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), + + /* Let the application define custom chunk data pointer */ + CINIT(CHUNK_DATA, OBJECTPOINT, 201), + + /* FNMATCH_FUNCTION user pointer */ + CINIT(FNMATCH_DATA, OBJECTPOINT, 202), + + /* send linked-list of name:port:address sets */ + CINIT(RESOLVE, SLISTPOINT, 203), + + /* Set a username for authenticated TLS */ + CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204), + + /* Set a password for authenticated TLS */ + CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205), + + /* Set authentication type for authenticated TLS */ + CINIT(TLSAUTH_TYPE, STRINGPOINT, 206), + + /* Set to 1 to enable the "TE:" header in HTTP requests to ask for + compressed transfer-encoded responses. Set to 0 to disable the use of TE: + in outgoing requests. The current default is 0, but it might change in a + future libcurl release. + + libcurl will ask for the compressed methods it knows of, and if that + isn't any, it will not ask for transfer-encoding at all even if this + option is set to 1. + + */ + CINIT(TRANSFER_ENCODING, LONG, 207), + + /* Callback function for closing socket (instead of close(2)). The callback + should have type curl_closesocket_callback */ + CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), + CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), + + /* allow GSSAPI credential delegation */ + CINIT(GSSAPI_DELEGATION, LONG, 210), + + /* Set the name servers to use for DNS resolution */ + CINIT(DNS_SERVERS, STRINGPOINT, 211), + + /* Time-out accept operations (currently for FTP only) after this amount + of milliseconds. */ + CINIT(ACCEPTTIMEOUT_MS, LONG, 212), + + /* Set TCP keepalive */ + CINIT(TCP_KEEPALIVE, LONG, 213), + + /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ + CINIT(TCP_KEEPIDLE, LONG, 214), + CINIT(TCP_KEEPINTVL, LONG, 215), + + /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ + CINIT(SSL_OPTIONS, LONG, 216), + + /* Set the SMTP auth originator */ + CINIT(MAIL_AUTH, STRINGPOINT, 217), + + /* Enable/disable SASL initial response */ + CINIT(SASL_IR, LONG, 218), + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_xferinfo_callback + * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ + CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219), + + /* The XOAUTH2 bearer token */ + CINIT(XOAUTH2_BEARER, STRINGPOINT, 220), + + /* Set the interface string to use as outgoing network + * interface for DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_INTERFACE, STRINGPOINT, 221), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222), + + /* Set the local IPv6 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223), + + /* Set authentication options directly */ + CINIT(LOGIN_OPTIONS, STRINGPOINT, 224), + + /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_NPN, LONG, 225), + + /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_ALPN, LONG, 226), + + /* Time to wait for a response to a HTTP request containing an + * Expect: 100-continue header before sending the data anyway. */ + CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227), + + /* This points to a linked list of headers used for proxy requests only, + struct curl_slist kind */ + CINIT(PROXYHEADER, SLISTPOINT, 228), + + /* Pass in a bitmask of "header options" */ + CINIT(HEADEROPT, LONG, 229), + + /* The public key in DER form used to validate the peer public key + this option is used only if SSL_VERIFYPEER is true */ + CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230), + + /* Path to Unix domain socket */ + CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231), + + /* Set if we should verify the certificate status. */ + CINIT(SSL_VERIFYSTATUS, LONG, 232), + + /* Set if we should enable TLS false start. */ + CINIT(SSL_FALSESTART, LONG, 233), + + /* Do not squash dot-dot sequences */ + CINIT(PATH_AS_IS, LONG, 234), + + /* Proxy Service Name */ + CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235), + + /* Service Name */ + CINIT(SERVICE_NAME, STRINGPOINT, 236), + + /* Wait/don't wait for pipe/mutex to clarify */ + CINIT(PIPEWAIT, LONG, 237), + + /* Set the protocol used when curl is given a URL without a protocol */ + CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238), + + /* Set stream weight, 1 - 256 (default is 16) */ + CINIT(STREAM_WEIGHT, LONG, 239), + + /* Set stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS, OBJECTPOINT, 240), + + /* Set E-xclusive stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241), + + /* Do not send any tftp option requests to the server */ + CINIT(TFTP_NO_OPTIONS, LONG, 242), + + /* Linked-list of host:port:connect-to-host:connect-to-port, + overrides the URL's host:port (only for the network layer) */ + CINIT(CONNECT_TO, SLISTPOINT, 243), + + /* Set TCP Fast Open */ + CINIT(TCP_FASTOPEN, LONG, 244), + + /* Continue to send data if the server responds early with an + * HTTP status code >= 300 */ + CINIT(KEEP_SENDING_ON_ERROR, LONG, 245), + + /* The CApath or CAfile used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_CAINFO, STRINGPOINT, 246), + + /* The CApath directory used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_CAPATH, STRINGPOINT, 247), + + /* Set if we should verify the proxy in ssl handshake, + set 1 to verify. */ + CINIT(PROXY_SSL_VERIFYPEER, LONG, 248), + + /* Set if we should verify the Common name from the proxy certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches + * the provided hostname. */ + CINIT(PROXY_SSL_VERIFYHOST, LONG, 249), + + /* What version to specifically try to use for proxy. + See CURL_SSLVERSION defines below. */ + CINIT(PROXY_SSLVERSION, LONG, 250), + + /* Set a username for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251), + + /* Set a password for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252), + + /* Set authentication type for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253), + + /* name of the file keeping your private SSL-certificate for proxy */ + CINIT(PROXY_SSLCERT, STRINGPOINT, 254), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for + proxy */ + CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255), + + /* name of the file keeping your private SSL-key for proxy */ + CINIT(PROXY_SSLKEY, STRINGPOINT, 256), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for + proxy */ + CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257), + + /* password for the SSL private key for proxy */ + CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258), + + /* Specify which SSL ciphers to use for proxy */ + CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259), + + /* CRL file for proxy */ + CINIT(PROXY_CRLFILE, STRINGPOINT, 260), + + /* Enable/disable specific SSL features with a bitmask for proxy, see + CURLSSLOPT_* */ + CINIT(PROXY_SSL_OPTIONS, LONG, 261), + + /* Name of pre proxy to use. */ + CINIT(PRE_PROXY, STRINGPOINT, 262), + + /* The public key in DER form used to validate the proxy public key + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263), + + /* Path to an abstract Unix domain socket */ + CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264), + + /* Suppress proxy CONNECT response headers from user callbacks */ + CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265), + + /* The request target, instead of extracted from the URL */ + CINIT(REQUEST_TARGET, STRINGPOINT, 266), + + /* bitmask of allowed auth methods for connections to SOCKS5 proxies */ + CINIT(SOCKS5_AUTH, LONG, 267), + + /* Enable/disable SSH compression */ + CINIT(SSH_COMPRESSION, LONG, 268), + + /* Post MIME data. */ + CINIT(MIMEPOST, OBJECTPOINT, 269), + + /* Time to use with the CURLOPT_TIMECONDITION. Specified in number of + seconds since 1 Jan 1970. */ + CINIT(TIMEVALUE_LARGE, OFF_T, 270), + + /* Head start in milliseconds to give happy eyeballs. */ + CINIT(HAPPY_EYEBALLS_TIMEOUT_MS, LONG, 271), + + /* Function that will be called before a resolver request is made */ + CINIT(RESOLVER_START_FUNCTION, FUNCTIONPOINT, 272), + + /* User data to pass to the resolver start callback. */ + CINIT(RESOLVER_START_DATA, OBJECTPOINT, 273), + + /* send HAProxy PROXY protocol header? */ + CINIT(HAPROXYPROTOCOL, LONG, 274), + + /* shuffle addresses before use when DNS returns multiple */ + CINIT(DNS_SHUFFLE_ADDRESSES, LONG, 275), + + /* Specify which TLS 1.3 ciphers suites to use */ + CINIT(TLS13_CIPHERS, STRINGPOINT, 276), + CINIT(PROXY_TLS13_CIPHERS, STRINGPOINT, 277), + + /* Disallow specifying username/login in URL. */ + CINIT(DISALLOW_USERNAME_IN_URL, LONG, 278), + + /* DNS-over-HTTPS URL */ + CINIT(DOH_URL, STRINGPOINT, 279), + + /* Preferred buffer size to use for uploads */ + CINIT(UPLOAD_BUFFERSIZE, LONG, 280), + + /* Time in ms between connection upkeep calls for long-lived connections. */ + CINIT(UPKEEP_INTERVAL_MS, LONG, 281), + + /* Specify URL using CURL URL API. */ + CINIT(CURLU, OBJECTPOINT, 282), + + /* add trailing data just after no more data is available */ + CINIT(TRAILERFUNCTION, FUNCTIONPOINT, 283), + + /* pointer to be passed to HTTP_TRAILER_FUNCTION */ + CINIT(TRAILERDATA, OBJECTPOINT, 284), + + /* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */ + CINIT(HTTP09_ALLOWED, LONG, 285), + + /* alt-svc control bitmask */ + CINIT(ALTSVC_CTRL, LONG, 286), + + /* alt-svc cache file name to possibly read from/write to */ + CINIT(ALTSVC, STRINGPOINT, 287), + + /* maximum age of a connection to consider it for reuse (in seconds) */ + CINIT(MAXAGE_CONN, LONG, 288), + + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2011 */ + +/* This was added in version 7.19.1 */ +#define CURLOPT_POST301 CURLOPT_POSTREDIR + +/* These are scheduled to disappear by 2009 */ + +/* The following were added in 7.17.0 */ +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_FTPAPPEND CURLOPT_APPEND +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL + +/* The following were added earlier */ + +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ + + /* three convenient "aliases" that follow the name scheme better */ +#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ + CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ + CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 + Upgrade */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +}; + +/* Convenience definition simple because the name of the version is HTTP/2 and + not 2.0. The 2_0 version of the enum name was set while the version was + still planned to be 2.0 and we stick to it for compatibility. */ +#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 + +/* + * Public API enums for RTSP requests + */ +enum { + CURL_RTSPREQ_NONE, /* first in list */ + CURL_RTSPREQ_OPTIONS, + CURL_RTSPREQ_DESCRIBE, + CURL_RTSPREQ_ANNOUNCE, + CURL_RTSPREQ_SETUP, + CURL_RTSPREQ_PLAY, + CURL_RTSPREQ_PAUSE, + CURL_RTSPREQ_TEARDOWN, + CURL_RTSPREQ_GET_PARAMETER, + CURL_RTSPREQ_SET_PARAMETER, + CURL_RTSPREQ_RECORD, + CURL_RTSPREQ_RECEIVE, + CURL_RTSPREQ_LAST /* last in list */ +}; + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +}; + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, /* TLS 1.x */ + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + CURL_SSLVERSION_TLSv1_0, + CURL_SSLVERSION_TLSv1_1, + CURL_SSLVERSION_TLSv1_2, + CURL_SSLVERSION_TLSv1_3, + + CURL_SSLVERSION_LAST /* never use, keep last */ +}; + +enum { + CURL_SSLVERSION_MAX_NONE = 0, + CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16), + CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16), + CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16), + CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16), + CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16), + + /* never use, keep last */ + CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16) +}; + +enum CURL_TLSAUTH { + CURL_TLSAUTH_NONE, + CURL_TLSAUTH_SRP, + CURL_TLSAUTH_LAST /* never use, keep last */ +}; + +/* symbols to use with CURLOPT_POSTREDIR. + CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 + can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 + | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ + +#define CURL_REDIR_GET_ALL 0 +#define CURL_REDIR_POST_301 1 +#define CURL_REDIR_POST_302 2 +#define CURL_REDIR_POST_303 4 +#define CURL_REDIR_POST_ALL \ + (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + +/* Special size_t value signaling a zero-terminated string. */ +#define CURL_ZERO_TERMINATED ((size_t) -1) + +/* curl_strequal() and curl_strnequal() are subject for removal in a future + release */ +CURL_EXTERN int curl_strequal(const char *s1, const char *s2); +CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n); + +/* Mime/form handling support. */ +typedef struct curl_mime_s curl_mime; /* Mime context. */ +typedef struct curl_mimepart_s curl_mimepart; /* Mime part context. */ + +/* + * NAME curl_mime_init() + * + * DESCRIPTION + * + * Create a mime context and return its handle. The easy parameter is the + * target handle. + */ +CURL_EXTERN curl_mime *curl_mime_init(CURL *easy); + +/* + * NAME curl_mime_free() + * + * DESCRIPTION + * + * release a mime handle and its substructures. + */ +CURL_EXTERN void curl_mime_free(curl_mime *mime); + +/* + * NAME curl_mime_addpart() + * + * DESCRIPTION + * + * Append a new empty part to the given mime context and return a handle to + * the created part. + */ +CURL_EXTERN curl_mimepart *curl_mime_addpart(curl_mime *mime); + +/* + * NAME curl_mime_name() + * + * DESCRIPTION + * + * Set mime/form part name. + */ +CURL_EXTERN CURLcode curl_mime_name(curl_mimepart *part, const char *name); + +/* + * NAME curl_mime_filename() + * + * DESCRIPTION + * + * Set mime part remote file name. + */ +CURL_EXTERN CURLcode curl_mime_filename(curl_mimepart *part, + const char *filename); + +/* + * NAME curl_mime_type() + * + * DESCRIPTION + * + * Set mime part type. + */ +CURL_EXTERN CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype); + +/* + * NAME curl_mime_encoder() + * + * DESCRIPTION + * + * Set mime data transfer encoder. + */ +CURL_EXTERN CURLcode curl_mime_encoder(curl_mimepart *part, + const char *encoding); + +/* + * NAME curl_mime_data() + * + * DESCRIPTION + * + * Set mime part data source from memory data, + */ +CURL_EXTERN CURLcode curl_mime_data(curl_mimepart *part, + const char *data, size_t datasize); + +/* + * NAME curl_mime_filedata() + * + * DESCRIPTION + * + * Set mime part data source from named file. + */ +CURL_EXTERN CURLcode curl_mime_filedata(curl_mimepart *part, + const char *filename); + +/* + * NAME curl_mime_data_cb() + * + * DESCRIPTION + * + * Set mime part data source from callback function. + */ +CURL_EXTERN CURLcode curl_mime_data_cb(curl_mimepart *part, + curl_off_t datasize, + curl_read_callback readfunc, + curl_seek_callback seekfunc, + curl_free_callback freefunc, + void *arg); + +/* + * NAME curl_mime_subparts() + * + * DESCRIPTION + * + * Set mime part data source from subparts. + */ +CURL_EXTERN CURLcode curl_mime_subparts(curl_mimepart *part, + curl_mime *subparts); +/* + * NAME curl_mime_headers() + * + * DESCRIPTION + * + * Set mime part headers. + */ +CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part, + struct curl_slist *headers, + int take_ownership); + +/* Old form API. */ +/* name is uppercase CURLFORM_ */ +#ifdef CFINIT +#undef CFINIT +#endif + +#ifdef CURL_ISOCPP +#define CFINIT(name) CURLFORM_ ## name +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define CFINIT(name) CURLFORM_/**/name +#endif + +typedef enum { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CFINIT(STREAM), + CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */ + + CURLFORM_LASTENTRY /* the last unused */ +} CURLformoption; + +#undef CFINIT /* done */ + +/* structure to be used as parameter for CURLFORM_ARRAY */ +struct curl_forms { + CURLformoption option; + const char *value; +}; + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +typedef enum { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} CURLFORMcode; + +/* + * NAME curl_formadd() + * + * DESCRIPTION + * + * Pretty advanced function for building multi-part formposts. Each invoke + * adds one part that together construct a full post. Then use + * CURLOPT_HTTPPOST to send it off to libcurl. + */ +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...); + +/* + * callback function for curl_formget() + * The void *arg pointer will be the one passed as second argument to + * curl_formget(). + * The character buffer passed to it must not be freed. + * Should return the buffer length passed to it as the argument "len" on + * success. + */ +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, + size_t len); + +/* + * NAME curl_formget() + * + * DESCRIPTION + * + * Serialize a curl_httppost struct built with curl_formadd(). + * Accepts a void pointer as second argument which will be passed to + * the curl_formget_callback function. + * Returns 0 on success. + */ +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append); +/* + * NAME curl_formfree() + * + * DESCRIPTION + * + * Free a multipart formpost previously built with curl_formadd(). + */ +CURL_EXTERN void curl_formfree(struct curl_httppost *form); + +/* + * NAME curl_getenv() + * + * DESCRIPTION + * + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is + * complete. DEPRECATED - see lib/README.curlx + */ +CURL_EXTERN char *curl_getenv(const char *variable); + +/* + * NAME curl_version() + * + * DESCRIPTION + * + * Returns a static ascii string of the libcurl version. + */ +CURL_EXTERN char *curl_version(void); + +/* + * NAME curl_easy_escape() + * + * DESCRIPTION + * + * Escapes URL strings (converts all letters consider illegal in URLs to their + * %XX versions). This function returns a new allocated string or NULL if an + * error occurred. + */ +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + + +/* + * NAME curl_easy_unescape() + * + * DESCRIPTION + * + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit + * versions). This function returns a new allocated string or NULL if an error + * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. + */ +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); + +/* + * NAME curl_free() + * + * DESCRIPTION + * + * Provided for de-allocation in the same translation unit that did the + * allocation. Added in libcurl 7.10 + */ +CURL_EXTERN void curl_free(void *p); + +/* + * NAME curl_global_init() + * + * DESCRIPTION + * + * curl_global_init() should be invoked exactly once for each application that + * uses libcurl and before any call of other libcurl functions. + * + * This function is not thread-safe! + */ +CURL_EXTERN CURLcode curl_global_init(long flags); + +/* + * NAME curl_global_init_mem() + * + * DESCRIPTION + * + * curl_global_init() or curl_global_init_mem() should be invoked exactly once + * for each application that uses libcurl. This function can be used to + * initialize libcurl and set user defined memory management callback + * functions. Users can implement memory management routines to check for + * memory leaks, check for mis-use of the curl library etc. User registered + * callback routines with be invoked by this library instead of the system + * memory management routines like malloc, free etc. + */ +CURL_EXTERN CURLcode curl_global_init_mem(long flags, + curl_malloc_callback m, + curl_free_callback f, + curl_realloc_callback r, + curl_strdup_callback s, + curl_calloc_callback c); + +/* + * NAME curl_global_cleanup() + * + * DESCRIPTION + * + * curl_global_cleanup() should be invoked exactly once for each application + * that uses libcurl + */ +CURL_EXTERN void curl_global_cleanup(void); + +/* linked-list structure for the CURLOPT_QUOTE option (and other) */ +struct curl_slist { + char *data; + struct curl_slist *next; +}; + +/* + * NAME curl_global_sslset() + * + * DESCRIPTION + * + * When built with multiple SSL backends, curl_global_sslset() allows to + * choose one. This function can only be called once, and it must be called + * *before* curl_global_init(). + * + * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The + * backend can also be specified via the name parameter (passing -1 as id). + * If both id and name are specified, the name will be ignored. If neither id + * nor name are specified, the function will fail with + * CURLSSLSET_UNKNOWN_BACKEND and set the "avail" pointer to the + * NULL-terminated list of available backends. + * + * Upon success, the function returns CURLSSLSET_OK. + * + * If the specified SSL backend is not available, the function returns + * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a NULL-terminated + * list of available SSL backends. + * + * The SSL backend can be set only once. If it has already been set, a + * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE. + */ + +typedef struct { + curl_sslbackend id; + const char *name; +} curl_ssl_backend; + +typedef enum { + CURLSSLSET_OK = 0, + CURLSSLSET_UNKNOWN_BACKEND, + CURLSSLSET_TOO_LATE, + CURLSSLSET_NO_BACKENDS /* libcurl was built without any SSL support */ +} CURLsslset; + +CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, + const curl_ssl_backend ***avail); + +/* + * NAME curl_slist_append() + * + * DESCRIPTION + * + * Appends a string to a linked list. If no list exists, it will be created + * first. Returns the new list, after appending. + */ +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, + const char *); + +/* + * NAME curl_slist_free_all() + * + * DESCRIPTION + * + * free a previously built curl_slist. + */ +CURL_EXTERN void curl_slist_free_all(struct curl_slist *); + +/* + * NAME curl_getdate() + * + * DESCRIPTION + * + * Returns the time, in seconds since 1 Jan 1970 of the time string given in + * the first argument. The time argument in the second parameter is unused + * and should be set to NULL. + */ +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); + +/* info about the certificate chain, only for OpenSSL, GnuTLS, Schannel, NSS + and GSKit builds. Asked for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ +struct curl_certinfo { + int num_of_certs; /* number of certificates with information */ + struct curl_slist **certinfo; /* for each index in this array, there's a + linked list with textual information in the + format "name: value" */ +}; + +/* Information about the SSL library used and the respective internal SSL + handle, which can be used to obtain further information regarding the + connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ +struct curl_tlssessioninfo { + curl_sslbackend backend; + void *internals; +}; + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_PTR 0x400000 /* same as SLIST */ +#define CURLINFO_SOCKET 0x500000 +#define CURLINFO_OFF_T 0x600000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SIZE_DOWNLOAD_T = CURLINFO_OFF_T + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_SPEED_UPLOAD_T = CURLINFO_OFF_T + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_FILETIME_T = CURLINFO_OFF_T + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_CONTENT_LENGTH_UPLOAD_T = CURLINFO_OFF_T + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_PTR + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_TLS_SESSION = CURLINFO_PTR + 43, + CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, + CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45, + CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, + CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, + CURLINFO_PROTOCOL = CURLINFO_LONG + 48, + CURLINFO_SCHEME = CURLINFO_STRING + 49, + /* Fill in new entries below here! */ + + /* Preferably these would be defined conditionally based on the + sizeof curl_off_t being 64-bits */ + CURLINFO_TOTAL_TIME_T = CURLINFO_OFF_T + 50, + CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51, + CURLINFO_CONNECT_TIME_T = CURLINFO_OFF_T + 52, + CURLINFO_PRETRANSFER_TIME_T = CURLINFO_OFF_T + 53, + CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54, + CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55, + CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56, + + CURLINFO_LASTONE = 56 +} CURLINFO; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +#define CURL_GLOBAL_SSL (1<<0) /* no purpose since since 7.57.0 */ +#define CURL_GLOBAL_WIN32 (1<<1) +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_NOTHING 0 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL +#define CURL_GLOBAL_ACK_EINTR (1<<2) + + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different data locks for a single share */ +typedef enum { + CURL_LOCK_DATA_NONE = 0, + /* CURL_LOCK_DATA_SHARE is used internally to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_PSL, + CURL_LOCK_DATA_LAST +} curl_lock_data; + +/* Different lock access types */ +typedef enum { + CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ + CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ + CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ + CURL_LOCK_ACCESS_LAST /* never use */ +} curl_lock_access; + +typedef void (*curl_lock_function)(CURL *handle, + curl_lock_data data, + curl_lock_access locktype, + void *userptr); +typedef void (*curl_unlock_function)(CURL *handle, + curl_lock_data data, + void *userptr); + + +typedef enum { + CURLSHE_OK, /* all is fine */ + CURLSHE_BAD_OPTION, /* 1 */ + CURLSHE_IN_USE, /* 2 */ + CURLSHE_INVALID, /* 3 */ + CURLSHE_NOMEM, /* 4 out of memory */ + CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ + CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ + CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ + CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock + callback functions */ + CURLSHOPT_LAST /* never use */ +} CURLSHoption; + +CURL_EXTERN CURLSH *curl_share_init(void); +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); + +/**************************************************************************** + * Structures for querying information about the curl library at runtime. + */ + +typedef enum { + CURLVERSION_FIRST, + CURLVERSION_SECOND, + CURLVERSION_THIRD, + CURLVERSION_FOURTH, + CURLVERSION_FIFTH, + CURLVERSION_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basically all programs ever that want to get version information. It is + meant to be a built-in version number for what kind of struct the caller + expects. If the struct ever changes, we redefine the NOW to another enum + from above. */ +#define CURLVERSION_NOW CURLVERSION_FIFTH + +typedef struct { + CURLversion age; /* age of the returned struct */ + const char *version; /* LIBCURL_VERSION */ + unsigned int version_num; /* LIBCURL_VERSION_NUM */ + const char *host; /* OS/host/cpu/machine when configured */ + int features; /* bitmask, see defines below */ + const char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used anymore, always 0 */ + const char *libz_version; /* human readable string */ + /* protocols is terminated by an entry with a NULL protoname */ + const char * const *protocols; + + /* The fields below this were added in CURLVERSION_SECOND */ + const char *ares; + int ares_num; + + /* This field was added in CURLVERSION_THIRD */ + const char *libidn; + + /* These field were added in CURLVERSION_FOURTH */ + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; + + const char *libssh_version; /* human readable string */ + + /* These fields were added in CURLVERSION_FIFTH */ + + unsigned int brotli_ver_num; /* Numeric Brotli version + (MAJOR << 24) | (MINOR << 12) | PATCH */ + const char *brotli_version; /* human readable string. */ + +} curl_version_info_data; + +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported + (deprecated) */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported + (deprecated) */ +#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ +#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are + supported */ +#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ +#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ +#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ +#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ +#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper + is supported */ +#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ +#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ +#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ +#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ +#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used + for cookie domain verification */ +#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */ +#define CURL_VERSION_MULTI_SSL (1<<22) /* Multiple SSL backends available */ +#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */ +#define CURL_VERSION_ALTSVC (1<<24) /* Alt-Svc handling built-in */ + + /* + * NAME curl_version_info() + * + * DESCRIPTION + * + * This function returns a pointer to a static copy of the version info + * struct. See above. + */ +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); + +/* + * NAME curl_easy_strerror() + * + * DESCRIPTION + * + * The curl_easy_strerror function may be used to turn a CURLcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_easy_strerror(CURLcode); + +/* + * NAME curl_share_strerror() + * + * DESCRIPTION + * + * The curl_share_strerror function may be used to turn a CURLSHcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_share_strerror(CURLSHcode); + +/* + * NAME curl_easy_pause() + * + * DESCRIPTION + * + * The curl_easy_pause function pauses or unpauses transfers. Select the new + * state by setting the bitmask, use the convenience defines below. + * + */ +CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); + +#define CURLPAUSE_RECV (1<<0) +#define CURLPAUSE_RECV_CONT (0) + +#define CURLPAUSE_SEND (1<<2) +#define CURLPAUSE_SEND_CONT (0) + +#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) +#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) + +#ifdef __cplusplus +} +#endif + +/* unfortunately, the easy.h and multi.h include files need options and info + stuff before they can be included! */ +#include "easy.h" /* nothing in curl is fun without the easy stuff */ +#include "multi.h" +#include "urlapi.h" + +/* the typechecker doesn't work in C++ (yet) */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ + !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) +#include "typecheck-gcc.h" +#else +#if defined(__STDC__) && (__STDC__ >= 1) +/* This preprocessor magic that replaces a call with the exact same call is + only done to make sure application authors pass exactly three arguments + to these functions. */ +#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) +#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) +#endif /* __STDC__ >= 1 */ +#endif /* gcc >= 4.3 && !__cplusplus */ + +#endif /* __CURL_CURL_H */ diff --git a/libcurl/include/curl/curlver.h b/libcurl/include/curl/curlver.h new file mode 100644 index 0000000..3e8789e --- /dev/null +++ b/libcurl/include/curl/curlver.h @@ -0,0 +1,77 @@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This header file contains nothing but libcurl version info, generated by + a script at release-time. This was made its own header file in 7.11.2 */ + +/* This is the global package copyright */ +#define LIBCURL_COPYRIGHT "1996 - 2019 Daniel Stenberg, ." + +/* This is the version number of the libcurl package from which this header + file origins: */ +#define LIBCURL_VERSION "7.65.3" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 +#define LIBCURL_VERSION_MINOR 65 +#define LIBCURL_VERSION_PATCH 3 + +/* This is the numeric version of the libcurl version number, meant for easier + parsing and comparions by programs. The LIBCURL_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. + + Note: This define is the full hex number and _does not_ use the + CURL_VERSION_BITS() macro since curl's own configure script greps for it + and needs it to contain the full number. +*/ +#define LIBCURL_VERSION_NUM 0x074103 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in git, as the timestamp is properly set in the + * tarballs by the maketgz script. + * + * The format of the date follows this template: + * + * "2007-11-23" + */ +#define LIBCURL_TIMESTAMP "2019-07-19" + +#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) +#define CURL_AT_LEAST_VERSION(x,y,z) \ + (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) + +#endif /* __CURL_CURLVER_H */ diff --git a/libcurl/include/curl/easy.h b/libcurl/include/curl/easy.h new file mode 100644 index 0000000..f42a8a9 --- /dev/null +++ b/libcurl/include/curl/easy.h @@ -0,0 +1,112 @@ +#ifndef __CURL_EASY_H +#define __CURL_EASY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN CURL *curl_easy_init(void); +CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); +CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); +CURL_EXTERN void curl_easy_cleanup(CURL *curl); + +/* + * NAME curl_easy_getinfo() + * + * DESCRIPTION + * + * Request internal information from the curl session with this function. The + * third argument MUST be a pointer to a long, a pointer to a char * or a + * pointer to a double (as the documentation describes elsewhere). The data + * pointed to will be filled in accordingly and can be relied upon only if the + * function returns CURLE_OK. This function is intended to get used *AFTER* a + * performed transfer, all results from this function are undefined until the + * transfer is completed. + */ +CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); + + +/* + * NAME curl_easy_duphandle() + * + * DESCRIPTION + * + * Creates a new curl session handle with the same options set for the handle + * passed in. Duplicating a handle could only be a matter of cloning data and + * options, internal state info and things like persistent connections cannot + * be transferred. It is useful in multithreaded applications when you can run + * curl_easy_duphandle() for each new thread to avoid a series of identical + * curl_easy_setopt() invokes in every thread. + */ +CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); + +/* + * NAME curl_easy_reset() + * + * DESCRIPTION + * + * Re-initializes a CURL handle to the default values. This puts back the + * handle to the same state as it was in when it was just created. + * + * It does keep: live connections, the Session ID cache, the DNS cache and the + * cookies. + */ +CURL_EXTERN void curl_easy_reset(CURL *curl); + +/* + * NAME curl_easy_recv() + * + * DESCRIPTION + * + * Receives data from the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, + size_t *n); + +/* + * NAME curl_easy_send() + * + * DESCRIPTION + * + * Sends data over the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, + size_t buflen, size_t *n); + + +/* + * NAME curl_easy_upkeep() + * + * DESCRIPTION + * + * Performs connection upkeep for the given session handle. + */ +CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libcurl/include/curl/mprintf.h b/libcurl/include/curl/mprintf.h new file mode 100644 index 0000000..e20f546 --- /dev/null +++ b/libcurl/include/curl/mprintf.h @@ -0,0 +1,50 @@ +#ifndef __CURL_MPRINTF_H +#define __CURL_MPRINTF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include +#include /* needed for FILE */ +#include "curl.h" /* for CURL_EXTERN */ + +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN int curl_mprintf(const char *format, ...); +CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); +CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); +CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, + const char *format, ...); +CURL_EXTERN int curl_mvprintf(const char *format, va_list args); +CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); +CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); +CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, + const char *format, va_list args); +CURL_EXTERN char *curl_maprintf(const char *format, ...); +CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); + +#ifdef __cplusplus +} +#endif + +#endif /* __CURL_MPRINTF_H */ diff --git a/libcurl/include/curl/multi.h b/libcurl/include/curl/multi.h new file mode 100644 index 0000000..b19dbaf --- /dev/null +++ b/libcurl/include/curl/multi.h @@ -0,0 +1,441 @@ +#ifndef __CURL_MULTI_H +#define __CURL_MULTI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + This is an "external" header file. Don't give away any internals here! + + GOALS + + o Enable a "pull" interface. The application that uses libcurl decides where + and when to ask libcurl to get/send data. + + o Enable multiple simultaneous transfers in the same thread without making it + complicated for the application. + + o Enable the application to select() on its own file descriptors and curl's + file descriptors simultaneous easily. + +*/ + +/* + * This header file should not really need to include "curl.h" since curl.h + * itself includes this file and we expect user applications to do #include + * without the need for especially including multi.h. + * + * For some reason we added this include here at one point, and rather than to + * break existing (wrongly written) libcurl applications, we leave it as-is + * but with this warning attached. + */ +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_multi CURLM; +#else +typedef void CURLM; +#endif + +typedef enum { + CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or + curl_multi_socket*() soon */ + CURLM_OK, + CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ + CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ + CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ + CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ + CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ + CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ + CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was + attempted to get added - again */ + CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a + callback */ + CURLM_LAST +} CURLMcode; + +/* just to make code nicer when using curl_multi_socket() you can now check + for CURLM_CALL_MULTI_SOCKET too in the same style it works for + curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ +#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM + +/* bitmask bits for CURLMOPT_PIPELINING */ +#define CURLPIPE_NOTHING 0L +#define CURLPIPE_HTTP1 1L +#define CURLPIPE_MULTIPLEX 2L + +typedef enum { + CURLMSG_NONE, /* first, not used */ + CURLMSG_DONE, /* This easy handle has completed. 'result' contains + the CURLcode of the transfer */ + CURLMSG_LAST /* last, not used */ +} CURLMSG; + +struct CURLMsg { + CURLMSG msg; /* what this message means */ + CURL *easy_handle; /* the handle it concerns */ + union { + void *whatever; /* message-specific data */ + CURLcode result; /* return code for transfer */ + } data; +}; +typedef struct CURLMsg CURLMsg; + +/* Based on poll(2) structure and values. + * We don't use pollfd and POLL* constants explicitly + * to cover platforms without poll(). */ +#define CURL_WAIT_POLLIN 0x0001 +#define CURL_WAIT_POLLPRI 0x0002 +#define CURL_WAIT_POLLOUT 0x0004 + +struct curl_waitfd { + curl_socket_t fd; + short events; + short revents; /* not supported yet */ +}; + +/* + * Name: curl_multi_init() + * + * Desc: inititalize multi-style curl usage + * + * Returns: a new CURLM handle to use in all 'curl_multi' functions. + */ +CURL_EXTERN CURLM *curl_multi_init(void); + +/* + * Name: curl_multi_add_handle() + * + * Desc: add a standard curl handle to the multi stack + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_remove_handle() + * + * Desc: removes a curl handle from the multi stack again + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_fdset() + * + * Desc: Ask curl for its fd_set sets. The app can use these to select() or + * poll() on. We want curl_multi_perform() called as soon as one of + * them are ready. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); + +/* + * Name: curl_multi_wait() + * + * Desc: Poll on all fds within a CURLM set as well as any + * additional fds passed to the function. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret); + + /* + * Name: curl_multi_perform() + * + * Desc: When the app thinks there's data available for curl it calls this + * function to read/write whatever there is right now. This returns + * as soon as the reads and writes are done. This function does not + * require that there actually is data available for reading or that + * data can be written, it can be called just in case. It returns + * the number of handles that still transfer data in the second + * argument's integer-pointer. + * + * Returns: CURLMcode type, general multi error code. *NOTE* that this only + * returns errors etc regarding the whole multi stack. There might + * still have occurred problems on individual transfers even when + * this returns OK. + */ +CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, + int *running_handles); + + /* + * Name: curl_multi_cleanup() + * + * Desc: Cleans up and removes a whole multi stack. It does not free or + * touch any individual easy handles in any way. We need to define + * in what state those handles will be if this function is called + * in the middle of a transfer. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); + +/* + * Name: curl_multi_info_read() + * + * Desc: Ask the multi handle if there's any messages/informationals from + * the individual transfers. Messages include informationals such as + * error code from the transfer or just the fact that a transfer is + * completed. More details on these should be written down as well. + * + * Repeated calls to this function will return a new struct each + * time, until a special "end of msgs" struct is returned as a signal + * that there is no more to get at this point. + * + * The data the returned pointer points to will not survive calling + * curl_multi_cleanup(). + * + * The 'CURLMsg' struct is meant to be very simple and only contain + * very basic information. If more involved information is wanted, + * we will provide the particular "transfer handle" in that struct + * and that should/could/would be used in subsequent + * curl_easy_getinfo() calls (or similar). The point being that we + * must never expose complex structs to applications, as then we'll + * undoubtably get backwards compatibility problems in the future. + * + * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out + * of structs. It also writes the number of messages left in the + * queue (after this read) in the integer the second argument points + * to. + */ +CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, + int *msgs_in_queue); + +/* + * Name: curl_multi_strerror() + * + * Desc: The curl_multi_strerror function may be used to turn a CURLMcode + * value into the equivalent human readable error string. This is + * useful for printing meaningful error messages. + * + * Returns: A pointer to a zero-terminated error message. + */ +CURL_EXTERN const char *curl_multi_strerror(CURLMcode); + +/* + * Name: curl_multi_socket() and + * curl_multi_socket_all() + * + * Desc: An alternative version of curl_multi_perform() that allows the + * application to pass in one of the file descriptors that have been + * detected to have "action" on them and let libcurl perform. + * See man page for details. + */ +#define CURL_POLL_NONE 0 +#define CURL_POLL_IN 1 +#define CURL_POLL_OUT 2 +#define CURL_POLL_INOUT 3 +#define CURL_POLL_REMOVE 4 + +#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD + +#define CURL_CSELECT_IN 0x01 +#define CURL_CSELECT_OUT 0x02 +#define CURL_CSELECT_ERR 0x04 + +typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* see above */ + void *userp, /* private callback + pointer */ + void *socketp); /* private socket + pointer */ +/* + * Name: curl_multi_timer_callback + * + * Desc: Called by libcurl whenever the library detects a change in the + * maximum number of milliseconds the app is allowed to wait before + * curl_multi_socket() or curl_multi_perform() must be called + * (to allow libcurl's timed events to take place). + * + * Returns: The callback should return zero. + */ +typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp); /* private callback + pointer */ + +CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, + curl_socket_t s, + int ev_bitmask, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); + +#ifndef CURL_ALLOW_OLD_MULTI_SOCKET +/* This macro below was added in 7.16.3 to push users who recompile to use + the new curl_multi_socket_action() instead of the old curl_multi_socket() +*/ +#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) +#endif + +/* + * Name: curl_multi_timeout() + * + * Desc: Returns the maximum number of milliseconds the app is allowed to + * wait before curl_multi_socket() or curl_multi_perform() must be + * called (to allow libcurl's timed events to take place). + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, + long *milliseconds); + +#undef CINIT /* re-using the same name as in curl.h */ + +#ifdef CURL_ISOCPP +#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLMOPT_/**/name = type + number +#endif + +typedef enum { + /* This is the socket callback function pointer */ + CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), + + /* This is the argument passed to the socket callback */ + CINIT(SOCKETDATA, OBJECTPOINT, 2), + + /* set to 1 to enable pipelining for this multi handle */ + CINIT(PIPELINING, LONG, 3), + + /* This is the timer callback function pointer */ + CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), + + /* This is the argument passed to the timer callback */ + CINIT(TIMERDATA, OBJECTPOINT, 5), + + /* maximum number of entries in the connection cache */ + CINIT(MAXCONNECTS, LONG, 6), + + /* maximum number of (pipelining) connections to one host */ + CINIT(MAX_HOST_CONNECTIONS, LONG, 7), + + /* maximum number of requests in a pipeline */ + CINIT(MAX_PIPELINE_LENGTH, LONG, 8), + + /* a connection with a content-length longer than this + will not be considered for pipelining */ + CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9), + + /* a connection with a chunk length longer than this + will not be considered for pipelining */ + CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10), + + /* a list of site names(+port) that are blacklisted from + pipelining */ + CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11), + + /* a list of server types that are blacklisted from + pipelining */ + CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12), + + /* maximum number of open connections in total */ + CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13), + + /* This is the server push callback function pointer */ + CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14), + + /* This is the argument passed to the server push callback */ + CINIT(PUSHDATA, OBJECTPOINT, 15), + + CURLMOPT_LASTENTRY /* the last unused */ +} CURLMoption; + + +/* + * Name: curl_multi_setopt() + * + * Desc: Sets options for the multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, + CURLMoption option, ...); + + +/* + * Name: curl_multi_assign() + * + * Desc: This function sets an association in the multi handle between the + * given socket and a private pointer of the application. This is + * (only) useful for curl_multi_socket uses. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, + curl_socket_t sockfd, void *sockp); + + +/* + * Name: curl_push_callback + * + * Desc: This callback gets called when a new stream is being pushed by the + * server. It approves or denies the new stream. + * + * Returns: CURL_PUSH_OK or CURL_PUSH_DENY. + */ +#define CURL_PUSH_OK 0 +#define CURL_PUSH_DENY 1 + +struct curl_pushheaders; /* forward declaration only */ + +CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, + size_t num); +CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, + const char *name); + +typedef int (*curl_push_callback)(CURL *parent, + CURL *easy, + size_t num_headers, + struct curl_pushheaders *headers, + void *userp); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/libcurl/include/curl/stdcheaders.h b/libcurl/include/curl/stdcheaders.h new file mode 100644 index 0000000..027b6f4 --- /dev/null +++ b/libcurl/include/curl/stdcheaders.h @@ -0,0 +1,33 @@ +#ifndef __STDC_HEADERS_H +#define __STDC_HEADERS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include + +size_t fread(void *, size_t, size_t, FILE *); +size_t fwrite(const void *, size_t, size_t, FILE *); + +int strcasecmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); + +#endif /* __STDC_HEADERS_H */ diff --git a/libcurl/include/curl/system.h b/libcurl/include/curl/system.h new file mode 100644 index 0000000..1e555ec --- /dev/null +++ b/libcurl/include/curl/system.h @@ -0,0 +1,493 @@ +#ifndef __CURL_SYSTEM_H +#define __CURL_SYSTEM_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Try to keep one section per platform, compiler and architecture, otherwise, + * if an existing section is reused for a different one and later on the + * original is adjusted, probably the piggybacking one can be adversely + * changed. + * + * In order to differentiate between platforms/compilers/architectures use + * only compiler built in predefined preprocessor symbols. + * + * curl_off_t + * ---------- + * + * For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit + * wide signed integral data type. The width of this data type must remain + * constant and independent of any possible large file support settings. + * + * As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit + * wide signed integral data type if there is no 64-bit type. + * + * As a general rule, curl_off_t shall not be mapped to off_t. This rule shall + * only be violated if off_t is the only 64-bit data type available and the + * size of off_t is independent of large file support settings. Keep your + * build on the safe side avoiding an off_t gating. If you have a 64-bit + * off_t then take for sure that another 64-bit data type exists, dig deeper + * and you will find it. + * + */ + +#if defined(__DJGPP__) || defined(__GO32__) +# if defined(__DJGPP__) && (__DJGPP__ > 1) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__SALFORDC__) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__BORLANDC__) +# if (__BORLANDC__ < 0x520) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__TURBOC__) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__WATCOMC__) +# if defined(__386__) +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__POCC__) +# if (__POCC__ < 280) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# elif defined(_MSC_VER) +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__LCC__) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__SYMBIAN32__) +# if defined(__EABI__) /* Treat all ARM compilers equally */ +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__CW32__) +# pragma longlong on +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__VC32__) +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int + +#elif defined(__MWERKS__) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(_WIN32_WCE) +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__MINGW32__) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_WS2TCPIP_H 1 + +#elif defined(__VMS) +# if defined(__VAX) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int + +#elif defined(__OS400__) +# if defined(__ILEC400__) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__MVS__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# elif defined(_LP64) +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__370__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# elif defined(_LP64) +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(TPF) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__TINYC__) /* also known as tcc */ + +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */ +# if !defined(__LP64) && (defined(__ILP32) || \ + defined(__i386) || \ + defined(__sparcv8) || \ + defined(__sparcv8plus)) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__LP64) || \ + defined(__amd64) || defined(__sparcv9) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +#elif defined(__xlc__) /* IBM xlc compiler */ +# if !defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +/* ===================================== */ +/* KEEP MSVC THE PENULTIMATE ENTRY */ +/* ===================================== */ + +#elif defined(_MSC_VER) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +/* ===================================== */ +/* KEEP GENERIC GCC THE LAST ENTRY */ +/* ===================================== */ + +#elif defined(__GNUC__) && !defined(_SCO_DS) +# if !defined(__LP64__) && \ + (defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \ + defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \ + defined(__sparc__) || defined(__mips__) || defined(__sh__) || \ + defined(__XTENSA__) || \ + (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \ + (defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L)) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__LP64__) || \ + defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \ + (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \ + (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +#else +/* generic "safe guess" on old 32 bit style */ +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +#endif + +#ifdef _AIX +/* AIX needs */ +#define CURL_PULL_SYS_POLL_H +#endif + + +/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file */ +/* ws2tcpip.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_WS2TCPIP_H +# include +# include +# include +#endif + +/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */ +/* sys/types.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */ +/* sys/socket.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file */ +/* sys/poll.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_POLL_H +# include +#endif + +/* Data type definition of curl_socklen_t. */ +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T + typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; +#endif + +/* Data type definition of curl_off_t. */ + +#ifdef CURL_TYPEOF_CURL_OFF_T + typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; +#endif + +/* + * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow + * these to be visible and exported by the external libcurl interface API, + * while also making them visible to the library internals, simply including + * curl_setup.h, without actually needing to include curl.h internally. + * If some day this section would grow big enough, all this should be moved + * to its own header file. + */ + +/* + * Figure out if we can use the ## preprocessor operator, which is supported + * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ + * or __cplusplus so we need to carefully check for them too. + */ + +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ + defined(__ILEC400__) + /* This compiler is believed to have an ISO compatible preprocessor */ +#define CURL_ISOCPP +#else + /* This compiler is believed NOT to have an ISO compatible preprocessor */ +#undef CURL_ISOCPP +#endif + +/* + * Macros for minimum-width signed and unsigned curl_off_t integer constants. + */ + +#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) +# define __CURL_OFF_T_C_HLPR2(x) x +# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) +#else +# ifdef CURL_ISOCPP +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix +# else +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix +# endif +# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) +#endif + +#endif /* __CURL_SYSTEM_H */ diff --git a/libcurl/include/curl/typecheck-gcc.h b/libcurl/include/curl/typecheck-gcc.h new file mode 100644 index 0000000..eeb36ab --- /dev/null +++ b/libcurl/include/curl/typecheck-gcc.h @@ -0,0 +1,698 @@ +#ifndef __CURL_TYPECHECK_GCC_H +#define __CURL_TYPECHECK_GCC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* wraps curl_easy_setopt() with typechecking */ + +/* To add a new kind of warning, add an + * if(_curl_is_sometype_option(_curl_opt)) + * if(!_curl_is_sometype(value)) + * _curl_easy_setopt_err_sometype(); + * block and define _curl_is_sometype_option, _curl_is_sometype and + * _curl_easy_setopt_err_sometype below + * + * NOTE: We use two nested 'if' statements here instead of the && operator, in + * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x + * when compiling with -Wlogical-op. + * + * To add an option that uses the same type as an existing option, you'll just + * need to extend the appropriate _curl_*_option macro + */ +#define curl_easy_setopt(handle, option, value) \ +__extension__ ({ \ + __typeof__(option) _curl_opt = option; \ + if(__builtin_constant_p(_curl_opt)) { \ + if(_curl_is_long_option(_curl_opt)) \ + if(!_curl_is_long(value)) \ + _curl_easy_setopt_err_long(); \ + if(_curl_is_off_t_option(_curl_opt)) \ + if(!_curl_is_off_t(value)) \ + _curl_easy_setopt_err_curl_off_t(); \ + if(_curl_is_string_option(_curl_opt)) \ + if(!_curl_is_string(value)) \ + _curl_easy_setopt_err_string(); \ + if(_curl_is_write_cb_option(_curl_opt)) \ + if(!_curl_is_write_cb(value)) \ + _curl_easy_setopt_err_write_callback(); \ + if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION) \ + if(!_curl_is_resolver_start_callback(value)) \ + _curl_easy_setopt_err_resolver_start_callback(); \ + if((_curl_opt) == CURLOPT_READFUNCTION) \ + if(!_curl_is_read_cb(value)) \ + _curl_easy_setopt_err_read_cb(); \ + if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ + if(!_curl_is_ioctl_cb(value)) \ + _curl_easy_setopt_err_ioctl_cb(); \ + if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ + if(!_curl_is_sockopt_cb(value)) \ + _curl_easy_setopt_err_sockopt_cb(); \ + if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ + if(!_curl_is_opensocket_cb(value)) \ + _curl_easy_setopt_err_opensocket_cb(); \ + if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ + if(!_curl_is_progress_cb(value)) \ + _curl_easy_setopt_err_progress_cb(); \ + if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ + if(!_curl_is_debug_cb(value)) \ + _curl_easy_setopt_err_debug_cb(); \ + if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ + if(!_curl_is_ssl_ctx_cb(value)) \ + _curl_easy_setopt_err_ssl_ctx_cb(); \ + if(_curl_is_conv_cb_option(_curl_opt)) \ + if(!_curl_is_conv_cb(value)) \ + _curl_easy_setopt_err_conv_cb(); \ + if((_curl_opt) == CURLOPT_SEEKFUNCTION) \ + if(!_curl_is_seek_cb(value)) \ + _curl_easy_setopt_err_seek_cb(); \ + if(_curl_is_cb_data_option(_curl_opt)) \ + if(!_curl_is_cb_data(value)) \ + _curl_easy_setopt_err_cb_data(); \ + if((_curl_opt) == CURLOPT_ERRORBUFFER) \ + if(!_curl_is_error_buffer(value)) \ + _curl_easy_setopt_err_error_buffer(); \ + if((_curl_opt) == CURLOPT_STDERR) \ + if(!_curl_is_FILE(value)) \ + _curl_easy_setopt_err_FILE(); \ + if(_curl_is_postfields_option(_curl_opt)) \ + if(!_curl_is_postfields(value)) \ + _curl_easy_setopt_err_postfields(); \ + if((_curl_opt) == CURLOPT_HTTPPOST) \ + if(!_curl_is_arr((value), struct curl_httppost)) \ + _curl_easy_setopt_err_curl_httpost(); \ + if((_curl_opt) == CURLOPT_MIMEPOST) \ + if(!_curl_is_ptr((value), curl_mime)) \ + _curl_easy_setopt_err_curl_mimepost(); \ + if(_curl_is_slist_option(_curl_opt)) \ + if(!_curl_is_arr((value), struct curl_slist)) \ + _curl_easy_setopt_err_curl_slist(); \ + if((_curl_opt) == CURLOPT_SHARE) \ + if(!_curl_is_ptr((value), CURLSH)) \ + _curl_easy_setopt_err_CURLSH(); \ + } \ + curl_easy_setopt(handle, _curl_opt, value); \ +}) + +/* wraps curl_easy_getinfo() with typechecking */ +#define curl_easy_getinfo(handle, info, arg) \ +__extension__ ({ \ + __typeof__(info) _curl_info = info; \ + if(__builtin_constant_p(_curl_info)) { \ + if(_curl_is_string_info(_curl_info)) \ + if(!_curl_is_arr((arg), char *)) \ + _curl_easy_getinfo_err_string(); \ + if(_curl_is_long_info(_curl_info)) \ + if(!_curl_is_arr((arg), long)) \ + _curl_easy_getinfo_err_long(); \ + if(_curl_is_double_info(_curl_info)) \ + if(!_curl_is_arr((arg), double)) \ + _curl_easy_getinfo_err_double(); \ + if(_curl_is_slist_info(_curl_info)) \ + if(!_curl_is_arr((arg), struct curl_slist *)) \ + _curl_easy_getinfo_err_curl_slist(); \ + if(_curl_is_tlssessioninfo_info(_curl_info)) \ + if(!_curl_is_arr((arg), struct curl_tlssessioninfo *)) \ + _curl_easy_getinfo_err_curl_tlssesssioninfo(); \ + if(_curl_is_certinfo_info(_curl_info)) \ + if(!_curl_is_arr((arg), struct curl_certinfo *)) \ + _curl_easy_getinfo_err_curl_certinfo(); \ + if(_curl_is_socket_info(_curl_info)) \ + if(!_curl_is_arr((arg), curl_socket_t)) \ + _curl_easy_getinfo_err_curl_socket(); \ + if(_curl_is_off_t_info(_curl_info)) \ + if(!_curl_is_arr((arg), curl_off_t)) \ + _curl_easy_getinfo_err_curl_off_t(); \ + } \ + curl_easy_getinfo(handle, _curl_info, arg); \ +}) + +/* + * For now, just make sure that the functions are called with three arguments + */ +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) + + +/* the actual warnings, triggered by calling the _curl_easy_setopt_err* + * functions */ + +/* To define a new warning, use _CURL_WARNING(identifier, "message") */ +#define _CURL_WARNING(id, message) \ + static void __attribute__((__warning__(message))) \ + __attribute__((__unused__)) __attribute__((__noinline__)) \ + id(void) { __asm__(""); } + +_CURL_WARNING(_curl_easy_setopt_err_long, + "curl_easy_setopt expects a long argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, + "curl_easy_setopt expects a curl_off_t argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_string, + "curl_easy_setopt expects a " + "string ('char *' or char[]) argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_write_callback, + "curl_easy_setopt expects a curl_write_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_resolver_start_callback, + "curl_easy_setopt expects a " + "curl_resolver_start_callback argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_read_cb, + "curl_easy_setopt expects a curl_read_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, + "curl_easy_setopt expects a curl_ioctl_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, + "curl_easy_setopt expects a curl_sockopt_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, + "curl_easy_setopt expects a " + "curl_opensocket_callback argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_progress_cb, + "curl_easy_setopt expects a curl_progress_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_debug_cb, + "curl_easy_setopt expects a curl_debug_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, + "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_conv_cb, + "curl_easy_setopt expects a curl_conv_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_seek_cb, + "curl_easy_setopt expects a curl_seek_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_cb_data, + "curl_easy_setopt expects a " + "private data pointer as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_error_buffer, + "curl_easy_setopt expects a " + "char buffer of CURL_ERROR_SIZE as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_FILE, + "curl_easy_setopt expects a 'FILE *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_postfields, + "curl_easy_setopt expects a 'void *' or 'char *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, + "curl_easy_setopt expects a 'struct curl_httppost *' " + "argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_mimepost, + "curl_easy_setopt expects a 'curl_mime *' " + "argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_slist, + "curl_easy_setopt expects a 'struct curl_slist *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_CURLSH, + "curl_easy_setopt expects a CURLSH* argument for this option") + +_CURL_WARNING(_curl_easy_getinfo_err_string, + "curl_easy_getinfo expects a pointer to 'char *' for this info") +_CURL_WARNING(_curl_easy_getinfo_err_long, + "curl_easy_getinfo expects a pointer to long for this info") +_CURL_WARNING(_curl_easy_getinfo_err_double, + "curl_easy_getinfo expects a pointer to double for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, + "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo, + "curl_easy_getinfo expects a pointer to " + "'struct curl_tlssessioninfo *' for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_certinfo, + "curl_easy_getinfo expects a pointer to " + "'struct curl_certinfo *' for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_socket, + "curl_easy_getinfo expects a pointer to curl_socket_t for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_off_t, + "curl_easy_getinfo expects a pointer to curl_off_t for this info") + +/* groups of curl_easy_setops options that take the same type of argument */ + +/* To add a new option to one of the groups, just add + * (option) == CURLOPT_SOMETHING + * to the or-expression. If the option takes a long or curl_off_t, you don't + * have to do anything + */ + +/* evaluates to true if option takes a long argument */ +#define _curl_is_long_option(option) \ + (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) + +#define _curl_is_off_t_option(option) \ + ((option) > CURLOPTTYPE_OFF_T) + +/* evaluates to true if option takes a char* argument */ +#define _curl_is_string_option(option) \ + ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \ + (option) == CURLOPT_ACCEPT_ENCODING || \ + (option) == CURLOPT_ALTSVC || \ + (option) == CURLOPT_CAINFO || \ + (option) == CURLOPT_CAPATH || \ + (option) == CURLOPT_COOKIE || \ + (option) == CURLOPT_COOKIEFILE || \ + (option) == CURLOPT_COOKIEJAR || \ + (option) == CURLOPT_COOKIELIST || \ + (option) == CURLOPT_CRLFILE || \ + (option) == CURLOPT_CUSTOMREQUEST || \ + (option) == CURLOPT_DEFAULT_PROTOCOL || \ + (option) == CURLOPT_DNS_INTERFACE || \ + (option) == CURLOPT_DNS_LOCAL_IP4 || \ + (option) == CURLOPT_DNS_LOCAL_IP6 || \ + (option) == CURLOPT_DNS_SERVERS || \ + (option) == CURLOPT_DOH_URL || \ + (option) == CURLOPT_EGDSOCKET || \ + (option) == CURLOPT_FTPPORT || \ + (option) == CURLOPT_FTP_ACCOUNT || \ + (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ + (option) == CURLOPT_INTERFACE || \ + (option) == CURLOPT_ISSUERCERT || \ + (option) == CURLOPT_KEYPASSWD || \ + (option) == CURLOPT_KRBLEVEL || \ + (option) == CURLOPT_LOGIN_OPTIONS || \ + (option) == CURLOPT_MAIL_AUTH || \ + (option) == CURLOPT_MAIL_FROM || \ + (option) == CURLOPT_NETRC_FILE || \ + (option) == CURLOPT_NOPROXY || \ + (option) == CURLOPT_PASSWORD || \ + (option) == CURLOPT_PINNEDPUBLICKEY || \ + (option) == CURLOPT_PRE_PROXY || \ + (option) == CURLOPT_PROXY || \ + (option) == CURLOPT_PROXYPASSWORD || \ + (option) == CURLOPT_PROXYUSERNAME || \ + (option) == CURLOPT_PROXYUSERPWD || \ + (option) == CURLOPT_PROXY_CAINFO || \ + (option) == CURLOPT_PROXY_CAPATH || \ + (option) == CURLOPT_PROXY_CRLFILE || \ + (option) == CURLOPT_PROXY_KEYPASSWD || \ + (option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \ + (option) == CURLOPT_PROXY_SERVICE_NAME || \ + (option) == CURLOPT_PROXY_SSLCERT || \ + (option) == CURLOPT_PROXY_SSLCERTTYPE || \ + (option) == CURLOPT_PROXY_SSLKEY || \ + (option) == CURLOPT_PROXY_SSLKEYTYPE || \ + (option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \ + (option) == CURLOPT_PROXY_TLS13_CIPHERS || \ + (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \ + (option) == CURLOPT_PROXY_TLSAUTH_TYPE || \ + (option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \ + (option) == CURLOPT_RANDOM_FILE || \ + (option) == CURLOPT_RANGE || \ + (option) == CURLOPT_REFERER || \ + (option) == CURLOPT_REQUEST_TARGET || \ + (option) == CURLOPT_RTSP_SESSION_ID || \ + (option) == CURLOPT_RTSP_STREAM_URI || \ + (option) == CURLOPT_RTSP_TRANSPORT || \ + (option) == CURLOPT_SERVICE_NAME || \ + (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ + (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ + (option) == CURLOPT_SSH_KNOWNHOSTS || \ + (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ + (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ + (option) == CURLOPT_SSLCERT || \ + (option) == CURLOPT_SSLCERTTYPE || \ + (option) == CURLOPT_SSLENGINE || \ + (option) == CURLOPT_SSLKEY || \ + (option) == CURLOPT_SSLKEYTYPE || \ + (option) == CURLOPT_SSL_CIPHER_LIST || \ + (option) == CURLOPT_TLS13_CIPHERS || \ + (option) == CURLOPT_TLSAUTH_PASSWORD || \ + (option) == CURLOPT_TLSAUTH_TYPE || \ + (option) == CURLOPT_TLSAUTH_USERNAME || \ + (option) == CURLOPT_UNIX_SOCKET_PATH || \ + (option) == CURLOPT_URL || \ + (option) == CURLOPT_USERAGENT || \ + (option) == CURLOPT_USERNAME || \ + (option) == CURLOPT_USERPWD || \ + (option) == CURLOPT_XOAUTH2_BEARER || \ + 0) + +/* evaluates to true if option takes a curl_write_callback argument */ +#define _curl_is_write_cb_option(option) \ + ((option) == CURLOPT_HEADERFUNCTION || \ + (option) == CURLOPT_WRITEFUNCTION) + +/* evaluates to true if option takes a curl_conv_callback argument */ +#define _curl_is_conv_cb_option(option) \ + ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) + +/* evaluates to true if option takes a data argument to pass to a callback */ +#define _curl_is_cb_data_option(option) \ + ((option) == CURLOPT_CHUNK_DATA || \ + (option) == CURLOPT_CLOSESOCKETDATA || \ + (option) == CURLOPT_DEBUGDATA || \ + (option) == CURLOPT_FNMATCH_DATA || \ + (option) == CURLOPT_HEADERDATA || \ + (option) == CURLOPT_INTERLEAVEDATA || \ + (option) == CURLOPT_IOCTLDATA || \ + (option) == CURLOPT_OPENSOCKETDATA || \ + (option) == CURLOPT_PRIVATE || \ + (option) == CURLOPT_PROGRESSDATA || \ + (option) == CURLOPT_READDATA || \ + (option) == CURLOPT_SEEKDATA || \ + (option) == CURLOPT_SOCKOPTDATA || \ + (option) == CURLOPT_SSH_KEYDATA || \ + (option) == CURLOPT_SSL_CTX_DATA || \ + (option) == CURLOPT_WRITEDATA || \ + (option) == CURLOPT_RESOLVER_START_DATA || \ + (option) == CURLOPT_TRAILERDATA || \ + 0) + +/* evaluates to true if option takes a POST data argument (void* or char*) */ +#define _curl_is_postfields_option(option) \ + ((option) == CURLOPT_POSTFIELDS || \ + (option) == CURLOPT_COPYPOSTFIELDS || \ + 0) + +/* evaluates to true if option takes a struct curl_slist * argument */ +#define _curl_is_slist_option(option) \ + ((option) == CURLOPT_HTTP200ALIASES || \ + (option) == CURLOPT_HTTPHEADER || \ + (option) == CURLOPT_MAIL_RCPT || \ + (option) == CURLOPT_POSTQUOTE || \ + (option) == CURLOPT_PREQUOTE || \ + (option) == CURLOPT_PROXYHEADER || \ + (option) == CURLOPT_QUOTE || \ + (option) == CURLOPT_RESOLVE || \ + (option) == CURLOPT_TELNETOPTIONS || \ + (option) == CURLOPT_CONNECT_TO || \ + 0) + +/* groups of curl_easy_getinfo infos that take the same type of argument */ + +/* evaluates to true if info expects a pointer to char * argument */ +#define _curl_is_string_info(info) \ + (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) + +/* evaluates to true if info expects a pointer to long argument */ +#define _curl_is_long_info(info) \ + (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) + +/* evaluates to true if info expects a pointer to double argument */ +#define _curl_is_double_info(info) \ + (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) + +/* true if info expects a pointer to struct curl_slist * argument */ +#define _curl_is_slist_info(info) \ + (((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST)) + +/* true if info expects a pointer to struct curl_tlssessioninfo * argument */ +#define _curl_is_tlssessioninfo_info(info) \ + (((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION)) + +/* true if info expects a pointer to struct curl_certinfo * argument */ +#define _curl_is_certinfo_info(info) ((info) == CURLINFO_CERTINFO) + +/* true if info expects a pointer to struct curl_socket_t argument */ +#define _curl_is_socket_info(info) \ + (CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T) + +/* true if info expects a pointer to curl_off_t argument */ +#define _curl_is_off_t_info(info) \ + (CURLINFO_OFF_T < (info)) + + +/* typecheck helpers -- check whether given expression has requested type*/ + +/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, + * otherwise define a new macro. Search for __builtin_types_compatible_p + * in the GCC manual. + * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is + * the actual expression passed to the curl_easy_setopt macro. This + * means that you can only apply the sizeof and __typeof__ operators, no + * == or whatsoever. + */ + +/* XXX: should evaluate to true if expr is a pointer */ +#define _curl_is_any_ptr(expr) \ + (sizeof(expr) == sizeof(void *)) + +/* evaluates to true if expr is NULL */ +/* XXX: must not evaluate expr, so this check is not accurate */ +#define _curl_is_NULL(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) + +/* evaluates to true if expr is type*, const type* or NULL */ +#define _curl_is_ptr(expr, type) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), type *) || \ + __builtin_types_compatible_p(__typeof__(expr), const type *)) + +/* evaluates to true if expr is one of type[], type*, NULL or const type* */ +#define _curl_is_arr(expr, type) \ + (_curl_is_ptr((expr), type) || \ + __builtin_types_compatible_p(__typeof__(expr), type [])) + +/* evaluates to true if expr is a string */ +#define _curl_is_string(expr) \ + (_curl_is_arr((expr), char) || \ + _curl_is_arr((expr), signed char) || \ + _curl_is_arr((expr), unsigned char)) + +/* evaluates to true if expr is a long (no matter the signedness) + * XXX: for now, int is also accepted (and therefore short and char, which + * are promoted to int when passed to a variadic function) */ +#define _curl_is_long(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), long) || \ + __builtin_types_compatible_p(__typeof__(expr), signed long) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ + __builtin_types_compatible_p(__typeof__(expr), int) || \ + __builtin_types_compatible_p(__typeof__(expr), signed int) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ + __builtin_types_compatible_p(__typeof__(expr), short) || \ + __builtin_types_compatible_p(__typeof__(expr), signed short) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ + __builtin_types_compatible_p(__typeof__(expr), char) || \ + __builtin_types_compatible_p(__typeof__(expr), signed char) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned char)) + +/* evaluates to true if expr is of type curl_off_t */ +#define _curl_is_off_t(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) + +/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ +/* XXX: also check size of an char[] array? */ +#define _curl_is_error_buffer(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), char *) || \ + __builtin_types_compatible_p(__typeof__(expr), char[])) + +/* evaluates to true if expr is of type (const) void* or (const) FILE* */ +#if 0 +#define _curl_is_cb_data(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_ptr((expr), FILE)) +#else /* be less strict */ +#define _curl_is_cb_data(expr) \ + _curl_is_any_ptr(expr) +#endif + +/* evaluates to true if expr is of type FILE* */ +#define _curl_is_FILE(expr) \ + (_curl_is_NULL(expr) || \ + (__builtin_types_compatible_p(__typeof__(expr), FILE *))) + +/* evaluates to true if expr can be passed as POST data (void* or char*) */ +#define _curl_is_postfields(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_arr((expr), char) || \ + _curl_is_arr((expr), unsigned char)) + +/* helper: __builtin_types_compatible_p distinguishes between functions and + * function pointers, hide it */ +#define _curl_callback_compatible(func, type) \ + (__builtin_types_compatible_p(__typeof__(func), type) || \ + __builtin_types_compatible_p(__typeof__(func) *, type)) + +/* evaluates to true if expr is of type curl_resolver_start_callback */ +#define _curl_is_resolver_start_callback(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_resolver_start_callback)) + +/* evaluates to true if expr is of type curl_read_callback or "similar" */ +#define _curl_is_read_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), __typeof__(fread) *) || \ + _curl_callback_compatible((expr), curl_read_callback) || \ + _curl_callback_compatible((expr), _curl_read_callback1) || \ + _curl_callback_compatible((expr), _curl_read_callback2) || \ + _curl_callback_compatible((expr), _curl_read_callback3) || \ + _curl_callback_compatible((expr), _curl_read_callback4) || \ + _curl_callback_compatible((expr), _curl_read_callback5) || \ + _curl_callback_compatible((expr), _curl_read_callback6)) +typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *); +typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *); +typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *); +typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *); +typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *); +typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *); + +/* evaluates to true if expr is of type curl_write_callback or "similar" */ +#define _curl_is_write_cb(expr) \ + (_curl_is_read_cb(expr) || \ + _curl_callback_compatible((expr), __typeof__(fwrite) *) || \ + _curl_callback_compatible((expr), curl_write_callback) || \ + _curl_callback_compatible((expr), _curl_write_callback1) || \ + _curl_callback_compatible((expr), _curl_write_callback2) || \ + _curl_callback_compatible((expr), _curl_write_callback3) || \ + _curl_callback_compatible((expr), _curl_write_callback4) || \ + _curl_callback_compatible((expr), _curl_write_callback5) || \ + _curl_callback_compatible((expr), _curl_write_callback6)) +typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *); +typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t, + const void *); +typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *); +typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *); +typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t, + const void *); +typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *); + +/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ +#define _curl_is_ioctl_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_ioctl_callback) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback4)) +typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *); +typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *); +typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *); +typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *); + +/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ +#define _curl_is_sockopt_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_sockopt_callback) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback2)) +typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); +typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t, + curlsocktype); + +/* evaluates to true if expr is of type curl_opensocket_callback or + "similar" */ +#define _curl_is_opensocket_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_opensocket_callback) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback4)) +typedef curl_socket_t (*_curl_opensocket_callback1) + (void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (*_curl_opensocket_callback2) + (void *, curlsocktype, const struct curl_sockaddr *); +typedef curl_socket_t (*_curl_opensocket_callback3) + (const void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (*_curl_opensocket_callback4) + (const void *, curlsocktype, const struct curl_sockaddr *); + +/* evaluates to true if expr is of type curl_progress_callback or "similar" */ +#define _curl_is_progress_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_progress_callback) || \ + _curl_callback_compatible((expr), _curl_progress_callback1) || \ + _curl_callback_compatible((expr), _curl_progress_callback2)) +typedef int (*_curl_progress_callback1)(void *, + double, double, double, double); +typedef int (*_curl_progress_callback2)(const void *, + double, double, double, double); + +/* evaluates to true if expr is of type curl_debug_callback or "similar" */ +#define _curl_is_debug_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_debug_callback) || \ + _curl_callback_compatible((expr), _curl_debug_callback1) || \ + _curl_callback_compatible((expr), _curl_debug_callback2) || \ + _curl_callback_compatible((expr), _curl_debug_callback3) || \ + _curl_callback_compatible((expr), _curl_debug_callback4) || \ + _curl_callback_compatible((expr), _curl_debug_callback5) || \ + _curl_callback_compatible((expr), _curl_debug_callback6) || \ + _curl_callback_compatible((expr), _curl_debug_callback7) || \ + _curl_callback_compatible((expr), _curl_debug_callback8)) +typedef int (*_curl_debug_callback1) (CURL *, + curl_infotype, char *, size_t, void *); +typedef int (*_curl_debug_callback2) (CURL *, + curl_infotype, char *, size_t, const void *); +typedef int (*_curl_debug_callback3) (CURL *, + curl_infotype, const char *, size_t, void *); +typedef int (*_curl_debug_callback4) (CURL *, + curl_infotype, const char *, size_t, const void *); +typedef int (*_curl_debug_callback5) (CURL *, + curl_infotype, unsigned char *, size_t, void *); +typedef int (*_curl_debug_callback6) (CURL *, + curl_infotype, unsigned char *, size_t, const void *); +typedef int (*_curl_debug_callback7) (CURL *, + curl_infotype, const unsigned char *, size_t, void *); +typedef int (*_curl_debug_callback8) (CURL *, + curl_infotype, const unsigned char *, size_t, const void *); + +/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ +/* this is getting even messier... */ +#define _curl_is_ssl_ctx_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_ssl_ctx_callback) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) +typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *); +typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *); +typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *); +typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *, + const void *); +#ifdef HEADER_SSL_H +/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX + * this will of course break if we're included before OpenSSL headers... + */ +typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); +typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); +typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); +typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, + const void *); +#else +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; +#endif + +/* evaluates to true if expr is of type curl_conv_callback or "similar" */ +#define _curl_is_conv_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_conv_callback) || \ + _curl_callback_compatible((expr), _curl_conv_callback1) || \ + _curl_callback_compatible((expr), _curl_conv_callback2) || \ + _curl_callback_compatible((expr), _curl_conv_callback3) || \ + _curl_callback_compatible((expr), _curl_conv_callback4)) +typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); +typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); +typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); +typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); + +/* evaluates to true if expr is of type curl_seek_callback or "similar" */ +#define _curl_is_seek_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_seek_callback) || \ + _curl_callback_compatible((expr), _curl_seek_callback1) || \ + _curl_callback_compatible((expr), _curl_seek_callback2)) +typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); +typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); + + +#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/libcurl/include/curl/urlapi.h b/libcurl/include/curl/urlapi.h new file mode 100644 index 0000000..58e89d8 --- /dev/null +++ b/libcurl/include/curl/urlapi.h @@ -0,0 +1,123 @@ +#ifndef __CURL_URLAPI_H +#define __CURL_URLAPI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2018 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* the error codes for the URL API */ +typedef enum { + CURLUE_OK, + CURLUE_BAD_HANDLE, /* 1 */ + CURLUE_BAD_PARTPOINTER, /* 2 */ + CURLUE_MALFORMED_INPUT, /* 3 */ + CURLUE_BAD_PORT_NUMBER, /* 4 */ + CURLUE_UNSUPPORTED_SCHEME, /* 5 */ + CURLUE_URLDECODE, /* 6 */ + CURLUE_OUT_OF_MEMORY, /* 7 */ + CURLUE_USER_NOT_ALLOWED, /* 8 */ + CURLUE_UNKNOWN_PART, /* 9 */ + CURLUE_NO_SCHEME, /* 10 */ + CURLUE_NO_USER, /* 11 */ + CURLUE_NO_PASSWORD, /* 12 */ + CURLUE_NO_OPTIONS, /* 13 */ + CURLUE_NO_HOST, /* 14 */ + CURLUE_NO_PORT, /* 15 */ + CURLUE_NO_QUERY, /* 16 */ + CURLUE_NO_FRAGMENT /* 17 */ +} CURLUcode; + +typedef enum { + CURLUPART_URL, + CURLUPART_SCHEME, + CURLUPART_USER, + CURLUPART_PASSWORD, + CURLUPART_OPTIONS, + CURLUPART_HOST, + CURLUPART_PORT, + CURLUPART_PATH, + CURLUPART_QUERY, + CURLUPART_FRAGMENT, + CURLUPART_ZONEID /* added in 7.65.0 */ +} CURLUPart; + +#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */ +#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set, + if the port number matches the + default for the scheme */ +#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if + missing */ +#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */ +#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */ +#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */ +#define CURLU_URLDECODE (1<<6) /* URL decode on get */ +#define CURLU_URLENCODE (1<<7) /* URL encode on set */ +#define CURLU_APPENDQUERY (1<<8) /* append a form style part */ +#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */ + +typedef struct Curl_URL CURLU; + +/* + * curl_url() creates a new CURLU handle and returns a pointer to it. + * Must be freed with curl_url_cleanup(). + */ +CURL_EXTERN CURLU *curl_url(void); + +/* + * curl_url_cleanup() frees the CURLU handle and related resources used for + * the URL parsing. It will not free strings previously returned with the URL + * API. + */ +CURL_EXTERN void curl_url_cleanup(CURLU *handle); + +/* + * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new + * handle must also be freed with curl_url_cleanup(). + */ +CURL_EXTERN CURLU *curl_url_dup(CURLU *in); + +/* + * curl_url_get() extracts a specific part of the URL from a CURLU + * handle. Returns error code. The returned pointer MUST be freed with + * curl_free() afterwards. + */ +CURL_EXTERN CURLUcode curl_url_get(CURLU *handle, CURLUPart what, + char **part, unsigned int flags); + +/* + * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns + * error code. The passed in string will be copied. Passing a NULL instead of + * a part string, clears that part. + */ +CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what, + const char *part, unsigned int flags); + + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/libcurl/lib/CMakeLists.txt b/libcurl/lib/CMakeLists.txt new file mode 100644 index 0000000..eca9a8a --- /dev/null +++ b/libcurl/lib/CMakeLists.txt @@ -0,0 +1,121 @@ +set(LIB_NAME libcurl) + +if(BUILD_SHARED_LIBS) + set(CURL_STATICLIB NO) +else() + set(CURL_STATICLIB YES) +endif() + +# Use: +# * CURL_STATICLIB +configure_file(curl_config.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h) + +transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") +include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake) + +list(APPEND HHEADERS + ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h + ) + +if(MSVC) + list(APPEND CSOURCES libcurl.rc) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4127") +endif() + +# SET(CSOURCES +# # memdebug.c -not used +# # nwlib.c - Not used +# # strtok.c - specify later +# # strtoofft.c - specify later +# ) + +# # if we have Kerberos 4, right now this is never on +# #OPTION(CURL_KRB4 "Use Kerberos 4" OFF) +# IF(CURL_KRB4) +# SET(CSOURCES ${CSOURCES} +# krb4.c +# security.c +# ) +# ENDIF(CURL_KRB4) + +# #OPTION(CURL_MALLOC_DEBUG "Debug mallocs in Curl" OFF) +# MARK_AS_ADVANCED(CURL_MALLOC_DEBUG) +# IF(CURL_MALLOC_DEBUG) +# SET(CSOURCES ${CSOURCES} +# memdebug.c +# ) +# ENDIF(CURL_MALLOC_DEBUG) + +# # only build compat strtoofft if we need to +# IF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64) +# SET(CSOURCES ${CSOURCES} +# strtoofft.c +# ) +# ENDIF(NOT HAVE_STRTOLL AND NOT HAVE__STRTOI64) + + +# The rest of the build + +include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/..) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +if(USE_ARES) + include_directories(${CARES_INCLUDE_DIR}) +endif() + +add_library( + ${LIB_NAME} + ${HHEADERS} ${CSOURCES} + ) + +if(MSVC AND NOT BUILD_SHARED_LIBS) + set_target_properties(${LIB_NAME} PROPERTIES STATIC_LIBRARY_FLAGS ${CMAKE_EXE_LINKER_FLAGS}) +endif() + +if(NOT BUILD_SHARED_LIBS) + set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB) +endif() + +target_link_libraries(${LIB_NAME} ${CURL_LIBS}) + +if(WIN32) + add_definitions(-D_USRDLL) +endif() + +set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL) + +if(HIDES_CURL_PRIVATE_SYMBOLS) + set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS") + set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE}) +endif() + +# Remove the "lib" prefix since the library is already named "libcurl". +set_target_properties(${LIB_NAME} PROPERTIES PREFIX "") +set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "") + +if(WIN32) + if(BUILD_SHARED_LIBS) + # Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib" + set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib") + endif() +endif() + +target_include_directories(${LIB_NAME} INTERFACE + $ + $) + +install(TARGETS ${LIB_NAME} + EXPORT ${TARGETS_EXPORT_NAME} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) + +export(TARGETS ${LIB_NAME} + APPEND FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake + NAMESPACE CURL:: +) diff --git a/libcurl/lib/Makefile.Watcom b/libcurl/lib/Makefile.Watcom new file mode 100644 index 0000000..942cd0c --- /dev/null +++ b/libcurl/lib/Makefile.Watcom @@ -0,0 +1,274 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 2005 - 2009, Gisle Vanem . +# Copyright (C) 2005 - 2017, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +#*************************************************************************** + +# +# Watcom / OpenWatcom / Win32 makefile for libcurl. +# + +.ERASE + +!if $(__VERSION__) < 1280 +!message !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!message ! This Open Watcom version is too old and is no longer supported ! +!message ! Please download latest version from www.openwatcom.org ! +!message !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!error Unsupported version of Open Watcom +!endif + +!ifndef %watcom +!error WATCOM environment variable not set! +!endif + +# In order to process Makefile.inc wmake must be called with -u switch! +!ifndef %MAKEFLAGS +!error You MUST call wmake with the -u switch! +!endif + +!ifdef %libname +LIBNAME = $(%libname) +!else +LIBNAME = libcurl +!endif +TARGETS = $(LIBNAME).dll $(LIBNAME).lib + +CC = wcc386 +LD = wlink +AR = wlib +RC = wrc + +!ifdef __LOADDLL__ +! loaddll wcc386 wccd386 +! loaddll wpp386 wppd386 +! loaddll wlib wlibd +! loaddll wlink wlinkd +!endif + +!ifdef __LINUX__ +CP = cp +MD = mkdir -p +!else +CP = copy 2>NUL +MD = mkdir +!endif +!if $(__VERSION__) > 1290 +RD = rm -rf +!else ifdef __UNIX__ +RD = rm -rf +!else +RD = rmdir /q /s 2>NUL +!endif + +SYS_INCL = -I"$(%watcom)/h/nt" -I"$(%watcom)/h" + +CFLAGS = -3r -mf -hc -zff -zgf -zq -zm -zc -s -fr=con -w2 -fpi -oilrtfm & + -wcd=201 -bt=nt -d+ -dWIN32 & + -dBUILDING_LIBCURL -I. -I"../include" $(SYS_INCL) + +!ifdef %debug +DEBUG = -dDEBUG=1 -dDEBUGBUILD +CFLAGS += -d3 $(DEBUG) +!else +CFLAGS += -d0 +!endif + +!ifdef %use_ipv6 +CFLAGS += -d_WIN32_WINNT=0x0501 -dENABLE_IPV6 +!endif + +!ifdef %use_sspi +CFLAGS += -dUSE_WINDOWS_SSPI +!endif + +!ifdef %use_winssl +CFLAGS += -dUSE_WINDOWS_SSPI +CFLAGS += -DUSE_SCHANNEL +!endif + +!ifdef %use_winidn +CFLAGS += -dWINVER=0x0600 -dUSE_WIN32_IDN +! if $(__VERSION__) <= 1290 +CFLAGS += -dWANT_IDN_PROTOTYPES +! endif +!endif + +# +# Change to suite. +# +!ifdef %zlib_root +ZLIB_ROOT = $(%zlib_root) +!else +ZLIB_ROOT = ../../zlib-1.2.8 +!endif + +!ifdef %libssh2_root +LIBSSH2_ROOT = $(%libssh2_root) +!else +LIBSSH2_ROOT = ../../libssh2-1.5.0 +!endif + +!ifdef %librtmp_root +LIBRTMP_ROOT = $(%librtmp_root) +!else +LIBRTMP_ROOT = ../../rtmpdump-2.3 +!endif + +!ifdef %openssl_root +OPENSSL_ROOT = $(%openssl_root) +!else +OPENSSL_ROOT = ../../openssl-1.0.2a +!endif + +!ifdef %ares_root +ARES_ROOT = $(%ares_root) +!else +ARES_ROOT = ../ares +!endif + +!ifdef %use_zlib +CFLAGS += -dHAVE_ZLIB_H -dHAVE_LIBZ -I"$(ZLIB_ROOT)" +!endif + +!ifdef %use_rtmp +CFLAGS += -dUSE_LIBRTMP -I"$(LIBRTMP_ROOT)" +!endif + +!ifdef %use_ssh2 +CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H -I"$(LIBSSH2_ROOT)/include" -I"$(LIBSSH2_ROOT)/win32" +!endif + +!ifdef %use_ssl +CFLAGS += -wcd=138 -dUSE_OPENSSL -I"$(OPENSSL_ROOT)/inc32" +!endif + +!ifdef %use_ares +CFLAGS += -dUSE_ARES -I"$(ARES_ROOT)" +!endif + +!ifdef %use_watt32 +CFLAGS += -dUSE_WATT32 -I"$(%watt_root)/inc" +!endif + +OBJ_BASE = WC_Win32.obj +!if $(__VERSION__) > 1290 +OBJ_STAT = $(OBJ_BASE)/stat +OBJ_DYN = $(OBJ_BASE)/dyn +!else ifdef __UNIX__ +OBJ_STAT = $(OBJ_BASE)/stat +OBJ_DYN = $(OBJ_BASE)/dyn +!else +OBJ_STAT = $(OBJ_BASE)\stat +OBJ_DYN = $(OBJ_BASE)\dyn +!endif + +LINK_ARG = $(OBJ_DYN)/wlink.arg +LIB_ARG = $(OBJ_STAT)/wlib.arg + +!include Makefile.inc + +OBJS1 = ./$(CSOURCES:.c=.obj) +OBJS2 = $(OBJS1:vtls/=) +OBJS3 = $(OBJS2:vauth/=) +OBJS4 = $(OBJS3: = ./) +OBJS_STAT = $(OBJS4:./=$(OBJ_STAT)/) +OBJS_DYN = $(OBJS4:./=$(OBJ_DYN)/) + +RESOURCE = $(OBJ_DYN)/libcurl.res + +DIRS = $(OBJ_BASE) $(OBJ_BASE)/stat $(OBJ_BASE)/dyn + +.c : vauth vtls + +all: $(DIRS) $(TARGETS) .SYMBOLIC + @echo Welcome to libcurl + +clean: .SYMBOLIC + -rm -f $(OBJS_STAT) + -rm -f $(OBJS_DYN) + -rm -f $(RESOURCE) $(LINK_ARG) $(LIB_ARG) + +vclean distclean: clean .SYMBOLIC + -rm -f $(TARGETS) $(LIBNAME).map $(LIBNAME).sym + -$(RD) $(OBJ_STAT) + -$(RD) $(OBJ_DYN) + -$(RD) $(OBJ_BASE) + +$(DIRS): + -$(MD) $^@ + +$(LIBNAME).dll: $(OBJS_DYN) $(RESOURCE) $(__MAKEFILES__) + %create $(LINK_ARG) + @%append $(LINK_ARG) system nt dll +!ifdef %debug + @%append $(LINK_ARG) debug all + @%append $(LINK_ARG) option symfile +!endif + @%append $(LINK_ARG) option quiet, caseexact, eliminate + @%append $(LINK_ARG) option map=$(OBJ_DYN)/$(LIBNAME).map + @%append $(LINK_ARG) option implib=$(LIBNAME)_imp.lib + @%append $(LINK_ARG) option res=$(RESOURCE) + @for %f in ($(OBJS_DYN)) do @%append $(LINK_ARG) file %f + @%append $(LINK_ARG) library wldap32.lib +!ifdef %use_watt32 + @%append $(LINK_ARG) library '$(%watt_root)/lib/wattcpw_imp.lib' +!else + @%append $(LINK_ARG) library ws2_32.lib +!endif +!ifdef %use_zlib + @%append $(LINK_ARG) library '$(ZLIB_ROOT)/zlib.lib' +!endif +!ifdef %use_rtmp + @%append $(LINK_ARG) library '$(LIBRTMP_ROOT)/librtmp/librtmp.lib' +!endif +!ifdef %use_ssh2 + @%append $(LINK_ARG) library '$(LIBSSH2_ROOT)/win32/libssh2.lib' +!endif +!ifdef %use_ssl + @%append $(LINK_ARG) library '$(OPENSSL_ROOT)/out32/libeay32.lib' + @%append $(LINK_ARG) library '$(OPENSSL_ROOT)/out32/ssleay32.lib' +!endif +!ifdef %use_ares + @%append $(LINK_ARG) library '$(ARES_ROOT)/cares.lib' +!endif +!ifdef %use_winidn +! if $(__VERSION__) > 1290 + @%append $(LINK_ARG) library normaliz.lib +! else + @%append $(LINK_ARG) import '_IdnToAscii@20' 'NORMALIZ.DLL'.'IdnToAscii' + @%append $(LINK_ARG) import '_IdnToUnicode@20' 'NORMALIZ.DLL'.'IdnToUnicode' +! endif +!endif + $(LD) name $^@ @$(LINK_ARG) + +$(LIBNAME).lib: $(OBJS_STAT) + %create $(LIB_ARG) + @for %f in ($<) do @%append $(LIB_ARG) +- %f + $(AR) -q -b -c -pa $^@ @$(LIB_ARG) + +$(RESOURCE): libcurl.rc + $(RC) $(DEBUG) -q -r -zm -bt=nt -I"../include" $(SYS_INCL) $[@ -fo=$^@ + +.c{$(OBJ_DYN)}.obj: + $(CC) $(CFLAGS) -bd -br $[@ -fo=$^@ + +.c{$(OBJ_STAT)}.obj: + $(CC) $(CFLAGS) -DCURL_STATICLIB $[@ -fo=$^@ diff --git a/libcurl/lib/Makefile.am b/libcurl/lib/Makefile.am new file mode 100644 index 0000000..7c258b3 --- /dev/null +++ b/libcurl/lib/Makefile.am @@ -0,0 +1,154 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### +AUTOMAKE_OPTIONS = foreign nostdinc + +CMAKE_DIST = CMakeLists.txt curl_config.h.cmake + +EXTRA_DIST = Makefile.m32 config-win32.h \ + config-win32ce.h config-riscos.h config-mac.h curl_config.h.in \ + makefile.dj config-dos.h libcurl.plist libcurl.rc config-amigaos.h \ + makefile.amiga Makefile.netware nwlib.c nwos.c config-win32ce.h \ + config-os400.h setup-os400.h config-symbian.h Makefile.Watcom \ + config-tpf.h mk-ca-bundle.pl mk-ca-bundle.vbs $(CMAKE_DIST) \ + firefox-db2pem.sh config-vxworks.h Makefile.vxworks checksrc.pl + +lib_LTLIBRARIES = libcurl.la + +if BUILD_UNITTESTS +noinst_LTLIBRARIES = libcurlu.la +else +noinst_LTLIBRARIES = +endif + +# This might hold -Werror +CFLAGS += @CURL_CFLAG_EXTRAS@ + +# Specify our include paths here, and do it relative to $(top_srcdir) and +# $(top_builddir), to ensure that these paths which belong to the library +# being currently built and tested are searched before the library which +# might possibly already be installed in the system. +# +# $(top_srcdir)/include is for libcurl's external include files +# $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file +# $(top_srcdir)/lib for libcurl's lib/curl_setup.h and other "private" files +# $(top_builddir)/ares is for in-tree c-ares's generated ares_build.h file +# $(top_srcdir)/ares is for in-tree c-ares's external include files + +AM_CPPFLAGS = -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib + +if USE_EMBEDDED_ARES +AM_CPPFLAGS += -I$(top_builddir)/ares \ + -I$(top_srcdir)/ares +endif + +# Prevent LIBS from being used for all link targets +LIBS = $(BLANK_AT_MAKETIME) + +VERSIONINFO=-version-info 9:0:5 +# This flag accepts an argument of the form current[:revision[:age]]. So, +# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to +# 1. +# +# Here's the simplified rule guide on how to change -version-info: +# (current version is C:R:A) +# +# 1. if there are only source changes, use C:R+1:A +# 2. if interfaces were added use C+1:0:A+1 +# 3. if interfaces were removed, then use C+1:0:0 +# +# For the full guide on libcurl ABI rules, see docs/libcurl/ABI + +AM_CPPFLAGS += -DBUILDING_LIBCURL +AM_LDFLAGS = +AM_CFLAGS = + +libcurl_la_CPPFLAGS_EXTRA = +libcurl_la_LDFLAGS_EXTRA = +libcurl_la_CFLAGS_EXTRA = + +if CURL_LT_SHLIB_USE_VERSION_INFO +libcurl_la_LDFLAGS_EXTRA += $(VERSIONINFO) +endif + +if CURL_LT_SHLIB_USE_NO_UNDEFINED +libcurl_la_LDFLAGS_EXTRA += -no-undefined +endif + +if CURL_LT_SHLIB_USE_MIMPURE_TEXT +libcurl_la_LDFLAGS_EXTRA += -mimpure-text +endif + +if CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS +libcurl_la_LDFLAGS_EXTRA += -Wl,--version-script=libcurl.vers +else +# if symbol-hiding is enabled, hide them! +if DOING_CURL_SYMBOL_HIDING +libcurl_la_LDFLAGS_EXTRA += -export-symbols-regex '^curl_.*' +endif +endif + +if USE_CPPFLAG_CURL_STATICLIB +libcurl_la_CPPFLAGS_EXTRA += -DCURL_STATICLIB +endif + +if DOING_CURL_SYMBOL_HIDING +libcurl_la_CPPFLAGS_EXTRA += -DCURL_HIDDEN_SYMBOLS +libcurl_la_CFLAGS_EXTRA += $(CFLAG_CURL_SYMBOL_HIDING) +endif + +libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA) +libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LDFLAGS) $(LIBCURL_LIBS) +libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA) + +libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS +libcurlu_la_LDFLAGS = $(AM_LDFLAGS) -static $(LIBCURL_LIBS) +libcurlu_la_CFLAGS = $(AM_CFLAGS) + +# Makefile.inc provides the CSOURCES and HHEADERS defines +include Makefile.inc + +libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS) +libcurlu_la_SOURCES = $(CSOURCES) $(HHEADERS) + +CHECKSRC = $(CS_$(V)) +CS_0 = @echo " RUN " $@; +CS_1 = +CS_ = $(CS_0) + +checksrc: + $(CHECKSRC)(@PERL@ $(srcdir)/checksrc.pl -D$(srcdir) -W$(srcdir)/curl_config.h \ + $(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] $(srcdir)/vtls/*.[ch]) + +if CURLDEBUG +# for debug builds, we scan the sources on all regular make invokes +all-local: checksrc +endif + +# disable the tests that are mostly causing false positives +TIDYFLAGS=-checks=-clang-analyzer-security.insecureAPI.strcpy,-clang-analyzer-optin.performance.Padding,-clang-analyzer-valist.Uninitialized,-clang-analyzer-core.NonNullParamChecker,-clang-analyzer-core.NullDereference -quiet + +TIDY:=clang-tidy + +tidy: + $(TIDY) $(CSOURCES) $(TIDYFLAGS) -- $(AM_CPPFLAGS) $(CPPFLAGS) -DHAVE_CONFIG_H diff --git a/libcurl/lib/Makefile.b32 b/libcurl/lib/Makefile.b32 new file mode 100644 index 0000000..5b5b5fa --- /dev/null +++ b/libcurl/lib/Makefile.b32 @@ -0,0 +1,185 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 2000, Jaepil Kim, . +# Copyright (C) 2001 - 2015, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +#*************************************************************************** + +############################################################ +# +# Makefile.b32 - Borland's C++ Compiler 5.X +# +# 'BCCDIR' has to be set up to point to the base directory +# of the compiler, i.e. SET BCCDIR = c:\Borland\BCC55 +# +############################################################ + +!if "$(__MAKE__)" == "" +!error __MAKE__ not defined. Use Borlands's MAKE to process this makefile. +!endif + +# Borland's $(MAKEDIR) expands to the path where make.exe is located, +# use this feature to define BCCDIR when user has not defined BCCDIR. +!ifndef BCCDIR +BCCDIR = $(MAKEDIR)\.. +!endif + +# Edit the path below to point to the base of your Zlib sources. +!ifndef ZLIB_PATH +ZLIB_PATH = ..\..\zlib-1.2.8 +!endif + +# Edit the path below to point to the base of your OpenSSL package. +!ifndef OPENSSL_PATH +OPENSSL_PATH = ..\..\openssl-1.0.2a +!endif + +# Set libcurl static lib, dll and import lib +LIBCURL_LIB = libcurl.lib +LIBCURL_DLL = libcurl.dll +LIBCURL_IMPLIB = libcurl_imp.lib + +# Setup environment +PP_CMD = cpp32 -q -P- +CC_CMD = bcc32 -q -c +LD = bcc32 +RM = del 2>NUL +MKDIR = md +RMDIR = rd /q +LIB = tlib +IMPLIB = implib + +CC_FLAGS = -5 -O2 -tWM -w -w-aus -w-ccc -w-dup -w-prc -w-pro -w-rch -w-sig -w-spa -w-inl -w-pia -w-pin -Dinline=__inline +LIBFLAGS = /C /P32 +LDFLAGS = -q -lq -laa -tWD + +SRCDIR = .;.\vauth;.\vtls +OBJDIR = .\BCC_objs +INCDIRS = -I.;.\lib;..\include +LINKLIB = $(BCCDIR)\lib\cw32mt.lib $(BCCDIR)\lib\ws2_32.lib +DEFINES = -DNDEBUG -DWIN32 -DBUILDING_LIBCURL + +# By default SSPI support is enabled for BCC +!ifndef DISABLE_SSPI +DEFINES = $(DEFINES) -DUSE_WINDOWS_SSPI +!endif + +# By default LDAP support is disabled for BCC +!ifndef WITH_LDAP +DEFINES = $(DEFINES) -DCURL_DISABLE_LDAP +!endif + +# ZLIB support is enabled setting WITH_ZLIB=1 +!ifdef WITH_ZLIB +DEFINES = $(DEFINES) -DHAVE_LIBZ -DHAVE_ZLIB_H +INCDIRS = $(INCDIRS);$(ZLIB_PATH) +LINKLIB = $(LINKLIB) $(ZLIB_PATH)\zlib.lib +!endif + +# SSL support is enabled setting WITH_SSL=1 +!ifdef WITH_SSL +DEFINES = $(DEFINES) -DUSE_OPENSSL +INCDIRS = $(INCDIRS);$(OPENSSL_PATH)\inc32;$(OPENSSL_PATH)\inc32\openssl +LINKLIB = $(LINKLIB) $(OPENSSL_PATH)\out32\ssleay32.lib $(OPENSSL_PATH)\out32\libeay32.lib +!endif + +.autodepend + +.path.c = $(SRCDIR) +.path.obj = $(OBJDIR) +.path.int = $(OBJDIR) + +# Makefile.inc provides the CSOURCES and HHEADERS defines +!include Makefile.inc + +# Borland's command line librarian program TLIB version 4.5 is not capable +# of building a library when any of its objects contains an hyphen in its +# name, due to a command line parsing bug. In order to workaround this, we +# build source files with hyphens in their name as objects with underscores +# using explicit compilation build rules instead of implicit ones. + +NOHYPHEN1 = $(CSOURCES:-=_) +NOHYPHEN2 = $(NOHYPHEN1:vauth/=) +NOHYPHEN3 = $(NOHYPHEN2:vtls/=) + +OBJECTS = $(NOHYPHEN3:.c=.obj) +PREPROCESSED = $(NOHYPHEN3:.c=.int) + +# Borland's command line compiler (BCC32) version 5.5.1 integrated +# preprocessor has a bug which results in silently generating wrong +# definitions for libcurl macros such as CURL_OFF_T_C, on the other +# hand Borland's command line preprocessor (CPP32) version 5.5.1 does +# not have the bug and achieves proper results. In order to avoid the +# silent bug we first preprocess source files and later compile the +# preprocessed result. + +.c.obj: + @-$(RM) $(@R).int + $(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(<) + $(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int + +all: $(OBJDIR) $(LIBCURL_LIB) $(LIBCURL_DLL) + +asyn_ares.obj: asyn-ares.c + @-$(RM) $(@R).int + $(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(?) + $(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int + +asyn_thread.obj: asyn-thread.c + @-$(RM) $(@R).int + $(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(?) + $(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int + +non_ascii.obj: non-ascii.c + @-$(RM) $(@R).int + $(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(?) + $(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int + +clean: + cd $(OBJDIR) + @-$(RM) $(OBJECTS) + @-$(RM) $(PREPROCESSED) + cd .. + @-$(RMDIR) $(OBJDIR) + @-$(RM) $(LIBCURL_LIB) + @-$(RM) $(LIBCURL_IMPLIB) + @-$(RM) libcurl.tds + +$(OBJDIR): + @-$(RMDIR) $(OBJDIR) + @-$(MKDIR) $(OBJDIR) + +$(LIBCURL_LIB): $(OBJECTS) + @-$(RM) $(LIBCURL_LIB) + $(LIB) $(LIBFLAGS) $@ @&&! ++$(**: = &^ ++) +! + +$(LIBCURL_DLL) $(LIBCURL_IMPLIB): $(OBJECTS) $(LINKLIB) + @-$(RM) $(LIBCURL_DLL) + @-$(RM) $(LIBCURL_IMPLIB) + $(LD) $(LDFLAGS) -e$(LIBCURL_DLL) @&&! +$(**: = ^ +) +! + $(IMPLIB) $(LIBCURL_IMPLIB) $(LIBCURL_DLL) + + +# End of Makefile.b32 diff --git a/libcurl/lib/Makefile.in b/libcurl/lib/Makefile.in new file mode 100644 index 0000000..da01c26 --- /dev/null +++ b/libcurl/lib/Makefile.in @@ -0,0 +1,4257 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@USE_EMBEDDED_ARES_TRUE@am__append_1 = -I$(top_builddir)/ares \ +@USE_EMBEDDED_ARES_TRUE@ -I$(top_srcdir)/ares + +@CURL_LT_SHLIB_USE_VERSION_INFO_TRUE@am__append_2 = $(VERSIONINFO) +@CURL_LT_SHLIB_USE_NO_UNDEFINED_TRUE@am__append_3 = -no-undefined +@CURL_LT_SHLIB_USE_MIMPURE_TEXT_TRUE@am__append_4 = -mimpure-text +@CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS_TRUE@am__append_5 = -Wl,--version-script=libcurl.vers +# if symbol-hiding is enabled, hide them! +@CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS_FALSE@@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_6 = -export-symbols-regex '^curl_.*' +@USE_CPPFLAG_CURL_STATICLIB_TRUE@am__append_7 = -DCURL_STATICLIB +@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_8 = -DCURL_HIDDEN_SYMBOLS +@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_9 = $(CFLAG_CURL_SYMBOL_HIDING) +subdir = lib +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compile_check_sizeof.m4 \ + $(top_srcdir)/m4/curl-compilers.m4 \ + $(top_srcdir)/m4/curl-confopts.m4 \ + $(top_srcdir)/m4/curl-functions.m4 \ + $(top_srcdir)/m4/curl-openssl.m4 \ + $(top_srcdir)/m4/curl-override.m4 \ + $(top_srcdir)/m4/curl-reentrant.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/xc-am-iface.m4 \ + $(top_srcdir)/m4/xc-cc-check.m4 \ + $(top_srcdir)/m4/xc-lt-iface.m4 \ + $(top_srcdir)/m4/xc-translit.m4 \ + $(top_srcdir)/m4/xc-val-flgs.m4 \ + $(top_srcdir)/m4/zz40-xc-ovr.m4 \ + $(top_srcdir)/m4/zz50-xc-ovr.m4 \ + $(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = curl_config.h +CONFIG_CLEAN_FILES = libcurl.vers +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) +libcurl_la_LIBADD = +am__objects_1 = libcurl_la-file.lo libcurl_la-timeval.lo \ + libcurl_la-base64.lo libcurl_la-hostip.lo \ + libcurl_la-progress.lo libcurl_la-formdata.lo \ + libcurl_la-cookie.lo libcurl_la-http.lo libcurl_la-sendf.lo \ + libcurl_la-ftp.lo libcurl_la-url.lo libcurl_la-dict.lo \ + libcurl_la-if2ip.lo libcurl_la-speedcheck.lo \ + libcurl_la-ldap.lo libcurl_la-version.lo libcurl_la-getenv.lo \ + libcurl_la-escape.lo libcurl_la-mprintf.lo \ + libcurl_la-telnet.lo libcurl_la-netrc.lo libcurl_la-getinfo.lo \ + libcurl_la-transfer.lo libcurl_la-strcase.lo \ + libcurl_la-easy.lo libcurl_la-security.lo \ + libcurl_la-curl_fnmatch.lo libcurl_la-fileinfo.lo \ + libcurl_la-ftplistparser.lo libcurl_la-wildcard.lo \ + libcurl_la-krb5.lo libcurl_la-memdebug.lo \ + libcurl_la-http_chunks.lo libcurl_la-strtok.lo \ + libcurl_la-connect.lo libcurl_la-llist.lo libcurl_la-hash.lo \ + libcurl_la-multi.lo libcurl_la-content_encoding.lo \ + libcurl_la-share.lo libcurl_la-http_digest.lo \ + libcurl_la-md4.lo libcurl_la-md5.lo \ + libcurl_la-http_negotiate.lo libcurl_la-inet_pton.lo \ + libcurl_la-strtoofft.lo libcurl_la-strerror.lo \ + libcurl_la-amigaos.lo libcurl_la-hostasyn.lo \ + libcurl_la-hostip4.lo libcurl_la-hostip6.lo \ + libcurl_la-hostsyn.lo libcurl_la-inet_ntop.lo \ + libcurl_la-parsedate.lo libcurl_la-select.lo \ + libcurl_la-tftp.lo libcurl_la-splay.lo libcurl_la-strdup.lo \ + libcurl_la-socks.lo libcurl_la-ssh.lo libcurl_la-ssh-libssh.lo \ + libcurl_la-curl_addrinfo.lo libcurl_la-socks_gssapi.lo \ + libcurl_la-socks_sspi.lo libcurl_la-curl_sspi.lo \ + libcurl_la-slist.lo libcurl_la-nonblock.lo \ + libcurl_la-curl_memrchr.lo libcurl_la-imap.lo \ + libcurl_la-pop3.lo libcurl_la-smtp.lo libcurl_la-pingpong.lo \ + libcurl_la-rtsp.lo libcurl_la-curl_threads.lo \ + libcurl_la-warnless.lo libcurl_la-hmac.lo \ + libcurl_la-curl_rtmp.lo libcurl_la-openldap.lo \ + libcurl_la-curl_gethostname.lo libcurl_la-gopher.lo \ + libcurl_la-idn_win32.lo libcurl_la-http_proxy.lo \ + libcurl_la-non-ascii.lo libcurl_la-asyn-ares.lo \ + libcurl_la-asyn-thread.lo libcurl_la-curl_gssapi.lo \ + libcurl_la-http_ntlm.lo libcurl_la-curl_ntlm_wb.lo \ + libcurl_la-curl_ntlm_core.lo libcurl_la-curl_sasl.lo \ + libcurl_la-rand.lo libcurl_la-curl_multibyte.lo \ + libcurl_la-hostcheck.lo libcurl_la-conncache.lo \ + libcurl_la-dotdot.lo libcurl_la-x509asn1.lo \ + libcurl_la-http2.lo libcurl_la-smb.lo \ + libcurl_la-curl_endian.lo libcurl_la-curl_des.lo \ + libcurl_la-system_win32.lo libcurl_la-mime.lo \ + libcurl_la-sha256.lo libcurl_la-setopt.lo \ + libcurl_la-curl_path.lo libcurl_la-curl_ctype.lo \ + libcurl_la-curl_range.lo libcurl_la-psl.lo libcurl_la-doh.lo \ + libcurl_la-urlapi.lo libcurl_la-curl_get_line.lo \ + libcurl_la-altsvc.lo +am__dirstamp = $(am__leading_dot)dirstamp +am__objects_2 = vauth/libcurl_la-vauth.lo \ + vauth/libcurl_la-cleartext.lo vauth/libcurl_la-cram.lo \ + vauth/libcurl_la-digest.lo vauth/libcurl_la-digest_sspi.lo \ + vauth/libcurl_la-krb5_gssapi.lo vauth/libcurl_la-krb5_sspi.lo \ + vauth/libcurl_la-ntlm.lo vauth/libcurl_la-ntlm_sspi.lo \ + vauth/libcurl_la-oauth2.lo vauth/libcurl_la-spnego_gssapi.lo \ + vauth/libcurl_la-spnego_sspi.lo +am__objects_3 = vtls/libcurl_la-openssl.lo vtls/libcurl_la-gtls.lo \ + vtls/libcurl_la-vtls.lo vtls/libcurl_la-nss.lo \ + vtls/libcurl_la-polarssl.lo \ + vtls/libcurl_la-polarssl_threadlock.lo \ + vtls/libcurl_la-wolfssl.lo vtls/libcurl_la-schannel.lo \ + vtls/libcurl_la-schannel_verify.lo \ + vtls/libcurl_la-sectransp.lo vtls/libcurl_la-gskit.lo \ + vtls/libcurl_la-mbedtls.lo vtls/libcurl_la-mesalink.lo +am__objects_4 = $(am__objects_1) $(am__objects_2) $(am__objects_3) +am__objects_5 = +am__objects_6 = $(am__objects_5) $(am__objects_5) $(am__objects_5) +am_libcurl_la_OBJECTS = $(am__objects_4) $(am__objects_6) +libcurl_la_OBJECTS = $(am_libcurl_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libcurl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libcurl_la_CFLAGS) \ + $(CFLAGS) $(libcurl_la_LDFLAGS) $(LDFLAGS) -o $@ +libcurlu_la_LIBADD = +am__objects_7 = libcurlu_la-file.lo libcurlu_la-timeval.lo \ + libcurlu_la-base64.lo libcurlu_la-hostip.lo \ + libcurlu_la-progress.lo libcurlu_la-formdata.lo \ + libcurlu_la-cookie.lo libcurlu_la-http.lo libcurlu_la-sendf.lo \ + libcurlu_la-ftp.lo libcurlu_la-url.lo libcurlu_la-dict.lo \ + libcurlu_la-if2ip.lo libcurlu_la-speedcheck.lo \ + libcurlu_la-ldap.lo libcurlu_la-version.lo \ + libcurlu_la-getenv.lo libcurlu_la-escape.lo \ + libcurlu_la-mprintf.lo libcurlu_la-telnet.lo \ + libcurlu_la-netrc.lo libcurlu_la-getinfo.lo \ + libcurlu_la-transfer.lo libcurlu_la-strcase.lo \ + libcurlu_la-easy.lo libcurlu_la-security.lo \ + libcurlu_la-curl_fnmatch.lo libcurlu_la-fileinfo.lo \ + libcurlu_la-ftplistparser.lo libcurlu_la-wildcard.lo \ + libcurlu_la-krb5.lo libcurlu_la-memdebug.lo \ + libcurlu_la-http_chunks.lo libcurlu_la-strtok.lo \ + libcurlu_la-connect.lo libcurlu_la-llist.lo \ + libcurlu_la-hash.lo libcurlu_la-multi.lo \ + libcurlu_la-content_encoding.lo libcurlu_la-share.lo \ + libcurlu_la-http_digest.lo libcurlu_la-md4.lo \ + libcurlu_la-md5.lo libcurlu_la-http_negotiate.lo \ + libcurlu_la-inet_pton.lo libcurlu_la-strtoofft.lo \ + libcurlu_la-strerror.lo libcurlu_la-amigaos.lo \ + libcurlu_la-hostasyn.lo libcurlu_la-hostip4.lo \ + libcurlu_la-hostip6.lo libcurlu_la-hostsyn.lo \ + libcurlu_la-inet_ntop.lo libcurlu_la-parsedate.lo \ + libcurlu_la-select.lo libcurlu_la-tftp.lo libcurlu_la-splay.lo \ + libcurlu_la-strdup.lo libcurlu_la-socks.lo libcurlu_la-ssh.lo \ + libcurlu_la-ssh-libssh.lo libcurlu_la-curl_addrinfo.lo \ + libcurlu_la-socks_gssapi.lo libcurlu_la-socks_sspi.lo \ + libcurlu_la-curl_sspi.lo libcurlu_la-slist.lo \ + libcurlu_la-nonblock.lo libcurlu_la-curl_memrchr.lo \ + libcurlu_la-imap.lo libcurlu_la-pop3.lo libcurlu_la-smtp.lo \ + libcurlu_la-pingpong.lo libcurlu_la-rtsp.lo \ + libcurlu_la-curl_threads.lo libcurlu_la-warnless.lo \ + libcurlu_la-hmac.lo libcurlu_la-curl_rtmp.lo \ + libcurlu_la-openldap.lo libcurlu_la-curl_gethostname.lo \ + libcurlu_la-gopher.lo libcurlu_la-idn_win32.lo \ + libcurlu_la-http_proxy.lo libcurlu_la-non-ascii.lo \ + libcurlu_la-asyn-ares.lo libcurlu_la-asyn-thread.lo \ + libcurlu_la-curl_gssapi.lo libcurlu_la-http_ntlm.lo \ + libcurlu_la-curl_ntlm_wb.lo libcurlu_la-curl_ntlm_core.lo \ + libcurlu_la-curl_sasl.lo libcurlu_la-rand.lo \ + libcurlu_la-curl_multibyte.lo libcurlu_la-hostcheck.lo \ + libcurlu_la-conncache.lo libcurlu_la-dotdot.lo \ + libcurlu_la-x509asn1.lo libcurlu_la-http2.lo \ + libcurlu_la-smb.lo libcurlu_la-curl_endian.lo \ + libcurlu_la-curl_des.lo libcurlu_la-system_win32.lo \ + libcurlu_la-mime.lo libcurlu_la-sha256.lo \ + libcurlu_la-setopt.lo libcurlu_la-curl_path.lo \ + libcurlu_la-curl_ctype.lo libcurlu_la-curl_range.lo \ + libcurlu_la-psl.lo libcurlu_la-doh.lo libcurlu_la-urlapi.lo \ + libcurlu_la-curl_get_line.lo libcurlu_la-altsvc.lo +am__objects_8 = vauth/libcurlu_la-vauth.lo \ + vauth/libcurlu_la-cleartext.lo vauth/libcurlu_la-cram.lo \ + vauth/libcurlu_la-digest.lo vauth/libcurlu_la-digest_sspi.lo \ + vauth/libcurlu_la-krb5_gssapi.lo \ + vauth/libcurlu_la-krb5_sspi.lo vauth/libcurlu_la-ntlm.lo \ + vauth/libcurlu_la-ntlm_sspi.lo vauth/libcurlu_la-oauth2.lo \ + vauth/libcurlu_la-spnego_gssapi.lo \ + vauth/libcurlu_la-spnego_sspi.lo +am__objects_9 = vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-gtls.lo \ + vtls/libcurlu_la-vtls.lo vtls/libcurlu_la-nss.lo \ + vtls/libcurlu_la-polarssl.lo \ + vtls/libcurlu_la-polarssl_threadlock.lo \ + vtls/libcurlu_la-wolfssl.lo vtls/libcurlu_la-schannel.lo \ + vtls/libcurlu_la-schannel_verify.lo \ + vtls/libcurlu_la-sectransp.lo vtls/libcurlu_la-gskit.lo \ + vtls/libcurlu_la-mbedtls.lo vtls/libcurlu_la-mesalink.lo +am__objects_10 = $(am__objects_7) $(am__objects_8) $(am__objects_9) +am_libcurlu_la_OBJECTS = $(am__objects_10) $(am__objects_6) +libcurlu_la_OBJECTS = $(am_libcurlu_la_OBJECTS) +libcurlu_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libcurlu_la_CFLAGS) \ + $(CFLAGS) $(libcurlu_la_LDFLAGS) $(LDFLAGS) -o $@ +@BUILD_UNITTESTS_TRUE@am_libcurlu_la_rpath = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ + ./$(DEPDIR)/libcurl_la-amigaos.Plo \ + ./$(DEPDIR)/libcurl_la-asyn-ares.Plo \ + ./$(DEPDIR)/libcurl_la-asyn-thread.Plo \ + ./$(DEPDIR)/libcurl_la-base64.Plo \ + ./$(DEPDIR)/libcurl_la-conncache.Plo \ + ./$(DEPDIR)/libcurl_la-connect.Plo \ + ./$(DEPDIR)/libcurl_la-content_encoding.Plo \ + ./$(DEPDIR)/libcurl_la-cookie.Plo \ + ./$(DEPDIR)/libcurl_la-curl_addrinfo.Plo \ + ./$(DEPDIR)/libcurl_la-curl_ctype.Plo \ + ./$(DEPDIR)/libcurl_la-curl_des.Plo \ + ./$(DEPDIR)/libcurl_la-curl_endian.Plo \ + ./$(DEPDIR)/libcurl_la-curl_fnmatch.Plo \ + ./$(DEPDIR)/libcurl_la-curl_get_line.Plo \ + ./$(DEPDIR)/libcurl_la-curl_gethostname.Plo \ + ./$(DEPDIR)/libcurl_la-curl_gssapi.Plo \ + ./$(DEPDIR)/libcurl_la-curl_memrchr.Plo \ + ./$(DEPDIR)/libcurl_la-curl_multibyte.Plo \ + ./$(DEPDIR)/libcurl_la-curl_ntlm_core.Plo \ + ./$(DEPDIR)/libcurl_la-curl_ntlm_wb.Plo \ + ./$(DEPDIR)/libcurl_la-curl_path.Plo \ + ./$(DEPDIR)/libcurl_la-curl_range.Plo \ + ./$(DEPDIR)/libcurl_la-curl_rtmp.Plo \ + ./$(DEPDIR)/libcurl_la-curl_sasl.Plo \ + ./$(DEPDIR)/libcurl_la-curl_sspi.Plo \ + ./$(DEPDIR)/libcurl_la-curl_threads.Plo \ + ./$(DEPDIR)/libcurl_la-dict.Plo ./$(DEPDIR)/libcurl_la-doh.Plo \ + ./$(DEPDIR)/libcurl_la-dotdot.Plo \ + ./$(DEPDIR)/libcurl_la-easy.Plo \ + ./$(DEPDIR)/libcurl_la-escape.Plo \ + ./$(DEPDIR)/libcurl_la-file.Plo \ + ./$(DEPDIR)/libcurl_la-fileinfo.Plo \ + ./$(DEPDIR)/libcurl_la-formdata.Plo \ + ./$(DEPDIR)/libcurl_la-ftp.Plo \ + ./$(DEPDIR)/libcurl_la-ftplistparser.Plo \ + ./$(DEPDIR)/libcurl_la-getenv.Plo \ + ./$(DEPDIR)/libcurl_la-getinfo.Plo \ + ./$(DEPDIR)/libcurl_la-gopher.Plo \ + ./$(DEPDIR)/libcurl_la-hash.Plo \ + ./$(DEPDIR)/libcurl_la-hmac.Plo \ + ./$(DEPDIR)/libcurl_la-hostasyn.Plo \ + ./$(DEPDIR)/libcurl_la-hostcheck.Plo \ + ./$(DEPDIR)/libcurl_la-hostip.Plo \ + ./$(DEPDIR)/libcurl_la-hostip4.Plo \ + ./$(DEPDIR)/libcurl_la-hostip6.Plo \ + ./$(DEPDIR)/libcurl_la-hostsyn.Plo \ + ./$(DEPDIR)/libcurl_la-http.Plo \ + ./$(DEPDIR)/libcurl_la-http2.Plo \ + ./$(DEPDIR)/libcurl_la-http_chunks.Plo \ + ./$(DEPDIR)/libcurl_la-http_digest.Plo \ + ./$(DEPDIR)/libcurl_la-http_negotiate.Plo \ + ./$(DEPDIR)/libcurl_la-http_ntlm.Plo \ + ./$(DEPDIR)/libcurl_la-http_proxy.Plo \ + ./$(DEPDIR)/libcurl_la-idn_win32.Plo \ + ./$(DEPDIR)/libcurl_la-if2ip.Plo \ + ./$(DEPDIR)/libcurl_la-imap.Plo \ + ./$(DEPDIR)/libcurl_la-inet_ntop.Plo \ + ./$(DEPDIR)/libcurl_la-inet_pton.Plo \ + ./$(DEPDIR)/libcurl_la-krb5.Plo \ + ./$(DEPDIR)/libcurl_la-ldap.Plo \ + ./$(DEPDIR)/libcurl_la-llist.Plo \ + ./$(DEPDIR)/libcurl_la-md4.Plo ./$(DEPDIR)/libcurl_la-md5.Plo \ + ./$(DEPDIR)/libcurl_la-memdebug.Plo \ + ./$(DEPDIR)/libcurl_la-mime.Plo \ + ./$(DEPDIR)/libcurl_la-mprintf.Plo \ + ./$(DEPDIR)/libcurl_la-multi.Plo \ + ./$(DEPDIR)/libcurl_la-netrc.Plo \ + ./$(DEPDIR)/libcurl_la-non-ascii.Plo \ + ./$(DEPDIR)/libcurl_la-nonblock.Plo \ + ./$(DEPDIR)/libcurl_la-openldap.Plo \ + ./$(DEPDIR)/libcurl_la-parsedate.Plo \ + ./$(DEPDIR)/libcurl_la-pingpong.Plo \ + ./$(DEPDIR)/libcurl_la-pop3.Plo \ + ./$(DEPDIR)/libcurl_la-progress.Plo \ + ./$(DEPDIR)/libcurl_la-psl.Plo ./$(DEPDIR)/libcurl_la-rand.Plo \ + ./$(DEPDIR)/libcurl_la-rtsp.Plo \ + ./$(DEPDIR)/libcurl_la-security.Plo \ + ./$(DEPDIR)/libcurl_la-select.Plo \ + ./$(DEPDIR)/libcurl_la-sendf.Plo \ + ./$(DEPDIR)/libcurl_la-setopt.Plo \ + ./$(DEPDIR)/libcurl_la-sha256.Plo \ + ./$(DEPDIR)/libcurl_la-share.Plo \ + ./$(DEPDIR)/libcurl_la-slist.Plo \ + ./$(DEPDIR)/libcurl_la-smb.Plo ./$(DEPDIR)/libcurl_la-smtp.Plo \ + ./$(DEPDIR)/libcurl_la-socks.Plo \ + ./$(DEPDIR)/libcurl_la-socks_gssapi.Plo \ + ./$(DEPDIR)/libcurl_la-socks_sspi.Plo \ + ./$(DEPDIR)/libcurl_la-speedcheck.Plo \ + ./$(DEPDIR)/libcurl_la-splay.Plo \ + ./$(DEPDIR)/libcurl_la-ssh-libssh.Plo \ + ./$(DEPDIR)/libcurl_la-ssh.Plo \ + ./$(DEPDIR)/libcurl_la-strcase.Plo \ + ./$(DEPDIR)/libcurl_la-strdup.Plo \ + ./$(DEPDIR)/libcurl_la-strerror.Plo \ + ./$(DEPDIR)/libcurl_la-strtok.Plo \ + ./$(DEPDIR)/libcurl_la-strtoofft.Plo \ + ./$(DEPDIR)/libcurl_la-system_win32.Plo \ + ./$(DEPDIR)/libcurl_la-telnet.Plo \ + ./$(DEPDIR)/libcurl_la-tftp.Plo \ + ./$(DEPDIR)/libcurl_la-timeval.Plo \ + ./$(DEPDIR)/libcurl_la-transfer.Plo \ + ./$(DEPDIR)/libcurl_la-url.Plo \ + ./$(DEPDIR)/libcurl_la-urlapi.Plo \ + ./$(DEPDIR)/libcurl_la-version.Plo \ + ./$(DEPDIR)/libcurl_la-warnless.Plo \ + ./$(DEPDIR)/libcurl_la-wildcard.Plo \ + ./$(DEPDIR)/libcurl_la-x509asn1.Plo \ + ./$(DEPDIR)/libcurlu_la-altsvc.Plo \ + ./$(DEPDIR)/libcurlu_la-amigaos.Plo \ + ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo \ + ./$(DEPDIR)/libcurlu_la-asyn-thread.Plo \ + ./$(DEPDIR)/libcurlu_la-base64.Plo \ + ./$(DEPDIR)/libcurlu_la-conncache.Plo \ + ./$(DEPDIR)/libcurlu_la-connect.Plo \ + ./$(DEPDIR)/libcurlu_la-content_encoding.Plo \ + ./$(DEPDIR)/libcurlu_la-cookie.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_addrinfo.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_ctype.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_des.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_endian.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_fnmatch.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_get_line.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_gethostname.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_gssapi.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_memrchr.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_multibyte.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_ntlm_core.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_ntlm_wb.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_path.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_range.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_rtmp.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_sasl.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_sspi.Plo \ + ./$(DEPDIR)/libcurlu_la-curl_threads.Plo \ + ./$(DEPDIR)/libcurlu_la-dict.Plo \ + ./$(DEPDIR)/libcurlu_la-doh.Plo \ + ./$(DEPDIR)/libcurlu_la-dotdot.Plo \ + ./$(DEPDIR)/libcurlu_la-easy.Plo \ + ./$(DEPDIR)/libcurlu_la-escape.Plo \ + ./$(DEPDIR)/libcurlu_la-file.Plo \ + ./$(DEPDIR)/libcurlu_la-fileinfo.Plo \ + ./$(DEPDIR)/libcurlu_la-formdata.Plo \ + ./$(DEPDIR)/libcurlu_la-ftp.Plo \ + ./$(DEPDIR)/libcurlu_la-ftplistparser.Plo \ + ./$(DEPDIR)/libcurlu_la-getenv.Plo \ + ./$(DEPDIR)/libcurlu_la-getinfo.Plo \ + ./$(DEPDIR)/libcurlu_la-gopher.Plo \ + ./$(DEPDIR)/libcurlu_la-hash.Plo \ + ./$(DEPDIR)/libcurlu_la-hmac.Plo \ + ./$(DEPDIR)/libcurlu_la-hostasyn.Plo \ + ./$(DEPDIR)/libcurlu_la-hostcheck.Plo \ + ./$(DEPDIR)/libcurlu_la-hostip.Plo \ + ./$(DEPDIR)/libcurlu_la-hostip4.Plo \ + ./$(DEPDIR)/libcurlu_la-hostip6.Plo \ + ./$(DEPDIR)/libcurlu_la-hostsyn.Plo \ + ./$(DEPDIR)/libcurlu_la-http.Plo \ + ./$(DEPDIR)/libcurlu_la-http2.Plo \ + ./$(DEPDIR)/libcurlu_la-http_chunks.Plo \ + ./$(DEPDIR)/libcurlu_la-http_digest.Plo \ + ./$(DEPDIR)/libcurlu_la-http_negotiate.Plo \ + ./$(DEPDIR)/libcurlu_la-http_ntlm.Plo \ + ./$(DEPDIR)/libcurlu_la-http_proxy.Plo \ + ./$(DEPDIR)/libcurlu_la-idn_win32.Plo \ + ./$(DEPDIR)/libcurlu_la-if2ip.Plo \ + ./$(DEPDIR)/libcurlu_la-imap.Plo \ + ./$(DEPDIR)/libcurlu_la-inet_ntop.Plo \ + ./$(DEPDIR)/libcurlu_la-inet_pton.Plo \ + ./$(DEPDIR)/libcurlu_la-krb5.Plo \ + ./$(DEPDIR)/libcurlu_la-ldap.Plo \ + ./$(DEPDIR)/libcurlu_la-llist.Plo \ + ./$(DEPDIR)/libcurlu_la-md4.Plo \ + ./$(DEPDIR)/libcurlu_la-md5.Plo \ + ./$(DEPDIR)/libcurlu_la-memdebug.Plo \ + ./$(DEPDIR)/libcurlu_la-mime.Plo \ + ./$(DEPDIR)/libcurlu_la-mprintf.Plo \ + ./$(DEPDIR)/libcurlu_la-multi.Plo \ + ./$(DEPDIR)/libcurlu_la-netrc.Plo \ + ./$(DEPDIR)/libcurlu_la-non-ascii.Plo \ + ./$(DEPDIR)/libcurlu_la-nonblock.Plo \ + ./$(DEPDIR)/libcurlu_la-openldap.Plo \ + ./$(DEPDIR)/libcurlu_la-parsedate.Plo \ + ./$(DEPDIR)/libcurlu_la-pingpong.Plo \ + ./$(DEPDIR)/libcurlu_la-pop3.Plo \ + ./$(DEPDIR)/libcurlu_la-progress.Plo \ + ./$(DEPDIR)/libcurlu_la-psl.Plo \ + ./$(DEPDIR)/libcurlu_la-rand.Plo \ + ./$(DEPDIR)/libcurlu_la-rtsp.Plo \ + ./$(DEPDIR)/libcurlu_la-security.Plo \ + ./$(DEPDIR)/libcurlu_la-select.Plo \ + ./$(DEPDIR)/libcurlu_la-sendf.Plo \ + ./$(DEPDIR)/libcurlu_la-setopt.Plo \ + ./$(DEPDIR)/libcurlu_la-sha256.Plo \ + ./$(DEPDIR)/libcurlu_la-share.Plo \ + ./$(DEPDIR)/libcurlu_la-slist.Plo \ + ./$(DEPDIR)/libcurlu_la-smb.Plo \ + ./$(DEPDIR)/libcurlu_la-smtp.Plo \ + ./$(DEPDIR)/libcurlu_la-socks.Plo \ + ./$(DEPDIR)/libcurlu_la-socks_gssapi.Plo \ + ./$(DEPDIR)/libcurlu_la-socks_sspi.Plo \ + ./$(DEPDIR)/libcurlu_la-speedcheck.Plo \ + ./$(DEPDIR)/libcurlu_la-splay.Plo \ + ./$(DEPDIR)/libcurlu_la-ssh-libssh.Plo \ + ./$(DEPDIR)/libcurlu_la-ssh.Plo \ + ./$(DEPDIR)/libcurlu_la-strcase.Plo \ + ./$(DEPDIR)/libcurlu_la-strdup.Plo \ + ./$(DEPDIR)/libcurlu_la-strerror.Plo \ + ./$(DEPDIR)/libcurlu_la-strtok.Plo \ + ./$(DEPDIR)/libcurlu_la-strtoofft.Plo \ + ./$(DEPDIR)/libcurlu_la-system_win32.Plo \ + ./$(DEPDIR)/libcurlu_la-telnet.Plo \ + ./$(DEPDIR)/libcurlu_la-tftp.Plo \ + ./$(DEPDIR)/libcurlu_la-timeval.Plo \ + ./$(DEPDIR)/libcurlu_la-transfer.Plo \ + ./$(DEPDIR)/libcurlu_la-url.Plo \ + ./$(DEPDIR)/libcurlu_la-urlapi.Plo \ + ./$(DEPDIR)/libcurlu_la-version.Plo \ + ./$(DEPDIR)/libcurlu_la-warnless.Plo \ + ./$(DEPDIR)/libcurlu_la-wildcard.Plo \ + ./$(DEPDIR)/libcurlu_la-x509asn1.Plo \ + vauth/$(DEPDIR)/libcurl_la-cleartext.Plo \ + vauth/$(DEPDIR)/libcurl_la-cram.Plo \ + vauth/$(DEPDIR)/libcurl_la-digest.Plo \ + vauth/$(DEPDIR)/libcurl_la-digest_sspi.Plo \ + vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Plo \ + vauth/$(DEPDIR)/libcurl_la-krb5_sspi.Plo \ + vauth/$(DEPDIR)/libcurl_la-ntlm.Plo \ + vauth/$(DEPDIR)/libcurl_la-ntlm_sspi.Plo \ + vauth/$(DEPDIR)/libcurl_la-oauth2.Plo \ + vauth/$(DEPDIR)/libcurl_la-spnego_gssapi.Plo \ + vauth/$(DEPDIR)/libcurl_la-spnego_sspi.Plo \ + vauth/$(DEPDIR)/libcurl_la-vauth.Plo \ + vauth/$(DEPDIR)/libcurlu_la-cleartext.Plo \ + vauth/$(DEPDIR)/libcurlu_la-cram.Plo \ + vauth/$(DEPDIR)/libcurlu_la-digest.Plo \ + vauth/$(DEPDIR)/libcurlu_la-digest_sspi.Plo \ + vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Plo \ + vauth/$(DEPDIR)/libcurlu_la-krb5_sspi.Plo \ + vauth/$(DEPDIR)/libcurlu_la-ntlm.Plo \ + vauth/$(DEPDIR)/libcurlu_la-ntlm_sspi.Plo \ + vauth/$(DEPDIR)/libcurlu_la-oauth2.Plo \ + vauth/$(DEPDIR)/libcurlu_la-spnego_gssapi.Plo \ + vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo \ + vauth/$(DEPDIR)/libcurlu_la-vauth.Plo \ + vtls/$(DEPDIR)/libcurl_la-gskit.Plo \ + vtls/$(DEPDIR)/libcurl_la-gtls.Plo \ + vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo \ + vtls/$(DEPDIR)/libcurl_la-mesalink.Plo \ + vtls/$(DEPDIR)/libcurl_la-nss.Plo \ + vtls/$(DEPDIR)/libcurl_la-openssl.Plo \ + vtls/$(DEPDIR)/libcurl_la-polarssl.Plo \ + vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo \ + vtls/$(DEPDIR)/libcurl_la-schannel.Plo \ + vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo \ + vtls/$(DEPDIR)/libcurl_la-sectransp.Plo \ + vtls/$(DEPDIR)/libcurl_la-vtls.Plo \ + vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo \ + vtls/$(DEPDIR)/libcurlu_la-gskit.Plo \ + vtls/$(DEPDIR)/libcurlu_la-gtls.Plo \ + vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo \ + vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo \ + vtls/$(DEPDIR)/libcurlu_la-nss.Plo \ + vtls/$(DEPDIR)/libcurlu_la-openssl.Plo \ + vtls/$(DEPDIR)/libcurlu_la-polarssl.Plo \ + vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo \ + vtls/$(DEPDIR)/libcurlu_la-schannel.Plo \ + vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo \ + vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo \ + vtls/$(DEPDIR)/libcurlu_la-vtls.Plo \ + vtls/$(DEPDIR)/libcurlu_la-wolfssl.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libcurl_la_SOURCES) $(libcurlu_la_SOURCES) +DIST_SOURCES = $(libcurl_la_SOURCES) $(libcurlu_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)curl_config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \ + $(srcdir)/curl_config.h.in $(srcdir)/libcurl.vers.in \ + $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AR_FLAGS = @AR_FLAGS@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLANK_AT_MAKETIME = @BLANK_AT_MAKETIME@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ + +# This might hold -Werror +CFLAGS = @CFLAGS@ @CURL_CFLAG_EXTRAS@ +CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ +CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ +CURLVERSION = @CURLVERSION@ +CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ +CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ +CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ +CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ +CURL_DISABLE_FTP = @CURL_DISABLE_FTP@ +CURL_DISABLE_GOPHER = @CURL_DISABLE_GOPHER@ +CURL_DISABLE_HTTP = @CURL_DISABLE_HTTP@ +CURL_DISABLE_IMAP = @CURL_DISABLE_IMAP@ +CURL_DISABLE_LDAP = @CURL_DISABLE_LDAP@ +CURL_DISABLE_LDAPS = @CURL_DISABLE_LDAPS@ +CURL_DISABLE_POP3 = @CURL_DISABLE_POP3@ +CURL_DISABLE_PROXY = @CURL_DISABLE_PROXY@ +CURL_DISABLE_RTSP = @CURL_DISABLE_RTSP@ +CURL_DISABLE_SMB = @CURL_DISABLE_SMB@ +CURL_DISABLE_SMTP = @CURL_DISABLE_SMTP@ +CURL_DISABLE_TELNET = @CURL_DISABLE_TELNET@ +CURL_DISABLE_TFTP = @CURL_DISABLE_TFTP@ +CURL_LT_SHLIB_VERSIONED_FLAVOUR = @CURL_LT_SHLIB_VERSIONED_FLAVOUR@ +CURL_NETWORK_AND_TIME_LIBS = @CURL_NETWORK_AND_TIME_LIBS@ +CURL_NETWORK_LIBS = @CURL_NETWORK_LIBS@ +CURL_WITH_MULTI_SSL = @CURL_WITH_MULTI_SSL@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_SSL_BACKEND = @DEFAULT_SSL_BACKEND@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_SHARED = @ENABLE_SHARED@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FISH_FUNCTIONS_DIR = @FISH_FUNCTIONS_DIR@ +GCOV = @GCOV@ +GREP = @GREP@ +HAVE_BROTLI = @HAVE_BROTLI@ +HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ +HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ +HAVE_LIBZ = @HAVE_LIBZ@ +HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ +HAVE_PROTO_BSDSOCKET_H = @HAVE_PROTO_BSDSOCKET_H@ +IDN_ENABLED = @IDN_ENABLED@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IPV6_ENABLED = @IPV6_ENABLED@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCURL_LIBS = @LIBCURL_LIBS@ +LIBMETALINK_CPPFLAGS = @LIBMETALINK_CPPFLAGS@ +LIBMETALINK_LDFLAGS = @LIBMETALINK_LDFLAGS@ +LIBMETALINK_LIBS = @LIBMETALINK_LIBS@ +LIBOBJS = @LIBOBJS@ + +# Prevent LIBS from being used for all link targets +LIBS = $(BLANK_AT_MAKETIME) +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MANOPT = @MANOPT@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NROFF = @NROFF@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKGADD_NAME = @PKGADD_NAME@ +PKGADD_PKG = @PKGADD_PKG@ +PKGADD_VENDOR = @PKGADD_VENDOR@ +PKGCONFIG = @PKGCONFIG@ +RANDOM_FILE = @RANDOM_FILE@ +RANLIB = @RANLIB@ +REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SSL_BACKENDS = @SSL_BACKENDS@ +SSL_ENABLED = @SSL_ENABLED@ +SSL_LIBS = @SSL_LIBS@ +STRIP = @STRIP@ +SUPPORT_FEATURES = @SUPPORT_FEATURES@ +SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ +USE_ARES = @USE_ARES@ +USE_GNUTLS = @USE_GNUTLS@ +USE_GNUTLS_NETTLE = @USE_GNUTLS_NETTLE@ +USE_LIBRTMP = @USE_LIBRTMP@ +USE_LIBSSH = @USE_LIBSSH@ +USE_LIBSSH2 = @USE_LIBSSH2@ +USE_MBEDTLS = @USE_MBEDTLS@ +USE_MESALINK = @USE_MESALINK@ +USE_NGHTTP2 = @USE_NGHTTP2@ +USE_NSS = @USE_NSS@ +USE_OPENLDAP = @USE_OPENLDAP@ +USE_SCHANNEL = @USE_SCHANNEL@ +USE_SECTRANSP = @USE_SECTRANSP@ +USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@ +USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@ +USE_WOLFSSL = @USE_WOLFSSL@ +VERSION = @VERSION@ +VERSIONNUM = @VERSIONNUM@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSH_FUNCTIONS_DIR = @ZSH_FUNCTIONS_DIR@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libext = @libext@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### +AUTOMAKE_OPTIONS = foreign nostdinc +CMAKE_DIST = CMakeLists.txt curl_config.h.cmake +EXTRA_DIST = Makefile.m32 config-win32.h \ + config-win32ce.h config-riscos.h config-mac.h curl_config.h.in \ + makefile.dj config-dos.h libcurl.plist libcurl.rc config-amigaos.h \ + makefile.amiga Makefile.netware nwlib.c nwos.c config-win32ce.h \ + config-os400.h setup-os400.h config-symbian.h Makefile.Watcom \ + config-tpf.h mk-ca-bundle.pl mk-ca-bundle.vbs $(CMAKE_DIST) \ + firefox-db2pem.sh config-vxworks.h Makefile.vxworks checksrc.pl + +lib_LTLIBRARIES = libcurl.la +@BUILD_UNITTESTS_FALSE@noinst_LTLIBRARIES = +@BUILD_UNITTESTS_TRUE@noinst_LTLIBRARIES = libcurlu.la + +# Specify our include paths here, and do it relative to $(top_srcdir) and +# $(top_builddir), to ensure that these paths which belong to the library +# being currently built and tested are searched before the library which +# might possibly already be installed in the system. +# +# $(top_srcdir)/include is for libcurl's external include files +# $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file +# $(top_srcdir)/lib for libcurl's lib/curl_setup.h and other "private" files +# $(top_builddir)/ares is for in-tree c-ares's generated ares_build.h file +# $(top_srcdir)/ares is for in-tree c-ares's external include files +# This flag accepts an argument of the form current[:revision[:age]]. So, +# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to +# 1. +# +# Here's the simplified rule guide on how to change -version-info: +# (current version is C:R:A) +# +# 1. if there are only source changes, use C:R+1:A +# 2. if interfaces were added use C+1:0:A+1 +# 3. if interfaces were removed, then use C+1:0:0 +# +# For the full guide on libcurl ABI rules, see docs/libcurl/ABI +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib $(am__append_1) -DBUILDING_LIBCURL +VERSIONINFO = -version-info 9:0:5 +AM_LDFLAGS = +AM_CFLAGS = +libcurl_la_CPPFLAGS_EXTRA = $(am__append_7) $(am__append_8) +libcurl_la_LDFLAGS_EXTRA = $(am__append_2) $(am__append_3) \ + $(am__append_4) $(am__append_5) $(am__append_6) +libcurl_la_CFLAGS_EXTRA = $(am__append_9) +libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA) +libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LDFLAGS) $(LIBCURL_LIBS) +libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA) +libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS +libcurlu_la_LDFLAGS = $(AM_LDFLAGS) -static $(LIBCURL_LIBS) +libcurlu_la_CFLAGS = $(AM_CFLAGS) +LIB_VAUTH_CFILES = vauth/vauth.c vauth/cleartext.c vauth/cram.c \ + vauth/digest.c vauth/digest_sspi.c vauth/krb5_gssapi.c \ + vauth/krb5_sspi.c vauth/ntlm.c vauth/ntlm_sspi.c vauth/oauth2.c \ + vauth/spnego_gssapi.c vauth/spnego_sspi.c + +LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h +LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \ + vtls/polarssl.c vtls/polarssl_threadlock.c \ + vtls/wolfssl.c vtls/schannel.c vtls/schannel_verify.c \ + vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c + +LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \ + vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h \ + vtls/wolfssl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h \ + vtls/mbedtls.h vtls/mesalink.h + +LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ + cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \ + ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \ + getinfo.c transfer.c strcase.c easy.c security.c curl_fnmatch.c \ + fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \ + strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c \ + http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c \ + strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c \ + inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c \ + ssh.c ssh-libssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \ + curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \ + pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c \ + openldap.c curl_gethostname.c gopher.c idn_win32.c \ + http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c \ + http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \ + curl_multibyte.c hostcheck.c conncache.c dotdot.c \ + x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \ + mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \ + doh.c urlapi.c curl_get_line.c altsvc.c + +LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ + formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \ + speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h \ + strcase.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h \ + wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h \ + hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \ + http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \ + inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \ + easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \ + socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h \ + slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \ + rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \ + curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \ + http_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h \ + curl_sasl.h curl_multibyte.h hostcheck.h conncache.h \ + curl_setup_once.h multihandle.h setup-vms.h dotdot.h \ + x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \ + curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \ + curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h \ + curl_get_line.h altsvc.h + +LIB_RCFILES = libcurl.rc +CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) +HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) + +# Makefile.inc provides the CSOURCES and HHEADERS defines +libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS) +libcurlu_la_SOURCES = $(CSOURCES) $(HHEADERS) +CHECKSRC = $(CS_$(V)) +CS_0 = @echo " RUN " $@; +CS_1 = +CS_ = $(CS_0) + +# disable the tests that are mostly causing false positives +TIDYFLAGS = -checks=-clang-analyzer-security.insecureAPI.strcpy,-clang-analyzer-optin.performance.Padding,-clang-analyzer-valist.Uninitialized,-clang-analyzer-core.NonNullParamChecker,-clang-analyzer-core.NullDereference -quiet +TIDY := clang-tidy +all: curl_config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile.inc $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign lib/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(srcdir)/Makefile.inc $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +curl_config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/curl_config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status lib/curl_config.h +$(srcdir)/curl_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f curl_config.h stamp-h1 +libcurl.vers: $(top_builddir)/config.status $(srcdir)/libcurl.vers.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +vauth/$(am__dirstamp): + @$(MKDIR_P) vauth + @: > vauth/$(am__dirstamp) +vauth/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) vauth/$(DEPDIR) + @: > vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-vauth.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-cleartext.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-cram.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-digest.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-digest_sspi.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-krb5_gssapi.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-krb5_sspi.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-ntlm.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-ntlm_sspi.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-oauth2.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-spnego_gssapi.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-spnego_sspi.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vtls/$(am__dirstamp): + @$(MKDIR_P) vtls + @: > vtls/$(am__dirstamp) +vtls/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) vtls/$(DEPDIR) + @: > vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-openssl.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-gtls.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-vtls.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-nss.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-polarssl.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-polarssl_threadlock.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-wolfssl.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-schannel.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-schannel_verify.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-sectransp.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-gskit.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-mbedtls.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-mesalink.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) + +libcurl.la: $(libcurl_la_OBJECTS) $(libcurl_la_DEPENDENCIES) $(EXTRA_libcurl_la_DEPENDENCIES) + $(AM_V_CCLD)$(libcurl_la_LINK) -rpath $(libdir) $(libcurl_la_OBJECTS) $(libcurl_la_LIBADD) $(LIBS) +vauth/libcurlu_la-vauth.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurlu_la-cleartext.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurlu_la-cram.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurlu_la-digest.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurlu_la-digest_sspi.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurlu_la-krb5_gssapi.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurlu_la-krb5_sspi.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurlu_la-ntlm.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurlu_la-ntlm_sspi.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurlu_la-oauth2.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurlu_la-spnego_gssapi.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurlu_la-spnego_sspi.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-openssl.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-gtls.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-vtls.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-nss.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-polarssl.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-polarssl_threadlock.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-wolfssl.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-schannel.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-schannel_verify.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-sectransp.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-gskit.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-mbedtls.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-mesalink.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) + +libcurlu.la: $(libcurlu_la_OBJECTS) $(libcurlu_la_DEPENDENCIES) $(EXTRA_libcurlu_la_DEPENDENCIES) + $(AM_V_CCLD)$(libcurlu_la_LINK) $(am_libcurlu_la_rpath) $(libcurlu_la_OBJECTS) $(libcurlu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f vauth/*.$(OBJEXT) + -rm -f vauth/*.lo + -rm -f vtls/*.$(OBJEXT) + -rm -f vtls/*.lo + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-altsvc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-amigaos.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-asyn-ares.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-asyn-thread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-base64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-conncache.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-connect.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-content_encoding.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-cookie.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_addrinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_ctype.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_des.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_endian.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_fnmatch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_get_line.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_gethostname.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_gssapi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_memrchr.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_multibyte.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_ntlm_core.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_ntlm_wb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_path.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_range.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_rtmp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_sasl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_threads.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-dict.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-doh.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-dotdot.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-easy.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-escape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-file.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-fileinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-formdata.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-ftp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-ftplistparser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-getenv.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-getinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-gopher.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-hash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-hmac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-hostasyn.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-hostcheck.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-hostip.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-hostip4.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-hostip6.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-hostsyn.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-http.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-http2.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-http_chunks.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-http_digest.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-http_negotiate.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-http_ntlm.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-http_proxy.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-idn_win32.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-if2ip.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-imap.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-inet_ntop.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-inet_pton.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-krb5.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-ldap.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-llist.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-md4.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-md5.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-memdebug.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-mime.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-mprintf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-multi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-netrc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-non-ascii.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-nonblock.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-openldap.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-parsedate.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-pingpong.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-pop3.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-progress.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-psl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-rand.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-rtsp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-security.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-select.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-sendf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-setopt.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-sha256.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-share.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-slist.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-smb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-smtp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-socks.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-socks_gssapi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-socks_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-speedcheck.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-splay.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-ssh-libssh.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-ssh.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-strcase.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-strdup.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-strerror.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-strtok.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-strtoofft.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-system_win32.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-telnet.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-tftp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-timeval.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-transfer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-url.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-urlapi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-version.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-warnless.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-wildcard.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-x509asn1.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-altsvc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-amigaos.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-asyn-ares.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-asyn-thread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-base64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-conncache.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-connect.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-content_encoding.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-cookie.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_addrinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_ctype.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_des.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_endian.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_fnmatch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_get_line.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_gethostname.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_gssapi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_memrchr.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_multibyte.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_ntlm_core.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_ntlm_wb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_path.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_range.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_rtmp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_sasl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_threads.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-dict.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-doh.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-dotdot.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-easy.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-escape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-file.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-fileinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-formdata.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-ftp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-ftplistparser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-getenv.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-getinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-gopher.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-hash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-hmac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-hostasyn.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-hostcheck.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-hostip.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-hostip4.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-hostip6.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-hostsyn.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-http.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-http2.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-http_chunks.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-http_digest.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-http_negotiate.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-http_ntlm.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-http_proxy.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-idn_win32.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-if2ip.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-imap.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-inet_ntop.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-inet_pton.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-krb5.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-ldap.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-llist.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-md4.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-md5.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-memdebug.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-mime.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-mprintf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-multi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-netrc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-non-ascii.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-nonblock.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-openldap.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-parsedate.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-pingpong.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-pop3.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-progress.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-psl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-rand.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-rtsp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-security.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-select.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-sendf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-setopt.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-sha256.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-share.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-slist.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-smb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-smtp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-socks.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-socks_gssapi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-socks_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-speedcheck.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-splay.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-ssh-libssh.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-ssh.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-strcase.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-strdup.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-strerror.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-strtok.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-strtoofft.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-system_win32.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-telnet.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-tftp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-timeval.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-transfer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-url.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-urlapi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-version.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-warnless.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-wildcard.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-x509asn1.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-cleartext.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-cram.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-digest.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-digest_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-krb5_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-ntlm.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-ntlm_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-oauth2.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-spnego_gssapi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-spnego_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-vauth.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-cleartext.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-cram.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-digest.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-digest_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-krb5_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-ntlm.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-ntlm_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-oauth2.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-spnego_gssapi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-vauth.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-gskit.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-gtls.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-mesalink.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-nss.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-openssl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-polarssl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-schannel.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-sectransp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-vtls.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-gskit.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-gtls.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-nss.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-openssl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-polarssl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-schannel.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-vtls.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-wolfssl.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libcurl_la-file.lo: file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-file.lo -MD -MP -MF $(DEPDIR)/libcurl_la-file.Tpo -c -o libcurl_la-file.lo `test -f 'file.c' || echo '$(srcdir)/'`file.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-file.Tpo $(DEPDIR)/libcurl_la-file.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='file.c' object='libcurl_la-file.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-file.lo `test -f 'file.c' || echo '$(srcdir)/'`file.c + +libcurl_la-timeval.lo: timeval.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-timeval.lo -MD -MP -MF $(DEPDIR)/libcurl_la-timeval.Tpo -c -o libcurl_la-timeval.lo `test -f 'timeval.c' || echo '$(srcdir)/'`timeval.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-timeval.Tpo $(DEPDIR)/libcurl_la-timeval.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='timeval.c' object='libcurl_la-timeval.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-timeval.lo `test -f 'timeval.c' || echo '$(srcdir)/'`timeval.c + +libcurl_la-base64.lo: base64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-base64.lo -MD -MP -MF $(DEPDIR)/libcurl_la-base64.Tpo -c -o libcurl_la-base64.lo `test -f 'base64.c' || echo '$(srcdir)/'`base64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-base64.Tpo $(DEPDIR)/libcurl_la-base64.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='libcurl_la-base64.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-base64.lo `test -f 'base64.c' || echo '$(srcdir)/'`base64.c + +libcurl_la-hostip.lo: hostip.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-hostip.lo -MD -MP -MF $(DEPDIR)/libcurl_la-hostip.Tpo -c -o libcurl_la-hostip.lo `test -f 'hostip.c' || echo '$(srcdir)/'`hostip.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-hostip.Tpo $(DEPDIR)/libcurl_la-hostip.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hostip.c' object='libcurl_la-hostip.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-hostip.lo `test -f 'hostip.c' || echo '$(srcdir)/'`hostip.c + +libcurl_la-progress.lo: progress.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-progress.lo -MD -MP -MF $(DEPDIR)/libcurl_la-progress.Tpo -c -o libcurl_la-progress.lo `test -f 'progress.c' || echo '$(srcdir)/'`progress.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-progress.Tpo $(DEPDIR)/libcurl_la-progress.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='progress.c' object='libcurl_la-progress.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-progress.lo `test -f 'progress.c' || echo '$(srcdir)/'`progress.c + +libcurl_la-formdata.lo: formdata.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-formdata.lo -MD -MP -MF $(DEPDIR)/libcurl_la-formdata.Tpo -c -o libcurl_la-formdata.lo `test -f 'formdata.c' || echo '$(srcdir)/'`formdata.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-formdata.Tpo $(DEPDIR)/libcurl_la-formdata.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='formdata.c' object='libcurl_la-formdata.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-formdata.lo `test -f 'formdata.c' || echo '$(srcdir)/'`formdata.c + +libcurl_la-cookie.lo: cookie.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-cookie.lo -MD -MP -MF $(DEPDIR)/libcurl_la-cookie.Tpo -c -o libcurl_la-cookie.lo `test -f 'cookie.c' || echo '$(srcdir)/'`cookie.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-cookie.Tpo $(DEPDIR)/libcurl_la-cookie.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cookie.c' object='libcurl_la-cookie.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-cookie.lo `test -f 'cookie.c' || echo '$(srcdir)/'`cookie.c + +libcurl_la-http.lo: http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-http.lo -MD -MP -MF $(DEPDIR)/libcurl_la-http.Tpo -c -o libcurl_la-http.lo `test -f 'http.c' || echo '$(srcdir)/'`http.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-http.Tpo $(DEPDIR)/libcurl_la-http.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='libcurl_la-http.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-http.lo `test -f 'http.c' || echo '$(srcdir)/'`http.c + +libcurl_la-sendf.lo: sendf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-sendf.lo -MD -MP -MF $(DEPDIR)/libcurl_la-sendf.Tpo -c -o libcurl_la-sendf.lo `test -f 'sendf.c' || echo '$(srcdir)/'`sendf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-sendf.Tpo $(DEPDIR)/libcurl_la-sendf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sendf.c' object='libcurl_la-sendf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-sendf.lo `test -f 'sendf.c' || echo '$(srcdir)/'`sendf.c + +libcurl_la-ftp.lo: ftp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-ftp.lo -MD -MP -MF $(DEPDIR)/libcurl_la-ftp.Tpo -c -o libcurl_la-ftp.lo `test -f 'ftp.c' || echo '$(srcdir)/'`ftp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-ftp.Tpo $(DEPDIR)/libcurl_la-ftp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftp.c' object='libcurl_la-ftp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-ftp.lo `test -f 'ftp.c' || echo '$(srcdir)/'`ftp.c + +libcurl_la-url.lo: url.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-url.lo -MD -MP -MF $(DEPDIR)/libcurl_la-url.Tpo -c -o libcurl_la-url.lo `test -f 'url.c' || echo '$(srcdir)/'`url.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-url.Tpo $(DEPDIR)/libcurl_la-url.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='url.c' object='libcurl_la-url.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-url.lo `test -f 'url.c' || echo '$(srcdir)/'`url.c + +libcurl_la-dict.lo: dict.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-dict.lo -MD -MP -MF $(DEPDIR)/libcurl_la-dict.Tpo -c -o libcurl_la-dict.lo `test -f 'dict.c' || echo '$(srcdir)/'`dict.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-dict.Tpo $(DEPDIR)/libcurl_la-dict.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dict.c' object='libcurl_la-dict.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-dict.lo `test -f 'dict.c' || echo '$(srcdir)/'`dict.c + +libcurl_la-if2ip.lo: if2ip.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-if2ip.lo -MD -MP -MF $(DEPDIR)/libcurl_la-if2ip.Tpo -c -o libcurl_la-if2ip.lo `test -f 'if2ip.c' || echo '$(srcdir)/'`if2ip.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-if2ip.Tpo $(DEPDIR)/libcurl_la-if2ip.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='if2ip.c' object='libcurl_la-if2ip.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-if2ip.lo `test -f 'if2ip.c' || echo '$(srcdir)/'`if2ip.c + +libcurl_la-speedcheck.lo: speedcheck.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-speedcheck.lo -MD -MP -MF $(DEPDIR)/libcurl_la-speedcheck.Tpo -c -o libcurl_la-speedcheck.lo `test -f 'speedcheck.c' || echo '$(srcdir)/'`speedcheck.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-speedcheck.Tpo $(DEPDIR)/libcurl_la-speedcheck.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='speedcheck.c' object='libcurl_la-speedcheck.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-speedcheck.lo `test -f 'speedcheck.c' || echo '$(srcdir)/'`speedcheck.c + +libcurl_la-ldap.lo: ldap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-ldap.lo -MD -MP -MF $(DEPDIR)/libcurl_la-ldap.Tpo -c -o libcurl_la-ldap.lo `test -f 'ldap.c' || echo '$(srcdir)/'`ldap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-ldap.Tpo $(DEPDIR)/libcurl_la-ldap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ldap.c' object='libcurl_la-ldap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-ldap.lo `test -f 'ldap.c' || echo '$(srcdir)/'`ldap.c + +libcurl_la-version.lo: version.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-version.lo -MD -MP -MF $(DEPDIR)/libcurl_la-version.Tpo -c -o libcurl_la-version.lo `test -f 'version.c' || echo '$(srcdir)/'`version.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-version.Tpo $(DEPDIR)/libcurl_la-version.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='version.c' object='libcurl_la-version.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-version.lo `test -f 'version.c' || echo '$(srcdir)/'`version.c + +libcurl_la-getenv.lo: getenv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-getenv.lo -MD -MP -MF $(DEPDIR)/libcurl_la-getenv.Tpo -c -o libcurl_la-getenv.lo `test -f 'getenv.c' || echo '$(srcdir)/'`getenv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-getenv.Tpo $(DEPDIR)/libcurl_la-getenv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getenv.c' object='libcurl_la-getenv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-getenv.lo `test -f 'getenv.c' || echo '$(srcdir)/'`getenv.c + +libcurl_la-escape.lo: escape.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-escape.lo -MD -MP -MF $(DEPDIR)/libcurl_la-escape.Tpo -c -o libcurl_la-escape.lo `test -f 'escape.c' || echo '$(srcdir)/'`escape.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-escape.Tpo $(DEPDIR)/libcurl_la-escape.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='escape.c' object='libcurl_la-escape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-escape.lo `test -f 'escape.c' || echo '$(srcdir)/'`escape.c + +libcurl_la-mprintf.lo: mprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-mprintf.lo -MD -MP -MF $(DEPDIR)/libcurl_la-mprintf.Tpo -c -o libcurl_la-mprintf.lo `test -f 'mprintf.c' || echo '$(srcdir)/'`mprintf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-mprintf.Tpo $(DEPDIR)/libcurl_la-mprintf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mprintf.c' object='libcurl_la-mprintf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-mprintf.lo `test -f 'mprintf.c' || echo '$(srcdir)/'`mprintf.c + +libcurl_la-telnet.lo: telnet.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-telnet.lo -MD -MP -MF $(DEPDIR)/libcurl_la-telnet.Tpo -c -o libcurl_la-telnet.lo `test -f 'telnet.c' || echo '$(srcdir)/'`telnet.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-telnet.Tpo $(DEPDIR)/libcurl_la-telnet.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='telnet.c' object='libcurl_la-telnet.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-telnet.lo `test -f 'telnet.c' || echo '$(srcdir)/'`telnet.c + +libcurl_la-netrc.lo: netrc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-netrc.lo -MD -MP -MF $(DEPDIR)/libcurl_la-netrc.Tpo -c -o libcurl_la-netrc.lo `test -f 'netrc.c' || echo '$(srcdir)/'`netrc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-netrc.Tpo $(DEPDIR)/libcurl_la-netrc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netrc.c' object='libcurl_la-netrc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-netrc.lo `test -f 'netrc.c' || echo '$(srcdir)/'`netrc.c + +libcurl_la-getinfo.lo: getinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-getinfo.lo -MD -MP -MF $(DEPDIR)/libcurl_la-getinfo.Tpo -c -o libcurl_la-getinfo.lo `test -f 'getinfo.c' || echo '$(srcdir)/'`getinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-getinfo.Tpo $(DEPDIR)/libcurl_la-getinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getinfo.c' object='libcurl_la-getinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-getinfo.lo `test -f 'getinfo.c' || echo '$(srcdir)/'`getinfo.c + +libcurl_la-transfer.lo: transfer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-transfer.lo -MD -MP -MF $(DEPDIR)/libcurl_la-transfer.Tpo -c -o libcurl_la-transfer.lo `test -f 'transfer.c' || echo '$(srcdir)/'`transfer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-transfer.Tpo $(DEPDIR)/libcurl_la-transfer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='transfer.c' object='libcurl_la-transfer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-transfer.lo `test -f 'transfer.c' || echo '$(srcdir)/'`transfer.c + +libcurl_la-strcase.lo: strcase.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-strcase.lo -MD -MP -MF $(DEPDIR)/libcurl_la-strcase.Tpo -c -o libcurl_la-strcase.lo `test -f 'strcase.c' || echo '$(srcdir)/'`strcase.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-strcase.Tpo $(DEPDIR)/libcurl_la-strcase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strcase.c' object='libcurl_la-strcase.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-strcase.lo `test -f 'strcase.c' || echo '$(srcdir)/'`strcase.c + +libcurl_la-easy.lo: easy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-easy.lo -MD -MP -MF $(DEPDIR)/libcurl_la-easy.Tpo -c -o libcurl_la-easy.lo `test -f 'easy.c' || echo '$(srcdir)/'`easy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-easy.Tpo $(DEPDIR)/libcurl_la-easy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='easy.c' object='libcurl_la-easy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-easy.lo `test -f 'easy.c' || echo '$(srcdir)/'`easy.c + +libcurl_la-security.lo: security.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-security.lo -MD -MP -MF $(DEPDIR)/libcurl_la-security.Tpo -c -o libcurl_la-security.lo `test -f 'security.c' || echo '$(srcdir)/'`security.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-security.Tpo $(DEPDIR)/libcurl_la-security.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='security.c' object='libcurl_la-security.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-security.lo `test -f 'security.c' || echo '$(srcdir)/'`security.c + +libcurl_la-curl_fnmatch.lo: curl_fnmatch.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_fnmatch.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_fnmatch.Tpo -c -o libcurl_la-curl_fnmatch.lo `test -f 'curl_fnmatch.c' || echo '$(srcdir)/'`curl_fnmatch.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_fnmatch.Tpo $(DEPDIR)/libcurl_la-curl_fnmatch.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_fnmatch.c' object='libcurl_la-curl_fnmatch.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_fnmatch.lo `test -f 'curl_fnmatch.c' || echo '$(srcdir)/'`curl_fnmatch.c + +libcurl_la-fileinfo.lo: fileinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-fileinfo.lo -MD -MP -MF $(DEPDIR)/libcurl_la-fileinfo.Tpo -c -o libcurl_la-fileinfo.lo `test -f 'fileinfo.c' || echo '$(srcdir)/'`fileinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-fileinfo.Tpo $(DEPDIR)/libcurl_la-fileinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fileinfo.c' object='libcurl_la-fileinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-fileinfo.lo `test -f 'fileinfo.c' || echo '$(srcdir)/'`fileinfo.c + +libcurl_la-ftplistparser.lo: ftplistparser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-ftplistparser.lo -MD -MP -MF $(DEPDIR)/libcurl_la-ftplistparser.Tpo -c -o libcurl_la-ftplistparser.lo `test -f 'ftplistparser.c' || echo '$(srcdir)/'`ftplistparser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-ftplistparser.Tpo $(DEPDIR)/libcurl_la-ftplistparser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftplistparser.c' object='libcurl_la-ftplistparser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-ftplistparser.lo `test -f 'ftplistparser.c' || echo '$(srcdir)/'`ftplistparser.c + +libcurl_la-wildcard.lo: wildcard.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-wildcard.lo -MD -MP -MF $(DEPDIR)/libcurl_la-wildcard.Tpo -c -o libcurl_la-wildcard.lo `test -f 'wildcard.c' || echo '$(srcdir)/'`wildcard.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-wildcard.Tpo $(DEPDIR)/libcurl_la-wildcard.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wildcard.c' object='libcurl_la-wildcard.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-wildcard.lo `test -f 'wildcard.c' || echo '$(srcdir)/'`wildcard.c + +libcurl_la-krb5.lo: krb5.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-krb5.lo -MD -MP -MF $(DEPDIR)/libcurl_la-krb5.Tpo -c -o libcurl_la-krb5.lo `test -f 'krb5.c' || echo '$(srcdir)/'`krb5.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-krb5.Tpo $(DEPDIR)/libcurl_la-krb5.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='krb5.c' object='libcurl_la-krb5.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-krb5.lo `test -f 'krb5.c' || echo '$(srcdir)/'`krb5.c + +libcurl_la-memdebug.lo: memdebug.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-memdebug.lo -MD -MP -MF $(DEPDIR)/libcurl_la-memdebug.Tpo -c -o libcurl_la-memdebug.lo `test -f 'memdebug.c' || echo '$(srcdir)/'`memdebug.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-memdebug.Tpo $(DEPDIR)/libcurl_la-memdebug.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='memdebug.c' object='libcurl_la-memdebug.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-memdebug.lo `test -f 'memdebug.c' || echo '$(srcdir)/'`memdebug.c + +libcurl_la-http_chunks.lo: http_chunks.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-http_chunks.lo -MD -MP -MF $(DEPDIR)/libcurl_la-http_chunks.Tpo -c -o libcurl_la-http_chunks.lo `test -f 'http_chunks.c' || echo '$(srcdir)/'`http_chunks.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-http_chunks.Tpo $(DEPDIR)/libcurl_la-http_chunks.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_chunks.c' object='libcurl_la-http_chunks.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-http_chunks.lo `test -f 'http_chunks.c' || echo '$(srcdir)/'`http_chunks.c + +libcurl_la-strtok.lo: strtok.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-strtok.lo -MD -MP -MF $(DEPDIR)/libcurl_la-strtok.Tpo -c -o libcurl_la-strtok.lo `test -f 'strtok.c' || echo '$(srcdir)/'`strtok.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-strtok.Tpo $(DEPDIR)/libcurl_la-strtok.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strtok.c' object='libcurl_la-strtok.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-strtok.lo `test -f 'strtok.c' || echo '$(srcdir)/'`strtok.c + +libcurl_la-connect.lo: connect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-connect.lo -MD -MP -MF $(DEPDIR)/libcurl_la-connect.Tpo -c -o libcurl_la-connect.lo `test -f 'connect.c' || echo '$(srcdir)/'`connect.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-connect.Tpo $(DEPDIR)/libcurl_la-connect.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='connect.c' object='libcurl_la-connect.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-connect.lo `test -f 'connect.c' || echo '$(srcdir)/'`connect.c + +libcurl_la-llist.lo: llist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-llist.lo -MD -MP -MF $(DEPDIR)/libcurl_la-llist.Tpo -c -o libcurl_la-llist.lo `test -f 'llist.c' || echo '$(srcdir)/'`llist.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-llist.Tpo $(DEPDIR)/libcurl_la-llist.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='llist.c' object='libcurl_la-llist.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-llist.lo `test -f 'llist.c' || echo '$(srcdir)/'`llist.c + +libcurl_la-hash.lo: hash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-hash.lo -MD -MP -MF $(DEPDIR)/libcurl_la-hash.Tpo -c -o libcurl_la-hash.lo `test -f 'hash.c' || echo '$(srcdir)/'`hash.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-hash.Tpo $(DEPDIR)/libcurl_la-hash.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hash.c' object='libcurl_la-hash.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-hash.lo `test -f 'hash.c' || echo '$(srcdir)/'`hash.c + +libcurl_la-multi.lo: multi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-multi.lo -MD -MP -MF $(DEPDIR)/libcurl_la-multi.Tpo -c -o libcurl_la-multi.lo `test -f 'multi.c' || echo '$(srcdir)/'`multi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-multi.Tpo $(DEPDIR)/libcurl_la-multi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='multi.c' object='libcurl_la-multi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-multi.lo `test -f 'multi.c' || echo '$(srcdir)/'`multi.c + +libcurl_la-content_encoding.lo: content_encoding.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-content_encoding.lo -MD -MP -MF $(DEPDIR)/libcurl_la-content_encoding.Tpo -c -o libcurl_la-content_encoding.lo `test -f 'content_encoding.c' || echo '$(srcdir)/'`content_encoding.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-content_encoding.Tpo $(DEPDIR)/libcurl_la-content_encoding.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='content_encoding.c' object='libcurl_la-content_encoding.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-content_encoding.lo `test -f 'content_encoding.c' || echo '$(srcdir)/'`content_encoding.c + +libcurl_la-share.lo: share.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-share.lo -MD -MP -MF $(DEPDIR)/libcurl_la-share.Tpo -c -o libcurl_la-share.lo `test -f 'share.c' || echo '$(srcdir)/'`share.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-share.Tpo $(DEPDIR)/libcurl_la-share.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='share.c' object='libcurl_la-share.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-share.lo `test -f 'share.c' || echo '$(srcdir)/'`share.c + +libcurl_la-http_digest.lo: http_digest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-http_digest.lo -MD -MP -MF $(DEPDIR)/libcurl_la-http_digest.Tpo -c -o libcurl_la-http_digest.lo `test -f 'http_digest.c' || echo '$(srcdir)/'`http_digest.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-http_digest.Tpo $(DEPDIR)/libcurl_la-http_digest.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_digest.c' object='libcurl_la-http_digest.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-http_digest.lo `test -f 'http_digest.c' || echo '$(srcdir)/'`http_digest.c + +libcurl_la-md4.lo: md4.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-md4.lo -MD -MP -MF $(DEPDIR)/libcurl_la-md4.Tpo -c -o libcurl_la-md4.lo `test -f 'md4.c' || echo '$(srcdir)/'`md4.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-md4.Tpo $(DEPDIR)/libcurl_la-md4.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md4.c' object='libcurl_la-md4.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-md4.lo `test -f 'md4.c' || echo '$(srcdir)/'`md4.c + +libcurl_la-md5.lo: md5.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-md5.lo -MD -MP -MF $(DEPDIR)/libcurl_la-md5.Tpo -c -o libcurl_la-md5.lo `test -f 'md5.c' || echo '$(srcdir)/'`md5.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-md5.Tpo $(DEPDIR)/libcurl_la-md5.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5.c' object='libcurl_la-md5.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-md5.lo `test -f 'md5.c' || echo '$(srcdir)/'`md5.c + +libcurl_la-http_negotiate.lo: http_negotiate.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-http_negotiate.lo -MD -MP -MF $(DEPDIR)/libcurl_la-http_negotiate.Tpo -c -o libcurl_la-http_negotiate.lo `test -f 'http_negotiate.c' || echo '$(srcdir)/'`http_negotiate.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-http_negotiate.Tpo $(DEPDIR)/libcurl_la-http_negotiate.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_negotiate.c' object='libcurl_la-http_negotiate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-http_negotiate.lo `test -f 'http_negotiate.c' || echo '$(srcdir)/'`http_negotiate.c + +libcurl_la-inet_pton.lo: inet_pton.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-inet_pton.lo -MD -MP -MF $(DEPDIR)/libcurl_la-inet_pton.Tpo -c -o libcurl_la-inet_pton.lo `test -f 'inet_pton.c' || echo '$(srcdir)/'`inet_pton.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-inet_pton.Tpo $(DEPDIR)/libcurl_la-inet_pton.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='inet_pton.c' object='libcurl_la-inet_pton.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-inet_pton.lo `test -f 'inet_pton.c' || echo '$(srcdir)/'`inet_pton.c + +libcurl_la-strtoofft.lo: strtoofft.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-strtoofft.lo -MD -MP -MF $(DEPDIR)/libcurl_la-strtoofft.Tpo -c -o libcurl_la-strtoofft.lo `test -f 'strtoofft.c' || echo '$(srcdir)/'`strtoofft.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-strtoofft.Tpo $(DEPDIR)/libcurl_la-strtoofft.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strtoofft.c' object='libcurl_la-strtoofft.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-strtoofft.lo `test -f 'strtoofft.c' || echo '$(srcdir)/'`strtoofft.c + +libcurl_la-strerror.lo: strerror.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-strerror.lo -MD -MP -MF $(DEPDIR)/libcurl_la-strerror.Tpo -c -o libcurl_la-strerror.lo `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-strerror.Tpo $(DEPDIR)/libcurl_la-strerror.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strerror.c' object='libcurl_la-strerror.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-strerror.lo `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c + +libcurl_la-amigaos.lo: amigaos.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-amigaos.lo -MD -MP -MF $(DEPDIR)/libcurl_la-amigaos.Tpo -c -o libcurl_la-amigaos.lo `test -f 'amigaos.c' || echo '$(srcdir)/'`amigaos.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-amigaos.Tpo $(DEPDIR)/libcurl_la-amigaos.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='amigaos.c' object='libcurl_la-amigaos.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-amigaos.lo `test -f 'amigaos.c' || echo '$(srcdir)/'`amigaos.c + +libcurl_la-hostasyn.lo: hostasyn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-hostasyn.lo -MD -MP -MF $(DEPDIR)/libcurl_la-hostasyn.Tpo -c -o libcurl_la-hostasyn.lo `test -f 'hostasyn.c' || echo '$(srcdir)/'`hostasyn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-hostasyn.Tpo $(DEPDIR)/libcurl_la-hostasyn.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hostasyn.c' object='libcurl_la-hostasyn.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-hostasyn.lo `test -f 'hostasyn.c' || echo '$(srcdir)/'`hostasyn.c + +libcurl_la-hostip4.lo: hostip4.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-hostip4.lo -MD -MP -MF $(DEPDIR)/libcurl_la-hostip4.Tpo -c -o libcurl_la-hostip4.lo `test -f 'hostip4.c' || echo '$(srcdir)/'`hostip4.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-hostip4.Tpo $(DEPDIR)/libcurl_la-hostip4.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hostip4.c' object='libcurl_la-hostip4.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-hostip4.lo `test -f 'hostip4.c' || echo '$(srcdir)/'`hostip4.c + +libcurl_la-hostip6.lo: hostip6.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-hostip6.lo -MD -MP -MF $(DEPDIR)/libcurl_la-hostip6.Tpo -c -o libcurl_la-hostip6.lo `test -f 'hostip6.c' || echo '$(srcdir)/'`hostip6.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-hostip6.Tpo $(DEPDIR)/libcurl_la-hostip6.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hostip6.c' object='libcurl_la-hostip6.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-hostip6.lo `test -f 'hostip6.c' || echo '$(srcdir)/'`hostip6.c + +libcurl_la-hostsyn.lo: hostsyn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-hostsyn.lo -MD -MP -MF $(DEPDIR)/libcurl_la-hostsyn.Tpo -c -o libcurl_la-hostsyn.lo `test -f 'hostsyn.c' || echo '$(srcdir)/'`hostsyn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-hostsyn.Tpo $(DEPDIR)/libcurl_la-hostsyn.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hostsyn.c' object='libcurl_la-hostsyn.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-hostsyn.lo `test -f 'hostsyn.c' || echo '$(srcdir)/'`hostsyn.c + +libcurl_la-inet_ntop.lo: inet_ntop.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-inet_ntop.lo -MD -MP -MF $(DEPDIR)/libcurl_la-inet_ntop.Tpo -c -o libcurl_la-inet_ntop.lo `test -f 'inet_ntop.c' || echo '$(srcdir)/'`inet_ntop.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-inet_ntop.Tpo $(DEPDIR)/libcurl_la-inet_ntop.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='inet_ntop.c' object='libcurl_la-inet_ntop.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-inet_ntop.lo `test -f 'inet_ntop.c' || echo '$(srcdir)/'`inet_ntop.c + +libcurl_la-parsedate.lo: parsedate.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-parsedate.lo -MD -MP -MF $(DEPDIR)/libcurl_la-parsedate.Tpo -c -o libcurl_la-parsedate.lo `test -f 'parsedate.c' || echo '$(srcdir)/'`parsedate.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-parsedate.Tpo $(DEPDIR)/libcurl_la-parsedate.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='parsedate.c' object='libcurl_la-parsedate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-parsedate.lo `test -f 'parsedate.c' || echo '$(srcdir)/'`parsedate.c + +libcurl_la-select.lo: select.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-select.lo -MD -MP -MF $(DEPDIR)/libcurl_la-select.Tpo -c -o libcurl_la-select.lo `test -f 'select.c' || echo '$(srcdir)/'`select.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-select.Tpo $(DEPDIR)/libcurl_la-select.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='select.c' object='libcurl_la-select.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-select.lo `test -f 'select.c' || echo '$(srcdir)/'`select.c + +libcurl_la-tftp.lo: tftp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-tftp.lo -MD -MP -MF $(DEPDIR)/libcurl_la-tftp.Tpo -c -o libcurl_la-tftp.lo `test -f 'tftp.c' || echo '$(srcdir)/'`tftp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-tftp.Tpo $(DEPDIR)/libcurl_la-tftp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tftp.c' object='libcurl_la-tftp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-tftp.lo `test -f 'tftp.c' || echo '$(srcdir)/'`tftp.c + +libcurl_la-splay.lo: splay.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-splay.lo -MD -MP -MF $(DEPDIR)/libcurl_la-splay.Tpo -c -o libcurl_la-splay.lo `test -f 'splay.c' || echo '$(srcdir)/'`splay.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-splay.Tpo $(DEPDIR)/libcurl_la-splay.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='splay.c' object='libcurl_la-splay.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-splay.lo `test -f 'splay.c' || echo '$(srcdir)/'`splay.c + +libcurl_la-strdup.lo: strdup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-strdup.lo -MD -MP -MF $(DEPDIR)/libcurl_la-strdup.Tpo -c -o libcurl_la-strdup.lo `test -f 'strdup.c' || echo '$(srcdir)/'`strdup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-strdup.Tpo $(DEPDIR)/libcurl_la-strdup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strdup.c' object='libcurl_la-strdup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-strdup.lo `test -f 'strdup.c' || echo '$(srcdir)/'`strdup.c + +libcurl_la-socks.lo: socks.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-socks.lo -MD -MP -MF $(DEPDIR)/libcurl_la-socks.Tpo -c -o libcurl_la-socks.lo `test -f 'socks.c' || echo '$(srcdir)/'`socks.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-socks.Tpo $(DEPDIR)/libcurl_la-socks.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='socks.c' object='libcurl_la-socks.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-socks.lo `test -f 'socks.c' || echo '$(srcdir)/'`socks.c + +libcurl_la-ssh.lo: ssh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-ssh.lo -MD -MP -MF $(DEPDIR)/libcurl_la-ssh.Tpo -c -o libcurl_la-ssh.lo `test -f 'ssh.c' || echo '$(srcdir)/'`ssh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-ssh.Tpo $(DEPDIR)/libcurl_la-ssh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssh.c' object='libcurl_la-ssh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-ssh.lo `test -f 'ssh.c' || echo '$(srcdir)/'`ssh.c + +libcurl_la-ssh-libssh.lo: ssh-libssh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-ssh-libssh.lo -MD -MP -MF $(DEPDIR)/libcurl_la-ssh-libssh.Tpo -c -o libcurl_la-ssh-libssh.lo `test -f 'ssh-libssh.c' || echo '$(srcdir)/'`ssh-libssh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-ssh-libssh.Tpo $(DEPDIR)/libcurl_la-ssh-libssh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssh-libssh.c' object='libcurl_la-ssh-libssh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-ssh-libssh.lo `test -f 'ssh-libssh.c' || echo '$(srcdir)/'`ssh-libssh.c + +libcurl_la-curl_addrinfo.lo: curl_addrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_addrinfo.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_addrinfo.Tpo -c -o libcurl_la-curl_addrinfo.lo `test -f 'curl_addrinfo.c' || echo '$(srcdir)/'`curl_addrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_addrinfo.Tpo $(DEPDIR)/libcurl_la-curl_addrinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_addrinfo.c' object='libcurl_la-curl_addrinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_addrinfo.lo `test -f 'curl_addrinfo.c' || echo '$(srcdir)/'`curl_addrinfo.c + +libcurl_la-socks_gssapi.lo: socks_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-socks_gssapi.lo -MD -MP -MF $(DEPDIR)/libcurl_la-socks_gssapi.Tpo -c -o libcurl_la-socks_gssapi.lo `test -f 'socks_gssapi.c' || echo '$(srcdir)/'`socks_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-socks_gssapi.Tpo $(DEPDIR)/libcurl_la-socks_gssapi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='socks_gssapi.c' object='libcurl_la-socks_gssapi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-socks_gssapi.lo `test -f 'socks_gssapi.c' || echo '$(srcdir)/'`socks_gssapi.c + +libcurl_la-socks_sspi.lo: socks_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-socks_sspi.lo -MD -MP -MF $(DEPDIR)/libcurl_la-socks_sspi.Tpo -c -o libcurl_la-socks_sspi.lo `test -f 'socks_sspi.c' || echo '$(srcdir)/'`socks_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-socks_sspi.Tpo $(DEPDIR)/libcurl_la-socks_sspi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='socks_sspi.c' object='libcurl_la-socks_sspi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-socks_sspi.lo `test -f 'socks_sspi.c' || echo '$(srcdir)/'`socks_sspi.c + +libcurl_la-curl_sspi.lo: curl_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_sspi.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_sspi.Tpo -c -o libcurl_la-curl_sspi.lo `test -f 'curl_sspi.c' || echo '$(srcdir)/'`curl_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_sspi.Tpo $(DEPDIR)/libcurl_la-curl_sspi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_sspi.c' object='libcurl_la-curl_sspi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_sspi.lo `test -f 'curl_sspi.c' || echo '$(srcdir)/'`curl_sspi.c + +libcurl_la-slist.lo: slist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-slist.lo -MD -MP -MF $(DEPDIR)/libcurl_la-slist.Tpo -c -o libcurl_la-slist.lo `test -f 'slist.c' || echo '$(srcdir)/'`slist.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-slist.Tpo $(DEPDIR)/libcurl_la-slist.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slist.c' object='libcurl_la-slist.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-slist.lo `test -f 'slist.c' || echo '$(srcdir)/'`slist.c + +libcurl_la-nonblock.lo: nonblock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-nonblock.lo -MD -MP -MF $(DEPDIR)/libcurl_la-nonblock.Tpo -c -o libcurl_la-nonblock.lo `test -f 'nonblock.c' || echo '$(srcdir)/'`nonblock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-nonblock.Tpo $(DEPDIR)/libcurl_la-nonblock.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nonblock.c' object='libcurl_la-nonblock.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-nonblock.lo `test -f 'nonblock.c' || echo '$(srcdir)/'`nonblock.c + +libcurl_la-curl_memrchr.lo: curl_memrchr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_memrchr.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_memrchr.Tpo -c -o libcurl_la-curl_memrchr.lo `test -f 'curl_memrchr.c' || echo '$(srcdir)/'`curl_memrchr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_memrchr.Tpo $(DEPDIR)/libcurl_la-curl_memrchr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_memrchr.c' object='libcurl_la-curl_memrchr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_memrchr.lo `test -f 'curl_memrchr.c' || echo '$(srcdir)/'`curl_memrchr.c + +libcurl_la-imap.lo: imap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-imap.lo -MD -MP -MF $(DEPDIR)/libcurl_la-imap.Tpo -c -o libcurl_la-imap.lo `test -f 'imap.c' || echo '$(srcdir)/'`imap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-imap.Tpo $(DEPDIR)/libcurl_la-imap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imap.c' object='libcurl_la-imap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-imap.lo `test -f 'imap.c' || echo '$(srcdir)/'`imap.c + +libcurl_la-pop3.lo: pop3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-pop3.lo -MD -MP -MF $(DEPDIR)/libcurl_la-pop3.Tpo -c -o libcurl_la-pop3.lo `test -f 'pop3.c' || echo '$(srcdir)/'`pop3.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-pop3.Tpo $(DEPDIR)/libcurl_la-pop3.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pop3.c' object='libcurl_la-pop3.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-pop3.lo `test -f 'pop3.c' || echo '$(srcdir)/'`pop3.c + +libcurl_la-smtp.lo: smtp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-smtp.lo -MD -MP -MF $(DEPDIR)/libcurl_la-smtp.Tpo -c -o libcurl_la-smtp.lo `test -f 'smtp.c' || echo '$(srcdir)/'`smtp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-smtp.Tpo $(DEPDIR)/libcurl_la-smtp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smtp.c' object='libcurl_la-smtp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-smtp.lo `test -f 'smtp.c' || echo '$(srcdir)/'`smtp.c + +libcurl_la-pingpong.lo: pingpong.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-pingpong.lo -MD -MP -MF $(DEPDIR)/libcurl_la-pingpong.Tpo -c -o libcurl_la-pingpong.lo `test -f 'pingpong.c' || echo '$(srcdir)/'`pingpong.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-pingpong.Tpo $(DEPDIR)/libcurl_la-pingpong.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pingpong.c' object='libcurl_la-pingpong.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-pingpong.lo `test -f 'pingpong.c' || echo '$(srcdir)/'`pingpong.c + +libcurl_la-rtsp.lo: rtsp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-rtsp.lo -MD -MP -MF $(DEPDIR)/libcurl_la-rtsp.Tpo -c -o libcurl_la-rtsp.lo `test -f 'rtsp.c' || echo '$(srcdir)/'`rtsp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-rtsp.Tpo $(DEPDIR)/libcurl_la-rtsp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rtsp.c' object='libcurl_la-rtsp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-rtsp.lo `test -f 'rtsp.c' || echo '$(srcdir)/'`rtsp.c + +libcurl_la-curl_threads.lo: curl_threads.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_threads.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_threads.Tpo -c -o libcurl_la-curl_threads.lo `test -f 'curl_threads.c' || echo '$(srcdir)/'`curl_threads.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_threads.Tpo $(DEPDIR)/libcurl_la-curl_threads.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_threads.c' object='libcurl_la-curl_threads.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_threads.lo `test -f 'curl_threads.c' || echo '$(srcdir)/'`curl_threads.c + +libcurl_la-warnless.lo: warnless.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-warnless.lo -MD -MP -MF $(DEPDIR)/libcurl_la-warnless.Tpo -c -o libcurl_la-warnless.lo `test -f 'warnless.c' || echo '$(srcdir)/'`warnless.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-warnless.Tpo $(DEPDIR)/libcurl_la-warnless.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='warnless.c' object='libcurl_la-warnless.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-warnless.lo `test -f 'warnless.c' || echo '$(srcdir)/'`warnless.c + +libcurl_la-hmac.lo: hmac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-hmac.lo -MD -MP -MF $(DEPDIR)/libcurl_la-hmac.Tpo -c -o libcurl_la-hmac.lo `test -f 'hmac.c' || echo '$(srcdir)/'`hmac.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-hmac.Tpo $(DEPDIR)/libcurl_la-hmac.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hmac.c' object='libcurl_la-hmac.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-hmac.lo `test -f 'hmac.c' || echo '$(srcdir)/'`hmac.c + +libcurl_la-curl_rtmp.lo: curl_rtmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_rtmp.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_rtmp.Tpo -c -o libcurl_la-curl_rtmp.lo `test -f 'curl_rtmp.c' || echo '$(srcdir)/'`curl_rtmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_rtmp.Tpo $(DEPDIR)/libcurl_la-curl_rtmp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_rtmp.c' object='libcurl_la-curl_rtmp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_rtmp.lo `test -f 'curl_rtmp.c' || echo '$(srcdir)/'`curl_rtmp.c + +libcurl_la-openldap.lo: openldap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-openldap.lo -MD -MP -MF $(DEPDIR)/libcurl_la-openldap.Tpo -c -o libcurl_la-openldap.lo `test -f 'openldap.c' || echo '$(srcdir)/'`openldap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-openldap.Tpo $(DEPDIR)/libcurl_la-openldap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openldap.c' object='libcurl_la-openldap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-openldap.lo `test -f 'openldap.c' || echo '$(srcdir)/'`openldap.c + +libcurl_la-curl_gethostname.lo: curl_gethostname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_gethostname.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_gethostname.Tpo -c -o libcurl_la-curl_gethostname.lo `test -f 'curl_gethostname.c' || echo '$(srcdir)/'`curl_gethostname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_gethostname.Tpo $(DEPDIR)/libcurl_la-curl_gethostname.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_gethostname.c' object='libcurl_la-curl_gethostname.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_gethostname.lo `test -f 'curl_gethostname.c' || echo '$(srcdir)/'`curl_gethostname.c + +libcurl_la-gopher.lo: gopher.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-gopher.lo -MD -MP -MF $(DEPDIR)/libcurl_la-gopher.Tpo -c -o libcurl_la-gopher.lo `test -f 'gopher.c' || echo '$(srcdir)/'`gopher.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-gopher.Tpo $(DEPDIR)/libcurl_la-gopher.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gopher.c' object='libcurl_la-gopher.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-gopher.lo `test -f 'gopher.c' || echo '$(srcdir)/'`gopher.c + +libcurl_la-idn_win32.lo: idn_win32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-idn_win32.lo -MD -MP -MF $(DEPDIR)/libcurl_la-idn_win32.Tpo -c -o libcurl_la-idn_win32.lo `test -f 'idn_win32.c' || echo '$(srcdir)/'`idn_win32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-idn_win32.Tpo $(DEPDIR)/libcurl_la-idn_win32.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='idn_win32.c' object='libcurl_la-idn_win32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-idn_win32.lo `test -f 'idn_win32.c' || echo '$(srcdir)/'`idn_win32.c + +libcurl_la-http_proxy.lo: http_proxy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-http_proxy.lo -MD -MP -MF $(DEPDIR)/libcurl_la-http_proxy.Tpo -c -o libcurl_la-http_proxy.lo `test -f 'http_proxy.c' || echo '$(srcdir)/'`http_proxy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-http_proxy.Tpo $(DEPDIR)/libcurl_la-http_proxy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_proxy.c' object='libcurl_la-http_proxy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-http_proxy.lo `test -f 'http_proxy.c' || echo '$(srcdir)/'`http_proxy.c + +libcurl_la-non-ascii.lo: non-ascii.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-non-ascii.lo -MD -MP -MF $(DEPDIR)/libcurl_la-non-ascii.Tpo -c -o libcurl_la-non-ascii.lo `test -f 'non-ascii.c' || echo '$(srcdir)/'`non-ascii.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-non-ascii.Tpo $(DEPDIR)/libcurl_la-non-ascii.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='non-ascii.c' object='libcurl_la-non-ascii.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-non-ascii.lo `test -f 'non-ascii.c' || echo '$(srcdir)/'`non-ascii.c + +libcurl_la-asyn-ares.lo: asyn-ares.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-asyn-ares.lo -MD -MP -MF $(DEPDIR)/libcurl_la-asyn-ares.Tpo -c -o libcurl_la-asyn-ares.lo `test -f 'asyn-ares.c' || echo '$(srcdir)/'`asyn-ares.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-asyn-ares.Tpo $(DEPDIR)/libcurl_la-asyn-ares.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asyn-ares.c' object='libcurl_la-asyn-ares.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-asyn-ares.lo `test -f 'asyn-ares.c' || echo '$(srcdir)/'`asyn-ares.c + +libcurl_la-asyn-thread.lo: asyn-thread.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-asyn-thread.lo -MD -MP -MF $(DEPDIR)/libcurl_la-asyn-thread.Tpo -c -o libcurl_la-asyn-thread.lo `test -f 'asyn-thread.c' || echo '$(srcdir)/'`asyn-thread.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-asyn-thread.Tpo $(DEPDIR)/libcurl_la-asyn-thread.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asyn-thread.c' object='libcurl_la-asyn-thread.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-asyn-thread.lo `test -f 'asyn-thread.c' || echo '$(srcdir)/'`asyn-thread.c + +libcurl_la-curl_gssapi.lo: curl_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_gssapi.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_gssapi.Tpo -c -o libcurl_la-curl_gssapi.lo `test -f 'curl_gssapi.c' || echo '$(srcdir)/'`curl_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_gssapi.Tpo $(DEPDIR)/libcurl_la-curl_gssapi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_gssapi.c' object='libcurl_la-curl_gssapi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_gssapi.lo `test -f 'curl_gssapi.c' || echo '$(srcdir)/'`curl_gssapi.c + +libcurl_la-http_ntlm.lo: http_ntlm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-http_ntlm.lo -MD -MP -MF $(DEPDIR)/libcurl_la-http_ntlm.Tpo -c -o libcurl_la-http_ntlm.lo `test -f 'http_ntlm.c' || echo '$(srcdir)/'`http_ntlm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-http_ntlm.Tpo $(DEPDIR)/libcurl_la-http_ntlm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_ntlm.c' object='libcurl_la-http_ntlm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-http_ntlm.lo `test -f 'http_ntlm.c' || echo '$(srcdir)/'`http_ntlm.c + +libcurl_la-curl_ntlm_wb.lo: curl_ntlm_wb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_ntlm_wb.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_ntlm_wb.Tpo -c -o libcurl_la-curl_ntlm_wb.lo `test -f 'curl_ntlm_wb.c' || echo '$(srcdir)/'`curl_ntlm_wb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_ntlm_wb.Tpo $(DEPDIR)/libcurl_la-curl_ntlm_wb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_ntlm_wb.c' object='libcurl_la-curl_ntlm_wb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_ntlm_wb.lo `test -f 'curl_ntlm_wb.c' || echo '$(srcdir)/'`curl_ntlm_wb.c + +libcurl_la-curl_ntlm_core.lo: curl_ntlm_core.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_ntlm_core.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_ntlm_core.Tpo -c -o libcurl_la-curl_ntlm_core.lo `test -f 'curl_ntlm_core.c' || echo '$(srcdir)/'`curl_ntlm_core.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_ntlm_core.Tpo $(DEPDIR)/libcurl_la-curl_ntlm_core.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_ntlm_core.c' object='libcurl_la-curl_ntlm_core.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_ntlm_core.lo `test -f 'curl_ntlm_core.c' || echo '$(srcdir)/'`curl_ntlm_core.c + +libcurl_la-curl_sasl.lo: curl_sasl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_sasl.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_sasl.Tpo -c -o libcurl_la-curl_sasl.lo `test -f 'curl_sasl.c' || echo '$(srcdir)/'`curl_sasl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_sasl.Tpo $(DEPDIR)/libcurl_la-curl_sasl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_sasl.c' object='libcurl_la-curl_sasl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_sasl.lo `test -f 'curl_sasl.c' || echo '$(srcdir)/'`curl_sasl.c + +libcurl_la-rand.lo: rand.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-rand.lo -MD -MP -MF $(DEPDIR)/libcurl_la-rand.Tpo -c -o libcurl_la-rand.lo `test -f 'rand.c' || echo '$(srcdir)/'`rand.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-rand.Tpo $(DEPDIR)/libcurl_la-rand.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rand.c' object='libcurl_la-rand.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-rand.lo `test -f 'rand.c' || echo '$(srcdir)/'`rand.c + +libcurl_la-curl_multibyte.lo: curl_multibyte.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_multibyte.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_multibyte.Tpo -c -o libcurl_la-curl_multibyte.lo `test -f 'curl_multibyte.c' || echo '$(srcdir)/'`curl_multibyte.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_multibyte.Tpo $(DEPDIR)/libcurl_la-curl_multibyte.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_multibyte.c' object='libcurl_la-curl_multibyte.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_multibyte.lo `test -f 'curl_multibyte.c' || echo '$(srcdir)/'`curl_multibyte.c + +libcurl_la-hostcheck.lo: hostcheck.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-hostcheck.lo -MD -MP -MF $(DEPDIR)/libcurl_la-hostcheck.Tpo -c -o libcurl_la-hostcheck.lo `test -f 'hostcheck.c' || echo '$(srcdir)/'`hostcheck.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-hostcheck.Tpo $(DEPDIR)/libcurl_la-hostcheck.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hostcheck.c' object='libcurl_la-hostcheck.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-hostcheck.lo `test -f 'hostcheck.c' || echo '$(srcdir)/'`hostcheck.c + +libcurl_la-conncache.lo: conncache.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-conncache.lo -MD -MP -MF $(DEPDIR)/libcurl_la-conncache.Tpo -c -o libcurl_la-conncache.lo `test -f 'conncache.c' || echo '$(srcdir)/'`conncache.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-conncache.Tpo $(DEPDIR)/libcurl_la-conncache.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='conncache.c' object='libcurl_la-conncache.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-conncache.lo `test -f 'conncache.c' || echo '$(srcdir)/'`conncache.c + +libcurl_la-dotdot.lo: dotdot.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-dotdot.lo -MD -MP -MF $(DEPDIR)/libcurl_la-dotdot.Tpo -c -o libcurl_la-dotdot.lo `test -f 'dotdot.c' || echo '$(srcdir)/'`dotdot.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-dotdot.Tpo $(DEPDIR)/libcurl_la-dotdot.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dotdot.c' object='libcurl_la-dotdot.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-dotdot.lo `test -f 'dotdot.c' || echo '$(srcdir)/'`dotdot.c + +libcurl_la-x509asn1.lo: x509asn1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-x509asn1.lo -MD -MP -MF $(DEPDIR)/libcurl_la-x509asn1.Tpo -c -o libcurl_la-x509asn1.lo `test -f 'x509asn1.c' || echo '$(srcdir)/'`x509asn1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-x509asn1.Tpo $(DEPDIR)/libcurl_la-x509asn1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='x509asn1.c' object='libcurl_la-x509asn1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-x509asn1.lo `test -f 'x509asn1.c' || echo '$(srcdir)/'`x509asn1.c + +libcurl_la-http2.lo: http2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-http2.lo -MD -MP -MF $(DEPDIR)/libcurl_la-http2.Tpo -c -o libcurl_la-http2.lo `test -f 'http2.c' || echo '$(srcdir)/'`http2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-http2.Tpo $(DEPDIR)/libcurl_la-http2.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http2.c' object='libcurl_la-http2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-http2.lo `test -f 'http2.c' || echo '$(srcdir)/'`http2.c + +libcurl_la-smb.lo: smb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-smb.lo -MD -MP -MF $(DEPDIR)/libcurl_la-smb.Tpo -c -o libcurl_la-smb.lo `test -f 'smb.c' || echo '$(srcdir)/'`smb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-smb.Tpo $(DEPDIR)/libcurl_la-smb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smb.c' object='libcurl_la-smb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-smb.lo `test -f 'smb.c' || echo '$(srcdir)/'`smb.c + +libcurl_la-curl_endian.lo: curl_endian.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_endian.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_endian.Tpo -c -o libcurl_la-curl_endian.lo `test -f 'curl_endian.c' || echo '$(srcdir)/'`curl_endian.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_endian.Tpo $(DEPDIR)/libcurl_la-curl_endian.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_endian.c' object='libcurl_la-curl_endian.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_endian.lo `test -f 'curl_endian.c' || echo '$(srcdir)/'`curl_endian.c + +libcurl_la-curl_des.lo: curl_des.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_des.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_des.Tpo -c -o libcurl_la-curl_des.lo `test -f 'curl_des.c' || echo '$(srcdir)/'`curl_des.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_des.Tpo $(DEPDIR)/libcurl_la-curl_des.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_des.c' object='libcurl_la-curl_des.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_des.lo `test -f 'curl_des.c' || echo '$(srcdir)/'`curl_des.c + +libcurl_la-system_win32.lo: system_win32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-system_win32.lo -MD -MP -MF $(DEPDIR)/libcurl_la-system_win32.Tpo -c -o libcurl_la-system_win32.lo `test -f 'system_win32.c' || echo '$(srcdir)/'`system_win32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-system_win32.Tpo $(DEPDIR)/libcurl_la-system_win32.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='system_win32.c' object='libcurl_la-system_win32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-system_win32.lo `test -f 'system_win32.c' || echo '$(srcdir)/'`system_win32.c + +libcurl_la-mime.lo: mime.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-mime.lo -MD -MP -MF $(DEPDIR)/libcurl_la-mime.Tpo -c -o libcurl_la-mime.lo `test -f 'mime.c' || echo '$(srcdir)/'`mime.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-mime.Tpo $(DEPDIR)/libcurl_la-mime.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mime.c' object='libcurl_la-mime.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-mime.lo `test -f 'mime.c' || echo '$(srcdir)/'`mime.c + +libcurl_la-sha256.lo: sha256.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-sha256.lo -MD -MP -MF $(DEPDIR)/libcurl_la-sha256.Tpo -c -o libcurl_la-sha256.lo `test -f 'sha256.c' || echo '$(srcdir)/'`sha256.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-sha256.Tpo $(DEPDIR)/libcurl_la-sha256.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha256.c' object='libcurl_la-sha256.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-sha256.lo `test -f 'sha256.c' || echo '$(srcdir)/'`sha256.c + +libcurl_la-setopt.lo: setopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-setopt.lo -MD -MP -MF $(DEPDIR)/libcurl_la-setopt.Tpo -c -o libcurl_la-setopt.lo `test -f 'setopt.c' || echo '$(srcdir)/'`setopt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-setopt.Tpo $(DEPDIR)/libcurl_la-setopt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='setopt.c' object='libcurl_la-setopt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-setopt.lo `test -f 'setopt.c' || echo '$(srcdir)/'`setopt.c + +libcurl_la-curl_path.lo: curl_path.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_path.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_path.Tpo -c -o libcurl_la-curl_path.lo `test -f 'curl_path.c' || echo '$(srcdir)/'`curl_path.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_path.Tpo $(DEPDIR)/libcurl_la-curl_path.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_path.c' object='libcurl_la-curl_path.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_path.lo `test -f 'curl_path.c' || echo '$(srcdir)/'`curl_path.c + +libcurl_la-curl_ctype.lo: curl_ctype.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_ctype.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_ctype.Tpo -c -o libcurl_la-curl_ctype.lo `test -f 'curl_ctype.c' || echo '$(srcdir)/'`curl_ctype.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_ctype.Tpo $(DEPDIR)/libcurl_la-curl_ctype.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_ctype.c' object='libcurl_la-curl_ctype.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_ctype.lo `test -f 'curl_ctype.c' || echo '$(srcdir)/'`curl_ctype.c + +libcurl_la-curl_range.lo: curl_range.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_range.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_range.Tpo -c -o libcurl_la-curl_range.lo `test -f 'curl_range.c' || echo '$(srcdir)/'`curl_range.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_range.Tpo $(DEPDIR)/libcurl_la-curl_range.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_range.c' object='libcurl_la-curl_range.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_range.lo `test -f 'curl_range.c' || echo '$(srcdir)/'`curl_range.c + +libcurl_la-psl.lo: psl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-psl.lo -MD -MP -MF $(DEPDIR)/libcurl_la-psl.Tpo -c -o libcurl_la-psl.lo `test -f 'psl.c' || echo '$(srcdir)/'`psl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-psl.Tpo $(DEPDIR)/libcurl_la-psl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='psl.c' object='libcurl_la-psl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-psl.lo `test -f 'psl.c' || echo '$(srcdir)/'`psl.c + +libcurl_la-doh.lo: doh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-doh.lo -MD -MP -MF $(DEPDIR)/libcurl_la-doh.Tpo -c -o libcurl_la-doh.lo `test -f 'doh.c' || echo '$(srcdir)/'`doh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-doh.Tpo $(DEPDIR)/libcurl_la-doh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='doh.c' object='libcurl_la-doh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-doh.lo `test -f 'doh.c' || echo '$(srcdir)/'`doh.c + +libcurl_la-urlapi.lo: urlapi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-urlapi.lo -MD -MP -MF $(DEPDIR)/libcurl_la-urlapi.Tpo -c -o libcurl_la-urlapi.lo `test -f 'urlapi.c' || echo '$(srcdir)/'`urlapi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-urlapi.Tpo $(DEPDIR)/libcurl_la-urlapi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='urlapi.c' object='libcurl_la-urlapi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-urlapi.lo `test -f 'urlapi.c' || echo '$(srcdir)/'`urlapi.c + +libcurl_la-curl_get_line.lo: curl_get_line.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_get_line.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_get_line.Tpo -c -o libcurl_la-curl_get_line.lo `test -f 'curl_get_line.c' || echo '$(srcdir)/'`curl_get_line.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_get_line.Tpo $(DEPDIR)/libcurl_la-curl_get_line.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_get_line.c' object='libcurl_la-curl_get_line.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_get_line.lo `test -f 'curl_get_line.c' || echo '$(srcdir)/'`curl_get_line.c + +libcurl_la-altsvc.lo: altsvc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-altsvc.lo -MD -MP -MF $(DEPDIR)/libcurl_la-altsvc.Tpo -c -o libcurl_la-altsvc.lo `test -f 'altsvc.c' || echo '$(srcdir)/'`altsvc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-altsvc.Tpo $(DEPDIR)/libcurl_la-altsvc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='altsvc.c' object='libcurl_la-altsvc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-altsvc.lo `test -f 'altsvc.c' || echo '$(srcdir)/'`altsvc.c + +vauth/libcurl_la-vauth.lo: vauth/vauth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-vauth.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-vauth.Tpo -c -o vauth/libcurl_la-vauth.lo `test -f 'vauth/vauth.c' || echo '$(srcdir)/'`vauth/vauth.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-vauth.Tpo vauth/$(DEPDIR)/libcurl_la-vauth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/vauth.c' object='vauth/libcurl_la-vauth.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurl_la-vauth.lo `test -f 'vauth/vauth.c' || echo '$(srcdir)/'`vauth/vauth.c + +vauth/libcurl_la-cleartext.lo: vauth/cleartext.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-cleartext.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-cleartext.Tpo -c -o vauth/libcurl_la-cleartext.lo `test -f 'vauth/cleartext.c' || echo '$(srcdir)/'`vauth/cleartext.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-cleartext.Tpo vauth/$(DEPDIR)/libcurl_la-cleartext.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/cleartext.c' object='vauth/libcurl_la-cleartext.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurl_la-cleartext.lo `test -f 'vauth/cleartext.c' || echo '$(srcdir)/'`vauth/cleartext.c + +vauth/libcurl_la-cram.lo: vauth/cram.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-cram.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-cram.Tpo -c -o vauth/libcurl_la-cram.lo `test -f 'vauth/cram.c' || echo '$(srcdir)/'`vauth/cram.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-cram.Tpo vauth/$(DEPDIR)/libcurl_la-cram.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/cram.c' object='vauth/libcurl_la-cram.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurl_la-cram.lo `test -f 'vauth/cram.c' || echo '$(srcdir)/'`vauth/cram.c + +vauth/libcurl_la-digest.lo: vauth/digest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-digest.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-digest.Tpo -c -o vauth/libcurl_la-digest.lo `test -f 'vauth/digest.c' || echo '$(srcdir)/'`vauth/digest.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-digest.Tpo vauth/$(DEPDIR)/libcurl_la-digest.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/digest.c' object='vauth/libcurl_la-digest.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurl_la-digest.lo `test -f 'vauth/digest.c' || echo '$(srcdir)/'`vauth/digest.c + +vauth/libcurl_la-digest_sspi.lo: vauth/digest_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-digest_sspi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-digest_sspi.Tpo -c -o vauth/libcurl_la-digest_sspi.lo `test -f 'vauth/digest_sspi.c' || echo '$(srcdir)/'`vauth/digest_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-digest_sspi.Tpo vauth/$(DEPDIR)/libcurl_la-digest_sspi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/digest_sspi.c' object='vauth/libcurl_la-digest_sspi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurl_la-digest_sspi.lo `test -f 'vauth/digest_sspi.c' || echo '$(srcdir)/'`vauth/digest_sspi.c + +vauth/libcurl_la-krb5_gssapi.lo: vauth/krb5_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-krb5_gssapi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Tpo -c -o vauth/libcurl_la-krb5_gssapi.lo `test -f 'vauth/krb5_gssapi.c' || echo '$(srcdir)/'`vauth/krb5_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Tpo vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/krb5_gssapi.c' object='vauth/libcurl_la-krb5_gssapi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurl_la-krb5_gssapi.lo `test -f 'vauth/krb5_gssapi.c' || echo '$(srcdir)/'`vauth/krb5_gssapi.c + +vauth/libcurl_la-krb5_sspi.lo: vauth/krb5_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-krb5_sspi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-krb5_sspi.Tpo -c -o vauth/libcurl_la-krb5_sspi.lo `test -f 'vauth/krb5_sspi.c' || echo '$(srcdir)/'`vauth/krb5_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-krb5_sspi.Tpo vauth/$(DEPDIR)/libcurl_la-krb5_sspi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/krb5_sspi.c' object='vauth/libcurl_la-krb5_sspi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurl_la-krb5_sspi.lo `test -f 'vauth/krb5_sspi.c' || echo '$(srcdir)/'`vauth/krb5_sspi.c + +vauth/libcurl_la-ntlm.lo: vauth/ntlm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-ntlm.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-ntlm.Tpo -c -o vauth/libcurl_la-ntlm.lo `test -f 'vauth/ntlm.c' || echo '$(srcdir)/'`vauth/ntlm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-ntlm.Tpo vauth/$(DEPDIR)/libcurl_la-ntlm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/ntlm.c' object='vauth/libcurl_la-ntlm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurl_la-ntlm.lo `test -f 'vauth/ntlm.c' || echo '$(srcdir)/'`vauth/ntlm.c + +vauth/libcurl_la-ntlm_sspi.lo: vauth/ntlm_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-ntlm_sspi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-ntlm_sspi.Tpo -c -o vauth/libcurl_la-ntlm_sspi.lo `test -f 'vauth/ntlm_sspi.c' || echo '$(srcdir)/'`vauth/ntlm_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-ntlm_sspi.Tpo vauth/$(DEPDIR)/libcurl_la-ntlm_sspi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/ntlm_sspi.c' object='vauth/libcurl_la-ntlm_sspi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurl_la-ntlm_sspi.lo `test -f 'vauth/ntlm_sspi.c' || echo '$(srcdir)/'`vauth/ntlm_sspi.c + +vauth/libcurl_la-oauth2.lo: vauth/oauth2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-oauth2.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-oauth2.Tpo -c -o vauth/libcurl_la-oauth2.lo `test -f 'vauth/oauth2.c' || echo '$(srcdir)/'`vauth/oauth2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-oauth2.Tpo vauth/$(DEPDIR)/libcurl_la-oauth2.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/oauth2.c' object='vauth/libcurl_la-oauth2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurl_la-oauth2.lo `test -f 'vauth/oauth2.c' || echo '$(srcdir)/'`vauth/oauth2.c + +vauth/libcurl_la-spnego_gssapi.lo: vauth/spnego_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-spnego_gssapi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-spnego_gssapi.Tpo -c -o vauth/libcurl_la-spnego_gssapi.lo `test -f 'vauth/spnego_gssapi.c' || echo '$(srcdir)/'`vauth/spnego_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-spnego_gssapi.Tpo vauth/$(DEPDIR)/libcurl_la-spnego_gssapi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/spnego_gssapi.c' object='vauth/libcurl_la-spnego_gssapi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurl_la-spnego_gssapi.lo `test -f 'vauth/spnego_gssapi.c' || echo '$(srcdir)/'`vauth/spnego_gssapi.c + +vauth/libcurl_la-spnego_sspi.lo: vauth/spnego_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-spnego_sspi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-spnego_sspi.Tpo -c -o vauth/libcurl_la-spnego_sspi.lo `test -f 'vauth/spnego_sspi.c' || echo '$(srcdir)/'`vauth/spnego_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-spnego_sspi.Tpo vauth/$(DEPDIR)/libcurl_la-spnego_sspi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/spnego_sspi.c' object='vauth/libcurl_la-spnego_sspi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurl_la-spnego_sspi.lo `test -f 'vauth/spnego_sspi.c' || echo '$(srcdir)/'`vauth/spnego_sspi.c + +vtls/libcurl_la-openssl.lo: vtls/openssl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-openssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-openssl.Tpo -c -o vtls/libcurl_la-openssl.lo `test -f 'vtls/openssl.c' || echo '$(srcdir)/'`vtls/openssl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-openssl.Tpo vtls/$(DEPDIR)/libcurl_la-openssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/openssl.c' object='vtls/libcurl_la-openssl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-openssl.lo `test -f 'vtls/openssl.c' || echo '$(srcdir)/'`vtls/openssl.c + +vtls/libcurl_la-gtls.lo: vtls/gtls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-gtls.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-gtls.Tpo -c -o vtls/libcurl_la-gtls.lo `test -f 'vtls/gtls.c' || echo '$(srcdir)/'`vtls/gtls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-gtls.Tpo vtls/$(DEPDIR)/libcurl_la-gtls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/gtls.c' object='vtls/libcurl_la-gtls.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-gtls.lo `test -f 'vtls/gtls.c' || echo '$(srcdir)/'`vtls/gtls.c + +vtls/libcurl_la-vtls.lo: vtls/vtls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-vtls.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-vtls.Tpo -c -o vtls/libcurl_la-vtls.lo `test -f 'vtls/vtls.c' || echo '$(srcdir)/'`vtls/vtls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-vtls.Tpo vtls/$(DEPDIR)/libcurl_la-vtls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/vtls.c' object='vtls/libcurl_la-vtls.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-vtls.lo `test -f 'vtls/vtls.c' || echo '$(srcdir)/'`vtls/vtls.c + +vtls/libcurl_la-nss.lo: vtls/nss.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-nss.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-nss.Tpo -c -o vtls/libcurl_la-nss.lo `test -f 'vtls/nss.c' || echo '$(srcdir)/'`vtls/nss.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-nss.Tpo vtls/$(DEPDIR)/libcurl_la-nss.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/nss.c' object='vtls/libcurl_la-nss.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-nss.lo `test -f 'vtls/nss.c' || echo '$(srcdir)/'`vtls/nss.c + +vtls/libcurl_la-polarssl.lo: vtls/polarssl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-polarssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-polarssl.Tpo -c -o vtls/libcurl_la-polarssl.lo `test -f 'vtls/polarssl.c' || echo '$(srcdir)/'`vtls/polarssl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-polarssl.Tpo vtls/$(DEPDIR)/libcurl_la-polarssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/polarssl.c' object='vtls/libcurl_la-polarssl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-polarssl.lo `test -f 'vtls/polarssl.c' || echo '$(srcdir)/'`vtls/polarssl.c + +vtls/libcurl_la-polarssl_threadlock.lo: vtls/polarssl_threadlock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-polarssl_threadlock.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Tpo -c -o vtls/libcurl_la-polarssl_threadlock.lo `test -f 'vtls/polarssl_threadlock.c' || echo '$(srcdir)/'`vtls/polarssl_threadlock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Tpo vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/polarssl_threadlock.c' object='vtls/libcurl_la-polarssl_threadlock.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-polarssl_threadlock.lo `test -f 'vtls/polarssl_threadlock.c' || echo '$(srcdir)/'`vtls/polarssl_threadlock.c + +vtls/libcurl_la-wolfssl.lo: vtls/wolfssl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-wolfssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-wolfssl.Tpo -c -o vtls/libcurl_la-wolfssl.lo `test -f 'vtls/wolfssl.c' || echo '$(srcdir)/'`vtls/wolfssl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-wolfssl.Tpo vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/wolfssl.c' object='vtls/libcurl_la-wolfssl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-wolfssl.lo `test -f 'vtls/wolfssl.c' || echo '$(srcdir)/'`vtls/wolfssl.c + +vtls/libcurl_la-schannel.lo: vtls/schannel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-schannel.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-schannel.Tpo -c -o vtls/libcurl_la-schannel.lo `test -f 'vtls/schannel.c' || echo '$(srcdir)/'`vtls/schannel.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-schannel.Tpo vtls/$(DEPDIR)/libcurl_la-schannel.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/schannel.c' object='vtls/libcurl_la-schannel.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-schannel.lo `test -f 'vtls/schannel.c' || echo '$(srcdir)/'`vtls/schannel.c + +vtls/libcurl_la-schannel_verify.lo: vtls/schannel_verify.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-schannel_verify.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-schannel_verify.Tpo -c -o vtls/libcurl_la-schannel_verify.lo `test -f 'vtls/schannel_verify.c' || echo '$(srcdir)/'`vtls/schannel_verify.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-schannel_verify.Tpo vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/schannel_verify.c' object='vtls/libcurl_la-schannel_verify.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-schannel_verify.lo `test -f 'vtls/schannel_verify.c' || echo '$(srcdir)/'`vtls/schannel_verify.c + +vtls/libcurl_la-sectransp.lo: vtls/sectransp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-sectransp.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-sectransp.Tpo -c -o vtls/libcurl_la-sectransp.lo `test -f 'vtls/sectransp.c' || echo '$(srcdir)/'`vtls/sectransp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-sectransp.Tpo vtls/$(DEPDIR)/libcurl_la-sectransp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/sectransp.c' object='vtls/libcurl_la-sectransp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-sectransp.lo `test -f 'vtls/sectransp.c' || echo '$(srcdir)/'`vtls/sectransp.c + +vtls/libcurl_la-gskit.lo: vtls/gskit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-gskit.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-gskit.Tpo -c -o vtls/libcurl_la-gskit.lo `test -f 'vtls/gskit.c' || echo '$(srcdir)/'`vtls/gskit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-gskit.Tpo vtls/$(DEPDIR)/libcurl_la-gskit.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/gskit.c' object='vtls/libcurl_la-gskit.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-gskit.lo `test -f 'vtls/gskit.c' || echo '$(srcdir)/'`vtls/gskit.c + +vtls/libcurl_la-mbedtls.lo: vtls/mbedtls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-mbedtls.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-mbedtls.Tpo -c -o vtls/libcurl_la-mbedtls.lo `test -f 'vtls/mbedtls.c' || echo '$(srcdir)/'`vtls/mbedtls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-mbedtls.Tpo vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/mbedtls.c' object='vtls/libcurl_la-mbedtls.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-mbedtls.lo `test -f 'vtls/mbedtls.c' || echo '$(srcdir)/'`vtls/mbedtls.c + +vtls/libcurl_la-mesalink.lo: vtls/mesalink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-mesalink.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-mesalink.Tpo -c -o vtls/libcurl_la-mesalink.lo `test -f 'vtls/mesalink.c' || echo '$(srcdir)/'`vtls/mesalink.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-mesalink.Tpo vtls/$(DEPDIR)/libcurl_la-mesalink.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/mesalink.c' object='vtls/libcurl_la-mesalink.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-mesalink.lo `test -f 'vtls/mesalink.c' || echo '$(srcdir)/'`vtls/mesalink.c + +libcurlu_la-file.lo: file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-file.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-file.Tpo -c -o libcurlu_la-file.lo `test -f 'file.c' || echo '$(srcdir)/'`file.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-file.Tpo $(DEPDIR)/libcurlu_la-file.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='file.c' object='libcurlu_la-file.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-file.lo `test -f 'file.c' || echo '$(srcdir)/'`file.c + +libcurlu_la-timeval.lo: timeval.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-timeval.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-timeval.Tpo -c -o libcurlu_la-timeval.lo `test -f 'timeval.c' || echo '$(srcdir)/'`timeval.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-timeval.Tpo $(DEPDIR)/libcurlu_la-timeval.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='timeval.c' object='libcurlu_la-timeval.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-timeval.lo `test -f 'timeval.c' || echo '$(srcdir)/'`timeval.c + +libcurlu_la-base64.lo: base64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-base64.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-base64.Tpo -c -o libcurlu_la-base64.lo `test -f 'base64.c' || echo '$(srcdir)/'`base64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-base64.Tpo $(DEPDIR)/libcurlu_la-base64.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='libcurlu_la-base64.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-base64.lo `test -f 'base64.c' || echo '$(srcdir)/'`base64.c + +libcurlu_la-hostip.lo: hostip.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-hostip.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-hostip.Tpo -c -o libcurlu_la-hostip.lo `test -f 'hostip.c' || echo '$(srcdir)/'`hostip.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-hostip.Tpo $(DEPDIR)/libcurlu_la-hostip.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hostip.c' object='libcurlu_la-hostip.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-hostip.lo `test -f 'hostip.c' || echo '$(srcdir)/'`hostip.c + +libcurlu_la-progress.lo: progress.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-progress.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-progress.Tpo -c -o libcurlu_la-progress.lo `test -f 'progress.c' || echo '$(srcdir)/'`progress.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-progress.Tpo $(DEPDIR)/libcurlu_la-progress.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='progress.c' object='libcurlu_la-progress.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-progress.lo `test -f 'progress.c' || echo '$(srcdir)/'`progress.c + +libcurlu_la-formdata.lo: formdata.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-formdata.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-formdata.Tpo -c -o libcurlu_la-formdata.lo `test -f 'formdata.c' || echo '$(srcdir)/'`formdata.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-formdata.Tpo $(DEPDIR)/libcurlu_la-formdata.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='formdata.c' object='libcurlu_la-formdata.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-formdata.lo `test -f 'formdata.c' || echo '$(srcdir)/'`formdata.c + +libcurlu_la-cookie.lo: cookie.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-cookie.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-cookie.Tpo -c -o libcurlu_la-cookie.lo `test -f 'cookie.c' || echo '$(srcdir)/'`cookie.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-cookie.Tpo $(DEPDIR)/libcurlu_la-cookie.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cookie.c' object='libcurlu_la-cookie.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-cookie.lo `test -f 'cookie.c' || echo '$(srcdir)/'`cookie.c + +libcurlu_la-http.lo: http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-http.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-http.Tpo -c -o libcurlu_la-http.lo `test -f 'http.c' || echo '$(srcdir)/'`http.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-http.Tpo $(DEPDIR)/libcurlu_la-http.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='libcurlu_la-http.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-http.lo `test -f 'http.c' || echo '$(srcdir)/'`http.c + +libcurlu_la-sendf.lo: sendf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-sendf.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-sendf.Tpo -c -o libcurlu_la-sendf.lo `test -f 'sendf.c' || echo '$(srcdir)/'`sendf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-sendf.Tpo $(DEPDIR)/libcurlu_la-sendf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sendf.c' object='libcurlu_la-sendf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-sendf.lo `test -f 'sendf.c' || echo '$(srcdir)/'`sendf.c + +libcurlu_la-ftp.lo: ftp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-ftp.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-ftp.Tpo -c -o libcurlu_la-ftp.lo `test -f 'ftp.c' || echo '$(srcdir)/'`ftp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-ftp.Tpo $(DEPDIR)/libcurlu_la-ftp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftp.c' object='libcurlu_la-ftp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-ftp.lo `test -f 'ftp.c' || echo '$(srcdir)/'`ftp.c + +libcurlu_la-url.lo: url.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-url.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-url.Tpo -c -o libcurlu_la-url.lo `test -f 'url.c' || echo '$(srcdir)/'`url.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-url.Tpo $(DEPDIR)/libcurlu_la-url.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='url.c' object='libcurlu_la-url.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-url.lo `test -f 'url.c' || echo '$(srcdir)/'`url.c + +libcurlu_la-dict.lo: dict.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-dict.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-dict.Tpo -c -o libcurlu_la-dict.lo `test -f 'dict.c' || echo '$(srcdir)/'`dict.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-dict.Tpo $(DEPDIR)/libcurlu_la-dict.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dict.c' object='libcurlu_la-dict.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-dict.lo `test -f 'dict.c' || echo '$(srcdir)/'`dict.c + +libcurlu_la-if2ip.lo: if2ip.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-if2ip.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-if2ip.Tpo -c -o libcurlu_la-if2ip.lo `test -f 'if2ip.c' || echo '$(srcdir)/'`if2ip.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-if2ip.Tpo $(DEPDIR)/libcurlu_la-if2ip.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='if2ip.c' object='libcurlu_la-if2ip.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-if2ip.lo `test -f 'if2ip.c' || echo '$(srcdir)/'`if2ip.c + +libcurlu_la-speedcheck.lo: speedcheck.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-speedcheck.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-speedcheck.Tpo -c -o libcurlu_la-speedcheck.lo `test -f 'speedcheck.c' || echo '$(srcdir)/'`speedcheck.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-speedcheck.Tpo $(DEPDIR)/libcurlu_la-speedcheck.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='speedcheck.c' object='libcurlu_la-speedcheck.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-speedcheck.lo `test -f 'speedcheck.c' || echo '$(srcdir)/'`speedcheck.c + +libcurlu_la-ldap.lo: ldap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-ldap.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-ldap.Tpo -c -o libcurlu_la-ldap.lo `test -f 'ldap.c' || echo '$(srcdir)/'`ldap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-ldap.Tpo $(DEPDIR)/libcurlu_la-ldap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ldap.c' object='libcurlu_la-ldap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-ldap.lo `test -f 'ldap.c' || echo '$(srcdir)/'`ldap.c + +libcurlu_la-version.lo: version.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-version.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-version.Tpo -c -o libcurlu_la-version.lo `test -f 'version.c' || echo '$(srcdir)/'`version.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-version.Tpo $(DEPDIR)/libcurlu_la-version.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='version.c' object='libcurlu_la-version.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-version.lo `test -f 'version.c' || echo '$(srcdir)/'`version.c + +libcurlu_la-getenv.lo: getenv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-getenv.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-getenv.Tpo -c -o libcurlu_la-getenv.lo `test -f 'getenv.c' || echo '$(srcdir)/'`getenv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-getenv.Tpo $(DEPDIR)/libcurlu_la-getenv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getenv.c' object='libcurlu_la-getenv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-getenv.lo `test -f 'getenv.c' || echo '$(srcdir)/'`getenv.c + +libcurlu_la-escape.lo: escape.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-escape.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-escape.Tpo -c -o libcurlu_la-escape.lo `test -f 'escape.c' || echo '$(srcdir)/'`escape.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-escape.Tpo $(DEPDIR)/libcurlu_la-escape.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='escape.c' object='libcurlu_la-escape.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-escape.lo `test -f 'escape.c' || echo '$(srcdir)/'`escape.c + +libcurlu_la-mprintf.lo: mprintf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-mprintf.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-mprintf.Tpo -c -o libcurlu_la-mprintf.lo `test -f 'mprintf.c' || echo '$(srcdir)/'`mprintf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-mprintf.Tpo $(DEPDIR)/libcurlu_la-mprintf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mprintf.c' object='libcurlu_la-mprintf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-mprintf.lo `test -f 'mprintf.c' || echo '$(srcdir)/'`mprintf.c + +libcurlu_la-telnet.lo: telnet.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-telnet.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-telnet.Tpo -c -o libcurlu_la-telnet.lo `test -f 'telnet.c' || echo '$(srcdir)/'`telnet.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-telnet.Tpo $(DEPDIR)/libcurlu_la-telnet.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='telnet.c' object='libcurlu_la-telnet.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-telnet.lo `test -f 'telnet.c' || echo '$(srcdir)/'`telnet.c + +libcurlu_la-netrc.lo: netrc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-netrc.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-netrc.Tpo -c -o libcurlu_la-netrc.lo `test -f 'netrc.c' || echo '$(srcdir)/'`netrc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-netrc.Tpo $(DEPDIR)/libcurlu_la-netrc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netrc.c' object='libcurlu_la-netrc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-netrc.lo `test -f 'netrc.c' || echo '$(srcdir)/'`netrc.c + +libcurlu_la-getinfo.lo: getinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-getinfo.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-getinfo.Tpo -c -o libcurlu_la-getinfo.lo `test -f 'getinfo.c' || echo '$(srcdir)/'`getinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-getinfo.Tpo $(DEPDIR)/libcurlu_la-getinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getinfo.c' object='libcurlu_la-getinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-getinfo.lo `test -f 'getinfo.c' || echo '$(srcdir)/'`getinfo.c + +libcurlu_la-transfer.lo: transfer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-transfer.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-transfer.Tpo -c -o libcurlu_la-transfer.lo `test -f 'transfer.c' || echo '$(srcdir)/'`transfer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-transfer.Tpo $(DEPDIR)/libcurlu_la-transfer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='transfer.c' object='libcurlu_la-transfer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-transfer.lo `test -f 'transfer.c' || echo '$(srcdir)/'`transfer.c + +libcurlu_la-strcase.lo: strcase.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-strcase.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-strcase.Tpo -c -o libcurlu_la-strcase.lo `test -f 'strcase.c' || echo '$(srcdir)/'`strcase.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-strcase.Tpo $(DEPDIR)/libcurlu_la-strcase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strcase.c' object='libcurlu_la-strcase.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-strcase.lo `test -f 'strcase.c' || echo '$(srcdir)/'`strcase.c + +libcurlu_la-easy.lo: easy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-easy.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-easy.Tpo -c -o libcurlu_la-easy.lo `test -f 'easy.c' || echo '$(srcdir)/'`easy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-easy.Tpo $(DEPDIR)/libcurlu_la-easy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='easy.c' object='libcurlu_la-easy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-easy.lo `test -f 'easy.c' || echo '$(srcdir)/'`easy.c + +libcurlu_la-security.lo: security.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-security.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-security.Tpo -c -o libcurlu_la-security.lo `test -f 'security.c' || echo '$(srcdir)/'`security.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-security.Tpo $(DEPDIR)/libcurlu_la-security.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='security.c' object='libcurlu_la-security.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-security.lo `test -f 'security.c' || echo '$(srcdir)/'`security.c + +libcurlu_la-curl_fnmatch.lo: curl_fnmatch.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_fnmatch.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_fnmatch.Tpo -c -o libcurlu_la-curl_fnmatch.lo `test -f 'curl_fnmatch.c' || echo '$(srcdir)/'`curl_fnmatch.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_fnmatch.Tpo $(DEPDIR)/libcurlu_la-curl_fnmatch.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_fnmatch.c' object='libcurlu_la-curl_fnmatch.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_fnmatch.lo `test -f 'curl_fnmatch.c' || echo '$(srcdir)/'`curl_fnmatch.c + +libcurlu_la-fileinfo.lo: fileinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-fileinfo.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-fileinfo.Tpo -c -o libcurlu_la-fileinfo.lo `test -f 'fileinfo.c' || echo '$(srcdir)/'`fileinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-fileinfo.Tpo $(DEPDIR)/libcurlu_la-fileinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fileinfo.c' object='libcurlu_la-fileinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-fileinfo.lo `test -f 'fileinfo.c' || echo '$(srcdir)/'`fileinfo.c + +libcurlu_la-ftplistparser.lo: ftplistparser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-ftplistparser.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-ftplistparser.Tpo -c -o libcurlu_la-ftplistparser.lo `test -f 'ftplistparser.c' || echo '$(srcdir)/'`ftplistparser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-ftplistparser.Tpo $(DEPDIR)/libcurlu_la-ftplistparser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftplistparser.c' object='libcurlu_la-ftplistparser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-ftplistparser.lo `test -f 'ftplistparser.c' || echo '$(srcdir)/'`ftplistparser.c + +libcurlu_la-wildcard.lo: wildcard.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-wildcard.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-wildcard.Tpo -c -o libcurlu_la-wildcard.lo `test -f 'wildcard.c' || echo '$(srcdir)/'`wildcard.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-wildcard.Tpo $(DEPDIR)/libcurlu_la-wildcard.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wildcard.c' object='libcurlu_la-wildcard.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-wildcard.lo `test -f 'wildcard.c' || echo '$(srcdir)/'`wildcard.c + +libcurlu_la-krb5.lo: krb5.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-krb5.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-krb5.Tpo -c -o libcurlu_la-krb5.lo `test -f 'krb5.c' || echo '$(srcdir)/'`krb5.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-krb5.Tpo $(DEPDIR)/libcurlu_la-krb5.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='krb5.c' object='libcurlu_la-krb5.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-krb5.lo `test -f 'krb5.c' || echo '$(srcdir)/'`krb5.c + +libcurlu_la-memdebug.lo: memdebug.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-memdebug.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-memdebug.Tpo -c -o libcurlu_la-memdebug.lo `test -f 'memdebug.c' || echo '$(srcdir)/'`memdebug.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-memdebug.Tpo $(DEPDIR)/libcurlu_la-memdebug.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='memdebug.c' object='libcurlu_la-memdebug.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-memdebug.lo `test -f 'memdebug.c' || echo '$(srcdir)/'`memdebug.c + +libcurlu_la-http_chunks.lo: http_chunks.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-http_chunks.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-http_chunks.Tpo -c -o libcurlu_la-http_chunks.lo `test -f 'http_chunks.c' || echo '$(srcdir)/'`http_chunks.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-http_chunks.Tpo $(DEPDIR)/libcurlu_la-http_chunks.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_chunks.c' object='libcurlu_la-http_chunks.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-http_chunks.lo `test -f 'http_chunks.c' || echo '$(srcdir)/'`http_chunks.c + +libcurlu_la-strtok.lo: strtok.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-strtok.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-strtok.Tpo -c -o libcurlu_la-strtok.lo `test -f 'strtok.c' || echo '$(srcdir)/'`strtok.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-strtok.Tpo $(DEPDIR)/libcurlu_la-strtok.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strtok.c' object='libcurlu_la-strtok.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-strtok.lo `test -f 'strtok.c' || echo '$(srcdir)/'`strtok.c + +libcurlu_la-connect.lo: connect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-connect.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-connect.Tpo -c -o libcurlu_la-connect.lo `test -f 'connect.c' || echo '$(srcdir)/'`connect.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-connect.Tpo $(DEPDIR)/libcurlu_la-connect.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='connect.c' object='libcurlu_la-connect.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-connect.lo `test -f 'connect.c' || echo '$(srcdir)/'`connect.c + +libcurlu_la-llist.lo: llist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-llist.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-llist.Tpo -c -o libcurlu_la-llist.lo `test -f 'llist.c' || echo '$(srcdir)/'`llist.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-llist.Tpo $(DEPDIR)/libcurlu_la-llist.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='llist.c' object='libcurlu_la-llist.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-llist.lo `test -f 'llist.c' || echo '$(srcdir)/'`llist.c + +libcurlu_la-hash.lo: hash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-hash.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-hash.Tpo -c -o libcurlu_la-hash.lo `test -f 'hash.c' || echo '$(srcdir)/'`hash.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-hash.Tpo $(DEPDIR)/libcurlu_la-hash.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hash.c' object='libcurlu_la-hash.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-hash.lo `test -f 'hash.c' || echo '$(srcdir)/'`hash.c + +libcurlu_la-multi.lo: multi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-multi.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-multi.Tpo -c -o libcurlu_la-multi.lo `test -f 'multi.c' || echo '$(srcdir)/'`multi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-multi.Tpo $(DEPDIR)/libcurlu_la-multi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='multi.c' object='libcurlu_la-multi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-multi.lo `test -f 'multi.c' || echo '$(srcdir)/'`multi.c + +libcurlu_la-content_encoding.lo: content_encoding.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-content_encoding.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-content_encoding.Tpo -c -o libcurlu_la-content_encoding.lo `test -f 'content_encoding.c' || echo '$(srcdir)/'`content_encoding.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-content_encoding.Tpo $(DEPDIR)/libcurlu_la-content_encoding.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='content_encoding.c' object='libcurlu_la-content_encoding.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-content_encoding.lo `test -f 'content_encoding.c' || echo '$(srcdir)/'`content_encoding.c + +libcurlu_la-share.lo: share.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-share.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-share.Tpo -c -o libcurlu_la-share.lo `test -f 'share.c' || echo '$(srcdir)/'`share.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-share.Tpo $(DEPDIR)/libcurlu_la-share.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='share.c' object='libcurlu_la-share.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-share.lo `test -f 'share.c' || echo '$(srcdir)/'`share.c + +libcurlu_la-http_digest.lo: http_digest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-http_digest.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-http_digest.Tpo -c -o libcurlu_la-http_digest.lo `test -f 'http_digest.c' || echo '$(srcdir)/'`http_digest.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-http_digest.Tpo $(DEPDIR)/libcurlu_la-http_digest.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_digest.c' object='libcurlu_la-http_digest.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-http_digest.lo `test -f 'http_digest.c' || echo '$(srcdir)/'`http_digest.c + +libcurlu_la-md4.lo: md4.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-md4.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-md4.Tpo -c -o libcurlu_la-md4.lo `test -f 'md4.c' || echo '$(srcdir)/'`md4.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-md4.Tpo $(DEPDIR)/libcurlu_la-md4.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md4.c' object='libcurlu_la-md4.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-md4.lo `test -f 'md4.c' || echo '$(srcdir)/'`md4.c + +libcurlu_la-md5.lo: md5.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-md5.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-md5.Tpo -c -o libcurlu_la-md5.lo `test -f 'md5.c' || echo '$(srcdir)/'`md5.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-md5.Tpo $(DEPDIR)/libcurlu_la-md5.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5.c' object='libcurlu_la-md5.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-md5.lo `test -f 'md5.c' || echo '$(srcdir)/'`md5.c + +libcurlu_la-http_negotiate.lo: http_negotiate.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-http_negotiate.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-http_negotiate.Tpo -c -o libcurlu_la-http_negotiate.lo `test -f 'http_negotiate.c' || echo '$(srcdir)/'`http_negotiate.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-http_negotiate.Tpo $(DEPDIR)/libcurlu_la-http_negotiate.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_negotiate.c' object='libcurlu_la-http_negotiate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-http_negotiate.lo `test -f 'http_negotiate.c' || echo '$(srcdir)/'`http_negotiate.c + +libcurlu_la-inet_pton.lo: inet_pton.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-inet_pton.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-inet_pton.Tpo -c -o libcurlu_la-inet_pton.lo `test -f 'inet_pton.c' || echo '$(srcdir)/'`inet_pton.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-inet_pton.Tpo $(DEPDIR)/libcurlu_la-inet_pton.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='inet_pton.c' object='libcurlu_la-inet_pton.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-inet_pton.lo `test -f 'inet_pton.c' || echo '$(srcdir)/'`inet_pton.c + +libcurlu_la-strtoofft.lo: strtoofft.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-strtoofft.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-strtoofft.Tpo -c -o libcurlu_la-strtoofft.lo `test -f 'strtoofft.c' || echo '$(srcdir)/'`strtoofft.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-strtoofft.Tpo $(DEPDIR)/libcurlu_la-strtoofft.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strtoofft.c' object='libcurlu_la-strtoofft.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-strtoofft.lo `test -f 'strtoofft.c' || echo '$(srcdir)/'`strtoofft.c + +libcurlu_la-strerror.lo: strerror.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-strerror.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-strerror.Tpo -c -o libcurlu_la-strerror.lo `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-strerror.Tpo $(DEPDIR)/libcurlu_la-strerror.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strerror.c' object='libcurlu_la-strerror.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-strerror.lo `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c + +libcurlu_la-amigaos.lo: amigaos.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-amigaos.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-amigaos.Tpo -c -o libcurlu_la-amigaos.lo `test -f 'amigaos.c' || echo '$(srcdir)/'`amigaos.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-amigaos.Tpo $(DEPDIR)/libcurlu_la-amigaos.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='amigaos.c' object='libcurlu_la-amigaos.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-amigaos.lo `test -f 'amigaos.c' || echo '$(srcdir)/'`amigaos.c + +libcurlu_la-hostasyn.lo: hostasyn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-hostasyn.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-hostasyn.Tpo -c -o libcurlu_la-hostasyn.lo `test -f 'hostasyn.c' || echo '$(srcdir)/'`hostasyn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-hostasyn.Tpo $(DEPDIR)/libcurlu_la-hostasyn.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hostasyn.c' object='libcurlu_la-hostasyn.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-hostasyn.lo `test -f 'hostasyn.c' || echo '$(srcdir)/'`hostasyn.c + +libcurlu_la-hostip4.lo: hostip4.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-hostip4.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-hostip4.Tpo -c -o libcurlu_la-hostip4.lo `test -f 'hostip4.c' || echo '$(srcdir)/'`hostip4.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-hostip4.Tpo $(DEPDIR)/libcurlu_la-hostip4.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hostip4.c' object='libcurlu_la-hostip4.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-hostip4.lo `test -f 'hostip4.c' || echo '$(srcdir)/'`hostip4.c + +libcurlu_la-hostip6.lo: hostip6.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-hostip6.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-hostip6.Tpo -c -o libcurlu_la-hostip6.lo `test -f 'hostip6.c' || echo '$(srcdir)/'`hostip6.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-hostip6.Tpo $(DEPDIR)/libcurlu_la-hostip6.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hostip6.c' object='libcurlu_la-hostip6.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-hostip6.lo `test -f 'hostip6.c' || echo '$(srcdir)/'`hostip6.c + +libcurlu_la-hostsyn.lo: hostsyn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-hostsyn.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-hostsyn.Tpo -c -o libcurlu_la-hostsyn.lo `test -f 'hostsyn.c' || echo '$(srcdir)/'`hostsyn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-hostsyn.Tpo $(DEPDIR)/libcurlu_la-hostsyn.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hostsyn.c' object='libcurlu_la-hostsyn.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-hostsyn.lo `test -f 'hostsyn.c' || echo '$(srcdir)/'`hostsyn.c + +libcurlu_la-inet_ntop.lo: inet_ntop.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-inet_ntop.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-inet_ntop.Tpo -c -o libcurlu_la-inet_ntop.lo `test -f 'inet_ntop.c' || echo '$(srcdir)/'`inet_ntop.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-inet_ntop.Tpo $(DEPDIR)/libcurlu_la-inet_ntop.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='inet_ntop.c' object='libcurlu_la-inet_ntop.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-inet_ntop.lo `test -f 'inet_ntop.c' || echo '$(srcdir)/'`inet_ntop.c + +libcurlu_la-parsedate.lo: parsedate.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-parsedate.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-parsedate.Tpo -c -o libcurlu_la-parsedate.lo `test -f 'parsedate.c' || echo '$(srcdir)/'`parsedate.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-parsedate.Tpo $(DEPDIR)/libcurlu_la-parsedate.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='parsedate.c' object='libcurlu_la-parsedate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-parsedate.lo `test -f 'parsedate.c' || echo '$(srcdir)/'`parsedate.c + +libcurlu_la-select.lo: select.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-select.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-select.Tpo -c -o libcurlu_la-select.lo `test -f 'select.c' || echo '$(srcdir)/'`select.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-select.Tpo $(DEPDIR)/libcurlu_la-select.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='select.c' object='libcurlu_la-select.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-select.lo `test -f 'select.c' || echo '$(srcdir)/'`select.c + +libcurlu_la-tftp.lo: tftp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-tftp.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-tftp.Tpo -c -o libcurlu_la-tftp.lo `test -f 'tftp.c' || echo '$(srcdir)/'`tftp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-tftp.Tpo $(DEPDIR)/libcurlu_la-tftp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tftp.c' object='libcurlu_la-tftp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-tftp.lo `test -f 'tftp.c' || echo '$(srcdir)/'`tftp.c + +libcurlu_la-splay.lo: splay.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-splay.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-splay.Tpo -c -o libcurlu_la-splay.lo `test -f 'splay.c' || echo '$(srcdir)/'`splay.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-splay.Tpo $(DEPDIR)/libcurlu_la-splay.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='splay.c' object='libcurlu_la-splay.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-splay.lo `test -f 'splay.c' || echo '$(srcdir)/'`splay.c + +libcurlu_la-strdup.lo: strdup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-strdup.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-strdup.Tpo -c -o libcurlu_la-strdup.lo `test -f 'strdup.c' || echo '$(srcdir)/'`strdup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-strdup.Tpo $(DEPDIR)/libcurlu_la-strdup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strdup.c' object='libcurlu_la-strdup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-strdup.lo `test -f 'strdup.c' || echo '$(srcdir)/'`strdup.c + +libcurlu_la-socks.lo: socks.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-socks.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-socks.Tpo -c -o libcurlu_la-socks.lo `test -f 'socks.c' || echo '$(srcdir)/'`socks.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-socks.Tpo $(DEPDIR)/libcurlu_la-socks.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='socks.c' object='libcurlu_la-socks.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-socks.lo `test -f 'socks.c' || echo '$(srcdir)/'`socks.c + +libcurlu_la-ssh.lo: ssh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-ssh.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-ssh.Tpo -c -o libcurlu_la-ssh.lo `test -f 'ssh.c' || echo '$(srcdir)/'`ssh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-ssh.Tpo $(DEPDIR)/libcurlu_la-ssh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssh.c' object='libcurlu_la-ssh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-ssh.lo `test -f 'ssh.c' || echo '$(srcdir)/'`ssh.c + +libcurlu_la-ssh-libssh.lo: ssh-libssh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-ssh-libssh.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-ssh-libssh.Tpo -c -o libcurlu_la-ssh-libssh.lo `test -f 'ssh-libssh.c' || echo '$(srcdir)/'`ssh-libssh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-ssh-libssh.Tpo $(DEPDIR)/libcurlu_la-ssh-libssh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssh-libssh.c' object='libcurlu_la-ssh-libssh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-ssh-libssh.lo `test -f 'ssh-libssh.c' || echo '$(srcdir)/'`ssh-libssh.c + +libcurlu_la-curl_addrinfo.lo: curl_addrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_addrinfo.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_addrinfo.Tpo -c -o libcurlu_la-curl_addrinfo.lo `test -f 'curl_addrinfo.c' || echo '$(srcdir)/'`curl_addrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_addrinfo.Tpo $(DEPDIR)/libcurlu_la-curl_addrinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_addrinfo.c' object='libcurlu_la-curl_addrinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_addrinfo.lo `test -f 'curl_addrinfo.c' || echo '$(srcdir)/'`curl_addrinfo.c + +libcurlu_la-socks_gssapi.lo: socks_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-socks_gssapi.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-socks_gssapi.Tpo -c -o libcurlu_la-socks_gssapi.lo `test -f 'socks_gssapi.c' || echo '$(srcdir)/'`socks_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-socks_gssapi.Tpo $(DEPDIR)/libcurlu_la-socks_gssapi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='socks_gssapi.c' object='libcurlu_la-socks_gssapi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-socks_gssapi.lo `test -f 'socks_gssapi.c' || echo '$(srcdir)/'`socks_gssapi.c + +libcurlu_la-socks_sspi.lo: socks_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-socks_sspi.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-socks_sspi.Tpo -c -o libcurlu_la-socks_sspi.lo `test -f 'socks_sspi.c' || echo '$(srcdir)/'`socks_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-socks_sspi.Tpo $(DEPDIR)/libcurlu_la-socks_sspi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='socks_sspi.c' object='libcurlu_la-socks_sspi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-socks_sspi.lo `test -f 'socks_sspi.c' || echo '$(srcdir)/'`socks_sspi.c + +libcurlu_la-curl_sspi.lo: curl_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_sspi.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_sspi.Tpo -c -o libcurlu_la-curl_sspi.lo `test -f 'curl_sspi.c' || echo '$(srcdir)/'`curl_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_sspi.Tpo $(DEPDIR)/libcurlu_la-curl_sspi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_sspi.c' object='libcurlu_la-curl_sspi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_sspi.lo `test -f 'curl_sspi.c' || echo '$(srcdir)/'`curl_sspi.c + +libcurlu_la-slist.lo: slist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-slist.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-slist.Tpo -c -o libcurlu_la-slist.lo `test -f 'slist.c' || echo '$(srcdir)/'`slist.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-slist.Tpo $(DEPDIR)/libcurlu_la-slist.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slist.c' object='libcurlu_la-slist.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-slist.lo `test -f 'slist.c' || echo '$(srcdir)/'`slist.c + +libcurlu_la-nonblock.lo: nonblock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-nonblock.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-nonblock.Tpo -c -o libcurlu_la-nonblock.lo `test -f 'nonblock.c' || echo '$(srcdir)/'`nonblock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-nonblock.Tpo $(DEPDIR)/libcurlu_la-nonblock.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nonblock.c' object='libcurlu_la-nonblock.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-nonblock.lo `test -f 'nonblock.c' || echo '$(srcdir)/'`nonblock.c + +libcurlu_la-curl_memrchr.lo: curl_memrchr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_memrchr.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_memrchr.Tpo -c -o libcurlu_la-curl_memrchr.lo `test -f 'curl_memrchr.c' || echo '$(srcdir)/'`curl_memrchr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_memrchr.Tpo $(DEPDIR)/libcurlu_la-curl_memrchr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_memrchr.c' object='libcurlu_la-curl_memrchr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_memrchr.lo `test -f 'curl_memrchr.c' || echo '$(srcdir)/'`curl_memrchr.c + +libcurlu_la-imap.lo: imap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-imap.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-imap.Tpo -c -o libcurlu_la-imap.lo `test -f 'imap.c' || echo '$(srcdir)/'`imap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-imap.Tpo $(DEPDIR)/libcurlu_la-imap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imap.c' object='libcurlu_la-imap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-imap.lo `test -f 'imap.c' || echo '$(srcdir)/'`imap.c + +libcurlu_la-pop3.lo: pop3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-pop3.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-pop3.Tpo -c -o libcurlu_la-pop3.lo `test -f 'pop3.c' || echo '$(srcdir)/'`pop3.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-pop3.Tpo $(DEPDIR)/libcurlu_la-pop3.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pop3.c' object='libcurlu_la-pop3.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-pop3.lo `test -f 'pop3.c' || echo '$(srcdir)/'`pop3.c + +libcurlu_la-smtp.lo: smtp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-smtp.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-smtp.Tpo -c -o libcurlu_la-smtp.lo `test -f 'smtp.c' || echo '$(srcdir)/'`smtp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-smtp.Tpo $(DEPDIR)/libcurlu_la-smtp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smtp.c' object='libcurlu_la-smtp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-smtp.lo `test -f 'smtp.c' || echo '$(srcdir)/'`smtp.c + +libcurlu_la-pingpong.lo: pingpong.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-pingpong.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-pingpong.Tpo -c -o libcurlu_la-pingpong.lo `test -f 'pingpong.c' || echo '$(srcdir)/'`pingpong.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-pingpong.Tpo $(DEPDIR)/libcurlu_la-pingpong.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pingpong.c' object='libcurlu_la-pingpong.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-pingpong.lo `test -f 'pingpong.c' || echo '$(srcdir)/'`pingpong.c + +libcurlu_la-rtsp.lo: rtsp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-rtsp.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-rtsp.Tpo -c -o libcurlu_la-rtsp.lo `test -f 'rtsp.c' || echo '$(srcdir)/'`rtsp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-rtsp.Tpo $(DEPDIR)/libcurlu_la-rtsp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rtsp.c' object='libcurlu_la-rtsp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-rtsp.lo `test -f 'rtsp.c' || echo '$(srcdir)/'`rtsp.c + +libcurlu_la-curl_threads.lo: curl_threads.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_threads.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_threads.Tpo -c -o libcurlu_la-curl_threads.lo `test -f 'curl_threads.c' || echo '$(srcdir)/'`curl_threads.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_threads.Tpo $(DEPDIR)/libcurlu_la-curl_threads.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_threads.c' object='libcurlu_la-curl_threads.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_threads.lo `test -f 'curl_threads.c' || echo '$(srcdir)/'`curl_threads.c + +libcurlu_la-warnless.lo: warnless.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-warnless.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-warnless.Tpo -c -o libcurlu_la-warnless.lo `test -f 'warnless.c' || echo '$(srcdir)/'`warnless.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-warnless.Tpo $(DEPDIR)/libcurlu_la-warnless.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='warnless.c' object='libcurlu_la-warnless.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-warnless.lo `test -f 'warnless.c' || echo '$(srcdir)/'`warnless.c + +libcurlu_la-hmac.lo: hmac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-hmac.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-hmac.Tpo -c -o libcurlu_la-hmac.lo `test -f 'hmac.c' || echo '$(srcdir)/'`hmac.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-hmac.Tpo $(DEPDIR)/libcurlu_la-hmac.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hmac.c' object='libcurlu_la-hmac.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-hmac.lo `test -f 'hmac.c' || echo '$(srcdir)/'`hmac.c + +libcurlu_la-curl_rtmp.lo: curl_rtmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_rtmp.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_rtmp.Tpo -c -o libcurlu_la-curl_rtmp.lo `test -f 'curl_rtmp.c' || echo '$(srcdir)/'`curl_rtmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_rtmp.Tpo $(DEPDIR)/libcurlu_la-curl_rtmp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_rtmp.c' object='libcurlu_la-curl_rtmp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_rtmp.lo `test -f 'curl_rtmp.c' || echo '$(srcdir)/'`curl_rtmp.c + +libcurlu_la-openldap.lo: openldap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-openldap.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-openldap.Tpo -c -o libcurlu_la-openldap.lo `test -f 'openldap.c' || echo '$(srcdir)/'`openldap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-openldap.Tpo $(DEPDIR)/libcurlu_la-openldap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openldap.c' object='libcurlu_la-openldap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-openldap.lo `test -f 'openldap.c' || echo '$(srcdir)/'`openldap.c + +libcurlu_la-curl_gethostname.lo: curl_gethostname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_gethostname.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_gethostname.Tpo -c -o libcurlu_la-curl_gethostname.lo `test -f 'curl_gethostname.c' || echo '$(srcdir)/'`curl_gethostname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_gethostname.Tpo $(DEPDIR)/libcurlu_la-curl_gethostname.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_gethostname.c' object='libcurlu_la-curl_gethostname.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_gethostname.lo `test -f 'curl_gethostname.c' || echo '$(srcdir)/'`curl_gethostname.c + +libcurlu_la-gopher.lo: gopher.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-gopher.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-gopher.Tpo -c -o libcurlu_la-gopher.lo `test -f 'gopher.c' || echo '$(srcdir)/'`gopher.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-gopher.Tpo $(DEPDIR)/libcurlu_la-gopher.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gopher.c' object='libcurlu_la-gopher.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-gopher.lo `test -f 'gopher.c' || echo '$(srcdir)/'`gopher.c + +libcurlu_la-idn_win32.lo: idn_win32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-idn_win32.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-idn_win32.Tpo -c -o libcurlu_la-idn_win32.lo `test -f 'idn_win32.c' || echo '$(srcdir)/'`idn_win32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-idn_win32.Tpo $(DEPDIR)/libcurlu_la-idn_win32.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='idn_win32.c' object='libcurlu_la-idn_win32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-idn_win32.lo `test -f 'idn_win32.c' || echo '$(srcdir)/'`idn_win32.c + +libcurlu_la-http_proxy.lo: http_proxy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-http_proxy.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-http_proxy.Tpo -c -o libcurlu_la-http_proxy.lo `test -f 'http_proxy.c' || echo '$(srcdir)/'`http_proxy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-http_proxy.Tpo $(DEPDIR)/libcurlu_la-http_proxy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_proxy.c' object='libcurlu_la-http_proxy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-http_proxy.lo `test -f 'http_proxy.c' || echo '$(srcdir)/'`http_proxy.c + +libcurlu_la-non-ascii.lo: non-ascii.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-non-ascii.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-non-ascii.Tpo -c -o libcurlu_la-non-ascii.lo `test -f 'non-ascii.c' || echo '$(srcdir)/'`non-ascii.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-non-ascii.Tpo $(DEPDIR)/libcurlu_la-non-ascii.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='non-ascii.c' object='libcurlu_la-non-ascii.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-non-ascii.lo `test -f 'non-ascii.c' || echo '$(srcdir)/'`non-ascii.c + +libcurlu_la-asyn-ares.lo: asyn-ares.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-asyn-ares.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-asyn-ares.Tpo -c -o libcurlu_la-asyn-ares.lo `test -f 'asyn-ares.c' || echo '$(srcdir)/'`asyn-ares.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-asyn-ares.Tpo $(DEPDIR)/libcurlu_la-asyn-ares.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asyn-ares.c' object='libcurlu_la-asyn-ares.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-asyn-ares.lo `test -f 'asyn-ares.c' || echo '$(srcdir)/'`asyn-ares.c + +libcurlu_la-asyn-thread.lo: asyn-thread.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-asyn-thread.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-asyn-thread.Tpo -c -o libcurlu_la-asyn-thread.lo `test -f 'asyn-thread.c' || echo '$(srcdir)/'`asyn-thread.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-asyn-thread.Tpo $(DEPDIR)/libcurlu_la-asyn-thread.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asyn-thread.c' object='libcurlu_la-asyn-thread.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-asyn-thread.lo `test -f 'asyn-thread.c' || echo '$(srcdir)/'`asyn-thread.c + +libcurlu_la-curl_gssapi.lo: curl_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_gssapi.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_gssapi.Tpo -c -o libcurlu_la-curl_gssapi.lo `test -f 'curl_gssapi.c' || echo '$(srcdir)/'`curl_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_gssapi.Tpo $(DEPDIR)/libcurlu_la-curl_gssapi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_gssapi.c' object='libcurlu_la-curl_gssapi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_gssapi.lo `test -f 'curl_gssapi.c' || echo '$(srcdir)/'`curl_gssapi.c + +libcurlu_la-http_ntlm.lo: http_ntlm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-http_ntlm.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-http_ntlm.Tpo -c -o libcurlu_la-http_ntlm.lo `test -f 'http_ntlm.c' || echo '$(srcdir)/'`http_ntlm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-http_ntlm.Tpo $(DEPDIR)/libcurlu_la-http_ntlm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_ntlm.c' object='libcurlu_la-http_ntlm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-http_ntlm.lo `test -f 'http_ntlm.c' || echo '$(srcdir)/'`http_ntlm.c + +libcurlu_la-curl_ntlm_wb.lo: curl_ntlm_wb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_ntlm_wb.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_ntlm_wb.Tpo -c -o libcurlu_la-curl_ntlm_wb.lo `test -f 'curl_ntlm_wb.c' || echo '$(srcdir)/'`curl_ntlm_wb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_ntlm_wb.Tpo $(DEPDIR)/libcurlu_la-curl_ntlm_wb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_ntlm_wb.c' object='libcurlu_la-curl_ntlm_wb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_ntlm_wb.lo `test -f 'curl_ntlm_wb.c' || echo '$(srcdir)/'`curl_ntlm_wb.c + +libcurlu_la-curl_ntlm_core.lo: curl_ntlm_core.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_ntlm_core.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_ntlm_core.Tpo -c -o libcurlu_la-curl_ntlm_core.lo `test -f 'curl_ntlm_core.c' || echo '$(srcdir)/'`curl_ntlm_core.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_ntlm_core.Tpo $(DEPDIR)/libcurlu_la-curl_ntlm_core.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_ntlm_core.c' object='libcurlu_la-curl_ntlm_core.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_ntlm_core.lo `test -f 'curl_ntlm_core.c' || echo '$(srcdir)/'`curl_ntlm_core.c + +libcurlu_la-curl_sasl.lo: curl_sasl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_sasl.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_sasl.Tpo -c -o libcurlu_la-curl_sasl.lo `test -f 'curl_sasl.c' || echo '$(srcdir)/'`curl_sasl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_sasl.Tpo $(DEPDIR)/libcurlu_la-curl_sasl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_sasl.c' object='libcurlu_la-curl_sasl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_sasl.lo `test -f 'curl_sasl.c' || echo '$(srcdir)/'`curl_sasl.c + +libcurlu_la-rand.lo: rand.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-rand.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-rand.Tpo -c -o libcurlu_la-rand.lo `test -f 'rand.c' || echo '$(srcdir)/'`rand.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-rand.Tpo $(DEPDIR)/libcurlu_la-rand.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rand.c' object='libcurlu_la-rand.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-rand.lo `test -f 'rand.c' || echo '$(srcdir)/'`rand.c + +libcurlu_la-curl_multibyte.lo: curl_multibyte.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_multibyte.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_multibyte.Tpo -c -o libcurlu_la-curl_multibyte.lo `test -f 'curl_multibyte.c' || echo '$(srcdir)/'`curl_multibyte.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_multibyte.Tpo $(DEPDIR)/libcurlu_la-curl_multibyte.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_multibyte.c' object='libcurlu_la-curl_multibyte.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_multibyte.lo `test -f 'curl_multibyte.c' || echo '$(srcdir)/'`curl_multibyte.c + +libcurlu_la-hostcheck.lo: hostcheck.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-hostcheck.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-hostcheck.Tpo -c -o libcurlu_la-hostcheck.lo `test -f 'hostcheck.c' || echo '$(srcdir)/'`hostcheck.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-hostcheck.Tpo $(DEPDIR)/libcurlu_la-hostcheck.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hostcheck.c' object='libcurlu_la-hostcheck.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-hostcheck.lo `test -f 'hostcheck.c' || echo '$(srcdir)/'`hostcheck.c + +libcurlu_la-conncache.lo: conncache.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-conncache.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-conncache.Tpo -c -o libcurlu_la-conncache.lo `test -f 'conncache.c' || echo '$(srcdir)/'`conncache.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-conncache.Tpo $(DEPDIR)/libcurlu_la-conncache.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='conncache.c' object='libcurlu_la-conncache.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-conncache.lo `test -f 'conncache.c' || echo '$(srcdir)/'`conncache.c + +libcurlu_la-dotdot.lo: dotdot.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-dotdot.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-dotdot.Tpo -c -o libcurlu_la-dotdot.lo `test -f 'dotdot.c' || echo '$(srcdir)/'`dotdot.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-dotdot.Tpo $(DEPDIR)/libcurlu_la-dotdot.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dotdot.c' object='libcurlu_la-dotdot.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-dotdot.lo `test -f 'dotdot.c' || echo '$(srcdir)/'`dotdot.c + +libcurlu_la-x509asn1.lo: x509asn1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-x509asn1.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-x509asn1.Tpo -c -o libcurlu_la-x509asn1.lo `test -f 'x509asn1.c' || echo '$(srcdir)/'`x509asn1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-x509asn1.Tpo $(DEPDIR)/libcurlu_la-x509asn1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='x509asn1.c' object='libcurlu_la-x509asn1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-x509asn1.lo `test -f 'x509asn1.c' || echo '$(srcdir)/'`x509asn1.c + +libcurlu_la-http2.lo: http2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-http2.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-http2.Tpo -c -o libcurlu_la-http2.lo `test -f 'http2.c' || echo '$(srcdir)/'`http2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-http2.Tpo $(DEPDIR)/libcurlu_la-http2.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http2.c' object='libcurlu_la-http2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-http2.lo `test -f 'http2.c' || echo '$(srcdir)/'`http2.c + +libcurlu_la-smb.lo: smb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-smb.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-smb.Tpo -c -o libcurlu_la-smb.lo `test -f 'smb.c' || echo '$(srcdir)/'`smb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-smb.Tpo $(DEPDIR)/libcurlu_la-smb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smb.c' object='libcurlu_la-smb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-smb.lo `test -f 'smb.c' || echo '$(srcdir)/'`smb.c + +libcurlu_la-curl_endian.lo: curl_endian.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_endian.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_endian.Tpo -c -o libcurlu_la-curl_endian.lo `test -f 'curl_endian.c' || echo '$(srcdir)/'`curl_endian.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_endian.Tpo $(DEPDIR)/libcurlu_la-curl_endian.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_endian.c' object='libcurlu_la-curl_endian.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_endian.lo `test -f 'curl_endian.c' || echo '$(srcdir)/'`curl_endian.c + +libcurlu_la-curl_des.lo: curl_des.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_des.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_des.Tpo -c -o libcurlu_la-curl_des.lo `test -f 'curl_des.c' || echo '$(srcdir)/'`curl_des.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_des.Tpo $(DEPDIR)/libcurlu_la-curl_des.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_des.c' object='libcurlu_la-curl_des.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_des.lo `test -f 'curl_des.c' || echo '$(srcdir)/'`curl_des.c + +libcurlu_la-system_win32.lo: system_win32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-system_win32.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-system_win32.Tpo -c -o libcurlu_la-system_win32.lo `test -f 'system_win32.c' || echo '$(srcdir)/'`system_win32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-system_win32.Tpo $(DEPDIR)/libcurlu_la-system_win32.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='system_win32.c' object='libcurlu_la-system_win32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-system_win32.lo `test -f 'system_win32.c' || echo '$(srcdir)/'`system_win32.c + +libcurlu_la-mime.lo: mime.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-mime.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-mime.Tpo -c -o libcurlu_la-mime.lo `test -f 'mime.c' || echo '$(srcdir)/'`mime.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-mime.Tpo $(DEPDIR)/libcurlu_la-mime.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mime.c' object='libcurlu_la-mime.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-mime.lo `test -f 'mime.c' || echo '$(srcdir)/'`mime.c + +libcurlu_la-sha256.lo: sha256.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-sha256.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-sha256.Tpo -c -o libcurlu_la-sha256.lo `test -f 'sha256.c' || echo '$(srcdir)/'`sha256.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-sha256.Tpo $(DEPDIR)/libcurlu_la-sha256.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha256.c' object='libcurlu_la-sha256.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-sha256.lo `test -f 'sha256.c' || echo '$(srcdir)/'`sha256.c + +libcurlu_la-setopt.lo: setopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-setopt.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-setopt.Tpo -c -o libcurlu_la-setopt.lo `test -f 'setopt.c' || echo '$(srcdir)/'`setopt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-setopt.Tpo $(DEPDIR)/libcurlu_la-setopt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='setopt.c' object='libcurlu_la-setopt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-setopt.lo `test -f 'setopt.c' || echo '$(srcdir)/'`setopt.c + +libcurlu_la-curl_path.lo: curl_path.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_path.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_path.Tpo -c -o libcurlu_la-curl_path.lo `test -f 'curl_path.c' || echo '$(srcdir)/'`curl_path.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_path.Tpo $(DEPDIR)/libcurlu_la-curl_path.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_path.c' object='libcurlu_la-curl_path.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_path.lo `test -f 'curl_path.c' || echo '$(srcdir)/'`curl_path.c + +libcurlu_la-curl_ctype.lo: curl_ctype.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_ctype.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_ctype.Tpo -c -o libcurlu_la-curl_ctype.lo `test -f 'curl_ctype.c' || echo '$(srcdir)/'`curl_ctype.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_ctype.Tpo $(DEPDIR)/libcurlu_la-curl_ctype.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_ctype.c' object='libcurlu_la-curl_ctype.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_ctype.lo `test -f 'curl_ctype.c' || echo '$(srcdir)/'`curl_ctype.c + +libcurlu_la-curl_range.lo: curl_range.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_range.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_range.Tpo -c -o libcurlu_la-curl_range.lo `test -f 'curl_range.c' || echo '$(srcdir)/'`curl_range.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_range.Tpo $(DEPDIR)/libcurlu_la-curl_range.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_range.c' object='libcurlu_la-curl_range.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_range.lo `test -f 'curl_range.c' || echo '$(srcdir)/'`curl_range.c + +libcurlu_la-psl.lo: psl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-psl.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-psl.Tpo -c -o libcurlu_la-psl.lo `test -f 'psl.c' || echo '$(srcdir)/'`psl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-psl.Tpo $(DEPDIR)/libcurlu_la-psl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='psl.c' object='libcurlu_la-psl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-psl.lo `test -f 'psl.c' || echo '$(srcdir)/'`psl.c + +libcurlu_la-doh.lo: doh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-doh.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-doh.Tpo -c -o libcurlu_la-doh.lo `test -f 'doh.c' || echo '$(srcdir)/'`doh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-doh.Tpo $(DEPDIR)/libcurlu_la-doh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='doh.c' object='libcurlu_la-doh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-doh.lo `test -f 'doh.c' || echo '$(srcdir)/'`doh.c + +libcurlu_la-urlapi.lo: urlapi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-urlapi.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-urlapi.Tpo -c -o libcurlu_la-urlapi.lo `test -f 'urlapi.c' || echo '$(srcdir)/'`urlapi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-urlapi.Tpo $(DEPDIR)/libcurlu_la-urlapi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='urlapi.c' object='libcurlu_la-urlapi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-urlapi.lo `test -f 'urlapi.c' || echo '$(srcdir)/'`urlapi.c + +libcurlu_la-curl_get_line.lo: curl_get_line.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_get_line.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_get_line.Tpo -c -o libcurlu_la-curl_get_line.lo `test -f 'curl_get_line.c' || echo '$(srcdir)/'`curl_get_line.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_get_line.Tpo $(DEPDIR)/libcurlu_la-curl_get_line.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_get_line.c' object='libcurlu_la-curl_get_line.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_get_line.lo `test -f 'curl_get_line.c' || echo '$(srcdir)/'`curl_get_line.c + +libcurlu_la-altsvc.lo: altsvc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-altsvc.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-altsvc.Tpo -c -o libcurlu_la-altsvc.lo `test -f 'altsvc.c' || echo '$(srcdir)/'`altsvc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-altsvc.Tpo $(DEPDIR)/libcurlu_la-altsvc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='altsvc.c' object='libcurlu_la-altsvc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-altsvc.lo `test -f 'altsvc.c' || echo '$(srcdir)/'`altsvc.c + +vauth/libcurlu_la-vauth.lo: vauth/vauth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-vauth.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-vauth.Tpo -c -o vauth/libcurlu_la-vauth.lo `test -f 'vauth/vauth.c' || echo '$(srcdir)/'`vauth/vauth.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-vauth.Tpo vauth/$(DEPDIR)/libcurlu_la-vauth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/vauth.c' object='vauth/libcurlu_la-vauth.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurlu_la-vauth.lo `test -f 'vauth/vauth.c' || echo '$(srcdir)/'`vauth/vauth.c + +vauth/libcurlu_la-cleartext.lo: vauth/cleartext.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-cleartext.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-cleartext.Tpo -c -o vauth/libcurlu_la-cleartext.lo `test -f 'vauth/cleartext.c' || echo '$(srcdir)/'`vauth/cleartext.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-cleartext.Tpo vauth/$(DEPDIR)/libcurlu_la-cleartext.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/cleartext.c' object='vauth/libcurlu_la-cleartext.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurlu_la-cleartext.lo `test -f 'vauth/cleartext.c' || echo '$(srcdir)/'`vauth/cleartext.c + +vauth/libcurlu_la-cram.lo: vauth/cram.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-cram.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-cram.Tpo -c -o vauth/libcurlu_la-cram.lo `test -f 'vauth/cram.c' || echo '$(srcdir)/'`vauth/cram.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-cram.Tpo vauth/$(DEPDIR)/libcurlu_la-cram.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/cram.c' object='vauth/libcurlu_la-cram.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurlu_la-cram.lo `test -f 'vauth/cram.c' || echo '$(srcdir)/'`vauth/cram.c + +vauth/libcurlu_la-digest.lo: vauth/digest.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-digest.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-digest.Tpo -c -o vauth/libcurlu_la-digest.lo `test -f 'vauth/digest.c' || echo '$(srcdir)/'`vauth/digest.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-digest.Tpo vauth/$(DEPDIR)/libcurlu_la-digest.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/digest.c' object='vauth/libcurlu_la-digest.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurlu_la-digest.lo `test -f 'vauth/digest.c' || echo '$(srcdir)/'`vauth/digest.c + +vauth/libcurlu_la-digest_sspi.lo: vauth/digest_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-digest_sspi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-digest_sspi.Tpo -c -o vauth/libcurlu_la-digest_sspi.lo `test -f 'vauth/digest_sspi.c' || echo '$(srcdir)/'`vauth/digest_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-digest_sspi.Tpo vauth/$(DEPDIR)/libcurlu_la-digest_sspi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/digest_sspi.c' object='vauth/libcurlu_la-digest_sspi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurlu_la-digest_sspi.lo `test -f 'vauth/digest_sspi.c' || echo '$(srcdir)/'`vauth/digest_sspi.c + +vauth/libcurlu_la-krb5_gssapi.lo: vauth/krb5_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-krb5_gssapi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Tpo -c -o vauth/libcurlu_la-krb5_gssapi.lo `test -f 'vauth/krb5_gssapi.c' || echo '$(srcdir)/'`vauth/krb5_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Tpo vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/krb5_gssapi.c' object='vauth/libcurlu_la-krb5_gssapi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurlu_la-krb5_gssapi.lo `test -f 'vauth/krb5_gssapi.c' || echo '$(srcdir)/'`vauth/krb5_gssapi.c + +vauth/libcurlu_la-krb5_sspi.lo: vauth/krb5_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-krb5_sspi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-krb5_sspi.Tpo -c -o vauth/libcurlu_la-krb5_sspi.lo `test -f 'vauth/krb5_sspi.c' || echo '$(srcdir)/'`vauth/krb5_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-krb5_sspi.Tpo vauth/$(DEPDIR)/libcurlu_la-krb5_sspi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/krb5_sspi.c' object='vauth/libcurlu_la-krb5_sspi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurlu_la-krb5_sspi.lo `test -f 'vauth/krb5_sspi.c' || echo '$(srcdir)/'`vauth/krb5_sspi.c + +vauth/libcurlu_la-ntlm.lo: vauth/ntlm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-ntlm.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-ntlm.Tpo -c -o vauth/libcurlu_la-ntlm.lo `test -f 'vauth/ntlm.c' || echo '$(srcdir)/'`vauth/ntlm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-ntlm.Tpo vauth/$(DEPDIR)/libcurlu_la-ntlm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/ntlm.c' object='vauth/libcurlu_la-ntlm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurlu_la-ntlm.lo `test -f 'vauth/ntlm.c' || echo '$(srcdir)/'`vauth/ntlm.c + +vauth/libcurlu_la-ntlm_sspi.lo: vauth/ntlm_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-ntlm_sspi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-ntlm_sspi.Tpo -c -o vauth/libcurlu_la-ntlm_sspi.lo `test -f 'vauth/ntlm_sspi.c' || echo '$(srcdir)/'`vauth/ntlm_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-ntlm_sspi.Tpo vauth/$(DEPDIR)/libcurlu_la-ntlm_sspi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/ntlm_sspi.c' object='vauth/libcurlu_la-ntlm_sspi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurlu_la-ntlm_sspi.lo `test -f 'vauth/ntlm_sspi.c' || echo '$(srcdir)/'`vauth/ntlm_sspi.c + +vauth/libcurlu_la-oauth2.lo: vauth/oauth2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-oauth2.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-oauth2.Tpo -c -o vauth/libcurlu_la-oauth2.lo `test -f 'vauth/oauth2.c' || echo '$(srcdir)/'`vauth/oauth2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-oauth2.Tpo vauth/$(DEPDIR)/libcurlu_la-oauth2.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/oauth2.c' object='vauth/libcurlu_la-oauth2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurlu_la-oauth2.lo `test -f 'vauth/oauth2.c' || echo '$(srcdir)/'`vauth/oauth2.c + +vauth/libcurlu_la-spnego_gssapi.lo: vauth/spnego_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-spnego_gssapi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-spnego_gssapi.Tpo -c -o vauth/libcurlu_la-spnego_gssapi.lo `test -f 'vauth/spnego_gssapi.c' || echo '$(srcdir)/'`vauth/spnego_gssapi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-spnego_gssapi.Tpo vauth/$(DEPDIR)/libcurlu_la-spnego_gssapi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/spnego_gssapi.c' object='vauth/libcurlu_la-spnego_gssapi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurlu_la-spnego_gssapi.lo `test -f 'vauth/spnego_gssapi.c' || echo '$(srcdir)/'`vauth/spnego_gssapi.c + +vauth/libcurlu_la-spnego_sspi.lo: vauth/spnego_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-spnego_sspi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Tpo -c -o vauth/libcurlu_la-spnego_sspi.lo `test -f 'vauth/spnego_sspi.c' || echo '$(srcdir)/'`vauth/spnego_sspi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Tpo vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/spnego_sspi.c' object='vauth/libcurlu_la-spnego_sspi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vauth/libcurlu_la-spnego_sspi.lo `test -f 'vauth/spnego_sspi.c' || echo '$(srcdir)/'`vauth/spnego_sspi.c + +vtls/libcurlu_la-openssl.lo: vtls/openssl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-openssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-openssl.Tpo -c -o vtls/libcurlu_la-openssl.lo `test -f 'vtls/openssl.c' || echo '$(srcdir)/'`vtls/openssl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-openssl.Tpo vtls/$(DEPDIR)/libcurlu_la-openssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/openssl.c' object='vtls/libcurlu_la-openssl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-openssl.lo `test -f 'vtls/openssl.c' || echo '$(srcdir)/'`vtls/openssl.c + +vtls/libcurlu_la-gtls.lo: vtls/gtls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-gtls.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-gtls.Tpo -c -o vtls/libcurlu_la-gtls.lo `test -f 'vtls/gtls.c' || echo '$(srcdir)/'`vtls/gtls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-gtls.Tpo vtls/$(DEPDIR)/libcurlu_la-gtls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/gtls.c' object='vtls/libcurlu_la-gtls.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-gtls.lo `test -f 'vtls/gtls.c' || echo '$(srcdir)/'`vtls/gtls.c + +vtls/libcurlu_la-vtls.lo: vtls/vtls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-vtls.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-vtls.Tpo -c -o vtls/libcurlu_la-vtls.lo `test -f 'vtls/vtls.c' || echo '$(srcdir)/'`vtls/vtls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-vtls.Tpo vtls/$(DEPDIR)/libcurlu_la-vtls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/vtls.c' object='vtls/libcurlu_la-vtls.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-vtls.lo `test -f 'vtls/vtls.c' || echo '$(srcdir)/'`vtls/vtls.c + +vtls/libcurlu_la-nss.lo: vtls/nss.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-nss.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-nss.Tpo -c -o vtls/libcurlu_la-nss.lo `test -f 'vtls/nss.c' || echo '$(srcdir)/'`vtls/nss.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-nss.Tpo vtls/$(DEPDIR)/libcurlu_la-nss.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/nss.c' object='vtls/libcurlu_la-nss.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-nss.lo `test -f 'vtls/nss.c' || echo '$(srcdir)/'`vtls/nss.c + +vtls/libcurlu_la-polarssl.lo: vtls/polarssl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-polarssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-polarssl.Tpo -c -o vtls/libcurlu_la-polarssl.lo `test -f 'vtls/polarssl.c' || echo '$(srcdir)/'`vtls/polarssl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-polarssl.Tpo vtls/$(DEPDIR)/libcurlu_la-polarssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/polarssl.c' object='vtls/libcurlu_la-polarssl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-polarssl.lo `test -f 'vtls/polarssl.c' || echo '$(srcdir)/'`vtls/polarssl.c + +vtls/libcurlu_la-polarssl_threadlock.lo: vtls/polarssl_threadlock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-polarssl_threadlock.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Tpo -c -o vtls/libcurlu_la-polarssl_threadlock.lo `test -f 'vtls/polarssl_threadlock.c' || echo '$(srcdir)/'`vtls/polarssl_threadlock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Tpo vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/polarssl_threadlock.c' object='vtls/libcurlu_la-polarssl_threadlock.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-polarssl_threadlock.lo `test -f 'vtls/polarssl_threadlock.c' || echo '$(srcdir)/'`vtls/polarssl_threadlock.c + +vtls/libcurlu_la-wolfssl.lo: vtls/wolfssl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-wolfssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-wolfssl.Tpo -c -o vtls/libcurlu_la-wolfssl.lo `test -f 'vtls/wolfssl.c' || echo '$(srcdir)/'`vtls/wolfssl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-wolfssl.Tpo vtls/$(DEPDIR)/libcurlu_la-wolfssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/wolfssl.c' object='vtls/libcurlu_la-wolfssl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-wolfssl.lo `test -f 'vtls/wolfssl.c' || echo '$(srcdir)/'`vtls/wolfssl.c + +vtls/libcurlu_la-schannel.lo: vtls/schannel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-schannel.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-schannel.Tpo -c -o vtls/libcurlu_la-schannel.lo `test -f 'vtls/schannel.c' || echo '$(srcdir)/'`vtls/schannel.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-schannel.Tpo vtls/$(DEPDIR)/libcurlu_la-schannel.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/schannel.c' object='vtls/libcurlu_la-schannel.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-schannel.lo `test -f 'vtls/schannel.c' || echo '$(srcdir)/'`vtls/schannel.c + +vtls/libcurlu_la-schannel_verify.lo: vtls/schannel_verify.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-schannel_verify.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Tpo -c -o vtls/libcurlu_la-schannel_verify.lo `test -f 'vtls/schannel_verify.c' || echo '$(srcdir)/'`vtls/schannel_verify.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Tpo vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/schannel_verify.c' object='vtls/libcurlu_la-schannel_verify.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-schannel_verify.lo `test -f 'vtls/schannel_verify.c' || echo '$(srcdir)/'`vtls/schannel_verify.c + +vtls/libcurlu_la-sectransp.lo: vtls/sectransp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-sectransp.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-sectransp.Tpo -c -o vtls/libcurlu_la-sectransp.lo `test -f 'vtls/sectransp.c' || echo '$(srcdir)/'`vtls/sectransp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-sectransp.Tpo vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/sectransp.c' object='vtls/libcurlu_la-sectransp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-sectransp.lo `test -f 'vtls/sectransp.c' || echo '$(srcdir)/'`vtls/sectransp.c + +vtls/libcurlu_la-gskit.lo: vtls/gskit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-gskit.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-gskit.Tpo -c -o vtls/libcurlu_la-gskit.lo `test -f 'vtls/gskit.c' || echo '$(srcdir)/'`vtls/gskit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-gskit.Tpo vtls/$(DEPDIR)/libcurlu_la-gskit.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/gskit.c' object='vtls/libcurlu_la-gskit.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-gskit.lo `test -f 'vtls/gskit.c' || echo '$(srcdir)/'`vtls/gskit.c + +vtls/libcurlu_la-mbedtls.lo: vtls/mbedtls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-mbedtls.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-mbedtls.Tpo -c -o vtls/libcurlu_la-mbedtls.lo `test -f 'vtls/mbedtls.c' || echo '$(srcdir)/'`vtls/mbedtls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-mbedtls.Tpo vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/mbedtls.c' object='vtls/libcurlu_la-mbedtls.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-mbedtls.lo `test -f 'vtls/mbedtls.c' || echo '$(srcdir)/'`vtls/mbedtls.c + +vtls/libcurlu_la-mesalink.lo: vtls/mesalink.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-mesalink.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-mesalink.Tpo -c -o vtls/libcurlu_la-mesalink.lo `test -f 'vtls/mesalink.c' || echo '$(srcdir)/'`vtls/mesalink.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-mesalink.Tpo vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/mesalink.c' object='vtls/libcurlu_la-mesalink.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-mesalink.lo `test -f 'vtls/mesalink.c' || echo '$(srcdir)/'`vtls/mesalink.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf vauth/.libs vauth/_libs + -rm -rf vtls/.libs vtls/_libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +@CURLDEBUG_FALSE@all-local: +all-am: Makefile $(LTLIBRARIES) curl_config.h all-local +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f vauth/$(DEPDIR)/$(am__dirstamp) + -rm -f vauth/$(am__dirstamp) + -rm -f vtls/$(DEPDIR)/$(am__dirstamp) + -rm -f vtls/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/libcurl_la-altsvc.Plo + -rm -f ./$(DEPDIR)/libcurl_la-amigaos.Plo + -rm -f ./$(DEPDIR)/libcurl_la-asyn-ares.Plo + -rm -f ./$(DEPDIR)/libcurl_la-asyn-thread.Plo + -rm -f ./$(DEPDIR)/libcurl_la-base64.Plo + -rm -f ./$(DEPDIR)/libcurl_la-conncache.Plo + -rm -f ./$(DEPDIR)/libcurl_la-connect.Plo + -rm -f ./$(DEPDIR)/libcurl_la-content_encoding.Plo + -rm -f ./$(DEPDIR)/libcurl_la-cookie.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_addrinfo.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_ctype.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_des.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_endian.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_fnmatch.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_get_line.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_gethostname.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_gssapi.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_memrchr.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_multibyte.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_ntlm_core.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_ntlm_wb.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_path.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_range.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_rtmp.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_sasl.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_sspi.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_threads.Plo + -rm -f ./$(DEPDIR)/libcurl_la-dict.Plo + -rm -f ./$(DEPDIR)/libcurl_la-doh.Plo + -rm -f ./$(DEPDIR)/libcurl_la-dotdot.Plo + -rm -f ./$(DEPDIR)/libcurl_la-easy.Plo + -rm -f ./$(DEPDIR)/libcurl_la-escape.Plo + -rm -f ./$(DEPDIR)/libcurl_la-file.Plo + -rm -f ./$(DEPDIR)/libcurl_la-fileinfo.Plo + -rm -f ./$(DEPDIR)/libcurl_la-formdata.Plo + -rm -f ./$(DEPDIR)/libcurl_la-ftp.Plo + -rm -f ./$(DEPDIR)/libcurl_la-ftplistparser.Plo + -rm -f ./$(DEPDIR)/libcurl_la-getenv.Plo + -rm -f ./$(DEPDIR)/libcurl_la-getinfo.Plo + -rm -f ./$(DEPDIR)/libcurl_la-gopher.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hash.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hmac.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hostasyn.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hostcheck.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hostip.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hostip4.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hostip6.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hostsyn.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http2.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http_chunks.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http_digest.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http_negotiate.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http_ntlm.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http_proxy.Plo + -rm -f ./$(DEPDIR)/libcurl_la-idn_win32.Plo + -rm -f ./$(DEPDIR)/libcurl_la-if2ip.Plo + -rm -f ./$(DEPDIR)/libcurl_la-imap.Plo + -rm -f ./$(DEPDIR)/libcurl_la-inet_ntop.Plo + -rm -f ./$(DEPDIR)/libcurl_la-inet_pton.Plo + -rm -f ./$(DEPDIR)/libcurl_la-krb5.Plo + -rm -f ./$(DEPDIR)/libcurl_la-ldap.Plo + -rm -f ./$(DEPDIR)/libcurl_la-llist.Plo + -rm -f ./$(DEPDIR)/libcurl_la-md4.Plo + -rm -f ./$(DEPDIR)/libcurl_la-md5.Plo + -rm -f ./$(DEPDIR)/libcurl_la-memdebug.Plo + -rm -f ./$(DEPDIR)/libcurl_la-mime.Plo + -rm -f ./$(DEPDIR)/libcurl_la-mprintf.Plo + -rm -f ./$(DEPDIR)/libcurl_la-multi.Plo + -rm -f ./$(DEPDIR)/libcurl_la-netrc.Plo + -rm -f ./$(DEPDIR)/libcurl_la-non-ascii.Plo + -rm -f ./$(DEPDIR)/libcurl_la-nonblock.Plo + -rm -f ./$(DEPDIR)/libcurl_la-openldap.Plo + -rm -f ./$(DEPDIR)/libcurl_la-parsedate.Plo + -rm -f ./$(DEPDIR)/libcurl_la-pingpong.Plo + -rm -f ./$(DEPDIR)/libcurl_la-pop3.Plo + -rm -f ./$(DEPDIR)/libcurl_la-progress.Plo + -rm -f ./$(DEPDIR)/libcurl_la-psl.Plo + -rm -f ./$(DEPDIR)/libcurl_la-rand.Plo + -rm -f ./$(DEPDIR)/libcurl_la-rtsp.Plo + -rm -f ./$(DEPDIR)/libcurl_la-security.Plo + -rm -f ./$(DEPDIR)/libcurl_la-select.Plo + -rm -f ./$(DEPDIR)/libcurl_la-sendf.Plo + -rm -f ./$(DEPDIR)/libcurl_la-setopt.Plo + -rm -f ./$(DEPDIR)/libcurl_la-sha256.Plo + -rm -f ./$(DEPDIR)/libcurl_la-share.Plo + -rm -f ./$(DEPDIR)/libcurl_la-slist.Plo + -rm -f ./$(DEPDIR)/libcurl_la-smb.Plo + -rm -f ./$(DEPDIR)/libcurl_la-smtp.Plo + -rm -f ./$(DEPDIR)/libcurl_la-socks.Plo + -rm -f ./$(DEPDIR)/libcurl_la-socks_gssapi.Plo + -rm -f ./$(DEPDIR)/libcurl_la-socks_sspi.Plo + -rm -f ./$(DEPDIR)/libcurl_la-speedcheck.Plo + -rm -f ./$(DEPDIR)/libcurl_la-splay.Plo + -rm -f ./$(DEPDIR)/libcurl_la-ssh-libssh.Plo + -rm -f ./$(DEPDIR)/libcurl_la-ssh.Plo + -rm -f ./$(DEPDIR)/libcurl_la-strcase.Plo + -rm -f ./$(DEPDIR)/libcurl_la-strdup.Plo + -rm -f ./$(DEPDIR)/libcurl_la-strerror.Plo + -rm -f ./$(DEPDIR)/libcurl_la-strtok.Plo + -rm -f ./$(DEPDIR)/libcurl_la-strtoofft.Plo + -rm -f ./$(DEPDIR)/libcurl_la-system_win32.Plo + -rm -f ./$(DEPDIR)/libcurl_la-telnet.Plo + -rm -f ./$(DEPDIR)/libcurl_la-tftp.Plo + -rm -f ./$(DEPDIR)/libcurl_la-timeval.Plo + -rm -f ./$(DEPDIR)/libcurl_la-transfer.Plo + -rm -f ./$(DEPDIR)/libcurl_la-url.Plo + -rm -f ./$(DEPDIR)/libcurl_la-urlapi.Plo + -rm -f ./$(DEPDIR)/libcurl_la-version.Plo + -rm -f ./$(DEPDIR)/libcurl_la-warnless.Plo + -rm -f ./$(DEPDIR)/libcurl_la-wildcard.Plo + -rm -f ./$(DEPDIR)/libcurl_la-x509asn1.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-altsvc.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-amigaos.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-asyn-thread.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-base64.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-conncache.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-connect.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-content_encoding.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-cookie.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_addrinfo.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_ctype.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_des.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_endian.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_fnmatch.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_get_line.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_gethostname.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_gssapi.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_memrchr.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_multibyte.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_ntlm_core.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_ntlm_wb.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_path.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_range.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_rtmp.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_sasl.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_sspi.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_threads.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-dict.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-doh.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-dotdot.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-easy.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-escape.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-file.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-fileinfo.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-formdata.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-ftp.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-ftplistparser.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-getenv.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-getinfo.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-gopher.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hash.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hmac.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hostasyn.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hostcheck.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hostip.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hostip4.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hostip6.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hostsyn.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http2.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http_chunks.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http_digest.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http_negotiate.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http_ntlm.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http_proxy.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-idn_win32.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-if2ip.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-imap.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-inet_ntop.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-inet_pton.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-krb5.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-ldap.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-llist.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-md4.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-md5.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-memdebug.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-mime.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-mprintf.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-multi.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-netrc.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-non-ascii.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-nonblock.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-openldap.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-parsedate.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-pingpong.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-pop3.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-progress.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-psl.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-rand.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-rtsp.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-security.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-select.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-sendf.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-setopt.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-sha256.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-share.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-slist.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-smb.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-smtp.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-socks.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-socks_gssapi.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-socks_sspi.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-speedcheck.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-splay.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-ssh-libssh.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-ssh.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-strcase.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-strdup.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-strerror.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-strtok.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-strtoofft.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-system_win32.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-telnet.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-tftp.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-timeval.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-transfer.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-url.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-urlapi.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-version.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-warnless.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-wildcard.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-x509asn1.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-cleartext.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-cram.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-digest.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-digest_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-krb5_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-ntlm.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-ntlm_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-oauth2.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-spnego_gssapi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-spnego_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-vauth.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-cleartext.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-cram.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-digest.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-digest_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-krb5_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-ntlm.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-ntlm_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-oauth2.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-spnego_gssapi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-vauth.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-gskit.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-gtls.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-mesalink.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-nss.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-openssl.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-polarssl.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-schannel.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-sectransp.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-vtls.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-gskit.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-gtls.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-nss.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-openssl.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-polarssl.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-schannel.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-vtls.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-wolfssl.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/libcurl_la-altsvc.Plo + -rm -f ./$(DEPDIR)/libcurl_la-amigaos.Plo + -rm -f ./$(DEPDIR)/libcurl_la-asyn-ares.Plo + -rm -f ./$(DEPDIR)/libcurl_la-asyn-thread.Plo + -rm -f ./$(DEPDIR)/libcurl_la-base64.Plo + -rm -f ./$(DEPDIR)/libcurl_la-conncache.Plo + -rm -f ./$(DEPDIR)/libcurl_la-connect.Plo + -rm -f ./$(DEPDIR)/libcurl_la-content_encoding.Plo + -rm -f ./$(DEPDIR)/libcurl_la-cookie.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_addrinfo.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_ctype.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_des.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_endian.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_fnmatch.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_get_line.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_gethostname.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_gssapi.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_memrchr.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_multibyte.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_ntlm_core.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_ntlm_wb.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_path.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_range.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_rtmp.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_sasl.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_sspi.Plo + -rm -f ./$(DEPDIR)/libcurl_la-curl_threads.Plo + -rm -f ./$(DEPDIR)/libcurl_la-dict.Plo + -rm -f ./$(DEPDIR)/libcurl_la-doh.Plo + -rm -f ./$(DEPDIR)/libcurl_la-dotdot.Plo + -rm -f ./$(DEPDIR)/libcurl_la-easy.Plo + -rm -f ./$(DEPDIR)/libcurl_la-escape.Plo + -rm -f ./$(DEPDIR)/libcurl_la-file.Plo + -rm -f ./$(DEPDIR)/libcurl_la-fileinfo.Plo + -rm -f ./$(DEPDIR)/libcurl_la-formdata.Plo + -rm -f ./$(DEPDIR)/libcurl_la-ftp.Plo + -rm -f ./$(DEPDIR)/libcurl_la-ftplistparser.Plo + -rm -f ./$(DEPDIR)/libcurl_la-getenv.Plo + -rm -f ./$(DEPDIR)/libcurl_la-getinfo.Plo + -rm -f ./$(DEPDIR)/libcurl_la-gopher.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hash.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hmac.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hostasyn.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hostcheck.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hostip.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hostip4.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hostip6.Plo + -rm -f ./$(DEPDIR)/libcurl_la-hostsyn.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http2.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http_chunks.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http_digest.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http_negotiate.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http_ntlm.Plo + -rm -f ./$(DEPDIR)/libcurl_la-http_proxy.Plo + -rm -f ./$(DEPDIR)/libcurl_la-idn_win32.Plo + -rm -f ./$(DEPDIR)/libcurl_la-if2ip.Plo + -rm -f ./$(DEPDIR)/libcurl_la-imap.Plo + -rm -f ./$(DEPDIR)/libcurl_la-inet_ntop.Plo + -rm -f ./$(DEPDIR)/libcurl_la-inet_pton.Plo + -rm -f ./$(DEPDIR)/libcurl_la-krb5.Plo + -rm -f ./$(DEPDIR)/libcurl_la-ldap.Plo + -rm -f ./$(DEPDIR)/libcurl_la-llist.Plo + -rm -f ./$(DEPDIR)/libcurl_la-md4.Plo + -rm -f ./$(DEPDIR)/libcurl_la-md5.Plo + -rm -f ./$(DEPDIR)/libcurl_la-memdebug.Plo + -rm -f ./$(DEPDIR)/libcurl_la-mime.Plo + -rm -f ./$(DEPDIR)/libcurl_la-mprintf.Plo + -rm -f ./$(DEPDIR)/libcurl_la-multi.Plo + -rm -f ./$(DEPDIR)/libcurl_la-netrc.Plo + -rm -f ./$(DEPDIR)/libcurl_la-non-ascii.Plo + -rm -f ./$(DEPDIR)/libcurl_la-nonblock.Plo + -rm -f ./$(DEPDIR)/libcurl_la-openldap.Plo + -rm -f ./$(DEPDIR)/libcurl_la-parsedate.Plo + -rm -f ./$(DEPDIR)/libcurl_la-pingpong.Plo + -rm -f ./$(DEPDIR)/libcurl_la-pop3.Plo + -rm -f ./$(DEPDIR)/libcurl_la-progress.Plo + -rm -f ./$(DEPDIR)/libcurl_la-psl.Plo + -rm -f ./$(DEPDIR)/libcurl_la-rand.Plo + -rm -f ./$(DEPDIR)/libcurl_la-rtsp.Plo + -rm -f ./$(DEPDIR)/libcurl_la-security.Plo + -rm -f ./$(DEPDIR)/libcurl_la-select.Plo + -rm -f ./$(DEPDIR)/libcurl_la-sendf.Plo + -rm -f ./$(DEPDIR)/libcurl_la-setopt.Plo + -rm -f ./$(DEPDIR)/libcurl_la-sha256.Plo + -rm -f ./$(DEPDIR)/libcurl_la-share.Plo + -rm -f ./$(DEPDIR)/libcurl_la-slist.Plo + -rm -f ./$(DEPDIR)/libcurl_la-smb.Plo + -rm -f ./$(DEPDIR)/libcurl_la-smtp.Plo + -rm -f ./$(DEPDIR)/libcurl_la-socks.Plo + -rm -f ./$(DEPDIR)/libcurl_la-socks_gssapi.Plo + -rm -f ./$(DEPDIR)/libcurl_la-socks_sspi.Plo + -rm -f ./$(DEPDIR)/libcurl_la-speedcheck.Plo + -rm -f ./$(DEPDIR)/libcurl_la-splay.Plo + -rm -f ./$(DEPDIR)/libcurl_la-ssh-libssh.Plo + -rm -f ./$(DEPDIR)/libcurl_la-ssh.Plo + -rm -f ./$(DEPDIR)/libcurl_la-strcase.Plo + -rm -f ./$(DEPDIR)/libcurl_la-strdup.Plo + -rm -f ./$(DEPDIR)/libcurl_la-strerror.Plo + -rm -f ./$(DEPDIR)/libcurl_la-strtok.Plo + -rm -f ./$(DEPDIR)/libcurl_la-strtoofft.Plo + -rm -f ./$(DEPDIR)/libcurl_la-system_win32.Plo + -rm -f ./$(DEPDIR)/libcurl_la-telnet.Plo + -rm -f ./$(DEPDIR)/libcurl_la-tftp.Plo + -rm -f ./$(DEPDIR)/libcurl_la-timeval.Plo + -rm -f ./$(DEPDIR)/libcurl_la-transfer.Plo + -rm -f ./$(DEPDIR)/libcurl_la-url.Plo + -rm -f ./$(DEPDIR)/libcurl_la-urlapi.Plo + -rm -f ./$(DEPDIR)/libcurl_la-version.Plo + -rm -f ./$(DEPDIR)/libcurl_la-warnless.Plo + -rm -f ./$(DEPDIR)/libcurl_la-wildcard.Plo + -rm -f ./$(DEPDIR)/libcurl_la-x509asn1.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-altsvc.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-amigaos.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-asyn-thread.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-base64.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-conncache.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-connect.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-content_encoding.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-cookie.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_addrinfo.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_ctype.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_des.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_endian.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_fnmatch.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_get_line.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_gethostname.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_gssapi.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_memrchr.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_multibyte.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_ntlm_core.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_ntlm_wb.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_path.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_range.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_rtmp.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_sasl.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_sspi.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-curl_threads.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-dict.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-doh.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-dotdot.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-easy.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-escape.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-file.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-fileinfo.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-formdata.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-ftp.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-ftplistparser.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-getenv.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-getinfo.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-gopher.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hash.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hmac.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hostasyn.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hostcheck.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hostip.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hostip4.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hostip6.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-hostsyn.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http2.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http_chunks.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http_digest.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http_negotiate.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http_ntlm.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-http_proxy.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-idn_win32.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-if2ip.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-imap.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-inet_ntop.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-inet_pton.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-krb5.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-ldap.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-llist.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-md4.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-md5.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-memdebug.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-mime.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-mprintf.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-multi.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-netrc.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-non-ascii.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-nonblock.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-openldap.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-parsedate.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-pingpong.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-pop3.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-progress.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-psl.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-rand.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-rtsp.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-security.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-select.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-sendf.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-setopt.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-sha256.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-share.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-slist.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-smb.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-smtp.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-socks.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-socks_gssapi.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-socks_sspi.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-speedcheck.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-splay.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-ssh-libssh.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-ssh.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-strcase.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-strdup.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-strerror.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-strtok.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-strtoofft.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-system_win32.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-telnet.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-tftp.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-timeval.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-transfer.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-url.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-urlapi.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-version.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-warnless.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-wildcard.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-x509asn1.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-cleartext.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-cram.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-digest.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-digest_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-krb5_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-ntlm.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-ntlm_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-oauth2.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-spnego_gssapi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-spnego_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-vauth.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-cleartext.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-cram.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-digest.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-digest_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-krb5_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-ntlm.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-ntlm_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-oauth2.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-spnego_gssapi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-spnego_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-vauth.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-gskit.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-gtls.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-mesalink.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-nss.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-openssl.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-polarssl.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-schannel.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-sectransp.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-vtls.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-gskit.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-gtls.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-nss.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-openssl.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-polarssl.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-schannel.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-vtls.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-wolfssl.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: all install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am all-local am--depfiles check \ + check-am clean clean-generic clean-libLTLIBRARIES \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-libLTLIBRARIES + +.PRECIOUS: Makefile + + +checksrc: + $(CHECKSRC)(@PERL@ $(srcdir)/checksrc.pl -D$(srcdir) -W$(srcdir)/curl_config.h \ + $(srcdir)/*.[ch] $(srcdir)/vauth/*.[ch] $(srcdir)/vtls/*.[ch]) + +# for debug builds, we scan the sources on all regular make invokes +@CURLDEBUG_TRUE@all-local: checksrc + +tidy: + $(TIDY) $(CSOURCES) $(TIDYFLAGS) -- $(AM_CPPFLAGS) $(CPPFLAGS) -DHAVE_CONFIG_H + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libcurl/lib/Makefile.inc b/libcurl/lib/Makefile.inc new file mode 100644 index 0000000..f795f32 --- /dev/null +++ b/libcurl/lib/Makefile.inc @@ -0,0 +1,85 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### + +LIB_VAUTH_CFILES = vauth/vauth.c vauth/cleartext.c vauth/cram.c \ + vauth/digest.c vauth/digest_sspi.c vauth/krb5_gssapi.c \ + vauth/krb5_sspi.c vauth/ntlm.c vauth/ntlm_sspi.c vauth/oauth2.c \ + vauth/spnego_gssapi.c vauth/spnego_sspi.c + +LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h + +LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \ + vtls/polarssl.c vtls/polarssl_threadlock.c \ + vtls/wolfssl.c vtls/schannel.c vtls/schannel_verify.c \ + vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c \ + vtls/bearssl.c + +LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \ + vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h \ + vtls/wolfssl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h \ + vtls/mbedtls.h vtls/mesalink.h vtls/bearssl.h + +LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ + cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \ + ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \ + getinfo.c transfer.c strcase.c easy.c security.c curl_fnmatch.c \ + fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \ + strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c \ + http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c \ + strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c \ + inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c \ + ssh.c ssh-libssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \ + curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \ + pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c \ + openldap.c curl_gethostname.c gopher.c idn_win32.c \ + http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c \ + http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \ + curl_multibyte.c hostcheck.c conncache.c dotdot.c \ + x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \ + mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \ + doh.c urlapi.c curl_get_line.c altsvc.c + +LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ + formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \ + speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h \ + strcase.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h \ + wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h \ + hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \ + http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \ + inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \ + easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \ + socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h \ + slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \ + rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \ + curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \ + http_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h \ + curl_sasl.h curl_multibyte.h hostcheck.h conncache.h \ + curl_setup_once.h multihandle.h setup-vms.h dotdot.h \ + x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \ + curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \ + curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h \ + curl_get_line.h altsvc.h + +LIB_RCFILES = libcurl.rc + +CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) +HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) diff --git a/libcurl/lib/Makefile.m32 b/libcurl/lib/Makefile.m32 new file mode 100644 index 0000000..ae88f4d --- /dev/null +++ b/libcurl/lib/Makefile.m32 @@ -0,0 +1,387 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1999 - 2017, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +#*************************************************************************** + +########################################################################### +# +## Makefile for building libcurl.a with MingW (GCC-3.2 or later or LLVM/Clang) +## and optionally OpenSSL (1.0.2a), libssh2 (1.5), zlib (1.2.8), librtmp (2.4), +## brotli (1.0.1) +## +## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...] +## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-sspi-winidn +## +## Hint: you can also set environment vars to control the build, f.e.: +## set ZLIB_PATH=c:/zlib-1.2.8 +## set ZLIB=1 +# +########################################################################### + +# Edit the path below to point to the base of your Zlib sources. +ifndef ZLIB_PATH +ZLIB_PATH = ../../zlib-1.2.8 +endif +# Edit the path below to point to the base of your Brotli sources. +ifndef BROTLI_PATH +BROTLI_PATH = ../../brotli-1.0.1 +endif +# Edit the path below to point to the base of your OpenSSL package. +ifndef OPENSSL_PATH +OPENSSL_PATH = ../../openssl-1.0.2a +endif +# Edit the path below to point to the base of your LibSSH2 package. +ifndef LIBSSH2_PATH +LIBSSH2_PATH = ../../libssh2-1.5.0 +endif +# Edit the path below to point to the base of your librtmp package. +ifndef LIBRTMP_PATH +LIBRTMP_PATH = ../../librtmp-2.4 +endif +# Edit the path below to point to the base of your libidn2 package. +ifndef LIBIDN2_PATH +LIBIDN2_PATH = ../../libidn2-2.0.3 +endif +# Edit the path below to point to the base of your MS IDN package. +# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1 +# https://www.microsoft.com/en-us/download/details.aspx?id=734 +ifndef WINIDN_PATH +WINIDN_PATH = ../../Microsoft IDN Mitigation APIs +endif +# Edit the path below to point to the base of your Novell LDAP NDK. +ifndef LDAP_SDK +LDAP_SDK = c:/novell/ndk/cldapsdk/win32 +endif +# Edit the path below to point to the base of your nghttp2 package. +ifndef NGHTTP2_PATH +NGHTTP2_PATH = ../../nghttp2-1.0.0 +endif + +PROOT = .. + +# Edit the path below to point to the base of your c-ares package. +ifndef LIBCARES_PATH +LIBCARES_PATH = $(PROOT)/ares +endif + +ifeq ($(CURL_CC),) +CURL_CC := $(CROSSPREFIX)gcc +endif +ifeq ($(CURL_AR),) +CURL_AR := $(CROSSPREFIX)ar +endif +ifeq ($(CURL_RANLIB),) +CURL_RANLIB := $(CROSSPREFIX)ranlib +endif + +CC = $(CURL_CC) +CFLAGS = $(CURL_CFLAG_EXTRAS) -g -O2 -Wall -W +CFLAGS += -fno-strict-aliasing +# comment LDFLAGS below to keep debug info +LDFLAGS = $(CURL_LDFLAG_EXTRAS) $(CURL_LDFLAG_EXTRAS_DLL) -s +AR = $(CURL_AR) +RANLIB = $(CURL_RANLIB) +RC = $(CROSSPREFIX)windres +RCFLAGS = --include-dir=$(PROOT)/include -DDEBUGBUILD=0 -O COFF +STRIP = $(CROSSPREFIX)strip -g + +# Set environment var ARCH to your architecture to override autodetection. +ifndef ARCH +ifeq ($(findstring x86_64,$(shell $(CC) -dumpmachine)),x86_64) +ARCH = w64 +else +ARCH = w32 +endif +endif + +ifeq ($(ARCH),w64) +CFLAGS += -m64 -D_AMD64_ +LDFLAGS += -m64 +RCFLAGS += -F pe-x86-64 +else +CFLAGS += -m32 +LDFLAGS += -m32 +RCFLAGS += -F pe-i386 +endif + +# Platform-dependent helper tool macros +ifeq ($(findstring /sh,$(SHELL)),/sh) +DEL = rm -f $1 +RMDIR = rm -fr $1 +MKDIR = mkdir -p $1 +COPY = -cp -afv $1 $2 +#COPYR = -cp -afr $1/* $2 +COPYR = -rsync -aC $1/* $2 +TOUCH = touch $1 +CAT = cat +ECHONL = echo "" +DL = ' +else +ifeq "$(OS)" "Windows_NT" +DEL = -del 2>NUL /q /f $(subst /,\,$1) +RMDIR = -rd 2>NUL /q /s $(subst /,\,$1) +else +DEL = -del 2>NUL $(subst /,\,$1) +RMDIR = -deltree 2>NUL /y $(subst /,\,$1) +endif +MKDIR = -md 2>NUL $(subst /,\,$1) +COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2) +COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2) +TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,, +CAT = type +ECHONL = $(ComSpec) /c echo. +endif + +######################################################## +## Nothing more to do below this line! + +ifeq ($(findstring -dyn,$(CFG)),-dyn) +DYN = 1 +endif +ifeq ($(findstring -ares,$(CFG)),-ares) +ARES = 1 +endif +ifeq ($(findstring -sync,$(CFG)),-sync) +SYNC = 1 +endif +ifeq ($(findstring -rtmp,$(CFG)),-rtmp) +RTMP = 1 +SSL = 1 +ZLIB = 1 +endif +ifeq ($(findstring -ssh2,$(CFG)),-ssh2) +SSH2 = 1 +SSL = 1 +ZLIB = 1 +endif +ifeq ($(findstring -ssl,$(CFG)),-ssl) +SSL = 1 +endif +ifeq ($(findstring -srp,$(CFG)),-srp) +SRP = 1 +endif +ifeq ($(findstring -zlib,$(CFG)),-zlib) +ZLIB = 1 +endif +ifeq ($(findstring -brotli,$(CFG)),-brotli) +BROTLI = 1 +endif +ifeq ($(findstring -idn2,$(CFG)),-idn2) +IDN2 = 1 +endif +ifeq ($(findstring -winidn,$(CFG)),-winidn) +WINIDN = 1 +endif +ifeq ($(findstring -sspi,$(CFG)),-sspi) +SSPI = 1 +endif +ifeq ($(findstring -ldaps,$(CFG)),-ldaps) +LDAPS = 1 +endif +ifeq ($(findstring -ipv6,$(CFG)),-ipv6) +IPV6 = 1 +endif +ifeq ($(findstring -winssl,$(CFG)),-winssl) +WINSSL = 1 +SSPI = 1 +endif +ifeq ($(findstring -nghttp2,$(CFG)),-nghttp2) +NGHTTP2 = 1 +endif + +INCLUDES = -I. -I../include +CFLAGS += -DBUILDING_LIBCURL +ifdef SSL + ifdef WINSSL + CFLAGS += -DCURL_WITH_MULTI_SSL + endif +endif + +ifdef SYNC + CFLAGS += -DUSE_SYNC_DNS +else + ifdef ARES + INCLUDES += -I"$(LIBCARES_PATH)" + CFLAGS += -DUSE_ARES -DCARES_STATICLIB + DLL_LIBS += -L"$(LIBCARES_PATH)" -lcares + libcurl_dll_DEPENDENCIES = $(LIBCARES_PATH)/libcares.a + endif +endif +ifdef RTMP + INCLUDES += -I"$(LIBRTMP_PATH)" + CFLAGS += -DUSE_LIBRTMP + DLL_LIBS += -L"$(LIBRTMP_PATH)/librtmp" -lrtmp -lwinmm +endif +ifdef NGHTTP2 + INCLUDES += -I"$(NGHTTP2_PATH)/include" + CFLAGS += -DUSE_NGHTTP2 + DLL_LIBS += -L"$(NGHTTP2_PATH)/lib" -lnghttp2 +endif +ifdef SSH2 + INCLUDES += -I"$(LIBSSH2_PATH)/include" -I"$(LIBSSH2_PATH)/win32" + CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H + DLL_LIBS += -L"$(LIBSSH2_PATH)/win32" -lssh2 + ifdef WINSSL + ifndef DYN + DLL_LIBS += -lbcrypt -lcrypt32 + endif + endif +endif +ifdef SSL + ifndef OPENSSL_INCLUDE + ifeq "$(wildcard $(OPENSSL_PATH)/outinc)" "$(OPENSSL_PATH)/outinc" + OPENSSL_INCLUDE = $(OPENSSL_PATH)/outinc + endif + ifeq "$(wildcard $(OPENSSL_PATH)/include)" "$(OPENSSL_PATH)/include" + OPENSSL_INCLUDE = $(OPENSSL_PATH)/include + endif + endif + ifneq "$(wildcard $(OPENSSL_INCLUDE)/openssl/opensslv.h)" "$(OPENSSL_INCLUDE)/openssl/opensslv.h" + $(error Invalid path to OpenSSL package: $(OPENSSL_PATH)) + endif + ifndef OPENSSL_LIBPATH + ifeq "$(wildcard $(OPENSSL_PATH)/out)" "$(OPENSSL_PATH)/out" + OPENSSL_LIBPATH = $(OPENSSL_PATH)/out + OPENSSL_LIBS = -leay32 -lssl32 + endif + ifeq "$(wildcard $(OPENSSL_PATH)/lib)" "$(OPENSSL_PATH)/lib" + OPENSSL_LIBPATH = $(OPENSSL_PATH)/lib + OPENSSL_LIBS = -lcrypto -lssl + endif + endif + ifndef DYN + OPENSSL_LIBS += -lgdi32 -lcrypt32 + endif + INCLUDES += -I"$(OPENSSL_INCLUDE)" + CFLAGS += -DUSE_OPENSSL -DHAVE_OPENSSL_ENGINE_H -DHAVE_OPENSSL_PKCS12_H \ + -DHAVE_ENGINE_LOAD_BUILTIN_ENGINES -DOPENSSL_NO_KRB5 + DLL_LIBS += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS) + ifdef SRP + ifeq "$(wildcard $(OPENSSL_INCLUDE)/openssl/srp.h)" "$(OPENSSL_INCLUDE)/openssl/srp.h" + CFLAGS += -DHAVE_OPENSSL_SRP -DUSE_TLS_SRP + endif + endif +endif +ifdef WINSSL + CFLAGS += -DUSE_SCHANNEL + DLL_LIBS += -lcrypt32 +endif +ifdef ZLIB + INCLUDES += -I"$(ZLIB_PATH)" + CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H + DLL_LIBS += -L"$(ZLIB_PATH)" -lz +endif +ifdef BROTLI + INCLUDES += -I"$(BROTLI_PATH)/include" + CFLAGS += -DHAVE_BROTLI + DLL_LIBS += -L"$(BROTLI_PATH)/lib" + ifdef BROTLI_LIBS + DLL_LIBS += $(BROTLI_LIBS) + else + DLL_LIBS += -lbrotlidec + endif +endif +ifdef IDN2 + INCLUDES += -I"$(LIBIDN2_PATH)/include" + CFLAGS += -DUSE_LIBIDN2 + DLL_LIBS += -L"$(LIBIDN2_PATH)/lib" -lidn2 +else +ifdef WINIDN + CFLAGS += -DUSE_WIN32_IDN + CFLAGS += -DWANT_IDN_PROTOTYPES + DLL_LIBS += -L"$(WINIDN_PATH)" -lnormaliz +endif +endif +ifdef SSPI + CFLAGS += -DUSE_WINDOWS_SSPI +endif +ifdef SPNEGO + CFLAGS += -DHAVE_SPNEGO +endif +ifdef IPV6 + CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501 +endif +ifdef LDAPS + CFLAGS += -DHAVE_LDAP_SSL +endif +ifdef USE_LDAP_NOVELL + INCLUDES += -I"$(LDAP_SDK)/inc" + CFLAGS += -DCURL_HAS_NOVELL_LDAPSDK + DLL_LIBS += -L"$(LDAP_SDK)/lib/mscvc" -lldapsdk -lldapssl -lldapx +endif +ifdef USE_LDAP_OPENLDAP + INCLUDES += -I"$(LDAP_SDK)/include" + CFLAGS += -DCURL_HAS_OPENLDAP_LDAPSDK + DLL_LIBS += -L"$(LDAP_SDK)/lib" -lldap -llber +endif +ifndef USE_LDAP_NOVELL +ifndef USE_LDAP_OPENLDAP + DLL_LIBS += -lwldap32 +endif +endif +DLL_LIBS += -lws2_32 + +# Makefile.inc provides the CSOURCES and HHEADERS defines +include Makefile.inc + +ifeq ($(CURL_DLL_A_SUFFIX),) +CURL_DLL_A_SUFFIX := dll +endif + +libcurl_dll_LIBRARY = libcurl$(CURL_DLL_SUFFIX).dll +libcurl_dll_a_LIBRARY = libcurl$(CURL_DLL_A_SUFFIX).a +libcurl_a_LIBRARY = libcurl.a + +libcurl_a_OBJECTS := $(patsubst %.c,%.o,$(strip $(CSOURCES))) +libcurl_a_DEPENDENCIES := $(strip $(CSOURCES) $(HHEADERS)) + +RESOURCE = libcurl.res + + +all: $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY) + +$(libcurl_a_LIBRARY): $(libcurl_a_OBJECTS) $(libcurl_a_DEPENDENCIES) + @$(call DEL, $@) + $(AR) cru $@ $(libcurl_a_OBJECTS) + $(RANLIB) $@ + $(STRIP) $@ + +# remove the last line above to keep debug info + +$(libcurl_dll_LIBRARY): $(libcurl_a_OBJECTS) $(RESOURCE) $(libcurl_dll_DEPENDENCIES) + @$(call DEL, $@) + $(CC) $(LDFLAGS) -shared -o $@ \ + -Wl,--output-def,$(@:.dll=.def),--out-implib,$(libcurl_dll_a_LIBRARY) \ + $(libcurl_a_OBJECTS) $(RESOURCE) $(DLL_LIBS) + +%.o: %.c + $(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@ + +%.res: %.rc + $(RC) $(RCFLAGS) -i $< -o $@ + +clean: + @$(call DEL, $(libcurl_a_OBJECTS) $(RESOURCE)) + +distclean vclean: clean + @$(call DEL, $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY) $(libcurl_dll_LIBRARY:.dll=.def) $(libcurl_dll_a_LIBRARY)) + +$(LIBCARES_PATH)/libcares.a: + $(MAKE) -C $(LIBCARES_PATH) -f Makefile.m32 diff --git a/libcurl/lib/Makefile.netware b/libcurl/lib/Makefile.netware new file mode 100644 index 0000000..29885a1 --- /dev/null +++ b/libcurl/lib/Makefile.netware @@ -0,0 +1,734 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 2004 - 2015, Guenter Knauf +# Copyright (C) 2001 - 2018, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +#*************************************************************************** + +################################################################# +# +## Makefile for building libcurl.nlm (NetWare version - gnu make) +## +## Use: make -f Makefile.netware +# +################################################################# + +# Edit the path below to point to the base of your Novell NDK. +ifndef NDKBASE +NDKBASE = c:/novell +endif + +# Edit the path below to point to the base of your Zlib sources. +ifndef ZLIB_PATH +ZLIB_PATH = ../../zlib-1.2.8 +endif + +# Edit the path below to point to the base of your OpenSSL package. +ifndef OPENSSL_PATH +OPENSSL_PATH = ../../openssl-1.0.2a +endif + +# Edit the path below to point to the base of your LibSSH2 package. +ifndef LIBSSH2_PATH +LIBSSH2_PATH = ../../libssh2-1.5.0 +endif + +# Edit the path below to point to the base of your libidn package. +ifndef LIBIDN_PATH +LIBIDN_PATH = ../../libidn-1.18 +endif + +# Edit the path below to point to the base of your librtmp package. +ifndef LIBRTMP_PATH +LIBRTMP_PATH = ../../librtmp-2.3 +endif + +# Edit the path below to point to the base of your nghttp2 package. +ifndef NGHTTP2_PATH +NGHTTP2_PATH = ../../nghttp2-0.6.7 +endif + +# Edit the path below to point to the base of your fbopenssl package. +ifndef FBOPENSSL_PATH +FBOPENSSL_PATH = ../../fbopenssl-0.4 +endif + +# Edit the path below to point to the base of your c-ares package. +ifndef LIBCARES_PATH +LIBCARES_PATH = ../ares +endif + +ifndef INSTDIR +INSTDIR = ..$(DS)curl-$(LIBCURL_VERSION_STR)-bin-nw +endif + +# Edit the vars below to change NLM target settings. +TARGET = libcurl +VERSION = $(LIBCURL_VERSION) +COPYR = Copyright (C) $(LIBCURL_COPYRIGHT_STR) +DESCR = curl libcurl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.haxx.se +MTSAFE = YES +STACK = 64000 +SCREEN = none +EXPORTF = $(TARGET).imp +EXPORTS = @$(EXPORTF) + +# Uncomment the next line to enable linking with POSIX semantics. +# POSIXFL = 1 + +# Edit the var below to point to your lib architecture. +ifndef LIBARCH +LIBARCH = LIBC +endif + +# must be equal to NDEBUG or DEBUG, CURLDEBUG +ifndef DB +DB = NDEBUG +endif +# Optimization: -O or debugging: -g +ifeq ($(DB),NDEBUG) + OPT = -O2 + OBJDIR = release +else + OPT = -g + OBJDIR = debug +endif + +# The following lines defines your compiler. +ifdef CWFolder + METROWERKS = $(CWFolder) +endif +ifdef METROWERKS + # MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support + MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support + CC = mwccnlm +else + CC = gcc +endif +PERL = perl +# Here you can find a native Win32 binary of the original awk: +# http://www.gknw.net/development/prgtools/awk-20100523.zip +AWK = awk +CP = cp -afv +MKDIR = mkdir +# RM = rm -f +# If you want to mark the target as MTSAFE you will need a tool for +# generating the xdc data for the linker; here's a minimal tool: +# http://www.gknw.net/development/prgtools/mkxdc.zip +MPKXDC = mkxdc + +# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH)) +LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH)) + +# Include the version info retrieved from curlver.h +-include $(OBJDIR)/version.inc + +# Global flags for all compilers +CFLAGS += $(OPT) -D$(DB) -DNETWARE -DHAVE_CONFIG_H -nostdinc + +ifeq ($(CC),mwccnlm) + LD = mwldnlm + LDFLAGS = -nostdlib $(PRELUDE) $(OBJL) -o $@ -commandfile + AR = mwldnlm + ARFLAGS = -nostdlib -type library -o + LIBEXT = lib + #RANLIB = + CFLAGS += -msgstyle gcc -gccinc -inline off -opt nointrinsics -proc 586 + CFLAGS += -relax_pointers + #CFLAGS += -w on + ifeq ($(LIBARCH),LIBC) + ifeq ($(POSIXFL),1) + PRELUDE = $(NDK_LIBC)/imports/posixpre.o + else + PRELUDE = $(NDK_LIBC)/imports/libcpre.o + endif + CFLAGS += -align 4 + else + # PRELUDE = $(NDK_CLIB)/imports/clibpre.o + # to avoid the __init_* / __deinit_* woes don't use prelude from NDK + PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj" + # CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h" + CFLAGS += -align 1 + endif +else + LD = nlmconv + LDFLAGS = -T + AR = ar + ARFLAGS = -cq + LIBEXT = a + RANLIB = ranlib + CFLAGS += -m32 + CFLAGS += -fno-builtin -fno-strict-aliasing + ifeq ($(findstring gcc,$(CC)),gcc) + CFLAGS += -fpcc-struct-return + endif + CFLAGS += -Wall # -pedantic + ifeq ($(LIBARCH),LIBC) + ifeq ($(POSIXFL),1) + PRELUDE = $(NDK_LIBC)/imports/posixpre.gcc.o + else + PRELUDE = $(NDK_LIBC)/imports/libcpre.gcc.o + endif + else + PRELUDE = $(NDK_CLIB)/imports/clibpre.gcc.o + # to avoid the __init_* / __deinit_* woes don't use prelude from NDK + # http://www.gknw.net/development/mk_nlm/gcc_pre.zip + # PRELUDE = $(NDK_ROOT)/pre/prelude.o + CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h + endif +endif + +NDK_ROOT = $(NDKBASE)/ndk +ifndef NDK_CLIB +NDK_CLIB = $(NDK_ROOT)/nwsdk +endif +ifndef NDK_LIBC +NDK_LIBC = $(NDK_ROOT)/libc +endif +ifndef NDK_LDAP +NDK_LDAP = $(NDK_ROOT)/cldapsdk/netware +endif +CURL_INC = ../include +CURL_LIB = ../lib + +INCLUDES = -I$(CURL_INC) -I$(CURL_LIB) + +ifeq ($(findstring -static,$(CFG)),-static) +LINK_STATIC = 1 +endif +ifeq ($(findstring -ares,$(CFG)),-ares) +WITH_ARES = 1 +endif +ifeq ($(findstring -rtmp,$(CFG)),-rtmp) +WITH_RTMP = 1 +WITH_SSL = 1 +WITH_ZLIB = 1 +endif +ifeq ($(findstring -ssh2,$(CFG)),-ssh2) +WITH_SSH2 = 1 +WITH_SSL = 1 +WITH_ZLIB = 1 +endif +ifeq ($(findstring -ssl,$(CFG)),-ssl) +WITH_SSL = 1 +ifeq ($(findstring -srp,$(CFG)),-srp) +ifeq "$(wildcard $(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L)/openssl/srp.h)" "$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L)/openssl/srp.h" +WITH_SRP = 1 +endif +endif +endif +ifeq ($(findstring -zlib,$(CFG)),-zlib) +WITH_ZLIB = 1 +endif +ifeq ($(findstring -idn,$(CFG)),-idn) +WITH_IDN = 1 +endif +ifeq ($(findstring -nghttp2,$(CFG)),-nghttp2) +WITH_NGHTTP2 = 1 +endif +ifeq ($(findstring -ipv6,$(CFG)),-ipv6) +ENABLE_IPV6 = 1 +endif + +ifdef WITH_ARES + INCLUDES += -I$(LIBCARES_PATH) + LDLIBS += $(LIBCARES_PATH)/libcares.$(LIBEXT) +endif +ifdef WITH_SSH2 + INCLUDES += -I$(LIBSSH2_PATH)/include +ifdef LINK_STATIC + LDLIBS += $(LIBSSH2_PATH)/nw/libssh2.$(LIBEXT) +else + MODULES += libssh2.nlm + IMPORTS += @$(LIBSSH2_PATH)/nw/libssh2.imp +endif +endif +ifdef WITH_RTMP + INCLUDES += -I$(LIBRTMP_PATH) + LDLIBS += $(LIBRTMP_PATH)/librtmp/librtmp.$(LIBEXT) +endif +ifdef WITH_SSL + INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L) + LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT) + LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT) + IMPORTS += GetProcessSwitchCount RunningProcess + INSTDEP += ca-bundle.crt +else +endif +ifdef WITH_ZLIB + INCLUDES += -I$(ZLIB_PATH) + ifdef LINK_STATIC + LDLIBS += $(ZLIB_PATH)/nw/$(LIBARCH)/libz.$(LIBEXT) + else + MODULES += libz.nlm + IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp + endif +endif +ifdef WITH_IDN + INCLUDES += -I$(LIBIDN_PATH)/include + LDLIBS += $(LIBIDN_PATH)/lib/libidn.$(LIBEXT) +endif +ifdef WITH_NGHTTP2 + INCLUDES += -I$(NGHTTP2_PATH)/include + LDLIBS += $(NGHTTP2_PATH)/lib/libnghttp2.$(LIBEXT) +endif + +ifeq ($(LIBARCH),LIBC) + INCLUDES += -I$(NDK_LIBC)/include + # INCLUDES += -I$(NDK_LIBC)/include/nks + # INCLUDES += -I$(NDK_LIBC)/include/winsock + CFLAGS += -D_POSIX_SOURCE +else + INCLUDES += -I$(NDK_CLIB)/include/nlm + # INCLUDES += -I$(NDK_CLIB)/include/nlm/obsolete + # INCLUDES += -I$(NDK_CLIB)/include +endif +ifndef DISABLE_LDAP + INCLUDES += -I$(NDK_LDAP)/$(LIBARCH_L)/inc +endif +CFLAGS += $(INCLUDES) + +ifeq ($(MTSAFE),YES) + XDCOPT = -n +endif +ifeq ($(MTSAFE),NO) + XDCOPT = -u +endif +ifdef XDCOPT + XDCDATA = $(OBJDIR)/$(TARGET).xdc +endif + +ifeq ($(findstring /sh,$(SHELL)),/sh) +DL = ' +DS = / +PCT = % +#-include $(NDKBASE)/nlmconv/ncpfs.inc +else +DS = \\ +PCT = %% +endif + +# Makefile.inc provides the CSOURCES and HHEADERS defines +include Makefile.inc + +OBJS := $(patsubst %.c,$(OBJDIR)/%.o,$(strip $(notdir $(CSOURCES)))) $(OBJDIR)/nwos.o + +OBJL = $(OBJS) $(OBJDIR)/nwlib.o $(LDLIBS) + +vpath %.c . vauth vtls + +all: lib nlm + +nlm: prebuild $(TARGET).nlm + +lib: prebuild $(TARGET).$(LIBEXT) + +prebuild: $(OBJDIR) $(OBJDIR)/version.inc curl_config.h + +$(OBJDIR)/%.o: %.c +# @echo Compiling $< + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)/version.inc: $(CURL_INC)/curl/curlver.h $(OBJDIR) + @echo Creating $@ + @$(AWK) -f ../packages/NetWare/get_ver.awk $< > $@ + +install: $(INSTDIR) all $(INSTDEP) + @$(CP) $(TARGET).nlm $(INSTDIR) + @$(CP) $(TARGET).$(LIBEXT) $(INSTDIR) + @$(CP) ../CHANGES $(INSTDIR) + @$(CP) ../COPYING $(INSTDIR) + @$(CP) ../README $(INSTDIR) + @$(CP) ../RELEASE-NOTES $(INSTDIR) +ifdef WITH_SSL + @-$(CP) ca-bundle.crt $(INSTDIR)/ca-bundle.crt +endif + +clean: + -$(RM) curl_config.h + -$(RM) -r $(OBJDIR) + +distclean vclean: clean + -$(RM) $(TARGET).$(LIBEXT) $(TARGET).nlm $(TARGET).imp + -$(RM) certdata.txt ca-bundle.crt + +$(OBJDIR) $(INSTDIR): + @$(MKDIR) $@ + +$(TARGET).$(LIBEXT): $(OBJS) + @echo Creating $@ + @-$(RM) $@ + @$(AR) $(ARFLAGS) $@ $^ +ifdef RANLIB + @$(RANLIB) $@ +endif + +$(TARGET).nlm: $(OBJDIR)/$(TARGET).def $(OBJL) $(EXPORTF) $(XDCDATA) + @echo Linking $@ + @-$(RM) $@ + @$(LD) $(LDFLAGS) $< + +$(OBJDIR)/%.xdc: Makefile.netware + @echo Creating $@ + @$(MPKXDC) $(XDCOPT) $@ + +$(OBJDIR)/%.def: Makefile.netware + @echo $(DL)# DEF file for linking with $(LD)$(DL) > $@ + @echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@ + @echo $(DL)# All your changes will be lost!!$(DL) >> $@ + @echo $(DL)#$(DL) >> $@ + @echo $(DL)copyright "$(COPYR)"$(DL) >> $@ + @echo $(DL)description "$(DESCR)"$(DL) >> $@ + @echo $(DL)version $(VERSION)$(DL) >> $@ +ifdef NLMTYPE + @echo $(DL)type $(NLMTYPE)$(DL) >> $@ +endif +ifdef STACK + @echo $(DL)stack $(STACK)$(DL) >> $@ +endif +ifdef SCREEN + @echo $(DL)screenname "$(SCREEN)"$(DL) >> $@ +else + @echo $(DL)screenname "DEFAULT"$(DL) >> $@ +endif +ifneq ($(DB),NDEBUG) + @echo $(DL)debug$(DL) >> $@ +endif + @echo $(DL)threadname "$(TARGET)"$(DL) >> $@ +ifdef XDCDATA + @echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@ +endif + @echo $(DL)flag_on 64$(DL) >> $@ +ifeq ($(LIBARCH),CLIB) + @echo $(DL)start _Prelude$(DL) >> $@ + @echo $(DL)exit _Stop$(DL) >> $@ + @echo $(DL)import @$(NDK_CLIB)/imports/clib.imp$(DL) >> $@ + @echo $(DL)import @$(NDK_CLIB)/imports/threads.imp$(DL) >> $@ + @echo $(DL)import @$(NDK_CLIB)/imports/nlmlib.imp$(DL) >> $@ + @echo $(DL)import @$(NDK_CLIB)/imports/socklib.imp$(DL) >> $@ + @echo $(DL)module clib$(DL) >> $@ +ifndef DISABLE_LDAP + @echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@ + @echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@ +# @echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@ + @echo $(DL)module ldapsdk ldapssl$(DL) >> $@ +endif +else +ifeq ($(POSIXFL),1) + @echo $(DL)flag_on 4194304$(DL) >> $@ +endif + @echo $(DL)pseudopreemption$(DL) >> $@ +ifeq ($(findstring posixpre,$(PRELUDE)),posixpre) + @echo $(DL)start POSIX_Start$(DL) >> $@ + @echo $(DL)exit POSIX_Stop$(DL) >> $@ + @echo $(DL)check POSIX_CheckUnload$(DL) >> $@ +else + @echo $(DL)start _LibCPrelude$(DL) >> $@ + @echo $(DL)exit _LibCPostlude$(DL) >> $@ + @echo $(DL)check _LibCCheckUnload$(DL) >> $@ +endif + @echo $(DL)import @$(NDK_LIBC)/imports/libc.imp$(DL) >> $@ + @echo $(DL)import @$(NDK_LIBC)/imports/netware.imp$(DL) >> $@ + @echo $(DL)module libc$(DL) >> $@ +ifndef DISABLE_LDAP + @echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@ + @echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@ +# @echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@ + @echo $(DL)module lldapsdk lldapssl$(DL) >> $@ +endif +endif +ifdef MODULES + @echo $(DL)module $(MODULES)$(DL) >> $@ +endif +ifdef EXPORTS + @echo $(DL)export $(EXPORTS)$(DL) >> $@ +endif +ifdef IMPORTS + @echo $(DL)import $(IMPORTS)$(DL) >> $@ +endif +ifeq ($(findstring nlmconv,$(LD)),nlmconv) + @echo $(DL)input $(PRELUDE)$(DL) >> $@ + @echo $(DL)input $(OBJL)$(DL) >> $@ +#ifdef LDLIBS +# @echo $(DL)input $(LDLIBS)$(DL) >> $@ +#endif + @echo $(DL)output $(TARGET).nlm$(DL) >> $@ +endif + +curl_config.h: Makefile.netware + @echo Creating $@ + @echo $(DL)/* $@ for NetWare target.$(DL) > $@ + @echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@ + @echo $(DL)** All your changes will be lost!!$(DL) >> $@ + @echo $(DL)*/$(DL) >> $@ + @echo $(DL)#ifndef NETWARE$(DL) >> $@ + @echo $(DL)#error This $(notdir $@) is created for NetWare platform!$(DL) >> $@ + @echo $(DL)#endif$(DL) >> $@ + @echo $(DL)#define VERSION "$(LIBCURL_VERSION_STR)"$(DL) >> $@ + @echo $(DL)#define PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.haxx.se/mail/"$(DL) >> $@ +ifeq ($(LIBARCH),CLIB) + @echo $(DL)#define OS "i586-pc-clib-NetWare"$(DL) >> $@ + @echo $(DL)#define NETDB_USE_INTERNET 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRICMP 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRNICMP 1$(DL) >> $@ + @echo $(DL)#define RECV_TYPE_ARG1 int$(DL) >> $@ + @echo $(DL)#define RECV_TYPE_ARG2 char *$(DL) >> $@ + @echo $(DL)#define RECV_TYPE_ARG3 int$(DL) >> $@ + @echo $(DL)#define RECV_TYPE_ARG4 int$(DL) >> $@ + @echo $(DL)#define RECV_TYPE_RETV int$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG1 int$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG2 char$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG3 int$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG4 int$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG5 struct sockaddr$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG6 int$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_RETV int$(DL) >> $@ + @echo $(DL)#define SEND_QUAL_ARG2$(DL) >> $@ + @echo $(DL)#define SEND_TYPE_ARG1 int$(DL) >> $@ + @echo $(DL)#define SEND_TYPE_ARG2 char *$(DL) >> $@ + @echo $(DL)#define SEND_TYPE_ARG3 int$(DL) >> $@ + @echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@ + @echo $(DL)#define SEND_TYPE_RETV int$(DL) >> $@ + @echo $(DL)#define SIZEOF_SIZE_T 4$(DL) >> $@ + @echo $(DL)#define pressanykey PressAnyKeyToContinue$(DL) >> $@ +else + @echo $(DL)#define OS "i586-pc-libc-NetWare"$(DL) >> $@ + @echo $(DL)#define HAVE_FTRUNCATE 1$(DL) >> $@ + @echo $(DL)#define HAVE_GETTIMEOFDAY 1$(DL) >> $@ + @echo $(DL)#define HAVE_INTTYPES_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_LONGLONG 1$(DL) >> $@ + @echo $(DL)#define HAVE_STDINT_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRCASECMP 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRLCAT 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRLCPY 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRTOLL 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_PARAM_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_SELECT_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_TERMIOS_H 1$(DL) >> $@ + @echo $(DL)#define RECV_TYPE_ARG1 int$(DL) >> $@ + @echo $(DL)#define RECV_TYPE_ARG2 void *$(DL) >> $@ + @echo $(DL)#define RECV_TYPE_ARG3 size_t$(DL) >> $@ + @echo $(DL)#define RECV_TYPE_ARG4 int$(DL) >> $@ + @echo $(DL)#define RECV_TYPE_RETV ssize_t$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG1 int$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG2 void$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG3 size_t$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG4 int$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG5 struct sockaddr$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG6 size_t$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_RETV ssize_t$(DL) >> $@ + @echo $(DL)#define RECVFROM_TYPE_ARG2_IS_VOID 1$(DL) >> $@ + @echo $(DL)#define SEND_QUAL_ARG2$(DL) >> $@ + @echo $(DL)#define SEND_TYPE_ARG1 int$(DL) >> $@ + @echo $(DL)#define SEND_TYPE_ARG2 void *$(DL) >> $@ + @echo $(DL)#define SEND_TYPE_ARG3 size_t$(DL) >> $@ + @echo $(DL)#define SEND_TYPE_ARG4 int$(DL) >> $@ + @echo $(DL)#define SEND_TYPE_RETV ssize_t$(DL) >> $@ + @echo $(DL)#define SIZEOF_OFF_T 8$(DL) >> $@ + @echo $(DL)#define SIZEOF_SIZE_T 8$(DL) >> $@ + @echo $(DL)#define _LARGEFILE 1$(DL) >> $@ +ifdef ENABLE_IPV6 + @echo $(DL)#define ENABLE_IPV6 1$(DL) >> $@ + @echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@ + @echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@ + @echo $(DL)#define HAVE_FREEADDRINFO 1$(DL) >> $@ + @echo $(DL)#define HAVE_GETADDRINFO 1$(DL) >> $@ + @echo $(DL)#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@ + @echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@ +endif +endif + @echo $(DL)#define USE_MANUAL 1$(DL) >> $@ + @echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_ERRNO_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_FCNTL_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_GETHOSTBYADDR 1$(DL) >> $@ + @echo $(DL)#define HAVE_GETHOSTBYNAME 1$(DL) >> $@ + @echo $(DL)#define HAVE_GETPROTOBYNAME 1$(DL) >> $@ + @echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@ + @echo $(DL)#define HAVE_INET_ADDR 1$(DL) >> $@ + @echo $(DL)#define HAVE_IOCTL 1$(DL) >> $@ + @echo $(DL)#define HAVE_IOCTL_FIONBIO 1$(DL) >> $@ + @echo $(DL)#define HAVE_LL 1$(DL) >> $@ + @echo $(DL)#define HAVE_LOCALE_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@ + @echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_NETINET_IN_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_RECV 1$(DL) >> $@ + @echo $(DL)#define HAVE_RECVFROM 1$(DL) >> $@ + @echo $(DL)#define HAVE_SELECT 1$(DL) >> $@ + @echo $(DL)#define HAVE_SEND 1$(DL) >> $@ + @echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SETLOCALE 1$(DL) >> $@ + @echo $(DL)#define HAVE_SIGNAL 1$(DL) >> $@ + @echo $(DL)#define HAVE_SIGNAL_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SIG_ATOMIC_T 1$(DL) >> $@ + @echo $(DL)#define HAVE_SOCKET 1$(DL) >> $@ + @echo $(DL)#define HAVE_STDLIB_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRDUP 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRFTIME 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRING_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRSTR 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRUCT_TIMEVAL 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_IOCTL_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_STAT_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_TIME_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_TIME_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_UNAME 1$(DL) >> $@ + @echo $(DL)#define HAVE_UNISTD_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_UTIME 1$(DL) >> $@ + @echo $(DL)#define HAVE_UTIME_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_WRITEV 1$(DL) >> $@ + @echo $(DL)#define RETSIGTYPE void$(DL) >> $@ + @echo $(DL)#define SIZEOF_INT 4$(DL) >> $@ + @echo $(DL)#define SIZEOF_SHORT 2$(DL) >> $@ + @echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@ + @echo $(DL)#define STDC_HEADERS 1$(DL) >> $@ + @echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@ +ifdef DISABLE_LDAP + @echo $(DL)#define CURL_DISABLE_LDAP 1$(DL) >> $@ +else + @echo $(DL)#define CURL_HAS_NOVELL_LDAPSDK 1$(DL) >> $@ +ifndef DISABLE_LDAPS + @echo $(DL)#define HAVE_LDAP_SSL 1$(DL) >> $@ +endif + @echo $(DL)#define HAVE_LDAP_SSL_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_LDAP_URL_PARSE 1$(DL) >> $@ +endif +ifdef NW_WINSOCK + @echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@ +else + @echo $(DL)#define USE_BSD_SOCKETS 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_TYPES_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_SOCKET_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_SOCKIO_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_NETDB_H 1$(DL) >> $@ +endif +ifdef WITH_ARES + @echo $(DL)#define USE_ARES 1$(DL) >> $@ +endif +ifdef WITH_ZLIB + @echo $(DL)#define HAVE_ZLIB_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_LIBZ 1$(DL) >> $@ +endif +ifdef WITH_SSL + @echo $(DL)#define USE_OPENSSL 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_X509_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_SSL_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_RSA_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_PEM_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_ERR_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_CRYPTO_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_ENGINE_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_LIBSSL 1$(DL) >> $@ + @echo $(DL)#define HAVE_LIBCRYPTO 1$(DL) >> $@ + @echo $(DL)#define OPENSSL_NO_KRB5 1$(DL) >> $@ +ifdef WITH_SRP + @echo $(DL)#define USE_TLS_SRP 1$(DL) >> $@ +endif +ifdef WITH_SPNEGO + @echo $(DL)#define HAVE_SPNEGO 1$(DL) >> $@ +endif +else +endif +ifdef WITH_SSH2 + @echo $(DL)#define USE_LIBSSH2 1$(DL) >> $@ + @echo $(DL)#define HAVE_LIBSSH2_H 1$(DL) >> $@ +endif +ifdef WITH_IDN + @echo $(DL)#define HAVE_LIBIDN 1$(DL) >> $@ + @echo $(DL)#define HAVE_TLD_H 1$(DL) >> $@ +endif +ifdef WITH_RTMP + @echo $(DL)#define USE_LIBRTMP 1$(DL) >> $@ +endif +ifdef WITH_NGHTTP2 + @echo $(DL)#define USE_NGHTTP2 1$(DL) >> $@ +endif + @echo $(DL)#ifdef __GNUC__$(DL) >> $@ + @echo $(DL)#define HAVE_VARIADIC_MACROS_GCC 1$(DL) >> $@ + @echo $(DL)#else$(DL) >> $@ + @echo $(DL)#define HAVE_VARIADIC_MACROS_C99 1$(DL) >> $@ + @echo $(DL)#endif$(DL) >> $@ +ifdef CABUNDLE + @echo $(DL)#define CURL_CA_BUNDLE "$(CABUNDLE)"$(DL) >> $@ +else + @echo $(DL)#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")$(DL) >> $@ +endif + +$(EXPORTF): $(CURL_INC)/curl/curl.h $(CURL_INC)/curl/easy.h $(CURL_INC)/curl/multi.h $(CURL_INC)/curl/mprintf.h + @echo Creating $@ + @$(AWK) -f ../packages/NetWare/get_exp.awk $^ > $@ + +FORCE: ; + +info: $(OBJDIR)/version.inc + @echo Configured to build $(TARGET) with these options: + @echo libarchitecture: $(LIBARCH) + @echo curl version: $(LIBCURL_VERSION_STR) + @echo compiler/linker: $(CC) / $(LD) +ifdef CABUNDLE + @echo ca-bundle path: $(CABUNDLE) +endif +ifdef WITH_SSL + @echo SSL support: enabled (OpenSSL) +else + @echo SSL support: no +endif +ifdef WITH_SRP + @echo SRP support: enabled +else + @echo SRP support: no +endif +ifdef WITH_SSH2 + @echo SSH2 support: enabled (libssh2) +else + @echo SSH2 support: no +endif +ifdef WITH_ZLIB + @echo zlib support: enabled +else + @echo zlib support: no +endif +ifdef WITH_NGHTTP2 + @echo http2 support: enabled +else + @echo http2 support: no +endif +ifdef WITH_ARES + @echo c-ares support: enabled +else + @echo c-ares support: no +endif +ifdef ENABLE_IPV6 + @echo IPv6 support: enabled +else + @echo IPv6 support: no +endif + +$(LIBCARES_PATH)/libcares.$(LIBEXT): + $(MAKE) -C $(LIBCARES_PATH) -f Makefile.netware lib + +ca-bundle.crt: mk-ca-bundle.pl + @echo Creating $@ + @-$(PERL) $< -b -n $@ diff --git a/libcurl/lib/Makefile.vxworks b/libcurl/lib/Makefile.vxworks new file mode 100644 index 0000000..7ff197f --- /dev/null +++ b/libcurl/lib/Makefile.vxworks @@ -0,0 +1,177 @@ +#***************************************************************************** +# +# +#Filename : Makefile.vxworks +#Description: makefile to be used in order to compile libcurl for VxWoorks 6.3. +# +#How to use: +# 1. Adjust environment variables at the file beginning +# 2. Open the Command Prompt window and change directory ('cd') +# into the 'lib' folder +# 3. Add /bin folder to the PATH environment variable +# For example type 'set PATH=C:/embedded/cygwin/bin;%PATH%' +# 4. Build the library by typing 'make -f ./Makefile.vxworks' +# As a result the libcurl.a should be created in the 'lib' folder. +# To clean package use 'make -f ./Makefile.vxworks clean' +#Requirements: +# 1. WinXP machine +# 2. Full CYGWIN installation (open source) with GNU make version +# v3.78 or higher +# 3. WindRiver Workbench with vxWorks 6.3 (commercial) +#***************************************************************************** + +# ---------------------------------------------------------------------- +# Environment +# ---------------------------------------------------------------------- + +export WIND_HOME := C:/embedded/Workbench2.5.0.1 +export WIND_BASE := $(WIND_HOME)/vxworks-6.3 +export WIND_HOST_TYPE := x86-win32 + +# BUILD_TYE:= | (build with debugging info or optimized) +BUILD_TYPE := debug +USER_CFLAGS:= + +# directories where to seek for includes and libraries +OPENSSL_INC := D:/libraries/openssl/openssl-0.9.8zc-vxWorks6.3/include +OPENSSL_LIB := D:/libraries/openssl/openssl-0.9.8zc-vxWorks6.3 +ZLIB_INC := D:/libraries/zlib/zlib-1.2.8-VxWorks6.3/zlib-1.2.8 +ZLIB_LIB := D:/libraries/zlib/zlib-1.2.8-VxWorks6.3/binaries/vxworks_3.1_gnu/Debug/lib +ARES_INC := +ARES_LIB := + + +# ---------------------------------------------------------------------- +# Compiler +# ---------------------------------------------------------------------- + +CC := ccppc +AR := arppc +LINK := ccppc +CFLAGS := -D__GNUC__ -D__ppc__ -msoft-float -fno-builtin -mcpu=604 -mlongcall -DCPU=PPC604 -D_GNU_TOOL -Wall -W -Winline $(USER_CFLAGS) +LDFLAGS := -nostdlib -Wl,-i -Wl,-X +INCLUDE_FLAG := -I +C_DEBUGFLAG := -g +C_OPTFLAG := -O2 +COMPILE_ONLY_FLAG := -c +OBJ_EXTENSION := .o +CC_OBJ_OUTPUT = -o $@ +ARFLAGS := -rc +LIBS_FLAG := -l +LIBS_DIRFLAG:= -L +LD_DEBUGFLAG := $(C_DEBUGFLAG) +EXECUTE_EXTENSION := .out +TOOL_CHAIN_BIN := $(WIND_HOME)/gnu/3.4.4-vxworks-6.3/$(WIND_HOST_TYPE)/bin/ + +# ---------------------------------------------------------------------- + +# Add -DINET6 if the OS kernel image was built with IPv6 support +# CFLAGS += -DINET6 + +# Set up compiler and linker flags for debug or optimization +ifeq ($(BUILD_TYPE), debug) +CFLAGS += $(C_DEBUGFLAG) +LDFLAGS += $(LD_DEBUGFLAG) +else +CFLAGS += $(C_OPTFLAG) +endif + +# ---------------------------------------------------------------------- + +# Main Makefile and possible sub-make files +MAKEFILES := Makefile.vxworks + +# List of external include directories +#----- +# IMPORTANT: include OPENSSL directories before system +# in order to prevent WindRiver OpenSSL to be used. +#----- +INCLUDE_DIRS := ../include $(OPENSSL_INC) $(ZLIB_INC) $(ARES_INC) $(WIND_BASE)/target/h $(WIND_BASE)/target/h/wrn/coreip + +# List of external libraries and their directories +LIBS_LIST := . +LIB_DIRS := . +ifneq ($(OPENSSL_LIB), ) +LIBS_LIST += crypto ssl +LIB_DIRS += $(OPENSSL_LIB) +endif +ifneq ($(ZLIB_LIB), ) +LIBS_LIST += z +LIB_DIRS += $(ZLIB_LIB) +endif +ifneq ($(ARES_LIB), ) +LIBS_LIST += ares +LIB_DIRS += $(ARES_LIB) +endif + +# Add include and library directories and libraries +CFLAGS += $(INCLUDE_DIRS:%=$(INCLUDE_FLAG)%) +LDFLAGS += $(LIB_DIRS:%=$(LIBS_DIRFLAG)%) + +# List of targets to make for libs target +LIBS_TARGET_LIST := libcurl.a + +# List of execuatble applications to make in addition to libs for all target +EXE_TARGET_LIST := + +# Support for echoing rules +# If ECHORULES variable was set (for example, using 'make' command line) +# some shell commands in the rules will be echoed +ifneq ($(strip $(findstring $(ECHORULES), yes YES 1 true TRUE)),) +_@_ := +else +_@_ := @ +endif + +# Directory to hold compilation intermediate files +TMP_DIR := tmp + +# Get sources and headers to be compiled +include Makefile.inc + +# List of headers +INCLUDE_FILES := $(HHEADERS) +INCLUDE_FILES += $(shell find ../include -name \*.h) + +# List of sources +OBJLIST := $(CSOURCES:%.c=$(TMP_DIR)/%$(OBJ_EXTENSION)) + + +# ---------------------------------------------------------------------- + +#### default rule +# It should be first rule in this file +.PHONY: default +default: libcurl.a + +#### Compiling C files +$(TMP_DIR)/%$(OBJ_EXTENSION): %.c $(MAKEFILES) + @echo Compiling C file $< $(ECHO_STDOUT) + @[ -d $(@D) ] || mkdir -p $(@D) + $(_@_) $(TOOL_CHAIN_BIN)$(CC) $(COMPILE_ONLY_FLAG) $(CFLAGS) $< $(CC_OBJ_OUTPUT) + +#### Creating library +$(LIBS_TARGET_LIST): $(INCLUDE_FILES) $(MAKEFILES) $(OBJLIST) + @echo Creating library $@ $(ECHO_STDOUT) + $(_@_) [ -d $(@D) ] || mkdir -p $(@D) + $(_@_) rm -f $@ + $(_@_) $(TOOL_CHAIN_BIN)$(AR) $(ARFLAGS) $@ $(filter %$(OBJ_EXTENSION), $^) + +#### Creating application +$(EXE_TARGET_LIST): $(INCLUDE_FILES) $(MAKEFILES) $(LIBS_TARGET_LIST) + @echo Creating application $@ + @[ -d $(@D) ] || mkdir -p $(@D) + $(_@_) $(TOOL_CHAIN_BIN)$(LINK) $(CC_OBJ_OUTPUT) $($(@)_EXE_OBJ_LIST) $(LDFLAGS) $($(@)_EXE_LIBS_NEEDED:%=$(LIBS_FLAG)%) $(LIBS_LIST:%=$(LIBS_FLAG)%) $(USER_LIBS_LIST) $(USER_LIBS_LIST) + +#### Master Targets +libs: $(LIBS_TARGET_LIST) + @echo All libs made. + +all: $(LIBS_TARGET_LIST) $(EXE_TARGET_LIST) $(INCLUDE_TARGET_LIST) + @echo All targets made. + +# Clean up +.PHONY: clean +clean: + $(_@_) rm -rf $(TMP_DIR) + @echo libcurl was cleaned. diff --git a/libcurl/lib/altsvc.c b/libcurl/lib/altsvc.c new file mode 100644 index 0000000..85a4e01 --- /dev/null +++ b/libcurl/lib/altsvc.c @@ -0,0 +1,569 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + * The Alt-Svc: header is defined in RFC 7838: + * https://tools.ietf.org/html/rfc7838 + */ +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC) +#include +#include "urldata.h" +#include "altsvc.h" +#include "curl_get_line.h" +#include "strcase.h" +#include "parsedate.h" +#include "sendf.h" +#include "warnless.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#define MAX_ALTSVC_LINE 4095 +#define MAX_ALTSVC_DATELENSTR "64" +#define MAX_ALTSVC_DATELEN 64 +#define MAX_ALTSVC_HOSTLENSTR "512" +#define MAX_ALTSVC_HOSTLEN 512 +#define MAX_ALTSVC_ALPNLENSTR "10" +#define MAX_ALTSVC_ALPNLEN 10 + +static enum alpnid alpn2alpnid(char *name) +{ + if(strcasecompare(name, "h1")) + return ALPN_h1; + if(strcasecompare(name, "h2")) + return ALPN_h2; + if(strcasecompare(name, "h2c")) + return ALPN_h2c; + if(strcasecompare(name, "h3")) + return ALPN_h3; + return ALPN_none; /* unknown, probably rubbish input */ +} + +/* Given the ALPN ID, return the name */ +const char *Curl_alpnid2str(enum alpnid id) +{ + switch(id) { + case ALPN_h1: + return "h1"; + case ALPN_h2: + return "h2"; + case ALPN_h2c: + return "h2c"; + case ALPN_h3: + return "h3"; + default: + return ""; /* bad */ + } +} + + +static void altsvc_free(struct altsvc *as) +{ + free(as->srchost); + free(as->dsthost); + free(as); +} + +static struct altsvc *altsvc_createid(const char *srchost, + const char *dsthost, + enum alpnid srcalpnid, + enum alpnid dstalpnid, + unsigned int srcport, + unsigned int dstport) +{ + struct altsvc *as = calloc(sizeof(struct altsvc), 1); + if(!as) + return NULL; + + as->srchost = strdup(srchost); + if(!as->srchost) + goto error; + as->dsthost = strdup(dsthost); + if(!as->dsthost) + goto error; + + as->srcalpnid = srcalpnid; + as->dstalpnid = dstalpnid; + as->srcport = curlx_ultous(srcport); + as->dstport = curlx_ultous(dstport); + + return as; + error: + altsvc_free(as); + return NULL; +} + +static struct altsvc *altsvc_create(char *srchost, + char *dsthost, + char *srcalpn, + char *dstalpn, + unsigned int srcport, + unsigned int dstport) +{ + enum alpnid dstalpnid = alpn2alpnid(dstalpn); + enum alpnid srcalpnid = alpn2alpnid(srcalpn); + if(!srcalpnid || !dstalpnid) + return NULL; + return altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid, + srcport, dstport); +} + +/* only returns SERIOUS errors */ +static CURLcode altsvc_add(struct altsvcinfo *asi, char *line) +{ + /* Example line: + h2 example.com 443 h3 shiny.example.com 8443 "20191231 10:00:00" 1 + */ + char srchost[MAX_ALTSVC_HOSTLEN + 1]; + char dsthost[MAX_ALTSVC_HOSTLEN + 1]; + char srcalpn[MAX_ALTSVC_ALPNLEN + 1]; + char dstalpn[MAX_ALTSVC_ALPNLEN + 1]; + char date[MAX_ALTSVC_DATELEN + 1]; + unsigned int srcport; + unsigned int dstport; + unsigned int prio; + unsigned int persist; + int rc; + + rc = sscanf(line, + "%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u " + "%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u " + "\"%" MAX_ALTSVC_DATELENSTR "[^\"]\" %u %u", + srcalpn, srchost, &srcport, + dstalpn, dsthost, &dstport, + date, &persist, &prio); + if(9 == rc) { + struct altsvc *as; + time_t expires = curl_getdate(date, NULL); + as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport); + if(as) { + as->expires = expires; + as->prio = prio; + as->persist = persist ? 1 : 0; + Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node); + asi->num++; /* one more entry */ + } + } + + return CURLE_OK; +} + +/* + * Load alt-svc entries from the given file. The text based line-oriented file + * format is documented here: + * https://github.com/curl/curl/wiki/QUIC-implementation + * + * This function only returns error on major problems that prevents alt-svc + * handling to work completely. It will ignore individual syntactical errors + * etc. + */ +static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file) +{ + CURLcode result = CURLE_OK; + char *line = NULL; + FILE *fp = fopen(file, FOPEN_READTEXT); + if(fp) { + line = malloc(MAX_ALTSVC_LINE); + if(!line) + goto fail; + while(Curl_get_line(line, MAX_ALTSVC_LINE, fp)) { + char *lineptr = line; + while(*lineptr && ISBLANK(*lineptr)) + lineptr++; + if(*lineptr == '#') + /* skip commented lines */ + continue; + + altsvc_add(asi, lineptr); + } + free(line); /* free the line buffer */ + fclose(fp); + } + return result; + + fail: + free(line); + fclose(fp); + return CURLE_OUT_OF_MEMORY; +} + +/* + * Write this single altsvc entry to a single output line + */ + +static CURLcode altsvc_out(struct altsvc *as, FILE *fp) +{ + struct tm stamp; + CURLcode result = Curl_gmtime(as->expires, &stamp); + if(result) + return result; + + fprintf(fp, + "%s %s %u " + "%s %s %u " + "\"%d%02d%02d " + "%02d:%02d:%02d\" " + "%u %d\n", + Curl_alpnid2str(as->srcalpnid), as->srchost, as->srcport, + Curl_alpnid2str(as->dstalpnid), as->dsthost, as->dstport, + stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday, + stamp.tm_hour, stamp.tm_min, stamp.tm_sec, + as->persist, as->prio); + return CURLE_OK; +} + +/* ---- library-wide functions below ---- */ + +/* + * Curl_altsvc_init() creates a new altsvc cache. + * It returns the new instance or NULL if something goes wrong. + */ +struct altsvcinfo *Curl_altsvc_init(void) +{ + struct altsvcinfo *asi = calloc(sizeof(struct altsvcinfo), 1); + if(!asi) + return NULL; + Curl_llist_init(&asi->list, NULL); + + /* set default behavior */ + asi->flags = CURLALTSVC_H1 +#ifdef USE_NGHTTP2 + | CURLALTSVC_H2 +#endif +#ifdef USE_HTTP3 + | CURLALTSVC_H3 +#endif + ; + return asi; +} + +/* + * Curl_altsvc_load() loads alt-svc from file. + */ +CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file) +{ + CURLcode result; + DEBUGASSERT(asi); + result = altsvc_load(asi, file); + return result; +} + +/* + * Curl_altsvc_ctrl() passes on the external bitmask. + */ +CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl) +{ + DEBUGASSERT(asi); + if(!ctrl) + /* unexpected */ + return CURLE_BAD_FUNCTION_ARGUMENT; + asi->flags = ctrl; + return CURLE_OK; +} + +/* + * Curl_altsvc_cleanup() frees an altsvc cache instance and all associated + * resources. + */ +void Curl_altsvc_cleanup(struct altsvcinfo *altsvc) +{ + struct curl_llist_element *e; + struct curl_llist_element *n; + if(altsvc) { + for(e = altsvc->list.head; e; e = n) { + struct altsvc *as = e->ptr; + n = e->next; + altsvc_free(as); + } + free(altsvc); + } +} + +/* + * Curl_altsvc_save() writes the altsvc cache to a file. + */ +CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file) +{ + struct curl_llist_element *e; + struct curl_llist_element *n; + CURLcode result = CURLE_OK; + FILE *out; + + if(!altsvc) + /* no cache activated */ + return CURLE_OK; + + if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file[0]) + /* marked as read-only or zero length file name */ + return CURLE_OK; + out = fopen(file, FOPEN_WRITETEXT); + if(!out) + return CURLE_WRITE_ERROR; + fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n" + "# This file was generated by libcurl! Edit at your own risk.\n", + out); + for(e = altsvc->list.head; e; e = n) { + struct altsvc *as = e->ptr; + n = e->next; + result = altsvc_out(as, out); + if(result) + break; + } + fclose(out); + return result; +} + +static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen) +{ + size_t len; + const char *protop; + const char *p = *ptr; + while(*p && ISBLANK(*p)) + p++; + protop = p; + while(*p && ISALNUM(*p)) + p++; + len = p - protop; + + if(!len || (len >= buflen)) + return CURLE_BAD_FUNCTION_ARGUMENT; + memcpy(alpnbuf, protop, len); + alpnbuf[len] = 0; + *ptr = p; + return CURLE_OK; +} + +/* altsvc_flush() removes all alternatives for this source origin from the + list */ +static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid, + const char *srchost, unsigned short srcport) +{ + struct curl_llist_element *e; + struct curl_llist_element *n; + for(e = asi->list.head; e; e = n) { + struct altsvc *as = e->ptr; + n = e->next; + if((srcalpnid == as->srcalpnid) && + (srcport == as->srcport) && + strcasecompare(srchost, as->srchost)) { + Curl_llist_remove(&asi->list, e, NULL); + altsvc_free(as); + asi->num--; + } + } +} + +#ifdef DEBUGBUILD +/* to play well with debug builds, we can *set* a fixed time this will + return */ +static time_t debugtime(void *unused) +{ + char *timestr = getenv("CURL_TIME"); + (void)unused; + if(timestr) { + unsigned long val = strtol(timestr, NULL, 10); + return (time_t)val; + } + return time(NULL); +} +#define time(x) debugtime(x) +#endif + +/* + * Curl_altsvc_parse() takes an incoming alt-svc response header and stores + * the data correctly in the cache. + * + * 'value' points to the header *value*. That's contents to the right of the + * header name. + */ +CURLcode Curl_altsvc_parse(struct Curl_easy *data, + struct altsvcinfo *asi, const char *value, + enum alpnid srcalpnid, const char *srchost, + unsigned short srcport) +{ + const char *p = value; + size_t len; + enum alpnid dstalpnid = srcalpnid; /* the same by default */ + char namebuf[MAX_ALTSVC_HOSTLEN] = ""; + char alpnbuf[MAX_ALTSVC_ALPNLEN] = ""; + struct altsvc *as; + unsigned short dstport = srcport; /* the same by default */ + const char *semip; + time_t maxage = 24 * 3600; /* default is 24 hours */ + bool persist = FALSE; + CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf)); + if(result) + return result; + + DEBUGASSERT(asi); + + /* Flush all cached alternatives for this source origin, if any */ + altsvc_flush(asi, srcalpnid, srchost, srcport); + + /* "clear" is a magic keyword */ + if(strcasecompare(alpnbuf, "clear")) { + return CURLE_OK; + } + + /* The 'ma' and 'persist' flags are annoyingly meant for all alternatives + but are set after the list on the line. Scan for the semicolons and get + those fields first! */ + semip = p; + do { + semip = strchr(semip, ';'); + if(semip) { + char option[32]; + unsigned long num; + char *end_ptr; + semip++; /* pass the semicolon */ + result = getalnum(&semip, option, sizeof(option)); + if(result) + break; + while(*semip && ISBLANK(*semip)) + semip++; + if(*semip != '=') + continue; + semip++; + num = strtoul(semip, &end_ptr, 10); + if(num < ULONG_MAX) { + if(strcasecompare("ma", option)) + maxage = num; + else if(strcasecompare("persist", option) && (num == 1)) + persist = TRUE; + } + semip = end_ptr; + } + } while(semip); + + do { + if(*p == '=') { + /* [protocol]="[host][:port]" */ + dstalpnid = alpn2alpnid(alpnbuf); + if(!dstalpnid) { + infof(data, "Unknown alt-svc protocol \"%s\", ignoring...\n", alpnbuf); + return CURLE_OK; + } + p++; + if(*p == '\"') { + const char *dsthost; + p++; + if(*p != ':') { + /* host name starts here */ + const char *hostp = p; + while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-'))) + p++; + len = p - hostp; + if(!len || (len >= MAX_ALTSVC_HOSTLEN)) + return CURLE_BAD_FUNCTION_ARGUMENT; + memcpy(namebuf, hostp, len); + namebuf[len] = 0; + dsthost = namebuf; + } + else { + /* no destination name, use source host */ + dsthost = srchost; + } + if(*p == ':') { + /* a port number */ + char *end_ptr; + unsigned long port = strtoul(++p, &end_ptr, 10); + if(port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') { + infof(data, "Unknown alt-svc port number, ignoring...\n"); + return CURLE_OK; + } + p = end_ptr; + dstport = curlx_ultous(port); + } + if(*p++ != '\"') + return CURLE_BAD_FUNCTION_ARGUMENT; + as = altsvc_createid(srchost, dsthost, + srcalpnid, dstalpnid, + srcport, dstport); + if(as) { + /* The expires time also needs to take the Age: value (if any) into + account. [See RFC 7838 section 3.1] */ + as->expires = maxage + time(NULL); + as->persist = persist; + Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node); + asi->num++; /* one more entry */ + infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport, + Curl_alpnid2str(dstalpnid)); + } + } + /* after the double quote there can be a comma if there's another + string or a semicolon if no more */ + if(*p == ',') { + /* comma means another alternative is presented */ + p++; + result = getalnum(&p, alpnbuf, sizeof(alpnbuf)); + if(result) + /* failed to parse, but since we already did at least one host we + return OK */ + return CURLE_OK; + } + } + } while(*p && (*p != ';') && (*p != '\n') && (*p != '\r')); + + return CURLE_OK; +} + +/* + * Return TRUE on a match + */ +bool Curl_altsvc_lookup(struct altsvcinfo *asi, + enum alpnid srcalpnid, const char *srchost, + int srcport, + enum alpnid *dstalpnid, const char **dsthost, + int *dstport) +{ + struct curl_llist_element *e; + struct curl_llist_element *n; + time_t now = time(NULL); + DEBUGASSERT(asi); + DEBUGASSERT(srchost); + DEBUGASSERT(dsthost); + + for(e = asi->list.head; e; e = n) { + struct altsvc *as = e->ptr; + n = e->next; + if(as->expires < now) { + /* an expired entry, remove */ + altsvc_free(as); + continue; + } + if((as->srcalpnid == srcalpnid) && + strcasecompare(as->srchost, srchost) && + as->srcport == srcport) { + /* match */ + *dstalpnid = as->dstalpnid; + *dsthost = as->dsthost; + *dstport = as->dstport; + return TRUE; + } + } + return FALSE; +} + +#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */ diff --git a/libcurl/lib/altsvc.h b/libcurl/lib/altsvc.h new file mode 100644 index 0000000..eefb45b --- /dev/null +++ b/libcurl/lib/altsvc.h @@ -0,0 +1,77 @@ +#ifndef HEADER_CURL_ALTSVC_H +#define HEADER_CURL_ALTSVC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC) +#include +#include "llist.h" + +enum alpnid { + ALPN_none, + ALPN_h1, + ALPN_h2, + ALPN_h2c, + ALPN_h3 +}; + +struct altsvc { + char *srchost; + char *dsthost; + unsigned short srcport; + unsigned short dstport; + enum alpnid srcalpnid; + enum alpnid dstalpnid; + time_t expires; + bool persist; + int prio; + struct curl_llist_element node; +}; + +struct altsvcinfo { + char *filename; + struct curl_llist list; /* list of entries */ + size_t num; /* number of alt-svc entries */ + long flags; /* the publicly set bitmask */ +}; + +const char *Curl_alpnid2str(enum alpnid id); +struct altsvcinfo *Curl_altsvc_init(void); +CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file); +CURLcode Curl_altsvc_save(struct altsvcinfo *asi, const char *file); +CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl); +void Curl_altsvc_cleanup(struct altsvcinfo *altsvc); +CURLcode Curl_altsvc_parse(struct Curl_easy *data, + struct altsvcinfo *altsvc, const char *value, + enum alpnid srcalpn, const char *srchost, + unsigned short srcport); +bool Curl_altsvc_lookup(struct altsvcinfo *asi, + enum alpnid srcalpnid, const char *srchost, + int srcport, + enum alpnid *dstalpnid, const char **dsthost, + int *dstport); +#else +/* disabled */ +#define Curl_altsvc_save(a,b) +#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */ +#endif /* HEADER_CURL_ALTSVC_H */ diff --git a/libcurl/lib/amigaos.c b/libcurl/lib/amigaos.c new file mode 100644 index 0000000..cf44bdc --- /dev/null +++ b/libcurl/lib/amigaos.c @@ -0,0 +1,95 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef __AMIGA__ +# include "amigaos.h" +# if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL) +# include +# endif +# ifdef __libnix__ +# include +# endif +#endif + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +#ifdef __AMIGA__ +#if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL) +struct Library *SocketBase = NULL; +extern int errno, h_errno; + +#ifdef __libnix__ +void __request(const char *msg); +#else +# define __request(msg) Printf(msg "\n\a") +#endif + +void Curl_amiga_cleanup() +{ + if(SocketBase) { + CloseLibrary(SocketBase); + SocketBase = NULL; + } +} + +bool Curl_amiga_init() +{ + if(!SocketBase) + SocketBase = OpenLibrary("bsdsocket.library", 4); + + if(!SocketBase) { + __request("No TCP/IP Stack running!"); + return FALSE; + } + + if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno, + SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl", + TAG_DONE)) { + __request("SocketBaseTags ERROR"); + return FALSE; + } + +#ifndef __libnix__ + atexit(Curl_amiga_cleanup); +#endif + + return TRUE; +} + +#ifdef __libnix__ +ADD2EXIT(Curl_amiga_cleanup, -50); +#endif + +#endif /* HAVE_PROTO_BSDSOCKET_H */ + +#ifdef USE_AMISSL +void Curl_amiga_X509_free(X509 *a) +{ + X509_free(a); +} +#endif /* USE_AMISSL */ +#endif /* __AMIGA__ */ + diff --git a/libcurl/lib/amigaos.h b/libcurl/lib/amigaos.h new file mode 100644 index 0000000..c776c9c --- /dev/null +++ b/libcurl/lib/amigaos.h @@ -0,0 +1,44 @@ +#ifndef HEADER_CURL_AMIGAOS_H +#define HEADER_CURL_AMIGAOS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#if defined(__AMIGA__) && defined(HAVE_BSDSOCKET_H) && !defined(USE_AMISSL) + +bool Curl_amiga_init(); +void Curl_amiga_cleanup(); + +#else + +#define Curl_amiga_init() 1 +#define Curl_amiga_cleanup() Curl_nop_stmt + +#endif + +#ifdef USE_AMISSL +#include +void Curl_amiga_X509_free(X509 *a); +#endif /* USE_AMISSL */ + +#endif /* HEADER_CURL_AMIGAOS_H */ + diff --git a/libcurl/lib/arpa_telnet.h b/libcurl/lib/arpa_telnet.h new file mode 100644 index 0000000..232680e --- /dev/null +++ b/libcurl/lib/arpa_telnet.h @@ -0,0 +1,108 @@ +#ifndef HEADER_CURL_ARPA_TELNET_H +#define HEADER_CURL_ARPA_TELNET_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifndef CURL_DISABLE_TELNET +/* + * Telnet option defines. Add more here if in need. + */ +#define CURL_TELOPT_BINARY 0 /* binary 8bit data */ +#define CURL_TELOPT_ECHO 1 /* just echo! */ +#define CURL_TELOPT_SGA 3 /* Suppress Go Ahead */ +#define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */ +#define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */ +#define CURL_TELOPT_NAWS 31 /* Negotiate About Window Size */ +#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */ + +#define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */ +#define CURL_NEW_ENV_VAR 0 +#define CURL_NEW_ENV_VALUE 1 + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +/* + * The telnet options represented as strings + */ +static const char * const telnetoptions[]= +{ + "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", + "NAME", "STATUS", "TIMING MARK", "RCTE", + "NAOL", "NAOP", "NAOCRD", "NAOHTS", + "NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD", + "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", + "DE TERMINAL", "SUPDUP", "SUPDUP OUTPUT", "SEND LOCATION", + "TERM TYPE", "END OF RECORD", "TACACS UID", "OUTPUT MARKING", + "TTYLOC", "3270 REGIME", "X3 PAD", "NAWS", + "TERM SPEED", "LFLOW", "LINEMODE", "XDISPLOC", + "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON" +}; +#endif + +#define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON + +#define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM) +#define CURL_TELOPT(x) telnetoptions[x] + +#define CURL_NTELOPTS 40 + +/* + * First some defines + */ +#define CURL_xEOF 236 /* End Of File */ +#define CURL_SE 240 /* Sub negotiation End */ +#define CURL_NOP 241 /* No OPeration */ +#define CURL_DM 242 /* Data Mark */ +#define CURL_GA 249 /* Go Ahead, reverse the line */ +#define CURL_SB 250 /* SuBnegotiation */ +#define CURL_WILL 251 /* Our side WILL use this option */ +#define CURL_WONT 252 /* Our side WON'T use this option */ +#define CURL_DO 253 /* DO use this option! */ +#define CURL_DONT 254 /* DON'T use this option! */ +#define CURL_IAC 255 /* Interpret As Command */ + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +/* + * Then those numbers represented as strings: + */ +static const char * const telnetcmds[]= +{ + "EOF", "SUSP", "ABORT", "EOR", "SE", + "NOP", "DMARK", "BRK", "IP", "AO", + "AYT", "EC", "EL", "GA", "SB", + "WILL", "WONT", "DO", "DONT", "IAC" +}; +#endif + +#define CURL_TELCMD_MINIMUM CURL_xEOF /* the first one */ +#define CURL_TELCMD_MAXIMUM CURL_IAC /* surprise, 255 is the last one! ;-) */ + +#define CURL_TELQUAL_IS 0 +#define CURL_TELQUAL_SEND 1 +#define CURL_TELQUAL_INFO 2 +#define CURL_TELQUAL_NAME 3 + +#define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \ + ((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) ) +#define CURL_TELCMD(x) telnetcmds[(x)-CURL_TELCMD_MINIMUM] + +#endif /* CURL_DISABLE_TELNET */ + +#endif /* HEADER_CURL_ARPA_TELNET_H */ diff --git a/libcurl/lib/asyn-ares.c b/libcurl/lib/asyn-ares.c new file mode 100644 index 0000000..6b14aa6 --- /dev/null +++ b/libcurl/lib/asyn-ares.c @@ -0,0 +1,830 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +/*********************************************************************** + * Only for ares-enabled builds + * And only for functions that fulfill the asynch resolver backend API + * as defined in asyn.h, nothing else belongs in this file! + **********************************************************************/ + +#ifdef CURLRES_ARES + +#include +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#ifdef HAVE_PROCESS_H +#include +#endif + +#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "hash.h" +#include "share.h" +#include "strerror.h" +#include "url.h" +#include "multiif.h" +#include "inet_pton.h" +#include "connect.h" +#include "select.h" +#include "progress.h" + +# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ + (defined(WIN32) || defined(__SYMBIAN32__)) +# define CARES_STATICLIB +# endif +# include +# include /* really old c-ares didn't include this by + itself */ + +#if ARES_VERSION >= 0x010500 +/* c-ares 1.5.0 or later, the callback proto is modified */ +#define HAVE_CARES_CALLBACK_TIMEOUTS 1 +#endif + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +struct ResolverResults { + int num_pending; /* number of ares_gethostbyname() requests */ + Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */ + int last_status; + struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */ +}; + +/* How long we are willing to wait for additional parallel responses after + obtaining a "definitive" one. + + This is intended to equal the c-ares default timeout. cURL always uses that + default value. Unfortunately, c-ares doesn't expose its default timeout in + its API, but it is officially documented as 5 seconds. + + See query_completed_cb() for an explanation of how this is used. + */ +#define HAPPY_EYEBALLS_DNS_TIMEOUT 5000 + +/* + * Curl_resolver_global_init() - the generic low-level asynchronous name + * resolve API. Called from curl_global_init() to initialize global resolver + * environment. Initializes ares library. + */ +int Curl_resolver_global_init(void) +{ +#ifdef CARES_HAVE_ARES_LIBRARY_INIT + if(ares_library_init(ARES_LIB_INIT_ALL)) { + return CURLE_FAILED_INIT; + } +#endif + return CURLE_OK; +} + +/* + * Curl_resolver_global_cleanup() + * + * Called from curl_global_cleanup() to destroy global resolver environment. + * Deinitializes ares library. + */ +void Curl_resolver_global_cleanup(void) +{ +#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP + ares_library_cleanup(); +#endif +} + + +static void Curl_ares_sock_state_cb(void *data, ares_socket_t socket_fd, + int readable, int writable) +{ + struct Curl_easy *easy = data; + if(!readable && !writable) { + DEBUGASSERT(easy); + Curl_multi_closed(easy, socket_fd); + } +} + +/* + * Curl_resolver_init() + * + * Called from curl_easy_init() -> Curl_open() to initialize resolver + * URL-state specific environment ('resolver' member of the UrlState + * structure). Fills the passed pointer by the initialized ares_channel. + */ +CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver) +{ + int status; + struct ares_options options; + int optmask = ARES_OPT_SOCK_STATE_CB; + options.sock_state_cb = Curl_ares_sock_state_cb; + options.sock_state_cb_data = easy; + status = ares_init_options((ares_channel*)resolver, &options, optmask); + if(status != ARES_SUCCESS) { + if(status == ARES_ENOMEM) + return CURLE_OUT_OF_MEMORY; + else + return CURLE_FAILED_INIT; + } + return CURLE_OK; + /* make sure that all other returns from this function should destroy the + ares channel before returning error! */ +} + +/* + * Curl_resolver_cleanup() + * + * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver + * URL-state specific environment ('resolver' member of the UrlState + * structure). Destroys the ares channel. + */ +void Curl_resolver_cleanup(void *resolver) +{ + ares_destroy((ares_channel)resolver); +} + +/* + * Curl_resolver_duphandle() + * + * Called from curl_easy_duphandle() to duplicate resolver URL-state specific + * environment ('resolver' member of the UrlState structure). Duplicates the + * 'from' ares channel and passes the resulting channel to the 'to' pointer. + */ +CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from) +{ + (void)from; + /* + * it would be better to call ares_dup instead, but right now + * it is not possible to set 'sock_state_cb_data' outside of + * ares_init_options + */ + return Curl_resolver_init(easy, to); +} + +static void destroy_async_data(struct Curl_async *async); + +/* + * Cancel all possibly still on-going resolves for this connection. + */ +void Curl_resolver_cancel(struct connectdata *conn) +{ + if(conn->data && conn->data->state.resolver) + ares_cancel((ares_channel)conn->data->state.resolver); + destroy_async_data(&conn->async); +} + +/* + * We're equivalent to Curl_resolver_cancel() for the c-ares resolver. We + * never block. + */ +void Curl_resolver_kill(struct connectdata *conn) +{ + /* We don't need to check the resolver state because we can be called safely + at any time and we always do the same thing. */ + Curl_resolver_cancel(conn); +} + +/* + * destroy_async_data() cleans up async resolver data. + */ +static void destroy_async_data(struct Curl_async *async) +{ + free(async->hostname); + + if(async->os_specific) { + struct ResolverResults *res = (struct ResolverResults *)async->os_specific; + if(res) { + if(res->temp_ai) { + Curl_freeaddrinfo(res->temp_ai); + res->temp_ai = NULL; + } + free(res); + } + async->os_specific = NULL; + } + + async->hostname = NULL; +} + +/* + * Curl_resolver_getsock() is called when someone from the outside world + * (using curl_multi_fdset()) wants to get our fd_set setup and we're talking + * with ares. The caller must make sure that this function is only called when + * we have a working ares channel. + * + * Returns: sockets-in-use-bitmap + */ + +int Curl_resolver_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) + +{ + struct timeval maxtime; + struct timeval timebuf; + struct timeval *timeout; + long milli; + int max = ares_getsock((ares_channel)conn->data->state.resolver, + (ares_socket_t *)socks, numsocks); + + maxtime.tv_sec = CURL_TIMEOUT_RESOLVE; + maxtime.tv_usec = 0; + + timeout = ares_timeout((ares_channel)conn->data->state.resolver, &maxtime, + &timebuf); + milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000); + if(milli == 0) + milli += 10; + Curl_expire(conn->data, milli, EXPIRE_ASYNC_NAME); + + return max; +} + +/* + * waitperform() + * + * 1) Ask ares what sockets it currently plays with, then + * 2) wait for the timeout period to check for action on ares' sockets. + * 3) tell ares to act on all the sockets marked as "with action" + * + * return number of sockets it worked on + */ + +static int waitperform(struct connectdata *conn, int timeout_ms) +{ + struct Curl_easy *data = conn->data; + int nfds; + int bitmask; + ares_socket_t socks[ARES_GETSOCK_MAXNUM]; + struct pollfd pfd[ARES_GETSOCK_MAXNUM]; + int i; + int num = 0; + + bitmask = ares_getsock((ares_channel)data->state.resolver, socks, + ARES_GETSOCK_MAXNUM); + + for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) { + pfd[i].events = 0; + pfd[i].revents = 0; + if(ARES_GETSOCK_READABLE(bitmask, i)) { + pfd[i].fd = socks[i]; + pfd[i].events |= POLLRDNORM|POLLIN; + } + if(ARES_GETSOCK_WRITABLE(bitmask, i)) { + pfd[i].fd = socks[i]; + pfd[i].events |= POLLWRNORM|POLLOUT; + } + if(pfd[i].events != 0) + num++; + else + break; + } + + if(num) + nfds = Curl_poll(pfd, num, timeout_ms); + else + nfds = 0; + + if(!nfds) + /* Call ares_process() unconditonally here, even if we simply timed out + above, as otherwise the ares name resolve won't timeout! */ + ares_process_fd((ares_channel)data->state.resolver, ARES_SOCKET_BAD, + ARES_SOCKET_BAD); + else { + /* move through the descriptors and ask for processing on them */ + for(i = 0; i < num; i++) + ares_process_fd((ares_channel)data->state.resolver, + (pfd[i].revents & (POLLRDNORM|POLLIN))? + pfd[i].fd:ARES_SOCKET_BAD, + (pfd[i].revents & (POLLWRNORM|POLLOUT))? + pfd[i].fd:ARES_SOCKET_BAD); + } + return nfds; +} + +/* + * Curl_resolver_is_resolved() is called repeatedly to check if a previous + * name resolve request has completed. It should also make sure to time-out if + * the operation seems to take too long. + * + * Returns normal CURLcode errors. + */ +CURLcode Curl_resolver_is_resolved(struct connectdata *conn, + struct Curl_dns_entry **dns) +{ + struct Curl_easy *data = conn->data; + struct ResolverResults *res = (struct ResolverResults *) + conn->async.os_specific; + CURLcode result = CURLE_OK; + + if(dns) + *dns = NULL; + + waitperform(conn, 0); + + /* Now that we've checked for any last minute results above, see if there are + any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer + expires. */ + if(res + && res->num_pending + /* This is only set to non-zero if the timer was started. */ + && (res->happy_eyeballs_dns_time.tv_sec + || res->happy_eyeballs_dns_time.tv_usec) + && (Curl_timediff(Curl_now(), res->happy_eyeballs_dns_time) + >= HAPPY_EYEBALLS_DNS_TIMEOUT)) { + /* Remember that the EXPIRE_HAPPY_EYEBALLS_DNS timer is no longer + running. */ + memset( + &res->happy_eyeballs_dns_time, 0, sizeof(res->happy_eyeballs_dns_time)); + + /* Cancel the raw c-ares request, which will fire query_completed_cb() with + ARES_ECANCELLED synchronously for all pending responses. This will + leave us with res->num_pending == 0, which is perfect for the next + block. */ + ares_cancel((ares_channel)data->state.resolver); + DEBUGASSERT(res->num_pending == 0); + } + + if(res && !res->num_pending) { + if(dns) { + (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai); + /* temp_ai ownership is moved to the connection, so we need not free-up + them */ + res->temp_ai = NULL; + } + if(!conn->async.dns) { + failf(data, "Could not resolve: %s (%s)", + conn->async.hostname, ares_strerror(conn->async.status)); + result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY: + CURLE_COULDNT_RESOLVE_HOST; + } + else if(dns) + *dns = conn->async.dns; + + destroy_async_data(&conn->async); + } + + return result; +} + +/* + * Curl_resolver_wait_resolv() + * + * Waits for a resolve to finish. This function should be avoided since using + * this risk getting the multi interface to "hang". + * + * If 'entry' is non-NULL, make it point to the resolved dns entry + * + * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, + * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors. + */ +CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, + struct Curl_dns_entry **entry) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + timediff_t timeout; + struct curltime now = Curl_now(); + struct Curl_dns_entry *temp_entry; + + if(entry) + *entry = NULL; /* clear on entry */ + + timeout = Curl_timeleft(data, &now, TRUE); + if(timeout < 0) { + /* already expired! */ + connclose(conn, "Timed out before name resolve started"); + return CURLE_OPERATION_TIMEDOUT; + } + if(!timeout) + timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */ + + /* Wait for the name resolve query to complete. */ + while(!result) { + struct timeval *tvp, tv, store; + int itimeout; + int timeout_ms; + + itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout; + + store.tv_sec = itimeout/1000; + store.tv_usec = (itimeout%1000)*1000; + + tvp = ares_timeout((ares_channel)data->state.resolver, &store, &tv); + + /* use the timeout period ares returned to us above if less than one + second is left, otherwise just use 1000ms to make sure the progress + callback gets called frequent enough */ + if(!tvp->tv_sec) + timeout_ms = (int)(tvp->tv_usec/1000); + else + timeout_ms = 1000; + + waitperform(conn, timeout_ms); + result = Curl_resolver_is_resolved(conn, entry?&temp_entry:NULL); + + if(result || conn->async.done) + break; + + if(Curl_pgrsUpdate(conn)) + result = CURLE_ABORTED_BY_CALLBACK; + else { + struct curltime now2 = Curl_now(); + timediff_t timediff = Curl_timediff(now2, now); /* spent time */ + if(timediff <= 0) + timeout -= 1; /* always deduct at least 1 */ + else if(timediff > timeout) + timeout = -1; + else + timeout -= (long)timediff; + now = now2; /* for next loop */ + } + if(timeout < 0) + result = CURLE_OPERATION_TIMEDOUT; + } + if(result) + /* failure, so we cancel the ares operation */ + ares_cancel((ares_channel)data->state.resolver); + + /* Operation complete, if the lookup was successful we now have the entry + in the cache. */ + if(entry) + *entry = conn->async.dns; + + if(result) + /* close the connection, since we can't return failure here without + cleaning up this connection properly. */ + connclose(conn, "c-ares resolve failed"); + + return result; +} + +/* Connects results to the list */ +static void compound_results(struct ResolverResults *res, + Curl_addrinfo *ai) +{ + Curl_addrinfo *ai_tail; + if(!ai) + return; + ai_tail = ai; + + while(ai_tail->ai_next) + ai_tail = ai_tail->ai_next; + + /* Add the new results to the list of old results. */ + ai_tail->ai_next = res->temp_ai; + res->temp_ai = ai; +} + +/* + * ares_query_completed_cb() is the callback that ares will call when + * the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(), + * when using ares, is completed either successfully or with failure. + */ +static void query_completed_cb(void *arg, /* (struct connectdata *) */ + int status, +#ifdef HAVE_CARES_CALLBACK_TIMEOUTS + int timeouts, +#endif + struct hostent *hostent) +{ + struct connectdata *conn = (struct connectdata *)arg; + struct ResolverResults *res; + +#ifdef HAVE_CARES_CALLBACK_TIMEOUTS + (void)timeouts; /* ignored */ +#endif + + if(ARES_EDESTRUCTION == status) + /* when this ares handle is getting destroyed, the 'arg' pointer may not + be valid so only defer it when we know the 'status' says its fine! */ + return; + + res = (struct ResolverResults *)conn->async.os_specific; + if(res) { + res->num_pending--; + + if(CURL_ASYNC_SUCCESS == status) { + Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port); + if(ai) { + compound_results(res, ai); + } + } + /* A successful result overwrites any previous error */ + if(res->last_status != ARES_SUCCESS) + res->last_status = status; + + /* If there are responses still pending, we presume they must be the + complementary IPv4 or IPv6 lookups that we started in parallel in + Curl_resolver_getaddrinfo() (for Happy Eyeballs). If we've got a + "definitive" response from one of a set of parallel queries, we need to + think about how long we're willing to wait for more responses. */ + if(res->num_pending + /* Only these c-ares status values count as "definitive" for these + purposes. For example, ARES_ENODATA is what we expect when there is + no IPv6 entry for a domain name, and that's not a reason to get more + aggressive in our timeouts for the other response. Other errors are + either a result of bad input (which should affect all parallel + requests), local or network conditions, non-definitive server + responses, or us cancelling the request. */ + && (status == ARES_SUCCESS || status == ARES_ENOTFOUND)) { + /* Right now, there can only be up to two parallel queries, so don't + bother handling any other cases. */ + DEBUGASSERT(res->num_pending == 1); + + /* It's possible that one of these parallel queries could succeed + quickly, but the other could always fail or timeout (when we're + talking to a pool of DNS servers that can only successfully resolve + IPv4 address, for example). + + It's also possible that the other request could always just take + longer because it needs more time or only the second DNS server can + fulfill it successfully. But, to align with the philosophy of Happy + Eyeballs, we don't want to wait _too_ long or users will think + requests are slow when IPv6 lookups don't actually work (but IPv4 ones + do). + + So, now that we have a usable answer (some IPv4 addresses, some IPv6 + addresses, or "no such domain"), we start a timeout for the remaining + pending responses. Even though it is typical that this resolved + request came back quickly, that needn't be the case. It might be that + this completing request didn't get a result from the first DNS server + or even the first round of the whole DNS server pool. So it could + already be quite some time after we issued the DNS queries in the + first place. Without modifying c-ares, we can't know exactly where in + its retry cycle we are. We could guess based on how much time has + gone by, but it doesn't really matter. Happy Eyeballs tells us that, + given usable information in hand, we simply don't want to wait "too + much longer" after we get a result. + + We simply wait an additional amount of time equal to the default + c-ares query timeout. That is enough time for a typical parallel + response to arrive without being "too long". Even on a network + where one of the two types of queries is failing or timing out + constantly, this will usually mean we wait a total of the default + c-ares timeout (5 seconds) plus the round trip time for the successful + request, which seems bearable. The downside is that c-ares might race + with us to issue one more retry just before we give up, but it seems + better to "waste" that request instead of trying to guess the perfect + timeout to prevent it. After all, we don't even know where in the + c-ares retry cycle each request is. + */ + res->happy_eyeballs_dns_time = Curl_now(); + Curl_expire( + conn->data, HAPPY_EYEBALLS_DNS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS_DNS); + } + } +} + +/* + * Curl_resolver_getaddrinfo() - when using ares + * + * Returns name information about the given hostname and port number. If + * successful, the 'hostent' is returned and the forth argument will point to + * memory we need to free after use. That memory *MUST* be freed with + * Curl_freeaddrinfo(), nothing else. + */ +Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, + const char *hostname, + int port, + int *waitp) +{ + char *bufp; + struct Curl_easy *data = conn->data; + struct in_addr in; + int family = PF_INET; +#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */ + struct in6_addr in6; +#endif /* CURLRES_IPV6 */ + + *waitp = 0; /* default to synchronous response */ + + /* First check if this is an IPv4 address string */ + if(Curl_inet_pton(AF_INET, hostname, &in) > 0) { + /* This is a dotted IP address 123.123.123.123-style */ + return Curl_ip2addr(AF_INET, &in, hostname, port); + } + +#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */ + /* Otherwise, check if this is an IPv6 address string */ + if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0) + /* This must be an IPv6 address literal. */ + return Curl_ip2addr(AF_INET6, &in6, hostname, port); + + switch(conn->ip_version) { + default: +#if ARES_VERSION >= 0x010601 + family = PF_UNSPEC; /* supported by c-ares since 1.6.1, so for older + c-ares versions this just falls through and defaults + to PF_INET */ + break; +#endif + case CURL_IPRESOLVE_V4: + family = PF_INET; + break; + case CURL_IPRESOLVE_V6: + family = PF_INET6; + break; + } +#endif /* CURLRES_IPV6 */ + + bufp = strdup(hostname); + if(bufp) { + struct ResolverResults *res = NULL; + free(conn->async.hostname); + conn->async.hostname = bufp; + conn->async.port = port; + conn->async.done = FALSE; /* not done */ + conn->async.status = 0; /* clear */ + conn->async.dns = NULL; /* clear */ + res = calloc(sizeof(struct ResolverResults), 1); + if(!res) { + free(conn->async.hostname); + conn->async.hostname = NULL; + return NULL; + } + conn->async.os_specific = res; + + /* initial status - failed */ + res->last_status = ARES_ENOTFOUND; +#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */ + if(family == PF_UNSPEC) { + if(Curl_ipv6works()) { + res->num_pending = 2; + + /* areschannel is already setup in the Curl_open() function */ + ares_gethostbyname((ares_channel)data->state.resolver, hostname, + PF_INET, query_completed_cb, conn); + ares_gethostbyname((ares_channel)data->state.resolver, hostname, + PF_INET6, query_completed_cb, conn); + } + else { + res->num_pending = 1; + + /* areschannel is already setup in the Curl_open() function */ + ares_gethostbyname((ares_channel)data->state.resolver, hostname, + PF_INET, query_completed_cb, conn); + } + } + else +#endif /* CURLRES_IPV6 */ + { + res->num_pending = 1; + + /* areschannel is already setup in the Curl_open() function */ + ares_gethostbyname((ares_channel)data->state.resolver, hostname, family, + query_completed_cb, conn); + } + + *waitp = 1; /* expect asynchronous response */ + } + return NULL; /* no struct yet */ +} + +CURLcode Curl_set_dns_servers(struct Curl_easy *data, + char *servers) +{ + CURLcode result = CURLE_NOT_BUILT_IN; + int ares_result; + + /* If server is NULL or empty, this would purge all DNS servers + * from ares library, which will cause any and all queries to fail. + * So, just return OK if none are configured and don't actually make + * any changes to c-ares. This lets c-ares use it's defaults, which + * it gets from the OS (for instance from /etc/resolv.conf on Linux). + */ + if(!(servers && servers[0])) + return CURLE_OK; + +#if (ARES_VERSION >= 0x010704) +#if (ARES_VERSION >= 0x010b00) + ares_result = ares_set_servers_ports_csv(data->state.resolver, servers); +#else + ares_result = ares_set_servers_csv(data->state.resolver, servers); +#endif + switch(ares_result) { + case ARES_SUCCESS: + result = CURLE_OK; + break; + case ARES_ENOMEM: + result = CURLE_OUT_OF_MEMORY; + break; + case ARES_ENOTINITIALIZED: + case ARES_ENODATA: + case ARES_EBADSTR: + default: + result = CURLE_BAD_FUNCTION_ARGUMENT; + break; + } +#else /* too old c-ares version! */ + (void)data; + (void)(ares_result); +#endif + return result; +} + +CURLcode Curl_set_dns_interface(struct Curl_easy *data, + const char *interf) +{ +#if (ARES_VERSION >= 0x010704) + if(!interf) + interf = ""; + + ares_set_local_dev((ares_channel)data->state.resolver, interf); + + return CURLE_OK; +#else /* c-ares version too old! */ + (void)data; + (void)interf; + return CURLE_NOT_BUILT_IN; +#endif +} + +CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data, + const char *local_ip4) +{ +#if (ARES_VERSION >= 0x010704) + struct in_addr a4; + + if((!local_ip4) || (local_ip4[0] == 0)) { + a4.s_addr = 0; /* disabled: do not bind to a specific address */ + } + else { + if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) { + return CURLE_BAD_FUNCTION_ARGUMENT; + } + } + + ares_set_local_ip4((ares_channel)data->state.resolver, ntohl(a4.s_addr)); + + return CURLE_OK; +#else /* c-ares version too old! */ + (void)data; + (void)local_ip4; + return CURLE_NOT_BUILT_IN; +#endif +} + +CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data, + const char *local_ip6) +{ +#if (ARES_VERSION >= 0x010704) && defined(ENABLE_IPV6) + unsigned char a6[INET6_ADDRSTRLEN]; + + if((!local_ip6) || (local_ip6[0] == 0)) { + /* disabled: do not bind to a specific address */ + memset(a6, 0, sizeof(a6)); + } + else { + if(Curl_inet_pton(AF_INET6, local_ip6, a6) != 1) { + return CURLE_BAD_FUNCTION_ARGUMENT; + } + } + + ares_set_local_ip6((ares_channel)data->state.resolver, a6); + + return CURLE_OK; +#else /* c-ares version too old! */ + (void)data; + (void)local_ip6; + return CURLE_NOT_BUILT_IN; +#endif +} +#endif /* CURLRES_ARES */ diff --git a/libcurl/lib/asyn-thread.c b/libcurl/lib/asyn-thread.c new file mode 100644 index 0000000..55e0811 --- /dev/null +++ b/libcurl/lib/asyn-thread.c @@ -0,0 +1,760 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +/*********************************************************************** + * Only for threaded name resolves builds + **********************************************************************/ +#ifdef CURLRES_THREADED + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#if defined(USE_THREADS_POSIX) +# ifdef HAVE_PTHREAD_H +# include +# endif +#elif defined(USE_THREADS_WIN32) +# ifdef HAVE_PROCESS_H +# include +# endif +#endif + +#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +#ifdef HAVE_GETADDRINFO +# define RESOLVER_ENOMEM EAI_MEMORY +#else +# define RESOLVER_ENOMEM ENOMEM +#endif + +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "hash.h" +#include "share.h" +#include "strerror.h" +#include "url.h" +#include "multiif.h" +#include "inet_pton.h" +#include "inet_ntop.h" +#include "curl_threads.h" +#include "connect.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +struct resdata { + struct curltime start; +}; + +/* + * Curl_resolver_global_init() + * Called from curl_global_init() to initialize global resolver environment. + * Does nothing here. + */ +int Curl_resolver_global_init(void) +{ + return CURLE_OK; +} + +/* + * Curl_resolver_global_cleanup() + * Called from curl_global_cleanup() to destroy global resolver environment. + * Does nothing here. + */ +void Curl_resolver_global_cleanup(void) +{ +} + +/* + * Curl_resolver_init() + * Called from curl_easy_init() -> Curl_open() to initialize resolver + * URL-state specific environment ('resolver' member of the UrlState + * structure). + */ +CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver) +{ + (void)easy; + *resolver = calloc(1, sizeof(struct resdata)); + if(!*resolver) + return CURLE_OUT_OF_MEMORY; + return CURLE_OK; +} + +/* + * Curl_resolver_cleanup() + * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver + * URL-state specific environment ('resolver' member of the UrlState + * structure). + */ +void Curl_resolver_cleanup(void *resolver) +{ + free(resolver); +} + +/* + * Curl_resolver_duphandle() + * Called from curl_easy_duphandle() to duplicate resolver URL state-specific + * environment ('resolver' member of the UrlState structure). + */ +CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from) +{ + (void)from; + return Curl_resolver_init(easy, to); +} + +static void destroy_async_data(struct Curl_async *); + +/* + * Cancel all possibly still on-going resolves for this connection. + */ +void Curl_resolver_cancel(struct connectdata *conn) +{ + destroy_async_data(&conn->async); +} + +/* This function is used to init a threaded resolve */ +static bool init_resolve_thread(struct connectdata *conn, + const char *hostname, int port, + const struct addrinfo *hints); + + +/* Data for synchronization between resolver thread and its parent */ +struct thread_sync_data { + curl_mutex_t * mtx; + int done; + + char *hostname; /* hostname to resolve, Curl_async.hostname + duplicate */ + int port; + int sock_error; + Curl_addrinfo *res; +#ifdef HAVE_GETADDRINFO + struct addrinfo hints; +#endif + struct thread_data *td; /* for thread-self cleanup */ +}; + +struct thread_data { + curl_thread_t thread_hnd; + unsigned int poll_interval; + time_t interval_end; + struct thread_sync_data tsd; +}; + +static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn) +{ + return &(((struct thread_data *)conn->async.os_specific)->tsd); +} + +/* Destroy resolver thread synchronization data */ +static +void destroy_thread_sync_data(struct thread_sync_data * tsd) +{ + if(tsd->mtx) { + Curl_mutex_destroy(tsd->mtx); + free(tsd->mtx); + } + + free(tsd->hostname); + + if(tsd->res) + Curl_freeaddrinfo(tsd->res); + + memset(tsd, 0, sizeof(*tsd)); +} + +/* Initialize resolver thread synchronization data */ +static +int init_thread_sync_data(struct thread_data * td, + const char *hostname, + int port, + const struct addrinfo *hints) +{ + struct thread_sync_data *tsd = &td->tsd; + + memset(tsd, 0, sizeof(*tsd)); + + tsd->td = td; + tsd->port = port; + /* Treat the request as done until the thread actually starts so any early + * cleanup gets done properly. + */ + tsd->done = 1; +#ifdef HAVE_GETADDRINFO + DEBUGASSERT(hints); + tsd->hints = *hints; +#else + (void) hints; +#endif + + tsd->mtx = malloc(sizeof(curl_mutex_t)); + if(tsd->mtx == NULL) + goto err_exit; + + Curl_mutex_init(tsd->mtx); + + tsd->sock_error = CURL_ASYNC_SUCCESS; + + /* Copying hostname string because original can be destroyed by parent + * thread during gethostbyname execution. + */ + tsd->hostname = strdup(hostname); + if(!tsd->hostname) + goto err_exit; + + return 1; + + err_exit: + /* Memory allocation failed */ + destroy_thread_sync_data(tsd); + return 0; +} + +static int getaddrinfo_complete(struct connectdata *conn) +{ + struct thread_sync_data *tsd = conn_thread_sync_data(conn); + int rc; + + rc = Curl_addrinfo_callback(conn, tsd->sock_error, tsd->res); + /* The tsd->res structure has been copied to async.dns and perhaps the DNS + cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it. + */ + tsd->res = NULL; + + return rc; +} + + +#ifdef HAVE_GETADDRINFO + +/* + * getaddrinfo_thread() resolves a name and then exits. + * + * For builds without ARES, but with ENABLE_IPV6, create a resolver thread + * and wait on it. + */ +static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) +{ + struct thread_sync_data *tsd = (struct thread_sync_data*)arg; + struct thread_data *td = tsd->td; + char service[12]; + int rc; + + msnprintf(service, sizeof(service), "%d", tsd->port); + + rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res); + + if(rc != 0) { + tsd->sock_error = SOCKERRNO?SOCKERRNO:rc; + if(tsd->sock_error == 0) + tsd->sock_error = RESOLVER_ENOMEM; + } + else { + Curl_addrinfo_set_port(tsd->res, tsd->port); + } + + Curl_mutex_acquire(tsd->mtx); + if(tsd->done) { + /* too late, gotta clean up the mess */ + Curl_mutex_release(tsd->mtx); + destroy_thread_sync_data(tsd); + free(td); + } + else { + tsd->done = 1; + Curl_mutex_release(tsd->mtx); + } + + return 0; +} + +#else /* HAVE_GETADDRINFO */ + +/* + * gethostbyname_thread() resolves a name and then exits. + */ +static unsigned int CURL_STDCALL gethostbyname_thread(void *arg) +{ + struct thread_sync_data *tsd = (struct thread_sync_data *)arg; + struct thread_data *td = tsd->td; + + tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port); + + if(!tsd->res) { + tsd->sock_error = SOCKERRNO; + if(tsd->sock_error == 0) + tsd->sock_error = RESOLVER_ENOMEM; + } + + Curl_mutex_acquire(tsd->mtx); + if(tsd->done) { + /* too late, gotta clean up the mess */ + Curl_mutex_release(tsd->mtx); + destroy_thread_sync_data(tsd); + free(td); + } + else { + tsd->done = 1; + Curl_mutex_release(tsd->mtx); + } + + return 0; +} + +#endif /* HAVE_GETADDRINFO */ + +/* + * destroy_async_data() cleans up async resolver data and thread handle. + */ +static void destroy_async_data(struct Curl_async *async) +{ + if(async->os_specific) { + struct thread_data *td = (struct thread_data*) async->os_specific; + int done; + + /* + * if the thread is still blocking in the resolve syscall, detach it and + * let the thread do the cleanup... + */ + Curl_mutex_acquire(td->tsd.mtx); + done = td->tsd.done; + td->tsd.done = 1; + Curl_mutex_release(td->tsd.mtx); + + if(!done) { + Curl_thread_destroy(td->thread_hnd); + } + else { + if(td->thread_hnd != curl_thread_t_null) + Curl_thread_join(&td->thread_hnd); + + destroy_thread_sync_data(&td->tsd); + + free(async->os_specific); + } + } + async->os_specific = NULL; + + free(async->hostname); + async->hostname = NULL; +} + +/* + * init_resolve_thread() starts a new thread that performs the actual + * resolve. This function returns before the resolve is done. + * + * Returns FALSE in case of failure, otherwise TRUE. + */ +static bool init_resolve_thread(struct connectdata *conn, + const char *hostname, int port, + const struct addrinfo *hints) +{ + struct thread_data *td = calloc(1, sizeof(struct thread_data)); + int err = ENOMEM; + + conn->async.os_specific = (void *)td; + if(!td) + goto errno_exit; + + conn->async.port = port; + conn->async.done = FALSE; + conn->async.status = 0; + conn->async.dns = NULL; + td->thread_hnd = curl_thread_t_null; + + if(!init_thread_sync_data(td, hostname, port, hints)) { + conn->async.os_specific = NULL; + free(td); + goto errno_exit; + } + + free(conn->async.hostname); + conn->async.hostname = strdup(hostname); + if(!conn->async.hostname) + goto err_exit; + + /* The thread will set this to 1 when complete. */ + td->tsd.done = 0; + +#ifdef HAVE_GETADDRINFO + td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd); +#else + td->thread_hnd = Curl_thread_create(gethostbyname_thread, &td->tsd); +#endif + + if(!td->thread_hnd) { + /* The thread never started, so mark it as done here for proper cleanup. */ + td->tsd.done = 1; + err = errno; + goto err_exit; + } + + return TRUE; + + err_exit: + destroy_async_data(&conn->async); + + errno_exit: + errno = err; + return FALSE; +} + +/* + * resolver_error() calls failf() with the appropriate message after a resolve + * error + */ + +static CURLcode resolver_error(struct connectdata *conn) +{ + const char *host_or_proxy; + CURLcode result; + + if(conn->bits.httpproxy) { + host_or_proxy = "proxy"; + result = CURLE_COULDNT_RESOLVE_PROXY; + } + else { + host_or_proxy = "host"; + result = CURLE_COULDNT_RESOLVE_HOST; + } + + failf(conn->data, "Could not resolve %s: %s", host_or_proxy, + conn->async.hostname); + + return result; +} + +static CURLcode thread_wait_resolv(struct connectdata *conn, + struct Curl_dns_entry **entry, + bool report) +{ + struct thread_data *td = (struct thread_data*) conn->async.os_specific; + CURLcode result = CURLE_OK; + + DEBUGASSERT(conn && td); + DEBUGASSERT(td->thread_hnd != curl_thread_t_null); + + /* wait for the thread to resolve the name */ + if(Curl_thread_join(&td->thread_hnd)) { + if(entry) + result = getaddrinfo_complete(conn); + } + else + DEBUGASSERT(0); + + conn->async.done = TRUE; + + if(entry) + *entry = conn->async.dns; + + if(!conn->async.dns && report) + /* a name was not resolved, report error */ + result = resolver_error(conn); + + destroy_async_data(&conn->async); + + if(!conn->async.dns && report) + connclose(conn, "asynch resolve failed"); + + return result; +} + + +/* + * Until we gain a way to signal the resolver threads to stop early, we must + * simply wait for them and ignore their results. + */ +void Curl_resolver_kill(struct connectdata *conn) +{ + struct thread_data *td = (struct thread_data*) conn->async.os_specific; + + /* If we're still resolving, we must wait for the threads to fully clean up, + unfortunately. Otherwise, we can simply cancel to clean up any resolver + data. */ + if(td && td->thread_hnd != curl_thread_t_null) + (void)thread_wait_resolv(conn, NULL, FALSE); + else + Curl_resolver_cancel(conn); +} + +/* + * Curl_resolver_wait_resolv() + * + * Waits for a resolve to finish. This function should be avoided since using + * this risk getting the multi interface to "hang". + * + * If 'entry' is non-NULL, make it point to the resolved dns entry + * + * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, + * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors. + * + * This is the version for resolves-in-a-thread. + */ +CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, + struct Curl_dns_entry **entry) +{ + return thread_wait_resolv(conn, entry, TRUE); +} + +/* + * Curl_resolver_is_resolved() is called repeatedly to check if a previous + * name resolve request has completed. It should also make sure to time-out if + * the operation seems to take too long. + */ +CURLcode Curl_resolver_is_resolved(struct connectdata *conn, + struct Curl_dns_entry **entry) +{ + struct Curl_easy *data = conn->data; + struct thread_data *td = (struct thread_data*) conn->async.os_specific; + int done = 0; + + *entry = NULL; + + if(!td) { + DEBUGASSERT(td); + return CURLE_COULDNT_RESOLVE_HOST; + } + + Curl_mutex_acquire(td->tsd.mtx); + done = td->tsd.done; + Curl_mutex_release(td->tsd.mtx); + + if(done) { + getaddrinfo_complete(conn); + + if(!conn->async.dns) { + CURLcode result = resolver_error(conn); + destroy_async_data(&conn->async); + return result; + } + destroy_async_data(&conn->async); + *entry = conn->async.dns; + } + else { + /* poll for name lookup done with exponential backoff up to 250ms */ + timediff_t elapsed = Curl_timediff(Curl_now(), + data->progress.t_startsingle); + if(elapsed < 0) + elapsed = 0; + + if(td->poll_interval == 0) + /* Start at 1ms poll interval */ + td->poll_interval = 1; + else if(elapsed >= td->interval_end) + /* Back-off exponentially if last interval expired */ + td->poll_interval *= 2; + + if(td->poll_interval > 250) + td->poll_interval = 250; + + td->interval_end = elapsed + td->poll_interval; + Curl_expire(conn->data, td->poll_interval, EXPIRE_ASYNC_NAME); + } + + return CURLE_OK; +} + +int Curl_resolver_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) +{ + time_t milli; + timediff_t ms; + struct Curl_easy *data = conn->data; + struct resdata *reslv = (struct resdata *)data->state.resolver; + (void)socks; + (void)numsocks; + ms = Curl_timediff(Curl_now(), reslv->start); + if(ms < 3) + milli = 0; + else if(ms <= 50) + milli = ms/3; + else if(ms <= 250) + milli = 50; + else + milli = 200; + Curl_expire(data, milli, EXPIRE_ASYNC_NAME); + return 0; +} + +#ifndef HAVE_GETADDRINFO +/* + * Curl_getaddrinfo() - for platforms without getaddrinfo + */ +Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, + const char *hostname, + int port, + int *waitp) +{ + struct in_addr in; + struct Curl_easy *data = conn->data; + struct resdata *reslv = (struct resdata *)data->state.resolver; + + *waitp = 0; /* default to synchronous response */ + + if(Curl_inet_pton(AF_INET, hostname, &in) > 0) + /* This is a dotted IP address 123.123.123.123-style */ + return Curl_ip2addr(AF_INET, &in, hostname, port); + + reslv->start = Curl_now(); + + /* fire up a new resolver thread! */ + if(init_resolve_thread(conn, hostname, port, NULL)) { + *waitp = 1; /* expect asynchronous response */ + return NULL; + } + + failf(conn->data, "getaddrinfo() thread failed\n"); + + return NULL; +} + +#else /* !HAVE_GETADDRINFO */ + +/* + * Curl_resolver_getaddrinfo() - for getaddrinfo + */ +Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, + const char *hostname, + int port, + int *waitp) +{ + struct addrinfo hints; + char sbuf[12]; + int pf = PF_INET; + struct Curl_easy *data = conn->data; + struct resdata *reslv = (struct resdata *)data->state.resolver; + + *waitp = 0; /* default to synchronous response */ + +#ifndef USE_RESOLVE_ON_IPS + { + struct in_addr in; + /* First check if this is an IPv4 address string */ + if(Curl_inet_pton(AF_INET, hostname, &in) > 0) + /* This is a dotted IP address 123.123.123.123-style */ + return Curl_ip2addr(AF_INET, &in, hostname, port); + } +#ifdef CURLRES_IPV6 + { + struct in6_addr in6; + /* check if this is an IPv6 address string */ + if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0) + /* This is an IPv6 address literal */ + return Curl_ip2addr(AF_INET6, &in6, hostname, port); + } +#endif /* CURLRES_IPV6 */ +#endif /* !USE_RESOLVE_ON_IPS */ + +#ifdef CURLRES_IPV6 + /* + * Check if a limited name resolve has been requested. + */ + switch(conn->ip_version) { + case CURL_IPRESOLVE_V4: + pf = PF_INET; + break; + case CURL_IPRESOLVE_V6: + pf = PF_INET6; + break; + default: + pf = PF_UNSPEC; + break; + } + + if((pf != PF_INET) && !Curl_ipv6works()) + /* The stack seems to be a non-IPv6 one */ + pf = PF_INET; +#endif /* CURLRES_IPV6 */ + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = pf; + hints.ai_socktype = conn->socktype; + + msnprintf(sbuf, sizeof(sbuf), "%d", port); + + reslv->start = Curl_now(); + /* fire up a new resolver thread! */ + if(init_resolve_thread(conn, hostname, port, &hints)) { + *waitp = 1; /* expect asynchronous response */ + return NULL; + } + + failf(data, "getaddrinfo() thread failed to start\n"); + return NULL; + +} + +#endif /* !HAVE_GETADDRINFO */ + +CURLcode Curl_set_dns_servers(struct Curl_easy *data, + char *servers) +{ + (void)data; + (void)servers; + return CURLE_NOT_BUILT_IN; + +} + +CURLcode Curl_set_dns_interface(struct Curl_easy *data, + const char *interf) +{ + (void)data; + (void)interf; + return CURLE_NOT_BUILT_IN; +} + +CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data, + const char *local_ip4) +{ + (void)data; + (void)local_ip4; + return CURLE_NOT_BUILT_IN; +} + +CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data, + const char *local_ip6) +{ + (void)data; + (void)local_ip6; + return CURLE_NOT_BUILT_IN; +} + +#endif /* CURLRES_THREADED */ diff --git a/libcurl/lib/asyn.h b/libcurl/lib/asyn.h new file mode 100644 index 0000000..ccd4b1f --- /dev/null +++ b/libcurl/lib/asyn.h @@ -0,0 +1,184 @@ +#ifndef HEADER_CURL_ASYN_H +#define HEADER_CURL_ASYN_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include "curl_addrinfo.h" + +struct addrinfo; +struct hostent; +struct Curl_easy; +struct connectdata; +struct Curl_dns_entry; + +/* + * This header defines all functions in the internal asynch resolver interface. + * All asynch resolvers need to provide these functions. + * asyn-ares.c and asyn-thread.c are the current implementations of asynch + * resolver backends. + */ + +/* + * Curl_resolver_global_init() + * + * Called from curl_global_init() to initialize global resolver environment. + * Returning anything else than CURLE_OK fails curl_global_init(). + */ +int Curl_resolver_global_init(void); + +/* + * Curl_resolver_global_cleanup() + * Called from curl_global_cleanup() to destroy global resolver environment. + */ +void Curl_resolver_global_cleanup(void); + +/* + * Curl_resolver_init() + * Called from curl_easy_init() -> Curl_open() to initialize resolver + * URL-state specific environment ('resolver' member of the UrlState + * structure). Should fill the passed pointer by the initialized handler. + * Returning anything else than CURLE_OK fails curl_easy_init() with the + * correspondent code. + */ +CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver); + +/* + * Curl_resolver_cleanup() + * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver + * URL-state specific environment ('resolver' member of the UrlState + * structure). Should destroy the handler and free all resources connected to + * it. + */ +void Curl_resolver_cleanup(void *resolver); + +/* + * Curl_resolver_duphandle() + * Called from curl_easy_duphandle() to duplicate resolver URL-state specific + * environment ('resolver' member of the UrlState structure). Should + * duplicate the 'from' handle and pass the resulting handle to the 'to' + * pointer. Returning anything else than CURLE_OK causes failed + * curl_easy_duphandle() call. + */ +CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, + void *from); + +/* + * Curl_resolver_cancel(). + * + * It is called from inside other functions to cancel currently performing + * resolver request. Should also free any temporary resources allocated to + * perform a request. This never waits for resolver threads to complete. + * + * It is safe to call this when conn is in any state. + */ +void Curl_resolver_cancel(struct connectdata *conn); + +/* + * Curl_resolver_kill(). + * + * This acts like Curl_resolver_cancel() except it will block until any threads + * associated with the resolver are complete. This never blocks for resolvers + * that do not use threads. This is intended to be the "last chance" function + * that cleans up an in-progress resolver completely (before its owner is about + * to die). + * + * It is safe to call this when conn is in any state. + */ +void Curl_resolver_kill(struct connectdata *conn); + +/* Curl_resolver_getsock() + * + * This function is called from the multi_getsock() function. 'sock' is a + * pointer to an array to hold the file descriptors, with 'numsock' being the + * size of that array (in number of entries). This function is supposed to + * return bitmask indicating what file descriptors (referring to array indexes + * in the 'sock' array) to wait for, read/write. + */ +int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock, + int numsocks); + +/* + * Curl_resolver_is_resolved() + * + * Called repeatedly to check if a previous name resolve request has + * completed. It should also make sure to time-out if the operation seems to + * take too long. + * + * Returns normal CURLcode errors. + */ +CURLcode Curl_resolver_is_resolved(struct connectdata *conn, + struct Curl_dns_entry **dns); + +/* + * Curl_resolver_wait_resolv() + * + * Waits for a resolve to finish. This function should be avoided since using + * this risk getting the multi interface to "hang". + * + * If 'entry' is non-NULL, make it point to the resolved dns entry + * + * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, + * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors. + */ +CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, + struct Curl_dns_entry **dnsentry); + +/* + * Curl_resolver_getaddrinfo() - when using this resolver + * + * Returns name information about the given hostname and port number. If + * successful, the 'hostent' is returned and the forth argument will point to + * memory we need to free after use. That memory *MUST* be freed with + * Curl_freeaddrinfo(), nothing else. + * + * Each resolver backend must of course make sure to return data in the + * correct format to comply with this. + */ +Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, + const char *hostname, + int port, + int *waitp); + +#ifndef CURLRES_ASYNCH +/* convert these functions if an asynch resolver isn't used */ +#define Curl_resolver_cancel(x) Curl_nop_stmt +#define Curl_resolver_kill(x) Curl_nop_stmt +#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST +#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST +#define Curl_resolver_getsock(x,y,z) 0 +#define Curl_resolver_duphandle(x,y,z) CURLE_OK +#define Curl_resolver_init(x,y) CURLE_OK +#define Curl_resolver_global_init() CURLE_OK +#define Curl_resolver_global_cleanup() Curl_nop_stmt +#define Curl_resolver_cleanup(x) Curl_nop_stmt +#endif + +#ifdef CURLRES_ASYNCH +#define Curl_resolver_asynch() 1 +#else +#define Curl_resolver_asynch() 0 +#endif + + +/********** end of generic resolver interface functions *****************/ +#endif /* HEADER_CURL_ASYN_H */ diff --git a/libcurl/lib/base64.c b/libcurl/lib/base64.c new file mode 100644 index 0000000..fb081a6 --- /dev/null +++ b/libcurl/lib/base64.c @@ -0,0 +1,326 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* Base64 encoding/decoding */ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_LIBSSH2) || \ + defined(USE_LIBSSH) || !defined(CURL_DISABLE_LDAP) || \ + !defined(CURL_DISABLE_DOH) || defined(USE_SSL) + +#include "urldata.h" /* for the Curl_easy definition */ +#include "warnless.h" +#include "curl_base64.h" +#include "non-ascii.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* ---- Base64 Encoding/Decoding Table --- */ +static const char base64[]= + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* The Base 64 encoding with an URL and filename safe alphabet, RFC 4648 + section 5 */ +static const char base64url[]= + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + +static size_t decodeQuantum(unsigned char *dest, const char *src) +{ + size_t padding = 0; + const char *s, *p; + unsigned long i, x = 0; + + for(i = 0, s = src; i < 4; i++, s++) { + if(*s == '=') { + x = (x << 6); + padding++; + } + else { + unsigned long v = 0; + p = base64; + + while(*p && (*p != *s)) { + v++; + p++; + } + + if(*p == *s) + x = (x << 6) + v; + else + return 0; + } + } + + if(padding < 1) + dest[2] = curlx_ultouc(x & 0xFFUL); + + x >>= 8; + if(padding < 2) + dest[1] = curlx_ultouc(x & 0xFFUL); + + x >>= 8; + dest[0] = curlx_ultouc(x & 0xFFUL); + + return 3 - padding; +} + +/* + * Curl_base64_decode() + * + * Given a base64 NUL-terminated string at src, decode it and return a + * pointer in *outptr to a newly allocated memory area holding decoded + * data. Size of decoded data is returned in variable pointed by outlen. + * + * Returns CURLE_OK on success, otherwise specific error code. Function + * output shall not be considered valid unless CURLE_OK is returned. + * + * When decoded data length is 0, returns NULL in *outptr. + * + * @unittest: 1302 + */ +CURLcode Curl_base64_decode(const char *src, + unsigned char **outptr, size_t *outlen) +{ + size_t srclen = 0; + size_t length = 0; + size_t padding = 0; + size_t i; + size_t numQuantums; + size_t rawlen = 0; + unsigned char *pos; + unsigned char *newstr; + + *outptr = NULL; + *outlen = 0; + srclen = strlen(src); + + /* Check the length of the input string is valid */ + if(!srclen || srclen % 4) + return CURLE_BAD_CONTENT_ENCODING; + + /* Find the position of any = padding characters */ + while((src[length] != '=') && src[length]) + length++; + + /* A maximum of two = padding characters is allowed */ + if(src[length] == '=') { + padding++; + if(src[length + 1] == '=') + padding++; + } + + /* Check the = padding characters weren't part way through the input */ + if(length + padding != srclen) + return CURLE_BAD_CONTENT_ENCODING; + + /* Calculate the number of quantums */ + numQuantums = srclen / 4; + + /* Calculate the size of the decoded string */ + rawlen = (numQuantums * 3) - padding; + + /* Allocate our buffer including room for a zero terminator */ + newstr = malloc(rawlen + 1); + if(!newstr) + return CURLE_OUT_OF_MEMORY; + + pos = newstr; + + /* Decode the quantums */ + for(i = 0; i < numQuantums; i++) { + size_t result = decodeQuantum(pos, src); + if(!result) { + free(newstr); + + return CURLE_BAD_CONTENT_ENCODING; + } + + pos += result; + src += 4; + } + + /* Zero terminate */ + *pos = '\0'; + + /* Return the decoded data */ + *outptr = newstr; + *outlen = rawlen; + + return CURLE_OK; +} + +static CURLcode base64_encode(const char *table64, + struct Curl_easy *data, + const char *inputbuff, size_t insize, + char **outptr, size_t *outlen) +{ + CURLcode result; + unsigned char ibuf[3]; + unsigned char obuf[4]; + int i; + int inputparts; + char *output; + char *base64data; + char *convbuf = NULL; + + const char *indata = inputbuff; + + *outptr = NULL; + *outlen = 0; + + if(!insize) + insize = strlen(indata); + +#if SIZEOF_SIZE_T == 4 + if(insize > UINT_MAX/4) + return CURLE_OUT_OF_MEMORY; +#endif + + base64data = output = malloc(insize * 4 / 3 + 4); + if(!output) + return CURLE_OUT_OF_MEMORY; + + /* + * The base64 data needs to be created using the network encoding + * not the host encoding. And we can't change the actual input + * so we copy it to a buffer, translate it, and use that instead. + */ + result = Curl_convert_clone(data, indata, insize, &convbuf); + if(result) { + free(output); + return result; + } + + if(convbuf) + indata = (char *)convbuf; + + while(insize > 0) { + for(i = inputparts = 0; i < 3; i++) { + if(insize > 0) { + inputparts++; + ibuf[i] = (unsigned char) *indata; + indata++; + insize--; + } + else + ibuf[i] = 0; + } + + obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2); + obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \ + ((ibuf[1] & 0xF0) >> 4)); + obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \ + ((ibuf[2] & 0xC0) >> 6)); + obuf[3] = (unsigned char) (ibuf[2] & 0x3F); + + switch(inputparts) { + case 1: /* only one byte read */ + msnprintf(output, 5, "%c%c==", + table64[obuf[0]], + table64[obuf[1]]); + break; + + case 2: /* two bytes read */ + msnprintf(output, 5, "%c%c%c=", + table64[obuf[0]], + table64[obuf[1]], + table64[obuf[2]]); + break; + + default: + msnprintf(output, 5, "%c%c%c%c", + table64[obuf[0]], + table64[obuf[1]], + table64[obuf[2]], + table64[obuf[3]]); + break; + } + output += 4; + } + + /* Zero terminate */ + *output = '\0'; + + /* Return the pointer to the new data (allocated memory) */ + *outptr = base64data; + + free(convbuf); + + /* Return the length of the new data */ + *outlen = strlen(base64data); + + return CURLE_OK; +} + +/* + * Curl_base64_encode() + * + * Given a pointer to an input buffer and an input size, encode it and + * return a pointer in *outptr to a newly allocated memory area holding + * encoded data. Size of encoded data is returned in variable pointed by + * outlen. + * + * Input length of 0 indicates input buffer holds a NUL-terminated string. + * + * Returns CURLE_OK on success, otherwise specific error code. Function + * output shall not be considered valid unless CURLE_OK is returned. + * + * When encoded data length is 0, returns NULL in *outptr. + * + * @unittest: 1302 + */ +CURLcode Curl_base64_encode(struct Curl_easy *data, + const char *inputbuff, size_t insize, + char **outptr, size_t *outlen) +{ + return base64_encode(base64, data, inputbuff, insize, outptr, outlen); +} + +/* + * Curl_base64url_encode() + * + * Given a pointer to an input buffer and an input size, encode it and + * return a pointer in *outptr to a newly allocated memory area holding + * encoded data. Size of encoded data is returned in variable pointed by + * outlen. + * + * Input length of 0 indicates input buffer holds a NUL-terminated string. + * + * Returns CURLE_OK on success, otherwise specific error code. Function + * output shall not be considered valid unless CURLE_OK is returned. + * + * When encoded data length is 0, returns NULL in *outptr. + * + * @unittest: 1302 + */ +CURLcode Curl_base64url_encode(struct Curl_easy *data, + const char *inputbuff, size_t insize, + char **outptr, size_t *outlen) +{ + return base64_encode(base64url, data, inputbuff, insize, outptr, outlen); +} + +#endif /* no users so disabled */ diff --git a/libcurl/lib/checksrc.pl b/libcurl/lib/checksrc.pl new file mode 100644 index 0000000..965f0ba --- /dev/null +++ b/libcurl/lib/checksrc.pl @@ -0,0 +1,756 @@ +#!/usr/bin/env perl +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 2011 - 2018, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### + +use strict; +use warnings; + +my $max_column = 79; +my $indent = 2; + +my $warnings = 0; +my $swarnings = 0; +my $errors = 0; +my $serrors = 0; +my $suppressed; # whitelisted problems +my $file; +my $dir="."; +my $wlist=""; +my @alist; +my $windows_os = $^O eq 'MSWin32' || $^O eq 'msys' || $^O eq 'cygwin'; +my $verbose; +my %whitelist; + +my %ignore; +my %ignore_set; +my %ignore_used; +my @ignore_line; + +my %warnings_extended = ( + 'COPYRIGHTYEAR' => 'copyright year incorrect', + ); + +my %warnings = ( + 'LONGLINE' => "Line longer than $max_column", + 'TABS' => 'TAB characters not allowed', + 'TRAILINGSPACE' => 'Trailing white space on the line', + 'CPPCOMMENTS' => '// comment detected', + 'SPACEBEFOREPAREN' => 'space before an open parenthesis', + 'SPACEAFTERPAREN' => 'space after open parenthesis', + 'SPACEBEFORECLOSE' => 'space before a close parenthesis', + 'SPACEBEFORECOMMA' => 'space before a comma', + 'RETURNNOSPACE' => 'return without space', + 'COMMANOSPACE' => 'comma without following space', + 'BRACEELSE' => '} else on the same line', + 'PARENBRACE' => '){ without sufficient space', + 'SPACESEMICOLON' => 'space before semicolon', + 'BANNEDFUNC' => 'a banned function was used', + 'FOPENMODE' => 'fopen needs a macro for the mode string', + 'BRACEPOS' => 'wrong position for an open brace', + 'INDENTATION' => 'wrong start column for code', + 'COPYRIGHT' => 'file missing a copyright statement', + 'BADCOMMAND' => 'bad !checksrc! instruction', + 'UNUSEDIGNORE' => 'a warning ignore was not used', + 'OPENCOMMENT' => 'file ended with a /* comment still "open"', + 'ASTERISKSPACE' => 'pointer declared with space after asterisk', + 'ASTERISKNOSPACE' => 'pointer declared without space before asterisk', + 'ASSIGNWITHINCONDITION' => 'assignment within conditional expression', + 'EQUALSNOSPACE' => 'equals sign without following space', + 'NOSPACEEQUALS' => 'equals sign without preceding space', + 'SEMINOSPACE' => 'semicolon without following space', + 'MULTISPACE' => 'multiple spaces used when not suitable', + 'SIZEOFNOPAREN' => 'use of sizeof without parentheses', + 'SNPRINTF' => 'use of snprintf', + ); + +sub readwhitelist { + open(W, "<$dir/checksrc.whitelist") or return; + my @all=; + for(@all) { + $windows_os ? $_ =~ s/\r?\n$// : chomp; + $whitelist{$_}=1; + } + close(W); +} + +# Reads the .checksrc in $dir for any extended warnings to enable locally. +# Currently there is no support for disabling warnings from the standard set, +# and since that's already handled via !checksrc! commands there is probably +# little use to add it. +sub readlocalfile { + my $i = 0; + + open(my $rcfile, "<", "$dir/.checksrc") or return; + + while(<$rcfile>) { + $i++; + + # Lines starting with '#' are considered comments + if (/^\s*(#.*)/) { + next; + } + elsif (/^\s*enable ([A-Z]+)$/) { + if(!defined($warnings_extended{$1})) { + print STDERR "invalid warning specified in .checksrc: \"$1\"\n"; + next; + } + $warnings{$1} = $warnings_extended{$1}; + } + else { + die "Invalid format in $dir/.checksrc on line $i\n"; + } + } +} + +sub checkwarn { + my ($name, $num, $col, $file, $line, $msg, $error) = @_; + + my $w=$error?"error":"warning"; + my $nowarn=0; + + #if(!$warnings{$name}) { + # print STDERR "Dev! there's no description for $name!\n"; + #} + + # checksrc.whitelist + if($whitelist{$line}) { + $nowarn = 1; + } + # !checksrc! controlled + elsif($ignore{$name}) { + $ignore{$name}--; + $ignore_used{$name}++; + $nowarn = 1; + if(!$ignore{$name}) { + # reached zero, enable again + enable_warn($name, $num, $file, $line); + } + } + + if($nowarn) { + $suppressed++; + if($w) { + $swarnings++; + } + else { + $serrors++; + } + return; + } + + if($w) { + $warnings++; + } + else { + $errors++; + } + + $col++; + print "$file:$num:$col: $w: $msg ($name)\n"; + print " $line\n"; + + if($col < 80) { + my $pref = (' ' x $col); + print "${pref}^\n"; + } +} + +$file = shift @ARGV; + +while(1) { + + if($file =~ /-D(.*)/) { + $dir = $1; + $file = shift @ARGV; + next; + } + elsif($file =~ /-W(.*)/) { + $wlist .= " $1 "; + $file = shift @ARGV; + next; + } + elsif($file =~ /-A(.+)/) { + push @alist, $1; + $file = shift @ARGV; + next; + } + elsif($file =~ /-i([1-9])/) { + $indent = $1 + 0; + $file = shift @ARGV; + next; + } + elsif($file =~ /-m([0-9]+)/) { + $max_column = $1 + 0; + $file = shift @ARGV; + next; + } + elsif($file =~ /^(-h|--help)/) { + undef $file; + last; + } + + last; +} + +if(!$file) { + print "checksrc.pl [option] [file2] ...\n"; + print " Options:\n"; + print " -A[rule] Accept this violation, can be used multiple times\n"; + print " -D[DIR] Directory to prepend file names\n"; + print " -h Show help output\n"; + print " -W[file] Whitelist the given file - ignore all its flaws\n"; + print " -i Indent spaces. Default: 2\n"; + print " -m Maximum line length. Default: 79\n"; + print "\nDetects and warns for these problems:\n"; + for(sort keys %warnings) { + printf (" %-18s: %s\n", $_, $warnings{$_}); + } + exit; +} + +readwhitelist(); +readlocalfile(); + +do { + if("$wlist" !~ / $file /) { + my $fullname = $file; + $fullname = "$dir/$file" if ($fullname !~ '^\.?\.?/'); + scanfile($fullname); + } + $file = shift @ARGV; + +} while($file); + +sub accept_violations { + for my $r (@alist) { + if(!$warnings{$r}) { + print "'$r' is not a warning to accept!\n"; + exit; + } + $ignore{$r}=999999; + $ignore_used{$r}=0; + } +} + +sub checksrc_clear { + undef %ignore; + undef %ignore_set; + undef @ignore_line; +} + +sub checksrc_endoffile { + my ($file) = @_; + for(keys %ignore_set) { + if($ignore_set{$_} && !$ignore_used{$_}) { + checkwarn("UNUSEDIGNORE", $ignore_set{$_}, + length($_)+11, $file, + $ignore_line[$ignore_set{$_}], + "Unused ignore: $_"); + } + } +} + +sub enable_warn { + my ($what, $line, $file, $l) = @_; + + # switch it back on, but warn if not triggered! + if(!$ignore_used{$what}) { + checkwarn("UNUSEDIGNORE", + $line, length($what) + 11, $file, $l, + "No warning was inhibited!"); + } + $ignore_set{$what}=0; + $ignore_used{$what}=0; + $ignore{$what}=0; +} +sub checksrc { + my ($cmd, $line, $file, $l) = @_; + if($cmd =~ / *([^ ]*) *(.*)/) { + my ($enable, $what) = ($1, $2); + $what =~ s: *\*/$::; # cut off end of C comment + # print "ENABLE $enable WHAT $what\n"; + if($enable eq "disable") { + my ($warn, $scope)=($1, $2); + if($what =~ /([^ ]*) +(.*)/) { + ($warn, $scope)=($1, $2); + } + else { + $warn = $what; + $scope = 1; + } + # print "IGNORE $warn for SCOPE $scope\n"; + if($scope eq "all") { + $scope=999999; + } + + # Comparing for a literal zero rather than the scalar value zero + # covers the case where $scope contains the ending '*' from the + # comment. If we use a scalar comparison (==) we induce warnings + # on non-scalar contents. + if($scope eq "0") { + checkwarn("BADCOMMAND", + $line, 0, $file, $l, + "Disable zero not supported, did you mean to enable?"); + } + elsif($ignore_set{$warn}) { + checkwarn("BADCOMMAND", + $line, 0, $file, $l, + "$warn already disabled from line $ignore_set{$warn}"); + } + else { + $ignore{$warn}=$scope; + $ignore_set{$warn}=$line; + $ignore_line[$line]=$l; + } + } + elsif($enable eq "enable") { + enable_warn($what, $line, $file, $l); + } + else { + checkwarn("BADCOMMAND", + $line, 0, $file, $l, + "Illegal !checksrc! command"); + } + } +} + +sub nostrings { + my ($str) = @_; + $str =~ s/\".*\"//g; + return $str; +} + +sub scanfile { + my ($file) = @_; + + my $line = 1; + my $prevl=""; + my $l; + open(R, "<$file") || die "failed to open $file"; + + my $incomment=0; + my @copyright=(); + checksrc_clear(); # for file based ignores + accept_violations(); + + while() { + $windows_os ? $_ =~ s/\r?\n$// : chomp; + my $l = $_; + my $ol = $l; # keep the unmodified line for error reporting + my $column = 0; + + # check for !checksrc! commands + if($l =~ /\!checksrc\! (.*)/) { + my $cmd = $1; + checksrc($cmd, $line, $file, $l) + } + + # check for a copyright statement and save the years + if($l =~ /\* +copyright .* \d\d\d\d/i) { + while($l =~ /([\d]{4})/g) { + push @copyright, { + year => $1, + line => $line, + col => index($l, $1), + code => $l + }; + } + } + + # detect long lines + if(length($l) > $max_column) { + checkwarn("LONGLINE", $line, length($l), $file, $l, + "Longer than $max_column columns"); + } + # detect TAB characters + if($l =~ /^(.*)\t/) { + checkwarn("TABS", + $line, length($1), $file, $l, "Contains TAB character", 1); + } + # detect trailing white space + if($l =~ /^(.*)[ \t]+\z/) { + checkwarn("TRAILINGSPACE", + $line, length($1), $file, $l, "Trailing whitespace"); + } + + # ------------------------------------------------------------ + # Above this marker, the checks were done on lines *including* + # comments + # ------------------------------------------------------------ + + # strip off C89 comments + + comment: + if(!$incomment) { + if($l =~ s/\/\*.*\*\// /g) { + # full /* comments */ were removed! + } + if($l =~ s/\/\*.*//) { + # start of /* comment was removed + $incomment = 1; + } + } + else { + if($l =~ s/.*\*\///) { + # end of comment */ was removed + $incomment = 0; + goto comment; + } + else { + # still within a comment + $l=""; + } + } + + # ------------------------------------------------------------ + # Below this marker, the checks were done on lines *without* + # comments + # ------------------------------------------------------------ + + # crude attempt to detect // comments without too many false + # positives + if($l =~ /^([^"\*]*)[^:"]\/\//) { + checkwarn("CPPCOMMENTS", + $line, length($1), $file, $l, "\/\/ comment"); + } + + my $nostr = nostrings($l); + # check spaces after for/if/while/function call + if($nostr =~ /^(.*)(for|if|while| ([a-zA-Z0-9_]+)) \((.)/) { + if($1 =~ / *\#/) { + # this is a #if, treat it differently + } + elsif(defined $3 && $3 eq "return") { + # return must have a space + } + elsif(defined $3 && $3 eq "case") { + # case must have a space + } + elsif($4 eq "*") { + # (* beginning makes the space OK! + } + elsif($1 =~ / *typedef/) { + # typedefs can use space-paren + } + else { + checkwarn("SPACEBEFOREPAREN", $line, length($1)+length($2), $file, $l, + "$2 with space"); + } + } + + if($nostr =~ /^((.*)(if) *\()(.*)\)/) { + my $pos = length($1); + if($4 =~ / = /) { + checkwarn("ASSIGNWITHINCONDITION", + $line, $pos+1, $file, $l, + "assignment within conditional expression"); + } + } + # check spaces after open parentheses + if($l =~ /^(.*[a-z])\( /i) { + checkwarn("SPACEAFTERPAREN", + $line, length($1)+1, $file, $l, + "space after open parenthesis"); + } + + # check spaces before close parentheses, unless it was a space or a + # close parenthesis! + if($l =~ /(.*[^\) ]) \)/) { + checkwarn("SPACEBEFORECLOSE", + $line, length($1)+1, $file, $l, + "space before close parenthesis"); + } + + # check spaces before comma! + if($l =~ /(.*[^ ]) ,/) { + checkwarn("SPACEBEFORECOMMA", + $line, length($1)+1, $file, $l, + "space before comma"); + } + + # check for "return(" without space + if($l =~ /^(.*)return\(/) { + if($1 =~ / *\#/) { + # this is a #if, treat it differently + } + else { + checkwarn("RETURNNOSPACE", $line, length($1)+6, $file, $l, + "return without space before paren"); + } + } + + # check for "sizeof" without parenthesis + if(($l =~ /^(.*)sizeof *([ (])/) && ($2 ne "(")) { + if($1 =~ / *\#/) { + # this is a #if, treat it differently + } + else { + checkwarn("SIZEOFNOPAREN", $line, length($1)+6, $file, $l, + "sizeof without parenthesis"); + } + } + + # check for comma without space + if($l =~ /^(.*),[^ \n]/) { + my $pref=$1; + my $ign=0; + if($pref =~ / *\#/) { + # this is a #if, treat it differently + $ign=1; + } + elsif($pref =~ /\/\*/) { + # this is a comment + $ign=1; + } + elsif($pref =~ /[\"\']/) { + $ign = 1; + # There is a quote here, figure out whether the comma is + # within a string or '' or not. + if($pref =~ /\"/) { + # within a string + } + elsif($pref =~ /\'$/) { + # a single letter + } + else { + $ign = 0; + } + } + if(!$ign) { + checkwarn("COMMANOSPACE", $line, length($pref)+1, $file, $l, + "comma without following space"); + } + } + + # check for "} else" + if($l =~ /^(.*)\} *else/) { + checkwarn("BRACEELSE", + $line, length($1), $file, $l, "else after closing brace on same line"); + } + # check for "){" + if($l =~ /^(.*)\)\{/) { + checkwarn("PARENBRACE", + $line, length($1)+1, $file, $l, "missing space after close paren"); + } + + # check for space before the semicolon last in a line + if($l =~ /^(.*[^ ].*) ;$/) { + checkwarn("SPACESEMICOLON", + $line, length($1), $file, $ol, "space before last semicolon"); + } + + # scan for use of banned functions + if($l =~ /^(.*\W) + (gets| + strtok| + v?sprintf| + (str|_mbs|_tcs|_wcs)n?cat| + LoadLibrary(Ex)?(A|W)?) + \s*\( + /x) { + checkwarn("BANNEDFUNC", + $line, length($1), $file, $ol, + "use of $2 is banned"); + } + + # scan for use of snprintf for curl-internals reasons + if($l =~ /^(.*\W)(v?snprintf)\s*\(/x) { + checkwarn("SNPRINTF", + $line, length($1), $file, $ol, + "use of $2 is banned"); + } + + # scan for use of non-binary fopen without the macro + if($l =~ /^(.*\W)fopen\s*\([^,]*, *\"([^"]*)/) { + my $mode = $2; + if($mode !~ /b/) { + checkwarn("FOPENMODE", + $line, length($1), $file, $ol, + "use of non-binary fopen without FOPEN_* macro: $mode"); + } + } + + # check for open brace first on line but not first column + # only alert if previous line ended with a close paren and wasn't a cpp + # line + if((($prevl =~ /\)\z/) && ($prevl !~ /^ *#/)) && ($l =~ /^( +)\{/)) { + checkwarn("BRACEPOS", + $line, length($1), $file, $ol, "badly placed open brace"); + } + + # if the previous line starts with if/while/for AND ends with an open + # brace, or an else statement, check that this line is indented $indent + # more steps, if not a cpp line + if($prevl =~ /^( *)((if|while|for)\(.*\{|else)\z/) { + my $first = length($1); + + # this line has some character besides spaces + if(($l !~ /^ *#/) && ($l =~ /^( *)[^ ]/)) { + my $second = length($1); + my $expect = $first+$indent; + if($expect != $second) { + my $diff = $second - $first; + checkwarn("INDENTATION", $line, length($1), $file, $ol, + "not indented $indent steps (uses $diff)"); + + } + } + } + + # check for 'char * name' + if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost) *(\*+)) (\w+)/) && ($4 ne "const")) { + checkwarn("ASTERISKNOSPACE", + $line, length($1), $file, $ol, + "no space after declarative asterisk"); + } + # check for 'char*' + if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost|sockaddr_in|FILE)\*)/)) { + checkwarn("ASTERISKNOSPACE", + $line, length($1)-1, $file, $ol, + "no space before asterisk"); + } + + # check for 'void func() {', but avoid false positives by requiring + # both an open and closed parentheses before the open brace + if($l =~ /^((\w).*)\{\z/) { + my $k = $1; + $k =~ s/const *//; + $k =~ s/static *//; + if($k =~ /\(.*\)/) { + checkwarn("BRACEPOS", + $line, length($l)-1, $file, $ol, + "wrongly placed open brace"); + } + } + + # check for equals sign without spaces next to it + if($nostr =~ /(.*)\=[a-z0-9]/i) { + checkwarn("EQUALSNOSPACE", + $line, length($1)+1, $file, $ol, + "no space after equals sign"); + } + # check for equals sign without spaces before it + elsif($nostr =~ /(.*)[a-z0-9]\=/i) { + checkwarn("NOSPACEEQUALS", + $line, length($1)+1, $file, $ol, + "no space before equals sign"); + } + + # check for plus signs without spaces next to it + if($nostr =~ /(.*)[^+]\+[a-z0-9]/i) { + checkwarn("PLUSNOSPACE", + $line, length($1)+1, $file, $ol, + "no space after plus sign"); + } + # check for plus sign without spaces before it + elsif($nostr =~ /(.*)[a-z0-9]\+[^+]/i) { + checkwarn("NOSPACEPLUS", + $line, length($1)+1, $file, $ol, + "no space before plus sign"); + } + + # check for semicolons without space next to it + if($nostr =~ /(.*)\;[a-z0-9]/i) { + checkwarn("SEMINOSPACE", + $line, length($1)+1, $file, $ol, + "no space after semicolon"); + } + + # check for more than one consecutive space before open brace or + # question mark. Skip lines containing strings since they make it hard + # due to artificially getting multiple spaces + if(($l eq $nostr) && + $nostr =~ /^(.*(\S)) + [{?]/i) { + checkwarn("MULTISPACE", + $line, length($1)+1, $file, $ol, + "multiple space"); + print STDERR "L: $l\n"; + print STDERR "nostr: $nostr\n"; + } + + $line++; + $prevl = $ol; + } + + if(!scalar(@copyright)) { + checkwarn("COPYRIGHT", 1, 0, $file, "", "Missing copyright statement", 1); + } + + # COPYRIGHTYEAR is a extended warning so we must first see if it has been + # enabled in .checksrc + if(defined($warnings{"COPYRIGHTYEAR"})) { + # The check for updated copyrightyear is overly complicated in order to + # not punish current hacking for past sins. The copyright years are + # right now a bit behind, so enforcing copyright year checking on all + # files would cause hundreds of errors. Instead we only look at files + # which are tracked in the Git repo and edited in the workdir, or + # committed locally on the branch without being in upstream master. + # + # The simple and naive test is to simply check for the current year, + # but updating the year even without an edit is against project policy + # (and it would fail every file on January 1st). + # + # A rather more interesting, and correct, check would be to not test + # only locally committed files but inspect all files wrt the year of + # their last commit. Removing the `git rev-list origin/master..HEAD` + # condition below will enfore copyright year checks against the year + # the file was last committed (and thus edited to some degree). + my $commityear = undef; + @copyright = sort {$$b{year} cmp $$a{year}} @copyright; + + if(`git status -s -- $file` =~ /^ [MARCU]/) { + $commityear = (localtime(time))[5] + 1900; + } + elsif (`git rev-list --count origin/master..HEAD -- $file` !~ /^0/) { + my $grl = `git rev-list --max-count=1 --timestamp HEAD -- $file`; + $commityear = (localtime((split(/ /, $grl))[0]))[5] + 1900; + } + + if(defined($commityear) && scalar(@copyright) && + $copyright[0]{year} != $commityear) { + checkwarn("COPYRIGHTYEAR", $copyright[0]{line}, $copyright[0]{col}, + $file, $copyright[0]{code}, + "Copyright year out of date, should be $commityear, " . + "is $copyright[0]{year}", 1); + } + } + + if($incomment) { + checkwarn("OPENCOMMENT", 1, 0, $file, "", "Missing closing comment", 1); + } + + checksrc_endoffile($file); + + close(R); + +} + + +if($errors || $warnings || $verbose) { + printf "checksrc: %d errors and %d warnings\n", $errors, $warnings; + if($suppressed) { + printf "checksrc: %d errors and %d warnings suppressed\n", + $serrors, + $swarnings; + } + exit 5; # return failure +} diff --git a/libcurl/lib/config-amigaos.h b/libcurl/lib/config-amigaos.h new file mode 100644 index 0000000..31cfc3a --- /dev/null +++ b/libcurl/lib/config-amigaos.h @@ -0,0 +1,166 @@ +#ifndef HEADER_CURL_CONFIG_AMIGAOS_H +#define HEADER_CURL_CONFIG_AMIGAOS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* Hand crafted config file for AmigaOS */ +/* ================================================================ */ + +#ifdef __AMIGA__ /* Any AmigaOS flavour */ + +#define HAVE_ARPA_INET_H 1 +#define HAVE_CLOSESOCKET_CAMEL 1 +#define HAVE_ERRNO_H 1 +#define HAVE_GETHOSTBYADDR 1 +#define HAVE_INET_ADDR 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_IOCTLSOCKET_CAMEL 1 +#define HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1 +#define HAVE_LIBCRYPTO 1 +#define HAVE_LIBSSL 1 +#define HAVE_LIBZ 1 +#define HAVE_LONGLONG 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_NETDB_H 1 +#define HAVE_NETINET_IN_H 1 +#define HAVE_NET_IF_H 1 +#define HAVE_OPENSSL_CRYPTO_H 1 +#define HAVE_OPENSSL_ERR_H 1 +#define HAVE_OPENSSL_PEM_H 1 +#define HAVE_OPENSSL_RSA_H 1 +#define HAVE_OPENSSL_SSL_H 1 +#define HAVE_OPENSSL_X509_H 1 +#define HAVE_PERROR 1 +#define HAVE_PWD_H 1 +#define HAVE_RAND_EGD 1 +#define HAVE_RAND_STATUS 1 +#define HAVE_SELECT 1 +#define HAVE_SETJMP_H 1 +#define HAVE_SGTTY_H 1 +#define HAVE_SIGNAL 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_SIG_ATOMIC_T 1 +#define HAVE_SOCKET 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRDUP 1 +#define HAVE_STRFTIME 1 +#define HAVE_STRICMP 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRSTR 1 +#define HAVE_STRUCT_TIMEVAL 1 +#define HAVE_SYS_PARAM_H 1 +#define HAVE_SYS_SOCKET_H 1 +#define HAVE_SYS_SOCKIO_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_TIME_H 1 +#define HAVE_UNAME 1 +#define HAVE_UNISTD_H 1 +#define HAVE_UTIME 1 +#define HAVE_UTIME_H 1 +#define HAVE_WRITABLE_ARGV 1 +#define HAVE_ZLIB_H 1 +#define HAVE_SYS_IOCTL_H 1 + +#define NEED_MALLOC_H 1 + +#define SIZEOF_INT 4 +#define SIZEOF_SHORT 2 +#define SIZEOF_SIZE_T 4 + +#define USE_MANUAL 1 +#define USE_OPENSSL 1 +#define CURL_DISABLE_LDAP 1 + +#define OS "AmigaOS" + +#define PACKAGE "curl" +#define PACKAGE_BUGREPORT "a suitable mailing list: https://curl.haxx.se/mail/" +#define PACKAGE_NAME "curl" +#define PACKAGE_STRING "curl -" +#define PACKAGE_TARNAME "curl" +#define PACKAGE_VERSION "-" +#define CURL_CA_BUNDLE "s:curl-ca-bundle.crt" + +#define RETSIGTYPE void +#define SELECT_TYPE_ARG1 int +#define SELECT_TYPE_ARG234 (fd_set *) +#define SELECT_TYPE_ARG5 (struct timeval *) + +#define STDC_HEADERS 1 +#define TIME_WITH_SYS_TIME 1 + +#define in_addr_t int + +#ifndef F_OK +# define F_OK 0 +#endif + +#ifndef O_RDONLY +# define O_RDONLY 0x0000 +#endif + +#ifndef LONG_MAX +# define LONG_MAX 0x7fffffffL +#endif + +#ifndef LONG_MIN +# define LONG_MIN (-0x7fffffffL-1) +#endif + +#define HAVE_GETNAMEINFO 1 +#define GETNAMEINFO_QUAL_ARG1 const +#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * +#define GETNAMEINFO_TYPE_ARG2 int +#define GETNAMEINFO_TYPE_ARG46 size_t +#define GETNAMEINFO_TYPE_ARG7 int + +#define HAVE_RECV 1 +#define RECV_TYPE_ARG1 long +#define RECV_TYPE_ARG2 char * +#define RECV_TYPE_ARG3 long +#define RECV_TYPE_ARG4 long +#define RECV_TYPE_RETV long + +#define HAVE_RECVFROM 1 +#define RECVFROM_TYPE_ARG1 long +#define RECVFROM_TYPE_ARG2 char +#define RECVFROM_TYPE_ARG3 long +#define RECVFROM_TYPE_ARG4 long +#define RECVFROM_TYPE_ARG5 struct sockaddr +#define RECVFROM_TYPE_ARG6 long +#define RECVFROM_TYPE_RETV long + +#define HAVE_SEND 1 +#define SEND_TYPE_ARG1 int +#define SEND_QUAL_ARG2 const +#define SEND_TYPE_ARG2 char * +#define SEND_TYPE_ARG3 int +#define SEND_TYPE_ARG4 int +#define SEND_TYPE_RETV int + +#endif /* __AMIGA__ */ +#endif /* HEADER_CURL_CONFIG_AMIGAOS_H */ diff --git a/libcurl/lib/config-dos.h b/libcurl/lib/config-dos.h new file mode 100644 index 0000000..3e973de --- /dev/null +++ b/libcurl/lib/config-dos.h @@ -0,0 +1,183 @@ +#ifndef HEADER_CURL_CONFIG_DOS_H +#define HEADER_CURL_CONFIG_DOS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + + +/* ================================================================ */ +/* lib/config-dos.h - Hand crafted config file for DOS */ +/* ================================================================ */ + +#if defined(DJGPP) + #define OS "MSDOS/djgpp" +#elif defined(__HIGHC__) + #define OS "MSDOS/HighC" +#elif defined(__WATCOMC__) + #define OS "MSDOS/Watcom" +#else + #define OS "MSDOS/?" +#endif + +#define PACKAGE "curl" + +#define HAVE_ARPA_INET_H 1 +#define HAVE_ASSERT_H 1 +#define HAVE_ERRNO_H 1 +#define HAVE_FCNTL_H 1 +#define HAVE_FREEADDRINFO 1 +#define HAVE_GETADDRINFO 1 +#define HAVE_GETNAMEINFO 1 +#define HAVE_GETPROTOBYNAME 1 +#define HAVE_GETTIMEOFDAY 1 +#define HAVE_IO_H 1 +#define HAVE_IOCTL 1 +#define HAVE_IOCTL_FIONBIO 1 +#define HAVE_IOCTLSOCKET 1 +#define HAVE_IOCTLSOCKET_FIONBIO 1 +#define HAVE_LOCALE_H 1 +#define HAVE_LONGLONG 1 +#define HAVE_MEMORY_H 1 +#define HAVE_NETDB_H 1 +#define HAVE_NETINET_IN_H 1 +#define HAVE_NETINET_TCP_H 1 +#define HAVE_NET_IF_H 1 +#define HAVE_PROCESS_H 1 +#define HAVE_RECV 1 +#define HAVE_RECVFROM 1 +#define HAVE_SELECT 1 +#define HAVE_SEND 1 +#define HAVE_SETJMP_H 1 +#define HAVE_SETLOCALE 1 +#define HAVE_SETMODE 1 +#define HAVE_SIGNAL 1 +#define HAVE_SOCKET 1 +#define HAVE_STRDUP 1 +#define HAVE_STRICMP 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRUCT_TIMEVAL 1 +#define HAVE_STRUCT_IN6_ADDR 1 +#define HAVE_SYS_IOCTL_H 1 +#define HAVE_SYS_SOCKET_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_TIME_H 1 +#define HAVE_UNISTD_H 1 + +#define NEED_MALLOC_H 1 + +#define RETSIGTYPE void +#define SIZEOF_INT 4 +#define SIZEOF_LONG 4 +#define SIZEOF_LONG_DOUBLE 16 +#define SIZEOF_SHORT 2 +#define SIZEOF_SIZE_T 4 +#define SIZEOF_CURL_OFF_T 4 +#define STDC_HEADERS 1 +#define TIME_WITH_SYS_TIME 1 + +/* Qualifiers for send(), recv(), recvfrom() and getnameinfo(). */ + +#define SEND_TYPE_ARG1 int +#define SEND_QUAL_ARG2 const +#define SEND_TYPE_ARG2 void * +#define SEND_TYPE_ARG3 int +#define SEND_TYPE_ARG4 int +#define SEND_TYPE_RETV int + +#define RECV_TYPE_ARG1 int +#define RECV_TYPE_ARG2 void * +#define RECV_TYPE_ARG3 int +#define RECV_TYPE_ARG4 int +#define RECV_TYPE_RETV int + +#define RECVFROM_TYPE_ARG1 int +#define RECVFROM_TYPE_ARG2 void +#define RECVFROM_TYPE_ARG3 int +#define RECVFROM_TYPE_ARG4 int +#define RECVFROM_TYPE_ARG5 struct sockaddr +#define RECVFROM_TYPE_ARG6 int +#define RECVFROM_TYPE_RETV int +#define RECVFROM_TYPE_ARG2_IS_VOID 1 + +#define GETNAMEINFO_QUAL_ARG1 const +#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * +#define GETNAMEINFO_TYPE_ARG2 int +#define GETNAMEINFO_TYPE_ARG46 int +#define GETNAMEINFO_TYPE_ARG7 int + +#define BSD + +/* CURLDEBUG definition enables memory tracking */ +/* #define CURLDEBUG */ + +/* USE_ZLIB on cmd-line */ +#ifdef USE_ZLIB + #define HAVE_ZLIB_H 1 + #define HAVE_LIBZ 1 +#endif + +/* USE_OPENSSL on cmd-line */ +#ifdef USE_OPENSSL + #define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 + #define HAVE_OPENSSL_ENGINE_H 1 + #define OPENSSL_NO_KRB5 1 +#endif + +/* to disable LDAP */ +#define CURL_DISABLE_LDAP 1 + +#define in_addr_t u_long + +#if defined(__HIGHC__) || \ + (defined(__GNUC__) && (__GNUC__ < 4)) + #define ssize_t int +#endif + +#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE") + +/* Target HAVE_x section */ + +#if defined(DJGPP) + #define HAVE_BASENAME 1 + #define HAVE_STRCASECMP 1 + #define HAVE_SIGACTION 1 + #define HAVE_SIGSETJMP 1 + #define HAVE_SYS_TIME_H 1 + #define HAVE_TERMIOS_H 1 + #define HAVE_VARIADIC_MACROS_GCC 1 + +#elif defined(__WATCOMC__) + #define HAVE_STRCASECMP 1 + +#elif defined(__HIGHC__) + #define HAVE_SYS_TIME_H 1 + #define strerror(e) strerror_s_((e)) +#endif + +#ifdef MSDOS /* Watt-32 */ + #define HAVE_CLOSE_S 1 +#endif + +#undef word +#undef byte + +#endif /* HEADER_CURL_CONFIG_DOS_H */ diff --git a/libcurl/lib/config-mac.h b/libcurl/lib/config-mac.h new file mode 100644 index 0000000..3c12bdf --- /dev/null +++ b/libcurl/lib/config-mac.h @@ -0,0 +1,125 @@ +#ifndef HEADER_CURL_CONFIG_MAC_H +#define HEADER_CURL_CONFIG_MAC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* =================================================================== */ +/* Hand crafted config file for Mac OS 9 */ +/* =================================================================== */ +/* On Mac OS X you must run configure to generate curl_config.h file */ +/* =================================================================== */ + +#define OS "mac" + +/* Define if you want the built-in manual */ +#define USE_MANUAL 1 + +#define HAVE_ERRNO_H 1 +#define HAVE_NETINET_IN_H 1 +#define HAVE_SYS_SOCKET_H 1 +#define HAVE_SYS_SELECT_H 1 +#define HAVE_NETDB_H 1 +#define HAVE_ARPA_INET_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_NET_IF_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_GETTIMEOFDAY 1 +#define HAVE_FCNTL_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_TIME_H 1 +#define HAVE_UTIME_H 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_UTIME_H 1 + +#define TIME_WITH_SYS_TIME 1 + +#define HAVE_ALARM 1 +#define HAVE_FTRUNCATE 1 +#define HAVE_UTIME 1 +#define HAVE_SETVBUF 1 +#define HAVE_STRFTIME 1 +#define HAVE_INET_ADDR 1 +#define HAVE_MEMCPY 1 +#define HAVE_SELECT 1 +#define HAVE_SOCKET 1 +#define HAVE_STRUCT_TIMEVAL 1 + +#define HAVE_SIGACTION 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_SIG_ATOMIC_T 1 + +#ifdef MACOS_SSL_SUPPORT +# define USE_OPENSSL 1 +#endif + +#define CURL_DISABLE_LDAP 1 + +#define HAVE_RAND_STATUS 1 +#define HAVE_RAND_EGD 1 + +#define HAVE_IOCTL 1 +#define HAVE_IOCTL_FIONBIO 1 + +#define RETSIGTYPE void + +#define SIZEOF_INT 4 +#define SIZEOF_SHORT 2 +#define SIZEOF_SIZE_T 4 + +#define HAVE_GETNAMEINFO 1 +#define GETNAMEINFO_QUAL_ARG1 const +#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * +#define GETNAMEINFO_TYPE_ARG2 socklen_t +#define GETNAMEINFO_TYPE_ARG46 size_t +#define GETNAMEINFO_TYPE_ARG7 int + +#define HAVE_RECV 1 +#define RECV_TYPE_ARG1 int +#define RECV_TYPE_ARG2 void * +#define RECV_TYPE_ARG3 size_t +#define RECV_TYPE_ARG4 int +#define RECV_TYPE_RETV ssize_t + +#define HAVE_RECVFROM 1 +#define RECVFROM_TYPE_ARG1 int +#define RECVFROM_TYPE_ARG2 void +#define RECVFROM_TYPE_ARG3 size_t +#define RECVFROM_TYPE_ARG4 int +#define RECVFROM_TYPE_ARG5 struct sockaddr +#define RECVFROM_TYPE_ARG6 int +#define RECVFROM_TYPE_RETV ssize_t +#define RECVFROM_TYPE_ARG2_IS_VOID 1 + +#define HAVE_SEND 1 +#define SEND_TYPE_ARG1 int +#define SEND_QUAL_ARG2 const +#define SEND_TYPE_ARG2 void * +#define SEND_TYPE_ARG3 size_T +#define SEND_TYPE_ARG4 int +#define SEND_TYPE_RETV ssize_t + +#define HAVE_EXTRA_STRICMP_H 1 +#define HAVE_EXTRA_STRDUP_H 1 + +#endif /* HEADER_CURL_CONFIG_MAC_H */ diff --git a/libcurl/lib/config-os400.h b/libcurl/lib/config-os400.h new file mode 100644 index 0000000..a741e91 --- /dev/null +++ b/libcurl/lib/config-os400.h @@ -0,0 +1,578 @@ +#ifndef HEADER_CURL_CONFIG_OS400_H +#define HEADER_CURL_CONFIG_OS400_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* Hand crafted config file for OS/400 */ +/* ================================================================ */ + +#pragma enum(int) + +#undef PACKAGE + +/* Version number of this archive. */ +#undef VERSION + +/* Define if you have the getpass function. */ +#undef HAVE_GETPASS + +/* Define cpu-machine-OS */ +#define OS "OS/400" + +/* Define if you have the gethostbyaddr_r() function with 5 arguments */ +#define HAVE_GETHOSTBYADDR_R_5 + +/* Define if you have the gethostbyaddr_r() function with 7 arguments */ +#undef HAVE_GETHOSTBYADDR_R_7 + +/* Define if you have the gethostbyaddr_r() function with 8 arguments */ +#undef HAVE_GETHOSTBYADDR_R_8 + +/* OS400 supports a 3-argument ASCII version of gethostbyaddr_r(), but its + * prototype is incompatible with the "standard" one (1st argument is not + * const). However, getaddrinfo() is supported (ASCII version defined as + * a local wrapper in setup-os400.h) in a threadsafe way: we can then + * configure getaddrinfo() as such and get rid of gethostbyname_r() without + * loss of threadsafeness. */ +#undef HAVE_GETHOSTBYNAME_R +#undef HAVE_GETHOSTBYNAME_R_3 +#undef HAVE_GETHOSTBYNAME_R_5 +#undef HAVE_GETHOSTBYNAME_R_6 +#define HAVE_GETADDRINFO +#define HAVE_GETADDRINFO_THREADSAFE + +/* Define if you need the _REENTRANT define for some functions */ +#undef NEED_REENTRANT + +/* Define if you have the Kerberos4 libraries (including -ldes) */ +#undef HAVE_KRB4 + +/* Define if you want to enable IPv6 support */ +#define ENABLE_IPV6 + +/* Define if struct sockaddr_in6 has the sin6_scope_id member */ +#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 + +/* Define this to 'int' if ssize_t is not an available typedefed type */ +#undef ssize_t + +/* Define this as a suitable file to read random data from */ +#undef RANDOM_FILE + +/* Define this to your Entropy Gathering Daemon socket pathname */ +#undef EGD_SOCKET + +/* Define to 1 if you have the alarm function. */ +#define HAVE_ALARM 1 + +/* Define if you have the header file. */ +#undef HAVE_ALLOCA_H + +/* Define if you have the header file. */ +#define HAVE_ARPA_INET_H + +/* Define if you have the `closesocket' function. */ +#undef HAVE_CLOSESOCKET + +/* Define if you have the header file. */ +#undef HAVE_CRYPTO_H + +/* Define if you have the header file. */ +#undef HAVE_DES_H + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H + +/* Define if you have the header file. */ +#undef HAVE_ERR_H + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H + +/* Define if you have the `geteuid' function. */ +#define HAVE_GETEUID + +/* Define if you have the `gethostbyaddr' function. */ +#define HAVE_GETHOSTBYADDR + +/* Define if you have the `gethostbyaddr_r' function. */ +#define HAVE_GETHOSTBYADDR_R + +/* Define if you have the `gethostname' function. */ +#define HAVE_GETHOSTNAME + +/* Define if you have the header file. */ +#undef HAVE_GETOPT_H + +/* Define if you have the `getpass_r' function. */ +#undef HAVE_GETPASS_R + +/* Define to 1 if you have the getpeername function. */ +#define HAVE_GETPEERNAME 1 + +/* Define if you have the `getpwuid' function. */ +#define HAVE_GETPWUID + +/* Define if you have the `getservbyname' function. */ +#define HAVE_GETSERVBYNAME + +/* Define to 1 if you have the getsockname function. */ +#define HAVE_GETSOCKNAME 1 + +/* Define if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY + +/* Define if you have the `timeval' struct. */ +#define HAVE_STRUCT_TIMEVAL + +/* Define if you have the `inet_addr' function. */ +#define HAVE_INET_ADDR + +/* Define if you have the header file. */ +#define HAVE_INTTYPES_H + +/* Define if you have the header file. */ +#undef HAVE_IO_H + +/* Define if you have the `krb_get_our_ip_for_realm' function. */ +#undef HAVE_KRB_GET_OUR_IP_FOR_REALM + +/* Define if you have the header file. */ +#undef HAVE_KRB_H + +/* Define if you have the `crypto' library (-lcrypto). */ +#undef HAVE_LIBCRYPTO + +/* Define if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define if you have the `resolv' library (-lresolv). */ +#undef HAVE_LIBRESOLV + +/* Define if you have the `resolve' library (-lresolve). */ +#undef HAVE_LIBRESOLVE + +/* Define if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define if you have the `ssl' library (-lssl). */ +#undef HAVE_LIBSSL + +/* Define if you have GSS API. */ +#define HAVE_GSSAPI + +/* Define if you have the GNU gssapi libraries */ +#undef HAVE_GSSGNU + +/* Define if you have the Heimdal gssapi libraries */ +#define HAVE_GSSHEIMDAL + +/* Define if you have the MIT gssapi libraries */ +#undef HAVE_GSSMIT + +/* Define if you have the `ucb' library (-lucb). */ +#undef HAVE_LIBUCB + +/* Define if you have the `localtime_r' function. */ +#define HAVE_LOCALTIME_R + +/* Define if you have the header file. */ +#define HAVE_MALLOC_H + +/* Define if you need the malloc.h header file even with stdlib.h */ +/* #define NEED_MALLOC_H 1 */ + +/* Define if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have the header file. */ +#define HAVE_NETDB_H + +/* Define if you have the header file. */ +#undef HAVE_NETINET_IF_ETHER_H + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H + +/* Define if you have the header file. */ +#define HAVE_NET_IF_H + +/* Define if you have the header file. */ +#undef HAVE_OPENSSL_CRYPTO_H + +/* Define if you have the header file. */ +#undef HAVE_OPENSSL_ERR_H + +/* Define if you have the header file. */ +#undef HAVE_OPENSSL_PEM_H + +/* Define if you have the header file. */ +#undef HAVE_OPENSSL_RSA_H + +/* Define if you have the header file. */ +#undef HAVE_OPENSSL_SSL_H + +/* Define if you have the header file. */ +#undef HAVE_OPENSSL_X509_H + +/* Define if you have the header file. */ +#undef HAVE_PEM_H + +/* Define if you have the `perror' function. */ +#define HAVE_PERROR + +/* Define if you have the header file. */ +#define HAVE_PWD_H + +/* Define if you have the `RAND_egd' function. */ +#undef HAVE_RAND_EGD + +/* Define if you have the `RAND_screen' function. */ +#undef HAVE_RAND_SCREEN + +/* Define if you have the `RAND_status' function. */ +#undef HAVE_RAND_STATUS + +/* Define if you have the header file. */ +#undef HAVE_RSA_H + +/* Define if you have the `select' function. */ +#define HAVE_SELECT + +/* Define if you have the `setvbuf' function. */ +#define HAVE_SETVBUF + +/* Define if you have the header file. */ +#undef HAVE_SGTTY_H + +/* Define if you have the `sigaction' function. */ +#define HAVE_SIGACTION + +/* Define if you have the `signal' function. */ +#undef HAVE_SIGNAL + +/* Define if you have the header file. */ +#define HAVE_SIGNAL_H + +/* Define if sig_atomic_t is an available typedef. */ +#define HAVE_SIG_ATOMIC_T + +/* Define if sig_atomic_t is already defined as volatile. */ +#undef HAVE_SIG_ATOMIC_T_VOLATILE + +/* Define if you have the `socket' function. */ +#define HAVE_SOCKET + +/* Define if you have the header file. */ +#undef HAVE_SSL_H + +/* Define if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + + +/* The following define is needed on OS400 to enable strcmpi(), stricmp() and + strdup(). */ +#define __cplusplus__strings__ + +/* Define if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define if you have the `strcmpi' function. */ +#define HAVE_STRCMPI + +/* Define if you have the `stricmp' function. */ +#define HAVE_STRICMP + +/* Define if you have the `strdup' function. */ +#define HAVE_STRDUP + + +/* Define if you have the `strftime' function. */ +#define HAVE_STRFTIME + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H + +/* Define if you have the header file. */ +#define HAVE_STRING_H + +/* Define if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define if you have the header file. */ +#undef HAVE_STROPTS_H + +/* Define if you have the `strstr' function. */ +#define HAVE_STRSTR + +/* Define if you have the `strtok_r' function. */ +#define HAVE_STRTOK_R + +/* Define if you have the `strtoll' function. */ +#undef HAVE_STRTOLL /* Allows ASCII compile on V5R1. */ + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SOCKIO_H + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H + +/* Define if you have the header file. */ +#define HAVE_SYS_UN_H + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H + +/* Define if you have the `tcgetattr' function. */ +#undef HAVE_TCGETATTR + +/* Define if you have the `tcsetattr' function. */ +#undef HAVE_TCSETATTR + +/* Define if you have the header file. */ +#undef HAVE_TERMIOS_H + +/* Define if you have the header file. */ +#undef HAVE_TERMIO_H + +/* Define if you have the header file. */ +#define HAVE_TIME_H + +/* Define if you have the `uname' function. */ +#undef HAVE_UNAME + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H + +/* Define if you have the header file. */ +#undef HAVE_WINSOCK_H + +/* Define if you have the header file. */ +#undef HAVE_X509_H + +/* Name of package */ +#undef PACKAGE + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* The size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of a `long double', as computed by sizeof. */ +#define SIZEOF_LONG_DOUBLE 8 + +/* Define if the compiler supports the 'long long' data type. */ +#define HAVE_LONGLONG + +/* The size of a `long long', as computed by sizeof. */ +#define SIZEOF_LONG_LONG 8 + +/* The size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* The size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 4 + +/* The size of `size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 4 + +/* The size of `curl_off_t', as computed by sizeof. */ +#define SIZEOF_CURL_OFF_T 8 + +/* Whether long long constants must be suffixed by LL. */ + +#define HAVE_LL + +/* Define this if you have struct sockaddr_storage */ +#define HAVE_STRUCT_SOCKADDR_STORAGE + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME + +/* Define to enable alt-svc support (experimental) */ +#undef USE_ALTSVC + +/* Version number of package */ +#undef VERSION + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#define _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* type to use in place of in_addr_t if not defined */ +#define in_addr_t unsigned long + +/* Define to `unsigned' if does not define. */ +#undef size_t + +/* Define if you have the ioctl function. */ +#define HAVE_IOCTL + +/* Define if you have a working ioctl FIONBIO function. */ +#define HAVE_IOCTL_FIONBIO + +/* Define if you have a working ioctl SIOCGIFADDR function. */ +#define HAVE_IOCTL_SIOCGIFADDR + +/* To disable LDAP */ +#undef CURL_DISABLE_LDAP + +/* Definition to make a library symbol externally visible. */ +#define CURL_EXTERN_SYMBOL + +/* Define if you have the ldap_url_parse procedure. */ +/* #define HAVE_LDAP_URL_PARSE */ /* Disabled because of an IBM bug. */ + +/* Define if you have the getnameinfo function. */ +/* OS400 has no ASCII version of this procedure: wrapped in setup-os400.h. */ +#define HAVE_GETNAMEINFO + +/* Define to the type qualifier of arg 1 for getnameinfo. */ +#define GETNAMEINFO_QUAL_ARG1 const + +/* Define to the type of arg 1 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * + +/* Define to the type of arg 2 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG2 socklen_t + +/* Define to the type of args 4 and 6 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG46 socklen_t + +/* Define to the type of arg 7 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG7 int + +/* Define if you have the recv function. */ +#define HAVE_RECV + +/* Define to the type of arg 1 for recv. */ +#define RECV_TYPE_ARG1 int + +/* Define to the type of arg 2 for recv. */ +#define RECV_TYPE_ARG2 char * + +/* Define to the type of arg 3 for recv. */ +#define RECV_TYPE_ARG3 int + +/* Define to the type of arg 4 for recv. */ +#define RECV_TYPE_ARG4 int + +/* Define to the function return type for recv. */ +#define RECV_TYPE_RETV int + +/* Define if you have the recvfrom function. */ +#define HAVE_RECVFROM + +/* Define to the type of arg 1 for recvfrom. */ +#define RECVFROM_TYPE_ARG1 int + +/* Define to the type pointed by arg 2 for recvfrom. */ +#define RECVFROM_TYPE_ARG2 char + +/* Define to the type of arg 3 for recvfrom. */ +#define RECVFROM_TYPE_ARG3 int + +/* Define to the type of arg 4 for recvfrom. */ +#define RECVFROM_TYPE_ARG4 int + +/* Define to the type pointed by arg 5 for recvfrom. */ +#define RECVFROM_TYPE_ARG5 struct sockaddr + +/* Define to the type pointed by arg 6 for recvfrom. */ +#define RECVFROM_TYPE_ARG6 int + +/* Define to the function return type for recvfrom. */ +#define RECVFROM_TYPE_RETV int + +/* Define if you have the send function. */ +#define HAVE_SEND + +/* Define to the type of arg 1 for send. */ +#define SEND_TYPE_ARG1 int + +/* Define to the type qualifier of arg 2 for send. */ +#define SEND_QUAL_ARG2 + +/* Define to the type of arg 2 for send. */ +#define SEND_TYPE_ARG2 char * + +/* Define to the type of arg 3 for send. */ +#define SEND_TYPE_ARG3 int + +/* Define to the type of arg 4 for send. */ +#define SEND_TYPE_ARG4 int + +/* Define to the function return type for send. */ +#define SEND_TYPE_RETV int + +/* Define to use the GSKit package. */ +#define USE_GSKIT + +/* Define to use the OS/400 crypto library. */ +#define USE_OS400CRYPTO + +/* Define to use Unix sockets. */ +#define USE_UNIX_SOCKETS + +/* Use the system keyring as the default CA bundle. */ +#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB" + +/* ---------------------------------------------------------------- */ +/* ADDITIONAL DEFINITIONS */ +/* ---------------------------------------------------------------- */ + +/* The following must be defined BEFORE system header files inclusion. */ + +#define __ptr128 /* No teraspace. */ +#define qadrt_use_fputc_inline /* Generate fputc() wrapper inline. */ +#define qadrt_use_fread_inline /* Generate fread() wrapper inline. */ +#define qadrt_use_fwrite_inline /* Generate fwrite() wrapper inline. */ + +#endif /* HEADER_CURL_CONFIG_OS400_H */ diff --git a/libcurl/lib/config-riscos.h b/libcurl/lib/config-riscos.h new file mode 100644 index 0000000..0379524 --- /dev/null +++ b/libcurl/lib/config-riscos.h @@ -0,0 +1,513 @@ +#ifndef HEADER_CURL_CONFIG_RISCOS_H +#define HEADER_CURL_CONFIG_RISCOS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* Hand crafted config file for RISC OS */ +/* ================================================================ */ + +/* Name of this package! */ +#undef PACKAGE + +/* Version number of this archive. */ +#undef VERSION + +/* Define if you have the getpass function. */ +#undef HAVE_GETPASS + +/* Define cpu-machine-OS */ +#define OS "ARM-RISC OS" + +/* Define if you want the built-in manual */ +#define USE_MANUAL + +/* Define if you have the gethostbyaddr_r() function with 5 arguments */ +#undef HAVE_GETHOSTBYADDR_R_5 + +/* Define if you have the gethostbyaddr_r() function with 7 arguments */ +#undef HAVE_GETHOSTBYADDR_R_7 + +/* Define if you have the gethostbyaddr_r() function with 8 arguments */ +#undef HAVE_GETHOSTBYADDR_R_8 + +/* Define if you have the gethostbyname_r() function with 3 arguments */ +#undef HAVE_GETHOSTBYNAME_R_3 + +/* Define if you have the gethostbyname_r() function with 5 arguments */ +#undef HAVE_GETHOSTBYNAME_R_5 + +/* Define if you have the gethostbyname_r() function with 6 arguments */ +#undef HAVE_GETHOSTBYNAME_R_6 + +/* Define if you need the _REENTRANT define for some functions */ +#undef NEED_REENTRANT + +/* Define if you have the Kerberos4 libraries (including -ldes) */ +#undef HAVE_KRB4 + +/* Define if you want to enable IPv6 support */ +#undef ENABLE_IPV6 + +/* Define if struct sockaddr_in6 has the sin6_scope_id member */ +#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 + +/* Define this to 'int' if ssize_t is not an available typedefed type */ +#undef ssize_t + +/* Define this as a suitable file to read random data from */ +#undef RANDOM_FILE + +/* Define this to your Entropy Gathering Daemon socket pathname */ +#undef EGD_SOCKET + +/* Define if you want to enable IPv6 support */ +#undef ENABLE_IPV6 + +/* Define if you have the alarm function. */ +#define HAVE_ALARM + +/* Define if you have the header file. */ +#define HAVE_ALLOCA_H + +/* Define if you have the header file. */ +#define HAVE_ARPA_INET_H + +/* Define if you have the `closesocket' function. */ +#undef HAVE_CLOSESOCKET + +/* Define if you have the header file. */ +#undef HAVE_CRYPTO_H + +/* Define if you have the header file. */ +#undef HAVE_DES_H + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H + +/* Define if you have the header file. */ +#undef HAVE_ERR_H + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H + +/* Define if you have the `ftruncate' function. */ +#define HAVE_FTRUNCATE + +/* Define if getaddrinfo exists and works */ +#define HAVE_GETADDRINFO + +/* Define if you have the `geteuid' function. */ +#undef HAVE_GETEUID + +/* Define if you have the `gethostbyaddr' function. */ +#define HAVE_GETHOSTBYADDR + +/* Define if you have the `gethostbyaddr_r' function. */ +#undef HAVE_GETHOSTBYADDR_R + +/* Define if you have the `gethostbyname_r' function. */ +#undef HAVE_GETHOSTBYNAME_R + +/* Define if you have the `gethostname' function. */ +#define HAVE_GETHOSTNAME + +/* Define if you have the header file. */ +#define HAVE_GETOPT_H + +/* Define if you have the `getpass_r' function. */ +#undef HAVE_GETPASS_R + +/* Define if you have the `getpwuid' function. */ +#undef HAVE_GETPWUID + +/* Define if you have the `getservbyname' function. */ +#undef HAVE_GETSERVBYNAME + +/* Define if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY + +/* Define if you have the `timeval' struct. */ +#define HAVE_STRUCT_TIMEVAL + +/* Define if you have the `inet_addr' function. */ +#undef HAVE_INET_ADDR + +/* Define if you have the header file. */ +#define HAVE_INTTYPES_H + +/* Define if you have the header file. */ +#undef HAVE_IO_H + +/* Define if you have the `krb_get_our_ip_for_realm' function. */ +#undef HAVE_KRB_GET_OUR_IP_FOR_REALM + +/* Define if you have the header file. */ +#undef HAVE_KRB_H + +/* Define if you have the `crypto' library (-lcrypto). */ +#undef HAVE_LIBCRYPTO + +/* Define if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define if you have the `resolv' library (-lresolv). */ +#undef HAVE_LIBRESOLV + +/* Define if you have the `resolve' library (-lresolve). */ +#undef HAVE_LIBRESOLVE + +/* Define if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define if you have the `ssl' library (-lssl). */ +#undef HAVE_LIBSSL + +/* Define if you have the `ucb' library (-lucb). */ +#undef HAVE_LIBUCB + +/* Define if you have the `localtime_r' function. */ +#undef HAVE_LOCALTIME_R + +/* Define if you have the header file. */ +#define HAVE_MALLOC_H + +/* Define if you need the malloc.h header file even with stdlib.h */ +/* #define NEED_MALLOC_H 1 */ + +/* Define if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have the header file. */ +#define HAVE_NETDB_H + +/* Define if you have the header file. */ +#undef HAVE_NETINET_IF_ETHER_H + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H + +/* Define if you have the header file. */ +#define HAVE_NET_IF_H + +/* Define if you have the header file. */ +#undef HAVE_OPENSSL_CRYPTO_H + +/* Define if you have the header file. */ +#undef HAVE_OPENSSL_ERR_H + +/* Define if you have the header file. */ +#undef HAVE_OPENSSL_PEM_H + +/* Define if you have the header file. */ +#undef HAVE_OPENSSL_RSA_H + +/* Define if you have the header file. */ +#undef HAVE_OPENSSL_SSL_H + +/* Define if you have the header file. */ +#undef HAVE_OPENSSL_X509_H + +/* Define if you have the header file. */ +#undef HAVE_PEM_H + +/* Define if you have the `perror' function. */ +#undef HAVE_PERROR + +/* Define if you have the header file. */ +#undef HAVE_PWD_H + +/* Define if you have the `RAND_egd' function. */ +#undef HAVE_RAND_EGD + +/* Define if you have the `RAND_screen' function. */ +#undef HAVE_RAND_SCREEN + +/* Define if you have the `RAND_status' function. */ +#undef HAVE_RAND_STATUS + +/* Define if you have the header file. */ +#undef HAVE_RSA_H + +/* Define if you have the `select' function. */ +#define HAVE_SELECT + +/* Define if you have the `setvbuf' function. */ +#undef HAVE_SETVBUF + +/* Define if you have the header file. */ +#define HAVE_SGTTY_H + +/* Define if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define if you have the `signal' function. */ +#define HAVE_SIGNAL + +/* Define if you have the header file. */ +#define HAVE_SIGNAL_H + +/* Define if sig_atomic_t is an available typedef. */ +#define HAVE_SIG_ATOMIC_T + +/* Define if sig_atomic_t is already defined as volatile. */ +#undef HAVE_SIG_ATOMIC_T_VOLATILE + +/* Define if you have the `socket' function. */ +#define HAVE_SOCKET + +/* Define if you have the header file. */ +#undef HAVE_SSL_H + +/* Define if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define if you have the `strcmpi' function. */ +#undef HAVE_STRCMPI + +/* Define if you have the `strdup' function. */ +#define HAVE_STRDUP + +/* Define if you have the `strftime' function. */ +#define HAVE_STRFTIME + +/* Define if you have the `stricmp' function. */ +#define HAVE_STRICMP + +/* Define if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define if you have the header file. */ +#define HAVE_STRING_H + +/* Define if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define if you have the `strstr' function. */ +#define HAVE_STRSTR + +/* Define if you have the `strtok_r' function. */ +#undef HAVE_STRTOK_R + +/* Define if you have the `strtoll' function. */ +#undef HAVE_STRTOLL + +/* Define if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_SOCKIO_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H + +/* Define if you have the `tcgetattr' function. */ +#define HAVE_TCGETATTR + +/* Define if you have the `tcsetattr' function. */ +#define HAVE_TCSETATTR + +/* Define if you have the header file. */ +#define HAVE_TERMIOS_H + +/* Define if you have the header file. */ +#undef HAVE_TERMIO_H + +/* Define if you have the header file. */ +#undef HAVE_TIME_H + +/* Define if you have the `uname' function. */ +#define HAVE_UNAME + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H + +/* Define if you have the header file. */ +#undef HAVE_WINSOCK_H + +/* Define if you have the header file. */ +#undef HAVE_X509_H + +/* Name of package */ +#undef PACKAGE + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* The size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of `long double', as computed by sizeof. */ +#undef SIZEOF_LONG_DOUBLE + +/* The size of `long long', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG + +/* The size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* The size of `size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 4 + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `unsigned' if does not define. */ +#undef size_t + +/* Define to `int' if does not define. */ +#undef ssize_t + +/* Define if you have the ioctl function. */ +#define HAVE_IOCTL + +/* Define if you have a working ioctl FIONBIO function. */ +#define HAVE_IOCTL_FIONBIO + +/* to disable LDAP */ +#define CURL_DISABLE_LDAP + +/* Define if you have the getnameinfo function. */ +#define HAVE_GETNAMEINFO 1 + +/* Define to the type qualifier of arg 1 for getnameinfo. */ +#define GETNAMEINFO_QUAL_ARG1 const + +/* Define to the type of arg 1 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * + +/* Define to the type of arg 2 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG2 socklen_t + +/* Define to the type of args 4 and 6 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG46 size_t + +/* Define to the type of arg 7 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG7 int + +/* Define if you have the recv function. */ +#define HAVE_RECV 1 + +/* Define to the type of arg 1 for recv. */ +#define RECV_TYPE_ARG1 int + +/* Define to the type of arg 2 for recv. */ +#define RECV_TYPE_ARG2 void * + +/* Define to the type of arg 3 for recv. */ +#define RECV_TYPE_ARG3 size_t + +/* Define to the type of arg 4 for recv. */ +#define RECV_TYPE_ARG4 int + +/* Define to the function return type for recv. */ +#define RECV_TYPE_RETV ssize_t + +/* Define 1 if you have the recvfrom function. */ +#define HAVE_RECVFROM 1 + +/* Define to the type of arg 1 for recvfrom. */ +#define RECVFROM_TYPE_ARG1 int + +/* Define to the type pointed by arg 2 for recvfrom. */ +#define RECVFROM_TYPE_ARG2 void + +/* Define if the type pointed by arg 2 for recvfrom is void. */ +#define RECVFROM_TYPE_ARG2_IS_VOID + +/* Define to the type of arg 3 for recvfrom. */ +#define RECVFROM_TYPE_ARG3 size_t + +/* Define to the type of arg 4 for recvfrom. */ +#define RECVFROM_TYPE_ARG4 int + +/* Define to the type pointed by arg 5 for recvfrom. */ +#define RECVFROM_TYPE_ARG5 struct sockaddr + +/* Define to the type pointed by arg 6 for recvfrom. */ +#define RECVFROM_TYPE_ARG6 int + +/* Define to the function return type for recvfrom. */ +#define RECVFROM_TYPE_RETV ssize_t + +/* Define if you have the send function. */ +#define HAVE_SEND 1 + +/* Define to the type of arg 1 for send. */ +#define SEND_TYPE_ARG1 int + +/* Define to the type qualifier of arg 2 for send. */ +#define SEND_QUAL_ARG2 const + +/* Define to the type of arg 2 for send. */ +#define SEND_TYPE_ARG2 void * + +/* Define to the type of arg 3 for send. */ +#define SEND_TYPE_ARG3 size_t + +/* Define to the type of arg 4 for send. */ +#define SEND_TYPE_ARG4 int + +/* Define to the function return type for send. */ +#define SEND_TYPE_RETV ssize_t + +#endif /* HEADER_CURL_CONFIG_RISCOS_H */ diff --git a/libcurl/lib/config-symbian.h b/libcurl/lib/config-symbian.h new file mode 100644 index 0000000..b7b93c6 --- /dev/null +++ b/libcurl/lib/config-symbian.h @@ -0,0 +1,805 @@ +#ifndef HEADER_CURL_CONFIG_SYMBIAN_H +#define HEADER_CURL_CONFIG_SYMBIAN_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* Hand crafted config file for Symbian */ +/* ================================================================ */ + +/* Location of default ca bundle */ +/* #define CURL_CA_BUNDLE "/etc/pki/tls/certs/ca-bundle.crt"*/ + +/* Location of default ca path */ +/* #undef CURL_CA_PATH */ + +/* to disable cookies support */ +/* #undef CURL_DISABLE_COOKIES */ + +/* to disable cryptographic authentication */ +/* #undef CURL_DISABLE_CRYPTO_AUTH */ + +/* to disable DICT */ +/* #undef CURL_DISABLE_DICT */ + +/* to disable FILE */ +/* #undef CURL_DISABLE_FILE */ + +/* to disable FTP */ +/* #undef CURL_DISABLE_FTP */ + +/* to disable HTTP */ +/* #undef CURL_DISABLE_HTTP */ + +/* to disable LDAP */ +#define CURL_DISABLE_LDAP 1 + +/* to disable LDAPS */ +#define CURL_DISABLE_LDAPS 1 + +/* to disable TELNET */ +/* #undef CURL_DISABLE_TELNET */ + +/* to disable TFTP */ +/* #undef CURL_DISABLE_TFTP */ + +/* to disable verbose strings */ +/* #define CURL_DISABLE_VERBOSE_STRINGS 1*/ + +/* Definition to make a library symbol externally visible. */ +/* #undef CURL_EXTERN_SYMBOL */ + +/* Use Windows LDAP implementation */ +/* #undef USE_WIN32_LDAP */ + +/* your Entropy Gathering Daemon socket pathname */ +/* #undef EGD_SOCKET */ + +/* Define if you want to enable IPv6 support */ +#define ENABLE_IPV6 1 + +/* Define if struct sockaddr_in6 has the sin6_scope_id member */ +#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 + +/* Define to the type qualifier of arg 1 for getnameinfo. */ +#define GETNAMEINFO_QUAL_ARG1 const + +/* Define to the type of arg 1 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * + +/* Define to the type of arg 2 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG2 socklen_t + +/* Define to the type of args 4 and 6 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG46 size_t + +/* Define to the type of arg 7 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG7 int + +/* Define to 1 if you have the header file. */ +/*#define HAVE_ALLOCA_H 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +/*#define HAVE_ARPA_TFTP_H 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_ASSERT_H 1 + +/* Define to 1 if you have the `basename' function. */ +/*#define HAVE_BASENAME 1*/ + +/* Define to 1 if bool is an available type. */ +/*#define HAVE_BOOL_T 1*/ + +/* Define to 1 if you have the `closesocket' function. */ +/* #undef HAVE_CLOSESOCKET */ + +/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ +/*#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1*/ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CRYPTO_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DES_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ +/*#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERR_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the fcntl function. */ +#define HAVE_FCNTL 1 + +/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ +#define HAVE_FCNTL_O_NONBLOCK 1 + +/* Define to 1 if you have the `fork' function. */ +/*#define HAVE_FORK 1*/ + +/* Define to 1 if you have the `ftruncate' function. */ +#define HAVE_FTRUNCATE 1 + +/* Define if getaddrinfo exists and works */ +#define HAVE_GETADDRINFO 1 + +/* Define to 1 if you have the `geteuid' function. */ +#define HAVE_GETEUID 1 + +/* Define to 1 if you have the `gethostbyaddr' function. */ +#define HAVE_GETHOSTBYADDR 1 + +/* If you have gethostbyname */ +#define HAVE_GETHOSTBYNAME 1 + +/* Define to 1 if you have the `gethostbyname_r' function. */ +/* #undef HAVE_GETHOSTBYNAME_R */ + +/* gethostbyname_r() takes 3 args */ +/* #undef HAVE_GETHOSTBYNAME_R_3 */ + +/* gethostbyname_r() takes 5 args */ +/* #undef HAVE_GETHOSTBYNAME_R_5 */ + +/* gethostbyname_r() takes 6 args */ +/* #undef HAVE_GETHOSTBYNAME_R_6 */ + +/* Define to 1 if you have the getnameinfo function. */ +#define HAVE_GETNAMEINFO 1 + +/* Define to 1 if you have the `getpass_r' function. */ +/* #undef HAVE_GETPASS_R */ + +/* Define to 1 if you have the `getppid' function. */ +#define HAVE_GETPPID 1 + +/* Define to 1 if you have the `getprotobyname' function. */ +#define HAVE_GETPROTOBYNAME 1 + +/* Define to 1 if you have the `getpwuid' function. */ +#define HAVE_GETPWUID 1 + +/* Define to 1 if you have the `getrlimit' function. */ +/*#define HAVE_GETRLIMIT 1*/ + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* we have a glibc-style strerror_r() */ +/* #undef HAVE_GLIBC_STRERROR_R */ + +/* Define to 1 if you have the `gmtime_r' function. */ +#define HAVE_GMTIME_R 1 + +/* if you have the gssapi libraries */ +/* #undef HAVE_GSSAPI */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */ + +/* if you have the GNU gssapi libraries */ +/* #undef HAVE_GSSGNU */ + +/* if you have the Heimdal gssapi libraries */ +/* #undef HAVE_GSSHEIMDAL */ + +/* if you have the MIT gssapi libraries */ +/* #undef HAVE_GSSMIT */ + +/* Define to 1 if you have the `idna_strerror' function. */ +/*#define HAVE_IDNA_STRERROR 1*/ + +/* Define to 1 if you have the `idn_free' function. */ +/*#define HAVE_IDN_FREE 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_IDN_FREE_H 1*/ + +/* Define to 1 if you have the `inet_addr' function. */ +/*#define HAVE_INET_ADDR 1*/ + +/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ +/*#define HAVE_INET_NTOP 1*/ + +/* Define to 1 if you have a IPv6 capable working inet_pton function. */ +/*#define HAVE_INET_PTON 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the ioctl function. */ +#define HAVE_IOCTL 1 + +/* Define to 1 if you have a working ioctl FIONBIO function. */ +#define HAVE_IOCTL_FIONBIO 1 + +/* Define to 1 if you have the ioctlsocket function. */ +/* #undef HAVE_IOCTLSOCKET */ + +/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ +/* #undef HAVE_IOCTLSOCKET_FIONBIO */ + +/* Define to 1 if you have the IoctlSocket camel case function. */ +/* #undef HAVE_IOCTLSOCKET_CAMEL */ + +/* Define to 1 if you have a working IoctlSocket camel case FIONBIO + function. */ +/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IO_H */ + +/* if you have the Kerberos4 libraries (including -ldes) */ +/* #undef HAVE_KRB4 */ + +/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ +/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_KRB_H */ + +/* Define to 1 if you have the lber.h header file. */ +/*#define HAVE_LBER_H 1*/ + +/* Define to 1 if you have the ldapssl.h header file. */ +/* #undef HAVE_LDAPSSL_H */ + +/* Define to 1 if you have the ldap.h header file. */ +/*#define HAVE_LDAP_H 1*/ + +/* Use LDAPS implementation */ +/*#define HAVE_LDAP_SSL 1*/ + +/* Define to 1 if you have the ldap_ssl.h header file. */ +/* #undef HAVE_LDAP_SSL_H */ + +/* Define to 1 if you have the `ldap_url_parse' function. */ +/*#define HAVE_LDAP_URL_PARSE 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_LIBGEN_H 1*/ + +/* Define to 1 if you have the `idn' library (-lidn). */ +/*#define HAVE_LIBIDN 1*/ + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +/* #undef HAVE_LIBRESOLV */ + +/* Define to 1 if you have the `resolve' library (-lresolve). */ +/* #undef HAVE_LIBRESOLVE */ + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the `ssh2' library (-lssh2). */ +/*#define HAVE_LIBSSH2 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_LIBSSH2_H 1*/ + +/* Define to 1 if you have the `ssl' library (-lssl). */ +/*#define HAVE_LIBSSL 1*/ + +/* if your compiler supports LL */ +#define HAVE_LL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define to 1 if you have the `localtime_r' function. */ +#define HAVE_LOCALTIME_R 1 + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#define HAVE_LONGLONG 1 + +/* Define to 1 if you have the malloc.h header file. */ +/*#define HAVE_MALLOC_H 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the MSG_NOSIGNAL flag. */ +/*#define HAVE_MSG_NOSIGNAL 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +/*#define HAVE_NETINET_TCP_H 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define to 1 if NI_WITHSCOPEID exists and works. */ +/*#define HAVE_NI_WITHSCOPEID 1*/ + +/* we have no strerror_r() proto */ +/* #undef HAVE_NO_STRERROR_R_DECL */ + +/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE + */ +/* #undef HAVE_OLD_GSSMIT */ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_OPENSSL_CRYPTO_H 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_OPENSSL_ENGINE_H 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_OPENSSL_ERR_H 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_OPENSSL_PEM_H 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_OPENSSL_PKCS12_H 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_OPENSSL_RSA_H 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_OPENSSL_SSL_H 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_OPENSSL_X509_H 1*/ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PEM_H */ + +/* Define to 1 if you have the `perror' function. */ +#define HAVE_PERROR 1 + +/* Define to 1 if you have the `pipe' function. */ +#define HAVE_PIPE 1 + +/* Define to 1 if you have the `poll' function. */ +/*#define HAVE_POLL 1*/ + +/* If you have a fine poll */ +/*#define HAVE_POLL_FINE 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_POLL_H 1*/ + +/* we have a POSIX-style strerror_r() */ +#define HAVE_POSIX_STRERROR_R 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define to 1 if you have the `RAND_egd' function. */ +#define HAVE_RAND_EGD 1 + +/* Define to 1 if you have the `RAND_screen' function. */ +/* #undef HAVE_RAND_SCREEN */ + +/* Define to 1 if you have the `RAND_status' function. */ +/*#define HAVE_RAND_STATUS 1*/ + +/* Define to 1 if you have the recv function. */ +#define HAVE_RECV 1 + +/* Define to 1 if you have the recvfrom function. */ +#define HAVE_RECVFROM 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_RSA_H */ + +/* Define to 1 if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define to 1 if you have the send function. */ +#define HAVE_SEND 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SETJMP_H 1 + +/* Define to 1 if you have the `setlocale' function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if you have the `setmode' function. */ +/* #undef HAVE_SETMODE */ + +/* Define to 1 if you have the `setrlimit' function. */ +/*#define HAVE_SETRLIMIT 1*/ + +/* Define to 1 if you have the setsockopt function. */ +/* #undef HAVE_SETSOCKOPT */ + +/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ +/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_SGTTY_H 1*/ + +/* Define to 1 if you have the `sigaction' function. */ +/*#define HAVE_SIGACTION 1*/ + +/* Define to 1 if you have the `siginterrupt' function. */ +/*#define HAVE_SIGINTERRUPT 1*/ + +/* Define to 1 if you have the `signal' function. */ +/*#define HAVE_SIGNAL 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* If you have sigsetjmp */ +/*#define HAVE_SIGSETJMP 1*/ + +/* Define to 1 if sig_atomic_t is an available typedef. */ +/*#define HAVE_SIG_ATOMIC_T 1*/ + +/* Define to 1 if sig_atomic_t is already defined as volatile. */ +/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SSL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strcasecmp' function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the `strcmpi' function. */ +/* #undef HAVE_STRCMPI */ + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror_r' function. */ +#define HAVE_STRERROR_R 1 + +/* Define to 1 if you have the `stricmp' function. */ +/* #undef HAVE_STRICMP */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcpy' function. */ +#define HAVE_STRLCPY 1 + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if you have the `strtok_r' function. */ +#define HAVE_STRTOK_R 1 + +/* Define to 1 if you have the `strtoll' function. */ +#define HAVE_STRTOLL 1 + +/* if struct sockaddr_storage is defined */ +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 + +/* Define to 1 if you have the timeval struct. */ +#define HAVE_STRUCT_TIMEVAL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FILIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +/*#define HAVE_SYS_POLL_H 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_UTIME_H */ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_TERMIOS_H 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_TERMIO_H 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define to 1 if you have the header file. */ +/*#define HAVE_TLD_H 1*/ + +/* Define to 1 if you have the `tld_strerror' function. */ +/*#define HAVE_TLD_STRERROR 1*/ + +/* Define to 1 if you have the `uname' function. */ +#define HAVE_UNAME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `utime' function. */ +#define HAVE_UTIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTIME_H 1 + +/* Define to 1 if compiler supports C99 variadic macro style. */ +#define HAVE_VARIADIC_MACROS_C99 1 + +/* Define to 1 if compiler supports old gcc variadic macro style. */ +/*#define HAVE_VARIADIC_MACROS_GCC 1*/ + +/* Define to 1 if you have the winber.h header file. */ +/* #undef HAVE_WINBER_H */ + +/* Define to 1 if you have the windows.h header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if you have the winldap.h header file. */ +/* #undef HAVE_WINLDAP_H */ + +/* Define to 1 if you have the winsock2.h header file. */ +/* #undef HAVE_WINSOCK2_H */ + +/* Define to 1 if you have the winsock.h header file. */ +/* #undef HAVE_WINSOCK_H */ + +/* Define this symbol if your OS supports changing the contents of argv */ +/*#define HAVE_WRITABLE_ARGV 1*/ + +/* Define to 1 if you have the ws2tcpip.h header file. */ +/* #undef HAVE_WS2TCPIP_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_X509_H */ + +/* Define to 1 if you need the lber.h header file even with ldap.h */ +/* #undef NEED_LBER_H */ + +/* Define to 1 if you need the malloc.h header file even with stdlib.h */ +/* #undef NEED_MALLOC_H */ + +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ +/* #undef NEED_REENTRANT */ + +/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ +/* #undef NEED_THREAD_SAFE */ + +/* cpu-machine-OS */ +#ifdef __WINS__ +#define OS "i386-pc-epoc32" +#elif __MARM__ +#define OS "arm-unknown-epoc32" +#else +/* This won't happen on any current Symbian version */ +#define OS "unknown-unknown-epoc32" +#endif + +/* Name of package */ +/*#define PACKAGE "curl"*/ + +/* Define to the address where bug reports for this package should be sent. */ +/*#define PACKAGE_BUGREPORT \ + "a suitable curl mailing list => https://curl.haxx.se/mail/"*/ + +/* Define to the full name of this package. */ +/*#define PACKAGE_NAME "curl"*/ + +/* Define to the full name and version of this package. */ +/*#define PACKAGE_STRING "curl -"*/ + +/* Define to the one symbol short name of this package. */ +/*#define PACKAGE_TARNAME "curl"*/ + +/* Define to the version of this package. */ +/*#define PACKAGE_VERSION "-"*/ + +/* a suitable file to read random data from */ +/*#define RANDOM_FILE "/dev/urandom"*/ + +#define RECV_TYPE_ARG1 int +#define RECV_TYPE_ARG2 void * +#define RECV_TYPE_ARG3 size_t +#define RECV_TYPE_ARG4 int +#define RECV_TYPE_RETV ssize_t + +#define RECVFROM_TYPE_ARG1 int +#define RECVFROM_TYPE_ARG2 void +#define RECVFROM_TYPE_ARG3 size_t +#define RECVFROM_TYPE_ARG4 int +#define RECVFROM_TYPE_ARG5 struct sockaddr +#define RECVFROM_TYPE_ARG6 size_t +#define RECVFROM_TYPE_RETV ssize_t +#define RECVFROM_TYPE_ARG2_IS_VOID 1 + +#define SEND_TYPE_ARG1 int +#define SEND_QUAL_ARG2 const +#define SEND_TYPE_ARG2 void * +#define SEND_TYPE_ARG3 size_t +#define SEND_TYPE_ARG4 int +#define SEND_TYPE_RETV ssize_t + + +/* Define as the return type of signal handlers (`int' or `void'). */ +/*#define RETSIGTYPE void*/ + +/* Define to the type of arg 1 for `select'. */ +#define SELECT_TYPE_ARG1 int + +/* Define to the type of args 2, 3 and 4 for `select'. */ +#define SELECT_TYPE_ARG234 (fd_set *) + +/* Define to the type of arg 5 for `select'. */ +#define SELECT_TYPE_ARG5 (struct timeval *) + +/* The size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of `off_t', as computed by sizeof. */ +#define SIZEOF_OFF_T 8 + +/* The size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* The size of `size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 4 + +/* The size of `time_t', as computed by sizeof. */ +#define SIZEOF_TIME_T 4 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define if you want to enable c-ares support */ +/* #undef USE_ARES */ + +/* Define to disable non-blocking sockets */ +/* #undef USE_BLOCKING_SOCKETS */ + +/* if GnuTLS is enabled */ +/* #undef USE_GNUTLS */ + +/* if libSSH2 is in use */ +/*#define USE_LIBSSH2 1*/ + +/* If you want to build curl with the built-in manual */ +/*#define USE_MANUAL 1*/ + +/* if NSS is enabled */ +/* #undef USE_NSS */ + +/* to enable SSPI support */ +/* #undef USE_WINDOWS_SSPI */ + +/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */ +/* #undef USE_YASSLEMUL */ + +/* Version number of package */ +/*#define VERSION "7.18.2-CVS"*/ + +/* Define to avoid automatic inclusion of winsock.h */ +/* #undef WIN32_LEAN_AND_MEAN */ + +/* Define to 1 if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* # undef _ALL_SOURCE */ +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#define _FILE_OFFSET_BITS 64 + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* type to use in place of in_addr_t if not defined */ +/* #undef in_addr_t */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* the signed version of size_t */ +/* #undef ssize_t */ + +/* Enabling curl debug mode when building in Symbian debug mode would work */ +/* except that debug mode introduces new exports that must be frozen. */ +#ifdef _DEBUG +/* #define CURLDEBUG */ +#endif + +/* sys/cdefs.h fails to define this for WINSCW prior to Symbian OS ver. 9.4 */ +#ifndef __LONG_LONG_SUPPORTED +#define __LONG_LONG_SUPPORTED +#endif + +/* Enable appropriate header only when zlib support is enabled */ +#ifdef HAVE_LIBZ +#define HAVE_ZLIB_H 1 +#endif + +#endif /* HEADER_CURL_CONFIG_SYMBIAN_H */ diff --git a/libcurl/lib/config-tpf.h b/libcurl/lib/config-tpf.h new file mode 100644 index 0000000..778d983 --- /dev/null +++ b/libcurl/lib/config-tpf.h @@ -0,0 +1,772 @@ +#ifndef HEADER_CURL_CONFIG_TPF_H +#define HEADER_CURL_CONFIG_TPF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* Hand crafted config file for TPF */ +/* ================================================================ */ + +/* ---------------------------------------------------------------- */ +/* FEATURES, FUNCTIONS, and DEFINITIONS */ +/* ---------------------------------------------------------------- */ + +/* NOTE: Refer also to the .mak file for some of the flags below */ + +/* to disable cookies support */ +/* #undef CURL_DISABLE_COOKIES */ + +/* to disable cryptographic authentication */ +/* #undef CURL_DISABLE_CRYPTO_AUTH */ + +/* to disable DICT */ +/* #undef CURL_DISABLE_DICT */ + +/* to disable FILE */ +/* #undef CURL_DISABLE_FILE */ + +/* to disable FTP */ +/* #undef CURL_DISABLE_FTP */ + +/* to disable HTTP */ +/* #undef CURL_DISABLE_HTTP */ + +/* to disable LDAP */ +/* #undef CURL_DISABLE_LDAP */ + +/* to disable TELNET */ +/* #undef CURL_DISABLE_TELNET */ + +/* to disable TFTP */ +/* #undef CURL_DISABLE_TFTP */ + +/* to disable verbose strings */ +/* #undef CURL_DISABLE_VERBOSE_STRINGS */ + +/* lber dynamic library file */ +/* #undef DL_LBER_FILE */ + +/* ldap dynamic library file */ +/* #undef DL_LDAP_FILE */ + +/* your Entropy Gathering Daemon socket pathname */ +/* #undef EGD_SOCKET */ + +/* Define if you want to enable IPv6 support */ +/* #undef ENABLE_IPV6 */ + +/* Define if struct sockaddr_in6 has the sin6_scope_id member */ +/* #undef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID */ + +/* Define to the type of arg 1 for getnameinfo. */ +/* #undef GETNAMEINFO_TYPE_ARG1 */ + +/* Define to the type of arg 2 for getnameinfo. */ +/* #undef GETNAMEINFO_TYPE_ARG2 */ + +/* Define to the type of args 4 and 6 for getnameinfo. */ +/* #undef GETNAMEINFO_TYPE_ARG46 */ + +/* Define to the type of arg 7 for getnameinfo. */ +/* #undef GETNAMEINFO_TYPE_ARG7 */ + +/* Define to 1 if you have the alarm function. */ +#define HAVE_ALARM 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ARPA_TFTP_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ASSERT_H 1 + +/* Define to 1 if you have the `basename' function. */ +#define HAVE_BASENAME 1 + +/* Define to 1 if you have the `closesocket' function. */ +/* #undef HAVE_CLOSESOCKET */ + +/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ +/* #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA */ +#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CRYPTO_H */ +#define HAVE_CRYPTO_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DES_H */ +#define HAVE_DES_H 1 + +/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ +/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */ +#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ERR_H */ +#define HAVE_ERR_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the fcntl function. */ +#define HAVE_FCNTL 1 + +/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ +#define HAVE_FCNTL_O_NONBLOCK 1 + +/* Define to 1 if you have the `fork' function. */ +/* #undef HAVE_FORK */ +#define HAVE_FORK 1 + +/* Define to 1 if you have the `ftruncate' function. */ +#define HAVE_FTRUNCATE 1 + +/* Define if getaddrinfo exists and works */ +/* #undef HAVE_GETADDRINFO */ + +/* Define to 1 if you have the `geteuid' function. */ +#define HAVE_GETEUID 1 + +/* Define to 1 if you have the `gethostbyaddr' function. */ +#define HAVE_GETHOSTBYADDR 1 + +/* If you have gethostbyname */ +#define HAVE_GETHOSTBYNAME 1 + +/* Define to 1 if you have the `gethostbyname_r' function. */ +/* #undef HAVE_GETHOSTBYNAME_R */ + +/* gethostbyname_r() takes 3 args */ +/* #undef HAVE_GETHOSTBYNAME_R_3 */ + +/* gethostbyname_r() takes 5 args */ +/* #undef HAVE_GETHOSTBYNAME_R_5 */ + +/* gethostbyname_r() takes 6 args */ +/* #undef HAVE_GETHOSTBYNAME_R_6 1 */ + +/* Define to 1 if you have the getnameinfo function. */ +/* #undef HAVE_GETNAMEINFO */ + +/* Define to 1 if you have the `getpass_r' function. */ +/* #undef HAVE_GETPASS_R */ + +/* Define to 1 if you have the `getprotobyname' function. */ +/* #undef HAVE_GETPROTOBYNAME */ + +/* Define to 1 if you have the `getpwuid' function. */ +#define HAVE_GETPWUID 1 + +/* Define to 1 if you have the `getrlimit' function. */ +/* #undef HAVE_GETRLIMIT */ + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* we have a glibc-style strerror_r() */ +/* #undef HAVE_GLIBC_STRERROR_R */ +#define HAVE_GLIBC_STRERROR_R 1 + +/* Define to 1 if you have the `gmtime_r' function. */ +#define HAVE_GMTIME_R 1 + +/* if you have the gssapi libraries */ +/* #undef HAVE_GSSAPI */ + +/* if you have the GNU gssapi libraries */ +/* #undef HAVE_GSSGNU */ + +/* if you have the Heimdal gssapi libraries */ +/* #undef HAVE_GSSHEIMDAL */ + +/* if you have the MIT gssapi libraries */ +/* #undef HAVE_GSSMIT */ + +/* Define to 1 if you have the `iconv' functions. */ +#define HAVE_ICONV 1 + +/* Define to 1 if you have the `idna_strerror' function. */ +/* #undef HAVE_IDNA_STRERROR */ + +/* Define to 1 if you have the `idn_free' function. */ +/* #undef HAVE_IDN_FREE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IDN_FREE_H */ + +/* Define to 1 if you have the `inet_addr' function. */ +#define HAVE_INET_ADDR 1 + +/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ +/* #undef HAVE_INET_NTOP */ + +/* Define to 1 if you have a IPv6 capable working inet_pton function. */ +/* #undef HAVE_INET_PTON */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the ioctl function. */ +#define HAVE_IOCTL 1 + +/* Define to 1 if you have a working ioctl FIONBIO function. */ +#define HAVE_IOCTL_FIONBIO 1 + +/* Define to 1 if you have the ioctlsocket function. */ +/* #undef HAVE_IOCTLSOCKET */ + +/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ +/* #undef HAVE_IOCTLSOCKET_FIONBIO */ + +/* Define to 1 if you have the IoctlSocket camel case function. */ +/* #undef HAVE_IOCTLSOCKET_CAMEL */ + +/* Define to 1 if you have a working IoctlSocket camel case FIONBIO + function. */ +/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IO_H */ + +/* if you have the Kerberos4 libraries (including -ldes) */ +/* #undef HAVE_KRB4 */ + +/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ +/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_KRB_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBGEN_H 1 */ + +/* Define to 1 if you have the `idn' library (-lidn). */ +/* #undef HAVE_LIBIDN */ + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +/* #undef HAVE_LIBRESOLV */ + +/* Define to 1 if you have the `resolve' library (-lresolve). */ +/* #undef HAVE_LIBRESOLVE */ + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the `ssl' library (-lssl). */ +/* #undef HAVE_LIBSSL */ +#define HAVE_LIBSSL 1 + +/* if zlib is available */ +/* #undef HAVE_LIBZ */ + +/* if your compiler supports LL */ +#define HAVE_LL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define to 1 if you have the `localtime_r' function. */ +#define HAVE_LOCALTIME_R 1 + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#define HAVE_LONGLONG 1 + +/* Define to 1 if you need the malloc.h header file even with stdlib.h */ +/* #undef NEED_MALLOC_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +/* undef HAVE_NETINET_TCP_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define if NI_WITHSCOPEID exists and works */ +/* #undef HAVE_NI_WITHSCOPEID */ + +/* we have no strerror_r() proto */ +/* #undef HAVE_NO_STRERROR_R_DECL */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_CRYPTO_H */ +#define HAVE_OPENSSL_CRYPTO_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_ENGINE_H */ +#define HAVE_OPENSSL_ENGINE_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_ERR_H */ +#define HAVE_OPENSSL_ERR_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_PEM_H */ +#define HAVE_OPENSSL_PEM_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_PKCS12_H */ +#define HAVE_OPENSSL_PKCS12_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_RSA_H */ +#define HAVE_OPENSSL_RSA_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_SSL_H */ +#define HAVE_OPENSSL_SSL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENSSL_X509_H */ +#define HAVE_OPENSSL_X509_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PEM_H */ +#define HAVE_PEM_H 1 + +/* Define to 1 if you have the `perror' function. */ +#define HAVE_PERROR 1 + +/* Define to 1 if you have the `pipe' function. */ +#define HAVE_PIPE 1 + +/* Define to 1 if you have the `poll' function. */ +/* #undef HAVE_POLL */ + +/* If you have a fine poll */ +/* #undef HAVE_POLL_FINE */ + +/* we have a POSIX-style strerror_r() */ +/* #undef HAVE_POSIX_STRERROR_R */ + +/* Define to 1 if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define to 1 if you have the `RAND_egd' function. */ +/* #undef HAVE_RAND_EGD */ +#define HAVE_RAND_EGD 1 + +/* Define to 1 if you have the `RAND_screen' function. */ +/* #undef HAVE_RAND_SCREEN */ + +/* Define to 1 if you have the `RAND_status' function. */ +/* #undef HAVE_RAND_STATUS */ +#define HAVE_RAND_STATUS 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_RSA_H */ +#define HAVE_RSA_H 1 + +/* Define to 1 if you have the `select' function. */ +#define HAVE_SELECT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SETJMP_H 1 + +/* Define to 1 if you have the `setlocale' function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if you have the `setrlimit' function. */ +#define HAVE_SETRLIMIT 1 + +/* Define to 1 if you have the setsockopt function. */ +/* #undef HAVE_SETSOCKOPT */ + +/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ +/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SGTTY_H 1 */ + +/* Define to 1 if you have the `sigaction' function. */ +#define HAVE_SIGACTION 1 + +/* Define to 1 if you have the `siginterrupt' function. */ +/* #undef HAVE_SIGINTERRUPT */ + +/* Define to 1 if you have the `signal' function. */ +#define HAVE_SIGNAL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define to 1 if sig_atomic_t is an available typedef. */ +#define HAVE_SIG_ATOMIC_T 1 + +/* Define to 1 if sig_atomic_t is already defined as volatile. */ +/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ + +/* If you have sigsetjmp */ +/* #undef HAVE_SIGSETJMP */ + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SSL_H */ +#define HAVE_SSL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strcasecmp' function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the `strcmpi' function. */ +/* #undef HAVE_STRCMPI */ + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror_r' function. */ +#define HAVE_STRERROR_R 1 + +/* Define to 1 if you have the `stricmp' function. */ +/* #undef HAVE_STRICMP */ +#define HAVE_STRICMP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcpy' function. */ +/* #undef HAVE_STRLCPY */ + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if you have the `strtok_r' function. */ +#define HAVE_STRTOK_R 1 + +/* Define to 1 if you have the `strtoll' function. */ +#define HAVE_STRTOLL 1 + +/* if struct sockaddr_storage is defined */ +/* #undef HAVE_STRUCT_SOCKADDR_STORAGE */ + +/* Define this if you have struct timeval */ +#define HAVE_STRUCT_TIMEVAL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FILIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_POLL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SOCKIO_H */ +#define HAVE_SYS_SOCKIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_UTIME_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TERMIOS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TERMIO_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TLD_H */ + +/* Define to 1 if you have the `tld_strerror' function. */ +/* #undef HAVE_TLD_STRERROR */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `utime' function. */ +#define HAVE_UTIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTIME_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINSOCK2_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINSOCK_H */ + +/* Define this symbol if your OS supports changing the contents of argv */ +/* #undef HAVE_WRITABLE_ARGV */ + +/* Define to 1 if you have the ws2tcpip.h header file. */ +/* #undef HAVE_WS2TCPIP_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_X509_H */ + +/* if you have the zlib.h header file */ +/* #undef HAVE_ZLIB_H */ + +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ +/* #undef NEED_REENTRANT */ + +/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ +/* #undef NEED_THREAD_SAFE */ + +/* cpu-machine-OS */ +#define OS "s390x-ibm-tpf" + +/* Name of package */ +#define PACKAGE "curl" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT \ + "a suitable curl mailing list => https://curl.haxx.se/mail/" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "curl" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "curl -" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "curl" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "-" + +/* a suitable file to read random data from */ +/* #undef RANDOM_FILE */ + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define to the type of arg 1 for `select'. */ +#define SELECT_TYPE_ARG1 int + +/* Define to the type of args 2, 3 and 4 for `select'. */ +#define SELECT_TYPE_ARG234 (fd_set *) + +/* Define to the type of arg 5 for `select'. */ +#define SELECT_TYPE_ARG5 (struct timeval *) + +/* The size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of `off_t', as computed by sizeof. */ +#define SIZEOF_OFF_T 8 + +/* The size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* Define to the size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 8 + +/* The size of `size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 8 + +/* The size of `time_t', as computed by sizeof. */ +#define SIZEOF_TIME_T 8 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define if you want to enable ares support */ +/* #undef USE_ARES */ + +/* Define to disable non-blocking sockets */ +/* #undef USE_BLOCKING_SOCKETS */ + +/* if GnuTLS is enabled */ +/* #undef USE_GNUTLS */ + +/* If you want to build curl with the built-in manual */ +/* #undef USE_MANUAL */ + +/* if OpenSSL is in use */ +/* #undef USE_OPENSSL */ + +/* if SSL is enabled */ +/* #undef USE_OPENSSL */ + +/* to enable SSPI support */ +/* #undef USE_WINDOWS_SSPI */ + +/* Version number of package */ +#define VERSION "not-used" + +/* Define to avoid automatic inclusion of winsock.h */ +/* #undef WIN32_LEAN_AND_MEAN */ + +/* Define to 1 if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* # undef _ALL_SOURCE */ +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* type to use in place of in_addr_t if not defined */ +/* #undef in_addr_t */ + +/* Define to `unsigned' if does not define. */ +/* #undef size_t */ + +/* the signed version of size_t */ +/* #undef ssize_t */ + +/* Define to 1 if you have the getnameinfo function. */ +/* #undef HAVE_GETNAMEINFO 1 */ + +/* Define to the type qualifier of arg 1 for getnameinfo. */ +/* #undef GETNAMEINFO_QUAL_ARG1 const */ + +/* Define to the type of arg 1 for getnameinfo. */ +/* #undef GETNAMEINFO_TYPE_ARG1 struct sockaddr * */ + +/* Define to the type of arg 2 for getnameinfo. */ +/* #undef GETNAMEINFO_TYPE_ARG2 socklen_t */ + +/* Define to the type of args 4 and 6 for getnameinfo. */ +/* #undef GETNAMEINFO_TYPE_ARG46 size_t */ + +/* Define to the type of arg 7 for getnameinfo. */ +/* #undef GETNAMEINFO_TYPE_ARG7 int */ + +/* Define to 1 if you have the recv function. */ +#define HAVE_RECV 1 + +/* Define to the type of arg 1 for recv. */ +#define RECV_TYPE_ARG1 int + +/* Define to the type of arg 2 for recv. */ +#define RECV_TYPE_ARG2 char * + +/* Define to the type of arg 3 for recv. */ +#define RECV_TYPE_ARG3 int + +/* Define to the type of arg 4 for recv. */ +#define RECV_TYPE_ARG4 int + +/* Define to the function return type for recv. */ +#define RECV_TYPE_RETV int + +/* Define to 1 if you have the recvfrom function. */ +#define HAVE_RECVFROM 1 + +/* Define to the type of arg 1 for recvfrom. */ +#define RECVFROM_TYPE_ARG1 int + +/* Define to the type pointed by arg 2 for recvfrom. */ +#define RECVFROM_TYPE_ARG2 char + +/* Define to the type of arg 3 for recvfrom. */ +#define RECVFROM_TYPE_ARG3 int + +/* Define to the type of arg 4 for recvfrom. */ +#define RECVFROM_TYPE_ARG4 int + +/* Define to the type pointed by arg 5 for recvfrom. */ +#define RECVFROM_TYPE_ARG5 struct sockaddr + +/* Define to the type pointed by arg 6 for recvfrom. */ +#define RECVFROM_TYPE_ARG6 int + +/* Define to the function return type for recvfrom. */ +#define RECVFROM_TYPE_RETV int + +/* Define to 1 if you have the send function. */ +#define HAVE_SEND 1 + +/* Define to the type of arg 1 for send. */ +#define SEND_TYPE_ARG1 int + +/* Define to the type qualifier of arg 2 for send. */ +#define SEND_QUAL_ARG2 const + +/* Define to the type of arg 2 for send. */ +#define SEND_TYPE_ARG2 char * + +/* Define to the type of arg 3 for send. */ +#define SEND_TYPE_ARG3 int + +/* Define to the type of arg 4 for send. */ +#define SEND_TYPE_ARG4 int + +/* Define to the function return type for send. */ +#define SEND_TYPE_RETV int + +#define CURL_DOES_CONVERSIONS +#ifndef CURL_ICONV_CODESET_OF_HOST +#define CURL_ICONV_CODESET_OF_HOST "IBM-1047" +#endif + + +#endif /* HEADER_CURL_CONFIG_TPF_H */ diff --git a/libcurl/lib/config-vxworks.h b/libcurl/lib/config-vxworks.h new file mode 100644 index 0000000..89af352 --- /dev/null +++ b/libcurl/lib/config-vxworks.h @@ -0,0 +1,916 @@ +#ifndef HEADER_CURL_CONFIG_VXWORKS_H +#define HEADER_CURL_CONFIG_VXWORKS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* =============================================================== */ +/* Hand crafted config file for VxWorks */ +/* =============================================================== */ + +/* Location of default ca bundle */ +/* #undef CURL_CA_BUNDLE */ + +/* Location of default ca path */ +/* #undef CURL_CA_PATH */ + +/* to disable cookies support */ +/* #undef CURL_DISABLE_COOKIES */ + +/* to disable cryptographic authentication */ +/* #undef CURL_DISABLE_CRYPTO_AUTH */ + +/* to disable DICT */ +/* #undef CURL_DISABLE_DICT */ + +/* to disable FILE */ +/* #undef CURL_DISABLE_FILE */ + +/* to disable FTP */ +#define CURL_DISABLE_FTP 1 + +/* to disable HTTP */ +/* #undef CURL_DISABLE_HTTP */ + +/* to disable LDAP */ +#define CURL_DISABLE_LDAP 1 + +/* to disable LDAPS */ +#define CURL_DISABLE_LDAPS 1 + +/* to disable NTLM authentication */ +#define CURL_DISABLE_NTLM 1 + +/* to disable proxies */ +/* #undef CURL_DISABLE_PROXY */ + +/* to disable TELNET */ +#define CURL_DISABLE_TELNET 1 + +/* to disable TFTP */ +#define CURL_DISABLE_TFTP 1 + +/* to disable verbose strings */ +/* #undef CURL_DISABLE_VERBOSE_STRINGS */ + +/* Definition to make a library symbol externally visible. */ +/* #undef CURL_EXTERN_SYMBOL */ + +/* Use Windows LDAP implementation */ +/* #undef USE_WIN32_LDAP */ + +/* your Entropy Gathering Daemon socket pathname */ +/* #undef EGD_SOCKET */ + +/* Define if you want to enable IPv6 support */ +#define ENABLE_IPV6 1 + +/* Define to the type qualifier of arg 1 for getnameinfo. */ +#define GETNAMEINFO_QUAL_ARG1 const + +/* Define to the type of arg 1 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * + +/* Define to the type of arg 2 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG2 socklen_t + +/* Define to the type of args 4 and 6 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG46 size_t + +/* Define to the type of arg 7 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG7 unsigned int + +/* Specifies the number of arguments to getservbyport_r */ +#define GETSERVBYPORT_R_ARGS 6 + +/* Specifies the size of the buffer to pass to getservbyport_r */ +#define GETSERVBYPORT_R_BUFSIZE 4096 + +/* Define to 1 if you have the alarm function. */ +#define HAVE_ALARM 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ARPA_TFTP_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ASSERT_H 1 + +/* Define to 1 if you have the `basename' function. */ +/* #undef HAVE_BASENAME */ + +/* Define to 1 if bool is an available type. */ +#define HAVE_BOOL_T 1 + +/* Define to 1 if you have the clock_gettime function and monotonic timer. */ +/* #undef HAVE_CLOCK_GETTIME_MONOTONIC */ + +/* Define to 1 if you have the `closesocket' function. */ +/* #undef HAVE_CLOSESOCKET */ + +/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ +#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CRYPTO_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DES_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ +#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_ERR_H */ + +/* Define to 1 if you have the fcntl function. */ +#define HAVE_FCNTL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ +#define HAVE_FCNTL_O_NONBLOCK 1 + +/* Define to 1 if you have the `fork' function. */ +#define HAVE_FORK 1 + +/* Define to 1 if you have the freeaddrinfo function. */ +#define HAVE_FREEADDRINFO 1 + +/* Define to 1 if you have the freeifaddrs function. */ +#define HAVE_FREEIFADDRS 1 + +/* Define to 1 if you have the ftruncate function. */ +#define HAVE_FTRUNCATE 1 + +/* Define to 1 if you have a working getaddrinfo function. */ +#define HAVE_GETADDRINFO 1 + +/* Define to 1 if you have the `geteuid' function. */ +/* #undef HAVE_GETEUID */ + +/* Define to 1 if you have the gethostbyaddr function. */ +#define HAVE_GETHOSTBYADDR 1 + +/* Define to 1 if you have the gethostbyaddr_r function. */ +#define HAVE_GETHOSTBYADDR_R 1 + +/* gethostbyaddr_r() takes 5 args */ +/* #undef HAVE_GETHOSTBYADDR_R_5 */ + +/* gethostbyaddr_r() takes 7 args */ +/* #undef HAVE_GETHOSTBYADDR_R_7 */ + +/* gethostbyaddr_r() takes 8 args */ +#define HAVE_GETHOSTBYADDR_R_8 1 + +/* Define to 1 if you have the gethostbyname function. */ +#define HAVE_GETHOSTBYNAME 1 + +/* Define to 1 if you have the gethostbyname_r function. */ +/* #undef HAVE_GETHOSTBYNAME_R */ + +/* gethostbyname_r() takes 3 args */ +/* #undef HAVE_GETHOSTBYNAME_R_3 */ + +/* gethostbyname_r() takes 5 args */ +/* #undef HAVE_GETHOSTBYNAME_R_5 */ + +/* gethostbyname_r() takes 6 args */ +/* #undef HAVE_GETHOSTBYNAME_R_6 */ + +/* Define to 1 if you have the gethostname function. */ +#define HAVE_GETHOSTNAME 1 + +/* Define to 1 if you have a working getifaddrs function. */ +/* #undef HAVE_GETIFADDRS */ + +/* Define to 1 if you have the getnameinfo function. */ +#define HAVE_GETNAMEINFO 1 + +/* Define to 1 if you have the `getpass_r' function. */ +/* #undef HAVE_GETPASS_R */ + +/* Define to 1 if you have the `getppid' function. */ +#define HAVE_GETPPID 1 + +/* Define to 1 if you have the `getprotobyname' function. */ +#define HAVE_GETPROTOBYNAME 1 + +/* Define to 1 if you have the `getpwuid' function. */ +/* #undef HAVE_GETPWUID */ + +/* Define to 1 if you have the `getrlimit' function. */ +#define HAVE_GETRLIMIT 1 + +/* Define to 1 if you have the getservbyport_r function. */ +/* #undef HAVE_GETSERVBYPORT_R */ + +/* Define to 1 if you have the `gettimeofday' function. */ +/* #undef HAVE_GETTIMEOFDAY */ + +/* Define to 1 if you have a working glibc-style strerror_r function. */ +/* #undef HAVE_GLIBC_STRERROR_R */ + +/* Define to 1 if you have a working gmtime_r function. */ +#define HAVE_GMTIME_R 1 + +/* if you have the gssapi libraries */ +/* #undef HAVE_GSSAPI */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */ + +/* if you have the GNU gssapi libraries */ +/* #undef HAVE_GSSGNU */ + +/* if you have the Heimdal gssapi libraries */ +/* #undef HAVE_GSSHEIMDAL */ + +/* if you have the MIT gssapi libraries */ +/* #undef HAVE_GSSMIT */ + +/* Define to 1 if you have the `idna_strerror' function. */ +/* #undef HAVE_IDNA_STRERROR */ + +/* Define to 1 if you have the `idn_free' function. */ +/* #undef HAVE_IDN_FREE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IDN_FREE_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IFADDRS_H */ + +/* Define to 1 if you have the `inet_addr' function. */ +#define HAVE_INET_ADDR 1 + +/* Define to 1 if you have the inet_ntoa_r function. */ +/* #undef HAVE_INET_NTOA_R */ + +/* inet_ntoa_r() takes 2 args */ +/* #undef HAVE_INET_NTOA_R_2 */ + +/* inet_ntoa_r() takes 3 args */ +/* #undef HAVE_INET_NTOA_R_3 */ + +/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ +/* #undef HAVE_INET_NTOP */ + +/* Define to 1 if you have a IPv6 capable working inet_pton function. */ +/* #undef HAVE_INET_PTON */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the ioctl function. */ +#define HAVE_IOCTL 1 + +/* Define to 1 if you have the ioctlsocket function. */ +/* #undef HAVE_IOCTLSOCKET */ + +/* Define to 1 if you have the IoctlSocket camel case function. */ +/* #undef HAVE_IOCTLSOCKET_CAMEL */ + +/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. + */ +/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ + +/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ +/* #undef HAVE_IOCTLSOCKET_FIONBIO */ + +/* Define to 1 if you have a working ioctl FIONBIO function. */ +#define HAVE_IOCTL_FIONBIO 1 + +/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ +#define HAVE_IOCTL_SIOCGIFADDR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_IO_H 1 + +/* if you have the Kerberos4 libraries (including -ldes) */ +/* #undef HAVE_KRB4 */ + +/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ +/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_KRB_H */ + +/* Define to 1 if you have the lber.h header file. */ +/* #undef HAVE_LBER_H */ + +/* Define to 1 if you have the ldapssl.h header file. */ +/* #undef HAVE_LDAPSSL_H */ + +/* Define to 1 if you have the ldap.h header file. */ +/* #undef HAVE_LDAP_H */ + +/* Use LDAPS implementation */ +/* #undef HAVE_LDAP_SSL */ + +/* Define to 1 if you have the ldap_ssl.h header file. */ +/* #undef HAVE_LDAP_SSL_H */ + +/* Define to 1 if you have the `ldap_url_parse' function. */ +/* #undef HAVE_LDAP_URL_PARSE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBGEN_H */ + +/* Define to 1 if you have the `idn' library (-lidn). */ +/* #undef HAVE_LIBIDN */ + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +/* #undef HAVE_LIBRESOLV */ + +/* Define to 1 if you have the `resolve' library (-lresolve). */ +/* #undef HAVE_LIBRESOLVE */ + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the `ssh2' library (-lssh2). */ +/* #undef HAVE_LIBSSH2 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBSSH2_H */ + +/* Define to 1 if you have the `libssh2_version' function. */ +/* #undef HAVE_LIBSSH2_VERSION */ + +/* Define to 1 if you have the `ssl' library (-lssl). */ +#define HAVE_LIBSSL 1 + +/* if zlib is available */ +#define HAVE_LIBZ 1 + +/* if your compiler supports LL */ +#define HAVE_LL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define to 1 if you have a working localtime_r function. */ +#define HAVE_LOCALTIME_R 1 + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#define HAVE_LONGLONG 1 + +/* Define to 1 if you have the malloc.h header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the memory.h header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the MSG_NOSIGNAL flag. */ +/* #undef HAVE_MSG_NOSIGNAL */ + +/* Define to 1 if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define to 1 if NI_WITHSCOPEID exists and works. */ +/* #undef HAVE_NI_WITHSCOPEID */ + +/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE + */ +/* #undef HAVE_OLD_GSSMIT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_CRYPTO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_ENGINE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_ERR_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_PEM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_PKCS12_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_RSA_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_SSL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_X509_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PEM_H */ + +/* Define to 1 if you have the `perror' function. */ +#define HAVE_PERROR 1 + +/* Define to 1 if you have the `pipe' function. */ +#define HAVE_PIPE 1 + +/* Define to 1 if you have a working poll function. */ +/* #undef HAVE_POLL */ + +/* If you have a fine poll */ +/* #undef HAVE_POLL_FINE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_POLL_H */ + +/* Define to 1 if you have a working POSIX-style strerror_r function. */ +/* #undef HAVE_POSIX_STRERROR_R */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PWD_H */ + +/* Define to 1 if you have the `RAND_egd' function. */ +#define HAVE_RAND_EGD 1 + +/* Define to 1 if you have the `RAND_screen' function. */ +/* #undef HAVE_RAND_SCREEN */ + +/* Define to 1 if you have the `RAND_status' function. */ +#define HAVE_RAND_STATUS 1 + +/* Define to 1 if you have the recv function. */ +#define HAVE_RECV 1 + +/* Define to 1 if you have the recvfrom function. */ +#define HAVE_RECVFROM 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_RSA_H */ + +/* Define to 1 if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define to 1 if you have the send function. */ +#define HAVE_SEND 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SETJMP_H 1 + +/* Define to 1 if you have the `setlocale' function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if you have the `setmode' function. */ +#define HAVE_SETMODE 1 + +/* Define to 1 if you have the `setrlimit' function. */ +#define HAVE_SETRLIMIT 1 + +/* Define to 1 if you have the setsockopt function. */ +#define HAVE_SETSOCKOPT 1 + +/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ +/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SGTTY_H */ + +/* Define to 1 if you have the sigaction function. */ +#define HAVE_SIGACTION 1 + +/* Define to 1 if you have the siginterrupt function. */ +#define HAVE_SIGINTERRUPT 1 + +/* Define to 1 if you have the signal function. */ +#define HAVE_SIGNAL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define to 1 if you have the sigsetjmp function or macro. */ +/* #undef HAVE_SIGSETJMP */ + +/* Define to 1 if sig_atomic_t is an available typedef. */ +#define HAVE_SIG_ATOMIC_T 1 + +/* Define to 1 if sig_atomic_t is already defined as volatile. */ +/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ + +/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */ +#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SSL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDINT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the strcmpi function. */ +/* #undef HAVE_STRCMPI */ + +/* Define to 1 if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the strerror_r function. */ +#define HAVE_STRERROR_R 1 + +/* Define to 1 if you have the stricmp function. */ +/* #undef HAVE_STRICMP */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcpy' function. */ +/* #undef HAVE_STRLCPY */ + +/* Define to 1 if you have the strncasecmp function. */ +#define HAVE_STRNCASECMP 1 + +/* Define to 1 if you have the strncmpi function. */ +/* #undef HAVE_STRNCMPI */ + +/* Define to 1 if you have the strnicmp function. */ +/* #undef HAVE_STRNICMP */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STROPTS_H */ + +/* Define to 1 if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if you have the strtok_r function. */ +#define HAVE_STRTOK_R 1 + +/* Define to 1 if you have the strtoll function. */ +/* #undef HAVE_STRTOLL */ + +/* if struct sockaddr_storage is defined */ +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 + +/* Define to 1 if you have the timeval struct. */ +#define HAVE_STRUCT_TIMEVAL 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_FILIO_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PARAM_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_POLL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SELECT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SOCKIO_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TIME_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UTIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TLD_H */ + +/* Define to 1 if you have the `tld_strerror' function. */ +/* #undef HAVE_TLD_STRERROR */ + +/* Define to 1 if you have the `uname' function. */ +#define HAVE_UNAME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `utime' function. */ +#define HAVE_UTIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTIME_H 1 + +/* Define to 1 if compiler supports C99 variadic macro style. */ +#define HAVE_VARIADIC_MACROS_C99 1 + +/* Define to 1 if compiler supports old gcc variadic macro style. */ +#define HAVE_VARIADIC_MACROS_GCC 1 + +/* Define to 1 if you have a working vxworks-style strerror_r function. */ +#define HAVE_VXWORKS_STRERROR_R 1 + +/* Define to 1 if you have the winber.h header file. */ +/* #undef HAVE_WINBER_H */ + +/* Define to 1 if you have the windows.h header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if you have the winldap.h header file. */ +/* #undef HAVE_WINLDAP_H */ + +/* Define to 1 if you have the winsock2.h header file. */ +/* #undef HAVE_WINSOCK2_H */ + +/* Define to 1 if you have the winsock.h header file. */ +/* #undef HAVE_WINSOCK_H */ + +/* Define this symbol if your OS supports changing the contents of argv */ +#define HAVE_WRITABLE_ARGV 1 + +/* Define to 1 if you have the writev function. */ +#define HAVE_WRITEV 1 + +/* Define to 1 if you have the ws2tcpip.h header file. */ +/* #undef HAVE_WS2TCPIP_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_X509_H */ + +/* if you have the zlib.h header file */ +#define HAVE_ZLIB_H 1 + +/* Define to 1 if you need the lber.h header file even with ldap.h */ +/* #undef NEED_LBER_H */ + +/* Define to 1 if you need the malloc.h header file even with stdlib.h */ +/* #undef NEED_MALLOC_H */ + +/* Define to 1 if you need the memory.h header file even with stdlib.h */ +/* #undef NEED_MEMORY_H */ + +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ +/* #undef NEED_REENTRANT */ + +/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ +/* #undef NEED_THREAD_SAFE */ + +/* Define to 1 if the open function requires three arguments. */ +#define OPEN_NEEDS_ARG3 1 + +/* cpu-machine-OS */ +#define OS "unknown-unknown-vxworks" + +/* Name of package */ +#define PACKAGE "curl" + +/* a suitable file to read random data from */ +#define RANDOM_FILE "/dev/urandom" + +/* Define to the type of arg 1 for recvfrom. */ +#define RECVFROM_TYPE_ARG1 int + +/* Define to the type pointed by arg 2 for recvfrom. */ +#define RECVFROM_TYPE_ARG2 void + +/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ +#define RECVFROM_TYPE_ARG2_IS_VOID 1 + +/* Define to the type of arg 3 for recvfrom. */ +#define RECVFROM_TYPE_ARG3 size_t + +/* Define to the type of arg 4 for recvfrom. */ +#define RECVFROM_TYPE_ARG4 int + +/* Define to the type pointed by arg 5 for recvfrom. */ +#define RECVFROM_TYPE_ARG5 struct sockaddr + +/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ +/* #undef RECVFROM_TYPE_ARG5_IS_VOID */ + +/* Define to the type pointed by arg 6 for recvfrom. */ +#define RECVFROM_TYPE_ARG6 socklen_t + +/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ +/* #undef RECVFROM_TYPE_ARG6_IS_VOID */ + +/* Define to the function return type for recvfrom. */ +#define RECVFROM_TYPE_RETV int + +/* Define to the type of arg 1 for recv. */ +#define RECV_TYPE_ARG1 int + +/* Define to the type of arg 2 for recv. */ +#define RECV_TYPE_ARG2 void * + +/* Define to the type of arg 3 for recv. */ +#define RECV_TYPE_ARG3 size_t + +/* Define to the type of arg 4 for recv. */ +#define RECV_TYPE_ARG4 int + +/* Define to the function return type for recv. */ +#define RECV_TYPE_RETV int + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define to the type qualifier of arg 5 for select. */ +#define SELECT_QUAL_ARG5 + +/* Define to the type of arg 1 for select. */ +#define SELECT_TYPE_ARG1 int + +/* Define to the type of args 2, 3 and 4 for select. */ +#define SELECT_TYPE_ARG234 fd_set * + +/* Define to the type of arg 5 for select. */ +#define SELECT_TYPE_ARG5 struct timeval * + +/* Define to the function return type for select. */ +#define SELECT_TYPE_RETV int + +/* Define to the type qualifier of arg 2 for send. */ +#define SEND_QUAL_ARG2 const + +/* Define to the type of arg 1 for send. */ +#define SEND_TYPE_ARG1 int + +/* Define to the type of arg 2 for send. */ +#define SEND_TYPE_ARG2 void * + +/* Define to the type of arg 3 for send. */ +#define SEND_TYPE_ARG3 size_t + +/* Define to the type of arg 4 for send. */ +#define SEND_TYPE_ARG4 int + +/* Define to the function return type for send. */ +#define SEND_TYPE_RETV int + +/* The size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 4 + +/* The size of `off_t', as computed by sizeof. */ +#define SIZEOF_OFF_T 8 + +/* The size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* The size of `size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 4 + +/* The size of `time_t', as computed by sizeof. */ +#define SIZEOF_TIME_T 4 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to the type of arg 3 for strerror_r. */ +/* #undef STRERROR_R_TYPE_ARG3 */ + +/* Define to 1 if you can safely include both and . */ +/* #undef TIME_WITH_SYS_TIME */ + +/* Define if you want to enable c-ares support */ +/* #undef USE_ARES */ + +/* Define to disable non-blocking sockets. */ +/* #undef USE_BLOCKING_SOCKETS */ + +/* if GnuTLS is enabled */ +/* #undef USE_GNUTLS */ + +/* if libSSH2 is in use */ +/* #undef USE_LIBSSH2 */ + +/* If you want to build curl with the built-in manual */ +#define USE_MANUAL 1 + +/* if NSS is enabled */ +/* #undef USE_NSS */ + +/* if OpenSSL is in use */ +#define USE_OPENSSL 1 + +/* Define to 1 if you are building a Windows target without large file + support. */ +/* #undef USE_WIN32_LARGE_FILES */ + +/* to enable SSPI support */ +/* #undef USE_WINDOWS_SSPI */ + +/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */ +/* #undef USE_YASSLEMUL */ + +/* Define to avoid automatic inclusion of winsock.h */ +/* #undef WIN32_LEAN_AND_MEAN */ + +/* Define to 1 if OS is AIX. */ +#ifndef _ALL_SOURCE +/* # undef _ALL_SOURCE */ +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Type to use in place of in_addr_t when system does not provide it. */ +/* #undef in_addr_t */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* the signed version of size_t */ +/* #undef ssize_t */ + +#endif /* HEADER_CURL_CONFIG_VXWORKS_H */ diff --git a/libcurl/lib/config-win32.h b/libcurl/lib/config-win32.h new file mode 100644 index 0000000..4209167 --- /dev/null +++ b/libcurl/lib/config-win32.h @@ -0,0 +1,783 @@ +#ifndef HEADER_CURL_CONFIG_WIN32_H +#define HEADER_CURL_CONFIG_WIN32_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#define CURL_DISABLE_LDAP 1 +#define CURL_DISABLE_TELNET 1 +#define CURL_DISABLE_KERBEROS_AUTH 1 +#define CURL_DISABLE_AWS 1 +#define CURL_DISABLE_CA_SEARCH 1 +#define CURL_DISABLE_DICT 1 +#define CURL_DISABLE_DOH 1 +#define CURL_DISABLE_GOPHER 1 +#define CURL_DISABLE_HSTS 1 +#define CURL_DISABLE_IMAP 1 +#define CURL_DISABLE_LDAPS 1 +#define CURL_DISABLE_RTSP 1 +#define CURL_DISABLE_DIGEST_AUTH 1 +#define CURL_DISABLE_BASIC_AUTH 1 +#define CURL_DISABLE_BEARER_AUTH 1 +#define CURL_DISABLE_CRYPTO_AUTH 1 +#define CURL_DISABLE_VERBOSE_STRINGS 1 +#define CURL_DISABLE_POP3 1 +#define CURL_DISABLE_NTLM 1 +#define CURL_DISABLE_MQTT 1 +#define CURL_DISABLE_TFTP 1 +#define CURL_DISABLE_SMB 1 +#define HTTP_ONLY 1 + +/* ================================================================ */ +/* Hand crafted config file for Windows */ +/* ================================================================ */ + +/* ---------------------------------------------------------------- */ +/* HEADER FILES */ +/* ---------------------------------------------------------------- */ + +/* Define if you have the header file. */ +/* #define HAVE_ARPA_INET_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_ASSERT_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_CRYPTO_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_ERR_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#if defined(__MINGW32__) || defined(__POCC__) +#define HAVE_GETOPT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1800) +#define HAVE_INTTYPES_H 1 +#endif + +/* Define if you have the header file. */ +#define HAVE_IO_H 1 + +/* Define if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define if you need header even with header file. */ +#if !defined(__SALFORDC__) && !defined(__POCC__) +#define NEED_MALLOC_H 1 +#endif + +/* Define if you have the header file. */ +/* #define HAVE_NETDB_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_NETINET_IN_H 1 */ + +/* Define if you have the header file. */ +#ifndef __SALFORDC__ +#define HAVE_PROCESS_H 1 +#endif + +/* Define if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_SGTTY_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SSL_H 1 */ + +/* Define to 1 if you have the header file. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1800) +#define HAVE_STDBOOL_H 1 +#endif + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_SYS_PARAM_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_SELECT_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_SOCKET_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_SOCKIO_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_SYS_TIME_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +#ifndef __BORLANDC__ +#define HAVE_SYS_UTIME_H 1 +#endif + +/* Define if you have the header file. */ +/* #define HAVE_TERMIO_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_TERMIOS_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define if you have the header file. */ +#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \ + defined(__POCC__) +#define HAVE_UNISTD_H 1 +#endif + +/* Define if you have the header file. */ +#define HAVE_WINDOWS_H 1 + +/* Define if you have the header file. */ +#define HAVE_WINSOCK_H 1 + +/* Define if you have the header file. */ +#ifndef __SALFORDC__ +#define HAVE_WINSOCK2_H 1 +#endif + +/* Define if you have the header file. */ +#ifndef __SALFORDC__ +#define HAVE_WS2TCPIP_H 1 +#endif + +/* ---------------------------------------------------------------- */ +/* OTHER HEADER INFO */ +/* ---------------------------------------------------------------- */ + +/* Define if sig_atomic_t is an available typedef. */ +#define HAVE_SIG_ATOMIC_T 1 + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +/* #define TIME_WITH_SYS_TIME 1 */ + +/* Define to 1 if bool is an available type. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1800) +#define HAVE_BOOL_T 1 +#endif + +/* ---------------------------------------------------------------- */ +/* FUNCTIONS */ +/* ---------------------------------------------------------------- */ + +/* Define if you have the closesocket function. */ +#define HAVE_CLOSESOCKET 1 + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #define HAVE_DOPRNT 1 */ + +/* Define if you have the ftruncate function. */ +#define HAVE_FTRUNCATE 1 + +/* Define to 1 if you have the `getpeername' function. */ +#define HAVE_GETPEERNAME 1 + +/* Define to 1 if you have the getsockname function. */ +#define HAVE_GETSOCKNAME 1 + +/* Define if you have the gethostbyaddr function. */ +#define HAVE_GETHOSTBYADDR 1 + +/* Define if you have the gethostname function. */ +#define HAVE_GETHOSTNAME 1 + +/* Define if you have the getpass function. */ +/* #define HAVE_GETPASS 1 */ + +/* Define if you have the getservbyname function. */ +#define HAVE_GETSERVBYNAME 1 + +/* Define if you have the getprotobyname function. */ +#define HAVE_GETPROTOBYNAME + +/* Define if you have the gettimeofday function. */ +/* #define HAVE_GETTIMEOFDAY 1 */ + +/* Define if you have the inet_addr function. */ +#define HAVE_INET_ADDR 1 + +/* Define if you have the ioctlsocket function. */ +#define HAVE_IOCTLSOCKET 1 + +/* Define if you have a working ioctlsocket FIONBIO function. */ +#define HAVE_IOCTLSOCKET_FIONBIO 1 + +/* Define if you have the perror function. */ +#define HAVE_PERROR 1 + +/* Define if you have the RAND_screen function when using SSL. */ +#define HAVE_RAND_SCREEN 1 + +/* Define if you have the `RAND_status' function when using SSL. */ +#define HAVE_RAND_STATUS 1 + +/* Define if you have the `CRYPTO_cleanup_all_ex_data' function. + This is present in OpenSSL versions after 0.9.6b */ +#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the setlocale function. */ +#define HAVE_SETLOCALE 1 + +/* Define if you have the setmode function. */ +#define HAVE_SETMODE 1 + +/* Define if you have the setvbuf function. */ +#define HAVE_SETVBUF 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strcasecmp function. */ +/* #define HAVE_STRCASECMP 1 */ + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have the stricmp function. */ +#define HAVE_STRICMP 1 + +/* Define if you have the strncasecmp function. */ +/* #define HAVE_STRNCASECMP 1 */ + +/* Define if you have the strnicmp function. */ +#define HAVE_STRNICMP 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtoll function. */ +#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__POCC__) || \ + (defined(_MSC_VER) && (_MSC_VER >= 1800)) +#define HAVE_STRTOLL 1 +#endif + +/* Define if you have the tcgetattr function. */ +/* #define HAVE_TCGETATTR 1 */ + +/* Define if you have the tcsetattr function. */ +/* #define HAVE_TCSETATTR 1 */ + +/* Define if you have the utime function. */ +#ifndef __BORLANDC__ +#define HAVE_UTIME 1 +#endif + +/* Define to the type qualifier of arg 1 for getnameinfo. */ +#define GETNAMEINFO_QUAL_ARG1 const + +/* Define to the type of arg 1 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * + +/* Define to the type of arg 2 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG2 socklen_t + +/* Define to the type of args 4 and 6 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG46 DWORD + +/* Define to the type of arg 7 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG7 int + +/* Define if you have the recv function. */ +#define HAVE_RECV 1 + +/* Define to the type of arg 1 for recv. */ +#define RECV_TYPE_ARG1 SOCKET + +/* Define to the type of arg 2 for recv. */ +#define RECV_TYPE_ARG2 char * + +/* Define to the type of arg 3 for recv. */ +#define RECV_TYPE_ARG3 int + +/* Define to the type of arg 4 for recv. */ +#define RECV_TYPE_ARG4 int + +/* Define to the function return type for recv. */ +#define RECV_TYPE_RETV int + +/* Define if you have the recvfrom function. */ +#define HAVE_RECVFROM 1 + +/* Define to the type of arg 1 for recvfrom. */ +#define RECVFROM_TYPE_ARG1 SOCKET + +/* Define to the type pointed by arg 2 for recvfrom. */ +#define RECVFROM_TYPE_ARG2 char + +/* Define to the type of arg 3 for recvfrom. */ +#define RECVFROM_TYPE_ARG3 int + +/* Define to the type of arg 4 for recvfrom. */ +#define RECVFROM_TYPE_ARG4 int + +/* Define to the type pointed by arg 5 for recvfrom. */ +#define RECVFROM_TYPE_ARG5 struct sockaddr + +/* Define to the type pointed by arg 6 for recvfrom. */ +#define RECVFROM_TYPE_ARG6 int + +/* Define to the function return type for recvfrom. */ +#define RECVFROM_TYPE_RETV int + +/* Define if you have the send function. */ +#define HAVE_SEND 1 + +/* Define to the type of arg 1 for send. */ +#define SEND_TYPE_ARG1 SOCKET + +/* Define to the type qualifier of arg 2 for send. */ +#define SEND_QUAL_ARG2 const + +/* Define to the type of arg 2 for send. */ +#define SEND_TYPE_ARG2 char * + +/* Define to the type of arg 3 for send. */ +#define SEND_TYPE_ARG3 int + +/* Define to the type of arg 4 for send. */ +#define SEND_TYPE_ARG4 int + +/* Define to the function return type for send. */ +#define SEND_TYPE_RETV int + +/* ---------------------------------------------------------------- */ +/* TYPEDEF REPLACEMENTS */ +/* ---------------------------------------------------------------- */ + +/* Define if in_addr_t is not an available 'typedefed' type. */ +#define in_addr_t unsigned long + +/* Define to the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define if ssize_t is not an available 'typedefed' type. */ +#ifndef _SSIZE_T_DEFINED +# if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \ + defined(__POCC__) || \ + defined(__MINGW32__) +# elif defined(_WIN64) +# define _SSIZE_T_DEFINED +# define ssize_t __int64 +# else +# define _SSIZE_T_DEFINED +# define ssize_t int +# endif +#endif + +/* ---------------------------------------------------------------- */ +/* TYPE SIZES */ +/* ---------------------------------------------------------------- */ + +/* Define to the size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* Define to the size of `long double', as computed by sizeof. */ +#define SIZEOF_LONG_DOUBLE 16 + +/* Define to the size of `long long', as computed by sizeof. */ +/* #define SIZEOF_LONG_LONG 8 */ + +/* Define to the size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* Define to the size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 4 + +/* Define to the size of `size_t', as computed by sizeof. */ +#if defined(_WIN64) +# define SIZEOF_SIZE_T 8 +#else +# define SIZEOF_SIZE_T 4 +#endif + +/* Define to the size of `curl_off_t', as computed by sizeof. */ +#define SIZEOF_CURL_OFF_T 8 + +/* ---------------------------------------------------------------- */ +/* BSD-style lwIP TCP/IP stack SPECIFIC */ +/* ---------------------------------------------------------------- */ + +/* Define to use BSD-style lwIP TCP/IP stack. */ +/* #define USE_LWIPSOCK 1 */ + +#ifdef USE_LWIPSOCK +# undef USE_WINSOCK +# undef HAVE_WINSOCK_H +# undef HAVE_WINSOCK2_H +# undef HAVE_WS2TCPIP_H +# undef HAVE_ERRNO_H +# undef HAVE_GETHOSTNAME +# undef HAVE_GETNAMEINFO +# undef LWIP_POSIX_SOCKETS_IO_NAMES +# undef RECV_TYPE_ARG1 +# undef RECV_TYPE_ARG3 +# undef SEND_TYPE_ARG1 +# undef SEND_TYPE_ARG3 +# define HAVE_FREEADDRINFO +# define HAVE_GETADDRINFO +# define HAVE_GETHOSTBYNAME +# define HAVE_GETHOSTBYNAME_R +# define HAVE_GETHOSTBYNAME_R_6 +# define LWIP_POSIX_SOCKETS_IO_NAMES 0 +# define RECV_TYPE_ARG1 int +# define RECV_TYPE_ARG3 size_t +# define SEND_TYPE_ARG1 int +# define SEND_TYPE_ARG3 size_t +#endif + +/* ---------------------------------------------------------------- */ +/* Watt-32 tcp/ip SPECIFIC */ +/* ---------------------------------------------------------------- */ + +#ifdef USE_WATT32 + #include + #undef byte + #undef word + #undef USE_WINSOCK + #undef HAVE_WINSOCK_H + #undef HAVE_WINSOCK2_H + #undef HAVE_WS2TCPIP_H + #define HAVE_GETADDRINFO + #define HAVE_GETNAMEINFO + #define HAVE_SYS_IOCTL_H + #define HAVE_SYS_SOCKET_H + #define HAVE_NETINET_IN_H + #define HAVE_NETDB_H + #define HAVE_ARPA_INET_H + #define HAVE_FREEADDRINFO + #define SOCKET int +#endif + + +/* ---------------------------------------------------------------- */ +/* COMPILER SPECIFIC */ +/* ---------------------------------------------------------------- */ + +/* Define to nothing if compiler does not support 'const' qualifier. */ +/* #define const */ + +/* Define to nothing if compiler does not support 'volatile' qualifier. */ +/* #define volatile */ + +/* Windows should not have HAVE_GMTIME_R defined */ +/* #undef HAVE_GMTIME_R */ + +/* Define if the compiler supports C99 variadic macro style. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#define HAVE_VARIADIC_MACROS_C99 1 +#endif + +/* Define if the compiler supports the 'long long' data type. */ +#if defined(__MINGW32__) || defined(__WATCOMC__) || \ + (defined(_MSC_VER) && (_MSC_VER >= 1310)) || \ + (defined(__BORLANDC__) && (__BORLANDC__ >= 0x561)) +#define HAVE_LONGLONG 1 +#endif + +/* Define to avoid VS2005 complaining about portable C functions. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#define _CRT_SECURE_NO_DEPRECATE 1 +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif + +/* VS2005 and later default size for time_t is 64-bit, unless + _USE_32BIT_TIME_T has been defined to get a 32-bit time_t. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +# ifndef _USE_32BIT_TIME_T +# define SIZEOF_TIME_T 8 +# else +# define SIZEOF_TIME_T 4 +# endif +#endif + +/* Define some minimum and default build targets for Visual Studio */ +#if defined(_MSC_VER) + /* Officially, Microsoft's Windows SDK versions 6.X does not support Windows + 2000 as a supported build target. VS2008 default installations provides + an embedded Windows SDK v6.0A along with the claim that Windows 2000 is a + valid build target for VS2008. Popular belief is that binaries built with + VS2008 using Windows SDK versions v6.X and Windows 2000 as a build target + are functional. */ +# define VS2008_MIN_TARGET 0x0500 + + /* The minimum build target for VS2012 is Vista unless Update 1 is installed + and the v110_xp toolset is chosen. */ +# if defined(_USING_V110_SDK71_) +# define VS2012_MIN_TARGET 0x0501 +# else +# define VS2012_MIN_TARGET 0x0600 +# endif + + /* VS2008 default build target is Windows Vista. We override default target + to be Windows XP. */ +# define VS2008_DEF_TARGET 0x0501 + + /* VS2012 default build target is Windows Vista unless Update 1 is installed + and the v110_xp toolset is chosen. */ +# if defined(_USING_V110_SDK71_) +# define VS2012_DEF_TARGET 0x0501 +# else +# define VS2012_DEF_TARGET 0x0600 +# endif +#endif + +/* VS2008 default target settings and minimum build target check. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (_MSC_VER <= 1600) +# ifndef _WIN32_WINNT +# define _WIN32_WINNT VS2008_DEF_TARGET +# endif +# ifndef WINVER +# define WINVER VS2008_DEF_TARGET +# endif +# if (_WIN32_WINNT < VS2008_MIN_TARGET) || (WINVER < VS2008_MIN_TARGET) +# error VS2008 does not support Windows build targets prior to Windows 2000 +# endif +#endif + +/* VS2012 default target settings and minimum build target check. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1700) +# ifndef _WIN32_WINNT +# define _WIN32_WINNT VS2012_DEF_TARGET +# endif +# ifndef WINVER +# define WINVER VS2012_DEF_TARGET +# endif +# if (_WIN32_WINNT < VS2012_MIN_TARGET) || (WINVER < VS2012_MIN_TARGET) +# if defined(_USING_V110_SDK71_) +# error VS2012 does not support Windows build targets prior to Windows XP +# else +# error VS2012 does not support Windows build targets prior to Windows \ +Vista +# endif +# endif +#endif + +/* When no build target is specified Pelles C 5.00 and later default build + target is Windows Vista. We override default target to be Windows 2000. */ +#if defined(__POCC__) && (__POCC__ >= 500) +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0500 +# endif +# ifndef WINVER +# define WINVER 0x0500 +# endif +#endif + +/* Availability of freeaddrinfo, getaddrinfo, getnameinfo and if_nametoindex + functions is quite convoluted, compiler dependent and even build target + dependent. */ +#if defined(HAVE_WS2TCPIP_H) +# if defined(__POCC__) +# define HAVE_FREEADDRINFO 1 +# define HAVE_GETADDRINFO 1 +# define HAVE_GETADDRINFO_THREADSAFE 1 +# define HAVE_GETNAMEINFO 1 +# elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) +# define HAVE_FREEADDRINFO 1 +# define HAVE_GETADDRINFO 1 +# define HAVE_GETADDRINFO_THREADSAFE 1 +# define HAVE_GETNAMEINFO 1 +# elif defined(_MSC_VER) && (_MSC_VER >= 1200) +# define HAVE_FREEADDRINFO 1 +# define HAVE_GETADDRINFO 1 +# define HAVE_GETADDRINFO_THREADSAFE 1 +# define HAVE_GETNAMEINFO 1 +# endif +#endif + +#if defined(__POCC__) +# ifndef _MSC_VER +# error Microsoft extensions /Ze compiler option is required +# endif +# ifndef __POCC__OLDNAMES +# error Compatibility names /Go compiler option is required +# endif +#endif + +/* ---------------------------------------------------------------- */ +/* STRUCT RELATED */ +/* ---------------------------------------------------------------- */ + +/* Define if you have struct sockaddr_storage. */ +#if !defined(__SALFORDC__) && !defined(__BORLANDC__) +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 +#endif + +/* Define if you have struct timeval. */ +#define HAVE_STRUCT_TIMEVAL 1 + +/* Define if struct sockaddr_in6 has the sin6_scope_id member. */ +#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 + +#if defined(HAVE_WINSOCK2_H) && defined(_WIN32_WINNT) && \ + (_WIN32_WINNT >= 0x0600) +#define HAVE_STRUCT_POLLFD 1 +#endif + +/* ---------------------------------------------------------------- */ +/* LARGE FILE SUPPORT */ +/* ---------------------------------------------------------------- */ + +#if defined(_MSC_VER) && !defined(_WIN32_WCE) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define USE_WIN32_LARGE_FILES +# else +# define USE_WIN32_SMALL_FILES +# endif +#endif + +#if defined(__MINGW32__) && !defined(USE_WIN32_LARGE_FILES) +# define USE_WIN32_LARGE_FILES +#endif + +#if defined(__WATCOMC__) && !defined(USE_WIN32_LARGE_FILES) +# define USE_WIN32_LARGE_FILES +#endif + +#if defined(__POCC__) +# undef USE_WIN32_LARGE_FILES +#endif + +#if !defined(USE_WIN32_LARGE_FILES) && !defined(USE_WIN32_SMALL_FILES) +# define USE_WIN32_SMALL_FILES +#endif + +/* ---------------------------------------------------------------- */ +/* DNS RESOLVER SPECIALTY */ +/* ---------------------------------------------------------------- */ + +/* + * Undefine both USE_ARES and USE_THREADS_WIN32 for synchronous DNS. + */ + +/* Define to enable c-ares asynchronous DNS lookups. */ +/* #define USE_ARES 1 */ + +/* Xbox: Use synchronous DNS resolution (no threading required) */ +#ifdef _XBOX +# define USE_SYNC_DNS 1 +#endif + +/* Default define to enable threaded asynchronous DNS lookups. */ +#if !defined(USE_SYNC_DNS) && !defined(USE_ARES) && \ + !defined(USE_THREADS_WIN32) +# define USE_THREADS_WIN32 1 +#endif + +#if defined(USE_ARES) && defined(USE_THREADS_WIN32) +# error "Only one DNS lookup specialty may be defined at most" +#endif + +/* ---------------------------------------------------------------- */ +/* LDAP SUPPORT */ +/* ---------------------------------------------------------------- */ + +#if defined(CURL_HAS_NOVELL_LDAPSDK) || defined(CURL_HAS_MOZILLA_LDAPSDK) +#undef USE_WIN32_LDAP +#define HAVE_LDAP_SSL_H 1 +#define HAVE_LDAP_URL_PARSE 1 +#elif defined(CURL_HAS_OPENLDAP_LDAPSDK) +#undef USE_WIN32_LDAP +#define HAVE_LDAP_URL_PARSE 1 +#else +#undef HAVE_LDAP_URL_PARSE +#define HAVE_LDAP_SSL 1 +#define USE_WIN32_LDAP 1 +#endif + +#if defined(__WATCOMC__) && defined(USE_WIN32_LDAP) +#if __WATCOMC__ < 1280 +#define WINBERAPI __declspec(cdecl) +#define WINLDAPAPI __declspec(cdecl) +#endif +#endif + +#if defined(__POCC__) && defined(USE_WIN32_LDAP) +# define CURL_DISABLE_LDAP 1 +#endif + +/* Define to use the Windows crypto library. */ +#define USE_WIN32_CRYPTO + +/* Define to use Unix sockets. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1500) +/* sdkddkver.h first shipped with Platform SDK v6.0A included with VS2008 */ +#include +#if defined(NTDDI_WIN10_RS4) +#define USE_UNIX_SOCKETS +#endif +#endif + +/* ---------------------------------------------------------------- */ +/* ADDITIONAL DEFINITIONS */ +/* ---------------------------------------------------------------- */ + +/* Define cpu-machine-OS */ +#undef OS +#if defined(_M_IX86) || defined(__i386__) /* x86 (MSVC or gcc) */ +#define OS "i386-pc-win32" +#elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (MSVC >=2005 or gcc) */ +#define OS "x86_64-pc-win32" +#elif defined(_M_IA64) /* Itanium */ +#define OS "ia64-pc-win32" +#else +#define OS "unknown-pc-win32" +#endif + +/* Name of package */ +#define PACKAGE "curl" + +/* If you want to build curl with the built-in manual */ +#define USE_MANUAL 1 + +#if defined(__POCC__) || defined(USE_IPV6) +# define ENABLE_IPV6 1 +#endif + +#endif /* HEADER_CURL_CONFIG_WIN32_H */ diff --git a/libcurl/lib/config-win32ce.h b/libcurl/lib/config-win32ce.h new file mode 100644 index 0000000..1820522 --- /dev/null +++ b/libcurl/lib/config-win32ce.h @@ -0,0 +1,448 @@ +#ifndef HEADER_CURL_CONFIG_WIN32CE_H +#define HEADER_CURL_CONFIG_WIN32CE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* lib/config-win32ce.h - Hand crafted config file for windows ce */ +/* ================================================================ */ + +/* ---------------------------------------------------------------- */ +/* HEADER FILES */ +/* ---------------------------------------------------------------- */ + +/* Define if you have the header file. */ +/* #define HAVE_ARPA_INET_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_ASSERT_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_CRYPTO_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_ERRNO_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_ERR_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_GETOPT_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_IO_H 1 + +/* Define if you need the malloc.h header header file even with stdlib.h */ +#define NEED_MALLOC_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_NETDB_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_NETINET_IN_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_SGTTY_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SSL_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_PROCESS_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_PARAM_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_SELECT_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_SOCKET_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_SOCKIO_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file */ +/* #define HAVE_SYS_TIME_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_TYPES_H 1 */ + +/* Define if you have the header file */ +#define HAVE_SYS_UTIME_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_TERMIO_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_TERMIOS_H 1 */ + +/* Define if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define if you have the header file. */ +#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) +#define HAVE_UNISTD_H 1 +#endif + +/* Define if you have the header file. */ +#define HAVE_WINDOWS_H 1 + +/* Define if you have the header file. */ +#define HAVE_WINSOCK_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_WINSOCK2_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_WS2TCPIP_H 1 */ + +/* ---------------------------------------------------------------- */ +/* OTHER HEADER INFO */ +/* ---------------------------------------------------------------- */ + +/* Define if sig_atomic_t is an available typedef. */ +#define HAVE_SIG_ATOMIC_T 1 + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +/* #define TIME_WITH_SYS_TIME 1 */ + +/* ---------------------------------------------------------------- */ +/* FUNCTIONS */ +/* ---------------------------------------------------------------- */ + +/* Define if you have the closesocket function. */ +#define HAVE_CLOSESOCKET 1 + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #define HAVE_DOPRNT 1 */ + +/* Define if you have the gethostbyaddr function. */ +#define HAVE_GETHOSTBYADDR 1 + +/* Define if you have the gethostname function. */ +#define HAVE_GETHOSTNAME 1 + +/* Define if you have the getpass function. */ +/* #define HAVE_GETPASS 1 */ + +/* Define if you have the getservbyname function. */ +#define HAVE_GETSERVBYNAME 1 + +/* Define if you have the gettimeofday function. */ +/* #define HAVE_GETTIMEOFDAY 1 */ + +/* Define if you have the inet_addr function. */ +#define HAVE_INET_ADDR 1 + +/* Define if you have the ioctlsocket function. */ +#define HAVE_IOCTLSOCKET 1 + +/* Define if you have a working ioctlsocket FIONBIO function. */ +#define HAVE_IOCTLSOCKET_FIONBIO 1 + +/* Define if you have the perror function. */ +#define HAVE_PERROR 1 + +/* Define if you have the RAND_screen function when using SSL */ +#define HAVE_RAND_SCREEN 1 + +/* Define if you have the `RAND_status' function when using SSL. */ +#define HAVE_RAND_STATUS 1 + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the setvbuf function. */ +#define HAVE_SETVBUF 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strcasecmp function. */ +/* #define HAVE_STRCASECMP 1 */ + +/* Define if you have the strdup function. */ +/* #define HAVE_STRDUP 1 */ + +/* Define if you have the strftime function. */ +/* #define HAVE_STRFTIME 1 */ + +/* Define if you have the stricmp function. */ +/* #define HAVE_STRICMP 1 */ + +/* Define if you have the strncasecmp function. */ +/* #define HAVE_STRNCASECMP 1 */ + +/* Define if you have the strnicmp function. */ +/* #define HAVE_STRNICMP 1 */ + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtoll function. */ +#if defined(__MINGW32__) || defined(__WATCOMC__) +#define HAVE_STRTOLL 1 +#endif + +/* Define if you have the tcgetattr function. */ +/* #define HAVE_TCGETATTR 1 */ + +/* Define if you have the tcsetattr function. */ +/* #define HAVE_TCSETATTR 1 */ + +/* Define if you have the utime function */ +#define HAVE_UTIME 1 + +/* Define if you have the getnameinfo function. */ +#define HAVE_GETNAMEINFO 1 + +/* Define to the type qualifier of arg 1 for getnameinfo. */ +#define GETNAMEINFO_QUAL_ARG1 const + +/* Define to the type of arg 1 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * + +/* Define to the type of arg 2 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG2 socklen_t + +/* Define to the type of args 4 and 6 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG46 DWORD + +/* Define to the type of arg 7 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG7 int + +/* Define if you have the recv function. */ +#define HAVE_RECV 1 + +/* Define to the type of arg 1 for recv. */ +#define RECV_TYPE_ARG1 SOCKET + +/* Define to the type of arg 2 for recv. */ +#define RECV_TYPE_ARG2 char * + +/* Define to the type of arg 3 for recv. */ +#define RECV_TYPE_ARG3 int + +/* Define to the type of arg 4 for recv. */ +#define RECV_TYPE_ARG4 int + +/* Define to the function return type for recv. */ +#define RECV_TYPE_RETV int + +/* Define if you have the recvfrom function. */ +#define HAVE_RECVFROM 1 + +/* Define to the type of arg 1 for recvfrom. */ +#define RECVFROM_TYPE_ARG1 SOCKET + +/* Define to the type pointed by arg 2 for recvfrom. */ +#define RECVFROM_TYPE_ARG2 char + +/* Define to the type of arg 3 for recvfrom. */ +#define RECVFROM_TYPE_ARG3 int + +/* Define to the type of arg 4 for recvfrom. */ +#define RECVFROM_TYPE_ARG4 int + +/* Define to the type pointed by arg 5 for recvfrom. */ +#define RECVFROM_TYPE_ARG5 struct sockaddr + +/* Define to the type pointed by arg 6 for recvfrom. */ +#define RECVFROM_TYPE_ARG6 int + +/* Define to the function return type for recvfrom. */ +#define RECVFROM_TYPE_RETV int + +/* Define if you have the send function. */ +#define HAVE_SEND 1 + +/* Define to the type of arg 1 for send. */ +#define SEND_TYPE_ARG1 SOCKET + +/* Define to the type qualifier of arg 2 for send. */ +#define SEND_QUAL_ARG2 const + +/* Define to the type of arg 2 for send. */ +#define SEND_TYPE_ARG2 char * + +/* Define to the type of arg 3 for send. */ +#define SEND_TYPE_ARG3 int + +/* Define to the type of arg 4 for send. */ +#define SEND_TYPE_ARG4 int + +/* Define to the function return type for send. */ +#define SEND_TYPE_RETV int + +/* ---------------------------------------------------------------- */ +/* TYPEDEF REPLACEMENTS */ +/* ---------------------------------------------------------------- */ + +/* Define this if in_addr_t is not an available 'typedefed' type */ +#define in_addr_t unsigned long + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define ssize_t if it is not an available 'typedefed' type */ +#if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || defined(__POCC__) +#elif defined(_WIN64) +#define ssize_t __int64 +#else +#define ssize_t int +#endif + +/* ---------------------------------------------------------------- */ +/* TYPE SIZES */ +/* ---------------------------------------------------------------- */ + +/* The size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of `long double', as computed by sizeof. */ +#define SIZEOF_LONG_DOUBLE 16 + +/* The size of `long long', as computed by sizeof. */ +/* #define SIZEOF_LONG_LONG 8 */ + +/* The size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* Define to the size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 4 + +/* The size of `size_t', as computed by sizeof. */ +#if defined(_WIN64) +# define SIZEOF_SIZE_T 8 +#else +# define SIZEOF_SIZE_T 4 +#endif + +/* ---------------------------------------------------------------- */ +/* STRUCT RELATED */ +/* ---------------------------------------------------------------- */ + +/* Define this if you have struct sockaddr_storage */ +/* #define HAVE_STRUCT_SOCKADDR_STORAGE 1 */ + +/* Define this if you have struct timeval */ +#define HAVE_STRUCT_TIMEVAL 1 + +/* Define this if struct sockaddr_in6 has the sin6_scope_id member */ +#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 + +/* ---------------------------------------------------------------- */ +/* COMPILER SPECIFIC */ +/* ---------------------------------------------------------------- */ + +/* Undef keyword 'const' if it does not work. */ +/* #undef const */ + +/* Define to avoid VS2005 complaining about portable C functions */ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#define _CRT_SECURE_NO_DEPRECATE 1 +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif + +/* VS2005 and later default size for time_t is 64-bit, unless */ +/* _USE_32BIT_TIME_T has been defined to get a 32-bit time_t. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +# ifndef _USE_32BIT_TIME_T +# define SIZEOF_TIME_T 8 +# else +# define SIZEOF_TIME_T 4 +# endif +#endif + +/* ---------------------------------------------------------------- */ +/* LARGE FILE SUPPORT */ +/* ---------------------------------------------------------------- */ + +#if defined(_MSC_VER) && !defined(_WIN32_WCE) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define USE_WIN32_LARGE_FILES +# else +# define USE_WIN32_SMALL_FILES +# endif +#endif + +#if !defined(USE_WIN32_LARGE_FILES) && !defined(USE_WIN32_SMALL_FILES) +# define USE_WIN32_SMALL_FILES +#endif + +/* ---------------------------------------------------------------- */ +/* LDAP SUPPORT */ +/* ---------------------------------------------------------------- */ + +#define USE_WIN32_LDAP 1 +#undef HAVE_LDAP_URL_PARSE + +/* ---------------------------------------------------------------- */ +/* ADDITIONAL DEFINITIONS */ +/* ---------------------------------------------------------------- */ + +/* Define cpu-machine-OS */ +#undef OS +#define OS "i386-pc-win32ce" + +/* Name of package */ +#define PACKAGE "curl" + +/* ---------------------------------------------------------------- */ +/* WinCE */ +/* ---------------------------------------------------------------- */ + +#ifndef UNICODE +# define UNICODE +#endif + +#ifndef _UNICODE +# define _UNICODE +#endif + +#define CURL_DISABLE_FILE 1 +#define CURL_DISABLE_TELNET 1 +#define CURL_DISABLE_LDAP 1 + +#define ENOSPC 1 +#define ENOMEM 2 +#define EAGAIN 3 + +extern int stat(const char *path, struct stat *buffer); + +#endif /* HEADER_CURL_CONFIG_WIN32CE_H */ diff --git a/libcurl/lib/conncache.c b/libcurl/lib/conncache.c new file mode 100644 index 0000000..2f4dd4b --- /dev/null +++ b/libcurl/lib/conncache.c @@ -0,0 +1,638 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, + * Copyright (C) 2012 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "urldata.h" +#include "url.h" +#include "progress.h" +#include "multiif.h" +#include "sendf.h" +#include "conncache.h" +#include "share.h" +#include "sigpipe.h" +#include "connect.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#ifdef CURLDEBUG +/* the debug versions of these macros make extra certain that the lock is + never doubly locked or unlocked */ +#define CONN_LOCK(x) if((x)->share) { \ + Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE); \ + DEBUGASSERT(!(x)->state.conncache_lock); \ + (x)->state.conncache_lock = TRUE; \ + } + +#define CONN_UNLOCK(x) if((x)->share) { \ + DEBUGASSERT((x)->state.conncache_lock); \ + (x)->state.conncache_lock = FALSE; \ + Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT); \ + } +#else +#define CONN_LOCK(x) if((x)->share) \ + Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE) +#define CONN_UNLOCK(x) if((x)->share) \ + Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT) +#endif + +#define HASHKEY_SIZE 128 + +static void conn_llist_dtor(void *user, void *element) +{ + struct connectdata *conn = element; + (void)user; + conn->bundle = NULL; +} + +static CURLcode bundle_create(struct Curl_easy *data, + struct connectbundle **cb_ptr) +{ + (void)data; + DEBUGASSERT(*cb_ptr == NULL); + *cb_ptr = malloc(sizeof(struct connectbundle)); + if(!*cb_ptr) + return CURLE_OUT_OF_MEMORY; + + (*cb_ptr)->num_connections = 0; + (*cb_ptr)->multiuse = BUNDLE_UNKNOWN; + + Curl_llist_init(&(*cb_ptr)->conn_list, (curl_llist_dtor) conn_llist_dtor); + return CURLE_OK; +} + +static void bundle_destroy(struct connectbundle *cb_ptr) +{ + if(!cb_ptr) + return; + + Curl_llist_destroy(&cb_ptr->conn_list, NULL); + + free(cb_ptr); +} + +/* Add a connection to a bundle */ +static void bundle_add_conn(struct connectbundle *cb_ptr, + struct connectdata *conn) +{ + Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn, + &conn->bundle_node); + conn->bundle = cb_ptr; + cb_ptr->num_connections++; +} + +/* Remove a connection from a bundle */ +static int bundle_remove_conn(struct connectbundle *cb_ptr, + struct connectdata *conn) +{ + struct curl_llist_element *curr; + + curr = cb_ptr->conn_list.head; + while(curr) { + if(curr->ptr == conn) { + Curl_llist_remove(&cb_ptr->conn_list, curr, NULL); + cb_ptr->num_connections--; + conn->bundle = NULL; + return 1; /* we removed a handle */ + } + curr = curr->next; + } + return 0; +} + +static void free_bundle_hash_entry(void *freethis) +{ + struct connectbundle *b = (struct connectbundle *) freethis; + + bundle_destroy(b); +} + +int Curl_conncache_init(struct conncache *connc, int size) +{ + int rc; + + /* allocate a new easy handle to use when closing cached connections */ + connc->closure_handle = curl_easy_init(); + if(!connc->closure_handle) + return 1; /* bad */ + + rc = Curl_hash_init(&connc->hash, size, Curl_hash_str, + Curl_str_key_compare, free_bundle_hash_entry); + if(rc) { + Curl_close(connc->closure_handle); + connc->closure_handle = NULL; + } + else + connc->closure_handle->state.conn_cache = connc; + + return rc; +} + +void Curl_conncache_destroy(struct conncache *connc) +{ + if(connc) + Curl_hash_destroy(&connc->hash); +} + +/* creates a key to find a bundle for this connection */ +static void hashkey(struct connectdata *conn, char *buf, + size_t len, /* something like 128 is fine */ + const char **hostp) +{ + const char *hostname; + long port = conn->remote_port; + + if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { + hostname = conn->http_proxy.host.name; + port = conn->port; + } + else if(conn->bits.conn_to_host) + hostname = conn->conn_to_host.name; + else + hostname = conn->host.name; + + if(hostp) + /* report back which name we used */ + *hostp = hostname; + + /* put the number first so that the hostname gets cut off if too long */ + msnprintf(buf, len, "%ld%s", port, hostname); +} + +void Curl_conncache_unlock(struct Curl_easy *data) +{ + CONN_UNLOCK(data); +} + +/* Returns number of connections currently held in the connection cache. + Locks/unlocks the cache itself! +*/ +size_t Curl_conncache_size(struct Curl_easy *data) +{ + size_t num; + CONN_LOCK(data); + num = data->state.conn_cache->num_conn; + CONN_UNLOCK(data); + return num; +} + +/* Returns number of connections currently held in the connections's bundle + Locks/unlocks the cache itself! +*/ +size_t Curl_conncache_bundle_size(struct connectdata *conn) +{ + size_t num; + CONN_LOCK(conn->data); + num = conn->bundle->num_connections; + CONN_UNLOCK(conn->data); + return num; +} + +/* Look up the bundle with all the connections to the same host this + connectdata struct is setup to use. + + **NOTE**: When it returns, it holds the connection cache lock! */ +struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn, + struct conncache *connc, + const char **hostp) +{ + struct connectbundle *bundle = NULL; + CONN_LOCK(conn->data); + if(connc) { + char key[HASHKEY_SIZE]; + hashkey(conn, key, sizeof(key), hostp); + bundle = Curl_hash_pick(&connc->hash, key, strlen(key)); + } + + return bundle; +} + +static bool conncache_add_bundle(struct conncache *connc, + char *key, + struct connectbundle *bundle) +{ + void *p = Curl_hash_add(&connc->hash, key, strlen(key), bundle); + + return p?TRUE:FALSE; +} + +static void conncache_remove_bundle(struct conncache *connc, + struct connectbundle *bundle) +{ + struct curl_hash_iterator iter; + struct curl_hash_element *he; + + if(!connc) + return; + + Curl_hash_start_iterate(&connc->hash, &iter); + + he = Curl_hash_next_element(&iter); + while(he) { + if(he->ptr == bundle) { + /* The bundle is destroyed by the hash destructor function, + free_bundle_hash_entry() */ + Curl_hash_delete(&connc->hash, he->key, he->key_len); + return; + } + + he = Curl_hash_next_element(&iter); + } +} + +CURLcode Curl_conncache_add_conn(struct conncache *connc, + struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct connectbundle *bundle; + struct connectbundle *new_bundle = NULL; + struct Curl_easy *data = conn->data; + + /* *find_bundle() locks the connection cache */ + bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache, NULL); + if(!bundle) { + int rc; + char key[HASHKEY_SIZE]; + + result = bundle_create(data, &new_bundle); + if(result) { + goto unlock; + } + + hashkey(conn, key, sizeof(key), NULL); + rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle); + + if(!rc) { + bundle_destroy(new_bundle); + result = CURLE_OUT_OF_MEMORY; + goto unlock; + } + bundle = new_bundle; + } + + bundle_add_conn(bundle, conn); + conn->connection_id = connc->next_connection_id++; + connc->num_conn++; + + DEBUGF(infof(conn->data, "Added connection %ld. " + "The cache now contains %zu members\n", + conn->connection_id, connc->num_conn)); + + unlock: + CONN_UNLOCK(data); + + return result; +} + +/* + * Removes the connectdata object from the connection cache *and* clears the + * ->data pointer association. Pass TRUE/FALSE in the 'lock' argument + * depending on if the parent function already holds the lock or not. + */ +void Curl_conncache_remove_conn(struct Curl_easy *data, + struct connectdata *conn, bool lock) +{ + struct connectbundle *bundle = conn->bundle; + struct conncache *connc = data->state.conn_cache; + + /* The bundle pointer can be NULL, since this function can be called + due to a failed connection attempt, before being added to a bundle */ + if(bundle) { + if(lock) { + CONN_LOCK(data); + } + bundle_remove_conn(bundle, conn); + if(bundle->num_connections == 0) + conncache_remove_bundle(connc, bundle); + conn->bundle = NULL; /* removed from it */ + if(connc) { + connc->num_conn--; + DEBUGF(infof(data, "The cache now contains %zu members\n", + connc->num_conn)); + } + conn->data = NULL; /* clear the association */ + if(lock) { + CONN_UNLOCK(data); + } + } +} + +/* This function iterates the entire connection cache and calls the function + func() with the connection pointer as the first argument and the supplied + 'param' argument as the other. + + The conncache lock is still held when the callback is called. It needs it, + so that it can safely continue traversing the lists once the callback + returns. + + Returns 1 if the loop was aborted due to the callback's return code. + + Return 0 from func() to continue the loop, return 1 to abort it. + */ +bool Curl_conncache_foreach(struct Curl_easy *data, + struct conncache *connc, + void *param, + int (*func)(struct connectdata *conn, void *param)) +{ + struct curl_hash_iterator iter; + struct curl_llist_element *curr; + struct curl_hash_element *he; + + if(!connc) + return FALSE; + + CONN_LOCK(data); + Curl_hash_start_iterate(&connc->hash, &iter); + + he = Curl_hash_next_element(&iter); + while(he) { + struct connectbundle *bundle; + + bundle = he->ptr; + he = Curl_hash_next_element(&iter); + + curr = bundle->conn_list.head; + while(curr) { + /* Yes, we need to update curr before calling func(), because func() + might decide to remove the connection */ + struct connectdata *conn = curr->ptr; + curr = curr->next; + + if(1 == func(conn, param)) { + CONN_UNLOCK(data); + return TRUE; + } + } + } + CONN_UNLOCK(data); + return FALSE; +} + +/* Return the first connection found in the cache. Used when closing all + connections. + + NOTE: no locking is done here as this is presumably only done when cleaning + up a cache! +*/ +static struct connectdata * +conncache_find_first_connection(struct conncache *connc) +{ + struct curl_hash_iterator iter; + struct curl_hash_element *he; + struct connectbundle *bundle; + + Curl_hash_start_iterate(&connc->hash, &iter); + + he = Curl_hash_next_element(&iter); + while(he) { + struct curl_llist_element *curr; + bundle = he->ptr; + + curr = bundle->conn_list.head; + if(curr) { + return curr->ptr; + } + + he = Curl_hash_next_element(&iter); + } + + return NULL; +} + +/* + * Give ownership of a connection back to the connection cache. Might + * disconnect the oldest existing in there to make space. + * + * Return TRUE if stored, FALSE if closed. + */ +bool Curl_conncache_return_conn(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + + /* data->multi->maxconnects can be negative, deal with it. */ + size_t maxconnects = + (data->multi->maxconnects < 0) ? data->multi->num_easy * 4: + data->multi->maxconnects; + struct connectdata *conn_candidate = NULL; + + conn->data = NULL; /* no owner anymore */ + conn->lastused = Curl_now(); /* it was used up until now */ + if(maxconnects > 0 && + Curl_conncache_size(data) > maxconnects) { + infof(data, "Connection cache is full, closing the oldest one.\n"); + + conn_candidate = Curl_conncache_extract_oldest(data); + if(conn_candidate) { + /* the winner gets the honour of being disconnected */ + (void)Curl_disconnect(data, conn_candidate, /* dead_connection */ FALSE); + } + } + + return (conn_candidate == conn) ? FALSE : TRUE; + +} + +/* + * This function finds the connection in the connection bundle that has been + * unused for the longest time. + * + * Does not lock the connection cache! + * + * Returns the pointer to the oldest idle connection, or NULL if none was + * found. + */ +struct connectdata * +Curl_conncache_extract_bundle(struct Curl_easy *data, + struct connectbundle *bundle) +{ + struct curl_llist_element *curr; + timediff_t highscore = -1; + timediff_t score; + struct curltime now; + struct connectdata *conn_candidate = NULL; + struct connectdata *conn; + + (void)data; + + now = Curl_now(); + + curr = bundle->conn_list.head; + while(curr) { + conn = curr->ptr; + + if(!CONN_INUSE(conn) && !conn->data) { + /* Set higher score for the age passed since the connection was used */ + score = Curl_timediff(now, conn->lastused); + + if(score > highscore) { + highscore = score; + conn_candidate = conn; + } + } + curr = curr->next; + } + if(conn_candidate) { + /* remove it to prevent another thread from nicking it */ + bundle_remove_conn(bundle, conn_candidate); + data->state.conn_cache->num_conn--; + DEBUGF(infof(data, "The cache now contains %zu members\n", + data->state.conn_cache->num_conn)); + conn_candidate->data = data; /* associate! */ + } + + return conn_candidate; +} + +/* + * This function finds the connection in the connection cache that has been + * unused for the longest time and extracts that from the bundle. + * + * Returns the pointer to the connection, or NULL if none was found. + */ +struct connectdata * +Curl_conncache_extract_oldest(struct Curl_easy *data) +{ + struct conncache *connc = data->state.conn_cache; + struct curl_hash_iterator iter; + struct curl_llist_element *curr; + struct curl_hash_element *he; + timediff_t highscore =- 1; + timediff_t score; + struct curltime now; + struct connectdata *conn_candidate = NULL; + struct connectbundle *bundle; + struct connectbundle *bundle_candidate = NULL; + + now = Curl_now(); + + CONN_LOCK(data); + Curl_hash_start_iterate(&connc->hash, &iter); + + he = Curl_hash_next_element(&iter); + while(he) { + struct connectdata *conn; + + bundle = he->ptr; + + curr = bundle->conn_list.head; + while(curr) { + conn = curr->ptr; + + if(!CONN_INUSE(conn) && !conn->data) { + /* Set higher score for the age passed since the connection was used */ + score = Curl_timediff(now, conn->lastused); + + if(score > highscore) { + highscore = score; + conn_candidate = conn; + bundle_candidate = bundle; + } + } + curr = curr->next; + } + + he = Curl_hash_next_element(&iter); + } + if(conn_candidate) { + /* remove it to prevent another thread from nicking it */ + bundle_remove_conn(bundle_candidate, conn_candidate); + connc->num_conn--; + DEBUGF(infof(data, "The cache now contains %zu members\n", + connc->num_conn)); + conn_candidate->data = data; /* associate! */ + } + CONN_UNLOCK(data); + + return conn_candidate; +} + +void Curl_conncache_close_all_connections(struct conncache *connc) +{ + struct connectdata *conn; + + conn = conncache_find_first_connection(connc); + while(conn) { + SIGPIPE_VARIABLE(pipe_st); + conn->data = connc->closure_handle; + + sigpipe_ignore(conn->data, &pipe_st); + /* This will remove the connection from the cache */ + connclose(conn, "kill all"); + (void)Curl_disconnect(connc->closure_handle, conn, FALSE); + sigpipe_restore(&pipe_st); + + conn = conncache_find_first_connection(connc); + } + + if(connc->closure_handle) { + SIGPIPE_VARIABLE(pipe_st); + sigpipe_ignore(connc->closure_handle, &pipe_st); + + Curl_hostcache_clean(connc->closure_handle, + connc->closure_handle->dns.hostcache); + Curl_close(connc->closure_handle); + sigpipe_restore(&pipe_st); + } +} + +#if 0 +/* Useful for debugging the connection cache */ +void Curl_conncache_print(struct conncache *connc) +{ + struct curl_hash_iterator iter; + struct curl_llist_element *curr; + struct curl_hash_element *he; + + if(!connc) + return; + + fprintf(stderr, "=Bundle cache=\n"); + + Curl_hash_start_iterate(connc->hash, &iter); + + he = Curl_hash_next_element(&iter); + while(he) { + struct connectbundle *bundle; + struct connectdata *conn; + + bundle = he->ptr; + + fprintf(stderr, "%s -", he->key); + curr = bundle->conn_list->head; + while(curr) { + conn = curr->ptr; + + fprintf(stderr, " [%p %d]", (void *)conn, conn->inuse); + curr = curr->next; + } + fprintf(stderr, "\n"); + + he = Curl_hash_next_element(&iter); + } +} +#endif diff --git a/libcurl/lib/conncache.h b/libcurl/lib/conncache.h new file mode 100644 index 0000000..58f9024 --- /dev/null +++ b/libcurl/lib/conncache.h @@ -0,0 +1,87 @@ +#ifndef HEADER_CURL_CONNCACHE_H +#define HEADER_CURL_CONNCACHE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2015 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * All accesses to struct fields and changing of data in the connection cache + * and connectbundles must be done with the conncache LOCKED. The cache might + * be shared. + */ + +struct conncache { + struct curl_hash hash; + size_t num_conn; + long next_connection_id; + struct curltime last_cleanup; + /* handle used for closing cached connections */ + struct Curl_easy *closure_handle; +}; + +#define BUNDLE_NO_MULTIUSE -1 +#define BUNDLE_UNKNOWN 0 /* initial value */ +#define BUNDLE_MULTIPLEX 2 + +struct connectbundle { + int multiuse; /* supports multi-use */ + size_t num_connections; /* Number of connections in the bundle */ + struct curl_llist conn_list; /* The connectdata members of the bundle */ +}; + +/* returns 1 on error, 0 is fine */ +int Curl_conncache_init(struct conncache *, int size); +void Curl_conncache_destroy(struct conncache *connc); + +/* return the correct bundle, to a host or a proxy */ +struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn, + struct conncache *connc, + const char **hostp); +void Curl_conncache_unlock(struct Curl_easy *data); +/* returns number of connections currently held in the connection cache */ +size_t Curl_conncache_size(struct Curl_easy *data); +size_t Curl_conncache_bundle_size(struct connectdata *conn); + +bool Curl_conncache_return_conn(struct connectdata *conn); +CURLcode Curl_conncache_add_conn(struct conncache *connc, + struct connectdata *conn) WARN_UNUSED_RESULT; +void Curl_conncache_remove_conn(struct Curl_easy *data, + struct connectdata *conn, + bool lock); +bool Curl_conncache_foreach(struct Curl_easy *data, + struct conncache *connc, + void *param, + int (*func)(struct connectdata *conn, + void *param)); + +struct connectdata * +Curl_conncache_find_first_connection(struct conncache *connc); + +struct connectdata * +Curl_conncache_extract_bundle(struct Curl_easy *data, + struct connectbundle *bundle); +struct connectdata * +Curl_conncache_extract_oldest(struct Curl_easy *data); +void Curl_conncache_close_all_connections(struct conncache *connc); +void Curl_conncache_print(struct conncache *connc); + +#endif /* HEADER_CURL_CONNCACHE_H */ diff --git a/libcurl/lib/connect.c b/libcurl/lib/connect.c new file mode 100644 index 0000000..7ff9f5c --- /dev/null +++ b/libcurl/lib/connect.c @@ -0,0 +1,1472 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_NETINET_IN_H +#include /* may need it */ +#endif +#ifdef HAVE_SYS_UN_H +#include /* for sockaddr_un */ +#endif +#ifdef HAVE_LINUX_TCP_H +#include +#elif defined(HAVE_NETINET_TCP_H) +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE)) +#include +#endif +#ifdef NETWARE +#undef in_addr_t +#define in_addr_t unsigned long +#endif +#ifdef __VMS +#include +#include +#endif + +#include "urldata.h" +#include "sendf.h" +#include "if2ip.h" +#include "strerror.h" +#include "connect.h" +#include "select.h" +#include "url.h" /* for Curl_safefree() */ +#include "multiif.h" +#include "sockaddr.h" /* required for Curl_sockaddr_storage */ +#include "inet_ntop.h" +#include "inet_pton.h" +#include "vtls/vtls.h" /* for Curl_ssl_check_cxn() */ +#include "progress.h" +#include "warnless.h" +#include "conncache.h" +#include "multihandle.h" +#include "system_win32.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#ifdef __SYMBIAN32__ +/* This isn't actually supported under Symbian OS */ +#undef SO_NOSIGPIPE +#endif + +static bool verifyconnect(curl_socket_t sockfd, int *error); + +#if defined(__DragonFly__) || defined(HAVE_WINSOCK_H) +/* DragonFlyBSD and Windows use millisecond units */ +#define KEEPALIVE_FACTOR(x) (x *= 1000) +#else +#define KEEPALIVE_FACTOR(x) +#endif + +/*#if defined(HAVE_WINSOCK2_H) && !defined(SIO_KEEPALIVE_VALS) +#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) + +struct tcp_keepalive { + u_long onoff; + u_long keepalivetime; + u_long keepaliveinterval; +}; +#endif +*/ + +static void +tcpkeepalive(struct Curl_easy *data, + curl_socket_t sockfd) +{ + int optval = data->set.tcp_keepalive?1:0; + + /* only set IDLE and INTVL if setting KEEPALIVE is successful */ +/* + if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, + (void *)&optval, sizeof(optval)) < 0) { + infof(data, "Failed to set SO_KEEPALIVE on fd %d\n", sockfd); + } + else { +*/ + + +#if defined(SIO_KEEPALIVE_VALS) + struct tcp_keepalive vals; + DWORD dummy; + vals.onoff = 1; + optval = curlx_sltosi(data->set.tcp_keepidle); + KEEPALIVE_FACTOR(optval); + vals.keepalivetime = optval; + optval = curlx_sltosi(data->set.tcp_keepintvl); + KEEPALIVE_FACTOR(optval); + vals.keepaliveinterval = optval; + if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals, sizeof(vals), + NULL, 0, &dummy, NULL, NULL) != 0) { + infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd %d: %d\n", + (int)sockfd, WSAGetLastError()); + } +#else +#ifdef TCP_KEEPIDLE + optval = curlx_sltosi(data->set.tcp_keepidle); + KEEPALIVE_FACTOR(optval); + if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, + (void *)&optval, sizeof(optval)) < 0) { + infof(data, "Failed to set TCP_KEEPIDLE on fd %d\n", sockfd); + } +#endif +#ifdef TCP_KEEPINTVL + optval = curlx_sltosi(data->set.tcp_keepintvl); + KEEPALIVE_FACTOR(optval); + if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, + (void *)&optval, sizeof(optval)) < 0) { + infof(data, "Failed to set TCP_KEEPINTVL on fd %d\n", sockfd); + } +#endif +#ifdef TCP_KEEPALIVE + /* Mac OS X style */ + optval = curlx_sltosi(data->set.tcp_keepidle); + KEEPALIVE_FACTOR(optval); + if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE, + (void *)&optval, sizeof(optval)) < 0) { + infof(data, "Failed to set TCP_KEEPALIVE on fd %d\n", sockfd); + } +#endif +#endif + //} +} + +static CURLcode +singleipconnect(struct connectdata *conn, + const Curl_addrinfo *ai, /* start connecting to this */ + curl_socket_t *sock); + +/* + * Curl_timeleft() returns the amount of milliseconds left allowed for the + * transfer/connection. If the value is negative, the timeout time has already + * elapsed. + * + * The start time is stored in progress.t_startsingle - as set with + * Curl_pgrsTime(..., TIMER_STARTSINGLE); + * + * If 'nowp' is non-NULL, it points to the current time. + * 'duringconnect' is FALSE if not during a connect, as then of course the + * connect timeout is not taken into account! + * + * @unittest: 1303 + */ +timediff_t Curl_timeleft(struct Curl_easy *data, + struct curltime *nowp, + bool duringconnect) +{ + int timeout_set = 0; + timediff_t timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0; + struct curltime now; + + /* if a timeout is set, use the most restrictive one */ + + if(data->set.timeout > 0) + timeout_set |= 1; + if(duringconnect && (data->set.connecttimeout > 0)) + timeout_set |= 2; + + switch(timeout_set) { + case 1: + timeout_ms = data->set.timeout; + break; + case 2: + timeout_ms = data->set.connecttimeout; + break; + case 3: + if(data->set.timeout < data->set.connecttimeout) + timeout_ms = data->set.timeout; + else + timeout_ms = data->set.connecttimeout; + break; + default: + /* use the default */ + if(!duringconnect) + /* if we're not during connect, there's no default timeout so if we're + at zero we better just return zero and not make it a negative number + by the math below */ + return 0; + break; + } + + if(!nowp) { + now = Curl_now(); + nowp = &now; + } + + /* subtract elapsed time */ + if(duringconnect) + /* since this most recent connect started */ + timeout_ms -= Curl_timediff(*nowp, data->progress.t_startsingle); + else + /* since the entire operation started */ + timeout_ms -= Curl_timediff(*nowp, data->progress.t_startop); + if(!timeout_ms) + /* avoid returning 0 as that means no timeout! */ + return -1; + + return timeout_ms; +} + +static CURLcode bindlocal(struct connectdata *conn, + curl_socket_t sockfd, int af, unsigned int scope) +{ + struct Curl_easy *data = conn->data; + + struct Curl_sockaddr_storage sa; + struct sockaddr *sock = (struct sockaddr *)&sa; /* bind to this address */ + curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */ + struct sockaddr_in *si4 = (struct sockaddr_in *)&sa; +#ifdef ENABLE_IPV6 + struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)&sa; +#endif + + struct Curl_dns_entry *h = NULL; + unsigned short port = data->set.localport; /* use this port number, 0 for + "random" */ + /* how many port numbers to try to bind to, increasing one at a time */ + int portnum = data->set.localportrange; + const char *dev = data->set.str[STRING_DEVICE]; + int error; + + /************************************************************* + * Select device to bind socket to + *************************************************************/ + if(!dev && !port) + /* no local kind of binding was requested */ + return CURLE_OK; + + memset(&sa, 0, sizeof(struct Curl_sockaddr_storage)); + + if(dev && (strlen(dev)<255) ) { + char myhost[256] = ""; + int done = 0; /* -1 for error, 1 for address found */ + bool is_interface = FALSE; + bool is_host = FALSE; + static const char *if_prefix = "if!"; + static const char *host_prefix = "host!"; + + if(strncmp(if_prefix, dev, strlen(if_prefix)) == 0) { + dev += strlen(if_prefix); + is_interface = TRUE; + } + else if(strncmp(host_prefix, dev, strlen(host_prefix)) == 0) { + dev += strlen(host_prefix); + is_host = TRUE; + } + + /* interface */ + if(!is_host) { +#ifdef SO_BINDTODEVICE + /* I am not sure any other OSs than Linux that provide this feature, + * and at the least I cannot test. --Ben + * + * This feature allows one to tightly bind the local socket to a + * particular interface. This will force even requests to other + * local interfaces to go out the external interface. + * + * + * Only bind to the interface when specified as interface, not just + * as a hostname or ip address. + * + * interface might be a VRF, eg: vrf-blue, which means it cannot be + * converted to an IP address and would fail Curl_if2ip. Simply try + * to use it straight away. + */ + if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, + dev, (curl_socklen_t)strlen(dev) + 1) == 0) { + /* This is typically "errno 1, error: Operation not permitted" if + * you're not running as root or another suitable privileged + * user. + * If it succeeds it means the parameter was a valid interface and + * not an IP address. Return immediately. + */ + return CURLE_OK; + } +#endif + + switch(Curl_if2ip(af, scope, conn->scope_id, dev, + myhost, sizeof(myhost))) { + case IF2IP_NOT_FOUND: + if(is_interface) { + /* Do not fall back to treating it as a host name */ + failf(data, "Couldn't bind to interface '%s'", dev); + return CURLE_INTERFACE_FAILED; + } + break; + case IF2IP_AF_NOT_SUPPORTED: + /* Signal the caller to try another address family if available */ + return CURLE_UNSUPPORTED_PROTOCOL; + case IF2IP_FOUND: + is_interface = TRUE; + /* + * We now have the numerical IP address in the 'myhost' buffer + */ + infof(data, "Local Interface %s is ip %s using address family %i\n", + dev, myhost, af); + done = 1; + break; + } + } + if(!is_interface) { + /* + * This was not an interface, resolve the name as a host name + * or IP number + * + * Temporarily force name resolution to use only the address type + * of the connection. The resolve functions should really be changed + * to take a type parameter instead. + */ + long ipver = conn->ip_version; + int rc; + + if(af == AF_INET) + conn->ip_version = CURL_IPRESOLVE_V4; +#ifdef ENABLE_IPV6 + else if(af == AF_INET6) + conn->ip_version = CURL_IPRESOLVE_V6; +#endif + + rc = Curl_resolv(conn, dev, 0, FALSE, &h); + if(rc == CURLRESOLV_PENDING) + (void)Curl_resolver_wait_resolv(conn, &h); + conn->ip_version = ipver; + + if(h) { + /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */ + Curl_printable_address(h->addr, myhost, sizeof(myhost)); + infof(data, "Name '%s' family %i resolved to '%s' family %i\n", + dev, af, myhost, h->addr->ai_family); + Curl_resolv_unlock(data, h); + if(af != h->addr->ai_family) { + /* bad IP version combo, signal the caller to try another address + family if available */ + return CURLE_UNSUPPORTED_PROTOCOL; + } + done = 1; + } + else { + /* + * provided dev was no interface (or interfaces are not supported + * e.g. solaris) no ip address and no domain we fail here + */ + done = -1; + } + } + + if(done > 0) { +#ifdef ENABLE_IPV6 + /* IPv6 address */ + if(af == AF_INET6) { +#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID + char *scope_ptr = strchr(myhost, '%'); + if(scope_ptr) + *(scope_ptr++) = 0; +#endif + if(Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) { + si6->sin6_family = AF_INET6; + si6->sin6_port = htons(port); +#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID + if(scope_ptr) + /* The "myhost" string either comes from Curl_if2ip or from + Curl_printable_address. The latter returns only numeric scope + IDs and the former returns none at all. So the scope ID, if + present, is known to be numeric */ + si6->sin6_scope_id = atoi(scope_ptr); +#endif + } + sizeof_sa = sizeof(struct sockaddr_in6); + } + else +#endif + /* IPv4 address */ + if((af == AF_INET) && + (Curl_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) { + si4->sin_family = AF_INET; + si4->sin_port = htons(port); + sizeof_sa = sizeof(struct sockaddr_in); + } + } + + if(done < 1) { + /* errorbuf is set false so failf will overwrite any message already in + the error buffer, so the user receives this error message instead of a + generic resolve error. */ + data->state.errorbuf = FALSE; + failf(data, "Couldn't bind to '%s'", dev); + return CURLE_INTERFACE_FAILED; + } + } + else { + /* no device was given, prepare sa to match af's needs */ +#ifdef ENABLE_IPV6 + if(af == AF_INET6) { + si6->sin6_family = AF_INET6; + si6->sin6_port = htons(port); + sizeof_sa = sizeof(struct sockaddr_in6); + } + else +#endif + if(af == AF_INET) { + si4->sin_family = AF_INET; + si4->sin_port = htons(port); + sizeof_sa = sizeof(struct sockaddr_in); + } + } + + for(;;) { + if(bind(sockfd, sock, sizeof_sa) >= 0) { + /* we succeeded to bind */ + struct Curl_sockaddr_storage add; + curl_socklen_t size = sizeof(add); + memset(&add, 0, sizeof(struct Curl_sockaddr_storage)); + if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) { + char buffer[STRERROR_LEN]; + data->state.os_errno = error = SOCKERRNO; + failf(data, "getsockname() failed with errno %d: %s", + error, Curl_strerror(error, buffer, sizeof(buffer))); + return CURLE_INTERFACE_FAILED; + } + infof(data, "Local port: %hu\n", port); + conn->bits.bound = TRUE; + return CURLE_OK; + } + + if(--portnum > 0) { + infof(data, "Bind to local port %hu failed, trying next\n", port); + port++; /* try next port */ + /* We re-use/clobber the port variable here below */ + if(sock->sa_family == AF_INET) + si4->sin_port = ntohs(port); +#ifdef ENABLE_IPV6 + else + si6->sin6_port = ntohs(port); +#endif + } + else + break; + } + { + char buffer[STRERROR_LEN]; + data->state.os_errno = error = SOCKERRNO; + failf(data, "bind failed with errno %d: %s", + error, Curl_strerror(error, buffer, sizeof(buffer))); + } + + return CURLE_INTERFACE_FAILED; +} + +/* + * verifyconnect() returns TRUE if the connect really has happened. + */ +static bool verifyconnect(curl_socket_t sockfd, int *error) +{ + bool rc = TRUE; +#ifdef SO_ERROR + int err = 0; + curl_socklen_t errSize = sizeof(err); + +#ifdef WIN32 + /* + * In October 2003 we effectively nullified this function on Windows due to + * problems with it using all CPU in multi-threaded cases. + * + * In May 2004, we bring it back to offer more info back on connect failures. + * Gisle Vanem could reproduce the former problems with this function, but + * could avoid them by adding this SleepEx() call below: + * + * "I don't have Rational Quantify, but the hint from his post was + * ntdll::NtRemoveIoCompletion(). So I'd assume the SleepEx (or maybe + * just Sleep(0) would be enough?) would release whatever + * mutex/critical-section the ntdll call is waiting on. + * + * Someone got to verify this on Win-NT 4.0, 2000." + */ + +#ifdef _WIN32_WCE + Sleep(0); +#else + SleepEx(0, FALSE); +#endif + +#endif + + if(0 != getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize)) + err = SOCKERRNO; +#ifdef _WIN32_WCE + /* Old WinCE versions don't support SO_ERROR */ + if(WSAENOPROTOOPT == err) { + SET_SOCKERRNO(0); + err = 0; + } +#endif +#if defined(EBADIOCTL) && defined(__minix) + /* Minix 3.1.x doesn't support getsockopt on UDP sockets */ + if(EBADIOCTL == err) { + SET_SOCKERRNO(0); + err = 0; + } +#endif + if((0 == err) || (EISCONN == err)) + /* we are connected, awesome! */ + rc = TRUE; + else + /* This wasn't a successful connect */ + rc = FALSE; + if(error) + *error = err; +#else + (void)sockfd; + if(error) + *error = SOCKERRNO; +#endif + return rc; +} + +/* Used within the multi interface. Try next IP address, return TRUE if no + more address exists or error */ +static CURLcode trynextip(struct connectdata *conn, + int sockindex, + int tempindex) +{ + const int other = tempindex ^ 1; + CURLcode result = CURLE_COULDNT_CONNECT; + + /* First clean up after the failed socket. + Don't close it yet to ensure that the next IP's socket gets a different + file descriptor, which can prevent bugs when the curl_multi_socket_action + interface is used with certain select() replacements such as kqueue. */ + curl_socket_t fd_to_close = conn->tempsock[tempindex]; + conn->tempsock[tempindex] = CURL_SOCKET_BAD; + + if(sockindex == FIRSTSOCKET) { + Curl_addrinfo *ai = NULL; + int family = AF_UNSPEC; + + if(conn->tempaddr[tempindex]) { + /* find next address in the same protocol family */ + family = conn->tempaddr[tempindex]->ai_family; + ai = conn->tempaddr[tempindex]->ai_next; + } +#ifdef ENABLE_IPV6 + else if(conn->tempaddr[0]) { + /* happy eyeballs - try the other protocol family */ + int firstfamily = conn->tempaddr[0]->ai_family; + family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET; + ai = conn->tempaddr[0]->ai_next; + } +#endif + + while(ai) { + if(conn->tempaddr[other]) { + /* we can safely skip addresses of the other protocol family */ + while(ai && ai->ai_family != family) + ai = ai->ai_next; + } + + if(ai) { + result = singleipconnect(conn, ai, &conn->tempsock[tempindex]); + if(result == CURLE_COULDNT_CONNECT) { + ai = ai->ai_next; + continue; + } + + conn->tempaddr[tempindex] = ai; + } + break; + } + } + + if(fd_to_close != CURL_SOCKET_BAD) + Curl_closesocket(conn, fd_to_close); + + return result; +} + +/* Copies connection info into the session handle to make it available + when the session handle is no longer associated with a connection. */ +void Curl_persistconninfo(struct connectdata *conn) +{ + memcpy(conn->data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN); + memcpy(conn->data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN); + conn->data->info.conn_scheme = conn->handler->scheme; + conn->data->info.conn_protocol = conn->handler->protocol; + conn->data->info.conn_primary_port = conn->primary_port; + conn->data->info.conn_local_port = conn->local_port; +} + +UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr, + long *port); + +/* retrieves ip address and port from a sockaddr structure. + note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */ +UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr, + long *port) +{ + struct sockaddr_in *si = NULL; +#ifdef ENABLE_IPV6 + struct sockaddr_in6 *si6 = NULL; +#endif +#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX) + struct sockaddr_un *su = NULL; +#endif + + switch(sa->sa_family) { + case AF_INET: + si = (struct sockaddr_in *)(void *) sa; + if(Curl_inet_ntop(sa->sa_family, &si->sin_addr, + addr, MAX_IPADR_LEN)) { + unsigned short us_port = ntohs(si->sin_port); + *port = us_port; + return TRUE; + } + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + si6 = (struct sockaddr_in6 *)(void *) sa; + if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr, + addr, MAX_IPADR_LEN)) { + unsigned short us_port = ntohs(si6->sin6_port); + *port = us_port; + return TRUE; + } + break; +#endif +#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX) + case AF_UNIX: + su = (struct sockaddr_un*)sa; + msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path); + *port = 0; + return TRUE; +#endif + default: + break; + } + + addr[0] = '\0'; + *port = 0; + errno = EAFNOSUPPORT; + return FALSE; +} + +/* retrieves the start/end point information of a socket of an established + connection */ +void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) +{ + if(conn->socktype == SOCK_DGRAM) + /* there's no connection! */ + return; + +#if defined(HAVE_GETPEERNAME) || defined(HAVE_GETSOCKNAME) + if(!conn->bits.reuse && !conn->bits.tcp_fastopen) { + struct Curl_easy *data = conn->data; + char buffer[STRERROR_LEN]; + struct Curl_sockaddr_storage ssrem; + struct Curl_sockaddr_storage ssloc; + curl_socklen_t len; +#ifdef HAVE_GETPEERNAME + len = sizeof(struct Curl_sockaddr_storage); + if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) { + int error = SOCKERRNO; + failf(data, "getpeername() failed with errno %d: %s", + error, Curl_strerror(error, buffer, sizeof(buffer))); + return; + } +#endif +#ifdef HAVE_GETSOCKNAME + len = sizeof(struct Curl_sockaddr_storage); + memset(&ssloc, 0, sizeof(ssloc)); + if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) { + int error = SOCKERRNO; + failf(data, "getsockname() failed with errno %d: %s", + error, Curl_strerror(error, buffer, sizeof(buffer))); + return; + } +#endif +#ifdef HAVE_GETPEERNAME + if(!getaddressinfo((struct sockaddr*)&ssrem, + conn->primary_ip, &conn->primary_port)) { + failf(data, "ssrem inet_ntop() failed with errno %d: %s", + errno, Curl_strerror(errno, buffer, sizeof(buffer))); + return; + } + memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); +#endif +#ifdef HAVE_GETSOCKNAME + if(!getaddressinfo((struct sockaddr*)&ssloc, + conn->local_ip, &conn->local_port)) { + failf(data, "ssloc inet_ntop() failed with errno %d: %s", + errno, Curl_strerror(errno, buffer, sizeof(buffer))); + return; + } +#endif + } +#else /* !HAVE_GETSOCKNAME && !HAVE_GETPEERNAME */ + (void)sockfd; /* unused */ +#endif + + /* persist connection info in session handle */ + Curl_persistconninfo(conn); +} + +/* + * Curl_is_connected() checks if the socket has connected. + */ + +CURLcode Curl_is_connected(struct connectdata *conn, + int sockindex, + bool *connected) +{ + struct Curl_easy *data = conn->data; + CURLcode result = CURLE_OK; + timediff_t allow; + int error = 0; + struct curltime now; + int rc; + int i; + + DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET); + + *connected = FALSE; /* a very negative world view is best */ + + if(conn->bits.tcpconnect[sockindex]) { + /* we are connected already! */ + *connected = TRUE; + return CURLE_OK; + } + + now = Curl_now(); + + /* figure out how long time we have left to connect */ + allow = Curl_timeleft(data, &now, TRUE); + + if(allow < 0) { + /* time-out, bail out, go home */ + failf(data, "Connection time-out"); + return CURLE_OPERATION_TIMEDOUT; + } + + for(i = 0; i<2; i++) { + const int other = i ^ 1; + if(conn->tempsock[i] == CURL_SOCKET_BAD) + continue; + +#ifdef mpeix + /* Call this function once now, and ignore the results. We do this to + "clear" the error state on the socket so that we can later read it + reliably. This is reported necessary on the MPE/iX operating system. */ + (void)verifyconnect(conn->tempsock[i], NULL); +#endif + + /* check socket for connect */ + rc = SOCKET_WRITABLE(conn->tempsock[i], 0); + + if(rc == 0) { /* no connection yet */ + error = 0; + if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr) { + infof(data, "After %ldms connect time, move on!\n", + conn->timeoutms_per_addr); + error = ETIMEDOUT; + } + + /* should we try another protocol family? */ + if(i == 0 && conn->tempaddr[1] == NULL && + (Curl_timediff(now, conn->connecttime) >= + data->set.happy_eyeballs_timeout)) { + trynextip(conn, sockindex, 1); + } + } + else if(rc == CURL_CSELECT_OUT || conn->bits.tcp_fastopen) { + if(verifyconnect(conn->tempsock[i], &error)) { + /* we are connected with TCP, awesome! */ + + /* use this socket from now on */ + conn->sock[sockindex] = conn->tempsock[i]; + conn->ip_addr = conn->tempaddr[i]; + conn->tempsock[i] = CURL_SOCKET_BAD; +#ifdef ENABLE_IPV6 + conn->bits.ipv6 = (conn->ip_addr->ai_family == AF_INET6)?TRUE:FALSE; +#endif + + /* close the other socket, if open */ + if(conn->tempsock[other] != CURL_SOCKET_BAD) { + Curl_closesocket(conn, conn->tempsock[other]); + conn->tempsock[other] = CURL_SOCKET_BAD; + } + + /* see if we need to do any proxy magic first once we connected */ + result = Curl_connected_proxy(conn, sockindex); + if(result) + return result; + + conn->bits.tcpconnect[sockindex] = TRUE; + + *connected = TRUE; + if(sockindex == FIRSTSOCKET) + Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ + Curl_updateconninfo(conn, conn->sock[sockindex]); + Curl_verboseconnect(conn); + + return CURLE_OK; + } + infof(data, "Connection failed\n"); + } + else if(rc & CURL_CSELECT_ERR) + (void)verifyconnect(conn->tempsock[i], &error); + + /* + * The connection failed here, we should attempt to connect to the "next + * address" for the given host. But first remember the latest error. + */ + if(error) { + data->state.os_errno = error; + SET_SOCKERRNO(error); + if(conn->tempaddr[i]) { + CURLcode status; + char ipaddress[MAX_IPADR_LEN]; + char buffer[STRERROR_LEN]; + Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN); + infof(data, "connect to %s port %ld failed: %s\n", + ipaddress, conn->port, + Curl_strerror(error, buffer, sizeof(buffer))); + + conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ? + allow : allow / 2; + + status = trynextip(conn, sockindex, i); + if(status != CURLE_COULDNT_CONNECT + || conn->tempsock[other] == CURL_SOCKET_BAD) + /* the last attempt failed and no other sockets remain open */ + result = status; + } + } + } + + if(result) { + /* no more addresses to try */ + const char *hostname; + char buffer[STRERROR_LEN]; + + /* if the first address family runs out of addresses to try before + the happy eyeball timeout, go ahead and try the next family now */ + if(conn->tempaddr[1] == NULL) { + result = trynextip(conn, sockindex, 1); + if(!result) + return result; + } + + if(conn->bits.socksproxy) + hostname = conn->socks_proxy.host.name; + else if(conn->bits.httpproxy) + hostname = conn->http_proxy.host.name; + else if(conn->bits.conn_to_host) + hostname = conn->conn_to_host.name; + else + hostname = conn->host.name; + + failf(data, "Failed to connect to %s port %ld: %s", + hostname, conn->port, + Curl_strerror(error, buffer, sizeof(buffer))); + } + + return result; +} + +static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) +{ +#if defined(TCP_NODELAY) +//#if !defined(CURL_DISABLE_VERBOSE_STRINGS) + struct Curl_easy *data = conn->data; +//#endif + curl_socklen_t onoff = (curl_socklen_t) 1; + int level = IPPROTO_TCP; + char buffer[STRERROR_LEN]; + +#if defined(CURL_DISABLE_VERBOSE_STRINGS) + (void) conn; +#endif + + if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff, + sizeof(onoff)) < 0) + infof(data, "Could not set TCP_NODELAY: %s\n", + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + else + infof(data, "TCP_NODELAY set\n"); +#else + (void)conn; + (void)sockfd; +#endif +} + +#ifdef SO_NOSIGPIPE +/* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when + sending data to a dead peer (instead of relying on the 4th argument to send + being MSG_NOSIGNAL). Possibly also existing and in use on other BSD + systems? */ +static void nosigpipe(struct connectdata *conn, + curl_socket_t sockfd) +{ + struct Curl_easy *data = conn->data; + int onoff = 1; + if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff, + sizeof(onoff)) < 0) { + char buffer[STRERROR_LEN]; + infof(data, "Could not set SO_NOSIGPIPE: %s\n", + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + } +} +#else +#define nosigpipe(x,y) Curl_nop_stmt +#endif + +#ifdef USE_WINSOCK +/* When you run a program that uses the Windows Sockets API, you may + experience slow performance when you copy data to a TCP server. + + https://support.microsoft.com/kb/823764 + + Work-around: Make the Socket Send Buffer Size Larger Than the Program Send + Buffer Size + + The problem described in this knowledge-base is applied only to pre-Vista + Windows. Following function trying to detect OS version and skips + SO_SNDBUF adjustment for Windows Vista and above. +*/ +#define DETECT_OS_NONE 0 +#define DETECT_OS_PREVISTA 1 +#define DETECT_OS_VISTA_OR_LATER 2 + +void Curl_sndbufset(curl_socket_t sockfd) +{ + int val = CURL_MAX_WRITE_SIZE + 32; + int curval = 0; + int curlen = sizeof(curval); + + static int detectOsState = DETECT_OS_NONE; + + if(detectOsState == DETECT_OS_NONE) { + if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) + detectOsState = DETECT_OS_VISTA_OR_LATER; + else + detectOsState = DETECT_OS_PREVISTA; + } + + if(detectOsState == DETECT_OS_VISTA_OR_LATER) + return; + + if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0) + if(curval > val) + return; + + setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val)); +} +#endif + +/* + * singleipconnect() + * + * Note that even on connect fail it returns CURLE_OK, but with 'sock' set to + * CURL_SOCKET_BAD. Other errors will however return proper errors. + * + * singleipconnect() connects to the given IP only, and it may return without + * having connected. + */ +static CURLcode singleipconnect(struct connectdata *conn, + const Curl_addrinfo *ai, + curl_socket_t *sockp) +{ + struct Curl_sockaddr_ex addr; + int rc = -1; + int error = 0; + bool isconnected = FALSE; + struct Curl_easy *data = conn->data; + curl_socket_t sockfd; + CURLcode result; + char ipaddress[MAX_IPADR_LEN]; + long port; + bool is_tcp; +#ifdef TCP_FASTOPEN_CONNECT + int optval = 1; +#endif + char buffer[STRERROR_LEN]; + + *sockp = CURL_SOCKET_BAD; + + result = Curl_socket(conn, ai, &addr, &sockfd); + if(result) + /* Failed to create the socket, but still return OK since we signal the + lack of socket as well. This allows the parent function to keep looping + over alternative addresses/socket families etc. */ + return CURLE_OK; + + /* store remote address and port used in this connection attempt */ + if(!getaddressinfo((struct sockaddr*)&addr.sa_addr, + ipaddress, &port)) { + /* malformed address or bug in inet_ntop, try next address */ + failf(data, "sa_addr inet_ntop() failed with errno %d: %s", + errno, Curl_strerror(errno, buffer, sizeof(buffer))); + Curl_closesocket(conn, sockfd); + return CURLE_OK; + } + infof(data, " Trying %s:%ld...\n", ipaddress, port); + +#ifdef ENABLE_IPV6 + is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) && + addr.socktype == SOCK_STREAM; +#else + is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM; +#endif + if(is_tcp && data->set.tcp_nodelay) + tcpnodelay(conn, sockfd); + + nosigpipe(conn, sockfd); + + Curl_sndbufset(sockfd); + + if(is_tcp && data->set.tcp_keepalive) + tcpkeepalive(data, sockfd); + + if(data->set.fsockopt) { + /* activate callback for setting socket options */ + Curl_set_in_callback(data, true); + error = data->set.fsockopt(data->set.sockopt_client, + sockfd, + CURLSOCKTYPE_IPCXN); + Curl_set_in_callback(data, false); + + if(error == CURL_SOCKOPT_ALREADY_CONNECTED) + isconnected = TRUE; + else if(error) { + Curl_closesocket(conn, sockfd); /* close the socket and bail out */ + return CURLE_ABORTED_BY_CALLBACK; + } + } + + /* possibly bind the local end to an IP, interface or port */ + if(addr.family == AF_INET +#ifdef ENABLE_IPV6 + || addr.family == AF_INET6 +#endif + ) { + result = bindlocal(conn, sockfd, addr.family, + Curl_ipv6_scope((struct sockaddr*)&addr.sa_addr)); + if(result) { + Curl_closesocket(conn, sockfd); /* close socket and bail out */ + if(result == CURLE_UNSUPPORTED_PROTOCOL) { + /* The address family is not supported on this interface. + We can continue trying addresses */ + return CURLE_COULDNT_CONNECT; + } + return result; + } + } + + /* set socket non-blocking */ + (void)curlx_nonblock(sockfd, TRUE); + + conn->connecttime = Curl_now(); + if(conn->num_addr > 1) + Curl_expire(data, conn->timeoutms_per_addr, EXPIRE_DNS_PER_NAME); + + /* Connect TCP sockets, bind UDP */ + if(!isconnected && (conn->socktype == SOCK_STREAM)) { + if(conn->bits.tcp_fastopen) { +#if defined(CONNECT_DATA_IDEMPOTENT) /* Darwin */ +# if defined(HAVE_BUILTIN_AVAILABLE) + /* while connectx function is available since macOS 10.11 / iOS 9, + it did not have the interface declared correctly until + Xcode 9 / macOS SDK 10.13 */ + if(__builtin_available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) { + sa_endpoints_t endpoints; + endpoints.sae_srcif = 0; + endpoints.sae_srcaddr = NULL; + endpoints.sae_srcaddrlen = 0; + endpoints.sae_dstaddr = &addr.sa_addr; + endpoints.sae_dstaddrlen = addr.addrlen; + + rc = connectx(sockfd, &endpoints, SAE_ASSOCID_ANY, + CONNECT_RESUME_ON_READ_WRITE | CONNECT_DATA_IDEMPOTENT, + NULL, 0, NULL, NULL); + } + else { + rc = connect(sockfd, &addr.sa_addr, addr.addrlen); + } +# else + rc = connect(sockfd, &addr.sa_addr, addr.addrlen); +# endif /* HAVE_BUILTIN_AVAILABLE */ +#elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */ + if(setsockopt(sockfd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT, + (void *)&optval, sizeof(optval)) < 0) + infof(data, "Failed to enable TCP Fast Open on fd %d\n", sockfd); + else + infof(data, "TCP_FASTOPEN_CONNECT set\n"); + + rc = connect(sockfd, &addr.sa_addr, addr.addrlen); +#elif defined(MSG_FASTOPEN) /* old Linux */ + if(conn->given->flags & PROTOPT_SSL) + rc = connect(sockfd, &addr.sa_addr, addr.addrlen); + else + rc = 0; /* Do nothing */ +#endif + } + else { + rc = connect(sockfd, &addr.sa_addr, addr.addrlen); + } + + if(-1 == rc) + error = SOCKERRNO; + } + else { + *sockp = sockfd; + return CURLE_OK; + } + + if(-1 == rc) { + switch(error) { + case EINPROGRESS: + case EWOULDBLOCK: +#if defined(EAGAIN) +#if (EAGAIN) != (EWOULDBLOCK) + /* On some platforms EAGAIN and EWOULDBLOCK are the + * same value, and on others they are different, hence + * the odd #if + */ + case EAGAIN: +#endif +#endif + result = CURLE_OK; + break; + + default: + /* unknown error, fallthrough and try another address! */ + infof(data, "Immediate connect fail for %s: %s\n", + ipaddress, Curl_strerror(error, buffer, sizeof(buffer))); + data->state.os_errno = error; + + /* connect failed */ + Curl_closesocket(conn, sockfd); + result = CURLE_COULDNT_CONNECT; + } + } + + if(!result) + *sockp = sockfd; + + return result; +} + +/* + * TCP connect to the given host with timeout, proxy or remote doesn't matter. + * There might be more than one IP address to try out. Fill in the passed + * pointer with the connected socket. + */ + +CURLcode Curl_connecthost(struct connectdata *conn, /* context */ + const struct Curl_dns_entry *remotehost) +{ + struct Curl_easy *data = conn->data; + struct curltime before = Curl_now(); + CURLcode result = CURLE_COULDNT_CONNECT; + + timediff_t timeout_ms = Curl_timeleft(data, &before, TRUE); + + if(timeout_ms < 0) { + /* a precaution, no need to continue if time already is up */ + failf(data, "Connection time-out"); + return CURLE_OPERATION_TIMEDOUT; + } + + conn->num_addr = Curl_num_addresses(remotehost->addr); + conn->tempaddr[0] = remotehost->addr; + conn->tempaddr[1] = NULL; + conn->tempsock[0] = CURL_SOCKET_BAD; + conn->tempsock[1] = CURL_SOCKET_BAD; + + /* Max time for the next connection attempt */ + conn->timeoutms_per_addr = + conn->tempaddr[0]->ai_next == NULL ? timeout_ms : timeout_ms / 2; + + /* start connecting to first IP */ + while(conn->tempaddr[0]) { + result = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0])); + if(!result) + break; + conn->tempaddr[0] = conn->tempaddr[0]->ai_next; + } + + if(conn->tempsock[0] == CURL_SOCKET_BAD) { + if(!result) + result = CURLE_COULDNT_CONNECT; + return result; + } + + data->info.numconnects++; /* to track the number of connections made */ + Curl_expire(conn->data, data->set.happy_eyeballs_timeout, + EXPIRE_HAPPY_EYEBALLS); + + return CURLE_OK; +} + +struct connfind { + struct connectdata *tofind; + bool found; +}; + +static int conn_is_conn(struct connectdata *conn, void *param) +{ + struct connfind *f = (struct connfind *)param; + if(conn == f->tofind) { + f->found = TRUE; + return 1; + } + return 0; +} + +/* + * Used to extract socket and connectdata struct for the most recent + * transfer on the given Curl_easy. + * + * The returned socket will be CURL_SOCKET_BAD in case of failure! + */ +curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, + struct connectdata **connp) +{ + DEBUGASSERT(data); + + /* this works for an easy handle: + * - that has been used for curl_easy_perform() + * - that is associated with a multi handle, and whose connection + * was detached with CURLOPT_CONNECT_ONLY + */ + if(data->state.lastconnect && (data->multi_easy || data->multi)) { + struct connectdata *c = data->state.lastconnect; + struct connfind find; + find.tofind = data->state.lastconnect; + find.found = FALSE; + + Curl_conncache_foreach(data, data->multi_easy? + &data->multi_easy->conn_cache: + &data->multi->conn_cache, &find, conn_is_conn); + + if(!find.found) { + data->state.lastconnect = NULL; + return CURL_SOCKET_BAD; + } + + if(connp) { + /* only store this if the caller cares for it */ + *connp = c; + c->data = data; + } + return c->sock[FIRSTSOCKET]; + } + else + return CURL_SOCKET_BAD; +} + +/* + * Check if a connection seems to be alive. + */ +bool Curl_connalive(struct connectdata *conn) +{ + /* First determine if ssl */ + if(conn->ssl[FIRSTSOCKET].use) { + /* use the SSL context */ + if(!Curl_ssl_check_cxn(conn)) + return false; /* FIN received */ + } +/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */ +#ifdef MSG_PEEK + else if(conn->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) + return false; + else { + /* use the socket */ + char buf; + if(recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf, + (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) { + return false; /* FIN received */ + } + } +#endif + return true; +} + +/* + * Close a socket. + * + * 'conn' can be NULL, beware! + */ +int Curl_closesocket(struct connectdata *conn, + curl_socket_t sock) +{ + if(conn && conn->fclosesocket) { + if((sock == conn->sock[SECONDARYSOCKET]) && + conn->sock_accepted[SECONDARYSOCKET]) + /* if this socket matches the second socket, and that was created with + accept, then we MUST NOT call the callback but clear the accepted + status */ + conn->sock_accepted[SECONDARYSOCKET] = FALSE; + else { + int rc; + Curl_multi_closed(conn->data, sock); + Curl_set_in_callback(conn->data, true); + rc = conn->fclosesocket(conn->closesocket_client, sock); + Curl_set_in_callback(conn->data, false); + return rc; + } + } + + if(conn) + /* tell the multi-socket code about this */ + Curl_multi_closed(conn->data, sock); + + sclose(sock); + + return 0; +} + +/* + * Create a socket based on info from 'conn' and 'ai'. + * + * 'addr' should be a pointer to the correct struct to get data back, or NULL. + * 'sockfd' must be a pointer to a socket descriptor. + * + * If the open socket callback is set, used that! + * + */ +CURLcode Curl_socket(struct connectdata *conn, + const Curl_addrinfo *ai, + struct Curl_sockaddr_ex *addr, + curl_socket_t *sockfd) +{ + struct Curl_easy *data = conn->data; + struct Curl_sockaddr_ex dummy; + + if(!addr) + /* if the caller doesn't want info back, use a local temp copy */ + addr = &dummy; + + /* + * The Curl_sockaddr_ex structure is basically libcurl's external API + * curl_sockaddr structure with enough space available to directly hold + * any protocol-specific address structures. The variable declared here + * will be used to pass / receive data to/from the fopensocket callback + * if this has been set, before that, it is initialized from parameters. + */ + + addr->family = ai->ai_family; + addr->socktype = conn->socktype; + addr->protocol = conn->socktype == SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol; + addr->addrlen = ai->ai_addrlen; + + if(addr->addrlen > sizeof(struct Curl_sockaddr_storage)) + addr->addrlen = sizeof(struct Curl_sockaddr_storage); + memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen); + + if(data->set.fopensocket) { + /* + * If the opensocket callback is set, all the destination address + * information is passed to the callback. Depending on this information the + * callback may opt to abort the connection, this is indicated returning + * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When + * the callback returns a valid socket the destination address information + * might have been changed and this 'new' address will actually be used + * here to connect. + */ + Curl_set_in_callback(data, true); + *sockfd = data->set.fopensocket(data->set.opensocket_client, + CURLSOCKTYPE_IPCXN, + (struct curl_sockaddr *)addr); + Curl_set_in_callback(data, false); + } + else + /* opensocket callback not set, so simply create the socket now */ + *sockfd = socket(addr->family, addr->socktype, addr->protocol); + + if(*sockfd == CURL_SOCKET_BAD) + /* no socket, no connection */ + return CURLE_COULDNT_CONNECT; + +#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) + if(conn->scope_id && (addr->family == AF_INET6)) { + struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr; + sa6->sin6_scope_id = conn->scope_id; + } +#endif + + return CURLE_OK; + +} + +/* + * Curl_conncontrol() marks streams or connection for closure. + */ +void Curl_conncontrol(struct connectdata *conn, + int ctrl /* see defines in header */ +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + , const char *reason +#endif + ) +{ + /* close if a connection, or a stream that isn't multiplexed */ + bool closeit = (ctrl == CONNCTRL_CONNECTION) || + ((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM)); + if((ctrl == CONNCTRL_STREAM) && + (conn->handler->flags & PROTOPT_STREAM)) + DEBUGF(infof(conn->data, "Kill stream: %s\n", reason)); + else if((bit)closeit != conn->bits.close) { + DEBUGF(infof(conn->data, "Marked for [%s]: %s\n", + closeit?"closure":"keep alive", reason)); + conn->bits.close = closeit; /* the only place in the source code that + should assign this bit */ + } +} + +/* Data received can be cached at various levels, so check them all here. */ +bool Curl_conn_data_pending(struct connectdata *conn, int sockindex) +{ + int readable; + + if(Curl_ssl_data_pending(conn, sockindex) || + Curl_recv_has_postponed_data(conn, sockindex)) + return true; + + readable = SOCKET_READABLE(conn->sock[sockindex], 0); + return (readable > 0 && (readable & CURL_CSELECT_IN)); +} diff --git a/libcurl/lib/connect.h b/libcurl/lib/connect.h new file mode 100644 index 0000000..6a5c755 --- /dev/null +++ b/libcurl/lib/connect.h @@ -0,0 +1,144 @@ +#ifndef HEADER_CURL_CONNECT_H +#define HEADER_CURL_CONNECT_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */ +#include "sockaddr.h" +#include "timeval.h" + +CURLcode Curl_is_connected(struct connectdata *conn, + int sockindex, + bool *connected); + +CURLcode Curl_connecthost(struct connectdata *conn, + const struct Curl_dns_entry *host); + +/* generic function that returns how much time there's left to run, according + to the timeouts set */ +timediff_t Curl_timeleft(struct Curl_easy *data, + struct curltime *nowp, + bool duringconnect); + +#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */ + +/* + * Used to extract socket and connectdata struct for the most recent + * transfer on the given Curl_easy. + * + * The returned socket will be CURL_SOCKET_BAD in case of failure! + */ +curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, + struct connectdata **connp); + +/* + * Check if a connection seems to be alive. + */ +bool Curl_connalive(struct connectdata *conn); + +#ifdef USE_WINSOCK +/* When you run a program that uses the Windows Sockets API, you may + experience slow performance when you copy data to a TCP server. + + https://support.microsoft.com/kb/823764 + + Work-around: Make the Socket Send Buffer Size Larger Than the Program Send + Buffer Size + +*/ +void Curl_sndbufset(curl_socket_t sockfd); +#else +#define Curl_sndbufset(y) Curl_nop_stmt +#endif + +void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd); +void Curl_persistconninfo(struct connectdata *conn); +int Curl_closesocket(struct connectdata *conn, curl_socket_t sock); + +/* + * The Curl_sockaddr_ex structure is basically libcurl's external API + * curl_sockaddr structure with enough space available to directly hold any + * protocol-specific address structures. The variable declared here will be + * used to pass / receive data to/from the fopensocket callback if this has + * been set, before that, it is initialized from parameters. + */ +struct Curl_sockaddr_ex { + int family; + int socktype; + int protocol; + unsigned int addrlen; + union { + struct sockaddr addr; + struct Curl_sockaddr_storage buff; + } _sa_ex_u; +}; +#define sa_addr _sa_ex_u.addr + +/* + * Create a socket based on info from 'conn' and 'ai'. + * + * Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open + * socket callback is set, used that! + * + */ +CURLcode Curl_socket(struct connectdata *conn, + const Curl_addrinfo *ai, + struct Curl_sockaddr_ex *addr, + curl_socket_t *sockfd); + +/* + * Curl_conncontrol() marks the end of a connection/stream. The 'closeit' + * argument specifies if it is the end of a connection or a stream. + * + * For stream-based protocols (such as HTTP/2), a stream close will not cause + * a connection close. Other protocols will close the connection for both + * cases. + * + * It sets the bit.close bit to TRUE (with an explanation for debug builds), + * when the connection will close. + */ + +#define CONNCTRL_KEEP 0 /* undo a marked closure */ +#define CONNCTRL_CONNECTION 1 +#define CONNCTRL_STREAM 2 + +void Curl_conncontrol(struct connectdata *conn, + int closeit +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + , const char *reason +#endif + ); + +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) +#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM, y) +#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION, y) +#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP, y) +#else /* if !DEBUGBUILD || CURL_DISABLE_VERBOSE_STRINGS */ +#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM) +#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION) +#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP) +#endif + +bool Curl_conn_data_pending(struct connectdata *conn, int sockindex); + +#endif /* HEADER_CURL_CONNECT_H */ diff --git a/libcurl/lib/content_encoding.c b/libcurl/lib/content_encoding.c new file mode 100644 index 0000000..6d47537 --- /dev/null +++ b/libcurl/lib/content_encoding.c @@ -0,0 +1,1020 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include "urldata.h" +#include +#include + +#ifdef HAVE_ZLIB_H +#include +#ifdef __SYMBIAN32__ +/* zlib pollutes the namespace with this definition */ +#undef WIN32 +#endif +#endif + +#ifdef HAVE_BROTLI +#include +#endif + +#include "sendf.h" +#include "http.h" +#include "content_encoding.h" +#include "strdup.h" +#include "strcase.h" +#include "curl_memory.h" +#include "memdebug.h" + +#define CONTENT_ENCODING_DEFAULT "identity" + +#ifndef CURL_DISABLE_HTTP + +#define DSIZ CURL_MAX_WRITE_SIZE /* buffer size for decompressed data */ + + +#ifdef HAVE_LIBZ + +/* Comment this out if zlib is always going to be at least ver. 1.2.0.4 + (doing so will reduce code size slightly). */ +#define OLD_ZLIB_SUPPORT 1 + +#define GZIP_MAGIC_0 0x1f +#define GZIP_MAGIC_1 0x8b + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef enum { + ZLIB_UNINIT, /* uninitialized */ + ZLIB_INIT, /* initialized */ + ZLIB_INFLATING, /* inflating started. */ + ZLIB_EXTERNAL_TRAILER, /* reading external trailer */ + ZLIB_GZIP_HEADER, /* reading gzip header */ + ZLIB_GZIP_INFLATING, /* inflating gzip stream */ + ZLIB_INIT_GZIP /* initialized in transparent gzip mode */ +} zlibInitState; + +/* Writer parameters. */ +typedef struct { + zlibInitState zlib_init; /* zlib init state */ + uInt trailerlen; /* Remaining trailer byte count. */ + z_stream z; /* State structure for zlib. */ +} zlib_params; + + +static voidpf +zalloc_cb(voidpf opaque, unsigned int items, unsigned int size) +{ + (void) opaque; + /* not a typo, keep it calloc() */ + return (voidpf) calloc(items, size); +} + +static void +zfree_cb(voidpf opaque, voidpf ptr) +{ + (void) opaque; + free(ptr); +} + +static CURLcode +process_zlib_error(struct connectdata *conn, z_stream *z) +{ + struct Curl_easy *data = conn->data; + if(z->msg) + failf(data, "Error while processing content unencoding: %s", + z->msg); + else + failf(data, "Error while processing content unencoding: " + "Unknown failure within decompression software."); + + return CURLE_BAD_CONTENT_ENCODING; +} + +static CURLcode +exit_zlib(struct connectdata *conn, + z_stream *z, zlibInitState *zlib_init, CURLcode result) +{ + if(*zlib_init == ZLIB_GZIP_HEADER) + Curl_safefree(z->next_in); + + if(*zlib_init != ZLIB_UNINIT) { + if(inflateEnd(z) != Z_OK && result == CURLE_OK) + result = process_zlib_error(conn, z); + *zlib_init = ZLIB_UNINIT; + } + + return result; +} + +static CURLcode process_trailer(struct connectdata *conn, zlib_params *zp) +{ + z_stream *z = &zp->z; + CURLcode result = CURLE_OK; + uInt len = z->avail_in < zp->trailerlen? z->avail_in: zp->trailerlen; + + /* Consume expected trailer bytes. Terminate stream if exhausted. + Issue an error if unexpected bytes follow. */ + + zp->trailerlen -= len; + z->avail_in -= len; + z->next_in += len; + if(z->avail_in) + result = CURLE_WRITE_ERROR; + if(result || !zp->trailerlen) + result = exit_zlib(conn, z, &zp->zlib_init, result); + else { + /* Only occurs for gzip with zlib < 1.2.0.4 or raw deflate. */ + zp->zlib_init = ZLIB_EXTERNAL_TRAILER; + } + return result; +} + +static CURLcode inflate_stream(struct connectdata *conn, + contenc_writer *writer, zlibInitState started) +{ + zlib_params *zp = (zlib_params *) &writer->params; + z_stream *z = &zp->z; /* zlib state structure */ + uInt nread = z->avail_in; + Bytef *orig_in = z->next_in; + bool done = FALSE; + CURLcode result = CURLE_OK; /* Curl_client_write status */ + char *decomp; /* Put the decompressed data here. */ + + /* Check state. */ + if(zp->zlib_init != ZLIB_INIT && + zp->zlib_init != ZLIB_INFLATING && + zp->zlib_init != ZLIB_INIT_GZIP && + zp->zlib_init != ZLIB_GZIP_INFLATING) + return exit_zlib(conn, z, &zp->zlib_init, CURLE_WRITE_ERROR); + + /* Dynamically allocate a buffer for decompression because it's uncommonly + large to hold on the stack */ + decomp = malloc(DSIZ); + if(decomp == NULL) + return exit_zlib(conn, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY); + + /* because the buffer size is fixed, iteratively decompress and transfer to + the client via downstream_write function. */ + while(!done) { + int status; /* zlib status */ + done = TRUE; + + /* (re)set buffer for decompressed output for every iteration */ + z->next_out = (Bytef *) decomp; + z->avail_out = DSIZ; + +#ifdef Z_BLOCK + /* Z_BLOCK is only available in zlib ver. >= 1.2.0.5 */ + status = inflate(z, Z_BLOCK); +#else + /* fallback for zlib ver. < 1.2.0.5 */ + status = inflate(z, Z_SYNC_FLUSH); +#endif + + /* Flush output data if some. */ + if(z->avail_out != DSIZ) { + if(status == Z_OK || status == Z_STREAM_END) { + zp->zlib_init = started; /* Data started. */ + result = Curl_unencode_write(conn, writer->downstream, decomp, + DSIZ - z->avail_out); + if(result) { + exit_zlib(conn, z, &zp->zlib_init, result); + break; + } + } + } + + /* Dispatch by inflate() status. */ + switch(status) { + case Z_OK: + /* Always loop: there may be unflushed latched data in zlib state. */ + done = FALSE; + break; + case Z_BUF_ERROR: + /* No more data to flush: just exit loop. */ + break; + case Z_STREAM_END: + result = process_trailer(conn, zp); + break; + case Z_DATA_ERROR: + /* some servers seem to not generate zlib headers, so this is an attempt + to fix and continue anyway */ + if(zp->zlib_init == ZLIB_INIT) { + /* Do not use inflateReset2(): only available since zlib 1.2.3.4. */ + (void) inflateEnd(z); /* don't care about the return code */ + if(inflateInit2(z, -MAX_WBITS) == Z_OK) { + z->next_in = orig_in; + z->avail_in = nread; + zp->zlib_init = ZLIB_INFLATING; + zp->trailerlen = 4; /* Tolerate up to 4 unknown trailer bytes. */ + done = FALSE; + break; + } + zp->zlib_init = ZLIB_UNINIT; /* inflateEnd() already called. */ + } + /* FALLTHROUGH */ + default: + result = exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z)); + break; + } + } + free(decomp); + + /* We're about to leave this call so the `nread' data bytes won't be seen + again. If we are in a state that would wrongly allow restart in raw mode + at the next call, assume output has already started. */ + if(nread && zp->zlib_init == ZLIB_INIT) + zp->zlib_init = started; /* Cannot restart anymore. */ + + return result; +} + + +/* Deflate handler. */ +static CURLcode deflate_init_writer(struct connectdata *conn, + contenc_writer *writer) +{ + zlib_params *zp = (zlib_params *) &writer->params; + z_stream *z = &zp->z; /* zlib state structure */ + + if(!writer->downstream) + return CURLE_WRITE_ERROR; + + /* Initialize zlib */ + z->zalloc = (alloc_func) zalloc_cb; + z->zfree = (free_func) zfree_cb; + + if(inflateInit(z) != Z_OK) + return process_zlib_error(conn, z); + zp->zlib_init = ZLIB_INIT; + return CURLE_OK; +} + +static CURLcode deflate_unencode_write(struct connectdata *conn, + contenc_writer *writer, + const char *buf, size_t nbytes) +{ + zlib_params *zp = (zlib_params *) &writer->params; + z_stream *z = &zp->z; /* zlib state structure */ + + /* Set the compressed input when this function is called */ + z->next_in = (Bytef *) buf; + z->avail_in = (uInt) nbytes; + + if(zp->zlib_init == ZLIB_EXTERNAL_TRAILER) + return process_trailer(conn, zp); + + /* Now uncompress the data */ + return inflate_stream(conn, writer, ZLIB_INFLATING); +} + +static void deflate_close_writer(struct connectdata *conn, + contenc_writer *writer) +{ + zlib_params *zp = (zlib_params *) &writer->params; + z_stream *z = &zp->z; /* zlib state structure */ + + exit_zlib(conn, z, &zp->zlib_init, CURLE_OK); +} + +static const content_encoding deflate_encoding = { + "deflate", + NULL, + deflate_init_writer, + deflate_unencode_write, + deflate_close_writer, + sizeof(zlib_params) +}; + + +/* Gzip handler. */ +static CURLcode gzip_init_writer(struct connectdata *conn, + contenc_writer *writer) +{ + zlib_params *zp = (zlib_params *) &writer->params; + z_stream *z = &zp->z; /* zlib state structure */ + + if(!writer->downstream) + return CURLE_WRITE_ERROR; + + /* Initialize zlib */ + z->zalloc = (alloc_func) zalloc_cb; + z->zfree = (free_func) zfree_cb; + + if(strcmp(zlibVersion(), "1.2.0.4") >= 0) { + /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */ + if(inflateInit2(z, MAX_WBITS + 32) != Z_OK) { + return process_zlib_error(conn, z); + } + zp->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ + } + else { + /* we must parse the gzip header and trailer ourselves */ + if(inflateInit2(z, -MAX_WBITS) != Z_OK) { + return process_zlib_error(conn, z); + } + zp->trailerlen = 8; /* A CRC-32 and a 32-bit input size (RFC 1952, 2.2) */ + zp->zlib_init = ZLIB_INIT; /* Initial call state */ + } + + return CURLE_OK; +} + +#ifdef OLD_ZLIB_SUPPORT +/* Skip over the gzip header */ +static enum { + GZIP_OK, + GZIP_BAD, + GZIP_UNDERFLOW +} check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen) +{ + int method, flags; + const ssize_t totallen = len; + + /* The shortest header is 10 bytes */ + if(len < 10) + return GZIP_UNDERFLOW; + + if((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1)) + return GZIP_BAD; + + method = data[2]; + flags = data[3]; + + if(method != Z_DEFLATED || (flags & RESERVED) != 0) { + /* Can't handle this compression method or unknown flag */ + return GZIP_BAD; + } + + /* Skip over time, xflags, OS code and all previous bytes */ + len -= 10; + data += 10; + + if(flags & EXTRA_FIELD) { + ssize_t extra_len; + + if(len < 2) + return GZIP_UNDERFLOW; + + extra_len = (data[1] << 8) | data[0]; + + if(len < (extra_len + 2)) + return GZIP_UNDERFLOW; + + len -= (extra_len + 2); + data += (extra_len + 2); + } + + if(flags & ORIG_NAME) { + /* Skip over NUL-terminated file name */ + while(len && *data) { + --len; + ++data; + } + if(!len || *data) + return GZIP_UNDERFLOW; + + /* Skip over the NUL */ + --len; + ++data; + } + + if(flags & COMMENT) { + /* Skip over NUL-terminated comment */ + while(len && *data) { + --len; + ++data; + } + if(!len || *data) + return GZIP_UNDERFLOW; + + /* Skip over the NUL */ + --len; + } + + if(flags & HEAD_CRC) { + if(len < 2) + return GZIP_UNDERFLOW; + + len -= 2; + } + + *headerlen = totallen - len; + return GZIP_OK; +} +#endif + +static CURLcode gzip_unencode_write(struct connectdata *conn, + contenc_writer *writer, + const char *buf, size_t nbytes) +{ + zlib_params *zp = (zlib_params *) &writer->params; + z_stream *z = &zp->z; /* zlib state structure */ + + if(zp->zlib_init == ZLIB_INIT_GZIP) { + /* Let zlib handle the gzip decompression entirely */ + z->next_in = (Bytef *) buf; + z->avail_in = (uInt) nbytes; + /* Now uncompress the data */ + return inflate_stream(conn, writer, ZLIB_INIT_GZIP); + } + +#ifndef OLD_ZLIB_SUPPORT + /* Support for old zlib versions is compiled away and we are running with + an old version, so return an error. */ + return exit_zlib(conn, z, &zp->zlib_init, CURLE_WRITE_ERROR); + +#else + /* This next mess is to get around the potential case where there isn't + * enough data passed in to skip over the gzip header. If that happens, we + * malloc a block and copy what we have then wait for the next call. If + * there still isn't enough (this is definitely a worst-case scenario), we + * make the block bigger, copy the next part in and keep waiting. + * + * This is only required with zlib versions < 1.2.0.4 as newer versions + * can handle the gzip header themselves. + */ + + switch(zp->zlib_init) { + /* Skip over gzip header? */ + case ZLIB_INIT: + { + /* Initial call state */ + ssize_t hlen; + + switch(check_gzip_header((unsigned char *) buf, nbytes, &hlen)) { + case GZIP_OK: + z->next_in = (Bytef *) buf + hlen; + z->avail_in = (uInt) (nbytes - hlen); + zp->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */ + break; + + case GZIP_UNDERFLOW: + /* We need more data so we can find the end of the gzip header. It's + * possible that the memory block we malloc here will never be freed if + * the transfer abruptly aborts after this point. Since it's unlikely + * that circumstances will be right for this code path to be followed in + * the first place, and it's even more unlikely for a transfer to fail + * immediately afterwards, it should seldom be a problem. + */ + z->avail_in = (uInt) nbytes; + z->next_in = malloc(z->avail_in); + if(z->next_in == NULL) { + return exit_zlib(conn, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY); + } + memcpy(z->next_in, buf, z->avail_in); + zp->zlib_init = ZLIB_GZIP_HEADER; /* Need more gzip header data state */ + /* We don't have any data to inflate yet */ + return CURLE_OK; + + case GZIP_BAD: + default: + return exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z)); + } + + } + break; + + case ZLIB_GZIP_HEADER: + { + /* Need more gzip header data state */ + ssize_t hlen; + z->avail_in += (uInt) nbytes; + z->next_in = Curl_saferealloc(z->next_in, z->avail_in); + if(z->next_in == NULL) { + return exit_zlib(conn, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY); + } + /* Append the new block of data to the previous one */ + memcpy(z->next_in + z->avail_in - nbytes, buf, nbytes); + + switch(check_gzip_header(z->next_in, z->avail_in, &hlen)) { + case GZIP_OK: + /* This is the zlib stream data */ + free(z->next_in); + /* Don't point into the malloced block since we just freed it */ + z->next_in = (Bytef *) buf + hlen + nbytes - z->avail_in; + z->avail_in = (uInt) (z->avail_in - hlen); + zp->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */ + break; + + case GZIP_UNDERFLOW: + /* We still don't have any data to inflate! */ + return CURLE_OK; + + case GZIP_BAD: + default: + return exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z)); + } + + } + break; + + case ZLIB_EXTERNAL_TRAILER: + z->next_in = (Bytef *) buf; + z->avail_in = (uInt) nbytes; + return process_trailer(conn, zp); + + case ZLIB_GZIP_INFLATING: + default: + /* Inflating stream state */ + z->next_in = (Bytef *) buf; + z->avail_in = (uInt) nbytes; + break; + } + + if(z->avail_in == 0) { + /* We don't have any data to inflate; wait until next time */ + return CURLE_OK; + } + + /* We've parsed the header, now uncompress the data */ + return inflate_stream(conn, writer, ZLIB_GZIP_INFLATING); +#endif +} + +static void gzip_close_writer(struct connectdata *conn, + contenc_writer *writer) +{ + zlib_params *zp = (zlib_params *) &writer->params; + z_stream *z = &zp->z; /* zlib state structure */ + + exit_zlib(conn, z, &zp->zlib_init, CURLE_OK); +} + +static const content_encoding gzip_encoding = { + "gzip", + "x-gzip", + gzip_init_writer, + gzip_unencode_write, + gzip_close_writer, + sizeof(zlib_params) +}; + +#endif /* HAVE_LIBZ */ + + +#ifdef HAVE_BROTLI + +/* Writer parameters. */ +typedef struct { + BrotliDecoderState *br; /* State structure for brotli. */ +} brotli_params; + + +static CURLcode brotli_map_error(BrotliDecoderErrorCode be) +{ + switch(be) { + case BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE: + case BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE: + case BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET: + case BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME: + case BROTLI_DECODER_ERROR_FORMAT_CL_SPACE: + case BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE: + case BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT: + case BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1: + case BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2: + case BROTLI_DECODER_ERROR_FORMAT_TRANSFORM: + case BROTLI_DECODER_ERROR_FORMAT_DICTIONARY: + case BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS: + case BROTLI_DECODER_ERROR_FORMAT_PADDING_1: + case BROTLI_DECODER_ERROR_FORMAT_PADDING_2: +#ifdef BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY + case BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY: +#endif +#ifdef BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET + case BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET: +#endif + case BROTLI_DECODER_ERROR_INVALID_ARGUMENTS: + return CURLE_BAD_CONTENT_ENCODING; + case BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES: + case BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS: + case BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP: + case BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1: + case BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2: + case BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES: + return CURLE_OUT_OF_MEMORY; + default: + break; + } + return CURLE_WRITE_ERROR; +} + +static CURLcode brotli_init_writer(struct connectdata *conn, + contenc_writer *writer) +{ + brotli_params *bp = (brotli_params *) &writer->params; + + (void) conn; + + if(!writer->downstream) + return CURLE_WRITE_ERROR; + + bp->br = BrotliDecoderCreateInstance(NULL, NULL, NULL); + return bp->br? CURLE_OK: CURLE_OUT_OF_MEMORY; +} + +static CURLcode brotli_unencode_write(struct connectdata *conn, + contenc_writer *writer, + const char *buf, size_t nbytes) +{ + brotli_params *bp = (brotli_params *) &writer->params; + const uint8_t *src = (const uint8_t *) buf; + char *decomp; + uint8_t *dst; + size_t dstleft; + CURLcode result = CURLE_OK; + BrotliDecoderResult r = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; + + if(!bp->br) + return CURLE_WRITE_ERROR; /* Stream already ended. */ + + decomp = malloc(DSIZ); + if(!decomp) + return CURLE_OUT_OF_MEMORY; + + while((nbytes || r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) && + result == CURLE_OK) { + dst = (uint8_t *) decomp; + dstleft = DSIZ; + r = BrotliDecoderDecompressStream(bp->br, + &nbytes, &src, &dstleft, &dst, NULL); + result = Curl_unencode_write(conn, writer->downstream, + decomp, DSIZ - dstleft); + if(result) + break; + switch(r) { + case BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT: + case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT: + break; + case BROTLI_DECODER_RESULT_SUCCESS: + BrotliDecoderDestroyInstance(bp->br); + bp->br = NULL; + if(nbytes) + result = CURLE_WRITE_ERROR; + break; + default: + result = brotli_map_error(BrotliDecoderGetErrorCode(bp->br)); + break; + } + } + free(decomp); + return result; +} + +static void brotli_close_writer(struct connectdata *conn, + contenc_writer *writer) +{ + brotli_params *bp = (brotli_params *) &writer->params; + + (void) conn; + + if(bp->br) { + BrotliDecoderDestroyInstance(bp->br); + bp->br = NULL; + } +} + +static const content_encoding brotli_encoding = { + "br", + NULL, + brotli_init_writer, + brotli_unencode_write, + brotli_close_writer, + sizeof(brotli_params) +}; +#endif + + +/* Identity handler. */ +static CURLcode identity_init_writer(struct connectdata *conn, + contenc_writer *writer) +{ + (void) conn; + return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR; +} + +static CURLcode identity_unencode_write(struct connectdata *conn, + contenc_writer *writer, + const char *buf, size_t nbytes) +{ + return Curl_unencode_write(conn, writer->downstream, buf, nbytes); +} + +static void identity_close_writer(struct connectdata *conn, + contenc_writer *writer) +{ + (void) conn; + (void) writer; +} + +static const content_encoding identity_encoding = { + "identity", + "none", + identity_init_writer, + identity_unencode_write, + identity_close_writer, + 0 +}; + + +/* supported content encodings table. */ +static const content_encoding * const encodings[] = { + &identity_encoding, +#ifdef HAVE_LIBZ + &deflate_encoding, + &gzip_encoding, +#endif +#ifdef HAVE_BROTLI + &brotli_encoding, +#endif + NULL +}; + + +/* Return a list of comma-separated names of supported encodings. */ +char *Curl_all_content_encodings(void) +{ + size_t len = 0; + const content_encoding * const *cep; + const content_encoding *ce; + char *ace; + + for(cep = encodings; *cep; cep++) { + ce = *cep; + if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) + len += strlen(ce->name) + 2; + } + + if(!len) + return strdup(CONTENT_ENCODING_DEFAULT); + + ace = malloc(len); + if(ace) { + char *p = ace; + for(cep = encodings; *cep; cep++) { + ce = *cep; + if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) { + strcpy(p, ce->name); + p += strlen(p); + *p++ = ','; + *p++ = ' '; + } + } + p[-2] = '\0'; + } + + return ace; +} + + +/* Real client writer: no downstream. */ +static CURLcode client_init_writer(struct connectdata *conn, + contenc_writer *writer) +{ + (void) conn; + return writer->downstream? CURLE_WRITE_ERROR: CURLE_OK; +} + +static CURLcode client_unencode_write(struct connectdata *conn, + contenc_writer *writer, + const char *buf, size_t nbytes) +{ + struct Curl_easy *data = conn->data; + struct SingleRequest *k = &data->req; + + (void) writer; + + if(!nbytes || k->ignorebody) + return CURLE_OK; + + return Curl_client_write(conn, CLIENTWRITE_BODY, (char *) buf, nbytes); +} + +static void client_close_writer(struct connectdata *conn, + contenc_writer *writer) +{ + (void) conn; + (void) writer; +} + +static const content_encoding client_encoding = { + NULL, + NULL, + client_init_writer, + client_unencode_write, + client_close_writer, + 0 +}; + + +/* Deferred error dummy writer. */ +static CURLcode error_init_writer(struct connectdata *conn, + contenc_writer *writer) +{ + (void) conn; + return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR; +} + +static CURLcode error_unencode_write(struct connectdata *conn, + contenc_writer *writer, + const char *buf, size_t nbytes) +{ + char *all = Curl_all_content_encodings(); + + (void) writer; + (void) buf; + (void) nbytes; + + if(!all) + return CURLE_OUT_OF_MEMORY; + failf(conn->data, "Unrecognized content encoding type. " + "libcurl understands %s content encodings.", all); + free(all); + return CURLE_BAD_CONTENT_ENCODING; +} + +static void error_close_writer(struct connectdata *conn, + contenc_writer *writer) +{ + (void) conn; + (void) writer; +} + +static const content_encoding error_encoding = { + NULL, + NULL, + error_init_writer, + error_unencode_write, + error_close_writer, + 0 +}; + +/* Create an unencoding writer stage using the given handler. */ +static contenc_writer *new_unencoding_writer(struct connectdata *conn, + const content_encoding *handler, + contenc_writer *downstream) +{ + size_t sz = offsetof(contenc_writer, params) + handler->paramsize; + contenc_writer *writer = (contenc_writer *) calloc(1, sz); + + if(writer) { + writer->handler = handler; + writer->downstream = downstream; + if(handler->init_writer(conn, writer)) { + free(writer); + writer = NULL; + } + } + + return writer; +} + +/* Write data using an unencoding writer stack. */ +CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer, + const char *buf, size_t nbytes) +{ + if(!nbytes) + return CURLE_OK; + return writer->handler->unencode_write(conn, writer, buf, nbytes); +} + +/* Close and clean-up the connection's writer stack. */ +void Curl_unencode_cleanup(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + struct SingleRequest *k = &data->req; + contenc_writer *writer = k->writer_stack; + + while(writer) { + k->writer_stack = writer->downstream; + writer->handler->close_writer(conn, writer); + free(writer); + writer = k->writer_stack; + } +} + +/* Find the content encoding by name. */ +static const content_encoding *find_encoding(const char *name, size_t len) +{ + const content_encoding * const *cep; + + for(cep = encodings; *cep; cep++) { + const content_encoding *ce = *cep; + if((strncasecompare(name, ce->name, len) && !ce->name[len]) || + (ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len])) + return ce; + } + return NULL; +} + +/* Set-up the unencoding stack from the Content-Encoding header value. + * See RFC 7231 section 3.1.2.2. */ +CURLcode Curl_build_unencoding_stack(struct connectdata *conn, + const char *enclist, int maybechunked) +{ + struct Curl_easy *data = conn->data; + struct SingleRequest *k = &data->req; + + do { + const char *name; + size_t namelen; + + /* Parse a single encoding name. */ + while(ISSPACE(*enclist) || *enclist == ',') + enclist++; + + name = enclist; + + for(namelen = 0; *enclist && *enclist != ','; enclist++) + if(!ISSPACE(*enclist)) + namelen = enclist - name + 1; + + /* Special case: chunked encoding is handled at the reader level. */ + if(maybechunked && namelen == 7 && strncasecompare(name, "chunked", 7)) { + k->chunk = TRUE; /* chunks coming our way. */ + Curl_httpchunk_init(conn); /* init our chunky engine. */ + } + else if(namelen) { + const content_encoding *encoding = find_encoding(name, namelen); + contenc_writer *writer; + + if(!k->writer_stack) { + k->writer_stack = new_unencoding_writer(conn, &client_encoding, NULL); + + if(!k->writer_stack) + return CURLE_OUT_OF_MEMORY; + } + + if(!encoding) + encoding = &error_encoding; /* Defer error at stack use. */ + + /* Stack the unencoding stage. */ + writer = new_unencoding_writer(conn, encoding, k->writer_stack); + if(!writer) + return CURLE_OUT_OF_MEMORY; + k->writer_stack = writer; + } + } while(*enclist); + + return CURLE_OK; +} + +#else +/* Stubs for builds without HTTP. */ +CURLcode Curl_build_unencoding_stack(struct connectdata *conn, + const char *enclist, int maybechunked) +{ + (void) conn; + (void) enclist; + (void) maybechunked; + return CURLE_NOT_BUILT_IN; +} + +CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer, + const char *buf, size_t nbytes) +{ + (void) conn; + (void) writer; + (void) buf; + (void) nbytes; + return CURLE_NOT_BUILT_IN; +} + +void Curl_unencode_cleanup(struct connectdata *conn) +{ + (void) conn; +} + +char *Curl_all_content_encodings(void) +{ + return strdup(CONTENT_ENCODING_DEFAULT); /* Satisfy caller. */ +} + +#endif /* CURL_DISABLE_HTTP */ diff --git a/libcurl/lib/content_encoding.h b/libcurl/lib/content_encoding.h new file mode 100644 index 0000000..4cd52be --- /dev/null +++ b/libcurl/lib/content_encoding.h @@ -0,0 +1,55 @@ +#ifndef HEADER_CURL_CONTENT_ENCODING_H +#define HEADER_CURL_CONTENT_ENCODING_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +/* Decoding writer. */ +typedef struct contenc_writer_s contenc_writer; +typedef struct content_encoding_s content_encoding; + +struct contenc_writer_s { + const content_encoding *handler; /* Encoding handler. */ + contenc_writer *downstream; /* Downstream writer. */ + void *params; /* Encoding-specific storage (variable length). */ +}; + +/* Content encoding writer. */ +struct content_encoding_s { + const char *name; /* Encoding name. */ + const char *alias; /* Encoding name alias. */ + CURLcode (*init_writer)(struct connectdata *conn, contenc_writer *writer); + CURLcode (*unencode_write)(struct connectdata *conn, contenc_writer *writer, + const char *buf, size_t nbytes); + void (*close_writer)(struct connectdata *conn, contenc_writer *writer); + size_t paramsize; +}; + + +CURLcode Curl_build_unencoding_stack(struct connectdata *conn, + const char *enclist, int maybechunked); +CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer, + const char *buf, size_t nbytes); +void Curl_unencode_cleanup(struct connectdata *conn); +char *Curl_all_content_encodings(void); + +#endif /* HEADER_CURL_CONTENT_ENCODING_H */ diff --git a/libcurl/lib/cookie.c b/libcurl/lib/cookie.c new file mode 100644 index 0000000..9a9e14d --- /dev/null +++ b/libcurl/lib/cookie.c @@ -0,0 +1,1657 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/*** + + +RECEIVING COOKIE INFORMATION +============================ + +struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, + const char *file, struct CookieInfo *inc, bool newsession); + + Inits a cookie struct to store data in a local file. This is always + called before any cookies are set. + +struct Cookie *Curl_cookie_add(struct Curl_easy *data, + struct CookieInfo *c, bool httpheader, char *lineptr, + const char *domain, const char *path); + + The 'lineptr' parameter is a full "Set-cookie:" line as + received from a server. + + The function need to replace previously stored lines that this new + line supersedes. + + It may remove lines that are expired. + + It should return an indication of success/error. + + +SENDING COOKIE INFORMATION +========================== + +struct Cookies *Curl_cookie_getlist(struct CookieInfo *cookie, + char *host, char *path, bool secure); + + For a given host and path, return a linked list of cookies that + the client should send to the server if used now. The secure + boolean informs the cookie if a secure connection is achieved or + not. + + It shall only return cookies that haven't expired. + + +Example set of cookies: + + Set-cookie: PRODUCTINFO=webxpress; domain=.fidelity.com; path=/; secure + Set-cookie: PERSONALIZE=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; + domain=.fidelity.com; path=/ftgw; secure + Set-cookie: FidHist=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; + domain=.fidelity.com; path=/; secure + Set-cookie: FidOrder=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; + domain=.fidelity.com; path=/; secure + Set-cookie: DisPend=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; + domain=.fidelity.com; path=/; secure + Set-cookie: FidDis=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; + domain=.fidelity.com; path=/; secure + Set-cookie: + Session_Key@6791a9e0-901a-11d0-a1c8-9b012c88aa77=none;expires=Monday, + 13-Jun-1988 03:04:55 GMT; domain=.fidelity.com; path=/; secure +****/ + + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) + +#include "urldata.h" +#include "cookie.h" +#include "psl.h" +#include "strtok.h" +#include "sendf.h" +#include "slist.h" +#include "share.h" +#include "strtoofft.h" +#include "strcase.h" +#include "curl_get_line.h" +#include "curl_memrchr.h" +#include "inet_pton.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +static void freecookie(struct Cookie *co) +{ + free(co->expirestr); + free(co->domain); + free(co->path); + free(co->spath); + free(co->name); + free(co->value); + free(co->maxage); + free(co->version); + free(co); +} + +static bool tailmatch(const char *cooke_domain, const char *hostname) +{ + size_t cookie_domain_len = strlen(cooke_domain); + size_t hostname_len = strlen(hostname); + + if(hostname_len < cookie_domain_len) + return FALSE; + + if(!strcasecompare(cooke_domain, hostname + hostname_len-cookie_domain_len)) + return FALSE; + + /* A lead char of cookie_domain is not '.'. + RFC6265 4.1.2.3. The Domain Attribute says: + For example, if the value of the Domain attribute is + "example.com", the user agent will include the cookie in the Cookie + header when making HTTP requests to example.com, www.example.com, and + www.corp.example.com. + */ + if(hostname_len == cookie_domain_len) + return TRUE; + if('.' == *(hostname + hostname_len - cookie_domain_len - 1)) + return TRUE; + return FALSE; +} + +/* + * Return true if the given string is an IP(v4|v6) address. + */ +static bool isip(const char *domain) +{ + struct in_addr addr; +#ifdef ENABLE_IPV6 + struct in6_addr addr6; +#endif + + if(Curl_inet_pton(AF_INET, domain, &addr) +#ifdef ENABLE_IPV6 + || Curl_inet_pton(AF_INET6, domain, &addr6) +#endif + ) { + /* domain name given as IP address */ + return TRUE; + } + + return FALSE; +} + +/* + * matching cookie path and url path + * RFC6265 5.1.4 Paths and Path-Match + */ +static bool pathmatch(const char *cookie_path, const char *request_uri) +{ + size_t cookie_path_len; + size_t uri_path_len; + char *uri_path = NULL; + char *pos; + bool ret = FALSE; + + /* cookie_path must not have last '/' separator. ex: /sample */ + cookie_path_len = strlen(cookie_path); + if(1 == cookie_path_len) { + /* cookie_path must be '/' */ + return TRUE; + } + + uri_path = strdup(request_uri); + if(!uri_path) + return FALSE; + pos = strchr(uri_path, '?'); + if(pos) + *pos = 0x0; + + /* #-fragments are already cut off! */ + if(0 == strlen(uri_path) || uri_path[0] != '/') { + free(uri_path); + uri_path = strdup("/"); + if(!uri_path) + return FALSE; + } + + /* here, RFC6265 5.1.4 says + 4. Output the characters of the uri-path from the first character up + to, but not including, the right-most %x2F ("/"). + but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site + without redirect. + Ignore this algorithm because /hoge is uri path for this case + (uri path is not /). + */ + + uri_path_len = strlen(uri_path); + + if(uri_path_len < cookie_path_len) { + ret = FALSE; + goto pathmatched; + } + + /* not using checkprefix() because matching should be case-sensitive */ + if(strncmp(cookie_path, uri_path, cookie_path_len)) { + ret = FALSE; + goto pathmatched; + } + + /* The cookie-path and the uri-path are identical. */ + if(cookie_path_len == uri_path_len) { + ret = TRUE; + goto pathmatched; + } + + /* here, cookie_path_len < uri_path_len */ + if(uri_path[cookie_path_len] == '/') { + ret = TRUE; + goto pathmatched; + } + + ret = FALSE; + +pathmatched: + free(uri_path); + return ret; +} + +/* + * Return the top-level domain, for optimal hashing. + */ +static const char *get_top_domain(const char * const domain, size_t *outlen) +{ + size_t len; + const char *first = NULL, *last; + + if(!domain) + return NULL; + + len = strlen(domain); + last = memrchr(domain, '.', len); + if(last) { + first = memrchr(domain, '.', (last - domain)); + if(first) + len -= (++first - domain); + } + + if(outlen) + *outlen = len; + + return first? first: domain; +} + +/* + * A case-insensitive hash for the cookie domains. + */ +static size_t cookie_hash_domain(const char *domain, const size_t len) +{ + const char *end = domain + len; + size_t h = 5381; + + while(domain < end) { + h += h << 5; + h ^= Curl_raw_toupper(*domain++); + } + + return (h % COOKIE_HASH_SIZE); +} + +/* + * Hash this domain. + */ +static size_t cookiehash(const char * const domain) +{ + const char *top; + size_t len; + + if(!domain || isip(domain)) + return 0; + + top = get_top_domain(domain, &len); + return cookie_hash_domain(top, len); +} + +/* + * cookie path sanitize + */ +static char *sanitize_cookie_path(const char *cookie_path) +{ + size_t len; + char *new_path = strdup(cookie_path); + if(!new_path) + return NULL; + + /* some stupid site sends path attribute with '"'. */ + len = strlen(new_path); + if(new_path[0] == '\"') { + memmove((void *)new_path, (const void *)(new_path + 1), len); + len--; + } + if(len && (new_path[len - 1] == '\"')) { + new_path[len - 1] = 0x0; + len--; + } + + /* RFC6265 5.2.4 The Path Attribute */ + if(new_path[0] != '/') { + /* Let cookie-path be the default-path. */ + free(new_path); + new_path = strdup("/"); + return new_path; + } + + /* convert /hoge/ to /hoge */ + if(len && new_path[len - 1] == '/') { + new_path[len - 1] = 0x0; + } + + return new_path; +} + +/* + * Load cookies from all given cookie files (CURLOPT_COOKIEFILE). + * + * NOTE: OOM or cookie parsing failures are ignored. + */ +void Curl_cookie_loadfiles(struct Curl_easy *data) +{ + struct curl_slist *list = data->change.cookielist; + if(list) { + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + while(list) { + struct CookieInfo *newcookies = Curl_cookie_init(data, + list->data, + data->cookies, + data->set.cookiesession); + if(!newcookies) + /* Failure may be due to OOM or a bad cookie; both are ignored + * but only the first should be + */ + infof(data, "ignoring failed cookie_init for %s\n", list->data); + else + data->cookies = newcookies; + list = list->next; + } + curl_slist_free_all(data->change.cookielist); /* clean up list */ + data->change.cookielist = NULL; /* don't do this again! */ + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + } +} + +/* + * strstore() makes a strdup() on the 'newstr' and if '*str' is non-NULL + * that will be freed before the allocated string is stored there. + * + * It is meant to easily replace strdup() + */ +static void strstore(char **str, const char *newstr) +{ + free(*str); + *str = strdup(newstr); +} + +/* + * remove_expired() removes expired cookies. + */ +static void remove_expired(struct CookieInfo *cookies) +{ + struct Cookie *co, *nx; + curl_off_t now = (curl_off_t)time(NULL); + unsigned int i; + + for(i = 0; i < COOKIE_HASH_SIZE; i++) { + struct Cookie *pv = NULL; + co = cookies->cookies[i]; + while(co) { + nx = co->next; + if(co->expires && co->expires < now) { + if(!pv) { + cookies->cookies[i] = co->next; + } + else { + pv->next = co->next; + } + cookies->numcookies--; + freecookie(co); + } + else { + pv = co; + } + co = nx; + } + } +} + +/* Make sure domain contains a dot or is localhost. */ +static bool bad_domain(const char *domain) +{ + return !strchr(domain, '.') && !strcasecompare(domain, "localhost"); +} + +/**************************************************************************** + * + * Curl_cookie_add() + * + * Add a single cookie line to the cookie keeping object. + * + * Be aware that sometimes we get an IP-only host name, and that might also be + * a numerical IPv6 address. + * + * Returns NULL on out of memory or invalid cookie. This is suboptimal, + * as they should be treated separately. + ***************************************************************************/ + +struct Cookie * +Curl_cookie_add(struct Curl_easy *data, + /* The 'data' pointer here may be NULL at times, and thus + must only be used very carefully for things that can deal + with data being NULL. Such as infof() and similar */ + + struct CookieInfo *c, + bool httpheader, /* TRUE if HTTP header-style line */ + bool noexpire, /* if TRUE, skip remove_expired() */ + char *lineptr, /* first character of the line */ + const char *domain, /* default domain */ + const char *path, /* full path used when this cookie is set, + used to get default path for the cookie + unless set */ + bool secure) /* TRUE if connection is over secure origin */ +{ + struct Cookie *clist; + struct Cookie *co; + struct Cookie *lastc = NULL; + time_t now = time(NULL); + bool replace_old = FALSE; + bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */ + size_t myhash; + +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)data; +#endif + + /* First, alloc and init a new struct for it */ + co = calloc(1, sizeof(struct Cookie)); + if(!co) + return NULL; /* bail out if we're this low on memory */ + + if(httpheader) { + /* This line was read off a HTTP-header */ + char name[MAX_NAME]; + char what[MAX_NAME]; + const char *ptr; + const char *semiptr; + + size_t linelength = strlen(lineptr); + if(linelength > MAX_COOKIE_LINE) { + /* discard overly long lines at once */ + free(co); + return NULL; + } + + semiptr = strchr(lineptr, ';'); /* first, find a semicolon */ + + while(*lineptr && ISBLANK(*lineptr)) + lineptr++; + + ptr = lineptr; + do { + /* we have a = pair or a stand-alone word here */ + name[0] = what[0] = 0; /* init the buffers */ + if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n=] =%" + MAX_NAME_TXT "[^;\r\n]", + name, what)) { + /* Use strstore() below to properly deal with received cookie + headers that have the same string property set more than once, + and then we use the last one. */ + const char *whatptr; + bool done = FALSE; + bool sep; + size_t len = strlen(what); + size_t nlen = strlen(name); + const char *endofn = &ptr[ nlen ]; + + if(nlen >= (MAX_NAME-1) || len >= (MAX_NAME-1) || + ((nlen + len) > MAX_NAME)) { + /* too long individual name or contents, or too long combination of + name + contents. Chrome and Firefox support 4095 or 4096 bytes + combo. */ + freecookie(co); + infof(data, "oversized cookie dropped, name/val %zu + %zu bytes\n", + nlen, len); + return NULL; + } + + /* name ends with a '=' ? */ + sep = (*endofn == '=')?TRUE:FALSE; + + if(nlen) { + endofn--; /* move to the last character */ + if(ISBLANK(*endofn)) { + /* skip trailing spaces in name */ + while(*endofn && ISBLANK(*endofn) && nlen) { + endofn--; + nlen--; + } + name[nlen] = 0; /* new end of name */ + } + } + + /* Strip off trailing whitespace from the 'what' */ + while(len && ISBLANK(what[len-1])) { + what[len-1] = 0; + len--; + } + + /* Skip leading whitespace from the 'what' */ + whatptr = what; + while(*whatptr && ISBLANK(*whatptr)) + whatptr++; + + /* + * Check if we have a reserved prefix set before anything else, as we + * otherwise have to test for the prefix in both the cookie name and + * "the rest". Prefixes must start with '__' and end with a '-', so + * only test for names where that can possibly be true. + */ + if(nlen > 3 && name[0] == '_' && name[1] == '_') { + if(strncasecompare("__Secure-", name, 9)) + co->prefix |= COOKIE_PREFIX__SECURE; + else if(strncasecompare("__Host-", name, 7)) + co->prefix |= COOKIE_PREFIX__HOST; + } + + if(!co->name) { + /* The very first name/value pair is the actual cookie name */ + if(!sep) { + /* Bad name/value pair. */ + badcookie = TRUE; + break; + } + co->name = strdup(name); + co->value = strdup(whatptr); + done = TRUE; + if(!co->name || !co->value) { + badcookie = TRUE; + break; + } + } + else if(!len) { + /* this was a "=" with no content, and we must allow + 'secure' and 'httponly' specified this weirdly */ + done = TRUE; + /* + * secure cookies are only allowed to be set when the connection is + * using a secure protocol, or when the cookie is being set by + * reading from file + */ + if(strcasecompare("secure", name)) { + if(secure || !c->running) { + co->secure = TRUE; + } + else { + badcookie = TRUE; + break; + } + } + else if(strcasecompare("httponly", name)) + co->httponly = TRUE; + else if(sep) + /* there was a '=' so we're not done parsing this field */ + done = FALSE; + } + if(done) + ; + else if(strcasecompare("path", name)) { + strstore(&co->path, whatptr); + if(!co->path) { + badcookie = TRUE; /* out of memory bad */ + break; + } + free(co->spath); /* if this is set again */ + co->spath = sanitize_cookie_path(co->path); + if(!co->spath) { + badcookie = TRUE; /* out of memory bad */ + break; + } + } + else if(strcasecompare("domain", name)) { + bool is_ip; + + /* Now, we make sure that our host is within the given domain, + or the given domain is not valid and thus cannot be set. */ + + if('.' == whatptr[0]) + whatptr++; /* ignore preceding dot */ + +#ifndef USE_LIBPSL + /* + * Without PSL we don't know when the incoming cookie is set on a + * TLD or otherwise "protected" suffix. To reduce risk, we require a + * dot OR the exact host name being "localhost". + */ + if(bad_domain(whatptr)) + domain = ":"; +#endif + + is_ip = isip(domain ? domain : whatptr); + + if(!domain + || (is_ip && !strcmp(whatptr, domain)) + || (!is_ip && tailmatch(whatptr, domain))) { + strstore(&co->domain, whatptr); + if(!co->domain) { + badcookie = TRUE; + break; + } + if(!is_ip) + co->tailmatch = TRUE; /* we always do that if the domain name was + given */ + } + else { + /* we did not get a tailmatch and then the attempted set domain + is not a domain to which the current host belongs. Mark as + bad. */ + badcookie = TRUE; + infof(data, "skipped cookie with bad tailmatch domain: %s\n", + whatptr); + } + } + else if(strcasecompare("version", name)) { + strstore(&co->version, whatptr); + if(!co->version) { + badcookie = TRUE; + break; + } + } + else if(strcasecompare("max-age", name)) { + /* Defined in RFC2109: + + Optional. The Max-Age attribute defines the lifetime of the + cookie, in seconds. The delta-seconds value is a decimal non- + negative integer. After delta-seconds seconds elapse, the + client should discard the cookie. A value of zero means the + cookie should be discarded immediately. + + */ + strstore(&co->maxage, whatptr); + if(!co->maxage) { + badcookie = TRUE; + break; + } + } + else if(strcasecompare("expires", name)) { + strstore(&co->expirestr, whatptr); + if(!co->expirestr) { + badcookie = TRUE; + break; + } + } + /* + else this is the second (or more) name we don't know + about! */ + } + else { + /* this is an "illegal" = pair */ + } + + if(!semiptr || !*semiptr) { + /* we already know there are no more cookies */ + semiptr = NULL; + continue; + } + + ptr = semiptr + 1; + while(*ptr && ISBLANK(*ptr)) + ptr++; + semiptr = strchr(ptr, ';'); /* now, find the next semicolon */ + + if(!semiptr && *ptr) + /* There are no more semicolons, but there's a final name=value pair + coming up */ + semiptr = strchr(ptr, '\0'); + } while(semiptr); + + if(co->maxage) { + CURLofft offt; + offt = curlx_strtoofft((*co->maxage == '\"')? + &co->maxage[1]:&co->maxage[0], NULL, 10, + &co->expires); + if(offt == CURL_OFFT_FLOW) + /* overflow, used max value */ + co->expires = CURL_OFF_T_MAX; + else if(!offt) { + if(!co->expires) + /* already expired */ + co->expires = 1; + else if(CURL_OFF_T_MAX - now < co->expires) + /* would overflow */ + co->expires = CURL_OFF_T_MAX; + else + co->expires += now; + } + } + else if(co->expirestr) { + /* Note that if the date couldn't get parsed for whatever reason, + the cookie will be treated as a session cookie */ + co->expires = curl_getdate(co->expirestr, NULL); + + /* Session cookies have expires set to 0 so if we get that back + from the date parser let's add a second to make it a + non-session cookie */ + if(co->expires == 0) + co->expires = 1; + else if(co->expires < 0) + co->expires = 0; + } + + if(!badcookie && !co->domain) { + if(domain) { + /* no domain was given in the header line, set the default */ + co->domain = strdup(domain); + if(!co->domain) + badcookie = TRUE; + } + } + + if(!badcookie && !co->path && path) { + /* No path was given in the header line, set the default. + Note that the passed-in path to this function MAY have a '?' and + following part that MUST not be stored as part of the path. */ + char *queryp = strchr(path, '?'); + + /* queryp is where the interesting part of the path ends, so now we + want to the find the last */ + char *endslash; + if(!queryp) + endslash = strrchr(path, '/'); + else + endslash = memrchr(path, '/', (queryp - path)); + if(endslash) { + size_t pathlen = (endslash-path + 1); /* include end slash */ + co->path = malloc(pathlen + 1); /* one extra for the zero byte */ + if(co->path) { + memcpy(co->path, path, pathlen); + co->path[pathlen] = 0; /* zero terminate */ + co->spath = sanitize_cookie_path(co->path); + if(!co->spath) + badcookie = TRUE; /* out of memory bad */ + } + else + badcookie = TRUE; + } + } + + if(badcookie || !co->name) { + /* we didn't get a cookie name or a bad one, + this is an illegal line, bail out */ + freecookie(co); + return NULL; + } + + } + else { + /* This line is NOT a HTTP header style line, we do offer support for + reading the odd netscape cookies-file format here */ + char *ptr; + char *firstptr; + char *tok_buf = NULL; + int fields; + + /* IE introduced HTTP-only cookies to prevent XSS attacks. Cookies + marked with httpOnly after the domain name are not accessible + from javascripts, but since curl does not operate at javascript + level, we include them anyway. In Firefox's cookie files, these + lines are preceded with #HttpOnly_ and then everything is + as usual, so we skip 10 characters of the line.. + */ + if(strncmp(lineptr, "#HttpOnly_", 10) == 0) { + lineptr += 10; + co->httponly = TRUE; + } + + if(lineptr[0]=='#') { + /* don't even try the comments */ + free(co); + return NULL; + } + /* strip off the possible end-of-line characters */ + ptr = strchr(lineptr, '\r'); + if(ptr) + *ptr = 0; /* clear it */ + ptr = strchr(lineptr, '\n'); + if(ptr) + *ptr = 0; /* clear it */ + + firstptr = strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */ + + /* Now loop through the fields and init the struct we already have + allocated */ + for(ptr = firstptr, fields = 0; ptr && !badcookie; + ptr = strtok_r(NULL, "\t", &tok_buf), fields++) { + switch(fields) { + case 0: + if(ptr[0]=='.') /* skip preceding dots */ + ptr++; + co->domain = strdup(ptr); + if(!co->domain) + badcookie = TRUE; + break; + case 1: + /* This field got its explanation on the 23rd of May 2001 by + Andrés García: + + flag: A TRUE/FALSE value indicating if all machines within a given + domain can access the variable. This value is set automatically by + the browser, depending on the value you set for the domain. + + As far as I can see, it is set to true when the cookie says + .domain.com and to false when the domain is complete www.domain.com + */ + co->tailmatch = strcasecompare(ptr, "TRUE")?TRUE:FALSE; + break; + case 2: + /* It turns out, that sometimes the file format allows the path + field to remain not filled in, we try to detect this and work + around it! Andrés García made us aware of this... */ + if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) { + /* only if the path doesn't look like a boolean option! */ + co->path = strdup(ptr); + if(!co->path) + badcookie = TRUE; + else { + co->spath = sanitize_cookie_path(co->path); + if(!co->spath) { + badcookie = TRUE; /* out of memory bad */ + } + } + break; + } + /* this doesn't look like a path, make one up! */ + co->path = strdup("/"); + if(!co->path) + badcookie = TRUE; + co->spath = strdup("/"); + if(!co->spath) + badcookie = TRUE; + fields++; /* add a field and fall down to secure */ + /* FALLTHROUGH */ + case 3: + co->secure = FALSE; + if(strcasecompare(ptr, "TRUE")) { + if(secure || c->running) + co->secure = TRUE; + else + badcookie = TRUE; + } + break; + case 4: + if(curlx_strtoofft(ptr, NULL, 10, &co->expires)) + badcookie = TRUE; + break; + case 5: + co->name = strdup(ptr); + if(!co->name) + badcookie = TRUE; + else { + /* For Netscape file format cookies we check prefix on the name */ + if(strncasecompare("__Secure-", co->name, 9)) + co->prefix |= COOKIE_PREFIX__SECURE; + else if(strncasecompare("__Host-", co->name, 7)) + co->prefix |= COOKIE_PREFIX__HOST; + } + break; + case 6: + co->value = strdup(ptr); + if(!co->value) + badcookie = TRUE; + break; + } + } + if(6 == fields) { + /* we got a cookie with blank contents, fix it */ + co->value = strdup(""); + if(!co->value) + badcookie = TRUE; + else + fields++; + } + + if(!badcookie && (7 != fields)) + /* we did not find the sufficient number of fields */ + badcookie = TRUE; + + if(badcookie) { + freecookie(co); + return NULL; + } + + } + + if(co->prefix & COOKIE_PREFIX__SECURE) { + /* The __Secure- prefix only requires that the cookie be set secure */ + if(!co->secure) { + freecookie(co); + return NULL; + } + } + if(co->prefix & COOKIE_PREFIX__HOST) { + /* + * The __Host- prefix requires the cookie to be secure, have a "/" path + * and not have a domain set. + */ + if(co->secure && co->path && strcmp(co->path, "/") == 0 && !co->tailmatch) + ; + else { + freecookie(co); + return NULL; + } + } + + if(!c->running && /* read from a file */ + c->newsession && /* clean session cookies */ + !co->expires) { /* this is a session cookie since it doesn't expire! */ + freecookie(co); + return NULL; + } + + co->livecookie = c->running; + co->creationtime = ++c->lastct; + + /* now, we have parsed the incoming line, we must now check if this + supersedes an already existing cookie, which it may if the previous have + the same domain and path as this */ + + /* at first, remove expired cookies */ + if(!noexpire) + remove_expired(c); + +#ifdef USE_LIBPSL + /* Check if the domain is a Public Suffix and if yes, ignore the cookie. */ + if(domain && co->domain && !isip(co->domain)) { + const psl_ctx_t *psl = Curl_psl_use(data); + int acceptable; + + if(psl) { + acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain); + Curl_psl_release(data); + } + else + acceptable = !bad_domain(domain); + + if(!acceptable) { + infof(data, "cookie '%s' dropped, domain '%s' must not " + "set cookies for '%s'\n", co->name, domain, co->domain); + freecookie(co); + return NULL; + } + } +#endif + + myhash = cookiehash(co->domain); + clist = c->cookies[myhash]; + replace_old = FALSE; + while(clist) { + if(strcasecompare(clist->name, co->name)) { + /* the names are identical */ + + if(clist->domain && co->domain) { + if(strcasecompare(clist->domain, co->domain) && + (clist->tailmatch == co->tailmatch)) + /* The domains are identical */ + replace_old = TRUE; + } + else if(!clist->domain && !co->domain) + replace_old = TRUE; + + if(replace_old) { + /* the domains were identical */ + + if(clist->spath && co->spath) { + if(clist->secure && !co->secure && !secure) { + size_t cllen; + const char *sep; + + /* + * A non-secure cookie may not overlay an existing secure cookie. + * For an existing cookie "a" with path "/login", refuse a new + * cookie "a" with for example path "/login/en", while the path + * "/loginhelper" is ok. + */ + + sep = strchr(clist->spath + 1, '/'); + + if(sep) + cllen = sep - clist->spath; + else + cllen = strlen(clist->spath); + + if(strncasecompare(clist->spath, co->spath, cllen)) { + freecookie(co); + return NULL; + } + } + else if(strcasecompare(clist->spath, co->spath)) + replace_old = TRUE; + else + replace_old = FALSE; + } + else if(!clist->spath && !co->spath) + replace_old = TRUE; + else + replace_old = FALSE; + + } + + if(replace_old && !co->livecookie && clist->livecookie) { + /* Both cookies matched fine, except that the already present + cookie is "live", which means it was set from a header, while + the new one isn't "live" and thus only read from a file. We let + live cookies stay alive */ + + /* Free the newcomer and get out of here! */ + freecookie(co); + return NULL; + } + + if(replace_old) { + co->next = clist->next; /* get the next-pointer first */ + + /* when replacing, creationtime is kept from old */ + co->creationtime = clist->creationtime; + + /* then free all the old pointers */ + free(clist->name); + free(clist->value); + free(clist->domain); + free(clist->path); + free(clist->spath); + free(clist->expirestr); + free(clist->version); + free(clist->maxage); + + *clist = *co; /* then store all the new data */ + + free(co); /* free the newly alloced memory */ + co = clist; /* point to the previous struct instead */ + + /* We have replaced a cookie, now skip the rest of the list but + make sure the 'lastc' pointer is properly set */ + do { + lastc = clist; + clist = clist->next; + } while(clist); + break; + } + } + lastc = clist; + clist = clist->next; + } + + if(c->running) + /* Only show this when NOT reading the cookies from a file */ + infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, " + "expire %" CURL_FORMAT_CURL_OFF_T "\n", + replace_old?"Replaced":"Added", co->name, co->value, + co->domain, co->path, co->expires); + + if(!replace_old) { + /* then make the last item point on this new one */ + if(lastc) + lastc->next = co; + else + c->cookies[myhash] = co; + c->numcookies++; /* one more cookie in the jar */ + } + + return co; +} + + +/***************************************************************************** + * + * Curl_cookie_init() + * + * Inits a cookie struct to read data from a local file. This is always + * called before any cookies are set. File may be NULL. + * + * If 'newsession' is TRUE, discard all "session cookies" on read from file. + * + * Returns NULL on out of memory. Invalid cookies are ignored. + ****************************************************************************/ +struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, + const char *file, + struct CookieInfo *inc, + bool newsession) +{ + struct CookieInfo *c; + FILE *fp = NULL; + bool fromfile = TRUE; + char *line = NULL; + + if(NULL == inc) { + /* we didn't get a struct, create one */ + c = calloc(1, sizeof(struct CookieInfo)); + if(!c) + return NULL; /* failed to get memory */ + c->filename = strdup(file?file:"none"); /* copy the name just in case */ + if(!c->filename) + goto fail; /* failed to get memory */ + } + else { + /* we got an already existing one, use that */ + c = inc; + } + c->running = FALSE; /* this is not running, this is init */ + + if(file && !strcmp(file, "-")) { + fp = stdin; + fromfile = FALSE; + } + else if(file && !*file) { + /* points to a "" string */ + fp = NULL; + } + else + fp = file?fopen(file, FOPEN_READTEXT):NULL; + + c->newsession = newsession; /* new session? */ + + if(fp) { + char *lineptr; + bool headerline; + + line = malloc(MAX_COOKIE_LINE); + if(!line) + goto fail; + while(Curl_get_line(line, MAX_COOKIE_LINE, fp)) { + if(checkprefix("Set-Cookie:", line)) { + /* This is a cookie line, get it! */ + lineptr = &line[11]; + headerline = TRUE; + } + else { + lineptr = line; + headerline = FALSE; + } + while(*lineptr && ISBLANK(*lineptr)) + lineptr++; + + Curl_cookie_add(data, c, headerline, TRUE, lineptr, NULL, NULL, TRUE); + } + free(line); /* free the line buffer */ + remove_expired(c); /* run this once, not on every cookie */ + + if(fromfile) + fclose(fp); + } + + c->running = TRUE; /* now, we're running */ + + return c; + +fail: + free(line); + if(!inc) + /* Only clean up if we allocated it here, as the original could still be in + * use by a share handle */ + Curl_cookie_cleanup(c); + if(fromfile && fp) + fclose(fp); + return NULL; /* out of memory */ +} + +/* sort this so that the longest path gets before the shorter path */ +static int cookie_sort(const void *p1, const void *p2) +{ + struct Cookie *c1 = *(struct Cookie **)p1; + struct Cookie *c2 = *(struct Cookie **)p2; + size_t l1, l2; + + /* 1 - compare cookie path lengths */ + l1 = c1->path ? strlen(c1->path) : 0; + l2 = c2->path ? strlen(c2->path) : 0; + + if(l1 != l2) + return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */ + + /* 2 - compare cookie domain lengths */ + l1 = c1->domain ? strlen(c1->domain) : 0; + l2 = c2->domain ? strlen(c2->domain) : 0; + + if(l1 != l2) + return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */ + + /* 3 - compare cookie name lengths */ + l1 = c1->name ? strlen(c1->name) : 0; + l2 = c2->name ? strlen(c2->name) : 0; + + if(l1 != l2) + return (l2 > l1) ? 1 : -1; + + /* 4 - compare cookie creation time */ + return (c2->creationtime > c1->creationtime) ? 1 : -1; +} + +/* sort cookies only according to creation time */ +static int cookie_sort_ct(const void *p1, const void *p2) +{ + struct Cookie *c1 = *(struct Cookie **)p1; + struct Cookie *c2 = *(struct Cookie **)p2; + + return (c2->creationtime > c1->creationtime) ? 1 : -1; +} + +#define CLONE(field) \ + do { \ + if(src->field) { \ + d->field = strdup(src->field); \ + if(!d->field) \ + goto fail; \ + } \ + } while(0) + +static struct Cookie *dup_cookie(struct Cookie *src) +{ + struct Cookie *d = calloc(sizeof(struct Cookie), 1); + if(d) { + CLONE(expirestr); + CLONE(domain); + CLONE(path); + CLONE(spath); + CLONE(name); + CLONE(value); + CLONE(maxage); + CLONE(version); + d->expires = src->expires; + d->tailmatch = src->tailmatch; + d->secure = src->secure; + d->livecookie = src->livecookie; + d->httponly = src->httponly; + d->creationtime = src->creationtime; + } + return d; + + fail: + freecookie(d); + return NULL; +} + +/***************************************************************************** + * + * Curl_cookie_getlist() + * + * For a given host and path, return a linked list of cookies that the + * client should send to the server if used now. The secure boolean informs + * the cookie if a secure connection is achieved or not. + * + * It shall only return cookies that haven't expired. + * + ****************************************************************************/ + +struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, + const char *host, const char *path, + bool secure) +{ + struct Cookie *newco; + struct Cookie *co; + struct Cookie *mainco = NULL; + size_t matches = 0; + bool is_ip; + const size_t myhash = cookiehash(host); + + if(!c || !c->cookies[myhash]) + return NULL; /* no cookie struct or no cookies in the struct */ + + /* at first, remove expired cookies */ + remove_expired(c); + + /* check if host is an IP(v4|v6) address */ + is_ip = isip(host); + + co = c->cookies[myhash]; + + while(co) { + /* if the cookie requires we're secure we must only continue if we are! */ + if(co->secure?secure:TRUE) { + + /* now check if the domain is correct */ + if(!co->domain || + (co->tailmatch && !is_ip && tailmatch(co->domain, host)) || + ((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) { + /* the right part of the host matches the domain stuff in the + cookie data */ + + /* now check the left part of the path with the cookies path + requirement */ + if(!co->spath || pathmatch(co->spath, path) ) { + + /* and now, we know this is a match and we should create an + entry for the return-linked-list */ + + newco = dup_cookie(co); + if(newco) { + /* then modify our next */ + newco->next = mainco; + + /* point the main to us */ + mainco = newco; + + matches++; + } + else + goto fail; + } + } + } + co = co->next; + } + + if(matches) { + /* Now we need to make sure that if there is a name appearing more than + once, the longest specified path version comes first. To make this + the swiftest way, we just sort them all based on path length. */ + struct Cookie **array; + size_t i; + + /* alloc an array and store all cookie pointers */ + array = malloc(sizeof(struct Cookie *) * matches); + if(!array) + goto fail; + + co = mainco; + + for(i = 0; co; co = co->next) + array[i++] = co; + + /* now sort the cookie pointers in path length order */ + qsort(array, matches, sizeof(struct Cookie *), cookie_sort); + + /* remake the linked list order according to the new order */ + + mainco = array[0]; /* start here */ + for(i = 0; inext = array[i + 1]; + array[matches-1]->next = NULL; /* terminate the list */ + + free(array); /* remove the temporary data again */ + } + + return mainco; /* return the new list */ + +fail: + /* failure, clear up the allocated chain and return NULL */ + Curl_cookie_freelist(mainco); + return NULL; +} + +/***************************************************************************** + * + * Curl_cookie_clearall() + * + * Clear all existing cookies and reset the counter. + * + ****************************************************************************/ +void Curl_cookie_clearall(struct CookieInfo *cookies) +{ + if(cookies) { + unsigned int i; + for(i = 0; i < COOKIE_HASH_SIZE; i++) { + Curl_cookie_freelist(cookies->cookies[i]); + cookies->cookies[i] = NULL; + } + cookies->numcookies = 0; + } +} + +/***************************************************************************** + * + * Curl_cookie_freelist() + * + * Free a list of cookies previously returned by Curl_cookie_getlist(); + * + ****************************************************************************/ + +void Curl_cookie_freelist(struct Cookie *co) +{ + struct Cookie *next; + while(co) { + next = co->next; + freecookie(co); + co = next; + } +} + + +/***************************************************************************** + * + * Curl_cookie_clearsess() + * + * Free all session cookies in the cookies list. + * + ****************************************************************************/ +void Curl_cookie_clearsess(struct CookieInfo *cookies) +{ + struct Cookie *first, *curr, *next, *prev = NULL; + unsigned int i; + + if(!cookies) + return; + + for(i = 0; i < COOKIE_HASH_SIZE; i++) { + if(!cookies->cookies[i]) + continue; + + first = curr = prev = cookies->cookies[i]; + + for(; curr; curr = next) { + next = curr->next; + if(!curr->expires) { + if(first == curr) + first = next; + + if(prev == curr) + prev = next; + else + prev->next = next; + + freecookie(curr); + cookies->numcookies--; + } + else + prev = curr; + } + + cookies->cookies[i] = first; + } +} + + +/***************************************************************************** + * + * Curl_cookie_cleanup() + * + * Free a "cookie object" previous created with Curl_cookie_init(). + * + ****************************************************************************/ +void Curl_cookie_cleanup(struct CookieInfo *c) +{ + if(c) { + unsigned int i; + free(c->filename); + for(i = 0; i < COOKIE_HASH_SIZE; i++) + Curl_cookie_freelist(c->cookies[i]); + free(c); /* free the base struct as well */ + } +} + +/* get_netscape_format() + * + * Formats a string for Netscape output file, w/o a newline at the end. + * + * Function returns a char * to a formatted line. Has to be free()d +*/ +static char *get_netscape_format(const struct Cookie *co) +{ + return aprintf( + "%s" /* httponly preamble */ + "%s%s\t" /* domain */ + "%s\t" /* tailmatch */ + "%s\t" /* path */ + "%s\t" /* secure */ + "%" CURL_FORMAT_CURL_OFF_T "\t" /* expires */ + "%s\t" /* name */ + "%s", /* value */ + co->httponly?"#HttpOnly_":"", + /* Make sure all domains are prefixed with a dot if they allow + tailmatching. This is Mozilla-style. */ + (co->tailmatch && co->domain && co->domain[0] != '.')? ".":"", + co->domain?co->domain:"unknown", + co->tailmatch?"TRUE":"FALSE", + co->path?co->path:"/", + co->secure?"TRUE":"FALSE", + co->expires, + co->name, + co->value?co->value:""); +} + +/* + * cookie_output() + * + * Writes all internally known cookies to the specified file. Specify + * "-" as file name to write to stdout. + * + * The function returns non-zero on write failure. + */ +static int cookie_output(struct CookieInfo *c, const char *dumphere) +{ + struct Cookie *co; + FILE *out; + bool use_stdout = FALSE; + + if(!c) + /* no cookie engine alive */ + return 0; + + /* at first, remove expired cookies */ + remove_expired(c); + + if(!strcmp("-", dumphere)) { + /* use stdout */ + out = stdout; + use_stdout = TRUE; + } + else { + out = fopen(dumphere, FOPEN_WRITETEXT); + if(!out) { + return 1; /* failure */ + } + } + + fputs("# Netscape HTTP Cookie File\n" + "# https://curl.haxx.se/docs/http-cookies.html\n" + "# This file was generated by libcurl! Edit at your own risk.\n\n", + out); + + if(c->numcookies) { + unsigned int i; + unsigned int j; + struct Cookie **array; + + array = malloc(sizeof(struct Cookie *) * c->numcookies); + if(!array) { + if(!use_stdout) + fclose(out); + return 1; + } + + j = 0; + for(i = 0; i < COOKIE_HASH_SIZE; i++) { + for(co = c->cookies[i]; co; co = co->next) { + if(!co->domain) + continue; + array[j++] = co; + } + } + + qsort(array, c->numcookies, sizeof(struct Cookie *), cookie_sort_ct); + + for(i = 0; i < j; i++) { + char *format_ptr = get_netscape_format(array[i]); + if(format_ptr == NULL) { + fprintf(out, "#\n# Fatal libcurl error\n"); + free(array); + if(!use_stdout) + fclose(out); + return 1; + } + fprintf(out, "%s\n", format_ptr); + free(format_ptr); + } + + free(array); + } + if(!use_stdout) + fclose(out); + + return 0; +} + +static struct curl_slist *cookie_list(struct Curl_easy *data) +{ + struct curl_slist *list = NULL; + struct curl_slist *beg; + struct Cookie *c; + char *line; + unsigned int i; + + if((data->cookies == NULL) || + (data->cookies->numcookies == 0)) + return NULL; + + for(i = 0; i < COOKIE_HASH_SIZE; i++) { + for(c = data->cookies->cookies[i]; c; c = c->next) { + if(!c->domain) + continue; + line = get_netscape_format(c); + if(!line) { + curl_slist_free_all(list); + return NULL; + } + beg = Curl_slist_append_nodup(list, line); + if(!beg) { + free(line); + curl_slist_free_all(list); + return NULL; + } + list = beg; + } + } + + return list; +} + +struct curl_slist *Curl_cookie_list(struct Curl_easy *data) +{ + struct curl_slist *list; + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + list = cookie_list(data); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + return list; +} + +void Curl_flush_cookies(struct Curl_easy *data, int cleanup) +{ + if(data->set.str[STRING_COOKIEJAR]) { + if(data->change.cookielist) { + /* If there is a list of cookie files to read, do it first so that + we have all the told files read before we write the new jar. + Curl_cookie_loadfiles() LOCKS and UNLOCKS the share itself! */ + Curl_cookie_loadfiles(data); + } + + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + + /* if we have a destination file for all the cookies to get dumped to */ + if(cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR])) + infof(data, "WARNING: failed to save cookies in %s\n", + data->set.str[STRING_COOKIEJAR]); + } + else { + if(cleanup && data->change.cookielist) { + /* since nothing is written, we can just free the list of cookie file + names */ + curl_slist_free_all(data->change.cookielist); /* clean up list */ + data->change.cookielist = NULL; + } + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + } + + if(cleanup && (!data->share || (data->cookies != data->share->cookies))) { + Curl_cookie_cleanup(data->cookies); + } + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); +} + +#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */ diff --git a/libcurl/lib/cookie.h b/libcurl/lib/cookie.h new file mode 100644 index 0000000..b2730cf --- /dev/null +++ b/libcurl/lib/cookie.h @@ -0,0 +1,120 @@ +#ifndef HEADER_CURL_COOKIE_H +#define HEADER_CURL_COOKIE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#include + +struct Cookie { + struct Cookie *next; /* next in the chain */ + char *name; /* = value */ + char *value; /* name = */ + char *path; /* path = which is in Set-Cookie: */ + char *spath; /* sanitized cookie path */ + char *domain; /* domain = */ + curl_off_t expires; /* expires = */ + char *expirestr; /* the plain text version */ + bool tailmatch; /* whether we do tail-matching of the domain name */ + + /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */ + char *version; /* Version = */ + char *maxage; /* Max-Age = */ + + bool secure; /* whether the 'secure' keyword was used */ + bool livecookie; /* updated from a server, not a stored file */ + bool httponly; /* true if the httponly directive is present */ + int creationtime; /* time when the cookie was written */ + unsigned char prefix; /* bitmap fields indicating which prefix are set */ +}; + +/* + * Available cookie prefixes, as defined in + * draft-ietf-httpbis-rfc6265bis-02 + */ +#define COOKIE_PREFIX__SECURE (1<<0) +#define COOKIE_PREFIX__HOST (1<<1) + +#define COOKIE_HASH_SIZE 256 + +struct CookieInfo { + /* linked list of cookies we know of */ + struct Cookie *cookies[COOKIE_HASH_SIZE]; + + char *filename; /* file we read from/write to */ + bool running; /* state info, for cookie adding information */ + long numcookies; /* number of cookies in the "jar" */ + bool newsession; /* new session, discard session cookies on load */ + int lastct; /* last creation-time used in the jar */ +}; + +/* This is the maximum line length we accept for a cookie line. RFC 2109 + section 6.3 says: + + "at least 4096 bytes per cookie (as measured by the size of the characters + that comprise the cookie non-terminal in the syntax description of the + Set-Cookie header)" + + We allow max 5000 bytes cookie header. Max 4095 bytes length per cookie + name and value. Name + value may not exceed 4096 bytes. + +*/ +#define MAX_COOKIE_LINE 5000 + +/* This is the maximum length of a cookie name or content we deal with: */ +#define MAX_NAME 4096 +#define MAX_NAME_TXT "4095" + +struct Curl_easy; +/* + * Add a cookie to the internal list of cookies. The domain and path arguments + * are only used if the header boolean is TRUE. + */ + +struct Cookie *Curl_cookie_add(struct Curl_easy *data, + struct CookieInfo *, bool header, bool noexpiry, + char *lineptr, + const char *domain, const char *path, + bool secure); + +struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *, + const char *, bool); +void Curl_cookie_freelist(struct Cookie *cookies); +void Curl_cookie_clearall(struct CookieInfo *cookies); +void Curl_cookie_clearsess(struct CookieInfo *cookies); + +#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES) +#define Curl_cookie_list(x) NULL +#define Curl_cookie_loadfiles(x) Curl_nop_stmt +#define Curl_cookie_init(x,y,z,w) NULL +#define Curl_cookie_cleanup(x) Curl_nop_stmt +#define Curl_flush_cookies(x,y) Curl_nop_stmt +#else +void Curl_flush_cookies(struct Curl_easy *data, int cleanup); +void Curl_cookie_cleanup(struct CookieInfo *); +struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, + const char *, struct CookieInfo *, bool); +struct curl_slist *Curl_cookie_list(struct Curl_easy *data); +void Curl_cookie_loadfiles(struct Curl_easy *data); +#endif + +#endif /* HEADER_CURL_COOKIE_H */ diff --git a/libcurl/lib/curl_addrinfo.c b/libcurl/lib/curl_addrinfo.c new file mode 100644 index 0000000..16c4779 --- /dev/null +++ b/libcurl/lib/curl_addrinfo.c @@ -0,0 +1,624 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_NETINET_IN6_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif + +#ifdef __VMS +# include +# include +#endif + +#if defined(NETWARE) && defined(__NOVELL_LIBC__) +# undef in_addr_t +# define in_addr_t unsigned long +#endif + +#if defined(WIN32) && defined(USE_UNIX_SOCKETS) +#include +#endif + +#include + +#include "curl_addrinfo.h" +#include "inet_pton.h" +#include "warnless.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Curl_freeaddrinfo() + * + * This is used to free a linked list of Curl_addrinfo structs along + * with all its associated allocated storage. This function should be + * called once for each successful call to Curl_getaddrinfo_ex() or to + * any function call which actually allocates a Curl_addrinfo struct. + */ + +#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \ + defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__) + /* workaround icc 9.1 optimizer issue */ +# define vqualifier volatile +#else +# define vqualifier +#endif + +void +Curl_freeaddrinfo(Curl_addrinfo *cahead) +{ + Curl_addrinfo *vqualifier canext; + Curl_addrinfo *ca; + + for(ca = cahead; ca != NULL; ca = canext) { + free(ca->ai_addr); + free(ca->ai_canonname); + canext = ca->ai_next; + + free(ca); + } +} + + +#ifdef HAVE_GETADDRINFO +/* + * Curl_getaddrinfo_ex() + * + * This is a wrapper function around system's getaddrinfo(), with + * the only difference that instead of returning a linked list of + * addrinfo structs this one returns a linked list of Curl_addrinfo + * ones. The memory allocated by this function *MUST* be free'd with + * Curl_freeaddrinfo(). For each successful call to this function + * there must be an associated call later to Curl_freeaddrinfo(). + * + * There should be no single call to system's getaddrinfo() in the + * whole library, any such call should be 'routed' through this one. + */ + +int +Curl_getaddrinfo_ex(const char *nodename, + const char *servname, + const struct addrinfo *hints, + Curl_addrinfo **result) +{ + const struct addrinfo *ai; + struct addrinfo *aihead; + Curl_addrinfo *cafirst = NULL; + Curl_addrinfo *calast = NULL; + Curl_addrinfo *ca; + size_t ss_size; + int error; + + *result = NULL; /* assume failure */ + + error = getaddrinfo(nodename, servname, hints, &aihead); + if(error) + return error; + + /* traverse the addrinfo list */ + + for(ai = aihead; ai != NULL; ai = ai->ai_next) { + + /* ignore elements with unsupported address family, */ + /* settle family-specific sockaddr structure size. */ + if(ai->ai_family == AF_INET) + ss_size = sizeof(struct sockaddr_in); +#ifdef ENABLE_IPV6 + else if(ai->ai_family == AF_INET6) + ss_size = sizeof(struct sockaddr_in6); +#endif + else + continue; + + /* ignore elements without required address info */ + if((ai->ai_addr == NULL) || !(ai->ai_addrlen > 0)) + continue; + + /* ignore elements with bogus address size */ + if((size_t)ai->ai_addrlen < ss_size) + continue; + + ca = malloc(sizeof(Curl_addrinfo)); + if(!ca) { + error = EAI_MEMORY; + break; + } + + /* copy each structure member individually, member ordering, */ + /* size, or padding might be different for each platform. */ + + ca->ai_flags = ai->ai_flags; + ca->ai_family = ai->ai_family; + ca->ai_socktype = ai->ai_socktype; + ca->ai_protocol = ai->ai_protocol; + ca->ai_addrlen = (curl_socklen_t)ss_size; + ca->ai_addr = NULL; + ca->ai_canonname = NULL; + ca->ai_next = NULL; + + ca->ai_addr = malloc(ss_size); + if(!ca->ai_addr) { + error = EAI_MEMORY; + free(ca); + break; + } + memcpy(ca->ai_addr, ai->ai_addr, ss_size); + + if(ai->ai_canonname != NULL) { + ca->ai_canonname = strdup(ai->ai_canonname); + if(!ca->ai_canonname) { + error = EAI_MEMORY; + free(ca->ai_addr); + free(ca); + break; + } + } + + /* if the return list is empty, this becomes the first element */ + if(!cafirst) + cafirst = ca; + + /* add this element last in the return list */ + if(calast) + calast->ai_next = ca; + calast = ca; + + } + + /* destroy the addrinfo list */ + if(aihead) + freeaddrinfo(aihead); + + /* if we failed, also destroy the Curl_addrinfo list */ + if(error) { + Curl_freeaddrinfo(cafirst); + cafirst = NULL; + } + else if(!cafirst) { +#ifdef EAI_NONAME + /* rfc3493 conformant */ + error = EAI_NONAME; +#else + /* rfc3493 obsoleted */ + error = EAI_NODATA; +#endif +#ifdef USE_WINSOCK + SET_SOCKERRNO(error); +#endif + } + + *result = cafirst; + + /* This is not a CURLcode */ + return error; +} +#endif /* HAVE_GETADDRINFO */ + + +/* + * Curl_he2ai() + * + * This function returns a pointer to the first element of a newly allocated + * Curl_addrinfo struct linked list filled with the data of a given hostent. + * Curl_addrinfo is meant to work like the addrinfo struct does for a IPv6 + * stack, but usable also for IPv4, all hosts and environments. + * + * The memory allocated by this function *MUST* be free'd later on calling + * Curl_freeaddrinfo(). For each successful call to this function there + * must be an associated call later to Curl_freeaddrinfo(). + * + * Curl_addrinfo defined in "lib/curl_addrinfo.h" + * + * struct Curl_addrinfo { + * int ai_flags; + * int ai_family; + * int ai_socktype; + * int ai_protocol; + * curl_socklen_t ai_addrlen; * Follow rfc3493 struct addrinfo * + * char *ai_canonname; + * struct sockaddr *ai_addr; + * struct Curl_addrinfo *ai_next; + * }; + * typedef struct Curl_addrinfo Curl_addrinfo; + * + * hostent defined in + * + * struct hostent { + * char *h_name; + * char **h_aliases; + * int h_addrtype; + * int h_length; + * char **h_addr_list; + * }; + * + * for backward compatibility: + * + * #define h_addr h_addr_list[0] + */ + +Curl_addrinfo * +Curl_he2ai(const struct hostent *he, int port) +{ + Curl_addrinfo *ai; + Curl_addrinfo *prevai = NULL; + Curl_addrinfo *firstai = NULL; + struct sockaddr_in *addr; +#ifdef ENABLE_IPV6 + struct sockaddr_in6 *addr6; +#endif + CURLcode result = CURLE_OK; + int i; + char *curr; + + if(!he) + /* no input == no output! */ + return NULL; + + DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL)); + + for(i = 0; (curr = he->h_addr_list[i]) != NULL; i++) { + + size_t ss_size; +#ifdef ENABLE_IPV6 + if(he->h_addrtype == AF_INET6) + ss_size = sizeof(struct sockaddr_in6); + else +#endif + ss_size = sizeof(struct sockaddr_in); + + ai = calloc(1, sizeof(Curl_addrinfo)); + if(!ai) { + result = CURLE_OUT_OF_MEMORY; + break; + } + ai->ai_canonname = strdup(he->h_name); + if(!ai->ai_canonname) { + result = CURLE_OUT_OF_MEMORY; + free(ai); + break; + } + ai->ai_addr = calloc(1, ss_size); + if(!ai->ai_addr) { + result = CURLE_OUT_OF_MEMORY; + free(ai->ai_canonname); + free(ai); + break; + } + + if(!firstai) + /* store the pointer we want to return from this function */ + firstai = ai; + + if(prevai) + /* make the previous entry point to this */ + prevai->ai_next = ai; + + ai->ai_family = he->h_addrtype; + + /* we return all names as STREAM, so when using this address for TFTP + the type must be ignored and conn->socktype be used instead! */ + ai->ai_socktype = SOCK_STREAM; + + ai->ai_addrlen = (curl_socklen_t)ss_size; + + /* leave the rest of the struct filled with zero */ + + switch(ai->ai_family) { + case AF_INET: + addr = (void *)ai->ai_addr; /* storage area for this info */ + + memcpy(&addr->sin_addr, curr, sizeof(struct in_addr)); + addr->sin_family = (CURL_SA_FAMILY_T)(he->h_addrtype); + addr->sin_port = htons((unsigned short)port); + break; + +#ifdef ENABLE_IPV6 + case AF_INET6: + addr6 = (void *)ai->ai_addr; /* storage area for this info */ + + memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr)); + addr6->sin6_family = (CURL_SA_FAMILY_T)(he->h_addrtype); + addr6->sin6_port = htons((unsigned short)port); + break; +#endif + } + + prevai = ai; + } + + if(result) { + Curl_freeaddrinfo(firstai); + firstai = NULL; + } + + return firstai; +} + + +struct namebuff { + struct hostent hostentry; + union { + struct in_addr ina4; +#ifdef ENABLE_IPV6 + struct in6_addr ina6; +#endif + } addrentry; + char *h_addr_list[2]; +}; + + +/* + * Curl_ip2addr() + * + * This function takes an internet address, in binary form, as input parameter + * along with its address family and the string version of the address, and it + * returns a Curl_addrinfo chain filled in correctly with information for the + * given address/host + */ + +Curl_addrinfo * +Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port) +{ + Curl_addrinfo *ai; + +#if defined(__VMS) && \ + defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64) +#pragma pointer_size save +#pragma pointer_size short +#pragma message disable PTRMISMATCH +#endif + + struct hostent *h; + struct namebuff *buf; + char *addrentry; + char *hoststr; + size_t addrsize; + + DEBUGASSERT(inaddr && hostname); + + buf = malloc(sizeof(struct namebuff)); + if(!buf) + return NULL; + + hoststr = strdup(hostname); + if(!hoststr) { + free(buf); + return NULL; + } + + switch(af) { + case AF_INET: + addrsize = sizeof(struct in_addr); + addrentry = (void *)&buf->addrentry.ina4; + memcpy(addrentry, inaddr, sizeof(struct in_addr)); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + addrsize = sizeof(struct in6_addr); + addrentry = (void *)&buf->addrentry.ina6; + memcpy(addrentry, inaddr, sizeof(struct in6_addr)); + break; +#endif + default: + free(hoststr); + free(buf); + return NULL; + } + + h = &buf->hostentry; + h->h_name = hoststr; + h->h_aliases = NULL; + h->h_addrtype = (short)af; + h->h_length = (short)addrsize; + h->h_addr_list = &buf->h_addr_list[0]; + h->h_addr_list[0] = addrentry; + h->h_addr_list[1] = NULL; /* terminate list of entries */ + +#if defined(__VMS) && \ + defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64) +#pragma pointer_size restore +#pragma message enable PTRMISMATCH +#endif + + ai = Curl_he2ai(h, port); + + free(hoststr); + free(buf); + + return ai; +} + +/* + * Given an IPv4 or IPv6 dotted string address, this converts it to a proper + * allocated Curl_addrinfo struct and returns it. + */ +Curl_addrinfo *Curl_str2addr(char *address, int port) +{ + struct in_addr in; + if(Curl_inet_pton(AF_INET, address, &in) > 0) + /* This is a dotted IP address 123.123.123.123-style */ + return Curl_ip2addr(AF_INET, &in, address, port); +#ifdef ENABLE_IPV6 + { + struct in6_addr in6; + if(Curl_inet_pton(AF_INET6, address, &in6) > 0) + /* This is a dotted IPv6 address ::1-style */ + return Curl_ip2addr(AF_INET6, &in6, address, port); + } +#endif + return NULL; /* bad input format */ +} + +#ifdef USE_UNIX_SOCKETS +/** + * Given a path to a Unix domain socket, return a newly allocated Curl_addrinfo + * struct initialized with this path. + * Set '*longpath' to TRUE if the error is a too long path. + */ +Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract) +{ + Curl_addrinfo *ai; + struct sockaddr_un *sa_un; + size_t path_len; + + *longpath = FALSE; + + ai = calloc(1, sizeof(Curl_addrinfo)); + if(!ai) + return NULL; + ai->ai_addr = calloc(1, sizeof(struct sockaddr_un)); + if(!ai->ai_addr) { + free(ai); + return NULL; + } + + sa_un = (void *) ai->ai_addr; + sa_un->sun_family = AF_UNIX; + + /* sun_path must be able to store the NUL-terminated path */ + path_len = strlen(path) + 1; + if(path_len > sizeof(sa_un->sun_path)) { + free(ai->ai_addr); + free(ai); + *longpath = TRUE; + return NULL; + } + + ai->ai_family = AF_UNIX; + ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */ + ai->ai_addrlen = (curl_socklen_t) + ((offsetof(struct sockaddr_un, sun_path) + path_len) & 0x7FFFFFFF); + + /* Abstract Unix domain socket have NULL prefix instead of suffix */ + if(abstract) + memcpy(sa_un->sun_path + 1, path, path_len - 1); + else + memcpy(sa_un->sun_path, path, path_len); /* copy NUL byte */ + + return ai; +} +#endif + +#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \ + defined(HAVE_FREEADDRINFO) +/* + * curl_dbg_freeaddrinfo() + * + * This is strictly for memory tracing and are using the same style as the + * family otherwise present in memdebug.c. I put these ones here since they + * require a bunch of structs I didn't want to include in memdebug.c + */ + +void +curl_dbg_freeaddrinfo(struct addrinfo *freethis, + int line, const char *source) +{ + curl_dbg_log("ADDR %s:%d freeaddrinfo(%p)\n", + source, line, (void *)freethis); +#ifdef USE_LWIPSOCK + lwip_freeaddrinfo(freethis); +#else + (freeaddrinfo)(freethis); +#endif +} +#endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */ + + +#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) +/* + * curl_dbg_getaddrinfo() + * + * This is strictly for memory tracing and are using the same style as the + * family otherwise present in memdebug.c. I put these ones here since they + * require a bunch of structs I didn't want to include in memdebug.c + */ + +int +curl_dbg_getaddrinfo(const char *hostname, + const char *service, + const struct addrinfo *hints, + struct addrinfo **result, + int line, const char *source) +{ +#ifdef USE_LWIPSOCK + int res = lwip_getaddrinfo(hostname, service, hints, result); +#else + int res = (getaddrinfo)(hostname, service, hints, result); +#endif + if(0 == res) + /* success */ + curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n", + source, line, (void *)*result); + else + curl_dbg_log("ADDR %s:%d getaddrinfo() failed\n", + source, line); + return res; +} +#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */ + +#if defined(HAVE_GETADDRINFO) && defined(USE_RESOLVE_ON_IPS) +/* + * Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and Mac OS X + * 10.11.5. + */ +void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port) +{ + Curl_addrinfo *ca; + struct sockaddr_in *addr; +#ifdef ENABLE_IPV6 + struct sockaddr_in6 *addr6; +#endif + for(ca = addrinfo; ca != NULL; ca = ca->ai_next) { + switch(ca->ai_family) { + case AF_INET: + addr = (void *)ca->ai_addr; /* storage area for this info */ + addr->sin_port = htons((unsigned short)port); + break; + +#ifdef ENABLE_IPV6 + case AF_INET6: + addr6 = (void *)ca->ai_addr; /* storage area for this info */ + addr6->sin6_port = htons((unsigned short)port); + break; +#endif + } + } +} +#endif diff --git a/libcurl/lib/curl_addrinfo.h b/libcurl/lib/curl_addrinfo.h new file mode 100644 index 0000000..c174504 --- /dev/null +++ b/libcurl/lib/curl_addrinfo.h @@ -0,0 +1,115 @@ +#ifndef HEADER_CURL_ADDRINFO_H +#define HEADER_CURL_ADDRINFO_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif + +#ifdef __VMS +# include +# include +# include +#endif + +// ADDED FOR XBOX + struct hostent { + char *h_name; + char **h_aliases; + int h_addrtype; + int h_length; + char **h_addr_list; + }; + +/* + * Curl_addrinfo is our internal struct definition that we use to allow + * consistent internal handling of this data. We use this even when the + * system provides an addrinfo structure definition. And we use this for + * all sorts of IPv4 and IPV6 builds. + */ + +struct Curl_addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + curl_socklen_t ai_addrlen; /* Follow rfc3493 struct addrinfo */ + char *ai_canonname; + struct sockaddr *ai_addr; + struct Curl_addrinfo *ai_next; +}; +typedef struct Curl_addrinfo Curl_addrinfo; + +void +Curl_freeaddrinfo(Curl_addrinfo *cahead); + +#ifdef HAVE_GETADDRINFO +int +Curl_getaddrinfo_ex(const char *nodename, + const char *servname, + const struct addrinfo *hints, + Curl_addrinfo **result); +#endif + +Curl_addrinfo * +Curl_he2ai(const struct hostent *he, int port); + +Curl_addrinfo * +Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port); + +Curl_addrinfo *Curl_str2addr(char *dotted, int port); + +#ifdef USE_UNIX_SOCKETS +Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract); +#endif + +#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \ + defined(HAVE_FREEADDRINFO) +void +curl_dbg_freeaddrinfo(struct addrinfo *freethis, int line, const char *source); +#endif + +#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) +int +curl_dbg_getaddrinfo(const char *hostname, const char *service, + const struct addrinfo *hints, struct addrinfo **result, + int line, const char *source); +#endif + +#ifdef HAVE_GETADDRINFO +#ifdef USE_RESOLVE_ON_IPS +void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port); +#else +#define Curl_addrinfo_set_port(x,y) +#endif +#endif + +#endif /* HEADER_CURL_ADDRINFO_H */ diff --git a/libcurl/lib/curl_base64.h b/libcurl/lib/curl_base64.h new file mode 100644 index 0000000..7e9fc26 --- /dev/null +++ b/libcurl/lib/curl_base64.h @@ -0,0 +1,35 @@ +#ifndef HEADER_CURL_BASE64_H +#define HEADER_CURL_BASE64_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +CURLcode Curl_base64_encode(struct Curl_easy *data, + const char *inputbuff, size_t insize, + char **outptr, size_t *outlen); +CURLcode Curl_base64url_encode(struct Curl_easy *data, + const char *inputbuff, size_t insize, + char **outptr, size_t *outlen); + +CURLcode Curl_base64_decode(const char *src, + unsigned char **outptr, size_t *outlen); + +#endif /* HEADER_CURL_BASE64_H */ diff --git a/libcurl/lib/curl_config.h.cmake b/libcurl/lib/curl_config.h.cmake new file mode 100644 index 0000000..5458cba --- /dev/null +++ b/libcurl/lib/curl_config.h.cmake @@ -0,0 +1,1026 @@ +/* lib/curl_config.h.in. Generated somehow by cmake. */ + +/* when building libcurl itself */ +#cmakedefine BUILDING_LIBCURL 1 + +/* Location of default ca bundle */ +#cmakedefine CURL_CA_BUNDLE "${CURL_CA_BUNDLE}" + +/* define "1" to use built-in ca store of TLS backend */ +#cmakedefine CURL_CA_FALLBACK 1 + +/* Location of default ca path */ +#cmakedefine CURL_CA_PATH "${CURL_CA_PATH}" + +/* to disable cookies support */ +#cmakedefine CURL_DISABLE_COOKIES 1 + +/* to disable cryptographic authentication */ +#cmakedefine CURL_DISABLE_CRYPTO_AUTH 1 + +/* to disable DICT */ +#cmakedefine CURL_DISABLE_DICT 1 + +/* to disable FILE */ +#cmakedefine CURL_DISABLE_FILE 1 + +/* to disable FTP */ +#cmakedefine CURL_DISABLE_FTP 1 + +/* to disable GOPHER */ +#cmakedefine CURL_DISABLE_GOPHER 1 + +/* to disable IMAP */ +#cmakedefine CURL_DISABLE_IMAP 1 + +/* to disable HTTP */ +#cmakedefine CURL_DISABLE_HTTP 1 + +/* to disable LDAP */ +#cmakedefine CURL_DISABLE_LDAP 1 + +/* to disable LDAPS */ +#cmakedefine CURL_DISABLE_LDAPS 1 + +/* to disable POP3 */ +#cmakedefine CURL_DISABLE_POP3 1 + +/* to disable proxies */ +#cmakedefine CURL_DISABLE_PROXY 1 + +/* to disable RTSP */ +#cmakedefine CURL_DISABLE_RTSP 1 + +/* to disable SMB */ +#cmakedefine CURL_DISABLE_SMB 1 + +/* to disable SMTP */ +#cmakedefine CURL_DISABLE_SMTP 1 + +/* to disable TELNET */ +#cmakedefine CURL_DISABLE_TELNET 1 + +/* to disable TFTP */ +#cmakedefine CURL_DISABLE_TFTP 1 + +/* to disable verbose strings */ +#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1 + +/* to make a symbol visible */ +#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL} +/* Ensure using CURL_EXTERN_SYMBOL is possible */ +#ifndef CURL_EXTERN_SYMBOL +#define CURL_EXTERN_SYMBOL +#endif + +/* Use Windows LDAP implementation */ +#cmakedefine USE_WIN32_LDAP 1 + +/* when not building a shared library */ +#cmakedefine CURL_STATICLIB 1 + +/* your Entropy Gathering Daemon socket pathname */ +#cmakedefine EGD_SOCKET ${EGD_SOCKET} + +/* Define if you want to enable IPv6 support */ +#cmakedefine ENABLE_IPV6 1 + +/* Define to the type qualifier of arg 1 for getnameinfo. */ +#cmakedefine GETNAMEINFO_QUAL_ARG1 ${GETNAMEINFO_QUAL_ARG1} + +/* Define to the type of arg 1 for getnameinfo. */ +#cmakedefine GETNAMEINFO_TYPE_ARG1 ${GETNAMEINFO_TYPE_ARG1} + +/* Define to the type of arg 2 for getnameinfo. */ +#cmakedefine GETNAMEINFO_TYPE_ARG2 ${GETNAMEINFO_TYPE_ARG2} + +/* Define to the type of args 4 and 6 for getnameinfo. */ +#cmakedefine GETNAMEINFO_TYPE_ARG46 ${GETNAMEINFO_TYPE_ARG46} + +/* Define to the type of arg 7 for getnameinfo. */ +#cmakedefine GETNAMEINFO_TYPE_ARG7 ${GETNAMEINFO_TYPE_ARG7} + +/* Specifies the number of arguments to getservbyport_r */ +#cmakedefine GETSERVBYPORT_R_ARGS ${GETSERVBYPORT_R_ARGS} + +/* Specifies the size of the buffer to pass to getservbyport_r */ +#cmakedefine GETSERVBYPORT_R_BUFSIZE ${GETSERVBYPORT_R_BUFSIZE} + +/* Define to 1 if you have the alarm function. */ +#cmakedefine HAVE_ALARM 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ARPA_TFTP_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ASSERT_H 1 + +/* Define to 1 if you have the `basename' function. */ +#cmakedefine HAVE_BASENAME 1 + +/* Define to 1 if bool is an available type. */ +#cmakedefine HAVE_BOOL_T 1 + +/* Define to 1 if you have the __builtin_available function. */ +#cmakedefine HAVE_BUILTIN_AVAILABLE 1 + +/* Define to 1 if you have the clock_gettime function and monotonic timer. */ +#cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC 1 + +/* Define to 1 if you have the `closesocket' function. */ +#cmakedefine HAVE_CLOSESOCKET 1 + +/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ +#cmakedefine HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_CRYPTO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ +#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ERR_H 1 + +/* Define to 1 if you have the fcntl function. */ +#cmakedefine HAVE_FCNTL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_FCNTL_H 1 + +/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ +#cmakedefine HAVE_FCNTL_O_NONBLOCK 1 + +/* Define to 1 if you have the fdopen function. */ +#cmakedefine HAVE_FDOPEN 1 + +/* Define to 1 if you have the `fork' function. */ +#cmakedefine HAVE_FORK 1 + +/* Define to 1 if you have the freeaddrinfo function. */ +#cmakedefine HAVE_FREEADDRINFO 1 + +/* Define to 1 if you have the freeifaddrs function. */ +#cmakedefine HAVE_FREEIFADDRS 1 + +/* Define to 1 if you have the ftruncate function. */ +#cmakedefine HAVE_FTRUNCATE 1 + +/* Define to 1 if you have a working getaddrinfo function. */ +#cmakedefine HAVE_GETADDRINFO 1 + +/* Define to 1 if you have the `geteuid' function. */ +#cmakedefine HAVE_GETEUID 1 + +/* Define to 1 if you have the gethostbyaddr function. */ +#cmakedefine HAVE_GETHOSTBYADDR 1 + +/* Define to 1 if you have the gethostbyaddr_r function. */ +#cmakedefine HAVE_GETHOSTBYADDR_R 1 + +/* gethostbyaddr_r() takes 5 args */ +#cmakedefine HAVE_GETHOSTBYADDR_R_5 1 + +/* gethostbyaddr_r() takes 7 args */ +#cmakedefine HAVE_GETHOSTBYADDR_R_7 1 + +/* gethostbyaddr_r() takes 8 args */ +#cmakedefine HAVE_GETHOSTBYADDR_R_8 1 + +/* Define to 1 if you have the gethostbyname function. */ +#cmakedefine HAVE_GETHOSTBYNAME 1 + +/* Define to 1 if you have the gethostbyname_r function. */ +#cmakedefine HAVE_GETHOSTBYNAME_R 1 + +/* gethostbyname_r() takes 3 args */ +#cmakedefine HAVE_GETHOSTBYNAME_R_3 1 + +/* gethostbyname_r() takes 5 args */ +#cmakedefine HAVE_GETHOSTBYNAME_R_5 1 + +/* gethostbyname_r() takes 6 args */ +#cmakedefine HAVE_GETHOSTBYNAME_R_6 1 + +/* Define to 1 if you have the gethostname function. */ +#cmakedefine HAVE_GETHOSTNAME 1 + +/* Define to 1 if you have a working getifaddrs function. */ +#cmakedefine HAVE_GETIFADDRS 1 + +/* Define to 1 if you have the getnameinfo function. */ +#cmakedefine HAVE_GETNAMEINFO 1 + +/* Define to 1 if you have the `getpass_r' function. */ +#cmakedefine HAVE_GETPASS_R 1 + +/* Define to 1 if you have the `getppid' function. */ +#cmakedefine HAVE_GETPPID 1 + +/* Define to 1 if you have the `getprotobyname' function. */ +#cmakedefine HAVE_GETPROTOBYNAME 1 + +/* Define to 1 if you have the `getpeername' function. */ +#cmakedefine HAVE_GETPEERNAME 1 + +/* Define to 1 if you have the `getsockname' function. */ +#cmakedefine HAVE_GETSOCKNAME 1 + +/* Define to 1 if you have the `if_nametoindex' function. */ +#cmakedefine HAVE_IF_NAMETOINDEX 1 + +/* Define to 1 if you have the `getpwuid' function. */ +#cmakedefine HAVE_GETPWUID 1 + +/* Define to 1 if you have the `getpwuid_r' function. */ +#cmakedefine HAVE_GETPWUID_R 1 + +/* Define to 1 if you have the `getrlimit' function. */ +#cmakedefine HAVE_GETRLIMIT 1 + +/* Define to 1 if you have the getservbyport_r function. */ +#cmakedefine HAVE_GETSERVBYPORT_R 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#cmakedefine HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have a working glibc-style strerror_r function. */ +#cmakedefine HAVE_GLIBC_STRERROR_R 1 + +/* Define to 1 if you have a working gmtime_r function. */ +#cmakedefine HAVE_GMTIME_R 1 + +/* if you have the gssapi libraries */ +#cmakedefine HAVE_GSSAPI 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GSSAPI_GSSAPI_GENERIC_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GSSAPI_GSSAPI_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GSSAPI_GSSAPI_KRB5_H 1 + +/* if you have the GNU gssapi libraries */ +#cmakedefine HAVE_GSSGNU 1 + +/* if you have the Heimdal gssapi libraries */ +#cmakedefine HAVE_GSSHEIMDAL 1 + +/* if you have the MIT gssapi libraries */ +#cmakedefine HAVE_GSSMIT 1 + +/* Define to 1 if you have the `idna_strerror' function. */ +#cmakedefine HAVE_IDNA_STRERROR 1 + +/* Define to 1 if you have the `idn_free' function. */ +#cmakedefine HAVE_IDN_FREE 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_IDN_FREE_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_IFADDRS_H 1 + +/* Define to 1 if you have the `inet_addr' function. */ +#cmakedefine HAVE_INET_ADDR 1 + +/* Define to 1 if you have the inet_ntoa_r function. */ +#cmakedefine HAVE_INET_NTOA_R 1 + +/* inet_ntoa_r() takes 2 args */ +#cmakedefine HAVE_INET_NTOA_R_2 1 + +/* inet_ntoa_r() takes 3 args */ +#cmakedefine HAVE_INET_NTOA_R_3 1 + +/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ +#cmakedefine HAVE_INET_NTOP 1 + +/* Define to 1 if you have a IPv6 capable working inet_pton function. */ +#cmakedefine HAVE_INET_PTON 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the ioctl function. */ +#cmakedefine HAVE_IOCTL 1 + +/* Define to 1 if you have the ioctlsocket function. */ +#cmakedefine HAVE_IOCTLSOCKET 1 + +/* Define to 1 if you have the IoctlSocket camel case function. */ +#cmakedefine HAVE_IOCTLSOCKET_CAMEL 1 + +/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. + */ +#cmakedefine HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1 + +/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ +#cmakedefine HAVE_IOCTLSOCKET_FIONBIO 1 + +/* Define to 1 if you have a working ioctl FIONBIO function. */ +#cmakedefine HAVE_IOCTL_FIONBIO 1 + +/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ +#cmakedefine HAVE_IOCTL_SIOCGIFADDR 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_IO_H 1 + +/* if you have the Kerberos4 libraries (including -ldes) */ +#cmakedefine HAVE_KRB4 1 + +/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ +#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_KRB_H 1 + +/* Define to 1 if you have the lber.h header file. */ +#cmakedefine HAVE_LBER_H 1 + +/* Define to 1 if you have the ldapssl.h header file. */ +#cmakedefine HAVE_LDAPSSL_H 1 + +/* Define to 1 if you have the ldap.h header file. */ +#cmakedefine HAVE_LDAP_H 1 + +/* Use LDAPS implementation */ +#cmakedefine HAVE_LDAP_SSL 1 + +/* Define to 1 if you have the ldap_ssl.h header file. */ +#cmakedefine HAVE_LDAP_SSL_H 1 + +/* Define to 1 if you have the `ldap_url_parse' function. */ +#cmakedefine HAVE_LDAP_URL_PARSE 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_LIBGEN_H 1 + +/* Define to 1 if you have the `idn' library (-lidn). */ +#cmakedefine HAVE_LIBIDN 1 + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +#cmakedefine HAVE_LIBRESOLV 1 + +/* Define to 1 if you have the `resolve' library (-lresolve). */ +#cmakedefine HAVE_LIBRESOLVE 1 + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#cmakedefine HAVE_LIBSOCKET 1 + +/* Define to 1 if you have the `ssh2' library (-lssh2). */ +#cmakedefine HAVE_LIBSSH2 1 + +/* Define to 1 if libssh2 provides `libssh2_version'. */ +#cmakedefine HAVE_LIBSSH2_VERSION 1 + +/* Define to 1 if libssh2 provides `libssh2_init'. */ +#cmakedefine HAVE_LIBSSH2_INIT 1 + +/* Define to 1 if libssh2 provides `libssh2_exit'. */ +#cmakedefine HAVE_LIBSSH2_EXIT 1 + +/* Define to 1 if libssh2 provides `libssh2_scp_send64'. */ +#cmakedefine HAVE_LIBSSH2_SCP_SEND64 1 + +/* Define to 1 if libssh2 provides `libssh2_session_handshake'. */ +#cmakedefine HAVE_LIBSSH2_SESSION_HANDSHAKE 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_LIBSSH2_H 1 + +/* Define to 1 if you have the `ssl' library (-lssl). */ +#cmakedefine HAVE_LIBSSL 1 + +/* if zlib is available */ +#cmakedefine HAVE_LIBZ 1 + +/* if brotli is available */ +#cmakedefine HAVE_BROTLI 1 + +/* if your compiler supports LL */ +#cmakedefine HAVE_LL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_LOCALE_H 1 + +/* Define to 1 if you have a working localtime_r function. */ +#cmakedefine HAVE_LOCALTIME_R 1 + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#cmakedefine HAVE_LONGLONG 1 + +/* Define to 1 if you have the malloc.h header file. */ +#cmakedefine HAVE_MALLOC_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H 1 + +/* Define to 1 if you have the MSG_NOSIGNAL flag. */ +#cmakedefine HAVE_MSG_NOSIGNAL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETDB_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NET_IF_H 1 + +/* Define to 1 if NI_WITHSCOPEID exists and works. */ +#cmakedefine HAVE_NI_WITHSCOPEID 1 + +/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE */ +#cmakedefine HAVE_OLD_GSSMIT 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_CRYPTO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_ENGINE_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_ERR_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_PEM_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_PKCS12_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_RSA_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_SSL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENSSL_X509_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_PEM_H 1 + +/* Define to 1 if you have the `perror' function. */ +#cmakedefine HAVE_PERROR 1 + +/* Define to 1 if you have the `pipe' function. */ +#cmakedefine HAVE_PIPE 1 + +/* Define to 1 if you have a working poll function. */ +#cmakedefine HAVE_POLL 1 + +/* If you have a fine poll */ +#cmakedefine HAVE_POLL_FINE 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_POLL_H 1 + +/* Define to 1 if you have a working POSIX-style strerror_r function. */ +#cmakedefine HAVE_POSIX_STRERROR_R 1 + +/* Define to 1 if you have the header file */ +#cmakedefine HAVE_PTHREAD_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_PWD_H 1 + +/* Define to 1 if you have the `RAND_egd' function. */ +#cmakedefine HAVE_RAND_EGD 1 + +/* Define to 1 if you have the `RAND_screen' function. */ +#cmakedefine HAVE_RAND_SCREEN 1 + +/* Define to 1 if you have the `RAND_status' function. */ +#cmakedefine HAVE_RAND_STATUS 1 + +/* Define to 1 if you have the recv function. */ +#cmakedefine HAVE_RECV 1 + +/* Define to 1 if you have the recvfrom function. */ +#cmakedefine HAVE_RECVFROM 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_RSA_H 1 + +/* Define to 1 if you have the select function. */ +#cmakedefine HAVE_SELECT 1 + +/* Define to 1 if you have the send function. */ +#cmakedefine HAVE_SEND 1 + +/* Define to 1 if you have the 'fsetxattr' function. */ +#cmakedefine HAVE_FSETXATTR 1 + +/* fsetxattr() takes 5 args */ +#cmakedefine HAVE_FSETXATTR_5 1 + +/* fsetxattr() takes 6 args */ +#cmakedefine HAVE_FSETXATTR_6 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SETJMP_H 1 + +/* Define to 1 if you have the `setlocale' function. */ +#cmakedefine HAVE_SETLOCALE 1 + +/* Define to 1 if you have the `setmode' function. */ +#cmakedefine HAVE_SETMODE 1 + +/* Define to 1 if you have the `setrlimit' function. */ +#cmakedefine HAVE_SETRLIMIT 1 + +/* Define to 1 if you have the setsockopt function. */ +#cmakedefine HAVE_SETSOCKOPT 1 + +/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ +#cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SGTTY_H 1 + +/* Define to 1 if you have the sigaction function. */ +#cmakedefine HAVE_SIGACTION 1 + +/* Define to 1 if you have the siginterrupt function. */ +#cmakedefine HAVE_SIGINTERRUPT 1 + +/* Define to 1 if you have the signal function. */ +#cmakedefine HAVE_SIGNAL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SIGNAL_H 1 + +/* Define to 1 if you have the sigsetjmp function or macro. */ +#cmakedefine HAVE_SIGSETJMP 1 + +/* Define to 1 if sig_atomic_t is an available typedef. */ +#cmakedefine HAVE_SIG_ATOMIC_T 1 + +/* Define to 1 if sig_atomic_t is already defined as volatile. */ +#cmakedefine HAVE_SIG_ATOMIC_T_VOLATILE 1 + +/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */ +#cmakedefine HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 + +/* Define to 1 if you have the `socket' function. */ +#cmakedefine HAVE_SOCKET 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SSL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H 1 + +/* Define to 1 if you have the strcasecmp function. */ +#cmakedefine HAVE_STRCASECMP 1 + +/* Define to 1 if you have the strcasestr function. */ +#cmakedefine HAVE_STRCASESTR 1 + +/* Define to 1 if you have the strcmpi function. */ +#cmakedefine HAVE_STRCMPI 1 + +/* Define to 1 if you have the strdup function. */ +#cmakedefine HAVE_STRDUP 1 + +/* Define to 1 if you have the strerror_r function. */ +#cmakedefine HAVE_STRERROR_R 1 + +/* Define to 1 if you have the stricmp function. */ +#cmakedefine HAVE_STRICMP 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H 1 + +/* Define to 1 if you have the strlcat function. */ +#cmakedefine HAVE_STRLCAT 1 + +/* Define to 1 if you have the `strlcpy' function. */ +#cmakedefine HAVE_STRLCPY 1 + +/* Define to 1 if you have the strncasecmp function. */ +#cmakedefine HAVE_STRNCASECMP 1 + +/* Define to 1 if you have the strncmpi function. */ +#cmakedefine HAVE_STRNCMPI 1 + +/* Define to 1 if you have the strnicmp function. */ +#cmakedefine HAVE_STRNICMP 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STROPTS_H 1 + +/* Define to 1 if you have the strstr function. */ +#cmakedefine HAVE_STRSTR 1 + +/* Define to 1 if you have the strtok_r function. */ +#cmakedefine HAVE_STRTOK_R 1 + +/* Define to 1 if you have the strtoll function. */ +#cmakedefine HAVE_STRTOLL 1 + +/* if struct sockaddr_storage is defined */ +#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE 1 + +/* Define to 1 if you have the timeval struct. */ +#cmakedefine HAVE_STRUCT_TIMEVAL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_FILIO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_POLL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SOCKIO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_UN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_UTIME_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TERMIOS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TERMIO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TLD_H 1 + +/* Define to 1 if you have the `tld_strerror' function. */ +#cmakedefine HAVE_TLD_STRERROR 1 + +/* Define to 1 if you have the `uname' function. */ +#cmakedefine HAVE_UNAME 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `utime' function. */ +#cmakedefine HAVE_UTIME 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UTIME_H 1 + +/* Define to 1 if compiler supports C99 variadic macro style. */ +#cmakedefine HAVE_VARIADIC_MACROS_C99 1 + +/* Define to 1 if compiler supports old gcc variadic macro style. */ +#cmakedefine HAVE_VARIADIC_MACROS_GCC 1 + +/* Define to 1 if you have the winber.h header file. */ +#cmakedefine HAVE_WINBER_H 1 + +/* Define to 1 if you have the windows.h header file. */ +#cmakedefine HAVE_WINDOWS_H 1 + +/* Define to 1 if you have the winldap.h header file. */ +#cmakedefine HAVE_WINLDAP_H 1 + +/* Define to 1 if you have the winsock2.h header file. */ +#cmakedefine HAVE_WINSOCK2_H 1 + +/* Define to 1 if you have the winsock.h header file. */ +#cmakedefine HAVE_WINSOCK_H 1 + +/* Define this symbol if your OS supports changing the contents of argv */ +#cmakedefine HAVE_WRITABLE_ARGV 1 + +/* Define to 1 if you have the writev function. */ +#cmakedefine HAVE_WRITEV 1 + +/* Define to 1 if you have the ws2tcpip.h header file. */ +#cmakedefine HAVE_WS2TCPIP_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_X509_H 1 + +/* Define if you have the header file. */ +#cmakedefine HAVE_PROCESS_H 1 + +/* if you have the zlib.h header file */ +#cmakedefine HAVE_ZLIB_H 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#cmakedefine LT_OBJDIR ${LT_OBJDIR} + +/* If you lack a fine basename() prototype */ +#cmakedefine NEED_BASENAME_PROTO 1 + +/* Define to 1 if you need the lber.h header file even with ldap.h */ +#cmakedefine NEED_LBER_H 1 + +/* Define to 1 if you need the malloc.h header file even with stdlib.h */ +#cmakedefine NEED_MALLOC_H 1 + +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ +#cmakedefine NEED_REENTRANT 1 + +/* cpu-machine-OS */ +#cmakedefine OS ${OS} + +/* Name of package */ +#cmakedefine PACKAGE ${PACKAGE} + +/* Define to the address where bug reports for this package should be sent. */ +#cmakedefine PACKAGE_BUGREPORT ${PACKAGE_BUGREPORT} + +/* Define to the full name of this package. */ +#cmakedefine PACKAGE_NAME ${PACKAGE_NAME} + +/* Define to the full name and version of this package. */ +#cmakedefine PACKAGE_STRING ${PACKAGE_STRING} + +/* Define to the one symbol short name of this package. */ +#cmakedefine PACKAGE_TARNAME ${PACKAGE_TARNAME} + +/* Define to the version of this package. */ +#cmakedefine PACKAGE_VERSION ${PACKAGE_VERSION} + +/* a suitable file to read random data from */ +#cmakedefine RANDOM_FILE "${RANDOM_FILE}" + +/* Define to the type of arg 1 for recvfrom. */ +#cmakedefine RECVFROM_TYPE_ARG1 ${RECVFROM_TYPE_ARG1} + +/* Define to the type pointed by arg 2 for recvfrom. */ +#cmakedefine RECVFROM_TYPE_ARG2 ${RECVFROM_TYPE_ARG2} + +/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ +#cmakedefine RECVFROM_TYPE_ARG2_IS_VOID 1 + +/* Define to the type of arg 3 for recvfrom. */ +#cmakedefine RECVFROM_TYPE_ARG3 ${RECVFROM_TYPE_ARG3} + +/* Define to the type of arg 4 for recvfrom. */ +#cmakedefine RECVFROM_TYPE_ARG4 ${RECVFROM_TYPE_ARG4} + +/* Define to the type pointed by arg 5 for recvfrom. */ +#cmakedefine RECVFROM_TYPE_ARG5 ${RECVFROM_TYPE_ARG5} + +/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ +#cmakedefine RECVFROM_TYPE_ARG5_IS_VOID 1 + +/* Define to the type pointed by arg 6 for recvfrom. */ +#cmakedefine RECVFROM_TYPE_ARG6 ${RECVFROM_TYPE_ARG6} + +/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ +#cmakedefine RECVFROM_TYPE_ARG6_IS_VOID 1 + +/* Define to the function return type for recvfrom. */ +#cmakedefine RECVFROM_TYPE_RETV ${RECVFROM_TYPE_RETV} + +/* Define to the type of arg 1 for recv. */ +#cmakedefine RECV_TYPE_ARG1 ${RECV_TYPE_ARG1} + +/* Define to the type of arg 2 for recv. */ +#cmakedefine RECV_TYPE_ARG2 ${RECV_TYPE_ARG2} + +/* Define to the type of arg 3 for recv. */ +#cmakedefine RECV_TYPE_ARG3 ${RECV_TYPE_ARG3} + +/* Define to the type of arg 4 for recv. */ +#cmakedefine RECV_TYPE_ARG4 ${RECV_TYPE_ARG4} + +/* Define to the function return type for recv. */ +#cmakedefine RECV_TYPE_RETV ${RECV_TYPE_RETV} + +/* Define as the return type of signal handlers (`int' or `void'). */ +#cmakedefine RETSIGTYPE ${RETSIGTYPE} + +/* Define to the type qualifier of arg 5 for select. */ +#cmakedefine SELECT_QUAL_ARG5 ${SELECT_QUAL_ARG5} + +/* Define to the type of arg 1 for select. */ +#cmakedefine SELECT_TYPE_ARG1 ${SELECT_TYPE_ARG1} + +/* Define to the type of args 2, 3 and 4 for select. */ +#cmakedefine SELECT_TYPE_ARG234 ${SELECT_TYPE_ARG234} + +/* Define to the type of arg 5 for select. */ +#cmakedefine SELECT_TYPE_ARG5 ${SELECT_TYPE_ARG5} + +/* Define to the function return type for select. */ +#cmakedefine SELECT_TYPE_RETV ${SELECT_TYPE_RETV} + +/* Define to the type qualifier of arg 2 for send. */ +#cmakedefine SEND_QUAL_ARG2 ${SEND_QUAL_ARG2} + +/* Define to the type of arg 1 for send. */ +#cmakedefine SEND_TYPE_ARG1 ${SEND_TYPE_ARG1} + +/* Define to the type of arg 2 for send. */ +#cmakedefine SEND_TYPE_ARG2 ${SEND_TYPE_ARG2} + +/* Define to the type of arg 3 for send. */ +#cmakedefine SEND_TYPE_ARG3 ${SEND_TYPE_ARG3} + +/* Define to the type of arg 4 for send. */ +#cmakedefine SEND_TYPE_ARG4 ${SEND_TYPE_ARG4} + +/* Define to the function return type for send. */ +#cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV} + +/* + Note: SIZEOF_* variables are fetched with CMake through check_type_size(). + As per CMake documentation on CheckTypeSize, C preprocessor code is + generated by CMake into SIZEOF_*_CODE. This is what we use in the + following statements. + + Reference: https://cmake.org/cmake/help/latest/module/CheckTypeSize.html +*/ + +/* The size of `int', as computed by sizeof. */ +${SIZEOF_INT_CODE} + +/* The size of `short', as computed by sizeof. */ +${SIZEOF_SHORT_CODE} + +/* The size of `long', as computed by sizeof. */ +${SIZEOF_LONG_CODE} + +/* The size of `off_t', as computed by sizeof. */ +${SIZEOF_OFF_T_CODE} + +/* The size of `curl_off_t', as computed by sizeof. */ +${SIZEOF_CURL_OFF_T_CODE} + +/* The size of `size_t', as computed by sizeof. */ +${SIZEOF_SIZE_T_CODE} + +/* The size of `time_t', as computed by sizeof. */ +${SIZEOF_TIME_T_CODE} + +/* Define to 1 if you have the ANSI C header files. */ +#cmakedefine STDC_HEADERS 1 + +/* Define to the type of arg 3 for strerror_r. */ +#cmakedefine STRERROR_R_TYPE_ARG3 ${STRERROR_R_TYPE_ARG3} + +/* Define to 1 if you can safely include both and . */ +#cmakedefine TIME_WITH_SYS_TIME 1 + +/* Define if you want to enable c-ares support */ +#cmakedefine USE_ARES 1 + +/* Define if you want to enable POSIX threaded DNS lookup */ +#cmakedefine USE_THREADS_POSIX 1 + +/* Define if you want to enable WIN32 threaded DNS lookup */ +#cmakedefine USE_THREADS_WIN32 1 + +/* Define to disable non-blocking sockets. */ +#cmakedefine USE_BLOCKING_SOCKETS 1 + +/* if GnuTLS is enabled */ +#cmakedefine USE_GNUTLS 1 + +/* if PolarSSL is enabled */ +#cmakedefine USE_POLARSSL 1 + +/* if Secure Transport is enabled */ +#cmakedefine USE_SECTRANSP 1 + +/* if mbedTLS is enabled */ +#cmakedefine USE_MBEDTLS 1 + +/* if libSSH2 is in use */ +#cmakedefine USE_LIBSSH2 1 + +/* If you want to build curl with the built-in manual */ +#cmakedefine USE_MANUAL 1 + +/* if NSS is enabled */ +#cmakedefine USE_NSS 1 + +/* if you want to use OpenLDAP code instead of legacy ldap implementation */ +#cmakedefine USE_OPENLDAP 1 + +/* if OpenSSL is in use */ +#cmakedefine USE_OPENSSL 1 + +/* to enable NGHTTP2 */ +#cmakedefine USE_NGHTTP2 1 + +/* if Unix domain sockets are enabled */ +#cmakedefine USE_UNIX_SOCKETS + +/* Define to 1 if you are building a Windows target with large file support. */ +#cmakedefine USE_WIN32_LARGE_FILES 1 + +/* to enable SSPI support */ +#cmakedefine USE_WINDOWS_SSPI 1 + +/* to enable Windows SSL */ +#cmakedefine USE_SCHANNEL 1 + +/* enable multiple SSL backends */ +#cmakedefine CURL_WITH_MULTI_SSL 1 + +/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */ +#cmakedefine USE_YASSLEMUL 1 + +/* Version number of package */ +#cmakedefine VERSION ${VERSION} + +/* Define to 1 if OS is AIX. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS} + +/* Define for large files, on AIX-style hosts. */ +#cmakedefine _LARGE_FILES ${_LARGE_FILES} + +/* define this if you need it to compile thread-safe code */ +#cmakedefine _THREAD_SAFE ${_THREAD_SAFE} + +/* Define to empty if `const' does not conform to ANSI C. */ +#cmakedefine const ${const} + +/* Type to use in place of in_addr_t when system does not provide it. */ +#cmakedefine in_addr_t ${in_addr_t} + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `unsigned int' if does not define. */ +#cmakedefine size_t ${size_t} + +/* the signed version of size_t */ +#cmakedefine ssize_t ${ssize_t} + +/* Define to 1 if you have the mach_absolute_time function. */ +#cmakedefine HAVE_MACH_ABSOLUTE_TIME 1 diff --git a/libcurl/lib/curl_config.h.in b/libcurl/lib/curl_config.h.in new file mode 100644 index 0000000..871c664 --- /dev/null +++ b/libcurl/lib/curl_config.h.in @@ -0,0 +1,1058 @@ +/* lib/curl_config.h.in. Generated from configure.ac by autoheader. */ + +/* to enable curl debug memory tracking */ +#undef CURLDEBUG + +/* Location of default ca bundle */ +#undef CURL_CA_BUNDLE + +/* define "1" to use built in CA store of SSL library */ +#undef CURL_CA_FALLBACK + +/* Location of default ca path */ +#undef CURL_CA_PATH + +/* Default SSL backend */ +#undef CURL_DEFAULT_SSL_BACKEND + +/* to disable cookies support */ +#undef CURL_DISABLE_COOKIES + +/* to disable cryptographic authentication */ +#undef CURL_DISABLE_CRYPTO_AUTH + +/* to disable DICT */ +#undef CURL_DISABLE_DICT + +/* disable DoH */ +#undef CURL_DISABLE_DOH + +/* to disable FILE */ +#undef CURL_DISABLE_FILE + +/* to disable FTP */ +#undef CURL_DISABLE_FTP + +/* to disable Gopher */ +#undef CURL_DISABLE_GOPHER + +/* to disable HTTP */ +#undef CURL_DISABLE_HTTP + +/* disable HTTP authentication */ +#undef CURL_DISABLE_HTTP_AUTH + +/* to disable IMAP */ +#undef CURL_DISABLE_IMAP + +/* to disable LDAP */ +#undef CURL_DISABLE_LDAP + +/* to disable LDAPS */ +#undef CURL_DISABLE_LDAPS + +/* to disable --libcurl C code generation option */ +#undef CURL_DISABLE_LIBCURL_OPTION + +/* disable mime API */ +#undef CURL_DISABLE_MIME + +/* disable netrc parsing */ +#undef CURL_DISABLE_NETRC + +/* if the OpenSSL configuration won't be loaded automatically */ +#undef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG + +/* disable date parsing */ +#undef CURL_DISABLE_PARSEDATE + +/* to disable POP3 */ +#undef CURL_DISABLE_POP3 + +/* disable progress-meter */ +#undef CURL_DISABLE_PROGRESS_METER + +/* to disable proxies */ +#undef CURL_DISABLE_PROXY + +/* to disable RTSP */ +#undef CURL_DISABLE_RTSP + +/* disable DNS shuffling */ +#undef CURL_DISABLE_SHUFFLE_DNS + +/* to disable SMB/CIFS */ +#undef CURL_DISABLE_SMB + +/* to disable SMTP */ +#undef CURL_DISABLE_SMTP + +/* to disable TELNET */ +#undef CURL_DISABLE_TELNET + +/* to disable TFTP */ +#undef CURL_DISABLE_TFTP + +/* to disable verbose strings */ +#undef CURL_DISABLE_VERBOSE_STRINGS + +/* Definition to make a library symbol externally visible. */ +#undef CURL_EXTERN_SYMBOL + +/* IP address type in sockaddr */ +#undef CURL_SA_FAMILY_T + +/* built with multiple SSL backends */ +#undef CURL_WITH_MULTI_SSL + +/* enable debug build options */ +#undef DEBUGBUILD + +/* your Entropy Gathering Daemon socket pathname */ +#undef EGD_SOCKET + +/* Define if you want to enable IPv6 support */ +#undef ENABLE_IPV6 + +/* Define to the type of arg 2 for gethostname. */ +#undef GETHOSTNAME_TYPE_ARG2 + +/* Specifies the number of arguments to getservbyport_r */ +#undef GETSERVBYPORT_R_ARGS + +/* Specifies the size of the buffer to pass to getservbyport_r */ +#undef GETSERVBYPORT_R_BUFSIZE + +/* Define to 1 if you have the alarm function. */ +#undef HAVE_ALARM + +/* Define to 1 if you have the header file. */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_TFTP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ASSERT_H + +/* Define to 1 if you have the basename function. */ +#undef HAVE_BASENAME + +/* Define to 1 if bool is an available type. */ +#undef HAVE_BOOL_T + +/* Define to 1 if using BoringSSL. */ +#undef HAVE_BORINGSSL + +/* if BROTLI is in use */ +#undef HAVE_BROTLI + +/* Define to 1 if you have the header file. */ +#undef HAVE_BROTLI_DECODE_H + +/* Define to 1 if you have the __builtin_available function. */ +#undef HAVE_BUILTIN_AVAILABLE + +/* Define to 1 if you have the clock_gettime function and monotonic timer. */ +#undef HAVE_CLOCK_GETTIME_MONOTONIC + +/* Define to 1 if you have the closesocket function. */ +#undef HAVE_CLOSESOCKET + +/* Define to 1 if you have the CloseSocket camel case function. */ +#undef HAVE_CLOSESOCKET_CAMEL + +/* Define to 1 if you have the connect function. */ +#undef HAVE_CONNECT + +/* Define to 1 if you have the header file. */ +#undef HAVE_CRYPTO_H + +/* Define to 1 if you have the declaration of `getpwuid_r', and to 0 if you + don't. */ +#undef HAVE_DECL_GETPWUID_R + +/* "Set if getpwuid_r() declaration is missing" */ +#undef HAVE_DECL_GETPWUID_R_MISSING + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERR_H + +/* Define to 1 if you have the fcntl function. */ +#undef HAVE_FCNTL + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ +#undef HAVE_FCNTL_O_NONBLOCK + +/* Define to 1 if you have the `fnmatch' function. */ +#undef HAVE_FNMATCH + +/* Define to 1 if you have the freeaddrinfo function. */ +#undef HAVE_FREEADDRINFO + +/* Define to 1 if you have the freeifaddrs function. */ +#undef HAVE_FREEIFADDRS + +/* Define to 1 if you have the fsetxattr function. */ +#undef HAVE_FSETXATTR + +/* fsetxattr() takes 5 args */ +#undef HAVE_FSETXATTR_5 + +/* fsetxattr() takes 6 args */ +#undef HAVE_FSETXATTR_6 + +/* Define to 1 if you have the ftruncate function. */ +#undef HAVE_FTRUNCATE + +/* Define to 1 if you have the gai_strerror function. */ +#undef HAVE_GAI_STRERROR + +/* Define to 1 if you have a working getaddrinfo function. */ +#undef HAVE_GETADDRINFO + +/* Define to 1 if the getaddrinfo function is threadsafe. */ +#undef HAVE_GETADDRINFO_THREADSAFE + +/* Define to 1 if you have the `geteuid' function. */ +#undef HAVE_GETEUID + +/* Define to 1 if you have the gethostbyaddr function. */ +#undef HAVE_GETHOSTBYADDR + +/* Define to 1 if you have the gethostbyaddr_r function. */ +#undef HAVE_GETHOSTBYADDR_R + +/* gethostbyaddr_r() takes 5 args */ +#undef HAVE_GETHOSTBYADDR_R_5 + +/* gethostbyaddr_r() takes 7 args */ +#undef HAVE_GETHOSTBYADDR_R_7 + +/* gethostbyaddr_r() takes 8 args */ +#undef HAVE_GETHOSTBYADDR_R_8 + +/* Define to 1 if you have the gethostbyname function. */ +#undef HAVE_GETHOSTBYNAME + +/* Define to 1 if you have the gethostbyname_r function. */ +#undef HAVE_GETHOSTBYNAME_R + +/* gethostbyname_r() takes 3 args */ +#undef HAVE_GETHOSTBYNAME_R_3 + +/* gethostbyname_r() takes 5 args */ +#undef HAVE_GETHOSTBYNAME_R_5 + +/* gethostbyname_r() takes 6 args */ +#undef HAVE_GETHOSTBYNAME_R_6 + +/* Define to 1 if you have the gethostname function. */ +#undef HAVE_GETHOSTNAME + +/* Define to 1 if you have a working getifaddrs function. */ +#undef HAVE_GETIFADDRS + +/* Define to 1 if you have the `getpass_r' function. */ +#undef HAVE_GETPASS_R + +/* Define to 1 if you have the getpeername function. */ +#undef HAVE_GETPEERNAME + +/* Define to 1 if you have the `getppid' function. */ +#undef HAVE_GETPPID + +/* Define to 1 if you have the `getpwuid' function. */ +#undef HAVE_GETPWUID + +/* Define to 1 if you have the `getpwuid_r' function. */ +#undef HAVE_GETPWUID_R + +/* Define to 1 if you have the `getrlimit' function. */ +#undef HAVE_GETRLIMIT + +/* Define to 1 if you have the getservbyport_r function. */ +#undef HAVE_GETSERVBYPORT_R + +/* Define to 1 if you have the getsockname function. */ +#undef HAVE_GETSOCKNAME + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have a working glibc-style strerror_r function. */ +#undef HAVE_GLIBC_STRERROR_R + +/* Define to 1 if you have a working gmtime_r function. */ +#undef HAVE_GMTIME_R + +/* Define to 1 if you have the `gnutls_alpn_set_protocols' function. */ +#undef HAVE_GNUTLS_ALPN_SET_PROTOCOLS + +/* Define to 1 if you have the `gnutls_certificate_set_x509_key_file2' + function. */ +#undef HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 + +/* Define to 1 if you have the `gnutls_ocsp_req_init' function. */ +#undef HAVE_GNUTLS_OCSP_REQ_INIT + +/* if you have the function gnutls_srp_verifier */ +#undef HAVE_GNUTLS_SRP + +/* if you have GSS-API libraries */ +#undef HAVE_GSSAPI + +/* Define to 1 if you have the header file. */ +#undef HAVE_GSSAPI_GSSAPI_GENERIC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GSSAPI_GSSAPI_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GSSAPI_GSSAPI_KRB5_H + +/* if you have GNU GSS */ +#undef HAVE_GSSGNU + +/* if you have Heimdal */ +#undef HAVE_GSSHEIMDAL + +/* if you have MIT Kerberos */ +#undef HAVE_GSSMIT + +/* Define to 1 if you have the header file. */ +#undef HAVE_IDN2_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_IFADDRS_H + +/* Define to 1 if you have the `if_nametoindex' function. */ +#undef HAVE_IF_NAMETOINDEX + +/* Define to 1 if you have the inet_ntoa_r function. */ +#undef HAVE_INET_NTOA_R + +/* inet_ntoa_r() takes 2 args */ +#undef HAVE_INET_NTOA_R_2 + +/* inet_ntoa_r() takes 3 args */ +#undef HAVE_INET_NTOA_R_3 + +/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ +#undef HAVE_INET_NTOP + +/* Define to 1 if you have a IPv6 capable working inet_pton function. */ +#undef HAVE_INET_PTON + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the ioctl function. */ +#undef HAVE_IOCTL + +/* Define to 1 if you have the ioctlsocket function. */ +#undef HAVE_IOCTLSOCKET + +/* Define to 1 if you have the IoctlSocket camel case function. */ +#undef HAVE_IOCTLSOCKET_CAMEL + +/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. + */ +#undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO + +/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ +#undef HAVE_IOCTLSOCKET_FIONBIO + +/* Define to 1 if you have a working ioctl FIONBIO function. */ +#undef HAVE_IOCTL_FIONBIO + +/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ +#undef HAVE_IOCTL_SIOCGIFADDR + +/* Define to 1 if you have the header file. */ +#undef HAVE_IO_H + +/* Define to 1 if you have the lber.h header file. */ +#undef HAVE_LBER_H + +/* Define to 1 if you have the ldapssl.h header file. */ +#undef HAVE_LDAPSSL_H + +/* Define to 1 if you have the ldap.h header file. */ +#undef HAVE_LDAP_H + +/* Define to 1 if you have the `ldap_init_fd' function. */ +#undef HAVE_LDAP_INIT_FD + +/* Use LDAPS implementation */ +#undef HAVE_LDAP_SSL + +/* Define to 1 if you have the ldap_ssl.h header file. */ +#undef HAVE_LDAP_SSL_H + +/* Define to 1 if you have the `ldap_url_parse' function. */ +#undef HAVE_LDAP_URL_PARSE + +/* Define to 1 if you have the `brotlidec' library (-lbrotlidec). */ +#undef HAVE_LIBBROTLIDEC + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBGEN_H + +/* Define to 1 if you have the `idn2' library (-lidn2). */ +#undef HAVE_LIBIDN2 + +/* Define to 1 if using libressl. */ +#undef HAVE_LIBRESSL + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBRTMP_RTMP_H + +/* Define to 1 if you have the `ssh' library (-lssh). */ +#undef HAVE_LIBSSH + +/* Define to 1 if you have the `ssh2' library (-lssh2). */ +#undef HAVE_LIBSSH2 + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBSSH2_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBSSH_LIBSSH_H + +/* Define to 1 if you have the `ssl' library (-lssl). */ +#undef HAVE_LIBSSL + +/* if zlib is available */ +#undef HAVE_LIBZ + +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_TCP_H + +/* if your compiler supports LL */ +#undef HAVE_LL + +/* Define to 1 if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define to 1 if you have a working localtime_r function. */ +#undef HAVE_LOCALTIME_R + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#undef HAVE_LONGLONG + +/* Define to 1 if you have the `mach_absolute_time' function. */ +#undef HAVE_MACH_ABSOLUTE_TIME + +/* Define to 1 if you have the malloc.h header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the memory.h header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the memrchr function or macro. */ +#undef HAVE_MEMRCHR + +/* Define to 1 if you have the MSG_NOSIGNAL flag. */ +#undef HAVE_MSG_NOSIGNAL + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN6_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_TCP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_IF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NGHTTP2_NGHTTP2_H + +/* if you have an old MIT Kerberos version, lacking GSS_C_NT_HOSTBASED_SERVICE + */ +#undef HAVE_OLD_GSSMIT + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_CRYPTO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_ERR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_PEM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_RSA_H + +/* if you have the function SRP_Calc_client_key */ +#undef HAVE_OPENSSL_SRP + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_SSL_H + +/* Define to 1 if you have the `OpenSSL_version' function. */ +#undef HAVE_OPENSSL_VERSION + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_X509_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_PEM_H + +/* Define to 1 if you have the `pipe' function. */ +#undef HAVE_PIPE + +/* if you have the PK11_CreateManagedGenericObject function */ +#undef HAVE_PK11_CREATEMANAGEDGENERICOBJECT + +/* Define to 1 if you have a working poll function. */ +#undef HAVE_POLL + +/* If you have a fine poll */ +#undef HAVE_POLL_FINE + +/* Define to 1 if you have the header file. */ +#undef HAVE_POLL_H + +/* Define to 1 if you have a working POSIX-style strerror_r function. */ +#undef HAVE_POSIX_STRERROR_R + +/* Define to 1 if you have the header file. */ +#undef HAVE_PROTO_BSDSOCKET_H + +/* if you have */ +#undef HAVE_PTHREAD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_PWD_H + +/* Define to 1 if you have the `RAND_egd' function. */ +#undef HAVE_RAND_EGD + +/* Define to 1 if you have the recv function. */ +#undef HAVE_RECV + +/* Define to 1 if you have the header file. */ +#undef HAVE_RSA_H + +/* Define to 1 if you have the select function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the send function. */ +#undef HAVE_SEND + +/* Define to 1 if you have the header file. */ +#undef HAVE_SETJMP_H + +/* Define to 1 if you have the `setlocale' function. */ +#undef HAVE_SETLOCALE + +/* Define to 1 if you have the `setmode' function. */ +#undef HAVE_SETMODE + +/* Define to 1 if you have the `setrlimit' function. */ +#undef HAVE_SETRLIMIT + +/* Define to 1 if you have the setsockopt function. */ +#undef HAVE_SETSOCKOPT + +/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ +#undef HAVE_SETSOCKOPT_SO_NONBLOCK + +/* Define to 1 if you have the header file. */ +#undef HAVE_SGTTY_H + +/* Define to 1 if you have the sigaction function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the siginterrupt function. */ +#undef HAVE_SIGINTERRUPT + +/* Define to 1 if you have the signal function. */ +#undef HAVE_SIGNAL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SIGNAL_H + +/* Define to 1 if you have the sigsetjmp function or macro. */ +#undef HAVE_SIGSETJMP + +/* Define to 1 if sig_atomic_t is an available typedef. */ +#undef HAVE_SIG_ATOMIC_T + +/* Define to 1 if sig_atomic_t is already defined as volatile. */ +#undef HAVE_SIG_ATOMIC_T_VOLATILE + +/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */ +#undef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID + +/* Define to 1 if you have the socket function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the socketpair function. */ +#undef HAVE_SOCKETPAIR + +/* Define to 1 if you have the header file. */ +#undef HAVE_SOCKET_H + +/* Define to 1 if you have the `SSLv2_client_method' function. */ +#undef HAVE_SSLV2_CLIENT_METHOD + +/* Define to 1 if you have the header file. */ +#undef HAVE_SSL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the strcasecmp function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the strcmpi function. */ +#undef HAVE_STRCMPI + +/* Define to 1 if you have the strdup function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the strerror_r function. */ +#undef HAVE_STRERROR_R + +/* Define to 1 if you have the stricmp function. */ +#undef HAVE_STRICMP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the strncasecmp function. */ +#undef HAVE_STRNCASECMP + +/* Define to 1 if you have the strncmpi function. */ +#undef HAVE_STRNCMPI + +/* Define to 1 if you have the strnicmp function. */ +#undef HAVE_STRNICMP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STROPTS_H + +/* Define to 1 if you have the strstr function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the strtok_r function. */ +#undef HAVE_STRTOK_R + +/* Define to 1 if you have the strtoll function. */ +#undef HAVE_STRTOLL + +/* if struct sockaddr_storage is defined */ +#undef HAVE_STRUCT_SOCKADDR_STORAGE + +/* Define to 1 if you have the timeval struct. */ +#undef HAVE_STRUCT_TIMEVAL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_FILIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_POLL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UTIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_XATTR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TERMIOS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TERMIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TIME_H + +/* Define this if time_t is unsigned */ +#undef HAVE_TIME_T_UNSIGNED + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `utime' function. */ +#undef HAVE_UTIME + +/* Define to 1 if you have the `utimes' function. */ +#undef HAVE_UTIMES + +/* Define to 1 if you have the header file. */ +#undef HAVE_UTIME_H + +/* Define to 1 if compiler supports C99 variadic macro style. */ +#undef HAVE_VARIADIC_MACROS_C99 + +/* Define to 1 if compiler supports old gcc variadic macro style. */ +#undef HAVE_VARIADIC_MACROS_GCC + +/* Define to 1 if you have the winber.h header file. */ +#undef HAVE_WINBER_H + +/* Define to 1 if you have the windows.h header file. */ +#undef HAVE_WINDOWS_H + +/* Define to 1 if you have the winldap.h header file. */ +#undef HAVE_WINLDAP_H + +/* Define to 1 if you have the winsock2.h header file. */ +#undef HAVE_WINSOCK2_H + +/* Define to 1 if you have the winsock.h header file. */ +#undef HAVE_WINSOCK_H + +/* Define to 1 if you have the `wolfSSLv3_client_method' function. */ +#undef HAVE_WOLFSSLV3_CLIENT_METHOD + +/* Define to 1 if you have the `wolfSSL_get_peer_certificate' function. */ +#undef HAVE_WOLFSSL_GET_PEER_CERTIFICATE + +/* Define to 1 if you have the `wolfSSL_UseALPN' function. */ +#undef HAVE_WOLFSSL_USEALPN + +/* Define this symbol if your OS supports changing the contents of argv */ +#undef HAVE_WRITABLE_ARGV + +/* Define to 1 if you have the writev function. */ +#undef HAVE_WRITEV + +/* Define to 1 if you have the ws2tcpip.h header file. */ +#undef HAVE_WS2TCPIP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X509_H + +/* if you have the zlib.h header file */ +#undef HAVE_ZLIB_H + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Define to 1 if you need the lber.h header file even with ldap.h */ +#undef NEED_LBER_H + +/* Define to 1 if you need the malloc.h header file even with stdlib.h */ +#undef NEED_MALLOC_H + +/* Define to 1 if you need the memory.h header file even with stdlib.h */ +#undef NEED_MEMORY_H + +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ +#undef NEED_REENTRANT + +/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ +#undef NEED_THREAD_SAFE + +/* Define to enable NTLM delegation to winbind's ntlm_auth helper. */ +#undef NTLM_WB_ENABLED + +/* Define absolute filename for winbind's ntlm_auth helper. */ +#undef NTLM_WB_FILE + +/* cpu-machine-OS */ +#undef OS + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* a suitable file to read random data from */ +#undef RANDOM_FILE + +/* Define to the type of arg 1 for recv. */ +#undef RECV_TYPE_ARG1 + +/* Define to the type of arg 2 for recv. */ +#undef RECV_TYPE_ARG2 + +/* Define to the type of arg 3 for recv. */ +#undef RECV_TYPE_ARG3 + +/* Define to the type of arg 4 for recv. */ +#undef RECV_TYPE_ARG4 + +/* Define to the function return type for recv. */ +#undef RECV_TYPE_RETV + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to the type qualifier of arg 5 for select. */ +#undef SELECT_QUAL_ARG5 + +/* Define to the type of arg 1 for select. */ +#undef SELECT_TYPE_ARG1 + +/* Define to the type of args 2, 3 and 4 for select. */ +#undef SELECT_TYPE_ARG234 + +/* Define to the type of arg 5 for select. */ +#undef SELECT_TYPE_ARG5 + +/* Define to the function return type for select. */ +#undef SELECT_TYPE_RETV + +/* Define to the type qualifier of arg 2 for send. */ +#undef SEND_QUAL_ARG2 + +/* Define to the type of arg 1 for send. */ +#undef SEND_TYPE_ARG1 + +/* Define to the type of arg 2 for send. */ +#undef SEND_TYPE_ARG2 + +/* Define to the type of arg 3 for send. */ +#undef SEND_TYPE_ARG3 + +/* Define to the type of arg 4 for send. */ +#undef SEND_TYPE_ARG4 + +/* Define to the function return type for send. */ +#undef SEND_TYPE_RETV + +/* The number of bytes in type curl_off_t */ +#undef SIZEOF_CURL_OFF_T + +/* The number of bytes in type int */ +#undef SIZEOF_INT + +/* The number of bytes in type long */ +#undef SIZEOF_LONG + +/* The number of bytes in type long long */ +#undef SIZEOF_LONG_LONG + +/* The number of bytes in type off_t */ +#undef SIZEOF_OFF_T + +/* The number of bytes in type short */ +#undef SIZEOF_SHORT + +/* The number of bytes in type size_t */ +#undef SIZEOF_SIZE_T + +/* The number of bytes in type time_t */ +#undef SIZEOF_TIME_T + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to the type of arg 3 for strerror_r. */ +#undef STRERROR_R_TYPE_ARG3 + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* to enable alt-svc */ +#undef USE_ALTSVC + +/* if AmiSSL is in use */ +#undef USE_AMISSL + +/* Define to enable c-ares support */ +#undef USE_ARES + +/* if GnuTLS is enabled */ +#undef USE_GNUTLS + +/* if GnuTLS uses nettle as crypto backend */ +#undef USE_GNUTLS_NETTLE + +/* PSL support enabled */ +#undef USE_LIBPSL + +/* if librtmp is in use */ +#undef USE_LIBRTMP + +/* if libSSH is in use */ +#undef USE_LIBSSH + +/* if libSSH2 is in use */ +#undef USE_LIBSSH2 + +/* If you want to build curl with the built-in manual */ +#undef USE_MANUAL + +/* if mbedTLS is enabled */ +#undef USE_MBEDTLS + +/* if MesaLink is enabled */ +#undef USE_MESALINK + +/* Define to enable metalink support */ +#undef USE_METALINK + +/* if nghttp2 is in use */ +#undef USE_NGHTTP2 + +/* if NSS is enabled */ +#undef USE_NSS + +/* Use OpenLDAP-specific code */ +#undef USE_OPENLDAP + +/* if OpenSSL is in use */ +#undef USE_OPENSSL + +/* to enable Windows native SSL/TLS support */ +#undef USE_SCHANNEL + +/* enable Secure Transport */ +#undef USE_SECTRANSP + +/* if you want POSIX threaded DNS lookup */ +#undef USE_THREADS_POSIX + +/* if you want Win32 threaded DNS lookup */ +#undef USE_THREADS_WIN32 + +/* Use TLS-SRP authentication */ +#undef USE_TLS_SRP + +/* Use Unix domain sockets */ +#undef USE_UNIX_SOCKETS + +/* Define to 1 if you have the `normaliz' (WinIDN) library (-lnormaliz). */ +#undef USE_WIN32_IDN + +/* Define to 1 if you are building a Windows target with large file support. + */ +#undef USE_WIN32_LARGE_FILES + +/* Use Windows LDAP implementation */ +#undef USE_WIN32_LDAP + +/* Define to 1 if you are building a Windows target without large file + support. */ +#undef USE_WIN32_SMALL_FILES + +/* to enable SSPI support */ +#undef USE_WINDOWS_SSPI + +/* if wolfSSL is enabled */ +#undef USE_WOLFSSL + +/* Version number of package */ +#undef VERSION + +/* Define to 1 to provide own prototypes. */ +#undef WANT_IDN_PROTOTYPES + +/* Define to 1 if OS is AIX. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Type to use in place of in_addr_t when system does not provide it. */ +#undef in_addr_t + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* the signed version of size_t */ +#undef ssize_t diff --git a/libcurl/lib/curl_ctype.c b/libcurl/lib/curl_ctype.c new file mode 100644 index 0000000..1a47fb5 --- /dev/null +++ b/libcurl/lib/curl_ctype.c @@ -0,0 +1,133 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DOES_CONVERSIONS + +#undef _U +#define _U (1<<0) /* upper case */ +#undef _L +#define _L (1<<1) /* lower case */ +#undef _N +#define _N (1<<2) /* decimal numerical digit */ +#undef _S +#define _S (1<<3) /* space */ +#undef _P +#define _P (1<<4) /* punctuation */ +#undef _C +#define _C (1<<5) /* control */ +#undef _X +#define _X (1<<6) /* hexadecimal letter */ +#undef _B +#define _B (1<<7) /* blank */ + +static const unsigned char ascii[128] = { + _C, _C, _C, _C, _C, _C, _C, _C, + _C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C, + _C, _C, _C, _C, _C, _C, _C, _C, + _C, _C, _C, _C, _C, _C, _C, _C, + _S|_B, _P, _P, _P, _P, _P, _P, _P, + _P, _P, _P, _P, _P, _P, _P, _P, + _N, _N, _N, _N, _N, _N, _N, _N, + _N, _N, _P, _P, _P, _P, _P, _P, + _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U, + _U, _U, _U, _U, _U, _U, _U, _U, + _U, _U, _U, _U, _U, _U, _U, _U, + _U, _U, _U, _P, _P, _P, _P, _P, + _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L, + _L, _L, _L, _L, _L, _L, _L, _L, + _L, _L, _L, _L, _L, _L, _L, _L, + _L, _L, _L, _P, _P, _P, _P, _C +}; + +int Curl_isspace(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & _S); +} + +int Curl_isdigit(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & _N); +} + +int Curl_isalnum(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_N|_U|_L)); +} + +int Curl_isxdigit(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_N|_X)); +} + +int Curl_isgraph(int c) +{ + if((c < 0) || (c >= 0x80) || (c == ' ')) + return FALSE; + return (ascii[c] & (_N|_X|_U|_L|_P|_S)); +} + +int Curl_isprint(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_N|_X|_U|_L|_P|_S)); +} + +int Curl_isalpha(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_U|_L)); +} + +int Curl_isupper(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_U)); +} + +int Curl_islower(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_L)); +} + +int Curl_iscntrl(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_C)); +} + +#endif /* !CURL_DOES_CONVERSIONS */ diff --git a/libcurl/lib/curl_ctype.h b/libcurl/lib/curl_ctype.h new file mode 100644 index 0000000..6e94bb1 --- /dev/null +++ b/libcurl/lib/curl_ctype.h @@ -0,0 +1,81 @@ +#ifndef HEADER_CURL_CTYPE_H +#define HEADER_CURL_CTYPE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef CURL_DOES_CONVERSIONS + +/* + * Uppercase macro versions of ANSI/ISO is*() functions/macros which + * avoid negative number inputs with argument byte codes > 127. + * + * For non-ASCII platforms the C library character classification routines + * are used despite being locale-dependent, because this is better than + * not to work at all. + */ +#include + +#define ISSPACE(x) (isspace((int) ((unsigned char)x))) +#define ISDIGIT(x) (isdigit((int) ((unsigned char)x))) +#define ISALNUM(x) (isalnum((int) ((unsigned char)x))) +#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x))) +#define ISGRAPH(x) (isgraph((int) ((unsigned char)x))) +#define ISALPHA(x) (isalpha((int) ((unsigned char)x))) +#define ISPRINT(x) (isprint((int) ((unsigned char)x))) +#define ISUPPER(x) (isupper((int) ((unsigned char)x))) +#define ISLOWER(x) (islower((int) ((unsigned char)x))) +#define ISCNTRL(x) (iscntrl((int) ((unsigned char)x))) +#define ISASCII(x) (isascii((int) ((unsigned char)x))) + +#else + +int Curl_isspace(int c); +int Curl_isdigit(int c); +int Curl_isalnum(int c); +int Curl_isxdigit(int c); +int Curl_isgraph(int c); +int Curl_isprint(int c); +int Curl_isalpha(int c); +int Curl_isupper(int c); +int Curl_islower(int c); +int Curl_iscntrl(int c); + +#define ISSPACE(x) (Curl_isspace((int) ((unsigned char)x))) +#define ISDIGIT(x) (Curl_isdigit((int) ((unsigned char)x))) +#define ISALNUM(x) (Curl_isalnum((int) ((unsigned char)x))) +#define ISXDIGIT(x) (Curl_isxdigit((int) ((unsigned char)x))) +#define ISGRAPH(x) (Curl_isgraph((int) ((unsigned char)x))) +#define ISALPHA(x) (Curl_isalpha((int) ((unsigned char)x))) +#define ISPRINT(x) (Curl_isprint((int) ((unsigned char)x))) +#define ISUPPER(x) (Curl_isupper((int) ((unsigned char)x))) +#define ISLOWER(x) (Curl_islower((int) ((unsigned char)x))) +#define ISCNTRL(x) (Curl_iscntrl((int) ((unsigned char)x))) +#define ISASCII(x) (((x) >= 0) && ((x) <= 0x80)) + +#endif + +#define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \ + (((unsigned char)x) == '\t')) + +#endif /* HEADER_CURL_CTYPE_H */ diff --git a/libcurl/lib/curl_des.c b/libcurl/lib/curl_des.c new file mode 100644 index 0000000..b123a00 --- /dev/null +++ b/libcurl/lib/curl_des.c @@ -0,0 +1,63 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2015, Steve Holme, . + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_NTLM) && !defined(USE_OPENSSL) + +#include "curl_des.h" + +/* + * Curl_des_set_odd_parity() + * + * This is used to apply odd parity to the given byte array. It is typically + * used by when a cryptography engines doesn't have it's own version. + * + * The function is a port of the Java based oddParity() function over at: + * + * https://davenport.sourceforge.io/ntlm.html + * + * Parameters: + * + * bytes [in/out] - The data whose parity bits are to be adjusted for + * odd parity. + * len [out] - The length of the data. + */ +void Curl_des_set_odd_parity(unsigned char *bytes, size_t len) +{ + size_t i; + + for(i = 0; i < len; i++) { + unsigned char b = bytes[i]; + + bool needs_parity = (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ + (b >> 4) ^ (b >> 3) ^ (b >> 2) ^ + (b >> 1)) & 0x01) == 0; + + if(needs_parity) + bytes[i] |= 0x01; + else + bytes[i] &= 0xfe; + } +} + +#endif /* USE_NTLM && !USE_OPENSSL */ diff --git a/libcurl/lib/curl_des.h b/libcurl/lib/curl_des.h new file mode 100644 index 0000000..129060f --- /dev/null +++ b/libcurl/lib/curl_des.h @@ -0,0 +1,34 @@ +#ifndef HEADER_CURL_DES_H +#define HEADER_CURL_DES_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2015, Steve Holme, . + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_NTLM) && !defined(USE_OPENSSL) + +/* Applies odd parity to the given byte array */ +void Curl_des_set_odd_parity(unsigned char *bytes, size_t length); + +#endif /* USE_NTLM && !USE_OPENSSL */ + +#endif /* HEADER_CURL_DES_H */ diff --git a/libcurl/lib/curl_endian.c b/libcurl/lib/curl_endian.c new file mode 100644 index 0000000..b7563b3 --- /dev/null +++ b/libcurl/lib/curl_endian.c @@ -0,0 +1,124 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include "curl_endian.h" + +/* + * Curl_read16_le() + * + * This function converts a 16-bit integer from the little endian format, as + * used in the incoming package to whatever endian format we're using + * natively. + * + * Parameters: + * + * buf [in] - A pointer to a 2 byte buffer. + * + * Returns the integer. + */ +unsigned short Curl_read16_le(const unsigned char *buf) +{ + return (unsigned short)(((unsigned short)buf[0]) | + ((unsigned short)buf[1] << 8)); +} + +/* + * Curl_read32_le() + * + * This function converts a 32-bit integer from the little endian format, as + * used in the incoming package to whatever endian format we're using + * natively. + * + * Parameters: + * + * buf [in] - A pointer to a 4 byte buffer. + * + * Returns the integer. + */ +unsigned int Curl_read32_le(const unsigned char *buf) +{ + return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) | + ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24); +} + +/* + * Curl_read16_be() + * + * This function converts a 16-bit integer from the big endian format, as + * used in the incoming package to whatever endian format we're using + * natively. + * + * Parameters: + * + * buf [in] - A pointer to a 2 byte buffer. + * + * Returns the integer. + */ +unsigned short Curl_read16_be(const unsigned char *buf) +{ + return (unsigned short)(((unsigned short)buf[0] << 8) | + ((unsigned short)buf[1])); +} + +/* + * write32_le() + * + * This function converts a 32-bit integer from the native endian format, + * to little endian format ready for sending down the wire. + * + * Parameters: + * + * value [in] - The 32-bit integer value. + * buffer [in] - A pointer to the output buffer. + */ +static void write32_le(const int value, unsigned char *buffer) +{ + buffer[0] = (char)(value & 0x000000FF); + buffer[1] = (char)((value & 0x0000FF00) >> 8); + buffer[2] = (char)((value & 0x00FF0000) >> 16); + buffer[3] = (char)((value & 0xFF000000) >> 24); +} + +#if (CURL_SIZEOF_CURL_OFF_T > 4) +/* + * Curl_write64_le() + * + * This function converts a 64-bit integer from the native endian format, + * to little endian format ready for sending down the wire. + * + * Parameters: + * + * value [in] - The 64-bit integer value. + * buffer [in] - A pointer to the output buffer. + */ +#if defined(HAVE_LONGLONG) +void Curl_write64_le(const long long value, unsigned char *buffer) +#else +void Curl_write64_le(const __int64 value, unsigned char *buffer) +#endif +{ + write32_le((int)value, buffer); + write32_le((int)(value >> 32), buffer + 4); +} +#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */ diff --git a/libcurl/lib/curl_endian.h b/libcurl/lib/curl_endian.h new file mode 100644 index 0000000..9830e58 --- /dev/null +++ b/libcurl/lib/curl_endian.h @@ -0,0 +1,43 @@ +#ifndef HEADER_CURL_ENDIAN_H +#define HEADER_CURL_ENDIAN_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* Converts a 16-bit integer from little endian */ +unsigned short Curl_read16_le(const unsigned char *buf); + +/* Converts a 32-bit integer from little endian */ +unsigned int Curl_read32_le(const unsigned char *buf); + +/* Converts a 16-bit integer from big endian */ +unsigned short Curl_read16_be(const unsigned char *buf); + +#if (CURL_SIZEOF_CURL_OFF_T > 4) +/* Converts a 64-bit integer to little endian */ +#if defined(HAVE_LONGLONG) +void Curl_write64_le(const long long value, unsigned char *buffer); +#else +void Curl_write64_le(const __int64 value, unsigned char *buffer); +#endif +#endif + +#endif /* HEADER_CURL_ENDIAN_H */ diff --git a/libcurl/lib/curl_fnmatch.c b/libcurl/lib/curl_fnmatch.c new file mode 100644 index 0000000..ab3e742 --- /dev/null +++ b/libcurl/lib/curl_fnmatch.c @@ -0,0 +1,389 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#ifndef CURL_DISABLE_FTP +#include + +#include "curl_fnmatch.h" +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +#ifndef HAVE_FNMATCH + +#define CURLFNM_CHARSET_LEN (sizeof(char) * 256) +#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15) + +#define CURLFNM_NEGATE CURLFNM_CHARSET_LEN + +#define CURLFNM_ALNUM (CURLFNM_CHARSET_LEN + 1) +#define CURLFNM_DIGIT (CURLFNM_CHARSET_LEN + 2) +#define CURLFNM_XDIGIT (CURLFNM_CHARSET_LEN + 3) +#define CURLFNM_ALPHA (CURLFNM_CHARSET_LEN + 4) +#define CURLFNM_PRINT (CURLFNM_CHARSET_LEN + 5) +#define CURLFNM_BLANK (CURLFNM_CHARSET_LEN + 6) +#define CURLFNM_LOWER (CURLFNM_CHARSET_LEN + 7) +#define CURLFNM_GRAPH (CURLFNM_CHARSET_LEN + 8) +#define CURLFNM_SPACE (CURLFNM_CHARSET_LEN + 9) +#define CURLFNM_UPPER (CURLFNM_CHARSET_LEN + 10) + +typedef enum { + CURLFNM_SCHS_DEFAULT = 0, + CURLFNM_SCHS_RIGHTBR, + CURLFNM_SCHS_RIGHTBRLEFTBR +} setcharset_state; + +typedef enum { + CURLFNM_PKW_INIT = 0, + CURLFNM_PKW_DDOT +} parsekey_state; + +typedef enum { + CCLASS_OTHER = 0, + CCLASS_DIGIT, + CCLASS_UPPER, + CCLASS_LOWER +} char_class; + +#define SETCHARSET_OK 1 +#define SETCHARSET_FAIL 0 + +static int parsekeyword(unsigned char **pattern, unsigned char *charset) +{ + parsekey_state state = CURLFNM_PKW_INIT; +#define KEYLEN 10 + char keyword[KEYLEN] = { 0 }; + int found = FALSE; + int i; + unsigned char *p = *pattern; + for(i = 0; !found; i++) { + char c = *p++; + if(i >= KEYLEN) + return SETCHARSET_FAIL; + switch(state) { + case CURLFNM_PKW_INIT: + if(ISLOWER(c)) + keyword[i] = c; + else if(c == ':') + state = CURLFNM_PKW_DDOT; + else + return SETCHARSET_FAIL; + break; + case CURLFNM_PKW_DDOT: + if(c == ']') + found = TRUE; + else + return SETCHARSET_FAIL; + } + } +#undef KEYLEN + + *pattern = p; /* move caller's pattern pointer */ + if(strcmp(keyword, "digit") == 0) + charset[CURLFNM_DIGIT] = 1; + else if(strcmp(keyword, "alnum") == 0) + charset[CURLFNM_ALNUM] = 1; + else if(strcmp(keyword, "alpha") == 0) + charset[CURLFNM_ALPHA] = 1; + else if(strcmp(keyword, "xdigit") == 0) + charset[CURLFNM_XDIGIT] = 1; + else if(strcmp(keyword, "print") == 0) + charset[CURLFNM_PRINT] = 1; + else if(strcmp(keyword, "graph") == 0) + charset[CURLFNM_GRAPH] = 1; + else if(strcmp(keyword, "space") == 0) + charset[CURLFNM_SPACE] = 1; + else if(strcmp(keyword, "blank") == 0) + charset[CURLFNM_BLANK] = 1; + else if(strcmp(keyword, "upper") == 0) + charset[CURLFNM_UPPER] = 1; + else if(strcmp(keyword, "lower") == 0) + charset[CURLFNM_LOWER] = 1; + else + return SETCHARSET_FAIL; + return SETCHARSET_OK; +} + +/* Return the character class. */ +static char_class charclass(unsigned char c) +{ + if(ISUPPER(c)) + return CCLASS_UPPER; + if(ISLOWER(c)) + return CCLASS_LOWER; + if(ISDIGIT(c)) + return CCLASS_DIGIT; + return CCLASS_OTHER; +} + +/* Include a character or a range in set. */ +static void setcharorrange(unsigned char **pp, unsigned char *charset) +{ + unsigned char *p = (*pp)++; + unsigned char c = *p++; + + charset[c] = 1; + if(ISALNUM(c) && *p++ == '-') { + char_class cc = charclass(c); + unsigned char endrange = *p++; + + if(endrange == '\\') + endrange = *p++; + if(endrange >= c && charclass(endrange) == cc) { + while(c++ != endrange) + if(charclass(c) == cc) /* Chars in class may be not consecutive. */ + charset[c] = 1; + *pp = p; + } + } +} + +/* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */ +static int setcharset(unsigned char **p, unsigned char *charset) +{ + setcharset_state state = CURLFNM_SCHS_DEFAULT; + bool something_found = FALSE; + unsigned char c; + + memset(charset, 0, CURLFNM_CHSET_SIZE); + for(;;) { + c = **p; + if(!c) + return SETCHARSET_FAIL; + + switch(state) { + case CURLFNM_SCHS_DEFAULT: + if(c == ']') { + if(something_found) + return SETCHARSET_OK; + something_found = TRUE; + state = CURLFNM_SCHS_RIGHTBR; + charset[c] = 1; + (*p)++; + } + else if(c == '[') { + unsigned char *pp = *p + 1; + + if(*pp++ == ':' && parsekeyword(&pp, charset)) + *p = pp; + else { + charset[c] = 1; + (*p)++; + } + something_found = TRUE; + } + else if(c == '^' || c == '!') { + if(!something_found) { + if(charset[CURLFNM_NEGATE]) { + charset[c] = 1; + something_found = TRUE; + } + else + charset[CURLFNM_NEGATE] = 1; /* negate charset */ + } + else + charset[c] = 1; + (*p)++; + } + else if(c == '\\') { + c = *(++(*p)); + if(c) + setcharorrange(p, charset); + else + charset['\\'] = 1; + something_found = TRUE; + } + else { + setcharorrange(p, charset); + something_found = TRUE; + } + break; + case CURLFNM_SCHS_RIGHTBR: + if(c == '[') { + state = CURLFNM_SCHS_RIGHTBRLEFTBR; + charset[c] = 1; + (*p)++; + } + else if(c == ']') { + return SETCHARSET_OK; + } + else if(ISPRINT(c)) { + charset[c] = 1; + (*p)++; + state = CURLFNM_SCHS_DEFAULT; + } + else + /* used 'goto fail' instead of 'return SETCHARSET_FAIL' to avoid a + * nonsense warning 'statement not reached' at end of the fnc when + * compiling on Solaris */ + goto fail; + break; + case CURLFNM_SCHS_RIGHTBRLEFTBR: + if(c == ']') + return SETCHARSET_OK; + state = CURLFNM_SCHS_DEFAULT; + charset[c] = 1; + (*p)++; + break; + } + } +fail: + return SETCHARSET_FAIL; +} + +static int loop(const unsigned char *pattern, const unsigned char *string, + int maxstars) +{ + unsigned char *p = (unsigned char *)pattern; + unsigned char *s = (unsigned char *)string; + unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 }; + + for(;;) { + unsigned char *pp; + + switch(*p) { + case '*': + if(!maxstars) + return CURL_FNMATCH_NOMATCH; + /* Regroup consecutive stars and question marks. This can be done because + '*?*?*' can be expressed as '??*'. */ + for(;;) { + if(*++p == '\0') + return CURL_FNMATCH_MATCH; + if(*p == '?') { + if(!*s++) + return CURL_FNMATCH_NOMATCH; + } + else if(*p != '*') + break; + } + /* Skip string characters until we find a match with pattern suffix. */ + for(maxstars--; *s; s++) { + if(loop(p, s, maxstars) == CURL_FNMATCH_MATCH) + return CURL_FNMATCH_MATCH; + } + return CURL_FNMATCH_NOMATCH; + case '?': + if(!*s) + return CURL_FNMATCH_NOMATCH; + s++; + p++; + break; + case '\0': + return *s? CURL_FNMATCH_NOMATCH: CURL_FNMATCH_MATCH; + case '\\': + if(p[1]) + p++; + if(*s++ != *p++) + return CURL_FNMATCH_NOMATCH; + break; + case '[': + pp = p + 1; /* Copy in case of syntax error in set. */ + if(setcharset(&pp, charset)) { + int found = FALSE; + if(!*s) + return CURL_FNMATCH_NOMATCH; + if(charset[(unsigned int)*s]) + found = TRUE; + else if(charset[CURLFNM_ALNUM]) + found = ISALNUM(*s); + else if(charset[CURLFNM_ALPHA]) + found = ISALPHA(*s); + else if(charset[CURLFNM_DIGIT]) + found = ISDIGIT(*s); + else if(charset[CURLFNM_XDIGIT]) + found = ISXDIGIT(*s); + else if(charset[CURLFNM_PRINT]) + found = ISPRINT(*s); + else if(charset[CURLFNM_SPACE]) + found = ISSPACE(*s); + else if(charset[CURLFNM_UPPER]) + found = ISUPPER(*s); + else if(charset[CURLFNM_LOWER]) + found = ISLOWER(*s); + else if(charset[CURLFNM_BLANK]) + found = ISBLANK(*s); + else if(charset[CURLFNM_GRAPH]) + found = ISGRAPH(*s); + + if(charset[CURLFNM_NEGATE]) + found = !found; + + if(!found) + return CURL_FNMATCH_NOMATCH; + p = pp + 1; + s++; + break; + } + /* Syntax error in set; mismatch! */ + return CURL_FNMATCH_NOMATCH; + + default: + if(*p++ != *s++) + return CURL_FNMATCH_NOMATCH; + break; + } + } +} + +/* + * @unittest: 1307 + */ +int Curl_fnmatch(void *ptr, const char *pattern, const char *string) +{ + (void)ptr; /* the argument is specified by the curl_fnmatch_callback + prototype, but not used by Curl_fnmatch() */ + if(!pattern || !string) { + return CURL_FNMATCH_FAIL; + } + return loop((unsigned char *)pattern, (unsigned char *)string, 2); +} +#else +#include +/* + * @unittest: 1307 + */ +int Curl_fnmatch(void *ptr, const char *pattern, const char *string) +{ + int rc; + (void)ptr; /* the argument is specified by the curl_fnmatch_callback + prototype, but not used by Curl_fnmatch() */ + if(!pattern || !string) { + return CURL_FNMATCH_FAIL; + } + rc = fnmatch(pattern, string, 0); + switch(rc) { + case 0: + return CURL_FNMATCH_MATCH; + case FNM_NOMATCH: + return CURL_FNMATCH_NOMATCH; + default: + return CURL_FNMATCH_FAIL; + } + /* not reached */ +} + +#endif + +#endif /* if FTP is disabled */ diff --git a/libcurl/lib/curl_fnmatch.h b/libcurl/lib/curl_fnmatch.h new file mode 100644 index 0000000..69ffe39 --- /dev/null +++ b/libcurl/lib/curl_fnmatch.h @@ -0,0 +1,44 @@ +#ifndef HEADER_CURL_FNMATCH_H +#define HEADER_CURL_FNMATCH_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#define CURL_FNMATCH_MATCH 0 +#define CURL_FNMATCH_NOMATCH 1 +#define CURL_FNMATCH_FAIL 2 + +/* default pattern matching function + * ================================= + * Implemented with recursive backtracking, if you want to use Curl_fnmatch, + * please note that there is not implemented UTF/UNICODE support. + * + * Implemented features: + * '?' notation, does not match UTF characters + * '*' can also work with UTF string + * [a-zA-Z0-9] enumeration support + * + * keywords: alnum, digit, xdigit, alpha, print, blank, lower, graph, space + * and upper (use as "[[:alnum:]]") + */ +int Curl_fnmatch(void *ptr, const char *pattern, const char *string); + +#endif /* HEADER_CURL_FNMATCH_H */ diff --git a/libcurl/lib/curl_get_line.c b/libcurl/lib/curl_get_line.c new file mode 100644 index 0000000..c419485 --- /dev/null +++ b/libcurl/lib/curl_get_line.c @@ -0,0 +1,55 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include "curl_get_line.h" +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* + * get_line() makes sure to only return complete whole lines that fit in 'len' + * bytes and end with a newline. + */ +char *Curl_get_line(char *buf, int len, FILE *input) +{ + bool partial = FALSE; + while(1) { + char *b = fgets(buf, len, input); + if(b) { + size_t rlen = strlen(b); + if(rlen && (b[rlen-1] == '\n')) { + if(partial) { + partial = FALSE; + continue; + } + return b; + } + /* read a partial, discard the next piece that ends with newline */ + partial = TRUE; + } + else + break; + } + return NULL; +} diff --git a/libcurl/lib/curl_get_line.h b/libcurl/lib/curl_get_line.h new file mode 100644 index 0000000..532ab08 --- /dev/null +++ b/libcurl/lib/curl_get_line.h @@ -0,0 +1,29 @@ +#ifndef HEADER_CURL_GET_LINE_H +#define HEADER_CURL_GET_LINE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* get_line() makes sure to only return complete whole lines that fit in 'len' + * bytes and end with a newline. */ +char *Curl_get_line(char *buf, int len, FILE *input); + +#endif /* HEADER_CURL_GET_LINE_H */ diff --git a/libcurl/lib/curl_gethostname.c b/libcurl/lib/curl_gethostname.c new file mode 100644 index 0000000..95f7ed4 --- /dev/null +++ b/libcurl/lib/curl_gethostname.c @@ -0,0 +1,108 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include "curl_gethostname.h" + +/* + * Curl_gethostname() is a wrapper around gethostname() which allows + * overriding the host name that the function would normally return. + * This capability is used by the test suite to verify exact matching + * of NTLM authentication, which exercises libcurl's MD4 and DES code + * as well as by the SMTP module when a hostname is not provided. + * + * For libcurl debug enabled builds host name overriding takes place + * when environment variable CURL_GETHOSTNAME is set, using the value + * held by the variable to override returned host name. + * + * Note: The function always returns the un-qualified hostname rather + * than being provider dependent. + * + * For libcurl shared library release builds the test suite preloads + * another shared library named libhostname using the LD_PRELOAD + * mechanism which intercepts, and might override, the gethostname() + * function call. In this case a given platform must support the + * LD_PRELOAD mechanism and additionally have environment variable + * CURL_GETHOSTNAME set in order to override the returned host name. + * + * For libcurl static library release builds no overriding takes place. + */ + +int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) +{ + +#ifdef _XBOX + (void) name; + (void) namelen; + return -1; +#else + +#ifndef HAVE_GETHOSTNAME + + /* Allow compilation and return failure when unavailable */ + (void) name; + (void) namelen; + return -1; + +#else + int err; + char *dot; + +#ifdef DEBUGBUILD + + /* Override host name when environment variable CURL_GETHOSTNAME is set */ + const char *force_hostname = getenv("CURL_GETHOSTNAME"); + if(force_hostname) { + strncpy(name, force_hostname, namelen); + err = 0; + } + else { + name[0] = '\0'; + err = gethostname(name, namelen); + } + +#else /* DEBUGBUILD */ + + /* The call to system's gethostname() might get intercepted by the + libhostname library when libcurl is built as a non-debug shared + library when running the test suite. */ + name[0] = '\0'; + err = gethostname(name, namelen); + +#endif + + name[namelen - 1] = '\0'; + + if(err) + return err; + + /* Truncate domain, leave only machine name */ + dot = strchr(name, '.'); + if(dot) + *dot = '\0'; + + return 0; +#endif +#endif // _XBOX + +} diff --git a/libcurl/lib/curl_gethostname.h b/libcurl/lib/curl_gethostname.h new file mode 100644 index 0000000..07517c5 --- /dev/null +++ b/libcurl/lib/curl_gethostname.h @@ -0,0 +1,31 @@ +#ifndef HEADER_CURL_GETHOSTNAME_H +#define HEADER_CURL_GETHOSTNAME_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* Hostname buffer size */ +#define HOSTNAME_MAX 1024 + +/* This returns the local machine's un-qualified hostname */ +int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen); + +#endif /* HEADER_CURL_GETHOSTNAME_H */ diff --git a/libcurl/lib/curl_gssapi.c b/libcurl/lib/curl_gssapi.c new file mode 100644 index 0000000..d854ab0 --- /dev/null +++ b/libcurl/lib/curl_gssapi.c @@ -0,0 +1,136 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2011 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_GSSAPI + +#include "curl_gssapi.h" +#include "sendf.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +static char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02"; +gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes }; +static char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"; +gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes }; + +OM_uint32 Curl_gss_init_sec_context( + struct Curl_easy *data, + OM_uint32 *minor_status, + gss_ctx_id_t *context, + gss_name_t target_name, + gss_OID mech_type, + gss_channel_bindings_t input_chan_bindings, + gss_buffer_t input_token, + gss_buffer_t output_token, + const bool mutual_auth, + OM_uint32 *ret_flags) +{ + OM_uint32 req_flags = GSS_C_REPLAY_FLAG; + + if(mutual_auth) + req_flags |= GSS_C_MUTUAL_FLAG; + + if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) { +#ifdef GSS_C_DELEG_POLICY_FLAG + req_flags |= GSS_C_DELEG_POLICY_FLAG; +#else + infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not " + "compiled in\n"); +#endif + } + + if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG) + req_flags |= GSS_C_DELEG_FLAG; + + return gss_init_sec_context(minor_status, + GSS_C_NO_CREDENTIAL, /* cred_handle */ + context, + target_name, + mech_type, + req_flags, + 0, /* time_req */ + input_chan_bindings, + input_token, + NULL, /* actual_mech_type */ + output_token, + ret_flags, + NULL /* time_rec */); +} + +#define GSS_LOG_BUFFER_LEN 1024 +static size_t display_gss_error(OM_uint32 status, int type, + char *buf, size_t len) { + OM_uint32 maj_stat; + OM_uint32 min_stat; + OM_uint32 msg_ctx = 0; + gss_buffer_desc status_string; + + do { + maj_stat = gss_display_status(&min_stat, + status, + type, + GSS_C_NO_OID, + &msg_ctx, + &status_string); + if(GSS_LOG_BUFFER_LEN > len + status_string.length + 3) { + len += msnprintf(buf + len, GSS_LOG_BUFFER_LEN - len, + "%.*s. ", (int)status_string.length, + (char *)status_string.value); + } + gss_release_buffer(&min_stat, &status_string); + } while(!GSS_ERROR(maj_stat) && msg_ctx != 0); + + return len; +} + +/* + * Curl_gss_log_error() + * + * This is used to log a GSS-API error status. + * + * Parameters: + * + * data [in] - The session handle. + * prefix [in] - The prefix of the log message. + * major [in] - The major status code. + * minor [in] - The minor status code. + */ +void Curl_gss_log_error(struct Curl_easy *data, const char *prefix, + OM_uint32 major, OM_uint32 minor) +{ + char buf[GSS_LOG_BUFFER_LEN]; + size_t len = 0; + + if(major != GSS_S_FAILURE) + len = display_gss_error(major, GSS_C_GSS_CODE, buf, len); + + display_gss_error(minor, GSS_C_MECH_CODE, buf, len); + + infof(data, "%s%s\n", prefix, buf); +} + +#endif /* HAVE_GSSAPI */ diff --git a/libcurl/lib/curl_gssapi.h b/libcurl/lib/curl_gssapi.h new file mode 100644 index 0000000..88f68db --- /dev/null +++ b/libcurl/lib/curl_gssapi.h @@ -0,0 +1,61 @@ +#ifndef HEADER_CURL_GSSAPI_H +#define HEADER_CURL_GSSAPI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2011 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include "urldata.h" + +#ifdef HAVE_GSSAPI +extern gss_OID_desc Curl_spnego_mech_oid; +extern gss_OID_desc Curl_krb5_mech_oid; + +/* Common method for using GSS-API */ +OM_uint32 Curl_gss_init_sec_context( + struct Curl_easy *data, + OM_uint32 *minor_status, + gss_ctx_id_t *context, + gss_name_t target_name, + gss_OID mech_type, + gss_channel_bindings_t input_chan_bindings, + gss_buffer_t input_token, + gss_buffer_t output_token, + const bool mutual_auth, + OM_uint32 *ret_flags); + +/* Helper to log a GSS-API error status */ +void Curl_gss_log_error(struct Curl_easy *data, const char *prefix, + OM_uint32 major, OM_uint32 minor); + +/* Provide some definitions missing in old headers */ +#ifdef HAVE_OLD_GSSMIT +#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name +#define NCOMPAT 1 +#endif + +/* Define our privacy and integrity protection values */ +#define GSSAUTH_P_NONE 1 +#define GSSAUTH_P_INTEGRITY 2 +#define GSSAUTH_P_PRIVACY 4 + +#endif /* HAVE_GSSAPI */ +#endif /* HEADER_CURL_GSSAPI_H */ diff --git a/libcurl/lib/curl_hmac.h b/libcurl/lib/curl_hmac.h new file mode 100644 index 0000000..756dc9e --- /dev/null +++ b/libcurl/lib/curl_hmac.h @@ -0,0 +1,67 @@ +#ifndef HEADER_CURL_HMAC_H +#define HEADER_CURL_HMAC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#ifndef CURL_DISABLE_CRYPTO_AUTH + +typedef void (* HMAC_hinit_func)(void *context); +typedef void (* HMAC_hupdate_func)(void *context, + const unsigned char *data, + unsigned int len); +typedef void (* HMAC_hfinal_func)(unsigned char *result, void *context); + + +/* Per-hash function HMAC parameters. */ + +typedef struct { + HMAC_hinit_func hmac_hinit; /* Initialize context procedure. */ + HMAC_hupdate_func hmac_hupdate; /* Update context with data. */ + HMAC_hfinal_func hmac_hfinal; /* Get final result procedure. */ + unsigned int hmac_ctxtsize; /* Context structure size. */ + unsigned int hmac_maxkeylen; /* Maximum key length (bytes). */ + unsigned int hmac_resultlen; /* Result length (bytes). */ +} HMAC_params; + + +/* HMAC computation context. */ + +typedef struct { + const HMAC_params *hmac_hash; /* Hash function definition. */ + void *hmac_hashctxt1; /* Hash function context 1. */ + void *hmac_hashctxt2; /* Hash function context 2. */ +} HMAC_context; + + +/* Prototypes. */ + +HMAC_context * Curl_HMAC_init(const HMAC_params *hashparams, + const unsigned char *key, + unsigned int keylen); +int Curl_HMAC_update(HMAC_context *context, + const unsigned char *data, + unsigned int len); +int Curl_HMAC_final(HMAC_context *context, unsigned char *result); + +#endif + +#endif /* HEADER_CURL_HMAC_H */ diff --git a/libcurl/lib/curl_ldap.h b/libcurl/lib/curl_ldap.h new file mode 100644 index 0000000..94c0029 --- /dev/null +++ b/libcurl/lib/curl_ldap.h @@ -0,0 +1,34 @@ +#ifndef HEADER_CURL_LDAP_H +#define HEADER_CURL_LDAP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifndef CURL_DISABLE_LDAP +extern const struct Curl_handler Curl_handler_ldap; + +#if !defined(CURL_DISABLE_LDAPS) && \ + ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ + (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) +extern const struct Curl_handler Curl_handler_ldaps; +#endif + +#endif +#endif /* HEADER_CURL_LDAP_H */ diff --git a/libcurl/lib/curl_md4.h b/libcurl/lib/curl_md4.h new file mode 100644 index 0000000..392203f --- /dev/null +++ b/libcurl/lib/curl_md4.h @@ -0,0 +1,37 @@ +#ifndef HEADER_CURL_MD4_H +#define HEADER_CURL_MD4_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_NSS) || defined(USE_OS400CRYPTO) || \ + (defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) || \ + (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) + +void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len); + +#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) || + (defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) || + (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) */ + +#endif /* HEADER_CURL_MD4_H */ diff --git a/libcurl/lib/curl_md5.h b/libcurl/lib/curl_md5.h new file mode 100644 index 0000000..aaf25f6 --- /dev/null +++ b/libcurl/lib/curl_md5.h @@ -0,0 +1,63 @@ +#ifndef HEADER_CURL_MD5_H +#define HEADER_CURL_MD5_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#ifndef CURL_DISABLE_CRYPTO_AUTH +#include "curl_hmac.h" + +#define MD5_DIGEST_LEN 16 + +typedef void (* Curl_MD5_init_func)(void *context); +typedef void (* Curl_MD5_update_func)(void *context, + const unsigned char *data, + unsigned int len); +typedef void (* Curl_MD5_final_func)(unsigned char *result, void *context); + +typedef struct { + Curl_MD5_init_func md5_init_func; /* Initialize context procedure */ + Curl_MD5_update_func md5_update_func; /* Update context with data */ + Curl_MD5_final_func md5_final_func; /* Get final result procedure */ + unsigned int md5_ctxtsize; /* Context structure size */ + unsigned int md5_resultlen; /* Result length (bytes) */ +} MD5_params; + +typedef struct { + const MD5_params *md5_hash; /* Hash function definition */ + void *md5_hashctx; /* Hash function context */ +} MD5_context; + +extern const MD5_params Curl_DIGEST_MD5[1]; +extern const HMAC_params Curl_HMAC_MD5[1]; + +void Curl_md5it(unsigned char *output, + const unsigned char *input); + +MD5_context * Curl_MD5_init(const MD5_params *md5params); +CURLcode Curl_MD5_update(MD5_context *context, + const unsigned char *data, + unsigned int len); +CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result); + +#endif + +#endif /* HEADER_CURL_MD5_H */ diff --git a/libcurl/lib/curl_memory.h b/libcurl/lib/curl_memory.h new file mode 100644 index 0000000..ce38a08 --- /dev/null +++ b/libcurl/lib/curl_memory.h @@ -0,0 +1,156 @@ +#ifndef HEADER_CURL_MEMORY_H +#define HEADER_CURL_MEMORY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Nasty internal details ahead... + * + * File curl_memory.h must be included by _all_ *.c source files + * that use memory related functions strdup, malloc, calloc, realloc + * or free, and given source file is used to build libcurl library. + * It should be included immediately before memdebug.h as the last files + * included to avoid undesired interaction with other memory function + * headers in dependent libraries. + * + * There is nearly no exception to above rule. All libcurl source + * files in 'lib' subdirectory as well as those living deep inside + * 'packages' subdirectories and linked together in order to build + * libcurl library shall follow it. + * + * File lib/strdup.c is an exception, given that it provides a strdup + * clone implementation while using malloc. Extra care needed inside + * this one. + * + * The need for curl_memory.h inclusion is due to libcurl's feature + * of allowing library user to provide memory replacement functions, + * memory callbacks, at runtime with curl_global_init_mem() + * + * Any *.c source file used to build libcurl library that does not + * include curl_memory.h and uses any memory function of the five + * mentioned above will compile without any indication, but it will + * trigger weird memory related issues at runtime. + * + * OTOH some source files from 'lib' subdirectory may additionally be + * used directly as source code when using some curlx_ functions by + * third party programs that don't even use libcurl at all. When using + * these source files in this way it is necessary these are compiled + * with CURLX_NO_MEMORY_CALLBACKS defined, in order to ensure that no + * attempt of calling libcurl's memory callbacks is done from code + * which can not use this machinery. + * + * Notice that libcurl's 'memory tracking' system works chaining into + * the memory callback machinery. This implies that when compiling + * 'lib' source files with CURLX_NO_MEMORY_CALLBACKS defined this file + * disengages usage of libcurl's 'memory tracking' system, defining + * MEMDEBUG_NODEFINES and overriding CURLDEBUG purpose. + * + * CURLX_NO_MEMORY_CALLBACKS takes precedence over CURLDEBUG. This is + * done in order to allow building a 'memory tracking' enabled libcurl + * and at the same time allow building programs which do not use it. + * + * Programs and libraries in 'tests' subdirectories have specific + * purposes and needs, and as such each one will use whatever fits + * best, depending additionally whether it links with libcurl or not. + * + * Caveat emptor. Proper curlx_* separation is a work in progress + * the same as CURLX_NO_MEMORY_CALLBACKS usage, some adjustments may + * still be required. IOW don't use them yet, there are sharp edges. + */ + +#ifdef HEADER_CURL_MEMDEBUG_H +#error "Header memdebug.h shall not be included before curl_memory.h" +#endif + +#ifndef CURLX_NO_MEMORY_CALLBACKS + +#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */ +/* + * The following memory function replacement typedef's are COPIED from + * curl/curl.h and MUST match the originals. We copy them to avoid having to + * include curl/curl.h here. We avoid that include since it includes stdio.h + * and other headers that may get messed up with defines done here. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); +#define CURL_DID_MEMORY_FUNC_TYPEDEFS +#endif + +extern curl_malloc_callback Curl_cmalloc; +extern curl_free_callback Curl_cfree; +extern curl_realloc_callback Curl_crealloc; +extern curl_strdup_callback Curl_cstrdup; +extern curl_calloc_callback Curl_ccalloc; +#if defined(WIN32) && defined(UNICODE) +extern curl_wcsdup_callback Curl_cwcsdup; +#endif + +#ifndef CURLDEBUG + +/* + * libcurl's 'memory tracking' system defines strdup, malloc, calloc, + * realloc and free, along with others, in memdebug.h in a different + * way although still using memory callbacks forward declared above. + * When using the 'memory tracking' system (CURLDEBUG defined) we do + * not define here the five memory functions given that definitions + * from memdebug.h are the ones that shall be used. + */ + +#undef strdup +#define strdup(ptr) Curl_cstrdup(ptr) +#undef malloc +#define malloc(size) Curl_cmalloc(size) +#undef calloc +#define calloc(nbelem,size) Curl_ccalloc(nbelem, size) +#undef realloc +#define realloc(ptr,size) Curl_crealloc(ptr, size) +#undef free +#define free(ptr) Curl_cfree(ptr) + +#ifdef WIN32 +# ifdef UNICODE +# undef wcsdup +# define wcsdup(ptr) Curl_cwcsdup(ptr) +# undef _wcsdup +# define _wcsdup(ptr) Curl_cwcsdup(ptr) +# undef _tcsdup +# define _tcsdup(ptr) Curl_cwcsdup(ptr) +# else +# undef _tcsdup +# define _tcsdup(ptr) Curl_cstrdup(ptr) +# endif +#endif + +#endif /* CURLDEBUG */ + +#else /* CURLX_NO_MEMORY_CALLBACKS */ + +#ifndef MEMDEBUG_NODEFINES +#define MEMDEBUG_NODEFINES +#endif + +#endif /* CURLX_NO_MEMORY_CALLBACKS */ + +#endif /* HEADER_CURL_MEMORY_H */ diff --git a/libcurl/lib/curl_memrchr.c b/libcurl/lib/curl_memrchr.c new file mode 100644 index 0000000..eeb3044 --- /dev/null +++ b/libcurl/lib/curl_memrchr.c @@ -0,0 +1,62 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "curl_memrchr.h" +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +#ifndef HAVE_MEMRCHR + +/* + * Curl_memrchr() + * + * Our memrchr() function clone for systems which lack this function. The + * memrchr() function is like the memchr() function, except that it searches + * backwards from the end of the n bytes pointed to by s instead of forward + * from the beginning. + */ + +void * +Curl_memrchr(const void *s, int c, size_t n) +{ + if(n > 0) { + const unsigned char *p = s; + const unsigned char *q = s; + + p += n - 1; + + while(p >= q) { + if(*p == (unsigned char)c) + return (void *)p; + p--; + } + } + return NULL; +} + +#endif /* HAVE_MEMRCHR */ diff --git a/libcurl/lib/curl_memrchr.h b/libcurl/lib/curl_memrchr.h new file mode 100644 index 0000000..747509c --- /dev/null +++ b/libcurl/lib/curl_memrchr.h @@ -0,0 +1,44 @@ +#ifndef HEADER_CURL_MEMRCHR_H +#define HEADER_CURL_MEMRCHR_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_MEMRCHR + +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#else /* HAVE_MEMRCHR */ + +void *Curl_memrchr(const void *s, int c, size_t n); + +#define memrchr(x,y,z) Curl_memrchr((x),(y),(z)) + +#endif /* HAVE_MEMRCHR */ + +#endif /* HEADER_CURL_MEMRCHR_H */ diff --git a/libcurl/lib/curl_multibyte.c b/libcurl/lib/curl_multibyte.c new file mode 100644 index 0000000..e48334f --- /dev/null +++ b/libcurl/lib/curl_multibyte.c @@ -0,0 +1,84 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \ + defined(USE_WIN32_LDAP)) && defined(UNICODE)) + + /* + * MultiByte conversions using Windows kernel32 library. + */ + +#include "curl_multibyte.h" +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8) +{ + wchar_t *str_w = NULL; + + if(str_utf8) { + int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, + str_utf8, -1, NULL, 0); + if(str_w_len > 0) { + str_w = malloc(str_w_len * sizeof(wchar_t)); + if(str_w) { + if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w, + str_w_len) == 0) { + free(str_w); + return NULL; + } + } + } + } + + return str_w; +} + +char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w) +{ + char *str_utf8 = NULL; + + if(str_w) { + int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, + NULL, 0, NULL, NULL); + if(bytes > 0) { + str_utf8 = malloc(bytes); + if(str_utf8) { + if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, bytes, + NULL, NULL) == 0) { + free(str_utf8); + return NULL; + } + } + } + } + + return str_utf8; +} + +#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */ diff --git a/libcurl/lib/curl_multibyte.h b/libcurl/lib/curl_multibyte.h new file mode 100644 index 0000000..615f5c0 --- /dev/null +++ b/libcurl/lib/curl_multibyte.h @@ -0,0 +1,92 @@ +#ifndef HEADER_CURL_MULTIBYTE_H +#define HEADER_CURL_MULTIBYTE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \ + defined(USE_WIN32_LDAP)) && defined(UNICODE)) + + /* + * MultiByte conversions using Windows kernel32 library. + */ + +wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8); +char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w); + +#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */ + + +#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI) || \ + defined(USE_WIN32_LDAP) + +/* + * Macros Curl_convert_UTF8_to_tchar(), Curl_convert_tchar_to_UTF8() + * and Curl_unicodefree() main purpose is to minimize the number of + * preprocessor conditional directives needed by code using these + * to differentiate UNICODE from non-UNICODE builds. + * + * When building with UNICODE defined, this two macros + * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8() + * return a pointer to a newly allocated memory area holding result. + * When the result is no longer needed, allocated memory is intended + * to be free'ed with Curl_unicodefree(). + * + * When building without UNICODE defined, this macros + * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8() + * return the pointer received as argument. Curl_unicodefree() does + * no actual free'ing of this pointer it is simply set to NULL. + */ + +#ifdef UNICODE + +#define Curl_convert_UTF8_to_tchar(ptr) Curl_convert_UTF8_to_wchar((ptr)) +#define Curl_convert_tchar_to_UTF8(ptr) Curl_convert_wchar_to_UTF8((ptr)) +#define Curl_unicodefree(ptr) \ + do {if((ptr)) {free((ptr)); (ptr) = NULL;}} WHILE_FALSE + +typedef union { + unsigned short *tchar_ptr; + const unsigned short *const_tchar_ptr; + unsigned short *tbyte_ptr; + const unsigned short *const_tbyte_ptr; +} xcharp_u; + +#else + +#define Curl_convert_UTF8_to_tchar(ptr) (ptr) +#define Curl_convert_tchar_to_UTF8(ptr) (ptr) +#define Curl_unicodefree(ptr) \ + do {(ptr) = NULL;} WHILE_FALSE + +typedef union { + char *tchar_ptr; + const char *const_tchar_ptr; + unsigned char *tbyte_ptr; + const unsigned char *const_tbyte_ptr; +} xcharp_u; + +#endif /* UNICODE */ + +#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI || USE_WIN32_LDAP */ + +#endif /* HEADER_CURL_MULTIBYTE_H */ diff --git a/libcurl/lib/curl_ntlm_core.c b/libcurl/lib/curl_ntlm_core.c new file mode 100644 index 0000000..9e6fdca --- /dev/null +++ b/libcurl/lib/curl_ntlm_core.c @@ -0,0 +1,823 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_NTLM) + +/* + * NTLM details: + * + * https://davenport.sourceforge.io/ntlm.html + * https://www.innovation.ch/java/ntlm.html + */ + +/* Please keep the SSL backend-specific #if branches in this order: + + 1. USE_OPENSSL + 2. USE_GNUTLS_NETTLE + 3. USE_GNUTLS + 4. USE_NSS + 5. USE_MBEDTLS + 6. USE_SECTRANSP + 7. USE_OS400CRYPTO + 8. USE_WIN32_CRYPTO + + This ensures that: + - the same SSL branch gets activated throughout this source + file even if multiple backends are enabled at the same time. + - OpenSSL and NSS have higher priority than Windows Crypt, due + to issues with the latter supporting NTLM2Session responses + in NTLM type-3 messages. + */ + +#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO) + +#ifdef USE_OPENSSL + +# include +# ifndef OPENSSL_NO_MD4 +# include +# else +# include "curl_md4.h" +# endif +# include +# include +# include +# if (OPENSSL_VERSION_NUMBER < 0x00907001L) +# define DES_key_schedule des_key_schedule +# define DES_cblock des_cblock +# define DES_set_odd_parity des_set_odd_parity +# define DES_set_key des_set_key +# define DES_ecb_encrypt des_ecb_encrypt +# define DESKEY(x) x +# define DESKEYARG(x) x +# else +# define DESKEYARG(x) *x +# define DESKEY(x) &x +# endif + +#elif defined(USE_GNUTLS_NETTLE) + +# include +# include + +#elif defined(USE_GNUTLS) + +# include +# define MD5_DIGEST_LENGTH 16 +# define MD4_DIGEST_LENGTH 16 + +#elif defined(USE_NSS) + +# include +# include +# include +# include "curl_md4.h" +# define MD5_DIGEST_LENGTH MD5_LENGTH + +#elif defined(USE_MBEDTLS) + +# include +# include +# if !defined(MBEDTLS_MD4_C) +# include "curl_md4.h" +# endif + +#elif defined(USE_SECTRANSP) + +# include +# include + +#elif defined(USE_OS400CRYPTO) +# include "cipher.mih" /* mih/cipher */ +# include "curl_md4.h" +#elif defined(USE_WIN32_CRYPTO) +# include +#else +# error "Can't compile NTLM support without a crypto library." +#endif + +#include "urldata.h" +#include "non-ascii.h" +#include "strcase.h" +#include "curl_ntlm_core.h" +#include "curl_md5.h" +#include "curl_hmac.h" +#include "warnless.h" +#include "curl_endian.h" +#include "curl_des.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#define NTLM_HMAC_MD5_LEN (16) +#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00" +#define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4) + +/* +* Turns a 56-bit key into being 64-bit wide. +*/ +static void extend_key_56_to_64(const unsigned char *key_56, char *key) +{ + key[0] = key_56[0]; + key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1)); + key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2)); + key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3)); + key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4)); + key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5)); + key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6)); + key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF); +} + +#ifdef USE_OPENSSL +/* + * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The + * key schedule ks is also set. + */ +static void setup_des_key(const unsigned char *key_56, + DES_key_schedule DESKEYARG(ks)) +{ + DES_cblock key; + + /* Expand the 56-bit key to 64-bits */ + extend_key_56_to_64(key_56, (char *) &key); + + /* Set the key parity to odd */ + DES_set_odd_parity(&key); + + /* Set the key */ + DES_set_key(&key, ks); +} + +#elif defined(USE_GNUTLS_NETTLE) + +static void setup_des_key(const unsigned char *key_56, + struct des_ctx *des) +{ + char key[8]; + + /* Expand the 56-bit key to 64-bits */ + extend_key_56_to_64(key_56, key); + + /* Set the key parity to odd */ + Curl_des_set_odd_parity((unsigned char *) key, sizeof(key)); + + /* Set the key */ + des_set_key(des, (const uint8_t *) key); +} + +#elif defined(USE_GNUTLS) + +/* + * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. + */ +static void setup_des_key(const unsigned char *key_56, + gcry_cipher_hd_t *des) +{ + char key[8]; + + /* Expand the 56-bit key to 64-bits */ + extend_key_56_to_64(key_56, key); + + /* Set the key parity to odd */ + Curl_des_set_odd_parity((unsigned char *) key, sizeof(key)); + + /* Set the key */ + gcry_cipher_setkey(*des, key, sizeof(key)); +} + +#elif defined(USE_NSS) + +/* + * Expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of data, using + * the expanded key. The caller is responsible for giving 64 bit of valid + * data is IN and (at least) 64 bit large buffer as OUT. + */ +static bool encrypt_des(const unsigned char *in, unsigned char *out, + const unsigned char *key_56) +{ + const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */ + char key[8]; /* expanded 64 bit key */ + SECItem key_item; + PK11SymKey *symkey = NULL; + SECItem *param = NULL; + PK11Context *ctx = NULL; + int out_len; /* not used, required by NSS */ + bool rv = FALSE; + + /* use internal slot for DES encryption (requires NSS to be initialized) */ + PK11SlotInfo *slot = PK11_GetInternalKeySlot(); + if(!slot) + return FALSE; + + /* Expand the 56-bit key to 64-bits */ + extend_key_56_to_64(key_56, key); + + /* Set the key parity to odd */ + Curl_des_set_odd_parity((unsigned char *) key, sizeof(key)); + + /* Import the key */ + key_item.data = (unsigned char *)key; + key_item.len = sizeof(key); + symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT, + &key_item, NULL); + if(!symkey) + goto fail; + + /* Create the DES encryption context */ + param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL); + if(!param) + goto fail; + ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param); + if(!ctx) + goto fail; + + /* Perform the encryption */ + if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8, + (unsigned char *)in, /* inbuflen */ 8) + && SECSuccess == PK11_Finalize(ctx)) + rv = /* all OK */ TRUE; + +fail: + /* cleanup */ + if(ctx) + PK11_DestroyContext(ctx, PR_TRUE); + if(symkey) + PK11_FreeSymKey(symkey); + if(param) + SECITEM_FreeItem(param, PR_TRUE); + PK11_FreeSlot(slot); + return rv; +} + +#elif defined(USE_MBEDTLS) + +static bool encrypt_des(const unsigned char *in, unsigned char *out, + const unsigned char *key_56) +{ + mbedtls_des_context ctx; + char key[8]; + + /* Expand the 56-bit key to 64-bits */ + extend_key_56_to_64(key_56, key); + + /* Set the key parity to odd */ + mbedtls_des_key_set_parity((unsigned char *) key); + + /* Perform the encryption */ + mbedtls_des_init(&ctx); + mbedtls_des_setkey_enc(&ctx, (unsigned char *) key); + return mbedtls_des_crypt_ecb(&ctx, in, out) == 0; +} + +#elif defined(USE_SECTRANSP) + +static bool encrypt_des(const unsigned char *in, unsigned char *out, + const unsigned char *key_56) +{ + char key[8]; + size_t out_len; + CCCryptorStatus err; + + /* Expand the 56-bit key to 64-bits */ + extend_key_56_to_64(key_56, key); + + /* Set the key parity to odd */ + Curl_des_set_odd_parity((unsigned char *) key, sizeof(key)); + + /* Perform the encryption */ + err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key, + kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out, + 8 /* outbuflen */, &out_len); + + return err == kCCSuccess; +} + +#elif defined(USE_OS400CRYPTO) + +static bool encrypt_des(const unsigned char *in, unsigned char *out, + const unsigned char *key_56) +{ + char key[8]; + _CIPHER_Control_T ctl; + + /* Setup the cipher control structure */ + ctl.Func_ID = ENCRYPT_ONLY; + ctl.Data_Len = sizeof(key); + + /* Expand the 56-bit key to 64-bits */ + extend_key_56_to_64(key_56, ctl.Crypto_Key); + + /* Set the key parity to odd */ + Curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len); + + /* Perform the encryption */ + _CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in); + + return TRUE; +} + +#elif defined(USE_WIN32_CRYPTO) + +static bool encrypt_des(const unsigned char *in, unsigned char *out, + const unsigned char *key_56) +{ + HCRYPTPROV hprov; + HCRYPTKEY hkey; + struct { + BLOBHEADER hdr; + unsigned int len; + char key[8]; + } blob; + DWORD len = 8; + + /* Acquire the crypto provider */ + if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) + return FALSE; + + /* Setup the key blob structure */ + memset(&blob, 0, sizeof(blob)); + blob.hdr.bType = PLAINTEXTKEYBLOB; + blob.hdr.bVersion = 2; + blob.hdr.aiKeyAlg = CALG_DES; + blob.len = sizeof(blob.key); + + /* Expand the 56-bit key to 64-bits */ + extend_key_56_to_64(key_56, blob.key); + + /* Set the key parity to odd */ + Curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key)); + + /* Import the key */ + if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) { + CryptReleaseContext(hprov, 0); + + return FALSE; + } + + memcpy(out, in, 8); + + /* Perform the encryption */ + CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len); + + CryptDestroyKey(hkey); + CryptReleaseContext(hprov, 0); + + return TRUE; +} + +#endif /* defined(USE_WIN32_CRYPTO) */ + + /* + * takes a 21 byte array and treats it as 3 56-bit DES keys. The + * 8 byte plaintext is encrypted with each key and the resulting 24 + * bytes are stored in the results array. + */ +void Curl_ntlm_core_lm_resp(const unsigned char *keys, + const unsigned char *plaintext, + unsigned char *results) +{ +#ifdef USE_OPENSSL + DES_key_schedule ks; + + setup_des_key(keys, DESKEY(ks)); + DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results, + DESKEY(ks), DES_ENCRYPT); + + setup_des_key(keys + 7, DESKEY(ks)); + DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 8), + DESKEY(ks), DES_ENCRYPT); + + setup_des_key(keys + 14, DESKEY(ks)); + DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16), + DESKEY(ks), DES_ENCRYPT); +#elif defined(USE_GNUTLS_NETTLE) + struct des_ctx des; + setup_des_key(keys, &des); + des_encrypt(&des, 8, results, plaintext); + setup_des_key(keys + 7, &des); + des_encrypt(&des, 8, results + 8, plaintext); + setup_des_key(keys + 14, &des); + des_encrypt(&des, 8, results + 16, plaintext); +#elif defined(USE_GNUTLS) + gcry_cipher_hd_t des; + + gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); + setup_des_key(keys, &des); + gcry_cipher_encrypt(des, results, 8, plaintext, 8); + gcry_cipher_close(des); + + gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); + setup_des_key(keys + 7, &des); + gcry_cipher_encrypt(des, results + 8, 8, plaintext, 8); + gcry_cipher_close(des); + + gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); + setup_des_key(keys + 14, &des); + gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8); + gcry_cipher_close(des); +#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ + || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) + encrypt_des(plaintext, results, keys); + encrypt_des(plaintext, results + 8, keys + 7); + encrypt_des(plaintext, results + 16, keys + 14); +#endif +} + +/* + * Set up lanmanager hashed password + */ +CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data, + const char *password, + unsigned char *lmbuffer /* 21 bytes */) +{ + CURLcode result; + unsigned char pw[14]; + static const unsigned char magic[] = { + 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */ + }; + size_t len = CURLMIN(strlen(password), 14); + + Curl_strntoupper((char *)pw, password, len); + memset(&pw[len], 0, 14 - len); + + /* + * The LanManager hashed password needs to be created using the + * password in the network encoding not the host encoding. + */ + result = Curl_convert_to_network(data, (char *)pw, 14); + if(result) + return result; + + { + /* Create LanManager hashed password. */ + +#ifdef USE_OPENSSL + DES_key_schedule ks; + + setup_des_key(pw, DESKEY(ks)); + DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer, + DESKEY(ks), DES_ENCRYPT); + + setup_des_key(pw + 7, DESKEY(ks)); + DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8), + DESKEY(ks), DES_ENCRYPT); +#elif defined(USE_GNUTLS_NETTLE) + struct des_ctx des; + setup_des_key(pw, &des); + des_encrypt(&des, 8, lmbuffer, magic); + setup_des_key(pw + 7, &des); + des_encrypt(&des, 8, lmbuffer + 8, magic); +#elif defined(USE_GNUTLS) + gcry_cipher_hd_t des; + + gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); + setup_des_key(pw, &des); + gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8); + gcry_cipher_close(des); + + gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); + setup_des_key(pw + 7, &des); + gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8); + gcry_cipher_close(des); +#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ + || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) + encrypt_des(magic, lmbuffer, pw); + encrypt_des(magic, lmbuffer + 8, pw + 7); +#endif + + memset(lmbuffer + 16, 0, 21 - 16); + } + + return CURLE_OK; +} + +#ifdef USE_NTRESPONSES +static void ascii_to_unicode_le(unsigned char *dest, const char *src, + size_t srclen) +{ + size_t i; + for(i = 0; i < srclen; i++) { + dest[2 * i] = (unsigned char)src[i]; + dest[2 * i + 1] = '\0'; + } +} + +#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI) + +static void ascii_uppercase_to_unicode_le(unsigned char *dest, + const char *src, size_t srclen) +{ + size_t i; + for(i = 0; i < srclen; i++) { + dest[2 * i] = (unsigned char)(Curl_raw_toupper(src[i])); + dest[2 * i + 1] = '\0'; + } +} + +#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */ + +/* + * Set up nt hashed passwords + * @unittest: 1600 + */ +CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data, + const char *password, + unsigned char *ntbuffer /* 21 bytes */) +{ + size_t len = strlen(password); + unsigned char *pw; + CURLcode result; + if(len > SIZE_T_MAX/2) /* avoid integer overflow */ + return CURLE_OUT_OF_MEMORY; + pw = len ? malloc(len * 2) : strdup(""); + if(!pw) + return CURLE_OUT_OF_MEMORY; + + ascii_to_unicode_le(pw, password, len); + + /* + * The NT hashed password needs to be created using the password in the + * network encoding not the host encoding. + */ + result = Curl_convert_to_network(data, (char *)pw, len * 2); + if(result) + return result; + + { + /* Create NT hashed password. */ +#ifdef USE_OPENSSL +#if !defined(OPENSSL_NO_MD4) + MD4_CTX MD4pw; + MD4_Init(&MD4pw); + MD4_Update(&MD4pw, pw, 2 * len); + MD4_Final(ntbuffer, &MD4pw); +#else + Curl_md4it(ntbuffer, pw, 2 * len); +#endif +#elif defined(USE_GNUTLS_NETTLE) + struct md4_ctx MD4pw; + md4_init(&MD4pw); + md4_update(&MD4pw, (unsigned int)(2 * len), pw); + md4_digest(&MD4pw, MD4_DIGEST_SIZE, ntbuffer); +#elif defined(USE_GNUTLS) + gcry_md_hd_t MD4pw; + gcry_md_open(&MD4pw, GCRY_MD_MD4, 0); + gcry_md_write(MD4pw, pw, 2 * len); + memcpy(ntbuffer, gcry_md_read(MD4pw, 0), MD4_DIGEST_LENGTH); + gcry_md_close(MD4pw); +#elif defined(USE_NSS) + Curl_md4it(ntbuffer, pw, 2 * len); +#elif defined(USE_MBEDTLS) +#if defined(MBEDTLS_MD4_C) + mbedtls_md4(pw, 2 * len, ntbuffer); +#else + Curl_md4it(ntbuffer, pw, 2 * len); +#endif +#elif defined(USE_SECTRANSP) + (void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer); +#elif defined(USE_OS400CRYPTO) + Curl_md4it(ntbuffer, pw, 2 * len); +#elif defined(USE_WIN32_CRYPTO) + HCRYPTPROV hprov; + if(CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) { + HCRYPTHASH hhash; + if(CryptCreateHash(hprov, CALG_MD4, 0, 0, &hhash)) { + DWORD length = 16; + CryptHashData(hhash, pw, (unsigned int)len * 2, 0); + CryptGetHashParam(hhash, HP_HASHVAL, ntbuffer, &length, 0); + CryptDestroyHash(hhash); + } + CryptReleaseContext(hprov, 0); + } +#endif + + memset(ntbuffer + 16, 0, 21 - 16); + } + + free(pw); + + return CURLE_OK; +} + +#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI) + +/* This returns the HMAC MD5 digest */ +static CURLcode hmac_md5(const unsigned char *key, unsigned int keylen, + const unsigned char *data, unsigned int datalen, + unsigned char *output) +{ + HMAC_context *ctxt = Curl_HMAC_init(Curl_HMAC_MD5, key, keylen); + + if(!ctxt) + return CURLE_OUT_OF_MEMORY; + + /* Update the digest with the given challenge */ + Curl_HMAC_update(ctxt, data, datalen); + + /* Finalise the digest */ + Curl_HMAC_final(ctxt, output); + + return CURLE_OK; +} + +/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode + * (uppercase UserName + Domain) as the data + */ +CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen, + const char *domain, size_t domlen, + unsigned char *ntlmhash, + unsigned char *ntlmv2hash) +{ + /* Unicode representation */ + size_t identity_len; + unsigned char *identity; + CURLcode result = CURLE_OK; + + /* we do the length checks below separately to avoid integer overflow risk + on extreme data lengths */ + if((userlen > SIZE_T_MAX/2) || + (domlen > SIZE_T_MAX/2) || + ((userlen + domlen) > SIZE_T_MAX/2)) + return CURLE_OUT_OF_MEMORY; + + identity_len = (userlen + domlen) * 2; + identity = malloc(identity_len); + + if(!identity) + return CURLE_OUT_OF_MEMORY; + + ascii_uppercase_to_unicode_le(identity, user, userlen); + ascii_to_unicode_le(identity + (userlen << 1), domain, domlen); + + result = hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len), + ntlmv2hash); + free(identity); + + return result; +} + +/* + * Curl_ntlm_core_mk_ntlmv2_resp() + * + * This creates the NTLMv2 response as set in the ntlm type-3 message. + * + * Parameters: + * + * ntlmv2hash [in] - The ntlmv2 hash (16 bytes) + * challenge_client [in] - The client nonce (8 bytes) + * ntlm [in] - The ntlm data struct being used to read TargetInfo + and Server challenge received in the type-2 message + * ntresp [out] - The address where a pointer to newly allocated + * memory holding the NTLMv2 response. + * ntresp_len [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash, + unsigned char *challenge_client, + struct ntlmdata *ntlm, + unsigned char **ntresp, + unsigned int *ntresp_len) +{ +/* NTLMv2 response structure : +------------------------------------------------------------------------------ +0 HMAC MD5 16 bytes +------BLOB-------------------------------------------------------------------- +16 Signature 0x01010000 +20 Reserved long (0x00000000) +24 Timestamp LE, 64-bit signed value representing the number of + tenths of a microsecond since January 1, 1601. +32 Client Nonce 8 bytes +40 Unknown 4 bytes +44 Target Info N bytes (from the type-2 message) +44+N Unknown 4 bytes +------------------------------------------------------------------------------ +*/ + + unsigned int len = 0; + unsigned char *ptr = NULL; + unsigned char hmac_output[NTLM_HMAC_MD5_LEN]; + curl_off_t tw; + + CURLcode result = CURLE_OK; + +#if CURL_SIZEOF_CURL_OFF_T < 8 +#error "this section needs 64bit support to work" +#endif + + /* Calculate the timestamp */ +#ifdef DEBUGBUILD + char *force_timestamp = getenv("CURL_FORCETIME"); + if(force_timestamp) + tw = CURL_OFF_T_C(11644473600) * 10000000; + else +#endif + tw = ((curl_off_t)time(NULL) + CURL_OFF_T_C(11644473600)) * 10000000; + + /* Calculate the response len */ + len = NTLM_HMAC_MD5_LEN + NTLMv2_BLOB_LEN; + + /* Allocate the response */ + ptr = calloc(1, len); + if(!ptr) + return CURLE_OUT_OF_MEMORY; + + /* Create the BLOB structure */ + msnprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN, + "%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */ + "%c%c%c%c", /* Reserved = 0 */ + NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1], + NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3], + 0, 0, 0, 0); + + Curl_write64_le(tw, ptr + 24); + memcpy(ptr + 32, challenge_client, 8); + memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len); + + /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */ + memcpy(ptr + 8, &ntlm->nonce[0], 8); + result = hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8, + NTLMv2_BLOB_LEN + 8, hmac_output); + if(result) { + free(ptr); + return result; + } + + /* Concatenate the HMAC MD5 output with the BLOB */ + memcpy(ptr, hmac_output, NTLM_HMAC_MD5_LEN); + + /* Return the response */ + *ntresp = ptr; + *ntresp_len = len; + + return result; +} + +/* + * Curl_ntlm_core_mk_lmv2_resp() + * + * This creates the LMv2 response as used in the ntlm type-3 message. + * + * Parameters: + * + * ntlmv2hash [in] - The ntlmv2 hash (16 bytes) + * challenge_client [in] - The client nonce (8 bytes) + * challenge_client [in] - The server challenge (8 bytes) + * lmresp [out] - The LMv2 response (24 bytes) + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash, + unsigned char *challenge_client, + unsigned char *challenge_server, + unsigned char *lmresp) +{ + unsigned char data[16]; + unsigned char hmac_output[16]; + CURLcode result = CURLE_OK; + + memcpy(&data[0], challenge_server, 8); + memcpy(&data[8], challenge_client, 8); + + result = hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output); + if(result) + return result; + + /* Concatenate the HMAC MD5 output with the client nonce */ + memcpy(lmresp, hmac_output, 16); + memcpy(lmresp + 16, challenge_client, 8); + + return result; +} + +#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */ + +#endif /* USE_NTRESPONSES */ + +#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */ + +#endif /* USE_NTLM */ diff --git a/libcurl/lib/curl_ntlm_core.h b/libcurl/lib/curl_ntlm_core.h new file mode 100644 index 0000000..3b4b805 --- /dev/null +++ b/libcurl/lib/curl_ntlm_core.h @@ -0,0 +1,105 @@ +#ifndef HEADER_CURL_NTLM_CORE_H +#define HEADER_CURL_NTLM_CORE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_NTLM) + +/* If NSS is the first available SSL backend (see order in curl_ntlm_core.c) + then it must be initialized to be used by NTLM. */ +#if !defined(USE_OPENSSL) && \ + !defined(USE_GNUTLS_NETTLE) && \ + !defined(USE_GNUTLS) && \ + defined(USE_NSS) +#define NTLM_NEEDS_NSS_INIT +#endif + +#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO) + +#ifdef USE_OPENSSL +# include +#endif + +/* Define USE_NTRESPONSES in order to make the type-3 message include + * the NT response message. */ +#define USE_NTRESPONSES + +/* Define USE_NTLM2SESSION in order to make the type-3 message include the + NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a + Crypto engine that we have curl_ssl_md5sum() for. */ +#if defined(USE_NTRESPONSES) && !defined(USE_WIN32_CRYPTO) +#define USE_NTLM2SESSION +#endif + +/* Define USE_NTLM_V2 in order to allow the type-3 message to include the + LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1 + and support for 64-bit integers. */ +#if defined(USE_NTRESPONSES) && (CURL_SIZEOF_CURL_OFF_T > 4) +#define USE_NTLM_V2 +#endif + +void Curl_ntlm_core_lm_resp(const unsigned char *keys, + const unsigned char *plaintext, + unsigned char *results); + +CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data, + const char *password, + unsigned char *lmbuffer /* 21 bytes */); + +#ifdef USE_NTRESPONSES +CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data, + const char *password, + unsigned char *ntbuffer /* 21 bytes */); + +#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI) + +CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen, + const unsigned char *data, unsigned int datalen, + unsigned char *output); + +CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen, + const char *domain, size_t domlen, + unsigned char *ntlmhash, + unsigned char *ntlmv2hash); + +CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash, + unsigned char *challenge_client, + struct ntlmdata *ntlm, + unsigned char **ntresp, + unsigned int *ntresp_len); + +CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash, + unsigned char *challenge_client, + unsigned char *challenge_server, + unsigned char *lmresp); + +#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */ + +#endif /* USE_NTRESPONSES */ + +#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */ + +#endif /* USE_NTLM */ + +#endif /* HEADER_CURL_NTLM_CORE_H */ diff --git a/libcurl/lib/curl_ntlm_wb.c b/libcurl/lib/curl_ntlm_wb.c new file mode 100644 index 0000000..80266e2 --- /dev/null +++ b/libcurl/lib/curl_ntlm_wb.c @@ -0,0 +1,489 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ + defined(NTLM_WB_ENABLED) + +/* + * NTLM details: + * + * https://davenport.sourceforge.io/ntlm.html + * https://www.innovation.ch/java/ntlm.html + */ + +#define DEBUG_ME 0 + +#ifdef HAVE_SYS_WAIT_H +#include +#endif +#ifdef HAVE_SIGNAL_H +#include +#endif +#ifdef HAVE_PWD_H +#include +#endif + +#include "urldata.h" +#include "sendf.h" +#include "select.h" +#include "vauth/ntlm.h" +#include "curl_ntlm_core.h" +#include "curl_ntlm_wb.h" +#include "url.h" +#include "strerror.h" +#include "strdup.h" +#include "strcase.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#if DEBUG_ME +# define DEBUG_OUT(x) x +#else +# define DEBUG_OUT(x) Curl_nop_stmt +#endif + +/* Portable 'sclose_nolog' used only in child process instead of 'sclose' + to avoid fooling the socket leak detector */ +#if defined(HAVE_CLOSESOCKET) +# define sclose_nolog(x) closesocket((x)) +#elif defined(HAVE_CLOSESOCKET_CAMEL) +# define sclose_nolog(x) CloseSocket((x)) +#else +# define sclose_nolog(x) close((x)) +#endif + +void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn) +{ + if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) { + sclose(conn->ntlm_auth_hlpr_socket); + conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; + } + + if(conn->ntlm_auth_hlpr_pid) { + int i; + for(i = 0; i < 4; i++) { + pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG); + if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD) + break; + switch(i) { + case 0: + kill(conn->ntlm_auth_hlpr_pid, SIGTERM); + break; + case 1: + /* Give the process another moment to shut down cleanly before + bringing down the axe */ + Curl_wait_ms(1); + break; + case 2: + kill(conn->ntlm_auth_hlpr_pid, SIGKILL); + break; + case 3: + break; + } + } + conn->ntlm_auth_hlpr_pid = 0; + } + + free(conn->challenge_header); + conn->challenge_header = NULL; + free(conn->response_header); + conn->response_header = NULL; +} + +static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) +{ + curl_socket_t sockfds[2]; + pid_t child_pid; + const char *username; + char *slash, *domain = NULL; + const char *ntlm_auth = NULL; + char *ntlm_auth_alloc = NULL; +#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) + struct passwd pw, *pw_res; + char pwbuf[1024]; +#endif + char buffer[STRERROR_LEN]; + + /* Return if communication with ntlm_auth already set up */ + if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD || + conn->ntlm_auth_hlpr_pid) + return CURLE_OK; + + username = userp; + /* The real ntlm_auth really doesn't like being invoked with an + empty username. It won't make inferences for itself, and expects + the client to do so (mostly because it's really designed for + servers like squid to use for auth, and client support is an + afterthought for it). So try hard to provide a suitable username + if we don't already have one. But if we can't, provide the + empty one anyway. Perhaps they have an implementation of the + ntlm_auth helper which *doesn't* need it so we might as well try */ + if(!username || !username[0]) { + username = getenv("NTLMUSER"); + if(!username || !username[0]) + username = getenv("LOGNAME"); + if(!username || !username[0]) + username = getenv("USER"); +#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) + if((!username || !username[0]) && + !getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) && + pw_res) { + username = pw.pw_name; + } +#endif + if(!username || !username[0]) + username = userp; + } + slash = strpbrk(username, "\\/"); + if(slash) { + domain = strdup(username); + if(!domain) + return CURLE_OUT_OF_MEMORY; + slash = domain + (slash - username); + *slash = '\0'; + username = username + (slash - domain) + 1; + } + + /* For testing purposes, when DEBUGBUILD is defined and environment + variable CURL_NTLM_WB_FILE is set a fake_ntlm is used to perform + NTLM challenge/response which only accepts commands and output + strings pre-written in test case definitions */ +#ifdef DEBUGBUILD + ntlm_auth_alloc = curl_getenv("CURL_NTLM_WB_FILE"); + if(ntlm_auth_alloc) + ntlm_auth = ntlm_auth_alloc; + else +#endif + ntlm_auth = NTLM_WB_FILE; + + if(access(ntlm_auth, X_OK) != 0) { + failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s", + ntlm_auth, errno, Curl_strerror(errno, buffer, sizeof(buffer))); + goto done; + } + + if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) { + failf(conn->data, "Could not open socket pair. errno %d: %s", + errno, Curl_strerror(errno, buffer, sizeof(buffer))); + goto done; + } + + child_pid = fork(); + if(child_pid == -1) { + sclose(sockfds[0]); + sclose(sockfds[1]); + failf(conn->data, "Could not fork. errno %d: %s", + errno, Curl_strerror(errno, buffer, sizeof(buffer))); + goto done; + } + else if(!child_pid) { + /* + * child process + */ + + /* Don't use sclose in the child since it fools the socket leak detector */ + sclose_nolog(sockfds[0]); + if(dup2(sockfds[1], STDIN_FILENO) == -1) { + failf(conn->data, "Could not redirect child stdin. errno %d: %s", + errno, Curl_strerror(errno, buffer, sizeof(buffer))); + exit(1); + } + + if(dup2(sockfds[1], STDOUT_FILENO) == -1) { + failf(conn->data, "Could not redirect child stdout. errno %d: %s", + errno, Curl_strerror(errno, buffer, sizeof(buffer))); + exit(1); + } + + if(domain) + execl(ntlm_auth, ntlm_auth, + "--helper-protocol", "ntlmssp-client-1", + "--use-cached-creds", + "--username", username, + "--domain", domain, + NULL); + else + execl(ntlm_auth, ntlm_auth, + "--helper-protocol", "ntlmssp-client-1", + "--use-cached-creds", + "--username", username, + NULL); + + sclose_nolog(sockfds[1]); + failf(conn->data, "Could not execl(). errno %d: %s", + errno, Curl_strerror(errno, buffer, sizeof(buffer))); + exit(1); + } + + sclose(sockfds[1]); + conn->ntlm_auth_hlpr_socket = sockfds[0]; + conn->ntlm_auth_hlpr_pid = child_pid; + free(domain); + free(ntlm_auth_alloc); + return CURLE_OK; + +done: + free(domain); + free(ntlm_auth_alloc); + return CURLE_REMOTE_ACCESS_DENIED; +} + +/* if larger than this, something is seriously wrong */ +#define MAX_NTLM_WB_RESPONSE 100000 + +static CURLcode ntlm_wb_response(struct connectdata *conn, + const char *input, curlntlm state) +{ + char *buf = malloc(NTLM_BUFSIZE); + size_t len_in = strlen(input), len_out = 0; + + if(!buf) + return CURLE_OUT_OF_MEMORY; + + while(len_in > 0) { + ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in); + if(written == -1) { + /* Interrupted by a signal, retry it */ + if(errno == EINTR) + continue; + /* write failed if other errors happen */ + goto done; + } + input += written; + len_in -= written; + } + /* Read one line */ + while(1) { + ssize_t size; + char *newbuf; + + size = sread(conn->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE); + if(size == -1) { + if(errno == EINTR) + continue; + goto done; + } + else if(size == 0) + goto done; + + len_out += size; + if(buf[len_out - 1] == '\n') { + buf[len_out - 1] = '\0'; + break; + } + + if(len_out > MAX_NTLM_WB_RESPONSE) { + failf(conn->data, "too large ntlm_wb response!"); + free(buf); + return CURLE_OUT_OF_MEMORY; + } + + newbuf = Curl_saferealloc(buf, len_out + NTLM_BUFSIZE); + if(!newbuf) + return CURLE_OUT_OF_MEMORY; + + buf = newbuf; + } + + /* Samba/winbind installed but not configured */ + if(state == NTLMSTATE_TYPE1 && + len_out == 3 && + buf[0] == 'P' && buf[1] == 'W') + goto done; + /* invalid response */ + if(len_out < 4) + goto done; + if(state == NTLMSTATE_TYPE1 && + (buf[0]!='Y' || buf[1]!='R' || buf[2]!=' ')) + goto done; + if(state == NTLMSTATE_TYPE2 && + (buf[0]!='K' || buf[1]!='K' || buf[2]!=' ') && + (buf[0]!='A' || buf[1]!='F' || buf[2]!=' ')) + goto done; + + conn->response_header = aprintf("NTLM %.*s", len_out - 4, buf + 3); + free(buf); + if(!conn->response_header) + return CURLE_OUT_OF_MEMORY; + return CURLE_OK; +done: + free(buf); + return CURLE_REMOTE_ACCESS_DENIED; +} + +CURLcode Curl_input_ntlm_wb(struct connectdata *conn, + bool proxy, + const char *header) +{ + curlntlm *state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state; + + if(!checkprefix("NTLM", header)) + return CURLE_BAD_CONTENT_ENCODING; + + header += strlen("NTLM"); + while(*header && ISSPACE(*header)) + header++; + + if(*header) { + conn->challenge_header = strdup(header); + if(!conn->challenge_header) + return CURLE_OUT_OF_MEMORY; + + *state = NTLMSTATE_TYPE2; /* We got a type-2 message */ + } + else { + if(*state == NTLMSTATE_LAST) { + infof(conn->data, "NTLM auth restarted\n"); + Curl_http_auth_cleanup_ntlm_wb(conn); + } + else if(*state == NTLMSTATE_TYPE3) { + infof(conn->data, "NTLM handshake rejected\n"); + Curl_http_auth_cleanup_ntlm_wb(conn); + *state = NTLMSTATE_NONE; + return CURLE_REMOTE_ACCESS_DENIED; + } + else if(*state >= NTLMSTATE_TYPE1) { + infof(conn->data, "NTLM handshake failure (internal error)\n"); + return CURLE_REMOTE_ACCESS_DENIED; + } + + *state = NTLMSTATE_TYPE1; /* We should send away a type-1 */ + } + + return CURLE_OK; +} + +/* + * This is for creating ntlm header output by delegating challenge/response + * to Samba's winbind daemon helper ntlm_auth. + */ +CURLcode Curl_output_ntlm_wb(struct connectdata *conn, + bool proxy) +{ + /* point to the address of the pointer that holds the string to send to the + server, which is for a plain host or for a HTTP proxy */ + char **allocuserpwd; + /* point to the name and password for this */ + const char *userp; + curlntlm *state; + struct auth *authp; + + CURLcode res = CURLE_OK; + char *input; + + DEBUGASSERT(conn); + DEBUGASSERT(conn->data); + + if(proxy) { + allocuserpwd = &conn->allocptr.proxyuserpwd; + userp = conn->http_proxy.user; + state = &conn->proxy_ntlm_state; + authp = &conn->data->state.authproxy; + } + else { + allocuserpwd = &conn->allocptr.userpwd; + userp = conn->user; + state = &conn->http_ntlm_state; + authp = &conn->data->state.authhost; + } + authp->done = FALSE; + + /* not set means empty */ + if(!userp) + userp = ""; + + switch(*state) { + case NTLMSTATE_TYPE1: + default: + /* Use Samba's 'winbind' daemon to support NTLM authentication, + * by delegating the NTLM challenge/response protocol to a helper + * in ntlm_auth. + * http://devel.squid-cache.org/ntlm/squid_helper_protocol.html + * https://www.samba.org/samba/docs/man/manpages-3/winbindd.8.html + * https://www.samba.org/samba/docs/man/manpages-3/ntlm_auth.1.html + * Preprocessor symbol 'NTLM_WB_ENABLED' is defined when this + * feature is enabled and 'NTLM_WB_FILE' symbol holds absolute + * filename of ntlm_auth helper. + * If NTLM authentication using winbind fails, go back to original + * request handling process. + */ + /* Create communication with ntlm_auth */ + res = ntlm_wb_init(conn, userp); + if(res) + return res; + res = ntlm_wb_response(conn, "YR\n", *state); + if(res) + return res; + + free(*allocuserpwd); + *allocuserpwd = aprintf("%sAuthorization: %s\r\n", + proxy ? "Proxy-" : "", + conn->response_header); + DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd)); + free(conn->response_header); + if(!*allocuserpwd) + return CURLE_OUT_OF_MEMORY; + conn->response_header = NULL; + break; + + case NTLMSTATE_TYPE2: + input = aprintf("TT %s\n", conn->challenge_header); + if(!input) + return CURLE_OUT_OF_MEMORY; + res = ntlm_wb_response(conn, input, *state); + free(input); + input = NULL; + if(res) + return res; + + free(*allocuserpwd); + *allocuserpwd = aprintf("%sAuthorization: %s\r\n", + proxy ? "Proxy-" : "", + conn->response_header); + DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd)); + *state = NTLMSTATE_TYPE3; /* we sent a type-3 */ + authp->done = TRUE; + Curl_http_auth_cleanup_ntlm_wb(conn); + if(!*allocuserpwd) + return CURLE_OUT_OF_MEMORY; + break; + + case NTLMSTATE_TYPE3: + /* connection is already authenticated, + * don't send a header in future requests */ + *state = NTLMSTATE_LAST; + /* FALLTHROUGH */ + case NTLMSTATE_LAST: + Curl_safefree(*allocuserpwd); + authp->done = TRUE; + break; + } + + return CURLE_OK; +} + +#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */ diff --git a/libcurl/lib/curl_ntlm_wb.h b/libcurl/lib/curl_ntlm_wb.h new file mode 100644 index 0000000..3cf841c --- /dev/null +++ b/libcurl/lib/curl_ntlm_wb.h @@ -0,0 +1,41 @@ +#ifndef HEADER_CURL_NTLM_WB_H +#define HEADER_CURL_NTLM_WB_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ + defined(NTLM_WB_ENABLED) + +/* this is for ntlm header input */ +CURLcode Curl_input_ntlm_wb(struct connectdata *conn, bool proxy, + const char *header); + +/* this is for creating ntlm header output */ +CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy); + +void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn); + +#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */ + +#endif /* HEADER_CURL_NTLM_WB_H */ diff --git a/libcurl/lib/curl_path.c b/libcurl/lib/curl_path.c new file mode 100644 index 0000000..85dddce --- /dev/null +++ b/libcurl/lib/curl_path.c @@ -0,0 +1,199 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_SSH) + +#include +#include "curl_memory.h" +#include "curl_path.h" +#include "escape.h" +#include "memdebug.h" + +/* figure out the path to work with in this particular request */ +CURLcode Curl_getworkingpath(struct connectdata *conn, + char *homedir, /* when SFTP is used */ + char **path) /* returns the allocated + real path to work with */ +{ + struct Curl_easy *data = conn->data; + char *real_path = NULL; + char *working_path; + size_t working_path_len; + CURLcode result = + Curl_urldecode(data, data->state.up.path, 0, &working_path, + &working_path_len, FALSE); + if(result) + return result; + + /* Check for /~/, indicating relative to the user's home directory */ + if(conn->handler->protocol & CURLPROTO_SCP) { + real_path = malloc(working_path_len + 1); + if(real_path == NULL) { + free(working_path); + return CURLE_OUT_OF_MEMORY; + } + if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) + /* It is referenced to the home directory, so strip the leading '/~/' */ + memcpy(real_path, working_path + 3, 4 + working_path_len-3); + else + memcpy(real_path, working_path, 1 + working_path_len); + } + else if(conn->handler->protocol & CURLPROTO_SFTP) { + if((working_path_len > 1) && (working_path[1] == '~')) { + size_t homelen = strlen(homedir); + real_path = malloc(homelen + working_path_len + 1); + if(real_path == NULL) { + free(working_path); + return CURLE_OUT_OF_MEMORY; + } + /* It is referenced to the home directory, so strip the + leading '/' */ + memcpy(real_path, homedir, homelen); + real_path[homelen] = '/'; + real_path[homelen + 1] = '\0'; + if(working_path_len > 3) { + memcpy(real_path + homelen + 1, working_path + 3, + 1 + working_path_len -3); + } + } + else { + real_path = malloc(working_path_len + 1); + if(real_path == NULL) { + free(working_path); + return CURLE_OUT_OF_MEMORY; + } + memcpy(real_path, working_path, 1 + working_path_len); + } + } + + free(working_path); + + /* store the pointer for the caller to receive */ + *path = real_path; + + return CURLE_OK; +} + +/* The get_pathname() function is being borrowed from OpenSSH sftp.c + version 4.6p1. */ +/* + * Copyright (c) 2001-2004 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir) +{ + const char *cp = *cpp, *end; + char quot; + unsigned int i, j; + size_t fullPathLength, pathLength; + bool relativePath = false; + static const char WHITESPACE[] = " \t\r\n"; + + if(!*cp) { + *cpp = NULL; + *path = NULL; + return CURLE_QUOTE_ERROR; + } + /* Ignore leading whitespace */ + cp += strspn(cp, WHITESPACE); + /* Allocate enough space for home directory and filename + separator */ + fullPathLength = strlen(cp) + strlen(homedir) + 2; + *path = malloc(fullPathLength); + if(*path == NULL) + return CURLE_OUT_OF_MEMORY; + + /* Check for quoted filenames */ + if(*cp == '\"' || *cp == '\'') { + quot = *cp++; + + /* Search for terminating quote, unescape some chars */ + for(i = j = 0; i <= strlen(cp); i++) { + if(cp[i] == quot) { /* Found quote */ + i++; + (*path)[j] = '\0'; + break; + } + if(cp[i] == '\0') { /* End of string */ + /*error("Unterminated quote");*/ + goto fail; + } + if(cp[i] == '\\') { /* Escaped characters */ + i++; + if(cp[i] != '\'' && cp[i] != '\"' && + cp[i] != '\\') { + /*error("Bad escaped character '\\%c'", + cp[i]);*/ + goto fail; + } + } + (*path)[j++] = cp[i]; + } + + if(j == 0) { + /*error("Empty quotes");*/ + goto fail; + } + *cpp = cp + i + strspn(cp + i, WHITESPACE); + } + else { + /* Read to end of filename - either to white space or terminator */ + end = strpbrk(cp, WHITESPACE); + if(end == NULL) + end = strchr(cp, '\0'); + /* return pointer to second parameter if it exists */ + *cpp = end + strspn(end, WHITESPACE); + pathLength = 0; + relativePath = (cp[0] == '/' && cp[1] == '~' && cp[2] == '/'); + /* Handling for relative path - prepend home directory */ + if(relativePath) { + strcpy(*path, homedir); + pathLength = strlen(homedir); + (*path)[pathLength++] = '/'; + (*path)[pathLength] = '\0'; + cp += 3; + } + /* Copy path name up until first "white space" */ + memcpy(&(*path)[pathLength], cp, (int)(end - cp)); + pathLength += (int)(end - cp); + (*path)[pathLength] = '\0'; + } + return CURLE_OK; + + fail: + Curl_safefree(*path); + return CURLE_QUOTE_ERROR; +} + +#endif /* if SSH is used */ diff --git a/libcurl/lib/curl_path.h b/libcurl/lib/curl_path.h new file mode 100644 index 0000000..636c37f --- /dev/null +++ b/libcurl/lib/curl_path.h @@ -0,0 +1,47 @@ +#ifndef HEADER_CURL_PATH_H +#define HEADER_CURL_PATH_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include +#include "urldata.h" + +#ifdef WIN32 +# undef PATH_MAX +# define PATH_MAX MAX_PATH +# ifndef R_OK +# define R_OK 4 +# endif +#endif + +#ifndef PATH_MAX +#define PATH_MAX 1024 /* just an extra precaution since there are systems that + have their definition hidden well */ +#endif + +CURLcode Curl_getworkingpath(struct connectdata *conn, + char *homedir, + char **path); + +CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir); +#endif /* HEADER_CURL_PATH_H */ diff --git a/libcurl/lib/curl_printf.h b/libcurl/lib/curl_printf.h new file mode 100644 index 0000000..0d37b8e --- /dev/null +++ b/libcurl/lib/curl_printf.h @@ -0,0 +1,48 @@ +#ifndef HEADER_CURL_PRINTF_H +#define HEADER_CURL_PRINTF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * This header should be included by ALL code in libcurl that uses any + * *rintf() functions. + */ + +#include + +# undef printf +# undef fprintf +# undef msnprintf +# undef vprintf +# undef vfprintf +# undef vsnprintf +# undef aprintf +# undef vaprintf +# define printf curl_mprintf +# define fprintf curl_mfprintf +# define msnprintf curl_msnprintf +# define vprintf curl_mvprintf +# define vfprintf curl_mvfprintf +# define mvsnprintf curl_mvsnprintf +# define aprintf curl_maprintf +# define vaprintf curl_mvaprintf +#endif /* HEADER_CURL_PRINTF_H */ diff --git a/libcurl/lib/curl_range.c b/libcurl/lib/curl_range.c new file mode 100644 index 0000000..aa3c493 --- /dev/null +++ b/libcurl/lib/curl_range.c @@ -0,0 +1,95 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include +#include "curl_range.h" +#include "sendf.h" +#include "strtoofft.h" + +/* Only include this function if one or more of FTP, FILE are enabled. */ +#if !defined(CURL_DISABLE_FTP) || !defined(CURL_DISABLE_FILE) + + /* + Check if this is a range download, and if so, set the internal variables + properly. + */ +CURLcode Curl_range(struct connectdata *conn) +{ + curl_off_t from, to; + char *ptr; + char *ptr2; + struct Curl_easy *data = conn->data; + + if(data->state.use_range && data->state.range) { + CURLofft from_t; + CURLofft to_t; + from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from); + if(from_t == CURL_OFFT_FLOW) + return CURLE_RANGE_ERROR; + while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) + ptr++; + to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); + if(to_t == CURL_OFFT_FLOW) + return CURLE_RANGE_ERROR; + if((to_t == CURL_OFFT_INVAL) && !from_t) { + /* X - */ + data->state.resume_from = from; + DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n", + from)); + } + else if((from_t == CURL_OFFT_INVAL) && !to_t) { + /* -Y */ + data->req.maxdownload = to; + data->state.resume_from = -to; + DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n", + to)); + } + else { + /* X-Y */ + curl_off_t totalsize; + + /* Ensure the range is sensible - to should follow from. */ + if(from > to) + return CURLE_RANGE_ERROR; + + totalsize = to - from; + if(totalsize == CURL_OFF_T_MAX) + return CURLE_RANGE_ERROR; + + data->req.maxdownload = totalsize + 1; /* include last byte */ + data->state.resume_from = from; + DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T + " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n", + from, data->req.maxdownload)); + } + DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T + " to %" CURL_FORMAT_CURL_OFF_T ", totally %" + CURL_FORMAT_CURL_OFF_T " bytes\n", + from, to, data->req.maxdownload)); + } + else + data->req.maxdownload = -1; + return CURLE_OK; +} + +#endif diff --git a/libcurl/lib/curl_range.h b/libcurl/lib/curl_range.h new file mode 100644 index 0000000..2350df9 --- /dev/null +++ b/libcurl/lib/curl_range.h @@ -0,0 +1,30 @@ +#ifndef HEADER_CURL_RANGE_H +#define HEADER_CURL_RANGE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include "urldata.h" + +CURLcode Curl_range(struct connectdata *conn); + +#endif /* HEADER_CURL_RANGE_H */ diff --git a/libcurl/lib/curl_rtmp.c b/libcurl/lib/curl_rtmp.c new file mode 100644 index 0000000..16b1de1 --- /dev/null +++ b/libcurl/lib/curl_rtmp.c @@ -0,0 +1,316 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 2010, Howard Chu, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_LIBRTMP + +#include "curl_rtmp.h" +#include "urldata.h" +#include "nonblock.h" /* for curlx_nonblock */ +#include "progress.h" /* for Curl_pgrsSetUploadSize */ +#include "transfer.h" +#include "warnless.h" +#include +#include +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +#if defined(WIN32) && !defined(USE_LWIPSOCK) +#define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e) +#define SET_RCVTIMEO(tv,s) int tv = s*1000 +#elif defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) +#define SET_RCVTIMEO(tv,s) int tv = s*1000 +#else +#define SET_RCVTIMEO(tv,s) struct timeval tv = {s,0} +#endif + +#define DEF_BUFTIME (2*60*60*1000) /* 2 hours */ + +static CURLcode rtmp_setup_connection(struct connectdata *conn); +static CURLcode rtmp_do(struct connectdata *conn, bool *done); +static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature); +static CURLcode rtmp_connect(struct connectdata *conn, bool *done); +static CURLcode rtmp_disconnect(struct connectdata *conn, bool dead); + +static Curl_recv rtmp_recv; +static Curl_send rtmp_send; + +/* + * RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu + */ + +const struct Curl_handler Curl_handler_rtmp = { + "RTMP", /* scheme */ + rtmp_setup_connection, /* setup_connection */ + rtmp_do, /* do_it */ + rtmp_done, /* done */ + ZERO_NULL, /* do_more */ + rtmp_connect, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + rtmp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_RTMP, /* defport */ + CURLPROTO_RTMP, /* protocol */ + PROTOPT_NONE /* flags*/ +}; + +const struct Curl_handler Curl_handler_rtmpt = { + "RTMPT", /* scheme */ + rtmp_setup_connection, /* setup_connection */ + rtmp_do, /* do_it */ + rtmp_done, /* done */ + ZERO_NULL, /* do_more */ + rtmp_connect, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + rtmp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_RTMPT, /* defport */ + CURLPROTO_RTMPT, /* protocol */ + PROTOPT_NONE /* flags*/ +}; + +const struct Curl_handler Curl_handler_rtmpe = { + "RTMPE", /* scheme */ + rtmp_setup_connection, /* setup_connection */ + rtmp_do, /* do_it */ + rtmp_done, /* done */ + ZERO_NULL, /* do_more */ + rtmp_connect, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + rtmp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_RTMP, /* defport */ + CURLPROTO_RTMPE, /* protocol */ + PROTOPT_NONE /* flags*/ +}; + +const struct Curl_handler Curl_handler_rtmpte = { + "RTMPTE", /* scheme */ + rtmp_setup_connection, /* setup_connection */ + rtmp_do, /* do_it */ + rtmp_done, /* done */ + ZERO_NULL, /* do_more */ + rtmp_connect, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + rtmp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_RTMPT, /* defport */ + CURLPROTO_RTMPTE, /* protocol */ + PROTOPT_NONE /* flags*/ +}; + +const struct Curl_handler Curl_handler_rtmps = { + "RTMPS", /* scheme */ + rtmp_setup_connection, /* setup_connection */ + rtmp_do, /* do_it */ + rtmp_done, /* done */ + ZERO_NULL, /* do_more */ + rtmp_connect, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + rtmp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_RTMPS, /* defport */ + CURLPROTO_RTMPS, /* protocol */ + PROTOPT_NONE /* flags*/ +}; + +const struct Curl_handler Curl_handler_rtmpts = { + "RTMPTS", /* scheme */ + rtmp_setup_connection, /* setup_connection */ + rtmp_do, /* do_it */ + rtmp_done, /* done */ + ZERO_NULL, /* do_more */ + rtmp_connect, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + rtmp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_RTMPS, /* defport */ + CURLPROTO_RTMPTS, /* protocol */ + PROTOPT_NONE /* flags*/ +}; + +static CURLcode rtmp_setup_connection(struct connectdata *conn) +{ + RTMP *r = RTMP_Alloc(); + if(!r) + return CURLE_OUT_OF_MEMORY; + + RTMP_Init(r); + RTMP_SetBufferMS(r, DEF_BUFTIME); + if(!RTMP_SetupURL(r, conn->data->change.url)) { + RTMP_Free(r); + return CURLE_URL_MALFORMAT; + } + conn->proto.generic = r; + return CURLE_OK; +} + +static CURLcode rtmp_connect(struct connectdata *conn, bool *done) +{ + RTMP *r = conn->proto.generic; + SET_RCVTIMEO(tv, 10); + + r->m_sb.sb_socket = (int)conn->sock[FIRSTSOCKET]; + + /* We have to know if it's a write before we send the + * connect request packet + */ + if(conn->data->set.upload) + r->Link.protocol |= RTMP_FEATURE_WRITE; + + /* For plain streams, use the buffer toggle trick to keep data flowing */ + if(!(r->Link.lFlags & RTMP_LF_LIVE) && + !(r->Link.protocol & RTMP_FEATURE_HTTP)) + r->Link.lFlags |= RTMP_LF_BUFX; + + (void)curlx_nonblock(r->m_sb.sb_socket, FALSE); + setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO, + (char *)&tv, sizeof(tv)); + + if(!RTMP_Connect1(r, NULL)) + return CURLE_FAILED_INIT; + + /* Clients must send a periodic BytesReceived report to the server */ + r->m_bSendCounter = true; + + *done = TRUE; + conn->recv[FIRSTSOCKET] = rtmp_recv; + conn->send[FIRSTSOCKET] = rtmp_send; + return CURLE_OK; +} + +static CURLcode rtmp_do(struct connectdata *conn, bool *done) +{ + struct Curl_easy *data = conn->data; + RTMP *r = conn->proto.generic; + + if(!RTMP_ConnectStream(r, 0)) + return CURLE_FAILED_INIT; + + if(conn->data->set.upload) { + Curl_pgrsSetUploadSize(data, data->state.infilesize); + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); + } + else + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); + *done = TRUE; + return CURLE_OK; +} + +static CURLcode rtmp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + (void)conn; /* unused */ + (void)status; /* unused */ + (void)premature; /* unused */ + + return CURLE_OK; +} + +static CURLcode rtmp_disconnect(struct connectdata *conn, + bool dead_connection) +{ + RTMP *r = conn->proto.generic; + (void)dead_connection; + if(r) { + conn->proto.generic = NULL; + RTMP_Close(r); + RTMP_Free(r); + } + return CURLE_OK; +} + +static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf, + size_t len, CURLcode *err) +{ + RTMP *r = conn->proto.generic; + ssize_t nread; + + (void)sockindex; /* unused */ + + nread = RTMP_Read(r, buf, curlx_uztosi(len)); + if(nread < 0) { + if(r->m_read.status == RTMP_READ_COMPLETE || + r->m_read.status == RTMP_READ_EOF) { + conn->data->req.size = conn->data->req.bytecount; + nread = 0; + } + else + *err = CURLE_RECV_ERROR; + } + return nread; +} + +static ssize_t rtmp_send(struct connectdata *conn, int sockindex, + const void *buf, size_t len, CURLcode *err) +{ + RTMP *r = conn->proto.generic; + ssize_t num; + + (void)sockindex; /* unused */ + + num = RTMP_Write(r, (char *)buf, curlx_uztosi(len)); + if(num < 0) + *err = CURLE_SEND_ERROR; + + return num; +} +#endif /* USE_LIBRTMP */ diff --git a/libcurl/lib/curl_rtmp.h b/libcurl/lib/curl_rtmp.h new file mode 100644 index 0000000..3306e22 --- /dev/null +++ b/libcurl/lib/curl_rtmp.h @@ -0,0 +1,33 @@ +#ifndef HEADER_CURL_RTMP_H +#define HEADER_CURL_RTMP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2010, Howard Chu, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifdef USE_LIBRTMP +extern const struct Curl_handler Curl_handler_rtmp; +extern const struct Curl_handler Curl_handler_rtmpt; +extern const struct Curl_handler Curl_handler_rtmpe; +extern const struct Curl_handler Curl_handler_rtmpte; +extern const struct Curl_handler Curl_handler_rtmps; +extern const struct Curl_handler Curl_handler_rtmpts; +#endif + +#endif /* HEADER_CURL_RTMP_H */ diff --git a/libcurl/lib/curl_sasl.c b/libcurl/lib/curl_sasl.c new file mode 100644 index 0000000..018e422 --- /dev/null +++ b/libcurl/lib/curl_sasl.c @@ -0,0 +1,629 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC2195 CRAM-MD5 authentication + * RFC2617 Basic and Digest Access Authentication + * RFC2831 DIGEST-MD5 authentication + * RFC4422 Simple Authentication and Security Layer (SASL) + * RFC4616 PLAIN authentication + * RFC6749 OAuth 2.0 Authorization Framework + * RFC7628 A Set of SASL Mechanisms for OAuth + * Draft LOGIN SASL Mechanism + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \ + !defined(CURL_DISABLE_POP3) + +#include +#include "urldata.h" + +#include "curl_base64.h" +#include "curl_md5.h" +#include "vauth/vauth.h" +#include "vtls/vtls.h" +#include "curl_hmac.h" +#include "curl_sasl.h" +#include "warnless.h" +#include "strtok.h" +#include "sendf.h" +#include "non-ascii.h" /* included for Curl_convert_... prototypes */ +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* Supported mechanisms */ +static const struct { + const char *name; /* Name */ + size_t len; /* Name length */ + unsigned int bit; /* Flag bit */ +} mechtable[] = { + { "LOGIN", 5, SASL_MECH_LOGIN }, + { "PLAIN", 5, SASL_MECH_PLAIN }, + { "CRAM-MD5", 8, SASL_MECH_CRAM_MD5 }, + { "DIGEST-MD5", 10, SASL_MECH_DIGEST_MD5 }, + { "GSSAPI", 6, SASL_MECH_GSSAPI }, + { "EXTERNAL", 8, SASL_MECH_EXTERNAL }, + { "NTLM", 4, SASL_MECH_NTLM }, + { "XOAUTH2", 7, SASL_MECH_XOAUTH2 }, + { "OAUTHBEARER", 11, SASL_MECH_OAUTHBEARER }, + { ZERO_NULL, 0, 0 } +}; + +/* + * Curl_sasl_cleanup() + * + * This is used to cleanup any libraries or curl modules used by the sasl + * functions. + * + * Parameters: + * + * conn [in] - The connection data. + * authused [in] - The authentication mechanism used. + */ +void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused) +{ +#if defined(USE_KERBEROS5) + /* Cleanup the gssapi structure */ + if(authused == SASL_MECH_GSSAPI) { + Curl_auth_cleanup_gssapi(&conn->krb5); + } +#endif + +#if defined(USE_NTLM) + /* Cleanup the NTLM structure */ + if(authused == SASL_MECH_NTLM) { + Curl_auth_cleanup_ntlm(&conn->ntlm); + } +#endif + +#if !defined(USE_KERBEROS5) && !defined(USE_NTLM) + /* Reserved for future use */ + (void)conn; + (void)authused; +#endif +} + +/* + * Curl_sasl_decode_mech() + * + * Convert a SASL mechanism name into a token. + * + * Parameters: + * + * ptr [in] - The mechanism string. + * maxlen [in] - Maximum mechanism string length. + * len [out] - If not NULL, effective name length. + * + * Returns the SASL mechanism token or 0 if no match. + */ +unsigned int Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len) +{ + unsigned int i; + char c; + + for(i = 0; mechtable[i].name; i++) { + if(maxlen >= mechtable[i].len && + !memcmp(ptr, mechtable[i].name, mechtable[i].len)) { + if(len) + *len = mechtable[i].len; + + if(maxlen == mechtable[i].len) + return mechtable[i].bit; + + c = ptr[mechtable[i].len]; + if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_') + return mechtable[i].bit; + } + } + + return 0; +} + +/* + * Curl_sasl_parse_url_auth_option() + * + * Parse the URL login options. + */ +CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl, + const char *value, size_t len) +{ + CURLcode result = CURLE_OK; + size_t mechlen; + + if(!len) + return CURLE_URL_MALFORMAT; + + if(sasl->resetprefs) { + sasl->resetprefs = FALSE; + sasl->prefmech = SASL_AUTH_NONE; + } + + if(!strncmp(value, "*", len)) + sasl->prefmech = SASL_AUTH_DEFAULT; + else { + unsigned int mechbit = Curl_sasl_decode_mech(value, len, &mechlen); + if(mechbit && mechlen == len) + sasl->prefmech |= mechbit; + else + result = CURLE_URL_MALFORMAT; + } + + return result; +} + +/* + * Curl_sasl_init() + * + * Initializes the SASL structure. + */ +void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params) +{ + sasl->params = params; /* Set protocol dependent parameters */ + sasl->state = SASL_STOP; /* Not yet running */ + sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */ + sasl->prefmech = SASL_AUTH_DEFAULT; /* Prefer all mechanisms */ + sasl->authused = SASL_AUTH_NONE; /* No the authentication mechanism used */ + sasl->resetprefs = TRUE; /* Reset prefmech upon AUTH parsing. */ + sasl->mutual_auth = FALSE; /* No mutual authentication (GSSAPI only) */ + sasl->force_ir = FALSE; /* Respect external option */ +} + +/* + * state() + * + * This is the ONLY way to change SASL state! + */ +static void state(struct SASL *sasl, struct connectdata *conn, + saslstate newstate) +{ +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* for debug purposes */ + static const char * const names[]={ + "STOP", + "PLAIN", + "LOGIN", + "LOGIN_PASSWD", + "EXTERNAL", + "CRAMMD5", + "DIGESTMD5", + "DIGESTMD5_RESP", + "NTLM", + "NTLM_TYPE2MSG", + "GSSAPI", + "GSSAPI_TOKEN", + "GSSAPI_NO_DATA", + "OAUTH2", + "OAUTH2_RESP", + "CANCEL", + "FINAL", + /* LAST */ + }; + + if(sasl->state != newstate) + infof(conn->data, "SASL %p state change from %s to %s\n", + (void *)sasl, names[sasl->state], names[newstate]); +#else + (void) conn; +#endif + + sasl->state = newstate; +} + +/* + * Curl_sasl_can_authenticate() + * + * Check if we have enough auth data and capabilities to authenticate. + */ +bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn) +{ + /* Have credentials been provided? */ + if(conn->bits.user_passwd) + return TRUE; + + /* EXTERNAL can authenticate without a user name and/or password */ + if(sasl->authmechs & sasl->prefmech & SASL_MECH_EXTERNAL) + return TRUE; + + return FALSE; +} + +/* + * Curl_sasl_start() + * + * Calculate the required login details for SASL authentication. + */ +CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, + bool force_ir, saslprogress *progress) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + unsigned int enabledmechs; + const char *mech = NULL; + char *resp = NULL; + size_t len = 0; + saslstate state1 = SASL_STOP; + saslstate state2 = SASL_FINAL; + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; +#if defined(USE_KERBEROS5) || defined(USE_NTLM) + const char *service = data->set.str[STRING_SERVICE_NAME] ? + data->set.str[STRING_SERVICE_NAME] : + sasl->params->service; +#endif + + sasl->force_ir = force_ir; /* Latch for future use */ + sasl->authused = 0; /* No mechanism used yet */ + enabledmechs = sasl->authmechs & sasl->prefmech; + *progress = SASL_IDLE; + + /* Calculate the supported authentication mechanism, by decreasing order of + security, as well as the initial response where appropriate */ + if((enabledmechs & SASL_MECH_EXTERNAL) && !conn->passwd[0]) { + mech = SASL_MECH_STRING_EXTERNAL; + state1 = SASL_EXTERNAL; + sasl->authused = SASL_MECH_EXTERNAL; + + if(force_ir || data->set.sasl_ir) + result = Curl_auth_create_external_message(data, conn->user, &resp, + &len); + } + else if(conn->bits.user_passwd) { +#if defined(USE_KERBEROS5) + if((enabledmechs & SASL_MECH_GSSAPI) && Curl_auth_is_gssapi_supported() && + Curl_auth_user_contains_domain(conn->user)) { + sasl->mutual_auth = FALSE; + mech = SASL_MECH_STRING_GSSAPI; + state1 = SASL_GSSAPI; + state2 = SASL_GSSAPI_TOKEN; + sasl->authused = SASL_MECH_GSSAPI; + + if(force_ir || data->set.sasl_ir) + result = Curl_auth_create_gssapi_user_message(data, conn->user, + conn->passwd, + service, + data->conn->host.name, + sasl->mutual_auth, + NULL, &conn->krb5, + &resp, &len); + } + else +#endif +#ifndef CURL_DISABLE_CRYPTO_AUTH + if((enabledmechs & SASL_MECH_DIGEST_MD5) && + Curl_auth_is_digest_supported()) { + mech = SASL_MECH_STRING_DIGEST_MD5; + state1 = SASL_DIGESTMD5; + sasl->authused = SASL_MECH_DIGEST_MD5; + } + else if(enabledmechs & SASL_MECH_CRAM_MD5) { + mech = SASL_MECH_STRING_CRAM_MD5; + state1 = SASL_CRAMMD5; + sasl->authused = SASL_MECH_CRAM_MD5; + } + else +#endif +#ifdef USE_NTLM + if((enabledmechs & SASL_MECH_NTLM) && Curl_auth_is_ntlm_supported()) { + mech = SASL_MECH_STRING_NTLM; + state1 = SASL_NTLM; + state2 = SASL_NTLM_TYPE2MSG; + sasl->authused = SASL_MECH_NTLM; + + if(force_ir || data->set.sasl_ir) + result = Curl_auth_create_ntlm_type1_message(data, + conn->user, conn->passwd, + service, + hostname, + &conn->ntlm, &resp, + &len); + } + else +#endif + if((enabledmechs & SASL_MECH_OAUTHBEARER) && conn->oauth_bearer) { + mech = SASL_MECH_STRING_OAUTHBEARER; + state1 = SASL_OAUTH2; + state2 = SASL_OAUTH2_RESP; + sasl->authused = SASL_MECH_OAUTHBEARER; + + if(force_ir || data->set.sasl_ir) + result = Curl_auth_create_oauth_bearer_message(data, conn->user, + hostname, + port, + conn->oauth_bearer, + &resp, &len); + } + else if((enabledmechs & SASL_MECH_XOAUTH2) && conn->oauth_bearer) { + mech = SASL_MECH_STRING_XOAUTH2; + state1 = SASL_OAUTH2; + sasl->authused = SASL_MECH_XOAUTH2; + + if(force_ir || data->set.sasl_ir) + result = Curl_auth_create_xoauth_bearer_message(data, conn->user, + conn->oauth_bearer, + &resp, &len); + } + else if(enabledmechs & SASL_MECH_PLAIN) { + mech = SASL_MECH_STRING_PLAIN; + state1 = SASL_PLAIN; + sasl->authused = SASL_MECH_PLAIN; + + if(force_ir || data->set.sasl_ir) + result = Curl_auth_create_plain_message(data, NULL, conn->user, + conn->passwd, &resp, &len); + } + else if(enabledmechs & SASL_MECH_LOGIN) { + mech = SASL_MECH_STRING_LOGIN; + state1 = SASL_LOGIN; + state2 = SASL_LOGIN_PASSWD; + sasl->authused = SASL_MECH_LOGIN; + + if(force_ir || data->set.sasl_ir) + result = Curl_auth_create_login_message(data, conn->user, &resp, &len); + } + } + + if(!result && mech) { + if(resp && sasl->params->maxirlen && + strlen(mech) + len > sasl->params->maxirlen) { + free(resp); + resp = NULL; + } + + result = sasl->params->sendauth(conn, mech, resp); + if(!result) { + *progress = SASL_INPROGRESS; + state(sasl, conn, resp ? state2 : state1); + } + } + + free(resp); + + return result; +} + +/* + * Curl_sasl_continue() + * + * Continue the authentication. + */ +CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, + int code, saslprogress *progress) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + saslstate newstate = SASL_FINAL; + char *resp = NULL; + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; +#if !defined(CURL_DISABLE_CRYPTO_AUTH) + char *chlg = NULL; + size_t chlglen = 0; +#endif +#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \ + defined(USE_NTLM) + const char *service = data->set.str[STRING_SERVICE_NAME] ? + data->set.str[STRING_SERVICE_NAME] : + sasl->params->service; + char *serverdata; +#endif + size_t len = 0; + + *progress = SASL_INPROGRESS; + + if(sasl->state == SASL_FINAL) { + if(code != sasl->params->finalcode) + result = CURLE_LOGIN_DENIED; + *progress = SASL_DONE; + state(sasl, conn, SASL_STOP); + return result; + } + + if(sasl->state != SASL_CANCEL && sasl->state != SASL_OAUTH2_RESP && + code != sasl->params->contcode) { + *progress = SASL_DONE; + state(sasl, conn, SASL_STOP); + return CURLE_LOGIN_DENIED; + } + + switch(sasl->state) { + case SASL_STOP: + *progress = SASL_DONE; + return result; + case SASL_PLAIN: + result = Curl_auth_create_plain_message(data, NULL, conn->user, + conn->passwd, &resp, &len); + break; + case SASL_LOGIN: + result = Curl_auth_create_login_message(data, conn->user, &resp, &len); + newstate = SASL_LOGIN_PASSWD; + break; + case SASL_LOGIN_PASSWD: + result = Curl_auth_create_login_message(data, conn->passwd, &resp, &len); + break; + case SASL_EXTERNAL: + result = Curl_auth_create_external_message(data, conn->user, &resp, &len); + break; + +#ifndef CURL_DISABLE_CRYPTO_AUTH + case SASL_CRAMMD5: + sasl->params->getmessage(data->state.buffer, &serverdata); + result = Curl_auth_decode_cram_md5_message(serverdata, &chlg, &chlglen); + if(!result) + result = Curl_auth_create_cram_md5_message(data, chlg, conn->user, + conn->passwd, &resp, &len); + free(chlg); + break; + case SASL_DIGESTMD5: + sasl->params->getmessage(data->state.buffer, &serverdata); + result = Curl_auth_create_digest_md5_message(data, serverdata, + conn->user, conn->passwd, + service, + &resp, &len); + newstate = SASL_DIGESTMD5_RESP; + break; + case SASL_DIGESTMD5_RESP: + resp = strdup(""); + if(!resp) + result = CURLE_OUT_OF_MEMORY; + break; +#endif + +#ifdef USE_NTLM + case SASL_NTLM: + /* Create the type-1 message */ + result = Curl_auth_create_ntlm_type1_message(data, + conn->user, conn->passwd, + service, hostname, + &conn->ntlm, &resp, &len); + newstate = SASL_NTLM_TYPE2MSG; + break; + case SASL_NTLM_TYPE2MSG: + /* Decode the type-2 message */ + sasl->params->getmessage(data->state.buffer, &serverdata); + result = Curl_auth_decode_ntlm_type2_message(data, serverdata, + &conn->ntlm); + if(!result) + result = Curl_auth_create_ntlm_type3_message(data, conn->user, + conn->passwd, &conn->ntlm, + &resp, &len); + break; +#endif + +#if defined(USE_KERBEROS5) + case SASL_GSSAPI: + result = Curl_auth_create_gssapi_user_message(data, conn->user, + conn->passwd, + service, + data->conn->host.name, + sasl->mutual_auth, NULL, + &conn->krb5, + &resp, &len); + newstate = SASL_GSSAPI_TOKEN; + break; + case SASL_GSSAPI_TOKEN: + sasl->params->getmessage(data->state.buffer, &serverdata); + if(sasl->mutual_auth) { + /* Decode the user token challenge and create the optional response + message */ + result = Curl_auth_create_gssapi_user_message(data, NULL, NULL, + NULL, NULL, + sasl->mutual_auth, + serverdata, &conn->krb5, + &resp, &len); + newstate = SASL_GSSAPI_NO_DATA; + } + else + /* Decode the security challenge and create the response message */ + result = Curl_auth_create_gssapi_security_message(data, serverdata, + &conn->krb5, + &resp, &len); + break; + case SASL_GSSAPI_NO_DATA: + sasl->params->getmessage(data->state.buffer, &serverdata); + /* Decode the security challenge and create the response message */ + result = Curl_auth_create_gssapi_security_message(data, serverdata, + &conn->krb5, + &resp, &len); + break; +#endif + + case SASL_OAUTH2: + /* Create the authorisation message */ + if(sasl->authused == SASL_MECH_OAUTHBEARER) { + result = Curl_auth_create_oauth_bearer_message(data, conn->user, + hostname, + port, + conn->oauth_bearer, + &resp, &len); + + /* Failures maybe sent by the server as continuations for OAUTHBEARER */ + newstate = SASL_OAUTH2_RESP; + } + else + result = Curl_auth_create_xoauth_bearer_message(data, conn->user, + conn->oauth_bearer, + &resp, &len); + break; + + case SASL_OAUTH2_RESP: + /* The continuation is optional so check the response code */ + if(code == sasl->params->finalcode) { + /* Final response was received so we are done */ + *progress = SASL_DONE; + state(sasl, conn, SASL_STOP); + return result; + } + else if(code == sasl->params->contcode) { + /* Acknowledge the continuation by sending a 0x01 response base64 + encoded */ + resp = strdup("AQ=="); + if(!resp) + result = CURLE_OUT_OF_MEMORY; + break; + } + else { + *progress = SASL_DONE; + state(sasl, conn, SASL_STOP); + return CURLE_LOGIN_DENIED; + } + + case SASL_CANCEL: + /* Remove the offending mechanism from the supported list */ + sasl->authmechs ^= sasl->authused; + + /* Start an alternative SASL authentication */ + result = Curl_sasl_start(sasl, conn, sasl->force_ir, progress); + newstate = sasl->state; /* Use state from Curl_sasl_start() */ + break; + default: + failf(data, "Unsupported SASL authentication mechanism"); + result = CURLE_UNSUPPORTED_PROTOCOL; /* Should not happen */ + break; + } + + switch(result) { + case CURLE_BAD_CONTENT_ENCODING: + /* Cancel dialog */ + result = sasl->params->sendcont(conn, "*"); + newstate = SASL_CANCEL; + break; + case CURLE_OK: + if(resp) + result = sasl->params->sendcont(conn, resp); + break; + default: + newstate = SASL_STOP; /* Stop on error */ + *progress = SASL_DONE; + break; + } + + free(resp); + + state(sasl, conn, newstate); + + return result; +} +#endif /* protocols are enabled that use SASL */ diff --git a/libcurl/lib/curl_sasl.h b/libcurl/lib/curl_sasl.h new file mode 100644 index 0000000..7647a48 --- /dev/null +++ b/libcurl/lib/curl_sasl.h @@ -0,0 +1,143 @@ +#ifndef HEADER_CURL_SASL_H +#define HEADER_CURL_SASL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include + +struct Curl_easy; +struct connectdata; + +/* Authentication mechanism flags */ +#define SASL_MECH_LOGIN (1 << 0) +#define SASL_MECH_PLAIN (1 << 1) +#define SASL_MECH_CRAM_MD5 (1 << 2) +#define SASL_MECH_DIGEST_MD5 (1 << 3) +#define SASL_MECH_GSSAPI (1 << 4) +#define SASL_MECH_EXTERNAL (1 << 5) +#define SASL_MECH_NTLM (1 << 6) +#define SASL_MECH_XOAUTH2 (1 << 7) +#define SASL_MECH_OAUTHBEARER (1 << 8) + +/* Authentication mechanism values */ +#define SASL_AUTH_NONE 0 +#define SASL_AUTH_ANY ~0U +#define SASL_AUTH_DEFAULT (SASL_AUTH_ANY & ~SASL_MECH_EXTERNAL) + +/* Authentication mechanism strings */ +#define SASL_MECH_STRING_LOGIN "LOGIN" +#define SASL_MECH_STRING_PLAIN "PLAIN" +#define SASL_MECH_STRING_CRAM_MD5 "CRAM-MD5" +#define SASL_MECH_STRING_DIGEST_MD5 "DIGEST-MD5" +#define SASL_MECH_STRING_GSSAPI "GSSAPI" +#define SASL_MECH_STRING_EXTERNAL "EXTERNAL" +#define SASL_MECH_STRING_NTLM "NTLM" +#define SASL_MECH_STRING_XOAUTH2 "XOAUTH2" +#define SASL_MECH_STRING_OAUTHBEARER "OAUTHBEARER" + +/* SASL machine states */ +typedef enum { + SASL_STOP, + SASL_PLAIN, + SASL_LOGIN, + SASL_LOGIN_PASSWD, + SASL_EXTERNAL, + SASL_CRAMMD5, + SASL_DIGESTMD5, + SASL_DIGESTMD5_RESP, + SASL_NTLM, + SASL_NTLM_TYPE2MSG, + SASL_GSSAPI, + SASL_GSSAPI_TOKEN, + SASL_GSSAPI_NO_DATA, + SASL_OAUTH2, + SASL_OAUTH2_RESP, + SASL_CANCEL, + SASL_FINAL +} saslstate; + +/* Progress indicator */ +typedef enum { + SASL_IDLE, + SASL_INPROGRESS, + SASL_DONE +} saslprogress; + +/* Protocol dependent SASL parameters */ +struct SASLproto { + const char *service; /* The service name */ + int contcode; /* Code to receive when continuation is expected */ + int finalcode; /* Code to receive upon authentication success */ + size_t maxirlen; /* Maximum initial response length */ + CURLcode (*sendauth)(struct connectdata *conn, + const char *mech, const char *ir); + /* Send authentication command */ + CURLcode (*sendcont)(struct connectdata *conn, const char *contauth); + /* Send authentication continuation */ + void (*getmessage)(char *buffer, char **outptr); + /* Get SASL response message */ +}; + +/* Per-connection parameters */ +struct SASL { + const struct SASLproto *params; /* Protocol dependent parameters */ + saslstate state; /* Current machine state */ + unsigned int authmechs; /* Accepted authentication mechanisms */ + unsigned int prefmech; /* Preferred authentication mechanism */ + unsigned int authused; /* Auth mechanism used for the connection */ + bool resetprefs; /* For URL auth option parsing. */ + bool mutual_auth; /* Mutual authentication enabled (GSSAPI only) */ + bool force_ir; /* Protocol always supports initial response */ +}; + +/* This is used to test whether the line starts with the given mechanism */ +#define sasl_mech_equal(line, wordlen, mech) \ + (wordlen == (sizeof(mech) - 1) / sizeof(char) && \ + !memcmp(line, mech, wordlen)) + +/* This is used to cleanup any libraries or curl modules used by the sasl + functions */ +void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused); + +/* Convert a mechanism name to a token */ +unsigned int Curl_sasl_decode_mech(const char *ptr, + size_t maxlen, size_t *len); + +/* Parse the URL login options */ +CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl, + const char *value, size_t len); + +/* Initializes an SASL structure */ +void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params); + +/* Check if we have enough auth data and capabilities to authenticate */ +bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn); + +/* Calculate the required login details for SASL authentication */ +CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, + bool force_ir, saslprogress *progress); + +/* Continue an SASL authentication */ +CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, + int code, saslprogress *progress); + +#endif /* HEADER_CURL_SASL_H */ diff --git a/libcurl/lib/curl_sec.h b/libcurl/lib/curl_sec.h new file mode 100644 index 0000000..7bdde26 --- /dev/null +++ b/libcurl/lib/curl_sec.h @@ -0,0 +1,51 @@ +#ifndef HEADER_CURL_SECURITY_H +#define HEADER_CURL_SECURITY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +struct Curl_sec_client_mech { + const char *name; + size_t size; + int (*init)(void *); + int (*auth)(void *, struct connectdata *); + void (*end)(void *); + int (*check_prot)(void *, int); + int (*overhead)(void *, int, int); + int (*encode)(void *, const void *, int, int, void **); + int (*decode)(void *, void *, int, int, struct connectdata *); +}; + +#define AUTH_OK 0 +#define AUTH_CONTINUE 1 +#define AUTH_ERROR 2 + +#ifdef HAVE_GSSAPI +int Curl_sec_read_msg(struct connectdata *conn, char *, + enum protection_level); +void Curl_sec_end(struct connectdata *); +CURLcode Curl_sec_login(struct connectdata *); +int Curl_sec_request_prot(struct connectdata *conn, const char *level); + +extern struct Curl_sec_client_mech Curl_krb5_client_mech; +#endif + +#endif /* HEADER_CURL_SECURITY_H */ diff --git a/libcurl/lib/curl_setup.h b/libcurl/lib/curl_setup.h new file mode 100644 index 0000000..16bc40a --- /dev/null +++ b/libcurl/lib/curl_setup.h @@ -0,0 +1,832 @@ +#ifndef HEADER_CURL_SETUP_H +#define HEADER_CURL_SETUP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#if defined(BUILDING_LIBCURL) && !defined(CURL_NO_OLDIES) +#define CURL_NO_OLDIES +#endif + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) && \ + !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#ifdef WIN32 +/* + * Don't include unneeded stuff in Windows headers to avoid compiler + * warnings and macro clashes. + * Make sure to define this macro before including any Windows headers. + */ +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# ifndef NOGDI +# define NOGDI +# endif +#endif + +/* + * Include configuration script results or hand-crafted + * configuration file for platforms which lack config tool. + */ + +#ifdef HAVE_CONFIG_H + +#include "curl_config.h" + +#else /* HAVE_CONFIG_H */ + +#ifdef _WIN32_WCE +# include "config-win32ce.h" +#else +# ifdef WIN32 +# include "config-win32.h" +# endif +#endif + +#if defined(macintosh) && defined(__MRC__) +# include "config-mac.h" +#endif + +#ifdef __riscos__ +# include "config-riscos.h" +#endif + +#ifdef __AMIGA__ +# include "config-amigaos.h" +#endif + +#ifdef __SYMBIAN32__ +# include "config-symbian.h" +#endif + +#ifdef __OS400__ +# include "config-os400.h" +#endif + +#ifdef TPF +# include "config-tpf.h" +#endif + +#ifdef __VXWORKS__ +# include "config-vxworks.h" +#endif + +#endif /* HAVE_CONFIG_H */ + +/* ================================================================ */ +/* Definition of preprocessor macros/symbols which modify compiler */ +/* behavior or generated code characteristics must be done here, */ +/* as appropriate, before any system header file is included. It is */ +/* also possible to have them defined in the config file included */ +/* before this point. As a result of all this we frown inclusion of */ +/* system header files in our config files, avoid this at any cost. */ +/* ================================================================ */ + +/* + * AIX 4.3 and newer needs _THREAD_SAFE defined to build + * proper reentrant code. Others may also need it. + */ + +#ifdef NEED_THREAD_SAFE +# ifndef _THREAD_SAFE +# define _THREAD_SAFE +# endif +#endif + +/* + * Tru64 needs _REENTRANT set for a few function prototypes and + * things to appear in the system header files. Unixware needs it + * to build proper reentrant code. Others may also need it. + */ + +#ifdef NEED_REENTRANT +# ifndef _REENTRANT +# define _REENTRANT +# endif +#endif + +/* Solaris needs this to get a POSIX-conformant getpwuid_r */ +#if defined(sun) || defined(__sun) +# ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +# endif +#endif + +/* ================================================================ */ +/* If you need to include a system header file for your platform, */ +/* please, do it beyond the point further indicated in this file. */ +/* ================================================================ */ + +#include + +#define CURL_SIZEOF_CURL_OFF_T SIZEOF_CURL_OFF_T + +/* + * Disable other protocols when http is the only one desired. + */ + +#ifdef HTTP_ONLY +# ifndef CURL_DISABLE_TFTP +# define CURL_DISABLE_TFTP +# endif +# ifndef CURL_DISABLE_FTP +# define CURL_DISABLE_FTP +# endif +# ifndef CURL_DISABLE_LDAP +# define CURL_DISABLE_LDAP +# endif +# ifndef CURL_DISABLE_TELNET +# define CURL_DISABLE_TELNET +# endif +# ifndef CURL_DISABLE_DICT +# define CURL_DISABLE_DICT +# endif +# ifndef CURL_DISABLE_FILE +# define CURL_DISABLE_FILE +# endif +# ifndef CURL_DISABLE_RTSP +# define CURL_DISABLE_RTSP +# endif +# ifndef CURL_DISABLE_POP3 +# define CURL_DISABLE_POP3 +# endif +# ifndef CURL_DISABLE_IMAP +# define CURL_DISABLE_IMAP +# endif +# ifndef CURL_DISABLE_SMTP +# define CURL_DISABLE_SMTP +# endif +# ifndef CURL_DISABLE_GOPHER +# define CURL_DISABLE_GOPHER +# endif +# ifndef CURL_DISABLE_SMB +# define CURL_DISABLE_SMB +# endif +#endif + +/* + * When http is disabled rtsp is not supported. + */ + +#if defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_RTSP) +# define CURL_DISABLE_RTSP +#endif + +/* ================================================================ */ +/* No system header file shall be included in this file before this */ +/* point. The only allowed ones are those included from curl/system.h */ +/* ================================================================ */ + +/* + * OS/400 setup file includes some system headers. + */ + +#ifdef __OS400__ +# include "setup-os400.h" +#endif + +/* + * VMS setup file includes some system headers. + */ + +#ifdef __VMS +# include "setup-vms.h" +#endif + +/* + * Use getaddrinfo to resolve the IPv4 address literal. If the current network + * interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64, + * performing this task will result in a synthesized IPv6 address. + */ +#ifdef __APPLE__ +#define USE_RESOLVE_ON_IPS 1 +#endif + +/* + * Include header files for windows builds before redefining anything. + * Use this preprocessor block only to include or exclude windows.h, + * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs + * to any other further and independent block. Under Cygwin things work + * just as under linux (e.g. ) and the winsock headers should + * never be included when __CYGWIN__ is defined. configure script takes + * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H, + * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined. + */ + +#ifdef HAVE_WINDOWS_H +# if defined(UNICODE) && !defined(_UNICODE) +# define _UNICODE +# endif +# if defined(_UNICODE) && !defined(UNICODE) +# define UNICODE +# endif +//# include +//# include +# include +# ifdef HAVE_WINSOCK2_H +//# include +# ifdef HAVE_WS2TCPIP_H +//# include +# endif +# else +# ifdef HAVE_WINSOCK_H +# include +# endif +# endif +# include +# ifdef UNICODE + typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str); +# endif +#endif + +/* + * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else + * define USE_WINSOCK to 1 if we have and use WINSOCK API, else + * undefine USE_WINSOCK. + */ + +#undef USE_WINSOCK + +#ifdef HAVE_WINSOCK2_H +# define USE_WINSOCK 2 +#else +# ifdef HAVE_WINSOCK_H +# define USE_WINSOCK 1 +# endif +#endif + +#ifdef USE_LWIPSOCK +# include +# include +# include +#endif + +#ifdef HAVE_EXTRA_STRICMP_H +# include +#endif + +#ifdef HAVE_EXTRA_STRDUP_H +# include +#endif + +#ifdef TPF +# include /* for bzero, strcasecmp, and strncasecmp */ +# include /* for strcpy and strlen */ +# include /* for rand and srand */ +# include /* for select and ioctl*/ +# include /* for in_addr_t definition */ +# include /* for tpf_process_signals */ + /* change which select is used for libcurl */ +# define select(a,b,c,d,e) tpf_select_libcurl(a,b,c,d,e) +#endif + +#ifdef __VXWORKS__ +# include /* for generic BSD socket functions */ +# include /* for basic I/O interface functions */ +#endif + +#ifdef __AMIGA__ +# include +# include +# include +# include +# ifdef HAVE_PROTO_BSDSOCKET_H +# include /* ensure bsdsocket.library use */ +# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0) +# endif +#endif + +#include +#ifdef HAVE_ASSERT_H +#include +#endif + +#ifdef __TANDEM /* for nsr-tandem-nsk systems */ +#include +#endif + +#ifndef STDC_HEADERS /* no standard C headers! */ +#include +#endif + +#ifdef __POCC__ +# include +# include +# define sys_nerr EILSEQ +#endif + +/* + * Salford-C kludge section (mostly borrowed from wxWidgets). + */ +#ifdef __SALFORDC__ + #pragma suppress 353 /* Possible nested comments */ + #pragma suppress 593 /* Define not used */ + #pragma suppress 61 /* enum has no name */ + #pragma suppress 106 /* unnamed, unused parameter */ + #include +#endif + +/* + * Large file (>2Gb) support using WIN32 functions. + */ + +#ifdef USE_WIN32_LARGE_FILES +# include +# include +# include +# undef lseek +# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence) +# undef fstat +# define fstat(fdes,stp) _fstati64(fdes, stp) +# undef stat +# define stat(fname,stp) _stati64(fname, stp) +# define struct_stat struct _stati64 +# define LSEEK_ERROR (__int64)-1 +#endif + +/* + * Small file (<2Gb) support using WIN32 functions. + */ + +#ifdef USE_WIN32_SMALL_FILES +# include +# include +# include +# ifndef _WIN32_WCE +# undef lseek +# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence) +# define fstat(fdes,stp) _fstat(fdes, stp) +# define stat(fname,stp) _stat(fname, stp) +# define struct_stat struct _stat +# endif +# define LSEEK_ERROR (long)-1 +#endif + +#ifndef struct_stat +# define struct_stat struct stat +#endif + +#ifndef LSEEK_ERROR +# define LSEEK_ERROR (off_t)-1 +#endif + +#ifndef SIZEOF_TIME_T +/* assume default size of time_t to be 32 bit */ +#define SIZEOF_TIME_T 4 +#endif + +/* + * Default sizeof(off_t) in case it hasn't been defined in config file. + */ + +#ifndef SIZEOF_OFF_T +# if defined(__VMS) && !defined(__VAX) +# if defined(_LARGEFILE) +# define SIZEOF_OFF_T 8 +# endif +# elif defined(__OS400__) && defined(__ILEC400__) +# if defined(_LARGE_FILES) +# define SIZEOF_OFF_T 8 +# endif +# elif defined(__MVS__) && defined(__IBMC__) +# if defined(_LP64) || defined(_LARGE_FILES) +# define SIZEOF_OFF_T 8 +# endif +# elif defined(__370__) && defined(__IBMC__) +# if defined(_LP64) || defined(_LARGE_FILES) +# define SIZEOF_OFF_T 8 +# endif +# endif +# ifndef SIZEOF_OFF_T +# define SIZEOF_OFF_T 4 +# endif +#endif + +#if (SIZEOF_CURL_OFF_T == 4) +# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFF) +#else + /* assume CURL_SIZEOF_CURL_OFF_T == 8 */ +# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) +#endif +#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1)) + +#if (SIZEOF_TIME_T == 4) +# ifdef HAVE_TIME_T_UNSIGNED +# define TIME_T_MAX UINT_MAX +# define TIME_T_MIN 0 +# else +# define TIME_T_MAX INT_MAX +# define TIME_T_MIN INT_MIN +# endif +#else +# ifdef HAVE_TIME_T_UNSIGNED +# define TIME_T_MAX 0xFFFFFFFFFFFFFFFF +# define TIME_T_MIN 0 +# else +# define TIME_T_MAX 0x7FFFFFFFFFFFFFFF +# define TIME_T_MIN (-TIME_T_MAX - 1) +# endif +#endif + +#ifndef SIZE_T_MAX +/* some limits.h headers have this defined, some don't */ +#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4) +#define SIZE_T_MAX 18446744073709551615U +#else +#define SIZE_T_MAX 4294967295U +#endif +#endif + +/* + * Arg 2 type for gethostname in case it hasn't been defined in config file. + */ + +#ifndef GETHOSTNAME_TYPE_ARG2 +# ifdef USE_WINSOCK +# define GETHOSTNAME_TYPE_ARG2 int +# else +# define GETHOSTNAME_TYPE_ARG2 size_t +# endif +#endif + +/* Below we define some functions. They should + + 4. set the SIGALRM signal timeout + 5. set dir/file naming defines + */ + +#ifdef WIN32 + +# define DIR_CHAR "\\" +# define DOT_CHAR "_" + +#else /* WIN32 */ + +# ifdef MSDOS /* Watt-32 */ + +# include +# define select(n,r,w,x,t) select_s(n,r,w,x,t) +# define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z)) +# include +# ifdef word +# undef word +# endif +# ifdef byte +# undef byte +# endif + +# endif /* MSDOS */ + +# ifdef __minix + /* Minix 3 versions up to at least 3.1.3 are missing these prototypes */ + extern char *strtok_r(char *s, const char *delim, char **last); + extern struct tm *gmtime_r(const time_t * const timep, struct tm *tmp); +# endif + +# define DIR_CHAR "/" +# ifndef DOT_CHAR +# define DOT_CHAR "." +# endif + +# ifdef MSDOS +# undef DOT_CHAR +# define DOT_CHAR "_" +# endif + +# ifndef fileno /* sunos 4 have this as a macro! */ + int fileno(FILE *stream); +# endif + +#endif /* WIN32 */ + +/* + * msvc 6.0 requires PSDK in order to have INET6_ADDRSTRLEN + * defined in ws2tcpip.h as well as to provide IPv6 support. + * Does not apply if lwIP is used. + */ + +//#if defined(_MSC_VER) && !defined(__POCC__) && !defined(USE_LWIPSOCK) +//# if !defined(HAVE_WS2TCPIP_H) || \ +// ((_MSC_VER < 1300) && !defined(INET6_ADDRSTRLEN)) +# undef HAVE_GETADDRINFO_THREADSAFE +# undef HAVE_FREEADDRINFO +# undef HAVE_GETADDRINFO +# undef HAVE_GETNAMEINFO +# undef ENABLE_IPV6 +//# endif +//#endif + +/* ---------------------------------------------------------------- */ +/* resolver specialty compile-time defines */ +/* CURLRES_* defines to use in the host*.c sources */ +/* ---------------------------------------------------------------- */ + +/* + * lcc-win32 doesn't have _beginthreadex(), lacks threads support. + */ + +#if defined(__LCC__) && defined(WIN32) +# undef USE_THREADS_POSIX +# undef USE_THREADS_WIN32 +#endif + +/* + * MSVC threads support requires a multi-threaded runtime library. + * _beginthreadex() is not available in single-threaded ones. + */ + +#if defined(_MSC_VER) && !defined(__POCC__) && !defined(_MT) +# undef USE_THREADS_POSIX +# undef USE_THREADS_WIN32 +#endif + +/* + * Mutually exclusive CURLRES_* definitions. + */ + +#ifdef USE_ARES +# define CURLRES_ASYNCH +# define CURLRES_ARES +/* now undef the stock libc functions just to avoid them being used */ +# undef HAVE_GETADDRINFO +# undef HAVE_FREEADDRINFO +# undef HAVE_GETHOSTBYNAME +#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) +# define CURLRES_ASYNCH +# define CURLRES_THREADED +#else +# define CURLRES_SYNCH +#endif + +#ifdef ENABLE_IPV6 +# define CURLRES_IPV6 +#else +# define CURLRES_IPV4 +#endif + +/* ---------------------------------------------------------------- */ + +/* + * When using WINSOCK, TELNET protocol requires WINSOCK2 API. + */ + +#if defined(USE_WINSOCK) && (USE_WINSOCK != 2) +# define CURL_DISABLE_TELNET 1 +#endif + +/* + * msvc 6.0 does not have struct sockaddr_storage and + * does not define IPPROTO_ESP in winsock2.h. But both + * are available if PSDK is properly installed. + */ + +//#if defined(_MSC_VER) && !defined(__POCC__) +//# if !defined(HAVE_WINSOCK2_H) || ((_MSC_VER < 1300) && !defined(IPPROTO_ESP)) +# undef HAVE_STRUCT_SOCKADDR_STORAGE +//# endif +//#endif + +/* + * Intentionally fail to build when using msvc 6.0 without PSDK installed. + * The brave of heart can circumvent this, defining ALLOW_MSVC6_WITHOUT_PSDK + * in lib/config-win32.h although absolutely discouraged and unsupported. + */ + +#if defined(_MSC_VER) && !defined(__POCC__) +# if !defined(HAVE_WINDOWS_H) || ((_MSC_VER < 1300) && !defined(_FILETIME_)) +# if !defined(ALLOW_MSVC6_WITHOUT_PSDK) +# error MSVC 6.0 requires "February 2003 Platform SDK" a.k.a. \ + "Windows Server 2003 PSDK" +# else +# define CURL_DISABLE_LDAP 1 +# endif +# endif +#endif + +#ifdef NETWARE +int netware_init(void); +#ifndef __NOVELL_LIBC__ +#include +#include +#endif +#endif + +#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H) && !defined(USE_WIN32_IDN) +/* The lib and header are present */ +#define USE_LIBIDN2 +#endif + +#if defined(USE_LIBIDN2) && defined(USE_WIN32_IDN) +#error "Both libidn2 and WinIDN are enabled, choose one." +#endif + +#define LIBIDN_REQUIRED_VERSION "0.4.1" + +#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \ + defined(USE_MBEDTLS) || defined(USE_BEARSSL) || \ + defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \ + defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK) +#define USE_SSL /* SSL support has been enabled */ +#endif + +/* Single point where USE_SPNEGO definition might be defined */ +#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \ + (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) +#define USE_SPNEGO +#endif + +/* Single point where USE_KERBEROS5 definition might be defined */ +#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \ + (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) +#define USE_KERBEROS5 +#endif + +/* Single point where USE_NTLM definition might be defined */ +#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH) +#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \ + defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \ + defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \ + defined(USE_MBEDTLS) + +#define USE_NTLM + +# if defined(USE_MBEDTLS) +/* Get definition of MBEDTLS_MD4_C */ +# include +# endif + +#endif +#endif + +#ifdef CURL_WANTS_CA_BUNDLE_ENV +#error "No longer supported. Set CURLOPT_CAINFO at runtime instead." +#endif + +#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) || defined(USE_WOLFSSH) +#define USE_SSH +#endif + +/* + * Provide a mechanism to silence picky compilers, such as gcc 4.6+. + * Parameters should of course normally not be unused, but for example when + * we have multiple implementations of the same interface it may happen. + */ + +#if defined(__GNUC__) && ((__GNUC__ >= 3) || \ + ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7))) +# define UNUSED_PARAM __attribute__((__unused__)) +# define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +# define UNUSED_PARAM /*NOTHING*/ +# define WARN_UNUSED_RESULT +#endif + +/* + * Include macros and defines that should only be processed once. + */ + +#ifndef HEADER_CURL_SETUP_ONCE_H +#include "curl_setup_once.h" +#endif + +/* + * Definition of our NOP statement Object-like macro + */ + +#ifndef Curl_nop_stmt +# define Curl_nop_stmt do { } WHILE_FALSE +#endif + +/* + * Ensure that Winsock and lwIP TCP/IP stacks are not mixed. + */ + +#if defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H) +# if defined(SOCKET) || \ + defined(USE_WINSOCK) || \ + defined(HAVE_WINSOCK_H) || \ + defined(HAVE_WINSOCK2_H) || \ + defined(HAVE_WS2TCPIP_H) +# error "Winsock and lwIP TCP/IP stack definitions shall not coexist!" +# endif +#endif + +/* + * Portable symbolic names for Winsock shutdown() mode flags. + */ + +#ifdef USE_WINSOCK +# define SHUT_RD 0x00 +# define SHUT_WR 0x01 +# define SHUT_RDWR 0x02 +#endif + +/* Define S_ISREG if not defined by system headers, f.e. MSVC */ +#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif + +/* Define S_ISDIR if not defined by system headers, f.e. MSVC */ +#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +/* In Windows the default file mode is text but an application can override it. +Therefore we specify it explicitly. https://github.com/curl/curl/pull/258 +*/ +#if defined(WIN32) || defined(MSDOS) +#define FOPEN_READTEXT "rt" +#define FOPEN_WRITETEXT "wt" +#define FOPEN_APPENDTEXT "at" +#elif defined(__CYGWIN__) +/* Cygwin has specific behavior we need to address when WIN32 is not defined. +https://cygwin.com/cygwin-ug-net/using-textbinary.html +For write we want our output to have line endings of LF and be compatible with +other Cygwin utilities. For read we want to handle input that may have line +endings either CRLF or LF so 't' is appropriate. +*/ +#define FOPEN_READTEXT "rt" +#define FOPEN_WRITETEXT "w" +#define FOPEN_APPENDTEXT "a" +#else +#define FOPEN_READTEXT "r" +#define FOPEN_WRITETEXT "w" +#define FOPEN_APPENDTEXT "a" +#endif + +/* WinSock destroys recv() buffer when send() failed. + * Enabled automatically for Windows and for Cygwin as Cygwin sockets are + * wrappers for WinSock sockets. https://github.com/curl/curl/issues/657 + * Define DONT_USE_RECV_BEFORE_SEND_WORKAROUND to force disable workaround. + * Disabled for Xbox - xnet stack doesn't need this workaround. + */ +#if !defined(DONT_USE_RECV_BEFORE_SEND_WORKAROUND) +# if (defined(WIN32) || defined(__CYGWIN__)) && !defined(_XBOX) +# define USE_RECV_BEFORE_SEND_WORKAROUND +# endif +#else /* DONT_USE_RECV_BEFORE_SEND_WORKAROUND */ +# ifdef USE_RECV_BEFORE_SEND_WORKAROUND +# undef USE_RECV_BEFORE_SEND_WORKAROUND +# endif +#endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUND */ + +/* Detect Windows App environment which has a restricted access + * to the Win32 APIs. */ +# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \ + defined(WINAPI_FAMILY) +# include +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ + !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define CURL_WINDOWS_APP +# endif +# endif + +/* for systems that don't detect this in configure, use a sensible default */ +#ifndef CURL_SA_FAMILY_T +#define CURL_SA_FAMILY_T unsigned short +#endif + +/* Some convenience macros to get the larger/smaller value out of two given. + We prefix with CURL to prevent name collisions. */ +#define CURLMAX(x,y) ((x)>(y)?(x):(y)) +#define CURLMIN(x,y) ((x)<(y)?(x):(y)) + +/* Some versions of the Android SDK is missing the declaration */ +#if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING) +struct passwd; +int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, + size_t buflen, struct passwd **result); +#endif + +#ifdef DEBUGBUILD +#define UNITTEST +#else +#define UNITTEST static +#endif + +#endif /* HEADER_CURL_SETUP_H */ diff --git a/libcurl/lib/curl_setup_once.h b/libcurl/lib/curl_setup_once.h new file mode 100644 index 0000000..413ccea --- /dev/null +++ b/libcurl/lib/curl_setup_once.h @@ -0,0 +1,517 @@ +#ifndef HEADER_CURL_SETUP_ONCE_H +#define HEADER_CURL_SETUP_ONCE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + + +/* + * Inclusion of common header files. + */ + +#include +#include +#include +#include +#include + +#ifdef HAVE_ERRNO_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef NEED_MALLOC_H +#include +#endif + +#ifdef NEED_MEMORY_H +#include +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#ifdef TIME_WITH_SYS_TIME +#include +#endif +#else +#ifdef HAVE_TIME_H +#include +#endif +#endif + +#ifdef WIN32 +#include +#include +#endif + +#if defined(HAVE_STDBOOL_H) && defined(HAVE_BOOL_T) +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef __hpux +# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL) +# ifdef _APP32_64BIT_OFF_T +# define OLD_APP32_64BIT_OFF_T _APP32_64BIT_OFF_T +# undef _APP32_64BIT_OFF_T +# else +# undef OLD_APP32_64BIT_OFF_T +# endif +# endif +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#ifdef __hpux +# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL) +# ifdef OLD_APP32_64BIT_OFF_T +# define _APP32_64BIT_OFF_T OLD_APP32_64BIT_OFF_T +# undef OLD_APP32_64BIT_OFF_T +# endif +# endif +#endif + +/* + * Definition of timeval struct for platforms that don't have it. + */ + +#ifndef HAVE_STRUCT_TIMEVAL +struct timeval { + long tv_sec; + long tv_usec; +}; +#endif + + +/* + * If we have the MSG_NOSIGNAL define, make sure we use + * it as the fourth argument of function send() + */ + +#ifdef HAVE_MSG_NOSIGNAL +#define SEND_4TH_ARG MSG_NOSIGNAL +#else +#define SEND_4TH_ARG 0 +#endif + + +#if defined(__minix) +/* Minix doesn't support recv on TCP sockets */ +#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \ + (RECV_TYPE_ARG2)(y), \ + (RECV_TYPE_ARG3)(z)) + +#elif defined(HAVE_RECV) +/* + * The definitions for the return type and arguments types + * of functions recv() and send() belong and come from the + * configuration file. Do not define them in any other place. + * + * HAVE_RECV is defined if you have a function named recv() + * which is used to read incoming data from sockets. If your + * function has another name then don't define HAVE_RECV. + * + * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2, + * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also + * be defined. + * + * HAVE_SEND is defined if you have a function named send() + * which is used to write outgoing data on a connected socket. + * If yours has another name then don't define HAVE_SEND. + * + * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2, + * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and + * SEND_TYPE_RETV must also be defined. + */ + +#if !defined(RECV_TYPE_ARG1) || \ + !defined(RECV_TYPE_ARG2) || \ + !defined(RECV_TYPE_ARG3) || \ + !defined(RECV_TYPE_ARG4) || \ + !defined(RECV_TYPE_RETV) + /* */ + Error Missing_definition_of_return_and_arguments_types_of_recv + /* */ +#else +#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \ + (RECV_TYPE_ARG2)(y), \ + (RECV_TYPE_ARG3)(z), \ + (RECV_TYPE_ARG4)(0)) +#endif +#else /* HAVE_RECV */ +#ifndef sread + /* */ + Error Missing_definition_of_macro_sread + /* */ +#endif +#endif /* HAVE_RECV */ + + +#if defined(__minix) +/* Minix doesn't support send on TCP sockets */ +#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \ + (SEND_TYPE_ARG2)(y), \ + (SEND_TYPE_ARG3)(z)) + +#elif defined(HAVE_SEND) +#if !defined(SEND_TYPE_ARG1) || \ + !defined(SEND_QUAL_ARG2) || \ + !defined(SEND_TYPE_ARG2) || \ + !defined(SEND_TYPE_ARG3) || \ + !defined(SEND_TYPE_ARG4) || \ + !defined(SEND_TYPE_RETV) + /* */ + Error Missing_definition_of_return_and_arguments_types_of_send + /* */ +#else +#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \ + (SEND_QUAL_ARG2 SEND_TYPE_ARG2)(y), \ + (SEND_TYPE_ARG3)(z), \ + (SEND_TYPE_ARG4)(SEND_4TH_ARG)) +#endif +#else /* HAVE_SEND */ +#ifndef swrite + /* */ + Error Missing_definition_of_macro_swrite + /* */ +#endif +#endif /* HAVE_SEND */ + + +#if 0 +#if defined(HAVE_RECVFROM) +/* + * Currently recvfrom is only used on udp sockets. + */ +#if !defined(RECVFROM_TYPE_ARG1) || \ + !defined(RECVFROM_TYPE_ARG2) || \ + !defined(RECVFROM_TYPE_ARG3) || \ + !defined(RECVFROM_TYPE_ARG4) || \ + !defined(RECVFROM_TYPE_ARG5) || \ + !defined(RECVFROM_TYPE_ARG6) || \ + !defined(RECVFROM_TYPE_RETV) + /* */ + Error Missing_definition_of_return_and_arguments_types_of_recvfrom + /* */ +#else +#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \ + (RECVFROM_TYPE_ARG2 *)(b), \ + (RECVFROM_TYPE_ARG3) (bl), \ + (RECVFROM_TYPE_ARG4) (0), \ + (RECVFROM_TYPE_ARG5 *)(f), \ + (RECVFROM_TYPE_ARG6 *)(fl)) +#endif +#else /* HAVE_RECVFROM */ +#ifndef sreadfrom + /* */ + Error Missing_definition_of_macro_sreadfrom + /* */ +#endif +#endif /* HAVE_RECVFROM */ + + +#ifdef RECVFROM_TYPE_ARG6_IS_VOID +# define RECVFROM_ARG6_T int +#else +# define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6 +#endif +#endif /* if 0 */ + + +/* + * Function-like macro definition used to close a socket. + */ + +#if defined(HAVE_CLOSESOCKET) +# define sclose(x) closesocket((x)) +#elif defined(HAVE_CLOSESOCKET_CAMEL) +# define sclose(x) CloseSocket((x)) +#elif defined(HAVE_CLOSE_S) +# define sclose(x) close_s((x)) +#elif defined(USE_LWIPSOCK) +# define sclose(x) lwip_close((x)) +#else +# define sclose(x) close((x)) +#endif + +/* + * Stack-independent version of fcntl() on sockets: + */ +#if defined(USE_LWIPSOCK) +# define sfcntl lwip_fcntl +#else +# define sfcntl fcntl +#endif + +#define TOLOWER(x) (tolower((int) ((unsigned char)x))) + + +/* + * 'bool' stuff compatible with HP-UX headers. + */ + +#if defined(__hpux) && !defined(HAVE_BOOL_T) + typedef int bool; +# define false 0 +# define true 1 +# define HAVE_BOOL_T +#endif + + +/* + * 'bool' exists on platforms with , i.e. C99 platforms. + * On non-C99 platforms there's no bool, so define an enum for that. + * On C99 platforms 'false' and 'true' also exist. Enum uses a + * global namespace though, so use bool_false and bool_true. + */ + +#ifndef HAVE_BOOL_T + typedef enum { + bool_false = 0, + bool_true = 1 + } bool; + +/* + * Use a define to let 'true' and 'false' use those enums. There + * are currently no use of true and false in libcurl proper, but + * there are some in the examples. This will cater for any later + * code happening to use true and false. + */ +# define false bool_false +# define true bool_true +# define HAVE_BOOL_T +#endif + + +/* + * Redefine TRUE and FALSE too, to catch current use. With this + * change, 'bool found = 1' will give a warning on MIPSPro, but + * 'bool found = TRUE' will not. Change tested on IRIX/MIPSPro, + * AIX 5.1/Xlc, Tru64 5.1/cc, w/make test too. + */ + +#ifndef TRUE +#define TRUE true +#endif +#ifndef FALSE +#define FALSE false +#endif + +#include "curl_ctype.h" + +/* + * Macro WHILE_FALSE may be used to build single-iteration do-while loops, + * avoiding compiler warnings. Mostly intended for other macro definitions. + */ + +#define WHILE_FALSE while(0) + +#if defined(_MSC_VER) && !defined(__POCC__) +# undef WHILE_FALSE +# if (_MSC_VER < 1500) +# define WHILE_FALSE while(1, 0) +# else +# define WHILE_FALSE \ +__pragma(warning(push)) \ +__pragma(warning(disable:4127)) \ +while(0) \ +__pragma(warning(pop)) +# endif +#endif + + +/* + * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type. + */ + +#ifndef HAVE_SIG_ATOMIC_T +typedef int sig_atomic_t; +#define HAVE_SIG_ATOMIC_T +#endif + + +/* + * Convenience SIG_ATOMIC_T definition + */ + +#ifdef HAVE_SIG_ATOMIC_T_VOLATILE +#define SIG_ATOMIC_T static sig_atomic_t +#else +#define SIG_ATOMIC_T static volatile sig_atomic_t +#endif + + +/* + * Default return type for signal handlers. + */ + +#ifndef RETSIGTYPE +#define RETSIGTYPE void +#endif + + +/* + * Macro used to include code only in debug builds. + */ + +#ifdef DEBUGBUILD +#define DEBUGF(x) x +#else +#define DEBUGF(x) do { } WHILE_FALSE +#endif + + +/* + * Macro used to include assertion code only in debug builds. + */ + +#if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H) +#define DEBUGASSERT(x) assert(x) +#else +#define DEBUGASSERT(x) do { } WHILE_FALSE +#endif + + +/* + * Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno + * (or equivalent) on this platform to hide platform details to code using it. + */ + +#ifdef USE_WINSOCK +#define SOCKERRNO ((int)WSAGetLastError()) +#define SET_SOCKERRNO(x) (WSASetLastError((int)(x))) +#else +#define SOCKERRNO (errno) +#define SET_SOCKERRNO(x) (errno = (x)) +#endif + + +/* + * Portable error number symbolic names defined to Winsock error codes. + */ + +#ifdef USE_WINSOCK +#undef EBADF /* override definition in errno.h */ +#define EBADF WSAEBADF +#undef EINTR /* override definition in errno.h */ +#define EINTR WSAEINTR +#undef EINVAL /* override definition in errno.h */ +#define EINVAL WSAEINVAL +#undef EWOULDBLOCK /* override definition in errno.h */ +#define EWOULDBLOCK WSAEWOULDBLOCK +#undef EINPROGRESS /* override definition in errno.h */ +#define EINPROGRESS WSAEINPROGRESS +#undef EALREADY /* override definition in errno.h */ +#define EALREADY WSAEALREADY +#undef ENOTSOCK /* override definition in errno.h */ +#define ENOTSOCK WSAENOTSOCK +#undef EDESTADDRREQ /* override definition in errno.h */ +#define EDESTADDRREQ WSAEDESTADDRREQ +#undef EMSGSIZE /* override definition in errno.h */ +#define EMSGSIZE WSAEMSGSIZE +#undef EPROTOTYPE /* override definition in errno.h */ +#define EPROTOTYPE WSAEPROTOTYPE +#undef ENOPROTOOPT /* override definition in errno.h */ +#define ENOPROTOOPT WSAENOPROTOOPT +#undef EPROTONOSUPPORT /* override definition in errno.h */ +#define EPROTONOSUPPORT WSAEPROTONOSUPPORT +#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT +#undef EOPNOTSUPP /* override definition in errno.h */ +#define EOPNOTSUPP WSAEOPNOTSUPP +#define EPFNOSUPPORT WSAEPFNOSUPPORT +#undef EAFNOSUPPORT /* override definition in errno.h */ +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#undef EADDRINUSE /* override definition in errno.h */ +#define EADDRINUSE WSAEADDRINUSE +#undef EADDRNOTAVAIL /* override definition in errno.h */ +#define EADDRNOTAVAIL WSAEADDRNOTAVAIL +#undef ENETDOWN /* override definition in errno.h */ +#define ENETDOWN WSAENETDOWN +#undef ENETUNREACH /* override definition in errno.h */ +#define ENETUNREACH WSAENETUNREACH +#undef ENETRESET /* override definition in errno.h */ +#define ENETRESET WSAENETRESET +#undef ECONNABORTED /* override definition in errno.h */ +#define ECONNABORTED WSAECONNABORTED +#undef ECONNRESET /* override definition in errno.h */ +#define ECONNRESET WSAECONNRESET +#undef ENOBUFS /* override definition in errno.h */ +#define ENOBUFS WSAENOBUFS +#undef EISCONN /* override definition in errno.h */ +#define EISCONN WSAEISCONN +#undef ENOTCONN /* override definition in errno.h */ +#define ENOTCONN WSAENOTCONN +#define ESHUTDOWN WSAESHUTDOWN +#define ETOOMANYREFS WSAETOOMANYREFS +#undef ETIMEDOUT /* override definition in errno.h */ +#define ETIMEDOUT WSAETIMEDOUT +#undef ECONNREFUSED /* override definition in errno.h */ +#define ECONNREFUSED WSAECONNREFUSED +#undef ELOOP /* override definition in errno.h */ +#define ELOOP WSAELOOP +#ifndef ENAMETOOLONG /* possible previous definition in errno.h */ +#define ENAMETOOLONG WSAENAMETOOLONG +#endif +#define EHOSTDOWN WSAEHOSTDOWN +#undef EHOSTUNREACH /* override definition in errno.h */ +#define EHOSTUNREACH WSAEHOSTUNREACH +#ifndef ENOTEMPTY /* possible previous definition in errno.h */ +#define ENOTEMPTY WSAENOTEMPTY +#endif +#define EPROCLIM WSAEPROCLIM +#define EUSERS WSAEUSERS +#define EDQUOT WSAEDQUOT +#define ESTALE WSAESTALE +#define EREMOTE WSAEREMOTE +#endif + +/* + * Macro argv_item_t hides platform details to code using it. + */ + +#ifdef __VMS +#define argv_item_t __char_ptr32 +#else +#define argv_item_t char * +#endif + + +/* + * We use this ZERO_NULL to avoid picky compiler warnings, + * when assigning a NULL pointer to a function pointer var. + */ + +#define ZERO_NULL 0 + + +#endif /* HEADER_CURL_SETUP_ONCE_H */ diff --git a/libcurl/lib/curl_sha256.h b/libcurl/lib/curl_sha256.h new file mode 100644 index 0000000..6db4b04 --- /dev/null +++ b/libcurl/lib/curl_sha256.h @@ -0,0 +1,32 @@ +#ifndef HEADER_CURL_SHA256_H +#define HEADER_CURL_SHA256_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Florin Petriuc, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#ifndef CURL_DISABLE_CRYPTO_AUTH + +void Curl_sha256it(unsigned char *outbuffer, + const unsigned char *input); + +#endif + +#endif /* HEADER_CURL_SHA256_H */ diff --git a/libcurl/lib/curl_sspi.c b/libcurl/lib/curl_sspi.c new file mode 100644 index 0000000..1d0de4e --- /dev/null +++ b/libcurl/lib/curl_sspi.c @@ -0,0 +1,236 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_WINDOWS_SSPI + +#include +#include "curl_sspi.h" +#include "curl_multibyte.h" +#include "system_win32.h" +#include "warnless.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* We use our own typedef here since some headers might lack these */ +typedef PSecurityFunctionTable (APIENTRY *INITSECURITYINTERFACE_FN)(VOID); + +/* See definition of SECURITY_ENTRYPOINT in sspi.h */ +#ifdef UNICODE +# ifdef _WIN32_WCE +# define SECURITYENTRYPOINT L"InitSecurityInterfaceW" +# else +# define SECURITYENTRYPOINT "InitSecurityInterfaceW" +# endif +#else +# define SECURITYENTRYPOINT "InitSecurityInterfaceA" +#endif + +/* Handle of security.dll or secur32.dll, depending on Windows version */ +HMODULE s_hSecDll = NULL; + +/* Pointer to SSPI dispatch table */ +PSecurityFunctionTable s_pSecFn = NULL; + +/* + * Curl_sspi_global_init() + * + * This is used to load the Security Service Provider Interface (SSPI) + * dynamic link library portably across all Windows versions, without + * the need to directly link libcurl, nor the application using it, at + * build time. + * + * Once this function has been executed, Windows SSPI functions can be + * called through the Security Service Provider Interface dispatch table. + * + * Parameters: + * + * None. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_sspi_global_init(void) +{ + INITSECURITYINTERFACE_FN pInitSecurityInterface; + + /* If security interface is not yet initialized try to do this */ + if(!s_hSecDll) { + /* Security Service Provider Interface (SSPI) functions are located in + * security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP + * have both these DLLs (security.dll forwards calls to secur32.dll) */ + + /* Load SSPI dll into the address space of the calling process */ + if(Curl_verify_windows_version(4, 0, PLATFORM_WINNT, VERSION_EQUAL)) + s_hSecDll = Curl_load_library(TEXT("security.dll")); + else + s_hSecDll = Curl_load_library(TEXT("secur32.dll")); + if(!s_hSecDll) + return CURLE_FAILED_INIT; + + /* Get address of the InitSecurityInterfaceA function from the SSPI dll */ + pInitSecurityInterface = + CURLX_FUNCTION_CAST(INITSECURITYINTERFACE_FN, + (GetProcAddress(s_hSecDll, SECURITYENTRYPOINT))); + if(!pInitSecurityInterface) + return CURLE_FAILED_INIT; + + /* Get pointer to Security Service Provider Interface dispatch table */ + s_pSecFn = pInitSecurityInterface(); + if(!s_pSecFn) + return CURLE_FAILED_INIT; + } + + return CURLE_OK; +} + +/* + * Curl_sspi_global_cleanup() + * + * This deinitializes the Security Service Provider Interface from libcurl. + * + * Parameters: + * + * None. + */ +void Curl_sspi_global_cleanup(void) +{ + if(s_hSecDll) { + FreeLibrary(s_hSecDll); + s_hSecDll = NULL; + s_pSecFn = NULL; + } +} + +/* + * Curl_create_sspi_identity() + * + * This is used to populate a SSPI identity structure based on the supplied + * username and password. + * + * Parameters: + * + * userp [in] - The user name in the format User or Domain\User. + * passwdp [in] - The user's password. + * identity [in/out] - The identity structure. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, + SEC_WINNT_AUTH_IDENTITY *identity) +{ + xcharp_u useranddomain; + xcharp_u user, dup_user; + xcharp_u domain, dup_domain; + xcharp_u passwd, dup_passwd; + size_t domlen = 0; + + domain.const_tchar_ptr = TEXT(""); + + /* Initialize the identity */ + memset(identity, 0, sizeof(*identity)); + + useranddomain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)userp); + if(!useranddomain.tchar_ptr) + return CURLE_OUT_OF_MEMORY; + + user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('\\')); + if(!user.const_tchar_ptr) + user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('/')); + + if(user.tchar_ptr) { + domain.tchar_ptr = useranddomain.tchar_ptr; + domlen = user.tchar_ptr - useranddomain.tchar_ptr; + user.tchar_ptr++; + } + else { + user.tchar_ptr = useranddomain.tchar_ptr; + domain.const_tchar_ptr = TEXT(""); + domlen = 0; + } + + /* Setup the identity's user and length */ + dup_user.tchar_ptr = _tcsdup(user.tchar_ptr); + if(!dup_user.tchar_ptr) { + Curl_unicodefree(useranddomain.tchar_ptr); + return CURLE_OUT_OF_MEMORY; + } + identity->User = dup_user.tbyte_ptr; + identity->UserLength = curlx_uztoul(_tcslen(dup_user.tchar_ptr)); + dup_user.tchar_ptr = NULL; + + /* Setup the identity's domain and length */ + dup_domain.tchar_ptr = malloc(sizeof(TCHAR) * (domlen + 1)); + if(!dup_domain.tchar_ptr) { + Curl_unicodefree(useranddomain.tchar_ptr); + return CURLE_OUT_OF_MEMORY; + } + _tcsncpy(dup_domain.tchar_ptr, domain.tchar_ptr, domlen); + *(dup_domain.tchar_ptr + domlen) = TEXT('\0'); + identity->Domain = dup_domain.tbyte_ptr; + identity->DomainLength = curlx_uztoul(domlen); + dup_domain.tchar_ptr = NULL; + + Curl_unicodefree(useranddomain.tchar_ptr); + + /* Setup the identity's password and length */ + passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp); + if(!passwd.tchar_ptr) + return CURLE_OUT_OF_MEMORY; + dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr); + if(!dup_passwd.tchar_ptr) { + Curl_unicodefree(passwd.tchar_ptr); + return CURLE_OUT_OF_MEMORY; + } + identity->Password = dup_passwd.tbyte_ptr; + identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr)); + dup_passwd.tchar_ptr = NULL; + + Curl_unicodefree(passwd.tchar_ptr); + + /* Setup the identity's flags */ + identity->Flags = SECFLAG_WINNT_AUTH_IDENTITY; + + return CURLE_OK; +} + +/* + * Curl_sspi_free_identity() + * + * This is used to free the contents of a SSPI identifier structure. + * + * Parameters: + * + * identity [in/out] - The identity structure. + */ +void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity) +{ + if(identity) { + Curl_safefree(identity->User); + Curl_safefree(identity->Password); + Curl_safefree(identity->Domain); + } +} + +#endif /* USE_WINDOWS_SSPI */ diff --git a/libcurl/lib/curl_sspi.h b/libcurl/lib/curl_sspi.h new file mode 100644 index 0000000..2bbf947 --- /dev/null +++ b/libcurl/lib/curl_sspi.h @@ -0,0 +1,350 @@ +#ifndef HEADER_CURL_SSPI_H +#define HEADER_CURL_SSPI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_WINDOWS_SSPI + +#include + +/* + * When including the following three headers, it is mandatory to define either + * SECURITY_WIN32 or SECURITY_KERNEL, indicating who is compiling the code. + */ + +#undef SECURITY_WIN32 +#undef SECURITY_KERNEL +#define SECURITY_WIN32 1 +#include +#include +#include + +CURLcode Curl_sspi_global_init(void); +void Curl_sspi_global_cleanup(void); + +/* This is used to populate the domain in a SSPI identity structure */ +CURLcode Curl_override_sspi_http_realm(const char *chlg, + SEC_WINNT_AUTH_IDENTITY *identity); + +/* This is used to generate an SSPI identity structure */ +CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, + SEC_WINNT_AUTH_IDENTITY *identity); + +/* This is used to free an SSPI identity structure */ +void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity); + +/* Forward-declaration of global variables defined in curl_sspi.c */ +extern HMODULE s_hSecDll; +extern PSecurityFunctionTable s_pSecFn; + +/* Provide some definitions missing in old headers */ +#define SP_NAME_DIGEST "WDigest" +#define SP_NAME_NTLM "NTLM" +#define SP_NAME_NEGOTIATE "Negotiate" +#define SP_NAME_KERBEROS "Kerberos" + +#ifndef ISC_REQ_USE_HTTP_STYLE +#define ISC_REQ_USE_HTTP_STYLE 0x01000000 +#endif + +#ifndef ISC_RET_REPLAY_DETECT +#define ISC_RET_REPLAY_DETECT 0x00000004 +#endif + +#ifndef ISC_RET_SEQUENCE_DETECT +#define ISC_RET_SEQUENCE_DETECT 0x00000008 +#endif + +#ifndef ISC_RET_CONFIDENTIALITY +#define ISC_RET_CONFIDENTIALITY 0x00000010 +#endif + +#ifndef ISC_RET_ALLOCATED_MEMORY +#define ISC_RET_ALLOCATED_MEMORY 0x00000100 +#endif + +#ifndef ISC_RET_STREAM +#define ISC_RET_STREAM 0x00008000 +#endif + +#ifndef SEC_E_INSUFFICIENT_MEMORY +# define SEC_E_INSUFFICIENT_MEMORY ((HRESULT)0x80090300L) +#endif +#ifndef SEC_E_INVALID_HANDLE +# define SEC_E_INVALID_HANDLE ((HRESULT)0x80090301L) +#endif +#ifndef SEC_E_UNSUPPORTED_FUNCTION +# define SEC_E_UNSUPPORTED_FUNCTION ((HRESULT)0x80090302L) +#endif +#ifndef SEC_E_TARGET_UNKNOWN +# define SEC_E_TARGET_UNKNOWN ((HRESULT)0x80090303L) +#endif +#ifndef SEC_E_INTERNAL_ERROR +# define SEC_E_INTERNAL_ERROR ((HRESULT)0x80090304L) +#endif +#ifndef SEC_E_SECPKG_NOT_FOUND +# define SEC_E_SECPKG_NOT_FOUND ((HRESULT)0x80090305L) +#endif +#ifndef SEC_E_NOT_OWNER +# define SEC_E_NOT_OWNER ((HRESULT)0x80090306L) +#endif +#ifndef SEC_E_CANNOT_INSTALL +# define SEC_E_CANNOT_INSTALL ((HRESULT)0x80090307L) +#endif +#ifndef SEC_E_INVALID_TOKEN +# define SEC_E_INVALID_TOKEN ((HRESULT)0x80090308L) +#endif +#ifndef SEC_E_CANNOT_PACK +# define SEC_E_CANNOT_PACK ((HRESULT)0x80090309L) +#endif +#ifndef SEC_E_QOP_NOT_SUPPORTED +# define SEC_E_QOP_NOT_SUPPORTED ((HRESULT)0x8009030AL) +#endif +#ifndef SEC_E_NO_IMPERSONATION +# define SEC_E_NO_IMPERSONATION ((HRESULT)0x8009030BL) +#endif +#ifndef SEC_E_LOGON_DENIED +# define SEC_E_LOGON_DENIED ((HRESULT)0x8009030CL) +#endif +#ifndef SEC_E_UNKNOWN_CREDENTIALS +# define SEC_E_UNKNOWN_CREDENTIALS ((HRESULT)0x8009030DL) +#endif +#ifndef SEC_E_NO_CREDENTIALS +# define SEC_E_NO_CREDENTIALS ((HRESULT)0x8009030EL) +#endif +#ifndef SEC_E_MESSAGE_ALTERED +# define SEC_E_MESSAGE_ALTERED ((HRESULT)0x8009030FL) +#endif +#ifndef SEC_E_OUT_OF_SEQUENCE +# define SEC_E_OUT_OF_SEQUENCE ((HRESULT)0x80090310L) +#endif +#ifndef SEC_E_NO_AUTHENTICATING_AUTHORITY +# define SEC_E_NO_AUTHENTICATING_AUTHORITY ((HRESULT)0x80090311L) +#endif +#ifndef SEC_E_BAD_PKGID +# define SEC_E_BAD_PKGID ((HRESULT)0x80090316L) +#endif +#ifndef SEC_E_CONTEXT_EXPIRED +# define SEC_E_CONTEXT_EXPIRED ((HRESULT)0x80090317L) +#endif +#ifndef SEC_E_INCOMPLETE_MESSAGE +# define SEC_E_INCOMPLETE_MESSAGE ((HRESULT)0x80090318L) +#endif +#ifndef SEC_E_INCOMPLETE_CREDENTIALS +# define SEC_E_INCOMPLETE_CREDENTIALS ((HRESULT)0x80090320L) +#endif +#ifndef SEC_E_BUFFER_TOO_SMALL +# define SEC_E_BUFFER_TOO_SMALL ((HRESULT)0x80090321L) +#endif +#ifndef SEC_E_WRONG_PRINCIPAL +# define SEC_E_WRONG_PRINCIPAL ((HRESULT)0x80090322L) +#endif +#ifndef SEC_E_TIME_SKEW +# define SEC_E_TIME_SKEW ((HRESULT)0x80090324L) +#endif +#ifndef SEC_E_UNTRUSTED_ROOT +# define SEC_E_UNTRUSTED_ROOT ((HRESULT)0x80090325L) +#endif +#ifndef SEC_E_ILLEGAL_MESSAGE +# define SEC_E_ILLEGAL_MESSAGE ((HRESULT)0x80090326L) +#endif +#ifndef SEC_E_CERT_UNKNOWN +# define SEC_E_CERT_UNKNOWN ((HRESULT)0x80090327L) +#endif +#ifndef SEC_E_CERT_EXPIRED +# define SEC_E_CERT_EXPIRED ((HRESULT)0x80090328L) +#endif +#ifndef SEC_E_ENCRYPT_FAILURE +# define SEC_E_ENCRYPT_FAILURE ((HRESULT)0x80090329L) +#endif +#ifndef SEC_E_DECRYPT_FAILURE +# define SEC_E_DECRYPT_FAILURE ((HRESULT)0x80090330L) +#endif +#ifndef SEC_E_ALGORITHM_MISMATCH +# define SEC_E_ALGORITHM_MISMATCH ((HRESULT)0x80090331L) +#endif +#ifndef SEC_E_SECURITY_QOS_FAILED +# define SEC_E_SECURITY_QOS_FAILED ((HRESULT)0x80090332L) +#endif +#ifndef SEC_E_UNFINISHED_CONTEXT_DELETED +# define SEC_E_UNFINISHED_CONTEXT_DELETED ((HRESULT)0x80090333L) +#endif +#ifndef SEC_E_NO_TGT_REPLY +# define SEC_E_NO_TGT_REPLY ((HRESULT)0x80090334L) +#endif +#ifndef SEC_E_NO_IP_ADDRESSES +# define SEC_E_NO_IP_ADDRESSES ((HRESULT)0x80090335L) +#endif +#ifndef SEC_E_WRONG_CREDENTIAL_HANDLE +# define SEC_E_WRONG_CREDENTIAL_HANDLE ((HRESULT)0x80090336L) +#endif +#ifndef SEC_E_CRYPTO_SYSTEM_INVALID +# define SEC_E_CRYPTO_SYSTEM_INVALID ((HRESULT)0x80090337L) +#endif +#ifndef SEC_E_MAX_REFERRALS_EXCEEDED +# define SEC_E_MAX_REFERRALS_EXCEEDED ((HRESULT)0x80090338L) +#endif +#ifndef SEC_E_MUST_BE_KDC +# define SEC_E_MUST_BE_KDC ((HRESULT)0x80090339L) +#endif +#ifndef SEC_E_STRONG_CRYPTO_NOT_SUPPORTED +# define SEC_E_STRONG_CRYPTO_NOT_SUPPORTED ((HRESULT)0x8009033AL) +#endif +#ifndef SEC_E_TOO_MANY_PRINCIPALS +# define SEC_E_TOO_MANY_PRINCIPALS ((HRESULT)0x8009033BL) +#endif +#ifndef SEC_E_NO_PA_DATA +# define SEC_E_NO_PA_DATA ((HRESULT)0x8009033CL) +#endif +#ifndef SEC_E_PKINIT_NAME_MISMATCH +# define SEC_E_PKINIT_NAME_MISMATCH ((HRESULT)0x8009033DL) +#endif +#ifndef SEC_E_SMARTCARD_LOGON_REQUIRED +# define SEC_E_SMARTCARD_LOGON_REQUIRED ((HRESULT)0x8009033EL) +#endif +#ifndef SEC_E_SHUTDOWN_IN_PROGRESS +# define SEC_E_SHUTDOWN_IN_PROGRESS ((HRESULT)0x8009033FL) +#endif +#ifndef SEC_E_KDC_INVALID_REQUEST +# define SEC_E_KDC_INVALID_REQUEST ((HRESULT)0x80090340L) +#endif +#ifndef SEC_E_KDC_UNABLE_TO_REFER +# define SEC_E_KDC_UNABLE_TO_REFER ((HRESULT)0x80090341L) +#endif +#ifndef SEC_E_KDC_UNKNOWN_ETYPE +# define SEC_E_KDC_UNKNOWN_ETYPE ((HRESULT)0x80090342L) +#endif +#ifndef SEC_E_UNSUPPORTED_PREAUTH +# define SEC_E_UNSUPPORTED_PREAUTH ((HRESULT)0x80090343L) +#endif +#ifndef SEC_E_DELEGATION_REQUIRED +# define SEC_E_DELEGATION_REQUIRED ((HRESULT)0x80090345L) +#endif +#ifndef SEC_E_BAD_BINDINGS +# define SEC_E_BAD_BINDINGS ((HRESULT)0x80090346L) +#endif +#ifndef SEC_E_MULTIPLE_ACCOUNTS +# define SEC_E_MULTIPLE_ACCOUNTS ((HRESULT)0x80090347L) +#endif +#ifndef SEC_E_NO_KERB_KEY +# define SEC_E_NO_KERB_KEY ((HRESULT)0x80090348L) +#endif +#ifndef SEC_E_CERT_WRONG_USAGE +# define SEC_E_CERT_WRONG_USAGE ((HRESULT)0x80090349L) +#endif +#ifndef SEC_E_DOWNGRADE_DETECTED +# define SEC_E_DOWNGRADE_DETECTED ((HRESULT)0x80090350L) +#endif +#ifndef SEC_E_SMARTCARD_CERT_REVOKED +# define SEC_E_SMARTCARD_CERT_REVOKED ((HRESULT)0x80090351L) +#endif +#ifndef SEC_E_ISSUING_CA_UNTRUSTED +# define SEC_E_ISSUING_CA_UNTRUSTED ((HRESULT)0x80090352L) +#endif +#ifndef SEC_E_REVOCATION_OFFLINE_C +# define SEC_E_REVOCATION_OFFLINE_C ((HRESULT)0x80090353L) +#endif +#ifndef SEC_E_PKINIT_CLIENT_FAILURE +# define SEC_E_PKINIT_CLIENT_FAILURE ((HRESULT)0x80090354L) +#endif +#ifndef SEC_E_SMARTCARD_CERT_EXPIRED +# define SEC_E_SMARTCARD_CERT_EXPIRED ((HRESULT)0x80090355L) +#endif +#ifndef SEC_E_NO_S4U_PROT_SUPPORT +# define SEC_E_NO_S4U_PROT_SUPPORT ((HRESULT)0x80090356L) +#endif +#ifndef SEC_E_CROSSREALM_DELEGATION_FAILURE +# define SEC_E_CROSSREALM_DELEGATION_FAILURE ((HRESULT)0x80090357L) +#endif +#ifndef SEC_E_REVOCATION_OFFLINE_KDC +# define SEC_E_REVOCATION_OFFLINE_KDC ((HRESULT)0x80090358L) +#endif +#ifndef SEC_E_ISSUING_CA_UNTRUSTED_KDC +# define SEC_E_ISSUING_CA_UNTRUSTED_KDC ((HRESULT)0x80090359L) +#endif +#ifndef SEC_E_KDC_CERT_EXPIRED +# define SEC_E_KDC_CERT_EXPIRED ((HRESULT)0x8009035AL) +#endif +#ifndef SEC_E_KDC_CERT_REVOKED +# define SEC_E_KDC_CERT_REVOKED ((HRESULT)0x8009035BL) +#endif +#ifndef SEC_E_INVALID_PARAMETER +# define SEC_E_INVALID_PARAMETER ((HRESULT)0x8009035DL) +#endif +#ifndef SEC_E_DELEGATION_POLICY +# define SEC_E_DELEGATION_POLICY ((HRESULT)0x8009035EL) +#endif +#ifndef SEC_E_POLICY_NLTM_ONLY +# define SEC_E_POLICY_NLTM_ONLY ((HRESULT)0x8009035FL) +#endif + +#ifndef SEC_I_CONTINUE_NEEDED +# define SEC_I_CONTINUE_NEEDED ((HRESULT)0x00090312L) +#endif +#ifndef SEC_I_COMPLETE_NEEDED +# define SEC_I_COMPLETE_NEEDED ((HRESULT)0x00090313L) +#endif +#ifndef SEC_I_COMPLETE_AND_CONTINUE +# define SEC_I_COMPLETE_AND_CONTINUE ((HRESULT)0x00090314L) +#endif +#ifndef SEC_I_LOCAL_LOGON +# define SEC_I_LOCAL_LOGON ((HRESULT)0x00090315L) +#endif +#ifndef SEC_I_CONTEXT_EXPIRED +# define SEC_I_CONTEXT_EXPIRED ((HRESULT)0x00090317L) +#endif +#ifndef SEC_I_INCOMPLETE_CREDENTIALS +# define SEC_I_INCOMPLETE_CREDENTIALS ((HRESULT)0x00090320L) +#endif +#ifndef SEC_I_RENEGOTIATE +# define SEC_I_RENEGOTIATE ((HRESULT)0x00090321L) +#endif +#ifndef SEC_I_NO_LSA_CONTEXT +# define SEC_I_NO_LSA_CONTEXT ((HRESULT)0x00090323L) +#endif +#ifndef SEC_I_SIGNATURE_NEEDED +# define SEC_I_SIGNATURE_NEEDED ((HRESULT)0x0009035CL) +#endif + +#ifndef CRYPT_E_REVOKED +# define CRYPT_E_REVOKED ((HRESULT)0x80092010L) +#endif + +#ifdef UNICODE +# define SECFLAG_WINNT_AUTH_IDENTITY \ + (unsigned long)SEC_WINNT_AUTH_IDENTITY_UNICODE +#else +# define SECFLAG_WINNT_AUTH_IDENTITY \ + (unsigned long)SEC_WINNT_AUTH_IDENTITY_ANSI +#endif + +/* + * Definitions required from ntsecapi.h are directly provided below this point + * to avoid including ntsecapi.h due to a conflict with OpenSSL's safestack.h + */ +#define KERB_WRAP_NO_ENCRYPT 0x80000001 + +#endif /* USE_WINDOWS_SSPI */ + +#endif /* HEADER_CURL_SSPI_H */ diff --git a/libcurl/lib/curl_threads.c b/libcurl/lib/curl_threads.c new file mode 100644 index 0000000..8e5937a --- /dev/null +++ b/libcurl/lib/curl_threads.c @@ -0,0 +1,155 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#if defined(USE_THREADS_POSIX) +# ifdef HAVE_PTHREAD_H +# include +# endif +#elif defined(USE_THREADS_WIN32) +# ifdef HAVE_PROCESS_H +# include +# endif +#endif + +#include "curl_threads.h" +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +#if defined(USE_THREADS_POSIX) + +struct curl_actual_call { + unsigned int (*func)(void *); + void *arg; +}; + +static void *curl_thread_create_thunk(void *arg) +{ + struct curl_actual_call * ac = arg; + unsigned int (*func)(void *) = ac->func; + void *real_arg = ac->arg; + + free(ac); + + (*func)(real_arg); + + return 0; +} + +curl_thread_t Curl_thread_create(unsigned int (*func) (void *), void *arg) +{ + curl_thread_t t = malloc(sizeof(pthread_t)); + struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call)); + if(!(ac && t)) + goto err; + + ac->func = func; + ac->arg = arg; + + if(pthread_create(t, NULL, curl_thread_create_thunk, ac) != 0) + goto err; + + return t; + +err: + free(t); + free(ac); + return curl_thread_t_null; +} + +void Curl_thread_destroy(curl_thread_t hnd) +{ + if(hnd != curl_thread_t_null) { + pthread_detach(*hnd); + free(hnd); + } +} + +int Curl_thread_join(curl_thread_t *hnd) +{ + int ret = (pthread_join(**hnd, NULL) == 0); + + free(*hnd); + *hnd = curl_thread_t_null; + + return ret; +} + +#elif defined(USE_THREADS_WIN32) + +/* !checksrc! disable SPACEBEFOREPAREN 1 */ +curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *), + void *arg) +{ +#ifdef _WIN32_WCE + typedef HANDLE curl_win_thread_handle_t; +#elif defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) + typedef unsigned long curl_win_thread_handle_t; +#else + typedef uintptr_t curl_win_thread_handle_t; +#endif + curl_thread_t t; + curl_win_thread_handle_t thread_handle; +#ifdef _WIN32_WCE + thread_handle = CreateThread(NULL, 0, func, arg, 0, NULL); +#else + thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL); +#endif + t = (curl_thread_t)thread_handle; + if((t == 0) || (t == LongToHandle(-1L))) { +#ifdef _WIN32_WCE + DWORD gle = GetLastError(); + errno = ((gle == ERROR_ACCESS_DENIED || + gle == ERROR_NOT_ENOUGH_MEMORY) ? + EACCES : EINVAL); +#endif + return curl_thread_t_null; + } + return t; +} + +void Curl_thread_destroy(curl_thread_t hnd) +{ + CloseHandle(hnd); +} + +int Curl_thread_join(curl_thread_t *hnd) +{ +#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \ + (_WIN32_WINNT < _WIN32_WINNT_VISTA) + int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0); +#else + int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0); +#endif + + Curl_thread_destroy(*hnd); + + *hnd = curl_thread_t_null; + + return ret; +} + +#endif /* USE_THREADS_* */ diff --git a/libcurl/lib/curl_threads.h b/libcurl/lib/curl_threads.h new file mode 100644 index 0000000..2a93644 --- /dev/null +++ b/libcurl/lib/curl_threads.h @@ -0,0 +1,64 @@ +#ifndef HEADER_CURL_THREADS_H +#define HEADER_CURL_THREADS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#if defined(USE_THREADS_POSIX) +# define CURL_STDCALL +# define curl_mutex_t pthread_mutex_t +# define curl_thread_t pthread_t * +# define curl_thread_t_null (pthread_t *)0 +# define Curl_mutex_init(m) pthread_mutex_init(m, NULL) +# define Curl_mutex_acquire(m) pthread_mutex_lock(m) +# define Curl_mutex_release(m) pthread_mutex_unlock(m) +# define Curl_mutex_destroy(m) pthread_mutex_destroy(m) +#elif defined(USE_THREADS_WIN32) +# define CURL_STDCALL __stdcall +# define curl_mutex_t CRITICAL_SECTION +# define curl_thread_t HANDLE +# define curl_thread_t_null (HANDLE)0 +# if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \ + (_WIN32_WINNT < _WIN32_WINNT_VISTA) || \ + (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)) +# define Curl_mutex_init(m) InitializeCriticalSection(m) +# else +# define Curl_mutex_init(m) InitializeCriticalSectionEx(m, 0, 1) +# endif +# define Curl_mutex_acquire(m) EnterCriticalSection(m) +# define Curl_mutex_release(m) LeaveCriticalSection(m) +# define Curl_mutex_destroy(m) DeleteCriticalSection(m) +#endif + +#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) + +/* !checksrc! disable SPACEBEFOREPAREN 1 */ +curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *), + void *arg); + +void Curl_thread_destroy(curl_thread_t hnd); + +int Curl_thread_join(curl_thread_t *hnd); + +#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */ + +#endif /* HEADER_CURL_THREADS_H */ diff --git a/libcurl/lib/curlx.h b/libcurl/lib/curlx.h new file mode 100644 index 0000000..3e9b516 --- /dev/null +++ b/libcurl/lib/curlx.h @@ -0,0 +1,103 @@ +#ifndef HEADER_CURL_CURLX_H +#define HEADER_CURL_CURLX_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Defines protos and includes all header files that provide the curlx_* + * functions. The curlx_* functions are not part of the libcurl API, but are + * stand-alone functions whose sources can be built and linked by apps if need + * be. + */ + +#include +/* this is still a public header file that provides the curl_mprintf() + functions while they still are offered publicly. They will be made library- + private one day */ + +#include "strcase.h" +/* "strcase.h" provides the strcasecompare protos */ + +#include "strtoofft.h" +/* "strtoofft.h" provides this function: curlx_strtoofft(), returns a + curl_off_t number from a given string. +*/ + +#include "nonblock.h" +/* "nonblock.h" provides curlx_nonblock() */ + +#include "warnless.h" +/* "warnless.h" provides functions: + + curlx_ultous() + curlx_ultouc() + curlx_uztosi() +*/ + +/* Now setup curlx_ * names for the functions that are to become curlx_ and + be removed from a future libcurl official API: + curlx_getenv + curlx_mprintf (and its variations) + curlx_strcasecompare + curlx_strncasecompare + +*/ + +#define curlx_getenv curl_getenv +#define curlx_mvsnprintf curl_mvsnprintf +#define curlx_msnprintf curl_msnprintf +#define curlx_maprintf curl_maprintf +#define curlx_mvaprintf curl_mvaprintf +#define curlx_msprintf curl_msprintf +#define curlx_mprintf curl_mprintf +#define curlx_mfprintf curl_mfprintf +#define curlx_mvsprintf curl_mvsprintf +#define curlx_mvprintf curl_mvprintf +#define curlx_mvfprintf curl_mvfprintf + +#ifdef ENABLE_CURLX_PRINTF +/* If this define is set, we define all "standard" printf() functions to use + the curlx_* version instead. It makes the source code transparent and + easier to understand/patch. Undefine them first. */ +# undef printf +# undef fprintf +# undef sprintf +# undef msnprintf +# undef vprintf +# undef vfprintf +# undef vsprintf +# undef mvsnprintf +# undef aprintf +# undef vaprintf + +# define printf curlx_mprintf +# define fprintf curlx_mfprintf +# define sprintf curlx_msprintf +# define msnprintf curlx_msnprintf +# define vprintf curlx_mvprintf +# define vfprintf curlx_mvfprintf +# define mvsnprintf curlx_mvsnprintf +# define aprintf curlx_maprintf +# define vaprintf curlx_mvaprintf +#endif /* ENABLE_CURLX_PRINTF */ + +#endif /* HEADER_CURL_CURLX_H */ diff --git a/libcurl/lib/dict.c b/libcurl/lib/dict.c new file mode 100644 index 0000000..208a233 --- /dev/null +++ b/libcurl/lib/dict.c @@ -0,0 +1,276 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_DICT + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#include "urldata.h" +#include +#include "transfer.h" +#include "sendf.h" +#include "escape.h" +#include "progress.h" +#include "dict.h" +#include "strcase.h" +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* + * Forward declarations. + */ + +static CURLcode dict_do(struct connectdata *conn, bool *done); + +/* + * DICT protocol handler. + */ + +const struct Curl_handler Curl_handler_dict = { + "DICT", /* scheme */ + ZERO_NULL, /* setup_connection */ + dict_do, /* do_it */ + ZERO_NULL, /* done */ + ZERO_NULL, /* do_more */ + ZERO_NULL, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_DICT, /* defport */ + CURLPROTO_DICT, /* protocol */ + PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */ +}; + +static char *unescape_word(struct Curl_easy *data, const char *inputbuff) +{ + char *newp = NULL; + char *dictp; + size_t len; + + CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE); + if(!newp || result) + return NULL; + + dictp = malloc(len*2 + 1); /* add one for terminating zero */ + if(dictp) { + char *ptr; + char ch; + int olen = 0; + /* According to RFC2229 section 2.2, these letters need to be escaped with + \[letter] */ + for(ptr = newp; + (ch = *ptr) != 0; + ptr++) { + if((ch <= 32) || (ch == 127) || + (ch == '\'') || (ch == '\"') || (ch == '\\')) { + dictp[olen++] = '\\'; + } + dictp[olen++] = ch; + } + dictp[olen] = 0; + } + free(newp); + return dictp; +} + +static CURLcode dict_do(struct connectdata *conn, bool *done) +{ + char *word; + char *eword; + char *ppath; + char *database = NULL; + char *strategy = NULL; + char *nthdef = NULL; /* This is not part of the protocol, but required + by RFC 2229 */ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; + + char *path = data->state.up.path; + + *done = TRUE; /* unconditionally */ + + if(conn->bits.user_passwd) { + /* AUTH is missing */ + } + + if(strncasecompare(path, DICT_MATCH, sizeof(DICT_MATCH)-1) || + strncasecompare(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) || + strncasecompare(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) { + + word = strchr(path, ':'); + if(word) { + word++; + database = strchr(word, ':'); + if(database) { + *database++ = (char)0; + strategy = strchr(database, ':'); + if(strategy) { + *strategy++ = (char)0; + nthdef = strchr(strategy, ':'); + if(nthdef) { + *nthdef = (char)0; + } + } + } + } + + if((word == NULL) || (*word == (char)0)) { + infof(data, "lookup word is missing\n"); + word = (char *)"default"; + } + if((database == NULL) || (*database == (char)0)) { + database = (char *)"!"; + } + if((strategy == NULL) || (*strategy == (char)0)) { + strategy = (char *)"."; + } + + eword = unescape_word(data, word); + if(!eword) + return CURLE_OUT_OF_MEMORY; + + result = Curl_sendf(sockfd, conn, + "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" + "MATCH " + "%s " /* database */ + "%s " /* strategy */ + "%s\r\n" /* word */ + "QUIT\r\n", + + database, + strategy, + eword + ); + + free(eword); + + if(result) { + failf(data, "Failed sending DICT request"); + return result; + } + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); /* no upload */ + } + else if(strncasecompare(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) || + strncasecompare(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) || + strncasecompare(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) { + + word = strchr(path, ':'); + if(word) { + word++; + database = strchr(word, ':'); + if(database) { + *database++ = (char)0; + nthdef = strchr(database, ':'); + if(nthdef) { + *nthdef = (char)0; + } + } + } + + if((word == NULL) || (*word == (char)0)) { + infof(data, "lookup word is missing\n"); + word = (char *)"default"; + } + if((database == NULL) || (*database == (char)0)) { + database = (char *)"!"; + } + + eword = unescape_word(data, word); + if(!eword) + return CURLE_OUT_OF_MEMORY; + + result = Curl_sendf(sockfd, conn, + "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" + "DEFINE " + "%s " /* database */ + "%s\r\n" /* word */ + "QUIT\r\n", + database, + eword); + + free(eword); + + if(result) { + failf(data, "Failed sending DICT request"); + return result; + } + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); + } + else { + + ppath = strchr(path, '/'); + if(ppath) { + int i; + + ppath++; + for(i = 0; ppath[i]; i++) { + if(ppath[i] == ':') + ppath[i] = ' '; + } + result = Curl_sendf(sockfd, conn, + "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" + "%s\r\n" + "QUIT\r\n", ppath); + if(result) { + failf(data, "Failed sending DICT request"); + return result; + } + + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); + } + } + + return CURLE_OK; +} +#endif /*CURL_DISABLE_DICT*/ diff --git a/libcurl/lib/dict.h b/libcurl/lib/dict.h new file mode 100644 index 0000000..12c0f33 --- /dev/null +++ b/libcurl/lib/dict.h @@ -0,0 +1,29 @@ +#ifndef HEADER_CURL_DICT_H +#define HEADER_CURL_DICT_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#ifndef CURL_DISABLE_DICT +extern const struct Curl_handler Curl_handler_dict; +#endif + +#endif /* HEADER_CURL_DICT_H */ diff --git a/libcurl/lib/doh.c b/libcurl/lib/doh.c new file mode 100644 index 0000000..6d1f330 --- /dev/null +++ b/libcurl/lib/doh.c @@ -0,0 +1,967 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2018 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_DOH + +#include "urldata.h" +#include "curl_addrinfo.h" +#include "doh.h" + +#include "sendf.h" +#include "multiif.h" +#include "url.h" +#include "share.h" +#include "curl_base64.h" +#include "connect.h" +#include "strdup.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#define DNS_CLASS_IN 0x01 +#define DOH_MAX_RESPONSE_SIZE 3000 /* bytes */ + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static const char * const errors[]={ + "", + "Bad label", + "Out of range", + "Label loop", + "Too small", + "Out of memory", + "RDATA length", + "Malformat", + "Bad RCODE", + "Unexpected TYPE", + "Unexpected CLASS", + "No content", + "Bad ID" +}; + +static const char *doh_strerror(DOHcode code) +{ + if((code >= DOH_OK) && (code <= DOH_DNS_BAD_ID)) + return errors[code]; + return "bad error code"; +} +#endif + +#ifdef DEBUGBUILD +#define UNITTEST +#else +#define UNITTEST static +#endif + +UNITTEST DOHcode doh_encode(const char *host, + DNStype dnstype, + unsigned char *dnsp, /* buffer */ + size_t len, /* buffer size */ + size_t *olen) /* output length */ +{ + size_t hostlen = strlen(host); + unsigned char *orig = dnsp; + const char *hostp = host; + + if(len < (12 + hostlen + 4)) + return DOH_TOO_SMALL_BUFFER; + + *dnsp++ = 0; /* 16 bit id */ + *dnsp++ = 0; + *dnsp++ = 0x01; /* |QR| Opcode |AA|TC|RD| Set the RD bit */ + *dnsp++ = '\0'; /* |RA| Z | RCODE | */ + *dnsp++ = '\0'; + *dnsp++ = 1; /* QDCOUNT (number of entries in the question section) */ + *dnsp++ = '\0'; + *dnsp++ = '\0'; /* ANCOUNT */ + *dnsp++ = '\0'; + *dnsp++ = '\0'; /* NSCOUNT */ + *dnsp++ = '\0'; + *dnsp++ = '\0'; /* ARCOUNT */ + + /* store a QNAME */ + do { + char *dot = strchr(hostp, '.'); + size_t labellen; + bool found = false; + if(dot) { + found = true; + labellen = dot - hostp; + } + else + labellen = strlen(hostp); + if(labellen > 63) { + /* too long label, error out */ + *olen = 0; + return DOH_DNS_BAD_LABEL; + } + *dnsp++ = (unsigned char)labellen; + memcpy(dnsp, hostp, labellen); + dnsp += labellen; + hostp += labellen + 1; + if(!found) { + *dnsp++ = 0; /* terminating zero */ + break; + } + } while(1); + + *dnsp++ = '\0'; /* upper 8 bit TYPE */ + *dnsp++ = (unsigned char)dnstype; + *dnsp++ = '\0'; /* upper 8 bit CLASS */ + *dnsp++ = DNS_CLASS_IN; /* IN - "the Internet" */ + + *olen = dnsp - orig; + return DOH_OK; +} + +static size_t +doh_write_cb(void *contents, size_t size, size_t nmemb, void *userp) +{ + size_t realsize = size * nmemb; + struct dohresponse *mem = (struct dohresponse *)userp; + + if((mem->size + realsize) > DOH_MAX_RESPONSE_SIZE) + /* suspiciously much for us */ + return 0; + + mem->memory = Curl_saferealloc(mem->memory, mem->size + realsize); + if(!mem->memory) + /* out of memory! */ + return 0; + + memcpy(&(mem->memory[mem->size]), contents, realsize); + mem->size += realsize; + + return realsize; +} + +/* called from multi.c when this DOH transfer is complete */ +static int Curl_doh_done(struct Curl_easy *doh, CURLcode result) +{ + struct Curl_easy *data = doh->set.dohfor; + /* so one of the DOH request done for the 'data' transfer is now complete! */ + data->req.doh.pending--; + infof(data, "a DOH request is completed, %u to go\n", data->req.doh.pending); + if(result) + infof(data, "DOH request %s\n", curl_easy_strerror(result)); + + if(!data->req.doh.pending) { + /* DOH completed */ + curl_slist_free_all(data->req.doh.headers); + data->req.doh.headers = NULL; + Curl_expire(data, 0, EXPIRE_RUN_NOW); + } + return 0; +} + +#define ERROR_CHECK_SETOPT(x,y) \ +do { \ + result = curl_easy_setopt(doh, x, y); \ + if(result) \ + goto error; \ +} WHILE_FALSE + +static CURLcode dohprobe(struct Curl_easy *data, + struct dnsprobe *p, DNStype dnstype, + const char *host, + const char *url, CURLM *multi, + struct curl_slist *headers) +{ + struct Curl_easy *doh = NULL; + char *nurl = NULL; + CURLcode result = CURLE_OK; + timediff_t timeout_ms; + DOHcode d = doh_encode(host, dnstype, p->dohbuffer, sizeof(p->dohbuffer), + &p->dohlen); + if(d) { + failf(data, "Failed to encode DOH packet [%d]\n", d); + return CURLE_OUT_OF_MEMORY; + } + + p->dnstype = dnstype; + p->serverdoh.memory = NULL; + /* the memory will be grown as needed by realloc in the doh_write_cb + function */ + p->serverdoh.size = 0; + + /* Note: this is code for sending the DoH request with GET but there's still + no logic that actually enables this. We should either add that ability or + yank out the GET code. Discuss! */ + if(data->set.doh_get) { + char *b64; + size_t b64len; + result = Curl_base64url_encode(data, (char *)p->dohbuffer, p->dohlen, + &b64, &b64len); + if(result) + goto error; + nurl = aprintf("%s?dns=%s", url, b64); + free(b64); + if(!nurl) { + result = CURLE_OUT_OF_MEMORY; + goto error; + } + url = nurl; + } + + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + /* Curl_open() is the internal version of curl_easy_init() */ + result = Curl_open(&doh); + if(!result) { + /* pass in the struct pointer via a local variable to please coverity and + the gcc typecheck helpers */ + struct dohresponse *resp = &p->serverdoh; + ERROR_CHECK_SETOPT(CURLOPT_URL, url); + ERROR_CHECK_SETOPT(CURLOPT_WRITEFUNCTION, doh_write_cb); + ERROR_CHECK_SETOPT(CURLOPT_WRITEDATA, resp); + if(!data->set.doh_get) { + ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDS, p->dohbuffer); + ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDSIZE, (long)p->dohlen); + } + ERROR_CHECK_SETOPT(CURLOPT_HTTPHEADER, headers); +#ifdef USE_NGHTTP2 + ERROR_CHECK_SETOPT(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS); +#endif +#ifndef CURLDEBUG + /* enforce HTTPS if not debug */ + ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); +#endif + ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms); + if(data->set.verbose) + ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L); + if(data->set.no_signal) + ERROR_CHECK_SETOPT(CURLOPT_NOSIGNAL, 1L); + + /* Inherit *some* SSL options from the user's transfer. This is a + best-guess as to which options are needed for compatibility. #3661 */ + if(data->set.ssl.falsestart) + ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L); + if(data->set.ssl.primary.verifyhost) + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, 2L); + if(data->set.proxy_ssl.primary.verifyhost) + ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYHOST, 2L); + if(data->set.ssl.primary.verifypeer) + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L); + if(data->set.proxy_ssl.primary.verifypeer) + ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYPEER, 1L); + if(data->set.ssl.primary.verifystatus) + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, 1L); + if(data->set.str[STRING_SSL_CAFILE_ORIG]) { + ERROR_CHECK_SETOPT(CURLOPT_CAINFO, + data->set.str[STRING_SSL_CAFILE_ORIG]); + } + if(data->set.str[STRING_SSL_CAFILE_PROXY]) { + ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAINFO, + data->set.str[STRING_SSL_CAFILE_PROXY]); + } + if(data->set.str[STRING_SSL_CAPATH_ORIG]) { + ERROR_CHECK_SETOPT(CURLOPT_CAPATH, + data->set.str[STRING_SSL_CAPATH_ORIG]); + } + if(data->set.str[STRING_SSL_CAPATH_PROXY]) { + ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH, + data->set.str[STRING_SSL_CAPATH_PROXY]); + } + if(data->set.str[STRING_SSL_CRLFILE_ORIG]) { + ERROR_CHECK_SETOPT(CURLOPT_CRLFILE, + data->set.str[STRING_SSL_CRLFILE_ORIG]); + } + if(data->set.str[STRING_SSL_CRLFILE_PROXY]) { + ERROR_CHECK_SETOPT(CURLOPT_PROXY_CRLFILE, + data->set.str[STRING_SSL_CRLFILE_PROXY]); + } + if(data->set.ssl.certinfo) + ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L); + if(data->set.str[STRING_SSL_RANDOM_FILE]) { + ERROR_CHECK_SETOPT(CURLOPT_RANDOM_FILE, + data->set.str[STRING_SSL_RANDOM_FILE]); + } + if(data->set.str[STRING_SSL_EGDSOCKET]) { + ERROR_CHECK_SETOPT(CURLOPT_EGDSOCKET, + data->set.str[STRING_SSL_EGDSOCKET]); + } + if(data->set.ssl.no_revoke) + ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); + if(data->set.proxy_ssl.no_revoke) + ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); + if(data->set.ssl.fsslctx) + ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx); + if(data->set.ssl.fsslctxp) + ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp); + + doh->set.fmultidone = Curl_doh_done; + doh->set.dohfor = data; /* identify for which transfer this is done */ + p->easy = doh; + + /* add this transfer to the multi handle */ + if(curl_multi_add_handle(multi, doh)) + goto error; + } + else + goto error; + free(nurl); + return CURLE_OK; + + error: + free(nurl); + Curl_close(doh); + return result; +} + +/* + * Curl_doh() resolves a name using DOH. It resolves a name and returns a + * 'Curl_addrinfo *' with the address information. + */ + +Curl_addrinfo *Curl_doh(struct connectdata *conn, + const char *hostname, + int port, + int *waitp) +{ + struct Curl_easy *data = conn->data; + CURLcode result = CURLE_OK; + *waitp = TRUE; /* this never returns synchronously */ + (void)conn; + (void)hostname; + (void)port; + + /* start clean, consider allocating this struct on demand */ + memset(&data->req.doh, 0, sizeof(struct dohdata)); + + data->req.doh.host = hostname; + data->req.doh.port = port; + data->req.doh.headers = + curl_slist_append(NULL, + "Content-Type: application/dns-message"); + if(!data->req.doh.headers) + goto error; + + if(conn->ip_version != CURL_IPRESOLVE_V6) { + /* create IPv4 DOH request */ + result = dohprobe(data, &data->req.doh.probe[0], DNS_TYPE_A, + hostname, data->set.str[STRING_DOH], + data->multi, data->req.doh.headers); + if(result) + goto error; + data->req.doh.pending++; + } + + if(conn->ip_version != CURL_IPRESOLVE_V4) { + /* create IPv6 DOH request */ + result = dohprobe(data, &data->req.doh.probe[1], DNS_TYPE_AAAA, + hostname, data->set.str[STRING_DOH], + data->multi, data->req.doh.headers); + if(result) + goto error; + data->req.doh.pending++; + } + return NULL; + + error: + curl_slist_free_all(data->req.doh.headers); + data->req.doh.headers = NULL; + curl_easy_cleanup(data->req.doh.probe[0].easy); + data->req.doh.probe[0].easy = NULL; + curl_easy_cleanup(data->req.doh.probe[1].easy); + data->req.doh.probe[1].easy = NULL; + return NULL; +} + +static DOHcode skipqname(unsigned char *doh, size_t dohlen, + unsigned int *indexp) +{ + unsigned char length; + do { + if(dohlen < (*indexp + 1)) + return DOH_DNS_OUT_OF_RANGE; + length = doh[*indexp]; + if((length & 0xc0) == 0xc0) { + /* name pointer, advance over it and be done */ + if(dohlen < (*indexp + 2)) + return DOH_DNS_OUT_OF_RANGE; + *indexp += 2; + break; + } + if(length & 0xc0) + return DOH_DNS_BAD_LABEL; + if(dohlen < (*indexp + 1 + length)) + return DOH_DNS_OUT_OF_RANGE; + *indexp += 1 + length; + } while(length); + return DOH_OK; +} + +static unsigned short get16bit(unsigned char *doh, int index) +{ + return (unsigned short)((doh[index] << 8) | doh[index + 1]); +} + +static unsigned int get32bit(unsigned char *doh, int index) +{ + return (doh[index] << 24) | (doh[index + 1] << 16) | + (doh[index + 2] << 8) | doh[index + 3]; +} + +static DOHcode store_a(unsigned char *doh, int index, struct dohentry *d) +{ + /* silently ignore addresses over the limit */ + if(d->numaddr < DOH_MAX_ADDR) { + struct dohaddr *a = &d->addr[d->numaddr]; + a->type = DNS_TYPE_A; + memcpy(&a->ip.v4, &doh[index], 4); + d->numaddr++; + } + return DOH_OK; +} + +static DOHcode store_aaaa(unsigned char *doh, int index, struct dohentry *d) +{ + /* silently ignore addresses over the limit */ + if(d->numaddr < DOH_MAX_ADDR) { + struct dohaddr *a = &d->addr[d->numaddr]; + a->type = DNS_TYPE_AAAA; + memcpy(&a->ip.v6, &doh[index], 16); + d->numaddr++; + } + return DOH_OK; +} + +static DOHcode cnameappend(struct cnamestore *c, + unsigned char *src, + size_t len) +{ + if(!c->alloc) { + c->allocsize = len + 1; + c->alloc = malloc(c->allocsize); + if(!c->alloc) + return DOH_OUT_OF_MEM; + } + else if(c->allocsize < (c->allocsize + len + 1)) { + char *ptr; + c->allocsize += len + 1; + ptr = realloc(c->alloc, c->allocsize); + if(!ptr) { + free(c->alloc); + return DOH_OUT_OF_MEM; + } + c->alloc = ptr; + } + memcpy(&c->alloc[c->len], src, len); + c->len += len; + c->alloc[c->len] = 0; /* keep it zero terminated */ + return DOH_OK; +} + +static DOHcode store_cname(unsigned char *doh, + size_t dohlen, + unsigned int index, + struct dohentry *d) +{ + struct cnamestore *c; + unsigned int loop = 128; /* a valid DNS name can never loop this much */ + unsigned char length; + + if(d->numcname == DOH_MAX_CNAME) + return DOH_OK; /* skip! */ + + c = &d->cname[d->numcname++]; + do { + if(index >= dohlen) + return DOH_DNS_OUT_OF_RANGE; + length = doh[index]; + if((length & 0xc0) == 0xc0) { + int newpos; + /* name pointer, get the new offset (14 bits) */ + if((index + 1) >= dohlen) + return DOH_DNS_OUT_OF_RANGE; + + /* move to the the new index */ + newpos = (length & 0x3f) << 8 | doh[index + 1]; + index = newpos; + continue; + } + else if(length & 0xc0) + return DOH_DNS_BAD_LABEL; /* bad input */ + else + index++; + + if(length) { + DOHcode rc; + if(c->len) { + rc = cnameappend(c, (unsigned char *)".", 1); + if(rc) + return rc; + } + if((index + length) > dohlen) + return DOH_DNS_BAD_LABEL; + + rc = cnameappend(c, &doh[index], length); + if(rc) + return rc; + index += length; + } + } while(length && --loop); + + if(!loop) + return DOH_DNS_LABEL_LOOP; + return DOH_OK; +} + +static DOHcode rdata(unsigned char *doh, + size_t dohlen, + unsigned short rdlength, + unsigned short type, + int index, + struct dohentry *d) +{ + /* RDATA + - A (TYPE 1): 4 bytes + - AAAA (TYPE 28): 16 bytes + - NS (TYPE 2): N bytes */ + DOHcode rc; + + switch(type) { + case DNS_TYPE_A: + if(rdlength != 4) + return DOH_DNS_RDATA_LEN; + rc = store_a(doh, index, d); + if(rc) + return rc; + break; + case DNS_TYPE_AAAA: + if(rdlength != 16) + return DOH_DNS_RDATA_LEN; + rc = store_aaaa(doh, index, d); + if(rc) + return rc; + break; + case DNS_TYPE_CNAME: + rc = store_cname(doh, dohlen, index, d); + if(rc) + return rc; + break; + default: + /* unsupported type, just skip it */ + break; + } + return DOH_OK; +} + +static void init_dohentry(struct dohentry *de) +{ + memset(de, 0, sizeof(*de)); + de->ttl = INT_MAX; +} + + +UNITTEST DOHcode doh_decode(unsigned char *doh, + size_t dohlen, + DNStype dnstype, + struct dohentry *d) +{ + unsigned char rcode; + unsigned short qdcount; + unsigned short ancount; + unsigned short type = 0; + unsigned short rdlength; + unsigned short nscount; + unsigned short arcount; + unsigned int index = 12; + DOHcode rc; + + if(dohlen < 12) + return DOH_TOO_SMALL_BUFFER; /* too small */ + if(!doh || doh[0] || doh[1]) + return DOH_DNS_BAD_ID; /* bad ID */ + rcode = doh[3] & 0x0f; + if(rcode) + return DOH_DNS_BAD_RCODE; /* bad rcode */ + + qdcount = get16bit(doh, 4); + while(qdcount) { + rc = skipqname(doh, dohlen, &index); + if(rc) + return rc; /* bad qname */ + if(dohlen < (index + 4)) + return DOH_DNS_OUT_OF_RANGE; + index += 4; /* skip question's type and class */ + qdcount--; + } + + ancount = get16bit(doh, 6); + while(ancount) { + unsigned short class; + unsigned int ttl; + + rc = skipqname(doh, dohlen, &index); + if(rc) + return rc; /* bad qname */ + + if(dohlen < (index + 2)) + return DOH_DNS_OUT_OF_RANGE; + + type = get16bit(doh, index); + if((type != DNS_TYPE_CNAME) && (type != dnstype)) + /* Not the same type as was asked for nor CNAME */ + return DOH_DNS_UNEXPECTED_TYPE; + index += 2; + + if(dohlen < (index + 2)) + return DOH_DNS_OUT_OF_RANGE; + class = get16bit(doh, index); + if(DNS_CLASS_IN != class) + return DOH_DNS_UNEXPECTED_CLASS; /* unsupported */ + index += 2; + + if(dohlen < (index + 4)) + return DOH_DNS_OUT_OF_RANGE; + + ttl = get32bit(doh, index); + if(ttl < d->ttl) + d->ttl = ttl; + index += 4; + + if(dohlen < (index + 2)) + return DOH_DNS_OUT_OF_RANGE; + + rdlength = get16bit(doh, index); + index += 2; + if(dohlen < (index + rdlength)) + return DOH_DNS_OUT_OF_RANGE; + + rc = rdata(doh, dohlen, rdlength, type, index, d); + if(rc) + return rc; /* bad rdata */ + index += rdlength; + ancount--; + } + + nscount = get16bit(doh, 8); + while(nscount) { + rc = skipqname(doh, dohlen, &index); + if(rc) + return rc; /* bad qname */ + + if(dohlen < (index + 8)) + return DOH_DNS_OUT_OF_RANGE; + + index += 2 + 2 + 4; /* type, class and ttl */ + + if(dohlen < (index + 2)) + return DOH_DNS_OUT_OF_RANGE; + + rdlength = get16bit(doh, index); + index += 2; + if(dohlen < (index + rdlength)) + return DOH_DNS_OUT_OF_RANGE; + index += rdlength; + nscount--; + } + + arcount = get16bit(doh, 10); + while(arcount) { + rc = skipqname(doh, dohlen, &index); + if(rc) + return rc; /* bad qname */ + + if(dohlen < (index + 8)) + return DOH_DNS_OUT_OF_RANGE; + + index += 2 + 2 + 4; /* type, class and ttl */ + + if(dohlen < (index + 2)) + return DOH_DNS_OUT_OF_RANGE; + + rdlength = get16bit(doh, index); + index += 2; + if(dohlen < (index + rdlength)) + return DOH_DNS_OUT_OF_RANGE; + index += rdlength; + arcount--; + } + + if(index != dohlen) + return DOH_DNS_MALFORMAT; /* something is wrong */ + + if((type != DNS_TYPE_NS) && !d->numcname && !d->numaddr) + /* nothing stored! */ + return DOH_NO_CONTENT; + + return DOH_OK; /* ok */ +} + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static void showdoh(struct Curl_easy *data, + struct dohentry *d) +{ + int i; + infof(data, "TTL: %u seconds\n", d->ttl); + for(i = 0; i < d->numaddr; i++) { + struct dohaddr *a = &d->addr[i]; + if(a->type == DNS_TYPE_A) { + infof(data, "DOH A: %u.%u.%u.%u\n", + a->ip.v4[0], a->ip.v4[1], + a->ip.v4[2], a->ip.v4[3]); + } + else if(a->type == DNS_TYPE_AAAA) { + int j; + char buffer[128]; + char *ptr; + size_t len; + msnprintf(buffer, 128, "DOH AAAA: "); + ptr = &buffer[10]; + len = 118; + for(j = 0; j < 16; j += 2) { + size_t l; + msnprintf(ptr, len, "%s%02x%02x", j?":":"", d->addr[i].ip.v6[j], + d->addr[i].ip.v6[j + 1]); + l = strlen(ptr); + len -= l; + ptr += l; + } + infof(data, "%s\n", buffer); + } + } + for(i = 0; i < d->numcname; i++) { + infof(data, "CNAME: %s\n", d->cname[i].alloc); + } +} +#else +#define showdoh(x,y) +#endif + +/* + * doh2ai() + * + * This function returns a pointer to the first element of a newly allocated + * Curl_addrinfo struct linked list filled with the data from a set of DOH + * lookups. Curl_addrinfo is meant to work like the addrinfo struct does for + * a IPv6 stack, but usable also for IPv4, all hosts and environments. + * + * The memory allocated by this function *MUST* be free'd later on calling + * Curl_freeaddrinfo(). For each successful call to this function there + * must be an associated call later to Curl_freeaddrinfo(). + */ + +static Curl_addrinfo * +doh2ai(const struct dohentry *de, const char *hostname, int port) +{ + Curl_addrinfo *ai; + Curl_addrinfo *prevai = NULL; + Curl_addrinfo *firstai = NULL; + struct sockaddr_in *addr; +#ifdef ENABLE_IPV6 + struct sockaddr_in6 *addr6; +#endif + CURLcode result = CURLE_OK; + int i; + + if(!de) + /* no input == no output! */ + return NULL; + + for(i = 0; i < de->numaddr; i++) { + size_t ss_size; + CURL_SA_FAMILY_T addrtype; + if(de->addr[i].type == DNS_TYPE_AAAA) { +#ifndef ENABLE_IPV6 + /* we can't handle IPv6 addresses */ + continue; +#else + ss_size = sizeof(struct sockaddr_in6); + addrtype = AF_INET6; +#endif + } + else { + ss_size = sizeof(struct sockaddr_in); + addrtype = AF_INET; + } + + ai = calloc(1, sizeof(Curl_addrinfo)); + if(!ai) { + result = CURLE_OUT_OF_MEMORY; + break; + } + ai->ai_canonname = strdup(hostname); + if(!ai->ai_canonname) { + result = CURLE_OUT_OF_MEMORY; + free(ai); + break; + } + ai->ai_addr = calloc(1, ss_size); + if(!ai->ai_addr) { + result = CURLE_OUT_OF_MEMORY; + free(ai->ai_canonname); + free(ai); + break; + } + + if(!firstai) + /* store the pointer we want to return from this function */ + firstai = ai; + + if(prevai) + /* make the previous entry point to this */ + prevai->ai_next = ai; + + ai->ai_family = addrtype; + + /* we return all names as STREAM, so when using this address for TFTP + the type must be ignored and conn->socktype be used instead! */ + ai->ai_socktype = SOCK_STREAM; + + ai->ai_addrlen = (curl_socklen_t)ss_size; + + /* leave the rest of the struct filled with zero */ + + switch(ai->ai_family) { + case AF_INET: + addr = (void *)ai->ai_addr; /* storage area for this info */ + DEBUGASSERT(sizeof(struct in_addr) == sizeof(de->addr[i].ip.v4)); + memcpy(&addr->sin_addr, &de->addr[i].ip.v4, sizeof(struct in_addr)); + addr->sin_family = (CURL_SA_FAMILY_T)addrtype; + addr->sin_port = htons((unsigned short)port); + break; + +#ifdef ENABLE_IPV6 + case AF_INET6: + addr6 = (void *)ai->ai_addr; /* storage area for this info */ + DEBUGASSERT(sizeof(struct in6_addr) == sizeof(de->addr[i].ip.v6)); + memcpy(&addr6->sin6_addr, &de->addr[i].ip.v6, sizeof(struct in6_addr)); + addr6->sin6_family = (CURL_SA_FAMILY_T)addrtype; + addr6->sin6_port = htons((unsigned short)port); + break; +#endif + } + + prevai = ai; + } + + if(result) { + Curl_freeaddrinfo(firstai); + firstai = NULL; + } + + return firstai; +} + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static const char *type2name(DNStype dnstype) +{ + return (dnstype == DNS_TYPE_A)?"A":"AAAA"; +} +#endif + +UNITTEST void de_cleanup(struct dohentry *d) +{ + int i = 0; + for(i = 0; i < d->numcname; i++) { + free(d->cname[i].alloc); + } +} + +CURLcode Curl_doh_is_resolved(struct connectdata *conn, + struct Curl_dns_entry **dnsp) +{ + struct Curl_easy *data = conn->data; + *dnsp = NULL; /* defaults to no response */ + + if(!data->req.doh.probe[0].easy && !data->req.doh.probe[1].easy) { + failf(data, "Could not DOH-resolve: %s", conn->async.hostname); + return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY: + CURLE_COULDNT_RESOLVE_HOST; + } + else if(!data->req.doh.pending) { + DOHcode rc; + DOHcode rc2; + struct dohentry de; + /* remove DOH handles from multi handle and close them */ + curl_multi_remove_handle(data->multi, data->req.doh.probe[0].easy); + Curl_close(data->req.doh.probe[0].easy); + curl_multi_remove_handle(data->multi, data->req.doh.probe[1].easy); + Curl_close(data->req.doh.probe[1].easy); + + /* parse the responses, create the struct and return it! */ + init_dohentry(&de); + rc = doh_decode(data->req.doh.probe[0].serverdoh.memory, + data->req.doh.probe[0].serverdoh.size, + data->req.doh.probe[0].dnstype, + &de); + free(data->req.doh.probe[0].serverdoh.memory); + if(rc) { + infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc), + type2name(data->req.doh.probe[0].dnstype), + data->req.doh.host); + } + rc2 = doh_decode(data->req.doh.probe[1].serverdoh.memory, + data->req.doh.probe[1].serverdoh.size, + data->req.doh.probe[1].dnstype, + &de); + free(data->req.doh.probe[1].serverdoh.memory); + if(rc2) { + infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc2), + type2name(data->req.doh.probe[1].dnstype), + data->req.doh.host); + } + if(!rc || !rc2) { + struct Curl_dns_entry *dns; + struct Curl_addrinfo *ai; + + infof(data, "DOH Host name: %s\n", data->req.doh.host); + showdoh(data, &de); + + ai = doh2ai(&de, data->req.doh.host, data->req.doh.port); + if(!ai) { + de_cleanup(&de); + return CURLE_OUT_OF_MEMORY; + } + + if(data->share) + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + + /* we got a response, store it in the cache */ + dns = Curl_cache_addr(data, ai, data->req.doh.host, data->req.doh.port); + + if(data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + + de_cleanup(&de); + if(!dns) + /* returned failure, bail out nicely */ + Curl_freeaddrinfo(ai); + else { + conn->async.dns = dns; + *dnsp = dns; + return CURLE_OK; + } + } + de_cleanup(&de); + + return CURLE_COULDNT_RESOLVE_HOST; + } + + return CURLE_OK; +} + +#endif /* CURL_DISABLE_DOH */ diff --git a/libcurl/lib/doh.h b/libcurl/lib/doh.h new file mode 100644 index 0000000..34bfa6f --- /dev/null +++ b/libcurl/lib/doh.h @@ -0,0 +1,113 @@ +#ifndef HEADER_CURL_DOH_H +#define HEADER_CURL_DOH_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2018 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "urldata.h" +#include "curl_addrinfo.h" + +#ifndef CURL_DISABLE_DOH + +/* + * Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name + * and returns a 'Curl_addrinfo *' with the address information. + */ + +Curl_addrinfo *Curl_doh(struct connectdata *conn, + const char *hostname, + int port, + int *waitp); + +CURLcode Curl_doh_is_resolved(struct connectdata *conn, + struct Curl_dns_entry **dns); + +int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); + +typedef enum { + DOH_OK, + DOH_DNS_BAD_LABEL, /* 1 */ + DOH_DNS_OUT_OF_RANGE, /* 2 */ + DOH_DNS_LABEL_LOOP, /* 3 */ + DOH_TOO_SMALL_BUFFER, /* 4 */ + DOH_OUT_OF_MEM, /* 5 */ + DOH_DNS_RDATA_LEN, /* 6 */ + DOH_DNS_MALFORMAT, /* 7 */ + DOH_DNS_BAD_RCODE, /* 8 - no such name */ + DOH_DNS_UNEXPECTED_TYPE, /* 9 */ + DOH_DNS_UNEXPECTED_CLASS, /* 10 */ + DOH_NO_CONTENT, /* 11 */ + DOH_DNS_BAD_ID /* 12 */ +} DOHcode; + +typedef enum { + DNS_TYPE_A = 1, + DNS_TYPE_NS = 2, + DNS_TYPE_CNAME = 5, + DNS_TYPE_AAAA = 28 +} DNStype; + +#define DOH_MAX_ADDR 24 +#define DOH_MAX_CNAME 4 + +struct cnamestore { + size_t len; /* length of cname */ + char *alloc; /* allocated pointer */ + size_t allocsize; /* allocated size */ +}; + +struct dohaddr { + int type; + union { + unsigned char v4[4]; /* network byte order */ + unsigned char v6[16]; + } ip; +}; + +struct dohentry { + unsigned int ttl; + int numaddr; + struct dohaddr addr[DOH_MAX_ADDR]; + int numcname; + struct cnamestore cname[DOH_MAX_CNAME]; +}; + + +#ifdef DEBUGBUILD +DOHcode doh_encode(const char *host, + DNStype dnstype, + unsigned char *dnsp, /* buffer */ + size_t len, /* buffer size */ + size_t *olen); /* output length */ +DOHcode doh_decode(unsigned char *doh, + size_t dohlen, + DNStype dnstype, + struct dohentry *d); +void de_cleanup(struct dohentry *d); +#endif + +#else /* if DOH is disabled */ +#define Curl_doh(a,b,c,d) NULL +#define Curl_doh_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST +#endif + +#endif /* HEADER_CURL_DOH_H */ diff --git a/libcurl/lib/dotdot.c b/libcurl/lib/dotdot.c new file mode 100644 index 0000000..2c6177a --- /dev/null +++ b/libcurl/lib/dotdot.c @@ -0,0 +1,182 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "dotdot.h" +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +/* + * "Remove Dot Segments" + * https://tools.ietf.org/html/rfc3986#section-5.2.4 + */ + +/* + * Curl_dedotdotify() + * @unittest: 1395 + * + * This function gets a zero-terminated path with dot and dotdot sequences + * passed in and strips them off according to the rules in RFC 3986 section + * 5.2.4. + * + * The function handles a query part ('?' + stuff) appended but it expects + * that fragments ('#' + stuff) have already been cut off. + * + * RETURNS + * + * an allocated dedotdotified output string + */ +char *Curl_dedotdotify(const char *input) +{ + size_t inlen = strlen(input); + char *clone; + size_t clen = inlen; /* the length of the cloned input */ + char *out = malloc(inlen + 1); + char *outptr; + char *orgclone; + char *queryp; + if(!out) + return NULL; /* out of memory */ + + *out = 0; /* zero terminates, for inputs like "./" */ + + /* get a cloned copy of the input */ + clone = strdup(input); + if(!clone) { + free(out); + return NULL; + } + orgclone = clone; + outptr = out; + + if(!*clone) { + /* zero length string, return that */ + free(out); + return clone; + } + + /* + * To handle query-parts properly, we must find it and remove it during the + * dotdot-operation and then append it again at the end to the output + * string. + */ + queryp = strchr(clone, '?'); + if(queryp) + *queryp = 0; + + do { + + /* A. If the input buffer begins with a prefix of "../" or "./", then + remove that prefix from the input buffer; otherwise, */ + + if(!strncmp("./", clone, 2)) { + clone += 2; + clen -= 2; + } + else if(!strncmp("../", clone, 3)) { + clone += 3; + clen -= 3; + } + + /* B. if the input buffer begins with a prefix of "/./" or "/.", where + "." is a complete path segment, then replace that prefix with "/" in + the input buffer; otherwise, */ + else if(!strncmp("/./", clone, 3)) { + clone += 2; + clen -= 2; + } + else if(!strcmp("/.", clone)) { + clone[1]='/'; + clone++; + clen -= 1; + } + + /* C. if the input buffer begins with a prefix of "/../" or "/..", where + ".." is a complete path segment, then replace that prefix with "/" in + the input buffer and remove the last segment and its preceding "/" (if + any) from the output buffer; otherwise, */ + + else if(!strncmp("/../", clone, 4)) { + clone += 3; + clen -= 3; + /* remove the last segment from the output buffer */ + while(outptr > out) { + outptr--; + if(*outptr == '/') + break; + } + *outptr = 0; /* zero-terminate where it stops */ + } + else if(!strcmp("/..", clone)) { + clone[2]='/'; + clone += 2; + clen -= 2; + /* remove the last segment from the output buffer */ + while(outptr > out) { + outptr--; + if(*outptr == '/') + break; + } + *outptr = 0; /* zero-terminate where it stops */ + } + + /* D. if the input buffer consists only of "." or "..", then remove + that from the input buffer; otherwise, */ + + else if(!strcmp(".", clone) || !strcmp("..", clone)) { + *clone = 0; + *out = 0; + } + + else { + /* E. move the first path segment in the input buffer to the end of + the output buffer, including the initial "/" character (if any) and + any subsequent characters up to, but not including, the next "/" + character or the end of the input buffer. */ + + do { + *outptr++ = *clone++; + clen--; + } while(*clone && (*clone != '/')); + *outptr = 0; + } + + } while(*clone); + + if(queryp) { + size_t qlen; + /* There was a query part, append that to the output. The 'clone' string + may now have been altered so we copy from the original input string + from the correct index. */ + size_t oindex = queryp - orgclone; + qlen = strlen(&input[oindex]); + memcpy(outptr, &input[oindex], qlen + 1); /* include the end zero byte */ + } + + free(orgclone); + return out; +} diff --git a/libcurl/lib/dotdot.h b/libcurl/lib/dotdot.h new file mode 100644 index 0000000..125af43 --- /dev/null +++ b/libcurl/lib/dotdot.h @@ -0,0 +1,25 @@ +#ifndef HEADER_CURL_DOTDOT_H +#define HEADER_CURL_DOTDOT_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +char *Curl_dedotdotify(const char *input); +#endif /* HEADER_CURL_DOTDOT_H */ diff --git a/libcurl/lib/easy.c b/libcurl/lib/easy.c new file mode 100644 index 0000000..a4fff5b --- /dev/null +++ b/libcurl/lib/easy.c @@ -0,0 +1,1160 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +/* + * See comment in curl_memory.h for the explanation of this sanity check. + */ + +#ifdef CURLX_NO_MEMORY_CALLBACKS +#error "libcurl shall not ever be built with CURLX_NO_MEMORY_CALLBACKS defined" +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#include "urldata.h" +#include +#include "transfer.h" +#include "vtls/vtls.h" +#include "url.h" +#include "getinfo.h" +#include "hostip.h" +#include "share.h" +#include "strdup.h" +#include "progress.h" +#include "easyif.h" +#include "multiif.h" +#include "select.h" +#include "sendf.h" /* for failf function prototype */ +#include "connect.h" /* for Curl_getconnectinfo */ +#include "slist.h" +#include "mime.h" +#include "amigaos.h" +#include "non-ascii.h" +#include "warnless.h" +#include "multiif.h" +#include "sigpipe.h" +#include "ssh.h" +#include "setopt.h" +#include "http_digest.h" +#include "system_win32.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +void Curl_version_init(void); + +/* true globals -- for curl_global_init() and curl_global_cleanup() */ +static unsigned int initialized; +static long init_flags; + +/* + * strdup (and other memory functions) is redefined in complicated + * ways, but at this point it must be defined as the system-supplied strdup + * so the callback pointer is initialized correctly. + */ +#if defined(_WIN32_WCE) +#define system_strdup _strdup +#elif !defined(HAVE_STRDUP) +#define system_strdup curlx_strdup +#else +#define system_strdup strdup +#endif + +#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__) +# pragma warning(disable:4232) /* MSVC extension, dllimport identity */ +#endif + +#ifndef __SYMBIAN32__ +/* + * If a memory-using function (like curl_getenv) is used before + * curl_global_init() is called, we need to have these pointers set already. + */ +curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc; +curl_free_callback Curl_cfree = (curl_free_callback)free; +curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc; +curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup; +curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; +#if defined(WIN32) && defined(UNICODE) +curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; +#endif +#else +/* + * Symbian OS doesn't support initialization to code in writable static data. + * Initialization will occur in the curl_global_init() call. + */ +curl_malloc_callback Curl_cmalloc; +curl_free_callback Curl_cfree; +curl_realloc_callback Curl_crealloc; +curl_strdup_callback Curl_cstrdup; +curl_calloc_callback Curl_ccalloc; +#endif + +#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__) +# pragma warning(default:4232) /* MSVC extension, dllimport identity */ +#endif + +/** + * curl_global_init() globally initializes curl given a bitwise set of the + * different features of what to initialize. + */ +static CURLcode global_init(long flags, bool memoryfuncs) +{ + if(initialized++) + return CURLE_OK; + + if(memoryfuncs) { + /* Setup the default memory functions here (again) */ + Curl_cmalloc = (curl_malloc_callback)malloc; + Curl_cfree = (curl_free_callback)free; + Curl_crealloc = (curl_realloc_callback)realloc; + Curl_cstrdup = (curl_strdup_callback)system_strdup; + Curl_ccalloc = (curl_calloc_callback)calloc; +#if defined(WIN32) && defined(UNICODE) + Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; +#endif + } + + if(!Curl_ssl_init()) { + DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n")); + return CURLE_FAILED_INIT; + } + +#ifdef WIN32 + if(Curl_win32_init(flags)) { + DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); + return CURLE_FAILED_INIT; + } +#endif + +#ifdef __AMIGA__ + if(!Curl_amiga_init()) { + DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n")); + return CURLE_FAILED_INIT; + } +#endif + +#ifdef NETWARE + if(netware_init()) { + DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n")); + } +#endif + + if(Curl_resolver_global_init()) { + DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n")); + return CURLE_FAILED_INIT; + } + + (void)Curl_ipv6works(); + +#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT) + if(libssh2_init(0)) { + DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n")); + return CURLE_FAILED_INIT; + } +#endif + +#if defined(USE_LIBSSH) + if(ssh_init()) { + DEBUGF(fprintf(stderr, "Error: libssh_init failed\n")); + return CURLE_FAILED_INIT; + } +#endif + + if(flags & CURL_GLOBAL_ACK_EINTR) + Curl_ack_eintr = 1; + + init_flags = flags; + + Curl_version_init(); + + return CURLE_OK; +} + + +/** + * curl_global_init() globally initializes curl given a bitwise set of the + * different features of what to initialize. + */ +CURLcode curl_global_init(long flags) +{ + return global_init(flags, TRUE); +} + +/* + * curl_global_init_mem() globally initializes curl and also registers the + * user provided callback routines. + */ +CURLcode curl_global_init_mem(long flags, curl_malloc_callback m, + curl_free_callback f, curl_realloc_callback r, + curl_strdup_callback s, curl_calloc_callback c) +{ + /* Invalid input, return immediately */ + if(!m || !f || !r || !s || !c) + return CURLE_FAILED_INIT; + + if(initialized) { + /* Already initialized, don't do it again, but bump the variable anyway to + work like curl_global_init() and require the same amount of cleanup + calls. */ + initialized++; + return CURLE_OK; + } + + /* set memory functions before global_init() in case it wants memory + functions */ + Curl_cmalloc = m; + Curl_cfree = f; + Curl_cstrdup = s; + Curl_crealloc = r; + Curl_ccalloc = c; + + /* Call the actual init function, but without setting */ + return global_init(flags, FALSE); +} + +/** + * curl_global_cleanup() globally cleanups curl, uses the value of + * "init_flags" to determine what needs to be cleaned up and what doesn't. + */ +void curl_global_cleanup(void) +{ + if(!initialized) + return; + + if(--initialized) + return; + + Curl_ssl_cleanup(); + Curl_resolver_global_cleanup(); + +#ifdef WIN32 + Curl_win32_cleanup(init_flags); +#endif + + Curl_amiga_cleanup(); + +#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT) + (void)libssh2_exit(); +#endif + +#if defined(USE_LIBSSH) + (void)ssh_finalize(); +#endif + + init_flags = 0; +} + +/* + * curl_easy_init() is the external interface to alloc, setup and init an + * easy handle that is returned. If anything goes wrong, NULL is returned. + */ +struct Curl_easy *curl_easy_init(void) +{ + CURLcode result; + struct Curl_easy *data; + + /* Make sure we inited the global SSL stuff */ + if(!initialized) { + result = curl_global_init(CURL_GLOBAL_DEFAULT); + if(result) { + /* something in the global init failed, return nothing */ + DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n")); + return NULL; + } + } + + /* We use curl_open() with undefined URL so far */ + result = Curl_open(&data); + if(result) { + DEBUGF(fprintf(stderr, "Error: Curl_open failed\n")); + return NULL; + } + + return data; +} + +#ifdef CURLDEBUG + +struct socketmonitor { + struct socketmonitor *next; /* the next node in the list or NULL */ + struct pollfd socket; /* socket info of what to monitor */ +}; + +struct events { + long ms; /* timeout, run the timeout function when reached */ + bool msbump; /* set TRUE when timeout is set by callback */ + int num_sockets; /* number of nodes in the monitor list */ + struct socketmonitor *list; /* list of sockets to monitor */ + int running_handles; /* store the returned number */ +}; + +/* events_timer + * + * Callback that gets called with a new value when the timeout should be + * updated. + */ + +static int events_timer(struct Curl_multi *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp) /* private callback pointer */ +{ + struct events *ev = userp; + (void)multi; + if(timeout_ms == -1) + /* timeout removed */ + timeout_ms = 0; + else if(timeout_ms == 0) + /* timeout is already reached! */ + timeout_ms = 1; /* trigger asap */ + + ev->ms = timeout_ms; + ev->msbump = TRUE; + return 0; +} + + +/* poll2cselect + * + * convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones + */ +static int poll2cselect(int pollmask) +{ + int omask = 0; + if(pollmask & POLLIN) + omask |= CURL_CSELECT_IN; + if(pollmask & POLLOUT) + omask |= CURL_CSELECT_OUT; + if(pollmask & POLLERR) + omask |= CURL_CSELECT_ERR; + return omask; +} + + +/* socketcb2poll + * + * convert from libcurl' CURL_POLL_* bit definitions to poll()'s + */ +static short socketcb2poll(int pollmask) +{ + short omask = 0; + if(pollmask & CURL_POLL_IN) + omask |= POLLIN; + if(pollmask & CURL_POLL_OUT) + omask |= POLLOUT; + return omask; +} + +/* events_socket + * + * Callback that gets called with information about socket activity to + * monitor. + */ +static int events_socket(struct Curl_easy *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* see above */ + void *userp, /* private callback + pointer */ + void *socketp) /* private socket + pointer */ +{ + struct events *ev = userp; + struct socketmonitor *m; + struct socketmonitor *prev = NULL; + +#if defined(CURL_DISABLE_VERBOSE_STRINGS) + (void) easy; +#endif + (void)socketp; + + m = ev->list; + while(m) { + if(m->socket.fd == s) { + + if(what == CURL_POLL_REMOVE) { + struct socketmonitor *nxt = m->next; + /* remove this node from the list of monitored sockets */ + if(prev) + prev->next = nxt; + else + ev->list = nxt; + free(m); + m = nxt; + infof(easy, "socket cb: socket %d REMOVED\n", s); + } + else { + /* The socket 's' is already being monitored, update the activity + mask. Convert from libcurl bitmask to the poll one. */ + m->socket.events = socketcb2poll(what); + infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s, + (what&CURL_POLL_IN)?"IN":"", + (what&CURL_POLL_OUT)?"OUT":""); + } + break; + } + prev = m; + m = m->next; /* move to next node */ + } + if(!m) { + if(what == CURL_POLL_REMOVE) { + /* this happens a bit too often, libcurl fix perhaps? */ + /* fprintf(stderr, + "%s: socket %d asked to be REMOVED but not present!\n", + __func__, s); */ + } + else { + m = malloc(sizeof(struct socketmonitor)); + if(m) { + m->next = ev->list; + m->socket.fd = s; + m->socket.events = socketcb2poll(what); + m->socket.revents = 0; + ev->list = m; + infof(easy, "socket cb: socket %d ADDED as %s%s\n", s, + (what&CURL_POLL_IN)?"IN":"", + (what&CURL_POLL_OUT)?"OUT":""); + } + else + return CURLE_OUT_OF_MEMORY; + } + } + + return 0; +} + + +/* + * events_setup() + * + * Do the multi handle setups that only event-based transfers need. + */ +static void events_setup(struct Curl_multi *multi, struct events *ev) +{ + /* timer callback */ + curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer); + curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev); + + /* socket callback */ + curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket); + curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev); +} + + +/* wait_or_timeout() + * + * waits for activity on any of the given sockets, or the timeout to trigger. + */ + +static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev) +{ + bool done = FALSE; + CURLMcode mcode = CURLM_OK; + CURLcode result = CURLE_OK; + + while(!done) { + CURLMsg *msg; + struct socketmonitor *m; + struct pollfd *f; + struct pollfd fds[4]; + int numfds = 0; + int pollrc; + int i; + struct curltime before; + struct curltime after; + + /* populate the fds[] array */ + for(m = ev->list, f = &fds[0]; m; m = m->next) { + f->fd = m->socket.fd; + f->events = m->socket.events; + f->revents = 0; + /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */ + f++; + numfds++; + } + + /* get the time stamp to use to figure out how long poll takes */ + before = Curl_now(); + + /* wait for activity or timeout */ + pollrc = Curl_poll(fds, numfds, (int)ev->ms); + + after = Curl_now(); + + ev->msbump = FALSE; /* reset here */ + + if(0 == pollrc) { + /* timeout! */ + ev->ms = 0; + /* fprintf(stderr, "call curl_multi_socket_action(TIMEOUT)\n"); */ + mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0, + &ev->running_handles); + } + else if(pollrc > 0) { + /* loop over the monitored sockets to see which ones had activity */ + for(i = 0; i< numfds; i++) { + if(fds[i].revents) { + /* socket activity, tell libcurl */ + int act = poll2cselect(fds[i].revents); /* convert */ + infof(multi->easyp, "call curl_multi_socket_action(socket %d)\n", + fds[i].fd); + mcode = curl_multi_socket_action(multi, fds[i].fd, act, + &ev->running_handles); + } + } + + if(!ev->msbump) { + /* If nothing updated the timeout, we decrease it by the spent time. + * If it was updated, it has the new timeout time stored already. + */ + timediff_t timediff = Curl_timediff(after, before); + if(timediff > 0) { + if(timediff > ev->ms) + ev->ms = 0; + else + ev->ms -= (long)timediff; + } + } + } + else + return CURLE_RECV_ERROR; + + if(mcode) + return CURLE_URL_MALFORMAT; + + /* we don't really care about the "msgs_in_queue" value returned in the + second argument */ + msg = curl_multi_info_read(multi, &pollrc); + if(msg) { + result = msg->data.result; + done = TRUE; + } + } + + return result; +} + + +/* easy_events() + * + * Runs a transfer in a blocking manner using the events-based API + */ +static CURLcode easy_events(struct Curl_multi *multi) +{ + /* this struct is made static to allow it to be used after this function + returns and curl_multi_remove_handle() is called */ + static struct events evs = {2, FALSE, 0, NULL, 0}; + + /* if running event-based, do some further multi inits */ + events_setup(multi, &evs); + + return wait_or_timeout(multi, &evs); +} +#else /* CURLDEBUG */ +/* when not built with debug, this function doesn't exist */ +#define easy_events(x) CURLE_NOT_BUILT_IN +#endif + +static CURLcode easy_transfer(struct Curl_multi *multi) +{ + bool done = FALSE; + CURLMcode mcode = CURLM_OK; + CURLcode result = CURLE_OK; + + while(!done && !mcode) { + int still_running = 0; + bool gotsocket = FALSE; + + mcode = Curl_multi_wait(multi, NULL, 0, 1000, NULL, &gotsocket); + + if(!mcode) { + if(!gotsocket) { + long sleep_ms; + + /* If it returns without any filedescriptor instantly, we need to + avoid busy-looping during periods where it has nothing particular + to wait for */ + curl_multi_timeout(multi, &sleep_ms); + if(sleep_ms) { + if(sleep_ms > 1000) + sleep_ms = 1000; + Curl_wait_ms((int)sleep_ms); + } + } + + mcode = curl_multi_perform(multi, &still_running); + } + + /* only read 'still_running' if curl_multi_perform() return OK */ + if(!mcode && !still_running) { + int rc; + CURLMsg *msg = curl_multi_info_read(multi, &rc); + if(msg) { + result = msg->data.result; + done = TRUE; + } + } + } + + /* Make sure to return some kind of error if there was a multi problem */ + if(mcode) { + result = (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY : + /* The other multi errors should never happen, so return + something suitably generic */ + CURLE_BAD_FUNCTION_ARGUMENT; + } + + return result; +} + + +/* + * easy_perform() is the external interface that performs a blocking + * transfer as previously setup. + * + * CONCEPT: This function creates a multi handle, adds the easy handle to it, + * runs curl_multi_perform() until the transfer is done, then detaches the + * easy handle, destroys the multi handle and returns the easy handle's return + * code. + * + * REALITY: it can't just create and destroy the multi handle that easily. It + * needs to keep it around since if this easy handle is used again by this + * function, the same multi handle must be re-used so that the same pools and + * caches can be used. + * + * DEBUG: if 'events' is set TRUE, this function will use a replacement engine + * instead of curl_multi_perform() and use curl_multi_socket_action(). + */ +static CURLcode easy_perform(struct Curl_easy *data, bool events) +{ + struct Curl_multi *multi; + CURLMcode mcode; + CURLcode result = CURLE_OK; + SIGPIPE_VARIABLE(pipe_st); + + if(!data) + return CURLE_BAD_FUNCTION_ARGUMENT; + + if(data->set.errorbuffer) + /* clear this as early as possible */ + data->set.errorbuffer[0] = 0; + + if(data->multi) { + failf(data, "easy handle already used in multi handle"); + return CURLE_FAILED_INIT; + } + + if(data->multi_easy) + multi = data->multi_easy; + else { + /* this multi handle will only ever have a single easy handled attached + to it, so make it use minimal hashes */ + multi = Curl_multi_handle(1, 3); + if(!multi) + return CURLE_OUT_OF_MEMORY; + data->multi_easy = multi; + } + + if(multi->in_callback) + return CURLE_RECURSIVE_API_CALL; + + /* Copy the MAXCONNECTS option to the multi handle */ + curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects); + + mcode = curl_multi_add_handle(multi, data); + if(mcode) { + curl_multi_cleanup(multi); + if(mcode == CURLM_OUT_OF_MEMORY) + return CURLE_OUT_OF_MEMORY; + return CURLE_FAILED_INIT; + } + + sigpipe_ignore(data, &pipe_st); + + /* assign this after curl_multi_add_handle() since that function checks for + it and rejects this handle otherwise */ + data->multi = multi; + + /* run the transfer */ + result = events ? easy_events(multi) : easy_transfer(multi); + + /* ignoring the return code isn't nice, but atm we can't really handle + a failure here, room for future improvement! */ + (void)curl_multi_remove_handle(multi, data); + + sigpipe_restore(&pipe_st); + + /* The multi handle is kept alive, owned by the easy handle */ + return result; +} + + +/* + * curl_easy_perform() is the external interface that performs a blocking + * transfer as previously setup. + */ +CURLcode curl_easy_perform(struct Curl_easy *data) +{ + return easy_perform(data, FALSE); +} + +#ifdef CURLDEBUG +/* + * curl_easy_perform_ev() is the external interface that performs a blocking + * transfer using the event-based API internally. + */ +CURLcode curl_easy_perform_ev(struct Curl_easy *data) +{ + return easy_perform(data, TRUE); +} + +#endif + +/* + * curl_easy_cleanup() is the external interface to cleaning/freeing the given + * easy handle. + */ +void curl_easy_cleanup(struct Curl_easy *data) +{ + SIGPIPE_VARIABLE(pipe_st); + + if(!data) + return; + + sigpipe_ignore(data, &pipe_st); + Curl_close(data); + sigpipe_restore(&pipe_st); +} + +/* + * curl_easy_getinfo() is an external interface that allows an app to retrieve + * information from a performed transfer and similar. + */ +#undef curl_easy_getinfo +CURLcode curl_easy_getinfo(struct Curl_easy *data, CURLINFO info, ...) +{ + va_list arg; + void *paramp; + CURLcode result; + + va_start(arg, info); + paramp = va_arg(arg, void *); + + result = Curl_getinfo(data, info, paramp); + + va_end(arg); + return result; +} + +static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) +{ + CURLcode result = CURLE_OK; + enum dupstring i; + + /* Copy src->set into dst->set first, then deal with the strings + afterwards */ + dst->set = src->set; + Curl_mime_initpart(&dst->set.mimepost, dst); + + /* clear all string pointers first */ + memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); + + /* duplicate all strings */ + for(i = (enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) { + result = Curl_setstropt(&dst->set.str[i], src->set.str[i]); + if(result) + return result; + } + + /* duplicate memory areas pointed to */ + i = STRING_COPYPOSTFIELDS; + if(src->set.postfieldsize && src->set.str[i]) { + /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */ + dst->set.str[i] = Curl_memdup(src->set.str[i], + curlx_sotouz(src->set.postfieldsize)); + if(!dst->set.str[i]) + return CURLE_OUT_OF_MEMORY; + /* point to the new copy */ + dst->set.postfields = dst->set.str[i]; + } + + /* Duplicate mime data. */ + result = Curl_mime_duppart(&dst->set.mimepost, &src->set.mimepost); + + if(src->set.resolve) + dst->change.resolve = dst->set.resolve; + + return result; +} + +/* + * curl_easy_duphandle() is an external interface to allow duplication of a + * given input easy handle. The returned handle will be a new working handle + * with all options set exactly as the input source handle. + */ +struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) +{ + struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy)); + if(NULL == outcurl) + goto fail; + + /* + * We setup a few buffers we need. We should probably make them + * get setup on-demand in the code, as that would probably decrease + * the likeliness of us forgetting to init a buffer here in the future. + */ + outcurl->set.buffer_size = data->set.buffer_size; + outcurl->state.buffer = malloc(outcurl->set.buffer_size + 1); + if(!outcurl->state.buffer) + goto fail; + + outcurl->state.headerbuff = malloc(HEADERSIZE); + if(!outcurl->state.headerbuff) + goto fail; + outcurl->state.headersize = HEADERSIZE; + + /* copy all userdefined values */ + if(dupset(outcurl, data)) + goto fail; + + /* the connection cache is setup on demand */ + outcurl->state.conn_cache = NULL; + + outcurl->state.lastconnect = NULL; + + outcurl->progress.flags = data->progress.flags; + outcurl->progress.callback = data->progress.callback; + + if(data->cookies) { + /* If cookies are enabled in the parent handle, we enable them + in the clone as well! */ + outcurl->cookies = Curl_cookie_init(data, + data->cookies->filename, + outcurl->cookies, + data->set.cookiesession); + if(!outcurl->cookies) + goto fail; + } + + /* duplicate all values in 'change' */ + if(data->change.cookielist) { + outcurl->change.cookielist = + Curl_slist_duplicate(data->change.cookielist); + if(!outcurl->change.cookielist) + goto fail; + } + + if(data->change.url) { + outcurl->change.url = strdup(data->change.url); + if(!outcurl->change.url) + goto fail; + outcurl->change.url_alloc = TRUE; + } + + if(data->change.referer) { + outcurl->change.referer = strdup(data->change.referer); + if(!outcurl->change.referer) + goto fail; + outcurl->change.referer_alloc = TRUE; + } + + /* Reinitialize an SSL engine for the new handle + * note: the engine name has already been copied by dupset */ + if(outcurl->set.str[STRING_SSL_ENGINE]) { + if(Curl_ssl_set_engine(outcurl, outcurl->set.str[STRING_SSL_ENGINE])) + goto fail; + } + + /* Clone the resolver handle, if present, for the new handle */ + if(Curl_resolver_duphandle(outcurl, + &outcurl->state.resolver, + data->state.resolver)) + goto fail; + + Curl_convert_setup(outcurl); + + Curl_initinfo(outcurl); + + outcurl->magic = CURLEASY_MAGIC_NUMBER; + + /* we reach this point and thus we are OK */ + + return outcurl; + + fail: + + if(outcurl) { + curl_slist_free_all(outcurl->change.cookielist); + outcurl->change.cookielist = NULL; + Curl_safefree(outcurl->state.buffer); + Curl_safefree(outcurl->state.headerbuff); + Curl_safefree(outcurl->change.url); + Curl_safefree(outcurl->change.referer); + Curl_freeset(outcurl); + free(outcurl); + } + + return NULL; +} + +/* + * curl_easy_reset() is an external interface that allows an app to re- + * initialize a session handle to the default values. + */ +void curl_easy_reset(struct Curl_easy *data) +{ + Curl_free_request_state(data); + + /* zero out UserDefined data: */ + Curl_freeset(data); + memset(&data->set, 0, sizeof(struct UserDefined)); + (void)Curl_init_userdefined(data); + + /* zero out Progress data: */ + memset(&data->progress, 0, sizeof(struct Progress)); + + /* zero out PureInfo data: */ + Curl_initinfo(data); + + data->progress.flags |= PGRS_HIDE; + data->state.current_speed = -1; /* init to negative == impossible */ + + /* zero out authentication data: */ + memset(&data->state.authhost, 0, sizeof(struct auth)); + memset(&data->state.authproxy, 0, sizeof(struct auth)); + +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) + Curl_http_auth_cleanup_digest(data); +#endif +} + +/* + * curl_easy_pause() allows an application to pause or unpause a specific + * transfer and direction. This function sets the full new state for the + * current connection this easy handle operates on. + * + * NOTE: if you have the receiving paused and you call this function to remove + * the pausing, you may get your write callback called at this point. + * + * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h + * + * NOTE: This is one of few API functions that are allowed to be called from + * within a callback. + */ +CURLcode curl_easy_pause(struct Curl_easy *data, int action) +{ + struct SingleRequest *k = &data->req; + CURLcode result = CURLE_OK; + + /* first switch off both pause bits */ + int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE); + + /* set the new desired pause bits */ + newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) | + ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0); + + /* put it back in the keepon */ + k->keepon = newstate; + + if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempcount) { + /* there are buffers for sending that can be delivered as the receive + pausing is lifted! */ + unsigned int i; + unsigned int count = data->state.tempcount; + struct tempbuf writebuf[3]; /* there can only be three */ + struct connectdata *conn = data->conn; + struct Curl_easy *saved_data = NULL; + + /* copy the structs to allow for immediate re-pausing */ + for(i = 0; i < data->state.tempcount; i++) { + writebuf[i] = data->state.tempwrite[i]; + data->state.tempwrite[i].buf = NULL; + } + data->state.tempcount = 0; + + /* set the connection's current owner */ + if(conn->data != data) { + saved_data = conn->data; + conn->data = data; + } + + for(i = 0; i < count; i++) { + /* even if one function returns error, this loops through and frees all + buffers */ + if(!result) + result = Curl_client_write(conn, writebuf[i].type, writebuf[i].buf, + writebuf[i].len); + free(writebuf[i].buf); + } + + /* recover previous owner of the connection */ + if(saved_data) + conn->data = saved_data; + + if(result) + return result; + } + + /* if there's no error and we're not pausing both directions, we want + to have this handle checked soon */ + if(!result && + ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) != + (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) ) { + Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */ + if(data->multi) + Curl_update_timer(data->multi); + } + + /* This transfer may have been moved in or out of the bundle, update + the corresponding socket callback, if used */ + Curl_updatesocket(data); + + return result; +} + + +static CURLcode easy_connection(struct Curl_easy *data, + curl_socket_t *sfd, + struct connectdata **connp) +{ + if(data == NULL) + return CURLE_BAD_FUNCTION_ARGUMENT; + + /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */ + if(!data->set.connect_only) { + failf(data, "CONNECT_ONLY is required!"); + return CURLE_UNSUPPORTED_PROTOCOL; + } + + *sfd = Curl_getconnectinfo(data, connp); + + if(*sfd == CURL_SOCKET_BAD) { + failf(data, "Failed to get recent socket"); + return CURLE_UNSUPPORTED_PROTOCOL; + } + + return CURLE_OK; +} + +/* + * Receives data from the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + * Returns CURLE_OK on success, error code on error. + */ +CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen, + size_t *n) +{ + curl_socket_t sfd; + CURLcode result; + ssize_t n1; + struct connectdata *c; + + if(Curl_is_in_callback(data)) + return CURLE_RECURSIVE_API_CALL; + + result = easy_connection(data, &sfd, &c); + if(result) + return result; + + *n = 0; + result = Curl_read(c, sfd, buffer, buflen, &n1); + + if(result) + return result; + + *n = (size_t)n1; + + return CURLE_OK; +} + +/* + * Sends data over the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, + size_t buflen, size_t *n) +{ + curl_socket_t sfd; + CURLcode result; + ssize_t n1; + struct connectdata *c = NULL; + + if(Curl_is_in_callback(data)) + return CURLE_RECURSIVE_API_CALL; + + result = easy_connection(data, &sfd, &c); + if(result) + return result; + + *n = 0; + result = Curl_write(c, sfd, buffer, buflen, &n1); + + if(n1 == -1) + return CURLE_SEND_ERROR; + + /* detect EAGAIN */ + if(!result && !n1) + return CURLE_AGAIN; + + *n = (size_t)n1; + + return result; +} + +/* + * Performs connection upkeep for the given session handle. + */ +CURLcode curl_easy_upkeep(struct Curl_easy *data) +{ + /* Verify that we got an easy handle we can work with. */ + if(!GOOD_EASY_HANDLE(data)) + return CURLE_BAD_FUNCTION_ARGUMENT; + + if(data->multi_easy) { + /* Use the common function to keep connections alive. */ + return Curl_upkeep(&data->multi_easy->conn_cache, data); + } + else { + /* No connections, so just return success */ + return CURLE_OK; + } +} diff --git a/libcurl/lib/easyif.h b/libcurl/lib/easyif.h new file mode 100644 index 0000000..6ba7e54 --- /dev/null +++ b/libcurl/lib/easyif.h @@ -0,0 +1,32 @@ +#ifndef HEADER_CURL_EASYIF_H +#define HEADER_CURL_EASYIF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Prototypes for library-wide functions provided by easy.c + */ +#ifdef CURLDEBUG +CURL_EXTERN CURLcode curl_easy_perform_ev(struct Curl_easy *easy); +#endif + +#endif /* HEADER_CURL_EASYIF_H */ diff --git a/libcurl/lib/escape.c b/libcurl/lib/escape.c new file mode 100644 index 0000000..7121db3 --- /dev/null +++ b/libcurl/lib/escape.c @@ -0,0 +1,244 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* Escape and unescape URL encoding in strings. The functions return a new + * allocated string or NULL if an error occurred. */ + +#include "curl_setup.h" + +#include + +#include "urldata.h" +#include "warnless.h" +#include "non-ascii.h" +#include "escape.h" +#include "strdup.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* Portable character check (remember EBCDIC). Do not use isalnum() because + its behavior is altered by the current locale. + See https://tools.ietf.org/html/rfc3986#section-2.3 +*/ +bool Curl_isunreserved(unsigned char in) +{ + switch(in) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': case 'g': case 'h': case 'i': case 'j': + case 'k': case 'l': case 'm': case 'n': case 'o': + case 'p': case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': case 'G': case 'H': case 'I': case 'J': + case 'K': case 'L': case 'M': case 'N': case 'O': + case 'P': case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': + case '-': case '.': case '_': case '~': + return TRUE; + default: + break; + } + return FALSE; +} + +/* for ABI-compatibility with previous versions */ +char *curl_escape(const char *string, int inlength) +{ + return curl_easy_escape(NULL, string, inlength); +} + +/* for ABI-compatibility with previous versions */ +char *curl_unescape(const char *string, int length) +{ + return curl_easy_unescape(NULL, string, length, NULL); +} + +char *curl_easy_escape(struct Curl_easy *data, const char *string, + int inlength) +{ + size_t alloc; + char *ns; + char *testing_ptr = NULL; + size_t newlen; + size_t strindex = 0; + size_t length; + CURLcode result; + + if(inlength < 0) + return NULL; + + alloc = (inlength?(size_t)inlength:strlen(string)) + 1; + newlen = alloc; + + ns = malloc(alloc); + if(!ns) + return NULL; + + length = alloc-1; + while(length--) { + unsigned char in = *string; /* we need to treat the characters unsigned */ + + if(Curl_isunreserved(in)) + /* just copy this */ + ns[strindex++] = in; + else { + /* encode it */ + newlen += 2; /* the size grows with two, since this'll become a %XX */ + if(newlen > alloc) { + alloc *= 2; + testing_ptr = Curl_saferealloc(ns, alloc); + if(!testing_ptr) + return NULL; + ns = testing_ptr; + } + + result = Curl_convert_to_network(data, (char *)&in, 1); + if(result) { + /* Curl_convert_to_network calls failf if unsuccessful */ + free(ns); + return NULL; + } + + msnprintf(&ns[strindex], 4, "%%%02X", in); + + strindex += 3; + } + string++; + } + ns[strindex] = 0; /* terminate it */ + return ns; +} + +/* + * Curl_urldecode() URL decodes the given string. + * + * Optionally detects control characters (byte codes lower than 32) in the + * data and rejects such data. + * + * Returns a pointer to a malloced string in *ostring with length given in + * *olen. If length == 0, the length is assumed to be strlen(string). + * + * 'data' can be set to NULL but then this function can't convert network + * data to host for non-ascii. + */ +CURLcode Curl_urldecode(struct Curl_easy *data, + const char *string, size_t length, + char **ostring, size_t *olen, + bool reject_ctrl) +{ + size_t alloc = (length?length:strlen(string)) + 1; + char *ns = malloc(alloc); + size_t strindex = 0; + unsigned long hex; + CURLcode result = CURLE_OK; + + if(!ns) + return CURLE_OUT_OF_MEMORY; + + while(--alloc > 0) { + unsigned char in = *string; + if(('%' == in) && (alloc > 2) && + ISXDIGIT(string[1]) && ISXDIGIT(string[2])) { + /* this is two hexadecimal digits following a '%' */ + char hexstr[3]; + char *ptr; + hexstr[0] = string[1]; + hexstr[1] = string[2]; + hexstr[2] = 0; + + hex = strtoul(hexstr, &ptr, 16); + + in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */ + + if(data) { + result = Curl_convert_from_network(data, (char *)&in, 1); + if(result) { + /* Curl_convert_from_network calls failf if unsuccessful */ + free(ns); + return result; + } + } + + string += 2; + alloc -= 2; + } + + if(reject_ctrl && (in < 0x20)) { + free(ns); + return CURLE_URL_MALFORMAT; + } + + ns[strindex++] = in; + string++; + } + ns[strindex] = 0; /* terminate it */ + + if(olen) + /* store output size */ + *olen = strindex; + + /* store output string */ + *ostring = ns; + + return CURLE_OK; +} + +/* + * Unescapes the given URL escaped string of given length. Returns a + * pointer to a malloced string with length given in *olen. + * If length == 0, the length is assumed to be strlen(string). + * If olen == NULL, no output length is stored. + */ +char *curl_easy_unescape(struct Curl_easy *data, const char *string, + int length, int *olen) +{ + char *str = NULL; + if(length >= 0) { + size_t inputlen = length; + size_t outputlen; + CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen, + FALSE); + if(res) + return NULL; + + if(olen) { + if(outputlen <= (size_t) INT_MAX) + *olen = curlx_uztosi(outputlen); + else + /* too large to return in an int, fail! */ + Curl_safefree(str); + } + } + return str; +} + +/* For operating systems/environments that use different malloc/free + systems for the app and for this library, we provide a free that uses + the library's memory system */ +void curl_free(void *p) +{ + free(p); +} diff --git a/libcurl/lib/escape.h b/libcurl/lib/escape.h new file mode 100644 index 0000000..d8bbe5c --- /dev/null +++ b/libcurl/lib/escape.h @@ -0,0 +1,33 @@ +#ifndef HEADER_CURL_ESCAPE_H +#define HEADER_CURL_ESCAPE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* Escape and unescape URL encoding in strings. The functions return a new + * allocated string or NULL if an error occurred. */ + +bool Curl_isunreserved(unsigned char in); +CURLcode Curl_urldecode(struct Curl_easy *data, + const char *string, size_t length, + char **ostring, size_t *olen, + bool reject_crlf); + +#endif /* HEADER_CURL_ESCAPE_H */ diff --git a/libcurl/lib/file.c b/libcurl/lib/file.c new file mode 100644 index 0000000..d349cd9 --- /dev/null +++ b/libcurl/lib/file.c @@ -0,0 +1,544 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_FILE + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#ifdef HAVE_FCNTL_H +#include +#endif + +#include "strtoofft.h" +#include "urldata.h" +#include +#include "progress.h" +#include "sendf.h" +#include "escape.h" +#include "file.h" +#include "speedcheck.h" +#include "getinfo.h" +#include "transfer.h" +#include "url.h" +#include "parsedate.h" /* for the week day and month names */ +#include "warnless.h" +#include "curl_range.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \ + defined(__SYMBIAN32__) +#define DOS_FILESYSTEM 1 +#endif + +#ifdef OPEN_NEEDS_ARG3 +# define open_readonly(p,f) open((p),(f),(0)) +#else +# define open_readonly(p,f) open((p),(f)) +#endif + +/* + * Forward declarations. + */ + +static CURLcode file_do(struct connectdata *, bool *done); +static CURLcode file_done(struct connectdata *conn, + CURLcode status, bool premature); +static CURLcode file_connect(struct connectdata *conn, bool *done); +static CURLcode file_disconnect(struct connectdata *conn, + bool dead_connection); +static CURLcode file_setup_connection(struct connectdata *conn); + +/* + * FILE scheme handler. + */ + +const struct Curl_handler Curl_handler_file = { + "FILE", /* scheme */ + file_setup_connection, /* setup_connection */ + file_do, /* do_it */ + file_done, /* done */ + ZERO_NULL, /* do_more */ + file_connect, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + file_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + 0, /* defport */ + CURLPROTO_FILE, /* protocol */ + PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */ +}; + + +static CURLcode file_setup_connection(struct connectdata *conn) +{ + /* allocate the FILE specific struct */ + conn->data->req.protop = calloc(1, sizeof(struct FILEPROTO)); + if(!conn->data->req.protop) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; +} + +/* + * file_connect() gets called from Curl_protocol_connect() to allow us to + * do protocol-specific actions at connect-time. We emulate a + * connect-then-transfer protocol and "connect" to the file here + */ +static CURLcode file_connect(struct connectdata *conn, bool *done) +{ + struct Curl_easy *data = conn->data; + char *real_path; + struct FILEPROTO *file = data->req.protop; + int fd; +#ifdef DOS_FILESYSTEM + size_t i; + char *actual_path; +#endif + size_t real_path_len; + + CURLcode result = Curl_urldecode(data, data->state.up.path, 0, &real_path, + &real_path_len, FALSE); + if(result) + return result; + +#ifdef DOS_FILESYSTEM + /* If the first character is a slash, and there's + something that looks like a drive at the beginning of + the path, skip the slash. If we remove the initial + slash in all cases, paths without drive letters end up + relative to the current directory which isn't how + browsers work. + + Some browsers accept | instead of : as the drive letter + separator, so we do too. + + On other platforms, we need the slash to indicate an + absolute pathname. On Windows, absolute paths start + with a drive letter. + */ + actual_path = real_path; + if((actual_path[0] == '/') && + actual_path[1] && + (actual_path[2] == ':' || actual_path[2] == '|')) { + actual_path[2] = ':'; + actual_path++; + real_path_len--; + } + + /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */ + for(i = 0; i < real_path_len; ++i) + if(actual_path[i] == '/') + actual_path[i] = '\\'; + else if(!actual_path[i]) { /* binary zero */ + Curl_safefree(real_path); + return CURLE_URL_MALFORMAT; + } + + fd = open_readonly(actual_path, O_RDONLY|O_BINARY); + file->path = actual_path; +#else + if(memchr(real_path, 0, real_path_len)) { + /* binary zeroes indicate foul play */ + Curl_safefree(real_path); + return CURLE_URL_MALFORMAT; + } + + fd = open_readonly(real_path, O_RDONLY); + file->path = real_path; +#endif + file->freepath = real_path; /* free this when done */ + + file->fd = fd; + if(!data->set.upload && (fd == -1)) { + failf(data, "Couldn't open file %s", data->state.up.path); + file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE); + return CURLE_FILE_COULDNT_READ_FILE; + } + *done = TRUE; + + return CURLE_OK; +} + +static CURLcode file_done(struct connectdata *conn, + CURLcode status, bool premature) +{ + struct FILEPROTO *file = conn->data->req.protop; + (void)status; /* not used */ + (void)premature; /* not used */ + + if(file) { + Curl_safefree(file->freepath); + file->path = NULL; + if(file->fd != -1) + close(file->fd); + file->fd = -1; + } + + return CURLE_OK; +} + +static CURLcode file_disconnect(struct connectdata *conn, + bool dead_connection) +{ + struct FILEPROTO *file = conn->data->req.protop; + (void)dead_connection; /* not used */ + + if(file) { + Curl_safefree(file->freepath); + file->path = NULL; + if(file->fd != -1) + close(file->fd); + file->fd = -1; + } + + return CURLE_OK; +} + +#ifdef DOS_FILESYSTEM +#define DIRSEP '\\' +#else +#define DIRSEP '/' +#endif + +static CURLcode file_upload(struct connectdata *conn) +{ + struct FILEPROTO *file = conn->data->req.protop; + const char *dir = strchr(file->path, DIRSEP); + int fd; + int mode; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + char *buf = data->state.buffer; + curl_off_t bytecount = 0; + struct_stat file_stat; + const char *buf2; + + /* + * Since FILE: doesn't do the full init, we need to provide some extra + * assignments here. + */ + conn->data->req.upload_fromhere = buf; + + if(!dir) + return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ + + if(!dir[1]) + return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ + +#ifdef O_BINARY +#define MODE_DEFAULT O_WRONLY|O_CREAT|O_BINARY +#else +#define MODE_DEFAULT O_WRONLY|O_CREAT +#endif + + if(data->state.resume_from) + mode = MODE_DEFAULT|O_APPEND; + else + mode = MODE_DEFAULT|O_TRUNC; + + fd = open(file->path, mode, conn->data->set.new_file_perms); + if(fd < 0) { + failf(data, "Can't open %s for writing", file->path); + return CURLE_WRITE_ERROR; + } + + if(-1 != data->state.infilesize) + /* known size of data to "upload" */ + Curl_pgrsSetUploadSize(data, data->state.infilesize); + + /* treat the negative resume offset value as the case of "-" */ + if(data->state.resume_from < 0) { + if(fstat(fd, &file_stat)) { + close(fd); + failf(data, "Can't get the size of %s", file->path); + return CURLE_WRITE_ERROR; + } + data->state.resume_from = (curl_off_t)file_stat.st_size; + } + + while(!result) { + size_t nread; + size_t nwrite; + size_t readcount; + result = Curl_fillreadbuffer(conn, data->set.buffer_size, &readcount); + if(result) + break; + + if(!readcount) + break; + + nread = readcount; + + /*skip bytes before resume point*/ + if(data->state.resume_from) { + if((curl_off_t)nread <= data->state.resume_from) { + data->state.resume_from -= nread; + nread = 0; + buf2 = buf; + } + else { + buf2 = buf + data->state.resume_from; + nread -= (size_t)data->state.resume_from; + data->state.resume_from = 0; + } + } + else + buf2 = buf; + + /* write the data to the target */ + nwrite = write(fd, buf2, nread); + if(nwrite != nread) { + result = CURLE_SEND_ERROR; + break; + } + + bytecount += nread; + + Curl_pgrsSetUploadCounter(data, bytecount); + + if(Curl_pgrsUpdate(conn)) + result = CURLE_ABORTED_BY_CALLBACK; + else + result = Curl_speedcheck(data, Curl_now()); + } + if(!result && Curl_pgrsUpdate(conn)) + result = CURLE_ABORTED_BY_CALLBACK; + + close(fd); + + return result; +} + +/* + * file_do() is the protocol-specific function for the do-phase, separated + * from the connect-phase above. Other protocols merely setup the transfer in + * the do-phase, to have it done in the main transfer loop but since some + * platforms we support don't allow select()ing etc on file handles (as + * opposed to sockets) we instead perform the whole do-operation in this + * function. + */ +static CURLcode file_do(struct connectdata *conn, bool *done) +{ + /* This implementation ignores the host name in conformance with + RFC 1738. Only local files (reachable via the standard file system) + are supported. This means that files on remotely mounted directories + (via NFS, Samba, NT sharing) can be accessed through a file:// URL + */ + CURLcode result = CURLE_OK; + struct_stat statbuf; /* struct_stat instead of struct stat just to allow the + Windows version to have a different struct without + having to redefine the simple word 'stat' */ + curl_off_t expected_size = 0; + bool size_known; + bool fstated = FALSE; + struct Curl_easy *data = conn->data; + char *buf = data->state.buffer; + curl_off_t bytecount = 0; + int fd; + struct FILEPROTO *file; + + *done = TRUE; /* unconditionally */ + + Curl_pgrsStartNow(data); + + if(data->set.upload) + return file_upload(conn); + + file = conn->data->req.protop; + + /* get the fd from the connection phase */ + fd = file->fd; + + /* VMS: This only works reliable for STREAMLF files */ + if(-1 != fstat(fd, &statbuf)) { + /* we could stat it, then read out the size */ + expected_size = statbuf.st_size; + /* and store the modification time */ + data->info.filetime = statbuf.st_mtime; + fstated = TRUE; + } + + if(fstated && !data->state.range && data->set.timecondition) { + if(!Curl_meets_timecondition(data, data->info.filetime)) { + *done = TRUE; + return CURLE_OK; + } + } + + if(fstated) { + time_t filetime; + struct tm buffer; + const struct tm *tm = &buffer; + char header[80]; + msnprintf(header, sizeof(header), + "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", + expected_size); + result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0); + if(result) + return result; + + result = Curl_client_write(conn, CLIENTWRITE_HEADER, + (char *)"Accept-ranges: bytes\r\n", 0); + if(result) + return result; + + filetime = (time_t)statbuf.st_mtime; + result = Curl_gmtime(filetime, &buffer); + if(result) + return result; + + /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ + msnprintf(header, sizeof(header), + "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n%s", + Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], + tm->tm_mday, + Curl_month[tm->tm_mon], + tm->tm_year + 1900, + tm->tm_hour, + tm->tm_min, + tm->tm_sec, + data->set.opt_no_body ? "": "\r\n"); + result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0); + if(result) + return result; + /* set the file size to make it available post transfer */ + Curl_pgrsSetDownloadSize(data, expected_size); + if(data->set.opt_no_body) + return result; + } + + /* Check whether file range has been specified */ + result = Curl_range(conn); + if(result) + return result; + + /* Adjust the start offset in case we want to get the N last bytes + * of the stream if the filesize could be determined */ + if(data->state.resume_from < 0) { + if(!fstated) { + failf(data, "Can't get the size of file."); + return CURLE_READ_ERROR; + } + data->state.resume_from += (curl_off_t)statbuf.st_size; + } + + if(data->state.resume_from <= expected_size) + expected_size -= data->state.resume_from; + else { + failf(data, "failed to resume file:// transfer"); + return CURLE_BAD_DOWNLOAD_RESUME; + } + + /* A high water mark has been specified so we obey... */ + if(data->req.maxdownload > 0) + expected_size = data->req.maxdownload; + + if(!fstated || (expected_size == 0)) + size_known = FALSE; + else + size_known = TRUE; + + /* The following is a shortcut implementation of file reading + this is both more efficient than the former call to download() and + it avoids problems with select() and recv() on file descriptors + in Winsock */ + if(fstated) + Curl_pgrsSetDownloadSize(data, expected_size); + + if(data->state.resume_from) { + if(data->state.resume_from != + lseek(fd, data->state.resume_from, SEEK_SET)) + return CURLE_BAD_DOWNLOAD_RESUME; + } + + Curl_pgrsTime(data, TIMER_STARTTRANSFER); + + while(!result) { + ssize_t nread; + /* Don't fill a whole buffer if we want less than all data */ + size_t bytestoread; + + if(size_known) { + bytestoread = (expected_size < data->set.buffer_size) ? + curlx_sotouz(expected_size) : (size_t)data->set.buffer_size; + } + else + bytestoread = data->set.buffer_size-1; + + nread = read(fd, buf, bytestoread); + + if(nread > 0) + buf[nread] = 0; + + if(nread <= 0 || (size_known && (expected_size == 0))) + break; + + bytecount += nread; + if(size_known) + expected_size -= nread; + + result = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread); + if(result) + return result; + + Curl_pgrsSetDownloadCounter(data, bytecount); + + if(Curl_pgrsUpdate(conn)) + result = CURLE_ABORTED_BY_CALLBACK; + else + result = Curl_speedcheck(data, Curl_now()); + } + if(Curl_pgrsUpdate(conn)) + result = CURLE_ABORTED_BY_CALLBACK; + + return result; +} + +#endif diff --git a/libcurl/lib/file.h b/libcurl/lib/file.h new file mode 100644 index 0000000..20828ad --- /dev/null +++ b/libcurl/lib/file.h @@ -0,0 +1,40 @@ +#ifndef HEADER_CURL_FILE_H +#define HEADER_CURL_FILE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + + +/**************************************************************************** + * FILE unique setup + ***************************************************************************/ +struct FILEPROTO { + char *path; /* the path we operate on */ + char *freepath; /* pointer to the allocated block we must free, this might + differ from the 'path' pointer */ + int fd; /* open file descriptor to read from! */ +}; + +#ifndef CURL_DISABLE_FILE +extern const struct Curl_handler Curl_handler_file; +#endif + +#endif /* HEADER_CURL_FILE_H */ diff --git a/libcurl/lib/fileinfo.c b/libcurl/lib/fileinfo.c new file mode 100644 index 0000000..2630c9e --- /dev/null +++ b/libcurl/lib/fileinfo.c @@ -0,0 +1,44 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2010 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#ifndef CURL_DISABLE_FTP +#include "strdup.h" +#include "fileinfo.h" +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +struct fileinfo *Curl_fileinfo_alloc(void) +{ + return calloc(1, sizeof(struct fileinfo)); +} + +void Curl_fileinfo_cleanup(struct fileinfo *finfo) +{ + if(!finfo) + return; + + Curl_safefree(finfo->info.b_data); + free(finfo); +} +#endif diff --git a/libcurl/lib/fileinfo.h b/libcurl/lib/fileinfo.h new file mode 100644 index 0000000..f4d8f3b --- /dev/null +++ b/libcurl/lib/fileinfo.h @@ -0,0 +1,36 @@ +#ifndef HEADER_CURL_FILEINFO_H +#define HEADER_CURL_FILEINFO_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2010 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include +#include "llist.h" + +struct fileinfo { + struct curl_fileinfo info; + struct curl_llist_element list; +}; + +struct fileinfo *Curl_fileinfo_alloc(void); +void Curl_fileinfo_cleanup(struct fileinfo *finfo); + +#endif /* HEADER_CURL_FILEINFO_H */ diff --git a/libcurl/lib/firefox-db2pem.sh b/libcurl/lib/firefox-db2pem.sh new file mode 100644 index 0000000..4548932 --- /dev/null +++ b/libcurl/lib/firefox-db2pem.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# *************************************************************************** +# * _ _ ____ _ +# * Project ___| | | | _ \| | +# * / __| | | | |_) | | +# * | (__| |_| | _ <| |___ +# * \___|\___/|_| \_\_____| +# * +# * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. +# * +# * This software is licensed as described in the file COPYING, which +# * you should have received as part of this distribution. The terms +# * are also available at https://curl.haxx.se/docs/copyright.html. +# * +# * You may opt to use, copy, modify, merge, publish, distribute and/or sell +# * copies of the Software, and permit persons to whom the Software is +# * furnished to do so, under the terms of the COPYING file. +# * +# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# * KIND, either express or implied. +# * +# *************************************************************************** +# This shell script creates a fresh ca-bundle.crt file for use with libcurl. +# It extracts all ca certs it finds in the local Firefox database and converts +# them all into PEM format. +# +db=`ls -1d $HOME/.mozilla/firefox/*default*` +out=$1 + +if test -z "$out"; then + out="ca-bundle.crt" # use a sensible default +fi + +currentdate=`date` + +cat >$out <> $out diff --git a/libcurl/lib/formdata.c b/libcurl/lib/formdata.c new file mode 100644 index 0000000..429d479 --- /dev/null +++ b/libcurl/lib/formdata.c @@ -0,0 +1,950 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "formdata.h" +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME) + +#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) +#include +#endif + +#include "urldata.h" /* for struct Curl_easy */ +#include "mime.h" +#include "non-ascii.h" +#include "vtls/vtls.h" +#include "strcase.h" +#include "sendf.h" +#include "strdup.h" +#include "rand.h" +#include "warnless.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + + +#define HTTPPOST_PTRNAME CURL_HTTPPOST_PTRNAME +#define HTTPPOST_FILENAME CURL_HTTPPOST_FILENAME +#define HTTPPOST_PTRCONTENTS CURL_HTTPPOST_PTRCONTENTS +#define HTTPPOST_READFILE CURL_HTTPPOST_READFILE +#define HTTPPOST_PTRBUFFER CURL_HTTPPOST_PTRBUFFER +#define HTTPPOST_CALLBACK CURL_HTTPPOST_CALLBACK +#define HTTPPOST_BUFFER CURL_HTTPPOST_BUFFER + +/*************************************************************************** + * + * AddHttpPost() + * + * Adds a HttpPost structure to the list, if parent_post is given becomes + * a subpost of parent_post instead of a direct list element. + * + * Returns newly allocated HttpPost on success and NULL if malloc failed. + * + ***************************************************************************/ +static struct curl_httppost * +AddHttpPost(char *name, size_t namelength, + char *value, curl_off_t contentslength, + char *buffer, size_t bufferlength, + char *contenttype, + long flags, + struct curl_slist *contentHeader, + char *showfilename, char *userp, + struct curl_httppost *parent_post, + struct curl_httppost **httppost, + struct curl_httppost **last_post) +{ + struct curl_httppost *post; + post = calloc(1, sizeof(struct curl_httppost)); + if(post) { + post->name = name; + post->namelength = (long)(name?(namelength?namelength:strlen(name)):0); + post->contents = value; + post->contentlen = contentslength; + post->buffer = buffer; + post->bufferlength = (long)bufferlength; + post->contenttype = contenttype; + post->contentheader = contentHeader; + post->showfilename = showfilename; + post->userp = userp; + post->flags = flags | CURL_HTTPPOST_LARGE; + } + else + return NULL; + + if(parent_post) { + /* now, point our 'more' to the original 'more' */ + post->more = parent_post->more; + + /* then move the original 'more' to point to ourselves */ + parent_post->more = post; + } + else { + /* make the previous point to this */ + if(*last_post) + (*last_post)->next = post; + else + (*httppost) = post; + + (*last_post) = post; + } + return post; +} + +/*************************************************************************** + * + * AddFormInfo() + * + * Adds a FormInfo structure to the list presented by parent_form_info. + * + * Returns newly allocated FormInfo on success and NULL if malloc failed/ + * parent_form_info is NULL. + * + ***************************************************************************/ +static FormInfo * AddFormInfo(char *value, + char *contenttype, + FormInfo *parent_form_info) +{ + FormInfo *form_info; + form_info = calloc(1, sizeof(struct FormInfo)); + if(form_info) { + if(value) + form_info->value = value; + if(contenttype) + form_info->contenttype = contenttype; + form_info->flags = HTTPPOST_FILENAME; + } + else + return NULL; + + if(parent_form_info) { + /* now, point our 'more' to the original 'more' */ + form_info->more = parent_form_info->more; + + /* then move the original 'more' to point to ourselves */ + parent_form_info->more = form_info; + } + + return form_info; +} + +/*************************************************************************** + * + * FormAdd() + * + * Stores a formpost parameter and builds the appropriate linked list. + * + * Has two principal functionalities: using files and byte arrays as + * post parts. Byte arrays are either copied or just the pointer is stored + * (as the user requests) while for files only the filename and not the + * content is stored. + * + * While you may have only one byte array for each name, multiple filenames + * are allowed (and because of this feature CURLFORM_END is needed after + * using CURLFORM_FILE). + * + * Examples: + * + * Simple name/value pair with copied contents: + * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", + * CURLFORM_COPYCONTENTS, "value", CURLFORM_END); + * + * name/value pair where only the content pointer is remembered: + * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", + * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END); + * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used) + * + * storing a filename (CONTENTTYPE is optional!): + * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", + * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text", + * CURLFORM_END); + * + * storing multiple filenames: + * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", + * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ + +static +CURLFORMcode FormAdd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + va_list params) +{ + FormInfo *first_form, *current_form, *form = NULL; + CURLFORMcode return_value = CURL_FORMADD_OK; + const char *prevtype = NULL; + struct curl_httppost *post = NULL; + CURLformoption option; + struct curl_forms *forms = NULL; + char *array_value = NULL; /* value read from an array */ + + /* This is a state variable, that if TRUE means that we're parsing an + array that we got passed to us. If FALSE we're parsing the input + va_list arguments. */ + bool array_state = FALSE; + + /* + * We need to allocate the first struct to fill in. + */ + first_form = calloc(1, sizeof(struct FormInfo)); + if(!first_form) + return CURL_FORMADD_MEMORY; + + current_form = first_form; + + /* + * Loop through all the options set. Break if we have an error to report. + */ + while(return_value == CURL_FORMADD_OK) { + + /* first see if we have more parts of the array param */ + if(array_state && forms) { + /* get the upcoming option from the given array */ + option = forms->option; + array_value = (char *)forms->value; + + forms++; /* advance this to next entry */ + if(CURLFORM_END == option) { + /* end of array state */ + array_state = FALSE; + continue; + } + } + else { + /* This is not array-state, get next option */ + option = va_arg(params, CURLformoption); + if(CURLFORM_END == option) + break; + } + + switch(option) { + case CURLFORM_ARRAY: + if(array_state) + /* we don't support an array from within an array */ + return_value = CURL_FORMADD_ILLEGAL_ARRAY; + else { + forms = va_arg(params, struct curl_forms *); + if(forms) + array_state = TRUE; + else + return_value = CURL_FORMADD_NULL; + } + break; + + /* + * Set the Name property. + */ + case CURLFORM_PTRNAME: +#ifdef CURL_DOES_CONVERSIONS + /* Treat CURLFORM_PTR like CURLFORM_COPYNAME so that libcurl will copy + * the data in all cases so that we'll have safe memory for the eventual + * conversion. + */ +#else + current_form->flags |= HTTPPOST_PTRNAME; /* fall through */ +#endif + /* FALLTHROUGH */ + case CURLFORM_COPYNAME: + if(current_form->name) + return_value = CURL_FORMADD_OPTION_TWICE; + else { + char *name = array_state? + array_value:va_arg(params, char *); + if(name) + current_form->name = name; /* store for the moment */ + else + return_value = CURL_FORMADD_NULL; + } + break; + case CURLFORM_NAMELENGTH: + if(current_form->namelength) + return_value = CURL_FORMADD_OPTION_TWICE; + else + current_form->namelength = + array_state?(size_t)array_value:(size_t)va_arg(params, long); + break; + + /* + * Set the contents property. + */ + case CURLFORM_PTRCONTENTS: + current_form->flags |= HTTPPOST_PTRCONTENTS; + /* FALLTHROUGH */ + case CURLFORM_COPYCONTENTS: + if(current_form->value) + return_value = CURL_FORMADD_OPTION_TWICE; + else { + char *value = + array_state?array_value:va_arg(params, char *); + if(value) + current_form->value = value; /* store for the moment */ + else + return_value = CURL_FORMADD_NULL; + } + break; + case CURLFORM_CONTENTSLENGTH: + current_form->contentslength = + array_state?(size_t)array_value:(size_t)va_arg(params, long); + break; + + case CURLFORM_CONTENTLEN: + current_form->flags |= CURL_HTTPPOST_LARGE; + current_form->contentslength = + array_state?(curl_off_t)(size_t)array_value:va_arg(params, curl_off_t); + break; + + /* Get contents from a given file name */ + case CURLFORM_FILECONTENT: + if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE)) + return_value = CURL_FORMADD_OPTION_TWICE; + else { + const char *filename = array_state? + array_value:va_arg(params, char *); + if(filename) { + current_form->value = strdup(filename); + if(!current_form->value) + return_value = CURL_FORMADD_MEMORY; + else { + current_form->flags |= HTTPPOST_READFILE; + current_form->value_alloc = TRUE; + } + } + else + return_value = CURL_FORMADD_NULL; + } + break; + + /* We upload a file */ + case CURLFORM_FILE: + { + const char *filename = array_state?array_value: + va_arg(params, char *); + + if(current_form->value) { + if(current_form->flags & HTTPPOST_FILENAME) { + if(filename) { + char *fname = strdup(filename); + if(!fname) + return_value = CURL_FORMADD_MEMORY; + else { + form = AddFormInfo(fname, NULL, current_form); + if(!form) { + free(fname); + return_value = CURL_FORMADD_MEMORY; + } + else { + form->value_alloc = TRUE; + current_form = form; + form = NULL; + } + } + } + else + return_value = CURL_FORMADD_NULL; + } + else + return_value = CURL_FORMADD_OPTION_TWICE; + } + else { + if(filename) { + current_form->value = strdup(filename); + if(!current_form->value) + return_value = CURL_FORMADD_MEMORY; + else { + current_form->flags |= HTTPPOST_FILENAME; + current_form->value_alloc = TRUE; + } + } + else + return_value = CURL_FORMADD_NULL; + } + break; + } + + case CURLFORM_BUFFERPTR: + current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER; + if(current_form->buffer) + return_value = CURL_FORMADD_OPTION_TWICE; + else { + char *buffer = + array_state?array_value:va_arg(params, char *); + if(buffer) { + current_form->buffer = buffer; /* store for the moment */ + current_form->value = buffer; /* make it non-NULL to be accepted + as fine */ + } + else + return_value = CURL_FORMADD_NULL; + } + break; + + case CURLFORM_BUFFERLENGTH: + if(current_form->bufferlength) + return_value = CURL_FORMADD_OPTION_TWICE; + else + current_form->bufferlength = + array_state?(size_t)array_value:(size_t)va_arg(params, long); + break; + + case CURLFORM_STREAM: + current_form->flags |= HTTPPOST_CALLBACK; + if(current_form->userp) + return_value = CURL_FORMADD_OPTION_TWICE; + else { + char *userp = + array_state?array_value:va_arg(params, char *); + if(userp) { + current_form->userp = userp; + current_form->value = userp; /* this isn't strictly true but we + derive a value from this later on + and we need this non-NULL to be + accepted as a fine form part */ + } + else + return_value = CURL_FORMADD_NULL; + } + break; + + case CURLFORM_CONTENTTYPE: + { + const char *contenttype = + array_state?array_value:va_arg(params, char *); + if(current_form->contenttype) { + if(current_form->flags & HTTPPOST_FILENAME) { + if(contenttype) { + char *type = strdup(contenttype); + if(!type) + return_value = CURL_FORMADD_MEMORY; + else { + form = AddFormInfo(NULL, type, current_form); + if(!form) { + free(type); + return_value = CURL_FORMADD_MEMORY; + } + else { + form->contenttype_alloc = TRUE; + current_form = form; + form = NULL; + } + } + } + else + return_value = CURL_FORMADD_NULL; + } + else + return_value = CURL_FORMADD_OPTION_TWICE; + } + else { + if(contenttype) { + current_form->contenttype = strdup(contenttype); + if(!current_form->contenttype) + return_value = CURL_FORMADD_MEMORY; + else + current_form->contenttype_alloc = TRUE; + } + else + return_value = CURL_FORMADD_NULL; + } + break; + } + case CURLFORM_CONTENTHEADER: + { + /* this "cast increases required alignment of target type" but + we consider it OK anyway */ + struct curl_slist *list = array_state? + (struct curl_slist *)(void *)array_value: + va_arg(params, struct curl_slist *); + + if(current_form->contentheader) + return_value = CURL_FORMADD_OPTION_TWICE; + else + current_form->contentheader = list; + + break; + } + case CURLFORM_FILENAME: + case CURLFORM_BUFFER: + { + const char *filename = array_state?array_value: + va_arg(params, char *); + if(current_form->showfilename) + return_value = CURL_FORMADD_OPTION_TWICE; + else { + current_form->showfilename = strdup(filename); + if(!current_form->showfilename) + return_value = CURL_FORMADD_MEMORY; + else + current_form->showfilename_alloc = TRUE; + } + break; + } + default: + return_value = CURL_FORMADD_UNKNOWN_OPTION; + break; + } + } + + if(CURL_FORMADD_OK != return_value) { + /* On error, free allocated fields for all nodes of the FormInfo linked + list without deallocating nodes. List nodes are deallocated later on */ + FormInfo *ptr; + for(ptr = first_form; ptr != NULL; ptr = ptr->more) { + if(ptr->name_alloc) { + Curl_safefree(ptr->name); + ptr->name_alloc = FALSE; + } + if(ptr->value_alloc) { + Curl_safefree(ptr->value); + ptr->value_alloc = FALSE; + } + if(ptr->contenttype_alloc) { + Curl_safefree(ptr->contenttype); + ptr->contenttype_alloc = FALSE; + } + if(ptr->showfilename_alloc) { + Curl_safefree(ptr->showfilename); + ptr->showfilename_alloc = FALSE; + } + } + } + + if(CURL_FORMADD_OK == return_value) { + /* go through the list, check for completeness and if everything is + * alright add the HttpPost item otherwise set return_value accordingly */ + + post = NULL; + for(form = first_form; + form != NULL; + form = form->more) { + if(((!form->name || !form->value) && !post) || + ( (form->contentslength) && + (form->flags & HTTPPOST_FILENAME) ) || + ( (form->flags & HTTPPOST_FILENAME) && + (form->flags & HTTPPOST_PTRCONTENTS) ) || + + ( (!form->buffer) && + (form->flags & HTTPPOST_BUFFER) && + (form->flags & HTTPPOST_PTRBUFFER) ) || + + ( (form->flags & HTTPPOST_READFILE) && + (form->flags & HTTPPOST_PTRCONTENTS) ) + ) { + return_value = CURL_FORMADD_INCOMPLETE; + break; + } + if(((form->flags & HTTPPOST_FILENAME) || + (form->flags & HTTPPOST_BUFFER)) && + !form->contenttype) { + char *f = (form->flags & HTTPPOST_BUFFER)? + form->showfilename : form->value; + char const *type; + type = Curl_mime_contenttype(f); + if(!type) + type = prevtype; + if(!type) + type = FILE_CONTENTTYPE_DEFAULT; + + /* our contenttype is missing */ + form->contenttype = strdup(type); + if(!form->contenttype) { + return_value = CURL_FORMADD_MEMORY; + break; + } + form->contenttype_alloc = TRUE; + } + if(form->name && form->namelength) { + /* Name should not contain nul bytes. */ + size_t i; + for(i = 0; i < form->namelength; i++) + if(!form->name[i]) { + return_value = CURL_FORMADD_NULL; + break; + } + if(return_value != CURL_FORMADD_OK) + break; + } + if(!(form->flags & HTTPPOST_PTRNAME) && + (form == first_form) ) { + /* Note that there's small risk that form->name is NULL here if the + app passed in a bad combo, so we better check for that first. */ + if(form->name) { + /* copy name (without strdup; possibly not nul-terminated) */ + form->name = Curl_memdup(form->name, form->namelength? + form->namelength: + strlen(form->name) + 1); + } + if(!form->name) { + return_value = CURL_FORMADD_MEMORY; + break; + } + form->name_alloc = TRUE; + } + if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE | + HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER | + HTTPPOST_CALLBACK)) && form->value) { + /* copy value (without strdup; possibly contains null characters) */ + size_t clen = (size_t) form->contentslength; + if(!clen) + clen = strlen(form->value) + 1; + + form->value = Curl_memdup(form->value, clen); + + if(!form->value) { + return_value = CURL_FORMADD_MEMORY; + break; + } + form->value_alloc = TRUE; + } + post = AddHttpPost(form->name, form->namelength, + form->value, form->contentslength, + form->buffer, form->bufferlength, + form->contenttype, form->flags, + form->contentheader, form->showfilename, + form->userp, + post, httppost, + last_post); + + if(!post) { + return_value = CURL_FORMADD_MEMORY; + break; + } + + if(form->contenttype) + prevtype = form->contenttype; + } + if(CURL_FORMADD_OK != return_value) { + /* On error, free allocated fields for nodes of the FormInfo linked + list which are not already owned by the httppost linked list + without deallocating nodes. List nodes are deallocated later on */ + FormInfo *ptr; + for(ptr = form; ptr != NULL; ptr = ptr->more) { + if(ptr->name_alloc) { + Curl_safefree(ptr->name); + ptr->name_alloc = FALSE; + } + if(ptr->value_alloc) { + Curl_safefree(ptr->value); + ptr->value_alloc = FALSE; + } + if(ptr->contenttype_alloc) { + Curl_safefree(ptr->contenttype); + ptr->contenttype_alloc = FALSE; + } + if(ptr->showfilename_alloc) { + Curl_safefree(ptr->showfilename); + ptr->showfilename_alloc = FALSE; + } + } + } + } + + /* Always deallocate FormInfo linked list nodes without touching node + fields given that these have either been deallocated or are owned + now by the httppost linked list */ + while(first_form) { + FormInfo *ptr = first_form->more; + free(first_form); + first_form = ptr; + } + + return return_value; +} + +/* + * curl_formadd() is a public API to add a section to the multipart formpost. + * + * @unittest: 1308 + */ + +CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...) +{ + va_list arg; + CURLFORMcode result; + va_start(arg, last_post); + result = FormAdd(httppost, last_post, arg); + va_end(arg); + return result; +} + +/* + * curl_formget() + * Serialize a curl_httppost struct. + * Returns 0 on success. + * + * @unittest: 1308 + */ +int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append) +{ + CURLcode result; + curl_mimepart toppart; + + Curl_mime_initpart(&toppart, NULL); /* default form is empty */ + result = Curl_getformdata(NULL, &toppart, form, NULL); + if(!result) + result = Curl_mime_prepare_headers(&toppart, "multipart/form-data", + NULL, MIMESTRATEGY_FORM); + + while(!result) { + char buffer[8192]; + size_t nread = Curl_mime_read(buffer, 1, sizeof(buffer), &toppart); + + if(!nread) + break; + + switch(nread) { + default: + if(append(arg, buffer, nread) != nread) + result = CURLE_READ_ERROR; + break; + case CURL_READFUNC_ABORT: + case CURL_READFUNC_PAUSE: + break; + } + } + + Curl_mime_cleanpart(&toppart); + return (int) result; +} + +/* + * curl_formfree() is an external function to free up a whole form post + * chain + */ +void curl_formfree(struct curl_httppost *form) +{ + struct curl_httppost *next; + + if(!form) + /* no form to free, just get out of this */ + return; + + do { + next = form->next; /* the following form line */ + + /* recurse to sub-contents */ + curl_formfree(form->more); + + if(!(form->flags & HTTPPOST_PTRNAME)) + free(form->name); /* free the name */ + if(!(form->flags & + (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK)) + ) + free(form->contents); /* free the contents */ + free(form->contenttype); /* free the content type */ + free(form->showfilename); /* free the faked file name */ + free(form); /* free the struct */ + form = next; + } while(form); /* continue */ +} + + +/* Set mime part name, taking care of non nul-terminated name string. */ +static CURLcode setname(curl_mimepart *part, const char *name, size_t len) +{ + char *zname; + CURLcode res; + + if(!name || !len) + return curl_mime_name(part, name); + zname = malloc(len + 1); + if(!zname) + return CURLE_OUT_OF_MEMORY; + memcpy(zname, name, len); + zname[len] = '\0'; + res = curl_mime_name(part, zname); + free(zname); + return res; +} + +/* + * Curl_getformdata() converts a linked list of "meta data" into a mime + * structure. The input list is in 'post', while the output is stored in + * mime part at '*finalform'. + * + * This function will not do a failf() for the potential memory failures but + * should for all other errors it spots. Just note that this function MAY get + * a NULL pointer in the 'data' argument. + */ + +CURLcode Curl_getformdata(struct Curl_easy *data, + curl_mimepart *finalform, + struct curl_httppost *post, + curl_read_callback fread_func) +{ + CURLcode result = CURLE_OK; + curl_mime *form = NULL; + curl_mimepart *part; + struct curl_httppost *file; + + Curl_mime_cleanpart(finalform); /* default form is empty */ + + if(!post) + return result; /* no input => no output! */ + + form = curl_mime_init(data); + if(!form) + result = CURLE_OUT_OF_MEMORY; + + if(!result) + result = curl_mime_subparts(finalform, form); + + /* Process each top part. */ + for(; !result && post; post = post->next) { + /* If we have more than a file here, create a mime subpart and fill it. */ + curl_mime *multipart = form; + if(post->more) { + part = curl_mime_addpart(form); + if(!part) + result = CURLE_OUT_OF_MEMORY; + if(!result) + result = setname(part, post->name, post->namelength); + if(!result) { + multipart = curl_mime_init(data); + if(!multipart) + result = CURLE_OUT_OF_MEMORY; + } + if(!result) + result = curl_mime_subparts(part, multipart); + } + + /* Generate all the part contents. */ + for(file = post; !result && file; file = file->more) { + /* Create the part. */ + part = curl_mime_addpart(multipart); + if(!part) + result = CURLE_OUT_OF_MEMORY; + + /* Set the headers. */ + if(!result) + result = curl_mime_headers(part, file->contentheader, 0); + + /* Set the content type. */ + if(!result && file->contenttype) + result = curl_mime_type(part, file->contenttype); + + /* Set field name. */ + if(!result && !post->more) + result = setname(part, post->name, post->namelength); + + /* Process contents. */ + if(!result) { + curl_off_t clen = post->contentslength; + + if(post->flags & CURL_HTTPPOST_LARGE) + clen = post->contentlen; + if(!clen) + clen = -1; + + if(post->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE)) { + if(!strcmp(file->contents, "-")) { + /* There are a few cases where the code below won't work; in + particular, freopen(stdin) by the caller is not guaranteed + to result as expected. This feature has been kept for backward + compatibility: use of "-" pseudo file name should be avoided. */ + result = curl_mime_data_cb(part, (curl_off_t) -1, + (curl_read_callback) fread, + CURLX_FUNCTION_CAST(curl_seek_callback, + fseek), + NULL, (void *) stdin); + } + else + result = curl_mime_filedata(part, file->contents); + if(!result && (post->flags & HTTPPOST_READFILE)) + result = curl_mime_filename(part, NULL); + } + else if(post->flags & HTTPPOST_BUFFER) + result = curl_mime_data(part, post->buffer, + post->bufferlength? post->bufferlength: -1); + else if(post->flags & HTTPPOST_CALLBACK) + /* the contents should be read with the callback and the size is set + with the contentslength */ + result = curl_mime_data_cb(part, clen, + fread_func, NULL, NULL, post->userp); + else { + result = curl_mime_data(part, post->contents, (ssize_t) clen); +#ifdef CURL_DOES_CONVERSIONS + /* Convert textual contents now. */ + if(!result && data && part->datasize) + result = Curl_convert_to_network(data, part->data, part->datasize); +#endif + } + } + + /* Set fake file name. */ + if(!result && post->showfilename) + if(post->more || (post->flags & (HTTPPOST_FILENAME | HTTPPOST_BUFFER | + HTTPPOST_CALLBACK))) + result = curl_mime_filename(part, post->showfilename); + } + } + + if(result) + Curl_mime_cleanpart(finalform); + + return result; +} + +#else +/* if disabled */ +CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...) +{ + (void)httppost; + (void)last_post; + return CURL_FORMADD_DISABLED; +} + +int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append) +{ + (void) form; + (void) arg; + (void) append; + return CURL_FORMADD_DISABLED; +} + +void curl_formfree(struct curl_httppost *form) +{ + (void)form; + /* does nothing HTTP is disabled */ +} + +#endif /* if disabled */ diff --git a/libcurl/lib/formdata.h b/libcurl/lib/formdata.h new file mode 100644 index 0000000..cb20805 --- /dev/null +++ b/libcurl/lib/formdata.h @@ -0,0 +1,60 @@ +#ifndef HEADER_CURL_FORMDATA_H +#define HEADER_CURL_FORMDATA_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_MIME + +/* used by FormAdd for temporary storage */ +typedef struct FormInfo { + char *name; + bool name_alloc; + size_t namelength; + char *value; + bool value_alloc; + curl_off_t contentslength; + char *contenttype; + bool contenttype_alloc; + long flags; + char *buffer; /* pointer to existing buffer used for file upload */ + size_t bufferlength; + char *showfilename; /* The file name to show. If not set, the actual + file name will be used */ + bool showfilename_alloc; + char *userp; /* pointer for the read callback */ + struct curl_slist *contentheader; + struct FormInfo *more; +} FormInfo; + +CURLcode Curl_getformdata(struct Curl_easy *data, + curl_mimepart *, + struct curl_httppost *post, + curl_read_callback fread_func); +#else +/* disabled */ +#define Curl_getformdata(a,b,c,d) CURLE_NOT_BUILT_IN +#endif + + +#endif /* HEADER_CURL_FORMDATA_H */ diff --git a/libcurl/lib/ftp.c b/libcurl/lib/ftp.c new file mode 100644 index 0000000..76ebbc4 --- /dev/null +++ b/libcurl/lib/ftp.c @@ -0,0 +1,4430 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_FTP + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_UTSNAME_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +#include +#include "urldata.h" +#include "sendf.h" +#include "if2ip.h" +#include "hostip.h" +#include "progress.h" +#include "transfer.h" +#include "escape.h" +#include "http.h" /* for HTTP proxy tunnel stuff */ +#include "socks.h" +#include "ftp.h" +#include "fileinfo.h" +#include "ftplistparser.h" +#include "curl_range.h" +#include "curl_sec.h" +#include "strtoofft.h" +#include "strcase.h" +#include "vtls/vtls.h" +#include "connect.h" +#include "strerror.h" +#include "inet_ntop.h" +#include "inet_pton.h" +#include "select.h" +#include "parsedate.h" /* for the week day and month names */ +#include "sockaddr.h" /* required for Curl_sockaddr_storage */ +#include "multiif.h" +#include "url.h" +#include "strcase.h" +#include "speedcheck.h" +#include "warnless.h" +#include "http_proxy.h" +#include "non-ascii.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + +#ifdef CURL_DISABLE_VERBOSE_STRINGS +#define ftp_pasv_verbose(a,b,c,d) Curl_nop_stmt +#endif + +/* Local API functions */ +#ifndef DEBUGBUILD +static void _state(struct connectdata *conn, + ftpstate newstate); +#define state(x,y) _state(x,y) +#else +static void _state(struct connectdata *conn, + ftpstate newstate, + int lineno); +#define state(x,y) _state(x,y,__LINE__) +#endif + +static CURLcode ftp_sendquote(struct connectdata *conn, + struct curl_slist *quote); +static CURLcode ftp_quit(struct connectdata *conn); +static CURLcode ftp_parse_url_path(struct connectdata *conn); +static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done); +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static void ftp_pasv_verbose(struct connectdata *conn, + Curl_addrinfo *ai, + char *newhost, /* ascii version */ + int port); +#endif +static CURLcode ftp_state_prepare_transfer(struct connectdata *conn); +static CURLcode ftp_state_mdtm(struct connectdata *conn); +static CURLcode ftp_state_quote(struct connectdata *conn, + bool init, ftpstate instate); +static CURLcode ftp_nb_type(struct connectdata *conn, + bool ascii, ftpstate newstate); +static int ftp_need_type(struct connectdata *conn, + bool ascii); +static CURLcode ftp_do(struct connectdata *conn, bool *done); +static CURLcode ftp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode ftp_connect(struct connectdata *conn, bool *done); +static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection); +static CURLcode ftp_do_more(struct connectdata *conn, int *completed); +static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done); +static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); +static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); +static CURLcode ftp_doing(struct connectdata *conn, + bool *dophase_done); +static CURLcode ftp_setup_connection(struct connectdata * conn); + +static CURLcode init_wc_data(struct connectdata *conn); +static CURLcode wc_statemach(struct connectdata *conn); + +static void wc_data_dtor(void *ptr); + +static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize); + +static CURLcode ftp_readresp(curl_socket_t sockfd, + struct pingpong *pp, + int *ftpcode, + size_t *size); +static CURLcode ftp_dophase_done(struct connectdata *conn, + bool connected); + +/* easy-to-use macro: */ +#define PPSENDF(x,y,z) result = Curl_pp_sendf(x,y,z); \ + if(result) \ + return result + + +/* + * FTP protocol handler. + */ + +const struct Curl_handler Curl_handler_ftp = { + "FTP", /* scheme */ + ftp_setup_connection, /* setup_connection */ + ftp_do, /* do_it */ + ftp_done, /* done */ + ftp_do_more, /* do_more */ + ftp_connect, /* connect_it */ + ftp_multi_statemach, /* connecting */ + ftp_doing, /* doing */ + ftp_getsock, /* proto_getsock */ + ftp_getsock, /* doing_getsock */ + ftp_domore_getsock, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ftp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_FTP, /* defport */ + CURLPROTO_FTP, /* protocol */ + PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD | + PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP | + PROTOPT_WILDCARD /* flags */ +}; + + +#ifdef USE_SSL +/* + * FTPS protocol handler. + */ + +const struct Curl_handler Curl_handler_ftps = { + "FTPS", /* scheme */ + ftp_setup_connection, /* setup_connection */ + ftp_do, /* do_it */ + ftp_done, /* done */ + ftp_do_more, /* do_more */ + ftp_connect, /* connect_it */ + ftp_multi_statemach, /* connecting */ + ftp_doing, /* doing */ + ftp_getsock, /* proto_getsock */ + ftp_getsock, /* doing_getsock */ + ftp_domore_getsock, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ftp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_FTPS, /* defport */ + CURLPROTO_FTPS, /* protocol */ + PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION | + PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD /* flags */ +}; +#endif + +static void close_secondarysocket(struct connectdata *conn) +{ + if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) { + Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]); + conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; + } + conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE; +} + +/* + * NOTE: back in the old days, we added code in the FTP code that made NOBODY + * requests on files respond with headers passed to the client/stdout that + * looked like HTTP ones. + * + * This approach is not very elegant, it causes confusion and is error-prone. + * It is subject for removal at the next (or at least a future) soname bump. + * Until then you can test the effects of the removal by undefining the + * following define named CURL_FTP_HTTPSTYLE_HEAD. + */ +#define CURL_FTP_HTTPSTYLE_HEAD 1 + +static void freedirs(struct ftp_conn *ftpc) +{ + if(ftpc->dirs) { + int i; + for(i = 0; i < ftpc->dirdepth; i++) { + free(ftpc->dirs[i]); + ftpc->dirs[i] = NULL; + } + free(ftpc->dirs); + ftpc->dirs = NULL; + ftpc->dirdepth = 0; + } + Curl_safefree(ftpc->file); + + /* no longer of any use */ + Curl_safefree(ftpc->newhost); +} + +/* Returns non-zero if the given string contains CR (\r) or LF (\n), + which are not allowed within RFC 959 . + Note: The input string is in the client's encoding which might + not be ASCII, so escape sequences \r & \n must be used instead + of hex values 0x0d & 0x0a. +*/ +static bool isBadFtpString(const char *string) +{ + return ((NULL != strchr(string, '\r')) || + (NULL != strchr(string, '\n'))) ? TRUE : FALSE; +} + +/*********************************************************************** + * + * AcceptServerConnect() + * + * After connection request is received from the server this function is + * called to accept the connection and close the listening socket + * + */ +static CURLcode AcceptServerConnect(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + curl_socket_t sock = conn->sock[SECONDARYSOCKET]; + curl_socket_t s = CURL_SOCKET_BAD; +#ifdef ENABLE_IPV6 + struct Curl_sockaddr_storage add; +#else + struct sockaddr_in add; +#endif + curl_socklen_t size = (curl_socklen_t) sizeof(add); + + if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) { + size = sizeof(add); + + s = accept(sock, (struct sockaddr *) &add, &size); + } + Curl_closesocket(conn, sock); /* close the first socket */ + + if(CURL_SOCKET_BAD == s) { + failf(data, "Error accept()ing server connect"); + return CURLE_FTP_PORT_FAILED; + } + infof(data, "Connection accepted from server\n"); + /* when this happens within the DO state it is important that we mark us as + not needing DO_MORE anymore */ + conn->bits.do_more = FALSE; + + conn->sock[SECONDARYSOCKET] = s; + (void)curlx_nonblock(s, TRUE); /* enable non-blocking */ + conn->sock_accepted[SECONDARYSOCKET] = TRUE; + + if(data->set.fsockopt) { + int error = 0; + + /* activate callback for setting socket options */ + Curl_set_in_callback(data, true); + error = data->set.fsockopt(data->set.sockopt_client, + s, + CURLSOCKTYPE_ACCEPT); + Curl_set_in_callback(data, false); + + if(error) { + close_secondarysocket(conn); + return CURLE_ABORTED_BY_CALLBACK; + } + } + + return CURLE_OK; + +} + +/* + * ftp_timeleft_accept() returns the amount of milliseconds left allowed for + * waiting server to connect. If the value is negative, the timeout time has + * already elapsed. + * + * The start time is stored in progress.t_acceptdata - as set with + * Curl_pgrsTime(..., TIMER_STARTACCEPT); + * + */ +static timediff_t ftp_timeleft_accept(struct Curl_easy *data) +{ + timediff_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT; + timediff_t other; + struct curltime now; + + if(data->set.accepttimeout > 0) + timeout_ms = data->set.accepttimeout; + + now = Curl_now(); + + /* check if the generic timeout possibly is set shorter */ + other = Curl_timeleft(data, &now, FALSE); + if(other && (other < timeout_ms)) + /* note that this also works fine for when other happens to be negative + due to it already having elapsed */ + timeout_ms = other; + else { + /* subtract elapsed time */ + timeout_ms -= Curl_timediff(now, data->progress.t_acceptdata); + if(!timeout_ms) + /* avoid returning 0 as that means no timeout! */ + return -1; + } + + return timeout_ms; +} + + +/*********************************************************************** + * + * ReceivedServerConnect() + * + * After allowing server to connect to us from data port, this function + * checks both data connection for connection establishment and ctrl + * connection for a negative response regarding a failure in connecting + * + */ +static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received) +{ + struct Curl_easy *data = conn->data; + curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET]; + curl_socket_t data_sock = conn->sock[SECONDARYSOCKET]; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + int result; + time_t timeout_ms; + ssize_t nread; + int ftpcode; + + *received = FALSE; + + timeout_ms = ftp_timeleft_accept(data); + infof(data, "Checking for server connect\n"); + if(timeout_ms < 0) { + /* if a timeout was already reached, bail out */ + failf(data, "Accept timeout occurred while waiting server connect"); + return CURLE_FTP_ACCEPT_TIMEOUT; + } + + /* First check whether there is a cached response from server */ + if(pp->cache_size && pp->cache && pp->cache[0] > '3') { + /* Data connection could not be established, let's return */ + infof(data, "There is negative response in cache while serv connect\n"); + Curl_GetFTPResponse(&nread, conn, &ftpcode); + return CURLE_FTP_ACCEPT_FAILED; + } + + result = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0); + + /* see if the connection request is already here */ + switch(result) { + case -1: /* error */ + /* let's die here */ + failf(data, "Error while waiting for server connect"); + return CURLE_FTP_ACCEPT_FAILED; + case 0: /* Server connect is not received yet */ + break; /* loop */ + default: + + if(result & CURL_CSELECT_IN2) { + infof(data, "Ready to accept data connection from server\n"); + *received = TRUE; + } + else if(result & CURL_CSELECT_IN) { + infof(data, "Ctrl conn has data while waiting for data conn\n"); + Curl_GetFTPResponse(&nread, conn, &ftpcode); + + if(ftpcode/100 > 3) + return CURLE_FTP_ACCEPT_FAILED; + + return CURLE_WEIRD_SERVER_REPLY; + } + + break; + } /* switch() */ + + return CURLE_OK; +} + + +/*********************************************************************** + * + * InitiateTransfer() + * + * After connection from server is accepted this function is called to + * setup transfer parameters and initiate the data transfer. + * + */ +static CURLcode InitiateTransfer(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + CURLcode result = CURLE_OK; + + if(conn->bits.ftp_use_data_ssl) { + /* since we only have a plaintext TCP connection here, we must now + * do the TLS stuff */ + infof(data, "Doing the SSL/TLS handshake on the data stream\n"); + result = Curl_ssl_connect(conn, SECONDARYSOCKET); + if(result) + return result; + } + + if(conn->proto.ftpc.state_saved == FTP_STOR) { + /* When we know we're uploading a specified file, we can get the file + size prior to the actual upload. */ + Curl_pgrsSetUploadSize(data, data->state.infilesize); + + /* set the SO_SNDBUF for the secondary socket for those who need it */ + Curl_sndbufset(conn->sock[SECONDARYSOCKET]); + + Curl_setup_transfer(data, -1, -1, FALSE, SECONDARYSOCKET); + } + else { + /* FTP download: */ + Curl_setup_transfer(data, SECONDARYSOCKET, + conn->proto.ftpc.retr_size_saved, FALSE, -1); + } + + conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */ + state(conn, FTP_STOP); + + return CURLE_OK; +} + +/*********************************************************************** + * + * AllowServerConnect() + * + * When we've issue the PORT command, we have told the server to connect to + * us. This function checks whether data connection is established if so it is + * accepted. + * + */ +static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected) +{ + struct Curl_easy *data = conn->data; + time_t timeout_ms; + CURLcode result = CURLE_OK; + + *connected = FALSE; + infof(data, "Preparing for accepting server on data port\n"); + + /* Save the time we start accepting server connect */ + Curl_pgrsTime(data, TIMER_STARTACCEPT); + + timeout_ms = ftp_timeleft_accept(data); + if(timeout_ms < 0) { + /* if a timeout was already reached, bail out */ + failf(data, "Accept timeout occurred while waiting server connect"); + return CURLE_FTP_ACCEPT_TIMEOUT; + } + + /* see if the connection request is already here */ + result = ReceivedServerConnect(conn, connected); + if(result) + return result; + + if(*connected) { + result = AcceptServerConnect(conn); + if(result) + return result; + + result = InitiateTransfer(conn); + if(result) + return result; + } + else { + /* Add timeout to multi handle and break out of the loop */ + if(!result && *connected == FALSE) { + Curl_expire(data, data->set.accepttimeout > 0 ? + data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT, 0); + } + } + + return result; +} + +/* macro to check for a three-digit ftp status code at the start of the + given string */ +#define STATUSCODE(line) (ISDIGIT(line[0]) && ISDIGIT(line[1]) && \ + ISDIGIT(line[2])) + +/* macro to check for the last line in an FTP server response */ +#define LASTLINE(line) (STATUSCODE(line) && (' ' == line[3])) + +static bool ftp_endofresp(struct connectdata *conn, char *line, size_t len, + int *code) +{ + (void)conn; + + if((len > 3) && LASTLINE(line)) { + *code = curlx_sltosi(strtol(line, NULL, 10)); + return TRUE; + } + + return FALSE; +} + +static CURLcode ftp_readresp(curl_socket_t sockfd, + struct pingpong *pp, + int *ftpcode, /* return the ftp-code if done */ + size_t *size) /* size of the response */ +{ + struct connectdata *conn = pp->conn; + struct Curl_easy *data = conn->data; +#ifdef HAVE_GSSAPI + char * const buf = data->state.buffer; +#endif + int code; + CURLcode result = Curl_pp_readresp(sockfd, pp, &code, size); + +#if defined(HAVE_GSSAPI) + /* handle the security-oriented responses 6xx ***/ + switch(code) { + case 631: + code = Curl_sec_read_msg(conn, buf, PROT_SAFE); + break; + case 632: + code = Curl_sec_read_msg(conn, buf, PROT_PRIVATE); + break; + case 633: + code = Curl_sec_read_msg(conn, buf, PROT_CONFIDENTIAL); + break; + default: + /* normal ftp stuff we pass through! */ + break; + } +#endif + + /* store the latest code for later retrieval */ + data->info.httpcode = code; + + if(ftpcode) + *ftpcode = code; + + if(421 == code) { + /* 421 means "Service not available, closing control connection." and FTP + * servers use it to signal that idle session timeout has been exceeded. + * If we ignored the response, it could end up hanging in some cases. + * + * This response code can come at any point so having it treated + * generically is a good idea. + */ + infof(data, "We got a 421 - timeout!\n"); + state(conn, FTP_STOP); + return CURLE_OPERATION_TIMEDOUT; + } + + return result; +} + +/* --- parse FTP server responses --- */ + +/* + * Curl_GetFTPResponse() is a BLOCKING function to read the full response + * from a server after a command. + * + */ + +CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */ + struct connectdata *conn, + int *ftpcode) /* return the ftp-code */ +{ + /* + * We cannot read just one byte per read() and then go back to select() as + * the OpenSSL read() doesn't grok that properly. + * + * Alas, read as much as possible, split up into lines, use the ending + * line in a response or continue reading. */ + + curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; + struct Curl_easy *data = conn->data; + CURLcode result = CURLE_OK; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + size_t nread; + int cache_skip = 0; + int value_to_be_ignored = 0; + + if(ftpcode) + *ftpcode = 0; /* 0 for errors */ + else + /* make the pointer point to something for the rest of this function */ + ftpcode = &value_to_be_ignored; + + *nreadp = 0; + + while(!*ftpcode && !result) { + /* check and reset timeout value every lap */ + time_t timeout = Curl_pp_state_timeout(pp, FALSE); + time_t interval_ms; + + if(timeout <= 0) { + failf(data, "FTP response timeout"); + return CURLE_OPERATION_TIMEDOUT; /* already too little time */ + } + + interval_ms = 1000; /* use 1 second timeout intervals */ + if(timeout < interval_ms) + interval_ms = timeout; + + /* + * Since this function is blocking, we need to wait here for input on the + * connection and only then we call the response reading function. We do + * timeout at least every second to make the timeout check run. + * + * A caution here is that the ftp_readresp() function has a cache that may + * contain pieces of a response from the previous invoke and we need to + * make sure we don't just wait for input while there is unhandled data in + * that cache. But also, if the cache is there, we call ftp_readresp() and + * the cache wasn't good enough to continue we must not just busy-loop + * around this function. + * + */ + + if(pp->cache && (cache_skip < 2)) { + /* + * There's a cache left since before. We then skipping the wait for + * socket action, unless this is the same cache like the previous round + * as then the cache was deemed not enough to act on and we then need to + * wait for more data anyway. + */ + } + else if(!Curl_conn_data_pending(conn, FIRSTSOCKET)) { + switch(SOCKET_READABLE(sockfd, interval_ms)) { + case -1: /* select() error, stop reading */ + failf(data, "FTP response aborted due to select/poll error: %d", + SOCKERRNO); + return CURLE_RECV_ERROR; + + case 0: /* timeout */ + if(Curl_pgrsUpdate(conn)) + return CURLE_ABORTED_BY_CALLBACK; + continue; /* just continue in our loop for the timeout duration */ + + default: /* for clarity */ + break; + } + } + result = ftp_readresp(sockfd, pp, ftpcode, &nread); + if(result) + break; + + if(!nread && pp->cache) + /* bump cache skip counter as on repeated skips we must wait for more + data */ + cache_skip++; + else + /* when we got data or there is no cache left, we reset the cache skip + counter */ + cache_skip = 0; + + *nreadp += nread; + + } /* while there's buffer left and loop is requested */ + + pp->pending_resp = FALSE; + + return result; +} + +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* for debug purposes */ +static const char * const ftp_state_names[]={ + "STOP", + "WAIT220", + "AUTH", + "USER", + "PASS", + "ACCT", + "PBSZ", + "PROT", + "CCC", + "PWD", + "SYST", + "NAMEFMT", + "QUOTE", + "RETR_PREQUOTE", + "STOR_PREQUOTE", + "POSTQUOTE", + "CWD", + "MKD", + "MDTM", + "TYPE", + "LIST_TYPE", + "RETR_TYPE", + "STOR_TYPE", + "SIZE", + "RETR_SIZE", + "STOR_SIZE", + "REST", + "RETR_REST", + "PORT", + "PRET", + "PASV", + "LIST", + "RETR", + "STOR", + "QUIT" +}; +#endif + +/* This is the ONLY way to change FTP state! */ +static void _state(struct connectdata *conn, + ftpstate newstate +#ifdef DEBUGBUILD + , int lineno +#endif + ) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + +#if defined(DEBUGBUILD) + +#if defined(CURL_DISABLE_VERBOSE_STRINGS) + (void) lineno; +#else + if(ftpc->state != newstate) + infof(conn->data, "FTP %p (line %d) state change from %s to %s\n", + (void *)ftpc, lineno, ftp_state_names[ftpc->state], + ftp_state_names[newstate]); +#endif +#endif + + ftpc->state = newstate; +} + +static CURLcode ftp_state_user(struct connectdata *conn) +{ + CURLcode result; + struct FTP *ftp = conn->data->req.protop; + /* send USER */ + PPSENDF(&conn->proto.ftpc.pp, "USER %s", ftp->user?ftp->user:""); + + state(conn, FTP_USER); + conn->data->state.ftp_trying_alternative = FALSE; + + return CURLE_OK; +} + +static CURLcode ftp_state_pwd(struct connectdata *conn) +{ + CURLcode result; + + /* send PWD to discover our entry point */ + PPSENDF(&conn->proto.ftpc.pp, "%s", "PWD"); + state(conn, FTP_PWD); + + return CURLE_OK; +} + +/* For the FTP "protocol connect" and "doing" phases only */ +static int ftp_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) +{ + return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks); +} + +/* For the FTP "DO_MORE" phase only */ +static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if(!numsocks) + return GETSOCK_BLANK; + + /* When in DO_MORE state, we could be either waiting for us to connect to a + * remote site, or we could wait for that site to connect to us. Or just + * handle ordinary commands. + */ + + if(FTP_STOP == ftpc->state) { + int bits = GETSOCK_READSOCK(0); + + /* if stopped and still in this state, then we're also waiting for a + connect on the secondary connection */ + socks[0] = conn->sock[FIRSTSOCKET]; + + if(!conn->data->set.ftp_use_port) { + int s; + int i; + /* PORT is used to tell the server to connect to us, and during that we + don't do happy eyeballs, but we do if we connect to the server */ + for(s = 1, i = 0; i<2; i++) { + if(conn->tempsock[i] != CURL_SOCKET_BAD) { + socks[s] = conn->tempsock[i]; + bits |= GETSOCK_WRITESOCK(s++); + } + } + } + else { + socks[1] = conn->sock[SECONDARYSOCKET]; + bits |= GETSOCK_WRITESOCK(1) | GETSOCK_READSOCK(1); + } + + return bits; + } + return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks); +} + +/* This is called after the FTP_QUOTE state is passed. + + ftp_state_cwd() sends the range of CWD commands to the server to change to + the correct directory. It may also need to send MKD commands to create + missing ones, if that option is enabled. +*/ +static CURLcode ftp_state_cwd(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if(ftpc->cwddone) + /* already done and fine */ + result = ftp_state_mdtm(conn); + else { + ftpc->count2 = 0; /* count2 counts failed CWDs */ + + /* count3 is set to allow a MKD to fail once. In the case when first CWD + fails and then MKD fails (due to another session raced it to create the + dir) this then allows for a second try to CWD to it */ + ftpc->count3 = (conn->data->set.ftp_create_missing_dirs == 2)?1:0; + + if((conn->data->set.ftp_filemethod == FTPFILE_NOCWD) && !ftpc->cwdcount) + /* No CWD necessary */ + result = ftp_state_mdtm(conn); + else if(conn->bits.reuse && ftpc->entrypath) { + /* This is a re-used connection. Since we change directory to where the + transfer is taking place, we must first get back to the original dir + where we ended up after login: */ + ftpc->cwdcount = 0; /* we count this as the first path, then we add one + for all upcoming ones in the ftp->dirs[] array */ + PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->entrypath); + state(conn, FTP_CWD); + } + else { + if(ftpc->dirdepth) { + ftpc->cwdcount = 1; + /* issue the first CWD, the rest is sent when the CWD responses are + received... */ + PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->dirs[ftpc->cwdcount -1]); + state(conn, FTP_CWD); + } + else { + /* No CWD necessary */ + result = ftp_state_mdtm(conn); + } + } + } + return result; +} + +typedef enum { + EPRT, + PORT, + DONE +} ftpport; + +static CURLcode ftp_state_use_port(struct connectdata *conn, + ftpport fcmd) /* start with this */ + +{ + CURLcode result = CURLE_OK; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct Curl_easy *data = conn->data; + curl_socket_t portsock = CURL_SOCKET_BAD; + char myhost[256] = ""; + + struct Curl_sockaddr_storage ss; + Curl_addrinfo *res, *ai; + curl_socklen_t sslen; + char hbuf[NI_MAXHOST]; + struct sockaddr *sa = (struct sockaddr *)&ss; + struct sockaddr_in * const sa4 = (void *)sa; +#ifdef ENABLE_IPV6 + struct sockaddr_in6 * const sa6 = (void *)sa; +#endif + char tmp[1024]; + static const char mode[][5] = { "EPRT", "PORT" }; + int rc; + int error; + char *host = NULL; + char *string_ftpport = data->set.str[STRING_FTPPORT]; + struct Curl_dns_entry *h = NULL; + unsigned short port_min = 0; + unsigned short port_max = 0; + unsigned short port; + bool possibly_non_local = TRUE; + char buffer[STRERROR_LEN]; + char *addr = NULL; + + /* Step 1, figure out what is requested, + * accepted format : + * (ipv4|ipv6|domain|interface)?(:port(-range)?)? + */ + + if(data->set.str[STRING_FTPPORT] && + (strlen(data->set.str[STRING_FTPPORT]) > 1)) { + +#ifdef ENABLE_IPV6 + size_t addrlen = INET6_ADDRSTRLEN > strlen(string_ftpport) ? + INET6_ADDRSTRLEN : strlen(string_ftpport); +#else + size_t addrlen = INET_ADDRSTRLEN > strlen(string_ftpport) ? + INET_ADDRSTRLEN : strlen(string_ftpport); +#endif + char *ip_start = string_ftpport; + char *ip_end = NULL; + char *port_start = NULL; + char *port_sep = NULL; + + addr = calloc(addrlen + 1, 1); + if(!addr) + return CURLE_OUT_OF_MEMORY; + +#ifdef ENABLE_IPV6 + if(*string_ftpport == '[') { + /* [ipv6]:port(-range) */ + ip_start = string_ftpport + 1; + ip_end = strchr(string_ftpport, ']'); + if(ip_end) + strncpy(addr, ip_start, ip_end - ip_start); + } + else +#endif + if(*string_ftpport == ':') { + /* :port */ + ip_end = string_ftpport; + } + else { + ip_end = strchr(string_ftpport, ':'); + if(ip_end) { + /* either ipv6 or (ipv4|domain|interface):port(-range) */ +#ifdef ENABLE_IPV6 + if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) { + /* ipv6 */ + port_min = port_max = 0; + strcpy(addr, string_ftpport); + ip_end = NULL; /* this got no port ! */ + } + else +#endif + /* (ipv4|domain|interface):port(-range) */ + strncpy(addr, string_ftpport, ip_end - ip_start); + } + else + /* ipv4|interface */ + strcpy(addr, string_ftpport); + } + + /* parse the port */ + if(ip_end != NULL) { + port_start = strchr(ip_end, ':'); + if(port_start) { + port_min = curlx_ultous(strtoul(port_start + 1, NULL, 10)); + port_sep = strchr(port_start, '-'); + if(port_sep) { + port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10)); + } + else + port_max = port_min; + } + } + + /* correct errors like: + * :1234-1230 + * :-4711, in this case port_min is (unsigned)-1, + * therefore port_min > port_max for all cases + * but port_max = (unsigned)-1 + */ + if(port_min > port_max) + port_min = port_max = 0; + + + if(*addr != '\0') { + /* attempt to get the address of the given interface name */ + switch(Curl_if2ip(conn->ip_addr->ai_family, + Curl_ipv6_scope(conn->ip_addr->ai_addr), + conn->scope_id, addr, hbuf, sizeof(hbuf))) { + case IF2IP_NOT_FOUND: + /* not an interface, use the given string as host name instead */ + host = addr; + break; + case IF2IP_AF_NOT_SUPPORTED: + return CURLE_FTP_PORT_FAILED; + case IF2IP_FOUND: + host = hbuf; /* use the hbuf for host name */ + } + } + else + /* there was only a port(-range) given, default the host */ + host = NULL; + } /* data->set.ftpport */ + + if(!host) { + /* not an interface and not a host name, get default by extracting + the IP from the control connection */ + sslen = sizeof(ss); + if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) { + failf(data, "getsockname() failed: %s", + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + free(addr); + return CURLE_FTP_PORT_FAILED; + } + switch(sa->sa_family) { +#ifdef ENABLE_IPV6 + case AF_INET6: + Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf)); + break; +#endif + default: + Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf)); + break; + } + host = hbuf; /* use this host name */ + possibly_non_local = FALSE; /* we know it is local now */ + } + + /* resolv ip/host to ip */ + rc = Curl_resolv(conn, host, 0, FALSE, &h); + if(rc == CURLRESOLV_PENDING) + (void)Curl_resolver_wait_resolv(conn, &h); + if(h) { + res = h->addr; + /* when we return from this function, we can forget about this entry + to we can unlock it now already */ + Curl_resolv_unlock(data, h); + } /* (h) */ + else + res = NULL; /* failure! */ + + if(res == NULL) { + failf(data, "failed to resolve the address provided to PORT: %s", host); + free(addr); + return CURLE_FTP_PORT_FAILED; + } + + free(addr); + host = NULL; + + /* step 2, create a socket for the requested address */ + + portsock = CURL_SOCKET_BAD; + error = 0; + for(ai = res; ai; ai = ai->ai_next) { + result = Curl_socket(conn, ai, NULL, &portsock); + if(result) { + error = SOCKERRNO; + continue; + } + break; + } + if(!ai) { + failf(data, "socket failure: %s", + Curl_strerror(error, buffer, sizeof(buffer))); + return CURLE_FTP_PORT_FAILED; + } + + /* step 3, bind to a suitable local address */ + + memcpy(sa, ai->ai_addr, ai->ai_addrlen); + sslen = ai->ai_addrlen; + + for(port = port_min; port <= port_max;) { + if(sa->sa_family == AF_INET) + sa4->sin_port = htons(port); +#ifdef ENABLE_IPV6 + else + sa6->sin6_port = htons(port); +#endif + /* Try binding the given address. */ + if(bind(portsock, sa, sslen) ) { + /* It failed. */ + error = SOCKERRNO; + if(possibly_non_local && (error == EADDRNOTAVAIL)) { + /* The requested bind address is not local. Use the address used for + * the control connection instead and restart the port loop + */ + infof(data, "bind(port=%hu) on non-local address failed: %s\n", port, + Curl_strerror(error, buffer, sizeof(buffer))); + + sslen = sizeof(ss); + if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) { + failf(data, "getsockname() failed: %s", + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + Curl_closesocket(conn, portsock); + return CURLE_FTP_PORT_FAILED; + } + port = port_min; + possibly_non_local = FALSE; /* don't try this again */ + continue; + } + if(error != EADDRINUSE && error != EACCES) { + failf(data, "bind(port=%hu) failed: %s", port, + Curl_strerror(error, buffer, sizeof(buffer))); + Curl_closesocket(conn, portsock); + return CURLE_FTP_PORT_FAILED; + } + } + else + break; + + port++; + } + + /* maybe all ports were in use already*/ + if(port > port_max) { + failf(data, "bind() failed, we ran out of ports!"); + Curl_closesocket(conn, portsock); + return CURLE_FTP_PORT_FAILED; + } + + /* get the name again after the bind() so that we can extract the + port number it uses now */ + sslen = sizeof(ss); + if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) { + failf(data, "getsockname() failed: %s", + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + Curl_closesocket(conn, portsock); + return CURLE_FTP_PORT_FAILED; + } + + /* step 4, listen on the socket */ + + if(listen(portsock, 1)) { + failf(data, "socket failure: %s", + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + Curl_closesocket(conn, portsock); + return CURLE_FTP_PORT_FAILED; + } + + /* step 5, send the proper FTP command */ + + /* get a plain printable version of the numerical address to work with + below */ + Curl_printable_address(ai, myhost, sizeof(myhost)); + +#ifdef ENABLE_IPV6 + if(!conn->bits.ftp_use_eprt && conn->bits.ipv6) + /* EPRT is disabled but we are connected to a IPv6 host, so we ignore the + request and enable EPRT again! */ + conn->bits.ftp_use_eprt = TRUE; +#endif + + for(; fcmd != DONE; fcmd++) { + + if(!conn->bits.ftp_use_eprt && (EPRT == fcmd)) + /* if disabled, goto next */ + continue; + + if((PORT == fcmd) && sa->sa_family != AF_INET) + /* PORT is IPv4 only */ + continue; + + switch(sa->sa_family) { + case AF_INET: + port = ntohs(sa4->sin_port); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + port = ntohs(sa6->sin6_port); + break; +#endif + default: + continue; /* might as well skip this */ + } + + if(EPRT == fcmd) { + /* + * Two fine examples from RFC2428; + * + * EPRT |1|132.235.1.2|6275| + * + * EPRT |2|1080::8:800:200C:417A|5282| + */ + + result = Curl_pp_sendf(&ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd], + sa->sa_family == AF_INET?1:2, + myhost, port); + if(result) { + failf(data, "Failure sending EPRT command: %s", + curl_easy_strerror(result)); + Curl_closesocket(conn, portsock); + /* don't retry using PORT */ + ftpc->count1 = PORT; + /* bail out */ + state(conn, FTP_STOP); + return result; + } + break; + } + if(PORT == fcmd) { + char *source = myhost; + char *dest = tmp; + + /* translate x.x.x.x to x,x,x,x */ + while(source && *source) { + if(*source == '.') + *dest = ','; + else + *dest = *source; + dest++; + source++; + } + *dest = 0; + msnprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff)); + + result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp); + if(result) { + failf(data, "Failure sending PORT command: %s", + curl_easy_strerror(result)); + Curl_closesocket(conn, portsock); + /* bail out */ + state(conn, FTP_STOP); + return result; + } + break; + } + } + + /* store which command was sent */ + ftpc->count1 = fcmd; + + close_secondarysocket(conn); + + /* we set the secondary socket variable to this for now, it is only so that + the cleanup function will close it in case we fail before the true + secondary stuff is made */ + conn->sock[SECONDARYSOCKET] = portsock; + + /* this tcpconnect assignment below is a hackish work-around to make the + multi interface with active FTP work - as it will not wait for a + (passive) connect in Curl_is_connected(). + + The *proper* fix is to make sure that the active connection from the + server is done in a non-blocking way. Currently, it is still BLOCKING. + */ + conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE; + + state(conn, FTP_PORT); + return result; +} + +static CURLcode ftp_state_use_pasv(struct connectdata *conn) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + CURLcode result = CURLE_OK; + /* + Here's the excecutive summary on what to do: + + PASV is RFC959, expect: + 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2) + + LPSV is RFC1639, expect: + 228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2) + + EPSV is RFC2428, expect: + 229 Entering Extended Passive Mode (|||port|) + + */ + + static const char mode[][5] = { "EPSV", "PASV" }; + int modeoff; + +#ifdef PF_INET6 + if(!conn->bits.ftp_use_epsv && conn->bits.ipv6) + /* EPSV is disabled but we are connected to a IPv6 host, so we ignore the + request and enable EPSV again! */ + conn->bits.ftp_use_epsv = TRUE; +#endif + + modeoff = conn->bits.ftp_use_epsv?0:1; + + PPSENDF(&ftpc->pp, "%s", mode[modeoff]); + + ftpc->count1 = modeoff; + state(conn, FTP_PASV); + infof(conn->data, "Connect data stream passively\n"); + + return result; +} + +/* + * ftp_state_prepare_transfer() starts PORT, PASV or PRET etc. + * + * REST is the last command in the chain of commands when a "head"-like + * request is made. Thus, if an actual transfer is to be made this is where we + * take off for real. + */ +static CURLcode ftp_state_prepare_transfer(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct FTP *ftp = conn->data->req.protop; + struct Curl_easy *data = conn->data; + + if(ftp->transfer != FTPTRANSFER_BODY) { + /* doesn't transfer any data */ + + /* still possibly do PRE QUOTE jobs */ + state(conn, FTP_RETR_PREQUOTE); + result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE); + } + else if(data->set.ftp_use_port) { + /* We have chosen to use the PORT (or similar) command */ + result = ftp_state_use_port(conn, EPRT); + } + else { + /* We have chosen (this is default) to use the PASV (or similar) command */ + if(data->set.ftp_use_pret) { + /* The user has requested that we send a PRET command + to prepare the server for the upcoming PASV */ + if(!conn->proto.ftpc.file) { + PPSENDF(&conn->proto.ftpc.pp, "PRET %s", + data->set.str[STRING_CUSTOMREQUEST]? + data->set.str[STRING_CUSTOMREQUEST]: + (data->set.ftp_list_only?"NLST":"LIST")); + } + else if(data->set.upload) { + PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file); + } + else { + PPSENDF(&conn->proto.ftpc.pp, "PRET RETR %s", conn->proto.ftpc.file); + } + state(conn, FTP_PRET); + } + else { + result = ftp_state_use_pasv(conn); + } + } + return result; +} + +static CURLcode ftp_state_rest(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct FTP *ftp = conn->data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if((ftp->transfer != FTPTRANSFER_BODY) && ftpc->file) { + /* if a "head"-like request is being made (on a file) */ + + /* Determine if server can respond to REST command and therefore + whether it supports range */ + PPSENDF(&conn->proto.ftpc.pp, "REST %d", 0); + + state(conn, FTP_REST); + } + else + result = ftp_state_prepare_transfer(conn); + + return result; +} + +static CURLcode ftp_state_size(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct FTP *ftp = conn->data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if((ftp->transfer == FTPTRANSFER_INFO) && ftpc->file) { + /* if a "head"-like request is being made (on a file) */ + + /* we know ftpc->file is a valid pointer to a file name */ + PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file); + + state(conn, FTP_SIZE); + } + else + result = ftp_state_rest(conn); + + return result; +} + +static CURLcode ftp_state_list(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + + /* If this output is to be machine-parsed, the NLST command might be better + to use, since the LIST command output is not specified or standard in any + way. It has turned out that the NLST list output is not the same on all + servers either... */ + + /* + if FTPFILE_NOCWD was specified, we are currently in + the user's home directory, so we should add the path + as argument for the LIST / NLST / or custom command. + Whether the server will support this, is uncertain. + + The other ftp_filemethods will CWD into dir/dir/ first and + then just do LIST (in that case: nothing to do here) + */ + char *cmd, *lstArg, *slashPos; + const char *inpath = ftp->path; + + lstArg = NULL; + if((data->set.ftp_filemethod == FTPFILE_NOCWD) && + inpath && inpath[0] && strchr(inpath, '/')) { + size_t n = strlen(inpath); + + /* Check if path does not end with /, as then we cut off the file part */ + if(inpath[n - 1] != '/') { + /* chop off the file part if format is dir/dir/file */ + slashPos = strrchr(inpath, '/'); + n = slashPos - inpath; + } + result = Curl_urldecode(data, inpath, n, &lstArg, NULL, TRUE); + if(result) + return result; + } + + cmd = aprintf("%s%s%s", + data->set.str[STRING_CUSTOMREQUEST]? + data->set.str[STRING_CUSTOMREQUEST]: + (data->set.ftp_list_only?"NLST":"LIST"), + lstArg? " ": "", + lstArg? lstArg: ""); + + if(!cmd) { + free(lstArg); + return CURLE_OUT_OF_MEMORY; + } + + result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd); + + free(lstArg); + free(cmd); + + if(result) + return result; + + state(conn, FTP_LIST); + + return result; +} + +static CURLcode ftp_state_retr_prequote(struct connectdata *conn) +{ + /* We've sent the TYPE, now we must send the list of prequote strings */ + return ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE); +} + +static CURLcode ftp_state_stor_prequote(struct connectdata *conn) +{ + /* We've sent the TYPE, now we must send the list of prequote strings */ + return ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE); +} + +static CURLcode ftp_state_type(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct FTP *ftp = conn->data->req.protop; + struct Curl_easy *data = conn->data; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + /* If we have selected NOBODY and HEADER, it means that we only want file + information. Which in FTP can't be much more than the file size and + date. */ + if(data->set.opt_no_body && ftpc->file && + ftp_need_type(conn, data->set.prefer_ascii)) { + /* The SIZE command is _not_ RFC 959 specified, and therefore many servers + may not support it! It is however the only way we have to get a file's + size! */ + + ftp->transfer = FTPTRANSFER_INFO; + /* this means no actual transfer will be made */ + + /* Some servers return different sizes for different modes, and thus we + must set the proper type before we check the size */ + result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_TYPE); + if(result) + return result; + } + else + result = ftp_state_size(conn); + + return result; +} + +/* This is called after the CWD commands have been done in the beginning of + the DO phase */ +static CURLcode ftp_state_mdtm(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + /* Requested time of file or time-depended transfer? */ + if((data->set.get_filetime || data->set.timecondition) && ftpc->file) { + + /* we have requested to get the modified-time of the file, this is a white + spot as the MDTM is not mentioned in RFC959 */ + PPSENDF(&ftpc->pp, "MDTM %s", ftpc->file); + + state(conn, FTP_MDTM); + } + else + result = ftp_state_type(conn); + + return result; +} + + +/* This is called after the TYPE and possible quote commands have been sent */ +static CURLcode ftp_state_ul_setup(struct connectdata *conn, + bool sizechecked) +{ + CURLcode result = CURLE_OK; + struct FTP *ftp = conn->data->req.protop; + struct Curl_easy *data = conn->data; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if((data->state.resume_from && !sizechecked) || + ((data->state.resume_from > 0) && sizechecked)) { + /* we're about to continue the uploading of a file */ + /* 1. get already existing file's size. We use the SIZE command for this + which may not exist in the server! The SIZE command is not in + RFC959. */ + + /* 2. This used to set REST. But since we can do append, we + don't another ftp command. We just skip the source file + offset and then we APPEND the rest on the file instead */ + + /* 3. pass file-size number of bytes in the source file */ + /* 4. lower the infilesize counter */ + /* => transfer as usual */ + int seekerr = CURL_SEEKFUNC_OK; + + if(data->state.resume_from < 0) { + /* Got no given size to start from, figure it out */ + PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file); + state(conn, FTP_STOR_SIZE); + return result; + } + + /* enable append */ + data->set.ftp_append = TRUE; + + /* Let's read off the proper amount of bytes from the input. */ + if(conn->seek_func) { + Curl_set_in_callback(data, true); + seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, + SEEK_SET); + Curl_set_in_callback(data, false); + } + + if(seekerr != CURL_SEEKFUNC_OK) { + curl_off_t passed = 0; + if(seekerr != CURL_SEEKFUNC_CANTSEEK) { + failf(data, "Could not seek stream"); + return CURLE_FTP_COULDNT_USE_REST; + } + /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ + do { + size_t readthisamountnow = + (data->state.resume_from - passed > data->set.buffer_size) ? + (size_t)data->set.buffer_size : + curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = + data->state.fread_func(data->state.buffer, 1, readthisamountnow, + data->state.in); + + passed += actuallyread; + if((actuallyread == 0) || (actuallyread > readthisamountnow)) { + /* this checks for greater-than only to make sure that the + CURL_READFUNC_ABORT return code still aborts */ + failf(data, "Failed to read data"); + return CURLE_FTP_COULDNT_USE_REST; + } + } while(passed < data->state.resume_from); + } + /* now, decrease the size of the read */ + if(data->state.infilesize>0) { + data->state.infilesize -= data->state.resume_from; + + if(data->state.infilesize <= 0) { + infof(data, "File already completely uploaded\n"); + + /* no data to transfer */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + + /* Set ->transfer so that we won't get any error in + * ftp_done() because we didn't transfer anything! */ + ftp->transfer = FTPTRANSFER_NONE; + + state(conn, FTP_STOP); + return CURLE_OK; + } + } + /* we've passed, proceed as normal */ + } /* resume_from */ + + PPSENDF(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s", + ftpc->file); + + state(conn, FTP_STOR); + + return result; +} + +static CURLcode ftp_state_quote(struct connectdata *conn, + bool init, + ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + bool quote = FALSE; + struct curl_slist *item; + + switch(instate) { + case FTP_QUOTE: + default: + item = data->set.quote; + break; + case FTP_RETR_PREQUOTE: + case FTP_STOR_PREQUOTE: + item = data->set.prequote; + break; + case FTP_POSTQUOTE: + item = data->set.postquote; + break; + } + + /* + * This state uses: + * 'count1' to iterate over the commands to send + * 'count2' to store whether to allow commands to fail + */ + + if(init) + ftpc->count1 = 0; + else + ftpc->count1++; + + if(item) { + int i = 0; + + /* Skip count1 items in the linked list */ + while((i< ftpc->count1) && item) { + item = item->next; + i++; + } + if(item) { + char *cmd = item->data; + if(cmd[0] == '*') { + cmd++; + ftpc->count2 = 1; /* the sent command is allowed to fail */ + } + else + ftpc->count2 = 0; /* failure means cancel operation */ + + PPSENDF(&ftpc->pp, "%s", cmd); + state(conn, instate); + quote = TRUE; + } + } + + if(!quote) { + /* No more quote to send, continue to ... */ + switch(instate) { + case FTP_QUOTE: + default: + result = ftp_state_cwd(conn); + break; + case FTP_RETR_PREQUOTE: + if(ftp->transfer != FTPTRANSFER_BODY) + state(conn, FTP_STOP); + else { + if(ftpc->known_filesize != -1) { + Curl_pgrsSetDownloadSize(data, ftpc->known_filesize); + result = ftp_state_retr(conn, ftpc->known_filesize); + } + else { + if(data->set.ignorecl) { + /* This code is to support download of growing files. It prevents + the state machine from requesting the file size from the + server. With an unknown file size the download continues until + the server terminates it, otherwise the client stops if the + received byte count exceeds the reported file size. Set option + CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this behavior.*/ + PPSENDF(&ftpc->pp, "RETR %s", ftpc->file); + state(conn, FTP_RETR); + } + else { + PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file); + state(conn, FTP_RETR_SIZE); + } + } + } + break; + case FTP_STOR_PREQUOTE: + result = ftp_state_ul_setup(conn, FALSE); + break; + case FTP_POSTQUOTE: + break; + } + } + + return result; +} + +/* called from ftp_state_pasv_resp to switch to PASV in case of EPSV + problems */ +static CURLcode ftp_epsv_disable(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + + if(conn->bits.ipv6 && !(conn->bits.tunnel_proxy || conn->bits.socksproxy)) { + /* We can't disable EPSV when doing IPv6, so this is instead a fail */ + failf(conn->data, "Failed EPSV attempt, exiting\n"); + return CURLE_WEIRD_SERVER_REPLY; + } + + infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n"); + /* disable it for next transfer */ + conn->bits.ftp_use_epsv = FALSE; + conn->data->state.errorbuf = FALSE; /* allow error message to get + rewritten */ + PPSENDF(&conn->proto.ftpc.pp, "%s", "PASV"); + conn->proto.ftpc.count1++; + /* remain in/go to the FTP_PASV state */ + state(conn, FTP_PASV); + return result; +} + + +static char *control_address(struct connectdata *conn) +{ + /* Returns the control connection IP address. + If a proxy tunnel is used, returns the original host name instead, because + the effective control connection address is the proxy address, + not the ftp host. */ + if(conn->bits.tunnel_proxy || conn->bits.socksproxy) + return conn->host.name; + + return conn->ip_addr_str; +} + +static CURLcode ftp_state_pasv_resp(struct connectdata *conn, + int ftpcode) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + CURLcode result; + struct Curl_easy *data = conn->data; + struct Curl_dns_entry *addr = NULL; + int rc; + unsigned short connectport; /* the local port connect() should use! */ + char *str = &data->state.buffer[4]; /* start on the first letter */ + + /* if we come here again, make sure the former name is cleared */ + Curl_safefree(ftpc->newhost); + + if((ftpc->count1 == 0) && + (ftpcode == 229)) { + /* positive EPSV response */ + char *ptr = strchr(str, '('); + if(ptr) { + unsigned int num; + char separator[4]; + ptr++; + if(5 == sscanf(ptr, "%c%c%c%u%c", + &separator[0], + &separator[1], + &separator[2], + &num, + &separator[3])) { + const char sep1 = separator[0]; + int i; + + /* The four separators should be identical, or else this is an oddly + formatted reply and we bail out immediately. */ + for(i = 1; i<4; i++) { + if(separator[i] != sep1) { + ptr = NULL; /* set to NULL to signal error */ + break; + } + } + if(num > 0xffff) { + failf(data, "Illegal port number in EPSV reply"); + return CURLE_FTP_WEIRD_PASV_REPLY; + } + if(ptr) { + ftpc->newport = (unsigned short)(num & 0xffff); + ftpc->newhost = strdup(control_address(conn)); + if(!ftpc->newhost) + return CURLE_OUT_OF_MEMORY; + } + } + else + ptr = NULL; + } + if(!ptr) { + failf(data, "Weirdly formatted EPSV reply"); + return CURLE_FTP_WEIRD_PASV_REPLY; + } + } + else if((ftpc->count1 == 1) && + (ftpcode == 227)) { + /* positive PASV response */ + unsigned int ip[4]; + unsigned int port[2]; + + /* + * Scan for a sequence of six comma-separated numbers and use them as + * IP+port indicators. + * + * Found reply-strings include: + * "227 Entering Passive Mode (127,0,0,1,4,51)" + * "227 Data transfer will passively listen to 127,0,0,1,4,51" + * "227 Entering passive mode. 127,0,0,1,4,51" + */ + while(*str) { + if(6 == sscanf(str, "%u,%u,%u,%u,%u,%u", + &ip[0], &ip[1], &ip[2], &ip[3], + &port[0], &port[1])) + break; + str++; + } + + if(!*str || (ip[0] > 255) || (ip[1] > 255) || (ip[2] > 255) || + (ip[3] > 255) || (port[0] > 255) || (port[1] > 255) ) { + failf(data, "Couldn't interpret the 227-response"); + return CURLE_FTP_WEIRD_227_FORMAT; + } + + /* we got OK from server */ + if(data->set.ftp_skip_ip) { + /* told to ignore the remotely given IP but instead use the host we used + for the control connection */ + infof(data, "Skip %u.%u.%u.%u for data connection, re-use %s instead\n", + ip[0], ip[1], ip[2], ip[3], + conn->host.name); + ftpc->newhost = strdup(control_address(conn)); + } + else + ftpc->newhost = aprintf("%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); + + if(!ftpc->newhost) + return CURLE_OUT_OF_MEMORY; + + ftpc->newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff); + } + else if(ftpc->count1 == 0) { + /* EPSV failed, move on to PASV */ + return ftp_epsv_disable(conn); + } + else { + failf(data, "Bad PASV/EPSV response: %03d", ftpcode); + return CURLE_FTP_WEIRD_PASV_REPLY; + } + + if(conn->bits.proxy) { + /* + * This connection uses a proxy and we need to connect to the proxy again + * here. We don't want to rely on a former host lookup that might've + * expired now, instead we remake the lookup here and now! + */ + const char * const host_name = conn->bits.socksproxy ? + conn->socks_proxy.host.name : conn->http_proxy.host.name; + rc = Curl_resolv(conn, host_name, (int)conn->port, FALSE, &addr); + if(rc == CURLRESOLV_PENDING) + /* BLOCKING, ignores the return code but 'addr' will be NULL in + case of failure */ + (void)Curl_resolver_wait_resolv(conn, &addr); + + connectport = + (unsigned short)conn->port; /* we connect to the proxy's port */ + + if(!addr) { + failf(data, "Can't resolve proxy host %s:%hu", host_name, connectport); + return CURLE_COULDNT_RESOLVE_PROXY; + } + } + else { + /* normal, direct, ftp connection */ + rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr); + if(rc == CURLRESOLV_PENDING) + /* BLOCKING */ + (void)Curl_resolver_wait_resolv(conn, &addr); + + connectport = ftpc->newport; /* we connect to the remote port */ + + if(!addr) { + failf(data, "Can't resolve new host %s:%hu", ftpc->newhost, connectport); + return CURLE_FTP_CANT_GET_HOST; + } + } + + conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE; + result = Curl_connecthost(conn, addr); + + if(result) { + Curl_resolv_unlock(data, addr); /* we're done using this address */ + if(ftpc->count1 == 0 && ftpcode == 229) + return ftp_epsv_disable(conn); + + return result; + } + + + /* + * When this is used from the multi interface, this might've returned with + * the 'connected' set to FALSE and thus we are now awaiting a non-blocking + * connect to connect. + */ + + if(data->set.verbose) + /* this just dumps information about this second connection */ + ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport); + + Curl_resolv_unlock(data, addr); /* we're done using this address */ + + Curl_safefree(conn->secondaryhostname); + conn->secondary_port = ftpc->newport; + conn->secondaryhostname = strdup(ftpc->newhost); + if(!conn->secondaryhostname) + return CURLE_OUT_OF_MEMORY; + + conn->bits.do_more = TRUE; + state(conn, FTP_STOP); /* this phase is completed */ + + return result; +} + +static CURLcode ftp_state_port_resp(struct connectdata *conn, + int ftpcode) +{ + struct Curl_easy *data = conn->data; + struct ftp_conn *ftpc = &conn->proto.ftpc; + ftpport fcmd = (ftpport)ftpc->count1; + CURLcode result = CURLE_OK; + + /* The FTP spec tells a positive response should have code 200. + Be more permissive here to tolerate deviant servers. */ + if(ftpcode / 100 != 2) { + /* the command failed */ + + if(EPRT == fcmd) { + infof(data, "disabling EPRT usage\n"); + conn->bits.ftp_use_eprt = FALSE; + } + fcmd++; + + if(fcmd == DONE) { + failf(data, "Failed to do PORT"); + result = CURLE_FTP_PORT_FAILED; + } + else + /* try next */ + result = ftp_state_use_port(conn, fcmd); + } + else { + infof(data, "Connect data stream actively\n"); + state(conn, FTP_STOP); /* end of DO phase */ + result = ftp_dophase_done(conn, FALSE); + } + + return result; +} + +static CURLcode ftp_state_mdtm_resp(struct connectdata *conn, + int ftpcode) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + switch(ftpcode) { + case 213: + { + /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the + last .sss part is optional and means fractions of a second */ + int year, month, day, hour, minute, second; + if(6 == sscanf(&data->state.buffer[4], "%04d%02d%02d%02d%02d%02d", + &year, &month, &day, &hour, &minute, &second)) { + /* we have a time, reformat it */ + char timebuf[24]; + time_t secs = time(NULL); + + msnprintf(timebuf, sizeof(timebuf), + "%04d%02d%02d %02d:%02d:%02d GMT", + year, month, day, hour, minute, second); + /* now, convert this into a time() value: */ + data->info.filetime = curl_getdate(timebuf, &secs); + } + +#ifdef CURL_FTP_HTTPSTYLE_HEAD + /* If we asked for a time of the file and we actually got one as well, + we "emulate" a HTTP-style header in our output. */ + + if(data->set.opt_no_body && + ftpc->file && + data->set.get_filetime && + (data->info.filetime >= 0) ) { + char headerbuf[128]; + time_t filetime = data->info.filetime; + struct tm buffer; + const struct tm *tm = &buffer; + + result = Curl_gmtime(filetime, &buffer); + if(result) + return result; + + /* format: "Tue, 15 Nov 1994 12:45:26" */ + msnprintf(headerbuf, sizeof(headerbuf), + "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", + Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], + tm->tm_mday, + Curl_month[tm->tm_mon], + tm->tm_year + 1900, + tm->tm_hour, + tm->tm_min, + tm->tm_sec); + result = Curl_client_write(conn, CLIENTWRITE_BOTH, headerbuf, 0); + if(result) + return result; + } /* end of a ridiculous amount of conditionals */ +#endif + } + break; + default: + infof(data, "unsupported MDTM reply format\n"); + break; + case 550: /* "No such file or directory" */ + failf(data, "Given file does not exist"); + result = CURLE_FTP_COULDNT_RETR_FILE; + break; + } + + if(data->set.timecondition) { + if((data->info.filetime > 0) && (data->set.timevalue > 0)) { + switch(data->set.timecondition) { + case CURL_TIMECOND_IFMODSINCE: + default: + if(data->info.filetime <= data->set.timevalue) { + infof(data, "The requested document is not new enough\n"); + ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */ + data->info.timecond = TRUE; + state(conn, FTP_STOP); + return CURLE_OK; + } + break; + case CURL_TIMECOND_IFUNMODSINCE: + if(data->info.filetime > data->set.timevalue) { + infof(data, "The requested document is not old enough\n"); + ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */ + data->info.timecond = TRUE; + state(conn, FTP_STOP); + return CURLE_OK; + } + break; + } /* switch */ + } + else { + infof(data, "Skipping time comparison\n"); + } + } + + if(!result) + result = ftp_state_type(conn); + + return result; +} + +static CURLcode ftp_state_type_resp(struct connectdata *conn, + int ftpcode, + ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + if(ftpcode/100 != 2) { + /* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a + successful 'TYPE I'. While that is not as RFC959 says, it is still a + positive response code and we allow that. */ + failf(data, "Couldn't set desired mode"); + return CURLE_FTP_COULDNT_SET_TYPE; + } + if(ftpcode != 200) + infof(data, "Got a %03d response code instead of the assumed 200\n", + ftpcode); + + if(instate == FTP_TYPE) + result = ftp_state_size(conn); + else if(instate == FTP_LIST_TYPE) + result = ftp_state_list(conn); + else if(instate == FTP_RETR_TYPE) + result = ftp_state_retr_prequote(conn); + else if(instate == FTP_STOR_TYPE) + result = ftp_state_stor_prequote(conn); + + return result; +} + +static CURLcode ftp_state_retr(struct connectdata *conn, + curl_off_t filesize) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if(data->set.max_filesize && (filesize > data->set.max_filesize)) { + failf(data, "Maximum file size exceeded"); + return CURLE_FILESIZE_EXCEEDED; + } + ftp->downloadsize = filesize; + + if(data->state.resume_from) { + /* We always (attempt to) get the size of downloads, so it is done before + this even when not doing resumes. */ + if(filesize == -1) { + infof(data, "ftp server doesn't support SIZE\n"); + /* We couldn't get the size and therefore we can't know if there really + is a part of the file left to get, although the server will just + close the connection when we start the connection so it won't cause + us any harm, just not make us exit as nicely. */ + } + else { + /* We got a file size report, so we check that there actually is a + part of the file left to get, or else we go home. */ + if(data->state.resume_from< 0) { + /* We're supposed to download the last abs(from) bytes */ + if(filesize < -data->state.resume_from) { + failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T + ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, filesize); + return CURLE_BAD_DOWNLOAD_RESUME; + } + /* convert to size to download */ + ftp->downloadsize = -data->state.resume_from; + /* download from where? */ + data->state.resume_from = filesize - ftp->downloadsize; + } + else { + if(filesize < data->state.resume_from) { + failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T + ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, filesize); + return CURLE_BAD_DOWNLOAD_RESUME; + } + /* Now store the number of bytes we are expected to download */ + ftp->downloadsize = filesize-data->state.resume_from; + } + } + + if(ftp->downloadsize == 0) { + /* no data to transfer */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + infof(data, "File already completely downloaded\n"); + + /* Set ->transfer so that we won't get any error in ftp_done() + * because we didn't transfer the any file */ + ftp->transfer = FTPTRANSFER_NONE; + state(conn, FTP_STOP); + return CURLE_OK; + } + + /* Set resume file transfer offset */ + infof(data, "Instructs server to resume from offset %" + CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from); + + PPSENDF(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T, + data->state.resume_from); + + state(conn, FTP_RETR_REST); + } + else { + /* no resume */ + PPSENDF(&ftpc->pp, "RETR %s", ftpc->file); + state(conn, FTP_RETR); + } + + return result; +} + +static CURLcode ftp_state_size_resp(struct connectdata *conn, + int ftpcode, + ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + curl_off_t filesize = -1; + char *buf = data->state.buffer; + + /* get the size from the ascii string: */ + if(ftpcode == 213) + /* ignores parsing errors, which will make the size remain unknown */ + (void)curlx_strtoofft(buf + 4, NULL, 0, &filesize); + + if(instate == FTP_SIZE) { +#ifdef CURL_FTP_HTTPSTYLE_HEAD + if(-1 != filesize) { + char clbuf[128]; + msnprintf(clbuf, sizeof(clbuf), + "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize); + result = Curl_client_write(conn, CLIENTWRITE_BOTH, clbuf, 0); + if(result) + return result; + } +#endif + Curl_pgrsSetDownloadSize(data, filesize); + result = ftp_state_rest(conn); + } + else if(instate == FTP_RETR_SIZE) { + Curl_pgrsSetDownloadSize(data, filesize); + result = ftp_state_retr(conn, filesize); + } + else if(instate == FTP_STOR_SIZE) { + data->state.resume_from = filesize; + result = ftp_state_ul_setup(conn, TRUE); + } + + return result; +} + +static CURLcode ftp_state_rest_resp(struct connectdata *conn, + int ftpcode, + ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + switch(instate) { + case FTP_REST: + default: +#ifdef CURL_FTP_HTTPSTYLE_HEAD + if(ftpcode == 350) { + char buffer[24]= { "Accept-ranges: bytes\r\n" }; + result = Curl_client_write(conn, CLIENTWRITE_BOTH, buffer, 0); + if(result) + return result; + } +#endif + result = ftp_state_prepare_transfer(conn); + break; + + case FTP_RETR_REST: + if(ftpcode != 350) { + failf(conn->data, "Couldn't use REST"); + result = CURLE_FTP_COULDNT_USE_REST; + } + else { + PPSENDF(&ftpc->pp, "RETR %s", ftpc->file); + state(conn, FTP_RETR); + } + break; + } + + return result; +} + +static CURLcode ftp_state_stor_resp(struct connectdata *conn, + int ftpcode, ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + if(ftpcode >= 400) { + failf(data, "Failed FTP upload: %0d", ftpcode); + state(conn, FTP_STOP); + /* oops, we never close the sockets! */ + return CURLE_UPLOAD_FAILED; + } + + conn->proto.ftpc.state_saved = instate; + + /* PORT means we are now awaiting the server to connect to us. */ + if(data->set.ftp_use_port) { + bool connected; + + state(conn, FTP_STOP); /* no longer in STOR state */ + + result = AllowServerConnect(conn, &connected); + if(result) + return result; + + if(!connected) { + struct ftp_conn *ftpc = &conn->proto.ftpc; + infof(data, "Data conn was not available immediately\n"); + ftpc->wait_data_conn = TRUE; + } + + return CURLE_OK; + } + return InitiateTransfer(conn); +} + +/* for LIST and RETR responses */ +static CURLcode ftp_state_get_resp(struct connectdata *conn, + int ftpcode, + ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + + if((ftpcode == 150) || (ftpcode == 125)) { + + /* + A; + 150 Opening BINARY mode data connection for /etc/passwd (2241 + bytes). (ok, the file is being transferred) + + B: + 150 Opening ASCII mode data connection for /bin/ls + + C: + 150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes). + + D: + 150 Opening ASCII mode data connection for [file] (0.0.0.0,0) (545 bytes) + + E: + 125 Data connection already open; Transfer starting. */ + + curl_off_t size = -1; /* default unknown size */ + + + /* + * It appears that there are FTP-servers that return size 0 for files when + * SIZE is used on the file while being in BINARY mode. To work around + * that (stupid) behavior, we attempt to parse the RETR response even if + * the SIZE returned size zero. + * + * Debugging help from Salvatore Sorrentino on February 26, 2003. + */ + + if((instate != FTP_LIST) && + !data->set.prefer_ascii && + (ftp->downloadsize < 1)) { + /* + * It seems directory listings either don't show the size or very + * often uses size 0 anyway. ASCII transfers may very well turn out + * that the transferred amount of data is not the same as this line + * tells, why using this number in those cases only confuses us. + * + * Example D above makes this parsing a little tricky */ + char *bytes; + char *buf = data->state.buffer; + bytes = strstr(buf, " bytes"); + if(bytes) { + long in = (long)(--bytes-buf); + /* this is a hint there is size information in there! ;-) */ + while(--in) { + /* scan for the left parenthesis and break there */ + if('(' == *bytes) + break; + /* skip only digits */ + if(!ISDIGIT(*bytes)) { + bytes = NULL; + break; + } + /* one more estep backwards */ + bytes--; + } + /* if we have nothing but digits: */ + if(bytes++) { + /* get the number! */ + (void)curlx_strtoofft(bytes, NULL, 0, &size); + } + } + } + else if(ftp->downloadsize > -1) + size = ftp->downloadsize; + + if(size > data->req.maxdownload && data->req.maxdownload > 0) + size = data->req.size = data->req.maxdownload; + else if((instate != FTP_LIST) && (data->set.prefer_ascii)) + size = -1; /* kludge for servers that understate ASCII mode file size */ + + infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T "\n", + data->req.maxdownload); + + if(instate != FTP_LIST) + infof(data, "Getting file with size: %" CURL_FORMAT_CURL_OFF_T "\n", + size); + + /* FTP download: */ + conn->proto.ftpc.state_saved = instate; + conn->proto.ftpc.retr_size_saved = size; + + if(data->set.ftp_use_port) { + bool connected; + + result = AllowServerConnect(conn, &connected); + if(result) + return result; + + if(!connected) { + struct ftp_conn *ftpc = &conn->proto.ftpc; + infof(data, "Data conn was not available immediately\n"); + state(conn, FTP_STOP); + ftpc->wait_data_conn = TRUE; + } + } + else + return InitiateTransfer(conn); + } + else { + if((instate == FTP_LIST) && (ftpcode == 450)) { + /* simply no matching files in the dir listing */ + ftp->transfer = FTPTRANSFER_NONE; /* don't download anything */ + state(conn, FTP_STOP); /* this phase is over */ + } + else { + failf(data, "RETR response: %03d", ftpcode); + return instate == FTP_RETR && ftpcode == 550? + CURLE_REMOTE_FILE_NOT_FOUND: + CURLE_FTP_COULDNT_RETR_FILE; + } + } + + return result; +} + +/* after USER, PASS and ACCT */ +static CURLcode ftp_state_loggedin(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + + if(conn->ssl[FIRSTSOCKET].use) { + /* PBSZ = PROTECTION BUFFER SIZE. + + The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says: + + Specifically, the PROT command MUST be preceded by a PBSZ + command and a PBSZ command MUST be preceded by a successful + security data exchange (the TLS negotiation in this case) + + ... (and on page 8): + + Thus the PBSZ command must still be issued, but must have a + parameter of '0' to indicate that no buffering is taking place + and the data connection should not be encapsulated. + */ + PPSENDF(&conn->proto.ftpc.pp, "PBSZ %d", 0); + state(conn, FTP_PBSZ); + } + else { + result = ftp_state_pwd(conn); + } + return result; +} + +/* for USER and PASS responses */ +static CURLcode ftp_state_user_resp(struct connectdata *conn, + int ftpcode, + ftpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + (void)instate; /* no use for this yet */ + + /* some need password anyway, and others just return 2xx ignored */ + if((ftpcode == 331) && (ftpc->state == FTP_USER)) { + /* 331 Password required for ... + (the server requires to send the user's password too) */ + PPSENDF(&ftpc->pp, "PASS %s", ftp->passwd?ftp->passwd:""); + state(conn, FTP_PASS); + } + else if(ftpcode/100 == 2) { + /* 230 User ... logged in. + (the user logged in with or without password) */ + result = ftp_state_loggedin(conn); + } + else if(ftpcode == 332) { + if(data->set.str[STRING_FTP_ACCOUNT]) { + PPSENDF(&ftpc->pp, "ACCT %s", data->set.str[STRING_FTP_ACCOUNT]); + state(conn, FTP_ACCT); + } + else { + failf(data, "ACCT requested but none available"); + result = CURLE_LOGIN_DENIED; + } + } + else { + /* All other response codes, like: + + 530 User ... access denied + (the server denies to log the specified user) */ + + if(conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] && + !conn->data->state.ftp_trying_alternative) { + /* Ok, USER failed. Let's try the supplied command. */ + PPSENDF(&conn->proto.ftpc.pp, "%s", + conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]); + conn->data->state.ftp_trying_alternative = TRUE; + state(conn, FTP_USER); + result = CURLE_OK; + } + else { + failf(data, "Access denied: %03d", ftpcode); + result = CURLE_LOGIN_DENIED; + } + } + return result; +} + +/* for ACCT response */ +static CURLcode ftp_state_acct_resp(struct connectdata *conn, + int ftpcode) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + if(ftpcode != 230) { + failf(data, "ACCT rejected by server: %03d", ftpcode); + result = CURLE_FTP_WEIRD_PASS_REPLY; /* FIX */ + } + else + result = ftp_state_loggedin(conn); + + return result; +} + + +static CURLcode ftp_statemach_act(struct connectdata *conn) +{ + CURLcode result; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + struct Curl_easy *data = conn->data; + int ftpcode; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + static const char ftpauth[][4] = { "SSL", "TLS" }; + size_t nread = 0; + + if(pp->sendleft) + return Curl_pp_flushsend(pp); + + result = ftp_readresp(sock, pp, &ftpcode, &nread); + if(result) + return result; + + if(ftpcode) { + /* we have now received a full FTP server response */ + switch(ftpc->state) { + case FTP_WAIT220: + if(ftpcode == 230) + /* 230 User logged in - already! */ + return ftp_state_user_resp(conn, ftpcode, ftpc->state); + else if(ftpcode != 220) { + failf(data, "Got a %03d ftp-server response when 220 was expected", + ftpcode); + return CURLE_WEIRD_SERVER_REPLY; + } + + /* We have received a 220 response fine, now we proceed. */ +#ifdef HAVE_GSSAPI + if(data->set.krb) { + /* If not anonymous login, try a secure login. Note that this + procedure is still BLOCKING. */ + + Curl_sec_request_prot(conn, "private"); + /* We set private first as default, in case the line below fails to + set a valid level */ + Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]); + + if(Curl_sec_login(conn)) + infof(data, "Logging in with password in cleartext!\n"); + else + infof(data, "Authentication successful\n"); + } +#endif + + if(data->set.use_ssl && + (!conn->ssl[FIRSTSOCKET].use || + (conn->bits.proxy_ssl_connected[FIRSTSOCKET] && + !conn->proxy_ssl[FIRSTSOCKET].use))) { + /* We don't have a SSL/TLS connection yet, but FTPS is + requested. Try a FTPS connection now */ + + ftpc->count3 = 0; + switch(data->set.ftpsslauth) { + case CURLFTPAUTH_DEFAULT: + case CURLFTPAUTH_SSL: + ftpc->count2 = 1; /* add one to get next */ + ftpc->count1 = 0; + break; + case CURLFTPAUTH_TLS: + ftpc->count2 = -1; /* subtract one to get next */ + ftpc->count1 = 1; + break; + default: + failf(data, "unsupported parameter to CURLOPT_FTPSSLAUTH: %d", + (int)data->set.ftpsslauth); + return CURLE_UNKNOWN_OPTION; /* we don't know what to do */ + } + PPSENDF(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]); + state(conn, FTP_AUTH); + } + else { + result = ftp_state_user(conn); + if(result) + return result; + } + + break; + + case FTP_AUTH: + /* we have gotten the response to a previous AUTH command */ + + /* RFC2228 (page 5) says: + * + * If the server is willing to accept the named security mechanism, + * and does not require any security data, it must respond with + * reply code 234/334. + */ + + if((ftpcode == 234) || (ftpcode == 334)) { + /* Curl_ssl_connect is BLOCKING */ + result = Curl_ssl_connect(conn, FIRSTSOCKET); + if(!result) { + conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */ + result = ftp_state_user(conn); + } + } + else if(ftpc->count3 < 1) { + ftpc->count3++; + ftpc->count1 += ftpc->count2; /* get next attempt */ + result = Curl_pp_sendf(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]); + /* remain in this same state */ + } + else { + if(data->set.use_ssl > CURLUSESSL_TRY) + /* we failed and CURLUSESSL_CONTROL or CURLUSESSL_ALL is set */ + result = CURLE_USE_SSL_FAILED; + else + /* ignore the failure and continue */ + result = ftp_state_user(conn); + } + + if(result) + return result; + break; + + case FTP_USER: + case FTP_PASS: + result = ftp_state_user_resp(conn, ftpcode, ftpc->state); + break; + + case FTP_ACCT: + result = ftp_state_acct_resp(conn, ftpcode); + break; + + case FTP_PBSZ: + PPSENDF(&ftpc->pp, "PROT %c", + data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P'); + state(conn, FTP_PROT); + + break; + + case FTP_PROT: + if(ftpcode/100 == 2) + /* We have enabled SSL for the data connection! */ + conn->bits.ftp_use_data_ssl = + (data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE; + /* FTP servers typically responds with 500 if they decide to reject + our 'P' request */ + else if(data->set.use_ssl > CURLUSESSL_CONTROL) + /* we failed and bails out */ + return CURLE_USE_SSL_FAILED; + + if(data->set.ftp_ccc) { + /* CCC - Clear Command Channel + */ + PPSENDF(&ftpc->pp, "%s", "CCC"); + state(conn, FTP_CCC); + } + else { + result = ftp_state_pwd(conn); + if(result) + return result; + } + break; + + case FTP_CCC: + if(ftpcode < 500) { + /* First shut down the SSL layer (note: this call will block) */ + result = Curl_ssl_shutdown(conn, FIRSTSOCKET); + + if(result) { + failf(conn->data, "Failed to clear the command channel (CCC)"); + return result; + } + } + + /* Then continue as normal */ + result = ftp_state_pwd(conn); + if(result) + return result; + break; + + case FTP_PWD: + if(ftpcode == 257) { + char *ptr = &data->state.buffer[4]; /* start on the first letter */ + const size_t buf_size = data->set.buffer_size; + char *dir; + bool entry_extracted = FALSE; + + dir = malloc(nread + 1); + if(!dir) + return CURLE_OUT_OF_MEMORY; + + /* Reply format is like + 257[rubbish]"" and the + RFC959 says + + The directory name can contain any character; embedded + double-quotes should be escaped by double-quotes (the + "quote-doubling" convention). + */ + + /* scan for the first double-quote for non-standard responses */ + while(ptr < &data->state.buffer[buf_size] + && *ptr != '\n' && *ptr != '\0' && *ptr != '"') + ptr++; + + if('\"' == *ptr) { + /* it started good */ + char *store; + ptr++; + for(store = dir; *ptr;) { + if('\"' == *ptr) { + if('\"' == ptr[1]) { + /* "quote-doubling" */ + *store = ptr[1]; + ptr++; + } + else { + /* end of path */ + entry_extracted = TRUE; + break; /* get out of this loop */ + } + } + else + *store = *ptr; + store++; + ptr++; + } + *store = '\0'; /* zero terminate */ + } + if(entry_extracted) { + /* If the path name does not look like an absolute path (i.e.: it + does not start with a '/'), we probably need some server-dependent + adjustments. For example, this is the case when connecting to + an OS400 FTP server: this server supports two name syntaxes, + the default one being incompatible with standard paths. In + addition, this server switches automatically to the regular path + syntax when one is encountered in a command: this results in + having an entrypath in the wrong syntax when later used in CWD. + The method used here is to check the server OS: we do it only + if the path name looks strange to minimize overhead on other + systems. */ + + if(!ftpc->server_os && dir[0] != '/') { + + result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST"); + if(result) { + free(dir); + return result; + } + Curl_safefree(ftpc->entrypath); + ftpc->entrypath = dir; /* remember this */ + infof(data, "Entry path is '%s'\n", ftpc->entrypath); + /* also save it where getinfo can access it: */ + data->state.most_recent_ftp_entrypath = ftpc->entrypath; + state(conn, FTP_SYST); + break; + } + + Curl_safefree(ftpc->entrypath); + ftpc->entrypath = dir; /* remember this */ + infof(data, "Entry path is '%s'\n", ftpc->entrypath); + /* also save it where getinfo can access it: */ + data->state.most_recent_ftp_entrypath = ftpc->entrypath; + } + else { + /* couldn't get the path */ + free(dir); + infof(data, "Failed to figure out path\n"); + } + } + state(conn, FTP_STOP); /* we are done with the CONNECT phase! */ + DEBUGF(infof(data, "protocol connect phase DONE\n")); + break; + + case FTP_SYST: + if(ftpcode == 215) { + char *ptr = &data->state.buffer[4]; /* start on the first letter */ + char *os; + char *store; + + os = malloc(nread + 1); + if(!os) + return CURLE_OUT_OF_MEMORY; + + /* Reply format is like + 215 + */ + while(*ptr == ' ') + ptr++; + for(store = os; *ptr && *ptr != ' ';) + *store++ = *ptr++; + *store = '\0'; /* zero terminate */ + + /* Check for special servers here. */ + + if(strcasecompare(os, "OS/400")) { + /* Force OS400 name format 1. */ + result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1"); + if(result) { + free(os); + return result; + } + /* remember target server OS */ + Curl_safefree(ftpc->server_os); + ftpc->server_os = os; + state(conn, FTP_NAMEFMT); + break; + } + /* Nothing special for the target server. */ + /* remember target server OS */ + Curl_safefree(ftpc->server_os); + ftpc->server_os = os; + } + else { + /* Cannot identify server OS. Continue anyway and cross fingers. */ + } + + state(conn, FTP_STOP); /* we are done with the CONNECT phase! */ + DEBUGF(infof(data, "protocol connect phase DONE\n")); + break; + + case FTP_NAMEFMT: + if(ftpcode == 250) { + /* Name format change successful: reload initial path. */ + ftp_state_pwd(conn); + break; + } + + state(conn, FTP_STOP); /* we are done with the CONNECT phase! */ + DEBUGF(infof(data, "protocol connect phase DONE\n")); + break; + + case FTP_QUOTE: + case FTP_POSTQUOTE: + case FTP_RETR_PREQUOTE: + case FTP_STOR_PREQUOTE: + if((ftpcode >= 400) && !ftpc->count2) { + /* failure response code, and not allowed to fail */ + failf(conn->data, "QUOT command failed with %03d", ftpcode); + return CURLE_QUOTE_ERROR; + } + result = ftp_state_quote(conn, FALSE, ftpc->state); + if(result) + return result; + + break; + + case FTP_CWD: + if(ftpcode/100 != 2) { + /* failure to CWD there */ + if(conn->data->set.ftp_create_missing_dirs && + ftpc->cwdcount && !ftpc->count2) { + /* try making it */ + ftpc->count2++; /* counter to prevent CWD-MKD loops */ + PPSENDF(&ftpc->pp, "MKD %s", ftpc->dirs[ftpc->cwdcount - 1]); + state(conn, FTP_MKD); + } + else { + /* return failure */ + failf(data, "Server denied you to change to the given directory"); + ftpc->cwdfail = TRUE; /* don't remember this path as we failed + to enter it */ + return CURLE_REMOTE_ACCESS_DENIED; + } + } + else { + /* success */ + ftpc->count2 = 0; + if(++ftpc->cwdcount <= ftpc->dirdepth) { + /* send next CWD */ + PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->cwdcount - 1]); + } + else { + result = ftp_state_mdtm(conn); + if(result) + return result; + } + } + break; + + case FTP_MKD: + if((ftpcode/100 != 2) && !ftpc->count3--) { + /* failure to MKD the dir */ + failf(data, "Failed to MKD dir: %03d", ftpcode); + return CURLE_REMOTE_ACCESS_DENIED; + } + state(conn, FTP_CWD); + /* send CWD */ + PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->cwdcount - 1]); + break; + + case FTP_MDTM: + result = ftp_state_mdtm_resp(conn, ftpcode); + break; + + case FTP_TYPE: + case FTP_LIST_TYPE: + case FTP_RETR_TYPE: + case FTP_STOR_TYPE: + result = ftp_state_type_resp(conn, ftpcode, ftpc->state); + break; + + case FTP_SIZE: + case FTP_RETR_SIZE: + case FTP_STOR_SIZE: + result = ftp_state_size_resp(conn, ftpcode, ftpc->state); + break; + + case FTP_REST: + case FTP_RETR_REST: + result = ftp_state_rest_resp(conn, ftpcode, ftpc->state); + break; + + case FTP_PRET: + if(ftpcode != 200) { + /* there only is this one standard OK return code. */ + failf(data, "PRET command not accepted: %03d", ftpcode); + return CURLE_FTP_PRET_FAILED; + } + result = ftp_state_use_pasv(conn); + break; + + case FTP_PASV: + result = ftp_state_pasv_resp(conn, ftpcode); + break; + + case FTP_PORT: + result = ftp_state_port_resp(conn, ftpcode); + break; + + case FTP_LIST: + case FTP_RETR: + result = ftp_state_get_resp(conn, ftpcode, ftpc->state); + break; + + case FTP_STOR: + result = ftp_state_stor_resp(conn, ftpcode, ftpc->state); + break; + + case FTP_QUIT: + /* fallthrough, just stop! */ + default: + /* internal error */ + state(conn, FTP_STOP); + break; + } + } /* if(ftpcode) */ + + return result; +} + + +/* called repeatedly until done from multi.c */ +static CURLcode ftp_multi_statemach(struct connectdata *conn, + bool *done) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE, FALSE); + + /* Check for the state outside of the Curl_socket_check() return code checks + since at times we are in fact already in this state when this function + gets called. */ + *done = (ftpc->state == FTP_STOP) ? TRUE : FALSE; + + return result; +} + +static CURLcode ftp_block_statemach(struct connectdata *conn) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + CURLcode result = CURLE_OK; + + while(ftpc->state != FTP_STOP) { + result = Curl_pp_statemach(pp, TRUE, TRUE /* disconnecting */); + if(result) + break; + } + + return result; +} + +/* + * ftp_connect() should do everything that is to be considered a part of + * the connection phase. + * + * The variable 'done' points to will be TRUE if the protocol-layer connect + * phase is done when this function returns, or FALSE if not. + * + */ +static CURLcode ftp_connect(struct connectdata *conn, + bool *done) /* see description above */ +{ + CURLcode result; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + + *done = FALSE; /* default to not done yet */ + + /* We always support persistent connections on ftp */ + connkeep(conn, "FTP default"); + + pp->response_time = RESP_TIMEOUT; /* set default response time-out */ + pp->statemach_act = ftp_statemach_act; + pp->endofresp = ftp_endofresp; + pp->conn = conn; + + if(conn->handler->flags & PROTOPT_SSL) { + /* BLOCKING */ + result = Curl_ssl_connect(conn, FIRSTSOCKET); + if(result) + return result; + } + + Curl_pp_init(pp); /* init the generic pingpong data */ + + /* When we connect, we start in the state where we await the 220 + response */ + state(conn, FTP_WAIT220); + + result = ftp_multi_statemach(conn, done); + + return result; +} + +/*********************************************************************** + * + * ftp_done() + * + * The DONE function. This does what needs to be done after a single DO has + * performed. + * + * Input argument is already checked for validity. + */ +static CURLcode ftp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + struct Curl_easy *data = conn->data; + struct FTP *ftp = data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + ssize_t nread; + int ftpcode; + CURLcode result = CURLE_OK; + char *path = NULL; + + if(!ftp) + return CURLE_OK; + + switch(status) { + case CURLE_BAD_DOWNLOAD_RESUME: + case CURLE_FTP_WEIRD_PASV_REPLY: + case CURLE_FTP_PORT_FAILED: + case CURLE_FTP_ACCEPT_FAILED: + case CURLE_FTP_ACCEPT_TIMEOUT: + case CURLE_FTP_COULDNT_SET_TYPE: + case CURLE_FTP_COULDNT_RETR_FILE: + case CURLE_PARTIAL_FILE: + case CURLE_UPLOAD_FAILED: + case CURLE_REMOTE_ACCESS_DENIED: + case CURLE_FILESIZE_EXCEEDED: + case CURLE_REMOTE_FILE_NOT_FOUND: + case CURLE_WRITE_ERROR: + /* the connection stays alive fine even though this happened */ + /* fall-through */ + case CURLE_OK: /* doesn't affect the control connection's status */ + if(!premature) + break; + + /* until we cope better with prematurely ended requests, let them + * fallback as if in complete failure */ + /* FALLTHROUGH */ + default: /* by default, an error means the control connection is + wedged and should not be used anymore */ + ftpc->ctl_valid = FALSE; + ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the + current path, as this connection is going */ + connclose(conn, "FTP ended with bad error code"); + result = status; /* use the already set error code */ + break; + } + + /* now store a copy of the directory we are in */ + free(ftpc->prevpath); + + if(data->state.wildcardmatch) { + if(data->set.chunk_end && ftpc->file) { + Curl_set_in_callback(data, true); + data->set.chunk_end(data->wildcard.customptr); + Curl_set_in_callback(data, false); + } + ftpc->known_filesize = -1; + } + + if(!result) + /* get the "raw" path */ + result = Curl_urldecode(data, ftp->path, 0, &path, NULL, TRUE); + if(result) { + /* We can limp along anyway (and should try to since we may already be in + * the error path) */ + ftpc->ctl_valid = FALSE; /* mark control connection as bad */ + connclose(conn, "FTP: out of memory!"); /* mark for connection closure */ + ftpc->prevpath = NULL; /* no path remembering */ + } + else { + size_t flen = ftpc->file?strlen(ftpc->file):0; /* file is "raw" already */ + size_t dlen = strlen(path)-flen; + if(!ftpc->cwdfail) { + ftpc->prevmethod = data->set.ftp_filemethod; + if(dlen && (data->set.ftp_filemethod != FTPFILE_NOCWD)) { + ftpc->prevpath = path; + if(flen) + /* if 'path' is not the whole string */ + ftpc->prevpath[dlen] = 0; /* terminate */ + } + else { + free(path); + /* we never changed dir */ + ftpc->prevpath = strdup(""); + if(!ftpc->prevpath) + return CURLE_OUT_OF_MEMORY; + } + if(ftpc->prevpath) + infof(data, "Remembering we are in dir \"%s\"\n", ftpc->prevpath); + } + else { + ftpc->prevpath = NULL; /* no path */ + free(path); + } + } + /* free the dir tree and file parts */ + freedirs(ftpc); + + /* shut down the socket to inform the server we're done */ + +#ifdef _WIN32_WCE + shutdown(conn->sock[SECONDARYSOCKET], 2); /* SD_BOTH */ +#endif + + if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) { + if(!result && ftpc->dont_check && data->req.maxdownload > 0) { + /* partial download completed */ + result = Curl_pp_sendf(pp, "%s", "ABOR"); + if(result) { + failf(data, "Failure sending ABOR command: %s", + curl_easy_strerror(result)); + ftpc->ctl_valid = FALSE; /* mark control connection as bad */ + connclose(conn, "ABOR command failed"); /* connection closure */ + } + } + + if(conn->ssl[SECONDARYSOCKET].use) { + /* The secondary socket is using SSL so we must close down that part + first before we close the socket for real */ + Curl_ssl_close(conn, SECONDARYSOCKET); + + /* Note that we keep "use" set to TRUE since that (next) connection is + still requested to use SSL */ + } + close_secondarysocket(conn); + } + + if(!result && (ftp->transfer == FTPTRANSFER_BODY) && ftpc->ctl_valid && + pp->pending_resp && !premature) { + /* + * Let's see what the server says about the transfer we just performed, + * but lower the timeout as sometimes this connection has died while the + * data has been transferred. This happens when doing through NATs etc that + * abandon old silent connections. + */ + long old_time = pp->response_time; + + pp->response_time = 60*1000; /* give it only a minute for now */ + pp->response = Curl_now(); /* timeout relative now */ + + result = Curl_GetFTPResponse(&nread, conn, &ftpcode); + + pp->response_time = old_time; /* set this back to previous value */ + + if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) { + failf(data, "control connection looks dead"); + ftpc->ctl_valid = FALSE; /* mark control connection as bad */ + connclose(conn, "Timeout or similar in FTP DONE operation"); /* close */ + } + + if(result) + return result; + + if(ftpc->dont_check && data->req.maxdownload > 0) { + /* we have just sent ABOR and there is no reliable way to check if it was + * successful or not; we have to close the connection now */ + infof(data, "partial download completed, closing connection\n"); + connclose(conn, "Partial download with no ability to check"); + return result; + } + + if(!ftpc->dont_check) { + /* 226 Transfer complete, 250 Requested file action okay, completed. */ + if((ftpcode != 226) && (ftpcode != 250)) { + failf(data, "server did not report OK, got %d", ftpcode); + result = CURLE_PARTIAL_FILE; + } + } + } + + if(result || premature) + /* the response code from the transfer showed an error already so no + use checking further */ + ; + else if(data->set.upload) { + if((-1 != data->state.infilesize) && + (data->state.infilesize != data->req.writebytecount) && + !data->set.crlf && + (ftp->transfer == FTPTRANSFER_BODY)) { + failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T + " out of %" CURL_FORMAT_CURL_OFF_T " bytes)", + data->req.bytecount, data->state.infilesize); + result = CURLE_PARTIAL_FILE; + } + } + else { + if((-1 != data->req.size) && + (data->req.size != data->req.bytecount) && +#ifdef CURL_DO_LINEEND_CONV + /* Most FTP servers don't adjust their file SIZE response for CRLFs, so + * we'll check to see if the discrepancy can be explained by the number + * of CRLFs we've changed to LFs. + */ + ((data->req.size + data->state.crlf_conversions) != + data->req.bytecount) && +#endif /* CURL_DO_LINEEND_CONV */ + (data->req.maxdownload != data->req.bytecount)) { + failf(data, "Received only partial file: %" CURL_FORMAT_CURL_OFF_T + " bytes", data->req.bytecount); + result = CURLE_PARTIAL_FILE; + } + else if(!ftpc->dont_check && + !data->req.bytecount && + (data->req.size>0)) { + failf(data, "No data was received!"); + result = CURLE_FTP_COULDNT_RETR_FILE; + } + } + + /* clear these for next connection */ + ftp->transfer = FTPTRANSFER_BODY; + ftpc->dont_check = FALSE; + + /* Send any post-transfer QUOTE strings? */ + if(!status && !result && !premature && data->set.postquote) + result = ftp_sendquote(conn, data->set.postquote); + Curl_safefree(ftp->pathalloc); + return result; +} + +/*********************************************************************** + * + * ftp_sendquote() + * + * Where a 'quote' means a list of custom commands to send to the server. + * The quote list is passed as an argument. + * + * BLOCKING + */ + +static +CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote) +{ + struct curl_slist *item; + ssize_t nread; + int ftpcode; + CURLcode result; + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + + item = quote; + while(item) { + if(item->data) { + char *cmd = item->data; + bool acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal FTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server reponds. */ + + if(cmd[0] == '*') { + cmd++; + acceptfail = TRUE; + } + + PPSENDF(&conn->proto.ftpc.pp, "%s", cmd); + + pp->response = Curl_now(); /* timeout relative now */ + + result = Curl_GetFTPResponse(&nread, conn, &ftpcode); + if(result) + return result; + + if(!acceptfail && (ftpcode >= 400)) { + failf(conn->data, "QUOT string not accepted: %s", cmd); + return CURLE_QUOTE_ERROR; + } + } + + item = item->next; + } + + return CURLE_OK; +} + +/*********************************************************************** + * + * ftp_need_type() + * + * Returns TRUE if we in the current situation should send TYPE + */ +static int ftp_need_type(struct connectdata *conn, + bool ascii_wanted) +{ + return conn->proto.ftpc.transfertype != (ascii_wanted?'A':'I'); +} + +/*********************************************************************** + * + * ftp_nb_type() + * + * Set TYPE. We only deal with ASCII or BINARY so this function + * sets one of them. + * If the transfer type is not sent, simulate on OK response in newstate + */ +static CURLcode ftp_nb_type(struct connectdata *conn, + bool ascii, ftpstate newstate) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + CURLcode result; + char want = (char)(ascii?'A':'I'); + + if(ftpc->transfertype == want) { + state(conn, newstate); + return ftp_state_type_resp(conn, 200, newstate); + } + + PPSENDF(&ftpc->pp, "TYPE %c", want); + state(conn, newstate); + + /* keep track of our current transfer type */ + ftpc->transfertype = want; + return CURLE_OK; +} + +/*************************************************************************** + * + * ftp_pasv_verbose() + * + * This function only outputs some informationals about this second connection + * when we've issued a PASV command before and thus we have connected to a + * possibly new IP address. + * + */ +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static void +ftp_pasv_verbose(struct connectdata *conn, + Curl_addrinfo *ai, + char *newhost, /* ascii version */ + int port) +{ + char buf[256]; + Curl_printable_address(ai, buf, sizeof(buf)); + infof(conn->data, "Connecting to %s (%s) port %d\n", newhost, buf, port); +} +#endif + +/* + * ftp_do_more() + * + * This function shall be called when the second FTP (data) connection is + * connected. + * + * 'complete' can return 0 for incomplete, 1 for done and -1 for go back + * (which basically is only for when PASV is being sent to retry a failed + * EPSV). + */ + +static CURLcode ftp_do_more(struct connectdata *conn, int *completep) +{ + struct Curl_easy *data = conn->data; + struct ftp_conn *ftpc = &conn->proto.ftpc; + CURLcode result = CURLE_OK; + bool connected = FALSE; + bool complete = FALSE; + + /* the ftp struct is inited in ftp_connect() */ + struct FTP *ftp = data->req.protop; + + /* if the second connection isn't done yet, wait for it */ + if(!conn->bits.tcpconnect[SECONDARYSOCKET]) { + if(Curl_connect_ongoing(conn)) { + /* As we're in TUNNEL_CONNECT state now, we know the proxy name and port + aren't used so we blank their arguments. */ + result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0); + + return result; + } + + result = Curl_is_connected(conn, SECONDARYSOCKET, &connected); + + /* Ready to do more? */ + if(connected) { + DEBUGF(infof(data, "DO-MORE connected phase starts\n")); + } + else { + if(result && (ftpc->count1 == 0)) { + *completep = -1; /* go back to DOING please */ + /* this is a EPSV connect failing, try PASV instead */ + return ftp_epsv_disable(conn); + } + return result; + } + } + + result = Curl_proxy_connect(conn, SECONDARYSOCKET); + if(result) + return result; + + if(CONNECT_SECONDARYSOCKET_PROXY_SSL()) + return result; + + if(conn->bits.tunnel_proxy && conn->bits.httpproxy && + Curl_connect_ongoing(conn)) + return result; + + + if(ftpc->state) { + /* already in a state so skip the initial commands. + They are only done to kickstart the do_more state */ + result = ftp_multi_statemach(conn, &complete); + + *completep = (int)complete; + + /* if we got an error or if we don't wait for a data connection return + immediately */ + if(result || (ftpc->wait_data_conn != TRUE)) + return result; + + if(ftpc->wait_data_conn) + /* if we reach the end of the FTP state machine here, *complete will be + TRUE but so is ftpc->wait_data_conn, which says we need to wait for + the data connection and therefore we're not actually complete */ + *completep = 0; + } + + if(ftp->transfer <= FTPTRANSFER_INFO) { + /* a transfer is about to take place, or if not a file name was given + so we'll do a SIZE on it later and then we need the right TYPE first */ + + if(ftpc->wait_data_conn == TRUE) { + bool serv_conned; + + result = ReceivedServerConnect(conn, &serv_conned); + if(result) + return result; /* Failed to accept data connection */ + + if(serv_conned) { + /* It looks data connection is established */ + result = AcceptServerConnect(conn); + ftpc->wait_data_conn = FALSE; + if(!result) + result = InitiateTransfer(conn); + + if(result) + return result; + + *completep = 1; /* this state is now complete when the server has + connected back to us */ + } + } + else if(data->set.upload) { + result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE); + if(result) + return result; + + result = ftp_multi_statemach(conn, &complete); + if(ftpc->wait_data_conn) + /* if we reach the end of the FTP state machine here, *complete will be + TRUE but so is ftpc->wait_data_conn, which says we need to wait for + the data connection and therefore we're not actually complete */ + *completep = 0; + else + *completep = (int)complete; + } + else { + /* download */ + ftp->downloadsize = -1; /* unknown as of yet */ + + result = Curl_range(conn); + + if(result == CURLE_OK && data->req.maxdownload >= 0) { + /* Don't check for successful transfer */ + ftpc->dont_check = TRUE; + } + + if(result) + ; + else if(data->set.ftp_list_only || !ftpc->file) { + /* The specified path ends with a slash, and therefore we think this + is a directory that is requested, use LIST. But before that we + need to set ASCII transfer mode. */ + + /* But only if a body transfer was requested. */ + if(ftp->transfer == FTPTRANSFER_BODY) { + result = ftp_nb_type(conn, TRUE, FTP_LIST_TYPE); + if(result) + return result; + } + /* otherwise just fall through */ + } + else { + result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_RETR_TYPE); + if(result) + return result; + } + + result = ftp_multi_statemach(conn, &complete); + *completep = (int)complete; + } + return result; + } + + if(!result && (ftp->transfer != FTPTRANSFER_BODY)) + /* no data to transfer. FIX: it feels like a kludge to have this here + too! */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + + if(!ftpc->wait_data_conn) { + /* no waiting for the data connection so this is now complete */ + *completep = 1; + DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result)); + } + + return result; +} + + + +/*********************************************************************** + * + * ftp_perform() + * + * This is the actual DO function for FTP. Get a file/directory according to + * the options previously setup. + */ + +static +CURLcode ftp_perform(struct connectdata *conn, + bool *connected, /* connect status after PASV / PORT */ + bool *dophase_done) +{ + /* this is FTP and no proxy */ + CURLcode result = CURLE_OK; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + if(conn->data->set.opt_no_body) { + /* requested no body means no transfer... */ + struct FTP *ftp = conn->data->req.protop; + ftp->transfer = FTPTRANSFER_INFO; + } + + *dophase_done = FALSE; /* not done yet */ + + /* start the first command in the DO phase */ + result = ftp_state_quote(conn, TRUE, FTP_QUOTE); + if(result) + return result; + + /* run the state-machine */ + result = ftp_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[SECONDARYSOCKET]; + + infof(conn->data, "ftp_perform ends with SECONDARY: %d\n", *connected); + + if(*dophase_done) + DEBUGF(infof(conn->data, "DO phase is complete1\n")); + + return result; +} + +static void wc_data_dtor(void *ptr) +{ + struct ftp_wc *ftpwc = ptr; + if(ftpwc && ftpwc->parser) + Curl_ftp_parselist_data_free(&ftpwc->parser); + free(ftpwc); +} + +static CURLcode init_wc_data(struct connectdata *conn) +{ + char *last_slash; + struct FTP *ftp = conn->data->req.protop; + char *path = ftp->path; + struct WildcardData *wildcard = &(conn->data->wildcard); + CURLcode result = CURLE_OK; + struct ftp_wc *ftpwc = NULL; + + last_slash = strrchr(ftp->path, '/'); + if(last_slash) { + last_slash++; + if(last_slash[0] == '\0') { + wildcard->state = CURLWC_CLEAN; + result = ftp_parse_url_path(conn); + return result; + } + wildcard->pattern = strdup(last_slash); + if(!wildcard->pattern) + return CURLE_OUT_OF_MEMORY; + last_slash[0] = '\0'; /* cut file from path */ + } + else { /* there is only 'wildcard pattern' or nothing */ + if(path[0]) { + wildcard->pattern = strdup(path); + if(!wildcard->pattern) + return CURLE_OUT_OF_MEMORY; + path[0] = '\0'; + } + else { /* only list */ + wildcard->state = CURLWC_CLEAN; + result = ftp_parse_url_path(conn); + return result; + } + } + + /* program continues only if URL is not ending with slash, allocate needed + resources for wildcard transfer */ + + /* allocate ftp protocol specific wildcard data */ + ftpwc = calloc(1, sizeof(struct ftp_wc)); + if(!ftpwc) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + + /* INITIALIZE parselist structure */ + ftpwc->parser = Curl_ftp_parselist_data_alloc(); + if(!ftpwc->parser) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + + wildcard->protdata = ftpwc; /* put it to the WildcardData tmp pointer */ + wildcard->dtor = wc_data_dtor; + + /* wildcard does not support NOCWD option (assert it?) */ + if(conn->data->set.ftp_filemethod == FTPFILE_NOCWD) + conn->data->set.ftp_filemethod = FTPFILE_MULTICWD; + + /* try to parse ftp url */ + result = ftp_parse_url_path(conn); + if(result) { + goto fail; + } + + wildcard->path = strdup(ftp->path); + if(!wildcard->path) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + + /* backup old write_function */ + ftpwc->backup.write_function = conn->data->set.fwrite_func; + /* parsing write function */ + conn->data->set.fwrite_func = Curl_ftp_parselist; + /* backup old file descriptor */ + ftpwc->backup.file_descriptor = conn->data->set.out; + /* let the writefunc callback know what curl pointer is working with */ + conn->data->set.out = conn; + + infof(conn->data, "Wildcard - Parsing started\n"); + return CURLE_OK; + + fail: + if(ftpwc) { + Curl_ftp_parselist_data_free(&ftpwc->parser); + free(ftpwc); + } + Curl_safefree(wildcard->pattern); + wildcard->dtor = ZERO_NULL; + wildcard->protdata = NULL; + return result; +} + +/* This is called recursively */ +static CURLcode wc_statemach(struct connectdata *conn) +{ + struct WildcardData * const wildcard = &(conn->data->wildcard); + CURLcode result = CURLE_OK; + + switch(wildcard->state) { + case CURLWC_INIT: + result = init_wc_data(conn); + if(wildcard->state == CURLWC_CLEAN) + /* only listing! */ + break; + wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING; + break; + + case CURLWC_MATCHING: { + /* In this state is LIST response successfully parsed, so lets restore + previous WRITEFUNCTION callback and WRITEDATA pointer */ + struct ftp_wc *ftpwc = wildcard->protdata; + conn->data->set.fwrite_func = ftpwc->backup.write_function; + conn->data->set.out = ftpwc->backup.file_descriptor; + ftpwc->backup.write_function = ZERO_NULL; + ftpwc->backup.file_descriptor = NULL; + wildcard->state = CURLWC_DOWNLOADING; + + if(Curl_ftp_parselist_geterror(ftpwc->parser)) { + /* error found in LIST parsing */ + wildcard->state = CURLWC_CLEAN; + return wc_statemach(conn); + } + if(wildcard->filelist.size == 0) { + /* no corresponding file */ + wildcard->state = CURLWC_CLEAN; + return CURLE_REMOTE_FILE_NOT_FOUND; + } + return wc_statemach(conn); + } + + case CURLWC_DOWNLOADING: { + /* filelist has at least one file, lets get first one */ + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct curl_fileinfo *finfo = wildcard->filelist.head->ptr; + struct FTP *ftp = conn->data->req.protop; + + char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename); + if(!tmp_path) + return CURLE_OUT_OF_MEMORY; + + /* switch default ftp->path and tmp_path */ + free(ftp->pathalloc); + ftp->pathalloc = ftp->path = tmp_path; + + infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename); + if(conn->data->set.chunk_bgn) { + long userresponse; + Curl_set_in_callback(conn->data, true); + userresponse = conn->data->set.chunk_bgn( + finfo, wildcard->customptr, (int)wildcard->filelist.size); + Curl_set_in_callback(conn->data, false); + switch(userresponse) { + case CURL_CHUNK_BGN_FUNC_SKIP: + infof(conn->data, "Wildcard - \"%s\" skipped by user\n", + finfo->filename); + wildcard->state = CURLWC_SKIP; + return wc_statemach(conn); + case CURL_CHUNK_BGN_FUNC_FAIL: + return CURLE_CHUNK_FAILED; + } + } + + if(finfo->filetype != CURLFILETYPE_FILE) { + wildcard->state = CURLWC_SKIP; + return wc_statemach(conn); + } + + if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE) + ftpc->known_filesize = finfo->size; + + result = ftp_parse_url_path(conn); + if(result) + return result; + + /* we don't need the Curl_fileinfo of first file anymore */ + Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); + + if(wildcard->filelist.size == 0) { /* remains only one file to down. */ + wildcard->state = CURLWC_CLEAN; + /* after that will be ftp_do called once again and no transfer + will be done because of CURLWC_CLEAN state */ + return CURLE_OK; + } + } break; + + case CURLWC_SKIP: { + if(conn->data->set.chunk_end) { + Curl_set_in_callback(conn->data, true); + conn->data->set.chunk_end(conn->data->wildcard.customptr); + Curl_set_in_callback(conn->data, false); + } + Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); + wildcard->state = (wildcard->filelist.size == 0) ? + CURLWC_CLEAN : CURLWC_DOWNLOADING; + return wc_statemach(conn); + } + + case CURLWC_CLEAN: { + struct ftp_wc *ftpwc = wildcard->protdata; + result = CURLE_OK; + if(ftpwc) + result = Curl_ftp_parselist_geterror(ftpwc->parser); + + wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE; + } break; + + case CURLWC_DONE: + case CURLWC_ERROR: + case CURLWC_CLEAR: + if(wildcard->dtor) + wildcard->dtor(wildcard->protdata); + break; + } + + return result; +} + +/*********************************************************************** + * + * ftp_do() + * + * This function is registered as 'curl_do' function. It decodes the path + * parts etc as a wrapper to the actual DO function (ftp_perform). + * + * The input argument is already checked for validity. + */ +static CURLcode ftp_do(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + *done = FALSE; /* default to false */ + ftpc->wait_data_conn = FALSE; /* default to no such wait */ + + if(conn->data->state.wildcardmatch) { + result = wc_statemach(conn); + if(conn->data->wildcard.state == CURLWC_SKIP || + conn->data->wildcard.state == CURLWC_DONE) { + /* do not call ftp_regular_transfer */ + return CURLE_OK; + } + if(result) /* error, loop or skipping the file */ + return result; + } + else { /* no wildcard FSM needed */ + result = ftp_parse_url_path(conn); + if(result) + return result; + } + + result = ftp_regular_transfer(conn, done); + + return result; +} + + +CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd) +{ + ssize_t bytes_written; +#define SBUF_SIZE 1024 + char s[SBUF_SIZE]; + size_t write_len; + char *sptr = s; + CURLcode result = CURLE_OK; +#ifdef HAVE_GSSAPI + enum protection_level data_sec = conn->data_prot; +#endif + + if(!cmd) + return CURLE_BAD_FUNCTION_ARGUMENT; + + write_len = strlen(cmd); + if(!write_len || write_len > (sizeof(s) -3)) + return CURLE_BAD_FUNCTION_ARGUMENT; + + memcpy(&s, cmd, write_len); + strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */ + write_len += 2; + bytes_written = 0; + + result = Curl_convert_to_network(conn->data, s, write_len); + /* Curl_convert_to_network calls failf if unsuccessful */ + if(result) + return result; + + for(;;) { +#ifdef HAVE_GSSAPI + conn->data_prot = PROT_CMD; +#endif + result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len, + &bytes_written); +#ifdef HAVE_GSSAPI + DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST); + conn->data_prot = data_sec; +#endif + + if(result) + break; + + if(conn->data->set.verbose) + Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, (size_t)bytes_written); + + if(bytes_written != (ssize_t)write_len) { + write_len -= bytes_written; + sptr += bytes_written; + } + else + break; + } + + return result; +} + +/*********************************************************************** + * + * ftp_quit() + * + * This should be called before calling sclose() on an ftp control connection + * (not data connections). We should then wait for the response from the + * server before returning. The calling code should then try to close the + * connection. + * + */ +static CURLcode ftp_quit(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + + if(conn->proto.ftpc.ctl_valid) { + result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "QUIT"); + if(result) { + failf(conn->data, "Failure sending QUIT command: %s", + curl_easy_strerror(result)); + conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */ + connclose(conn, "QUIT command failed"); /* mark for connection closure */ + state(conn, FTP_STOP); + return result; + } + + state(conn, FTP_QUIT); + + result = ftp_block_statemach(conn); + } + + return result; +} + +/*********************************************************************** + * + * ftp_disconnect() + * + * Disconnect from an FTP server. Cleanup protocol-specific per-connection + * resources. BLOCKING. + */ +static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection) +{ + struct ftp_conn *ftpc = &conn->proto.ftpc; + struct pingpong *pp = &ftpc->pp; + + /* We cannot send quit unconditionally. If this connection is stale or + bad in any way, sending quit and waiting around here will make the + disconnect wait in vain and cause more problems than we need to. + + ftp_quit() will check the state of ftp->ctl_valid. If it's ok it + will try to send the QUIT command, otherwise it will just return. + */ + if(dead_connection) + ftpc->ctl_valid = FALSE; + + /* The FTP session may or may not have been allocated/setup at this point! */ + (void)ftp_quit(conn); /* ignore errors on the QUIT */ + + if(ftpc->entrypath) { + struct Curl_easy *data = conn->data; + if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) { + data->state.most_recent_ftp_entrypath = NULL; + } + free(ftpc->entrypath); + ftpc->entrypath = NULL; + } + + freedirs(ftpc); + free(ftpc->prevpath); + ftpc->prevpath = NULL; + free(ftpc->server_os); + ftpc->server_os = NULL; + + Curl_pp_disconnect(pp); + +#ifdef HAVE_GSSAPI + Curl_sec_end(conn); +#endif + + return CURLE_OK; +} + +/*********************************************************************** + * + * ftp_parse_url_path() + * + * Parse the URL path into separate path components. + * + */ +static +CURLcode ftp_parse_url_path(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + /* the ftp struct is already inited in ftp_connect() */ + struct FTP *ftp = data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + const char *slash_pos; /* position of the first '/' char in curpos */ + const char *path_to_use = ftp->path; + const char *cur_pos; + const char *filename = NULL; + + cur_pos = path_to_use; /* current position in path. point at the begin of + next path component */ + + ftpc->ctl_valid = FALSE; + ftpc->cwdfail = FALSE; + + switch(data->set.ftp_filemethod) { + case FTPFILE_NOCWD: + /* fastest, but less standard-compliant */ + + /* + The best time to check whether the path is a file or directory is right + here. so: + + the first condition in the if() right here, is there just in case + someone decides to set path to NULL one day + */ + if(path_to_use[0] && + (path_to_use[strlen(path_to_use) - 1] != '/') ) + filename = path_to_use; /* this is a full file path */ + /* + else { + ftpc->file is not used anywhere other than for operations on a file. + In other words, never for directory operations. + So we can safely leave filename as NULL here and use it as a + argument in dir/file decisions. + } + */ + break; + + case FTPFILE_SINGLECWD: + /* get the last slash */ + if(!path_to_use[0]) { + /* no dir, no file */ + ftpc->dirdepth = 0; + break; + } + slash_pos = strrchr(cur_pos, '/'); + if(slash_pos || !*cur_pos) { + size_t dirlen = slash_pos-cur_pos; + CURLcode result; + + ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0])); + if(!ftpc->dirs) + return CURLE_OUT_OF_MEMORY; + + if(!dirlen) + dirlen++; + + result = Curl_urldecode(conn->data, slash_pos ? cur_pos : "/", + slash_pos ? dirlen : 1, + &ftpc->dirs[0], NULL, + TRUE); + if(result) { + freedirs(ftpc); + return result; + } + ftpc->dirdepth = 1; /* we consider it to be a single dir */ + filename = slash_pos ? slash_pos + 1 : cur_pos; /* rest is file name */ + } + else + filename = cur_pos; /* this is a file name only */ + break; + + default: /* allow pretty much anything */ + case FTPFILE_MULTICWD: + ftpc->dirdepth = 0; + ftpc->diralloc = 5; /* default dir depth to allocate */ + ftpc->dirs = calloc(ftpc->diralloc, sizeof(ftpc->dirs[0])); + if(!ftpc->dirs) + return CURLE_OUT_OF_MEMORY; + + /* we have a special case for listing the root dir only */ + if(!strcmp(path_to_use, "/")) { + cur_pos++; /* make it point to the zero byte */ + ftpc->dirs[0] = strdup("/"); + ftpc->dirdepth++; + } + else { + /* parse the URL path into separate path components */ + while((slash_pos = strchr(cur_pos, '/')) != NULL) { + /* 1 or 0 pointer offset to indicate absolute directory */ + ssize_t absolute_dir = ((cur_pos - ftp->path > 0) && + (ftpc->dirdepth == 0))?1:0; + + /* seek out the next path component */ + if(slash_pos-cur_pos) { + /* we skip empty path components, like "x//y" since the FTP command + CWD requires a parameter and a non-existent parameter a) doesn't + work on many servers and b) has no effect on the others. */ + size_t len = slash_pos - cur_pos + absolute_dir; + CURLcode result = + Curl_urldecode(conn->data, cur_pos - absolute_dir, len, + &ftpc->dirs[ftpc->dirdepth], NULL, + TRUE); + if(result) { + freedirs(ftpc); + return result; + } + } + else { + cur_pos = slash_pos + 1; /* jump to the rest of the string */ + if(!ftpc->dirdepth) { + /* path starts with a slash, add that as a directory */ + ftpc->dirs[ftpc->dirdepth] = strdup("/"); + if(!ftpc->dirs[ftpc->dirdepth++]) { /* run out of memory ... */ + failf(data, "no memory"); + freedirs(ftpc); + return CURLE_OUT_OF_MEMORY; + } + } + continue; + } + + cur_pos = slash_pos + 1; /* jump to the rest of the string */ + if(++ftpc->dirdepth >= ftpc->diralloc) { + /* enlarge array */ + char **bigger; + ftpc->diralloc *= 2; /* double the size each time */ + bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0])); + if(!bigger) { + freedirs(ftpc); + return CURLE_OUT_OF_MEMORY; + } + ftpc->dirs = bigger; + } + } + } + filename = cur_pos; /* the rest is the file name */ + break; + } /* switch */ + + if(filename && *filename) { + CURLcode result = + Curl_urldecode(conn->data, filename, 0, &ftpc->file, NULL, TRUE); + + if(result) { + freedirs(ftpc); + return result; + } + } + else + ftpc->file = NULL; /* instead of point to a zero byte, we make it a NULL + pointer */ + + if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) { + /* We need a file name when uploading. Return error! */ + failf(data, "Uploading to a URL without a file name!"); + return CURLE_URL_MALFORMAT; + } + + ftpc->cwddone = FALSE; /* default to not done */ + + if(ftpc->prevpath) { + /* prevpath is "raw" so we convert the input path before we compare the + strings */ + size_t dlen; + char *path; + CURLcode result = + Curl_urldecode(conn->data, ftp->path, 0, &path, &dlen, TRUE); + if(result) { + freedirs(ftpc); + return result; + } + + dlen -= ftpc->file?strlen(ftpc->file):0; + if((dlen == strlen(ftpc->prevpath)) && + !strncmp(path, ftpc->prevpath, dlen) && + (ftpc->prevmethod == data->set.ftp_filemethod)) { + infof(data, "Request has same path as previous transfer\n"); + ftpc->cwddone = TRUE; + } + free(path); + } + + return CURLE_OK; +} + +/* call this when the DO phase has completed */ +static CURLcode ftp_dophase_done(struct connectdata *conn, + bool connected) +{ + struct FTP *ftp = conn->data->req.protop; + struct ftp_conn *ftpc = &conn->proto.ftpc; + + if(connected) { + int completed; + CURLcode result = ftp_do_more(conn, &completed); + + if(result) { + close_secondarysocket(conn); + return result; + } + } + + if(ftp->transfer != FTPTRANSFER_BODY) + /* no data to transfer */ + Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); + else if(!connected) + /* since we didn't connect now, we want do_more to get called */ + conn->bits.do_more = TRUE; + + ftpc->ctl_valid = TRUE; /* seems good */ + + return CURLE_OK; +} + +/* called from multi.c while DOing */ +static CURLcode ftp_doing(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result = ftp_multi_statemach(conn, dophase_done); + + if(result) + DEBUGF(infof(conn->data, "DO phase failed\n")); + else if(*dophase_done) { + result = ftp_dophase_done(conn, FALSE /* not connected */); + + DEBUGF(infof(conn->data, "DO phase is complete2\n")); + } + return result; +} + +/*********************************************************************** + * + * ftp_regular_transfer() + * + * The input argument is already checked for validity. + * + * Performs all commands done before a regular transfer between a local and a + * remote host. + * + * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the + * ftp_done() function without finding any major problem. + */ +static +CURLcode ftp_regular_transfer(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result = CURLE_OK; + bool connected = FALSE; + struct Curl_easy *data = conn->data; + struct ftp_conn *ftpc = &conn->proto.ftpc; + data->req.size = -1; /* make sure this is unknown at this point */ + + Curl_pgrsSetUploadCounter(data, 0); + Curl_pgrsSetDownloadCounter(data, 0); + Curl_pgrsSetUploadSize(data, -1); + Curl_pgrsSetDownloadSize(data, -1); + + ftpc->ctl_valid = TRUE; /* starts good */ + + result = ftp_perform(conn, + &connected, /* have we connected after PASV/PORT */ + dophase_done); /* all commands in the DO-phase done? */ + + if(!result) { + + if(!*dophase_done) + /* the DO phase has not completed yet */ + return CURLE_OK; + + result = ftp_dophase_done(conn, connected); + + if(result) + return result; + } + else + freedirs(ftpc); + + return result; +} + +static CURLcode ftp_setup_connection(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + char *type; + struct FTP *ftp; + + conn->data->req.protop = ftp = calloc(sizeof(struct FTP), 1); + if(NULL == ftp) + return CURLE_OUT_OF_MEMORY; + + ftp->path = &data->state.up.path[1]; /* don't include the initial slash */ + + /* FTP URLs support an extension like ";type=" that + * we'll try to get now! */ + type = strstr(ftp->path, ";type="); + + if(!type) + type = strstr(conn->host.rawalloc, ";type="); + + if(type) { + char command; + *type = 0; /* it was in the middle of the hostname */ + command = Curl_raw_toupper(type[6]); + conn->bits.type_set = TRUE; + + switch(command) { + case 'A': /* ASCII mode */ + data->set.prefer_ascii = TRUE; + break; + + case 'D': /* directory mode */ + data->set.ftp_list_only = TRUE; + break; + + case 'I': /* binary mode */ + default: + /* switch off ASCII */ + data->set.prefer_ascii = FALSE; + break; + } + } + + /* get some initial data into the ftp struct */ + ftp->transfer = FTPTRANSFER_BODY; + ftp->downloadsize = 0; + + /* No need to duplicate user+password, the connectdata struct won't change + during a session, but we re-init them here since on subsequent inits + since the conn struct may have changed or been replaced. + */ + ftp->user = conn->user; + ftp->passwd = conn->passwd; + if(isBadFtpString(ftp->user)) + return CURLE_URL_MALFORMAT; + if(isBadFtpString(ftp->passwd)) + return CURLE_URL_MALFORMAT; + + conn->proto.ftpc.known_filesize = -1; /* unknown size for now */ + + return CURLE_OK; +} + +#endif /* CURL_DISABLE_FTP */ diff --git a/libcurl/lib/ftp.h b/libcurl/lib/ftp.h new file mode 100644 index 0000000..828d69a --- /dev/null +++ b/libcurl/lib/ftp.h @@ -0,0 +1,162 @@ +#ifndef HEADER_CURL_FTP_H +#define HEADER_CURL_FTP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "pingpong.h" + +#ifndef CURL_DISABLE_FTP +extern const struct Curl_handler Curl_handler_ftp; + +#ifdef USE_SSL +extern const struct Curl_handler Curl_handler_ftps; +#endif + +CURLcode Curl_ftpsend(struct connectdata *, const char *cmd); +CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn, + int *ftpcode); +#endif /* CURL_DISABLE_FTP */ + +/**************************************************************************** + * FTP unique setup + ***************************************************************************/ +typedef enum { + FTP_STOP, /* do nothing state, stops the state machine */ + FTP_WAIT220, /* waiting for the initial 220 response immediately after + a connect */ + FTP_AUTH, + FTP_USER, + FTP_PASS, + FTP_ACCT, + FTP_PBSZ, + FTP_PROT, + FTP_CCC, + FTP_PWD, + FTP_SYST, + FTP_NAMEFMT, + FTP_QUOTE, /* waiting for a response to a command sent in a quote list */ + FTP_RETR_PREQUOTE, + FTP_STOR_PREQUOTE, + FTP_POSTQUOTE, + FTP_CWD, /* change dir */ + FTP_MKD, /* if the dir didn't exist */ + FTP_MDTM, /* to figure out the datestamp */ + FTP_TYPE, /* to set type when doing a head-like request */ + FTP_LIST_TYPE, /* set type when about to do a dir list */ + FTP_RETR_TYPE, /* set type when about to RETR a file */ + FTP_STOR_TYPE, /* set type when about to STOR a file */ + FTP_SIZE, /* get the remote file's size for head-like request */ + FTP_RETR_SIZE, /* get the remote file's size for RETR */ + FTP_STOR_SIZE, /* get the size for STOR */ + FTP_REST, /* when used to check if the server supports it in head-like */ + FTP_RETR_REST, /* when asking for "resume" in for RETR */ + FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */ + FTP_PRET, /* generic state for PRET RETR, PRET STOR and PRET LIST/NLST */ + FTP_PASV, /* generic state for PASV and EPSV, check count1 */ + FTP_LIST, /* generic state for LIST, NLST or a custom list command */ + FTP_RETR, + FTP_STOR, /* generic state for STOR and APPE */ + FTP_QUIT, + FTP_LAST /* never used */ +} ftpstate; + +struct ftp_parselist_data; /* defined later in ftplistparser.c */ + +struct ftp_wc { + struct ftp_parselist_data *parser; + + struct { + curl_write_callback write_function; + FILE *file_descriptor; + } backup; +}; + +typedef enum { + FTPFILE_MULTICWD = 1, /* as defined by RFC1738 */ + FTPFILE_NOCWD = 2, /* use SIZE / RETR / STOR on the full path */ + FTPFILE_SINGLECWD = 3 /* make one CWD, then SIZE / RETR / STOR on the + file */ +} curl_ftpfile; + +/* This FTP struct is used in the Curl_easy. All FTP data that is + connection-oriented must be in FTP_conn to properly deal with the fact that + perhaps the Curl_easy is changed between the times the connection is + used. */ +struct FTP { + char *user; /* user name string */ + char *passwd; /* password string */ + char *path; /* points to the urlpieces struct field */ + char *pathalloc; /* if non-NULL a pointer to an allocated path */ + + /* transfer a file/body or not, done as a typedefed enum just to make + debuggers display the full symbol and not just the numerical value */ + curl_pp_transfer transfer; + curl_off_t downloadsize; +}; + + +/* ftp_conn is used for struct connection-oriented data in the connectdata + struct */ +struct ftp_conn { + struct pingpong pp; + char *entrypath; /* the PWD reply when we logged on */ + char **dirs; /* realloc()ed array for path components */ + int dirdepth; /* number of entries used in the 'dirs' array */ + int diralloc; /* number of entries allocated for the 'dirs' array */ + char *file; /* decoded file */ + bool dont_check; /* Set to TRUE to prevent the final (post-transfer) + file size and 226/250 status check. It should still + read the line, just ignore the result. */ + bool ctl_valid; /* Tells Curl_ftp_quit() whether or not to do anything. If + the connection has timed out or been closed, this + should be FALSE when it gets to Curl_ftp_quit() */ + bool cwddone; /* if it has been determined that the proper CWD combo + already has been done */ + int cwdcount; /* number of CWD commands issued */ + bool cwdfail; /* set TRUE if a CWD command fails, as then we must prevent + caching the current directory */ + bool wait_data_conn; /* this is set TRUE if data connection is waited */ + char *prevpath; /* conn->path from the previous transfer */ + curl_ftpfile prevmethod; /* ftp method in previous transfer */ + char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a + and others (A/I or zero) */ + int count1; /* general purpose counter for the state machine */ + int count2; /* general purpose counter for the state machine */ + int count3; /* general purpose counter for the state machine */ + ftpstate state; /* always use ftp.c:state() to change state! */ + ftpstate state_saved; /* transfer type saved to be reloaded after + data connection is established */ + curl_off_t retr_size_saved; /* Size of retrieved file saved */ + char *server_os; /* The target server operating system. */ + curl_off_t known_filesize; /* file size is different from -1, if wildcard + LIST parsing was done and wc_statemach set + it */ + /* newhost is the (allocated) IP addr or host name to connect the data + connection to */ + char *newhost; /* this is the pair to connect the DATA... */ + unsigned short newport; /* connection to */ + +}; + +#define DEFAULT_ACCEPT_TIMEOUT 60000 /* milliseconds == one minute */ + +#endif /* HEADER_CURL_FTP_H */ diff --git a/libcurl/lib/ftplistparser.c b/libcurl/lib/ftplistparser.c new file mode 100644 index 0000000..c4eb437 --- /dev/null +++ b/libcurl/lib/ftplistparser.c @@ -0,0 +1,1019 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/** + * Now implemented: + * + * 1) Unix version 1 + * drwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog + * 2) Unix version 2 + * drwxr-xr-x 1 user01 ftp 512 Jan 29 1997 prog + * 3) Unix version 3 + * drwxr-xr-x 1 1 1 512 Jan 29 23:32 prog + * 4) Unix symlink + * lrwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog -> prog2000 + * 5) DOS style + * 01-29-97 11:32PM prog + */ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_FTP + +#include + +#include "urldata.h" +#include "fileinfo.h" +#include "llist.h" +#include "strtoofft.h" +#include "ftp.h" +#include "ftplistparser.h" +#include "curl_fnmatch.h" +#include "curl_memory.h" +#include "multiif.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* allocs buffer which will contain one line of LIST command response */ +#define FTP_BUFFER_ALLOCSIZE 160 + +typedef enum { + PL_UNIX_TOTALSIZE = 0, + PL_UNIX_FILETYPE, + PL_UNIX_PERMISSION, + PL_UNIX_HLINKS, + PL_UNIX_USER, + PL_UNIX_GROUP, + PL_UNIX_SIZE, + PL_UNIX_TIME, + PL_UNIX_FILENAME, + PL_UNIX_SYMLINK +} pl_unix_mainstate; + +typedef union { + enum { + PL_UNIX_TOTALSIZE_INIT = 0, + PL_UNIX_TOTALSIZE_READING + } total_dirsize; + + enum { + PL_UNIX_HLINKS_PRESPACE = 0, + PL_UNIX_HLINKS_NUMBER + } hlinks; + + enum { + PL_UNIX_USER_PRESPACE = 0, + PL_UNIX_USER_PARSING + } user; + + enum { + PL_UNIX_GROUP_PRESPACE = 0, + PL_UNIX_GROUP_NAME + } group; + + enum { + PL_UNIX_SIZE_PRESPACE = 0, + PL_UNIX_SIZE_NUMBER + } size; + + enum { + PL_UNIX_TIME_PREPART1 = 0, + PL_UNIX_TIME_PART1, + PL_UNIX_TIME_PREPART2, + PL_UNIX_TIME_PART2, + PL_UNIX_TIME_PREPART3, + PL_UNIX_TIME_PART3 + } time; + + enum { + PL_UNIX_FILENAME_PRESPACE = 0, + PL_UNIX_FILENAME_NAME, + PL_UNIX_FILENAME_WINDOWSEOL + } filename; + + enum { + PL_UNIX_SYMLINK_PRESPACE = 0, + PL_UNIX_SYMLINK_NAME, + PL_UNIX_SYMLINK_PRETARGET1, + PL_UNIX_SYMLINK_PRETARGET2, + PL_UNIX_SYMLINK_PRETARGET3, + PL_UNIX_SYMLINK_PRETARGET4, + PL_UNIX_SYMLINK_TARGET, + PL_UNIX_SYMLINK_WINDOWSEOL + } symlink; +} pl_unix_substate; + +typedef enum { + PL_WINNT_DATE = 0, + PL_WINNT_TIME, + PL_WINNT_DIRORSIZE, + PL_WINNT_FILENAME +} pl_winNT_mainstate; + +typedef union { + enum { + PL_WINNT_TIME_PRESPACE = 0, + PL_WINNT_TIME_TIME + } time; + enum { + PL_WINNT_DIRORSIZE_PRESPACE = 0, + PL_WINNT_DIRORSIZE_CONTENT + } dirorsize; + enum { + PL_WINNT_FILENAME_PRESPACE = 0, + PL_WINNT_FILENAME_CONTENT, + PL_WINNT_FILENAME_WINEOL + } filename; +} pl_winNT_substate; + +/* This struct is used in wildcard downloading - for parsing LIST response */ +struct ftp_parselist_data { + enum { + OS_TYPE_UNKNOWN = 0, + OS_TYPE_UNIX, + OS_TYPE_WIN_NT + } os_type; + + union { + struct { + pl_unix_mainstate main; + pl_unix_substate sub; + } UNIX; + + struct { + pl_winNT_mainstate main; + pl_winNT_substate sub; + } NT; + } state; + + CURLcode error; + struct fileinfo *file_data; + unsigned int item_length; + size_t item_offset; + struct { + size_t filename; + size_t user; + size_t group; + size_t time; + size_t perm; + size_t symlink_target; + } offsets; +}; + +struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void) +{ + return calloc(1, sizeof(struct ftp_parselist_data)); +} + + +void Curl_ftp_parselist_data_free(struct ftp_parselist_data **parserp) +{ + struct ftp_parselist_data *parser = *parserp; + if(parser) + Curl_fileinfo_cleanup(parser->file_data); + free(parser); + *parserp = NULL; +} + + +CURLcode Curl_ftp_parselist_geterror(struct ftp_parselist_data *pl_data) +{ + return pl_data->error; +} + + +#define FTP_LP_MALFORMATED_PERM 0x01000000 + +static int ftp_pl_get_permission(const char *str) +{ + int permissions = 0; + /* USER */ + if(str[0] == 'r') + permissions |= 1 << 8; + else if(str[0] != '-') + permissions |= FTP_LP_MALFORMATED_PERM; + if(str[1] == 'w') + permissions |= 1 << 7; + else if(str[1] != '-') + permissions |= FTP_LP_MALFORMATED_PERM; + + if(str[2] == 'x') + permissions |= 1 << 6; + else if(str[2] == 's') { + permissions |= 1 << 6; + permissions |= 1 << 11; + } + else if(str[2] == 'S') + permissions |= 1 << 11; + else if(str[2] != '-') + permissions |= FTP_LP_MALFORMATED_PERM; + /* GROUP */ + if(str[3] == 'r') + permissions |= 1 << 5; + else if(str[3] != '-') + permissions |= FTP_LP_MALFORMATED_PERM; + if(str[4] == 'w') + permissions |= 1 << 4; + else if(str[4] != '-') + permissions |= FTP_LP_MALFORMATED_PERM; + if(str[5] == 'x') + permissions |= 1 << 3; + else if(str[5] == 's') { + permissions |= 1 << 3; + permissions |= 1 << 10; + } + else if(str[5] == 'S') + permissions |= 1 << 10; + else if(str[5] != '-') + permissions |= FTP_LP_MALFORMATED_PERM; + /* others */ + if(str[6] == 'r') + permissions |= 1 << 2; + else if(str[6] != '-') + permissions |= FTP_LP_MALFORMATED_PERM; + if(str[7] == 'w') + permissions |= 1 << 1; + else if(str[7] != '-') + permissions |= FTP_LP_MALFORMATED_PERM; + if(str[8] == 'x') + permissions |= 1; + else if(str[8] == 't') { + permissions |= 1; + permissions |= 1 << 9; + } + else if(str[8] == 'T') + permissions |= 1 << 9; + else if(str[8] != '-') + permissions |= FTP_LP_MALFORMATED_PERM; + + return permissions; +} + +static CURLcode ftp_pl_insert_finfo(struct connectdata *conn, + struct fileinfo *infop) +{ + curl_fnmatch_callback compare; + struct WildcardData *wc = &conn->data->wildcard; + struct ftp_wc *ftpwc = wc->protdata; + struct curl_llist *llist = &wc->filelist; + struct ftp_parselist_data *parser = ftpwc->parser; + bool add = TRUE; + struct curl_fileinfo *finfo = &infop->info; + + /* move finfo pointers to b_data */ + char *str = finfo->b_data; + finfo->filename = str + parser->offsets.filename; + finfo->strings.group = parser->offsets.group ? + str + parser->offsets.group : NULL; + finfo->strings.perm = parser->offsets.perm ? + str + parser->offsets.perm : NULL; + finfo->strings.target = parser->offsets.symlink_target ? + str + parser->offsets.symlink_target : NULL; + finfo->strings.time = str + parser->offsets.time; + finfo->strings.user = parser->offsets.user ? + str + parser->offsets.user : NULL; + + /* get correct fnmatch callback */ + compare = conn->data->set.fnmatch; + if(!compare) + compare = Curl_fnmatch; + + /* filter pattern-corresponding filenames */ + Curl_set_in_callback(conn->data, true); + if(compare(conn->data->set.fnmatch_data, wc->pattern, + finfo->filename) == 0) { + /* discard symlink which is containing multiple " -> " */ + if((finfo->filetype == CURLFILETYPE_SYMLINK) && finfo->strings.target && + (strstr(finfo->strings.target, " -> "))) { + add = FALSE; + } + } + else { + add = FALSE; + } + Curl_set_in_callback(conn->data, false); + + if(add) { + Curl_llist_insert_next(llist, llist->tail, finfo, &infop->list); + } + else { + Curl_fileinfo_cleanup(infop); + } + + ftpwc->parser->file_data = NULL; + return CURLE_OK; +} + +size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, + void *connptr) +{ + size_t bufflen = size*nmemb; + struct connectdata *conn = (struct connectdata *)connptr; + struct ftp_wc *ftpwc = conn->data->wildcard.protdata; + struct ftp_parselist_data *parser = ftpwc->parser; + struct fileinfo *infop; + struct curl_fileinfo *finfo; + unsigned long i = 0; + CURLcode result; + size_t retsize = bufflen; + + if(parser->error) { /* error in previous call */ + /* scenario: + * 1. call => OK.. + * 2. call => OUT_OF_MEMORY (or other error) + * 3. (last) call => is skipped RIGHT HERE and the error is hadled later + * in wc_statemach() + */ + goto fail; + } + + if(parser->os_type == OS_TYPE_UNKNOWN && bufflen > 0) { + /* considering info about FILE response format */ + parser->os_type = (buffer[0] >= '0' && buffer[0] <= '9') ? + OS_TYPE_WIN_NT : OS_TYPE_UNIX; + } + + while(i < bufflen) { /* FSM */ + + char c = buffer[i]; + if(!parser->file_data) { /* tmp file data is not allocated yet */ + parser->file_data = Curl_fileinfo_alloc(); + if(!parser->file_data) { + parser->error = CURLE_OUT_OF_MEMORY; + goto fail; + } + parser->file_data->info.b_data = malloc(FTP_BUFFER_ALLOCSIZE); + if(!parser->file_data->info.b_data) { + parser->error = CURLE_OUT_OF_MEMORY; + goto fail; + } + parser->file_data->info.b_size = FTP_BUFFER_ALLOCSIZE; + parser->item_offset = 0; + parser->item_length = 0; + } + + infop = parser->file_data; + finfo = &infop->info; + finfo->b_data[finfo->b_used++] = c; + + if(finfo->b_used >= finfo->b_size - 1) { + /* if it is important, extend buffer space for file data */ + char *tmp = realloc(finfo->b_data, + finfo->b_size + FTP_BUFFER_ALLOCSIZE); + if(tmp) { + finfo->b_size += FTP_BUFFER_ALLOCSIZE; + finfo->b_data = tmp; + } + else { + Curl_fileinfo_cleanup(parser->file_data); + parser->file_data = NULL; + parser->error = CURLE_OUT_OF_MEMORY; + goto fail; + } + } + + switch(parser->os_type) { + case OS_TYPE_UNIX: + switch(parser->state.UNIX.main) { + case PL_UNIX_TOTALSIZE: + switch(parser->state.UNIX.sub.total_dirsize) { + case PL_UNIX_TOTALSIZE_INIT: + if(c == 't') { + parser->state.UNIX.sub.total_dirsize = PL_UNIX_TOTALSIZE_READING; + parser->item_length++; + } + else { + parser->state.UNIX.main = PL_UNIX_FILETYPE; + /* start FSM again not considering size of directory */ + finfo->b_used = 0; + continue; + } + break; + case PL_UNIX_TOTALSIZE_READING: + parser->item_length++; + if(c == '\r') { + parser->item_length--; + finfo->b_used--; + } + else if(c == '\n') { + finfo->b_data[parser->item_length - 1] = 0; + if(strncmp("total ", finfo->b_data, 6) == 0) { + char *endptr = finfo->b_data + 6; + /* here we can deal with directory size, pass the leading white + spaces and then the digits */ + while(ISSPACE(*endptr)) + endptr++; + while(ISDIGIT(*endptr)) + endptr++; + if(*endptr != 0) { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + parser->state.UNIX.main = PL_UNIX_FILETYPE; + finfo->b_used = 0; + } + else { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + } + break; + } + break; + case PL_UNIX_FILETYPE: + switch(c) { + case '-': + finfo->filetype = CURLFILETYPE_FILE; + break; + case 'd': + finfo->filetype = CURLFILETYPE_DIRECTORY; + break; + case 'l': + finfo->filetype = CURLFILETYPE_SYMLINK; + break; + case 'p': + finfo->filetype = CURLFILETYPE_NAMEDPIPE; + break; + case 's': + finfo->filetype = CURLFILETYPE_SOCKET; + break; + case 'c': + finfo->filetype = CURLFILETYPE_DEVICE_CHAR; + break; + case 'b': + finfo->filetype = CURLFILETYPE_DEVICE_BLOCK; + break; + case 'D': + finfo->filetype = CURLFILETYPE_DOOR; + break; + default: + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + parser->state.UNIX.main = PL_UNIX_PERMISSION; + parser->item_length = 0; + parser->item_offset = 1; + break; + case PL_UNIX_PERMISSION: + parser->item_length++; + if(parser->item_length <= 9) { + if(!strchr("rwx-tTsS", c)) { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + } + else if(parser->item_length == 10) { + unsigned int perm; + if(c != ' ') { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + finfo->b_data[10] = 0; /* terminate permissions */ + perm = ftp_pl_get_permission(finfo->b_data + parser->item_offset); + if(perm & FTP_LP_MALFORMATED_PERM) { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_PERM; + parser->file_data->info.perm = perm; + parser->offsets.perm = parser->item_offset; + + parser->item_length = 0; + parser->state.UNIX.main = PL_UNIX_HLINKS; + parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_PRESPACE; + } + break; + case PL_UNIX_HLINKS: + switch(parser->state.UNIX.sub.hlinks) { + case PL_UNIX_HLINKS_PRESPACE: + if(c != ' ') { + if(c >= '0' && c <= '9') { + parser->item_offset = finfo->b_used - 1; + parser->item_length = 1; + parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_NUMBER; + } + else { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + } + break; + case PL_UNIX_HLINKS_NUMBER: + parser->item_length ++; + if(c == ' ') { + char *p; + long int hlinks; + finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; + hlinks = strtol(finfo->b_data + parser->item_offset, &p, 10); + if(p[0] == '\0' && hlinks != LONG_MAX && hlinks != LONG_MIN) { + parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT; + parser->file_data->info.hardlinks = hlinks; + } + parser->item_length = 0; + parser->item_offset = 0; + parser->state.UNIX.main = PL_UNIX_USER; + parser->state.UNIX.sub.user = PL_UNIX_USER_PRESPACE; + } + else if(c < '0' || c > '9') { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + break; + } + break; + case PL_UNIX_USER: + switch(parser->state.UNIX.sub.user) { + case PL_UNIX_USER_PRESPACE: + if(c != ' ') { + parser->item_offset = finfo->b_used - 1; + parser->item_length = 1; + parser->state.UNIX.sub.user = PL_UNIX_USER_PARSING; + } + break; + case PL_UNIX_USER_PARSING: + parser->item_length++; + if(c == ' ') { + finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; + parser->offsets.user = parser->item_offset; + parser->state.UNIX.main = PL_UNIX_GROUP; + parser->state.UNIX.sub.group = PL_UNIX_GROUP_PRESPACE; + parser->item_offset = 0; + parser->item_length = 0; + } + break; + } + break; + case PL_UNIX_GROUP: + switch(parser->state.UNIX.sub.group) { + case PL_UNIX_GROUP_PRESPACE: + if(c != ' ') { + parser->item_offset = finfo->b_used - 1; + parser->item_length = 1; + parser->state.UNIX.sub.group = PL_UNIX_GROUP_NAME; + } + break; + case PL_UNIX_GROUP_NAME: + parser->item_length++; + if(c == ' ') { + finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; + parser->offsets.group = parser->item_offset; + parser->state.UNIX.main = PL_UNIX_SIZE; + parser->state.UNIX.sub.size = PL_UNIX_SIZE_PRESPACE; + parser->item_offset = 0; + parser->item_length = 0; + } + break; + } + break; + case PL_UNIX_SIZE: + switch(parser->state.UNIX.sub.size) { + case PL_UNIX_SIZE_PRESPACE: + if(c != ' ') { + if(c >= '0' && c <= '9') { + parser->item_offset = finfo->b_used - 1; + parser->item_length = 1; + parser->state.UNIX.sub.size = PL_UNIX_SIZE_NUMBER; + } + else { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + } + break; + case PL_UNIX_SIZE_NUMBER: + parser->item_length++; + if(c == ' ') { + char *p; + curl_off_t fsize; + finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; + if(!curlx_strtoofft(finfo->b_data + parser->item_offset, + &p, 10, &fsize)) { + if(p[0] == '\0' && fsize != CURL_OFF_T_MAX && + fsize != CURL_OFF_T_MIN) { + parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_SIZE; + parser->file_data->info.size = fsize; + } + parser->item_length = 0; + parser->item_offset = 0; + parser->state.UNIX.main = PL_UNIX_TIME; + parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART1; + } + } + else if(!ISDIGIT(c)) { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + break; + } + break; + case PL_UNIX_TIME: + switch(parser->state.UNIX.sub.time) { + case PL_UNIX_TIME_PREPART1: + if(c != ' ') { + if(ISALNUM(c)) { + parser->item_offset = finfo->b_used -1; + parser->item_length = 1; + parser->state.UNIX.sub.time = PL_UNIX_TIME_PART1; + } + else { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + } + break; + case PL_UNIX_TIME_PART1: + parser->item_length++; + if(c == ' ') { + parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART2; + } + else if(!ISALNUM(c) && c != '.') { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + break; + case PL_UNIX_TIME_PREPART2: + parser->item_length++; + if(c != ' ') { + if(ISALNUM(c)) { + parser->state.UNIX.sub.time = PL_UNIX_TIME_PART2; + } + else { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + } + break; + case PL_UNIX_TIME_PART2: + parser->item_length++; + if(c == ' ') { + parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART3; + } + else if(!ISALNUM(c) && c != '.') { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + break; + case PL_UNIX_TIME_PREPART3: + parser->item_length++; + if(c != ' ') { + if(ISALNUM(c)) { + parser->state.UNIX.sub.time = PL_UNIX_TIME_PART3; + } + else { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + } + break; + case PL_UNIX_TIME_PART3: + parser->item_length++; + if(c == ' ') { + finfo->b_data[parser->item_offset + parser->item_length -1] = 0; + parser->offsets.time = parser->item_offset; + /* + if(ftp_pl_gettime(parser, finfo->b_data + parser->item_offset)) { + parser->file_data->flags |= CURLFINFOFLAG_KNOWN_TIME; + } + */ + if(finfo->filetype == CURLFILETYPE_SYMLINK) { + parser->state.UNIX.main = PL_UNIX_SYMLINK; + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRESPACE; + } + else { + parser->state.UNIX.main = PL_UNIX_FILENAME; + parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_PRESPACE; + } + } + else if(!ISALNUM(c) && c != '.' && c != ':') { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + break; + } + break; + case PL_UNIX_FILENAME: + switch(parser->state.UNIX.sub.filename) { + case PL_UNIX_FILENAME_PRESPACE: + if(c != ' ') { + parser->item_offset = finfo->b_used - 1; + parser->item_length = 1; + parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_NAME; + } + break; + case PL_UNIX_FILENAME_NAME: + parser->item_length++; + if(c == '\r') { + parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_WINDOWSEOL; + } + else if(c == '\n') { + finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; + parser->offsets.filename = parser->item_offset; + parser->state.UNIX.main = PL_UNIX_FILETYPE; + result = ftp_pl_insert_finfo(conn, infop); + if(result) { + parser->error = result; + goto fail; + } + } + break; + case PL_UNIX_FILENAME_WINDOWSEOL: + if(c == '\n') { + finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; + parser->offsets.filename = parser->item_offset; + parser->state.UNIX.main = PL_UNIX_FILETYPE; + result = ftp_pl_insert_finfo(conn, infop); + if(result) { + parser->error = result; + goto fail; + } + } + else { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + break; + } + break; + case PL_UNIX_SYMLINK: + switch(parser->state.UNIX.sub.symlink) { + case PL_UNIX_SYMLINK_PRESPACE: + if(c != ' ') { + parser->item_offset = finfo->b_used - 1; + parser->item_length = 1; + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; + } + break; + case PL_UNIX_SYMLINK_NAME: + parser->item_length++; + if(c == ' ') { + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET1; + } + else if(c == '\r' || c == '\n') { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + break; + case PL_UNIX_SYMLINK_PRETARGET1: + parser->item_length++; + if(c == '-') { + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET2; + } + else if(c == '\r' || c == '\n') { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + else { + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; + } + break; + case PL_UNIX_SYMLINK_PRETARGET2: + parser->item_length++; + if(c == '>') { + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET3; + } + else if(c == '\r' || c == '\n') { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + else { + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; + } + break; + case PL_UNIX_SYMLINK_PRETARGET3: + parser->item_length++; + if(c == ' ') { + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET4; + /* now place where is symlink following */ + finfo->b_data[parser->item_offset + parser->item_length - 4] = 0; + parser->offsets.filename = parser->item_offset; + parser->item_length = 0; + parser->item_offset = 0; + } + else if(c == '\r' || c == '\n') { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + else { + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; + } + break; + case PL_UNIX_SYMLINK_PRETARGET4: + if(c != '\r' && c != '\n') { + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_TARGET; + parser->item_offset = finfo->b_used - 1; + parser->item_length = 1; + } + else { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + break; + case PL_UNIX_SYMLINK_TARGET: + parser->item_length++; + if(c == '\r') { + parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_WINDOWSEOL; + } + else if(c == '\n') { + finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; + parser->offsets.symlink_target = parser->item_offset; + result = ftp_pl_insert_finfo(conn, infop); + if(result) { + parser->error = result; + goto fail; + } + parser->state.UNIX.main = PL_UNIX_FILETYPE; + } + break; + case PL_UNIX_SYMLINK_WINDOWSEOL: + if(c == '\n') { + finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; + parser->offsets.symlink_target = parser->item_offset; + result = ftp_pl_insert_finfo(conn, infop); + if(result) { + parser->error = result; + goto fail; + } + parser->state.UNIX.main = PL_UNIX_FILETYPE; + } + else { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + break; + } + break; + } + break; + case OS_TYPE_WIN_NT: + switch(parser->state.NT.main) { + case PL_WINNT_DATE: + parser->item_length++; + if(parser->item_length < 9) { + if(!strchr("0123456789-", c)) { /* only simple control */ + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + } + else if(parser->item_length == 9) { + if(c == ' ') { + parser->state.NT.main = PL_WINNT_TIME; + parser->state.NT.sub.time = PL_WINNT_TIME_PRESPACE; + } + else { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + } + else { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + break; + case PL_WINNT_TIME: + parser->item_length++; + switch(parser->state.NT.sub.time) { + case PL_WINNT_TIME_PRESPACE: + if(!ISSPACE(c)) { + parser->state.NT.sub.time = PL_WINNT_TIME_TIME; + } + break; + case PL_WINNT_TIME_TIME: + if(c == ' ') { + parser->offsets.time = parser->item_offset; + finfo->b_data[parser->item_offset + parser->item_length -1] = 0; + parser->state.NT.main = PL_WINNT_DIRORSIZE; + parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_PRESPACE; + parser->item_length = 0; + } + else if(!strchr("APM0123456789:", c)) { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + break; + } + break; + case PL_WINNT_DIRORSIZE: + switch(parser->state.NT.sub.dirorsize) { + case PL_WINNT_DIRORSIZE_PRESPACE: + if(c != ' ') { + parser->item_offset = finfo->b_used - 1; + parser->item_length = 1; + parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_CONTENT; + } + break; + case PL_WINNT_DIRORSIZE_CONTENT: + parser->item_length ++; + if(c == ' ') { + finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; + if(strcmp("", finfo->b_data + parser->item_offset) == 0) { + finfo->filetype = CURLFILETYPE_DIRECTORY; + finfo->size = 0; + } + else { + char *endptr; + if(curlx_strtoofft(finfo->b_data + + parser->item_offset, + &endptr, 10, &finfo->size)) { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + /* correct file type */ + parser->file_data->info.filetype = CURLFILETYPE_FILE; + } + + parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_SIZE; + parser->item_length = 0; + parser->state.NT.main = PL_WINNT_FILENAME; + parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE; + } + break; + } + break; + case PL_WINNT_FILENAME: + switch(parser->state.NT.sub.filename) { + case PL_WINNT_FILENAME_PRESPACE: + if(c != ' ') { + parser->item_offset = finfo->b_used -1; + parser->item_length = 1; + parser->state.NT.sub.filename = PL_WINNT_FILENAME_CONTENT; + } + break; + case PL_WINNT_FILENAME_CONTENT: + parser->item_length++; + if(c == '\r') { + parser->state.NT.sub.filename = PL_WINNT_FILENAME_WINEOL; + finfo->b_data[finfo->b_used - 1] = 0; + } + else if(c == '\n') { + parser->offsets.filename = parser->item_offset; + finfo->b_data[finfo->b_used - 1] = 0; + parser->offsets.filename = parser->item_offset; + result = ftp_pl_insert_finfo(conn, infop); + if(result) { + parser->error = result; + goto fail; + } + parser->state.NT.main = PL_WINNT_DATE; + parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE; + } + break; + case PL_WINNT_FILENAME_WINEOL: + if(c == '\n') { + parser->offsets.filename = parser->item_offset; + result = ftp_pl_insert_finfo(conn, infop); + if(result) { + parser->error = result; + goto fail; + } + parser->state.NT.main = PL_WINNT_DATE; + parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE; + } + else { + parser->error = CURLE_FTP_BAD_FILE_LIST; + goto fail; + } + break; + } + break; + } + break; + default: + retsize = bufflen + 1; + goto fail; + } + + i++; + } + return retsize; + +fail: + + /* Clean up any allocated memory. */ + if(parser->file_data) { + Curl_fileinfo_cleanup(parser->file_data); + parser->file_data = NULL; + } + + return retsize; +} + +#endif /* CURL_DISABLE_FTP */ diff --git a/libcurl/lib/ftplistparser.h b/libcurl/lib/ftplistparser.h new file mode 100644 index 0000000..8128887 --- /dev/null +++ b/libcurl/lib/ftplistparser.h @@ -0,0 +1,41 @@ +#ifndef HEADER_CURL_FTPLISTPARSER_H +#define HEADER_CURL_FTPLISTPARSER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifndef CURL_DISABLE_FTP + +/* WRITEFUNCTION callback for parsing LIST responses */ +size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, + void *connptr); + +struct ftp_parselist_data; /* defined inside ftplibparser.c */ + +CURLcode Curl_ftp_parselist_geterror(struct ftp_parselist_data *pl_data); + +struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void); + +void Curl_ftp_parselist_data_free(struct ftp_parselist_data **pl_data); + +#endif /* CURL_DISABLE_FTP */ +#endif /* HEADER_CURL_FTPLISTPARSER_H */ diff --git a/libcurl/lib/getenv.c b/libcurl/lib/getenv.c new file mode 100644 index 0000000..25e0ea3 --- /dev/null +++ b/libcurl/lib/getenv.c @@ -0,0 +1,54 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include +#include "curl_memory.h" + +#include "memdebug.h" + +static +char *GetEnv(const char *variable) +{ +#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)|| defined(_XBOX) + (void)variable; + return NULL; +#else +#ifdef WIN32 + char env[MAX_PATH]; /* MAX_PATH is from windef.h */ + char *temp = getenv(variable); + env[0] = '\0'; + if(temp != NULL) + ExpandEnvironmentStringsA(temp, env, sizeof(env)); + return (env[0] != '\0')?strdup(env):NULL; +#else + char *env = getenv(variable); + return (env && env[0])?strdup(env):NULL; +#endif +#endif +} + +char *curl_getenv(const char *v) +{ + return GetEnv(v); +} diff --git a/libcurl/lib/getinfo.c b/libcurl/lib/getinfo.c new file mode 100644 index 0000000..e118da8 --- /dev/null +++ b/libcurl/lib/getinfo.c @@ -0,0 +1,490 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "urldata.h" +#include "getinfo.h" + +#include "vtls/vtls.h" +#include "connect.h" /* Curl_getconnectinfo() */ +#include "progress.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Initialize statistical and informational data. + * + * This function is called in curl_easy_reset, curl_easy_duphandle and at the + * beginning of a perform session. It must reset the session-info variables, + * in particular all variables in struct PureInfo. + */ +CURLcode Curl_initinfo(struct Curl_easy *data) +{ + struct Progress *pro = &data->progress; + struct PureInfo *info = &data->info; + + pro->t_nslookup = 0; + pro->t_connect = 0; + pro->t_appconnect = 0; + pro->t_pretransfer = 0; + pro->t_starttransfer = 0; + pro->timespent = 0; + pro->t_redirect = 0; + pro->is_t_startransfer_set = false; + + info->httpcode = 0; + info->httpproxycode = 0; + info->httpversion = 0; + info->filetime = -1; /* -1 is an illegal time and thus means unknown */ + info->timecond = FALSE; + + info->header_size = 0; + info->request_size = 0; + info->proxyauthavail = 0; + info->httpauthavail = 0; + info->numconnects = 0; + + free(info->contenttype); + info->contenttype = NULL; + + free(info->wouldredirect); + info->wouldredirect = NULL; + + info->conn_primary_ip[0] = '\0'; + info->conn_local_ip[0] = '\0'; + info->conn_primary_port = 0; + info->conn_local_port = 0; + + info->conn_scheme = 0; + info->conn_protocol = 0; + +#ifdef USE_SSL + Curl_ssl_free_certinfo(data); +#endif + return CURLE_OK; +} + +static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info, + const char **param_charp) +{ + switch(info) { + case CURLINFO_EFFECTIVE_URL: + *param_charp = data->change.url?data->change.url:(char *)""; + break; + case CURLINFO_CONTENT_TYPE: + *param_charp = data->info.contenttype; + break; + case CURLINFO_PRIVATE: + *param_charp = (char *) data->set.private_data; + break; + case CURLINFO_FTP_ENTRY_PATH: + /* Return the entrypath string from the most recent connection. + This pointer was copied from the connectdata structure by FTP. + The actual string may be free()ed by subsequent libcurl calls so + it must be copied to a safer area before the next libcurl call. + Callers must never free it themselves. */ + *param_charp = data->state.most_recent_ftp_entrypath; + break; + case CURLINFO_REDIRECT_URL: + /* Return the URL this request would have been redirected to if that + option had been enabled! */ + *param_charp = data->info.wouldredirect; + break; + case CURLINFO_PRIMARY_IP: + /* Return the ip address of the most recent (primary) connection */ + *param_charp = data->info.conn_primary_ip; + break; + case CURLINFO_LOCAL_IP: + /* Return the source/local ip address of the most recent (primary) + connection */ + *param_charp = data->info.conn_local_ip; + break; + case CURLINFO_RTSP_SESSION_ID: + *param_charp = data->set.str[STRING_RTSP_SESSION_ID]; + break; + case CURLINFO_SCHEME: + *param_charp = data->info.conn_scheme; + break; + + default: + return CURLE_UNKNOWN_OPTION; + } + + return CURLE_OK; +} + +static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info, + long *param_longp) +{ + curl_socket_t sockfd; + + union { + unsigned long *to_ulong; + long *to_long; + } lptr; + + switch(info) { + case CURLINFO_RESPONSE_CODE: + *param_longp = data->info.httpcode; + break; + case CURLINFO_HTTP_CONNECTCODE: + *param_longp = data->info.httpproxycode; + break; + case CURLINFO_FILETIME: + if(data->info.filetime > LONG_MAX) + *param_longp = LONG_MAX; + else if(data->info.filetime < LONG_MIN) + *param_longp = LONG_MIN; + else + *param_longp = (long)data->info.filetime; + break; + case CURLINFO_HEADER_SIZE: + *param_longp = (long)data->info.header_size; + break; + case CURLINFO_REQUEST_SIZE: + *param_longp = (long)data->info.request_size; + break; + case CURLINFO_SSL_VERIFYRESULT: + *param_longp = data->set.ssl.certverifyresult; + break; + case CURLINFO_PROXY_SSL_VERIFYRESULT: + *param_longp = data->set.proxy_ssl.certverifyresult; + break; + case CURLINFO_REDIRECT_COUNT: + *param_longp = data->set.followlocation; + break; + case CURLINFO_HTTPAUTH_AVAIL: + lptr.to_long = param_longp; + *lptr.to_ulong = data->info.httpauthavail; + break; + case CURLINFO_PROXYAUTH_AVAIL: + lptr.to_long = param_longp; + *lptr.to_ulong = data->info.proxyauthavail; + break; + case CURLINFO_OS_ERRNO: + *param_longp = data->state.os_errno; + break; + case CURLINFO_NUM_CONNECTS: + *param_longp = data->info.numconnects; + break; + case CURLINFO_LASTSOCKET: + sockfd = Curl_getconnectinfo(data, NULL); + + /* note: this is not a good conversion for systems with 64 bit sockets and + 32 bit longs */ + if(sockfd != CURL_SOCKET_BAD) + *param_longp = (long)sockfd; + else + /* this interface is documented to return -1 in case of badness, which + may not be the same as the CURL_SOCKET_BAD value */ + *param_longp = -1; + break; + case CURLINFO_PRIMARY_PORT: + /* Return the (remote) port of the most recent (primary) connection */ + *param_longp = data->info.conn_primary_port; + break; + case CURLINFO_LOCAL_PORT: + /* Return the local port of the most recent (primary) connection */ + *param_longp = data->info.conn_local_port; + break; + case CURLINFO_CONDITION_UNMET: + /* return if the condition prevented the document to get transferred */ + *param_longp = data->info.timecond ? 1L : 0L; + break; + case CURLINFO_RTSP_CLIENT_CSEQ: + *param_longp = data->state.rtsp_next_client_CSeq; + break; + case CURLINFO_RTSP_SERVER_CSEQ: + *param_longp = data->state.rtsp_next_server_CSeq; + break; + case CURLINFO_RTSP_CSEQ_RECV: + *param_longp = data->state.rtsp_CSeq_recv; + break; + case CURLINFO_HTTP_VERSION: + switch(data->info.httpversion) { + case 10: + *param_longp = CURL_HTTP_VERSION_1_0; + break; + case 11: + *param_longp = CURL_HTTP_VERSION_1_1; + break; + case 20: + *param_longp = CURL_HTTP_VERSION_2_0; + break; + default: + *param_longp = CURL_HTTP_VERSION_NONE; + break; + } + break; + case CURLINFO_PROTOCOL: + *param_longp = data->info.conn_protocol; + break; + + default: + return CURLE_UNKNOWN_OPTION; + } + + return CURLE_OK; +} + +#define DOUBLE_SECS(x) (double)(x)/1000000 + +static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info, + curl_off_t *param_offt) +{ + switch(info) { + case CURLINFO_FILETIME_T: + *param_offt = (curl_off_t)data->info.filetime; + break; + case CURLINFO_SIZE_UPLOAD_T: + *param_offt = data->progress.uploaded; + break; + case CURLINFO_SIZE_DOWNLOAD_T: + *param_offt = data->progress.downloaded; + break; + case CURLINFO_SPEED_DOWNLOAD_T: + *param_offt = data->progress.dlspeed; + break; + case CURLINFO_SPEED_UPLOAD_T: + *param_offt = data->progress.ulspeed; + break; + case CURLINFO_CONTENT_LENGTH_DOWNLOAD_T: + *param_offt = (data->progress.flags & PGRS_DL_SIZE_KNOWN)? + data->progress.size_dl:-1; + break; + case CURLINFO_CONTENT_LENGTH_UPLOAD_T: + *param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)? + data->progress.size_ul:-1; + break; + case CURLINFO_TOTAL_TIME_T: + *param_offt = data->progress.timespent; + break; + case CURLINFO_NAMELOOKUP_TIME_T: + *param_offt = data->progress.t_nslookup; + break; + case CURLINFO_CONNECT_TIME_T: + *param_offt = data->progress.t_connect; + break; + case CURLINFO_APPCONNECT_TIME_T: + *param_offt = data->progress.t_appconnect; + break; + case CURLINFO_PRETRANSFER_TIME_T: + *param_offt = data->progress.t_pretransfer; + break; + case CURLINFO_STARTTRANSFER_TIME_T: + *param_offt = data->progress.t_starttransfer; + break; + case CURLINFO_REDIRECT_TIME_T: + *param_offt = data->progress.t_redirect; + break; + + default: + return CURLE_UNKNOWN_OPTION; + } + + return CURLE_OK; +} + +static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info, + double *param_doublep) +{ + switch(info) { + case CURLINFO_TOTAL_TIME: + *param_doublep = DOUBLE_SECS(data->progress.timespent); + break; + case CURLINFO_NAMELOOKUP_TIME: + *param_doublep = DOUBLE_SECS(data->progress.t_nslookup); + break; + case CURLINFO_CONNECT_TIME: + *param_doublep = DOUBLE_SECS(data->progress.t_connect); + break; + case CURLINFO_APPCONNECT_TIME: + *param_doublep = DOUBLE_SECS(data->progress.t_appconnect); + break; + case CURLINFO_PRETRANSFER_TIME: + *param_doublep = DOUBLE_SECS(data->progress.t_pretransfer); + break; + case CURLINFO_STARTTRANSFER_TIME: + *param_doublep = DOUBLE_SECS(data->progress.t_starttransfer); + break; + case CURLINFO_SIZE_UPLOAD: + *param_doublep = (double)data->progress.uploaded; + break; + case CURLINFO_SIZE_DOWNLOAD: + *param_doublep = (double)data->progress.downloaded; + break; + case CURLINFO_SPEED_DOWNLOAD: + *param_doublep = (double)data->progress.dlspeed; + break; + case CURLINFO_SPEED_UPLOAD: + *param_doublep = (double)data->progress.ulspeed; + break; + case CURLINFO_CONTENT_LENGTH_DOWNLOAD: + *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)? + (double)data->progress.size_dl:-1; + break; + case CURLINFO_CONTENT_LENGTH_UPLOAD: + *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)? + (double)data->progress.size_ul:-1; + break; + case CURLINFO_REDIRECT_TIME: + *param_doublep = DOUBLE_SECS(data->progress.t_redirect); + break; + + default: + return CURLE_UNKNOWN_OPTION; + } + + return CURLE_OK; +} + +static CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info, + struct curl_slist **param_slistp) +{ + union { + struct curl_certinfo *to_certinfo; + struct curl_slist *to_slist; + } ptr; + + switch(info) { + case CURLINFO_SSL_ENGINES: + *param_slistp = Curl_ssl_engines_list(data); + break; + case CURLINFO_COOKIELIST: + *param_slistp = Curl_cookie_list(data); + break; + case CURLINFO_CERTINFO: + /* Return the a pointer to the certinfo struct. Not really an slist + pointer but we can pretend it is here */ + ptr.to_certinfo = &data->info.certs; + *param_slistp = ptr.to_slist; + break; + case CURLINFO_TLS_SESSION: + case CURLINFO_TLS_SSL_PTR: + { + struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **) + param_slistp; + struct curl_tlssessioninfo *tsi = &data->tsi; +#ifdef USE_SSL + struct connectdata *conn = data->conn; +#endif + + *tsip = tsi; + tsi->backend = Curl_ssl_backend(); + tsi->internals = NULL; + +#ifdef USE_SSL + if(conn && tsi->backend != CURLSSLBACKEND_NONE) { + unsigned int i; + for(i = 0; i < (sizeof(conn->ssl) / sizeof(conn->ssl[0])); ++i) { + if(conn->ssl[i].use) { + tsi->internals = Curl_ssl->get_internals(&conn->ssl[i], info); + break; + } + } + } +#endif + } + break; + default: + return CURLE_UNKNOWN_OPTION; + } + + return CURLE_OK; +} + +static CURLcode getinfo_socket(struct Curl_easy *data, CURLINFO info, + curl_socket_t *param_socketp) +{ + switch(info) { + case CURLINFO_ACTIVESOCKET: + *param_socketp = Curl_getconnectinfo(data, NULL); + break; + default: + return CURLE_UNKNOWN_OPTION; + } + + return CURLE_OK; +} + +CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...) +{ + va_list arg; + long *param_longp = NULL; + double *param_doublep = NULL; + curl_off_t *param_offt = NULL; + const char **param_charp = NULL; + struct curl_slist **param_slistp = NULL; + curl_socket_t *param_socketp = NULL; + int type; + CURLcode result = CURLE_UNKNOWN_OPTION; + + if(!data) + return result; + + va_start(arg, info); + + type = CURLINFO_TYPEMASK & (int)info; + switch(type) { + case CURLINFO_STRING: + param_charp = va_arg(arg, const char **); + if(param_charp) + result = getinfo_char(data, info, param_charp); + break; + case CURLINFO_LONG: + param_longp = va_arg(arg, long *); + if(param_longp) + result = getinfo_long(data, info, param_longp); + break; + case CURLINFO_DOUBLE: + param_doublep = va_arg(arg, double *); + if(param_doublep) + result = getinfo_double(data, info, param_doublep); + break; + case CURLINFO_OFF_T: + param_offt = va_arg(arg, curl_off_t *); + if(param_offt) + result = getinfo_offt(data, info, param_offt); + break; + case CURLINFO_SLIST: + param_slistp = va_arg(arg, struct curl_slist **); + if(param_slistp) + result = getinfo_slist(data, info, param_slistp); + break; + case CURLINFO_SOCKET: + param_socketp = va_arg(arg, curl_socket_t *); + if(param_socketp) + result = getinfo_socket(data, info, param_socketp); + break; + default: + break; + } + + va_end(arg); + + return result; +} diff --git a/libcurl/lib/getinfo.h b/libcurl/lib/getinfo.h new file mode 100644 index 0000000..aecf717 --- /dev/null +++ b/libcurl/lib/getinfo.h @@ -0,0 +1,27 @@ +#ifndef HEADER_CURL_GETINFO_H +#define HEADER_CURL_GETINFO_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...); +CURLcode Curl_initinfo(struct Curl_easy *data); + +#endif /* HEADER_CURL_GETINFO_H */ diff --git a/libcurl/lib/gopher.c b/libcurl/lib/gopher.c new file mode 100644 index 0000000..b296c62 --- /dev/null +++ b/libcurl/lib/gopher.c @@ -0,0 +1,174 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_GOPHER + +#include "urldata.h" +#include +#include "transfer.h" +#include "sendf.h" +#include "progress.h" +#include "gopher.h" +#include "select.h" +#include "strdup.h" +#include "url.h" +#include "escape.h" +#include "warnless.h" +#include "curl_printf.h" +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* + * Forward declarations. + */ + +static CURLcode gopher_do(struct connectdata *conn, bool *done); + +/* + * Gopher protocol handler. + * This is also a nice simple template to build off for simple + * connect-command-download protocols. + */ + +const struct Curl_handler Curl_handler_gopher = { + "GOPHER", /* scheme */ + ZERO_NULL, /* setup_connection */ + gopher_do, /* do_it */ + ZERO_NULL, /* done */ + ZERO_NULL, /* do_more */ + ZERO_NULL, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_GOPHER, /* defport */ + CURLPROTO_GOPHER, /* protocol */ + PROTOPT_NONE /* flags */ +}; + +static CURLcode gopher_do(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; + char *gopherpath; + char *path = data->state.up.path; + char *query = data->state.up.query; + char *sel = NULL; + char *sel_org = NULL; + ssize_t amount, k; + size_t len; + + *done = TRUE; /* unconditionally */ + + /* path is guaranteed non-NULL */ + DEBUGASSERT(path); + + if(query) + gopherpath = aprintf("%s?%s", path, query); + else + gopherpath = strdup(path); + + if(!gopherpath) + return CURLE_OUT_OF_MEMORY; + + /* Create selector. Degenerate cases: / and /1 => convert to "" */ + if(strlen(gopherpath) <= 2) { + sel = (char *)""; + len = strlen(sel); + free(gopherpath); + } + else { + char *newp; + + /* Otherwise, drop / and the first character (i.e., item type) ... */ + newp = gopherpath; + newp += 2; + + /* ... and finally unescape */ + result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE); + free(gopherpath); + if(result) + return result; + sel_org = sel; + } + + /* We use Curl_write instead of Curl_sendf to make sure the entire buffer is + sent, which could be sizeable with long selectors. */ + k = curlx_uztosz(len); + + for(;;) { + result = Curl_write(conn, sockfd, sel, k, &amount); + if(!result) { /* Which may not have written it all! */ + result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount); + if(result) + break; + + k -= amount; + sel += amount; + if(k < 1) + break; /* but it did write it all */ + } + else + break; + + /* Don't busyloop. The entire loop thing is a work-around as it causes a + BLOCKING behavior which is a NO-NO. This function should rather be + split up in a do and a doing piece where the pieces that aren't + possible to send now will be sent in the doing function repeatedly + until the entire request is sent. + + Wait a while for the socket to be writable. Note that this doesn't + acknowledge the timeout. + */ + if(SOCKET_WRITABLE(sockfd, 100) < 0) { + result = CURLE_SEND_ERROR; + break; + } + } + + free(sel_org); + + if(!result) + /* We can use Curl_sendf to send the terminal \r\n relatively safely and + save allocing another string/doing another _write loop. */ + result = Curl_sendf(sockfd, conn, "\r\n"); + if(result) { + failf(data, "Failed sending Gopher request"); + return result; + } + result = Curl_client_write(conn, CLIENTWRITE_HEADER, (char *)"\r\n", 2); + if(result) + return result; + + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); + return CURLE_OK; +} +#endif /*CURL_DISABLE_GOPHER*/ diff --git a/libcurl/lib/gopher.h b/libcurl/lib/gopher.h new file mode 100644 index 0000000..501c990 --- /dev/null +++ b/libcurl/lib/gopher.h @@ -0,0 +1,29 @@ +#ifndef HEADER_CURL_GOPHER_H +#define HEADER_CURL_GOPHER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#ifndef CURL_DISABLE_GOPHER +extern const struct Curl_handler Curl_handler_gopher; +#endif + +#endif /* HEADER_CURL_GOPHER_H */ diff --git a/libcurl/lib/hash.c b/libcurl/lib/hash.c new file mode 100644 index 0000000..421d68f --- /dev/null +++ b/libcurl/lib/hash.c @@ -0,0 +1,351 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "hash.h" +#include "llist.h" +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +static void +hash_element_dtor(void *user, void *element) +{ + struct curl_hash *h = (struct curl_hash *) user; + struct curl_hash_element *e = (struct curl_hash_element *) element; + + if(e->ptr) { + h->dtor(e->ptr); + e->ptr = NULL; + } + + e->key_len = 0; + + free(e); +} + +/* Initializes a hash structure. + * Return 1 on error, 0 is fine. + * + * @unittest: 1602 + * @unittest: 1603 + */ +int +Curl_hash_init(struct curl_hash *h, + int slots, + hash_function hfunc, + comp_function comparator, + curl_hash_dtor dtor) +{ + if(!slots || !hfunc || !comparator ||!dtor) { + return 1; /* failure */ + } + + h->hash_func = hfunc; + h->comp_func = comparator; + h->dtor = dtor; + h->size = 0; + h->slots = slots; + + h->table = malloc(slots * sizeof(struct curl_llist)); + if(h->table) { + int i; + for(i = 0; i < slots; ++i) + Curl_llist_init(&h->table[i], (curl_llist_dtor) hash_element_dtor); + return 0; /* fine */ + } + h->slots = 0; + return 1; /* failure */ +} + +static struct curl_hash_element * +mk_hash_element(const void *key, size_t key_len, const void *p) +{ + /* allocate the struct plus memory after it to store the key */ + struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element) + + key_len); + if(he) { + /* copy the key */ + memcpy(he->key, key, key_len); + he->key_len = key_len; + he->ptr = (void *) p; + } + return he; +} + +#define FETCH_LIST(x,y,z) &x->table[x->hash_func(y, z, x->slots)] + +/* Insert the data in the hash. If there already was a match in the hash, + * that data is replaced. + * + * @unittest: 1305 + * @unittest: 1602 + * @unittest: 1603 + */ +void * +Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p) +{ + struct curl_hash_element *he; + struct curl_llist_element *le; + struct curl_llist *l = FETCH_LIST(h, key, key_len); + + for(le = l->head; le; le = le->next) { + he = (struct curl_hash_element *) le->ptr; + if(h->comp_func(he->key, he->key_len, key, key_len)) { + Curl_llist_remove(l, le, (void *)h); + --h->size; + break; + } + } + + he = mk_hash_element(key, key_len, p); + if(he) { + Curl_llist_insert_next(l, l->tail, he, &he->list); + ++h->size; + return p; /* return the new entry */ + } + + return NULL; /* failure */ +} + +/* Remove the identified hash entry. + * Returns non-zero on failure. + * + * @unittest: 1603 + */ +int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len) +{ + struct curl_llist_element *le; + struct curl_llist *l = FETCH_LIST(h, key, key_len); + + for(le = l->head; le; le = le->next) { + struct curl_hash_element *he = le->ptr; + if(h->comp_func(he->key, he->key_len, key, key_len)) { + Curl_llist_remove(l, le, (void *) h); + --h->size; + return 0; + } + } + return 1; +} + +/* Retrieves a hash element. + * + * @unittest: 1603 + */ +void * +Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len) +{ + struct curl_llist_element *le; + struct curl_llist *l; + + if(h) { + l = FETCH_LIST(h, key, key_len); + for(le = l->head; le; le = le->next) { + struct curl_hash_element *he = le->ptr; + if(h->comp_func(he->key, he->key_len, key, key_len)) { + return he->ptr; + } + } + } + + return NULL; +} + +#if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST) +void +Curl_hash_apply(curl_hash *h, void *user, + void (*cb)(void *user, void *ptr)) +{ + struct curl_llist_element *le; + int i; + + for(i = 0; i < h->slots; ++i) { + for(le = (h->table[i])->head; + le; + le = le->next) { + curl_hash_element *el = le->ptr; + cb(user, el->ptr); + } + } +} +#endif + +/* Destroys all the entries in the given hash and resets its attributes, + * prepping the given hash for [static|dynamic] deallocation. + * + * @unittest: 1305 + * @unittest: 1602 + * @unittest: 1603 + */ +void +Curl_hash_destroy(struct curl_hash *h) +{ + int i; + + for(i = 0; i < h->slots; ++i) { + Curl_llist_destroy(&h->table[i], (void *) h); + } + + Curl_safefree(h->table); + h->size = 0; + h->slots = 0; +} + +/* Removes all the entries in the given hash. + * + * @unittest: 1602 + */ +void +Curl_hash_clean(struct curl_hash *h) +{ + Curl_hash_clean_with_criterium(h, NULL, NULL); +} + +/* Cleans all entries that pass the comp function criteria. */ +void +Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, + int (*comp)(void *, void *)) +{ + struct curl_llist_element *le; + struct curl_llist_element *lnext; + struct curl_llist *list; + int i; + + if(!h) + return; + + for(i = 0; i < h->slots; ++i) { + list = &h->table[i]; + le = list->head; /* get first list entry */ + while(le) { + struct curl_hash_element *he = le->ptr; + lnext = le->next; + /* ask the callback function if we shall remove this entry or not */ + if(comp == NULL || comp(user, he->ptr)) { + Curl_llist_remove(list, le, (void *) h); + --h->size; /* one less entry in the hash now */ + } + le = lnext; + } + } +} + +size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num) +{ + const char *key_str = (const char *) key; + const char *end = key_str + key_length; + size_t h = 5381; + + while(key_str < end) { + h += h << 5; + h ^= *key_str++; + } + + return (h % slots_num); +} + +size_t Curl_str_key_compare(void *k1, size_t key1_len, + void *k2, size_t key2_len) +{ + if((key1_len == key2_len) && !memcmp(k1, k2, key1_len)) + return 1; + + return 0; +} + +void Curl_hash_start_iterate(struct curl_hash *hash, + struct curl_hash_iterator *iter) +{ + iter->hash = hash; + iter->slot_index = 0; + iter->current_element = NULL; +} + +struct curl_hash_element * +Curl_hash_next_element(struct curl_hash_iterator *iter) +{ + struct curl_hash *h = iter->hash; + + /* Get the next element in the current list, if any */ + if(iter->current_element) + iter->current_element = iter->current_element->next; + + /* If we have reached the end of the list, find the next one */ + if(!iter->current_element) { + int i; + for(i = iter->slot_index; i < h->slots; i++) { + if(h->table[i].head) { + iter->current_element = h->table[i].head; + iter->slot_index = i + 1; + break; + } + } + } + + if(iter->current_element) { + struct curl_hash_element *he = iter->current_element->ptr; + return he; + } + iter->current_element = NULL; + return NULL; +} + +#if 0 /* useful function for debugging hashes and their contents */ +void Curl_hash_print(struct curl_hash *h, + void (*func)(void *)) +{ + struct curl_hash_iterator iter; + struct curl_hash_element *he; + int last_index = -1; + + if(!h) + return; + + fprintf(stderr, "=Hash dump=\n"); + + Curl_hash_start_iterate(h, &iter); + + he = Curl_hash_next_element(&iter); + while(he) { + if(iter.slot_index != last_index) { + fprintf(stderr, "index %d:", iter.slot_index); + if(last_index >= 0) { + fprintf(stderr, "\n"); + } + last_index = iter.slot_index; + } + + if(func) + func(he->ptr); + else + fprintf(stderr, " [%p]", (void *)he->ptr); + + he = Curl_hash_next_element(&iter); + } + fprintf(stderr, "\n"); +} +#endif diff --git a/libcurl/lib/hash.h b/libcurl/lib/hash.h new file mode 100644 index 0000000..558d0f4 --- /dev/null +++ b/libcurl/lib/hash.h @@ -0,0 +1,100 @@ +#ifndef HEADER_CURL_HASH_H +#define HEADER_CURL_HASH_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "llist.h" + +/* Hash function prototype */ +typedef size_t (*hash_function) (void *key, + size_t key_length, + size_t slots_num); + +/* + Comparator function prototype. Compares two keys. +*/ +typedef size_t (*comp_function) (void *key1, + size_t key1_len, + void *key2, + size_t key2_len); + +typedef void (*curl_hash_dtor)(void *); + +struct curl_hash { + struct curl_llist *table; + + /* Hash function to be used for this hash table */ + hash_function hash_func; + + /* Comparator function to compare keys */ + comp_function comp_func; + curl_hash_dtor dtor; + int slots; + size_t size; +}; + +struct curl_hash_element { + struct curl_llist_element list; + void *ptr; + size_t key_len; + char key[1]; /* allocated memory following the struct */ +}; + +struct curl_hash_iterator { + struct curl_hash *hash; + int slot_index; + struct curl_llist_element *current_element; +}; + +int Curl_hash_init(struct curl_hash *h, + int slots, + hash_function hfunc, + comp_function comparator, + curl_hash_dtor dtor); + +void *Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p); +int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len); +void *Curl_hash_pick(struct curl_hash *, void *key, size_t key_len); +void Curl_hash_apply(struct curl_hash *h, void *user, + void (*cb)(void *user, void *ptr)); +#define Curl_hash_count(h) ((h)->size) +void Curl_hash_destroy(struct curl_hash *h); +void Curl_hash_clean(struct curl_hash *h); +void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, + int (*comp)(void *, void *)); +size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num); +size_t Curl_str_key_compare(void *k1, size_t key1_len, void *k2, + size_t key2_len); +void Curl_hash_start_iterate(struct curl_hash *hash, + struct curl_hash_iterator *iter); +struct curl_hash_element * +Curl_hash_next_element(struct curl_hash_iterator *iter); + +void Curl_hash_print(struct curl_hash *h, + void (*func)(void *)); + + +#endif /* HEADER_CURL_HASH_H */ diff --git a/libcurl/lib/hmac.c b/libcurl/lib/hmac.c new file mode 100644 index 0000000..bf49ebe --- /dev/null +++ b/libcurl/lib/hmac.c @@ -0,0 +1,132 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC2104 Keyed-Hashing for Message Authentication + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_CRYPTO_AUTH + +#include + +#include "curl_hmac.h" +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +/* + * Generic HMAC algorithm. + * + * This module computes HMAC digests based on any hash function. Parameters + * and computing procedures are set-up dynamically at HMAC computation + * context initialisation. + */ + +static const unsigned char hmac_ipad = 0x36; +static const unsigned char hmac_opad = 0x5C; + + + +HMAC_context * +Curl_HMAC_init(const HMAC_params * hashparams, + const unsigned char *key, + unsigned int keylen) +{ + size_t i; + HMAC_context *ctxt; + unsigned char *hkey; + unsigned char b; + + /* Create HMAC context. */ + i = sizeof(*ctxt) + 2 * hashparams->hmac_ctxtsize + + hashparams->hmac_resultlen; + ctxt = malloc(i); + + if(!ctxt) + return ctxt; + + ctxt->hmac_hash = hashparams; + ctxt->hmac_hashctxt1 = (void *) (ctxt + 1); + ctxt->hmac_hashctxt2 = (void *) ((char *) ctxt->hmac_hashctxt1 + + hashparams->hmac_ctxtsize); + + /* If the key is too long, replace it by its hash digest. */ + if(keylen > hashparams->hmac_maxkeylen) { + (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1); + (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, key, keylen); + hkey = (unsigned char *) ctxt->hmac_hashctxt2 + hashparams->hmac_ctxtsize; + (*hashparams->hmac_hfinal)(hkey, ctxt->hmac_hashctxt1); + key = hkey; + keylen = hashparams->hmac_resultlen; + } + + /* Prime the two hash contexts with the modified key. */ + (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1); + (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt2); + + for(i = 0; i < keylen; i++) { + b = (unsigned char)(*key ^ hmac_ipad); + (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &b, 1); + b = (unsigned char)(*key++ ^ hmac_opad); + (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &b, 1); + } + + for(; i < hashparams->hmac_maxkeylen; i++) { + (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &hmac_ipad, 1); + (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &hmac_opad, 1); + } + + /* Done, return pointer to HMAC context. */ + return ctxt; +} + +int Curl_HMAC_update(HMAC_context * ctxt, + const unsigned char *data, + unsigned int len) +{ + /* Update first hash calculation. */ + (*ctxt->hmac_hash->hmac_hupdate)(ctxt->hmac_hashctxt1, data, len); + return 0; +} + + +int Curl_HMAC_final(HMAC_context *ctxt, unsigned char *result) +{ + const HMAC_params * hashparams = ctxt->hmac_hash; + + /* Do not get result if called with a null parameter: only release + storage. */ + + if(!result) + result = (unsigned char *) ctxt->hmac_hashctxt2 + + ctxt->hmac_hash->hmac_ctxtsize; + + (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt1); + (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, + result, hashparams->hmac_resultlen); + (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt2); + free((char *) ctxt); + return 0; +} + +#endif /* CURL_DISABLE_CRYPTO_AUTH */ diff --git a/libcurl/lib/hostasyn.c b/libcurl/lib/hostasyn.c new file mode 100644 index 0000000..99d872b --- /dev/null +++ b/libcurl/lib/hostasyn.c @@ -0,0 +1,128 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +/*********************************************************************** + * Only for builds using asynchronous name resolves + **********************************************************************/ +#ifdef CURLRES_ASYNCH + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#ifdef HAVE_PROCESS_H +#include +#endif + +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "hash.h" +#include "share.h" +#include "strerror.h" +#include "url.h" +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* + * Curl_addrinfo_callback() gets called by ares, gethostbyname_thread() + * or getaddrinfo_thread() when we got the name resolved (or not!). + * + * If the status argument is CURL_ASYNC_SUCCESS, this function takes + * ownership of the Curl_addrinfo passed, storing the resolved data + * in the DNS cache. + * + * The storage operation locks and unlocks the DNS cache. + */ +CURLcode Curl_addrinfo_callback(struct connectdata *conn, + int status, + struct Curl_addrinfo *ai) +{ + struct Curl_dns_entry *dns = NULL; + CURLcode result = CURLE_OK; + + conn->async.status = status; + + if(CURL_ASYNC_SUCCESS == status) { + if(ai) { + struct Curl_easy *data = conn->data; + + if(data->share) + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + + dns = Curl_cache_addr(data, ai, + conn->async.hostname, + conn->async.port); + if(data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + + if(!dns) { + /* failed to store, cleanup and return error */ + Curl_freeaddrinfo(ai); + result = CURLE_OUT_OF_MEMORY; + } + } + else { + result = CURLE_OUT_OF_MEMORY; + } + } + + conn->async.dns = dns; + + /* Set async.done TRUE last in this function since it may be used multi- + threaded and once this is TRUE the other thread may read fields from the + async struct */ + conn->async.done = TRUE; + + /* IPv4: The input hostent struct will be freed by ares when we return from + this function */ + return result; +} + +/* + * Curl_getaddrinfo() is the generic low-level name resolve API within this + * source file. There are several versions of this function - for different + * name resolve layers (selected at build-time). They all take this same set + * of arguments + */ +Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, + const char *hostname, + int port, + int *waitp) +{ + return Curl_resolver_getaddrinfo(conn, hostname, port, waitp); +} + +#endif /* CURLRES_ASYNCH */ diff --git a/libcurl/lib/hostcheck.c b/libcurl/lib/hostcheck.c new file mode 100644 index 0000000..115d24b --- /dev/null +++ b/libcurl/lib/hostcheck.c @@ -0,0 +1,150 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_OPENSSL) \ + || defined(USE_GSKIT) \ + || defined(USE_SCHANNEL) +/* these backends use functions from this file */ + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETINET_IN6_H +#include +#endif + +#include "hostcheck.h" +#include "strcase.h" +#include "inet_pton.h" + +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* + * Match a hostname against a wildcard pattern. + * E.g. + * "foo.host.com" matches "*.host.com". + * + * We use the matching rule described in RFC6125, section 6.4.3. + * https://tools.ietf.org/html/rfc6125#section-6.4.3 + * + * In addition: ignore trailing dots in the host names and wildcards, so that + * the names are used normalized. This is what the browsers do. + * + * Do not allow wildcard matching on IP numbers. There are apparently + * certificates being used with an IP address in the CN field, thus making no + * apparent distinction between a name and an IP. We need to detect the use of + * an IP address and not wildcard match on such names. + * + * NOTE: hostmatch() gets called with copied buffers so that it can modify the + * contents at will. + */ + +static int hostmatch(char *hostname, char *pattern) +{ + const char *pattern_label_end, *pattern_wildcard, *hostname_label_end; + int wildcard_enabled; + size_t prefixlen, suffixlen; + struct in_addr ignored; +#ifdef ENABLE_IPV6 + struct sockaddr_in6 si6; +#endif + + /* normalize pattern and hostname by stripping off trailing dots */ + size_t len = strlen(hostname); + if(hostname[len-1]=='.') + hostname[len-1] = 0; + len = strlen(pattern); + if(pattern[len-1]=='.') + pattern[len-1] = 0; + + pattern_wildcard = strchr(pattern, '*'); + if(pattern_wildcard == NULL) + return strcasecompare(pattern, hostname) ? + CURL_HOST_MATCH : CURL_HOST_NOMATCH; + + /* detect IP address as hostname and fail the match if so */ + if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0) + return CURL_HOST_NOMATCH; +#ifdef ENABLE_IPV6 + if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0) + return CURL_HOST_NOMATCH; +#endif + + /* We require at least 2 dots in pattern to avoid too wide wildcard + match. */ + wildcard_enabled = 1; + pattern_label_end = strchr(pattern, '.'); + if(pattern_label_end == NULL || strchr(pattern_label_end + 1, '.') == NULL || + pattern_wildcard > pattern_label_end || + strncasecompare(pattern, "xn--", 4)) { + wildcard_enabled = 0; + } + if(!wildcard_enabled) + return strcasecompare(pattern, hostname) ? + CURL_HOST_MATCH : CURL_HOST_NOMATCH; + + hostname_label_end = strchr(hostname, '.'); + if(hostname_label_end == NULL || + !strcasecompare(pattern_label_end, hostname_label_end)) + return CURL_HOST_NOMATCH; + + /* The wildcard must match at least one character, so the left-most + label of the hostname is at least as large as the left-most label + of the pattern. */ + if(hostname_label_end - hostname < pattern_label_end - pattern) + return CURL_HOST_NOMATCH; + + prefixlen = pattern_wildcard - pattern; + suffixlen = pattern_label_end - (pattern_wildcard + 1); + return strncasecompare(pattern, hostname, prefixlen) && + strncasecompare(pattern_wildcard + 1, hostname_label_end - suffixlen, + suffixlen) ? + CURL_HOST_MATCH : CURL_HOST_NOMATCH; +} + +int Curl_cert_hostcheck(const char *match_pattern, const char *hostname) +{ + int res = 0; + if(!match_pattern || !*match_pattern || + !hostname || !*hostname) /* sanity check */ + ; + else { + char *matchp = strdup(match_pattern); + if(matchp) { + char *hostp = strdup(hostname); + if(hostp) { + if(hostmatch(hostp, matchp) == CURL_HOST_MATCH) + res = 1; + free(hostp); + } + free(matchp); + } + } + + return res; +} + +#endif /* OPENSSL, GSKIT or schannel+wince */ diff --git a/libcurl/lib/hostcheck.h b/libcurl/lib/hostcheck.h new file mode 100644 index 0000000..f562df9 --- /dev/null +++ b/libcurl/lib/hostcheck.h @@ -0,0 +1,31 @@ +#ifndef HEADER_CURL_HOSTCHECK_H +#define HEADER_CURL_HOSTCHECK_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include + +#define CURL_HOST_NOMATCH 0 +#define CURL_HOST_MATCH 1 +int Curl_cert_hostcheck(const char *match_pattern, const char *hostname); + +#endif /* HEADER_CURL_HOSTCHECK_H */ diff --git a/libcurl/lib/hostip.c b/libcurl/lib/hostip.c new file mode 100644 index 0000000..609d809 --- /dev/null +++ b/libcurl/lib/hostip.c @@ -0,0 +1,1071 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETINET_IN6_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#ifdef HAVE_SETJMP_H +#include +#endif +#ifdef HAVE_SIGNAL_H +#include +#endif + +#ifdef HAVE_PROCESS_H +#include +#endif + +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "hash.h" +#include "rand.h" +#include "share.h" +#include "strerror.h" +#include "url.h" +#include "inet_ntop.h" +#include "multiif.h" +#include "doh.h" +#include "warnless.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#if defined(CURLRES_SYNCH) && \ + defined(HAVE_ALARM) && defined(SIGALRM) && defined(HAVE_SIGSETJMP) +/* alarm-based timeouts can only be used with all the dependencies satisfied */ +#define USE_ALARM_TIMEOUT +#endif + +#define MAX_HOSTCACHE_LEN (255 + 7) /* max FQDN + colon + port number + zero */ + +/* + * hostip.c explained + * ================== + * + * The main COMPILE-TIME DEFINES to keep in mind when reading the host*.c + * source file are these: + * + * CURLRES_IPV6 - this host has getaddrinfo() and family, and thus we use + * that. The host may not be able to resolve IPv6, but we don't really have to + * take that into account. Hosts that aren't IPv6-enabled have CURLRES_IPV4 + * defined. + * + * CURLRES_ARES - is defined if libcurl is built to use c-ares for + * asynchronous name resolves. This can be Windows or *nix. + * + * CURLRES_THREADED - is defined if libcurl is built to run under (native) + * Windows, and then the name resolve will be done in a new thread, and the + * supported API will be the same as for ares-builds. + * + * If any of the two previous are defined, CURLRES_ASYNCH is defined too. If + * libcurl is not built to use an asynchronous resolver, CURLRES_SYNCH is + * defined. + * + * The host*.c sources files are split up like this: + * + * hostip.c - method-independent resolver functions and utility functions + * hostasyn.c - functions for asynchronous name resolves + * hostsyn.c - functions for synchronous name resolves + * hostip4.c - IPv4 specific functions + * hostip6.c - IPv6 specific functions + * + * The two asynchronous name resolver backends are implemented in: + * asyn-ares.c - functions for ares-using name resolves + * asyn-thread.c - functions for threaded name resolves + + * The hostip.h is the united header file for all this. It defines the + * CURLRES_* defines based on the config*.h and curl_setup.h defines. + */ + +static void freednsentry(void *freethis); + +/* + * Return # of addresses in a Curl_addrinfo struct + */ +int Curl_num_addresses(const Curl_addrinfo *addr) +{ + int i = 0; + while(addr) { + addr = addr->ai_next; + i++; + } + return i; +} + +/* + * Curl_printable_address() returns a printable version of the 1st address + * given in the 'ai' argument. The result will be stored in the buf that is + * bufsize bytes big. + * + * If the conversion fails, it returns NULL. + */ +const char * +Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize) +{ + const struct sockaddr_in *sa4; + const struct in_addr *ipaddr4; +#ifdef ENABLE_IPV6 + const struct sockaddr_in6 *sa6; + const struct in6_addr *ipaddr6; +#endif + + switch(ai->ai_family) { + case AF_INET: + sa4 = (const void *)ai->ai_addr; + ipaddr4 = &sa4->sin_addr; + return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf, + bufsize); +#ifdef ENABLE_IPV6 + case AF_INET6: + sa6 = (const void *)ai->ai_addr; + ipaddr6 = &sa6->sin6_addr; + return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf, + bufsize); +#endif + default: + break; + } + return NULL; +} + +/* + * Create a hostcache id string for the provided host + port, to be used by + * the DNS caching. Without alloc. + */ +static void +create_hostcache_id(const char *name, int port, char *ptr, size_t buflen) +{ + size_t len = strlen(name); + if(len > (buflen - 7)) + len = buflen - 7; + /* store and lower case the name */ + while(len--) + *ptr++ = (char)TOLOWER(*name++); + msnprintf(ptr, 7, ":%u", port); +} + +struct hostcache_prune_data { + long cache_timeout; + time_t now; +}; + +/* + * This function is set as a callback to be called for every entry in the DNS + * cache when we want to prune old unused entries. + * + * Returning non-zero means remove the entry, return 0 to keep it in the + * cache. + */ +static int +hostcache_timestamp_remove(void *datap, void *hc) +{ + struct hostcache_prune_data *data = + (struct hostcache_prune_data *) datap; + struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc; + + return (0 != c->timestamp) + && (data->now - c->timestamp >= data->cache_timeout); +} + +/* + * Prune the DNS cache. This assumes that a lock has already been taken. + */ +static void +hostcache_prune(struct curl_hash *hostcache, long cache_timeout, time_t now) +{ + struct hostcache_prune_data user; + + user.cache_timeout = cache_timeout; + user.now = now; + + Curl_hash_clean_with_criterium(hostcache, + (void *) &user, + hostcache_timestamp_remove); +} + +/* + * Library-wide function for pruning the DNS cache. This function takes and + * returns the appropriate locks. + */ +void Curl_hostcache_prune(struct Curl_easy *data) +{ + time_t now; + + if((data->set.dns_cache_timeout == -1) || !data->dns.hostcache) + /* cache forever means never prune, and NULL hostcache means + we can't do it */ + return; + + if(data->share) + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + + time(&now); + + /* Remove outdated and unused entries from the hostcache */ + hostcache_prune(data->dns.hostcache, + data->set.dns_cache_timeout, + now); + + if(data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); +} + +#ifdef HAVE_SIGSETJMP +/* Beware this is a global and unique instance. This is used to store the + return address that we can jump back to from inside a signal handler. This + is not thread-safe stuff. */ +sigjmp_buf curl_jmpenv; +#endif + +/* lookup address, returns entry if found and not stale */ +static struct Curl_dns_entry * +fetch_addr(struct connectdata *conn, + const char *hostname, + int port) +{ + struct Curl_dns_entry *dns = NULL; + size_t entry_len; + struct Curl_easy *data = conn->data; + char entry_id[MAX_HOSTCACHE_LEN]; + + /* Create an entry id, based upon the hostname and port */ + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); + entry_len = strlen(entry_id); + + /* See if its already in our dns cache */ + dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1); + + /* No entry found in cache, check if we might have a wildcard entry */ + if(!dns && data->change.wildcard_resolve) { + create_hostcache_id("*", port, entry_id, sizeof(entry_id)); + entry_len = strlen(entry_id); + + /* See if it's already in our dns cache */ + dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1); + } + + if(dns && (data->set.dns_cache_timeout != -1)) { + /* See whether the returned entry is stale. Done before we release lock */ + struct hostcache_prune_data user; + + time(&user.now); + user.cache_timeout = data->set.dns_cache_timeout; + + if(hostcache_timestamp_remove(&user, dns)) { + infof(data, "Hostname in DNS cache was stale, zapped\n"); + dns = NULL; /* the memory deallocation is being handled by the hash */ + Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1); + } + } + + return dns; +} + +/* + * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache. + * + * Curl_resolv() checks initially and multi_runsingle() checks each time + * it discovers the handle in the state WAITRESOLVE whether the hostname + * has already been resolved and the address has already been stored in + * the DNS cache. This short circuits waiting for a lot of pending + * lookups for the same hostname requested by different handles. + * + * Returns the Curl_dns_entry entry pointer or NULL if not in the cache. + * + * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after + * use, or we'll leak memory! + */ +struct Curl_dns_entry * +Curl_fetch_addr(struct connectdata *conn, + const char *hostname, + int port) +{ + struct Curl_easy *data = conn->data; + struct Curl_dns_entry *dns = NULL; + + if(data->share) + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + + dns = fetch_addr(conn, hostname, port); + + if(dns) + dns->inuse++; /* we use it! */ + + if(data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + + return dns; +} + +#ifndef CURL_DISABLE_SHUFFLE_DNS +UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data, + Curl_addrinfo **addr); +/* + * Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo' + * struct by re-linking its linked list. + * + * The addr argument should be the address of a pointer to the head node of a + * `Curl_addrinfo` list and it will be modified to point to the new head after + * shuffling. + * + * Not declared static only to make it easy to use in a unit test! + * + * @unittest: 1608 + */ +UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data, + Curl_addrinfo **addr) +{ + CURLcode result = CURLE_OK; + const int num_addrs = Curl_num_addresses(*addr); + + if(num_addrs > 1) { + Curl_addrinfo **nodes; + infof(data, "Shuffling %i addresses", num_addrs); + + nodes = malloc(num_addrs*sizeof(*nodes)); + if(nodes) { + int i; + unsigned int *rnd; + const size_t rnd_size = num_addrs * sizeof(*rnd); + + /* build a plain array of Curl_addrinfo pointers */ + nodes[0] = *addr; + for(i = 1; i < num_addrs; i++) { + nodes[i] = nodes[i-1]->ai_next; + } + + rnd = malloc(rnd_size); + if(rnd) { + /* Fisher-Yates shuffle */ + if(Curl_rand(data, (unsigned char *)rnd, rnd_size) == CURLE_OK) { + Curl_addrinfo *swap_tmp; + for(i = num_addrs - 1; i > 0; i--) { + swap_tmp = nodes[rnd[i] % (i + 1)]; + nodes[rnd[i] % (i + 1)] = nodes[i]; + nodes[i] = swap_tmp; + } + + /* relink list in the new order */ + for(i = 1; i < num_addrs; i++) { + nodes[i-1]->ai_next = nodes[i]; + } + + nodes[num_addrs-1]->ai_next = NULL; + *addr = nodes[0]; + } + free(rnd); + } + else + result = CURLE_OUT_OF_MEMORY; + free(nodes); + } + else + result = CURLE_OUT_OF_MEMORY; + } + return result; +} +#endif + +/* + * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. + * + * When calling Curl_resolv() has resulted in a response with a returned + * address, we call this function to store the information in the dns + * cache etc + * + * Returns the Curl_dns_entry entry pointer or NULL if the storage failed. + */ +struct Curl_dns_entry * +Curl_cache_addr(struct Curl_easy *data, + Curl_addrinfo *addr, + const char *hostname, + int port) +{ + char entry_id[MAX_HOSTCACHE_LEN]; + size_t entry_len; + struct Curl_dns_entry *dns; + struct Curl_dns_entry *dns2; + +#ifndef CURL_DISABLE_SHUFFLE_DNS + /* shuffle addresses if requested */ + if(data->set.dns_shuffle_addresses) { + CURLcode result = Curl_shuffle_addr(data, &addr); + if(result) + return NULL; + } +#endif + + /* Create a new cache entry */ + dns = calloc(1, sizeof(struct Curl_dns_entry)); + if(!dns) { + return NULL; + } + + /* Create an entry id, based upon the hostname and port */ + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); + entry_len = strlen(entry_id); + + dns->inuse = 1; /* the cache has the first reference */ + dns->addr = addr; /* this is the address(es) */ + time(&dns->timestamp); + if(dns->timestamp == 0) + dns->timestamp = 1; /* zero indicates CURLOPT_RESOLVE entry */ + + /* Store the resolved data in our DNS cache. */ + dns2 = Curl_hash_add(data->dns.hostcache, entry_id, entry_len + 1, + (void *)dns); + if(!dns2) { + free(dns); + return NULL; + } + + dns = dns2; + dns->inuse++; /* mark entry as in-use */ + return dns; +} + +/* + * Curl_resolv() is the main name resolve function within libcurl. It resolves + * a name and returns a pointer to the entry in the 'entry' argument (if one + * is provided). This function might return immediately if we're using asynch + * resolves. See the return codes. + * + * The cache entry we return will get its 'inuse' counter increased when this + * function is used. You MUST call Curl_resolv_unlock() later (when you're + * done using this struct) to decrease the counter again. + * + * In debug mode, we specifically test for an interface name "LocalHost" + * and resolve "localhost" instead as a means to permit test cases + * to connect to a local test server with any host name. + * + * Return codes: + * + * CURLRESOLV_ERROR (-1) = error, no pointer + * CURLRESOLV_RESOLVED (0) = OK, pointer provided + * CURLRESOLV_PENDING (1) = waiting for response, no pointer + */ + +int Curl_resolv(struct connectdata *conn, + const char *hostname, + int port, + bool allowDOH, + struct Curl_dns_entry **entry) +{ + struct Curl_dns_entry *dns = NULL; + struct Curl_easy *data = conn->data; + CURLcode result; + int rc = CURLRESOLV_ERROR; /* default to failure */ + + *entry = NULL; + + if(data->share) + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + + dns = fetch_addr(conn, hostname, port); + + if(dns) { + infof(data, "Hostname %s was found in DNS cache\n", hostname); + dns->inuse++; /* we use it! */ + rc = CURLRESOLV_RESOLVED; + } + + if(data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + + if(!dns) { + /* The entry was not in the cache. Resolve it to IP address */ + + Curl_addrinfo *addr; + int respwait = 0; + + /* Check what IP specifics the app has requested and if we can provide it. + * If not, bail out. */ + if(!Curl_ipvalid(conn)) + return CURLRESOLV_ERROR; + + /* notify the resolver start callback */ + if(data->set.resolver_start) { + int st; + Curl_set_in_callback(data, true); + st = data->set.resolver_start(data->state.resolver, NULL, + data->set.resolver_start_client); + Curl_set_in_callback(data, false); + if(st) + return CURLRESOLV_ERROR; + } + + if(allowDOH && data->set.doh) { + addr = Curl_doh(conn, hostname, port, &respwait); + } + else { + /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a + non-zero value indicating that we need to wait for the response to the + resolve call */ + addr = Curl_getaddrinfo(conn, +#ifdef DEBUGBUILD + (data->set.str[STRING_DEVICE] + && !strcmp(data->set.str[STRING_DEVICE], + "LocalHost"))?"localhost": +#endif + hostname, port, &respwait); + } + if(!addr) { + if(respwait) { + /* the response to our resolve call will come asynchronously at + a later time, good or bad */ + /* First, check that we haven't received the info by now */ + result = Curl_resolv_check(conn, &dns); + if(result) /* error detected */ + return CURLRESOLV_ERROR; + if(dns) + rc = CURLRESOLV_RESOLVED; /* pointer provided */ + else + rc = CURLRESOLV_PENDING; /* no info yet */ + } + } + else { + if(data->share) + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + + /* we got a response, store it in the cache */ + dns = Curl_cache_addr(data, addr, hostname, port); + + if(data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + + if(!dns) + /* returned failure, bail out nicely */ + Curl_freeaddrinfo(addr); + else + rc = CURLRESOLV_RESOLVED; + } + } + + *entry = dns; + + return rc; +} + +#ifdef USE_ALARM_TIMEOUT +/* + * This signal handler jumps back into the main libcurl code and continues + * execution. This effectively causes the remainder of the application to run + * within a signal handler which is nonportable and could lead to problems. + */ +static +RETSIGTYPE alarmfunc(int sig) +{ + /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ + (void)sig; + siglongjmp(curl_jmpenv, 1); +} +#endif /* USE_ALARM_TIMEOUT */ + +/* + * Curl_resolv_timeout() is the same as Curl_resolv() but specifies a + * timeout. This function might return immediately if we're using asynch + * resolves. See the return codes. + * + * The cache entry we return will get its 'inuse' counter increased when this + * function is used. You MUST call Curl_resolv_unlock() later (when you're + * done using this struct) to decrease the counter again. + * + * If built with a synchronous resolver and use of signals is not + * disabled by the application, then a nonzero timeout will cause a + * timeout after the specified number of milliseconds. Otherwise, timeout + * is ignored. + * + * Return codes: + * + * CURLRESOLV_TIMEDOUT(-2) = warning, time too short or previous alarm expired + * CURLRESOLV_ERROR (-1) = error, no pointer + * CURLRESOLV_RESOLVED (0) = OK, pointer provided + * CURLRESOLV_PENDING (1) = waiting for response, no pointer + */ + +int Curl_resolv_timeout(struct connectdata *conn, + const char *hostname, + int port, + struct Curl_dns_entry **entry, + time_t timeoutms) +{ +#ifdef USE_ALARM_TIMEOUT +#ifdef HAVE_SIGACTION + struct sigaction keep_sigact; /* store the old struct here */ + volatile bool keep_copysig = FALSE; /* whether old sigact has been saved */ + struct sigaction sigact; +#else +#ifdef HAVE_SIGNAL + void (*keep_sigact)(int); /* store the old handler here */ +#endif /* HAVE_SIGNAL */ +#endif /* HAVE_SIGACTION */ + volatile long timeout; + volatile unsigned int prev_alarm = 0; + struct Curl_easy *data = conn->data; +#endif /* USE_ALARM_TIMEOUT */ + int rc; + + *entry = NULL; + + if(timeoutms < 0) + /* got an already expired timeout */ + return CURLRESOLV_TIMEDOUT; + +#ifdef USE_ALARM_TIMEOUT + if(data->set.no_signal) + /* Ignore the timeout when signals are disabled */ + timeout = 0; + else + timeout = (timeoutms > LONG_MAX) ? LONG_MAX : (long)timeoutms; + + if(!timeout) + /* USE_ALARM_TIMEOUT defined, but no timeout actually requested */ + return Curl_resolv(conn, hostname, port, TRUE, entry); + + if(timeout < 1000) { + /* The alarm() function only provides integer second resolution, so if + we want to wait less than one second we must bail out already now. */ + failf(data, + "remaining timeout of %ld too small to resolve via SIGALRM method", + timeout); + return CURLRESOLV_TIMEDOUT; + } + /* This allows us to time-out from the name resolver, as the timeout + will generate a signal and we will siglongjmp() from that here. + This technique has problems (see alarmfunc). + This should be the last thing we do before calling Curl_resolv(), + as otherwise we'd have to worry about variables that get modified + before we invoke Curl_resolv() (and thus use "volatile"). */ + if(sigsetjmp(curl_jmpenv, 1)) { + /* this is coming from a siglongjmp() after an alarm signal */ + failf(data, "name lookup timed out"); + rc = CURLRESOLV_ERROR; + goto clean_up; + } + else { + /************************************************************* + * Set signal handler to catch SIGALRM + * Store the old value to be able to set it back later! + *************************************************************/ +#ifdef HAVE_SIGACTION + sigaction(SIGALRM, NULL, &sigact); + keep_sigact = sigact; + keep_copysig = TRUE; /* yes, we have a copy */ + sigact.sa_handler = alarmfunc; +#ifdef SA_RESTART + /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ + sigact.sa_flags &= ~SA_RESTART; +#endif + /* now set the new struct */ + sigaction(SIGALRM, &sigact, NULL); +#else /* HAVE_SIGACTION */ + /* no sigaction(), revert to the much lamer signal() */ +#ifdef HAVE_SIGNAL + keep_sigact = signal(SIGALRM, alarmfunc); +#endif +#endif /* HAVE_SIGACTION */ + + /* alarm() makes a signal get sent when the timeout fires off, and that + will abort system calls */ + prev_alarm = alarm(curlx_sltoui(timeout/1000L)); + } + +#else +#ifndef CURLRES_ASYNCH + if(timeoutms) + infof(conn->data, "timeout on name lookup is not supported\n"); +#else + (void)timeoutms; /* timeoutms not used with an async resolver */ +#endif +#endif /* USE_ALARM_TIMEOUT */ + + /* Perform the actual name resolution. This might be interrupted by an + * alarm if it takes too long. + */ + rc = Curl_resolv(conn, hostname, port, TRUE, entry); + +#ifdef USE_ALARM_TIMEOUT +clean_up: + + if(!prev_alarm) + /* deactivate a possibly active alarm before uninstalling the handler */ + alarm(0); + +#ifdef HAVE_SIGACTION + if(keep_copysig) { + /* we got a struct as it looked before, now put that one back nice + and clean */ + sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */ + } +#else +#ifdef HAVE_SIGNAL + /* restore the previous SIGALRM handler */ + signal(SIGALRM, keep_sigact); +#endif +#endif /* HAVE_SIGACTION */ + + /* switch back the alarm() to either zero or to what it was before minus + the time we spent until now! */ + if(prev_alarm) { + /* there was an alarm() set before us, now put it back */ + timediff_t elapsed_secs = Curl_timediff(Curl_now(), + conn->created) / 1000; + + /* the alarm period is counted in even number of seconds */ + unsigned long alarm_set = prev_alarm - elapsed_secs; + + if(!alarm_set || + ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) { + /* if the alarm time-left reached zero or turned "negative" (counted + with unsigned values), we should fire off a SIGALRM here, but we + won't, and zero would be to switch it off so we never set it to + less than 1! */ + alarm(1); + rc = CURLRESOLV_TIMEDOUT; + failf(data, "Previous alarm fired off!"); + } + else + alarm((unsigned int)alarm_set); + } +#endif /* USE_ALARM_TIMEOUT */ + + return rc; +} + +/* + * Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been + * made, the struct may be destroyed due to pruning. It is important that only + * one unlock is made for each Curl_resolv() call. + * + * May be called with 'data' == NULL for global cache. + */ +void Curl_resolv_unlock(struct Curl_easy *data, struct Curl_dns_entry *dns) +{ + if(data && data->share) + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + + freednsentry(dns); + + if(data && data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); +} + +/* + * File-internal: release cache dns entry reference, free if inuse drops to 0 + */ +static void freednsentry(void *freethis) +{ + struct Curl_dns_entry *dns = (struct Curl_dns_entry *) freethis; + DEBUGASSERT(dns && (dns->inuse>0)); + + dns->inuse--; + if(dns->inuse == 0) { + Curl_freeaddrinfo(dns->addr); + free(dns); + } +} + +/* + * Curl_mk_dnscache() inits a new DNS cache and returns success/failure. + */ +int Curl_mk_dnscache(struct curl_hash *hash) +{ + return Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare, + freednsentry); +} + +/* + * Curl_hostcache_clean() + * + * This _can_ be called with 'data' == NULL but then of course no locking + * can be done! + */ + +void Curl_hostcache_clean(struct Curl_easy *data, + struct curl_hash *hash) +{ + if(data && data->share) + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + + Curl_hash_clean(hash); + + if(data && data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); +} + + +CURLcode Curl_loadhostpairs(struct Curl_easy *data) +{ + struct curl_slist *hostp; + char hostname[256]; + int port = 0; + + /* Default is no wildcard found */ + data->change.wildcard_resolve = false; + + for(hostp = data->change.resolve; hostp; hostp = hostp->next) { + char entry_id[MAX_HOSTCACHE_LEN]; + if(!hostp->data) + continue; + if(hostp->data[0] == '-') { + size_t entry_len; + + if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) { + infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'!\n", + hostp->data); + continue; + } + + /* Create an entry id, based upon the hostname and port */ + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); + entry_len = strlen(entry_id); + + if(data->share) + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + + /* delete entry, ignore if it didn't exist */ + Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1); + + if(data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + } + else { + struct Curl_dns_entry *dns; + Curl_addrinfo *head = NULL, *tail = NULL; + size_t entry_len; + char address[64]; +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) + char *addresses = NULL; +#endif + char *addr_begin; + char *addr_end; + char *port_ptr; + char *end_ptr; + char *host_end; + unsigned long tmp_port; + bool error = true; + + host_end = strchr(hostp->data, ':'); + if(!host_end || + ((host_end - hostp->data) >= (ptrdiff_t)sizeof(hostname))) + goto err; + + memcpy(hostname, hostp->data, host_end - hostp->data); + hostname[host_end - hostp->data] = '\0'; + + port_ptr = host_end + 1; + tmp_port = strtoul(port_ptr, &end_ptr, 10); + if(tmp_port > USHRT_MAX || end_ptr == port_ptr || *end_ptr != ':') + goto err; + + port = (int)tmp_port; +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) + addresses = end_ptr + 1; +#endif + + while(*end_ptr) { + size_t alen; + Curl_addrinfo *ai; + + addr_begin = end_ptr + 1; + addr_end = strchr(addr_begin, ','); + if(!addr_end) + addr_end = addr_begin + strlen(addr_begin); + end_ptr = addr_end; + + /* allow IP(v6) address within [brackets] */ + if(*addr_begin == '[') { + if(addr_end == addr_begin || *(addr_end - 1) != ']') + goto err; + ++addr_begin; + --addr_end; + } + + alen = addr_end - addr_begin; + if(!alen) + continue; + + if(alen >= sizeof(address)) + goto err; + + memcpy(address, addr_begin, alen); + address[alen] = '\0'; + +#ifndef ENABLE_IPV6 + if(strchr(address, ':')) { + infof(data, "Ignoring resolve address '%s', missing IPv6 support.\n", + address); + continue; + } +#endif + + ai = Curl_str2addr(address, port); + if(!ai) { + infof(data, "Resolve address '%s' found illegal!\n", address); + goto err; + } + + if(tail) { + tail->ai_next = ai; + tail = tail->ai_next; + } + else { + head = tail = ai; + } + } + + if(!head) + goto err; + + error = false; + err: + if(error) { + infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n", + hostp->data); + Curl_freeaddrinfo(head); + continue; + } + + /* Create an entry id, based upon the hostname and port */ + create_hostcache_id(hostname, port, entry_id, sizeof(entry_id)); + entry_len = strlen(entry_id); + + if(data->share) + Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); + + /* See if its already in our dns cache */ + dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1); + + if(dns) { + infof(data, "RESOLVE %s:%d is - old addresses discarded!\n", + hostname, port); + /* delete old entry entry, there are two reasons for this + 1. old entry may have different addresses. + 2. even if entry with correct addresses is already in the cache, + but if it is close to expire, then by the time next http + request is made, it can get expired and pruned because old + entry is not necessarily marked as added by CURLOPT_RESOLVE. */ + + Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1); + } + + /* put this new host in the cache */ + dns = Curl_cache_addr(data, head, hostname, port); + if(dns) { + dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */ + /* release the returned reference; the cache itself will keep the + * entry alive: */ + dns->inuse--; + } + + if(data->share) + Curl_share_unlock(data, CURL_LOCK_DATA_DNS); + + if(!dns) { + Curl_freeaddrinfo(head); + return CURLE_OUT_OF_MEMORY; + } + + //infof(data, "Added %s:%d:%s to DNS cache\n", + //hostname, port, addresses); + + /* Wildcard hostname */ + if(hostname[0] == '*' && hostname[1] == '\0') { + infof(data, "RESOLVE %s:%d is wildcard, enabling wildcard checks\n", + hostname, port); + data->change.wildcard_resolve = true; + } + } + } + data->change.resolve = NULL; /* dealt with now */ + + return CURLE_OK; +} + +CURLcode Curl_resolv_check(struct connectdata *conn, + struct Curl_dns_entry **dns) +{ + if(conn->data->set.doh) + return Curl_doh_is_resolved(conn, dns); + return Curl_resolver_is_resolved(conn, dns); +} + +int Curl_resolv_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) +{ +#ifdef CURLRES_ASYNCH + if(conn->data->set.doh) + /* nothing to wait for during DOH resolve, those handles have their own + sockets */ + return GETSOCK_BLANK; + return Curl_resolver_getsock(conn, socks, numsocks); +#else + (void)conn; + (void)socks; + (void)numsocks; + return GETSOCK_BLANK; +#endif +} + +/* Call this function after Curl_connect() has returned async=TRUE and + then a successful name resolve has been received. + + Note: this function disconnects and frees the conn data in case of + resolve failure */ +CURLcode Curl_once_resolved(struct connectdata *conn, + bool *protocol_done) +{ + CURLcode result; + + if(conn->async.dns) { + conn->dns_entry = conn->async.dns; + conn->async.dns = NULL; + } + + result = Curl_setup_conn(conn, protocol_done); + + if(result) + /* We're not allowed to return failure with memory left allocated + in the connectdata struct, free those here */ + Curl_disconnect(conn->data, conn, TRUE); /* close the connection */ + + return result; +} diff --git a/libcurl/lib/hostip.h b/libcurl/lib/hostip.h new file mode 100644 index 0000000..1bda524 --- /dev/null +++ b/libcurl/lib/hostip.h @@ -0,0 +1,246 @@ +#ifndef HEADER_CURL_HOSTIP_H +#define HEADER_CURL_HOSTIP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include "hash.h" +#include "curl_addrinfo.h" +#include "asyn.h" + +#ifdef HAVE_SETJMP_H +#include +#endif + +#ifdef NETWARE +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +/* Allocate enough memory to hold the full name information structs and + * everything. OSF1 is known to require at least 8872 bytes. The buffer + * required for storing all possible aliases and IP numbers is according to + * Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes! + */ +#define CURL_HOSTENT_SIZE 9000 + +#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this + many seconds for a name resolve */ + +#define CURL_ASYNC_SUCCESS CURLE_OK + +struct addrinfo; +struct hostent; +struct Curl_easy; +struct connectdata; + +/* + * Curl_global_host_cache_init() initializes and sets up a global DNS cache. + * Global DNS cache is general badness. Do not use. This will be removed in + * a future version. Use the share interface instead! + * + * Returns a struct curl_hash pointer on success, NULL on failure. + */ +struct curl_hash *Curl_global_host_cache_init(void); + +struct Curl_dns_entry { + Curl_addrinfo *addr; + /* timestamp == 0 -- CURLOPT_RESOLVE entry, doesn't timeout */ + time_t timestamp; + /* use-counter, use Curl_resolv_unlock to release reference */ + long inuse; +}; + +/* + * Curl_resolv() returns an entry with the info for the specified host + * and port. + * + * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after + * use, or we'll leak memory! + */ +/* return codes */ +#define CURLRESOLV_TIMEDOUT -2 +#define CURLRESOLV_ERROR -1 +#define CURLRESOLV_RESOLVED 0 +#define CURLRESOLV_PENDING 1 +int Curl_resolv(struct connectdata *conn, + const char *hostname, + int port, + bool allowDOH, + struct Curl_dns_entry **dnsentry); +int Curl_resolv_timeout(struct connectdata *conn, const char *hostname, + int port, struct Curl_dns_entry **dnsentry, + time_t timeoutms); + +#ifdef CURLRES_IPV6 +/* + * Curl_ipv6works() returns TRUE if IPv6 seems to work. + */ +bool Curl_ipv6works(void); +#else +#define Curl_ipv6works() FALSE +#endif + +/* + * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've + * been set and returns TRUE if they are OK. + */ +bool Curl_ipvalid(struct connectdata *conn); + + +/* + * Curl_getaddrinfo() is the generic low-level name resolve API within this + * source file. There are several versions of this function - for different + * name resolve layers (selected at build-time). They all take this same set + * of arguments + */ +Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, + const char *hostname, + int port, + int *waitp); + + +/* unlock a previously resolved dns entry */ +void Curl_resolv_unlock(struct Curl_easy *data, + struct Curl_dns_entry *dns); + +/* init a new dns cache and return success */ +int Curl_mk_dnscache(struct curl_hash *hash); + +/* prune old entries from the DNS cache */ +void Curl_hostcache_prune(struct Curl_easy *data); + +/* Return # of addresses in a Curl_addrinfo struct */ +int Curl_num_addresses(const Curl_addrinfo *addr); + +#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) +int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa, + GETNAMEINFO_TYPE_ARG2 salen, + char *host, GETNAMEINFO_TYPE_ARG46 hostlen, + char *serv, GETNAMEINFO_TYPE_ARG46 servlen, + GETNAMEINFO_TYPE_ARG7 flags, + int line, const char *source); +#endif + +/* IPv4 threadsafe resolve function used for synch and asynch builds */ +Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port); + +CURLcode Curl_once_resolved(struct connectdata *conn, bool *protocol_connect); + +/* + * Curl_addrinfo_callback() is used when we build with any asynch specialty. + * Handles end of async request processing. Inserts ai into hostcache when + * status is CURL_ASYNC_SUCCESS. Twiddles fields in conn to indicate async + * request completed whether successful or failed. + */ +CURLcode Curl_addrinfo_callback(struct connectdata *conn, + int status, + Curl_addrinfo *ai); + +/* + * Curl_printable_address() returns a printable version of the 1st address + * given in the 'ip' argument. The result will be stored in the buf that is + * bufsize bytes big. + */ +const char *Curl_printable_address(const Curl_addrinfo *ip, + char *buf, size_t bufsize); + +/* + * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache. + * + * Returns the Curl_dns_entry entry pointer or NULL if not in the cache. + * + * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after + * use, or we'll leak memory! + */ +struct Curl_dns_entry * +Curl_fetch_addr(struct connectdata *conn, + const char *hostname, + int port); + +/* + * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. + * + * Returns the Curl_dns_entry entry pointer or NULL if the storage failed. + */ +struct Curl_dns_entry * +Curl_cache_addr(struct Curl_easy *data, Curl_addrinfo *addr, + const char *hostname, int port); + +#ifndef INADDR_NONE +#define CURL_INADDR_NONE (in_addr_t) ~0 +#else +#define CURL_INADDR_NONE INADDR_NONE +#endif + +#ifdef HAVE_SIGSETJMP +/* Forward-declaration of variable defined in hostip.c. Beware this + * is a global and unique instance. This is used to store the return + * address that we can jump back to from inside a signal handler. + * This is not thread-safe stuff. + */ +extern sigjmp_buf curl_jmpenv; +#endif + +/* + * Function provided by the resolver backend to set DNS servers to use. + */ +CURLcode Curl_set_dns_servers(struct Curl_easy *data, char *servers); + +/* + * Function provided by the resolver backend to set + * outgoing interface to use for DNS requests + */ +CURLcode Curl_set_dns_interface(struct Curl_easy *data, + const char *interf); + +/* + * Function provided by the resolver backend to set + * local IPv4 address to use as source address for DNS requests + */ +CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data, + const char *local_ip4); + +/* + * Function provided by the resolver backend to set + * local IPv6 address to use as source address for DNS requests + */ +CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data, + const char *local_ip6); + +/* + * Clean off entries from the cache + */ +void Curl_hostcache_clean(struct Curl_easy *data, struct curl_hash *hash); + +/* + * Populate the cache with specified entries from CURLOPT_RESOLVE. + */ +CURLcode Curl_loadhostpairs(struct Curl_easy *data); + +CURLcode Curl_resolv_check(struct connectdata *conn, + struct Curl_dns_entry **dns); +int Curl_resolv_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks); + +#endif /* HEADER_CURL_HOSTIP_H */ diff --git a/libcurl/lib/hostip4.c b/libcurl/lib/hostip4.c new file mode 100644 index 0000000..47312c3 --- /dev/null +++ b/libcurl/lib/hostip4.c @@ -0,0 +1,503 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +/*********************************************************************** + * Only for plain IPv4 builds + **********************************************************************/ +#ifdef CURLRES_IPV4 /* plain IPv4 code coming up */ + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#ifdef HAVE_PROCESS_H +#include +#endif + +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "hash.h" +#include "share.h" +#include "strerror.h" +#include "url.h" +#include "inet_pton.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#ifdef _XBOX +/* Forward declaration for Xbox hostent cleanup function */ +void xbox_freehostent(struct hostent *hp); +#endif + +#ifdef _XBOX + +/* + * Xbox-specific gethostbyname() implementation using XNetDnsLookup. + * This allocates memory that MUST be freed by calling xbox_freehostent(). + */ +struct hostent * gethostbyname (char *host) { + struct hostent *hp = NULL; + struct sockaddr_in sa; + char szLocalHostName[256]; + size_t hostLen; + int iLen; + WSAEVENT hEvent = NULL; + XNDNS *heHost = NULL; + + /* Validate input parameter */ + if(host == NULL || host[0] == '\0') { + return NULL; + } + + /* Safely copy hostname with length check */ + hostLen = strlen(host); + if(hostLen >= sizeof(szLocalHostName)) { + return NULL; + } + memcpy(szLocalHostName, host, hostLen + 1); + + /* Determine if this is an IP address or hostname by checking + * if it contains only digits and dots */ + iLen = (int)hostLen; + while(--iLen >= 0 && (szLocalHostName[iLen] == '.' || + isdigit((unsigned char)szLocalHostName[iLen]))); + + if(iLen >= 0) { + /* This is a hostname - perform DNS lookup */ + + /* Create event for async DNS notification */ + hEvent = WSACreateEvent(); + if(hEvent == NULL) { + return NULL; + } + + /* Initiate DNS lookup */ + if(XNetDnsLookup(szLocalHostName, hEvent, &heHost) != 0) { + WSACloseEvent(hEvent); + return NULL; + } + + /* Wait for DNS response with timeout */ + { + DWORD wait_result = WaitForSingleObject(hEvent, 30000); + WSACloseEvent(hEvent); + hEvent = NULL; + + if(wait_result == WAIT_TIMEOUT) { + XNetDnsRelease(heHost); + return NULL; + } + } + + /* Check DNS lookup result */ + if(heHost->iStatus != 0) { + /* DNS lookup failed */ + XNetDnsRelease(heHost); + return NULL; + } + + /* Verify we got at least one address */ + if(heHost->cina == 0) { + XNetDnsRelease(heHost); + return NULL; + } + + /* Allocate and populate hostent structure with ALL returned addresses */ + hp = (struct hostent *)calloc(1, sizeof(struct hostent)); + if(!hp) { + XNetDnsRelease(heHost); + return NULL; + } + + hp->h_aliases = NULL; + hp->h_addrtype = AF_INET; + hp->h_length = sizeof(struct in_addr); + hp->h_name = strdup(host); + if(!hp->h_name) { + free(hp); + XNetDnsRelease(heHost); + return NULL; + } + + /* Allocate pointer array for all addresses + NULL terminator */ + hp->h_addr_list = (char **)calloc(heHost->cina + 1, sizeof(char *)); + if(!hp->h_addr_list) { + free(hp->h_name); + free(hp); + XNetDnsRelease(heHost); + return NULL; + } + + /* Populate all returned addresses */ + { + int i; + for(i = 0; i < (int)heHost->cina; i++) { + hp->h_addr_list[i] = (char *)calloc(1, sizeof(struct in_addr)); + if(!hp->h_addr_list[i]) { + /* Cleanup on allocation failure */ + int j; + for(j = 0; j < i; j++) { + free(hp->h_addr_list[j]); + } + free(hp->h_addr_list); + free(hp->h_name); + free(hp); + XNetDnsRelease(heHost); + return NULL; + } + memcpy(hp->h_addr_list[i], &(heHost->aina[i].S_un.S_addr), hp->h_length); + } + } + XNetDnsRelease(heHost); + } + else { + /* This is an IP address (only digits and dots) - parse it directly */ + if(Curl_inet_pton(AF_INET, host, &(sa.sin_addr)) != 1) { + return NULL; + } + + /* Allocate and populate hostent structure */ + hp = (struct hostent *)calloc(1, sizeof(struct hostent)); + if(!hp) { + return NULL; + } + + hp->h_aliases = NULL; + hp->h_addrtype = AF_INET; + hp->h_length = sizeof(struct in_addr); + hp->h_name = strdup(host); + if(!hp->h_name) { + free(hp); + return NULL; + } + + hp->h_addr_list = (char **)calloc(2, sizeof(char *)); + if(!hp->h_addr_list) { + free(hp->h_name); + free(hp); + return NULL; + } + + hp->h_addr_list[0] = (char *)calloc(1, sizeof(struct in_addr)); + if(!hp->h_addr_list[0]) { + free(hp->h_addr_list); + free(hp->h_name); + free(hp); + return NULL; + } + + memcpy(hp->h_addr_list[0], &(sa.sin_addr), hp->h_length); + } + + return hp; +} + +/* + * Free a hostent structure allocated by Xbox gethostbyname(). + * This is called from Curl_ipv4_resolve_r() after conversion to Curl_addrinfo. + */ +void xbox_freehostent(struct hostent *hp) { + if(hp) { + if(hp->h_addr_list) { + int i; + for(i = 0; hp->h_addr_list[i] != NULL; i++) { + free(hp->h_addr_list[i]); + } + free(hp->h_addr_list); + } + if(hp->h_name) { + free(hp->h_name); + } + free(hp); + } +} + +#endif /* _XBOX */ + + +/* + * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've + * been set and returns TRUE if they are OK. + */ +bool Curl_ipvalid(struct connectdata *conn) +{ + if(conn->ip_version == CURL_IPRESOLVE_V6) + /* An IPv6 address was requested and we can't get/use one */ + return FALSE; + + return TRUE; /* OK, proceed */ +} + +#ifdef CURLRES_SYNCH + +/* + * Curl_getaddrinfo() - the IPv4 synchronous version. + * + * The original code to this function was from the Dancer source code, written + * by Bjorn Reese, it has since been patched and modified considerably. + * + * gethostbyname_r() is the thread-safe version of the gethostbyname() + * function. When we build for plain IPv4, we attempt to use this + * function. There are _three_ different gethostbyname_r() versions, and we + * detect which one this platform supports in the configure script and set up + * the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or + * HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME + * has the corresponding rules. This is primarily on *nix. Note that some unix + * flavours have thread-safe versions of the plain gethostbyname() etc. + * + */ +Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, + const char *hostname, + int port, + int *waitp) +{ + Curl_addrinfo *ai = NULL; + +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)conn; +#endif + + *waitp = 0; /* synchronous response only */ + + ai = Curl_ipv4_resolve_r(hostname, port); + if(!ai) + infof(conn->data, "Curl_ipv4_resolve_r failed for %s\n", hostname); + + return ai; +} +#endif /* CURLRES_SYNCH */ +#endif /* CURLRES_IPV4 */ + +#if defined(CURLRES_IPV4) && !defined(CURLRES_ARES) + +/* + * Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function. + * + * This is used for both synchronous and asynchronous resolver builds, + * implying that only threadsafe code and function calls may be used. + * + */ +Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, + int port) +{ +#if !defined(HAVE_GETADDRINFO_THREADSAFE) && defined(HAVE_GETHOSTBYNAME_R_3) + int res; +#endif + Curl_addrinfo *ai = NULL; + struct hostent *h = NULL; + struct in_addr in; + struct hostent *buf = NULL; + + if(Curl_inet_pton(AF_INET, hostname, &in) > 0) + /* This is a dotted IP address 123.123.123.123-style */ + return Curl_ip2addr(AF_INET, &in, hostname, port); + +#if defined(HAVE_GETADDRINFO_THREADSAFE) + else { + struct addrinfo hints; + char sbuf[12]; + char *sbufptr = NULL; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_INET; + hints.ai_socktype = SOCK_STREAM; + if(port) { + msnprintf(sbuf, sizeof(sbuf), "%d", port); + sbufptr = sbuf; + } + + (void)Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &ai); + +#elif defined(HAVE_GETHOSTBYNAME_R) + /* + * gethostbyname_r() is the preferred resolve function for many platforms. + * Since there are three different versions of it, the following code is + * somewhat #ifdef-ridden. + */ + else { + int h_errnop; + + buf = calloc(1, CURL_HOSTENT_SIZE); + if(!buf) + return NULL; /* major failure */ + /* + * The clearing of the buffer is a workaround for a gethostbyname_r bug in + * qnx nto and it is also _required_ for some of these functions on some + * platforms. + */ + +#if defined(HAVE_GETHOSTBYNAME_R_5) + /* Solaris, IRIX and more */ + h = gethostbyname_r(hostname, + (struct hostent *)buf, + (char *)buf + sizeof(struct hostent), + CURL_HOSTENT_SIZE - sizeof(struct hostent), + &h_errnop); + + /* If the buffer is too small, it returns NULL and sets errno to + * ERANGE. The errno is thread safe if this is compiled with + * -D_REENTRANT as then the 'errno' variable is a macro defined to get + * used properly for threads. + */ + + if(h) { + ; + } + else +#elif defined(HAVE_GETHOSTBYNAME_R_6) + /* Linux */ + + (void)gethostbyname_r(hostname, + (struct hostent *)buf, + (char *)buf + sizeof(struct hostent), + CURL_HOSTENT_SIZE - sizeof(struct hostent), + &h, /* DIFFERENCE */ + &h_errnop); + /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a + * sudden this function returns EAGAIN if the given buffer size is too + * small. Previous versions are known to return ERANGE for the same + * problem. + * + * This wouldn't be such a big problem if older versions wouldn't + * sometimes return EAGAIN on a common failure case. Alas, we can't + * assume that EAGAIN *or* ERANGE means ERANGE for any given version of + * glibc. + * + * For now, we do that and thus we may call the function repeatedly and + * fail for older glibc versions that return EAGAIN, until we run out of + * buffer size (step_size grows beyond CURL_HOSTENT_SIZE). + * + * If anyone has a better fix, please tell us! + * + * ------------------------------------------------------------------- + * + * On October 23rd 2003, Dan C dug up more details on the mysteries of + * gethostbyname_r() in glibc: + * + * In glibc 2.2.5 the interface is different (this has also been + * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't + * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32 + * (shipped/upgraded by Redhat 7.2) don't show this behavior! + * + * In this "buggy" version, the return code is -1 on error and 'errno' + * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a + * thread-safe variable. + */ + + if(!h) /* failure */ +#elif defined(HAVE_GETHOSTBYNAME_R_3) + /* AIX, Digital Unix/Tru64, HPUX 10, more? */ + + /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of + * the plain fact that it does not return unique full buffers on each + * call, but instead several of the pointers in the hostent structs will + * point to the same actual data! This have the unfortunate down-side that + * our caching system breaks down horribly. Luckily for us though, AIX 4.3 + * and more recent versions have a "completely thread-safe"[*] libc where + * all the data is stored in thread-specific memory areas making calls to + * the plain old gethostbyname() work fine even for multi-threaded + * programs. + * + * This AIX 4.3 or later detection is all made in the configure script. + * + * Troels Walsted Hansen helped us work this out on March 3rd, 2003. + * + * [*] = much later we've found out that it isn't at all "completely + * thread-safe", but at least the gethostbyname() function is. + */ + + if(CURL_HOSTENT_SIZE >= + (sizeof(struct hostent) + sizeof(struct hostent_data))) { + + /* August 22nd, 2000: Albert Chin-A-Young brought an updated version + * that should work! September 20: Richard Prescott worked on the buffer + * size dilemma. + */ + + res = gethostbyname_r(hostname, + (struct hostent *)buf, + (struct hostent_data *)((char *)buf + + sizeof(struct hostent))); + h_errnop = SOCKERRNO; /* we don't deal with this, but set it anyway */ + } + else + res = -1; /* failure, too smallish buffer size */ + + if(!res) { /* success */ + + h = buf; /* result expected in h */ + + /* This is the worst kind of the different gethostbyname_r() interfaces. + * Since we don't know how big buffer this particular lookup required, + * we can't realloc down the huge alloc without doing closer analysis of + * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every + * name lookup. Fixing this would require an extra malloc() and then + * calling Curl_addrinfo_copy() that subsequent realloc()s down the new + * memory area to the actually used amount. + */ + } + else +#endif /* HAVE_...BYNAME_R_5 || HAVE_...BYNAME_R_6 || HAVE_...BYNAME_R_3 */ + { + h = NULL; /* set return code to NULL */ + free(buf); + } +#else /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */ + /* + * Here is code for platforms that don't have a thread safe + * getaddrinfo() nor gethostbyname_r() function or for which + * gethostbyname() is the preferred one. + */ + else { + h = gethostbyname((void *)hostname); +#endif /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */ + } + + if(h) { + ai = Curl_he2ai(h, port); + + if(buf) /* used a *_r() function */ + free(buf); +#ifdef _XBOX + /* Xbox gethostbyname() allocates memory that must be freed */ + xbox_freehostent(h); +#endif + } + + return ai; +} +#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) */ diff --git a/libcurl/lib/hostip6.c b/libcurl/lib/hostip6.c new file mode 100644 index 0000000..5511f1a --- /dev/null +++ b/libcurl/lib/hostip6.c @@ -0,0 +1,203 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +/*********************************************************************** + * Only for IPv6-enabled builds + **********************************************************************/ +#ifdef CURLRES_IPV6 + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#ifdef HAVE_PROCESS_H +#include +#endif + +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "hash.h" +#include "share.h" +#include "strerror.h" +#include "url.h" +#include "inet_pton.h" +#include "connect.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Curl_ipv6works() returns TRUE if IPv6 seems to work. + */ +bool Curl_ipv6works(void) +{ + /* the nature of most system is that IPv6 status doesn't come and go + during a program's lifetime so we only probe the first time and then we + have the info kept for fast re-use */ + static int ipv6_works = -1; + if(-1 == ipv6_works) { + /* probe to see if we have a working IPv6 stack */ + curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0); + if(s == CURL_SOCKET_BAD) + /* an IPv6 address was requested but we can't get/use one */ + ipv6_works = 0; + else { + ipv6_works = 1; + Curl_closesocket(NULL, s); + } + } + return (ipv6_works>0)?TRUE:FALSE; +} + +/* + * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've + * been set and returns TRUE if they are OK. + */ +bool Curl_ipvalid(struct connectdata *conn) +{ + if(conn->ip_version == CURL_IPRESOLVE_V6) + return Curl_ipv6works(); + + return TRUE; +} + +#if defined(CURLRES_SYNCH) + +#ifdef DEBUG_ADDRINFO +static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai) +{ + printf("dump_addrinfo:\n"); + for(; ai; ai = ai->ai_next) { + char buf[INET6_ADDRSTRLEN]; + printf(" fam %2d, CNAME %s, ", + ai->ai_family, ai->ai_canonname ? ai->ai_canonname : ""); + if(Curl_printable_address(ai, buf, sizeof(buf))) + printf("%s\n", buf); + else { + char buffer[STRERROR_LEN]; + printf("failed; %s\n", + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + } + } +} +#else +#define dump_addrinfo(x,y) Curl_nop_stmt +#endif + +/* + * Curl_getaddrinfo() when built IPv6-enabled (non-threading and + * non-ares version). + * + * Returns name information about the given hostname and port number. If + * successful, the 'addrinfo' is returned and the forth argument will point to + * memory we need to free after use. That memory *MUST* be freed with + * Curl_freeaddrinfo(), nothing else. + */ +Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, + const char *hostname, + int port, + int *waitp) +{ + struct addrinfo hints; + Curl_addrinfo *res; + int error; + char sbuf[12]; + char *sbufptr = NULL; +#ifndef USE_RESOLVE_ON_IPS + char addrbuf[128]; +#endif + int pf; +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) + struct Curl_easy *data = conn->data; +#endif + + *waitp = 0; /* synchronous response only */ + + /* Check if a limited name resolve has been requested */ + switch(conn->ip_version) { + case CURL_IPRESOLVE_V4: + pf = PF_INET; + break; + case CURL_IPRESOLVE_V6: + pf = PF_INET6; + break; + default: + pf = PF_UNSPEC; + break; + } + + if((pf != PF_INET) && !Curl_ipv6works()) + /* The stack seems to be a non-IPv6 one */ + pf = PF_INET; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = pf; + hints.ai_socktype = conn->socktype; + +#ifndef USE_RESOLVE_ON_IPS + /* + * The AI_NUMERICHOST must not be set to get synthesized IPv6 address from + * an IPv4 address on iOS and Mac OS X. + */ + if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) || + (1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) { + /* the given address is numerical only, prevent a reverse lookup */ + hints.ai_flags = AI_NUMERICHOST; + } +#endif + + if(port) { + msnprintf(sbuf, sizeof(sbuf), "%d", port); + sbufptr = sbuf; + } + + error = Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &res); + if(error) { + infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port); + return NULL; + } + + if(port) { + Curl_addrinfo_set_port(res, port); + } + + dump_addrinfo(conn, res); + + return res; +} +#endif /* CURLRES_SYNCH */ + +#endif /* CURLRES_IPV6 */ diff --git a/libcurl/lib/hostsyn.c b/libcurl/lib/hostsyn.c new file mode 100644 index 0000000..3de6746 --- /dev/null +++ b/libcurl/lib/hostsyn.c @@ -0,0 +1,107 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +/*********************************************************************** + * Only for builds using synchronous name resolves + **********************************************************************/ +#ifdef CURLRES_SYNCH + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#ifdef HAVE_PROCESS_H +#include +#endif + +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "hash.h" +#include "share.h" +#include "strerror.h" +#include "url.h" +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* + * Function provided by the resolver backend to set DNS servers to use. + */ +CURLcode Curl_set_dns_servers(struct Curl_easy *data, + char *servers) +{ + (void)data; + (void)servers; + return CURLE_NOT_BUILT_IN; + +} + +/* + * Function provided by the resolver backend to set + * outgoing interface to use for DNS requests + */ +CURLcode Curl_set_dns_interface(struct Curl_easy *data, + const char *interf) +{ + (void)data; + (void)interf; + return CURLE_NOT_BUILT_IN; +} + +/* + * Function provided by the resolver backend to set + * local IPv4 address to use as source address for DNS requests + */ +CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data, + const char *local_ip4) +{ + (void)data; + (void)local_ip4; + return CURLE_NOT_BUILT_IN; +} + +/* + * Function provided by the resolver backend to set + * local IPv6 address to use as source address for DNS requests + */ +CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data, + const char *local_ip6) +{ + (void)data; + (void)local_ip6; + return CURLE_NOT_BUILT_IN; +} + +#endif /* truly sync */ diff --git a/libcurl/lib/http.c b/libcurl/lib/http.c new file mode 100644 index 0000000..f6b8296 --- /dev/null +++ b/libcurl/lib/http.c @@ -0,0 +1,4110 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_HTTP + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#include "urldata.h" +#include +#include "transfer.h" +#include "sendf.h" +#include "formdata.h" +#include "mime.h" +#include "progress.h" +#include "curl_base64.h" +#include "cookie.h" +#include "vauth/vauth.h" +#include "vtls/vtls.h" +#include "http_digest.h" +#include "http_ntlm.h" +#include "curl_ntlm_wb.h" +#include "http_negotiate.h" +#include "url.h" +#include "share.h" +#include "hostip.h" +#include "http.h" +#include "select.h" +#include "parsedate.h" /* for the week day and month names */ +#include "strtoofft.h" +#include "multiif.h" +#include "strcase.h" +#include "content_encoding.h" +#include "http_proxy.h" +#include "warnless.h" +#include "non-ascii.h" +#include "http2.h" +#include "connect.h" +#include "strdup.h" +#include "altsvc.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Forward declarations. + */ + +static int http_getsock_do(struct connectdata *conn, + curl_socket_t *socks, + int numsocks); +static int http_should_fail(struct connectdata *conn); + +#ifndef CURL_DISABLE_PROXY +static CURLcode add_haproxy_protocol_header(struct connectdata *conn); +#endif + +#ifdef USE_SSL +static CURLcode https_connecting(struct connectdata *conn, bool *done); +static int https_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks); +#else +#define https_connecting(x,y) CURLE_COULDNT_CONNECT +#endif +static CURLcode http_setup_conn(struct connectdata *conn); + +/* + * HTTP handler interface. + */ +const struct Curl_handler Curl_handler_http = { + "HTTP", /* scheme */ + http_setup_conn, /* setup_connection */ + Curl_http, /* do_it */ + Curl_http_done, /* done */ + ZERO_NULL, /* do_more */ + Curl_http_connect, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + http_getsock_do, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_HTTP, /* defport */ + CURLPROTO_HTTP, /* protocol */ + PROTOPT_CREDSPERREQUEST /* flags */ +}; + +#ifdef USE_SSL +/* + * HTTPS handler interface. + */ +const struct Curl_handler Curl_handler_https = { + "HTTPS", /* scheme */ + http_setup_conn, /* setup_connection */ + Curl_http, /* do_it */ + Curl_http_done, /* done */ + ZERO_NULL, /* do_more */ + Curl_http_connect, /* connect_it */ + https_connecting, /* connecting */ + ZERO_NULL, /* doing */ + https_getsock, /* proto_getsock */ + http_getsock_do, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_HTTPS, /* defport */ + CURLPROTO_HTTPS, /* protocol */ + PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN /* flags */ +}; +#endif + +static CURLcode http_setup_conn(struct connectdata *conn) +{ + /* allocate the HTTP-specific struct for the Curl_easy, only to survive + during this request */ + struct HTTP *http; + struct Curl_easy *data = conn->data; + DEBUGASSERT(data->req.protop == NULL); + + http = calloc(1, sizeof(struct HTTP)); + if(!http) + return CURLE_OUT_OF_MEMORY; + + Curl_mime_initpart(&http->form, conn->data); + data->req.protop = http; + + if(!CONN_INUSE(conn)) + /* if not already multi-using, setup connection details */ + Curl_http2_setup_conn(conn); + Curl_http2_setup_req(data); + return CURLE_OK; +} + +#ifndef CURL_DISABLE_PROXY +/* + * checkProxyHeaders() checks the linked list of custom proxy headers + * if proxy headers are not available, then it will lookup into http header + * link list + * + * It takes a connectdata struct as input instead of the Curl_easy simply to + * know if this is a proxy request or not, as it then might check a different + * header list. Provide the header prefix without colon!. + */ +char *Curl_checkProxyheaders(const struct connectdata *conn, + const char *thisheader) +{ + struct curl_slist *head; + size_t thislen = strlen(thisheader); + struct Curl_easy *data = conn->data; + + for(head = (conn->bits.proxy && data->set.sep_headers) ? + data->set.proxyheaders : data->set.headers; + head; head = head->next) { + if(strncasecompare(head->data, thisheader, thislen) && + Curl_headersep(head->data[thislen])) + return head->data; + } + + return NULL; +} +#else +/* disabled */ +#define Curl_checkProxyheaders(x,y) NULL +#endif + +/* + * Strip off leading and trailing whitespace from the value in the + * given HTTP header line and return a strdupped copy. Returns NULL in + * case of allocation failure. Returns an empty string if the header value + * consists entirely of whitespace. + */ +char *Curl_copy_header_value(const char *header) +{ + const char *start; + const char *end; + char *value; + size_t len; + + /* Find the end of the header name */ + while(*header && (*header != ':')) + ++header; + + if(*header) + /* Skip over colon */ + ++header; + + /* Find the first non-space letter */ + start = header; + while(*start && ISSPACE(*start)) + start++; + + /* data is in the host encoding so + use '\r' and '\n' instead of 0x0d and 0x0a */ + end = strchr(start, '\r'); + if(!end) + end = strchr(start, '\n'); + if(!end) + end = strchr(start, '\0'); + if(!end) + return NULL; + + /* skip all trailing space letters */ + while((end > start) && ISSPACE(*end)) + end--; + + /* get length of the type */ + len = end - start + 1; + + value = malloc(len + 1); + if(!value) + return NULL; + + memcpy(value, start, len); + value[len] = 0; /* zero terminate */ + + return value; +} + +#ifndef CURL_DISABLE_HTTP_AUTH +/* + * http_output_basic() sets up an Authorization: header (or the proxy version) + * for HTTP Basic authentication. + * + * Returns CURLcode. + */ +static CURLcode http_output_basic(struct connectdata *conn, bool proxy) +{ + size_t size = 0; + char *authorization = NULL; + struct Curl_easy *data = conn->data; + char **userp; + const char *user; + const char *pwd; + CURLcode result; + char *out; + + if(proxy) { + userp = &conn->allocptr.proxyuserpwd; + user = conn->http_proxy.user; + pwd = conn->http_proxy.passwd; + } + else { + userp = &conn->allocptr.userpwd; + user = conn->user; + pwd = conn->passwd; + } + + out = aprintf("%s:%s", user, pwd); + if(!out) + return CURLE_OUT_OF_MEMORY; + + result = Curl_base64_encode(data, out, strlen(out), &authorization, &size); + if(result) + goto fail; + + if(!authorization) { + result = CURLE_REMOTE_ACCESS_DENIED; + goto fail; + } + + free(*userp); + *userp = aprintf("%sAuthorization: Basic %s\r\n", + proxy ? "Proxy-" : "", + authorization); + free(authorization); + if(!*userp) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + + fail: + free(out); + return result; +} + +/* + * http_output_bearer() sets up an Authorization: header + * for HTTP Bearer authentication. + * + * Returns CURLcode. + */ +static CURLcode http_output_bearer(struct connectdata *conn) +{ + char **userp; + CURLcode result = CURLE_OK; + + userp = &conn->allocptr.userpwd; + free(*userp); + *userp = aprintf("Authorization: Bearer %s\r\n", + conn->oauth_bearer); + + if(!*userp) { + result = CURLE_OUT_OF_MEMORY; + goto fail; + } + + fail: + return result; +} + +#endif + +/* pickoneauth() selects the most favourable authentication method from the + * ones available and the ones we want. + * + * return TRUE if one was picked + */ +static bool pickoneauth(struct auth *pick, unsigned long mask) +{ + bool picked; + /* only deal with authentication we want */ + unsigned long avail = pick->avail & pick->want & mask; + picked = TRUE; + + /* The order of these checks is highly relevant, as this will be the order + of preference in case of the existence of multiple accepted types. */ + if(avail & CURLAUTH_NEGOTIATE) + pick->picked = CURLAUTH_NEGOTIATE; + else if(avail & CURLAUTH_BEARER) + pick->picked = CURLAUTH_BEARER; + else if(avail & CURLAUTH_DIGEST) + pick->picked = CURLAUTH_DIGEST; + else if(avail & CURLAUTH_NTLM) + pick->picked = CURLAUTH_NTLM; + else if(avail & CURLAUTH_NTLM_WB) + pick->picked = CURLAUTH_NTLM_WB; + else if(avail & CURLAUTH_BASIC) + pick->picked = CURLAUTH_BASIC; + else { + pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */ + picked = FALSE; + } + pick->avail = CURLAUTH_NONE; /* clear it here */ + + return picked; +} + +/* + * http_perhapsrewind() + * + * If we are doing POST or PUT { + * If we have more data to send { + * If we are doing NTLM { + * Keep sending since we must not disconnect + * } + * else { + * If there is more than just a little data left to send, close + * the current connection by force. + * } + * } + * If we have sent any data { + * If we don't have track of all the data { + * call app to tell it to rewind + * } + * else { + * rewind internally so that the operation can restart fine + * } + * } + * } + */ +static CURLcode http_perhapsrewind(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + struct HTTP *http = data->req.protop; + curl_off_t bytessent; + curl_off_t expectsend = -1; /* default is unknown */ + + if(!http) + /* If this is still NULL, we have not reach very far and we can safely + skip this rewinding stuff */ + return CURLE_OK; + + switch(data->set.httpreq) { + case HTTPREQ_GET: + case HTTPREQ_HEAD: + return CURLE_OK; + default: + break; + } + + bytessent = data->req.writebytecount; + + if(conn->bits.authneg) { + /* This is a state where we are known to be negotiating and we don't send + any data then. */ + expectsend = 0; + } + else if(!conn->bits.protoconnstart) { + /* HTTP CONNECT in progress: there is no body */ + expectsend = 0; + } + else { + /* figure out how much data we are expected to send */ + switch(data->set.httpreq) { + case HTTPREQ_POST: + if(data->state.infilesize != -1) + expectsend = data->state.infilesize; + break; + case HTTPREQ_PUT: + if(data->state.infilesize != -1) + expectsend = data->state.infilesize; + break; + case HTTPREQ_POST_FORM: + case HTTPREQ_POST_MIME: + expectsend = http->postsize; + break; + default: + break; + } + } + + conn->bits.rewindaftersend = FALSE; /* default */ + + if((expectsend == -1) || (expectsend > bytessent)) { +#if defined(USE_NTLM) + /* There is still data left to send */ + if((data->state.authproxy.picked == CURLAUTH_NTLM) || + (data->state.authhost.picked == CURLAUTH_NTLM) || + (data->state.authproxy.picked == CURLAUTH_NTLM_WB) || + (data->state.authhost.picked == CURLAUTH_NTLM_WB)) { + if(((expectsend - bytessent) < 2000) || + (conn->http_ntlm_state != NTLMSTATE_NONE) || + (conn->proxy_ntlm_state != NTLMSTATE_NONE)) { + /* The NTLM-negotiation has started *OR* there is just a little (<2K) + data left to send, keep on sending. */ + + /* rewind data when completely done sending! */ + if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) { + conn->bits.rewindaftersend = TRUE; + infof(data, "Rewind stream after send\n"); + } + + return CURLE_OK; + } + + if(conn->bits.close) + /* this is already marked to get closed */ + return CURLE_OK; + + infof(data, "NTLM send, close instead of sending %" + CURL_FORMAT_CURL_OFF_T " bytes\n", + (curl_off_t)(expectsend - bytessent)); + } +#endif +#if defined(USE_SPNEGO) + /* There is still data left to send */ + if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) || + (data->state.authhost.picked == CURLAUTH_NEGOTIATE)) { + if(((expectsend - bytessent) < 2000) || + (conn->http_negotiate_state != GSS_AUTHNONE) || + (conn->proxy_negotiate_state != GSS_AUTHNONE)) { + /* The NEGOTIATE-negotiation has started *OR* + there is just a little (<2K) data left to send, keep on sending. */ + + /* rewind data when completely done sending! */ + if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) { + conn->bits.rewindaftersend = TRUE; + infof(data, "Rewind stream after send\n"); + } + + return CURLE_OK; + } + + if(conn->bits.close) + /* this is already marked to get closed */ + return CURLE_OK; + + infof(data, "NEGOTIATE send, close instead of sending %" + CURL_FORMAT_CURL_OFF_T " bytes\n", + (curl_off_t)(expectsend - bytessent)); + } +#endif + + /* This is not NEGOTIATE/NTLM or many bytes left to send: close */ + streamclose(conn, "Mid-auth HTTP and much data left to send"); + data->req.size = 0; /* don't download any more than 0 bytes */ + + /* There still is data left to send, but this connection is marked for + closure so we can safely do the rewind right now */ + } + + if(bytessent) + /* we rewind now at once since if we already sent something */ + return Curl_readrewind(conn); + + return CURLE_OK; +} + +/* + * Curl_http_auth_act() gets called when all HTTP headers have been received + * and it checks what authentication methods that are available and decides + * which one (if any) to use. It will set 'newurl' if an auth method was + * picked. + */ + +CURLcode Curl_http_auth_act(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + bool pickhost = FALSE; + bool pickproxy = FALSE; + CURLcode result = CURLE_OK; + unsigned long authmask = ~0ul; + + if(!conn->oauth_bearer) + authmask &= (unsigned long)~CURLAUTH_BEARER; + + if(100 <= data->req.httpcode && 199 >= data->req.httpcode) + /* this is a transient response code, ignore */ + return CURLE_OK; + + if(data->state.authproblem) + return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK; + + if((conn->bits.user_passwd || conn->oauth_bearer) && + ((data->req.httpcode == 401) || + (conn->bits.authneg && data->req.httpcode < 300))) { + pickhost = pickoneauth(&data->state.authhost, authmask); + if(!pickhost) + data->state.authproblem = TRUE; + if(data->state.authhost.picked == CURLAUTH_NTLM && + conn->httpversion > 11) { + infof(data, "Forcing HTTP/1.1 for NTLM"); + connclose(conn, "Force HTTP/1.1 connection"); + conn->data->set.httpversion = CURL_HTTP_VERSION_1_1; + } + } + if(conn->bits.proxy_user_passwd && + ((data->req.httpcode == 407) || + (conn->bits.authneg && data->req.httpcode < 300))) { + pickproxy = pickoneauth(&data->state.authproxy, + authmask & ~CURLAUTH_BEARER); + if(!pickproxy) + data->state.authproblem = TRUE; + } + + if(pickhost || pickproxy) { + if((data->set.httpreq != HTTPREQ_GET) && + (data->set.httpreq != HTTPREQ_HEAD) && + !conn->bits.rewindaftersend) { + result = http_perhapsrewind(conn); + if(result) + return result; + } + /* In case this is GSS auth, the newurl field is already allocated so + we must make sure to free it before allocating a new one. As figured + out in bug #2284386 */ + Curl_safefree(data->req.newurl); + data->req.newurl = strdup(data->change.url); /* clone URL */ + if(!data->req.newurl) + return CURLE_OUT_OF_MEMORY; + } + else if((data->req.httpcode < 300) && + (!data->state.authhost.done) && + conn->bits.authneg) { + /* no (known) authentication available, + authentication is not "done" yet and + no authentication seems to be required and + we didn't try HEAD or GET */ + if((data->set.httpreq != HTTPREQ_GET) && + (data->set.httpreq != HTTPREQ_HEAD)) { + data->req.newurl = strdup(data->change.url); /* clone URL */ + if(!data->req.newurl) + return CURLE_OUT_OF_MEMORY; + data->state.authhost.done = TRUE; + } + } + if(http_should_fail(conn)) { + failf(data, "The requested URL returned error: %d", + data->req.httpcode); + result = CURLE_HTTP_RETURNED_ERROR; + } + + return result; +} + +#ifndef CURL_DISABLE_HTTP_AUTH +/* + * Output the correct authentication header depending on the auth type + * and whether or not it is to a proxy. + */ +static CURLcode +output_auth_headers(struct connectdata *conn, + struct auth *authstatus, + const char *request, + const char *path, + bool proxy) +{ + const char *auth = NULL; + CURLcode result = CURLE_OK; +//#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO) + struct Curl_easy *data = conn->data; +//#endif + +#ifdef CURL_DISABLE_CRYPTO_AUTH + (void)request; + (void)path; +#endif + +#ifdef USE_SPNEGO + if(authstatus->picked == CURLAUTH_NEGOTIATE) { + auth = "Negotiate"; + result = Curl_output_negotiate(conn, proxy); + if(result) + return result; + } + else +#endif +#ifdef USE_NTLM + if(authstatus->picked == CURLAUTH_NTLM) { + auth = "NTLM"; + result = Curl_output_ntlm(conn, proxy); + if(result) + return result; + } + else +#endif +#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED) + if(authstatus->picked == CURLAUTH_NTLM_WB) { + auth = "NTLM_WB"; + result = Curl_output_ntlm_wb(conn, proxy); + if(result) + return result; + } + else +#endif +#ifndef CURL_DISABLE_CRYPTO_AUTH + if(authstatus->picked == CURLAUTH_DIGEST) { + auth = "Digest"; + result = Curl_output_digest(conn, + proxy, + (const unsigned char *)request, + (const unsigned char *)path); + if(result) + return result; + } + else +#endif + if(authstatus->picked == CURLAUTH_BASIC) { + /* Basic */ + if((proxy && conn->bits.proxy_user_passwd && + !Curl_checkProxyheaders(conn, "Proxy-authorization")) || + (!proxy && conn->bits.user_passwd && + !Curl_checkheaders(conn, "Authorization"))) { + auth = "Basic"; + result = http_output_basic(conn, proxy); + if(result) + return result; + } + + /* NOTE: this function should set 'done' TRUE, as the other auth + functions work that way */ + authstatus->done = TRUE; + } + if(authstatus->picked == CURLAUTH_BEARER) { + /* Bearer */ + if((!proxy && conn->oauth_bearer && + !Curl_checkheaders(conn, "Authorization:"))) { + auth = "Bearer"; + result = http_output_bearer(conn); + if(result) + return result; + } + + /* NOTE: this function should set 'done' TRUE, as the other auth + functions work that way */ + authstatus->done = TRUE; + } + + if(auth) { + infof(data, "%s auth using %s with user '%s'\n", + proxy ? "Proxy" : "Server", auth, + proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") : + (conn->user ? conn->user : "")); + authstatus->multipass = (!authstatus->done) ? TRUE : FALSE; + } + else + authstatus->multipass = FALSE; + + return CURLE_OK; +} + +/** + * Curl_http_output_auth() setups the authentication headers for the + * host/proxy and the correct authentication + * method. conn->data->state.authdone is set to TRUE when authentication is + * done. + * + * @param conn all information about the current connection + * @param request pointer to the request keyword + * @param path pointer to the requested path; should include query part + * @param proxytunnel boolean if this is the request setting up a "proxy + * tunnel" + * + * @returns CURLcode + */ +CURLcode +Curl_http_output_auth(struct connectdata *conn, + const char *request, + const char *path, + bool proxytunnel) /* TRUE if this is the request setting + up the proxy tunnel */ +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct auth *authhost; + struct auth *authproxy; + + DEBUGASSERT(data); + + authhost = &data->state.authhost; + authproxy = &data->state.authproxy; + + if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) || + conn->bits.user_passwd || conn->oauth_bearer) + /* continue please */; + else { + authhost->done = TRUE; + authproxy->done = TRUE; + return CURLE_OK; /* no authentication with no user or password */ + } + + if(authhost->want && !authhost->picked) + /* The app has selected one or more methods, but none has been picked + so far by a server round-trip. Then we set the picked one to the + want one, and if this is one single bit it'll be used instantly. */ + authhost->picked = authhost->want; + + if(authproxy->want && !authproxy->picked) + /* The app has selected one or more methods, but none has been picked so + far by a proxy round-trip. Then we set the picked one to the want one, + and if this is one single bit it'll be used instantly. */ + authproxy->picked = authproxy->want; + +#ifndef CURL_DISABLE_PROXY + /* Send proxy authentication header if needed */ + if(conn->bits.httpproxy && + (conn->bits.tunnel_proxy == (bit)proxytunnel)) { + result = output_auth_headers(conn, authproxy, request, path, TRUE); + if(result) + return result; + } + else +#else + (void)proxytunnel; +#endif /* CURL_DISABLE_PROXY */ + /* we have no proxy so let's pretend we're done authenticating + with it */ + authproxy->done = TRUE; + + /* To prevent the user+password to get sent to other than the original + host due to a location-follow, we do some weirdo checks here */ + if(!data->state.this_is_a_follow || + conn->bits.netrc || + !data->state.first_host || + data->set.allow_auth_to_other_hosts || + strcasecompare(data->state.first_host, conn->host.name)) { + result = output_auth_headers(conn, authhost, request, path, FALSE); + } + else + authhost->done = TRUE; + + return result; +} + +#else +/* when disabled */ +CURLcode +Curl_http_output_auth(struct connectdata *conn, + const char *request, + const char *path, + bool proxytunnel) +{ + (void)conn; + (void)request; + (void)path; + (void)proxytunnel; + return CURLE_OK; +} +#endif + +/* + * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate: + * headers. They are dealt with both in the transfer.c main loop and in the + * proxy CONNECT loop. + */ + +CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, + const char *auth) /* the first non-space */ +{ + /* + * This resource requires authentication + */ + struct Curl_easy *data = conn->data; + +#ifdef USE_SPNEGO + curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state : + &conn->http_negotiate_state; +#endif + unsigned long *availp; + struct auth *authp; + + if(proxy) { + availp = &data->info.proxyauthavail; + authp = &data->state.authproxy; + } + else { + availp = &data->info.httpauthavail; + authp = &data->state.authhost; + } + + /* + * Here we check if we want the specific single authentication (using ==) and + * if we do, we initiate usage of it. + * + * If the provided authentication is wanted as one out of several accepted + * types (using &), we OR this authentication type to the authavail + * variable. + * + * Note: + * + * ->picked is first set to the 'want' value (one or more bits) before the + * request is sent, and then it is again set _after_ all response 401/407 + * headers have been received but then only to a single preferred method + * (bit). + */ + + while(*auth) { +#ifdef USE_SPNEGO + if(checkprefix("Negotiate", auth)) { + if((authp->avail & CURLAUTH_NEGOTIATE) || + Curl_auth_is_spnego_supported()) { + *availp |= CURLAUTH_NEGOTIATE; + authp->avail |= CURLAUTH_NEGOTIATE; + + if(authp->picked == CURLAUTH_NEGOTIATE) { + CURLcode result = Curl_input_negotiate(conn, proxy, auth); + if(!result) { + DEBUGASSERT(!data->req.newurl); + data->req.newurl = strdup(data->change.url); + if(!data->req.newurl) + return CURLE_OUT_OF_MEMORY; + data->state.authproblem = FALSE; + /* we received a GSS auth token and we dealt with it fine */ + *negstate = GSS_AUTHRECV; + } + else + data->state.authproblem = TRUE; + } + } + } + else +#endif +#ifdef USE_NTLM + /* NTLM support requires the SSL crypto libs */ + if(checkprefix("NTLM", auth)) { + if((authp->avail & CURLAUTH_NTLM) || + (authp->avail & CURLAUTH_NTLM_WB) || + Curl_auth_is_ntlm_supported()) { + *availp |= CURLAUTH_NTLM; + authp->avail |= CURLAUTH_NTLM; + + if(authp->picked == CURLAUTH_NTLM || + authp->picked == CURLAUTH_NTLM_WB) { + /* NTLM authentication is picked and activated */ + CURLcode result = Curl_input_ntlm(conn, proxy, auth); + if(!result) { + data->state.authproblem = FALSE; +#ifdef NTLM_WB_ENABLED + if(authp->picked == CURLAUTH_NTLM_WB) { + *availp &= ~CURLAUTH_NTLM; + authp->avail &= ~CURLAUTH_NTLM; + *availp |= CURLAUTH_NTLM_WB; + authp->avail |= CURLAUTH_NTLM_WB; + + result = Curl_input_ntlm_wb(conn, proxy, auth); + if(result) { + infof(data, "Authentication problem. Ignoring this.\n"); + data->state.authproblem = TRUE; + } + } +#endif + } + else { + infof(data, "Authentication problem. Ignoring this.\n"); + data->state.authproblem = TRUE; + } + } + } + } + else +#endif +#ifndef CURL_DISABLE_CRYPTO_AUTH + if(checkprefix("Digest", auth)) { + if((authp->avail & CURLAUTH_DIGEST) != 0) + infof(data, "Ignoring duplicate digest auth header.\n"); + else if(Curl_auth_is_digest_supported()) { + CURLcode result; + + *availp |= CURLAUTH_DIGEST; + authp->avail |= CURLAUTH_DIGEST; + + /* We call this function on input Digest headers even if Digest + * authentication isn't activated yet, as we need to store the + * incoming data from this header in case we are going to use + * Digest */ + result = Curl_input_digest(conn, proxy, auth); + if(result) { + infof(data, "Authentication problem. Ignoring this.\n"); + data->state.authproblem = TRUE; + } + } + } + else +#endif + if(checkprefix("Basic", auth)) { + *availp |= CURLAUTH_BASIC; + authp->avail |= CURLAUTH_BASIC; + if(authp->picked == CURLAUTH_BASIC) { + /* We asked for Basic authentication but got a 40X back + anyway, which basically means our name+password isn't + valid. */ + authp->avail = CURLAUTH_NONE; + infof(data, "Authentication problem. Ignoring this.\n"); + data->state.authproblem = TRUE; + } + } + else + if(checkprefix("Bearer", auth)) { + *availp |= CURLAUTH_BEARER; + authp->avail |= CURLAUTH_BEARER; + if(authp->picked == CURLAUTH_BEARER) { + /* We asked for Bearer authentication but got a 40X back + anyway, which basically means our token isn't valid. */ + authp->avail = CURLAUTH_NONE; + infof(data, "Authentication problem. Ignoring this.\n"); + data->state.authproblem = TRUE; + } + } + + /* there may be multiple methods on one line, so keep reading */ + while(*auth && *auth != ',') /* read up to the next comma */ + auth++; + if(*auth == ',') /* if we're on a comma, skip it */ + auth++; + while(*auth && ISSPACE(*auth)) + auth++; + } + + return CURLE_OK; +} + +/** + * http_should_fail() determines whether an HTTP response has gotten us + * into an error state or not. + * + * @param conn all information about the current connection + * + * @retval 0 communications should continue + * + * @retval 1 communications should not continue + */ +static int http_should_fail(struct connectdata *conn) +{ + struct Curl_easy *data; + int httpcode; + + DEBUGASSERT(conn); + data = conn->data; + DEBUGASSERT(data); + + httpcode = data->req.httpcode; + + /* + ** If we haven't been asked to fail on error, + ** don't fail. + */ + if(!data->set.http_fail_on_error) + return 0; + + /* + ** Any code < 400 is never terminal. + */ + if(httpcode < 400) + return 0; + + /* + ** Any code >= 400 that's not 401 or 407 is always + ** a terminal error + */ + if((httpcode != 401) && (httpcode != 407)) + return 1; + + /* + ** All we have left to deal with is 401 and 407 + */ + DEBUGASSERT((httpcode == 401) || (httpcode == 407)); + + /* + ** Examine the current authentication state to see if this + ** is an error. The idea is for this function to get + ** called after processing all the headers in a response + ** message. So, if we've been to asked to authenticate a + ** particular stage, and we've done it, we're OK. But, if + ** we're already completely authenticated, it's not OK to + ** get another 401 or 407. + ** + ** It is possible for authentication to go stale such that + ** the client needs to reauthenticate. Once that info is + ** available, use it here. + */ + + /* + ** Either we're not authenticating, or we're supposed to + ** be authenticating something else. This is an error. + */ + if((httpcode == 401) && !conn->bits.user_passwd) + return TRUE; + if((httpcode == 407) && !conn->bits.proxy_user_passwd) + return TRUE; + + return data->state.authproblem; +} + +/* + * readmoredata() is a "fread() emulation" to provide POST and/or request + * data. It is used when a huge POST is to be made and the entire chunk wasn't + * sent in the first send(). This function will then be called from the + * transfer.c loop when more data is to be sent to the peer. + * + * Returns the amount of bytes it filled the buffer with. + */ +static size_t readmoredata(char *buffer, + size_t size, + size_t nitems, + void *userp) +{ + struct connectdata *conn = (struct connectdata *)userp; + struct HTTP *http = conn->data->req.protop; + size_t fullsize = size * nitems; + + if(!http->postsize) + /* nothing to return */ + return 0; + + /* make sure that a HTTP request is never sent away chunked! */ + conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE; + + if(http->postsize <= (curl_off_t)fullsize) { + memcpy(buffer, http->postdata, (size_t)http->postsize); + fullsize = (size_t)http->postsize; + + if(http->backup.postsize) { + /* move backup data into focus and continue on that */ + http->postdata = http->backup.postdata; + http->postsize = http->backup.postsize; + conn->data->state.fread_func = http->backup.fread_func; + conn->data->state.in = http->backup.fread_in; + + http->sending++; /* move one step up */ + + http->backup.postsize = 0; + } + else + http->postsize = 0; + + return fullsize; + } + + memcpy(buffer, http->postdata, fullsize); + http->postdata += fullsize; + http->postsize -= fullsize; + + return fullsize; +} + +/* ------------------------------------------------------------------------- */ +/* add_buffer functions */ + +/* + * Curl_add_buffer_init() sets up and returns a fine buffer struct + */ +Curl_send_buffer *Curl_add_buffer_init(void) +{ + return calloc(1, sizeof(Curl_send_buffer)); +} + +/* + * Curl_add_buffer_free() frees all associated resources. + */ +void Curl_add_buffer_free(Curl_send_buffer **inp) +{ + Curl_send_buffer *in = *inp; + if(in) /* deal with NULL input */ + free(in->buffer); + free(in); + *inp = NULL; +} + +/* + * Curl_add_buffer_send() sends a header buffer and frees all associated + * memory. Body data may be appended to the header data if desired. + * + * Returns CURLcode + */ +CURLcode Curl_add_buffer_send(Curl_send_buffer **inp, + struct connectdata *conn, + + /* add the number of sent bytes to this + counter */ + curl_off_t *bytes_written, + + /* how much of the buffer contains body data */ + size_t included_body_bytes, + int socketindex) +{ + ssize_t amount; + CURLcode result; + char *ptr; + size_t size; + struct Curl_easy *data = conn->data; + struct HTTP *http = data->req.protop; + size_t sendsize; + curl_socket_t sockfd; + size_t headersize; + Curl_send_buffer *in = *inp; + + DEBUGASSERT(socketindex <= SECONDARYSOCKET); + + sockfd = conn->sock[socketindex]; + + /* The looping below is required since we use non-blocking sockets, but due + to the circumstances we will just loop and try again and again etc */ + + ptr = in->buffer; + size = in->size_used; + + headersize = size - included_body_bytes; /* the initial part that isn't body + is header */ + + DEBUGASSERT(size > included_body_bytes); + + result = Curl_convert_to_network(data, ptr, headersize); + /* Curl_convert_to_network calls failf if unsuccessful */ + if(result) { + /* conversion failed, free memory and return to the caller */ + Curl_add_buffer_free(inp); + return result; + } + + if((conn->handler->flags & PROTOPT_SSL || + conn->http_proxy.proxytype == CURLPROXY_HTTPS) + && conn->httpversion != 20) { + /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk + when we speak HTTPS, as if only a fraction of it is sent now, this data + needs to fit into the normal read-callback buffer later on and that + buffer is using this size. + */ + + sendsize = CURLMIN(size, CURL_MAX_WRITE_SIZE); + + /* OpenSSL is very picky and we must send the SAME buffer pointer to the + library when we attempt to re-send this buffer. Sending the same data + is not enough, we must use the exact same address. For this reason, we + must copy the data to the uploadbuffer first, since that is the buffer + we will be using if this send is retried later. + */ + result = Curl_get_upload_buffer(data); + if(result) { + /* malloc failed, free memory and return to the caller */ + Curl_add_buffer_free(&in); + return result; + } + memcpy(data->state.ulbuf, ptr, sendsize); + ptr = data->state.ulbuf; + } + else + sendsize = size; + + result = Curl_write(conn, sockfd, ptr, sendsize, &amount); + + if(!result) { + /* + * Note that we may not send the entire chunk at once, and we have a set + * number of data bytes at the end of the big buffer (out of which we may + * only send away a part). + */ + /* how much of the header that was sent */ + size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount; + size_t bodylen = amount - headlen; + + if(data->set.verbose) { + /* this data _may_ contain binary stuff */ + Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen); + if(bodylen) { + /* there was body data sent beyond the initial header part, pass that + on to the debug callback too */ + Curl_debug(data, CURLINFO_DATA_OUT, + ptr + headlen, bodylen); + } + } + + /* 'amount' can never be a very large value here so typecasting it so a + signed 31 bit value should not cause problems even if ssize_t is + 64bit */ + *bytes_written += (long)amount; + + if(http) { + /* if we sent a piece of the body here, up the byte counter for it + accordingly */ + data->req.writebytecount += bodylen; + Curl_pgrsSetUploadCounter(data, data->req.writebytecount); + + if((size_t)amount != size) { + /* The whole request could not be sent in one system call. We must + queue it up and send it later when we get the chance. We must not + loop here and wait until it might work again. */ + + size -= amount; + + ptr = in->buffer + amount; + + /* backup the currently set pointers */ + http->backup.fread_func = data->state.fread_func; + http->backup.fread_in = data->state.in; + http->backup.postdata = http->postdata; + http->backup.postsize = http->postsize; + + /* set the new pointers for the request-sending */ + data->state.fread_func = (curl_read_callback)readmoredata; + data->state.in = (void *)conn; + http->postdata = ptr; + http->postsize = (curl_off_t)size; + + http->send_buffer = in; + http->sending = HTTPSEND_REQUEST; + + return CURLE_OK; + } + http->sending = HTTPSEND_BODY; + /* the full buffer was sent, clean up and return */ + } + else { + if((size_t)amount != size) + /* We have no continue-send mechanism now, fail. This can only happen + when this function is used from the CONNECT sending function. We + currently (stupidly) assume that the whole request is always sent + away in the first single chunk. + + This needs FIXing. + */ + return CURLE_SEND_ERROR; + } + } + Curl_add_buffer_free(&in); + + return result; +} + + +/* + * add_bufferf() add the formatted input to the buffer. + */ +CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const char *fmt, ...) +{ + char *s; + va_list ap; + Curl_send_buffer *in = *inp; + va_start(ap, fmt); + s = vaprintf(fmt, ap); /* this allocs a new string to append */ + va_end(ap); + + if(s) { + CURLcode result = Curl_add_buffer(inp, s, strlen(s)); + free(s); + return result; + } + /* If we failed, we cleanup the whole buffer and return error */ + free(in->buffer); + free(in); + *inp = NULL; + return CURLE_OUT_OF_MEMORY; +} + +/* + * Curl_add_buffer() appends a memory chunk to the existing buffer + */ +CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr, + size_t size) +{ + char *new_rb; + Curl_send_buffer *in = *inp; + + if(~size < in->size_used) { + /* If resulting used size of send buffer would wrap size_t, cleanup + the whole buffer and return error. Otherwise the required buffer + size will fit into a single allocatable memory chunk */ + Curl_safefree(in->buffer); + free(in); + *inp = NULL; + return CURLE_OUT_OF_MEMORY; + } + + if(!in->buffer || + ((in->size_used + size) > (in->size_max - 1))) { + /* If current buffer size isn't enough to hold the result, use a + buffer size that doubles the required size. If this new size + would wrap size_t, then just use the largest possible one */ + size_t new_size; + + if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) || + (~(size * 2) < (in->size_used * 2))) + new_size = (size_t)-1; + else + new_size = (in->size_used + size) * 2; + + if(in->buffer) + /* we have a buffer, enlarge the existing one */ + new_rb = Curl_saferealloc(in->buffer, new_size); + else + /* create a new buffer */ + new_rb = malloc(new_size); + + if(!new_rb) { + /* If we failed, we cleanup the whole buffer and return error */ + free(in); + *inp = NULL; + return CURLE_OUT_OF_MEMORY; + } + + in->buffer = new_rb; + in->size_max = new_size; + } + memcpy(&in->buffer[in->size_used], inptr, size); + + in->size_used += size; + + return CURLE_OK; +} + +/* end of the add_buffer functions */ +/* ------------------------------------------------------------------------- */ + + + +/* + * Curl_compareheader() + * + * Returns TRUE if 'headerline' contains the 'header' with given 'content'. + * Pass headers WITH the colon. + */ +bool +Curl_compareheader(const char *headerline, /* line to check */ + const char *header, /* header keyword _with_ colon */ + const char *content) /* content string to find */ +{ + /* RFC2616, section 4.2 says: "Each header field consists of a name followed + * by a colon (":") and the field value. Field names are case-insensitive. + * The field value MAY be preceded by any amount of LWS, though a single SP + * is preferred." */ + + size_t hlen = strlen(header); + size_t clen; + size_t len; + const char *start; + const char *end; + + if(!strncasecompare(headerline, header, hlen)) + return FALSE; /* doesn't start with header */ + + /* pass the header */ + start = &headerline[hlen]; + + /* pass all white spaces */ + while(*start && ISSPACE(*start)) + start++; + + /* find the end of the header line */ + end = strchr(start, '\r'); /* lines end with CRLF */ + if(!end) { + /* in case there's a non-standard compliant line here */ + end = strchr(start, '\n'); + + if(!end) + /* hm, there's no line ending here, use the zero byte! */ + end = strchr(start, '\0'); + } + + len = end-start; /* length of the content part of the input line */ + clen = strlen(content); /* length of the word to find */ + + /* find the content string in the rest of the line */ + for(; len >= clen; len--, start++) { + if(strncasecompare(start, content, clen)) + return TRUE; /* match! */ + } + + return FALSE; /* no match */ +} + +/* + * Curl_http_connect() performs HTTP stuff to do at connect-time, called from + * the generic Curl_connect(). + */ +CURLcode Curl_http_connect(struct connectdata *conn, bool *done) +{ + CURLcode result; + + /* We default to persistent connections. We set this already in this connect + function to make the re-use checks properly be able to check this bit. */ + connkeep(conn, "HTTP default"); + + /* the CONNECT procedure might not have been completed */ + result = Curl_proxy_connect(conn, FIRSTSOCKET); + if(result) + return result; + + if(conn->bits.proxy_connect_closed) + /* this is not an error, just part of the connection negotiation */ + return CURLE_OK; + + if(CONNECT_FIRSTSOCKET_PROXY_SSL()) + return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */ + + if(Curl_connect_ongoing(conn)) + /* nothing else to do except wait right now - we're not done here. */ + return CURLE_OK; + +#ifndef CURL_DISABLE_PROXY + if(conn->data->set.haproxyprotocol) { + /* add HAProxy PROXY protocol header */ + result = add_haproxy_protocol_header(conn); + if(result) + return result; + } +#endif + + if(conn->given->protocol & CURLPROTO_HTTPS) { + /* perform SSL initialization */ + result = https_connecting(conn, done); + if(result) + return result; + } + else + *done = TRUE; + + return CURLE_OK; +} + +/* this returns the socket to wait for in the DO and DOING state for the multi + interface and then we're always _sending_ a request and thus we wait for + the single socket to become writable only */ +static int http_getsock_do(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) +{ + /* write mode */ + (void)numsocks; /* unused, we trust it to be at least 1 */ + socks[0] = conn->sock[FIRSTSOCKET]; + return GETSOCK_WRITESOCK(0); +} + +#ifndef CURL_DISABLE_PROXY +static CURLcode add_haproxy_protocol_header(struct connectdata *conn) +{ + char proxy_header[128]; + Curl_send_buffer *req_buffer; + CURLcode result; + char tcp_version[5]; + + /* Emit the correct prefix for IPv6 */ + if(conn->bits.ipv6) { + strcpy(tcp_version, "TCP6"); + } + else { + strcpy(tcp_version, "TCP4"); + } + + msnprintf(proxy_header, + sizeof(proxy_header), + "PROXY %s %s %s %li %li\r\n", + tcp_version, + conn->data->info.conn_local_ip, + conn->data->info.conn_primary_ip, + conn->data->info.conn_local_port, + conn->data->info.conn_primary_port); + + req_buffer = Curl_add_buffer_init(); + if(!req_buffer) + return CURLE_OUT_OF_MEMORY; + + result = Curl_add_bufferf(&req_buffer, proxy_header); + if(result) + return result; + + result = Curl_add_buffer_send(&req_buffer, + conn, + &conn->data->info.request_size, + 0, + FIRSTSOCKET); + + return result; +} +#endif + +#ifdef USE_SSL +static CURLcode https_connecting(struct connectdata *conn, bool *done) +{ + CURLcode result; + DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL)); + + /* perform SSL initialization for this socket */ + result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done); + if(result) + connclose(conn, "Failed HTTPS connection"); + + return result; +} + +static int https_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) +{ + if(conn->handler->flags & PROTOPT_SSL) + return Curl_ssl_getsock(conn, socks, numsocks); + return GETSOCK_BLANK; +} +#endif /* USE_SSL */ + +/* + * Curl_http_done() gets called after a single HTTP request has been + * performed. + */ + +CURLcode Curl_http_done(struct connectdata *conn, + CURLcode status, bool premature) +{ + struct Curl_easy *data = conn->data; + struct HTTP *http = data->req.protop; + + /* Clear multipass flag. If authentication isn't done yet, then it will get + * a chance to be set back to true when we output the next auth header */ + data->state.authhost.multipass = FALSE; + data->state.authproxy.multipass = FALSE; + + Curl_unencode_cleanup(conn); + + /* set the proper values (possibly modified on POST) */ + conn->seek_func = data->set.seek_func; /* restore */ + conn->seek_client = data->set.seek_client; /* restore */ + + if(!http) + return CURLE_OK; + + if(http->send_buffer) { + Curl_add_buffer_free(&http->send_buffer); + } + + Curl_http2_done(conn, premature); + + Curl_mime_cleanpart(&http->form); + + if(status) + return status; + + if(!premature && /* this check is pointless when DONE is called before the + entire operation is complete */ + !conn->bits.retry && + !data->set.connect_only && + (data->req.bytecount + + data->req.headerbytecount - + data->req.deductheadercount) <= 0) { + /* If this connection isn't simply closed to be retried, AND nothing was + read from the HTTP server (that counts), this can't be right so we + return an error here */ + failf(data, "Empty reply from server"); + return CURLE_GOT_NOTHING; + } + + return CURLE_OK; +} + +/* + * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons + * to avoid it include: + * + * - if the user specifically requested HTTP 1.0 + * - if the server we are connected to only supports 1.0 + * - if any server previously contacted to handle this request only supports + * 1.0. + */ +static bool use_http_1_1plus(const struct Curl_easy *data, + const struct connectdata *conn) +{ + if((data->state.httpversion == 10) || (conn->httpversion == 10)) + return FALSE; + if((data->set.httpversion == CURL_HTTP_VERSION_1_0) && + (conn->httpversion <= 10)) + return FALSE; + return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) || + (data->set.httpversion >= CURL_HTTP_VERSION_1_1)); +} + +static const char *get_http_string(const struct Curl_easy *data, + const struct connectdata *conn) +{ +#ifdef USE_NGHTTP2 + if(conn->proto.httpc.h2) + return "2"; +#endif + + if(use_http_1_1plus(data, conn)) + return "1.1"; + + return "1.0"; +} + +/* check and possibly add an Expect: header */ +static CURLcode expect100(struct Curl_easy *data, + struct connectdata *conn, + Curl_send_buffer *req_buffer) +{ + CURLcode result = CURLE_OK; + data->state.expect100header = FALSE; /* default to false unless it is set + to TRUE below */ + if(use_http_1_1plus(data, conn) && + (conn->httpversion != 20)) { + /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an + Expect: 100-continue to the headers which actually speeds up post + operations (as there is one packet coming back from the web server) */ + const char *ptr = Curl_checkheaders(conn, "Expect"); + if(ptr) { + data->state.expect100header = + Curl_compareheader(ptr, "Expect:", "100-continue"); + } + else { + result = Curl_add_bufferf(&req_buffer, + "Expect: 100-continue\r\n"); + if(!result) + data->state.expect100header = TRUE; + } + } + + return result; +} + +enum proxy_use { + HEADER_SERVER, /* direct to server */ + HEADER_PROXY, /* regular request to proxy */ + HEADER_CONNECT /* sending CONNECT to a proxy */ +}; + +/* used to compile the provided trailers into one buffer + will return an error code if one of the headers is + not formatted correctly */ +CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, + Curl_send_buffer *buffer, + struct Curl_easy *handle) +{ + char *ptr = NULL; + CURLcode result = CURLE_OK; + const char *endofline_native = NULL; + const char *endofline_network = NULL; + + if( +#ifdef CURL_DO_LINEEND_CONV + (handle->set.prefer_ascii) || +#endif + (handle->set.crlf)) { + /* \n will become \r\n later on */ + endofline_native = "\n"; + endofline_network = "\x0a"; + } + else { + endofline_native = "\r\n"; + endofline_network = "\x0d\x0a"; + } + + while(trailers) { + /* only add correctly formatted trailers */ + ptr = strchr(trailers->data, ':'); + if(ptr && *(ptr + 1) == ' ') { + result = Curl_add_bufferf(&buffer, "%s%s", trailers->data, + endofline_native); + if(result) + return result; + } + else + infof(handle, "Malformatted trailing header ! Skipping trailer."); + trailers = trailers->next; + } + result = Curl_add_buffer(&buffer, endofline_network, + strlen(endofline_network)); + return result; +} + +CURLcode Curl_add_custom_headers(struct connectdata *conn, + bool is_connect, + Curl_send_buffer *req_buffer) +{ + char *ptr; + struct curl_slist *h[2]; + struct curl_slist *headers; + int numlists = 1; /* by default */ + struct Curl_easy *data = conn->data; + int i; + + enum proxy_use proxy; + + if(is_connect) + proxy = HEADER_CONNECT; + else + proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy? + HEADER_PROXY:HEADER_SERVER; + + switch(proxy) { + case HEADER_SERVER: + h[0] = data->set.headers; + break; + case HEADER_PROXY: + h[0] = data->set.headers; + if(data->set.sep_headers) { + h[1] = data->set.proxyheaders; + numlists++; + } + break; + case HEADER_CONNECT: + if(data->set.sep_headers) + h[0] = data->set.proxyheaders; + else + h[0] = data->set.headers; + break; + } + + /* loop through one or two lists */ + for(i = 0; i < numlists; i++) { + headers = h[i]; + + while(headers) { + char *semicolonp = NULL; + ptr = strchr(headers->data, ':'); + if(!ptr) { + char *optr; + /* no colon, semicolon? */ + ptr = strchr(headers->data, ';'); + if(ptr) { + optr = ptr; + ptr++; /* pass the semicolon */ + while(*ptr && ISSPACE(*ptr)) + ptr++; + + if(*ptr) { + /* this may be used for something else in the future */ + optr = NULL; + } + else { + if(*(--ptr) == ';') { + /* copy the source */ + semicolonp = strdup(headers->data); + if(!semicolonp) { + Curl_add_buffer_free(&req_buffer); + return CURLE_OUT_OF_MEMORY; + } + /* put a colon where the semicolon is */ + semicolonp[ptr - headers->data] = ':'; + /* point at the colon */ + optr = &semicolonp [ptr - headers->data]; + } + } + ptr = optr; + } + } + if(ptr) { + /* we require a colon for this to be a true header */ + + ptr++; /* pass the colon */ + while(*ptr && ISSPACE(*ptr)) + ptr++; + + if(*ptr || semicolonp) { + /* only send this if the contents was non-blank or done special */ + CURLcode result = CURLE_OK; + char *compare = semicolonp ? semicolonp : headers->data; + + if(conn->allocptr.host && + /* a Host: header was sent already, don't pass on any custom Host: + header as that will produce *two* in the same request! */ + checkprefix("Host:", compare)) + ; + else if(data->set.httpreq == HTTPREQ_POST_FORM && + /* this header (extended by formdata.c) is sent later */ + checkprefix("Content-Type:", compare)) + ; + else if(data->set.httpreq == HTTPREQ_POST_MIME && + /* this header is sent later */ + checkprefix("Content-Type:", compare)) + ; + else if(conn->bits.authneg && + /* while doing auth neg, don't allow the custom length since + we will force length zero then */ + checkprefix("Content-Length:", compare)) + ; + else if(conn->allocptr.te && + /* when asking for Transfer-Encoding, don't pass on a custom + Connection: */ + checkprefix("Connection:", compare)) + ; + else if((conn->httpversion == 20) && + checkprefix("Transfer-Encoding:", compare)) + /* HTTP/2 doesn't support chunked requests */ + ; + else if((checkprefix("Authorization:", compare) || + checkprefix("Cookie:", compare)) && + /* be careful of sending this potentially sensitive header to + other hosts */ + (data->state.this_is_a_follow && + data->state.first_host && + !data->set.allow_auth_to_other_hosts && + !strcasecompare(data->state.first_host, conn->host.name))) + ; + else { + result = Curl_add_bufferf(&req_buffer, "%s\r\n", compare); + } + if(semicolonp) + free(semicolonp); + if(result) + return result; + } + } + headers = headers->next; + } + } + + return CURLE_OK; +} + +#ifndef CURL_DISABLE_PARSEDATE +CURLcode Curl_add_timecondition(const struct connectdata *conn, + Curl_send_buffer *req_buffer) +{ + struct Curl_easy *data = conn->data; + const struct tm *tm; + struct tm keeptime; + CURLcode result; + char datestr[80]; + const char *condp; + + if(data->set.timecondition == CURL_TIMECOND_NONE) + /* no condition was asked for */ + return CURLE_OK; + + result = Curl_gmtime(data->set.timevalue, &keeptime); + if(result) { + failf(data, "Invalid TIMEVALUE"); + return result; + } + tm = &keeptime; + + switch(data->set.timecondition) { + default: + return CURLE_BAD_FUNCTION_ARGUMENT; + + case CURL_TIMECOND_IFMODSINCE: + condp = "If-Modified-Since"; + break; + case CURL_TIMECOND_IFUNMODSINCE: + condp = "If-Unmodified-Since"; + break; + case CURL_TIMECOND_LASTMOD: + condp = "Last-Modified"; + break; + } + + if(Curl_checkheaders(conn, condp)) { + /* A custom header was specified; it will be sent instead. */ + return CURLE_OK; + } + + /* The If-Modified-Since header family should have their times set in + * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be + * represented in Greenwich Mean Time (GMT), without exception. For the + * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal + * Time)." (see page 20 of RFC2616). + */ + + /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ + msnprintf(datestr, sizeof(datestr), + "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", + condp, + Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], + tm->tm_mday, + Curl_month[tm->tm_mon], + tm->tm_year + 1900, + tm->tm_hour, + tm->tm_min, + tm->tm_sec); + + result = Curl_add_buffer(&req_buffer, datestr, strlen(datestr)); + + return result; +} +#else +/* disabled */ +CURLcode Curl_add_timecondition(const struct connectdata *conn, + Curl_send_buffer *req_buffer) +{ + (void)conn; + (void)req_buffer; + return CURLE_OK; +} +#endif + +/* + * Curl_http() gets called from the generic multi_do() function when a HTTP + * request is to be performed. This creates and sends a properly constructed + * HTTP request. + */ +CURLcode Curl_http(struct connectdata *conn, bool *done) +{ + struct Curl_easy *data = conn->data; + CURLcode result = CURLE_OK; + struct HTTP *http; + const char *path = data->state.up.path; + const char *query = data->state.up.query; + bool paste_ftp_userpwd = FALSE; + char ftp_typecode[sizeof("/;type=?")] = ""; + const char *host = conn->host.name; + const char *te = ""; /* transfer-encoding */ + const char *ptr; + const char *request; + Curl_HttpReq httpreq = data->set.httpreq; +#if !defined(CURL_DISABLE_COOKIES) + char *addcookies = NULL; +#endif + curl_off_t included_body = 0; + const char *httpstring; + Curl_send_buffer *req_buffer; + curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */ + + /* Always consider the DO phase done after this function call, even if there + may be parts of the request that is not yet sent, since we can deal with + the rest of the request in the PERFORM phase. */ + *done = TRUE; + + if(conn->httpversion < 20) { /* unless the connection is re-used and already + http2 */ + switch(conn->negnpn) { + case CURL_HTTP_VERSION_2: + conn->httpversion = 20; /* we know we're on HTTP/2 now */ + + result = Curl_http2_switched(conn, NULL, 0); + if(result) + return result; + break; + case CURL_HTTP_VERSION_1_1: + /* continue with HTTP/1.1 when explicitly requested */ + break; + default: + /* Check if user wants to use HTTP/2 with clear TCP*/ +#ifdef USE_NGHTTP2 + if(conn->data->set.httpversion == + CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) { + if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { + /* We don't support HTTP/2 proxies yet. Also it's debatable whether + or not this setting should apply to HTTP/2 proxies. */ + infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n"); + break; + } + + DEBUGF(infof(data, "HTTP/2 over clean TCP\n")); + conn->httpversion = 20; + + result = Curl_http2_switched(conn, NULL, 0); + if(result) + return result; + } +#endif + break; + } + } + else { + /* prepare for a http2 request */ + result = Curl_http2_setup(conn); + if(result) + return result; + } + + http = data->req.protop; + DEBUGASSERT(http); + + if(!data->state.this_is_a_follow) { + /* Free to avoid leaking memory on multiple requests*/ + free(data->state.first_host); + + data->state.first_host = strdup(conn->host.name); + if(!data->state.first_host) + return CURLE_OUT_OF_MEMORY; + + data->state.first_remote_port = conn->remote_port; + } + + if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) && + data->set.upload) { + httpreq = HTTPREQ_PUT; + } + + /* Now set the 'request' pointer to the proper request string */ + if(data->set.str[STRING_CUSTOMREQUEST]) + request = data->set.str[STRING_CUSTOMREQUEST]; + else { + if(data->set.opt_no_body) + request = "HEAD"; + else { + DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST)); + switch(httpreq) { + case HTTPREQ_POST: + case HTTPREQ_POST_FORM: + case HTTPREQ_POST_MIME: + request = "POST"; + break; + case HTTPREQ_PUT: + request = "PUT"; + break; + case HTTPREQ_OPTIONS: + request = "OPTIONS"; + break; + default: /* this should never happen */ + case HTTPREQ_GET: + request = "GET"; + break; + case HTTPREQ_HEAD: + request = "HEAD"; + break; + } + } + } + + /* The User-Agent string might have been allocated in url.c already, because + it might have been used in the proxy connect, but if we have got a header + with the user-agent string specified, we erase the previously made string + here. */ + if(Curl_checkheaders(conn, "User-Agent")) { + free(conn->allocptr.uagent); + conn->allocptr.uagent = NULL; + } + + /* setup the authentication headers */ + { + char *pq = NULL; + if(query && *query) { + pq = aprintf("%s?%s", path, query); + if(!pq) + return CURLE_OUT_OF_MEMORY; + } + result = Curl_http_output_auth(conn, request, (pq ? pq : path), FALSE); + free(pq); + if(result) + return result; + } + + if(((data->state.authhost.multipass && !data->state.authhost.done) + || (data->state.authproxy.multipass && !data->state.authproxy.done)) && + (httpreq != HTTPREQ_GET) && + (httpreq != HTTPREQ_HEAD)) { + /* Auth is required and we are not authenticated yet. Make a PUT or POST + with content-length zero as a "probe". */ + conn->bits.authneg = TRUE; + } + else + conn->bits.authneg = FALSE; + + Curl_safefree(conn->allocptr.ref); + if(data->change.referer && !Curl_checkheaders(conn, "Referer")) { + conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer); + if(!conn->allocptr.ref) + return CURLE_OUT_OF_MEMORY; + } + else + conn->allocptr.ref = NULL; + +#if !defined(CURL_DISABLE_COOKIES) + if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie")) + addcookies = data->set.str[STRING_COOKIE]; +#endif + + if(!Curl_checkheaders(conn, "Accept-Encoding") && + data->set.str[STRING_ENCODING]) { + Curl_safefree(conn->allocptr.accept_encoding); + conn->allocptr.accept_encoding = + aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]); + if(!conn->allocptr.accept_encoding) + return CURLE_OUT_OF_MEMORY; + } + else { + Curl_safefree(conn->allocptr.accept_encoding); + conn->allocptr.accept_encoding = NULL; + } + +#ifdef HAVE_LIBZ + /* we only consider transfer-encoding magic if libz support is built-in */ + + if(!Curl_checkheaders(conn, "TE") && + data->set.http_transfer_encoding) { + /* When we are to insert a TE: header in the request, we must also insert + TE in a Connection: header, so we need to merge the custom provided + Connection: header and prevent the original to get sent. Note that if + the user has inserted his/hers own TE: header we don't do this magic + but then assume that the user will handle it all! */ + char *cptr = Curl_checkheaders(conn, "Connection"); +#define TE_HEADER "TE: gzip\r\n" + + Curl_safefree(conn->allocptr.te); + + if(cptr) { + cptr = Curl_copy_header_value(cptr); + if(!cptr) + return CURLE_OUT_OF_MEMORY; + } + + /* Create the (updated) Connection: header */ + conn->allocptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER, + cptr ? cptr : "", (cptr && *cptr) ? ", ":""); + + free(cptr); + if(!conn->allocptr.te) + return CURLE_OUT_OF_MEMORY; + } +#endif + + switch(httpreq) { + case HTTPREQ_POST_MIME: + http->sendit = &data->set.mimepost; + break; + case HTTPREQ_POST_FORM: + /* Convert the form structure into a mime structure. */ + Curl_mime_cleanpart(&http->form); + result = Curl_getformdata(data, &http->form, data->set.httppost, + data->state.fread_func); + if(result) + return result; + http->sendit = &http->form; + break; + default: + http->sendit = NULL; + } + +#ifndef CURL_DISABLE_MIME + if(http->sendit) { + const char *cthdr = Curl_checkheaders(conn, "Content-Type"); + + /* Read and seek body only. */ + http->sendit->flags |= MIME_BODY_ONLY; + + /* Prepare the mime structure headers & set content type. */ + + if(cthdr) + for(cthdr += 13; *cthdr == ' '; cthdr++) + ; + else if(http->sendit->kind == MIMEKIND_MULTIPART) + cthdr = "multipart/form-data"; + + curl_mime_headers(http->sendit, data->set.headers, 0); + result = Curl_mime_prepare_headers(http->sendit, cthdr, + NULL, MIMESTRATEGY_FORM); + curl_mime_headers(http->sendit, NULL, 0); + if(!result) + result = Curl_mime_rewind(http->sendit); + if(result) + return result; + http->postsize = Curl_mime_size(http->sendit); + } +#endif + + ptr = Curl_checkheaders(conn, "Transfer-Encoding"); + if(ptr) { + /* Some kind of TE is requested, check if 'chunked' is chosen */ + data->req.upload_chunky = + Curl_compareheader(ptr, "Transfer-Encoding:", "chunked"); + } + else { + if((conn->handler->protocol & PROTO_FAMILY_HTTP) && + (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) && + http->postsize < 0) || + (data->set.upload && data->state.infilesize == -1))) { + if(conn->bits.authneg) + /* don't enable chunked during auth neg */ + ; + else if(use_http_1_1plus(data, conn)) { + /* HTTP, upload, unknown file size and not HTTP 1.0 */ + data->req.upload_chunky = TRUE; + } + else { + failf(data, "Chunky upload is not supported by HTTP 1.0"); + return CURLE_UPLOAD_FAILED; + } + } + else { + /* else, no chunky upload */ + data->req.upload_chunky = FALSE; + } + + if(data->req.upload_chunky) + te = "Transfer-Encoding: chunked\r\n"; + } + + Curl_safefree(conn->allocptr.host); + + ptr = Curl_checkheaders(conn, "Host"); + if(ptr && (!data->state.this_is_a_follow || + strcasecompare(data->state.first_host, conn->host.name))) { +#if !defined(CURL_DISABLE_COOKIES) + /* If we have a given custom Host: header, we extract the host name in + order to possibly use it for cookie reasons later on. We only allow the + custom Host: header if this is NOT a redirect, as setting Host: in the + redirected request is being out on thin ice. Except if the host name + is the same as the first one! */ + char *cookiehost = Curl_copy_header_value(ptr); + if(!cookiehost) + return CURLE_OUT_OF_MEMORY; + if(!*cookiehost) + /* ignore empty data */ + free(cookiehost); + else { + /* If the host begins with '[', we start searching for the port after + the bracket has been closed */ + if(*cookiehost == '[') { + char *closingbracket; + /* since the 'cookiehost' is an allocated memory area that will be + freed later we cannot simply increment the pointer */ + memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1); + closingbracket = strchr(cookiehost, ']'); + if(closingbracket) + *closingbracket = 0; + } + else { + int startsearch = 0; + char *colon = strchr(cookiehost + startsearch, ':'); + if(colon) + *colon = 0; /* The host must not include an embedded port number */ + } + Curl_safefree(conn->allocptr.cookiehost); + conn->allocptr.cookiehost = cookiehost; + } +#endif + + if(strcmp("Host:", ptr)) { + conn->allocptr.host = aprintf("Host:%s\r\n", &ptr[5]); + if(!conn->allocptr.host) + return CURLE_OUT_OF_MEMORY; + } + else + /* when clearing the header */ + conn->allocptr.host = NULL; + } + else { + /* When building Host: headers, we must put the host name within + [brackets] if the host name is a plain IPv6-address. RFC2732-style. */ + + if(((conn->given->protocol&CURLPROTO_HTTPS) && + (conn->remote_port == PORT_HTTPS)) || + ((conn->given->protocol&CURLPROTO_HTTP) && + (conn->remote_port == PORT_HTTP)) ) + /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include + the port number in the host string */ + conn->allocptr.host = aprintf("Host: %s%s%s\r\n", + conn->bits.ipv6_ip?"[":"", + host, + conn->bits.ipv6_ip?"]":""); + else + conn->allocptr.host = aprintf("Host: %s%s%s:%d\r\n", + conn->bits.ipv6_ip?"[":"", + host, + conn->bits.ipv6_ip?"]":"", + conn->remote_port); + + if(!conn->allocptr.host) + /* without Host: we can't make a nice request */ + return CURLE_OUT_OF_MEMORY; + } + +#ifndef CURL_DISABLE_PROXY + if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { + /* Using a proxy but does not tunnel through it */ + + /* The path sent to the proxy is in fact the entire URL. But if the remote + host is a IDN-name, we must make sure that the request we produce only + uses the encoded host name! */ + + /* and no fragment part */ + CURLUcode uc; + char *url; + CURLU *h = curl_url_dup(data->state.uh); + if(!h) + return CURLE_OUT_OF_MEMORY; + + if(conn->host.dispname != conn->host.name) { + uc = curl_url_set(h, CURLUPART_HOST, conn->host.name, 0); + if(uc) { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; + } + } + uc = curl_url_set(h, CURLUPART_FRAGMENT, NULL, 0); + if(uc) { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; + } + + if(strcasecompare("http", data->state.up.scheme)) { + /* when getting HTTP, we don't want the userinfo the URL */ + uc = curl_url_set(h, CURLUPART_USER, NULL, 0); + if(uc) { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; + } + uc = curl_url_set(h, CURLUPART_PASSWORD, NULL, 0); + if(uc) { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; + } + } + /* now extract the new version of the URL */ + uc = curl_url_get(h, CURLUPART_URL, &url, 0); + if(uc) { + curl_url_cleanup(h); + return CURLE_OUT_OF_MEMORY; + } + + if(data->change.url_alloc) + free(data->change.url); + + data->change.url = url; + data->change.url_alloc = TRUE; + + curl_url_cleanup(h); + + if(strcasecompare("ftp", data->state.up.scheme)) { + if(data->set.proxy_transfer_mode) { + /* when doing ftp, append ;type= if not present */ + char *type = strstr(path, ";type="); + if(type && type[6] && type[7] == 0) { + switch(Curl_raw_toupper(type[6])) { + case 'A': + case 'D': + case 'I': + break; + default: + type = NULL; + } + } + if(!type) { + char *p = ftp_typecode; + /* avoid sending invalid URLs like ftp://example.com;type=i if the + * user specified ftp://example.com without the slash */ + if(!*data->state.up.path && path[strlen(path) - 1] != '/') { + *p++ = '/'; + } + msnprintf(p, sizeof(ftp_typecode) - 1, ";type=%c", + data->set.prefer_ascii ? 'a' : 'i'); + } + } + if(conn->bits.user_passwd && !conn->bits.userpwd_in_url) + paste_ftp_userpwd = TRUE; + } + } +#endif /* CURL_DISABLE_PROXY */ + + http->p_accept = Curl_checkheaders(conn, "Accept")?NULL:"Accept: */*\r\n"; + + if((HTTPREQ_POST == httpreq || HTTPREQ_PUT == httpreq) && + data->state.resume_from) { + /********************************************************************** + * Resuming upload in HTTP means that we PUT or POST and that we have + * got a resume_from value set. The resume value has already created + * a Range: header that will be passed along. We need to "fast forward" + * the file the given number of bytes and decrease the assume upload + * file size before we continue this venture in the dark lands of HTTP. + * Resuming mime/form posting at an offset > 0 has no sense and is ignored. + *********************************************************************/ + + if(data->state.resume_from < 0) { + /* + * This is meant to get the size of the present remote-file by itself. + * We don't support this now. Bail out! + */ + data->state.resume_from = 0; + } + + if(data->state.resume_from && !data->state.this_is_a_follow) { + /* do we still game? */ + + /* Now, let's read off the proper amount of bytes from the + input. */ + int seekerr = CURL_SEEKFUNC_CANTSEEK; + if(conn->seek_func) { + Curl_set_in_callback(data, true); + seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, + SEEK_SET); + Curl_set_in_callback(data, false); + } + + if(seekerr != CURL_SEEKFUNC_OK) { + curl_off_t passed = 0; + + if(seekerr != CURL_SEEKFUNC_CANTSEEK) { + failf(data, "Could not seek stream"); + return CURLE_READ_ERROR; + } + /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ + do { + size_t readthisamountnow = + (data->state.resume_from - passed > data->set.buffer_size) ? + (size_t)data->set.buffer_size : + curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = + data->state.fread_func(data->state.buffer, 1, readthisamountnow, + data->state.in); + + passed += actuallyread; + if((actuallyread == 0) || (actuallyread > readthisamountnow)) { + /* this checks for greater-than only to make sure that the + CURL_READFUNC_ABORT return code still aborts */ + failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T + " bytes from the input", passed); + return CURLE_READ_ERROR; + } + } while(passed < data->state.resume_from); + } + + /* now, decrease the size of the read */ + if(data->state.infilesize>0) { + data->state.infilesize -= data->state.resume_from; + + if(data->state.infilesize <= 0) { + failf(data, "File already completely uploaded"); + return CURLE_PARTIAL_FILE; + } + } + /* we've passed, proceed as normal */ + } + } + if(data->state.use_range) { + /* + * A range is selected. We use different headers whether we're downloading + * or uploading and we always let customized headers override our internal + * ones if any such are specified. + */ + if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) && + !Curl_checkheaders(conn, "Range")) { + /* if a line like this was already allocated, free the previous one */ + free(conn->allocptr.rangeline); + conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", + data->state.range); + } + else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) && + !Curl_checkheaders(conn, "Content-Range")) { + + /* if a line like this was already allocated, free the previous one */ + free(conn->allocptr.rangeline); + + if(data->set.set_resume_from < 0) { + /* Upload resume was asked for, but we don't know the size of the + remote part so we tell the server (and act accordingly) that we + upload the whole file (again) */ + conn->allocptr.rangeline = + aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T + "/%" CURL_FORMAT_CURL_OFF_T "\r\n", + data->state.infilesize - 1, data->state.infilesize); + + } + else if(data->state.resume_from) { + /* This is because "resume" was selected */ + curl_off_t total_expected_size = + data->state.resume_from + data->state.infilesize; + conn->allocptr.rangeline = + aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T + "/%" CURL_FORMAT_CURL_OFF_T "\r\n", + data->state.range, total_expected_size-1, + total_expected_size); + } + else { + /* Range was selected and then we just pass the incoming range and + append total size */ + conn->allocptr.rangeline = + aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n", + data->state.range, data->state.infilesize); + } + if(!conn->allocptr.rangeline) + return CURLE_OUT_OF_MEMORY; + } + } + + httpstring = get_http_string(data, conn); + + /* initialize a dynamic send-buffer */ + req_buffer = Curl_add_buffer_init(); + + if(!req_buffer) + return CURLE_OUT_OF_MEMORY; + + /* add the main request stuff */ + /* GET/HEAD/POST/PUT */ + result = Curl_add_bufferf(&req_buffer, "%s ", request); + if(result) + return result; + + if(data->set.str[STRING_TARGET]) { + path = data->set.str[STRING_TARGET]; + query = NULL; + } + + /* url */ + if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { + char *url = data->change.url; + result = Curl_add_buffer(&req_buffer, url, strlen(url)); + } + else if(paste_ftp_userpwd) + result = Curl_add_bufferf(&req_buffer, "ftp://%s:%s@%s", + conn->user, conn->passwd, + path + sizeof("ftp://") - 1); + else { + result = Curl_add_buffer(&req_buffer, path, strlen(path)); + if(result) + return result; + if(query) + result = Curl_add_bufferf(&req_buffer, "?%s", query); + } + if(result) + return result; + + result = + Curl_add_bufferf(&req_buffer, + "%s" /* ftp typecode (;type=x) */ + " HTTP/%s\r\n" /* HTTP version */ + "%s" /* host */ + "%s" /* proxyuserpwd */ + "%s" /* userpwd */ + "%s" /* range */ + "%s" /* user agent */ + "%s" /* accept */ + "%s" /* TE: */ + "%s" /* accept-encoding */ + "%s" /* referer */ + "%s" /* Proxy-Connection */ + "%s",/* transfer-encoding */ + + ftp_typecode, + httpstring, + (conn->allocptr.host?conn->allocptr.host:""), + conn->allocptr.proxyuserpwd? + conn->allocptr.proxyuserpwd:"", + conn->allocptr.userpwd?conn->allocptr.userpwd:"", + (data->state.use_range && conn->allocptr.rangeline)? + conn->allocptr.rangeline:"", + (data->set.str[STRING_USERAGENT] && + *data->set.str[STRING_USERAGENT] && + conn->allocptr.uagent)? + conn->allocptr.uagent:"", + http->p_accept?http->p_accept:"", + conn->allocptr.te?conn->allocptr.te:"", + (data->set.str[STRING_ENCODING] && + *data->set.str[STRING_ENCODING] && + conn->allocptr.accept_encoding)? + conn->allocptr.accept_encoding:"", + (data->change.referer && conn->allocptr.ref)? + conn->allocptr.ref:"" /* Referer: */, + (conn->bits.httpproxy && + !conn->bits.tunnel_proxy && + !Curl_checkProxyheaders(conn, "Proxy-Connection"))? + "Proxy-Connection: Keep-Alive\r\n":"", + te + ); + + /* clear userpwd and proxyuserpwd to avoid re-using old credentials + * from re-used connections */ + Curl_safefree(conn->allocptr.userpwd); + Curl_safefree(conn->allocptr.proxyuserpwd); + + if(result) + return result; + + if(!(conn->handler->flags&PROTOPT_SSL) && + conn->httpversion != 20 && + (data->set.httpversion == CURL_HTTP_VERSION_2)) { + /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done + over SSL */ + result = Curl_http2_request_upgrade(req_buffer, conn); + if(result) + return result; + } + +#if !defined(CURL_DISABLE_COOKIES) + if(data->cookies || addcookies) { + struct Cookie *co = NULL; /* no cookies from start */ + int count = 0; + + if(data->cookies) { + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + co = Curl_cookie_getlist(data->cookies, + conn->allocptr.cookiehost? + conn->allocptr.cookiehost:host, + data->state.up.path, + (conn->handler->protocol&CURLPROTO_HTTPS)? + TRUE:FALSE); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + } + if(co) { + struct Cookie *store = co; + /* now loop through all cookies that matched */ + while(co) { + if(co->value) { + if(0 == count) { + result = Curl_add_bufferf(&req_buffer, "Cookie: "); + if(result) + break; + } + result = Curl_add_bufferf(&req_buffer, + "%s%s=%s", count?"; ":"", + co->name, co->value); + if(result) + break; + count++; + } + co = co->next; /* next cookie please */ + } + Curl_cookie_freelist(store); + } + if(addcookies && !result) { + if(!count) + result = Curl_add_bufferf(&req_buffer, "Cookie: "); + if(!result) { + result = Curl_add_bufferf(&req_buffer, "%s%s", count?"; ":"", + addcookies); + count++; + } + } + if(count && !result) + result = Curl_add_buffer(&req_buffer, "\r\n", 2); + + if(result) + return result; + } +#endif + + result = Curl_add_timecondition(conn, req_buffer); + if(result) + return result; + + result = Curl_add_custom_headers(conn, FALSE, req_buffer); + if(result) + return result; + + http->postdata = NULL; /* nothing to post at this point */ + Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */ + + /* If 'authdone' is FALSE, we must not set the write socket index to the + Curl_transfer() call below, as we're not ready to actually upload any + data yet. */ + + switch(httpreq) { + + case HTTPREQ_PUT: /* Let's PUT the data to the server! */ + + if(conn->bits.authneg) + postsize = 0; + else + postsize = data->state.infilesize; + + if((postsize != -1) && !data->req.upload_chunky && + (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) { + /* only add Content-Length if not uploading chunked */ + result = Curl_add_bufferf(&req_buffer, + "Content-Length: %" CURL_FORMAT_CURL_OFF_T + "\r\n", postsize); + if(result) + return result; + } + + if(postsize != 0) { + result = expect100(data, conn, req_buffer); + if(result) + return result; + } + + result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers */ + if(result) + return result; + + /* set the upload size to the progress meter */ + Curl_pgrsSetUploadSize(data, postsize); + + /* this sends the buffer and frees all the buffer resources */ + result = Curl_add_buffer_send(&req_buffer, conn, + &data->info.request_size, 0, FIRSTSOCKET); + if(result) + failf(data, "Failed sending PUT request"); + else + /* prepare for transfer */ + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, + postsize?FIRSTSOCKET:-1); + if(result) + return result; + break; + + case HTTPREQ_POST_FORM: + case HTTPREQ_POST_MIME: + /* This is form posting using mime data. */ + if(conn->bits.authneg) { + /* nothing to post! */ + result = Curl_add_bufferf(&req_buffer, "Content-Length: 0\r\n\r\n"); + if(result) + return result; + + result = Curl_add_buffer_send(&req_buffer, conn, + &data->info.request_size, 0, FIRSTSOCKET); + if(result) + failf(data, "Failed sending POST request"); + else + /* setup variables for the upcoming transfer */ + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1); + break; + } + + data->state.infilesize = postsize = http->postsize; + + /* We only set Content-Length and allow a custom Content-Length if + we don't upload data chunked, as RFC2616 forbids us to set both + kinds of headers (Transfer-Encoding: chunked and Content-Length) */ + if(postsize != -1 && !data->req.upload_chunky && + (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) { + /* we allow replacing this header if not during auth negotiation, + although it isn't very wise to actually set your own */ + result = Curl_add_bufferf(&req_buffer, + "Content-Length: %" CURL_FORMAT_CURL_OFF_T + "\r\n", postsize); + if(result) + return result; + } + +#ifndef CURL_DISABLE_MIME + /* Output mime-generated headers. */ + { + struct curl_slist *hdr; + + for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) { + result = Curl_add_bufferf(&req_buffer, "%s\r\n", hdr->data); + if(result) + return result; + } + } +#endif + + /* For really small posts we don't use Expect: headers at all, and for + the somewhat bigger ones we allow the app to disable it. Just make + sure that the expect100header is always set to the preferred value + here. */ + ptr = Curl_checkheaders(conn, "Expect"); + if(ptr) { + data->state.expect100header = + Curl_compareheader(ptr, "Expect:", "100-continue"); + } + else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) { + result = expect100(data, conn, req_buffer); + if(result) + return result; + } + else + data->state.expect100header = FALSE; + + /* make the request end in a true CRLF */ + result = Curl_add_buffer(&req_buffer, "\r\n", 2); + if(result) + return result; + + /* set the upload size to the progress meter */ + Curl_pgrsSetUploadSize(data, postsize); + + /* Read from mime structure. */ + data->state.fread_func = (curl_read_callback) Curl_mime_read; + data->state.in = (void *) http->sendit; + http->sending = HTTPSEND_BODY; + + /* this sends the buffer and frees all the buffer resources */ + result = Curl_add_buffer_send(&req_buffer, conn, + &data->info.request_size, 0, FIRSTSOCKET); + if(result) + failf(data, "Failed sending POST request"); + else + /* prepare for transfer */ + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, + postsize?FIRSTSOCKET:-1); + if(result) + return result; + + break; + + case HTTPREQ_POST: + /* this is the simple POST, using x-www-form-urlencoded style */ + + if(conn->bits.authneg) + postsize = 0; + else + /* the size of the post body */ + postsize = data->state.infilesize; + + /* We only set Content-Length and allow a custom Content-Length if + we don't upload data chunked, as RFC2616 forbids us to set both + kinds of headers (Transfer-Encoding: chunked and Content-Length) */ + if((postsize != -1) && !data->req.upload_chunky && + (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) { + /* we allow replacing this header if not during auth negotiation, + although it isn't very wise to actually set your own */ + result = Curl_add_bufferf(&req_buffer, + "Content-Length: %" CURL_FORMAT_CURL_OFF_T + "\r\n", postsize); + if(result) + return result; + } + + if(!Curl_checkheaders(conn, "Content-Type")) { + result = Curl_add_bufferf(&req_buffer, + "Content-Type: application/" + "x-www-form-urlencoded\r\n"); + if(result) + return result; + } + + /* For really small posts we don't use Expect: headers at all, and for + the somewhat bigger ones we allow the app to disable it. Just make + sure that the expect100header is always set to the preferred value + here. */ + ptr = Curl_checkheaders(conn, "Expect"); + if(ptr) { + data->state.expect100header = + Curl_compareheader(ptr, "Expect:", "100-continue"); + } + else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) { + result = expect100(data, conn, req_buffer); + if(result) + return result; + } + else + data->state.expect100header = FALSE; + + if(data->set.postfields) { + + /* In HTTP2, we send request body in DATA frame regardless of + its size. */ + if(conn->httpversion != 20 && + !data->state.expect100header && + (postsize < MAX_INITIAL_POST_SIZE)) { + /* if we don't use expect: 100 AND + postsize is less than MAX_INITIAL_POST_SIZE + + then append the post data to the HTTP request header. This limit + is no magic limit but only set to prevent really huge POSTs to + get the data duplicated with malloc() and family. */ + + result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */ + if(result) + return result; + + if(!data->req.upload_chunky) { + /* We're not sending it 'chunked', append it to the request + already now to reduce the number if send() calls */ + result = Curl_add_buffer(&req_buffer, data->set.postfields, + (size_t)postsize); + included_body = postsize; + } + else { + if(postsize) { + /* Append the POST data chunky-style */ + result = Curl_add_bufferf(&req_buffer, "%x\r\n", (int)postsize); + if(!result) { + result = Curl_add_buffer(&req_buffer, data->set.postfields, + (size_t)postsize); + if(!result) + result = Curl_add_buffer(&req_buffer, "\r\n", 2); + included_body = postsize + 2; + } + } + if(!result) + result = Curl_add_buffer(&req_buffer, "\x30\x0d\x0a\x0d\x0a", 5); + /* 0 CR LF CR LF */ + included_body += 5; + } + if(result) + return result; + /* Make sure the progress information is accurate */ + Curl_pgrsSetUploadSize(data, postsize); + } + else { + /* A huge POST coming up, do data separate from the request */ + http->postsize = postsize; + http->postdata = data->set.postfields; + + http->sending = HTTPSEND_BODY; + + data->state.fread_func = (curl_read_callback)readmoredata; + data->state.in = (void *)conn; + + /* set the upload size to the progress meter */ + Curl_pgrsSetUploadSize(data, http->postsize); + + result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */ + if(result) + return result; + } + } + else { + result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */ + if(result) + return result; + + if(data->req.upload_chunky && conn->bits.authneg) { + /* Chunky upload is selected and we're negotiating auth still, send + end-of-data only */ + result = Curl_add_buffer(&req_buffer, + "\x30\x0d\x0a\x0d\x0a", 5); + /* 0 CR LF CR LF */ + if(result) + return result; + } + + else if(data->state.infilesize) { + /* set the upload size to the progress meter */ + Curl_pgrsSetUploadSize(data, postsize?postsize:-1); + + /* set the pointer to mark that we will send the post body using the + read callback, but only if we're not in authenticate + negotiation */ + if(!conn->bits.authneg) { + http->postdata = (char *)&http->postdata; + http->postsize = postsize; + } + } + } + /* issue the request */ + result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size, + (size_t)included_body, FIRSTSOCKET); + + if(result) + failf(data, "Failed sending HTTP POST request"); + else + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, + http->postdata?FIRSTSOCKET:-1); + break; + + default: + result = Curl_add_buffer(&req_buffer, "\r\n", 2); + if(result) + return result; + + /* issue the request */ + result = Curl_add_buffer_send(&req_buffer, conn, + &data->info.request_size, 0, FIRSTSOCKET); + + if(result) + failf(data, "Failed sending HTTP request"); + else + /* HTTP GET/HEAD download: */ + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, + http->postdata?FIRSTSOCKET:-1); + } + if(result) + return result; + + if(data->req.writebytecount) { + /* if a request-body has been sent off, we make sure this progress is noted + properly */ + Curl_pgrsSetUploadCounter(data, data->req.writebytecount); + if(Curl_pgrsUpdate(conn)) + result = CURLE_ABORTED_BY_CALLBACK; + + if(data->req.writebytecount >= postsize) { + /* already sent the entire request body, mark the "upload" as + complete */ + infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T + " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n", + data->req.writebytecount, postsize); + data->req.upload_done = TRUE; + data->req.keepon &= ~KEEP_SEND; /* we're done writing */ + data->req.exp100 = EXP100_SEND_DATA; /* already sent */ + Curl_expire_done(data, EXPIRE_100_TIMEOUT); + } + } + + if((conn->httpversion == 20) && data->req.upload_chunky) + /* upload_chunky was set above to set up the request in a chunky fashion, + but is disabled here again to avoid that the chunked encoded version is + actually used when sending the request body over h2 */ + data->req.upload_chunky = FALSE; + return result; +} + +typedef enum { + STATUS_UNKNOWN, /* not enough data to tell yet */ + STATUS_DONE, /* a status line was read */ + STATUS_BAD /* not a status line */ +} statusline; + + +/* Check a string for a prefix. Check no more than 'len' bytes */ +static bool checkprefixmax(const char *prefix, const char *buffer, size_t len) +{ + size_t ch = CURLMIN(strlen(prefix), len); + return curl_strnequal(prefix, buffer, ch); +} + +/* + * checkhttpprefix() + * + * Returns TRUE if member of the list matches prefix of string + */ +static statusline +checkhttpprefix(struct Curl_easy *data, + const char *s, size_t len) +{ + struct curl_slist *head = data->set.http200aliases; + statusline rc = STATUS_BAD; + statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN; +#ifdef CURL_DOES_CONVERSIONS + /* convert from the network encoding using a scratch area */ + char *scratch = strdup(s); + if(NULL == scratch) { + failf(data, "Failed to allocate memory for conversion!"); + return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */ + } + if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) { + /* Curl_convert_from_network calls failf if unsuccessful */ + free(scratch); + return FALSE; /* can't return CURLE_foobar so return FALSE */ + } + s = scratch; +#endif /* CURL_DOES_CONVERSIONS */ + + while(head) { + if(checkprefixmax(head->data, s, len)) { + rc = onmatch; + break; + } + head = head->next; + } + + if((rc != STATUS_DONE) && (checkprefixmax("HTTP/", s, len))) + rc = onmatch; + +#ifdef CURL_DOES_CONVERSIONS + free(scratch); +#endif /* CURL_DOES_CONVERSIONS */ + return rc; +} + +#ifndef CURL_DISABLE_RTSP +static statusline +checkrtspprefix(struct Curl_easy *data, + const char *s, size_t len) +{ + statusline result = STATUS_BAD; + statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN; + +#ifdef CURL_DOES_CONVERSIONS + /* convert from the network encoding using a scratch area */ + char *scratch = strdup(s); + if(NULL == scratch) { + failf(data, "Failed to allocate memory for conversion!"); + return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */ + } + if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) { + /* Curl_convert_from_network calls failf if unsuccessful */ + result = FALSE; /* can't return CURLE_foobar so return FALSE */ + } + else if(checkprefixmax("RTSP/", scratch, len)) + result = onmatch; + free(scratch); +#else + (void)data; /* unused */ + if(checkprefixmax("RTSP/", s, len)) + result = onmatch; +#endif /* CURL_DOES_CONVERSIONS */ + + return result; +} +#endif /* CURL_DISABLE_RTSP */ + +static statusline +checkprotoprefix(struct Curl_easy *data, struct connectdata *conn, + const char *s, size_t len) +{ +#ifndef CURL_DISABLE_RTSP + if(conn->handler->protocol & CURLPROTO_RTSP) + return checkrtspprefix(data, s, len); +#else + (void)conn; +#endif /* CURL_DISABLE_RTSP */ + + return checkhttpprefix(data, s, len); +} + +/* + * header_append() copies a chunk of data to the end of the already received + * header. We make sure that the full string fit in the allocated header + * buffer, or else we enlarge it. + */ +static CURLcode header_append(struct Curl_easy *data, + struct SingleRequest *k, + size_t length) +{ + /* length is at most the size of a full read buffer, for which the upper + bound is CURL_MAX_READ_SIZE. There is thus no chance of overflow in this + calculation. */ + size_t newsize = k->hbuflen + length; + if(newsize > CURL_MAX_HTTP_HEADER) { + /* The reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a never-ending header that will cause + reallocs infinitely */ + failf(data, "Rejected %zu bytes header (max is %d)!", newsize, + CURL_MAX_HTTP_HEADER); + return CURLE_OUT_OF_MEMORY; + } + if(newsize >= data->state.headersize) { + /* We enlarge the header buffer as it is too small */ + char *newbuff; + size_t hbufp_index; + + newsize = CURLMAX((k->hbuflen + length) * 3 / 2, data->state.headersize*2); + hbufp_index = k->hbufp - data->state.headerbuff; + newbuff = realloc(data->state.headerbuff, newsize); + if(!newbuff) { + failf(data, "Failed to alloc memory for big header!"); + return CURLE_OUT_OF_MEMORY; + } + data->state.headersize = newsize; + data->state.headerbuff = newbuff; + k->hbufp = data->state.headerbuff + hbufp_index; + } + memcpy(k->hbufp, k->str_start, length); + k->hbufp += length; + k->hbuflen += length; + *k->hbufp = 0; + + return CURLE_OK; +} + +static void print_http_error(struct Curl_easy *data) +{ + struct SingleRequest *k = &data->req; + char *beg = k->p; + + /* make sure that data->req.p points to the HTTP status line */ + if(!strncmp(beg, "HTTP", 4)) { + + /* skip to HTTP status code */ + beg = strchr(beg, ' '); + if(beg && *++beg) { + + /* find trailing CR */ + char end_char = '\r'; + char *end = strchr(beg, end_char); + if(!end) { + /* try to find LF (workaround for non-compliant HTTP servers) */ + end_char = '\n'; + end = strchr(beg, end_char); + } + + if(end) { + /* temporarily replace CR or LF by NUL and print the error message */ + *end = '\0'; + failf(data, "The requested URL returned error: %s", beg); + + /* restore the previously replaced CR or LF */ + *end = end_char; + return; + } + } + } + + /* fall-back to printing the HTTP status code only */ + failf(data, "The requested URL returned error: %d", k->httpcode); +} + +/* + * Read any HTTP header lines from the server and pass them to the client app. + */ +CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, + struct connectdata *conn, + ssize_t *nread, + bool *stop_reading) +{ + CURLcode result; + struct SingleRequest *k = &data->req; + ssize_t onread = *nread; + char *ostr = k->str; + + /* header line within buffer loop */ + do { + size_t rest_length; + size_t full_length; + int writetype; + + /* str_start is start of line within buf */ + k->str_start = k->str; + + /* data is in network encoding so use 0x0a instead of '\n' */ + k->end_ptr = memchr(k->str_start, 0x0a, *nread); + + if(!k->end_ptr) { + /* Not a complete header line within buffer, append the data to + the end of the headerbuff. */ + result = header_append(data, k, *nread); + if(result) + return result; + + if(!k->headerline) { + /* check if this looks like a protocol header */ + statusline st = checkprotoprefix(data, conn, data->state.headerbuff, + k->hbuflen); + if(st == STATUS_BAD) { + /* this is not the beginning of a protocol first header line */ + k->header = FALSE; + k->badheader = HEADER_ALLBAD; + streamclose(conn, "bad HTTP: No end-of-message indicator"); + if(!data->set.http09_allowed) { + failf(data, "Received HTTP/0.9 when not allowed\n"); + return CURLE_UNSUPPORTED_PROTOCOL; + } + break; + } + } + + break; /* read more and try again */ + } + + /* decrease the size of the remaining (supposed) header line */ + rest_length = (k->end_ptr - k->str) + 1; + *nread -= (ssize_t)rest_length; + + k->str = k->end_ptr + 1; /* move past new line */ + + full_length = k->str - k->str_start; + + result = header_append(data, k, full_length); + if(result) + return result; + + k->end_ptr = k->hbufp; + k->p = data->state.headerbuff; + + /**** + * We now have a FULL header line that p points to + *****/ + + if(!k->headerline) { + /* the first read header */ + statusline st = checkprotoprefix(data, conn, data->state.headerbuff, + k->hbuflen); + if(st == STATUS_BAD) { + streamclose(conn, "bad HTTP: No end-of-message indicator"); + /* this is not the beginning of a protocol first header line */ + if(!data->set.http09_allowed) { + failf(data, "Received HTTP/0.9 when not allowed\n"); + return CURLE_UNSUPPORTED_PROTOCOL; + } + k->header = FALSE; + if(*nread) + /* since there's more, this is a partial bad header */ + k->badheader = HEADER_PARTHEADER; + else { + /* this was all we read so it's all a bad header */ + k->badheader = HEADER_ALLBAD; + *nread = onread; + k->str = ostr; + return CURLE_OK; + } + break; + } + } + + /* headers are in network encoding so + use 0x0a and 0x0d instead of '\n' and '\r' */ + if((0x0a == *k->p) || (0x0d == *k->p)) { + size_t headerlen; + /* Zero-length header line means end of headers! */ + +#ifdef CURL_DOES_CONVERSIONS + if(0x0d == *k->p) { + *k->p = '\r'; /* replace with CR in host encoding */ + k->p++; /* pass the CR byte */ + } + if(0x0a == *k->p) { + *k->p = '\n'; /* replace with LF in host encoding */ + k->p++; /* pass the LF byte */ + } +#else + if('\r' == *k->p) + k->p++; /* pass the \r byte */ + if('\n' == *k->p) + k->p++; /* pass the \n byte */ +#endif /* CURL_DOES_CONVERSIONS */ + + if(100 <= k->httpcode && 199 >= k->httpcode) { + /* "A user agent MAY ignore unexpected 1xx status responses." */ + switch(k->httpcode) { + case 100: + /* + * We have made a HTTP PUT or POST and this is 1.1-lingo + * that tells us that the server is OK with this and ready + * to receive the data. + * However, we'll get more headers now so we must get + * back into the header-parsing state! + */ + k->header = TRUE; + k->headerline = 0; /* restart the header line counter */ + + /* if we did wait for this do enable write now! */ + if(k->exp100 > EXP100_SEND_DATA) { + k->exp100 = EXP100_SEND_DATA; + k->keepon |= KEEP_SEND; + Curl_expire_done(data, EXPIRE_100_TIMEOUT); + } + break; + case 101: + /* Switching Protocols */ + if(k->upgr101 == UPGR101_REQUESTED) { + /* Switching to HTTP/2 */ + infof(data, "Received 101\n"); + k->upgr101 = UPGR101_RECEIVED; + + /* we'll get more headers (HTTP/2 response) */ + k->header = TRUE; + k->headerline = 0; /* restart the header line counter */ + + /* switch to http2 now. The bytes after response headers + are also processed here, otherwise they are lost. */ + result = Curl_http2_switched(conn, k->str, *nread); + if(result) + return result; + *nread = 0; + } + else { + /* Switching to another protocol (e.g. WebSocket) */ + k->header = FALSE; /* no more header to parse! */ + } + break; + default: + /* the status code 1xx indicates a provisional response, so + we'll get another set of headers */ + k->header = TRUE; + k->headerline = 0; /* restart the header line counter */ + break; + } + } + else { + k->header = FALSE; /* no more header to parse! */ + + if((k->size == -1) && !k->chunk && !conn->bits.close && + (conn->httpversion == 11) && + !(conn->handler->protocol & CURLPROTO_RTSP) && + data->set.httpreq != HTTPREQ_HEAD) { + /* On HTTP 1.1, when connection is not to get closed, but no + Content-Length nor Transfer-Encoding chunked have been + received, according to RFC2616 section 4.4 point 5, we + assume that the server will close the connection to + signal the end of the document. */ + infof(data, "no chunk, no close, no size. Assume close to " + "signal end\n"); + streamclose(conn, "HTTP: No end-of-message indicator"); + } + } + + /* At this point we have some idea about the fate of the connection. + If we are closing the connection it may result auth failure. */ +#if defined(USE_NTLM) + if(conn->bits.close && + (((data->req.httpcode == 401) && + (conn->http_ntlm_state == NTLMSTATE_TYPE2)) || + ((data->req.httpcode == 407) && + (conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) { + infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n"); + data->state.authproblem = TRUE; + } +#endif +#if defined(USE_SPNEGO) + if(conn->bits.close && + (((data->req.httpcode == 401) && + (conn->http_negotiate_state == GSS_AUTHRECV)) || + ((data->req.httpcode == 407) && + (conn->proxy_negotiate_state == GSS_AUTHRECV)))) { + infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n"); + data->state.authproblem = TRUE; + } + if((conn->http_negotiate_state == GSS_AUTHDONE) && + (data->req.httpcode != 401)) { + conn->http_negotiate_state = GSS_AUTHSUCC; + } + if((conn->proxy_negotiate_state == GSS_AUTHDONE) && + (data->req.httpcode != 407)) { + conn->proxy_negotiate_state = GSS_AUTHSUCC; + } +#endif + /* + * When all the headers have been parsed, see if we should give + * up and return an error. + */ + if(http_should_fail(conn)) { + failf(data, "The requested URL returned error: %d", + k->httpcode); + return CURLE_HTTP_RETURNED_ERROR; + } + + /* now, only output this if the header AND body are requested: + */ + writetype = CLIENTWRITE_HEADER; + if(data->set.include_header) + writetype |= CLIENTWRITE_BODY; + + headerlen = k->p - data->state.headerbuff; + + result = Curl_client_write(conn, writetype, + data->state.headerbuff, + headerlen); + if(result) + return result; + + data->info.header_size += (long)headerlen; + data->req.headerbytecount += (long)headerlen; + + data->req.deductheadercount = + (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0; + + /* Curl_http_auth_act() checks what authentication methods + * that are available and decides which one (if any) to + * use. It will set 'newurl' if an auth method was picked. */ + result = Curl_http_auth_act(conn); + + if(result) + return result; + + if(k->httpcode >= 300) { + if((!conn->bits.authneg) && !conn->bits.close && + !conn->bits.rewindaftersend) { + /* + * General treatment of errors when about to send data. Including : + * "417 Expectation Failed", while waiting for 100-continue. + * + * The check for close above is done simply because of something + * else has already deemed the connection to get closed then + * something else should've considered the big picture and we + * avoid this check. + * + * rewindaftersend indicates that something has told libcurl to + * continue sending even if it gets discarded + */ + + switch(data->set.httpreq) { + case HTTPREQ_PUT: + case HTTPREQ_POST: + case HTTPREQ_POST_FORM: + case HTTPREQ_POST_MIME: + /* We got an error response. If this happened before the whole + * request body has been sent we stop sending and mark the + * connection for closure after we've read the entire response. + */ + Curl_expire_done(data, EXPIRE_100_TIMEOUT); + if(!k->upload_done) { + if(data->set.http_keep_sending_on_error) { + infof(data, "HTTP error before end of send, keep sending\n"); + if(k->exp100 > EXP100_SEND_DATA) { + k->exp100 = EXP100_SEND_DATA; + k->keepon |= KEEP_SEND; + } + } + else { + infof(data, "HTTP error before end of send, stop sending\n"); + streamclose(conn, "Stop sending data before everything sent"); + result = Curl_done_sending(conn, k); + if(result) + return result; + k->upload_done = TRUE; + if(data->state.expect100header) + k->exp100 = EXP100_FAILED; + } + } + break; + + default: /* default label present to avoid compiler warnings */ + break; + } + } + + if(conn->bits.rewindaftersend) { + /* We rewind after a complete send, so thus we continue + sending now */ + infof(data, "Keep sending data to get tossed away!\n"); + k->keepon |= KEEP_SEND; + } + } + + if(!k->header) { + /* + * really end-of-headers. + * + * If we requested a "no body", this is a good time to get + * out and return home. + */ + if(data->set.opt_no_body) + *stop_reading = TRUE; +#ifndef CURL_DISABLE_RTSP + else if((conn->handler->protocol & CURLPROTO_RTSP) && + (data->set.rtspreq == RTSPREQ_DESCRIBE) && + (k->size <= -1)) + /* Respect section 4.4 of rfc2326: If the Content-Length header is + absent, a length 0 must be assumed. It will prevent libcurl from + hanging on DESCRIBE request that got refused for whatever + reason */ + *stop_reading = TRUE; +#endif + else { + /* If we know the expected size of this document, we set the + maximum download size to the size of the expected + document or else, we won't know when to stop reading! + + Note that we set the download maximum even if we read a + "Connection: close" header, to make sure that + "Content-Length: 0" still prevents us from attempting to + read the (missing) response-body. + */ + /* According to RFC2616 section 4.4, we MUST ignore + Content-Length: headers if we are now receiving data + using chunked Transfer-Encoding. + */ + if(k->chunk) + k->maxdownload = k->size = -1; + } + if(-1 != k->size) { + /* We do this operation even if no_body is true, since this + data might be retrieved later with curl_easy_getinfo() + and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */ + + Curl_pgrsSetDownloadSize(data, k->size); + k->maxdownload = k->size; + } + + /* If max download size is *zero* (nothing) we already have + nothing and can safely return ok now! But for HTTP/2, we'd + like to call http2_handle_stream_close to properly close a + stream. In order to do this, we keep reading until we + close the stream. */ + if(0 == k->maxdownload +#if defined(USE_NGHTTP2) + && !((conn->handler->protocol & PROTO_FAMILY_HTTP) && + conn->httpversion == 20) +#endif + ) + *stop_reading = TRUE; + + if(*stop_reading) { + /* we make sure that this socket isn't read more now */ + k->keepon &= ~KEEP_RECV; + } + + if(data->set.verbose) + Curl_debug(data, CURLINFO_HEADER_IN, + k->str_start, headerlen); + break; /* exit header line loop */ + } + + /* We continue reading headers, so reset the line-based + header parsing variables hbufp && hbuflen */ + k->hbufp = data->state.headerbuff; + k->hbuflen = 0; + continue; + } + + /* + * Checks for special headers coming up. + */ + + if(!k->headerline++) { + /* This is the first header, it MUST be the error code line + or else we consider this to be the body right away! */ + int httpversion_major; + int rtspversion_major; + int nc = 0; +#ifdef CURL_DOES_CONVERSIONS +#define HEADER1 scratch +#define SCRATCHSIZE 21 + CURLcode res; + char scratch[SCRATCHSIZE + 1]; /* "HTTP/major.minor 123" */ + /* We can't really convert this yet because we + don't know if it's the 1st header line or the body. + So we do a partial conversion into a scratch area, + leaving the data at k->p as-is. + */ + strncpy(&scratch[0], k->p, SCRATCHSIZE); + scratch[SCRATCHSIZE] = 0; /* null terminate */ + res = Curl_convert_from_network(data, + &scratch[0], + SCRATCHSIZE); + if(res) + /* Curl_convert_from_network calls failf if unsuccessful */ + return res; +#else +#define HEADER1 k->p /* no conversion needed, just use k->p */ +#endif /* CURL_DOES_CONVERSIONS */ + + if(conn->handler->protocol & PROTO_FAMILY_HTTP) { + /* + * https://tools.ietf.org/html/rfc7230#section-3.1.2 + * + * The response code is always a three-digit number in HTTP as the spec + * says. We try to allow any number here, but we cannot make + * guarantees on future behaviors since it isn't within the protocol. + */ + char separator; + nc = sscanf(HEADER1, + " HTTP/%1d.%1d%c%3d", + &httpversion_major, + &conn->httpversion, + &separator, + &k->httpcode); + + if(nc == 1 && httpversion_major == 2 && + 1 == sscanf(HEADER1, " HTTP/2 %d", &k->httpcode)) { + conn->httpversion = 0; + nc = 4; + separator = ' '; + } + + if((nc == 4) && (' ' == separator)) { + conn->httpversion += 10 * httpversion_major; + + if(k->upgr101 == UPGR101_RECEIVED) { + /* supposedly upgraded to http2 now */ + if(conn->httpversion != 20) + infof(data, "Lying server, not serving HTTP/2\n"); + } + if(conn->httpversion < 20) { + conn->bundle->multiuse = BUNDLE_NO_MULTIUSE; + infof(data, "Mark bundle as not supporting multiuse\n"); + } + } + else if(!nc) { + /* this is the real world, not a Nirvana + NCSA 1.5.x returns this crap when asked for HTTP/1.1 + */ + nc = sscanf(HEADER1, " HTTP %3d", &k->httpcode); + conn->httpversion = 10; + + /* If user has set option HTTP200ALIASES, + compare header line against list of aliases + */ + if(!nc) { + if(checkhttpprefix(data, k->p, k->hbuflen) == STATUS_DONE) { + nc = 1; + k->httpcode = 200; + conn->httpversion = 10; + } + } + } + else { + failf(data, "Unsupported HTTP version in response\n"); + return CURLE_UNSUPPORTED_PROTOCOL; + } + } + else if(conn->handler->protocol & CURLPROTO_RTSP) { + char separator; + nc = sscanf(HEADER1, + " RTSP/%1d.%1d%c%3d", + &rtspversion_major, + &conn->rtspversion, + &separator, + &k->httpcode); + if((nc == 4) && (' ' == separator)) { + conn->rtspversion += 10 * rtspversion_major; + conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */ + } + else { + nc = 0; + } + } + + if(nc) { + data->info.httpcode = k->httpcode; + + data->info.httpversion = conn->httpversion; + if(!data->state.httpversion || + data->state.httpversion > conn->httpversion) + /* store the lowest server version we encounter */ + data->state.httpversion = conn->httpversion; + + /* + * This code executes as part of processing the header. As a + * result, it's not totally clear how to interpret the + * response code yet as that depends on what other headers may + * be present. 401 and 407 may be errors, but may be OK + * depending on how authentication is working. Other codes + * are definitely errors, so give up here. + */ + if(data->state.resume_from && data->set.httpreq == HTTPREQ_GET && + k->httpcode == 416) { + /* "Requested Range Not Satisfiable", just proceed and + pretend this is no error */ + k->ignorebody = TRUE; /* Avoid appending error msg to good data. */ + } + else if(data->set.http_fail_on_error && (k->httpcode >= 400) && + ((k->httpcode != 401) || !conn->bits.user_passwd) && + ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) { + /* serious error, go home! */ + print_http_error(data); + return CURLE_HTTP_RETURNED_ERROR; + } + + if(conn->httpversion == 10) { + /* Default action for HTTP/1.0 must be to close, unless + we get one of those fancy headers that tell us the + server keeps it open for us! */ + infof(data, "HTTP 1.0, assume close after body\n"); + connclose(conn, "HTTP/1.0 close after body"); + } + else if(conn->httpversion == 20 || + (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) { + DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n")); + + /* HTTP/2 cannot blacklist multiplexing since it is a core + functionality of the protocol */ + conn->bundle->multiuse = BUNDLE_MULTIPLEX; + } + else if(conn->httpversion >= 11 && + !conn->bits.close) { + /* If HTTP version is >= 1.1 and connection is persistent */ + DEBUGF(infof(data, + "HTTP 1.1 or later with persistent connection\n")); + } + + k->http_bodyless = k->httpcode >= 100 && k->httpcode < 200; + switch(k->httpcode) { + case 304: + /* (quote from RFC2616, section 10.3.5): The 304 response + * MUST NOT contain a message-body, and thus is always + * terminated by the first empty line after the header + * fields. */ + if(data->set.timecondition) + data->info.timecond = TRUE; + /* FALLTHROUGH */ + case 204: + /* (quote from RFC2616, section 10.2.5): The server has + * fulfilled the request but does not need to return an + * entity-body ... The 204 response MUST NOT include a + * message-body, and thus is always terminated by the first + * empty line after the header fields. */ + k->size = 0; + k->maxdownload = 0; + k->http_bodyless = TRUE; + break; + default: + break; + } + } + else { + k->header = FALSE; /* this is not a header line */ + break; + } + } + + result = Curl_convert_from_network(data, k->p, strlen(k->p)); + /* Curl_convert_from_network calls failf if unsuccessful */ + if(result) + return result; + + /* Check for Content-Length: header lines to get size */ + if(!k->http_bodyless && + !data->set.ignorecl && checkprefix("Content-Length:", k->p)) { + curl_off_t contentlength; + CURLofft offt = curlx_strtoofft(k->p + 15, NULL, 10, &contentlength); + + if(offt == CURL_OFFT_OK) { + if(data->set.max_filesize && + contentlength > data->set.max_filesize) { + failf(data, "Maximum file size exceeded"); + return CURLE_FILESIZE_EXCEEDED; + } + k->size = contentlength; + k->maxdownload = k->size; + /* we set the progress download size already at this point + just to make it easier for apps/callbacks to extract this + info as soon as possible */ + Curl_pgrsSetDownloadSize(data, k->size); + } + else if(offt == CURL_OFFT_FLOW) { + /* out of range */ + if(data->set.max_filesize) { + failf(data, "Maximum file size exceeded"); + return CURLE_FILESIZE_EXCEEDED; + } + streamclose(conn, "overflow content-length"); + infof(data, "Overflow Content-Length: value!\n"); + } + else { + /* negative or just rubbish - bad HTTP */ + failf(data, "Invalid Content-Length: value"); + return CURLE_WEIRD_SERVER_REPLY; + } + } + /* check for Content-Type: header lines to get the MIME-type */ + else if(checkprefix("Content-Type:", k->p)) { + char *contenttype = Curl_copy_header_value(k->p); + if(!contenttype) + return CURLE_OUT_OF_MEMORY; + if(!*contenttype) + /* ignore empty data */ + free(contenttype); + else { + Curl_safefree(data->info.contenttype); + data->info.contenttype = contenttype; + } + } + else if((conn->httpversion == 10) && + conn->bits.httpproxy && + Curl_compareheader(k->p, + "Proxy-Connection:", "keep-alive")) { + /* + * When a HTTP/1.0 reply comes when using a proxy, the + * 'Proxy-Connection: keep-alive' line tells us the + * connection will be kept alive for our pleasure. + * Default action for 1.0 is to close. + */ + connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */ + infof(data, "HTTP/1.0 proxy connection set to keep alive!\n"); + } + else if((conn->httpversion == 11) && + conn->bits.httpproxy && + Curl_compareheader(k->p, + "Proxy-Connection:", "close")) { + /* + * We get a HTTP/1.1 response from a proxy and it says it'll + * close down after this transfer. + */ + connclose(conn, "Proxy-Connection: asked to close after done"); + infof(data, "HTTP/1.1 proxy connection set close!\n"); + } + else if((conn->httpversion == 10) && + Curl_compareheader(k->p, "Connection:", "keep-alive")) { + /* + * A HTTP/1.0 reply with the 'Connection: keep-alive' line + * tells us the connection will be kept alive for our + * pleasure. Default action for 1.0 is to close. + * + * [RFC2068, section 19.7.1] */ + connkeep(conn, "Connection keep-alive"); + infof(data, "HTTP/1.0 connection set to keep alive!\n"); + } + else if(Curl_compareheader(k->p, "Connection:", "close")) { + /* + * [RFC 2616, section 8.1.2.1] + * "Connection: close" is HTTP/1.1 language and means that + * the connection will close when this request has been + * served. + */ + streamclose(conn, "Connection: close used"); + } + else if(!k->http_bodyless && checkprefix("Transfer-Encoding:", k->p)) { + /* One or more encodings. We check for chunked and/or a compression + algorithm. */ + /* + * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding + * means that the server will send a series of "chunks". Each + * chunk starts with line with info (including size of the + * coming block) (terminated with CRLF), then a block of data + * with the previously mentioned size. There can be any amount + * of chunks, and a chunk-data set to zero signals the + * end-of-chunks. */ + + result = Curl_build_unencoding_stack(conn, k->p + 18, TRUE); + if(result) + return result; + } + else if(!k->http_bodyless && checkprefix("Content-Encoding:", k->p) && + data->set.str[STRING_ENCODING]) { + /* + * Process Content-Encoding. Look for the values: identity, + * gzip, deflate, compress, x-gzip and x-compress. x-gzip and + * x-compress are the same as gzip and compress. (Sec 3.5 RFC + * 2616). zlib cannot handle compress. However, errors are + * handled further down when the response body is processed + */ + result = Curl_build_unencoding_stack(conn, k->p + 17, FALSE); + if(result) + return result; + } + else if(!k->http_bodyless && checkprefix("Content-Range:", k->p)) { + /* Content-Range: bytes [num]- + Content-Range: bytes: [num]- + Content-Range: [num]- + Content-Range: [asterisk]/[total] + + The second format was added since Sun's webserver + JavaWebServer/1.1.1 obviously sends the header this way! + The third added since some servers use that! + The forth means the requested range was unsatisfied. + */ + + char *ptr = k->p + 14; + + /* Move forward until first digit or asterisk */ + while(*ptr && !ISDIGIT(*ptr) && *ptr != '*') + ptr++; + + /* if it truly stopped on a digit */ + if(ISDIGIT(*ptr)) { + if(!curlx_strtoofft(ptr, NULL, 10, &k->offset)) { + if(data->state.resume_from == k->offset) + /* we asked for a resume and we got it */ + k->content_range = TRUE; + } + } + else + data->state.resume_from = 0; /* get everything */ + } +#if !defined(CURL_DISABLE_COOKIES) + else if(data->cookies && + checkprefix("Set-Cookie:", k->p)) { + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, + CURL_LOCK_ACCESS_SINGLE); + Curl_cookie_add(data, + data->cookies, TRUE, FALSE, k->p + 11, + /* If there is a custom-set Host: name, use it + here, or else use real peer host name. */ + conn->allocptr.cookiehost? + conn->allocptr.cookiehost:conn->host.name, + data->state.up.path, + (conn->handler->protocol&CURLPROTO_HTTPS)? + TRUE:FALSE); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + } +#endif + else if(!k->http_bodyless && checkprefix("Last-Modified:", k->p) && + (data->set.timecondition || data->set.get_filetime) ) { + time_t secs = time(NULL); + k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"), + &secs); + if(data->set.get_filetime) + data->info.filetime = k->timeofdoc; + } + else if((checkprefix("WWW-Authenticate:", k->p) && + (401 == k->httpcode)) || + (checkprefix("Proxy-authenticate:", k->p) && + (407 == k->httpcode))) { + + bool proxy = (k->httpcode == 407) ? TRUE : FALSE; + char *auth = Curl_copy_header_value(k->p); + if(!auth) + return CURLE_OUT_OF_MEMORY; + + result = Curl_http_input_auth(conn, proxy, auth); + + free(auth); + + if(result) + return result; + } + #ifdef USE_SPNEGO + else if(checkprefix("Persistent-Auth", k->p)) { + struct negotiatedata *negdata = &conn->negotiate; + struct auth *authp = &data->state.authhost; + if(authp->picked == CURLAUTH_NEGOTIATE) { + char *persistentauth = Curl_copy_header_value(k->p); + if(!persistentauth) + return CURLE_OUT_OF_MEMORY; + negdata->noauthpersist = checkprefix("false", persistentauth); + negdata->havenoauthpersist = TRUE; + infof(data, "Negotiate: noauthpersist -> %d, header part: %s", + negdata->noauthpersist, persistentauth); + free(persistentauth); + } + } + #endif + else if((k->httpcode >= 300 && k->httpcode < 400) && + checkprefix("Location:", k->p) && + !data->req.location) { + /* this is the URL that the server advises us to use instead */ + char *location = Curl_copy_header_value(k->p); + if(!location) + return CURLE_OUT_OF_MEMORY; + if(!*location) + /* ignore empty data */ + free(location); + else { + data->req.location = location; + + if(data->set.http_follow_location) { + DEBUGASSERT(!data->req.newurl); + data->req.newurl = strdup(data->req.location); /* clone */ + if(!data->req.newurl) + return CURLE_OUT_OF_MEMORY; + + /* some cases of POST and PUT etc needs to rewind the data + stream at this point */ + result = http_perhapsrewind(conn); + if(result) + return result; + } + } + } +#ifdef USE_ALTSVC + /* If enabled, the header is incoming and this is over HTTPS */ + else if(data->asi && checkprefix("Alt-Svc:", k->p) && + ((conn->handler->flags & PROTOPT_SSL) || +#ifdef CURLDEBUG + /* allow debug builds to circumvent the HTTPS restriction */ + getenv("CURL_ALTSVC_HTTP") +#else + 0 +#endif + )) { + /* the ALPN of the current request */ + enum alpnid id = (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1; + result = Curl_altsvc_parse(data, data->asi, + &k->p[ strlen("Alt-Svc:") ], + id, conn->host.name, + curlx_uitous(conn->remote_port)); + if(result) + return result; + } +#endif + else if(conn->handler->protocol & CURLPROTO_RTSP) { + result = Curl_rtsp_parseheader(conn, k->p); + if(result) + return result; + } + + /* + * End of header-checks. Write them to the client. + */ + + writetype = CLIENTWRITE_HEADER; + if(data->set.include_header) + writetype |= CLIENTWRITE_BODY; + + if(data->set.verbose) + Curl_debug(data, CURLINFO_HEADER_IN, k->p, (size_t)k->hbuflen); + + result = Curl_client_write(conn, writetype, k->p, k->hbuflen); + if(result) + return result; + + data->info.header_size += (long)k->hbuflen; + data->req.headerbytecount += (long)k->hbuflen; + + /* reset hbufp pointer && hbuflen */ + k->hbufp = data->state.headerbuff; + k->hbuflen = 0; + } + while(*k->str); /* header line within buffer */ + + /* We might have reached the end of the header part here, but + there might be a non-header part left in the end of the read + buffer. */ + + return CURLE_OK; +} + +#endif /* CURL_DISABLE_HTTP */ diff --git a/libcurl/lib/http.h b/libcurl/lib/http.h new file mode 100644 index 0000000..72161f6 --- /dev/null +++ b/libcurl/lib/http.h @@ -0,0 +1,257 @@ +#ifndef HEADER_CURL_HTTP_H +#define HEADER_CURL_HTTP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifndef CURL_DISABLE_HTTP + +#ifdef USE_NGHTTP2 +#include +#endif + +extern const struct Curl_handler Curl_handler_http; + +#ifdef USE_SSL +extern const struct Curl_handler Curl_handler_https; +#endif + +/* Header specific functions */ +bool Curl_compareheader(const char *headerline, /* line to check */ + const char *header, /* header keyword _with_ colon */ + const char *content); /* content string to find */ + +char *Curl_copy_header_value(const char *header); + +char *Curl_checkProxyheaders(const struct connectdata *conn, + const char *thisheader); +/* ------------------------------------------------------------------------- */ +/* + * The add_buffer series of functions are used to build one large memory chunk + * from repeated function invokes. Used so that the entire HTTP request can + * be sent in one go. + */ +struct Curl_send_buffer { + char *buffer; + size_t size_max; + size_t size_used; +}; +typedef struct Curl_send_buffer Curl_send_buffer; + +Curl_send_buffer *Curl_add_buffer_init(void); +void Curl_add_buffer_free(Curl_send_buffer **inp); +CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const char *fmt, ...) + WARN_UNUSED_RESULT; +CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr, + size_t size) WARN_UNUSED_RESULT; +CURLcode Curl_add_buffer_send(Curl_send_buffer **inp, + struct connectdata *conn, + curl_off_t *bytes_written, + size_t included_body_bytes, + int socketindex); + +CURLcode Curl_add_timecondition(const struct connectdata *conn, + Curl_send_buffer *buf); +CURLcode Curl_add_custom_headers(struct connectdata *conn, + bool is_connect, + Curl_send_buffer *req_buffer); +CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, + Curl_send_buffer *buffer, + struct Curl_easy *handle); + +/* protocol-specific functions set up to be called by the main engine */ +CURLcode Curl_http(struct connectdata *conn, bool *done); +CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature); +CURLcode Curl_http_connect(struct connectdata *conn, bool *done); + +/* The following functions are defined in http_chunks.c */ +void Curl_httpchunk_init(struct connectdata *conn); +CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap, + ssize_t length, ssize_t *wrote); + +/* These functions are in http.c */ +CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, + const char *auth); +CURLcode Curl_http_auth_act(struct connectdata *conn); + +/* If only the PICKNONE bit is set, there has been a round-trip and we + selected to use no auth at all. Ie, we actively select no auth, as opposed + to not having one selected. The other CURLAUTH_* defines are present in the + public curl/curl.h header. */ +#define CURLAUTH_PICKNONE (1<<30) /* don't use auth */ + +/* MAX_INITIAL_POST_SIZE indicates the number of bytes that will make the POST + data get included in the initial data chunk sent to the server. If the + data is larger than this, it will automatically get split up in multiple + system calls. + + This value used to be fairly big (100K), but we must take into account that + if the server rejects the POST due for authentication reasons, this data + will always be unconditionally sent and thus it may not be larger than can + always be afforded to send twice. + + It must not be greater than 64K to work on VMS. +*/ +#ifndef MAX_INITIAL_POST_SIZE +#define MAX_INITIAL_POST_SIZE (64*1024) +#endif + +/* EXPECT_100_THRESHOLD is the request body size limit for when libcurl will + * automatically add an "Expect: 100-continue" header in HTTP requests. When + * the size is unknown, it will always add it. + * + */ +#ifndef EXPECT_100_THRESHOLD +#define EXPECT_100_THRESHOLD 1024 +#endif + +#endif /* CURL_DISABLE_HTTP */ + +/**************************************************************************** + * HTTP unique setup + ***************************************************************************/ +struct HTTP { + curl_mimepart *sendit; + curl_off_t postsize; /* off_t to handle large file sizes */ + const char *postdata; + + const char *p_pragma; /* Pragma: string */ + const char *p_accept; /* Accept: string */ + + /* For FORM posting */ + curl_mimepart form; + + struct back { + curl_read_callback fread_func; /* backup storage for fread pointer */ + void *fread_in; /* backup storage for fread_in pointer */ + const char *postdata; + curl_off_t postsize; + } backup; + + enum { + HTTPSEND_NADA, /* init */ + HTTPSEND_REQUEST, /* sending a request */ + HTTPSEND_BODY, /* sending body */ + HTTPSEND_LAST /* never use this */ + } sending; + +#ifndef CURL_DISABLE_HTTP + Curl_send_buffer *send_buffer; /* used if the request couldn't be sent in + one chunk, points to an allocated + send_buffer struct */ +#endif +#ifdef USE_NGHTTP2 + /*********** for HTTP/2 we store stream-local data here *************/ + int32_t stream_id; /* stream we are interested in */ + + bool bodystarted; + /* We store non-final and final response headers here, per-stream */ + Curl_send_buffer *header_recvbuf; + size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into + upper layer */ + Curl_send_buffer *trailer_recvbuf; + int status_code; /* HTTP status code */ + const uint8_t *pausedata; /* pointer to data received in on_data_chunk */ + size_t pauselen; /* the number of bytes left in data */ + bool closed; /* TRUE on HTTP2 stream close */ + bool close_handled; /* TRUE if stream closure is handled by libcurl */ + char *mem; /* points to a buffer in memory to store received data */ + size_t len; /* size of the buffer 'mem' points to */ + size_t memlen; /* size of data copied to mem */ + + const uint8_t *upload_mem; /* points to a buffer to read from */ + size_t upload_len; /* size of the buffer 'upload_mem' points to */ + curl_off_t upload_left; /* number of bytes left to upload */ + + char **push_headers; /* allocated array */ + size_t push_headers_used; /* number of entries filled in */ + size_t push_headers_alloc; /* number of entries allocated */ +#endif +}; + +#ifdef USE_NGHTTP2 +/* h2 settings for this connection */ +struct h2settings { + uint32_t max_concurrent_streams; + bool enable_push; +}; +#endif + +struct http_conn { +#ifdef USE_NGHTTP2 +#define H2_BINSETTINGS_LEN 80 + nghttp2_session *h2; + uint8_t binsettings[H2_BINSETTINGS_LEN]; + size_t binlen; /* length of the binsettings data */ + Curl_send *send_underlying; /* underlying send Curl_send callback */ + Curl_recv *recv_underlying; /* underlying recv Curl_recv callback */ + char *inbuf; /* buffer to receive data from underlying socket */ + size_t inbuflen; /* number of bytes filled in inbuf */ + size_t nread_inbuf; /* number of bytes read from in inbuf */ + /* We need separate buffer for transmission and reception because we + may call nghttp2_session_send() after the + nghttp2_session_mem_recv() but mem buffer is still not full. In + this case, we wrongly sends the content of mem buffer if we share + them for both cases. */ + int32_t pause_stream_id; /* stream ID which paused + nghttp2_session_mem_recv */ + size_t drain_total; /* sum of all stream's UrlState.drain */ + + /* this is a hash of all individual streams (Curl_easy structs) */ + struct h2settings settings; + + /* list of settings that will be sent */ + nghttp2_settings_entry local_settings[3]; + size_t local_settings_num; + uint32_t error_code; /* HTTP/2 error code */ +#else + int unused; /* prevent a compiler warning */ +#endif +}; + +CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, + struct connectdata *conn, + ssize_t *nread, + bool *stop_reading); + +/** + * Curl_http_output_auth() setups the authentication headers for the + * host/proxy and the correct authentication + * method. conn->data->state.authdone is set to TRUE when authentication is + * done. + * + * @param conn all information about the current connection + * @param request pointer to the request keyword + * @param path pointer to the requested path + * @param proxytunnel boolean if this is the request setting up a "proxy + * tunnel" + * + * @returns CURLcode + */ +CURLcode +Curl_http_output_auth(struct connectdata *conn, + const char *request, + const char *path, + bool proxytunnel); /* TRUE if this is the request setting + up the proxy tunnel */ + +#endif /* HEADER_CURL_HTTP_H */ diff --git a/libcurl/lib/http2.c b/libcurl/lib/http2.c new file mode 100644 index 0000000..eb55e62 --- /dev/null +++ b/libcurl/lib/http2.c @@ -0,0 +1,2437 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_NGHTTP2 +#include +#include "urldata.h" +#include "http2.h" +#include "http.h" +#include "sendf.h" +#include "select.h" +#include "curl_base64.h" +#include "strcase.h" +#include "multiif.h" +#include "url.h" +#include "connect.h" +#include "strtoofft.h" +#include "strdup.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#define H2_BUFSIZE 32768 + +#if (NGHTTP2_VERSION_NUM < 0x010000) +#error too old nghttp2 version, upgrade! +#endif + +#if (NGHTTP2_VERSION_NUM > 0x010800) +#define NGHTTP2_HAS_HTTP2_STRERROR 1 +#endif + +#if (NGHTTP2_VERSION_NUM >= 0x010900) +/* nghttp2_session_callbacks_set_error_callback is present in nghttp2 1.9.0 or + later */ +#define NGHTTP2_HAS_ERROR_CALLBACK 1 +#else +#define nghttp2_session_callbacks_set_error_callback(x,y) +#endif + +#if (NGHTTP2_VERSION_NUM >= 0x010c00) +#define NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE 1 +#endif + +#define HTTP2_HUGE_WINDOW_SIZE (1 << 30) + +#ifdef DEBUG_HTTP2 +#define H2BUGF(x) x +#else +#define H2BUGF(x) do { } WHILE_FALSE +#endif + + +static ssize_t http2_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err); +static bool http2_connisdead(struct connectdata *conn); +static int h2_session_send(struct Curl_easy *data, + nghttp2_session *h2); +static int h2_process_pending_input(struct connectdata *conn, + struct http_conn *httpc, + CURLcode *err); + +/* + * Curl_http2_init_state() is called when the easy handle is created and + * allows for HTTP/2 specific init of state. + */ +void Curl_http2_init_state(struct UrlState *state) +{ + state->stream_weight = NGHTTP2_DEFAULT_WEIGHT; +} + +/* + * Curl_http2_init_userset() is called when the easy handle is created and + * allows for HTTP/2 specific user-set fields. + */ +void Curl_http2_init_userset(struct UserDefined *set) +{ + set->stream_weight = NGHTTP2_DEFAULT_WEIGHT; +} + +static int http2_perform_getsock(const struct connectdata *conn, + curl_socket_t *sock, /* points to + numsocks + number of + sockets */ + int numsocks) +{ + const struct http_conn *c = &conn->proto.httpc; + struct SingleRequest *k = &conn->data->req; + int bitmap = GETSOCK_BLANK; + (void)numsocks; + + sock[0] = conn->sock[FIRSTSOCKET]; + + /* in a HTTP/2 connection we can basically always get a frame so we should + always be ready for one */ + bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); + + /* we're still uploading or the HTTP/2 layer wants to send data */ + if(((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND) || + nghttp2_session_want_write(c->h2)) + bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); + + return bitmap; +} + +static int http2_getsock(struct connectdata *conn, + curl_socket_t *sock, /* points to numsocks + number of sockets */ + int numsocks) +{ + return http2_perform_getsock(conn, sock, numsocks); +} + +/* + * http2_stream_free() free HTTP2 stream related data + */ +static void http2_stream_free(struct HTTP *http) +{ + if(http) { + Curl_add_buffer_free(&http->header_recvbuf); + Curl_add_buffer_free(&http->trailer_recvbuf); + for(; http->push_headers_used > 0; --http->push_headers_used) { + free(http->push_headers[http->push_headers_used - 1]); + } + free(http->push_headers); + http->push_headers = NULL; + } +} + +/* + * Disconnects *a* connection used for HTTP/2. It might be an old one from the + * connection cache and not the "main" one. Don't touch the easy handle! + */ + +static CURLcode http2_disconnect(struct connectdata *conn, + bool dead_connection) +{ + struct http_conn *c = &conn->proto.httpc; + (void)dead_connection; + + H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n")); + + nghttp2_session_del(c->h2); + Curl_safefree(c->inbuf); + + H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n")); + + return CURLE_OK; +} + +/* + * The server may send us data at any point (e.g. PING frames). Therefore, + * we cannot assume that an HTTP/2 socket is dead just because it is readable. + * + * Instead, if it is readable, run Curl_connalive() to peek at the socket + * and distinguish between closed and data. + */ +static bool http2_connisdead(struct connectdata *conn) +{ + int sval; + bool dead = TRUE; + + if(conn->bits.close) + return TRUE; + + sval = SOCKET_READABLE(conn->sock[FIRSTSOCKET], 0); + if(sval == 0) { + /* timeout */ + dead = FALSE; + } + else if(sval & CURL_CSELECT_ERR) { + /* socket is in an error state */ + dead = TRUE; + } + else if(sval & CURL_CSELECT_IN) { + /* readable with no error. could still be closed */ + dead = !Curl_connalive(conn); + if(!dead) { + /* This happens before we've sent off a request and the connection is + not in use by any other transfer, there shouldn't be any data here, + only "protocol frames" */ + CURLcode result; + struct http_conn *httpc = &conn->proto.httpc; + ssize_t nread = -1; + if(httpc->recv_underlying) + /* if called "too early", this pointer isn't setup yet! */ + nread = ((Curl_recv *)httpc->recv_underlying)( + conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result); + if(nread != -1) { + infof(conn->data, + "%d bytes stray data read before trying h2 connection\n", + (int)nread); + httpc->nread_inbuf = 0; + httpc->inbuflen = nread; + (void)h2_process_pending_input(conn, httpc, &result); + } + else + /* the read failed so let's say this is dead anyway */ + dead = TRUE; + } + } + + return dead; +} + +static unsigned int http2_conncheck(struct connectdata *check, + unsigned int checks_to_perform) +{ + unsigned int ret_val = CONNRESULT_NONE; + struct http_conn *c = &check->proto.httpc; + int rc; + bool send_frames = false; + + if(checks_to_perform & CONNCHECK_ISDEAD) { + if(http2_connisdead(check)) + ret_val |= CONNRESULT_DEAD; + } + + if(checks_to_perform & CONNCHECK_KEEPALIVE) { + struct curltime now = Curl_now(); + time_t elapsed = Curl_timediff(now, check->keepalive); + + if(elapsed > check->upkeep_interval_ms) { + /* Perform an HTTP/2 PING */ + rc = nghttp2_submit_ping(c->h2, 0, ZERO_NULL); + if(!rc) { + /* Successfully added a PING frame to the session. Need to flag this + so the frame is sent. */ + send_frames = true; + } + else { + failf(check->data, "nghttp2_submit_ping() failed: %s(%d)", + nghttp2_strerror(rc), rc); + } + + check->keepalive = now; + } + } + + if(send_frames) { + rc = nghttp2_session_send(c->h2); + if(rc) + failf(check->data, "nghttp2_session_send() failed: %s(%d)", + nghttp2_strerror(rc), rc); + } + + return ret_val; +} + +/* called from http_setup_conn */ +void Curl_http2_setup_req(struct Curl_easy *data) +{ + struct HTTP *http = data->req.protop; + + http->nread_header_recvbuf = 0; + http->bodystarted = FALSE; + http->status_code = -1; + http->pausedata = NULL; + http->pauselen = 0; + http->closed = FALSE; + http->close_handled = FALSE; + http->mem = data->state.buffer; + http->len = data->set.buffer_size; + http->memlen = 0; +} + +/* called from http_setup_conn */ +void Curl_http2_setup_conn(struct connectdata *conn) +{ + conn->proto.httpc.settings.max_concurrent_streams = + DEFAULT_MAX_CONCURRENT_STREAMS; + conn->proto.httpc.error_code = NGHTTP2_NO_ERROR; +} + +/* + * HTTP2 handler interface. This isn't added to the general list of protocols + * but will be used at run-time when the protocol is dynamically switched from + * HTTP to HTTP2. + */ +static const struct Curl_handler Curl_handler_http2 = { + "HTTP", /* scheme */ + ZERO_NULL, /* setup_connection */ + Curl_http, /* do_it */ + Curl_http_done, /* done */ + ZERO_NULL, /* do_more */ + ZERO_NULL, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + http2_getsock, /* proto_getsock */ + http2_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + http2_perform_getsock, /* perform_getsock */ + http2_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + http2_conncheck, /* connection_check */ + PORT_HTTP, /* defport */ + CURLPROTO_HTTP, /* protocol */ + PROTOPT_STREAM /* flags */ +}; + +static const struct Curl_handler Curl_handler_http2_ssl = { + "HTTPS", /* scheme */ + ZERO_NULL, /* setup_connection */ + Curl_http, /* do_it */ + Curl_http_done, /* done */ + ZERO_NULL, /* do_more */ + ZERO_NULL, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + http2_getsock, /* proto_getsock */ + http2_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + http2_perform_getsock, /* perform_getsock */ + http2_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + http2_conncheck, /* connection_check */ + PORT_HTTP, /* defport */ + CURLPROTO_HTTPS, /* protocol */ + PROTOPT_SSL | PROTOPT_STREAM /* flags */ +}; + +/* + * Store nghttp2 version info in this buffer, Prefix with a space. Return + * total length written. + */ +int Curl_http2_ver(char *p, size_t len) +{ + nghttp2_info *h2 = nghttp2_version(0); + return msnprintf(p, len, " nghttp2/%s", h2->version_str); +} + +/* HTTP/2 error code to name based on the Error Code Registry. +https://tools.ietf.org/html/rfc7540#page-77 +nghttp2_error_code enums are identical. +*/ +static const char *http2_strerror(uint32_t err) +{ +#ifndef NGHTTP2_HAS_HTTP2_STRERROR + const char *str[] = { + "NO_ERROR", /* 0x0 */ + "PROTOCOL_ERROR", /* 0x1 */ + "INTERNAL_ERROR", /* 0x2 */ + "FLOW_CONTROL_ERROR", /* 0x3 */ + "SETTINGS_TIMEOUT", /* 0x4 */ + "STREAM_CLOSED", /* 0x5 */ + "FRAME_SIZE_ERROR", /* 0x6 */ + "REFUSED_STREAM", /* 0x7 */ + "CANCEL", /* 0x8 */ + "COMPRESSION_ERROR", /* 0x9 */ + "CONNECT_ERROR", /* 0xA */ + "ENHANCE_YOUR_CALM", /* 0xB */ + "INADEQUATE_SECURITY", /* 0xC */ + "HTTP_1_1_REQUIRED" /* 0xD */ + }; + return (err < sizeof(str) / sizeof(str[0])) ? str[err] : "unknown"; +#else + return nghttp2_http2_strerror(err); +#endif +} + +/* + * The implementation of nghttp2_send_callback type. Here we write |data| with + * size |length| to the network and return the number of bytes actually + * written. See the documentation of nghttp2_send_callback for the details. + */ +static ssize_t send_callback(nghttp2_session *h2, + const uint8_t *data, size_t length, int flags, + void *userp) +{ + struct connectdata *conn = (struct connectdata *)userp; + struct http_conn *c = &conn->proto.httpc; + ssize_t written; + CURLcode result = CURLE_OK; + + (void)h2; + (void)flags; + + if(!c->send_underlying) + /* called before setup properly! */ + return NGHTTP2_ERR_CALLBACK_FAILURE; + + written = ((Curl_send*)c->send_underlying)(conn, FIRSTSOCKET, + data, length, &result); + + if(result == CURLE_AGAIN) { + return NGHTTP2_ERR_WOULDBLOCK; + } + + if(written == -1) { + failf(conn->data, "Failed sending HTTP2 data"); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + + if(!written) + return NGHTTP2_ERR_WOULDBLOCK; + + return written; +} + + +/* We pass a pointer to this struct in the push callback, but the contents of + the struct are hidden from the user. */ +struct curl_pushheaders { + struct Curl_easy *data; + const nghttp2_push_promise *frame; +}; + +/* + * push header access function. Only to be used from within the push callback + */ +char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num) +{ + /* Verify that we got a good easy handle in the push header struct, mostly to + detect rubbish input fast(er). */ + if(!h || !GOOD_EASY_HANDLE(h->data)) + return NULL; + else { + struct HTTP *stream = h->data->req.protop; + if(num < stream->push_headers_used) + return stream->push_headers[num]; + } + return NULL; +} + +/* + * push header access function. Only to be used from within the push callback + */ +char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header) +{ + /* Verify that we got a good easy handle in the push header struct, + mostly to detect rubbish input fast(er). Also empty header name + is just a rubbish too. We have to allow ":" at the beginning of + the header, but header == ":" must be rejected. If we have ':' in + the middle of header, it could be matched in middle of the value, + this is because we do prefix match.*/ + if(!h || !GOOD_EASY_HANDLE(h->data) || !header || !header[0] || + !strcmp(header, ":") || strchr(header + 1, ':')) + return NULL; + else { + struct HTTP *stream = h->data->req.protop; + size_t len = strlen(header); + size_t i; + for(i = 0; ipush_headers_used; i++) { + if(!strncmp(header, stream->push_headers[i], len)) { + /* sub-match, make sure that it is followed by a colon */ + if(stream->push_headers[i][len] != ':') + continue; + return &stream->push_headers[i][len + 1]; + } + } + } + return NULL; +} + +/* + * This specific transfer on this connection has been "drained". + */ +static void drained_transfer(struct Curl_easy *data, + struct http_conn *httpc) +{ + DEBUGASSERT(httpc->drain_total >= data->state.drain); + httpc->drain_total -= data->state.drain; + data->state.drain = 0; +} + +/* + * Mark this transfer to get "drained". + */ +static void drain_this(struct Curl_easy *data, + struct http_conn *httpc) +{ + data->state.drain++; + httpc->drain_total++; + DEBUGASSERT(httpc->drain_total >= data->state.drain); +} + +static struct Curl_easy *duphandle(struct Curl_easy *data) +{ + struct Curl_easy *second = curl_easy_duphandle(data); + if(second) { + /* setup the request struct */ + struct HTTP *http = calloc(1, sizeof(struct HTTP)); + if(!http) { + (void)Curl_close(second); + second = NULL; + } + else { + second->req.protop = http; + http->header_recvbuf = Curl_add_buffer_init(); + if(!http->header_recvbuf) { + free(http); + (void)Curl_close(second); + second = NULL; + } + else { + Curl_http2_setup_req(second); + second->state.stream_weight = data->state.stream_weight; + } + } + } + return second; +} + + +static int push_promise(struct Curl_easy *data, + struct connectdata *conn, + const nghttp2_push_promise *frame) +{ + int rv; + H2BUGF(infof(data, "PUSH_PROMISE received, stream %u!\n", + frame->promised_stream_id)); + if(data->multi->push_cb) { + struct HTTP *stream; + struct HTTP *newstream; + struct curl_pushheaders heads; + CURLMcode rc; + struct http_conn *httpc; + size_t i; + /* clone the parent */ + struct Curl_easy *newhandle = duphandle(data); + if(!newhandle) { + infof(data, "failed to duplicate handle\n"); + rv = 1; /* FAIL HARD */ + goto fail; + } + + heads.data = data; + heads.frame = frame; + /* ask the application */ + H2BUGF(infof(data, "Got PUSH_PROMISE, ask application!\n")); + + stream = data->req.protop; + if(!stream) { + failf(data, "Internal NULL stream!\n"); + (void)Curl_close(newhandle); + rv = 1; + goto fail; + } + + Curl_set_in_callback(data, true); + rv = data->multi->push_cb(data, newhandle, + stream->push_headers_used, &heads, + data->multi->push_userp); + Curl_set_in_callback(data, false); + + /* free the headers again */ + for(i = 0; ipush_headers_used; i++) + free(stream->push_headers[i]); + free(stream->push_headers); + stream->push_headers = NULL; + stream->push_headers_used = 0; + + if(rv) { + /* denied, kill off the new handle again */ + http2_stream_free(newhandle->req.protop); + newhandle->req.protop = NULL; + (void)Curl_close(newhandle); + goto fail; + } + + newstream = newhandle->req.protop; + newstream->stream_id = frame->promised_stream_id; + newhandle->req.maxdownload = -1; + newhandle->req.size = -1; + + /* approved, add to the multi handle and immediately switch to PERFORM + state with the given connection !*/ + rc = Curl_multi_add_perform(data->multi, newhandle, conn); + if(rc) { + infof(data, "failed to add handle to multi\n"); + http2_stream_free(newhandle->req.protop); + newhandle->req.protop = NULL; + Curl_close(newhandle); + rv = 1; + goto fail; + } + + httpc = &conn->proto.httpc; + rv = nghttp2_session_set_stream_user_data(httpc->h2, + frame->promised_stream_id, + newhandle); + if(rv) { + infof(data, "failed to set user_data for stream %d\n", + frame->promised_stream_id); + DEBUGASSERT(0); + goto fail; + } + } + else { + H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n")); + rv = 1; + } + fail: + return rv; +} + +/* + * multi_connchanged() is called to tell that there is a connection in + * this multi handle that has changed state (multiplexing become possible, the + * number of allowed streams changed or similar), and a subsequent use of this + * multi handle should move CONNECT_PEND handles back to CONNECT to have them + * retry. + */ +static void multi_connchanged(struct Curl_multi *multi) +{ + multi->recheckstate = TRUE; +} + +static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, + void *userp) +{ + struct connectdata *conn = (struct connectdata *)userp; + struct http_conn *httpc = &conn->proto.httpc; + struct Curl_easy *data_s = NULL; + struct HTTP *stream = NULL; + int rv; + size_t left, ncopy; + int32_t stream_id = frame->hd.stream_id; + CURLcode result; + + if(!stream_id) { + /* stream ID zero is for connection-oriented stuff */ + if(frame->hd.type == NGHTTP2_SETTINGS) { + uint32_t max_conn = httpc->settings.max_concurrent_streams; + H2BUGF(infof(conn->data, "Got SETTINGS\n")); + httpc->settings.max_concurrent_streams = + nghttp2_session_get_remote_settings( + session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS); + httpc->settings.enable_push = + nghttp2_session_get_remote_settings( + session, NGHTTP2_SETTINGS_ENABLE_PUSH); + H2BUGF(infof(conn->data, "MAX_CONCURRENT_STREAMS == %d\n", + httpc->settings.max_concurrent_streams)); + H2BUGF(infof(conn->data, "ENABLE_PUSH == %s\n", + httpc->settings.enable_push?"TRUE":"false")); + if(max_conn != httpc->settings.max_concurrent_streams) { + /* only signal change if the value actually changed */ + infof(conn->data, + "Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\n", + httpc->settings.max_concurrent_streams); + multi_connchanged(conn->data->multi); + } + } + return 0; + } + data_s = nghttp2_session_get_stream_user_data(session, stream_id); + if(!data_s) { + H2BUGF(infof(conn->data, + "No Curl_easy associated with stream: %x\n", + stream_id)); + return 0; + } + + stream = data_s->req.protop; + if(!stream) { + H2BUGF(infof(data_s, "No proto pointer for stream: %x\n", + stream_id)); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + + H2BUGF(infof(data_s, "on_frame_recv() header %x stream %x\n", + frame->hd.type, stream_id)); + + switch(frame->hd.type) { + case NGHTTP2_DATA: + /* If body started on this stream, then receiving DATA is illegal. */ + if(!stream->bodystarted) { + rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, + stream_id, NGHTTP2_PROTOCOL_ERROR); + + if(nghttp2_is_fatal(rv)) { + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + } + break; + case NGHTTP2_HEADERS: + if(stream->bodystarted) { + /* Only valid HEADERS after body started is trailer HEADERS. We + buffer them in on_header callback. */ + break; + } + + /* nghttp2 guarantees that :status is received, and we store it to + stream->status_code. Fuzzing has proven this can still be reached + without status code having been set. */ + if(stream->status_code == -1) + return NGHTTP2_ERR_CALLBACK_FAILURE; + + /* Only final status code signals the end of header */ + if(stream->status_code / 100 != 1) { + stream->bodystarted = TRUE; + stream->status_code = -1; + } + + result = Curl_add_buffer(&stream->header_recvbuf, "\r\n", 2); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + + left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf; + ncopy = CURLMIN(stream->len, left); + + memcpy(&stream->mem[stream->memlen], + stream->header_recvbuf->buffer + stream->nread_header_recvbuf, + ncopy); + stream->nread_header_recvbuf += ncopy; + + H2BUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n", + ncopy, stream_id, stream->mem)); + + stream->len -= ncopy; + stream->memlen += ncopy; + + drain_this(data_s, httpc); + { + /* get the pointer from userp again since it was re-assigned above */ + struct connectdata *conn_s = (struct connectdata *)userp; + + /* if we receive data for another handle, wake that up */ + if(conn_s->data != data_s) + Curl_expire(data_s, 0, EXPIRE_RUN_NOW); + } + break; + case NGHTTP2_PUSH_PROMISE: + rv = push_promise(data_s, conn, &frame->push_promise); + if(rv) { /* deny! */ + rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, + frame->push_promise.promised_stream_id, + NGHTTP2_CANCEL); + if(nghttp2_is_fatal(rv)) { + return rv; + } + } + break; + default: + H2BUGF(infof(data_s, "Got frame type %x for stream %u!\n", + frame->hd.type, stream_id)); + break; + } + return 0; +} + +static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, + int32_t stream_id, + const uint8_t *data, size_t len, void *userp) +{ + struct HTTP *stream; + struct Curl_easy *data_s; + size_t nread; + struct connectdata *conn = (struct connectdata *)userp; + (void)session; + (void)flags; + (void)data; + + DEBUGASSERT(stream_id); /* should never be a zero stream ID here */ + + /* get the stream from the hash based on Stream ID */ + data_s = nghttp2_session_get_stream_user_data(session, stream_id); + if(!data_s) + /* Receiving a Stream ID not in the hash should not happen, this is an + internal error more than anything else! */ + return NGHTTP2_ERR_CALLBACK_FAILURE; + + stream = data_s->req.protop; + if(!stream) + return NGHTTP2_ERR_CALLBACK_FAILURE; + + nread = CURLMIN(stream->len, len); + memcpy(&stream->mem[stream->memlen], data, nread); + + stream->len -= nread; + stream->memlen += nread; + + drain_this(data_s, &conn->proto.httpc); + + /* if we receive data for another handle, wake that up */ + if(conn->data != data_s) + Curl_expire(data_s, 0, EXPIRE_RUN_NOW); + + H2BUGF(infof(data_s, "%zu data received for stream %u " + "(%zu left in buffer %p, total %zu)\n", + nread, stream_id, + stream->len, stream->mem, + stream->memlen)); + + if(nread < len) { + stream->pausedata = data + nread; + stream->pauselen = len - nread; + H2BUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer" + ", stream %u\n", + len - nread, stream_id)); + data_s->conn->proto.httpc.pause_stream_id = stream_id; + + return NGHTTP2_ERR_PAUSE; + } + + /* pause execution of nghttp2 if we received data for another handle + in order to process them first. */ + if(conn->data != data_s) { + data_s->conn->proto.httpc.pause_stream_id = stream_id; + + return NGHTTP2_ERR_PAUSE; + } + + return 0; +} + +static int on_stream_close(nghttp2_session *session, int32_t stream_id, + uint32_t error_code, void *userp) +{ + struct Curl_easy *data_s; + struct HTTP *stream; + struct connectdata *conn = (struct connectdata *)userp; + int rv; + (void)session; + (void)stream_id; + + if(stream_id) { + struct http_conn *httpc; + /* get the stream from the hash based on Stream ID, stream ID zero is for + connection-oriented stuff */ + data_s = nghttp2_session_get_stream_user_data(session, stream_id); + if(!data_s) { + /* We could get stream ID not in the hash. For example, if we + decided to reject stream (e.g., PUSH_PROMISE). */ + return 0; + } + H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n", + http2_strerror(error_code), error_code, stream_id)); + stream = data_s->req.protop; + if(!stream) + return NGHTTP2_ERR_CALLBACK_FAILURE; + + stream->closed = TRUE; + httpc = &conn->proto.httpc; + drain_this(data_s, httpc); + httpc->error_code = error_code; + + /* remove the entry from the hash as the stream is now gone */ + rv = nghttp2_session_set_stream_user_data(session, stream_id, 0); + if(rv) { + infof(data_s, "http/2: failed to clear user_data for stream %d!\n", + stream_id); + DEBUGASSERT(0); + } + if(stream_id == httpc->pause_stream_id) { + H2BUGF(infof(data_s, "Stopped the pause stream!\n")); + httpc->pause_stream_id = 0; + } + H2BUGF(infof(data_s, "Removed stream %u hash!\n", stream_id)); + stream->stream_id = 0; /* cleared */ + } + return 0; +} + +static int on_begin_headers(nghttp2_session *session, + const nghttp2_frame *frame, void *userp) +{ + struct HTTP *stream; + struct Curl_easy *data_s = NULL; + (void)userp; + + data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); + if(!data_s) { + return 0; + } + + H2BUGF(infof(data_s, "on_begin_headers() was called\n")); + + if(frame->hd.type != NGHTTP2_HEADERS) { + return 0; + } + + stream = data_s->req.protop; + if(!stream || !stream->bodystarted) { + return 0; + } + + if(!stream->trailer_recvbuf) { + stream->trailer_recvbuf = Curl_add_buffer_init(); + if(!stream->trailer_recvbuf) { + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + } + } + return 0; +} + +/* Decode HTTP status code. Returns -1 if no valid status code was + decoded. */ +static int decode_status_code(const uint8_t *value, size_t len) +{ + int i; + int res; + + if(len != 3) { + return -1; + } + + res = 0; + + for(i = 0; i < 3; ++i) { + char c = value[i]; + + if(c < '0' || c > '9') { + return -1; + } + + res *= 10; + res += c - '0'; + } + + return res; +} + +/* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */ +static int on_header(nghttp2_session *session, const nghttp2_frame *frame, + const uint8_t *name, size_t namelen, + const uint8_t *value, size_t valuelen, + uint8_t flags, + void *userp) +{ + struct HTTP *stream; + struct Curl_easy *data_s; + int32_t stream_id = frame->hd.stream_id; + struct connectdata *conn = (struct connectdata *)userp; + CURLcode result; + (void)flags; + + DEBUGASSERT(stream_id); /* should never be a zero stream ID here */ + + /* get the stream from the hash based on Stream ID */ + data_s = nghttp2_session_get_stream_user_data(session, stream_id); + if(!data_s) + /* Receiving a Stream ID not in the hash should not happen, this is an + internal error more than anything else! */ + return NGHTTP2_ERR_CALLBACK_FAILURE; + + stream = data_s->req.protop; + if(!stream) { + failf(data_s, "Internal NULL stream! 5\n"); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + + /* Store received PUSH_PROMISE headers to be used when the subsequent + PUSH_PROMISE callback comes */ + if(frame->hd.type == NGHTTP2_PUSH_PROMISE) { + char *h; + + if(!strcmp(":authority", (const char *)name)) { + /* pseudo headers are lower case */ + int rc = 0; + char *check = aprintf("%s:%d", conn->host.name, conn->remote_port); + if(!check) + /* no memory */ + return NGHTTP2_ERR_CALLBACK_FAILURE; + if(!Curl_strcasecompare(check, (const char *)value)) { + /* This is push is not for the same authority that was asked for in + * the URL. RFC 7540 section 8.2 says: "A client MUST treat a + * PUSH_PROMISE for which the server is not authoritative as a stream + * error of type PROTOCOL_ERROR." + */ + (void)nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, + stream_id, NGHTTP2_PROTOCOL_ERROR); + rc = NGHTTP2_ERR_CALLBACK_FAILURE; + } + free(check); + if(rc) + return rc; + } + + if(!stream->push_headers) { + stream->push_headers_alloc = 10; + stream->push_headers = malloc(stream->push_headers_alloc * + sizeof(char *)); + if(!stream->push_headers) + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + stream->push_headers_used = 0; + } + else if(stream->push_headers_used == + stream->push_headers_alloc) { + char **headp; + stream->push_headers_alloc *= 2; + headp = Curl_saferealloc(stream->push_headers, + stream->push_headers_alloc * sizeof(char *)); + if(!headp) { + stream->push_headers = NULL; + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + } + stream->push_headers = headp; + } + h = aprintf("%s:%s", name, value); + if(h) + stream->push_headers[stream->push_headers_used++] = h; + return 0; + } + + if(stream->bodystarted) { + /* This is trailer fields. */ + /* 4 is for ": " and "\r\n". */ + uint32_t n = (uint32_t)(namelen + valuelen + 4); + + H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen, + value)); + + result = Curl_add_buffer(&stream->trailer_recvbuf, &n, sizeof(n)); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->trailer_recvbuf, name, namelen); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->trailer_recvbuf, ": ", 2); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->trailer_recvbuf, value, valuelen); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->trailer_recvbuf, "\r\n\0", 3); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + + return 0; + } + + if(namelen == sizeof(":status") - 1 && + memcmp(":status", name, namelen) == 0) { + /* nghttp2 guarantees :status is received first and only once, and + value is 3 digits status code, and decode_status_code always + succeeds. */ + stream->status_code = decode_status_code(value, valuelen); + DEBUGASSERT(stream->status_code != -1); + + result = Curl_add_buffer(&stream->header_recvbuf, "HTTP/2 ", 7); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->header_recvbuf, value, valuelen); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + /* the space character after the status code is mandatory */ + result = Curl_add_buffer(&stream->header_recvbuf, " \r\n", 3); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + /* if we receive data for another handle, wake that up */ + if(conn->data != data_s) + Curl_expire(data_s, 0, EXPIRE_RUN_NOW); + + H2BUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n", + stream->status_code, data_s)); + return 0; + } + + /* nghttp2 guarantees that namelen > 0, and :status was already + received, and this is not pseudo-header field . */ + /* convert to a HTTP1-style header */ + result = Curl_add_buffer(&stream->header_recvbuf, name, namelen); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->header_recvbuf, ": ", 2); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->header_recvbuf, value, valuelen); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + result = Curl_add_buffer(&stream->header_recvbuf, "\r\n", 2); + if(result) + return NGHTTP2_ERR_CALLBACK_FAILURE; + /* if we receive data for another handle, wake that up */ + if(conn->data != data_s) + Curl_expire(data_s, 0, EXPIRE_RUN_NOW); + + H2BUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen, + value)); + + return 0; /* 0 is successful */ +} + +static ssize_t data_source_read_callback(nghttp2_session *session, + int32_t stream_id, + uint8_t *buf, size_t length, + uint32_t *data_flags, + nghttp2_data_source *source, + void *userp) +{ + struct Curl_easy *data_s; + struct HTTP *stream = NULL; + size_t nread; + (void)source; + (void)userp; + + if(stream_id) { + /* get the stream from the hash based on Stream ID, stream ID zero is for + connection-oriented stuff */ + data_s = nghttp2_session_get_stream_user_data(session, stream_id); + if(!data_s) + /* Receiving a Stream ID not in the hash should not happen, this is an + internal error more than anything else! */ + return NGHTTP2_ERR_CALLBACK_FAILURE; + + stream = data_s->req.protop; + if(!stream) + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + else + return NGHTTP2_ERR_INVALID_ARGUMENT; + + nread = CURLMIN(stream->upload_len, length); + if(nread > 0) { + memcpy(buf, stream->upload_mem, nread); + stream->upload_mem += nread; + stream->upload_len -= nread; + if(data_s->state.infilesize != -1) + stream->upload_left -= nread; + } + + if(stream->upload_left == 0) + *data_flags = NGHTTP2_DATA_FLAG_EOF; + else if(nread == 0) + return NGHTTP2_ERR_DEFERRED; + + H2BUGF(infof(data_s, "data_source_read_callback: " + "returns %zu bytes stream %u\n", + nread, stream_id)); + + return nread; +} + +#if defined(NGHTTP2_HAS_ERROR_CALLBACK) && \ + !defined(CURL_DISABLE_VERBOSE_STRINGS) +static int error_callback(nghttp2_session *session, + const char *msg, + size_t len, + void *userp) +{ + struct connectdata *conn = (struct connectdata *)userp; + (void)session; + infof(conn->data, "http2 error: %.*s\n", len, msg); + return 0; +} +#endif + +static void populate_settings(struct connectdata *conn, + struct http_conn *httpc) +{ + nghttp2_settings_entry *iv = httpc->local_settings; + + iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS; + iv[0].value = 100; + + iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; + iv[1].value = HTTP2_HUGE_WINDOW_SIZE; + + iv[2].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH; + iv[2].value = conn->data->multi->push_cb != NULL; + + httpc->local_settings_num = 3; +} + +void Curl_http2_done(struct connectdata *conn, bool premature) +{ + struct Curl_easy *data = conn->data; + struct HTTP *http = data->req.protop; + struct http_conn *httpc = &conn->proto.httpc; + + /* there might be allocated resources done before this got the 'h2' pointer + setup */ + if(http->header_recvbuf) { + Curl_add_buffer_free(&http->header_recvbuf); + Curl_add_buffer_free(&http->trailer_recvbuf); + if(http->push_headers) { + /* if they weren't used and then freed before */ + for(; http->push_headers_used > 0; --http->push_headers_used) { + free(http->push_headers[http->push_headers_used - 1]); + } + free(http->push_headers); + http->push_headers = NULL; + } + } + + if(!httpc->h2) /* not HTTP/2 ? */ + return; + + if(premature) { + /* RST_STREAM */ + if(!nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE, + http->stream_id, NGHTTP2_STREAM_CLOSED)) + (void)nghttp2_session_send(httpc->h2); + + if(http->stream_id == httpc->pause_stream_id) { + infof(data, "stopped the pause stream!\n"); + httpc->pause_stream_id = 0; + } + } + + if(data->state.drain) + drained_transfer(data, httpc); + + /* -1 means unassigned and 0 means cleared */ + if(http->stream_id > 0) { + int rv = nghttp2_session_set_stream_user_data(httpc->h2, + http->stream_id, 0); + if(rv) { + infof(data, "http/2: failed to clear user_data for stream %d!\n", + http->stream_id); + DEBUGASSERT(0); + } + http->stream_id = 0; + } +} + +/* + * Initialize nghttp2 for a Curl connection + */ +static CURLcode http2_init(struct connectdata *conn) +{ + if(!conn->proto.httpc.h2) { + int rc; + nghttp2_session_callbacks *callbacks; + + conn->proto.httpc.inbuf = malloc(H2_BUFSIZE); + if(conn->proto.httpc.inbuf == NULL) + return CURLE_OUT_OF_MEMORY; + + rc = nghttp2_session_callbacks_new(&callbacks); + + if(rc) { + failf(conn->data, "Couldn't initialize nghttp2 callbacks!"); + return CURLE_OUT_OF_MEMORY; /* most likely at least */ + } + + /* nghttp2_send_callback */ + nghttp2_session_callbacks_set_send_callback(callbacks, send_callback); + /* nghttp2_on_frame_recv_callback */ + nghttp2_session_callbacks_set_on_frame_recv_callback + (callbacks, on_frame_recv); + /* nghttp2_on_data_chunk_recv_callback */ + nghttp2_session_callbacks_set_on_data_chunk_recv_callback + (callbacks, on_data_chunk_recv); + /* nghttp2_on_stream_close_callback */ + nghttp2_session_callbacks_set_on_stream_close_callback + (callbacks, on_stream_close); + /* nghttp2_on_begin_headers_callback */ + nghttp2_session_callbacks_set_on_begin_headers_callback + (callbacks, on_begin_headers); + /* nghttp2_on_header_callback */ + nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header); + +#ifndef CURL_DISABLE_VERBOSE_STRINGS + nghttp2_session_callbacks_set_error_callback(callbacks, error_callback); +#endif + + /* The nghttp2 session is not yet setup, do it */ + rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn); + + nghttp2_session_callbacks_del(callbacks); + + if(rc) { + failf(conn->data, "Couldn't initialize nghttp2!"); + return CURLE_OUT_OF_MEMORY; /* most likely at least */ + } + } + return CURLE_OK; +} + +/* + * Append headers to ask for a HTTP1.1 to HTTP2 upgrade. + */ +CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req, + struct connectdata *conn) +{ + CURLcode result; + ssize_t binlen; + char *base64; + size_t blen; + struct SingleRequest *k = &conn->data->req; + uint8_t *binsettings = conn->proto.httpc.binsettings; + struct http_conn *httpc = &conn->proto.httpc; + + populate_settings(conn, httpc); + + /* this returns number of bytes it wrote */ + binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN, + httpc->local_settings, + httpc->local_settings_num); + if(!binlen) { + failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload"); + Curl_add_buffer_free(&req); + return CURLE_FAILED_INIT; + } + conn->proto.httpc.binlen = binlen; + + result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen, + &base64, &blen); + if(result) { + Curl_add_buffer_free(&req); + return result; + } + + result = Curl_add_bufferf(&req, + "Connection: Upgrade, HTTP2-Settings\r\n" + "Upgrade: %s\r\n" + "HTTP2-Settings: %s\r\n", + NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64); + free(base64); + + k->upgr101 = UPGR101_REQUESTED; + + return result; +} + +/* + * Returns nonzero if current HTTP/2 session should be closed. + */ +static int should_close_session(struct http_conn *httpc) +{ + return httpc->drain_total == 0 && !nghttp2_session_want_read(httpc->h2) && + !nghttp2_session_want_write(httpc->h2); +} + +/* + * h2_process_pending_input() processes pending input left in + * httpc->inbuf. Then, call h2_session_send() to send pending data. + * This function returns 0 if it succeeds, or -1 and error code will + * be assigned to *err. + */ +static int h2_process_pending_input(struct connectdata *conn, + struct http_conn *httpc, + CURLcode *err) +{ + ssize_t nread; + char *inbuf; + ssize_t rv; + struct Curl_easy *data = conn->data; + + nread = httpc->inbuflen - httpc->nread_inbuf; + inbuf = httpc->inbuf + httpc->nread_inbuf; + + rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread); + if(rv < 0) { + failf(data, + "h2_process_pending_input: nghttp2_session_mem_recv() returned " + "%zd:%s\n", rv, nghttp2_strerror((int)rv)); + *err = CURLE_RECV_ERROR; + return -1; + } + + if(nread == rv) { + H2BUGF(infof(data, + "h2_process_pending_input: All data in connection buffer " + "processed\n")); + httpc->inbuflen = 0; + httpc->nread_inbuf = 0; + } + else { + httpc->nread_inbuf += rv; + H2BUGF(infof(data, + "h2_process_pending_input: %zu bytes left in connection " + "buffer\n", + httpc->inbuflen - httpc->nread_inbuf)); + } + + rv = h2_session_send(data, httpc->h2); + if(rv != 0) { + *err = CURLE_SEND_ERROR; + return -1; + } + + if(should_close_session(httpc)) { + H2BUGF(infof(data, + "h2_process_pending_input: nothing to do in this session\n")); + if(httpc->error_code) + *err = CURLE_HTTP2; + else { + /* not an error per se, but should still close the connection */ + connclose(conn, "GOAWAY received"); + *err = CURLE_OK; + } + return -1; + } + + return 0; +} + +/* + * Called from transfer.c:done_sending when we stop uploading. + */ +CURLcode Curl_http2_done_sending(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + + if((conn->handler == &Curl_handler_http2_ssl) || + (conn->handler == &Curl_handler_http2)) { + /* make sure this is only attempted for HTTP/2 transfers */ + + struct HTTP *stream = conn->data->req.protop; + + if(stream->upload_left) { + /* If the stream still thinks there's data left to upload. */ + struct http_conn *httpc = &conn->proto.httpc; + nghttp2_session *h2 = httpc->h2; + + stream->upload_left = 0; /* DONE! */ + + /* resume sending here to trigger the callback to get called again so + that it can signal EOF to nghttp2 */ + (void)nghttp2_session_resume_data(h2, stream->stream_id); + + (void)h2_process_pending_input(conn, httpc, &result); + } + } + return result; +} + +static ssize_t http2_handle_stream_close(struct connectdata *conn, + struct Curl_easy *data, + struct HTTP *stream, CURLcode *err) +{ + char *trailer_pos, *trailer_end; + CURLcode result; + struct http_conn *httpc = &conn->proto.httpc; + + if(httpc->pause_stream_id == stream->stream_id) { + httpc->pause_stream_id = 0; + } + + drained_transfer(data, httpc); + + if(httpc->pause_stream_id == 0) { + if(h2_process_pending_input(conn, httpc, err) != 0) { + return -1; + } + } + + DEBUGASSERT(data->state.drain == 0); + + /* Reset to FALSE to prevent infinite loop in readwrite_data function. */ + stream->closed = FALSE; + if(httpc->error_code == NGHTTP2_REFUSED_STREAM) { + H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection!\n", + stream->stream_id)); + connclose(conn, "REFUSED_STREAM"); /* don't use this anymore */ + data->state.refused_stream = TRUE; + *err = CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */ + return -1; + } + else if(httpc->error_code != NGHTTP2_NO_ERROR) { + failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)", + stream->stream_id, http2_strerror(httpc->error_code), + httpc->error_code); + *err = CURLE_HTTP2_STREAM; + return -1; + } + + if(!stream->bodystarted) { + failf(data, "HTTP/2 stream %d was closed cleanly, but before getting " + " all response header fields, treated as error", + stream->stream_id); + *err = CURLE_HTTP2_STREAM; + return -1; + } + + if(stream->trailer_recvbuf && stream->trailer_recvbuf->buffer) { + trailer_pos = stream->trailer_recvbuf->buffer; + trailer_end = trailer_pos + stream->trailer_recvbuf->size_used; + + for(; trailer_pos < trailer_end;) { + uint32_t n; + memcpy(&n, trailer_pos, sizeof(n)); + trailer_pos += sizeof(n); + + result = Curl_client_write(conn, CLIENTWRITE_HEADER, trailer_pos, n); + if(result) { + *err = result; + return -1; + } + + trailer_pos += n + 1; + } + } + + stream->close_handled = TRUE; + + H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n")); + return 0; +} + +/* + * h2_pri_spec() fills in the pri_spec struct, used by nghttp2 to send weight + * and dependency to the peer. It also stores the updated values in the state + * struct. + */ + +static void h2_pri_spec(struct Curl_easy *data, + nghttp2_priority_spec *pri_spec) +{ + struct HTTP *depstream = (data->set.stream_depends_on? + data->set.stream_depends_on->req.protop:NULL); + int32_t depstream_id = depstream? depstream->stream_id:0; + nghttp2_priority_spec_init(pri_spec, depstream_id, data->set.stream_weight, + data->set.stream_depends_e); + data->state.stream_weight = data->set.stream_weight; + data->state.stream_depends_e = data->set.stream_depends_e; + data->state.stream_depends_on = data->set.stream_depends_on; +} + +/* + * h2_session_send() checks if there's been an update in the priority / + * dependency settings and if so it submits a PRIORITY frame with the updated + * info. + */ +static int h2_session_send(struct Curl_easy *data, + nghttp2_session *h2) +{ + struct HTTP *stream = data->req.protop; + if((data->set.stream_weight != data->state.stream_weight) || + (data->set.stream_depends_e != data->state.stream_depends_e) || + (data->set.stream_depends_on != data->state.stream_depends_on) ) { + /* send new weight and/or dependency */ + nghttp2_priority_spec pri_spec; + int rv; + + h2_pri_spec(data, &pri_spec); + + H2BUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n", + stream->stream_id, data)); + rv = nghttp2_submit_priority(h2, NGHTTP2_FLAG_NONE, stream->stream_id, + &pri_spec); + if(rv) + return rv; + } + + return nghttp2_session_send(h2); +} + +static ssize_t http2_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) +{ + CURLcode result = CURLE_OK; + ssize_t rv; + ssize_t nread; + struct http_conn *httpc = &conn->proto.httpc; + struct Curl_easy *data = conn->data; + struct HTTP *stream = data->req.protop; + + (void)sockindex; /* we always do HTTP2 on sockindex 0 */ + + if(should_close_session(httpc)) { + H2BUGF(infof(data, + "http2_recv: nothing to do in this session\n")); + *err = CURLE_HTTP2; + return -1; + } + + /* Nullify here because we call nghttp2_session_send() and they + might refer to the old buffer. */ + stream->upload_mem = NULL; + stream->upload_len = 0; + + /* + * At this point 'stream' is just in the Curl_easy the connection + * identifies as its owner at this time. + */ + + if(stream->bodystarted && + stream->nread_header_recvbuf < stream->header_recvbuf->size_used) { + /* If there is body data pending for this stream to return, do that */ + size_t left = + stream->header_recvbuf->size_used - stream->nread_header_recvbuf; + size_t ncopy = CURLMIN(len, left); + memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf, + ncopy); + stream->nread_header_recvbuf += ncopy; + + H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n", + (int)ncopy)); + return ncopy; + } + + H2BUGF(infof(data, "http2_recv: easy %p (stream %u)\n", + data, stream->stream_id)); + + if((data->state.drain) && stream->memlen) { + H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n", + stream->memlen, stream->stream_id, + stream->mem, mem)); + if(mem != stream->mem) { + /* if we didn't get the same buffer this time, we must move the data to + the beginning */ + memmove(mem, stream->mem, stream->memlen); + stream->len = len - stream->memlen; + stream->mem = mem; + } + if(httpc->pause_stream_id == stream->stream_id && !stream->pausedata) { + /* We have paused nghttp2, but we have no pause data (see + on_data_chunk_recv). */ + httpc->pause_stream_id = 0; + if(h2_process_pending_input(conn, httpc, &result) != 0) { + *err = result; + return -1; + } + } + } + else if(stream->pausedata) { + DEBUGASSERT(httpc->pause_stream_id == stream->stream_id); + nread = CURLMIN(len, stream->pauselen); + memcpy(mem, stream->pausedata, nread); + + stream->pausedata += nread; + stream->pauselen -= nread; + + infof(data, "%zd data bytes written\n", nread); + if(stream->pauselen == 0) { + H2BUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id)); + DEBUGASSERT(httpc->pause_stream_id == stream->stream_id); + httpc->pause_stream_id = 0; + + stream->pausedata = NULL; + stream->pauselen = 0; + + /* When NGHTTP2_ERR_PAUSE is returned from + data_source_read_callback, we might not process DATA frame + fully. Calling nghttp2_session_mem_recv() again will + continue to process DATA frame, but if there is no incoming + frames, then we have to call it again with 0-length data. + Without this, on_stream_close callback will not be called, + and stream could be hanged. */ + if(h2_process_pending_input(conn, httpc, &result) != 0) { + *err = result; + return -1; + } + } + H2BUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n", + nread, stream->stream_id)); + return nread; + } + else if(httpc->pause_stream_id) { + /* If a stream paused nghttp2_session_mem_recv previously, and has + not processed all data, it still refers to the buffer in + nghttp2_session. If we call nghttp2_session_mem_recv(), we may + overwrite that buffer. To avoid that situation, just return + here with CURLE_AGAIN. This could be busy loop since data in + socket is not read. But it seems that usually streams are + notified with its drain property, and socket is read again + quickly. */ + H2BUGF(infof(data, "stream %x is paused, pause id: %x\n", + stream->stream_id, httpc->pause_stream_id)); + *err = CURLE_AGAIN; + return -1; + } + else { + char *inbuf; + /* remember where to store incoming data for this stream and how big the + buffer is */ + stream->mem = mem; + stream->len = len; + stream->memlen = 0; + + if(httpc->inbuflen == 0) { + nread = ((Curl_recv *)httpc->recv_underlying)( + conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result); + + if(nread == -1) { + if(result != CURLE_AGAIN) + failf(data, "Failed receiving HTTP2 data"); + else if(stream->closed) + /* received when the stream was already closed! */ + return http2_handle_stream_close(conn, data, stream, err); + + *err = result; + return -1; + } + + if(nread == 0) { + H2BUGF(infof(data, "end of stream\n")); + *err = CURLE_OK; + return 0; + } + + H2BUGF(infof(data, "nread=%zd\n", nread)); + + httpc->inbuflen = nread; + inbuf = httpc->inbuf; + } + else { + nread = httpc->inbuflen - httpc->nread_inbuf; + inbuf = httpc->inbuf + httpc->nread_inbuf; + + H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n", + nread)); + } + rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread); + + if(nghttp2_is_fatal((int)rv)) { + failf(data, "nghttp2_session_mem_recv() returned %zd:%s\n", + rv, nghttp2_strerror((int)rv)); + *err = CURLE_RECV_ERROR; + return -1; + } + H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv)); + if(nread == rv) { + H2BUGF(infof(data, "All data in connection buffer processed\n")); + httpc->inbuflen = 0; + httpc->nread_inbuf = 0; + } + else { + httpc->nread_inbuf += rv; + H2BUGF(infof(data, "%zu bytes left in connection buffer\n", + httpc->inbuflen - httpc->nread_inbuf)); + } + /* Always send pending frames in nghttp2 session, because + nghttp2_session_mem_recv() may queue new frame */ + rv = h2_session_send(data, httpc->h2); + if(rv != 0) { + *err = CURLE_SEND_ERROR; + return -1; + } + + if(should_close_session(httpc)) { + H2BUGF(infof(data, "http2_recv: nothing to do in this session\n")); + *err = CURLE_HTTP2; + return -1; + } + } + if(stream->memlen) { + ssize_t retlen = stream->memlen; + H2BUGF(infof(data, "http2_recv: returns %zd for stream %u\n", + retlen, stream->stream_id)); + stream->memlen = 0; + + if(httpc->pause_stream_id == stream->stream_id) { + /* data for this stream is returned now, but this stream caused a pause + already so we need it called again asap */ + H2BUGF(infof(data, "Data returned for PAUSED stream %u\n", + stream->stream_id)); + } + else if(!stream->closed) { + drained_transfer(data, httpc); + } + + return retlen; + } + /* If this stream is closed, return 0 to signal the http routine to close + the connection */ + if(stream->closed) + return 0; + *err = CURLE_AGAIN; + H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u\n", + stream->stream_id)); + return -1; +} + +/* Index where :authority header field will appear in request header + field list. */ +#define AUTHORITY_DST_IDX 3 + +#define HEADER_OVERFLOW(x) \ + (x.namelen > (uint16_t)-1 || x.valuelen > (uint16_t)-1 - x.namelen) + +/* + * Check header memory for the token "trailers". + * Parse the tokens as separated by comma and surrounded by whitespace. + * Returns TRUE if found or FALSE if not. + */ +static bool contains_trailers(const char *p, size_t len) +{ + const char *end = p + len; + for(;;) { + for(; p != end && (*p == ' ' || *p == '\t'); ++p) + ; + if(p == end || (size_t)(end - p) < sizeof("trailers") - 1) + return FALSE; + if(strncasecompare("trailers", p, sizeof("trailers") - 1)) { + p += sizeof("trailers") - 1; + for(; p != end && (*p == ' ' || *p == '\t'); ++p) + ; + if(p == end || *p == ',') + return TRUE; + } + /* skip to next token */ + for(; p != end && *p != ','; ++p) + ; + if(p == end) + return FALSE; + ++p; + } +} + +typedef enum { + /* Send header to server */ + HEADERINST_FORWARD, + /* Don't send header to server */ + HEADERINST_IGNORE, + /* Discard header, and replace it with "te: trailers" */ + HEADERINST_TE_TRAILERS +} header_instruction; + +/* Decides how to treat given header field. */ +static header_instruction inspect_header(const char *name, size_t namelen, + const char *value, size_t valuelen) { + switch(namelen) { + case 2: + if(!strncasecompare("te", name, namelen)) + return HEADERINST_FORWARD; + + return contains_trailers(value, valuelen) ? + HEADERINST_TE_TRAILERS : HEADERINST_IGNORE; + case 7: + return strncasecompare("upgrade", name, namelen) ? + HEADERINST_IGNORE : HEADERINST_FORWARD; + case 10: + return (strncasecompare("connection", name, namelen) || + strncasecompare("keep-alive", name, namelen)) ? + HEADERINST_IGNORE : HEADERINST_FORWARD; + case 16: + return strncasecompare("proxy-connection", name, namelen) ? + HEADERINST_IGNORE : HEADERINST_FORWARD; + case 17: + return strncasecompare("transfer-encoding", name, namelen) ? + HEADERINST_IGNORE : HEADERINST_FORWARD; + default: + return HEADERINST_FORWARD; + } +} + +static ssize_t http2_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) +{ + /* + * Currently, we send request in this function, but this function is also + * used to send request body. It would be nice to add dedicated function for + * request. + */ + int rv; + struct http_conn *httpc = &conn->proto.httpc; + struct HTTP *stream = conn->data->req.protop; + nghttp2_nv *nva = NULL; + size_t nheader; + size_t i; + size_t authority_idx; + char *hdbuf = (char *)mem; + char *end, *line_end; + nghttp2_data_provider data_prd; + int32_t stream_id; + nghttp2_session *h2 = httpc->h2; + nghttp2_priority_spec pri_spec; + + (void)sockindex; + + H2BUGF(infof(conn->data, "http2_send len=%zu\n", len)); + + if(stream->stream_id != -1) { + if(stream->close_handled) { + infof(conn->data, "stream %d closed\n", stream->stream_id); + *err = CURLE_HTTP2_STREAM; + return -1; + } + else if(stream->closed) { + return http2_handle_stream_close(conn, conn->data, stream, err); + } + /* If stream_id != -1, we have dispatched request HEADERS, and now + are going to send or sending request body in DATA frame */ + stream->upload_mem = mem; + stream->upload_len = len; + rv = nghttp2_session_resume_data(h2, stream->stream_id); + if(nghttp2_is_fatal(rv)) { + *err = CURLE_SEND_ERROR; + return -1; + } + rv = h2_session_send(conn->data, h2); + if(nghttp2_is_fatal(rv)) { + *err = CURLE_SEND_ERROR; + return -1; + } + len -= stream->upload_len; + + /* Nullify here because we call nghttp2_session_send() and they + might refer to the old buffer. */ + stream->upload_mem = NULL; + stream->upload_len = 0; + + if(should_close_session(httpc)) { + H2BUGF(infof(conn->data, "http2_send: nothing to do in this session\n")); + *err = CURLE_HTTP2; + return -1; + } + + if(stream->upload_left) { + /* we are sure that we have more data to send here. Calling the + following API will make nghttp2_session_want_write() return + nonzero if remote window allows it, which then libcurl checks + socket is writable or not. See http2_perform_getsock(). */ + nghttp2_session_resume_data(h2, stream->stream_id); + } + + H2BUGF(infof(conn->data, "http2_send returns %zu for stream %u\n", len, + stream->stream_id)); + return len; + } + + /* Calculate number of headers contained in [mem, mem + len) */ + /* Here, we assume the curl http code generate *correct* HTTP header + field block */ + nheader = 0; + for(i = 1; i < len; ++i) { + if(hdbuf[i] == '\n' && hdbuf[i - 1] == '\r') { + ++nheader; + ++i; + } + } + if(nheader < 2) + goto fail; + + /* We counted additional 2 \r\n in the first and last line. We need 3 + new headers: :method, :path and :scheme. Therefore we need one + more space. */ + nheader += 1; + nva = malloc(sizeof(nghttp2_nv) * nheader); + if(nva == NULL) { + *err = CURLE_OUT_OF_MEMORY; + return -1; + } + + /* Extract :method, :path from request line + We do line endings with CRLF so checking for CR is enough */ + line_end = memchr(hdbuf, '\r', len); + if(!line_end) + goto fail; + + /* Method does not contain spaces */ + end = memchr(hdbuf, ' ', line_end - hdbuf); + if(!end || end == hdbuf) + goto fail; + nva[0].name = (unsigned char *)":method"; + nva[0].namelen = strlen((char *)nva[0].name); + nva[0].value = (unsigned char *)hdbuf; + nva[0].valuelen = (size_t)(end - hdbuf); + nva[0].flags = NGHTTP2_NV_FLAG_NONE; + if(HEADER_OVERFLOW(nva[0])) { + failf(conn->data, "Failed sending HTTP request: Header overflow"); + goto fail; + } + + hdbuf = end + 1; + + /* Path may contain spaces so scan backwards */ + end = NULL; + for(i = (size_t)(line_end - hdbuf); i; --i) { + if(hdbuf[i - 1] == ' ') { + end = &hdbuf[i - 1]; + break; + } + } + if(!end || end == hdbuf) + goto fail; + nva[1].name = (unsigned char *)":path"; + nva[1].namelen = strlen((char *)nva[1].name); + nva[1].value = (unsigned char *)hdbuf; + nva[1].valuelen = (size_t)(end - hdbuf); + nva[1].flags = NGHTTP2_NV_FLAG_NONE; + if(HEADER_OVERFLOW(nva[1])) { + failf(conn->data, "Failed sending HTTP request: Header overflow"); + goto fail; + } + + nva[2].name = (unsigned char *)":scheme"; + nva[2].namelen = strlen((char *)nva[2].name); + if(conn->handler->flags & PROTOPT_SSL) + nva[2].value = (unsigned char *)"https"; + else + nva[2].value = (unsigned char *)"http"; + nva[2].valuelen = strlen((char *)nva[2].value); + nva[2].flags = NGHTTP2_NV_FLAG_NONE; + if(HEADER_OVERFLOW(nva[2])) { + failf(conn->data, "Failed sending HTTP request: Header overflow"); + goto fail; + } + + authority_idx = 0; + i = 3; + while(i < nheader) { + size_t hlen; + + hdbuf = line_end + 2; + + /* check for next CR, but only within the piece of data left in the given + buffer */ + line_end = memchr(hdbuf, '\r', len - (hdbuf - (char *)mem)); + if(!line_end || (line_end == hdbuf)) + goto fail; + + /* header continuation lines are not supported */ + if(*hdbuf == ' ' || *hdbuf == '\t') + goto fail; + + for(end = hdbuf; end < line_end && *end != ':'; ++end) + ; + if(end == hdbuf || end == line_end) + goto fail; + hlen = end - hdbuf; + + if(hlen == 4 && strncasecompare("host", hdbuf, 4)) { + authority_idx = i; + nva[i].name = (unsigned char *)":authority"; + nva[i].namelen = strlen((char *)nva[i].name); + } + else { + nva[i].name = (unsigned char *)hdbuf; + nva[i].namelen = (size_t)(end - hdbuf); + } + hdbuf = end + 1; + while(*hdbuf == ' ' || *hdbuf == '\t') + ++hdbuf; + end = line_end; + + switch(inspect_header((const char *)nva[i].name, nva[i].namelen, hdbuf, + end - hdbuf)) { + case HEADERINST_IGNORE: + /* skip header fields prohibited by HTTP/2 specification. */ + --nheader; + continue; + case HEADERINST_TE_TRAILERS: + nva[i].value = (uint8_t*)"trailers"; + nva[i].valuelen = sizeof("trailers") - 1; + break; + default: + nva[i].value = (unsigned char *)hdbuf; + nva[i].valuelen = (size_t)(end - hdbuf); + } + + nva[i].flags = NGHTTP2_NV_FLAG_NONE; + if(HEADER_OVERFLOW(nva[i])) { + failf(conn->data, "Failed sending HTTP request: Header overflow"); + goto fail; + } + ++i; + } + + /* :authority must come before non-pseudo header fields */ + if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) { + nghttp2_nv authority = nva[authority_idx]; + for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) { + nva[i] = nva[i - 1]; + } + nva[i] = authority; + } + + /* Warn stream may be rejected if cumulative length of headers is too large. + It appears nghttp2 will not send a header frame larger than 64KB. */ +#define MAX_ACC 60000 /* <64KB to account for some overhead */ + { + size_t acc = 0; + + for(i = 0; i < nheader; ++i) { + acc += nva[i].namelen + nva[i].valuelen; + + H2BUGF(infof(conn->data, "h2 header: %.*s:%.*s\n", + nva[i].namelen, nva[i].name, + nva[i].valuelen, nva[i].value)); + } + + if(acc > MAX_ACC) { + infof(conn->data, "http2_send: Warning: The cumulative length of all " + "headers exceeds %zu bytes and that could cause the " + "stream to be rejected.\n", MAX_ACC); + } + } + + h2_pri_spec(conn->data, &pri_spec); + + switch(conn->data->set.httpreq) { + case HTTPREQ_POST: + case HTTPREQ_POST_FORM: + case HTTPREQ_POST_MIME: + case HTTPREQ_PUT: + if(conn->data->state.infilesize != -1) + stream->upload_left = conn->data->state.infilesize; + else + /* data sending without specifying the data amount up front */ + stream->upload_left = -1; /* unknown, but not zero */ + + data_prd.read_callback = data_source_read_callback; + data_prd.source.ptr = NULL; + stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader, + &data_prd, conn->data); + break; + default: + stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader, + NULL, conn->data); + } + + Curl_safefree(nva); + + if(stream_id < 0) { + H2BUGF(infof(conn->data, "http2_send() send error\n")); + *err = CURLE_SEND_ERROR; + return -1; + } + + infof(conn->data, "Using Stream ID: %x (easy handle %p)\n", + stream_id, (void *)conn->data); + stream->stream_id = stream_id; + + /* this does not call h2_session_send() since there can not have been any + * priority upodate since the nghttp2_submit_request() call above */ + rv = nghttp2_session_send(h2); + + if(rv != 0) { + *err = CURLE_SEND_ERROR; + return -1; + } + + if(should_close_session(httpc)) { + H2BUGF(infof(conn->data, "http2_send: nothing to do in this session\n")); + *err = CURLE_HTTP2; + return -1; + } + + if(stream->stream_id != -1) { + /* If whole HEADERS frame was sent off to the underlying socket, + the nghttp2 library calls data_source_read_callback. But only + it found that no data available, so it deferred the DATA + transmission. Which means that nghttp2_session_want_write() + returns 0 on http2_perform_getsock(), which results that no + writable socket check is performed. To workaround this, we + issue nghttp2_session_resume_data() here to bring back DATA + transmission from deferred state. */ + nghttp2_session_resume_data(h2, stream->stream_id); + } + + return len; + +fail: + free(nva); + *err = CURLE_SEND_ERROR; + return -1; +} + +CURLcode Curl_http2_setup(struct connectdata *conn) +{ + CURLcode result; + struct http_conn *httpc = &conn->proto.httpc; + struct HTTP *stream = conn->data->req.protop; + + stream->stream_id = -1; + + if(!stream->header_recvbuf) { + stream->header_recvbuf = Curl_add_buffer_init(); + if(!stream->header_recvbuf) + return CURLE_OUT_OF_MEMORY; + } + + if((conn->handler == &Curl_handler_http2_ssl) || + (conn->handler == &Curl_handler_http2)) + return CURLE_OK; /* already done */ + + if(conn->handler->flags & PROTOPT_SSL) + conn->handler = &Curl_handler_http2_ssl; + else + conn->handler = &Curl_handler_http2; + + result = http2_init(conn); + if(result) { + Curl_add_buffer_free(&stream->header_recvbuf); + return result; + } + + infof(conn->data, "Using HTTP2, server supports multi-use\n"); + stream->upload_left = 0; + stream->upload_mem = NULL; + stream->upload_len = 0; + + httpc->inbuflen = 0; + httpc->nread_inbuf = 0; + + httpc->pause_stream_id = 0; + httpc->drain_total = 0; + + conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ + conn->httpversion = 20; + conn->bundle->multiuse = BUNDLE_MULTIPLEX; + + infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n"); + multi_connchanged(conn->data->multi); + + return CURLE_OK; +} + +CURLcode Curl_http2_switched(struct connectdata *conn, + const char *mem, size_t nread) +{ + CURLcode result; + struct http_conn *httpc = &conn->proto.httpc; + int rv; + ssize_t nproc; + struct Curl_easy *data = conn->data; + struct HTTP *stream = conn->data->req.protop; + + result = Curl_http2_setup(conn); + if(result) + return result; + + httpc->recv_underlying = conn->recv[FIRSTSOCKET]; + httpc->send_underlying = conn->send[FIRSTSOCKET]; + conn->recv[FIRSTSOCKET] = http2_recv; + conn->send[FIRSTSOCKET] = http2_send; + + if(conn->data->req.upgr101 == UPGR101_RECEIVED) { + /* stream 1 is opened implicitly on upgrade */ + stream->stream_id = 1; + /* queue SETTINGS frame (again) */ + rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings, + httpc->binlen, NULL); + if(rv != 0) { + failf(data, "nghttp2_session_upgrade() failed: %s(%d)", + nghttp2_strerror(rv), rv); + return CURLE_HTTP2; + } + + rv = nghttp2_session_set_stream_user_data(httpc->h2, + stream->stream_id, + data); + if(rv) { + infof(data, "http/2: failed to set user_data for stream %d!\n", + stream->stream_id); + DEBUGASSERT(0); + } + } + else { + populate_settings(conn, httpc); + + /* stream ID is unknown at this point */ + stream->stream_id = -1; + rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, + httpc->local_settings, + httpc->local_settings_num); + if(rv != 0) { + failf(data, "nghttp2_submit_settings() failed: %s(%d)", + nghttp2_strerror(rv), rv); + return CURLE_HTTP2; + } + } + +#ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE + rv = nghttp2_session_set_local_window_size(httpc->h2, NGHTTP2_FLAG_NONE, 0, + HTTP2_HUGE_WINDOW_SIZE); + if(rv != 0) { + failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)", + nghttp2_strerror(rv), rv); + return CURLE_HTTP2; + } +#endif + + /* we are going to copy mem to httpc->inbuf. This is required since + mem is part of buffer pointed by stream->mem, and callbacks + called by nghttp2_session_mem_recv() will write stream specific + data into stream->mem, overwriting data already there. */ + if(H2_BUFSIZE < nread) { + failf(data, "connection buffer size is too small to store data following " + "HTTP Upgrade response header: buflen=%zu, datalen=%zu", + H2_BUFSIZE, nread); + return CURLE_HTTP2; + } + + infof(conn->data, "Copying HTTP/2 data in stream buffer to connection buffer" + " after upgrade: len=%zu\n", + nread); + + if(nread) + memcpy(httpc->inbuf, mem, nread); + httpc->inbuflen = nread; + + nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf, + httpc->inbuflen); + + if(nghttp2_is_fatal((int)nproc)) { + failf(data, "nghttp2_session_mem_recv() failed: %s(%d)", + nghttp2_strerror((int)nproc), (int)nproc); + return CURLE_HTTP2; + } + + H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc)); + + if((ssize_t)nread == nproc) { + httpc->inbuflen = 0; + httpc->nread_inbuf = 0; + } + else { + httpc->nread_inbuf += nproc; + } + + /* Try to send some frames since we may read SETTINGS already. */ + rv = h2_session_send(data, httpc->h2); + + if(rv != 0) { + failf(data, "nghttp2_session_send() failed: %s(%d)", + nghttp2_strerror(rv), rv); + return CURLE_HTTP2; + } + + if(should_close_session(httpc)) { + H2BUGF(infof(data, + "nghttp2_session_send(): nothing to do in this session\n")); + return CURLE_HTTP2; + } + + return CURLE_OK; +} + +CURLcode Curl_http2_add_child(struct Curl_easy *parent, + struct Curl_easy *child, + bool exclusive) +{ + if(parent) { + struct Curl_http2_dep **tail; + struct Curl_http2_dep *dep = calloc(1, sizeof(struct Curl_http2_dep)); + if(!dep) + return CURLE_OUT_OF_MEMORY; + dep->data = child; + + if(parent->set.stream_dependents && exclusive) { + struct Curl_http2_dep *node = parent->set.stream_dependents; + while(node) { + node->data->set.stream_depends_on = child; + node = node->next; + } + + tail = &child->set.stream_dependents; + while(*tail) + tail = &(*tail)->next; + + DEBUGASSERT(!*tail); + *tail = parent->set.stream_dependents; + parent->set.stream_dependents = 0; + } + + tail = &parent->set.stream_dependents; + while(*tail) { + (*tail)->data->set.stream_depends_e = FALSE; + tail = &(*tail)->next; + } + + DEBUGASSERT(!*tail); + *tail = dep; + } + + child->set.stream_depends_on = parent; + child->set.stream_depends_e = exclusive; + return CURLE_OK; +} + +void Curl_http2_remove_child(struct Curl_easy *parent, struct Curl_easy *child) +{ + struct Curl_http2_dep *last = 0; + struct Curl_http2_dep *data = parent->set.stream_dependents; + DEBUGASSERT(child->set.stream_depends_on == parent); + + while(data && data->data != child) { + last = data; + data = data->next; + } + + DEBUGASSERT(data); + + if(data) { + if(last) { + last->next = data->next; + } + else { + parent->set.stream_dependents = data->next; + } + free(data); + } + + child->set.stream_depends_on = 0; + child->set.stream_depends_e = FALSE; +} + +void Curl_http2_cleanup_dependencies(struct Curl_easy *data) +{ + while(data->set.stream_dependents) { + struct Curl_easy *tmp = data->set.stream_dependents->data; + Curl_http2_remove_child(data, tmp); + if(data->set.stream_depends_on) + Curl_http2_add_child(data->set.stream_depends_on, tmp, FALSE); + } + + if(data->set.stream_depends_on) + Curl_http2_remove_child(data->set.stream_depends_on, data); +} + +/* Only call this function for a transfer that already got a HTTP/2 + CURLE_HTTP2_STREAM error! */ +bool Curl_h2_http_1_1_error(struct connectdata *conn) +{ + struct http_conn *httpc = &conn->proto.httpc; + return (httpc->error_code == NGHTTP2_HTTP_1_1_REQUIRED); +} + +#else /* !USE_NGHTTP2 */ + +/* Satisfy external references even if http2 is not compiled in. */ +#include + +char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num) +{ + (void) h; + (void) num; + return NULL; +} + +char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header) +{ + (void) h; + (void) header; + return NULL; +} + +#endif /* USE_NGHTTP2 */ diff --git a/libcurl/lib/http2.h b/libcurl/lib/http2.h new file mode 100644 index 0000000..93058cc --- /dev/null +++ b/libcurl/lib/http2.h @@ -0,0 +1,80 @@ +#ifndef HEADER_CURL_HTTP2_H +#define HEADER_CURL_HTTP2_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_NGHTTP2 +#include "http.h" + +/* value for MAX_CONCURRENT_STREAMS we use until we get an updated setting + from the peer */ +#define DEFAULT_MAX_CONCURRENT_STREAMS 13 + +/* + * Store nghttp2 version info in this buffer, Prefix with a space. Return + * total length written. + */ +int Curl_http2_ver(char *p, size_t len); + +const char *Curl_http2_strerror(uint32_t err); + +CURLcode Curl_http2_init(struct connectdata *conn); +void Curl_http2_init_state(struct UrlState *state); +void Curl_http2_init_userset(struct UserDefined *set); +CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req, + struct connectdata *conn); +CURLcode Curl_http2_setup(struct connectdata *conn); +CURLcode Curl_http2_switched(struct connectdata *conn, + const char *data, size_t nread); +/* called from http_setup_conn */ +void Curl_http2_setup_conn(struct connectdata *conn); +void Curl_http2_setup_req(struct Curl_easy *data); +void Curl_http2_done(struct connectdata *conn, bool premature); +CURLcode Curl_http2_done_sending(struct connectdata *conn); +CURLcode Curl_http2_add_child(struct Curl_easy *parent, + struct Curl_easy *child, + bool exclusive); +void Curl_http2_remove_child(struct Curl_easy *parent, + struct Curl_easy *child); +void Curl_http2_cleanup_dependencies(struct Curl_easy *data); + +/* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */ +bool Curl_h2_http_1_1_error(struct connectdata *conn); +#else /* USE_NGHTTP2 */ +#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL +#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL +#define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL +#define Curl_http2_setup_conn(x) Curl_nop_stmt +#define Curl_http2_setup_req(x) +#define Curl_http2_init_state(x) +#define Curl_http2_init_userset(x) +#define Curl_http2_done(x,y) +#define Curl_http2_done_sending(x) +#define Curl_http2_add_child(x, y, z) +#define Curl_http2_remove_child(x, y) +#define Curl_http2_cleanup_dependencies(x) +#define Curl_h2_http_1_1_error(x) 0 +#endif + +#endif /* HEADER_CURL_HTTP2_H */ diff --git a/libcurl/lib/http_chunks.c b/libcurl/lib/http_chunks.c new file mode 100644 index 0000000..18dfcb2 --- /dev/null +++ b/libcurl/lib/http_chunks.c @@ -0,0 +1,351 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_HTTP + +#include "urldata.h" /* it includes http_chunks.h */ +#include "sendf.h" /* for the client write stuff */ + +#include "content_encoding.h" +#include "http.h" +#include "non-ascii.h" /* for Curl_convert_to_network prototype */ +#include "strtoofft.h" +#include "warnless.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Chunk format (simplified): + * + * [ chunk extension ] CRLF + * CRLF + * + * Highlights from RFC2616 section 3.6 say: + + The chunked encoding modifies the body of a message in order to + transfer it as a series of chunks, each with its own size indicator, + followed by an OPTIONAL trailer containing entity-header fields. This + allows dynamically produced content to be transferred along with the + information necessary for the recipient to verify that it has + received the full message. + + Chunked-Body = *chunk + last-chunk + trailer + CRLF + + chunk = chunk-size [ chunk-extension ] CRLF + chunk-data CRLF + chunk-size = 1*HEX + last-chunk = 1*("0") [ chunk-extension ] CRLF + + chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) + chunk-ext-name = token + chunk-ext-val = token | quoted-string + chunk-data = chunk-size(OCTET) + trailer = *(entity-header CRLF) + + The chunk-size field is a string of hex digits indicating the size of + the chunk. The chunked encoding is ended by any chunk whose size is + zero, followed by the trailer, which is terminated by an empty line. + + */ + +#ifdef CURL_DOES_CONVERSIONS +/* Check for an ASCII hex digit. + We avoid the use of ISXDIGIT to accommodate non-ASCII hosts. */ +static bool Curl_isxdigit_ascii(char digit) +{ + return (digit >= 0x30 && digit <= 0x39) /* 0-9 */ + || (digit >= 0x41 && digit <= 0x46) /* A-F */ + || (digit >= 0x61 && digit <= 0x66); /* a-f */ +} +#else +#define Curl_isxdigit_ascii(x) Curl_isxdigit(x) +#endif + +void Curl_httpchunk_init(struct connectdata *conn) +{ + struct Curl_chunker *chunk = &conn->chunk; + chunk->hexindex = 0; /* start at 0 */ + chunk->dataleft = 0; /* no data left yet! */ + chunk->state = CHUNK_HEX; /* we get hex first! */ +} + +/* + * chunk_read() returns a OK for normal operations, or a positive return code + * for errors. STOP means this sequence of chunks is complete. The 'wrote' + * argument is set to tell the caller how many bytes we actually passed to the + * client (for byte-counting and whatever). + * + * The states and the state-machine is further explained in the header file. + * + * This function always uses ASCII hex values to accommodate non-ASCII hosts. + * For example, 0x0d and 0x0a are used instead of '\r' and '\n'. + */ +CHUNKcode Curl_httpchunk_read(struct connectdata *conn, + char *datap, + ssize_t datalen, + ssize_t *wrotep) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct Curl_chunker *ch = &conn->chunk; + struct SingleRequest *k = &data->req; + size_t piece; + curl_off_t length = (curl_off_t)datalen; + size_t *wrote = (size_t *)wrotep; + + *wrote = 0; /* nothing's written yet */ + + /* the original data is written to the client, but we go on with the + chunk read process, to properly calculate the content length*/ + if(data->set.http_te_skip && !k->ignorebody) { + result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, datalen); + if(result) + return CHUNKE_WRITE_ERROR; + } + + while(length) { + switch(ch->state) { + case CHUNK_HEX: + if(Curl_isxdigit_ascii(*datap)) { + if(ch->hexindex < MAXNUM_SIZE) { + ch->hexbuffer[ch->hexindex] = *datap; + datap++; + length--; + ch->hexindex++; + } + else { + return CHUNKE_TOO_LONG_HEX; /* longer hex than we support */ + } + } + else { + char *endptr; + if(0 == ch->hexindex) + /* This is illegal data, we received junk where we expected + a hexadecimal digit. */ + return CHUNKE_ILLEGAL_HEX; + + /* length and datap are unmodified */ + ch->hexbuffer[ch->hexindex] = 0; + + /* convert to host encoding before calling strtoul */ + result = Curl_convert_from_network(conn->data, ch->hexbuffer, + ch->hexindex); + if(result) { + /* Curl_convert_from_network calls failf if unsuccessful */ + /* Treat it as a bad hex character */ + return CHUNKE_ILLEGAL_HEX; + } + + if(curlx_strtoofft(ch->hexbuffer, &endptr, 16, &ch->datasize)) + return CHUNKE_ILLEGAL_HEX; + ch->state = CHUNK_LF; /* now wait for the CRLF */ + } + break; + + case CHUNK_LF: + /* waiting for the LF after a chunk size */ + if(*datap == 0x0a) { + /* we're now expecting data to come, unless size was zero! */ + if(0 == ch->datasize) { + ch->state = CHUNK_TRAILER; /* now check for trailers */ + conn->trlPos = 0; + } + else + ch->state = CHUNK_DATA; + } + + datap++; + length--; + break; + + case CHUNK_DATA: + /* We expect 'datasize' of data. We have 'length' right now, it can be + more or less than 'datasize'. Get the smallest piece. + */ + piece = curlx_sotouz((ch->datasize >= length)?length:ch->datasize); + + /* Write the data portion available */ + if(!conn->data->set.http_te_skip && !k->ignorebody) { + if(!conn->data->set.http_ce_skip && k->writer_stack) + result = Curl_unencode_write(conn, k->writer_stack, datap, piece); + else + result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, piece); + + if(result) + return CHUNKE_WRITE_ERROR; + } + + *wrote += piece; + ch->datasize -= piece; /* decrease amount left to expect */ + datap += piece; /* move read pointer forward */ + length -= piece; /* decrease space left in this round */ + + if(0 == ch->datasize) + /* end of data this round, we now expect a trailing CRLF */ + ch->state = CHUNK_POSTLF; + break; + + case CHUNK_POSTLF: + if(*datap == 0x0a) { + /* The last one before we go back to hex state and start all over. */ + Curl_httpchunk_init(conn); /* sets state back to CHUNK_HEX */ + } + else if(*datap != 0x0d) + return CHUNKE_BAD_CHUNK; + datap++; + length--; + break; + + case CHUNK_TRAILER: + if((*datap == 0x0d) || (*datap == 0x0a)) { + /* this is the end of a trailer, but if the trailer was zero bytes + there was no trailer and we move on */ + + if(conn->trlPos) { + /* we allocate trailer with 3 bytes extra room to fit this */ + conn->trailer[conn->trlPos++] = 0x0d; + conn->trailer[conn->trlPos++] = 0x0a; + conn->trailer[conn->trlPos] = 0; + + /* Convert to host encoding before calling Curl_client_write */ + result = Curl_convert_from_network(conn->data, conn->trailer, + conn->trlPos); + if(result) + /* Curl_convert_from_network calls failf if unsuccessful */ + /* Treat it as a bad chunk */ + return CHUNKE_BAD_CHUNK; + + if(!data->set.http_te_skip) { + result = Curl_client_write(conn, CLIENTWRITE_HEADER, + conn->trailer, conn->trlPos); + if(result) + return CHUNKE_WRITE_ERROR; + } + conn->trlPos = 0; + ch->state = CHUNK_TRAILER_CR; + if(*datap == 0x0a) + /* already on the LF */ + break; + } + else { + /* no trailer, we're on the final CRLF pair */ + ch->state = CHUNK_TRAILER_POSTCR; + break; /* don't advance the pointer */ + } + } + else { + /* conn->trailer is assumed to be freed in url.c on a + connection basis */ + if(conn->trlPos >= conn->trlMax) { + /* we always allocate three extra bytes, just because when the full + header has been received we append CRLF\0 */ + char *ptr; + if(conn->trlMax) { + conn->trlMax *= 2; + ptr = realloc(conn->trailer, conn->trlMax + 3); + } + else { + conn->trlMax = 128; + ptr = malloc(conn->trlMax + 3); + } + if(!ptr) + return CHUNKE_OUT_OF_MEMORY; + conn->trailer = ptr; + } + conn->trailer[conn->trlPos++]=*datap; + } + datap++; + length--; + break; + + case CHUNK_TRAILER_CR: + if(*datap == 0x0a) { + ch->state = CHUNK_TRAILER_POSTCR; + datap++; + length--; + } + else + return CHUNKE_BAD_CHUNK; + break; + + case CHUNK_TRAILER_POSTCR: + /* We enter this state when a CR should arrive so we expect to + have to first pass a CR before we wait for LF */ + if((*datap != 0x0d) && (*datap != 0x0a)) { + /* not a CR then it must be another header in the trailer */ + ch->state = CHUNK_TRAILER; + break; + } + if(*datap == 0x0d) { + /* skip if CR */ + datap++; + length--; + } + /* now wait for the final LF */ + ch->state = CHUNK_STOP; + break; + + case CHUNK_STOP: + if(*datap == 0x0a) { + length--; + + /* Record the length of any data left in the end of the buffer + even if there's no more chunks to read */ + ch->dataleft = curlx_sotouz(length); + + return CHUNKE_STOP; /* return stop */ + } + else + return CHUNKE_BAD_CHUNK; + } + } + return CHUNKE_OK; +} + +const char *Curl_chunked_strerror(CHUNKcode code) +{ + switch(code) { + default: + return "OK"; + case CHUNKE_TOO_LONG_HEX: + return "Too long hexadecimal number"; + case CHUNKE_ILLEGAL_HEX: + return "Illegal or missing hexadecimal sequence"; + case CHUNKE_BAD_CHUNK: + return "Malformed encoding found"; + case CHUNKE_WRITE_ERROR: + return "Write error"; + case CHUNKE_BAD_ENCODING: + return "Bad content-encoding found"; + case CHUNKE_OUT_OF_MEMORY: + return "Out of memory"; + } +} + +#endif /* CURL_DISABLE_HTTP */ diff --git a/libcurl/lib/http_chunks.h b/libcurl/lib/http_chunks.h new file mode 100644 index 0000000..b969c55 --- /dev/null +++ b/libcurl/lib/http_chunks.h @@ -0,0 +1,90 @@ +#ifndef HEADER_CURL_HTTP_CHUNKS_H +#define HEADER_CURL_HTTP_CHUNKS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + * The longest possible hexadecimal number we support in a chunked transfer. + * Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul() + * to convert it, we "only" support 2^32 bytes chunk data. + */ +#define MAXNUM_SIZE 16 + +typedef enum { + /* await and buffer all hexadecimal digits until we get one that isn't a + hexadecimal digit. When done, we go CHUNK_LF */ + CHUNK_HEX, + + /* wait for LF, ignore all else */ + CHUNK_LF, + + /* We eat the amount of data specified. When done, we move on to the + POST_CR state. */ + CHUNK_DATA, + + /* POSTLF should get a CR and then a LF and nothing else, then move back to + HEX as the CRLF combination marks the end of a chunk. A missing CR is no + big deal. */ + CHUNK_POSTLF, + + /* Used to mark that we're out of the game. NOTE: that there's a 'dataleft' + field in the struct that will tell how many bytes that were not passed to + the client in the end of the last buffer! */ + CHUNK_STOP, + + /* At this point optional trailer headers can be found, unless the next line + is CRLF */ + CHUNK_TRAILER, + + /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR. + Next char must be a LF */ + CHUNK_TRAILER_CR, + + /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be + signalled If this is an empty trailer CHUNKE_STOP will be signalled. + Otherwise the trailer will be broadcasted via Curl_client_write() and the + next state will be CHUNK_TRAILER */ + CHUNK_TRAILER_POSTCR +} ChunkyState; + +typedef enum { + CHUNKE_STOP = -1, + CHUNKE_OK = 0, + CHUNKE_TOO_LONG_HEX = 1, + CHUNKE_ILLEGAL_HEX, + CHUNKE_BAD_CHUNK, + CHUNKE_WRITE_ERROR, + CHUNKE_BAD_ENCODING, + CHUNKE_OUT_OF_MEMORY, + CHUNKE_LAST +} CHUNKcode; + +const char *Curl_chunked_strerror(CHUNKcode code); + +struct Curl_chunker { + char hexbuffer[ MAXNUM_SIZE + 1]; + int hexindex; + ChunkyState state; + curl_off_t datasize; + size_t dataleft; /* untouched data amount at the end of the last buffer */ +}; + +#endif /* HEADER_CURL_HTTP_CHUNKS_H */ diff --git a/libcurl/lib/http_digest.c b/libcurl/lib/http_digest.c new file mode 100644 index 0000000..9616c30 --- /dev/null +++ b/libcurl/lib/http_digest.c @@ -0,0 +1,181 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) + +#include "urldata.h" +#include "strcase.h" +#include "vauth/vauth.h" +#include "http_digest.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* Test example headers: + +WWW-Authenticate: Digest realm="testrealm", nonce="1053604598" +Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598" + +*/ + +CURLcode Curl_input_digest(struct connectdata *conn, + bool proxy, + const char *header) /* rest of the *-authenticate: + header */ +{ + struct Curl_easy *data = conn->data; + + /* Point to the correct struct with this */ + struct digestdata *digest; + + if(proxy) { + digest = &data->state.proxydigest; + } + else { + digest = &data->state.digest; + } + + if(!checkprefix("Digest", header)) + return CURLE_BAD_CONTENT_ENCODING; + + header += strlen("Digest"); + while(*header && ISSPACE(*header)) + header++; + + return Curl_auth_decode_digest_http_message(header, digest); +} + +CURLcode Curl_output_digest(struct connectdata *conn, + bool proxy, + const unsigned char *request, + const unsigned char *uripath) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + unsigned char *path = NULL; + char *tmp = NULL; + char *response; + size_t len; + bool have_chlg; + + /* Point to the address of the pointer that holds the string to send to the + server, which is for a plain host or for a HTTP proxy */ + char **allocuserpwd; + + /* Point to the name and password for this */ + const char *userp; + const char *passwdp; + + /* Point to the correct struct with this */ + struct digestdata *digest; + struct auth *authp; + + if(proxy) { + digest = &data->state.proxydigest; + allocuserpwd = &conn->allocptr.proxyuserpwd; + userp = conn->http_proxy.user; + passwdp = conn->http_proxy.passwd; + authp = &data->state.authproxy; + } + else { + digest = &data->state.digest; + allocuserpwd = &conn->allocptr.userpwd; + userp = conn->user; + passwdp = conn->passwd; + authp = &data->state.authhost; + } + + Curl_safefree(*allocuserpwd); + + /* not set means empty */ + if(!userp) + userp = ""; + + if(!passwdp) + passwdp = ""; + +#if defined(USE_WINDOWS_SSPI) + have_chlg = digest->input_token ? TRUE : FALSE; +#else + have_chlg = digest->nonce ? TRUE : FALSE; +#endif + + if(!have_chlg) { + authp->done = FALSE; + return CURLE_OK; + } + + /* So IE browsers < v7 cut off the URI part at the query part when they + evaluate the MD5 and some (IIS?) servers work with them so we may need to + do the Digest IE-style. Note that the different ways cause different MD5 + sums to get sent. + + Apache servers can be set to do the Digest IE-style automatically using + the BrowserMatch feature: + https://httpd.apache.org/docs/2.2/mod/mod_auth_digest.html#msie + + Further details on Digest implementation differences: + http://www.fngtps.com/2006/09/http-authentication + */ + + if(authp->iestyle) { + tmp = strchr((char *)uripath, '?'); + if(tmp) { + size_t urilen = tmp - (char *)uripath; + path = (unsigned char *) aprintf("%.*s", urilen, uripath); + } + } + if(!tmp) + path = (unsigned char *) strdup((char *) uripath); + + if(!path) + return CURLE_OUT_OF_MEMORY; + + result = Curl_auth_create_digest_http_message(data, userp, passwdp, request, + path, digest, &response, &len); + free(path); + if(result) + return result; + + *allocuserpwd = aprintf("%sAuthorization: Digest %s\r\n", + proxy ? "Proxy-" : "", + response); + free(response); + if(!*allocuserpwd) + return CURLE_OUT_OF_MEMORY; + + authp->done = TRUE; + + return CURLE_OK; +} + +void Curl_http_auth_cleanup_digest(struct Curl_easy *data) +{ + Curl_auth_digest_cleanup(&data->state.digest); + Curl_auth_digest_cleanup(&data->state.proxydigest); +} + +#endif diff --git a/libcurl/lib/http_digest.h b/libcurl/lib/http_digest.h new file mode 100644 index 0000000..73410ae --- /dev/null +++ b/libcurl/lib/http_digest.h @@ -0,0 +1,42 @@ +#ifndef HEADER_CURL_HTTP_DIGEST_H +#define HEADER_CURL_HTTP_DIGEST_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) + +/* this is for digest header input */ +CURLcode Curl_input_digest(struct connectdata *conn, + bool proxy, const char *header); + +/* this is for creating digest header output */ +CURLcode Curl_output_digest(struct connectdata *conn, + bool proxy, + const unsigned char *request, + const unsigned char *uripath); + +void Curl_http_auth_cleanup_digest(struct Curl_easy *data); + +#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_CRYPTO_AUTH */ + +#endif /* HEADER_CURL_HTTP_DIGEST_H */ diff --git a/libcurl/lib/http_negotiate.c b/libcurl/lib/http_negotiate.c new file mode 100644 index 0000000..c8f4064 --- /dev/null +++ b/libcurl/lib/http_negotiate.c @@ -0,0 +1,220 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) + +#include "urldata.h" +#include "sendf.h" +#include "http_negotiate.h" +#include "vauth/vauth.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, + const char *header) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + size_t len; + + /* Point to the username, password, service and host */ + const char *userp; + const char *passwdp; + const char *service; + const char *host; + + /* Point to the correct struct with this */ + struct negotiatedata *neg_ctx; + curlnegotiate state; + + if(proxy) { + userp = conn->http_proxy.user; + passwdp = conn->http_proxy.passwd; + service = data->set.str[STRING_PROXY_SERVICE_NAME] ? + data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; + host = conn->http_proxy.host.name; + neg_ctx = &conn->proxyneg; + state = conn->proxy_negotiate_state; + } + else { + userp = conn->user; + passwdp = conn->passwd; + service = data->set.str[STRING_SERVICE_NAME] ? + data->set.str[STRING_SERVICE_NAME] : "HTTP"; + host = conn->host.name; + neg_ctx = &conn->negotiate; + state = conn->http_negotiate_state; + } + + /* Not set means empty */ + if(!userp) + userp = ""; + + if(!passwdp) + passwdp = ""; + + /* Obtain the input token, if any */ + header += strlen("Negotiate"); + while(*header && ISSPACE(*header)) + header++; + + len = strlen(header); + neg_ctx->havenegdata = len != 0; + if(!len) { + if(state == GSS_AUTHSUCC) { + infof(conn->data, "Negotiate auth restarted\n"); + Curl_http_auth_cleanup_negotiate(conn); + } + else if(state != GSS_AUTHNONE) { + /* The server rejected our authentication and hasn't supplied any more + negotiation mechanisms */ + Curl_http_auth_cleanup_negotiate(conn); + return CURLE_LOGIN_DENIED; + } + } + + /* Supports SSL channel binding for Windows ISS extended protection */ +#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS) + neg_ctx->sslContext = conn->sslContext; +#endif + + /* Initialize the security context and decode our challenge */ + result = Curl_auth_decode_spnego_message(data, userp, passwdp, service, + host, header, neg_ctx); + + if(result) + Curl_http_auth_cleanup_negotiate(conn); + + return result; +} + +CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy) +{ + struct negotiatedata *neg_ctx = proxy ? &conn->proxyneg : + &conn->negotiate; + struct auth *authp = proxy ? &conn->data->state.authproxy : + &conn->data->state.authhost; + curlnegotiate *state = proxy ? &conn->proxy_negotiate_state : + &conn->http_negotiate_state; + char *base64 = NULL; + size_t len = 0; + char *userp; + CURLcode result; + + authp->done = FALSE; + + if(*state == GSS_AUTHRECV) { + if(neg_ctx->havenegdata) { + neg_ctx->havemultiplerequests = TRUE; + } + } + else if(*state == GSS_AUTHSUCC) { + if(!neg_ctx->havenoauthpersist) { + neg_ctx->noauthpersist = !neg_ctx->havemultiplerequests; + } + } + + if(neg_ctx->noauthpersist || + (*state != GSS_AUTHDONE && *state != GSS_AUTHSUCC)) { + + if(neg_ctx->noauthpersist && *state == GSS_AUTHSUCC) { + infof(conn->data, "Curl_output_negotiate, " + "no persistent authentication: cleanup existing context"); + Curl_http_auth_cleanup_negotiate(conn); + } + if(!neg_ctx->context) { + result = Curl_input_negotiate(conn, proxy, "Negotiate"); + if(result == CURLE_LOGIN_DENIED) { + /* negotiate auth failed, let's continue unauthenticated to stay + * compatible with the behavior before curl-7_64_0-158-g6c6035532 */ + conn->data->state.authproblem = TRUE; + return CURLE_OK; + } + else if(result) + return result; + } + + result = Curl_auth_create_spnego_message(conn->data, + neg_ctx, &base64, &len); + if(result) + return result; + + userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "", + base64); + + if(proxy) { + Curl_safefree(conn->allocptr.proxyuserpwd); + conn->allocptr.proxyuserpwd = userp; + } + else { + Curl_safefree(conn->allocptr.userpwd); + conn->allocptr.userpwd = userp; + } + + free(base64); + + if(userp == NULL) { + return CURLE_OUT_OF_MEMORY; + } + + *state = GSS_AUTHSENT; + #ifdef HAVE_GSSAPI + if(neg_ctx->status == GSS_S_COMPLETE || + neg_ctx->status == GSS_S_CONTINUE_NEEDED) { + *state = GSS_AUTHDONE; + } + #else + #ifdef USE_WINDOWS_SSPI + if(neg_ctx->status == SEC_E_OK || + neg_ctx->status == SEC_I_CONTINUE_NEEDED) { + *state = GSS_AUTHDONE; + } + #endif + #endif + } + + if(*state == GSS_AUTHDONE || *state == GSS_AUTHSUCC) { + /* connection is already authenticated, + * don't send a header in future requests */ + authp->done = TRUE; + } + + neg_ctx->havenegdata = FALSE; + + return CURLE_OK; +} + +void Curl_http_auth_cleanup_negotiate(struct connectdata *conn) +{ + conn->http_negotiate_state = GSS_AUTHNONE; + conn->proxy_negotiate_state = GSS_AUTHNONE; + + Curl_auth_cleanup_spnego(&conn->negotiate); + Curl_auth_cleanup_spnego(&conn->proxyneg); +} + +#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */ diff --git a/libcurl/lib/http_negotiate.h b/libcurl/lib/http_negotiate.h new file mode 100644 index 0000000..4f0ac16 --- /dev/null +++ b/libcurl/lib/http_negotiate.h @@ -0,0 +1,38 @@ +#ifndef HEADER_CURL_HTTP_NEGOTIATE_H +#define HEADER_CURL_HTTP_NEGOTIATE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) + +/* this is for Negotiate header input */ +CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, + const char *header); + +/* this is for creating Negotiate header output */ +CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy); + +void Curl_http_auth_cleanup_negotiate(struct connectdata *conn); + +#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */ + +#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */ diff --git a/libcurl/lib/http_ntlm.c b/libcurl/lib/http_ntlm.c new file mode 100644 index 0000000..e4a4fe0 --- /dev/null +++ b/libcurl/lib/http_ntlm.c @@ -0,0 +1,259 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) + +/* + * NTLM details: + * + * https://davenport.sourceforge.io/ntlm.html + * https://www.innovation.ch/java/ntlm.html + */ + +#define DEBUG_ME 0 + +#include "urldata.h" +#include "sendf.h" +#include "strcase.h" +#include "http_ntlm.h" +#include "curl_ntlm_core.h" +#include "curl_ntlm_wb.h" +#include "vauth/vauth.h" +#include "url.h" + +/* SSL backend-specific #if branches in this file must be kept in the order + documented in curl_ntlm_core. */ +#if defined(NTLM_NEEDS_NSS_INIT) +#include "vtls/nssg.h" +#elif defined(USE_WINDOWS_SSPI) +#include "curl_sspi.h" +#endif + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#if DEBUG_ME +# define DEBUG_OUT(x) x +#else +# define DEBUG_OUT(x) Curl_nop_stmt +#endif + +CURLcode Curl_input_ntlm(struct connectdata *conn, + bool proxy, /* if proxy or not */ + const char *header) /* rest of the www-authenticate: + header */ +{ + /* point to the correct struct with this */ + struct ntlmdata *ntlm; + curlntlm *state; + CURLcode result = CURLE_OK; + + ntlm = proxy ? &conn->proxyntlm : &conn->ntlm; + state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state; + + if(checkprefix("NTLM", header)) { + header += strlen("NTLM"); + + while(*header && ISSPACE(*header)) + header++; + + if(*header) { + result = Curl_auth_decode_ntlm_type2_message(conn->data, header, ntlm); + if(result) + return result; + + *state = NTLMSTATE_TYPE2; /* We got a type-2 message */ + } + else { + if(*state == NTLMSTATE_LAST) { + infof(conn->data, "NTLM auth restarted\n"); + Curl_http_auth_cleanup_ntlm(conn); + } + else if(*state == NTLMSTATE_TYPE3) { + infof(conn->data, "NTLM handshake rejected\n"); + Curl_http_auth_cleanup_ntlm(conn); + *state = NTLMSTATE_NONE; + return CURLE_REMOTE_ACCESS_DENIED; + } + else if(*state >= NTLMSTATE_TYPE1) { + infof(conn->data, "NTLM handshake failure (internal error)\n"); + return CURLE_REMOTE_ACCESS_DENIED; + } + + *state = NTLMSTATE_TYPE1; /* We should send away a type-1 */ + } + } + + return result; +} + +/* + * This is for creating ntlm header output + */ +CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) +{ + char *base64 = NULL; + size_t len = 0; + CURLcode result; + + /* point to the address of the pointer that holds the string to send to the + server, which is for a plain host or for a HTTP proxy */ + char **allocuserpwd; + + /* point to the username, password, service and host */ + const char *userp; + const char *passwdp; + const char *service = NULL; + const char *hostname = NULL; + + /* point to the correct struct with this */ + struct ntlmdata *ntlm; + curlntlm *state; + struct auth *authp; + + DEBUGASSERT(conn); + DEBUGASSERT(conn->data); + +#if defined(NTLM_NEEDS_NSS_INIT) + if(CURLE_OK != Curl_nss_force_init(conn->data)) + return CURLE_OUT_OF_MEMORY; +#endif + + if(proxy) { + allocuserpwd = &conn->allocptr.proxyuserpwd; + userp = conn->http_proxy.user; + passwdp = conn->http_proxy.passwd; + service = conn->data->set.str[STRING_PROXY_SERVICE_NAME] ? + conn->data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; + hostname = conn->http_proxy.host.name; + ntlm = &conn->proxyntlm; + state = &conn->proxy_ntlm_state; + authp = &conn->data->state.authproxy; + } + else { + allocuserpwd = &conn->allocptr.userpwd; + userp = conn->user; + passwdp = conn->passwd; + service = conn->data->set.str[STRING_SERVICE_NAME] ? + conn->data->set.str[STRING_SERVICE_NAME] : "HTTP"; + hostname = conn->host.name; + ntlm = &conn->ntlm; + state = &conn->http_ntlm_state; + authp = &conn->data->state.authhost; + } + authp->done = FALSE; + + /* not set means empty */ + if(!userp) + userp = ""; + + if(!passwdp) + passwdp = ""; + +#ifdef USE_WINDOWS_SSPI + if(s_hSecDll == NULL) { + /* not thread safe and leaks - use curl_global_init() to avoid */ + CURLcode err = Curl_sspi_global_init(); + if(s_hSecDll == NULL) + return err; + } +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + ntlm->sslContext = conn->sslContext; +#endif +#endif + + switch(*state) { + case NTLMSTATE_TYPE1: + default: /* for the weird cases we (re)start here */ + /* Create a type-1 message */ + result = Curl_auth_create_ntlm_type1_message(conn->data, userp, passwdp, + service, hostname, + ntlm, &base64, + &len); + if(result) + return result; + + if(base64) { + free(*allocuserpwd); + *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", + proxy ? "Proxy-" : "", + base64); + free(base64); + if(!*allocuserpwd) + return CURLE_OUT_OF_MEMORY; + + DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd)); + } + break; + + case NTLMSTATE_TYPE2: + /* We already received the type-2 message, create a type-3 message */ + result = Curl_auth_create_ntlm_type3_message(conn->data, userp, passwdp, + ntlm, &base64, &len); + if(result) + return result; + + if(base64) { + free(*allocuserpwd); + *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", + proxy ? "Proxy-" : "", + base64); + free(base64); + if(!*allocuserpwd) + return CURLE_OUT_OF_MEMORY; + + DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd)); + + *state = NTLMSTATE_TYPE3; /* we send a type-3 */ + authp->done = TRUE; + } + break; + + case NTLMSTATE_TYPE3: + /* connection is already authenticated, + * don't send a header in future requests */ + *state = NTLMSTATE_LAST; + /* FALLTHROUGH */ + case NTLMSTATE_LAST: + Curl_safefree(*allocuserpwd); + authp->done = TRUE; + break; + } + + return CURLE_OK; +} + +void Curl_http_auth_cleanup_ntlm(struct connectdata *conn) +{ + Curl_auth_cleanup_ntlm(&conn->ntlm); + Curl_auth_cleanup_ntlm(&conn->proxyntlm); + +#if defined(NTLM_WB_ENABLED) + Curl_http_auth_cleanup_ntlm_wb(conn); +#endif +} + +#endif /* !CURL_DISABLE_HTTP && USE_NTLM */ diff --git a/libcurl/lib/http_ntlm.h b/libcurl/lib/http_ntlm.h new file mode 100644 index 0000000..003714d --- /dev/null +++ b/libcurl/lib/http_ntlm.h @@ -0,0 +1,40 @@ +#ifndef HEADER_CURL_HTTP_NTLM_H +#define HEADER_CURL_HTTP_NTLM_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) + +/* this is for ntlm header input */ +CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy, + const char *header); + +/* this is for creating ntlm header output */ +CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy); + +void Curl_http_auth_cleanup_ntlm(struct connectdata *conn); + +#endif /* !CURL_DISABLE_HTTP && USE_NTLM */ + +#endif /* HEADER_CURL_HTTP_NTLM_H */ diff --git a/libcurl/lib/http_proxy.c b/libcurl/lib/http_proxy.c new file mode 100644 index 0000000..ba67b86 --- /dev/null +++ b/libcurl/lib/http_proxy.c @@ -0,0 +1,686 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include "http_proxy.h" + +#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP) + +#include +#include "sendf.h" +#include "http.h" +#include "url.h" +#include "select.h" +#include "progress.h" +#include "non-ascii.h" +#include "connect.h" +#include "curlx.h" +#include "vtls/vtls.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Perform SSL initialization for HTTPS proxy. Sets + * proxy_ssl_connected connection bit when complete. Can be + * called multiple times. + */ +static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex) +{ +#ifdef USE_SSL + CURLcode result = CURLE_OK; + DEBUGASSERT(conn->http_proxy.proxytype == CURLPROXY_HTTPS); + if(!conn->bits.proxy_ssl_connected[sockindex]) { + /* perform SSL initialization for this socket */ + result = + Curl_ssl_connect_nonblocking(conn, sockindex, + &conn->bits.proxy_ssl_connected[sockindex]); + if(result) + conn->bits.close = TRUE; /* a failed connection is marked for closure to + prevent (bad) re-use or similar */ + } + return result; +#else + (void) conn; + (void) sockindex; + return CURLE_NOT_BUILT_IN; +#endif +} + +CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex) +{ + if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) { + const CURLcode result = https_proxy_connect(conn, sockindex); + if(result) + return result; + if(!conn->bits.proxy_ssl_connected[sockindex]) + return result; /* wait for HTTPS proxy SSL initialization to complete */ + } + + if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { +#ifndef CURL_DISABLE_PROXY + /* for [protocol] tunneled through HTTP proxy */ + struct HTTP http_proxy; + void *prot_save; + const char *hostname; + int remote_port; + CURLcode result; + + /* BLOCKING */ + /* We want "seamless" operations through HTTP proxy tunnel */ + + /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the + * member conn->proto.http; we want [protocol] through HTTP and we have + * to change the member temporarily for connecting to the HTTP + * proxy. After Curl_proxyCONNECT we have to set back the member to the + * original pointer + * + * This function might be called several times in the multi interface case + * if the proxy's CONNECT response is not instant. + */ + prot_save = conn->data->req.protop; + memset(&http_proxy, 0, sizeof(http_proxy)); + conn->data->req.protop = &http_proxy; + connkeep(conn, "HTTP proxy CONNECT"); + + /* for the secondary socket (FTP), use the "connect to host" + * but ignore the "connect to port" (use the secondary port) + */ + + if(conn->bits.conn_to_host) + hostname = conn->conn_to_host.name; + else if(sockindex == SECONDARYSOCKET) + hostname = conn->secondaryhostname; + else + hostname = conn->host.name; + + if(sockindex == SECONDARYSOCKET) + remote_port = conn->secondary_port; + else if(conn->bits.conn_to_port) + remote_port = conn->conn_to_port; + else + remote_port = conn->remote_port; + result = Curl_proxyCONNECT(conn, sockindex, hostname, remote_port); + conn->data->req.protop = prot_save; + if(CURLE_OK != result) + return result; + Curl_safefree(conn->allocptr.proxyuserpwd); +#else + return CURLE_NOT_BUILT_IN; +#endif + } + /* no HTTP tunnel proxy, just return */ + return CURLE_OK; +} + +bool Curl_connect_complete(struct connectdata *conn) +{ + return !conn->connect_state || + (conn->connect_state->tunnel_state == TUNNEL_COMPLETE); +} + +bool Curl_connect_ongoing(struct connectdata *conn) +{ + return conn->connect_state && + (conn->connect_state->tunnel_state != TUNNEL_COMPLETE); +} + +static CURLcode connect_init(struct connectdata *conn, bool reinit) +{ + struct http_connect_state *s; + if(!reinit) { + DEBUGASSERT(!conn->connect_state); + s = calloc(1, sizeof(struct http_connect_state)); + if(!s) + return CURLE_OUT_OF_MEMORY; + infof(conn->data, "allocate connect buffer!\n"); + conn->connect_state = s; + } + else { + DEBUGASSERT(conn->connect_state); + s = conn->connect_state; + } + s->tunnel_state = TUNNEL_INIT; + s->keepon = TRUE; + s->line_start = s->connect_buffer; + s->ptr = s->line_start; + s->cl = 0; + s->close_connection = FALSE; + return CURLE_OK; +} + +static void connect_done(struct connectdata *conn) +{ + struct http_connect_state *s = conn->connect_state; + s->tunnel_state = TUNNEL_COMPLETE; + infof(conn->data, "CONNECT phase completed!\n"); +} + +static CURLcode CONNECT(struct connectdata *conn, + int sockindex, + const char *hostname, + int remote_port) +{ + int subversion = 0; + struct Curl_easy *data = conn->data; + struct SingleRequest *k = &data->req; + CURLcode result; + curl_socket_t tunnelsocket = conn->sock[sockindex]; + struct http_connect_state *s = conn->connect_state; + +#define SELECT_OK 0 +#define SELECT_ERROR 1 + + if(Curl_connect_complete(conn)) + return CURLE_OK; /* CONNECT is already completed */ + + conn->bits.proxy_connect_closed = FALSE; + + do { + timediff_t check; + if(TUNNEL_INIT == s->tunnel_state) { + /* BEGIN CONNECT PHASE */ + char *host_port; + Curl_send_buffer *req_buffer; + + infof(data, "Establish HTTP proxy tunnel to %s:%d\n", + hostname, remote_port); + + /* This only happens if we've looped here due to authentication + reasons, and we don't really use the newly cloned URL here + then. Just free() it. */ + free(data->req.newurl); + data->req.newurl = NULL; + + /* initialize a dynamic send-buffer */ + req_buffer = Curl_add_buffer_init(); + + if(!req_buffer) + return CURLE_OUT_OF_MEMORY; + + host_port = aprintf("%s:%d", hostname, remote_port); + if(!host_port) { + Curl_add_buffer_free(&req_buffer); + return CURLE_OUT_OF_MEMORY; + } + + /* Setup the proxy-authorization header, if any */ + result = Curl_http_output_auth(conn, "CONNECT", host_port, TRUE); + + free(host_port); + + if(!result) { + char *host = NULL; + const char *proxyconn = ""; + const char *useragent = ""; + const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ? + "1.0" : "1.1"; + bool ipv6_ip = conn->bits.ipv6_ip; + char *hostheader; + + /* the hostname may be different */ + if(hostname != conn->host.name) + ipv6_ip = (strchr(hostname, ':') != NULL); + hostheader = /* host:port with IPv6 support */ + aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"", + remote_port); + if(!hostheader) { + Curl_add_buffer_free(&req_buffer); + return CURLE_OUT_OF_MEMORY; + } + + if(!Curl_checkProxyheaders(conn, "Host")) { + host = aprintf("Host: %s\r\n", hostheader); + if(!host) { + free(hostheader); + Curl_add_buffer_free(&req_buffer); + return CURLE_OUT_OF_MEMORY; + } + } + if(!Curl_checkProxyheaders(conn, "Proxy-Connection")) + proxyconn = "Proxy-Connection: Keep-Alive\r\n"; + + if(!Curl_checkProxyheaders(conn, "User-Agent") && + data->set.str[STRING_USERAGENT]) + useragent = conn->allocptr.uagent; + + result = + Curl_add_bufferf(&req_buffer, + "CONNECT %s HTTP/%s\r\n" + "%s" /* Host: */ + "%s" /* Proxy-Authorization */ + "%s" /* User-Agent */ + "%s", /* Proxy-Connection */ + hostheader, + http, + host?host:"", + conn->allocptr.proxyuserpwd? + conn->allocptr.proxyuserpwd:"", + useragent, + proxyconn); + + if(host) + free(host); + free(hostheader); + + if(!result) + result = Curl_add_custom_headers(conn, TRUE, req_buffer); + + if(!result) + /* CRLF terminate the request */ + result = Curl_add_bufferf(&req_buffer, "\r\n"); + + if(!result) { + /* Send the connect request to the proxy */ + /* BLOCKING */ + result = + Curl_add_buffer_send(&req_buffer, conn, + &data->info.request_size, 0, sockindex); + } + req_buffer = NULL; + if(result) + failf(data, "Failed sending CONNECT to proxy"); + } + + Curl_add_buffer_free(&req_buffer); + if(result) + return result; + + s->tunnel_state = TUNNEL_CONNECT; + s->perline = 0; + } /* END CONNECT PHASE */ + + check = Curl_timeleft(data, NULL, TRUE); + if(check <= 0) { + failf(data, "Proxy CONNECT aborted due to timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + if(!Curl_conn_data_pending(conn, sockindex)) + /* return so we'll be called again polling-style */ + return CURLE_OK; + + /* at this point, the tunnel_connecting phase is over. */ + + { /* READING RESPONSE PHASE */ + int error = SELECT_OK; + + while(s->keepon && !error) { + ssize_t gotbytes; + + /* make sure we have space to read more data */ + if(s->ptr >= &s->connect_buffer[CONNECT_BUFFER_SIZE]) { + failf(data, "CONNECT response too large!"); + return CURLE_RECV_ERROR; + } + + /* Read one byte at a time to avoid a race condition. Wait at most one + second before looping to ensure continuous pgrsUpdates. */ + result = Curl_read(conn, tunnelsocket, s->ptr, 1, &gotbytes); + if(result == CURLE_AGAIN) + /* socket buffer drained, return */ + return CURLE_OK; + + if(Curl_pgrsUpdate(conn)) + return CURLE_ABORTED_BY_CALLBACK; + + if(result) { + s->keepon = FALSE; + break; + } + else if(gotbytes <= 0) { + if(data->set.proxyauth && data->state.authproxy.avail) { + /* proxy auth was requested and there was proxy auth available, + then deem this as "mere" proxy disconnect */ + conn->bits.proxy_connect_closed = TRUE; + infof(data, "Proxy CONNECT connection closed\n"); + } + else { + error = SELECT_ERROR; + failf(data, "Proxy CONNECT aborted"); + } + s->keepon = FALSE; + break; + } + + + if(s->keepon > TRUE) { + /* This means we are currently ignoring a response-body */ + + s->ptr = s->connect_buffer; + if(s->cl) { + /* A Content-Length based body: simply count down the counter + and make sure to break out of the loop when we're done! */ + s->cl--; + if(s->cl <= 0) { + s->keepon = FALSE; + s->tunnel_state = TUNNEL_COMPLETE; + break; + } + } + else { + /* chunked-encoded body, so we need to do the chunked dance + properly to know when the end of the body is reached */ + CHUNKcode r; + ssize_t tookcareof = 0; + + /* now parse the chunked piece of data so that we can + properly tell when the stream ends */ + r = Curl_httpchunk_read(conn, s->ptr, 1, &tookcareof); + if(r == CHUNKE_STOP) { + /* we're done reading chunks! */ + infof(data, "chunk reading DONE\n"); + s->keepon = FALSE; + /* we did the full CONNECT treatment, go COMPLETE */ + s->tunnel_state = TUNNEL_COMPLETE; + } + } + continue; + } + + s->perline++; /* amount of bytes in this line so far */ + + /* if this is not the end of a header line then continue */ + if(*s->ptr != 0x0a) { + s->ptr++; + continue; + } + + /* convert from the network encoding */ + result = Curl_convert_from_network(data, s->line_start, + (size_t)s->perline); + /* Curl_convert_from_network calls failf if unsuccessful */ + if(result) + return result; + + /* output debug if that is requested */ + if(data->set.verbose) + Curl_debug(data, CURLINFO_HEADER_IN, + s->line_start, (size_t)s->perline); + + if(!data->set.suppress_connect_headers) { + /* send the header to the callback */ + int writetype = CLIENTWRITE_HEADER; + if(data->set.include_header) + writetype |= CLIENTWRITE_BODY; + + result = Curl_client_write(conn, writetype, + s->line_start, s->perline); + if(result) + return result; + } + + data->info.header_size += (long)s->perline; + data->req.headerbytecount += (long)s->perline; + + /* Newlines are CRLF, so the CR is ignored as the line isn't + really terminated until the LF comes. Treat a following CR + as end-of-headers as well.*/ + + if(('\r' == s->line_start[0]) || + ('\n' == s->line_start[0])) { + /* end of response-headers from the proxy */ + s->ptr = s->connect_buffer; + if((407 == k->httpcode) && !data->state.authproblem) { + /* If we get a 407 response code with content length + when we have no auth problem, we must ignore the + whole response-body */ + s->keepon = 2; + + if(s->cl) { + infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T + " bytes of response-body\n", s->cl); + } + else if(s->chunked_encoding) { + CHUNKcode r; + + infof(data, "Ignore chunked response-body\n"); + + /* We set ignorebody true here since the chunked + decoder function will acknowledge that. Pay + attention so that this is cleared again when this + function returns! */ + k->ignorebody = TRUE; + + if(s->line_start[1] == '\n') { + /* this can only be a LF if the letter at index 0 + was a CR */ + s->line_start++; + } + + /* now parse the chunked piece of data so that we can + properly tell when the stream ends */ + r = Curl_httpchunk_read(conn, s->line_start + 1, 1, &gotbytes); + if(r == CHUNKE_STOP) { + /* we're done reading chunks! */ + infof(data, "chunk reading DONE\n"); + s->keepon = FALSE; + /* we did the full CONNECT treatment, go to COMPLETE */ + s->tunnel_state = TUNNEL_COMPLETE; + } + } + else { + /* without content-length or chunked encoding, we + can't keep the connection alive since the close is + the end signal so we bail out at once instead */ + s->keepon = FALSE; + } + } + else + s->keepon = FALSE; + if(!s->cl) + /* we did the full CONNECT treatment, go to COMPLETE */ + s->tunnel_state = TUNNEL_COMPLETE; + continue; + } + + s->line_start[s->perline] = 0; /* zero terminate the buffer */ + if((checkprefix("WWW-Authenticate:", s->line_start) && + (401 == k->httpcode)) || + (checkprefix("Proxy-authenticate:", s->line_start) && + (407 == k->httpcode))) { + + bool proxy = (k->httpcode == 407) ? TRUE : FALSE; + char *auth = Curl_copy_header_value(s->line_start); + if(!auth) + return CURLE_OUT_OF_MEMORY; + + result = Curl_http_input_auth(conn, proxy, auth); + + free(auth); + + if(result) + return result; + } + else if(checkprefix("Content-Length:", s->line_start)) { + if(k->httpcode/100 == 2) { + /* A client MUST ignore any Content-Length or Transfer-Encoding + header fields received in a successful response to CONNECT. + "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ + infof(data, "Ignoring Content-Length in CONNECT %03d response\n", + k->httpcode); + } + else { + (void)curlx_strtoofft(s->line_start + + strlen("Content-Length:"), NULL, 10, &s->cl); + } + } + else if(Curl_compareheader(s->line_start, "Connection:", "close")) + s->close_connection = TRUE; + else if(checkprefix("Transfer-Encoding:", s->line_start)) { + if(k->httpcode/100 == 2) { + /* A client MUST ignore any Content-Length or Transfer-Encoding + header fields received in a successful response to CONNECT. + "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ + infof(data, "Ignoring Transfer-Encoding in " + "CONNECT %03d response\n", k->httpcode); + } + else if(Curl_compareheader(s->line_start, + "Transfer-Encoding:", "chunked")) { + infof(data, "CONNECT responded chunked\n"); + s->chunked_encoding = TRUE; + /* init our chunky engine */ + Curl_httpchunk_init(conn); + } + } + else if(Curl_compareheader(s->line_start, + "Proxy-Connection:", "close")) + s->close_connection = TRUE; + else if(2 == sscanf(s->line_start, "HTTP/1.%d %d", + &subversion, + &k->httpcode)) { + /* store the HTTP code from the proxy */ + data->info.httpproxycode = k->httpcode; + } + + s->perline = 0; /* line starts over here */ + s->ptr = s->connect_buffer; + s->line_start = s->ptr; + } /* while there's buffer left and loop is requested */ + + if(Curl_pgrsUpdate(conn)) + return CURLE_ABORTED_BY_CALLBACK; + + if(error) + return CURLE_RECV_ERROR; + + if(data->info.httpproxycode/100 != 2) { + /* Deal with the possibly already received authenticate + headers. 'newurl' is set to a new URL if we must loop. */ + result = Curl_http_auth_act(conn); + if(result) + return result; + + if(conn->bits.close) + /* the connection has been marked for closure, most likely in the + Curl_http_auth_act() function and thus we can kill it at once + below */ + s->close_connection = TRUE; + } + + if(s->close_connection && data->req.newurl) { + /* Connection closed by server. Don't use it anymore */ + Curl_closesocket(conn, conn->sock[sockindex]); + conn->sock[sockindex] = CURL_SOCKET_BAD; + break; + } + } /* END READING RESPONSE PHASE */ + + /* If we are supposed to continue and request a new URL, which basically + * means the HTTP authentication is still going on so if the tunnel + * is complete we start over in INIT state */ + if(data->req.newurl && (TUNNEL_COMPLETE == s->tunnel_state)) { + connect_init(conn, TRUE); /* reinit */ + } + + } while(data->req.newurl); + + if(data->info.httpproxycode/100 != 2) { + if(s->close_connection && data->req.newurl) { + conn->bits.proxy_connect_closed = TRUE; + infof(data, "Connect me again please\n"); + connect_done(conn); + } + else { + free(data->req.newurl); + data->req.newurl = NULL; + /* failure, close this connection to avoid re-use */ + streamclose(conn, "proxy CONNECT failure"); + Curl_closesocket(conn, conn->sock[sockindex]); + conn->sock[sockindex] = CURL_SOCKET_BAD; + } + + /* to back to init state */ + s->tunnel_state = TUNNEL_INIT; + + if(conn->bits.proxy_connect_closed) + /* this is not an error, just part of the connection negotiation */ + return CURLE_OK; + failf(data, "Received HTTP code %d from proxy after CONNECT", + data->req.httpcode); + return CURLE_RECV_ERROR; + } + + s->tunnel_state = TUNNEL_COMPLETE; + + /* If a proxy-authorization header was used for the proxy, then we should + make sure that it isn't accidentally used for the document request + after we've connected. So let's free and clear it here. */ + Curl_safefree(conn->allocptr.proxyuserpwd); + conn->allocptr.proxyuserpwd = NULL; + + data->state.authproxy.done = TRUE; + data->state.authproxy.multipass = FALSE; + + infof(data, "Proxy replied %d to CONNECT request\n", + data->info.httpproxycode); + data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */ + conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the + document request */ + return CURLE_OK; +} + +void Curl_connect_free(struct Curl_easy *data) +{ + struct connectdata *conn = data->conn; + struct http_connect_state *s = conn->connect_state; + if(s) { + free(s); + conn->connect_state = NULL; + } +} + +/* + * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This + * function will issue the necessary commands to get a seamless tunnel through + * this proxy. After that, the socket can be used just as a normal socket. + */ + +CURLcode Curl_proxyCONNECT(struct connectdata *conn, + int sockindex, + const char *hostname, + int remote_port) +{ + CURLcode result; + if(!conn->connect_state) { + result = connect_init(conn, FALSE); + if(result) + return result; + } + result = CONNECT(conn, sockindex, hostname, remote_port); + + if(result || Curl_connect_complete(conn)) + connect_done(conn); + + return result; +} + +#else +void Curl_connect_free(struct Curl_easy *data) +{ + (void)data; +} + +#endif /* CURL_DISABLE_PROXY */ diff --git a/libcurl/lib/http_proxy.h b/libcurl/lib/http_proxy.h new file mode 100644 index 0000000..e19fa85 --- /dev/null +++ b/libcurl/lib/http_proxy.h @@ -0,0 +1,51 @@ +#ifndef HEADER_CURL_HTTP_PROXY_H +#define HEADER_CURL_HTTP_PROXY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include "urldata.h" + +#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP) +/* ftp can use this as well */ +CURLcode Curl_proxyCONNECT(struct connectdata *conn, + int tunnelsocket, + const char *hostname, int remote_port); + +/* Default proxy timeout in milliseconds */ +#define PROXY_TIMEOUT (3600*1000) + +CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex); + +bool Curl_connect_complete(struct connectdata *conn); +bool Curl_connect_ongoing(struct connectdata *conn); + +#else +#define Curl_proxyCONNECT(x,y,z,w) CURLE_NOT_BUILT_IN +#define Curl_proxy_connect(x,y) CURLE_OK +#define Curl_connect_complete(x) CURLE_OK +#define Curl_connect_ongoing(x) FALSE +#endif + +void Curl_connect_free(struct Curl_easy *data); + +#endif /* HEADER_CURL_HTTP_PROXY_H */ diff --git a/libcurl/lib/idn_win32.c b/libcurl/lib/idn_win32.c new file mode 100644 index 0000000..8dc300b --- /dev/null +++ b/libcurl/lib/idn_win32.c @@ -0,0 +1,111 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + + /* + * IDN conversions using Windows kernel32 and normaliz libraries. + */ + +#include "curl_setup.h" + +#ifdef USE_WIN32_IDN + +#include "curl_multibyte.h" +#include "curl_memory.h" +#include "warnless.h" + + /* The last #include file should be: */ +#include "memdebug.h" + +#ifdef WANT_IDN_PROTOTYPES +# if defined(_SAL_VERSION) +WINNORMALIZEAPI int WINAPI +IdnToAscii(_In_ DWORD dwFlags, + _In_reads_(cchUnicodeChar) LPCWSTR lpUnicodeCharStr, + _In_ int cchUnicodeChar, + _Out_writes_opt_(cchASCIIChar) LPWSTR lpASCIICharStr, + _In_ int cchASCIIChar); +WINNORMALIZEAPI int WINAPI +IdnToUnicode(_In_ DWORD dwFlags, + _In_reads_(cchASCIIChar) LPCWSTR lpASCIICharStr, + _In_ int cchASCIIChar, + _Out_writes_opt_(cchUnicodeChar) LPWSTR lpUnicodeCharStr, + _In_ int cchUnicodeChar); +# else +WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags, + const WCHAR *lpUnicodeCharStr, + int cchUnicodeChar, + WCHAR *lpASCIICharStr, + int cchASCIIChar); +WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags, + const WCHAR *lpASCIICharStr, + int cchASCIIChar, + WCHAR *lpUnicodeCharStr, + int cchUnicodeChar); +# endif +#endif + +#define IDN_MAX_LENGTH 255 + +bool curl_win32_idn_to_ascii(const char *in, char **out); +bool curl_win32_ascii_to_idn(const char *in, char **out); + +bool curl_win32_idn_to_ascii(const char *in, char **out) +{ + bool success = FALSE; + + wchar_t *in_w = Curl_convert_UTF8_to_wchar(in); + if(in_w) { + wchar_t punycode[IDN_MAX_LENGTH]; + int chars = IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH); + free(in_w); + if(chars) { + *out = Curl_convert_wchar_to_UTF8(punycode); + if(*out) + success = TRUE; + } + } + + return success; +} + +bool curl_win32_ascii_to_idn(const char *in, char **out) +{ + bool success = FALSE; + + wchar_t *in_w = Curl_convert_UTF8_to_wchar(in); + if(in_w) { + size_t in_len = wcslen(in_w) + 1; + wchar_t unicode[IDN_MAX_LENGTH]; + int chars = IdnToUnicode(0, in_w, curlx_uztosi(in_len), + unicode, IDN_MAX_LENGTH); + free(in_w); + if(chars) { + *out = Curl_convert_wchar_to_UTF8(unicode); + if(*out) + success = TRUE; + } + } + + return success; +} + +#endif /* USE_WIN32_IDN */ diff --git a/libcurl/lib/if2ip.c b/libcurl/lib/if2ip.c new file mode 100644 index 0000000..d003de6 --- /dev/null +++ b/libcurl/lib/if2ip.c @@ -0,0 +1,243 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_NET_IF_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include +#endif +#ifdef HAVE_IFADDRS_H +# include +#endif +#ifdef HAVE_STROPTS_H +# include +#endif +#ifdef __VMS +# include +#endif + +#include "inet_ntop.h" +#include "strcase.h" +#include "if2ip.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* ------------------------------------------------------------------ */ + +/* Return the scope of the given address. */ +unsigned int Curl_ipv6_scope(const struct sockaddr *sa) +{ +#ifndef ENABLE_IPV6 + (void) sa; +#else + if(sa->sa_family == AF_INET6) { + const struct sockaddr_in6 * sa6 = (const struct sockaddr_in6 *)(void *) sa; + const unsigned char *b = sa6->sin6_addr.s6_addr; + unsigned short w = (unsigned short) ((b[0] << 8) | b[1]); + + if((b[0] & 0xFE) == 0xFC) /* Handle ULAs */ + return IPV6_SCOPE_UNIQUELOCAL; + switch(w & 0xFFC0) { + case 0xFE80: + return IPV6_SCOPE_LINKLOCAL; + case 0xFEC0: + return IPV6_SCOPE_SITELOCAL; + case 0x0000: + w = b[1] | b[2] | b[3] | b[4] | b[5] | b[6] | b[7] | b[8] | b[9] | + b[10] | b[11] | b[12] | b[13] | b[14]; + if(w || b[15] != 0x01) + break; + return IPV6_SCOPE_NODELOCAL; + default: + break; + } + } +#endif + + return IPV6_SCOPE_GLOBAL; +} + + +#if defined(HAVE_GETIFADDRS) + +if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, + unsigned int local_scope_id, const char *interf, + char *buf, int buf_size) +{ + struct ifaddrs *iface, *head; + if2ip_result_t res = IF2IP_NOT_FOUND; + +#ifndef ENABLE_IPV6 + (void) remote_scope; +#endif + +#if !defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) || \ + !defined(ENABLE_IPV6) + (void) local_scope_id; +#endif + + if(getifaddrs(&head) >= 0) { + for(iface = head; iface != NULL; iface = iface->ifa_next) { + if(iface->ifa_addr != NULL) { + if(iface->ifa_addr->sa_family == af) { + if(strcasecompare(iface->ifa_name, interf)) { + void *addr; + char *ip; + char scope[12] = ""; + char ipstr[64]; +#ifdef ENABLE_IPV6 + if(af == AF_INET6) { +#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID + unsigned int scopeid = 0; +#endif + unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr); + + if(ifscope != remote_scope) { + /* We are interested only in interface addresses whose + scope matches the remote address we want to + connect to: global for global, link-local for + link-local, etc... */ + if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED; + continue; + } + + addr = + &((struct sockaddr_in6 *)(void *)iface->ifa_addr)->sin6_addr; +#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID + /* Include the scope of this interface as part of the address */ + scopeid = ((struct sockaddr_in6 *)(void *)iface->ifa_addr) + ->sin6_scope_id; + + /* If given, scope id should match. */ + if(local_scope_id && scopeid != local_scope_id) { + if(res == IF2IP_NOT_FOUND) + res = IF2IP_AF_NOT_SUPPORTED; + + continue; + } + + if(scopeid) + msnprintf(scope, sizeof(scope), "%%%u", scopeid); +#endif + } + else +#endif + addr = + &((struct sockaddr_in *)(void *)iface->ifa_addr)->sin_addr; + res = IF2IP_FOUND; + ip = (char *) Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr)); + msnprintf(buf, buf_size, "%s%s", ip, scope); + break; + } + } + else if((res == IF2IP_NOT_FOUND) && + strcasecompare(iface->ifa_name, interf)) { + res = IF2IP_AF_NOT_SUPPORTED; + } + } + } + + freeifaddrs(head); + } + + return res; +} + +#elif defined(HAVE_IOCTL_SIOCGIFADDR) + +if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, + unsigned int local_scope_id, const char *interf, + char *buf, int buf_size) +{ + struct ifreq req; + struct in_addr in; + struct sockaddr_in *s; + curl_socket_t dummy; + size_t len; + + (void)remote_scope; + (void)local_scope_id; + + if(!interf || (af != AF_INET)) + return IF2IP_NOT_FOUND; + + len = strlen(interf); + if(len >= sizeof(req.ifr_name)) + return IF2IP_NOT_FOUND; + + dummy = socket(AF_INET, SOCK_STREAM, 0); + if(CURL_SOCKET_BAD == dummy) + return IF2IP_NOT_FOUND; + + memset(&req, 0, sizeof(req)); + memcpy(req.ifr_name, interf, len + 1); + req.ifr_addr.sa_family = AF_INET; + + if(ioctl(dummy, SIOCGIFADDR, &req) < 0) { + sclose(dummy); + /* With SIOCGIFADDR, we cannot tell the difference between an interface + that does not exist and an interface that has no address of the + correct family. Assume the interface does not exist */ + return IF2IP_NOT_FOUND; + } + + s = (struct sockaddr_in *)(void *)&req.ifr_addr; + memcpy(&in, &s->sin_addr, sizeof(in)); + Curl_inet_ntop(s->sin_family, &in, buf, buf_size); + + sclose(dummy); + return IF2IP_FOUND; +} + +#else + +if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, + unsigned int local_scope_id, const char *interf, + char *buf, int buf_size) +{ + (void) af; + (void) remote_scope; + (void) local_scope_id; + (void) interf; + (void) buf; + (void) buf_size; + return IF2IP_NOT_FOUND; +} + +#endif diff --git a/libcurl/lib/if2ip.h b/libcurl/lib/if2ip.h new file mode 100644 index 0000000..f193d42 --- /dev/null +++ b/libcurl/lib/if2ip.h @@ -0,0 +1,82 @@ +#ifndef HEADER_CURL_IF2IP_H +#define HEADER_CURL_IF2IP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +/* IPv6 address scopes. */ +#define IPV6_SCOPE_GLOBAL 0 /* Global scope. */ +#define IPV6_SCOPE_LINKLOCAL 1 /* Link-local scope. */ +#define IPV6_SCOPE_SITELOCAL 2 /* Site-local scope (deprecated). */ +#define IPV6_SCOPE_UNIQUELOCAL 3 /* Unique local */ +#define IPV6_SCOPE_NODELOCAL 4 /* Loopback. */ + +unsigned int Curl_ipv6_scope(const struct sockaddr *sa); + +typedef enum { + IF2IP_NOT_FOUND = 0, /* Interface not found */ + IF2IP_AF_NOT_SUPPORTED = 1, /* Int. exists but has no address for this af */ + IF2IP_FOUND = 2 /* The address has been stored in "buf" */ +} if2ip_result_t; + +if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, + unsigned int local_scope_id, const char *interf, + char *buf, int buf_size); + +#ifdef __INTERIX + +/* Nedelcho Stanev's work-around for SFU 3.0 */ +struct ifreq { +#define IFNAMSIZ 16 +#define IFHWADDRLEN 6 + union { + char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + } ifr_ifrn; + + union { + struct sockaddr ifru_addr; + struct sockaddr ifru_broadaddr; + struct sockaddr ifru_netmask; + struct sockaddr ifru_hwaddr; + short ifru_flags; + int ifru_metric; + int ifru_mtu; + } ifr_ifru; +}; + +/* This define was added by Daniel to avoid an extra #ifdef INTERIX in the + C code. */ + +#define ifr_name ifr_ifrn.ifrn_name /* interface name */ +#define ifr_addr ifr_ifru.ifru_addr /* address */ +#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ +#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */ +#define ifr_flags ifr_ifru.ifru_flags /* flags */ +#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ +#define ifr_metric ifr_ifru.ifru_metric /* metric */ +#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ + +#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */ + +#endif /* __INTERIX */ + +#endif /* HEADER_CURL_IF2IP_H */ diff --git a/libcurl/lib/imap.c b/libcurl/lib/imap.c new file mode 100644 index 0000000..f3ffa29 --- /dev/null +++ b/libcurl/lib/imap.c @@ -0,0 +1,2107 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC2195 CRAM-MD5 authentication + * RFC2595 Using TLS with IMAP, POP3 and ACAP + * RFC2831 DIGEST-MD5 authentication + * RFC3501 IMAPv4 protocol + * RFC4422 Simple Authentication and Security Layer (SASL) + * RFC4616 PLAIN authentication + * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism + * RFC4959 IMAP Extension for SASL Initial Client Response + * RFC5092 IMAP URL Scheme + * RFC6749 OAuth 2.0 Authorization Framework + * RFC8314 Use of TLS for Email Submission and Access + * Draft LOGIN SASL Mechanism + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_IMAP + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_UTSNAME_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +#include +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "progress.h" +#include "transfer.h" +#include "escape.h" +#include "http.h" /* for HTTP proxy tunnel stuff */ +#include "socks.h" +#include "imap.h" +#include "mime.h" +#include "strtoofft.h" +#include "strcase.h" +#include "vtls/vtls.h" +#include "connect.h" +#include "strerror.h" +#include "select.h" +#include "multiif.h" +#include "url.h" +#include "strcase.h" +#include "curl_sasl.h" +#include "warnless.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* Local API functions */ +static CURLcode imap_regular_transfer(struct connectdata *conn, bool *done); +static CURLcode imap_do(struct connectdata *conn, bool *done); +static CURLcode imap_done(struct connectdata *conn, CURLcode status, + bool premature); +static CURLcode imap_connect(struct connectdata *conn, bool *done); +static CURLcode imap_disconnect(struct connectdata *conn, bool dead); +static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done); +static int imap_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); +static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done); +static CURLcode imap_setup_connection(struct connectdata *conn); +static char *imap_atom(const char *str, bool escape_only); +static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...); +static CURLcode imap_parse_url_options(struct connectdata *conn); +static CURLcode imap_parse_url_path(struct connectdata *conn); +static CURLcode imap_parse_custom_request(struct connectdata *conn); +static CURLcode imap_perform_authenticate(struct connectdata *conn, + const char *mech, + const char *initresp); +static CURLcode imap_continue_authenticate(struct connectdata *conn, + const char *resp); +static void imap_get_message(char *buffer, char **outptr); + +/* + * IMAP protocol handler. + */ + +const struct Curl_handler Curl_handler_imap = { + "IMAP", /* scheme */ + imap_setup_connection, /* setup_connection */ + imap_do, /* do_it */ + imap_done, /* done */ + ZERO_NULL, /* do_more */ + imap_connect, /* connect_it */ + imap_multi_statemach, /* connecting */ + imap_doing, /* doing */ + imap_getsock, /* proto_getsock */ + imap_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + imap_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_IMAP, /* defport */ + CURLPROTO_IMAP, /* protocol */ + PROTOPT_CLOSEACTION| /* flags */ + PROTOPT_URLOPTIONS +}; + +#ifdef USE_SSL +/* + * IMAPS protocol handler. + */ + +const struct Curl_handler Curl_handler_imaps = { + "IMAPS", /* scheme */ + imap_setup_connection, /* setup_connection */ + imap_do, /* do_it */ + imap_done, /* done */ + ZERO_NULL, /* do_more */ + imap_connect, /* connect_it */ + imap_multi_statemach, /* connecting */ + imap_doing, /* doing */ + imap_getsock, /* proto_getsock */ + imap_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + imap_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_IMAPS, /* defport */ + CURLPROTO_IMAPS, /* protocol */ + PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ + PROTOPT_URLOPTIONS +}; +#endif + +#define IMAP_RESP_OK 1 +#define IMAP_RESP_NOT_OK 2 +#define IMAP_RESP_PREAUTH 3 + +/* SASL parameters for the imap protocol */ +static const struct SASLproto saslimap = { + "imap", /* The service name */ + '+', /* Code received when continuation is expected */ + IMAP_RESP_OK, /* Code to receive upon authentication success */ + 0, /* Maximum initial response length (no max) */ + imap_perform_authenticate, /* Send authentication command */ + imap_continue_authenticate, /* Send authentication continuation */ + imap_get_message /* Get SASL response message */ +}; + + +#ifdef USE_SSL +static void imap_to_imaps(struct connectdata *conn) +{ + /* Change the connection handler */ + conn->handler = &Curl_handler_imaps; + + /* Set the connection's upgraded to TLS flag */ + conn->tls_upgraded = TRUE; +} +#else +#define imap_to_imaps(x) Curl_nop_stmt +#endif + +/*********************************************************************** + * + * imap_matchresp() + * + * Determines whether the untagged response is related to the specified + * command by checking if it is in format "* ..." or + * "* ...". + * + * The "* " marker is assumed to have already been checked by the caller. + */ +static bool imap_matchresp(const char *line, size_t len, const char *cmd) +{ + const char *end = line + len; + size_t cmd_len = strlen(cmd); + + /* Skip the untagged response marker */ + line += 2; + + /* Do we have a number after the marker? */ + if(line < end && ISDIGIT(*line)) { + /* Skip the number */ + do + line++; + while(line < end && ISDIGIT(*line)); + + /* Do we have the space character? */ + if(line == end || *line != ' ') + return FALSE; + + line++; + } + + /* Does the command name match and is it followed by a space character or at + the end of line? */ + if(line + cmd_len <= end && strncasecompare(line, cmd, cmd_len) && + (line[cmd_len] == ' ' || line + cmd_len + 2 == end)) + return TRUE; + + return FALSE; +} + +/*********************************************************************** + * + * imap_endofresp() + * + * Checks whether the given string is a valid tagged, untagged or continuation + * response which can be processed by the response handler. + */ +static bool imap_endofresp(struct connectdata *conn, char *line, size_t len, + int *resp) +{ + struct IMAP *imap = conn->data->req.protop; + struct imap_conn *imapc = &conn->proto.imapc; + const char *id = imapc->resptag; + size_t id_len = strlen(id); + + /* Do we have a tagged command response? */ + if(len >= id_len + 1 && !memcmp(id, line, id_len) && line[id_len] == ' ') { + line += id_len + 1; + len -= id_len + 1; + + if(len >= 2 && !memcmp(line, "OK", 2)) + *resp = IMAP_RESP_OK; + else if(len >= 7 && !memcmp(line, "PREAUTH", 7)) + *resp = IMAP_RESP_PREAUTH; + else + *resp = IMAP_RESP_NOT_OK; + + return TRUE; + } + + /* Do we have an untagged command response? */ + if(len >= 2 && !memcmp("* ", line, 2)) { + switch(imapc->state) { + /* States which are interested in untagged responses */ + case IMAP_CAPABILITY: + if(!imap_matchresp(line, len, "CAPABILITY")) + return FALSE; + break; + + case IMAP_LIST: + if((!imap->custom && !imap_matchresp(line, len, "LIST")) || + (imap->custom && !imap_matchresp(line, len, imap->custom) && + (!strcasecompare(imap->custom, "STORE") || + !imap_matchresp(line, len, "FETCH")) && + !strcasecompare(imap->custom, "SELECT") && + !strcasecompare(imap->custom, "EXAMINE") && + !strcasecompare(imap->custom, "SEARCH") && + !strcasecompare(imap->custom, "EXPUNGE") && + !strcasecompare(imap->custom, "LSUB") && + !strcasecompare(imap->custom, "UID") && + !strcasecompare(imap->custom, "NOOP"))) + return FALSE; + break; + + case IMAP_SELECT: + /* SELECT is special in that its untagged responses do not have a + common prefix so accept anything! */ + break; + + case IMAP_FETCH: + if(!imap_matchresp(line, len, "FETCH")) + return FALSE; + break; + + case IMAP_SEARCH: + if(!imap_matchresp(line, len, "SEARCH")) + return FALSE; + break; + + /* Ignore other untagged responses */ + default: + return FALSE; + } + + *resp = '*'; + return TRUE; + } + + /* Do we have a continuation response? This should be a + symbol followed by + a space and optionally some text as per RFC-3501 for the AUTHENTICATE and + APPEND commands and as outlined in Section 4. Examples of RFC-4959 but + some e-mail servers ignore this and only send a single + instead. */ + if(imap && !imap->custom && ((len == 3 && line[0] == '+') || + (len >= 2 && !memcmp("+ ", line, 2)))) { + switch(imapc->state) { + /* States which are interested in continuation responses */ + case IMAP_AUTHENTICATE: + case IMAP_APPEND: + *resp = '+'; + break; + + default: + failf(conn->data, "Unexpected continuation response"); + *resp = -1; + break; + } + + return TRUE; + } + + return FALSE; /* Nothing for us */ +} + +/*********************************************************************** + * + * imap_get_message() + * + * Gets the authentication message from the response buffer. + */ +static void imap_get_message(char *buffer, char **outptr) +{ + size_t len = strlen(buffer); + char *message = NULL; + + if(len > 2) { + /* Find the start of the message */ + len -= 2; + for(message = buffer + 2; *message == ' ' || *message == '\t'; + message++, len--) + ; + + /* Find the end of the message */ + for(; len--;) + if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' && + message[len] != '\t') + break; + + /* Terminate the message */ + if(++len) { + message[len] = '\0'; + } + } + else + /* junk input => zero length output */ + message = &buffer[len]; + + *outptr = message; +} + +/*********************************************************************** + * + * state() + * + * This is the ONLY way to change IMAP state! + */ +static void state(struct connectdata *conn, imapstate newstate) +{ + struct imap_conn *imapc = &conn->proto.imapc; +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* for debug purposes */ + static const char * const names[]={ + "STOP", + "SERVERGREET", + "CAPABILITY", + "STARTTLS", + "UPGRADETLS", + "AUTHENTICATE", + "LOGIN", + "LIST", + "SELECT", + "FETCH", + "FETCH_FINAL", + "APPEND", + "APPEND_FINAL", + "SEARCH", + "LOGOUT", + /* LAST */ + }; + + if(imapc->state != newstate) + infof(conn->data, "IMAP %p state change from %s to %s\n", + (void *)imapc, names[imapc->state], names[newstate]); +#endif + + imapc->state = newstate; +} + +/*********************************************************************** + * + * imap_perform_capability() + * + * Sends the CAPABILITY command in order to obtain a list of server side + * supported capabilities. + */ +static CURLcode imap_perform_capability(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct imap_conn *imapc = &conn->proto.imapc; + imapc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */ + imapc->sasl.authused = SASL_AUTH_NONE; /* Clear the auth. mechanism used */ + imapc->tls_supported = FALSE; /* Clear the TLS capability */ + + /* Send the CAPABILITY command */ + result = imap_sendf(conn, "CAPABILITY"); + + if(!result) + state(conn, IMAP_CAPABILITY); + + return result; +} + +/*********************************************************************** + * + * imap_perform_starttls() + * + * Sends the STARTTLS command to start the upgrade to TLS. + */ +static CURLcode imap_perform_starttls(struct connectdata *conn) +{ + /* Send the STARTTLS command */ + CURLcode result = imap_sendf(conn, "STARTTLS"); + + if(!result) + state(conn, IMAP_STARTTLS); + + return result; +} + +/*********************************************************************** + * + * imap_perform_upgrade_tls() + * + * Performs the upgrade to TLS. + */ +static CURLcode imap_perform_upgrade_tls(struct connectdata *conn) +{ + /* Start the SSL connection */ + struct imap_conn *imapc = &conn->proto.imapc; + CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, + &imapc->ssldone); + + if(!result) { + if(imapc->state != IMAP_UPGRADETLS) + state(conn, IMAP_UPGRADETLS); + + if(imapc->ssldone) { + imap_to_imaps(conn); + result = imap_perform_capability(conn); + } + } + + return result; +} + +/*********************************************************************** + * + * imap_perform_login() + * + * Sends a clear text LOGIN command to authenticate with. + */ +static CURLcode imap_perform_login(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + char *user; + char *passwd; + + /* Check we have a username and password to authenticate with and end the + connect phase if we don't */ + if(!conn->bits.user_passwd) { + state(conn, IMAP_STOP); + + return result; + } + + /* Make sure the username and password are in the correct atom format */ + user = imap_atom(conn->user, false); + passwd = imap_atom(conn->passwd, false); + + /* Send the LOGIN command */ + result = imap_sendf(conn, "LOGIN %s %s", user ? user : "", + passwd ? passwd : ""); + + free(user); + free(passwd); + + if(!result) + state(conn, IMAP_LOGIN); + + return result; +} + +/*********************************************************************** + * + * imap_perform_authenticate() + * + * Sends an AUTHENTICATE command allowing the client to login with the given + * SASL authentication mechanism. + */ +static CURLcode imap_perform_authenticate(struct connectdata *conn, + const char *mech, + const char *initresp) +{ + CURLcode result = CURLE_OK; + + if(initresp) { + /* Send the AUTHENTICATE command with the initial response */ + result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp); + } + else { + /* Send the AUTHENTICATE command */ + result = imap_sendf(conn, "AUTHENTICATE %s", mech); + } + + return result; +} + +/*********************************************************************** + * + * imap_continue_authenticate() + * + * Sends SASL continuation data or cancellation. + */ +static CURLcode imap_continue_authenticate(struct connectdata *conn, + const char *resp) +{ + struct imap_conn *imapc = &conn->proto.imapc; + + return Curl_pp_sendf(&imapc->pp, "%s", resp); +} + +/*********************************************************************** + * + * imap_perform_authentication() + * + * Initiates the authentication sequence, with the appropriate SASL + * authentication mechanism, falling back to clear text should a common + * mechanism not be available between the client and server. + */ +static CURLcode imap_perform_authentication(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct imap_conn *imapc = &conn->proto.imapc; + saslprogress progress; + + /* Check if already authenticated OR if there is enough data to authenticate + with and end the connect phase if we don't */ + if(imapc->preauth || + !Curl_sasl_can_authenticate(&imapc->sasl, conn)) { + state(conn, IMAP_STOP); + return result; + } + + /* Calculate the SASL login details */ + result = Curl_sasl_start(&imapc->sasl, conn, imapc->ir_supported, &progress); + + if(!result) { + if(progress == SASL_INPROGRESS) + state(conn, IMAP_AUTHENTICATE); + else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT)) + /* Perform clear text authentication */ + result = imap_perform_login(conn); + else { + /* Other mechanisms not supported */ + infof(conn->data, "No known authentication mechanisms supported!\n"); + result = CURLE_LOGIN_DENIED; + } + } + + return result; +} + +/*********************************************************************** + * + * imap_perform_list() + * + * Sends a LIST command or an alternative custom request. + */ +static CURLcode imap_perform_list(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct IMAP *imap = data->req.protop; + + if(imap->custom) + /* Send the custom request */ + result = imap_sendf(conn, "%s%s", imap->custom, + imap->custom_params ? imap->custom_params : ""); + else { + /* Make sure the mailbox is in the correct atom format if necessary */ + char *mailbox = imap->mailbox ? imap_atom(imap->mailbox, true) + : strdup(""); + if(!mailbox) + return CURLE_OUT_OF_MEMORY; + + /* Send the LIST command */ + result = imap_sendf(conn, "LIST \"%s\" *", mailbox); + + free(mailbox); + } + + if(!result) + state(conn, IMAP_LIST); + + return result; +} + +/*********************************************************************** + * + * imap_perform_select() + * + * Sends a SELECT command to ask the server to change the selected mailbox. + */ +static CURLcode imap_perform_select(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct IMAP *imap = data->req.protop; + struct imap_conn *imapc = &conn->proto.imapc; + char *mailbox; + + /* Invalidate old information as we are switching mailboxes */ + Curl_safefree(imapc->mailbox); + Curl_safefree(imapc->mailbox_uidvalidity); + + /* Check we have a mailbox */ + if(!imap->mailbox) { + failf(conn->data, "Cannot SELECT without a mailbox."); + return CURLE_URL_MALFORMAT; + } + + /* Make sure the mailbox is in the correct atom format */ + mailbox = imap_atom(imap->mailbox, false); + if(!mailbox) + return CURLE_OUT_OF_MEMORY; + + /* Send the SELECT command */ + result = imap_sendf(conn, "SELECT %s", mailbox); + + free(mailbox); + + if(!result) + state(conn, IMAP_SELECT); + + return result; +} + +/*********************************************************************** + * + * imap_perform_fetch() + * + * Sends a FETCH command to initiate the download of a message. + */ +static CURLcode imap_perform_fetch(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct IMAP *imap = conn->data->req.protop; + /* Check we have a UID */ + if(imap->uid) { + + /* Send the FETCH command */ + if(imap->partial) + result = imap_sendf(conn, "UID FETCH %s BODY[%s]<%s>", + imap->uid, + imap->section ? imap->section : "", + imap->partial); + else + result = imap_sendf(conn, "UID FETCH %s BODY[%s]", + imap->uid, + imap->section ? imap->section : ""); + } + else if(imap->mindex) { + + /* Send the FETCH command */ + if(imap->partial) + result = imap_sendf(conn, "FETCH %s BODY[%s]<%s>", + imap->mindex, + imap->section ? imap->section : "", + imap->partial); + else + result = imap_sendf(conn, "FETCH %s BODY[%s]", + imap->mindex, + imap->section ? imap->section : ""); + } + else { + failf(conn->data, "Cannot FETCH without a UID."); + return CURLE_URL_MALFORMAT; + } + if(!result) + state(conn, IMAP_FETCH); + + return result; +} + +/*********************************************************************** + * + * imap_perform_append() + * + * Sends an APPEND command to initiate the upload of a message. + */ +static CURLcode imap_perform_append(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct IMAP *imap = data->req.protop; + char *mailbox; + + /* Check we have a mailbox */ + if(!imap->mailbox) { + failf(data, "Cannot APPEND without a mailbox."); + return CURLE_URL_MALFORMAT; + } + + /* Prepare the mime data if some. */ + if(data->set.mimepost.kind != MIMEKIND_NONE) { + /* Use the whole structure as data. */ + data->set.mimepost.flags &= ~MIME_BODY_ONLY; + + /* Add external headers and mime version. */ + curl_mime_headers(&data->set.mimepost, data->set.headers, 0); + result = Curl_mime_prepare_headers(&data->set.mimepost, NULL, + NULL, MIMESTRATEGY_MAIL); + + if(!result) + if(!Curl_checkheaders(conn, "Mime-Version")) + result = Curl_mime_add_header(&data->set.mimepost.curlheaders, + "Mime-Version: 1.0"); + + /* Make sure we will read the entire mime structure. */ + if(!result) + result = Curl_mime_rewind(&data->set.mimepost); + + if(result) + return result; + + data->state.infilesize = Curl_mime_size(&data->set.mimepost); + + /* Read from mime structure. */ + data->state.fread_func = (curl_read_callback) Curl_mime_read; + data->state.in = (void *) &data->set.mimepost; + } + + /* Check we know the size of the upload */ + if(data->state.infilesize < 0) { + failf(data, "Cannot APPEND with unknown input file size\n"); + return CURLE_UPLOAD_FAILED; + } + + /* Make sure the mailbox is in the correct atom format */ + mailbox = imap_atom(imap->mailbox, false); + if(!mailbox) + return CURLE_OUT_OF_MEMORY; + + /* Send the APPEND command */ + result = imap_sendf(conn, "APPEND %s (\\Seen) {%" CURL_FORMAT_CURL_OFF_T "}", + mailbox, data->state.infilesize); + + free(mailbox); + + if(!result) + state(conn, IMAP_APPEND); + + return result; +} + +/*********************************************************************** + * + * imap_perform_search() + * + * Sends a SEARCH command. + */ +static CURLcode imap_perform_search(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct IMAP *imap = conn->data->req.protop; + + /* Check we have a query string */ + if(!imap->query) { + failf(conn->data, "Cannot SEARCH without a query string."); + return CURLE_URL_MALFORMAT; + } + + /* Send the SEARCH command */ + result = imap_sendf(conn, "SEARCH %s", imap->query); + + if(!result) + state(conn, IMAP_SEARCH); + + return result; +} + +/*********************************************************************** + * + * imap_perform_logout() + * + * Performs the logout action prior to sclose() being called. + */ +static CURLcode imap_perform_logout(struct connectdata *conn) +{ + /* Send the LOGOUT command */ + CURLcode result = imap_sendf(conn, "LOGOUT"); + + if(!result) + state(conn, IMAP_LOGOUT); + + return result; +} + +/* For the initial server greeting */ +static CURLcode imap_state_servergreet_resp(struct connectdata *conn, + int imapcode, + imapstate instate) +{ + struct Curl_easy *data = conn->data; + (void)instate; /* no use for this yet */ + + if(imapcode == IMAP_RESP_PREAUTH) { + /* PREAUTH */ + struct imap_conn *imapc = &conn->proto.imapc; + imapc->preauth = TRUE; + infof(data, "PREAUTH connection, already authenticated!\n"); + } + else if(imapcode != IMAP_RESP_OK) { + failf(data, "Got unexpected imap-server response"); + return CURLE_WEIRD_SERVER_REPLY; + } + + return imap_perform_capability(conn); +} + +/* For CAPABILITY responses */ +static CURLcode imap_state_capability_resp(struct connectdata *conn, + int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct imap_conn *imapc = &conn->proto.imapc; + const char *line = data->state.buffer; + + (void)instate; /* no use for this yet */ + + /* Do we have a untagged response? */ + if(imapcode == '*') { + line += 2; + + /* Loop through the data line */ + for(;;) { + size_t wordlen; + while(*line && + (*line == ' ' || *line == '\t' || + *line == '\r' || *line == '\n')) { + + line++; + } + + if(!*line) + break; + + /* Extract the word */ + for(wordlen = 0; line[wordlen] && line[wordlen] != ' ' && + line[wordlen] != '\t' && line[wordlen] != '\r' && + line[wordlen] != '\n';) + wordlen++; + + /* Does the server support the STARTTLS capability? */ + if(wordlen == 8 && !memcmp(line, "STARTTLS", 8)) + imapc->tls_supported = TRUE; + + /* Has the server explicitly disabled clear text authentication? */ + else if(wordlen == 13 && !memcmp(line, "LOGINDISABLED", 13)) + imapc->login_disabled = TRUE; + + /* Does the server support the SASL-IR capability? */ + else if(wordlen == 7 && !memcmp(line, "SASL-IR", 7)) + imapc->ir_supported = TRUE; + + /* Do we have a SASL based authentication mechanism? */ + else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) { + size_t llen; + unsigned int mechbit; + + line += 5; + wordlen -= 5; + + /* Test the word for a matching authentication mechanism */ + mechbit = Curl_sasl_decode_mech(line, wordlen, &llen); + if(mechbit && llen == wordlen) + imapc->sasl.authmechs |= mechbit; + } + + line += wordlen; + } + } + else if(imapcode == IMAP_RESP_OK) { + if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { + /* We don't have a SSL/TLS connection yet, but SSL is requested */ + if(imapc->tls_supported) + /* Switch to TLS connection now */ + result = imap_perform_starttls(conn); + else if(data->set.use_ssl == CURLUSESSL_TRY) + /* Fallback and carry on with authentication */ + result = imap_perform_authentication(conn); + else { + failf(data, "STARTTLS not supported."); + result = CURLE_USE_SSL_FAILED; + } + } + else + result = imap_perform_authentication(conn); + } + else + result = imap_perform_authentication(conn); + + return result; +} + +/* For STARTTLS responses */ +static CURLcode imap_state_starttls_resp(struct connectdata *conn, + int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + (void)instate; /* no use for this yet */ + + if(imapcode != IMAP_RESP_OK) { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied"); + result = CURLE_USE_SSL_FAILED; + } + else + result = imap_perform_authentication(conn); + } + else + result = imap_perform_upgrade_tls(conn); + + return result; +} + +/* For SASL authentication responses */ +static CURLcode imap_state_auth_resp(struct connectdata *conn, + int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct imap_conn *imapc = &conn->proto.imapc; + saslprogress progress; + + (void)instate; /* no use for this yet */ + + result = Curl_sasl_continue(&imapc->sasl, conn, imapcode, &progress); + if(!result) + switch(progress) { + case SASL_DONE: + state(conn, IMAP_STOP); /* Authenticated */ + break; + case SASL_IDLE: /* No mechanism left after cancellation */ + if((!imapc->login_disabled) && (imapc->preftype & IMAP_TYPE_CLEARTEXT)) + /* Perform clear text authentication */ + result = imap_perform_login(conn); + else { + failf(data, "Authentication cancelled"); + result = CURLE_LOGIN_DENIED; + } + break; + default: + break; + } + + return result; +} + +/* For LOGIN responses */ +static CURLcode imap_state_login_resp(struct connectdata *conn, + int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + (void)instate; /* no use for this yet */ + + if(imapcode != IMAP_RESP_OK) { + failf(data, "Access denied. %c", imapcode); + result = CURLE_LOGIN_DENIED; + } + else + /* End of connect phase */ + state(conn, IMAP_STOP); + + return result; +} + +/* For LIST and SEARCH responses */ +static CURLcode imap_state_listsearch_resp(struct connectdata *conn, + int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + char *line = conn->data->state.buffer; + size_t len = strlen(line); + + (void)instate; /* No use for this yet */ + + if(imapcode == '*') { + /* Temporarily add the LF character back and send as body to the client */ + line[len] = '\n'; + result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1); + line[len] = '\0'; + } + else if(imapcode != IMAP_RESP_OK) + result = CURLE_QUOTE_ERROR; + else + /* End of DO phase */ + state(conn, IMAP_STOP); + + return result; +} + +/* For SELECT responses */ +static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct IMAP *imap = conn->data->req.protop; + struct imap_conn *imapc = &conn->proto.imapc; + const char *line = data->state.buffer; + + (void)instate; /* no use for this yet */ + + if(imapcode == '*') { + /* See if this is an UIDVALIDITY response */ + char tmp[20]; + if(sscanf(line + 2, "OK [UIDVALIDITY %19[0123456789]]", tmp) == 1) { + Curl_safefree(imapc->mailbox_uidvalidity); + imapc->mailbox_uidvalidity = strdup(tmp); + } + } + else if(imapcode == IMAP_RESP_OK) { + /* Check if the UIDVALIDITY has been specified and matches */ + if(imap->uidvalidity && imapc->mailbox_uidvalidity && + !strcasecompare(imap->uidvalidity, imapc->mailbox_uidvalidity)) { + failf(conn->data, "Mailbox UIDVALIDITY has changed"); + result = CURLE_REMOTE_FILE_NOT_FOUND; + } + else { + /* Note the currently opened mailbox on this connection */ + imapc->mailbox = strdup(imap->mailbox); + + if(imap->custom) + result = imap_perform_list(conn); + else if(imap->query) + result = imap_perform_search(conn); + else + result = imap_perform_fetch(conn); + } + } + else { + failf(data, "Select failed"); + result = CURLE_LOGIN_DENIED; + } + + return result; +} + +/* For the (first line of the) FETCH responses */ +static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct imap_conn *imapc = &conn->proto.imapc; + struct pingpong *pp = &imapc->pp; + const char *ptr = data->state.buffer; + bool parsed = FALSE; + curl_off_t size = 0; + + (void)instate; /* no use for this yet */ + + if(imapcode != '*') { + Curl_pgrsSetDownloadSize(data, -1); + state(conn, IMAP_STOP); + return CURLE_REMOTE_FILE_NOT_FOUND; + } + + /* Something like this is received "* 1 FETCH (BODY[TEXT] {2021}\r" so parse + the continuation data contained within the curly brackets */ + while(*ptr && (*ptr != '{')) + ptr++; + + if(*ptr == '{') { + char *endptr; + if(!curlx_strtoofft(ptr + 1, &endptr, 10, &size)) { + if(endptr - ptr > 1 && endptr[0] == '}' && + endptr[1] == '\r' && endptr[2] == '\0') + parsed = TRUE; + } + } + + if(parsed) { + infof(data, "Found %" CURL_FORMAT_CURL_OFF_T " bytes to download\n", + size); + Curl_pgrsSetDownloadSize(data, size); + + if(pp->cache) { + /* At this point there is a bunch of data in the header "cache" that is + actually body content, send it as body and then skip it. Do note + that there may even be additional "headers" after the body. */ + size_t chunk = pp->cache_size; + + if(chunk > (size_t)size) + /* The conversion from curl_off_t to size_t is always fine here */ + chunk = (size_t)size; + + if(!chunk) { + /* no size, we're done with the data */ + state(conn, IMAP_STOP); + return CURLE_OK; + } + result = Curl_client_write(conn, CLIENTWRITE_BODY, pp->cache, chunk); + if(result) + return result; + + data->req.bytecount += chunk; + + infof(data, "Written %zu bytes, %" CURL_FORMAT_CURL_OFF_TU + " bytes are left for transfer\n", chunk, size - chunk); + + /* Have we used the entire cache or just part of it?*/ + if(pp->cache_size > chunk) { + /* Only part of it so shrink the cache to fit the trailing data */ + memmove(pp->cache, pp->cache + chunk, pp->cache_size - chunk); + pp->cache_size -= chunk; + } + else { + /* Free the cache */ + Curl_safefree(pp->cache); + + /* Reset the cache size */ + pp->cache_size = 0; + } + } + + if(data->req.bytecount == size) + /* The entire data is already transferred! */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + else { + /* IMAP download */ + data->req.maxdownload = size; + Curl_setup_transfer(data, FIRSTSOCKET, size, FALSE, -1); + } + } + else { + /* We don't know how to parse this line */ + failf(pp->conn->data, "Failed to parse FETCH response."); + result = CURLE_WEIRD_SERVER_REPLY; + } + + /* End of DO phase */ + state(conn, IMAP_STOP); + + return result; +} + +/* For final FETCH responses performed after the download */ +static CURLcode imap_state_fetch_final_resp(struct connectdata *conn, + int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + + (void)instate; /* No use for this yet */ + + if(imapcode != IMAP_RESP_OK) + result = CURLE_WEIRD_SERVER_REPLY; + else + /* End of DONE phase */ + state(conn, IMAP_STOP); + + return result; +} + +/* For APPEND responses */ +static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + (void)instate; /* No use for this yet */ + + if(imapcode != '+') { + result = CURLE_UPLOAD_FAILED; + } + else { + /* Set the progress upload size */ + Curl_pgrsSetUploadSize(data, data->state.infilesize); + + /* IMAP upload */ + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); + + /* End of DO phase */ + state(conn, IMAP_STOP); + } + + return result; +} + +/* For final APPEND responses performed after the upload */ +static CURLcode imap_state_append_final_resp(struct connectdata *conn, + int imapcode, + imapstate instate) +{ + CURLcode result = CURLE_OK; + + (void)instate; /* No use for this yet */ + + if(imapcode != IMAP_RESP_OK) + result = CURLE_UPLOAD_FAILED; + else + /* End of DONE phase */ + state(conn, IMAP_STOP); + + return result; +} + +static CURLcode imap_statemach_act(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + int imapcode; + struct imap_conn *imapc = &conn->proto.imapc; + struct pingpong *pp = &imapc->pp; + size_t nread = 0; + + /* Busy upgrading the connection; right now all I/O is SSL/TLS, not IMAP */ + if(imapc->state == IMAP_UPGRADETLS) + return imap_perform_upgrade_tls(conn); + + /* Flush any data that needs to be sent */ + if(pp->sendleft) + return Curl_pp_flushsend(pp); + + do { + /* Read the response from the server */ + result = Curl_pp_readresp(sock, pp, &imapcode, &nread); + if(result) + return result; + + /* Was there an error parsing the response line? */ + if(imapcode == -1) + return CURLE_WEIRD_SERVER_REPLY; + + if(!imapcode) + break; + + /* We have now received a full IMAP server response */ + switch(imapc->state) { + case IMAP_SERVERGREET: + result = imap_state_servergreet_resp(conn, imapcode, imapc->state); + break; + + case IMAP_CAPABILITY: + result = imap_state_capability_resp(conn, imapcode, imapc->state); + break; + + case IMAP_STARTTLS: + result = imap_state_starttls_resp(conn, imapcode, imapc->state); + break; + + case IMAP_AUTHENTICATE: + result = imap_state_auth_resp(conn, imapcode, imapc->state); + break; + + case IMAP_LOGIN: + result = imap_state_login_resp(conn, imapcode, imapc->state); + break; + + case IMAP_LIST: + result = imap_state_listsearch_resp(conn, imapcode, imapc->state); + break; + + case IMAP_SELECT: + result = imap_state_select_resp(conn, imapcode, imapc->state); + break; + + case IMAP_FETCH: + result = imap_state_fetch_resp(conn, imapcode, imapc->state); + break; + + case IMAP_FETCH_FINAL: + result = imap_state_fetch_final_resp(conn, imapcode, imapc->state); + break; + + case IMAP_APPEND: + result = imap_state_append_resp(conn, imapcode, imapc->state); + break; + + case IMAP_APPEND_FINAL: + result = imap_state_append_final_resp(conn, imapcode, imapc->state); + break; + + case IMAP_SEARCH: + result = imap_state_listsearch_resp(conn, imapcode, imapc->state); + break; + + case IMAP_LOGOUT: + /* fallthrough, just stop! */ + default: + /* internal error */ + state(conn, IMAP_STOP); + break; + } + } while(!result && imapc->state != IMAP_STOP && Curl_pp_moredata(pp)); + + return result; +} + +/* Called repeatedly until done from multi.c */ +static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + struct imap_conn *imapc = &conn->proto.imapc; + + if((conn->handler->flags & PROTOPT_SSL) && !imapc->ssldone) { + result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone); + if(result || !imapc->ssldone) + return result; + } + + result = Curl_pp_statemach(&imapc->pp, FALSE, FALSE); + *done = (imapc->state == IMAP_STOP) ? TRUE : FALSE; + + return result; +} + +static CURLcode imap_block_statemach(struct connectdata *conn, + bool disconnecting) +{ + CURLcode result = CURLE_OK; + struct imap_conn *imapc = &conn->proto.imapc; + + while(imapc->state != IMAP_STOP && !result) + result = Curl_pp_statemach(&imapc->pp, TRUE, disconnecting); + + return result; +} + +/* Allocate and initialize the struct IMAP for the current Curl_easy if + required */ +static CURLcode imap_init(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct IMAP *imap; + + imap = data->req.protop = calloc(sizeof(struct IMAP), 1); + if(!imap) + result = CURLE_OUT_OF_MEMORY; + + return result; +} + +/* For the IMAP "protocol connect" and "doing" phases only */ +static int imap_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks) +{ + return Curl_pp_getsock(&conn->proto.imapc.pp, socks, numsocks); +} + +/*********************************************************************** + * + * imap_connect() + * + * This function should do everything that is to be considered a part of the + * connection phase. + * + * The variable 'done' points to will be TRUE if the protocol-layer connect + * phase is done when this function returns, or FALSE if not. + */ +static CURLcode imap_connect(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + struct imap_conn *imapc = &conn->proto.imapc; + struct pingpong *pp = &imapc->pp; + + *done = FALSE; /* default to not done yet */ + + /* We always support persistent connections in IMAP */ + connkeep(conn, "IMAP default"); + + /* Set the default response time-out */ + pp->response_time = RESP_TIMEOUT; + pp->statemach_act = imap_statemach_act; + pp->endofresp = imap_endofresp; + pp->conn = conn; + + /* Set the default preferred authentication type and mechanism */ + imapc->preftype = IMAP_TYPE_ANY; + Curl_sasl_init(&imapc->sasl, &saslimap); + + /* Initialise the pingpong layer */ + Curl_pp_init(pp); + + /* Parse the URL options */ + result = imap_parse_url_options(conn); + if(result) + return result; + + /* Start off waiting for the server greeting response */ + state(conn, IMAP_SERVERGREET); + + /* Start off with an response id of '*' */ + strcpy(imapc->resptag, "*"); + + result = imap_multi_statemach(conn, done); + + return result; +} + +/*********************************************************************** + * + * imap_done() + * + * The DONE function. This does what needs to be done after a single DO has + * performed. + * + * Input argument is already checked for validity. + */ +static CURLcode imap_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct IMAP *imap = data->req.protop; + + (void)premature; + + if(!imap) + return CURLE_OK; + + if(status) { + connclose(conn, "IMAP done with bad status"); /* marked for closure */ + result = status; /* use the already set error code */ + } + else if(!data->set.connect_only && !imap->custom && + (imap->uid || imap->mindex || data->set.upload || + data->set.mimepost.kind != MIMEKIND_NONE)) { + /* Handle responses after FETCH or APPEND transfer has finished */ + + if(!data->set.upload && data->set.mimepost.kind == MIMEKIND_NONE) + state(conn, IMAP_FETCH_FINAL); + else { + /* End the APPEND command first by sending an empty line */ + result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", ""); + if(!result) + state(conn, IMAP_APPEND_FINAL); + } + + /* Run the state-machine */ + if(!result) + result = imap_block_statemach(conn, FALSE); + } + + /* Cleanup our per-request based variables */ + Curl_safefree(imap->mailbox); + Curl_safefree(imap->uidvalidity); + Curl_safefree(imap->uid); + Curl_safefree(imap->mindex); + Curl_safefree(imap->section); + Curl_safefree(imap->partial); + Curl_safefree(imap->query); + Curl_safefree(imap->custom); + Curl_safefree(imap->custom_params); + + /* Clear the transfer mode for the next request */ + imap->transfer = FTPTRANSFER_BODY; + + return result; +} + +/*********************************************************************** + * + * imap_perform() + * + * This is the actual DO function for IMAP. Fetch or append a message, or do + * other things according to the options previously setup. + */ +static CURLcode imap_perform(struct connectdata *conn, bool *connected, + bool *dophase_done) +{ + /* This is IMAP and no proxy */ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct IMAP *imap = data->req.protop; + struct imap_conn *imapc = &conn->proto.imapc; + bool selected = FALSE; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + if(conn->data->set.opt_no_body) { + /* Requested no body means no transfer */ + imap->transfer = FTPTRANSFER_INFO; + } + + *dophase_done = FALSE; /* not done yet */ + + /* Determine if the requested mailbox (with the same UIDVALIDITY if set) + has already been selected on this connection */ + if(imap->mailbox && imapc->mailbox && + strcasecompare(imap->mailbox, imapc->mailbox) && + (!imap->uidvalidity || !imapc->mailbox_uidvalidity || + strcasecompare(imap->uidvalidity, imapc->mailbox_uidvalidity))) + selected = TRUE; + + /* Start the first command in the DO phase */ + if(conn->data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE) + /* APPEND can be executed directly */ + result = imap_perform_append(conn); + else if(imap->custom && (selected || !imap->mailbox)) + /* Custom command using the same mailbox or no mailbox */ + result = imap_perform_list(conn); + else if(!imap->custom && selected && (imap->uid || imap->mindex)) + /* FETCH from the same mailbox */ + result = imap_perform_fetch(conn); + else if(!imap->custom && selected && imap->query) + /* SEARCH the current mailbox */ + result = imap_perform_search(conn); + else if(imap->mailbox && !selected && + (imap->custom || imap->uid || imap->mindex || imap->query)) + /* SELECT the mailbox */ + result = imap_perform_select(conn); + else + /* LIST */ + result = imap_perform_list(conn); + + if(result) + return result; + + /* Run the state-machine */ + result = imap_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) + DEBUGF(infof(conn->data, "DO phase is complete\n")); + + return result; +} + +/*********************************************************************** + * + * imap_do() + * + * This function is registered as 'curl_do' function. It decodes the path + * parts etc as a wrapper to the actual DO function (imap_perform). + * + * The input argument is already checked for validity. + */ +static CURLcode imap_do(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + + *done = FALSE; /* default to false */ + + /* Parse the URL path */ + result = imap_parse_url_path(conn); + if(result) + return result; + + /* Parse the custom request */ + result = imap_parse_custom_request(conn); + if(result) + return result; + + result = imap_regular_transfer(conn, done); + + return result; +} + +/*********************************************************************** + * + * imap_disconnect() + * + * Disconnect from an IMAP server. Cleanup protocol-specific per-connection + * resources. BLOCKING. + */ +static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection) +{ + struct imap_conn *imapc = &conn->proto.imapc; + + /* We cannot send quit unconditionally. If this connection is stale or + bad in any way, sending quit and waiting around here will make the + disconnect wait in vain and cause more problems than we need to. */ + + /* The IMAP session may or may not have been allocated/setup at this + point! */ + if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart) + if(!imap_perform_logout(conn)) + (void)imap_block_statemach(conn, TRUE); /* ignore errors on LOGOUT */ + + /* Disconnect from the server */ + Curl_pp_disconnect(&imapc->pp); + + /* Cleanup the SASL module */ + Curl_sasl_cleanup(conn, imapc->sasl.authused); + + /* Cleanup our connection based variables */ + Curl_safefree(imapc->mailbox); + Curl_safefree(imapc->mailbox_uidvalidity); + + return CURLE_OK; +} + +/* Call this when the DO phase has completed */ +static CURLcode imap_dophase_done(struct connectdata *conn, bool connected) +{ + struct IMAP *imap = conn->data->req.protop; + + (void)connected; + + if(imap->transfer != FTPTRANSFER_BODY) + /* no data to transfer */ + Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); + + return CURLE_OK; +} + +/* Called from multi.c while DOing */ +static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done) +{ + CURLcode result = imap_multi_statemach(conn, dophase_done); + + if(result) + DEBUGF(infof(conn->data, "DO phase failed\n")); + else if(*dophase_done) { + result = imap_dophase_done(conn, FALSE /* not connected */); + + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +/*********************************************************************** + * + * imap_regular_transfer() + * + * The input argument is already checked for validity. + * + * Performs all commands done before a regular transfer between a local and a + * remote host. + */ +static CURLcode imap_regular_transfer(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result = CURLE_OK; + bool connected = FALSE; + struct Curl_easy *data = conn->data; + + /* Make sure size is unknown at this point */ + data->req.size = -1; + + /* Set the progress data */ + Curl_pgrsSetUploadCounter(data, 0); + Curl_pgrsSetDownloadCounter(data, 0); + Curl_pgrsSetUploadSize(data, -1); + Curl_pgrsSetDownloadSize(data, -1); + + /* Carry out the perform */ + result = imap_perform(conn, &connected, dophase_done); + + /* Perform post DO phase operations if necessary */ + if(!result && *dophase_done) + result = imap_dophase_done(conn, connected); + + return result; +} + +static CURLcode imap_setup_connection(struct connectdata *conn) +{ + /* Initialise the IMAP layer */ + CURLcode result = imap_init(conn); + if(result) + return result; + + /* Clear the TLS upgraded flag */ + conn->tls_upgraded = FALSE; + + return CURLE_OK; +} + +/*********************************************************************** + * + * imap_sendf() + * + * Sends the formatted string as an IMAP command to the server. + * + * Designed to never block. + */ +static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...) +{ + CURLcode result = CURLE_OK; + struct imap_conn *imapc = &conn->proto.imapc; + char *taggedfmt; + va_list ap; + + DEBUGASSERT(fmt); + + /* Calculate the next command ID wrapping at 3 digits */ + imapc->cmdid = (imapc->cmdid + 1) % 1000; + + /* Calculate the tag based on the connection ID and command ID */ + msnprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d", + 'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid); + + /* Prefix the format with the tag */ + taggedfmt = aprintf("%s %s", imapc->resptag, fmt); + if(!taggedfmt) + return CURLE_OUT_OF_MEMORY; + + /* Send the data with the tag */ + va_start(ap, fmt); + result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap); + va_end(ap); + + free(taggedfmt); + + return result; +} + +/*********************************************************************** + * + * imap_atom() + * + * Checks the input string for characters that need escaping and returns an + * atom ready for sending to the server. + * + * The returned string needs to be freed. + * + */ +static char *imap_atom(const char *str, bool escape_only) +{ + /* !checksrc! disable PARENBRACE 1 */ + const char atom_specials[] = "(){ %*]"; + const char *p1; + char *p2; + size_t backsp_count = 0; + size_t quote_count = 0; + bool others_exists = FALSE; + size_t newlen = 0; + char *newstr = NULL; + + if(!str) + return NULL; + + /* Look for "atom-specials", counting the backslash and quote characters as + these will need escaping */ + p1 = str; + while(*p1) { + if(*p1 == '\\') + backsp_count++; + else if(*p1 == '"') + quote_count++; + else if(!escape_only) { + const char *p3 = atom_specials; + + while(*p3 && !others_exists) { + if(*p1 == *p3) + others_exists = TRUE; + + p3++; + } + } + + p1++; + } + + /* Does the input contain any "atom-special" characters? */ + if(!backsp_count && !quote_count && !others_exists) + return strdup(str); + + /* Calculate the new string length */ + newlen = strlen(str) + backsp_count + quote_count + (escape_only ? 0 : 2); + + /* Allocate the new string */ + newstr = (char *) malloc((newlen + 1) * sizeof(char)); + if(!newstr) + return NULL; + + /* Surround the string in quotes if necessary */ + p2 = newstr; + if(!escape_only) { + newstr[0] = '"'; + newstr[newlen - 1] = '"'; + p2++; + } + + /* Copy the string, escaping backslash and quote characters along the way */ + p1 = str; + while(*p1) { + if(*p1 == '\\' || *p1 == '"') { + *p2 = '\\'; + p2++; + } + + *p2 = *p1; + + p1++; + p2++; + } + + /* Terminate the string */ + newstr[newlen] = '\0'; + + return newstr; +} + +/*********************************************************************** + * + * imap_is_bchar() + * + * Portable test of whether the specified char is a "bchar" as defined in the + * grammar of RFC-5092. + */ +static bool imap_is_bchar(char ch) +{ + switch(ch) { + /* bchar */ + case ':': case '@': case '/': + /* bchar -> achar */ + case '&': case '=': + /* bchar -> achar -> uchar -> unreserved */ + case '0': case '1': case '2': case '3': case '4': case '5': case '6': + case '7': case '8': case '9': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': + case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': + case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': + case 'V': case 'W': case 'X': case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': + case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': + case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': + case 'v': case 'w': case 'x': case 'y': case 'z': + case '-': case '.': case '_': case '~': + /* bchar -> achar -> uchar -> sub-delims-sh */ + case '!': case '$': case '\'': case '(': case ')': case '*': + case '+': case ',': + /* bchar -> achar -> uchar -> pct-encoded */ + case '%': /* HEXDIG chars are already included above */ + return true; + + default: + return false; + } +} + +/*********************************************************************** + * + * imap_parse_url_options() + * + * Parse the URL login options. + */ +static CURLcode imap_parse_url_options(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct imap_conn *imapc = &conn->proto.imapc; + const char *ptr = conn->options; + + imapc->sasl.resetprefs = TRUE; + + while(!result && ptr && *ptr) { + const char *key = ptr; + const char *value; + + while(*ptr && *ptr != '=') + ptr++; + + value = ptr + 1; + + while(*ptr && *ptr != ';') + ptr++; + + if(strncasecompare(key, "AUTH=", 5)) + result = Curl_sasl_parse_url_auth_option(&imapc->sasl, + value, ptr - value); + else + result = CURLE_URL_MALFORMAT; + + if(*ptr == ';') + ptr++; + } + + switch(imapc->sasl.prefmech) { + case SASL_AUTH_NONE: + imapc->preftype = IMAP_TYPE_NONE; + break; + case SASL_AUTH_DEFAULT: + imapc->preftype = IMAP_TYPE_ANY; + break; + default: + imapc->preftype = IMAP_TYPE_SASL; + break; + } + + return result; +} + +/*********************************************************************** + * + * imap_parse_url_path() + * + * Parse the URL path into separate path components. + * + */ +static CURLcode imap_parse_url_path(struct connectdata *conn) +{ + /* The imap struct is already initialised in imap_connect() */ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct IMAP *imap = data->req.protop; + const char *begin = &data->state.up.path[1]; /* skip leading slash */ + const char *ptr = begin; + + /* See how much of the URL is a valid path and decode it */ + while(imap_is_bchar(*ptr)) + ptr++; + + if(ptr != begin) { + /* Remove the trailing slash if present */ + const char *end = ptr; + if(end > begin && end[-1] == '/') + end--; + + result = Curl_urldecode(data, begin, end - begin, &imap->mailbox, NULL, + TRUE); + if(result) + return result; + } + else + imap->mailbox = NULL; + + /* There can be any number of parameters in the form ";NAME=VALUE" */ + while(*ptr == ';') { + char *name; + char *value; + size_t valuelen; + + /* Find the length of the name parameter */ + begin = ++ptr; + while(*ptr && *ptr != '=') + ptr++; + + if(!*ptr) + return CURLE_URL_MALFORMAT; + + /* Decode the name parameter */ + result = Curl_urldecode(data, begin, ptr - begin, &name, NULL, TRUE); + if(result) + return result; + + /* Find the length of the value parameter */ + begin = ++ptr; + while(imap_is_bchar(*ptr)) + ptr++; + + /* Decode the value parameter */ + result = Curl_urldecode(data, begin, ptr - begin, &value, &valuelen, TRUE); + if(result) { + free(name); + return result; + } + + DEBUGF(infof(conn->data, "IMAP URL parameter '%s' = '%s'\n", name, value)); + + /* Process the known hierarchical parameters (UIDVALIDITY, UID, SECTION and + PARTIAL) stripping of the trailing slash character if it is present. + + Note: Unknown parameters trigger a URL_MALFORMAT error. */ + if(strcasecompare(name, "UIDVALIDITY") && !imap->uidvalidity) { + if(valuelen > 0 && value[valuelen - 1] == '/') + value[valuelen - 1] = '\0'; + + imap->uidvalidity = value; + value = NULL; + } + else if(strcasecompare(name, "UID") && !imap->uid) { + if(valuelen > 0 && value[valuelen - 1] == '/') + value[valuelen - 1] = '\0'; + + imap->uid = value; + value = NULL; + } + else if(strcasecompare(name, "MAILINDEX") && !imap->mindex) { + if(valuelen > 0 && value[valuelen - 1] == '/') + value[valuelen - 1] = '\0'; + + imap->mindex = value; + value = NULL; + } + else if(strcasecompare(name, "SECTION") && !imap->section) { + if(valuelen > 0 && value[valuelen - 1] == '/') + value[valuelen - 1] = '\0'; + + imap->section = value; + value = NULL; + } + else if(strcasecompare(name, "PARTIAL") && !imap->partial) { + if(valuelen > 0 && value[valuelen - 1] == '/') + value[valuelen - 1] = '\0'; + + imap->partial = value; + value = NULL; + } + else { + free(name); + free(value); + + return CURLE_URL_MALFORMAT; + } + + free(name); + free(value); + } + + /* Does the URL contain a query parameter? Only valid when we have a mailbox + and no UID as per RFC-5092 */ + if(imap->mailbox && !imap->uid && !imap->mindex) { + /* Get the query parameter, URL decoded */ + (void)curl_url_get(data->state.uh, CURLUPART_QUERY, &imap->query, + CURLU_URLDECODE); + } + + /* Any extra stuff at the end of the URL is an error */ + if(*ptr) + return CURLE_URL_MALFORMAT; + + return CURLE_OK; +} + +/*********************************************************************** + * + * imap_parse_custom_request() + * + * Parse the custom request. + */ +static CURLcode imap_parse_custom_request(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct IMAP *imap = data->req.protop; + const char *custom = data->set.str[STRING_CUSTOMREQUEST]; + + if(custom) { + /* URL decode the custom request */ + result = Curl_urldecode(data, custom, 0, &imap->custom, NULL, TRUE); + + /* Extract the parameters if specified */ + if(!result) { + const char *params = imap->custom; + + while(*params && *params != ' ') + params++; + + if(*params) { + imap->custom_params = strdup(params); + imap->custom[params - imap->custom] = '\0'; + + if(!imap->custom_params) + result = CURLE_OUT_OF_MEMORY; + } + } + } + + return result; +} + +#endif /* CURL_DISABLE_IMAP */ diff --git a/libcurl/lib/imap.h b/libcurl/lib/imap.h new file mode 100644 index 0000000..0efcfd2 --- /dev/null +++ b/libcurl/lib/imap.h @@ -0,0 +1,98 @@ +#ifndef HEADER_CURL_IMAP_H +#define HEADER_CURL_IMAP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2009 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "pingpong.h" +#include "curl_sasl.h" + +/**************************************************************************** + * IMAP unique setup + ***************************************************************************/ +typedef enum { + IMAP_STOP, /* do nothing state, stops the state machine */ + IMAP_SERVERGREET, /* waiting for the initial greeting immediately after + a connect */ + IMAP_CAPABILITY, + IMAP_STARTTLS, + IMAP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS + (multi mode only) */ + IMAP_AUTHENTICATE, + IMAP_LOGIN, + IMAP_LIST, + IMAP_SELECT, + IMAP_FETCH, + IMAP_FETCH_FINAL, + IMAP_APPEND, + IMAP_APPEND_FINAL, + IMAP_SEARCH, + IMAP_LOGOUT, + IMAP_LAST /* never used */ +} imapstate; + +/* This IMAP struct is used in the Curl_easy. All IMAP data that is + connection-oriented must be in imap_conn to properly deal with the fact that + perhaps the Curl_easy is changed between the times the connection is + used. */ +struct IMAP { + curl_pp_transfer transfer; + char *mailbox; /* Mailbox to select */ + char *uidvalidity; /* UIDVALIDITY to check in select */ + char *uid; /* Message UID to fetch */ + char *mindex; /* Index in mail box of mail to fetch */ + char *section; /* Message SECTION to fetch */ + char *partial; /* Message PARTIAL to fetch */ + char *query; /* Query to search for */ + char *custom; /* Custom request */ + char *custom_params; /* Parameters for the custom request */ +}; + +/* imap_conn is used for struct connection-oriented data in the connectdata + struct */ +struct imap_conn { + struct pingpong pp; + imapstate state; /* Always use imap.c:state() to change state! */ + bool ssldone; /* Is connect() over SSL done? */ + bool preauth; /* Is this connection PREAUTH? */ + struct SASL sasl; /* SASL-related parameters */ + unsigned int preftype; /* Preferred authentication type */ + int cmdid; /* Last used command ID */ + char resptag[5]; /* Response tag to wait for */ + bool tls_supported; /* StartTLS capability supported by server */ + bool login_disabled; /* LOGIN command disabled by server */ + bool ir_supported; /* Initial response supported by server */ + char *mailbox; /* The last selected mailbox */ + char *mailbox_uidvalidity; /* UIDVALIDITY parsed from select response */ +}; + +extern const struct Curl_handler Curl_handler_imap; +extern const struct Curl_handler Curl_handler_imaps; + +/* Authentication type flags */ +#define IMAP_TYPE_CLEARTEXT (1 << 0) +#define IMAP_TYPE_SASL (1 << 1) + +/* Authentication type values */ +#define IMAP_TYPE_NONE 0 +#define IMAP_TYPE_ANY ~0U + +#endif /* HEADER_CURL_IMAP_H */ diff --git a/libcurl/lib/inet_ntop.c b/libcurl/lib/inet_ntop.c new file mode 100644 index 0000000..855981c --- /dev/null +++ b/libcurl/lib/inet_ntop.c @@ -0,0 +1,197 @@ +/* + * Copyright (C) 1996-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * Original code by Paul Vixie. "curlified" by Gisle Vanem. + */ + +#include "curl_setup.h" + +#ifndef HAVE_INET_NTOP + +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#include "inet_ntop.h" +#include "curl_printf.h" + +#define IN6ADDRSZ 16 +#define INADDRSZ 4 +#define INT16SZ 2 + +/* + * Format an IPv4 address, more or less like inet_ntoa(). + * + * Returns `dst' (as a const) + * Note: + * - uses no statics + * - takes a unsigned char* not an in_addr as input + */ +static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size) +{ + char tmp[sizeof("255.255.255.255")]; + size_t len; + + DEBUGASSERT(size >= 16); + + tmp[0] = '\0'; + (void)msnprintf(tmp, sizeof(tmp), "%d.%d.%d.%d", + ((int)((unsigned char)src[0])) & 0xff, + ((int)((unsigned char)src[1])) & 0xff, + ((int)((unsigned char)src[2])) & 0xff, + ((int)((unsigned char)src[3])) & 0xff); + + len = strlen(tmp); + if(len == 0 || len >= size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return dst; +} + +#ifdef ENABLE_IPV6 +/* + * Convert IPv6 binary address into presentation (printable) format. + */ +static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; + char *tp; + struct { + long base; + long len; + } best, cur; + unsigned long words[IN6ADDRSZ / INT16SZ]; + int i; + + /* Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof(words)); + for(i = 0; i < IN6ADDRSZ; i++) + words[i/2] |= (src[i] << ((1 - (i % 2)) << 3)); + + best.base = -1; + cur.base = -1; + best.len = 0; + cur.len = 0; + + for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + if(words[i] == 0) { + if(cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } + else if(cur.base != -1) { + if(best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + if((cur.base != -1) && (best.base == -1 || cur.len > best.len)) + best = cur; + if(best.base != -1 && best.len < 2) + best.base = -1; + /* Format the result. */ + tp = tmp; + for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if(best.base != -1 && i >= best.base && i < (best.base + best.len)) { + if(i == best.base) + *tp++ = ':'; + continue; + } + + /* Are we following an initial run of 0x00s or any real hex? + */ + if(i != 0) + *tp++ = ':'; + + /* Is this address an encapsulated IPv4? + */ + if(i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if(!inet_ntop4(src + 12, tp, sizeof(tmp) - (tp - tmp))) { + errno = ENOSPC; + return (NULL); + } + tp += strlen(tp); + break; + } + tp += msnprintf(tp, 5, "%lx", words[i]); + } + + /* Was it a trailing run of 0x00's? + */ + if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* Check for overflow, copy, and we're done. + */ + if((size_t)(tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return dst; +} +#endif /* ENABLE_IPV6 */ + +/* + * Convert a network format address to presentation format. + * + * Returns pointer to presentation format address (`buf'). + * Returns NULL on error and errno set with the specific + * error, EAFNOSUPPORT or ENOSPC. + * + * On Windows we store the error in the thread errno, not + * in the winsock error code. This is to avoid losing the + * actual last winsock error. So when this function returns + * NULL, check errno not SOCKERRNO. + */ +char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size) +{ + switch(af) { + case AF_INET: + return inet_ntop4((const unsigned char *)src, buf, size); +#ifdef ENABLE_IPV6 + case AF_INET6: + return inet_ntop6((const unsigned char *)src, buf, size); +#endif + default: + errno = EAFNOSUPPORT; + return NULL; + } +} +#endif /* HAVE_INET_NTOP */ diff --git a/libcurl/lib/inet_ntop.h b/libcurl/lib/inet_ntop.h new file mode 100644 index 0000000..d150bb6 --- /dev/null +++ b/libcurl/lib/inet_ntop.h @@ -0,0 +1,37 @@ +#ifndef HEADER_CURL_INET_NTOP_H +#define HEADER_CURL_INET_NTOP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size); + +#ifdef HAVE_INET_NTOP +#ifdef HAVE_ARPA_INET_H +#include +#endif +#define Curl_inet_ntop(af,addr,buf,size) \ + inet_ntop(af, addr, buf, (curl_socklen_t)size) +#endif + +#endif /* HEADER_CURL_INET_NTOP_H */ diff --git a/libcurl/lib/inet_pton.c b/libcurl/lib/inet_pton.c new file mode 100644 index 0000000..0d65ae0 --- /dev/null +++ b/libcurl/lib/inet_pton.c @@ -0,0 +1,237 @@ +/* This is from the BIND 4.9.4 release, modified to compile by itself */ + +/* Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include "curl_setup.h" + +#ifndef HAVE_INET_PTON + +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#include "inet_pton.h" + +#define IN6ADDRSZ 16 +#define INADDRSZ 4 +#define INT16SZ 2 + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static int inet_pton4(const char *src, unsigned char *dst); +#ifdef ENABLE_IPV6 +static int inet_pton6(const char *src, unsigned char *dst); +#endif + +/* int + * inet_pton(af, src, dst) + * convert from presentation format (which usually means ASCII printable) + * to network format (which is usually some kind of binary format). + * return: + * 1 if the address was valid for the specified address family + * 0 if the address wasn't valid (`dst' is untouched in this case) + * -1 if some other error occurred (`dst' is untouched in this case, too) + * notice: + * On Windows we store the error in the thread errno, not + * in the winsock error code. This is to avoid losing the + * actual last winsock error. So when this function returns + * -1, check errno not SOCKERRNO. + * author: + * Paul Vixie, 1996. + */ +int +Curl_inet_pton(int af, const char *src, void *dst) +{ + switch(af) { + case AF_INET: + return (inet_pton4(src, (unsigned char *)dst)); +#ifdef ENABLE_IPV6 + case AF_INET6: + return (inet_pton6(src, (unsigned char *)dst)); +#endif + default: + errno = EAFNOSUPPORT; + return (-1); + } + /* NOTREACHED */ +} + +/* int + * inet_pton4(src, dst) + * like inet_aton() but without all the hexadecimal and shorthand. + * return: + * 1 if `src' is a valid dotted quad, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton4(const char *src, unsigned char *dst) +{ + static const char digits[] = "0123456789"; + int saw_digit, octets, ch; + unsigned char tmp[INADDRSZ], *tp; + + saw_digit = 0; + octets = 0; + tp = tmp; + *tp = 0; + while((ch = *src++) != '\0') { + const char *pch; + + pch = strchr(digits, ch); + if(pch) { + unsigned int val = *tp * 10 + (unsigned int)(pch - digits); + + if(saw_digit && *tp == 0) + return (0); + if(val > 255) + return (0); + *tp = (unsigned char)val; + if(! saw_digit) { + if(++octets > 4) + return (0); + saw_digit = 1; + } + } + else if(ch == '.' && saw_digit) { + if(octets == 4) + return (0); + *++tp = 0; + saw_digit = 0; + } + else + return (0); + } + if(octets < 4) + return (0); + memcpy(dst, tmp, INADDRSZ); + return (1); +} + +#ifdef ENABLE_IPV6 +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * (1) does not touch `dst' unless it's returning 1. + * (2) :: in a full address is silently ignored. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton6(const char *src, unsigned char *dst) +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp; + const char *curtok; + int ch, saw_xdigit; + size_t val; + + memset((tp = tmp), 0, IN6ADDRSZ); + endp = tp + IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if(*src == ':') + if(*++src != ':') + return (0); + curtok = src; + saw_xdigit = 0; + val = 0; + while((ch = *src++) != '\0') { + const char *xdigits; + const char *pch; + + pch = strchr((xdigits = xdigits_l), ch); + if(!pch) + pch = strchr((xdigits = xdigits_u), ch); + if(pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if(++saw_xdigit > 4) + return (0); + continue; + } + if(ch == ':') { + curtok = src; + if(!saw_xdigit) { + if(colonp) + return (0); + colonp = tp; + continue; + } + if(tp + INT16SZ > endp) + return (0); + *tp++ = (unsigned char) ((val >> 8) & 0xff); + *tp++ = (unsigned char) (val & 0xff); + saw_xdigit = 0; + val = 0; + continue; + } + if(ch == '.' && ((tp + INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if(saw_xdigit) { + if(tp + INT16SZ > endp) + return (0); + *tp++ = (unsigned char) ((val >> 8) & 0xff); + *tp++ = (unsigned char) (val & 0xff); + } + if(colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const ssize_t n = tp - colonp; + ssize_t i; + + if(tp == endp) + return (0); + for(i = 1; i <= n; i++) { + *(endp - i) = *(colonp + n - i); + *(colonp + n - i) = 0; + } + tp = endp; + } + if(tp != endp) + return (0); + memcpy(dst, tmp, IN6ADDRSZ); + return (1); +} +#endif /* ENABLE_IPV6 */ + +#endif /* HAVE_INET_PTON */ diff --git a/libcurl/lib/inet_pton.h b/libcurl/lib/inet_pton.h new file mode 100644 index 0000000..0209b9b --- /dev/null +++ b/libcurl/lib/inet_pton.h @@ -0,0 +1,39 @@ +#ifndef HEADER_CURL_INET_PTON_H +#define HEADER_CURL_INET_PTON_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +int Curl_inet_pton(int, const char *, void *); + +#ifdef HAVE_INET_PTON +#ifdef HAVE_ARPA_INET_H +#include +#elif defined(HAVE_WS2TCPIP_H) +/* inet_pton() exists in Vista or later */ +#include +#endif +#define Curl_inet_pton(x,y,z) inet_pton(x,y,z) +#endif + +#endif /* HEADER_CURL_INET_PTON_H */ diff --git a/libcurl/lib/krb5.c b/libcurl/lib/krb5.c new file mode 100644 index 0000000..5a47d48 --- /dev/null +++ b/libcurl/lib/krb5.c @@ -0,0 +1,341 @@ +/* GSSAPI/krb5 support for FTP - loosely based on old krb4.c + * + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * Copyright (c) 2004 - 2017 Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ + +#include "curl_setup.h" + +#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_FTP) + +#ifdef HAVE_NETDB_H +#include +#endif + +#include "urldata.h" +#include "curl_base64.h" +#include "ftp.h" +#include "curl_gssapi.h" +#include "sendf.h" +#include "curl_sec.h" +#include "warnless.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +static int +krb5_init(void *app_data) +{ + gss_ctx_id_t *context = app_data; + /* Make sure our context is initialized for krb5_end. */ + *context = GSS_C_NO_CONTEXT; + return 0; +} + +static int +krb5_check_prot(void *app_data, int level) +{ + (void)app_data; /* unused */ + if(level == PROT_CONFIDENTIAL) + return -1; + return 0; +} + +static int +krb5_decode(void *app_data, void *buf, int len, + int level UNUSED_PARAM, + struct connectdata *conn UNUSED_PARAM) +{ + gss_ctx_id_t *context = app_data; + OM_uint32 maj, min; + gss_buffer_desc enc, dec; + + (void)level; + (void)conn; + + enc.value = buf; + enc.length = len; + maj = gss_unwrap(&min, *context, &enc, &dec, NULL, NULL); + if(maj != GSS_S_COMPLETE) { + if(len >= 4) + strcpy(buf, "599 "); + return -1; + } + + memcpy(buf, dec.value, dec.length); + len = curlx_uztosi(dec.length); + gss_release_buffer(&min, &dec); + + return len; +} + +static int +krb5_overhead(void *app_data, int level, int len) +{ + /* no arguments are used */ + (void)app_data; + (void)level; + (void)len; + return 0; +} + +static int +krb5_encode(void *app_data, const void *from, int length, int level, void **to) +{ + gss_ctx_id_t *context = app_data; + gss_buffer_desc dec, enc; + OM_uint32 maj, min; + int state; + int len; + + /* NOTE that the cast is safe, neither of the krb5, gnu gss and heimdal + * libraries modify the input buffer in gss_wrap() + */ + dec.value = (void *)from; + dec.length = length; + maj = gss_wrap(&min, *context, + level == PROT_PRIVATE, + GSS_C_QOP_DEFAULT, + &dec, &state, &enc); + + if(maj != GSS_S_COMPLETE) + return -1; + + /* malloc a new buffer, in case gss_release_buffer doesn't work as + expected */ + *to = malloc(enc.length); + if(!*to) + return -1; + memcpy(*to, enc.value, enc.length); + len = curlx_uztosi(enc.length); + gss_release_buffer(&min, &enc); + return len; +} + +static int +krb5_auth(void *app_data, struct connectdata *conn) +{ + int ret = AUTH_OK; + char *p; + const char *host = conn->host.name; + ssize_t nread; + curl_socklen_t l = sizeof(conn->local_addr); + struct Curl_easy *data = conn->data; + CURLcode result; + const char *service = data->set.str[STRING_SERVICE_NAME] ? + data->set.str[STRING_SERVICE_NAME] : + "ftp"; + const char *srv_host = "host"; + gss_buffer_desc input_buffer, output_buffer, _gssresp, *gssresp; + OM_uint32 maj, min; + gss_name_t gssname; + gss_ctx_id_t *context = app_data; + struct gss_channel_bindings_struct chan; + size_t base64_sz = 0; + struct sockaddr_in **remote_addr = + (struct sockaddr_in **)&conn->ip_addr->ai_addr; + char *stringp; + + if(getsockname(conn->sock[FIRSTSOCKET], + (struct sockaddr *)&conn->local_addr, &l) < 0) + perror("getsockname()"); + + chan.initiator_addrtype = GSS_C_AF_INET; + chan.initiator_address.length = l - 4; + chan.initiator_address.value = &conn->local_addr.sin_addr.s_addr; + chan.acceptor_addrtype = GSS_C_AF_INET; + chan.acceptor_address.length = l - 4; + chan.acceptor_address.value = &(*remote_addr)->sin_addr.s_addr; + chan.application_data.length = 0; + chan.application_data.value = NULL; + + /* this loop will execute twice (once for service, once for host) */ + for(;;) { + /* this really shouldn't be repeated here, but can't help it */ + if(service == srv_host) { + result = Curl_ftpsend(conn, "AUTH GSSAPI"); + if(result) + return -2; + + if(Curl_GetFTPResponse(&nread, conn, NULL)) + return -1; + + if(data->state.buffer[0] != '3') + return -1; + } + + stringp = aprintf("%s@%s", service, host); + if(!stringp) + return -2; + + input_buffer.value = stringp; + input_buffer.length = strlen(stringp); + maj = gss_import_name(&min, &input_buffer, GSS_C_NT_HOSTBASED_SERVICE, + &gssname); + free(stringp); + if(maj != GSS_S_COMPLETE) { + gss_release_name(&min, &gssname); + if(service == srv_host) { + failf(data, "Error importing service name %s@%s", service, host); + return AUTH_ERROR; + } + service = srv_host; + continue; + } + /* We pass NULL as |output_name_type| to avoid a leak. */ + gss_display_name(&min, gssname, &output_buffer, NULL); + Curl_infof(data, "Trying against %s\n", output_buffer.value); + gssresp = GSS_C_NO_BUFFER; + *context = GSS_C_NO_CONTEXT; + + do { + /* Release the buffer at each iteration to avoid leaking: the first time + we are releasing the memory from gss_display_name. The last item is + taken care by a final gss_release_buffer. */ + gss_release_buffer(&min, &output_buffer); + ret = AUTH_OK; + maj = Curl_gss_init_sec_context(data, + &min, + context, + gssname, + &Curl_krb5_mech_oid, + &chan, + gssresp, + &output_buffer, + TRUE, + NULL); + + if(gssresp) { + free(_gssresp.value); + gssresp = NULL; + } + + if(GSS_ERROR(maj)) { + Curl_infof(data, "Error creating security context\n"); + ret = AUTH_ERROR; + break; + } + + if(output_buffer.length != 0) { + char *cmd; + + result = Curl_base64_encode(data, (char *)output_buffer.value, + output_buffer.length, &p, &base64_sz); + if(result) { + Curl_infof(data, "base64-encoding: %s\n", + curl_easy_strerror(result)); + ret = AUTH_ERROR; + break; + } + + cmd = aprintf("ADAT %s", p); + if(cmd) + result = Curl_ftpsend(conn, cmd); + else + result = CURLE_OUT_OF_MEMORY; + + free(p); + free(cmd); + + if(result) { + ret = -2; + break; + } + + if(Curl_GetFTPResponse(&nread, conn, NULL)) { + ret = -1; + break; + } + + if(data->state.buffer[0] != '2' && data->state.buffer[0] != '3') { + Curl_infof(data, "Server didn't accept auth data\n"); + ret = AUTH_ERROR; + break; + } + + _gssresp.value = NULL; /* make sure it is initialized */ + p = data->state.buffer + 4; + p = strstr(p, "ADAT="); + if(p) { + result = Curl_base64_decode(p + 5, + (unsigned char **)&_gssresp.value, + &_gssresp.length); + if(result) { + failf(data, "base64-decoding: %s", curl_easy_strerror(result)); + ret = AUTH_CONTINUE; + break; + } + } + + gssresp = &_gssresp; + } + } while(maj == GSS_S_CONTINUE_NEEDED); + + gss_release_name(&min, &gssname); + gss_release_buffer(&min, &output_buffer); + + if(gssresp) + free(_gssresp.value); + + if(ret == AUTH_OK || service == srv_host) + return ret; + + service = srv_host; + } + return ret; +} + +static void krb5_end(void *app_data) +{ + OM_uint32 min; + gss_ctx_id_t *context = app_data; + if(*context != GSS_C_NO_CONTEXT) { + OM_uint32 maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER); + (void)maj; + DEBUGASSERT(maj == GSS_S_COMPLETE); + } +} + +struct Curl_sec_client_mech Curl_krb5_client_mech = { + "GSSAPI", + sizeof(gss_ctx_id_t), + krb5_init, + krb5_auth, + krb5_end, + krb5_check_prot, + krb5_overhead, + krb5_encode, + krb5_decode +}; + +#endif /* HAVE_GSSAPI && !CURL_DISABLE_FTP */ diff --git a/libcurl/lib/ldap.c b/libcurl/lib/ldap.c new file mode 100644 index 0000000..fd31faa --- /dev/null +++ b/libcurl/lib/ldap.c @@ -0,0 +1,1088 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_LDAP) && !defined(USE_OPENLDAP) + +/* + * Notice that USE_OPENLDAP is only a source code selection switch. When + * libcurl is built with USE_OPENLDAP defined the libcurl source code that + * gets compiled is the code from openldap.c, otherwise the code that gets + * compiled is the code from ldap.c. + * + * When USE_OPENLDAP is defined a recent version of the OpenLDAP library + * might be required for compilation and runtime. In order to use ancient + * OpenLDAP library versions, USE_OPENLDAP shall not be defined. + */ + +#ifdef USE_WIN32_LDAP /* Use Windows LDAP implementation. */ +# include +# ifndef LDAP_VENDOR_NAME +# error Your Platform SDK is NOT sufficient for LDAP support! \ + Update your Platform SDK, or disable LDAP support! +# else +# include +# endif +#else +# define LDAP_DEPRECATED 1 /* Be sure ldap_init() is defined. */ +# ifdef HAVE_LBER_H +# include +# endif +# include +# if (defined(HAVE_LDAP_SSL) && defined(HAVE_LDAP_SSL_H)) +# include +# endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */ +#endif + +#include "urldata.h" +#include +#include "sendf.h" +#include "escape.h" +#include "progress.h" +#include "transfer.h" +#include "strcase.h" +#include "strtok.h" +#include "curl_ldap.h" +#include "curl_multibyte.h" +#include "curl_base64.h" +#include "connect.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#ifndef HAVE_LDAP_URL_PARSE + +/* Use our own implementation. */ + +typedef struct { + char *lud_host; + int lud_port; +#if defined(USE_WIN32_LDAP) + TCHAR *lud_dn; + TCHAR **lud_attrs; +#else + char *lud_dn; + char **lud_attrs; +#endif + int lud_scope; +#if defined(USE_WIN32_LDAP) + TCHAR *lud_filter; +#else + char *lud_filter; +#endif + char **lud_exts; + size_t lud_attrs_dups; /* how many were dup'ed, this field is not in the + "real" struct so can only be used in code + without HAVE_LDAP_URL_PARSE defined */ +} CURL_LDAPURLDesc; + +#undef LDAPURLDesc +#define LDAPURLDesc CURL_LDAPURLDesc + +static int _ldap_url_parse(const struct connectdata *conn, + LDAPURLDesc **ludp); +static void _ldap_free_urldesc(LDAPURLDesc *ludp); + +#undef ldap_free_urldesc +#define ldap_free_urldesc _ldap_free_urldesc +#endif + +#ifdef DEBUG_LDAP + #define LDAP_TRACE(x) do { \ + _ldap_trace("%u: ", __LINE__); \ + _ldap_trace x; \ + } WHILE_FALSE + + static void _ldap_trace(const char *fmt, ...); +#else + #define LDAP_TRACE(x) Curl_nop_stmt +#endif + + +static CURLcode Curl_ldap(struct connectdata *conn, bool *done); + +/* + * LDAP protocol handler. + */ + +const struct Curl_handler Curl_handler_ldap = { + "LDAP", /* scheme */ + ZERO_NULL, /* setup_connection */ + Curl_ldap, /* do_it */ + ZERO_NULL, /* done */ + ZERO_NULL, /* do_more */ + ZERO_NULL, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_LDAP, /* defport */ + CURLPROTO_LDAP, /* protocol */ + PROTOPT_NONE /* flags */ +}; + +#ifdef HAVE_LDAP_SSL +/* + * LDAPS protocol handler. + */ + +const struct Curl_handler Curl_handler_ldaps = { + "LDAPS", /* scheme */ + ZERO_NULL, /* setup_connection */ + Curl_ldap, /* do_it */ + ZERO_NULL, /* done */ + ZERO_NULL, /* do_more */ + ZERO_NULL, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_LDAPS, /* defport */ + CURLPROTO_LDAPS, /* protocol */ + PROTOPT_SSL /* flags */ +}; +#endif + +#if defined(USE_WIN32_LDAP) + +#if defined(USE_WINDOWS_SSPI) +static int ldap_win_bind_auth(LDAP *server, const char *user, + const char *passwd, unsigned long authflags) +{ + ULONG method = 0; + SEC_WINNT_AUTH_IDENTITY cred; + int rc = LDAP_AUTH_METHOD_NOT_SUPPORTED; + + memset(&cred, 0, sizeof(cred)); + +#if defined(USE_SPNEGO) + if(authflags & CURLAUTH_NEGOTIATE) { + method = LDAP_AUTH_NEGOTIATE; + } + else +#endif +#if defined(USE_NTLM) + if(authflags & CURLAUTH_NTLM) { + method = LDAP_AUTH_NTLM; + } + else +#endif +#if !defined(CURL_DISABLE_CRYPTO_AUTH) + if(authflags & CURLAUTH_DIGEST) { + method = LDAP_AUTH_DIGEST; + } + else +#endif + { + /* required anyway if one of upper preprocessor definitions enabled */ + } + + if(method && user && passwd) { + rc = Curl_create_sspi_identity(user, passwd, &cred); + if(!rc) { + rc = ldap_bind_s(server, NULL, (TCHAR *)&cred, method); + Curl_sspi_free_identity(&cred); + } + } + else { + /* proceed with current user credentials */ + method = LDAP_AUTH_NEGOTIATE; + rc = ldap_bind_s(server, NULL, NULL, method); + } + return rc; +} +#endif /* #if defined(USE_WINDOWS_SSPI) */ + +static int ldap_win_bind(struct connectdata *conn, LDAP *server, + const char *user, const char *passwd) +{ + int rc = LDAP_INVALID_CREDENTIALS; + + PTCHAR inuser = NULL; + PTCHAR inpass = NULL; + + if(user && passwd && (conn->data->set.httpauth & CURLAUTH_BASIC)) { + inuser = Curl_convert_UTF8_to_tchar((char *) user); + inpass = Curl_convert_UTF8_to_tchar((char *) passwd); + + rc = ldap_simple_bind_s(server, inuser, inpass); + + Curl_unicodefree(inuser); + Curl_unicodefree(inpass); + } +#if defined(USE_WINDOWS_SSPI) + else { + rc = ldap_win_bind_auth(server, user, passwd, conn->data->set.httpauth); + } +#endif + + return rc; +} +#endif /* #if defined(USE_WIN32_LDAP) */ + +static CURLcode Curl_ldap(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + int rc = 0; + LDAP *server = NULL; + LDAPURLDesc *ludp = NULL; + LDAPMessage *ldapmsg = NULL; + LDAPMessage *entryIterator; + int num = 0; + struct Curl_easy *data = conn->data; + int ldap_proto = LDAP_VERSION3; + int ldap_ssl = 0; + char *val_b64 = NULL; + size_t val_b64_sz = 0; + curl_off_t dlsize = 0; +#ifdef LDAP_OPT_NETWORK_TIMEOUT + struct timeval ldap_timeout = {10, 0}; /* 10 sec connection/search timeout */ +#endif +#if defined(USE_WIN32_LDAP) + TCHAR *host = NULL; +#else + char *host = NULL; +#endif + char *user = NULL; + char *passwd = NULL; + + *done = TRUE; /* unconditionally */ + infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n", + LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION); + infof(data, "LDAP local: %s\n", data->change.url); + +#ifdef HAVE_LDAP_URL_PARSE + rc = ldap_url_parse(data->change.url, &ludp); +#else + rc = _ldap_url_parse(conn, &ludp); +#endif + if(rc != 0) { + failf(data, "LDAP local: %s", ldap_err2string(rc)); + result = CURLE_LDAP_INVALID_URL; + goto quit; + } + + /* Get the URL scheme (either ldap or ldaps) */ + if(conn->given->flags & PROTOPT_SSL) + ldap_ssl = 1; + infof(data, "LDAP local: trying to establish %s connection\n", + ldap_ssl ? "encrypted" : "cleartext"); + +#if defined(USE_WIN32_LDAP) + host = Curl_convert_UTF8_to_tchar(conn->host.name); + if(!host) { + result = CURLE_OUT_OF_MEMORY; + + goto quit; + } +#else + host = conn->host.name; +#endif + + if(conn->bits.user_passwd) { + user = conn->user; + passwd = conn->passwd; + } + +#ifdef LDAP_OPT_NETWORK_TIMEOUT + ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout); +#endif + ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); + + if(ldap_ssl) { +#ifdef HAVE_LDAP_SSL +#ifdef USE_WIN32_LDAP + /* Win32 LDAP SDK doesn't support insecure mode without CA! */ + server = ldap_sslinit(host, (int)conn->port, 1); + ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON); +#else + int ldap_option; + char *ldap_ca = conn->ssl_config.CAfile; +#if defined(CURL_HAS_NOVELL_LDAPSDK) + rc = ldapssl_client_init(NULL, NULL); + if(rc != LDAP_SUCCESS) { + failf(data, "LDAP local: ldapssl_client_init %s", ldap_err2string(rc)); + result = CURLE_SSL_CERTPROBLEM; + goto quit; + } + if(conn->ssl_config.verifypeer) { + /* Novell SDK supports DER or BASE64 files. */ + int cert_type = LDAPSSL_CERT_FILETYPE_B64; + if((data->set.ssl.cert_type) && + (strcasecompare(data->set.ssl.cert_type, "DER"))) + cert_type = LDAPSSL_CERT_FILETYPE_DER; + if(!ldap_ca) { + failf(data, "LDAP local: ERROR %s CA cert not set!", + (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM")); + result = CURLE_SSL_CERTPROBLEM; + goto quit; + } + infof(data, "LDAP local: using %s CA cert '%s'\n", + (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"), + ldap_ca); + rc = ldapssl_add_trusted_cert(ldap_ca, cert_type); + if(rc != LDAP_SUCCESS) { + failf(data, "LDAP local: ERROR setting %s CA cert: %s", + (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"), + ldap_err2string(rc)); + result = CURLE_SSL_CERTPROBLEM; + goto quit; + } + ldap_option = LDAPSSL_VERIFY_SERVER; + } + else + ldap_option = LDAPSSL_VERIFY_NONE; + rc = ldapssl_set_verify_mode(ldap_option); + if(rc != LDAP_SUCCESS) { + failf(data, "LDAP local: ERROR setting cert verify mode: %s", + ldap_err2string(rc)); + result = CURLE_SSL_CERTPROBLEM; + goto quit; + } + server = ldapssl_init(host, (int)conn->port, 1); + if(server == NULL) { + failf(data, "LDAP local: Cannot connect to %s:%ld", + conn->host.dispname, conn->port); + result = CURLE_COULDNT_CONNECT; + goto quit; + } +#elif defined(LDAP_OPT_X_TLS) + if(conn->ssl_config.verifypeer) { + /* OpenLDAP SDK supports BASE64 files. */ + if((data->set.ssl.cert_type) && + (!strcasecompare(data->set.ssl.cert_type, "PEM"))) { + failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!"); + result = CURLE_SSL_CERTPROBLEM; + goto quit; + } + if(!ldap_ca) { + failf(data, "LDAP local: ERROR PEM CA cert not set!"); + result = CURLE_SSL_CERTPROBLEM; + goto quit; + } + infof(data, "LDAP local: using PEM CA cert: %s\n", ldap_ca); + rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca); + if(rc != LDAP_SUCCESS) { + failf(data, "LDAP local: ERROR setting PEM CA cert: %s", + ldap_err2string(rc)); + result = CURLE_SSL_CERTPROBLEM; + goto quit; + } + ldap_option = LDAP_OPT_X_TLS_DEMAND; + } + else + ldap_option = LDAP_OPT_X_TLS_NEVER; + + rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option); + if(rc != LDAP_SUCCESS) { + failf(data, "LDAP local: ERROR setting cert verify mode: %s", + ldap_err2string(rc)); + result = CURLE_SSL_CERTPROBLEM; + goto quit; + } + server = ldap_init(host, (int)conn->port); + if(server == NULL) { + failf(data, "LDAP local: Cannot connect to %s:%ld", + conn->host.dispname, conn->port); + result = CURLE_COULDNT_CONNECT; + goto quit; + } + ldap_option = LDAP_OPT_X_TLS_HARD; + rc = ldap_set_option(server, LDAP_OPT_X_TLS, &ldap_option); + if(rc != LDAP_SUCCESS) { + failf(data, "LDAP local: ERROR setting SSL/TLS mode: %s", + ldap_err2string(rc)); + result = CURLE_SSL_CERTPROBLEM; + goto quit; + } +/* + rc = ldap_start_tls_s(server, NULL, NULL); + if(rc != LDAP_SUCCESS) { + failf(data, "LDAP local: ERROR starting SSL/TLS mode: %s", + ldap_err2string(rc)); + result = CURLE_SSL_CERTPROBLEM; + goto quit; + } +*/ +#else + /* we should probably never come up to here since configure + should check in first place if we can support LDAP SSL/TLS */ + failf(data, "LDAP local: SSL/TLS not supported with this version " + "of the OpenLDAP toolkit\n"); + result = CURLE_SSL_CERTPROBLEM; + goto quit; +#endif +#endif +#endif /* CURL_LDAP_USE_SSL */ + } + else { + server = ldap_init(host, (int)conn->port); + if(server == NULL) { + failf(data, "LDAP local: Cannot connect to %s:%ld", + conn->host.dispname, conn->port); + result = CURLE_COULDNT_CONNECT; + goto quit; + } + } +#ifdef USE_WIN32_LDAP + ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); +#endif + +#ifdef USE_WIN32_LDAP + rc = ldap_win_bind(conn, server, user, passwd); +#else + rc = ldap_simple_bind_s(server, user, passwd); +#endif + if(!ldap_ssl && rc != 0) { + ldap_proto = LDAP_VERSION2; + ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); +#ifdef USE_WIN32_LDAP + rc = ldap_win_bind(conn, server, user, passwd); +#else + rc = ldap_simple_bind_s(server, user, passwd); +#endif + } + if(rc != 0) { +#ifdef USE_WIN32_LDAP + failf(data, "LDAP local: bind via ldap_win_bind %s", + ldap_err2string(rc)); +#else + failf(data, "LDAP local: bind via ldap_simple_bind_s %s", + ldap_err2string(rc)); +#endif + result = CURLE_LDAP_CANNOT_BIND; + goto quit; + } + + rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope, + ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg); + + if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) { + failf(data, "LDAP remote: %s", ldap_err2string(rc)); + result = CURLE_LDAP_SEARCH_FAILED; + goto quit; + } + + for(num = 0, entryIterator = ldap_first_entry(server, ldapmsg); + entryIterator; + entryIterator = ldap_next_entry(server, entryIterator), num++) { + BerElement *ber = NULL; +#if defined(USE_WIN32_LDAP) + TCHAR *attribute; +#else + char *attribute; /*! suspicious that this isn't 'const' */ +#endif + int i; + + /* Get the DN and write it to the client */ + { + char *name; + size_t name_len; +#if defined(USE_WIN32_LDAP) + TCHAR *dn = ldap_get_dn(server, entryIterator); + name = Curl_convert_tchar_to_UTF8(dn); + if(!name) { + ldap_memfree(dn); + + result = CURLE_OUT_OF_MEMORY; + + goto quit; + } +#else + char *dn = name = ldap_get_dn(server, entryIterator); +#endif + name_len = strlen(name); + + result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4); + if(result) { +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(name); +#endif + ldap_memfree(dn); + + goto quit; + } + + result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *) name, + name_len); + if(result) { +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(name); +#endif + ldap_memfree(dn); + + goto quit; + } + + result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); + if(result) { +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(name); +#endif + ldap_memfree(dn); + + goto quit; + } + + dlsize += name_len + 5; + +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(name); +#endif + ldap_memfree(dn); + } + + /* Get the attributes and write them to the client */ + for(attribute = ldap_first_attribute(server, entryIterator, &ber); + attribute; + attribute = ldap_next_attribute(server, entryIterator, ber)) { + BerValue **vals; + size_t attr_len; +#if defined(USE_WIN32_LDAP) + char *attr = Curl_convert_tchar_to_UTF8(attribute); + if(!attr) { + if(ber) + ber_free(ber, 0); + + result = CURLE_OUT_OF_MEMORY; + + goto quit; + } +#else + char *attr = attribute; +#endif + attr_len = strlen(attr); + + vals = ldap_get_values_len(server, entryIterator, attribute); + if(vals != NULL) { + for(i = 0; (vals[i] != NULL); i++) { + result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); + if(result) { + ldap_value_free_len(vals); +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(attr); +#endif + ldap_memfree(attribute); + if(ber) + ber_free(ber, 0); + + goto quit; + } + + result = Curl_client_write(conn, CLIENTWRITE_BODY, + (char *) attr, attr_len); + if(result) { + ldap_value_free_len(vals); +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(attr); +#endif + ldap_memfree(attribute); + if(ber) + ber_free(ber, 0); + + goto quit; + } + + result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2); + if(result) { + ldap_value_free_len(vals); +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(attr); +#endif + ldap_memfree(attribute); + if(ber) + ber_free(ber, 0); + + goto quit; + } + + dlsize += attr_len + 3; + + if((attr_len > 7) && + (strcmp(";binary", (char *) attr + (attr_len - 7)) == 0)) { + /* Binary attribute, encode to base64. */ + result = Curl_base64_encode(data, + vals[i]->bv_val, + vals[i]->bv_len, + &val_b64, + &val_b64_sz); + if(result) { + ldap_value_free_len(vals); +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(attr); +#endif + ldap_memfree(attribute); + if(ber) + ber_free(ber, 0); + + goto quit; + } + + if(val_b64_sz > 0) { + result = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, + val_b64_sz); + free(val_b64); + if(result) { + ldap_value_free_len(vals); +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(attr); +#endif + ldap_memfree(attribute); + if(ber) + ber_free(ber, 0); + + goto quit; + } + + dlsize += val_b64_sz; + } + } + else { + result = Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val, + vals[i]->bv_len); + if(result) { + ldap_value_free_len(vals); +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(attr); +#endif + ldap_memfree(attribute); + if(ber) + ber_free(ber, 0); + + goto quit; + } + + dlsize += vals[i]->bv_len; + } + + result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); + if(result) { + ldap_value_free_len(vals); +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(attr); +#endif + ldap_memfree(attribute); + if(ber) + ber_free(ber, 0); + + goto quit; + } + + dlsize++; + } + + /* Free memory used to store values */ + ldap_value_free_len(vals); + } + + /* Free the attribute as we are done with it */ +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(attr); +#endif + ldap_memfree(attribute); + + result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); + if(result) + goto quit; + dlsize++; + Curl_pgrsSetDownloadCounter(data, dlsize); + } + + if(ber) + ber_free(ber, 0); + } + +quit: + if(ldapmsg) { + ldap_msgfree(ldapmsg); + LDAP_TRACE(("Received %d entries\n", num)); + } + if(rc == LDAP_SIZELIMIT_EXCEEDED) + infof(data, "There are more than %d entries\n", num); + if(ludp) + ldap_free_urldesc(ludp); + if(server) + ldap_unbind_s(server); +#if defined(HAVE_LDAP_SSL) && defined(CURL_HAS_NOVELL_LDAPSDK) + if(ldap_ssl) + ldapssl_client_deinit(); +#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */ + +#if defined(USE_WIN32_LDAP) + Curl_unicodefree(host); +#endif + + /* no data to transfer */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + connclose(conn, "LDAP connection always disable re-use"); + + return result; +} + +#ifdef DEBUG_LDAP +static void _ldap_trace(const char *fmt, ...) +{ + static int do_trace = -1; + va_list args; + + if(do_trace == -1) { + const char *env = getenv("CURL_TRACE"); + do_trace = (env && strtol(env, NULL, 10) > 0); + } + if(!do_trace) + return; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); +} +#endif + +#ifndef HAVE_LDAP_URL_PARSE + +/* + * Return scope-value for a scope-string. + */ +static int str2scope(const char *p) +{ + if(strcasecompare(p, "one")) + return LDAP_SCOPE_ONELEVEL; + if(strcasecompare(p, "onetree")) + return LDAP_SCOPE_ONELEVEL; + if(strcasecompare(p, "base")) + return LDAP_SCOPE_BASE; + if(strcasecompare(p, "sub")) + return LDAP_SCOPE_SUBTREE; + if(strcasecompare(p, "subtree")) + return LDAP_SCOPE_SUBTREE; + return (-1); +} + +/* + * Split 'str' into strings separated by commas. + * Note: out[] points into 'str'. + */ +static bool split_str(char *str, char ***out, size_t *count) +{ + char **res; + char *lasts; + char *s; + size_t i; + size_t items = 1; + + s = strchr(str, ','); + while(s) { + items++; + s = strchr(++s, ','); + } + + res = calloc(items, sizeof(char *)); + if(!res) + return FALSE; + + for(i = 0, s = strtok_r(str, ",", &lasts); s && i < items; + s = strtok_r(NULL, ",", &lasts), i++) + res[i] = s; + + *out = res; + *count = items; + + return TRUE; +} + +/* + * Break apart the pieces of an LDAP URL. + * Syntax: + * ldap://:/???? + * + * already known from 'conn->host.name'. + * already known from 'conn->remote_port'. + * extract the rest from 'conn->data->state.path+1'. All fields are optional. + * e.g. + * ldap://:/??? + * yields ludp->lud_dn = "". + * + * Defined in RFC4516 section 2. + */ +static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp) +{ + int rc = LDAP_SUCCESS; + char *path; + char *query; + char *p; + char *q; + size_t i; + + if(!conn->data || + !conn->data->state.up.path || + conn->data->state.up.path[0] != '/' || + !strncasecompare("LDAP", conn->data->state.up.scheme, 4)) + return LDAP_INVALID_SYNTAX; + + ludp->lud_scope = LDAP_SCOPE_BASE; + ludp->lud_port = conn->remote_port; + ludp->lud_host = conn->host.name; + + /* Duplicate the path */ + p = path = strdup(conn->data->state.up.path + 1); + if(!path) + return LDAP_NO_MEMORY; + + /* Duplicate the query */ + q = query = strdup(conn->data->state.up.query); + if(!query) { + free(path); + return LDAP_NO_MEMORY; + } + + /* Parse the DN (Distinguished Name) */ + if(*p) { + char *dn = p; + char *unescaped; + CURLcode result; + + LDAP_TRACE(("DN '%s'\n", dn)); + + /* Unescape the DN */ + result = Curl_urldecode(conn->data, dn, 0, &unescaped, NULL, FALSE); + if(result) { + rc = LDAP_NO_MEMORY; + + goto quit; + } + +#if defined(USE_WIN32_LDAP) + /* Convert the unescaped string to a tchar */ + ludp->lud_dn = Curl_convert_UTF8_to_tchar(unescaped); + + /* Free the unescaped string as we are done with it */ + Curl_unicodefree(unescaped); + + if(!ludp->lud_dn) { + rc = LDAP_NO_MEMORY; + + goto quit; + } +#else + ludp->lud_dn = unescaped; +#endif + } + + p = q; + if(!p) + goto quit; + + /* Parse the attributes. skip "??" */ + q = strchr(p, '?'); + if(q) + *q++ = '\0'; + + if(*p) { + char **attributes; + size_t count = 0; + + /* Split the string into an array of attributes */ + if(!split_str(p, &attributes, &count)) { + rc = LDAP_NO_MEMORY; + + goto quit; + } + + /* Allocate our array (+1 for the NULL entry) */ +#if defined(USE_WIN32_LDAP) + ludp->lud_attrs = calloc(count + 1, sizeof(TCHAR *)); +#else + ludp->lud_attrs = calloc(count + 1, sizeof(char *)); +#endif + if(!ludp->lud_attrs) { + free(attributes); + + rc = LDAP_NO_MEMORY; + + goto quit; + } + + for(i = 0; i < count; i++) { + char *unescaped; + CURLcode result; + + LDAP_TRACE(("attr[%d] '%s'\n", i, attributes[i])); + + /* Unescape the attribute */ + result = Curl_urldecode(conn->data, attributes[i], 0, &unescaped, NULL, + FALSE); + if(result) { + free(attributes); + + rc = LDAP_NO_MEMORY; + + goto quit; + } + +#if defined(USE_WIN32_LDAP) + /* Convert the unescaped string to a tchar */ + ludp->lud_attrs[i] = Curl_convert_UTF8_to_tchar(unescaped); + + /* Free the unescaped string as we are done with it */ + Curl_unicodefree(unescaped); + + if(!ludp->lud_attrs[i]) { + free(attributes); + + rc = LDAP_NO_MEMORY; + + goto quit; + } +#else + ludp->lud_attrs[i] = unescaped; +#endif + + ludp->lud_attrs_dups++; + } + + free(attributes); + } + + p = q; + if(!p) + goto quit; + + /* Parse the scope. skip "??" */ + q = strchr(p, '?'); + if(q) + *q++ = '\0'; + + if(*p) { + ludp->lud_scope = str2scope(p); + if(ludp->lud_scope == -1) { + rc = LDAP_INVALID_SYNTAX; + + goto quit; + } + LDAP_TRACE(("scope %d\n", ludp->lud_scope)); + } + + p = q; + if(!p) + goto quit; + + /* Parse the filter */ + q = strchr(p, '?'); + if(q) + *q++ = '\0'; + + if(*p) { + char *filter = p; + char *unescaped; + CURLcode result; + + LDAP_TRACE(("filter '%s'\n", filter)); + + /* Unescape the filter */ + result = Curl_urldecode(conn->data, filter, 0, &unescaped, NULL, FALSE); + if(result) { + rc = LDAP_NO_MEMORY; + + goto quit; + } + +#if defined(USE_WIN32_LDAP) + /* Convert the unescaped string to a tchar */ + ludp->lud_filter = Curl_convert_UTF8_to_tchar(unescaped); + + /* Free the unescaped string as we are done with it */ + Curl_unicodefree(unescaped); + + if(!ludp->lud_filter) { + rc = LDAP_NO_MEMORY; + + goto quit; + } +#else + ludp->lud_filter = unescaped; +#endif + } + + p = q; + if(p && !*p) { + rc = LDAP_INVALID_SYNTAX; + + goto quit; + } + +quit: + free(path); + free(query); + + return rc; +} + +static int _ldap_url_parse(const struct connectdata *conn, + LDAPURLDesc **ludpp) +{ + LDAPURLDesc *ludp = calloc(1, sizeof(*ludp)); + int rc; + + *ludpp = NULL; + if(!ludp) + return LDAP_NO_MEMORY; + + rc = _ldap_url_parse2(conn, ludp); + if(rc != LDAP_SUCCESS) { + _ldap_free_urldesc(ludp); + ludp = NULL; + } + *ludpp = ludp; + return (rc); +} + +static void _ldap_free_urldesc(LDAPURLDesc *ludp) +{ + if(!ludp) + return; + + free(ludp->lud_dn); + free(ludp->lud_filter); + + if(ludp->lud_attrs) { + size_t i; + for(i = 0; i < ludp->lud_attrs_dups; i++) + free(ludp->lud_attrs[i]); + free(ludp->lud_attrs); + } + + free(ludp); +} +#endif /* !HAVE_LDAP_URL_PARSE */ +#endif /* !CURL_DISABLE_LDAP && !USE_OPENLDAP */ diff --git a/libcurl/lib/libcurl.plist b/libcurl/lib/libcurl.plist new file mode 100644 index 0000000..c0adf43 --- /dev/null +++ b/libcurl/lib/libcurl.plist @@ -0,0 +1,35 @@ + + + + + CFBundleInfoDictionaryVersion + 6.0 + + CFBundleDevelopmentRegion + English + + CFBundleExecutable + curl + + CFBundleIdentifier + se.haxx.curl.libcurl + + CFBundleVersion + 7.65.3 + + CFBundleName + libcurl + + CFBundlePackageType + FMWK + + CFBundleSignature + ???? + + CFBundleShortVersionString + libcurl 7.65.3 + + CFBundleGetInfoString + libcurl.plist 7.65.3 + + diff --git a/libcurl/lib/libcurl.rc b/libcurl/lib/libcurl.rc new file mode 100644 index 0000000..4839d0a --- /dev/null +++ b/libcurl/lib/libcurl.rc @@ -0,0 +1,63 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include +#include "../include/curl/curlver.h" + +LANGUAGE 0, 0 + +#define RC_VERSION LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR, LIBCURL_VERSION_PATCH, 0 + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RC_VERSION + PRODUCTVERSION RC_VERSION + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#if defined(DEBUGBUILD) || defined(_DEBUG) + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0L + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "The curl library, https://curl.haxx.se/\0" + VALUE "FileDescription", "libcurl Shared Library\0" + VALUE "FileVersion", LIBCURL_VERSION "\0" + VALUE "InternalName", "libcurl\0" + VALUE "OriginalFilename", "libcurl.dll\0" + VALUE "ProductName", "The curl library\0" + VALUE "ProductVersion", LIBCURL_VERSION "\0" + VALUE "LegalCopyright", "\xa9 " LIBCURL_COPYRIGHT "\0" /* a9: Copyright symbol */ + VALUE "License", "https://curl.haxx.se/docs/copyright.html\0" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/libcurl/lib/libcurl.vers.in b/libcurl/lib/libcurl.vers.in new file mode 100644 index 0000000..ae978a4 --- /dev/null +++ b/libcurl/lib/libcurl.vers.in @@ -0,0 +1,13 @@ +HIDDEN +{ + local: + __*; + _rest*; + _save*; +}; + +CURL_@CURL_LT_SHLIB_VERSIONED_FLAVOUR@4 +{ + global: curl_*; + local: *; +}; diff --git a/libcurl/lib/llist.c b/libcurl/lib/llist.c new file mode 100644 index 0000000..f8769c2 --- /dev/null +++ b/libcurl/lib/llist.c @@ -0,0 +1,197 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "llist.h" +#include "curl_memory.h" + +/* this must be the last include file */ +#include "memdebug.h" + +/* + * @unittest: 1300 + */ +void +Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor) +{ + l->size = 0; + l->dtor = dtor; + l->head = NULL; + l->tail = NULL; +} + +/* + * Curl_llist_insert_next() + * + * Inserts a new list element after the given one 'e'. If the given existing + * entry is NULL and the list already has elements, the new one will be + * inserted first in the list. + * + * The 'ne' argument should be a pointer into the object to store. + * + * @unittest: 1300 + */ +void +Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e, + const void *p, + struct curl_llist_element *ne) +{ + ne->ptr = (void *) p; + if(list->size == 0) { + list->head = ne; + list->head->prev = NULL; + list->head->next = NULL; + list->tail = ne; + } + else { + /* if 'e' is NULL here, we insert the new element first in the list */ + ne->next = e?e->next:list->head; + ne->prev = e; + if(!e) { + list->head->prev = ne; + list->head = ne; + } + else if(e->next) { + e->next->prev = ne; + } + else { + list->tail = ne; + } + if(e) + e->next = ne; + } + + ++list->size; +} + +/* + * @unittest: 1300 + */ +void +Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e, + void *user) +{ + void *ptr; + if(e == NULL || list->size == 0) + return; + + if(e == list->head) { + list->head = e->next; + + if(list->head == NULL) + list->tail = NULL; + else + e->next->prev = NULL; + } + else { + if(!e->prev) + list->head = e->next; + else + e->prev->next = e->next; + + if(!e->next) + list->tail = e->prev; + else + e->next->prev = e->prev; + } + + ptr = e->ptr; + + e->ptr = NULL; + e->prev = NULL; + e->next = NULL; + + --list->size; + + /* call the dtor() last for when it actually frees the 'e' memory itself */ + if(list->dtor) + list->dtor(user, ptr); +} + +void +Curl_llist_destroy(struct curl_llist *list, void *user) +{ + if(list) { + while(list->size > 0) + Curl_llist_remove(list, list->tail, user); + } +} + +size_t +Curl_llist_count(struct curl_llist *list) +{ + return list->size; +} + +/* + * @unittest: 1300 + */ +void Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e, + struct curl_llist *to_list, + struct curl_llist_element *to_e) +{ + /* Remove element from list */ + if(e == NULL || list->size == 0) + return; + + if(e == list->head) { + list->head = e->next; + + if(list->head == NULL) + list->tail = NULL; + else + e->next->prev = NULL; + } + else { + e->prev->next = e->next; + if(!e->next) + list->tail = e->prev; + else + e->next->prev = e->prev; + } + + --list->size; + + /* Add element to to_list after to_e */ + if(to_list->size == 0) { + to_list->head = e; + to_list->head->prev = NULL; + to_list->head->next = NULL; + to_list->tail = e; + } + else { + e->next = to_e->next; + e->prev = to_e; + if(to_e->next) { + to_e->next->prev = e; + } + else { + to_list->tail = e; + } + to_e->next = e; + } + + ++to_list->size; +} diff --git a/libcurl/lib/llist.h b/libcurl/lib/llist.h new file mode 100644 index 0000000..b9d4c89 --- /dev/null +++ b/libcurl/lib/llist.h @@ -0,0 +1,53 @@ +#ifndef HEADER_CURL_LLIST_H +#define HEADER_CURL_LLIST_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include + +typedef void (*curl_llist_dtor)(void *, void *); + +struct curl_llist_element { + void *ptr; + struct curl_llist_element *prev; + struct curl_llist_element *next; +}; + +struct curl_llist { + struct curl_llist_element *head; + struct curl_llist_element *tail; + curl_llist_dtor dtor; + size_t size; +}; + +void Curl_llist_init(struct curl_llist *, curl_llist_dtor); +void Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *, + const void *, struct curl_llist_element *node); +void Curl_llist_remove(struct curl_llist *, struct curl_llist_element *, + void *); +size_t Curl_llist_count(struct curl_llist *); +void Curl_llist_destroy(struct curl_llist *, void *); +void Curl_llist_move(struct curl_llist *, struct curl_llist_element *, + struct curl_llist *, struct curl_llist_element *); + +#endif /* HEADER_CURL_LLIST_H */ diff --git a/libcurl/lib/makefile.amiga b/libcurl/lib/makefile.amiga new file mode 100644 index 0000000..673b147 --- /dev/null +++ b/libcurl/lib/makefile.amiga @@ -0,0 +1,21 @@ +# +# libcurl Makefile for AmigaOS ... +# + +# change the follow to where you have the AmiTCP SDK v4.3 includes: + +ATCPSDKI= /GG/netinclude + + +CC = m68k-amigaos-gcc +CFLAGS = -I$(ATCPSDKI) -m68020-60 -O2 -msoft-float -noixemul -g -I. -I../include -W -Wall + +include Makefile.inc +OBJS = $(CSOURCES:.c=.o) + +all: $(OBJS) + ar cru libcurl.a $(OBJS) + ranlib libcurl.a + +install: + $(INSTALL) -c ./libcurl.a /lib/libcurl.a diff --git a/libcurl/lib/makefile.dj b/libcurl/lib/makefile.dj new file mode 100644 index 0000000..941f8ce --- /dev/null +++ b/libcurl/lib/makefile.dj @@ -0,0 +1,71 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 2003 - 2008, Gisle Vanem . +# Copyright (C) 2003 - 2017, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +#*************************************************************************** + +# +# Adapted for djgpp2 / Watt-32 / DOS +# + +DEPEND_PREREQ = curl_config.h +VPATH = vtls vauth +TOPDIR = .. + +include ../packages/DOS/common.dj +include Makefile.inc + +CFLAGS += -DBUILDING_LIBCURL + +SOURCES = $(sort $(CSOURCES)) +OBJECTS = $(addprefix $(OBJ_DIR)/, $(notdir $(SOURCES:.c=.o))) + +CURL_LIB = libcurl.a + +all: $(OBJ_DIR) curl_config.h $(CURL_LIB) + +$(CURL_LIB): $(OBJECTS) + ar rs $@ $? + +curl_config.h: config-dos.h + $(COPY) $^ $@ + +# clean generated files +# +genclean: + - $(DELETE) curl_config.h + +# clean object files and subdir +# +objclean: genclean + - $(DELETE) $(OBJ_DIR)$(DS)*.o + - $(RMDIR) $(OBJ_DIR) + +# clean without removing built library +# +clean: objclean + - $(DELETE) depend.dj + +# clean everything +# +realclean vclean: clean + - $(DELETE) $(CURL_LIB) + +-include depend.dj diff --git a/libcurl/lib/md4.c b/libcurl/lib/md4.c new file mode 100644 index 0000000..0b4ea9a --- /dev/null +++ b/libcurl/lib/md4.c @@ -0,0 +1,320 @@ +/* + * !checksrc! disable COPYRIGHT + * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. + * MD4 Message-Digest Algorithm (RFC 1320). + * + * Homepage: + https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4 + * + * Author: + * Alexander Peslyak, better known as Solar Designer + * + * This software was written by Alexander Peslyak in 2001. No copyright is + * claimed, and the software is hereby placed in the public domain. In case + * this attempt to disclaim copyright and place the software in the public + * domain is deemed null and void, then the software is Copyright (c) 2001 + * Alexander Peslyak and it is hereby released to the general public under the + * following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * (This is a heavily cut-down "BSD license".) + * + * This differs from Colin Plumb's older public domain implementation in that + * no exactly 32-bit integer data type is required (any 32-bit or wider + * unsigned integer data type will do), there's no compile-time endianness + * configuration, and the function prototypes match OpenSSL's. No code from + * Colin Plumb's implementation has been reused; this comment merely compares + * the properties of the two independent implementations. + * + * The primary goals of this implementation are portability and ease of use. + * It is meant to be fast, but not as fast as possible. Some known + * optimizations are not included to reduce source code size and avoid + * compile-time configuration. + */ + +#include "curl_setup.h" + +#ifdef USE_OPENSSL +#include +#endif +#ifdef USE_MBEDTLS +#include +#endif + +/* The NSS, OS/400, and when not included, OpenSSL and mbed TLS crypto + * libraries do not provide the MD4 hash algorithm, so we use this + * implementation of it */ +#if defined(USE_NSS) || defined(USE_OS400CRYPTO) || \ + (defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) || \ + (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) + +#include "curl_md4.h" +#include "warnless.h" + +#ifndef HAVE_OPENSSL + +#include + +/* Any 32-bit or wider unsigned integer data type will do */ +typedef unsigned int MD4_u32plus; + +typedef struct { + MD4_u32plus lo, hi; + MD4_u32plus a, b, c, d; + unsigned char buffer[64]; + MD4_u32plus block[16]; +} MD4_CTX; + +static void MD4_Init(MD4_CTX *ctx); +static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size); +static void MD4_Final(unsigned char *result, MD4_CTX *ctx); + +/* + * The basic MD4 functions. + * + * F and G are optimized compared to their RFC 1320 definitions, with the + * optimization for F borrowed from Colin Plumb's MD5 implementation. + */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +/* + * The MD4 transformation for all three rounds. + */ +#define STEP(f, a, b, c, d, x, s) \ + (a) += f((b), (c), (d)) + (x); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + * + * The check for little-endian architectures that tolerate unaligned + * memory accesses is just an optimization. Nothing will break if it + * doesn't work. + */ +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define SET(n) \ + (*(MD4_u32plus *)(void *)&ptr[(n) * 4]) +#define GET(n) \ + SET(n) +#else +#define SET(n) \ + (ctx->block[(n)] = \ + (MD4_u32plus)ptr[(n) * 4] | \ + ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \ + ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \ + ((MD4_u32plus)ptr[(n) * 4 + 3] << 24)) +#define GET(n) \ + (ctx->block[(n)]) +#endif + +/* + * This processes one or more 64-byte data blocks, but does NOT update + * the bit counters. There are no alignment requirements. + */ +static const void *body(MD4_CTX *ctx, const void *data, unsigned long size) +{ + const unsigned char *ptr; + MD4_u32plus a, b, c, d; + + ptr = (const unsigned char *)data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + MD4_u32plus saved_a, saved_b, saved_c, saved_d; + + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + +/* Round 1 */ + STEP(F, a, b, c, d, SET(0), 3) + STEP(F, d, a, b, c, SET(1), 7) + STEP(F, c, d, a, b, SET(2), 11) + STEP(F, b, c, d, a, SET(3), 19) + STEP(F, a, b, c, d, SET(4), 3) + STEP(F, d, a, b, c, SET(5), 7) + STEP(F, c, d, a, b, SET(6), 11) + STEP(F, b, c, d, a, SET(7), 19) + STEP(F, a, b, c, d, SET(8), 3) + STEP(F, d, a, b, c, SET(9), 7) + STEP(F, c, d, a, b, SET(10), 11) + STEP(F, b, c, d, a, SET(11), 19) + STEP(F, a, b, c, d, SET(12), 3) + STEP(F, d, a, b, c, SET(13), 7) + STEP(F, c, d, a, b, SET(14), 11) + STEP(F, b, c, d, a, SET(15), 19) + +/* Round 2 */ + STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3) + STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5) + STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9) + STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13) + STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3) + STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5) + STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9) + STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13) + STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3) + STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5) + STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9) + STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13) + STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3) + STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5) + STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9) + STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13) + +/* Round 3 */ + STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3) + STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9) + STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11) + STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15) + STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3) + STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9) + STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11) + STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15) + STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3) + STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9) + STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11) + STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15) + STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3) + STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9) + STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11) + STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while(size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + return ptr; +} + +static void MD4_Init(MD4_CTX *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + + ctx->lo = 0; + ctx->hi = 0; +} + +static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) +{ + MD4_u32plus saved_lo; + unsigned long used; + + saved_lo = ctx->lo; + ctx->lo = (saved_lo + size) & 0x1fffffff; + if(ctx->lo < saved_lo) + ctx->hi++; + ctx->hi += (MD4_u32plus)size >> 29; + + used = saved_lo & 0x3f; + + if(used) { + unsigned long available = 64 - used; + + if(size < available) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, available); + data = (const unsigned char *)data + available; + size -= available; + body(ctx, ctx->buffer, 64); + } + + if(size >= 64) { + data = body(ctx, data, size & ~(unsigned long)0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + +static void MD4_Final(unsigned char *result, MD4_CTX *ctx) +{ + unsigned long used, available; + + used = ctx->lo & 0x3f; + + ctx->buffer[used++] = 0x80; + + available = 64 - used; + + if(available < 8) { + memset(&ctx->buffer[used], 0, available); + body(ctx, ctx->buffer, 64); + used = 0; + available = 64; + } + + memset(&ctx->buffer[used], 0, available - 8); + + ctx->lo <<= 3; + ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff); + ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff); + ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff); + ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff); + ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff); + ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff); + ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff); + ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24); + + body(ctx, ctx->buffer, 64); + + result[0] = curlx_ultouc((ctx->a)&0xff); + result[1] = curlx_ultouc((ctx->a >> 8)&0xff); + result[2] = curlx_ultouc((ctx->a >> 16)&0xff); + result[3] = curlx_ultouc(ctx->a >> 24); + result[4] = curlx_ultouc((ctx->b)&0xff); + result[5] = curlx_ultouc((ctx->b >> 8)&0xff); + result[6] = curlx_ultouc((ctx->b >> 16)&0xff); + result[7] = curlx_ultouc(ctx->b >> 24); + result[8] = curlx_ultouc((ctx->c)&0xff); + result[9] = curlx_ultouc((ctx->c >> 8)&0xff); + result[10] = curlx_ultouc((ctx->c >> 16)&0xff); + result[11] = curlx_ultouc(ctx->c >> 24); + result[12] = curlx_ultouc((ctx->d)&0xff); + result[13] = curlx_ultouc((ctx->d >> 8)&0xff); + result[14] = curlx_ultouc((ctx->d >> 16)&0xff); + result[15] = curlx_ultouc(ctx->d >> 24); + + memset(ctx, 0, sizeof(*ctx)); +} + +#endif + +void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len) +{ + MD4_CTX ctx; + MD4_Init(&ctx); + MD4_Update(&ctx, input, curlx_uztoui(len)); + MD4_Final(output, &ctx); +} + +#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) || + (defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) || + (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) */ diff --git a/libcurl/lib/md5.c b/libcurl/lib/md5.c new file mode 100644 index 0000000..2b81ca4 --- /dev/null +++ b/libcurl/lib/md5.c @@ -0,0 +1,568 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_CRYPTO_AUTH + +#include + +#include "curl_md5.h" +#include "curl_hmac.h" +#include "warnless.h" + +#if defined(USE_GNUTLS_NETTLE) + +#include +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +typedef struct md5_ctx MD5_CTX; + +static void MD5_Init(MD5_CTX *ctx) +{ + md5_init(ctx); +} + +static void MD5_Update(MD5_CTX *ctx, + const unsigned char *input, + unsigned int inputLen) +{ + md5_update(ctx, inputLen, input); +} + +static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) +{ + md5_digest(ctx, 16, digest); +} + +#elif defined(USE_GNUTLS) + +#include +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +typedef gcry_md_hd_t MD5_CTX; + +static void MD5_Init(MD5_CTX *ctx) +{ + gcry_md_open(ctx, GCRY_MD_MD5, 0); +} + +static void MD5_Update(MD5_CTX *ctx, + const unsigned char *input, + unsigned int inputLen) +{ + gcry_md_write(*ctx, input, inputLen); +} + +static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) +{ + memcpy(digest, gcry_md_read(*ctx, 0), 16); + gcry_md_close(*ctx); +} + +#elif defined(USE_OPENSSL) && !defined(USE_AMISSL) +/* When OpenSSL is available we use the MD5-function from OpenSSL */ +#include +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ + (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \ + (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ + (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000)) + +/* For Apple operating systems: CommonCrypto has the functions we need. + These functions are available on Tiger and later, as well as iOS 2.0 + and later. If you're building for an older cat, well, sorry. + + Declaring the functions as static like this seems to be a bit more + reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */ +# include +# define MD5_CTX CC_MD5_CTX +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +static void MD5_Init(MD5_CTX *ctx) +{ + CC_MD5_Init(ctx); +} + +static void MD5_Update(MD5_CTX *ctx, + const unsigned char *input, + unsigned int inputLen) +{ + CC_MD5_Update(ctx, input, inputLen); +} + +static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) +{ + CC_MD5_Final(digest, ctx); +} + +#elif defined(WIN32) && !defined(CURL_WINDOWS_APP) + +#include +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +typedef struct { + HCRYPTPROV hCryptProv; + HCRYPTHASH hHash; +} MD5_CTX; + +static void MD5_Init(MD5_CTX *ctx) +{ + if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash); + } +} + +static void MD5_Update(MD5_CTX *ctx, + const unsigned char *input, + unsigned int inputLen) +{ + CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0); +} + +static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) +{ + unsigned long length = 0; + CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); + if(length == 16) + CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0); + if(ctx->hHash) + CryptDestroyHash(ctx->hHash); + if(ctx->hCryptProv) + CryptReleaseContext(ctx->hCryptProv, 0); +} + +#else +/* When no other crypto library is available we use this code segment */ +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. + * MD5 Message-Digest Algorithm (RFC 1321). + * + * Homepage: + https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + * + * Author: + * Alexander Peslyak, better known as Solar Designer + * + * This software was written by Alexander Peslyak in 2001. No copyright is + * claimed, and the software is hereby placed in the public domain. + * In case this attempt to disclaim copyright and place the software in the + * public domain is deemed null and void, then the software is + * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * (This is a heavily cut-down "BSD license".) + * + * This differs from Colin Plumb's older public domain implementation in that + * no exactly 32-bit integer data type is required (any 32-bit or wider + * unsigned integer data type will do), there's no compile-time endianness + * configuration, and the function prototypes match OpenSSL's. No code from + * Colin Plumb's implementation has been reused; this comment merely compares + * the properties of the two independent implementations. + * + * The primary goals of this implementation are portability and ease of use. + * It is meant to be fast, but not as fast as possible. Some known + * optimizations are not included to reduce source code size and avoid + * compile-time configuration. + */ + +#include + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* Any 32-bit or wider unsigned integer data type will do */ +typedef unsigned int MD5_u32plus; + +typedef struct { + MD5_u32plus lo, hi; + MD5_u32plus a, b, c, d; + unsigned char buffer[64]; + MD5_u32plus block[16]; +} MD5_CTX; + +static void MD5_Init(MD5_CTX *ctx); +static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size); +static void MD5_Final(unsigned char *result, MD5_CTX *ctx); + +/* + * The basic MD5 functions. + * + * F and G are optimized compared to their RFC 1321 definitions for + * architectures that lack an AND-NOT instruction, just like in Colin Plumb's + * implementation. + */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) (((x) ^ (y)) ^ (z)) +#define H2(x, y, z) ((x) ^ ((y) ^ (z))) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) + +/* + * The MD5 transformation for all four rounds. + */ +#define STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + * + * The check for little-endian architectures that tolerate unaligned + * memory accesses is just an optimization. Nothing will break if it + * doesn't work. + */ +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define SET(n) \ + (*(MD5_u32plus *)(void *)&ptr[(n) * 4]) +#define GET(n) \ + SET(n) +#else +#define SET(n) \ + (ctx->block[(n)] = \ + (MD5_u32plus)ptr[(n) * 4] | \ + ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ + ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ + ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) +#define GET(n) \ + (ctx->block[(n)]) +#endif + +/* + * This processes one or more 64-byte data blocks, but does NOT update + * the bit counters. There are no alignment requirements. + */ +static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) +{ + const unsigned char *ptr; + MD5_u32plus a, b, c, d; + + ptr = (const unsigned char *)data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + MD5_u32plus saved_a, saved_b, saved_c, saved_d; + + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + +/* Round 1 */ + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) + +/* Round 2 */ + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) + +/* Round 3 */ + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) + STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) + STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) + STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) + STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) + STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) + STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) + STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) + STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) + +/* Round 4 */ + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while(size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + return ptr; +} + +static void MD5_Init(MD5_CTX *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + + ctx->lo = 0; + ctx->hi = 0; +} + +static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) +{ + MD5_u32plus saved_lo; + unsigned long used; + + saved_lo = ctx->lo; + ctx->lo = (saved_lo + size) & 0x1fffffff; + if(ctx->lo < saved_lo) + ctx->hi++; + ctx->hi += (MD5_u32plus)size >> 29; + + used = saved_lo & 0x3f; + + if(used) { + unsigned long available = 64 - used; + + if(size < available) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, available); + data = (const unsigned char *)data + available; + size -= available; + body(ctx, ctx->buffer, 64); + } + + if(size >= 64) { + data = body(ctx, data, size & ~(unsigned long)0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + +static void MD5_Final(unsigned char *result, MD5_CTX *ctx) +{ + unsigned long used, available; + + used = ctx->lo & 0x3f; + + ctx->buffer[used++] = 0x80; + + available = 64 - used; + + if(available < 8) { + memset(&ctx->buffer[used], 0, available); + body(ctx, ctx->buffer, 64); + used = 0; + available = 64; + } + + memset(&ctx->buffer[used], 0, available - 8); + + ctx->lo <<= 3; + ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff); + ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff); + ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff); + ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24); + ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff); + ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff); + ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff); + ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24); + + body(ctx, ctx->buffer, 64); + + result[0] = curlx_ultouc((ctx->a)&0xff); + result[1] = curlx_ultouc((ctx->a >> 8)&0xff); + result[2] = curlx_ultouc((ctx->a >> 16)&0xff); + result[3] = curlx_ultouc(ctx->a >> 24); + result[4] = curlx_ultouc((ctx->b)&0xff); + result[5] = curlx_ultouc((ctx->b >> 8)&0xff); + result[6] = curlx_ultouc((ctx->b >> 16)&0xff); + result[7] = curlx_ultouc(ctx->b >> 24); + result[8] = curlx_ultouc((ctx->c)&0xff); + result[9] = curlx_ultouc((ctx->c >> 8)&0xff); + result[10] = curlx_ultouc((ctx->c >> 16)&0xff); + result[11] = curlx_ultouc(ctx->c >> 24); + result[12] = curlx_ultouc((ctx->d)&0xff); + result[13] = curlx_ultouc((ctx->d >> 8)&0xff); + result[14] = curlx_ultouc((ctx->d >> 16)&0xff); + result[15] = curlx_ultouc(ctx->d >> 24); + + memset(ctx, 0, sizeof(*ctx)); +} + +#endif /* CRYPTO LIBS */ + +const HMAC_params Curl_HMAC_MD5[] = { + { + /* Hash initialization function. */ + CURLX_FUNCTION_CAST(HMAC_hinit_func, MD5_Init), + /* Hash update function. */ + CURLX_FUNCTION_CAST(HMAC_hupdate_func, MD5_Update), + /* Hash computation end function. */ + CURLX_FUNCTION_CAST(HMAC_hfinal_func, MD5_Final), + /* Size of hash context structure. */ + sizeof(MD5_CTX), + /* Maximum key length. */ + 64, + /* Result size. */ + 16 + } +}; + +const MD5_params Curl_DIGEST_MD5[] = { + { + /* Digest initialization function */ + CURLX_FUNCTION_CAST(Curl_MD5_init_func, MD5_Init), + /* Digest update function */ + CURLX_FUNCTION_CAST(Curl_MD5_update_func, MD5_Update), + /* Digest computation end function */ + CURLX_FUNCTION_CAST(Curl_MD5_final_func, MD5_Final), + /* Size of digest context struct */ + sizeof(MD5_CTX), + /* Result size */ + 16 + } +}; + +/* + * @unittest: 1601 + */ +void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */ + const unsigned char *input) +{ + MD5_CTX ctx; + MD5_Init(&ctx); + MD5_Update(&ctx, input, curlx_uztoui(strlen((char *)input))); + MD5_Final(outbuffer, &ctx); +} + +MD5_context *Curl_MD5_init(const MD5_params *md5params) +{ + MD5_context *ctxt; + + /* Create MD5 context */ + ctxt = malloc(sizeof(*ctxt)); + + if(!ctxt) + return ctxt; + + ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize); + + if(!ctxt->md5_hashctx) { + free(ctxt); + return NULL; + } + + ctxt->md5_hash = md5params; + + (*md5params->md5_init_func)(ctxt->md5_hashctx); + + return ctxt; +} + +CURLcode Curl_MD5_update(MD5_context *context, + const unsigned char *data, + unsigned int len) +{ + (*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len); + + return CURLE_OK; +} + +CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result) +{ + (*context->md5_hash->md5_final_func)(result, context->md5_hashctx); + + free(context->md5_hashctx); + free(context); + + return CURLE_OK; +} + +#endif /* CURL_DISABLE_CRYPTO_AUTH */ diff --git a/libcurl/lib/memdebug.c b/libcurl/lib/memdebug.c new file mode 100644 index 0000000..ede6009 --- /dev/null +++ b/libcurl/lib/memdebug.c @@ -0,0 +1,503 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef CURLDEBUG + +#include + +#include "urldata.h" + +#define MEMDEBUG_NODEFINES /* don't redefine the standard functions */ + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Until 2011-08-17 libcurl's Memory Tracking feature also performed + * automatic malloc and free filling operations using 0xA5 and 0x13 + * values. Our own preinitialization of dynamically allocated memory + * might be useful when not using third party memory debuggers, but + * on the other hand this would fool memory debuggers into thinking + * that all dynamically allocated memory is properly initialized. + * + * As a default setting, libcurl's Memory Tracking feature no longer + * performs preinitialization of dynamically allocated memory on its + * own. If you know what you are doing, and really want to retain old + * behavior, you can achieve this compiling with preprocessor symbols + * CURL_MT_MALLOC_FILL and CURL_MT_FREE_FILL defined with appropriate + * values. + */ + +#ifdef CURL_MT_MALLOC_FILL +# if (CURL_MT_MALLOC_FILL < 0) || (CURL_MT_MALLOC_FILL > 0xff) +# error "invalid CURL_MT_MALLOC_FILL or out of range" +# endif +#endif + +#ifdef CURL_MT_FREE_FILL +# if (CURL_MT_FREE_FILL < 0) || (CURL_MT_FREE_FILL > 0xff) +# error "invalid CURL_MT_FREE_FILL or out of range" +# endif +#endif + +#if defined(CURL_MT_MALLOC_FILL) && defined(CURL_MT_FREE_FILL) +# if (CURL_MT_MALLOC_FILL == CURL_MT_FREE_FILL) +# error "CURL_MT_MALLOC_FILL same as CURL_MT_FREE_FILL" +# endif +#endif + +#ifdef CURL_MT_MALLOC_FILL +# define mt_malloc_fill(buf,len) memset((buf), CURL_MT_MALLOC_FILL, (len)) +#else +# define mt_malloc_fill(buf,len) Curl_nop_stmt +#endif + +#ifdef CURL_MT_FREE_FILL +# define mt_free_fill(buf,len) memset((buf), CURL_MT_FREE_FILL, (len)) +#else +# define mt_free_fill(buf,len) Curl_nop_stmt +#endif + +struct memdebug { + size_t size; + union { + curl_off_t o; + double d; + void *p; + } mem[1]; + /* I'm hoping this is the thing with the strictest alignment + * requirements. That also means we waste some space :-( */ +}; + +/* + * Note that these debug functions are very simple and they are meant to + * remain so. For advanced analysis, record a log file and write perl scripts + * to analyze them! + * + * Don't use these with multithreaded test programs! + */ + +FILE *curl_dbg_logfile = NULL; +static bool memlimit = FALSE; /* enable memory limit */ +static long memsize = 0; /* set number of mallocs allowed */ + +/* this sets the log file name */ +void curl_dbg_memdebug(const char *logname) +{ + if(!curl_dbg_logfile) { + if(logname && *logname) + curl_dbg_logfile = fopen(logname, FOPEN_WRITETEXT); + else + curl_dbg_logfile = stderr; +#ifdef MEMDEBUG_LOG_SYNC + /* Flush the log file after every line so the log isn't lost in a crash */ + if(curl_dbg_logfile) + setbuf(curl_dbg_logfile, (char *)NULL); +#endif + } +} + +/* This function sets the number of malloc() calls that should return + successfully! */ +void curl_dbg_memlimit(long limit) +{ + if(!memlimit) { + memlimit = TRUE; + memsize = limit; + } +} + +/* returns TRUE if this isn't allowed! */ +static bool countcheck(const char *func, int line, const char *source) +{ + /* if source is NULL, then the call is made internally and this check + should not be made */ + if(memlimit && source) { + if(!memsize) { + if(source) { + /* log to file */ + curl_dbg_log("LIMIT %s:%d %s reached memlimit\n", + source, line, func); + /* log to stderr also */ + fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n", + source, line, func); + fflush(curl_dbg_logfile); /* because it might crash now */ + } + errno = ENOMEM; + return TRUE; /* RETURN ERROR! */ + } + else + memsize--; /* countdown */ + + + } + + return FALSE; /* allow this */ +} + +void *curl_dbg_malloc(size_t wantedsize, int line, const char *source) +{ + struct memdebug *mem; + size_t size; + + DEBUGASSERT(wantedsize != 0); + + if(countcheck("malloc", line, source)) + return NULL; + + /* alloc at least 64 bytes */ + size = sizeof(struct memdebug) + wantedsize; + + mem = (Curl_cmalloc)(size); + if(mem) { + /* fill memory with junk */ + mt_malloc_fill(mem->mem, wantedsize); + mem->size = wantedsize; + } + + if(source) + curl_dbg_log("MEM %s:%d malloc(%zu) = %p\n", + source, line, wantedsize, + mem ? (void *)mem->mem : (void *)0); + + return (mem ? mem->mem : NULL); +} + +void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size, + int line, const char *source) +{ + struct memdebug *mem; + size_t size, user_size; + + DEBUGASSERT(wanted_elements != 0); + DEBUGASSERT(wanted_size != 0); + + if(countcheck("calloc", line, source)) + return NULL; + + /* alloc at least 64 bytes */ + user_size = wanted_size * wanted_elements; + size = sizeof(struct memdebug) + user_size; + + mem = (Curl_ccalloc)(1, size); + if(mem) + mem->size = user_size; + + if(source) + curl_dbg_log("MEM %s:%d calloc(%zu,%zu) = %p\n", + source, line, wanted_elements, wanted_size, + mem ? (void *)mem->mem : (void *)0); + + return (mem ? mem->mem : NULL); +} + +char *curl_dbg_strdup(const char *str, int line, const char *source) +{ + char *mem; + size_t len; + + DEBUGASSERT(str != NULL); + + if(countcheck("strdup", line, source)) + return NULL; + + len = strlen(str) + 1; + + mem = curl_dbg_malloc(len, 0, NULL); /* NULL prevents logging */ + if(mem) + memcpy(mem, str, len); + + if(source) + curl_dbg_log("MEM %s:%d strdup(%p) (%zu) = %p\n", + source, line, (const void *)str, len, (const void *)mem); + + return mem; +} + +#if defined(WIN32) && defined(UNICODE) +wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source) +{ + wchar_t *mem; + size_t wsiz, bsiz; + + DEBUGASSERT(str != NULL); + + if(countcheck("wcsdup", line, source)) + return NULL; + + wsiz = wcslen(str) + 1; + bsiz = wsiz * sizeof(wchar_t); + + mem = curl_dbg_malloc(bsiz, 0, NULL); /* NULL prevents logging */ + if(mem) + memcpy(mem, str, bsiz); + + if(source) + curl_dbg_log("MEM %s:%d wcsdup(%p) (%zu) = %p\n", + source, line, (void *)str, bsiz, (void *)mem); + + return mem; +} +#endif + +/* We provide a realloc() that accepts a NULL as pointer, which then + performs a malloc(). In order to work with ares. */ +void *curl_dbg_realloc(void *ptr, size_t wantedsize, + int line, const char *source) +{ + struct memdebug *mem = NULL; + + size_t size = sizeof(struct memdebug) + wantedsize; + + DEBUGASSERT(wantedsize != 0); + + if(countcheck("realloc", line, source)) + return NULL; + +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:1684) + /* 1684: conversion from pointer to same-sized integral type */ +#endif + + if(ptr) + mem = (void *)((char *)ptr - offsetof(struct memdebug, mem)); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif + + mem = (Curl_crealloc)(mem, size); + if(source) + curl_dbg_log("MEM %s:%d realloc(%p, %zu) = %p\n", + source, line, (void *)ptr, wantedsize, + mem ? (void *)mem->mem : (void *)0); + + if(mem) { + mem->size = wantedsize; + return mem->mem; + } + + return NULL; +} + +void curl_dbg_free(void *ptr, int line, const char *source) +{ + if(ptr) { + struct memdebug *mem; + +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:1684) + /* 1684: conversion from pointer to same-sized integral type */ +#endif + + mem = (void *)((char *)ptr - offsetof(struct memdebug, mem)); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif + + /* destroy */ + mt_free_fill(mem->mem, mem->size); + + /* free for real */ + (Curl_cfree)(mem); + } + + if(source) + curl_dbg_log("MEM %s:%d free(%p)\n", source, line, (void *)ptr); +} + +curl_socket_t curl_dbg_socket(int domain, int type, int protocol, + int line, const char *source) +{ + const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? + "FD %s:%d socket() = %d\n" : + (sizeof(curl_socket_t) == sizeof(long)) ? + "FD %s:%d socket() = %ld\n" : + "FD %s:%d socket() = %zd\n"; + + curl_socket_t sockfd; + + if(countcheck("socket", line, source)) + return CURL_SOCKET_BAD; + + sockfd = socket(domain, type, protocol); + + if(source && (sockfd != CURL_SOCKET_BAD)) + curl_dbg_log(fmt, source, line, sockfd); + + return sockfd; +} + +SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd, + SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, + SEND_TYPE_ARG3 len, SEND_TYPE_ARG4 flags, int line, + const char *source) +{ + SEND_TYPE_RETV rc; + if(countcheck("send", line, source)) + return -1; + rc = send(sockfd, buf, len, flags); + if(source) + curl_dbg_log("SEND %s:%d send(%lu) = %ld\n", + source, line, (unsigned long)len, (long)rc); + return rc; +} + +RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf, + RECV_TYPE_ARG3 len, RECV_TYPE_ARG4 flags, int line, + const char *source) +{ + RECV_TYPE_RETV rc; + if(countcheck("recv", line, source)) + return -1; + rc = recv(sockfd, buf, len, flags); + if(source) + curl_dbg_log("RECV %s:%d recv(%lu) = %ld\n", + source, line, (unsigned long)len, (long)rc); + return rc; +} + +#ifdef HAVE_SOCKETPAIR +int curl_dbg_socketpair(int domain, int type, int protocol, + curl_socket_t socket_vector[2], + int line, const char *source) +{ + const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? + "FD %s:%d socketpair() = %d %d\n" : + (sizeof(curl_socket_t) == sizeof(long)) ? + "FD %s:%d socketpair() = %ld %ld\n" : + "FD %s:%d socketpair() = %zd %zd\n"; + + int res = socketpair(domain, type, protocol, socket_vector); + + if(source && (0 == res)) + curl_dbg_log(fmt, source, line, socket_vector[0], socket_vector[1]); + + return res; +} +#endif + +curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen, + int line, const char *source) +{ + const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? + "FD %s:%d accept() = %d\n" : + (sizeof(curl_socket_t) == sizeof(long)) ? + "FD %s:%d accept() = %ld\n" : + "FD %s:%d accept() = %zd\n"; + + struct sockaddr *addr = (struct sockaddr *)saddr; + curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen; + + curl_socket_t sockfd = accept(s, addr, addrlen); + + if(source && (sockfd != CURL_SOCKET_BAD)) + curl_dbg_log(fmt, source, line, sockfd); + + return sockfd; +} + +/* separate function to allow libcurl to mark a "faked" close */ +void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source) +{ + const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? + "FD %s:%d sclose(%d)\n": + (sizeof(curl_socket_t) == sizeof(long)) ? + "FD %s:%d sclose(%ld)\n": + "FD %s:%d sclose(%zd)\n"; + + if(source) + curl_dbg_log(fmt, source, line, sockfd); +} + +/* this is our own defined way to close sockets on *ALL* platforms */ +int curl_dbg_sclose(curl_socket_t sockfd, int line, const char *source) +{ + int res = sclose(sockfd); + curl_dbg_mark_sclose(sockfd, line, source); + return res; +} + +FILE *curl_dbg_fopen(const char *file, const char *mode, + int line, const char *source) +{ + FILE *res = fopen(file, mode); + + if(source) + curl_dbg_log("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n", + source, line, file, mode, (void *)res); + + return res; +} + +int curl_dbg_fclose(FILE *file, int line, const char *source) +{ + int res; + + DEBUGASSERT(file != NULL); + + if(source) + curl_dbg_log("FILE %s:%d fclose(%p)\n", + source, line, (void *)file); + + res = fclose(file); + + return res; +} + +#define LOGLINE_BUFSIZE 1024 + +/* this does the writing to the memory tracking log file */ +void curl_dbg_log(const char *format, ...) +{ + char *buf; + int nchars; + va_list ap; + + if(!curl_dbg_logfile) + return; + + buf = (Curl_cmalloc)(LOGLINE_BUFSIZE); + if(!buf) + return; + + va_start(ap, format); + nchars = mvsnprintf(buf, LOGLINE_BUFSIZE, format, ap); + va_end(ap); + + if(nchars > LOGLINE_BUFSIZE - 1) + nchars = LOGLINE_BUFSIZE - 1; + + if(nchars > 0) + fwrite(buf, 1, (size_t)nchars, curl_dbg_logfile); + + (Curl_cfree)(buf); +} + +#endif /* CURLDEBUG */ diff --git a/libcurl/lib/memdebug.h b/libcurl/lib/memdebug.h new file mode 100644 index 0000000..5236f60 --- /dev/null +++ b/libcurl/lib/memdebug.h @@ -0,0 +1,174 @@ +#ifndef HEADER_CURL_MEMDEBUG_H +#define HEADER_CURL_MEMDEBUG_H +#ifdef CURLDEBUG +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * CAUTION: this header is designed to work when included by the app-side + * as well as the library. Do not mix with library internals! + */ + +#define CURL_MT_LOGFNAME_BUFSIZE 512 + +extern FILE *curl_dbg_logfile; + +/* memory functions */ +CURL_EXTERN void *curl_dbg_malloc(size_t size, int line, const char *source); +CURL_EXTERN void *curl_dbg_calloc(size_t elements, size_t size, int line, + const char *source); +CURL_EXTERN void *curl_dbg_realloc(void *ptr, size_t size, int line, + const char *source); +CURL_EXTERN void curl_dbg_free(void *ptr, int line, const char *source); +CURL_EXTERN char *curl_dbg_strdup(const char *str, int line, const char *src); +#if defined(WIN32) && defined(UNICODE) +CURL_EXTERN wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, + const char *source); +#endif + +CURL_EXTERN void curl_dbg_memdebug(const char *logname); +CURL_EXTERN void curl_dbg_memlimit(long limit); +CURL_EXTERN void curl_dbg_log(const char *format, ...); + +/* file descriptor manipulators */ +CURL_EXTERN curl_socket_t curl_dbg_socket(int domain, int type, int protocol, + int line, const char *source); +CURL_EXTERN void curl_dbg_mark_sclose(curl_socket_t sockfd, + int line, const char *source); +CURL_EXTERN int curl_dbg_sclose(curl_socket_t sockfd, + int line, const char *source); +CURL_EXTERN curl_socket_t curl_dbg_accept(curl_socket_t s, void *a, void *alen, + int line, const char *source); +#ifdef HAVE_SOCKETPAIR +CURL_EXTERN int curl_dbg_socketpair(int domain, int type, int protocol, + curl_socket_t socket_vector[2], + int line, const char *source); +#endif + +/* send/receive sockets */ +CURL_EXTERN SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd, + SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf, + SEND_TYPE_ARG3 len, + SEND_TYPE_ARG4 flags, int line, + const char *source); +CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, + RECV_TYPE_ARG2 buf, + RECV_TYPE_ARG3 len, + RECV_TYPE_ARG4 flags, int line, + const char *source); + +/* FILE functions */ +CURL_EXTERN FILE *curl_dbg_fopen(const char *file, const char *mode, int line, + const char *source); +CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); + +#ifndef MEMDEBUG_NODEFINES + +/* Set this symbol on the command-line, recompile all lib-sources */ +#undef strdup +#define strdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__) +#define malloc(size) curl_dbg_malloc(size, __LINE__, __FILE__) +#define calloc(nbelem,size) curl_dbg_calloc(nbelem, size, __LINE__, __FILE__) +#define realloc(ptr,size) curl_dbg_realloc(ptr, size, __LINE__, __FILE__) +#define free(ptr) curl_dbg_free(ptr, __LINE__, __FILE__) +#define send(a,b,c,d) curl_dbg_send(a,b,c,d, __LINE__, __FILE__) +#define recv(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__) + +#ifdef WIN32 +# ifdef UNICODE +# undef wcsdup +# define wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) +# undef _wcsdup +# define _wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) +# undef _tcsdup +# define _tcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__) +# else +# undef _tcsdup +# define _tcsdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__) +# endif +#endif + +#undef socket +#define socket(domain,type,protocol)\ + curl_dbg_socket(domain, type, protocol, __LINE__, __FILE__) +#undef accept /* for those with accept as a macro */ +#define accept(sock,addr,len)\ + curl_dbg_accept(sock, addr, len, __LINE__, __FILE__) +#ifdef HAVE_SOCKETPAIR +#define socketpair(domain,type,protocol,socket_vector)\ + curl_dbg_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__) +#endif + +#ifdef HAVE_GETADDRINFO +#if defined(getaddrinfo) && defined(__osf__) +/* OSF/1 and Tru64 have getaddrinfo as a define already, so we cannot define + our macro as for other platforms. Instead, we redefine the new name they + define getaddrinfo to become! */ +#define ogetaddrinfo(host,serv,hint,res) \ + curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__) +#else +#undef getaddrinfo +#define getaddrinfo(host,serv,hint,res) \ + curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__) +#endif +#endif /* HAVE_GETADDRINFO */ + +#ifdef HAVE_FREEADDRINFO +#undef freeaddrinfo +#define freeaddrinfo(data) \ + curl_dbg_freeaddrinfo(data, __LINE__, __FILE__) +#endif /* HAVE_FREEADDRINFO */ + +/* sclose is probably already defined, redefine it! */ +#undef sclose +#define sclose(sockfd) curl_dbg_sclose(sockfd,__LINE__,__FILE__) + +#define fake_sclose(sockfd) curl_dbg_mark_sclose(sockfd,__LINE__,__FILE__) + +#undef fopen +#define fopen(file,mode) curl_dbg_fopen(file,mode,__LINE__,__FILE__) +#undef fdopen +#define fdopen(file,mode) curl_dbg_fdopen(file,mode,__LINE__,__FILE__) +#define fclose(file) curl_dbg_fclose(file,__LINE__,__FILE__) + +#endif /* MEMDEBUG_NODEFINES */ + +#endif /* CURLDEBUG */ + +/* +** Following section applies even when CURLDEBUG is not defined. +*/ + +#ifndef fake_sclose +#define fake_sclose(x) Curl_nop_stmt +#endif + +/* + * Curl_safefree defined as a macro to allow MemoryTracking feature + * to log free() calls at same location where Curl_safefree is used. + * This macro also assigns NULL to given pointer when free'd. + */ + +#define Curl_safefree(ptr) \ + do { free((ptr)); (ptr) = NULL;} WHILE_FALSE + +#endif /* HEADER_CURL_MEMDEBUG_H */ diff --git a/libcurl/lib/mime.c b/libcurl/lib/mime.c new file mode 100644 index 0000000..2135f72 --- /dev/null +++ b/libcurl/lib/mime.c @@ -0,0 +1,1904 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "mime.h" +#include "non-ascii.h" +#include "urldata.h" +#include "sendf.h" + +#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \ + !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP) + +#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) +#include +#endif + +#include "rand.h" +#include "slist.h" +#include "strcase.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#ifdef WIN32 +# ifndef R_OK +# define R_OK 4 +# endif +#endif + + +#define READ_ERROR ((size_t) -1) + +/* Encoders. */ +static size_t encoder_nop_read(char *buffer, size_t size, bool ateof, + curl_mimepart *part); +static curl_off_t encoder_nop_size(curl_mimepart *part); +static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof, + curl_mimepart *part); +static size_t encoder_base64_read(char *buffer, size_t size, bool ateof, + curl_mimepart *part); +static curl_off_t encoder_base64_size(curl_mimepart *part); +static size_t encoder_qp_read(char *buffer, size_t size, bool ateof, + curl_mimepart *part); +static curl_off_t encoder_qp_size(curl_mimepart *part); + +static const mime_encoder encoders[] = { + {"binary", encoder_nop_read, encoder_nop_size}, + {"8bit", encoder_nop_read, encoder_nop_size}, + {"7bit", encoder_7bit_read, encoder_nop_size}, + {"base64", encoder_base64_read, encoder_base64_size}, + {"quoted-printable", encoder_qp_read, encoder_qp_size}, + {ZERO_NULL, ZERO_NULL, ZERO_NULL} +}; + +/* Base64 encoding table */ +static const char base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* Quoted-printable character class table. + * + * We cannot rely on ctype functions since quoted-printable input data + * is assumed to be ascii-compatible, even on non-ascii platforms. */ +#define QP_OK 1 /* Can be represented by itself. */ +#define QP_SP 2 /* Space or tab. */ +#define QP_CR 3 /* Carriage return. */ +#define QP_LF 4 /* Line-feed. */ +static const unsigned char qp_class[] = { + 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 07 */ + 0, QP_SP, QP_LF, 0, 0, QP_CR, 0, 0, /* 08 - 0F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 17 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 18 - 1F */ + QP_SP, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 20 - 27 */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 28 - 2F */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 30 - 37 */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0 , QP_OK, QP_OK, /* 38 - 3F */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 40 - 47 */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 48 - 4F */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 50 - 57 */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 58 - 5F */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 60 - 67 */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 68 - 6F */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, /* 70 - 77 */ + QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0, /* 78 - 7F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */ +}; + + +/* Binary --> hexadecimal ASCII table. */ +static const char aschex[] = + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x41\x42\x43\x44\x45\x46"; + + + +#ifndef __VMS +#define filesize(name, stat_data) (stat_data.st_size) +#define fopen_read fopen + +#else + +#include +/* + * get_vms_file_size does what it takes to get the real size of the file + * + * For fixed files, find out the size of the EOF block and adjust. + * + * For all others, have to read the entire file in, discarding the contents. + * Most posted text files will be small, and binary files like zlib archives + * and CD/DVD images should be either a STREAM_LF format or a fixed format. + * + */ +curl_off_t VmsRealFileSize(const char *name, + const struct_stat *stat_buf) +{ + char buffer[8192]; + curl_off_t count; + int ret_stat; + FILE * file; + + file = fopen(name, FOPEN_READTEXT); /* VMS */ + if(file == NULL) + return 0; + + count = 0; + ret_stat = 1; + while(ret_stat > 0) { + ret_stat = fread(buffer, 1, sizeof(buffer), file); + if(ret_stat != 0) + count += ret_stat; + } + fclose(file); + + return count; +} + +/* + * + * VmsSpecialSize checks to see if the stat st_size can be trusted and + * if not to call a routine to get the correct size. + * + */ +static curl_off_t VmsSpecialSize(const char *name, + const struct_stat *stat_buf) +{ + switch(stat_buf->st_fab_rfm) { + case FAB$C_VAR: + case FAB$C_VFC: + return VmsRealFileSize(name, stat_buf); + break; + default: + return stat_buf->st_size; + } +} + +#define filesize(name, stat_data) VmsSpecialSize(name, &stat_data) + +/* + * vmsfopenread + * + * For upload to work as expected on VMS, different optional + * parameters must be added to the fopen command based on + * record format of the file. + * + */ +static FILE * vmsfopenread(const char *file, const char *mode) +{ + struct_stat statbuf; + int result; + + result = stat(file, &statbuf); + + switch(statbuf.st_fab_rfm) { + case FAB$C_VAR: + case FAB$C_VFC: + case FAB$C_STMCR: + return fopen(file, FOPEN_READTEXT); /* VMS */ + break; + default: + return fopen(file, FOPEN_READTEXT, "rfm=stmlf", "ctx=stm"); + } +} + +#define fopen_read vmsfopenread +#endif + + +#ifndef HAVE_BASENAME +/* + (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 + Edition) + + The basename() function shall take the pathname pointed to by path and + return a pointer to the final component of the pathname, deleting any + trailing '/' characters. + + If the string pointed to by path consists entirely of the '/' character, + basename() shall return a pointer to the string "/". If the string pointed + to by path is exactly "//", it is implementation-defined whether '/' or "//" + is returned. + + If path is a null pointer or points to an empty string, basename() shall + return a pointer to the string ".". + + The basename() function may modify the string pointed to by path, and may + return a pointer to static storage that may then be overwritten by a + subsequent call to basename(). + + The basename() function need not be reentrant. A function that is not + required to be reentrant is not required to be thread-safe. + +*/ +static char *Curl_basename(char *path) +{ + /* Ignore all the details above for now and make a quick and simple + implementation here */ + char *s1; + char *s2; + + s1 = strrchr(path, '/'); + s2 = strrchr(path, '\\'); + + if(s1 && s2) { + path = (s1 > s2? s1 : s2) + 1; + } + else if(s1) + path = s1 + 1; + else if(s2) + path = s2 + 1; + + return path; +} + +#define basename(x) Curl_basename((x)) +#endif + + +/* Set readback state. */ +static void mimesetstate(mime_state *state, enum mimestate tok, void *ptr) +{ + state->state = tok; + state->ptr = ptr; + state->offset = 0; +} + + +/* Escape header string into allocated memory. */ +static char *escape_string(const char *src) +{ + size_t bytecount = 0; + size_t i; + char *dst; + + for(i = 0; src[i]; i++) + if(src[i] == '"' || src[i] == '\\') + bytecount++; + + bytecount += i; + dst = malloc(bytecount + 1); + if(!dst) + return NULL; + + for(i = 0; *src; src++) { + if(*src == '"' || *src == '\\') + dst[i++] = '\\'; + dst[i++] = *src; + } + + dst[i] = '\0'; + return dst; +} + +/* Check if header matches. */ +static char *match_header(struct curl_slist *hdr, const char *lbl, size_t len) +{ + char *value = NULL; + + if(strncasecompare(hdr->data, lbl, len) && hdr->data[len] == ':') + for(value = hdr->data + len + 1; *value == ' '; value++) + ; + return value; +} + +/* Get a header from an slist. */ +static char *search_header(struct curl_slist *hdrlist, const char *hdr) +{ + size_t len = strlen(hdr); + char *value = NULL; + + for(; !value && hdrlist; hdrlist = hdrlist->next) + value = match_header(hdrlist, hdr, len); + + return value; +} + +static char *strippath(const char *fullfile) +{ + char *filename; + char *base; + filename = strdup(fullfile); /* duplicate since basename() may ruin the + buffer it works on */ + if(!filename) + return NULL; + base = strdup(basename(filename)); + + free(filename); /* free temporary buffer */ + + return base; /* returns an allocated string or NULL ! */ +} + +/* Initialize data encoder state. */ +static void cleanup_encoder_state(mime_encoder_state *p) +{ + p->pos = 0; + p->bufbeg = 0; + p->bufend = 0; +} + + +/* Dummy encoder. This is used for 8bit and binary content encodings. */ +static size_t encoder_nop_read(char *buffer, size_t size, bool ateof, + curl_mimepart *part) +{ + mime_encoder_state *st = &part->encstate; + size_t insize = st->bufend - st->bufbeg; + + (void) ateof; + + if(size > insize) + size = insize; + if(size) + memcpy(buffer, st->buf, size); + st->bufbeg += size; + return size; +} + +static curl_off_t encoder_nop_size(curl_mimepart *part) +{ + return part->datasize; +} + + +/* 7bit encoder: the encoder is just a data validity check. */ +static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof, + curl_mimepart *part) +{ + mime_encoder_state *st = &part->encstate; + size_t cursize = st->bufend - st->bufbeg; + + (void) ateof; + + if(size > cursize) + size = cursize; + + for(cursize = 0; cursize < size; cursize++) { + *buffer = st->buf[st->bufbeg]; + if(*buffer++ & 0x80) + return cursize? cursize: READ_ERROR; + st->bufbeg++; + } + + return cursize; +} + + +/* Base64 content encoder. */ +static size_t encoder_base64_read(char *buffer, size_t size, bool ateof, + curl_mimepart *part) +{ + mime_encoder_state *st = &part->encstate; + size_t cursize = 0; + int i; + char *ptr = buffer; + + while(st->bufbeg < st->bufend) { + /* Line full ? */ + if(st->pos > MAX_ENCODED_LINE_LENGTH - 4) { + /* Yes, we need 2 characters for CRLF. */ + if(size < 2) + break; + *ptr++ = '\r'; + *ptr++ = '\n'; + st->pos = 0; + cursize += 2; + size -= 2; + } + + /* Be sure there is enough space and input data for a base64 group. */ + if(size < 4 || st->bufend - st->bufbeg < 3) + break; + + /* Encode three bytes as four characters. */ + i = st->buf[st->bufbeg++] & 0xFF; + i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF); + i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF); + *ptr++ = base64[(i >> 18) & 0x3F]; + *ptr++ = base64[(i >> 12) & 0x3F]; + *ptr++ = base64[(i >> 6) & 0x3F]; + *ptr++ = base64[i & 0x3F]; + cursize += 4; + st->pos += 4; + size -= 4; + } + + /* If at eof, we have to flush the buffered data. */ + if(ateof && size >= 4) { + /* Buffered data size can only be 0, 1 or 2. */ + ptr[2] = ptr[3] = '='; + i = 0; + switch(st->bufend - st->bufbeg) { + case 2: + i = (st->buf[st->bufbeg + 1] & 0xFF) << 8; + /* FALLTHROUGH */ + case 1: + i |= (st->buf[st->bufbeg] & 0xFF) << 16; + ptr[0] = base64[(i >> 18) & 0x3F]; + ptr[1] = base64[(i >> 12) & 0x3F]; + if(++st->bufbeg != st->bufend) { + ptr[2] = base64[(i >> 6) & 0x3F]; + st->bufbeg++; + } + cursize += 4; + st->pos += 4; + break; + } + } + +#ifdef CURL_DOES_CONVERSIONS + /* This is now textual data, Convert character codes. */ + if(part->easy && cursize) { + CURLcode result = Curl_convert_to_network(part->easy, buffer, cursize); + if(result) + return READ_ERROR; + } +#endif + + return cursize; +} + +static curl_off_t encoder_base64_size(curl_mimepart *part) +{ + curl_off_t size = part->datasize; + + if(size <= 0) + return size; /* Unknown size or no data. */ + + /* Compute base64 character count. */ + size = 4 * (1 + (size - 1) / 3); + + /* Effective character count must include CRLFs. */ + return size + 2 * ((size - 1) / MAX_ENCODED_LINE_LENGTH); +} + + +/* Quoted-printable lookahead. + * + * Check if a CRLF or end of data is in input buffer at current position + n. + * Return -1 if more data needed, 1 if CRLF or end of data, else 0. + */ +static int qp_lookahead_eol(mime_encoder_state *st, int ateof, size_t n) +{ + n += st->bufbeg; + if(n >= st->bufend && ateof) + return 1; + if(n + 2 > st->bufend) + return ateof? 0: -1; + if(qp_class[st->buf[n] & 0xFF] == QP_CR && + qp_class[st->buf[n + 1] & 0xFF] == QP_LF) + return 1; + return 0; +} + +/* Quoted-printable encoder. */ +static size_t encoder_qp_read(char *buffer, size_t size, bool ateof, + curl_mimepart *part) +{ + mime_encoder_state *st = &part->encstate; + char *ptr = buffer; + size_t cursize = 0; + int softlinebreak; + char buf[4]; + + /* On all platforms, input is supposed to be ASCII compatible: for this + reason, we use hexadecimal ASCII codes in this function rather than + character constants that can be interpreted as non-ascii on some + platforms. Preserve ASCII encoding on output too. */ + while(st->bufbeg < st->bufend) { + size_t len = 1; + size_t consumed = 1; + int i = st->buf[st->bufbeg]; + buf[0] = (char) i; + buf[1] = aschex[(i >> 4) & 0xF]; + buf[2] = aschex[i & 0xF]; + + switch(qp_class[st->buf[st->bufbeg] & 0xFF]) { + case QP_OK: /* Not a special character. */ + break; + case QP_SP: /* Space or tab. */ + /* Spacing must be escaped if followed by CRLF. */ + switch(qp_lookahead_eol(st, ateof, 1)) { + case -1: /* More input data needed. */ + return cursize; + case 0: /* No encoding needed. */ + break; + default: /* CRLF after space or tab. */ + buf[0] = '\x3D'; /* '=' */ + len = 3; + break; + } + break; + case QP_CR: /* Carriage return. */ + /* If followed by a line-feed, output the CRLF pair. + Else escape it. */ + switch(qp_lookahead_eol(st, ateof, 0)) { + case -1: /* Need more data. */ + return cursize; + case 1: /* CRLF found. */ + buf[len++] = '\x0A'; /* Append '\n'. */ + consumed = 2; + break; + default: /* Not followed by LF: escape. */ + buf[0] = '\x3D'; /* '=' */ + len = 3; + break; + } + break; + default: /* Character must be escaped. */ + buf[0] = '\x3D'; /* '=' */ + len = 3; + break; + } + + /* Be sure the encoded character fits within maximum line length. */ + if(buf[len - 1] != '\x0A') { /* '\n' */ + softlinebreak = st->pos + len > MAX_ENCODED_LINE_LENGTH; + if(!softlinebreak && st->pos + len == MAX_ENCODED_LINE_LENGTH) { + /* We may use the current line only if end of data or followed by + a CRLF. */ + switch(qp_lookahead_eol(st, ateof, consumed)) { + case -1: /* Need more data. */ + return cursize; + break; + case 0: /* Not followed by a CRLF. */ + softlinebreak = 1; + break; + } + } + if(softlinebreak) { + strcpy(buf, "\x3D\x0D\x0A"); /* "=\r\n" */ + len = 3; + consumed = 0; + } + } + + /* If the output buffer would overflow, do not store. */ + if(len > size) + break; + + /* Append to output buffer. */ + memcpy(ptr, buf, len); + cursize += len; + ptr += len; + size -= len; + st->pos += len; + if(buf[len - 1] == '\x0A') /* '\n' */ + st->pos = 0; + st->bufbeg += consumed; + } + + return cursize; +} + +static curl_off_t encoder_qp_size(curl_mimepart *part) +{ + /* Determining the size can only be done by reading the data: unless the + data size is 0, we return it as unknown (-1). */ + return part->datasize? -1: 0; +} + + +/* In-memory data callbacks. */ +/* Argument is a pointer to the mime part. */ +static size_t mime_mem_read(char *buffer, size_t size, size_t nitems, + void *instream) +{ + curl_mimepart *part = (curl_mimepart *) instream; + size_t sz = (size_t) part->datasize - part->state.offset; + (void) size; /* Always 1.*/ + + if(sz > nitems) + sz = nitems; + + if(sz) + memcpy(buffer, (char *) &part->data[part->state.offset], sz); + + part->state.offset += sz; + return sz; +} + +static int mime_mem_seek(void *instream, curl_off_t offset, int whence) +{ + curl_mimepart *part = (curl_mimepart *) instream; + + switch(whence) { + case SEEK_CUR: + offset += part->state.offset; + break; + case SEEK_END: + offset += part->datasize; + break; + } + + if(offset < 0 || offset > part->datasize) + return CURL_SEEKFUNC_FAIL; + + part->state.offset = (size_t) offset; + return CURL_SEEKFUNC_OK; +} + +static void mime_mem_free(void *ptr) +{ + Curl_safefree(((curl_mimepart *) ptr)->data); +} + + +/* Named file callbacks. */ +/* Argument is a pointer to the mime part. */ +static int mime_open_file(curl_mimepart * part) +{ + /* Open a MIMEKIND_FILE part. */ + + if(part->fp) + return 0; + part->fp = fopen_read(part->data, "rb"); + return part->fp? 0: -1; +} + +static size_t mime_file_read(char *buffer, size_t size, size_t nitems, + void *instream) +{ + curl_mimepart *part = (curl_mimepart *) instream; + + if(mime_open_file(part)) + return READ_ERROR; + + return fread(buffer, size, nitems, part->fp); +} + +static int mime_file_seek(void *instream, curl_off_t offset, int whence) +{ + curl_mimepart *part = (curl_mimepart *) instream; + + if(whence == SEEK_SET && !offset && !part->fp) + return CURL_SEEKFUNC_OK; /* Not open: implicitly already at BOF. */ + + if(mime_open_file(part)) + return CURL_SEEKFUNC_FAIL; + + return fseek(part->fp, (long) offset, whence)? + CURL_SEEKFUNC_CANTSEEK: CURL_SEEKFUNC_OK; +} + +static void mime_file_free(void *ptr) +{ + curl_mimepart *part = (curl_mimepart *) ptr; + + if(part->fp) { + fclose(part->fp); + part->fp = NULL; + } + Curl_safefree(part->data); + part->data = NULL; +} + + +/* Subparts callbacks. */ +/* Argument is a pointer to the mime structure. */ + +/* Readback a byte string segment. */ +static size_t readback_bytes(mime_state *state, + char *buffer, size_t bufsize, + const char *bytes, size_t numbytes, + const char *trail) +{ + size_t sz; + + if(numbytes > state->offset) { + sz = numbytes - state->offset; + bytes += state->offset; + } + else { + size_t tsz = strlen(trail); + + sz = state->offset - numbytes; + if(sz >= tsz) + return 0; + bytes = trail + sz; + sz = tsz - sz; + } + + if(sz > bufsize) + sz = bufsize; + + memcpy(buffer, bytes, sz); + state->offset += sz; + return sz; +} + +/* Read a non-encoded part content. */ +static size_t read_part_content(curl_mimepart *part, + char *buffer, size_t bufsize) +{ + size_t sz = 0; + + if(part->readfunc) + sz = part->readfunc(buffer, 1, bufsize, part->arg); + return sz; +} + +/* Read and encode part content. */ +static size_t read_encoded_part_content(curl_mimepart *part, + char *buffer, size_t bufsize) +{ + mime_encoder_state *st = &part->encstate; + size_t cursize = 0; + size_t sz; + bool ateof = FALSE; + + while(bufsize) { + if(st->bufbeg < st->bufend || ateof) { + /* Encode buffered data. */ + sz = part->encoder->encodefunc(buffer, bufsize, ateof, part); + switch(sz) { + case 0: + if(ateof) + return cursize; + break; + case CURL_READFUNC_ABORT: + case CURL_READFUNC_PAUSE: + case READ_ERROR: + return cursize? cursize: sz; + default: + cursize += sz; + buffer += sz; + bufsize -= sz; + continue; + } + } + + /* We need more data in input buffer. */ + if(st->bufbeg) { + size_t len = st->bufend - st->bufbeg; + + if(len) + memmove(st->buf, st->buf + st->bufbeg, len); + st->bufbeg = 0; + st->bufend = len; + } + if(st->bufend >= sizeof(st->buf)) + return cursize? cursize: READ_ERROR; /* Buffer full. */ + sz = read_part_content(part, st->buf + st->bufend, + sizeof(st->buf) - st->bufend); + switch(sz) { + case 0: + ateof = TRUE; + break; + case CURL_READFUNC_ABORT: + case CURL_READFUNC_PAUSE: + case READ_ERROR: + return cursize? cursize: sz; + default: + st->bufend += sz; + break; + } + } + + return cursize; +} + +/* Readback a mime part. */ +static size_t readback_part(curl_mimepart *part, + char *buffer, size_t bufsize) +{ + size_t cursize = 0; +#ifdef CURL_DOES_CONVERSIONS + char *convbuf = buffer; +#endif + + /* Readback from part. */ + + while(bufsize) { + size_t sz = 0; + struct curl_slist *hdr = (struct curl_slist *) part->state.ptr; + switch(part->state.state) { + case MIMESTATE_BEGIN: + mimesetstate(&part->state, + (part->flags & MIME_BODY_ONLY)? + MIMESTATE_BODY: MIMESTATE_CURLHEADERS, + part->curlheaders); + break; + case MIMESTATE_USERHEADERS: + if(!hdr) { + mimesetstate(&part->state, MIMESTATE_EOH, NULL); + break; + } + if(match_header(hdr, "Content-Type", 12)) { + mimesetstate(&part->state, MIMESTATE_USERHEADERS, hdr->next); + break; + } + /* FALLTHROUGH */ + case MIMESTATE_CURLHEADERS: + if(!hdr) + mimesetstate(&part->state, MIMESTATE_USERHEADERS, part->userheaders); + else { + sz = readback_bytes(&part->state, buffer, bufsize, + hdr->data, strlen(hdr->data), "\r\n"); + if(!sz) + mimesetstate(&part->state, part->state.state, hdr->next); + } + break; + case MIMESTATE_EOH: + sz = readback_bytes(&part->state, buffer, bufsize, "\r\n", 2, ""); + if(!sz) + mimesetstate(&part->state, MIMESTATE_BODY, NULL); + break; + case MIMESTATE_BODY: +#ifdef CURL_DOES_CONVERSIONS + if(part->easy && convbuf < buffer) { + CURLcode result = Curl_convert_to_network(part->easy, convbuf, + buffer - convbuf); + if(result) + return READ_ERROR; + convbuf = buffer; + } +#endif + cleanup_encoder_state(&part->encstate); + mimesetstate(&part->state, MIMESTATE_CONTENT, NULL); + break; + case MIMESTATE_CONTENT: + if(part->encoder) + sz = read_encoded_part_content(part, buffer, bufsize); + else + sz = read_part_content(part, buffer, bufsize); + switch(sz) { + case 0: + mimesetstate(&part->state, MIMESTATE_END, NULL); + /* Try sparing open file descriptors. */ + if(part->kind == MIMEKIND_FILE && part->fp) { + fclose(part->fp); + part->fp = NULL; + } + /* FALLTHROUGH */ + case CURL_READFUNC_ABORT: + case CURL_READFUNC_PAUSE: + case READ_ERROR: + return cursize? cursize: sz; + } + break; + case MIMESTATE_END: + return cursize; + default: + break; /* Other values not in part state. */ + } + + /* Bump buffer and counters according to read size. */ + cursize += sz; + buffer += sz; + bufsize -= sz; + } + +#ifdef CURL_DOES_CONVERSIONS + if(part->easy && convbuf < buffer && + part->state.state < MIMESTATE_BODY) { + CURLcode result = Curl_convert_to_network(part->easy, convbuf, + buffer - convbuf); + if(result) + return READ_ERROR; + } +#endif + + return cursize; +} + +/* Readback from mime. */ +static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems, + void *instream) +{ + curl_mime *mime = (curl_mime *) instream; + size_t cursize = 0; +#ifdef CURL_DOES_CONVERSIONS + char *convbuf = buffer; +#endif + + (void) size; /* Always 1. */ + + while(nitems) { + size_t sz = 0; + curl_mimepart *part = mime->state.ptr; + switch(mime->state.state) { + case MIMESTATE_BEGIN: + case MIMESTATE_BODY: +#ifdef CURL_DOES_CONVERSIONS + convbuf = buffer; +#endif + mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, mime->firstpart); + /* The first boundary always follows the header termination empty line, + so is always preceded by a CRLK. We can then spare 2 characters + by skipping the leading CRLF in boundary. */ + mime->state.offset += 2; + break; + case MIMESTATE_BOUNDARY1: + sz = readback_bytes(&mime->state, buffer, nitems, "\r\n--", 4, ""); + if(!sz) + mimesetstate(&mime->state, MIMESTATE_BOUNDARY2, part); + break; + case MIMESTATE_BOUNDARY2: + sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary, + strlen(mime->boundary), part? "\r\n": "--\r\n"); + if(!sz) { +#ifdef CURL_DOES_CONVERSIONS + if(mime->easy && convbuf < buffer) { + CURLcode result = Curl_convert_to_network(mime->easy, convbuf, + buffer - convbuf); + if(result) + return READ_ERROR; + convbuf = buffer; + } +#endif + mimesetstate(&mime->state, MIMESTATE_CONTENT, part); + } + break; + case MIMESTATE_CONTENT: + if(!part) { + mimesetstate(&mime->state, MIMESTATE_END, NULL); + break; + } + sz = readback_part(part, buffer, nitems); + switch(sz) { + case CURL_READFUNC_ABORT: + case CURL_READFUNC_PAUSE: + case READ_ERROR: + return cursize? cursize: sz; + case 0: +#ifdef CURL_DOES_CONVERSIONS + convbuf = buffer; +#endif + mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, part->nextpart); + break; + } + break; + case MIMESTATE_END: + return cursize; + default: + break; /* other values not used in mime state. */ + } + + /* Bump buffer and counters according to read size. */ + cursize += sz; + buffer += sz; + nitems -= sz; + } + +#ifdef CURL_DOES_CONVERSIONS + if(mime->easy && convbuf < buffer && + mime->state.state <= MIMESTATE_CONTENT) { + CURLcode result = Curl_convert_to_network(mime->easy, convbuf, + buffer - convbuf); + if(result) + return READ_ERROR; + } +#endif + + return cursize; +} + +static int mime_part_rewind(curl_mimepart *part) +{ + int res = CURL_SEEKFUNC_OK; + enum mimestate targetstate = MIMESTATE_BEGIN; + + if(part->flags & MIME_BODY_ONLY) + targetstate = MIMESTATE_BODY; + cleanup_encoder_state(&part->encstate); + if(part->state.state > targetstate) { + res = CURL_SEEKFUNC_CANTSEEK; + if(part->seekfunc) { + res = part->seekfunc(part->arg, (curl_off_t) 0, SEEK_SET); + switch(res) { + case CURL_SEEKFUNC_OK: + case CURL_SEEKFUNC_FAIL: + case CURL_SEEKFUNC_CANTSEEK: + break; + case -1: /* For fseek() error. */ + res = CURL_SEEKFUNC_CANTSEEK; + break; + default: + res = CURL_SEEKFUNC_FAIL; + break; + } + } + } + + if(res == CURL_SEEKFUNC_OK) + mimesetstate(&part->state, targetstate, NULL); + + return res; +} + +static int mime_subparts_seek(void *instream, curl_off_t offset, int whence) +{ + curl_mime *mime = (curl_mime *) instream; + curl_mimepart *part; + int result = CURL_SEEKFUNC_OK; + + if(whence != SEEK_SET || offset) + return CURL_SEEKFUNC_CANTSEEK; /* Only support full rewind. */ + + if(mime->state.state == MIMESTATE_BEGIN) + return CURL_SEEKFUNC_OK; /* Already rewound. */ + + for(part = mime->firstpart; part; part = part->nextpart) { + int res = mime_part_rewind(part); + if(res != CURL_SEEKFUNC_OK) + result = res; + } + + if(result == CURL_SEEKFUNC_OK) + mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL); + + return result; +} + +/* Release part content. */ +static void cleanup_part_content(curl_mimepart *part) +{ + if(part->freefunc) + part->freefunc(part->arg); + + part->readfunc = NULL; + part->seekfunc = NULL; + part->freefunc = NULL; + part->arg = (void *) part; /* Defaults to part itself. */ + part->data = NULL; + part->fp = NULL; + part->datasize = (curl_off_t) 0; /* No size yet. */ + cleanup_encoder_state(&part->encstate); + part->kind = MIMEKIND_NONE; +} + +static void mime_subparts_free(void *ptr) +{ + curl_mime *mime = (curl_mime *) ptr; + + if(mime && mime->parent) { + mime->parent->freefunc = NULL; /* Be sure we won't be called again. */ + cleanup_part_content(mime->parent); /* Avoid dangling pointer in part. */ + } + curl_mime_free(mime); +} + +/* Do not free subparts: unbind them. This is used for the top level only. */ +static void mime_subparts_unbind(void *ptr) +{ + curl_mime *mime = (curl_mime *) ptr; + + if(mime && mime->parent) { + mime->parent->freefunc = NULL; /* Be sure we won't be called again. */ + cleanup_part_content(mime->parent); /* Avoid dangling pointer in part. */ + mime->parent = NULL; + } +} + + +void Curl_mime_cleanpart(curl_mimepart *part) +{ + cleanup_part_content(part); + curl_slist_free_all(part->curlheaders); + if(part->flags & MIME_USERHEADERS_OWNER) + curl_slist_free_all(part->userheaders); + Curl_safefree(part->mimetype); + Curl_safefree(part->name); + Curl_safefree(part->filename); + Curl_mime_initpart(part, part->easy); +} + +/* Recursively delete a mime handle and its parts. */ +void curl_mime_free(curl_mime *mime) +{ + curl_mimepart *part; + + if(mime) { + mime_subparts_unbind(mime); /* Be sure it's not referenced anymore. */ + while(mime->firstpart) { + part = mime->firstpart; + mime->firstpart = part->nextpart; + Curl_mime_cleanpart(part); + free(part); + } + free(mime); + } +} + +CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src) +{ + curl_mime *mime; + curl_mimepart *d; + const curl_mimepart *s; + CURLcode res = CURLE_OK; + + /* Duplicate content. */ + switch(src->kind) { + case MIMEKIND_NONE: + break; + case MIMEKIND_DATA: + res = curl_mime_data(dst, src->data, (size_t) src->datasize); + break; + case MIMEKIND_FILE: + res = curl_mime_filedata(dst, src->data); + /* Do not abort duplication if file is not readable. */ + if(res == CURLE_READ_ERROR) + res = CURLE_OK; + break; + case MIMEKIND_CALLBACK: + res = curl_mime_data_cb(dst, src->datasize, src->readfunc, + src->seekfunc, src->freefunc, src->arg); + break; + case MIMEKIND_MULTIPART: + /* No one knows about the cloned subparts, thus always attach ownership + to the part. */ + mime = curl_mime_init(dst->easy); + res = mime? curl_mime_subparts(dst, mime): CURLE_OUT_OF_MEMORY; + + /* Duplicate subparts. */ + for(s = ((curl_mime *) src->arg)->firstpart; !res && s; s = s->nextpart) { + d = curl_mime_addpart(mime); + res = d? Curl_mime_duppart(d, s): CURLE_OUT_OF_MEMORY; + } + break; + default: /* Invalid kind: should not occur. */ + res = CURLE_BAD_FUNCTION_ARGUMENT; /* Internal error? */ + break; + } + + /* Duplicate headers. */ + if(!res && src->userheaders) { + struct curl_slist *hdrs = Curl_slist_duplicate(src->userheaders); + + if(!hdrs) + res = CURLE_OUT_OF_MEMORY; + else { + /* No one but this procedure knows about the new header list, + so always take ownership. */ + res = curl_mime_headers(dst, hdrs, TRUE); + if(res) + curl_slist_free_all(hdrs); + } + } + + /* Duplicate other fields. */ + if(dst != NULL) + dst->encoder = src->encoder; + else + res = CURLE_WRITE_ERROR; + if(!res) + res = curl_mime_type(dst, src->mimetype); + if(!res) + res = curl_mime_name(dst, src->name); + if(!res) + res = curl_mime_filename(dst, src->filename); + + /* If an error occurred, rollback. */ + if(res && dst) + Curl_mime_cleanpart(dst); + + return res; +} + +/* + * Mime build functions. + */ + +/* Create a mime handle. */ +curl_mime *curl_mime_init(struct Curl_easy *easy) +{ + curl_mime *mime; + + mime = (curl_mime *) malloc(sizeof(*mime)); + + if(mime) { + mime->easy = easy; + mime->parent = NULL; + mime->firstpart = NULL; + mime->lastpart = NULL; + + memset(mime->boundary, '-', 24); + if(Curl_rand_hex(easy, (unsigned char *) &mime->boundary[24], + MIME_RAND_BOUNDARY_CHARS + 1)) { + /* failed to get random separator, bail out */ + free(mime); + return NULL; + } + mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL); + } + + return mime; +} + +/* Initialize a mime part. */ +void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy) +{ + memset((char *) part, 0, sizeof(*part)); + part->easy = easy; + mimesetstate(&part->state, MIMESTATE_BEGIN, NULL); +} + +/* Create a mime part and append it to a mime handle's part list. */ +curl_mimepart *curl_mime_addpart(curl_mime *mime) +{ + curl_mimepart *part; + + if(!mime) + return NULL; + + part = (curl_mimepart *) malloc(sizeof(*part)); + + if(part) { + Curl_mime_initpart(part, mime->easy); + part->parent = mime; + + if(mime->lastpart) + mime->lastpart->nextpart = part; + else + mime->firstpart = part; + + mime->lastpart = part; + } + + return part; +} + +/* Set mime part name. */ +CURLcode curl_mime_name(curl_mimepart *part, const char *name) +{ + if(!part) + return CURLE_BAD_FUNCTION_ARGUMENT; + + Curl_safefree(part->name); + part->name = NULL; + + if(name) { + part->name = strdup(name); + if(!part->name) + return CURLE_OUT_OF_MEMORY; + } + + return CURLE_OK; +} + +/* Set mime part remote file name. */ +CURLcode curl_mime_filename(curl_mimepart *part, const char *filename) +{ + if(!part) + return CURLE_BAD_FUNCTION_ARGUMENT; + + Curl_safefree(part->filename); + part->filename = NULL; + + if(filename) { + part->filename = strdup(filename); + if(!part->filename) + return CURLE_OUT_OF_MEMORY; + } + + return CURLE_OK; +} + +/* Set mime part content from memory data. */ +CURLcode curl_mime_data(curl_mimepart *part, + const char *data, size_t datasize) +{ + if(!part) + return CURLE_BAD_FUNCTION_ARGUMENT; + + cleanup_part_content(part); + + if(data) { + if(datasize == CURL_ZERO_TERMINATED) + datasize = strlen(data); + + part->data = malloc(datasize + 1); + if(!part->data) + return CURLE_OUT_OF_MEMORY; + + part->datasize = datasize; + + if(datasize) + memcpy(part->data, data, datasize); + part->data[datasize] = '\0'; /* Set a nul terminator as sentinel. */ + + part->readfunc = mime_mem_read; + part->seekfunc = mime_mem_seek; + part->freefunc = mime_mem_free; + part->kind = MIMEKIND_DATA; + } + + return CURLE_OK; +} + +/* Set mime part content from named local file. */ +CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename) +{ + CURLcode result = CURLE_OK; + + if(!part) + return CURLE_BAD_FUNCTION_ARGUMENT; + + cleanup_part_content(part); + + if(filename) { + char *base; + struct_stat sbuf; + + if(stat(filename, &sbuf) || access(filename, R_OK)) + result = CURLE_READ_ERROR; + + part->data = strdup(filename); + if(!part->data) + result = CURLE_OUT_OF_MEMORY; + + part->datasize = -1; + if(!result && S_ISREG(sbuf.st_mode)) { + part->datasize = filesize(filename, sbuf); + part->seekfunc = mime_file_seek; + } + + part->readfunc = mime_file_read; + part->freefunc = mime_file_free; + part->kind = MIMEKIND_FILE; + + /* As a side effect, set the filename to the current file's base name. + It is possible to withdraw this by explicitly calling + curl_mime_filename() with a NULL filename argument after the current + call. */ + base = strippath(filename); + if(!base) + result = CURLE_OUT_OF_MEMORY; + else { + CURLcode res = curl_mime_filename(part, base); + + if(res) + result = res; + free(base); + } + } + return result; +} + +/* Set mime part type. */ +CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype) +{ + if(!part) + return CURLE_BAD_FUNCTION_ARGUMENT; + + Curl_safefree(part->mimetype); + part->mimetype = NULL; + + if(mimetype) { + part->mimetype = strdup(mimetype); + if(!part->mimetype) + return CURLE_OUT_OF_MEMORY; + } + + return CURLE_OK; +} + +/* Set mime data transfer encoder. */ +CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding) +{ + CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT; + const mime_encoder *mep; + + if(!part) + return result; + + part->encoder = NULL; + + if(!encoding) + return CURLE_OK; /* Removing current encoder. */ + + for(mep = encoders; mep->name; mep++) + if(strcasecompare(encoding, mep->name)) { + part->encoder = mep; + result = CURLE_OK; + } + + return result; +} + +/* Set mime part headers. */ +CURLcode curl_mime_headers(curl_mimepart *part, + struct curl_slist *headers, int take_ownership) +{ + if(!part) + return CURLE_BAD_FUNCTION_ARGUMENT; + + if(part->flags & MIME_USERHEADERS_OWNER) { + if(part->userheaders != headers) /* Allow setting twice the same list. */ + curl_slist_free_all(part->userheaders); + part->flags &= ~MIME_USERHEADERS_OWNER; + } + part->userheaders = headers; + if(headers && take_ownership) + part->flags |= MIME_USERHEADERS_OWNER; + return CURLE_OK; +} + +/* Set mime part content from callback. */ +CURLcode curl_mime_data_cb(curl_mimepart *part, curl_off_t datasize, + curl_read_callback readfunc, + curl_seek_callback seekfunc, + curl_free_callback freefunc, void *arg) +{ + if(!part) + return CURLE_BAD_FUNCTION_ARGUMENT; + + cleanup_part_content(part); + + if(readfunc) { + part->readfunc = readfunc; + part->seekfunc = seekfunc; + part->freefunc = freefunc; + part->arg = arg; + part->datasize = datasize; + part->kind = MIMEKIND_CALLBACK; + } + + return CURLE_OK; +} + +/* Set mime part content from subparts. */ +CURLcode Curl_mime_set_subparts(curl_mimepart *part, + curl_mime *subparts, int take_ownership) +{ + curl_mime *root; + + if(!part) + return CURLE_BAD_FUNCTION_ARGUMENT; + + /* Accept setting twice the same subparts. */ + if(part->kind == MIMEKIND_MULTIPART && part->arg == subparts) + return CURLE_OK; + + cleanup_part_content(part); + + if(subparts) { + /* Must belong to the same data handle. */ + if(part->easy && subparts->easy && part->easy != subparts->easy) + return CURLE_BAD_FUNCTION_ARGUMENT; + + /* Should not have been attached already. */ + if(subparts->parent) + return CURLE_BAD_FUNCTION_ARGUMENT; + + /* Should not be the part's root. */ + root = part->parent; + if(root) { + while(root->parent && root->parent->parent) + root = root->parent->parent; + if(subparts == root) { + if(part->easy) + failf(part->easy, "Can't add itself as a subpart!"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + } + + subparts->parent = part; + part->readfunc = mime_subparts_read; + part->seekfunc = mime_subparts_seek; + part->freefunc = take_ownership? mime_subparts_free: mime_subparts_unbind; + part->arg = subparts; + part->datasize = -1; + part->kind = MIMEKIND_MULTIPART; + } + + return CURLE_OK; +} + +CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts) +{ + return Curl_mime_set_subparts(part, subparts, TRUE); +} + + +/* Readback from top mime. */ +/* Argument is the dummy top part. */ +size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream) +{ + curl_mimepart *part = (curl_mimepart *) instream; + + (void) size; /* Always 1. */ + return readback_part(part, buffer, nitems); +} + +/* Rewind mime stream. */ +CURLcode Curl_mime_rewind(curl_mimepart *part) +{ + return mime_part_rewind(part) == CURL_SEEKFUNC_OK? + CURLE_OK: CURLE_SEND_FAIL_REWIND; +} + +/* Compute header list size. */ +static size_t slist_size(struct curl_slist *s, + size_t overhead, const char *skip) +{ + size_t size = 0; + size_t skiplen = skip? strlen(skip): 0; + + for(; s; s = s->next) + if(!skip || !match_header(s, skip, skiplen)) + size += strlen(s->data) + overhead; + return size; +} + +/* Get/compute multipart size. */ +static curl_off_t multipart_size(curl_mime *mime) +{ + curl_off_t size; + size_t boundarysize; + curl_mimepart *part; + + if(!mime) + return 0; /* Not present -> empty. */ + + boundarysize = 4 + strlen(mime->boundary) + 2; + size = boundarysize; /* Final boundary - CRLF after headers. */ + + for(part = mime->firstpart; part; part = part->nextpart) { + curl_off_t sz = Curl_mime_size(part); + + if(sz < 0) + size = sz; + + if(size >= 0) + size += boundarysize + sz; + } + + return size; +} + +/* Get/compute mime size. */ +curl_off_t Curl_mime_size(curl_mimepart *part) +{ + curl_off_t size; + + if(part->kind == MIMEKIND_MULTIPART) + part->datasize = multipart_size(part->arg); + + size = part->datasize; + + if(part->encoder) + size = part->encoder->sizefunc(part); + + if(size >= 0 && !(part->flags & MIME_BODY_ONLY)) { + /* Compute total part size. */ + size += slist_size(part->curlheaders, 2, NULL); + size += slist_size(part->userheaders, 2, "Content-Type"); + size += 2; /* CRLF after headers. */ + } + return size; +} + +/* Add a header. */ +/* VARARGS2 */ +CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...) +{ + struct curl_slist *hdr = NULL; + char *s = NULL; + va_list ap; + + va_start(ap, fmt); + s = curl_mvaprintf(fmt, ap); + va_end(ap); + + if(s) { + hdr = Curl_slist_append_nodup(*slp, s); + if(hdr) + *slp = hdr; + else + free(s); + } + + return hdr? CURLE_OK: CURLE_OUT_OF_MEMORY; +} + +/* Add a content type header. */ +static CURLcode add_content_type(struct curl_slist **slp, + const char *type, const char *boundary) +{ + return Curl_mime_add_header(slp, "Content-Type: %s%s%s", type, + boundary? "; boundary=": "", + boundary? boundary: ""); +} + +const char *Curl_mime_contenttype(const char *filename) +{ + /* + * If no content type was specified, we scan through a few well-known + * extensions and pick the first we match! + */ + struct ContentType { + const char *extension; + const char *type; + }; + static const struct ContentType ctts[] = { + {".gif", "image/gif"}, + {".jpg", "image/jpeg"}, + {".jpeg", "image/jpeg"}, + {".png", "image/png"}, + {".svg", "image/svg+xml"}, + {".txt", "text/plain"}, + {".htm", "text/html"}, + {".html", "text/html"}, + {".pdf", "application/pdf"}, + {".xml", "application/xml"} + }; + + if(filename) { + size_t len1 = strlen(filename); + const char *nameend = filename + len1; + unsigned int i; + + for(i = 0; i < sizeof(ctts) / sizeof(ctts[0]); i++) { + size_t len2 = strlen(ctts[i].extension); + + if(len1 >= len2 && strcasecompare(nameend - len2, ctts[i].extension)) + return ctts[i].type; + } + } + return NULL; +} + +CURLcode Curl_mime_prepare_headers(curl_mimepart *part, + const char *contenttype, + const char *disposition, + enum mimestrategy strategy) +{ + curl_mime *mime = NULL; + const char *boundary = NULL; + char *customct; + const char *cte = NULL; + CURLcode ret = CURLE_OK; + + /* Get rid of previously prepared headers. */ + curl_slist_free_all(part->curlheaders); + part->curlheaders = NULL; + + /* Be sure we won't access old headers later. */ + if(part->state.state == MIMESTATE_CURLHEADERS) + mimesetstate(&part->state, MIMESTATE_CURLHEADERS, NULL); + + /* Check if content type is specified. */ + customct = part->mimetype; + if(!customct) + customct = search_header(part->userheaders, "Content-Type"); + if(customct) + contenttype = customct; + + /* If content type is not specified, try to determine it. */ + if(!contenttype) { + switch(part->kind) { + case MIMEKIND_MULTIPART: + contenttype = MULTIPART_CONTENTTYPE_DEFAULT; + break; + case MIMEKIND_FILE: + contenttype = Curl_mime_contenttype(part->filename); + if(!contenttype) + contenttype = Curl_mime_contenttype(part->data); + if(!contenttype && part->filename) + contenttype = FILE_CONTENTTYPE_DEFAULT; + break; + default: + contenttype = Curl_mime_contenttype(part->filename); + break; + } + } + + if(part->kind == MIMEKIND_MULTIPART) { + mime = (curl_mime *) part->arg; + if(mime) + boundary = mime->boundary; + } + else if(contenttype && !customct && + strcasecompare(contenttype, "text/plain")) + if(strategy == MIMESTRATEGY_MAIL || !part->filename) + contenttype = NULL; + + /* Issue content-disposition header only if not already set by caller. */ + if(!search_header(part->userheaders, "Content-Disposition")) { + if(!disposition) + if(part->filename || part->name || + (contenttype && !strncasecompare(contenttype, "multipart/", 10))) + disposition = DISPOSITION_DEFAULT; + if(disposition && curl_strequal(disposition, "attachment") && + !part->name && !part->filename) + disposition = NULL; + if(disposition) { + char *name = NULL; + char *filename = NULL; + + if(part->name) { + name = escape_string(part->name); + if(!name) + ret = CURLE_OUT_OF_MEMORY; + } + if(!ret && part->filename) { + filename = escape_string(part->filename); + if(!filename) + ret = CURLE_OUT_OF_MEMORY; + } + if(!ret) + ret = Curl_mime_add_header(&part->curlheaders, + "Content-Disposition: %s%s%s%s%s%s%s", + disposition, + name? "; name=\"": "", + name? name: "", + name? "\"": "", + filename? "; filename=\"": "", + filename? filename: "", + filename? "\"": ""); + Curl_safefree(name); + Curl_safefree(filename); + if(ret) + return ret; + } + } + + /* Issue Content-Type header. */ + if(contenttype) { + ret = add_content_type(&part->curlheaders, contenttype, boundary); + if(ret) + return ret; + } + + /* Content-Transfer-Encoding header. */ + if(!search_header(part->userheaders, "Content-Transfer-Encoding")) { + if(part->encoder) + cte = part->encoder->name; + else if(contenttype && strategy == MIMESTRATEGY_MAIL && + part->kind != MIMEKIND_MULTIPART) + cte = "8bit"; + if(cte) { + ret = Curl_mime_add_header(&part->curlheaders, + "Content-Transfer-Encoding: %s", cte); + if(ret) + return ret; + } + } + + /* If we were reading curl-generated headers, restart with new ones (this + should not occur). */ + if(part->state.state == MIMESTATE_CURLHEADERS) + mimesetstate(&part->state, MIMESTATE_CURLHEADERS, part->curlheaders); + + /* Process subparts. */ + if(part->kind == MIMEKIND_MULTIPART && mime) { + curl_mimepart *subpart; + + disposition = NULL; + if(strcasecompare(contenttype, "multipart/form-data")) + disposition = "form-data"; + for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) { + ret = Curl_mime_prepare_headers(subpart, NULL, disposition, strategy); + if(ret) + return ret; + } + } + return ret; +} + +#else /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */ + +/* Mime not compiled in: define stubs for externally-referenced functions. */ +curl_mime *curl_mime_init(CURL *easy) +{ + (void) easy; + return NULL; +} + +void curl_mime_free(curl_mime *mime) +{ + (void) mime; +} + +curl_mimepart *curl_mime_addpart(curl_mime *mime) +{ + (void) mime; + return NULL; +} + +CURLcode curl_mime_name(curl_mimepart *part, const char *name) +{ + (void) part; + (void) name; + return CURLE_NOT_BUILT_IN; +} + +CURLcode curl_mime_filename(curl_mimepart *part, const char *filename) +{ + (void) part; + (void) filename; + return CURLE_NOT_BUILT_IN; +} + +CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype) +{ + (void) part; + (void) mimetype; + return CURLE_NOT_BUILT_IN; +} + +CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding) +{ + (void) part; + (void) encoding; + return CURLE_NOT_BUILT_IN; +} + +CURLcode curl_mime_data(curl_mimepart *part, + const char *data, size_t datasize) +{ + (void) part; + (void) data; + (void) datasize; + return CURLE_NOT_BUILT_IN; +} + +CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename) +{ + (void) part; + (void) filename; + return CURLE_NOT_BUILT_IN; +} + +CURLcode curl_mime_data_cb(curl_mimepart *part, + curl_off_t datasize, + curl_read_callback readfunc, + curl_seek_callback seekfunc, + curl_free_callback freefunc, + void *arg) +{ + (void) part; + (void) datasize; + (void) readfunc; + (void) seekfunc; + (void) freefunc; + (void) arg; + return CURLE_NOT_BUILT_IN; +} + +CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts) +{ + (void) part; + (void) subparts; + return CURLE_NOT_BUILT_IN; +} + +CURLcode curl_mime_headers(curl_mimepart *part, + struct curl_slist *headers, int take_ownership) +{ + (void) part; + (void) headers; + (void) take_ownership; + return CURLE_NOT_BUILT_IN; +} + +#endif /* if disabled */ diff --git a/libcurl/lib/mime.h b/libcurl/lib/mime.h new file mode 100644 index 0000000..4c9a5fb --- /dev/null +++ b/libcurl/lib/mime.h @@ -0,0 +1,164 @@ +#ifndef HEADER_CURL_MIME_H +#define HEADER_CURL_MIME_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#define MIME_RAND_BOUNDARY_CHARS 16 /* Nb. of random boundary chars. */ +#define MAX_ENCODED_LINE_LENGTH 76 /* Maximum encoded line length. */ +#define ENCODING_BUFFER_SIZE 256 /* Encoding temp buffers size. */ + +/* Part flags. */ +#define MIME_USERHEADERS_OWNER (1 << 0) +#define MIME_BODY_ONLY (1 << 1) + +#define FILE_CONTENTTYPE_DEFAULT "application/octet-stream" +#define MULTIPART_CONTENTTYPE_DEFAULT "multipart/mixed" +#define DISPOSITION_DEFAULT "attachment" + +/* Part source kinds. */ +enum mimekind { + MIMEKIND_NONE = 0, /* Part not set. */ + MIMEKIND_DATA, /* Allocated mime data. */ + MIMEKIND_FILE, /* Data from file. */ + MIMEKIND_CALLBACK, /* Data from `read' callback. */ + MIMEKIND_MULTIPART, /* Data is a mime subpart. */ + MIMEKIND_LAST +}; + +/* Readback state tokens. */ +enum mimestate { + MIMESTATE_BEGIN, /* Readback has not yet started. */ + MIMESTATE_CURLHEADERS, /* In curl-generated headers. */ + MIMESTATE_USERHEADERS, /* In caller's supplied headers. */ + MIMESTATE_EOH, /* End of headers. */ + MIMESTATE_BODY, /* Placeholder. */ + MIMESTATE_BOUNDARY1, /* In boundary prefix. */ + MIMESTATE_BOUNDARY2, /* In boundary. */ + MIMESTATE_CONTENT, /* In content. */ + MIMESTATE_END, /* End of part reached. */ + MIMESTATE_LAST +}; + +/* Mime headers strategies. */ +enum mimestrategy { + MIMESTRATEGY_MAIL, /* Mime mail. */ + MIMESTRATEGY_FORM, /* HTTP post form. */ + MIMESTRATEGY_LAST +}; + +/* Content transfer encoder. */ +typedef struct { + const char * name; /* Encoding name. */ + size_t (*encodefunc)(char *buffer, size_t size, bool ateof, + curl_mimepart *part); /* Encoded read. */ + curl_off_t (*sizefunc)(curl_mimepart *part); /* Encoded size. */ +} mime_encoder; + +/* Content transfer encoder state. */ +typedef struct { + size_t pos; /* Position on output line. */ + size_t bufbeg; /* Next data index in input buffer. */ + size_t bufend; /* First unused byte index in input buffer. */ + char buf[ENCODING_BUFFER_SIZE]; /* Input buffer. */ +} mime_encoder_state; + +/* Mime readback state. */ +typedef struct { + enum mimestate state; /* Current state token. */ + void *ptr; /* State-dependent pointer. */ + size_t offset; /* State-dependent offset. */ +} mime_state; + +/* minimum buffer size for the boundary string */ +#define MIME_BOUNDARY_LEN (24 + MIME_RAND_BOUNDARY_CHARS + 1) + +/* A mime multipart. */ +struct curl_mime_s { + struct Curl_easy *easy; /* The associated easy handle. */ + curl_mimepart *parent; /* Parent part. */ + curl_mimepart *firstpart; /* First part. */ + curl_mimepart *lastpart; /* Last part. */ + char boundary[MIME_BOUNDARY_LEN]; /* The part boundary. */ + mime_state state; /* Current readback state. */ +}; + +/* A mime part. */ +struct curl_mimepart_s { + struct Curl_easy *easy; /* The associated easy handle. */ + curl_mime *parent; /* Parent mime structure. */ + curl_mimepart *nextpart; /* Forward linked list. */ + enum mimekind kind; /* The part kind. */ + char *data; /* Memory data or file name. */ + curl_read_callback readfunc; /* Read function. */ + curl_seek_callback seekfunc; /* Seek function. */ + curl_free_callback freefunc; /* Argument free function. */ + void *arg; /* Argument to callback functions. */ + FILE *fp; /* File pointer. */ + struct curl_slist *curlheaders; /* Part headers. */ + struct curl_slist *userheaders; /* Part headers. */ + char *mimetype; /* Part mime type. */ + char *filename; /* Remote file name. */ + char *name; /* Data name. */ + curl_off_t datasize; /* Expected data size. */ + unsigned int flags; /* Flags. */ + mime_state state; /* Current readback state. */ + const mime_encoder *encoder; /* Content data encoder. */ + mime_encoder_state encstate; /* Data encoder state. */ +}; + +#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \ + !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP) + +/* Prototypes. */ +void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy); +void Curl_mime_cleanpart(curl_mimepart *part); +CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src); +CURLcode Curl_mime_set_subparts(curl_mimepart *part, + curl_mime *subparts, int take_ownership); +CURLcode Curl_mime_prepare_headers(curl_mimepart *part, + const char *contenttype, + const char *disposition, + enum mimestrategy strategy); +curl_off_t Curl_mime_size(curl_mimepart *part); +size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, + void *instream); +CURLcode Curl_mime_rewind(curl_mimepart *part); +CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...); +const char *Curl_mime_contenttype(const char *filename); + +#else +/* if disabled */ +#define Curl_mime_initpart(x,y) +#define Curl_mime_cleanpart(x) +#define Curl_mime_duppart(x,y) CURLE_OK /* Nothing to duplicate. Succeed */ +#define Curl_mime_set_subparts(a,b,c) CURLE_NOT_BUILT_IN +#define Curl_mime_prepare_headers(a,b,c,d) CURLE_NOT_BUILT_IN +#define Curl_mime_size(x) (curl_off_t) -1 +#define Curl_mime_read NULL +#define Curl_mime_rewind(x) ((void)x, CURLE_NOT_BUILT_IN) +#define Curl_mime_add_header(x,y,...) CURLE_NOT_BUILT_IN +#endif + + +#endif /* HEADER_CURL_MIME_H */ diff --git a/libcurl/lib/mk-ca-bundle.pl b/libcurl/lib/mk-ca-bundle.pl new file mode 100644 index 0000000..33977f3 --- /dev/null +++ b/libcurl/lib/mk-ca-bundle.pl @@ -0,0 +1,558 @@ +#!/usr/bin/env perl +# *************************************************************************** +# * _ _ ____ _ +# * Project ___| | | | _ \| | +# * / __| | | | |_) | | +# * | (__| |_| | _ <| |___ +# * \___|\___/|_| \_\_____| +# * +# * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. +# * +# * This software is licensed as described in the file COPYING, which +# * you should have received as part of this distribution. The terms +# * are also available at https://curl.haxx.se/docs/copyright.html. +# * +# * You may opt to use, copy, modify, merge, publish, distribute and/or sell +# * copies of the Software, and permit persons to whom the Software is +# * furnished to do so, under the terms of the COPYING file. +# * +# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# * KIND, either express or implied. +# * +# *************************************************************************** +# This Perl script creates a fresh ca-bundle.crt file for use with libcurl. +# It downloads certdata.txt from Mozilla's source tree (see URL below), +# then parses certdata.txt and extracts CA Root Certificates into PEM format. +# These are then processed with the OpenSSL commandline tool to produce the +# final ca-bundle.crt file. +# The script is based on the parse-certs script written by Roland Krikava. +# This Perl script works on almost any platform since its only external +# dependency is the OpenSSL commandline tool for optional text listing. +# Hacked by Guenter Knauf. +# +use Encode; +use Getopt::Std; +use MIME::Base64; +use strict; +use warnings; +use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_k $opt_l $opt_m $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w); +use List::Util; +use Text::Wrap; +my $MOD_SHA = "Digest::SHA"; +eval "require $MOD_SHA"; +if ($@) { + $MOD_SHA = "Digest::SHA::PurePerl"; + eval "require $MOD_SHA"; +} +eval "require LWP::UserAgent"; + +my %urls = ( + 'nss' => + 'https://hg.mozilla.org/projects/nss/raw-file/default/lib/ckfw/builtins/certdata.txt', + 'central' => + 'https://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt', + 'beta' => + 'https://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt', + 'release' => + 'https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt', +); + +$opt_d = 'release'; + +# If the OpenSSL commandline is not in search path you can configure it here! +my $openssl = 'openssl'; + +my $version = '1.27'; + +$opt_w = 76; # default base64 encoded lines length + +# default cert types to include in the output (default is to include CAs which may issue SSL server certs) +my $default_mozilla_trust_purposes = "SERVER_AUTH"; +my $default_mozilla_trust_levels = "TRUSTED_DELEGATOR"; +$opt_p = $default_mozilla_trust_purposes . ":" . $default_mozilla_trust_levels; + +my @valid_mozilla_trust_purposes = ( + "DIGITAL_SIGNATURE", + "NON_REPUDIATION", + "KEY_ENCIPHERMENT", + "DATA_ENCIPHERMENT", + "KEY_AGREEMENT", + "KEY_CERT_SIGN", + "CRL_SIGN", + "SERVER_AUTH", + "CLIENT_AUTH", + "CODE_SIGNING", + "EMAIL_PROTECTION", + "IPSEC_END_SYSTEM", + "IPSEC_TUNNEL", + "IPSEC_USER", + "TIME_STAMPING", + "STEP_UP_APPROVED" +); + +my @valid_mozilla_trust_levels = ( + "TRUSTED_DELEGATOR", # CAs + "NOT_TRUSTED", # Don't trust these certs. + "MUST_VERIFY_TRUST", # This explicitly tells us that it ISN'T a CA but is otherwise ok. In other words, this should tell the app to ignore any other sources that claim this is a CA. + "TRUSTED" # This cert is trusted, but only for itself and not for delegates (i.e. it is not a CA). +); + +my $default_signature_algorithms = $opt_s = "MD5"; + +my @valid_signature_algorithms = ( + "MD5", + "SHA1", + "SHA256", + "SHA384", + "SHA512" +); + +$0 =~ s@.*(/|\\)@@; +$Getopt::Std::STANDARD_HELP_VERSION = 1; +getopts('bd:fhiklmnp:qs:tuvw:'); + +if(!defined($opt_d)) { + # to make plain "-d" use not cause warnings, and actually still work + $opt_d = 'release'; +} + +# Use predefined URL or else custom URL specified on command line. +my $url; +if(defined($urls{$opt_d})) { + $url = $urls{$opt_d}; + if(!$opt_k && $url !~ /^https:\/\//i) { + die "The URL for '$opt_d' is not HTTPS. Use -k to override (insecure).\n"; + } +} +else { + $url = $opt_d; +} + +my $curl = `curl -V`; + +if ($opt_i) { + print ("=" x 78 . "\n"); + print "Script Version : $version\n"; + print "Perl Version : $]\n"; + print "Operating System Name : $^O\n"; + print "Getopt::Std.pm Version : ${Getopt::Std::VERSION}\n"; + print "Encode::Encoding.pm Version : ${Encode::Encoding::VERSION}\n"; + print "MIME::Base64.pm Version : ${MIME::Base64::VERSION}\n"; + print "LWP::UserAgent.pm Version : ${LWP::UserAgent::VERSION}\n" if($LWP::UserAgent::VERSION); + print "LWP.pm Version : ${LWP::VERSION}\n" if($LWP::VERSION); + print "Digest::SHA.pm Version : ${Digest::SHA::VERSION}\n" if ($Digest::SHA::VERSION); + print "Digest::SHA::PurePerl.pm Version : ${Digest::SHA::PurePerl::VERSION}\n" if ($Digest::SHA::PurePerl::VERSION); + print ("=" x 78 . "\n"); +} + +sub warning_message() { + if ( $opt_d =~ m/^risk$/i ) { # Long Form Warning and Exit + print "Warning: Use of this script may pose some risk:\n"; + print "\n"; + print " 1) If you use HTTP URLs they are subject to a man in the middle attack\n"; + print " 2) Default to 'release', but more recent updates may be found in other trees\n"; + print " 3) certdata.txt file format may change, lag time to update this script\n"; + print " 4) Generally unwise to blindly trust CAs without manual review & verification\n"; + print " 5) Mozilla apps use additional security checks aren't represented in certdata\n"; + print " 6) Use of this script will make a security engineer grind his teeth and\n"; + print " swear at you. ;)\n"; + exit; + } else { # Short Form Warning + print "Warning: Use of this script may pose some risk, -d risk for more details.\n"; + } +} + +sub HELP_MESSAGE() { + print "Usage:\t${0} [-b] [-d] [-f] [-i] [-k] [-l] [-n] [-p] [-q] [-s] [-t] [-u] [-v] [-w] []\n"; + print "\t-b\tbackup an existing version of ca-bundle.crt\n"; + print "\t-d\tspecify Mozilla tree to pull certdata.txt or custom URL\n"; + print "\t\t Valid names are:\n"; + print "\t\t ", join( ", ", map { ( $_ =~ m/$opt_d/ ) ? "$_ (default)" : "$_" } sort keys %urls ), "\n"; + print "\t-f\tforce rebuild even if certdata.txt is current\n"; + print "\t-i\tprint version info about used modules\n"; + print "\t-k\tallow URLs other than HTTPS, enable HTTP fallback (insecure)\n"; + print "\t-l\tprint license info about certdata.txt\n"; + print "\t-m\tinclude meta data in output\n"; + print "\t-n\tno download of certdata.txt (to use existing)\n"; + print wrap("\t","\t\t", "-p\tlist of Mozilla trust purposes and levels for certificates to include in output. Takes the form of a comma separated list of purposes, a colon, and a comma separated list of levels. (default: $default_mozilla_trust_purposes:$default_mozilla_trust_levels)"), "\n"; + print "\t\t Valid purposes are:\n"; + print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_mozilla_trust_purposes ) ), "\n"; + print "\t\t Valid levels are:\n"; + print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_mozilla_trust_levels ) ), "\n"; + print "\t-q\tbe really quiet (no progress output at all)\n"; + print wrap("\t","\t\t", "-s\tcomma separated list of certificate signatures/hashes to output in plain text mode. (default: $default_signature_algorithms)\n"); + print "\t\t Valid signature algorithms are:\n"; + print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_signature_algorithms ) ), "\n"; + print "\t-t\tinclude plain text listing of certificates\n"; + print "\t-u\tunlink (remove) certdata.txt after processing\n"; + print "\t-v\tbe verbose and print out processed CAs\n"; + print "\t-w \twrap base64 output lines after chars (default: ${opt_w})\n"; + exit; +} + +sub VERSION_MESSAGE() { + print "${0} version ${version} running Perl ${]} on ${^O}\n"; +} + +warning_message() unless ($opt_q || $url =~ m/^(ht|f)tps:/i ); +HELP_MESSAGE() if ($opt_h); + +sub report($@) { + my $output = shift; + + print STDERR $output . "\n" unless $opt_q; +} + +sub is_in_list($@) { + my $target = shift; + + return defined(List::Util::first { $target eq $_ } @_); +} + +# Parses $param_string as a case insensitive comma separated list with optional whitespace +# validates that only allowed parameters are supplied +sub parse_csv_param($$@) { + my $description = shift; + my $param_string = shift; + my @valid_values = @_; + + my @values = map { + s/^\s+//; # strip leading spaces + s/\s+$//; # strip trailing spaces + uc $_ # return the modified string as upper case + } split( ',', $param_string ); + + # Find all values which are not in the list of valid values or "ALL" + my @invalid = grep { !is_in_list($_,"ALL",@valid_values) } @values; + + if ( scalar(@invalid) > 0 ) { + # Tell the user which parameters were invalid and print the standard help message which will exit + print "Error: Invalid ", $description, scalar(@invalid) == 1 ? ": " : "s: ", join( ", ", map { "\"$_\"" } @invalid ), "\n"; + HELP_MESSAGE(); + } + + @values = @valid_values if ( is_in_list("ALL",@values) ); + + return @values; +} + +sub sha256 { + my $result; + if ($Digest::SHA::VERSION || $Digest::SHA::PurePerl::VERSION) { + open(FILE, $_[0]) or die "Can't open '$_[0]': $!"; + binmode(FILE); + $result = $MOD_SHA->new(256)->addfile(*FILE)->hexdigest; + close(FILE); + } else { + # Use OpenSSL command if Perl Digest::SHA modules not available + $result = `"$openssl" dgst -r -sha256 "$_[0]"`; + $result =~ s/^([0-9a-f]{64}) .+/$1/is; + } + return $result; +} + + +sub oldhash { + my $hash = ""; + open(C, "<$_[0]") || return 0; + while() { + chomp; + if($_ =~ /^\#\# SHA256: (.*)/) { + $hash = $1; + last; + } + } + close(C); + return $hash; +} + +if ( $opt_p !~ m/:/ ) { + print "Error: Mozilla trust identifier list must include both purposes and levels\n"; + HELP_MESSAGE(); +} + +(my $included_mozilla_trust_purposes_string, my $included_mozilla_trust_levels_string) = split( ':', $opt_p ); +my @included_mozilla_trust_purposes = parse_csv_param( "trust purpose", $included_mozilla_trust_purposes_string, @valid_mozilla_trust_purposes ); +my @included_mozilla_trust_levels = parse_csv_param( "trust level", $included_mozilla_trust_levels_string, @valid_mozilla_trust_levels ); + +my @included_signature_algorithms = parse_csv_param( "signature algorithm", $opt_s, @valid_signature_algorithms ); + +sub should_output_cert(%) { + my %trust_purposes_by_level = @_; + + foreach my $level (@included_mozilla_trust_levels) { + # for each level we want to output, see if any of our desired purposes are included + return 1 if ( defined( List::Util::first { is_in_list( $_, @included_mozilla_trust_purposes ) } @{$trust_purposes_by_level{$level}} ) ); + } + + return 0; +} + +my $crt = $ARGV[0] || 'ca-bundle.crt'; +(my $txt = $url) =~ s@(.*/|\?.*)@@g; + +my $stdout = $crt eq '-'; +my $resp; +my $fetched; + +my $oldhash = oldhash($crt); + +report "SHA256 of old file: $oldhash"; + +if(!$opt_n) { + report "Downloading $txt ..."; + + # If we have an HTTPS URL then use curl + if($url =~ /^https:\/\//i) { + if($curl) { + if($curl =~ /^Protocols:.* https( |$)/m) { + report "Get certdata with curl!"; + my $proto = !$opt_k ? "--proto =https" : ""; + my $quiet = $opt_q ? "-s" : ""; + my @out = `curl -w %{response_code} $proto $quiet -o "$txt" "$url"`; + if(!$? && @out && $out[0] == 200) { + $fetched = 1; + report "Downloaded $txt"; + } + else { + report "Failed downloading via HTTPS with curl"; + if(-e $txt && !unlink($txt)) { + report "Failed to remove '$txt': $!"; + } + } + } + else { + report "curl lacks https support"; + } + } + else { + report "curl not found"; + } + } + + # If nothing was fetched then use LWP + if(!$fetched) { + if($url =~ /^https:\/\//i) { + report "Falling back to HTTP"; + $url =~ s/^https:\/\//http:\/\//i; + } + if(!$opt_k) { + report "URLs other than HTTPS are disabled by default, to enable use -k"; + exit 1; + } + report "Get certdata with LWP!"; + if(!defined(${LWP::UserAgent::VERSION})) { + report "LWP is not available (LWP::UserAgent not found)"; + exit 1; + } + my $ua = new LWP::UserAgent(agent => "$0/$version"); + $ua->env_proxy(); + $resp = $ua->mirror($url, $txt); + if($resp && $resp->code eq '304') { + report "Not modified"; + exit 0 if -e $crt && !$opt_f; + } + else { + $fetched = 1; + report "Downloaded $txt"; + } + if(!$resp || $resp->code !~ /^(?:200|304)$/) { + report "Unable to download latest data: " + . ($resp? $resp->code . ' - ' . $resp->message : "LWP failed"); + exit 1 if -e $crt || ! -r $txt; + } + } +} + +my $filedate = $resp ? $resp->last_modified : (stat($txt))[9]; +my $datesrc = "as of"; +if(!$filedate) { + # mxr.mozilla.org gave us a time, hg.mozilla.org does not! + $filedate = time(); + $datesrc="downloaded on"; +} + +# get the hash from the download file +my $newhash= sha256($txt); + +if(!$opt_f && $oldhash eq $newhash) { + report "Downloaded file identical to previous run\'s source file. Exiting"; + if($opt_u && -e $txt && !unlink($txt)) { + report "Failed to remove $txt: $!\n"; + } + exit; +} + +report "SHA256 of new file: $newhash"; + +my $currentdate = scalar gmtime($filedate); + +my $format = $opt_t ? "plain text and " : ""; +if( $stdout ) { + open(CRT, '> -') or die "Couldn't open STDOUT: $!\n"; +} else { + open(CRT,">$crt.~") or die "Couldn't open $crt.~: $!\n"; +} +print CRT <) { + if (/\*\*\*\*\* BEGIN LICENSE BLOCK \*\*\*\*\*/) { + print CRT; + print if ($opt_l); + while () { + print CRT; + print if ($opt_l); + last if (/\*\*\*\*\* END LICENSE BLOCK \*\*\*\*\*/); + } + } + elsif(/^# (Issuer|Serial Number|Subject|Not Valid Before|Not Valid After |Fingerprint \(MD5\)|Fingerprint \(SHA1\)):/) { + push @precert, $_; + next; + } + elsif(/^#|^\s*$/) { + undef @precert; + next; + } + chomp; + + # this is a match for the start of a certificate + if (/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) { + $start_of_cert = 1 + } + if ($start_of_cert && /^CKA_LABEL UTF8 \"(.*)\"/) { + $caname = $1; + } + my %trust_purposes_by_level; + if ($start_of_cert && /^CKA_VALUE MULTILINE_OCTAL/) { + my $data; + while () { + last if (/^END/); + chomp; + my @octets = split(/\\/); + shift @octets; + for (@octets) { + $data .= chr(oct); + } + } + # scan forwards until the trust part + while () { + last if (/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/); + chomp; + } + # now scan the trust part to determine how we should trust this cert + while () { + last if (/^#/); + if (/^CKA_TRUST_([A-Z_]+)\s+CK_TRUST\s+CKT_NSS_([A-Z_]+)\s*$/) { + if ( !is_in_list($1,@valid_mozilla_trust_purposes) ) { + report "Warning: Unrecognized trust purpose for cert: $caname. Trust purpose: $1. Trust Level: $2"; + } elsif ( !is_in_list($2,@valid_mozilla_trust_levels) ) { + report "Warning: Unrecognized trust level for cert: $caname. Trust purpose: $1. Trust Level: $2"; + } else { + push @{$trust_purposes_by_level{$2}}, $1; + } + } + } + + if ( !should_output_cert(%trust_purposes_by_level) ) { + $skipnum ++; + report "Skipping: $caname" if ($opt_v); + } else { + my $encoded = MIME::Base64::encode_base64($data, ''); + $encoded =~ s/(.{1,${opt_w}})/$1\n/g; + my $pem = "-----BEGIN CERTIFICATE-----\n" + . $encoded + . "-----END CERTIFICATE-----\n"; + print CRT "\n$caname\n"; + print CRT @precert if($opt_m); + my $maxStringLength = length(decode('UTF-8', $caname, Encode::FB_CROAK | Encode::LEAVE_SRC)); + if ($opt_t) { + foreach my $key (keys %trust_purposes_by_level) { + my $string = $key . ": " . join(", ", @{$trust_purposes_by_level{$key}}); + $maxStringLength = List::Util::max( length($string), $maxStringLength ); + print CRT $string . "\n"; + } + } + print CRT ("=" x $maxStringLength . "\n"); + if (!$opt_t) { + print CRT $pem; + } else { + my $pipe = ""; + foreach my $hash (@included_signature_algorithms) { + $pipe = "|$openssl x509 -" . $hash . " -fingerprint -noout -inform PEM"; + if (!$stdout) { + $pipe .= " >> $crt.~"; + close(CRT) or die "Couldn't close $crt.~: $!"; + } + open(TMP, $pipe) or die "Couldn't open openssl pipe: $!"; + print TMP $pem; + close(TMP) or die "Couldn't close openssl pipe: $!"; + if (!$stdout) { + open(CRT, ">>$crt.~") or die "Couldn't open $crt.~: $!"; + } + } + $pipe = "|$openssl x509 -text -inform PEM"; + if (!$stdout) { + $pipe .= " >> $crt.~"; + close(CRT) or die "Couldn't close $crt.~: $!"; + } + open(TMP, $pipe) or die "Couldn't open openssl pipe: $!"; + print TMP $pem; + close(TMP) or die "Couldn't close openssl pipe: $!"; + if (!$stdout) { + open(CRT, ">>$crt.~") or die "Couldn't open $crt.~: $!"; + } + } + report "Parsing: $caname" if ($opt_v); + $certnum ++; + $start_of_cert = 0; + } + undef @precert; + } + +} +close(TXT) or die "Couldn't close $txt: $!\n"; +close(CRT) or die "Couldn't close $crt.~: $!\n"; +unless( $stdout ) { + if ($opt_b && -e $crt) { + my $bk = 1; + while (-e "$crt.~${bk}~") { + $bk++; + } + rename $crt, "$crt.~${bk}~" or die "Failed to create backup $crt.~$bk}~: $!\n"; + } elsif( -e $crt ) { + unlink( $crt ) or die "Failed to remove $crt: $!\n"; + } + rename "$crt.~", $crt or die "Failed to rename $crt.~ to $crt: $!\n"; +} +if($opt_u && -e $txt && !unlink($txt)) { + report "Failed to remove $txt: $!\n"; +} +report "Done ($certnum CA certs processed, $skipnum skipped)."; diff --git a/libcurl/lib/mk-ca-bundle.vbs b/libcurl/lib/mk-ca-bundle.vbs new file mode 100644 index 0000000..bd4e4a3 --- /dev/null +++ b/libcurl/lib/mk-ca-bundle.vbs @@ -0,0 +1,431 @@ +'*************************************************************************** +'* _ _ ____ _ +'* Project ___| | | | _ \| | +'* / __| | | | |_) | | +'* | (__| |_| | _ <| |___ +'* \___|\___/|_| \_\_____| +'* +'* Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. +'* +'* This software is licensed as described in the file COPYING, which +'* you should have received as part of this distribution. The terms +'* are also available at https://curl.haxx.se/docs/copyright.html. +'* +'* You may opt to use, copy, modify, merge, publish, distribute and/or sell +'* copies of the Software, and permit persons to whom the Software is +'* furnished to do so, under the terms of the COPYING file. +'* +'* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +'* KIND, either express or implied. +'* +'*************************************************************************** +'* Script to fetch certdata.txt from Mozilla.org site and create a +'* ca-bundle.crt for use with OpenSSL / libcurl / libcurl bindings +'* Requires WinHttp.WinHttpRequest.5.1 and ADODB.Stream which are part of +'* W2000 SP3 or later, WXP SP1 or later, W2003 Server SP1 or later. +'* Hacked by Guenter Knauf +'*************************************************************************** +Option Explicit +Const myVersion = "0.4.0" + +Const myUrl = "https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt" + +Const myOpenSSL = "openssl.exe" +Dim myUseOpenSSL +myUseOpenSSL = TRUE ' Flag: TRUE to use OpenSSL. If TRUE and is not + ' found then a warning is shown before continuing. + +Const myCdSavF = TRUE ' Flag: save downloaded data to file certdata.txt +Const myCaBakF = TRUE ' Flag: backup existing ca-bundle certificate +Const myAskLiF = TRUE ' Flag: display certdata.txt license agreement +Const myWrapLe = 76 ' Default length of base64 output lines + +' cert info code doesn't work properly with any recent openssl, leave disabled. +' Also: we want our certificate output by default to be as similar as possible +' to mk-ca-bundle.pl and setting this TRUE changes the base64 width to +' OpenSSL's built-in default width, which is not the same as mk-ca-bundle.pl. +Const myAskTiF = FALSE ' Flag: ask to include certificate text info + +' +'******************* Nothing to configure below! ******************* +' +Const adTypeBinary = 1 +Const adTypeText = 2 +Const adSaveCreateNotExist = 1 +Const adSaveCreateOverWrite = 2 +Dim objShell, objNetwork, objFSO, objHttp +Dim myBase, mySelf, myStream, myTmpFh, myCdData, myCdFile +Dim myCaFile, myTmpName, myBakNum, myOptTxt, i +Set objNetwork = WScript.CreateObject("WScript.Network") +Set objShell = WScript.CreateObject("WScript.Shell") +Set objFSO = WScript.CreateObject("Scripting.FileSystemObject") +Set objHttp = WScript.CreateObject("WinHttp.WinHttpRequest.5.1") +If objHttp Is Nothing Then Set objHttp = WScript.CreateObject("WinHttp.WinHttpRequest") +myBase = Left(WScript.ScriptFullName, InstrRev(WScript.ScriptFullName, "\")) +mySelf = Left(WScript.ScriptName, InstrRev(WScript.ScriptName, ".") - 1) & " " & myVersion + +myCdFile = Mid(myUrl, InstrRev(myUrl, "/") + 1) +myCaFile = "ca-bundle.crt" +myTmpName = InputBox("It will take a minute to download and parse the " & _ + "certificate data." & _ + vbLf & vbLf & _ + "Please enter the output filename:", mySelf, myCaFile) +If (myTmpName = "") Then + WScript.Quit 1 +End If +myCaFile = myTmpName +If (myCdFile = "") Then + MsgBox("URL does not contain filename!"), vbCritical, mySelf + WScript.Quit 1 +End If + +' Don't use OpenSSL if it's not present. +If (myUseOpenSSL = TRUE) Then + Dim errnum + + On Error Resume Next + Call objShell.Run("""" & myOpenSSL & """ version", 0, TRUE) + errnum = Err.Number + On Error GoTo 0 + + If Not (errnum = 0) Then + myUseOpenSSL = FALSE + MsgBox("OpenSSL was not found so the certificate bundle will not " & _ + "include the SHA256 hash of the raw certificate data file " & _ + "that was used to generate the certificates in the bundle. " & _ + vbLf & vbLf & _ + "This does not have any effect on the certificate output, " & _ + "so this script will continue." & _ + vbLf & vbLf & _ + "If you want to set a custom location for OpenSSL or disable " & _ + "this message then edit the variables at the start of the " & _ + "script."), vbInformation, mySelf + End If +End If + +If (myAskTiF = TRUE) And (myUseOpenSSL = TRUE) Then + If (6 = objShell.PopUp("Do you want to include text information about " & _ + "each certificate?" & vbLf & _ + "(Requires OpenSSL.exe in the current directory " & _ + "or search path)",, _ + mySelf, vbQuestion + vbYesNo + vbDefaultButton2)) Then + myOptTxt = TRUE + Else + myOptTxt = FALSE + End If +End If + +' Uncomment the line below to ignore SSL invalid cert errors +' objHttp.Option(4) = 256 + 512 + 4096 + 8192 +objHttp.SetTimeouts 0, 5000, 10000, 10000 +objHttp.Open "GET", myUrl, FALSE +objHttp.setRequestHeader "User-Agent", WScript.ScriptName & "/" & myVersion +objHttp.Send "" +If Not (objHttp.Status = 200) Then + MsgBox("Failed to download '" & myCdFile & "': " & objHttp.Status & " - " & objHttp.StatusText), vbCritical, mySelf + WScript.Quit 1 +End If +' Write received data to file if enabled +If (myCdSavF = TRUE) Then + Call SaveBinaryData(myCdFile, objHttp.ResponseBody) +End If +' Convert data from ResponseBody instead of using ResponseText because of UTF-8 +myCdData = ConvertBinaryToUTF8(objHttp.ResponseBody) +Set objHttp = Nothing +' Backup exitsing ca-bundle certificate file +If (myCaBakF = TRUE) Then + If objFSO.FileExists(myCaFile) Then + Dim myBakFile, b + b = 1 + myBakFile = myCaFile & ".~" & b & "~" + While objFSO.FileExists(myBakFile) + b = b + 1 + myBakFile = myCaFile & ".~" & b & "~" + Wend + Set myTmpFh = objFSO.GetFile(myCaFile) + myTmpFh.Move myBakFile + End If +End If + +' Process the received data +Dim myLines, myPattern, myInsideCert, myInsideLicense, myLicenseText, myNumCerts, myNumSkipped +Dim myLabel, myOctets, myData, myPem, myRev, myUntrusted, j +myNumSkipped = 0 +myNumCerts = 0 +myData = "" +myLines = Split(myCdData, vbLf, -1) +Set myStream = CreateObject("ADODB.Stream") +myStream.Open +myStream.Type = adTypeText +myStream.Charset = "utf-8" +myStream.WriteText "##" & vbLf & _ + "## Bundle of CA Root Certificates" & vbLf & _ + "##" & vbLf & _ + "## Certificate data from Mozilla as of: " & _ + ConvertDateToString(LocalDateToUTC(Now)) & " GMT" & vbLf & _ + "##" & vbLf & _ + "## This is a bundle of X.509 certificates of public Certificate Authorities" & vbLf & _ + "## (CA). These were automatically extracted from Mozilla's root certificates" & vbLf & _ + "## file (certdata.txt). This file can be found in the mozilla source tree:" & vbLf & _ + "## " & myUrl & vbLf & _ + "##" & vbLf & _ + "## It contains the certificates in PEM format and therefore" & vbLf & _ + "## can be directly used with curl / libcurl / php_curl, or with" & vbLf & _ + "## an Apache+mod_ssl webserver for SSL client authentication." & vbLf & _ + "## Just configure this file as the SSLCACertificateFile." & vbLf & _ + "##" & vbLf & _ + "## Conversion done with mk-ca-bundle.vbs version " & myVersion & "." & vbLf +If (myCdSavF = TRUE) And (myUseOpenSSL = TRUE) Then + myStream.WriteText "## SHA256: " & FileSHA256(myCdFile) & vbLf +End If +myStream.WriteText "##" & vbLf & vbLf + +myStream.WriteText vbLf +For i = 0 To UBound(myLines) + If InstrRev(myLines(i), "CKA_LABEL ") Then + myPattern = "^CKA_LABEL\s+[A-Z0-9]+\s+""(.+?)""" + myLabel = RegExprFirst(myPattern, myLines(i)) + End If + If (myInsideCert = TRUE) Then + If InstrRev(myLines(i), "END") Then + myInsideCert = FALSE + While (i < UBound(myLines)) And Not (myLines(i) = "#") + i = i + 1 + If InstrRev(myLines(i), "CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR") Then + myUntrusted = FALSE + End If + Wend + If (myUntrusted = TRUE) Then + myNumSkipped = myNumSkipped + 1 + Else + myStream.WriteText myLabel & vbLf + myStream.WriteText String(Len(myLabel), "=") & vbLf + myPem = "-----BEGIN CERTIFICATE-----" & vbLf & _ + Base64Encode(myData) & vbLf & _ + "-----END CERTIFICATE-----" & vbLf + If (myOptTxt = FALSE) Then + myStream.WriteText myPem & vbLf + Else + Dim myCmd, myRval, myTmpIn, myTmpOut + myTmpIn = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName + myTmpOut = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName + Set myTmpFh = objFSO.OpenTextFile(myTmpIn, 2, TRUE) + myTmpFh.Write myPem + myTmpFh.Close + myCmd = """" & myOpenSSL & """ x509 -md5 -fingerprint -text " & _ + "-inform PEM -in " & myTmpIn & " -out " & myTmpOut + myRval = objShell.Run (myCmd, 0, TRUE) + objFSO.DeleteFile myTmpIn, TRUE + If Not (myRval = 0) Then + MsgBox("Failed to process PEM cert with OpenSSL commandline!"), vbCritical, mySelf + objFSO.DeleteFile myTmpOut, TRUE + WScript.Quit 3 + End If + Set myTmpFh = objFSO.OpenTextFile(myTmpOut, 1) + myStream.WriteText myTmpFh.ReadAll & vbLf + myTmpFh.Close + objFSO.DeleteFile myTmpOut, TRUE + End If + myNumCerts = myNumCerts + 1 + End If + Else + myOctets = Split(myLines(i), "\") + For j = 1 To UBound(myOctets) + myData = myData & Chr(CByte("&o" & myOctets(j))) + Next + End If + End If + If InstrRev(myLines(i), "CVS_ID ") Then + myPattern = "^CVS_ID\s+""(.+?)""" + myRev = RegExprFirst(myPattern, myLines(i)) + myStream.WriteText "# " & myRev & vbLf & vbLf + End If + If InstrRev(myLines(i), "CKA_VALUE MULTILINE_OCTAL") Then + myInsideCert = TRUE + myUntrusted = TRUE + myData = "" + End If + If InstrRev(myLines(i), "***** BEGIN LICENSE BLOCK *****") Then + myInsideLicense = TRUE + End If + If (myInsideLicense = TRUE) Then + myStream.WriteText myLines(i) & vbLf + myLicenseText = myLicenseText & Mid(myLines(i), 2) & vbLf + End If + If InstrRev(myLines(i), "***** END LICENSE BLOCK *****") Then + myInsideLicense = FALSE + If (myAskLiF = TRUE) Then + If Not (6 = objShell.PopUp(myLicenseText & vbLf & _ + "Do you agree to the license shown above (required to proceed) ?",, _ + mySelf, vbQuestion + vbYesNo + vbDefaultButton1)) Then + myStream.Close + objFSO.DeleteFile myCaFile, TRUE + WScript.Quit 2 + End If + End If + End If +Next + +' To stop the UTF-8 BOM from being written the stream has to be copied and +' then saved as binary. +Dim myCopy +Set myCopy = CreateObject("ADODB.Stream") +myCopy.Type = adTypeBinary +myCopy.Open +myStream.Position = 3 ' Skip UTF-8 BOM +myStream.CopyTo myCopy +myCopy.SaveToFile myCaFile, adSaveCreateOverWrite +myCopy.Close +myStream.Close +Set myCopy = Nothing +Set myStream = Nothing + +' Done +objShell.PopUp "Done (" & myNumCerts & " CA certs processed, " & myNumSkipped & _ + " untrusted skipped).", 20, mySelf, vbInformation +WScript.Quit 0 + +Function ConvertBinaryToUTF8(arrBytes) + Dim objStream + Set objStream = CreateObject("ADODB.Stream") + objStream.Open + objStream.Type = adTypeBinary + objStream.Write arrBytes + objStream.Position = 0 + objStream.Type = adTypeText + objStream.Charset = "utf-8" + ConvertBinaryToUTF8 = objStream.ReadText + Set objStream = Nothing +End Function + +Function SaveBinaryData(filename, data) + Dim objStream + Set objStream = CreateObject("ADODB.Stream") + objStream.Type = adTypeBinary + objStream.Open + objStream.Write data + objStream.SaveToFile filename, adSaveCreateOverWrite + objStream.Close + Set objStream = Nothing +End Function + +Function RegExprFirst(SearchPattern, TheString) + Dim objRegExp, Matches ' create variables. + Set objRegExp = New RegExp ' create a regular expression. + objRegExp.Pattern = SearchPattern ' sets the search pattern. + objRegExp.IgnoreCase = TRUE ' set to ignores case. + objRegExp.Global = TRUE ' set to global search. + Set Matches = objRegExp.Execute(TheString) ' do the search. + If (Matches.Count) Then + RegExprFirst = Matches(0).SubMatches(0) ' return first match. + Else + RegExprFirst = "" + End If + Set objRegExp = Nothing +End Function + +Function Base64Encode(inData) + Const Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + Dim cOut, sOut, lWrap, I + lWrap = Int(myWrapLe * 3 / 4) + + 'For each group of 3 bytes + For I = 1 To Len(inData) Step 3 + Dim nGroup, pOut, sGroup + + 'Create one long from this 3 bytes. + nGroup = &H10000 * Asc(Mid(inData, I, 1)) + _ + &H100 * MyASC(Mid(inData, I + 1, 1)) + _ + MyASC(Mid(inData, I + 2, 1)) + + 'Oct splits the long To 8 groups with 3 bits + nGroup = Oct(nGroup) + + 'Add leading zeros + nGroup = String(8 - Len(nGroup), "0") & nGroup + + 'Convert To base64 + pOut = Mid(Base64, CLng("&o" & Mid(nGroup, 1, 2)) + 1, 1) & _ + Mid(Base64, CLng("&o" & Mid(nGroup, 3, 2)) + 1, 1) & _ + Mid(Base64, CLng("&o" & Mid(nGroup, 5, 2)) + 1, 1) & _ + Mid(Base64, CLng("&o" & Mid(nGroup, 7, 2)) + 1, 1) + + 'Add the part To OutPut string + sOut = sOut + pOut + + 'Add a new line For Each myWrapLe chars In dest + If (I < Len(inData) - 2) Then + If (I + 2) Mod lWrap = 0 Then sOut = sOut & vbLf + End If + Next + Select Case Len(inData) Mod 3 + Case 1: '8 bit final + sOut = Left(sOut, Len(sOut) - 2) & "==" + Case 2: '16 bit final + sOut = Left(sOut, Len(sOut) - 1) & "=" + End Select + Base64Encode = sOut +End Function + +Function MyASC(OneChar) + If OneChar = "" Then MyASC = 0 Else MyASC = Asc(OneChar) +End Function + +' Return the date in the same format as perl to match mk-ca-bundle.pl output: +' Wed Sep 7 03:12:05 2016 +Function ConvertDateToString(input) + Dim output + output = WeekDayName(WeekDay(input), TRUE) & " " & _ + MonthName(Month(input), TRUE) & " " + If (Len(Day(input)) = 1) Then + output = output & " " + End If + output = output & _ + Day(input) & " " & _ + FormatDateTime(input, vbShortTime) & ":" + If (Len(Second(input)) = 1) Then + output = output & "0" + End If + output = output & _ + Second(input) & " " & _ + Year(input) + ConvertDateToString = output +End Function + +' Convert local Date to UTC. Microsoft says: +' Use Win32_ComputerSystem CurrentTimeZone property, because it automatically +' adjusts the Time Zone bias for daylight saving time; Win32_Time Zone Bias +' property does not. +' https://msdn.microsoft.com/en-us/library/windows/desktop/ms696015.aspx +Function LocalDateToUTC(localdate) + Dim item, offset + For Each item In GetObject("winmgmts:").InstancesOf("Win32_ComputerSystem") + offset = item.CurrentTimeZone ' the offset in minutes + Next + If (offset < 0) Then + LocalDateToUTC = DateAdd("n", ABS(offset), localdate) + Else + LocalDateToUTC = DateAdd("n", -ABS(offset), localdate) + End If + 'objShell.PopUp LocalDateToUTC +End Function + +Function FileSHA256(filename) + Dim cmd, rval, tmpOut, tmpFh + if (myUseOpenSSL = TRUE) Then + tmpOut = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName + cmd = """" & myOpenSSL & """ dgst -r -sha256 -out """ & tmpOut & """ """ & filename & """" + rval = objShell.Run(cmd, 0, TRUE) + If Not (rval = 0) Then + MsgBox("Failed to get sha256 of """ & filename & """ with OpenSSL commandline!"), vbCritical, mySelf + objFSO.DeleteFile tmpOut, TRUE + WScript.Quit 3 + End If + Set tmpFh = objFSO.OpenTextFile(tmpOut, 1) + FileSHA256 = RegExprFirst("^([0-9a-f]{64}) .+", tmpFh.ReadAll) + tmpFh.Close + objFSO.DeleteFile tmpOut, TRUE + Else + FileSHA256 = "" + End If +End Function diff --git a/libcurl/lib/mprintf.c b/libcurl/lib/mprintf.c new file mode 100644 index 0000000..e190936 --- /dev/null +++ b/libcurl/lib/mprintf.c @@ -0,0 +1,1173 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1999 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * + * Purpose: + * A merge of Bjorn Reese's format() function and Daniel's dsprintf() + * 1.0. A full blooded printf() clone with full support for $ + * everywhere (parameters, widths and precisions) including variabled + * sized parameters (like doubles, long longs, long doubles and even + * void * in 64-bit architectures). + * + * Current restrictions: + * - Max 128 parameters + * - No 'long double' support. + * + * If you ever want truly portable and good *printf() clones, the project that + * took on from here is named 'Trio' and you find more details on the trio web + * page at https://daniel.haxx.se/projects/trio/ + */ + +#include "curl_setup.h" +#include + +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* + * If SIZEOF_SIZE_T has not been defined, default to the size of long. + */ + +#ifdef HAVE_LONGLONG +# define LONG_LONG_TYPE long long +# define HAVE_LONG_LONG_TYPE +#else +# if defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define LONG_LONG_TYPE __int64 +# define HAVE_LONG_LONG_TYPE +# else +# undef LONG_LONG_TYPE +# undef HAVE_LONG_LONG_TYPE +# endif +#endif + +/* + * Non-ANSI integer extensions + */ + +#if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x520)) || \ + (defined(__WATCOMC__) && defined(__386__)) || \ + (defined(__POCC__) && defined(_MSC_VER)) || \ + (defined(_WIN32_WCE)) || \ + (defined(__MINGW32__)) || \ + (defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)) +# define MP_HAVE_INT_EXTENSIONS +#endif + +/* + * Max integer data types that mprintf.c is capable + */ + +#ifdef HAVE_LONG_LONG_TYPE +# define mp_intmax_t LONG_LONG_TYPE +# define mp_uintmax_t unsigned LONG_LONG_TYPE +#else +# define mp_intmax_t long +# define mp_uintmax_t unsigned long +#endif + +#define BUFFSIZE 326 /* buffer for long-to-str and float-to-str calcs, should + fit negative DBL_MAX (317 letters) */ +#define MAX_PARAMETERS 128 /* lame static limit */ + +#ifdef __AMIGA__ +# undef FORMAT_INT +#endif + +/* Lower-case digits. */ +static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + +/* Upper-case digits. */ +static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +#define OUTCHAR(x) \ + do{ \ + if(stream((unsigned char)(x), (FILE *)data) != -1) \ + done++; \ + else \ + return done; /* return immediately on failure */ \ + } WHILE_FALSE + +/* Data type to read from the arglist */ +typedef enum { + FORMAT_UNKNOWN = 0, + FORMAT_STRING, + FORMAT_PTR, + FORMAT_INT, + FORMAT_INTPTR, + FORMAT_LONG, + FORMAT_LONGLONG, + FORMAT_DOUBLE, + FORMAT_LONGDOUBLE, + FORMAT_WIDTH /* For internal use */ +} FormatType; + +/* conversion and display flags */ +enum { + FLAGS_NEW = 0, + FLAGS_SPACE = 1<<0, + FLAGS_SHOWSIGN = 1<<1, + FLAGS_LEFT = 1<<2, + FLAGS_ALT = 1<<3, + FLAGS_SHORT = 1<<4, + FLAGS_LONG = 1<<5, + FLAGS_LONGLONG = 1<<6, + FLAGS_LONGDOUBLE = 1<<7, + FLAGS_PAD_NIL = 1<<8, + FLAGS_UNSIGNED = 1<<9, + FLAGS_OCTAL = 1<<10, + FLAGS_HEX = 1<<11, + FLAGS_UPPER = 1<<12, + FLAGS_WIDTH = 1<<13, /* '*' or '*$' used */ + FLAGS_WIDTHPARAM = 1<<14, /* width PARAMETER was specified */ + FLAGS_PREC = 1<<15, /* precision was specified */ + FLAGS_PRECPARAM = 1<<16, /* precision PARAMETER was specified */ + FLAGS_CHAR = 1<<17, /* %c story */ + FLAGS_FLOATE = 1<<18, /* %e or %E */ + FLAGS_FLOATG = 1<<19 /* %g or %G */ +}; + +typedef struct { + FormatType type; + int flags; + long width; /* width OR width parameter number */ + long precision; /* precision OR precision parameter number */ + union { + char *str; + void *ptr; + union { + mp_intmax_t as_signed; + mp_uintmax_t as_unsigned; + } num; + double dnum; + } data; +} va_stack_t; + +struct nsprintf { + char *buffer; + size_t length; + size_t max; +}; + +struct asprintf { + char *buffer; /* allocated buffer */ + size_t len; /* length of string */ + size_t alloc; /* length of alloc */ + int fail; /* (!= 0) if an alloc has failed and thus + the output is not the complete data */ +}; + +static long dprintf_DollarString(char *input, char **end) +{ + int number = 0; + while(ISDIGIT(*input)) { + number *= 10; + number += *input-'0'; + input++; + } + if(number && ('$'==*input++)) { + *end = input; + return number; + } + return 0; +} + +static bool dprintf_IsQualifierNoDollar(const char *fmt) +{ +#if defined(MP_HAVE_INT_EXTENSIONS) + if(!strncmp(fmt, "I32", 3) || !strncmp(fmt, "I64", 3)) { + return TRUE; + } +#endif + + switch(*fmt) { + case '-': case '+': case ' ': case '#': case '.': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case 'h': case 'l': case 'L': case 'z': case 'q': + case '*': case 'O': +#if defined(MP_HAVE_INT_EXTENSIONS) + case 'I': +#endif + return TRUE; + + default: + return FALSE; + } +} + +/****************************************************************** + * + * Pass 1: + * Create an index with the type of each parameter entry and its + * value (may vary in size) + * + * Returns zero on success. + * + ******************************************************************/ + +static int dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos, + va_list arglist) +{ + char *fmt = (char *)format; + int param_num = 0; + long this_param; + long width; + long precision; + int flags; + long max_param = 0; + long i; + + while(*fmt) { + if(*fmt++ == '%') { + if(*fmt == '%') { + fmt++; + continue; /* while */ + } + + flags = FLAGS_NEW; + + /* Handle the positional case (N$) */ + + param_num++; + + this_param = dprintf_DollarString(fmt, &fmt); + if(0 == this_param) + /* we got no positional, get the next counter */ + this_param = param_num; + + if(this_param > max_param) + max_param = this_param; + + /* + * The parameter with number 'i' should be used. Next, we need + * to get SIZE and TYPE of the parameter. Add the information + * to our array. + */ + + width = 0; + precision = 0; + + /* Handle the flags */ + + while(dprintf_IsQualifierNoDollar(fmt)) { +#if defined(MP_HAVE_INT_EXTENSIONS) + if(!strncmp(fmt, "I32", 3)) { + flags |= FLAGS_LONG; + fmt += 3; + } + else if(!strncmp(fmt, "I64", 3)) { + flags |= FLAGS_LONGLONG; + fmt += 3; + } + else +#endif + + switch(*fmt++) { + case ' ': + flags |= FLAGS_SPACE; + break; + case '+': + flags |= FLAGS_SHOWSIGN; + break; + case '-': + flags |= FLAGS_LEFT; + flags &= ~FLAGS_PAD_NIL; + break; + case '#': + flags |= FLAGS_ALT; + break; + case '.': + if('*' == *fmt) { + /* The precision is picked from a specified parameter */ + + flags |= FLAGS_PRECPARAM; + fmt++; + param_num++; + + i = dprintf_DollarString(fmt, &fmt); + if(i) + precision = i; + else + precision = param_num; + + if(precision > max_param) + max_param = precision; + } + else { + flags |= FLAGS_PREC; + precision = strtol(fmt, &fmt, 10); + } + break; + case 'h': + flags |= FLAGS_SHORT; + break; +#if defined(MP_HAVE_INT_EXTENSIONS) + case 'I': +#if (SIZEOF_CURL_OFF_T > SIZEOF_LONG) + flags |= FLAGS_LONGLONG; +#else + flags |= FLAGS_LONG; +#endif + break; +#endif + case 'l': + if(flags & FLAGS_LONG) + flags |= FLAGS_LONGLONG; + else + flags |= FLAGS_LONG; + break; + case 'L': + flags |= FLAGS_LONGDOUBLE; + break; + case 'q': + flags |= FLAGS_LONGLONG; + break; + case 'z': + /* the code below generates a warning if -Wunreachable-code is + used */ +#if (SIZEOF_SIZE_T > SIZEOF_LONG) + flags |= FLAGS_LONGLONG; +#else + flags |= FLAGS_LONG; +#endif + break; + case 'O': +#if (SIZEOF_CURL_OFF_T > SIZEOF_LONG) + flags |= FLAGS_LONGLONG; +#else + flags |= FLAGS_LONG; +#endif + break; + case '0': + if(!(flags & FLAGS_LEFT)) + flags |= FLAGS_PAD_NIL; + /* FALLTHROUGH */ + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + flags |= FLAGS_WIDTH; + width = strtol(fmt-1, &fmt, 10); + break; + case '*': /* Special case */ + flags |= FLAGS_WIDTHPARAM; + param_num++; + + i = dprintf_DollarString(fmt, &fmt); + if(i) + width = i; + else + width = param_num; + if(width > max_param) + max_param = width; + break; + default: + break; + } + } /* switch */ + + /* Handle the specifier */ + + i = this_param - 1; + + if((i < 0) || (i >= MAX_PARAMETERS)) + /* out of allowed range */ + return 1; + + switch (*fmt) { + case 'S': + flags |= FLAGS_ALT; + /* FALLTHROUGH */ + case 's': + vto[i].type = FORMAT_STRING; + break; + case 'n': + vto[i].type = FORMAT_INTPTR; + break; + case 'p': + vto[i].type = FORMAT_PTR; + break; + case 'd': case 'i': + vto[i].type = FORMAT_INT; + break; + case 'u': + vto[i].type = FORMAT_INT; + flags |= FLAGS_UNSIGNED; + break; + case 'o': + vto[i].type = FORMAT_INT; + flags |= FLAGS_OCTAL; + break; + case 'x': + vto[i].type = FORMAT_INT; + flags |= FLAGS_HEX|FLAGS_UNSIGNED; + break; + case 'X': + vto[i].type = FORMAT_INT; + flags |= FLAGS_HEX|FLAGS_UPPER|FLAGS_UNSIGNED; + break; + case 'c': + vto[i].type = FORMAT_INT; + flags |= FLAGS_CHAR; + break; + case 'f': + vto[i].type = FORMAT_DOUBLE; + break; + case 'e': + vto[i].type = FORMAT_DOUBLE; + flags |= FLAGS_FLOATE; + break; + case 'E': + vto[i].type = FORMAT_DOUBLE; + flags |= FLAGS_FLOATE|FLAGS_UPPER; + break; + case 'g': + vto[i].type = FORMAT_DOUBLE; + flags |= FLAGS_FLOATG; + break; + case 'G': + vto[i].type = FORMAT_DOUBLE; + flags |= FLAGS_FLOATG|FLAGS_UPPER; + break; + default: + vto[i].type = FORMAT_UNKNOWN; + break; + } /* switch */ + + vto[i].flags = flags; + vto[i].width = width; + vto[i].precision = precision; + + if(flags & FLAGS_WIDTHPARAM) { + /* we have the width specified from a parameter, so we make that + parameter's info setup properly */ + long k = width - 1; + vto[i].width = k; + vto[k].type = FORMAT_WIDTH; + vto[k].flags = FLAGS_NEW; + /* can't use width or precision of width! */ + vto[k].width = 0; + vto[k].precision = 0; + } + if(flags & FLAGS_PRECPARAM) { + /* we have the precision specified from a parameter, so we make that + parameter's info setup properly */ + long k = precision - 1; + vto[i].precision = k; + vto[k].type = FORMAT_WIDTH; + vto[k].flags = FLAGS_NEW; + /* can't use width or precision of width! */ + vto[k].width = 0; + vto[k].precision = 0; + } + *endpos++ = fmt + 1; /* end of this sequence */ + } + } + + /* Read the arg list parameters into our data list */ + for(i = 0; i$ sequence */ + param = dprintf_DollarString(f, &f); + + if(!param) + param = param_num; + else + --param; + + param_num++; /* increase this always to allow "%2$s %1$s %s" and then the + third %s will pick the 3rd argument */ + + p = &vto[param]; + + /* pick up the specified width */ + if(p->flags & FLAGS_WIDTHPARAM) { + width = (long)vto[p->width].data.num.as_signed; + param_num++; /* since the width is extracted from a parameter, we + must skip that to get to the next one properly */ + if(width < 0) { + /* "A negative field width is taken as a '-' flag followed by a + positive field width." */ + width = -width; + p->flags |= FLAGS_LEFT; + p->flags &= ~FLAGS_PAD_NIL; + } + } + else + width = p->width; + + /* pick up the specified precision */ + if(p->flags & FLAGS_PRECPARAM) { + prec = (long)vto[p->precision].data.num.as_signed; + param_num++; /* since the precision is extracted from a parameter, we + must skip that to get to the next one properly */ + if(prec < 0) + /* "A negative precision is taken as if the precision were + omitted." */ + prec = -1; + } + else if(p->flags & FLAGS_PREC) + prec = p->precision; + else + prec = -1; + + is_alt = (p->flags & FLAGS_ALT) ? 1 : 0; + + switch(p->type) { + case FORMAT_INT: + num = p->data.num.as_unsigned; + if(p->flags & FLAGS_CHAR) { + /* Character. */ + if(!(p->flags & FLAGS_LEFT)) + while(--width > 0) + OUTCHAR(' '); + OUTCHAR((char) num); + if(p->flags & FLAGS_LEFT) + while(--width > 0) + OUTCHAR(' '); + break; + } + if(p->flags & FLAGS_OCTAL) { + /* Octal unsigned integer. */ + base = 8; + goto unsigned_number; + } + else if(p->flags & FLAGS_HEX) { + /* Hexadecimal unsigned integer. */ + + digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits; + base = 16; + goto unsigned_number; + } + else if(p->flags & FLAGS_UNSIGNED) { + /* Decimal unsigned integer. */ + base = 10; + goto unsigned_number; + } + + /* Decimal integer. */ + base = 10; + + is_neg = (p->data.num.as_signed < (mp_intmax_t)0) ? 1 : 0; + if(is_neg) { + /* signed_num might fail to hold absolute negative minimum by 1 */ + signed_num = p->data.num.as_signed + (mp_intmax_t)1; + signed_num = -signed_num; + num = (mp_uintmax_t)signed_num; + num += (mp_uintmax_t)1; + } + + goto number; + + unsigned_number: + /* Unsigned number of base BASE. */ + is_neg = 0; + + number: + /* Number of base BASE. */ + + /* Supply a default precision if none was given. */ + if(prec == -1) + prec = 1; + + /* Put the number in WORK. */ + w = workend; + while(num > 0) { + *w-- = digits[num % base]; + num /= base; + } + width -= (long)(workend - w); + prec -= (long)(workend - w); + + if(is_alt && base == 8 && prec <= 0) { + *w-- = '0'; + --width; + } + + if(prec > 0) { + width -= prec; + while(prec-- > 0) + *w-- = '0'; + } + + if(is_alt && base == 16) + width -= 2; + + if(is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE)) + --width; + + if(!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL)) + while(width-- > 0) + OUTCHAR(' '); + + if(is_neg) + OUTCHAR('-'); + else if(p->flags & FLAGS_SHOWSIGN) + OUTCHAR('+'); + else if(p->flags & FLAGS_SPACE) + OUTCHAR(' '); + + if(is_alt && base == 16) { + OUTCHAR('0'); + if(p->flags & FLAGS_UPPER) + OUTCHAR('X'); + else + OUTCHAR('x'); + } + + if(!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL)) + while(width-- > 0) + OUTCHAR('0'); + + /* Write the number. */ + while(++w <= workend) { + OUTCHAR(*w); + } + + if(p->flags & FLAGS_LEFT) + while(width-- > 0) + OUTCHAR(' '); + break; + + case FORMAT_STRING: + /* String. */ + { + static const char null[] = "(nil)"; + const char *str; + size_t len; + + str = (char *) p->data.str; + if(str == NULL) { + /* Write null[] if there's space. */ + if(prec == -1 || prec >= (long) sizeof(null) - 1) { + str = null; + len = sizeof(null) - 1; + /* Disable quotes around (nil) */ + p->flags &= (~FLAGS_ALT); + } + else { + str = ""; + len = 0; + } + } + else if(prec != -1) + len = (size_t)prec; + else + len = strlen(str); + + width -= (len > LONG_MAX) ? LONG_MAX : (long)len; + + if(p->flags & FLAGS_ALT) + OUTCHAR('"'); + + if(!(p->flags&FLAGS_LEFT)) + while(width-- > 0) + OUTCHAR(' '); + + for(; len && *str; len--) + OUTCHAR(*str++); + if(p->flags&FLAGS_LEFT) + while(width-- > 0) + OUTCHAR(' '); + + if(p->flags & FLAGS_ALT) + OUTCHAR('"'); + } + break; + + case FORMAT_PTR: + /* Generic pointer. */ + { + void *ptr; + ptr = (void *) p->data.ptr; + if(ptr != NULL) { + /* If the pointer is not NULL, write it as a %#x spec. */ + base = 16; + digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits; + is_alt = 1; + num = (size_t) ptr; + is_neg = 0; + goto number; + } + else { + /* Write "(nil)" for a nil pointer. */ + static const char strnil[] = "(nil)"; + const char *point; + + width -= (long)(sizeof(strnil) - 1); + if(p->flags & FLAGS_LEFT) + while(width-- > 0) + OUTCHAR(' '); + for(point = strnil; *point != '\0'; ++point) + OUTCHAR(*point); + if(! (p->flags & FLAGS_LEFT)) + while(width-- > 0) + OUTCHAR(' '); + } + } + break; + + case FORMAT_DOUBLE: + { + char formatbuf[32]="%"; + char *fptr = &formatbuf[1]; + size_t left = sizeof(formatbuf)-strlen(formatbuf); + int len; + + width = -1; + if(p->flags & FLAGS_WIDTH) + width = p->width; + else if(p->flags & FLAGS_WIDTHPARAM) + width = (long)vto[p->width].data.num.as_signed; + + prec = -1; + if(p->flags & FLAGS_PREC) + prec = p->precision; + else if(p->flags & FLAGS_PRECPARAM) + prec = (long)vto[p->precision].data.num.as_signed; + + if(p->flags & FLAGS_LEFT) + *fptr++ = '-'; + if(p->flags & FLAGS_SHOWSIGN) + *fptr++ = '+'; + if(p->flags & FLAGS_SPACE) + *fptr++ = ' '; + if(p->flags & FLAGS_ALT) + *fptr++ = '#'; + + *fptr = 0; + + if(width >= 0) { + if(width >= (long)sizeof(work)) + width = sizeof(work)-1; + /* RECURSIVE USAGE */ + len = curl_msnprintf(fptr, left, "%ld", width); + fptr += len; + left -= len; + } + if(prec >= 0) { + /* for each digit in the integer part, we can have one less + precision */ + size_t maxprec = sizeof(work) - 2; + double val = p->data.dnum; + while(val >= 10.0) { + val /= 10; + maxprec--; + } + + if(prec > (long)maxprec) + prec = (long)maxprec-1; + /* RECURSIVE USAGE */ + len = curl_msnprintf(fptr, left, ".%ld", prec); + fptr += len; + } + if(p->flags & FLAGS_LONG) + *fptr++ = 'l'; + + if(p->flags & FLAGS_FLOATE) + *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'E':'e'); + else if(p->flags & FLAGS_FLOATG) + *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'G' : 'g'); + else + *fptr++ = 'f'; + + *fptr = 0; /* and a final zero termination */ + + /* NOTE NOTE NOTE!! Not all sprintf implementations return number of + output characters */ + (sprintf)(work, formatbuf, p->data.dnum); + DEBUGASSERT(strlen(work) <= sizeof(work)); + for(fptr = work; *fptr; fptr++) + OUTCHAR(*fptr); + } + break; + + case FORMAT_INTPTR: + /* Answer the count of characters written. */ +#ifdef HAVE_LONG_LONG_TYPE + if(p->flags & FLAGS_LONGLONG) + *(LONG_LONG_TYPE *) p->data.ptr = (LONG_LONG_TYPE)done; + else +#endif + if(p->flags & FLAGS_LONG) + *(long *) p->data.ptr = (long)done; + else if(!(p->flags & FLAGS_SHORT)) + *(int *) p->data.ptr = (int)done; + else + *(short *) p->data.ptr = (short)done; + break; + + default: + break; + } + f = *end++; /* goto end of %-code */ + + } + return done; +} + +/* fputc() look-alike */ +static int addbyter(int output, FILE *data) +{ + struct nsprintf *infop = (struct nsprintf *)data; + unsigned char outc = (unsigned char)output; + + if(infop->length < infop->max) { + /* only do this if we haven't reached max length yet */ + infop->buffer[0] = outc; /* store */ + infop->buffer++; /* increase pointer */ + infop->length++; /* we are now one byte larger */ + return outc; /* fputc() returns like this on success */ + } + return -1; +} + +int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format, + va_list ap_save) +{ + int retcode; + struct nsprintf info; + + info.buffer = buffer; + info.length = 0; + info.max = maxlength; + + retcode = dprintf_formatf(&info, addbyter, format, ap_save); + if((retcode != -1) && info.max) { + /* we terminate this with a zero byte */ + if(info.max == info.length) + /* we're at maximum, scrap the last letter */ + info.buffer[-1] = 0; + else + info.buffer[0] = 0; + } + return retcode; +} + +int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...) +{ + int retcode; + va_list ap_save; /* argument pointer */ + va_start(ap_save, format); + retcode = curl_mvsnprintf(buffer, maxlength, format, ap_save); + va_end(ap_save); + return retcode; +} + +/* fputc() look-alike */ +static int alloc_addbyter(int output, FILE *data) +{ + struct asprintf *infop = (struct asprintf *)data; + unsigned char outc = (unsigned char)output; + + if(!infop->buffer) { + infop->buffer = malloc(32); + if(!infop->buffer) { + infop->fail = 1; + return -1; /* fail */ + } + infop->alloc = 32; + infop->len = 0; + } + else if(infop->len + 1 >= infop->alloc) { + char *newptr = NULL; + size_t newsize = infop->alloc*2; + + /* detect wrap-around or other overflow problems */ + if(newsize > infop->alloc) + newptr = realloc(infop->buffer, newsize); + + if(!newptr) { + infop->fail = 1; + return -1; /* fail */ + } + infop->buffer = newptr; + infop->alloc = newsize; + } + + infop->buffer[ infop->len ] = outc; + + infop->len++; + + return outc; /* fputc() returns like this on success */ +} + +char *curl_maprintf(const char *format, ...) +{ + va_list ap_save; /* argument pointer */ + int retcode; + struct asprintf info; + + info.buffer = NULL; + info.len = 0; + info.alloc = 0; + info.fail = 0; + + va_start(ap_save, format); + retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); + va_end(ap_save); + if((-1 == retcode) || info.fail) { + if(info.alloc) + free(info.buffer); + return NULL; + } + if(info.alloc) { + info.buffer[info.len] = 0; /* we terminate this with a zero byte */ + return info.buffer; + } + return strdup(""); +} + +char *curl_mvaprintf(const char *format, va_list ap_save) +{ + int retcode; + struct asprintf info; + + info.buffer = NULL; + info.len = 0; + info.alloc = 0; + info.fail = 0; + + retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); + if((-1 == retcode) || info.fail) { + if(info.alloc) + free(info.buffer); + return NULL; + } + + if(info.alloc) { + info.buffer[info.len] = 0; /* we terminate this with a zero byte */ + return info.buffer; + } + return strdup(""); +} + +static int storebuffer(int output, FILE *data) +{ + char **buffer = (char **)data; + unsigned char outc = (unsigned char)output; + **buffer = outc; + (*buffer)++; + return outc; /* act like fputc() ! */ +} + +int curl_msprintf(char *buffer, const char *format, ...) +{ + va_list ap_save; /* argument pointer */ + int retcode; + va_start(ap_save, format); + retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save); + va_end(ap_save); + *buffer = 0; /* we terminate this with a zero byte */ + return retcode; +} + +int curl_mprintf(const char *format, ...) +{ + int retcode; + va_list ap_save; /* argument pointer */ + va_start(ap_save, format); + + retcode = dprintf_formatf(stdout, fputc, format, ap_save); + va_end(ap_save); + return retcode; +} + +int curl_mfprintf(FILE *whereto, const char *format, ...) +{ + int retcode; + va_list ap_save; /* argument pointer */ + va_start(ap_save, format); + retcode = dprintf_formatf(whereto, fputc, format, ap_save); + va_end(ap_save); + return retcode; +} + +int curl_mvsprintf(char *buffer, const char *format, va_list ap_save) +{ + int retcode; + retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save); + *buffer = 0; /* we terminate this with a zero byte */ + return retcode; +} + +int curl_mvprintf(const char *format, va_list ap_save) +{ + return dprintf_formatf(stdout, fputc, format, ap_save); +} + +int curl_mvfprintf(FILE *whereto, const char *format, va_list ap_save) +{ + return dprintf_formatf(whereto, fputc, format, ap_save); +} diff --git a/libcurl/lib/multi.c b/libcurl/lib/multi.c new file mode 100644 index 0000000..2b6b1bc --- /dev/null +++ b/libcurl/lib/multi.c @@ -0,0 +1,3076 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "urldata.h" +#include "transfer.h" +#include "url.h" +#include "connect.h" +#include "progress.h" +#include "easyif.h" +#include "share.h" +#include "psl.h" +#include "multiif.h" +#include "sendf.h" +#include "timeval.h" +#include "http.h" +#include "select.h" +#include "warnless.h" +#include "speedcheck.h" +#include "conncache.h" +#include "multihandle.h" +#include "sigpipe.h" +#include "vtls/vtls.h" +#include "connect.h" +#include "http_proxy.h" +#include "http2.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* + CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97 + to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every + CURL handle takes 45-50 K memory, therefore this 3K are not significant. +*/ +#ifndef CURL_SOCKET_HASH_TABLE_SIZE +#define CURL_SOCKET_HASH_TABLE_SIZE 911 +#endif + +#ifndef CURL_CONNECTION_HASH_SIZE +#define CURL_CONNECTION_HASH_SIZE 97 +#endif + +#define CURL_MULTI_HANDLE 0x000bab1e + +#define GOOD_MULTI_HANDLE(x) \ + ((x) && (x)->type == CURL_MULTI_HANDLE) + +static CURLMcode singlesocket(struct Curl_multi *multi, + struct Curl_easy *data); +static CURLMcode add_next_timeout(struct curltime now, + struct Curl_multi *multi, + struct Curl_easy *d); +static CURLMcode multi_timeout(struct Curl_multi *multi, + long *timeout_ms); +static void process_pending_handles(struct Curl_multi *multi); +static void detach_connnection(struct Curl_easy *data); + +#ifdef DEBUGBUILD +static const char * const statename[]={ + "INIT", + "CONNECT_PEND", + "CONNECT", + "WAITRESOLVE", + "WAITCONNECT", + "WAITPROXYCONNECT", + "SENDPROTOCONNECT", + "PROTOCONNECT", + "DO", + "DOING", + "DO_MORE", + "DO_DONE", + "PERFORM", + "TOOFAST", + "DONE", + "COMPLETED", + "MSGSENT", +}; +#endif + +/* function pointer called once when switching TO a state */ +typedef void (*init_multistate_func)(struct Curl_easy *data); + +static void Curl_init_completed(struct Curl_easy *data) +{ + /* this is a completed transfer */ + + /* Important: reset the conn pointer so that we don't point to memory + that could be freed anytime */ + detach_connnection(data); + Curl_expire_clear(data); /* stop all timers */ +} + +/* always use this function to change state, to make debugging easier */ +static void mstate(struct Curl_easy *data, CURLMstate state +#ifdef DEBUGBUILD + , int lineno +#endif +) +{ + CURLMstate oldstate = data->mstate; + static const init_multistate_func finit[CURLM_STATE_LAST] = { + NULL, /* INIT */ + NULL, /* CONNECT_PEND */ + Curl_init_CONNECT, /* CONNECT */ + NULL, /* WAITRESOLVE */ + NULL, /* WAITCONNECT */ + NULL, /* WAITPROXYCONNECT */ + NULL, /* SENDPROTOCONNECT */ + NULL, /* PROTOCONNECT */ + Curl_connect_free, /* DO */ + NULL, /* DOING */ + NULL, /* DO_MORE */ + NULL, /* DO_DONE */ + NULL, /* PERFORM */ + NULL, /* TOOFAST */ + NULL, /* DONE */ + Curl_init_completed, /* COMPLETED */ + NULL /* MSGSENT */ + }; + +#if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS) + (void) lineno; +#endif + + if(oldstate == state) + /* don't bother when the new state is the same as the old state */ + return; + + data->mstate = state; + +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + if(data->mstate >= CURLM_STATE_CONNECT_PEND && + data->mstate < CURLM_STATE_COMPLETED) { + long connection_id = -5000; + + if(data->conn) + connection_id = data->conn->connection_id; + + infof(data, + "STATE: %s => %s handle %p; line %d (connection #%ld)\n", + statename[oldstate], statename[data->mstate], + (void *)data, lineno, connection_id); + } +#endif + + if(state == CURLM_STATE_COMPLETED) + /* changing to COMPLETED means there's one less easy handle 'alive' */ + data->multi->num_alive--; + + /* if this state has an init-function, run it */ + if(finit[state]) + finit[state](data); +} + +#ifndef DEBUGBUILD +#define multistate(x,y) mstate(x,y) +#else +#define multistate(x,y) mstate(x,y, __LINE__) +#endif + +/* + * We add one of these structs to the sockhash for each socket + */ + +struct Curl_sh_entry { + struct curl_hash transfers; /* hash of transfers using this socket */ + unsigned int action; /* what combined action READ/WRITE this socket waits + for */ + void *socketp; /* settable by users with curl_multi_assign() */ + unsigned int users; /* number of transfers using this */ + unsigned int readers; /* this many transfers want to read */ + unsigned int writers; /* this many transfers want to write */ +}; +/* bits for 'action' having no bits means this socket is not expecting any + action */ +#define SH_READ 1 +#define SH_WRITE 2 + +/* look up a given socket in the socket hash, skip invalid sockets */ +static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh, + curl_socket_t s) +{ + if(s != CURL_SOCKET_BAD) { + /* only look for proper sockets */ + return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t)); + } + return NULL; +} + +#define TRHASH_SIZE 13 +static size_t trhash(void *key, size_t key_length, size_t slots_num) +{ + size_t keyval = (size_t)*(struct Curl_easy **)key; + (void) key_length; + + return (keyval % slots_num); +} + +static size_t trhash_compare(void *k1, size_t k1_len, void *k2, size_t k2_len) +{ + (void)k1_len; + (void)k2_len; + + return *(struct Curl_easy **)k1 == *(struct Curl_easy **)k2; +} + +static void trhash_dtor(void *nada) +{ + (void)nada; +} + + +/* make sure this socket is present in the hash for this handle */ +static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh, + curl_socket_t s) +{ + struct Curl_sh_entry *there = sh_getentry(sh, s); + struct Curl_sh_entry *check; + + if(there) { + /* it is present, return fine */ + return there; + } + + /* not present, add it */ + check = calloc(1, sizeof(struct Curl_sh_entry)); + if(!check) + return NULL; /* major failure */ + + if(Curl_hash_init(&check->transfers, TRHASH_SIZE, trhash, + trhash_compare, trhash_dtor)) { + free(check); + return NULL; + } + + /* make/add new hash entry */ + if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) { + free(check); + return NULL; /* major failure */ + } + + return check; /* things are good in sockhash land */ +} + + +/* delete the given socket + handle from the hash */ +static void sh_delentry(struct Curl_sh_entry *entry, + struct curl_hash *sh, curl_socket_t s) +{ + Curl_hash_destroy(&entry->transfers); + + /* We remove the hash entry. This will end up in a call to + sh_freeentry(). */ + Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t)); +} + +/* + * free a sockhash entry + */ +static void sh_freeentry(void *freethis) +{ + struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis; + + free(p); +} + +static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len) +{ + (void) k1_len; (void) k2_len; + + return (*((curl_socket_t *) k1)) == (*((curl_socket_t *) k2)); +} + +static size_t hash_fd(void *key, size_t key_length, size_t slots_num) +{ + curl_socket_t fd = *((curl_socket_t *) key); + (void) key_length; + + return (fd % slots_num); +} + +/* + * sh_init() creates a new socket hash and returns the handle for it. + * + * Quote from README.multi_socket: + * + * "Some tests at 7000 and 9000 connections showed that the socket hash lookup + * is somewhat of a bottle neck. Its current implementation may be a bit too + * limiting. It simply has a fixed-size array, and on each entry in the array + * it has a linked list with entries. So the hash only checks which list to + * scan through. The code I had used so for used a list with merely 7 slots + * (as that is what the DNS hash uses) but with 7000 connections that would + * make an average of 1000 nodes in each list to run through. I upped that to + * 97 slots (I believe a prime is suitable) and noticed a significant speed + * increase. I need to reconsider the hash implementation or use a rather + * large default value like this. At 9000 connections I was still below 10us + * per call." + * + */ +static int sh_init(struct curl_hash *hash, int hashsize) +{ + return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare, + sh_freeentry); +} + +/* + * multi_addmsg() + * + * Called when a transfer is completed. Adds the given msg pointer to + * the list kept in the multi handle. + */ +static CURLMcode multi_addmsg(struct Curl_multi *multi, + struct Curl_message *msg) +{ + Curl_llist_insert_next(&multi->msglist, multi->msglist.tail, msg, + &msg->list); + return CURLM_OK; +} + +struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ + int chashsize) /* connection hash */ +{ + struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi)); + + if(!multi) + return NULL; + + multi->type = CURL_MULTI_HANDLE; + + if(Curl_mk_dnscache(&multi->hostcache)) + goto error; + + if(sh_init(&multi->sockhash, hashsize)) + goto error; + + if(Curl_conncache_init(&multi->conn_cache, chashsize)) + goto error; + + Curl_llist_init(&multi->msglist, NULL); + Curl_llist_init(&multi->pending, NULL); + + multi->multiplexing = CURLPIPE_MULTIPLEX; + + /* -1 means it not set by user, use the default value */ + multi->maxconnects = -1; + return multi; + + error: + + Curl_hash_destroy(&multi->sockhash); + Curl_hash_destroy(&multi->hostcache); + Curl_conncache_destroy(&multi->conn_cache); + Curl_llist_destroy(&multi->msglist, NULL); + Curl_llist_destroy(&multi->pending, NULL); + + free(multi); + return NULL; +} + +struct Curl_multi *curl_multi_init(void) +{ + return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE, + CURL_CONNECTION_HASH_SIZE); +} + +CURLMcode curl_multi_add_handle(struct Curl_multi *multi, + struct Curl_easy *data) +{ + /* First, make some basic checks that the CURLM handle is a good handle */ + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + /* Verify that we got a somewhat good easy handle too */ + if(!GOOD_EASY_HANDLE(data)) + return CURLM_BAD_EASY_HANDLE; + + /* Prevent users from adding same easy handle more than once and prevent + adding to more than one multi stack */ + if(data->multi) + return CURLM_ADDED_ALREADY; + + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + + /* Initialize timeout list for this handle */ + Curl_llist_init(&data->state.timeoutlist, NULL); + + /* + * No failure allowed in this function beyond this point. And no + * modification of easy nor multi handle allowed before this except for + * potential multi's connection cache growing which won't be undone in this + * function no matter what. + */ + if(data->set.errorbuffer) + data->set.errorbuffer[0] = 0; + + /* set the easy handle */ + multistate(data, CURLM_STATE_INIT); + + /* for multi interface connections, we share DNS cache automatically if the + easy handle's one is currently not set. */ + if(!data->dns.hostcache || + (data->dns.hostcachetype == HCACHE_NONE)) { + data->dns.hostcache = &multi->hostcache; + data->dns.hostcachetype = HCACHE_MULTI; + } + + /* Point to the shared or multi handle connection cache */ + if(data->share && (data->share->specifier & (1<< CURL_LOCK_DATA_CONNECT))) + data->state.conn_cache = &data->share->conn_cache; + else + data->state.conn_cache = &multi->conn_cache; + +#ifdef USE_LIBPSL + /* Do the same for PSL. */ + if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL))) + data->psl = &data->share->psl; + else + data->psl = &multi->psl; +#endif + + /* We add the new entry last in the list. */ + data->next = NULL; /* end of the line */ + if(multi->easyp) { + struct Curl_easy *last = multi->easylp; + last->next = data; + data->prev = last; + multi->easylp = data; /* the new last node */ + } + else { + /* first node, make prev NULL! */ + data->prev = NULL; + multi->easylp = multi->easyp = data; /* both first and last */ + } + + /* make the Curl_easy refer back to this multi handle */ + data->multi = multi; + + /* Set the timeout for this handle to expire really soon so that it will + be taken care of even when this handle is added in the midst of operation + when only the curl_multi_socket() API is used. During that flow, only + sockets that time-out or have actions will be dealt with. Since this + handle has no action yet, we make sure it times out to get things to + happen. */ + Curl_expire(data, 0, EXPIRE_RUN_NOW); + + /* increase the node-counter */ + multi->num_easy++; + + /* increase the alive-counter */ + multi->num_alive++; + + /* A somewhat crude work-around for a little glitch in Curl_update_timer() + that happens if the lastcall time is set to the same time when the handle + is removed as when the next handle is added, as then the check in + Curl_update_timer() that prevents calling the application multiple times + with the same timer info will not trigger and then the new handle's + timeout will not be notified to the app. + + The work-around is thus simply to clear the 'lastcall' variable to force + Curl_update_timer() to always trigger a callback to the app when a new + easy handle is added */ + memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); + + /* The closure handle only ever has default timeouts set. To improve the + state somewhat we clone the timeouts from each added handle so that the + closure handle always has the same timeouts as the most recently added + easy handle. */ + data->state.conn_cache->closure_handle->set.timeout = data->set.timeout; + data->state.conn_cache->closure_handle->set.server_response_timeout = + data->set.server_response_timeout; + data->state.conn_cache->closure_handle->set.no_signal = + data->set.no_signal; + + Curl_update_timer(multi); + return CURLM_OK; +} + +#if 0 +/* Debug-function, used like this: + * + * Curl_hash_print(multi->sockhash, debug_print_sock_hash); + * + * Enable the hash print function first by editing hash.c + */ +static void debug_print_sock_hash(void *p) +{ + struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p; + + fprintf(stderr, " [easy %p/magic %x/socket %d]", + (void *)sh->data, sh->data->magic, (int)sh->socket); +} +#endif + +static CURLcode multi_done(struct Curl_easy *data, + CURLcode status, /* an error if this is called + after an error was detected */ + bool premature) +{ + CURLcode result; + struct connectdata *conn = data->conn; + unsigned int i; + + DEBUGF(infof(data, "multi_done\n")); + + if(data->state.done) + /* Stop if multi_done() has already been called */ + return CURLE_OK; + + /* Stop the resolver and free its own resources (but not dns_entry yet). */ + Curl_resolver_kill(conn); + + /* Cleanup possible redirect junk */ + Curl_safefree(data->req.newurl); + Curl_safefree(data->req.location); + + switch(status) { + case CURLE_ABORTED_BY_CALLBACK: + case CURLE_READ_ERROR: + case CURLE_WRITE_ERROR: + /* When we're aborted due to a callback return code it basically have to + be counted as premature as there is trouble ahead if we don't. We have + many callbacks and protocols work differently, we could potentially do + this more fine-grained in the future. */ + premature = TRUE; + default: + break; + } + + /* this calls the protocol-specific function pointer previously set */ + if(conn->handler->done) + result = conn->handler->done(conn, status, premature); + else + result = status; + + if(CURLE_ABORTED_BY_CALLBACK != result) { + /* avoid this if we already aborted by callback to avoid this calling + another callback */ + CURLcode rc = Curl_pgrsDone(conn); + if(!result && rc) + result = CURLE_ABORTED_BY_CALLBACK; + } + + process_pending_handles(data->multi); /* connection / multiplex */ + + detach_connnection(data); + if(CONN_INUSE(conn)) { + /* Stop if still used. */ + DEBUGF(infof(data, "Connection still in use %zu, " + "no more multi_done now!\n", + conn->easyq.size)); + return CURLE_OK; + } + + data->state.done = TRUE; /* called just now! */ + + if(conn->dns_entry) { + Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ + conn->dns_entry = NULL; + } + Curl_hostcache_prune(data); + Curl_safefree(data->state.ulbuf); + + /* if the transfer was completed in a paused state there can be buffered + data left to free */ + for(i = 0; i < data->state.tempcount; i++) { + free(data->state.tempwrite[i].buf); + } + data->state.tempcount = 0; + + /* if data->set.reuse_forbid is TRUE, it means the libcurl client has + forced us to close this connection. This is ignored for requests taking + place in a NTLM/NEGOTIATE authentication handshake + + if conn->bits.close is TRUE, it means that the connection should be + closed in spite of all our efforts to be nice, due to protocol + restrictions in our or the server's end + + if premature is TRUE, it means this connection was said to be DONE before + the entire request operation is complete and thus we can't know in what + state it is for re-using, so we're forced to close it. In a perfect world + we can add code that keep track of if we really must close it here or not, + but currently we have no such detail knowledge. + */ + + if((data->set.reuse_forbid +#if defined(USE_NTLM) + && !(conn->http_ntlm_state == NTLMSTATE_TYPE2 || + conn->proxy_ntlm_state == NTLMSTATE_TYPE2) +#endif +#if defined(USE_SPNEGO) + && !(conn->http_negotiate_state == GSS_AUTHRECV || + conn->proxy_negotiate_state == GSS_AUTHRECV) +#endif + ) || conn->bits.close + || (premature && !(conn->handler->flags & PROTOPT_STREAM))) { + CURLcode res2 = Curl_disconnect(data, conn, premature); + + /* If we had an error already, make sure we return that one. But + if we got a new error, return that. */ + if(!result && res2) + result = res2; + } + else { + char buffer[256]; + /* create string before returning the connection */ + msnprintf(buffer, sizeof(buffer), + "Connection #%ld to host %s left intact", + conn->connection_id, + conn->bits.socksproxy ? conn->socks_proxy.host.dispname : + conn->bits.httpproxy ? conn->http_proxy.host.dispname : + conn->bits.conn_to_host ? conn->conn_to_host.dispname : + conn->host.dispname); + + /* the connection is no longer in use by this transfer */ + if(Curl_conncache_return_conn(conn)) { + /* remember the most recently used connection */ + data->state.lastconnect = conn; + infof(data, "%s\n", buffer); + } + else + data->state.lastconnect = NULL; + } + + Curl_free_request_state(data); + return result; +} + +CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, + struct Curl_easy *data) +{ + struct Curl_easy *easy = data; + bool premature; + bool easy_owns_conn; + struct curl_llist_element *e; + + /* First, make some basic checks that the CURLM handle is a good handle */ + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + /* Verify that we got a somewhat good easy handle too */ + if(!GOOD_EASY_HANDLE(data)) + return CURLM_BAD_EASY_HANDLE; + + /* Prevent users from trying to remove same easy handle more than once */ + if(!data->multi) + return CURLM_OK; /* it is already removed so let's say it is fine! */ + + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + + premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE; + easy_owns_conn = (data->conn && (data->conn->data == easy)) ? + TRUE : FALSE; + + /* If the 'state' is not INIT or COMPLETED, we might need to do something + nice to put the easy_handle in a good known state when this returns. */ + if(premature) { + /* this handle is "alive" so we need to count down the total number of + alive connections when this is removed */ + multi->num_alive--; + } + + if(data->conn && + data->mstate > CURLM_STATE_DO && + data->mstate < CURLM_STATE_COMPLETED) { + /* Set connection owner so that the DONE function closes it. We can + safely do this here since connection is killed. */ + data->conn->data = easy; + streamclose(data->conn, "Removed with partial response"); + easy_owns_conn = TRUE; + } + + /* The timer must be shut down before data->multi is set to NULL, + else the timenode will remain in the splay tree after + curl_easy_cleanup is called. */ + Curl_expire_clear(data); + + if(data->conn) { + + /* we must call multi_done() here (if we still own the connection) so that + we don't leave a half-baked one around */ + if(easy_owns_conn) { + + /* multi_done() clears the conn->data field to lose the association + between the easy handle and the connection + + Note that this ignores the return code simply because there's + nothing really useful to do with it anyway! */ + (void)multi_done(data, data->result, premature); + } + } + + if(data->connect_queue.ptr) + /* the handle was in the pending list waiting for an available connection, + so go ahead and remove it */ + Curl_llist_remove(&multi->pending, &data->connect_queue, NULL); + + if(data->dns.hostcachetype == HCACHE_MULTI) { + /* stop using the multi handle's DNS cache, *after* the possible + multi_done() call above */ + data->dns.hostcache = NULL; + data->dns.hostcachetype = HCACHE_NONE; + } + + Curl_wildcard_dtor(&data->wildcard); + + /* destroy the timeout list that is held in the easy handle, do this *after* + multi_done() as that may actually call Curl_expire that uses this */ + Curl_llist_destroy(&data->state.timeoutlist, NULL); + + /* as this was using a shared connection cache we clear the pointer to that + since we're not part of that multi handle anymore */ + data->state.conn_cache = NULL; + + /* change state without using multistate(), only to make singlesocket() do + what we want */ + data->mstate = CURLM_STATE_COMPLETED; + singlesocket(multi, easy); /* to let the application know what sockets that + vanish with this handle */ + + /* Remove the association between the connection and the handle */ + if(data->conn) { + data->conn->data = NULL; + detach_connnection(data); + } + +#ifdef USE_LIBPSL + /* Remove the PSL association. */ + if(data->psl == &multi->psl) + data->psl = NULL; +#endif + + data->multi = NULL; /* clear the association to this multi handle */ + + /* make sure there's no pending message in the queue sent from this easy + handle */ + + for(e = multi->msglist.head; e; e = e->next) { + struct Curl_message *msg = e->ptr; + + if(msg->extmsg.easy_handle == easy) { + Curl_llist_remove(&multi->msglist, e, NULL); + /* there can only be one from this specific handle */ + break; + } + } + + /* make the previous node point to our next */ + if(data->prev) + data->prev->next = data->next; + else + multi->easyp = data->next; /* point to first node */ + + /* make our next point to our previous node */ + if(data->next) + data->next->prev = data->prev; + else + multi->easylp = data->prev; /* point to last node */ + + /* NOTE NOTE NOTE + We do not touch the easy handle here! */ + multi->num_easy--; /* one less to care about now */ + + Curl_update_timer(multi); + return CURLM_OK; +} + +/* Return TRUE if the application asked for multiplexing */ +bool Curl_multiplex_wanted(const struct Curl_multi *multi) +{ + return (multi && (multi->multiplexing)); +} + +/* This is the only function that should clear data->conn. This will + occasionally be called with the pointer already cleared. */ +static void detach_connnection(struct Curl_easy *data) +{ + struct connectdata *conn = data->conn; + if(conn) + Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL); + data->conn = NULL; +} + +/* This is the only function that should assign data->conn */ +void Curl_attach_connnection(struct Curl_easy *data, + struct connectdata *conn) +{ + DEBUGASSERT(!data->conn); + DEBUGASSERT(conn); + data->conn = conn; + Curl_llist_insert_next(&conn->easyq, conn->easyq.tail, data, + &data->conn_queue); +} + +static int waitconnect_getsock(struct connectdata *conn, + curl_socket_t *sock, + int numsocks) +{ + int i; + int s = 0; + int rc = 0; + + if(!numsocks) + return GETSOCK_BLANK; + +#ifdef USE_SSL + if(CONNECT_FIRSTSOCKET_PROXY_SSL()) + return Curl_ssl_getsock(conn, sock, numsocks); +#endif + + for(i = 0; i<2; i++) { + if(conn->tempsock[i] != CURL_SOCKET_BAD) { + sock[s] = conn->tempsock[i]; + rc |= GETSOCK_WRITESOCK(s++); + } + } + + return rc; +} + +static int waitproxyconnect_getsock(struct connectdata *conn, + curl_socket_t *sock, + int numsocks) +{ + if(!numsocks) + return GETSOCK_BLANK; + + sock[0] = conn->sock[FIRSTSOCKET]; + + /* when we've sent a CONNECT to a proxy, we should rather wait for the + socket to become readable to be able to get the response headers */ + if(conn->connect_state) + return GETSOCK_READSOCK(0); + + return GETSOCK_WRITESOCK(0); +} + +static int domore_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) +{ + if(conn && conn->handler->domore_getsock) + return conn->handler->domore_getsock(conn, socks, numsocks); + return GETSOCK_BLANK; +} + +/* returns bitmapped flags for this handle and its sockets */ +static int multi_getsock(struct Curl_easy *data, + curl_socket_t *socks, /* points to numsocks number + of sockets */ + int numsocks) +{ + /* The no connection case can happen when this is called from + curl_multi_remove_handle() => singlesocket() => multi_getsock(). + */ + if(!data->conn) + return 0; + + if(data->mstate > CURLM_STATE_CONNECT && + data->mstate < CURLM_STATE_COMPLETED) { + /* Set up ownership correctly */ + data->conn->data = data; + } + + switch(data->mstate) { + default: +#if 0 /* switch back on these cases to get the compiler to check for all enums + to be present */ + case CURLM_STATE_TOOFAST: /* returns 0, so will not select. */ + case CURLM_STATE_COMPLETED: + case CURLM_STATE_MSGSENT: + case CURLM_STATE_INIT: + case CURLM_STATE_CONNECT: + case CURLM_STATE_WAITDO: + case CURLM_STATE_DONE: + case CURLM_STATE_LAST: + /* this will get called with CURLM_STATE_COMPLETED when a handle is + removed */ +#endif + return 0; + + case CURLM_STATE_WAITRESOLVE: + return Curl_resolv_getsock(data->conn, socks, numsocks); + + case CURLM_STATE_PROTOCONNECT: + case CURLM_STATE_SENDPROTOCONNECT: + return Curl_protocol_getsock(data->conn, socks, numsocks); + + case CURLM_STATE_DO: + case CURLM_STATE_DOING: + return Curl_doing_getsock(data->conn, socks, numsocks); + + case CURLM_STATE_WAITPROXYCONNECT: + return waitproxyconnect_getsock(data->conn, socks, numsocks); + + case CURLM_STATE_WAITCONNECT: + return waitconnect_getsock(data->conn, socks, numsocks); + + case CURLM_STATE_DO_MORE: + return domore_getsock(data->conn, socks, numsocks); + + case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch + to waiting for the same as the *PERFORM + states */ + case CURLM_STATE_PERFORM: + return Curl_single_getsock(data->conn, socks, numsocks); + } + +} + +CURLMcode curl_multi_fdset(struct Curl_multi *multi, + fd_set *read_fd_set, fd_set *write_fd_set, + fd_set *exc_fd_set, int *max_fd) +{ + /* Scan through all the easy handles to get the file descriptors set. + Some easy handles may not have connected to the remote host yet, + and then we must make sure that is done. */ + struct Curl_easy *data; + int this_max_fd = -1; + curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; + int i; + (void)exc_fd_set; /* not used */ + + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + + data = multi->easyp; + while(data) { + int bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE); + + for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) { + curl_socket_t s = CURL_SOCKET_BAD; + + if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) { + FD_SET(sockbunch[i], read_fd_set); + s = sockbunch[i]; + } + if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) { + FD_SET(sockbunch[i], write_fd_set); + s = sockbunch[i]; + } + if(s == CURL_SOCKET_BAD) + /* this socket is unused, break out of loop */ + break; + if((int)s > this_max_fd) + this_max_fd = (int)s; + } + + data = data->next; /* check next handle */ + } + + *max_fd = this_max_fd; + + return CURLM_OK; +} + +#define NUM_POLLS_ON_STACK 10 + +CURLMcode Curl_multi_wait(struct Curl_multi *multi, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret, + bool *gotsocket) /* if any socket was checked */ +{ + struct Curl_easy *data; + curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; + int bitmap; + unsigned int i; + unsigned int nfds = 0; + unsigned int curlfds; + bool ufds_malloc = FALSE; + long timeout_internal; + int retcode = 0; + struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; + struct pollfd *ufds = &a_few_on_stack[0]; + + if(gotsocket) + *gotsocket = FALSE; + + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + + /* Count up how many fds we have from the multi handle */ + data = multi->easyp; + while(data) { + bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE); + + for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) { + curl_socket_t s = CURL_SOCKET_BAD; + + if(bitmap & GETSOCK_READSOCK(i)) { + ++nfds; + s = sockbunch[i]; + } + if(bitmap & GETSOCK_WRITESOCK(i)) { + ++nfds; + s = sockbunch[i]; + } + if(s == CURL_SOCKET_BAD) { + break; + } + } + + data = data->next; /* check next handle */ + } + + /* If the internally desired timeout is actually shorter than requested from + the outside, then use the shorter time! But only if the internal timer + is actually larger than -1! */ + (void)multi_timeout(multi, &timeout_internal); + if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms)) + timeout_ms = (int)timeout_internal; + + curlfds = nfds; /* number of internal file descriptors */ + nfds += extra_nfds; /* add the externally provided ones */ + + if(nfds > NUM_POLLS_ON_STACK) { + /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes + big, so at 2^29 sockets this value might wrap. When a process gets + the capability to actually handle over 500 million sockets this + calculation needs a integer overflow check. */ + ufds = malloc(nfds * sizeof(struct pollfd)); + if(!ufds) + return CURLM_OUT_OF_MEMORY; + ufds_malloc = TRUE; + } + nfds = 0; + + /* only do the second loop if we found descriptors in the first stage run + above */ + + if(curlfds) { + /* Add the curl handles to our pollfds first */ + data = multi->easyp; + while(data) { + bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE); + + for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) { + curl_socket_t s = CURL_SOCKET_BAD; + + if(bitmap & GETSOCK_READSOCK(i)) { + ufds[nfds].fd = sockbunch[i]; + ufds[nfds].events = POLLIN; + ++nfds; + s = sockbunch[i]; + } + if(bitmap & GETSOCK_WRITESOCK(i)) { + ufds[nfds].fd = sockbunch[i]; + ufds[nfds].events = POLLOUT; + ++nfds; + s = sockbunch[i]; + } + if(s == CURL_SOCKET_BAD) { + break; + } + } + + data = data->next; /* check next handle */ + } + } + + /* Add external file descriptions from poll-like struct curl_waitfd */ + for(i = 0; i < extra_nfds; i++) { + ufds[nfds].fd = extra_fds[i].fd; + ufds[nfds].events = 0; + if(extra_fds[i].events & CURL_WAIT_POLLIN) + ufds[nfds].events |= POLLIN; + if(extra_fds[i].events & CURL_WAIT_POLLPRI) + ufds[nfds].events |= POLLPRI; + if(extra_fds[i].events & CURL_WAIT_POLLOUT) + ufds[nfds].events |= POLLOUT; + ++nfds; + } + + if(nfds) { + int pollrc; + /* wait... */ + pollrc = Curl_poll(ufds, nfds, timeout_ms); + + if(pollrc > 0) { + retcode = pollrc; + /* copy revents results from the poll to the curl_multi_wait poll + struct, the bit values of the actual underlying poll() implementation + may not be the same as the ones in the public libcurl API! */ + for(i = 0; i < extra_nfds; i++) { + unsigned short mask = 0; + unsigned r = ufds[curlfds + i].revents; + + if(r & POLLIN) + mask |= CURL_WAIT_POLLIN; + if(r & POLLOUT) + mask |= CURL_WAIT_POLLOUT; + if(r & POLLPRI) + mask |= CURL_WAIT_POLLPRI; + + extra_fds[i].revents = mask; + } + } + } + + if(ufds_malloc) + free(ufds); + if(ret) + *ret = retcode; + if(gotsocket && (extra_fds || curlfds)) + /* if any socket was checked */ + *gotsocket = TRUE; + + return CURLM_OK; +} + +CURLMcode curl_multi_wait(struct Curl_multi *multi, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret) +{ + return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, NULL); +} + +/* + * multi_ischanged() is called + * + * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND + * => CONNECT action. + * + * Set 'clear' to TRUE to have it also clear the state variable. + */ +static bool multi_ischanged(struct Curl_multi *multi, bool clear) +{ + bool retval = multi->recheckstate; + if(clear) + multi->recheckstate = FALSE; + return retval; +} + +CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, + struct Curl_easy *data, + struct connectdata *conn) +{ + CURLMcode rc; + + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + + rc = curl_multi_add_handle(multi, data); + if(!rc) { + struct SingleRequest *k = &data->req; + + /* pass in NULL for 'conn' here since we don't want to init the + connection, only this transfer */ + Curl_init_do(data, NULL); + + /* take this handle to the perform state right away */ + multistate(data, CURLM_STATE_PERFORM); + Curl_attach_connnection(data, conn); + k->keepon |= KEEP_RECV; /* setup to receive! */ + } + return rc; +} + +/* + * do_complete is called when the DO actions are complete. + * + * We init chunking and trailer bits to their default values here immediately + * before receiving any header data for the current request. + */ +static void do_complete(struct connectdata *conn) +{ + conn->data->req.chunk = FALSE; + Curl_pgrsTime(conn->data, TIMER_PRETRANSFER); +} + +static CURLcode multi_do(struct Curl_easy *data, bool *done) +{ + CURLcode result = CURLE_OK; + struct connectdata *conn = data->conn; + + DEBUGASSERT(conn); + DEBUGASSERT(conn->handler); + + if(conn->handler->do_it) { + /* generic protocol-specific function pointer set in curl_connect() */ + result = conn->handler->do_it(conn, done); + + if(!result && *done) + /* do_complete must be called after the protocol-specific DO function */ + do_complete(conn); + } + return result; +} + +/* + * multi_do_more() is called during the DO_MORE multi state. It is basically a + * second stage DO state which (wrongly) was introduced to support FTP's + * second connection. + * + * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to + * DOING state there's more work to do! + */ + +static CURLcode multi_do_more(struct connectdata *conn, int *complete) +{ + CURLcode result = CURLE_OK; + + *complete = 0; + + if(conn->handler->do_more) + result = conn->handler->do_more(conn, complete); + + if(!result && (*complete == 1)) + /* do_complete must be called after the protocol-specific DO function */ + do_complete(conn); + + return result; +} + +static CURLMcode multi_runsingle(struct Curl_multi *multi, + struct curltime now, + struct Curl_easy *data) +{ + struct Curl_message *msg = NULL; + bool connected; + bool async; + bool protocol_connect = FALSE; + bool dophase_done = FALSE; + bool done = FALSE; + CURLMcode rc; + CURLcode result = CURLE_OK; + timediff_t timeout_ms; + timediff_t recv_timeout_ms; + timediff_t send_timeout_ms; + int control; + + if(!GOOD_EASY_HANDLE(data)) + return CURLM_BAD_EASY_HANDLE; + + do { + /* A "stream" here is a logical stream if the protocol can handle that + (HTTP/2), or the full connection for older protocols */ + bool stream_error = FALSE; + rc = CURLM_OK; + + DEBUGASSERT((data->mstate <= CURLM_STATE_CONNECT) || + (data->mstate >= CURLM_STATE_DONE) || + data->conn); + if(!data->conn && + data->mstate > CURLM_STATE_CONNECT && + data->mstate < CURLM_STATE_DONE) { + /* In all these states, the code will blindly access 'data->conn' + so this is precaution that it isn't NULL. And it silences static + analyzers. */ + failf(data, "In state %d with no conn, bail out!\n", data->mstate); + return CURLM_INTERNAL_ERROR; + } + + if(multi_ischanged(multi, TRUE)) { + DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n")); + process_pending_handles(multi); /* multiplexed */ + } + + if(data->conn && data->mstate > CURLM_STATE_CONNECT && + data->mstate < CURLM_STATE_COMPLETED) { + /* Make sure we set the connection's current owner */ + data->conn->data = data; + } + + if(data->conn && + (data->mstate >= CURLM_STATE_CONNECT) && + (data->mstate < CURLM_STATE_COMPLETED)) { + /* we need to wait for the connect state as only then is the start time + stored, but we must not check already completed handles */ + timeout_ms = Curl_timeleft(data, &now, + (data->mstate <= CURLM_STATE_DO)? + TRUE:FALSE); + + if(timeout_ms < 0) { + /* Handle timed out */ + if(data->mstate == CURLM_STATE_WAITRESOLVE) + failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds", + Curl_timediff(now, data->progress.t_startsingle)); + else if(data->mstate == CURLM_STATE_WAITCONNECT) + failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds", + Curl_timediff(now, data->progress.t_startsingle)); + else { + struct SingleRequest *k = &data->req; + if(k->size != -1) { + failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" + CURL_FORMAT_CURL_OFF_T " bytes received", + Curl_timediff(now, data->progress.t_startsingle), + k->bytecount, k->size); + } + else { + failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds with %" CURL_FORMAT_CURL_OFF_T + " bytes received", + Curl_timediff(now, data->progress.t_startsingle), + k->bytecount); + } + } + + /* Force connection closed if the connection has indeed been used */ + if(data->mstate > CURLM_STATE_DO) { + streamclose(data->conn, "Disconnected with pending data"); + stream_error = TRUE; + } + result = CURLE_OPERATION_TIMEDOUT; + (void)multi_done(data, result, TRUE); + /* Skip the statemachine and go directly to error handling section. */ + goto statemachine_end; + } + } + + switch(data->mstate) { + case CURLM_STATE_INIT: + /* init this transfer. */ + result = Curl_pretransfer(data); + + if(!result) { + /* after init, go CONNECT */ + multistate(data, CURLM_STATE_CONNECT); + Curl_pgrsTime(data, TIMER_STARTOP); + rc = CURLM_CALL_MULTI_PERFORM; + } + break; + + case CURLM_STATE_CONNECT_PEND: + /* We will stay here until there is a connection available. Then + we try again in the CURLM_STATE_CONNECT state. */ + break; + + case CURLM_STATE_CONNECT: + /* Connect. We want to get a connection identifier filled in. */ + Curl_pgrsTime(data, TIMER_STARTSINGLE); + if(data->set.timeout) + Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT); + + if(data->set.connecttimeout) + Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT); + + result = Curl_connect(data, &async, &protocol_connect); + if(CURLE_NO_CONNECTION_AVAILABLE == result) { + /* There was no connection available. We will go to the pending + state and wait for an available connection. */ + multistate(data, CURLM_STATE_CONNECT_PEND); + + /* add this handle to the list of connect-pending handles */ + Curl_llist_insert_next(&multi->pending, multi->pending.tail, data, + &data->connect_queue); + result = CURLE_OK; + break; + } + else if(data->state.previouslypending) { + /* this transfer comes from the pending queue so try move another */ + infof(data, "Transfer was pending, now try another\n"); + process_pending_handles(data->multi); + } + + if(!result) { + if(async) + /* We're now waiting for an asynchronous name lookup */ + multistate(data, CURLM_STATE_WAITRESOLVE); + else { + /* after the connect has been sent off, go WAITCONNECT unless the + protocol connect is already done and we can go directly to + WAITDO or DO! */ + rc = CURLM_CALL_MULTI_PERFORM; + + if(protocol_connect) + multistate(data, CURLM_STATE_DO); + else { +#ifndef CURL_DISABLE_HTTP + if(Curl_connect_ongoing(data->conn)) + multistate(data, CURLM_STATE_WAITPROXYCONNECT); + else +#endif + multistate(data, CURLM_STATE_WAITCONNECT); + } + } + } + break; + + case CURLM_STATE_WAITRESOLVE: + /* awaiting an asynch name resolve to complete */ + { + struct Curl_dns_entry *dns = NULL; + struct connectdata *conn = data->conn; + const char *hostname; + + DEBUGASSERT(conn); + if(conn->bits.httpproxy) + hostname = conn->http_proxy.host.name; + else if(conn->bits.conn_to_host) + hostname = conn->conn_to_host.name; + else + hostname = conn->host.name; + + /* check if we have the name resolved by now */ + dns = Curl_fetch_addr(conn, hostname, (int)conn->port); + + if(dns) { +#ifdef CURLRES_ASYNCH + conn->async.dns = dns; + conn->async.done = TRUE; +#endif + result = CURLE_OK; + infof(data, "Hostname '%s' was found in DNS cache\n", hostname); + } + + if(!dns) + result = Curl_resolv_check(data->conn, &dns); + + /* Update sockets here, because the socket(s) may have been + closed and the application thus needs to be told, even if it + is likely that the same socket(s) will again be used further + down. If the name has not yet been resolved, it is likely + that new sockets have been opened in an attempt to contact + another resolver. */ + singlesocket(multi, data); + + if(dns) { + /* Perform the next step in the connection phase, and then move on + to the WAITCONNECT state */ + result = Curl_once_resolved(data->conn, &protocol_connect); + + if(result) + /* if Curl_once_resolved() returns failure, the connection struct + is already freed and gone */ + data->conn = NULL; /* no more connection */ + else { + /* call again please so that we get the next socket setup */ + rc = CURLM_CALL_MULTI_PERFORM; + if(protocol_connect) + multistate(data, CURLM_STATE_DO); + else { +#ifndef CURL_DISABLE_HTTP + if(Curl_connect_ongoing(data->conn)) + multistate(data, CURLM_STATE_WAITPROXYCONNECT); + else +#endif + multistate(data, CURLM_STATE_WAITCONNECT); + } + } + } + + if(result) { + /* failure detected */ + stream_error = TRUE; + break; + } + } + break; + +#ifndef CURL_DISABLE_HTTP + case CURLM_STATE_WAITPROXYCONNECT: + /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */ + DEBUGASSERT(data->conn); + result = Curl_http_connect(data->conn, &protocol_connect); + + if(data->conn->bits.proxy_connect_closed) { + rc = CURLM_CALL_MULTI_PERFORM; + /* connect back to proxy again */ + result = CURLE_OK; + multi_done(data, CURLE_OK, FALSE); + multistate(data, CURLM_STATE_CONNECT); + } + else if(!result) { + if((data->conn->http_proxy.proxytype != CURLPROXY_HTTPS || + data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) && + Curl_connect_complete(data->conn)) { + rc = CURLM_CALL_MULTI_PERFORM; + /* initiate protocol connect phase */ + multistate(data, CURLM_STATE_SENDPROTOCONNECT); + } + } + else if(result) + stream_error = TRUE; + break; +#endif + + case CURLM_STATE_WAITCONNECT: + /* awaiting a completion of an asynch TCP connect */ + DEBUGASSERT(data->conn); + result = Curl_is_connected(data->conn, FIRSTSOCKET, &connected); + if(connected && !result) { +#ifndef CURL_DISABLE_HTTP + if((data->conn->http_proxy.proxytype == CURLPROXY_HTTPS && + !data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) || + Curl_connect_ongoing(data->conn)) { + multistate(data, CURLM_STATE_WAITPROXYCONNECT); + break; + } +#endif + rc = CURLM_CALL_MULTI_PERFORM; + multistate(data, data->conn->bits.tunnel_proxy? + CURLM_STATE_WAITPROXYCONNECT: + CURLM_STATE_SENDPROTOCONNECT); + } + else if(result) { + /* failure detected */ + Curl_posttransfer(data); + multi_done(data, result, TRUE); + stream_error = TRUE; + break; + } + break; + + case CURLM_STATE_SENDPROTOCONNECT: + result = Curl_protocol_connect(data->conn, &protocol_connect); + if(!result && !protocol_connect) + /* switch to waiting state */ + multistate(data, CURLM_STATE_PROTOCONNECT); + else if(!result) { + /* protocol connect has completed, go WAITDO or DO */ + multistate(data, CURLM_STATE_DO); + rc = CURLM_CALL_MULTI_PERFORM; + } + else if(result) { + /* failure detected */ + Curl_posttransfer(data); + multi_done(data, result, TRUE); + stream_error = TRUE; + } + break; + + case CURLM_STATE_PROTOCONNECT: + /* protocol-specific connect phase */ + result = Curl_protocol_connecting(data->conn, &protocol_connect); + if(!result && protocol_connect) { + /* after the connect has completed, go WAITDO or DO */ + multistate(data, CURLM_STATE_DO); + rc = CURLM_CALL_MULTI_PERFORM; + } + else if(result) { + /* failure detected */ + Curl_posttransfer(data); + multi_done(data, result, TRUE); + stream_error = TRUE; + } + break; + + case CURLM_STATE_DO: + if(data->set.connect_only) { + /* keep connection open for application to use the socket */ + connkeep(data->conn, "CONNECT_ONLY"); + multistate(data, CURLM_STATE_DONE); + result = CURLE_OK; + rc = CURLM_CALL_MULTI_PERFORM; + } + else { + /* Perform the protocol's DO action */ + result = multi_do(data, &dophase_done); + + /* When multi_do() returns failure, data->conn might be NULL! */ + + if(!result) { + if(!dophase_done) { +#ifndef CURL_DISABLE_FTP + /* some steps needed for wildcard matching */ + if(data->state.wildcardmatch) { + struct WildcardData *wc = &data->wildcard; + if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) { + /* skip some states if it is important */ + multi_done(data, CURLE_OK, FALSE); + multistate(data, CURLM_STATE_DONE); + rc = CURLM_CALL_MULTI_PERFORM; + break; + } + } +#endif + /* DO was not completed in one function call, we must continue + DOING... */ + multistate(data, CURLM_STATE_DOING); + rc = CURLM_OK; + } + + /* after DO, go DO_DONE... or DO_MORE */ + else if(data->conn->bits.do_more) { + /* we're supposed to do more, but we need to sit down, relax + and wait a little while first */ + multistate(data, CURLM_STATE_DO_MORE); + rc = CURLM_OK; + } + else { + /* we're done with the DO, now DO_DONE */ + multistate(data, CURLM_STATE_DO_DONE); + rc = CURLM_CALL_MULTI_PERFORM; + } + } + else if((CURLE_SEND_ERROR == result) && + data->conn->bits.reuse) { + /* + * In this situation, a connection that we were trying to use + * may have unexpectedly died. If possible, send the connection + * back to the CONNECT phase so we can try again. + */ + char *newurl = NULL; + followtype follow = FOLLOW_NONE; + CURLcode drc; + + drc = Curl_retry_request(data->conn, &newurl); + if(drc) { + /* a failure here pretty much implies an out of memory */ + result = drc; + stream_error = TRUE; + } + + Curl_posttransfer(data); + drc = multi_done(data, result, FALSE); + + /* When set to retry the connection, we must to go back to + * the CONNECT state */ + if(newurl) { + if(!drc || (drc == CURLE_SEND_ERROR)) { + follow = FOLLOW_RETRY; + drc = Curl_follow(data, newurl, follow); + if(!drc) { + multistate(data, CURLM_STATE_CONNECT); + rc = CURLM_CALL_MULTI_PERFORM; + result = CURLE_OK; + } + else { + /* Follow failed */ + result = drc; + } + } + else { + /* done didn't return OK or SEND_ERROR */ + result = drc; + } + } + else { + /* Have error handler disconnect conn if we can't retry */ + stream_error = TRUE; + } + free(newurl); + } + else { + /* failure detected */ + Curl_posttransfer(data); + if(data->conn) + multi_done(data, result, FALSE); + stream_error = TRUE; + } + } + break; + + case CURLM_STATE_DOING: + /* we continue DOING until the DO phase is complete */ + DEBUGASSERT(data->conn); + result = Curl_protocol_doing(data->conn, + &dophase_done); + if(!result) { + if(dophase_done) { + /* after DO, go DO_DONE or DO_MORE */ + multistate(data, data->conn->bits.do_more? + CURLM_STATE_DO_MORE: + CURLM_STATE_DO_DONE); + rc = CURLM_CALL_MULTI_PERFORM; + } /* dophase_done */ + } + else { + /* failure detected */ + Curl_posttransfer(data); + multi_done(data, result, FALSE); + stream_error = TRUE; + } + break; + + case CURLM_STATE_DO_MORE: + /* + * When we are connected, DO MORE and then go DO_DONE + */ + DEBUGASSERT(data->conn); + result = multi_do_more(data->conn, &control); + + if(!result) { + if(control) { + /* if positive, advance to DO_DONE + if negative, go back to DOING */ + multistate(data, control == 1? + CURLM_STATE_DO_DONE: + CURLM_STATE_DOING); + rc = CURLM_CALL_MULTI_PERFORM; + } + else + /* stay in DO_MORE */ + rc = CURLM_OK; + } + else { + /* failure detected */ + Curl_posttransfer(data); + multi_done(data, result, FALSE); + stream_error = TRUE; + } + break; + + case CURLM_STATE_DO_DONE: + DEBUGASSERT(data->conn); + if(data->conn->bits.multiplex) + /* Check if we can move pending requests to send pipe */ + process_pending_handles(multi); /* multiplexed */ + + /* Only perform the transfer if there's a good socket to work with. + Having both BAD is a signal to skip immediately to DONE */ + if((data->conn->sockfd != CURL_SOCKET_BAD) || + (data->conn->writesockfd != CURL_SOCKET_BAD)) + multistate(data, CURLM_STATE_PERFORM); + else { +#ifndef CURL_DISABLE_FTP + if(data->state.wildcardmatch && + ((data->conn->handler->flags & PROTOPT_WILDCARD) == 0)) { + data->wildcard.state = CURLWC_DONE; + } +#endif + multistate(data, CURLM_STATE_DONE); + } + rc = CURLM_CALL_MULTI_PERFORM; + break; + + case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */ + DEBUGASSERT(data->conn); + /* if both rates are within spec, resume transfer */ + if(Curl_pgrsUpdate(data->conn)) + result = CURLE_ABORTED_BY_CALLBACK; + else + result = Curl_speedcheck(data, now); + + if(!result) { + send_timeout_ms = 0; + if(data->set.max_send_speed > 0) + send_timeout_ms = + Curl_pgrsLimitWaitTime(data->progress.uploaded, + data->progress.ul_limit_size, + data->set.max_send_speed, + data->progress.ul_limit_start, + now); + + recv_timeout_ms = 0; + if(data->set.max_recv_speed > 0) + recv_timeout_ms = + Curl_pgrsLimitWaitTime(data->progress.downloaded, + data->progress.dl_limit_size, + data->set.max_recv_speed, + data->progress.dl_limit_start, + now); + + if(!send_timeout_ms && !recv_timeout_ms) { + multistate(data, CURLM_STATE_PERFORM); + Curl_ratelimit(data, now); + } + else if(send_timeout_ms >= recv_timeout_ms) + Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST); + else + Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST); + } + break; + + case CURLM_STATE_PERFORM: + { + char *newurl = NULL; + bool retry = FALSE; + bool comeback = FALSE; + + /* check if over send speed */ + send_timeout_ms = 0; + if(data->set.max_send_speed > 0) + send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded, + data->progress.ul_limit_size, + data->set.max_send_speed, + data->progress.ul_limit_start, + now); + + /* check if over recv speed */ + recv_timeout_ms = 0; + if(data->set.max_recv_speed > 0) + recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded, + data->progress.dl_limit_size, + data->set.max_recv_speed, + data->progress.dl_limit_start, + now); + + if(send_timeout_ms || recv_timeout_ms) { + Curl_ratelimit(data, now); + multistate(data, CURLM_STATE_TOOFAST); + if(send_timeout_ms >= recv_timeout_ms) + Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST); + else + Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST); + break; + } + + /* read/write data if it is ready to do so */ + result = Curl_readwrite(data->conn, data, &done, &comeback); + + if(done || (result == CURLE_RECV_ERROR)) { + /* If CURLE_RECV_ERROR happens early enough, we assume it was a race + * condition and the server closed the re-used connection exactly when + * we wanted to use it, so figure out if that is indeed the case. + */ + CURLcode ret = Curl_retry_request(data->conn, &newurl); + if(!ret) + retry = (newurl)?TRUE:FALSE; + else if(!result) + result = ret; + + if(retry) { + /* if we are to retry, set the result to OK and consider the + request as done */ + result = CURLE_OK; + done = TRUE; + } + } + else if((CURLE_HTTP2_STREAM == result) && + Curl_h2_http_1_1_error(data->conn)) { + CURLcode ret = Curl_retry_request(data->conn, &newurl); + + if(!ret) { + infof(data, "Downgrades to HTTP/1.1!\n"); + data->set.httpversion = CURL_HTTP_VERSION_1_1; + /* clear the error message bit too as we ignore the one we got */ + data->state.errorbuf = FALSE; + if(!newurl) + /* typically for HTTP_1_1_REQUIRED error on first flight */ + newurl = strdup(data->change.url); + /* if we are to retry, set the result to OK and consider the request + as done */ + retry = TRUE; + result = CURLE_OK; + done = TRUE; + } + else + result = ret; + } + + if(result) { + /* + * The transfer phase returned error, we mark the connection to get + * closed to prevent being re-used. This is because we can't possibly + * know if the connection is in a good shape or not now. Unless it is + * a protocol which uses two "channels" like FTP, as then the error + * happened in the data connection. + */ + + if(!(data->conn->handler->flags & PROTOPT_DUAL) && + result != CURLE_HTTP2_STREAM) + streamclose(data->conn, "Transfer returned error"); + + Curl_posttransfer(data); + multi_done(data, result, TRUE); + } + else if(done) { + followtype follow = FOLLOW_NONE; + + /* call this even if the readwrite function returned error */ + Curl_posttransfer(data); + + /* When we follow redirects or is set to retry the connection, we must + to go back to the CONNECT state */ + if(data->req.newurl || retry) { + if(!retry) { + /* if the URL is a follow-location and not just a retried request + then figure out the URL here */ + free(newurl); + newurl = data->req.newurl; + data->req.newurl = NULL; + follow = FOLLOW_REDIR; + } + else + follow = FOLLOW_RETRY; + (void)multi_done(data, CURLE_OK, FALSE); + /* multi_done() might return CURLE_GOT_NOTHING */ + result = Curl_follow(data, newurl, follow); + if(!result) { + multistate(data, CURLM_STATE_CONNECT); + rc = CURLM_CALL_MULTI_PERFORM; + } + free(newurl); + } + else { + /* after the transfer is done, go DONE */ + + /* but first check to see if we got a location info even though we're + not following redirects */ + if(data->req.location) { + free(newurl); + newurl = data->req.location; + data->req.location = NULL; + result = Curl_follow(data, newurl, FOLLOW_FAKE); + free(newurl); + if(result) { + stream_error = TRUE; + result = multi_done(data, result, TRUE); + } + } + + if(!result) { + multistate(data, CURLM_STATE_DONE); + rc = CURLM_CALL_MULTI_PERFORM; + } + } + } + else if(comeback) + rc = CURLM_CALL_MULTI_PERFORM; + break; + } + + case CURLM_STATE_DONE: + /* this state is highly transient, so run another loop after this */ + rc = CURLM_CALL_MULTI_PERFORM; + + if(data->conn) { + CURLcode res; + + if(data->conn->bits.multiplex) + /* Check if we can move pending requests to connection */ + process_pending_handles(multi); /* multiplexing */ + + /* post-transfer command */ + res = multi_done(data, result, FALSE); + + /* allow a previously set error code take precedence */ + if(!result) + result = res; + + /* + * If there are other handles on the connection, multi_done won't set + * conn to NULL. In such a case, curl_multi_remove_handle() can + * access free'd data, if the connection is free'd and the handle + * removed before we perform the processing in CURLM_STATE_COMPLETED + */ + if(data->conn) + detach_connnection(data); + } + +#ifndef CURL_DISABLE_FTP + if(data->state.wildcardmatch) { + if(data->wildcard.state != CURLWC_DONE) { + /* if a wildcard is set and we are not ending -> lets start again + with CURLM_STATE_INIT */ + multistate(data, CURLM_STATE_INIT); + break; + } + } +#endif + /* after we have DONE what we're supposed to do, go COMPLETED, and + it doesn't matter what the multi_done() returned! */ + multistate(data, CURLM_STATE_COMPLETED); + break; + + case CURLM_STATE_COMPLETED: + break; + + case CURLM_STATE_MSGSENT: + data->result = result; + return CURLM_OK; /* do nothing */ + + default: + return CURLM_INTERNAL_ERROR; + } + statemachine_end: + + if(data->mstate < CURLM_STATE_COMPLETED) { + if(result) { + /* + * If an error was returned, and we aren't in completed state now, + * then we go to completed and consider this transfer aborted. + */ + + /* NOTE: no attempt to disconnect connections must be made + in the case blocks above - cleanup happens only here */ + + /* Check if we can move pending requests to send pipe */ + process_pending_handles(multi); /* connection */ + + if(data->conn) { + if(stream_error) { + /* Don't attempt to send data over a connection that timed out */ + bool dead_connection = result == CURLE_OPERATION_TIMEDOUT; + /* disconnect properly */ + Curl_disconnect(data, data->conn, dead_connection); + + /* This is where we make sure that the conn pointer is reset. + We don't have to do this in every case block above where a + failure is detected */ + detach_connnection(data); + } + } + else if(data->mstate == CURLM_STATE_CONNECT) { + /* Curl_connect() failed */ + (void)Curl_posttransfer(data); + } + + multistate(data, CURLM_STATE_COMPLETED); + rc = CURLM_CALL_MULTI_PERFORM; + } + /* if there's still a connection to use, call the progress function */ + else if(data->conn && Curl_pgrsUpdate(data->conn)) { + /* aborted due to progress callback return code must close the + connection */ + result = CURLE_ABORTED_BY_CALLBACK; + streamclose(data->conn, "Aborted by callback"); + + /* if not yet in DONE state, go there, otherwise COMPLETED */ + multistate(data, (data->mstate < CURLM_STATE_DONE)? + CURLM_STATE_DONE: CURLM_STATE_COMPLETED); + rc = CURLM_CALL_MULTI_PERFORM; + } + } + + if(CURLM_STATE_COMPLETED == data->mstate) { + if(data->set.fmultidone) { + /* signal via callback instead */ + data->set.fmultidone(data, result); + } + else { + /* now fill in the Curl_message with this info */ + msg = &data->msg; + + msg->extmsg.msg = CURLMSG_DONE; + msg->extmsg.easy_handle = data; + msg->extmsg.data.result = result; + + rc = multi_addmsg(multi, msg); + DEBUGASSERT(!data->conn); + } + multistate(data, CURLM_STATE_MSGSENT); + } + } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE)); + + data->result = result; + return rc; +} + + +CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) +{ + struct Curl_easy *data; + CURLMcode returncode = CURLM_OK; + struct Curl_tree *t; + struct curltime now = Curl_now(); + + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + + data = multi->easyp; + while(data) { + CURLMcode result; + SIGPIPE_VARIABLE(pipe_st); + + sigpipe_ignore(data, &pipe_st); + result = multi_runsingle(multi, now, data); + sigpipe_restore(&pipe_st); + + if(result) + returncode = result; + + data = data->next; /* operate on next handle */ + } + + /* + * Simply remove all expired timers from the splay since handles are dealt + * with unconditionally by this function and curl_multi_timeout() requires + * that already passed/handled expire times are removed from the splay. + * + * It is important that the 'now' value is set at the entry of this function + * and not for the current time as it may have ticked a little while since + * then and then we risk this loop to remove timers that actually have not + * been handled! + */ + do { + multi->timetree = Curl_splaygetbest(now, multi->timetree, &t); + if(t) + /* the removed may have another timeout in queue */ + (void)add_next_timeout(now, multi, t->payload); + + } while(t); + + *running_handles = multi->num_alive; + + if(CURLM_OK >= returncode) + Curl_update_timer(multi); + + return returncode; +} + +CURLMcode curl_multi_cleanup(struct Curl_multi *multi) +{ + struct Curl_easy *data; + struct Curl_easy *nextdata; + + if(GOOD_MULTI_HANDLE(multi)) { + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + + multi->type = 0; /* not good anymore */ + + /* Firsrt remove all remaining easy handles */ + data = multi->easyp; + while(data) { + nextdata = data->next; + if(!data->state.done && data->conn) + /* if DONE was never called for this handle */ + (void)multi_done(data, CURLE_OK, TRUE); + if(data->dns.hostcachetype == HCACHE_MULTI) { + /* clear out the usage of the shared DNS cache */ + Curl_hostcache_clean(data, data->dns.hostcache); + data->dns.hostcache = NULL; + data->dns.hostcachetype = HCACHE_NONE; + } + + /* Clear the pointer to the connection cache */ + data->state.conn_cache = NULL; + data->multi = NULL; /* clear the association */ + +#ifdef USE_LIBPSL + if(data->psl == &multi->psl) + data->psl = NULL; +#endif + + data = nextdata; + } + + /* Close all the connections in the connection cache */ + Curl_conncache_close_all_connections(&multi->conn_cache); + + Curl_hash_destroy(&multi->sockhash); + Curl_conncache_destroy(&multi->conn_cache); + Curl_llist_destroy(&multi->msglist, NULL); + Curl_llist_destroy(&multi->pending, NULL); + + Curl_hash_destroy(&multi->hostcache); + Curl_psl_destroy(&multi->psl); + free(multi); + + return CURLM_OK; + } + return CURLM_BAD_HANDLE; +} + +/* + * curl_multi_info_read() + * + * This function is the primary way for a multi/multi_socket application to + * figure out if a transfer has ended. We MUST make this function as fast as + * possible as it will be polled frequently and we MUST NOT scan any lists in + * here to figure out things. We must scale fine to thousands of handles and + * beyond. The current design is fully O(1). + */ + +CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue) +{ + struct Curl_message *msg; + + *msgs_in_queue = 0; /* default to none */ + + if(GOOD_MULTI_HANDLE(multi) && + !multi->in_callback && + Curl_llist_count(&multi->msglist)) { + /* there is one or more messages in the list */ + struct curl_llist_element *e; + + /* extract the head of the list to return */ + e = multi->msglist.head; + + msg = e->ptr; + + /* remove the extracted entry */ + Curl_llist_remove(&multi->msglist, e, NULL); + + *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist)); + + return &msg->extmsg; + } + return NULL; +} + +/* + * singlesocket() checks what sockets we deal with and their "action state" + * and if we have a different state in any of those sockets from last time we + * call the callback accordingly. + */ +static CURLMcode singlesocket(struct Curl_multi *multi, + struct Curl_easy *data) +{ + curl_socket_t socks[MAX_SOCKSPEREASYHANDLE]; + int i; + struct Curl_sh_entry *entry; + curl_socket_t s; + int num; + unsigned int curraction; + int actions[MAX_SOCKSPEREASYHANDLE]; + + for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) + socks[i] = CURL_SOCKET_BAD; + + /* Fill in the 'current' struct with the state as it is now: what sockets to + supervise and for what actions */ + curraction = multi_getsock(data, socks, MAX_SOCKSPEREASYHANDLE); + + /* We have 0 .. N sockets already and we get to know about the 0 .. M + sockets we should have from now on. Detect the differences, remove no + longer supervised ones and add new ones */ + + /* walk over the sockets we got right now */ + for(i = 0; (i< MAX_SOCKSPEREASYHANDLE) && + (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))); + i++) { + unsigned int action = CURL_POLL_NONE; + unsigned int prevaction = 0; + unsigned int comboaction; + bool sincebefore = FALSE; + + s = socks[i]; + + /* get it from the hash */ + entry = sh_getentry(&multi->sockhash, s); + + if(curraction & GETSOCK_READSOCK(i)) + action |= CURL_POLL_IN; + if(curraction & GETSOCK_WRITESOCK(i)) + action |= CURL_POLL_OUT; + + actions[i] = action; + if(entry) { + /* check if new for this transfer */ + int j; + for(j = 0; j< data->numsocks; j++) { + if(s == data->sockets[j]) { + prevaction = data->actions[j]; + sincebefore = TRUE; + break; + } + } + } + else { + /* this is a socket we didn't have before, add it to the hash! */ + entry = sh_addentry(&multi->sockhash, s); + if(!entry) + /* fatal */ + return CURLM_OUT_OF_MEMORY; + } + if(sincebefore && (prevaction != action)) { + /* Socket was used already, but different action now */ + if(prevaction & CURL_POLL_IN) + entry->readers--; + if(prevaction & CURL_POLL_OUT) + entry->writers--; + if(action & CURL_POLL_IN) + entry->readers++; + if(action & CURL_POLL_OUT) + entry->writers++; + } + else if(!sincebefore) { + /* a new user */ + entry->users++; + if(action & CURL_POLL_IN) + entry->readers++; + if(action & CURL_POLL_OUT) + entry->writers++; + + /* add 'data' to the transfer hash on this socket! */ + if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */ + sizeof(struct Curl_easy *), data)) + return CURLM_OUT_OF_MEMORY; + } + + comboaction = (entry->writers? CURL_POLL_OUT : 0) | + (entry->readers ? CURL_POLL_IN : 0); + + /* socket existed before and has the same action set as before */ + if(sincebefore && (entry->action == comboaction)) + /* same, continue */ + continue; + + if(multi->socket_cb) + multi->socket_cb(data, s, comboaction, multi->socket_userp, + entry->socketp); + + entry->action = comboaction; /* store the current action state */ + } + + num = i; /* number of sockets */ + + /* when we've walked over all the sockets we should have right now, we must + make sure to detect sockets that are removed */ + for(i = 0; i< data->numsocks; i++) { + int j; + bool stillused = FALSE; + s = data->sockets[i]; + for(j = 0; j < num; j++) { + if(s == socks[j]) { + /* this is still supervised */ + stillused = TRUE; + break; + } + } + if(stillused) + continue; + + entry = sh_getentry(&multi->sockhash, s); + /* if this is NULL here, the socket has been closed and notified so + already by Curl_multi_closed() */ + if(entry) { + int oldactions = data->actions[i]; + /* this socket has been removed. Decrease user count */ + entry->users--; + if(oldactions & CURL_POLL_OUT) + entry->writers--; + if(oldactions & CURL_POLL_IN) + entry->readers--; + if(!entry->users) { + if(multi->socket_cb) + multi->socket_cb(data, s, CURL_POLL_REMOVE, + multi->socket_userp, + entry->socketp); + sh_delentry(entry, &multi->sockhash, s); + } + else { + /* still users, but remove this handle as a user of this socket */ + if(Curl_hash_delete(&entry->transfers, (char *)&data, + sizeof(struct Curl_easy *))) { + DEBUGASSERT(NULL); + } + } + } + } /* for loop over numsocks */ + + memcpy(data->sockets, socks, num*sizeof(curl_socket_t)); + memcpy(data->actions, actions, num*sizeof(int)); + data->numsocks = num; + return CURLM_OK; +} + +void Curl_updatesocket(struct Curl_easy *data) +{ + singlesocket(data->multi, data); +} + + +/* + * Curl_multi_closed() + * + * Used by the connect code to tell the multi_socket code that one of the + * sockets we were using is about to be closed. This function will then + * remove it from the sockethash for this handle to make the multi_socket API + * behave properly, especially for the case when libcurl will create another + * socket again and it gets the same file descriptor number. + */ + +void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s) +{ + if(data) { + /* if there's still an easy handle associated with this connection */ + struct Curl_multi *multi = data->multi; + if(multi) { + /* this is set if this connection is part of a handle that is added to + a multi handle, and only then this is necessary */ + struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); + + if(entry) { + if(multi->socket_cb) + multi->socket_cb(data, s, CURL_POLL_REMOVE, + multi->socket_userp, + entry->socketp); + + /* now remove it from the socket hash */ + sh_delentry(entry, &multi->sockhash, s); + } + } + } +} + +/* + * add_next_timeout() + * + * Each Curl_easy has a list of timeouts. The add_next_timeout() is called + * when it has just been removed from the splay tree because the timeout has + * expired. This function is then to advance in the list to pick the next + * timeout to use (skip the already expired ones) and add this node back to + * the splay tree again. + * + * The splay tree only has each sessionhandle as a single node and the nearest + * timeout is used to sort it on. + */ +static CURLMcode add_next_timeout(struct curltime now, + struct Curl_multi *multi, + struct Curl_easy *d) +{ + struct curltime *tv = &d->state.expiretime; + struct curl_llist *list = &d->state.timeoutlist; + struct curl_llist_element *e; + struct time_node *node = NULL; + + /* move over the timeout list for this specific handle and remove all + timeouts that are now passed tense and store the next pending + timeout in *tv */ + for(e = list->head; e;) { + struct curl_llist_element *n = e->next; + timediff_t diff; + node = (struct time_node *)e->ptr; + diff = Curl_timediff(node->time, now); + if(diff <= 0) + /* remove outdated entry */ + Curl_llist_remove(list, e, NULL); + else + /* the list is sorted so get out on the first mismatch */ + break; + e = n; + } + e = list->head; + if(!e) { + /* clear the expire times within the handles that we remove from the + splay tree */ + tv->tv_sec = 0; + tv->tv_usec = 0; + } + else { + /* copy the first entry to 'tv' */ + memcpy(tv, &node->time, sizeof(*tv)); + + /* Insert this node again into the splay. Keep the timer in the list in + case we need to recompute future timers. */ + multi->timetree = Curl_splayinsert(*tv, multi->timetree, + &d->state.timenode); + } + return CURLM_OK; +} + +static CURLMcode multi_socket(struct Curl_multi *multi, + bool checkall, + curl_socket_t s, + int ev_bitmask, + int *running_handles) +{ + CURLMcode result = CURLM_OK; + struct Curl_easy *data = NULL; + struct Curl_tree *t; + struct curltime now = Curl_now(); + + if(checkall) { + /* *perform() deals with running_handles on its own */ + result = curl_multi_perform(multi, running_handles); + + /* walk through each easy handle and do the socket state change magic + and callbacks */ + if(result != CURLM_BAD_HANDLE) { + data = multi->easyp; + while(data && !result) { + result = singlesocket(multi, data); + data = data->next; + } + } + + /* or should we fall-through and do the timer-based stuff? */ + return result; + } + if(s != CURL_SOCKET_TIMEOUT) { + struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); + + if(!entry) + /* Unmatched socket, we can't act on it but we ignore this fact. In + real-world tests it has been proved that libevent can in fact give + the application actions even though the socket was just previously + asked to get removed, so thus we better survive stray socket actions + and just move on. */ + ; + else { + struct curl_hash_iterator iter; + struct curl_hash_element *he; + + /* the socket can be shared by many transfers, iterate */ + Curl_hash_start_iterate(&entry->transfers, &iter); + for(he = Curl_hash_next_element(&iter); he; + he = Curl_hash_next_element(&iter)) { + data = (struct Curl_easy *)he->ptr; + DEBUGASSERT(data); + DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER); + + if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK)) + /* set socket event bitmask if they're not locked */ + data->conn->cselect_bits = ev_bitmask; + + Curl_expire(data, 0, EXPIRE_RUN_NOW); + } + + /* Now we fall-through and do the timer-based stuff, since we don't want + to force the user to have to deal with timeouts as long as at least + one connection in fact has traffic. */ + + data = NULL; /* set data to NULL again to avoid calling + multi_runsingle() in case there's no need to */ + now = Curl_now(); /* get a newer time since the multi_runsingle() loop + may have taken some time */ + } + } + else { + /* Asked to run due to time-out. Clear the 'lastcall' variable to force + Curl_update_timer() to trigger a callback to the app again even if the + same timeout is still the one to run after this call. That handles the + case when the application asks libcurl to run the timeout + prematurely. */ + memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); + } + + /* + * The loop following here will go on as long as there are expire-times left + * to process in the splay and 'data' will be re-assigned for every expired + * handle we deal with. + */ + do { + /* the first loop lap 'data' can be NULL */ + if(data) { + SIGPIPE_VARIABLE(pipe_st); + + sigpipe_ignore(data, &pipe_st); + result = multi_runsingle(multi, now, data); + sigpipe_restore(&pipe_st); + + if(CURLM_OK >= result) { + /* get the socket(s) and check if the state has been changed since + last */ + result = singlesocket(multi, data); + if(result) + return result; + } + } + + /* Check if there's one (more) expired timer to deal with! This function + extracts a matching node if there is one */ + + multi->timetree = Curl_splaygetbest(now, multi->timetree, &t); + if(t) { + data = t->payload; /* assign this for next loop */ + (void)add_next_timeout(now, multi, t->payload); + } + + } while(t); + + *running_handles = multi->num_alive; + return result; +} + +#undef curl_multi_setopt +CURLMcode curl_multi_setopt(struct Curl_multi *multi, + CURLMoption option, ...) +{ + CURLMcode res = CURLM_OK; + va_list param; + + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + + va_start(param, option); + + switch(option) { + case CURLMOPT_SOCKETFUNCTION: + multi->socket_cb = va_arg(param, curl_socket_callback); + break; + case CURLMOPT_SOCKETDATA: + multi->socket_userp = va_arg(param, void *); + break; + case CURLMOPT_PUSHFUNCTION: + multi->push_cb = va_arg(param, curl_push_callback); + break; + case CURLMOPT_PUSHDATA: + multi->push_userp = va_arg(param, void *); + break; + case CURLMOPT_PIPELINING: + multi->multiplexing = va_arg(param, long) & CURLPIPE_MULTIPLEX; + break; + case CURLMOPT_TIMERFUNCTION: + multi->timer_cb = va_arg(param, curl_multi_timer_callback); + break; + case CURLMOPT_TIMERDATA: + multi->timer_userp = va_arg(param, void *); + break; + case CURLMOPT_MAXCONNECTS: + multi->maxconnects = va_arg(param, long); + break; + case CURLMOPT_MAX_HOST_CONNECTIONS: + multi->max_host_connections = va_arg(param, long); + break; + case CURLMOPT_MAX_TOTAL_CONNECTIONS: + multi->max_total_connections = va_arg(param, long); + break; + /* options formerly used for pipelining */ + case CURLMOPT_MAX_PIPELINE_LENGTH: + break; + case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE: + break; + case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE: + break; + case CURLMOPT_PIPELINING_SITE_BL: + break; + case CURLMOPT_PIPELINING_SERVER_BL: + break; + default: + res = CURLM_UNKNOWN_OPTION; + break; + } + va_end(param); + return res; +} + +/* we define curl_multi_socket() in the public multi.h header */ +#undef curl_multi_socket + +CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s, + int *running_handles) +{ + CURLMcode result; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + result = multi_socket(multi, FALSE, s, 0, running_handles); + if(CURLM_OK >= result) + Curl_update_timer(multi); + return result; +} + +CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s, + int ev_bitmask, int *running_handles) +{ + CURLMcode result; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles); + if(CURLM_OK >= result) + Curl_update_timer(multi); + return result; +} + +CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles) + +{ + CURLMcode result; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles); + if(CURLM_OK >= result) + Curl_update_timer(multi); + return result; +} + +static CURLMcode multi_timeout(struct Curl_multi *multi, + long *timeout_ms) +{ + static struct curltime tv_zero = {0, 0}; + + if(multi->timetree) { + /* we have a tree of expire times */ + struct curltime now = Curl_now(); + + /* splay the lowest to the bottom */ + multi->timetree = Curl_splay(tv_zero, multi->timetree); + + if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) { + /* some time left before expiration */ + timediff_t diff = Curl_timediff(multi->timetree->key, now); + if(diff <= 0) + /* + * Since we only provide millisecond resolution on the returned value + * and the diff might be less than one millisecond here, we don't + * return zero as that may cause short bursts of busyloops on fast + * processors while the diff is still present but less than one + * millisecond! instead we return 1 until the time is ripe. + */ + *timeout_ms = 1; + else + /* this should be safe even on 64 bit archs, as we don't use that + overly long timeouts */ + *timeout_ms = (long)diff; + } + else + /* 0 means immediately */ + *timeout_ms = 0; + } + else + *timeout_ms = -1; + + return CURLM_OK; +} + +CURLMcode curl_multi_timeout(struct Curl_multi *multi, + long *timeout_ms) +{ + /* First, make some basic checks that the CURLM handle is a good handle */ + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + + return multi_timeout(multi, timeout_ms); +} + +/* + * Tell the application it should update its timers, if it subscribes to the + * update timer callback. + */ +void Curl_update_timer(struct Curl_multi *multi) +{ + long timeout_ms; + + if(!multi->timer_cb) + return; + if(multi_timeout(multi, &timeout_ms)) { + return; + } + if(timeout_ms < 0) { + static const struct curltime none = {0, 0}; + if(Curl_splaycomparekeys(none, multi->timer_lastcall)) { + multi->timer_lastcall = none; + /* there's no timeout now but there was one previously, tell the app to + disable it */ + multi->timer_cb(multi, -1, multi->timer_userp); + return; + } + return; + } + + /* When multi_timeout() is done, multi->timetree points to the node with the + * timeout we got the (relative) time-out time for. We can thus easily check + * if this is the same (fixed) time as we got in a previous call and then + * avoid calling the callback again. */ + if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0) + return; + + multi->timer_lastcall = multi->timetree->key; + + multi->timer_cb(multi, timeout_ms, multi->timer_userp); +} + +/* + * multi_deltimeout() + * + * Remove a given timestamp from the list of timeouts. + */ +static void +multi_deltimeout(struct Curl_easy *data, expire_id eid) +{ + struct curl_llist_element *e; + struct curl_llist *timeoutlist = &data->state.timeoutlist; + /* find and remove the specific node from the list */ + for(e = timeoutlist->head; e; e = e->next) { + struct time_node *n = (struct time_node *)e->ptr; + if(n->eid == eid) { + Curl_llist_remove(timeoutlist, e, NULL); + return; + } + } +} + +/* + * multi_addtimeout() + * + * Add a timestamp to the list of timeouts. Keep the list sorted so that head + * of list is always the timeout nearest in time. + * + */ +static CURLMcode +multi_addtimeout(struct Curl_easy *data, + struct curltime *stamp, + expire_id eid) +{ + struct curl_llist_element *e; + struct time_node *node; + struct curl_llist_element *prev = NULL; + size_t n; + struct curl_llist *timeoutlist = &data->state.timeoutlist; + + node = &data->state.expires[eid]; + + /* copy the timestamp and id */ + memcpy(&node->time, stamp, sizeof(*stamp)); + node->eid = eid; /* also marks it as in use */ + + n = Curl_llist_count(timeoutlist); + if(n) { + /* find the correct spot in the list */ + for(e = timeoutlist->head; e; e = e->next) { + struct time_node *check = (struct time_node *)e->ptr; + timediff_t diff = Curl_timediff(check->time, node->time); + if(diff > 0) + break; + prev = e; + } + + } + /* else + this is the first timeout on the list */ + + Curl_llist_insert_next(timeoutlist, prev, node, &node->list); + return CURLM_OK; +} + +/* + * Curl_expire() + * + * given a number of milliseconds from now to use to set the 'act before + * this'-time for the transfer, to be extracted by curl_multi_timeout() + * + * The timeout will be added to a queue of timeouts if it defines a moment in + * time that is later than the current head of queue. + * + * Expire replaces a former timeout using the same id if already set. + */ +void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id) +{ + struct Curl_multi *multi = data->multi; + struct curltime *nowp = &data->state.expiretime; + struct curltime set; + + /* this is only interesting while there is still an associated multi struct + remaining! */ + if(!multi) + return; + + DEBUGASSERT(id < EXPIRE_LAST); + + set = Curl_now(); + set.tv_sec += milli/1000; + set.tv_usec += (unsigned int)(milli%1000)*1000; + + if(set.tv_usec >= 1000000) { + set.tv_sec++; + set.tv_usec -= 1000000; + } + + /* Remove any timer with the same id just in case. */ + multi_deltimeout(data, id); + + /* Add it to the timer list. It must stay in the list until it has expired + in case we need to recompute the minimum timer later. */ + multi_addtimeout(data, &set, id); + + if(nowp->tv_sec || nowp->tv_usec) { + /* This means that the struct is added as a node in the splay tree. + Compare if the new time is earlier, and only remove-old/add-new if it + is. */ + timediff_t diff = Curl_timediff(set, *nowp); + int rc; + + if(diff > 0) { + /* The current splay tree entry is sooner than this new expiry time. + We don't need to update our splay tree entry. */ + return; + } + + /* Since this is an updated time, we must remove the previous entry from + the splay tree first and then re-add the new value */ + rc = Curl_splayremovebyaddr(multi->timetree, + &data->state.timenode, + &multi->timetree); + if(rc) + infof(data, "Internal error removing splay node = %d\n", rc); + } + + /* Indicate that we are in the splay tree and insert the new timer expiry + value since it is our local minimum. */ + *nowp = set; + data->state.timenode.payload = data; + multi->timetree = Curl_splayinsert(*nowp, multi->timetree, + &data->state.timenode); +} + +/* + * Curl_expire_done() + * + * Removes the expire timer. Marks it as done. + * + */ +void Curl_expire_done(struct Curl_easy *data, expire_id id) +{ + /* remove the timer, if there */ + multi_deltimeout(data, id); +} + +/* + * Curl_expire_clear() + * + * Clear ALL timeout values for this handle. + */ +void Curl_expire_clear(struct Curl_easy *data) +{ + struct Curl_multi *multi = data->multi; + struct curltime *nowp = &data->state.expiretime; + + /* this is only interesting while there is still an associated multi struct + remaining! */ + if(!multi) + return; + + if(nowp->tv_sec || nowp->tv_usec) { + /* Since this is an cleared time, we must remove the previous entry from + the splay tree */ + struct curl_llist *list = &data->state.timeoutlist; + int rc; + + rc = Curl_splayremovebyaddr(multi->timetree, + &data->state.timenode, + &multi->timetree); + if(rc) + infof(data, "Internal error clearing splay node = %d\n", rc); + + /* flush the timeout list too */ + while(list->size > 0) { + Curl_llist_remove(list, list->tail, NULL); + } + +#ifdef DEBUGBUILD + infof(data, "Expire cleared (transfer %p)\n", data); +#endif + nowp->tv_sec = 0; + nowp->tv_usec = 0; + } +} + + + + +CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s, + void *hashp) +{ + struct Curl_sh_entry *there = NULL; + + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + + there = sh_getentry(&multi->sockhash, s); + + if(!there) + return CURLM_BAD_SOCKET; + + there->socketp = hashp; + + return CURLM_OK; +} + +size_t Curl_multi_max_host_connections(struct Curl_multi *multi) +{ + return multi ? multi->max_host_connections : 0; +} + +size_t Curl_multi_max_total_connections(struct Curl_multi *multi) +{ + return multi ? multi->max_total_connections : 0; +} + +/* + * When information about a connection has appeared, call this! + */ + +void Curl_multiuse_state(struct connectdata *conn, + int bundlestate) /* use BUNDLE_* defines */ +{ + DEBUGASSERT(conn); + DEBUGASSERT(conn->bundle); + DEBUGASSERT(conn->data); + DEBUGASSERT(conn->data->multi); + + conn->bundle->multiuse = bundlestate; + process_pending_handles(conn->data->multi); +} + +static void process_pending_handles(struct Curl_multi *multi) +{ + struct curl_llist_element *e = multi->pending.head; + if(e) { + struct Curl_easy *data = e->ptr; + + DEBUGASSERT(data->mstate == CURLM_STATE_CONNECT_PEND); + + multistate(data, CURLM_STATE_CONNECT); + + /* Remove this node from the list */ + Curl_llist_remove(&multi->pending, e, NULL); + + /* Make sure that the handle will be processed soonish. */ + Curl_expire(data, 0, EXPIRE_RUN_NOW); + + /* mark this as having been in the pending queue */ + data->state.previouslypending = TRUE; + } +} + +void Curl_set_in_callback(struct Curl_easy *data, bool value) +{ + /* might get called when there is no data pointer! */ + if(data) { + if(data->multi_easy) + data->multi_easy->in_callback = value; + else if(data->multi) + data->multi->in_callback = value; + } +} + +bool Curl_is_in_callback(struct Curl_easy *easy) +{ + return ((easy->multi && easy->multi->in_callback) || + (easy->multi_easy && easy->multi_easy->in_callback)); +} + +#ifdef DEBUGBUILD +void Curl_multi_dump(struct Curl_multi *multi) +{ + struct Curl_easy *data; + int i; + fprintf(stderr, "* Multi status: %d handles, %d alive\n", + multi->num_easy, multi->num_alive); + for(data = multi->easyp; data; data = data->next) { + if(data->mstate < CURLM_STATE_COMPLETED) { + /* only display handles that are not completed */ + fprintf(stderr, "handle %p, state %s, %d sockets\n", + (void *)data, + statename[data->mstate], data->numsocks); + for(i = 0; i < data->numsocks; i++) { + curl_socket_t s = data->sockets[i]; + struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); + + fprintf(stderr, "%d ", (int)s); + if(!entry) { + fprintf(stderr, "INTERNAL CONFUSION\n"); + continue; + } + fprintf(stderr, "[%s %s] ", + (entry->action&CURL_POLL_IN)?"RECVING":"", + (entry->action&CURL_POLL_OUT)?"SENDING":""); + } + if(data->numsocks) + fprintf(stderr, "\n"); + } + } +} +#endif diff --git a/libcurl/lib/multihandle.h b/libcurl/lib/multihandle.h new file mode 100644 index 0000000..279379a --- /dev/null +++ b/libcurl/lib/multihandle.h @@ -0,0 +1,138 @@ +#ifndef HEADER_CURL_MULTIHANDLE_H +#define HEADER_CURL_MULTIHANDLE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "conncache.h" +#include "psl.h" + +struct Curl_message { + struct curl_llist_element list; + /* the 'CURLMsg' is the part that is visible to the external user */ + struct CURLMsg extmsg; +}; + +/* NOTE: if you add a state here, add the name to the statename[] array as + well! +*/ +typedef enum { + CURLM_STATE_INIT, /* 0 - start in this state */ + CURLM_STATE_CONNECT_PEND, /* 1 - no connections, waiting for one */ + CURLM_STATE_CONNECT, /* 2 - resolve/connect has been sent off */ + CURLM_STATE_WAITRESOLVE, /* 3 - awaiting the resolve to finalize */ + CURLM_STATE_WAITCONNECT, /* 4 - awaiting the TCP connect to finalize */ + CURLM_STATE_WAITPROXYCONNECT, /* 5 - awaiting HTTPS proxy SSL initialization + to complete and/or proxy CONNECT to + finalize */ + CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */ + CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect + phase */ + CURLM_STATE_DO, /* 8 - start send off the request (part 1) */ + CURLM_STATE_DOING, /* 9 - sending off the request (part 1) */ + CURLM_STATE_DO_MORE, /* 10 - send off the request (part 2) */ + CURLM_STATE_DO_DONE, /* 11 - done sending off request */ + CURLM_STATE_PERFORM, /* 12 - transfer data */ + CURLM_STATE_TOOFAST, /* 13 - wait because limit-rate exceeded */ + CURLM_STATE_DONE, /* 14 - post data transfer operation */ + CURLM_STATE_COMPLETED, /* 15 - operation complete */ + CURLM_STATE_MSGSENT, /* 16 - the operation complete message is sent */ + CURLM_STATE_LAST /* 17 - not a true state, never use this */ +} CURLMstate; + +/* we support N sockets per easy handle. Set the corresponding bit to what + action we should wait for */ +#define MAX_SOCKSPEREASYHANDLE 5 +#define GETSOCK_READABLE (0x00ff) +#define GETSOCK_WRITABLE (0xff00) + +#define CURLPIPE_ANY (CURLPIPE_MULTIPLEX) + +/* This is the struct known as CURLM on the outside */ +struct Curl_multi { + /* First a simple identifier to easier detect if a user mix up + this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */ + long type; + + /* We have a doubly-linked circular list with easy handles */ + struct Curl_easy *easyp; + struct Curl_easy *easylp; /* last node */ + + int num_easy; /* amount of entries in the linked list above. */ + int num_alive; /* amount of easy handles that are added but have not yet + reached COMPLETE state */ + + struct curl_llist msglist; /* a list of messages from completed transfers */ + + struct curl_llist pending; /* Curl_easys that are in the + CURLM_STATE_CONNECT_PEND state */ + + /* callback function and user data pointer for the *socket() API */ + curl_socket_callback socket_cb; + void *socket_userp; + + /* callback function and user data pointer for server push */ + curl_push_callback push_cb; + void *push_userp; + + /* Hostname cache */ + struct curl_hash hostcache; + +#ifdef USE_LIBPSL + /* PSL cache. */ + struct PslCache psl; +#endif + + /* timetree points to the splay-tree of time nodes to figure out expire + times of all currently set timers */ + struct Curl_tree *timetree; + + /* 'sockhash' is the lookup hash for socket descriptor => easy handles (note + the pluralis form, there can be more than one easy handle waiting on the + same actual socket) */ + struct curl_hash sockhash; + + /* multiplexing wanted */ + bool multiplexing; + + bool recheckstate; /* see Curl_multi_connchanged */ + + /* Shared connection cache (bundles)*/ + struct conncache conn_cache; + + long maxconnects; /* if >0, a fixed limit of the maximum number of entries + we're allowed to grow the connection cache to */ + + long max_host_connections; /* if >0, a fixed limit of the maximum number + of connections per host */ + + long max_total_connections; /* if >0, a fixed limit of the maximum number + of connections in total */ + + /* timer callback and user data pointer for the *socket() API */ + curl_multi_timer_callback timer_cb; + void *timer_userp; + struct curltime timer_lastcall; /* the fixed time for the timeout for the + previous callback */ + bool in_callback; /* true while executing a callback */ +}; + +#endif /* HEADER_CURL_MULTIHANDLE_H */ diff --git a/libcurl/lib/multiif.h b/libcurl/lib/multiif.h new file mode 100644 index 0000000..a644558 --- /dev/null +++ b/libcurl/lib/multiif.h @@ -0,0 +1,99 @@ +#ifndef HEADER_CURL_MULTIIF_H +#define HEADER_CURL_MULTIIF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Prototypes for library-wide functions provided by multi.c + */ + +void Curl_updatesocket(struct Curl_easy *data); +void Curl_expire(struct Curl_easy *data, time_t milli, expire_id); +void Curl_expire_clear(struct Curl_easy *data); +void Curl_expire_done(struct Curl_easy *data, expire_id id); +void Curl_update_timer(struct Curl_multi *multi); +void Curl_attach_connnection(struct Curl_easy *data, + struct connectdata *conn); +bool Curl_multiplex_wanted(const struct Curl_multi *multi); +void Curl_set_in_callback(struct Curl_easy *data, bool value); +bool Curl_is_in_callback(struct Curl_easy *easy); + +/* Internal version of curl_multi_init() accepts size parameters for the + socket and connection hashes */ +struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize); + +/* the write bits start at bit 16 for the *getsock() bitmap */ +#define GETSOCK_WRITEBITSTART 16 + +#define GETSOCK_BLANK 0 /* no bits set */ + +/* set the bit for the given sock number to make the bitmap for writable */ +#define GETSOCK_WRITESOCK(x) (1 << (GETSOCK_WRITEBITSTART + (x))) + +/* set the bit for the given sock number to make the bitmap for readable */ +#define GETSOCK_READSOCK(x) (1 << (x)) + +#ifdef DEBUGBUILD + /* + * Curl_multi_dump is not a stable public function, this is only meant to + * allow easier tracking of the internal handle's state and what sockets + * they use. Only for research and development DEBUGBUILD enabled builds. + */ +void Curl_multi_dump(struct Curl_multi *multi); +#endif + +/* Return the value of the CURLMOPT_MAX_HOST_CONNECTIONS option */ +size_t Curl_multi_max_host_connections(struct Curl_multi *multi); + +/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */ +size_t Curl_multi_max_total_connections(struct Curl_multi *multi); + +void Curl_multiuse_state(struct connectdata *conn, + int bundlestate); /* use BUNDLE_* defines */ + +/* + * Curl_multi_closed() + * + * Used by the connect code to tell the multi_socket code that one of the + * sockets we were using is about to be closed. This function will then + * remove it from the sockethash for this handle to make the multi_socket API + * behave properly, especially for the case when libcurl will create another + * socket again and it gets the same file descriptor number. + */ + +void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s); + +/* + * Add a handle and move it into PERFORM state at once. For pushed streams. + */ +CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, + struct Curl_easy *data, + struct connectdata *conn); + +CURLMcode Curl_multi_wait(struct Curl_multi *multi, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret, + bool *gotsocket); /* if any socket was checked */ + +#endif /* HEADER_CURL_MULTIIF_H */ diff --git a/libcurl/lib/netrc.c b/libcurl/lib/netrc.c new file mode 100644 index 0000000..f41636e --- /dev/null +++ b/libcurl/lib/netrc.c @@ -0,0 +1,245 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#ifndef CURL_DISABLE_NETRC + +#ifdef HAVE_PWD_H +#include +#endif + +#include +#include "netrc.h" +#include "strtok.h" +#include "strcase.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* Get user and password from .netrc when given a machine name */ + +enum host_lookup_state { + NOTHING, + HOSTFOUND, /* the 'machine' keyword was found */ + HOSTVALID /* this is "our" machine! */ +}; + +/* + * @unittest: 1304 + * + * *loginp and *passwordp MUST be allocated if they aren't NULL when passed + * in. + */ +int Curl_parsenetrc(const char *host, + char **loginp, + char **passwordp, + bool *login_changed, + bool *password_changed, + char *netrcfile) +{ + FILE *file; + int retcode = 1; + char *login = *loginp; + char *password = *passwordp; + bool specific_login = (login && *login != 0); + bool login_alloc = FALSE; + bool password_alloc = FALSE; + bool netrc_alloc = FALSE; + enum host_lookup_state state = NOTHING; + + char state_login = 0; /* Found a login keyword */ + char state_password = 0; /* Found a password keyword */ + int state_our_login = FALSE; /* With specific_login, found *our* login + name */ + +#define NETRC DOT_CHAR "netrc" + + if(!netrcfile) { + bool home_alloc = FALSE; + char *home = curl_getenv("HOME"); /* portable environment reader */ + if(home) { + home_alloc = TRUE; +#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) + } + else { + struct passwd pw, *pw_res; + char pwbuf[1024]; + if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) + && pw_res) { + home = strdup(pw.pw_dir); + if(!home) + return -1; + home_alloc = TRUE; + } +#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) + } + else { + struct passwd *pw; + pw = getpwuid(geteuid()); + if(pw) { + home = pw->pw_dir; + } +#endif + } + + if(!home) + return retcode; /* no home directory found (or possibly out of memory) */ + + netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC); + if(home_alloc) + free(home); + if(!netrcfile) { + return -1; + } + netrc_alloc = TRUE; + } + + file = fopen(netrcfile, FOPEN_READTEXT); + if(netrc_alloc) + free(netrcfile); + if(file) { + char *tok; + char *tok_buf; + bool done = FALSE; + char netrcbuffer[4096]; + int netrcbuffsize = (int)sizeof(netrcbuffer); + + while(!done && fgets(netrcbuffer, netrcbuffsize, file)) { + tok = strtok_r(netrcbuffer, " \t\n", &tok_buf); + if(tok && *tok == '#') + /* treat an initial hash as a comment line */ + continue; + while(!done && tok) { + + if((login && *login) && (password && *password)) { + done = TRUE; + break; + } + + switch(state) { + case NOTHING: + if(strcasecompare("machine", tok)) { + /* the next tok is the machine name, this is in itself the + delimiter that starts the stuff entered for this machine, + after this we need to search for 'login' and + 'password'. */ + state = HOSTFOUND; + } + else if(strcasecompare("default", tok)) { + state = HOSTVALID; + retcode = 0; /* we did find our host */ + } + break; + case HOSTFOUND: + if(strcasecompare(host, tok)) { + /* and yes, this is our host! */ + state = HOSTVALID; + retcode = 0; /* we did find our host */ + } + else + /* not our host */ + state = NOTHING; + break; + case HOSTVALID: + /* we are now parsing sub-keywords concerning "our" host */ + if(state_login) { + if(specific_login) { + state_our_login = strcasecompare(login, tok); + } + else if(!login || strcmp(login, tok)) { + if(login_alloc) { + free(login); + login_alloc = FALSE; + } + login = strdup(tok); + if(!login) { + retcode = -1; /* allocation failed */ + goto out; + } + login_alloc = TRUE; + } + state_login = 0; + } + else if(state_password) { + if((state_our_login || !specific_login) + && (!password || strcmp(password, tok))) { + if(password_alloc) { + free(password); + password_alloc = FALSE; + } + password = strdup(tok); + if(!password) { + retcode = -1; /* allocation failed */ + goto out; + } + password_alloc = TRUE; + } + state_password = 0; + } + else if(strcasecompare("login", tok)) + state_login = 1; + else if(strcasecompare("password", tok)) + state_password = 1; + else if(strcasecompare("machine", tok)) { + /* ok, there's machine here go => */ + state = HOSTFOUND; + state_our_login = FALSE; + } + break; + } /* switch (state) */ + + tok = strtok_r(NULL, " \t\n", &tok_buf); + } /* while(tok) */ + } /* while fgets() */ + + out: + if(!retcode) { + *login_changed = FALSE; + *password_changed = FALSE; + if(login_alloc) { + if(*loginp) + free(*loginp); + *loginp = login; + *login_changed = TRUE; + } + if(password_alloc) { + if(*passwordp) + free(*passwordp); + *passwordp = password; + *password_changed = TRUE; + } + } + else { + if(login_alloc) + free(login); + if(password_alloc) + free(password); + } + fclose(file); + } + + return retcode; +} + +#endif diff --git a/libcurl/lib/netrc.h b/libcurl/lib/netrc.h new file mode 100644 index 0000000..7f56c4b --- /dev/null +++ b/libcurl/lib/netrc.h @@ -0,0 +1,45 @@ +#ifndef HEADER_CURL_NETRC_H +#define HEADER_CURL_NETRC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#ifndef CURL_DISABLE_NETRC + +/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */ +int Curl_parsenetrc(const char *host, + char **loginp, + char **passwordp, + bool *login_changed, + bool *password_changed, + char *filename); + /* Assume: (*passwordp)[0]=0, host[0] != 0. + * If (*loginp)[0] = 0, search for login and password within a machine + * section in the netrc. + * If (*loginp)[0] != 0, search for password within machine and login. + */ +#else +/* disabled */ +#define Curl_parsenetrc(a,b,c,d,e,f) 1 +#endif + +#endif /* HEADER_CURL_NETRC_H */ diff --git a/libcurl/lib/non-ascii.c b/libcurl/lib/non-ascii.c new file mode 100644 index 0000000..42beaec --- /dev/null +++ b/libcurl/lib/non-ascii.c @@ -0,0 +1,332 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef CURL_DOES_CONVERSIONS + +#include + +#include "non-ascii.h" +#include "formdata.h" +#include "sendf.h" +#include "urldata.h" +#include "multiif.h" + +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +#ifdef HAVE_ICONV +#include +/* set default codesets for iconv */ +#ifndef CURL_ICONV_CODESET_OF_NETWORK +#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1" +#endif +#ifndef CURL_ICONV_CODESET_FOR_UTF8 +#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8" +#endif +#define ICONV_ERROR (size_t)-1 +#endif /* HAVE_ICONV */ + +/* + * Curl_convert_clone() returns a malloced copy of the source string (if + * returning CURLE_OK), with the data converted to network format. + */ +CURLcode Curl_convert_clone(struct Curl_easy *data, + const char *indata, + size_t insize, + char **outbuf) +{ + char *convbuf; + CURLcode result; + + convbuf = malloc(insize); + if(!convbuf) + return CURLE_OUT_OF_MEMORY; + + memcpy(convbuf, indata, insize); + result = Curl_convert_to_network(data, convbuf, insize); + if(result) { + free(convbuf); + return result; + } + + *outbuf = convbuf; /* return the converted buffer */ + + return CURLE_OK; +} + +/* + * Curl_convert_to_network() is an internal function for performing ASCII + * conversions on non-ASCII platforms. It converts the buffer _in place_. + */ +CURLcode Curl_convert_to_network(struct Curl_easy *data, + char *buffer, size_t length) +{ + if(data && data->set.convtonetwork) { + /* use translation callback */ + CURLcode result; + Curl_set_in_callback(data, true); + result = data->set.convtonetwork(buffer, length); + Curl_set_in_callback(data, false); + if(result) { + failf(data, + "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s", + (int)result, curl_easy_strerror(result)); + } + + return result; + } + else { +#ifdef HAVE_ICONV + /* do the translation ourselves */ + iconv_t tmpcd = (iconv_t) -1; + iconv_t *cd = &tmpcd; + char *input_ptr, *output_ptr; + size_t in_bytes, out_bytes, rc; + + /* open an iconv conversion descriptor if necessary */ + if(data) + cd = &data->outbound_cd; + if(*cd == (iconv_t)-1) { + *cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK, + CURL_ICONV_CODESET_OF_HOST); + if(*cd == (iconv_t)-1) { + failf(data, + "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s", + CURL_ICONV_CODESET_OF_NETWORK, + CURL_ICONV_CODESET_OF_HOST, + errno, strerror(errno)); + return CURLE_CONV_FAILED; + } + } + /* call iconv */ + input_ptr = output_ptr = buffer; + in_bytes = out_bytes = length; + rc = iconv(*cd, &input_ptr, &in_bytes, + &output_ptr, &out_bytes); + if(!data) + iconv_close(tmpcd); + if((rc == ICONV_ERROR) || (in_bytes != 0)) { + failf(data, + "The Curl_convert_to_network iconv call failed with errno %i: %s", + errno, strerror(errno)); + return CURLE_CONV_FAILED; + } +#else + failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required"); + return CURLE_CONV_REQD; +#endif /* HAVE_ICONV */ + } + + return CURLE_OK; +} + +/* + * Curl_convert_from_network() is an internal function for performing ASCII + * conversions on non-ASCII platforms. It converts the buffer _in place_. + */ +CURLcode Curl_convert_from_network(struct Curl_easy *data, + char *buffer, size_t length) +{ + if(data && data->set.convfromnetwork) { + /* use translation callback */ + CURLcode result; + Curl_set_in_callback(data, true); + result = data->set.convfromnetwork(buffer, length); + Curl_set_in_callback(data, false); + if(result) { + failf(data, + "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s", + (int)result, curl_easy_strerror(result)); + } + + return result; + } + else { +#ifdef HAVE_ICONV + /* do the translation ourselves */ + iconv_t tmpcd = (iconv_t) -1; + iconv_t *cd = &tmpcd; + char *input_ptr, *output_ptr; + size_t in_bytes, out_bytes, rc; + + /* open an iconv conversion descriptor if necessary */ + if(data) + cd = &data->inbound_cd; + if(*cd == (iconv_t)-1) { + *cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, + CURL_ICONV_CODESET_OF_NETWORK); + if(*cd == (iconv_t)-1) { + failf(data, + "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s", + CURL_ICONV_CODESET_OF_HOST, + CURL_ICONV_CODESET_OF_NETWORK, + errno, strerror(errno)); + return CURLE_CONV_FAILED; + } + } + /* call iconv */ + input_ptr = output_ptr = buffer; + in_bytes = out_bytes = length; + rc = iconv(*cd, &input_ptr, &in_bytes, + &output_ptr, &out_bytes); + if(!data) + iconv_close(tmpcd); + if((rc == ICONV_ERROR) || (in_bytes != 0)) { + failf(data, + "Curl_convert_from_network iconv call failed with errno %i: %s", + errno, strerror(errno)); + return CURLE_CONV_FAILED; + } +#else + failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required"); + return CURLE_CONV_REQD; +#endif /* HAVE_ICONV */ + } + + return CURLE_OK; +} + +/* + * Curl_convert_from_utf8() is an internal function for performing UTF-8 + * conversions on non-ASCII platforms. + */ +CURLcode Curl_convert_from_utf8(struct Curl_easy *data, + char *buffer, size_t length) +{ + if(data && data->set.convfromutf8) { + /* use translation callback */ + CURLcode result; + Curl_set_in_callback(data, true); + result = data->set.convfromutf8(buffer, length); + Curl_set_in_callback(data, false); + if(result) { + failf(data, + "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s", + (int)result, curl_easy_strerror(result)); + } + + return result; + } + else { +#ifdef HAVE_ICONV + /* do the translation ourselves */ + iconv_t tmpcd = (iconv_t) -1; + iconv_t *cd = &tmpcd; + char *input_ptr; + char *output_ptr; + size_t in_bytes, out_bytes, rc; + + /* open an iconv conversion descriptor if necessary */ + if(data) + cd = &data->utf8_cd; + if(*cd == (iconv_t)-1) { + *cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, + CURL_ICONV_CODESET_FOR_UTF8); + if(*cd == (iconv_t)-1) { + failf(data, + "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s", + CURL_ICONV_CODESET_OF_HOST, + CURL_ICONV_CODESET_FOR_UTF8, + errno, strerror(errno)); + return CURLE_CONV_FAILED; + } + } + /* call iconv */ + input_ptr = output_ptr = buffer; + in_bytes = out_bytes = length; + rc = iconv(*cd, &input_ptr, &in_bytes, + &output_ptr, &out_bytes); + if(!data) + iconv_close(tmpcd); + if((rc == ICONV_ERROR) || (in_bytes != 0)) { + failf(data, + "The Curl_convert_from_utf8 iconv call failed with errno %i: %s", + errno, strerror(errno)); + return CURLE_CONV_FAILED; + } + if(output_ptr < input_ptr) { + /* null terminate the now shorter output string */ + *output_ptr = 0x00; + } +#else + failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required"); + return CURLE_CONV_REQD; +#endif /* HAVE_ICONV */ + } + + return CURLE_OK; +} + +/* + * Init conversion stuff for a Curl_easy + */ +void Curl_convert_init(struct Curl_easy *data) +{ +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) + /* conversion descriptors for iconv calls */ + data->outbound_cd = (iconv_t)-1; + data->inbound_cd = (iconv_t)-1; + data->utf8_cd = (iconv_t)-1; +#else + (void)data; +#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ +} + +/* + * Setup conversion stuff for a Curl_easy + */ +void Curl_convert_setup(struct Curl_easy *data) +{ + data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, + CURL_ICONV_CODESET_OF_NETWORK); + data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK, + CURL_ICONV_CODESET_OF_HOST); + data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, + CURL_ICONV_CODESET_FOR_UTF8); +} + +/* + * Close conversion stuff for a Curl_easy + */ + +void Curl_convert_close(struct Curl_easy *data) +{ +#ifdef HAVE_ICONV + /* close iconv conversion descriptors */ + if(data->inbound_cd != (iconv_t)-1) { + iconv_close(data->inbound_cd); + } + if(data->outbound_cd != (iconv_t)-1) { + iconv_close(data->outbound_cd); + } + if(data->utf8_cd != (iconv_t)-1) { + iconv_close(data->utf8_cd); + } +#else + (void)data; +#endif /* HAVE_ICONV */ +} + +#endif /* CURL_DOES_CONVERSIONS */ diff --git a/libcurl/lib/non-ascii.h b/libcurl/lib/non-ascii.h new file mode 100644 index 0000000..5fb5771 --- /dev/null +++ b/libcurl/lib/non-ascii.h @@ -0,0 +1,61 @@ +#ifndef HEADER_CURL_NON_ASCII_H +#define HEADER_CURL_NON_ASCII_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef CURL_DOES_CONVERSIONS + +#include "urldata.h" + +/* + * Curl_convert_clone() returns a malloced copy of the source string (if + * returning CURLE_OK), with the data converted to network format. + * + * If no conversion was needed *outbuf may be NULL. + */ +CURLcode Curl_convert_clone(struct Curl_easy *data, + const char *indata, + size_t insize, + char **outbuf); + +void Curl_convert_init(struct Curl_easy *data); +void Curl_convert_setup(struct Curl_easy *data); +void Curl_convert_close(struct Curl_easy *data); + +CURLcode Curl_convert_to_network(struct Curl_easy *data, + char *buffer, size_t length); +CURLcode Curl_convert_from_network(struct Curl_easy *data, + char *buffer, size_t length); +CURLcode Curl_convert_from_utf8(struct Curl_easy *data, + char *buffer, size_t length); +#else +#define Curl_convert_clone(a,b,c,d) ((void)a, CURLE_OK) +#define Curl_convert_init(x) Curl_nop_stmt +#define Curl_convert_setup(x) Curl_nop_stmt +#define Curl_convert_close(x) Curl_nop_stmt +#define Curl_convert_to_network(a,b,c) ((void)a, CURLE_OK) +#define Curl_convert_from_network(a,b,c) ((void)a, CURLE_OK) +#define Curl_convert_from_utf8(a,b,c) ((void)a, CURLE_OK) +#endif + +#endif /* HEADER_CURL_NON_ASCII_H */ diff --git a/libcurl/lib/nonblock.c b/libcurl/lib/nonblock.c new file mode 100644 index 0000000..4d105c1 --- /dev/null +++ b/libcurl/lib/nonblock.c @@ -0,0 +1,91 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif + +#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE)) +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#include "nonblock.h" + +/* + * curlx_nonblock() set the given socket to either blocking or non-blocking + * mode based on the 'nonblock' boolean argument. This function is highly + * portable. + */ +int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ + int nonblock /* TRUE or FALSE */) +{ +#if defined(USE_BLOCKING_SOCKETS) + (void)sockfd; + (void)nonblock; + return 0; /* returns success */ + +#elif defined(HAVE_FCNTL_O_NONBLOCK) + + /* most recent unix versions */ + int flags; + flags = sfcntl(sockfd, F_GETFL, 0); + if(nonblock) + return sfcntl(sockfd, F_SETFL, flags | O_NONBLOCK); + return sfcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); + +#elif defined(HAVE_IOCTL_FIONBIO) + + /* older unix versions */ + int flags = nonblock ? 1 : 0; + return ioctl(sockfd, FIONBIO, &flags); + +#elif defined(HAVE_IOCTLSOCKET_FIONBIO) + + /* Windows */ + unsigned long flags = nonblock ? 1UL : 0UL; + return ioctlsocket(sockfd, FIONBIO, &flags); + +#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO) + + /* Amiga */ + long flags = nonblock ? 1L : 0L; + return IoctlSocket(sockfd, FIONBIO, (char *)&flags); + +#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK) + + /* BeOS */ + long b = nonblock ? 1L : 0L; + return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); + +#else +# error "no non-blocking method was found/used/set" +#endif +} diff --git a/libcurl/lib/nonblock.h b/libcurl/lib/nonblock.h new file mode 100644 index 0000000..eb18ea1 --- /dev/null +++ b/libcurl/lib/nonblock.h @@ -0,0 +1,30 @@ +#ifndef HEADER_CURL_NONBLOCK_H +#define HEADER_CURL_NONBLOCK_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include /* for curl_socket_t */ + +int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ + int nonblock /* TRUE or FALSE */); + +#endif /* HEADER_CURL_NONBLOCK_H */ diff --git a/libcurl/lib/nwlib.c b/libcurl/lib/nwlib.c new file mode 100644 index 0000000..7bf5f51 --- /dev/null +++ b/libcurl/lib/nwlib.c @@ -0,0 +1,328 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef NETWARE /* Novell NetWare */ + +#ifdef __NOVELL_LIBC__ +/* For native LibC-based NLM we need to register as a real lib. */ +#include +#include +#include +#include +#include + +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +typedef struct +{ + int _errno; + void *twentybytes; +} libthreaddata_t; + +typedef struct +{ + int x; + int y; + int z; + void *tenbytes; + NXKey_t perthreadkey; /* if -1, no key obtained... */ + NXMutex_t *lock; +} libdata_t; + +int gLibId = -1; +void *gLibHandle = (void *) NULL; +rtag_t gAllocTag = (rtag_t) NULL; +NXMutex_t *gLibLock = (NXMutex_t *) NULL; + +/* internal library function prototypes... */ +int DisposeLibraryData(void *); +void DisposeThreadData(void *); +int GetOrSetUpData(int id, libdata_t **data, libthreaddata_t **threaddata); + + +int _NonAppStart(void *NLMHandle, + void *errorScreen, + const char *cmdLine, + const char *loadDirPath, + size_t uninitializedDataLength, + void *NLMFileHandle, + int (*readRoutineP)(int conn, + void *fileHandle, size_t offset, + size_t nbytes, + size_t *bytesRead, + void *buffer), + size_t customDataOffset, + size_t customDataSize, + int messageCount, + const char **messages) +{ + NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0); + +#ifndef __GNUC__ +#pragma unused(cmdLine) +#pragma unused(loadDirPath) +#pragma unused(uninitializedDataLength) +#pragma unused(NLMFileHandle) +#pragma unused(readRoutineP) +#pragma unused(customDataOffset) +#pragma unused(customDataSize) +#pragma unused(messageCount) +#pragma unused(messages) +#endif + + /* + * Here we process our command line, post errors (to the error screen), + * perform initializations and anything else we need to do before being able + * to accept calls into us. If we succeed, we return non-zero and the NetWare + * Loader will leave us up, otherwise we fail to load and get dumped. + */ + gAllocTag = AllocateResourceTag(NLMHandle, + " memory allocations", + AllocSignature); + + if(!gAllocTag) { + OutputToScreen(errorScreen, "Unable to allocate resource tag for " + "library memory allocations.\n"); + return -1; + } + + gLibId = register_library(DisposeLibraryData); + + if(gLibId < -1) { + OutputToScreen(errorScreen, "Unable to register library with kernel.\n"); + return -1; + } + + gLibHandle = NLMHandle; + + gLibLock = NXMutexAlloc(0, 0, &liblock); + + if(!gLibLock) { + OutputToScreen(errorScreen, "Unable to allocate library data lock.\n"); + return -1; + } + + return 0; +} + +/* + * Here we clean up any resources we allocated. Resource tags is a big part + * of what we created, but NetWare doesn't ask us to free those. + */ +void _NonAppStop(void) +{ + (void) unregister_library(gLibId); + NXMutexFree(gLibLock); +} + +/* + * This function cannot be the first in the file for if the file is linked + * first, then the check-unload function's offset will be nlmname.nlm+0 + * which is how to tell that there isn't one. When the check function is + * first in the linked objects, it is ambiguous. For this reason, we will + * put it inside this file after the stop function. + * + * Here we check to see if it's alright to ourselves to be unloaded. If not, + * we return a non-zero value. Right now, there isn't any reason not to allow + * it. + */ +int _NonAppCheckUnload(void) +{ + return 0; +} + +int GetOrSetUpData(int id, libdata_t **appData, + libthreaddata_t **threadData) +{ + int err; + libdata_t *app_data; + libthreaddata_t *thread_data; + NXKey_t key; + NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0); + + err = 0; + thread_data = (libthreaddata_t *) NULL; + + /* + * Attempt to get our data for the application calling us. This is where we + * store whatever application-specific information we need to carry in + * support of calling applications. + */ + app_data = (libdata_t *) get_app_data(id); + + if(!app_data) { + /* + * This application hasn't called us before; set up application AND + * per-thread data. Of course, just in case a thread from this same + * application is calling us simultaneously, we better lock our application + * data-creation mutex. We also need to recheck for data after we acquire + * the lock because WE might be that other thread that was too late to + * create the data and the first thread in will have created it. + */ + NXLock(gLibLock); + + app_data = (libdata_t *) get_app_data(id); + if(!app_data) { + app_data = calloc(1, sizeof(libdata_t)); + + if(app_data) { + app_data->tenbytes = malloc(10); + app_data->lock = NXMutexAlloc(0, 0, &liblock); + + if(!app_data->tenbytes || !app_data->lock) { + if(app_data->lock) + NXMutexFree(app_data->lock); + free(app_data->tenbytes); + free(app_data); + app_data = (libdata_t *) NULL; + err = ENOMEM; + } + + if(app_data) { + /* + * Here we burn in the application data that we were trying to get + * by calling get_app_data(). Next time we call the first function, + * we'll get this data we're just now setting. We also go on here to + * establish the per-thread data for the calling thread, something + * we'll have to do on each application thread the first time + * it calls us. + */ + err = set_app_data(gLibId, app_data); + + if(err) { + if(app_data->lock) + NXMutexFree(app_data->lock); + free(app_data->tenbytes); + free(app_data); + app_data = (libdata_t *) NULL; + err = ENOMEM; + } + else { + /* create key for thread-specific data... */ + err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key); + + if(err) /* (no more keys left?) */ + key = -1; + + app_data->perthreadkey = key; + } + } + } + } + + NXUnlock(gLibLock); + } + + if(app_data) { + key = app_data->perthreadkey; + + if(key != -1 /* couldn't create a key? no thread data */ + && !(err = NXKeyGetValue(key, (void **) &thread_data)) + && !thread_data) { + /* + * Allocate the per-thread data for the calling thread. Regardless of + * whether there was already application data or not, this may be the + * first call by a new thread. The fact that we allocation 20 bytes on + * a pointer is not very important, this just helps to demonstrate that + * we can have arbitrarily complex per-thread data. + */ + thread_data = malloc(sizeof(libthreaddata_t)); + + if(thread_data) { + thread_data->_errno = 0; + thread_data->twentybytes = malloc(20); + + if(!thread_data->twentybytes) { + free(thread_data); + thread_data = (libthreaddata_t *) NULL; + err = ENOMEM; + } + + err = NXKeySetValue(key, thread_data); + if(err) { + free(thread_data->twentybytes); + free(thread_data); + thread_data = (libthreaddata_t *) NULL; + } + } + } + } + + if(appData) + *appData = app_data; + + if(threadData) + *threadData = thread_data; + + return err; +} + +int DisposeLibraryData(void *data) +{ + if(data) { + void *tenbytes = ((libdata_t *) data)->tenbytes; + + free(tenbytes); + free(data); + } + + return 0; +} + +void DisposeThreadData(void *data) +{ + if(data) { + void *twentybytes = ((libthreaddata_t *) data)->twentybytes; + + free(twentybytes); + free(data); + } +} + +#else /* __NOVELL_LIBC__ */ +/* For native CLib-based NLM seems we can do a bit more simple. */ +#include + +int main(void) +{ + /* initialize any globals here... */ + + /* do this if any global initializing was done + SynchronizeStart(); + */ + ExitThread(TSR_THREAD, 0); + return 0; +} + +#endif /* __NOVELL_LIBC__ */ + +#else /* NETWARE */ + +#ifdef __POCC__ +# pragma warn(disable:2024) /* Disable warning #2024: Empty input file */ +#endif + +#endif /* NETWARE */ diff --git a/libcurl/lib/nwos.c b/libcurl/lib/nwos.c new file mode 100644 index 0000000..c6c22cc --- /dev/null +++ b/libcurl/lib/nwos.c @@ -0,0 +1,88 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef NETWARE /* Novell NetWare */ + +#ifdef __NOVELL_LIBC__ +/* For native LibC-based NLM we need to do nothing. */ +int netware_init(void) +{ + return 0; +} + +#else /* __NOVELL_LIBC__ */ + +/* For native CLib-based NLM we need to initialize the LONG namespace. */ +#include +#include +#include +/* Make the CLIB Ctx stuff link */ +#include +NETDB_DEFINE_CONTEXT +/* Make the CLIB Inet stuff link */ +#include +#include +NETINET_DEFINE_CONTEXT + +int netware_init(void) +{ + int rc = 0; + unsigned int myHandle = GetNLMHandle(); + /* import UnAugmentAsterisk dynamically for NW4.x compatibility */ + void (*pUnAugmentAsterisk)(int) = (void(*)(int)) + ImportSymbol(myHandle, "UnAugmentAsterisk"); + /* import UseAccurateCaseForPaths dynamically for NW3.x compatibility */ + void (*pUseAccurateCaseForPaths)(int) = (void(*)(int)) + ImportSymbol(myHandle, "UseAccurateCaseForPaths"); + if(pUnAugmentAsterisk) + pUnAugmentAsterisk(1); + if(pUseAccurateCaseForPaths) + pUseAccurateCaseForPaths(1); + UnimportSymbol(myHandle, "UnAugmentAsterisk"); + UnimportSymbol(myHandle, "UseAccurateCaseForPaths"); + /* set long name space */ + if((SetCurrentNameSpace(4) == 255)) { + rc = 1; + } + if((SetTargetNameSpace(4) == 255)) { + rc = rc + 2; + } + return rc; +} + +/* dummy function to satisfy newer prelude */ +int __init_environment(void) +{ + return 0; +} + +/* dummy function to satisfy newer prelude */ +int __deinit_environment(void) +{ + return 0; +} + +#endif /* __NOVELL_LIBC__ */ + +#endif /* NETWARE */ diff --git a/libcurl/lib/objnames-test08.sh b/libcurl/lib/objnames-test08.sh new file mode 100644 index 0000000..4859757 --- /dev/null +++ b/libcurl/lib/objnames-test08.sh @@ -0,0 +1,217 @@ +#!/bin/sh +# *************************************************************************** +# * _ _ ____ _ +# * Project ___| | | | _ \| | +# * / __| | | | |_) | | +# * | (__| |_| | _ <| |___ +# * \___|\___/|_| \_\_____| +# * +# * Copyright (C) 2013, Daniel Stenberg, , et al. +# * +# * This software is licensed as described in the file COPYING, which +# * you should have received as part of this distribution. The terms +# * are also available at https://curl.haxx.se/docs/copyright.html. +# * +# * You may opt to use, copy, modify, merge, publish, distribute and/or sell +# * copies of the Software, and permit persons to whom the Software is +# * furnished to do so, under the terms of the COPYING file. +# * +# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# * KIND, either express or implied. +# * +# *************************************************************************** + +# +# This Bourne shell script file is used by test case 1222 to do +# unit testing of curl_8char_object_name() shell function which +# is defined in file objnames.inc and sourced by this file and +# any other shell script that may use it. +# + +# +# argument validation +# + +if test $# -eq 1; then + : +else + echo "Usage: ${0} srcdir" + exit 1 +fi + +if test -f "${1}/runtests.pl"; then + : +else + echo "${0}: Wrong srcdir" + exit 1 +fi + +srcdir=${1} + +if test -f "$srcdir/../lib/objnames.inc"; then + : +else + echo "$0: Missing objnames.inc" + exit 1 +fi + +# +# Some variables +# + +logdir=log +tstnum=1222 + +list_c=$logdir/${tstnum}_list_c +list_obj=$logdir/${tstnum}_list_obj +list_obj_c=$logdir/${tstnum}_list_obj_c +list_obj_uniq=$logdir/${tstnum}_list_obj_uniq + + +# +# Source curl_8char_object_name() function definition +# + +. $srcdir/../lib/objnames.inc + +# +# Some curl_8char_object_name() unit tests +# + +echo 'Testing curl_8char_object_name...' +echo "" + +argstr=123__678__ABC__FGH__KLM__PQRSTUV +expect=16AFKPQR +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123__678__ABC__FGH__KLM__PQ.S.UV +expect=16AFKPQ +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123__678__ABC..FGH..KLM..PQRSTUV +expect=16ABC +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123__678_.ABC._FGH__KLM__PQRSTUV +expect=16 +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123.567.90ABCDEFGHIJKLMNOPQRSTUV +expect=123 +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=1234567.90A.CDEFGHIJKLMNOPQRSTUV +expect=1234567 +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=1234567890.BCD.FGHIJKLMNOPQRSTUV +expect=12345678 +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=12=45-78+0AB.DE.GHIJKLMNOPQRSTUV +expect=1470AB +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV +expect=12345678 +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123_567_90A_CDE_GHIJKLMNOPQRSTUV +expect=159CGHIJ +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123_567_90A_CDEFGHIJKLMNOPQRSTUV +expect=159CDEFG +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123_567_90ABCDEFGHIJKLMNOPQRSTUV +expect=1590ABCD +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123_567890ABCDEFGHIJKLMNOPQRSTUV +expect=1567890A +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV +expect=12345678 +outstr=`curl_8char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +# +# Verify that generated object name is distinct for +# all *.c source files in lib and src subdirectories. +# + +ls $srcdir/../lib/*.c > $list_c +ls $srcdir/../src/*.c >> $list_c + +rm -f $list_obj + +for c_fname in `cat $list_c`; do + obj_name=`curl_8char_object_name $c_fname` + echo "$obj_name" >> $list_obj +done + +sort -u $list_obj > $list_obj_uniq + +cnt_c=`cat $list_c | wc -l` +cnt_u=`cat $list_obj_uniq | wc -l` + +echo "" +echo "" +echo "" +if test $cnt_c -eq $cnt_u; then + echo "8-characters-or-less generated object names are unique." + obj_name_clash="no" +else + echo "8-characters-or-less generated object names are clashing..." + obj_name_clash="yes" +fi + +if test $obj_name_clash = "yes"; then + # + # Show clashing object names and respective source file names + # + echo "" + paste $list_obj $list_c | sort > $list_obj_c + prev_match="no" + prev_line="unknown" + prev_obj_name="unknown" + while read this_line; do + obj_name=`echo "$this_line" | cut -f1` + if test "x$obj_name" = "x$prev_obj_name"; then + if test "x$prev_match" != "xyes"; then + echo "$prev_line" + echo "$this_line" + prev_match="yes" + else + echo "$this_line" + fi + else + prev_match="no" + fi + prev_line=$this_line + prev_obj_name=$obj_name + done < $list_obj_c +fi + +rm -f $list_c +rm -f $list_obj +rm -f $list_obj_c +rm -f $list_obj_uniq + +# end of objnames-test.sh diff --git a/libcurl/lib/objnames-test10.sh b/libcurl/lib/objnames-test10.sh new file mode 100644 index 0000000..62184b8 --- /dev/null +++ b/libcurl/lib/objnames-test10.sh @@ -0,0 +1,217 @@ +#!/bin/sh +# *************************************************************************** +# * _ _ ____ _ +# * Project ___| | | | _ \| | +# * / __| | | | |_) | | +# * | (__| |_| | _ <| |___ +# * \___|\___/|_| \_\_____| +# * +# * Copyright (C) 2013, Daniel Stenberg, , et al. +# * +# * This software is licensed as described in the file COPYING, which +# * you should have received as part of this distribution. The terms +# * are also available at https://curl.haxx.se/docs/copyright.html. +# * +# * You may opt to use, copy, modify, merge, publish, distribute and/or sell +# * copies of the Software, and permit persons to whom the Software is +# * furnished to do so, under the terms of the COPYING file. +# * +# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# * KIND, either express or implied. +# * +# *************************************************************************** + +# +# This Bourne shell script file is used by test case 1221 to do +# unit testing of curl_10char_object_name() shell function which +# is defined in file objnames.inc and sourced by this file and +# any other shell script that may use it. +# + +# +# argument validation +# + +if test $# -eq 1; then + : +else + echo "Usage: ${0} srcdir" + exit 1 +fi + +if test -f "${1}/runtests.pl"; then + : +else + echo "${0}: Wrong srcdir" + exit 1 +fi + +srcdir=${1} + +if test -f "$srcdir/../lib/objnames.inc"; then + : +else + echo "$0: Missing objnames.inc" + exit 1 +fi + +# +# Some variables +# + +logdir=log +tstnum=1221 + +list_c=$logdir/${tstnum}_list_c +list_obj=$logdir/${tstnum}_list_obj +list_obj_c=$logdir/${tstnum}_list_obj_c +list_obj_uniq=$logdir/${tstnum}_list_obj_uniq + + +# +# Source curl_10char_object_name() function definition +# + +. $srcdir/../lib/objnames.inc + +# +# Some curl_10char_object_name() unit tests +# + +echo 'Testing curl_10char_object_name...' +echo "" + +argstr=123__678__ABC__FGH__KLM__PQRSTUV +expect=16AFKPQRST +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123__678__ABC__FGH__KLM__PQ.S.UV +expect=16AFKPQ +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123__678__ABC..FGH..KLM..PQRSTUV +expect=16ABC +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123__678_.ABC._FGH__KLM__PQRSTUV +expect=16 +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123.567.90ABCDEFGHIJKLMNOPQRSTUV +expect=123 +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=1234567.90A.CDEFGHIJKLMNOPQRSTUV +expect=1234567 +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=1234567890.BCD.FGHIJKLMNOPQRSTUV +expect=1234567890 +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=12=45-78+0AB.DE.GHIJKLMNOPQRSTUV +expect=1470AB +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV +expect=1234567890 +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123_567_90A_CDE_GHIJKLMNOPQRSTUV +expect=159CGHIJKL +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123_567_90A_CDEFGHIJKLMNOPQRSTUV +expect=159CDEFGHI +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123_567_90ABCDEFGHIJKLMNOPQRSTUV +expect=1590ABCDEF +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=123_567890ABCDEFGHIJKLMNOPQRSTUV +expect=1567890ABC +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV +expect=1234567890 +outstr=`curl_10char_object_name $argstr` +echo "result: $outstr expected: $expect input: $argstr" + +# +# Verify that generated object name is distinct for +# all *.c source files in lib and src subdirectories. +# + +ls $srcdir/../lib/*.c > $list_c +ls $srcdir/../src/*.c >> $list_c + +rm -f $list_obj + +for c_fname in `cat $list_c`; do + obj_name=`curl_10char_object_name $c_fname` + echo "$obj_name" >> $list_obj +done + +sort -u $list_obj > $list_obj_uniq + +cnt_c=`cat $list_c | wc -l` +cnt_u=`cat $list_obj_uniq | wc -l` + +echo "" +echo "" +echo "" +if test $cnt_c -eq $cnt_u; then + echo "10-characters-or-less generated object names are unique." + obj_name_clash="no" +else + echo "10-characters-or-less generated object names are clashing..." + obj_name_clash="yes" +fi + +if test $obj_name_clash = "yes"; then + # + # Show clashing object names and respective source file names + # + echo "" + paste $list_obj $list_c | sort > $list_obj_c + prev_match="no" + prev_line="unknown" + prev_obj_name="unknown" + while read this_line; do + obj_name=`echo "$this_line" | cut -f1` + if test "x$obj_name" = "x$prev_obj_name"; then + if test "x$prev_match" != "xyes"; then + echo "$prev_line" + echo "$this_line" + prev_match="yes" + else + echo "$this_line" + fi + else + prev_match="no" + fi + prev_line=$this_line + prev_obj_name=$obj_name + done < $list_obj_c +fi + +rm -f $list_c +rm -f $list_obj +rm -f $list_obj_c +rm -f $list_obj_uniq + +# end of objnames-test10.sh diff --git a/libcurl/lib/objnames.inc b/libcurl/lib/objnames.inc new file mode 100644 index 0000000..6a5b2a8 --- /dev/null +++ b/libcurl/lib/objnames.inc @@ -0,0 +1,107 @@ +# *************************************************************************** +# * _ _ ____ _ +# * Project ___| | | | _ \| | +# * / __| | | | |_) | | +# * | (__| |_| | _ <| |___ +# * \___|\___/|_| \_\_____| +# * +# * Copyright (C) 2012 - 2017, Daniel Stenberg, , et al. +# * +# * This software is licensed as described in the file COPYING, which +# * you should have received as part of this distribution. The terms +# * are also available at https://curl.haxx.se/docs/copyright.html. +# * +# * You may opt to use, copy, modify, merge, publish, distribute and/or sell +# * copies of the Software, and permit persons to whom the Software is +# * furnished to do so, under the terms of the COPYING file. +# * +# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# * KIND, either express or implied. +# * +# *************************************************************************** + +# +# This file is sourced from curl/packages/OS400/initscript.sh and +# other Bourne shell scripts. Keep it as portable as possible. +# + +# +# curl_10char_object_name +# +# This shell function accepts a single string argument with unspecified +# length representing a (*.c) source file name and returns a string which +# is a transformation of given argument. +# +# The intended purpose of this function is to transliterate a (*.c) source +# file name that may be longer than 10 characters, or not, into a string +# with at most 10 characters which may be used as an OS/400 object name. +# +# This function might not be universally useful, nor we care about it. +# +# It is intended to be used with libcurl's (*.c) source file names, so +# dependency on libcurl's source file naming scheme is acceptable and +# good enough for its intended use. Specifically it makes use of the fact +# that libcurl's (*.c) source file names which may be longer than 10 chars +# are conformed with underscore '_' separated substrings, or separated by +# other character which does not belong to the [0-9], [a-z] or [A-Z] sets. +# +# This allows repeatable and automatic short object name generation with +# no need for a hardcoded mapping table. +# +# Transformation is done in the following way: +# +# 1) Leading directory components are removed. +# 2) Leftmost dot character and any other char following it are removed. +# 3) Lowercase characters are transliterated to uppercase. +# 4) Characters not in [A-Z] or [0-9] are transliterated to underscore '_'. +# 5) Every sequence of one or more underscores is replaced with a single one. +# 6) Five leftmost substrings which end in an underscore character are +# replaced by the first character of each substring, while retaining +# the rest of the string. +# 7) Finally the result is truncated to 10 characters. +# +# Resulting object name may be shorter than 10 characters. +# +# Test case 1221 does unit testng of this function and also verifies +# that it is possible to generate distinct short object names for all +# curl and libcurl *.c source file names. +# + +curl_10char_object_name() { + echo "${1}" | \ + sed -e 's:.*/::' \ + -e 's:[.].*::' \ + -e 'y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:' \ + -e 's:[^ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_]:_:g' \ + -e 's:__*:_:g' \ + -e 's:\([^_]\)[^_]*_\(.*\):\1\2:' \ + -e 's:\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3:' \ + -e 's:\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4:' \ + -e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5:' \ + -e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5\6:' \ + -e 's:^\(..........\).*:\1:' +} + +# +# curl_8char_object_name +# +# Same as curl_10char_object_name() description and details above, except +# that object name is limited to 8 charcters maximum. +# + +curl_8char_object_name() { + echo "${1}" | \ + sed -e 's:.*/::' \ + -e 's:[.].*::' \ + -e 'y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:' \ + -e 's:[^ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_]:_:g' \ + -e 's:__*:_:g' \ + -e 's:\([^_]\)[^_]*_\(.*\):\1\2:' \ + -e 's:\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3:' \ + -e 's:\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4:' \ + -e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5:' \ + -e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5\6:' \ + -e 's:^\(........\).*:\1:' +} + +# end of objectname.inc diff --git a/libcurl/lib/openldap.c b/libcurl/lib/openldap.c new file mode 100644 index 0000000..eeab2c7 --- /dev/null +++ b/libcurl/lib/openldap.c @@ -0,0 +1,758 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2010, Howard Chu, + * Copyright (C) 2011 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP) + +/* + * Notice that USE_OPENLDAP is only a source code selection switch. When + * libcurl is built with USE_OPENLDAP defined the libcurl source code that + * gets compiled is the code from openldap.c, otherwise the code that gets + * compiled is the code from ldap.c. + * + * When USE_OPENLDAP is defined a recent version of the OpenLDAP library + * might be required for compilation and runtime. In order to use ancient + * OpenLDAP library versions, USE_OPENLDAP shall not be defined. + */ + +#include + +#include "urldata.h" +#include +#include "sendf.h" +#include "vtls/vtls.h" +#include "transfer.h" +#include "curl_ldap.h" +#include "curl_base64.h" +#include "connect.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Uncommenting this will enable the built-in debug logging of the openldap + * library. The debug log level can be set using the CURL_OPENLDAP_TRACE + * environment variable. The debug output is written to stderr. + * + * The library supports the following debug flags: + * LDAP_DEBUG_NONE 0x0000 + * LDAP_DEBUG_TRACE 0x0001 + * LDAP_DEBUG_CONSTRUCT 0x0002 + * LDAP_DEBUG_DESTROY 0x0004 + * LDAP_DEBUG_PARAMETER 0x0008 + * LDAP_DEBUG_ANY 0xffff + * + * For example, use CURL_OPENLDAP_TRACE=0 for no debug, + * CURL_OPENLDAP_TRACE=2 for LDAP_DEBUG_CONSTRUCT messages only, + * CURL_OPENLDAP_TRACE=65535 for all debug message levels. + */ +/* #define CURL_OPENLDAP_DEBUG */ + +#ifndef _LDAP_PVT_H +extern int ldap_pvt_url_scheme2proto(const char *); +extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url, + LDAP **ld); +#endif + +static CURLcode ldap_setup_connection(struct connectdata *conn); +static CURLcode ldap_do(struct connectdata *conn, bool *done); +static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool); +static CURLcode ldap_connect(struct connectdata *conn, bool *done); +static CURLcode ldap_connecting(struct connectdata *conn, bool *done); +static CURLcode ldap_disconnect(struct connectdata *conn, bool dead); + +static Curl_recv ldap_recv; + +/* + * LDAP protocol handler. + */ + +const struct Curl_handler Curl_handler_ldap = { + "LDAP", /* scheme */ + ldap_setup_connection, /* setup_connection */ + ldap_do, /* do_it */ + ldap_done, /* done */ + ZERO_NULL, /* do_more */ + ldap_connect, /* connect_it */ + ldap_connecting, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ldap_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_LDAP, /* defport */ + CURLPROTO_LDAP, /* protocol */ + PROTOPT_NONE /* flags */ +}; + +#ifdef USE_SSL +/* + * LDAPS protocol handler. + */ + +const struct Curl_handler Curl_handler_ldaps = { + "LDAPS", /* scheme */ + ldap_setup_connection, /* setup_connection */ + ldap_do, /* do_it */ + ldap_done, /* done */ + ZERO_NULL, /* do_more */ + ldap_connect, /* connect_it */ + ldap_connecting, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ldap_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_LDAPS, /* defport */ + CURLPROTO_LDAP, /* protocol */ + PROTOPT_SSL /* flags */ +}; +#endif + +static const char *url_errs[] = { + "success", + "out of memory", + "bad parameter", + "unrecognized scheme", + "unbalanced delimiter", + "bad URL", + "bad host or port", + "bad or missing attributes", + "bad or missing scope", + "bad or missing filter", + "bad or missing extensions" +}; + +typedef struct ldapconninfo { + LDAP *ld; + Curl_recv *recv; /* for stacking SSL handler */ + Curl_send *send; + int proto; + int msgid; + bool ssldone; + bool sslinst; + bool didbind; +} ldapconninfo; + +typedef struct ldapreqinfo { + int msgid; + int nument; +} ldapreqinfo; + +static CURLcode ldap_setup_connection(struct connectdata *conn) +{ + ldapconninfo *li; + LDAPURLDesc *lud; + struct Curl_easy *data = conn->data; + int rc, proto; + CURLcode status; + + rc = ldap_url_parse(data->change.url, &lud); + if(rc != LDAP_URL_SUCCESS) { + const char *msg = "url parsing problem"; + status = CURLE_URL_MALFORMAT; + if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) { + if(rc == LDAP_URL_ERR_MEM) + status = CURLE_OUT_OF_MEMORY; + msg = url_errs[rc]; + } + failf(conn->data, "LDAP local: %s", msg); + return status; + } + proto = ldap_pvt_url_scheme2proto(lud->lud_scheme); + ldap_free_urldesc(lud); + + li = calloc(1, sizeof(ldapconninfo)); + if(!li) + return CURLE_OUT_OF_MEMORY; + li->proto = proto; + conn->proto.generic = li; + connkeep(conn, "OpenLDAP default"); + return CURLE_OK; +} + +#ifdef USE_SSL +static Sockbuf_IO ldapsb_tls; +#endif + +static CURLcode ldap_connect(struct connectdata *conn, bool *done) +{ + ldapconninfo *li = conn->proto.generic; + struct Curl_easy *data = conn->data; + int rc, proto = LDAP_VERSION3; + char hosturl[1024]; + char *ptr; + + (void)done; + + strcpy(hosturl, "ldap"); + ptr = hosturl + 4; + if(conn->handler->flags & PROTOPT_SSL) + *ptr++ = 's'; + msnprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d", + conn->host.name, conn->remote_port); + +#ifdef CURL_OPENLDAP_DEBUG + static int do_trace = 0; + const char *env = getenv("CURL_OPENLDAP_TRACE"); + do_trace = (env && strtol(env, NULL, 10) > 0); + if(do_trace) { + ldap_set_option(li->ld, LDAP_OPT_DEBUG_LEVEL, &do_trace); + } +#endif + + rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld); + if(rc) { + failf(data, "LDAP local: Cannot connect to %s, %s", + hosturl, ldap_err2string(rc)); + return CURLE_COULDNT_CONNECT; + } + + ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto); + +#ifdef USE_SSL + if(conn->handler->flags & PROTOPT_SSL) { + CURLcode result; + result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone); + if(result) + return result; + } +#endif + + return CURLE_OK; +} + +static CURLcode ldap_connecting(struct connectdata *conn, bool *done) +{ + ldapconninfo *li = conn->proto.generic; + struct Curl_easy *data = conn->data; + LDAPMessage *msg = NULL; + struct timeval tv = {0, 1}, *tvp; + int rc, err; + char *info = NULL; + +#ifdef USE_SSL + if(conn->handler->flags & PROTOPT_SSL) { + /* Is the SSL handshake complete yet? */ + if(!li->ssldone) { + CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, + &li->ssldone); + if(result || !li->ssldone) + return result; + } + + /* Have we installed the libcurl SSL handlers into the sockbuf yet? */ + if(!li->sslinst) { + Sockbuf *sb; + ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb); + ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn); + li->sslinst = TRUE; + li->recv = conn->recv[FIRSTSOCKET]; + li->send = conn->send[FIRSTSOCKET]; + } + } +#endif + + tvp = &tv; + + retry: + if(!li->didbind) { + char *binddn; + struct berval passwd; + + if(conn->bits.user_passwd) { + binddn = conn->user; + passwd.bv_val = conn->passwd; + passwd.bv_len = strlen(passwd.bv_val); + } + else { + binddn = NULL; + passwd.bv_val = NULL; + passwd.bv_len = 0; + } + rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd, + NULL, NULL, &li->msgid); + if(rc) + return CURLE_LDAP_CANNOT_BIND; + li->didbind = TRUE; + if(tvp) + return CURLE_OK; + } + + rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg); + if(rc < 0) { + failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc)); + return CURLE_LDAP_CANNOT_BIND; + } + if(rc == 0) { + /* timed out */ + return CURLE_OK; + } + + rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1); + if(rc) { + failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc)); + return CURLE_LDAP_CANNOT_BIND; + } + + /* Try to fallback to LDAPv2? */ + if(err == LDAP_PROTOCOL_ERROR) { + int proto; + ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto); + if(proto == LDAP_VERSION3) { + if(info) { + ldap_memfree(info); + info = NULL; + } + proto = LDAP_VERSION2; + ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto); + li->didbind = FALSE; + goto retry; + } + } + + if(err) { + failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc), + info ? info : ""); + if(info) + ldap_memfree(info); + return CURLE_LOGIN_DENIED; + } + + if(info) + ldap_memfree(info); + conn->recv[FIRSTSOCKET] = ldap_recv; + *done = TRUE; + + return CURLE_OK; +} + +static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection) +{ + ldapconninfo *li = conn->proto.generic; + (void) dead_connection; + + if(li) { + if(li->ld) { + ldap_unbind_ext(li->ld, NULL, NULL); + li->ld = NULL; + } + conn->proto.generic = NULL; + free(li); + } + return CURLE_OK; +} + +static CURLcode ldap_do(struct connectdata *conn, bool *done) +{ + ldapconninfo *li = conn->proto.generic; + ldapreqinfo *lr; + CURLcode status = CURLE_OK; + int rc = 0; + LDAPURLDesc *ludp = NULL; + int msgid; + struct Curl_easy *data = conn->data; + + connkeep(conn, "OpenLDAP do"); + + infof(data, "LDAP local: %s\n", data->change.url); + + rc = ldap_url_parse(data->change.url, &ludp); + if(rc != LDAP_URL_SUCCESS) { + const char *msg = "url parsing problem"; + status = CURLE_URL_MALFORMAT; + if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) { + if(rc == LDAP_URL_ERR_MEM) + status = CURLE_OUT_OF_MEMORY; + msg = url_errs[rc]; + } + failf(conn->data, "LDAP local: %s", msg); + return status; + } + + rc = ldap_search_ext(li->ld, ludp->lud_dn, ludp->lud_scope, + ludp->lud_filter, ludp->lud_attrs, 0, + NULL, NULL, NULL, 0, &msgid); + ldap_free_urldesc(ludp); + if(rc != LDAP_SUCCESS) { + failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc)); + return CURLE_LDAP_SEARCH_FAILED; + } + lr = calloc(1, sizeof(ldapreqinfo)); + if(!lr) + return CURLE_OUT_OF_MEMORY; + lr->msgid = msgid; + data->req.protop = lr; + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); + *done = TRUE; + return CURLE_OK; +} + +static CURLcode ldap_done(struct connectdata *conn, CURLcode res, + bool premature) +{ + ldapreqinfo *lr = conn->data->req.protop; + + (void)res; + (void)premature; + + if(lr) { + /* if there was a search in progress, abandon it */ + if(lr->msgid) { + ldapconninfo *li = conn->proto.generic; + ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL); + lr->msgid = 0; + } + conn->data->req.protop = NULL; + free(lr); + } + + return CURLE_OK; +} + +static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf, + size_t len, CURLcode *err) +{ + ldapconninfo *li = conn->proto.generic; + struct Curl_easy *data = conn->data; + ldapreqinfo *lr = data->req.protop; + int rc, ret; + LDAPMessage *msg = NULL; + LDAPMessage *ent; + BerElement *ber = NULL; + struct timeval tv = {0, 1}; + + (void)len; + (void)buf; + (void)sockindex; + + rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg); + if(rc < 0) { + failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc)); + *err = CURLE_RECV_ERROR; + return -1; + } + + *err = CURLE_AGAIN; + ret = -1; + + /* timed out */ + if(!msg) + return ret; + + for(ent = ldap_first_message(li->ld, msg); ent; + ent = ldap_next_message(li->ld, ent)) { + struct berval bv, *bvals; + int binary = 0, msgtype; + CURLcode writeerr; + + msgtype = ldap_msgtype(ent); + if(msgtype == LDAP_RES_SEARCH_RESULT) { + int code; + char *info = NULL; + rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0); + if(rc) { + failf(data, "LDAP local: search ldap_parse_result %s", + ldap_err2string(rc)); + *err = CURLE_LDAP_SEARCH_FAILED; + } + else if(code && code != LDAP_SIZELIMIT_EXCEEDED) { + failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc), + info ? info : ""); + *err = CURLE_LDAP_SEARCH_FAILED; + } + else { + /* successful */ + if(code == LDAP_SIZELIMIT_EXCEEDED) + infof(data, "There are more than %d entries\n", lr->nument); + data->req.size = data->req.bytecount; + *err = CURLE_OK; + ret = 0; + } + lr->msgid = 0; + ldap_memfree(info); + break; + } + else if(msgtype != LDAP_RES_SEARCH_ENTRY) + continue; + + lr->nument++; + rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv); + if(rc < 0) { + *err = CURLE_RECV_ERROR; + return -1; + } + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4); + if(writeerr) { + *err = writeerr; + return -1; + } + + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, + bv.bv_len); + if(writeerr) { + *err = writeerr; + return -1; + } + + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); + if(writeerr) { + *err = writeerr; + return -1; + } + data->req.bytecount += bv.bv_len + 5; + + for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals); + rc == LDAP_SUCCESS; + rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals)) { + int i; + + if(bv.bv_val == NULL) + break; + + if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7)) + binary = 1; + else + binary = 0; + + if(bvals == NULL) { + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); + if(writeerr) { + *err = writeerr; + return -1; + } + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, + bv.bv_len); + if(writeerr) { + *err = writeerr; + return -1; + } + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":\n", 2); + if(writeerr) { + *err = writeerr; + return -1; + } + data->req.bytecount += bv.bv_len + 3; + continue; + } + + for(i = 0; bvals[i].bv_val != NULL; i++) { + int binval = 0; + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); + if(writeerr) { + *err = writeerr; + return -1; + } + + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, + bv.bv_len); + if(writeerr) { + *err = writeerr; + return -1; + } + + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1); + if(writeerr) { + *err = writeerr; + return -1; + } + data->req.bytecount += bv.bv_len + 2; + + if(!binary) { + /* check for leading or trailing whitespace */ + if(ISSPACE(bvals[i].bv_val[0]) || + ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1])) + binval = 1; + else { + /* check for unprintable characters */ + unsigned int j; + for(j = 0; jreq.bytecount += 2; + if(val_b64_sz > 0) { + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, + val_b64_sz); + if(writeerr) { + *err = writeerr; + return -1; + } + free(val_b64); + data->req.bytecount += val_b64_sz; + } + } + else { + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1); + if(writeerr) { + *err = writeerr; + return -1; + } + + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val, + bvals[i].bv_len); + if(writeerr) { + *err = writeerr; + return -1; + } + + data->req.bytecount += bvals[i].bv_len + 1; + } + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); + if(writeerr) { + *err = writeerr; + return -1; + } + + data->req.bytecount++; + } + ber_memfree(bvals); + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); + if(writeerr) { + *err = writeerr; + return -1; + } + data->req.bytecount++; + } + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); + if(writeerr) { + *err = writeerr; + return -1; + } + data->req.bytecount++; + ber_free(ber, 0); + } + ldap_msgfree(msg); + return ret; +} + +#ifdef USE_SSL +static int +ldapsb_tls_setup(Sockbuf_IO_Desc *sbiod, void *arg) +{ + sbiod->sbiod_pvt = arg; + return 0; +} + +static int +ldapsb_tls_remove(Sockbuf_IO_Desc *sbiod) +{ + sbiod->sbiod_pvt = NULL; + return 0; +} + +/* We don't need to do anything because libcurl does it already */ +static int +ldapsb_tls_close(Sockbuf_IO_Desc *sbiod) +{ + (void)sbiod; + return 0; +} + +static int +ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg) +{ + (void)arg; + if(opt == LBER_SB_OPT_DATA_READY) { + struct connectdata *conn = sbiod->sbiod_pvt; + return Curl_ssl_data_pending(conn, FIRSTSOCKET); + } + return 0; +} + +static ber_slen_t +ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) +{ + struct connectdata *conn = sbiod->sbiod_pvt; + ldapconninfo *li = conn->proto.generic; + ber_slen_t ret; + CURLcode err = CURLE_RECV_ERROR; + + ret = (li->recv)(conn, FIRSTSOCKET, buf, len, &err); + if(ret < 0 && err == CURLE_AGAIN) { + SET_SOCKERRNO(EWOULDBLOCK); + } + return ret; +} + +static ber_slen_t +ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) +{ + struct connectdata *conn = sbiod->sbiod_pvt; + ldapconninfo *li = conn->proto.generic; + ber_slen_t ret; + CURLcode err = CURLE_SEND_ERROR; + + ret = (li->send)(conn, FIRSTSOCKET, buf, len, &err); + if(ret < 0 && err == CURLE_AGAIN) { + SET_SOCKERRNO(EWOULDBLOCK); + } + return ret; +} + +static Sockbuf_IO ldapsb_tls = +{ + ldapsb_tls_setup, + ldapsb_tls_remove, + ldapsb_tls_ctrl, + ldapsb_tls_read, + ldapsb_tls_write, + ldapsb_tls_close +}; +#endif /* USE_SSL */ + +#endif /* !CURL_DISABLE_LDAP && USE_OPENLDAP */ diff --git a/libcurl/lib/parsedate.c b/libcurl/lib/parsedate.c new file mode 100644 index 0000000..7ae5eb8 --- /dev/null +++ b/libcurl/lib/parsedate.c @@ -0,0 +1,607 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + A brief summary of the date string formats this parser groks: + + RFC 2616 3.3.1 + + Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 + Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 + Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format + + we support dates without week day name: + + 06 Nov 1994 08:49:37 GMT + 06-Nov-94 08:49:37 GMT + Nov 6 08:49:37 1994 + + without the time zone: + + 06 Nov 1994 08:49:37 + 06-Nov-94 08:49:37 + + weird order: + + 1994 Nov 6 08:49:37 (GNU date fails) + GMT 08:49:37 06-Nov-94 Sunday + 94 6 Nov 08:49:37 (GNU date fails) + + time left out: + + 1994 Nov 6 + 06-Nov-94 + Sun Nov 6 94 + + unusual separators: + + 1994.Nov.6 + Sun/Nov/6/94/GMT + + commonly used time zone names: + + Sun, 06 Nov 1994 08:49:37 CET + 06 Nov 1994 08:49:37 EST + + time zones specified using RFC822 style: + + Sun, 12 Sep 2004 15:05:58 -0700 + Sat, 11 Sep 2004 21:32:11 +0200 + + compact numerical date strings: + + 20040912 15:05:58 -0700 + 20040911 +0200 + +*/ + +#include "curl_setup.h" + +#include + +#include +#include "strcase.h" +#include "warnless.h" +#include "parsedate.h" + +/* + * parsedate() + * + * Returns: + * + * PARSEDATE_OK - a fine conversion + * PARSEDATE_FAIL - failed to convert + * PARSEDATE_LATER - time overflow at the far end of time_t + * PARSEDATE_SOONER - time underflow at the low end of time_t + */ + +static int parsedate(const char *date, time_t *output); + +#define PARSEDATE_OK 0 +#define PARSEDATE_FAIL -1 +#define PARSEDATE_LATER 1 +#define PARSEDATE_SOONER 2 + +#ifndef CURL_DISABLE_PARSEDATE + +const char * const Curl_wkday[] = +{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; +static const char * const weekday[] = +{ "Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday", "Sunday" }; +const char * const Curl_month[]= +{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + +struct tzinfo { + char name[5]; + int offset; /* +/- in minutes */ +}; + +/* Here's a bunch of frequently used time zone names. These were supported + by the old getdate parser. */ +#define tDAYZONE -60 /* offset for daylight savings time */ +static const struct tzinfo tz[]= { + {"GMT", 0}, /* Greenwich Mean */ + {"UT", 0}, /* Universal Time */ + {"UTC", 0}, /* Universal (Coordinated) */ + {"WET", 0}, /* Western European */ + {"BST", 0 tDAYZONE}, /* British Summer */ + {"WAT", 60}, /* West Africa */ + {"AST", 240}, /* Atlantic Standard */ + {"ADT", 240 tDAYZONE}, /* Atlantic Daylight */ + {"EST", 300}, /* Eastern Standard */ + {"EDT", 300 tDAYZONE}, /* Eastern Daylight */ + {"CST", 360}, /* Central Standard */ + {"CDT", 360 tDAYZONE}, /* Central Daylight */ + {"MST", 420}, /* Mountain Standard */ + {"MDT", 420 tDAYZONE}, /* Mountain Daylight */ + {"PST", 480}, /* Pacific Standard */ + {"PDT", 480 tDAYZONE}, /* Pacific Daylight */ + {"YST", 540}, /* Yukon Standard */ + {"YDT", 540 tDAYZONE}, /* Yukon Daylight */ + {"HST", 600}, /* Hawaii Standard */ + {"HDT", 600 tDAYZONE}, /* Hawaii Daylight */ + {"CAT", 600}, /* Central Alaska */ + {"AHST", 600}, /* Alaska-Hawaii Standard */ + {"NT", 660}, /* Nome */ + {"IDLW", 720}, /* International Date Line West */ + {"CET", -60}, /* Central European */ + {"MET", -60}, /* Middle European */ + {"MEWT", -60}, /* Middle European Winter */ + {"MEST", -60 tDAYZONE}, /* Middle European Summer */ + {"CEST", -60 tDAYZONE}, /* Central European Summer */ + {"MESZ", -60 tDAYZONE}, /* Middle European Summer */ + {"FWT", -60}, /* French Winter */ + {"FST", -60 tDAYZONE}, /* French Summer */ + {"EET", -120}, /* Eastern Europe, USSR Zone 1 */ + {"WAST", -420}, /* West Australian Standard */ + {"WADT", -420 tDAYZONE}, /* West Australian Daylight */ + {"CCT", -480}, /* China Coast, USSR Zone 7 */ + {"JST", -540}, /* Japan Standard, USSR Zone 8 */ + {"EAST", -600}, /* Eastern Australian Standard */ + {"EADT", -600 tDAYZONE}, /* Eastern Australian Daylight */ + {"GST", -600}, /* Guam Standard, USSR Zone 9 */ + {"NZT", -720}, /* New Zealand */ + {"NZST", -720}, /* New Zealand Standard */ + {"NZDT", -720 tDAYZONE}, /* New Zealand Daylight */ + {"IDLE", -720}, /* International Date Line East */ + /* Next up: Military timezone names. RFC822 allowed these, but (as noted in + RFC 1123) had their signs wrong. Here we use the correct signs to match + actual military usage. + */ + {"A", 1 * 60}, /* Alpha */ + {"B", 2 * 60}, /* Bravo */ + {"C", 3 * 60}, /* Charlie */ + {"D", 4 * 60}, /* Delta */ + {"E", 5 * 60}, /* Echo */ + {"F", 6 * 60}, /* Foxtrot */ + {"G", 7 * 60}, /* Golf */ + {"H", 8 * 60}, /* Hotel */ + {"I", 9 * 60}, /* India */ + /* "J", Juliet is not used as a timezone, to indicate the observer's local + time */ + {"K", 10 * 60}, /* Kilo */ + {"L", 11 * 60}, /* Lima */ + {"M", 12 * 60}, /* Mike */ + {"N", -1 * 60}, /* November */ + {"O", -2 * 60}, /* Oscar */ + {"P", -3 * 60}, /* Papa */ + {"Q", -4 * 60}, /* Quebec */ + {"R", -5 * 60}, /* Romeo */ + {"S", -6 * 60}, /* Sierra */ + {"T", -7 * 60}, /* Tango */ + {"U", -8 * 60}, /* Uniform */ + {"V", -9 * 60}, /* Victor */ + {"W", -10 * 60}, /* Whiskey */ + {"X", -11 * 60}, /* X-ray */ + {"Y", -12 * 60}, /* Yankee */ + {"Z", 0}, /* Zulu, zero meridian, a.k.a. UTC */ +}; + +/* returns: + -1 no day + 0 monday - 6 sunday +*/ + +static int checkday(const char *check, size_t len) +{ + int i; + const char * const *what; + bool found = FALSE; + if(len > 3) + what = &weekday[0]; + else + what = &Curl_wkday[0]; + for(i = 0; i<7; i++) { + if(strcasecompare(check, what[0])) { + found = TRUE; + break; + } + what++; + } + return found?i:-1; +} + +static int checkmonth(const char *check) +{ + int i; + const char * const *what; + bool found = FALSE; + + what = &Curl_month[0]; + for(i = 0; i<12; i++) { + if(strcasecompare(check, what[0])) { + found = TRUE; + break; + } + what++; + } + return found?i:-1; /* return the offset or -1, no real offset is -1 */ +} + +/* return the time zone offset between GMT and the input one, in number + of seconds or -1 if the timezone wasn't found/legal */ + +static int checktz(const char *check) +{ + unsigned int i; + const struct tzinfo *what; + bool found = FALSE; + + what = tz; + for(i = 0; i< sizeof(tz)/sizeof(tz[0]); i++) { + if(strcasecompare(check, what->name)) { + found = TRUE; + break; + } + what++; + } + return found?what->offset*60:-1; +} + +static void skip(const char **date) +{ + /* skip everything that aren't letters or digits */ + while(**date && !ISALNUM(**date)) + (*date)++; +} + +enum assume { + DATE_MDAY, + DATE_YEAR, + DATE_TIME +}; + +/* this is a clone of 'struct tm' but with all fields we don't need or use + cut out */ +struct my_tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; /* full year */ +}; + +/* struct tm to time since epoch in GMT time zone. + * This is similar to the standard mktime function but for GMT only, and + * doesn't suffer from the various bugs and portability problems that + * some systems' implementations have. + * + * Returns 0 on success, otherwise non-zero. + */ +static void my_timegm(struct my_tm *tm, time_t *t) +{ + static const int month_days_cumulative [12] = + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + int month, year, leap_days; + + year = tm->tm_year; + month = tm->tm_mon; + if(month < 0) { + year += (11 - month) / 12; + month = 11 - (11 - month) % 12; + } + else if(month >= 12) { + year -= month / 12; + month = month % 12; + } + + leap_days = year - (tm->tm_mon <= 1); + leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400) + - (1969 / 4) + (1969 / 100) - (1969 / 400)); + + *t = ((((time_t) (year - 1970) * 365 + + leap_days + month_days_cumulative[month] + tm->tm_mday - 1) * 24 + + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec; +} + +/* + * parsedate() + * + * Returns: + * + * PARSEDATE_OK - a fine conversion + * PARSEDATE_FAIL - failed to convert + * PARSEDATE_LATER - time overflow at the far end of time_t + * PARSEDATE_SOONER - time underflow at the low end of time_t + */ + +static int parsedate(const char *date, time_t *output) +{ + time_t t = 0; + int wdaynum = -1; /* day of the week number, 0-6 (mon-sun) */ + int monnum = -1; /* month of the year number, 0-11 */ + int mdaynum = -1; /* day of month, 1 - 31 */ + int hournum = -1; + int minnum = -1; + int secnum = -1; + int yearnum = -1; + int tzoff = -1; + struct my_tm tm; + enum assume dignext = DATE_MDAY; + const char *indate = date; /* save the original pointer */ + int part = 0; /* max 6 parts */ + + while(*date && (part < 6)) { + bool found = FALSE; + + skip(&date); + + if(ISALPHA(*date)) { + /* a name coming up */ + char buf[32]=""; + size_t len; + if(sscanf(date, "%31[ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz]", buf)) + len = strlen(buf); + else + len = 0; + + if(wdaynum == -1) { + wdaynum = checkday(buf, len); + if(wdaynum != -1) + found = TRUE; + } + if(!found && (monnum == -1)) { + monnum = checkmonth(buf); + if(monnum != -1) + found = TRUE; + } + + if(!found && (tzoff == -1)) { + /* this just must be a time zone string */ + tzoff = checktz(buf); + if(tzoff != -1) + found = TRUE; + } + + if(!found) + return PARSEDATE_FAIL; /* bad string */ + + date += len; + } + else if(ISDIGIT(*date)) { + /* a digit */ + int val; + char *end; + int len = 0; + if((secnum == -1) && + (3 == sscanf(date, "%02d:%02d:%02d%n", + &hournum, &minnum, &secnum, &len))) { + /* time stamp! */ + date += len; + } + else if((secnum == -1) && + (2 == sscanf(date, "%02d:%02d%n", &hournum, &minnum, &len))) { + /* time stamp without seconds */ + date += len; + secnum = 0; + } + else { + long lval; + int error; + int old_errno; + + old_errno = errno; + errno = 0; + lval = strtol(date, &end, 10); + error = errno; + if(errno != old_errno) + errno = old_errno; + + if(error) + return PARSEDATE_FAIL; + +#if LONG_MAX != INT_MAX + if((lval > (long)INT_MAX) || (lval < (long)INT_MIN)) + return PARSEDATE_FAIL; +#endif + + val = curlx_sltosi(lval); + + if((tzoff == -1) && + ((end - date) == 4) && + (val <= 1400) && + (indate< date) && + ((date[-1] == '+' || date[-1] == '-'))) { + /* four digits and a value less than or equal to 1400 (to take into + account all sorts of funny time zone diffs) and it is preceded + with a plus or minus. This is a time zone indication. 1400 is + picked since +1300 is frequently used and +1400 is mentioned as + an edge number in the document "ISO C 200X Proposal: Timezone + Functions" at http://david.tribble.com/text/c0xtimezone.html If + anyone has a more authoritative source for the exact maximum time + zone offsets, please speak up! */ + found = TRUE; + tzoff = (val/100 * 60 + val%100)*60; + + /* the + and - prefix indicates the local time compared to GMT, + this we need their reversed math to get what we want */ + tzoff = date[-1]=='+'?-tzoff:tzoff; + } + + if(((end - date) == 8) && + (yearnum == -1) && + (monnum == -1) && + (mdaynum == -1)) { + /* 8 digits, no year, month or day yet. This is YYYYMMDD */ + found = TRUE; + yearnum = val/10000; + monnum = (val%10000)/100-1; /* month is 0 - 11 */ + mdaynum = val%100; + } + + if(!found && (dignext == DATE_MDAY) && (mdaynum == -1)) { + if((val > 0) && (val<32)) { + mdaynum = val; + found = TRUE; + } + dignext = DATE_YEAR; + } + + if(!found && (dignext == DATE_YEAR) && (yearnum == -1)) { + yearnum = val; + found = TRUE; + if(yearnum < 100) { + if(yearnum > 70) + yearnum += 1900; + else + yearnum += 2000; + } + if(mdaynum == -1) + dignext = DATE_MDAY; + } + + if(!found) + return PARSEDATE_FAIL; + + date = end; + } + } + + part++; + } + + if(-1 == secnum) + secnum = minnum = hournum = 0; /* no time, make it zero */ + + if((-1 == mdaynum) || + (-1 == monnum) || + (-1 == yearnum)) + /* lacks vital info, fail */ + return PARSEDATE_FAIL; + +#ifdef HAVE_TIME_T_UNSIGNED + if(yearnum < 1970) { + /* only positive numbers cannot return earlier */ + *output = TIME_T_MIN; + return PARSEDATE_SOONER; + } +#endif + +#if (SIZEOF_TIME_T < 5) + +#ifdef HAVE_TIME_T_UNSIGNED + /* an unsigned 32 bit time_t can only hold dates to 2106 */ + if(yearnum > 2105) { + *output = TIME_T_MAX; + return PARSEDATE_LATER; + } +#else + /* a signed 32 bit time_t can only hold dates to the beginning of 2038 */ + if(yearnum > 2037) { + *output = TIME_T_MAX; + return PARSEDATE_LATER; + } + if(yearnum < 1903) { + *output = TIME_T_MIN; + return PARSEDATE_SOONER; + } +#endif + +#else + /* The Gregorian calendar was introduced 1582 */ + if(yearnum < 1583) + return PARSEDATE_FAIL; +#endif + + if((mdaynum > 31) || (monnum > 11) || + (hournum > 23) || (minnum > 59) || (secnum > 60)) + return PARSEDATE_FAIL; /* clearly an illegal date */ + + tm.tm_sec = secnum; + tm.tm_min = minnum; + tm.tm_hour = hournum; + tm.tm_mday = mdaynum; + tm.tm_mon = monnum; + tm.tm_year = yearnum; + + /* my_timegm() returns a time_t. time_t is often 32 bits, sometimes even on + architectures that feature 64 bit 'long' but ultimately time_t is the + correct data type to use. + */ + my_timegm(&tm, &t); + + /* Add the time zone diff between local time zone and GMT. */ + if(tzoff == -1) + tzoff = 0; + + if((tzoff > 0) && (t > TIME_T_MAX - tzoff)) { + *output = TIME_T_MAX; + return PARSEDATE_LATER; /* time_t overflow */ + } + + t += tzoff; + + *output = t; + + return PARSEDATE_OK; +} +#else +/* disabled */ +static int parsedate(const char *date, time_t *output) +{ + (void)date; + *output = 0; + return PARSEDATE_OK; /* a lie */ +} +#endif + +time_t curl_getdate(const char *p, const time_t *now) +{ + time_t parsed = -1; + int rc = parsedate(p, &parsed); + (void)now; /* legacy argument from the past that we ignore */ + + if(rc == PARSEDATE_OK) { + if(parsed == -1) + /* avoid returning -1 for a working scenario */ + parsed++; + return parsed; + } + /* everything else is fail */ + return -1; +} + +/* + * Curl_gmtime() is a gmtime() replacement for portability. Do not use the + * gmtime_r() or gmtime() functions anywhere else but here. + * + */ + +CURLcode Curl_gmtime(time_t intime, struct tm *store) +{ + const struct tm *tm; +#ifdef HAVE_GMTIME_R + /* thread-safe version */ + tm = (struct tm *)gmtime_r(&intime, store); +#else + tm = gmtime(&intime); + if(tm) + *store = *tm; /* copy the pointed struct to the local copy */ +#endif + + if(!tm) + return CURLE_BAD_FUNCTION_ARGUMENT; + return CURLE_OK; +} diff --git a/libcurl/lib/parsedate.h b/libcurl/lib/parsedate.h new file mode 100644 index 0000000..8dc3b90 --- /dev/null +++ b/libcurl/lib/parsedate.h @@ -0,0 +1,30 @@ +#ifndef HEADER_CURL_PARSEDATE_H +#define HEADER_CURL_PARSEDATE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +extern const char * const Curl_wkday[7]; +extern const char * const Curl_month[12]; + +CURLcode Curl_gmtime(time_t intime, struct tm *store); + +#endif /* HEADER_CURL_PARSEDATE_H */ diff --git a/libcurl/lib/pingpong.c b/libcurl/lib/pingpong.c new file mode 100644 index 0000000..e9568ee --- /dev/null +++ b/libcurl/lib/pingpong.c @@ -0,0 +1,522 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * 'pingpong' is for generic back-and-forth support functions used by FTP, + * IMAP, POP3, SMTP and whatever more that likes them. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include "urldata.h" +#include "sendf.h" +#include "select.h" +#include "progress.h" +#include "speedcheck.h" +#include "pingpong.h" +#include "multiif.h" +#include "non-ascii.h" +#include "vtls/vtls.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#ifdef USE_PINGPONG + +/* Returns timeout in ms. 0 or negative number means the timeout has already + triggered */ +time_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting) +{ + struct connectdata *conn = pp->conn; + struct Curl_easy *data = conn->data; + time_t timeout_ms; /* in milliseconds */ + long response_time = (data->set.server_response_timeout)? + data->set.server_response_timeout: pp->response_time; + + /* if CURLOPT_SERVER_RESPONSE_TIMEOUT is set, use that to determine + remaining time, or use pp->response because SERVER_RESPONSE_TIMEOUT is + supposed to govern the response for any given server response, not for + the time from connect to the given server response. */ + + /* Without a requested timeout, we only wait 'response_time' seconds for the + full response to arrive before we bail out */ + timeout_ms = response_time - + Curl_timediff(Curl_now(), pp->response); /* spent time */ + + if(data->set.timeout && !disconnecting) { + /* if timeout is requested, find out how much remaining time we have */ + time_t timeout2_ms = data->set.timeout - /* timeout time */ + Curl_timediff(Curl_now(), conn->now); /* spent time */ + + /* pick the lowest number */ + timeout_ms = CURLMIN(timeout_ms, timeout2_ms); + } + + return timeout_ms; +} + +/* + * Curl_pp_statemach() + */ +CURLcode Curl_pp_statemach(struct pingpong *pp, bool block, + bool disconnecting) +{ + struct connectdata *conn = pp->conn; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + int rc; + time_t interval_ms; + time_t timeout_ms = Curl_pp_state_timeout(pp, disconnecting); + struct Curl_easy *data = conn->data; + CURLcode result = CURLE_OK; + + if(timeout_ms <= 0) { + failf(data, "server response timeout"); + return CURLE_OPERATION_TIMEDOUT; /* already too little time */ + } + + if(block) { + interval_ms = 1000; /* use 1 second timeout intervals */ + if(timeout_ms < interval_ms) + interval_ms = timeout_ms; + } + else + interval_ms = 0; /* immediate */ + + if(Curl_ssl_data_pending(conn, FIRSTSOCKET)) + rc = 1; + else if(Curl_pp_moredata(pp)) + /* We are receiving and there is data in the cache so just read it */ + rc = 1; + else if(!pp->sendleft && Curl_ssl_data_pending(conn, FIRSTSOCKET)) + /* We are receiving and there is data ready in the SSL library */ + rc = 1; + else + rc = Curl_socket_check(pp->sendleft?CURL_SOCKET_BAD:sock, /* reading */ + CURL_SOCKET_BAD, + pp->sendleft?sock:CURL_SOCKET_BAD, /* writing */ + interval_ms); + + if(block) { + /* if we didn't wait, we don't have to spend time on this now */ + if(Curl_pgrsUpdate(conn)) + result = CURLE_ABORTED_BY_CALLBACK; + else + result = Curl_speedcheck(data, Curl_now()); + + if(result) + return result; + } + + if(rc == -1) { + failf(data, "select/poll error"); + result = CURLE_OUT_OF_MEMORY; + } + else if(rc) + result = pp->statemach_act(conn); + + return result; +} + +/* initialize stuff to prepare for reading a fresh new response */ +void Curl_pp_init(struct pingpong *pp) +{ + struct connectdata *conn = pp->conn; + pp->nread_resp = 0; + pp->linestart_resp = conn->data->state.buffer; + pp->pending_resp = TRUE; + pp->response = Curl_now(); /* start response time-out now! */ +} + + + +/*********************************************************************** + * + * Curl_pp_vsendf() + * + * Send the formatted string as a command to a pingpong server. Note that + * the string should not have any CRLF appended, as this function will + * append the necessary things itself. + * + * made to never block + */ +CURLcode Curl_pp_vsendf(struct pingpong *pp, + const char *fmt, + va_list args) +{ + ssize_t bytes_written; + size_t write_len; + char *fmt_crlf; + char *s; + CURLcode result; + struct connectdata *conn = pp->conn; + struct Curl_easy *data; + +#ifdef HAVE_GSSAPI + enum protection_level data_sec; +#endif + + DEBUGASSERT(pp->sendleft == 0); + DEBUGASSERT(pp->sendsize == 0); + DEBUGASSERT(pp->sendthis == NULL); + + if(!conn) + /* can't send without a connection! */ + return CURLE_SEND_ERROR; + + data = conn->data; + + fmt_crlf = aprintf("%s\r\n", fmt); /* append a trailing CRLF */ + if(!fmt_crlf) + return CURLE_OUT_OF_MEMORY; + + s = vaprintf(fmt_crlf, args); /* trailing CRLF appended */ + free(fmt_crlf); + if(!s) + return CURLE_OUT_OF_MEMORY; + + bytes_written = 0; + write_len = strlen(s); + + Curl_pp_init(pp); + + result = Curl_convert_to_network(data, s, write_len); + /* Curl_convert_to_network calls failf if unsuccessful */ + if(result) { + free(s); + return result; + } + +#ifdef HAVE_GSSAPI + conn->data_prot = PROT_CMD; +#endif + result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len, + &bytes_written); +#ifdef HAVE_GSSAPI + data_sec = conn->data_prot; + DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST); + conn->data_prot = data_sec; +#endif + + if(result) { + free(s); + return result; + } + + if(conn->data->set.verbose) + Curl_debug(conn->data, CURLINFO_HEADER_OUT, s, (size_t)bytes_written); + + if(bytes_written != (ssize_t)write_len) { + /* the whole chunk was not sent, keep it around and adjust sizes */ + pp->sendthis = s; + pp->sendsize = write_len; + pp->sendleft = write_len - bytes_written; + } + else { + free(s); + pp->sendthis = NULL; + pp->sendleft = pp->sendsize = 0; + pp->response = Curl_now(); + } + + return CURLE_OK; +} + + +/*********************************************************************** + * + * Curl_pp_sendf() + * + * Send the formatted string as a command to a pingpong server. Note that + * the string should not have any CRLF appended, as this function will + * append the necessary things itself. + * + * made to never block + */ +CURLcode Curl_pp_sendf(struct pingpong *pp, + const char *fmt, ...) +{ + CURLcode result; + va_list ap; + va_start(ap, fmt); + + result = Curl_pp_vsendf(pp, fmt, ap); + + va_end(ap); + + return result; +} + +/* + * Curl_pp_readresp() + * + * Reads a piece of a server response. + */ +CURLcode Curl_pp_readresp(curl_socket_t sockfd, + struct pingpong *pp, + int *code, /* return the server code if done */ + size_t *size) /* size of the response */ +{ + ssize_t perline; /* count bytes per line */ + bool keepon = TRUE; + ssize_t gotbytes; + char *ptr; + struct connectdata *conn = pp->conn; + struct Curl_easy *data = conn->data; + char * const buf = data->state.buffer; + CURLcode result = CURLE_OK; + + *code = 0; /* 0 for errors or not done */ + *size = 0; + + ptr = buf + pp->nread_resp; + + /* number of bytes in the current line, so far */ + perline = (ssize_t)(ptr-pp->linestart_resp); + + while((pp->nread_resp < (size_t)data->set.buffer_size) && + (keepon && !result)) { + + if(pp->cache) { + /* we had data in the "cache", copy that instead of doing an actual + * read + * + * pp->cache_size is cast to ssize_t here. This should be safe, because + * it would have been populated with something of size int to begin + * with, even though its datatype may be larger than an int. + */ + if((ptr + pp->cache_size) > (buf + data->set.buffer_size + 1)) { + failf(data, "cached response data too big to handle"); + return CURLE_RECV_ERROR; + } + memcpy(ptr, pp->cache, pp->cache_size); + gotbytes = (ssize_t)pp->cache_size; + free(pp->cache); /* free the cache */ + pp->cache = NULL; /* clear the pointer */ + pp->cache_size = 0; /* zero the size just in case */ + } + else { +#ifdef HAVE_GSSAPI + enum protection_level prot = conn->data_prot; + conn->data_prot = PROT_CLEAR; +#endif + DEBUGASSERT((ptr + data->set.buffer_size - pp->nread_resp) <= + (buf + data->set.buffer_size + 1)); + result = Curl_read(conn, sockfd, ptr, + data->set.buffer_size - pp->nread_resp, + &gotbytes); +#ifdef HAVE_GSSAPI + DEBUGASSERT(prot > PROT_NONE && prot < PROT_LAST); + conn->data_prot = prot; +#endif + if(result == CURLE_AGAIN) + return CURLE_OK; /* return */ + + if(!result && (gotbytes > 0)) + /* convert from the network encoding */ + result = Curl_convert_from_network(data, ptr, gotbytes); + /* Curl_convert_from_network calls failf if unsuccessful */ + + if(result) + /* Set outer result variable to this error. */ + keepon = FALSE; + } + + if(!keepon) + ; + else if(gotbytes <= 0) { + keepon = FALSE; + result = CURLE_RECV_ERROR; + failf(data, "response reading failed"); + } + else { + /* we got a whole chunk of data, which can be anything from one + * byte to a set of lines and possible just a piece of the last + * line */ + ssize_t i; + ssize_t clipamount = 0; + bool restart = FALSE; + + data->req.headerbytecount += (long)gotbytes; + + pp->nread_resp += gotbytes; + for(i = 0; i < gotbytes; ptr++, i++) { + perline++; + if(*ptr == '\n') { + /* a newline is CRLF in pp-talk, so the CR is ignored as + the line isn't really terminated until the LF comes */ + + /* output debug output if that is requested */ +#ifdef HAVE_GSSAPI + if(!conn->sec_complete) +#endif + if(data->set.verbose) + Curl_debug(data, CURLINFO_HEADER_IN, + pp->linestart_resp, (size_t)perline); + + /* + * We pass all response-lines to the callback function registered + * for "headers". The response lines can be seen as a kind of + * headers. + */ + result = Curl_client_write(conn, CLIENTWRITE_HEADER, + pp->linestart_resp, perline); + if(result) + return result; + + if(pp->endofresp(conn, pp->linestart_resp, perline, code)) { + /* This is the end of the last line, copy the last line to the + start of the buffer and zero terminate, for old times sake */ + size_t n = ptr - pp->linestart_resp; + memmove(buf, pp->linestart_resp, n); + buf[n] = 0; /* zero terminate */ + keepon = FALSE; + pp->linestart_resp = ptr + 1; /* advance pointer */ + i++; /* skip this before getting out */ + + *size = pp->nread_resp; /* size of the response */ + pp->nread_resp = 0; /* restart */ + break; + } + perline = 0; /* line starts over here */ + pp->linestart_resp = ptr + 1; + } + } + + if(!keepon && (i != gotbytes)) { + /* We found the end of the response lines, but we didn't parse the + full chunk of data we have read from the server. We therefore need + to store the rest of the data to be checked on the next invoke as + it may actually contain another end of response already! */ + clipamount = gotbytes - i; + restart = TRUE; + DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing " + "server response left\n", + (int)clipamount)); + } + else if(keepon) { + + if((perline == gotbytes) && (gotbytes > data->set.buffer_size/2)) { + /* We got an excessive line without newlines and we need to deal + with it. We keep the first bytes of the line then we throw + away the rest. */ + infof(data, "Excessive server response line length received, " + "%zd bytes. Stripping\n", gotbytes); + restart = TRUE; + + /* we keep 40 bytes since all our pingpong protocols are only + interested in the first piece */ + clipamount = 40; + } + else if(pp->nread_resp > (size_t)data->set.buffer_size/2) { + /* We got a large chunk of data and there's potentially still + trailing data to take care of, so we put any such part in the + "cache", clear the buffer to make space and restart. */ + clipamount = perline; + restart = TRUE; + } + } + else if(i == gotbytes) + restart = TRUE; + + if(clipamount) { + pp->cache_size = clipamount; + pp->cache = malloc(pp->cache_size); + if(pp->cache) + memcpy(pp->cache, pp->linestart_resp, pp->cache_size); + else + return CURLE_OUT_OF_MEMORY; + } + if(restart) { + /* now reset a few variables to start over nicely from the start of + the big buffer */ + pp->nread_resp = 0; /* start over from scratch in the buffer */ + ptr = pp->linestart_resp = buf; + perline = 0; + } + + } /* there was data */ + + } /* while there's buffer left and loop is requested */ + + pp->pending_resp = FALSE; + + return result; +} + +int Curl_pp_getsock(struct pingpong *pp, + curl_socket_t *socks, + int numsocks) +{ + struct connectdata *conn = pp->conn; + + if(!numsocks) + return GETSOCK_BLANK; + + socks[0] = conn->sock[FIRSTSOCKET]; + + if(pp->sendleft) { + /* write mode */ + return GETSOCK_WRITESOCK(0); + } + + /* read mode */ + return GETSOCK_READSOCK(0); +} + +CURLcode Curl_pp_flushsend(struct pingpong *pp) +{ + /* we have a piece of a command still left to send */ + struct connectdata *conn = pp->conn; + ssize_t written; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + CURLcode result = Curl_write(conn, sock, pp->sendthis + pp->sendsize - + pp->sendleft, pp->sendleft, &written); + if(result) + return result; + + if(written != (ssize_t)pp->sendleft) { + /* only a fraction was sent */ + pp->sendleft -= written; + } + else { + free(pp->sendthis); + pp->sendthis = NULL; + pp->sendleft = pp->sendsize = 0; + pp->response = Curl_now(); + } + return CURLE_OK; +} + +CURLcode Curl_pp_disconnect(struct pingpong *pp) +{ + free(pp->cache); + pp->cache = NULL; + return CURLE_OK; +} + +bool Curl_pp_moredata(struct pingpong *pp) +{ + return (!pp->sendleft && pp->cache && pp->nread_resp < pp->cache_size) ? + TRUE : FALSE; +} + +#endif diff --git a/libcurl/lib/pingpong.h b/libcurl/lib/pingpong.h new file mode 100644 index 0000000..dbe1f8d --- /dev/null +++ b/libcurl/lib/pingpong.h @@ -0,0 +1,151 @@ +#ifndef HEADER_CURL_PINGPONG_H +#define HEADER_CURL_PINGPONG_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_FTP) || \ + !defined(CURL_DISABLE_POP3) || !defined(CURL_DISABLE_SMTP) +#define USE_PINGPONG +#endif + +/* forward-declaration, this is defined in urldata.h */ +struct connectdata; + +typedef enum { + FTPTRANSFER_BODY, /* yes do transfer a body */ + FTPTRANSFER_INFO, /* do still go through to get info/headers */ + FTPTRANSFER_NONE, /* don't get anything and don't get info */ + FTPTRANSFER_LAST /* end of list marker, never used */ +} curl_pp_transfer; + +/* + * 'pingpong' is the generic struct used for protocols doing server<->client + * conversations in a back-and-forth style such as FTP, IMAP, POP3, SMTP etc. + * + * It holds response cache and non-blocking sending data. + */ +struct pingpong { + char *cache; /* data cache between getresponse()-calls */ + size_t cache_size; /* size of cache in bytes */ + size_t nread_resp; /* number of bytes currently read of a server response */ + char *linestart_resp; /* line start pointer for the server response + reader function */ + bool pending_resp; /* set TRUE when a server response is pending or in + progress, and is cleared once the last response is + read */ + char *sendthis; /* allocated pointer to a buffer that is to be sent to the + server */ + size_t sendleft; /* number of bytes left to send from the sendthis buffer */ + size_t sendsize; /* total size of the sendthis buffer */ + struct curltime response; /* set to Curl_now() when a command has been sent + off, used to time-out response reading */ + long response_time; /* When no timeout is given, this is the amount of + milliseconds we await for a server response. */ + + struct connectdata *conn; /* points to the connectdata struct that this + belongs to */ + + /* Function pointers the protocols MUST implement and provide for the + pingpong layer to function */ + + CURLcode (*statemach_act)(struct connectdata *conn); + + bool (*endofresp)(struct connectdata *conn, char *ptr, size_t len, + int *code); +}; + +/* + * Curl_pp_statemach() + * + * called repeatedly until done. Set 'wait' to make it wait a while on the + * socket if there's no traffic. + */ +CURLcode Curl_pp_statemach(struct pingpong *pp, bool block, + bool disconnecting); + +/* initialize stuff to prepare for reading a fresh new response */ +void Curl_pp_init(struct pingpong *pp); + +/* Returns timeout in ms. 0 or negative number means the timeout has already + triggered */ +time_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting); + + +/*********************************************************************** + * + * Curl_pp_sendf() + * + * Send the formatted string as a command to a pingpong server. Note that + * the string should not have any CRLF appended, as this function will + * append the necessary things itself. + * + * made to never block + */ +CURLcode Curl_pp_sendf(struct pingpong *pp, + const char *fmt, ...); + +/*********************************************************************** + * + * Curl_pp_vsendf() + * + * Send the formatted string as a command to a pingpong server. Note that + * the string should not have any CRLF appended, as this function will + * append the necessary things itself. + * + * made to never block + */ +CURLcode Curl_pp_vsendf(struct pingpong *pp, + const char *fmt, + va_list args); + +/* + * Curl_pp_readresp() + * + * Reads a piece of a server response. + */ +CURLcode Curl_pp_readresp(curl_socket_t sockfd, + struct pingpong *pp, + int *code, /* return the server code if done */ + size_t *size); /* size of the response */ + + +CURLcode Curl_pp_flushsend(struct pingpong *pp); + +/* call this when a pingpong connection is disconnected */ +CURLcode Curl_pp_disconnect(struct pingpong *pp); + +int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks, + int numsocks); + + +/*********************************************************************** + * + * Curl_pp_moredata() + * + * Returns whether there are still more data in the cache and so a call + * to Curl_pp_readresp() will not block. + */ +bool Curl_pp_moredata(struct pingpong *pp); + +#endif /* HEADER_CURL_PINGPONG_H */ diff --git a/libcurl/lib/pipeline.c b/libcurl/lib/pipeline.c new file mode 100644 index 0000000..4d41b04 --- /dev/null +++ b/libcurl/lib/pipeline.c @@ -0,0 +1,403 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2013, Linus Nielsen Feltzing, + * Copyright (C) 2013 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "urldata.h" +#include "url.h" +#include "progress.h" +#include "multiif.h" +#include "pipeline.h" +#include "sendf.h" +#include "strcase.h" + +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +struct site_blacklist_entry { + struct curl_llist_element list; + unsigned short port; + char hostname[1]; +}; + +static void site_blacklist_llist_dtor(void *user, void *element) +{ + struct site_blacklist_entry *entry = element; + (void)user; + free(entry); +} + +static void server_blacklist_llist_dtor(void *user, void *element) +{ + (void)user; + free(element); +} + +bool Curl_pipeline_penalized(struct Curl_easy *data, + struct connectdata *conn) +{ + if(data) { + bool penalized = FALSE; + curl_off_t penalty_size = + Curl_multi_content_length_penalty_size(data->multi); + curl_off_t chunk_penalty_size = + Curl_multi_chunk_length_penalty_size(data->multi); + curl_off_t recv_size = -2; /* Make it easy to spot in the log */ + + /* Find the head of the recv pipe, if any */ + if(conn->recv_pipe.head) { + struct Curl_easy *recv_handle = conn->recv_pipe.head->ptr; + + recv_size = recv_handle->req.size; + + if(penalty_size > 0 && recv_size > penalty_size) + penalized = TRUE; + } + + if(chunk_penalty_size > 0 && + (curl_off_t)conn->chunk.datasize > chunk_penalty_size) + penalized = TRUE; + + infof(data, "Conn: %ld (%p) Receive pipe weight: (%" + CURL_FORMAT_CURL_OFF_T "/%zu), penalized: %s\n", + conn->connection_id, (void *)conn, recv_size, + conn->chunk.datasize, penalized?"TRUE":"FALSE"); + return penalized; + } + return FALSE; +} + +static CURLcode addHandleToPipeline(struct Curl_easy *data, + struct curl_llist *pipeline) +{ + Curl_llist_insert_next(pipeline, pipeline->tail, data, + &data->pipeline_queue); + return CURLE_OK; +} + + +CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle, + struct connectdata *conn) +{ + struct curl_llist_element *sendhead = conn->send_pipe.head; + struct curl_llist *pipeline; + CURLcode result; + + pipeline = &conn->send_pipe; + + result = addHandleToPipeline(handle, pipeline); + + if(pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head) { + /* this is a new one as head, expire it */ + Curl_pipeline_leave_write(conn); /* not in use yet */ + Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW); + } + +#if 0 /* enable for pipeline debugging */ + print_pipeline(conn); +#endif + + return result; +} + +/* Move this transfer from the sending list to the receiving list. + + Pay special attention to the new sending list "leader" as it needs to get + checked to update what sockets it acts on. + +*/ +void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle, + struct connectdata *conn) +{ + struct curl_llist_element *curr; + + curr = conn->send_pipe.head; + while(curr) { + if(curr->ptr == handle) { + Curl_llist_move(&conn->send_pipe, curr, + &conn->recv_pipe, conn->recv_pipe.tail); + + if(conn->send_pipe.head) { + /* Since there's a new easy handle at the start of the send pipeline, + set its timeout value to 1ms to make it trigger instantly */ + Curl_pipeline_leave_write(conn); /* not used now */ +#ifdef DEBUGBUILD + infof(conn->data, "%p is at send pipe head B!\n", + (void *)conn->send_pipe.head->ptr); +#endif + Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW); + } + + /* The receiver's list is not really interesting here since either this + handle is now first in the list and we'll deal with it soon, or + another handle is already first and thus is already taken care of */ + + break; /* we're done! */ + } + curr = curr->next; + } +} + +bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle, + struct connectdata *conn) +{ + if(handle->multi) { + struct curl_llist *blacklist = + Curl_multi_pipelining_site_bl(handle->multi); + + if(blacklist) { + struct curl_llist_element *curr; + + curr = blacklist->head; + while(curr) { + struct site_blacklist_entry *site; + + site = curr->ptr; + if(strcasecompare(site->hostname, conn->host.name) && + site->port == conn->remote_port) { + infof(handle, "Site %s:%d is pipeline blacklisted\n", + conn->host.name, conn->remote_port); + return TRUE; + } + curr = curr->next; + } + } + } + return FALSE; +} + +CURLMcode Curl_pipeline_set_site_blacklist(char **sites, + struct curl_llist *list) +{ + /* Free the old list */ + if(list->size) + Curl_llist_destroy(list, NULL); + + if(sites) { + Curl_llist_init(list, (curl_llist_dtor) site_blacklist_llist_dtor); + + /* Parse the URLs and populate the list */ + while(*sites) { + char *port; + struct site_blacklist_entry *entry; + + entry = malloc(sizeof(struct site_blacklist_entry) + strlen(*sites)); + if(!entry) { + Curl_llist_destroy(list, NULL); + return CURLM_OUT_OF_MEMORY; + } + strcpy(entry->hostname, *sites); + + port = strchr(entry->hostname, ':'); + if(port) { + *port = '\0'; + port++; + entry->port = (unsigned short)strtol(port, NULL, 10); + } + else { + /* Default port number for HTTP */ + entry->port = 80; + } + + Curl_llist_insert_next(list, list->tail, entry, &entry->list); + sites++; + } + } + + return CURLM_OK; +} + +struct blacklist_node { + struct curl_llist_element list; + char server_name[1]; +}; + +bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle, + char *server_name) +{ + if(handle->multi && server_name) { + struct curl_llist *list = + Curl_multi_pipelining_server_bl(handle->multi); + + struct curl_llist_element *e = list->head; + while(e) { + struct blacklist_node *bl = (struct blacklist_node *)e; + if(strncasecompare(bl->server_name, server_name, + strlen(bl->server_name))) { + infof(handle, "Server %s is blacklisted\n", server_name); + return TRUE; + } + e = e->next; + } + + DEBUGF(infof(handle, "Server %s is not blacklisted\n", server_name)); + } + return FALSE; +} + +CURLMcode Curl_pipeline_set_server_blacklist(char **servers, + struct curl_llist *list) +{ + /* Free the old list */ + if(list->size) + Curl_llist_destroy(list, NULL); + + if(servers) { + Curl_llist_init(list, (curl_llist_dtor) server_blacklist_llist_dtor); + + /* Parse the URLs and populate the list */ + while(*servers) { + struct blacklist_node *n; + size_t len = strlen(*servers); + + n = malloc(sizeof(struct blacklist_node) + len); + if(!n) { + Curl_llist_destroy(list, NULL); + return CURLM_OUT_OF_MEMORY; + } + strcpy(n->server_name, *servers); + + Curl_llist_insert_next(list, list->tail, n, &n->list); + servers++; + } + } + + + return CURLM_OK; +} + +static bool pipe_head(struct Curl_easy *data, + struct curl_llist *pipeline) +{ + if(pipeline) { + struct curl_llist_element *curr = pipeline->head; + if(curr) + return (curr->ptr == data) ? TRUE : FALSE; + } + return FALSE; +} + +/* returns TRUE if the given handle is head of the recv pipe */ +bool Curl_recvpipe_head(struct Curl_easy *data, + struct connectdata *conn) +{ + return pipe_head(data, &conn->recv_pipe); +} + +/* returns TRUE if the given handle is head of the send pipe */ +bool Curl_sendpipe_head(struct Curl_easy *data, + struct connectdata *conn) +{ + return pipe_head(data, &conn->send_pipe); +} + + +/* + * Check if the write channel is available and this handle as at the head, + * then grab the channel and return TRUE. + * + * If not available, return FALSE. + */ + +bool Curl_pipeline_checkget_write(struct Curl_easy *data, + struct connectdata *conn) +{ + if(conn->bits.multiplex) + /* when multiplexing, we can use it at once */ + return TRUE; + + if(!conn->writechannel_inuse && Curl_sendpipe_head(data, conn)) { + /* Grab the channel */ + conn->writechannel_inuse = TRUE; + return TRUE; + } + return FALSE; +} + + +/* + * Check if the read channel is available and this handle as at the head, then + * grab the channel and return TRUE. + * + * If not available, return FALSE. + */ + +bool Curl_pipeline_checkget_read(struct Curl_easy *data, + struct connectdata *conn) +{ + if(conn->bits.multiplex) + /* when multiplexing, we can use it at once */ + return TRUE; + + if(!conn->readchannel_inuse && Curl_recvpipe_head(data, conn)) { + /* Grab the channel */ + conn->readchannel_inuse = TRUE; + return TRUE; + } + return FALSE; +} + +/* + * The current user of the pipeline write channel gives it up. + */ +void Curl_pipeline_leave_write(struct connectdata *conn) +{ + conn->writechannel_inuse = FALSE; +} + +/* + * The current user of the pipeline read channel gives it up. + */ +void Curl_pipeline_leave_read(struct connectdata *conn) +{ + conn->readchannel_inuse = FALSE; +} + + +#if 0 +void print_pipeline(struct connectdata *conn) +{ + struct curl_llist_element *curr; + struct connectbundle *cb_ptr; + struct Curl_easy *data = conn->data; + + cb_ptr = conn->bundle; + + if(cb_ptr) { + curr = cb_ptr->conn_list->head; + while(curr) { + conn = curr->ptr; + infof(data, "- Conn %ld (%p) send_pipe: %zu, recv_pipe: %zu\n", + conn->connection_id, + (void *)conn, + conn->send_pipe->size, + conn->recv_pipe->size); + curr = curr->next; + } + } +} + +#endif diff --git a/libcurl/lib/pipeline.h b/libcurl/lib/pipeline.h new file mode 100644 index 0000000..413ba31 --- /dev/null +++ b/libcurl/lib/pipeline.h @@ -0,0 +1,56 @@ +#ifndef HEADER_CURL_PIPELINE_H +#define HEADER_CURL_PIPELINE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2015 - 2017, Daniel Stenberg, , et al. + * Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle, + struct connectdata *conn); +void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle, + struct connectdata *conn); +bool Curl_pipeline_penalized(struct Curl_easy *data, + struct connectdata *conn); + +bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle, + struct connectdata *conn); + +CURLMcode Curl_pipeline_set_site_blacklist(char **sites, + struct curl_llist *list_ptr); + +bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle, + char *server_name); + +CURLMcode Curl_pipeline_set_server_blacklist(char **servers, + struct curl_llist *list_ptr); + +bool Curl_pipeline_checkget_write(struct Curl_easy *data, + struct connectdata *conn); +bool Curl_pipeline_checkget_read(struct Curl_easy *data, + struct connectdata *conn); +void Curl_pipeline_leave_write(struct connectdata *conn); +void Curl_pipeline_leave_read(struct connectdata *conn); +bool Curl_recvpipe_head(struct Curl_easy *data, + struct connectdata *conn); +bool Curl_sendpipe_head(struct Curl_easy *data, + struct connectdata *conn); + +#endif /* HEADER_CURL_PIPELINE_H */ diff --git a/libcurl/lib/pop3.c b/libcurl/lib/pop3.c new file mode 100644 index 0000000..a681d52 --- /dev/null +++ b/libcurl/lib/pop3.c @@ -0,0 +1,1546 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC1734 POP3 Authentication + * RFC1939 POP3 protocol + * RFC2195 CRAM-MD5 authentication + * RFC2384 POP URL Scheme + * RFC2449 POP3 Extension Mechanism + * RFC2595 Using TLS with IMAP, POP3 and ACAP + * RFC2831 DIGEST-MD5 authentication + * RFC4422 Simple Authentication and Security Layer (SASL) + * RFC4616 PLAIN authentication + * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism + * RFC5034 POP3 SASL Authentication Mechanism + * RFC6749 OAuth 2.0 Authorization Framework + * RFC8314 Use of TLS for Email Submission and Access + * Draft LOGIN SASL Mechanism + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_POP3 + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_UTSNAME_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +#include +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "progress.h" +#include "transfer.h" +#include "escape.h" +#include "http.h" /* for HTTP proxy tunnel stuff */ +#include "socks.h" +#include "pop3.h" +#include "strtoofft.h" +#include "strcase.h" +#include "vtls/vtls.h" +#include "connect.h" +#include "strerror.h" +#include "select.h" +#include "multiif.h" +#include "url.h" +#include "curl_sasl.h" +#include "curl_md5.h" +#include "warnless.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* Local API functions */ +static CURLcode pop3_regular_transfer(struct connectdata *conn, bool *done); +static CURLcode pop3_do(struct connectdata *conn, bool *done); +static CURLcode pop3_done(struct connectdata *conn, CURLcode status, + bool premature); +static CURLcode pop3_connect(struct connectdata *conn, bool *done); +static CURLcode pop3_disconnect(struct connectdata *conn, bool dead); +static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done); +static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); +static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done); +static CURLcode pop3_setup_connection(struct connectdata *conn); +static CURLcode pop3_parse_url_options(struct connectdata *conn); +static CURLcode pop3_parse_url_path(struct connectdata *conn); +static CURLcode pop3_parse_custom_request(struct connectdata *conn); +static CURLcode pop3_perform_auth(struct connectdata *conn, const char *mech, + const char *initresp); +static CURLcode pop3_continue_auth(struct connectdata *conn, const char *resp); +static void pop3_get_message(char *buffer, char **outptr); + +/* + * POP3 protocol handler. + */ + +const struct Curl_handler Curl_handler_pop3 = { + "POP3", /* scheme */ + pop3_setup_connection, /* setup_connection */ + pop3_do, /* do_it */ + pop3_done, /* done */ + ZERO_NULL, /* do_more */ + pop3_connect, /* connect_it */ + pop3_multi_statemach, /* connecting */ + pop3_doing, /* doing */ + pop3_getsock, /* proto_getsock */ + pop3_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + pop3_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_POP3, /* defport */ + CURLPROTO_POP3, /* protocol */ + PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */ + PROTOPT_URLOPTIONS +}; + +#ifdef USE_SSL +/* + * POP3S protocol handler. + */ + +const struct Curl_handler Curl_handler_pop3s = { + "POP3S", /* scheme */ + pop3_setup_connection, /* setup_connection */ + pop3_do, /* do_it */ + pop3_done, /* done */ + ZERO_NULL, /* do_more */ + pop3_connect, /* connect_it */ + pop3_multi_statemach, /* connecting */ + pop3_doing, /* doing */ + pop3_getsock, /* proto_getsock */ + pop3_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + pop3_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_POP3S, /* defport */ + CURLPROTO_POP3S, /* protocol */ + PROTOPT_CLOSEACTION | PROTOPT_SSL + | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */ +}; +#endif + +/* SASL parameters for the pop3 protocol */ +static const struct SASLproto saslpop3 = { + "pop", /* The service name */ + '*', /* Code received when continuation is expected */ + '+', /* Code to receive upon authentication success */ + 255 - 8, /* Maximum initial response length (no max) */ + pop3_perform_auth, /* Send authentication command */ + pop3_continue_auth, /* Send authentication continuation */ + pop3_get_message /* Get SASL response message */ +}; + +#ifdef USE_SSL +static void pop3_to_pop3s(struct connectdata *conn) +{ + /* Change the connection handler */ + conn->handler = &Curl_handler_pop3s; + + /* Set the connection's upgraded to TLS flag */ + conn->tls_upgraded = TRUE; +} +#else +#define pop3_to_pop3s(x) Curl_nop_stmt +#endif + +/*********************************************************************** + * + * pop3_endofresp() + * + * Checks for an ending POP3 status code at the start of the given string, but + * also detects the APOP timestamp from the server greeting and various + * capabilities from the CAPA response including the supported authentication + * types and allowed SASL mechanisms. + */ +static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len, + int *resp) +{ + struct pop3_conn *pop3c = &conn->proto.pop3c; + + /* Do we have an error response? */ + if(len >= 4 && !memcmp("-ERR", line, 4)) { + *resp = '-'; + + return TRUE; + } + + /* Are we processing CAPA command responses? */ + if(pop3c->state == POP3_CAPA) { + /* Do we have the terminating line? */ + if(len >= 1 && line[0] == '.') + /* Treat the response as a success */ + *resp = '+'; + else + /* Treat the response as an untagged continuation */ + *resp = '*'; + + return TRUE; + } + + /* Do we have a success response? */ + if(len >= 3 && !memcmp("+OK", line, 3)) { + *resp = '+'; + + return TRUE; + } + + /* Do we have a continuation response? */ + if(len >= 1 && line[0] == '+') { + *resp = '*'; + + return TRUE; + } + + return FALSE; /* Nothing for us */ +} + +/*********************************************************************** + * + * pop3_get_message() + * + * Gets the authentication message from the response buffer. + */ +static void pop3_get_message(char *buffer, char **outptr) +{ + size_t len = strlen(buffer); + char *message = NULL; + + if(len > 2) { + /* Find the start of the message */ + len -= 2; + for(message = buffer + 2; *message == ' ' || *message == '\t'; + message++, len--) + ; + + /* Find the end of the message */ + for(; len--;) + if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' && + message[len] != '\t') + break; + + /* Terminate the message */ + if(++len) { + message[len] = '\0'; + } + } + else + /* junk input => zero length output */ + message = &buffer[len]; + + *outptr = message; +} + +/*********************************************************************** + * + * state() + * + * This is the ONLY way to change POP3 state! + */ +static void state(struct connectdata *conn, pop3state newstate) +{ + struct pop3_conn *pop3c = &conn->proto.pop3c; +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* for debug purposes */ + static const char * const names[] = { + "STOP", + "SERVERGREET", + "CAPA", + "STARTTLS", + "UPGRADETLS", + "AUTH", + "APOP", + "USER", + "PASS", + "COMMAND", + "QUIT", + /* LAST */ + }; + + if(pop3c->state != newstate) + infof(conn->data, "POP3 %p state change from %s to %s\n", + (void *)pop3c, names[pop3c->state], names[newstate]); +#endif + + pop3c->state = newstate; +} + +/*********************************************************************** + * + * pop3_perform_capa() + * + * Sends the CAPA command in order to obtain a list of server side supported + * capabilities. + */ +static CURLcode pop3_perform_capa(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct pop3_conn *pop3c = &conn->proto.pop3c; + + pop3c->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */ + pop3c->sasl.authused = SASL_AUTH_NONE; /* Clear the auth. mechanism used */ + pop3c->tls_supported = FALSE; /* Clear the TLS capability */ + + /* Send the CAPA command */ + result = Curl_pp_sendf(&pop3c->pp, "%s", "CAPA"); + + if(!result) + state(conn, POP3_CAPA); + + return result; +} + +/*********************************************************************** + * + * pop3_perform_starttls() + * + * Sends the STLS command to start the upgrade to TLS. + */ +static CURLcode pop3_perform_starttls(struct connectdata *conn) +{ + /* Send the STLS command */ + CURLcode result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS"); + + if(!result) + state(conn, POP3_STARTTLS); + + return result; +} + +/*********************************************************************** + * + * pop3_perform_upgrade_tls() + * + * Performs the upgrade to TLS. + */ +static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn) +{ + /* Start the SSL connection */ + struct pop3_conn *pop3c = &conn->proto.pop3c; + CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, + &pop3c->ssldone); + + if(!result) { + if(pop3c->state != POP3_UPGRADETLS) + state(conn, POP3_UPGRADETLS); + + if(pop3c->ssldone) { + pop3_to_pop3s(conn); + result = pop3_perform_capa(conn); + } + } + + return result; +} + +/*********************************************************************** + * + * pop3_perform_user() + * + * Sends a clear text USER command to authenticate with. + */ +static CURLcode pop3_perform_user(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + + /* Check we have a username and password to authenticate with and end the + connect phase if we don't */ + if(!conn->bits.user_passwd) { + state(conn, POP3_STOP); + + return result; + } + + /* Send the USER command */ + result = Curl_pp_sendf(&conn->proto.pop3c.pp, "USER %s", + conn->user ? conn->user : ""); + if(!result) + state(conn, POP3_USER); + + return result; +} + +#ifndef CURL_DISABLE_CRYPTO_AUTH +/*********************************************************************** + * + * pop3_perform_apop() + * + * Sends an APOP command to authenticate with. + */ +static CURLcode pop3_perform_apop(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct pop3_conn *pop3c = &conn->proto.pop3c; + size_t i; + MD5_context *ctxt; + unsigned char digest[MD5_DIGEST_LEN]; + char secret[2 * MD5_DIGEST_LEN + 1]; + + /* Check we have a username and password to authenticate with and end the + connect phase if we don't */ + if(!conn->bits.user_passwd) { + state(conn, POP3_STOP); + + return result; + } + + /* Create the digest */ + ctxt = Curl_MD5_init(Curl_DIGEST_MD5); + if(!ctxt) + return CURLE_OUT_OF_MEMORY; + + Curl_MD5_update(ctxt, (const unsigned char *) pop3c->apoptimestamp, + curlx_uztoui(strlen(pop3c->apoptimestamp))); + + Curl_MD5_update(ctxt, (const unsigned char *) conn->passwd, + curlx_uztoui(strlen(conn->passwd))); + + /* Finalise the digest */ + Curl_MD5_final(ctxt, digest); + + /* Convert the calculated 16 octet digest into a 32 byte hex string */ + for(i = 0; i < MD5_DIGEST_LEN; i++) + msnprintf(&secret[2 * i], 3, "%02x", digest[i]); + + result = Curl_pp_sendf(&pop3c->pp, "APOP %s %s", conn->user, secret); + + if(!result) + state(conn, POP3_APOP); + + return result; +} +#endif + +/*********************************************************************** + * + * pop3_perform_auth() + * + * Sends an AUTH command allowing the client to login with the given SASL + * authentication mechanism. + */ +static CURLcode pop3_perform_auth(struct connectdata *conn, + const char *mech, + const char *initresp) +{ + CURLcode result = CURLE_OK; + struct pop3_conn *pop3c = &conn->proto.pop3c; + + if(initresp) { /* AUTH ... */ + /* Send the AUTH command with the initial response */ + result = Curl_pp_sendf(&pop3c->pp, "AUTH %s %s", mech, initresp); + } + else { + /* Send the AUTH command */ + result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech); + } + + return result; +} + +/*********************************************************************** + * + * pop3_continue_auth() + * + * Sends SASL continuation data or cancellation. + */ +static CURLcode pop3_continue_auth(struct connectdata *conn, + const char *resp) +{ + struct pop3_conn *pop3c = &conn->proto.pop3c; + + return Curl_pp_sendf(&pop3c->pp, "%s", resp); +} + +/*********************************************************************** + * + * pop3_perform_authentication() + * + * Initiates the authentication sequence, with the appropriate SASL + * authentication mechanism, falling back to APOP and clear text should a + * common mechanism not be available between the client and server. + */ +static CURLcode pop3_perform_authentication(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct pop3_conn *pop3c = &conn->proto.pop3c; + saslprogress progress = SASL_IDLE; + + /* Check we have enough data to authenticate with and end the + connect phase if we don't */ + if(!Curl_sasl_can_authenticate(&pop3c->sasl, conn)) { + state(conn, POP3_STOP); + return result; + } + + if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_SASL) { + /* Calculate the SASL login details */ + result = Curl_sasl_start(&pop3c->sasl, conn, FALSE, &progress); + + if(!result) + if(progress == SASL_INPROGRESS) + state(conn, POP3_AUTH); + } + + if(!result && progress == SASL_IDLE) { +#ifndef CURL_DISABLE_CRYPTO_AUTH + if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP) + /* Perform APOP authentication */ + result = pop3_perform_apop(conn); + else +#endif + if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT) + /* Perform clear text authentication */ + result = pop3_perform_user(conn); + else { + /* Other mechanisms not supported */ + infof(conn->data, "No known authentication mechanisms supported!\n"); + result = CURLE_LOGIN_DENIED; + } + } + + return result; +} + +/*********************************************************************** + * + * pop3_perform_command() + * + * Sends a POP3 based command. + */ +static CURLcode pop3_perform_command(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct POP3 *pop3 = data->req.protop; + const char *command = NULL; + + /* Calculate the default command */ + if(pop3->id[0] == '\0' || conn->data->set.ftp_list_only) { + command = "LIST"; + + if(pop3->id[0] != '\0') + /* Message specific LIST so skip the BODY transfer */ + pop3->transfer = FTPTRANSFER_INFO; + } + else + command = "RETR"; + + /* Send the command */ + if(pop3->id[0] != '\0') + result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s", + (pop3->custom && pop3->custom[0] != '\0' ? + pop3->custom : command), pop3->id); + else + result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", + (pop3->custom && pop3->custom[0] != '\0' ? + pop3->custom : command)); + + if(!result) + state(conn, POP3_COMMAND); + + return result; +} + +/*********************************************************************** + * + * pop3_perform_quit() + * + * Performs the quit action prior to sclose() be called. + */ +static CURLcode pop3_perform_quit(struct connectdata *conn) +{ + /* Send the QUIT command */ + CURLcode result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT"); + + if(!result) + state(conn, POP3_QUIT); + + return result; +} + +/* For the initial server greeting */ +static CURLcode pop3_state_servergreet_resp(struct connectdata *conn, + int pop3code, + pop3state instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct pop3_conn *pop3c = &conn->proto.pop3c; + const char *line = data->state.buffer; + size_t len = strlen(line); + + (void)instate; /* no use for this yet */ + + if(pop3code != '+') { + failf(data, "Got unexpected pop3-server response"); + result = CURLE_WEIRD_SERVER_REPLY; + } + else { + /* Does the server support APOP authentication? */ + if(len >= 4 && line[len - 2] == '>') { + /* Look for the APOP timestamp */ + size_t i; + for(i = 3; i < len - 2; ++i) { + if(line[i] == '<') { + /* Calculate the length of the timestamp */ + size_t timestamplen = len - 1 - i; + char *at; + if(!timestamplen) + break; + + /* Allocate some memory for the timestamp */ + pop3c->apoptimestamp = (char *)calloc(1, timestamplen + 1); + + if(!pop3c->apoptimestamp) + break; + + /* Copy the timestamp */ + memcpy(pop3c->apoptimestamp, line + i, timestamplen); + pop3c->apoptimestamp[timestamplen] = '\0'; + + /* If the timestamp does not contain '@' it is not (as required by + RFC-1939) conformant to the RFC-822 message id syntax, and we + therefore do not use APOP authentication. */ + at = strchr(pop3c->apoptimestamp, '@'); + if(!at) + Curl_safefree(pop3c->apoptimestamp); + else + /* Store the APOP capability */ + pop3c->authtypes |= POP3_TYPE_APOP; + break; + } + } + } + + result = pop3_perform_capa(conn); + } + + return result; +} + +/* For CAPA responses */ +static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code, + pop3state instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct pop3_conn *pop3c = &conn->proto.pop3c; + const char *line = data->state.buffer; + size_t len = strlen(line); + + (void)instate; /* no use for this yet */ + + /* Do we have a untagged continuation response? */ + if(pop3code == '*') { + /* Does the server support the STLS capability? */ + if(len >= 4 && !memcmp(line, "STLS", 4)) + pop3c->tls_supported = TRUE; + + /* Does the server support clear text authentication? */ + else if(len >= 4 && !memcmp(line, "USER", 4)) + pop3c->authtypes |= POP3_TYPE_CLEARTEXT; + + /* Does the server support SASL based authentication? */ + else if(len >= 5 && !memcmp(line, "SASL ", 5)) { + pop3c->authtypes |= POP3_TYPE_SASL; + + /* Advance past the SASL keyword */ + line += 5; + len -= 5; + + /* Loop through the data line */ + for(;;) { + size_t llen; + size_t wordlen; + unsigned int mechbit; + + while(len && + (*line == ' ' || *line == '\t' || + *line == '\r' || *line == '\n')) { + + line++; + len--; + } + + if(!len) + break; + + /* Extract the word */ + for(wordlen = 0; wordlen < len && line[wordlen] != ' ' && + line[wordlen] != '\t' && line[wordlen] != '\r' && + line[wordlen] != '\n';) + wordlen++; + + /* Test the word for a matching authentication mechanism */ + mechbit = Curl_sasl_decode_mech(line, wordlen, &llen); + if(mechbit && llen == wordlen) + pop3c->sasl.authmechs |= mechbit; + + line += wordlen; + len -= wordlen; + } + } + } + else if(pop3code == '+') { + if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { + /* We don't have a SSL/TLS connection yet, but SSL is requested */ + if(pop3c->tls_supported) + /* Switch to TLS connection now */ + result = pop3_perform_starttls(conn); + else if(data->set.use_ssl == CURLUSESSL_TRY) + /* Fallback and carry on with authentication */ + result = pop3_perform_authentication(conn); + else { + failf(data, "STLS not supported."); + result = CURLE_USE_SSL_FAILED; + } + } + else + result = pop3_perform_authentication(conn); + } + else { + /* Clear text is supported when CAPA isn't recognised */ + pop3c->authtypes |= POP3_TYPE_CLEARTEXT; + + result = pop3_perform_authentication(conn); + } + + return result; +} + +/* For STARTTLS responses */ +static CURLcode pop3_state_starttls_resp(struct connectdata *conn, + int pop3code, + pop3state instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + (void)instate; /* no use for this yet */ + + if(pop3code != '+') { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied"); + result = CURLE_USE_SSL_FAILED; + } + else + result = pop3_perform_authentication(conn); + } + else + result = pop3_perform_upgrade_tls(conn); + + return result; +} + +/* For SASL authentication responses */ +static CURLcode pop3_state_auth_resp(struct connectdata *conn, + int pop3code, + pop3state instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct pop3_conn *pop3c = &conn->proto.pop3c; + saslprogress progress; + + (void)instate; /* no use for this yet */ + + result = Curl_sasl_continue(&pop3c->sasl, conn, pop3code, &progress); + if(!result) + switch(progress) { + case SASL_DONE: + state(conn, POP3_STOP); /* Authenticated */ + break; + case SASL_IDLE: /* No mechanism left after cancellation */ +#ifndef CURL_DISABLE_CRYPTO_AUTH + if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP) + /* Perform APOP authentication */ + result = pop3_perform_apop(conn); + else +#endif + if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT) + /* Perform clear text authentication */ + result = pop3_perform_user(conn); + else { + failf(data, "Authentication cancelled"); + result = CURLE_LOGIN_DENIED; + } + break; + default: + break; + } + + return result; +} + +#ifndef CURL_DISABLE_CRYPTO_AUTH +/* For APOP responses */ +static CURLcode pop3_state_apop_resp(struct connectdata *conn, int pop3code, + pop3state instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + (void)instate; /* no use for this yet */ + + if(pop3code != '+') { + failf(data, "Authentication failed: %d", pop3code); + result = CURLE_LOGIN_DENIED; + } + else + /* End of connect phase */ + state(conn, POP3_STOP); + + return result; +} +#endif + +/* For USER responses */ +static CURLcode pop3_state_user_resp(struct connectdata *conn, int pop3code, + pop3state instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + (void)instate; /* no use for this yet */ + + if(pop3code != '+') { + failf(data, "Access denied. %c", pop3code); + result = CURLE_LOGIN_DENIED; + } + else + /* Send the PASS command */ + result = Curl_pp_sendf(&conn->proto.pop3c.pp, "PASS %s", + conn->passwd ? conn->passwd : ""); + if(!result) + state(conn, POP3_PASS); + + return result; +} + +/* For PASS responses */ +static CURLcode pop3_state_pass_resp(struct connectdata *conn, int pop3code, + pop3state instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + (void)instate; /* no use for this yet */ + + if(pop3code != '+') { + failf(data, "Access denied. %c", pop3code); + result = CURLE_LOGIN_DENIED; + } + else + /* End of connect phase */ + state(conn, POP3_STOP); + + return result; +} + +/* For command responses */ +static CURLcode pop3_state_command_resp(struct connectdata *conn, + int pop3code, + pop3state instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct POP3 *pop3 = data->req.protop; + struct pop3_conn *pop3c = &conn->proto.pop3c; + struct pingpong *pp = &pop3c->pp; + + (void)instate; /* no use for this yet */ + + if(pop3code != '+') { + state(conn, POP3_STOP); + return CURLE_RECV_ERROR; + } + + /* This 'OK' line ends with a CR LF pair which is the two first bytes of the + EOB string so count this is two matching bytes. This is necessary to make + the code detect the EOB if the only data than comes now is %2e CR LF like + when there is no body to return. */ + pop3c->eob = 2; + + /* But since this initial CR LF pair is not part of the actual body, we set + the strip counter here so that these bytes won't be delivered. */ + pop3c->strip = 2; + + if(pop3->transfer == FTPTRANSFER_BODY) { + /* POP3 download */ + Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); + + if(pp->cache) { + /* The header "cache" contains a bunch of data that is actually body + content so send it as such. Note that there may even be additional + "headers" after the body */ + + if(!data->set.opt_no_body) { + result = Curl_pop3_write(conn, pp->cache, pp->cache_size); + if(result) + return result; + } + + /* Free the cache */ + Curl_safefree(pp->cache); + + /* Reset the cache size */ + pp->cache_size = 0; + } + } + + /* End of DO phase */ + state(conn, POP3_STOP); + + return result; +} + +static CURLcode pop3_statemach_act(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + int pop3code; + struct pop3_conn *pop3c = &conn->proto.pop3c; + struct pingpong *pp = &pop3c->pp; + size_t nread = 0; + + /* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */ + if(pop3c->state == POP3_UPGRADETLS) + return pop3_perform_upgrade_tls(conn); + + /* Flush any data that needs to be sent */ + if(pp->sendleft) + return Curl_pp_flushsend(pp); + + do { + /* Read the response from the server */ + result = Curl_pp_readresp(sock, pp, &pop3code, &nread); + if(result) + return result; + + if(!pop3code) + break; + + /* We have now received a full POP3 server response */ + switch(pop3c->state) { + case POP3_SERVERGREET: + result = pop3_state_servergreet_resp(conn, pop3code, pop3c->state); + break; + + case POP3_CAPA: + result = pop3_state_capa_resp(conn, pop3code, pop3c->state); + break; + + case POP3_STARTTLS: + result = pop3_state_starttls_resp(conn, pop3code, pop3c->state); + break; + + case POP3_AUTH: + result = pop3_state_auth_resp(conn, pop3code, pop3c->state); + break; + +#ifndef CURL_DISABLE_CRYPTO_AUTH + case POP3_APOP: + result = pop3_state_apop_resp(conn, pop3code, pop3c->state); + break; +#endif + + case POP3_USER: + result = pop3_state_user_resp(conn, pop3code, pop3c->state); + break; + + case POP3_PASS: + result = pop3_state_pass_resp(conn, pop3code, pop3c->state); + break; + + case POP3_COMMAND: + result = pop3_state_command_resp(conn, pop3code, pop3c->state); + break; + + case POP3_QUIT: + /* fallthrough, just stop! */ + default: + /* internal error */ + state(conn, POP3_STOP); + break; + } + } while(!result && pop3c->state != POP3_STOP && Curl_pp_moredata(pp)); + + return result; +} + +/* Called repeatedly until done from multi.c */ +static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + struct pop3_conn *pop3c = &conn->proto.pop3c; + + if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) { + result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone); + if(result || !pop3c->ssldone) + return result; + } + + result = Curl_pp_statemach(&pop3c->pp, FALSE, FALSE); + *done = (pop3c->state == POP3_STOP) ? TRUE : FALSE; + + return result; +} + +static CURLcode pop3_block_statemach(struct connectdata *conn, + bool disconnecting) +{ + CURLcode result = CURLE_OK; + struct pop3_conn *pop3c = &conn->proto.pop3c; + + while(pop3c->state != POP3_STOP && !result) + result = Curl_pp_statemach(&pop3c->pp, TRUE, disconnecting); + + return result; +} + +/* Allocate and initialize the POP3 struct for the current Curl_easy if + required */ +static CURLcode pop3_init(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct POP3 *pop3; + + pop3 = data->req.protop = calloc(sizeof(struct POP3), 1); + if(!pop3) + result = CURLE_OUT_OF_MEMORY; + + return result; +} + +/* For the POP3 "protocol connect" and "doing" phases only */ +static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks) +{ + return Curl_pp_getsock(&conn->proto.pop3c.pp, socks, numsocks); +} + +/*********************************************************************** + * + * pop3_connect() + * + * This function should do everything that is to be considered a part of the + * connection phase. + * + * The variable 'done' points to will be TRUE if the protocol-layer connect + * phase is done when this function returns, or FALSE if not. + */ +static CURLcode pop3_connect(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + struct pop3_conn *pop3c = &conn->proto.pop3c; + struct pingpong *pp = &pop3c->pp; + + *done = FALSE; /* default to not done yet */ + + /* We always support persistent connections in POP3 */ + connkeep(conn, "POP3 default"); + + /* Set the default response time-out */ + pp->response_time = RESP_TIMEOUT; + pp->statemach_act = pop3_statemach_act; + pp->endofresp = pop3_endofresp; + pp->conn = conn; + + /* Set the default preferred authentication type and mechanism */ + pop3c->preftype = POP3_TYPE_ANY; + Curl_sasl_init(&pop3c->sasl, &saslpop3); + + /* Initialise the pingpong layer */ + Curl_pp_init(pp); + + /* Parse the URL options */ + result = pop3_parse_url_options(conn); + if(result) + return result; + + /* Start off waiting for the server greeting response */ + state(conn, POP3_SERVERGREET); + + result = pop3_multi_statemach(conn, done); + + return result; +} + +/*********************************************************************** + * + * pop3_done() + * + * The DONE function. This does what needs to be done after a single DO has + * performed. + * + * Input argument is already checked for validity. + */ +static CURLcode pop3_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct POP3 *pop3 = data->req.protop; + + (void)premature; + + if(!pop3) + return CURLE_OK; + + if(status) { + connclose(conn, "POP3 done with bad status"); + result = status; /* use the already set error code */ + } + + /* Cleanup our per-request based variables */ + Curl_safefree(pop3->id); + Curl_safefree(pop3->custom); + + /* Clear the transfer mode for the next request */ + pop3->transfer = FTPTRANSFER_BODY; + + return result; +} + +/*********************************************************************** + * + * pop3_perform() + * + * This is the actual DO function for POP3. Get a message/listing according to + * the options previously setup. + */ +static CURLcode pop3_perform(struct connectdata *conn, bool *connected, + bool *dophase_done) +{ + /* This is POP3 and no proxy */ + CURLcode result = CURLE_OK; + struct POP3 *pop3 = conn->data->req.protop; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + if(conn->data->set.opt_no_body) { + /* Requested no body means no transfer */ + pop3->transfer = FTPTRANSFER_INFO; + } + + *dophase_done = FALSE; /* not done yet */ + + /* Start the first command in the DO phase */ + result = pop3_perform_command(conn); + if(result) + return result; + + /* Run the state-machine */ + result = pop3_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) + DEBUGF(infof(conn->data, "DO phase is complete\n")); + + return result; +} + +/*********************************************************************** + * + * pop3_do() + * + * This function is registered as 'curl_do' function. It decodes the path + * parts etc as a wrapper to the actual DO function (pop3_perform). + * + * The input argument is already checked for validity. + */ +static CURLcode pop3_do(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + + *done = FALSE; /* default to false */ + + /* Parse the URL path */ + result = pop3_parse_url_path(conn); + if(result) + return result; + + /* Parse the custom request */ + result = pop3_parse_custom_request(conn); + if(result) + return result; + + result = pop3_regular_transfer(conn, done); + + return result; +} + +/*********************************************************************** + * + * pop3_disconnect() + * + * Disconnect from an POP3 server. Cleanup protocol-specific per-connection + * resources. BLOCKING. + */ +static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection) +{ + struct pop3_conn *pop3c = &conn->proto.pop3c; + + /* We cannot send quit unconditionally. If this connection is stale or + bad in any way, sending quit and waiting around here will make the + disconnect wait in vain and cause more problems than we need to. */ + + /* The POP3 session may or may not have been allocated/setup at this + point! */ + if(!dead_connection && pop3c->pp.conn && pop3c->pp.conn->bits.protoconnstart) + if(!pop3_perform_quit(conn)) + (void)pop3_block_statemach(conn, TRUE); /* ignore errors on QUIT */ + + /* Disconnect from the server */ + Curl_pp_disconnect(&pop3c->pp); + + /* Cleanup the SASL module */ + Curl_sasl_cleanup(conn, pop3c->sasl.authused); + + /* Cleanup our connection based variables */ + Curl_safefree(pop3c->apoptimestamp); + + return CURLE_OK; +} + +/* Call this when the DO phase has completed */ +static CURLcode pop3_dophase_done(struct connectdata *conn, bool connected) +{ + (void)conn; + (void)connected; + + return CURLE_OK; +} + +/* Called from multi.c while DOing */ +static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done) +{ + CURLcode result = pop3_multi_statemach(conn, dophase_done); + + if(result) + DEBUGF(infof(conn->data, "DO phase failed\n")); + else if(*dophase_done) { + result = pop3_dophase_done(conn, FALSE /* not connected */); + + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +/*********************************************************************** + * + * pop3_regular_transfer() + * + * The input argument is already checked for validity. + * + * Performs all commands done before a regular transfer between a local and a + * remote host. + */ +static CURLcode pop3_regular_transfer(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result = CURLE_OK; + bool connected = FALSE; + struct Curl_easy *data = conn->data; + + /* Make sure size is unknown at this point */ + data->req.size = -1; + + /* Set the progress data */ + Curl_pgrsSetUploadCounter(data, 0); + Curl_pgrsSetDownloadCounter(data, 0); + Curl_pgrsSetUploadSize(data, -1); + Curl_pgrsSetDownloadSize(data, -1); + + /* Carry out the perform */ + result = pop3_perform(conn, &connected, dophase_done); + + /* Perform post DO phase operations if necessary */ + if(!result && *dophase_done) + result = pop3_dophase_done(conn, connected); + + return result; +} + +static CURLcode pop3_setup_connection(struct connectdata *conn) +{ + /* Initialise the POP3 layer */ + CURLcode result = pop3_init(conn); + if(result) + return result; + + /* Clear the TLS upgraded flag */ + conn->tls_upgraded = FALSE; + + return CURLE_OK; +} + +/*********************************************************************** + * + * pop3_parse_url_options() + * + * Parse the URL login options. + */ +static CURLcode pop3_parse_url_options(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct pop3_conn *pop3c = &conn->proto.pop3c; + const char *ptr = conn->options; + + pop3c->sasl.resetprefs = TRUE; + + while(!result && ptr && *ptr) { + const char *key = ptr; + const char *value; + + while(*ptr && *ptr != '=') + ptr++; + + value = ptr + 1; + + while(*ptr && *ptr != ';') + ptr++; + + if(strncasecompare(key, "AUTH=", 5)) { + result = Curl_sasl_parse_url_auth_option(&pop3c->sasl, + value, ptr - value); + + if(result && strncasecompare(value, "+APOP", ptr - value)) { + pop3c->preftype = POP3_TYPE_APOP; + pop3c->sasl.prefmech = SASL_AUTH_NONE; + result = CURLE_OK; + } + } + else + result = CURLE_URL_MALFORMAT; + + if(*ptr == ';') + ptr++; + } + + if(pop3c->preftype != POP3_TYPE_APOP) + switch(pop3c->sasl.prefmech) { + case SASL_AUTH_NONE: + pop3c->preftype = POP3_TYPE_NONE; + break; + case SASL_AUTH_DEFAULT: + pop3c->preftype = POP3_TYPE_ANY; + break; + default: + pop3c->preftype = POP3_TYPE_SASL; + break; + } + + return result; +} + +/*********************************************************************** + * + * pop3_parse_url_path() + * + * Parse the URL path into separate path components. + */ +static CURLcode pop3_parse_url_path(struct connectdata *conn) +{ + /* The POP3 struct is already initialised in pop3_connect() */ + struct Curl_easy *data = conn->data; + struct POP3 *pop3 = data->req.protop; + const char *path = &data->state.up.path[1]; /* skip leading path */ + + /* URL decode the path for the message ID */ + return Curl_urldecode(data, path, 0, &pop3->id, NULL, TRUE); +} + +/*********************************************************************** + * + * pop3_parse_custom_request() + * + * Parse the custom request. + */ +static CURLcode pop3_parse_custom_request(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct POP3 *pop3 = data->req.protop; + const char *custom = data->set.str[STRING_CUSTOMREQUEST]; + + /* URL decode the custom request */ + if(custom) + result = Curl_urldecode(data, custom, 0, &pop3->custom, NULL, TRUE); + + return result; +} + +/*********************************************************************** + * + * Curl_pop3_write() + * + * This function scans the body after the end-of-body and writes everything + * until the end is found. + */ +CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread) +{ + /* This code could be made into a special function in the handler struct */ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct SingleRequest *k = &data->req; + + struct pop3_conn *pop3c = &conn->proto.pop3c; + bool strip_dot = FALSE; + size_t last = 0; + size_t i; + + /* Search through the buffer looking for the end-of-body marker which is + 5 bytes (0d 0a 2e 0d 0a). Note that a line starting with a dot matches + the eob so the server will have prefixed it with an extra dot which we + need to strip out. Additionally the marker could of course be spread out + over 5 different data chunks. */ + for(i = 0; i < nread; i++) { + size_t prev = pop3c->eob; + + switch(str[i]) { + case 0x0d: + if(pop3c->eob == 0) { + pop3c->eob++; + + if(i) { + /* Write out the body part that didn't match */ + result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last], + i - last); + + if(result) + return result; + + last = i; + } + } + else if(pop3c->eob == 3) + pop3c->eob++; + else + /* If the character match wasn't at position 0 or 3 then restart the + pattern matching */ + pop3c->eob = 1; + break; + + case 0x0a: + if(pop3c->eob == 1 || pop3c->eob == 4) + pop3c->eob++; + else + /* If the character match wasn't at position 1 or 4 then start the + search again */ + pop3c->eob = 0; + break; + + case 0x2e: + if(pop3c->eob == 2) + pop3c->eob++; + else if(pop3c->eob == 3) { + /* We have an extra dot after the CRLF which we need to strip off */ + strip_dot = TRUE; + pop3c->eob = 0; + } + else + /* If the character match wasn't at position 2 then start the search + again */ + pop3c->eob = 0; + break; + + default: + pop3c->eob = 0; + break; + } + + /* Did we have a partial match which has subsequently failed? */ + if(prev && prev >= pop3c->eob) { + /* Strip can only be non-zero for the very first mismatch after CRLF + and then both prev and strip are equal and nothing will be output + below */ + while(prev && pop3c->strip) { + prev--; + pop3c->strip--; + } + + if(prev) { + /* If the partial match was the CRLF and dot then only write the CRLF + as the server would have inserted the dot */ + result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)POP3_EOB, + strip_dot ? prev - 1 : prev); + + if(result) + return result; + + last = i; + strip_dot = FALSE; + } + } + } + + if(pop3c->eob == POP3_EOB_LEN) { + /* We have a full match so the transfer is done, however we must transfer + the CRLF at the start of the EOB as this is considered to be part of the + message as per RFC-1939, sect. 3 */ + result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)POP3_EOB, 2); + + k->keepon &= ~KEEP_RECV; + pop3c->eob = 0; + + return result; + } + + if(pop3c->eob) + /* While EOB is matching nothing should be output */ + return CURLE_OK; + + if(nread - last) { + result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last], + nread - last); + } + + return result; +} + +#endif /* CURL_DISABLE_POP3 */ diff --git a/libcurl/lib/pop3.h b/libcurl/lib/pop3.h new file mode 100644 index 0000000..a8e697c --- /dev/null +++ b/libcurl/lib/pop3.h @@ -0,0 +1,95 @@ +#ifndef HEADER_CURL_POP3_H +#define HEADER_CURL_POP3_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2009 - 2015, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "pingpong.h" +#include "curl_sasl.h" + +/**************************************************************************** + * POP3 unique setup + ***************************************************************************/ +typedef enum { + POP3_STOP, /* do nothing state, stops the state machine */ + POP3_SERVERGREET, /* waiting for the initial greeting immediately after + a connect */ + POP3_CAPA, + POP3_STARTTLS, + POP3_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS + (multi mode only) */ + POP3_AUTH, + POP3_APOP, + POP3_USER, + POP3_PASS, + POP3_COMMAND, + POP3_QUIT, + POP3_LAST /* never used */ +} pop3state; + +/* This POP3 struct is used in the Curl_easy. All POP3 data that is + connection-oriented must be in pop3_conn to properly deal with the fact that + perhaps the Curl_easy is changed between the times the connection is + used. */ +struct POP3 { + curl_pp_transfer transfer; + char *id; /* Message ID */ + char *custom; /* Custom Request */ +}; + +/* pop3_conn is used for struct connection-oriented data in the connectdata + struct */ +struct pop3_conn { + struct pingpong pp; + pop3state state; /* Always use pop3.c:state() to change state! */ + bool ssldone; /* Is connect() over SSL done? */ + size_t eob; /* Number of bytes of the EOB (End Of Body) that + have been received so far */ + size_t strip; /* Number of bytes from the start to ignore as + non-body */ + struct SASL sasl; /* SASL-related storage */ + unsigned int authtypes; /* Accepted authentication types */ + unsigned int preftype; /* Preferred authentication type */ + char *apoptimestamp; /* APOP timestamp from the server greeting */ + bool tls_supported; /* StartTLS capability supported by server */ +}; + +extern const struct Curl_handler Curl_handler_pop3; +extern const struct Curl_handler Curl_handler_pop3s; + +/* Authentication type flags */ +#define POP3_TYPE_CLEARTEXT (1 << 0) +#define POP3_TYPE_APOP (1 << 1) +#define POP3_TYPE_SASL (1 << 2) + +/* Authentication type values */ +#define POP3_TYPE_NONE 0 +#define POP3_TYPE_ANY ~0U + +/* This is the 5-bytes End-Of-Body marker for POP3 */ +#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a" +#define POP3_EOB_LEN 5 + +/* This function scans the body after the end-of-body and writes everything + * until the end is found */ +CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread); + +#endif /* HEADER_CURL_POP3_H */ diff --git a/libcurl/lib/progress.c b/libcurl/lib/progress.c new file mode 100644 index 0000000..9f953ef --- /dev/null +++ b/libcurl/lib/progress.c @@ -0,0 +1,618 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include "urldata.h" +#include "sendf.h" +#include "multiif.h" +#include "progress.h" +#include "curl_printf.h" + +/* check rate limits within this many recent milliseconds, at minimum. */ +#define MIN_RATE_LIMIT_PERIOD 3000 + +#ifndef CURL_DISABLE_PROGRESS_METER +/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero + byte) */ +static void time2str(char *r, curl_off_t seconds) +{ + curl_off_t h; + if(seconds <= 0) { + strcpy(r, "--:--:--"); + return; + } + h = seconds / CURL_OFF_T_C(3600); + if(h <= CURL_OFF_T_C(99)) { + curl_off_t m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60); + curl_off_t s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60)); + msnprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T + ":%02" CURL_FORMAT_CURL_OFF_T, h, m, s); + } + else { + /* this equals to more than 99 hours, switch to a more suitable output + format to fit within the limits. */ + curl_off_t d = seconds / CURL_OFF_T_C(86400); + h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600); + if(d <= CURL_OFF_T_C(999)) + msnprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T + "d %02" CURL_FORMAT_CURL_OFF_T "h", d, h); + else + msnprintf(r, 9, "%7" CURL_FORMAT_CURL_OFF_T "d", d); + } +} + +/* The point of this function would be to return a string of the input data, + but never longer than 5 columns (+ one zero byte). + Add suffix k, M, G when suitable... */ +static char *max5data(curl_off_t bytes, char *max5) +{ +#define ONE_KILOBYTE CURL_OFF_T_C(1024) +#define ONE_MEGABYTE (CURL_OFF_T_C(1024) * ONE_KILOBYTE) +#define ONE_GIGABYTE (CURL_OFF_T_C(1024) * ONE_MEGABYTE) +#define ONE_TERABYTE (CURL_OFF_T_C(1024) * ONE_GIGABYTE) +#define ONE_PETABYTE (CURL_OFF_T_C(1024) * ONE_TERABYTE) + + if(bytes < CURL_OFF_T_C(100000)) + msnprintf(max5, 6, "%5" CURL_FORMAT_CURL_OFF_T, bytes); + + else if(bytes < CURL_OFF_T_C(10000) * ONE_KILOBYTE) + msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "k", bytes/ONE_KILOBYTE); + + else if(bytes < CURL_OFF_T_C(100) * ONE_MEGABYTE) + /* 'XX.XM' is good as long as we're less than 100 megs */ + msnprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0" + CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE, + (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) ); + +#if (CURL_SIZEOF_CURL_OFF_T > 4) + + else if(bytes < CURL_OFF_T_C(10000) * ONE_MEGABYTE) + /* 'XXXXM' is good until we're at 10000MB or above */ + msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE); + + else if(bytes < CURL_OFF_T_C(100) * ONE_GIGABYTE) + /* 10000 MB - 100 GB, we show it as XX.XG */ + msnprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0" + CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE, + (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/CURL_OFF_T_C(10)) ); + + else if(bytes < CURL_OFF_T_C(10000) * ONE_GIGABYTE) + /* up to 10000GB, display without decimal: XXXXG */ + msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE); + + else if(bytes < CURL_OFF_T_C(10000) * ONE_TERABYTE) + /* up to 10000TB, display without decimal: XXXXT */ + msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "T", bytes/ONE_TERABYTE); + + else + /* up to 10000PB, display without decimal: XXXXP */ + msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "P", bytes/ONE_PETABYTE); + + /* 16384 petabytes (16 exabytes) is the maximum a 64 bit unsigned number + can hold, but our data type is signed so 8192PB will be the maximum. */ + +#else + + else + msnprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE); + +#endif + + return max5; +} +#endif + +/* + + New proposed interface, 9th of February 2000: + + pgrsStartNow() - sets start time + pgrsSetDownloadSize(x) - known expected download size + pgrsSetUploadSize(x) - known expected upload size + pgrsSetDownloadCounter() - amount of data currently downloaded + pgrsSetUploadCounter() - amount of data currently uploaded + pgrsUpdate() - show progress + pgrsDone() - transfer complete + +*/ + +int Curl_pgrsDone(struct connectdata *conn) +{ + int rc; + struct Curl_easy *data = conn->data; + data->progress.lastshow = 0; + rc = Curl_pgrsUpdate(conn); /* the final (forced) update */ + if(rc) + return rc; + + if(!(data->progress.flags & PGRS_HIDE) && + !data->progress.callback) + /* only output if we don't use a progress callback and we're not + * hidden */ + fprintf(data->set.err, "\n"); + + data->progress.speeder_c = 0; /* reset the progress meter display */ + return 0; +} + +/* reset the known transfer sizes */ +void Curl_pgrsResetTransferSizes(struct Curl_easy *data) +{ + Curl_pgrsSetDownloadSize(data, -1); + Curl_pgrsSetUploadSize(data, -1); +} + +/* + * @unittest: 1399 + */ +void Curl_pgrsTime(struct Curl_easy *data, timerid timer) +{ + struct curltime now = Curl_now(); + time_t *delta = NULL; + + switch(timer) { + default: + case TIMER_NONE: + /* mistake filter */ + break; + case TIMER_STARTOP: + /* This is set at the start of a transfer */ + data->progress.t_startop = now; + break; + case TIMER_STARTSINGLE: + /* This is set at the start of each single fetch */ + data->progress.t_startsingle = now; + data->progress.is_t_startransfer_set = false; + break; + case TIMER_STARTACCEPT: + data->progress.t_acceptdata = now; + break; + case TIMER_NAMELOOKUP: + delta = &data->progress.t_nslookup; + break; + case TIMER_CONNECT: + delta = &data->progress.t_connect; + break; + case TIMER_APPCONNECT: + delta = &data->progress.t_appconnect; + break; + case TIMER_PRETRANSFER: + delta = &data->progress.t_pretransfer; + break; + case TIMER_STARTTRANSFER: + delta = &data->progress.t_starttransfer; + /* prevent updating t_starttransfer unless: + * 1) this is the first time we're setting t_starttransfer + * 2) a redirect has occurred since the last time t_starttransfer was set + * This prevents repeated invocations of the function from incorrectly + * changing the t_starttransfer time. + */ + if(data->progress.is_t_startransfer_set) { + return; + } + else { + data->progress.is_t_startransfer_set = true; + break; + } + case TIMER_POSTRANSFER: + /* this is the normal end-of-transfer thing */ + break; + case TIMER_REDIRECT: + data->progress.t_redirect = Curl_timediff_us(now, data->progress.start); + break; + } + if(delta) { + timediff_t us = Curl_timediff_us(now, data->progress.t_startsingle); + if(us < 1) + us = 1; /* make sure at least one microsecond passed */ + *delta += us; + } +} + +void Curl_pgrsStartNow(struct Curl_easy *data) +{ + data->progress.speeder_c = 0; /* reset the progress meter display */ + data->progress.start = Curl_now(); + data->progress.is_t_startransfer_set = false; + data->progress.ul_limit_start.tv_sec = 0; + data->progress.ul_limit_start.tv_usec = 0; + data->progress.dl_limit_start.tv_sec = 0; + data->progress.dl_limit_start.tv_usec = 0; + /* clear all bits except HIDE and HEADERS_OUT */ + data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT; + Curl_ratelimit(data, data->progress.start); +} + +/* + * This is used to handle speed limits, calculating how many milliseconds to + * wait until we're back under the speed limit, if needed. + * + * The way it works is by having a "starting point" (time & amount of data + * transferred by then) used in the speed computation, to be used instead of + * the start of the transfer. This starting point is regularly moved as + * transfer goes on, to keep getting accurate values (instead of average over + * the entire transfer). + * + * This function takes the current amount of data transferred, the amount at + * the starting point, the limit (in bytes/s), the time of the starting point + * and the current time. + * + * Returns 0 if no waiting is needed or when no waiting is needed but the + * starting point should be reset (to current); or the number of milliseconds + * to wait to get back under the speed limit. + */ +timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, + curl_off_t startsize, + curl_off_t limit, + struct curltime start, + struct curltime now) +{ + curl_off_t size = cursize - startsize; + time_t minimum; + time_t actual; + + if(!limit || !size) + return 0; + + /* + * 'minimum' is the number of milliseconds 'size' should take to download to + * stay below 'limit'. + */ + if(size < CURL_OFF_T_MAX/1000) + minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit); + else { + minimum = (time_t) (size / limit); + if(minimum < TIME_T_MAX/1000) + minimum *= 1000; + else + minimum = TIME_T_MAX; + } + + /* + * 'actual' is the time in milliseconds it took to actually download the + * last 'size' bytes. + */ + actual = Curl_timediff(now, start); + if(actual < minimum) { + /* if it downloaded the data faster than the limit, make it wait the + difference */ + return (minimum - actual); + } + + return 0; +} + +/* + * Set the number of downloaded bytes so far. + */ +void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size) +{ + data->progress.downloaded = size; +} + +/* + * Update the timestamp and sizestamp to use for rate limit calculations. + */ +void Curl_ratelimit(struct Curl_easy *data, struct curltime now) +{ + /* don't set a new stamp unless the time since last update is long enough */ + if(data->set.max_recv_speed > 0) { + if(Curl_timediff(now, data->progress.dl_limit_start) >= + MIN_RATE_LIMIT_PERIOD) { + data->progress.dl_limit_start = now; + data->progress.dl_limit_size = data->progress.downloaded; + } + } + if(data->set.max_send_speed > 0) { + if(Curl_timediff(now, data->progress.ul_limit_start) >= + MIN_RATE_LIMIT_PERIOD) { + data->progress.ul_limit_start = now; + data->progress.ul_limit_size = data->progress.uploaded; + } + } +} + +/* + * Set the number of uploaded bytes so far. + */ +void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size) +{ + data->progress.uploaded = size; +} + +void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size) +{ + if(size >= 0) { + data->progress.size_dl = size; + data->progress.flags |= PGRS_DL_SIZE_KNOWN; + } + else { + data->progress.size_dl = 0; + data->progress.flags &= ~PGRS_DL_SIZE_KNOWN; + } +} + +void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size) +{ + if(size >= 0) { + data->progress.size_ul = size; + data->progress.flags |= PGRS_UL_SIZE_KNOWN; + } + else { + data->progress.size_ul = 0; + data->progress.flags &= ~PGRS_UL_SIZE_KNOWN; + } +} + +/* returns TRUE if it's time to show the progress meter */ +static bool progress_calc(struct connectdata *conn, struct curltime now) +{ + curl_off_t timespent; + curl_off_t timespent_ms; /* milliseconds */ + struct Curl_easy *data = conn->data; + curl_off_t dl = data->progress.downloaded; + curl_off_t ul = data->progress.uploaded; + bool timetoshow = FALSE; + + /* The time spent so far (from the start) */ + data->progress.timespent = Curl_timediff_us(now, data->progress.start); + timespent = (curl_off_t)data->progress.timespent/1000000; /* seconds */ + timespent_ms = (curl_off_t)data->progress.timespent/1000; /* ms */ + + /* The average download speed this far */ + if(dl < CURL_OFF_T_MAX/1000) + data->progress.dlspeed = (dl * 1000 / (timespent_ms>0?timespent_ms:1)); + else + data->progress.dlspeed = (dl / (timespent>0?timespent:1)); + + /* The average upload speed this far */ + if(ul < CURL_OFF_T_MAX/1000) + data->progress.ulspeed = (ul * 1000 / (timespent_ms>0?timespent_ms:1)); + else + data->progress.ulspeed = (ul / (timespent>0?timespent:1)); + + /* Calculations done at most once a second, unless end is reached */ + if(data->progress.lastshow != now.tv_sec) { + int countindex; /* amount of seconds stored in the speeder array */ + int nowindex = data->progress.speeder_c% CURR_TIME; + data->progress.lastshow = now.tv_sec; + timetoshow = TRUE; + + /* Let's do the "current speed" thing, with the dl + ul speeds + combined. Store the speed at entry 'nowindex'. */ + data->progress.speeder[ nowindex ] = + data->progress.downloaded + data->progress.uploaded; + + /* remember the exact time for this moment */ + data->progress.speeder_time [ nowindex ] = now; + + /* advance our speeder_c counter, which is increased every time we get + here and we expect it to never wrap as 2^32 is a lot of seconds! */ + data->progress.speeder_c++; + + /* figure out how many index entries of data we have stored in our speeder + array. With N_ENTRIES filled in, we have about N_ENTRIES-1 seconds of + transfer. Imagine, after one second we have filled in two entries, + after two seconds we've filled in three entries etc. */ + countindex = ((data->progress.speeder_c >= CURR_TIME)? + CURR_TIME:data->progress.speeder_c) - 1; + + /* first of all, we don't do this if there's no counted seconds yet */ + if(countindex) { + int checkindex; + timediff_t span_ms; + + /* Get the index position to compare with the 'nowindex' position. + Get the oldest entry possible. While we have less than CURR_TIME + entries, the first entry will remain the oldest. */ + checkindex = (data->progress.speeder_c >= CURR_TIME)? + data->progress.speeder_c%CURR_TIME:0; + + /* Figure out the exact time for the time span */ + span_ms = Curl_timediff(now, data->progress.speeder_time[checkindex]); + if(0 == span_ms) + span_ms = 1; /* at least one millisecond MUST have passed */ + + /* Calculate the average speed the last 'span_ms' milliseconds */ + { + curl_off_t amount = data->progress.speeder[nowindex]- + data->progress.speeder[checkindex]; + + if(amount > CURL_OFF_T_C(4294967) /* 0xffffffff/1000 */) + /* the 'amount' value is bigger than would fit in 32 bits if + multiplied with 1000, so we use the double math for this */ + data->progress.current_speed = (curl_off_t) + ((double)amount/((double)span_ms/1000.0)); + else + /* the 'amount' value is small enough to fit within 32 bits even + when multiplied with 1000 */ + data->progress.current_speed = amount*CURL_OFF_T_C(1000)/span_ms; + } + } + else + /* the first second we use the average */ + data->progress.current_speed = + data->progress.ulspeed + data->progress.dlspeed; + + } /* Calculations end */ + return timetoshow; +} + +#ifndef CURL_DISABLE_PROGRESS_METER +static void progress_meter(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + char max5[6][10]; + curl_off_t dlpercen = 0; + curl_off_t ulpercen = 0; + curl_off_t total_percen = 0; + curl_off_t total_transfer; + curl_off_t total_expected_transfer; + char time_left[10]; + char time_total[10]; + char time_spent[10]; + curl_off_t ulestimate = 0; + curl_off_t dlestimate = 0; + curl_off_t total_estimate; + curl_off_t timespent = + (curl_off_t)data->progress.timespent/1000000; /* seconds */ + + if(!(data->progress.flags & PGRS_HEADERS_OUT)) { + if(data->state.resume_from) { + fprintf(data->set.err, + "** Resuming transfer from byte position %" + CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from); + } + fprintf(data->set.err, + " %% Total %% Received %% Xferd Average Speed " + "Time Time Time Current\n" + " Dload Upload " + "Total Spent Left Speed\n"); + data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */ + } + + /* Figure out the estimated time of arrival for the upload */ + if((data->progress.flags & PGRS_UL_SIZE_KNOWN) && + (data->progress.ulspeed > CURL_OFF_T_C(0))) { + ulestimate = data->progress.size_ul / data->progress.ulspeed; + + if(data->progress.size_ul > CURL_OFF_T_C(10000)) + ulpercen = data->progress.uploaded / + (data->progress.size_ul/CURL_OFF_T_C(100)); + else if(data->progress.size_ul > CURL_OFF_T_C(0)) + ulpercen = (data->progress.uploaded*100) / + data->progress.size_ul; + } + + /* ... and the download */ + if((data->progress.flags & PGRS_DL_SIZE_KNOWN) && + (data->progress.dlspeed > CURL_OFF_T_C(0))) { + dlestimate = data->progress.size_dl / data->progress.dlspeed; + + if(data->progress.size_dl > CURL_OFF_T_C(10000)) + dlpercen = data->progress.downloaded / + (data->progress.size_dl/CURL_OFF_T_C(100)); + else if(data->progress.size_dl > CURL_OFF_T_C(0)) + dlpercen = (data->progress.downloaded*100) / + data->progress.size_dl; + } + + /* Now figure out which of them is slower and use that one for the + total estimate! */ + total_estimate = ulestimate>dlestimate?ulestimate:dlestimate; + + /* create the three time strings */ + time2str(time_left, total_estimate > 0?(total_estimate - timespent):0); + time2str(time_total, total_estimate); + time2str(time_spent, timespent); + + /* Get the total amount of data expected to get transferred */ + total_expected_transfer = + ((data->progress.flags & PGRS_UL_SIZE_KNOWN)? + data->progress.size_ul:data->progress.uploaded)+ + ((data->progress.flags & PGRS_DL_SIZE_KNOWN)? + data->progress.size_dl:data->progress.downloaded); + + /* We have transferred this much so far */ + total_transfer = data->progress.downloaded + data->progress.uploaded; + + /* Get the percentage of data transferred so far */ + if(total_expected_transfer > CURL_OFF_T_C(10000)) + total_percen = total_transfer / + (total_expected_transfer/CURL_OFF_T_C(100)); + else if(total_expected_transfer > CURL_OFF_T_C(0)) + total_percen = (total_transfer*100) / total_expected_transfer; + + fprintf(data->set.err, + "\r" + "%3" CURL_FORMAT_CURL_OFF_T " %s " + "%3" CURL_FORMAT_CURL_OFF_T " %s " + "%3" CURL_FORMAT_CURL_OFF_T " %s %s %s %s %s %s %s", + total_percen, /* 3 letters */ /* total % */ + max5data(total_expected_transfer, max5[2]), /* total size */ + dlpercen, /* 3 letters */ /* rcvd % */ + max5data(data->progress.downloaded, max5[0]), /* rcvd size */ + ulpercen, /* 3 letters */ /* xfer % */ + max5data(data->progress.uploaded, max5[1]), /* xfer size */ + max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */ + max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */ + time_total, /* 8 letters */ /* total time */ + time_spent, /* 8 letters */ /* time spent */ + time_left, /* 8 letters */ /* time left */ + max5data(data->progress.current_speed, max5[5]) + ); + + /* we flush the output stream to make it appear as soon as possible */ + fflush(data->set.err); +} +#else + /* progress bar disabled */ +#define progress_meter(x) Curl_nop_stmt +#endif + + +/* + * Curl_pgrsUpdate() returns 0 for success or the value returned by the + * progress callback! + */ +int Curl_pgrsUpdate(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + struct curltime now = Curl_now(); /* what time is it */ + bool showprogress = progress_calc(conn, now); + if(!(data->progress.flags & PGRS_HIDE)) { + if(data->set.fxferinfo) { + int result; + /* There's a callback set, call that */ + Curl_set_in_callback(data, true); + result = data->set.fxferinfo(data->set.progress_client, + data->progress.size_dl, + data->progress.downloaded, + data->progress.size_ul, + data->progress.uploaded); + Curl_set_in_callback(data, false); + if(result) + failf(data, "Callback aborted"); + return result; + } + if(data->set.fprogress) { + int result; + /* The older deprecated callback is set, call that */ + Curl_set_in_callback(data, true); + result = data->set.fprogress(data->set.progress_client, + (double)data->progress.size_dl, + (double)data->progress.downloaded, + (double)data->progress.size_ul, + (double)data->progress.uploaded); + Curl_set_in_callback(data, false); + if(result) + failf(data, "Callback aborted"); + return result; + } + + if(showprogress) + progress_meter(conn); + } + + return 0; +} diff --git a/libcurl/lib/progress.h b/libcurl/lib/progress.h new file mode 100644 index 0000000..3515ac6 --- /dev/null +++ b/libcurl/lib/progress.h @@ -0,0 +1,64 @@ +#ifndef HEADER_CURL_PROGRESS_H +#define HEADER_CURL_PROGRESS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "timeval.h" + + +typedef enum { + TIMER_NONE, + TIMER_STARTOP, + TIMER_STARTSINGLE, + TIMER_NAMELOOKUP, + TIMER_CONNECT, + TIMER_APPCONNECT, + TIMER_PRETRANSFER, + TIMER_STARTTRANSFER, + TIMER_POSTRANSFER, + TIMER_STARTACCEPT, + TIMER_REDIRECT, + TIMER_LAST /* must be last */ +} timerid; + +int Curl_pgrsDone(struct connectdata *); +void Curl_pgrsStartNow(struct Curl_easy *data); +void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size); +void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size); +void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size); +void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size); +void Curl_ratelimit(struct Curl_easy *data, struct curltime now); +int Curl_pgrsUpdate(struct connectdata *); +void Curl_pgrsResetTransferSizes(struct Curl_easy *data); +void Curl_pgrsTime(struct Curl_easy *data, timerid timer); +timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, + curl_off_t startsize, + curl_off_t limit, + struct curltime start, + struct curltime now); + +#define PGRS_HIDE (1<<4) +#define PGRS_UL_SIZE_KNOWN (1<<5) +#define PGRS_DL_SIZE_KNOWN (1<<6) +#define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */ + +#endif /* HEADER_CURL_PROGRESS_H */ diff --git a/libcurl/lib/psl.c b/libcurl/lib/psl.c new file mode 100644 index 0000000..568baff --- /dev/null +++ b/libcurl/lib/psl.c @@ -0,0 +1,111 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#ifdef USE_LIBPSL + +#include "psl.h" +#include "share.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +void Curl_psl_destroy(struct PslCache *pslcache) +{ + if(pslcache->psl) { + if(pslcache->dynamic) + psl_free((psl_ctx_t *) pslcache->psl); + pslcache->psl = NULL; + pslcache->dynamic = FALSE; + } +} + +static time_t now_seconds(void) +{ + struct curltime now = Curl_now(); + + return now.tv_sec; +} + +const psl_ctx_t *Curl_psl_use(struct Curl_easy *easy) +{ + struct PslCache *pslcache = easy->psl; + const psl_ctx_t *psl; + time_t now; + + if(!pslcache) + return NULL; + + Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SHARED); + now = now_seconds(); + if(!pslcache->psl || pslcache->expires <= now) { + /* Let a chance to other threads to do the job: avoids deadlock. */ + Curl_share_unlock(easy, CURL_LOCK_DATA_PSL); + + /* Update cache: this needs an exclusive lock. */ + Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SINGLE); + + /* Recheck in case another thread did the job. */ + now = now_seconds(); + if(!pslcache->psl || pslcache->expires <= now) { + bool dynamic = FALSE; + time_t expires = TIME_T_MAX; + +#if defined(PSL_VERSION_NUMBER) && PSL_VERSION_NUMBER >= 0x001000 + psl = psl_latest(NULL); + dynamic = psl != NULL; + /* Take care of possible time computation overflow. */ + expires = now < TIME_T_MAX - PSL_TTL? now + PSL_TTL: TIME_T_MAX; + + /* Only get the built-in PSL if we do not already have the "latest". */ + if(!psl && !pslcache->dynamic) +#endif + + psl = psl_builtin(); + + if(psl) { + Curl_psl_destroy(pslcache); + pslcache->psl = psl; + pslcache->dynamic = dynamic; + pslcache->expires = expires; + } + } + Curl_share_unlock(easy, CURL_LOCK_DATA_PSL); /* Release exclusive lock. */ + Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SHARED); + } + psl = pslcache->psl; + if(!psl) + Curl_share_unlock(easy, CURL_LOCK_DATA_PSL); + return psl; +} + +void Curl_psl_release(struct Curl_easy *easy) +{ + Curl_share_unlock(easy, CURL_LOCK_DATA_PSL); +} + +#endif /* USE_LIBPSL */ diff --git a/libcurl/lib/psl.h b/libcurl/lib/psl.h new file mode 100644 index 0000000..e9f99d0 --- /dev/null +++ b/libcurl/lib/psl.h @@ -0,0 +1,47 @@ +#ifndef HEADER_PSL_H +#define HEADER_PSL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#ifdef USE_LIBPSL +#include + +#define PSL_TTL (72 * 3600) /* PSL time to live before a refresh. */ + +struct PslCache { + const psl_ctx_t *psl; /* The PSL. */ + time_t expires; /* Time this PSL life expires. */ + bool dynamic; /* PSL should be released when no longer needed. */ +}; + +const psl_ctx_t *Curl_psl_use(struct Curl_easy *easy); +void Curl_psl_release(struct Curl_easy *easy); +void Curl_psl_destroy(struct PslCache *pslcache); + +#else + +#define Curl_psl_use(easy) NULL +#define Curl_psl_release(easy) +#define Curl_psl_destroy(pslcache) + +#endif /* USE_LIBPSL */ +#endif /* HEADER_PSL_H */ diff --git a/libcurl/lib/rand.c b/libcurl/lib/rand.c new file mode 100644 index 0000000..c415048 --- /dev/null +++ b/libcurl/lib/rand.c @@ -0,0 +1,186 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_FCNTL_H +#include +#endif + +#include +#include "vtls/vtls.h" +#include "sendf.h" +#include "rand.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) +{ + unsigned int r; + CURLcode result = CURLE_OK; + static unsigned int randseed; + static bool seeded = FALSE; + +#ifdef CURLDEBUG + char *force_entropy = getenv("CURL_ENTROPY"); + if(force_entropy) { + if(!seeded) { + unsigned int seed = 0; + size_t elen = strlen(force_entropy); + size_t clen = sizeof(seed); + size_t min = elen < clen ? elen : clen; + memcpy((char *)&seed, force_entropy, min); + randseed = ntohl(seed); + seeded = TRUE; + } + else + randseed++; + *rnd = randseed; + return CURLE_OK; + } +#endif + + /* data may be NULL! */ + result = Curl_ssl_random(data, (unsigned char *)rnd, sizeof(*rnd)); + if(result != CURLE_NOT_BUILT_IN) + /* only if there is no random function in the TLS backend do the non crypto + version, otherwise return result */ + return result; + + /* ---- non-cryptographic version following ---- */ + +#ifdef RANDOM_FILE + if(!seeded) { + /* if there's a random file to read a seed from, use it */ + int fd = open(RANDOM_FILE, O_RDONLY); + if(fd > -1) { + /* read random data into the randseed variable */ + ssize_t nread = read(fd, &randseed, sizeof(randseed)); + if(nread == sizeof(randseed)) + seeded = TRUE; + close(fd); + } + } +#endif + + if(!seeded) { + struct curltime now = Curl_now(); + infof(data, "WARNING: Using weak random seed\n"); + randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec; + randseed = randseed * 1103515245 + 12345; + randseed = randseed * 1103515245 + 12345; + randseed = randseed * 1103515245 + 12345; + seeded = TRUE; + } + + /* Return an unsigned 32-bit pseudo-random number. */ + r = randseed = randseed * 1103515245 + 12345; + *rnd = (r << 16) | ((r >> 16) & 0xFFFF); + return CURLE_OK; +} + +/* + * Curl_rand() stores 'num' number of random unsigned integers in the buffer + * 'rndptr' points to. + * + * If libcurl is built without TLS support or with a TLS backend that lacks a + * proper random API (Gskit or mbedTLS), this function will use "weak" random. + * + * When built *with* TLS support and a backend that offers strong random, it + * will return error if it cannot provide strong random values. + * + * NOTE: 'data' may be passed in as NULL when coming from external API without + * easy handle! + * + */ + +CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num) +{ + CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT; + + DEBUGASSERT(num > 0); + + while(num) { + unsigned int r; + size_t left = num < sizeof(unsigned int) ? num : sizeof(unsigned int); + + result = randit(data, &r); + if(result) + return result; + + while(left) { + *rnd++ = (unsigned char)(r & 0xFF); + r >>= 8; + --num; + --left; + } + } + + return result; +} + +/* + * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random + * hexadecimal digits PLUS a zero terminating byte. It must be an odd number + * size. + */ + +CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, + size_t num) +{ + CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT; + const char *hex = "0123456789abcdef"; + unsigned char buffer[128]; + unsigned char *bufp = buffer; + DEBUGASSERT(num > 1); + +#ifdef __clang_analyzer__ + /* This silences a scan-build warning about accessing this buffer with + uninitialized memory. */ + memset(buffer, 0, sizeof(buffer)); +#endif + + if((num/2 >= sizeof(buffer)) || !(num&1)) + /* make sure it fits in the local buffer and that it is an odd number! */ + return CURLE_BAD_FUNCTION_ARGUMENT; + + num--; /* save one for zero termination */ + + result = Curl_rand(data, buffer, num/2); + if(result) + return result; + + while(num) { + /* clang-tidy warns on this line without this comment: */ + /* NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult) */ + *rnd++ = hex[(*bufp & 0xF0)>>4]; + *rnd++ = hex[*bufp & 0x0F]; + bufp++; + num -= 2; + } + *rnd = 0; + + return result; +} diff --git a/libcurl/lib/rand.h b/libcurl/lib/rand.h new file mode 100644 index 0000000..3c8e2b8 --- /dev/null +++ b/libcurl/lib/rand.h @@ -0,0 +1,49 @@ +#ifndef HEADER_CURL_RAND_H +#define HEADER_CURL_RAND_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Curl_rand() stores 'num' number of random unsigned characters in the buffer + * 'rnd' points to. + * + * If libcurl is built without TLS support or with a TLS backend that lacks a + * proper random API (Gskit or mbedTLS), this function will use "weak" random. + * + * When built *with* TLS support and a backend that offers strong random, it + * will return error if it cannot provide strong random values. + * + * NOTE: 'data' may be passed in as NULL when coming from external API without + * easy handle! + * + */ +CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num); + +/* + * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random + * hexadecimal digits PLUS a zero terminating byte. It must be an odd number + * size. + */ +CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, + size_t num); + +#endif /* HEADER_CURL_RAND_H */ diff --git a/libcurl/lib/rtsp.c b/libcurl/lib/rtsp.c new file mode 100644 index 0000000..25e194a --- /dev/null +++ b/libcurl/lib/rtsp.c @@ -0,0 +1,827 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_RTSP + +#include "urldata.h" +#include +#include "transfer.h" +#include "sendf.h" +#include "multiif.h" +#include "http.h" +#include "url.h" +#include "progress.h" +#include "rtsp.h" +#include "strcase.h" +#include "select.h" +#include "connect.h" +#include "strdup.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#define RTP_PKT_CHANNEL(p) ((int)((unsigned char)((p)[1]))) + +#define RTP_PKT_LENGTH(p) ((((int)((unsigned char)((p)[2]))) << 8) | \ + ((int)((unsigned char)((p)[3])))) + +/* protocol-specific functions set up to be called by the main engine */ +static CURLcode rtsp_do(struct connectdata *conn, bool *done); +static CURLcode rtsp_done(struct connectdata *conn, CURLcode, bool premature); +static CURLcode rtsp_connect(struct connectdata *conn, bool *done); +static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead); + +static int rtsp_getsock_do(struct connectdata *conn, + curl_socket_t *socks, + int numsocks); + +/* + * Parse and write out any available RTP data. + * + * nread: amount of data left after k->str. will be modified if RTP + * data is parsed and k->str is moved up + * readmore: whether or not the RTP parser needs more data right away + */ +static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data, + struct connectdata *conn, + ssize_t *nread, + bool *readmore); + +static CURLcode rtsp_setup_connection(struct connectdata *conn); +static unsigned int rtsp_conncheck(struct connectdata *check, + unsigned int checks_to_perform); + +/* this returns the socket to wait for in the DO and DOING state for the multi + interface and then we're always _sending_ a request and thus we wait for + the single socket to become writable only */ +static int rtsp_getsock_do(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) +{ + /* write mode */ + (void)numsocks; /* unused, we trust it to be at least 1 */ + socks[0] = conn->sock[FIRSTSOCKET]; + return GETSOCK_WRITESOCK(0); +} + +static +CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len); + + +/* + * RTSP handler interface. + */ +const struct Curl_handler Curl_handler_rtsp = { + "RTSP", /* scheme */ + rtsp_setup_connection, /* setup_connection */ + rtsp_do, /* do_it */ + rtsp_done, /* done */ + ZERO_NULL, /* do_more */ + rtsp_connect, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + rtsp_getsock_do, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + rtsp_disconnect, /* disconnect */ + rtsp_rtp_readwrite, /* readwrite */ + rtsp_conncheck, /* connection_check */ + PORT_RTSP, /* defport */ + CURLPROTO_RTSP, /* protocol */ + PROTOPT_NONE /* flags */ +}; + + +static CURLcode rtsp_setup_connection(struct connectdata *conn) +{ + struct RTSP *rtsp; + + conn->data->req.protop = rtsp = calloc(1, sizeof(struct RTSP)); + if(!rtsp) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; +} + + +/* + * The server may send us RTP data at any point, and RTSPREQ_RECEIVE does not + * want to block the application forever while receiving a stream. Therefore, + * we cannot assume that an RTSP socket is dead just because it is readable. + * + * Instead, if it is readable, run Curl_connalive() to peek at the socket + * and distinguish between closed and data. + */ +static bool rtsp_connisdead(struct connectdata *check) +{ + int sval; + bool ret_val = TRUE; + + sval = SOCKET_READABLE(check->sock[FIRSTSOCKET], 0); + if(sval == 0) { + /* timeout */ + ret_val = FALSE; + } + else if(sval & CURL_CSELECT_ERR) { + /* socket is in an error state */ + ret_val = TRUE; + } + else if(sval & CURL_CSELECT_IN) { + /* readable with no error. could still be closed */ + ret_val = !Curl_connalive(check); + } + + return ret_val; +} + +/* + * Function to check on various aspects of a connection. + */ +static unsigned int rtsp_conncheck(struct connectdata *check, + unsigned int checks_to_perform) +{ + unsigned int ret_val = CONNRESULT_NONE; + + if(checks_to_perform & CONNCHECK_ISDEAD) { + if(rtsp_connisdead(check)) + ret_val |= CONNRESULT_DEAD; + } + + return ret_val; +} + + +static CURLcode rtsp_connect(struct connectdata *conn, bool *done) +{ + CURLcode httpStatus; + struct Curl_easy *data = conn->data; + + httpStatus = Curl_http_connect(conn, done); + + /* Initialize the CSeq if not already done */ + if(data->state.rtsp_next_client_CSeq == 0) + data->state.rtsp_next_client_CSeq = 1; + if(data->state.rtsp_next_server_CSeq == 0) + data->state.rtsp_next_server_CSeq = 1; + + conn->proto.rtspc.rtp_channel = -1; + + return httpStatus; +} + +static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead) +{ + (void) dead; + Curl_safefree(conn->proto.rtspc.rtp_buf); + return CURLE_OK; +} + + +static CURLcode rtsp_done(struct connectdata *conn, + CURLcode status, bool premature) +{ + struct Curl_easy *data = conn->data; + struct RTSP *rtsp = data->req.protop; + CURLcode httpStatus; + + /* Bypass HTTP empty-reply checks on receive */ + if(data->set.rtspreq == RTSPREQ_RECEIVE) + premature = TRUE; + + httpStatus = Curl_http_done(conn, status, premature); + + if(rtsp) { + /* Check the sequence numbers */ + long CSeq_sent = rtsp->CSeq_sent; + long CSeq_recv = rtsp->CSeq_recv; + if((data->set.rtspreq != RTSPREQ_RECEIVE) && (CSeq_sent != CSeq_recv)) { + failf(data, + "The CSeq of this request %ld did not match the response %ld", + CSeq_sent, CSeq_recv); + return CURLE_RTSP_CSEQ_ERROR; + } + if(data->set.rtspreq == RTSPREQ_RECEIVE && + (conn->proto.rtspc.rtp_channel == -1)) { + infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv); + } + } + + return httpStatus; +} + +static CURLcode rtsp_do(struct connectdata *conn, bool *done) +{ + struct Curl_easy *data = conn->data; + CURLcode result = CURLE_OK; + Curl_RtspReq rtspreq = data->set.rtspreq; + struct RTSP *rtsp = data->req.protop; + Curl_send_buffer *req_buffer; + curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */ + curl_off_t putsize = 0; /* for ANNOUNCE and SET_PARAMETER */ + + const char *p_request = NULL; + const char *p_session_id = NULL; + const char *p_accept = NULL; + const char *p_accept_encoding = NULL; + const char *p_range = NULL; + const char *p_referrer = NULL; + const char *p_stream_uri = NULL; + const char *p_transport = NULL; + const char *p_uagent = NULL; + const char *p_proxyuserpwd = NULL; + const char *p_userpwd = NULL; + + *done = TRUE; + + rtsp->CSeq_sent = data->state.rtsp_next_client_CSeq; + rtsp->CSeq_recv = 0; + + /* Setup the 'p_request' pointer to the proper p_request string + * Since all RTSP requests are included here, there is no need to + * support custom requests like HTTP. + **/ + data->set.opt_no_body = TRUE; /* most requests don't contain a body */ + switch(rtspreq) { + default: + failf(data, "Got invalid RTSP request"); + return CURLE_BAD_FUNCTION_ARGUMENT; + case RTSPREQ_OPTIONS: + p_request = "OPTIONS"; + break; + case RTSPREQ_DESCRIBE: + p_request = "DESCRIBE"; + data->set.opt_no_body = FALSE; + break; + case RTSPREQ_ANNOUNCE: + p_request = "ANNOUNCE"; + break; + case RTSPREQ_SETUP: + p_request = "SETUP"; + break; + case RTSPREQ_PLAY: + p_request = "PLAY"; + break; + case RTSPREQ_PAUSE: + p_request = "PAUSE"; + break; + case RTSPREQ_TEARDOWN: + p_request = "TEARDOWN"; + break; + case RTSPREQ_GET_PARAMETER: + /* GET_PARAMETER's no_body status is determined later */ + p_request = "GET_PARAMETER"; + data->set.opt_no_body = FALSE; + break; + case RTSPREQ_SET_PARAMETER: + p_request = "SET_PARAMETER"; + break; + case RTSPREQ_RECORD: + p_request = "RECORD"; + break; + case RTSPREQ_RECEIVE: + p_request = ""; + /* Treat interleaved RTP as body*/ + data->set.opt_no_body = FALSE; + break; + case RTSPREQ_LAST: + failf(data, "Got invalid RTSP request: RTSPREQ_LAST"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + + if(rtspreq == RTSPREQ_RECEIVE) { + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1); + + return result; + } + + p_session_id = data->set.str[STRING_RTSP_SESSION_ID]; + if(!p_session_id && + (rtspreq & ~(RTSPREQ_OPTIONS | RTSPREQ_DESCRIBE | RTSPREQ_SETUP))) { + failf(data, "Refusing to issue an RTSP request [%s] without a session ID.", + p_request); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + + /* Stream URI. Default to server '*' if not specified */ + if(data->set.str[STRING_RTSP_STREAM_URI]) { + p_stream_uri = data->set.str[STRING_RTSP_STREAM_URI]; + } + else { + p_stream_uri = "*"; + } + + /* Transport Header for SETUP requests */ + p_transport = Curl_checkheaders(conn, "Transport"); + if(rtspreq == RTSPREQ_SETUP && !p_transport) { + /* New Transport: setting? */ + if(data->set.str[STRING_RTSP_TRANSPORT]) { + Curl_safefree(conn->allocptr.rtsp_transport); + + conn->allocptr.rtsp_transport = + aprintf("Transport: %s\r\n", + data->set.str[STRING_RTSP_TRANSPORT]); + if(!conn->allocptr.rtsp_transport) + return CURLE_OUT_OF_MEMORY; + } + else { + failf(data, + "Refusing to issue an RTSP SETUP without a Transport: header."); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + + p_transport = conn->allocptr.rtsp_transport; + } + + /* Accept Headers for DESCRIBE requests */ + if(rtspreq == RTSPREQ_DESCRIBE) { + /* Accept Header */ + p_accept = Curl_checkheaders(conn, "Accept")? + NULL:"Accept: application/sdp\r\n"; + + /* Accept-Encoding header */ + if(!Curl_checkheaders(conn, "Accept-Encoding") && + data->set.str[STRING_ENCODING]) { + Curl_safefree(conn->allocptr.accept_encoding); + conn->allocptr.accept_encoding = + aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]); + + if(!conn->allocptr.accept_encoding) + return CURLE_OUT_OF_MEMORY; + + p_accept_encoding = conn->allocptr.accept_encoding; + } + } + + /* The User-Agent string might have been allocated in url.c already, because + it might have been used in the proxy connect, but if we have got a header + with the user-agent string specified, we erase the previously made string + here. */ + if(Curl_checkheaders(conn, "User-Agent") && conn->allocptr.uagent) { + Curl_safefree(conn->allocptr.uagent); + conn->allocptr.uagent = NULL; + } + else if(!Curl_checkheaders(conn, "User-Agent") && + data->set.str[STRING_USERAGENT]) { + p_uagent = conn->allocptr.uagent; + } + + /* setup the authentication headers */ + result = Curl_http_output_auth(conn, p_request, p_stream_uri, FALSE); + if(result) + return result; + + p_proxyuserpwd = conn->allocptr.proxyuserpwd; + p_userpwd = conn->allocptr.userpwd; + + /* Referrer */ + Curl_safefree(conn->allocptr.ref); + if(data->change.referer && !Curl_checkheaders(conn, "Referer")) + conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer); + else + conn->allocptr.ref = NULL; + + p_referrer = conn->allocptr.ref; + + /* + * Range Header + * Only applies to PLAY, PAUSE, RECORD + * + * Go ahead and use the Range stuff supplied for HTTP + */ + if(data->state.use_range && + (rtspreq & (RTSPREQ_PLAY | RTSPREQ_PAUSE | RTSPREQ_RECORD))) { + + /* Check to see if there is a range set in the custom headers */ + if(!Curl_checkheaders(conn, "Range") && data->state.range) { + Curl_safefree(conn->allocptr.rangeline); + conn->allocptr.rangeline = aprintf("Range: %s\r\n", data->state.range); + p_range = conn->allocptr.rangeline; + } + } + + /* + * Sanity check the custom headers + */ + if(Curl_checkheaders(conn, "CSeq")) { + failf(data, "CSeq cannot be set as a custom header."); + return CURLE_RTSP_CSEQ_ERROR; + } + if(Curl_checkheaders(conn, "Session")) { + failf(data, "Session ID cannot be set as a custom header."); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + + /* Initialize a dynamic send buffer */ + req_buffer = Curl_add_buffer_init(); + + if(!req_buffer) + return CURLE_OUT_OF_MEMORY; + + result = + Curl_add_bufferf(&req_buffer, + "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */ + "CSeq: %ld\r\n", /* CSeq */ + p_request, p_stream_uri, rtsp->CSeq_sent); + if(result) + return result; + + /* + * Rather than do a normal alloc line, keep the session_id unformatted + * to make comparison easier + */ + if(p_session_id) { + result = Curl_add_bufferf(&req_buffer, "Session: %s\r\n", p_session_id); + if(result) + return result; + } + + /* + * Shared HTTP-like options + */ + result = Curl_add_bufferf(&req_buffer, + "%s" /* transport */ + "%s" /* accept */ + "%s" /* accept-encoding */ + "%s" /* range */ + "%s" /* referrer */ + "%s" /* user-agent */ + "%s" /* proxyuserpwd */ + "%s" /* userpwd */ + , + p_transport ? p_transport : "", + p_accept ? p_accept : "", + p_accept_encoding ? p_accept_encoding : "", + p_range ? p_range : "", + p_referrer ? p_referrer : "", + p_uagent ? p_uagent : "", + p_proxyuserpwd ? p_proxyuserpwd : "", + p_userpwd ? p_userpwd : ""); + + /* + * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM + * with basic and digest, it will be freed anyway by the next request + */ + Curl_safefree(conn->allocptr.userpwd); + conn->allocptr.userpwd = NULL; + + if(result) + return result; + + if((rtspreq == RTSPREQ_SETUP) || (rtspreq == RTSPREQ_DESCRIBE)) { + result = Curl_add_timecondition(conn, req_buffer); + if(result) + return result; + } + + result = Curl_add_custom_headers(conn, FALSE, req_buffer); + if(result) + return result; + + if(rtspreq == RTSPREQ_ANNOUNCE || + rtspreq == RTSPREQ_SET_PARAMETER || + rtspreq == RTSPREQ_GET_PARAMETER) { + + if(data->set.upload) { + putsize = data->state.infilesize; + data->set.httpreq = HTTPREQ_PUT; + + } + else { + postsize = (data->state.infilesize != -1)? + data->state.infilesize: + (data->set.postfields? (curl_off_t)strlen(data->set.postfields):0); + data->set.httpreq = HTTPREQ_POST; + } + + if(putsize > 0 || postsize > 0) { + /* As stated in the http comments, it is probably not wise to + * actually set a custom Content-Length in the headers */ + if(!Curl_checkheaders(conn, "Content-Length")) { + result = + Curl_add_bufferf(&req_buffer, + "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n", + (data->set.upload ? putsize : postsize)); + if(result) + return result; + } + + if(rtspreq == RTSPREQ_SET_PARAMETER || + rtspreq == RTSPREQ_GET_PARAMETER) { + if(!Curl_checkheaders(conn, "Content-Type")) { + result = Curl_add_bufferf(&req_buffer, + "Content-Type: text/parameters\r\n"); + if(result) + return result; + } + } + + if(rtspreq == RTSPREQ_ANNOUNCE) { + if(!Curl_checkheaders(conn, "Content-Type")) { + result = Curl_add_bufferf(&req_buffer, + "Content-Type: application/sdp\r\n"); + if(result) + return result; + } + } + + data->state.expect100header = FALSE; /* RTSP posts are simple/small */ + } + else if(rtspreq == RTSPREQ_GET_PARAMETER) { + /* Check for an empty GET_PARAMETER (heartbeat) request */ + data->set.httpreq = HTTPREQ_HEAD; + data->set.opt_no_body = TRUE; + } + } + + /* RTSP never allows chunked transfer */ + data->req.forbidchunk = TRUE; + /* Finish the request buffer */ + result = Curl_add_buffer(&req_buffer, "\r\n", 2); + if(result) + return result; + + if(postsize > 0) { + result = Curl_add_buffer(&req_buffer, data->set.postfields, + (size_t)postsize); + if(result) + return result; + } + + /* issue the request */ + result = Curl_add_buffer_send(&req_buffer, conn, + &data->info.request_size, 0, FIRSTSOCKET); + if(result) { + failf(data, "Failed sending RTSP request"); + return result; + } + + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, putsize?FIRSTSOCKET:-1); + + /* Increment the CSeq on success */ + data->state.rtsp_next_client_CSeq++; + + if(data->req.writebytecount) { + /* if a request-body has been sent off, we make sure this progress is + noted properly */ + Curl_pgrsSetUploadCounter(data, data->req.writebytecount); + if(Curl_pgrsUpdate(conn)) + result = CURLE_ABORTED_BY_CALLBACK; + } + + return result; +} + + +static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data, + struct connectdata *conn, + ssize_t *nread, + bool *readmore) { + struct SingleRequest *k = &data->req; + struct rtsp_conn *rtspc = &(conn->proto.rtspc); + + char *rtp; /* moving pointer to rtp data */ + ssize_t rtp_dataleft; /* how much data left to parse in this round */ + char *scratch; + CURLcode result; + + if(rtspc->rtp_buf) { + /* There was some leftover data the last time. Merge buffers */ + char *newptr = Curl_saferealloc(rtspc->rtp_buf, + rtspc->rtp_bufsize + *nread); + if(!newptr) { + rtspc->rtp_buf = NULL; + rtspc->rtp_bufsize = 0; + return CURLE_OUT_OF_MEMORY; + } + rtspc->rtp_buf = newptr; + memcpy(rtspc->rtp_buf + rtspc->rtp_bufsize, k->str, *nread); + rtspc->rtp_bufsize += *nread; + rtp = rtspc->rtp_buf; + rtp_dataleft = rtspc->rtp_bufsize; + } + else { + /* Just parse the request buffer directly */ + rtp = k->str; + rtp_dataleft = *nread; + } + + while((rtp_dataleft > 0) && + (rtp[0] == '$')) { + if(rtp_dataleft > 4) { + int rtp_length; + + /* Parse the header */ + /* The channel identifier immediately follows and is 1 byte */ + rtspc->rtp_channel = RTP_PKT_CHANNEL(rtp); + + /* The length is two bytes */ + rtp_length = RTP_PKT_LENGTH(rtp); + + if(rtp_dataleft < rtp_length + 4) { + /* Need more - incomplete payload*/ + *readmore = TRUE; + break; + } + /* We have the full RTP interleaved packet + * Write out the header including the leading '$' */ + DEBUGF(infof(data, "RTP write channel %d rtp_length %d\n", + rtspc->rtp_channel, rtp_length)); + result = rtp_client_write(conn, &rtp[0], rtp_length + 4); + if(result) { + failf(data, "Got an error writing an RTP packet"); + *readmore = FALSE; + Curl_safefree(rtspc->rtp_buf); + rtspc->rtp_buf = NULL; + rtspc->rtp_bufsize = 0; + return result; + } + + /* Move forward in the buffer */ + rtp_dataleft -= rtp_length + 4; + rtp += rtp_length + 4; + + if(data->set.rtspreq == RTSPREQ_RECEIVE) { + /* If we are in a passive receive, give control back + * to the app as often as we can. + */ + k->keepon &= ~KEEP_RECV; + } + } + else { + /* Need more - incomplete header */ + *readmore = TRUE; + break; + } + } + + if(rtp_dataleft != 0 && rtp[0] == '$') { + DEBUGF(infof(data, "RTP Rewinding %zd %s\n", rtp_dataleft, + *readmore ? "(READMORE)" : "")); + + /* Store the incomplete RTP packet for a "rewind" */ + scratch = malloc(rtp_dataleft); + if(!scratch) { + Curl_safefree(rtspc->rtp_buf); + rtspc->rtp_buf = NULL; + rtspc->rtp_bufsize = 0; + return CURLE_OUT_OF_MEMORY; + } + memcpy(scratch, rtp, rtp_dataleft); + Curl_safefree(rtspc->rtp_buf); + rtspc->rtp_buf = scratch; + rtspc->rtp_bufsize = rtp_dataleft; + + /* As far as the transfer is concerned, this data is consumed */ + *nread = 0; + return CURLE_OK; + } + /* Fix up k->str to point just after the last RTP packet */ + k->str += *nread - rtp_dataleft; + + /* either all of the data has been read or... + * rtp now points at the next byte to parse + */ + if(rtp_dataleft > 0) + DEBUGASSERT(k->str[0] == rtp[0]); + + DEBUGASSERT(rtp_dataleft <= *nread); /* sanity check */ + + *nread = rtp_dataleft; + + /* If we get here, we have finished with the leftover/merge buffer */ + Curl_safefree(rtspc->rtp_buf); + rtspc->rtp_buf = NULL; + rtspc->rtp_bufsize = 0; + + return CURLE_OK; +} + +static +CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len) +{ + struct Curl_easy *data = conn->data; + size_t wrote; + curl_write_callback writeit; + void *user_ptr; + + if(len == 0) { + failf(data, "Cannot write a 0 size RTP packet."); + return CURLE_WRITE_ERROR; + } + + /* If the user has configured CURLOPT_INTERLEAVEFUNCTION then use that + function and any configured CURLOPT_INTERLEAVEDATA to write out the RTP + data. Otherwise, use the CURLOPT_WRITEFUNCTION with the CURLOPT_WRITEDATA + pointer to write out the RTP data. */ + if(data->set.fwrite_rtp) { + writeit = data->set.fwrite_rtp; + user_ptr = data->set.rtp_out; + } + else { + writeit = data->set.fwrite_func; + user_ptr = data->set.out; + } + + Curl_set_in_callback(data, true); + wrote = writeit(ptr, 1, len, user_ptr); + Curl_set_in_callback(data, false); + + if(CURL_WRITEFUNC_PAUSE == wrote) { + failf(data, "Cannot pause RTP"); + return CURLE_WRITE_ERROR; + } + + if(wrote != len) { + failf(data, "Failed writing RTP data"); + return CURLE_WRITE_ERROR; + } + + return CURLE_OK; +} + +CURLcode Curl_rtsp_parseheader(struct connectdata *conn, + char *header) +{ + struct Curl_easy *data = conn->data; + long CSeq = 0; + + if(checkprefix("CSeq:", header)) { + /* Store the received CSeq. Match is verified in rtsp_done */ + int nc = sscanf(&header[4], ": %ld", &CSeq); + if(nc == 1) { + struct RTSP *rtsp = data->req.protop; + rtsp->CSeq_recv = CSeq; /* mark the request */ + data->state.rtsp_CSeq_recv = CSeq; /* update the handle */ + } + else { + failf(data, "Unable to read the CSeq header: [%s]", header); + return CURLE_RTSP_CSEQ_ERROR; + } + } + else if(checkprefix("Session:", header)) { + char *start; + + /* Find the first non-space letter */ + start = header + 8; + while(*start && ISSPACE(*start)) + start++; + + if(!*start) { + failf(data, "Got a blank Session ID"); + } + else if(data->set.str[STRING_RTSP_SESSION_ID]) { + /* If the Session ID is set, then compare */ + if(strncmp(start, data->set.str[STRING_RTSP_SESSION_ID], + strlen(data->set.str[STRING_RTSP_SESSION_ID])) != 0) { + failf(data, "Got RTSP Session ID Line [%s], but wanted ID [%s]", + start, data->set.str[STRING_RTSP_SESSION_ID]); + return CURLE_RTSP_SESSION_ERROR; + } + } + else { + /* If the Session ID is not set, and we find it in a response, then set + * it. + * + * Allow any non whitespace content, up to the field separator or end of + * line. RFC 2326 isn't 100% clear on the session ID and for example + * gstreamer does url-encoded session ID's not covered by the standard. + */ + char *end = start; + while(*end && *end != ';' && !ISSPACE(*end)) + end++; + + /* Copy the id substring into a new buffer */ + data->set.str[STRING_RTSP_SESSION_ID] = malloc(end - start + 1); + if(data->set.str[STRING_RTSP_SESSION_ID] == NULL) + return CURLE_OUT_OF_MEMORY; + memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, end - start); + (data->set.str[STRING_RTSP_SESSION_ID])[end - start] = '\0'; + } + } + return CURLE_OK; +} + +#endif /* CURL_DISABLE_RTSP */ diff --git a/libcurl/lib/rtsp.h b/libcurl/lib/rtsp.h new file mode 100644 index 0000000..2f9cc32 --- /dev/null +++ b/libcurl/lib/rtsp.h @@ -0,0 +1,66 @@ +#ifndef HEADER_CURL_RTSP_H +#define HEADER_CURL_RTSP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifndef CURL_DISABLE_RTSP + +extern const struct Curl_handler Curl_handler_rtsp; + +CURLcode Curl_rtsp_parseheader(struct connectdata *conn, char *header); + +#else +/* disabled */ +#define Curl_rtsp_parseheader(x,y) CURLE_NOT_BUILT_IN + +#endif /* CURL_DISABLE_RTSP */ + +/* + * RTSP Connection data + * + * Currently, only used for tracking incomplete RTP data reads + */ +struct rtsp_conn { + char *rtp_buf; + ssize_t rtp_bufsize; + int rtp_channel; +}; + +/**************************************************************************** + * RTSP unique setup + ***************************************************************************/ +struct RTSP { + /* + * http_wrapper MUST be the first element of this structure for the wrap + * logic to work. In this way, we get a cheap polymorphism because + * &(data->state.proto.rtsp) == &(data->state.proto.http) per the C spec + * + * HTTP functions can safely treat this as an HTTP struct, but RTSP aware + * functions can also index into the later elements. + */ + struct HTTP http_wrapper; /*wrap HTTP to do the heavy lifting */ + + long CSeq_sent; /* CSeq of this request */ + long CSeq_recv; /* CSeq received */ +}; + + +#endif /* HEADER_CURL_RTSP_H */ diff --git a/libcurl/lib/security.c b/libcurl/lib/security.c new file mode 100644 index 0000000..550ea2d --- /dev/null +++ b/libcurl/lib/security.c @@ -0,0 +1,581 @@ +/* This source code was modified by Martin Hedenfalk for + * use in Curl. His latest changes were done 2000-09-18. + * + * It has since been patched and modified a lot by Daniel Stenberg + * to make it better applied to curl conditions, and to make + * it not use globals, pollute name space and more. This source code awaits a + * rewrite to work around the paragraph 2 in the BSD licenses as explained + * below. + * + * Copyright (c) 1998, 1999, 2017 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * + * Copyright (C) 2001 - 2019, Daniel Stenberg, , et al. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_FTP +#ifdef HAVE_GSSAPI + +#ifdef HAVE_NETDB_H +#include +#endif + +#include + +#include "urldata.h" +#include "curl_base64.h" +#include "curl_memory.h" +#include "curl_sec.h" +#include "ftp.h" +#include "sendf.h" +#include "strcase.h" +#include "warnless.h" +#include "strdup.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +static const struct { + enum protection_level level; + const char *name; +} level_names[] = { + { PROT_CLEAR, "clear" }, + { PROT_SAFE, "safe" }, + { PROT_CONFIDENTIAL, "confidential" }, + { PROT_PRIVATE, "private" } +}; + +static enum protection_level +name_to_level(const char *name) +{ + int i; + for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++) + if(checkprefix(name, level_names[i].name)) + return level_names[i].level; + return PROT_NONE; +} + +/* Convert a protocol |level| to its char representation. + We take an int to catch programming mistakes. */ +static char level_to_char(int level) +{ + switch(level) { + case PROT_CLEAR: + return 'C'; + case PROT_SAFE: + return 'S'; + case PROT_CONFIDENTIAL: + return 'E'; + case PROT_PRIVATE: + return 'P'; + case PROT_CMD: + /* Fall through */ + default: + /* Those 2 cases should not be reached! */ + break; + } + DEBUGASSERT(0); + /* Default to the most secure alternative. */ + return 'P'; +} + +/* Send an FTP command defined by |message| and the optional arguments. The + function returns the ftp_code. If an error occurs, -1 is returned. */ +static int ftp_send_command(struct connectdata *conn, const char *message, ...) +{ + int ftp_code; + ssize_t nread = 0; + va_list args; + char print_buffer[50]; + + va_start(args, message); + mvsnprintf(print_buffer, sizeof(print_buffer), message, args); + va_end(args); + + if(Curl_ftpsend(conn, print_buffer)) { + ftp_code = -1; + } + else { + if(Curl_GetFTPResponse(&nread, conn, &ftp_code)) + ftp_code = -1; + } + + (void)nread; /* Unused */ + return ftp_code; +} + +/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode + saying whether an error occurred or CURLE_OK if |len| was read. */ +static CURLcode +socket_read(curl_socket_t fd, void *to, size_t len) +{ + char *to_p = to; + CURLcode result; + ssize_t nread = 0; + + while(len > 0) { + result = Curl_read_plain(fd, to_p, len, &nread); + if(!result) { + len -= nread; + to_p += nread; + } + else { + if(result == CURLE_AGAIN) + continue; + return result; + } + } + return CURLE_OK; +} + + +/* Write |len| bytes from the buffer |to| to the socket |fd|. Return a + CURLcode saying whether an error occurred or CURLE_OK if |len| was + written. */ +static CURLcode +socket_write(struct connectdata *conn, curl_socket_t fd, const void *to, + size_t len) +{ + const char *to_p = to; + CURLcode result; + ssize_t written; + + while(len > 0) { + result = Curl_write_plain(conn, fd, to_p, len, &written); + if(!result) { + len -= written; + to_p += written; + } + else { + if(result == CURLE_AGAIN) + continue; + return result; + } + } + return CURLE_OK; +} + +static CURLcode read_data(struct connectdata *conn, + curl_socket_t fd, + struct krb5buffer *buf) +{ + int len; + void *tmp = NULL; + CURLcode result; + + result = socket_read(fd, &len, sizeof(len)); + if(result) + return result; + + if(len) { + /* only realloc if there was a length */ + len = ntohl(len); + tmp = Curl_saferealloc(buf->data, len); + } + if(tmp == NULL) + return CURLE_OUT_OF_MEMORY; + + buf->data = tmp; + result = socket_read(fd, buf->data, len); + if(result) + return result; + buf->size = conn->mech->decode(conn->app_data, buf->data, len, + conn->data_prot, conn); + buf->index = 0; + return CURLE_OK; +} + +static size_t +buffer_read(struct krb5buffer *buf, void *data, size_t len) +{ + if(buf->size - buf->index < len) + len = buf->size - buf->index; + memcpy(data, (char *)buf->data + buf->index, len); + buf->index += len; + return len; +} + +/* Matches Curl_recv signature */ +static ssize_t sec_recv(struct connectdata *conn, int sockindex, + char *buffer, size_t len, CURLcode *err) +{ + size_t bytes_read; + size_t total_read = 0; + curl_socket_t fd = conn->sock[sockindex]; + + *err = CURLE_OK; + + /* Handle clear text response. */ + if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR) + return read(fd, buffer, len); + + if(conn->in_buffer.eof_flag) { + conn->in_buffer.eof_flag = 0; + return 0; + } + + bytes_read = buffer_read(&conn->in_buffer, buffer, len); + len -= bytes_read; + total_read += bytes_read; + buffer += bytes_read; + + while(len > 0) { + if(read_data(conn, fd, &conn->in_buffer)) + return -1; + if(conn->in_buffer.size == 0) { + if(bytes_read > 0) + conn->in_buffer.eof_flag = 1; + return bytes_read; + } + bytes_read = buffer_read(&conn->in_buffer, buffer, len); + len -= bytes_read; + total_read += bytes_read; + buffer += bytes_read; + } + return total_read; +} + +/* Send |length| bytes from |from| to the |fd| socket taking care of encoding + and negotiating with the server. |from| can be NULL. */ +static void do_sec_send(struct connectdata *conn, curl_socket_t fd, + const char *from, int length) +{ + int bytes, htonl_bytes; /* 32-bit integers for htonl */ + char *buffer = NULL; + char *cmd_buffer; + size_t cmd_size = 0; + CURLcode error; + enum protection_level prot_level = conn->data_prot; + bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE; + + DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST); + + if(iscmd) { + if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5)) + prot_level = PROT_PRIVATE; + else + prot_level = conn->command_prot; + } + bytes = conn->mech->encode(conn->app_data, from, length, prot_level, + (void **)&buffer); + if(!buffer || bytes <= 0) + return; /* error */ + + if(iscmd) { + error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes), + &cmd_buffer, &cmd_size); + if(error) { + free(buffer); + return; /* error */ + } + if(cmd_size > 0) { + static const char *enc = "ENC "; + static const char *mic = "MIC "; + if(prot_level == PROT_PRIVATE) + socket_write(conn, fd, enc, 4); + else + socket_write(conn, fd, mic, 4); + + socket_write(conn, fd, cmd_buffer, cmd_size); + socket_write(conn, fd, "\r\n", 2); + infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic, + cmd_buffer); + free(cmd_buffer); + } + } + else { + htonl_bytes = htonl(bytes); + socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes)); + socket_write(conn, fd, buffer, curlx_sitouz(bytes)); + } + free(buffer); +} + +static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd, + const char *buffer, size_t length) +{ + ssize_t tx = 0, len = conn->buffer_size; + + len -= conn->mech->overhead(conn->app_data, conn->data_prot, + curlx_sztosi(len)); + if(len <= 0) + len = length; + while(length) { + if(length < (size_t)len) + len = length; + + do_sec_send(conn, fd, buffer, curlx_sztosi(len)); + length -= len; + buffer += len; + tx += len; + } + return tx; +} + +/* Matches Curl_send signature */ +static ssize_t sec_send(struct connectdata *conn, int sockindex, + const void *buffer, size_t len, CURLcode *err) +{ + curl_socket_t fd = conn->sock[sockindex]; + *err = CURLE_OK; + return sec_write(conn, fd, buffer, len); +} + +int Curl_sec_read_msg(struct connectdata *conn, char *buffer, + enum protection_level level) +{ + /* decoded_len should be size_t or ssize_t but conn->mech->decode returns an + int */ + int decoded_len; + char *buf; + int ret_code = 0; + size_t decoded_sz = 0; + CURLcode error; + + if(!conn->mech) + /* not inititalized, return error */ + return -1; + + DEBUGASSERT(level > PROT_NONE && level < PROT_LAST); + + error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz); + if(error || decoded_sz == 0) + return -1; + + if(decoded_sz > (size_t)INT_MAX) { + free(buf); + return -1; + } + decoded_len = curlx_uztosi(decoded_sz); + + decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len, + level, conn); + if(decoded_len <= 0) { + free(buf); + return -1; + } + + if(conn->data->set.verbose) { + buf[decoded_len] = '\n'; + Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1); + } + + buf[decoded_len] = '\0'; + if(decoded_len <= 3) + /* suspiciously short */ + return 0; + + if(buf[3] != '-') + /* safe to ignore return code */ + (void)sscanf(buf, "%d", &ret_code); + + if(buf[decoded_len - 1] == '\n') + buf[decoded_len - 1] = '\0'; + strcpy(buffer, buf); + free(buf); + return ret_code; +} + +static int sec_set_protection_level(struct connectdata *conn) +{ + int code; + enum protection_level level = conn->request_data_prot; + + DEBUGASSERT(level > PROT_NONE && level < PROT_LAST); + + if(!conn->sec_complete) { + infof(conn->data, "Trying to change the protection level after the" + " completion of the data exchange.\n"); + return -1; + } + + /* Bail out if we try to set up the same level */ + if(conn->data_prot == level) + return 0; + + if(level) { + char *pbsz; + static unsigned int buffer_size = 1 << 20; /* 1048576 */ + + code = ftp_send_command(conn, "PBSZ %u", buffer_size); + if(code < 0) + return -1; + + if(code/100 != 2) { + failf(conn->data, "Failed to set the protection's buffer size."); + return -1; + } + conn->buffer_size = buffer_size; + + pbsz = strstr(conn->data->state.buffer, "PBSZ="); + if(pbsz) { + /* ignore return code, use default value if it fails */ + (void)sscanf(pbsz, "PBSZ=%u", &buffer_size); + if(buffer_size < conn->buffer_size) + conn->buffer_size = buffer_size; + } + } + + /* Now try to negiociate the protection level. */ + code = ftp_send_command(conn, "PROT %c", level_to_char(level)); + + if(code < 0) + return -1; + + if(code/100 != 2) { + failf(conn->data, "Failed to set the protection level."); + return -1; + } + + conn->data_prot = level; + if(level == PROT_PRIVATE) + conn->command_prot = level; + + return 0; +} + +int +Curl_sec_request_prot(struct connectdata *conn, const char *level) +{ + enum protection_level l = name_to_level(level); + if(l == PROT_NONE) + return -1; + DEBUGASSERT(l > PROT_NONE && l < PROT_LAST); + conn->request_data_prot = l; + return 0; +} + +static CURLcode choose_mech(struct connectdata *conn) +{ + int ret; + struct Curl_easy *data = conn->data; + void *tmp_allocation; + const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech; + + tmp_allocation = realloc(conn->app_data, mech->size); + if(tmp_allocation == NULL) { + failf(data, "Failed realloc of size %zu", mech->size); + mech = NULL; + return CURLE_OUT_OF_MEMORY; + } + conn->app_data = tmp_allocation; + + if(mech->init) { + ret = mech->init(conn->app_data); + if(ret) { + infof(data, "Failed initialization for %s. Skipping it.\n", + mech->name); + return CURLE_FAILED_INIT; + } + } + + infof(data, "Trying mechanism %s...\n", mech->name); + ret = ftp_send_command(conn, "AUTH %s", mech->name); + if(ret < 0) + return CURLE_COULDNT_CONNECT; + + if(ret/100 != 3) { + switch(ret) { + case 504: + infof(data, "Mechanism %s is not supported by the server (server " + "returned ftp code: 504).\n", mech->name); + break; + case 534: + infof(data, "Mechanism %s was rejected by the server (server returned " + "ftp code: 534).\n", mech->name); + break; + default: + if(ret/100 == 5) { + infof(data, "server does not support the security extensions\n"); + return CURLE_USE_SSL_FAILED; + } + break; + } + return CURLE_LOGIN_DENIED; + } + + /* Authenticate */ + ret = mech->auth(conn->app_data, conn); + + if(ret != AUTH_CONTINUE) { + if(ret != AUTH_OK) { + /* Mechanism has dumped the error to stderr, don't error here. */ + return -1; + } + DEBUGASSERT(ret == AUTH_OK); + + conn->mech = mech; + conn->sec_complete = 1; + conn->recv[FIRSTSOCKET] = sec_recv; + conn->send[FIRSTSOCKET] = sec_send; + conn->recv[SECONDARYSOCKET] = sec_recv; + conn->send[SECONDARYSOCKET] = sec_send; + conn->command_prot = PROT_SAFE; + /* Set the requested protection level */ + /* BLOCKING */ + (void)sec_set_protection_level(conn); + } + + return CURLE_OK; +} + +CURLcode +Curl_sec_login(struct connectdata *conn) +{ + return choose_mech(conn); +} + + +void +Curl_sec_end(struct connectdata *conn) +{ + if(conn->mech != NULL && conn->mech->end) + conn->mech->end(conn->app_data); + free(conn->app_data); + conn->app_data = NULL; + if(conn->in_buffer.data) { + free(conn->in_buffer.data); + conn->in_buffer.data = NULL; + conn->in_buffer.size = 0; + conn->in_buffer.index = 0; + conn->in_buffer.eof_flag = 0; + } + conn->sec_complete = 0; + conn->data_prot = PROT_CLEAR; + conn->mech = NULL; +} + +#endif /* HAVE_GSSAPI */ + +#endif /* CURL_DISABLE_FTP */ diff --git a/libcurl/lib/select.c b/libcurl/lib/select.c new file mode 100644 index 0000000..8cd9eb2 --- /dev/null +++ b/libcurl/lib/select.c @@ -0,0 +1,585 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE) +#error "We can't compile without select() or poll() support." +#endif + +#if defined(__BEOS__) && !defined(__HAIKU__) +/* BeOS has FD_SET defined in socket.h */ +#include +#endif + +#ifdef MSDOS +#include /* delay() */ +#endif + +#ifdef __VXWORKS__ +#include /* bzero() in FD_SET */ +#endif + +#include + +#include "urldata.h" +#include "connect.h" +#include "select.h" +#include "warnless.h" + +/* Convenience local macros */ +#define ELAPSED_MS() (int)Curl_timediff(Curl_now(), initial_tv) + +int Curl_ack_eintr = 0; +#define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR) + +/* + * Internal function used for waiting a specific amount of ms + * in Curl_socket_check() and Curl_poll() when no file descriptor + * is provided to wait on, just being used to delay execution. + * WinSock select() and poll() timeout mechanisms need a valid + * socket descriptor in a not null file descriptor set to work. + * Waiting indefinitely with this function is not allowed, a + * zero or negative timeout value will return immediately. + * Timeout resolution, accuracy, as well as maximum supported + * value is system dependent, neither factor is a citical issue + * for the intended use of this function in the library. + * + * Return values: + * -1 = system call error, invalid timeout value, or interrupted + * 0 = specified timeout has elapsed + */ +int Curl_wait_ms(int timeout_ms) +{ +#if !defined(MSDOS) && !defined(USE_WINSOCK) +#ifndef HAVE_POLL_FINE + struct timeval pending_tv; +#endif + struct curltime initial_tv; + int pending_ms; +#endif + int r = 0; + + if(!timeout_ms) + return 0; + if(timeout_ms < 0) { + SET_SOCKERRNO(EINVAL); + return -1; + } +#if defined(MSDOS) + delay(timeout_ms); +#elif defined(USE_WINSOCK) + Sleep(timeout_ms); +#else + pending_ms = timeout_ms; + initial_tv = Curl_now(); + do { + int error; +#if defined(HAVE_POLL_FINE) + r = poll(NULL, 0, pending_ms); +#else + pending_tv.tv_sec = pending_ms / 1000; + pending_tv.tv_usec = (pending_ms % 1000) * 1000; + r = select(0, NULL, NULL, NULL, &pending_tv); +#endif /* HAVE_POLL_FINE */ + if(r != -1) + break; + error = SOCKERRNO; + if(error && ERROR_NOT_EINTR(error)) + break; + pending_ms = timeout_ms - ELAPSED_MS(); + if(pending_ms <= 0) { + r = 0; /* Simulate a "call timed out" case */ + break; + } + } while(r == -1); +#endif /* USE_WINSOCK */ + if(r) + r = -1; + return r; +} + +/* + * Wait for read or write events on a set of file descriptors. It uses poll() + * when a fine poll() is available, in order to avoid limits with FD_SETSIZE, + * otherwise select() is used. An error is returned if select() is being used + * and a file descriptor is too large for FD_SETSIZE. + * + * A negative timeout value makes this function wait indefinitely, + * unless no valid file descriptor is given, when this happens the + * negative timeout is ignored and the function times out immediately. + * + * Return values: + * -1 = system call error or fd >= FD_SETSIZE + * 0 = timeout + * [bitmask] = action as described below + * + * CURL_CSELECT_IN - first socket is readable + * CURL_CSELECT_IN2 - second socket is readable + * CURL_CSELECT_OUT - write socket is writable + * CURL_CSELECT_ERR - an error condition occurred + */ +int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */ + curl_socket_t readfd1, + curl_socket_t writefd, /* socket to write to */ + time_t timeout_ms) /* milliseconds to wait */ +{ +#ifdef HAVE_POLL_FINE + struct pollfd pfd[3]; + int num; +#else + struct timeval pending_tv; + struct timeval *ptimeout; + fd_set fds_read; + fd_set fds_write; + fd_set fds_err; + curl_socket_t maxfd; +#endif + struct curltime initial_tv = {0, 0}; + int pending_ms = 0; + int r; + int ret; + +#if SIZEOF_TIME_T != SIZEOF_INT + /* wrap-around precaution */ + if(timeout_ms >= INT_MAX) + timeout_ms = INT_MAX; +#endif + + if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) && + (writefd == CURL_SOCKET_BAD)) { + /* no sockets, just wait */ + r = Curl_wait_ms((int)timeout_ms); + return r; + } + + /* Avoid initial timestamp, avoid Curl_now() call, when elapsed + time in this function does not need to be measured. This happens + when function is called with a zero timeout or a negative timeout + value indicating a blocking call should be performed. */ + + if(timeout_ms > 0) { + pending_ms = (int)timeout_ms; + initial_tv = Curl_now(); + } + +#ifdef HAVE_POLL_FINE + + num = 0; + if(readfd0 != CURL_SOCKET_BAD) { + pfd[num].fd = readfd0; + pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI; + pfd[num].revents = 0; + num++; + } + if(readfd1 != CURL_SOCKET_BAD) { + pfd[num].fd = readfd1; + pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI; + pfd[num].revents = 0; + num++; + } + if(writefd != CURL_SOCKET_BAD) { + pfd[num].fd = writefd; + pfd[num].events = POLLWRNORM|POLLOUT; + pfd[num].revents = 0; + num++; + } + + do { + int error; + if(timeout_ms < 0) + pending_ms = -1; + else if(!timeout_ms) + pending_ms = 0; + r = poll(pfd, num, pending_ms); + if(r != -1) + break; + error = SOCKERRNO; + if(error && ERROR_NOT_EINTR(error)) + break; + if(timeout_ms > 0) { + pending_ms = (int)(timeout_ms - ELAPSED_MS()); + if(pending_ms <= 0) { + r = 0; /* Simulate a "call timed out" case */ + break; + } + } + } while(r == -1); + + if(r < 0) + return -1; + if(r == 0) + return 0; + + ret = 0; + num = 0; + if(readfd0 != CURL_SOCKET_BAD) { + if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP)) + ret |= CURL_CSELECT_IN; + if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL)) + ret |= CURL_CSELECT_ERR; + num++; + } + if(readfd1 != CURL_SOCKET_BAD) { + if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP)) + ret |= CURL_CSELECT_IN2; + if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL)) + ret |= CURL_CSELECT_ERR; + num++; + } + if(writefd != CURL_SOCKET_BAD) { + if(pfd[num].revents & (POLLWRNORM|POLLOUT)) + ret |= CURL_CSELECT_OUT; + if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL)) + ret |= CURL_CSELECT_ERR; + } + + return ret; + +#else /* HAVE_POLL_FINE */ + + FD_ZERO(&fds_err); + maxfd = (curl_socket_t)-1; + + FD_ZERO(&fds_read); + if(readfd0 != CURL_SOCKET_BAD) { + VERIFY_SOCK(readfd0); + FD_SET(readfd0, &fds_read); + FD_SET(readfd0, &fds_err); + maxfd = readfd0; + } + if(readfd1 != CURL_SOCKET_BAD) { + VERIFY_SOCK(readfd1); + FD_SET(readfd1, &fds_read); + FD_SET(readfd1, &fds_err); + if(readfd1 > maxfd) + maxfd = readfd1; + } + + FD_ZERO(&fds_write); + if(writefd != CURL_SOCKET_BAD) { + VERIFY_SOCK(writefd); + FD_SET(writefd, &fds_write); + FD_SET(writefd, &fds_err); + if(writefd > maxfd) + maxfd = writefd; + } + + ptimeout = (timeout_ms < 0) ? NULL : &pending_tv; + + do { + int error; + if(timeout_ms > 0) { + pending_tv.tv_sec = pending_ms / 1000; + pending_tv.tv_usec = (pending_ms % 1000) * 1000; + } + else if(!timeout_ms) { + pending_tv.tv_sec = 0; + pending_tv.tv_usec = 0; + } + + /* WinSock select() must not be called with an fd_set that contains zero + fd flags, or it will return WSAEINVAL. But, it also can't be called + with no fd_sets at all! From the documentation: + + Any two of the parameters, readfds, writefds, or exceptfds, can be + given as null. At least one must be non-null, and any non-null + descriptor set must contain at least one handle to a socket. + + We know that we have at least one bit set in at least two fd_sets in + this case, but we may have no bits set in either fds_read or fd_write, + so check for that and handle it. Luckily, with WinSock, we can _also_ + ask how many bits are set on an fd_set. + + It is unclear why WinSock doesn't just handle this for us instead of + calling this an error. + + Note also that WinSock ignores the first argument, so we don't worry + about the fact that maxfd is computed incorrectly with WinSock (since + curl_socket_t is unsigned in such cases and thus -1 is the largest + value). + */ +#ifdef USE_WINSOCK + r = select((int)maxfd + 1, + fds_read.fd_count ? &fds_read : NULL, + fds_write.fd_count ? &fds_write : NULL, + &fds_err, ptimeout); +#else + r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout); +#endif + + if(r != -1) + break; + error = SOCKERRNO; + if(error && ERROR_NOT_EINTR(error)) + break; + if(timeout_ms > 0) { + pending_ms = (int)(timeout_ms - ELAPSED_MS()); + if(pending_ms <= 0) { + r = 0; /* Simulate a "call timed out" case */ + break; + } + } + } while(r == -1); + + if(r < 0) + return -1; + if(r == 0) + return 0; + + ret = 0; + if(readfd0 != CURL_SOCKET_BAD) { + if(FD_ISSET(readfd0, &fds_read)) + ret |= CURL_CSELECT_IN; + if(FD_ISSET(readfd0, &fds_err)) + ret |= CURL_CSELECT_ERR; + } + if(readfd1 != CURL_SOCKET_BAD) { + if(FD_ISSET(readfd1, &fds_read)) + ret |= CURL_CSELECT_IN2; + if(FD_ISSET(readfd1, &fds_err)) + ret |= CURL_CSELECT_ERR; + } + if(writefd != CURL_SOCKET_BAD) { + if(FD_ISSET(writefd, &fds_write)) + ret |= CURL_CSELECT_OUT; + if(FD_ISSET(writefd, &fds_err)) + ret |= CURL_CSELECT_ERR; + } + + return ret; + +#endif /* HAVE_POLL_FINE */ + +} + +/* + * This is a wrapper around poll(). If poll() does not exist, then + * select() is used instead. An error is returned if select() is + * being used and a file descriptor is too large for FD_SETSIZE. + * A negative timeout value makes this function wait indefinitely, + * unless no valid file descriptor is given, when this happens the + * negative timeout is ignored and the function times out immediately. + * + * Return values: + * -1 = system call error or fd >= FD_SETSIZE + * 0 = timeout + * N = number of structures with non zero revent fields + */ +int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms) +{ +#ifndef HAVE_POLL_FINE + struct timeval pending_tv; + struct timeval *ptimeout; + fd_set fds_read; + fd_set fds_write; + fd_set fds_err; + curl_socket_t maxfd; +#endif + struct curltime initial_tv = {0, 0}; + bool fds_none = TRUE; + unsigned int i; + int pending_ms = 0; + int r; + + if(ufds) { + for(i = 0; i < nfds; i++) { + if(ufds[i].fd != CURL_SOCKET_BAD) { + fds_none = FALSE; + break; + } + } + } + if(fds_none) { + r = Curl_wait_ms(timeout_ms); + return r; + } + + /* Avoid initial timestamp, avoid Curl_now() call, when elapsed + time in this function does not need to be measured. This happens + when function is called with a zero timeout or a negative timeout + value indicating a blocking call should be performed. */ + + if(timeout_ms > 0) { + pending_ms = timeout_ms; + initial_tv = Curl_now(); + } + +#ifdef HAVE_POLL_FINE + + do { + int error; + if(timeout_ms < 0) + pending_ms = -1; + else if(!timeout_ms) + pending_ms = 0; + r = poll(ufds, nfds, pending_ms); + if(r != -1) + break; + error = SOCKERRNO; + if(error && ERROR_NOT_EINTR(error)) + break; + if(timeout_ms > 0) { + pending_ms = (int)(timeout_ms - ELAPSED_MS()); + if(pending_ms <= 0) { + r = 0; /* Simulate a "call timed out" case */ + break; + } + } + } while(r == -1); + + if(r < 0) + return -1; + if(r == 0) + return 0; + + for(i = 0; i < nfds; i++) { + if(ufds[i].fd == CURL_SOCKET_BAD) + continue; + if(ufds[i].revents & POLLHUP) + ufds[i].revents |= POLLIN; + if(ufds[i].revents & POLLERR) + ufds[i].revents |= (POLLIN|POLLOUT); + } + +#else /* HAVE_POLL_FINE */ + + FD_ZERO(&fds_read); + FD_ZERO(&fds_write); + FD_ZERO(&fds_err); + maxfd = (curl_socket_t)-1; + + for(i = 0; i < nfds; i++) { + ufds[i].revents = 0; + if(ufds[i].fd == CURL_SOCKET_BAD) + continue; + VERIFY_SOCK(ufds[i].fd); + if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI| + POLLRDNORM|POLLWRNORM|POLLRDBAND)) { + if(ufds[i].fd > maxfd) + maxfd = ufds[i].fd; + if(ufds[i].events & (POLLRDNORM|POLLIN)) + FD_SET(ufds[i].fd, &fds_read); + if(ufds[i].events & (POLLWRNORM|POLLOUT)) + FD_SET(ufds[i].fd, &fds_write); + if(ufds[i].events & (POLLRDBAND|POLLPRI)) + FD_SET(ufds[i].fd, &fds_err); + } + } + +#ifdef USE_WINSOCK + /* WinSock select() can't handle zero events. See the comment about this in + Curl_check_socket(). */ + if(fds_read.fd_count == 0 && fds_write.fd_count == 0 + && fds_err.fd_count == 0) { + r = Curl_wait_ms(timeout_ms); + return r; + } +#endif + + ptimeout = (timeout_ms < 0) ? NULL : &pending_tv; + + do { + int error; + if(timeout_ms > 0) { + pending_tv.tv_sec = pending_ms / 1000; + pending_tv.tv_usec = (pending_ms % 1000) * 1000; + } + else if(!timeout_ms) { + pending_tv.tv_sec = 0; + pending_tv.tv_usec = 0; + } + +#ifdef USE_WINSOCK + r = select((int)maxfd + 1, + /* WinSock select() can't handle fd_sets with zero bits set, so + don't give it such arguments. See the comment about this in + Curl_check_socket(). + */ + fds_read.fd_count ? &fds_read : NULL, + fds_write.fd_count ? &fds_write : NULL, + fds_err.fd_count ? &fds_err : NULL, ptimeout); +#else + r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout); +#endif + if(r != -1) + break; + error = SOCKERRNO; + if(error && ERROR_NOT_EINTR(error)) + break; + if(timeout_ms > 0) { + pending_ms = timeout_ms - ELAPSED_MS(); + if(pending_ms <= 0) { + r = 0; /* Simulate a "call timed out" case */ + break; + } + } + } while(r == -1); + + if(r < 0) + return -1; + if(r == 0) + return 0; + + r = 0; + for(i = 0; i < nfds; i++) { + ufds[i].revents = 0; + if(ufds[i].fd == CURL_SOCKET_BAD) + continue; + if(FD_ISSET(ufds[i].fd, &fds_read)) + ufds[i].revents |= POLLIN; + if(FD_ISSET(ufds[i].fd, &fds_write)) + ufds[i].revents |= POLLOUT; + if(FD_ISSET(ufds[i].fd, &fds_err)) + ufds[i].revents |= POLLPRI; + if(ufds[i].revents != 0) + r++; + } + +#endif /* HAVE_POLL_FINE */ + + return r; +} + +#ifdef TPF +/* + * This is a replacement for select() on the TPF platform. + * It is used whenever libcurl calls select(). + * The call below to tpf_process_signals() is required because + * TPF's select calls are not signal interruptible. + * + * Return values are the same as select's. + */ +int tpf_select_libcurl(int maxfds, fd_set *reads, fd_set *writes, + fd_set *excepts, struct timeval *tv) +{ + int rc; + + rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv); + tpf_process_signals(); + return rc; +} +#endif /* TPF */ diff --git a/libcurl/lib/select.h b/libcurl/lib/select.h new file mode 100644 index 0000000..9a1ba45 --- /dev/null +++ b/libcurl/lib/select.h @@ -0,0 +1,115 @@ +#ifndef HEADER_CURL_SELECT_H +#define HEADER_CURL_SELECT_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_POLL_H +#include +#elif defined(HAVE_SYS_POLL_H) +#include +#endif + +/* + * Definition of pollfd struct and constants for platforms lacking them. + */ + +#if !defined(HAVE_STRUCT_POLLFD) && \ + !defined(HAVE_SYS_POLL_H) && \ + !defined(HAVE_POLL_H) && \ + !defined(POLLIN) + +#define POLLIN 0x01 +#define POLLPRI 0x02 +#define POLLOUT 0x04 +#define POLLERR 0x08 +#define POLLHUP 0x10 +#define POLLNVAL 0x20 + +struct pollfd +{ + curl_socket_t fd; + short events; + short revents; +}; + +#endif + +#ifndef POLLRDNORM +#define POLLRDNORM POLLIN +#endif + +#ifndef POLLWRNORM +#define POLLWRNORM POLLOUT +#endif + +#ifndef POLLRDBAND +#define POLLRDBAND POLLPRI +#endif + +/* there are three CSELECT defines that are defined in the public header that + are exposed to users, but this *IN2 bit is only ever used internally and + therefore defined here */ +#define CURL_CSELECT_IN2 (CURL_CSELECT_ERR << 1) + +int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2, + curl_socket_t writefd, + time_t timeout_ms); + +#define SOCKET_READABLE(x,z) \ + Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, z) +#define SOCKET_WRITABLE(x,z) \ + Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, z) + +int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms); + +/* On non-DOS and non-Winsock platforms, when Curl_ack_eintr is set, + * EINTR condition is honored and function might exit early without + * awaiting full timeout. Otherwise EINTR will be ignored and full + * timeout will elapse. */ +extern int Curl_ack_eintr; + +int Curl_wait_ms(int timeout_ms); + +#ifdef TPF +int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes, + fd_set* excepts, struct timeval* tv); +#endif + +/* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1], which + unfortunately makes it impossible for us to easily check if they're valid +*/ +#if defined(USE_WINSOCK) || defined(TPF) +#define VALID_SOCK(x) 1 +#define VERIFY_SOCK(x) Curl_nop_stmt +#else +#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE)) +#define VERIFY_SOCK(x) do { \ + if(!VALID_SOCK(x)) { \ + SET_SOCKERRNO(EINVAL); \ + return -1; \ + } \ +} WHILE_FALSE +#endif + +#endif /* HEADER_CURL_SELECT_H */ diff --git a/libcurl/lib/sendf.c b/libcurl/lib/sendf.c new file mode 100644 index 0000000..5913ea4 --- /dev/null +++ b/libcurl/lib/sendf.c @@ -0,0 +1,821 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_LINUX_TCP_H +#include +#endif + +#include + +#include "urldata.h" +#include "sendf.h" +#include "connect.h" +#include "vtls/vtls.h" +#include "ssh.h" +#include "easyif.h" +#include "multiif.h" +#include "non-ascii.h" +#include "strerror.h" +#include "select.h" +#include "strdup.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#ifdef CURL_DO_LINEEND_CONV +/* + * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF + * (\n), with special processing for CRLF sequences that are split between two + * blocks of data. Remaining, bare CRs are changed to LFs. The possibly new + * size of the data is returned. + */ +static size_t convert_lineends(struct Curl_easy *data, + char *startPtr, size_t size) +{ + char *inPtr, *outPtr; + + /* sanity check */ + if((startPtr == NULL) || (size < 1)) { + return size; + } + + if(data->state.prev_block_had_trailing_cr) { + /* The previous block of incoming data + had a trailing CR, which was turned into a LF. */ + if(*startPtr == '\n') { + /* This block of incoming data starts with the + previous block's LF so get rid of it */ + memmove(startPtr, startPtr + 1, size-1); + size--; + /* and it wasn't a bare CR but a CRLF conversion instead */ + data->state.crlf_conversions++; + } + data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */ + } + + /* find 1st CR, if any */ + inPtr = outPtr = memchr(startPtr, '\r', size); + if(inPtr) { + /* at least one CR, now look for CRLF */ + while(inPtr < (startPtr + size-1)) { + /* note that it's size-1, so we'll never look past the last byte */ + if(memcmp(inPtr, "\r\n", 2) == 0) { + /* CRLF found, bump past the CR and copy the NL */ + inPtr++; + *outPtr = *inPtr; + /* keep track of how many CRLFs we converted */ + data->state.crlf_conversions++; + } + else { + if(*inPtr == '\r') { + /* lone CR, move LF instead */ + *outPtr = '\n'; + } + else { + /* not a CRLF nor a CR, just copy whatever it is */ + *outPtr = *inPtr; + } + } + outPtr++; + inPtr++; + } /* end of while loop */ + + if(inPtr < startPtr + size) { + /* handle last byte */ + if(*inPtr == '\r') { + /* deal with a CR at the end of the buffer */ + *outPtr = '\n'; /* copy a NL instead */ + /* note that a CRLF might be split across two blocks */ + data->state.prev_block_had_trailing_cr = TRUE; + } + else { + /* copy last byte */ + *outPtr = *inPtr; + } + outPtr++; + } + if(outPtr < startPtr + size) + /* tidy up by null terminating the now shorter data */ + *outPtr = '\0'; + + return (outPtr - startPtr); + } + return size; +} +#endif /* CURL_DO_LINEEND_CONV */ + +#ifdef USE_RECV_BEFORE_SEND_WORKAROUND +bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex) +{ + struct postponed_data * const psnd = &(conn->postponed[sockindex]); + return psnd->buffer && psnd->allocated_size && + psnd->recv_size > psnd->recv_processed; +} + +static void pre_receive_plain(struct connectdata *conn, int num) +{ + const curl_socket_t sockfd = conn->sock[num]; + struct postponed_data * const psnd = &(conn->postponed[num]); + size_t bytestorecv = psnd->allocated_size - psnd->recv_size; + /* WinSock will destroy unread received data if send() is + failed. + To avoid lossage of received data, recv() must be + performed before every send() if any incoming data is + available. However, skip this, if buffer is already full. */ + if((conn->handler->protocol&PROTO_FAMILY_HTTP) != 0 && + conn->recv[num] == Curl_recv_plain && + (!psnd->buffer || bytestorecv)) { + const int readymask = Curl_socket_check(sockfd, CURL_SOCKET_BAD, + CURL_SOCKET_BAD, 0); + if(readymask != -1 && (readymask & CURL_CSELECT_IN) != 0) { + /* Have some incoming data */ + if(!psnd->buffer) { + /* Use buffer double default size for intermediate buffer */ + psnd->allocated_size = 2 * conn->data->set.buffer_size; + psnd->buffer = malloc(psnd->allocated_size); + psnd->recv_size = 0; + psnd->recv_processed = 0; +#ifdef DEBUGBUILD + psnd->bindsock = sockfd; /* Used only for DEBUGASSERT */ +#endif /* DEBUGBUILD */ + bytestorecv = psnd->allocated_size; + } + if(psnd->buffer) { + ssize_t recvedbytes; + DEBUGASSERT(psnd->bindsock == sockfd); + recvedbytes = sread(sockfd, psnd->buffer + psnd->recv_size, + bytestorecv); + if(recvedbytes > 0) + psnd->recv_size += recvedbytes; + } + else + psnd->allocated_size = 0; + } + } +} + +static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf, + size_t len) +{ + struct postponed_data * const psnd = &(conn->postponed[num]); + size_t copysize; + if(!psnd->buffer) + return 0; + + DEBUGASSERT(psnd->allocated_size > 0); + DEBUGASSERT(psnd->recv_size <= psnd->allocated_size); + DEBUGASSERT(psnd->recv_processed <= psnd->recv_size); + /* Check and process data that already received and storied in internal + intermediate buffer */ + if(psnd->recv_size > psnd->recv_processed) { + DEBUGASSERT(psnd->bindsock == conn->sock[num]); + copysize = CURLMIN(len, psnd->recv_size - psnd->recv_processed); + memcpy(buf, psnd->buffer + psnd->recv_processed, copysize); + psnd->recv_processed += copysize; + } + else + copysize = 0; /* buffer was allocated, but nothing was received */ + + /* Free intermediate buffer if it has no unprocessed data */ + if(psnd->recv_processed == psnd->recv_size) { + free(psnd->buffer); + psnd->buffer = NULL; + psnd->allocated_size = 0; + psnd->recv_size = 0; + psnd->recv_processed = 0; +#ifdef DEBUGBUILD + psnd->bindsock = CURL_SOCKET_BAD; +#endif /* DEBUGBUILD */ + } + return (ssize_t)copysize; +} +#else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ +/* Use "do-nothing" macros instead of functions when workaround not used */ +bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex) +{ + (void)conn; + (void)sockindex; + return false; +} +#define pre_receive_plain(c,n) do {} WHILE_FALSE +#define get_pre_recved(c,n,b,l) 0 +#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ + +/* Curl_infof() is for info message along the way */ + +void Curl_infof(struct Curl_easy *data, const char *fmt, ...) +{ + if(data && data->set.verbose) { + va_list ap; + size_t len; + char print_buffer[2048 + 1]; + va_start(ap, fmt); + len = mvsnprintf(print_buffer, sizeof(print_buffer), fmt, ap); + /* + * Indicate truncation of the input by replacing the last 3 characters + * with "...", and transfer the newline over in case the format had one. + */ + if(len >= sizeof(print_buffer)) { + len = strlen(fmt); + if(fmt[--len] == '\n') + msnprintf(print_buffer + (sizeof(print_buffer) - 5), 5, "...\n"); + else + msnprintf(print_buffer + (sizeof(print_buffer) - 4), 4, "..."); + } + va_end(ap); + len = strlen(print_buffer); + Curl_debug(data, CURLINFO_TEXT, print_buffer, len); + } +} + +/* Curl_failf() is for messages stating why we failed. + * The message SHALL NOT include any LF or CR. + */ + +void Curl_failf(struct Curl_easy *data, const char *fmt, ...) +{ + if(data->set.verbose || data->set.errorbuffer) { + va_list ap; + size_t len; + char error[CURL_ERROR_SIZE + 2]; + va_start(ap, fmt); + mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap); + len = strlen(error); + + if(data->set.errorbuffer && !data->state.errorbuf) { + strcpy(data->set.errorbuffer, error); + data->state.errorbuf = TRUE; /* wrote error string */ + } + if(data->set.verbose) { + error[len] = '\n'; + error[++len] = '\0'; + Curl_debug(data, CURLINFO_TEXT, error, len); + } + va_end(ap); + } +} + +/* Curl_sendf() sends formatted data to the server */ +CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn, + const char *fmt, ...) +{ + struct Curl_easy *data = conn->data; + ssize_t bytes_written; + size_t write_len; + CURLcode result = CURLE_OK; + char *s; + char *sptr; + va_list ap; + va_start(ap, fmt); + s = vaprintf(fmt, ap); /* returns an allocated string */ + va_end(ap); + if(!s) + return CURLE_OUT_OF_MEMORY; /* failure */ + + bytes_written = 0; + write_len = strlen(s); + sptr = s; + + for(;;) { + /* Write the buffer to the socket */ + result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written); + + if(result) + break; + + if(data->set.verbose) + Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written); + + if((size_t)bytes_written != write_len) { + /* if not all was written at once, we must advance the pointer, decrease + the size left and try again! */ + write_len -= bytes_written; + sptr += bytes_written; + } + else + break; + } + + free(s); /* free the output string */ + + return result; +} + +/* + * Curl_write() is an internal write function that sends data to the + * server. Works with plain sockets, SCP, SSL or kerberos. + * + * If the write would block (CURLE_AGAIN), we return CURLE_OK and + * (*written == 0). Otherwise we return regular CURLcode value. + */ +CURLcode Curl_write(struct connectdata *conn, + curl_socket_t sockfd, + const void *mem, + size_t len, + ssize_t *written) +{ + ssize_t bytes_written; + CURLcode result = CURLE_OK; + int num = (sockfd == conn->sock[SECONDARYSOCKET]); + + bytes_written = conn->send[num](conn, num, mem, len, &result); + + *written = bytes_written; + if(bytes_written >= 0) + /* we completely ignore the curlcode value when subzero is not returned */ + return CURLE_OK; + + /* handle CURLE_AGAIN or a send failure */ + switch(result) { + case CURLE_AGAIN: + *written = 0; + return CURLE_OK; + + case CURLE_OK: + /* general send failure */ + return CURLE_SEND_ERROR; + + default: + /* we got a specific curlcode, forward it */ + return result; + } +} + +ssize_t Curl_send_plain(struct connectdata *conn, int num, + const void *mem, size_t len, CURLcode *code) +{ + curl_socket_t sockfd = conn->sock[num]; + ssize_t bytes_written; + /* WinSock will destroy unread received data if send() is + failed. + To avoid lossage of received data, recv() must be + performed before every send() if any incoming data is + available. */ + pre_receive_plain(conn, num); + +#if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */ + if(conn->bits.tcp_fastopen) { + bytes_written = sendto(sockfd, mem, len, MSG_FASTOPEN, + conn->ip_addr->ai_addr, conn->ip_addr->ai_addrlen); + conn->bits.tcp_fastopen = FALSE; + } + else +#endif + bytes_written = swrite(sockfd, mem, len); + + *code = CURLE_OK; + if(-1 == bytes_written) { + int err = SOCKERRNO; + + if( +#ifdef WSAEWOULDBLOCK + /* This is how Windows does it */ + (WSAEWOULDBLOCK == err) +#else + /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned + due to its inability to send off data without blocking. We therefore + treat both error codes the same here */ + (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) || + (EINPROGRESS == err) +#endif + ) { + /* this is just a case of EWOULDBLOCK */ + bytes_written = 0; + *code = CURLE_AGAIN; + } + else { + char buffer[STRERROR_LEN]; + failf(conn->data, "Send failure: %s", + Curl_strerror(err, buffer, sizeof(buffer))); + conn->data->state.os_errno = err; + *code = CURLE_SEND_ERROR; + } + } + return bytes_written; +} + +/* + * Curl_write_plain() is an internal write function that sends data to the + * server using plain sockets only. Otherwise meant to have the exact same + * proto as Curl_write() + */ +CURLcode Curl_write_plain(struct connectdata *conn, + curl_socket_t sockfd, + const void *mem, + size_t len, + ssize_t *written) +{ + ssize_t bytes_written; + CURLcode result; + int num = (sockfd == conn->sock[SECONDARYSOCKET]); + + bytes_written = Curl_send_plain(conn, num, mem, len, &result); + + *written = bytes_written; + + return result; +} + +ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, + size_t len, CURLcode *code) +{ + curl_socket_t sockfd = conn->sock[num]; + ssize_t nread; + /* Check and return data that already received and storied in internal + intermediate buffer */ + nread = get_pre_recved(conn, num, buf, len); + if(nread > 0) { + *code = CURLE_OK; + return nread; + } + + nread = sread(sockfd, buf, len); + + *code = CURLE_OK; + if(-1 == nread) { + int err = SOCKERRNO; + + if( +#ifdef WSAEWOULDBLOCK + /* This is how Windows does it */ + (WSAEWOULDBLOCK == err) +#else + /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned + due to its inability to send off data without blocking. We therefore + treat both error codes the same here */ + (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) +#endif + ) { + /* this is just a case of EWOULDBLOCK */ + *code = CURLE_AGAIN; + } + else { + char buffer[STRERROR_LEN]; + failf(conn->data, "Recv failure: %s", + Curl_strerror(err, buffer, sizeof(buffer))); + conn->data->state.os_errno = err; + *code = CURLE_RECV_ERROR; + } + } + return nread; +} + +static CURLcode pausewrite(struct Curl_easy *data, + int type, /* what type of data */ + const char *ptr, + size_t len) +{ + /* signalled to pause sending on this connection, but since we have data + we want to send we need to dup it to save a copy for when the sending + is again enabled */ + struct SingleRequest *k = &data->req; + struct UrlState *s = &data->state; + char *dupl; + unsigned int i; + bool newtype = TRUE; + + if(s->tempcount) { + for(i = 0; i< s->tempcount; i++) { + if(s->tempwrite[i].type == type) { + /* data for this type exists */ + newtype = FALSE; + break; + } + } + DEBUGASSERT(i < 3); + } + else + i = 0; + + if(!newtype) { + /* append new data to old data */ + + /* figure out the new size of the data to save */ + size_t newlen = len + s->tempwrite[i].len; + /* allocate the new memory area */ + char *newptr = realloc(s->tempwrite[i].buf, newlen); + if(!newptr) + return CURLE_OUT_OF_MEMORY; + /* copy the new data to the end of the new area */ + memcpy(newptr + s->tempwrite[i].len, ptr, len); + + /* update the pointer and the size */ + s->tempwrite[i].buf = newptr; + s->tempwrite[i].len = newlen; + } + else { + dupl = Curl_memdup(ptr, len); + if(!dupl) + return CURLE_OUT_OF_MEMORY; + + /* store this information in the state struct for later use */ + s->tempwrite[i].buf = dupl; + s->tempwrite[i].len = len; + s->tempwrite[i].type = type; + + if(newtype) + s->tempcount++; + } + + /* mark the connection as RECV paused */ + k->keepon |= KEEP_RECV_PAUSE; + + DEBUGF(infof(data, "Paused %zu bytes in buffer for type %02x\n", + len, type)); + + return CURLE_OK; +} + + +/* chop_write() writes chunks of data not larger than CURL_MAX_WRITE_SIZE via + * client write callback(s) and takes care of pause requests from the + * callbacks. + */ +static CURLcode chop_write(struct connectdata *conn, + int type, + char *optr, + size_t olen) +{ + struct Curl_easy *data = conn->data; + curl_write_callback writeheader = NULL; + curl_write_callback writebody = NULL; + char *ptr = optr; + size_t len = olen; + + if(!len) + return CURLE_OK; + + /* If reading is paused, append this data to the already held data for this + type. */ + if(data->req.keepon & KEEP_RECV_PAUSE) + return pausewrite(data, type, ptr, len); + + /* Determine the callback(s) to use. */ + if(type & CLIENTWRITE_BODY) + writebody = data->set.fwrite_func; + if((type & CLIENTWRITE_HEADER) && + (data->set.fwrite_header || data->set.writeheader)) { + /* + * Write headers to the same callback or to the especially setup + * header callback function (added after version 7.7.1). + */ + writeheader = + data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func; + } + + /* Chop data, write chunks. */ + while(len) { + size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE; + + if(writebody) { + size_t wrote; + Curl_set_in_callback(data, true); + wrote = writebody(ptr, 1, chunklen, data->set.out); + Curl_set_in_callback(data, false); + + if(CURL_WRITEFUNC_PAUSE == wrote) { + if(conn->handler->flags & PROTOPT_NONETWORK) { + /* Protocols that work without network cannot be paused. This is + actually only FILE:// just now, and it can't pause since the + transfer isn't done using the "normal" procedure. */ + failf(data, "Write callback asked for PAUSE when not supported!"); + return CURLE_WRITE_ERROR; + } + return pausewrite(data, type, ptr, len); + } + if(wrote != chunklen) { + failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen); + return CURLE_WRITE_ERROR; + } + } + + ptr += chunklen; + len -= chunklen; + } + + if(writeheader) { + size_t wrote; + ptr = optr; + len = olen; + Curl_set_in_callback(data, true); + wrote = writeheader(ptr, 1, len, data->set.writeheader); + Curl_set_in_callback(data, false); + + if(CURL_WRITEFUNC_PAUSE == wrote) + /* here we pass in the HEADER bit only since if this was body as well + then it was passed already and clearly that didn't trigger the + pause, so this is saved for later with the HEADER bit only */ + return pausewrite(data, CLIENTWRITE_HEADER, ptr, len); + + if(wrote != len) { + failf(data, "Failed writing header"); + return CURLE_WRITE_ERROR; + } + } + + return CURLE_OK; +} + + +/* Curl_client_write() sends data to the write callback(s) + + The bit pattern defines to what "streams" to write to. Body and/or header. + The defines are in sendf.h of course. + + If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the + local character encoding. This is a problem and should be changed in + the future to leave the original data alone. + */ +CURLcode Curl_client_write(struct connectdata *conn, + int type, + char *ptr, + size_t len) +{ + struct Curl_easy *data = conn->data; + + if(0 == len) + len = strlen(ptr); + + DEBUGASSERT(type <= 3); + + /* FTP data may need conversion. */ + if((type & CLIENTWRITE_BODY) && + (conn->handler->protocol & PROTO_FAMILY_FTP) && + conn->proto.ftpc.transfertype == 'A') { + /* convert from the network encoding */ + CURLcode result = Curl_convert_from_network(data, ptr, len); + /* Curl_convert_from_network calls failf if unsuccessful */ + if(result) + return result; + +#ifdef CURL_DO_LINEEND_CONV + /* convert end-of-line markers */ + len = convert_lineends(data, ptr, len); +#endif /* CURL_DO_LINEEND_CONV */ + } + + return chop_write(conn, type, ptr, len); +} + +CURLcode Curl_read_plain(curl_socket_t sockfd, + char *buf, + size_t bytesfromsocket, + ssize_t *n) +{ + ssize_t nread = sread(sockfd, buf, bytesfromsocket); + + if(-1 == nread) { + int err = SOCKERRNO; + int return_error; +#ifdef USE_WINSOCK + return_error = WSAEWOULDBLOCK == err; +#else + return_error = EWOULDBLOCK == err || EAGAIN == err || EINTR == err; +#endif + if(return_error) + return CURLE_AGAIN; + return CURLE_RECV_ERROR; + } + + /* we only return number of bytes read when we return OK */ + *n = nread; + return CURLE_OK; +} + +/* + * Internal read-from-socket function. This is meant to deal with plain + * sockets, SSL sockets and kerberos sockets. + * + * Returns a regular CURLcode value. + */ +CURLcode Curl_read(struct connectdata *conn, /* connection data */ + curl_socket_t sockfd, /* read from this socket */ + char *buf, /* store read data here */ + size_t sizerequested, /* max amount to read */ + ssize_t *n) /* amount bytes read */ +{ + CURLcode result = CURLE_RECV_ERROR; + ssize_t nread = 0; + size_t bytesfromsocket = 0; + char *buffertofill = NULL; + struct Curl_easy *data = conn->data; + + /* Set 'num' to 0 or 1, depending on which socket that has been sent here. + If it is the second socket, we set num to 1. Otherwise to 0. This lets + us use the correct ssl handle. */ + int num = (sockfd == conn->sock[SECONDARYSOCKET]); + + *n = 0; /* reset amount to zero */ + + bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size); + buffertofill = buf; + + nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result); + if(nread < 0) + return result; + + *n += nread; + + return CURLE_OK; +} + +/* return 0 on success */ +int Curl_debug(struct Curl_easy *data, curl_infotype type, + char *ptr, size_t size) +{ + static const char s_infotype[CURLINFO_END][3] = { + "* ", "< ", "> ", "{ ", "} ", "{ ", "} " }; + int rc = 0; + +#ifdef CURL_DOES_CONVERSIONS + char *buf = NULL; + size_t conv_size = 0; + + switch(type) { + case CURLINFO_HEADER_OUT: + buf = Curl_memdup(ptr, size); + if(!buf) + return 1; + conv_size = size; + + /* Special processing is needed for this block if it + * contains both headers and data (separated by CRLFCRLF). + * We want to convert just the headers, leaving the data as-is. + */ + if(size > 4) { + size_t i; + for(i = 0; i < size-4; i++) { + if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) { + /* convert everything through this CRLFCRLF but no further */ + conv_size = i + 4; + break; + } + } + } + + Curl_convert_from_network(data, buf, conv_size); + /* Curl_convert_from_network calls failf if unsuccessful */ + /* we might as well continue even if it fails... */ + ptr = buf; /* switch pointer to use my buffer instead */ + break; + default: + /* leave everything else as-is */ + break; + } +#endif /* CURL_DOES_CONVERSIONS */ + + if(data->set.fdebug) { + Curl_set_in_callback(data, true); + rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata); + Curl_set_in_callback(data, false); + } + else { + switch(type) { + case CURLINFO_TEXT: + case CURLINFO_HEADER_OUT: + case CURLINFO_HEADER_IN: + fwrite(s_infotype[type], 2, 1, data->set.err); + fwrite(ptr, size, 1, data->set.err); +#ifdef CURL_DOES_CONVERSIONS + if(size != conv_size) { + /* we had untranslated data so we need an explicit newline */ + fwrite("\n", 1, 1, data->set.err); + } +#endif + break; + default: /* nada */ + break; + } + } +#ifdef CURL_DOES_CONVERSIONS + free(buf); +#endif + return rc; +} diff --git a/libcurl/lib/sendf.h b/libcurl/lib/sendf.h new file mode 100644 index 0000000..638d595 --- /dev/null +++ b/libcurl/lib/sendf.h @@ -0,0 +1,92 @@ +#ifndef HEADER_CURL_SENDF_H +#define HEADER_CURL_SENDF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *, + const char *fmt, ...); +void Curl_infof(struct Curl_easy *, const char *fmt, ...); +void Curl_failf(struct Curl_easy *, const char *fmt, ...); + +#if defined(CURL_DISABLE_VERBOSE_STRINGS) + +#if defined(HAVE_VARIADIC_MACROS_C99) +#define infof(...) Curl_nop_stmt +#elif defined(HAVE_VARIADIC_MACROS_GCC) +#define infof(x...) Curl_nop_stmt +#else +//#error "missing VARIADIC macro define, fix and rebuild!" +#define infof (void) +#endif + +#else /* CURL_DISABLE_VERBOSE_STRINGS */ + +#define infof Curl_infof + +#endif /* CURL_DISABLE_VERBOSE_STRINGS */ + +#define failf Curl_failf + +#define CLIENTWRITE_BODY (1<<0) +#define CLIENTWRITE_HEADER (1<<1) +#define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER) + +CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, + size_t len) WARN_UNUSED_RESULT; + +bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex); + +/* internal read-function, does plain socket only */ +CURLcode Curl_read_plain(curl_socket_t sockfd, + char *buf, + size_t bytesfromsocket, + ssize_t *n); + +ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, + size_t len, CURLcode *code); +ssize_t Curl_send_plain(struct connectdata *conn, int num, + const void *mem, size_t len, CURLcode *code); + +/* internal read-function, does plain socket, SSL and krb4 */ +CURLcode Curl_read(struct connectdata *conn, curl_socket_t sockfd, + char *buf, size_t buffersize, + ssize_t *n); +/* internal write-function, does plain socket, SSL, SCP, SFTP and krb4 */ +CURLcode Curl_write(struct connectdata *conn, + curl_socket_t sockfd, + const void *mem, size_t len, + ssize_t *written); + +/* internal write-function, does plain sockets ONLY */ +CURLcode Curl_write_plain(struct connectdata *conn, + curl_socket_t sockfd, + const void *mem, size_t len, + ssize_t *written); + +/* the function used to output verbose information */ +int Curl_debug(struct Curl_easy *data, curl_infotype type, + char *ptr, size_t size); + + +#endif /* HEADER_CURL_SENDF_H */ diff --git a/libcurl/lib/setopt.c b/libcurl/lib/setopt.c new file mode 100644 index 0000000..1dbf00f --- /dev/null +++ b/libcurl/lib/setopt.c @@ -0,0 +1,2779 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_LINUX_TCP_H +#include +#endif + +#include "urldata.h" +#include "url.h" +#include "progress.h" +#include "content_encoding.h" +#include "strcase.h" +#include "share.h" +#include "vtls/vtls.h" +#include "warnless.h" +#include "sendf.h" +#include "http2.h" +#include "setopt.h" +#include "multiif.h" +#include "altsvc.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +CURLcode Curl_setstropt(char **charp, const char *s) +{ + /* Release the previous storage at `charp' and replace by a dynamic storage + copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */ + + Curl_safefree(*charp); + + if(s) { + char *str = strdup(s); + + if(str) { + size_t len = strlen(str); + if(len > CURL_MAX_INPUT_LENGTH) { + free(str); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + } + if(!str) + return CURLE_OUT_OF_MEMORY; + + *charp = str; + } + + return CURLE_OK; +} + +static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp) +{ + CURLcode result = CURLE_OK; + char *user = NULL; + char *passwd = NULL; + + /* Parse the login details if specified. It not then we treat NULL as a hint + to clear the existing data */ + if(option) { + result = Curl_parse_login_details(option, strlen(option), + (userp ? &user : NULL), + (passwdp ? &passwd : NULL), + NULL); + } + + if(!result) { + /* Store the username part of option if required */ + if(userp) { + if(!user && option && option[0] == ':') { + /* Allocate an empty string instead of returning NULL as user name */ + user = strdup(""); + if(!user) + result = CURLE_OUT_OF_MEMORY; + } + + Curl_safefree(*userp); + *userp = user; + } + + /* Store the password part of option if required */ + if(passwdp) { + Curl_safefree(*passwdp); + *passwdp = passwd; + } + } + + return result; +} + +#define C_SSLVERSION_VALUE(x) (x & 0xffff) +#define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000) + +/* + * Do not make Curl_vsetopt() static: it is called from + * packages/OS400/ccsidcurl.c. + */ +CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) +{ + char *argptr; + CURLcode result = CURLE_OK; + long arg; + unsigned long uarg; + curl_off_t bigsize; + + switch(option) { + case CURLOPT_DNS_CACHE_TIMEOUT: + arg = va_arg(param, long); + if(arg < -1) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.dns_cache_timeout = arg; + break; + case CURLOPT_DNS_USE_GLOBAL_CACHE: + /* deprecated */ + break; + case CURLOPT_SSL_CIPHER_LIST: + /* set a list of cipher we want to use in the SSL connection */ + result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG], + va_arg(param, char *)); + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_SSL_CIPHER_LIST: + /* set a list of cipher we want to use in the SSL connection for proxy */ + result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY], + va_arg(param, char *)); + break; +#endif + case CURLOPT_TLS13_CIPHERS: + if(Curl_ssl_tls13_ciphersuites()) { + /* set preferred list of TLS 1.3 cipher suites */ + result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_ORIG], + va_arg(param, char *)); + } + else + return CURLE_NOT_BUILT_IN; + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_TLS13_CIPHERS: + if(Curl_ssl_tls13_ciphersuites()) { + /* set preferred list of TLS 1.3 cipher suites for proxy */ + result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_PROXY], + va_arg(param, char *)); + } + else + return CURLE_NOT_BUILT_IN; + break; +#endif + case CURLOPT_RANDOM_FILE: + /* + * This is the path name to a file that contains random data to seed + * the random SSL stuff with. The file is only used for reading. + */ + result = Curl_setstropt(&data->set.str[STRING_SSL_RANDOM_FILE], + va_arg(param, char *)); + break; + case CURLOPT_EGDSOCKET: + /* + * The Entropy Gathering Daemon socket pathname + */ + result = Curl_setstropt(&data->set.str[STRING_SSL_EGDSOCKET], + va_arg(param, char *)); + break; + case CURLOPT_MAXCONNECTS: + /* + * Set the absolute number of maximum simultaneous alive connection that + * libcurl is allowed to have. + */ + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.maxconnects = arg; + break; + case CURLOPT_FORBID_REUSE: + /* + * When this transfer is done, it must not be left to be reused by a + * subsequent transfer but shall be closed immediately. + */ + data->set.reuse_forbid = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_FRESH_CONNECT: + /* + * This transfer shall not use a previously cached connection but + * should be made with a fresh new connect! + */ + data->set.reuse_fresh = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_VERBOSE: + /* + * Verbose means infof() calls that give a lot of information about + * the connection and transfer procedures as well as internal choices. + */ + data->set.verbose = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_HEADER: + /* + * Set to include the header in the general data output stream. + */ + data->set.include_header = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_NOPROGRESS: + /* + * Shut off the internal supported progress meter + */ + data->set.hide_progress = (0 != va_arg(param, long)) ? TRUE : FALSE; + if(data->set.hide_progress) + data->progress.flags |= PGRS_HIDE; + else + data->progress.flags &= ~PGRS_HIDE; + break; + case CURLOPT_NOBODY: + /* + * Do not include the body part in the output data stream. + */ + data->set.opt_no_body = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_FAILONERROR: + /* + * Don't output the >=400 error code HTML-page, but instead only + * return error. + */ + data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_KEEP_SENDING_ON_ERROR: + data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ? + TRUE : FALSE; + break; + case CURLOPT_UPLOAD: + case CURLOPT_PUT: + /* + * We want to sent data to the remote host. If this is HTTP, that equals + * using the PUT request. + */ + data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE; + if(data->set.upload) { + /* If this is HTTP, PUT is what's needed to "upload" */ + data->set.httpreq = HTTPREQ_PUT; + data->set.opt_no_body = FALSE; /* this is implied */ + } + else + /* In HTTP, the opposite of upload is GET (unless NOBODY is true as + then this can be changed to HEAD later on) */ + data->set.httpreq = HTTPREQ_GET; + break; + case CURLOPT_REQUEST_TARGET: + result = Curl_setstropt(&data->set.str[STRING_TARGET], + va_arg(param, char *)); + break; + case CURLOPT_FILETIME: + /* + * Try to get the file time of the remote document. The time will + * later (possibly) become available using curl_easy_getinfo(). + */ + data->set.get_filetime = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_SERVER_RESPONSE_TIMEOUT: + /* + * Option that specifies how quickly an server response must be obtained + * before it is considered failure. For pingpong protocols. + */ + arg = va_arg(param, long); + if((arg >= 0) && (arg <= (INT_MAX/1000))) + data->set.server_response_timeout = arg * 1000; + else + return CURLE_BAD_FUNCTION_ARGUMENT; + break; +#ifndef CURL_DISABLE_TFTP + case CURLOPT_TFTP_NO_OPTIONS: + /* + * Option that prevents libcurl from sending TFTP option requests to the + * server. + */ + data->set.tftp_no_options = va_arg(param, long) != 0; + break; + case CURLOPT_TFTP_BLKSIZE: + /* + * TFTP option that specifies the block size to use for data transmission. + */ + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.tftp_blksize = arg; + break; +#endif +#ifndef CURL_DISABLE_NETRC + case CURLOPT_NETRC: + /* + * Parse the $HOME/.netrc file + */ + arg = va_arg(param, long); + if((arg < CURL_NETRC_IGNORED) || (arg > CURL_NETRC_REQUIRED)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.use_netrc = (enum CURL_NETRC_OPTION)arg; + break; + case CURLOPT_NETRC_FILE: + /* + * Use this file instead of the $HOME/.netrc file + */ + result = Curl_setstropt(&data->set.str[STRING_NETRC_FILE], + va_arg(param, char *)); + break; +#endif + case CURLOPT_TRANSFERTEXT: + /* + * This option was previously named 'FTPASCII'. Renamed to work with + * more protocols than merely FTP. + * + * Transfer using ASCII (instead of BINARY). + */ + data->set.prefer_ascii = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_TIMECONDITION: + /* + * Set HTTP time condition. This must be one of the defines in the + * curl/curl.h header file. + */ + arg = va_arg(param, long); + if((arg < CURL_TIMECOND_NONE) || (arg > CURL_TIMECOND_LASTMOD)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.timecondition = (curl_TimeCond)arg; + break; + case CURLOPT_TIMEVALUE: + /* + * This is the value to compare with the remote document with the + * method set with CURLOPT_TIMECONDITION + */ + data->set.timevalue = (time_t)va_arg(param, long); + break; + + case CURLOPT_TIMEVALUE_LARGE: + /* + * This is the value to compare with the remote document with the + * method set with CURLOPT_TIMECONDITION + */ + data->set.timevalue = (time_t)va_arg(param, curl_off_t); + break; + + case CURLOPT_SSLVERSION: + case CURLOPT_PROXY_SSLVERSION: + /* + * Set explicit SSL version to try to connect with, as some SSL + * implementations are lame. + */ +#ifdef USE_SSL + { + long version, version_max; + struct ssl_primary_config *primary = (option == CURLOPT_SSLVERSION ? + &data->set.ssl.primary : + &data->set.proxy_ssl.primary); + + arg = va_arg(param, long); + + version = C_SSLVERSION_VALUE(arg); + version_max = C_SSLVERSION_MAX_VALUE(arg); + + if(version < CURL_SSLVERSION_DEFAULT || + version >= CURL_SSLVERSION_LAST || + version_max < CURL_SSLVERSION_MAX_NONE || + version_max >= CURL_SSLVERSION_MAX_LAST) + return CURLE_BAD_FUNCTION_ARGUMENT; + + primary->version = version; + primary->version_max = version_max; + } +#else + result = CURLE_UNKNOWN_OPTION; +#endif + break; + +#ifndef CURL_DISABLE_HTTP + case CURLOPT_AUTOREFERER: + /* + * Switch on automatic referer that gets set if curl follows locations. + */ + data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_ACCEPT_ENCODING: + /* + * String to use at the value of Accept-Encoding header. + * + * If the encoding is set to "" we use an Accept-Encoding header that + * encompasses all the encodings we support. + * If the encoding is set to NULL we don't send an Accept-Encoding header + * and ignore an received Content-Encoding header. + * + */ + argptr = va_arg(param, char *); + if(argptr && !*argptr) { + argptr = Curl_all_content_encodings(); + if(!argptr) + result = CURLE_OUT_OF_MEMORY; + else { + result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr); + free(argptr); + } + } + else + result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr); + break; + + case CURLOPT_TRANSFER_ENCODING: + data->set.http_transfer_encoding = (0 != va_arg(param, long)) ? + TRUE : FALSE; + break; + + case CURLOPT_FOLLOWLOCATION: + /* + * Follow Location: header hints on a HTTP-server. + */ + data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_UNRESTRICTED_AUTH: + /* + * Send authentication (user+password) when following locations, even when + * hostname changed. + */ + data->set.allow_auth_to_other_hosts = + (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_MAXREDIRS: + /* + * The maximum amount of hops you allow curl to follow Location: + * headers. This should mostly be used to detect never-ending loops. + */ + arg = va_arg(param, long); + if(arg < -1) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.maxredirs = arg; + break; + + case CURLOPT_POSTREDIR: + /* + * Set the behaviour of POST when redirecting + * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302 + * CURL_REDIR_POST_301 - POST is kept as POST after 301 + * CURL_REDIR_POST_302 - POST is kept as POST after 302 + * CURL_REDIR_POST_303 - POST is kept as POST after 303 + * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303 + * other - POST is kept as POST after 301 and 302 + */ + arg = va_arg(param, long); + if(arg < CURL_REDIR_GET_ALL) + /* no return error on too high numbers since the bitmask could be + extended in a future */ + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.keep_post = arg & CURL_REDIR_POST_ALL; + break; + + case CURLOPT_POST: + /* Does this option serve a purpose anymore? Yes it does, when + CURLOPT_POSTFIELDS isn't used and the POST data is read off the + callback! */ + if(va_arg(param, long)) { + data->set.httpreq = HTTPREQ_POST; + data->set.opt_no_body = FALSE; /* this is implied */ + } + else + data->set.httpreq = HTTPREQ_GET; + break; + + case CURLOPT_COPYPOSTFIELDS: + /* + * A string with POST data. Makes curl HTTP POST. Even if it is NULL. + * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to + * CURLOPT_COPYPOSTFIELDS and not altered later. + */ + argptr = va_arg(param, char *); + + if(!argptr || data->set.postfieldsize == -1) + result = Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr); + else { + /* + * Check that requested length does not overflow the size_t type. + */ + + if((data->set.postfieldsize < 0) || + ((sizeof(curl_off_t) != sizeof(size_t)) && + (data->set.postfieldsize > (curl_off_t)((size_t)-1)))) + result = CURLE_OUT_OF_MEMORY; + else { + char *p; + + (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); + + /* Allocate even when size == 0. This satisfies the need of possible + later address compare to detect the COPYPOSTFIELDS mode, and + to mark that postfields is used rather than read function or + form data. + */ + p = malloc((size_t)(data->set.postfieldsize? + data->set.postfieldsize:1)); + + if(!p) + result = CURLE_OUT_OF_MEMORY; + else { + if(data->set.postfieldsize) + memcpy(p, argptr, (size_t)data->set.postfieldsize); + + data->set.str[STRING_COPYPOSTFIELDS] = p; + } + } + } + + data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS]; + data->set.httpreq = HTTPREQ_POST; + break; + + case CURLOPT_POSTFIELDS: + /* + * Like above, but use static data instead of copying it. + */ + data->set.postfields = va_arg(param, void *); + /* Release old copied data. */ + (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); + data->set.httpreq = HTTPREQ_POST; + break; + + case CURLOPT_POSTFIELDSIZE: + /* + * The size of the POSTFIELD data to prevent libcurl to do strlen() to + * figure it out. Enables binary posts. + */ + bigsize = va_arg(param, long); + if(bigsize < -1) + return CURLE_BAD_FUNCTION_ARGUMENT; + + if(data->set.postfieldsize < bigsize && + data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { + /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ + (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); + data->set.postfields = NULL; + } + + data->set.postfieldsize = bigsize; + break; + + case CURLOPT_POSTFIELDSIZE_LARGE: + /* + * The size of the POSTFIELD data to prevent libcurl to do strlen() to + * figure it out. Enables binary posts. + */ + bigsize = va_arg(param, curl_off_t); + if(bigsize < -1) + return CURLE_BAD_FUNCTION_ARGUMENT; + + if(data->set.postfieldsize < bigsize && + data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { + /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ + (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); + data->set.postfields = NULL; + } + + data->set.postfieldsize = bigsize; + break; + + case CURLOPT_HTTPPOST: + /* + * Set to make us do HTTP POST + */ + data->set.httppost = va_arg(param, struct curl_httppost *); + data->set.httpreq = HTTPREQ_POST_FORM; + data->set.opt_no_body = FALSE; /* this is implied */ + break; +#endif /* CURL_DISABLE_HTTP */ + + case CURLOPT_MIMEPOST: + /* + * Set to make us do MIME/form POST + */ + result = Curl_mime_set_subparts(&data->set.mimepost, + va_arg(param, curl_mime *), FALSE); + if(!result) { + data->set.httpreq = HTTPREQ_POST_MIME; + data->set.opt_no_body = FALSE; /* this is implied */ + } + break; + + case CURLOPT_REFERER: + /* + * String to set in the HTTP Referer: field. + */ + if(data->change.referer_alloc) { + Curl_safefree(data->change.referer); + data->change.referer_alloc = FALSE; + } + result = Curl_setstropt(&data->set.str[STRING_SET_REFERER], + va_arg(param, char *)); + data->change.referer = data->set.str[STRING_SET_REFERER]; + break; + + case CURLOPT_USERAGENT: + /* + * String to use in the HTTP User-Agent field + */ + result = Curl_setstropt(&data->set.str[STRING_USERAGENT], + va_arg(param, char *)); + break; + + case CURLOPT_HTTPHEADER: + /* + * Set a list with HTTP headers to use (or replace internals with) + */ + data->set.headers = va_arg(param, struct curl_slist *); + break; + +#ifndef CURL_DISABLE_HTTP +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXYHEADER: + /* + * Set a list with proxy headers to use (or replace internals with) + * + * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a + * long time we remain doing it this way until CURLOPT_PROXYHEADER is + * used. As soon as this option has been used, if set to anything but + * NULL, custom headers for proxies are only picked from this list. + * + * Set this option to NULL to restore the previous behavior. + */ + data->set.proxyheaders = va_arg(param, struct curl_slist *); + break; +#endif + case CURLOPT_HEADEROPT: + /* + * Set header option. + */ + arg = va_arg(param, long); + data->set.sep_headers = (bool)((arg & CURLHEADER_SEPARATE)? TRUE: FALSE); + break; + + case CURLOPT_HTTP200ALIASES: + /* + * Set a list of aliases for HTTP 200 in response header + */ + data->set.http200aliases = va_arg(param, struct curl_slist *); + break; + +#if !defined(CURL_DISABLE_COOKIES) + case CURLOPT_COOKIE: + /* + * Cookie string to send to the remote server in the request. + */ + result = Curl_setstropt(&data->set.str[STRING_COOKIE], + va_arg(param, char *)); + break; + + case CURLOPT_COOKIEFILE: + /* + * Set cookie file to read and parse. Can be used multiple times. + */ + argptr = (char *)va_arg(param, void *); + if(argptr) { + struct curl_slist *cl; + /* append the cookie file name to the list of file names, and deal with + them later */ + cl = curl_slist_append(data->change.cookielist, argptr); + if(!cl) { + curl_slist_free_all(data->change.cookielist); + data->change.cookielist = NULL; + return CURLE_OUT_OF_MEMORY; + } + data->change.cookielist = cl; /* store the list for later use */ + } + break; + + case CURLOPT_COOKIEJAR: + /* + * Set cookie file name to dump all cookies to when we're done. + */ + { + struct CookieInfo *newcookies; + result = Curl_setstropt(&data->set.str[STRING_COOKIEJAR], + va_arg(param, char *)); + + /* + * Activate the cookie parser. This may or may not already + * have been made. + */ + newcookies = Curl_cookie_init(data, NULL, data->cookies, + data->set.cookiesession); + if(!newcookies) + result = CURLE_OUT_OF_MEMORY; + data->cookies = newcookies; + } + break; + + case CURLOPT_COOKIESESSION: + /* + * Set this option to TRUE to start a new "cookie session". It will + * prevent the forthcoming read-cookies-from-file actions to accept + * cookies that are marked as being session cookies, as they belong to a + * previous session. + * + * In the original Netscape cookie spec, "session cookies" are cookies + * with no expire date set. RFC2109 describes the same action if no + * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds + * a 'Discard' action that can enforce the discard even for cookies that + * have a Max-Age. + * + * We run mostly with the original cookie spec, as hardly anyone implements + * anything else. + */ + data->set.cookiesession = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_COOKIELIST: + argptr = va_arg(param, char *); + + if(argptr == NULL) + break; + + if(strcasecompare(argptr, "ALL")) { + /* clear all cookies */ + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + Curl_cookie_clearall(data->cookies); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + } + else if(strcasecompare(argptr, "SESS")) { + /* clear session cookies */ + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + Curl_cookie_clearsess(data->cookies); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + } + else if(strcasecompare(argptr, "FLUSH")) { + /* flush cookies to file, takes care of the locking */ + Curl_flush_cookies(data, 0); + } + else if(strcasecompare(argptr, "RELOAD")) { + /* reload cookies from file */ + Curl_cookie_loadfiles(data); + break; + } + else { + if(!data->cookies) + /* if cookie engine was not running, activate it */ + data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE); + + argptr = strdup(argptr); + if(!argptr || !data->cookies) { + result = CURLE_OUT_OF_MEMORY; + free(argptr); + } + else { + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + + if(checkprefix("Set-Cookie:", argptr)) + /* HTTP Header format line */ + Curl_cookie_add(data, data->cookies, TRUE, FALSE, argptr + 11, NULL, + NULL, TRUE); + + else + /* Netscape format line */ + Curl_cookie_add(data, data->cookies, FALSE, FALSE, argptr, NULL, + NULL, TRUE); + + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + free(argptr); + } + } + + break; +#endif /* !CURL_DISABLE_COOKIES */ + + case CURLOPT_HTTPGET: + /* + * Set to force us do HTTP GET + */ + if(va_arg(param, long)) { + data->set.httpreq = HTTPREQ_GET; + data->set.upload = FALSE; /* switch off upload */ + data->set.opt_no_body = FALSE; /* this is implied */ + } + break; + + case CURLOPT_HTTP_VERSION: + /* + * This sets a requested HTTP version to be used. The value is one of + * the listed enums in curl/curl.h. + */ + arg = va_arg(param, long); + if(arg < CURL_HTTP_VERSION_NONE) + return CURLE_BAD_FUNCTION_ARGUMENT; +#ifndef USE_NGHTTP2 + if(arg >= CURL_HTTP_VERSION_2) + return CURLE_UNSUPPORTED_PROTOCOL; +#else + if(arg > CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) + return CURLE_UNSUPPORTED_PROTOCOL; + if(arg == CURL_HTTP_VERSION_NONE) + arg = CURL_HTTP_VERSION_2TLS; +#endif + data->set.httpversion = arg; + break; + + case CURLOPT_EXPECT_100_TIMEOUT_MS: + /* + * Time to wait for a response to a HTTP request containing an + * Expect: 100-continue header before sending the data anyway. + */ + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.expect_100_timeout = arg; + break; + + case CURLOPT_HTTP09_ALLOWED: + arg = va_arg(param, unsigned long); + if(arg > 1L) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.http09_allowed = arg ? TRUE : FALSE; + break; +#endif /* CURL_DISABLE_HTTP */ + + case CURLOPT_HTTPAUTH: + /* + * Set HTTP Authentication type BITMASK. + */ + { + int bitcheck; + bool authbits; + unsigned long auth = va_arg(param, unsigned long); + + if(auth == CURLAUTH_NONE) { + data->set.httpauth = auth; + break; + } + + /* the DIGEST_IE bit is only used to set a special marker, for all the + rest we need to handle it as normal DIGEST */ + data->state.authhost.iestyle = + (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE); + + if(auth & CURLAUTH_DIGEST_IE) { + auth |= CURLAUTH_DIGEST; /* set standard digest bit */ + auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */ + } + + /* switch off bits we can't support */ +#ifndef USE_NTLM + auth &= ~CURLAUTH_NTLM; /* no NTLM support */ + auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ +#elif !defined(NTLM_WB_ENABLED) + auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ +#endif +#ifndef USE_SPNEGO + auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without + GSS-API or SSPI */ +#endif + + /* check if any auth bit lower than CURLAUTH_ONLY is still set */ + bitcheck = 0; + authbits = FALSE; + while(bitcheck < 31) { + if(auth & (1UL << bitcheck++)) { + authbits = TRUE; + break; + } + } + if(!authbits) + return CURLE_NOT_BUILT_IN; /* no supported types left! */ + + data->set.httpauth = auth; + } + break; + + case CURLOPT_CUSTOMREQUEST: + /* + * Set a custom string to use as request + */ + result = Curl_setstropt(&data->set.str[STRING_CUSTOMREQUEST], + va_arg(param, char *)); + + /* we don't set + data->set.httpreq = HTTPREQ_CUSTOM; + here, we continue as if we were using the already set type + and this just changes the actual request keyword */ + break; + +#ifndef CURL_DISABLE_PROXY + case CURLOPT_HTTPPROXYTUNNEL: + /* + * Tunnel operations through the proxy instead of normal proxy use + */ + data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long)) ? + TRUE : FALSE; + break; + + case CURLOPT_PROXYPORT: + /* + * Explicitly set HTTP proxy port number. + */ + arg = va_arg(param, long); + if((arg < 0) || (arg > 65535)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.proxyport = arg; + break; + + case CURLOPT_PROXYAUTH: + /* + * Set HTTP Authentication type BITMASK. + */ + { + int bitcheck; + bool authbits; + unsigned long auth = va_arg(param, unsigned long); + + if(auth == CURLAUTH_NONE) { + data->set.proxyauth = auth; + break; + } + + /* the DIGEST_IE bit is only used to set a special marker, for all the + rest we need to handle it as normal DIGEST */ + data->state.authproxy.iestyle = + (bool)((auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE); + + if(auth & CURLAUTH_DIGEST_IE) { + auth |= CURLAUTH_DIGEST; /* set standard digest bit */ + auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */ + } + /* switch off bits we can't support */ +#ifndef USE_NTLM + auth &= ~CURLAUTH_NTLM; /* no NTLM support */ + auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ +#elif !defined(NTLM_WB_ENABLED) + auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ +#endif +#ifndef USE_SPNEGO + auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without + GSS-API or SSPI */ +#endif + + /* check if any auth bit lower than CURLAUTH_ONLY is still set */ + bitcheck = 0; + authbits = FALSE; + while(bitcheck < 31) { + if(auth & (1UL << bitcheck++)) { + authbits = TRUE; + break; + } + } + if(!authbits) + return CURLE_NOT_BUILT_IN; /* no supported types left! */ + + data->set.proxyauth = auth; + } + break; + + case CURLOPT_PROXY: + /* + * Set proxy server:port to use as proxy. + * + * If the proxy is set to "" (and CURLOPT_SOCKS_PROXY is set to "" or NULL) + * we explicitly say that we don't want to use a proxy + * (even though there might be environment variables saying so). + * + * Setting it to NULL, means no proxy but allows the environment variables + * to decide for us (if CURLOPT_SOCKS_PROXY setting it to NULL). + */ + result = Curl_setstropt(&data->set.str[STRING_PROXY], + va_arg(param, char *)); + break; + + case CURLOPT_PRE_PROXY: + /* + * Set proxy server:port to use as SOCKS proxy. + * + * If the proxy is set to "" or NULL we explicitly say that we don't want + * to use the socks proxy. + */ + result = Curl_setstropt(&data->set.str[STRING_PRE_PROXY], + va_arg(param, char *)); + break; + + case CURLOPT_PROXYTYPE: + /* + * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME + */ + arg = va_arg(param, long); + if((arg < CURLPROXY_HTTP) || (arg > CURLPROXY_SOCKS5_HOSTNAME)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.proxytype = (curl_proxytype)arg; + break; + + case CURLOPT_PROXY_TRANSFER_MODE: + /* + * set transfer mode (;type=) when doing FTP via an HTTP proxy + */ + switch(va_arg(param, long)) { + case 0: + data->set.proxy_transfer_mode = FALSE; + break; + case 1: + data->set.proxy_transfer_mode = TRUE; + break; + default: + /* reserve other values for future use */ + result = CURLE_UNKNOWN_OPTION; + break; + } + break; +#endif /* CURL_DISABLE_PROXY */ + + case CURLOPT_SOCKS5_AUTH: + data->set.socks5auth = va_arg(param, unsigned long); + if(data->set.socks5auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) + result = CURLE_NOT_BUILT_IN; + break; +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + case CURLOPT_SOCKS5_GSSAPI_NEC: + /* + * Set flag for NEC SOCK5 support + */ + data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; +#endif +#ifndef CURL_DISABLE_PROXY + case CURLOPT_SOCKS5_GSSAPI_SERVICE: + case CURLOPT_PROXY_SERVICE_NAME: + /* + * Set proxy authentication service name for Kerberos 5 and SPNEGO + */ + result = Curl_setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME], + va_arg(param, char *)); + break; +#endif + case CURLOPT_SERVICE_NAME: + /* + * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO + */ + result = Curl_setstropt(&data->set.str[STRING_SERVICE_NAME], + va_arg(param, char *)); + break; + + case CURLOPT_HEADERDATA: + /* + * Custom pointer to pass the header write callback function + */ + data->set.writeheader = (void *)va_arg(param, void *); + break; + case CURLOPT_ERRORBUFFER: + /* + * Error buffer provided by the caller to get the human readable + * error string in. + */ + data->set.errorbuffer = va_arg(param, char *); + break; + case CURLOPT_WRITEDATA: + /* + * FILE pointer to write to. Or possibly + * used as argument to the write callback. + */ + data->set.out = va_arg(param, void *); + break; + + case CURLOPT_DIRLISTONLY: + /* + * An option that changes the command to one that asks for a list only, no + * file info details. Used for FTP, POP3 and SFTP. + */ + data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_APPEND: + /* + * We want to upload and append to an existing file. Used for FTP and + * SFTP. + */ + data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + +#ifndef CURL_DISABLE_FTP + case CURLOPT_FTP_FILEMETHOD: + /* + * How do access files over FTP. + */ + arg = va_arg(param, long); + if((arg < CURLFTPMETHOD_DEFAULT) || (arg > CURLFTPMETHOD_SINGLECWD)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.ftp_filemethod = (curl_ftpfile)arg; + break; + case CURLOPT_FTPPORT: + /* + * Use FTP PORT, this also specifies which IP address to use + */ + result = Curl_setstropt(&data->set.str[STRING_FTPPORT], + va_arg(param, char *)); + data->set.ftp_use_port = (data->set.str[STRING_FTPPORT]) ? TRUE : FALSE; + break; + + case CURLOPT_FTP_USE_EPRT: + data->set.ftp_use_eprt = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_FTP_USE_EPSV: + data->set.ftp_use_epsv = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_FTP_USE_PRET: + data->set.ftp_use_pret = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_FTP_SSL_CCC: + arg = va_arg(param, long); + if((arg < CURLFTPSSL_CCC_NONE) || (arg > CURLFTPSSL_CCC_ACTIVE)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.ftp_ccc = (curl_ftpccc)arg; + break; + + case CURLOPT_FTP_SKIP_PASV_IP: + /* + * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the + * bypass of the IP address in PASV responses. + */ + data->set.ftp_skip_ip = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_FTP_ACCOUNT: + result = Curl_setstropt(&data->set.str[STRING_FTP_ACCOUNT], + va_arg(param, char *)); + break; + + case CURLOPT_FTP_ALTERNATIVE_TO_USER: + result = Curl_setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER], + va_arg(param, char *)); + break; + + case CURLOPT_FTPSSLAUTH: + /* + * Set a specific auth for FTP-SSL transfers. + */ + arg = va_arg(param, long); + if((arg < CURLFTPAUTH_DEFAULT) || (arg > CURLFTPAUTH_TLS)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.ftpsslauth = (curl_ftpauth)arg; + break; + case CURLOPT_KRBLEVEL: + /* + * A string that defines the kerberos security level. + */ + result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL], + va_arg(param, char *)); + data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE; + break; +#endif + case CURLOPT_FTP_CREATE_MISSING_DIRS: + /* + * An FTP/SFTP option that modifies an upload to create missing + * directories on the server. + */ + switch(va_arg(param, long)) { + case 0: + data->set.ftp_create_missing_dirs = 0; + break; + case 1: + data->set.ftp_create_missing_dirs = 1; + break; + case 2: + data->set.ftp_create_missing_dirs = 2; + break; + default: + /* reserve other values for future use */ + result = CURLE_UNKNOWN_OPTION; + break; + } + break; + case CURLOPT_READDATA: + /* + * FILE pointer to read the file to be uploaded from. Or possibly + * used as argument to the read callback. + */ + data->set.in_set = va_arg(param, void *); + break; + case CURLOPT_INFILESIZE: + /* + * If known, this should inform curl about the file size of the + * to-be-uploaded file. + */ + arg = va_arg(param, long); + if(arg < -1) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.filesize = arg; + break; + case CURLOPT_INFILESIZE_LARGE: + /* + * If known, this should inform curl about the file size of the + * to-be-uploaded file. + */ + bigsize = va_arg(param, curl_off_t); + if(bigsize < -1) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.filesize = bigsize; + break; + case CURLOPT_LOW_SPEED_LIMIT: + /* + * The low speed limit that if transfers are below this for + * CURLOPT_LOW_SPEED_TIME, the transfer is aborted. + */ + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.low_speed_limit = arg; + break; + case CURLOPT_MAX_SEND_SPEED_LARGE: + /* + * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE + * bytes per second the transfer is throttled.. + */ + bigsize = va_arg(param, curl_off_t); + if(bigsize < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.max_send_speed = bigsize; + break; + case CURLOPT_MAX_RECV_SPEED_LARGE: + /* + * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per + * second the transfer is throttled.. + */ + bigsize = va_arg(param, curl_off_t); + if(bigsize < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.max_recv_speed = bigsize; + break; + case CURLOPT_LOW_SPEED_TIME: + /* + * The low speed time that if transfers are below the set + * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted. + */ + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.low_speed_time = arg; + break; + case CURLOPT_CURLU: + /* + * pass CURLU to set URL + */ + data->set.uh = va_arg(param, CURLU *); + break; + case CURLOPT_URL: + /* + * The URL to fetch. + */ + if(data->change.url_alloc) { + /* the already set URL is allocated, free it first! */ + Curl_safefree(data->change.url); + data->change.url_alloc = FALSE; + } + result = Curl_setstropt(&data->set.str[STRING_SET_URL], + va_arg(param, char *)); + data->change.url = data->set.str[STRING_SET_URL]; + break; + case CURLOPT_PORT: + /* + * The port number to use when getting the URL + */ + arg = va_arg(param, long); + if((arg < 0) || (arg > 65535)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.use_port = arg; + break; + case CURLOPT_TIMEOUT: + /* + * The maximum time you allow curl to use for a single transfer + * operation. + */ + arg = va_arg(param, long); + if((arg >= 0) && (arg <= (INT_MAX/1000))) + data->set.timeout = arg * 1000; + else + return CURLE_BAD_FUNCTION_ARGUMENT; + break; + + case CURLOPT_TIMEOUT_MS: + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.timeout = arg; + break; + + case CURLOPT_CONNECTTIMEOUT: + /* + * The maximum time you allow curl to use to connect. + */ + arg = va_arg(param, long); + if((arg >= 0) && (arg <= (INT_MAX/1000))) + data->set.connecttimeout = arg * 1000; + else + return CURLE_BAD_FUNCTION_ARGUMENT; + break; + + case CURLOPT_CONNECTTIMEOUT_MS: + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.connecttimeout = arg; + break; + + case CURLOPT_ACCEPTTIMEOUT_MS: + /* + * The maximum time you allow curl to wait for server connect + */ + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.accepttimeout = arg; + break; + + case CURLOPT_USERPWD: + /* + * user:password to use in the operation + */ + result = setstropt_userpwd(va_arg(param, char *), + &data->set.str[STRING_USERNAME], + &data->set.str[STRING_PASSWORD]); + break; + + case CURLOPT_USERNAME: + /* + * authentication user name to use in the operation + */ + result = Curl_setstropt(&data->set.str[STRING_USERNAME], + va_arg(param, char *)); + break; + + case CURLOPT_PASSWORD: + /* + * authentication password to use in the operation + */ + result = Curl_setstropt(&data->set.str[STRING_PASSWORD], + va_arg(param, char *)); + break; + + case CURLOPT_LOGIN_OPTIONS: + /* + * authentication options to use in the operation + */ + result = Curl_setstropt(&data->set.str[STRING_OPTIONS], + va_arg(param, char *)); + break; + + case CURLOPT_XOAUTH2_BEARER: + /* + * OAuth 2.0 bearer token to use in the operation + */ + result = Curl_setstropt(&data->set.str[STRING_BEARER], + va_arg(param, char *)); + break; + + case CURLOPT_POSTQUOTE: + /* + * List of RAW FTP commands to use after a transfer + */ + data->set.postquote = va_arg(param, struct curl_slist *); + break; + case CURLOPT_PREQUOTE: + /* + * List of RAW FTP commands to use prior to RETR (Wesley Laxton) + */ + data->set.prequote = va_arg(param, struct curl_slist *); + break; + case CURLOPT_QUOTE: + /* + * List of RAW FTP commands to use before a transfer + */ + data->set.quote = va_arg(param, struct curl_slist *); + break; + case CURLOPT_RESOLVE: + /* + * List of NAME:[address] names to populate the DNS cache with + * Prefix the NAME with dash (-) to _remove_ the name from the cache. + * + * Names added with this API will remain in the cache until explicitly + * removed or the handle is cleaned up. + * + * This API can remove any name from the DNS cache, but only entries + * that aren't actually in use right now will be pruned immediately. + */ + data->set.resolve = va_arg(param, struct curl_slist *); + data->change.resolve = data->set.resolve; + break; + case CURLOPT_PROGRESSFUNCTION: + /* + * Progress callback function + */ + data->set.fprogress = va_arg(param, curl_progress_callback); + if(data->set.fprogress) + data->progress.callback = TRUE; /* no longer internal */ + else + data->progress.callback = FALSE; /* NULL enforces internal */ + break; + + case CURLOPT_XFERINFOFUNCTION: + /* + * Transfer info callback function + */ + data->set.fxferinfo = va_arg(param, curl_xferinfo_callback); + if(data->set.fxferinfo) + data->progress.callback = TRUE; /* no longer internal */ + else + data->progress.callback = FALSE; /* NULL enforces internal */ + + break; + + case CURLOPT_PROGRESSDATA: + /* + * Custom client data to pass to the progress callback + */ + data->set.progress_client = va_arg(param, void *); + break; + +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXYUSERPWD: + /* + * user:password needed to use the proxy + */ + result = setstropt_userpwd(va_arg(param, char *), + &data->set.str[STRING_PROXYUSERNAME], + &data->set.str[STRING_PROXYPASSWORD]); + break; + case CURLOPT_PROXYUSERNAME: + /* + * authentication user name to use in the operation + */ + result = Curl_setstropt(&data->set.str[STRING_PROXYUSERNAME], + va_arg(param, char *)); + break; + case CURLOPT_PROXYPASSWORD: + /* + * authentication password to use in the operation + */ + result = Curl_setstropt(&data->set.str[STRING_PROXYPASSWORD], + va_arg(param, char *)); + break; + case CURLOPT_NOPROXY: + /* + * proxy exception list + */ + result = Curl_setstropt(&data->set.str[STRING_NOPROXY], + va_arg(param, char *)); + break; +#endif + + case CURLOPT_RANGE: + /* + * What range of the file you want to transfer + */ + result = Curl_setstropt(&data->set.str[STRING_SET_RANGE], + va_arg(param, char *)); + break; + case CURLOPT_RESUME_FROM: + /* + * Resume transfer at the given file position + */ + arg = va_arg(param, long); + if(arg < -1) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.set_resume_from = arg; + break; + case CURLOPT_RESUME_FROM_LARGE: + /* + * Resume transfer at the given file position + */ + bigsize = va_arg(param, curl_off_t); + if(bigsize < -1) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.set_resume_from = bigsize; + break; + case CURLOPT_DEBUGFUNCTION: + /* + * stderr write callback. + */ + data->set.fdebug = va_arg(param, curl_debug_callback); + /* + * if the callback provided is NULL, it'll use the default callback + */ + break; + case CURLOPT_DEBUGDATA: + /* + * Set to a void * that should receive all error writes. This + * defaults to CURLOPT_STDERR for normal operations. + */ + data->set.debugdata = va_arg(param, void *); + break; + case CURLOPT_STDERR: + /* + * Set to a FILE * that should receive all error writes. This + * defaults to stderr for normal operations. + */ + data->set.err = va_arg(param, FILE *); + if(!data->set.err) + data->set.err = stderr; + break; + case CURLOPT_HEADERFUNCTION: + /* + * Set header write callback + */ + data->set.fwrite_header = va_arg(param, curl_write_callback); + break; + case CURLOPT_WRITEFUNCTION: + /* + * Set data write callback + */ + data->set.fwrite_func = va_arg(param, curl_write_callback); + if(!data->set.fwrite_func) { + data->set.is_fwrite_set = 0; + /* When set to NULL, reset to our internal default function */ + data->set.fwrite_func = (curl_write_callback)fwrite; + } + else + data->set.is_fwrite_set = 1; + break; + case CURLOPT_READFUNCTION: + /* + * Read data callback + */ + data->set.fread_func_set = va_arg(param, curl_read_callback); + if(!data->set.fread_func_set) { + data->set.is_fread_set = 0; + /* When set to NULL, reset to our internal default function */ + data->set.fread_func_set = (curl_read_callback)fread; + } + else + data->set.is_fread_set = 1; + break; + case CURLOPT_SEEKFUNCTION: + /* + * Seek callback. Might be NULL. + */ + data->set.seek_func = va_arg(param, curl_seek_callback); + break; + case CURLOPT_SEEKDATA: + /* + * Seek control callback. Might be NULL. + */ + data->set.seek_client = va_arg(param, void *); + break; + case CURLOPT_CONV_FROM_NETWORK_FUNCTION: + /* + * "Convert from network encoding" callback + */ + data->set.convfromnetwork = va_arg(param, curl_conv_callback); + break; + case CURLOPT_CONV_TO_NETWORK_FUNCTION: + /* + * "Convert to network encoding" callback + */ + data->set.convtonetwork = va_arg(param, curl_conv_callback); + break; + case CURLOPT_CONV_FROM_UTF8_FUNCTION: + /* + * "Convert from UTF-8 encoding" callback + */ + data->set.convfromutf8 = va_arg(param, curl_conv_callback); + break; + case CURLOPT_IOCTLFUNCTION: + /* + * I/O control callback. Might be NULL. + */ + data->set.ioctl_func = va_arg(param, curl_ioctl_callback); + break; + case CURLOPT_IOCTLDATA: + /* + * I/O control data pointer. Might be NULL. + */ + data->set.ioctl_client = va_arg(param, void *); + break; + case CURLOPT_SSLCERT: + /* + * String that holds file name of the SSL certificate to use + */ + result = Curl_setstropt(&data->set.str[STRING_CERT_ORIG], + va_arg(param, char *)); + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_SSLCERT: + /* + * String that holds file name of the SSL certificate to use for proxy + */ + result = Curl_setstropt(&data->set.str[STRING_CERT_PROXY], + va_arg(param, char *)); + break; +#endif + case CURLOPT_SSLCERTTYPE: + /* + * String that holds file type of the SSL certificate to use + */ + result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_ORIG], + va_arg(param, char *)); + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_SSLCERTTYPE: + /* + * String that holds file type of the SSL certificate to use for proxy + */ + result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_PROXY], + va_arg(param, char *)); + break; +#endif + case CURLOPT_SSLKEY: + /* + * String that holds file name of the SSL key to use + */ + result = Curl_setstropt(&data->set.str[STRING_KEY_ORIG], + va_arg(param, char *)); + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_SSLKEY: + /* + * String that holds file name of the SSL key to use for proxy + */ + result = Curl_setstropt(&data->set.str[STRING_KEY_PROXY], + va_arg(param, char *)); + break; +#endif + case CURLOPT_SSLKEYTYPE: + /* + * String that holds file type of the SSL key to use + */ + result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_ORIG], + va_arg(param, char *)); + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_SSLKEYTYPE: + /* + * String that holds file type of the SSL key to use for proxy + */ + result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_PROXY], + va_arg(param, char *)); + break; +#endif + case CURLOPT_KEYPASSWD: + /* + * String that holds the SSL or SSH private key password. + */ + result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG], + va_arg(param, char *)); + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_KEYPASSWD: + /* + * String that holds the SSL private key password for proxy. + */ + result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_PROXY], + va_arg(param, char *)); + break; +#endif + case CURLOPT_SSLENGINE: + /* + * String that holds the SSL crypto engine. + */ + argptr = va_arg(param, char *); + if(argptr && argptr[0]) { + result = Curl_setstropt(&data->set.str[STRING_SSL_ENGINE], argptr); + if(!result) { + result = Curl_ssl_set_engine(data, argptr); + } + } + break; + + case CURLOPT_SSLENGINE_DEFAULT: + /* + * flag to set engine as default. + */ + Curl_setstropt(&data->set.str[STRING_SSL_ENGINE], NULL); + result = Curl_ssl_set_engine_default(data); + break; + case CURLOPT_CRLF: + /* + * Kludgy option to enable CRLF conversions. Subject for removal. + */ + data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_HAPROXYPROTOCOL: + /* + * Set to send the HAProxy Proxy Protocol header + */ + data->set.haproxyprotocol = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; +#endif + case CURLOPT_INTERFACE: + /* + * Set what interface or address/hostname to bind the socket to when + * performing an operation and thus what from-IP your connection will use. + */ + result = Curl_setstropt(&data->set.str[STRING_DEVICE], + va_arg(param, char *)); + break; + case CURLOPT_LOCALPORT: + /* + * Set what local port to bind the socket to when performing an operation. + */ + arg = va_arg(param, long); + if((arg < 0) || (arg > 65535)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.localport = curlx_sltous(arg); + break; + case CURLOPT_LOCALPORTRANGE: + /* + * Set number of local ports to try, starting with CURLOPT_LOCALPORT. + */ + arg = va_arg(param, long); + if((arg < 0) || (arg > 65535)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.localportrange = curlx_sltosi(arg); + break; + case CURLOPT_GSSAPI_DELEGATION: + /* + * GSS-API credential delegation bitmask + */ + arg = va_arg(param, long); + if(arg < CURLGSSAPI_DELEGATION_NONE) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.gssapi_delegation = arg; + break; + case CURLOPT_SSL_VERIFYPEER: + /* + * Enable peer SSL verifying. + */ + data->set.ssl.primary.verifypeer = (0 != va_arg(param, long)) ? + TRUE : FALSE; + + /* Update the current connection ssl_config. */ + if(data->conn) { + data->conn->ssl_config.verifypeer = + data->set.ssl.primary.verifypeer; + } + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_SSL_VERIFYPEER: + /* + * Enable peer SSL verifying for proxy. + */ + data->set.proxy_ssl.primary.verifypeer = + (0 != va_arg(param, long))?TRUE:FALSE; + + /* Update the current connection proxy_ssl_config. */ + if(data->conn) { + data->conn->proxy_ssl_config.verifypeer = + data->set.proxy_ssl.primary.verifypeer; + } + break; +#endif + case CURLOPT_SSL_VERIFYHOST: + /* + * Enable verification of the host name in the peer certificate + */ + arg = va_arg(param, long); + + /* Obviously people are not reading documentation and too many thought + this argument took a boolean when it wasn't and misused it. We thus ban + 1 as a sensible input and we warn about its use. Then we only have the + 2 action internally stored as TRUE. */ + + if(1 == arg) { + failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + + data->set.ssl.primary.verifyhost = (0 != arg) ? TRUE : FALSE; + + /* Update the current connection ssl_config. */ + if(data->conn) { + data->conn->ssl_config.verifyhost = + data->set.ssl.primary.verifyhost; + } + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_SSL_VERIFYHOST: + /* + * Enable verification of the host name in the peer certificate for proxy + */ + arg = va_arg(param, long); + + /* Obviously people are not reading documentation and too many thought + this argument took a boolean when it wasn't and misused it. We thus ban + 1 as a sensible input and we warn about its use. Then we only have the + 2 action internally stored as TRUE. */ + + if(1 == arg) { + failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + + data->set.proxy_ssl.primary.verifyhost = (0 != arg)?TRUE:FALSE; + + /* Update the current connection proxy_ssl_config. */ + if(data->conn) { + data->conn->proxy_ssl_config.verifyhost = + data->set.proxy_ssl.primary.verifyhost; + } + break; +#endif + case CURLOPT_SSL_VERIFYSTATUS: + /* + * Enable certificate status verifying. + */ + if(!Curl_ssl_cert_status_request()) { + result = CURLE_NOT_BUILT_IN; + break; + } + + data->set.ssl.primary.verifystatus = (0 != va_arg(param, long)) ? + TRUE : FALSE; + + /* Update the current connection ssl_config. */ + if(data->conn) { + data->conn->ssl_config.verifystatus = + data->set.ssl.primary.verifystatus; + } + break; + case CURLOPT_SSL_CTX_FUNCTION: + /* + * Set a SSL_CTX callback + */ +#ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_SSL_CTX) + data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); + else +#endif + result = CURLE_NOT_BUILT_IN; + break; + case CURLOPT_SSL_CTX_DATA: + /* + * Set a SSL_CTX callback parameter pointer + */ +#ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_SSL_CTX) + data->set.ssl.fsslctxp = va_arg(param, void *); + else +#endif + result = CURLE_NOT_BUILT_IN; + break; + case CURLOPT_SSL_FALSESTART: + /* + * Enable TLS false start. + */ + if(!Curl_ssl_false_start()) { + result = CURLE_NOT_BUILT_IN; + break; + } + + data->set.ssl.falsestart = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_CERTINFO: +#ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_CERTINFO) + data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE; + else +#endif + result = CURLE_NOT_BUILT_IN; + break; + case CURLOPT_PINNEDPUBLICKEY: + /* + * Set pinned public key for SSL connection. + * Specify file name of the public key in DER format. + */ +#ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_PINNEDPUBKEY) + result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG], + va_arg(param, char *)); + else +#endif + result = CURLE_NOT_BUILT_IN; + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_PINNEDPUBLICKEY: + /* + * Set pinned public key for SSL connection. + * Specify file name of the public key in DER format. + */ +#ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_PINNEDPUBKEY) + result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY], + va_arg(param, char *)); + else +#endif + result = CURLE_NOT_BUILT_IN; + break; +#endif + case CURLOPT_CAINFO: + /* + * Set CA info for SSL connection. Specify file name of the CA certificate + */ + result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG], + va_arg(param, char *)); + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_CAINFO: + /* + * Set CA info SSL connection for proxy. Specify file name of the + * CA certificate + */ + result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY], + va_arg(param, char *)); + break; +#endif + case CURLOPT_CAPATH: + /* + * Set CA path info for SSL connection. Specify directory name of the CA + * certificates which have been prepared using openssl c_rehash utility. + */ +#ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_CA_PATH) + /* This does not work on windows. */ + result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG], + va_arg(param, char *)); + else +#endif + result = CURLE_NOT_BUILT_IN; + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_CAPATH: + /* + * Set CA path info for SSL connection proxy. Specify directory name of the + * CA certificates which have been prepared using openssl c_rehash utility. + */ +#ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_CA_PATH) + /* This does not work on windows. */ + result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY], + va_arg(param, char *)); + else +#endif + result = CURLE_NOT_BUILT_IN; + break; +#endif + case CURLOPT_CRLFILE: + /* + * Set CRL file info for SSL connection. Specify file name of the CRL + * to check certificates revocation + */ + result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG], + va_arg(param, char *)); + break; +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_CRLFILE: + /* + * Set CRL file info for SSL connection for proxy. Specify file name of the + * CRL to check certificates revocation + */ + result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_PROXY], + va_arg(param, char *)); + break; +#endif + case CURLOPT_ISSUERCERT: + /* + * Set Issuer certificate file + * to check certificates issuer + */ + result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG], + va_arg(param, char *)); + break; +#ifndef CURL_DISABLE_TELNET + case CURLOPT_TELNETOPTIONS: + /* + * Set a linked list of telnet options + */ + data->set.telnet_options = va_arg(param, struct curl_slist *); + break; +#endif + case CURLOPT_BUFFERSIZE: + /* + * The application kindly asks for a differently sized receive buffer. + * If it seems reasonable, we'll use it. + */ + arg = va_arg(param, long); + + if(arg > READBUFFER_MAX) + arg = READBUFFER_MAX; + else if(arg < 1) + arg = READBUFFER_SIZE; + else if(arg < READBUFFER_MIN) + arg = READBUFFER_MIN; + + /* Resize if new size */ + if(arg != data->set.buffer_size) { + char *newbuff = realloc(data->state.buffer, arg + 1); + if(!newbuff) { + DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n")); + result = CURLE_OUT_OF_MEMORY; + } + else + data->state.buffer = newbuff; + } + data->set.buffer_size = arg; + + break; + + case CURLOPT_UPLOAD_BUFFERSIZE: + /* + * The application kindly asks for a differently sized upload buffer. + * Cap it to sensible. + */ + arg = va_arg(param, long); + + if(arg > UPLOADBUFFER_MAX) + arg = UPLOADBUFFER_MAX; + else if(arg < UPLOADBUFFER_MIN) + arg = UPLOADBUFFER_MIN; + + data->set.upload_buffer_size = arg; + Curl_safefree(data->state.ulbuf); /* force a realloc next opportunity */ + break; + + case CURLOPT_NOSIGNAL: + /* + * The application asks not to set any signal() or alarm() handlers, + * even when using a timeout. + */ + data->set.no_signal = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_SHARE: + { + struct Curl_share *set; + set = va_arg(param, struct Curl_share *); + + /* disconnect from old share, if any */ + if(data->share) { + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + + if(data->dns.hostcachetype == HCACHE_SHARED) { + data->dns.hostcache = NULL; + data->dns.hostcachetype = HCACHE_NONE; + } + +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) + if(data->share->cookies == data->cookies) + data->cookies = NULL; +#endif + + if(data->share->sslsession == data->state.session) + data->state.session = NULL; + +#ifdef USE_LIBPSL + if(data->psl == &data->share->psl) + data->psl = data->multi? &data->multi->psl: NULL; +#endif + + data->share->dirty--; + + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + data->share = NULL; + } + + /* use new share if it set */ + data->share = set; + if(data->share) { + + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + + data->share->dirty++; + + if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) { + /* use shared host cache */ + data->dns.hostcache = &data->share->hostcache; + data->dns.hostcachetype = HCACHE_SHARED; + } +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) + if(data->share->cookies) { + /* use shared cookie list, first free own one if any */ + Curl_cookie_cleanup(data->cookies); + /* enable cookies since we now use a share that uses cookies! */ + data->cookies = data->share->cookies; + } +#endif /* CURL_DISABLE_HTTP */ + if(data->share->sslsession) { + data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions; + data->state.session = data->share->sslsession; + } +#ifdef USE_LIBPSL + if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL)) + data->psl = &data->share->psl; +#endif + + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + } + /* check for host cache not needed, + * it will be done by curl_easy_perform */ + } + break; + + case CURLOPT_PRIVATE: + /* + * Set private data pointer. + */ + data->set.private_data = va_arg(param, void *); + break; + + case CURLOPT_MAXFILESIZE: + /* + * Set the maximum size of a file to download. + */ + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.max_filesize = arg; + break; + +#ifdef USE_SSL + case CURLOPT_USE_SSL: + /* + * Make transfers attempt to use SSL/TLS. + */ + arg = va_arg(param, long); + if((arg < CURLUSESSL_NONE) || (arg > CURLUSESSL_ALL)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.use_ssl = (curl_usessl)arg; + break; + + case CURLOPT_SSL_OPTIONS: + arg = va_arg(param, long); + data->set.ssl.enable_beast = + (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); + data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); + break; + +#ifndef CURL_DISABLE_PROXY + case CURLOPT_PROXY_SSL_OPTIONS: + arg = va_arg(param, long); + data->set.proxy_ssl.enable_beast = + (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); + data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); + break; +#endif + +#endif + case CURLOPT_IPRESOLVE: + arg = va_arg(param, long); + if((arg < CURL_IPRESOLVE_WHATEVER) || (arg > CURL_IPRESOLVE_V6)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.ipver = arg; + break; + + case CURLOPT_MAXFILESIZE_LARGE: + /* + * Set the maximum size of a file to download. + */ + bigsize = va_arg(param, curl_off_t); + if(bigsize < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.max_filesize = bigsize; + break; + + case CURLOPT_TCP_NODELAY: + /* + * Enable or disable TCP_NODELAY, which will disable/enable the Nagle + * algorithm + */ + data->set.tcp_nodelay = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_IGNORE_CONTENT_LENGTH: + data->set.ignorecl = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_CONNECT_ONLY: + /* + * No data transfer, set up connection and let application use the socket + */ + data->set.connect_only = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_SOCKOPTFUNCTION: + /* + * socket callback function: called after socket() but before connect() + */ + data->set.fsockopt = va_arg(param, curl_sockopt_callback); + break; + + case CURLOPT_SOCKOPTDATA: + /* + * socket callback data pointer. Might be NULL. + */ + data->set.sockopt_client = va_arg(param, void *); + break; + + case CURLOPT_OPENSOCKETFUNCTION: + /* + * open/create socket callback function: called instead of socket(), + * before connect() + */ + data->set.fopensocket = va_arg(param, curl_opensocket_callback); + break; + + case CURLOPT_OPENSOCKETDATA: + /* + * socket callback data pointer. Might be NULL. + */ + data->set.opensocket_client = va_arg(param, void *); + break; + + case CURLOPT_CLOSESOCKETFUNCTION: + /* + * close socket callback function: called instead of close() + * when shutting down a connection + */ + data->set.fclosesocket = va_arg(param, curl_closesocket_callback); + break; + + case CURLOPT_RESOLVER_START_FUNCTION: + /* + * resolver start callback function: called before a new resolver request + * is started + */ + data->set.resolver_start = va_arg(param, curl_resolver_start_callback); + break; + + case CURLOPT_RESOLVER_START_DATA: + /* + * resolver start callback data pointer. Might be NULL. + */ + data->set.resolver_start_client = va_arg(param, void *); + break; + + case CURLOPT_CLOSESOCKETDATA: + /* + * socket callback data pointer. Might be NULL. + */ + data->set.closesocket_client = va_arg(param, void *); + break; + + case CURLOPT_SSL_SESSIONID_CACHE: + data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ? + TRUE : FALSE; + data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid; + break; + +#ifdef USE_SSH + /* we only include SSH options if explicitly built to support SSH */ + case CURLOPT_SSH_AUTH_TYPES: + data->set.ssh_auth_types = va_arg(param, long); + break; + + case CURLOPT_SSH_PUBLIC_KEYFILE: + /* + * Use this file instead of the $HOME/.ssh/id_dsa.pub file + */ + result = Curl_setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY], + va_arg(param, char *)); + break; + + case CURLOPT_SSH_PRIVATE_KEYFILE: + /* + * Use this file instead of the $HOME/.ssh/id_dsa file + */ + result = Curl_setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY], + va_arg(param, char *)); + break; + case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: + /* + * Option to allow for the MD5 of the host public key to be checked + * for validation purposes. + */ + result = Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], + va_arg(param, char *)); + break; + + case CURLOPT_SSH_KNOWNHOSTS: + /* + * Store the file name to read known hosts from. + */ + result = Curl_setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS], + va_arg(param, char *)); + break; + + case CURLOPT_SSH_KEYFUNCTION: + /* setting to NULL is fine since the ssh.c functions themselves will + then rever to use the internal default */ + data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback); + break; + + case CURLOPT_SSH_KEYDATA: + /* + * Custom client data to pass to the SSH keyfunc callback + */ + data->set.ssh_keyfunc_userp = va_arg(param, void *); + break; + + case CURLOPT_SSH_COMPRESSION: + data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE; + break; +#endif /* USE_SSH */ + + case CURLOPT_HTTP_TRANSFER_DECODING: + /* + * disable libcurl transfer encoding is used + */ + data->set.http_te_skip = (0 == va_arg(param, long)) ? TRUE : FALSE; + break; + + case CURLOPT_HTTP_CONTENT_DECODING: + /* + * raw data passed to the application when content encoding is used + */ + data->set.http_ce_skip = (0 == va_arg(param, long)) ? TRUE : FALSE; + break; + +#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) + case CURLOPT_NEW_FILE_PERMS: + /* + * Uses these permissions instead of 0644 + */ + arg = va_arg(param, long); + if((arg < 0) || (arg > 0777)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.new_file_perms = arg; + break; + + case CURLOPT_NEW_DIRECTORY_PERMS: + /* + * Uses these permissions instead of 0755 + */ + arg = va_arg(param, long); + if((arg < 0) || (arg > 0777)) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.new_directory_perms = arg; + break; +#endif + + case CURLOPT_ADDRESS_SCOPE: + /* + * Use this scope id when using IPv6 + * We always get longs when passed plain numericals so we should check + * that the value fits into an unsigned 32 bit integer. + */ + uarg = va_arg(param, unsigned long); +#if SIZEOF_LONG > 4 + if(uarg > UINT_MAX) + return CURLE_BAD_FUNCTION_ARGUMENT; +#endif + data->set.scope_id = (unsigned int)uarg; + break; + + case CURLOPT_PROTOCOLS: + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + data->set.allowed_protocols = va_arg(param, long); + break; + + case CURLOPT_REDIR_PROTOCOLS: + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. */ + data->set.redir_protocols = va_arg(param, long); + break; + + case CURLOPT_DEFAULT_PROTOCOL: + /* Set the protocol to use when the URL doesn't include any protocol */ + result = Curl_setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL], + va_arg(param, char *)); + break; +#ifndef CURL_DISABLE_SMTP + case CURLOPT_MAIL_FROM: + /* Set the SMTP mail originator */ + result = Curl_setstropt(&data->set.str[STRING_MAIL_FROM], + va_arg(param, char *)); + break; + + case CURLOPT_MAIL_AUTH: + /* Set the SMTP auth originator */ + result = Curl_setstropt(&data->set.str[STRING_MAIL_AUTH], + va_arg(param, char *)); + break; + + case CURLOPT_MAIL_RCPT: + /* Set the list of mail recipients */ + data->set.mail_rcpt = va_arg(param, struct curl_slist *); + break; +#endif + + case CURLOPT_SASL_IR: + /* Enable/disable SASL initial response */ + data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; +#ifndef CURL_DISABLE_RTSP + case CURLOPT_RTSP_REQUEST: + { + /* + * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...) + * Would this be better if the RTSPREQ_* were just moved into here? + */ + long curl_rtspreq = va_arg(param, long); + Curl_RtspReq rtspreq = RTSPREQ_NONE; + switch(curl_rtspreq) { + case CURL_RTSPREQ_OPTIONS: + rtspreq = RTSPREQ_OPTIONS; + break; + + case CURL_RTSPREQ_DESCRIBE: + rtspreq = RTSPREQ_DESCRIBE; + break; + + case CURL_RTSPREQ_ANNOUNCE: + rtspreq = RTSPREQ_ANNOUNCE; + break; + + case CURL_RTSPREQ_SETUP: + rtspreq = RTSPREQ_SETUP; + break; + + case CURL_RTSPREQ_PLAY: + rtspreq = RTSPREQ_PLAY; + break; + + case CURL_RTSPREQ_PAUSE: + rtspreq = RTSPREQ_PAUSE; + break; + + case CURL_RTSPREQ_TEARDOWN: + rtspreq = RTSPREQ_TEARDOWN; + break; + + case CURL_RTSPREQ_GET_PARAMETER: + rtspreq = RTSPREQ_GET_PARAMETER; + break; + + case CURL_RTSPREQ_SET_PARAMETER: + rtspreq = RTSPREQ_SET_PARAMETER; + break; + + case CURL_RTSPREQ_RECORD: + rtspreq = RTSPREQ_RECORD; + break; + + case CURL_RTSPREQ_RECEIVE: + rtspreq = RTSPREQ_RECEIVE; + break; + default: + rtspreq = RTSPREQ_NONE; + } + + data->set.rtspreq = rtspreq; + break; + } + + + case CURLOPT_RTSP_SESSION_ID: + /* + * Set the RTSP Session ID manually. Useful if the application is + * resuming a previously established RTSP session + */ + result = Curl_setstropt(&data->set.str[STRING_RTSP_SESSION_ID], + va_arg(param, char *)); + break; + + case CURLOPT_RTSP_STREAM_URI: + /* + * Set the Stream URI for the RTSP request. Unless the request is + * for generic server options, the application will need to set this. + */ + result = Curl_setstropt(&data->set.str[STRING_RTSP_STREAM_URI], + va_arg(param, char *)); + break; + + case CURLOPT_RTSP_TRANSPORT: + /* + * The content of the Transport: header for the RTSP request + */ + result = Curl_setstropt(&data->set.str[STRING_RTSP_TRANSPORT], + va_arg(param, char *)); + break; + + case CURLOPT_RTSP_CLIENT_CSEQ: + /* + * Set the CSEQ number to issue for the next RTSP request. Useful if the + * application is resuming a previously broken connection. The CSEQ + * will increment from this new number henceforth. + */ + data->state.rtsp_next_client_CSeq = va_arg(param, long); + break; + + case CURLOPT_RTSP_SERVER_CSEQ: + /* Same as the above, but for server-initiated requests */ + data->state.rtsp_next_client_CSeq = va_arg(param, long); + break; + + case CURLOPT_INTERLEAVEDATA: + data->set.rtp_out = va_arg(param, void *); + break; + case CURLOPT_INTERLEAVEFUNCTION: + /* Set the user defined RTP write function */ + data->set.fwrite_rtp = va_arg(param, curl_write_callback); + break; +#endif +#ifndef CURL_DISABLE_FTP + case CURLOPT_WILDCARDMATCH: + data->set.wildcard_enabled = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_CHUNK_BGN_FUNCTION: + data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback); + break; + case CURLOPT_CHUNK_END_FUNCTION: + data->set.chunk_end = va_arg(param, curl_chunk_end_callback); + break; + case CURLOPT_FNMATCH_FUNCTION: + data->set.fnmatch = va_arg(param, curl_fnmatch_callback); + break; + case CURLOPT_CHUNK_DATA: + data->wildcard.customptr = va_arg(param, void *); + break; + case CURLOPT_FNMATCH_DATA: + data->set.fnmatch_data = va_arg(param, void *); + break; +#endif +#ifdef USE_TLS_SRP + case CURLOPT_TLSAUTH_USERNAME: + result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG], + va_arg(param, char *)); + if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_PROXY_TLSAUTH_USERNAME: + result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY], + va_arg(param, char *)); + if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] && + !data->set.proxy_ssl.authtype) + data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_TLSAUTH_PASSWORD: + result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG], + va_arg(param, char *)); + if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_PROXY_TLSAUTH_PASSWORD: + result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY], + va_arg(param, char *)); + if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] && + !data->set.proxy_ssl.authtype) + data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_TLSAUTH_TYPE: + argptr = va_arg(param, char *); + if(!argptr || + strncasecompare(argptr, "SRP", strlen("SRP"))) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; + else + data->set.ssl.authtype = CURL_TLSAUTH_NONE; + break; + case CURLOPT_PROXY_TLSAUTH_TYPE: + argptr = va_arg(param, char *); + if(!argptr || + strncasecompare(argptr, "SRP", strlen("SRP"))) + data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; + else + data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE; + break; +#endif +#ifdef USE_ARES + case CURLOPT_DNS_SERVERS: + result = Curl_set_dns_servers(data, va_arg(param, char *)); + break; + case CURLOPT_DNS_INTERFACE: + result = Curl_set_dns_interface(data, va_arg(param, char *)); + break; + case CURLOPT_DNS_LOCAL_IP4: + result = Curl_set_dns_local_ip4(data, va_arg(param, char *)); + break; + case CURLOPT_DNS_LOCAL_IP6: + result = Curl_set_dns_local_ip6(data, va_arg(param, char *)); + break; +#endif + case CURLOPT_TCP_KEEPALIVE: + data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_TCP_KEEPIDLE: + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.tcp_keepidle = arg; + break; + case CURLOPT_TCP_KEEPINTVL: + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.tcp_keepintvl = arg; + break; + case CURLOPT_TCP_FASTOPEN: +#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \ + defined(TCP_FASTOPEN_CONNECT) + data->set.tcp_fastopen = (0 != va_arg(param, long))?TRUE:FALSE; +#else + result = CURLE_NOT_BUILT_IN; +#endif + break; +#ifdef USE_NGHTTP2 + case CURLOPT_SSL_ENABLE_NPN: + data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_SSL_ENABLE_ALPN: + data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; +#endif +#ifdef USE_UNIX_SOCKETS + case CURLOPT_UNIX_SOCKET_PATH: + data->set.abstract_unix_socket = FALSE; + result = Curl_setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH], + va_arg(param, char *)); + break; + case CURLOPT_ABSTRACT_UNIX_SOCKET: + data->set.abstract_unix_socket = TRUE; + result = Curl_setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH], + va_arg(param, char *)); + break; +#endif + + case CURLOPT_PATH_AS_IS: + data->set.path_as_is = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_PIPEWAIT: + data->set.pipewait = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_STREAM_WEIGHT: +#ifndef USE_NGHTTP2 + return CURLE_NOT_BUILT_IN; +#else + arg = va_arg(param, long); + if((arg >= 1) && (arg <= 256)) + data->set.stream_weight = (int)arg; + break; +#endif + case CURLOPT_STREAM_DEPENDS: + case CURLOPT_STREAM_DEPENDS_E: + { +#ifndef USE_NGHTTP2 + return CURLE_NOT_BUILT_IN; +#else + struct Curl_easy *dep = va_arg(param, struct Curl_easy *); + if(!dep || GOOD_EASY_HANDLE(dep)) { + if(data->set.stream_depends_on) { + Curl_http2_remove_child(data->set.stream_depends_on, data); + } + Curl_http2_add_child(dep, data, (option == CURLOPT_STREAM_DEPENDS_E)); + } + break; +#endif + } + case CURLOPT_CONNECT_TO: + data->set.connect_to = va_arg(param, struct curl_slist *); + break; + case CURLOPT_SUPPRESS_CONNECT_HEADERS: + data->set.suppress_connect_headers = (0 != va_arg(param, long))?TRUE:FALSE; + break; + case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS: + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.happy_eyeballs_timeout = arg; + break; +#ifndef CURL_DISABLE_SHUFFLE_DNS + case CURLOPT_DNS_SHUFFLE_ADDRESSES: + data->set.dns_shuffle_addresses = (0 != va_arg(param, long)) ? TRUE:FALSE; + break; +#endif + case CURLOPT_DISALLOW_USERNAME_IN_URL: + data->set.disallow_username_in_url = + (0 != va_arg(param, long)) ? TRUE : FALSE; + break; +#ifndef CURL_DISABLE_DOH + case CURLOPT_DOH_URL: + result = Curl_setstropt(&data->set.str[STRING_DOH], + va_arg(param, char *)); + data->set.doh = data->set.str[STRING_DOH]?TRUE:FALSE; + break; +#endif + case CURLOPT_UPKEEP_INTERVAL_MS: + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.upkeep_interval_ms = arg; + break; + case CURLOPT_MAXAGE_CONN: + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.maxage_conn = arg; + break; + case CURLOPT_TRAILERFUNCTION: +#ifndef CURL_DISABLE_HTTP + data->set.trailer_callback = va_arg(param, curl_trailer_callback); +#endif + break; + case CURLOPT_TRAILERDATA: +#ifndef CURL_DISABLE_HTTP + data->set.trailer_data = va_arg(param, void *); +#endif + break; +#ifdef USE_ALTSVC + case CURLOPT_ALTSVC: + if(!data->asi) { + data->asi = Curl_altsvc_init(); + if(!data->asi) + return CURLE_OUT_OF_MEMORY; + } + argptr = va_arg(param, char *); + result = Curl_setstropt(&data->set.str[STRING_ALTSVC], argptr); + if(result) + return result; + (void)Curl_altsvc_load(data->asi, argptr); + break; + case CURLOPT_ALTSVC_CTRL: + if(!data->asi) { + data->asi = Curl_altsvc_init(); + if(!data->asi) + return CURLE_OUT_OF_MEMORY; + } + arg = va_arg(param, long); + result = Curl_altsvc_ctrl(data->asi, arg); + if(result) + return result; + break; +#endif + default: + /* unknown tag and its companion, just ignore: */ + result = CURLE_UNKNOWN_OPTION; + break; + } + + return result; +} + +/* + * curl_easy_setopt() is the external interface for setting options on an + * easy handle. + * + * NOTE: This is one of few API functions that are allowed to be called from + * within a callback. + */ + +#undef curl_easy_setopt +CURLcode curl_easy_setopt(struct Curl_easy *data, CURLoption tag, ...) +{ + va_list arg; + CURLcode result; + + if(!data) + return CURLE_BAD_FUNCTION_ARGUMENT; + + va_start(arg, tag); + + result = Curl_vsetopt(data, tag, arg); + + va_end(arg); + return result; +} diff --git a/libcurl/lib/setopt.h b/libcurl/lib/setopt.h new file mode 100644 index 0000000..5e347dd --- /dev/null +++ b/libcurl/lib/setopt.h @@ -0,0 +1,28 @@ +#ifndef HEADER_CURL_SETOPT_H +#define HEADER_CURL_SETOPT_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +CURLcode Curl_setstropt(char **charp, const char *s); +CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list arg); + +#endif /* HEADER_CURL_SETOPT_H */ diff --git a/libcurl/lib/setup-os400.h b/libcurl/lib/setup-os400.h new file mode 100644 index 0000000..a3c2a7b --- /dev/null +++ b/libcurl/lib/setup-os400.h @@ -0,0 +1,223 @@ +#ifndef HEADER_CURL_SETUP_OS400_H +#define HEADER_CURL_SETUP_OS400_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + + +/* OS/400 netdb.h does not define NI_MAXHOST. */ +#define NI_MAXHOST 1025 + +/* OS/400 netdb.h does not define NI_MAXSERV. */ +#define NI_MAXSERV 32 + +/* No OS/400 header file defines u_int32_t. */ +typedef unsigned long u_int32_t; + + +/* System API wrapper prototypes & definitions to support ASCII parameters. */ + +#include +#include +#include +#include +#include + +extern int Curl_getaddrinfo_a(const char *nodename, + const char *servname, + const struct addrinfo *hints, + struct addrinfo **res); +#define getaddrinfo Curl_getaddrinfo_a + + +extern int Curl_getnameinfo_a(const struct sockaddr *sa, + curl_socklen_t salen, + char *nodename, curl_socklen_t nodenamelen, + char *servname, curl_socklen_t servnamelen, + int flags); +#define getnameinfo Curl_getnameinfo_a + + +/* GSKit wrappers. */ + +extern int Curl_gsk_environment_open(gsk_handle * my_env_handle); +#define gsk_environment_open Curl_gsk_environment_open + +extern int Curl_gsk_secure_soc_open(gsk_handle my_env_handle, + gsk_handle * my_session_handle); +#define gsk_secure_soc_open Curl_gsk_secure_soc_open + +extern int Curl_gsk_environment_close(gsk_handle * my_env_handle); +#define gsk_environment_close Curl_gsk_environment_close + +extern int Curl_gsk_secure_soc_close(gsk_handle * my_session_handle); +#define gsk_secure_soc_close Curl_gsk_secure_soc_close + +extern int Curl_gsk_environment_init(gsk_handle my_env_handle); +#define gsk_environment_init Curl_gsk_environment_init + +extern int Curl_gsk_secure_soc_init(gsk_handle my_session_handle); +#define gsk_secure_soc_init Curl_gsk_secure_soc_init + +extern int Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, + GSK_BUF_ID bufID, + const char *buffer, + int bufSize); +#define gsk_attribute_set_buffer Curl_gsk_attribute_set_buffer_a + +extern int Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, + GSK_ENUM_ID enumID, + GSK_ENUM_VALUE enumValue); +#define gsk_attribute_set_enum Curl_gsk_attribute_set_enum + +extern int Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle, + GSK_NUM_ID numID, + int numValue); +#define gsk_attribute_set_numeric_value Curl_gsk_attribute_set_numeric_value + +extern int Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle, + GSK_CALLBACK_ID callBackID, + void *callBackAreaPtr); +#define gsk_attribute_set_callback Curl_gsk_attribute_set_callback + +extern int Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, + GSK_BUF_ID bufID, + const char **buffer, + int *bufSize); +#define gsk_attribute_get_buffer Curl_gsk_attribute_get_buffer_a + +extern int Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, + GSK_ENUM_ID enumID, + GSK_ENUM_VALUE *enumValue); +#define gsk_attribute_get_enum Curl_gsk_attribute_get_enum + +extern int Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle, + GSK_NUM_ID numID, + int *numValue); +#define gsk_attribute_get_numeric_value Curl_gsk_attribute_get_numeric_value + +extern int Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle, + GSK_CERT_ID certID, + const gsk_cert_data_elem **certDataElem, + int *certDataElementCount); +#define gsk_attribute_get_cert_info Curl_gsk_attribute_get_cert_info + +extern int Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, + GSK_MISC_ID miscID); +#define gsk_secure_soc_misc Curl_gsk_secure_soc_misc + +extern int Curl_gsk_secure_soc_read(gsk_handle my_session_handle, + char *readBuffer, + int readBufSize, int *amtRead); +#define gsk_secure_soc_read Curl_gsk_secure_soc_read + +extern int Curl_gsk_secure_soc_write(gsk_handle my_session_handle, + char *writeBuffer, + int writeBufSize, int *amtWritten); +#define gsk_secure_soc_write Curl_gsk_secure_soc_write + +extern const char * Curl_gsk_strerror_a(int gsk_return_value); +#define gsk_strerror Curl_gsk_strerror_a + +extern int Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle, + int IOCompletionPort, + Qso_OverlappedIO_t * communicationsArea); +#define gsk_secure_soc_startInit Curl_gsk_secure_soc_startInit + + +/* GSSAPI wrappers. */ + +extern OM_uint32 Curl_gss_import_name_a(OM_uint32 * minor_status, + gss_buffer_t in_name, + gss_OID in_name_type, + gss_name_t * out_name); +#define gss_import_name Curl_gss_import_name_a + + +extern OM_uint32 Curl_gss_display_status_a(OM_uint32 * minor_status, + OM_uint32 status_value, + int status_type, gss_OID mech_type, + gss_msg_ctx_t * message_context, + gss_buffer_t status_string); +#define gss_display_status Curl_gss_display_status_a + + +extern OM_uint32 Curl_gss_init_sec_context_a(OM_uint32 * minor_status, + gss_cred_id_t cred_handle, + gss_ctx_id_t * context_handle, + gss_name_t target_name, + gss_OID mech_type, + gss_flags_t req_flags, + OM_uint32 time_req, + gss_channel_bindings_t + input_chan_bindings, + gss_buffer_t input_token, + gss_OID * actual_mech_type, + gss_buffer_t output_token, + gss_flags_t * ret_flags, + OM_uint32 * time_rec); +#define gss_init_sec_context Curl_gss_init_sec_context_a + + +extern OM_uint32 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status, + gss_ctx_id_t * context_handle, + gss_buffer_t output_token); +#define gss_delete_sec_context Curl_gss_delete_sec_context_a + + +/* LDAP wrappers. */ + +#define BerValue struct berval + +#define ldap_url_parse ldap_url_parse_utf8 +#define ldap_init Curl_ldap_init_a +#define ldap_simple_bind_s Curl_ldap_simple_bind_s_a +#define ldap_search_s Curl_ldap_search_s_a +#define ldap_get_values_len Curl_ldap_get_values_len_a +#define ldap_err2string Curl_ldap_err2string_a +#define ldap_get_dn Curl_ldap_get_dn_a +#define ldap_first_attribute Curl_ldap_first_attribute_a +#define ldap_next_attribute Curl_ldap_next_attribute_a + +/* Some socket functions must be wrapped to process textual addresses + like AF_UNIX. */ + +extern int Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen); +extern int Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen); +extern int Curl_os400_sendto(int sd, char *buffer, int buflen, int flags, + struct sockaddr * dstaddr, int addrlen); +extern int Curl_os400_recvfrom(int sd, char *buffer, int buflen, int flags, + struct sockaddr *fromaddr, int *addrlen); + +#define connect Curl_os400_connect +#define bind Curl_os400_bind +#define sendto Curl_os400_sendto +#define recvfrom Curl_os400_recvfrom + +#ifdef HAVE_LIBZ +#define zlibVersion Curl_os400_zlibVersion +#define inflateInit_ Curl_os400_inflateInit_ +#define inflateInit2_ Curl_os400_inflateInit2_ +#define inflate Curl_os400_inflate +#define inflateEnd Curl_os400_inflateEnd +#endif + +#endif /* HEADER_CURL_SETUP_OS400_H */ diff --git a/libcurl/lib/setup-vms.h b/libcurl/lib/setup-vms.h new file mode 100644 index 0000000..6c454ae --- /dev/null +++ b/libcurl/lib/setup-vms.h @@ -0,0 +1,443 @@ +#ifndef HEADER_CURL_SETUP_VMS_H +#define HEADER_CURL_SETUP_VMS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* */ +/* JEM, 12/30/12, VMS now generates config.h, so only define wrappers for */ +/* getenv(), getpwuid() and provide is_vms_shell() */ +/* Also need upper case symbols for system services, and */ +/* OpenSSL, and some Kerberos image */ + +#ifdef __DECC +#pragma message save +#pragma message disable dollarid +#endif + +/* Hide the stuff we are overriding */ +#define getenv decc_getenv +#ifdef __DECC +# if __INITIAL_POINTER_SIZE != 64 +# define getpwuid decc_getpwuid +# endif +#endif +#include +char *decc$getenv(const char *__name); +#include + +#include +#include + +#undef getenv +#undef getpwuid +#define getenv vms_getenv +#define getpwuid vms_getpwuid + +/* VAX needs these in upper case when compiling exact case */ +#define sys$assign SYS$ASSIGN +#define sys$dassgn SYS$DASSGN +#define sys$qiow SYS$QIOW + +#ifdef __DECC +# if __INITIAL_POINTER_SIZE +# pragma __pointer_size __save +# endif +#endif + +#if __USE_LONG_GID_T +# define decc_getpwuid DECC$__LONG_GID_GETPWUID +#else +# if __INITIAL_POINTER_SIZE +# define decc_getpwuid decc$__32_getpwuid +# else +# define decc_getpwuid decc$getpwuid +# endif +#endif + + struct passwd * decc_getpwuid(uid_t uid); + +#ifdef __DECC +# if __INITIAL_POINTER_SIZE == 32 +/* Translate the path, but only if the path is a VMS file specification */ +/* The translation is usually only needed for older versions of VMS */ +static char *vms_translate_path(const char *path) +{ + char *unix_path; + char *test_str; + + /* See if the result is in VMS format, if not, we are done */ + /* Assume that this is a PATH, not just some data */ + test_str = strpbrk(path, ":[<^"); + if(test_str == NULL) { + return (char *)path; + } + + unix_path = decc$translate_vms(path); + + if((int)unix_path <= 0) { + /* We can not translate it, so return the original string */ + return (char *)path; + } +} +# else + /* VMS translate path is actually not needed on the current 64 bit */ + /* VMS platforms, so instead of figuring out the pointer settings */ + /* Change it to a noop */ +# define vms_translate_path(__path) __path +# endif +#endif + +#ifdef __DECC +# if __INITIAL_POINTER_SIZE +# pragma __pointer_size __restore +# endif +#endif + +static char *vms_getenv(const char *envvar) +{ + char *result; + char *vms_path; + + /* first use the DECC getenv() function */ + result = decc$getenv(envvar); + if(result == NULL) { + return result; + } + + vms_path = result; + result = vms_translate_path(vms_path); + + /* note that if you backport this to use VAX C RTL, that the VAX C RTL */ + /* may do a malloc(2048) for each call to getenv(), so you will need */ + /* to add a free(vms_path) */ + /* Do not do a free() for DEC C RTL builds, which should be used for */ + /* VMS 5.5-2 and later, even if using GCC */ + + return result; +} + + +static struct passwd vms_passwd_cache; + +static struct passwd * vms_getpwuid(uid_t uid) +{ + struct passwd * my_passwd; + +/* Hack needed to support 64 bit builds, decc_getpwnam is 32 bit only */ +#ifdef __DECC +# if __INITIAL_POINTER_SIZE + __char_ptr32 unix_path; +# else + char *unix_path; +# endif +#else + char *unix_path; +#endif + + my_passwd = decc_getpwuid(uid); + if(my_passwd == NULL) { + return my_passwd; + } + + unix_path = vms_translate_path(my_passwd->pw_dir); + + if((long)unix_path <= 0) { + /* We can not translate it, so return the original string */ + return my_passwd; + } + + /* If no changes needed just return it */ + if(unix_path == my_passwd->pw_dir) { + return my_passwd; + } + + /* Need to copy the structure returned */ + /* Since curl is only using pw_dir, no need to fix up */ + /* the pw_shell when running under Bash */ + vms_passwd_cache.pw_name = my_passwd->pw_name; + vms_passwd_cache.pw_uid = my_passwd->pw_uid; + vms_passwd_cache.pw_gid = my_passwd->pw_uid; + vms_passwd_cache.pw_dir = unix_path; + vms_passwd_cache.pw_shell = my_passwd->pw_shell; + + return &vms_passwd_cache; +} + +#ifdef __DECC +#pragma message restore +#endif + +/* Bug - VMS OpenSSL and Kerberos universal symbols are in uppercase only */ +/* VMS libraries should have universal symbols in exact and uppercase */ + +#define ASN1_INTEGER_get ASN1_INTEGER_GET +#define ASN1_STRING_data ASN1_STRING_DATA +#define ASN1_STRING_length ASN1_STRING_LENGTH +#define ASN1_STRING_print ASN1_STRING_PRINT +#define ASN1_STRING_to_UTF8 ASN1_STRING_TO_UTF8 +#define ASN1_STRING_type ASN1_STRING_TYPE +#define BIO_ctrl BIO_CTRL +#define BIO_free BIO_FREE +#define BIO_new BIO_NEW +#define BIO_s_mem BIO_S_MEM +#define BN_bn2bin BN_BN2BIN +#define BN_num_bits BN_NUM_BITS +#define CRYPTO_cleanup_all_ex_data CRYPTO_CLEANUP_ALL_EX_DATA +#define CRYPTO_free CRYPTO_FREE +#define CRYPTO_malloc CRYPTO_MALLOC +#define CONF_modules_load_file CONF_MODULES_LOAD_FILE +#ifdef __VAX +# ifdef VMS_OLD_SSL + /* Ancient OpenSSL on VAX/VMS missing this constant */ +# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 +# undef CONF_modules_load_file + static int CONF_modules_load_file(const char *filename, + const char *appname, + unsigned long flags) { + return 1; + } +# endif +#endif +#define DES_ecb_encrypt DES_ECB_ENCRYPT +#define DES_set_key DES_SET_KEY +#define DES_set_odd_parity DES_SET_ODD_PARITY +#define ENGINE_ctrl ENGINE_CTRL +#define ENGINE_ctrl_cmd ENGINE_CTRL_CMD +#define ENGINE_finish ENGINE_FINISH +#define ENGINE_free ENGINE_FREE +#define ENGINE_get_first ENGINE_GET_FIRST +#define ENGINE_get_id ENGINE_GET_ID +#define ENGINE_get_next ENGINE_GET_NEXT +#define ENGINE_init ENGINE_INIT +#define ENGINE_load_builtin_engines ENGINE_LOAD_BUILTIN_ENGINES +#define ENGINE_load_private_key ENGINE_LOAD_PRIVATE_KEY +#define ENGINE_set_default ENGINE_SET_DEFAULT +#define ERR_clear_error ERR_CLEAR_ERROR +#define ERR_error_string ERR_ERROR_STRING +#define ERR_error_string_n ERR_ERROR_STRING_N +#define ERR_free_strings ERR_FREE_STRINGS +#define ERR_get_error ERR_GET_ERROR +#define ERR_peek_error ERR_PEEK_ERROR +#define ERR_remove_state ERR_REMOVE_STATE +#define EVP_PKEY_copy_parameters EVP_PKEY_COPY_PARAMETERS +#define EVP_PKEY_free EVP_PKEY_FREE +#define EVP_cleanup EVP_CLEANUP +#define GENERAL_NAMES_free GENERAL_NAMES_FREE +#define i2d_X509_PUBKEY I2D_X509_PUBKEY +#define MD4_Final MD4_FINAL +#define MD4_Init MD4_INIT +#define MD4_Update MD4_UPDATE +#define MD5_Final MD5_FINAL +#define MD5_Init MD5_INIT +#define MD5_Update MD5_UPDATE +#define OPENSSL_add_all_algo_noconf OPENSSL_ADD_ALL_ALGO_NOCONF +#ifndef __VAX +#define OPENSSL_load_builtin_modules OPENSSL_LOAD_BUILTIN_MODULES +#endif +#define PEM_read_X509 PEM_READ_X509 +#define PEM_write_bio_X509 PEM_WRITE_BIO_X509 +#define PKCS12_PBE_add PKCS12_PBE_ADD +#define PKCS12_free PKCS12_FREE +#define PKCS12_parse PKCS12_PARSE +#define RAND_add RAND_ADD +#define RAND_bytes RAND_BYTES +#define RAND_egd RAND_EGD +#define RAND_file_name RAND_FILE_NAME +#define RAND_load_file RAND_LOAD_FILE +#define RAND_status RAND_STATUS +#define SSL_CIPHER_get_name SSL_CIPHER_GET_NAME +#define SSL_CTX_add_client_CA SSL_CTX_ADD_CLIENT_CA +#define SSL_CTX_callback_ctrl SSL_CTX_CALLBACK_CTRL +#define SSL_CTX_check_private_key SSL_CTX_CHECK_PRIVATE_KEY +#define SSL_CTX_ctrl SSL_CTX_CTRL +#define SSL_CTX_free SSL_CTX_FREE +#define SSL_CTX_get_cert_store SSL_CTX_GET_CERT_STORE +#define SSL_CTX_load_verify_locations SSL_CTX_LOAD_VERIFY_LOCATIONS +#define SSL_CTX_new SSL_CTX_NEW +#define SSL_CTX_set_cipher_list SSL_CTX_SET_CIPHER_LIST +#define SSL_CTX_set_def_passwd_cb_ud SSL_CTX_SET_DEF_PASSWD_CB_UD +#define SSL_CTX_set_default_passwd_cb SSL_CTX_SET_DEFAULT_PASSWD_CB +#define SSL_CTX_set_msg_callback SSL_CTX_SET_MSG_CALLBACK +#define SSL_CTX_set_verify SSL_CTX_SET_VERIFY +#define SSL_CTX_use_PrivateKey SSL_CTX_USE_PRIVATEKEY +#define SSL_CTX_use_PrivateKey_file SSL_CTX_USE_PRIVATEKEY_FILE +#define SSL_CTX_use_cert_chain_file SSL_CTX_USE_CERT_CHAIN_FILE +#define SSL_CTX_use_certificate SSL_CTX_USE_CERTIFICATE +#define SSL_CTX_use_certificate_file SSL_CTX_USE_CERTIFICATE_FILE +#define SSL_SESSION_free SSL_SESSION_FREE +#define SSL_connect SSL_CONNECT +#define SSL_free SSL_FREE +#define SSL_get1_session SSL_GET1_SESSION +#define SSL_get_certificate SSL_GET_CERTIFICATE +#define SSL_get_current_cipher SSL_GET_CURRENT_CIPHER +#define SSL_get_error SSL_GET_ERROR +#define SSL_get_peer_cert_chain SSL_GET_PEER_CERT_CHAIN +#define SSL_get_peer_certificate SSL_GET_PEER_CERTIFICATE +#define SSL_get_privatekey SSL_GET_PRIVATEKEY +#define SSL_get_session SSL_GET_SESSION +#define SSL_get_shutdown SSL_GET_SHUTDOWN +#define SSL_get_verify_result SSL_GET_VERIFY_RESULT +#define SSL_library_init SSL_LIBRARY_INIT +#define SSL_load_error_strings SSL_LOAD_ERROR_STRINGS +#define SSL_new SSL_NEW +#define SSL_peek SSL_PEEK +#define SSL_pending SSL_PENDING +#define SSL_read SSL_READ +#define SSL_set_connect_state SSL_SET_CONNECT_STATE +#define SSL_set_fd SSL_SET_FD +#define SSL_set_session SSL_SET_SESSION +#define SSL_shutdown SSL_SHUTDOWN +#define SSL_version SSL_VERSION +#define SSL_write SSL_WRITE +#define SSLeay SSLEAY +#define SSLv23_client_method SSLV23_CLIENT_METHOD +#define SSLv3_client_method SSLV3_CLIENT_METHOD +#define TLSv1_client_method TLSV1_CLIENT_METHOD +#define UI_create_method UI_CREATE_METHOD +#define UI_destroy_method UI_DESTROY_METHOD +#define UI_get0_user_data UI_GET0_USER_DATA +#define UI_get_input_flags UI_GET_INPUT_FLAGS +#define UI_get_string_type UI_GET_STRING_TYPE +#define UI_create_method UI_CREATE_METHOD +#define UI_destroy_method UI_DESTROY_METHOD +#define UI_method_get_closer UI_METHOD_GET_CLOSER +#define UI_method_get_opener UI_METHOD_GET_OPENER +#define UI_method_get_reader UI_METHOD_GET_READER +#define UI_method_get_writer UI_METHOD_GET_WRITER +#define UI_method_set_closer UI_METHOD_SET_CLOSER +#define UI_method_set_opener UI_METHOD_SET_OPENER +#define UI_method_set_reader UI_METHOD_SET_READER +#define UI_method_set_writer UI_METHOD_SET_WRITER +#define UI_OpenSSL UI_OPENSSL +#define UI_set_result UI_SET_RESULT +#define X509V3_EXT_print X509V3_EXT_PRINT +#define X509_EXTENSION_get_critical X509_EXTENSION_GET_CRITICAL +#define X509_EXTENSION_get_data X509_EXTENSION_GET_DATA +#define X509_EXTENSION_get_object X509_EXTENSION_GET_OBJECT +#define X509_LOOKUP_file X509_LOOKUP_FILE +#define X509_NAME_ENTRY_get_data X509_NAME_ENTRY_GET_DATA +#define X509_NAME_get_entry X509_NAME_GET_ENTRY +#define X509_NAME_get_index_by_NID X509_NAME_GET_INDEX_BY_NID +#define X509_NAME_print_ex X509_NAME_PRINT_EX +#define X509_STORE_CTX_get_current_cert X509_STORE_CTX_GET_CURRENT_CERT +#define X509_STORE_add_lookup X509_STORE_ADD_LOOKUP +#define X509_STORE_set_flags X509_STORE_SET_FLAGS +#define X509_check_issued X509_CHECK_ISSUED +#define X509_free X509_FREE +#define X509_get_ext_d2i X509_GET_EXT_D2I +#define X509_get_issuer_name X509_GET_ISSUER_NAME +#define X509_get_pubkey X509_GET_PUBKEY +#define X509_get_serialNumber X509_GET_SERIALNUMBER +#define X509_get_subject_name X509_GET_SUBJECT_NAME +#define X509_load_crl_file X509_LOAD_CRL_FILE +#define X509_verify_cert_error_string X509_VERIFY_CERT_ERROR_STRING +#define d2i_PKCS12_fp D2I_PKCS12_FP +#define i2t_ASN1_OBJECT I2T_ASN1_OBJECT +#define sk_num SK_NUM +#define sk_pop SK_POP +#define sk_pop_free SK_POP_FREE +#define sk_value SK_VALUE +#ifdef __VAX +#define OPENSSL_NO_SHA256 +#endif +#define SHA256_Final SHA256_FINAL +#define SHA256_Init SHA256_INIT +#define SHA256_Update SHA256_UPDATE + +#define USE_UPPERCASE_GSSAPI 1 +#define gss_seal GSS_SEAL +#define gss_unseal GSS_UNSEAL + +#define USE_UPPERCASE_KRBAPI 1 + +/* AI_NUMERICHOST needed for IP V6 support in Curl */ +#ifdef HAVE_NETDB_H +#include +#ifndef AI_NUMERICHOST +#ifdef ENABLE_IPV6 +#undef ENABLE_IPV6 +#endif +#endif +#endif + +/* VAX symbols are always in uppercase */ +#ifdef __VAX +#define inflate INFLATE +#define inflateEnd INFLATEEND +#define inflateInit2_ INFLATEINIT2_ +#define inflateInit_ INFLATEINIT_ +#define zlibVersion ZLIBVERSION +#endif + +/* Older VAX OpenSSL port defines these as Macros */ +/* Need to include the headers first and then redefine */ +/* that way a newer port will also work if some one has one */ +#ifdef __VAX + +# if (OPENSSL_VERSION_NUMBER < 0x00907001L) +# define des_set_odd_parity DES_SET_ODD_PARITY +# define des_set_key DES_SET_KEY +# define des_ecb_encrypt DES_ECB_ENCRYPT + +# endif +# include +# ifndef OpenSSL_add_all_algorithms +# define OpenSSL_add_all_algorithms OPENSSL_ADD_ALL_ALGORITHMS + void OPENSSL_ADD_ALL_ALGORITHMS(void); +# endif + + /* Curl defines these to lower case and VAX needs them in upper case */ + /* So we need static routines */ +# if (OPENSSL_VERSION_NUMBER < 0x00907001L) + +# undef des_set_odd_parity +# undef DES_set_odd_parity +# undef des_set_key +# undef DES_set_key +# undef des_ecb_encrypt +# undef DES_ecb_encrypt + + static void des_set_odd_parity(des_cblock *key) { + DES_SET_ODD_PARITY(key); + } + + static int des_set_key(const_des_cblock *key, + des_key_schedule schedule) { + return DES_SET_KEY(key, schedule); + } + + static void des_ecb_encrypt(const_des_cblock *input, + des_cblock *output, + des_key_schedule ks, int enc) { + DES_ECB_ENCRYPT(input, output, ks, enc); + } +#endif +/* Need this to stop a macro redefinition error */ +#if OPENSSL_VERSION_NUMBER < 0x00907000L +# ifdef X509_STORE_set_flags +# undef X509_STORE_set_flags +# define X509_STORE_set_flags(x,y) Curl_nop_stmt +# endif +#endif +#endif + +#endif /* HEADER_CURL_SETUP_VMS_H */ diff --git a/libcurl/lib/sha256.c b/libcurl/lib/sha256.c new file mode 100644 index 0000000..f9287af --- /dev/null +++ b/libcurl/lib/sha256.c @@ -0,0 +1,267 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Florin Petriuc, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_CRYPTO_AUTH + +#include "warnless.h" +#include "curl_sha256.h" + +#if defined(USE_OPENSSL) + +#include + +#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) +#define USE_OPENSSL_SHA256 +#endif + +#endif + +#ifdef USE_OPENSSL_SHA256 +/* When OpenSSL is available we use the SHA256-function from OpenSSL */ +#include +#else + +/* When no other crypto library is available we use this code segment */ + +/* ===== start - public domain SHA256 implementation ===== */ +/* This is based on SHA256 implementation in LibTomCrypt that was released into + * public domain by Tom St Denis. */ + +#define WPA_GET_BE32(a) ((((unsigned long)(a)[0]) << 24) | \ + (((unsigned long)(a)[1]) << 16) | \ + (((unsigned long)(a)[2]) << 8) | \ + ((unsigned long)(a)[3])) +#define WPA_PUT_BE32(a, val) \ +do { \ + (a)[0] = (unsigned char)((((unsigned long) (val)) >> 24) & 0xff); \ + (a)[1] = (unsigned char)((((unsigned long) (val)) >> 16) & 0xff); \ + (a)[2] = (unsigned char)((((unsigned long) (val)) >> 8) & 0xff); \ + (a)[3] = (unsigned char)(((unsigned long) (val)) & 0xff); \ +} while(0) + +#ifdef HAVE_LONGLONG +#define WPA_PUT_BE64(a, val) \ +do { \ + (a)[0] = (unsigned char)(((unsigned long long)(val)) >> 56); \ + (a)[1] = (unsigned char)(((unsigned long long)(val)) >> 48); \ + (a)[2] = (unsigned char)(((unsigned long long)(val)) >> 40); \ + (a)[3] = (unsigned char)(((unsigned long long)(val)) >> 32); \ + (a)[4] = (unsigned char)(((unsigned long long)(val)) >> 24); \ + (a)[5] = (unsigned char)(((unsigned long long)(val)) >> 16); \ + (a)[6] = (unsigned char)(((unsigned long long)(val)) >> 8); \ + (a)[7] = (unsigned char)(((unsigned long long)(val)) & 0xff); \ +} while(0) +#else +#define WPA_PUT_BE64(a, val) \ +do { \ + (a)[0] = (unsigned char)(((unsigned __int64)(val)) >> 56); \ + (a)[1] = (unsigned char)(((unsigned __int64)(val)) >> 48); \ + (a)[2] = (unsigned char)(((unsigned __int64)(val)) >> 40); \ + (a)[3] = (unsigned char)(((unsigned __int64)(val)) >> 32); \ + (a)[4] = (unsigned char)(((unsigned __int64)(val)) >> 24); \ + (a)[5] = (unsigned char)(((unsigned __int64)(val)) >> 16); \ + (a)[6] = (unsigned char)(((unsigned __int64)(val)) >> 8); \ + (a)[7] = (unsigned char)(((unsigned __int64)(val)) & 0xff); \ +} while(0) +#endif + +typedef struct sha256_state { +#ifdef HAVE_LONGLONG + unsigned long long length; +#else + unsigned __int64 length; +#endif + unsigned long state[8], curlen; + unsigned char buf[64]; +} SHA256_CTX; +/* the K array */ +static const unsigned long K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; +/* Various logical functions */ +#define RORc(x, y) \ +(((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \ + ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL) +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x), (n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) +/* compress 512-bits */ +static int sha256_compress(struct sha256_state *md, + unsigned char *buf) +{ + unsigned long S[8], W[64]; + int i; + /* copy state into S */ + for(i = 0; i < 8; i++) { + S[i] = md->state[i]; + } + /* copy the state into 512-bits into W[0..15] */ + for(i = 0; i < 16; i++) + W[i] = WPA_GET_BE32(buf + (4 * i)); + /* fill W[16..63] */ + for(i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + + W[i - 16]; + } + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i) \ + unsigned long t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + unsigned long t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + for(i = 0; i < 64; ++i) { + unsigned long t; + RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } + /* feedback */ + for(i = 0; i < 8; i++) { + md->state[i] = md->state[i] + S[i]; + } + return 0; +} +/* Initialize the hash state */ +static void SHA256_Init(struct sha256_state *md) +{ + md->curlen = 0; + md->length = 0; + md->state[0] = 0x6A09E667UL; + md->state[1] = 0xBB67AE85UL; + md->state[2] = 0x3C6EF372UL; + md->state[3] = 0xA54FF53AUL; + md->state[4] = 0x510E527FUL; + md->state[5] = 0x9B05688CUL; + md->state[6] = 0x1F83D9ABUL; + md->state[7] = 0x5BE0CD19UL; +} +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +static int SHA256_Update(struct sha256_state *md, + const unsigned char *in, + unsigned long inlen) +{ + unsigned long n; +#define block_size 64 + if(md->curlen > sizeof(md->buf)) + return -1; + while(inlen > 0) { + if(md->curlen == 0 && inlen >= block_size) { + if(sha256_compress(md, (unsigned char *)in) < 0) + return -1; + md->length += block_size * 8; + in += block_size; + inlen -= block_size; + } + else { + n = CURLMIN(inlen, (block_size - md->curlen)); + memcpy(md->buf + md->curlen, in, n); + md->curlen += n; + in += n; + inlen -= n; + if(md->curlen == block_size) { + if(sha256_compress(md, md->buf) < 0) + return -1; + md->length += 8 * block_size; + md->curlen = 0; + } + } + } + return 0; +} +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful +*/ +static int SHA256_Final(unsigned char *out, + struct sha256_state *md) +{ + int i; + if(md->curlen >= sizeof(md->buf)) + return -1; + /* increase the length of the message */ + md->length += md->curlen * 8; + /* append the '1' bit */ + md->buf[md->curlen++] = (unsigned char)0x80; + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if(md->curlen > 56) { + while(md->curlen < 64) { + md->buf[md->curlen++] = (unsigned char)0; + } + sha256_compress(md, md->buf); + md->curlen = 0; + } + /* pad up to 56 bytes of zeroes */ + while(md->curlen < 56) { + md->buf[md->curlen++] = (unsigned char)0; + } + /* store length */ + WPA_PUT_BE64(md->buf + 56, md->length); + sha256_compress(md, md->buf); + /* copy output */ + for(i = 0; i < 8; i++) + WPA_PUT_BE32(out + (4 * i), md->state[i]); + return 0; +} +/* ===== end - public domain SHA256 implementation ===== */ + +#endif + +void Curl_sha256it(unsigned char *outbuffer, /* 32 unsigned chars */ + const unsigned char *input) +{ + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, input, curlx_uztoui(strlen((char *)input))); + SHA256_Final(outbuffer, &ctx); +} + +#endif /* CURL_DISABLE_CRYPTO_AUTH */ diff --git a/libcurl/lib/share.c b/libcurl/lib/share.c new file mode 100644 index 0000000..3d51086 --- /dev/null +++ b/libcurl/lib/share.c @@ -0,0 +1,257 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include +#include "urldata.h" +#include "share.h" +#include "psl.h" +#include "vtls/vtls.h" +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +struct Curl_share * +curl_share_init(void) +{ + struct Curl_share *share = calloc(1, sizeof(struct Curl_share)); + if(share) { + share->specifier |= (1<hostcache)) { + free(share); + return NULL; + } + } + + return share; +} + +#undef curl_share_setopt +CURLSHcode +curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...) +{ + va_list param; + int type; + curl_lock_function lockfunc; + curl_unlock_function unlockfunc; + void *ptr; + CURLSHcode res = CURLSHE_OK; + + if(share->dirty) + /* don't allow setting options while one or more handles are already + using this share */ + return CURLSHE_IN_USE; + + va_start(param, option); + + switch(option) { + case CURLSHOPT_SHARE: + /* this is a type this share will share */ + type = va_arg(param, int); + share->specifier |= (1<cookies) { + share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE); + if(!share->cookies) + res = CURLSHE_NOMEM; + } +#else /* CURL_DISABLE_HTTP */ + res = CURLSHE_NOT_BUILT_IN; +#endif + break; + + case CURL_LOCK_DATA_SSL_SESSION: +#ifdef USE_SSL + if(!share->sslsession) { + share->max_ssl_sessions = 8; + share->sslsession = calloc(share->max_ssl_sessions, + sizeof(struct curl_ssl_session)); + share->sessionage = 0; + if(!share->sslsession) + res = CURLSHE_NOMEM; + } +#else + res = CURLSHE_NOT_BUILT_IN; +#endif + break; + + case CURL_LOCK_DATA_CONNECT: /* not supported (yet) */ + if(Curl_conncache_init(&share->conn_cache, 103)) + res = CURLSHE_NOMEM; + break; + + case CURL_LOCK_DATA_PSL: +#ifndef USE_LIBPSL + res = CURLSHE_NOT_BUILT_IN; +#endif + break; + + default: + res = CURLSHE_BAD_OPTION; + } + break; + + case CURLSHOPT_UNSHARE: + /* this is a type this share will no longer share */ + type = va_arg(param, int); + share->specifier &= ~(1<cookies) { + Curl_cookie_cleanup(share->cookies); + share->cookies = NULL; + } +#else /* CURL_DISABLE_HTTP */ + res = CURLSHE_NOT_BUILT_IN; +#endif + break; + + case CURL_LOCK_DATA_SSL_SESSION: +#ifdef USE_SSL + Curl_safefree(share->sslsession); +#else + res = CURLSHE_NOT_BUILT_IN; +#endif + break; + + case CURL_LOCK_DATA_CONNECT: + break; + + default: + res = CURLSHE_BAD_OPTION; + break; + } + break; + + case CURLSHOPT_LOCKFUNC: + lockfunc = va_arg(param, curl_lock_function); + share->lockfunc = lockfunc; + break; + + case CURLSHOPT_UNLOCKFUNC: + unlockfunc = va_arg(param, curl_unlock_function); + share->unlockfunc = unlockfunc; + break; + + case CURLSHOPT_USERDATA: + ptr = va_arg(param, void *); + share->clientdata = ptr; + break; + + default: + res = CURLSHE_BAD_OPTION; + break; + } + + va_end(param); + + return res; +} + +CURLSHcode +curl_share_cleanup(struct Curl_share *share) +{ + if(share == NULL) + return CURLSHE_INVALID; + + if(share->lockfunc) + share->lockfunc(NULL, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE, + share->clientdata); + + if(share->dirty) { + if(share->unlockfunc) + share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata); + return CURLSHE_IN_USE; + } + + Curl_conncache_close_all_connections(&share->conn_cache); + Curl_conncache_destroy(&share->conn_cache); + Curl_hash_destroy(&share->hostcache); + +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) + Curl_cookie_cleanup(share->cookies); +#endif + +#ifdef USE_SSL + if(share->sslsession) { + size_t i; + for(i = 0; i < share->max_ssl_sessions; i++) + Curl_ssl_kill_session(&(share->sslsession[i])); + free(share->sslsession); + } +#endif + + Curl_psl_destroy(&share->psl); + + if(share->unlockfunc) + share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata); + free(share); + + return CURLSHE_OK; +} + + +CURLSHcode +Curl_share_lock(struct Curl_easy *data, curl_lock_data type, + curl_lock_access accesstype) +{ + struct Curl_share *share = data->share; + + if(share == NULL) + return CURLSHE_INVALID; + + if(share->specifier & (1<lockfunc) /* only call this if set! */ + share->lockfunc(data, type, accesstype, share->clientdata); + } + /* else if we don't share this, pretend successful lock */ + + return CURLSHE_OK; +} + +CURLSHcode +Curl_share_unlock(struct Curl_easy *data, curl_lock_data type) +{ + struct Curl_share *share = data->share; + + if(share == NULL) + return CURLSHE_INVALID; + + if(share->specifier & (1<unlockfunc) /* only call this if set! */ + share->unlockfunc (data, type, share->clientdata); + } + + return CURLSHE_OK; +} diff --git a/libcurl/lib/share.h b/libcurl/lib/share.h new file mode 100644 index 0000000..a7dea41 --- /dev/null +++ b/libcurl/lib/share.h @@ -0,0 +1,66 @@ +#ifndef HEADER_CURL_SHARE_H +#define HEADER_CURL_SHARE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include +#include "cookie.h" +#include "psl.h" +#include "urldata.h" +#include "conncache.h" + +/* SalfordC says "A structure member may not be volatile". Hence: + */ +#ifdef __SALFORDC__ +#define CURL_VOLATILE +#else +#define CURL_VOLATILE volatile +#endif + +/* this struct is libcurl-private, don't export details */ +struct Curl_share { + unsigned int specifier; + CURL_VOLATILE unsigned int dirty; + + curl_lock_function lockfunc; + curl_unlock_function unlockfunc; + void *clientdata; + struct conncache conn_cache; + struct curl_hash hostcache; +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) + struct CookieInfo *cookies; +#endif +#ifdef USE_LIBPSL + struct PslCache psl; +#endif + + struct curl_ssl_session *sslsession; + size_t max_ssl_sessions; + long sessionage; +}; + +CURLSHcode Curl_share_lock(struct Curl_easy *, curl_lock_data, + curl_lock_access); +CURLSHcode Curl_share_unlock(struct Curl_easy *, curl_lock_data); + +#endif /* HEADER_CURL_SHARE_H */ diff --git a/libcurl/lib/sigpipe.h b/libcurl/lib/sigpipe.h new file mode 100644 index 0000000..3960a13 --- /dev/null +++ b/libcurl/lib/sigpipe.h @@ -0,0 +1,79 @@ +#ifndef HEADER_CURL_SIGPIPE_H +#define HEADER_CURL_SIGPIPE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && \ + (defined(USE_OPENSSL) || defined(USE_MBEDTLS)) +#include + +struct sigpipe_ignore { + struct sigaction old_pipe_act; + bool no_signal; +}; + +#define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x + +/* + * sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl + * internals, and then sigpipe_restore() will restore the situation when we + * return from libcurl again. + */ +static void sigpipe_ignore(struct Curl_easy *data, + struct sigpipe_ignore *ig) +{ + /* get a local copy of no_signal because the Curl_easy might not be + around when we restore */ + ig->no_signal = data->set.no_signal; + if(!data->set.no_signal) { + struct sigaction action; + /* first, extract the existing situation */ + memset(&ig->old_pipe_act, 0, sizeof(struct sigaction)); + sigaction(SIGPIPE, NULL, &ig->old_pipe_act); + action = ig->old_pipe_act; + /* ignore this signal */ + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); + } +} + +/* + * sigpipe_restore() puts back the outside world's opinion of signal handler + * and SIGPIPE handling. It MUST only be called after a corresponding + * sigpipe_ignore() was used. + */ +static void sigpipe_restore(struct sigpipe_ignore *ig) +{ + if(!ig->no_signal) + /* restore the outside state */ + sigaction(SIGPIPE, &ig->old_pipe_act, NULL); +} + +#else +/* for systems without sigaction */ +#define sigpipe_ignore(x,y) Curl_nop_stmt +#define sigpipe_restore(x) Curl_nop_stmt +#define SIGPIPE_VARIABLE(x) +#endif + +#endif /* HEADER_CURL_SIGPIPE_H */ diff --git a/libcurl/lib/slist.c b/libcurl/lib/slist.c new file mode 100644 index 0000000..392b84d --- /dev/null +++ b/libcurl/lib/slist.c @@ -0,0 +1,144 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "slist.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* returns last node in linked list */ +static struct curl_slist *slist_get_last(struct curl_slist *list) +{ + struct curl_slist *item; + + /* if caller passed us a NULL, return now */ + if(!list) + return NULL; + + /* loop through to find the last item */ + item = list; + while(item->next) { + item = item->next; + } + return item; +} + +/* + * Curl_slist_append_nodup() appends a string to the linked list. Rather than + * copying the string in dynamic storage, it takes its ownership. The string + * should have been malloc()ated. Curl_slist_append_nodup always returns + * the address of the first record, so that you can use this function as an + * initialization function as well as an append function. + * If an error occurs, NULL is returned and the string argument is NOT + * released. + */ +struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list, char *data) +{ + struct curl_slist *last; + struct curl_slist *new_item; + + DEBUGASSERT(data); + + new_item = malloc(sizeof(struct curl_slist)); + if(!new_item) + return NULL; + + new_item->next = NULL; + new_item->data = data; + + /* if this is the first item, then new_item *is* the list */ + if(!list) + return new_item; + + last = slist_get_last(list); + last->next = new_item; + return list; +} + +/* + * curl_slist_append() appends a string to the linked list. It always returns + * the address of the first record, so that you can use this function as an + * initialization function as well as an append function. If you find this + * bothersome, then simply create a separate _init function and call it + * appropriately from within the program. + */ +struct curl_slist *curl_slist_append(struct curl_slist *list, + const char *data) +{ + char *dupdata = strdup(data); + + if(!dupdata) + return NULL; + + list = Curl_slist_append_nodup(list, dupdata); + if(!list) + free(dupdata); + + return list; +} + +/* + * Curl_slist_duplicate() duplicates a linked list. It always returns the + * address of the first record of the cloned list or NULL in case of an + * error (or if the input list was NULL). + */ +struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist) +{ + struct curl_slist *outlist = NULL; + struct curl_slist *tmp; + + while(inlist) { + tmp = curl_slist_append(outlist, inlist->data); + + if(!tmp) { + curl_slist_free_all(outlist); + return NULL; + } + + outlist = tmp; + inlist = inlist->next; + } + return outlist; +} + +/* be nice and clean up resources */ +void curl_slist_free_all(struct curl_slist *list) +{ + struct curl_slist *next; + struct curl_slist *item; + + if(!list) + return; + + item = list; + do { + next = item->next; + Curl_safefree(item->data); + free(item); + item = next; + } while(next); +} diff --git a/libcurl/lib/slist.h b/libcurl/lib/slist.h new file mode 100644 index 0000000..d73dbf6 --- /dev/null +++ b/libcurl/lib/slist.h @@ -0,0 +1,39 @@ +#ifndef HEADER_CURL_SLIST_H +#define HEADER_CURL_SLIST_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Curl_slist_duplicate() duplicates a linked list. It always returns the + * address of the first record of the cloned list or NULL in case of an + * error (or if the input list was NULL). + */ +struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist); + +/* + * Curl_slist_append_nodup() takes ownership of the given string and appends + * it to the list. + */ +struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list, + char *data); + +#endif /* HEADER_CURL_SLIST_H */ diff --git a/libcurl/lib/smb.c b/libcurl/lib/smb.c new file mode 100644 index 0000000..870244c --- /dev/null +++ b/libcurl/lib/smb.c @@ -0,0 +1,1004 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2014, Bill Nagel , Exacq Technologies + * Copyright (C) 2016-2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ + (CURL_SIZEOF_CURL_OFF_T > 4) + +#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO) + +#define BUILDING_CURL_SMB_C + +#ifdef HAVE_PROCESS_H +#include +#ifdef CURL_WINDOWS_APP +#define getpid GetCurrentProcessId +#elif !defined(MSDOS) +#define getpid _getpid +#endif +#endif + +#include "smb.h" +#include "urldata.h" +#include "sendf.h" +#include "multiif.h" +#include "connect.h" +#include "progress.h" +#include "transfer.h" +#include "vtls/vtls.h" +#include "curl_ntlm_core.h" +#include "escape.h" +#include "curl_endian.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* Local API functions */ +static CURLcode smb_setup_connection(struct connectdata *conn); +static CURLcode smb_connect(struct connectdata *conn, bool *done); +static CURLcode smb_connection_state(struct connectdata *conn, bool *done); +static CURLcode smb_do(struct connectdata *conn, bool *done); +static CURLcode smb_request_state(struct connectdata *conn, bool *done); +static CURLcode smb_done(struct connectdata *conn, CURLcode status, + bool premature); +static CURLcode smb_disconnect(struct connectdata *conn, bool dead); +static int smb_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); +static CURLcode smb_parse_url_path(struct connectdata *conn); + +/* + * SMB handler interface + */ +const struct Curl_handler Curl_handler_smb = { + "SMB", /* scheme */ + smb_setup_connection, /* setup_connection */ + smb_do, /* do_it */ + smb_done, /* done */ + ZERO_NULL, /* do_more */ + smb_connect, /* connect_it */ + smb_connection_state, /* connecting */ + smb_request_state, /* doing */ + smb_getsock, /* proto_getsock */ + smb_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + smb_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SMB, /* defport */ + CURLPROTO_SMB, /* protocol */ + PROTOPT_NONE /* flags */ +}; + +#ifdef USE_SSL +/* + * SMBS handler interface + */ +const struct Curl_handler Curl_handler_smbs = { + "SMBS", /* scheme */ + smb_setup_connection, /* setup_connection */ + smb_do, /* do_it */ + smb_done, /* done */ + ZERO_NULL, /* do_more */ + smb_connect, /* connect_it */ + smb_connection_state, /* connecting */ + smb_request_state, /* doing */ + smb_getsock, /* proto_getsock */ + smb_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + smb_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SMBS, /* defport */ + CURLPROTO_SMBS, /* protocol */ + PROTOPT_SSL /* flags */ +}; +#endif + +#define MAX_PAYLOAD_SIZE 0x8000 +#define MAX_MESSAGE_SIZE (MAX_PAYLOAD_SIZE + 0x1000) +#define CLIENTNAME "curl" +#define SERVICENAME "?????" + +/* Append a string to an SMB message */ +#define MSGCAT(str) \ + strcpy(p, (str)); \ + p += strlen(str); + +/* Append a null-terminated string to an SMB message */ +#define MSGCATNULL(str) \ + strcpy(p, (str)); \ + p += strlen(str) + 1; + +/* SMB is mostly little endian */ +#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \ + defined(__OS400__) +static unsigned short smb_swap16(unsigned short x) +{ + return (unsigned short) ((x << 8) | ((x >> 8) & 0xff)); +} + +static unsigned int smb_swap32(unsigned int x) +{ + return (x << 24) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) | + ((x >> 24) & 0xff); +} + +static curl_off_t smb_swap64(curl_off_t x) +{ + return ((curl_off_t) smb_swap32((unsigned int) x) << 32) | + smb_swap32((unsigned int) (x >> 32)); +} + +#else +# define smb_swap16(x) (x) +# define smb_swap32(x) (x) +# define smb_swap64(x) (x) +#endif + +/* SMB request state */ +enum smb_req_state { + SMB_REQUESTING, + SMB_TREE_CONNECT, + SMB_OPEN, + SMB_DOWNLOAD, + SMB_UPLOAD, + SMB_CLOSE, + SMB_TREE_DISCONNECT, + SMB_DONE +}; + +/* SMB request data */ +struct smb_request { + enum smb_req_state state; + char *path; + unsigned short tid; /* Even if we connect to the same tree as another */ + unsigned short fid; /* request, the tid will be different */ + CURLcode result; +}; + +static void conn_state(struct connectdata *conn, enum smb_conn_state newstate) +{ + struct smb_conn *smbc = &conn->proto.smbc; +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* For debug purposes */ + static const char * const names[] = { + "SMB_NOT_CONNECTED", + "SMB_CONNECTING", + "SMB_NEGOTIATE", + "SMB_SETUP", + "SMB_CONNECTED", + /* LAST */ + }; + + if(smbc->state != newstate) + infof(conn->data, "SMB conn %p state change from %s to %s\n", + (void *)smbc, names[smbc->state], names[newstate]); +#endif + + smbc->state = newstate; +} + +static void request_state(struct connectdata *conn, + enum smb_req_state newstate) +{ + struct smb_request *req = conn->data->req.protop; +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* For debug purposes */ + static const char * const names[] = { + "SMB_REQUESTING", + "SMB_TREE_CONNECT", + "SMB_OPEN", + "SMB_DOWNLOAD", + "SMB_UPLOAD", + "SMB_CLOSE", + "SMB_TREE_DISCONNECT", + "SMB_DONE", + /* LAST */ + }; + + if(req->state != newstate) + infof(conn->data, "SMB request %p state change from %s to %s\n", + (void *)req, names[req->state], names[newstate]); +#endif + + req->state = newstate; +} + +/* this should setup things in the connection, not in the easy + handle */ +static CURLcode smb_setup_connection(struct connectdata *conn) +{ + struct smb_request *req; + + /* Initialize the request state */ + conn->data->req.protop = req = calloc(1, sizeof(struct smb_request)); + if(!req) + return CURLE_OUT_OF_MEMORY; + + /* Parse the URL path */ + return smb_parse_url_path(conn); +} + +static CURLcode smb_connect(struct connectdata *conn, bool *done) +{ + struct smb_conn *smbc = &conn->proto.smbc; + char *slash; + + (void) done; + + /* Check we have a username and password to authenticate with */ + if(!conn->bits.user_passwd) + return CURLE_LOGIN_DENIED; + + /* Initialize the connection state */ + smbc->state = SMB_CONNECTING; + smbc->recv_buf = malloc(MAX_MESSAGE_SIZE); + if(!smbc->recv_buf) + return CURLE_OUT_OF_MEMORY; + + /* Multiple requests are allowed with this connection */ + connkeep(conn, "SMB default"); + + /* Parse the username, domain, and password */ + slash = strchr(conn->user, '/'); + if(!slash) + slash = strchr(conn->user, '\\'); + + if(slash) { + smbc->user = slash + 1; + smbc->domain = strdup(conn->user); + if(!smbc->domain) + return CURLE_OUT_OF_MEMORY; + smbc->domain[slash - conn->user] = 0; + } + else { + smbc->user = conn->user; + smbc->domain = strdup(conn->host.name); + if(!smbc->domain) + return CURLE_OUT_OF_MEMORY; + } + + return CURLE_OK; +} + +static CURLcode smb_recv_message(struct connectdata *conn, void **msg) +{ + struct smb_conn *smbc = &conn->proto.smbc; + char *buf = smbc->recv_buf; + ssize_t bytes_read; + size_t nbt_size; + size_t msg_size; + size_t len = MAX_MESSAGE_SIZE - smbc->got; + CURLcode result; + + result = Curl_read(conn, FIRSTSOCKET, buf + smbc->got, len, &bytes_read); + if(result) + return result; + + if(!bytes_read) + return CURLE_OK; + + smbc->got += bytes_read; + + /* Check for a 32-bit nbt header */ + if(smbc->got < sizeof(unsigned int)) + return CURLE_OK; + + nbt_size = Curl_read16_be((const unsigned char *) + (buf + sizeof(unsigned short))) + + sizeof(unsigned int); + if(smbc->got < nbt_size) + return CURLE_OK; + + msg_size = sizeof(struct smb_header); + if(nbt_size >= msg_size + 1) { + /* Add the word count */ + msg_size += 1 + ((unsigned char) buf[msg_size]) * sizeof(unsigned short); + if(nbt_size >= msg_size + sizeof(unsigned short)) { + /* Add the byte count */ + msg_size += sizeof(unsigned short) + + Curl_read16_le((const unsigned char *)&buf[msg_size]); + if(nbt_size < msg_size) + return CURLE_READ_ERROR; + } + } + + *msg = buf; + + return CURLE_OK; +} + +static void smb_pop_message(struct connectdata *conn) +{ + struct smb_conn *smbc = &conn->proto.smbc; + + smbc->got = 0; +} + +static void smb_format_message(struct connectdata *conn, struct smb_header *h, + unsigned char cmd, size_t len) +{ + struct smb_conn *smbc = &conn->proto.smbc; + struct smb_request *req = conn->data->req.protop; + unsigned int pid; + + memset(h, 0, sizeof(*h)); + h->nbt_length = htons((unsigned short) (sizeof(*h) - sizeof(unsigned int) + + len)); + memcpy((char *)h->magic, "\xffSMB", 4); + h->command = cmd; + h->flags = SMB_FLAGS_CANONICAL_PATHNAMES | SMB_FLAGS_CASELESS_PATHNAMES; + h->flags2 = smb_swap16(SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_KNOWS_LONG_NAME); + h->uid = smb_swap16(smbc->uid); + h->tid = smb_swap16(req->tid); + pid = getpid(); + h->pid_high = smb_swap16((unsigned short)(pid >> 16)); + h->pid = smb_swap16((unsigned short) pid); +} + +static CURLcode smb_send(struct connectdata *conn, ssize_t len, + size_t upload_size) +{ + struct smb_conn *smbc = &conn->proto.smbc; + ssize_t bytes_written; + CURLcode result; + + result = Curl_write(conn, FIRSTSOCKET, conn->data->state.ulbuf, + len, &bytes_written); + if(result) + return result; + + if(bytes_written != len) { + smbc->send_size = len; + smbc->sent = bytes_written; + } + + smbc->upload_size = upload_size; + + return CURLE_OK; +} + +static CURLcode smb_flush(struct connectdata *conn) +{ + struct smb_conn *smbc = &conn->proto.smbc; + ssize_t bytes_written; + ssize_t len = smbc->send_size - smbc->sent; + CURLcode result; + + if(!smbc->send_size) + return CURLE_OK; + + result = Curl_write(conn, FIRSTSOCKET, + conn->data->state.ulbuf + smbc->sent, + len, &bytes_written); + if(result) + return result; + + if(bytes_written != len) + smbc->sent += bytes_written; + else + smbc->send_size = 0; + + return CURLE_OK; +} + +static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd, + const void *msg, size_t msg_len) +{ + CURLcode result = Curl_get_upload_buffer(conn->data); + if(result) + return result; + smb_format_message(conn, (struct smb_header *)conn->data->state.ulbuf, + cmd, msg_len); + memcpy(conn->data->state.ulbuf + sizeof(struct smb_header), + msg, msg_len); + + return smb_send(conn, sizeof(struct smb_header) + msg_len, 0); +} + +static CURLcode smb_send_negotiate(struct connectdata *conn) +{ + const char *msg = "\x00\x0c\x00\x02NT LM 0.12"; + + return smb_send_message(conn, SMB_COM_NEGOTIATE, msg, 15); +} + +static CURLcode smb_send_setup(struct connectdata *conn) +{ + struct smb_conn *smbc = &conn->proto.smbc; + struct smb_setup msg; + char *p = msg.bytes; + unsigned char lm_hash[21]; + unsigned char lm[24]; + unsigned char nt_hash[21]; + unsigned char nt[24]; + + size_t byte_count = sizeof(lm) + sizeof(nt); + byte_count += strlen(smbc->user) + strlen(smbc->domain); + byte_count += strlen(OS) + strlen(CLIENTNAME) + 4; /* 4 null chars */ + if(byte_count > sizeof(msg.bytes)) + return CURLE_FILESIZE_EXCEEDED; + + Curl_ntlm_core_mk_lm_hash(conn->data, conn->passwd, lm_hash); + Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm); +#ifdef USE_NTRESPONSES + Curl_ntlm_core_mk_nt_hash(conn->data, conn->passwd, nt_hash); + Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt); +#else + memset(nt, 0, sizeof(nt)); +#endif + + memset(&msg, 0, sizeof(msg)); + msg.word_count = SMB_WC_SETUP_ANDX; + msg.andx.command = SMB_COM_NO_ANDX_COMMAND; + msg.max_buffer_size = smb_swap16(MAX_MESSAGE_SIZE); + msg.max_mpx_count = smb_swap16(1); + msg.vc_number = smb_swap16(1); + msg.session_key = smb_swap32(smbc->session_key); + msg.capabilities = smb_swap32(SMB_CAP_LARGE_FILES); + msg.lengths[0] = smb_swap16(sizeof(lm)); + msg.lengths[1] = smb_swap16(sizeof(nt)); + memcpy(p, lm, sizeof(lm)); + p += sizeof(lm); + memcpy(p, nt, sizeof(nt)); + p += sizeof(nt); + MSGCATNULL(smbc->user); + MSGCATNULL(smbc->domain); + MSGCATNULL(OS); + MSGCATNULL(CLIENTNAME); + byte_count = p - msg.bytes; + msg.byte_count = smb_swap16((unsigned short)byte_count); + + return smb_send_message(conn, SMB_COM_SETUP_ANDX, &msg, + sizeof(msg) - sizeof(msg.bytes) + byte_count); +} + +static CURLcode smb_send_tree_connect(struct connectdata *conn) +{ + struct smb_tree_connect msg; + struct smb_conn *smbc = &conn->proto.smbc; + char *p = msg.bytes; + + size_t byte_count = strlen(conn->host.name) + strlen(smbc->share); + byte_count += strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */ + if(byte_count > sizeof(msg.bytes)) + return CURLE_FILESIZE_EXCEEDED; + + memset(&msg, 0, sizeof(msg)); + msg.word_count = SMB_WC_TREE_CONNECT_ANDX; + msg.andx.command = SMB_COM_NO_ANDX_COMMAND; + msg.pw_len = 0; + MSGCAT("\\\\"); + MSGCAT(conn->host.name); + MSGCAT("\\"); + MSGCATNULL(smbc->share); + MSGCATNULL(SERVICENAME); /* Match any type of service */ + byte_count = p - msg.bytes; + msg.byte_count = smb_swap16((unsigned short)byte_count); + + return smb_send_message(conn, SMB_COM_TREE_CONNECT_ANDX, &msg, + sizeof(msg) - sizeof(msg.bytes) + byte_count); +} + +static CURLcode smb_send_open(struct connectdata *conn) +{ + struct smb_request *req = conn->data->req.protop; + struct smb_nt_create msg; + size_t byte_count; + + if((strlen(req->path) + 1) > sizeof(msg.bytes)) + return CURLE_FILESIZE_EXCEEDED; + + memset(&msg, 0, sizeof(msg)); + msg.word_count = SMB_WC_NT_CREATE_ANDX; + msg.andx.command = SMB_COM_NO_ANDX_COMMAND; + byte_count = strlen(req->path); + msg.name_length = smb_swap16((unsigned short)byte_count); + msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL); + if(conn->data->set.upload) { + msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE); + msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF); + } + else { + msg.access = smb_swap32(SMB_GENERIC_READ); + msg.create_disposition = smb_swap32(SMB_FILE_OPEN); + } + msg.byte_count = smb_swap16((unsigned short) ++byte_count); + strcpy(msg.bytes, req->path); + + return smb_send_message(conn, SMB_COM_NT_CREATE_ANDX, &msg, + sizeof(msg) - sizeof(msg.bytes) + byte_count); +} + +static CURLcode smb_send_close(struct connectdata *conn) +{ + struct smb_request *req = conn->data->req.protop; + struct smb_close msg; + + memset(&msg, 0, sizeof(msg)); + msg.word_count = SMB_WC_CLOSE; + msg.fid = smb_swap16(req->fid); + + return smb_send_message(conn, SMB_COM_CLOSE, &msg, sizeof(msg)); +} + +static CURLcode smb_send_tree_disconnect(struct connectdata *conn) +{ + struct smb_tree_disconnect msg; + + memset(&msg, 0, sizeof(msg)); + + return smb_send_message(conn, SMB_COM_TREE_DISCONNECT, &msg, sizeof(msg)); +} + +static CURLcode smb_send_read(struct connectdata *conn) +{ + struct smb_request *req = conn->data->req.protop; + curl_off_t offset = conn->data->req.offset; + struct smb_read msg; + + memset(&msg, 0, sizeof(msg)); + msg.word_count = SMB_WC_READ_ANDX; + msg.andx.command = SMB_COM_NO_ANDX_COMMAND; + msg.fid = smb_swap16(req->fid); + msg.offset = smb_swap32((unsigned int) offset); + msg.offset_high = smb_swap32((unsigned int) (offset >> 32)); + msg.min_bytes = smb_swap16(MAX_PAYLOAD_SIZE); + msg.max_bytes = smb_swap16(MAX_PAYLOAD_SIZE); + + return smb_send_message(conn, SMB_COM_READ_ANDX, &msg, sizeof(msg)); +} + +static CURLcode smb_send_write(struct connectdata *conn) +{ + struct smb_write *msg; + struct smb_request *req = conn->data->req.protop; + curl_off_t offset = conn->data->req.offset; + curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount; + CURLcode result = Curl_get_upload_buffer(conn->data); + if(result) + return result; + msg = (struct smb_write *)conn->data->state.ulbuf; + + if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */ + upload_size = MAX_PAYLOAD_SIZE - 1; + + memset(msg, 0, sizeof(*msg)); + msg->word_count = SMB_WC_WRITE_ANDX; + msg->andx.command = SMB_COM_NO_ANDX_COMMAND; + msg->fid = smb_swap16(req->fid); + msg->offset = smb_swap32((unsigned int) offset); + msg->offset_high = smb_swap32((unsigned int) (offset >> 32)); + msg->data_length = smb_swap16((unsigned short) upload_size); + msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int)); + msg->byte_count = smb_swap16((unsigned short) (upload_size + 1)); + + smb_format_message(conn, &msg->h, SMB_COM_WRITE_ANDX, + sizeof(*msg) - sizeof(msg->h) + (size_t) upload_size); + + return smb_send(conn, sizeof(*msg), (size_t) upload_size); +} + +static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg) +{ + struct smb_conn *smbc = &conn->proto.smbc; + CURLcode result; + + /* Check if there is data in the transfer buffer */ + if(!smbc->send_size && smbc->upload_size) { + size_t nread = smbc->upload_size > conn->data->set.upload_buffer_size ? + conn->data->set.upload_buffer_size : + smbc->upload_size; + conn->data->req.upload_fromhere = conn->data->state.ulbuf; + result = Curl_fillreadbuffer(conn, nread, &nread); + if(result && result != CURLE_AGAIN) + return result; + if(!nread) + return CURLE_OK; + + smbc->upload_size -= nread; + smbc->send_size = nread; + smbc->sent = 0; + } + + /* Check if there is data to send */ + if(smbc->send_size) { + result = smb_flush(conn); + if(result) + return result; + } + + /* Check if there is still data to be sent */ + if(smbc->send_size || smbc->upload_size) + return CURLE_AGAIN; + + return smb_recv_message(conn, msg); +} + +static CURLcode smb_connection_state(struct connectdata *conn, bool *done) +{ + struct smb_conn *smbc = &conn->proto.smbc; + struct smb_negotiate_response *nrsp; + struct smb_header *h; + CURLcode result; + void *msg = NULL; + + if(smbc->state == SMB_CONNECTING) { +#ifdef USE_SSL + if((conn->handler->flags & PROTOPT_SSL)) { + bool ssl_done = FALSE; + result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &ssl_done); + if(result && result != CURLE_AGAIN) + return result; + if(!ssl_done) + return CURLE_OK; + } +#endif + + result = smb_send_negotiate(conn); + if(result) { + connclose(conn, "SMB: failed to send negotiate message"); + return result; + } + + conn_state(conn, SMB_NEGOTIATE); + } + + /* Send the previous message and check for a response */ + result = smb_send_and_recv(conn, &msg); + if(result && result != CURLE_AGAIN) { + connclose(conn, "SMB: failed to communicate"); + return result; + } + + if(!msg) + return CURLE_OK; + + h = msg; + + switch(smbc->state) { + case SMB_NEGOTIATE: + if(h->status || smbc->got < sizeof(*nrsp) + sizeof(smbc->challenge) - 1) { + connclose(conn, "SMB: negotiation failed"); + return CURLE_COULDNT_CONNECT; + } + nrsp = msg; + memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge)); + smbc->session_key = smb_swap32(nrsp->session_key); + result = smb_send_setup(conn); + if(result) { + connclose(conn, "SMB: failed to send setup message"); + return result; + } + conn_state(conn, SMB_SETUP); + break; + + case SMB_SETUP: + if(h->status) { + connclose(conn, "SMB: authentication failed"); + return CURLE_LOGIN_DENIED; + } + smbc->uid = smb_swap16(h->uid); + conn_state(conn, SMB_CONNECTED); + *done = true; + break; + + default: + smb_pop_message(conn); + return CURLE_OK; /* ignore */ + } + + smb_pop_message(conn); + + return CURLE_OK; +} + +/* + * Convert a timestamp from the Windows world (100 nsec units from 1 Jan 1601) + * to Posix time. Cap the output to fit within a time_t. + */ +static void get_posix_time(time_t *out, curl_off_t timestamp) +{ + timestamp -= 116444736000000000; + timestamp /= 10000000; +#if SIZEOF_TIME_T < SIZEOF_CURL_OFF_T + if(timestamp > TIME_T_MAX) + *out = TIME_T_MAX; + else if(timestamp < TIME_T_MIN) + *out = TIME_T_MIN; + else +#endif + *out = (time_t) timestamp; +} + +static CURLcode smb_request_state(struct connectdata *conn, bool *done) +{ + struct smb_request *req = conn->data->req.protop; + struct smb_header *h; + struct smb_conn *smbc = &conn->proto.smbc; + enum smb_req_state next_state = SMB_DONE; + unsigned short len; + unsigned short off; + CURLcode result; + void *msg = NULL; + const struct smb_nt_create_response *smb_m; + + /* Start the request */ + if(req->state == SMB_REQUESTING) { + result = smb_send_tree_connect(conn); + if(result) { + connclose(conn, "SMB: failed to send tree connect message"); + return result; + } + + request_state(conn, SMB_TREE_CONNECT); + } + + /* Send the previous message and check for a response */ + result = smb_send_and_recv(conn, &msg); + if(result && result != CURLE_AGAIN) { + connclose(conn, "SMB: failed to communicate"); + return result; + } + + if(!msg) + return CURLE_OK; + + h = msg; + + switch(req->state) { + case SMB_TREE_CONNECT: + if(h->status) { + req->result = CURLE_REMOTE_FILE_NOT_FOUND; + if(h->status == smb_swap32(SMB_ERR_NOACCESS)) + req->result = CURLE_REMOTE_ACCESS_DENIED; + break; + } + req->tid = smb_swap16(h->tid); + next_state = SMB_OPEN; + break; + + case SMB_OPEN: + if(h->status || smbc->got < sizeof(struct smb_nt_create_response)) { + req->result = CURLE_REMOTE_FILE_NOT_FOUND; + if(h->status == smb_swap32(SMB_ERR_NOACCESS)) + req->result = CURLE_REMOTE_ACCESS_DENIED; + next_state = SMB_TREE_DISCONNECT; + break; + } + smb_m = (const struct smb_nt_create_response*) msg; + req->fid = smb_swap16(smb_m->fid); + conn->data->req.offset = 0; + if(conn->data->set.upload) { + conn->data->req.size = conn->data->state.infilesize; + Curl_pgrsSetUploadSize(conn->data, conn->data->req.size); + next_state = SMB_UPLOAD; + } + else { + smb_m = (const struct smb_nt_create_response*) msg; + conn->data->req.size = smb_swap64(smb_m->end_of_file); + if(conn->data->req.size < 0) { + req->result = CURLE_WEIRD_SERVER_REPLY; + next_state = SMB_CLOSE; + } + else { + Curl_pgrsSetDownloadSize(conn->data, conn->data->req.size); + if(conn->data->set.get_filetime) + get_posix_time(&conn->data->info.filetime, smb_m->last_change_time); + next_state = SMB_DOWNLOAD; + } + } + break; + + case SMB_DOWNLOAD: + if(h->status || smbc->got < sizeof(struct smb_header) + 14) { + req->result = CURLE_RECV_ERROR; + next_state = SMB_CLOSE; + break; + } + len = Curl_read16_le(((const unsigned char *) msg) + + sizeof(struct smb_header) + 11); + off = Curl_read16_le(((const unsigned char *) msg) + + sizeof(struct smb_header) + 13); + if(len > 0) { + if(off + sizeof(unsigned int) + len > smbc->got) { + failf(conn->data, "Invalid input packet"); + result = CURLE_RECV_ERROR; + } + else + result = Curl_client_write(conn, CLIENTWRITE_BODY, + (char *)msg + off + sizeof(unsigned int), + len); + if(result) { + req->result = result; + next_state = SMB_CLOSE; + break; + } + } + conn->data->req.bytecount += len; + conn->data->req.offset += len; + Curl_pgrsSetDownloadCounter(conn->data, conn->data->req.bytecount); + next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD; + break; + + case SMB_UPLOAD: + if(h->status || smbc->got < sizeof(struct smb_header) + 6) { + req->result = CURLE_UPLOAD_FAILED; + next_state = SMB_CLOSE; + break; + } + len = Curl_read16_le(((const unsigned char *) msg) + + sizeof(struct smb_header) + 5); + conn->data->req.bytecount += len; + conn->data->req.offset += len; + Curl_pgrsSetUploadCounter(conn->data, conn->data->req.bytecount); + if(conn->data->req.bytecount >= conn->data->req.size) + next_state = SMB_CLOSE; + else + next_state = SMB_UPLOAD; + break; + + case SMB_CLOSE: + /* We don't care if the close failed, proceed to tree disconnect anyway */ + next_state = SMB_TREE_DISCONNECT; + break; + + case SMB_TREE_DISCONNECT: + next_state = SMB_DONE; + break; + + default: + smb_pop_message(conn); + return CURLE_OK; /* ignore */ + } + + smb_pop_message(conn); + + switch(next_state) { + case SMB_OPEN: + result = smb_send_open(conn); + break; + + case SMB_DOWNLOAD: + result = smb_send_read(conn); + break; + + case SMB_UPLOAD: + result = smb_send_write(conn); + break; + + case SMB_CLOSE: + result = smb_send_close(conn); + break; + + case SMB_TREE_DISCONNECT: + result = smb_send_tree_disconnect(conn); + break; + + case SMB_DONE: + result = req->result; + *done = true; + break; + + default: + break; + } + + if(result) { + connclose(conn, "SMB: failed to send message"); + return result; + } + + request_state(conn, next_state); + + return CURLE_OK; +} + +static CURLcode smb_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + (void) premature; + Curl_safefree(conn->data->req.protop); + return status; +} + +static CURLcode smb_disconnect(struct connectdata *conn, bool dead) +{ + struct smb_conn *smbc = &conn->proto.smbc; + (void) dead; + Curl_safefree(smbc->share); + Curl_safefree(smbc->domain); + Curl_safefree(smbc->recv_buf); + return CURLE_OK; +} + +static int smb_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks) +{ + if(!numsocks) + return GETSOCK_BLANK; + + socks[0] = conn->sock[FIRSTSOCKET]; + return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0); +} + +static CURLcode smb_do(struct connectdata *conn, bool *done) +{ + struct smb_conn *smbc = &conn->proto.smbc; + + *done = FALSE; + if(smbc->share) { + return CURLE_OK; + } + return CURLE_URL_MALFORMAT; +} + +static CURLcode smb_parse_url_path(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + struct smb_request *req = data->req.protop; + struct smb_conn *smbc = &conn->proto.smbc; + char *path; + char *slash; + + /* URL decode the path */ + CURLcode result = Curl_urldecode(data, data->state.up.path, 0, &path, NULL, + TRUE); + if(result) + return result; + + /* Parse the path for the share */ + smbc->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path); + free(path); + if(!smbc->share) + return CURLE_OUT_OF_MEMORY; + + slash = strchr(smbc->share, '/'); + if(!slash) + slash = strchr(smbc->share, '\\'); + + /* The share must be present */ + if(!slash) { + Curl_safefree(smbc->share); + return CURLE_URL_MALFORMAT; + } + + /* Parse the path for the file path converting any forward slashes into + backslashes */ + *slash++ = 0; + req->path = slash; + + for(; *slash; slash++) { + if(*slash == '/') + *slash = '\\'; + } + return CURLE_OK; +} + +#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */ + +#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */ diff --git a/libcurl/lib/smb.h b/libcurl/lib/smb.h new file mode 100644 index 0000000..9ce6b56 --- /dev/null +++ b/libcurl/lib/smb.h @@ -0,0 +1,259 @@ +#ifndef HEADER_CURL_SMB_H +#define HEADER_CURL_SMB_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2014, Bill Nagel , Exacq Technologies + * Copyright (C) 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +enum smb_conn_state { + SMB_NOT_CONNECTED = 0, + SMB_CONNECTING, + SMB_NEGOTIATE, + SMB_SETUP, + SMB_CONNECTED +}; + +struct smb_conn { + enum smb_conn_state state; + char *user; + char *domain; + char *share; + unsigned char challenge[8]; + unsigned int session_key; + unsigned short uid; + char *recv_buf; + size_t upload_size; + size_t send_size; + size_t sent; + size_t got; +}; + +/* + * Definitions for SMB protocol data structures + */ +#ifdef BUILDING_CURL_SMB_C + +#if defined(_MSC_VER) || defined(__ILEC400__) +# define PACK +# pragma pack(push) +# pragma pack(1) +#elif defined(__GNUC__) +# define PACK __attribute__((packed)) +#else +# define PACK +#endif + +#define SMB_COM_CLOSE 0x04 +#define SMB_COM_READ_ANDX 0x2e +#define SMB_COM_WRITE_ANDX 0x2f +#define SMB_COM_TREE_DISCONNECT 0x71 +#define SMB_COM_NEGOTIATE 0x72 +#define SMB_COM_SETUP_ANDX 0x73 +#define SMB_COM_TREE_CONNECT_ANDX 0x75 +#define SMB_COM_NT_CREATE_ANDX 0xa2 +#define SMB_COM_NO_ANDX_COMMAND 0xff + +#define SMB_WC_CLOSE 0x03 +#define SMB_WC_READ_ANDX 0x0c +#define SMB_WC_WRITE_ANDX 0x0e +#define SMB_WC_SETUP_ANDX 0x0d +#define SMB_WC_TREE_CONNECT_ANDX 0x04 +#define SMB_WC_NT_CREATE_ANDX 0x18 + +#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10 +#define SMB_FLAGS_CASELESS_PATHNAMES 0x08 +#define SMB_FLAGS2_UNICODE_STRINGS 0x8000 +#define SMB_FLAGS2_IS_LONG_NAME 0x0040 +#define SMB_FLAGS2_KNOWS_LONG_NAME 0x0001 + +#define SMB_CAP_LARGE_FILES 0x08 +#define SMB_GENERIC_WRITE 0x40000000 +#define SMB_GENERIC_READ 0x80000000 +#define SMB_FILE_SHARE_ALL 0x07 +#define SMB_FILE_OPEN 0x01 +#define SMB_FILE_OVERWRITE_IF 0x05 + +#define SMB_ERR_NOACCESS 0x00050001 + +struct smb_header { + unsigned char nbt_type; + unsigned char nbt_flags; + unsigned short nbt_length; + unsigned char magic[4]; + unsigned char command; + unsigned int status; + unsigned char flags; + unsigned short flags2; + unsigned short pid_high; + unsigned char signature[8]; + unsigned short pad; + unsigned short tid; + unsigned short pid; + unsigned short uid; + unsigned short mid; +} PACK; + +struct smb_negotiate_response { + struct smb_header h; + unsigned char word_count; + unsigned short dialect_index; + unsigned char security_mode; + unsigned short max_mpx_count; + unsigned short max_number_vcs; + unsigned int max_buffer_size; + unsigned int max_raw_size; + unsigned int session_key; + unsigned int capabilities; + unsigned int system_time_low; + unsigned int system_time_high; + unsigned short server_time_zone; + unsigned char encryption_key_length; + unsigned short byte_count; + char bytes[1]; +} PACK; + +struct andx { + unsigned char command; + unsigned char pad; + unsigned short offset; +} PACK; + +struct smb_setup { + unsigned char word_count; + struct andx andx; + unsigned short max_buffer_size; + unsigned short max_mpx_count; + unsigned short vc_number; + unsigned int session_key; + unsigned short lengths[2]; + unsigned int pad; + unsigned int capabilities; + unsigned short byte_count; + char bytes[1024]; +} PACK; + +struct smb_tree_connect { + unsigned char word_count; + struct andx andx; + unsigned short flags; + unsigned short pw_len; + unsigned short byte_count; + char bytes[1024]; +} PACK; + +struct smb_nt_create { + unsigned char word_count; + struct andx andx; + unsigned char pad; + unsigned short name_length; + unsigned int flags; + unsigned int root_fid; + unsigned int access; + curl_off_t allocation_size; + unsigned int ext_file_attributes; + unsigned int share_access; + unsigned int create_disposition; + unsigned int create_options; + unsigned int impersonation_level; + unsigned char security_flags; + unsigned short byte_count; + char bytes[1024]; +} PACK; + +struct smb_nt_create_response { + struct smb_header h; + unsigned char word_count; + struct andx andx; + unsigned char op_lock_level; + unsigned short fid; + unsigned int create_disposition; + + curl_off_t create_time; + curl_off_t last_access_time; + curl_off_t last_write_time; + curl_off_t last_change_time; + unsigned int ext_file_attributes; + curl_off_t allocation_size; + curl_off_t end_of_file; + +} PACK; + +struct smb_read { + unsigned char word_count; + struct andx andx; + unsigned short fid; + unsigned int offset; + unsigned short max_bytes; + unsigned short min_bytes; + unsigned int timeout; + unsigned short remaining; + unsigned int offset_high; + unsigned short byte_count; +} PACK; + +struct smb_write { + struct smb_header h; + unsigned char word_count; + struct andx andx; + unsigned short fid; + unsigned int offset; + unsigned int timeout; + unsigned short write_mode; + unsigned short remaining; + unsigned short pad; + unsigned short data_length; + unsigned short data_offset; + unsigned int offset_high; + unsigned short byte_count; + unsigned char pad2; +} PACK; + +struct smb_close { + unsigned char word_count; + unsigned short fid; + unsigned int last_mtime; + unsigned short byte_count; +} PACK; + +struct smb_tree_disconnect { + unsigned char word_count; + unsigned short byte_count; +} PACK; + +#if defined(_MSC_VER) || defined(__ILEC400__) +# pragma pack(pop) +#endif + +#endif /* BUILDING_CURL_SMB_C */ + +#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ + (CURL_SIZEOF_CURL_OFF_T > 4) + +#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO) + +extern const struct Curl_handler Curl_handler_smb; +extern const struct Curl_handler Curl_handler_smbs; + +#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */ + +#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */ + +#endif /* HEADER_CURL_SMB_H */ diff --git a/libcurl/lib/smtp.c b/libcurl/lib/smtp.c new file mode 100644 index 0000000..e10d0fb --- /dev/null +++ b/libcurl/lib/smtp.c @@ -0,0 +1,1639 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC1870 SMTP Service Extension for Message Size + * RFC2195 CRAM-MD5 authentication + * RFC2831 DIGEST-MD5 authentication + * RFC3207 SMTP over TLS + * RFC4422 Simple Authentication and Security Layer (SASL) + * RFC4616 PLAIN authentication + * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism + * RFC4954 SMTP Authentication + * RFC5321 SMTP protocol + * RFC6749 OAuth 2.0 Authorization Framework + * RFC8314 Use of TLS for Email Submission and Access + * Draft SMTP URL Interface + * Draft LOGIN SASL Mechanism + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_SMTP + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_UTSNAME_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +#include +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "progress.h" +#include "transfer.h" +#include "escape.h" +#include "http.h" /* for HTTP proxy tunnel stuff */ +#include "mime.h" +#include "socks.h" +#include "smtp.h" +#include "strtoofft.h" +#include "strcase.h" +#include "vtls/vtls.h" +#include "connect.h" +#include "strerror.h" +#include "select.h" +#include "multiif.h" +#include "url.h" +#include "curl_gethostname.h" +#include "curl_sasl.h" +#include "warnless.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* Local API functions */ +static CURLcode smtp_regular_transfer(struct connectdata *conn, bool *done); +static CURLcode smtp_do(struct connectdata *conn, bool *done); +static CURLcode smtp_done(struct connectdata *conn, CURLcode status, + bool premature); +static CURLcode smtp_connect(struct connectdata *conn, bool *done); +static CURLcode smtp_disconnect(struct connectdata *conn, bool dead); +static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done); +static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); +static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done); +static CURLcode smtp_setup_connection(struct connectdata *conn); +static CURLcode smtp_parse_url_options(struct connectdata *conn); +static CURLcode smtp_parse_url_path(struct connectdata *conn); +static CURLcode smtp_parse_custom_request(struct connectdata *conn); +static CURLcode smtp_perform_auth(struct connectdata *conn, const char *mech, + const char *initresp); +static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp); +static void smtp_get_message(char *buffer, char **outptr); + +/* + * SMTP protocol handler. + */ + +const struct Curl_handler Curl_handler_smtp = { + "SMTP", /* scheme */ + smtp_setup_connection, /* setup_connection */ + smtp_do, /* do_it */ + smtp_done, /* done */ + ZERO_NULL, /* do_more */ + smtp_connect, /* connect_it */ + smtp_multi_statemach, /* connecting */ + smtp_doing, /* doing */ + smtp_getsock, /* proto_getsock */ + smtp_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + smtp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SMTP, /* defport */ + CURLPROTO_SMTP, /* protocol */ + PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */ + PROTOPT_URLOPTIONS +}; + +#ifdef USE_SSL +/* + * SMTPS protocol handler. + */ + +const struct Curl_handler Curl_handler_smtps = { + "SMTPS", /* scheme */ + smtp_setup_connection, /* setup_connection */ + smtp_do, /* do_it */ + smtp_done, /* done */ + ZERO_NULL, /* do_more */ + smtp_connect, /* connect_it */ + smtp_multi_statemach, /* connecting */ + smtp_doing, /* doing */ + smtp_getsock, /* proto_getsock */ + smtp_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + smtp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SMTPS, /* defport */ + CURLPROTO_SMTPS, /* protocol */ + PROTOPT_CLOSEACTION | PROTOPT_SSL + | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */ +}; +#endif + +/* SASL parameters for the smtp protocol */ +static const struct SASLproto saslsmtp = { + "smtp", /* The service name */ + 334, /* Code received when continuation is expected */ + 235, /* Code to receive upon authentication success */ + 512 - 8, /* Maximum initial response length (no max) */ + smtp_perform_auth, /* Send authentication command */ + smtp_continue_auth, /* Send authentication continuation */ + smtp_get_message /* Get SASL response message */ +}; + +#ifdef USE_SSL +static void smtp_to_smtps(struct connectdata *conn) +{ + /* Change the connection handler */ + conn->handler = &Curl_handler_smtps; + + /* Set the connection's upgraded to TLS flag */ + conn->tls_upgraded = TRUE; +} +#else +#define smtp_to_smtps(x) Curl_nop_stmt +#endif + +/*********************************************************************** + * + * smtp_endofresp() + * + * Checks for an ending SMTP status code at the start of the given string, but + * also detects various capabilities from the EHLO response including the + * supported authentication mechanisms. + */ +static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len, + int *resp) +{ + struct smtp_conn *smtpc = &conn->proto.smtpc; + bool result = FALSE; + + /* Nothing for us */ + if(len < 4 || !ISDIGIT(line[0]) || !ISDIGIT(line[1]) || !ISDIGIT(line[2])) + return FALSE; + + /* Do we have a command response? This should be the response code followed + by a space and optionally some text as per RFC-5321 and as outlined in + Section 4. Examples of RFC-4954 but some e-mail servers ignore this and + only send the response code instead as per Section 4.2. */ + if(line[3] == ' ' || len == 5) { + char tmpline[6]; + + result = TRUE; + memset(tmpline, '\0', sizeof(tmpline)); + memcpy(tmpline, line, (len == 5 ? 5 : 3)); + *resp = curlx_sltosi(strtol(tmpline, NULL, 10)); + + /* Make sure real server never sends internal value */ + if(*resp == 1) + *resp = 0; + } + /* Do we have a multiline (continuation) response? */ + else if(line[3] == '-' && + (smtpc->state == SMTP_EHLO || smtpc->state == SMTP_COMMAND)) { + result = TRUE; + *resp = 1; /* Internal response code */ + } + + return result; +} + +/*********************************************************************** + * + * smtp_get_message() + * + * Gets the authentication message from the response buffer. + */ +static void smtp_get_message(char *buffer, char **outptr) +{ + size_t len = strlen(buffer); + char *message = NULL; + + if(len > 4) { + /* Find the start of the message */ + len -= 4; + for(message = buffer + 4; *message == ' ' || *message == '\t'; + message++, len--) + ; + + /* Find the end of the message */ + for(; len--;) + if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' && + message[len] != '\t') + break; + + /* Terminate the message */ + if(++len) { + message[len] = '\0'; + } + } + else + /* junk input => zero length output */ + message = &buffer[len]; + + *outptr = message; +} + +/*********************************************************************** + * + * state() + * + * This is the ONLY way to change SMTP state! + */ +static void state(struct connectdata *conn, smtpstate newstate) +{ + struct smtp_conn *smtpc = &conn->proto.smtpc; +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* for debug purposes */ + static const char * const names[] = { + "STOP", + "SERVERGREET", + "EHLO", + "HELO", + "STARTTLS", + "UPGRADETLS", + "AUTH", + "COMMAND", + "MAIL", + "RCPT", + "DATA", + "POSTDATA", + "QUIT", + /* LAST */ + }; + + if(smtpc->state != newstate) + infof(conn->data, "SMTP %p state change from %s to %s\n", + (void *)smtpc, names[smtpc->state], names[newstate]); +#endif + + smtpc->state = newstate; +} + +/*********************************************************************** + * + * smtp_perform_ehlo() + * + * Sends the EHLO command to not only initialise communication with the ESMTP + * server but to also obtain a list of server side supported capabilities. + */ +static CURLcode smtp_perform_ehlo(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct smtp_conn *smtpc = &conn->proto.smtpc; + + smtpc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanism yet */ + smtpc->sasl.authused = SASL_AUTH_NONE; /* Clear the authentication mechanism + used for esmtp connections */ + smtpc->tls_supported = FALSE; /* Clear the TLS capability */ + smtpc->auth_supported = FALSE; /* Clear the AUTH capability */ + + /* Send the EHLO command */ + result = Curl_pp_sendf(&smtpc->pp, "EHLO %s", smtpc->domain); + + if(!result) + state(conn, SMTP_EHLO); + + return result; +} + +/*********************************************************************** + * + * smtp_perform_helo() + * + * Sends the HELO command to initialise communication with the SMTP server. + */ +static CURLcode smtp_perform_helo(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct smtp_conn *smtpc = &conn->proto.smtpc; + + smtpc->sasl.authused = SASL_AUTH_NONE; /* No authentication mechanism used + in smtp connections */ + + /* Send the HELO command */ + result = Curl_pp_sendf(&smtpc->pp, "HELO %s", smtpc->domain); + + if(!result) + state(conn, SMTP_HELO); + + return result; +} + +/*********************************************************************** + * + * smtp_perform_starttls() + * + * Sends the STLS command to start the upgrade to TLS. + */ +static CURLcode smtp_perform_starttls(struct connectdata *conn) +{ + /* Send the STARTTLS command */ + CURLcode result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "STARTTLS"); + + if(!result) + state(conn, SMTP_STARTTLS); + + return result; +} + +/*********************************************************************** + * + * smtp_perform_upgrade_tls() + * + * Performs the upgrade to TLS. + */ +static CURLcode smtp_perform_upgrade_tls(struct connectdata *conn) +{ + /* Start the SSL connection */ + struct smtp_conn *smtpc = &conn->proto.smtpc; + CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, + &smtpc->ssldone); + + if(!result) { + if(smtpc->state != SMTP_UPGRADETLS) + state(conn, SMTP_UPGRADETLS); + + if(smtpc->ssldone) { + smtp_to_smtps(conn); + result = smtp_perform_ehlo(conn); + } + } + + return result; +} + +/*********************************************************************** + * + * smtp_perform_auth() + * + * Sends an AUTH command allowing the client to login with the given SASL + * authentication mechanism. + */ +static CURLcode smtp_perform_auth(struct connectdata *conn, + const char *mech, + const char *initresp) +{ + CURLcode result = CURLE_OK; + struct smtp_conn *smtpc = &conn->proto.smtpc; + + if(initresp) { /* AUTH ... */ + /* Send the AUTH command with the initial response */ + result = Curl_pp_sendf(&smtpc->pp, "AUTH %s %s", mech, initresp); + } + else { + /* Send the AUTH command */ + result = Curl_pp_sendf(&smtpc->pp, "AUTH %s", mech); + } + + return result; +} + +/*********************************************************************** + * + * smtp_continue_auth() + * + * Sends SASL continuation data or cancellation. + */ +static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp) +{ + struct smtp_conn *smtpc = &conn->proto.smtpc; + + return Curl_pp_sendf(&smtpc->pp, "%s", resp); +} + +/*********************************************************************** + * + * smtp_perform_authentication() + * + * Initiates the authentication sequence, with the appropriate SASL + * authentication mechanism. + */ +static CURLcode smtp_perform_authentication(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct smtp_conn *smtpc = &conn->proto.smtpc; + saslprogress progress; + + /* Check we have enough data to authenticate with, and the + server supports authentiation, and end the connect phase if not */ + if(!smtpc->auth_supported || + !Curl_sasl_can_authenticate(&smtpc->sasl, conn)) { + state(conn, SMTP_STOP); + return result; + } + + /* Calculate the SASL login details */ + result = Curl_sasl_start(&smtpc->sasl, conn, FALSE, &progress); + + if(!result) { + if(progress == SASL_INPROGRESS) + state(conn, SMTP_AUTH); + else { + /* Other mechanisms not supported */ + infof(conn->data, "No known authentication mechanisms supported!\n"); + result = CURLE_LOGIN_DENIED; + } + } + + return result; +} + +/*********************************************************************** + * + * smtp_perform_command() + * + * Sends a SMTP based command. + */ +static CURLcode smtp_perform_command(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct SMTP *smtp = data->req.protop; + + /* Send the command */ + if(smtp->rcpt) + result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s %s", + smtp->custom && smtp->custom[0] != '\0' ? + smtp->custom : "VRFY", + smtp->rcpt->data); + else + result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", + smtp->custom && smtp->custom[0] != '\0' ? + smtp->custom : "HELP"); + + if(!result) + state(conn, SMTP_COMMAND); + + return result; +} + +/*********************************************************************** + * + * smtp_perform_mail() + * + * Sends an MAIL command to initiate the upload of a message. + */ +static CURLcode smtp_perform_mail(struct connectdata *conn) +{ + char *from = NULL; + char *auth = NULL; + char *size = NULL; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + /* Calculate the FROM parameter */ + if(!data->set.str[STRING_MAIL_FROM]) + /* Null reverse-path, RFC-5321, sect. 3.6.3 */ + from = strdup("<>"); + else if(data->set.str[STRING_MAIL_FROM][0] == '<') + from = aprintf("%s", data->set.str[STRING_MAIL_FROM]); + else + from = aprintf("<%s>", data->set.str[STRING_MAIL_FROM]); + + if(!from) + return CURLE_OUT_OF_MEMORY; + + /* Calculate the optional AUTH parameter */ + if(data->set.str[STRING_MAIL_AUTH] && conn->proto.smtpc.sasl.authused) { + if(data->set.str[STRING_MAIL_AUTH][0] != '\0') + auth = aprintf("%s", data->set.str[STRING_MAIL_AUTH]); + else + /* Empty AUTH, RFC-2554, sect. 5 */ + auth = strdup("<>"); + + if(!auth) { + free(from); + + return CURLE_OUT_OF_MEMORY; + } + } + + /* Prepare the mime data if some. */ + if(data->set.mimepost.kind != MIMEKIND_NONE) { + /* Use the whole structure as data. */ + data->set.mimepost.flags &= ~MIME_BODY_ONLY; + + /* Add external headers and mime version. */ + curl_mime_headers(&data->set.mimepost, data->set.headers, 0); + result = Curl_mime_prepare_headers(&data->set.mimepost, NULL, + NULL, MIMESTRATEGY_MAIL); + + if(!result) + if(!Curl_checkheaders(conn, "Mime-Version")) + result = Curl_mime_add_header(&data->set.mimepost.curlheaders, + "Mime-Version: 1.0"); + + /* Make sure we will read the entire mime structure. */ + if(!result) + result = Curl_mime_rewind(&data->set.mimepost); + + if(result) { + free(from); + free(auth); + return result; + } + + data->state.infilesize = Curl_mime_size(&data->set.mimepost); + + /* Read from mime structure. */ + data->state.fread_func = (curl_read_callback) Curl_mime_read; + data->state.in = (void *) &data->set.mimepost; + } + + /* Calculate the optional SIZE parameter */ + if(conn->proto.smtpc.size_supported && data->state.infilesize > 0) { + size = aprintf("%" CURL_FORMAT_CURL_OFF_T, data->state.infilesize); + + if(!size) { + free(from); + free(auth); + + return CURLE_OUT_OF_MEMORY; + } + } + + /* Send the MAIL command */ + if(!auth && !size) + result = Curl_pp_sendf(&conn->proto.smtpc.pp, + "MAIL FROM:%s", from); + else if(auth && !size) + result = Curl_pp_sendf(&conn->proto.smtpc.pp, + "MAIL FROM:%s AUTH=%s", from, auth); + else if(auth && size) + result = Curl_pp_sendf(&conn->proto.smtpc.pp, + "MAIL FROM:%s AUTH=%s SIZE=%s", from, auth, size); + else + result = Curl_pp_sendf(&conn->proto.smtpc.pp, + "MAIL FROM:%s SIZE=%s", from, size); + + free(from); + free(auth); + free(size); + + if(!result) + state(conn, SMTP_MAIL); + + return result; +} + +/*********************************************************************** + * + * smtp_perform_rcpt_to() + * + * Sends a RCPT TO command for a given recipient as part of the message upload + * process. + */ +static CURLcode smtp_perform_rcpt_to(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct SMTP *smtp = data->req.protop; + + /* Send the RCPT TO command */ + if(smtp->rcpt->data[0] == '<') + result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:%s", + smtp->rcpt->data); + else + result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s>", + smtp->rcpt->data); + if(!result) + state(conn, SMTP_RCPT); + + return result; +} + +/*********************************************************************** + * + * smtp_perform_quit() + * + * Performs the quit action prior to sclose() being called. + */ +static CURLcode smtp_perform_quit(struct connectdata *conn) +{ + /* Send the QUIT command */ + CURLcode result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "QUIT"); + + if(!result) + state(conn, SMTP_QUIT); + + return result; +} + +/* For the initial server greeting */ +static CURLcode smtp_state_servergreet_resp(struct connectdata *conn, + int smtpcode, + smtpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + (void)instate; /* no use for this yet */ + + if(smtpcode/100 != 2) { + failf(data, "Got unexpected smtp-server response: %d", smtpcode); + result = CURLE_WEIRD_SERVER_REPLY; + } + else + result = smtp_perform_ehlo(conn); + + return result; +} + +/* For STARTTLS responses */ +static CURLcode smtp_state_starttls_resp(struct connectdata *conn, + int smtpcode, + smtpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + (void)instate; /* no use for this yet */ + + if(smtpcode != 220) { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied, code %d", smtpcode); + result = CURLE_USE_SSL_FAILED; + } + else + result = smtp_perform_authentication(conn); + } + else + result = smtp_perform_upgrade_tls(conn); + + return result; +} + +/* For EHLO responses */ +static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode, + smtpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct smtp_conn *smtpc = &conn->proto.smtpc; + const char *line = data->state.buffer; + size_t len = strlen(line); + + (void)instate; /* no use for this yet */ + + if(smtpcode/100 != 2 && smtpcode != 1) { + if(data->set.use_ssl <= CURLUSESSL_TRY || conn->ssl[FIRSTSOCKET].use) + result = smtp_perform_helo(conn); + else { + failf(data, "Remote access denied: %d", smtpcode); + result = CURLE_REMOTE_ACCESS_DENIED; + } + } + else { + line += 4; + len -= 4; + + /* Does the server support the STARTTLS capability? */ + if(len >= 8 && !memcmp(line, "STARTTLS", 8)) + smtpc->tls_supported = TRUE; + + /* Does the server support the SIZE capability? */ + else if(len >= 4 && !memcmp(line, "SIZE", 4)) + smtpc->size_supported = TRUE; + + /* Does the server support authentication? */ + else if(len >= 5 && !memcmp(line, "AUTH ", 5)) { + smtpc->auth_supported = TRUE; + + /* Advance past the AUTH keyword */ + line += 5; + len -= 5; + + /* Loop through the data line */ + for(;;) { + size_t llen; + size_t wordlen; + unsigned int mechbit; + + while(len && + (*line == ' ' || *line == '\t' || + *line == '\r' || *line == '\n')) { + + line++; + len--; + } + + if(!len) + break; + + /* Extract the word */ + for(wordlen = 0; wordlen < len && line[wordlen] != ' ' && + line[wordlen] != '\t' && line[wordlen] != '\r' && + line[wordlen] != '\n';) + wordlen++; + + /* Test the word for a matching authentication mechanism */ + mechbit = Curl_sasl_decode_mech(line, wordlen, &llen); + if(mechbit && llen == wordlen) + smtpc->sasl.authmechs |= mechbit; + + line += wordlen; + len -= wordlen; + } + } + + if(smtpcode != 1) { + if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { + /* We don't have a SSL/TLS connection yet, but SSL is requested */ + if(smtpc->tls_supported) + /* Switch to TLS connection now */ + result = smtp_perform_starttls(conn); + else if(data->set.use_ssl == CURLUSESSL_TRY) + /* Fallback and carry on with authentication */ + result = smtp_perform_authentication(conn); + else { + failf(data, "STARTTLS not supported."); + result = CURLE_USE_SSL_FAILED; + } + } + else + result = smtp_perform_authentication(conn); + } + } + + return result; +} + +/* For HELO responses */ +static CURLcode smtp_state_helo_resp(struct connectdata *conn, int smtpcode, + smtpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + (void)instate; /* no use for this yet */ + + if(smtpcode/100 != 2) { + failf(data, "Remote access denied: %d", smtpcode); + result = CURLE_REMOTE_ACCESS_DENIED; + } + else + /* End of connect phase */ + state(conn, SMTP_STOP); + + return result; +} + +/* For SASL authentication responses */ +static CURLcode smtp_state_auth_resp(struct connectdata *conn, + int smtpcode, + smtpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct smtp_conn *smtpc = &conn->proto.smtpc; + saslprogress progress; + + (void)instate; /* no use for this yet */ + + result = Curl_sasl_continue(&smtpc->sasl, conn, smtpcode, &progress); + if(!result) + switch(progress) { + case SASL_DONE: + state(conn, SMTP_STOP); /* Authenticated */ + break; + case SASL_IDLE: /* No mechanism left after cancellation */ + failf(data, "Authentication cancelled"); + result = CURLE_LOGIN_DENIED; + break; + default: + break; + } + + return result; +} + +/* For command responses */ +static CURLcode smtp_state_command_resp(struct connectdata *conn, int smtpcode, + smtpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct SMTP *smtp = data->req.protop; + char *line = data->state.buffer; + size_t len = strlen(line); + + (void)instate; /* no use for this yet */ + + if((smtp->rcpt && smtpcode/100 != 2 && smtpcode != 553 && smtpcode != 1) || + (!smtp->rcpt && smtpcode/100 != 2 && smtpcode != 1)) { + failf(data, "Command failed: %d", smtpcode); + result = CURLE_RECV_ERROR; + } + else { + /* Temporarily add the LF character back and send as body to the client */ + if(!data->set.opt_no_body) { + line[len] = '\n'; + result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1); + line[len] = '\0'; + } + + if(smtpcode != 1) { + if(smtp->rcpt) { + smtp->rcpt = smtp->rcpt->next; + + if(smtp->rcpt) { + /* Send the next command */ + result = smtp_perform_command(conn); + } + else + /* End of DO phase */ + state(conn, SMTP_STOP); + } + else + /* End of DO phase */ + state(conn, SMTP_STOP); + } + } + + return result; +} + +/* For MAIL responses */ +static CURLcode smtp_state_mail_resp(struct connectdata *conn, int smtpcode, + smtpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + (void)instate; /* no use for this yet */ + + if(smtpcode/100 != 2) { + failf(data, "MAIL failed: %d", smtpcode); + result = CURLE_SEND_ERROR; + } + else + /* Start the RCPT TO command */ + result = smtp_perform_rcpt_to(conn); + + return result; +} + +/* For RCPT responses */ +static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode, + smtpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct SMTP *smtp = data->req.protop; + + (void)instate; /* no use for this yet */ + + if(smtpcode/100 != 2) { + failf(data, "RCPT failed: %d", smtpcode); + result = CURLE_SEND_ERROR; + } + else { + smtp->rcpt = smtp->rcpt->next; + + if(smtp->rcpt) + /* Send the next RCPT TO command */ + result = smtp_perform_rcpt_to(conn); + else { + /* Send the DATA command */ + result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA"); + + if(!result) + state(conn, SMTP_DATA); + } + } + + return result; +} + +/* For DATA response */ +static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode, + smtpstate instate) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + (void)instate; /* no use for this yet */ + + if(smtpcode != 354) { + failf(data, "DATA failed: %d", smtpcode); + result = CURLE_SEND_ERROR; + } + else { + /* Set the progress upload size */ + Curl_pgrsSetUploadSize(data, data->state.infilesize); + + /* SMTP upload */ + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); + + /* End of DO phase */ + state(conn, SMTP_STOP); + } + + return result; +} + +/* For POSTDATA responses, which are received after the entire DATA + part has been sent to the server */ +static CURLcode smtp_state_postdata_resp(struct connectdata *conn, + int smtpcode, + smtpstate instate) +{ + CURLcode result = CURLE_OK; + + (void)instate; /* no use for this yet */ + + if(smtpcode != 250) + result = CURLE_RECV_ERROR; + + /* End of DONE phase */ + state(conn, SMTP_STOP); + + return result; +} + +static CURLcode smtp_statemach_act(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + struct Curl_easy *data = conn->data; + int smtpcode; + struct smtp_conn *smtpc = &conn->proto.smtpc; + struct pingpong *pp = &smtpc->pp; + size_t nread = 0; + + /* Busy upgrading the connection; right now all I/O is SSL/TLS, not SMTP */ + if(smtpc->state == SMTP_UPGRADETLS) + return smtp_perform_upgrade_tls(conn); + + /* Flush any data that needs to be sent */ + if(pp->sendleft) + return Curl_pp_flushsend(pp); + + do { + /* Read the response from the server */ + result = Curl_pp_readresp(sock, pp, &smtpcode, &nread); + if(result) + return result; + + /* Store the latest response for later retrieval if necessary */ + if(smtpc->state != SMTP_QUIT && smtpcode != 1) + data->info.httpcode = smtpcode; + + if(!smtpcode) + break; + + /* We have now received a full SMTP server response */ + switch(smtpc->state) { + case SMTP_SERVERGREET: + result = smtp_state_servergreet_resp(conn, smtpcode, smtpc->state); + break; + + case SMTP_EHLO: + result = smtp_state_ehlo_resp(conn, smtpcode, smtpc->state); + break; + + case SMTP_HELO: + result = smtp_state_helo_resp(conn, smtpcode, smtpc->state); + break; + + case SMTP_STARTTLS: + result = smtp_state_starttls_resp(conn, smtpcode, smtpc->state); + break; + + case SMTP_AUTH: + result = smtp_state_auth_resp(conn, smtpcode, smtpc->state); + break; + + case SMTP_COMMAND: + result = smtp_state_command_resp(conn, smtpcode, smtpc->state); + break; + + case SMTP_MAIL: + result = smtp_state_mail_resp(conn, smtpcode, smtpc->state); + break; + + case SMTP_RCPT: + result = smtp_state_rcpt_resp(conn, smtpcode, smtpc->state); + break; + + case SMTP_DATA: + result = smtp_state_data_resp(conn, smtpcode, smtpc->state); + break; + + case SMTP_POSTDATA: + result = smtp_state_postdata_resp(conn, smtpcode, smtpc->state); + break; + + case SMTP_QUIT: + /* fallthrough, just stop! */ + default: + /* internal error */ + state(conn, SMTP_STOP); + break; + } + } while(!result && smtpc->state != SMTP_STOP && Curl_pp_moredata(pp)); + + return result; +} + +/* Called repeatedly until done from multi.c */ +static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + struct smtp_conn *smtpc = &conn->proto.smtpc; + + if((conn->handler->flags & PROTOPT_SSL) && !smtpc->ssldone) { + result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone); + if(result || !smtpc->ssldone) + return result; + } + + result = Curl_pp_statemach(&smtpc->pp, FALSE, FALSE); + *done = (smtpc->state == SMTP_STOP) ? TRUE : FALSE; + + return result; +} + +static CURLcode smtp_block_statemach(struct connectdata *conn, + bool disconnecting) +{ + CURLcode result = CURLE_OK; + struct smtp_conn *smtpc = &conn->proto.smtpc; + + while(smtpc->state != SMTP_STOP && !result) + result = Curl_pp_statemach(&smtpc->pp, TRUE, disconnecting); + + return result; +} + +/* Allocate and initialize the SMTP struct for the current Curl_easy if + required */ +static CURLcode smtp_init(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct SMTP *smtp; + + smtp = data->req.protop = calloc(sizeof(struct SMTP), 1); + if(!smtp) + result = CURLE_OUT_OF_MEMORY; + + return result; +} + +/* For the SMTP "protocol connect" and "doing" phases only */ +static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks) +{ + return Curl_pp_getsock(&conn->proto.smtpc.pp, socks, numsocks); +} + +/*********************************************************************** + * + * smtp_connect() + * + * This function should do everything that is to be considered a part of + * the connection phase. + * + * The variable pointed to by 'done' will be TRUE if the protocol-layer + * connect phase is done when this function returns, or FALSE if not. + */ +static CURLcode smtp_connect(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + struct smtp_conn *smtpc = &conn->proto.smtpc; + struct pingpong *pp = &smtpc->pp; + + *done = FALSE; /* default to not done yet */ + + /* We always support persistent connections in SMTP */ + connkeep(conn, "SMTP default"); + + /* Set the default response time-out */ + pp->response_time = RESP_TIMEOUT; + pp->statemach_act = smtp_statemach_act; + pp->endofresp = smtp_endofresp; + pp->conn = conn; + + /* Initialize the SASL storage */ + Curl_sasl_init(&smtpc->sasl, &saslsmtp); + + /* Initialise the pingpong layer */ + Curl_pp_init(pp); + + /* Parse the URL options */ + result = smtp_parse_url_options(conn); + if(result) + return result; + + /* Parse the URL path */ + result = smtp_parse_url_path(conn); + if(result) + return result; + + /* Start off waiting for the server greeting response */ + state(conn, SMTP_SERVERGREET); + + result = smtp_multi_statemach(conn, done); + + return result; +} + +/*********************************************************************** + * + * smtp_done() + * + * The DONE function. This does what needs to be done after a single DO has + * performed. + * + * Input argument is already checked for validity. + */ +static CURLcode smtp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct SMTP *smtp = data->req.protop; + struct pingpong *pp = &conn->proto.smtpc.pp; + char *eob; + ssize_t len; + ssize_t bytes_written; + + (void)premature; + + if(!smtp || !pp->conn) + return CURLE_OK; + + /* Cleanup our per-request based variables */ + Curl_safefree(smtp->custom); + + if(status) { + connclose(conn, "SMTP done with bad status"); /* marked for closure */ + result = status; /* use the already set error code */ + } + else if(!data->set.connect_only && data->set.mail_rcpt && + (data->set.upload || data->set.mimepost.kind)) { + /* Calculate the EOB taking into account any terminating CRLF from the + previous line of the email or the CRLF of the DATA command when there + is "no mail data". RFC-5321, sect. 4.1.1.4. + + Note: As some SSL backends, such as OpenSSL, will cause Curl_write() to + fail when using a different pointer following a previous write, that + returned CURLE_AGAIN, we duplicate the EOB now rather than when the + bytes written doesn't equal len. */ + if(smtp->trailing_crlf || !conn->data->state.infilesize) { + eob = strdup(&SMTP_EOB[2]); + len = SMTP_EOB_LEN - 2; + } + else { + eob = strdup(SMTP_EOB); + len = SMTP_EOB_LEN; + } + + if(!eob) + return CURLE_OUT_OF_MEMORY; + + /* Send the end of block data */ + result = Curl_write(conn, conn->writesockfd, eob, len, &bytes_written); + if(result) { + free(eob); + return result; + } + + if(bytes_written != len) { + /* The whole chunk was not sent so keep it around and adjust the + pingpong structure accordingly */ + pp->sendthis = eob; + pp->sendsize = len; + pp->sendleft = len - bytes_written; + } + else { + /* Successfully sent so adjust the response timeout relative to now */ + pp->response = Curl_now(); + + free(eob); + } + + state(conn, SMTP_POSTDATA); + + /* Run the state-machine */ + result = smtp_block_statemach(conn, FALSE); + } + + /* Clear the transfer mode for the next request */ + smtp->transfer = FTPTRANSFER_BODY; + + return result; +} + +/*********************************************************************** + * + * smtp_perform() + * + * This is the actual DO function for SMTP. Transfer a mail, send a command + * or get some data according to the options previously setup. + */ +static CURLcode smtp_perform(struct connectdata *conn, bool *connected, + bool *dophase_done) +{ + /* This is SMTP and no proxy */ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct SMTP *smtp = data->req.protop; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + if(data->set.opt_no_body) { + /* Requested no body means no transfer */ + smtp->transfer = FTPTRANSFER_INFO; + } + + *dophase_done = FALSE; /* not done yet */ + + /* Store the first recipient (or NULL if not specified) */ + smtp->rcpt = data->set.mail_rcpt; + + /* Initial data character is the first character in line: it is implicitly + preceded by a virtual CRLF. */ + smtp->trailing_crlf = TRUE; + smtp->eob = 2; + + /* Start the first command in the DO phase */ + if((data->set.upload || data->set.mimepost.kind) && data->set.mail_rcpt) + /* MAIL transfer */ + result = smtp_perform_mail(conn); + else + /* SMTP based command (VRFY, EXPN, NOOP, RSET or HELP) */ + result = smtp_perform_command(conn); + + if(result) + return result; + + /* Run the state-machine */ + result = smtp_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) + DEBUGF(infof(conn->data, "DO phase is complete\n")); + + return result; +} + +/*********************************************************************** + * + * smtp_do() + * + * This function is registered as 'curl_do' function. It decodes the path + * parts etc as a wrapper to the actual DO function (smtp_perform). + * + * The input argument is already checked for validity. + */ +static CURLcode smtp_do(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + + *done = FALSE; /* default to false */ + + /* Parse the custom request */ + result = smtp_parse_custom_request(conn); + if(result) + return result; + + result = smtp_regular_transfer(conn, done); + + return result; +} + +/*********************************************************************** + * + * smtp_disconnect() + * + * Disconnect from an SMTP server. Cleanup protocol-specific per-connection + * resources. BLOCKING. + */ +static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection) +{ + struct smtp_conn *smtpc = &conn->proto.smtpc; + + /* We cannot send quit unconditionally. If this connection is stale or + bad in any way, sending quit and waiting around here will make the + disconnect wait in vain and cause more problems than we need to. */ + + /* The SMTP session may or may not have been allocated/setup at this + point! */ + if(!dead_connection && smtpc->pp.conn && smtpc->pp.conn->bits.protoconnstart) + if(!smtp_perform_quit(conn)) + (void)smtp_block_statemach(conn, TRUE); /* ignore errors on QUIT */ + + /* Disconnect from the server */ + Curl_pp_disconnect(&smtpc->pp); + + /* Cleanup the SASL module */ + Curl_sasl_cleanup(conn, smtpc->sasl.authused); + + /* Cleanup our connection based variables */ + Curl_safefree(smtpc->domain); + + return CURLE_OK; +} + +/* Call this when the DO phase has completed */ +static CURLcode smtp_dophase_done(struct connectdata *conn, bool connected) +{ + struct SMTP *smtp = conn->data->req.protop; + + (void)connected; + + if(smtp->transfer != FTPTRANSFER_BODY) + /* no data to transfer */ + Curl_setup_transfer(conn->data, -1, -1, FALSE, -1); + + return CURLE_OK; +} + +/* Called from multi.c while DOing */ +static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done) +{ + CURLcode result = smtp_multi_statemach(conn, dophase_done); + + if(result) + DEBUGF(infof(conn->data, "DO phase failed\n")); + else if(*dophase_done) { + result = smtp_dophase_done(conn, FALSE /* not connected */); + + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +/*********************************************************************** + * + * smtp_regular_transfer() + * + * The input argument is already checked for validity. + * + * Performs all commands done before a regular transfer between a local and a + * remote host. + */ +static CURLcode smtp_regular_transfer(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result = CURLE_OK; + bool connected = FALSE; + struct Curl_easy *data = conn->data; + + /* Make sure size is unknown at this point */ + data->req.size = -1; + + /* Set the progress data */ + Curl_pgrsSetUploadCounter(data, 0); + Curl_pgrsSetDownloadCounter(data, 0); + Curl_pgrsSetUploadSize(data, -1); + Curl_pgrsSetDownloadSize(data, -1); + + /* Carry out the perform */ + result = smtp_perform(conn, &connected, dophase_done); + + /* Perform post DO phase operations if necessary */ + if(!result && *dophase_done) + result = smtp_dophase_done(conn, connected); + + return result; +} + +static CURLcode smtp_setup_connection(struct connectdata *conn) +{ + CURLcode result; + + /* Clear the TLS upgraded flag */ + conn->tls_upgraded = FALSE; + + /* Initialise the SMTP layer */ + result = smtp_init(conn); + if(result) + return result; + + return CURLE_OK; +} + +/*********************************************************************** + * + * smtp_parse_url_options() + * + * Parse the URL login options. + */ +static CURLcode smtp_parse_url_options(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct smtp_conn *smtpc = &conn->proto.smtpc; + const char *ptr = conn->options; + + smtpc->sasl.resetprefs = TRUE; + + while(!result && ptr && *ptr) { + const char *key = ptr; + const char *value; + + while(*ptr && *ptr != '=') + ptr++; + + value = ptr + 1; + + while(*ptr && *ptr != ';') + ptr++; + + if(strncasecompare(key, "AUTH=", 5)) + result = Curl_sasl_parse_url_auth_option(&smtpc->sasl, + value, ptr - value); + else + result = CURLE_URL_MALFORMAT; + + if(*ptr == ';') + ptr++; + } + + return result; +} + +/*********************************************************************** + * + * smtp_parse_url_path() + * + * Parse the URL path into separate path components. + */ +static CURLcode smtp_parse_url_path(struct connectdata *conn) +{ + /* The SMTP struct is already initialised in smtp_connect() */ + struct Curl_easy *data = conn->data; + struct smtp_conn *smtpc = &conn->proto.smtpc; + const char *path = &data->state.up.path[1]; /* skip leading path */ + char localhost[HOSTNAME_MAX + 1]; + + /* Calculate the path if necessary */ + if(!*path) { + if(!Curl_gethostname(localhost, sizeof(localhost))) + path = localhost; + else + path = "localhost"; + } + + /* URL decode the path and use it as the domain in our EHLO */ + return Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL, TRUE); +} + +/*********************************************************************** + * + * smtp_parse_custom_request() + * + * Parse the custom request. + */ +static CURLcode smtp_parse_custom_request(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct SMTP *smtp = data->req.protop; + const char *custom = data->set.str[STRING_CUSTOMREQUEST]; + + /* URL decode the custom request */ + if(custom) + result = Curl_urldecode(data, custom, 0, &smtp->custom, NULL, TRUE); + + return result; +} + +CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread) +{ + /* When sending a SMTP payload we must detect CRLF. sequences making sure + they are sent as CRLF.. instead, as a . on the beginning of a line will + be deleted by the server when not part of an EOB terminator and a + genuine CRLF.CRLF which isn't escaped will wrongly be detected as end of + data by the server + */ + ssize_t i; + ssize_t si; + struct Curl_easy *data = conn->data; + struct SMTP *smtp = data->req.protop; + char *scratch = data->state.scratch; + char *newscratch = NULL; + char *oldscratch = NULL; + size_t eob_sent; + + /* Do we need to allocate a scratch buffer? */ + if(!scratch || data->set.crlf) { + oldscratch = scratch; + + scratch = newscratch = malloc(2 * data->set.upload_buffer_size); + if(!newscratch) { + failf(data, "Failed to alloc scratch buffer!"); + + return CURLE_OUT_OF_MEMORY; + } + } + DEBUGASSERT(data->set.upload_buffer_size >= (size_t)nread); + + /* Have we already sent part of the EOB? */ + eob_sent = smtp->eob; + + /* This loop can be improved by some kind of Boyer-Moore style of + approach but that is saved for later... */ + for(i = 0, si = 0; i < nread; i++) { + if(SMTP_EOB[smtp->eob] == data->req.upload_fromhere[i]) { + smtp->eob++; + + /* Is the EOB potentially the terminating CRLF? */ + if(2 == smtp->eob || SMTP_EOB_LEN == smtp->eob) + smtp->trailing_crlf = TRUE; + else + smtp->trailing_crlf = FALSE; + } + else if(smtp->eob) { + /* A previous substring matched so output that first */ + memcpy(&scratch[si], &SMTP_EOB[eob_sent], smtp->eob - eob_sent); + si += smtp->eob - eob_sent; + + /* Then compare the first byte */ + if(SMTP_EOB[0] == data->req.upload_fromhere[i]) + smtp->eob = 1; + else + smtp->eob = 0; + + eob_sent = 0; + + /* Reset the trailing CRLF flag as there was more data */ + smtp->trailing_crlf = FALSE; + } + + /* Do we have a match for CRLF. as per RFC-5321, sect. 4.5.2 */ + if(SMTP_EOB_FIND_LEN == smtp->eob) { + /* Copy the replacement data to the target buffer */ + memcpy(&scratch[si], &SMTP_EOB_REPL[eob_sent], + SMTP_EOB_REPL_LEN - eob_sent); + si += SMTP_EOB_REPL_LEN - eob_sent; + smtp->eob = 0; + eob_sent = 0; + } + else if(!smtp->eob) + scratch[si++] = data->req.upload_fromhere[i]; + } + + if(smtp->eob - eob_sent) { + /* A substring matched before processing ended so output that now */ + memcpy(&scratch[si], &SMTP_EOB[eob_sent], smtp->eob - eob_sent); + si += smtp->eob - eob_sent; + } + + /* Only use the new buffer if we replaced something */ + if(si != nread) { + /* Upload from the new (replaced) buffer instead */ + data->req.upload_fromhere = scratch; + + /* Save the buffer so it can be freed later */ + data->state.scratch = scratch; + + /* Free the old scratch buffer */ + free(oldscratch); + + /* Set the new amount too */ + data->req.upload_present = si; + } + else + free(newscratch); + + return CURLE_OK; +} + +#endif /* CURL_DISABLE_SMTP */ diff --git a/libcurl/lib/smtp.h b/libcurl/lib/smtp.h new file mode 100644 index 0000000..b67340a --- /dev/null +++ b/libcurl/lib/smtp.h @@ -0,0 +1,91 @@ +#ifndef HEADER_CURL_SMTP_H +#define HEADER_CURL_SMTP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2009 - 2014, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "pingpong.h" +#include "curl_sasl.h" + +/**************************************************************************** + * SMTP unique setup + ***************************************************************************/ +typedef enum { + SMTP_STOP, /* do nothing state, stops the state machine */ + SMTP_SERVERGREET, /* waiting for the initial greeting immediately after + a connect */ + SMTP_EHLO, + SMTP_HELO, + SMTP_STARTTLS, + SMTP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS + (multi mode only) */ + SMTP_AUTH, + SMTP_COMMAND, /* VRFY, EXPN, NOOP, RSET and HELP */ + SMTP_MAIL, /* MAIL FROM */ + SMTP_RCPT, /* RCPT TO */ + SMTP_DATA, + SMTP_POSTDATA, + SMTP_QUIT, + SMTP_LAST /* never used */ +} smtpstate; + +/* This SMTP struct is used in the Curl_easy. All SMTP data that is + connection-oriented must be in smtp_conn to properly deal with the fact that + perhaps the Curl_easy is changed between the times the connection is + used. */ +struct SMTP { + curl_pp_transfer transfer; + char *custom; /* Custom Request */ + struct curl_slist *rcpt; /* Recipient list */ + size_t eob; /* Number of bytes of the EOB (End Of Body) that + have been received so far */ + bool trailing_crlf; /* Specifies if the tailing CRLF is present */ +}; + +/* smtp_conn is used for struct connection-oriented data in the connectdata + struct */ +struct smtp_conn { + struct pingpong pp; + smtpstate state; /* Always use smtp.c:state() to change state! */ + bool ssldone; /* Is connect() over SSL done? */ + char *domain; /* Client address/name to send in the EHLO */ + struct SASL sasl; /* SASL-related storage */ + bool tls_supported; /* StartTLS capability supported by server */ + bool size_supported; /* If server supports SIZE extension according to + RFC 1870 */ + bool auth_supported; /* AUTH capability supported by server */ +}; + +extern const struct Curl_handler Curl_handler_smtp; +extern const struct Curl_handler Curl_handler_smtps; + +/* this is the 5-bytes End-Of-Body marker for SMTP */ +#define SMTP_EOB "\x0d\x0a\x2e\x0d\x0a" +#define SMTP_EOB_LEN 5 +#define SMTP_EOB_FIND_LEN 3 + +/* if found in data, replace it with this string instead */ +#define SMTP_EOB_REPL "\x0d\x0a\x2e\x2e" +#define SMTP_EOB_REPL_LEN 4 + +CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread); + +#endif /* HEADER_CURL_SMTP_H */ diff --git a/libcurl/lib/sockaddr.h b/libcurl/lib/sockaddr.h new file mode 100644 index 0000000..db14680 --- /dev/null +++ b/libcurl/lib/sockaddr.h @@ -0,0 +1,42 @@ +#ifndef HEADER_CURL_SOCKADDR_H +#define HEADER_CURL_SOCKADDR_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +struct Curl_sockaddr_storage { + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#ifdef ENABLE_IPV6 + struct sockaddr_in6 sa_in6; +#endif +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE + struct sockaddr_storage sa_stor; +#else + char cbuf[256]; /* this should be big enough to fit a lot */ +#endif + } buffer; +}; + +#endif /* HEADER_CURL_SOCKADDR_H */ diff --git a/libcurl/lib/socks.c b/libcurl/lib/socks.c new file mode 100644 index 0000000..d8fcc3b --- /dev/null +++ b/libcurl/lib/socks.c @@ -0,0 +1,803 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_PROXY) + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#include "urldata.h" +#include "sendf.h" +#include "select.h" +#include "connect.h" +#include "timeval.h" +#include "socks.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +/* + * Helper read-from-socket functions. Does the same as Curl_read() but it + * blocks until all bytes amount of buffersize will be read. No more, no less. + * + * This is STUPID BLOCKING behaviour which we frown upon, but right now this + * is what we have... + */ +int Curl_blockread_all(struct connectdata *conn, /* connection data */ + curl_socket_t sockfd, /* read from this socket */ + char *buf, /* store read data here */ + ssize_t buffersize, /* max amount to read */ + ssize_t *n) /* amount bytes read */ +{ + ssize_t nread = 0; + ssize_t allread = 0; + int result; + *n = 0; + for(;;) { + timediff_t timeleft = Curl_timeleft(conn->data, NULL, TRUE); + if(timeleft < 0) { + /* we already got the timeout */ + result = CURLE_OPERATION_TIMEDOUT; + break; + } + if(SOCKET_READABLE(sockfd, timeleft) <= 0) { + result = ~CURLE_OK; + break; + } + result = Curl_read_plain(sockfd, buf, buffersize, &nread); + if(CURLE_AGAIN == result) + continue; + if(result) + break; + + if(buffersize == nread) { + allread += nread; + *n = allread; + result = CURLE_OK; + break; + } + if(!nread) { + result = ~CURLE_OK; + break; + } + + buffersize -= nread; + buf += nread; + allread += nread; + } + return result; +} + +/* +* This function logs in to a SOCKS4 proxy and sends the specifics to the final +* destination server. +* +* Reference : +* https://www.openssh.com/txt/socks4.protocol +* +* Note : +* Set protocol4a=true for "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" +* Nonsupport "Identification Protocol (RFC1413)" +*/ +CURLcode Curl_SOCKS4(const char *proxy_user, + const char *hostname, + int remote_port, + int sockindex, + struct connectdata *conn) +{ + const bool protocol4a = + (conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE; +#define SOCKS4REQLEN 262 + unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user + id */ + CURLcode code; + curl_socket_t sock = conn->sock[sockindex]; + struct Curl_easy *data = conn->data; + + if(Curl_timeleft(data, NULL, TRUE) < 0) { + /* time-out, bail out, go home */ + failf(data, "Connection time-out"); + return CURLE_OPERATION_TIMEDOUT; + } + + if(conn->bits.httpproxy) + infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n", + protocol4a ? "a" : "", hostname, remote_port); + + (void)curlx_nonblock(sock, FALSE); + + infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port); + + /* + * Compose socks4 request + * + * Request format + * + * +----+----+----+----+----+----+----+----+----+----+....+----+ + * | VN | CD | DSTPORT | DSTIP | USERID |NULL| + * +----+----+----+----+----+----+----+----+----+----+....+----+ + * # of bytes: 1 1 2 4 variable 1 + */ + + socksreq[0] = 4; /* version (SOCKS4) */ + socksreq[1] = 1; /* connect */ + socksreq[2] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */ + socksreq[3] = (unsigned char)(remote_port & 0xff); /* PORT LSB */ + + /* DNS resolve only for SOCKS4, not SOCKS4a */ + if(!protocol4a) { + struct Curl_dns_entry *dns; + Curl_addrinfo *hp = NULL; + int rc; + + rc = Curl_resolv(conn, hostname, remote_port, FALSE, &dns); + + if(rc == CURLRESOLV_ERROR) + return CURLE_COULDNT_RESOLVE_PROXY; + + if(rc == CURLRESOLV_PENDING) + /* ignores the return code, but 'dns' remains NULL on failure */ + (void)Curl_resolver_wait_resolv(conn, &dns); + + /* + * We cannot use 'hostent' as a struct that Curl_resolv() returns. It + * returns a Curl_addrinfo pointer that may not always look the same. + */ + if(dns) + hp = dns->addr; + if(hp) { + char buf[64]; + Curl_printable_address(hp, buf, sizeof(buf)); + + if(hp->ai_family == AF_INET) { + struct sockaddr_in *saddr_in; + + saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr; + socksreq[4] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[0]; + socksreq[5] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[1]; + socksreq[6] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[2]; + socksreq[7] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[3]; + + infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)\n", buf); + } + else { + hp = NULL; /* fail! */ + + failf(data, "SOCKS4 connection to %s not supported\n", buf); + } + + Curl_resolv_unlock(data, dns); /* not used anymore from now on */ + } + if(!hp) { + failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.", + hostname); + return CURLE_COULDNT_RESOLVE_HOST; + } + } + + /* + * This is currently not supporting "Identification Protocol (RFC1413)". + */ + socksreq[8] = 0; /* ensure empty userid is NUL-terminated */ + if(proxy_user) { + size_t plen = strlen(proxy_user); + if(plen >= sizeof(socksreq) - 8) { + failf(data, "Too long SOCKS proxy name, can't use!\n"); + return CURLE_COULDNT_CONNECT; + } + /* copy the proxy name WITH trailing zero */ + memcpy(socksreq + 8, proxy_user, plen + 1); + } + + /* + * Make connection + */ + { + int result; + ssize_t actualread; + ssize_t written; + ssize_t hostnamelen = 0; + ssize_t packetsize = 9 + + strlen((char *)socksreq + 8); /* size including NUL */ + + /* If SOCKS4a, set special invalid IP address 0.0.0.x */ + if(protocol4a) { + socksreq[4] = 0; + socksreq[5] = 0; + socksreq[6] = 0; + socksreq[7] = 1; + /* If still enough room in buffer, also append hostname */ + hostnamelen = (ssize_t)strlen(hostname) + 1; /* length including NUL */ + if(packetsize + hostnamelen <= SOCKS4REQLEN) + strcpy((char *)socksreq + packetsize, hostname); + else + hostnamelen = 0; /* Flag: hostname did not fit in buffer */ + } + + /* Send request */ + code = Curl_write_plain(conn, sock, (char *)socksreq, + packetsize + hostnamelen, + &written); + if(code || (written != packetsize + hostnamelen)) { + failf(data, "Failed to send SOCKS4 connect request."); + return CURLE_COULDNT_CONNECT; + } + if(protocol4a && hostnamelen == 0) { + /* SOCKS4a with very long hostname - send that name separately */ + hostnamelen = (ssize_t)strlen(hostname) + 1; + code = Curl_write_plain(conn, sock, (char *)hostname, hostnamelen, + &written); + if(code || (written != hostnamelen)) { + failf(data, "Failed to send SOCKS4 connect request."); + return CURLE_COULDNT_CONNECT; + } + } + + packetsize = 8; /* receive data size */ + + /* Receive response */ + result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize, + &actualread); + if(result || (actualread != packetsize)) { + failf(data, "Failed to receive SOCKS4 connect request ack."); + return CURLE_COULDNT_CONNECT; + } + + /* + * Response format + * + * +----+----+----+----+----+----+----+----+ + * | VN | CD | DSTPORT | DSTIP | + * +----+----+----+----+----+----+----+----+ + * # of bytes: 1 1 2 4 + * + * VN is the version of the reply code and should be 0. CD is the result + * code with one of the following values: + * + * 90: request granted + * 91: request rejected or failed + * 92: request rejected because SOCKS server cannot connect to + * identd on the client + * 93: request rejected because the client program and identd + * report different user-ids + */ + + /* wrong version ? */ + if(socksreq[0] != 0) { + failf(data, + "SOCKS4 reply has wrong version, version should be 0."); + return CURLE_COULDNT_CONNECT; + } + + /* Result */ + switch(socksreq[1]) { + case 90: + infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":""); + break; + case 91: + failf(data, + "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" + ", request rejected or failed.", + (unsigned char)socksreq[4], (unsigned char)socksreq[5], + (unsigned char)socksreq[6], (unsigned char)socksreq[7], + (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), + (unsigned char)socksreq[1]); + return CURLE_COULDNT_CONNECT; + case 92: + failf(data, + "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" + ", request rejected because SOCKS server cannot connect to " + "identd on the client.", + (unsigned char)socksreq[4], (unsigned char)socksreq[5], + (unsigned char)socksreq[6], (unsigned char)socksreq[7], + (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), + (unsigned char)socksreq[1]); + return CURLE_COULDNT_CONNECT; + case 93: + failf(data, + "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" + ", request rejected because the client program and identd " + "report different user-ids.", + (unsigned char)socksreq[4], (unsigned char)socksreq[5], + (unsigned char)socksreq[6], (unsigned char)socksreq[7], + (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), + (unsigned char)socksreq[1]); + return CURLE_COULDNT_CONNECT; + default: + failf(data, + "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" + ", Unknown.", + (unsigned char)socksreq[4], (unsigned char)socksreq[5], + (unsigned char)socksreq[6], (unsigned char)socksreq[7], + (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), + (unsigned char)socksreq[1]); + return CURLE_COULDNT_CONNECT; + } + } + + (void)curlx_nonblock(sock, TRUE); + + return CURLE_OK; /* Proxy was successful! */ +} + +/* + * This function logs in to a SOCKS5 proxy and sends the specifics to the final + * destination server. + */ +CURLcode Curl_SOCKS5(const char *proxy_user, + const char *proxy_password, + const char *hostname, + int remote_port, + int sockindex, + struct connectdata *conn) +{ + /* + According to the RFC1928, section "6. Replies". This is what a SOCK5 + replies: + + +----+-----+-------+------+----------+----------+ + |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | + +----+-----+-------+------+----------+----------+ + | 1 | 1 | X'00' | 1 | Variable | 2 | + +----+-----+-------+------+----------+----------+ + + Where: + + o VER protocol version: X'05' + o REP Reply field: + o X'00' succeeded + */ + + unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ + int idx; + ssize_t actualread; + ssize_t written; + int result; + CURLcode code; + curl_socket_t sock = conn->sock[sockindex]; + struct Curl_easy *data = conn->data; + timediff_t timeout; + bool socks5_resolve_local = + (conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE; + const size_t hostname_len = strlen(hostname); + ssize_t len = 0; + const unsigned long auth = data->set.socks5auth; + bool allow_gssapi = FALSE; + + if(conn->bits.httpproxy) + infof(conn->data, "SOCKS5: connecting to HTTP proxy %s port %d\n", + hostname, remote_port); + + /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */ + if(!socks5_resolve_local && hostname_len > 255) { + infof(conn->data, "SOCKS5: server resolving disabled for hostnames of " + "length > 255 [actual len=%zu]\n", hostname_len); + socks5_resolve_local = TRUE; + } + + /* get timeout */ + timeout = Curl_timeleft(data, NULL, TRUE); + + if(timeout < 0) { + /* time-out, bail out, go home */ + failf(data, "Connection time-out"); + return CURLE_OPERATION_TIMEDOUT; + } + + (void)curlx_nonblock(sock, TRUE); + + /* wait until socket gets connected */ + result = SOCKET_WRITABLE(sock, timeout); + + if(-1 == result) { + failf(conn->data, "SOCKS5: no connection here"); + return CURLE_COULDNT_CONNECT; + } + if(0 == result) { + failf(conn->data, "SOCKS5: connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + if(result & CURL_CSELECT_ERR) { + failf(conn->data, "SOCKS5: error occurred during connection"); + return CURLE_COULDNT_CONNECT; + } + + if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) + infof(conn->data, + "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n", + auth); + if(!(auth & CURLAUTH_BASIC)) + /* disable username/password auth */ + proxy_user = NULL; +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + if(auth & CURLAUTH_GSSAPI) + allow_gssapi = TRUE; +#endif + + idx = 0; + socksreq[idx++] = 5; /* version */ + idx++; /* reserve for the number of authentication methods */ + socksreq[idx++] = 0; /* no authentication */ + if(allow_gssapi) + socksreq[idx++] = 1; /* GSS-API */ + if(proxy_user) + socksreq[idx++] = 2; /* username/password */ + /* write the number of authentication methods */ + socksreq[1] = (unsigned char) (idx - 2); + + (void)curlx_nonblock(sock, FALSE); + + infof(data, "SOCKS5 communication to %s:%d\n", hostname, remote_port); + + code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]), + &written); + if(code || (written != (2 + (int)socksreq[1]))) { + failf(data, "Unable to send initial SOCKS5 request."); + return CURLE_COULDNT_CONNECT; + } + + (void)curlx_nonblock(sock, TRUE); + + result = SOCKET_READABLE(sock, timeout); + + if(-1 == result) { + failf(conn->data, "SOCKS5 nothing to read"); + return CURLE_COULDNT_CONNECT; + } + if(0 == result) { + failf(conn->data, "SOCKS5 read timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + if(result & CURL_CSELECT_ERR) { + failf(conn->data, "SOCKS5 read error occurred"); + return CURLE_RECV_ERROR; + } + + (void)curlx_nonblock(sock, FALSE); + + result = Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread); + if(result || (actualread != 2)) { + failf(data, "Unable to receive initial SOCKS5 response."); + return CURLE_COULDNT_CONNECT; + } + + if(socksreq[0] != 5) { + failf(data, "Received invalid version in initial SOCKS5 response."); + return CURLE_COULDNT_CONNECT; + } + if(socksreq[1] == 0) { + /* Nothing to do, no authentication needed */ + ; + } +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + else if(allow_gssapi && (socksreq[1] == 1)) { + code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn); + if(code) { + failf(data, "Unable to negotiate SOCKS5 GSS-API context."); + return CURLE_COULDNT_CONNECT; + } + } +#endif + else if(socksreq[1] == 2) { + /* Needs user name and password */ + size_t proxy_user_len, proxy_password_len; + if(proxy_user && proxy_password) { + proxy_user_len = strlen(proxy_user); + proxy_password_len = strlen(proxy_password); + } + else { + proxy_user_len = 0; + proxy_password_len = 0; + } + + /* username/password request looks like + * +----+------+----------+------+----------+ + * |VER | ULEN | UNAME | PLEN | PASSWD | + * +----+------+----------+------+----------+ + * | 1 | 1 | 1 to 255 | 1 | 1 to 255 | + * +----+------+----------+------+----------+ + */ + len = 0; + socksreq[len++] = 1; /* username/pw subnegotiation version */ + socksreq[len++] = (unsigned char) proxy_user_len; + if(proxy_user && proxy_user_len) { + /* the length must fit in a single byte */ + if(proxy_user_len >= 255) { + failf(data, "Excessive user name length for proxy auth"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + memcpy(socksreq + len, proxy_user, proxy_user_len); + } + len += proxy_user_len; + socksreq[len++] = (unsigned char) proxy_password_len; + if(proxy_password && proxy_password_len) { + /* the length must fit in a single byte */ + if(proxy_password_len > 255) { + failf(data, "Excessive password length for proxy auth"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + memcpy(socksreq + len, proxy_password, proxy_password_len); + } + len += proxy_password_len; + + code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written); + if(code || (len != written)) { + failf(data, "Failed to send SOCKS5 sub-negotiation request."); + return CURLE_COULDNT_CONNECT; + } + + result = Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread); + if(result || (actualread != 2)) { + failf(data, "Unable to receive SOCKS5 sub-negotiation response."); + return CURLE_COULDNT_CONNECT; + } + + /* ignore the first (VER) byte */ + if(socksreq[1] != 0) { /* status */ + failf(data, "User was rejected by the SOCKS5 server (%d %d).", + socksreq[0], socksreq[1]); + return CURLE_COULDNT_CONNECT; + } + + /* Everything is good so far, user was authenticated! */ + } + else { + /* error */ + if(!allow_gssapi && (socksreq[1] == 1)) { + failf(data, + "SOCKS5 GSSAPI per-message authentication is not supported."); + return CURLE_COULDNT_CONNECT; + } + if(socksreq[1] == 255) { + if(!proxy_user || !*proxy_user) { + failf(data, + "No authentication method was acceptable. (It is quite likely" + " that the SOCKS5 server wanted a username/password, since none" + " was supplied to the server on this connection.)"); + } + else { + failf(data, "No authentication method was acceptable."); + } + return CURLE_COULDNT_CONNECT; + } + else { + failf(data, + "Undocumented SOCKS5 mode attempted to be used by server."); + return CURLE_COULDNT_CONNECT; + } + } + + /* Authentication is complete, now specify destination to the proxy */ + len = 0; + socksreq[len++] = 5; /* version (SOCKS5) */ + socksreq[len++] = 1; /* connect */ + socksreq[len++] = 0; /* must be zero */ + + if(!socks5_resolve_local) { + socksreq[len++] = 3; /* ATYP: domain name = 3 */ + socksreq[len++] = (char) hostname_len; /* address length */ + memcpy(&socksreq[len], hostname, hostname_len); /* address str w/o NULL */ + len += hostname_len; + } + else { + struct Curl_dns_entry *dns; + Curl_addrinfo *hp = NULL; + int rc = Curl_resolv(conn, hostname, remote_port, FALSE, &dns); + + if(rc == CURLRESOLV_ERROR) + return CURLE_COULDNT_RESOLVE_HOST; + + if(rc == CURLRESOLV_PENDING) { + /* this requires that we're in "wait for resolve" state */ + code = Curl_resolver_wait_resolv(conn, &dns); + if(code) + return code; + } + + /* + * We cannot use 'hostent' as a struct that Curl_resolv() returns. It + * returns a Curl_addrinfo pointer that may not always look the same. + */ + if(dns) + hp = dns->addr; + if(hp) { + char buf[64]; + Curl_printable_address(hp, buf, sizeof(buf)); + + if(hp->ai_family == AF_INET) { + int i; + struct sockaddr_in *saddr_in; + socksreq[len++] = 1; /* ATYP: IPv4 = 1 */ + + saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr; + for(i = 0; i < 4; i++) { + socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i]; + } + + infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)\n", buf); + } +#ifdef ENABLE_IPV6 + else if(hp->ai_family == AF_INET6) { + int i; + struct sockaddr_in6 *saddr_in6; + socksreq[len++] = 4; /* ATYP: IPv6 = 4 */ + + saddr_in6 = (struct sockaddr_in6 *)(void *)hp->ai_addr; + for(i = 0; i < 16; i++) { + socksreq[len++] = + ((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i]; + } + + infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)\n", buf); + } +#endif + else { + hp = NULL; /* fail! */ + + failf(data, "SOCKS5 connection to %s not supported\n", buf); + } + + Curl_resolv_unlock(data, dns); /* not used anymore from now on */ + } + if(!hp) { + failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.", + hostname); + return CURLE_COULDNT_RESOLVE_HOST; + } + } + + socksreq[len++] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */ + socksreq[len++] = (unsigned char)(remote_port & 0xff); /* PORT LSB */ + +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + if(conn->socks5_gssapi_enctype) { + failf(data, "SOCKS5 GSS-API protection not yet implemented."); + } + else +#endif + code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written); + + if(code || (len != written)) { + failf(data, "Failed to send SOCKS5 connect request."); + return CURLE_COULDNT_CONNECT; + } + + len = 10; /* minimum packet size is 10 */ + +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + if(conn->socks5_gssapi_enctype) { + failf(data, "SOCKS5 GSS-API protection not yet implemented."); + } + else +#endif + result = Curl_blockread_all(conn, sock, (char *)socksreq, + len, &actualread); + + if(result || (len != actualread)) { + failf(data, "Failed to receive SOCKS5 connect request ack."); + return CURLE_COULDNT_CONNECT; + } + + if(socksreq[0] != 5) { /* version */ + failf(data, + "SOCKS5 reply has wrong version, version should be 5."); + return CURLE_COULDNT_CONNECT; + } + + /* Fix: in general, returned BND.ADDR is variable length parameter by RFC + 1928, so the reply packet should be read until the end to avoid errors at + subsequent protocol level. + + +----+-----+-------+------+----------+----------+ + |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | + +----+-----+-------+------+----------+----------+ + | 1 | 1 | X'00' | 1 | Variable | 2 | + +----+-----+-------+------+----------+----------+ + + ATYP: + o IP v4 address: X'01', BND.ADDR = 4 byte + o domain name: X'03', BND.ADDR = [ 1 byte length, string ] + o IP v6 address: X'04', BND.ADDR = 16 byte + */ + + /* Calculate real packet size */ + if(socksreq[3] == 3) { + /* domain name */ + int addrlen = (int) socksreq[4]; + len = 5 + addrlen + 2; + } + else if(socksreq[3] == 4) { + /* IPv6 */ + len = 4 + 16 + 2; + } + + /* At this point we already read first 10 bytes */ +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + if(!conn->socks5_gssapi_enctype) { + /* decrypt_gssapi_blockread already read the whole packet */ +#endif + if(len > 10) { + result = Curl_blockread_all(conn, sock, (char *)&socksreq[10], + len - 10, &actualread); + if(result || ((len - 10) != actualread)) { + failf(data, "Failed to receive SOCKS5 connect request ack."); + return CURLE_COULDNT_CONNECT; + } + } +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + } +#endif + + if(socksreq[1] != 0) { /* Anything besides 0 is an error */ + if(socksreq[3] == 1) { + failf(data, + "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)", + (unsigned char)socksreq[4], (unsigned char)socksreq[5], + (unsigned char)socksreq[6], (unsigned char)socksreq[7], + (((unsigned char)socksreq[8] << 8) | + (unsigned char)socksreq[9]), + (unsigned char)socksreq[1]); + } + else if(socksreq[3] == 3) { + unsigned char port_upper = (unsigned char)socksreq[len - 2]; + socksreq[len - 2] = 0; + failf(data, + "Can't complete SOCKS5 connection to %s:%d. (%d)", + (char *)&socksreq[5], + ((port_upper << 8) | + (unsigned char)socksreq[len - 1]), + (unsigned char)socksreq[1]); + socksreq[len - 2] = port_upper; + } + else if(socksreq[3] == 4) { + failf(data, + "Can't complete SOCKS5 connection to %02x%02x:%02x%02x:" + "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)", + (unsigned char)socksreq[4], (unsigned char)socksreq[5], + (unsigned char)socksreq[6], (unsigned char)socksreq[7], + (unsigned char)socksreq[8], (unsigned char)socksreq[9], + (unsigned char)socksreq[10], (unsigned char)socksreq[11], + (unsigned char)socksreq[12], (unsigned char)socksreq[13], + (unsigned char)socksreq[14], (unsigned char)socksreq[15], + (unsigned char)socksreq[16], (unsigned char)socksreq[17], + (unsigned char)socksreq[18], (unsigned char)socksreq[19], + (((unsigned char)socksreq[20] << 8) | + (unsigned char)socksreq[21]), + (unsigned char)socksreq[1]); + } + return CURLE_COULDNT_CONNECT; + } + infof(data, "SOCKS5 request granted.\n"); + + (void)curlx_nonblock(sock, TRUE); + return CURLE_OK; /* Proxy was successful! */ +} + +#endif /* CURL_DISABLE_PROXY */ diff --git a/libcurl/lib/socks.h b/libcurl/lib/socks.h new file mode 100644 index 0000000..daa07c1 --- /dev/null +++ b/libcurl/lib/socks.h @@ -0,0 +1,75 @@ +#ifndef HEADER_CURL_SOCKS_H +#define HEADER_CURL_SOCKS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef CURL_DISABLE_PROXY +#define Curl_SOCKS4(a,b,c,d,e) CURLE_NOT_BUILT_IN +#define Curl_SOCKS5(a,b,c,d,e,f) CURLE_NOT_BUILT_IN +#else +/* + * Helper read-from-socket functions. Does the same as Curl_read() but it + * blocks until all bytes amount of buffersize will be read. No more, no less. + * + * This is STUPID BLOCKING behaviour which we frown upon, but right now this + * is what we have... + */ +int Curl_blockread_all(struct connectdata *conn, + curl_socket_t sockfd, + char *buf, + ssize_t buffersize, + ssize_t *n); + +/* + * This function logs in to a SOCKS4(a) proxy and sends the specifics to the + * final destination server. + */ +CURLcode Curl_SOCKS4(const char *proxy_name, + const char *hostname, + int remote_port, + int sockindex, + struct connectdata *conn); + +/* + * This function logs in to a SOCKS5 proxy and sends the specifics to the + * final destination server. + */ +CURLcode Curl_SOCKS5(const char *proxy_name, + const char *proxy_password, + const char *hostname, + int remote_port, + int sockindex, + struct connectdata *conn); + +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) +/* + * This function handles the SOCKS5 GSS-API negotiation and initialisation + */ +CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, + struct connectdata *conn); +#endif + +#endif /* CURL_DISABLE_PROXY */ + +#endif /* HEADER_CURL_SOCKS_H */ diff --git a/libcurl/lib/socks_gssapi.c b/libcurl/lib/socks_gssapi.c new file mode 100644 index 0000000..65294bb --- /dev/null +++ b/libcurl/lib/socks_gssapi.c @@ -0,0 +1,527 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2009, Markus Moeller, + * Copyright (C) 2012 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_PROXY) + +#include "curl_gssapi.h" +#include "urldata.h" +#include "sendf.h" +#include "connect.h" +#include "timeval.h" +#include "socks.h" +#include "warnless.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +static gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT; + +/* + * Helper GSS-API error functions. + */ +static int check_gss_err(struct Curl_easy *data, + OM_uint32 major_status, + OM_uint32 minor_status, + const char *function) +{ + if(GSS_ERROR(major_status)) { + OM_uint32 maj_stat, min_stat; + OM_uint32 msg_ctx = 0; + gss_buffer_desc status_string; + char buf[1024]; + size_t len; + + len = 0; + msg_ctx = 0; + while(!msg_ctx) { + /* convert major status code (GSS-API error) to text */ + maj_stat = gss_display_status(&min_stat, major_status, + GSS_C_GSS_CODE, + GSS_C_NULL_OID, + &msg_ctx, &status_string); + if(maj_stat == GSS_S_COMPLETE) { + if(sizeof(buf) > len + status_string.length + 1) { + strcpy(buf + len, (char *) status_string.value); + len += status_string.length; + } + gss_release_buffer(&min_stat, &status_string); + break; + } + gss_release_buffer(&min_stat, &status_string); + } + if(sizeof(buf) > len + 3) { + strcpy(buf + len, ".\n"); + len += 2; + } + msg_ctx = 0; + while(!msg_ctx) { + /* convert minor status code (underlying routine error) to text */ + maj_stat = gss_display_status(&min_stat, minor_status, + GSS_C_MECH_CODE, + GSS_C_NULL_OID, + &msg_ctx, &status_string); + if(maj_stat == GSS_S_COMPLETE) { + if(sizeof(buf) > len + status_string.length) + strcpy(buf + len, (char *) status_string.value); + gss_release_buffer(&min_stat, &status_string); + break; + } + gss_release_buffer(&min_stat, &status_string); + } + failf(data, "GSS-API error: %s failed:\n%s", function, buf); + return 1; + } + + return 0; +} + +CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, + struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + curl_socket_t sock = conn->sock[sockindex]; + CURLcode code; + ssize_t actualread; + ssize_t written; + int result; + OM_uint32 gss_major_status, gss_minor_status, gss_status; + OM_uint32 gss_ret_flags; + int gss_conf_state, gss_enc; + gss_buffer_desc service = GSS_C_EMPTY_BUFFER; + gss_buffer_desc gss_send_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc gss_recv_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc gss_w_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc* gss_token = GSS_C_NO_BUFFER; + gss_name_t server = GSS_C_NO_NAME; + gss_name_t gss_client_name = GSS_C_NO_NAME; + unsigned short us_length; + char *user = NULL; + unsigned char socksreq[4]; /* room for GSS-API exchange header only */ + const char *serviceptr = data->set.str[STRING_PROXY_SERVICE_NAME] ? + data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd"; + const size_t serviceptr_length = strlen(serviceptr); + + /* GSS-API request looks like + * +----+------+-----+----------------+ + * |VER | MTYP | LEN | TOKEN | + * +----+------+----------------------+ + * | 1 | 1 | 2 | up to 2^16 - 1 | + * +----+------+-----+----------------+ + */ + + /* prepare service name */ + if(strchr(serviceptr, '/')) { + service.length = serviceptr_length; + service.value = malloc(service.length); + if(!service.value) + return CURLE_OUT_OF_MEMORY; + memcpy(service.value, serviceptr, service.length); + + gss_major_status = gss_import_name(&gss_minor_status, &service, + (gss_OID) GSS_C_NULL_OID, &server); + } + else { + service.value = malloc(serviceptr_length + + strlen(conn->socks_proxy.host.name) + 2); + if(!service.value) + return CURLE_OUT_OF_MEMORY; + service.length = serviceptr_length + + strlen(conn->socks_proxy.host.name) + 1; + msnprintf(service.value, service.length + 1, "%s@%s", + serviceptr, conn->socks_proxy.host.name); + + gss_major_status = gss_import_name(&gss_minor_status, &service, + GSS_C_NT_HOSTBASED_SERVICE, &server); + } + + gss_release_buffer(&gss_status, &service); /* clear allocated memory */ + + if(check_gss_err(data, gss_major_status, + gss_minor_status, "gss_import_name()")) { + failf(data, "Failed to create service name."); + gss_release_name(&gss_status, &server); + return CURLE_COULDNT_CONNECT; + } + + /* As long as we need to keep sending some context info, and there's no */ + /* errors, keep sending it... */ + for(;;) { + gss_major_status = Curl_gss_init_sec_context(data, + &gss_minor_status, + &gss_context, + server, + &Curl_krb5_mech_oid, + NULL, + gss_token, + &gss_send_token, + TRUE, + &gss_ret_flags); + + if(gss_token != GSS_C_NO_BUFFER) + gss_release_buffer(&gss_status, &gss_recv_token); + if(check_gss_err(data, gss_major_status, + gss_minor_status, "gss_init_sec_context")) { + gss_release_name(&gss_status, &server); + gss_release_buffer(&gss_status, &gss_recv_token); + gss_release_buffer(&gss_status, &gss_send_token); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + failf(data, "Failed to initial GSS-API token."); + return CURLE_COULDNT_CONNECT; + } + + if(gss_send_token.length != 0) { + socksreq[0] = 1; /* GSS-API subnegotiation version */ + socksreq[1] = 1; /* authentication message type */ + us_length = htons((short)gss_send_token.length); + memcpy(socksreq + 2, &us_length, sizeof(short)); + + code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written); + if(code || (4 != written)) { + failf(data, "Failed to send GSS-API authentication request."); + gss_release_name(&gss_status, &server); + gss_release_buffer(&gss_status, &gss_recv_token); + gss_release_buffer(&gss_status, &gss_send_token); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + code = Curl_write_plain(conn, sock, (char *)gss_send_token.value, + gss_send_token.length, &written); + + if(code || ((ssize_t)gss_send_token.length != written)) { + failf(data, "Failed to send GSS-API authentication token."); + gss_release_name(&gss_status, &server); + gss_release_buffer(&gss_status, &gss_recv_token); + gss_release_buffer(&gss_status, &gss_send_token); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + } + + gss_release_buffer(&gss_status, &gss_send_token); + gss_release_buffer(&gss_status, &gss_recv_token); + if(gss_major_status != GSS_S_CONTINUE_NEEDED) break; + + /* analyse response */ + + /* GSS-API response looks like + * +----+------+-----+----------------+ + * |VER | MTYP | LEN | TOKEN | + * +----+------+----------------------+ + * | 1 | 1 | 2 | up to 2^16 - 1 | + * +----+------+-----+----------------+ + */ + + result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread); + if(result || (actualread != 4)) { + failf(data, "Failed to receive GSS-API authentication response."); + gss_release_name(&gss_status, &server); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + /* ignore the first (VER) byte */ + if(socksreq[1] == 255) { /* status / message type */ + failf(data, "User was rejected by the SOCKS5 server (%d %d).", + socksreq[0], socksreq[1]); + gss_release_name(&gss_status, &server); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + if(socksreq[1] != 1) { /* status / messgae type */ + failf(data, "Invalid GSS-API authentication response type (%d %d).", + socksreq[0], socksreq[1]); + gss_release_name(&gss_status, &server); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + memcpy(&us_length, socksreq + 2, sizeof(short)); + us_length = ntohs(us_length); + + gss_recv_token.length = us_length; + gss_recv_token.value = malloc(us_length); + if(!gss_recv_token.value) { + failf(data, + "Could not allocate memory for GSS-API authentication " + "response token."); + gss_release_name(&gss_status, &server); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_OUT_OF_MEMORY; + } + + result = Curl_blockread_all(conn, sock, (char *)gss_recv_token.value, + gss_recv_token.length, &actualread); + + if(result || (actualread != us_length)) { + failf(data, "Failed to receive GSS-API authentication token."); + gss_release_name(&gss_status, &server); + gss_release_buffer(&gss_status, &gss_recv_token); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + gss_token = &gss_recv_token; + } + + gss_release_name(&gss_status, &server); + + /* Everything is good so far, user was authenticated! */ + gss_major_status = gss_inquire_context(&gss_minor_status, gss_context, + &gss_client_name, NULL, NULL, NULL, + NULL, NULL, NULL); + if(check_gss_err(data, gss_major_status, + gss_minor_status, "gss_inquire_context")) { + gss_delete_sec_context(&gss_status, &gss_context, NULL); + gss_release_name(&gss_status, &gss_client_name); + failf(data, "Failed to determine user name."); + return CURLE_COULDNT_CONNECT; + } + gss_major_status = gss_display_name(&gss_minor_status, gss_client_name, + &gss_send_token, NULL); + if(check_gss_err(data, gss_major_status, + gss_minor_status, "gss_display_name")) { + gss_delete_sec_context(&gss_status, &gss_context, NULL); + gss_release_name(&gss_status, &gss_client_name); + gss_release_buffer(&gss_status, &gss_send_token); + failf(data, "Failed to determine user name."); + return CURLE_COULDNT_CONNECT; + } + user = malloc(gss_send_token.length + 1); + if(!user) { + gss_delete_sec_context(&gss_status, &gss_context, NULL); + gss_release_name(&gss_status, &gss_client_name); + gss_release_buffer(&gss_status, &gss_send_token); + return CURLE_OUT_OF_MEMORY; + } + + memcpy(user, gss_send_token.value, gss_send_token.length); + user[gss_send_token.length] = '\0'; + gss_release_name(&gss_status, &gss_client_name); + gss_release_buffer(&gss_status, &gss_send_token); + infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",user); + free(user); + user = NULL; + + /* Do encryption */ + socksreq[0] = 1; /* GSS-API subnegotiation version */ + socksreq[1] = 2; /* encryption message type */ + + gss_enc = 0; /* no data protection */ + /* do confidentiality protection if supported */ + if(gss_ret_flags & GSS_C_CONF_FLAG) + gss_enc = 2; + /* else do integrity protection */ + else if(gss_ret_flags & GSS_C_INTEG_FLAG) + gss_enc = 1; + + infof(data, "SOCKS5 server supports GSS-API %s data protection.\n", + (gss_enc == 0)?"no":((gss_enc==1)?"integrity":"confidentiality")); + /* force for the moment to no data protection */ + gss_enc = 0; + /* + * Sending the encryption type in clear seems wrong. It should be + * protected with gss_seal()/gss_wrap(). See RFC1961 extract below + * The NEC reference implementations on which this is based is + * therefore at fault + * + * +------+------+------+.......................+ + * + ver | mtyp | len | token | + * +------+------+------+.......................+ + * + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets | + * +------+------+------+.......................+ + * + * Where: + * + * - "ver" is the protocol version number, here 1 to represent the + * first version of the SOCKS/GSS-API protocol + * + * - "mtyp" is the message type, here 2 to represent a protection + * -level negotiation message + * + * - "len" is the length of the "token" field in octets + * + * - "token" is the GSS-API encapsulated protection level + * + * The token is produced by encapsulating an octet containing the + * required protection level using gss_seal()/gss_wrap() with conf_req + * set to FALSE. The token is verified using gss_unseal()/ + * gss_unwrap(). + * + */ + if(data->set.socks5_gssapi_nec) { + us_length = htons((short)1); + memcpy(socksreq + 2, &us_length, sizeof(short)); + } + else { + gss_send_token.length = 1; + gss_send_token.value = malloc(1); + if(!gss_send_token.value) { + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_OUT_OF_MEMORY; + } + memcpy(gss_send_token.value, &gss_enc, 1); + + gss_major_status = gss_wrap(&gss_minor_status, gss_context, 0, + GSS_C_QOP_DEFAULT, &gss_send_token, + &gss_conf_state, &gss_w_token); + + if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_wrap")) { + gss_release_buffer(&gss_status, &gss_send_token); + gss_release_buffer(&gss_status, &gss_w_token); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + failf(data, "Failed to wrap GSS-API encryption value into token."); + return CURLE_COULDNT_CONNECT; + } + gss_release_buffer(&gss_status, &gss_send_token); + + us_length = htons((short)gss_w_token.length); + memcpy(socksreq + 2, &us_length, sizeof(short)); + } + + code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written); + if(code || (4 != written)) { + failf(data, "Failed to send GSS-API encryption request."); + gss_release_buffer(&gss_status, &gss_w_token); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + if(data->set.socks5_gssapi_nec) { + memcpy(socksreq, &gss_enc, 1); + code = Curl_write_plain(conn, sock, socksreq, 1, &written); + if(code || ( 1 != written)) { + failf(data, "Failed to send GSS-API encryption type."); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + } + else { + code = Curl_write_plain(conn, sock, (char *)gss_w_token.value, + gss_w_token.length, &written); + if(code || ((ssize_t)gss_w_token.length != written)) { + failf(data, "Failed to send GSS-API encryption type."); + gss_release_buffer(&gss_status, &gss_w_token); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + gss_release_buffer(&gss_status, &gss_w_token); + } + + result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread); + if(result || (actualread != 4)) { + failf(data, "Failed to receive GSS-API encryption response."); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + /* ignore the first (VER) byte */ + if(socksreq[1] == 255) { /* status / message type */ + failf(data, "User was rejected by the SOCKS5 server (%d %d).", + socksreq[0], socksreq[1]); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + if(socksreq[1] != 2) { /* status / messgae type */ + failf(data, "Invalid GSS-API encryption response type (%d %d).", + socksreq[0], socksreq[1]); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + memcpy(&us_length, socksreq + 2, sizeof(short)); + us_length = ntohs(us_length); + + gss_recv_token.length = us_length; + gss_recv_token.value = malloc(gss_recv_token.length); + if(!gss_recv_token.value) { + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_OUT_OF_MEMORY; + } + result = Curl_blockread_all(conn, sock, (char *)gss_recv_token.value, + gss_recv_token.length, &actualread); + + if(result || (actualread != us_length)) { + failf(data, "Failed to receive GSS-API encryptrion type."); + gss_release_buffer(&gss_status, &gss_recv_token); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + if(!data->set.socks5_gssapi_nec) { + gss_major_status = gss_unwrap(&gss_minor_status, gss_context, + &gss_recv_token, &gss_w_token, + 0, GSS_C_QOP_DEFAULT); + + if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_unwrap")) { + gss_release_buffer(&gss_status, &gss_recv_token); + gss_release_buffer(&gss_status, &gss_w_token); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + failf(data, "Failed to unwrap GSS-API encryption value into token."); + return CURLE_COULDNT_CONNECT; + } + gss_release_buffer(&gss_status, &gss_recv_token); + + if(gss_w_token.length != 1) { + failf(data, "Invalid GSS-API encryption response length (%d).", + gss_w_token.length); + gss_release_buffer(&gss_status, &gss_w_token); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + memcpy(socksreq, gss_w_token.value, gss_w_token.length); + gss_release_buffer(&gss_status, &gss_w_token); + } + else { + if(gss_recv_token.length != 1) { + failf(data, "Invalid GSS-API encryption response length (%d).", + gss_recv_token.length); + gss_release_buffer(&gss_status, &gss_recv_token); + gss_delete_sec_context(&gss_status, &gss_context, NULL); + return CURLE_COULDNT_CONNECT; + } + + memcpy(socksreq, gss_recv_token.value, gss_recv_token.length); + gss_release_buffer(&gss_status, &gss_recv_token); + } + + infof(data, "SOCKS5 access with%s protection granted.\n", + (socksreq[0] == 0)?"out GSS-API data": + ((socksreq[0] == 1)?" GSS-API integrity":" GSS-API confidentiality")); + + conn->socks5_gssapi_enctype = socksreq[0]; + if(socksreq[0] == 0) + gss_delete_sec_context(&gss_status, &gss_context, NULL); + + return CURLE_OK; +} + +#endif /* HAVE_GSSAPI && !CURL_DISABLE_PROXY */ diff --git a/libcurl/lib/socks_sspi.c b/libcurl/lib/socks_sspi.c new file mode 100644 index 0000000..57027ef --- /dev/null +++ b/libcurl/lib/socks_sspi.c @@ -0,0 +1,606 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 2009, 2011, Markus Moeller, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_PROXY) + +#include "urldata.h" +#include "sendf.h" +#include "connect.h" +#include "strerror.h" +#include "timeval.h" +#include "socks.h" +#include "curl_sspi.h" +#include "curl_multibyte.h" +#include "warnless.h" +#include "strdup.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Helper sspi error functions. + */ +static int check_sspi_err(struct connectdata *conn, + SECURITY_STATUS status, + const char *function) +{ + if(status != SEC_E_OK && + status != SEC_I_COMPLETE_AND_CONTINUE && + status != SEC_I_COMPLETE_NEEDED && + status != SEC_I_CONTINUE_NEEDED) { + char buffer[STRERROR_LEN]; + failf(conn->data, "SSPI error: %s failed: %s", function, + Curl_sspi_strerror(status, buffer, sizeof(buffer))); + return 1; + } + return 0; +} + +/* This is the SSPI-using version of this function */ +CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, + struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + curl_socket_t sock = conn->sock[sockindex]; + CURLcode code; + ssize_t actualread; + ssize_t written; + int result; + /* Needs GSS-API authentication */ + SECURITY_STATUS status; + unsigned long sspi_ret_flags = 0; + unsigned char gss_enc; + SecBuffer sspi_send_token, sspi_recv_token, sspi_w_token[3]; + SecBufferDesc input_desc, output_desc, wrap_desc; + SecPkgContext_Sizes sspi_sizes; + CredHandle cred_handle; + CtxtHandle sspi_context; + PCtxtHandle context_handle = NULL; + SecPkgCredentials_Names names; + TimeStamp expiry; + char *service_name = NULL; + unsigned short us_length; + unsigned long qop; + unsigned char socksreq[4]; /* room for GSS-API exchange header only */ + const char *service = data->set.str[STRING_PROXY_SERVICE_NAME] ? + data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd"; + const size_t service_length = strlen(service); + + /* GSS-API request looks like + * +----+------+-----+----------------+ + * |VER | MTYP | LEN | TOKEN | + * +----+------+----------------------+ + * | 1 | 1 | 2 | up to 2^16 - 1 | + * +----+------+-----+----------------+ + */ + + /* prepare service name */ + if(strchr(service, '/')) { + service_name = strdup(service); + if(!service_name) + return CURLE_OUT_OF_MEMORY; + } + else { + service_name = malloc(service_length + + strlen(conn->socks_proxy.host.name) + 2); + if(!service_name) + return CURLE_OUT_OF_MEMORY; + msnprintf(service_name, service_length + + strlen(conn->socks_proxy.host.name) + 2, "%s/%s", + service, conn->socks_proxy.host.name); + } + + input_desc.cBuffers = 1; + input_desc.pBuffers = &sspi_recv_token; + input_desc.ulVersion = SECBUFFER_VERSION; + + sspi_recv_token.BufferType = SECBUFFER_TOKEN; + sspi_recv_token.cbBuffer = 0; + sspi_recv_token.pvBuffer = NULL; + + output_desc.cBuffers = 1; + output_desc.pBuffers = &sspi_send_token; + output_desc.ulVersion = SECBUFFER_VERSION; + + sspi_send_token.BufferType = SECBUFFER_TOKEN; + sspi_send_token.cbBuffer = 0; + sspi_send_token.pvBuffer = NULL; + + wrap_desc.cBuffers = 3; + wrap_desc.pBuffers = sspi_w_token; + wrap_desc.ulVersion = SECBUFFER_VERSION; + + cred_handle.dwLower = 0; + cred_handle.dwUpper = 0; + + status = s_pSecFn->AcquireCredentialsHandle(NULL, + (TCHAR *) TEXT("Kerberos"), + SECPKG_CRED_OUTBOUND, + NULL, + NULL, + NULL, + NULL, + &cred_handle, + &expiry); + + if(check_sspi_err(conn, status, "AcquireCredentialsHandle")) { + failf(data, "Failed to acquire credentials."); + free(service_name); + s_pSecFn->FreeCredentialsHandle(&cred_handle); + return CURLE_COULDNT_CONNECT; + } + + /* As long as we need to keep sending some context info, and there's no */ + /* errors, keep sending it... */ + for(;;) { + TCHAR *sname; + + sname = Curl_convert_UTF8_to_tchar(service_name); + if(!sname) + return CURLE_OUT_OF_MEMORY; + + status = s_pSecFn->InitializeSecurityContext(&cred_handle, + context_handle, + sname, + ISC_REQ_MUTUAL_AUTH | + ISC_REQ_ALLOCATE_MEMORY | + ISC_REQ_CONFIDENTIALITY | + ISC_REQ_REPLAY_DETECT, + 0, + SECURITY_NATIVE_DREP, + &input_desc, + 0, + &sspi_context, + &output_desc, + &sspi_ret_flags, + &expiry); + + Curl_unicodefree(sname); + + if(sspi_recv_token.pvBuffer) { + s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); + sspi_recv_token.pvBuffer = NULL; + sspi_recv_token.cbBuffer = 0; + } + + if(check_sspi_err(conn, status, "InitializeSecurityContext")) { + free(service_name); + s_pSecFn->FreeCredentialsHandle(&cred_handle); + s_pSecFn->DeleteSecurityContext(&sspi_context); + if(sspi_recv_token.pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); + failf(data, "Failed to initialise security context."); + return CURLE_COULDNT_CONNECT; + } + + if(sspi_send_token.cbBuffer != 0) { + socksreq[0] = 1; /* GSS-API subnegotiation version */ + socksreq[1] = 1; /* authentication message type */ + us_length = htons((short)sspi_send_token.cbBuffer); + memcpy(socksreq + 2, &us_length, sizeof(short)); + + code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written); + if(code || (4 != written)) { + failf(data, "Failed to send SSPI authentication request."); + free(service_name); + if(sspi_send_token.pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); + if(sspi_recv_token.pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); + s_pSecFn->FreeCredentialsHandle(&cred_handle); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + + code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer, + sspi_send_token.cbBuffer, &written); + if(code || (sspi_send_token.cbBuffer != (size_t)written)) { + failf(data, "Failed to send SSPI authentication token."); + free(service_name); + if(sspi_send_token.pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); + if(sspi_recv_token.pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); + s_pSecFn->FreeCredentialsHandle(&cred_handle); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + + } + + if(sspi_send_token.pvBuffer) { + s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); + sspi_send_token.pvBuffer = NULL; + } + sspi_send_token.cbBuffer = 0; + + if(sspi_recv_token.pvBuffer) { + s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); + sspi_recv_token.pvBuffer = NULL; + } + sspi_recv_token.cbBuffer = 0; + + if(status != SEC_I_CONTINUE_NEEDED) + break; + + /* analyse response */ + + /* GSS-API response looks like + * +----+------+-----+----------------+ + * |VER | MTYP | LEN | TOKEN | + * +----+------+----------------------+ + * | 1 | 1 | 2 | up to 2^16 - 1 | + * +----+------+-----+----------------+ + */ + + result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread); + if(result || (actualread != 4)) { + failf(data, "Failed to receive SSPI authentication response."); + free(service_name); + s_pSecFn->FreeCredentialsHandle(&cred_handle); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + + /* ignore the first (VER) byte */ + if(socksreq[1] == 255) { /* status / message type */ + failf(data, "User was rejected by the SOCKS5 server (%u %u).", + (unsigned int)socksreq[0], (unsigned int)socksreq[1]); + free(service_name); + s_pSecFn->FreeCredentialsHandle(&cred_handle); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + + if(socksreq[1] != 1) { /* status / messgae type */ + failf(data, "Invalid SSPI authentication response type (%u %u).", + (unsigned int)socksreq[0], (unsigned int)socksreq[1]); + free(service_name); + s_pSecFn->FreeCredentialsHandle(&cred_handle); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + + memcpy(&us_length, socksreq + 2, sizeof(short)); + us_length = ntohs(us_length); + + sspi_recv_token.cbBuffer = us_length; + sspi_recv_token.pvBuffer = malloc(us_length); + + if(!sspi_recv_token.pvBuffer) { + free(service_name); + s_pSecFn->FreeCredentialsHandle(&cred_handle); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_OUT_OF_MEMORY; + } + result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer, + sspi_recv_token.cbBuffer, &actualread); + + if(result || (actualread != us_length)) { + failf(data, "Failed to receive SSPI authentication token."); + free(service_name); + if(sspi_recv_token.pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); + s_pSecFn->FreeCredentialsHandle(&cred_handle); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + + context_handle = &sspi_context; + } + + free(service_name); + + /* Everything is good so far, user was authenticated! */ + status = s_pSecFn->QueryCredentialsAttributes(&cred_handle, + SECPKG_CRED_ATTR_NAMES, + &names); + s_pSecFn->FreeCredentialsHandle(&cred_handle); + if(check_sspi_err(conn, status, "QueryCredentialAttributes")) { + s_pSecFn->DeleteSecurityContext(&sspi_context); + s_pSecFn->FreeContextBuffer(names.sUserName); + failf(data, "Failed to determine user name."); + return CURLE_COULDNT_CONNECT; + } + infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n", + names.sUserName); + s_pSecFn->FreeContextBuffer(names.sUserName); + + /* Do encryption */ + socksreq[0] = 1; /* GSS-API subnegotiation version */ + socksreq[1] = 2; /* encryption message type */ + + gss_enc = 0; /* no data protection */ + /* do confidentiality protection if supported */ + if(sspi_ret_flags & ISC_REQ_CONFIDENTIALITY) + gss_enc = 2; + /* else do integrity protection */ + else if(sspi_ret_flags & ISC_REQ_INTEGRITY) + gss_enc = 1; + + infof(data, "SOCKS5 server supports GSS-API %s data protection.\n", + (gss_enc == 0)?"no":((gss_enc == 1)?"integrity":"confidentiality") ); + /* force to no data protection, avoid encryption/decryption for now */ + gss_enc = 0; + /* + * Sending the encryption type in clear seems wrong. It should be + * protected with gss_seal()/gss_wrap(). See RFC1961 extract below + * The NEC reference implementations on which this is based is + * therefore at fault + * + * +------+------+------+.......................+ + * + ver | mtyp | len | token | + * +------+------+------+.......................+ + * + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets | + * +------+------+------+.......................+ + * + * Where: + * + * - "ver" is the protocol version number, here 1 to represent the + * first version of the SOCKS/GSS-API protocol + * + * - "mtyp" is the message type, here 2 to represent a protection + * -level negotiation message + * + * - "len" is the length of the "token" field in octets + * + * - "token" is the GSS-API encapsulated protection level + * + * The token is produced by encapsulating an octet containing the + * required protection level using gss_seal()/gss_wrap() with conf_req + * set to FALSE. The token is verified using gss_unseal()/ + * gss_unwrap(). + * + */ + + if(data->set.socks5_gssapi_nec) { + us_length = htons((short)1); + memcpy(socksreq + 2, &us_length, sizeof(short)); + } + else { + status = s_pSecFn->QueryContextAttributes(&sspi_context, + SECPKG_ATTR_SIZES, + &sspi_sizes); + if(check_sspi_err(conn, status, "QueryContextAttributes")) { + s_pSecFn->DeleteSecurityContext(&sspi_context); + failf(data, "Failed to query security context attributes."); + return CURLE_COULDNT_CONNECT; + } + + sspi_w_token[0].cbBuffer = sspi_sizes.cbSecurityTrailer; + sspi_w_token[0].BufferType = SECBUFFER_TOKEN; + sspi_w_token[0].pvBuffer = malloc(sspi_sizes.cbSecurityTrailer); + + if(!sspi_w_token[0].pvBuffer) { + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_OUT_OF_MEMORY; + } + + sspi_w_token[1].cbBuffer = 1; + sspi_w_token[1].pvBuffer = malloc(1); + if(!sspi_w_token[1].pvBuffer) { + s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_OUT_OF_MEMORY; + } + + memcpy(sspi_w_token[1].pvBuffer, &gss_enc, 1); + sspi_w_token[2].BufferType = SECBUFFER_PADDING; + sspi_w_token[2].cbBuffer = sspi_sizes.cbBlockSize; + sspi_w_token[2].pvBuffer = malloc(sspi_sizes.cbBlockSize); + if(!sspi_w_token[2].pvBuffer) { + s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_OUT_OF_MEMORY; + } + status = s_pSecFn->EncryptMessage(&sspi_context, + KERB_WRAP_NO_ENCRYPT, + &wrap_desc, + 0); + if(check_sspi_err(conn, status, "EncryptMessage")) { + s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer); + s_pSecFn->DeleteSecurityContext(&sspi_context); + failf(data, "Failed to query security context attributes."); + return CURLE_COULDNT_CONNECT; + } + sspi_send_token.cbBuffer = sspi_w_token[0].cbBuffer + + sspi_w_token[1].cbBuffer + + sspi_w_token[2].cbBuffer; + sspi_send_token.pvBuffer = malloc(sspi_send_token.cbBuffer); + if(!sspi_send_token.pvBuffer) { + s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_OUT_OF_MEMORY; + } + + memcpy(sspi_send_token.pvBuffer, sspi_w_token[0].pvBuffer, + sspi_w_token[0].cbBuffer); + memcpy((PUCHAR) sspi_send_token.pvBuffer +(int)sspi_w_token[0].cbBuffer, + sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer); + memcpy((PUCHAR) sspi_send_token.pvBuffer + + sspi_w_token[0].cbBuffer + + sspi_w_token[1].cbBuffer, + sspi_w_token[2].pvBuffer, sspi_w_token[2].cbBuffer); + + s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + sspi_w_token[0].pvBuffer = NULL; + sspi_w_token[0].cbBuffer = 0; + s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + sspi_w_token[1].pvBuffer = NULL; + sspi_w_token[1].cbBuffer = 0; + s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer); + sspi_w_token[2].pvBuffer = NULL; + sspi_w_token[2].cbBuffer = 0; + + us_length = htons((short)sspi_send_token.cbBuffer); + memcpy(socksreq + 2, &us_length, sizeof(short)); + } + + code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written); + if(code || (4 != written)) { + failf(data, "Failed to send SSPI encryption request."); + if(sspi_send_token.pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + + if(data->set.socks5_gssapi_nec) { + memcpy(socksreq, &gss_enc, 1); + code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written); + if(code || (1 != written)) { + failf(data, "Failed to send SSPI encryption type."); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + } + else { + code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer, + sspi_send_token.cbBuffer, &written); + if(code || (sspi_send_token.cbBuffer != (size_t)written)) { + failf(data, "Failed to send SSPI encryption type."); + if(sspi_send_token.pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + if(sspi_send_token.pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); + } + + result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread); + if(result || (actualread != 4)) { + failf(data, "Failed to receive SSPI encryption response."); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + + /* ignore the first (VER) byte */ + if(socksreq[1] == 255) { /* status / message type */ + failf(data, "User was rejected by the SOCKS5 server (%u %u).", + (unsigned int)socksreq[0], (unsigned int)socksreq[1]); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + + if(socksreq[1] != 2) { /* status / message type */ + failf(data, "Invalid SSPI encryption response type (%u %u).", + (unsigned int)socksreq[0], (unsigned int)socksreq[1]); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + + memcpy(&us_length, socksreq + 2, sizeof(short)); + us_length = ntohs(us_length); + + sspi_w_token[0].cbBuffer = us_length; + sspi_w_token[0].pvBuffer = malloc(us_length); + if(!sspi_w_token[0].pvBuffer) { + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_OUT_OF_MEMORY; + } + + result = Curl_blockread_all(conn, sock, (char *)sspi_w_token[0].pvBuffer, + sspi_w_token[0].cbBuffer, &actualread); + + if(result || (actualread != us_length)) { + failf(data, "Failed to receive SSPI encryption type."); + s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + + + if(!data->set.socks5_gssapi_nec) { + wrap_desc.cBuffers = 2; + sspi_w_token[0].BufferType = SECBUFFER_STREAM; + sspi_w_token[1].BufferType = SECBUFFER_DATA; + sspi_w_token[1].cbBuffer = 0; + sspi_w_token[1].pvBuffer = NULL; + + status = s_pSecFn->DecryptMessage(&sspi_context, + &wrap_desc, + 0, + &qop); + + if(check_sspi_err(conn, status, "DecryptMessage")) { + if(sspi_w_token[0].pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + if(sspi_w_token[1].pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + s_pSecFn->DeleteSecurityContext(&sspi_context); + failf(data, "Failed to query security context attributes."); + return CURLE_COULDNT_CONNECT; + } + + if(sspi_w_token[1].cbBuffer != 1) { + failf(data, "Invalid SSPI encryption response length (%lu).", + (unsigned long)sspi_w_token[1].cbBuffer); + if(sspi_w_token[0].pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + if(sspi_w_token[1].pvBuffer) + s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + + memcpy(socksreq, sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer); + s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); + } + else { + if(sspi_w_token[0].cbBuffer != 1) { + failf(data, "Invalid SSPI encryption response length (%lu).", + (unsigned long)sspi_w_token[0].cbBuffer); + s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + s_pSecFn->DeleteSecurityContext(&sspi_context); + return CURLE_COULDNT_CONNECT; + } + memcpy(socksreq, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer); + s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); + } + + infof(data, "SOCKS5 access with%s protection granted.\n", + (socksreq[0] == 0)?"out GSS-API data": + ((socksreq[0] == 1)?" GSS-API integrity":" GSS-API confidentiality")); + + /* For later use if encryption is required + conn->socks5_gssapi_enctype = socksreq[0]; + if(socksreq[0] != 0) + conn->socks5_sspi_context = sspi_context; + else { + s_pSecFn->DeleteSecurityContext(&sspi_context); + conn->socks5_sspi_context = sspi_context; + } + */ + return CURLE_OK; +} +#endif diff --git a/libcurl/lib/speedcheck.c b/libcurl/lib/speedcheck.c new file mode 100644 index 0000000..3aeea91 --- /dev/null +++ b/libcurl/lib/speedcheck.c @@ -0,0 +1,73 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include +#include "urldata.h" +#include "sendf.h" +#include "multiif.h" +#include "speedcheck.h" + +void Curl_speedinit(struct Curl_easy *data) +{ + memset(&data->state.keeps_speed, 0, sizeof(struct curltime)); +} + +/* + * @unittest: 1606 + */ +CURLcode Curl_speedcheck(struct Curl_easy *data, + struct curltime now) +{ + if((data->progress.current_speed >= 0) && data->set.low_speed_time) { + if(data->progress.current_speed < data->set.low_speed_limit) { + if(!data->state.keeps_speed.tv_sec) + /* under the limit at this very moment */ + data->state.keeps_speed = now; + else { + /* how long has it been under the limit */ + timediff_t howlong = Curl_timediff(now, data->state.keeps_speed); + + if(howlong >= data->set.low_speed_time * 1000) { + /* too long */ + failf(data, + "Operation too slow. " + "Less than %ld bytes/sec transferred the last %ld seconds", + data->set.low_speed_limit, + data->set.low_speed_time); + return CURLE_OPERATION_TIMEDOUT; + } + } + } + else + /* faster right now */ + data->state.keeps_speed.tv_sec = 0; + } + + if(data->set.low_speed_limit) + /* if low speed limit is enabled, set the expire timer to make this + connection's speed get checked again in a second */ + Curl_expire(data, 1000, EXPIRE_SPEEDCHECK); + + return CURLE_OK; +} diff --git a/libcurl/lib/speedcheck.h b/libcurl/lib/speedcheck.h new file mode 100644 index 0000000..5c2dc9a --- /dev/null +++ b/libcurl/lib/speedcheck.h @@ -0,0 +1,33 @@ +#ifndef HEADER_CURL_SPEEDCHECK_H +#define HEADER_CURL_SPEEDCHECK_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include "timeval.h" + +void Curl_speedinit(struct Curl_easy *data); +CURLcode Curl_speedcheck(struct Curl_easy *data, + struct curltime now); + +#endif /* HEADER_CURL_SPEEDCHECK_H */ diff --git a/libcurl/lib/splay.c b/libcurl/lib/splay.c new file mode 100644 index 0000000..0f5fcd1 --- /dev/null +++ b/libcurl/lib/splay.c @@ -0,0 +1,276 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1997 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include "splay.h" + +/* + * This macro compares two node keys i and j and returns: + * + * negative value: when i is smaller than j + * zero : when i is equal to j + * positive when : when i is larger than j + */ +#define compare(i,j) Curl_splaycomparekeys((i),(j)) + +/* + * Splay using the key i (which may or may not be in the tree.) The starting + * root is t. + */ +struct Curl_tree *Curl_splay(struct curltime i, + struct Curl_tree *t) +{ + struct Curl_tree N, *l, *r, *y; + + if(t == NULL) + return t; + N.smaller = N.larger = NULL; + l = r = &N; + + for(;;) { + long comp = compare(i, t->key); + if(comp < 0) { + if(t->smaller == NULL) + break; + if(compare(i, t->smaller->key) < 0) { + y = t->smaller; /* rotate smaller */ + t->smaller = y->larger; + y->larger = t; + t = y; + if(t->smaller == NULL) + break; + } + r->smaller = t; /* link smaller */ + r = t; + t = t->smaller; + } + else if(comp > 0) { + if(t->larger == NULL) + break; + if(compare(i, t->larger->key) > 0) { + y = t->larger; /* rotate larger */ + t->larger = y->smaller; + y->smaller = t; + t = y; + if(t->larger == NULL) + break; + } + l->larger = t; /* link larger */ + l = t; + t = t->larger; + } + else + break; + } + + l->larger = t->smaller; /* assemble */ + r->smaller = t->larger; + t->smaller = N.larger; + t->larger = N.smaller; + + return t; +} + +/* Insert key i into the tree t. Return a pointer to the resulting tree or + * NULL if something went wrong. + * + * @unittest: 1309 + */ +struct Curl_tree *Curl_splayinsert(struct curltime i, + struct Curl_tree *t, + struct Curl_tree *node) +{ + static const struct curltime KEY_NOTUSED = { + (time_t)-1, (unsigned int)-1 + }; /* will *NEVER* appear */ + + if(node == NULL) + return t; + + if(t != NULL) { + t = Curl_splay(i, t); + if(compare(i, t->key) == 0) { + /* There already exists a node in the tree with the very same key. Build + a doubly-linked circular list of nodes. We add the new 'node' struct + to the end of this list. */ + + node->key = KEY_NOTUSED; /* we set the key in the sub node to NOTUSED + to quickly identify this node as a subnode */ + node->samen = t; + node->samep = t->samep; + t->samep->samen = node; + t->samep = node; + + return t; /* the root node always stays the same */ + } + } + + if(t == NULL) { + node->smaller = node->larger = NULL; + } + else if(compare(i, t->key) < 0) { + node->smaller = t->smaller; + node->larger = t; + t->smaller = NULL; + + } + else { + node->larger = t->larger; + node->smaller = t; + t->larger = NULL; + } + node->key = i; + + /* no identical nodes (yet), we are the only one in the list of nodes */ + node->samen = node; + node->samep = node; + return node; +} + +/* Finds and deletes the best-fit node from the tree. Return a pointer to the + resulting tree. best-fit means the smallest node if it is not larger than + the key */ +struct Curl_tree *Curl_splaygetbest(struct curltime i, + struct Curl_tree *t, + struct Curl_tree **removed) +{ + static struct curltime tv_zero = {0, 0}; + struct Curl_tree *x; + + if(!t) { + *removed = NULL; /* none removed since there was no root */ + return NULL; + } + + /* find smallest */ + t = Curl_splay(tv_zero, t); + if(compare(i, t->key) < 0) { + /* even the smallest is too big */ + *removed = NULL; + return t; + } + + /* FIRST! Check if there is a list with identical keys */ + x = t->samen; + if(x != t) { + /* there is, pick one from the list */ + + /* 'x' is the new root node */ + + x->key = t->key; + x->larger = t->larger; + x->smaller = t->smaller; + x->samep = t->samep; + t->samep->samen = x; + + *removed = t; + return x; /* new root */ + } + + /* we splayed the tree to the smallest element, there is no smaller */ + x = t->larger; + *removed = t; + + return x; +} + + +/* Deletes the very node we point out from the tree if it's there. Stores a + * pointer to the new resulting tree in 'newroot'. + * + * Returns zero on success and non-zero on errors! + * When returning error, it does not touch the 'newroot' pointer. + * + * NOTE: when the last node of the tree is removed, there's no tree left so + * 'newroot' will be made to point to NULL. + * + * @unittest: 1309 + */ +int Curl_splayremovebyaddr(struct Curl_tree *t, + struct Curl_tree *removenode, + struct Curl_tree **newroot) +{ + static const struct curltime KEY_NOTUSED = { + (time_t)-1, (unsigned int)-1 + }; /* will *NEVER* appear */ + struct Curl_tree *x; + + if(!t || !removenode) + return 1; + + if(compare(KEY_NOTUSED, removenode->key) == 0) { + /* Key set to NOTUSED means it is a subnode within a 'same' linked list + and thus we can unlink it easily. */ + if(removenode->samen == removenode) + /* A non-subnode should never be set to KEY_NOTUSED */ + return 3; + + removenode->samep->samen = removenode->samen; + removenode->samen->samep = removenode->samep; + + /* Ensures that double-remove gets caught. */ + removenode->samen = removenode; + + *newroot = t; /* return the same root */ + return 0; + } + + t = Curl_splay(removenode->key, t); + + /* First make sure that we got the same root node as the one we want + to remove, as otherwise we might be trying to remove a node that + isn't actually in the tree. + + We cannot just compare the keys here as a double remove in quick + succession of a node with key != KEY_NOTUSED && same != NULL + could return the same key but a different node. */ + if(t != removenode) + return 2; + + /* Check if there is a list with identical sizes, as then we're trying to + remove the root node of a list of nodes with identical keys. */ + x = t->samen; + if(x != t) { + /* 'x' is the new root node, we just make it use the root node's + smaller/larger links */ + + x->key = t->key; + x->larger = t->larger; + x->smaller = t->smaller; + x->samep = t->samep; + t->samep->samen = x; + } + else { + /* Remove the root node */ + if(t->smaller == NULL) + x = t->larger; + else { + x = Curl_splay(removenode->key, t->smaller); + x->larger = t->larger; + } + } + + *newroot = x; /* store new root pointer */ + + return 0; +} diff --git a/libcurl/lib/splay.h b/libcurl/lib/splay.h new file mode 100644 index 0000000..9292f34 --- /dev/null +++ b/libcurl/lib/splay.h @@ -0,0 +1,62 @@ +#ifndef HEADER_CURL_SPLAY_H +#define HEADER_CURL_SPLAY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1997 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" +#include "timeval.h" + +struct Curl_tree { + struct Curl_tree *smaller; /* smaller node */ + struct Curl_tree *larger; /* larger node */ + struct Curl_tree *samen; /* points to the next node with identical key */ + struct Curl_tree *samep; /* points to the prev node with identical key */ + struct curltime key; /* this node's "sort" key */ + void *payload; /* data the splay code doesn't care about */ +}; + +struct Curl_tree *Curl_splay(struct curltime i, + struct Curl_tree *t); + +struct Curl_tree *Curl_splayinsert(struct curltime key, + struct Curl_tree *t, + struct Curl_tree *newnode); + +#if 0 +struct Curl_tree *Curl_splayremove(struct curltime key, + struct Curl_tree *t, + struct Curl_tree **removed); +#endif + +struct Curl_tree *Curl_splaygetbest(struct curltime key, + struct Curl_tree *t, + struct Curl_tree **removed); + +int Curl_splayremovebyaddr(struct Curl_tree *t, + struct Curl_tree *removenode, + struct Curl_tree **newroot); + +#define Curl_splaycomparekeys(i,j) ( ((i.tv_sec) < (j.tv_sec)) ? -1 : \ + ( ((i.tv_sec) > (j.tv_sec)) ? 1 : \ + ( ((i.tv_usec) < (j.tv_usec)) ? -1 : \ + ( ((i.tv_usec) > (j.tv_usec)) ? 1 : 0)))) + +#endif /* HEADER_CURL_SPLAY_H */ diff --git a/libcurl/lib/ssh-libssh.c b/libcurl/lib/ssh-libssh.c new file mode 100644 index 0000000..ca13376 --- /dev/null +++ b/libcurl/lib/ssh-libssh.c @@ -0,0 +1,2739 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2017 - 2019 Red Hat, Inc. + * + * Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek, + * Robert Kolcun, Andreas Schneider + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_LIBSSH + +#include + +#include +#include + +#ifdef HAVE_FCNTL_H +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_UTSNAME_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +#include +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "progress.h" +#include "transfer.h" +#include "escape.h" +#include "http.h" /* for HTTP proxy tunnel stuff */ +#include "ssh.h" +#include "url.h" +#include "speedcheck.h" +#include "getinfo.h" +#include "strdup.h" +#include "strcase.h" +#include "vtls/vtls.h" +#include "connect.h" +#include "strerror.h" +#include "inet_ntop.h" +#include "parsedate.h" /* for the week day and month names */ +#include "sockaddr.h" /* required for Curl_sockaddr_storage */ +#include "strtoofft.h" +#include "multiif.h" +#include "select.h" +#include "warnless.h" + +/* for permission and open flags */ +#include +#include +#include +#include + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" +#include "curl_path.h" + +/* A recent macro provided by libssh. Or make our own. */ +#ifndef SSH_STRING_FREE_CHAR +/* !checksrc! disable ASSIGNWITHINCONDITION 1 */ +#define SSH_STRING_FREE_CHAR(x) \ + do { if((x) != NULL) { ssh_string_free_char(x); x = NULL; } } while(0) +#endif + +/* Local functions: */ +static CURLcode myssh_connect(struct connectdata *conn, bool *done); +static CURLcode myssh_multi_statemach(struct connectdata *conn, + bool *done); +static CURLcode myssh_do_it(struct connectdata *conn, bool *done); + +static CURLcode scp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done); +static CURLcode scp_disconnect(struct connectdata *conn, + bool dead_connection); + +static CURLcode sftp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode sftp_doing(struct connectdata *conn, + bool *dophase_done); +static CURLcode sftp_disconnect(struct connectdata *conn, bool dead); +static +CURLcode sftp_perform(struct connectdata *conn, + bool *connected, + bool *dophase_done); + +static void sftp_quote(struct connectdata *conn); +static void sftp_quote_stat(struct connectdata *conn); + +static int myssh_getsock(struct connectdata *conn, curl_socket_t *sock, + int numsocks); + +static int myssh_perform_getsock(const struct connectdata *conn, + curl_socket_t *sock, + int numsocks); + +static CURLcode myssh_setup_connection(struct connectdata *conn); + +/* + * SCP protocol handler. + */ + +const struct Curl_handler Curl_handler_scp = { + "SCP", /* scheme */ + myssh_setup_connection, /* setup_connection */ + myssh_do_it, /* do_it */ + scp_done, /* done */ + ZERO_NULL, /* do_more */ + myssh_connect, /* connect_it */ + myssh_multi_statemach, /* connecting */ + scp_doing, /* doing */ + myssh_getsock, /* proto_getsock */ + myssh_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + myssh_perform_getsock, /* perform_getsock */ + scp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SSH, /* defport */ + CURLPROTO_SCP, /* protocol */ + PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */ +}; + +/* + * SFTP protocol handler. + */ + +const struct Curl_handler Curl_handler_sftp = { + "SFTP", /* scheme */ + myssh_setup_connection, /* setup_connection */ + myssh_do_it, /* do_it */ + sftp_done, /* done */ + ZERO_NULL, /* do_more */ + myssh_connect, /* connect_it */ + myssh_multi_statemach, /* connecting */ + sftp_doing, /* doing */ + myssh_getsock, /* proto_getsock */ + myssh_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + myssh_perform_getsock, /* perform_getsock */ + sftp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SSH, /* defport */ + CURLPROTO_SFTP, /* protocol */ + PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION + | PROTOPT_NOURLQUERY /* flags */ +}; + +static CURLcode sftp_error_to_CURLE(int err) +{ + switch(err) { + case SSH_FX_OK: + return CURLE_OK; + + case SSH_FX_NO_SUCH_FILE: + case SSH_FX_NO_SUCH_PATH: + return CURLE_REMOTE_FILE_NOT_FOUND; + + case SSH_FX_PERMISSION_DENIED: + case SSH_FX_WRITE_PROTECT: + return CURLE_REMOTE_ACCESS_DENIED; + + case SSH_FX_FILE_ALREADY_EXISTS: + return CURLE_REMOTE_FILE_EXISTS; + + default: + break; + } + + return CURLE_SSH; +} + +#ifndef DEBUGBUILD +#define state(x,y) mystate(x,y) +#else +#define state(x,y) mystate(x,y, __LINE__) +#endif + +/* + * SSH State machine related code + */ +/* This is the ONLY way to change SSH state! */ +static void mystate(struct connectdata *conn, sshstate nowstate +#ifdef DEBUGBUILD + , int lineno +#endif + ) +{ + struct ssh_conn *sshc = &conn->proto.sshc; +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* for debug purposes */ + static const char *const names[] = { + "SSH_STOP", + "SSH_INIT", + "SSH_S_STARTUP", + "SSH_HOSTKEY", + "SSH_AUTHLIST", + "SSH_AUTH_PKEY_INIT", + "SSH_AUTH_PKEY", + "SSH_AUTH_PASS_INIT", + "SSH_AUTH_PASS", + "SSH_AUTH_AGENT_INIT", + "SSH_AUTH_AGENT_LIST", + "SSH_AUTH_AGENT", + "SSH_AUTH_HOST_INIT", + "SSH_AUTH_HOST", + "SSH_AUTH_KEY_INIT", + "SSH_AUTH_KEY", + "SSH_AUTH_GSSAPI", + "SSH_AUTH_DONE", + "SSH_SFTP_INIT", + "SSH_SFTP_REALPATH", + "SSH_SFTP_QUOTE_INIT", + "SSH_SFTP_POSTQUOTE_INIT", + "SSH_SFTP_QUOTE", + "SSH_SFTP_NEXT_QUOTE", + "SSH_SFTP_QUOTE_STAT", + "SSH_SFTP_QUOTE_SETSTAT", + "SSH_SFTP_QUOTE_SYMLINK", + "SSH_SFTP_QUOTE_MKDIR", + "SSH_SFTP_QUOTE_RENAME", + "SSH_SFTP_QUOTE_RMDIR", + "SSH_SFTP_QUOTE_UNLINK", + "SSH_SFTP_QUOTE_STATVFS", + "SSH_SFTP_GETINFO", + "SSH_SFTP_FILETIME", + "SSH_SFTP_TRANS_INIT", + "SSH_SFTP_UPLOAD_INIT", + "SSH_SFTP_CREATE_DIRS_INIT", + "SSH_SFTP_CREATE_DIRS", + "SSH_SFTP_CREATE_DIRS_MKDIR", + "SSH_SFTP_READDIR_INIT", + "SSH_SFTP_READDIR", + "SSH_SFTP_READDIR_LINK", + "SSH_SFTP_READDIR_BOTTOM", + "SSH_SFTP_READDIR_DONE", + "SSH_SFTP_DOWNLOAD_INIT", + "SSH_SFTP_DOWNLOAD_STAT", + "SSH_SFTP_CLOSE", + "SSH_SFTP_SHUTDOWN", + "SSH_SCP_TRANS_INIT", + "SSH_SCP_UPLOAD_INIT", + "SSH_SCP_DOWNLOAD_INIT", + "SSH_SCP_DOWNLOAD", + "SSH_SCP_DONE", + "SSH_SCP_SEND_EOF", + "SSH_SCP_WAIT_EOF", + "SSH_SCP_WAIT_CLOSE", + "SSH_SCP_CHANNEL_FREE", + "SSH_SESSION_DISCONNECT", + "SSH_SESSION_FREE", + "QUIT" + }; + + + if(sshc->state != nowstate) { + infof(conn->data, "SSH %p state change from %s to %s (line %d)\n", + (void *) sshc, names[sshc->state], names[nowstate], + lineno); + } +#endif + + sshc->state = nowstate; +} + +/* Multiple options: + * 1. data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] is set with an MD5 + * hash (90s style auth, not sure we should have it here) + * 2. data->set.ssh_keyfunc callback is set. Then we do trust on first + * use. We even save on knownhosts if CURLKHSTAT_FINE_ADD_TO_FILE + * is returned by it. + * 3. none of the above. We only accept if it is present on known hosts. + * + * Returns SSH_OK or SSH_ERROR. + */ +static int myssh_is_known(struct connectdata *conn) +{ + int rc; + struct Curl_easy *data = conn->data; + struct ssh_conn *sshc = &conn->proto.sshc; + ssh_key pubkey; + size_t hlen; + unsigned char *hash = NULL; + char *base64 = NULL; + int vstate; + enum curl_khmatch keymatch; + struct curl_khkey foundkey; + curl_sshkeycallback func = + data->set.ssh_keyfunc; + + rc = ssh_get_publickey(sshc->ssh_session, &pubkey); + if(rc != SSH_OK) + return rc; + + if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) { + rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5, + &hash, &hlen); + if(rc != SSH_OK) + goto cleanup; + + if(hlen != strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) || + memcmp(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], hash, hlen)) { + rc = SSH_ERROR; + goto cleanup; + } + + rc = SSH_OK; + goto cleanup; + } + + if(data->set.ssl.primary.verifyhost != TRUE) { + rc = SSH_OK; + goto cleanup; + } + + vstate = ssh_is_server_known(sshc->ssh_session); + switch(vstate) { + case SSH_SERVER_KNOWN_OK: + keymatch = CURLKHMATCH_OK; + break; + case SSH_SERVER_FILE_NOT_FOUND: + /* fallthrough */ + case SSH_SERVER_NOT_KNOWN: + keymatch = CURLKHMATCH_MISSING; + break; + default: + keymatch = CURLKHMATCH_MISMATCH; + break; + } + + if(func) { /* use callback to determine action */ + rc = ssh_pki_export_pubkey_base64(pubkey, &base64); + if(rc != SSH_OK) + goto cleanup; + + foundkey.key = base64; + foundkey.len = strlen(base64); + + switch(ssh_key_type(pubkey)) { + case SSH_KEYTYPE_RSA: + foundkey.keytype = CURLKHTYPE_RSA; + break; + case SSH_KEYTYPE_RSA1: + foundkey.keytype = CURLKHTYPE_RSA1; + break; + case SSH_KEYTYPE_ECDSA: + foundkey.keytype = CURLKHTYPE_ECDSA; + break; +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,7,0) + case SSH_KEYTYPE_ED25519: + foundkey.keytype = CURLKHTYPE_ED25519; + break; +#endif + case SSH_KEYTYPE_DSS: + foundkey.keytype = CURLKHTYPE_DSS; + break; + default: + rc = SSH_ERROR; + goto cleanup; + } + + /* we don't have anything equivalent to knownkey. Always NULL */ + Curl_set_in_callback(data, true); + rc = func(data, NULL, &foundkey, /* from the remote host */ + keymatch, data->set.ssh_keyfunc_userp); + Curl_set_in_callback(data, false); + + switch(rc) { + case CURLKHSTAT_FINE_ADD_TO_FILE: + rc = ssh_write_knownhost(sshc->ssh_session); + if(rc != SSH_OK) { + goto cleanup; + } + break; + case CURLKHSTAT_FINE: + break; + default: /* REJECT/DEFER */ + rc = SSH_ERROR; + goto cleanup; + } + } + else { + if(keymatch != CURLKHMATCH_OK) { + rc = SSH_ERROR; + goto cleanup; + } + } + rc = SSH_OK; + +cleanup: + if(hash) + ssh_clean_pubkey_hash(&hash); + ssh_key_free(pubkey); + return rc; +} + +#define MOVE_TO_ERROR_STATE(_r) { \ + state(conn, SSH_SESSION_DISCONNECT); \ + sshc->actualcode = _r; \ + rc = SSH_ERROR; \ + break; \ +} + +#define MOVE_TO_SFTP_CLOSE_STATE() { \ + state(conn, SSH_SFTP_CLOSE); \ + sshc->actualcode = sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \ + rc = SSH_ERROR; \ + break; \ +} + +#define MOVE_TO_LAST_AUTH \ + if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \ + rc = SSH_OK; \ + state(conn, SSH_AUTH_PASS_INIT); \ + break; \ + } \ + else { \ + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \ + } + +#define MOVE_TO_TERTIARY_AUTH \ + if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \ + rc = SSH_OK; \ + state(conn, SSH_AUTH_KEY_INIT); \ + break; \ + } \ + else { \ + MOVE_TO_LAST_AUTH; \ + } + +#define MOVE_TO_SECONDARY_AUTH \ + if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \ + rc = SSH_OK; \ + state(conn, SSH_AUTH_GSSAPI); \ + break; \ + } \ + else { \ + MOVE_TO_TERTIARY_AUTH; \ + } + +static +int myssh_auth_interactive(struct connectdata *conn) +{ + int rc; + struct ssh_conn *sshc = &conn->proto.sshc; + int nprompts; + +restart: + switch(sshc->kbd_state) { + case 0: + rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + + if(rc != SSH_AUTH_INFO) + return SSH_ERROR; + + nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session); + if(nprompts == SSH_ERROR || nprompts != 1) + return SSH_ERROR; + + rc = ssh_userauth_kbdint_setanswer(sshc->ssh_session, 0, conn->passwd); + if(rc < 0) + return SSH_ERROR; + + /* FALLTHROUGH */ + case 1: + sshc->kbd_state = 1; + + rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + else if(rc == SSH_AUTH_SUCCESS) + rc = SSH_OK; + else if(rc == SSH_AUTH_INFO) { + nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session); + if(nprompts != 0) + return SSH_ERROR; + + sshc->kbd_state = 2; + goto restart; + } + else + rc = SSH_ERROR; + break; + case 2: + sshc->kbd_state = 2; + + rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + else if(rc == SSH_AUTH_SUCCESS) + rc = SSH_OK; + else + rc = SSH_ERROR; + + break; + default: + return SSH_ERROR; + } + + sshc->kbd_state = 0; + return rc; +} + +/* + * ssh_statemach_act() runs the SSH state machine as far as it can without + * blocking and without reaching the end. The data the pointer 'block' points + * to will be set to TRUE if the libssh function returns SSH_AGAIN + * meaning it wants to be called again when the socket is ready + */ +static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct SSHPROTO *protop = data->req.protop; + struct ssh_conn *sshc = &conn->proto.sshc; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + int rc = SSH_NO_ERROR, err; + char *new_readdir_line; + int seekerr = CURL_SEEKFUNC_OK; + const char *err_msg; + *block = 0; /* we're not blocking by default */ + + do { + + switch(sshc->state) { + case SSH_INIT: + sshc->secondCreateDirs = 0; + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_OK; + +#if 0 + ssh_set_log_level(SSH_LOG_PROTOCOL); +#endif + + /* Set libssh to non-blocking, since everything internally is + non-blocking */ + ssh_set_blocking(sshc->ssh_session, 0); + + state(conn, SSH_S_STARTUP); + /* FALLTHROUGH */ + + case SSH_S_STARTUP: + rc = ssh_connect(sshc->ssh_session); + if(rc == SSH_AGAIN) + break; + + if(rc != SSH_OK) { + failf(data, "Failure establishing ssh session"); + MOVE_TO_ERROR_STATE(CURLE_FAILED_INIT); + } + + state(conn, SSH_HOSTKEY); + + /* FALLTHROUGH */ + case SSH_HOSTKEY: + + rc = myssh_is_known(conn); + if(rc != SSH_OK) { + MOVE_TO_ERROR_STATE(CURLE_PEER_FAILED_VERIFICATION); + } + + state(conn, SSH_AUTHLIST); + /* FALLTHROUGH */ + case SSH_AUTHLIST:{ + sshc->authed = FALSE; + + rc = ssh_userauth_none(sshc->ssh_session, NULL); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc == SSH_AUTH_SUCCESS) { + sshc->authed = TRUE; + infof(data, "Authenticated with none\n"); + state(conn, SSH_AUTH_DONE); + break; + } + else if(rc == SSH_AUTH_ERROR) { + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + + sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL); + if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { + state(conn, SSH_AUTH_PKEY_INIT); + infof(data, "Authentication using SSH public key file\n"); + } + else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { + state(conn, SSH_AUTH_GSSAPI); + } + else if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { + state(conn, SSH_AUTH_KEY_INIT); + } + else if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { + state(conn, SSH_AUTH_PASS_INIT); + } + else { /* unsupported authentication method */ + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + + break; + } + case SSH_AUTH_PKEY_INIT: + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) { + MOVE_TO_SECONDARY_AUTH; + } + + /* Two choices, (1) private key was given on CMD, + * (2) use the "default" keys. */ + if(data->set.str[STRING_SSH_PRIVATE_KEY]) { + if(sshc->pubkey && !data->set.ssl.key_passwd) { + rc = ssh_userauth_try_publickey(sshc->ssh_session, NULL, + sshc->pubkey); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc != SSH_OK) { + MOVE_TO_SECONDARY_AUTH; + } + } + + rc = ssh_pki_import_privkey_file(data-> + set.str[STRING_SSH_PRIVATE_KEY], + data->set.ssl.key_passwd, NULL, + NULL, &sshc->privkey); + if(rc != SSH_OK) { + failf(data, "Could not load private key file %s", + data->set.str[STRING_SSH_PRIVATE_KEY]); + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + break; + } + + state(conn, SSH_AUTH_PKEY); + break; + + } + else { + rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL, + data->set.ssl.key_passwd); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + if(rc == SSH_AUTH_SUCCESS) { + rc = SSH_OK; + sshc->authed = TRUE; + infof(data, "Completed public key authentication\n"); + state(conn, SSH_AUTH_DONE); + break; + } + + MOVE_TO_SECONDARY_AUTH; + } + break; + case SSH_AUTH_PKEY: + rc = ssh_userauth_publickey(sshc->ssh_session, NULL, sshc->privkey); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc == SSH_AUTH_SUCCESS) { + sshc->authed = TRUE; + infof(data, "Completed public key authentication\n"); + state(conn, SSH_AUTH_DONE); + break; + } + else { + infof(data, "Failed public key authentication (rc: %d)\n", rc); + MOVE_TO_SECONDARY_AUTH; + } + break; + + case SSH_AUTH_GSSAPI: + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) { + MOVE_TO_TERTIARY_AUTH; + } + + rc = ssh_userauth_gssapi(sshc->ssh_session); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc == SSH_AUTH_SUCCESS) { + rc = SSH_OK; + sshc->authed = TRUE; + infof(data, "Completed gssapi authentication\n"); + state(conn, SSH_AUTH_DONE); + break; + } + + MOVE_TO_TERTIARY_AUTH; + break; + + case SSH_AUTH_KEY_INIT: + if(data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) { + state(conn, SSH_AUTH_KEY); + } + else { + MOVE_TO_LAST_AUTH; + } + break; + + case SSH_AUTH_KEY: + + /* Authentication failed. Continue with keyboard-interactive now. */ + rc = myssh_auth_interactive(conn); + if(rc == SSH_AGAIN) { + break; + } + if(rc == SSH_OK) { + sshc->authed = TRUE; + infof(data, "completed keyboard interactive authentication\n"); + } + state(conn, SSH_AUTH_DONE); + break; + + case SSH_AUTH_PASS_INIT: + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) { + /* Host key authentication is intentionally not implemented */ + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + state(conn, SSH_AUTH_PASS); + /* FALLTHROUGH */ + + case SSH_AUTH_PASS: + rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc == SSH_AUTH_SUCCESS) { + sshc->authed = TRUE; + infof(data, "Completed password authentication\n"); + state(conn, SSH_AUTH_DONE); + } + else { + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + break; + + case SSH_AUTH_DONE: + if(!sshc->authed) { + failf(data, "Authentication failure"); + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + break; + } + + /* + * At this point we have an authenticated ssh session. + */ + infof(data, "Authentication complete\n"); + + Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */ + + conn->sockfd = sock; + conn->writesockfd = CURL_SOCKET_BAD; + + if(conn->handler->protocol == CURLPROTO_SFTP) { + state(conn, SSH_SFTP_INIT); + break; + } + infof(data, "SSH CONNECT phase done\n"); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_INIT: + ssh_set_blocking(sshc->ssh_session, 1); + + sshc->sftp_session = sftp_new(sshc->ssh_session); + if(!sshc->sftp_session) { + failf(data, "Failure initializing sftp session: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + break; + } + + rc = sftp_init(sshc->sftp_session); + if(rc != SSH_OK) { + rc = sftp_get_error(sshc->sftp_session); + failf(data, "Failure initializing sftp session: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(rc)); + break; + } + state(conn, SSH_SFTP_REALPATH); + /* FALLTHROUGH */ + case SSH_SFTP_REALPATH: + /* + * Get the "home" directory + */ + sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, "."); + if(sshc->homedir == NULL) { + MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + } + conn->data->state.most_recent_ftp_entrypath = sshc->homedir; + + /* This is the last step in the SFTP connect phase. Do note that while + we get the homedir here, we get the "workingpath" in the DO action + since the homedir will remain the same between request but the + working path will not. */ + DEBUGF(infof(data, "SSH CONNECT phase done\n")); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_QUOTE_INIT: + + result = Curl_getworkingpath(conn, sshc->homedir, &protop->path); + if(result) { + sshc->actualcode = result; + state(conn, SSH_STOP); + break; + } + + if(data->set.quote) { + infof(data, "Sending quote commands\n"); + sshc->quote_item = data->set.quote; + state(conn, SSH_SFTP_QUOTE); + } + else { + state(conn, SSH_SFTP_GETINFO); + } + break; + + case SSH_SFTP_POSTQUOTE_INIT: + if(data->set.postquote) { + infof(data, "Sending quote commands\n"); + sshc->quote_item = data->set.postquote; + state(conn, SSH_SFTP_QUOTE); + } + else { + state(conn, SSH_STOP); + } + break; + + case SSH_SFTP_QUOTE: + /* Send any quote commands */ + sftp_quote(conn); + break; + + case SSH_SFTP_NEXT_QUOTE: + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + + sshc->quote_item = sshc->quote_item->next; + + if(sshc->quote_item) { + state(conn, SSH_SFTP_QUOTE); + } + else { + if(sshc->nextstate != SSH_NO_STATE) { + state(conn, sshc->nextstate); + sshc->nextstate = SSH_NO_STATE; + } + else { + state(conn, SSH_SFTP_GETINFO); + } + } + break; + + case SSH_SFTP_QUOTE_STAT: + sftp_quote_stat(conn); + break; + + case SSH_SFTP_QUOTE_SETSTAT: + rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2, + sshc->quote_attrs); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Attempt to set SFTP stats failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + /* sshc->actualcode = sftp_error_to_CURLE(err); + * we do not send the actual error; we return + * the error the libssh2 backend is returning */ + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_SYMLINK: + rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2, + sshc->quote_path1); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "symlink command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_MKDIR: + rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1, + (mode_t)data->set.new_directory_perms); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "mkdir command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_RENAME: + rc = sftp_rename(sshc->sftp_session, sshc->quote_path1, + sshc->quote_path2); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "rename command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_RMDIR: + rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "rmdir command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_UNLINK: + rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "rm command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_STATVFS: + { + sftp_statvfs_t statvfs; + + statvfs = sftp_statvfs(sshc->sftp_session, sshc->quote_path1); + if(!statvfs && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "statvfs command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + else if(statvfs) { + char *tmp = aprintf("statvfs:\n" + "f_bsize: %llu\n" "f_frsize: %llu\n" + "f_blocks: %llu\n" "f_bfree: %llu\n" + "f_bavail: %llu\n" "f_files: %llu\n" + "f_ffree: %llu\n" "f_favail: %llu\n" + "f_fsid: %llu\n" "f_flag: %llu\n" + "f_namemax: %llu\n", + statvfs->f_bsize, statvfs->f_frsize, + statvfs->f_blocks, statvfs->f_bfree, + statvfs->f_bavail, statvfs->f_files, + statvfs->f_ffree, statvfs->f_favail, + statvfs->f_fsid, statvfs->f_flag, + statvfs->f_namemax); + sftp_statvfs_free(statvfs); + + if(!tmp) { + result = CURLE_OUT_OF_MEMORY; + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + break; + } + + result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + free(tmp); + if(result) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + } + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + } + + case SSH_SFTP_GETINFO: + if(data->set.get_filetime) { + state(conn, SSH_SFTP_FILETIME); + } + else { + state(conn, SSH_SFTP_TRANS_INIT); + } + break; + + case SSH_SFTP_FILETIME: + { + sftp_attributes attrs; + + attrs = sftp_stat(sshc->sftp_session, protop->path); + if(attrs != 0) { + data->info.filetime = attrs->mtime; + sftp_attributes_free(attrs); + } + + state(conn, SSH_SFTP_TRANS_INIT); + break; + } + + case SSH_SFTP_TRANS_INIT: + if(data->set.upload) + state(conn, SSH_SFTP_UPLOAD_INIT); + else { + if(protop->path[strlen(protop->path)-1] == '/') + state(conn, SSH_SFTP_READDIR_INIT); + else + state(conn, SSH_SFTP_DOWNLOAD_INIT); + } + break; + + case SSH_SFTP_UPLOAD_INIT: + { + int flags; + + if(data->state.resume_from != 0) { + sftp_attributes attrs; + + if(data->state.resume_from < 0) { + attrs = sftp_stat(sshc->sftp_session, protop->path); + if(attrs != 0) { + curl_off_t size = attrs->size; + if(size < 0) { + failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME); + } + data->state.resume_from = attrs->size; + + sftp_attributes_free(attrs); + } + else { + data->state.resume_from = 0; + } + } + } + + if(data->set.ftp_append) + /* Try to open for append, but create if nonexisting */ + flags = O_WRONLY|O_CREAT|O_APPEND; + else if(data->state.resume_from > 0) + /* If we have restart position then open for append */ + flags = O_WRONLY|O_APPEND; + else + /* Clear file before writing (normal behaviour) */ + flags = O_WRONLY|O_APPEND|O_CREAT|O_TRUNC; + + if(sshc->sftp_file) + sftp_close(sshc->sftp_file); + sshc->sftp_file = + sftp_open(sshc->sftp_session, protop->path, + flags, (mode_t)data->set.new_file_perms); + if(!sshc->sftp_file) { + err = sftp_get_error(sshc->sftp_session); + + if(((err == SSH_FX_NO_SUCH_FILE || err == SSH_FX_FAILURE || + err == SSH_FX_NO_SUCH_PATH)) && + (data->set.ftp_create_missing_dirs && + (strlen(protop->path) > 1))) { + /* try to create the path remotely */ + rc = 0; + sshc->secondCreateDirs = 1; + state(conn, SSH_SFTP_CREATE_DIRS_INIT); + break; + } + else { + MOVE_TO_SFTP_CLOSE_STATE(); + } + } + + /* If we have a restart point then we need to seek to the correct + position. */ + if(data->state.resume_from > 0) { + /* Let's read off the proper amount of bytes from the input. */ + if(conn->seek_func) { + Curl_set_in_callback(data, true); + seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, + SEEK_SET); + Curl_set_in_callback(data, false); + } + + if(seekerr != CURL_SEEKFUNC_OK) { + curl_off_t passed = 0; + + if(seekerr != CURL_SEEKFUNC_CANTSEEK) { + failf(data, "Could not seek stream"); + return CURLE_FTP_COULDNT_USE_REST; + } + /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ + do { + size_t readthisamountnow = + (data->state.resume_from - passed > data->set.buffer_size) ? + (size_t)data->set.buffer_size : + curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = + data->state.fread_func(data->state.buffer, 1, + readthisamountnow, data->state.in); + + passed += actuallyread; + if((actuallyread == 0) || (actuallyread > readthisamountnow)) { + /* this checks for greater-than only to make sure that the + CURL_READFUNC_ABORT return code still aborts */ + failf(data, "Failed to read data"); + MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST); + } + } while(passed < data->state.resume_from); + } + + /* now, decrease the size of the read */ + if(data->state.infilesize > 0) { + data->state.infilesize -= data->state.resume_from; + data->req.size = data->state.infilesize; + Curl_pgrsSetUploadSize(data, data->state.infilesize); + } + + rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); + if(rc != 0) { + MOVE_TO_SFTP_CLOSE_STATE(); + } + } + if(data->state.infilesize > 0) { + data->req.size = data->state.infilesize; + Curl_pgrsSetUploadSize(data, data->state.infilesize); + } + /* upload data */ + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->sockfd = conn->writesockfd; + + /* store this original bitmask setup to use later on if we can't + figure out a "real" bitmask */ + sshc->orig_waitfor = data->req.keepon; + + /* we want to use the _sending_ function even when the socket turns + out readable as the underlying libssh sftp send function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_OUT; + + /* since we don't really wait for anything at this point, we want the + state machine to move on as soon as possible so we set a very short + timeout here */ + Curl_expire(data, 0, EXPIRE_RUN_NOW); + + state(conn, SSH_STOP); + break; + } + + case SSH_SFTP_CREATE_DIRS_INIT: + if(strlen(protop->path) > 1) { + sshc->slash_pos = protop->path + 1; /* ignore the leading '/' */ + state(conn, SSH_SFTP_CREATE_DIRS); + } + else { + state(conn, SSH_SFTP_UPLOAD_INIT); + } + break; + + case SSH_SFTP_CREATE_DIRS: + sshc->slash_pos = strchr(sshc->slash_pos, '/'); + if(sshc->slash_pos) { + *sshc->slash_pos = 0; + + infof(data, "Creating directory '%s'\n", protop->path); + state(conn, SSH_SFTP_CREATE_DIRS_MKDIR); + break; + } + state(conn, SSH_SFTP_UPLOAD_INIT); + break; + + case SSH_SFTP_CREATE_DIRS_MKDIR: + /* 'mode' - parameter is preliminary - default to 0644 */ + rc = sftp_mkdir(sshc->sftp_session, protop->path, + (mode_t)data->set.new_directory_perms); + *sshc->slash_pos = '/'; + ++sshc->slash_pos; + if(rc < 0) { + /* + * Abort if failure wasn't that the dir already exists or the + * permission was denied (creation might succeed further down the + * path) - retry on unspecific FAILURE also + */ + err = sftp_get_error(sshc->sftp_session); + if((err != SSH_FX_FILE_ALREADY_EXISTS) && + (err != SSH_FX_FAILURE) && + (err != SSH_FX_PERMISSION_DENIED)) { + MOVE_TO_SFTP_CLOSE_STATE(); + } + rc = 0; /* clear rc and continue */ + } + state(conn, SSH_SFTP_CREATE_DIRS); + break; + + case SSH_SFTP_READDIR_INIT: + Curl_pgrsSetDownloadSize(data, -1); + if(data->set.opt_no_body) { + state(conn, SSH_STOP); + break; + } + + /* + * This is a directory that we are trying to get, so produce a directory + * listing + */ + sshc->sftp_dir = sftp_opendir(sshc->sftp_session, + protop->path); + if(!sshc->sftp_dir) { + failf(data, "Could not open directory for reading: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_SFTP_CLOSE_STATE(); + } + state(conn, SSH_SFTP_READDIR); + break; + + case SSH_SFTP_READDIR: + + if(sshc->readdir_attrs) + sftp_attributes_free(sshc->readdir_attrs); + + sshc->readdir_attrs = sftp_readdir(sshc->sftp_session, sshc->sftp_dir); + if(sshc->readdir_attrs) { + sshc->readdir_filename = sshc->readdir_attrs->name; + sshc->readdir_longentry = sshc->readdir_attrs->longname; + sshc->readdir_len = strlen(sshc->readdir_filename); + + if(data->set.ftp_list_only) { + char *tmpLine; + + tmpLine = aprintf("%s\n", sshc->readdir_filename); + if(tmpLine == NULL) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + result = Curl_client_write(conn, CLIENTWRITE_BODY, + tmpLine, sshc->readdir_len + 1); + free(tmpLine); + + if(result) { + state(conn, SSH_STOP); + break; + } + /* since this counts what we send to the client, we include the + newline in this counter */ + data->req.bytecount += sshc->readdir_len + 1; + + /* output debug output if that is requested */ + if(data->set.verbose) { + Curl_debug(data, CURLINFO_DATA_OUT, + (char *)sshc->readdir_filename, + sshc->readdir_len); + } + } + else { + sshc->readdir_currLen = strlen(sshc->readdir_longentry); + sshc->readdir_totalLen = 80 + sshc->readdir_currLen; + sshc->readdir_line = calloc(sshc->readdir_totalLen, 1); + if(!sshc->readdir_line) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + + memcpy(sshc->readdir_line, sshc->readdir_longentry, + sshc->readdir_currLen); + if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) && + ((sshc->readdir_attrs->permissions & S_IFMT) == + S_IFLNK)) { + sshc->readdir_linkPath = malloc(PATH_MAX + 1); + if(sshc->readdir_linkPath == NULL) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + + msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", protop->path, + sshc->readdir_filename); + + state(conn, SSH_SFTP_READDIR_LINK); + break; + } + state(conn, SSH_SFTP_READDIR_BOTTOM); + break; + } + } + else if(sshc->readdir_attrs == NULL && sftp_dir_eof(sshc->sftp_dir)) { + state(conn, SSH_SFTP_READDIR_DONE); + break; + } + else { + failf(data, "Could not open remote file for reading: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_SFTP_CLOSE_STATE(); + break; + } + break; + + case SSH_SFTP_READDIR_LINK: + if(sshc->readdir_link_attrs) + sftp_attributes_free(sshc->readdir_link_attrs); + + sshc->readdir_link_attrs = sftp_lstat(sshc->sftp_session, + sshc->readdir_linkPath); + if(sshc->readdir_link_attrs == 0) { + failf(data, "Could not read symlink for reading: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_SFTP_CLOSE_STATE(); + } + + if(sshc->readdir_link_attrs->name == NULL) { + sshc->readdir_tmp = sftp_readlink(sshc->sftp_session, + sshc->readdir_linkPath); + if(sshc->readdir_filename == NULL) + sshc->readdir_len = 0; + else + sshc->readdir_len = strlen(sshc->readdir_tmp); + sshc->readdir_longentry = NULL; + sshc->readdir_filename = sshc->readdir_tmp; + } + else { + sshc->readdir_len = strlen(sshc->readdir_link_attrs->name); + sshc->readdir_filename = sshc->readdir_link_attrs->name; + sshc->readdir_longentry = sshc->readdir_link_attrs->longname; + } + + Curl_safefree(sshc->readdir_linkPath); + + /* get room for the filename and extra output */ + sshc->readdir_totalLen += 4 + sshc->readdir_len; + new_readdir_line = Curl_saferealloc(sshc->readdir_line, + sshc->readdir_totalLen); + if(!new_readdir_line) { + sshc->readdir_line = NULL; + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + sshc->readdir_line = new_readdir_line; + + sshc->readdir_currLen += msnprintf(sshc->readdir_line + + sshc->readdir_currLen, + sshc->readdir_totalLen - + sshc->readdir_currLen, + " -> %s", + sshc->readdir_filename); + + sftp_attributes_free(sshc->readdir_link_attrs); + sshc->readdir_link_attrs = NULL; + sshc->readdir_filename = NULL; + sshc->readdir_longentry = NULL; + + state(conn, SSH_SFTP_READDIR_BOTTOM); + /* FALLTHROUGH */ + case SSH_SFTP_READDIR_BOTTOM: + sshc->readdir_currLen += msnprintf(sshc->readdir_line + + sshc->readdir_currLen, + sshc->readdir_totalLen - + sshc->readdir_currLen, "\n"); + result = Curl_client_write(conn, CLIENTWRITE_BODY, + sshc->readdir_line, + sshc->readdir_currLen); + + if(!result) { + + /* output debug output if that is requested */ + if(data->set.verbose) { + Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line, + sshc->readdir_currLen); + } + data->req.bytecount += sshc->readdir_currLen; + } + Curl_safefree(sshc->readdir_line); + ssh_string_free_char(sshc->readdir_tmp); + sshc->readdir_tmp = NULL; + + if(result) { + state(conn, SSH_STOP); + } + else + state(conn, SSH_SFTP_READDIR); + break; + + case SSH_SFTP_READDIR_DONE: + sftp_closedir(sshc->sftp_dir); + sshc->sftp_dir = NULL; + + /* no data to transfer */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_DOWNLOAD_INIT: + /* + * Work on getting the specified file + */ + if(sshc->sftp_file) + sftp_close(sshc->sftp_file); + + sshc->sftp_file = sftp_open(sshc->sftp_session, protop->path, + O_RDONLY, (mode_t)data->set.new_file_perms); + if(!sshc->sftp_file) { + failf(data, "Could not open remote file for reading: %s", + ssh_get_error(sshc->ssh_session)); + + MOVE_TO_SFTP_CLOSE_STATE(); + } + + state(conn, SSH_SFTP_DOWNLOAD_STAT); + break; + + case SSH_SFTP_DOWNLOAD_STAT: + { + sftp_attributes attrs; + curl_off_t size; + + attrs = sftp_fstat(sshc->sftp_file); + if(!attrs || + !(attrs->flags & SSH_FILEXFER_ATTR_SIZE) || + (attrs->size == 0)) { + /* + * sftp_fstat didn't return an error, so maybe the server + * just doesn't support stat() + * OR the server doesn't return a file size with a stat() + * OR file size is 0 + */ + data->req.size = -1; + data->req.maxdownload = -1; + Curl_pgrsSetDownloadSize(data, -1); + size = 0; + } + else { + size = attrs->size; + + sftp_attributes_free(attrs); + + if(size < 0) { + failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + if(conn->data->state.use_range) { + curl_off_t from, to; + char *ptr; + char *ptr2; + CURLofft to_t; + CURLofft from_t; + + from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from); + if(from_t == CURL_OFFT_FLOW) { + return CURLE_RANGE_ERROR; + } + while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) + ptr++; + to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); + if(to_t == CURL_OFFT_FLOW) { + return CURLE_RANGE_ERROR; + } + if((to_t == CURL_OFFT_INVAL) /* no "to" value given */ + || (to >= size)) { + to = size - 1; + } + if(from_t) { + /* from is relative to end of file */ + from = size - to; + to = size - 1; + } + if(from > size) { + failf(data, "Offset (%" + CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" + CURL_FORMAT_CURL_OFF_T ")", from, size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + if(from > to) { + from = to; + size = 0; + } + else { + size = to - from + 1; + } + + rc = sftp_seek64(sshc->sftp_file, from); + if(rc != 0) { + MOVE_TO_SFTP_CLOSE_STATE(); + } + } + data->req.size = size; + data->req.maxdownload = size; + Curl_pgrsSetDownloadSize(data, size); + } + + /* We can resume if we can seek to the resume position */ + if(data->state.resume_from) { + if(data->state.resume_from < 0) { + /* We're supposed to download the last abs(from) bytes */ + if((curl_off_t)size < -data->state.resume_from) { + failf(data, "Offset (%" + CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" + CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + /* download from where? */ + data->state.resume_from += size; + } + else { + if((curl_off_t)size < data->state.resume_from) { + failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T + ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + } + /* Does a completed file need to be seeked and started or closed ? */ + /* Now store the number of bytes we are expected to download */ + data->req.size = size - data->state.resume_from; + data->req.maxdownload = size - data->state.resume_from; + Curl_pgrsSetDownloadSize(data, + size - data->state.resume_from); + + rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); + if(rc != 0) { + MOVE_TO_SFTP_CLOSE_STATE(); + } + } + } + + /* Setup the actual download */ + if(data->req.size == 0) { + /* no data to transfer */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + infof(data, "File already completely downloaded\n"); + state(conn, SSH_STOP); + break; + } + Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->writesockfd = conn->sockfd; + + /* we want to use the _receiving_ function even when the socket turns + out writableable as the underlying libssh recv function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_IN; + + if(result) { + /* this should never occur; the close state should be entered + at the time the error occurs */ + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = result; + } + else { + sshc->sftp_recv_state = 0; + state(conn, SSH_STOP); + } + break; + + case SSH_SFTP_CLOSE: + if(sshc->sftp_file) { + sftp_close(sshc->sftp_file); + sshc->sftp_file = NULL; + } + Curl_safefree(protop->path); + + DEBUGF(infof(data, "SFTP DONE done\n")); + + /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT + After nextstate is executed, the control should come back to + SSH_SFTP_CLOSE to pass the correct result back */ + if(sshc->nextstate != SSH_NO_STATE && + sshc->nextstate != SSH_SFTP_CLOSE) { + state(conn, sshc->nextstate); + sshc->nextstate = SSH_SFTP_CLOSE; + } + else { + state(conn, SSH_STOP); + result = sshc->actualcode; + } + break; + + case SSH_SFTP_SHUTDOWN: + /* during times we get here due to a broken transfer and then the + sftp_handle might not have been taken down so make sure that is done + before we proceed */ + + if(sshc->sftp_file) { + sftp_close(sshc->sftp_file); + sshc->sftp_file = NULL; + } + + if(sshc->sftp_session) { + sftp_free(sshc->sftp_session); + sshc->sftp_session = NULL; + } + + SSH_STRING_FREE_CHAR(sshc->homedir); + conn->data->state.most_recent_ftp_entrypath = NULL; + + state(conn, SSH_SESSION_DISCONNECT); + break; + + + case SSH_SCP_TRANS_INIT: + result = Curl_getworkingpath(conn, sshc->homedir, &protop->path); + if(result) { + sshc->actualcode = result; + state(conn, SSH_STOP); + break; + } + + /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */ + ssh_set_blocking(sshc->ssh_session, 1); + + if(data->set.upload) { + if(data->state.infilesize < 0) { + failf(data, "SCP requires a known file size for upload"); + sshc->actualcode = CURLE_UPLOAD_FAILED; + MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + } + + sshc->scp_session = + ssh_scp_new(sshc->ssh_session, SSH_SCP_WRITE, protop->path); + state(conn, SSH_SCP_UPLOAD_INIT); + } + else { + sshc->scp_session = + ssh_scp_new(sshc->ssh_session, SSH_SCP_READ, protop->path); + state(conn, SSH_SCP_DOWNLOAD_INIT); + } + + if(!sshc->scp_session) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + } + + break; + + case SSH_SCP_UPLOAD_INIT: + + rc = ssh_scp_init(sshc->scp_session); + if(rc != SSH_OK) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + } + + rc = ssh_scp_push_file(sshc->scp_session, protop->path, + data->state.infilesize, + (int)data->set.new_file_perms); + if(rc != SSH_OK) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + } + + /* upload data */ + Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->sockfd = conn->writesockfd; + + /* store this original bitmask setup to use later on if we can't + figure out a "real" bitmask */ + sshc->orig_waitfor = data->req.keepon; + + /* we want to use the _sending_ function even when the socket turns + out readable as the underlying libssh scp send function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_OUT; + + state(conn, SSH_STOP); + + break; + + case SSH_SCP_DOWNLOAD_INIT: + + rc = ssh_scp_init(sshc->scp_session); + if(rc != SSH_OK) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + } + state(conn, SSH_SCP_DOWNLOAD); + /* FALLTHROUGH */ + + case SSH_SCP_DOWNLOAD:{ + curl_off_t bytecount; + + rc = ssh_scp_pull_request(sshc->scp_session); + if(rc != SSH_SCP_REQUEST_NEWFILE) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_REMOTE_FILE_NOT_FOUND); + break; + } + + /* download data */ + bytecount = ssh_scp_request_get_size(sshc->scp_session); + data->req.maxdownload = (curl_off_t) bytecount; + Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->writesockfd = conn->sockfd; + + /* we want to use the _receiving_ function even when the socket turns + out writableable as the underlying libssh recv function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_IN; + + state(conn, SSH_STOP); + break; + } + case SSH_SCP_DONE: + if(data->set.upload) + state(conn, SSH_SCP_SEND_EOF); + else + state(conn, SSH_SCP_CHANNEL_FREE); + break; + + case SSH_SCP_SEND_EOF: + if(sshc->scp_session) { + rc = ssh_scp_close(sshc->scp_session); + if(rc == SSH_AGAIN) { + /* Currently the ssh_scp_close handles waiting for EOF in + * blocking way. + */ + break; + } + if(rc != SSH_OK) { + infof(data, "Failed to close libssh scp channel: %s\n", + ssh_get_error(sshc->ssh_session)); + } + } + + state(conn, SSH_SCP_CHANNEL_FREE); + break; + + case SSH_SCP_CHANNEL_FREE: + if(sshc->scp_session) { + ssh_scp_free(sshc->scp_session); + sshc->scp_session = NULL; + } + DEBUGF(infof(data, "SCP DONE phase complete\n")); + + ssh_set_blocking(sshc->ssh_session, 0); + + state(conn, SSH_SESSION_DISCONNECT); + /* FALLTHROUGH */ + + case SSH_SESSION_DISCONNECT: + /* during weird times when we've been prematurely aborted, the channel + is still alive when we reach this state and we MUST kill the channel + properly first */ + if(sshc->scp_session) { + ssh_scp_free(sshc->scp_session); + sshc->scp_session = NULL; + } + + ssh_disconnect(sshc->ssh_session); + + SSH_STRING_FREE_CHAR(sshc->homedir); + conn->data->state.most_recent_ftp_entrypath = NULL; + + state(conn, SSH_SESSION_FREE); + /* FALLTHROUGH */ + case SSH_SESSION_FREE: + if(sshc->ssh_session) { + ssh_free(sshc->ssh_session); + sshc->ssh_session = NULL; + } + + /* worst-case scenario cleanup */ + + DEBUGASSERT(sshc->ssh_session == NULL); + DEBUGASSERT(sshc->scp_session == NULL); + + if(sshc->readdir_tmp) { + ssh_string_free_char(sshc->readdir_tmp); + sshc->readdir_tmp = NULL; + } + + if(sshc->quote_attrs) + sftp_attributes_free(sshc->quote_attrs); + + if(sshc->readdir_attrs) + sftp_attributes_free(sshc->readdir_attrs); + + if(sshc->readdir_link_attrs) + sftp_attributes_free(sshc->readdir_link_attrs); + + if(sshc->privkey) + ssh_key_free(sshc->privkey); + if(sshc->pubkey) + ssh_key_free(sshc->pubkey); + + Curl_safefree(sshc->rsa_pub); + Curl_safefree(sshc->rsa); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + Curl_safefree(sshc->readdir_line); + Curl_safefree(sshc->readdir_linkPath); + SSH_STRING_FREE_CHAR(sshc->homedir); + + /* the code we are about to return */ + result = sshc->actualcode; + + memset(sshc, 0, sizeof(struct ssh_conn)); + + connclose(conn, "SSH session free"); + sshc->state = SSH_SESSION_FREE; /* current */ + sshc->nextstate = SSH_NO_STATE; + state(conn, SSH_STOP); + break; + + case SSH_QUIT: + /* fallthrough, just stop! */ + default: + /* internal error */ + sshc->nextstate = SSH_NO_STATE; + state(conn, SSH_STOP); + break; + + } + } while(!rc && (sshc->state != SSH_STOP)); + + + if(rc == SSH_AGAIN) { + /* we would block, we need to wait for the socket to be ready (in the + right direction too)! */ + *block = TRUE; + } + + return result; +} + + +/* called by the multi interface to figure out what socket(s) to wait for and + for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ +static int myssh_perform_getsock(const struct connectdata *conn, + curl_socket_t *sock, /* points to numsocks + number of sockets */ + int numsocks) +{ + int bitmap = GETSOCK_BLANK; + (void) numsocks; + + sock[0] = conn->sock[FIRSTSOCKET]; + + if(conn->waitfor & KEEP_RECV) + bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); + + if(conn->waitfor & KEEP_SEND) + bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); + + return bitmap; +} + +/* Generic function called by the multi interface to figure out what socket(s) + to wait for and for what actions during the DOING and PROTOCONNECT states*/ +static int myssh_getsock(struct connectdata *conn, + curl_socket_t *sock, /* points to numsocks + number of sockets */ + int numsocks) +{ + /* if we know the direction we can use the generic *_getsock() function even + for the protocol_connect and doing states */ + return myssh_perform_getsock(conn, sock, numsocks); +} + +static void myssh_block2waitfor(struct connectdata *conn, bool block) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + + /* If it didn't block, or nothing was returned by ssh_get_poll_flags + * have the original set */ + conn->waitfor = sshc->orig_waitfor; + + if(block) { + int dir = ssh_get_poll_flags(sshc->ssh_session); + if(dir & SSH_READ_PENDING) { + /* translate the libssh define bits into our own bit defines */ + conn->waitfor = KEEP_RECV; + } + else if(dir & SSH_WRITE_PENDING) { + conn->waitfor = KEEP_SEND; + } + } +} + +/* called repeatedly until done from multi.c */ +static CURLcode myssh_multi_statemach(struct connectdata *conn, + bool *done) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + bool block; /* we store the status and use that to provide a ssh_getsock() + implementation */ + CURLcode result = myssh_statemach_act(conn, &block); + + *done = (sshc->state == SSH_STOP) ? TRUE : FALSE; + myssh_block2waitfor(conn, block); + + return result; +} + +static CURLcode myssh_block_statemach(struct connectdata *conn, + bool disconnect) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + while((sshc->state != SSH_STOP) && !result) { + bool block; + timediff_t left = 1000; + struct curltime now = Curl_now(); + + result = myssh_statemach_act(conn, &block); + if(result) + break; + + if(!disconnect) { + if(Curl_pgrsUpdate(conn)) + return CURLE_ABORTED_BY_CALLBACK; + + result = Curl_speedcheck(data, now); + if(result) + break; + + left = Curl_timeleft(data, NULL, FALSE); + if(left < 0) { + failf(data, "Operation timed out"); + return CURLE_OPERATION_TIMEDOUT; + } + } + + if(!result && block) { + curl_socket_t fd_read = conn->sock[FIRSTSOCKET]; + /* wait for the socket to become ready */ + (void) Curl_socket_check(fd_read, CURL_SOCKET_BAD, + CURL_SOCKET_BAD, left > 1000 ? 1000 : left); + } + + } + + return result; +} + +/* + * SSH setup connection + */ +static CURLcode myssh_setup_connection(struct connectdata *conn) +{ + struct SSHPROTO *ssh; + + conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO)); + if(!ssh) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; +} + +static Curl_recv scp_recv, sftp_recv; +static Curl_send scp_send, sftp_send; + +/* + * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to + * do protocol-specific actions at connect-time. + */ +static CURLcode myssh_connect(struct connectdata *conn, bool *done) +{ + struct ssh_conn *ssh; + CURLcode result; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + struct Curl_easy *data = conn->data; + + /* initialize per-handle data if not already */ + if(!data->req.protop) + myssh_setup_connection(conn); + + /* We default to persistent connections. We set this already in this connect + function to make the re-use checks properly be able to check this bit. */ + connkeep(conn, "SSH default"); + + if(conn->handler->protocol & CURLPROTO_SCP) { + conn->recv[FIRSTSOCKET] = scp_recv; + conn->send[FIRSTSOCKET] = scp_send; + } + else { + conn->recv[FIRSTSOCKET] = sftp_recv; + conn->send[FIRSTSOCKET] = sftp_send; + } + + ssh = &conn->proto.sshc; + + ssh->ssh_session = ssh_new(); + if(ssh->ssh_session == NULL) { + failf(data, "Failure initialising ssh session"); + return CURLE_FAILED_INIT; + } + + ssh_options_set(ssh->ssh_session, SSH_OPTIONS_FD, &sock); + + if(conn->user) { + infof(data, "User: %s\n", conn->user); + ssh_options_set(ssh->ssh_session, SSH_OPTIONS_USER, conn->user); + } + + if(data->set.str[STRING_SSH_KNOWNHOSTS]) { + infof(data, "Known hosts: %s\n", data->set.str[STRING_SSH_KNOWNHOSTS]); + ssh_options_set(ssh->ssh_session, SSH_OPTIONS_KNOWNHOSTS, + data->set.str[STRING_SSH_KNOWNHOSTS]); + } + + ssh_options_set(ssh->ssh_session, SSH_OPTIONS_HOST, conn->host.name); + if(conn->remote_port) + ssh_options_set(ssh->ssh_session, SSH_OPTIONS_PORT, + &conn->remote_port); + + if(data->set.ssh_compression) { + ssh_options_set(ssh->ssh_session, SSH_OPTIONS_COMPRESSION, + "zlib,zlib@openssh.com,none"); + } + + ssh->privkey = NULL; + ssh->pubkey = NULL; + + if(data->set.str[STRING_SSH_PUBLIC_KEY]) { + int rc = ssh_pki_import_pubkey_file(data->set.str[STRING_SSH_PUBLIC_KEY], + &ssh->pubkey); + if(rc != SSH_OK) { + failf(data, "Could not load public key file"); + /* ignore */ + } + } + + /* we do not verify here, we do it at the state machine, + * after connection */ + + state(conn, SSH_INIT); + + result = myssh_multi_statemach(conn, done); + + return result; +} + +/* called from multi.c while DOing */ +static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done) +{ + CURLcode result; + + result = myssh_multi_statemach(conn, dophase_done); + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + return result; +} + +/* + *********************************************************************** + * + * scp_perform() + * + * This is the actual DO function for SCP. Get a file according to + * the options previously setup. + */ + +static +CURLcode scp_perform(struct connectdata *conn, + bool *connected, bool *dophase_done) +{ + CURLcode result = CURLE_OK; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + *dophase_done = FALSE; /* not done yet */ + + /* start the first command in the DO phase */ + state(conn, SSH_SCP_TRANS_INIT); + + result = myssh_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +static CURLcode myssh_do_it(struct connectdata *conn, bool *done) +{ + CURLcode result; + bool connected = 0; + struct Curl_easy *data = conn->data; + struct ssh_conn *sshc = &conn->proto.sshc; + + *done = FALSE; /* default to false */ + + data->req.size = -1; /* make sure this is unknown at this point */ + + sshc->actualcode = CURLE_OK; /* reset error code */ + sshc->secondCreateDirs = 0; /* reset the create dir attempt state + variable */ + + Curl_pgrsSetUploadCounter(data, 0); + Curl_pgrsSetDownloadCounter(data, 0); + Curl_pgrsSetUploadSize(data, -1); + Curl_pgrsSetDownloadSize(data, -1); + + if(conn->handler->protocol & CURLPROTO_SCP) + result = scp_perform(conn, &connected, done); + else + result = sftp_perform(conn, &connected, done); + + return result; +} + +/* BLOCKING, but the function is using the state machine so the only reason + this is still blocking is that the multi interface code has no support for + disconnecting operations that takes a while */ +static CURLcode scp_disconnect(struct connectdata *conn, + bool dead_connection) +{ + CURLcode result = CURLE_OK; + struct ssh_conn *ssh = &conn->proto.sshc; + (void) dead_connection; + + if(ssh->ssh_session) { + /* only if there's a session still around to use! */ + + state(conn, SSH_SESSION_DISCONNECT); + + result = myssh_block_statemach(conn, TRUE); + } + + return result; +} + +/* generic done function for both SCP and SFTP called from their specific + done functions */ +static CURLcode myssh_done(struct connectdata *conn, CURLcode status) +{ + CURLcode result = CURLE_OK; + struct SSHPROTO *protop = conn->data->req.protop; + + if(!status) { + /* run the state-machine */ + result = myssh_block_statemach(conn, FALSE); + } + else + result = status; + + if(protop) + Curl_safefree(protop->path); + if(Curl_pgrsDone(conn)) + return CURLE_ABORTED_BY_CALLBACK; + + conn->data->req.keepon = 0; /* clear all bits */ + return result; +} + + +static CURLcode scp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + (void) premature; /* not used */ + + if(!status) + state(conn, SSH_SCP_DONE); + + return myssh_done(conn, status); + +} + +static ssize_t scp_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) +{ + int rc; + (void) sockindex; /* we only support SCP on the fixed known primary socket */ + (void) err; + + rc = ssh_scp_write(conn->proto.sshc.scp_session, mem, len); + +#if 0 + /* The following code is misleading, mostly added as wishful thinking + * that libssh at some point will implement non-blocking ssh_scp_write/read. + * Currently rc can only be number of bytes read or SSH_ERROR. */ + myssh_block2waitfor(conn, (rc == SSH_AGAIN) ? TRUE : FALSE); + + if(rc == SSH_AGAIN) { + *err = CURLE_AGAIN; + return 0; + } + else +#endif + if(rc != SSH_OK) { + *err = CURLE_SSH; + return -1; + } + + return len; +} + +static ssize_t scp_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) +{ + ssize_t nread; + (void) err; + (void) sockindex; /* we only support SCP on the fixed known primary socket */ + + /* libssh returns int */ + nread = ssh_scp_read(conn->proto.sshc.scp_session, mem, len); + +#if 0 + /* The following code is misleading, mostly added as wishful thinking + * that libssh at some point will implement non-blocking ssh_scp_write/read. + * Currently rc can only be SSH_OK or SSH_ERROR. */ + + myssh_block2waitfor(conn, (nread == SSH_AGAIN) ? TRUE : FALSE); + if(nread == SSH_AGAIN) { + *err = CURLE_AGAIN; + nread = -1; + } +#endif + + return nread; +} + +/* + * =============== SFTP =============== + */ + +/* + *********************************************************************** + * + * sftp_perform() + * + * This is the actual DO function for SFTP. Get a file/directory according to + * the options previously setup. + */ + +static +CURLcode sftp_perform(struct connectdata *conn, + bool *connected, + bool *dophase_done) +{ + CURLcode result = CURLE_OK; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + *dophase_done = FALSE; /* not done yet */ + + /* start the first command in the DO phase */ + state(conn, SSH_SFTP_QUOTE_INIT); + + /* run the state-machine */ + result = myssh_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +/* called from multi.c while DOing */ +static CURLcode sftp_doing(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result = myssh_multi_statemach(conn, dophase_done); + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + return result; +} + +/* BLOCKING, but the function is using the state machine so the only reason + this is still blocking is that the multi interface code has no support for + disconnecting operations that takes a while */ +static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection) +{ + CURLcode result = CURLE_OK; + (void) dead_connection; + + DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n")); + + if(conn->proto.sshc.ssh_session) { + /* only if there's a session still around to use! */ + state(conn, SSH_SFTP_SHUTDOWN); + result = myssh_block_statemach(conn, TRUE); + } + + DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n")); + + return result; + +} + +static CURLcode sftp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + + if(!status) { + /* Post quote commands are executed after the SFTP_CLOSE state to avoid + errors that could happen due to open file handles during POSTQUOTE + operation */ + if(!premature && conn->data->set.postquote && !conn->bits.retry) + sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; + state(conn, SSH_SFTP_CLOSE); + } + return myssh_done(conn, status); +} + +/* return number of sent bytes */ +static ssize_t sftp_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) +{ + ssize_t nwrite; + (void)sockindex; + + nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len); + + myssh_block2waitfor(conn, FALSE); + +#if 0 /* not returned by libssh on write */ + if(nwrite == SSH_AGAIN) { + *err = CURLE_AGAIN; + nwrite = 0; + } + else +#endif + if(nwrite < 0) { + *err = CURLE_SSH; + nwrite = -1; + } + + return nwrite; +} + +/* + * Return number of received (decrypted) bytes + * or <0 on error + */ +static ssize_t sftp_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) +{ + ssize_t nread; + (void)sockindex; + + DEBUGASSERT(len < CURL_MAX_READ_SIZE); + + switch(conn->proto.sshc.sftp_recv_state) { + case 0: + conn->proto.sshc.sftp_file_index = + sftp_async_read_begin(conn->proto.sshc.sftp_file, + (uint32_t)len); + if(conn->proto.sshc.sftp_file_index < 0) { + *err = CURLE_RECV_ERROR; + return -1; + } + + /* FALLTHROUGH */ + case 1: + conn->proto.sshc.sftp_recv_state = 1; + + nread = sftp_async_read(conn->proto.sshc.sftp_file, + mem, (uint32_t)len, + conn->proto.sshc.sftp_file_index); + + myssh_block2waitfor(conn, (nread == SSH_AGAIN)?TRUE:FALSE); + + if(nread == SSH_AGAIN) { + *err = CURLE_AGAIN; + return -1; + } + else if(nread < 0) { + *err = CURLE_RECV_ERROR; + return -1; + } + + conn->proto.sshc.sftp_recv_state = 0; + return nread; + + default: + /* we never reach here */ + return -1; + } +} + +static void sftp_quote(struct connectdata *conn) +{ + const char *cp; + struct Curl_easy *data = conn->data; + struct SSHPROTO *protop = data->req.protop; + struct ssh_conn *sshc = &conn->proto.sshc; + CURLcode result; + + /* + * Support some of the "FTP" commands + */ + char *cmd = sshc->quote_item->data; + sshc->acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal SFTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server reponds. */ + + if(cmd[0] == '*') { + cmd++; + sshc->acceptfail = TRUE; + } + + if(strcasecompare("pwd", cmd)) { + /* output debug output if that is requested */ + char *tmp = aprintf("257 \"%s\" is current directory.\n", + protop->path); + if(!tmp) { + sshc->actualcode = CURLE_OUT_OF_MEMORY; + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + return; + } + if(data->set.verbose) { + Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4); + Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp)); + } + /* this sends an FTP-like "header" to the header callback so that the + current directory can be read very similar to how it is read when + using ordinary FTP. */ + result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + free(tmp); + if(result) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + } + else + state(conn, SSH_SFTP_NEXT_QUOTE); + return; + } + + /* + * the arguments following the command must be separated from the + * command with a space so we can check for it unconditionally + */ + cp = strchr(cmd, ' '); + if(cp == NULL) { + failf(data, "Syntax error in SFTP command. Supply parameter(s)!"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + + /* + * also, every command takes at least one argument so we get that + * first argument right now + */ + result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error: Bad first parameter"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return; + } + + /* + * SFTP is a binary protocol, so we don't send text commands + * to the server. Instead, we scan for commands used by + * OpenSSH's sftp program and call the appropriate libssh + * functions. + */ + if(strncasecompare(cmd, "chgrp ", 6) || + strncasecompare(cmd, "chmod ", 6) || + strncasecompare(cmd, "chown ", 6)) { + /* attribute change */ + + /* sshc->quote_path1 contains the mode to set */ + /* get the destination */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in chgrp/chmod/chown: " + "Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return; + } + sshc->quote_attrs = NULL; + state(conn, SSH_SFTP_QUOTE_STAT); + return; + } + if(strncasecompare(cmd, "ln ", 3) || + strncasecompare(cmd, "symlink ", 8)) { + /* symbolic linking */ + /* sshc->quote_path1 is the source */ + /* get the destination */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in ln/symlink: Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return; + } + state(conn, SSH_SFTP_QUOTE_SYMLINK); + return; + } + else if(strncasecompare(cmd, "mkdir ", 6)) { + /* create dir */ + state(conn, SSH_SFTP_QUOTE_MKDIR); + return; + } + else if(strncasecompare(cmd, "rename ", 7)) { + /* rename file */ + /* first param is the source path */ + /* second param is the dest. path */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in rename: Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return; + } + state(conn, SSH_SFTP_QUOTE_RENAME); + return; + } + else if(strncasecompare(cmd, "rmdir ", 6)) { + /* delete dir */ + state(conn, SSH_SFTP_QUOTE_RMDIR); + return; + } + else if(strncasecompare(cmd, "rm ", 3)) { + state(conn, SSH_SFTP_QUOTE_UNLINK); + return; + } +#ifdef HAS_STATVFS_SUPPORT + else if(strncasecompare(cmd, "statvfs ", 8)) { + state(conn, SSH_SFTP_QUOTE_STATVFS); + return; + } +#endif + + failf(data, "Unknown SFTP command"); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; +} + +static void sftp_quote_stat(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + struct ssh_conn *sshc = &conn->proto.sshc; + char *cmd = sshc->quote_item->data; + sshc->acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal SFTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server reponds. */ + + if(cmd[0] == '*') { + cmd++; + sshc->acceptfail = TRUE; + } + + /* We read the file attributes, store them in sshc->quote_attrs + * and modify them accordingly to command. Then we switch to + * QUOTE_SETSTAT state to write new ones. + */ + + if(sshc->quote_attrs) + sftp_attributes_free(sshc->quote_attrs); + sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2); + if(sshc->quote_attrs == NULL) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Attempt to get SFTP stats failed: %d", + sftp_get_error(sshc->sftp_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + + /* Now set the new attributes... */ + if(strncasecompare(cmd, "chgrp", 5)) { + sshc->quote_attrs->gid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10); + if(sshc->quote_attrs->gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chgrp gid not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; + } + else if(strncasecompare(cmd, "chmod", 5)) { + mode_t perms; + perms = (mode_t)strtoul(sshc->quote_path1, NULL, 8); + /* permissions are octal */ + if(perms == 0 && !ISDIGIT(sshc->quote_path1[0])) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chmod permissions not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + sshc->quote_attrs->permissions = perms; + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_PERMISSIONS; + } + else if(strncasecompare(cmd, "chown", 5)) { + sshc->quote_attrs->uid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10); + if(sshc->quote_attrs->uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chown uid not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; + } + + /* Now send the completed structure... */ + state(conn, SSH_SFTP_QUOTE_SETSTAT); + return; +} + + +#endif /* USE_LIBSSH */ diff --git a/libcurl/lib/ssh.c b/libcurl/lib/ssh.c new file mode 100644 index 0000000..a265c3c --- /dev/null +++ b/libcurl/lib/ssh.c @@ -0,0 +1,3337 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* #define CURL_LIBSSH2_DEBUG */ + +#include "curl_setup.h" + +#ifdef USE_LIBSSH2 + +#include + +#include +#include + +#ifdef HAVE_FCNTL_H +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_UTSNAME_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef __VMS +#include +#include +#endif + +#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +#include +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "progress.h" +#include "transfer.h" +#include "escape.h" +#include "http.h" /* for HTTP proxy tunnel stuff */ +#include "ssh.h" +#include "url.h" +#include "speedcheck.h" +#include "getinfo.h" +#include "strdup.h" +#include "strcase.h" +#include "vtls/vtls.h" +#include "connect.h" +#include "strerror.h" +#include "inet_ntop.h" +#include "parsedate.h" /* for the week day and month names */ +#include "sockaddr.h" /* required for Curl_sockaddr_storage */ +#include "strtoofft.h" +#include "multiif.h" +#include "select.h" +#include "warnless.h" +#include "curl_path.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#if LIBSSH2_VERSION_NUM >= 0x010206 +/* libssh2_sftp_statvfs and friends were added in 1.2.6 */ +#define HAS_STATVFS_SUPPORT 1 +#endif + +#define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s)) + +#define sftp_libssh2_realpath(s,p,t,m) \ + libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \ + (t), (m), LIBSSH2_SFTP_REALPATH) + + +/* Local functions: */ +static const char *sftp_libssh2_strerror(int err); +static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc); +static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc); +static LIBSSH2_FREE_FUNC(my_libssh2_free); + +static CURLcode ssh_connect(struct connectdata *conn, bool *done); +static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done); +static CURLcode ssh_do(struct connectdata *conn, bool *done); + +static CURLcode scp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode scp_doing(struct connectdata *conn, + bool *dophase_done); +static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection); + +static CURLcode sftp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode sftp_doing(struct connectdata *conn, + bool *dophase_done); +static CURLcode sftp_disconnect(struct connectdata *conn, bool dead); +static +CURLcode sftp_perform(struct connectdata *conn, + bool *connected, + bool *dophase_done); + +static int ssh_getsock(struct connectdata *conn, + curl_socket_t *sock, /* points to numsocks number + of sockets */ + int numsocks); + +static int ssh_perform_getsock(const struct connectdata *conn, + curl_socket_t *sock, /* points to numsocks + number of sockets */ + int numsocks); + +static CURLcode ssh_setup_connection(struct connectdata *conn); + +/* + * SCP protocol handler. + */ + +const struct Curl_handler Curl_handler_scp = { + "SCP", /* scheme */ + ssh_setup_connection, /* setup_connection */ + ssh_do, /* do_it */ + scp_done, /* done */ + ZERO_NULL, /* do_more */ + ssh_connect, /* connect_it */ + ssh_multi_statemach, /* connecting */ + scp_doing, /* doing */ + ssh_getsock, /* proto_getsock */ + ssh_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ssh_perform_getsock, /* perform_getsock */ + scp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SSH, /* defport */ + CURLPROTO_SCP, /* protocol */ + PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION + | PROTOPT_NOURLQUERY /* flags */ +}; + + +/* + * SFTP protocol handler. + */ + +const struct Curl_handler Curl_handler_sftp = { + "SFTP", /* scheme */ + ssh_setup_connection, /* setup_connection */ + ssh_do, /* do_it */ + sftp_done, /* done */ + ZERO_NULL, /* do_more */ + ssh_connect, /* connect_it */ + ssh_multi_statemach, /* connecting */ + sftp_doing, /* doing */ + ssh_getsock, /* proto_getsock */ + ssh_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ssh_perform_getsock, /* perform_getsock */ + sftp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SSH, /* defport */ + CURLPROTO_SFTP, /* protocol */ + PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION + | PROTOPT_NOURLQUERY /* flags */ +}; + +static void +kbd_callback(const char *name, int name_len, const char *instruction, + int instruction_len, int num_prompts, + const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, + LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, + void **abstract) +{ + struct connectdata *conn = (struct connectdata *)*abstract; + +#ifdef CURL_LIBSSH2_DEBUG + fprintf(stderr, "name=%s\n", name); + fprintf(stderr, "name_len=%d\n", name_len); + fprintf(stderr, "instruction=%s\n", instruction); + fprintf(stderr, "instruction_len=%d\n", instruction_len); + fprintf(stderr, "num_prompts=%d\n", num_prompts); +#else + (void)name; + (void)name_len; + (void)instruction; + (void)instruction_len; +#endif /* CURL_LIBSSH2_DEBUG */ + if(num_prompts == 1) { + responses[0].text = strdup(conn->passwd); + responses[0].length = curlx_uztoui(strlen(conn->passwd)); + } + (void)prompts; + (void)abstract; +} /* kbd_callback */ + +static CURLcode sftp_libssh2_error_to_CURLE(int err) +{ + switch(err) { + case LIBSSH2_FX_OK: + return CURLE_OK; + + case LIBSSH2_FX_NO_SUCH_FILE: + case LIBSSH2_FX_NO_SUCH_PATH: + return CURLE_REMOTE_FILE_NOT_FOUND; + + case LIBSSH2_FX_PERMISSION_DENIED: + case LIBSSH2_FX_WRITE_PROTECT: + case LIBSSH2_FX_LOCK_CONFlICT: + return CURLE_REMOTE_ACCESS_DENIED; + + case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM: + case LIBSSH2_FX_QUOTA_EXCEEDED: + return CURLE_REMOTE_DISK_FULL; + + case LIBSSH2_FX_FILE_ALREADY_EXISTS: + return CURLE_REMOTE_FILE_EXISTS; + + case LIBSSH2_FX_DIR_NOT_EMPTY: + return CURLE_QUOTE_ERROR; + + default: + break; + } + + return CURLE_SSH; +} + +static CURLcode libssh2_session_error_to_CURLE(int err) +{ + switch(err) { + /* Ordered by order of appearance in libssh2.h */ + case LIBSSH2_ERROR_NONE: + return CURLE_OK; + + /* This is the error returned by libssh2_scp_recv2 + * on unknown file */ + case LIBSSH2_ERROR_SCP_PROTOCOL: + return CURLE_REMOTE_FILE_NOT_FOUND; + + case LIBSSH2_ERROR_SOCKET_NONE: + return CURLE_COULDNT_CONNECT; + + case LIBSSH2_ERROR_ALLOC: + return CURLE_OUT_OF_MEMORY; + + case LIBSSH2_ERROR_SOCKET_SEND: + return CURLE_SEND_ERROR; + + case LIBSSH2_ERROR_HOSTKEY_INIT: + case LIBSSH2_ERROR_HOSTKEY_SIGN: + case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED: + case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED: + return CURLE_PEER_FAILED_VERIFICATION; + + case LIBSSH2_ERROR_PASSWORD_EXPIRED: + return CURLE_LOGIN_DENIED; + + case LIBSSH2_ERROR_SOCKET_TIMEOUT: + case LIBSSH2_ERROR_TIMEOUT: + return CURLE_OPERATION_TIMEDOUT; + + case LIBSSH2_ERROR_EAGAIN: + return CURLE_AGAIN; + } + + return CURLE_SSH; +} + +static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc) +{ + (void)abstract; /* arg not used */ + return malloc(count); +} + +static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc) +{ + (void)abstract; /* arg not used */ + return realloc(ptr, count); +} + +static LIBSSH2_FREE_FUNC(my_libssh2_free) +{ + (void)abstract; /* arg not used */ + if(ptr) /* ssh2 agent sometimes call free with null ptr */ + free(ptr); +} + +/* + * SSH State machine related code + */ +/* This is the ONLY way to change SSH state! */ +static void state(struct connectdata *conn, sshstate nowstate) +{ + struct ssh_conn *sshc = &conn->proto.sshc; +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* for debug purposes */ + static const char * const names[] = { + "SSH_STOP", + "SSH_INIT", + "SSH_S_STARTUP", + "SSH_HOSTKEY", + "SSH_AUTHLIST", + "SSH_AUTH_PKEY_INIT", + "SSH_AUTH_PKEY", + "SSH_AUTH_PASS_INIT", + "SSH_AUTH_PASS", + "SSH_AUTH_AGENT_INIT", + "SSH_AUTH_AGENT_LIST", + "SSH_AUTH_AGENT", + "SSH_AUTH_HOST_INIT", + "SSH_AUTH_HOST", + "SSH_AUTH_KEY_INIT", + "SSH_AUTH_KEY", + "SSH_AUTH_GSSAPI", + "SSH_AUTH_DONE", + "SSH_SFTP_INIT", + "SSH_SFTP_REALPATH", + "SSH_SFTP_QUOTE_INIT", + "SSH_SFTP_POSTQUOTE_INIT", + "SSH_SFTP_QUOTE", + "SSH_SFTP_NEXT_QUOTE", + "SSH_SFTP_QUOTE_STAT", + "SSH_SFTP_QUOTE_SETSTAT", + "SSH_SFTP_QUOTE_SYMLINK", + "SSH_SFTP_QUOTE_MKDIR", + "SSH_SFTP_QUOTE_RENAME", + "SSH_SFTP_QUOTE_RMDIR", + "SSH_SFTP_QUOTE_UNLINK", + "SSH_SFTP_QUOTE_STATVFS", + "SSH_SFTP_GETINFO", + "SSH_SFTP_FILETIME", + "SSH_SFTP_TRANS_INIT", + "SSH_SFTP_UPLOAD_INIT", + "SSH_SFTP_CREATE_DIRS_INIT", + "SSH_SFTP_CREATE_DIRS", + "SSH_SFTP_CREATE_DIRS_MKDIR", + "SSH_SFTP_READDIR_INIT", + "SSH_SFTP_READDIR", + "SSH_SFTP_READDIR_LINK", + "SSH_SFTP_READDIR_BOTTOM", + "SSH_SFTP_READDIR_DONE", + "SSH_SFTP_DOWNLOAD_INIT", + "SSH_SFTP_DOWNLOAD_STAT", + "SSH_SFTP_CLOSE", + "SSH_SFTP_SHUTDOWN", + "SSH_SCP_TRANS_INIT", + "SSH_SCP_UPLOAD_INIT", + "SSH_SCP_DOWNLOAD_INIT", + "SSH_SCP_DOWNLOAD", + "SSH_SCP_DONE", + "SSH_SCP_SEND_EOF", + "SSH_SCP_WAIT_EOF", + "SSH_SCP_WAIT_CLOSE", + "SSH_SCP_CHANNEL_FREE", + "SSH_SESSION_DISCONNECT", + "SSH_SESSION_FREE", + "QUIT" + }; + + /* a precaution to make sure the lists are in sync */ + DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST); + + if(sshc->state != nowstate) { + infof(conn->data, "SFTP %p state change from %s to %s\n", + (void *)sshc, names[sshc->state], names[nowstate]); + } +#endif + + sshc->state = nowstate; +} + + +#ifdef HAVE_LIBSSH2_KNOWNHOST_API +static int sshkeycallback(struct Curl_easy *easy, + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch match, + void *clientp) +{ + (void)easy; + (void)knownkey; + (void)foundkey; + (void)clientp; + + /* we only allow perfect matches, and we reject everything else */ + return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE; +} +#endif + +/* + * Earlier libssh2 versions didn't have the ability to seek to 64bit positions + * with 32bit size_t. + */ +#ifdef HAVE_LIBSSH2_SFTP_SEEK64 +#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y) +#else +#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y) +#endif + +/* + * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit + * architectures so we check of the necessary function is present. + */ +#ifndef HAVE_LIBSSH2_SCP_SEND64 +#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0) +#else +#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \ + (libssh2_uint64_t)d, 0, 0) +#endif + +/* + * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64. + */ +#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE +#define libssh2_session_startup(x,y) libssh2_session_handshake(x,y) +#endif + +static CURLcode ssh_knownhost(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + +#ifdef HAVE_LIBSSH2_KNOWNHOST_API + struct Curl_easy *data = conn->data; + + if(data->set.str[STRING_SSH_KNOWNHOSTS]) { + /* we're asked to verify the host against a file */ + struct ssh_conn *sshc = &conn->proto.sshc; + int rc; + int keytype; + size_t keylen; + const char *remotekey = libssh2_session_hostkey(sshc->ssh_session, + &keylen, &keytype); + int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE; + int keybit = 0; + + if(remotekey) { + /* + * A subject to figure out is what host name we need to pass in here. + * What host name does OpenSSH store in its file if an IDN name is + * used? + */ + struct libssh2_knownhost *host; + enum curl_khmatch keymatch; + curl_sshkeycallback func = + data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback; + struct curl_khkey knownkey; + struct curl_khkey *knownkeyp = NULL; + struct curl_khkey foundkey; + + keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? + LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS; + +#ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP + keycheck = libssh2_knownhost_checkp(sshc->kh, + conn->host.name, + (conn->remote_port != PORT_SSH)? + conn->remote_port:-1, + remotekey, keylen, + LIBSSH2_KNOWNHOST_TYPE_PLAIN| + LIBSSH2_KNOWNHOST_KEYENC_RAW| + keybit, + &host); +#else + keycheck = libssh2_knownhost_check(sshc->kh, + conn->host.name, + remotekey, keylen, + LIBSSH2_KNOWNHOST_TYPE_PLAIN| + LIBSSH2_KNOWNHOST_KEYENC_RAW| + keybit, + &host); +#endif + + infof(data, "SSH host check: %d, key: %s\n", keycheck, + (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)? + host->key:""); + + /* setup 'knownkey' */ + if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) { + knownkey.key = host->key; + knownkey.len = 0; + knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? + CURLKHTYPE_RSA : CURLKHTYPE_DSS; + knownkeyp = &knownkey; + } + + /* setup 'foundkey' */ + foundkey.key = remotekey; + foundkey.len = keylen; + foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? + CURLKHTYPE_RSA : CURLKHTYPE_DSS; + + /* + * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the + * curl_khmatch enum are ever modified, we need to introduce a + * translation table here! + */ + keymatch = (enum curl_khmatch)keycheck; + + /* Ask the callback how to behave */ + Curl_set_in_callback(data, true); + rc = func(data, knownkeyp, /* from the knownhosts file */ + &foundkey, /* from the remote host */ + keymatch, data->set.ssh_keyfunc_userp); + Curl_set_in_callback(data, false); + } + else + /* no remotekey means failure! */ + rc = CURLKHSTAT_REJECT; + + switch(rc) { + default: /* unknown return codes will equal reject */ + /* FALLTHROUGH */ + case CURLKHSTAT_REJECT: + state(conn, SSH_SESSION_FREE); + /* FALLTHROUGH */ + case CURLKHSTAT_DEFER: + /* DEFER means bail out but keep the SSH_HOSTKEY state */ + result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; + break; + case CURLKHSTAT_FINE: + case CURLKHSTAT_FINE_ADD_TO_FILE: + /* proceed */ + if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) { + /* the found host+key didn't match but has been told to be fine + anyway so we add it in memory */ + int addrc = libssh2_knownhost_add(sshc->kh, + conn->host.name, NULL, + remotekey, keylen, + LIBSSH2_KNOWNHOST_TYPE_PLAIN| + LIBSSH2_KNOWNHOST_KEYENC_RAW| + keybit, NULL); + if(addrc) + infof(data, "Warning adding the known host %s failed!\n", + conn->host.name); + else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) { + /* now we write the entire in-memory list of known hosts to the + known_hosts file */ + int wrc = + libssh2_knownhost_writefile(sshc->kh, + data->set.str[STRING_SSH_KNOWNHOSTS], + LIBSSH2_KNOWNHOST_FILE_OPENSSH); + if(wrc) { + infof(data, "Warning, writing %s failed!\n", + data->set.str[STRING_SSH_KNOWNHOSTS]); + } + } + } + break; + } + } +#else /* HAVE_LIBSSH2_KNOWNHOST_API */ + (void)conn; +#endif + return result; +} + +static CURLcode ssh_check_fingerprint(struct connectdata *conn) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + struct Curl_easy *data = conn->data; + const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]; + char md5buffer[33]; + + const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session, + LIBSSH2_HOSTKEY_HASH_MD5); + + if(fingerprint) { + /* The fingerprint points to static storage (!), don't free() it. */ + int i; + for(i = 0; i < 16; i++) + msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]); + infof(data, "SSH MD5 fingerprint: %s\n", md5buffer); + } + + /* Before we authenticate we check the hostkey's MD5 fingerprint + * against a known fingerprint, if available. + */ + if(pubkey_md5 && strlen(pubkey_md5) == 32) { + if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) { + if(fingerprint) + failf(data, + "Denied establishing ssh session: mismatch md5 fingerprint. " + "Remote %s is not equal to %s", md5buffer, pubkey_md5); + else + failf(data, + "Denied establishing ssh session: md5 fingerprint not available"); + state(conn, SSH_SESSION_FREE); + sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; + return sshc->actualcode; + } + infof(data, "MD5 checksum match!\n"); + /* as we already matched, we skip the check for known hosts */ + return CURLE_OK; + } + return ssh_knownhost(conn); +} + +/* + * ssh_statemach_act() runs the SSH state machine as far as it can without + * blocking and without reaching the end. The data the pointer 'block' points + * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN + * meaning it wants to be called again when the socket is ready + */ + +static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct SSHPROTO *sftp_scp = data->req.protop; + struct ssh_conn *sshc = &conn->proto.sshc; + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + char *new_readdir_line; + int rc = LIBSSH2_ERROR_NONE; + int err; + int seekerr = CURL_SEEKFUNC_OK; + *block = 0; /* we're not blocking by default */ + + do { + + switch(sshc->state) { + case SSH_INIT: + sshc->secondCreateDirs = 0; + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_OK; + + /* Set libssh2 to non-blocking, since everything internally is + non-blocking */ + libssh2_session_set_blocking(sshc->ssh_session, 0); + + state(conn, SSH_S_STARTUP); + /* FALLTHROUGH */ + + case SSH_S_STARTUP: + rc = libssh2_session_startup(sshc->ssh_session, (int)sock); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); + failf(data, "Failure establishing ssh session: %d, %s", rc, err_msg); + + state(conn, SSH_SESSION_FREE); + sshc->actualcode = CURLE_FAILED_INIT; + break; + } + + state(conn, SSH_HOSTKEY); + + /* FALLTHROUGH */ + case SSH_HOSTKEY: + /* + * Before we authenticate we should check the hostkey's fingerprint + * against our known hosts. How that is handled (reading from file, + * whatever) is up to us. + */ + result = ssh_check_fingerprint(conn); + if(!result) + state(conn, SSH_AUTHLIST); + /* ssh_check_fingerprint sets state appropriately on error */ + break; + + case SSH_AUTHLIST: + /* + * Figure out authentication methods + * NB: As soon as we have provided a username to an openssh server we + * must never change it later. Thus, always specify the correct username + * here, even though the libssh2 docs kind of indicate that it should be + * possible to get a 'generic' list (not user-specific) of authentication + * methods, presumably with a blank username. That won't work in my + * experience. + * So always specify it here. + */ + sshc->authlist = libssh2_userauth_list(sshc->ssh_session, + conn->user, + curlx_uztoui(strlen(conn->user))); + + if(!sshc->authlist) { + if(libssh2_userauth_authenticated(sshc->ssh_session)) { + sshc->authed = TRUE; + infof(data, "SSH user accepted with no authentication\n"); + state(conn, SSH_AUTH_DONE); + break; + } + err = libssh2_session_last_errno(sshc->ssh_session); + if(err == LIBSSH2_ERROR_EAGAIN) + rc = LIBSSH2_ERROR_EAGAIN; + else { + state(conn, SSH_SESSION_FREE); + sshc->actualcode = libssh2_session_error_to_CURLE(err); + } + break; + } + infof(data, "SSH authentication methods available: %s\n", + sshc->authlist); + + state(conn, SSH_AUTH_PKEY_INIT); + break; + + case SSH_AUTH_PKEY_INIT: + /* + * Check the supported auth types in the order I feel is most secure + * with the requested type of authentication + */ + sshc->authed = FALSE; + + if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) && + (strstr(sshc->authlist, "publickey") != NULL)) { + bool out_of_memory = FALSE; + + sshc->rsa_pub = sshc->rsa = NULL; + + if(data->set.str[STRING_SSH_PRIVATE_KEY]) + sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]); + else { + /* To ponder about: should really the lib be messing about with the + HOME environment variable etc? */ + char *home = curl_getenv("HOME"); + + /* If no private key file is specified, try some common paths. */ + if(home) { + /* Try ~/.ssh first. */ + sshc->rsa = aprintf("%s/.ssh/id_rsa", home); + if(!sshc->rsa) + out_of_memory = TRUE; + else if(access(sshc->rsa, R_OK) != 0) { + Curl_safefree(sshc->rsa); + sshc->rsa = aprintf("%s/.ssh/id_dsa", home); + if(!sshc->rsa) + out_of_memory = TRUE; + else if(access(sshc->rsa, R_OK) != 0) { + Curl_safefree(sshc->rsa); + } + } + free(home); + } + if(!out_of_memory && !sshc->rsa) { + /* Nothing found; try the current dir. */ + sshc->rsa = strdup("id_rsa"); + if(sshc->rsa && access(sshc->rsa, R_OK) != 0) { + Curl_safefree(sshc->rsa); + sshc->rsa = strdup("id_dsa"); + if(sshc->rsa && access(sshc->rsa, R_OK) != 0) { + Curl_safefree(sshc->rsa); + /* Out of guesses. Set to the empty string to avoid + * surprising info messages. */ + sshc->rsa = strdup(""); + } + } + } + } + + /* + * Unless the user explicitly specifies a public key file, let + * libssh2 extract the public key from the private key file. + * This is done by simply passing sshc->rsa_pub = NULL. + */ + if(data->set.str[STRING_SSH_PUBLIC_KEY] + /* treat empty string the same way as NULL */ + && data->set.str[STRING_SSH_PUBLIC_KEY][0]) { + sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]); + if(!sshc->rsa_pub) + out_of_memory = TRUE; + } + + if(out_of_memory || sshc->rsa == NULL) { + Curl_safefree(sshc->rsa); + Curl_safefree(sshc->rsa_pub); + state(conn, SSH_SESSION_FREE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + + sshc->passphrase = data->set.ssl.key_passwd; + if(!sshc->passphrase) + sshc->passphrase = ""; + + if(sshc->rsa_pub) + infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub); + infof(data, "Using SSH private key file '%s'\n", sshc->rsa); + + state(conn, SSH_AUTH_PKEY); + } + else { + state(conn, SSH_AUTH_PASS_INIT); + } + break; + + case SSH_AUTH_PKEY: + /* The function below checks if the files exists, no need to stat() here. + */ + rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session, + conn->user, + curlx_uztoui( + strlen(conn->user)), + sshc->rsa_pub, + sshc->rsa, sshc->passphrase); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + + Curl_safefree(sshc->rsa_pub); + Curl_safefree(sshc->rsa); + + if(rc == 0) { + sshc->authed = TRUE; + infof(data, "Initialized SSH public key authentication\n"); + state(conn, SSH_AUTH_DONE); + } + else { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "SSH public key authentication failed: %s\n", err_msg); + state(conn, SSH_AUTH_PASS_INIT); + rc = 0; /* clear rc and continue */ + } + break; + + case SSH_AUTH_PASS_INIT: + if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) && + (strstr(sshc->authlist, "password") != NULL)) { + state(conn, SSH_AUTH_PASS); + } + else { + state(conn, SSH_AUTH_HOST_INIT); + rc = 0; /* clear rc and continue */ + } + break; + + case SSH_AUTH_PASS: + rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user, + curlx_uztoui(strlen(conn->user)), + conn->passwd, + curlx_uztoui(strlen(conn->passwd)), + NULL); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc == 0) { + sshc->authed = TRUE; + infof(data, "Initialized password authentication\n"); + state(conn, SSH_AUTH_DONE); + } + else { + state(conn, SSH_AUTH_HOST_INIT); + rc = 0; /* clear rc and continue */ + } + break; + + case SSH_AUTH_HOST_INIT: + if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) && + (strstr(sshc->authlist, "hostbased") != NULL)) { + state(conn, SSH_AUTH_HOST); + } + else { + state(conn, SSH_AUTH_AGENT_INIT); + } + break; + + case SSH_AUTH_HOST: + state(conn, SSH_AUTH_AGENT_INIT); + break; + + case SSH_AUTH_AGENT_INIT: +#ifdef HAVE_LIBSSH2_AGENT_API + if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT) + && (strstr(sshc->authlist, "publickey") != NULL)) { + + /* Connect to the ssh-agent */ + /* The agent could be shared by a curl thread i believe + but nothing obvious as keys can be added/removed at any time */ + if(!sshc->ssh_agent) { + sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session); + if(!sshc->ssh_agent) { + infof(data, "Could not create agent object\n"); + + state(conn, SSH_AUTH_KEY_INIT); + break; + } + } + + rc = libssh2_agent_connect(sshc->ssh_agent); + if(rc == LIBSSH2_ERROR_EAGAIN) + break; + if(rc < 0) { + infof(data, "Failure connecting to agent\n"); + state(conn, SSH_AUTH_KEY_INIT); + rc = 0; /* clear rc and continue */ + } + else { + state(conn, SSH_AUTH_AGENT_LIST); + } + } + else +#endif /* HAVE_LIBSSH2_AGENT_API */ + state(conn, SSH_AUTH_KEY_INIT); + break; + + case SSH_AUTH_AGENT_LIST: +#ifdef HAVE_LIBSSH2_AGENT_API + rc = libssh2_agent_list_identities(sshc->ssh_agent); + + if(rc == LIBSSH2_ERROR_EAGAIN) + break; + if(rc < 0) { + infof(data, "Failure requesting identities to agent\n"); + state(conn, SSH_AUTH_KEY_INIT); + rc = 0; /* clear rc and continue */ + } + else { + state(conn, SSH_AUTH_AGENT); + sshc->sshagent_prev_identity = NULL; + } +#endif + break; + + case SSH_AUTH_AGENT: +#ifdef HAVE_LIBSSH2_AGENT_API + /* as prev_identity evolves only after an identity user auth finished we + can safely request it again as long as EAGAIN is returned here or by + libssh2_agent_userauth */ + rc = libssh2_agent_get_identity(sshc->ssh_agent, + &sshc->sshagent_identity, + sshc->sshagent_prev_identity); + if(rc == LIBSSH2_ERROR_EAGAIN) + break; + + if(rc == 0) { + rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user, + sshc->sshagent_identity); + + if(rc < 0) { + if(rc != LIBSSH2_ERROR_EAGAIN) { + /* tried and failed? go to next identity */ + sshc->sshagent_prev_identity = sshc->sshagent_identity; + } + break; + } + } + + if(rc < 0) + infof(data, "Failure requesting identities to agent\n"); + else if(rc == 1) + infof(data, "No identity would match\n"); + + if(rc == LIBSSH2_ERROR_NONE) { + sshc->authed = TRUE; + infof(data, "Agent based authentication successful\n"); + state(conn, SSH_AUTH_DONE); + } + else { + state(conn, SSH_AUTH_KEY_INIT); + rc = 0; /* clear rc and continue */ + } +#endif + break; + + case SSH_AUTH_KEY_INIT: + if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) + && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) { + state(conn, SSH_AUTH_KEY); + } + else { + state(conn, SSH_AUTH_DONE); + } + break; + + case SSH_AUTH_KEY: + /* Authentication failed. Continue with keyboard-interactive now. */ + rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session, + conn->user, + curlx_uztoui( + strlen(conn->user)), + &kbd_callback); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc == 0) { + sshc->authed = TRUE; + infof(data, "Initialized keyboard interactive authentication\n"); + } + state(conn, SSH_AUTH_DONE); + break; + + case SSH_AUTH_DONE: + if(!sshc->authed) { + failf(data, "Authentication failure"); + state(conn, SSH_SESSION_FREE); + sshc->actualcode = CURLE_LOGIN_DENIED; + break; + } + + /* + * At this point we have an authenticated ssh session. + */ + infof(data, "Authentication complete\n"); + + Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */ + + conn->sockfd = sock; + conn->writesockfd = CURL_SOCKET_BAD; + + if(conn->handler->protocol == CURLPROTO_SFTP) { + state(conn, SSH_SFTP_INIT); + break; + } + infof(data, "SSH CONNECT phase done\n"); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_INIT: + /* + * Start the libssh2 sftp session + */ + sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session); + if(!sshc->sftp_session) { + char *err_msg = NULL; + if(libssh2_session_last_errno(sshc->ssh_session) == + LIBSSH2_ERROR_EAGAIN) { + rc = LIBSSH2_ERROR_EAGAIN; + break; + } + + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + failf(data, "Failure initializing sftp session: %s", err_msg); + state(conn, SSH_SESSION_FREE); + sshc->actualcode = CURLE_FAILED_INIT; + break; + } + state(conn, SSH_SFTP_REALPATH); + break; + + case SSH_SFTP_REALPATH: + { + char tempHome[PATH_MAX]; + + /* + * Get the "home" directory + */ + rc = sftp_libssh2_realpath(sshc->sftp_session, ".", + tempHome, PATH_MAX-1); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc > 0) { + /* It seems that this string is not always NULL terminated */ + tempHome[rc] = '\0'; + sshc->homedir = strdup(tempHome); + if(!sshc->homedir) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + conn->data->state.most_recent_ftp_entrypath = sshc->homedir; + } + else { + /* Return the error type */ + err = sftp_libssh2_last_error(sshc->sftp_session); + if(err) + result = sftp_libssh2_error_to_CURLE(err); + else + /* in this case, the error wasn't in the SFTP level but for example + a time-out or similar */ + result = CURLE_SSH; + sshc->actualcode = result; + DEBUGF(infof(data, "error = %d makes libcurl = %d\n", + err, (int)result)); + state(conn, SSH_STOP); + break; + } + } + /* This is the last step in the SFTP connect phase. Do note that while + we get the homedir here, we get the "workingpath" in the DO action + since the homedir will remain the same between request but the + working path will not. */ + DEBUGF(infof(data, "SSH CONNECT phase done\n")); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_QUOTE_INIT: + + result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path); + if(result) { + sshc->actualcode = result; + state(conn, SSH_STOP); + break; + } + + if(data->set.quote) { + infof(data, "Sending quote commands\n"); + sshc->quote_item = data->set.quote; + state(conn, SSH_SFTP_QUOTE); + } + else { + state(conn, SSH_SFTP_GETINFO); + } + break; + + case SSH_SFTP_POSTQUOTE_INIT: + if(data->set.postquote) { + infof(data, "Sending quote commands\n"); + sshc->quote_item = data->set.postquote; + state(conn, SSH_SFTP_QUOTE); + } + else { + state(conn, SSH_STOP); + } + break; + + case SSH_SFTP_QUOTE: + /* Send any quote commands */ + { + const char *cp; + + /* + * Support some of the "FTP" commands + * + * 'sshc->quote_item' is already verified to be non-NULL before it + * switched to this state. + */ + char *cmd = sshc->quote_item->data; + sshc->acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal SFTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server reponds. */ + + if(cmd[0] == '*') { + cmd++; + sshc->acceptfail = TRUE; + } + + if(strcasecompare("pwd", cmd)) { + /* output debug output if that is requested */ + char *tmp = aprintf("257 \"%s\" is current directory.\n", + sftp_scp->path); + if(!tmp) { + result = CURLE_OUT_OF_MEMORY; + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + break; + } + if(data->set.verbose) { + Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4); + Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp)); + } + /* this sends an FTP-like "header" to the header callback so that the + current directory can be read very similar to how it is read when + using ordinary FTP. */ + result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + free(tmp); + if(result) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + } + else + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + } + { + /* + * the arguments following the command must be separated from the + * command with a space so we can check for it unconditionally + */ + cp = strchr(cmd, ' '); + if(cp == NULL) { + failf(data, "Syntax error in SFTP command. Supply parameter(s)!"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + + /* + * also, every command takes at least one argument so we get that + * first argument right now + */ + result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error: Bad first parameter"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + break; + } + + /* + * SFTP is a binary protocol, so we don't send text commands + * to the server. Instead, we scan for commands used by + * OpenSSH's sftp program and call the appropriate libssh2 + * functions. + */ + if(strncasecompare(cmd, "chgrp ", 6) || + strncasecompare(cmd, "chmod ", 6) || + strncasecompare(cmd, "chown ", 6) ) { + /* attribute change */ + + /* sshc->quote_path1 contains the mode to set */ + /* get the destination */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in chgrp/chmod/chown: " + "Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + break; + } + memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + state(conn, SSH_SFTP_QUOTE_STAT); + break; + } + if(strncasecompare(cmd, "ln ", 3) || + strncasecompare(cmd, "symlink ", 8)) { + /* symbolic linking */ + /* sshc->quote_path1 is the source */ + /* get the destination */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, + "Syntax error in ln/symlink: Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + break; + } + state(conn, SSH_SFTP_QUOTE_SYMLINK); + break; + } + else if(strncasecompare(cmd, "mkdir ", 6)) { + /* create dir */ + state(conn, SSH_SFTP_QUOTE_MKDIR); + break; + } + else if(strncasecompare(cmd, "rename ", 7)) { + /* rename file */ + /* first param is the source path */ + /* second param is the dest. path */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in rename: Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + break; + } + state(conn, SSH_SFTP_QUOTE_RENAME); + break; + } + else if(strncasecompare(cmd, "rmdir ", 6)) { + /* delete dir */ + state(conn, SSH_SFTP_QUOTE_RMDIR); + break; + } + else if(strncasecompare(cmd, "rm ", 3)) { + state(conn, SSH_SFTP_QUOTE_UNLINK); + break; + } +#ifdef HAS_STATVFS_SUPPORT + else if(strncasecompare(cmd, "statvfs ", 8)) { + state(conn, SSH_SFTP_QUOTE_STATVFS); + break; + } +#endif + + failf(data, "Unknown SFTP command"); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + } + break; + + case SSH_SFTP_NEXT_QUOTE: + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + + sshc->quote_item = sshc->quote_item->next; + + if(sshc->quote_item) { + state(conn, SSH_SFTP_QUOTE); + } + else { + if(sshc->nextstate != SSH_NO_STATE) { + state(conn, sshc->nextstate); + sshc->nextstate = SSH_NO_STATE; + } + else { + state(conn, SSH_SFTP_GETINFO); + } + } + break; + + case SSH_SFTP_QUOTE_STAT: + { + char *cmd = sshc->quote_item->data; + sshc->acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal SFTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server reponds. */ + + if(cmd[0] == '*') { + cmd++; + sshc->acceptfail = TRUE; + } + + if(!strncasecompare(cmd, "chmod", 5)) { + /* Since chown and chgrp only set owner OR group but libssh2 wants to + * set them both at once, we need to obtain the current ownership + * first. This takes an extra protocol round trip. + */ + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2, + curlx_uztoui(strlen(sshc->quote_path2)), + LIBSSH2_SFTP_STAT, + &sshc->quote_attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { /* get those attributes */ + err = sftp_libssh2_last_error(sshc->sftp_session); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Attempt to get SFTP stats failed: %s", + sftp_libssh2_strerror(err)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + } + + /* Now set the new attributes... */ + if(strncasecompare(cmd, "chgrp", 5)) { + sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10); + sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; + if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chgrp gid not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + } + else if(strncasecompare(cmd, "chmod", 5)) { + sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8); + sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS; + /* permissions are octal */ + if(sshc->quote_attrs.permissions == 0 && + !ISDIGIT(sshc->quote_path1[0])) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chmod permissions not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + } + else if(strncasecompare(cmd, "chown", 5)) { + sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10); + sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; + if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chown uid not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + } + + /* Now send the completed structure... */ + state(conn, SSH_SFTP_QUOTE_SETSTAT); + break; + } + + case SSH_SFTP_QUOTE_SETSTAT: + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2, + curlx_uztoui(strlen(sshc->quote_path2)), + LIBSSH2_SFTP_SETSTAT, + &sshc->quote_attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { + err = sftp_libssh2_last_error(sshc->sftp_session); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Attempt to set SFTP stats failed: %s", + sftp_libssh2_strerror(err)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_SYMLINK: + rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1, + curlx_uztoui(strlen(sshc->quote_path1)), + sshc->quote_path2, + curlx_uztoui(strlen(sshc->quote_path2)), + LIBSSH2_SFTP_SYMLINK); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { + err = sftp_libssh2_last_error(sshc->sftp_session); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "symlink command failed: %s", + sftp_libssh2_strerror(err)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_MKDIR: + rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1, + curlx_uztoui(strlen(sshc->quote_path1)), + data->set.new_directory_perms); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { + err = sftp_libssh2_last_error(sshc->sftp_session); + Curl_safefree(sshc->quote_path1); + failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_RENAME: + rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1, + curlx_uztoui(strlen(sshc->quote_path1)), + sshc->quote_path2, + curlx_uztoui(strlen(sshc->quote_path2)), + LIBSSH2_SFTP_RENAME_OVERWRITE | + LIBSSH2_SFTP_RENAME_ATOMIC | + LIBSSH2_SFTP_RENAME_NATIVE); + + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { + err = sftp_libssh2_last_error(sshc->sftp_session); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "rename command failed: %s", sftp_libssh2_strerror(err)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_RMDIR: + rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1, + curlx_uztoui(strlen(sshc->quote_path1))); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { + err = sftp_libssh2_last_error(sshc->sftp_session); + Curl_safefree(sshc->quote_path1); + failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_UNLINK: + rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1, + curlx_uztoui(strlen(sshc->quote_path1))); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { + err = sftp_libssh2_last_error(sshc->sftp_session); + Curl_safefree(sshc->quote_path1); + failf(data, "rm command failed: %s", sftp_libssh2_strerror(err)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + +#ifdef HAS_STATVFS_SUPPORT + case SSH_SFTP_QUOTE_STATVFS: + { + LIBSSH2_SFTP_STATVFS statvfs; + rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1, + curlx_uztoui(strlen(sshc->quote_path1)), + &statvfs); + + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc != 0 && !sshc->acceptfail) { + err = sftp_libssh2_last_error(sshc->sftp_session); + Curl_safefree(sshc->quote_path1); + failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(err)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + else if(rc == 0) { + char *tmp = aprintf("statvfs:\n" + "f_bsize: %llu\n" "f_frsize: %llu\n" + "f_blocks: %llu\n" "f_bfree: %llu\n" + "f_bavail: %llu\n" "f_files: %llu\n" + "f_ffree: %llu\n" "f_favail: %llu\n" + "f_fsid: %llu\n" "f_flag: %llu\n" + "f_namemax: %llu\n", + statvfs.f_bsize, statvfs.f_frsize, + statvfs.f_blocks, statvfs.f_bfree, + statvfs.f_bavail, statvfs.f_files, + statvfs.f_ffree, statvfs.f_favail, + statvfs.f_fsid, statvfs.f_flag, + statvfs.f_namemax); + if(!tmp) { + result = CURLE_OUT_OF_MEMORY; + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + break; + } + + result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + free(tmp); + if(result) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + } + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + } +#endif + case SSH_SFTP_GETINFO: + { + if(data->set.get_filetime) { + state(conn, SSH_SFTP_FILETIME); + } + else { + state(conn, SSH_SFTP_TRANS_INIT); + } + break; + } + + case SSH_SFTP_FILETIME: + { + LIBSSH2_SFTP_ATTRIBUTES attrs; + + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, + curlx_uztoui(strlen(sftp_scp->path)), + LIBSSH2_SFTP_STAT, &attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc == 0) { + data->info.filetime = attrs.mtime; + } + + state(conn, SSH_SFTP_TRANS_INIT); + break; + } + + case SSH_SFTP_TRANS_INIT: + if(data->set.upload) + state(conn, SSH_SFTP_UPLOAD_INIT); + else { + if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/') + state(conn, SSH_SFTP_READDIR_INIT); + else + state(conn, SSH_SFTP_DOWNLOAD_INIT); + } + break; + + case SSH_SFTP_UPLOAD_INIT: + { + unsigned long flags; + /* + * NOTE!!! libssh2 requires that the destination path is a full path + * that includes the destination file and name OR ends in a "/" + * If this is not done the destination file will be named the + * same name as the last directory in the path. + */ + + if(data->state.resume_from != 0) { + LIBSSH2_SFTP_ATTRIBUTES attrs; + if(data->state.resume_from < 0) { + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, + curlx_uztoui(strlen(sftp_scp->path)), + LIBSSH2_SFTP_STAT, &attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc) { + data->state.resume_from = 0; + } + else { + curl_off_t size = attrs.filesize; + if(size < 0) { + failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + data->state.resume_from = attrs.filesize; + } + } + } + + if(data->set.ftp_append) + /* Try to open for append, but create if nonexisting */ + flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND; + else if(data->state.resume_from > 0) + /* If we have restart position then open for append */ + flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND; + else + /* Clear file before writing (normal behaviour) */ + flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC; + + sshc->sftp_handle = + libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path, + curlx_uztoui(strlen(sftp_scp->path)), + flags, data->set.new_file_perms, + LIBSSH2_SFTP_OPENFILE); + + if(!sshc->sftp_handle) { + rc = libssh2_session_last_errno(sshc->ssh_session); + + if(LIBSSH2_ERROR_EAGAIN == rc) + break; + + if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc) + /* only when there was an SFTP protocol error can we extract + the sftp error! */ + err = sftp_libssh2_last_error(sshc->sftp_session); + else + err = -1; /* not an sftp error at all */ + + if(sshc->secondCreateDirs) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = err>= LIBSSH2_FX_OK? + sftp_libssh2_error_to_CURLE(err):CURLE_SSH; + failf(data, "Creating the dir/file failed: %s", + sftp_libssh2_strerror(err)); + break; + } + if(((err == LIBSSH2_FX_NO_SUCH_FILE) || + (err == LIBSSH2_FX_FAILURE) || + (err == LIBSSH2_FX_NO_SUCH_PATH)) && + (data->set.ftp_create_missing_dirs && + (strlen(sftp_scp->path) > 1))) { + /* try to create the path remotely */ + rc = 0; /* clear rc and continue */ + sshc->secondCreateDirs = 1; + state(conn, SSH_SFTP_CREATE_DIRS_INIT); + break; + } + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = err>= LIBSSH2_FX_OK? + sftp_libssh2_error_to_CURLE(err):CURLE_SSH; + if(!sshc->actualcode) { + /* Sometimes, for some reason libssh2_sftp_last_error() returns + zero even though libssh2_sftp_open() failed previously! We need + to work around that! */ + sshc->actualcode = CURLE_SSH; + err = -1; + } + failf(data, "Upload failed: %s (%d/%d)", + err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error", + err, rc); + break; + } + + /* If we have a restart point then we need to seek to the correct + position. */ + if(data->state.resume_from > 0) { + /* Let's read off the proper amount of bytes from the input. */ + if(conn->seek_func) { + Curl_set_in_callback(data, true); + seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, + SEEK_SET); + Curl_set_in_callback(data, false); + } + + if(seekerr != CURL_SEEKFUNC_OK) { + curl_off_t passed = 0; + + if(seekerr != CURL_SEEKFUNC_CANTSEEK) { + failf(data, "Could not seek stream"); + return CURLE_FTP_COULDNT_USE_REST; + } + /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ + do { + size_t readthisamountnow = + (data->state.resume_from - passed > data->set.buffer_size) ? + (size_t)data->set.buffer_size : + curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread; + Curl_set_in_callback(data, true); + actuallyread = data->state.fread_func(data->state.buffer, 1, + readthisamountnow, + data->state.in); + Curl_set_in_callback(data, false); + + passed += actuallyread; + if((actuallyread == 0) || (actuallyread > readthisamountnow)) { + /* this checks for greater-than only to make sure that the + CURL_READFUNC_ABORT return code still aborts */ + failf(data, "Failed to read data"); + return CURLE_FTP_COULDNT_USE_REST; + } + } while(passed < data->state.resume_from); + } + + /* now, decrease the size of the read */ + if(data->state.infilesize > 0) { + data->state.infilesize -= data->state.resume_from; + data->req.size = data->state.infilesize; + Curl_pgrsSetUploadSize(data, data->state.infilesize); + } + + SFTP_SEEK(sshc->sftp_handle, data->state.resume_from); + } + if(data->state.infilesize > 0) { + data->req.size = data->state.infilesize; + Curl_pgrsSetUploadSize(data, data->state.infilesize); + } + /* upload data */ + Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->sockfd = conn->writesockfd; + + if(result) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = result; + } + else { + /* store this original bitmask setup to use later on if we can't + figure out a "real" bitmask */ + sshc->orig_waitfor = data->req.keepon; + + /* we want to use the _sending_ function even when the socket turns + out readable as the underlying libssh2 sftp send function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_OUT; + + /* since we don't really wait for anything at this point, we want the + state machine to move on as soon as possible so we set a very short + timeout here */ + Curl_expire(data, 0, EXPIRE_RUN_NOW); + + state(conn, SSH_STOP); + } + break; + } + + case SSH_SFTP_CREATE_DIRS_INIT: + if(strlen(sftp_scp->path) > 1) { + sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */ + state(conn, SSH_SFTP_CREATE_DIRS); + } + else { + state(conn, SSH_SFTP_UPLOAD_INIT); + } + break; + + case SSH_SFTP_CREATE_DIRS: + sshc->slash_pos = strchr(sshc->slash_pos, '/'); + if(sshc->slash_pos) { + *sshc->slash_pos = 0; + + infof(data, "Creating directory '%s'\n", sftp_scp->path); + state(conn, SSH_SFTP_CREATE_DIRS_MKDIR); + break; + } + state(conn, SSH_SFTP_UPLOAD_INIT); + break; + + case SSH_SFTP_CREATE_DIRS_MKDIR: + /* 'mode' - parameter is preliminary - default to 0644 */ + rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path, + curlx_uztoui(strlen(sftp_scp->path)), + data->set.new_directory_perms); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + *sshc->slash_pos = '/'; + ++sshc->slash_pos; + if(rc < 0) { + /* + * Abort if failure wasn't that the dir already exists or the + * permission was denied (creation might succeed further down the + * path) - retry on unspecific FAILURE also + */ + err = sftp_libssh2_last_error(sshc->sftp_session); + if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) && + (err != LIBSSH2_FX_FAILURE) && + (err != LIBSSH2_FX_PERMISSION_DENIED)) { + result = sftp_libssh2_error_to_CURLE(err); + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = result?result:CURLE_SSH; + break; + } + rc = 0; /* clear rc and continue */ + } + state(conn, SSH_SFTP_CREATE_DIRS); + break; + + case SSH_SFTP_READDIR_INIT: + Curl_pgrsSetDownloadSize(data, -1); + if(data->set.opt_no_body) { + state(conn, SSH_STOP); + break; + } + + /* + * This is a directory that we are trying to get, so produce a directory + * listing + */ + sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session, + sftp_scp->path, + curlx_uztoui( + strlen(sftp_scp->path)), + 0, 0, LIBSSH2_SFTP_OPENDIR); + if(!sshc->sftp_handle) { + if(libssh2_session_last_errno(sshc->ssh_session) == + LIBSSH2_ERROR_EAGAIN) { + rc = LIBSSH2_ERROR_EAGAIN; + break; + } + err = sftp_libssh2_last_error(sshc->sftp_session); + failf(data, "Could not open directory for reading: %s", + sftp_libssh2_strerror(err)); + state(conn, SSH_SFTP_CLOSE); + result = sftp_libssh2_error_to_CURLE(err); + sshc->actualcode = result?result:CURLE_SSH; + break; + } + sshc->readdir_filename = malloc(PATH_MAX + 1); + if(!sshc->readdir_filename) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + sshc->readdir_longentry = malloc(PATH_MAX + 1); + if(!sshc->readdir_longentry) { + Curl_safefree(sshc->readdir_filename); + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + state(conn, SSH_SFTP_READDIR); + break; + + case SSH_SFTP_READDIR: + rc = libssh2_sftp_readdir_ex(sshc->sftp_handle, + sshc->readdir_filename, + PATH_MAX, + sshc->readdir_longentry, + PATH_MAX, + &sshc->readdir_attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc > 0) { + sshc->readdir_len = (size_t) rc; + sshc->readdir_filename[sshc->readdir_len] = '\0'; + + if(data->set.ftp_list_only) { + char *tmpLine; + + tmpLine = aprintf("%s\n", sshc->readdir_filename); + if(tmpLine == NULL) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + result = Curl_client_write(conn, CLIENTWRITE_BODY, + tmpLine, sshc->readdir_len + 1); + free(tmpLine); + + if(result) { + state(conn, SSH_STOP); + break; + } + /* since this counts what we send to the client, we include the + newline in this counter */ + data->req.bytecount += sshc->readdir_len + 1; + + /* output debug output if that is requested */ + if(data->set.verbose) { + Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename, + sshc->readdir_len); + } + } + else { + sshc->readdir_currLen = strlen(sshc->readdir_longentry); + sshc->readdir_totalLen = 80 + sshc->readdir_currLen; + sshc->readdir_line = calloc(sshc->readdir_totalLen, 1); + if(!sshc->readdir_line) { + Curl_safefree(sshc->readdir_filename); + Curl_safefree(sshc->readdir_longentry); + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + + memcpy(sshc->readdir_line, sshc->readdir_longentry, + sshc->readdir_currLen); + if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) && + ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) == + LIBSSH2_SFTP_S_IFLNK)) { + sshc->readdir_linkPath = malloc(PATH_MAX + 1); + if(sshc->readdir_linkPath == NULL) { + Curl_safefree(sshc->readdir_filename); + Curl_safefree(sshc->readdir_longentry); + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + + msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path, + sshc->readdir_filename); + state(conn, SSH_SFTP_READDIR_LINK); + break; + } + state(conn, SSH_SFTP_READDIR_BOTTOM); + break; + } + } + else if(rc == 0) { + Curl_safefree(sshc->readdir_filename); + Curl_safefree(sshc->readdir_longentry); + state(conn, SSH_SFTP_READDIR_DONE); + break; + } + else if(rc < 0) { + err = sftp_libssh2_last_error(sshc->sftp_session); + result = sftp_libssh2_error_to_CURLE(err); + sshc->actualcode = result?result:CURLE_SSH; + failf(data, "Could not open remote file for reading: %s :: %d", + sftp_libssh2_strerror(err), + libssh2_session_last_errno(sshc->ssh_session)); + Curl_safefree(sshc->readdir_filename); + Curl_safefree(sshc->readdir_longentry); + state(conn, SSH_SFTP_CLOSE); + break; + } + break; + + case SSH_SFTP_READDIR_LINK: + rc = + libssh2_sftp_symlink_ex(sshc->sftp_session, + sshc->readdir_linkPath, + curlx_uztoui(strlen(sshc->readdir_linkPath)), + sshc->readdir_filename, + PATH_MAX, LIBSSH2_SFTP_READLINK); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + sshc->readdir_len = (size_t) rc; + Curl_safefree(sshc->readdir_linkPath); + + /* get room for the filename and extra output */ + sshc->readdir_totalLen += 4 + sshc->readdir_len; + new_readdir_line = Curl_saferealloc(sshc->readdir_line, + sshc->readdir_totalLen); + if(!new_readdir_line) { + sshc->readdir_line = NULL; + Curl_safefree(sshc->readdir_filename); + Curl_safefree(sshc->readdir_longentry); + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + sshc->readdir_line = new_readdir_line; + + sshc->readdir_currLen += msnprintf(sshc->readdir_line + + sshc->readdir_currLen, + sshc->readdir_totalLen - + sshc->readdir_currLen, + " -> %s", + sshc->readdir_filename); + + state(conn, SSH_SFTP_READDIR_BOTTOM); + break; + + case SSH_SFTP_READDIR_BOTTOM: + sshc->readdir_currLen += msnprintf(sshc->readdir_line + + sshc->readdir_currLen, + sshc->readdir_totalLen - + sshc->readdir_currLen, "\n"); + result = Curl_client_write(conn, CLIENTWRITE_BODY, + sshc->readdir_line, + sshc->readdir_currLen); + + if(!result) { + + /* output debug output if that is requested */ + if(data->set.verbose) { + Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line, + sshc->readdir_currLen); + } + data->req.bytecount += sshc->readdir_currLen; + } + Curl_safefree(sshc->readdir_line); + if(result) { + state(conn, SSH_STOP); + } + else + state(conn, SSH_SFTP_READDIR); + break; + + case SSH_SFTP_READDIR_DONE: + if(libssh2_sftp_closedir(sshc->sftp_handle) == + LIBSSH2_ERROR_EAGAIN) { + rc = LIBSSH2_ERROR_EAGAIN; + break; + } + sshc->sftp_handle = NULL; + Curl_safefree(sshc->readdir_filename); + Curl_safefree(sshc->readdir_longentry); + + /* no data to transfer */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_DOWNLOAD_INIT: + /* + * Work on getting the specified file + */ + sshc->sftp_handle = + libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path, + curlx_uztoui(strlen(sftp_scp->path)), + LIBSSH2_FXF_READ, data->set.new_file_perms, + LIBSSH2_SFTP_OPENFILE); + if(!sshc->sftp_handle) { + if(libssh2_session_last_errno(sshc->ssh_session) == + LIBSSH2_ERROR_EAGAIN) { + rc = LIBSSH2_ERROR_EAGAIN; + break; + } + err = sftp_libssh2_last_error(sshc->sftp_session); + failf(data, "Could not open remote file for reading: %s", + sftp_libssh2_strerror(err)); + state(conn, SSH_SFTP_CLOSE); + result = sftp_libssh2_error_to_CURLE(err); + sshc->actualcode = result?result:CURLE_SSH; + break; + } + state(conn, SSH_SFTP_DOWNLOAD_STAT); + break; + + case SSH_SFTP_DOWNLOAD_STAT: + { + LIBSSH2_SFTP_ATTRIBUTES attrs; + + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, + curlx_uztoui(strlen(sftp_scp->path)), + LIBSSH2_SFTP_STAT, &attrs); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc || + !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) || + (attrs.filesize == 0)) { + /* + * libssh2_sftp_open() didn't return an error, so maybe the server + * just doesn't support stat() + * OR the server doesn't return a file size with a stat() + * OR file size is 0 + */ + data->req.size = -1; + data->req.maxdownload = -1; + Curl_pgrsSetDownloadSize(data, -1); + } + else { + curl_off_t size = attrs.filesize; + + if(size < 0) { + failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + if(conn->data->state.use_range) { + curl_off_t from, to; + char *ptr; + char *ptr2; + CURLofft to_t; + CURLofft from_t; + + from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from); + if(from_t == CURL_OFFT_FLOW) + return CURLE_RANGE_ERROR; + while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) + ptr++; + to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); + if(to_t == CURL_OFFT_FLOW) + return CURLE_RANGE_ERROR; + if((to_t == CURL_OFFT_INVAL) /* no "to" value given */ + || (to >= size)) { + to = size - 1; + } + if(from_t) { + /* from is relative to end of file */ + from = size - to; + to = size - 1; + } + if(from > size) { + failf(data, "Offset (%" + CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" + CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize); + return CURLE_BAD_DOWNLOAD_RESUME; + } + if(from > to) { + from = to; + size = 0; + } + else { + size = to - from + 1; + } + + SFTP_SEEK(conn->proto.sshc.sftp_handle, from); + } + data->req.size = size; + data->req.maxdownload = size; + Curl_pgrsSetDownloadSize(data, size); + } + + /* We can resume if we can seek to the resume position */ + if(data->state.resume_from) { + if(data->state.resume_from < 0) { + /* We're supposed to download the last abs(from) bytes */ + if((curl_off_t)attrs.filesize < -data->state.resume_from) { + failf(data, "Offset (%" + CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" + CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, attrs.filesize); + return CURLE_BAD_DOWNLOAD_RESUME; + } + /* download from where? */ + data->state.resume_from += attrs.filesize; + } + else { + if((curl_off_t)attrs.filesize < data->state.resume_from) { + failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T + ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, attrs.filesize); + return CURLE_BAD_DOWNLOAD_RESUME; + } + } + /* Does a completed file need to be seeked and started or closed ? */ + /* Now store the number of bytes we are expected to download */ + data->req.size = attrs.filesize - data->state.resume_from; + data->req.maxdownload = attrs.filesize - data->state.resume_from; + Curl_pgrsSetDownloadSize(data, + attrs.filesize - data->state.resume_from); + SFTP_SEEK(sshc->sftp_handle, data->state.resume_from); + } + } + + /* Setup the actual download */ + if(data->req.size == 0) { + /* no data to transfer */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + infof(data, "File already completely downloaded\n"); + state(conn, SSH_STOP); + break; + } + Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->writesockfd = conn->sockfd; + + /* we want to use the _receiving_ function even when the socket turns + out writableable as the underlying libssh2 recv function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_IN; + + if(result) { + /* this should never occur; the close state should be entered + at the time the error occurs */ + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = result; + } + else { + state(conn, SSH_STOP); + } + break; + + case SSH_SFTP_CLOSE: + if(sshc->sftp_handle) { + rc = libssh2_sftp_close(sshc->sftp_handle); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg); + } + sshc->sftp_handle = NULL; + } + + Curl_safefree(sftp_scp->path); + + DEBUGF(infof(data, "SFTP DONE done\n")); + + /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT + After nextstate is executed, the control should come back to + SSH_SFTP_CLOSE to pass the correct result back */ + if(sshc->nextstate != SSH_NO_STATE && + sshc->nextstate != SSH_SFTP_CLOSE) { + state(conn, sshc->nextstate); + sshc->nextstate = SSH_SFTP_CLOSE; + } + else { + state(conn, SSH_STOP); + result = sshc->actualcode; + } + break; + + case SSH_SFTP_SHUTDOWN: + /* during times we get here due to a broken transfer and then the + sftp_handle might not have been taken down so make sure that is done + before we proceed */ + + if(sshc->sftp_handle) { + rc = libssh2_sftp_close(sshc->sftp_handle); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, + NULL, 0); + infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg); + } + sshc->sftp_handle = NULL; + } + if(sshc->sftp_session) { + rc = libssh2_sftp_shutdown(sshc->sftp_session); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + infof(data, "Failed to stop libssh2 sftp subsystem\n"); + } + sshc->sftp_session = NULL; + } + + Curl_safefree(sshc->homedir); + conn->data->state.most_recent_ftp_entrypath = NULL; + + state(conn, SSH_SESSION_DISCONNECT); + break; + + case SSH_SCP_TRANS_INIT: + result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path); + if(result) { + sshc->actualcode = result; + state(conn, SSH_STOP); + break; + } + + if(data->set.upload) { + if(data->state.infilesize < 0) { + failf(data, "SCP requires a known file size for upload"); + sshc->actualcode = CURLE_UPLOAD_FAILED; + state(conn, SSH_SCP_CHANNEL_FREE); + break; + } + state(conn, SSH_SCP_UPLOAD_INIT); + } + else { + state(conn, SSH_SCP_DOWNLOAD_INIT); + } + break; + + case SSH_SCP_UPLOAD_INIT: + /* + * libssh2 requires that the destination path is a full path that + * includes the destination file and name OR ends in a "/" . If this is + * not done the destination file will be named the same name as the last + * directory in the path. + */ + sshc->ssh_channel = + SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms, + data->state.infilesize); + if(!sshc->ssh_channel) { + int ssh_err; + char *err_msg = NULL; + + if(libssh2_session_last_errno(sshc->ssh_session) == + LIBSSH2_ERROR_EAGAIN) { + rc = LIBSSH2_ERROR_EAGAIN; + break; + } + + ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0)); + failf(conn->data, "%s", err_msg); + state(conn, SSH_SCP_CHANNEL_FREE); + sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err); + /* Map generic errors to upload failed */ + if(sshc->actualcode == CURLE_SSH || + sshc->actualcode == CURLE_REMOTE_FILE_NOT_FOUND) + sshc->actualcode = CURLE_UPLOAD_FAILED; + break; + } + + /* upload data */ + Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->sockfd = conn->writesockfd; + + if(result) { + state(conn, SSH_SCP_CHANNEL_FREE); + sshc->actualcode = result; + } + else { + /* store this original bitmask setup to use later on if we can't + figure out a "real" bitmask */ + sshc->orig_waitfor = data->req.keepon; + + /* we want to use the _sending_ function even when the socket turns + out readable as the underlying libssh2 scp send function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_OUT; + + state(conn, SSH_STOP); + } + break; + + case SSH_SCP_DOWNLOAD_INIT: + { + curl_off_t bytecount; + + /* + * We must check the remote file; if it is a directory no values will + * be set in sb + */ + + /* + * If support for >2GB files exists, use it. + */ + + /* get a fresh new channel from the ssh layer */ +#if LIBSSH2_VERSION_NUM < 0x010700 + struct stat sb; + memset(&sb, 0, sizeof(struct stat)); + sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session, + sftp_scp->path, &sb); +#else + libssh2_struct_stat sb; + memset(&sb, 0, sizeof(libssh2_struct_stat)); + sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session, + sftp_scp->path, &sb); +#endif + + if(!sshc->ssh_channel) { + int ssh_err; + char *err_msg = NULL; + + if(libssh2_session_last_errno(sshc->ssh_session) == + LIBSSH2_ERROR_EAGAIN) { + rc = LIBSSH2_ERROR_EAGAIN; + break; + } + + + ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0)); + failf(conn->data, "%s", err_msg); + state(conn, SSH_SCP_CHANNEL_FREE); + sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err); + break; + } + + /* download data */ + bytecount = (curl_off_t)sb.st_size; + data->req.maxdownload = (curl_off_t)sb.st_size; + Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->writesockfd = conn->sockfd; + + /* we want to use the _receiving_ function even when the socket turns + out writableable as the underlying libssh2 recv function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_IN; + + if(result) { + state(conn, SSH_SCP_CHANNEL_FREE); + sshc->actualcode = result; + } + else + state(conn, SSH_STOP); + } + break; + + case SSH_SCP_DONE: + if(data->set.upload) + state(conn, SSH_SCP_SEND_EOF); + else + state(conn, SSH_SCP_CHANNEL_FREE); + break; + + case SSH_SCP_SEND_EOF: + if(sshc->ssh_channel) { + rc = libssh2_channel_send_eof(sshc->ssh_channel); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to send libssh2 channel EOF: %d %s\n", + rc, err_msg); + } + } + state(conn, SSH_SCP_WAIT_EOF); + break; + + case SSH_SCP_WAIT_EOF: + if(sshc->ssh_channel) { + rc = libssh2_channel_wait_eof(sshc->ssh_channel); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to get channel EOF: %d %s\n", rc, err_msg); + } + } + state(conn, SSH_SCP_WAIT_CLOSE); + break; + + case SSH_SCP_WAIT_CLOSE: + if(sshc->ssh_channel) { + rc = libssh2_channel_wait_closed(sshc->ssh_channel); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Channel failed to close: %d %s\n", rc, err_msg); + } + } + state(conn, SSH_SCP_CHANNEL_FREE); + break; + + case SSH_SCP_CHANNEL_FREE: + if(sshc->ssh_channel) { + rc = libssh2_channel_free(sshc->ssh_channel); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to free libssh2 scp subsystem: %d %s\n", + rc, err_msg); + } + sshc->ssh_channel = NULL; + } + DEBUGF(infof(data, "SCP DONE phase complete\n")); +#if 0 /* PREV */ + state(conn, SSH_SESSION_DISCONNECT); +#endif + state(conn, SSH_STOP); + result = sshc->actualcode; + break; + + case SSH_SESSION_DISCONNECT: + /* during weird times when we've been prematurely aborted, the channel + is still alive when we reach this state and we MUST kill the channel + properly first */ + if(sshc->ssh_channel) { + rc = libssh2_channel_free(sshc->ssh_channel); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to free libssh2 scp subsystem: %d %s\n", + rc, err_msg); + } + sshc->ssh_channel = NULL; + } + + if(sshc->ssh_session) { + rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown"); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to disconnect libssh2 session: %d %s\n", + rc, err_msg); + } + } + + Curl_safefree(sshc->homedir); + conn->data->state.most_recent_ftp_entrypath = NULL; + + state(conn, SSH_SESSION_FREE); + break; + + case SSH_SESSION_FREE: +#ifdef HAVE_LIBSSH2_KNOWNHOST_API + if(sshc->kh) { + libssh2_knownhost_free(sshc->kh); + sshc->kh = NULL; + } +#endif + +#ifdef HAVE_LIBSSH2_AGENT_API + if(sshc->ssh_agent) { + rc = libssh2_agent_disconnect(sshc->ssh_agent); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to disconnect from libssh2 agent: %d %s\n", + rc, err_msg); + } + libssh2_agent_free(sshc->ssh_agent); + sshc->ssh_agent = NULL; + + /* NB: there is no need to free identities, they are part of internal + agent stuff */ + sshc->sshagent_identity = NULL; + sshc->sshagent_prev_identity = NULL; + } +#endif + + if(sshc->ssh_session) { + rc = libssh2_session_free(sshc->ssh_session); + if(rc == LIBSSH2_ERROR_EAGAIN) { + break; + } + if(rc < 0) { + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to free libssh2 session: %d %s\n", rc, err_msg); + } + sshc->ssh_session = NULL; + } + + /* worst-case scenario cleanup */ + + DEBUGASSERT(sshc->ssh_session == NULL); + DEBUGASSERT(sshc->ssh_channel == NULL); + DEBUGASSERT(sshc->sftp_session == NULL); + DEBUGASSERT(sshc->sftp_handle == NULL); +#ifdef HAVE_LIBSSH2_KNOWNHOST_API + DEBUGASSERT(sshc->kh == NULL); +#endif +#ifdef HAVE_LIBSSH2_AGENT_API + DEBUGASSERT(sshc->ssh_agent == NULL); +#endif + + Curl_safefree(sshc->rsa_pub); + Curl_safefree(sshc->rsa); + + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + + Curl_safefree(sshc->homedir); + + Curl_safefree(sshc->readdir_filename); + Curl_safefree(sshc->readdir_longentry); + Curl_safefree(sshc->readdir_line); + Curl_safefree(sshc->readdir_linkPath); + + /* the code we are about to return */ + result = sshc->actualcode; + + memset(sshc, 0, sizeof(struct ssh_conn)); + + connclose(conn, "SSH session free"); + sshc->state = SSH_SESSION_FREE; /* current */ + sshc->nextstate = SSH_NO_STATE; + state(conn, SSH_STOP); + break; + + case SSH_QUIT: + /* fallthrough, just stop! */ + default: + /* internal error */ + sshc->nextstate = SSH_NO_STATE; + state(conn, SSH_STOP); + break; + } + + } while(!rc && (sshc->state != SSH_STOP)); + + if(rc == LIBSSH2_ERROR_EAGAIN) { + /* we would block, we need to wait for the socket to be ready (in the + right direction too)! */ + *block = TRUE; + } + + return result; +} + +/* called by the multi interface to figure out what socket(s) to wait for and + for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ +static int ssh_perform_getsock(const struct connectdata *conn, + curl_socket_t *sock, /* points to numsocks + number of sockets */ + int numsocks) +{ +#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION + int bitmap = GETSOCK_BLANK; + (void)numsocks; + + sock[0] = conn->sock[FIRSTSOCKET]; + + if(conn->waitfor & KEEP_RECV) + bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); + + if(conn->waitfor & KEEP_SEND) + bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); + + return bitmap; +#else + /* if we don't know the direction we can use the generic *_getsock() + function even for the protocol_connect and doing states */ + return Curl_single_getsock(conn, sock, numsocks); +#endif +} + +/* Generic function called by the multi interface to figure out what socket(s) + to wait for and for what actions during the DOING and PROTOCONNECT states*/ +static int ssh_getsock(struct connectdata *conn, + curl_socket_t *sock, /* points to numsocks number + of sockets */ + int numsocks) +{ +#ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION + (void)conn; + (void)sock; + (void)numsocks; + /* if we don't know any direction we can just play along as we used to and + not provide any sensible info */ + return GETSOCK_BLANK; +#else + /* if we know the direction we can use the generic *_getsock() function even + for the protocol_connect and doing states */ + return ssh_perform_getsock(conn, sock, numsocks); +#endif +} + +#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION +/* + * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this + * function is used to figure out in what direction and stores this info so + * that the multi interface can take advantage of it. Make sure to call this + * function in all cases so that when it _doesn't_ return EAGAIN we can + * restore the default wait bits. + */ +static void ssh_block2waitfor(struct connectdata *conn, bool block) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + int dir = 0; + if(block) { + dir = libssh2_session_block_directions(sshc->ssh_session); + if(dir) { + /* translate the libssh2 define bits into our own bit defines */ + conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) | + ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0); + } + } + if(!dir) + /* It didn't block or libssh2 didn't reveal in which direction, put back + the original set */ + conn->waitfor = sshc->orig_waitfor; +} +#else + /* no libssh2 directional support so we simply don't know */ +#define ssh_block2waitfor(x,y) Curl_nop_stmt +#endif + +/* called repeatedly until done from multi.c */ +static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + CURLcode result = CURLE_OK; + bool block; /* we store the status and use that to provide a ssh_getsock() + implementation */ + do { + result = ssh_statemach_act(conn, &block); + *done = (sshc->state == SSH_STOP) ? TRUE : FALSE; + /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then + try again */ + } while(!result && !*done && !block); + ssh_block2waitfor(conn, block); + + return result; +} + +static CURLcode ssh_block_statemach(struct connectdata *conn, + bool disconnect) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + while((sshc->state != SSH_STOP) && !result) { + bool block; + timediff_t left = 1000; + struct curltime now = Curl_now(); + + result = ssh_statemach_act(conn, &block); + if(result) + break; + + if(!disconnect) { + if(Curl_pgrsUpdate(conn)) + return CURLE_ABORTED_BY_CALLBACK; + + result = Curl_speedcheck(data, now); + if(result) + break; + + left = Curl_timeleft(data, NULL, FALSE); + if(left < 0) { + failf(data, "Operation timed out"); + return CURLE_OPERATION_TIMEDOUT; + } + } + +#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION + if(!result && block) { + int dir = libssh2_session_block_directions(sshc->ssh_session); + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + curl_socket_t fd_read = CURL_SOCKET_BAD; + curl_socket_t fd_write = CURL_SOCKET_BAD; + if(LIBSSH2_SESSION_BLOCK_INBOUND & dir) + fd_read = sock; + if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) + fd_write = sock; + /* wait for the socket to become ready */ + (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, + left>1000?1000:left); /* ignore result */ + } +#endif + + } + + return result; +} + +/* + * SSH setup and connection + */ +static CURLcode ssh_setup_connection(struct connectdata *conn) +{ + struct SSHPROTO *ssh; + + conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO)); + if(!ssh) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; +} + +static Curl_recv scp_recv, sftp_recv; +static Curl_send scp_send, sftp_send; + +/* + * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to + * do protocol-specific actions at connect-time. + */ +static CURLcode ssh_connect(struct connectdata *conn, bool *done) +{ +#ifdef CURL_LIBSSH2_DEBUG + curl_socket_t sock; +#endif + struct ssh_conn *ssh; + CURLcode result; + struct Curl_easy *data = conn->data; + + /* initialize per-handle data if not already */ + if(!data->req.protop) + ssh_setup_connection(conn); + + /* We default to persistent connections. We set this already in this connect + function to make the re-use checks properly be able to check this bit. */ + connkeep(conn, "SSH default"); + + if(conn->handler->protocol & CURLPROTO_SCP) { + conn->recv[FIRSTSOCKET] = scp_recv; + conn->send[FIRSTSOCKET] = scp_send; + } + else { + conn->recv[FIRSTSOCKET] = sftp_recv; + conn->send[FIRSTSOCKET] = sftp_send; + } + ssh = &conn->proto.sshc; + +#ifdef CURL_LIBSSH2_DEBUG + if(conn->user) { + infof(data, "User: %s\n", conn->user); + } + if(conn->passwd) { + infof(data, "Password: %s\n", conn->passwd); + } + sock = conn->sock[FIRSTSOCKET]; +#endif /* CURL_LIBSSH2_DEBUG */ + + ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc, + my_libssh2_free, + my_libssh2_realloc, conn); + if(ssh->ssh_session == NULL) { + failf(data, "Failure initialising ssh session"); + return CURLE_FAILED_INIT; + } + + if(data->set.ssh_compression) { +#if LIBSSH2_VERSION_NUM >= 0x010208 + if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0) +#endif + infof(data, "Failed to enable compression for ssh session\n"); + } + +#ifdef HAVE_LIBSSH2_KNOWNHOST_API + if(data->set.str[STRING_SSH_KNOWNHOSTS]) { + int rc; + ssh->kh = libssh2_knownhost_init(ssh->ssh_session); + if(!ssh->kh) { + libssh2_session_free(ssh->ssh_session); + return CURLE_FAILED_INIT; + } + + /* read all known hosts from there */ + rc = libssh2_knownhost_readfile(ssh->kh, + data->set.str[STRING_SSH_KNOWNHOSTS], + LIBSSH2_KNOWNHOST_FILE_OPENSSH); + if(rc < 0) + infof(data, "Failed to read known hosts from %s\n", + data->set.str[STRING_SSH_KNOWNHOSTS]); + } +#endif /* HAVE_LIBSSH2_KNOWNHOST_API */ + +#ifdef CURL_LIBSSH2_DEBUG + libssh2_trace(ssh->ssh_session, ~0); + infof(data, "SSH socket: %d\n", (int)sock); +#endif /* CURL_LIBSSH2_DEBUG */ + + state(conn, SSH_INIT); + + result = ssh_multi_statemach(conn, done); + + return result; +} + +/* + *********************************************************************** + * + * scp_perform() + * + * This is the actual DO function for SCP. Get a file according to + * the options previously setup. + */ + +static +CURLcode scp_perform(struct connectdata *conn, + bool *connected, + bool *dophase_done) +{ + CURLcode result = CURLE_OK; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + *dophase_done = FALSE; /* not done yet */ + + /* start the first command in the DO phase */ + state(conn, SSH_SCP_TRANS_INIT); + + /* run the state-machine */ + result = ssh_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +/* called from multi.c while DOing */ +static CURLcode scp_doing(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result; + result = ssh_multi_statemach(conn, dophase_done); + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + return result; +} + +/* + * The DO function is generic for both protocols. There was previously two + * separate ones but this way means less duplicated code. + */ + +static CURLcode ssh_do(struct connectdata *conn, bool *done) +{ + CURLcode result; + bool connected = 0; + struct Curl_easy *data = conn->data; + struct ssh_conn *sshc = &conn->proto.sshc; + + *done = FALSE; /* default to false */ + + data->req.size = -1; /* make sure this is unknown at this point */ + + sshc->actualcode = CURLE_OK; /* reset error code */ + sshc->secondCreateDirs = 0; /* reset the create dir attempt state + variable */ + + Curl_pgrsSetUploadCounter(data, 0); + Curl_pgrsSetDownloadCounter(data, 0); + Curl_pgrsSetUploadSize(data, -1); + Curl_pgrsSetDownloadSize(data, -1); + + if(conn->handler->protocol & CURLPROTO_SCP) + result = scp_perform(conn, &connected, done); + else + result = sftp_perform(conn, &connected, done); + + return result; +} + +/* BLOCKING, but the function is using the state machine so the only reason + this is still blocking is that the multi interface code has no support for + disconnecting operations that takes a while */ +static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection) +{ + CURLcode result = CURLE_OK; + struct ssh_conn *ssh = &conn->proto.sshc; + (void) dead_connection; + + if(ssh->ssh_session) { + /* only if there's a session still around to use! */ + + state(conn, SSH_SESSION_DISCONNECT); + + result = ssh_block_statemach(conn, TRUE); + } + + return result; +} + +/* generic done function for both SCP and SFTP called from their specific + done functions */ +static CURLcode ssh_done(struct connectdata *conn, CURLcode status) +{ + CURLcode result = CURLE_OK; + struct SSHPROTO *sftp_scp = conn->data->req.protop; + + if(!status) { + /* run the state-machine */ + result = ssh_block_statemach(conn, FALSE); + } + else + result = status; + + if(sftp_scp) + Curl_safefree(sftp_scp->path); + if(Curl_pgrsDone(conn)) + return CURLE_ABORTED_BY_CALLBACK; + + conn->data->req.keepon = 0; /* clear all bits */ + return result; +} + + +static CURLcode scp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + (void)premature; /* not used */ + + if(!status) + state(conn, SSH_SCP_DONE); + + return ssh_done(conn, status); + +} + +static ssize_t scp_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) +{ + ssize_t nwrite; + (void)sockindex; /* we only support SCP on the fixed known primary socket */ + + /* libssh2_channel_write() returns int! */ + nwrite = (ssize_t) + libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len); + + ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + + if(nwrite == LIBSSH2_ERROR_EAGAIN) { + *err = CURLE_AGAIN; + nwrite = 0; + } + else if(nwrite < LIBSSH2_ERROR_NONE) { + *err = libssh2_session_error_to_CURLE((int)nwrite); + nwrite = -1; + } + + return nwrite; +} + +static ssize_t scp_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) +{ + ssize_t nread; + (void)sockindex; /* we only support SCP on the fixed known primary socket */ + + /* libssh2_channel_read() returns int */ + nread = (ssize_t) + libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len); + + ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + if(nread == LIBSSH2_ERROR_EAGAIN) { + *err = CURLE_AGAIN; + nread = -1; + } + + return nread; +} + +/* + * =============== SFTP =============== + */ + +/* + *********************************************************************** + * + * sftp_perform() + * + * This is the actual DO function for SFTP. Get a file/directory according to + * the options previously setup. + */ + +static +CURLcode sftp_perform(struct connectdata *conn, + bool *connected, + bool *dophase_done) +{ + CURLcode result = CURLE_OK; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + *dophase_done = FALSE; /* not done yet */ + + /* start the first command in the DO phase */ + state(conn, SSH_SFTP_QUOTE_INIT); + + /* run the state-machine */ + result = ssh_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +/* called from multi.c while DOing */ +static CURLcode sftp_doing(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result = ssh_multi_statemach(conn, dophase_done); + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + return result; +} + +/* BLOCKING, but the function is using the state machine so the only reason + this is still blocking is that the multi interface code has no support for + disconnecting operations that takes a while */ +static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection) +{ + CURLcode result = CURLE_OK; + (void) dead_connection; + + DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n")); + + if(conn->proto.sshc.ssh_session) { + /* only if there's a session still around to use! */ + state(conn, SSH_SFTP_SHUTDOWN); + result = ssh_block_statemach(conn, TRUE); + } + + DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n")); + + return result; + +} + +static CURLcode sftp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + + if(!status) { + /* Post quote commands are executed after the SFTP_CLOSE state to avoid + errors that could happen due to open file handles during POSTQUOTE + operation */ + if(!premature && conn->data->set.postquote && !conn->bits.retry) + sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; + state(conn, SSH_SFTP_CLOSE); + } + return ssh_done(conn, status); +} + +/* return number of sent bytes */ +static ssize_t sftp_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) +{ + ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14 + but is changed to ssize_t in 0.15. These days we don't + support libssh2 0.15*/ + (void)sockindex; + + nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len); + + ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + + if(nwrite == LIBSSH2_ERROR_EAGAIN) { + *err = CURLE_AGAIN; + nwrite = 0; + } + else if(nwrite < LIBSSH2_ERROR_NONE) { + *err = libssh2_session_error_to_CURLE((int)nwrite); + nwrite = -1; + } + + return nwrite; +} + +/* + * Return number of received (decrypted) bytes + * or <0 on error + */ +static ssize_t sftp_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) +{ + ssize_t nread; + (void)sockindex; + + nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len); + + ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + + if(nread == LIBSSH2_ERROR_EAGAIN) { + *err = CURLE_AGAIN; + nread = -1; + + } + else if(nread < 0) { + *err = libssh2_session_error_to_CURLE((int)nread); + } + return nread; +} + +static const char *sftp_libssh2_strerror(int err) +{ + switch(err) { + case LIBSSH2_FX_NO_SUCH_FILE: + return "No such file or directory"; + + case LIBSSH2_FX_PERMISSION_DENIED: + return "Permission denied"; + + case LIBSSH2_FX_FAILURE: + return "Operation failed"; + + case LIBSSH2_FX_BAD_MESSAGE: + return "Bad message from SFTP server"; + + case LIBSSH2_FX_NO_CONNECTION: + return "Not connected to SFTP server"; + + case LIBSSH2_FX_CONNECTION_LOST: + return "Connection to SFTP server lost"; + + case LIBSSH2_FX_OP_UNSUPPORTED: + return "Operation not supported by SFTP server"; + + case LIBSSH2_FX_INVALID_HANDLE: + return "Invalid handle"; + + case LIBSSH2_FX_NO_SUCH_PATH: + return "No such file or directory"; + + case LIBSSH2_FX_FILE_ALREADY_EXISTS: + return "File already exists"; + + case LIBSSH2_FX_WRITE_PROTECT: + return "File is write protected"; + + case LIBSSH2_FX_NO_MEDIA: + return "No media"; + + case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM: + return "Disk full"; + + case LIBSSH2_FX_QUOTA_EXCEEDED: + return "User quota exceeded"; + + case LIBSSH2_FX_UNKNOWN_PRINCIPLE: + return "Unknown principle"; + + case LIBSSH2_FX_LOCK_CONFlICT: + return "File lock conflict"; + + case LIBSSH2_FX_DIR_NOT_EMPTY: + return "Directory not empty"; + + case LIBSSH2_FX_NOT_A_DIRECTORY: + return "Not a directory"; + + case LIBSSH2_FX_INVALID_FILENAME: + return "Invalid filename"; + + case LIBSSH2_FX_LINK_LOOP: + return "Link points to itself"; + } + return "Unknown error in libssh2"; +} + +#endif /* USE_LIBSSH2 */ diff --git a/libcurl/lib/ssh.h b/libcurl/lib/ssh.h new file mode 100644 index 0000000..0620aac --- /dev/null +++ b/libcurl/lib/ssh.h @@ -0,0 +1,245 @@ +#ifndef HEADER_CURL_SSH_H +#define HEADER_CURL_SSH_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(HAVE_LIBSSH2_H) +#include +#include +#elif defined(HAVE_LIBSSH_LIBSSH_H) +#include +#include +#endif /* HAVE_LIBSSH2_H */ + +/**************************************************************************** + * SSH unique setup + ***************************************************************************/ +typedef enum { + SSH_NO_STATE = -1, /* Used for "nextState" so say there is none */ + SSH_STOP = 0, /* do nothing state, stops the state machine */ + + SSH_INIT, /* First state in SSH-CONNECT */ + SSH_S_STARTUP, /* Session startup */ + SSH_HOSTKEY, /* verify hostkey */ + SSH_AUTHLIST, + SSH_AUTH_PKEY_INIT, + SSH_AUTH_PKEY, + SSH_AUTH_PASS_INIT, + SSH_AUTH_PASS, + SSH_AUTH_AGENT_INIT, /* initialize then wait for connection to agent */ + SSH_AUTH_AGENT_LIST, /* ask for list then wait for entire list to come */ + SSH_AUTH_AGENT, /* attempt one key at a time */ + SSH_AUTH_HOST_INIT, + SSH_AUTH_HOST, + SSH_AUTH_KEY_INIT, + SSH_AUTH_KEY, + SSH_AUTH_GSSAPI, + SSH_AUTH_DONE, + SSH_SFTP_INIT, + SSH_SFTP_REALPATH, /* Last state in SSH-CONNECT */ + + SSH_SFTP_QUOTE_INIT, /* First state in SFTP-DO */ + SSH_SFTP_POSTQUOTE_INIT, /* (Possibly) First state in SFTP-DONE */ + SSH_SFTP_QUOTE, + SSH_SFTP_NEXT_QUOTE, + SSH_SFTP_QUOTE_STAT, + SSH_SFTP_QUOTE_SETSTAT, + SSH_SFTP_QUOTE_SYMLINK, + SSH_SFTP_QUOTE_MKDIR, + SSH_SFTP_QUOTE_RENAME, + SSH_SFTP_QUOTE_RMDIR, + SSH_SFTP_QUOTE_UNLINK, + SSH_SFTP_QUOTE_STATVFS, + SSH_SFTP_GETINFO, + SSH_SFTP_FILETIME, + SSH_SFTP_TRANS_INIT, + SSH_SFTP_UPLOAD_INIT, + SSH_SFTP_CREATE_DIRS_INIT, + SSH_SFTP_CREATE_DIRS, + SSH_SFTP_CREATE_DIRS_MKDIR, + SSH_SFTP_READDIR_INIT, + SSH_SFTP_READDIR, + SSH_SFTP_READDIR_LINK, + SSH_SFTP_READDIR_BOTTOM, + SSH_SFTP_READDIR_DONE, + SSH_SFTP_DOWNLOAD_INIT, + SSH_SFTP_DOWNLOAD_STAT, /* Last state in SFTP-DO */ + SSH_SFTP_CLOSE, /* Last state in SFTP-DONE */ + SSH_SFTP_SHUTDOWN, /* First state in SFTP-DISCONNECT */ + SSH_SCP_TRANS_INIT, /* First state in SCP-DO */ + SSH_SCP_UPLOAD_INIT, + SSH_SCP_DOWNLOAD_INIT, + SSH_SCP_DOWNLOAD, + SSH_SCP_DONE, + SSH_SCP_SEND_EOF, + SSH_SCP_WAIT_EOF, + SSH_SCP_WAIT_CLOSE, + SSH_SCP_CHANNEL_FREE, /* Last state in SCP-DONE */ + SSH_SESSION_DISCONNECT, /* First state in SCP-DISCONNECT */ + SSH_SESSION_FREE, /* Last state in SCP/SFTP-DISCONNECT */ + SSH_QUIT, + SSH_LAST /* never used */ +} sshstate; + +/* this struct is used in the HandleData struct which is part of the + Curl_easy, which means this is used on a per-easy handle basis. + Everything that is strictly related to a connection is banned from this + struct. */ +struct SSHPROTO { + char *path; /* the path we operate on */ +}; + +/* ssh_conn is used for struct connection-oriented data in the connectdata + struct */ +struct ssh_conn { + const char *authlist; /* List of auth. methods, managed by libssh2 */ + + /* common */ + const char *passphrase; /* pass-phrase to use */ + char *rsa_pub; /* path name */ + char *rsa; /* path name */ + bool authed; /* the connection has been authenticated fine */ + sshstate state; /* always use ssh.c:state() to change state! */ + sshstate nextstate; /* the state to goto after stopping */ + CURLcode actualcode; /* the actual error code */ + struct curl_slist *quote_item; /* for the quote option */ + char *quote_path1; /* two generic pointers for the QUOTE stuff */ + char *quote_path2; + + bool acceptfail; /* used by the SFTP_QUOTE (continue if + quote command fails) */ + char *homedir; /* when doing SFTP we figure out home dir in the + connect phase */ + size_t readdir_len, readdir_totalLen, readdir_currLen; + char *readdir_line; + char *readdir_linkPath; + /* end of READDIR stuff */ + + int secondCreateDirs; /* counter use by the code to see if the + second attempt has been made to change + to/create a directory */ + char *slash_pos; /* used by the SFTP_CREATE_DIRS state */ + + int orig_waitfor; /* default READ/WRITE bits wait for */ + +#if defined(USE_LIBSSH) +/* our variables */ + unsigned kbd_state; /* 0 or 1 */ + ssh_key privkey; + ssh_key pubkey; + int auth_methods; + ssh_session ssh_session; + ssh_scp scp_session; + sftp_session sftp_session; + sftp_file sftp_file; + sftp_dir sftp_dir; + + unsigned sftp_recv_state; /* 0 or 1 */ + int sftp_file_index; /* for async read */ + sftp_attributes readdir_attrs; /* used by the SFTP readdir actions */ + sftp_attributes readdir_link_attrs; /* used by the SFTP readdir actions */ + sftp_attributes quote_attrs; /* used by the SFTP_QUOTE state */ + + const char *readdir_filename; /* points within readdir_attrs */ + const char *readdir_longentry; + char *readdir_tmp; +#elif defined(USE_LIBSSH2) + char *readdir_filename; + char *readdir_longentry; + + LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */ + + /* Here's a set of struct members used by the SFTP_READDIR state */ + LIBSSH2_SFTP_ATTRIBUTES readdir_attrs; + LIBSSH2_SESSION *ssh_session; /* Secure Shell session */ + LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */ + LIBSSH2_SFTP *sftp_session; /* SFTP handle */ + LIBSSH2_SFTP_HANDLE *sftp_handle; + +#ifdef HAVE_LIBSSH2_AGENT_API + LIBSSH2_AGENT *ssh_agent; /* proxy to ssh-agent/pageant */ + struct libssh2_agent_publickey *sshagent_identity, + *sshagent_prev_identity; +#endif + + /* note that HAVE_LIBSSH2_KNOWNHOST_API is a define set in the libssh2.h + header */ +#ifdef HAVE_LIBSSH2_KNOWNHOST_API + LIBSSH2_KNOWNHOSTS *kh; +#endif +#endif /* USE_LIBSSH */ +}; + +#if defined(USE_LIBSSH) + +#define CURL_LIBSSH_VERSION ssh_version(0) + +extern const struct Curl_handler Curl_handler_scp; +extern const struct Curl_handler Curl_handler_sftp; + +#elif defined(USE_LIBSSH2) + +/* Feature detection based on version numbers to better work with + non-configure platforms */ + +#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000) +# error "SCP/SFTP protocols require libssh2 0.16 or later" +#endif + +#if LIBSSH2_VERSION_NUM >= 0x010000 +#define HAVE_LIBSSH2_SFTP_SEEK64 1 +#endif + +#if LIBSSH2_VERSION_NUM >= 0x010100 +#define HAVE_LIBSSH2_VERSION 1 +#endif + +#if LIBSSH2_VERSION_NUM >= 0x010205 +#define HAVE_LIBSSH2_INIT 1 +#define HAVE_LIBSSH2_EXIT 1 +#endif + +#if LIBSSH2_VERSION_NUM >= 0x010206 +#define HAVE_LIBSSH2_KNOWNHOST_CHECKP 1 +#define HAVE_LIBSSH2_SCP_SEND64 1 +#endif + +#if LIBSSH2_VERSION_NUM >= 0x010208 +#define HAVE_LIBSSH2_SESSION_HANDSHAKE 1 +#endif + +#ifdef HAVE_LIBSSH2_VERSION +/* get it run-time if possible */ +#define CURL_LIBSSH2_VERSION libssh2_version(0) +#else +/* use build-time if run-time not possible */ +#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION +#endif + +extern const struct Curl_handler Curl_handler_scp; +extern const struct Curl_handler Curl_handler_sftp; + +#endif /* USE_LIBSSH2 */ + +#endif /* HEADER_CURL_SSH_H */ diff --git a/libcurl/lib/strcase.c b/libcurl/lib/strcase.c new file mode 100644 index 0000000..24bcca9 --- /dev/null +++ b/libcurl/lib/strcase.c @@ -0,0 +1,177 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "strcase.h" + +/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because + its behavior is altered by the current locale. */ +char Curl_raw_toupper(char in) +{ +#if !defined(CURL_DOES_CONVERSIONS) + if(in >= 'a' && in <= 'z') + return (char)('A' + in - 'a'); +#else + switch(in) { + case 'a': + return 'A'; + case 'b': + return 'B'; + case 'c': + return 'C'; + case 'd': + return 'D'; + case 'e': + return 'E'; + case 'f': + return 'F'; + case 'g': + return 'G'; + case 'h': + return 'H'; + case 'i': + return 'I'; + case 'j': + return 'J'; + case 'k': + return 'K'; + case 'l': + return 'L'; + case 'm': + return 'M'; + case 'n': + return 'N'; + case 'o': + return 'O'; + case 'p': + return 'P'; + case 'q': + return 'Q'; + case 'r': + return 'R'; + case 's': + return 'S'; + case 't': + return 'T'; + case 'u': + return 'U'; + case 'v': + return 'V'; + case 'w': + return 'W'; + case 'x': + return 'X'; + case 'y': + return 'Y'; + case 'z': + return 'Z'; + } +#endif + + return in; +} + +/* + * Curl_strcasecompare() is for doing "raw" case insensitive strings. This is + * meant to be locale independent and only compare strings we know are safe + * for this. See + * https://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for some + * further explanation to why this function is necessary. + * + * The function is capable of comparing a-z case insensitively even for + * non-ascii. + * + * @unittest: 1301 + */ + +int Curl_strcasecompare(const char *first, const char *second) +{ + while(*first && *second) { + if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) + /* get out of the loop as soon as they don't match */ + break; + first++; + second++; + } + /* we do the comparison here (possibly again), just to make sure that if the + loop above is skipped because one of the strings reached zero, we must not + return this as a successful match */ + return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second)); +} + +int Curl_safe_strcasecompare(const char *first, const char *second) +{ + if(first && second) + /* both pointers point to something then compare them */ + return Curl_strcasecompare(first, second); + + /* if both pointers are NULL then treat them as equal */ + return (NULL == first && NULL == second); +} + +/* + * @unittest: 1301 + */ +int Curl_strncasecompare(const char *first, const char *second, size_t max) +{ + while(*first && *second && max) { + if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) { + break; + } + max--; + first++; + second++; + } + if(0 == max) + return 1; /* they are equal this far */ + + return Curl_raw_toupper(*first) == Curl_raw_toupper(*second); +} + +/* Copy an upper case version of the string from src to dest. The + * strings may overlap. No more than n characters of the string are copied + * (including any NUL) and the destination string will NOT be + * NUL-terminated if that limit is reached. + */ +void Curl_strntoupper(char *dest, const char *src, size_t n) +{ + if(n < 1) + return; + + do { + *dest++ = Curl_raw_toupper(*src); + } while(*src++ && --n); +} + +/* --- public functions --- */ + +int curl_strequal(const char *first, const char *second) +{ + return Curl_strcasecompare(first, second); +} +int curl_strnequal(const char *first, const char *second, size_t max) +{ + return Curl_strncasecompare(first, second, max); +} diff --git a/libcurl/lib/strcase.h b/libcurl/lib/strcase.h new file mode 100644 index 0000000..6fee384 --- /dev/null +++ b/libcurl/lib/strcase.h @@ -0,0 +1,50 @@ +#ifndef HEADER_CURL_STRCASE_H +#define HEADER_CURL_STRCASE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include + +/* + * Only "raw" case insensitive strings. This is meant to be locale independent + * and only compare strings we know are safe for this. + * + * The function is capable of comparing a-z case insensitively even for + * non-ascii. + */ + +#define strcasecompare(a,b) Curl_strcasecompare(a,b) +#define strncasecompare(a,b,c) Curl_strncasecompare(a,b,c) + +int Curl_strcasecompare(const char *first, const char *second); +int Curl_safe_strcasecompare(const char *first, const char *second); +int Curl_strncasecompare(const char *first, const char *second, size_t max); + +char Curl_raw_toupper(char in); + +/* checkprefix() is a shorter version of the above, used when the first + argument is zero-byte terminated */ +#define checkprefix(a,b) curl_strnequal(a,b,strlen(a)) + +void Curl_strntoupper(char *dest, const char *src, size_t n); + +#endif /* HEADER_CURL_STRCASE_H */ diff --git a/libcurl/lib/strdup.c b/libcurl/lib/strdup.c new file mode 100644 index 0000000..51e7978 --- /dev/null +++ b/libcurl/lib/strdup.c @@ -0,0 +1,100 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "strdup.h" +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +#ifndef HAVE_STRDUP +char *curlx_strdup(const char *str) +{ + size_t len; + char *newstr; + + if(!str) + return (char *)NULL; + + len = strlen(str); + + if(len >= ((size_t)-1) / sizeof(char)) + return (char *)NULL; + + newstr = malloc((len + 1)*sizeof(char)); + if(!newstr) + return (char *)NULL; + + memcpy(newstr, str, (len + 1)*sizeof(char)); + + return newstr; + +} +#endif + +/*************************************************************************** + * + * Curl_memdup(source, length) + * + * Copies the 'source' data to a newly allocated buffer (that is + * returned). Copies 'length' bytes. + * + * Returns the new pointer or NULL on failure. + * + ***************************************************************************/ +void *Curl_memdup(const void *src, size_t length) +{ + void *buffer = malloc(length); + if(!buffer) + return NULL; /* fail */ + + memcpy(buffer, src, length); + + return buffer; +} + +/*************************************************************************** + * + * Curl_saferealloc(ptr, size) + * + * Does a normal realloc(), but will free the data pointer if the realloc + * fails. If 'size' is non-zero, it will free the data and return a failure. + * + * This convenience function is provided and used to help us avoid a common + * mistake pattern when we could pass in a zero, catch the NULL return and end + * up free'ing the memory twice. + * + * Returns the new pointer or NULL on failure. + * + ***************************************************************************/ +void *Curl_saferealloc(void *ptr, size_t size) +{ + void *datap = realloc(ptr, size); + if(size && !datap) + /* only free 'ptr' if size was non-zero */ + free(ptr); + return datap; +} diff --git a/libcurl/lib/strdup.h b/libcurl/lib/strdup.h new file mode 100644 index 0000000..ae3d5d0 --- /dev/null +++ b/libcurl/lib/strdup.h @@ -0,0 +1,32 @@ +#ifndef HEADER_CURL_STRDUP_H +#define HEADER_CURL_STRDUP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifndef HAVE_STRDUP +extern char *curlx_strdup(const char *str); +#endif +void *Curl_memdup(const void *src, size_t buffer_length); +void *Curl_saferealloc(void *ptr, size_t size); + +#endif /* HEADER_CURL_STRDUP_H */ diff --git a/libcurl/lib/strerror.c b/libcurl/lib/strerror.c new file mode 100644 index 0000000..132f0c7 --- /dev/null +++ b/libcurl/lib/strerror.c @@ -0,0 +1,1103 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2004 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_STRERROR_R +# if (!defined(HAVE_POSIX_STRERROR_R) && \ + !defined(HAVE_GLIBC_STRERROR_R) && \ + !defined(HAVE_VXWORKS_STRERROR_R)) || \ + (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \ + (defined(HAVE_GLIBC_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \ + (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)) +# error "strerror_r MUST be either POSIX, glibc or vxworks-style" +# endif +#endif + +#include + +#ifdef USE_LIBIDN2 +#include +#endif + +#ifdef USE_WINDOWS_SSPI +#include "curl_sspi.h" +#endif + +#include "strerror.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#if defined(WIN32) || defined(_WIN32_WCE) +#define PRESERVE_WINDOWS_ERROR_CODE +#endif + +const char * +curl_easy_strerror(CURLcode error) +{ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + switch(error) { + case CURLE_OK: + return "No error"; + + case CURLE_UNSUPPORTED_PROTOCOL: + return "Unsupported protocol"; + + case CURLE_FAILED_INIT: + return "Failed initialization"; + + case CURLE_URL_MALFORMAT: + return "URL using bad/illegal format or missing URL"; + + case CURLE_NOT_BUILT_IN: + return "A requested feature, protocol or option was not found built-in in" + " this libcurl due to a build-time decision."; + + case CURLE_COULDNT_RESOLVE_PROXY: + return "Couldn't resolve proxy name"; + + case CURLE_COULDNT_RESOLVE_HOST: + return "Couldn't resolve host name"; + + case CURLE_COULDNT_CONNECT: + return "Couldn't connect to server"; + + case CURLE_WEIRD_SERVER_REPLY: + return "Weird server reply"; + + case CURLE_REMOTE_ACCESS_DENIED: + return "Access denied to remote resource"; + + case CURLE_FTP_ACCEPT_FAILED: + return "FTP: The server failed to connect to data port"; + + case CURLE_FTP_ACCEPT_TIMEOUT: + return "FTP: Accepting server connect has timed out"; + + case CURLE_FTP_PRET_FAILED: + return "FTP: The server did not accept the PRET command."; + + case CURLE_FTP_WEIRD_PASS_REPLY: + return "FTP: unknown PASS reply"; + + case CURLE_FTP_WEIRD_PASV_REPLY: + return "FTP: unknown PASV reply"; + + case CURLE_FTP_WEIRD_227_FORMAT: + return "FTP: unknown 227 response format"; + + case CURLE_FTP_CANT_GET_HOST: + return "FTP: can't figure out the host in the PASV response"; + + case CURLE_HTTP2: + return "Error in the HTTP2 framing layer"; + + case CURLE_FTP_COULDNT_SET_TYPE: + return "FTP: couldn't set file type"; + + case CURLE_PARTIAL_FILE: + return "Transferred a partial file"; + + case CURLE_FTP_COULDNT_RETR_FILE: + return "FTP: couldn't retrieve (RETR failed) the specified file"; + + case CURLE_QUOTE_ERROR: + return "Quote command returned error"; + + case CURLE_HTTP_RETURNED_ERROR: + return "HTTP response code said error"; + + case CURLE_WRITE_ERROR: + return "Failed writing received data to disk/application"; + + case CURLE_UPLOAD_FAILED: + return "Upload failed (at start/before it took off)"; + + case CURLE_READ_ERROR: + return "Failed to open/read local data from file/application"; + + case CURLE_OUT_OF_MEMORY: + return "Out of memory"; + + case CURLE_OPERATION_TIMEDOUT: + return "Timeout was reached"; + + case CURLE_FTP_PORT_FAILED: + return "FTP: command PORT failed"; + + case CURLE_FTP_COULDNT_USE_REST: + return "FTP: command REST failed"; + + case CURLE_RANGE_ERROR: + return "Requested range was not delivered by the server"; + + case CURLE_HTTP_POST_ERROR: + return "Internal problem setting up the POST"; + + case CURLE_SSL_CONNECT_ERROR: + return "SSL connect error"; + + case CURLE_BAD_DOWNLOAD_RESUME: + return "Couldn't resume download"; + + case CURLE_FILE_COULDNT_READ_FILE: + return "Couldn't read a file:// file"; + + case CURLE_LDAP_CANNOT_BIND: + return "LDAP: cannot bind"; + + case CURLE_LDAP_SEARCH_FAILED: + return "LDAP: search failed"; + + case CURLE_FUNCTION_NOT_FOUND: + return "A required function in the library was not found"; + + case CURLE_ABORTED_BY_CALLBACK: + return "Operation was aborted by an application callback"; + + case CURLE_BAD_FUNCTION_ARGUMENT: + return "A libcurl function was given a bad argument"; + + case CURLE_INTERFACE_FAILED: + return "Failed binding local connection end"; + + case CURLE_TOO_MANY_REDIRECTS : + return "Number of redirects hit maximum amount"; + + case CURLE_UNKNOWN_OPTION: + return "An unknown option was passed in to libcurl"; + + case CURLE_TELNET_OPTION_SYNTAX : + return "Malformed telnet option"; + + case CURLE_GOT_NOTHING: + return "Server returned nothing (no headers, no data)"; + + case CURLE_SSL_ENGINE_NOTFOUND: + return "SSL crypto engine not found"; + + case CURLE_SSL_ENGINE_SETFAILED: + return "Can not set SSL crypto engine as default"; + + case CURLE_SSL_ENGINE_INITFAILED: + return "Failed to initialise SSL crypto engine"; + + case CURLE_SEND_ERROR: + return "Failed sending data to the peer"; + + case CURLE_RECV_ERROR: + return "Failure when receiving data from the peer"; + + case CURLE_SSL_CERTPROBLEM: + return "Problem with the local SSL certificate"; + + case CURLE_SSL_CIPHER: + return "Couldn't use specified SSL cipher"; + + case CURLE_PEER_FAILED_VERIFICATION: + return "SSL peer certificate or SSH remote key was not OK"; + + case CURLE_SSL_CACERT_BADFILE: + return "Problem with the SSL CA cert (path? access rights?)"; + + case CURLE_BAD_CONTENT_ENCODING: + return "Unrecognized or bad HTTP Content or Transfer-Encoding"; + + case CURLE_LDAP_INVALID_URL: + return "Invalid LDAP URL"; + + case CURLE_FILESIZE_EXCEEDED: + return "Maximum file size exceeded"; + + case CURLE_USE_SSL_FAILED: + return "Requested SSL level failed"; + + case CURLE_SSL_SHUTDOWN_FAILED: + return "Failed to shut down the SSL connection"; + + case CURLE_SSL_CRL_BADFILE: + return "Failed to load CRL file (path? access rights?, format?)"; + + case CURLE_SSL_ISSUER_ERROR: + return "Issuer check against peer certificate failed"; + + case CURLE_SEND_FAIL_REWIND: + return "Send failed since rewinding of the data stream failed"; + + case CURLE_LOGIN_DENIED: + return "Login denied"; + + case CURLE_TFTP_NOTFOUND: + return "TFTP: File Not Found"; + + case CURLE_TFTP_PERM: + return "TFTP: Access Violation"; + + case CURLE_REMOTE_DISK_FULL: + return "Disk full or allocation exceeded"; + + case CURLE_TFTP_ILLEGAL: + return "TFTP: Illegal operation"; + + case CURLE_TFTP_UNKNOWNID: + return "TFTP: Unknown transfer ID"; + + case CURLE_REMOTE_FILE_EXISTS: + return "Remote file already exists"; + + case CURLE_TFTP_NOSUCHUSER: + return "TFTP: No such user"; + + case CURLE_CONV_FAILED: + return "Conversion failed"; + + case CURLE_CONV_REQD: + return "Caller must register CURLOPT_CONV_ callback options"; + + case CURLE_REMOTE_FILE_NOT_FOUND: + return "Remote file not found"; + + case CURLE_SSH: + return "Error in the SSH layer"; + + case CURLE_AGAIN: + return "Socket not ready for send/recv"; + + case CURLE_RTSP_CSEQ_ERROR: + return "RTSP CSeq mismatch or invalid CSeq"; + + case CURLE_RTSP_SESSION_ERROR: + return "RTSP session error"; + + case CURLE_FTP_BAD_FILE_LIST: + return "Unable to parse FTP file list"; + + case CURLE_CHUNK_FAILED: + return "Chunk callback failed"; + + case CURLE_NO_CONNECTION_AVAILABLE: + return "The max connection limit is reached"; + + case CURLE_SSL_PINNEDPUBKEYNOTMATCH: + return "SSL public key does not match pinned public key"; + + case CURLE_SSL_INVALIDCERTSTATUS: + return "SSL server certificate status verification FAILED"; + + case CURLE_HTTP2_STREAM: + return "Stream error in the HTTP/2 framing layer"; + + case CURLE_RECURSIVE_API_CALL: + return "API function called from within callback"; + + /* error codes not used by current libcurl */ + case CURLE_OBSOLETE20: + case CURLE_OBSOLETE24: + case CURLE_OBSOLETE29: + case CURLE_OBSOLETE32: + case CURLE_OBSOLETE40: + case CURLE_OBSOLETE44: + case CURLE_OBSOLETE46: + case CURLE_OBSOLETE50: + case CURLE_OBSOLETE51: + case CURLE_OBSOLETE57: + case CURL_LAST: + break; + } + /* + * By using a switch, gcc -Wall will complain about enum values + * which do not appear, helping keep this function up-to-date. + * By using gcc -Wall -Werror, you can't forget. + * + * A table would not have the same benefit. Most compilers will + * generate code very similar to a table in any case, so there + * is little performance gain from a table. And something is broken + * for the user's application, anyways, so does it matter how fast + * it _doesn't_ work? + * + * The line number for the error will be near this comment, which + * is why it is here, and not at the start of the switch. + */ + return "Unknown error"; +#else + if(!error) + return "No error"; + else + return "Error"; +#endif +} + +const char * +curl_multi_strerror(CURLMcode error) +{ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + switch(error) { + case CURLM_CALL_MULTI_PERFORM: + return "Please call curl_multi_perform() soon"; + + case CURLM_OK: + return "No error"; + + case CURLM_BAD_HANDLE: + return "Invalid multi handle"; + + case CURLM_BAD_EASY_HANDLE: + return "Invalid easy handle"; + + case CURLM_OUT_OF_MEMORY: + return "Out of memory"; + + case CURLM_INTERNAL_ERROR: + return "Internal error"; + + case CURLM_BAD_SOCKET: + return "Invalid socket argument"; + + case CURLM_UNKNOWN_OPTION: + return "Unknown option"; + + case CURLM_ADDED_ALREADY: + return "The easy handle is already added to a multi handle"; + + case CURLM_RECURSIVE_API_CALL: + return "API function called from within callback"; + + case CURLM_LAST: + break; + } + + return "Unknown error"; +#else + if(error == CURLM_OK) + return "No error"; + else + return "Error"; +#endif +} + +const char * +curl_share_strerror(CURLSHcode error) +{ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + switch(error) { + case CURLSHE_OK: + return "No error"; + + case CURLSHE_BAD_OPTION: + return "Unknown share option"; + + case CURLSHE_IN_USE: + return "Share currently in use"; + + case CURLSHE_INVALID: + return "Invalid share handle"; + + case CURLSHE_NOMEM: + return "Out of memory"; + + case CURLSHE_NOT_BUILT_IN: + return "Feature not enabled in this library"; + + case CURLSHE_LAST: + break; + } + + return "CURLSHcode unknown"; +#else + if(error == CURLSHE_OK) + return "No error"; + else + return "Error"; +#endif +} + +#ifdef USE_WINSOCK + +/* This function handles most / all (?) Winsock errors curl is able to produce. + */ +static const char * +get_winsock_error (int err, char *buf, size_t len) +{ +#ifdef PRESERVE_WINDOWS_ERROR_CODE + DWORD old_win_err = GetLastError(); +#endif + int old_errno = errno; + const char *p; + +#ifndef CURL_DISABLE_VERBOSE_STRINGS + switch(err) { + case WSAEINTR: + p = "Call interrupted"; + break; + case WSAEBADF: + p = "Bad file"; + break; + case WSAEACCES: + p = "Bad access"; + break; + case WSAEFAULT: + p = "Bad argument"; + break; + case WSAEINVAL: + p = "Invalid arguments"; + break; + case WSAEMFILE: + p = "Out of file descriptors"; + break; + case WSAEWOULDBLOCK: + p = "Call would block"; + break; + case WSAEINPROGRESS: + case WSAEALREADY: + p = "Blocking call in progress"; + break; + case WSAENOTSOCK: + p = "Descriptor is not a socket"; + break; + case WSAEDESTADDRREQ: + p = "Need destination address"; + break; + case WSAEMSGSIZE: + p = "Bad message size"; + break; + case WSAEPROTOTYPE: + p = "Bad protocol"; + break; + case WSAENOPROTOOPT: + p = "Protocol option is unsupported"; + break; + case WSAEPROTONOSUPPORT: + p = "Protocol is unsupported"; + break; + case WSAESOCKTNOSUPPORT: + p = "Socket is unsupported"; + break; + case WSAEOPNOTSUPP: + p = "Operation not supported"; + break; + case WSAEAFNOSUPPORT: + p = "Address family not supported"; + break; + case WSAEPFNOSUPPORT: + p = "Protocol family not supported"; + break; + case WSAEADDRINUSE: + p = "Address already in use"; + break; + case WSAEADDRNOTAVAIL: + p = "Address not available"; + break; + case WSAENETDOWN: + p = "Network down"; + break; + case WSAENETUNREACH: + p = "Network unreachable"; + break; + case WSAENETRESET: + p = "Network has been reset"; + break; + case WSAECONNABORTED: + p = "Connection was aborted"; + break; + case WSAECONNRESET: + p = "Connection was reset"; + break; + case WSAENOBUFS: + p = "No buffer space"; + break; + case WSAEISCONN: + p = "Socket is already connected"; + break; + case WSAENOTCONN: + p = "Socket is not connected"; + break; + case WSAESHUTDOWN: + p = "Socket has been shut down"; + break; + case WSAETOOMANYREFS: + p = "Too many references"; + break; + case WSAETIMEDOUT: + p = "Timed out"; + break; + case WSAECONNREFUSED: + p = "Connection refused"; + break; + case WSAELOOP: + p = "Loop??"; + break; + case WSAENAMETOOLONG: + p = "Name too long"; + break; + case WSAEHOSTDOWN: + p = "Host down"; + break; + case WSAEHOSTUNREACH: + p = "Host unreachable"; + break; + case WSAENOTEMPTY: + p = "Not empty"; + break; + case WSAEPROCLIM: + p = "Process limit reached"; + break; + case WSAEUSERS: + p = "Too many users"; + break; + case WSAEDQUOT: + p = "Bad quota"; + break; + case WSAESTALE: + p = "Something is stale"; + break; + case WSAEREMOTE: + p = "Remote error"; + break; +#ifdef WSAEDISCON /* missing in SalfordC! */ + case WSAEDISCON: + p = "Disconnected"; + break; +#endif + /* Extended Winsock errors */ + case WSASYSNOTREADY: + p = "Winsock library is not ready"; + break; + case WSANOTINITIALISED: + p = "Winsock library not initialised"; + break; + case WSAVERNOTSUPPORTED: + p = "Winsock version not supported"; + break; + + /* getXbyY() errors (already handled in herrmsg): + * Authoritative Answer: Host not found */ + case WSAHOST_NOT_FOUND: + p = "Host not found"; + break; + + /* Non-Authoritative: Host not found, or SERVERFAIL */ + case WSATRY_AGAIN: + p = "Host not found, try again"; + break; + + /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ + case WSANO_RECOVERY: + p = "Unrecoverable error in call to nameserver"; + break; + + /* Valid name, no data record of requested type */ + case WSANO_DATA: + p = "No data record of requested type"; + break; + + default: + return NULL; + } +#else + if(!err) + return NULL; + else + p = "error"; +#endif + strncpy(buf, p, len); + buf [len-1] = '\0'; + + if(errno != old_errno) + errno = old_errno; + +#ifdef PRESERVE_WINDOWS_ERROR_CODE + if(old_win_err != GetLastError()) + SetLastError(old_win_err); +#endif + + return buf; +} +#endif /* USE_WINSOCK */ + +/* + * Our thread-safe and smart strerror() replacement. + * + * The 'err' argument passed in to this function MUST be a true errno number + * as reported on this system. We do no range checking on the number before + * we pass it to the "number-to-message" conversion function and there might + * be systems that don't do proper range checking in there themselves. + * + * We don't do range checking (on systems other than Windows) since there is + * no good reliable and portable way to do it. + */ +const char *Curl_strerror(int err, char *buf, size_t buflen) +{ +#ifdef PRESERVE_WINDOWS_ERROR_CODE + DWORD old_win_err = GetLastError(); +#endif + int old_errno = errno; + char *p; + size_t max; + + DEBUGASSERT(err >= 0); + + max = buflen - 1; + *buf = '\0'; + +#ifdef USE_WINSOCK + +#ifdef _WIN32_WCE + { + wchar_t wbuf[256]; + wbuf[0] = L'\0'; + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, + LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL); + wcstombs(buf, wbuf, max); + } +#else + /* 'sys_nerr' is the maximum errno number, it is not widely portable */ + //if(err >= 0 && err < sys_nerr) + strncpy(buf, strerror(err), max); + /*else { + if(!get_winsock_error(err, buf, max) && + !FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, + LANG_NEUTRAL, buf, (DWORD)max, NULL)) + msnprintf(buf, max, "Unknown error %d (%#x)", err, err); + } + */ +#endif + +#else /* not USE_WINSOCK coming up */ + +#if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R) + /* + * The POSIX-style strerror_r() may set errno to ERANGE if insufficient + * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated + * message string, or EINVAL if 'errnum' is not a valid error number. + */ + if(0 != strerror_r(err, buf, max)) { + if('\0' == buf[0]) + msnprintf(buf, max, "Unknown error %d", err); + } +#elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R) + /* + * The glibc-style strerror_r() only *might* use the buffer we pass to + * the function, but it always returns the error message as a pointer, + * so we must copy that string unconditionally (if non-NULL). + */ + { + char buffer[256]; + char *msg = strerror_r(err, buffer, sizeof(buffer)); + if(msg) + strncpy(buf, msg, max); + else + msnprintf(buf, max, "Unknown error %d", err); + } +#elif defined(HAVE_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R) + /* + * The vxworks-style strerror_r() does use the buffer we pass to the function. + * The buffer size should be at least NAME_MAX (256) + */ + { + char buffer[256]; + if(OK == strerror_r(err, buffer)) + strncpy(buf, buffer, max); + else + msnprintf(buf, max, "Unknown error %d", err); + } +#else + { + char *msg = strerror(err); + if(msg) + strncpy(buf, msg, max); + else + msnprintf(buf, max, "Unknown error %d", err); + } +#endif + +#endif /* end of ! USE_WINSOCK */ + + buf[max] = '\0'; /* make sure the string is zero terminated */ + + /* strip trailing '\r\n' or '\n'. */ + p = strrchr(buf, '\n'); + if(p && (p - buf) >= 2) + *p = '\0'; + p = strrchr(buf, '\r'); + if(p && (p - buf) >= 1) + *p = '\0'; + + if(errno != old_errno) + errno = old_errno; + +#ifdef PRESERVE_WINDOWS_ERROR_CODE + if(old_win_err != GetLastError()) + SetLastError(old_win_err); +#endif + + return buf; +} + +#ifdef USE_WINDOWS_SSPI +const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) +{ +#ifdef PRESERVE_WINDOWS_ERROR_CODE + DWORD old_win_err = GetLastError(); +#endif + int old_errno = errno; + const char *txt; + char *outbuf; + size_t outmax; +#ifndef CURL_DISABLE_VERBOSE_STRINGS + char txtbuf[80]; + char msgbuf[256]; + char *p, *str, *msg = NULL; + bool msg_formatted = FALSE; +#endif + + outbuf = buf; + outmax = buflen - 1; + *outbuf = '\0'; + +#ifndef CURL_DISABLE_VERBOSE_STRINGS + + switch(err) { + case SEC_E_OK: + txt = "No error"; + break; + case CRYPT_E_REVOKED: + txt = "CRYPT_E_REVOKED"; + break; + case SEC_E_ALGORITHM_MISMATCH: + txt = "SEC_E_ALGORITHM_MISMATCH"; + break; + case SEC_E_BAD_BINDINGS: + txt = "SEC_E_BAD_BINDINGS"; + break; + case SEC_E_BAD_PKGID: + txt = "SEC_E_BAD_PKGID"; + break; + case SEC_E_BUFFER_TOO_SMALL: + txt = "SEC_E_BUFFER_TOO_SMALL"; + break; + case SEC_E_CANNOT_INSTALL: + txt = "SEC_E_CANNOT_INSTALL"; + break; + case SEC_E_CANNOT_PACK: + txt = "SEC_E_CANNOT_PACK"; + break; + case SEC_E_CERT_EXPIRED: + txt = "SEC_E_CERT_EXPIRED"; + break; + case SEC_E_CERT_UNKNOWN: + txt = "SEC_E_CERT_UNKNOWN"; + break; + case SEC_E_CERT_WRONG_USAGE: + txt = "SEC_E_CERT_WRONG_USAGE"; + break; + case SEC_E_CONTEXT_EXPIRED: + txt = "SEC_E_CONTEXT_EXPIRED"; + break; + case SEC_E_CROSSREALM_DELEGATION_FAILURE: + txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE"; + break; + case SEC_E_CRYPTO_SYSTEM_INVALID: + txt = "SEC_E_CRYPTO_SYSTEM_INVALID"; + break; + case SEC_E_DECRYPT_FAILURE: + txt = "SEC_E_DECRYPT_FAILURE"; + break; + case SEC_E_DELEGATION_POLICY: + txt = "SEC_E_DELEGATION_POLICY"; + break; + case SEC_E_DELEGATION_REQUIRED: + txt = "SEC_E_DELEGATION_REQUIRED"; + break; + case SEC_E_DOWNGRADE_DETECTED: + txt = "SEC_E_DOWNGRADE_DETECTED"; + break; + case SEC_E_ENCRYPT_FAILURE: + txt = "SEC_E_ENCRYPT_FAILURE"; + break; + case SEC_E_ILLEGAL_MESSAGE: + txt = "SEC_E_ILLEGAL_MESSAGE"; + break; + case SEC_E_INCOMPLETE_CREDENTIALS: + txt = "SEC_E_INCOMPLETE_CREDENTIALS"; + break; + case SEC_E_INCOMPLETE_MESSAGE: + txt = "SEC_E_INCOMPLETE_MESSAGE"; + break; + case SEC_E_INSUFFICIENT_MEMORY: + txt = "SEC_E_INSUFFICIENT_MEMORY"; + break; + case SEC_E_INTERNAL_ERROR: + txt = "SEC_E_INTERNAL_ERROR"; + break; + case SEC_E_INVALID_HANDLE: + txt = "SEC_E_INVALID_HANDLE"; + break; + case SEC_E_INVALID_PARAMETER: + txt = "SEC_E_INVALID_PARAMETER"; + break; + case SEC_E_INVALID_TOKEN: + txt = "SEC_E_INVALID_TOKEN"; + break; + case SEC_E_ISSUING_CA_UNTRUSTED: + txt = "SEC_E_ISSUING_CA_UNTRUSTED"; + break; + case SEC_E_ISSUING_CA_UNTRUSTED_KDC: + txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC"; + break; + case SEC_E_KDC_CERT_EXPIRED: + txt = "SEC_E_KDC_CERT_EXPIRED"; + break; + case SEC_E_KDC_CERT_REVOKED: + txt = "SEC_E_KDC_CERT_REVOKED"; + break; + case SEC_E_KDC_INVALID_REQUEST: + txt = "SEC_E_KDC_INVALID_REQUEST"; + break; + case SEC_E_KDC_UNABLE_TO_REFER: + txt = "SEC_E_KDC_UNABLE_TO_REFER"; + break; + case SEC_E_KDC_UNKNOWN_ETYPE: + txt = "SEC_E_KDC_UNKNOWN_ETYPE"; + break; + case SEC_E_LOGON_DENIED: + txt = "SEC_E_LOGON_DENIED"; + break; + case SEC_E_MAX_REFERRALS_EXCEEDED: + txt = "SEC_E_MAX_REFERRALS_EXCEEDED"; + break; + case SEC_E_MESSAGE_ALTERED: + txt = "SEC_E_MESSAGE_ALTERED"; + break; + case SEC_E_MULTIPLE_ACCOUNTS: + txt = "SEC_E_MULTIPLE_ACCOUNTS"; + break; + case SEC_E_MUST_BE_KDC: + txt = "SEC_E_MUST_BE_KDC"; + break; + case SEC_E_NOT_OWNER: + txt = "SEC_E_NOT_OWNER"; + break; + case SEC_E_NO_AUTHENTICATING_AUTHORITY: + txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY"; + break; + case SEC_E_NO_CREDENTIALS: + txt = "SEC_E_NO_CREDENTIALS"; + break; + case SEC_E_NO_IMPERSONATION: + txt = "SEC_E_NO_IMPERSONATION"; + break; + case SEC_E_NO_IP_ADDRESSES: + txt = "SEC_E_NO_IP_ADDRESSES"; + break; + case SEC_E_NO_KERB_KEY: + txt = "SEC_E_NO_KERB_KEY"; + break; + case SEC_E_NO_PA_DATA: + txt = "SEC_E_NO_PA_DATA"; + break; + case SEC_E_NO_S4U_PROT_SUPPORT: + txt = "SEC_E_NO_S4U_PROT_SUPPORT"; + break; + case SEC_E_NO_TGT_REPLY: + txt = "SEC_E_NO_TGT_REPLY"; + break; + case SEC_E_OUT_OF_SEQUENCE: + txt = "SEC_E_OUT_OF_SEQUENCE"; + break; + case SEC_E_PKINIT_CLIENT_FAILURE: + txt = "SEC_E_PKINIT_CLIENT_FAILURE"; + break; + case SEC_E_PKINIT_NAME_MISMATCH: + txt = "SEC_E_PKINIT_NAME_MISMATCH"; + break; + case SEC_E_POLICY_NLTM_ONLY: + txt = "SEC_E_POLICY_NLTM_ONLY"; + break; + case SEC_E_QOP_NOT_SUPPORTED: + txt = "SEC_E_QOP_NOT_SUPPORTED"; + break; + case SEC_E_REVOCATION_OFFLINE_C: + txt = "SEC_E_REVOCATION_OFFLINE_C"; + break; + case SEC_E_REVOCATION_OFFLINE_KDC: + txt = "SEC_E_REVOCATION_OFFLINE_KDC"; + break; + case SEC_E_SECPKG_NOT_FOUND: + txt = "SEC_E_SECPKG_NOT_FOUND"; + break; + case SEC_E_SECURITY_QOS_FAILED: + txt = "SEC_E_SECURITY_QOS_FAILED"; + break; + case SEC_E_SHUTDOWN_IN_PROGRESS: + txt = "SEC_E_SHUTDOWN_IN_PROGRESS"; + break; + case SEC_E_SMARTCARD_CERT_EXPIRED: + txt = "SEC_E_SMARTCARD_CERT_EXPIRED"; + break; + case SEC_E_SMARTCARD_CERT_REVOKED: + txt = "SEC_E_SMARTCARD_CERT_REVOKED"; + break; + case SEC_E_SMARTCARD_LOGON_REQUIRED: + txt = "SEC_E_SMARTCARD_LOGON_REQUIRED"; + break; + case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED: + txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED"; + break; + case SEC_E_TARGET_UNKNOWN: + txt = "SEC_E_TARGET_UNKNOWN"; + break; + case SEC_E_TIME_SKEW: + txt = "SEC_E_TIME_SKEW"; + break; + case SEC_E_TOO_MANY_PRINCIPALS: + txt = "SEC_E_TOO_MANY_PRINCIPALS"; + break; + case SEC_E_UNFINISHED_CONTEXT_DELETED: + txt = "SEC_E_UNFINISHED_CONTEXT_DELETED"; + break; + case SEC_E_UNKNOWN_CREDENTIALS: + txt = "SEC_E_UNKNOWN_CREDENTIALS"; + break; + case SEC_E_UNSUPPORTED_FUNCTION: + txt = "SEC_E_UNSUPPORTED_FUNCTION"; + break; + case SEC_E_UNSUPPORTED_PREAUTH: + txt = "SEC_E_UNSUPPORTED_PREAUTH"; + break; + case SEC_E_UNTRUSTED_ROOT: + txt = "SEC_E_UNTRUSTED_ROOT"; + break; + case SEC_E_WRONG_CREDENTIAL_HANDLE: + txt = "SEC_E_WRONG_CREDENTIAL_HANDLE"; + break; + case SEC_E_WRONG_PRINCIPAL: + txt = "SEC_E_WRONG_PRINCIPAL"; + break; + case SEC_I_COMPLETE_AND_CONTINUE: + txt = "SEC_I_COMPLETE_AND_CONTINUE"; + break; + case SEC_I_COMPLETE_NEEDED: + txt = "SEC_I_COMPLETE_NEEDED"; + break; + case SEC_I_CONTEXT_EXPIRED: + txt = "SEC_I_CONTEXT_EXPIRED"; + break; + case SEC_I_CONTINUE_NEEDED: + txt = "SEC_I_CONTINUE_NEEDED"; + break; + case SEC_I_INCOMPLETE_CREDENTIALS: + txt = "SEC_I_INCOMPLETE_CREDENTIALS"; + break; + case SEC_I_LOCAL_LOGON: + txt = "SEC_I_LOCAL_LOGON"; + break; + case SEC_I_NO_LSA_CONTEXT: + txt = "SEC_I_NO_LSA_CONTEXT"; + break; + case SEC_I_RENEGOTIATE: + txt = "SEC_I_RENEGOTIATE"; + break; + case SEC_I_SIGNATURE_NEEDED: + txt = "SEC_I_SIGNATURE_NEEDED"; + break; + default: + txt = "Unknown error"; + } + + if(err == SEC_E_OK) + strncpy(outbuf, txt, outmax); + else if(err == SEC_E_ILLEGAL_MESSAGE) + msnprintf(outbuf, outmax, + "SEC_E_ILLEGAL_MESSAGE (0x%08X) - This error usually occurs " + "when a fatal SSL/TLS alert is received (e.g. handshake failed)." + " More detail may be available in the Windows System event log.", + err); + else { + str = txtbuf; + msnprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err); + txtbuf[sizeof(txtbuf)-1] = '\0'; + +#ifdef _WIN32_WCE + { + wchar_t wbuf[256]; + wbuf[0] = L'\0'; + + if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, LANG_NEUTRAL, + wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) { + wcstombs(msgbuf, wbuf, sizeof(msgbuf)-1); + msg_formatted = TRUE; + } + } +#else + if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, LANG_NEUTRAL, + msgbuf, sizeof(msgbuf)-1, NULL)) { + msg_formatted = TRUE; + } +#endif + if(msg_formatted) { + msgbuf[sizeof(msgbuf)-1] = '\0'; + /* strip trailing '\r\n' or '\n' */ + p = strrchr(msgbuf, '\n'); + if(p && (p - msgbuf) >= 2) + *p = '\0'; + p = strrchr(msgbuf, '\r'); + if(p && (p - msgbuf) >= 1) + *p = '\0'; + msg = msgbuf; + } + if(msg) + msnprintf(outbuf, outmax, "%s - %s", str, msg); + else + strncpy(outbuf, str, outmax); + } + +#else + + if(err == SEC_E_OK) + txt = "No error"; + else + txt = "Error"; + + strncpy(outbuf, txt, outmax); + +#endif + + outbuf[outmax] = '\0'; + + if(errno != old_errno) + errno = old_errno; + +#ifdef PRESERVE_WINDOWS_ERROR_CODE + if(old_win_err != GetLastError()) + SetLastError(old_win_err); +#endif + + return outbuf; +} +#endif /* USE_WINDOWS_SSPI */ diff --git a/libcurl/lib/strerror.h b/libcurl/lib/strerror.h new file mode 100644 index 0000000..683b5b4 --- /dev/null +++ b/libcurl/lib/strerror.h @@ -0,0 +1,34 @@ +#ifndef HEADER_CURL_STRERROR_H +#define HEADER_CURL_STRERROR_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "urldata.h" + +#define STRERROR_LEN 128 /* a suitable length */ + +const char *Curl_strerror(int err, char *buf, size_t buflen); +#ifdef USE_WINDOWS_SSPI +const char *Curl_sspi_strerror(int err, char *buf, size_t buflen); +#endif + +#endif /* HEADER_CURL_STRERROR_H */ diff --git a/libcurl/lib/strtok.c b/libcurl/lib/strtok.c new file mode 100644 index 0000000..460eb87 --- /dev/null +++ b/libcurl/lib/strtok.c @@ -0,0 +1,66 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef HAVE_STRTOK_R +#include + +#include "strtok.h" + +char * +Curl_strtok_r(char *ptr, const char *sep, char **end) +{ + if(!ptr) + /* we got NULL input so then we get our last position instead */ + ptr = *end; + + /* pass all letters that are including in the separator string */ + while(*ptr && strchr(sep, *ptr)) + ++ptr; + + if(*ptr) { + /* so this is where the next piece of string starts */ + char *start = ptr; + + /* set the end pointer to the first byte after the start */ + *end = start + 1; + + /* scan through the string to find where it ends, it ends on a + null byte or a character that exists in the separator string */ + while(**end && !strchr(sep, **end)) + ++*end; + + if(**end) { + /* the end is not a null byte */ + **end = '\0'; /* zero terminate it! */ + ++*end; /* advance the last pointer to beyond the null byte */ + } + + return start; /* return the position where the string starts */ + } + + /* we ended up on a null byte, there are no more strings to find! */ + return NULL; +} + +#endif /* this was only compiled if strtok_r wasn't present */ diff --git a/libcurl/lib/strtok.h b/libcurl/lib/strtok.h new file mode 100644 index 0000000..90b831e --- /dev/null +++ b/libcurl/lib/strtok.h @@ -0,0 +1,34 @@ +#ifndef HEADER_CURL_STRTOK_H +#define HEADER_CURL_STRTOK_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" +#include + +#ifndef HAVE_STRTOK_R +char *Curl_strtok_r(char *s, const char *delim, char **last); +#define strtok_r Curl_strtok_r +#else +#include +#endif + +#endif /* HEADER_CURL_STRTOK_H */ diff --git a/libcurl/lib/strtoofft.c b/libcurl/lib/strtoofft.c new file mode 100644 index 0000000..546a3ff --- /dev/null +++ b/libcurl/lib/strtoofft.c @@ -0,0 +1,242 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include +#include "curl_setup.h" + +#include "strtoofft.h" + +/* + * NOTE: + * + * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we + * could use in case strtoll() doesn't exist... See + * https://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html + */ + +#if (SIZEOF_CURL_OFF_T > SIZEOF_LONG) +# ifdef HAVE_STRTOLL +# define strtooff strtoll +# else +# if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_INTEGRAL_MAX_BITS >= 64) +# if defined(_SAL_VERSION) + _Check_return_ _CRTIMP __int64 __cdecl _strtoi64( + _In_z_ const char *_String, + _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix); +# else + _CRTIMP __int64 __cdecl _strtoi64(const char *_String, + char **_EndPtr, int _Radix); +# endif +# define strtooff _strtoi64 +# else +# define PRIVATE_STRTOOFF 1 +# endif +# endif +#else +# define strtooff strtol +#endif + +#ifdef PRIVATE_STRTOOFF + +/* Range tests can be used for alphanum decoding if characters are consecutive, + like in ASCII. Else an array is scanned. Determine this condition now. */ + +#if('9' - '0') != 9 || ('Z' - 'A') != 25 || ('z' - 'a') != 25 + +#define NO_RANGE_TEST + +static const char valchars[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +#endif + +static int get_char(char c, int base); + +/** + * Custom version of the strtooff function. This extracts a curl_off_t + * value from the given input string and returns it. + */ +static curl_off_t strtooff(const char *nptr, char **endptr, int base) +{ + char *end; + int is_negative = 0; + int overflow; + int i; + curl_off_t value = 0; + curl_off_t newval; + + /* Skip leading whitespace. */ + end = (char *)nptr; + while(ISSPACE(end[0])) { + end++; + } + + /* Handle the sign, if any. */ + if(end[0] == '-') { + is_negative = 1; + end++; + } + else if(end[0] == '+') { + end++; + } + else if(end[0] == '\0') { + /* We had nothing but perhaps some whitespace -- there was no number. */ + if(endptr) { + *endptr = end; + } + return 0; + } + + /* Handle special beginnings, if present and allowed. */ + if(end[0] == '0' && end[1] == 'x') { + if(base == 16 || base == 0) { + end += 2; + base = 16; + } + } + else if(end[0] == '0') { + if(base == 8 || base == 0) { + end++; + base = 8; + } + } + + /* Matching strtol, if the base is 0 and it doesn't look like + * the number is octal or hex, we assume it's base 10. + */ + if(base == 0) { + base = 10; + } + + /* Loop handling digits. */ + value = 0; + overflow = 0; + for(i = get_char(end[0], base); + i != -1; + end++, i = get_char(end[0], base)) { + newval = base * value + i; + if(newval < value) { + /* We've overflowed. */ + overflow = 1; + break; + } + else + value = newval; + } + + if(!overflow) { + if(is_negative) { + /* Fix the sign. */ + value *= -1; + } + } + else { + if(is_negative) + value = CURL_OFF_T_MIN; + else + value = CURL_OFF_T_MAX; + + errno = ERANGE; + } + + if(endptr) + *endptr = end; + + return value; +} + +/** + * Returns the value of c in the given base, or -1 if c cannot + * be interpreted properly in that base (i.e., is out of range, + * is a null, etc.). + * + * @param c the character to interpret according to base + * @param base the base in which to interpret c + * + * @return the value of c in base, or -1 if c isn't in range + */ +static int get_char(char c, int base) +{ +#ifndef NO_RANGE_TEST + int value = -1; + if(c <= '9' && c >= '0') { + value = c - '0'; + } + else if(c <= 'Z' && c >= 'A') { + value = c - 'A' + 10; + } + else if(c <= 'z' && c >= 'a') { + value = c - 'a' + 10; + } +#else + const char *cp; + int value; + + cp = memchr(valchars, c, 10 + 26 + 26); + + if(!cp) + return -1; + + value = cp - valchars; + + if(value >= 10 + 26) + value -= 26; /* Lowercase. */ +#endif + + if(value >= base) { + value = -1; + } + + return value; +} +#endif /* Only present if we need strtoll, but don't have it. */ + +/* + * Parse a *positive* up to 64 bit number written in ascii. + */ +CURLofft curlx_strtoofft(const char *str, char **endp, int base, + curl_off_t *num) +{ + char *end; + curl_off_t number; + errno = 0; + *num = 0; /* clear by default */ + + while(*str && ISSPACE(*str)) + str++; + if('-' == *str) { + if(endp) + *endp = (char *)str; /* didn't actually move */ + return CURL_OFFT_INVAL; /* nothing parsed */ + } + number = strtooff(str, &end, base); + if(endp) + *endp = end; + if(errno == ERANGE) + /* overflow/underflow */ + return CURL_OFFT_FLOW; + else if(str == end) + /* nothing parsed */ + return CURL_OFFT_INVAL; + + *num = number; + return CURL_OFFT_OK; +} diff --git a/libcurl/lib/strtoofft.h b/libcurl/lib/strtoofft.h new file mode 100644 index 0000000..be19cd7 --- /dev/null +++ b/libcurl/lib/strtoofft.h @@ -0,0 +1,52 @@ +#ifndef HEADER_CURL_STRTOOFFT_H +#define HEADER_CURL_STRTOOFFT_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +/* + * Determine which string to integral data type conversion function we use + * to implement string conversion to our curl_off_t integral data type. + * + * Notice that curl_off_t might be 64 or 32 bit wide, and that it might use + * an underlying data type which might be 'long', 'int64_t', 'long long' or + * '__int64' and more remotely other data types. + * + * On systems where the size of curl_off_t is greater than the size of 'long' + * the conversion function to use is strtoll() if it is available, otherwise, + * we emulate its functionality with our own clone. + * + * On systems where the size of curl_off_t is smaller or equal than the size + * of 'long' the conversion function to use is strtol(). + */ + +typedef enum { + CURL_OFFT_OK, /* parsed fine */ + CURL_OFFT_FLOW, /* over or underflow */ + CURL_OFFT_INVAL /* nothing was parsed */ +} CURLofft; + +CURLofft curlx_strtoofft(const char *str, char **endp, int base, + curl_off_t *num); + +#endif /* HEADER_CURL_STRTOOFFT_H */ diff --git a/libcurl/lib/system_win32.c b/libcurl/lib/system_win32.c new file mode 100644 index 0000000..da3c86c --- /dev/null +++ b/libcurl/lib/system_win32.c @@ -0,0 +1,451 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2016 - 2019, Steve Holme, . + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(WIN32) + +#include +#include "system_win32.h" +#include "curl_sspi.h" +#include "warnless.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +LARGE_INTEGER Curl_freq; +bool Curl_isVistaOrGreater; + +/* Handle of iphlpapp.dll */ +static HMODULE s_hIpHlpApiDll = NULL; + +/* Pointer to the if_nametoindex function */ +IF_NAMETOINDEX_FN Curl_if_nametoindex = NULL; + +/* Curl_win32_init() performs win32 global initialization */ +CURLcode Curl_win32_init(long flags) +{ + /* CURL_GLOBAL_WIN32 controls the *optional* part of the initialization which + is just for Winsock at the moment. Any required win32 initialization + should take place after this block. */ + if(flags & CURL_GLOBAL_WIN32) { +#ifdef USE_WINSOCK + WORD wVersionRequested; + WSADATA wsaData; + int res; + +#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2) +#error IPV6_requires_winsock2 +#endif + + wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK); + + res = WSAStartup(wVersionRequested, &wsaData); + + if(res != 0) + /* Tell the user that we couldn't find a usable */ + /* winsock.dll. */ + return CURLE_FAILED_INIT; + + /* Confirm that the Windows Sockets DLL supports what we need.*/ + /* Note that if the DLL supports versions greater */ + /* than wVersionRequested, it will still return */ + /* wVersionRequested in wVersion. wHighVersion contains the */ + /* highest supported version. */ + + if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || + HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) { + /* Tell the user that we couldn't find a usable */ + + /* winsock.dll. */ + WSACleanup(); + return CURLE_FAILED_INIT; + } + /* The Windows Sockets DLL is acceptable. Proceed. */ + #elif defined(USE_LWIPSOCK) + lwip_init(); + #endif + } /* CURL_GLOBAL_WIN32 */ + +#ifdef USE_WINDOWS_SSPI + { + CURLcode result = Curl_sspi_global_init(); + if(result) + return result; + } +#endif + + #ifdef _XBOX +// Xbox does not support LoadLibrary or GetProcAddress +#else +s_hIpHlpApiDll = Curl_load_library(TEXT("iphlpapi.dll")); +if(s_hIpHlpApiDll) { + /* Get the address of the if_nametoindex function */ + IF_NAMETOINDEX_FN pIfNameToIndex = + CURLX_FUNCTION_CAST(IF_NAMETOINDEX_FN, + (GetProcAddress(s_hIpHlpApiDll, "if_nametoindex"))); + + if(pIfNameToIndex) + Curl_if_nametoindex = pIfNameToIndex; +} +#endif + + if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) { + Curl_isVistaOrGreater = TRUE; + QueryPerformanceFrequency(&Curl_freq); + } + else + Curl_isVistaOrGreater = FALSE; + + return CURLE_OK; +} + +/* Curl_win32_cleanup() is the opposite of Curl_win32_init() */ +void Curl_win32_cleanup(long init_flags) +{ +#ifdef _XBOX + // Xbox does not support FreeLibrary +#else + if(s_hIpHlpApiDll) { + FreeLibrary(s_hIpHlpApiDll); + s_hIpHlpApiDll = NULL; + Curl_if_nametoindex = NULL; + } +#endif + +#ifdef USE_WINDOWS_SSPI + Curl_sspi_global_cleanup(); +#endif + + if(init_flags & CURL_GLOBAL_WIN32) { +#ifdef USE_WINSOCK + WSACleanup(); +#endif + } +} + +#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH) +#define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 +#endif + +#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32) +#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 +#endif + +/* We use our own typedef here since some headers might lack these */ +typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD); + +/* See function definitions in winbase.h */ +#ifdef UNICODE +# ifdef _WIN32_WCE +# define LOADLIBARYEX L"LoadLibraryExW" +# else +# define LOADLIBARYEX "LoadLibraryExW" +# endif +#else +# define LOADLIBARYEX "LoadLibraryExA" +#endif + +/* + * Curl_verify_windows_version() + * + * This is used to verify if we are running on a specific windows version. + * + * Parameters: + * + * majorVersion [in] - The major version number. + * minorVersion [in] - The minor version number. + * platform [in] - The optional platform identifier. + * condition [in] - The test condition used to specifier whether we are + * checking a version less then, equal to or greater than + * what is specified in the major and minor version + * numbers. + * + * Returns TRUE if matched; otherwise FALSE. + */ +bool Curl_verify_windows_version(const unsigned int majorVersion, + const unsigned int minorVersion, + const PlatformIdentifier platform, + const VersionCondition condition) +{ + bool matched = FALSE; + +#if defined(CURL_WINDOWS_APP) + /* We have no way to determine the Windows version from Windows apps, + so let's assume we're running on the target Windows version. */ + /*const WORD fullVersion = MAKEWORD(minorVersion, majorVersion); + const WORD targetVersion = (WORD)_WIN32_WINNT; + + switch(condition) { + case VERSION_LESS_THAN: + matched = targetVersion < fullVersion; + break; + + case VERSION_LESS_THAN_EQUAL: + matched = targetVersion <= fullVersion; + break; + + case VERSION_EQUAL: + matched = targetVersion == fullVersion; + break; + + case VERSION_GREATER_THAN_EQUAL: + matched = targetVersion >= fullVersion; + break; + + case VERSION_GREATER_THAN: + matched = targetVersion > fullVersion; + break; + } + + if(matched && (platform == PLATFORM_WINDOWS)) { + /* we're always running on PLATFORM_WINNT */ + /*matched = FALSE; + }*/ +#elif !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \ + (_WIN32_WINNT < _WIN32_WINNT_WIN2K) + /*OSVERSIONINFO osver; + + memset(&osver, 0, sizeof(osver)); + osver.dwOSVersionInfoSize = sizeof(osver); + + /* Find out Windows version */ + /*if(GetVersionEx(&osver)) { + /* Verify the Operating System version number */ + /*switch(condition) { + case VERSION_LESS_THAN: + if(osver.dwMajorVersion < majorVersion || + (osver.dwMajorVersion == majorVersion && + osver.dwMinorVersion < minorVersion)) + matched = TRUE; + break; + + case VERSION_LESS_THAN_EQUAL: + if(osver.dwMajorVersion < majorVersion || + (osver.dwMajorVersion == majorVersion && + osver.dwMinorVersion <= minorVersion)) + matched = TRUE; + break; + + case VERSION_EQUAL: + if(osver.dwMajorVersion == majorVersion && + osver.dwMinorVersion == minorVersion) + matched = TRUE; + break; + + case VERSION_GREATER_THAN_EQUAL: + if(osver.dwMajorVersion > majorVersion || + (osver.dwMajorVersion == majorVersion && + osver.dwMinorVersion >= minorVersion)) + matched = TRUE; + break; + + case VERSION_GREATER_THAN: + if(osver.dwMajorVersion > majorVersion || + (osver.dwMajorVersion == majorVersion && + osver.dwMinorVersion > minorVersion)) + matched = TRUE; + break; + }*/ + + /* Verify the platform identifier (if necessary) */ + /*if(matched) { + switch(platform) { + case PLATFORM_WINDOWS: + if(osver.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) + matched = FALSE; + break; + + case PLATFORM_WINNT: + if(osver.dwPlatformId != VER_PLATFORM_WIN32_NT) + matched = FALSE; + + default: */ /*like platform == PLATFORM_DONT_CARE */ + /*break; + } + } + }*/ +#else + ULONGLONG cm = 0; + OSVERSIONINFOEX osver; + BYTE majorCondition; + BYTE minorCondition; + BYTE spMajorCondition; + BYTE spMinorCondition; + + switch(condition) { + case VERSION_LESS_THAN: + majorCondition = VER_LESS; + minorCondition = VER_LESS; + spMajorCondition = VER_LESS_EQUAL; + spMinorCondition = VER_LESS_EQUAL; + break; + + case VERSION_LESS_THAN_EQUAL: + majorCondition = VER_LESS_EQUAL; + minorCondition = VER_LESS_EQUAL; + spMajorCondition = VER_LESS_EQUAL; + spMinorCondition = VER_LESS_EQUAL; + break; + + case VERSION_EQUAL: + majorCondition = VER_EQUAL; + minorCondition = VER_EQUAL; + spMajorCondition = VER_GREATER_EQUAL; + spMinorCondition = VER_GREATER_EQUAL; + break; + + case VERSION_GREATER_THAN_EQUAL: + majorCondition = VER_GREATER_EQUAL; + minorCondition = VER_GREATER_EQUAL; + spMajorCondition = VER_GREATER_EQUAL; + spMinorCondition = VER_GREATER_EQUAL; + break; + + case VERSION_GREATER_THAN: + majorCondition = VER_GREATER; + minorCondition = VER_GREATER; + spMajorCondition = VER_GREATER_EQUAL; + spMinorCondition = VER_GREATER_EQUAL; + break; + + default: + return FALSE; + } + + memset(&osver, 0, sizeof(osver)); + osver.dwOSVersionInfoSize = sizeof(osver); + osver.dwMajorVersion = majorVersion; + osver.dwMinorVersion = minorVersion; + if(platform == PLATFORM_WINDOWS) + osver.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS; + else if(platform == PLATFORM_WINNT) + osver.dwPlatformId = VER_PLATFORM_WIN32_NT; + + cm = VerSetConditionMask(cm, VER_MAJORVERSION, majorCondition); + cm = VerSetConditionMask(cm, VER_MINORVERSION, minorCondition); + cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, spMajorCondition); + cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, spMinorCondition); + if(platform != PLATFORM_DONT_CARE) + cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL); + + if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION | + VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR), + cm)) + matched = TRUE; +#endif + + return matched; +} + +/* + * Curl_load_library() + * + * This is used to dynamically load DLLs using the most secure method available + * for the version of Windows that we are running on. + * + * Parameters: + * + * filename [in] - The filename or full path of the DLL to load. If only the + * filename is passed then the DLL will be loaded from the + * Windows system directory. + * + * Returns the handle of the module on success; otherwise NULL. + */ +#ifdef _XBOX +HMODULE Curl_load_library(LPCTSTR filename) { + (void)filename; + return NULL; // Xbox does not support dynamic library loading +} +#else +#ifndef CURL_WINDOWS_APP + HMODULE hModule = NULL; + LOADLIBRARYEX_FN pLoadLibraryEx = NULL; + + /* Get a handle to kernel32 so we can access it's functions at runtime */ + HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32")); + if(!hKernel32) + return NULL; + + /* Attempt to find LoadLibraryEx() which is only available on Windows 2000 + and above */ + pLoadLibraryEx = + CURLX_FUNCTION_CAST(LOADLIBRARYEX_FN, + (GetProcAddress(hKernel32, LOADLIBARYEX))); + + /* Detect if there's already a path in the filename and load the library if + there is. Note: Both back slashes and forward slashes have been supported + since the earlier days of DOS at an API level although they are not + supported by command prompt */ + if(_tcspbrk(filename, TEXT("\\/"))) { + /** !checksrc! disable BANNEDFUNC 1 **/ + hModule = pLoadLibraryEx ? + pLoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : + LoadLibrary(filename); + } + /* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only + supported on Windows Vista, Windows Server 2008, Windows 7 and Windows + Server 2008 R2 with this patch or natively on Windows 8 and above */ + else if(pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) { + /* Load the DLL from the Windows system directory */ + hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); + } + else { + /* Attempt to get the Windows system path */ + #ifdef _XBOX + UINT systemdirlen = 0; // Xbox does not have a system directory + #else + UINT systemdirlen = GetSystemDirectory(NULL, 0); + #endif + if(systemdirlen) { + /* Allocate space for the full DLL path (Room for the null terminator + is included in systemdirlen) */ + size_t filenamelen = _tcslen(filename); + TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen)); + if(path && GetSystemDirectory(path, systemdirlen)) { + /* Calculate the full DLL path */ + _tcscpy(path + _tcslen(path), TEXT("\\")); + _tcscpy(path + _tcslen(path), filename); + + /* Load the DLL from the Windows system directory */ + /** !checksrc! disable BANNEDFUNC 1 **/ + hModule = pLoadLibraryEx ? + pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : + LoadLibrary(path); + + } + free(path); + } + } + return hModule; +#else + /* the Universal Windows Platform (UWP) can't do this */ + (void)filename; + return NULL; +#endif + +} +#endif + +#endif /* WIN32 */ diff --git a/libcurl/lib/system_win32.h b/libcurl/lib/system_win32.h new file mode 100644 index 0000000..d2882fc --- /dev/null +++ b/libcurl/lib/system_win32.h @@ -0,0 +1,68 @@ +#ifndef HEADER_CURL_SYSTEM_WIN32_H +#define HEADER_CURL_SYSTEM_WIN32_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2016 - 2019, Steve Holme, . + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(WIN32) + +extern LARGE_INTEGER Curl_freq; +extern bool Curl_isVistaOrGreater; + +CURLcode Curl_win32_init(long flags); +void Curl_win32_cleanup(long init_flags); + +/* Version condition */ +typedef enum { + VERSION_LESS_THAN, + VERSION_LESS_THAN_EQUAL, + VERSION_EQUAL, + VERSION_GREATER_THAN_EQUAL, + VERSION_GREATER_THAN +} VersionCondition; + +/* Platform identifier */ +typedef enum { + PLATFORM_DONT_CARE, + PLATFORM_WINDOWS, + PLATFORM_WINNT +} PlatformIdentifier; + +/* We use our own typedef here since some headers might lack this */ +typedef unsigned int(WINAPI *IF_NAMETOINDEX_FN)(const char *); + +/* This is used instead of if_nametoindex if available on Windows */ +extern IF_NAMETOINDEX_FN Curl_if_nametoindex; + +/* This is used to verify if we are running on a specific windows version */ +bool Curl_verify_windows_version(const unsigned int majorVersion, + const unsigned int minorVersion, + const PlatformIdentifier platform, + const VersionCondition condition); + +/* This is used to dynamically load DLLs */ +HMODULE Curl_load_library(LPCTSTR filename); + +#endif /* WIN32 */ + +#endif /* HEADER_CURL_SYSTEM_WIN32_H */ diff --git a/libcurl/lib/telnet.c b/libcurl/lib/telnet.c new file mode 100644 index 0000000..955255c --- /dev/null +++ b/libcurl/lib/telnet.c @@ -0,0 +1,1699 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_TELNET + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#include "urldata.h" +#include +#include "transfer.h" +#include "sendf.h" +#include "telnet.h" +#include "connect.h" +#include "progress.h" +#include "system_win32.h" +#include "arpa_telnet.h" +#include "select.h" +#include "strcase.h" +#include "warnless.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#define SUBBUFSIZE 512 + +#define CURL_SB_CLEAR(x) x->subpointer = x->subbuffer +#define CURL_SB_TERM(x) \ + do { \ + x->subend = x->subpointer; \ + CURL_SB_CLEAR(x); \ + } WHILE_FALSE +#define CURL_SB_ACCUM(x,c) \ + do { \ + if(x->subpointer < (x->subbuffer + sizeof(x->subbuffer))) \ + *x->subpointer++ = (c); \ + } WHILE_FALSE + +#define CURL_SB_GET(x) ((*x->subpointer++)&0xff) +#define CURL_SB_LEN(x) (x->subend - x->subpointer) + +/* For posterity: +#define CURL_SB_PEEK(x) ((*x->subpointer)&0xff) +#define CURL_SB_EOF(x) (x->subpointer >= x->subend) */ + +#ifdef CURL_DISABLE_VERBOSE_STRINGS +#define printoption(a,b,c,d) Curl_nop_stmt +#endif + +#ifdef USE_WINSOCK +typedef WSAEVENT (WINAPI *WSOCK2_EVENT)(void); +typedef FARPROC WSOCK2_FUNC; +static CURLcode check_wsock2(struct Curl_easy *data); +#endif + +static +CURLcode telrcv(struct connectdata *, + const unsigned char *inbuf, /* Data received from socket */ + ssize_t count); /* Number of bytes received */ + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static void printoption(struct Curl_easy *data, + const char *direction, + int cmd, int option); +#endif + +static void negotiate(struct connectdata *); +static void send_negotiation(struct connectdata *, int cmd, int option); +static void set_local_option(struct connectdata *conn, + int option, int newstate); +static void set_remote_option(struct connectdata *conn, + int option, int newstate); + +static void printsub(struct Curl_easy *data, + int direction, unsigned char *pointer, + size_t length); +static void suboption(struct connectdata *); +static void sendsuboption(struct connectdata *conn, int option); + +static CURLcode telnet_do(struct connectdata *conn, bool *done); +static CURLcode telnet_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode send_telnet_data(struct connectdata *conn, + char *buffer, ssize_t nread); + +/* For negotiation compliant to RFC 1143 */ +#define CURL_NO 0 +#define CURL_YES 1 +#define CURL_WANTYES 2 +#define CURL_WANTNO 3 + +#define CURL_EMPTY 0 +#define CURL_OPPOSITE 1 + +/* + * Telnet receiver states for fsm + */ +typedef enum +{ + CURL_TS_DATA = 0, + CURL_TS_IAC, + CURL_TS_WILL, + CURL_TS_WONT, + CURL_TS_DO, + CURL_TS_DONT, + CURL_TS_CR, + CURL_TS_SB, /* sub-option collection */ + CURL_TS_SE /* looking for sub-option end */ +} TelnetReceive; + +struct TELNET { + int please_negotiate; + int already_negotiated; + int us[256]; + int usq[256]; + int us_preferred[256]; + int him[256]; + int himq[256]; + int him_preferred[256]; + int subnegotiation[256]; + char subopt_ttype[32]; /* Set with suboption TTYPE */ + char subopt_xdisploc[128]; /* Set with suboption XDISPLOC */ + unsigned short subopt_wsx; /* Set with suboption NAWS */ + unsigned short subopt_wsy; /* Set with suboption NAWS */ + struct curl_slist *telnet_vars; /* Environment variables */ + + /* suboptions */ + unsigned char subbuffer[SUBBUFSIZE]; + unsigned char *subpointer, *subend; /* buffer for sub-options */ + + TelnetReceive telrcv_state; +}; + + +/* + * TELNET protocol handler. + */ + +const struct Curl_handler Curl_handler_telnet = { + "TELNET", /* scheme */ + ZERO_NULL, /* setup_connection */ + telnet_do, /* do_it */ + telnet_done, /* done */ + ZERO_NULL, /* do_more */ + ZERO_NULL, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_TELNET, /* defport */ + CURLPROTO_TELNET, /* protocol */ + PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */ +}; + + +#ifdef USE_WINSOCK +static CURLcode +check_wsock2(struct Curl_easy *data) +{ + int err; + WORD wVersionRequested; + WSADATA wsaData; + + DEBUGASSERT(data); + + /* telnet requires at least WinSock 2.0 so ask for it. */ + wVersionRequested = MAKEWORD(2, 0); + + err = WSAStartup(wVersionRequested, &wsaData); + + /* We must've called this once already, so this call */ + /* should always succeed. But, just in case... */ + if(err != 0) { + failf(data,"WSAStartup failed (%d)",err); + return CURLE_FAILED_INIT; + } + + /* We have to have a WSACleanup call for every successful */ + /* WSAStartup call. */ + WSACleanup(); + + /* Check that our version is supported */ + if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || + HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) { + /* Our version isn't supported */ + failf(data, "insufficient winsock version to support " + "telnet"); + return CURLE_FAILED_INIT; + } + + /* Our version is supported */ + return CURLE_OK; +} +#endif + +static +CURLcode init_telnet(struct connectdata *conn) +{ + struct TELNET *tn; + + tn = calloc(1, sizeof(struct TELNET)); + if(!tn) + return CURLE_OUT_OF_MEMORY; + + conn->data->req.protop = tn; /* make us known */ + + tn->telrcv_state = CURL_TS_DATA; + + /* Init suboptions */ + CURL_SB_CLEAR(tn); + + /* Set the options we want by default */ + tn->us_preferred[CURL_TELOPT_SGA] = CURL_YES; + tn->him_preferred[CURL_TELOPT_SGA] = CURL_YES; + + /* To be compliant with previous releases of libcurl + we enable this option by default. This behaviour + can be changed thanks to the "BINARY" option in + CURLOPT_TELNETOPTIONS + */ + tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES; + tn->him_preferred[CURL_TELOPT_BINARY] = CURL_YES; + + /* We must allow the server to echo what we sent + but it is not necessary to request the server + to do so (it might forces the server to close + the connection). Hence, we ignore ECHO in the + negotiate function + */ + tn->him_preferred[CURL_TELOPT_ECHO] = CURL_YES; + + /* Set the subnegotiation fields to send information + just after negotiation passed (do/will) + + Default values are (0,0) initialized by calloc. + According to the RFC1013 it is valid: + A value equal to zero is acceptable for the width (or height), + and means that no character width (or height) is being sent. + In this case, the width (or height) that will be assumed by the + Telnet server is operating system specific (it will probably be + based upon the terminal type information that may have been sent + using the TERMINAL TYPE Telnet option). */ + tn->subnegotiation[CURL_TELOPT_NAWS] = CURL_YES; + return CURLE_OK; +} + +static void negotiate(struct connectdata *conn) +{ + int i; + struct TELNET *tn = (struct TELNET *) conn->data->req.protop; + + for(i = 0; i < CURL_NTELOPTS; i++) { + if(i == CURL_TELOPT_ECHO) + continue; + + if(tn->us_preferred[i] == CURL_YES) + set_local_option(conn, i, CURL_YES); + + if(tn->him_preferred[i] == CURL_YES) + set_remote_option(conn, i, CURL_YES); + } +} + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static void printoption(struct Curl_easy *data, + const char *direction, int cmd, int option) +{ + if(data->set.verbose) { + if(cmd == CURL_IAC) { + if(CURL_TELCMD_OK(option)) + infof(data, "%s IAC %s\n", direction, CURL_TELCMD(option)); + else + infof(data, "%s IAC %d\n", direction, option); + } + else { + const char *fmt = (cmd == CURL_WILL) ? "WILL" : + (cmd == CURL_WONT) ? "WONT" : + (cmd == CURL_DO) ? "DO" : + (cmd == CURL_DONT) ? "DONT" : 0; + if(fmt) { + const char *opt; + if(CURL_TELOPT_OK(option)) + opt = CURL_TELOPT(option); + else if(option == CURL_TELOPT_EXOPL) + opt = "EXOPL"; + else + opt = NULL; + + if(opt) + infof(data, "%s %s %s\n", direction, fmt, opt); + else + infof(data, "%s %s %d\n", direction, fmt, option); + } + else + infof(data, "%s %d %d\n", direction, cmd, option); + } + } +} +#endif + +static void send_negotiation(struct connectdata *conn, int cmd, int option) +{ + unsigned char buf[3]; + ssize_t bytes_written; + struct Curl_easy *data = conn->data; + + buf[0] = CURL_IAC; + buf[1] = (unsigned char)cmd; + buf[2] = (unsigned char)option; + + bytes_written = swrite(conn->sock[FIRSTSOCKET], buf, 3); + if(bytes_written < 0) { + int err = SOCKERRNO; + failf(data,"Sending data failed (%d)",err); + } + + printoption(conn->data, "SENT", cmd, option); +} + +static +void set_remote_option(struct connectdata *conn, int option, int newstate) +{ + struct TELNET *tn = (struct TELNET *)conn->data->req.protop; + if(newstate == CURL_YES) { + switch(tn->him[option]) { + case CURL_NO: + tn->him[option] = CURL_WANTYES; + send_negotiation(conn, CURL_DO, option); + break; + + case CURL_YES: + /* Already enabled */ + break; + + case CURL_WANTNO: + switch(tn->himq[option]) { + case CURL_EMPTY: + /* Already negotiating for CURL_YES, queue the request */ + tn->himq[option] = CURL_OPPOSITE; + break; + case CURL_OPPOSITE: + /* Error: already queued an enable request */ + break; + } + break; + + case CURL_WANTYES: + switch(tn->himq[option]) { + case CURL_EMPTY: + /* Error: already negotiating for enable */ + break; + case CURL_OPPOSITE: + tn->himq[option] = CURL_EMPTY; + break; + } + break; + } + } + else { /* NO */ + switch(tn->him[option]) { + case CURL_NO: + /* Already disabled */ + break; + + case CURL_YES: + tn->him[option] = CURL_WANTNO; + send_negotiation(conn, CURL_DONT, option); + break; + + case CURL_WANTNO: + switch(tn->himq[option]) { + case CURL_EMPTY: + /* Already negotiating for NO */ + break; + case CURL_OPPOSITE: + tn->himq[option] = CURL_EMPTY; + break; + } + break; + + case CURL_WANTYES: + switch(tn->himq[option]) { + case CURL_EMPTY: + tn->himq[option] = CURL_OPPOSITE; + break; + case CURL_OPPOSITE: + break; + } + break; + } + } +} + +static +void rec_will(struct connectdata *conn, int option) +{ + struct TELNET *tn = (struct TELNET *)conn->data->req.protop; + switch(tn->him[option]) { + case CURL_NO: + if(tn->him_preferred[option] == CURL_YES) { + tn->him[option] = CURL_YES; + send_negotiation(conn, CURL_DO, option); + } + else + send_negotiation(conn, CURL_DONT, option); + + break; + + case CURL_YES: + /* Already enabled */ + break; + + case CURL_WANTNO: + switch(tn->himq[option]) { + case CURL_EMPTY: + /* Error: DONT answered by WILL */ + tn->him[option] = CURL_NO; + break; + case CURL_OPPOSITE: + /* Error: DONT answered by WILL */ + tn->him[option] = CURL_YES; + tn->himq[option] = CURL_EMPTY; + break; + } + break; + + case CURL_WANTYES: + switch(tn->himq[option]) { + case CURL_EMPTY: + tn->him[option] = CURL_YES; + break; + case CURL_OPPOSITE: + tn->him[option] = CURL_WANTNO; + tn->himq[option] = CURL_EMPTY; + send_negotiation(conn, CURL_DONT, option); + break; + } + break; + } +} + +static +void rec_wont(struct connectdata *conn, int option) +{ + struct TELNET *tn = (struct TELNET *)conn->data->req.protop; + switch(tn->him[option]) { + case CURL_NO: + /* Already disabled */ + break; + + case CURL_YES: + tn->him[option] = CURL_NO; + send_negotiation(conn, CURL_DONT, option); + break; + + case CURL_WANTNO: + switch(tn->himq[option]) { + case CURL_EMPTY: + tn->him[option] = CURL_NO; + break; + + case CURL_OPPOSITE: + tn->him[option] = CURL_WANTYES; + tn->himq[option] = CURL_EMPTY; + send_negotiation(conn, CURL_DO, option); + break; + } + break; + + case CURL_WANTYES: + switch(tn->himq[option]) { + case CURL_EMPTY: + tn->him[option] = CURL_NO; + break; + case CURL_OPPOSITE: + tn->him[option] = CURL_NO; + tn->himq[option] = CURL_EMPTY; + break; + } + break; + } +} + +static void +set_local_option(struct connectdata *conn, int option, int newstate) +{ + struct TELNET *tn = (struct TELNET *)conn->data->req.protop; + if(newstate == CURL_YES) { + switch(tn->us[option]) { + case CURL_NO: + tn->us[option] = CURL_WANTYES; + send_negotiation(conn, CURL_WILL, option); + break; + + case CURL_YES: + /* Already enabled */ + break; + + case CURL_WANTNO: + switch(tn->usq[option]) { + case CURL_EMPTY: + /* Already negotiating for CURL_YES, queue the request */ + tn->usq[option] = CURL_OPPOSITE; + break; + case CURL_OPPOSITE: + /* Error: already queued an enable request */ + break; + } + break; + + case CURL_WANTYES: + switch(tn->usq[option]) { + case CURL_EMPTY: + /* Error: already negotiating for enable */ + break; + case CURL_OPPOSITE: + tn->usq[option] = CURL_EMPTY; + break; + } + break; + } + } + else { /* NO */ + switch(tn->us[option]) { + case CURL_NO: + /* Already disabled */ + break; + + case CURL_YES: + tn->us[option] = CURL_WANTNO; + send_negotiation(conn, CURL_WONT, option); + break; + + case CURL_WANTNO: + switch(tn->usq[option]) { + case CURL_EMPTY: + /* Already negotiating for NO */ + break; + case CURL_OPPOSITE: + tn->usq[option] = CURL_EMPTY; + break; + } + break; + + case CURL_WANTYES: + switch(tn->usq[option]) { + case CURL_EMPTY: + tn->usq[option] = CURL_OPPOSITE; + break; + case CURL_OPPOSITE: + break; + } + break; + } + } +} + +static +void rec_do(struct connectdata *conn, int option) +{ + struct TELNET *tn = (struct TELNET *)conn->data->req.protop; + switch(tn->us[option]) { + case CURL_NO: + if(tn->us_preferred[option] == CURL_YES) { + tn->us[option] = CURL_YES; + send_negotiation(conn, CURL_WILL, option); + if(tn->subnegotiation[option] == CURL_YES) + /* transmission of data option */ + sendsuboption(conn, option); + } + else if(tn->subnegotiation[option] == CURL_YES) { + /* send information to achieve this option*/ + tn->us[option] = CURL_YES; + send_negotiation(conn, CURL_WILL, option); + sendsuboption(conn, option); + } + else + send_negotiation(conn, CURL_WONT, option); + break; + + case CURL_YES: + /* Already enabled */ + break; + + case CURL_WANTNO: + switch(tn->usq[option]) { + case CURL_EMPTY: + /* Error: DONT answered by WILL */ + tn->us[option] = CURL_NO; + break; + case CURL_OPPOSITE: + /* Error: DONT answered by WILL */ + tn->us[option] = CURL_YES; + tn->usq[option] = CURL_EMPTY; + break; + } + break; + + case CURL_WANTYES: + switch(tn->usq[option]) { + case CURL_EMPTY: + tn->us[option] = CURL_YES; + if(tn->subnegotiation[option] == CURL_YES) { + /* transmission of data option */ + sendsuboption(conn, option); + } + break; + case CURL_OPPOSITE: + tn->us[option] = CURL_WANTNO; + tn->himq[option] = CURL_EMPTY; + send_negotiation(conn, CURL_WONT, option); + break; + } + break; + } +} + +static +void rec_dont(struct connectdata *conn, int option) +{ + struct TELNET *tn = (struct TELNET *)conn->data->req.protop; + switch(tn->us[option]) { + case CURL_NO: + /* Already disabled */ + break; + + case CURL_YES: + tn->us[option] = CURL_NO; + send_negotiation(conn, CURL_WONT, option); + break; + + case CURL_WANTNO: + switch(tn->usq[option]) { + case CURL_EMPTY: + tn->us[option] = CURL_NO; + break; + + case CURL_OPPOSITE: + tn->us[option] = CURL_WANTYES; + tn->usq[option] = CURL_EMPTY; + send_negotiation(conn, CURL_WILL, option); + break; + } + break; + + case CURL_WANTYES: + switch(tn->usq[option]) { + case CURL_EMPTY: + tn->us[option] = CURL_NO; + break; + case CURL_OPPOSITE: + tn->us[option] = CURL_NO; + tn->usq[option] = CURL_EMPTY; + break; + } + break; + } +} + + +static void printsub(struct Curl_easy *data, + int direction, /* '<' or '>' */ + unsigned char *pointer, /* where suboption data is */ + size_t length) /* length of suboption data */ +{ + if(data->set.verbose) { + unsigned int i = 0; + if(direction) { + infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT"); + if(length >= 3) { + int j; + + i = pointer[length-2]; + j = pointer[length-1]; + + if(i != CURL_IAC || j != CURL_SE) { + infof(data, "(terminated by "); + if(CURL_TELOPT_OK(i)) + infof(data, "%s ", CURL_TELOPT(i)); + else if(CURL_TELCMD_OK(i)) + infof(data, "%s ", CURL_TELCMD(i)); + else + infof(data, "%u ", i); + if(CURL_TELOPT_OK(j)) + infof(data, "%s", CURL_TELOPT(j)); + else if(CURL_TELCMD_OK(j)) + infof(data, "%s", CURL_TELCMD(j)); + else + infof(data, "%d", j); + infof(data, ", not IAC SE!) "); + } + } + length -= 2; + } + if(length < 1) { + infof(data, "(Empty suboption?)"); + return; + } + + if(CURL_TELOPT_OK(pointer[0])) { + switch(pointer[0]) { + case CURL_TELOPT_TTYPE: + case CURL_TELOPT_XDISPLOC: + case CURL_TELOPT_NEW_ENVIRON: + case CURL_TELOPT_NAWS: + infof(data, "%s", CURL_TELOPT(pointer[0])); + break; + default: + infof(data, "%s (unsupported)", CURL_TELOPT(pointer[0])); + break; + } + } + else + infof(data, "%d (unknown)", pointer[i]); + + switch(pointer[0]) { + case CURL_TELOPT_NAWS: + if(length > 4) + infof(data, "Width: %d ; Height: %d", (pointer[1]<<8) | pointer[2], + (pointer[3]<<8) | pointer[4]); + break; + default: + switch(pointer[1]) { + case CURL_TELQUAL_IS: + infof(data, " IS"); + break; + case CURL_TELQUAL_SEND: + infof(data, " SEND"); + break; + case CURL_TELQUAL_INFO: + infof(data, " INFO/REPLY"); + break; + case CURL_TELQUAL_NAME: + infof(data, " NAME"); + break; + } + + switch(pointer[0]) { + case CURL_TELOPT_TTYPE: + case CURL_TELOPT_XDISPLOC: + pointer[length] = 0; + infof(data, " \"%s\"", &pointer[2]); + break; + case CURL_TELOPT_NEW_ENVIRON: + if(pointer[1] == CURL_TELQUAL_IS) { + infof(data, " "); + for(i = 3; i < length; i++) { + switch(pointer[i]) { + case CURL_NEW_ENV_VAR: + infof(data, ", "); + break; + case CURL_NEW_ENV_VALUE: + infof(data, " = "); + break; + default: + infof(data, "%c", pointer[i]); + break; + } + } + } + break; + default: + for(i = 2; i < length; i++) + infof(data, " %.2x", pointer[i]); + break; + } + } + if(direction) + infof(data, "\n"); + } +} + +static CURLcode check_telnet_options(struct connectdata *conn) +{ + struct curl_slist *head; + struct curl_slist *beg; + char option_keyword[128] = ""; + char option_arg[256] = ""; + struct Curl_easy *data = conn->data; + struct TELNET *tn = (struct TELNET *)conn->data->req.protop; + CURLcode result = CURLE_OK; + int binary_option; + + /* Add the user name as an environment variable if it + was given on the command line */ + if(conn->bits.user_passwd) { + msnprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user); + beg = curl_slist_append(tn->telnet_vars, option_arg); + if(!beg) { + curl_slist_free_all(tn->telnet_vars); + tn->telnet_vars = NULL; + return CURLE_OUT_OF_MEMORY; + } + tn->telnet_vars = beg; + tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES; + } + + for(head = data->set.telnet_options; head; head = head->next) { + if(sscanf(head->data, "%127[^= ]%*[ =]%255s", + option_keyword, option_arg) == 2) { + + /* Terminal type */ + if(strcasecompare(option_keyword, "TTYPE")) { + strncpy(tn->subopt_ttype, option_arg, 31); + tn->subopt_ttype[31] = 0; /* String termination */ + tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES; + continue; + } + + /* Display variable */ + if(strcasecompare(option_keyword, "XDISPLOC")) { + strncpy(tn->subopt_xdisploc, option_arg, 127); + tn->subopt_xdisploc[127] = 0; /* String termination */ + tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES; + continue; + } + + /* Environment variable */ + if(strcasecompare(option_keyword, "NEW_ENV")) { + beg = curl_slist_append(tn->telnet_vars, option_arg); + if(!beg) { + result = CURLE_OUT_OF_MEMORY; + break; + } + tn->telnet_vars = beg; + tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES; + continue; + } + + /* Window Size */ + if(strcasecompare(option_keyword, "WS")) { + if(sscanf(option_arg, "%hu%*[xX]%hu", + &tn->subopt_wsx, &tn->subopt_wsy) == 2) + tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES; + else { + failf(data, "Syntax error in telnet option: %s", head->data); + result = CURLE_TELNET_OPTION_SYNTAX; + break; + } + continue; + } + + /* To take care or not of the 8th bit in data exchange */ + if(strcasecompare(option_keyword, "BINARY")) { + binary_option = atoi(option_arg); + if(binary_option != 1) { + tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO; + tn->him_preferred[CURL_TELOPT_BINARY] = CURL_NO; + } + continue; + } + + failf(data, "Unknown telnet option %s", head->data); + result = CURLE_UNKNOWN_OPTION; + break; + } + failf(data, "Syntax error in telnet option: %s", head->data); + result = CURLE_TELNET_OPTION_SYNTAX; + break; + } + + if(result) { + curl_slist_free_all(tn->telnet_vars); + tn->telnet_vars = NULL; + } + + return result; +} + +/* + * suboption() + * + * Look at the sub-option buffer, and try to be helpful to the other + * side. + */ + +static void suboption(struct connectdata *conn) +{ + struct curl_slist *v; + unsigned char temp[2048]; + ssize_t bytes_written; + size_t len; + int err; + char varname[128] = ""; + char varval[128] = ""; + struct Curl_easy *data = conn->data; + struct TELNET *tn = (struct TELNET *)data->req.protop; + + printsub(data, '<', (unsigned char *)tn->subbuffer, CURL_SB_LEN(tn) + 2); + switch(CURL_SB_GET(tn)) { + case CURL_TELOPT_TTYPE: + len = strlen(tn->subopt_ttype) + 4 + 2; + msnprintf((char *)temp, sizeof(temp), + "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE, + CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, CURL_SE); + bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len); + if(bytes_written < 0) { + err = SOCKERRNO; + failf(data,"Sending data failed (%d)",err); + } + printsub(data, '>', &temp[2], len-2); + break; + case CURL_TELOPT_XDISPLOC: + len = strlen(tn->subopt_xdisploc) + 4 + 2; + msnprintf((char *)temp, sizeof(temp), + "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC, + CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, CURL_SE); + bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len); + if(bytes_written < 0) { + err = SOCKERRNO; + failf(data,"Sending data failed (%d)",err); + } + printsub(data, '>', &temp[2], len-2); + break; + case CURL_TELOPT_NEW_ENVIRON: + msnprintf((char *)temp, sizeof(temp), + "%c%c%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_NEW_ENVIRON, + CURL_TELQUAL_IS); + len = 4; + + for(v = tn->telnet_vars; v; v = v->next) { + size_t tmplen = (strlen(v->data) + 1); + /* Add the variable only if it fits */ + if(len + tmplen < (int)sizeof(temp)-6) { + if(sscanf(v->data, "%127[^,],%127s", varname, varval)) { + msnprintf((char *)&temp[len], sizeof(temp) - len, + "%c%s%c%s", CURL_NEW_ENV_VAR, varname, + CURL_NEW_ENV_VALUE, varval); + len += tmplen; + } + } + } + msnprintf((char *)&temp[len], sizeof(temp) - len, + "%c%c", CURL_IAC, CURL_SE); + len += 2; + bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len); + if(bytes_written < 0) { + err = SOCKERRNO; + failf(data,"Sending data failed (%d)",err); + } + printsub(data, '>', &temp[2], len-2); + break; + } + return; +} + + +/* + * sendsuboption() + * + * Send suboption information to the server side. + */ + +static void sendsuboption(struct connectdata *conn, int option) +{ + ssize_t bytes_written; + int err; + unsigned short x, y; + unsigned char *uc1, *uc2; + + struct Curl_easy *data = conn->data; + struct TELNET *tn = (struct TELNET *)data->req.protop; + + switch(option) { + case CURL_TELOPT_NAWS: + /* We prepare data to be sent */ + CURL_SB_CLEAR(tn); + CURL_SB_ACCUM(tn, CURL_IAC); + CURL_SB_ACCUM(tn, CURL_SB); + CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS); + /* We must deal either with little or big endian processors */ + /* Window size must be sent according to the 'network order' */ + x = htons(tn->subopt_wsx); + y = htons(tn->subopt_wsy); + uc1 = (unsigned char *)&x; + uc2 = (unsigned char *)&y; + CURL_SB_ACCUM(tn, uc1[0]); + CURL_SB_ACCUM(tn, uc1[1]); + CURL_SB_ACCUM(tn, uc2[0]); + CURL_SB_ACCUM(tn, uc2[1]); + + CURL_SB_ACCUM(tn, CURL_IAC); + CURL_SB_ACCUM(tn, CURL_SE); + CURL_SB_TERM(tn); + /* data suboption is now ready */ + + printsub(data, '>', (unsigned char *)tn->subbuffer + 2, + CURL_SB_LEN(tn)-2); + + /* we send the header of the suboption... */ + bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer, 3); + if(bytes_written < 0) { + err = SOCKERRNO; + failf(data, "Sending data failed (%d)", err); + } + /* ... then the window size with the send_telnet_data() function + to deal with 0xFF cases ... */ + send_telnet_data(conn, (char *)tn->subbuffer + 3, 4); + /* ... and the footer */ + bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer + 7, 2); + if(bytes_written < 0) { + err = SOCKERRNO; + failf(data, "Sending data failed (%d)", err); + } + break; + } +} + + +static +CURLcode telrcv(struct connectdata *conn, + const unsigned char *inbuf, /* Data received from socket */ + ssize_t count) /* Number of bytes received */ +{ + unsigned char c; + CURLcode result; + int in = 0; + int startwrite = -1; + struct Curl_easy *data = conn->data; + struct TELNET *tn = (struct TELNET *)data->req.protop; + +#define startskipping() \ + if(startwrite >= 0) { \ + result = Curl_client_write(conn, \ + CLIENTWRITE_BODY, \ + (char *)&inbuf[startwrite], \ + in-startwrite); \ + if(result) \ + return result; \ + } \ + startwrite = -1 + +#define writebyte() \ + if(startwrite < 0) \ + startwrite = in + +#define bufferflush() startskipping() + + while(count--) { + c = inbuf[in]; + + switch(tn->telrcv_state) { + case CURL_TS_CR: + tn->telrcv_state = CURL_TS_DATA; + if(c == '\0') { + startskipping(); + break; /* Ignore \0 after CR */ + } + writebyte(); + break; + + case CURL_TS_DATA: + if(c == CURL_IAC) { + tn->telrcv_state = CURL_TS_IAC; + startskipping(); + break; + } + else if(c == '\r') + tn->telrcv_state = CURL_TS_CR; + writebyte(); + break; + + case CURL_TS_IAC: + process_iac: + DEBUGASSERT(startwrite < 0); + switch(c) { + case CURL_WILL: + tn->telrcv_state = CURL_TS_WILL; + break; + case CURL_WONT: + tn->telrcv_state = CURL_TS_WONT; + break; + case CURL_DO: + tn->telrcv_state = CURL_TS_DO; + break; + case CURL_DONT: + tn->telrcv_state = CURL_TS_DONT; + break; + case CURL_SB: + CURL_SB_CLEAR(tn); + tn->telrcv_state = CURL_TS_SB; + break; + case CURL_IAC: + tn->telrcv_state = CURL_TS_DATA; + writebyte(); + break; + case CURL_DM: + case CURL_NOP: + case CURL_GA: + default: + tn->telrcv_state = CURL_TS_DATA; + printoption(data, "RCVD", CURL_IAC, c); + break; + } + break; + + case CURL_TS_WILL: + printoption(data, "RCVD", CURL_WILL, c); + tn->please_negotiate = 1; + rec_will(conn, c); + tn->telrcv_state = CURL_TS_DATA; + break; + + case CURL_TS_WONT: + printoption(data, "RCVD", CURL_WONT, c); + tn->please_negotiate = 1; + rec_wont(conn, c); + tn->telrcv_state = CURL_TS_DATA; + break; + + case CURL_TS_DO: + printoption(data, "RCVD", CURL_DO, c); + tn->please_negotiate = 1; + rec_do(conn, c); + tn->telrcv_state = CURL_TS_DATA; + break; + + case CURL_TS_DONT: + printoption(data, "RCVD", CURL_DONT, c); + tn->please_negotiate = 1; + rec_dont(conn, c); + tn->telrcv_state = CURL_TS_DATA; + break; + + case CURL_TS_SB: + if(c == CURL_IAC) + tn->telrcv_state = CURL_TS_SE; + else + CURL_SB_ACCUM(tn, c); + break; + + case CURL_TS_SE: + if(c != CURL_SE) { + if(c != CURL_IAC) { + /* + * This is an error. We only expect to get "IAC IAC" or "IAC SE". + * Several things may have happened. An IAC was not doubled, the + * IAC SE was left off, or another option got inserted into the + * suboption are all possibilities. If we assume that the IAC was + * not doubled, and really the IAC SE was left off, we could get + * into an infinite loop here. So, instead, we terminate the + * suboption, and process the partial suboption if we can. + */ + CURL_SB_ACCUM(tn, CURL_IAC); + CURL_SB_ACCUM(tn, c); + tn->subpointer -= 2; + CURL_SB_TERM(tn); + + printoption(data, "In SUBOPTION processing, RCVD", CURL_IAC, c); + suboption(conn); /* handle sub-option */ + tn->telrcv_state = CURL_TS_IAC; + goto process_iac; + } + CURL_SB_ACCUM(tn, c); + tn->telrcv_state = CURL_TS_SB; + } + else { + CURL_SB_ACCUM(tn, CURL_IAC); + CURL_SB_ACCUM(tn, CURL_SE); + tn->subpointer -= 2; + CURL_SB_TERM(tn); + suboption(conn); /* handle sub-option */ + tn->telrcv_state = CURL_TS_DATA; + } + break; + } + ++in; + } + bufferflush(); + return CURLE_OK; +} + +/* Escape and send a telnet data block */ +static CURLcode send_telnet_data(struct connectdata *conn, + char *buffer, ssize_t nread) +{ + ssize_t escapes, i, outlen; + unsigned char *outbuf = NULL; + CURLcode result = CURLE_OK; + ssize_t bytes_written, total_written; + + /* Determine size of new buffer after escaping */ + escapes = 0; + for(i = 0; i < nread; i++) + if((unsigned char)buffer[i] == CURL_IAC) + escapes++; + outlen = nread + escapes; + + if(outlen == nread) + outbuf = (unsigned char *)buffer; + else { + ssize_t j; + outbuf = malloc(nread + escapes + 1); + if(!outbuf) + return CURLE_OUT_OF_MEMORY; + + j = 0; + for(i = 0; i < nread; i++) { + outbuf[j++] = buffer[i]; + if((unsigned char)buffer[i] == CURL_IAC) + outbuf[j++] = CURL_IAC; + } + outbuf[j] = '\0'; + } + + total_written = 0; + while(!result && total_written < outlen) { + /* Make sure socket is writable to avoid EWOULDBLOCK condition */ + struct pollfd pfd[1]; + pfd[0].fd = conn->sock[FIRSTSOCKET]; + pfd[0].events = POLLOUT; + switch(Curl_poll(pfd, 1, -1)) { + case -1: /* error, abort writing */ + case 0: /* timeout (will never happen) */ + result = CURLE_SEND_ERROR; + break; + default: /* write! */ + bytes_written = 0; + result = Curl_write(conn, conn->sock[FIRSTSOCKET], + outbuf + total_written, + outlen - total_written, + &bytes_written); + total_written += bytes_written; + break; + } + } + + /* Free malloc copy if escaped */ + if(outbuf != (unsigned char *)buffer) + free(outbuf); + + return result; +} + +static CURLcode telnet_done(struct connectdata *conn, + CURLcode status, bool premature) +{ + struct TELNET *tn = (struct TELNET *)conn->data->req.protop; + (void)status; /* unused */ + (void)premature; /* not used */ + + if(!tn) + return CURLE_OK; + + curl_slist_free_all(tn->telnet_vars); + tn->telnet_vars = NULL; + + Curl_safefree(conn->data->req.protop); + + return CURLE_OK; +} + +static CURLcode telnet_do(struct connectdata *conn, bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; +#ifdef USE_WINSOCK + HMODULE wsock2; + WSOCK2_FUNC close_event_func; + WSOCK2_EVENT create_event_func; + WSOCK2_FUNC event_select_func; + WSOCK2_FUNC enum_netevents_func; + WSAEVENT event_handle; + WSANETWORKEVENTS events; + HANDLE stdin_handle; + HANDLE objs[2]; + DWORD obj_count; + DWORD wait_timeout; + DWORD readfile_read; + int err; +#else + int interval_ms; + struct pollfd pfd[2]; + int poll_cnt; + curl_off_t total_dl = 0; + curl_off_t total_ul = 0; +#endif + ssize_t nread; + struct curltime now; + bool keepon = TRUE; + char *buf = data->state.buffer; + struct TELNET *tn; + + *done = TRUE; /* unconditionally */ + + result = init_telnet(conn); + if(result) + return result; + + tn = (struct TELNET *)data->req.protop; + + result = check_telnet_options(conn); + if(result) + return result; + +#ifdef USE_WINSOCK + /* + ** This functionality only works with WinSock >= 2.0. So, + ** make sure we have it. + */ + result = check_wsock2(data); + if(result) + return result; + + /* OK, so we have WinSock 2.0. We need to dynamically */ + /* load ws2_32.dll and get the function pointers we need. */ + wsock2 = Curl_load_library(TEXT("WS2_32.DLL")); + if(wsock2 == NULL) { + failf(data, "failed to load WS2_32.DLL (%u)", GetLastError()); + return CURLE_FAILED_INIT; + } + + /* Grab a pointer to WSACreateEvent */ + create_event_func = + CURLX_FUNCTION_CAST(WSOCK2_EVENT, + (GetProcAddress(wsock2, "WSACreateEvent"))); + if(create_event_func == NULL) { + failf(data, "failed to find WSACreateEvent function (%u)", GetLastError()); + FreeLibrary(wsock2); + return CURLE_FAILED_INIT; + } + + /* And WSACloseEvent */ + close_event_func = GetProcAddress(wsock2, "WSACloseEvent"); + if(close_event_func == NULL) { + failf(data, "failed to find WSACloseEvent function (%u)", GetLastError()); + FreeLibrary(wsock2); + return CURLE_FAILED_INIT; + } + + /* And WSAEventSelect */ + event_select_func = GetProcAddress(wsock2, "WSAEventSelect"); + if(event_select_func == NULL) { + failf(data, "failed to find WSAEventSelect function (%u)", GetLastError()); + FreeLibrary(wsock2); + return CURLE_FAILED_INIT; + } + + /* And WSAEnumNetworkEvents */ + enum_netevents_func = GetProcAddress(wsock2, "WSAEnumNetworkEvents"); + if(enum_netevents_func == NULL) { + failf(data, "failed to find WSAEnumNetworkEvents function (%u)", + GetLastError()); + FreeLibrary(wsock2); + return CURLE_FAILED_INIT; + } + + /* We want to wait for both stdin and the socket. Since + ** the select() function in winsock only works on sockets + ** we have to use the WaitForMultipleObjects() call. + */ + + /* First, create a sockets event object */ + event_handle = (WSAEVENT)create_event_func(); + if(event_handle == WSA_INVALID_EVENT) { + failf(data, "WSACreateEvent failed (%d)", SOCKERRNO); + FreeLibrary(wsock2); + return CURLE_FAILED_INIT; + } + + /* Tell winsock what events we want to listen to */ + if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) == + SOCKET_ERROR) { + close_event_func(event_handle); + FreeLibrary(wsock2); + return CURLE_OK; + } + + /* The get the Windows file handle for stdin */ + stdin_handle = GetStdHandle(STD_INPUT_HANDLE); + + /* Create the list of objects to wait for */ + objs[0] = event_handle; + objs[1] = stdin_handle; + + /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it, + else use the old WaitForMultipleObjects() way */ + if(GetFileType(stdin_handle) == FILE_TYPE_PIPE || + data->set.is_fread_set) { + /* Don't wait for stdin_handle, just wait for event_handle */ + obj_count = 1; + /* Check stdin_handle per 100 milliseconds */ + wait_timeout = 100; + } + else { + obj_count = 2; + wait_timeout = 1000; + } + + /* Keep on listening and act on events */ + while(keepon) { + const DWORD buf_size = (DWORD)data->set.buffer_size; + DWORD waitret = WaitForMultipleObjects(obj_count, objs, + FALSE, wait_timeout); + switch(waitret) { + case WAIT_TIMEOUT: + { + for(;;) { + if(data->set.is_fread_set) { + size_t n; + /* read from user-supplied method */ + n = data->state.fread_func(buf, 1, buf_size, data->state.in); + if(n == CURL_READFUNC_ABORT) { + keepon = FALSE; + result = CURLE_READ_ERROR; + break; + } + + if(n == CURL_READFUNC_PAUSE) + break; + + if(n == 0) /* no bytes */ + break; + + /* fall through with number of bytes read */ + readfile_read = (DWORD)n; + } + else { + /* read from stdin */ + if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL, + &readfile_read, NULL)) { + keepon = FALSE; + result = CURLE_READ_ERROR; + break; + } + + if(!readfile_read) + break; + + if(!ReadFile(stdin_handle, buf, buf_size, + &readfile_read, NULL)) { + keepon = FALSE; + result = CURLE_READ_ERROR; + break; + } + } + + result = send_telnet_data(conn, buf, readfile_read); + if(result) { + keepon = FALSE; + break; + } + } + } + break; + + case WAIT_OBJECT_0 + 1: + { + if(!ReadFile(stdin_handle, buf, buf_size, + &readfile_read, NULL)) { + keepon = FALSE; + result = CURLE_READ_ERROR; + break; + } + + result = send_telnet_data(conn, buf, readfile_read); + if(result) { + keepon = FALSE; + break; + } + } + break; + + case WAIT_OBJECT_0: + + events.lNetworkEvents = 0; + if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) { + err = SOCKERRNO; + if(err != EINPROGRESS) { + infof(data, "WSAEnumNetworkEvents failed (%d)", err); + keepon = FALSE; + result = CURLE_READ_ERROR; + } + break; + } + if(events.lNetworkEvents & FD_READ) { + /* read data from network */ + result = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread); + /* read would've blocked. Loop again */ + if(result == CURLE_AGAIN) + break; + /* returned not-zero, this an error */ + else if(result) { + keepon = FALSE; + break; + } + /* returned zero but actually received 0 or less here, + the server closed the connection and we bail out */ + else if(nread <= 0) { + keepon = FALSE; + break; + } + + result = telrcv(conn, (unsigned char *) buf, nread); + if(result) { + keepon = FALSE; + break; + } + + /* Negotiate if the peer has started negotiating, + otherwise don't. We don't want to speak telnet with + non-telnet servers, like POP or SMTP. */ + if(tn->please_negotiate && !tn->already_negotiated) { + negotiate(conn); + tn->already_negotiated = 1; + } + } + if(events.lNetworkEvents & FD_CLOSE) { + keepon = FALSE; + } + break; + + } + + if(data->set.timeout) { + now = Curl_now(); + if(Curl_timediff(now, conn->created) >= data->set.timeout) { + failf(data, "Time-out"); + result = CURLE_OPERATION_TIMEDOUT; + keepon = FALSE; + } + } + } + + /* We called WSACreateEvent, so call WSACloseEvent */ + if(!close_event_func(event_handle)) { + infof(data, "WSACloseEvent failed (%d)", SOCKERRNO); + } + + /* "Forget" pointers into the library we're about to free */ + create_event_func = NULL; + close_event_func = NULL; + event_select_func = NULL; + enum_netevents_func = NULL; + + /* We called LoadLibrary, so call FreeLibrary */ + if(!FreeLibrary(wsock2)) + infof(data, "FreeLibrary(wsock2) failed (%u)", GetLastError()); +#else + pfd[0].fd = sockfd; + pfd[0].events = POLLIN; + + if(data->set.is_fread_set) { + poll_cnt = 1; + interval_ms = 100; /* poll user-supplied read function */ + } + else { + /* really using fread, so infile is a FILE* */ + pfd[1].fd = fileno((FILE *)data->state.in); + pfd[1].events = POLLIN; + poll_cnt = 2; + interval_ms = 1 * 1000; + } + + while(keepon) { + switch(Curl_poll(pfd, poll_cnt, interval_ms)) { + case -1: /* error, stop reading */ + keepon = FALSE; + continue; + case 0: /* timeout */ + pfd[0].revents = 0; + pfd[1].revents = 0; + /* FALLTHROUGH */ + default: /* read! */ + if(pfd[0].revents & POLLIN) { + /* read data from network */ + result = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread); + /* read would've blocked. Loop again */ + if(result == CURLE_AGAIN) + break; + /* returned not-zero, this an error */ + if(result) { + keepon = FALSE; + break; + } + /* returned zero but actually received 0 or less here, + the server closed the connection and we bail out */ + else if(nread <= 0) { + keepon = FALSE; + break; + } + + total_dl += nread; + Curl_pgrsSetDownloadCounter(data, total_dl); + result = telrcv(conn, (unsigned char *)buf, nread); + if(result) { + keepon = FALSE; + break; + } + + /* Negotiate if the peer has started negotiating, + otherwise don't. We don't want to speak telnet with + non-telnet servers, like POP or SMTP. */ + if(tn->please_negotiate && !tn->already_negotiated) { + negotiate(conn); + tn->already_negotiated = 1; + } + } + + nread = 0; + if(poll_cnt == 2) { + if(pfd[1].revents & POLLIN) { /* read from in file */ + nread = read(pfd[1].fd, buf, data->set.buffer_size); + } + } + else { + /* read from user-supplied method */ + nread = (int)data->state.fread_func(buf, 1, data->set.buffer_size, + data->state.in); + if(nread == CURL_READFUNC_ABORT) { + keepon = FALSE; + break; + } + if(nread == CURL_READFUNC_PAUSE) + break; + } + + if(nread > 0) { + result = send_telnet_data(conn, buf, nread); + if(result) { + keepon = FALSE; + break; + } + total_ul += nread; + Curl_pgrsSetUploadCounter(data, total_ul); + } + else if(nread < 0) + keepon = FALSE; + + break; + } /* poll switch statement */ + + if(data->set.timeout) { + now = Curl_now(); + if(Curl_timediff(now, conn->created) >= data->set.timeout) { + failf(data, "Time-out"); + result = CURLE_OPERATION_TIMEDOUT; + keepon = FALSE; + } + } + + if(Curl_pgrsUpdate(conn)) { + result = CURLE_ABORTED_BY_CALLBACK; + break; + } + } +#endif + /* mark this as "no further transfer wanted" */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + + return result; +} +#endif diff --git a/libcurl/lib/telnet.h b/libcurl/lib/telnet.h new file mode 100644 index 0000000..668a78a --- /dev/null +++ b/libcurl/lib/telnet.h @@ -0,0 +1,28 @@ +#ifndef HEADER_CURL_TELNET_H +#define HEADER_CURL_TELNET_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifndef CURL_DISABLE_TELNET +extern const struct Curl_handler Curl_handler_telnet; +#endif + +#endif /* HEADER_CURL_TELNET_H */ diff --git a/libcurl/lib/tftp.c b/libcurl/lib/tftp.c new file mode 100644 index 0000000..289cda2 --- /dev/null +++ b/libcurl/lib/tftp.c @@ -0,0 +1,1410 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_TFTP + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#include "urldata.h" +#include +#include "transfer.h" +#include "sendf.h" +#include "tftp.h" +#include "progress.h" +#include "connect.h" +#include "strerror.h" +#include "sockaddr.h" /* required for Curl_sockaddr_storage */ +#include "multiif.h" +#include "url.h" +#include "strcase.h" +#include "speedcheck.h" +#include "select.h" +#include "escape.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* RFC2348 allows the block size to be negotiated */ +#define TFTP_BLKSIZE_DEFAULT 512 +#define TFTP_BLKSIZE_MIN 8 +#define TFTP_BLKSIZE_MAX 65464 +#define TFTP_OPTION_BLKSIZE "blksize" + +/* from RFC2349: */ +#define TFTP_OPTION_TSIZE "tsize" +#define TFTP_OPTION_INTERVAL "timeout" + +typedef enum { + TFTP_MODE_NETASCII = 0, + TFTP_MODE_OCTET +} tftp_mode_t; + +typedef enum { + TFTP_STATE_START = 0, + TFTP_STATE_RX, + TFTP_STATE_TX, + TFTP_STATE_FIN +} tftp_state_t; + +typedef enum { + TFTP_EVENT_NONE = -1, + TFTP_EVENT_INIT = 0, + TFTP_EVENT_RRQ = 1, + TFTP_EVENT_WRQ = 2, + TFTP_EVENT_DATA = 3, + TFTP_EVENT_ACK = 4, + TFTP_EVENT_ERROR = 5, + TFTP_EVENT_OACK = 6, + TFTP_EVENT_TIMEOUT +} tftp_event_t; + +typedef enum { + TFTP_ERR_UNDEF = 0, + TFTP_ERR_NOTFOUND, + TFTP_ERR_PERM, + TFTP_ERR_DISKFULL, + TFTP_ERR_ILLEGAL, + TFTP_ERR_UNKNOWNID, + TFTP_ERR_EXISTS, + TFTP_ERR_NOSUCHUSER, /* This will never be triggered by this code */ + + /* The remaining error codes are internal to curl */ + TFTP_ERR_NONE = -100, + TFTP_ERR_TIMEOUT, + TFTP_ERR_NORESPONSE +} tftp_error_t; + +typedef struct tftp_packet { + unsigned char *data; +} tftp_packet_t; + +typedef struct tftp_state_data { + tftp_state_t state; + tftp_mode_t mode; + tftp_error_t error; + tftp_event_t event; + struct connectdata *conn; + curl_socket_t sockfd; + int retries; + int retry_time; + int retry_max; + time_t start_time; + time_t max_time; + time_t rx_time; + unsigned short block; + struct Curl_sockaddr_storage local_addr; + struct Curl_sockaddr_storage remote_addr; + curl_socklen_t remote_addrlen; + int rbytes; + int sbytes; + int blksize; + int requested_blksize; + tftp_packet_t rpacket; + tftp_packet_t spacket; +} tftp_state_data_t; + + +/* Forward declarations */ +static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event); +static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event); +static CURLcode tftp_connect(struct connectdata *conn, bool *done); +static CURLcode tftp_disconnect(struct connectdata *conn, + bool dead_connection); +static CURLcode tftp_do(struct connectdata *conn, bool *done); +static CURLcode tftp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode tftp_setup_connection(struct connectdata * conn); +static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done); +static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done); +static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); +static CURLcode tftp_translate_code(tftp_error_t error); + + +/* + * TFTP protocol handler. + */ + +const struct Curl_handler Curl_handler_tftp = { + "TFTP", /* scheme */ + tftp_setup_connection, /* setup_connection */ + tftp_do, /* do_it */ + tftp_done, /* done */ + ZERO_NULL, /* do_more */ + tftp_connect, /* connect_it */ + tftp_multi_statemach, /* connecting */ + tftp_doing, /* doing */ + tftp_getsock, /* proto_getsock */ + tftp_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + tftp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_TFTP, /* defport */ + CURLPROTO_TFTP, /* protocol */ + PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */ +}; + +/********************************************************** + * + * tftp_set_timeouts - + * + * Set timeouts based on state machine state. + * Use user provided connect timeouts until DATA or ACK + * packet is received, then use user-provided transfer timeouts + * + * + **********************************************************/ +static CURLcode tftp_set_timeouts(tftp_state_data_t *state) +{ + time_t maxtime, timeout; + timediff_t timeout_ms; + bool start = (state->state == TFTP_STATE_START) ? TRUE : FALSE; + + time(&state->start_time); + + /* Compute drop-dead time */ + timeout_ms = Curl_timeleft(state->conn->data, NULL, start); + + if(timeout_ms < 0) { + /* time-out, bail out, go home */ + failf(state->conn->data, "Connection time-out"); + return CURLE_OPERATION_TIMEDOUT; + } + + if(start) { + + maxtime = (time_t)(timeout_ms + 500) / 1000; + state->max_time = state->start_time + maxtime; + + /* Set per-block timeout to total */ + timeout = maxtime; + + /* Average restart after 5 seconds */ + state->retry_max = (int)timeout/5; + + if(state->retry_max < 1) + /* avoid division by zero below */ + state->retry_max = 1; + + /* Compute the re-start interval to suit the timeout */ + state->retry_time = (int)timeout/state->retry_max; + if(state->retry_time<1) + state->retry_time = 1; + + } + else { + if(timeout_ms > 0) + maxtime = (time_t)(timeout_ms + 500) / 1000; + else + maxtime = 3600; + + state->max_time = state->start_time + maxtime; + + /* Set per-block timeout to total */ + timeout = maxtime; + + /* Average reposting an ACK after 5 seconds */ + state->retry_max = (int)timeout/5; + } + /* But bound the total number */ + if(state->retry_max<3) + state->retry_max = 3; + + if(state->retry_max>50) + state->retry_max = 50; + + /* Compute the re-ACK interval to suit the timeout */ + state->retry_time = (int)(timeout/state->retry_max); + if(state->retry_time<1) + state->retry_time = 1; + + infof(state->conn->data, + "set timeouts for state %d; Total %ld, retry %d maxtry %d\n", + (int)state->state, (long)(state->max_time-state->start_time), + state->retry_time, state->retry_max); + + /* init RX time */ + time(&state->rx_time); + + return CURLE_OK; +} + +/********************************************************** + * + * tftp_set_send_first + * + * Event handler for the START state + * + **********************************************************/ + +static void setpacketevent(tftp_packet_t *packet, unsigned short num) +{ + packet->data[0] = (unsigned char)(num >> 8); + packet->data[1] = (unsigned char)(num & 0xff); +} + + +static void setpacketblock(tftp_packet_t *packet, unsigned short num) +{ + packet->data[2] = (unsigned char)(num >> 8); + packet->data[3] = (unsigned char)(num & 0xff); +} + +static unsigned short getrpacketevent(const tftp_packet_t *packet) +{ + return (unsigned short)((packet->data[0] << 8) | packet->data[1]); +} + +static unsigned short getrpacketblock(const tftp_packet_t *packet) +{ + return (unsigned short)((packet->data[2] << 8) | packet->data[3]); +} + +static size_t Curl_strnlen(const char *string, size_t maxlen) +{ + const char *end = memchr(string, '\0', maxlen); + return end ? (size_t) (end - string) : maxlen; +} + +static const char *tftp_option_get(const char *buf, size_t len, + const char **option, const char **value) +{ + size_t loc; + + loc = Curl_strnlen(buf, len); + loc++; /* NULL term */ + + if(loc >= len) + return NULL; + *option = buf; + + loc += Curl_strnlen(buf + loc, len-loc); + loc++; /* NULL term */ + + if(loc > len) + return NULL; + *value = &buf[strlen(*option) + 1]; + + return &buf[loc]; +} + +static CURLcode tftp_parse_option_ack(tftp_state_data_t *state, + const char *ptr, int len) +{ + const char *tmp = ptr; + struct Curl_easy *data = state->conn->data; + + /* if OACK doesn't contain blksize option, the default (512) must be used */ + state->blksize = TFTP_BLKSIZE_DEFAULT; + + while(tmp < ptr + len) { + const char *option, *value; + + tmp = tftp_option_get(tmp, ptr + len - tmp, &option, &value); + if(tmp == NULL) { + failf(data, "Malformed ACK packet, rejecting"); + return CURLE_TFTP_ILLEGAL; + } + + infof(data, "got option=(%s) value=(%s)\n", option, value); + + if(checkprefix(option, TFTP_OPTION_BLKSIZE)) { + long blksize; + + blksize = strtol(value, NULL, 10); + + if(!blksize) { + failf(data, "invalid blocksize value in OACK packet"); + return CURLE_TFTP_ILLEGAL; + } + if(blksize > TFTP_BLKSIZE_MAX) { + failf(data, "%s (%d)", "blksize is larger than max supported", + TFTP_BLKSIZE_MAX); + return CURLE_TFTP_ILLEGAL; + } + else if(blksize < TFTP_BLKSIZE_MIN) { + failf(data, "%s (%d)", "blksize is smaller than min supported", + TFTP_BLKSIZE_MIN); + return CURLE_TFTP_ILLEGAL; + } + else if(blksize > state->requested_blksize) { + /* could realloc pkt buffers here, but the spec doesn't call out + * support for the server requesting a bigger blksize than the client + * requests */ + failf(data, "%s (%ld)", + "server requested blksize larger than allocated", blksize); + return CURLE_TFTP_ILLEGAL; + } + + state->blksize = (int)blksize; + infof(data, "%s (%d) %s (%d)\n", "blksize parsed from OACK", + state->blksize, "requested", state->requested_blksize); + } + else if(checkprefix(option, TFTP_OPTION_TSIZE)) { + long tsize = 0; + + tsize = strtol(value, NULL, 10); + infof(data, "%s (%ld)\n", "tsize parsed from OACK", tsize); + + /* tsize should be ignored on upload: Who cares about the size of the + remote file? */ + if(!data->set.upload) { + if(!tsize) { + failf(data, "invalid tsize -:%s:- value in OACK packet", value); + return CURLE_TFTP_ILLEGAL; + } + Curl_pgrsSetDownloadSize(data, tsize); + } + } + } + + return CURLE_OK; +} + +static size_t tftp_option_add(tftp_state_data_t *state, size_t csize, + char *buf, const char *option) +{ + if(( strlen(option) + csize + 1) > (size_t)state->blksize) + return 0; + strcpy(buf, option); + return strlen(option) + 1; +} + +static CURLcode tftp_connect_for_tx(tftp_state_data_t *state, + tftp_event_t event) +{ + CURLcode result; +#ifndef CURL_DISABLE_VERBOSE_STRINGS + struct Curl_easy *data = state->conn->data; + + infof(data, "%s\n", "Connected for transmit"); +#endif + state->state = TFTP_STATE_TX; + result = tftp_set_timeouts(state); + if(result) + return result; + return tftp_tx(state, event); +} + +static CURLcode tftp_connect_for_rx(tftp_state_data_t *state, + tftp_event_t event) +{ + CURLcode result; +#ifndef CURL_DISABLE_VERBOSE_STRINGS + struct Curl_easy *data = state->conn->data; + + infof(data, "%s\n", "Connected for receive"); +#endif + state->state = TFTP_STATE_RX; + result = tftp_set_timeouts(state); + if(result) + return result; + return tftp_rx(state, event); +} + +static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event) +{ + size_t sbytes; + ssize_t senddata; + const char *mode = "octet"; + char *filename; + struct Curl_easy *data = state->conn->data; + CURLcode result = CURLE_OK; + + /* Set ascii mode if -B flag was used */ + if(data->set.prefer_ascii) + mode = "netascii"; + + switch(event) { + + case TFTP_EVENT_INIT: /* Send the first packet out */ + case TFTP_EVENT_TIMEOUT: /* Resend the first packet out */ + /* Increment the retry counter, quit if over the limit */ + state->retries++; + if(state->retries>state->retry_max) { + state->error = TFTP_ERR_NORESPONSE; + state->state = TFTP_STATE_FIN; + return result; + } + + if(data->set.upload) { + /* If we are uploading, send an WRQ */ + setpacketevent(&state->spacket, TFTP_EVENT_WRQ); + state->conn->data->req.upload_fromhere = + (char *)state->spacket.data + 4; + if(data->state.infilesize != -1) + Curl_pgrsSetUploadSize(data, data->state.infilesize); + } + else { + /* If we are downloading, send an RRQ */ + setpacketevent(&state->spacket, TFTP_EVENT_RRQ); + } + /* As RFC3617 describes the separator slash is not actually part of the + file name so we skip the always-present first letter of the path + string. */ + result = Curl_urldecode(data, &state->conn->data->state.up.path[1], 0, + &filename, NULL, FALSE); + if(result) + return result; + + if(strlen(filename) > (state->blksize - strlen(mode) - 4)) { + failf(data, "TFTP file name too long\n"); + free(filename); + return CURLE_TFTP_ILLEGAL; /* too long file name field */ + } + + msnprintf((char *)state->spacket.data + 2, + state->blksize, + "%s%c%s%c", filename, '\0', mode, '\0'); + sbytes = 4 + strlen(filename) + strlen(mode); + + /* optional addition of TFTP options */ + if(!data->set.tftp_no_options) { + char buf[64]; + /* add tsize option */ + if(data->set.upload && (data->state.infilesize != -1)) + msnprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T, + data->state.infilesize); + else + strcpy(buf, "0"); /* the destination is large enough */ + + sbytes += tftp_option_add(state, sbytes, + (char *)state->spacket.data + sbytes, + TFTP_OPTION_TSIZE); + sbytes += tftp_option_add(state, sbytes, + (char *)state->spacket.data + sbytes, buf); + /* add blksize option */ + msnprintf(buf, sizeof(buf), "%d", state->requested_blksize); + sbytes += tftp_option_add(state, sbytes, + (char *)state->spacket.data + sbytes, + TFTP_OPTION_BLKSIZE); + sbytes += tftp_option_add(state, sbytes, + (char *)state->spacket.data + sbytes, buf); + + /* add timeout option */ + msnprintf(buf, sizeof(buf), "%d", state->retry_time); + sbytes += tftp_option_add(state, sbytes, + (char *)state->spacket.data + sbytes, + TFTP_OPTION_INTERVAL); + sbytes += tftp_option_add(state, sbytes, + (char *)state->spacket.data + sbytes, buf); + } + + /* the typecase for the 3rd argument is mostly for systems that do + not have a size_t argument, like older unixes that want an 'int' */ + senddata = sendto(state->sockfd, (void *)state->spacket.data, + (SEND_TYPE_ARG3)sbytes, 0, + state->conn->ip_addr->ai_addr, + state->conn->ip_addr->ai_addrlen); + if(senddata != (ssize_t)sbytes) { + char buffer[STRERROR_LEN]; + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + } + free(filename); + break; + + case TFTP_EVENT_OACK: + if(data->set.upload) { + result = tftp_connect_for_tx(state, event); + } + else { + result = tftp_connect_for_rx(state, event); + } + break; + + case TFTP_EVENT_ACK: /* Connected for transmit */ + result = tftp_connect_for_tx(state, event); + break; + + case TFTP_EVENT_DATA: /* Connected for receive */ + result = tftp_connect_for_rx(state, event); + break; + + case TFTP_EVENT_ERROR: + state->state = TFTP_STATE_FIN; + break; + + default: + failf(state->conn->data, "tftp_send_first: internal error"); + break; + } + + return result; +} + +/* the next blocknum is x + 1 but it needs to wrap at an unsigned 16bit + boundary */ +#define NEXT_BLOCKNUM(x) (((x) + 1)&0xffff) + +/********************************************************** + * + * tftp_rx + * + * Event handler for the RX state + * + **********************************************************/ +static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event) +{ + ssize_t sbytes; + int rblock; + struct Curl_easy *data = state->conn->data; + char buffer[STRERROR_LEN]; + + switch(event) { + + case TFTP_EVENT_DATA: + /* Is this the block we expect? */ + rblock = getrpacketblock(&state->rpacket); + if(NEXT_BLOCKNUM(state->block) == rblock) { + /* This is the expected block. Reset counters and ACK it. */ + state->retries = 0; + } + else if(state->block == rblock) { + /* This is the last recently received block again. Log it and ACK it + again. */ + infof(data, "Received last DATA packet block %d again.\n", rblock); + } + else { + /* totally unexpected, just log it */ + infof(data, + "Received unexpected DATA packet block %d, expecting block %d\n", + rblock, NEXT_BLOCKNUM(state->block)); + break; + } + + /* ACK this block. */ + state->block = (unsigned short)rblock; + setpacketevent(&state->spacket, TFTP_EVENT_ACK); + setpacketblock(&state->spacket, state->block); + sbytes = sendto(state->sockfd, (void *)state->spacket.data, + 4, SEND_4TH_ARG, + (struct sockaddr *)&state->remote_addr, + state->remote_addrlen); + if(sbytes < 0) { + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + return CURLE_SEND_ERROR; + } + + /* Check if completed (That is, a less than full packet is received) */ + if(state->rbytes < (ssize_t)state->blksize + 4) { + state->state = TFTP_STATE_FIN; + } + else { + state->state = TFTP_STATE_RX; + } + time(&state->rx_time); + break; + + case TFTP_EVENT_OACK: + /* ACK option acknowledgement so we can move on to data */ + state->block = 0; + state->retries = 0; + setpacketevent(&state->spacket, TFTP_EVENT_ACK); + setpacketblock(&state->spacket, state->block); + sbytes = sendto(state->sockfd, (void *)state->spacket.data, + 4, SEND_4TH_ARG, + (struct sockaddr *)&state->remote_addr, + state->remote_addrlen); + if(sbytes < 0) { + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + return CURLE_SEND_ERROR; + } + + /* we're ready to RX data */ + state->state = TFTP_STATE_RX; + time(&state->rx_time); + break; + + case TFTP_EVENT_TIMEOUT: + /* Increment the retry count and fail if over the limit */ + state->retries++; + infof(data, + "Timeout waiting for block %d ACK. Retries = %d\n", + NEXT_BLOCKNUM(state->block), state->retries); + if(state->retries > state->retry_max) { + state->error = TFTP_ERR_TIMEOUT; + state->state = TFTP_STATE_FIN; + } + else { + /* Resend the previous ACK */ + sbytes = sendto(state->sockfd, (void *)state->spacket.data, + 4, SEND_4TH_ARG, + (struct sockaddr *)&state->remote_addr, + state->remote_addrlen); + if(sbytes<0) { + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + return CURLE_SEND_ERROR; + } + } + break; + + case TFTP_EVENT_ERROR: + setpacketevent(&state->spacket, TFTP_EVENT_ERROR); + setpacketblock(&state->spacket, state->block); + (void)sendto(state->sockfd, (void *)state->spacket.data, + 4, SEND_4TH_ARG, + (struct sockaddr *)&state->remote_addr, + state->remote_addrlen); + /* don't bother with the return code, but if the socket is still up we + * should be a good TFTP client and let the server know we're done */ + state->state = TFTP_STATE_FIN; + break; + + default: + failf(data, "%s", "tftp_rx: internal error"); + return CURLE_TFTP_ILLEGAL; /* not really the perfect return code for + this */ + } + return CURLE_OK; +} + +/********************************************************** + * + * tftp_tx + * + * Event handler for the TX state + * + **********************************************************/ +static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) +{ + struct Curl_easy *data = state->conn->data; + ssize_t sbytes; + CURLcode result = CURLE_OK; + struct SingleRequest *k = &data->req; + size_t cb; /* Bytes currently read */ + char buffer[STRERROR_LEN]; + + switch(event) { + + case TFTP_EVENT_ACK: + case TFTP_EVENT_OACK: + if(event == TFTP_EVENT_ACK) { + /* Ack the packet */ + int rblock = getrpacketblock(&state->rpacket); + + if(rblock != state->block && + /* There's a bug in tftpd-hpa that causes it to send us an ack for + * 65535 when the block number wraps to 0. So when we're expecting + * 0, also accept 65535. See + * http://syslinux.zytor.com/archives/2010-September/015253.html + * */ + !(state->block == 0 && rblock == 65535)) { + /* This isn't the expected block. Log it and up the retry counter */ + infof(data, "Received ACK for block %d, expecting %d\n", + rblock, state->block); + state->retries++; + /* Bail out if over the maximum */ + if(state->retries>state->retry_max) { + failf(data, "tftp_tx: giving up waiting for block %d ack", + state->block); + result = CURLE_SEND_ERROR; + } + else { + /* Re-send the data packet */ + sbytes = sendto(state->sockfd, (void *)state->spacket.data, + 4 + state->sbytes, SEND_4TH_ARG, + (struct sockaddr *)&state->remote_addr, + state->remote_addrlen); + /* Check all sbytes were sent */ + if(sbytes<0) { + failf(data, "%s", Curl_strerror(SOCKERRNO, + buffer, sizeof(buffer))); + result = CURLE_SEND_ERROR; + } + } + + return result; + } + /* This is the expected packet. Reset the counters and send the next + block */ + time(&state->rx_time); + state->block++; + } + else + state->block = 1; /* first data block is 1 when using OACK */ + + state->retries = 0; + setpacketevent(&state->spacket, TFTP_EVENT_DATA); + setpacketblock(&state->spacket, state->block); + if(state->block > 1 && state->sbytes < state->blksize) { + state->state = TFTP_STATE_FIN; + return CURLE_OK; + } + + /* TFTP considers data block size < 512 bytes as an end of session. So + * in some cases we must wait for additional data to build full (512 bytes) + * data block. + * */ + state->sbytes = 0; + state->conn->data->req.upload_fromhere = (char *)state->spacket.data + 4; + do { + result = Curl_fillreadbuffer(state->conn, state->blksize - state->sbytes, + &cb); + if(result) + return result; + state->sbytes += (int)cb; + state->conn->data->req.upload_fromhere += cb; + } while(state->sbytes < state->blksize && cb != 0); + + sbytes = sendto(state->sockfd, (void *) state->spacket.data, + 4 + state->sbytes, SEND_4TH_ARG, + (struct sockaddr *)&state->remote_addr, + state->remote_addrlen); + /* Check all sbytes were sent */ + if(sbytes<0) { + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + return CURLE_SEND_ERROR; + } + /* Update the progress meter */ + k->writebytecount += state->sbytes; + Curl_pgrsSetUploadCounter(data, k->writebytecount); + break; + + case TFTP_EVENT_TIMEOUT: + /* Increment the retry counter and log the timeout */ + state->retries++; + infof(data, "Timeout waiting for block %d ACK. " + " Retries = %d\n", NEXT_BLOCKNUM(state->block), state->retries); + /* Decide if we've had enough */ + if(state->retries > state->retry_max) { + state->error = TFTP_ERR_TIMEOUT; + state->state = TFTP_STATE_FIN; + } + else { + /* Re-send the data packet */ + sbytes = sendto(state->sockfd, (void *)state->spacket.data, + 4 + state->sbytes, SEND_4TH_ARG, + (struct sockaddr *)&state->remote_addr, + state->remote_addrlen); + /* Check all sbytes were sent */ + if(sbytes<0) { + failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + return CURLE_SEND_ERROR; + } + /* since this was a re-send, we remain at the still byte position */ + Curl_pgrsSetUploadCounter(data, k->writebytecount); + } + break; + + case TFTP_EVENT_ERROR: + state->state = TFTP_STATE_FIN; + setpacketevent(&state->spacket, TFTP_EVENT_ERROR); + setpacketblock(&state->spacket, state->block); + (void)sendto(state->sockfd, (void *)state->spacket.data, 4, SEND_4TH_ARG, + (struct sockaddr *)&state->remote_addr, + state->remote_addrlen); + /* don't bother with the return code, but if the socket is still up we + * should be a good TFTP client and let the server know we're done */ + state->state = TFTP_STATE_FIN; + break; + + default: + failf(data, "tftp_tx: internal error, event: %i", (int)(event)); + break; + } + + return result; +} + +/********************************************************** + * + * tftp_translate_code + * + * Translate internal error codes to CURL error codes + * + **********************************************************/ +static CURLcode tftp_translate_code(tftp_error_t error) +{ + CURLcode result = CURLE_OK; + + if(error != TFTP_ERR_NONE) { + switch(error) { + case TFTP_ERR_NOTFOUND: + result = CURLE_TFTP_NOTFOUND; + break; + case TFTP_ERR_PERM: + result = CURLE_TFTP_PERM; + break; + case TFTP_ERR_DISKFULL: + result = CURLE_REMOTE_DISK_FULL; + break; + case TFTP_ERR_UNDEF: + case TFTP_ERR_ILLEGAL: + result = CURLE_TFTP_ILLEGAL; + break; + case TFTP_ERR_UNKNOWNID: + result = CURLE_TFTP_UNKNOWNID; + break; + case TFTP_ERR_EXISTS: + result = CURLE_REMOTE_FILE_EXISTS; + break; + case TFTP_ERR_NOSUCHUSER: + result = CURLE_TFTP_NOSUCHUSER; + break; + case TFTP_ERR_TIMEOUT: + result = CURLE_OPERATION_TIMEDOUT; + break; + case TFTP_ERR_NORESPONSE: + result = CURLE_COULDNT_CONNECT; + break; + default: + result = CURLE_ABORTED_BY_CALLBACK; + break; + } + } + else + result = CURLE_OK; + + return result; +} + +/********************************************************** + * + * tftp_state_machine + * + * The tftp state machine event dispatcher + * + **********************************************************/ +static CURLcode tftp_state_machine(tftp_state_data_t *state, + tftp_event_t event) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = state->conn->data; + + switch(state->state) { + case TFTP_STATE_START: + DEBUGF(infof(data, "TFTP_STATE_START\n")); + result = tftp_send_first(state, event); + break; + case TFTP_STATE_RX: + DEBUGF(infof(data, "TFTP_STATE_RX\n")); + result = tftp_rx(state, event); + break; + case TFTP_STATE_TX: + DEBUGF(infof(data, "TFTP_STATE_TX\n")); + result = tftp_tx(state, event); + break; + case TFTP_STATE_FIN: + infof(data, "%s\n", "TFTP finished"); + break; + default: + DEBUGF(infof(data, "STATE: %d\n", state->state)); + failf(data, "%s", "Internal state machine error"); + result = CURLE_TFTP_ILLEGAL; + break; + } + + return result; +} + +/********************************************************** + * + * tftp_disconnect + * + * The disconnect callback + * + **********************************************************/ +static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection) +{ + tftp_state_data_t *state = conn->proto.tftpc; + (void) dead_connection; + + /* done, free dynamically allocated pkt buffers */ + if(state) { + Curl_safefree(state->rpacket.data); + Curl_safefree(state->spacket.data); + free(state); + } + + return CURLE_OK; +} + +/********************************************************** + * + * tftp_connect + * + * The connect callback + * + **********************************************************/ +static CURLcode tftp_connect(struct connectdata *conn, bool *done) +{ + tftp_state_data_t *state; + int blksize; + + blksize = TFTP_BLKSIZE_DEFAULT; + + state = conn->proto.tftpc = calloc(1, sizeof(tftp_state_data_t)); + if(!state) + return CURLE_OUT_OF_MEMORY; + + /* alloc pkt buffers based on specified blksize */ + if(conn->data->set.tftp_blksize) { + blksize = (int)conn->data->set.tftp_blksize; + if(blksize > TFTP_BLKSIZE_MAX || blksize < TFTP_BLKSIZE_MIN) + return CURLE_TFTP_ILLEGAL; + } + + if(!state->rpacket.data) { + state->rpacket.data = calloc(1, blksize + 2 + 2); + + if(!state->rpacket.data) + return CURLE_OUT_OF_MEMORY; + } + + if(!state->spacket.data) { + state->spacket.data = calloc(1, blksize + 2 + 2); + + if(!state->spacket.data) + return CURLE_OUT_OF_MEMORY; + } + + /* we don't keep TFTP connections up basically because there's none or very + * little gain for UDP */ + connclose(conn, "TFTP"); + + state->conn = conn; + state->sockfd = state->conn->sock[FIRSTSOCKET]; + state->state = TFTP_STATE_START; + state->error = TFTP_ERR_NONE; + state->blksize = blksize; + state->requested_blksize = blksize; + + ((struct sockaddr *)&state->local_addr)->sa_family = + (CURL_SA_FAMILY_T)(conn->ip_addr->ai_family); + + tftp_set_timeouts(state); + + if(!conn->bits.bound) { + /* If not already bound, bind to any interface, random UDP port. If it is + * reused or a custom local port was desired, this has already been done! + * + * We once used the size of the local_addr struct as the third argument + * for bind() to better work with IPv6 or whatever size the struct could + * have, but we learned that at least Tru64, AIX and IRIX *requires* the + * size of that argument to match the exact size of a 'sockaddr_in' struct + * when running IPv4-only. + * + * Therefore we use the size from the address we connected to, which we + * assume uses the same IP version and thus hopefully this works for both + * IPv4 and IPv6... + */ + int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr, + conn->ip_addr->ai_addrlen); + if(rc) { + char buffer[STRERROR_LEN]; + failf(conn->data, "bind() failed; %s", + Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); + return CURLE_COULDNT_CONNECT; + } + conn->bits.bound = TRUE; + } + + Curl_pgrsStartNow(conn->data); + + *done = TRUE; + + return CURLE_OK; +} + +/********************************************************** + * + * tftp_done + * + * The done callback + * + **********************************************************/ +static CURLcode tftp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + CURLcode result = CURLE_OK; + tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc; + + (void)status; /* unused */ + (void)premature; /* not used */ + + if(Curl_pgrsDone(conn)) + return CURLE_ABORTED_BY_CALLBACK; + + /* If we have encountered an error */ + if(state) + result = tftp_translate_code(state->error); + + return result; +} + +/********************************************************** + * + * tftp_getsock + * + * The getsock callback + * + **********************************************************/ +static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks) +{ + if(!numsocks) + return GETSOCK_BLANK; + + socks[0] = conn->sock[FIRSTSOCKET]; + + return GETSOCK_READSOCK(0); +} + +/********************************************************** + * + * tftp_receive_packet + * + * Called once select fires and data is ready on the socket + * + **********************************************************/ +static CURLcode tftp_receive_packet(struct connectdata *conn) +{ + struct Curl_sockaddr_storage fromaddr; + curl_socklen_t fromlen; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc; + struct SingleRequest *k = &data->req; + + /* Receive the packet */ + fromlen = sizeof(fromaddr); + state->rbytes = (int)recvfrom(state->sockfd, + (void *)state->rpacket.data, + state->blksize + 4, + 0, + (struct sockaddr *)&fromaddr, + &fromlen); + if(state->remote_addrlen == 0) { + memcpy(&state->remote_addr, &fromaddr, fromlen); + state->remote_addrlen = fromlen; + } + + /* Sanity check packet length */ + if(state->rbytes < 4) { + failf(data, "Received too short packet"); + /* Not a timeout, but how best to handle it? */ + state->event = TFTP_EVENT_TIMEOUT; + } + else { + /* The event is given by the TFTP packet time */ + unsigned short event = getrpacketevent(&state->rpacket); + state->event = (tftp_event_t)event; + + switch(state->event) { + case TFTP_EVENT_DATA: + /* Don't pass to the client empty or retransmitted packets */ + if(state->rbytes > 4 && + (NEXT_BLOCKNUM(state->block) == getrpacketblock(&state->rpacket))) { + result = Curl_client_write(conn, CLIENTWRITE_BODY, + (char *)state->rpacket.data + 4, + state->rbytes-4); + if(result) { + tftp_state_machine(state, TFTP_EVENT_ERROR); + return result; + } + k->bytecount += state->rbytes-4; + Curl_pgrsSetDownloadCounter(data, (curl_off_t) k->bytecount); + } + break; + case TFTP_EVENT_ERROR: + { + unsigned short error = getrpacketblock(&state->rpacket); + char *str = (char *)state->rpacket.data + 4; + size_t strn = state->rbytes - 4; + state->error = (tftp_error_t)error; + if(Curl_strnlen(str, strn) < strn) + infof(data, "TFTP error: %s\n", str); + break; + } + case TFTP_EVENT_ACK: + break; + case TFTP_EVENT_OACK: + result = tftp_parse_option_ack(state, + (const char *)state->rpacket.data + 2, + state->rbytes-2); + if(result) + return result; + break; + case TFTP_EVENT_RRQ: + case TFTP_EVENT_WRQ: + default: + failf(data, "%s", "Internal error: Unexpected packet"); + break; + } + + /* Update the progress meter */ + if(Curl_pgrsUpdate(conn)) { + tftp_state_machine(state, TFTP_EVENT_ERROR); + return CURLE_ABORTED_BY_CALLBACK; + } + } + return result; +} + +/********************************************************** + * + * tftp_state_timeout + * + * Check if timeouts have been reached + * + **********************************************************/ +static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event) +{ + time_t current; + tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc; + + if(event) + *event = TFTP_EVENT_NONE; + + time(¤t); + if(current > state->max_time) { + DEBUGF(infof(conn->data, "timeout: %ld > %ld\n", + (long)current, (long)state->max_time)); + state->error = TFTP_ERR_TIMEOUT; + state->state = TFTP_STATE_FIN; + return 0; + } + if(current > state->rx_time + state->retry_time) { + if(event) + *event = TFTP_EVENT_TIMEOUT; + time(&state->rx_time); /* update even though we received nothing */ + } + + /* there's a typecast below here since 'time_t' may in fact be larger than + 'long', but we estimate that a 'long' will still be able to hold number + of seconds even if "only" 32 bit */ + return (long)(state->max_time - current); +} + +/********************************************************** + * + * tftp_multi_statemach + * + * Handle single RX socket event and return + * + **********************************************************/ +static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done) +{ + tftp_event_t event; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc; + long timeout_ms = tftp_state_timeout(conn, &event); + + *done = FALSE; + + if(timeout_ms <= 0) { + failf(data, "TFTP response timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + if(event != TFTP_EVENT_NONE) { + result = tftp_state_machine(state, event); + if(result) + return result; + *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE; + if(*done) + /* Tell curl we're done */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + } + else { + /* no timeouts to handle, check our socket */ + int rc = SOCKET_READABLE(state->sockfd, 0); + + if(rc == -1) { + /* bail out */ + int error = SOCKERRNO; + char buffer[STRERROR_LEN]; + failf(data, "%s", Curl_strerror(error, buffer, sizeof(buffer))); + state->event = TFTP_EVENT_ERROR; + } + else if(rc != 0) { + result = tftp_receive_packet(conn); + if(result) + return result; + result = tftp_state_machine(state, state->event); + if(result) + return result; + *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE; + if(*done) + /* Tell curl we're done */ + Curl_setup_transfer(data, -1, -1, FALSE, -1); + } + /* if rc == 0, then select() timed out */ + } + + return result; +} + +/********************************************************** + * + * tftp_doing + * + * Called from multi.c while DOing + * + **********************************************************/ +static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done) +{ + CURLcode result; + result = tftp_multi_statemach(conn, dophase_done); + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + else if(!result) { + /* The multi code doesn't have this logic for the DOING state so we + provide it for TFTP since it may do the entire transfer in this + state. */ + if(Curl_pgrsUpdate(conn)) + result = CURLE_ABORTED_BY_CALLBACK; + else + result = Curl_speedcheck(conn->data, Curl_now()); + } + return result; +} + +/********************************************************** + * + * tftp_peform + * + * Entry point for transfer from tftp_do, sarts state mach + * + **********************************************************/ +static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done) +{ + CURLcode result = CURLE_OK; + tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc; + + *dophase_done = FALSE; + + result = tftp_state_machine(state, TFTP_EVENT_INIT); + + if((state->state == TFTP_STATE_FIN) || result) + return result; + + tftp_multi_statemach(conn, dophase_done); + + if(*dophase_done) + DEBUGF(infof(conn->data, "DO phase is complete\n")); + + return result; +} + + +/********************************************************** + * + * tftp_do + * + * The do callback + * + * This callback initiates the TFTP transfer + * + **********************************************************/ + +static CURLcode tftp_do(struct connectdata *conn, bool *done) +{ + tftp_state_data_t *state; + CURLcode result; + + *done = FALSE; + + if(!conn->proto.tftpc) { + result = tftp_connect(conn, done); + if(result) + return result; + } + + state = (tftp_state_data_t *)conn->proto.tftpc; + if(!state) + return CURLE_TFTP_ILLEGAL; + + result = tftp_perform(conn, done); + + /* If tftp_perform() returned an error, use that for return code. If it + was OK, see if tftp_translate_code() has an error. */ + if(!result) + /* If we have encountered an internal tftp error, translate it. */ + result = tftp_translate_code(state->error); + + return result; +} + +static CURLcode tftp_setup_connection(struct connectdata * conn) +{ + struct Curl_easy *data = conn->data; + char *type; + + conn->socktype = SOCK_DGRAM; /* UDP datagram based */ + + /* TFTP URLs support an extension like ";mode=" that + * we'll try to get now! */ + type = strstr(data->state.up.path, ";mode="); + + if(!type) + type = strstr(conn->host.rawalloc, ";mode="); + + if(type) { + char command; + *type = 0; /* it was in the middle of the hostname */ + command = Curl_raw_toupper(type[6]); + + switch(command) { + case 'A': /* ASCII mode */ + case 'N': /* NETASCII mode */ + data->set.prefer_ascii = TRUE; + break; + + case 'O': /* octet mode */ + case 'I': /* binary mode */ + default: + /* switch off ASCII */ + data->set.prefer_ascii = FALSE; + break; + } + } + + return CURLE_OK; +} +#endif diff --git a/libcurl/lib/tftp.h b/libcurl/lib/tftp.h new file mode 100644 index 0000000..1335f64 --- /dev/null +++ b/libcurl/lib/tftp.h @@ -0,0 +1,28 @@ +#ifndef HEADER_CURL_TFTP_H +#define HEADER_CURL_TFTP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifndef CURL_DISABLE_TFTP +extern const struct Curl_handler Curl_handler_tftp; +#endif + +#endif /* HEADER_CURL_TFTP_H */ diff --git a/libcurl/lib/timeval.c b/libcurl/lib/timeval.c new file mode 100644 index 0000000..dbb8bc0 --- /dev/null +++ b/libcurl/lib/timeval.c @@ -0,0 +1,214 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "timeval.h" + +#if defined(WIN32) && !defined(MSDOS) + +/* set in win32_init() */ +extern LARGE_INTEGER Curl_freq; +extern bool Curl_isVistaOrGreater; + +struct curltime Curl_now(void) +{ + struct curltime now; + if(Curl_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */ + LARGE_INTEGER count; + QueryPerformanceCounter(&count); + now.tv_sec = (time_t)(count.QuadPart / Curl_freq.QuadPart); + now.tv_usec = (int)((count.QuadPart % Curl_freq.QuadPart) * 1000000 / + Curl_freq.QuadPart); + } + else { + /* Disable /analyze warning that GetTickCount64 is preferred */ + /* Note: warning 28159 only exists in VS2005+ (_MSC_VER >= 1400) */ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma warning(push) +#pragma warning(disable:28159) +#endif + DWORD milliseconds = GetTickCount(); +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma warning(pop) +#endif + + now.tv_sec = milliseconds / 1000; + now.tv_usec = (milliseconds % 1000) * 1000; + } + return now; +} + +#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) + +struct curltime Curl_now(void) +{ + /* + ** clock_gettime() is granted to be increased monotonically when the + ** monotonic clock is queried. Time starting point is unspecified, it + ** could be the system start-up time, the Epoch, or something else, + ** in any case the time starting point does not change once that the + ** system has started up. + */ +#ifdef HAVE_GETTIMEOFDAY + struct timeval now; +#endif + struct curltime cnow; + struct timespec tsnow; + + /* + ** clock_gettime() may be defined by Apple's SDK as weak symbol thus + ** code compiles but fails during run-time if clock_gettime() is + ** called on unsupported OS version. + */ +#if defined(__APPLE__) && (HAVE_BUILTIN_AVAILABLE == 1) + bool have_clock_gettime = FALSE; + if(__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *)) + have_clock_gettime = TRUE; +#endif + + if( +#if defined(__APPLE__) && (HAVE_BUILTIN_AVAILABLE == 1) + have_clock_gettime && +#endif + (0 == clock_gettime(CLOCK_MONOTONIC, &tsnow))) { + cnow.tv_sec = tsnow.tv_sec; + cnow.tv_usec = (unsigned int)(tsnow.tv_nsec / 1000); + } + /* + ** Even when the configure process has truly detected monotonic clock + ** availability, it might happen that it is not actually available at + ** run-time. When this occurs simply fallback to other time source. + */ +#ifdef HAVE_GETTIMEOFDAY + else { + (void)gettimeofday(&now, NULL); + cnow.tv_sec = now.tv_sec; + cnow.tv_usec = (unsigned int)now.tv_usec; + } +#else + else { + cnow.tv_sec = time(NULL); + cnow.tv_usec = 0; + } +#endif + return cnow; +} + +#elif defined(HAVE_MACH_ABSOLUTE_TIME) + +#include +#include + +struct curltime Curl_now(void) +{ + /* + ** Monotonic timer on Mac OS is provided by mach_absolute_time(), which + ** returns time in Mach "absolute time units," which are platform-dependent. + ** To convert to nanoseconds, one must use conversion factors specified by + ** mach_timebase_info(). + */ + static mach_timebase_info_data_t timebase; + struct curltime cnow; + uint64_t usecs; + + if(0 == timebase.denom) + (void) mach_timebase_info(&timebase); + + usecs = mach_absolute_time(); + usecs *= timebase.numer; + usecs /= timebase.denom; + usecs /= 1000; + + cnow.tv_sec = usecs / 1000000; + cnow.tv_usec = (int)(usecs % 1000000); + + return cnow; +} + +#elif defined(HAVE_GETTIMEOFDAY) + +struct curltime Curl_now(void) +{ + /* + ** gettimeofday() is not granted to be increased monotonically, due to + ** clock drifting and external source time synchronization it can jump + ** forward or backward in time. + */ + struct timeval now; + struct curltime ret; + (void)gettimeofday(&now, NULL); + ret.tv_sec = now.tv_sec; + ret.tv_usec = (int)now.tv_usec; + return ret; +} + +#else + +struct curltime Curl_now(void) +{ + /* + ** time() returns the value of time in seconds since the Epoch. + */ + struct curltime now; + now.tv_sec = time(NULL); + now.tv_usec = 0; + return now; +} + +#endif + +#if SIZEOF_TIME_T < 8 +#define TIME_MAX INT_MAX +#define TIME_MIN INT_MIN +#else +#define TIME_MAX 9223372036854775807LL +#define TIME_MIN -9223372036854775807LL +#endif + +/* + * Returns: time difference in number of milliseconds. For too large diffs it + * returns max value. + * + * @unittest: 1323 + */ +timediff_t Curl_timediff(struct curltime newer, struct curltime older) +{ + timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec; + if(diff >= (TIME_MAX/1000)) + return TIME_MAX; + else if(diff <= (TIME_MIN/1000)) + return TIME_MIN; + return diff * 1000 + (newer.tv_usec-older.tv_usec)/1000; +} + +/* + * Returns: time difference in number of microseconds. For too large diffs it + * returns max value. + */ +timediff_t Curl_timediff_us(struct curltime newer, struct curltime older) +{ + timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec; + if(diff >= (TIME_MAX/1000000)) + return TIME_MAX; + else if(diff <= (TIME_MIN/1000000)) + return TIME_MIN; + return diff * 1000000 + newer.tv_usec-older.tv_usec; +} diff --git a/libcurl/lib/timeval.h b/libcurl/lib/timeval.h new file mode 100644 index 0000000..96867d7 --- /dev/null +++ b/libcurl/lib/timeval.h @@ -0,0 +1,58 @@ +#ifndef HEADER_CURL_TIMEVAL_H +#define HEADER_CURL_TIMEVAL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if SIZEOF_TIME_T < 8 +typedef int timediff_t; +#define CURL_FORMAT_TIMEDIFF_T "d" +#else +typedef curl_off_t timediff_t; +#define CURL_FORMAT_TIMEDIFF_T CURL_FORMAT_CURL_OFF_T +#endif + +struct curltime { + time_t tv_sec; /* seconds */ + int tv_usec; /* microseconds */ +}; + +struct curltime Curl_now(void); + +/* + * Make sure that the first argument (t1) is the more recent time and t2 is + * the older time, as otherwise you get a weird negative time-diff back... + * + * Returns: the time difference in number of milliseconds. + */ +timediff_t Curl_timediff(struct curltime t1, struct curltime t2); + +/* + * Make sure that the first argument (t1) is the more recent time and t2 is + * the older time, as otherwise you get a weird negative time-diff back... + * + * Returns: the time difference in number of microseconds. + */ +timediff_t Curl_timediff_us(struct curltime newer, struct curltime older); + +#endif /* HEADER_CURL_TIMEVAL_H */ diff --git a/libcurl/lib/transfer.c b/libcurl/lib/transfer.c new file mode 100644 index 0000000..4426a4b --- /dev/null +++ b/libcurl/lib/transfer.c @@ -0,0 +1,1902 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include "strtoofft.h" + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +#ifdef HAVE_SIGNAL_H +#include +#endif + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#ifndef HAVE_SOCKET +#error "We can't compile without socket() support!" +#endif + +#include "urldata.h" +#include +#include "netrc.h" + +#include "content_encoding.h" +#include "hostip.h" +#include "transfer.h" +#include "sendf.h" +#include "speedcheck.h" +#include "progress.h" +#include "http.h" +#include "url.h" +#include "getinfo.h" +#include "vtls/vtls.h" +#include "select.h" +#include "multiif.h" +#include "connect.h" +#include "non-ascii.h" +#include "http2.h" +#include "mime.h" +#include "strcase.h" +#include "urlapi-int.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \ + !defined(CURL_DISABLE_IMAP) +/* + * checkheaders() checks the linked list of custom headers for a + * particular header (prefix). Provide the prefix without colon! + * + * Returns a pointer to the first matching header or NULL if none matched. + */ +char *Curl_checkheaders(const struct connectdata *conn, + const char *thisheader) +{ + struct curl_slist *head; + size_t thislen = strlen(thisheader); + struct Curl_easy *data = conn->data; + + for(head = data->set.headers; head; head = head->next) { + if(strncasecompare(head->data, thisheader, thislen) && + Curl_headersep(head->data[thislen]) ) + return head->data; + } + + return NULL; +} +#endif + +CURLcode Curl_get_upload_buffer(struct Curl_easy *data) +{ + if(!data->state.ulbuf) { + data->state.ulbuf = malloc(data->set.upload_buffer_size); + if(!data->state.ulbuf) + return CURLE_OUT_OF_MEMORY; + } + return CURLE_OK; +} + +#ifndef CURL_DISABLE_HTTP +/* + * This function will be called to loop through the trailers buffer + * until no more data is available for sending. + */ +static size_t Curl_trailers_read(char *buffer, size_t size, size_t nitems, + void *raw) +{ + struct Curl_easy *data = (struct Curl_easy *)raw; + Curl_send_buffer *trailers_buf = data->state.trailers_buf; + size_t bytes_left = trailers_buf->size_used-data->state.trailers_bytes_sent; + size_t to_copy = (size*nitems < bytes_left) ? size*nitems : bytes_left; + if(to_copy) { + memcpy(buffer, + &trailers_buf->buffer[data->state.trailers_bytes_sent], + to_copy); + data->state.trailers_bytes_sent += to_copy; + } + return to_copy; +} + +static size_t Curl_trailers_left(void *raw) +{ + struct Curl_easy *data = (struct Curl_easy *)raw; + Curl_send_buffer *trailers_buf = data->state.trailers_buf; + return trailers_buf->size_used - data->state.trailers_bytes_sent; +} +#endif + +/* + * This function will call the read callback to fill our buffer with data + * to upload. + */ +CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, + size_t *nreadp) +{ + struct Curl_easy *data = conn->data; + size_t buffersize = bytes; + size_t nread; + + curl_read_callback readfunc = NULL; + void *extra_data = NULL; + +#ifdef CURL_DOES_CONVERSIONS + bool sending_http_headers = FALSE; + + if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) { + const struct HTTP *http = data->req.protop; + + if(http->sending == HTTPSEND_REQUEST) + /* We're sending the HTTP request headers, not the data. + Remember that so we don't re-translate them into garbage. */ + sending_http_headers = TRUE; + } +#endif + +#ifndef CURL_DISABLE_HTTP + if(data->state.trailers_state == TRAILERS_INITIALIZED) { + struct curl_slist *trailers = NULL; + CURLcode c; + int trailers_ret_code; + + /* at this point we already verified that the callback exists + so we compile and store the trailers buffer, then proceed */ + infof(data, + "Moving trailers state machine from initialized to sending.\n"); + data->state.trailers_state = TRAILERS_SENDING; + data->state.trailers_buf = Curl_add_buffer_init(); + if(!data->state.trailers_buf) { + failf(data, "Unable to allocate trailing headers buffer !"); + return CURLE_OUT_OF_MEMORY; + } + data->state.trailers_bytes_sent = 0; + Curl_set_in_callback(data, true); + trailers_ret_code = data->set.trailer_callback(&trailers, + data->set.trailer_data); + Curl_set_in_callback(data, false); + if(trailers_ret_code == CURL_TRAILERFUNC_OK) { + c = Curl_http_compile_trailers(trailers, data->state.trailers_buf, data); + } + else { + failf(data, "operation aborted by trailing headers callback"); + *nreadp = 0; + c = CURLE_ABORTED_BY_CALLBACK; + } + if(c != CURLE_OK) { + Curl_add_buffer_free(&data->state.trailers_buf); + curl_slist_free_all(trailers); + return c; + } + infof(data, "Successfully compiled trailers.\r\n"); + curl_slist_free_all(trailers); + } +#endif + + /* if we are transmitting trailing data, we don't need to write + a chunk size so we skip this */ + if(data->req.upload_chunky && + data->state.trailers_state == TRAILERS_NONE) { + /* if chunked Transfer-Encoding */ + buffersize -= (8 + 2 + 2); /* 32bit hex + CRLF + CRLF */ + data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */ + } + +#ifndef CURL_DISABLE_HTTP + if(data->state.trailers_state == TRAILERS_SENDING) { + /* if we're here then that means that we already sent the last empty chunk + but we didn't send a final CR LF, so we sent 0 CR LF. We then start + pulling trailing data until we have no more at which point we + simply return to the previous point in the state machine as if + nothing happened. + */ + readfunc = Curl_trailers_read; + extra_data = (void *)data; + } + else +#endif + { + readfunc = data->state.fread_func; + extra_data = data->state.in; + } + + Curl_set_in_callback(data, true); + nread = readfunc(data->req.upload_fromhere, 1, + buffersize, extra_data); + Curl_set_in_callback(data, false); + + if(nread == CURL_READFUNC_ABORT) { + failf(data, "operation aborted by callback"); + *nreadp = 0; + return CURLE_ABORTED_BY_CALLBACK; + } + if(nread == CURL_READFUNC_PAUSE) { + struct SingleRequest *k = &data->req; + + if(conn->handler->flags & PROTOPT_NONETWORK) { + /* protocols that work without network cannot be paused. This is + actually only FILE:// just now, and it can't pause since the transfer + isn't done using the "normal" procedure. */ + failf(data, "Read callback asked for PAUSE when not supported!"); + return CURLE_READ_ERROR; + } + + /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */ + k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */ + if(data->req.upload_chunky) { + /* Back out the preallocation done above */ + data->req.upload_fromhere -= (8 + 2); + } + *nreadp = 0; + + return CURLE_OK; /* nothing was read */ + } + else if(nread > buffersize) { + /* the read function returned a too large value */ + *nreadp = 0; + failf(data, "read function returned funny value"); + return CURLE_READ_ERROR; + } + + if(!data->req.forbidchunk && data->req.upload_chunky) { + /* if chunked Transfer-Encoding + * build chunk: + * + * CRLF + * CRLF + */ + /* On non-ASCII platforms the may or may not be + translated based on set.prefer_ascii while the protocol + portion must always be translated to the network encoding. + To further complicate matters, line end conversion might be + done later on, so we need to prevent CRLFs from becoming + CRCRLFs if that's the case. To do this we use bare LFs + here, knowing they'll become CRLFs later on. + */ + + bool added_crlf = FALSE; + int hexlen = 0; + const char *endofline_native; + const char *endofline_network; + + if( +#ifdef CURL_DO_LINEEND_CONV + (data->set.prefer_ascii) || +#endif + (data->set.crlf)) { + /* \n will become \r\n later on */ + endofline_native = "\n"; + endofline_network = "\x0a"; + } + else { + endofline_native = "\r\n"; + endofline_network = "\x0d\x0a"; + } + + /* if we're not handling trailing data, proceed as usual */ + if(data->state.trailers_state != TRAILERS_SENDING) { + char hexbuffer[11] = ""; + hexlen = msnprintf(hexbuffer, sizeof(hexbuffer), + "%zx%s", nread, endofline_native); + + /* move buffer pointer */ + data->req.upload_fromhere -= hexlen; + nread += hexlen; + + /* copy the prefix to the buffer, leaving out the NUL */ + memcpy(data->req.upload_fromhere, hexbuffer, hexlen); + + /* always append ASCII CRLF to the data unless + we have a valid trailer callback */ +#ifndef CURL_DISABLE_HTTP + if((nread-hexlen) == 0 && + data->set.trailer_callback != NULL && + data->state.trailers_state == TRAILERS_NONE) { + data->state.trailers_state = TRAILERS_INITIALIZED; + } + else +#endif + { + memcpy(data->req.upload_fromhere + nread, + endofline_network, + strlen(endofline_network)); + added_crlf = TRUE; + } + } + +#ifdef CURL_DOES_CONVERSIONS + { + CURLcode result; + size_t length; + if(data->set.prefer_ascii) + /* translate the protocol and data */ + length = nread; + else + /* just translate the protocol portion */ + length = hexlen; + if(length) { + result = Curl_convert_to_network(data, data->req.upload_fromhere, + length); + /* Curl_convert_to_network calls failf if unsuccessful */ + if(result) + return result; + } + } +#endif /* CURL_DOES_CONVERSIONS */ + +#ifndef CURL_DISABLE_HTTP + if(data->state.trailers_state == TRAILERS_SENDING && + !Curl_trailers_left(data)) { + Curl_add_buffer_free(&data->state.trailers_buf); + data->state.trailers_state = TRAILERS_DONE; + data->set.trailer_data = NULL; + data->set.trailer_callback = NULL; + /* mark the transfer as done */ + data->req.upload_done = TRUE; + infof(data, "Signaling end of chunked upload after trailers.\n"); + } + else +#endif + if((nread - hexlen) == 0 && + data->state.trailers_state != TRAILERS_INITIALIZED) { + /* mark this as done once this chunk is transferred */ + data->req.upload_done = TRUE; + infof(data, + "Signaling end of chunked upload via terminating chunk.\n"); + } + + if(added_crlf) + nread += strlen(endofline_network); /* for the added end of line */ + } +#ifdef CURL_DOES_CONVERSIONS + else if((data->set.prefer_ascii) && (!sending_http_headers)) { + CURLcode result; + result = Curl_convert_to_network(data, data->req.upload_fromhere, nread); + /* Curl_convert_to_network calls failf if unsuccessful */ + if(result) + return result; + } +#endif /* CURL_DOES_CONVERSIONS */ + + *nreadp = nread; + + return CURLE_OK; +} + + +/* + * Curl_readrewind() rewinds the read stream. This is typically used for HTTP + * POST/PUT with multi-pass authentication when a sending was denied and a + * resend is necessary. + */ +CURLcode Curl_readrewind(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + curl_mimepart *mimepart = &data->set.mimepost; + + conn->bits.rewindaftersend = FALSE; /* we rewind now */ + + /* explicitly switch off sending data on this connection now since we are + about to restart a new transfer and thus we want to avoid inadvertently + sending more data on the existing connection until the next transfer + starts */ + data->req.keepon &= ~KEEP_SEND; + + /* We have sent away data. If not using CURLOPT_POSTFIELDS or + CURLOPT_HTTPPOST, call app to rewind + */ + if(conn->handler->protocol & PROTO_FAMILY_HTTP) { + struct HTTP *http = data->req.protop; + + if(http->sendit) + mimepart = http->sendit; + } + if(data->set.postfields) + ; /* do nothing */ + else if(data->set.httpreq == HTTPREQ_POST_MIME || + data->set.httpreq == HTTPREQ_POST_FORM) { + if(Curl_mime_rewind(mimepart)) { + failf(data, "Cannot rewind mime/post data"); + return CURLE_SEND_FAIL_REWIND; + } + } + else { + if(data->set.seek_func) { + int err; + + Curl_set_in_callback(data, true); + err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET); + Curl_set_in_callback(data, false); + if(err) { + failf(data, "seek callback returned error %d", (int)err); + return CURLE_SEND_FAIL_REWIND; + } + } + else if(data->set.ioctl_func) { + curlioerr err; + + Curl_set_in_callback(data, true); + err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD, + data->set.ioctl_client); + Curl_set_in_callback(data, false); + infof(data, "the ioctl callback returned %d\n", (int)err); + + if(err) { + failf(data, "ioctl callback returned error %d", (int)err); + return CURLE_SEND_FAIL_REWIND; + } + } + else { + /* If no CURLOPT_READFUNCTION is used, we know that we operate on a + given FILE * stream and we can actually attempt to rewind that + ourselves with fseek() */ + if(data->state.fread_func == (curl_read_callback)fread) { + if(-1 != fseek(data->state.in, 0, SEEK_SET)) + /* successful rewind */ + return CURLE_OK; + } + + /* no callback set or failure above, makes us fail at once */ + failf(data, "necessary data rewind wasn't possible"); + return CURLE_SEND_FAIL_REWIND; + } + } + return CURLE_OK; +} + +static int data_pending(const struct connectdata *conn) +{ + /* in the case of libssh2, we can never be really sure that we have emptied + its internal buffers so we MUST always try until we get EAGAIN back */ + return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) || +#if defined(USE_NGHTTP2) + Curl_ssl_data_pending(conn, FIRSTSOCKET) || + /* For HTTP/2, we may read up everything including response body + with header fields in Curl_http_readwrite_headers. If no + content-length is provided, curl waits for the connection + close, which we emulate it using conn->proto.httpc.closed = + TRUE. The thing is if we read everything, then http2_recv won't + be called and we cannot signal the HTTP/2 stream has closed. As + a workaround, we return nonzero here to call http2_recv. */ + ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion == 20); +#else + Curl_ssl_data_pending(conn, FIRSTSOCKET); +#endif +} + +/* + * Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the + * remote document with the time provided by CURLOPT_TIMEVAL + */ +bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc) +{ + if((timeofdoc == 0) || (data->set.timevalue == 0)) + return TRUE; + + switch(data->set.timecondition) { + case CURL_TIMECOND_IFMODSINCE: + default: + if(timeofdoc <= data->set.timevalue) { + infof(data, + "The requested document is not new enough\n"); + data->info.timecond = TRUE; + return FALSE; + } + break; + case CURL_TIMECOND_IFUNMODSINCE: + if(timeofdoc >= data->set.timevalue) { + infof(data, + "The requested document is not old enough\n"); + data->info.timecond = TRUE; + return FALSE; + } + break; + } + + return TRUE; +} + +/* + * Go ahead and do a read if we have a readable socket or if + * the stream was rewound (in which case we have data in a + * buffer) + * + * return '*comeback' TRUE if we didn't properly drain the socket so this + * function should get called again without select() or similar in between! + */ +static CURLcode readwrite_data(struct Curl_easy *data, + struct connectdata *conn, + struct SingleRequest *k, + int *didwhat, bool *done, + bool *comeback) +{ + CURLcode result = CURLE_OK; + ssize_t nread; /* number of bytes read */ + size_t excess = 0; /* excess bytes read */ + bool readmore = FALSE; /* used by RTP to signal for more data */ + int maxloops = 100; + + *done = FALSE; + *comeback = FALSE; + + /* This is where we loop until we have read everything there is to + read or we get a CURLE_AGAIN */ + do { + bool is_empty_data = FALSE; + size_t buffersize = data->set.buffer_size; + size_t bytestoread = buffersize; + + if( +#if defined(USE_NGHTTP2) + /* For HTTP/2, read data without caring about the content + length. This is safe because body in HTTP/2 is always + segmented thanks to its framing layer. Meanwhile, we have to + call Curl_read to ensure that http2_handle_stream_close is + called when we read all incoming bytes for a particular + stream. */ + !((conn->handler->protocol & PROTO_FAMILY_HTTP) && + conn->httpversion == 20) && +#endif + k->size != -1 && !k->header) { + /* make sure we don't read too much */ + curl_off_t totalleft = k->size - k->bytecount; + if(totalleft < (curl_off_t)bytestoread) + bytestoread = (size_t)totalleft; + } + + if(bytestoread) { + /* receive data from the network! */ + result = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread); + + /* read would've blocked */ + if(CURLE_AGAIN == result) + break; /* get out of loop */ + + if(result>0) + return result; + } + else { + /* read nothing but since we wanted nothing we consider this an OK + situation to proceed from */ + DEBUGF(infof(data, "readwrite_data: we're done!\n")); + nread = 0; + } + + if((k->bytecount == 0) && (k->writebytecount == 0)) { + Curl_pgrsTime(data, TIMER_STARTTRANSFER); + if(k->exp100 > EXP100_SEND_DATA) + /* set time stamp to compare with when waiting for the 100 */ + k->start100 = Curl_now(); + } + + *didwhat |= KEEP_RECV; + /* indicates data of zero size, i.e. empty file */ + is_empty_data = ((nread == 0) && (k->bodywrites == 0)) ? TRUE : FALSE; + + /* NUL terminate, allowing string ops to be used */ + if(0 < nread || is_empty_data) { + k->buf[nread] = 0; + } + else { + /* if we receive 0 or less here, the server closed the connection + and we bail out from this! */ + DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n")); + k->keepon &= ~KEEP_RECV; + break; + } + + /* Default buffer to use when we write the buffer, it may be changed + in the flow below before the actual storing is done. */ + k->str = k->buf; + + if(conn->handler->readwrite) { + result = conn->handler->readwrite(data, conn, &nread, &readmore); + if(result) + return result; + if(readmore) + break; + } + +#ifndef CURL_DISABLE_HTTP + /* Since this is a two-state thing, we check if we are parsing + headers at the moment or not. */ + if(k->header) { + /* we are in parse-the-header-mode */ + bool stop_reading = FALSE; + result = Curl_http_readwrite_headers(data, conn, &nread, &stop_reading); + if(result) + return result; + + if(conn->handler->readwrite && + (k->maxdownload <= 0 && nread > 0)) { + result = conn->handler->readwrite(data, conn, &nread, &readmore); + if(result) + return result; + if(readmore) + break; + } + + if(stop_reading) { + /* We've stopped dealing with input, get out of the do-while loop */ + + if(nread > 0) { + infof(data, + "Excess found:" + " excess = %zd" + " url = %s (zero-length body)\n", + nread, data->state.up.path); + } + + break; + } + } +#endif /* CURL_DISABLE_HTTP */ + + + /* This is not an 'else if' since it may be a rest from the header + parsing, where the beginning of the buffer is headers and the end + is non-headers. */ + if(k->str && !k->header && (nread > 0 || is_empty_data)) { + + if(data->set.opt_no_body) { + /* data arrives although we want none, bail out */ + streamclose(conn, "ignoring body"); + *done = TRUE; + return CURLE_WEIRD_SERVER_REPLY; + } + +#ifndef CURL_DISABLE_HTTP + if(0 == k->bodywrites && !is_empty_data) { + /* These checks are only made the first time we are about to + write a piece of the body */ + if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) { + /* HTTP-only checks */ + + if(data->req.newurl) { + if(conn->bits.close) { + /* Abort after the headers if "follow Location" is set + and we're set to close anyway. */ + k->keepon &= ~KEEP_RECV; + *done = TRUE; + return CURLE_OK; + } + /* We have a new url to load, but since we want to be able + to re-use this connection properly, we read the full + response in "ignore more" */ + k->ignorebody = TRUE; + infof(data, "Ignoring the response-body\n"); + } + if(data->state.resume_from && !k->content_range && + (data->set.httpreq == HTTPREQ_GET) && + !k->ignorebody) { + + if(k->size == data->state.resume_from) { + /* The resume point is at the end of file, consider this fine + even if it doesn't allow resume from here. */ + infof(data, "The entire document is already downloaded"); + connclose(conn, "already downloaded"); + /* Abort download */ + k->keepon &= ~KEEP_RECV; + *done = TRUE; + return CURLE_OK; + } + + /* we wanted to resume a download, although the server doesn't + * seem to support this and we did this with a GET (if it + * wasn't a GET we did a POST or PUT resume) */ + failf(data, "HTTP server doesn't seem to support " + "byte ranges. Cannot resume."); + return CURLE_RANGE_ERROR; + } + + if(data->set.timecondition && !data->state.range) { + /* A time condition has been set AND no ranges have been + requested. This seems to be what chapter 13.3.4 of + RFC 2616 defines to be the correct action for a + HTTP/1.1 client */ + + if(!Curl_meets_timecondition(data, k->timeofdoc)) { + *done = TRUE; + /* We're simulating a http 304 from server so we return + what should have been returned from the server */ + data->info.httpcode = 304; + infof(data, "Simulate a HTTP 304 response!\n"); + /* we abort the transfer before it is completed == we ruin the + re-use ability. Close the connection */ + connclose(conn, "Simulated 304 handling"); + return CURLE_OK; + } + } /* we have a time condition */ + + } /* this is HTTP or RTSP */ + } /* this is the first time we write a body part */ +#endif /* CURL_DISABLE_HTTP */ + + k->bodywrites++; + + /* pass data to the debug function before it gets "dechunked" */ + if(data->set.verbose) { + if(k->badheader) { + Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff, + (size_t)k->hbuflen); + if(k->badheader == HEADER_PARTHEADER) + Curl_debug(data, CURLINFO_DATA_IN, + k->str, (size_t)nread); + } + else + Curl_debug(data, CURLINFO_DATA_IN, + k->str, (size_t)nread); + } + +#ifndef CURL_DISABLE_HTTP + if(k->chunk) { + /* + * Here comes a chunked transfer flying and we need to decode this + * properly. While the name says read, this function both reads + * and writes away the data. The returned 'nread' holds the number + * of actual data it wrote to the client. + */ + + CHUNKcode res = + Curl_httpchunk_read(conn, k->str, nread, &nread); + + if(CHUNKE_OK < res) { + if(CHUNKE_WRITE_ERROR == res) { + failf(data, "Failed writing data"); + return CURLE_WRITE_ERROR; + } + failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res)); + return CURLE_RECV_ERROR; + } + if(CHUNKE_STOP == res) { + size_t dataleft; + /* we're done reading chunks! */ + k->keepon &= ~KEEP_RECV; /* read no more */ + + /* There are now possibly N number of bytes at the end of the + str buffer that weren't written to the client. + Push it back to be read on the next pass. */ + + dataleft = conn->chunk.dataleft; + if(dataleft != 0) { + infof(conn->data, "Leftovers after chunking: %zu bytes\n", + dataleft); + } + } + /* If it returned OK, we just keep going */ + } +#endif /* CURL_DISABLE_HTTP */ + + /* Account for body content stored in the header buffer */ + if((k->badheader == HEADER_PARTHEADER) && !k->ignorebody) { + DEBUGF(infof(data, "Increasing bytecount by %zu from hbuflen\n", + k->hbuflen)); + k->bytecount += k->hbuflen; + } + + if((-1 != k->maxdownload) && + (k->bytecount + nread >= k->maxdownload)) { + + excess = (size_t)(k->bytecount + nread - k->maxdownload); + if(excess > 0 && !k->ignorebody) { + infof(data, + "Excess found in a read:" + " excess = %zu" + ", size = %" CURL_FORMAT_CURL_OFF_T + ", maxdownload = %" CURL_FORMAT_CURL_OFF_T + ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n", + excess, k->size, k->maxdownload, k->bytecount); + } + + nread = (ssize_t) (k->maxdownload - k->bytecount); + if(nread < 0) /* this should be unusual */ + nread = 0; + + k->keepon &= ~KEEP_RECV; /* we're done reading */ + } + + k->bytecount += nread; + + Curl_pgrsSetDownloadCounter(data, k->bytecount); + + if(!k->chunk && (nread || k->badheader || is_empty_data)) { + /* If this is chunky transfer, it was already written */ + + if(k->badheader && !k->ignorebody) { + /* we parsed a piece of data wrongly assuming it was a header + and now we output it as body instead */ + + /* Don't let excess data pollute body writes */ + if(k->maxdownload == -1 || (curl_off_t)k->hbuflen <= k->maxdownload) + result = Curl_client_write(conn, CLIENTWRITE_BODY, + data->state.headerbuff, + k->hbuflen); + else + result = Curl_client_write(conn, CLIENTWRITE_BODY, + data->state.headerbuff, + (size_t)k->maxdownload); + + if(result) + return result; + } + if(k->badheader < HEADER_ALLBAD) { + /* This switch handles various content encodings. If there's an + error here, be sure to check over the almost identical code + in http_chunks.c. + Make sure that ALL_CONTENT_ENCODINGS contains all the + encodings handled here. */ + if(conn->data->set.http_ce_skip || !k->writer_stack) { + if(!k->ignorebody) { +#ifndef CURL_DISABLE_POP3 + if(conn->handler->protocol & PROTO_FAMILY_POP3) + result = Curl_pop3_write(conn, k->str, nread); + else +#endif /* CURL_DISABLE_POP3 */ + result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str, + nread); + } + } + else if(!k->ignorebody) + result = Curl_unencode_write(conn, k->writer_stack, k->str, nread); + } + k->badheader = HEADER_NORMAL; /* taken care of now */ + + if(result) + return result; + } + + } /* if(!header and data to read) */ + + if(conn->handler->readwrite && excess && !conn->bits.stream_was_rewound) { + /* Parse the excess data */ + k->str += nread; + + if(&k->str[excess] > &k->buf[data->set.buffer_size]) { + /* the excess amount was too excessive(!), make sure + it doesn't read out of buffer */ + excess = &k->buf[data->set.buffer_size] - k->str; + } + nread = (ssize_t)excess; + + result = conn->handler->readwrite(data, conn, &nread, &readmore); + if(result) + return result; + + if(readmore) + k->keepon |= KEEP_RECV; /* we're not done reading */ + break; + } + + if(is_empty_data) { + /* if we received nothing, the server closed the connection and we + are done */ + k->keepon &= ~KEEP_RECV; + } + + if(k->keepon & KEEP_RECV_PAUSE) { + /* this is a paused transfer */ + break; + } + + } while(data_pending(conn) && maxloops--); + + if(maxloops <= 0) { + /* we mark it as read-again-please */ + conn->cselect_bits = CURL_CSELECT_IN; + *comeback = TRUE; + } + + if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) && + conn->bits.close) { + /* When we've read the entire thing and the close bit is set, the server + may now close the connection. If there's now any kind of sending going + on from our side, we need to stop that immediately. */ + infof(data, "we are done reading and this is set to close, stop send\n"); + k->keepon &= ~KEEP_SEND; /* no writing anymore either */ + } + + return CURLE_OK; +} + +CURLcode Curl_done_sending(struct connectdata *conn, + struct SingleRequest *k) +{ + k->keepon &= ~KEEP_SEND; /* we're done writing */ + + Curl_http2_done_sending(conn); + + if(conn->bits.rewindaftersend) { + CURLcode result = Curl_readrewind(conn); + if(result) + return result; + } + return CURLE_OK; +} + +#if defined(WIN32) && !defined(USE_LWIPSOCK) +#ifndef SIO_IDEAL_SEND_BACKLOG_QUERY +#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B +#endif + +#ifdef _XBOX +static void win_update_buffer_size(curl_socket_t sockfd) +{ + // Xbox does not support WSAIoctl, so do nothing + (void)sockfd; // Prevents unused variable warning +} +#else +static void win_update_buffer_size(curl_socket_t sockfd) +{ + int result; + ULONG ideal; + DWORD ideallen; + result = WSAIoctl(sockfd, SIO_IDEAL_SEND_BACKLOG_QUERY, 0, 0, + &ideal, sizeof(ideal), &ideallen, 0, 0); + if(result == 0) { + setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, + (const char *)&ideal, sizeof(ideal)); + } +} +#endif // _XBOX + +#else +#define win_update_buffer_size(x) +#endif + +/* + * Send data to upload to the server, when the socket is writable. + */ +static CURLcode readwrite_upload(struct Curl_easy *data, + struct connectdata *conn, + int *didwhat) +{ + ssize_t i, si; + ssize_t bytes_written; + CURLcode result; + ssize_t nread; /* number of bytes read */ + bool sending_http_headers = FALSE; + struct SingleRequest *k = &data->req; + + if((k->bytecount == 0) && (k->writebytecount == 0)) + Curl_pgrsTime(data, TIMER_STARTTRANSFER); + + *didwhat |= KEEP_SEND; + + do { + /* only read more data if there's no upload data already + present in the upload buffer */ + if(0 == k->upload_present) { + result = Curl_get_upload_buffer(data); + if(result) + return result; + /* init the "upload from here" pointer */ + k->upload_fromhere = data->state.ulbuf; + + if(!k->upload_done) { + /* HTTP pollution, this should be written nicer to become more + protocol agnostic. */ + size_t fillcount; + struct HTTP *http = k->protop; + + if((k->exp100 == EXP100_SENDING_REQUEST) && + (http->sending == HTTPSEND_BODY)) { + /* If this call is to send body data, we must take some action: + We have sent off the full HTTP 1.1 request, and we shall now + go into the Expect: 100 state and await such a header */ + k->exp100 = EXP100_AWAITING_CONTINUE; /* wait for the header */ + k->keepon &= ~KEEP_SEND; /* disable writing */ + k->start100 = Curl_now(); /* timeout count starts now */ + *didwhat &= ~KEEP_SEND; /* we didn't write anything actually */ + /* set a timeout for the multi interface */ + Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT); + break; + } + + if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) { + if(http->sending == HTTPSEND_REQUEST) + /* We're sending the HTTP request headers, not the data. + Remember that so we don't change the line endings. */ + sending_http_headers = TRUE; + else + sending_http_headers = FALSE; + } + + result = Curl_fillreadbuffer(conn, data->set.upload_buffer_size, + &fillcount); + if(result) + return result; + + nread = fillcount; + } + else + nread = 0; /* we're done uploading/reading */ + + if(!nread && (k->keepon & KEEP_SEND_PAUSE)) { + /* this is a paused transfer */ + break; + } + if(nread <= 0) { + result = Curl_done_sending(conn, k); + if(result) + return result; + break; + } + + /* store number of bytes available for upload */ + k->upload_present = nread; + + /* convert LF to CRLF if so asked */ + if((!sending_http_headers) && ( +#ifdef CURL_DO_LINEEND_CONV + /* always convert if we're FTPing in ASCII mode */ + (data->set.prefer_ascii) || +#endif + (data->set.crlf))) { + /* Do we need to allocate a scratch buffer? */ + if(!data->state.scratch) { + data->state.scratch = malloc(2 * data->set.upload_buffer_size); + if(!data->state.scratch) { + failf(data, "Failed to alloc scratch buffer!"); + + return CURLE_OUT_OF_MEMORY; + } + } + + /* + * ASCII/EBCDIC Note: This is presumably a text (not binary) + * transfer so the data should already be in ASCII. + * That means the hex values for ASCII CR (0x0d) & LF (0x0a) + * must be used instead of the escape sequences \r & \n. + */ + for(i = 0, si = 0; i < nread; i++, si++) { + if(k->upload_fromhere[i] == 0x0a) { + data->state.scratch[si++] = 0x0d; + data->state.scratch[si] = 0x0a; + if(!data->set.crlf) { + /* we're here only because FTP is in ASCII mode... + bump infilesize for the LF we just added */ + if(data->state.infilesize != -1) + data->state.infilesize++; + } + } + else + data->state.scratch[si] = k->upload_fromhere[i]; + } + + if(si != nread) { + /* only perform the special operation if we really did replace + anything */ + nread = si; + + /* upload from the new (replaced) buffer instead */ + k->upload_fromhere = data->state.scratch; + + /* set the new amount too */ + k->upload_present = nread; + } + } + +#ifndef CURL_DISABLE_SMTP + if(conn->handler->protocol & PROTO_FAMILY_SMTP) { + result = Curl_smtp_escape_eob(conn, nread); + if(result) + return result; + } +#endif /* CURL_DISABLE_SMTP */ + } /* if 0 == k->upload_present */ + else { + /* We have a partial buffer left from a previous "round". Use + that instead of reading more data */ + } + + /* write to socket (send away data) */ + result = Curl_write(conn, + conn->writesockfd, /* socket to send to */ + k->upload_fromhere, /* buffer pointer */ + k->upload_present, /* buffer size */ + &bytes_written); /* actually sent */ + if(result) + return result; + + win_update_buffer_size(conn->writesockfd); + + if(data->set.verbose) + /* show the data before we change the pointer upload_fromhere */ + Curl_debug(data, CURLINFO_DATA_OUT, k->upload_fromhere, + (size_t)bytes_written); + + k->writebytecount += bytes_written; + Curl_pgrsSetUploadCounter(data, k->writebytecount); + + if((!k->upload_chunky || k->forbidchunk) && + (k->writebytecount == data->state.infilesize)) { + /* we have sent all data we were supposed to */ + k->upload_done = TRUE; + infof(data, "We are completely uploaded and fine\n"); + } + + if(k->upload_present != bytes_written) { + /* we only wrote a part of the buffer (if anything), deal with it! */ + + /* store the amount of bytes left in the buffer to write */ + k->upload_present -= bytes_written; + + /* advance the pointer where to find the buffer when the next send + is to happen */ + k->upload_fromhere += bytes_written; + } + else { + /* we've uploaded that buffer now */ + result = Curl_get_upload_buffer(data); + if(result) + return result; + k->upload_fromhere = data->state.ulbuf; + k->upload_present = 0; /* no more bytes left */ + + if(k->upload_done) { + result = Curl_done_sending(conn, k); + if(result) + return result; + } + } + + + } WHILE_FALSE; /* just to break out from! */ + + return CURLE_OK; +} + +/* + * Curl_readwrite() is the low-level function to be called when data is to + * be read and written to/from the connection. + * + * return '*comeback' TRUE if we didn't properly drain the socket so this + * function should get called again without select() or similar in between! + */ +CURLcode Curl_readwrite(struct connectdata *conn, + struct Curl_easy *data, + bool *done, + bool *comeback) +{ + struct SingleRequest *k = &data->req; + CURLcode result; + int didwhat = 0; + + curl_socket_t fd_read; + curl_socket_t fd_write; + int select_res = conn->cselect_bits; + + conn->cselect_bits = 0; + + /* only use the proper socket if the *_HOLD bit is not set simultaneously as + then we are in rate limiting state in that transfer direction */ + + if((k->keepon & KEEP_RECVBITS) == KEEP_RECV) + fd_read = conn->sockfd; + else + fd_read = CURL_SOCKET_BAD; + + if((k->keepon & KEEP_SENDBITS) == KEEP_SEND) + fd_write = conn->writesockfd; + else + fd_write = CURL_SOCKET_BAD; + + if(conn->data->state.drain) { + select_res |= CURL_CSELECT_IN; + DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n")); + } + + if(!select_res) /* Call for select()/poll() only, if read/write/error + status is not known. */ + select_res = Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, 0); + + if(select_res == CURL_CSELECT_ERR) { + failf(data, "select/poll returned error"); + return CURLE_SEND_ERROR; + } + + /* We go ahead and do a read if we have a readable socket or if + the stream was rewound (in which case we have data in a + buffer) */ + if((k->keepon & KEEP_RECV) && + ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) { + + result = readwrite_data(data, conn, k, &didwhat, done, comeback); + if(result || *done) + return result; + } + + /* If we still have writing to do, we check if we have a writable socket. */ + if((k->keepon & KEEP_SEND) && (select_res & CURL_CSELECT_OUT)) { + /* write */ + + result = readwrite_upload(data, conn, &didwhat); + if(result) + return result; + } + + k->now = Curl_now(); + if(didwhat) { + ; + } + else { + /* no read no write, this is a timeout? */ + if(k->exp100 == EXP100_AWAITING_CONTINUE) { + /* This should allow some time for the header to arrive, but only a + very short time as otherwise it'll be too much wasted time too + often. */ + + /* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status": + + Therefore, when a client sends this header field to an origin server + (possibly via a proxy) from which it has never seen a 100 (Continue) + status, the client SHOULD NOT wait for an indefinite period before + sending the request body. + + */ + + timediff_t ms = Curl_timediff(k->now, k->start100); + if(ms >= data->set.expect_100_timeout) { + /* we've waited long enough, continue anyway */ + k->exp100 = EXP100_SEND_DATA; + k->keepon |= KEEP_SEND; + Curl_expire_done(data, EXPIRE_100_TIMEOUT); + infof(data, "Done waiting for 100-continue\n"); + } + } + } + + if(Curl_pgrsUpdate(conn)) + result = CURLE_ABORTED_BY_CALLBACK; + else + result = Curl_speedcheck(data, k->now); + if(result) + return result; + + if(k->keepon) { + if(0 > Curl_timeleft(data, &k->now, FALSE)) { + if(k->size != -1) { + failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" + CURL_FORMAT_CURL_OFF_T " bytes received", + Curl_timediff(k->now, data->progress.t_startsingle), + k->bytecount, k->size); + } + else { + failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds with %" CURL_FORMAT_CURL_OFF_T " bytes received", + Curl_timediff(k->now, data->progress.t_startsingle), + k->bytecount); + } + return CURLE_OPERATION_TIMEDOUT; + } + } + else { + /* + * The transfer has been performed. Just make some general checks before + * returning. + */ + + if(!(data->set.opt_no_body) && (k->size != -1) && + (k->bytecount != k->size) && +#ifdef CURL_DO_LINEEND_CONV + /* Most FTP servers don't adjust their file SIZE response for CRLFs, + so we'll check to see if the discrepancy can be explained + by the number of CRLFs we've changed to LFs. + */ + (k->bytecount != (k->size + data->state.crlf_conversions)) && +#endif /* CURL_DO_LINEEND_CONV */ + !k->newurl) { + failf(data, "transfer closed with %" CURL_FORMAT_CURL_OFF_T + " bytes remaining to read", k->size - k->bytecount); + return CURLE_PARTIAL_FILE; + } + if(!(data->set.opt_no_body) && k->chunk && + (conn->chunk.state != CHUNK_STOP)) { + /* + * In chunked mode, return an error if the connection is closed prior to + * the empty (terminating) chunk is read. + * + * The condition above used to check for + * conn->proto.http->chunk.datasize != 0 which is true after reading + * *any* chunk, not just the empty chunk. + * + */ + failf(data, "transfer closed with outstanding read data remaining"); + return CURLE_PARTIAL_FILE; + } + if(Curl_pgrsUpdate(conn)) + return CURLE_ABORTED_BY_CALLBACK; + } + + /* Now update the "done" boolean we return */ + *done = (0 == (k->keepon&(KEEP_RECV|KEEP_SEND| + KEEP_RECV_PAUSE|KEEP_SEND_PAUSE))) ? TRUE : FALSE; + + return CURLE_OK; +} + +/* + * Curl_single_getsock() gets called by the multi interface code when the app + * has requested to get the sockets for the current connection. This function + * will then be called once for every connection that the multi interface + * keeps track of. This function will only be called for connections that are + * in the proper state to have this information available. + */ +int Curl_single_getsock(const struct connectdata *conn, + curl_socket_t *sock, /* points to numsocks number + of sockets */ + int numsocks) +{ + const struct Curl_easy *data = conn->data; + int bitmap = GETSOCK_BLANK; + unsigned sockindex = 0; + + if(conn->handler->perform_getsock) + return conn->handler->perform_getsock(conn, sock, numsocks); + + if(numsocks < 2) + /* simple check but we might need two slots */ + return GETSOCK_BLANK; + + /* don't include HOLD and PAUSE connections */ + if((data->req.keepon & KEEP_RECVBITS) == KEEP_RECV) { + + DEBUGASSERT(conn->sockfd != CURL_SOCKET_BAD); + + bitmap |= GETSOCK_READSOCK(sockindex); + sock[sockindex] = conn->sockfd; + } + + /* don't include HOLD and PAUSE connections */ + if((data->req.keepon & KEEP_SENDBITS) == KEEP_SEND) { + + if((conn->sockfd != conn->writesockfd) || + bitmap == GETSOCK_BLANK) { + /* only if they are not the same socket and we have a readable + one, we increase index */ + if(bitmap != GETSOCK_BLANK) + sockindex++; /* increase index if we need two entries */ + + DEBUGASSERT(conn->writesockfd != CURL_SOCKET_BAD); + + sock[sockindex] = conn->writesockfd; + } + + bitmap |= GETSOCK_WRITESOCK(sockindex); + } + + return bitmap; +} + +/* Curl_init_CONNECT() gets called each time the handle switches to CONNECT + which means this gets called once for each subsequent redirect etc */ +void Curl_init_CONNECT(struct Curl_easy *data) +{ + data->state.fread_func = data->set.fread_func_set; + data->state.in = data->set.in_set; +} + +/* + * Curl_pretransfer() is called immediately before a transfer starts, and only + * once for one transfer no matter if it has redirects or do multi-pass + * authentication etc. + */ +CURLcode Curl_pretransfer(struct Curl_easy *data) +{ + CURLcode result; + + if(!data->change.url && !data->set.uh) { + /* we can't do anything without URL */ + failf(data, "No URL set!"); + return CURLE_URL_MALFORMAT; + } + + /* since the URL may have been redirected in a previous use of this handle */ + if(data->change.url_alloc) { + /* the already set URL is allocated, free it first! */ + Curl_safefree(data->change.url); + data->change.url_alloc = FALSE; + } + + if(!data->change.url && data->set.uh) { + CURLUcode uc; + uc = curl_url_get(data->set.uh, + CURLUPART_URL, &data->set.str[STRING_SET_URL], 0); + if(uc) { + failf(data, "No URL set!"); + return CURLE_URL_MALFORMAT; + } + } + + data->change.url = data->set.str[STRING_SET_URL]; + + /* Init the SSL session ID cache here. We do it here since we want to do it + after the *_setopt() calls (that could specify the size of the cache) but + before any transfer takes place. */ + result = Curl_ssl_initsessions(data, data->set.general_ssl.max_ssl_sessions); + if(result) + return result; + + data->state.wildcardmatch = data->set.wildcard_enabled; + data->set.followlocation = 0; /* reset the location-follow counter */ + data->state.this_is_a_follow = FALSE; /* reset this */ + data->state.errorbuf = FALSE; /* no error has occurred */ + data->state.httpversion = 0; /* don't assume any particular server version */ + + data->state.authproblem = FALSE; + data->state.authhost.want = data->set.httpauth; + data->state.authproxy.want = data->set.proxyauth; + Curl_safefree(data->info.wouldredirect); + data->info.wouldredirect = NULL; + + if(data->set.httpreq == HTTPREQ_PUT) + data->state.infilesize = data->set.filesize; + else if((data->set.httpreq != HTTPREQ_GET) && + (data->set.httpreq != HTTPREQ_HEAD)) { + data->state.infilesize = data->set.postfieldsize; + if(data->set.postfields && (data->state.infilesize == -1)) + data->state.infilesize = (curl_off_t)strlen(data->set.postfields); + } + else + data->state.infilesize = 0; + + /* If there is a list of cookie files to read, do it now! */ + if(data->change.cookielist) + Curl_cookie_loadfiles(data); + + /* If there is a list of host pairs to deal with */ + if(data->change.resolve) + result = Curl_loadhostpairs(data); + + if(!result) { + /* Allow data->set.use_port to set which port to use. This needs to be + * disabled for example when we follow Location: headers to URLs using + * different ports! */ + data->state.allow_port = TRUE; + +#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) + /************************************************************* + * Tell signal handler to ignore SIGPIPE + *************************************************************/ + if(!data->set.no_signal) + data->state.prev_signal = signal(SIGPIPE, SIG_IGN); +#endif + + Curl_initinfo(data); /* reset session-specific information "variables" */ + Curl_pgrsResetTransferSizes(data); + Curl_pgrsStartNow(data); + + /* In case the handle is re-used and an authentication method was picked + in the session we need to make sure we only use the one(s) we now + consider to be fine */ + data->state.authhost.picked &= data->state.authhost.want; + data->state.authproxy.picked &= data->state.authproxy.want; + +#ifndef CURL_DISABLE_FTP + if(data->state.wildcardmatch) { + struct WildcardData *wc = &data->wildcard; + if(wc->state < CURLWC_INIT) { + result = Curl_wildcard_init(wc); /* init wildcard structures */ + if(result) + return CURLE_OUT_OF_MEMORY; + } + } +#endif + } + + return result; +} + +/* + * Curl_posttransfer() is called immediately after a transfer ends + */ +CURLcode Curl_posttransfer(struct Curl_easy *data) +{ +#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) + /* restore the signal handler for SIGPIPE before we get back */ + if(!data->set.no_signal) + signal(SIGPIPE, data->state.prev_signal); +#else + (void)data; /* unused parameter */ +#endif + + return CURLE_OK; +} + +/* + * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string + * as given by the remote server and set up the new URL to request. + * + * This function DOES NOT FREE the given url. + */ +CURLcode Curl_follow(struct Curl_easy *data, + char *newurl, /* the Location: string */ + followtype type) /* see transfer.h */ +{ +#ifdef CURL_DISABLE_HTTP + (void)data; + (void)newurl; + (void)type; + /* Location: following will not happen when HTTP is disabled */ + return CURLE_TOO_MANY_REDIRECTS; +#else + + /* Location: redirect */ + bool disallowport = FALSE; + bool reachedmax = FALSE; + CURLUcode uc; + + if(type == FOLLOW_REDIR) { + if((data->set.maxredirs != -1) && + (data->set.followlocation >= data->set.maxredirs)) { + reachedmax = TRUE; + type = FOLLOW_FAKE; /* switch to fake to store the would-be-redirected + to URL */ + } + else { + /* mark the next request as a followed location: */ + data->state.this_is_a_follow = TRUE; + + data->set.followlocation++; /* count location-followers */ + + if(data->set.http_auto_referer) { + /* We are asked to automatically set the previous URL as the referer + when we get the next URL. We pick the ->url field, which may or may + not be 100% correct */ + + if(data->change.referer_alloc) { + Curl_safefree(data->change.referer); + data->change.referer_alloc = FALSE; + } + + data->change.referer = strdup(data->change.url); + if(!data->change.referer) + return CURLE_OUT_OF_MEMORY; + data->change.referer_alloc = TRUE; /* yes, free this later */ + } + } + } + + if(Curl_is_absolute_url(newurl, NULL, MAX_SCHEME_LEN)) + /* This is an absolute URL, don't allow the custom port number */ + disallowport = TRUE; + + DEBUGASSERT(data->state.uh); + uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl, + (type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME : 0); + if(uc) { + if(type != FOLLOW_FAKE) + return Curl_uc_to_curlcode(uc); + + /* the URL could not be parsed for some reason, but since this is FAKE + mode, just duplicate the field as-is */ + newurl = strdup(newurl); + if(!newurl) + return CURLE_OUT_OF_MEMORY; + } + else { + + uc = curl_url_get(data->state.uh, CURLUPART_URL, &newurl, 0); + if(uc) + return Curl_uc_to_curlcode(uc); + } + + if(type == FOLLOW_FAKE) { + /* we're only figuring out the new url if we would've followed locations + but now we're done so we can get out! */ + data->info.wouldredirect = newurl; + + if(reachedmax) { + failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs); + return CURLE_TOO_MANY_REDIRECTS; + } + return CURLE_OK; + } + + if(disallowport) + data->state.allow_port = FALSE; + + if(data->change.url_alloc) + Curl_safefree(data->change.url); + + data->change.url = newurl; + data->change.url_alloc = TRUE; + + infof(data, "Issue another request to this URL: '%s'\n", data->change.url); + + /* + * We get here when the HTTP code is 300-399 (and 401). We need to perform + * differently based on exactly what return code there was. + * + * News from 7.10.6: we can also get here on a 401 or 407, in case we act on + * a HTTP (proxy-) authentication scheme other than Basic. + */ + switch(data->info.httpcode) { + /* 401 - Act on a WWW-Authenticate, we keep on moving and do the + Authorization: XXXX header in the HTTP request code snippet */ + /* 407 - Act on a Proxy-Authenticate, we keep on moving and do the + Proxy-Authorization: XXXX header in the HTTP request code snippet */ + /* 300 - Multiple Choices */ + /* 306 - Not used */ + /* 307 - Temporary Redirect */ + default: /* for all above (and the unknown ones) */ + /* Some codes are explicitly mentioned since I've checked RFC2616 and they + * seem to be OK to POST to. + */ + break; + case 301: /* Moved Permanently */ + /* (quote from RFC7231, section 6.4.2) + * + * Note: For historical reasons, a user agent MAY change the request + * method from POST to GET for the subsequent request. If this + * behavior is undesired, the 307 (Temporary Redirect) status code + * can be used instead. + * + * ---- + * + * Many webservers expect this, so these servers often answers to a POST + * request with an error page. To be sure that libcurl gets the page that + * most user agents would get, libcurl has to force GET. + * + * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and + * can be overridden with CURLOPT_POSTREDIR. + */ + if((data->set.httpreq == HTTPREQ_POST + || data->set.httpreq == HTTPREQ_POST_FORM + || data->set.httpreq == HTTPREQ_POST_MIME) + && !(data->set.keep_post & CURL_REDIR_POST_301)) { + infof(data, "Switch from POST to GET\n"); + data->set.httpreq = HTTPREQ_GET; + } + break; + case 302: /* Found */ + /* (quote from RFC7231, section 6.4.3) + * + * Note: For historical reasons, a user agent MAY change the request + * method from POST to GET for the subsequent request. If this + * behavior is undesired, the 307 (Temporary Redirect) status code + * can be used instead. + * + * ---- + * + * Many webservers expect this, so these servers often answers to a POST + * request with an error page. To be sure that libcurl gets the page that + * most user agents would get, libcurl has to force GET. + * + * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and + * can be overridden with CURLOPT_POSTREDIR. + */ + if((data->set.httpreq == HTTPREQ_POST + || data->set.httpreq == HTTPREQ_POST_FORM + || data->set.httpreq == HTTPREQ_POST_MIME) + && !(data->set.keep_post & CURL_REDIR_POST_302)) { + infof(data, "Switch from POST to GET\n"); + data->set.httpreq = HTTPREQ_GET; + } + break; + + case 303: /* See Other */ + /* Disable both types of POSTs, unless the user explicitly + asks for POST after POST */ + if(data->set.httpreq != HTTPREQ_GET + && !(data->set.keep_post & CURL_REDIR_POST_303)) { + data->set.httpreq = HTTPREQ_GET; /* enforce GET request */ + infof(data, "Disables POST, goes with %s\n", + data->set.opt_no_body?"HEAD":"GET"); + } + break; + case 304: /* Not Modified */ + /* 304 means we did a conditional request and it was "Not modified". + * We shouldn't get any Location: header in this response! + */ + break; + case 305: /* Use Proxy */ + /* (quote from RFC2616, section 10.3.6): + * "The requested resource MUST be accessed through the proxy given + * by the Location field. The Location field gives the URI of the + * proxy. The recipient is expected to repeat this single request + * via the proxy. 305 responses MUST only be generated by origin + * servers." + */ + break; + } + Curl_pgrsTime(data, TIMER_REDIRECT); + Curl_pgrsResetTransferSizes(data); + + return CURLE_OK; +#endif /* CURL_DISABLE_HTTP */ +} + +/* Returns CURLE_OK *and* sets '*url' if a request retry is wanted. + + NOTE: that the *url is malloc()ed. */ +CURLcode Curl_retry_request(struct connectdata *conn, + char **url) +{ + struct Curl_easy *data = conn->data; + bool retry = FALSE; + *url = NULL; + + /* if we're talking upload, we can't do the checks below, unless the protocol + is HTTP as when uploading over HTTP we will still get a response */ + if(data->set.upload && + !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP))) + return CURLE_OK; + + if((data->req.bytecount + data->req.headerbytecount == 0) && + conn->bits.reuse && + (!data->set.opt_no_body + || (conn->handler->protocol & PROTO_FAMILY_HTTP)) && + (data->set.rtspreq != RTSPREQ_RECEIVE)) + /* We got no data, we attempted to re-use a connection. For HTTP this + can be a retry so we try again regardless if we expected a body. + For other protocols we only try again only if we expected a body. + + This might happen if the connection was left alive when we were + done using it before, but that was closed when we wanted to read from + it again. Bad luck. Retry the same request on a fresh connect! */ + retry = TRUE; + else if(data->state.refused_stream && + (data->req.bytecount + data->req.headerbytecount == 0) ) { + /* This was sent on a refused stream, safe to rerun. A refused stream + error can typically only happen on HTTP/2 level if the stream is safe + to issue again, but the nghttp2 API can deliver the message to other + streams as well, which is why this adds the check the data counters + too. */ + infof(conn->data, "REFUSED_STREAM, retrying a fresh connect\n"); + data->state.refused_stream = FALSE; /* clear again */ + retry = TRUE; + } + if(retry) { + infof(conn->data, "Connection died, retrying a fresh connect\n"); + *url = strdup(conn->data->change.url); + if(!*url) + return CURLE_OUT_OF_MEMORY; + + connclose(conn, "retry"); /* close this connection */ + conn->bits.retry = TRUE; /* mark this as a connection we're about + to retry. Marking it this way should + prevent i.e HTTP transfers to return + error just because nothing has been + transferred! */ + + + if(conn->handler->protocol&PROTO_FAMILY_HTTP) { + if(data->req.writebytecount) { + CURLcode result = Curl_readrewind(conn); + if(result) { + Curl_safefree(*url); + return result; + } + } + } + } + return CURLE_OK; +} + +/* + * Curl_setup_transfer() is called to setup some basic properties for the + * upcoming transfer. + */ +void +Curl_setup_transfer( + struct Curl_easy *data, /* transfer */ + int sockindex, /* socket index to read from or -1 */ + curl_off_t size, /* -1 if unknown at this point */ + bool getheader, /* TRUE if header parsing is wanted */ + int writesockindex /* socket index to write to, it may very well be + the same we read from. -1 disables */ + ) +{ + struct SingleRequest *k = &data->req; + struct connectdata *conn = data->conn; + DEBUGASSERT(conn != NULL); + DEBUGASSERT((sockindex <= 1) && (sockindex >= -1)); + + if(conn->bits.multiplex || conn->httpversion == 20) { + /* when multiplexing, the read/write sockets need to be the same! */ + conn->sockfd = sockindex == -1 ? + ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) : + conn->sock[sockindex]; + conn->writesockfd = conn->sockfd; + } + else { + conn->sockfd = sockindex == -1 ? + CURL_SOCKET_BAD : conn->sock[sockindex]; + conn->writesockfd = writesockindex == -1 ? + CURL_SOCKET_BAD:conn->sock[writesockindex]; + } + k->getheader = getheader; + + k->size = size; + + /* The code sequence below is placed in this function just because all + necessary input is not always known in do_complete() as this function may + be called after that */ + + if(!k->getheader) { + k->header = FALSE; + if(size > 0) + Curl_pgrsSetDownloadSize(data, size); + } + /* we want header and/or body, if neither then don't do this! */ + if(k->getheader || !data->set.opt_no_body) { + + if(sockindex != -1) + k->keepon |= KEEP_RECV; + + if(writesockindex != -1) { + struct HTTP *http = data->req.protop; + /* HTTP 1.1 magic: + + Even if we require a 100-return code before uploading data, we might + need to write data before that since the REQUEST may not have been + finished sent off just yet. + + Thus, we must check if the request has been sent before we set the + state info where we wait for the 100-return code + */ + if((data->state.expect100header) && + (conn->handler->protocol&PROTO_FAMILY_HTTP) && + (http->sending == HTTPSEND_BODY)) { + /* wait with write until we either got 100-continue or a timeout */ + k->exp100 = EXP100_AWAITING_CONTINUE; + k->start100 = Curl_now(); + + /* Set a timeout for the multi interface. Add the inaccuracy margin so + that we don't fire slightly too early and get denied to run. */ + Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT); + } + else { + if(data->state.expect100header) + /* when we've sent off the rest of the headers, we must await a + 100-continue but first finish sending the request */ + k->exp100 = EXP100_SENDING_REQUEST; + + /* enable the write bit when we're not waiting for continue */ + k->keepon |= KEEP_SEND; + } + } /* if(writesockindex != -1) */ + } /* if(k->getheader || !data->set.opt_no_body) */ + +} diff --git a/libcurl/lib/transfer.h b/libcurl/lib/transfer.h new file mode 100644 index 0000000..da36f19 --- /dev/null +++ b/libcurl/lib/transfer.h @@ -0,0 +1,73 @@ +#ifndef HEADER_CURL_TRANSFER_H +#define HEADER_CURL_TRANSFER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#define Curl_headersep(x) ((((x)==':') || ((x)==';'))) +char *Curl_checkheaders(const struct connectdata *conn, + const char *thisheader); + +void Curl_init_CONNECT(struct Curl_easy *data); + +CURLcode Curl_pretransfer(struct Curl_easy *data); +CURLcode Curl_posttransfer(struct Curl_easy *data); + +typedef enum { + FOLLOW_NONE, /* not used within the function, just a placeholder to + allow initing to this */ + FOLLOW_FAKE, /* only records stuff, not actually following */ + FOLLOW_RETRY, /* set if this is a request retry as opposed to a real + redirect following */ + FOLLOW_REDIR, /* a full true redirect */ + FOLLOW_LAST /* never used */ +} followtype; + +CURLcode Curl_follow(struct Curl_easy *data, char *newurl, + followtype type); +CURLcode Curl_readwrite(struct connectdata *conn, + struct Curl_easy *data, bool *done, + bool *comeback); +int Curl_single_getsock(const struct connectdata *conn, + curl_socket_t *socks, + int numsocks); +CURLcode Curl_readrewind(struct connectdata *conn); +CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes, + size_t *nreadp); +CURLcode Curl_retry_request(struct connectdata *conn, char **url); +bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc); +CURLcode Curl_get_upload_buffer(struct Curl_easy *data); + +CURLcode Curl_done_sending(struct connectdata *conn, + struct SingleRequest *k); + +/* This sets up a forthcoming transfer */ +void +Curl_setup_transfer (struct Curl_easy *data, + int sockindex, /* socket index to read from or -1 */ + curl_off_t size, /* -1 if unknown at this point */ + bool getheader, /* TRUE if header parsing is wanted */ + int writesockindex /* socket index to write to. May be + the same we read from. -1 + disables */ + ); + +#endif /* HEADER_CURL_TRANSFER_H */ diff --git a/libcurl/lib/url.c b/libcurl/lib/url.c new file mode 100644 index 0000000..2b47b23 --- /dev/null +++ b/libcurl/lib/url.c @@ -0,0 +1,4195 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETDB_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif +#ifdef HAVE_IPHLPAPI_H +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#ifdef __VMS +#include +#include +#endif + +#ifdef HAVE_SYS_UN_H +#include +#endif + +#ifndef HAVE_SOCKET +#error "We can't compile without socket() support!" +#endif + +#include + +#ifdef USE_LIBIDN2 +#include + +#elif defined(USE_WIN32_IDN) +/* prototype for curl_win32_idn_to_ascii() */ +bool curl_win32_idn_to_ascii(const char *in, char **out); +#endif /* USE_LIBIDN2 */ + +#include "urldata.h" +#include "netrc.h" + +#include "formdata.h" +#include "mime.h" +#include "vtls/vtls.h" +#include "hostip.h" +#include "transfer.h" +#include "sendf.h" +#include "progress.h" +#include "cookie.h" +#include "strcase.h" +#include "strerror.h" +#include "escape.h" +#include "strtok.h" +#include "share.h" +#include "content_encoding.h" +#include "http_digest.h" +#include "http_negotiate.h" +#include "select.h" +#include "multiif.h" +#include "easyif.h" +#include "speedcheck.h" +#include "warnless.h" +#include "non-ascii.h" +#include "inet_pton.h" +#include "getinfo.h" +#include "urlapi-int.h" +#include "system_win32.h" + +/* And now for the protocols */ +#include "ftp.h" +#include "dict.h" +#include "telnet.h" +#include "tftp.h" +#include "http.h" +#include "http2.h" +#include "file.h" +#include "curl_ldap.h" +#include "ssh.h" +#include "imap.h" +#include "url.h" +#include "connect.h" +#include "inet_ntop.h" +#include "http_ntlm.h" +#include "socks.h" +#include "curl_rtmp.h" +#include "gopher.h" +#include "http_proxy.h" +#include "conncache.h" +#include "multihandle.h" +#include "dotdot.h" +#include "strdup.h" +#include "setopt.h" +#include "altsvc.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +static void conn_free(struct connectdata *conn); +static void free_idnconverted_hostname(struct hostname *host); +static unsigned int get_protocol_family(unsigned int protocol); + +/* Some parts of the code (e.g. chunked encoding) assume this buffer has at + * more than just a few bytes to play with. Don't let it become too small or + * bad things will happen. + */ +#if READBUFFER_SIZE < READBUFFER_MIN +# error READBUFFER_SIZE is too small +#endif + + +/* + * Protocol table. + */ + +static const struct Curl_handler * const protocols[] = { + +#ifndef CURL_DISABLE_HTTP + &Curl_handler_http, +#endif + +#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) + &Curl_handler_https, +#endif + +#ifndef CURL_DISABLE_FTP + &Curl_handler_ftp, +#endif + +#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) + &Curl_handler_ftps, +#endif + +#ifndef CURL_DISABLE_TELNET + &Curl_handler_telnet, +#endif + +#ifndef CURL_DISABLE_DICT + &Curl_handler_dict, +#endif + +#ifndef CURL_DISABLE_LDAP + &Curl_handler_ldap, +#if !defined(CURL_DISABLE_LDAPS) && \ + ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ + (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) + &Curl_handler_ldaps, +#endif +#endif + +#ifndef CURL_DISABLE_FILE + &Curl_handler_file, +#endif + +#ifndef CURL_DISABLE_TFTP + &Curl_handler_tftp, +#endif + +#if defined(USE_SSH) + &Curl_handler_scp, +#endif + +#if defined(USE_SSH) + &Curl_handler_sftp, +#endif + +#ifndef CURL_DISABLE_IMAP + &Curl_handler_imap, +#ifdef USE_SSL + &Curl_handler_imaps, +#endif +#endif + +#ifndef CURL_DISABLE_POP3 + &Curl_handler_pop3, +#ifdef USE_SSL + &Curl_handler_pop3s, +#endif +#endif + +#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ + (CURL_SIZEOF_CURL_OFF_T > 4) && \ + (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)) + &Curl_handler_smb, +#ifdef USE_SSL + &Curl_handler_smbs, +#endif +#endif + +#ifndef CURL_DISABLE_SMTP + &Curl_handler_smtp, +#ifdef USE_SSL + &Curl_handler_smtps, +#endif +#endif + +#ifndef CURL_DISABLE_RTSP + &Curl_handler_rtsp, +#endif + +#ifndef CURL_DISABLE_GOPHER + &Curl_handler_gopher, +#endif + +#ifdef USE_LIBRTMP + &Curl_handler_rtmp, + &Curl_handler_rtmpt, + &Curl_handler_rtmpe, + &Curl_handler_rtmpte, + &Curl_handler_rtmps, + &Curl_handler_rtmpts, +#endif + + (struct Curl_handler *) NULL +}; + +/* + * Dummy handler for undefined protocol schemes. + */ + +static const struct Curl_handler Curl_handler_dummy = { + "", /* scheme */ + ZERO_NULL, /* setup_connection */ + ZERO_NULL, /* do_it */ + ZERO_NULL, /* done */ + ZERO_NULL, /* do_more */ + ZERO_NULL, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + ZERO_NULL, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + 0, /* defport */ + 0, /* protocol */ + PROTOPT_NONE /* flags */ +}; + +void Curl_freeset(struct Curl_easy *data) +{ + /* Free all dynamic strings stored in the data->set substructure. */ + enum dupstring i; + for(i = (enum dupstring)0; i < STRING_LAST; i++) { + Curl_safefree(data->set.str[i]); + } + + if(data->change.referer_alloc) { + Curl_safefree(data->change.referer); + data->change.referer_alloc = FALSE; + } + data->change.referer = NULL; + if(data->change.url_alloc) { + Curl_safefree(data->change.url); + data->change.url_alloc = FALSE; + } + data->change.url = NULL; + + Curl_mime_cleanpart(&data->set.mimepost); +} + +/* free the URL pieces */ +static void up_free(struct Curl_easy *data) +{ + struct urlpieces *up = &data->state.up; + Curl_safefree(up->scheme); + Curl_safefree(up->hostname); + Curl_safefree(up->port); + Curl_safefree(up->user); + Curl_safefree(up->password); + Curl_safefree(up->options); + Curl_safefree(up->path); + Curl_safefree(up->query); + curl_url_cleanup(data->state.uh); + data->state.uh = NULL; +} + +/* + * This is the internal function curl_easy_cleanup() calls. This should + * cleanup and free all resources associated with this sessionhandle. + * + * NOTE: if we ever add something that attempts to write to a socket or + * similar here, we must ignore SIGPIPE first. It is currently only done + * when curl_easy_perform() is invoked. + */ + +CURLcode Curl_close(struct Curl_easy *data) +{ + struct Curl_multi *m; + + if(!data) + return CURLE_OK; + + Curl_expire_clear(data); /* shut off timers */ + + m = data->multi; + if(m) + /* This handle is still part of a multi handle, take care of this first + and detach this handle from there. */ + curl_multi_remove_handle(data->multi, data); + + if(data->multi_easy) { + /* when curl_easy_perform() is used, it creates its own multi handle to + use and this is the one */ + curl_multi_cleanup(data->multi_easy); + data->multi_easy = NULL; + } + + /* Destroy the timeout list that is held in the easy handle. It is + /normally/ done by curl_multi_remove_handle() but this is "just in + case" */ + Curl_llist_destroy(&data->state.timeoutlist, NULL); + + data->magic = 0; /* force a clear AFTER the possibly enforced removal from + the multi handle, since that function uses the magic + field! */ + + if(data->state.rangestringalloc) + free(data->state.range); + + /* freed here just in case DONE wasn't called */ + Curl_free_request_state(data); + + /* Close down all open SSL info and sessions */ + Curl_ssl_close_all(data); + Curl_safefree(data->state.first_host); + Curl_safefree(data->state.scratch); + Curl_ssl_free_certinfo(data); + + /* Cleanup possible redirect junk */ + free(data->req.newurl); + data->req.newurl = NULL; + + if(data->change.referer_alloc) { + Curl_safefree(data->change.referer); + data->change.referer_alloc = FALSE; + } + data->change.referer = NULL; + + up_free(data); + Curl_safefree(data->state.buffer); + Curl_safefree(data->state.headerbuff); + Curl_safefree(data->state.ulbuf); + Curl_flush_cookies(data, 1); +#ifdef USE_ALTSVC + Curl_altsvc_save(data->asi, data->set.str[STRING_ALTSVC]); + Curl_altsvc_cleanup(data->asi); + data->asi = NULL; +#endif +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) + Curl_http_auth_cleanup_digest(data); +#endif + Curl_safefree(data->info.contenttype); + Curl_safefree(data->info.wouldredirect); + + /* this destroys the channel and we cannot use it anymore after this */ + Curl_resolver_cleanup(data->state.resolver); + + Curl_http2_cleanup_dependencies(data); + Curl_convert_close(data); + + /* No longer a dirty share, if it exists */ + if(data->share) { + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + data->share->dirty--; + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + } + + /* destruct wildcard structures if it is needed */ + Curl_wildcard_dtor(&data->wildcard); + Curl_freeset(data); + free(data); + return CURLE_OK; +} + +/* + * Initialize the UserDefined fields within a Curl_easy. + * This may be safely called on a new or existing Curl_easy. + */ +CURLcode Curl_init_userdefined(struct Curl_easy *data) +{ + struct UserDefined *set = &data->set; + CURLcode result = CURLE_OK; + + set->out = stdout; /* default output to stdout */ + set->in_set = stdin; /* default input from stdin */ + set->err = stderr; /* default stderr to stderr */ + + /* use fwrite as default function to store output */ + set->fwrite_func = (curl_write_callback)fwrite; + + /* use fread as default function to read input */ + set->fread_func_set = (curl_read_callback)fread; + set->is_fread_set = 0; + set->is_fwrite_set = 0; + + set->seek_func = ZERO_NULL; + set->seek_client = ZERO_NULL; + + /* conversion callbacks for non-ASCII hosts */ + set->convfromnetwork = ZERO_NULL; + set->convtonetwork = ZERO_NULL; + set->convfromutf8 = ZERO_NULL; + + set->filesize = -1; /* we don't know the size */ + set->postfieldsize = -1; /* unknown size */ + set->maxredirs = -1; /* allow any amount by default */ + + set->httpreq = HTTPREQ_GET; /* Default HTTP request */ + set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */ +#ifndef CURL_DISABLE_FTP + set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ + set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ + set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */ + set->ftp_filemethod = FTPFILE_MULTICWD; +#endif + set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ + + /* Set the default size of the SSL session ID cache */ + set->general_ssl.max_ssl_sessions = 5; + + set->proxyport = 0; + set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ + set->httpauth = CURLAUTH_BASIC; /* defaults to basic */ + set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */ + + /* SOCKS5 proxy auth defaults to username/password + GSS-API */ + set->socks5auth = CURLAUTH_BASIC | CURLAUTH_GSSAPI; + + /* make libcurl quiet by default: */ + set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ + + Curl_mime_initpart(&set->mimepost, data); + + /* + * libcurl 7.10 introduced SSL verification *by default*! This needs to be + * switched off unless wanted. + */ + set->ssl.primary.verifypeer = TRUE; + set->ssl.primary.verifyhost = TRUE; +#ifdef USE_TLS_SRP + set->ssl.authtype = CURL_TLSAUTH_NONE; +#endif + set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth + type */ + set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by + default */ + set->proxy_ssl = set->ssl; + + set->new_file_perms = 0644; /* Default permissions */ + set->new_directory_perms = 0755; /* Default permissions */ + + /* for the *protocols fields we don't use the CURLPROTO_ALL convenience + define since we internally only use the lower 16 bits for the passed + in bitmask to not conflict with the private bits */ + set->allowed_protocols = CURLPROTO_ALL; + set->redir_protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | + CURLPROTO_FTPS; + +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + /* + * disallow unprotected protection negotiation NEC reference implementation + * seem not to follow rfc1961 section 4.3/4.4 + */ + set->socks5_gssapi_nec = FALSE; +#endif + + /* Set the default CA cert bundle/path detected/specified at build time. + * + * If Schannel is the selected SSL backend then these locations are + * ignored. We allow setting CA location for schannel only when explicitly + * specified by the user via CURLOPT_CAINFO / --cacert. + */ + if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { +#if defined(CURL_CA_BUNDLE) + result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE); + if(result) + return result; + + result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_PROXY], + CURL_CA_BUNDLE); + if(result) + return result; +#endif +#if defined(CURL_CA_PATH) + result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH); + if(result) + return result; + + result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_PROXY], CURL_CA_PATH); + if(result) + return result; +#endif + } + + set->wildcard_enabled = FALSE; + set->chunk_bgn = ZERO_NULL; + set->chunk_end = ZERO_NULL; + set->tcp_keepalive = FALSE; + set->tcp_keepintvl = 60; + set->tcp_keepidle = 60; + set->tcp_fastopen = FALSE; + set->tcp_nodelay = TRUE; + set->ssl_enable_npn = TRUE; + set->ssl_enable_alpn = TRUE; + set->expect_100_timeout = 1000L; /* Wait for a second by default. */ + set->sep_headers = TRUE; /* separated header lists by default */ + set->buffer_size = READBUFFER_SIZE; + set->upload_buffer_size = UPLOADBUFFER_DEFAULT; + set->happy_eyeballs_timeout = CURL_HET_DEFAULT; + set->fnmatch = ZERO_NULL; + set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT; + set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */ + set->maxage_conn = 118; + set->http09_allowed = TRUE; + set->httpversion = +#ifdef USE_NGHTTP2 + CURL_HTTP_VERSION_2TLS +#else + CURL_HTTP_VERSION_1_1 +#endif + ; + Curl_http2_init_userset(set); + return result; +} + +/** + * Curl_open() + * + * @param curl is a pointer to a sessionhandle pointer that gets set by this + * function. + * @return CURLcode + */ + +CURLcode Curl_open(struct Curl_easy **curl) +{ + CURLcode result; + struct Curl_easy *data; + + /* Very simple start-up: alloc the struct, init it with zeroes and return */ + data = calloc(1, sizeof(struct Curl_easy)); + if(!data) { + /* this is a very serious error */ + DEBUGF(fprintf(stderr, "Error: calloc of Curl_easy failed\n")); + return CURLE_OUT_OF_MEMORY; + } + + data->magic = CURLEASY_MAGIC_NUMBER; + + result = Curl_resolver_init(data, &data->state.resolver); + if(result) { + DEBUGF(fprintf(stderr, "Error: resolver_init failed\n")); + free(data); + return result; + } + + /* We do some initial setup here, all those fields that can't be just 0 */ + + data->state.buffer = malloc(READBUFFER_SIZE + 1); + if(!data->state.buffer) { + DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n")); + result = CURLE_OUT_OF_MEMORY; + } + else { + data->state.headerbuff = malloc(HEADERSIZE); + if(!data->state.headerbuff) { + DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n")); + result = CURLE_OUT_OF_MEMORY; + } + else { + result = Curl_init_userdefined(data); + + data->state.headersize = HEADERSIZE; + Curl_convert_init(data); + Curl_initinfo(data); + + /* most recent connection is not yet defined */ + data->state.lastconnect = NULL; + + data->progress.flags |= PGRS_HIDE; + data->state.current_speed = -1; /* init to negative == impossible */ + + Curl_http2_init_state(&data->state); + } + } + + if(result) { + Curl_resolver_cleanup(data->state.resolver); + free(data->state.buffer); + free(data->state.headerbuff); + Curl_freeset(data); + free(data); + data = NULL; + } + else + *curl = data; + + return result; +} + +#ifdef USE_RECV_BEFORE_SEND_WORKAROUND +static void conn_reset_postponed_data(struct connectdata *conn, int num) +{ + struct postponed_data * const psnd = &(conn->postponed[num]); + if(psnd->buffer) { + DEBUGASSERT(psnd->allocated_size > 0); + DEBUGASSERT(psnd->recv_size <= psnd->allocated_size); + DEBUGASSERT(psnd->recv_size ? + (psnd->recv_processed < psnd->recv_size) : + (psnd->recv_processed == 0)); + DEBUGASSERT(psnd->bindsock != CURL_SOCKET_BAD); + free(psnd->buffer); + psnd->buffer = NULL; + psnd->allocated_size = 0; + psnd->recv_size = 0; + psnd->recv_processed = 0; +#ifdef DEBUGBUILD + psnd->bindsock = CURL_SOCKET_BAD; /* used only for DEBUGASSERT */ +#endif /* DEBUGBUILD */ + } + else { + DEBUGASSERT(psnd->allocated_size == 0); + DEBUGASSERT(psnd->recv_size == 0); + DEBUGASSERT(psnd->recv_processed == 0); + DEBUGASSERT(psnd->bindsock == CURL_SOCKET_BAD); + } +} + +static void conn_reset_all_postponed_data(struct connectdata *conn) +{ + conn_reset_postponed_data(conn, 0); + conn_reset_postponed_data(conn, 1); +} +#else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ +/* Use "do-nothing" macro instead of function when workaround not used */ +#define conn_reset_all_postponed_data(c) do {} WHILE_FALSE +#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ + + +static void conn_shutdown(struct connectdata *conn) +{ + if(!conn) + return; + + infof(conn->data, "Closing connection %ld\n", conn->connection_id); + DEBUGASSERT(conn->data); + + /* possible left-overs from the async name resolvers */ + Curl_resolver_cancel(conn); + + /* close the SSL stuff before we close any sockets since they will/may + write to the sockets */ + Curl_ssl_close(conn, FIRSTSOCKET); + Curl_ssl_close(conn, SECONDARYSOCKET); + + /* close possibly still open sockets */ + if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) + Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]); + if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET]) + Curl_closesocket(conn, conn->sock[FIRSTSOCKET]); + if(CURL_SOCKET_BAD != conn->tempsock[0]) + Curl_closesocket(conn, conn->tempsock[0]); + if(CURL_SOCKET_BAD != conn->tempsock[1]) + Curl_closesocket(conn, conn->tempsock[1]); + + /* unlink ourselves. this should be called last since other shutdown + procedures need a valid conn->data and this may clear it. */ + Curl_conncache_remove_conn(conn->data, conn, TRUE); +} + +static void conn_free(struct connectdata *conn) +{ + if(!conn) + return; + + free_idnconverted_hostname(&conn->host); + free_idnconverted_hostname(&conn->conn_to_host); + free_idnconverted_hostname(&conn->http_proxy.host); + free_idnconverted_hostname(&conn->socks_proxy.host); + + Curl_safefree(conn->user); + Curl_safefree(conn->passwd); + Curl_safefree(conn->oauth_bearer); + Curl_safefree(conn->options); + Curl_safefree(conn->http_proxy.user); + Curl_safefree(conn->socks_proxy.user); + Curl_safefree(conn->http_proxy.passwd); + Curl_safefree(conn->socks_proxy.passwd); + Curl_safefree(conn->allocptr.proxyuserpwd); + Curl_safefree(conn->allocptr.uagent); + Curl_safefree(conn->allocptr.userpwd); + Curl_safefree(conn->allocptr.accept_encoding); + Curl_safefree(conn->allocptr.te); + Curl_safefree(conn->allocptr.rangeline); + Curl_safefree(conn->allocptr.ref); + Curl_safefree(conn->allocptr.host); + Curl_safefree(conn->allocptr.cookiehost); + Curl_safefree(conn->allocptr.rtsp_transport); + Curl_safefree(conn->trailer); + Curl_safefree(conn->host.rawalloc); /* host name buffer */ + Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */ + Curl_safefree(conn->hostname_resolve); + Curl_safefree(conn->secondaryhostname); + Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */ + Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */ + Curl_safefree(conn->connect_state); + + conn_reset_all_postponed_data(conn); + Curl_llist_destroy(&conn->easyq, NULL); + Curl_safefree(conn->localdev); + Curl_free_primary_ssl_config(&conn->ssl_config); + Curl_free_primary_ssl_config(&conn->proxy_ssl_config); + +#ifdef USE_UNIX_SOCKETS + Curl_safefree(conn->unix_domain_socket); +#endif + +#ifdef USE_SSL + Curl_safefree(conn->ssl_extra); +#endif + free(conn); /* free all the connection oriented data */ +} + +/* + * Disconnects the given connection. Note the connection may not be the + * primary connection, like when freeing room in the connection cache or + * killing of a dead old connection. + * + * A connection needs an easy handle when closing down. We support this passed + * in separately since the connection to get closed here is often already + * disassociated from an easy handle. + * + * This function MUST NOT reset state in the Curl_easy struct if that + * isn't strictly bound to the life-time of *this* particular connection. + * + */ + +CURLcode Curl_disconnect(struct Curl_easy *data, + struct connectdata *conn, bool dead_connection) +{ + if(!conn) + return CURLE_OK; /* this is closed and fine already */ + + if(!data) { + DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n")); + return CURLE_OK; + } + + /* + * If this connection isn't marked to force-close, leave it open if there + * are other users of it + */ + if(CONN_INUSE(conn) && !dead_connection) { + DEBUGF(infof(data, "Curl_disconnect when inuse: %zu\n", CONN_INUSE(conn))); + return CURLE_OK; + } + + if(conn->dns_entry != NULL) { + Curl_resolv_unlock(data, conn->dns_entry); + conn->dns_entry = NULL; + } + + Curl_hostcache_prune(data); /* kill old DNS cache entries */ + +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) + /* Cleanup NTLM connection-related data */ + Curl_http_auth_cleanup_ntlm(conn); +#endif +#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) + /* Cleanup NEGOTIATE connection-related data */ + Curl_http_auth_cleanup_negotiate(conn); +#endif + + /* the protocol specific disconnect handler and conn_shutdown need a transfer + for the connection! */ + conn->data = data; + + if(conn->bits.connect_only) + /* treat the connection as dead in CONNECT_ONLY situations */ + dead_connection = TRUE; + + if(conn->handler->disconnect) + /* This is set if protocol-specific cleanups should be made */ + conn->handler->disconnect(conn, dead_connection); + + conn_shutdown(conn); + conn_free(conn); + return CURLE_OK; +} + +/* + * This function should return TRUE if the socket is to be assumed to + * be dead. Most commonly this happens when the server has closed the + * connection due to inactivity. + */ +static bool SocketIsDead(curl_socket_t sock) +{ + int sval; + bool ret_val = TRUE; + + sval = SOCKET_READABLE(sock, 0); + if(sval == 0) + /* timeout */ + ret_val = FALSE; + + return ret_val; +} + +/* + * IsMultiplexingPossible() + * + * Return a bitmask with the available multiplexing options for the given + * requested connection. + */ +static int IsMultiplexingPossible(const struct Curl_easy *handle, + const struct connectdata *conn) +{ + int avail = 0; + + /* If a HTTP protocol and multiplexing is enabled */ + if((conn->handler->protocol & PROTO_FAMILY_HTTP) && + (!conn->bits.protoconnstart || !conn->bits.close)) { + + if(Curl_multiplex_wanted(handle->multi) && + (handle->set.httpversion >= CURL_HTTP_VERSION_2)) + /* allows HTTP/2 */ + avail |= CURLPIPE_MULTIPLEX; + } + return avail; +} + +#ifndef CURL_DISABLE_PROXY +static bool +proxy_info_matches(const struct proxy_info* data, + const struct proxy_info* needle) +{ + if((data->proxytype == needle->proxytype) && + (data->port == needle->port) && + Curl_safe_strcasecompare(data->host.name, needle->host.name)) + return TRUE; + + return FALSE; +} +#else +/* disabled, won't get called */ +#define proxy_info_matches(x,y) FALSE +#endif + +/* A connection has to have been idle for a shorter time than 'maxage_conn' to + be subject for reuse. The success rate is just too low after this. */ + +static bool conn_maxage(struct Curl_easy *data, + struct connectdata *conn, + struct curltime now) +{ + if(!conn->data) { + timediff_t idletime = Curl_timediff(now, conn->lastused); + idletime /= 1000; /* integer seconds is fine */ + + if(idletime > data->set.maxage_conn) { + infof(data, "Too old connection (%ld seconds), disconnect it\n", + idletime); + return TRUE; + } + } + return FALSE; +} + +/* + * This function checks if the given connection is dead and extracts it from + * the connection cache if so. + * + * When this is called as a Curl_conncache_foreach() callback, the connection + * cache lock is held! + * + * Returns TRUE if the connection was dead and extracted. + */ +static bool extract_if_dead(struct connectdata *conn, + struct Curl_easy *data) +{ + if(!CONN_INUSE(conn) && !conn->data) { + /* The check for a dead socket makes sense only if the connection isn't in + use */ + bool dead; + struct curltime now = Curl_now(); + if(conn_maxage(data, conn, now)) { + dead = TRUE; + } + else if(conn->handler->connection_check) { + /* The protocol has a special method for checking the state of the + connection. Use it to check if the connection is dead. */ + unsigned int state; + struct Curl_easy *olddata = conn->data; + conn->data = data; /* use this transfer for now */ + state = conn->handler->connection_check(conn, CONNCHECK_ISDEAD); + conn->data = olddata; + dead = (state & CONNRESULT_DEAD); + } + else { + /* Use the general method for determining the death of a connection */ + dead = SocketIsDead(conn->sock[FIRSTSOCKET]); + } + + if(dead) { + infof(data, "Connection %ld seems to be dead!\n", conn->connection_id); + Curl_conncache_remove_conn(data, conn, FALSE); + return TRUE; + } + } + return FALSE; +} + +struct prunedead { + struct Curl_easy *data; + struct connectdata *extracted; +}; + +/* + * Wrapper to use extract_if_dead() function in Curl_conncache_foreach() + * + */ +static int call_extract_if_dead(struct connectdata *conn, void *param) +{ + struct prunedead *p = (struct prunedead *)param; + if(extract_if_dead(conn, p->data)) { + /* stop the iteration here, pass back the connection that was extracted */ + p->extracted = conn; + return 1; + } + return 0; /* continue iteration */ +} + +/* + * This function scans the connection cache for half-open/dead connections, + * closes and removes them. + * The cleanup is done at most once per second. + */ +static void prune_dead_connections(struct Curl_easy *data) +{ + struct curltime now = Curl_now(); + time_t elapsed = Curl_timediff(now, data->state.conn_cache->last_cleanup); + + if(elapsed >= 1000L) { + struct prunedead prune; + prune.data = data; + prune.extracted = NULL; + while(Curl_conncache_foreach(data, data->state.conn_cache, &prune, + call_extract_if_dead)) { + /* disconnect it */ + (void)Curl_disconnect(data, prune.extracted, /* dead_connection */TRUE); + } + data->state.conn_cache->last_cleanup = now; + } +} + +/* + * Given one filled in connection struct (named needle), this function should + * detect if there already is one that has all the significant details + * exactly the same and thus should be used instead. + * + * If there is a match, this function returns TRUE - and has marked the + * connection as 'in-use'. It must later be called with ConnectionDone() to + * return back to 'idle' (unused) state. + * + * The force_reuse flag is set if the connection must be used. + */ +static bool +ConnectionExists(struct Curl_easy *data, + struct connectdata *needle, + struct connectdata **usethis, + bool *force_reuse, + bool *waitpipe) +{ + struct connectdata *check; + struct connectdata *chosen = 0; + bool foundPendingCandidate = FALSE; + bool canmultiplex = IsMultiplexingPossible(data, needle); + struct connectbundle *bundle; + const char *hostbundle; + +#ifdef USE_NTLM + bool wantNTLMhttp = ((data->state.authhost.want & + (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && + (needle->handler->protocol & PROTO_FAMILY_HTTP)); + bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd && + ((data->state.authproxy.want & + (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && + (needle->handler->protocol & PROTO_FAMILY_HTTP))); +#endif + + *force_reuse = FALSE; + *waitpipe = FALSE; + + /* Look up the bundle with all the connections to this particular host. + Locks the connection cache, beware of early returns! */ + bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache, + &hostbundle); + if(bundle) { + /* Max pipe length is zero (unlimited) for multiplexed connections */ + struct curl_llist_element *curr; + + infof(data, "Found bundle for host %s: %p [%s]\n", + hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ? + "can multiplex" : "serially")); + + /* We can't multiplex if we don't know anything about the server */ + if(canmultiplex) { + if(bundle->multiuse == BUNDLE_UNKNOWN) { + if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) { + infof(data, "Server doesn't support multiplex yet, wait\n"); + *waitpipe = TRUE; + Curl_conncache_unlock(data); + return FALSE; /* no re-use */ + } + + infof(data, "Server doesn't support multiplex (yet)\n"); + canmultiplex = FALSE; + } + if((bundle->multiuse == BUNDLE_MULTIPLEX) && + !Curl_multiplex_wanted(data->multi)) { + infof(data, "Could multiplex, but not asked to!\n"); + canmultiplex = FALSE; + } + if(bundle->multiuse == BUNDLE_NO_MULTIUSE) { + infof(data, "Can not multiplex, even if we wanted to!\n"); + canmultiplex = FALSE; + } + } + + curr = bundle->conn_list.head; + while(curr) { + bool match = FALSE; + size_t multiplexed; + + /* + * Note that if we use a HTTP proxy in normal mode (no tunneling), we + * check connections to that proxy and not to the actual remote server. + */ + check = curr->ptr; + curr = curr->next; + + if(check->bits.connect_only) + /* connect-only connections will not be reused */ + continue; + + multiplexed = CONN_INUSE(check) && + (bundle->multiuse == BUNDLE_MULTIPLEX); + + if(canmultiplex) { + if(check->bits.protoconnstart && check->bits.close) + continue; + } + else { + if(multiplexed) { + /* can only happen within multi handles, and means that another easy + handle is using this connection */ + continue; + } + + if(Curl_resolver_asynch()) { + /* ip_addr_str[0] is NUL only if the resolving of the name hasn't + completed yet and until then we don't re-use this connection */ + if(!check->ip_addr_str[0]) { + infof(data, + "Connection #%ld is still name resolving, can't reuse\n", + check->connection_id); + continue; + } + } + + if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || + check->bits.close) { + if(!check->bits.close) + foundPendingCandidate = TRUE; + /* Don't pick a connection that hasn't connected yet or that is going + to get closed. */ + infof(data, "Connection #%ld isn't open enough, can't reuse\n", + check->connection_id); + continue; + } + } + +#ifdef USE_UNIX_SOCKETS + if(needle->unix_domain_socket) { + if(!check->unix_domain_socket) + continue; + if(strcmp(needle->unix_domain_socket, check->unix_domain_socket)) + continue; + if(needle->abstract_unix_socket != check->abstract_unix_socket) + continue; + } + else if(check->unix_domain_socket) + continue; +#endif + + if((needle->handler->flags&PROTOPT_SSL) != + (check->handler->flags&PROTOPT_SSL)) + /* don't do mixed SSL and non-SSL connections */ + if(get_protocol_family(check->handler->protocol) != + needle->handler->protocol || !check->tls_upgraded) + /* except protocols that have been upgraded via TLS */ + continue; + + if(needle->bits.httpproxy != check->bits.httpproxy || + needle->bits.socksproxy != check->bits.socksproxy) + continue; + + if(needle->bits.socksproxy && !proxy_info_matches(&needle->socks_proxy, + &check->socks_proxy)) + continue; + + if(needle->bits.conn_to_host != check->bits.conn_to_host) + /* don't mix connections that use the "connect to host" feature and + * connections that don't use this feature */ + continue; + + if(needle->bits.conn_to_port != check->bits.conn_to_port) + /* don't mix connections that use the "connect to port" feature and + * connections that don't use this feature */ + continue; + + if(needle->bits.httpproxy) { + if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy)) + continue; + + if(needle->bits.tunnel_proxy != check->bits.tunnel_proxy) + continue; + + if(needle->http_proxy.proxytype == CURLPROXY_HTTPS) { + /* use https proxy */ + if(needle->handler->flags&PROTOPT_SSL) { + /* use double layer ssl */ + if(!Curl_ssl_config_matches(&needle->proxy_ssl_config, + &check->proxy_ssl_config)) + continue; + if(check->proxy_ssl[FIRSTSOCKET].state != ssl_connection_complete) + continue; + } + else { + if(!Curl_ssl_config_matches(&needle->ssl_config, + &check->ssl_config)) + continue; + if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) + continue; + } + } + } + + if(!canmultiplex && check->data) + /* this request can't be multiplexed but the checked connection is + already in use so we skip it */ + continue; + + if(CONN_INUSE(check) && check->data && + (check->data->multi != needle->data->multi)) + /* this could be subject for multiplex use, but only if they belong to + * the same multi handle */ + continue; + + if(needle->localdev || needle->localport) { + /* If we are bound to a specific local end (IP+port), we must not + re-use a random other one, although if we didn't ask for a + particular one we can reuse one that was bound. + + This comparison is a bit rough and too strict. Since the input + parameters can be specified in numerous ways and still end up the + same it would take a lot of processing to make it really accurate. + Instead, this matching will assume that re-uses of bound connections + will most likely also re-use the exact same binding parameters and + missing out a few edge cases shouldn't hurt anyone very much. + */ + if((check->localport != needle->localport) || + (check->localportrange != needle->localportrange) || + (needle->localdev && + (!check->localdev || strcmp(check->localdev, needle->localdev)))) + continue; + } + + if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) { + /* This protocol requires credentials per connection, + so verify that we're using the same name and password as well */ + if(strcmp(needle->user, check->user) || + strcmp(needle->passwd, check->passwd)) { + /* one of them was different */ + continue; + } + } + + if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) || + needle->bits.tunnel_proxy) { + /* The requested connection does not use a HTTP proxy or it uses SSL or + it is a non-SSL protocol tunneled or it is a non-SSL protocol which + is allowed to be upgraded via TLS */ + + if((strcasecompare(needle->handler->scheme, check->handler->scheme) || + (get_protocol_family(check->handler->protocol) == + needle->handler->protocol && check->tls_upgraded)) && + (!needle->bits.conn_to_host || strcasecompare( + needle->conn_to_host.name, check->conn_to_host.name)) && + (!needle->bits.conn_to_port || + needle->conn_to_port == check->conn_to_port) && + strcasecompare(needle->host.name, check->host.name) && + needle->remote_port == check->remote_port) { + /* The schemes match or the the protocol family is the same and the + previous connection was TLS upgraded, and the hostname and host + port match */ + if(needle->handler->flags & PROTOPT_SSL) { + /* This is a SSL connection so verify that we're using the same + SSL options as well */ + if(!Curl_ssl_config_matches(&needle->ssl_config, + &check->ssl_config)) { + DEBUGF(infof(data, + "Connection #%ld has different SSL parameters, " + "can't reuse\n", + check->connection_id)); + continue; + } + if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) { + foundPendingCandidate = TRUE; + DEBUGF(infof(data, + "Connection #%ld has not started SSL connect, " + "can't reuse\n", + check->connection_id)); + continue; + } + } + match = TRUE; + } + } + else { + /* The requested connection is using the same HTTP proxy in normal + mode (no tunneling) */ + match = TRUE; + } + + if(match) { +#if defined(USE_NTLM) + /* If we are looking for an HTTP+NTLM connection, check if this is + already authenticating with the right credentials. If not, keep + looking so that we can reuse NTLM connections if + possible. (Especially we must not reuse the same connection if + partway through a handshake!) */ + if(wantNTLMhttp) { + if(strcmp(needle->user, check->user) || + strcmp(needle->passwd, check->passwd)) + continue; + } + else if(check->http_ntlm_state != NTLMSTATE_NONE) { + /* Connection is using NTLM auth but we don't want NTLM */ + continue; + } + + /* Same for Proxy NTLM authentication */ + if(wantProxyNTLMhttp) { + /* Both check->http_proxy.user and check->http_proxy.passwd can be + * NULL */ + if(!check->http_proxy.user || !check->http_proxy.passwd) + continue; + + if(strcmp(needle->http_proxy.user, check->http_proxy.user) || + strcmp(needle->http_proxy.passwd, check->http_proxy.passwd)) + continue; + } + else if(check->proxy_ntlm_state != NTLMSTATE_NONE) { + /* Proxy connection is using NTLM auth but we don't want NTLM */ + continue; + } + + if(wantNTLMhttp || wantProxyNTLMhttp) { + /* Credentials are already checked, we can use this connection */ + chosen = check; + + if((wantNTLMhttp && + (check->http_ntlm_state != NTLMSTATE_NONE)) || + (wantProxyNTLMhttp && + (check->proxy_ntlm_state != NTLMSTATE_NONE))) { + /* We must use this connection, no other */ + *force_reuse = TRUE; + break; + } + + /* Continue look up for a better connection */ + continue; + } +#endif + if(canmultiplex) { + /* We can multiplex if we want to. Let's continue looking for + the optimal connection to use. */ + + if(!multiplexed) { + /* We have the optimal connection. Let's stop looking. */ + chosen = check; + break; + } + +#ifdef USE_NGHTTP2 + /* If multiplexed, make sure we don't go over concurrency limit */ + if(check->bits.multiplex) { + /* Multiplexed connections can only be HTTP/2 for now */ + struct http_conn *httpc = &check->proto.httpc; + if(multiplexed >= httpc->settings.max_concurrent_streams) { + infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n", + multiplexed); + continue; + } + } +#endif + /* When not multiplexed, we have a match here! */ + chosen = check; + infof(data, "Multiplexed connection found!\n"); + break; + } + else { + /* We have found a connection. Let's stop searching. */ + chosen = check; + break; + } + } + } + } + + if(chosen) { + /* mark it as used before releasing the lock */ + chosen->data = data; /* own it! */ + Curl_conncache_unlock(data); + *usethis = chosen; + return TRUE; /* yes, we found one to use! */ + } + Curl_conncache_unlock(data); + + if(foundPendingCandidate && data->set.pipewait) { + infof(data, + "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set\n"); + *waitpipe = TRUE; + } + + return FALSE; /* no matching connecting exists */ +} + +/* after a TCP connection to the proxy has been verified, this function does + the next magic step. + + Note: this function's sub-functions call failf() + +*/ +CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex) +{ + CURLcode result = CURLE_OK; + + if(conn->bits.socksproxy) { +#ifndef CURL_DISABLE_PROXY + /* for the secondary socket (FTP), use the "connect to host" + * but ignore the "connect to port" (use the secondary port) + */ + const char * const host = conn->bits.httpproxy ? + conn->http_proxy.host.name : + conn->bits.conn_to_host ? + conn->conn_to_host.name : + sockindex == SECONDARYSOCKET ? + conn->secondaryhostname : conn->host.name; + const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port : + sockindex == SECONDARYSOCKET ? conn->secondary_port : + conn->bits.conn_to_port ? conn->conn_to_port : + conn->remote_port; + conn->bits.socksproxy_connecting = TRUE; + switch(conn->socks_proxy.proxytype) { + case CURLPROXY_SOCKS5: + case CURLPROXY_SOCKS5_HOSTNAME: + result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd, + host, port, sockindex, conn); + break; + + case CURLPROXY_SOCKS4: + case CURLPROXY_SOCKS4A: + result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex, + conn); + break; + + default: + failf(conn->data, "unknown proxytype option given"); + result = CURLE_COULDNT_CONNECT; + } /* switch proxytype */ + conn->bits.socksproxy_connecting = FALSE; +#else + (void)sockindex; +#endif /* CURL_DISABLE_PROXY */ + } + + return result; +} + +/* + * verboseconnect() displays verbose information after a connect + */ +#ifndef CURL_DISABLE_VERBOSE_STRINGS +void Curl_verboseconnect(struct connectdata *conn) +{ + if(conn->data->set.verbose) + infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n", + conn->bits.socksproxy ? conn->socks_proxy.host.dispname : + conn->bits.httpproxy ? conn->http_proxy.host.dispname : + conn->bits.conn_to_host ? conn->conn_to_host.dispname : + conn->host.dispname, + conn->ip_addr_str, conn->port, conn->connection_id); +} +#endif + +int Curl_protocol_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) +{ + if(conn->handler->proto_getsock) + return conn->handler->proto_getsock(conn, socks, numsocks); + /* Backup getsock logic. Since there is a live socket in use, we must wait + for it or it will be removed from watching when the multi_socket API is + used. */ + socks[0] = conn->sock[FIRSTSOCKET]; + return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0); +} + +int Curl_doing_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) +{ + if(conn && conn->handler->doing_getsock) + return conn->handler->doing_getsock(conn, socks, numsocks); + return GETSOCK_BLANK; +} + +/* + * We are doing protocol-specific connecting and this is being called over and + * over from the multi interface until the connection phase is done on + * protocol layer. + */ + +CURLcode Curl_protocol_connecting(struct connectdata *conn, + bool *done) +{ + CURLcode result = CURLE_OK; + + if(conn && conn->handler->connecting) { + *done = FALSE; + result = conn->handler->connecting(conn, done); + } + else + *done = TRUE; + + return result; +} + +/* + * We are DOING this is being called over and over from the multi interface + * until the DOING phase is done on protocol layer. + */ + +CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done) +{ + CURLcode result = CURLE_OK; + + if(conn && conn->handler->doing) { + *done = FALSE; + result = conn->handler->doing(conn, done); + } + else + *done = TRUE; + + return result; +} + +/* + * We have discovered that the TCP connection has been successful, we can now + * proceed with some action. + * + */ +CURLcode Curl_protocol_connect(struct connectdata *conn, + bool *protocol_done) +{ + CURLcode result = CURLE_OK; + + *protocol_done = FALSE; + + if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) { + /* We already are connected, get back. This may happen when the connect + worked fine in the first call, like when we connect to a local server + or proxy. Note that we don't know if the protocol is actually done. + + Unless this protocol doesn't have any protocol-connect callback, as + then we know we're done. */ + if(!conn->handler->connecting) + *protocol_done = TRUE; + + return CURLE_OK; + } + + if(!conn->bits.protoconnstart) { + + result = Curl_proxy_connect(conn, FIRSTSOCKET); + if(result) + return result; + + if(CONNECT_FIRSTSOCKET_PROXY_SSL()) + /* wait for HTTPS proxy SSL initialization to complete */ + return CURLE_OK; + + if(conn->bits.tunnel_proxy && conn->bits.httpproxy && + Curl_connect_ongoing(conn)) + /* when using an HTTP tunnel proxy, await complete tunnel establishment + before proceeding further. Return CURLE_OK so we'll be called again */ + return CURLE_OK; + + if(conn->handler->connect_it) { + /* is there a protocol-specific connect() procedure? */ + + /* Call the protocol-specific connect function */ + result = conn->handler->connect_it(conn, protocol_done); + } + else + *protocol_done = TRUE; + + /* it has started, possibly even completed but that knowledge isn't stored + in this bit! */ + if(!result) + conn->bits.protoconnstart = TRUE; + } + + return result; /* pass back status */ +} + +/* + * Helpers for IDNA conversions. + */ +static bool is_ASCII_name(const char *hostname) +{ + const unsigned char *ch = (const unsigned char *)hostname; + + while(*ch) { + if(*ch++ & 0x80) + return FALSE; + } + return TRUE; +} + +/* + * Strip single trailing dot in the hostname, + * primarily for SNI and http host header. + */ +static void strip_trailing_dot(struct hostname *host) +{ + size_t len; + if(!host || !host->name) + return; + len = strlen(host->name); + if(len && (host->name[len-1] == '.')) + host->name[len-1] = 0; +} + +/* + * Perform any necessary IDN conversion of hostname + */ +static CURLcode idnconvert_hostname(struct connectdata *conn, + struct hostname *host) +{ + struct Curl_easy *data = conn->data; + +#ifndef USE_LIBIDN2 + (void)data; + (void)conn; +#elif defined(CURL_DISABLE_VERBOSE_STRINGS) + (void)conn; +#endif + + /* set the name we use to display the host name */ + host->dispname = host->name; + + /* Check name for non-ASCII and convert hostname to ACE form if we can */ + if(!is_ASCII_name(host->name)) { +#ifdef USE_LIBIDN2 + if(idn2_check_version(IDN2_VERSION)) { + char *ace_hostname = NULL; +#if IDN2_VERSION_NUMBER >= 0x00140000 + /* IDN2_NFC_INPUT: Normalize input string using normalization form C. + IDN2_NONTRANSITIONAL: Perform Unicode TR46 non-transitional + processing. */ + int flags = IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL; +#else + int flags = IDN2_NFC_INPUT; +#endif + int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, flags); + if(rc == IDN2_OK) { + host->encalloc = (char *)ace_hostname; + /* change the name pointer to point to the encoded hostname */ + host->name = host->encalloc; + } + else { + failf(data, "Failed to convert %s to ACE; %s\n", host->name, + idn2_strerror(rc)); + return CURLE_URL_MALFORMAT; + } + } +#elif defined(USE_WIN32_IDN) + char *ace_hostname = NULL; + + if(curl_win32_idn_to_ascii(host->name, &ace_hostname)) { + host->encalloc = ace_hostname; + /* change the name pointer to point to the encoded hostname */ + host->name = host->encalloc; + } + else { + failf(data, "Failed to convert %s to ACE;\n", host->name); + return CURLE_URL_MALFORMAT; + } +#else + infof(data, "IDN support not present, can't parse Unicode domains\n"); +#endif + } + return CURLE_OK; +} + +/* + * Frees data allocated by idnconvert_hostname() + */ +static void free_idnconverted_hostname(struct hostname *host) +{ +#if defined(USE_LIBIDN2) + if(host->encalloc) { + idn2_free(host->encalloc); /* must be freed with idn2_free() since this was + allocated by libidn */ + host->encalloc = NULL; + } +#elif defined(USE_WIN32_IDN) + free(host->encalloc); /* must be freed with free() since this was + allocated by curl_win32_idn_to_ascii */ + host->encalloc = NULL; +#else + (void)host; +#endif +} + +/* + * Allocate and initialize a new connectdata object. + */ +static struct connectdata *allocate_conn(struct Curl_easy *data) +{ + struct connectdata *conn = calloc(1, sizeof(struct connectdata)); + if(!conn) + return NULL; + +#ifdef USE_SSL + /* The SSL backend-specific data (ssl_backend_data) objects are allocated as + a separate array to ensure suitable alignment. + Note that these backend pointers can be swapped by vtls (eg ssl backend + data becomes proxy backend data). */ + { + size_t sslsize = Curl_ssl->sizeof_ssl_backend_data; + char *ssl = calloc(4, sslsize); + if(!ssl) { + free(conn); + return NULL; + } + conn->ssl_extra = ssl; + conn->ssl[0].backend = (void *)ssl; + conn->ssl[1].backend = (void *)(ssl + sslsize); + conn->proxy_ssl[0].backend = (void *)(ssl + 2 * sslsize); + conn->proxy_ssl[1].backend = (void *)(ssl + 3 * sslsize); + } +#endif + + conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined + already from start to avoid NULL + situations and checks */ + + /* and we setup a few fields in case we end up actually using this struct */ + + conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ + conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ + conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */ + conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */ + conn->connection_id = -1; /* no ID */ + conn->port = -1; /* unknown at this point */ + conn->remote_port = -1; /* unknown at this point */ +#if defined(USE_RECV_BEFORE_SEND_WORKAROUND) && defined(DEBUGBUILD) + conn->postponed[0].bindsock = CURL_SOCKET_BAD; /* no file descriptor */ + conn->postponed[1].bindsock = CURL_SOCKET_BAD; /* no file descriptor */ +#endif /* USE_RECV_BEFORE_SEND_WORKAROUND && DEBUGBUILD */ + + /* Default protocol-independent behavior doesn't support persistent + connections, so we set this to force-close. Protocols that support + this need to set this to FALSE in their "curl_do" functions. */ + connclose(conn, "Default to force-close"); + + /* Store creation time to help future close decision making */ + conn->created = Curl_now(); + + /* Store current time to give a baseline to keepalive connection times. */ + conn->keepalive = Curl_now(); + + /* Store off the configured connection upkeep time. */ + conn->upkeep_interval_ms = data->set.upkeep_interval_ms; + + conn->data = data; /* Setup the association between this connection + and the Curl_easy */ + + conn->http_proxy.proxytype = data->set.proxytype; + conn->socks_proxy.proxytype = CURLPROXY_SOCKS4; + +#if !defined(CURL_DISABLE_PROXY) + /* note that these two proxy bits are now just on what looks to be + requested, they may be altered down the road */ + conn->bits.proxy = (data->set.str[STRING_PROXY] && + *data->set.str[STRING_PROXY]) ? TRUE : FALSE; + conn->bits.httpproxy = (conn->bits.proxy && + (conn->http_proxy.proxytype == CURLPROXY_HTTP || + conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0 || + conn->http_proxy.proxytype == CURLPROXY_HTTPS)) ? + TRUE : FALSE; + conn->bits.socksproxy = (conn->bits.proxy && + !conn->bits.httpproxy) ? TRUE : FALSE; + + if(data->set.str[STRING_PRE_PROXY] && *data->set.str[STRING_PRE_PROXY]) { + conn->bits.proxy = TRUE; + conn->bits.socksproxy = TRUE; + } + + conn->bits.proxy_user_passwd = + (data->set.str[STRING_PROXYUSERNAME]) ? TRUE : FALSE; + conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; +#endif /* CURL_DISABLE_PROXY */ + + conn->bits.user_passwd = (data->set.str[STRING_USERNAME]) ? TRUE : FALSE; +#ifndef CURL_DISABLE_FTP + conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; + conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; +#endif + conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus; + conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer; + conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost; + conn->proxy_ssl_config.verifystatus = + data->set.proxy_ssl.primary.verifystatus; + conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer; + conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost; + conn->ip_version = data->set.ipver; + conn->bits.connect_only = data->set.connect_only; + +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ + defined(NTLM_WB_ENABLED) + conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; +#endif + + /* Initialize the easy handle list */ + Curl_llist_init(&conn->easyq, NULL); + +#ifdef HAVE_GSSAPI + conn->data_prot = PROT_CLEAR; +#endif + + /* Store the local bind parameters that will be used for this connection */ + if(data->set.str[STRING_DEVICE]) { + conn->localdev = strdup(data->set.str[STRING_DEVICE]); + if(!conn->localdev) + goto error; + } + conn->localportrange = data->set.localportrange; + conn->localport = data->set.localport; + + /* the close socket stuff needs to be copied to the connection struct as + it may live on without (this specific) Curl_easy */ + conn->fclosesocket = data->set.fclosesocket; + conn->closesocket_client = data->set.closesocket_client; + + return conn; + error: + + Curl_llist_destroy(&conn->easyq, NULL); + free(conn->localdev); +#ifdef USE_SSL + free(conn->ssl_extra); +#endif + free(conn); + return NULL; +} + +/* returns the handler if the given scheme is built-in */ +const struct Curl_handler *Curl_builtin_scheme(const char *scheme) +{ + const struct Curl_handler * const *pp; + const struct Curl_handler *p; + /* Scan protocol handler table and match against 'scheme'. The handler may + be changed later when the protocol specific setup function is called. */ + for(pp = protocols; (p = *pp) != NULL; pp++) + if(strcasecompare(p->scheme, scheme)) + /* Protocol found in table. Check if allowed */ + return p; + return NULL; /* not found */ +} + + +static CURLcode findprotocol(struct Curl_easy *data, + struct connectdata *conn, + const char *protostr) +{ + const struct Curl_handler *p = Curl_builtin_scheme(protostr); + + if(p && /* Protocol found in table. Check if allowed */ + (data->set.allowed_protocols & p->protocol)) { + + /* it is allowed for "normal" request, now do an extra check if this is + the result of a redirect */ + if(data->state.this_is_a_follow && + !(data->set.redir_protocols & p->protocol)) + /* nope, get out */ + ; + else { + /* Perform setup complement if some. */ + conn->handler = conn->given = p; + + /* 'port' and 'remote_port' are set in setup_connection_internals() */ + return CURLE_OK; + } + } + + /* The protocol was not found in the table, but we don't have to assign it + to anything since it is already assigned to a dummy-struct in the + create_conn() function when the connectdata struct is allocated. */ + failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME, + protostr); + + return CURLE_UNSUPPORTED_PROTOCOL; +} + + +CURLcode Curl_uc_to_curlcode(CURLUcode uc) +{ + switch(uc) { + default: + return CURLE_URL_MALFORMAT; + case CURLUE_UNSUPPORTED_SCHEME: + return CURLE_UNSUPPORTED_PROTOCOL; + case CURLUE_OUT_OF_MEMORY: + return CURLE_OUT_OF_MEMORY; + case CURLUE_USER_NOT_ALLOWED: + return CURLE_LOGIN_DENIED; + } +} + +/* + * If the URL was set with an IPv6 numerical address with a zone id part, set + * the scope_id based on that! + */ + +static void zonefrom_url(CURLU *uh, struct connectdata *conn) +{ + char *zoneid; + CURLUcode uc; + + uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0); + + if(!uc && zoneid) { + char *endp; + unsigned long scope = strtoul(zoneid, &endp, 10); + if(!*endp && (scope < UINT_MAX)) + /* A plain number, use it directly as a scope id. */ + conn->scope_id = (unsigned int)scope; +#if defined(HAVE_IF_NAMETOINDEX) + else { +#elif defined(WIN32) + else if(Curl_if_nametoindex) { +#endif + +#if defined(HAVE_IF_NAMETOINDEX) || defined(WIN32) + /* Zone identifier is not numeric */ + unsigned int scopeidx = 0; +#if defined(WIN32) + scopeidx = Curl_if_nametoindex(zoneid); +#else + scopeidx = if_nametoindex(zoneid); +#endif + if(!scopeidx) + infof(conn->data, "Invalid zoneid: %s; %s\n", zoneid, + strerror(errno)); + else + conn->scope_id = scopeidx; + } +#endif /* HAVE_IF_NAMETOINDEX || WIN32 */ + + free(zoneid); + } +} + +/* + * Parse URL and fill in the relevant members of the connection struct. + */ +static CURLcode parseurlandfillconn(struct Curl_easy *data, + struct connectdata *conn) +{ + CURLcode result; + CURLU *uh; + CURLUcode uc; + char *hostname; + + up_free(data); /* cleanup previous leftovers first */ + + /* parse the URL */ + if(data->set.uh) { + uh = data->state.uh = curl_url_dup(data->set.uh); + } + else { + uh = data->state.uh = curl_url(); + } + + if(!uh) + return CURLE_OUT_OF_MEMORY; + + if(data->set.str[STRING_DEFAULT_PROTOCOL] && + !Curl_is_absolute_url(data->change.url, NULL, MAX_SCHEME_LEN)) { + char *url; + if(data->change.url_alloc) + free(data->change.url); + url = aprintf("%s://%s", data->set.str[STRING_DEFAULT_PROTOCOL], + data->change.url); + if(!url) + return CURLE_OUT_OF_MEMORY; + data->change.url = url; + data->change.url_alloc = TRUE; + } + + if(!data->set.uh) { + uc = curl_url_set(uh, CURLUPART_URL, data->change.url, + CURLU_GUESS_SCHEME | + CURLU_NON_SUPPORT_SCHEME | + (data->set.disallow_username_in_url ? + CURLU_DISALLOW_USER : 0) | + (data->set.path_as_is ? CURLU_PATH_AS_IS : 0)); + if(uc) { + DEBUGF(infof(data, "curl_url_set rejected %s\n", data->change.url)); + return Curl_uc_to_curlcode(uc); + } + } + + uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0); + if(uc) + return Curl_uc_to_curlcode(uc); + + result = findprotocol(data, conn, data->state.up.scheme); + if(result) + return result; + + uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user, + CURLU_URLDECODE); + if(!uc) { + conn->user = strdup(data->state.up.user); + if(!conn->user) + return CURLE_OUT_OF_MEMORY; + conn->bits.user_passwd = TRUE; + } + else if(uc != CURLUE_NO_USER) + return Curl_uc_to_curlcode(uc); + + uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, + CURLU_URLDECODE); + if(!uc) { + conn->passwd = strdup(data->state.up.password); + if(!conn->passwd) + return CURLE_OUT_OF_MEMORY; + conn->bits.user_passwd = TRUE; + } + else if(uc != CURLUE_NO_PASSWORD) + return Curl_uc_to_curlcode(uc); + + uc = curl_url_get(uh, CURLUPART_OPTIONS, &data->state.up.options, + CURLU_URLDECODE); + if(!uc) { + conn->options = strdup(data->state.up.options); + if(!conn->options) + return CURLE_OUT_OF_MEMORY; + } + else if(uc != CURLUE_NO_OPTIONS) + return Curl_uc_to_curlcode(uc); + + uc = curl_url_get(uh, CURLUPART_HOST, &data->state.up.hostname, 0); + if(uc) { + if(!strcasecompare("file", data->state.up.scheme)) + return CURLE_OUT_OF_MEMORY; + } + + uc = curl_url_get(uh, CURLUPART_PATH, &data->state.up.path, 0); + if(uc) + return Curl_uc_to_curlcode(uc); + + uc = curl_url_get(uh, CURLUPART_PORT, &data->state.up.port, + CURLU_DEFAULT_PORT); + if(uc) { + if(!strcasecompare("file", data->state.up.scheme)) + return CURLE_OUT_OF_MEMORY; + } + else { + unsigned long port = strtoul(data->state.up.port, NULL, 10); + conn->port = conn->remote_port = curlx_ultous(port); + } + + (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0); + + hostname = data->state.up.hostname; + if(!hostname) + /* this is for file:// transfers, get a dummy made */ + hostname = (char *)""; + + if(hostname[0] == '[') { + /* This looks like an IPv6 address literal. See if there is an address + scope. */ + size_t hlen; + conn->bits.ipv6_ip = TRUE; + /* cut off the brackets! */ + hostname++; + hlen = strlen(hostname); + hostname[hlen - 1] = 0; + + zonefrom_url(uh, conn); + } + + /* make sure the connect struct gets its own copy of the host name */ + conn->host.rawalloc = strdup(hostname); + if(!conn->host.rawalloc) + return CURLE_OUT_OF_MEMORY; + conn->host.name = conn->host.rawalloc; + + if(data->set.scope_id) + /* Override any scope that was set above. */ + conn->scope_id = data->set.scope_id; + + return CURLE_OK; +} + + +/* + * If we're doing a resumed transfer, we need to setup our stuff + * properly. + */ +static CURLcode setup_range(struct Curl_easy *data) +{ + struct UrlState *s = &data->state; + s->resume_from = data->set.set_resume_from; + if(s->resume_from || data->set.str[STRING_SET_RANGE]) { + if(s->rangestringalloc) + free(s->range); + + if(s->resume_from) + s->range = aprintf("%" CURL_FORMAT_CURL_OFF_T "-", s->resume_from); + else + s->range = strdup(data->set.str[STRING_SET_RANGE]); + + s->rangestringalloc = (s->range) ? TRUE : FALSE; + + if(!s->range) + return CURLE_OUT_OF_MEMORY; + + /* tell ourselves to fetch this range */ + s->use_range = TRUE; /* enable range download */ + } + else + s->use_range = FALSE; /* disable range download */ + + return CURLE_OK; +} + + +/* + * setup_connection_internals() - + * + * Setup connection internals specific to the requested protocol in the + * Curl_easy. This is inited and setup before the connection is made but + * is about the particular protocol that is to be used. + * + * This MUST get called after proxy magic has been figured out. + */ +static CURLcode setup_connection_internals(struct connectdata *conn) +{ + const struct Curl_handler * p; + CURLcode result; + conn->socktype = SOCK_STREAM; /* most of them are TCP streams */ + + /* Perform setup complement if some. */ + p = conn->handler; + + if(p->setup_connection) { + result = (*p->setup_connection)(conn); + + if(result) + return result; + + p = conn->handler; /* May have changed. */ + } + + if(conn->port < 0) + /* we check for -1 here since if proxy was detected already, this + was very likely already set to the proxy port */ + conn->port = p->defport; + + return CURLE_OK; +} + +/* + * Curl_free_request_state() should free temp data that was allocated in the + * Curl_easy for this single request. + */ + +void Curl_free_request_state(struct Curl_easy *data) +{ + Curl_safefree(data->req.protop); + Curl_safefree(data->req.newurl); +} + + +#ifndef CURL_DISABLE_PROXY +/**************************************************************** +* Checks if the host is in the noproxy list. returns true if it matches +* and therefore the proxy should NOT be used. +****************************************************************/ +static bool check_noproxy(const char *name, const char *no_proxy) +{ + /* no_proxy=domain1.dom,host.domain2.dom + * (a comma-separated list of hosts which should + * not be proxied, or an asterisk to override + * all proxy variables) + */ + if(no_proxy && no_proxy[0]) { + size_t tok_start; + size_t tok_end; + const char *separator = ", "; + size_t no_proxy_len; + size_t namelen; + char *endptr; + if(strcasecompare("*", no_proxy)) { + return TRUE; + } + + /* NO_PROXY was specified and it wasn't just an asterisk */ + + no_proxy_len = strlen(no_proxy); + if(name[0] == '[') { + /* IPv6 numerical address */ + endptr = strchr(name, ']'); + if(!endptr) + return FALSE; + name++; + namelen = endptr - name; + } + else + namelen = strlen(name); + + for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) { + while(tok_start < no_proxy_len && + strchr(separator, no_proxy[tok_start]) != NULL) { + /* Look for the beginning of the token. */ + ++tok_start; + } + + if(tok_start == no_proxy_len) + break; /* It was all trailing separator chars, no more tokens. */ + + for(tok_end = tok_start; tok_end < no_proxy_len && + strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end) + /* Look for the end of the token. */ + ; + + /* To match previous behaviour, where it was necessary to specify + * ".local.com" to prevent matching "notlocal.com", we will leave + * the '.' off. + */ + if(no_proxy[tok_start] == '.') + ++tok_start; + + if((tok_end - tok_start) <= namelen) { + /* Match the last part of the name to the domain we are checking. */ + const char *checkn = name + namelen - (tok_end - tok_start); + if(strncasecompare(no_proxy + tok_start, checkn, + tok_end - tok_start)) { + if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') { + /* We either have an exact match, or the previous character is a . + * so it is within the same domain, so no proxy for this host. + */ + return TRUE; + } + } + } /* if((tok_end - tok_start) <= namelen) */ + } /* for(tok_start = 0; tok_start < no_proxy_len; + tok_start = tok_end + 1) */ + } /* NO_PROXY was specified and it wasn't just an asterisk */ + + return FALSE; +} + +#ifndef CURL_DISABLE_HTTP +/**************************************************************** +* Detect what (if any) proxy to use. Remember that this selects a host +* name and is not limited to HTTP proxies only. +* The returned pointer must be freed by the caller (unless NULL) +****************************************************************/ +static char *detect_proxy(struct connectdata *conn) +{ + char *proxy = NULL; + + /* If proxy was not specified, we check for default proxy environment + * variables, to enable i.e Lynx compliance: + * + * http_proxy=http://some.server.dom:port/ + * https_proxy=http://some.server.dom:port/ + * ftp_proxy=http://some.server.dom:port/ + * no_proxy=domain1.dom,host.domain2.dom + * (a comma-separated list of hosts which should + * not be proxied, or an asterisk to override + * all proxy variables) + * all_proxy=http://some.server.dom:port/ + * (seems to exist for the CERN www lib. Probably + * the first to check for.) + * + * For compatibility, the all-uppercase versions of these variables are + * checked if the lowercase versions don't exist. + */ + char proxy_env[128]; + const char *protop = conn->handler->scheme; + char *envp = proxy_env; + char *prox; + + /* Now, build _proxy and check for such a one to use */ + while(*protop) + *envp++ = (char)tolower((int)*protop++); + + /* append _proxy */ + strcpy(envp, "_proxy"); + + /* read the protocol proxy: */ + prox = curl_getenv(proxy_env); + + /* + * We don't try the uppercase version of HTTP_PROXY because of + * security reasons: + * + * When curl is used in a webserver application + * environment (cgi or php), this environment variable can + * be controlled by the web server user by setting the + * http header 'Proxy:' to some value. + * + * This can cause 'internal' http/ftp requests to be + * arbitrarily redirected by any external attacker. + */ + if(!prox && !strcasecompare("http_proxy", proxy_env)) { + /* There was no lowercase variable, try the uppercase version: */ + Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env)); + prox = curl_getenv(proxy_env); + } + + envp = proxy_env; + if(prox) { + proxy = prox; /* use this */ + } + else { + envp = (char *)"all_proxy"; + proxy = curl_getenv(envp); /* default proxy to use */ + if(!proxy) { + envp = (char *)"ALL_PROXY"; + proxy = curl_getenv(envp); + } + } + if(proxy) + infof(conn->data, "Uses proxy env variable %s == '%s'\n", envp, proxy); + + return proxy; +} +#endif /* CURL_DISABLE_HTTP */ + +/* + * If this is supposed to use a proxy, we need to figure out the proxy + * host name, so that we can re-use an existing connection + * that may exist registered to the same proxy host. + */ +static CURLcode parse_proxy(struct Curl_easy *data, + struct connectdata *conn, char *proxy, + curl_proxytype proxytype) +{ + char *portptr = NULL; + long port = -1; + char *proxyuser = NULL; + char *proxypasswd = NULL; + char *host; + bool sockstype; + CURLUcode uc; + struct proxy_info *proxyinfo; + CURLU *uhp = curl_url(); + CURLcode result = CURLE_OK; + char *scheme = NULL; + + /* When parsing the proxy, allowing non-supported schemes since we have + these made up ones for proxies. Guess scheme for URLs without it. */ + uc = curl_url_set(uhp, CURLUPART_URL, proxy, + CURLU_NON_SUPPORT_SCHEME|CURLU_GUESS_SCHEME); + if(!uc) { + /* parsed okay as a URL */ + uc = curl_url_get(uhp, CURLUPART_SCHEME, &scheme, 0); + if(uc) { + result = CURLE_OUT_OF_MEMORY; + goto error; + } + + if(strcasecompare("https", scheme)) + proxytype = CURLPROXY_HTTPS; + else if(strcasecompare("socks5h", scheme)) + proxytype = CURLPROXY_SOCKS5_HOSTNAME; + else if(strcasecompare("socks5", scheme)) + proxytype = CURLPROXY_SOCKS5; + else if(strcasecompare("socks4a", scheme)) + proxytype = CURLPROXY_SOCKS4A; + else if(strcasecompare("socks4", scheme) || + strcasecompare("socks", scheme)) + proxytype = CURLPROXY_SOCKS4; + else if(strcasecompare("http", scheme)) + ; /* leave it as HTTP or HTTP/1.0 */ + else { + /* Any other xxx:// reject! */ + failf(data, "Unsupported proxy scheme for \'%s\'", proxy); + result = CURLE_COULDNT_CONNECT; + goto error; + } + } + else { + failf(data, "Unsupported proxy syntax in \'%s\'", proxy); + result = CURLE_COULDNT_RESOLVE_PROXY; + goto error; + } + +#ifdef USE_SSL + if(!(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY)) +#endif + if(proxytype == CURLPROXY_HTTPS) { + failf(data, "Unsupported proxy \'%s\', libcurl is built without the " + "HTTPS-proxy support.", proxy); + result = CURLE_NOT_BUILT_IN; + goto error; + } + + sockstype = + proxytype == CURLPROXY_SOCKS5_HOSTNAME || + proxytype == CURLPROXY_SOCKS5 || + proxytype == CURLPROXY_SOCKS4A || + proxytype == CURLPROXY_SOCKS4; + + proxyinfo = sockstype ? &conn->socks_proxy : &conn->http_proxy; + proxyinfo->proxytype = proxytype; + + /* Is there a username and password given in this proxy url? */ + curl_url_get(uhp, CURLUPART_USER, &proxyuser, CURLU_URLDECODE); + curl_url_get(uhp, CURLUPART_PASSWORD, &proxypasswd, CURLU_URLDECODE); + if(proxyuser || proxypasswd) { + Curl_safefree(proxyinfo->user); + proxyinfo->user = proxyuser; + Curl_safefree(proxyinfo->passwd); + if(!proxypasswd) { + proxypasswd = strdup(""); + if(!proxypasswd) { + result = CURLE_OUT_OF_MEMORY; + goto error; + } + } + proxyinfo->passwd = proxypasswd; + conn->bits.proxy_user_passwd = TRUE; /* enable it */ + } + + curl_url_get(uhp, CURLUPART_PORT, &portptr, 0); + + if(portptr) { + port = strtol(portptr, NULL, 10); + free(portptr); + } + else { + if(data->set.proxyport) + /* None given in the proxy string, then get the default one if it is + given */ + port = data->set.proxyport; + else { + if(proxytype == CURLPROXY_HTTPS) + port = CURL_DEFAULT_HTTPS_PROXY_PORT; + else + port = CURL_DEFAULT_PROXY_PORT; + } + } + if(port >= 0) { + proxyinfo->port = port; + if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc) + conn->port = port; + } + + /* now, clone the proxy host name */ + uc = curl_url_get(uhp, CURLUPART_HOST, &host, CURLU_URLDECODE); + if(uc) { + result = CURLE_OUT_OF_MEMORY; + goto error; + } + Curl_safefree(proxyinfo->host.rawalloc); + proxyinfo->host.rawalloc = host; + if(host[0] == '[') { + /* this is a numerical IPv6, strip off the brackets */ + size_t len = strlen(host); + host[len-1] = 0; /* clear the trailing bracket */ + host++; + zonefrom_url(uhp, conn); + } + proxyinfo->host.name = host; + + error: + free(scheme); + curl_url_cleanup(uhp); + return result; +} + +/* + * Extract the user and password from the authentication string + */ +static CURLcode parse_proxy_auth(struct Curl_easy *data, + struct connectdata *conn) +{ + char proxyuser[MAX_CURL_USER_LENGTH]=""; + char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; + CURLcode result; + + if(data->set.str[STRING_PROXYUSERNAME] != NULL) { + strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME], + MAX_CURL_USER_LENGTH); + proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/ + } + if(data->set.str[STRING_PROXYPASSWORD] != NULL) { + strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD], + MAX_CURL_PASSWORD_LENGTH); + proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/ + } + + result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL, + FALSE); + if(!result) + result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd, + NULL, FALSE); + return result; +} + +/* create_conn helper to parse and init proxy values. to be called after unix + socket init but before any proxy vars are evaluated. */ +static CURLcode create_conn_helper_init_proxy(struct connectdata *conn) +{ + char *proxy = NULL; + char *socksproxy = NULL; + char *no_proxy = NULL; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + /************************************************************* + * Extract the user and password from the authentication string + *************************************************************/ + if(conn->bits.proxy_user_passwd) { + result = parse_proxy_auth(data, conn); + if(result) + goto out; + } + + /************************************************************* + * Detect what (if any) proxy to use + *************************************************************/ + if(data->set.str[STRING_PROXY]) { + proxy = strdup(data->set.str[STRING_PROXY]); + /* if global proxy is set, this is it */ + if(NULL == proxy) { + failf(data, "memory shortage"); + result = CURLE_OUT_OF_MEMORY; + goto out; + } + } + + if(data->set.str[STRING_PRE_PROXY]) { + socksproxy = strdup(data->set.str[STRING_PRE_PROXY]); + /* if global socks proxy is set, this is it */ + if(NULL == socksproxy) { + failf(data, "memory shortage"); + result = CURLE_OUT_OF_MEMORY; + goto out; + } + } + + if(!data->set.str[STRING_NOPROXY]) { + const char *p = "no_proxy"; + no_proxy = curl_getenv(p); + if(!no_proxy) { + p = "NO_PROXY"; + no_proxy = curl_getenv(p); + } + if(no_proxy) { + infof(conn->data, "Uses proxy env variable %s == '%s'\n", p, no_proxy); + } + } + + if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY] ? + data->set.str[STRING_NOPROXY] : no_proxy)) { + Curl_safefree(proxy); + Curl_safefree(socksproxy); + } +#ifndef CURL_DISABLE_HTTP + else if(!proxy && !socksproxy) + /* if the host is not in the noproxy list, detect proxy. */ + proxy = detect_proxy(conn); +#endif /* CURL_DISABLE_HTTP */ + + Curl_safefree(no_proxy); + +#ifdef USE_UNIX_SOCKETS + /* For the time being do not mix proxy and unix domain sockets. See #1274 */ + if(proxy && conn->unix_domain_socket) { + free(proxy); + proxy = NULL; + } +#endif + + if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) { + free(proxy); /* Don't bother with an empty proxy string or if the + protocol doesn't work with network */ + proxy = NULL; + } + if(socksproxy && (!*socksproxy || + (conn->handler->flags & PROTOPT_NONETWORK))) { + free(socksproxy); /* Don't bother with an empty socks proxy string or if + the protocol doesn't work with network */ + socksproxy = NULL; + } + + /*********************************************************************** + * If this is supposed to use a proxy, we need to figure out the proxy host + * name, proxy type and port number, so that we can re-use an existing + * connection that may exist registered to the same proxy host. + ***********************************************************************/ + if(proxy || socksproxy) { + if(proxy) { + result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype); + Curl_safefree(proxy); /* parse_proxy copies the proxy string */ + if(result) + goto out; + } + + if(socksproxy) { + result = parse_proxy(data, conn, socksproxy, + conn->socks_proxy.proxytype); + /* parse_proxy copies the socks proxy string */ + Curl_safefree(socksproxy); + if(result) + goto out; + } + + if(conn->http_proxy.host.rawalloc) { +#ifdef CURL_DISABLE_HTTP + /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */ + result = CURLE_UNSUPPORTED_PROTOCOL; + goto out; +#else + /* force this connection's protocol to become HTTP if compatible */ + if(!(conn->handler->protocol & PROTO_FAMILY_HTTP)) { + if((conn->handler->flags & PROTOPT_PROXY_AS_HTTP) && + !conn->bits.tunnel_proxy) + conn->handler = &Curl_handler_http; + else + /* if not converting to HTTP over the proxy, enforce tunneling */ + conn->bits.tunnel_proxy = TRUE; + } + conn->bits.httpproxy = TRUE; +#endif + } + else { + conn->bits.httpproxy = FALSE; /* not a HTTP proxy */ + conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */ + } + + if(conn->socks_proxy.host.rawalloc) { + if(!conn->http_proxy.host.rawalloc) { + /* once a socks proxy */ + if(!conn->socks_proxy.user) { + conn->socks_proxy.user = conn->http_proxy.user; + conn->http_proxy.user = NULL; + Curl_safefree(conn->socks_proxy.passwd); + conn->socks_proxy.passwd = conn->http_proxy.passwd; + conn->http_proxy.passwd = NULL; + } + } + conn->bits.socksproxy = TRUE; + } + else + conn->bits.socksproxy = FALSE; /* not a socks proxy */ + } + else { + conn->bits.socksproxy = FALSE; + conn->bits.httpproxy = FALSE; + } + conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy; + + if(!conn->bits.proxy) { + /* we aren't using the proxy after all... */ + conn->bits.proxy = FALSE; + conn->bits.httpproxy = FALSE; + conn->bits.socksproxy = FALSE; + conn->bits.proxy_user_passwd = FALSE; + conn->bits.tunnel_proxy = FALSE; + } + +out: + + free(socksproxy); + free(proxy); + return result; +} +#endif /* CURL_DISABLE_PROXY */ + +/* + * Curl_parse_login_details() + * + * This is used to parse a login string for user name, password and options in + * the following formats: + * + * user + * user:password + * user:password;options + * user;options + * user;options:password + * :password + * :password;options + * ;options + * ;options:password + * + * Parameters: + * + * login [in] - The login string. + * len [in] - The length of the login string. + * userp [in/out] - The address where a pointer to newly allocated memory + * holding the user will be stored upon completion. + * passwdp [in/out] - The address where a pointer to newly allocated memory + * holding the password will be stored upon completion. + * optionsp [in/out] - The address where a pointer to newly allocated memory + * holding the options will be stored upon completion. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_parse_login_details(const char *login, const size_t len, + char **userp, char **passwdp, + char **optionsp) +{ + CURLcode result = CURLE_OK; + char *ubuf = NULL; + char *pbuf = NULL; + char *obuf = NULL; + const char *psep = NULL; + const char *osep = NULL; + size_t ulen; + size_t plen; + size_t olen; + + /* Attempt to find the password separator */ + if(passwdp) { + psep = strchr(login, ':'); + + /* Within the constraint of the login string */ + if(psep >= login + len) + psep = NULL; + } + + /* Attempt to find the options separator */ + if(optionsp) { + osep = strchr(login, ';'); + + /* Within the constraint of the login string */ + if(osep >= login + len) + osep = NULL; + } + + /* Calculate the portion lengths */ + ulen = (psep ? + (size_t)(osep && psep > osep ? osep - login : psep - login) : + (osep ? (size_t)(osep - login) : len)); + plen = (psep ? + (osep && osep > psep ? (size_t)(osep - psep) : + (size_t)(login + len - psep)) - 1 : 0); + olen = (osep ? + (psep && psep > osep ? (size_t)(psep - osep) : + (size_t)(login + len - osep)) - 1 : 0); + + /* Allocate the user portion buffer */ + if(userp && ulen) { + ubuf = malloc(ulen + 1); + if(!ubuf) + result = CURLE_OUT_OF_MEMORY; + } + + /* Allocate the password portion buffer */ + if(!result && passwdp && plen) { + pbuf = malloc(plen + 1); + if(!pbuf) { + free(ubuf); + result = CURLE_OUT_OF_MEMORY; + } + } + + /* Allocate the options portion buffer */ + if(!result && optionsp && olen) { + obuf = malloc(olen + 1); + if(!obuf) { + free(pbuf); + free(ubuf); + result = CURLE_OUT_OF_MEMORY; + } + } + + if(!result) { + /* Store the user portion if necessary */ + if(ubuf) { + memcpy(ubuf, login, ulen); + ubuf[ulen] = '\0'; + Curl_safefree(*userp); + *userp = ubuf; + } + + /* Store the password portion if necessary */ + if(pbuf) { + memcpy(pbuf, psep + 1, plen); + pbuf[plen] = '\0'; + Curl_safefree(*passwdp); + *passwdp = pbuf; + } + + /* Store the options portion if necessary */ + if(obuf) { + memcpy(obuf, osep + 1, olen); + obuf[olen] = '\0'; + Curl_safefree(*optionsp); + *optionsp = obuf; + } + } + + return result; +} + +/************************************************************* + * Figure out the remote port number and fix it in the URL + * + * No matter if we use a proxy or not, we have to figure out the remote + * port number of various reasons. + * + * The port number embedded in the URL is replaced, if necessary. + *************************************************************/ +static CURLcode parse_remote_port(struct Curl_easy *data, + struct connectdata *conn) +{ + + if(data->set.use_port && data->state.allow_port) { + /* if set, we use this instead of the port possibly given in the URL */ + char portbuf[16]; + CURLUcode uc; + conn->remote_port = (unsigned short)data->set.use_port; + msnprintf(portbuf, sizeof(portbuf), "%d", conn->remote_port); + uc = curl_url_set(data->state.uh, CURLUPART_PORT, portbuf, 0); + if(uc) + return CURLE_OUT_OF_MEMORY; + } + + return CURLE_OK; +} + +/* + * Override the login details from the URL with that in the CURLOPT_USERPWD + * option or a .netrc file, if applicable. + */ +static CURLcode override_login(struct Curl_easy *data, + struct connectdata *conn, + char **userp, char **passwdp, char **optionsp) +{ + bool user_changed = FALSE; + bool passwd_changed = FALSE; + CURLUcode uc; + + if(data->set.use_netrc == CURL_NETRC_REQUIRED && conn->bits.user_passwd) { + /* ignore user+password in the URL */ + if(*userp) { + Curl_safefree(*userp); + user_changed = TRUE; + } + if(*passwdp) { + Curl_safefree(*passwdp); + passwd_changed = TRUE; + } + conn->bits.user_passwd = FALSE; /* disable user+password */ + } + + if(data->set.str[STRING_USERNAME]) { + free(*userp); + *userp = strdup(data->set.str[STRING_USERNAME]); + if(!*userp) + return CURLE_OUT_OF_MEMORY; + conn->bits.user_passwd = TRUE; /* enable user+password */ + user_changed = TRUE; + } + + if(data->set.str[STRING_PASSWORD]) { + free(*passwdp); + *passwdp = strdup(data->set.str[STRING_PASSWORD]); + if(!*passwdp) + return CURLE_OUT_OF_MEMORY; + conn->bits.user_passwd = TRUE; /* enable user+password */ + passwd_changed = TRUE; + } + + if(data->set.str[STRING_OPTIONS]) { + free(*optionsp); + *optionsp = strdup(data->set.str[STRING_OPTIONS]); + if(!*optionsp) + return CURLE_OUT_OF_MEMORY; + } + + conn->bits.netrc = FALSE; + if(data->set.use_netrc != CURL_NETRC_IGNORED && + (!*userp || !**userp || !*passwdp || !**passwdp)) { + bool netrc_user_changed = FALSE; + bool netrc_passwd_changed = FALSE; + int ret; + + ret = Curl_parsenetrc(conn->host.name, + userp, passwdp, + &netrc_user_changed, &netrc_passwd_changed, + data->set.str[STRING_NETRC_FILE]); + if(ret > 0) { + infof(data, "Couldn't find host %s in the " + DOT_CHAR "netrc file; using defaults\n", + conn->host.name); + } + else if(ret < 0) { + return CURLE_OUT_OF_MEMORY; + } + else { + /* set bits.netrc TRUE to remember that we got the name from a .netrc + file, so that it is safe to use even if we followed a Location: to a + different host or similar. */ + conn->bits.netrc = TRUE; + conn->bits.user_passwd = TRUE; /* enable user+password */ + + if(netrc_user_changed) { + user_changed = TRUE; + } + if(netrc_passwd_changed) { + passwd_changed = TRUE; + } + } + } + + /* for updated strings, we update them in the URL */ + if(user_changed) { + uc = curl_url_set(data->state.uh, CURLUPART_USER, *userp, 0); + if(uc) + return Curl_uc_to_curlcode(uc); + } + if(passwd_changed) { + uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, *passwdp, 0); + if(uc) + return Curl_uc_to_curlcode(uc); + } + return CURLE_OK; +} + +/* + * Set the login details so they're available in the connection + */ +static CURLcode set_login(struct connectdata *conn) +{ + CURLcode result = CURLE_OK; + const char *setuser = CURL_DEFAULT_USER; + const char *setpasswd = CURL_DEFAULT_PASSWORD; + + /* If our protocol needs a password and we have none, use the defaults */ + if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) + ; + else { + setuser = ""; + setpasswd = ""; + } + /* Store the default user */ + if(!conn->user) { + conn->user = strdup(setuser); + if(!conn->user) + return CURLE_OUT_OF_MEMORY; + } + + /* Store the default password */ + if(!conn->passwd) { + conn->passwd = strdup(setpasswd); + if(!conn->passwd) + result = CURLE_OUT_OF_MEMORY; + } + + /* if there's a user without password, consider password blank */ + if(conn->user && !conn->passwd) { + conn->passwd = strdup(""); + if(!conn->passwd) + result = CURLE_OUT_OF_MEMORY; + } + + return result; +} + +/* + * Parses a "host:port" string to connect to. + * The hostname and the port may be empty; in this case, NULL is returned for + * the hostname and -1 for the port. + */ +static CURLcode parse_connect_to_host_port(struct Curl_easy *data, + const char *host, + char **hostname_result, + int *port_result) +{ + char *host_dup; + char *hostptr; + char *host_portno; + char *portptr; + int port = -1; + +#if defined(CURL_DISABLE_VERBOSE_STRINGS) + (void) data; +#endif + + *hostname_result = NULL; + *port_result = -1; + + if(!host || !*host) + return CURLE_OK; + + host_dup = strdup(host); + if(!host_dup) + return CURLE_OUT_OF_MEMORY; + + hostptr = host_dup; + + /* start scanning for port number at this point */ + portptr = hostptr; + + /* detect and extract RFC6874-style IPv6-addresses */ + if(*hostptr == '[') { +#ifdef ENABLE_IPV6 + char *ptr = ++hostptr; /* advance beyond the initial bracket */ + while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.'))) + ptr++; + if(*ptr == '%') { + /* There might be a zone identifier */ + if(strncmp("%25", ptr, 3)) + infof(data, "Please URL encode %% as %%25, see RFC 6874.\n"); + ptr++; + /* Allow unreserved characters as defined in RFC 3986 */ + while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') || + (*ptr == '.') || (*ptr == '_') || (*ptr == '~'))) + ptr++; + } + if(*ptr == ']') + /* yeps, it ended nicely with a bracket as well */ + *ptr++ = '\0'; + else + infof(data, "Invalid IPv6 address format\n"); + portptr = ptr; + /* Note that if this didn't end with a bracket, we still advanced the + * hostptr first, but I can't see anything wrong with that as no host + * name nor a numeric can legally start with a bracket. + */ +#else + failf(data, "Use of IPv6 in *_CONNECT_TO without IPv6 support built-in!"); + free(host_dup); + return CURLE_NOT_BUILT_IN; +#endif + } + + /* Get port number off server.com:1080 */ + host_portno = strchr(portptr, ':'); + if(host_portno) { + char *endp = NULL; + *host_portno = '\0'; /* cut off number from host name */ + host_portno++; + if(*host_portno) { + long portparse = strtol(host_portno, &endp, 10); + if((endp && *endp) || (portparse < 0) || (portparse > 65535)) { + infof(data, "No valid port number in connect to host string (%s)\n", + host_portno); + hostptr = NULL; + port = -1; + } + else + port = (int)portparse; /* we know it will fit */ + } + } + + /* now, clone the cleaned host name */ + if(hostptr) { + *hostname_result = strdup(hostptr); + if(!*hostname_result) { + free(host_dup); + return CURLE_OUT_OF_MEMORY; + } + } + + *port_result = port; + + free(host_dup); + return CURLE_OK; +} + +/* + * Parses one "connect to" string in the form: + * "HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT". + */ +static CURLcode parse_connect_to_string(struct Curl_easy *data, + struct connectdata *conn, + const char *conn_to_host, + char **host_result, + int *port_result) +{ + CURLcode result = CURLE_OK; + const char *ptr = conn_to_host; + int host_match = FALSE; + int port_match = FALSE; + + *host_result = NULL; + *port_result = -1; + + if(*ptr == ':') { + /* an empty hostname always matches */ + host_match = TRUE; + ptr++; + } + else { + /* check whether the URL's hostname matches */ + size_t hostname_to_match_len; + char *hostname_to_match = aprintf("%s%s%s", + conn->bits.ipv6_ip ? "[" : "", + conn->host.name, + conn->bits.ipv6_ip ? "]" : ""); + if(!hostname_to_match) + return CURLE_OUT_OF_MEMORY; + hostname_to_match_len = strlen(hostname_to_match); + host_match = strncasecompare(ptr, hostname_to_match, + hostname_to_match_len); + free(hostname_to_match); + ptr += hostname_to_match_len; + + host_match = host_match && *ptr == ':'; + ptr++; + } + + if(host_match) { + if(*ptr == ':') { + /* an empty port always matches */ + port_match = TRUE; + ptr++; + } + else { + /* check whether the URL's port matches */ + char *ptr_next = strchr(ptr, ':'); + if(ptr_next) { + char *endp = NULL; + long port_to_match = strtol(ptr, &endp, 10); + if((endp == ptr_next) && (port_to_match == conn->remote_port)) { + port_match = TRUE; + ptr = ptr_next + 1; + } + } + } + } + + if(host_match && port_match) { + /* parse the hostname and port to connect to */ + result = parse_connect_to_host_port(data, ptr, host_result, port_result); + } + + return result; +} + +/* + * Processes all strings in the "connect to" slist, and uses the "connect + * to host" and "connect to port" of the first string that matches. + */ +static CURLcode parse_connect_to_slist(struct Curl_easy *data, + struct connectdata *conn, + struct curl_slist *conn_to_host) +{ + CURLcode result = CURLE_OK; + char *host = NULL; + int port = -1; + + while(conn_to_host && !host && port == -1) { + result = parse_connect_to_string(data, conn, conn_to_host->data, + &host, &port); + if(result) + return result; + + if(host && *host) { + conn->conn_to_host.rawalloc = host; + conn->conn_to_host.name = host; + conn->bits.conn_to_host = TRUE; + + infof(data, "Connecting to hostname: %s\n", host); + } + else { + /* no "connect to host" */ + conn->bits.conn_to_host = FALSE; + Curl_safefree(host); + } + + if(port >= 0) { + conn->conn_to_port = port; + conn->bits.conn_to_port = TRUE; + infof(data, "Connecting to port: %d\n", port); + } + else { + /* no "connect to port" */ + conn->bits.conn_to_port = FALSE; + port = -1; + } + + conn_to_host = conn_to_host->next; + } + +#ifdef USE_ALTSVC + if(data->asi && !host && (port == -1) && + (conn->handler->protocol == CURLPROTO_HTTPS)) { + /* no connect_to match, try alt-svc! */ + const char *nhost; + int nport; + enum alpnid nalpnid; + bool hit; + host = conn->host.rawalloc; + hit = Curl_altsvc_lookup(data->asi, + ALPN_h1, host, conn->remote_port, /* from */ + &nalpnid, &nhost, &nport /* to */); + if(hit) { + char *hostd = strdup((char *)nhost); + if(!hostd) + return CURLE_OUT_OF_MEMORY; + conn->conn_to_host.rawalloc = hostd; + conn->conn_to_host.name = hostd; + conn->bits.conn_to_host = TRUE; + conn->conn_to_port = nport; + conn->bits.conn_to_port = TRUE; + infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d\n", + Curl_alpnid2str(ALPN_h1), host, conn->remote_port, + Curl_alpnid2str(nalpnid), hostd, nport); + } + } +#endif + + return result; +} + +/************************************************************* + * Resolve the address of the server or proxy + *************************************************************/ +static CURLcode resolve_server(struct Curl_easy *data, + struct connectdata *conn, + bool *async) +{ + CURLcode result = CURLE_OK; + timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); + + DEBUGASSERT(conn); + DEBUGASSERT(data); + /************************************************************* + * Resolve the name of the server or proxy + *************************************************************/ + if(conn->bits.reuse) + /* We're reusing the connection - no need to resolve anything, and + idnconvert_hostname() was called already in create_conn() for the re-use + case. */ + *async = FALSE; + + else { + /* this is a fresh connect */ + int rc; + struct Curl_dns_entry *hostaddr; + +#ifdef USE_UNIX_SOCKETS + if(conn->unix_domain_socket) { + /* Unix domain sockets are local. The host gets ignored, just use the + * specified domain socket address. Do not cache "DNS entries". There is + * no DNS involved and we already have the filesystem path available */ + const char *path = conn->unix_domain_socket; + + hostaddr = calloc(1, sizeof(struct Curl_dns_entry)); + if(!hostaddr) + result = CURLE_OUT_OF_MEMORY; + else { + bool longpath = FALSE; + hostaddr->addr = Curl_unix2addr(path, &longpath, + conn->abstract_unix_socket); + if(hostaddr->addr) + hostaddr->inuse++; + else { + /* Long paths are not supported for now */ + if(longpath) { + failf(data, "Unix socket path too long: '%s'", path); + result = CURLE_COULDNT_RESOLVE_HOST; + } + else + result = CURLE_OUT_OF_MEMORY; + free(hostaddr); + hostaddr = NULL; + } + } + } + else +#endif + if(!conn->bits.proxy) { + struct hostname *connhost; + if(conn->bits.conn_to_host) + connhost = &conn->conn_to_host; + else + connhost = &conn->host; + + /* If not connecting via a proxy, extract the port from the URL, if it is + * there, thus overriding any defaults that might have been set above. */ + if(conn->bits.conn_to_port) + conn->port = conn->conn_to_port; + else + conn->port = conn->remote_port; + + /* Resolve target host right on */ + conn->hostname_resolve = strdup(connhost->name); + if(!conn->hostname_resolve) + return CURLE_OUT_OF_MEMORY; + rc = Curl_resolv_timeout(conn, conn->hostname_resolve, (int)conn->port, + &hostaddr, timeout_ms); + if(rc == CURLRESOLV_PENDING) + *async = TRUE; + + else if(rc == CURLRESOLV_TIMEDOUT) + result = CURLE_OPERATION_TIMEDOUT; + + else if(!hostaddr) { + failf(data, "Couldn't resolve host '%s'", connhost->dispname); + result = CURLE_COULDNT_RESOLVE_HOST; + /* don't return yet, we need to clean up the timeout first */ + } + } + else { + /* This is a proxy that hasn't been resolved yet. */ + + struct hostname * const host = conn->bits.socksproxy ? + &conn->socks_proxy.host : &conn->http_proxy.host; + + /* resolve proxy */ + conn->hostname_resolve = strdup(host->name); + if(!conn->hostname_resolve) + return CURLE_OUT_OF_MEMORY; + rc = Curl_resolv_timeout(conn, conn->hostname_resolve, (int)conn->port, + &hostaddr, timeout_ms); + + if(rc == CURLRESOLV_PENDING) + *async = TRUE; + + else if(rc == CURLRESOLV_TIMEDOUT) + result = CURLE_OPERATION_TIMEDOUT; + + else if(!hostaddr) { + failf(data, "Couldn't resolve proxy '%s'", host->dispname); + result = CURLE_COULDNT_RESOLVE_PROXY; + /* don't return yet, we need to clean up the timeout first */ + } + } + DEBUGASSERT(conn->dns_entry == NULL); + conn->dns_entry = hostaddr; + } + + return result; +} + +/* + * Cleanup the connection just allocated before we can move along and use the + * previously existing one. All relevant data is copied over and old_conn is + * ready for freeing once this function returns. + */ +static void reuse_conn(struct connectdata *old_conn, + struct connectdata *conn) +{ + free_idnconverted_hostname(&old_conn->http_proxy.host); + free_idnconverted_hostname(&old_conn->socks_proxy.host); + + free(old_conn->http_proxy.host.rawalloc); + free(old_conn->socks_proxy.host.rawalloc); + + /* free the SSL config struct from this connection struct as this was + allocated in vain and is targeted for destruction */ + Curl_free_primary_ssl_config(&old_conn->ssl_config); + Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config); + + conn->data = old_conn->data; + + /* get the user+password information from the old_conn struct since it may + * be new for this request even when we re-use an existing connection */ + conn->bits.user_passwd = old_conn->bits.user_passwd; + if(conn->bits.user_passwd) { + /* use the new user name and password though */ + Curl_safefree(conn->user); + Curl_safefree(conn->passwd); + conn->user = old_conn->user; + conn->passwd = old_conn->passwd; + old_conn->user = NULL; + old_conn->passwd = NULL; + } + + conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; + if(conn->bits.proxy_user_passwd) { + /* use the new proxy user name and proxy password though */ + Curl_safefree(conn->http_proxy.user); + Curl_safefree(conn->socks_proxy.user); + Curl_safefree(conn->http_proxy.passwd); + Curl_safefree(conn->socks_proxy.passwd); + conn->http_proxy.user = old_conn->http_proxy.user; + conn->socks_proxy.user = old_conn->socks_proxy.user; + conn->http_proxy.passwd = old_conn->http_proxy.passwd; + conn->socks_proxy.passwd = old_conn->socks_proxy.passwd; + old_conn->http_proxy.user = NULL; + old_conn->socks_proxy.user = NULL; + old_conn->http_proxy.passwd = NULL; + old_conn->socks_proxy.passwd = NULL; + } + + /* host can change, when doing keepalive with a proxy or if the case is + different this time etc */ + free_idnconverted_hostname(&conn->host); + free_idnconverted_hostname(&conn->conn_to_host); + Curl_safefree(conn->host.rawalloc); + Curl_safefree(conn->conn_to_host.rawalloc); + conn->host = old_conn->host; + conn->conn_to_host = old_conn->conn_to_host; + conn->conn_to_port = old_conn->conn_to_port; + conn->remote_port = old_conn->remote_port; + Curl_safefree(conn->hostname_resolve); + + conn->hostname_resolve = old_conn->hostname_resolve; + old_conn->hostname_resolve = NULL; + + /* persist connection info in session handle */ + Curl_persistconninfo(conn); + + conn_reset_all_postponed_data(old_conn); /* free buffers */ + + /* re-use init */ + conn->bits.reuse = TRUE; /* yes, we're re-using here */ + + Curl_safefree(old_conn->user); + Curl_safefree(old_conn->passwd); + Curl_safefree(old_conn->options); + Curl_safefree(old_conn->http_proxy.user); + Curl_safefree(old_conn->socks_proxy.user); + Curl_safefree(old_conn->http_proxy.passwd); + Curl_safefree(old_conn->socks_proxy.passwd); + Curl_safefree(old_conn->localdev); + Curl_llist_destroy(&old_conn->easyq, NULL); + +#ifdef USE_UNIX_SOCKETS + Curl_safefree(old_conn->unix_domain_socket); +#endif +} + +/** + * create_conn() sets up a new connectdata struct, or re-uses an already + * existing one, and resolves host name. + * + * if this function returns CURLE_OK and *async is set to TRUE, the resolve + * response will be coming asynchronously. If *async is FALSE, the name is + * already resolved. + * + * @param data The sessionhandle pointer + * @param in_connect is set to the next connection data pointer + * @param async is set TRUE when an async DNS resolution is pending + * @see Curl_setup_conn() + * + * *NOTE* this function assigns the conn->data pointer! + */ + +static CURLcode create_conn(struct Curl_easy *data, + struct connectdata **in_connect, + bool *async) +{ + CURLcode result = CURLE_OK; + struct connectdata *conn; + struct connectdata *conn_temp = NULL; + bool reuse; + bool connections_available = TRUE; + bool force_reuse = FALSE; + bool waitpipe = FALSE; + size_t max_host_connections = Curl_multi_max_host_connections(data->multi); + size_t max_total_connections = Curl_multi_max_total_connections(data->multi); + + *async = FALSE; + *in_connect = NULL; + + /************************************************************* + * Check input data + *************************************************************/ + if(!data->change.url) { + result = CURLE_URL_MALFORMAT; + goto out; + } + + /* First, split up the current URL in parts so that we can use the + parts for checking against the already present connections. In order + to not have to modify everything at once, we allocate a temporary + connection data struct and fill in for comparison purposes. */ + conn = allocate_conn(data); + + if(!conn) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } + + /* We must set the return variable as soon as possible, so that our + parent can cleanup any possible allocs we may have done before + any failure */ + *in_connect = conn; + + result = parseurlandfillconn(data, conn); + if(result) + goto out; + + if(data->set.str[STRING_BEARER]) { + conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]); + if(!conn->oauth_bearer) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } + } + +#ifdef USE_UNIX_SOCKETS + if(data->set.str[STRING_UNIX_SOCKET_PATH]) { + conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]); + if(conn->unix_domain_socket == NULL) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } + conn->abstract_unix_socket = data->set.abstract_unix_socket; + } +#endif + + /* After the unix socket init but before the proxy vars are used, parse and + initialize the proxy vars */ +#ifndef CURL_DISABLE_PROXY + result = create_conn_helper_init_proxy(conn); + if(result) + goto out; +#endif + + /************************************************************* + * If the protocol is using SSL and HTTP proxy is used, we set + * the tunnel_proxy bit. + *************************************************************/ + if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy) + conn->bits.tunnel_proxy = TRUE; + + /************************************************************* + * Figure out the remote port number and fix it in the URL + *************************************************************/ + result = parse_remote_port(data, conn); + if(result) + goto out; + + /* Check for overridden login details and set them accordingly so they + they are known when protocol->setup_connection is called! */ + result = override_login(data, conn, &conn->user, &conn->passwd, + &conn->options); + if(result) + goto out; + + result = set_login(conn); /* default credentials */ + if(result) + goto out; + + /************************************************************* + * Process the "connect to" linked list of hostname/port mappings. + * Do this after the remote port number has been fixed in the URL. + *************************************************************/ + result = parse_connect_to_slist(data, conn, data->set.connect_to); + if(result) + goto out; + + /************************************************************* + * IDN-convert the hostnames + *************************************************************/ + result = idnconvert_hostname(conn, &conn->host); + if(result) + goto out; + if(conn->bits.conn_to_host) { + result = idnconvert_hostname(conn, &conn->conn_to_host); + if(result) + goto out; + } + if(conn->bits.httpproxy) { + result = idnconvert_hostname(conn, &conn->http_proxy.host); + if(result) + goto out; + } + if(conn->bits.socksproxy) { + result = idnconvert_hostname(conn, &conn->socks_proxy.host); + if(result) + goto out; + } + + /************************************************************* + * Check whether the host and the "connect to host" are equal. + * Do this after the hostnames have been IDN-converted. + *************************************************************/ + if(conn->bits.conn_to_host && + strcasecompare(conn->conn_to_host.name, conn->host.name)) { + conn->bits.conn_to_host = FALSE; + } + + /************************************************************* + * Check whether the port and the "connect to port" are equal. + * Do this after the remote port number has been fixed in the URL. + *************************************************************/ + if(conn->bits.conn_to_port && conn->conn_to_port == conn->remote_port) { + conn->bits.conn_to_port = FALSE; + } + + /************************************************************* + * If the "connect to" feature is used with an HTTP proxy, + * we set the tunnel_proxy bit. + *************************************************************/ + if((conn->bits.conn_to_host || conn->bits.conn_to_port) && + conn->bits.httpproxy) + conn->bits.tunnel_proxy = TRUE; + + /************************************************************* + * Setup internals depending on protocol. Needs to be done after + * we figured out what/if proxy to use. + *************************************************************/ + result = setup_connection_internals(conn); + if(result) + goto out; + + conn->recv[FIRSTSOCKET] = Curl_recv_plain; + conn->send[FIRSTSOCKET] = Curl_send_plain; + conn->recv[SECONDARYSOCKET] = Curl_recv_plain; + conn->send[SECONDARYSOCKET] = Curl_send_plain; + + conn->bits.tcp_fastopen = data->set.tcp_fastopen; + + /*********************************************************************** + * file: is a special case in that it doesn't need a network connection + ***********************************************************************/ +#ifndef CURL_DISABLE_FILE + if(conn->handler->flags & PROTOPT_NONETWORK) { + bool done; + /* this is supposed to be the connect function so we better at least check + that the file is present here! */ + DEBUGASSERT(conn->handler->connect_it); + Curl_persistconninfo(conn); + result = conn->handler->connect_it(conn, &done); + + /* Setup a "faked" transfer that'll do nothing */ + if(!result) { + conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */ + + result = Curl_conncache_add_conn(data->state.conn_cache, conn); + if(result) + goto out; + + /* + * Setup whatever necessary for a resumed transfer + */ + result = setup_range(data); + if(result) { + DEBUGASSERT(conn->handler->done); + /* we ignore the return code for the protocol-specific DONE */ + (void)conn->handler->done(conn, result, FALSE); + goto out; + } + Curl_attach_connnection(data, conn); + Curl_setup_transfer(data, -1, -1, FALSE, -1); + } + + /* since we skip do_init() */ + Curl_init_do(data, conn); + + goto out; + } +#endif + + /* Get a cloned copy of the SSL config situation stored in the + connection struct. But to get this going nicely, we must first make + sure that the strings in the master copy are pointing to the correct + strings in the session handle strings array! + + Keep in mind that the pointers in the master copy are pointing to strings + that will be freed as part of the Curl_easy struct, but all cloned + copies will be separately allocated. + */ + data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG]; + data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; + data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG]; + data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; + data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; + data->set.proxy_ssl.primary.random_file = + data->set.str[STRING_SSL_RANDOM_FILE]; + data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; + data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; + data->set.ssl.primary.cipher_list = + data->set.str[STRING_SSL_CIPHER_LIST_ORIG]; + data->set.proxy_ssl.primary.cipher_list = + data->set.str[STRING_SSL_CIPHER_LIST_PROXY]; + data->set.ssl.primary.cipher_list13 = + data->set.str[STRING_SSL_CIPHER13_LIST_ORIG]; + data->set.proxy_ssl.primary.cipher_list13 = + data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; + + data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG]; + data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; + data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG]; + data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; + data->set.ssl.cert = data->set.str[STRING_CERT_ORIG]; + data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY]; + data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG]; + data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; + data->set.ssl.key = data->set.str[STRING_KEY_ORIG]; + data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY]; + data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG]; + data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; + data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG]; + data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; + data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG]; + data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY]; +#ifdef USE_TLS_SRP + data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG]; + data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; + data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG]; + data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; +#endif + + if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary, + &conn->ssl_config)) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } + + if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary, + &conn->proxy_ssl_config)) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } + + prune_dead_connections(data); + + /************************************************************* + * Check the current list of connections to see if we can + * re-use an already existing one or if we have to create a + * new one. + *************************************************************/ + + DEBUGASSERT(conn->user); + DEBUGASSERT(conn->passwd); + + /* reuse_fresh is TRUE if we are told to use a new connection by force, but + we only acknowledge this option if this is not a re-used connection + already (which happens due to follow-location or during a HTTP + authentication phase). CONNECT_ONLY transfers also refuse reuse. */ + if((data->set.reuse_fresh && !data->state.this_is_a_follow) || + data->set.connect_only) + reuse = FALSE; + else + reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe); + + /* If we found a reusable connection that is now marked as in use, we may + still want to open a new connection if we are multiplexing. */ + if(reuse && !force_reuse && IsMultiplexingPossible(data, conn_temp)) { + size_t multiplexed = CONN_INUSE(conn_temp); + if(multiplexed > 0) { + infof(data, "Found connection %ld, with %zu requests on it\n", + conn_temp->connection_id, multiplexed); + + if(Curl_conncache_bundle_size(conn_temp) < max_host_connections && + Curl_conncache_size(data) < max_total_connections) { + /* We want a new connection anyway */ + reuse = FALSE; + + infof(data, "We can reuse, but we want a new connection anyway\n"); + Curl_conncache_return_conn(conn_temp); + } + } + } + + if(reuse) { + /* + * We already have a connection for this, we got the former connection + * in the conn_temp variable and thus we need to cleanup the one we + * just allocated before we can move along and use the previously + * existing one. + */ + reuse_conn(conn, conn_temp); +#ifdef USE_SSL + free(conn->ssl_extra); +#endif + free(conn); /* we don't need this anymore */ + conn = conn_temp; + *in_connect = conn; + + infof(data, "Re-using existing connection! (#%ld) with %s %s\n", + conn->connection_id, + conn->bits.proxy?"proxy":"host", + conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname : + conn->http_proxy.host.name ? conn->http_proxy.host.dispname : + conn->host.dispname); + } + else { + /* We have decided that we want a new connection. However, we may not + be able to do that if we have reached the limit of how many + connections we are allowed to open. */ + + if(conn->handler->flags & PROTOPT_ALPN_NPN) { + /* The protocol wants it, so set the bits if enabled in the easy handle + (default) */ + if(data->set.ssl_enable_alpn) + conn->bits.tls_enable_alpn = TRUE; + if(data->set.ssl_enable_npn) + conn->bits.tls_enable_npn = TRUE; + } + + if(waitpipe) + /* There is a connection that *might* become usable for multiplexing + "soon", and we wait for that */ + connections_available = FALSE; + else { + /* this gets a lock on the conncache */ + const char *bundlehost; + struct connectbundle *bundle = + Curl_conncache_find_bundle(conn, data->state.conn_cache, &bundlehost); + + if(max_host_connections > 0 && bundle && + (bundle->num_connections >= max_host_connections)) { + struct connectdata *conn_candidate; + + /* The bundle is full. Extract the oldest connection. */ + conn_candidate = Curl_conncache_extract_bundle(data, bundle); + Curl_conncache_unlock(data); + + if(conn_candidate) + (void)Curl_disconnect(data, conn_candidate, + /* dead_connection */ FALSE); + else { + infof(data, "No more connections allowed to host %s: %zu\n", + bundlehost, max_host_connections); + connections_available = FALSE; + } + } + else + Curl_conncache_unlock(data); + + } + + if(connections_available && + (max_total_connections > 0) && + (Curl_conncache_size(data) >= max_total_connections)) { + struct connectdata *conn_candidate; + + /* The cache is full. Let's see if we can kill a connection. */ + conn_candidate = Curl_conncache_extract_oldest(data); + if(conn_candidate) + (void)Curl_disconnect(data, conn_candidate, + /* dead_connection */ FALSE); + else { + infof(data, "No connections available in cache\n"); + connections_available = FALSE; + } + } + + if(!connections_available) { + infof(data, "No connections available.\n"); + + conn_free(conn); + *in_connect = NULL; + + result = CURLE_NO_CONNECTION_AVAILABLE; + goto out; + } + else { + /* + * This is a brand new connection, so let's store it in the connection + * cache of ours! + */ + result = Curl_conncache_add_conn(data->state.conn_cache, conn); + if(result) + goto out; + } + +#if defined(USE_NTLM) + /* If NTLM is requested in a part of this connection, make sure we don't + assume the state is fine as this is a fresh connection and NTLM is + connection based. */ + if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && + data->state.authhost.done) { + infof(data, "NTLM picked AND auth done set, clear picked!\n"); + data->state.authhost.picked = CURLAUTH_NONE; + data->state.authhost.done = FALSE; + } + + if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && + data->state.authproxy.done) { + infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n"); + data->state.authproxy.picked = CURLAUTH_NONE; + data->state.authproxy.done = FALSE; + } +#endif + } + + /* Setup and init stuff before DO starts, in preparing for the transfer. */ + Curl_init_do(data, conn); + + /* + * Setup whatever necessary for a resumed transfer + */ + result = setup_range(data); + if(result) + goto out; + + /* Continue connectdata initialization here. */ + + /* + * Inherit the proper values from the urldata struct AFTER we have arranged + * the persistent connection stuff + */ + conn->seek_func = data->set.seek_func; + conn->seek_client = data->set.seek_client; + + /************************************************************* + * Resolve the address of the server or proxy + *************************************************************/ + result = resolve_server(data, conn, async); + + /* Strip trailing dots. resolve_server copied the name. */ + strip_trailing_dot(&conn->host); + if(conn->bits.httpproxy) + strip_trailing_dot(&conn->http_proxy.host); + if(conn->bits.socksproxy) + strip_trailing_dot(&conn->socks_proxy.host); + if(conn->bits.conn_to_host) + strip_trailing_dot(&conn->conn_to_host); + +out: + return result; +} + +/* Curl_setup_conn() is called after the name resolve initiated in + * create_conn() is all done. + * + * Curl_setup_conn() also handles reused connections + * + * conn->data MUST already have been setup fine (in create_conn) + */ + +CURLcode Curl_setup_conn(struct connectdata *conn, + bool *protocol_done) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + Curl_pgrsTime(data, TIMER_NAMELOOKUP); + + if(conn->handler->flags & PROTOPT_NONETWORK) { + /* nothing to setup when not using a network */ + *protocol_done = TRUE; + return result; + } + *protocol_done = FALSE; /* default to not done */ + + /* set proxy_connect_closed to false unconditionally already here since it + is used strictly to provide extra information to a parent function in the + case of proxy CONNECT failures and we must make sure we don't have it + lingering set from a previous invoke */ + conn->bits.proxy_connect_closed = FALSE; + + /* + * Set user-agent. Used for HTTP, but since we can attempt to tunnel + * basically anything through a http proxy we can't limit this based on + * protocol. + */ + if(data->set.str[STRING_USERAGENT]) { + Curl_safefree(conn->allocptr.uagent); + conn->allocptr.uagent = + aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]); + if(!conn->allocptr.uagent) + return CURLE_OUT_OF_MEMORY; + } + + data->req.headerbytecount = 0; + +#ifdef CURL_DO_LINEEND_CONV + data->state.crlf_conversions = 0; /* reset CRLF conversion counter */ +#endif /* CURL_DO_LINEEND_CONV */ + + /* set start time here for timeout purposes in the connect procedure, it + is later set again for the progress meter purpose */ + conn->now = Curl_now(); + + if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { + conn->bits.tcpconnect[FIRSTSOCKET] = FALSE; + result = Curl_connecthost(conn, conn->dns_entry); + if(result) + return result; + } + else { + Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ + Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */ + conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; + *protocol_done = TRUE; + Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]); + Curl_verboseconnect(conn); + } + + conn->now = Curl_now(); /* time this *after* the connect is done, we set + this here perhaps a second time */ + return result; +} + +CURLcode Curl_connect(struct Curl_easy *data, + bool *asyncp, + bool *protocol_done) +{ + CURLcode result; + struct connectdata *conn; + + *asyncp = FALSE; /* assume synchronous resolves by default */ + + /* init the single-transfer specific data */ + Curl_free_request_state(data); + memset(&data->req, 0, sizeof(struct SingleRequest)); + data->req.maxdownload = -1; + + /* call the stuff that needs to be called */ + result = create_conn(data, &conn, asyncp); + + if(!result) { + if(CONN_INUSE(conn)) + /* multiplexed */ + *protocol_done = TRUE; + else if(!*asyncp) { + /* DNS resolution is done: that's either because this is a reused + connection, in which case DNS was unnecessary, or because DNS + really did finish already (synch resolver/fast async resolve) */ + result = Curl_setup_conn(conn, protocol_done); + } + } + + if(result == CURLE_NO_CONNECTION_AVAILABLE) { + return result; + } + else if(result && conn) { + /* We're not allowed to return failure with memory left allocated in the + connectdata struct, free those here */ + Curl_disconnect(data, conn, TRUE); + } + else if(!result && !data->conn) + /* FILE: transfers already have the connection attached */ + Curl_attach_connnection(data, conn); + + return result; +} + +/* + * Curl_init_do() inits the readwrite session. This is inited each time (in + * the DO function before the protocol-specific DO functions are invoked) for + * a transfer, sometimes multiple times on the same Curl_easy. Make sure + * nothing in here depends on stuff that are setup dynamically for the + * transfer. + * + * Allow this function to get called with 'conn' set to NULL. + */ + +CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn) +{ + struct SingleRequest *k = &data->req; + + if(conn) { + conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to + use */ + /* if the protocol used doesn't support wildcards, switch it off */ + if(data->state.wildcardmatch && + !(conn->handler->flags & PROTOPT_WILDCARD)) + data->state.wildcardmatch = FALSE; + } + + data->state.done = FALSE; /* *_done() is not called yet */ + data->state.expect100header = FALSE; + + + if(data->set.opt_no_body) + /* in HTTP lingo, no body means using the HEAD request... */ + data->set.httpreq = HTTPREQ_HEAD; + else if(HTTPREQ_HEAD == data->set.httpreq) + /* ... but if unset there really is no perfect method that is the + "opposite" of HEAD but in reality most people probably think GET + then. The important thing is that we can't let it remain HEAD if the + opt_no_body is set FALSE since then we'll behave wrong when getting + HTTP. */ + data->set.httpreq = HTTPREQ_GET; + + k->start = Curl_now(); /* start time */ + k->now = k->start; /* current time is now */ + k->header = TRUE; /* assume header */ + + k->bytecount = 0; + + k->buf = data->state.buffer; + k->hbufp = data->state.headerbuff; + k->ignorebody = FALSE; + + Curl_speedinit(data); + + Curl_pgrsSetUploadCounter(data, 0); + Curl_pgrsSetDownloadCounter(data, 0); + + return CURLE_OK; +} + +/* +* get_protocol_family() +* +* This is used to return the protocol family for a given protocol. +* +* Parameters: +* +* protocol [in] - A single bit protocol identifier such as HTTP or HTTPS. +* +* Returns the family as a single bit protocol identifier. +*/ + +static unsigned int get_protocol_family(unsigned int protocol) +{ + unsigned int family; + + switch(protocol) { + case CURLPROTO_HTTP: + case CURLPROTO_HTTPS: + family = CURLPROTO_HTTP; + break; + + case CURLPROTO_FTP: + case CURLPROTO_FTPS: + family = CURLPROTO_FTP; + break; + + case CURLPROTO_SCP: + family = CURLPROTO_SCP; + break; + + case CURLPROTO_SFTP: + family = CURLPROTO_SFTP; + break; + + case CURLPROTO_TELNET: + family = CURLPROTO_TELNET; + break; + + case CURLPROTO_LDAP: + case CURLPROTO_LDAPS: + family = CURLPROTO_LDAP; + break; + + case CURLPROTO_DICT: + family = CURLPROTO_DICT; + break; + + case CURLPROTO_FILE: + family = CURLPROTO_FILE; + break; + + case CURLPROTO_TFTP: + family = CURLPROTO_TFTP; + break; + + case CURLPROTO_IMAP: + case CURLPROTO_IMAPS: + family = CURLPROTO_IMAP; + break; + + case CURLPROTO_POP3: + case CURLPROTO_POP3S: + family = CURLPROTO_POP3; + break; + + case CURLPROTO_SMTP: + case CURLPROTO_SMTPS: + family = CURLPROTO_SMTP; + break; + + case CURLPROTO_RTSP: + family = CURLPROTO_RTSP; + break; + + case CURLPROTO_RTMP: + case CURLPROTO_RTMPS: + family = CURLPROTO_RTMP; + break; + + case CURLPROTO_RTMPT: + case CURLPROTO_RTMPTS: + family = CURLPROTO_RTMPT; + break; + + case CURLPROTO_RTMPE: + family = CURLPROTO_RTMPE; + break; + + case CURLPROTO_RTMPTE: + family = CURLPROTO_RTMPTE; + break; + + case CURLPROTO_GOPHER: + family = CURLPROTO_GOPHER; + break; + + case CURLPROTO_SMB: + case CURLPROTO_SMBS: + family = CURLPROTO_SMB; + break; + + default: + family = 0; + break; + } + + return family; +} + + +/* + * Wrapper to call functions in Curl_conncache_foreach() + * + * Returns always 0. + */ +static int conn_upkeep(struct connectdata *conn, + void *param) +{ + /* Param is unused. */ + (void)param; + + if(conn->handler->connection_check) { + /* Do a protocol-specific keepalive check on the connection. */ + conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE); + } + + return 0; /* continue iteration */ +} + +CURLcode Curl_upkeep(struct conncache *conn_cache, + void *data) +{ + /* Loop over every connection and make connection alive. */ + Curl_conncache_foreach(data, + conn_cache, + data, + conn_upkeep); + return CURLE_OK; +} diff --git a/libcurl/lib/url.h b/libcurl/lib/url.h new file mode 100644 index 0000000..7c87432 --- /dev/null +++ b/libcurl/lib/url.h @@ -0,0 +1,100 @@ +#ifndef HEADER_CURL_URL_H +#define HEADER_CURL_URL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#define READBUFFER_SIZE CURL_MAX_WRITE_SIZE +#define READBUFFER_MAX CURL_MAX_READ_SIZE +#define READBUFFER_MIN 1024 + +/* The default upload buffer size, should not be smaller than + CURL_MAX_WRITE_SIZE, as it needs to hold a full buffer as could be sent in + a write callback. + + The size was 16KB for many years but was bumped to 64KB because it makes + libcurl able to do significantly faster uploads in some circumstances. Even + larger buffers can help further, but this is deemed a fair memory/speed + compromise. */ +#define UPLOADBUFFER_DEFAULT 65536 +#define UPLOADBUFFER_MAX (2*1024*1024) +#define UPLOADBUFFER_MIN CURL_MAX_WRITE_SIZE + +/* + * Prototypes for library-wide functions provided by url.c + */ + +CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn); +CURLcode Curl_open(struct Curl_easy **curl); +CURLcode Curl_init_userdefined(struct Curl_easy *data); + +void Curl_freeset(struct Curl_easy * data); +CURLcode Curl_uc_to_curlcode(CURLUcode uc); +CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */ +CURLcode Curl_connect(struct Curl_easy *, bool *async, bool *protocol_connect); +CURLcode Curl_disconnect(struct Curl_easy *data, + struct connectdata *, bool dead_connection); +CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done); +CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done); +CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done); +CURLcode Curl_setup_conn(struct connectdata *conn, + bool *protocol_done); +void Curl_free_request_state(struct Curl_easy *data); + +int Curl_protocol_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks); +int Curl_doing_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks); +CURLcode Curl_parse_login_details(const char *login, const size_t len, + char **userptr, char **passwdptr, + char **optionsptr); +CURLcode Curl_upkeep(struct conncache *conn_cache, void *data); + +const struct Curl_handler *Curl_builtin_scheme(const char *scheme); + +#define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */ +#define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless + specified */ + +CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex); + +#ifdef CURL_DISABLE_VERBOSE_STRINGS +#define Curl_verboseconnect(x) Curl_nop_stmt +#else +void Curl_verboseconnect(struct connectdata *conn); +#endif + +#define CONNECT_PROXY_SSL()\ + (conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\ + !conn->bits.proxy_ssl_connected[sockindex]) + +#define CONNECT_FIRSTSOCKET_PROXY_SSL()\ + (conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\ + !conn->bits.proxy_ssl_connected[FIRSTSOCKET]) + +#define CONNECT_SECONDARYSOCKET_PROXY_SSL()\ + (conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\ + !conn->bits.proxy_ssl_connected[SECONDARYSOCKET]) + +#endif /* HEADER_CURL_URL_H */ diff --git a/libcurl/lib/urlapi-int.h b/libcurl/lib/urlapi-int.h new file mode 100644 index 0000000..d14d53d --- /dev/null +++ b/libcurl/lib/urlapi-int.h @@ -0,0 +1,34 @@ +#ifndef HEADER_CURL_URLAPI_INT_H +#define HEADER_CURL_URLAPI_INT_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" +/* scheme is not URL encoded, the longest libcurl supported ones are... */ +#define MAX_SCHEME_LEN 40 + +bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen); + +#ifdef DEBUGBUILD +CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname); +#endif + +#endif /* HEADER_CURL_URLAPI_INT_H */ diff --git a/libcurl/lib/urlapi.c b/libcurl/lib/urlapi.c new file mode 100644 index 0000000..d07e4f5 --- /dev/null +++ b/libcurl/lib/urlapi.c @@ -0,0 +1,1440 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include "urldata.h" +#include "urlapi-int.h" +#include "strcase.h" +#include "dotdot.h" +#include "url.h" +#include "escape.h" +#include "curl_ctype.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + + /* MSDOS/Windows style drive prefix, eg c: in c:foo */ +#define STARTS_WITH_DRIVE_PREFIX(str) \ + ((('a' <= str[0] && str[0] <= 'z') || \ + ('A' <= str[0] && str[0] <= 'Z')) && \ + (str[1] == ':')) + + /* MSDOS/Windows style drive prefix, optionally with + * a '|' instead of ':', followed by a slash or NUL */ +#define STARTS_WITH_URL_DRIVE_PREFIX(str) \ + ((('a' <= (str)[0] && (str)[0] <= 'z') || \ + ('A' <= (str)[0] && (str)[0] <= 'Z')) && \ + ((str)[1] == ':' || (str)[1] == '|') && \ + ((str)[2] == '/' || (str)[2] == '\\' || (str)[2] == 0)) + +/* Internal representation of CURLU. Point to URL-encoded strings. */ +struct Curl_URL { + char *scheme; + char *user; + char *password; + char *options; /* IMAP only? */ + char *host; + char *zoneid; /* for numerical IPv6 addresses */ + char *port; + char *path; + char *query; + char *fragment; + + char *scratch; /* temporary scratch area */ + long portnum; /* the numerical version */ +}; + +#define DEFAULT_SCHEME "https" + +static void free_urlhandle(struct Curl_URL *u) +{ + free(u->scheme); + free(u->user); + free(u->password); + free(u->options); + free(u->host); + free(u->zoneid); + free(u->port); + free(u->path); + free(u->query); + free(u->fragment); + free(u->scratch); +} + +/* move the full contents of one handle onto another and + free the original */ +static void mv_urlhandle(struct Curl_URL *from, + struct Curl_URL *to) +{ + free_urlhandle(to); + *to = *from; + free(from); +} + +/* + * Find the separator at the end of the host name, or the '?' in cases like + * http://www.url.com?id=2380 + */ +static const char *find_host_sep(const char *url) +{ + const char *sep; + const char *query; + + /* Find the start of the hostname */ + sep = strstr(url, "//"); + if(!sep) + sep = url; + else + sep += 2; + + query = strchr(sep, '?'); + sep = strchr(sep, '/'); + + if(!sep) + sep = url + strlen(url); + + if(!query) + query = url + strlen(url); + + return sep < query ? sep : query; +} + +/* + * Decide in an encoding-independent manner whether a character in an + * URL must be escaped. The same criterion must be used in strlen_url() + * and strcpy_url(). + */ +static bool urlchar_needs_escaping(int c) +{ + return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c)); +} + +/* + * strlen_url() returns the length of the given URL if the spaces within the + * URL were properly URL encoded. + * URL encoding should be skipped for host names, otherwise IDN resolution + * will fail. + */ +static size_t strlen_url(const char *url, bool relative) +{ + const unsigned char *ptr; + size_t newlen = 0; + bool left = TRUE; /* left side of the ? */ + const unsigned char *host_sep = (const unsigned char *) url; + + if(!relative) + host_sep = (const unsigned char *) find_host_sep(url); + + for(ptr = (unsigned char *)url; *ptr; ptr++) { + + if(ptr < host_sep) { + ++newlen; + continue; + } + + switch(*ptr) { + case '?': + left = FALSE; + /* FALLTHROUGH */ + default: + if(urlchar_needs_escaping(*ptr)) + newlen += 2; + newlen++; + break; + case ' ': + if(left) + newlen += 3; + else + newlen++; + break; + } + } + return newlen; +} + +/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in + * the source URL accordingly. + * URL encoding should be skipped for host names, otherwise IDN resolution + * will fail. + */ +static void strcpy_url(char *output, const char *url, bool relative) +{ + /* we must add this with whitespace-replacing */ + bool left = TRUE; + const unsigned char *iptr; + char *optr = output; + const unsigned char *host_sep = (const unsigned char *) url; + + if(!relative) + host_sep = (const unsigned char *) find_host_sep(url); + + for(iptr = (unsigned char *)url; /* read from here */ + *iptr; /* until zero byte */ + iptr++) { + + if(iptr < host_sep) { + *optr++ = *iptr; + continue; + } + + switch(*iptr) { + case '?': + left = FALSE; + /* FALLTHROUGH */ + default: + if(urlchar_needs_escaping(*iptr)) { + msnprintf(optr, 4, "%%%02x", *iptr); + optr += 3; + } + else + *optr++=*iptr; + break; + case ' ': + if(left) { + *optr++='%'; /* add a '%' */ + *optr++='2'; /* add a '2' */ + *optr++='0'; /* add a '0' */ + } + else + *optr++='+'; /* add a '+' here */ + break; + } + } + *optr = 0; /* zero terminate output buffer */ + +} + +/* + * Returns true if the given URL is absolute (as opposed to relative) within + * the buffer size. Returns the scheme in the buffer if TRUE and 'buf' is + * non-NULL. + */ +bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen) +{ + size_t i; +#ifdef WIN32 + if(STARTS_WITH_DRIVE_PREFIX(url)) + return FALSE; +#endif + for(i = 0; i < buflen && url[i]; ++i) { + char s = url[i]; + if((s == ':') && (url[i + 1] == '/')) { + if(buf) + buf[i] = 0; + return TRUE; + } + /* RFC 3986 3.1 explains: + scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + */ + else if(ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') ) { + if(buf) + buf[i] = (char)TOLOWER(s); + } + else + break; + } + return FALSE; +} + +/* + * Concatenate a relative URL to a base URL making it absolute. + * URL-encodes any spaces. + * The returned pointer must be freed by the caller unless NULL + * (returns NULL on out of memory). + */ +static char *concat_url(const char *base, const char *relurl) +{ + /*** + TRY to append this new path to the old URL + to the right of the host part. Oh crap, this is doomed to cause + problems in the future... + */ + char *newest; + char *protsep; + char *pathsep; + size_t newlen; + bool host_changed = FALSE; + + const char *useurl = relurl; + size_t urllen; + + /* we must make our own copy of the URL to play with, as it may + point to read-only data */ + char *url_clone = strdup(base); + + if(!url_clone) + return NULL; /* skip out of this NOW */ + + /* protsep points to the start of the host name */ + protsep = strstr(url_clone, "//"); + if(!protsep) + protsep = url_clone; + else + protsep += 2; /* pass the slashes */ + + if('/' != relurl[0]) { + int level = 0; + + /* First we need to find out if there's a ?-letter in the URL, + and cut it and the right-side of that off */ + pathsep = strchr(protsep, '?'); + if(pathsep) + *pathsep = 0; + + /* we have a relative path to append to the last slash if there's one + available, or if the new URL is just a query string (starts with a + '?') we append the new one at the end of the entire currently worked + out URL */ + if(useurl[0] != '?') { + pathsep = strrchr(protsep, '/'); + if(pathsep) + *pathsep = 0; + } + + /* Check if there's any slash after the host name, and if so, remember + that position instead */ + pathsep = strchr(protsep, '/'); + if(pathsep) + protsep = pathsep + 1; + else + protsep = NULL; + + /* now deal with one "./" or any amount of "../" in the newurl + and act accordingly */ + + if((useurl[0] == '.') && (useurl[1] == '/')) + useurl += 2; /* just skip the "./" */ + + while((useurl[0] == '.') && + (useurl[1] == '.') && + (useurl[2] == '/')) { + level++; + useurl += 3; /* pass the "../" */ + } + + if(protsep) { + while(level--) { + /* cut off one more level from the right of the original URL */ + pathsep = strrchr(protsep, '/'); + if(pathsep) + *pathsep = 0; + else { + *protsep = 0; + break; + } + } + } + } + else { + /* We got a new absolute path for this server */ + + if((relurl[0] == '/') && (relurl[1] == '/')) { + /* the new URL starts with //, just keep the protocol part from the + original one */ + *protsep = 0; + useurl = &relurl[2]; /* we keep the slashes from the original, so we + skip the new ones */ + host_changed = TRUE; + } + else { + /* cut off the original URL from the first slash, or deal with URLs + without slash */ + pathsep = strchr(protsep, '/'); + if(pathsep) { + /* When people use badly formatted URLs, such as + "http://www.url.com?dir=/home/daniel" we must not use the first + slash, if there's a ?-letter before it! */ + char *sep = strchr(protsep, '?'); + if(sep && (sep < pathsep)) + pathsep = sep; + *pathsep = 0; + } + else { + /* There was no slash. Now, since we might be operating on a badly + formatted URL, such as "http://www.url.com?id=2380" which doesn't + use a slash separator as it is supposed to, we need to check for a + ?-letter as well! */ + pathsep = strchr(protsep, '?'); + if(pathsep) + *pathsep = 0; + } + } + } + + /* If the new part contains a space, this is a mighty stupid redirect + but we still make an effort to do "right". To the left of a '?' + letter we replace each space with %20 while it is replaced with '+' + on the right side of the '?' letter. + */ + newlen = strlen_url(useurl, !host_changed); + + urllen = strlen(url_clone); + + newest = malloc(urllen + 1 + /* possible slash */ + newlen + 1 /* zero byte */); + + if(!newest) { + free(url_clone); /* don't leak this */ + return NULL; + } + + /* copy over the root url part */ + memcpy(newest, url_clone, urllen); + + /* check if we need to append a slash */ + if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0])) + ; + else + newest[urllen++]='/'; + + /* then append the new piece on the right side */ + strcpy_url(&newest[urllen], useurl, !host_changed); + + free(url_clone); + + return newest; +} + +/* + * parse_hostname_login() + * + * Parse the login details (user name, password and options) from the URL and + * strip them out of the host name + * + */ +static CURLUcode parse_hostname_login(struct Curl_URL *u, + const struct Curl_handler *h, + char **hostname, + unsigned int flags) +{ + CURLUcode result = CURLUE_OK; + CURLcode ccode; + char *userp = NULL; + char *passwdp = NULL; + char *optionsp = NULL; + + /* At this point, we're hoping all the other special cases have + * been taken care of, so conn->host.name is at most + * [user[:password][;options]]@]hostname + * + * We need somewhere to put the embedded details, so do that first. + */ + + char *ptr = strchr(*hostname, '@'); + char *login = *hostname; + + if(!ptr) + goto out; + + /* We will now try to extract the + * possible login information in a string like: + * ftp://user:password@ftp.my.site:8021/README */ + *hostname = ++ptr; + + /* We could use the login information in the URL so extract it. Only parse + options if the handler says we should. Note that 'h' might be NULL! */ + ccode = Curl_parse_login_details(login, ptr - login - 1, + &userp, &passwdp, + (h && (h->flags & PROTOPT_URLOPTIONS)) ? + &optionsp:NULL); + if(ccode) { + result = CURLUE_MALFORMED_INPUT; + goto out; + } + + if(userp) { + if(flags & CURLU_DISALLOW_USER) { + /* Option DISALLOW_USER is set and url contains username. */ + result = CURLUE_USER_NOT_ALLOWED; + goto out; + } + + u->user = userp; + } + + if(passwdp) + u->password = passwdp; + + if(optionsp) + u->options = optionsp; + + return CURLUE_OK; + out: + + free(userp); + free(passwdp); + free(optionsp); + + return result; +} + +UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname) +{ + char *portptr = NULL; + char endbracket; + int len; + + /* + * Find the end of an IPv6 address, either on the ']' ending bracket or + * a percent-encoded zone index. + */ + if(1 == sscanf(hostname, "[%*45[0123456789abcdefABCDEF:.]%c%n", + &endbracket, &len)) { + if(']' == endbracket) + portptr = &hostname[len]; + else if('%' == endbracket) { + int zonelen = len; + if(1 == sscanf(hostname + zonelen, "%*[^]]%c%n", &endbracket, &len)) { + if(']' != endbracket) + return CURLUE_MALFORMED_INPUT; + portptr = &hostname[--zonelen + len + 1]; + } + else + return CURLUE_MALFORMED_INPUT; + } + else + return CURLUE_MALFORMED_INPUT; + + /* this is a RFC2732-style specified IP-address */ + if(portptr && *portptr) { + if(*portptr != ':') + return CURLUE_MALFORMED_INPUT; + } + else + portptr = NULL; + } + else + portptr = strchr(hostname, ':'); + + if(portptr) { + char *rest; + long port; + char portbuf[7]; + + /* Browser behavior adaptation. If there's a colon with no digits after, + just cut off the name there which makes us ignore the colon and just + use the default port. Firefox, Chrome and Safari all do that. */ + if(!portptr[1]) { + *portptr = '\0'; + return CURLUE_OK; + } + + if(!ISDIGIT(portptr[1])) + return CURLUE_BAD_PORT_NUMBER; + + port = strtol(portptr + 1, &rest, 10); /* Port number must be decimal */ + + if((port <= 0) || (port > 0xffff)) + /* Single unix standard says port numbers are 16 bits long, but we don't + treat port zero as OK. */ + return CURLUE_BAD_PORT_NUMBER; + + if(rest[0]) + return CURLUE_BAD_PORT_NUMBER; + + *portptr++ = '\0'; /* cut off the name there */ + *rest = 0; + /* generate a new port number string to get rid of leading zeroes etc */ + msnprintf(portbuf, sizeof(portbuf), "%ld", port); + u->portnum = port; + u->port = strdup(portbuf); + if(!u->port) + return CURLUE_OUT_OF_MEMORY; + } + + return CURLUE_OK; +} + +/* scan for byte values < 31 or 127 */ +static CURLUcode junkscan(char *part) +{ + if(part) { + static const char badbytes[]={ + /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x7f, + 0x00 /* zero terminate */ + }; + size_t n = strlen(part); + size_t nfine = strcspn(part, badbytes); + if(nfine != n) + /* since we don't know which part is scanned, return a generic error + code */ + return CURLUE_MALFORMED_INPUT; + } + return CURLUE_OK; +} + +static CURLUcode hostname_check(struct Curl_URL *u, char *hostname) +{ + const char *l = NULL; /* accepted characters */ + size_t len; + size_t hlen = strlen(hostname); + + if(hostname[0] == '[') { + hostname++; + l = "0123456789abcdefABCDEF::."; + hlen -= 2; + } + + if(l) { + /* only valid letters are ok */ + len = strspn(hostname, l); + if(hlen != len) { + if(hostname[len] == '%') { + /* this could now be '%[zone id]' */ + char zoneid[16]; + int i = 0; + char *h = &hostname[len + 1]; + /* pass '25' if present and is a url encoded percent sign */ + if(!strncmp(h, "25", 2) && h[2] && (h[2] != ']')) + h += 2; + while(*h && (*h != ']') && (i < 15)) + zoneid[i++] = *h++; + if(!i || (']' != *h)) + return CURLUE_MALFORMED_INPUT; + zoneid[i] = 0; + u->zoneid = strdup(zoneid); + if(!u->zoneid) + return CURLUE_OUT_OF_MEMORY; + hostname[len] = ']'; /* insert end bracket */ + hostname[len + 1] = 0; /* terminate the hostname */ + } + else + return CURLUE_MALFORMED_INPUT; + /* hostname is fine */ + } + } + else { + /* letters from the second string is not ok */ + len = strcspn(hostname, " "); + if(hlen != len) + /* hostname with bad content */ + return CURLUE_MALFORMED_INPUT; + } + if(!hostname[0]) + return CURLUE_NO_HOST; + return CURLUE_OK; +} + +#define HOSTNAME_END(x) (((x) == '/') || ((x) == '?') || ((x) == '#')) + +static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) +{ + char *path; + bool path_alloced = FALSE; + char *hostname; + char *query = NULL; + char *fragment = NULL; + CURLUcode result; + bool url_has_scheme = FALSE; + char schemebuf[MAX_SCHEME_LEN + 1]; + char *schemep = NULL; + size_t schemelen = 0; + size_t urllen; + const struct Curl_handler *h = NULL; + + if(!url) + return CURLUE_MALFORMED_INPUT; + + /************************************************************* + * Parse the URL. + ************************************************************/ + /* allocate scratch area */ + urllen = strlen(url); + if(urllen > CURL_MAX_INPUT_LENGTH) + /* excessive input length */ + return CURLUE_MALFORMED_INPUT; + + path = u->scratch = malloc(urllen * 2 + 2); + if(!path) + return CURLUE_OUT_OF_MEMORY; + + hostname = &path[urllen + 1]; + hostname[0] = 0; + + if(Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf))) { + url_has_scheme = TRUE; + schemelen = strlen(schemebuf); + } + + /* handle the file: scheme */ + if(url_has_scheme && strcasecompare(schemebuf, "file")) { + /* path has been allocated large enough to hold this */ + strcpy(path, &url[5]); + + hostname = NULL; /* no host for file: URLs */ + u->scheme = strdup("file"); + if(!u->scheme) + return CURLUE_OUT_OF_MEMORY; + + /* Extra handling URLs with an authority component (i.e. that start with + * "file://") + * + * We allow omitted hostname (e.g. file:/) -- valid according to + * RFC 8089, but not the (current) WHAT-WG URL spec. + */ + if(path[0] == '/' && path[1] == '/') { + /* swallow the two slashes */ + char *ptr = &path[2]; + + /* + * According to RFC 8089, a file: URL can be reliably dereferenced if: + * + * o it has no/blank hostname, or + * + * o the hostname matches "localhost" (case-insensitively), or + * + * o the hostname is a FQDN that resolves to this machine. + * + * For brevity, we only consider URLs with empty, "localhost", or + * "127.0.0.1" hostnames as local. + * + * Additionally, there is an exception for URLs with a Windows drive + * letter in the authority (which was accidentally omitted from RFC 8089 + * Appendix E, but believe me, it was meant to be there. --MK) + */ + if(ptr[0] != '/' && !STARTS_WITH_URL_DRIVE_PREFIX(ptr)) { + /* the URL includes a host name, it must match "localhost" or + "127.0.0.1" to be valid */ + if(!checkprefix("localhost/", ptr) && + !checkprefix("127.0.0.1/", ptr)) { + /* Invalid file://hostname/, expected localhost or 127.0.0.1 or + none */ + return CURLUE_MALFORMED_INPUT; + } + ptr += 9; /* now points to the slash after the host */ + } + + path = ptr; + } + +#if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__) + /* Don't allow Windows drive letters when not in Windows. + * This catches both "file:/c:" and "file:c:" */ + if(('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) || + STARTS_WITH_URL_DRIVE_PREFIX(path)) { + /* File drive letters are only accepted in MSDOS/Windows */ + return CURLUE_MALFORMED_INPUT; + } +#else + /* If the path starts with a slash and a drive letter, ditch the slash */ + if('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) { + /* This cannot be done with strcpy, as the memory chunks overlap! */ + memmove(path, &path[1], strlen(&path[1]) + 1); + } +#endif + + } + else { + /* clear path */ + const char *p; + const char *hostp; + size_t len; + path[0] = 0; + + if(url_has_scheme) { + int i = 0; + p = &url[schemelen + 1]; + while(p && (*p == '/') && (i < 4)) { + p++; + i++; + } + if((i < 1) || (i>3)) + /* less than one or more than three slashes */ + return CURLUE_MALFORMED_INPUT; + + schemep = schemebuf; + if(!Curl_builtin_scheme(schemep) && + !(flags & CURLU_NON_SUPPORT_SCHEME)) + return CURLUE_UNSUPPORTED_SCHEME; + + if(junkscan(schemep)) + return CURLUE_MALFORMED_INPUT; + } + else { + /* no scheme! */ + + if(!(flags & (CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME))) + return CURLUE_MALFORMED_INPUT; + if(flags & CURLU_DEFAULT_SCHEME) + schemep = (char *) DEFAULT_SCHEME; + + /* + * The URL was badly formatted, let's try without scheme specified. + */ + p = url; + } + hostp = p; /* host name starts here */ + + while(*p && !HOSTNAME_END(*p)) /* find end of host name */ + p++; + + len = p - hostp; + if(!len) + return CURLUE_MALFORMED_INPUT; + + memcpy(hostname, hostp, len); + hostname[len] = 0; + + if((flags & CURLU_GUESS_SCHEME) && !schemep) { + /* legacy curl-style guess based on host name */ + if(checkprefix("ftp.", hostname)) + schemep = (char *)"ftp"; + else if(checkprefix("dict.", hostname)) + schemep = (char *)"dict"; + else if(checkprefix("ldap.", hostname)) + schemep = (char *)"ldap"; + else if(checkprefix("imap.", hostname)) + schemep = (char *)"imap"; + else if(checkprefix("smtp.", hostname)) + schemep = (char *)"smtp"; + else if(checkprefix("pop3.", hostname)) + schemep = (char *)"pop3"; + else + schemep = (char *)"http"; + } + + len = strlen(p); + memcpy(path, p, len); + path[len] = 0; + + u->scheme = strdup(schemep); + if(!u->scheme) + return CURLUE_OUT_OF_MEMORY; + } + + /* if this is a known scheme, get some details */ + h = Curl_builtin_scheme(u->scheme); + + if(junkscan(path)) + return CURLUE_MALFORMED_INPUT; + + query = strchr(path, '?'); + if(query) + *query++ = 0; + + fragment = strchr(query?query:path, '#'); + if(fragment) + *fragment++ = 0; + + if(!path[0]) + /* if there's no path set, unset */ + path = NULL; + else if(!(flags & CURLU_PATH_AS_IS)) { + /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */ + char *newp = Curl_dedotdotify(path); + if(!newp) + return CURLUE_OUT_OF_MEMORY; + + if(strcmp(newp, path)) { + /* if we got a new version */ + path = newp; + path_alloced = TRUE; + } + else + free(newp); + } + if(path) { + u->path = path_alloced?path:strdup(path); + if(!u->path) + return CURLUE_OUT_OF_MEMORY; + } + + if(hostname) { + /* + * Parse the login details and strip them out of the host name. + */ + if(junkscan(hostname)) + return CURLUE_MALFORMED_INPUT; + + result = parse_hostname_login(u, h, &hostname, flags); + if(result) + return result; + + result = Curl_parse_port(u, hostname); + if(result) + return result; + + result = hostname_check(u, hostname); + if(result) + return result; + + u->host = strdup(hostname); + if(!u->host) + return CURLUE_OUT_OF_MEMORY; + } + + if(query) { + u->query = strdup(query); + if(!u->query) + return CURLUE_OUT_OF_MEMORY; + } + if(fragment && fragment[0]) { + u->fragment = strdup(fragment); + if(!u->fragment) + return CURLUE_OUT_OF_MEMORY; + } + + free(u->scratch); + u->scratch = NULL; + + return CURLUE_OK; +} + +/* + * Parse the URL and set the relevant members of the Curl_URL struct. + */ +static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) +{ + CURLUcode result = seturl(url, u, flags); + if(result) { + free_urlhandle(u); + memset(u, 0, sizeof(struct Curl_URL)); + } + return result; +} + +/* + */ +CURLU *curl_url(void) +{ + return calloc(sizeof(struct Curl_URL), 1); +} + +void curl_url_cleanup(CURLU *u) +{ + if(u) { + free_urlhandle(u); + free(u); + } +} + +#define DUP(dest, src, name) \ + if(src->name) { \ + dest->name = strdup(src->name); \ + if(!dest->name) \ + goto fail; \ + } + +CURLU *curl_url_dup(CURLU *in) +{ + struct Curl_URL *u = calloc(sizeof(struct Curl_URL), 1); + if(u) { + DUP(u, in, scheme); + DUP(u, in, user); + DUP(u, in, password); + DUP(u, in, options); + DUP(u, in, host); + DUP(u, in, port); + DUP(u, in, path); + DUP(u, in, query); + DUP(u, in, fragment); + u->portnum = in->portnum; + } + return u; + fail: + curl_url_cleanup(u); + return NULL; +} + +CURLUcode curl_url_get(CURLU *u, CURLUPart what, + char **part, unsigned int flags) +{ + char *ptr; + CURLUcode ifmissing = CURLUE_UNKNOWN_PART; + char portbuf[7]; + bool urldecode = (flags & CURLU_URLDECODE)?1:0; + bool plusdecode = FALSE; + (void)flags; + if(!u) + return CURLUE_BAD_HANDLE; + if(!part) + return CURLUE_BAD_PARTPOINTER; + *part = NULL; + + switch(what) { + case CURLUPART_SCHEME: + ptr = u->scheme; + ifmissing = CURLUE_NO_SCHEME; + urldecode = FALSE; /* never for schemes */ + break; + case CURLUPART_USER: + ptr = u->user; + ifmissing = CURLUE_NO_USER; + break; + case CURLUPART_PASSWORD: + ptr = u->password; + ifmissing = CURLUE_NO_PASSWORD; + break; + case CURLUPART_OPTIONS: + ptr = u->options; + ifmissing = CURLUE_NO_OPTIONS; + break; + case CURLUPART_HOST: + ptr = u->host; + ifmissing = CURLUE_NO_HOST; + break; + case CURLUPART_ZONEID: + ptr = u->zoneid; + break; + case CURLUPART_PORT: + ptr = u->port; + ifmissing = CURLUE_NO_PORT; + urldecode = FALSE; /* never for port */ + if(!ptr && (flags & CURLU_DEFAULT_PORT) && u->scheme) { + /* there's no stored port number, but asked to deliver + a default one for the scheme */ + const struct Curl_handler *h = + Curl_builtin_scheme(u->scheme); + if(h) { + msnprintf(portbuf, sizeof(portbuf), "%ld", h->defport); + ptr = portbuf; + } + } + else if(ptr && u->scheme) { + /* there is a stored port number, but ask to inhibit if + it matches the default one for the scheme */ + const struct Curl_handler *h = + Curl_builtin_scheme(u->scheme); + if(h && (h->defport == u->portnum) && + (flags & CURLU_NO_DEFAULT_PORT)) + ptr = NULL; + } + break; + case CURLUPART_PATH: + ptr = u->path; + if(!ptr) { + ptr = u->path = strdup("/"); + if(!u->path) + return CURLUE_OUT_OF_MEMORY; + } + break; + case CURLUPART_QUERY: + ptr = u->query; + ifmissing = CURLUE_NO_QUERY; + plusdecode = urldecode; + break; + case CURLUPART_FRAGMENT: + ptr = u->fragment; + ifmissing = CURLUE_NO_FRAGMENT; + break; + case CURLUPART_URL: { + char *url; + char *scheme; + char *options = u->options; + char *port = u->port; + char *allochost = NULL; + if(u->scheme && strcasecompare("file", u->scheme)) { + url = aprintf("file://%s%s%s", + u->path, + u->fragment? "#": "", + u->fragment? u->fragment : ""); + } + else if(!u->host) + return CURLUE_NO_HOST; + else { + const struct Curl_handler *h = NULL; + if(u->scheme) + scheme = u->scheme; + else if(flags & CURLU_DEFAULT_SCHEME) + scheme = (char *) DEFAULT_SCHEME; + else + return CURLUE_NO_SCHEME; + + if(scheme) { + h = Curl_builtin_scheme(scheme); + if(!port && (flags & CURLU_DEFAULT_PORT)) { + /* there's no stored port number, but asked to deliver + a default one for the scheme */ + if(h) { + msnprintf(portbuf, sizeof(portbuf), "%ld", h->defport); + port = portbuf; + } + } + else if(port) { + /* there is a stored port number, but asked to inhibit if it matches + the default one for the scheme */ + if(h && (h->defport == u->portnum) && + (flags & CURLU_NO_DEFAULT_PORT)) + port = NULL; + } + } + if(h && !(h->flags & PROTOPT_URLOPTIONS)) + options = NULL; + + if((u->host[0] == '[') && u->zoneid) { + /* make it '[ host %25 zoneid ]' */ + size_t hostlen = strlen(u->host); + size_t alen = hostlen + 3 + strlen(u->zoneid) + 1; + allochost = malloc(alen); + if(!allochost) + return CURLUE_OUT_OF_MEMORY; + memcpy(allochost, u->host, hostlen - 1); + msnprintf(&allochost[hostlen - 1], alen - hostlen + 1, + "%%25%s]", u->zoneid); + } + + url = aprintf("%s://%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + scheme, + u->user ? u->user : "", + u->password ? ":": "", + u->password ? u->password : "", + options ? ";" : "", + options ? options : "", + (u->user || u->password || options) ? "@": "", + allochost ? allochost : u->host, + port ? ":": "", + port ? port : "", + (u->path && (u->path[0] != '/')) ? "/": "", + u->path ? u->path : "/", + (u->query && u->query[0]) ? "?": "", + (u->query && u->query[0]) ? u->query : "", + u->fragment? "#": "", + u->fragment? u->fragment : ""); + free(allochost); + } + if(!url) + return CURLUE_OUT_OF_MEMORY; + *part = url; + return CURLUE_OK; + } + default: + ptr = NULL; + break; + } + if(ptr) { + *part = strdup(ptr); + if(!*part) + return CURLUE_OUT_OF_MEMORY; + if(plusdecode) { + /* convert + to space */ + char *plus; + for(plus = *part; *plus; ++plus) { + if(*plus == '+') + *plus = ' '; + } + } + if(urldecode) { + char *decoded; + size_t dlen; + CURLcode res = Curl_urldecode(NULL, *part, 0, &decoded, &dlen, TRUE); + free(*part); + if(res) { + *part = NULL; + return CURLUE_URLDECODE; + } + *part = decoded; + } + return CURLUE_OK; + } + else + return ifmissing; +} + +CURLUcode curl_url_set(CURLU *u, CURLUPart what, + const char *part, unsigned int flags) +{ + char **storep = NULL; + long port = 0; + bool urlencode = (flags & CURLU_URLENCODE)? 1 : 0; + bool plusencode = FALSE; + bool urlskipslash = FALSE; + bool appendquery = FALSE; + bool equalsencode = FALSE; + + if(!u) + return CURLUE_BAD_HANDLE; + if(!part) { + /* setting a part to NULL clears it */ + switch(what) { + case CURLUPART_URL: + break; + case CURLUPART_SCHEME: + storep = &u->scheme; + break; + case CURLUPART_USER: + storep = &u->user; + break; + case CURLUPART_PASSWORD: + storep = &u->password; + break; + case CURLUPART_OPTIONS: + storep = &u->options; + break; + case CURLUPART_HOST: + storep = &u->host; + break; + case CURLUPART_ZONEID: + storep = &u->zoneid; + break; + case CURLUPART_PORT: + u->portnum = 0; + storep = &u->port; + break; + case CURLUPART_PATH: + storep = &u->path; + break; + case CURLUPART_QUERY: + storep = &u->query; + break; + case CURLUPART_FRAGMENT: + storep = &u->fragment; + break; + default: + return CURLUE_UNKNOWN_PART; + } + if(storep && *storep) { + free(*storep); + *storep = NULL; + } + return CURLUE_OK; + } + + switch(what) { + case CURLUPART_SCHEME: + if(strlen(part) > MAX_SCHEME_LEN) + /* too long */ + return CURLUE_MALFORMED_INPUT; + if(!(flags & CURLU_NON_SUPPORT_SCHEME) && + /* verify that it is a fine scheme */ + !Curl_builtin_scheme(part)) + return CURLUE_UNSUPPORTED_SCHEME; + storep = &u->scheme; + urlencode = FALSE; /* never */ + break; + case CURLUPART_USER: + storep = &u->user; + break; + case CURLUPART_PASSWORD: + storep = &u->password; + break; + case CURLUPART_OPTIONS: + storep = &u->options; + break; + case CURLUPART_HOST: + storep = &u->host; + free(u->zoneid); + u->zoneid = NULL; + break; + case CURLUPART_ZONEID: + storep = &u->zoneid; + break; + case CURLUPART_PORT: + { + char *endp; + urlencode = FALSE; /* never */ + port = strtol(part, &endp, 10); /* Port number must be decimal */ + if((port <= 0) || (port > 0xffff)) + return CURLUE_BAD_PORT_NUMBER; + if(*endp) + /* weirdly provided number, not good! */ + return CURLUE_MALFORMED_INPUT; + storep = &u->port; + } + break; + case CURLUPART_PATH: + urlskipslash = TRUE; + storep = &u->path; + break; + case CURLUPART_QUERY: + plusencode = urlencode; + appendquery = (flags & CURLU_APPENDQUERY)?1:0; + equalsencode = appendquery; + storep = &u->query; + break; + case CURLUPART_FRAGMENT: + storep = &u->fragment; + break; + case CURLUPART_URL: { + /* + * Allow a new URL to replace the existing (if any) contents. + * + * If the existing contents is enough for a URL, allow a relative URL to + * replace it. + */ + CURLUcode result; + char *oldurl; + char *redired_url; + CURLU *handle2; + + if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN + 1)) { + handle2 = curl_url(); + if(!handle2) + return CURLUE_OUT_OF_MEMORY; + result = parseurl(part, handle2, flags); + if(!result) + mv_urlhandle(handle2, u); + else + curl_url_cleanup(handle2); + return result; + } + /* extract the full "old" URL to do the redirect on */ + result = curl_url_get(u, CURLUPART_URL, &oldurl, flags); + if(result) { + /* couldn't get the old URL, just use the new! */ + handle2 = curl_url(); + if(!handle2) + return CURLUE_OUT_OF_MEMORY; + result = parseurl(part, handle2, flags); + if(!result) + mv_urlhandle(handle2, u); + else + curl_url_cleanup(handle2); + return result; + } + + /* apply the relative part to create a new URL */ + redired_url = concat_url(oldurl, part); + free(oldurl); + if(!redired_url) + return CURLUE_OUT_OF_MEMORY; + + /* now parse the new URL */ + handle2 = curl_url(); + if(!handle2) { + free(redired_url); + return CURLUE_OUT_OF_MEMORY; + } + result = parseurl(redired_url, handle2, flags); + free(redired_url); + if(!result) + mv_urlhandle(handle2, u); + else + curl_url_cleanup(handle2); + return result; + } + default: + return CURLUE_UNKNOWN_PART; + } + if(storep) { + const char *newp = part; + size_t nalloc = strlen(part); + + if(nalloc > CURL_MAX_INPUT_LENGTH) + /* excessive input length */ + return CURLUE_MALFORMED_INPUT; + + if(urlencode) { + const unsigned char *i; + char *o; + bool free_part = FALSE; + char *enc = malloc(nalloc * 3 + 1); /* for worst case! */ + if(!enc) + return CURLUE_OUT_OF_MEMORY; + if(plusencode) { + /* space to plus */ + i = (const unsigned char *)part; + for(o = enc; *i; ++o, ++i) + *o = (*i == ' ') ? '+' : *i; + *o = 0; /* zero terminate */ + part = strdup(enc); + if(!part) { + free(enc); + return CURLUE_OUT_OF_MEMORY; + } + free_part = TRUE; + } + for(i = (const unsigned char *)part, o = enc; *i; i++) { + if(Curl_isunreserved(*i) || + ((*i == '/') && urlskipslash) || + ((*i == '=') && equalsencode) || + ((*i == '+') && plusencode)) { + if((*i == '=') && equalsencode) + /* only skip the first equals sign */ + equalsencode = FALSE; + *o = *i; + o++; + } + else { + msnprintf(o, 4, "%%%02x", *i); + o += 3; + } + } + *o = 0; /* zero terminate */ + newp = enc; + if(free_part) + free((char *)part); + } + else { + char *p; + newp = strdup(part); + if(!newp) + return CURLUE_OUT_OF_MEMORY; + p = (char *)newp; + while(*p) { + /* make sure percent encoded are lower case */ + if((*p == '%') && ISXDIGIT(p[1]) && ISXDIGIT(p[2]) && + (ISUPPER(p[1]) || ISUPPER(p[2]))) { + p[1] = (char)TOLOWER(p[1]); + p[2] = (char)TOLOWER(p[2]); + p += 3; + } + else + p++; + } + } + + if(appendquery) { + /* Append the string onto the old query. Add a '&' separator if none is + present at the end of the exsting query already */ + size_t querylen = u->query ? strlen(u->query) : 0; + bool addamperand = querylen && (u->query[querylen -1] != '&'); + if(querylen) { + size_t newplen = strlen(newp); + char *p = malloc(querylen + addamperand + newplen + 1); + if(!p) { + free((char *)newp); + return CURLUE_OUT_OF_MEMORY; + } + strcpy(p, u->query); /* original query */ + if(addamperand) + p[querylen] = '&'; /* ampersand */ + strcpy(&p[querylen + addamperand], newp); /* new suffix */ + free((char *)newp); + free(*storep); + *storep = p; + return CURLUE_OK; + } + } + + if(what == CURLUPART_HOST) { + if(hostname_check(u, (char *)newp)) { + free((char *)newp); + return CURLUE_MALFORMED_INPUT; + } + } + + free(*storep); + *storep = (char *)newp; + } + /* set after the string, to make it not assigned if the allocation above + fails */ + if(port) + u->portnum = port; + return CURLUE_OK; +} diff --git a/libcurl/lib/urldata.h b/libcurl/lib/urldata.h new file mode 100644 index 0000000..fdc185b --- /dev/null +++ b/libcurl/lib/urldata.h @@ -0,0 +1,1837 @@ +#ifndef HEADER_CURL_URLDATA_H +#define HEADER_CURL_URLDATA_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This file is for lib internal stuff */ + +#include "curl_setup.h" + +#define PORT_FTP 21 +#define PORT_FTPS 990 +#define PORT_TELNET 23 +#define PORT_HTTP 80 +#define PORT_HTTPS 443 +#define PORT_DICT 2628 +#define PORT_LDAP 389 +#define PORT_LDAPS 636 +#define PORT_TFTP 69 +#define PORT_SSH 22 +#define PORT_IMAP 143 +#define PORT_IMAPS 993 +#define PORT_POP3 110 +#define PORT_POP3S 995 +#define PORT_SMB 445 +#define PORT_SMBS 445 +#define PORT_SMTP 25 +#define PORT_SMTPS 465 /* sometimes called SSMTP */ +#define PORT_RTSP 554 +#define PORT_RTMP 1935 +#define PORT_RTMPT PORT_HTTP +#define PORT_RTMPS PORT_HTTPS +#define PORT_GOPHER 70 + +#define DICT_MATCH "/MATCH:" +#define DICT_MATCH2 "/M:" +#define DICT_MATCH3 "/FIND:" +#define DICT_DEFINE "/DEFINE:" +#define DICT_DEFINE2 "/D:" +#define DICT_DEFINE3 "/LOOKUP:" + +#define CURL_DEFAULT_USER "anonymous" +#define CURL_DEFAULT_PASSWORD "ftp@example.com" + +/* Convenience defines for checking protocols or their SSL based version. Each + protocol handler should only ever have a single CURLPROTO_ in its protocol + field. */ +#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP|CURLPROTO_HTTPS) +#define PROTO_FAMILY_FTP (CURLPROTO_FTP|CURLPROTO_FTPS) +#define PROTO_FAMILY_POP3 (CURLPROTO_POP3|CURLPROTO_POP3S) +#define PROTO_FAMILY_SMB (CURLPROTO_SMB|CURLPROTO_SMBS) +#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP|CURLPROTO_SMTPS) + +#define DEFAULT_CONNCACHE_SIZE 5 + +/* length of longest IPv6 address string including the trailing null */ +#define MAX_IPADR_LEN sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") + +/* Default FTP/IMAP etc response timeout in milliseconds. + Symbian OS panics when given a timeout much greater than 1/2 hour. +*/ +#define RESP_TIMEOUT (120*1000) + +/* Max string intput length is a precaution against abuse and to detect junk + input easier and better. */ +#define CURL_MAX_INPUT_LENGTH 8000000 + +#include "cookie.h" +#include "psl.h" +#include "formdata.h" + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NETINET_IN6_H +#include +#endif + +#include "timeval.h" + +#include + +#include "http_chunks.h" /* for the structs and enum stuff */ +#include "hostip.h" +#include "hash.h" +#include "splay.h" + +/* return the count of bytes sent, or -1 on error */ +typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */ + int sockindex, /* socketindex */ + const void *buf, /* data to write */ + size_t len, /* max amount to write */ + CURLcode *err); /* error to return */ + +/* return the count of bytes read, or -1 on error */ +typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ + int sockindex, /* socketindex */ + char *buf, /* store data here */ + size_t len, /* max amount to read */ + CURLcode *err); /* error to return */ + +#include "mime.h" +#include "imap.h" +#include "pop3.h" +#include "smtp.h" +#include "ftp.h" +#include "file.h" +#include "ssh.h" +#include "http.h" +#include "rtsp.h" +#include "smb.h" +#include "wildcard.h" +#include "multihandle.h" + +#ifdef HAVE_GSSAPI +# ifdef HAVE_GSSGNU +# include +# elif defined HAVE_GSSAPI_GSSAPI_H +# include +# else +# include +# endif +# ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H +# include +# endif +#endif + +#ifdef HAVE_LIBSSH2_H +#include +#include +#endif /* HAVE_LIBSSH2_H */ + +/* Initial size of the buffer to store headers in, it'll be enlarged in case + of need. */ +#define HEADERSIZE 256 + +#define CURLEASY_MAGIC_NUMBER 0xc0dedbadU +#define GOOD_EASY_HANDLE(x) \ + ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER)) + +/* the type we use for storing a single boolean bit */ +typedef unsigned int bit; + +#ifdef HAVE_GSSAPI +/* Types needed for krb5-ftp connections */ +struct krb5buffer { + void *data; + size_t size; + size_t index; + bit eof_flag:1; +}; + +enum protection_level { + PROT_NONE, /* first in list */ + PROT_CLEAR, + PROT_SAFE, + PROT_CONFIDENTIAL, + PROT_PRIVATE, + PROT_CMD, + PROT_LAST /* last in list */ +}; +#endif + +/* enum for the nonblocking SSL connection state machine */ +typedef enum { + ssl_connect_1, + ssl_connect_2, + ssl_connect_2_reading, + ssl_connect_2_writing, + ssl_connect_3, + ssl_connect_done +} ssl_connect_state; + +typedef enum { + ssl_connection_none, + ssl_connection_negotiating, + ssl_connection_complete +} ssl_connection_state; + +/* SSL backend-specific data; declared differently by each SSL backend */ +struct ssl_backend_data; + +/* struct for data related to each SSL connection */ +struct ssl_connect_data { + /* Use ssl encrypted communications TRUE/FALSE, not necessarily using it atm + but at least asked to or meaning to use it. See 'state' for the exact + current state of the connection. */ + ssl_connection_state state; + ssl_connect_state connecting_state; +#if defined(USE_SSL) + struct ssl_backend_data *backend; +#endif + bit use:1; +}; + +struct ssl_primary_config { + long version; /* what version the client wants to use */ + long version_max; /* max supported version the client wants to use*/ + char *CApath; /* certificate dir (doesn't work on windows) */ + char *CAfile; /* certificate to verify peer against */ + char *clientcert; + char *random_file; /* path to file containing "random" data */ + char *egdsocket; /* path to file containing the EGD daemon socket */ + char *cipher_list; /* list of ciphers to use */ + char *cipher_list13; /* list of TLS 1.3 cipher suites to use */ + bit verifypeer:1; /* set TRUE if this is desired */ + bit verifyhost:1; /* set TRUE if CN/SAN must match hostname */ + bit verifystatus:1; /* set TRUE if certificate status must be checked */ + bit sessionid:1; /* cache session IDs or not */ +}; + +struct ssl_config_data { + struct ssl_primary_config primary; + long certverifyresult; /* result from the certificate verification */ + char *CRLfile; /* CRL to check certificate revocation */ + char *issuercert;/* optional issuer certificate filename */ + curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ + void *fsslctxp; /* parameter for call back */ + char *cert; /* client certificate file name */ + char *cert_type; /* format for certificate (default: PEM)*/ + char *key; /* private key file name */ + char *key_type; /* format for private key (default: PEM) */ + char *key_passwd; /* plain text private key password */ +#ifdef USE_TLS_SRP + char *username; /* TLS username (for, e.g., SRP) */ + char *password; /* TLS password (for, e.g., SRP) */ + enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */ +#endif + bit certinfo:1; /* gather lots of certificate info */ + bit falsestart:1; + bit enable_beast:1; /* allow this flaw for interoperability's sake*/ + bit no_revoke:1; /* disable SSL certificate revocation checks */ +}; + +struct ssl_general_config { + size_t max_ssl_sessions; /* SSL session id cache size */ +}; + +/* information stored about one single SSL session */ +struct curl_ssl_session { + char *name; /* host name for which this ID was used */ + char *conn_to_host; /* host name for the connection (may be NULL) */ + const char *scheme; /* protocol scheme used */ + void *sessionid; /* as returned from the SSL layer */ + size_t idsize; /* if known, otherwise 0 */ + long age; /* just a number, the higher the more recent */ + int remote_port; /* remote port */ + int conn_to_port; /* remote port for the connection (may be -1) */ + struct ssl_primary_config ssl_config; /* setup for this session */ +}; + +#ifdef USE_WINDOWS_SSPI +#include "curl_sspi.h" +#endif + +/* Struct used for Digest challenge-response authentication */ +struct digestdata { +#if defined(USE_WINDOWS_SSPI) + BYTE *input_token; + size_t input_token_len; + CtxtHandle *http_context; + /* copy of user/passwd used to make the identity for http_context. + either may be NULL. */ + char *user; + char *passwd; +#else + char *nonce; + char *cnonce; + char *realm; + int algo; + char *opaque; + char *qop; + char *algorithm; + int nc; /* nounce count */ + bit stale:1; /* set true for re-negotiation */ + bit userhash:1; +#endif +}; + +typedef enum { + NTLMSTATE_NONE, + NTLMSTATE_TYPE1, + NTLMSTATE_TYPE2, + NTLMSTATE_TYPE3, + NTLMSTATE_LAST +} curlntlm; + +typedef enum { + GSS_AUTHNONE, + GSS_AUTHRECV, + GSS_AUTHSENT, + GSS_AUTHDONE, + GSS_AUTHSUCC +} curlnegotiate; + +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) +#include +#endif + +/* Struct used for GSSAPI (Kerberos V5) authentication */ +#if defined(USE_KERBEROS5) +struct kerberos5data { +#if defined(USE_WINDOWS_SSPI) + CredHandle *credentials; + CtxtHandle *context; + TCHAR *spn; + SEC_WINNT_AUTH_IDENTITY identity; + SEC_WINNT_AUTH_IDENTITY *p_identity; + size_t token_max; + BYTE *output_token; +#else + gss_ctx_id_t context; + gss_name_t spn; +#endif +}; +#endif + +/* Struct used for NTLM challenge-response authentication */ +#if defined(USE_NTLM) +struct ntlmdata { +#ifdef USE_WINDOWS_SSPI +/* The sslContext is used for the Schannel bindings. The + * api is available on the Windows 7 SDK and later. + */ +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + CtxtHandle *sslContext; +#endif + CredHandle *credentials; + CtxtHandle *context; + SEC_WINNT_AUTH_IDENTITY identity; + SEC_WINNT_AUTH_IDENTITY *p_identity; + size_t token_max; + BYTE *output_token; + BYTE *input_token; + size_t input_token_len; + TCHAR *spn; +#else + unsigned int flags; + unsigned char nonce[8]; + void *target_info; /* TargetInfo received in the ntlm type-2 message */ + unsigned int target_info_len; +#endif +}; +#endif + +/* Struct used for Negotiate (SPNEGO) authentication */ +#ifdef USE_SPNEGO +struct negotiatedata { +#ifdef HAVE_GSSAPI + OM_uint32 status; + gss_ctx_id_t context; + gss_name_t spn; + gss_buffer_desc output_token; +#else +#ifdef USE_WINDOWS_SSPI +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + CtxtHandle *sslContext; +#endif + DWORD status; + CredHandle *credentials; + CtxtHandle *context; + SEC_WINNT_AUTH_IDENTITY identity; + SEC_WINNT_AUTH_IDENTITY *p_identity; + TCHAR *spn; + size_t token_max; + BYTE *output_token; + size_t output_token_length; +#endif +#endif + bool noauthpersist; + bool havenoauthpersist; + bool havenegdata; + bool havemultiplerequests; +}; +#endif + + +/* + * Boolean values that concerns this connection. + */ +struct ConnectBits { + /* always modify bits.close with the connclose() and connkeep() macros! */ + bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy + is complete */ + bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set + the first time on the first connect function call */ + bit close:1; /* if set, we close the connection after this request */ + bit reuse:1; /* if set, this is a re-used connection */ + bit conn_to_host:1; /* if set, this connection has a "connect to host" + that overrides the host in the URL */ + bit conn_to_port:1; /* if set, this connection has a "connect to port" + that overrides the port in the URL (remote port) */ + bit proxy:1; /* if set, this transfer is done through a proxy - any type */ + bit httpproxy:1; /* if set, this transfer is done through a http proxy */ + bit socksproxy:1; /* if set, this transfer is done through a socks proxy */ + bit user_passwd:1; /* do we use user+password for this connection? */ + bit proxy_user_passwd:1; /* user+password for the proxy? */ + bit ipv6_ip:1; /* we communicate with a remote site specified with pure IPv6 + IP address */ + bit ipv6:1; /* we communicate with a site using an IPv6 address */ + bit do_more:1; /* this is set TRUE if the ->curl_do_more() function is + supposed to be called, after ->curl_do() */ + bit protoconnstart:1;/* the protocol layer has STARTED its operation after + the TCP layer connect */ + bit retry:1; /* this connection is about to get closed and then + re-attempted at another connection. */ + bit tunnel_proxy:1; /* if CONNECT is used to "tunnel" through the proxy. + This is implicit when SSL-protocols are used through + proxies, but can also be enabled explicitly by + apps */ + bit authneg:1; /* TRUE when the auth phase has started, which means + that we are creating a request with an auth header, + but it is not the final request in the auth + negotiation. */ + bit rewindaftersend:1;/* TRUE when the sending couldn't be stopped even + though it will be discarded. When the whole send + operation is done, we must call the data rewind + callback. */ +#ifndef CURL_DISABLE_FTP + bit ftp_use_epsv:1; /* As set with CURLOPT_FTP_USE_EPSV, but if we find out + EPSV doesn't work we disable it for the forthcoming + requests */ + bit ftp_use_eprt:1; /* As set with CURLOPT_FTP_USE_EPRT, but if we find out + EPRT doesn't work we disable it for the forthcoming + requests */ + bit ftp_use_data_ssl:1; /* Enabled SSL for the data connection */ +#endif + bit netrc:1; /* name+password provided by netrc */ + bit userpwd_in_url:1; /* name+password found in url */ + bit stream_was_rewound:1; /* The stream was rewound after a request read + past the end of its response byte boundary */ + bit proxy_connect_closed:1; /* TRUE if a proxy disconnected the connection + in a CONNECT request with auth, so that + libcurl should reconnect and continue. */ + bit bound:1; /* set true if bind() has already been done on this socket/ + connection */ + bit type_set:1; /* type= was used in the URL */ + bit multiplex:1; /* connection is multiplexed */ + bit tcp_fastopen:1; /* use TCP Fast Open */ + bit tls_enable_npn:1; /* TLS NPN extension? */ + bit tls_enable_alpn:1; /* TLS ALPN extension? */ + bit socksproxy_connecting:1; /* connecting through a socks proxy */ + bit connect_only:1; +}; + +struct hostname { + char *rawalloc; /* allocated "raw" version of the name */ + char *encalloc; /* allocated IDN-encoded version of the name */ + char *name; /* name to use internally, might be encoded, might be raw */ + const char *dispname; /* name to display, as 'name' might be encoded */ +}; + +/* + * Flags on the keepon member of the Curl_transfer_keeper + */ + +#define KEEP_NONE 0 +#define KEEP_RECV (1<<0) /* there is or may be data to read */ +#define KEEP_SEND (1<<1) /* there is or may be data to write */ +#define KEEP_RECV_HOLD (1<<2) /* when set, no reading should be done but there + might still be data to read */ +#define KEEP_SEND_HOLD (1<<3) /* when set, no writing should be done but there + might still be data to write */ +#define KEEP_RECV_PAUSE (1<<4) /* reading is paused */ +#define KEEP_SEND_PAUSE (1<<5) /* writing is paused */ + +#define KEEP_RECVBITS (KEEP_RECV | KEEP_RECV_HOLD | KEEP_RECV_PAUSE) +#define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE) + +struct Curl_async { + char *hostname; + int port; + struct Curl_dns_entry *dns; + int status; /* if done is TRUE, this is the status from the callback */ + void *os_specific; /* 'struct thread_data' for Windows */ + bit done:1; /* set TRUE when the lookup is complete */ +}; + +#define FIRSTSOCKET 0 +#define SECONDARYSOCKET 1 + +/* These function pointer types are here only to allow easier typecasting + within the source when we need to cast between data pointers (such as NULL) + and function pointers. */ +typedef CURLcode (*Curl_do_more_func)(struct connectdata *, int *); +typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool); + +enum expect100 { + EXP100_SEND_DATA, /* enough waiting, just send the body now */ + EXP100_AWAITING_CONTINUE, /* waiting for the 100 Continue header */ + EXP100_SENDING_REQUEST, /* still sending the request but will wait for + the 100 header once done with the request */ + EXP100_FAILED /* used on 417 Expectation Failed */ +}; + +enum upgrade101 { + UPGR101_INIT, /* default state */ + UPGR101_REQUESTED, /* upgrade requested */ + UPGR101_RECEIVED, /* response received */ + UPGR101_WORKING /* talking upgraded protocol */ +}; + +struct dohresponse { + unsigned char *memory; + size_t size; +}; + +/* one of these for each DoH request */ +struct dnsprobe { + CURL *easy; + int dnstype; + unsigned char dohbuffer[512]; + size_t dohlen; + struct dohresponse serverdoh; +}; + +struct dohdata { + struct curl_slist *headers; + struct dnsprobe probe[2]; + unsigned int pending; /* still outstanding requests */ + const char *host; + int port; +}; + +/* + * Request specific data in the easy handle (Curl_easy). Previously, + * these members were on the connectdata struct but since a conn struct may + * now be shared between different Curl_easys, we store connection-specific + * data here. This struct only keeps stuff that's interesting for *this* + * request, as it will be cleared between multiple ones + */ +struct SingleRequest { + curl_off_t size; /* -1 if unknown at this point */ + curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch, + -1 means unlimited */ + curl_off_t bytecount; /* total number of bytes read */ + curl_off_t writebytecount; /* number of bytes written */ + + curl_off_t headerbytecount; /* only count received headers */ + curl_off_t deductheadercount; /* this amount of bytes doesn't count when we + check if anything has been transferred at + the end of a connection. We use this + counter to make only a 100 reply (without a + following second response code) result in a + CURLE_GOT_NOTHING error code */ + + struct curltime start; /* transfer started at this time */ + struct curltime now; /* current time */ + enum { + HEADER_NORMAL, /* no bad header at all */ + HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest + is normal data */ + HEADER_ALLBAD /* all was believed to be header */ + } badheader; /* the header was deemed bad and will be + written as body */ + int headerline; /* counts header lines to better track the + first one */ + char *hbufp; /* points at *end* of header line */ + size_t hbuflen; + char *str; /* within buf */ + char *str_start; /* within buf */ + char *end_ptr; /* within buf */ + char *p; /* within headerbuff */ + curl_off_t offset; /* possible resume offset read from the + Content-Range: header */ + int httpcode; /* error code from the 'HTTP/1.? XXX' or + 'RTSP/1.? XXX' line */ + struct curltime start100; /* time stamp to wait for the 100 code from */ + enum expect100 exp100; /* expect 100 continue state */ + enum upgrade101 upgr101; /* 101 upgrade state */ + + struct contenc_writer_s *writer_stack; /* Content unencoding stack. */ + /* See sec 3.5, RFC2616. */ + time_t timeofdoc; + long bodywrites; + char *buf; + int keepon; + char *location; /* This points to an allocated version of the Location: + header data */ + char *newurl; /* Set to the new URL to use when a redirect or a retry is + wanted */ + + /* 'upload_present' is used to keep a byte counter of how much data there is + still left in the buffer, aimed for upload. */ + ssize_t upload_present; + + /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a + buffer, so the next read should read from where this pointer points to, + and the 'upload_present' contains the number of bytes available at this + position */ + char *upload_fromhere; + void *protop; /* Allocated protocol-specific data. Each protocol + handler makes sure this points to data it needs. */ +#ifndef CURL_DISABLE_DOH + struct dohdata doh; /* DoH specific data for this request */ +#endif + bit header:1; /* incoming data has HTTP header */ + bit content_range:1; /* set TRUE if Content-Range: was found */ + bit upload_done:1; /* set to TRUE when doing chunked transfer-encoding + upload and we're uploading the last chunk */ + bit ignorebody:1; /* we read a response-body but we ignore it! */ + bit http_bodyless:1; /* HTTP response status code is between 100 and 199, + 204 or 304 */ + bit chunk:1; /* if set, this is a chunked transfer-encoding */ + bit upload_chunky:1; /* set TRUE if we are doing chunked transfer-encoding + on upload */ + bit getheader:1; /* TRUE if header parsing is wanted */ + bit forbidchunk:1; /* used only to explicitly forbid chunk-upload for + specific upload buffers. See readmoredata() in http.c + for details. */ +}; + +/* + * Specific protocol handler. + */ + +struct Curl_handler { + const char *scheme; /* URL scheme name. */ + + /* Complement to setup_connection_internals(). */ + CURLcode (*setup_connection)(struct connectdata *); + + /* These two functions MUST be set to be protocol dependent */ + CURLcode (*do_it)(struct connectdata *, bool *done); + Curl_done_func done; + + /* If the curl_do() function is better made in two halves, this + * curl_do_more() function will be called afterwards, if set. For example + * for doing the FTP stuff after the PASV/PORT command. + */ + Curl_do_more_func do_more; + + /* This function *MAY* be set to a protocol-dependent function that is run + * after the connect() and everything is done, as a step in the connection. + * The 'done' pointer points to a bool that should be set to TRUE if the + * function completes before return. If it doesn't complete, the caller + * should call the curl_connecting() function until it is. + */ + CURLcode (*connect_it)(struct connectdata *, bool *done); + + /* See above. */ + CURLcode (*connecting)(struct connectdata *, bool *done); + CURLcode (*doing)(struct connectdata *, bool *done); + + /* Called from the multi interface during the PROTOCONNECT phase, and it + should then return a proper fd set */ + int (*proto_getsock)(struct connectdata *conn, + curl_socket_t *socks, + int numsocks); + + /* Called from the multi interface during the DOING phase, and it should + then return a proper fd set */ + int (*doing_getsock)(struct connectdata *conn, + curl_socket_t *socks, + int numsocks); + + /* Called from the multi interface during the DO_MORE phase, and it should + then return a proper fd set */ + int (*domore_getsock)(struct connectdata *conn, + curl_socket_t *socks, + int numsocks); + + /* Called from the multi interface during the DO_DONE, PERFORM and + WAITPERFORM phases, and it should then return a proper fd set. Not setting + this will make libcurl use the generic default one. */ + int (*perform_getsock)(const struct connectdata *conn, + curl_socket_t *socks, + int numsocks); + + /* This function *MAY* be set to a protocol-dependent function that is run + * by the curl_disconnect(), as a step in the disconnection. If the handler + * is called because the connection has been considered dead, dead_connection + * is set to TRUE. + */ + CURLcode (*disconnect)(struct connectdata *, bool dead_connection); + + /* If used, this function gets called from transfer.c:readwrite_data() to + allow the protocol to do extra reads/writes */ + CURLcode (*readwrite)(struct Curl_easy *data, struct connectdata *conn, + ssize_t *nread, bool *readmore); + + /* This function can perform various checks on the connection. See + CONNCHECK_* for more information about the checks that can be performed, + and CONNRESULT_* for the results that can be returned. */ + unsigned int (*connection_check)(struct connectdata *conn, + unsigned int checks_to_perform); + + long defport; /* Default port. */ + unsigned int protocol; /* See CURLPROTO_* - this needs to be the single + specific protocol bit */ + unsigned int flags; /* Extra particular characteristics, see PROTOPT_* */ +}; + +#define PROTOPT_NONE 0 /* nothing extra */ +#define PROTOPT_SSL (1<<0) /* uses SSL */ +#define PROTOPT_DUAL (1<<1) /* this protocol uses two connections */ +#define PROTOPT_CLOSEACTION (1<<2) /* need action before socket close */ +/* some protocols will have to call the underlying functions without regard to + what exact state the socket signals. IE even if the socket says "readable", + the send function might need to be called while uploading, or vice versa. +*/ +#define PROTOPT_DIRLOCK (1<<3) +#define PROTOPT_NONETWORK (1<<4) /* protocol doesn't use the network! */ +#define PROTOPT_NEEDSPWD (1<<5) /* needs a password, and if none is set it + gets a default */ +#define PROTOPT_NOURLQUERY (1<<6) /* protocol can't handle + url query strings (?foo=bar) ! */ +#define PROTOPT_CREDSPERREQUEST (1<<7) /* requires login credentials per + request instead of per connection */ +#define PROTOPT_ALPN_NPN (1<<8) /* set ALPN and/or NPN for this */ +#define PROTOPT_STREAM (1<<9) /* a protocol with individual logical streams */ +#define PROTOPT_URLOPTIONS (1<<10) /* allow options part in the userinfo field + of the URL */ +#define PROTOPT_PROXY_AS_HTTP (1<<11) /* allow this non-HTTP scheme over a + HTTP proxy as HTTP proxies may know + this protocol and act as a gateway */ +#define PROTOPT_WILDCARD (1<<12) /* protocol supports wildcard matching */ + +#define CONNCHECK_NONE 0 /* No checks */ +#define CONNCHECK_ISDEAD (1<<0) /* Check if the connection is dead. */ +#define CONNCHECK_KEEPALIVE (1<<1) /* Perform any keepalive function. */ + +#define CONNRESULT_NONE 0 /* No extra information. */ +#define CONNRESULT_DEAD (1<<0) /* The connection is dead. */ + +#ifdef USE_RECV_BEFORE_SEND_WORKAROUND +struct postponed_data { + char *buffer; /* Temporal store for received data during + sending, must be freed */ + size_t allocated_size; /* Size of temporal store */ + size_t recv_size; /* Size of received data during sending */ + size_t recv_processed; /* Size of processed part of postponed data */ +#ifdef DEBUGBUILD + curl_socket_t bindsock;/* Structure must be bound to specific socket, + used only for DEBUGASSERT */ +#endif /* DEBUGBUILD */ +}; +#endif /* USE_RECV_BEFORE_SEND_WORKAROUND */ + +struct proxy_info { + struct hostname host; + long port; + curl_proxytype proxytype; /* what kind of proxy that is in use */ + char *user; /* proxy user name string, allocated */ + char *passwd; /* proxy password string, allocated */ +}; + +#define CONNECT_BUFFER_SIZE 16384 + +/* struct for HTTP CONNECT state data */ +struct http_connect_state { + char connect_buffer[CONNECT_BUFFER_SIZE]; + int perline; /* count bytes per line */ + int keepon; + char *line_start; + char *ptr; /* where to store more data */ + curl_off_t cl; /* size of content to read and ignore */ + enum { + TUNNEL_INIT, /* init/default/no tunnel state */ + TUNNEL_CONNECT, /* CONNECT has been sent off */ + TUNNEL_COMPLETE /* CONNECT response received completely */ + } tunnel_state; + bit chunked_encoding:1; + bit close_connection:1; +}; + +/* + * The connectdata struct contains all fields and variables that should be + * unique for an entire connection. + */ +struct connectdata { + /* 'data' is the CURRENT Curl_easy using this connection -- take great + caution that this might very well vary between different times this + connection is used! */ + struct Curl_easy *data; + + struct curl_llist_element bundle_node; /* conncache */ + + /* chunk is for HTTP chunked encoding, but is in the general connectdata + struct only because we can do just about any protocol through a HTTP proxy + and a HTTP proxy may in fact respond using chunked encoding */ + struct Curl_chunker chunk; + + curl_closesocket_callback fclosesocket; /* function closing the socket(s) */ + void *closesocket_client; + + /* This is used by the connection cache logic. If this returns TRUE, this + handle is still used by one or more easy handles and can only used by any + other easy handle without careful consideration (== only for + multiplexing) and it cannot be used by another multi handle! */ +#define CONN_INUSE(c) ((c)->easyq.size) + + /**** Fields set when inited and not modified again */ + long connection_id; /* Contains a unique number to make it easier to + track the connections in the log output */ + + /* 'dns_entry' is the particular host we use. This points to an entry in the + DNS cache and it will not get pruned while locked. It gets unlocked in + Curl_done(). This entry will be NULL if the connection is re-used as then + there is no name resolve done. */ + struct Curl_dns_entry *dns_entry; + + /* 'ip_addr' is the particular IP we connected to. It points to a struct + within the DNS cache, so this pointer is only valid as long as the DNS + cache entry remains locked. It gets unlocked in Curl_done() */ + Curl_addrinfo *ip_addr; + Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */ + + /* 'ip_addr_str' is the ip_addr data as a human readable string. + It remains available as long as the connection does, which is longer than + the ip_addr itself. */ + char ip_addr_str[MAX_IPADR_LEN]; + + unsigned int scope_id; /* Scope id for IPv6 */ + + int socktype; /* SOCK_STREAM or SOCK_DGRAM */ + + struct hostname host; + char *hostname_resolve; /* host name to resolve to address, allocated */ + char *secondaryhostname; /* secondary socket host name (ftp) */ + struct hostname conn_to_host; /* the host to connect to. valid only if + bits.conn_to_host is set */ + + struct proxy_info socks_proxy; + struct proxy_info http_proxy; + + long port; /* which port to use locally */ + int remote_port; /* the remote port, not the proxy port! */ + int conn_to_port; /* the remote port to connect to. valid only if + bits.conn_to_port is set */ + unsigned short secondary_port; /* secondary socket remote port to connect to + (ftp) */ + + /* 'primary_ip' and 'primary_port' get filled with peer's numerical + ip address and port number whenever an outgoing connection is + *attempted* from the primary socket to a remote address. When more + than one address is tried for a connection these will hold data + for the last attempt. When the connection is actually established + these are updated with data which comes directly from the socket. */ + + char primary_ip[MAX_IPADR_LEN]; + long primary_port; + + /* 'local_ip' and 'local_port' get filled with local's numerical + ip address and port number whenever an outgoing connection is + **established** from the primary socket to a remote address. */ + + char local_ip[MAX_IPADR_LEN]; + long local_port; + + char *user; /* user name string, allocated */ + char *passwd; /* password string, allocated */ + char *options; /* options string, allocated */ + + char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */ + + int httpversion; /* the HTTP version*10 reported by the server */ + int rtspversion; /* the RTSP version*10 reported by the server */ + + struct curltime now; /* "current" time */ + struct curltime created; /* creation time */ + struct curltime lastused; /* when returned to the connection cache */ + curl_socket_t sock[2]; /* two sockets, the second is used for the data + transfer when doing FTP */ + curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */ + bool sock_accepted[2]; /* TRUE if the socket on this index was created with + accept() */ + Curl_recv *recv[2]; + Curl_send *send[2]; + +#ifdef USE_RECV_BEFORE_SEND_WORKAROUND + struct postponed_data postponed[2]; /* two buffers for two sockets */ +#endif /* USE_RECV_BEFORE_SEND_WORKAROUND */ + struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */ + struct ssl_connect_data proxy_ssl[2]; /* this is for proxy ssl-stuff */ +#ifdef USE_SSL + void *ssl_extra; /* separately allocated backend-specific data */ +#endif + struct ssl_primary_config ssl_config; + struct ssl_primary_config proxy_ssl_config; + struct ConnectBits bits; /* various state-flags for this connection */ + + /* connecttime: when connect() is called on the current IP address. Used to + be able to track when to move on to try next IP - but only when the multi + interface is used. */ + struct curltime connecttime; + /* The two fields below get set in Curl_connecthost */ + int num_addr; /* number of addresses to try to connect to */ + time_t timeoutms_per_addr; /* how long time in milliseconds to spend on + trying to connect to each IP address */ + + const struct Curl_handler *handler; /* Connection's protocol handler */ + const struct Curl_handler *given; /* The protocol first given */ + + long ip_version; /* copied from the Curl_easy at creation time */ + + /* Protocols can use a custom keepalive mechanism to keep connections alive. + This allows those protocols to track the last time the keepalive mechanism + was used on this connection. */ + struct curltime keepalive; + + long upkeep_interval_ms; /* Time between calls for connection upkeep. */ + + /**** curl_get() phase fields */ + + curl_socket_t sockfd; /* socket to read from or CURL_SOCKET_BAD */ + curl_socket_t writesockfd; /* socket to write to, it may very + well be the same we read from. + CURL_SOCKET_BAD disables */ + + /** Dynamically allocated strings, MUST be freed before this **/ + /** struct is killed. **/ + struct dynamically_allocated_data { + char *proxyuserpwd; + char *uagent; + char *accept_encoding; + char *userpwd; + char *rangeline; + char *ref; + char *host; + char *cookiehost; + char *rtsp_transport; + char *te; /* TE: request header */ + } allocptr; + +#ifdef HAVE_GSSAPI + bit sec_complete:1; /* if Kerberos is enabled for this connection */ + enum protection_level command_prot; + enum protection_level data_prot; + enum protection_level request_data_prot; + size_t buffer_size; + struct krb5buffer in_buffer; + void *app_data; + const struct Curl_sec_client_mech *mech; + struct sockaddr_in local_addr; +#endif + +#if defined(USE_KERBEROS5) /* Consider moving some of the above GSS-API */ + struct kerberos5data krb5; /* variables into the structure definition, */ +#endif /* however, some of them are ftp specific. */ + + struct curl_llist easyq; /* List of easy handles using this connection */ + curl_seek_callback seek_func; /* function that seeks the input */ + void *seek_client; /* pointer to pass to the seek() above */ + + /*************** Request - specific items ************/ +#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS) + CtxtHandle *sslContext; +#endif + +#if defined(USE_NTLM) + curlntlm http_ntlm_state; + curlntlm proxy_ntlm_state; + + struct ntlmdata ntlm; /* NTLM differs from other authentication schemes + because it authenticates connections, not + single requests! */ + struct ntlmdata proxyntlm; /* NTLM data for proxy */ + +#if defined(NTLM_WB_ENABLED) + /* used for communication with Samba's winbind daemon helper ntlm_auth */ + curl_socket_t ntlm_auth_hlpr_socket; + pid_t ntlm_auth_hlpr_pid; + char *challenge_header; + char *response_header; +#endif +#endif + +#ifdef USE_SPNEGO + curlnegotiate http_negotiate_state; + curlnegotiate proxy_negotiate_state; + + struct negotiatedata negotiate; /* state data for host Negotiate auth */ + struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */ +#endif + + /* data used for the asynch name resolve callback */ + struct Curl_async async; + + /* These three are used for chunked-encoding trailer support */ + char *trailer; /* allocated buffer to store trailer in */ + int trlMax; /* allocated buffer size */ + int trlPos; /* index of where to store data */ + + union { + struct ftp_conn ftpc; + struct http_conn httpc; + struct ssh_conn sshc; + struct tftp_state_data *tftpc; + struct imap_conn imapc; + struct pop3_conn pop3c; + struct smtp_conn smtpc; + struct rtsp_conn rtspc; + struct smb_conn smbc; + void *generic; /* RTMP and LDAP use this */ + } proto; + + int cselect_bits; /* bitmask of socket events */ + int waitfor; /* current READ/WRITE bits to wait for */ + +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + int socks5_gssapi_enctype; +#endif + + /* When this connection is created, store the conditions for the local end + bind. This is stored before the actual bind and before any connection is + made and will serve the purpose of being used for comparison reasons so + that subsequent bound-requested connections aren't accidentally re-using + wrong connections. */ + char *localdev; + unsigned short localport; + int localportrange; + struct http_connect_state *connect_state; /* for HTTP CONNECT */ + struct connectbundle *bundle; /* The bundle we are member of */ + int negnpn; /* APLN or NPN TLS negotiated protocol, CURL_HTTP_VERSION* */ + +#ifdef USE_UNIX_SOCKETS + char *unix_domain_socket; + bit abstract_unix_socket:1; +#endif + bit tls_upgraded:1; + /* the two following *_inuse fields are only flags, not counters in any way. + If TRUE it means the channel is in use, and if FALSE it means the channel + is up for grabs by one. */ + bit readchannel_inuse:1; /* whether the read channel is in use by an easy + handle */ + bit writechannel_inuse:1; /* whether the write channel is in use by an easy + handle */ +}; + +/* The end of connectdata. */ + +/* + * Struct to keep statistical and informational data. + * All variables in this struct must be initialized/reset in Curl_initinfo(). + */ +struct PureInfo { + int httpcode; /* Recent HTTP, FTP, RTSP or SMTP response code */ + int httpproxycode; /* response code from proxy when received separate */ + int httpversion; /* the http version number X.Y = X*10+Y */ + time_t filetime; /* If requested, this is might get set. Set to -1 if the + time was unretrievable. */ + curl_off_t header_size; /* size of read header(s) in bytes */ + curl_off_t request_size; /* the amount of bytes sent in the request(s) */ + unsigned long proxyauthavail; /* what proxy auth types were announced */ + unsigned long httpauthavail; /* what host auth types were announced */ + long numconnects; /* how many new connection did libcurl created */ + char *contenttype; /* the content type of the object */ + char *wouldredirect; /* URL this would've been redirected to if asked to */ + + /* PureInfo members 'conn_primary_ip', 'conn_primary_port', 'conn_local_ip' + and, 'conn_local_port' are copied over from the connectdata struct in + order to allow curl_easy_getinfo() to return this information even when + the session handle is no longer associated with a connection, and also + allow curl_easy_reset() to clear this information from the session handle + without disturbing information which is still alive, and that might be + reused, in the connection cache. */ + + char conn_primary_ip[MAX_IPADR_LEN]; + long conn_primary_port; + char conn_local_ip[MAX_IPADR_LEN]; + long conn_local_port; + const char *conn_scheme; + unsigned int conn_protocol; + struct curl_certinfo certs; /* info about the certs, only populated in + OpenSSL, GnuTLS, Schannel, NSS and GSKit + builds. Asked for with CURLOPT_CERTINFO + / CURLINFO_CERTINFO */ + + bit timecond:1; /* set to TRUE if the time condition didn't match, which + thus made the document NOT get fetched */ +}; + + +struct Progress { + time_t lastshow; /* time() of the last displayed progress meter or NULL to + force redraw at next call */ + curl_off_t size_dl; /* total expected size */ + curl_off_t size_ul; /* total expected size */ + curl_off_t downloaded; /* transferred so far */ + curl_off_t uploaded; /* transferred so far */ + + curl_off_t current_speed; /* uses the currently fastest transfer */ + + int width; /* screen width at download start */ + int flags; /* see progress.h */ + + time_t timespent; + + curl_off_t dlspeed; + curl_off_t ulspeed; + + time_t t_nslookup; + time_t t_connect; + time_t t_appconnect; + time_t t_pretransfer; + time_t t_starttransfer; + time_t t_redirect; + + struct curltime start; + struct curltime t_startsingle; + struct curltime t_startop; + struct curltime t_acceptdata; + + + /* upload speed limit */ + struct curltime ul_limit_start; + curl_off_t ul_limit_size; + /* download speed limit */ + struct curltime dl_limit_start; + curl_off_t dl_limit_size; + +#define CURR_TIME (5 + 1) /* 6 entries for 5 seconds */ + + curl_off_t speeder[ CURR_TIME ]; + struct curltime speeder_time[ CURR_TIME ]; + int speeder_c; + bit callback:1; /* set when progress callback is used */ + bit is_t_startransfer_set:1; +}; + +typedef enum { + HTTPREQ_NONE, /* first in list */ + HTTPREQ_GET, + HTTPREQ_POST, + HTTPREQ_POST_FORM, /* we make a difference internally */ + HTTPREQ_POST_MIME, /* we make a difference internally */ + HTTPREQ_PUT, + HTTPREQ_HEAD, + HTTPREQ_OPTIONS, + HTTPREQ_LAST /* last in list */ +} Curl_HttpReq; + +typedef enum { + RTSPREQ_NONE, /* first in list */ + RTSPREQ_OPTIONS, + RTSPREQ_DESCRIBE, + RTSPREQ_ANNOUNCE, + RTSPREQ_SETUP, + RTSPREQ_PLAY, + RTSPREQ_PAUSE, + RTSPREQ_TEARDOWN, + RTSPREQ_GET_PARAMETER, + RTSPREQ_SET_PARAMETER, + RTSPREQ_RECORD, + RTSPREQ_RECEIVE, + RTSPREQ_LAST /* last in list */ +} Curl_RtspReq; + +/* + * Values that are generated, temporary or calculated internally for a + * "session handle" must be defined within the 'struct UrlState'. This struct + * will be used within the Curl_easy struct. When the 'Curl_easy' + * struct is cloned, this data MUST NOT be copied. + * + * Remember that any "state" information goes globally for the curl handle. + * Session-data MUST be put in the connectdata struct and here. */ +#define MAX_CURL_USER_LENGTH 256 +#define MAX_CURL_PASSWORD_LENGTH 256 + +struct auth { + unsigned long want; /* Bitmask set to the authentication methods wanted by + app (with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH). */ + unsigned long picked; + unsigned long avail; /* Bitmask for what the server reports to support for + this resource */ + bit done:1; /* TRUE when the auth phase is done and ready to do the + *actual* request */ + bit multipass:1; /* TRUE if this is not yet authenticated but within the + auth multipass negotiation */ + bit iestyle:1; /* TRUE if digest should be done IE-style or FALSE if it + should be RFC compliant */ +}; + +struct Curl_http2_dep { + struct Curl_http2_dep *next; + struct Curl_easy *data; +}; + +/* + * This struct is for holding data that was attempted to get sent to the user's + * callback but is held due to pausing. One instance per type (BOTH, HEADER, + * BODY). + */ +struct tempbuf { + char *buf; /* allocated buffer to keep data in when a write callback + returns to make the connection paused */ + size_t len; /* size of the 'tempwrite' allocated buffer */ + int type; /* type of the 'tempwrite' buffer as a bitmask that is used with + Curl_client_write() */ +}; + +/* Timers */ +typedef enum { + EXPIRE_100_TIMEOUT, + EXPIRE_ASYNC_NAME, + EXPIRE_CONNECTTIMEOUT, + EXPIRE_DNS_PER_NAME, + EXPIRE_HAPPY_EYEBALLS_DNS, /* See asyn-ares.c */ + EXPIRE_HAPPY_EYEBALLS, + EXPIRE_MULTI_PENDING, + EXPIRE_RUN_NOW, + EXPIRE_SPEEDCHECK, + EXPIRE_TIMEOUT, + EXPIRE_TOOFAST, + EXPIRE_LAST /* not an actual timer, used as a marker only */ +} expire_id; + + +typedef enum { + TRAILERS_NONE, + TRAILERS_INITIALIZED, + TRAILERS_SENDING, + TRAILERS_DONE +} trailers_state; + + +/* + * One instance for each timeout an easy handle can set. + */ +struct time_node { + struct curl_llist_element list; + struct curltime time; + expire_id eid; +}; + +/* individual pieces of the URL */ +struct urlpieces { + char *scheme; + char *hostname; + char *port; + char *user; + char *password; + char *options; + char *path; + char *query; +}; + +struct UrlState { + + /* Points to the connection cache */ + struct conncache *conn_cache; + + /* buffers to store authentication data in, as parsed from input options */ + struct curltime keeps_speed; /* for the progress meter really */ + + struct connectdata *lastconnect; /* The last connection, NULL if undefined */ + + char *headerbuff; /* allocated buffer to store headers in */ + size_t headersize; /* size of the allocation */ + + char *buffer; /* download buffer */ + char *ulbuf; /* allocated upload buffer or NULL */ + curl_off_t current_speed; /* the ProgressShow() function sets this, + bytes / second */ + char *first_host; /* host name of the first (not followed) request. + if set, this should be the host name that we will + sent authorization to, no else. Used to make Location: + following not keep sending user+password... This is + strdup() data. + */ + int first_remote_port; /* remote port of the first (not followed) request */ + struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */ + long sessionage; /* number of the most recent session */ + unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */ + struct tempbuf tempwrite[3]; /* BOTH, HEADER, BODY */ + char *scratch; /* huge buffer[set.buffer_size*2] for upload CRLF replacing */ + int os_errno; /* filled in with errno whenever an error occurs */ +#ifdef HAVE_SIGNAL + /* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */ + void (*prev_signal)(int sig); +#endif + struct digestdata digest; /* state data for host Digest auth */ + struct digestdata proxydigest; /* state data for proxy Digest auth */ + + struct auth authhost; /* auth details for host */ + struct auth authproxy; /* auth details for proxy */ + void *resolver; /* resolver state, if it is used in the URL state - + ares_channel f.e. */ + +#if defined(USE_OPENSSL) + /* void instead of ENGINE to avoid bleeding OpenSSL into this header */ + void *engine; +#endif /* USE_OPENSSL */ + struct curltime expiretime; /* set this with Curl_expire() only */ + struct Curl_tree timenode; /* for the splay stuff */ + struct curl_llist timeoutlist; /* list of pending timeouts */ + struct time_node expires[EXPIRE_LAST]; /* nodes for each expire type */ + + /* a place to store the most recently set FTP entrypath */ + char *most_recent_ftp_entrypath; + + int httpversion; /* the lowest HTTP version*10 reported by any server + involved in this request */ + +#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \ + !defined(__SYMBIAN32__) +/* do FTP line-end conversions on most platforms */ +#define CURL_DO_LINEEND_CONV + /* for FTP downloads: track CRLF sequences that span blocks */ + bit prev_block_had_trailing_cr:1; + /* for FTP downloads: how many CRLFs did we converted to LFs? */ + curl_off_t crlf_conversions; +#endif + char *range; /* range, if used. See README for detailed specification on + this syntax. */ + curl_off_t resume_from; /* continue [ftp] transfer from here */ + + /* This RTSP state information survives requests and connections */ + long rtsp_next_client_CSeq; /* the session's next client CSeq */ + long rtsp_next_server_CSeq; /* the session's next server CSeq */ + long rtsp_CSeq_recv; /* most recent CSeq received */ + + curl_off_t infilesize; /* size of file to upload, -1 means unknown. + Copied from set.filesize at start of operation */ + + size_t drain; /* Increased when this stream has data to read, even if its + socket is not necessarily is readable. Decreased when + checked. */ + + curl_read_callback fread_func; /* read callback/function */ + void *in; /* CURLOPT_READDATA */ + + struct Curl_easy *stream_depends_on; + int stream_weight; + CURLU *uh; /* URL handle for the current parsed URL */ + struct urlpieces up; +#ifndef CURL_DISABLE_HTTP + size_t trailers_bytes_sent; + Curl_send_buffer *trailers_buf; /* a buffer containing the compiled trailing + headers */ +#endif + trailers_state trailers_state; /* whether we are sending trailers + and what stage are we at */ +#ifdef CURLDEBUG + bit conncache_lock:1; +#endif + /* when curl_easy_perform() is called, the multi handle is "owned" by + the easy handle so curl_easy_cleanup() on such an easy handle will + also close the multi handle! */ + bit multi_owned_by_easy:1; + + bit this_is_a_follow:1; /* this is a followed Location: request */ + bit refused_stream:1; /* this was refused, try again */ + bit errorbuf:1; /* Set to TRUE if the error buffer is already filled in. + This must be set to FALSE every time _easy_perform() is + called. */ + bit allow_port:1; /* Is set.use_port allowed to take effect or not. This + is always set TRUE when curl_easy_perform() is called. */ + bit authproblem:1; /* TRUE if there's some problem authenticating */ + /* set after initial USER failure, to prevent an authentication loop */ + bit ftp_trying_alternative:1; + bit wildcardmatch:1; /* enable wildcard matching */ + bit expect100header:1; /* TRUE if we added Expect: 100-continue */ + bit use_range:1; + bit rangestringalloc:1; /* the range string is malloc()'ed */ + bit done:1; /* set to FALSE when Curl_init_do() is called and set to TRUE + when multi_done() is called, to prevent multi_done() to get + invoked twice when the multi interface is used. */ + bit stream_depends_e:1; /* set or don't set the Exclusive bit */ + bit previouslypending:1; /* this transfer WAS in the multi->pending queue */ +}; + + +/* + * This 'DynamicStatic' struct defines dynamic states that actually change + * values in the 'UserDefined' area, which MUST be taken into consideration + * if the UserDefined struct is cloned or similar. You can probably just + * copy these, but each one indicate a special action on other data. + */ + +struct DynamicStatic { + char *url; /* work URL, copied from UserDefined */ + char *referer; /* referer string */ + struct curl_slist *cookielist; /* list of cookie files set by + curl_easy_setopt(COOKIEFILE) calls */ + struct curl_slist *resolve; /* set to point to the set.resolve list when + this should be dealt with in pretransfer */ + bit url_alloc:1; /* URL string is malloc()'ed */ + bit referer_alloc:1; /* referer string is malloc()ed */ + bit wildcard_resolve:1; /* Set to true if any resolve change is a + wildcard */ +}; + +/* + * This 'UserDefined' struct must only contain data that is set once to go + * for many (perhaps) independent connections. Values that are generated or + * calculated internally for the "session handle" MUST be defined within the + * 'struct UrlState' instead. The only exceptions MUST note the changes in + * the 'DynamicStatic' struct. + * Character pointer fields point to dynamic storage, unless otherwise stated. + */ + +struct Curl_multi; /* declared and used only in multi.c */ + +enum dupstring { + STRING_CERT_ORIG, /* client certificate file name */ + STRING_CERT_PROXY, /* client certificate file name */ + STRING_CERT_TYPE_ORIG, /* format for certificate (default: PEM)*/ + STRING_CERT_TYPE_PROXY, /* format for certificate (default: PEM)*/ + STRING_COOKIE, /* HTTP cookie string to send */ + STRING_COOKIEJAR, /* dump all cookies to this file */ + STRING_CUSTOMREQUEST, /* HTTP/FTP/RTSP request/method to use */ + STRING_DEFAULT_PROTOCOL, /* Protocol to use when the URL doesn't specify */ + STRING_DEVICE, /* local network interface/address to use */ + STRING_ENCODING, /* Accept-Encoding string */ + STRING_FTP_ACCOUNT, /* ftp account data */ + STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */ + STRING_FTPPORT, /* port to send with the FTP PORT command */ + STRING_KEY_ORIG, /* private key file name */ + STRING_KEY_PROXY, /* private key file name */ + STRING_KEY_PASSWD_ORIG, /* plain text private key password */ + STRING_KEY_PASSWD_PROXY, /* plain text private key password */ + STRING_KEY_TYPE_ORIG, /* format for private key (default: PEM) */ + STRING_KEY_TYPE_PROXY, /* format for private key (default: PEM) */ + STRING_KRB_LEVEL, /* krb security level */ + STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find + $HOME/.netrc */ + STRING_PROXY, /* proxy to use */ + STRING_PRE_PROXY, /* pre socks proxy to use */ + STRING_SET_RANGE, /* range, if used */ + STRING_SET_REFERER, /* custom string for the HTTP referer field */ + STRING_SET_URL, /* what original URL to work on */ + STRING_SSL_CAPATH_ORIG, /* CA directory name (doesn't work on windows) */ + STRING_SSL_CAPATH_PROXY, /* CA directory name (doesn't work on windows) */ + STRING_SSL_CAFILE_ORIG, /* certificate file to verify peer against */ + STRING_SSL_CAFILE_PROXY, /* certificate file to verify peer against */ + STRING_SSL_PINNEDPUBLICKEY_ORIG, /* public key file to verify peer against */ + STRING_SSL_PINNEDPUBLICKEY_PROXY, /* public key file to verify proxy */ + STRING_SSL_CIPHER_LIST_ORIG, /* list of ciphers to use */ + STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */ + STRING_SSL_CIPHER13_LIST_ORIG, /* list of TLS 1.3 ciphers to use */ + STRING_SSL_CIPHER13_LIST_PROXY, /* list of TLS 1.3 ciphers to use */ + STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */ + STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */ + STRING_USERAGENT, /* User-Agent string */ + STRING_SSL_CRLFILE_ORIG, /* crl file to check certificate */ + STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */ + STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */ + STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */ + STRING_SSL_ENGINE, /* name of ssl engine */ + STRING_USERNAME, /* , if used */ + STRING_PASSWORD, /* , if used */ + STRING_OPTIONS, /* , if used */ + STRING_PROXYUSERNAME, /* Proxy , if used */ + STRING_PROXYPASSWORD, /* Proxy , if used */ + STRING_NOPROXY, /* List of hosts which should not use the proxy, if + used */ + STRING_RTSP_SESSION_ID, /* Session ID to use */ + STRING_RTSP_STREAM_URI, /* Stream URI for this request */ + STRING_RTSP_TRANSPORT, /* Transport for this session */ +#ifdef USE_SSH + STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */ + STRING_SSH_PUBLIC_KEY, /* path to the public key file for auth */ + STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */ + STRING_SSH_KNOWNHOSTS, /* file name of knownhosts file */ +#endif + STRING_PROXY_SERVICE_NAME, /* Proxy service name */ + STRING_SERVICE_NAME, /* Service name */ + STRING_MAIL_FROM, + STRING_MAIL_AUTH, + +#ifdef USE_TLS_SRP + STRING_TLSAUTH_USERNAME_ORIG, /* TLS auth */ + STRING_TLSAUTH_USERNAME_PROXY, /* TLS auth */ + STRING_TLSAUTH_PASSWORD_ORIG, /* TLS auth */ + STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth */ +#endif + STRING_BEARER, /* , if used */ +#ifdef USE_UNIX_SOCKETS + STRING_UNIX_SOCKET_PATH, /* path to Unix socket, if used */ +#endif + STRING_TARGET, /* CURLOPT_REQUEST_TARGET */ + STRING_DOH, /* CURLOPT_DOH_URL */ +#ifdef USE_ALTSVC + STRING_ALTSVC, /* CURLOPT_ALTSVC */ +#endif + /* -- end of zero-terminated strings -- */ + + STRING_LASTZEROTERMINATED, + + /* -- below this are pointers to binary data that cannot be strdup'ed. --- */ + + STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */ + + STRING_LAST /* not used, just an end-of-list marker */ +}; + +/* callback that gets called when this easy handle is completed within a multi + handle. Only used for internally created transfers, like for example + DoH. */ +typedef int (*multidone_func)(struct Curl_easy *easy, CURLcode result); + +struct UserDefined { + FILE *err; /* the stderr user data goes here */ + void *debugdata; /* the data that will be passed to fdebug */ + char *errorbuffer; /* (Static) store failure messages in here */ + long proxyport; /* If non-zero, use this port number by default. If the + proxy string features a ":[port]" that one will override + this. */ + void *out; /* CURLOPT_WRITEDATA */ + void *in_set; /* CURLOPT_READDATA */ + void *writeheader; /* write the header to this if non-NULL */ + void *rtp_out; /* write RTP to this if non-NULL */ + long use_port; /* which port to use (when not using default) */ + unsigned long httpauth; /* kind of HTTP authentication to use (bitmask) */ + unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */ + unsigned long socks5auth;/* kind of SOCKS5 authentication to use (bitmask) */ + long followlocation; /* as in HTTP Location: */ + long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1 + for infinity */ + + int keep_post; /* keep POSTs as POSTs after a 30x request; each + bit represents a request, from 301 to 303 */ + void *postfields; /* if POST, set the fields' values here */ + curl_seek_callback seek_func; /* function that seeks the input */ + curl_off_t postfieldsize; /* if POST, this might have a size to use instead + of strlen(), and then the data *may* be binary + (contain zero bytes) */ + unsigned short localport; /* local port number to bind to */ + int localportrange; /* number of additional port numbers to test in case the + 'localport' one can't be bind()ed */ + curl_write_callback fwrite_func; /* function that stores the output */ + curl_write_callback fwrite_header; /* function that stores headers */ + curl_write_callback fwrite_rtp; /* function that stores interleaved RTP */ + curl_read_callback fread_func_set; /* function that reads the input */ + curl_progress_callback fprogress; /* OLD and deprecated progress callback */ + curl_xferinfo_callback fxferinfo; /* progress callback */ + curl_debug_callback fdebug; /* function that write informational data */ + curl_ioctl_callback ioctl_func; /* function for I/O control */ + curl_sockopt_callback fsockopt; /* function for setting socket options */ + void *sockopt_client; /* pointer to pass to the socket options callback */ + curl_opensocket_callback fopensocket; /* function for checking/translating + the address and opening the + socket */ + void *opensocket_client; + curl_closesocket_callback fclosesocket; /* function for closing the + socket */ + void *closesocket_client; + + void *seek_client; /* pointer to pass to the seek callback */ + /* the 3 curl_conv_callback functions below are used on non-ASCII hosts */ + /* function to convert from the network encoding: */ + curl_conv_callback convfromnetwork; + /* function to convert to the network encoding: */ + curl_conv_callback convtonetwork; + /* function to convert from UTF-8 encoding: */ + curl_conv_callback convfromutf8; + + void *progress_client; /* pointer to pass to the progress callback */ + void *ioctl_client; /* pointer to pass to the ioctl callback */ + long timeout; /* in milliseconds, 0 means no timeout */ + long connecttimeout; /* in milliseconds, 0 means no timeout */ + long accepttimeout; /* in milliseconds, 0 means no timeout */ + long happy_eyeballs_timeout; /* in milliseconds, 0 is a valid value */ + long server_response_timeout; /* in milliseconds, 0 means no timeout */ + long maxage_conn; /* in seconds, max idle time to allow a connection that + is to be reused */ + long tftp_blksize; /* in bytes, 0 means use default */ + curl_off_t filesize; /* size of file to upload, -1 means unknown */ + long low_speed_limit; /* bytes/second */ + long low_speed_time; /* number of seconds */ + curl_off_t max_send_speed; /* high speed limit in bytes/second for upload */ + curl_off_t max_recv_speed; /* high speed limit in bytes/second for + download */ + curl_off_t set_resume_from; /* continue [ftp] transfer from here */ + struct curl_slist *headers; /* linked list of extra headers */ + struct curl_slist *proxyheaders; /* linked list of extra CONNECT headers */ + struct curl_httppost *httppost; /* linked list of old POST data */ + curl_mimepart mimepost; /* MIME/POST data. */ + struct curl_slist *quote; /* after connection is established */ + struct curl_slist *postquote; /* after the transfer */ + struct curl_slist *prequote; /* before the transfer, after type */ + struct curl_slist *source_quote; /* 3rd party quote */ + struct curl_slist *source_prequote; /* in 3rd party transfer mode - before + the transfer on source host */ + struct curl_slist *source_postquote; /* in 3rd party transfer mode - after + the transfer on source host */ + struct curl_slist *telnet_options; /* linked list of telnet options */ + struct curl_slist *resolve; /* list of names to add/remove from + DNS cache */ + struct curl_slist *connect_to; /* list of host:port mappings to override + the hostname and port to connect to */ + curl_TimeCond timecondition; /* kind of time/date comparison */ + time_t timevalue; /* what time to compare with */ + Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */ + long httpversion; /* when non-zero, a specific HTTP version requested to + be used in the library's request(s) */ + struct ssl_config_data ssl; /* user defined SSL stuff */ + struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */ + struct ssl_general_config general_ssl; /* general user defined SSL stuff */ + curl_proxytype proxytype; /* what kind of proxy that is in use */ + long dns_cache_timeout; /* DNS cache timeout */ + long buffer_size; /* size of receive buffer to use */ + size_t upload_buffer_size; /* size of upload buffer to use, + keep it >= CURL_MAX_WRITE_SIZE */ + void *private_data; /* application-private data */ + struct curl_slist *http200aliases; /* linked list of aliases for http200 */ + long ipver; /* the CURL_IPRESOLVE_* defines in the public header file + 0 - whatever, 1 - v2, 2 - v6 */ + curl_off_t max_filesize; /* Maximum file size to download */ +#ifndef CURL_DISABLE_FTP + curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used */ + curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */ + curl_ftpccc ftp_ccc; /* FTP CCC options */ +#endif + int ftp_create_missing_dirs; /* 1 - create directories that don't exist + 2 - the same but also allow MKD to fail once + */ + curl_sshkeycallback ssh_keyfunc; /* key matching callback */ + void *ssh_keyfunc_userp; /* custom pointer to callback */ + enum CURL_NETRC_OPTION + use_netrc; /* defined in include/curl.h */ + curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or + IMAP or POP3 or others! */ + long new_file_perms; /* Permissions to use when creating remote files */ + long new_directory_perms; /* Permissions to use when creating remote dirs */ + long ssh_auth_types; /* allowed SSH auth types */ + char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */ + unsigned int scope_id; /* Scope id for IPv6 */ + long allowed_protocols; + long redir_protocols; + struct curl_slist *mail_rcpt; /* linked list of mail recipients */ + /* Common RTSP header options */ + Curl_RtspReq rtspreq; /* RTSP request type */ + long rtspversion; /* like httpversion, for RTSP */ + curl_chunk_bgn_callback chunk_bgn; /* called before part of transfer + starts */ + curl_chunk_end_callback chunk_end; /* called after part transferring + stopped */ + curl_fnmatch_callback fnmatch; /* callback to decide which file corresponds + to pattern (e.g. if WILDCARDMATCH is on) */ + void *fnmatch_data; + + long gssapi_delegation; /* GSS-API credential delegation, see the + documentation of CURLOPT_GSSAPI_DELEGATION */ + + long tcp_keepidle; /* seconds in idle before sending keepalive probe */ + long tcp_keepintvl; /* seconds between TCP keepalive probes */ + + size_t maxconnects; /* Max idle connections in the connection cache */ + + long expect_100_timeout; /* in milliseconds */ + struct Curl_easy *stream_depends_on; + int stream_weight; + struct Curl_http2_dep *stream_dependents; + + curl_resolver_start_callback resolver_start; /* optional callback called + before resolver start */ + void *resolver_start_client; /* pointer to pass to resolver start callback */ + long upkeep_interval_ms; /* Time between calls for connection upkeep. */ + multidone_func fmultidone; + struct Curl_easy *dohfor; /* this is a DoH request for that transfer */ + CURLU *uh; /* URL handle for the current parsed URL */ + void *trailer_data; /* pointer to pass to trailer data callback */ + curl_trailer_callback trailer_callback; /* trailing data callback */ + bit is_fread_set:1; /* has read callback been set to non-NULL? */ + bit is_fwrite_set:1; /* has write callback been set to non-NULL? */ + bit free_referer:1; /* set TRUE if 'referer' points to a string we + allocated */ + bit tftp_no_options:1; /* do not send TFTP options requests */ + bit sep_headers:1; /* handle host and proxy headers separately */ + bit cookiesession:1; /* new cookie session? */ + bit crlf:1; /* convert crlf on ftp upload(?) */ + bit strip_path_slash:1; /* strip off initial slash from path */ + bit ssh_compression:1; /* enable SSH compression */ + +/* Here follows boolean settings that define how to behave during + this session. They are STATIC, set by libcurl users or at least initially + and they don't change during operations. */ + bit get_filetime:1; /* get the time and get of the remote file */ + bit tunnel_thru_httpproxy:1; /* use CONNECT through a HTTP proxy */ + bit prefer_ascii:1; /* ASCII rather than binary */ + bit ftp_append:1; /* append, not overwrite, on upload */ + bit ftp_list_only:1; /* switch FTP command for listing directories */ +#ifndef CURL_DISABLE_FTP + bit ftp_use_port:1; /* use the FTP PORT command */ + bit ftp_use_epsv:1; /* if EPSV is to be attempted or not */ + bit ftp_use_eprt:1; /* if EPRT is to be attempted or not */ + bit ftp_use_pret:1; /* if PRET is to be used before PASV or not */ + bit ftp_skip_ip:1; /* skip the IP address the FTP server passes on to + us */ +#endif + bit hide_progress:1; /* don't use the progress meter */ + bit http_fail_on_error:1; /* fail on HTTP error codes >= 400 */ + bit http_keep_sending_on_error:1; /* for HTTP status codes >= 300 */ + bit http_follow_location:1; /* follow HTTP redirects */ + bit http_transfer_encoding:1; /* request compressed HTTP + transfer-encoding */ + bit allow_auth_to_other_hosts:1; + bit include_header:1; /* include received protocol headers in data output */ + bit http_set_referer:1; /* is a custom referer used */ + bit http_auto_referer:1; /* set "correct" referer when following + location: */ + bit opt_no_body:1; /* as set with CURLOPT_NOBODY */ + bit upload:1; /* upload request */ + bit verbose:1; /* output verbosity */ + bit krb:1; /* Kerberos connection requested */ + bit reuse_forbid:1; /* forbidden to be reused, close after use */ + bit reuse_fresh:1; /* do not re-use an existing connection */ + + bit no_signal:1; /* do not use any signal/alarm handler */ + bit tcp_nodelay:1; /* whether to enable TCP_NODELAY or not */ + bit ignorecl:1; /* ignore content length */ + bit connect_only:1; /* make connection, let application use the socket */ + bit http_te_skip:1; /* pass the raw body data to the user, even when + transfer-encoded (chunked, compressed) */ + bit http_ce_skip:1; /* pass the raw body data to the user, even when + content-encoded (chunked, compressed) */ + bit proxy_transfer_mode:1; /* set transfer mode (;type=) when doing + FTP via an HTTP proxy */ +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + bit socks5_gssapi_nec:1; /* Flag to support NEC SOCKS5 server */ +#endif + bit sasl_ir:1; /* Enable/disable SASL initial response */ + bit wildcard_enabled:1; /* enable wildcard matching */ + bit tcp_keepalive:1; /* use TCP keepalives */ + bit tcp_fastopen:1; /* use TCP Fast Open */ + bit ssl_enable_npn:1; /* TLS NPN extension? */ + bit ssl_enable_alpn:1;/* TLS ALPN extension? */ + bit path_as_is:1; /* allow dotdots? */ + bit pipewait:1; /* wait for multiplex status before starting a new + connection */ + bit suppress_connect_headers:1; /* suppress proxy CONNECT response headers + from user callbacks */ + bit dns_shuffle_addresses:1; /* whether to shuffle addresses before use */ + bit stream_depends_e:1; /* set or don't set the Exclusive bit */ + bit haproxyprotocol:1; /* whether to send HAProxy PROXY protocol v1 + header */ + bit abstract_unix_socket:1; + bit disallow_username_in_url:1; /* disallow username in url */ + bit doh:1; /* DNS-over-HTTPS enabled */ + bit doh_get:1; /* use GET for DoH requests, instead of POST */ + bit http09_allowed:1; /* allow HTTP/0.9 responses */ +}; + +struct Names { + struct curl_hash *hostcache; + enum { + HCACHE_NONE, /* not pointing to anything */ + HCACHE_MULTI, /* points to a shared one in the multi handle */ + HCACHE_SHARED /* points to a shared one in a shared object */ + } hostcachetype; +}; + +/* + * The 'connectdata' struct MUST have all the connection oriented stuff as we + * may have several simultaneous connections and connection structs in memory. + * + * The 'struct UserDefined' must only contain data that is set once to go for + * many (perhaps) independent connections. Values that are generated or + * calculated internally for the "session handle" must be defined within the + * 'struct UrlState' instead. + */ + +struct Curl_easy { + /* first, two fields for the linked list of these */ + struct Curl_easy *next; + struct Curl_easy *prev; + + struct connectdata *conn; + struct curl_llist_element connect_queue; + struct curl_llist_element conn_queue; /* list per connectdata */ + + CURLMstate mstate; /* the handle's state */ + CURLcode result; /* previous result */ + + struct Curl_message msg; /* A single posted message. */ + + /* Array with the plain socket numbers this handle takes care of, in no + particular order. Note that all sockets are added to the sockhash, where + the state etc are also kept. This array is mostly used to detect when a + socket is to be removed from the hash. See singlesocket(). */ + curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE]; + int actions[MAX_SOCKSPEREASYHANDLE]; /* action for each socket in + sockets[] */ + int numsocks; + + struct Names dns; + struct Curl_multi *multi; /* if non-NULL, points to the multi handle + struct to which this "belongs" when used by + the multi interface */ + struct Curl_multi *multi_easy; /* if non-NULL, points to the multi handle + struct to which this "belongs" when used + by the easy interface */ + struct Curl_share *share; /* Share, handles global variable mutexing */ +#ifdef USE_LIBPSL + struct PslCache *psl; /* The associated PSL cache. */ +#endif + struct SingleRequest req; /* Request-specific data */ + struct UserDefined set; /* values set by the libcurl user */ + struct DynamicStatic change; /* possibly modified userdefined data */ + struct CookieInfo *cookies; /* the cookies, read from files and servers. + NOTE that the 'cookie' field in the + UserDefined struct defines if the "engine" + is to be used or not. */ +#ifdef USE_ALTSVC + struct altsvcinfo *asi; /* the alt-svc cache */ +#endif + struct Progress progress; /* for all the progress meter data */ + struct UrlState state; /* struct for fields used for state info and + other dynamic purposes */ +#ifndef CURL_DISABLE_FTP + struct WildcardData wildcard; /* wildcard download state info */ +#endif + struct PureInfo info; /* stats, reports and info data */ + struct curl_tlssessioninfo tsi; /* Information about the TLS session, only + valid after a client has asked for it */ +#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) + iconv_t outbound_cd; /* for translating to the network encoding */ + iconv_t inbound_cd; /* for translating from the network encoding */ + iconv_t utf8_cd; /* for translating to UTF8 */ +#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ + unsigned int magic; /* set to a CURLEASY_MAGIC_NUMBER */ +}; + +#define LIBCURL_NAME "libcurl" + +#endif /* HEADER_CURL_URLDATA_H */ diff --git a/libcurl/lib/vauth/cleartext.c b/libcurl/lib/vauth/cleartext.c new file mode 100644 index 0000000..6f452c1 --- /dev/null +++ b/libcurl/lib/vauth/cleartext.c @@ -0,0 +1,169 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC4616 PLAIN authentication + * Draft LOGIN SASL Mechanism + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \ + !defined(CURL_DISABLE_POP3) + +#include +#include "urldata.h" + +#include "vauth/vauth.h" +#include "curl_base64.h" +#include "curl_md5.h" +#include "warnless.h" +#include "strtok.h" +#include "sendf.h" +#include "curl_printf.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Curl_auth_create_plain_message() + * + * This is used to generate an already encoded PLAIN message ready + * for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * authzid [in] - The authorization identity. + * authcid [in] - The authentication identity. + * passwd [in] - The password. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_plain_message(struct Curl_easy *data, + const char *authzid, + const char *authcid, + const char *passwd, + char **outptr, size_t *outlen) +{ + CURLcode result; + char *plainauth; + size_t zlen; + size_t clen; + size_t plen; + size_t plainlen; + + *outlen = 0; + *outptr = NULL; + zlen = (authzid == NULL ? 0 : strlen(authzid)); + clen = strlen(authcid); + plen = strlen(passwd); + + /* Compute binary message length. Check for overflows. */ + if(((zlen + clen) > SIZE_T_MAX/4) || (plen > (SIZE_T_MAX/2 - 2))) + return CURLE_OUT_OF_MEMORY; + plainlen = zlen + clen + plen + 2; + + plainauth = malloc(plainlen); + if(!plainauth) + return CURLE_OUT_OF_MEMORY; + + /* Calculate the reply */ + if(zlen != 0) + memcpy(plainauth, authzid, zlen); + plainauth[zlen] = '\0'; + memcpy(plainauth + zlen + 1, authcid, clen); + plainauth[zlen + clen + 1] = '\0'; + memcpy(plainauth + zlen + clen + 2, passwd, plen); + + /* Base64 encode the reply */ + result = Curl_base64_encode(data, plainauth, plainlen, outptr, outlen); + free(plainauth); + + return result; +} + +/* + * Curl_auth_create_login_message() + * + * This is used to generate an already encoded LOGIN message containing the + * user name or password ready for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * valuep [in] - The user name or user's password. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_login_message(struct Curl_easy *data, + const char *valuep, char **outptr, + size_t *outlen) +{ + size_t vlen = strlen(valuep); + + if(!vlen) { + /* Calculate an empty reply */ + *outptr = strdup("="); + if(*outptr) { + *outlen = (size_t) 1; + return CURLE_OK; + } + + *outlen = 0; + return CURLE_OUT_OF_MEMORY; + } + + /* Base64 encode the value */ + return Curl_base64_encode(data, valuep, vlen, outptr, outlen); +} + +/* + * Curl_auth_create_external_message() + * + * This is used to generate an already encoded EXTERNAL message containing + * the user name ready for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * user [in] - The user name. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_external_message(struct Curl_easy *data, + const char *user, char **outptr, + size_t *outlen) +{ + /* This is the same formatting as the login message */ + return Curl_auth_create_login_message(data, user, outptr, outlen); +} + +#endif /* if no users */ diff --git a/libcurl/lib/vauth/cram.c b/libcurl/lib/vauth/cram.c new file mode 100644 index 0000000..d148618 --- /dev/null +++ b/libcurl/lib/vauth/cram.c @@ -0,0 +1,138 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC2195 CRAM-MD5 authentication + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_CRYPTO_AUTH) + +#include +#include "urldata.h" + +#include "vauth/vauth.h" +#include "curl_base64.h" +#include "curl_hmac.h" +#include "curl_md5.h" +#include "warnless.h" +#include "curl_printf.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Curl_auth_decode_cram_md5_message() + * + * This is used to decode an already encoded CRAM-MD5 challenge message. + * + * Parameters: + * + * chlg64 [in] - The base64 encoded challenge message. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_decode_cram_md5_message(const char *chlg64, char **outptr, + size_t *outlen) +{ + CURLcode result = CURLE_OK; + size_t chlg64len = strlen(chlg64); + + *outptr = NULL; + *outlen = 0; + + /* Decode the challenge if necessary */ + if(chlg64len && *chlg64 != '=') + result = Curl_base64_decode(chlg64, (unsigned char **) outptr, outlen); + + return result; +} + +/* + * Curl_auth_create_cram_md5_message() + * + * This is used to generate an already encoded CRAM-MD5 response message ready + * for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * chlg [in] - The challenge. + * userp [in] - The user name. + * passwdp [in] - The user's password. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data, + const char *chlg, + const char *userp, + const char *passwdp, + char **outptr, size_t *outlen) +{ + CURLcode result = CURLE_OK; + size_t chlglen = 0; + HMAC_context *ctxt; + unsigned char digest[MD5_DIGEST_LEN]; + char *response; + + if(chlg) + chlglen = strlen(chlg); + + /* Compute the digest using the password as the key */ + ctxt = Curl_HMAC_init(Curl_HMAC_MD5, + (const unsigned char *) passwdp, + curlx_uztoui(strlen(passwdp))); + if(!ctxt) + return CURLE_OUT_OF_MEMORY; + + /* Update the digest with the given challenge */ + if(chlglen > 0) + Curl_HMAC_update(ctxt, (const unsigned char *) chlg, + curlx_uztoui(chlglen)); + + /* Finalise the digest */ + Curl_HMAC_final(ctxt, digest); + + /* Generate the response */ + response = aprintf( + "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + userp, digest[0], digest[1], digest[2], digest[3], digest[4], + digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], + digest[11], digest[12], digest[13], digest[14], digest[15]); + if(!response) + return CURLE_OUT_OF_MEMORY; + + /* Base64 encode the response */ + result = Curl_base64_encode(data, response, 0, outptr, outlen); + + free(response); + + return result; +} + +#endif /* !CURL_DISABLE_CRYPTO_AUTH */ diff --git a/libcurl/lib/vauth/digest.c b/libcurl/lib/vauth/digest.c new file mode 100644 index 0000000..8cd4d83 --- /dev/null +++ b/libcurl/lib/vauth/digest.c @@ -0,0 +1,1005 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC2831 DIGEST-MD5 authentication + * RFC7616 DIGEST-SHA256, DIGEST-SHA512-256 authentication + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_CRYPTO_AUTH) + +#include + +#include "vauth/vauth.h" +#include "vauth/digest.h" +#include "urldata.h" +#include "curl_base64.h" +#include "curl_hmac.h" +#include "curl_md5.h" +#include "curl_sha256.h" +#include "vtls/vtls.h" +#include "warnless.h" +#include "strtok.h" +#include "strcase.h" +#include "non-ascii.h" /* included for Curl_convert_... prototypes */ +#include "curl_printf.h" +#include "rand.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +#if !defined(USE_WINDOWS_SSPI) +#define DIGEST_QOP_VALUE_AUTH (1 << 0) +#define DIGEST_QOP_VALUE_AUTH_INT (1 << 1) +#define DIGEST_QOP_VALUE_AUTH_CONF (1 << 2) + +#define DIGEST_QOP_VALUE_STRING_AUTH "auth" +#define DIGEST_QOP_VALUE_STRING_AUTH_INT "auth-int" +#define DIGEST_QOP_VALUE_STRING_AUTH_CONF "auth-conf" + +/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines. + It converts digest text to ASCII so the MD5 will be correct for + what ultimately goes over the network. +*/ +#define CURL_OUTPUT_DIGEST_CONV(a, b) \ + result = Curl_convert_to_network(a, (char *)b, strlen((const char *)b)); \ + if(result) { \ + free(b); \ + return result; \ + } +#endif /* !USE_WINDOWS_SSPI */ + +bool Curl_auth_digest_get_pair(const char *str, char *value, char *content, + const char **endptr) +{ + int c; + bool starts_with_quote = FALSE; + bool escape = FALSE; + + for(c = DIGEST_MAX_VALUE_LENGTH - 1; (*str && (*str != '=') && c--);) + *value++ = *str++; + *value = 0; + + if('=' != *str++) + /* eek, no match */ + return FALSE; + + if('\"' == *str) { + /* This starts with a quote so it must end with one as well! */ + str++; + starts_with_quote = TRUE; + } + + for(c = DIGEST_MAX_CONTENT_LENGTH - 1; *str && c--; str++) { + switch(*str) { + case '\\': + if(!escape) { + /* possibly the start of an escaped quote */ + escape = TRUE; + *content++ = '\\'; /* Even though this is an escape character, we still + store it as-is in the target buffer */ + continue; + } + break; + + case ',': + if(!starts_with_quote) { + /* This signals the end of the content if we didn't get a starting + quote and then we do "sloppy" parsing */ + c = 0; /* the end */ + continue; + } + break; + + case '\r': + case '\n': + /* end of string */ + c = 0; + continue; + + case '\"': + if(!escape && starts_with_quote) { + /* end of string */ + c = 0; + continue; + } + break; + } + + escape = FALSE; + *content++ = *str; + } + + *content = 0; + *endptr = str; + + return TRUE; +} + +#if !defined(USE_WINDOWS_SSPI) +/* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/ +static void auth_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */ + unsigned char *dest) /* 33 bytes */ +{ + int i; + for(i = 0; i < 16; i++) + msnprintf((char *) &dest[i * 2], 3, "%02x", source[i]); +} + +/* Convert sha256 chunk to RFC7616 -suitable ascii string*/ +static void auth_digest_sha256_to_ascii(unsigned char *source, /* 32 bytes */ + unsigned char *dest) /* 65 bytes */ +{ + int i; + for(i = 0; i < 32; i++) + msnprintf((char *) &dest[i * 2], 3, "%02x", source[i]); +} + +/* Perform quoted-string escaping as described in RFC2616 and its errata */ +static char *auth_digest_string_quoted(const char *source) +{ + char *dest; + const char *s = source; + size_t n = 1; /* null terminator */ + + /* Calculate size needed */ + while(*s) { + ++n; + if(*s == '"' || *s == '\\') { + ++n; + } + ++s; + } + + dest = malloc(n); + if(dest) { + char *d = dest; + s = source; + while(*s) { + if(*s == '"' || *s == '\\') { + *d++ = '\\'; + } + *d++ = *s++; + } + *d = 0; + } + + return dest; +} + +/* Retrieves the value for a corresponding key from the challenge string + * returns TRUE if the key could be found, FALSE if it does not exists + */ +static bool auth_digest_get_key_value(const char *chlg, + const char *key, + char *value, + size_t max_val_len, + char end_char) +{ + char *find_pos; + size_t i; + + find_pos = strstr(chlg, key); + if(!find_pos) + return FALSE; + + find_pos += strlen(key); + + for(i = 0; *find_pos && *find_pos != end_char && i < max_val_len - 1; ++i) + value[i] = *find_pos++; + value[i] = '\0'; + + return TRUE; +} + +static CURLcode auth_digest_get_qop_values(const char *options, int *value) +{ + char *tmp; + char *token; + char *tok_buf = NULL; + + /* Initialise the output */ + *value = 0; + + /* Tokenise the list of qop values. Use a temporary clone of the buffer since + strtok_r() ruins it. */ + tmp = strdup(options); + if(!tmp) + return CURLE_OUT_OF_MEMORY; + + token = strtok_r(tmp, ",", &tok_buf); + while(token != NULL) { + if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH)) + *value |= DIGEST_QOP_VALUE_AUTH; + else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) + *value |= DIGEST_QOP_VALUE_AUTH_INT; + else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_CONF)) + *value |= DIGEST_QOP_VALUE_AUTH_CONF; + + token = strtok_r(NULL, ",", &tok_buf); + } + + free(tmp); + + return CURLE_OK; +} + +/* + * auth_decode_digest_md5_message() + * + * This is used internally to decode an already encoded DIGEST-MD5 challenge + * message into the separate attributes. + * + * Parameters: + * + * chlg64 [in] - The base64 encoded challenge message. + * nonce [in/out] - The buffer where the nonce will be stored. + * nlen [in] - The length of the nonce buffer. + * realm [in/out] - The buffer where the realm will be stored. + * rlen [in] - The length of the realm buffer. + * alg [in/out] - The buffer where the algorithm will be stored. + * alen [in] - The length of the algorithm buffer. + * qop [in/out] - The buffer where the qop-options will be stored. + * qlen [in] - The length of the qop buffer. + * + * Returns CURLE_OK on success. + */ +static CURLcode auth_decode_digest_md5_message(const char *chlg64, + char *nonce, size_t nlen, + char *realm, size_t rlen, + char *alg, size_t alen, + char *qop, size_t qlen) +{ + CURLcode result = CURLE_OK; + unsigned char *chlg = NULL; + size_t chlglen = 0; + size_t chlg64len = strlen(chlg64); + + /* Decode the base-64 encoded challenge message */ + if(chlg64len && *chlg64 != '=') { + result = Curl_base64_decode(chlg64, &chlg, &chlglen); + if(result) + return result; + } + + /* Ensure we have a valid challenge message */ + if(!chlg) + return CURLE_BAD_CONTENT_ENCODING; + + /* Retrieve nonce string from the challenge */ + if(!auth_digest_get_key_value((char *) chlg, "nonce=\"", nonce, nlen, + '\"')) { + free(chlg); + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Retrieve realm string from the challenge */ + if(!auth_digest_get_key_value((char *) chlg, "realm=\"", realm, rlen, + '\"')) { + /* Challenge does not have a realm, set empty string [RFC2831] page 6 */ + strcpy(realm, ""); + } + + /* Retrieve algorithm string from the challenge */ + if(!auth_digest_get_key_value((char *) chlg, "algorithm=", alg, alen, ',')) { + free(chlg); + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Retrieve qop-options string from the challenge */ + if(!auth_digest_get_key_value((char *) chlg, "qop=\"", qop, qlen, '\"')) { + free(chlg); + return CURLE_BAD_CONTENT_ENCODING; + } + + free(chlg); + + return CURLE_OK; +} + +/* + * Curl_auth_is_digest_supported() + * + * This is used to evaluate if DIGEST is supported. + * + * Parameters: None + * + * Returns TRUE as DIGEST as handled by libcurl. + */ +bool Curl_auth_is_digest_supported(void) +{ + return TRUE; +} + +/* + * Curl_auth_create_digest_md5_message() + * + * This is used to generate an already encoded DIGEST-MD5 response message + * ready for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * chlg64 [in] - The base64 encoded challenge message. + * userp [in] - The user name. + * passwdp [in] - The user's password. + * service [in] - The service type such as http, smtp, pop or imap. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, + const char *chlg64, + const char *userp, + const char *passwdp, + const char *service, + char **outptr, size_t *outlen) +{ + size_t i; + MD5_context *ctxt; + char *response = NULL; + unsigned char digest[MD5_DIGEST_LEN]; + char HA1_hex[2 * MD5_DIGEST_LEN + 1]; + char HA2_hex[2 * MD5_DIGEST_LEN + 1]; + char resp_hash_hex[2 * MD5_DIGEST_LEN + 1]; + char nonce[64]; + char realm[128]; + char algorithm[64]; + char qop_options[64]; + int qop_values; + char cnonce[33]; + char nonceCount[] = "00000001"; + char method[] = "AUTHENTICATE"; + char qop[] = DIGEST_QOP_VALUE_STRING_AUTH; + char *spn = NULL; + + /* Decode the challenge message */ + CURLcode result = auth_decode_digest_md5_message(chlg64, nonce, + sizeof(nonce), realm, + sizeof(realm), algorithm, + sizeof(algorithm), + qop_options, + sizeof(qop_options)); + if(result) + return result; + + /* We only support md5 sessions */ + if(strcmp(algorithm, "md5-sess") != 0) + return CURLE_BAD_CONTENT_ENCODING; + + /* Get the qop-values from the qop-options */ + result = auth_digest_get_qop_values(qop_options, &qop_values); + if(result) + return result; + + /* We only support auth quality-of-protection */ + if(!(qop_values & DIGEST_QOP_VALUE_AUTH)) + return CURLE_BAD_CONTENT_ENCODING; + + /* Generate 32 random hex chars, 32 bytes + 1 zero termination */ + result = Curl_rand_hex(data, (unsigned char *)cnonce, sizeof(cnonce)); + if(result) + return result; + + /* So far so good, now calculate A1 and H(A1) according to RFC 2831 */ + ctxt = Curl_MD5_init(Curl_DIGEST_MD5); + if(!ctxt) + return CURLE_OUT_OF_MEMORY; + + Curl_MD5_update(ctxt, (const unsigned char *) userp, + curlx_uztoui(strlen(userp))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) realm, + curlx_uztoui(strlen(realm))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) passwdp, + curlx_uztoui(strlen(passwdp))); + Curl_MD5_final(ctxt, digest); + + ctxt = Curl_MD5_init(Curl_DIGEST_MD5); + if(!ctxt) + return CURLE_OUT_OF_MEMORY; + + Curl_MD5_update(ctxt, (const unsigned char *) digest, MD5_DIGEST_LEN); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) nonce, + curlx_uztoui(strlen(nonce))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) cnonce, + curlx_uztoui(strlen(cnonce))); + Curl_MD5_final(ctxt, digest); + + /* Convert calculated 16 octet hex into 32 bytes string */ + for(i = 0; i < MD5_DIGEST_LEN; i++) + msnprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]); + + /* Generate our SPN */ + spn = Curl_auth_build_spn(service, realm, NULL); + if(!spn) + return CURLE_OUT_OF_MEMORY; + + /* Calculate H(A2) */ + ctxt = Curl_MD5_init(Curl_DIGEST_MD5); + if(!ctxt) { + free(spn); + + return CURLE_OUT_OF_MEMORY; + } + + Curl_MD5_update(ctxt, (const unsigned char *) method, + curlx_uztoui(strlen(method))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) spn, + curlx_uztoui(strlen(spn))); + Curl_MD5_final(ctxt, digest); + + for(i = 0; i < MD5_DIGEST_LEN; i++) + msnprintf(&HA2_hex[2 * i], 3, "%02x", digest[i]); + + /* Now calculate the response hash */ + ctxt = Curl_MD5_init(Curl_DIGEST_MD5); + if(!ctxt) { + free(spn); + + return CURLE_OUT_OF_MEMORY; + } + + Curl_MD5_update(ctxt, (const unsigned char *) HA1_hex, 2 * MD5_DIGEST_LEN); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) nonce, + curlx_uztoui(strlen(nonce))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + + Curl_MD5_update(ctxt, (const unsigned char *) nonceCount, + curlx_uztoui(strlen(nonceCount))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) cnonce, + curlx_uztoui(strlen(cnonce))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) qop, + curlx_uztoui(strlen(qop))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + + Curl_MD5_update(ctxt, (const unsigned char *) HA2_hex, 2 * MD5_DIGEST_LEN); + Curl_MD5_final(ctxt, digest); + + for(i = 0; i < MD5_DIGEST_LEN; i++) + msnprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]); + + /* Generate the response */ + response = aprintf("username=\"%s\",realm=\"%s\",nonce=\"%s\"," + "cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s," + "qop=%s", + userp, realm, nonce, + cnonce, nonceCount, spn, resp_hash_hex, qop); + free(spn); + if(!response) + return CURLE_OUT_OF_MEMORY; + + /* Base64 encode the response */ + result = Curl_base64_encode(data, response, 0, outptr, outlen); + + free(response); + + return result; +} + +/* + * Curl_auth_decode_digest_http_message() + * + * This is used to decode a HTTP DIGEST challenge message into the separate + * attributes. + * + * Parameters: + * + * chlg [in] - The challenge message. + * digest [in/out] - The digest data struct being used and modified. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_decode_digest_http_message(const char *chlg, + struct digestdata *digest) +{ + bool before = FALSE; /* got a nonce before */ + bool foundAuth = FALSE; + bool foundAuthInt = FALSE; + char *token = NULL; + char *tmp = NULL; + + /* If we already have received a nonce, keep that in mind */ + if(digest->nonce) + before = TRUE; + + /* Clean up any former leftovers and initialise to defaults */ + Curl_auth_digest_cleanup(digest); + + for(;;) { + char value[DIGEST_MAX_VALUE_LENGTH]; + char content[DIGEST_MAX_CONTENT_LENGTH]; + + /* Pass all additional spaces here */ + while(*chlg && ISSPACE(*chlg)) + chlg++; + + /* Extract a value=content pair */ + if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) { + if(strcasecompare(value, "nonce")) { + free(digest->nonce); + digest->nonce = strdup(content); + if(!digest->nonce) + return CURLE_OUT_OF_MEMORY; + } + else if(strcasecompare(value, "stale")) { + if(strcasecompare(content, "true")) { + digest->stale = TRUE; + digest->nc = 1; /* we make a new nonce now */ + } + } + else if(strcasecompare(value, "realm")) { + free(digest->realm); + digest->realm = strdup(content); + if(!digest->realm) + return CURLE_OUT_OF_MEMORY; + } + else if(strcasecompare(value, "opaque")) { + free(digest->opaque); + digest->opaque = strdup(content); + if(!digest->opaque) + return CURLE_OUT_OF_MEMORY; + } + else if(strcasecompare(value, "qop")) { + char *tok_buf = NULL; + /* Tokenize the list and choose auth if possible, use a temporary + clone of the buffer since strtok_r() ruins it */ + tmp = strdup(content); + if(!tmp) + return CURLE_OUT_OF_MEMORY; + + token = strtok_r(tmp, ",", &tok_buf); + while(token != NULL) { + if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH)) { + foundAuth = TRUE; + } + else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) { + foundAuthInt = TRUE; + } + token = strtok_r(NULL, ",", &tok_buf); + } + + free(tmp); + + /* Select only auth or auth-int. Otherwise, ignore */ + if(foundAuth) { + free(digest->qop); + digest->qop = strdup(DIGEST_QOP_VALUE_STRING_AUTH); + if(!digest->qop) + return CURLE_OUT_OF_MEMORY; + } + else if(foundAuthInt) { + free(digest->qop); + digest->qop = strdup(DIGEST_QOP_VALUE_STRING_AUTH_INT); + if(!digest->qop) + return CURLE_OUT_OF_MEMORY; + } + } + else if(strcasecompare(value, "algorithm")) { + free(digest->algorithm); + digest->algorithm = strdup(content); + if(!digest->algorithm) + return CURLE_OUT_OF_MEMORY; + + if(strcasecompare(content, "MD5-sess")) + digest->algo = CURLDIGESTALGO_MD5SESS; + else if(strcasecompare(content, "MD5")) + digest->algo = CURLDIGESTALGO_MD5; + else if(strcasecompare(content, "SHA-256")) + digest->algo = CURLDIGESTALGO_SHA256; + else if(strcasecompare(content, "SHA-256-SESS")) + digest->algo = CURLDIGESTALGO_SHA256SESS; + else if(strcasecompare(content, "SHA-512-256")) + digest->algo = CURLDIGESTALGO_SHA512_256; + else if(strcasecompare(content, "SHA-512-256-SESS")) + digest->algo = CURLDIGESTALGO_SHA512_256SESS; + else + return CURLE_BAD_CONTENT_ENCODING; + } + else if(strcasecompare(value, "userhash")) { + if(strcasecompare(content, "true")) { + digest->userhash = TRUE; + } + } + else { + /* Unknown specifier, ignore it! */ + } + } + else + break; /* We're done here */ + + /* Pass all additional spaces here */ + while(*chlg && ISSPACE(*chlg)) + chlg++; + + /* Allow the list to be comma-separated */ + if(',' == *chlg) + chlg++; + } + + /* We had a nonce since before, and we got another one now without + 'stale=true'. This means we provided bad credentials in the previous + request */ + if(before && !digest->stale) + return CURLE_BAD_CONTENT_ENCODING; + + /* We got this header without a nonce, that's a bad Digest line! */ + if(!digest->nonce) + return CURLE_BAD_CONTENT_ENCODING; + + return CURLE_OK; +} + +/* + * _Curl_auth_create_digest_http_message() + * + * This is used to generate a HTTP DIGEST response message ready for sending + * to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name. + * passwdp [in] - The user's password. + * request [in] - The HTTP request. + * uripath [in] - The path of the HTTP uri. + * digest [in/out] - The digest data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +static CURLcode _Curl_auth_create_digest_http_message( + struct Curl_easy *data, + const char *userp, + const char *passwdp, + const unsigned char *request, + const unsigned char *uripath, + struct digestdata *digest, + char **outptr, size_t *outlen, + void (*convert_to_ascii)(unsigned char *, unsigned char *), + void (*hash)(unsigned char *, const unsigned char *)) +{ + CURLcode result; + unsigned char hashbuf[32]; /* 32 bytes/256 bits */ + unsigned char request_digest[65]; + unsigned char *hashthis; + unsigned char ha1[65]; /* 64 digits and 1 zero byte */ + unsigned char ha2[65]; /* 64 digits and 1 zero byte */ + char userh[65]; + char *cnonce = NULL; + size_t cnonce_sz = 0; + char *userp_quoted; + char *response = NULL; + char *tmp = NULL; + + if(!digest->nc) + digest->nc = 1; + + if(!digest->cnonce) { + char cnoncebuf[33]; + result = Curl_rand_hex(data, (unsigned char *)cnoncebuf, + sizeof(cnoncebuf)); + if(result) + return result; + + result = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf), + &cnonce, &cnonce_sz); + if(result) + return result; + + digest->cnonce = cnonce; + } + + if(digest->userhash) { + hashthis = (unsigned char *) aprintf("%s:%s", userp, digest->realm); + if(!hashthis) + return CURLE_OUT_OF_MEMORY; + + CURL_OUTPUT_DIGEST_CONV(data, hashthis); + hash(hashbuf, hashthis); + free(hashthis); + convert_to_ascii(hashbuf, (unsigned char *)userh); + } + + /* + If the algorithm is "MD5" or unspecified (which then defaults to MD5): + + A1 = unq(username-value) ":" unq(realm-value) ":" passwd + + If the algorithm is "MD5-sess" then: + + A1 = H(unq(username-value) ":" unq(realm-value) ":" passwd) ":" + unq(nonce-value) ":" unq(cnonce-value) + */ + + hashthis = (unsigned char *) + aprintf("%s:%s:%s", digest->userhash ? userh : userp, + digest->realm, passwdp); + if(!hashthis) + return CURLE_OUT_OF_MEMORY; + + CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */ + hash(hashbuf, hashthis); + free(hashthis); + convert_to_ascii(hashbuf, ha1); + + if(digest->algo == CURLDIGESTALGO_MD5SESS || + digest->algo == CURLDIGESTALGO_SHA256SESS || + digest->algo == CURLDIGESTALGO_SHA512_256SESS) { + /* nonce and cnonce are OUTSIDE the hash */ + tmp = aprintf("%s:%s:%s", ha1, digest->nonce, digest->cnonce); + if(!tmp) + return CURLE_OUT_OF_MEMORY; + + CURL_OUTPUT_DIGEST_CONV(data, tmp); /* Convert on non-ASCII machines */ + hash(hashbuf, (unsigned char *) tmp); + free(tmp); + convert_to_ascii(hashbuf, ha1); + } + + /* + If the "qop" directive's value is "auth" or is unspecified, then A2 is: + + A2 = Method ":" digest-uri-value + + If the "qop" value is "auth-int", then A2 is: + + A2 = Method ":" digest-uri-value ":" H(entity-body) + + (The "Method" value is the HTTP request method as specified in section + 5.1.1 of RFC 2616) + */ + + hashthis = (unsigned char *) aprintf("%s:%s", request, uripath); + if(!hashthis) + return CURLE_OUT_OF_MEMORY; + + if(digest->qop && strcasecompare(digest->qop, "auth-int")) { + /* We don't support auth-int for PUT or POST */ + char hashed[65]; + unsigned char *hashthis2; + + hash(hashbuf, (const unsigned char *)""); + convert_to_ascii(hashbuf, (unsigned char *)hashed); + + hashthis2 = (unsigned char *)aprintf("%s:%s", hashthis, hashed); + free(hashthis); + hashthis = hashthis2; + } + + if(!hashthis) + return CURLE_OUT_OF_MEMORY; + + CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */ + hash(hashbuf, hashthis); + free(hashthis); + convert_to_ascii(hashbuf, ha2); + + if(digest->qop) { + hashthis = (unsigned char *) aprintf("%s:%s:%08x:%s:%s:%s", + ha1, + digest->nonce, + digest->nc, + digest->cnonce, + digest->qop, + ha2); + } + else { + hashthis = (unsigned char *) aprintf("%s:%s:%s", + ha1, + digest->nonce, + ha2); + } + + if(!hashthis) + return CURLE_OUT_OF_MEMORY; + + CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */ + hash(hashbuf, hashthis); + free(hashthis); + convert_to_ascii(hashbuf, request_digest); + + /* For test case 64 (snooped from a Mozilla 1.3a request) + + Authorization: Digest username="testuser", realm="testrealm", \ + nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca" + + Digest parameters are all quoted strings. Username which is provided by + the user will need double quotes and backslashes within it escaped. For + the other fields, this shouldn't be an issue. realm, nonce, and opaque + are copied as is from the server, escapes and all. cnonce is generated + with web-safe characters. uri is already percent encoded. nc is 8 hex + characters. algorithm and qop with standard values only contain web-safe + characters. + */ + userp_quoted = auth_digest_string_quoted(digest->userhash ? userh : userp); + if(!userp_quoted) + return CURLE_OUT_OF_MEMORY; + + if(digest->qop) { + response = aprintf("username=\"%s\", " + "realm=\"%s\", " + "nonce=\"%s\", " + "uri=\"%s\", " + "cnonce=\"%s\", " + "nc=%08x, " + "qop=%s, " + "response=\"%s\"", + userp_quoted, + digest->realm, + digest->nonce, + uripath, + digest->cnonce, + digest->nc, + digest->qop, + request_digest); + + if(strcasecompare(digest->qop, "auth")) + digest->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0 + padded which tells to the server how many times you are + using the same nonce in the qop=auth mode */ + } + else { + response = aprintf("username=\"%s\", " + "realm=\"%s\", " + "nonce=\"%s\", " + "uri=\"%s\", " + "response=\"%s\"", + userp_quoted, + digest->realm, + digest->nonce, + uripath, + request_digest); + } + free(userp_quoted); + if(!response) + return CURLE_OUT_OF_MEMORY; + + /* Add the optional fields */ + if(digest->opaque) { + /* Append the opaque */ + tmp = aprintf("%s, opaque=\"%s\"", response, digest->opaque); + free(response); + if(!tmp) + return CURLE_OUT_OF_MEMORY; + + response = tmp; + } + + if(digest->algorithm) { + /* Append the algorithm */ + tmp = aprintf("%s, algorithm=\"%s\"", response, digest->algorithm); + free(response); + if(!tmp) + return CURLE_OUT_OF_MEMORY; + + response = tmp; + } + + if(digest->userhash) { + /* Append the userhash */ + tmp = aprintf("%s, userhash=true", response); + free(response); + if(!tmp) + return CURLE_OUT_OF_MEMORY; + + response = tmp; + } + + /* Return the output */ + *outptr = response; + *outlen = strlen(response); + + return CURLE_OK; +} + +/* + * Curl_auth_create_digest_http_message() + * + * This is used to generate a HTTP DIGEST response message ready for sending + * to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name. + * passwdp [in] - The user's password. + * request [in] - The HTTP request. + * uripath [in] - The path of the HTTP uri. + * digest [in/out] - The digest data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, + const char *userp, + const char *passwdp, + const unsigned char *request, + const unsigned char *uripath, + struct digestdata *digest, + char **outptr, size_t *outlen) +{ + switch(digest->algo) { + case CURLDIGESTALGO_MD5: + case CURLDIGESTALGO_MD5SESS: + return _Curl_auth_create_digest_http_message(data, userp, passwdp, + request, uripath, digest, + outptr, outlen, + auth_digest_md5_to_ascii, + Curl_md5it); + + case CURLDIGESTALGO_SHA256: + case CURLDIGESTALGO_SHA256SESS: + case CURLDIGESTALGO_SHA512_256: + case CURLDIGESTALGO_SHA512_256SESS: + return _Curl_auth_create_digest_http_message(data, userp, passwdp, + request, uripath, digest, + outptr, outlen, + auth_digest_sha256_to_ascii, + Curl_sha256it); + + default: + return CURLE_UNSUPPORTED_PROTOCOL; + } +} + +/* + * Curl_auth_digest_cleanup() + * + * This is used to clean up the digest specific data. + * + * Parameters: + * + * digest [in/out] - The digest data struct being cleaned up. + * + */ +void Curl_auth_digest_cleanup(struct digestdata *digest) +{ + Curl_safefree(digest->nonce); + Curl_safefree(digest->cnonce); + Curl_safefree(digest->realm); + Curl_safefree(digest->opaque); + Curl_safefree(digest->qop); + Curl_safefree(digest->algorithm); + + digest->nc = 0; + digest->algo = CURLDIGESTALGO_MD5; /* default algorithm */ + digest->stale = FALSE; /* default means normal, not stale */ + digest->userhash = FALSE; +} +#endif /* !USE_WINDOWS_SSPI */ + +#endif /* CURL_DISABLE_CRYPTO_AUTH */ diff --git a/libcurl/lib/vauth/digest.h b/libcurl/lib/vauth/digest.h new file mode 100644 index 0000000..8686c44 --- /dev/null +++ b/libcurl/lib/vauth/digest.h @@ -0,0 +1,47 @@ +#ifndef HEADER_CURL_DIGEST_H +#define HEADER_CURL_DIGEST_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include + +#if !defined(CURL_DISABLE_CRYPTO_AUTH) + +#define DIGEST_MAX_VALUE_LENGTH 256 +#define DIGEST_MAX_CONTENT_LENGTH 1024 + +enum { + CURLDIGESTALGO_MD5, + CURLDIGESTALGO_MD5SESS, + CURLDIGESTALGO_SHA256, + CURLDIGESTALGO_SHA256SESS, + CURLDIGESTALGO_SHA512_256, + CURLDIGESTALGO_SHA512_256SESS +}; + +/* This is used to extract the realm from a challenge message */ +bool Curl_auth_digest_get_pair(const char *str, char *value, char *content, + const char **endptr); + +#endif + +#endif /* HEADER_CURL_DIGEST_H */ diff --git a/libcurl/lib/vauth/digest_sspi.c b/libcurl/lib/vauth/digest_sspi.c new file mode 100644 index 0000000..fe8093e --- /dev/null +++ b/libcurl/lib/vauth/digest_sspi.c @@ -0,0 +1,669 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2014 - 2016, Steve Holme, . + * Copyright (C) 2015 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC2831 DIGEST-MD5 authentication + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_CRYPTO_AUTH) + +#include + +#include "vauth/vauth.h" +#include "vauth/digest.h" +#include "urldata.h" +#include "curl_base64.h" +#include "warnless.h" +#include "curl_multibyte.h" +#include "sendf.h" +#include "strdup.h" +#include "strcase.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* +* Curl_auth_is_digest_supported() +* +* This is used to evaluate if DIGEST is supported. +* +* Parameters: None +* +* Returns TRUE if DIGEST is supported by Windows SSPI. +*/ +bool Curl_auth_is_digest_supported(void) +{ + PSecPkgInfo SecurityPackage; + SECURITY_STATUS status; + + /* Query the security package for Digest */ + status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), + &SecurityPackage); + + return (status == SEC_E_OK ? TRUE : FALSE); +} + +/* + * Curl_auth_create_digest_md5_message() + * + * This is used to generate an already encoded DIGEST-MD5 response message + * ready for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * chlg64 [in] - The base64 encoded challenge message. + * userp [in] - The user name in the format User or Domain\User. + * passwdp [in] - The user's password. + * service [in] - The service type such as http, smtp, pop or imap. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, + const char *chlg64, + const char *userp, + const char *passwdp, + const char *service, + char **outptr, size_t *outlen) +{ + CURLcode result = CURLE_OK; + TCHAR *spn = NULL; + size_t chlglen = 0; + size_t token_max = 0; + unsigned char *input_token = NULL; + unsigned char *output_token = NULL; + CredHandle credentials; + CtxtHandle context; + PSecPkgInfo SecurityPackage; + SEC_WINNT_AUTH_IDENTITY identity; + SEC_WINNT_AUTH_IDENTITY *p_identity; + SecBuffer chlg_buf; + SecBuffer resp_buf; + SecBufferDesc chlg_desc; + SecBufferDesc resp_desc; + SECURITY_STATUS status; + unsigned long attrs; + TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ + + /* Decode the base-64 encoded challenge message */ + if(strlen(chlg64) && *chlg64 != '=') { + result = Curl_base64_decode(chlg64, &input_token, &chlglen); + if(result) + return result; + } + + /* Ensure we have a valid challenge message */ + if(!input_token) { + infof(data, "DIGEST-MD5 handshake failure (empty challenge message)\n"); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Query the security package for DigestSSP */ + status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), + &SecurityPackage); + if(status != SEC_E_OK) { + free(input_token); + + return CURLE_NOT_BUILT_IN; + } + + token_max = SecurityPackage->cbMaxToken; + + /* Release the package buffer as it is not required anymore */ + s_pSecFn->FreeContextBuffer(SecurityPackage); + + /* Allocate our response buffer */ + output_token = malloc(token_max); + if(!output_token) { + free(input_token); + + return CURLE_OUT_OF_MEMORY; + } + + /* Generate our SPN */ + spn = Curl_auth_build_spn(service, data->conn->host.name, NULL); + if(!spn) { + free(output_token); + free(input_token); + + return CURLE_OUT_OF_MEMORY; + } + + if(userp && *userp) { + /* Populate our identity structure */ + result = Curl_create_sspi_identity(userp, passwdp, &identity); + if(result) { + free(spn); + free(output_token); + free(input_token); + + return result; + } + + /* Allow proper cleanup of the identity structure */ + p_identity = &identity; + } + else + /* Use the current Windows user */ + p_identity = NULL; + + /* Acquire our credentials handle */ + status = s_pSecFn->AcquireCredentialsHandle(NULL, + (TCHAR *) TEXT(SP_NAME_DIGEST), + SECPKG_CRED_OUTBOUND, NULL, + p_identity, NULL, NULL, + &credentials, &expiry); + + if(status != SEC_E_OK) { + Curl_sspi_free_identity(p_identity); + free(spn); + free(output_token); + free(input_token); + + return CURLE_LOGIN_DENIED; + } + + /* Setup the challenge "input" security buffer */ + chlg_desc.ulVersion = SECBUFFER_VERSION; + chlg_desc.cBuffers = 1; + chlg_desc.pBuffers = &chlg_buf; + chlg_buf.BufferType = SECBUFFER_TOKEN; + chlg_buf.pvBuffer = input_token; + chlg_buf.cbBuffer = curlx_uztoul(chlglen); + + /* Setup the response "output" security buffer */ + resp_desc.ulVersion = SECBUFFER_VERSION; + resp_desc.cBuffers = 1; + resp_desc.pBuffers = &resp_buf; + resp_buf.BufferType = SECBUFFER_TOKEN; + resp_buf.pvBuffer = output_token; + resp_buf.cbBuffer = curlx_uztoul(token_max); + + /* Generate our response message */ + status = s_pSecFn->InitializeSecurityContext(&credentials, NULL, spn, + 0, 0, 0, &chlg_desc, 0, + &context, &resp_desc, &attrs, + &expiry); + + if(status == SEC_I_COMPLETE_NEEDED || + status == SEC_I_COMPLETE_AND_CONTINUE) + s_pSecFn->CompleteAuthToken(&credentials, &resp_desc); + else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { + s_pSecFn->FreeCredentialsHandle(&credentials); + Curl_sspi_free_identity(p_identity); + free(spn); + free(output_token); + free(input_token); + + return CURLE_RECV_ERROR; + } + + /* Base64 encode the response */ + result = Curl_base64_encode(data, (char *) output_token, resp_buf.cbBuffer, + outptr, outlen); + + /* Free our handles */ + s_pSecFn->DeleteSecurityContext(&context); + s_pSecFn->FreeCredentialsHandle(&credentials); + + /* Free the identity structure */ + Curl_sspi_free_identity(p_identity); + + /* Free the SPN */ + free(spn); + + /* Free the response buffer */ + free(output_token); + + /* Free the decoded challenge message */ + free(input_token); + + return result; +} + +/* + * Curl_override_sspi_http_realm() + * + * This is used to populate the domain in a SSPI identity structure + * The realm is extracted from the challenge message and used as the + * domain if it is not already explicitly set. + * + * Parameters: + * + * chlg [in] - The challenge message. + * identity [in/out] - The identity structure. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_override_sspi_http_realm(const char *chlg, + SEC_WINNT_AUTH_IDENTITY *identity) +{ + xcharp_u domain, dup_domain; + + /* If domain is blank or unset, check challenge message for realm */ + if(!identity->Domain || !identity->DomainLength) { + for(;;) { + char value[DIGEST_MAX_VALUE_LENGTH]; + char content[DIGEST_MAX_CONTENT_LENGTH]; + + /* Pass all additional spaces here */ + while(*chlg && ISSPACE(*chlg)) + chlg++; + + /* Extract a value=content pair */ + if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) { + if(strcasecompare(value, "realm")) { + + /* Setup identity's domain and length */ + domain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *) content); + if(!domain.tchar_ptr) + return CURLE_OUT_OF_MEMORY; + + dup_domain.tchar_ptr = _tcsdup(domain.tchar_ptr); + if(!dup_domain.tchar_ptr) { + Curl_unicodefree(domain.tchar_ptr); + return CURLE_OUT_OF_MEMORY; + } + + free(identity->Domain); + identity->Domain = dup_domain.tbyte_ptr; + identity->DomainLength = curlx_uztoul(_tcslen(dup_domain.tchar_ptr)); + dup_domain.tchar_ptr = NULL; + + Curl_unicodefree(domain.tchar_ptr); + } + else { + /* Unknown specifier, ignore it! */ + } + } + else + break; /* We're done here */ + + /* Pass all additional spaces here */ + while(*chlg && ISSPACE(*chlg)) + chlg++; + + /* Allow the list to be comma-separated */ + if(',' == *chlg) + chlg++; + } + } + + return CURLE_OK; +} + +/* + * Curl_auth_decode_digest_http_message() + * + * This is used to decode a HTTP DIGEST challenge message into the separate + * attributes. + * + * Parameters: + * + * chlg [in] - The challenge message. + * digest [in/out] - The digest data struct being used and modified. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_decode_digest_http_message(const char *chlg, + struct digestdata *digest) +{ + size_t chlglen = strlen(chlg); + + /* We had an input token before so if there's another one now that means we + provided bad credentials in the previous request or it's stale. */ + if(digest->input_token) { + bool stale = false; + const char *p = chlg; + + /* Check for the 'stale' directive */ + for(;;) { + char value[DIGEST_MAX_VALUE_LENGTH]; + char content[DIGEST_MAX_CONTENT_LENGTH]; + + while(*p && ISSPACE(*p)) + p++; + + if(!Curl_auth_digest_get_pair(p, value, content, &p)) + break; + + if(strcasecompare(value, "stale") && + strcasecompare(content, "true")) { + stale = true; + break; + } + + while(*p && ISSPACE(*p)) + p++; + + if(',' == *p) + p++; + } + + if(stale) + Curl_auth_digest_cleanup(digest); + else + return CURLE_LOGIN_DENIED; + } + + /* Store the challenge for use later */ + digest->input_token = (BYTE *) Curl_memdup(chlg, chlglen + 1); + if(!digest->input_token) + return CURLE_OUT_OF_MEMORY; + + digest->input_token_len = chlglen; + + return CURLE_OK; +} + +/* + * Curl_auth_create_digest_http_message() + * + * This is used to generate a HTTP DIGEST response message ready for sending + * to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name in the format User or Domain\User. + * passwdp [in] - The user's password. + * request [in] - The HTTP request. + * uripath [in] - The path of the HTTP uri. + * digest [in/out] - The digest data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, + const char *userp, + const char *passwdp, + const unsigned char *request, + const unsigned char *uripath, + struct digestdata *digest, + char **outptr, size_t *outlen) +{ + size_t token_max; + char *resp; + BYTE *output_token; + size_t output_token_len = 0; + PSecPkgInfo SecurityPackage; + SecBuffer chlg_buf[5]; + SecBufferDesc chlg_desc; + SECURITY_STATUS status; + + (void) data; + + /* Query the security package for DigestSSP */ + status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), + &SecurityPackage); + if(status != SEC_E_OK) + return CURLE_NOT_BUILT_IN; + + token_max = SecurityPackage->cbMaxToken; + + /* Release the package buffer as it is not required anymore */ + s_pSecFn->FreeContextBuffer(SecurityPackage); + + /* Allocate the output buffer according to the max token size as indicated + by the security package */ + output_token = malloc(token_max); + if(!output_token) { + return CURLE_OUT_OF_MEMORY; + } + + /* If the user/passwd that was used to make the identity for http_context + has changed then delete that context. */ + if((userp && !digest->user) || (!userp && digest->user) || + (passwdp && !digest->passwd) || (!passwdp && digest->passwd) || + (userp && digest->user && strcmp(userp, digest->user)) || + (passwdp && digest->passwd && strcmp(passwdp, digest->passwd))) { + if(digest->http_context) { + s_pSecFn->DeleteSecurityContext(digest->http_context); + Curl_safefree(digest->http_context); + } + Curl_safefree(digest->user); + Curl_safefree(digest->passwd); + } + + if(digest->http_context) { + chlg_desc.ulVersion = SECBUFFER_VERSION; + chlg_desc.cBuffers = 5; + chlg_desc.pBuffers = chlg_buf; + chlg_buf[0].BufferType = SECBUFFER_TOKEN; + chlg_buf[0].pvBuffer = NULL; + chlg_buf[0].cbBuffer = 0; + chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS; + chlg_buf[1].pvBuffer = (void *) request; + chlg_buf[1].cbBuffer = curlx_uztoul(strlen((const char *) request)); + chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS; + chlg_buf[2].pvBuffer = (void *) uripath; + chlg_buf[2].cbBuffer = curlx_uztoul(strlen((const char *) uripath)); + chlg_buf[3].BufferType = SECBUFFER_PKG_PARAMS; + chlg_buf[3].pvBuffer = NULL; + chlg_buf[3].cbBuffer = 0; + chlg_buf[4].BufferType = SECBUFFER_PADDING; + chlg_buf[4].pvBuffer = output_token; + chlg_buf[4].cbBuffer = curlx_uztoul(token_max); + + status = s_pSecFn->MakeSignature(digest->http_context, 0, &chlg_desc, 0); + if(status == SEC_E_OK) + output_token_len = chlg_buf[4].cbBuffer; + else { /* delete the context so a new one can be made */ + infof(data, "digest_sspi: MakeSignature failed, error 0x%08lx\n", + (long)status); + s_pSecFn->DeleteSecurityContext(digest->http_context); + Curl_safefree(digest->http_context); + } + } + + if(!digest->http_context) { + CredHandle credentials; + SEC_WINNT_AUTH_IDENTITY identity; + SEC_WINNT_AUTH_IDENTITY *p_identity; + SecBuffer resp_buf; + SecBufferDesc resp_desc; + unsigned long attrs; + TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ + TCHAR *spn; + + /* free the copy of user/passwd used to make the previous identity */ + Curl_safefree(digest->user); + Curl_safefree(digest->passwd); + + if(userp && *userp) { + /* Populate our identity structure */ + if(Curl_create_sspi_identity(userp, passwdp, &identity)) { + free(output_token); + return CURLE_OUT_OF_MEMORY; + } + + /* Populate our identity domain */ + if(Curl_override_sspi_http_realm((const char *) digest->input_token, + &identity)) { + free(output_token); + return CURLE_OUT_OF_MEMORY; + } + + /* Allow proper cleanup of the identity structure */ + p_identity = &identity; + } + else + /* Use the current Windows user */ + p_identity = NULL; + + if(userp) { + digest->user = strdup(userp); + + if(!digest->user) { + free(output_token); + return CURLE_OUT_OF_MEMORY; + } + } + + if(passwdp) { + digest->passwd = strdup(passwdp); + + if(!digest->passwd) { + free(output_token); + Curl_safefree(digest->user); + return CURLE_OUT_OF_MEMORY; + } + } + + /* Acquire our credentials handle */ + status = s_pSecFn->AcquireCredentialsHandle(NULL, + (TCHAR *) TEXT(SP_NAME_DIGEST), + SECPKG_CRED_OUTBOUND, NULL, + p_identity, NULL, NULL, + &credentials, &expiry); + if(status != SEC_E_OK) { + Curl_sspi_free_identity(p_identity); + free(output_token); + + return CURLE_LOGIN_DENIED; + } + + /* Setup the challenge "input" security buffer if present */ + chlg_desc.ulVersion = SECBUFFER_VERSION; + chlg_desc.cBuffers = 3; + chlg_desc.pBuffers = chlg_buf; + chlg_buf[0].BufferType = SECBUFFER_TOKEN; + chlg_buf[0].pvBuffer = digest->input_token; + chlg_buf[0].cbBuffer = curlx_uztoul(digest->input_token_len); + chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS; + chlg_buf[1].pvBuffer = (void *) request; + chlg_buf[1].cbBuffer = curlx_uztoul(strlen((const char *) request)); + chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS; + chlg_buf[2].pvBuffer = NULL; + chlg_buf[2].cbBuffer = 0; + + /* Setup the response "output" security buffer */ + resp_desc.ulVersion = SECBUFFER_VERSION; + resp_desc.cBuffers = 1; + resp_desc.pBuffers = &resp_buf; + resp_buf.BufferType = SECBUFFER_TOKEN; + resp_buf.pvBuffer = output_token; + resp_buf.cbBuffer = curlx_uztoul(token_max); + + spn = Curl_convert_UTF8_to_tchar((char *) uripath); + if(!spn) { + s_pSecFn->FreeCredentialsHandle(&credentials); + + Curl_sspi_free_identity(p_identity); + free(output_token); + + return CURLE_OUT_OF_MEMORY; + } + + /* Allocate our new context handle */ + digest->http_context = calloc(1, sizeof(CtxtHandle)); + if(!digest->http_context) + return CURLE_OUT_OF_MEMORY; + + /* Generate our response message */ + status = s_pSecFn->InitializeSecurityContext(&credentials, NULL, + spn, + ISC_REQ_USE_HTTP_STYLE, 0, 0, + &chlg_desc, 0, + digest->http_context, + &resp_desc, &attrs, &expiry); + Curl_unicodefree(spn); + + if(status == SEC_I_COMPLETE_NEEDED || + status == SEC_I_COMPLETE_AND_CONTINUE) + s_pSecFn->CompleteAuthToken(&credentials, &resp_desc); + else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { + s_pSecFn->FreeCredentialsHandle(&credentials); + + Curl_sspi_free_identity(p_identity); + free(output_token); + + Curl_safefree(digest->http_context); + + return CURLE_OUT_OF_MEMORY; + } + + output_token_len = resp_buf.cbBuffer; + + s_pSecFn->FreeCredentialsHandle(&credentials); + Curl_sspi_free_identity(p_identity); + } + + resp = malloc(output_token_len + 1); + if(!resp) { + free(output_token); + + return CURLE_OUT_OF_MEMORY; + } + + /* Copy the generated response */ + memcpy(resp, output_token, output_token_len); + resp[output_token_len] = 0; + + /* Return the response */ + *outptr = resp; + *outlen = output_token_len; + + /* Free the response buffer */ + free(output_token); + + return CURLE_OK; +} + +/* + * Curl_auth_digest_cleanup() + * + * This is used to clean up the digest specific data. + * + * Parameters: + * + * digest [in/out] - The digest data struct being cleaned up. + * + */ +void Curl_auth_digest_cleanup(struct digestdata *digest) +{ + /* Free the input token */ + Curl_safefree(digest->input_token); + + /* Reset any variables */ + digest->input_token_len = 0; + + /* Delete security context */ + if(digest->http_context) { + s_pSecFn->DeleteSecurityContext(digest->http_context); + Curl_safefree(digest->http_context); + } + + /* Free the copy of user/passwd used to make the identity for http_context */ + Curl_safefree(digest->user); + Curl_safefree(digest->passwd); +} + +#endif /* USE_WINDOWS_SSPI && !CURL_DISABLE_CRYPTO_AUTH */ diff --git a/libcurl/lib/vauth/krb5_gssapi.c b/libcurl/lib/vauth/krb5_gssapi.c new file mode 100644 index 0000000..ea0a5f1 --- /dev/null +++ b/libcurl/lib/vauth/krb5_gssapi.c @@ -0,0 +1,401 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2014 - 2019, Steve Holme, . + * Copyright (C) 2015, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(HAVE_GSSAPI) && defined(USE_KERBEROS5) + +#include + +#include "vauth/vauth.h" +#include "curl_sasl.h" +#include "urldata.h" +#include "curl_base64.h" +#include "curl_gssapi.h" +#include "sendf.h" +#include "curl_printf.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Curl_auth_is_gssapi_supported() + * + * This is used to evaluate if GSSAPI (Kerberos V5) is supported. + * + * Parameters: None + * + * Returns TRUE if Kerberos V5 is supported by the GSS-API library. + */ +bool Curl_auth_is_gssapi_supported(void) +{ + return TRUE; +} + +/* + * Curl_auth_create_gssapi_user_message() + * + * This is used to generate an already encoded GSSAPI (Kerberos V5) user token + * message ready for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name. + * passwdp [in] - The user's password. + * service [in] - The service type such as http, smtp, pop or imap. + * host [in[ - The host name. + * mutual_auth [in] - Flag specifying whether or not mutual authentication + * is enabled. + * chlg64 [in] - Pointer to the optional base64 encoded challenge + * message. + * krb5 [in/out] - The Kerberos 5 data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, + const char *userp, + const char *passwdp, + const char *service, + const char *host, + const bool mutual_auth, + const char *chlg64, + struct kerberos5data *krb5, + char **outptr, size_t *outlen) +{ + CURLcode result = CURLE_OK; + size_t chlglen = 0; + unsigned char *chlg = NULL; + OM_uint32 major_status; + OM_uint32 minor_status; + OM_uint32 unused_status; + gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; + + (void) userp; + (void) passwdp; + + if(!krb5->spn) { + /* Generate our SPN */ + char *spn = Curl_auth_build_spn(service, NULL, host); + if(!spn) + return CURLE_OUT_OF_MEMORY; + + /* Populate the SPN structure */ + spn_token.value = spn; + spn_token.length = strlen(spn); + + /* Import the SPN */ + major_status = gss_import_name(&minor_status, &spn_token, + GSS_C_NT_HOSTBASED_SERVICE, &krb5->spn); + if(GSS_ERROR(major_status)) { + Curl_gss_log_error(data, "gss_import_name() failed: ", + major_status, minor_status); + + free(spn); + + return CURLE_OUT_OF_MEMORY; + } + + free(spn); + } + + if(chlg64 && *chlg64) { + /* Decode the base-64 encoded challenge message */ + if(*chlg64 != '=') { + result = Curl_base64_decode(chlg64, &chlg, &chlglen); + if(result) + return result; + } + + /* Ensure we have a valid challenge message */ + if(!chlg) { + infof(data, "GSSAPI handshake failure (empty challenge message)\n"); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Setup the challenge "input" security buffer */ + input_token.value = chlg; + input_token.length = chlglen; + } + + major_status = Curl_gss_init_sec_context(data, + &minor_status, + &krb5->context, + krb5->spn, + &Curl_krb5_mech_oid, + GSS_C_NO_CHANNEL_BINDINGS, + &input_token, + &output_token, + mutual_auth, + NULL); + + /* Free the decoded challenge as it is not required anymore */ + free(input_token.value); + + if(GSS_ERROR(major_status)) { + if(output_token.value) + gss_release_buffer(&unused_status, &output_token); + + Curl_gss_log_error(data, "gss_init_sec_context() failed: ", + major_status, minor_status); + + return CURLE_RECV_ERROR; + } + + if(output_token.value && output_token.length) { + /* Base64 encode the response */ + result = Curl_base64_encode(data, (char *) output_token.value, + output_token.length, outptr, outlen); + + gss_release_buffer(&unused_status, &output_token); + } + else if(mutual_auth) { + *outptr = strdup(""); + if(!*outptr) + result = CURLE_OUT_OF_MEMORY; + } + + return result; +} + +/* + * Curl_auth_create_gssapi_security_message() + * + * This is used to generate an already encoded GSSAPI (Kerberos V5) security + * token message ready for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * chlg64 [in] - Pointer to the optional base64 encoded challenge message. + * krb5 [in/out] - The Kerberos 5 data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, + const char *chlg64, + struct kerberos5data *krb5, + char **outptr, + size_t *outlen) +{ + CURLcode result = CURLE_OK; + size_t chlglen = 0; + size_t messagelen = 0; + unsigned char *chlg = NULL; + unsigned char *message = NULL; + OM_uint32 major_status; + OM_uint32 minor_status; + OM_uint32 unused_status; + gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; + unsigned int indata = 0; + unsigned int outdata = 0; + gss_qop_t qop = GSS_C_QOP_DEFAULT; + unsigned int sec_layer = 0; + unsigned int max_size = 0; + gss_name_t username = GSS_C_NO_NAME; + gss_buffer_desc username_token; + + /* Decode the base-64 encoded input message */ + if(strlen(chlg64) && *chlg64 != '=') { + result = Curl_base64_decode(chlg64, &chlg, &chlglen); + if(result) + return result; + } + + /* Ensure we have a valid challenge message */ + if(!chlg) { + infof(data, "GSSAPI handshake failure (empty security message)\n"); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Get the fully qualified username back from the context */ + major_status = gss_inquire_context(&minor_status, krb5->context, + &username, NULL, NULL, NULL, NULL, + NULL, NULL); + if(GSS_ERROR(major_status)) { + Curl_gss_log_error(data, "gss_inquire_context() failed: ", + major_status, minor_status); + + free(chlg); + + return CURLE_OUT_OF_MEMORY; + } + + /* Convert the username from internal format to a displayable token */ + major_status = gss_display_name(&minor_status, username, + &username_token, NULL); + if(GSS_ERROR(major_status)) { + Curl_gss_log_error(data, "gss_display_name() failed: ", + major_status, minor_status); + + free(chlg); + + return CURLE_OUT_OF_MEMORY; + } + + /* Setup the challenge "input" security buffer */ + input_token.value = chlg; + input_token.length = chlglen; + + /* Decrypt the inbound challenge and obtain the qop */ + major_status = gss_unwrap(&minor_status, krb5->context, &input_token, + &output_token, NULL, &qop); + if(GSS_ERROR(major_status)) { + Curl_gss_log_error(data, "gss_unwrap() failed: ", + major_status, minor_status); + + gss_release_buffer(&unused_status, &username_token); + free(chlg); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Not 4 octets long so fail as per RFC4752 Section 3.1 */ + if(output_token.length != 4) { + infof(data, "GSSAPI handshake failure (invalid security data)\n"); + + gss_release_buffer(&unused_status, &username_token); + free(chlg); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Copy the data out and free the challenge as it is not required anymore */ + memcpy(&indata, output_token.value, 4); + gss_release_buffer(&unused_status, &output_token); + free(chlg); + + /* Extract the security layer */ + sec_layer = indata & 0x000000FF; + if(!(sec_layer & GSSAUTH_P_NONE)) { + infof(data, "GSSAPI handshake failure (invalid security layer)\n"); + + gss_release_buffer(&unused_status, &username_token); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Extract the maximum message size the server can receive */ + max_size = ntohl(indata & 0xFFFFFF00); + if(max_size > 0) { + /* The server has told us it supports a maximum receive buffer, however, as + we don't require one unless we are encrypting data, we tell the server + our receive buffer is zero. */ + max_size = 0; + } + + /* Allocate our message */ + messagelen = sizeof(outdata) + username_token.length + 1; + message = malloc(messagelen); + if(!message) { + gss_release_buffer(&unused_status, &username_token); + + return CURLE_OUT_OF_MEMORY; + } + + /* Populate the message with the security layer, client supported receive + message size and authorization identity including the 0x00 based + terminator. Note: Despite RFC4752 Section 3.1 stating "The authorization + identity is not terminated with the zero-valued (%x00) octet." it seems + necessary to include it. */ + outdata = htonl(max_size) | sec_layer; + memcpy(message, &outdata, sizeof(outdata)); + memcpy(message + sizeof(outdata), username_token.value, + username_token.length); + message[messagelen - 1] = '\0'; + + /* Free the username token as it is not required anymore */ + gss_release_buffer(&unused_status, &username_token); + + /* Setup the "authentication data" security buffer */ + input_token.value = message; + input_token.length = messagelen; + + /* Encrypt the data */ + major_status = gss_wrap(&minor_status, krb5->context, 0, + GSS_C_QOP_DEFAULT, &input_token, NULL, + &output_token); + if(GSS_ERROR(major_status)) { + Curl_gss_log_error(data, "gss_wrap() failed: ", + major_status, minor_status); + + free(message); + + return CURLE_OUT_OF_MEMORY; + } + + /* Base64 encode the response */ + result = Curl_base64_encode(data, (char *) output_token.value, + output_token.length, outptr, outlen); + + /* Free the output buffer */ + gss_release_buffer(&unused_status, &output_token); + + /* Free the message buffer */ + free(message); + + return result; +} + +/* + * Curl_auth_cleanup_gssapi() + * + * This is used to clean up the GSSAPI (Kerberos V5) specific data. + * + * Parameters: + * + * krb5 [in/out] - The Kerberos 5 data struct being cleaned up. + * + */ +void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5) +{ + OM_uint32 minor_status; + + /* Free our security context */ + if(krb5->context != GSS_C_NO_CONTEXT) { + gss_delete_sec_context(&minor_status, &krb5->context, GSS_C_NO_BUFFER); + krb5->context = GSS_C_NO_CONTEXT; + } + + /* Free the SPN */ + if(krb5->spn != GSS_C_NO_NAME) { + gss_release_name(&minor_status, &krb5->spn); + krb5->spn = GSS_C_NO_NAME; + } +} + +#endif /* HAVE_GSSAPI && USE_KERBEROS5 */ diff --git a/libcurl/lib/vauth/krb5_sspi.c b/libcurl/lib/vauth/krb5_sspi.c new file mode 100644 index 0000000..1f6e462 --- /dev/null +++ b/libcurl/lib/vauth/krb5_sspi.c @@ -0,0 +1,514 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2014 - 2019, Steve Holme, . + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_WINDOWS_SSPI) && defined(USE_KERBEROS5) + +#include + +#include "vauth/vauth.h" +#include "urldata.h" +#include "curl_base64.h" +#include "warnless.h" +#include "curl_multibyte.h" +#include "sendf.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Curl_auth_is_gssapi_supported() + * + * This is used to evaluate if GSSAPI (Kerberos V5) is supported. + * + * Parameters: None + * + * Returns TRUE if Kerberos V5 is supported by Windows SSPI. + */ +bool Curl_auth_is_gssapi_supported(void) +{ + PSecPkgInfo SecurityPackage; + SECURITY_STATUS status; + + /* Query the security package for Kerberos */ + status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) + TEXT(SP_NAME_KERBEROS), + &SecurityPackage); + + return (status == SEC_E_OK ? TRUE : FALSE); +} + +/* + * Curl_auth_create_gssapi_user_message() + * + * This is used to generate an already encoded GSSAPI (Kerberos V5) user token + * message ready for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name in the format User or Domain\User. + * passwdp [in] - The user's password. + * service [in] - The service type such as http, smtp, pop or imap. + * host [in] - The host name. + * mutual_auth [in] - Flag specifying whether or not mutual authentication + * is enabled. + * chlg64 [in] - The optional base64 encoded challenge message. + * krb5 [in/out] - The Kerberos 5 data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, + const char *userp, + const char *passwdp, + const char *service, + const char *host, + const bool mutual_auth, + const char *chlg64, + struct kerberos5data *krb5, + char **outptr, size_t *outlen) +{ + CURLcode result = CURLE_OK; + size_t chlglen = 0; + unsigned char *chlg = NULL; + CtxtHandle context; + PSecPkgInfo SecurityPackage; + SecBuffer chlg_buf; + SecBuffer resp_buf; + SecBufferDesc chlg_desc; + SecBufferDesc resp_desc; + SECURITY_STATUS status; + unsigned long attrs; + TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ + + if(!krb5->spn) { + /* Generate our SPN */ + krb5->spn = Curl_auth_build_spn(service, host, NULL); + if(!krb5->spn) + return CURLE_OUT_OF_MEMORY; + } + + if(!krb5->output_token) { + /* Query the security package for Kerberos */ + status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) + TEXT(SP_NAME_KERBEROS), + &SecurityPackage); + if(status != SEC_E_OK) { + return CURLE_NOT_BUILT_IN; + } + + krb5->token_max = SecurityPackage->cbMaxToken; + + /* Release the package buffer as it is not required anymore */ + s_pSecFn->FreeContextBuffer(SecurityPackage); + + /* Allocate our response buffer */ + krb5->output_token = malloc(krb5->token_max); + if(!krb5->output_token) + return CURLE_OUT_OF_MEMORY; + } + + if(!krb5->credentials) { + /* Do we have credentials to use or are we using single sign-on? */ + if(userp && *userp) { + /* Populate our identity structure */ + result = Curl_create_sspi_identity(userp, passwdp, &krb5->identity); + if(result) + return result; + + /* Allow proper cleanup of the identity structure */ + krb5->p_identity = &krb5->identity; + } + else + /* Use the current Windows user */ + krb5->p_identity = NULL; + + /* Allocate our credentials handle */ + krb5->credentials = calloc(1, sizeof(CredHandle)); + if(!krb5->credentials) + return CURLE_OUT_OF_MEMORY; + + /* Acquire our credentials handle */ + status = s_pSecFn->AcquireCredentialsHandle(NULL, + (TCHAR *) + TEXT(SP_NAME_KERBEROS), + SECPKG_CRED_OUTBOUND, NULL, + krb5->p_identity, NULL, NULL, + krb5->credentials, &expiry); + if(status != SEC_E_OK) + return CURLE_LOGIN_DENIED; + + /* Allocate our new context handle */ + krb5->context = calloc(1, sizeof(CtxtHandle)); + if(!krb5->context) + return CURLE_OUT_OF_MEMORY; + } + + if(chlg64 && *chlg64) { + /* Decode the base-64 encoded challenge message */ + if(*chlg64 != '=') { + result = Curl_base64_decode(chlg64, &chlg, &chlglen); + if(result) + return result; + } + + /* Ensure we have a valid challenge message */ + if(!chlg) { + infof(data, "GSSAPI handshake failure (empty challenge message)\n"); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Setup the challenge "input" security buffer */ + chlg_desc.ulVersion = SECBUFFER_VERSION; + chlg_desc.cBuffers = 1; + chlg_desc.pBuffers = &chlg_buf; + chlg_buf.BufferType = SECBUFFER_TOKEN; + chlg_buf.pvBuffer = chlg; + chlg_buf.cbBuffer = curlx_uztoul(chlglen); + } + + /* Setup the response "output" security buffer */ + resp_desc.ulVersion = SECBUFFER_VERSION; + resp_desc.cBuffers = 1; + resp_desc.pBuffers = &resp_buf; + resp_buf.BufferType = SECBUFFER_TOKEN; + resp_buf.pvBuffer = krb5->output_token; + resp_buf.cbBuffer = curlx_uztoul(krb5->token_max); + + /* Generate our challenge-response message */ + status = s_pSecFn->InitializeSecurityContext(krb5->credentials, + chlg ? krb5->context : NULL, + krb5->spn, + (mutual_auth ? + ISC_REQ_MUTUAL_AUTH : 0), + 0, SECURITY_NATIVE_DREP, + chlg ? &chlg_desc : NULL, 0, + &context, + &resp_desc, &attrs, + &expiry); + + /* Free the decoded challenge as it is not required anymore */ + free(chlg); + + if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { + return CURLE_RECV_ERROR; + } + + if(memcmp(&context, krb5->context, sizeof(context))) { + s_pSecFn->DeleteSecurityContext(krb5->context); + + memcpy(krb5->context, &context, sizeof(context)); + } + + if(resp_buf.cbBuffer) { + /* Base64 encode the response */ + result = Curl_base64_encode(data, (char *) resp_buf.pvBuffer, + resp_buf.cbBuffer, outptr, outlen); + } + else if(mutual_auth) { + *outptr = strdup(""); + if(!*outptr) + result = CURLE_OUT_OF_MEMORY; + } + + return result; +} + +/* + * Curl_auth_create_gssapi_security_message() + * + * This is used to generate an already encoded GSSAPI (Kerberos V5) security + * token message ready for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * chlg64 [in] - The optional base64 encoded challenge message. + * krb5 [in/out] - The Kerberos 5 data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, + const char *chlg64, + struct kerberos5data *krb5, + char **outptr, + size_t *outlen) +{ + CURLcode result = CURLE_OK; + size_t offset = 0; + size_t chlglen = 0; + size_t messagelen = 0; + size_t appdatalen = 0; + unsigned char *chlg = NULL; + unsigned char *trailer = NULL; + unsigned char *message = NULL; + unsigned char *padding = NULL; + unsigned char *appdata = NULL; + SecBuffer input_buf[2]; + SecBuffer wrap_buf[3]; + SecBufferDesc input_desc; + SecBufferDesc wrap_desc; + unsigned long indata = 0; + unsigned long outdata = 0; + unsigned long qop = 0; + unsigned long sec_layer = 0; + unsigned long max_size = 0; + SecPkgContext_Sizes sizes; + SecPkgCredentials_Names names; + SECURITY_STATUS status; + char *user_name; + + /* Decode the base-64 encoded input message */ + if(strlen(chlg64) && *chlg64 != '=') { + result = Curl_base64_decode(chlg64, &chlg, &chlglen); + if(result) + return result; + } + + /* Ensure we have a valid challenge message */ + if(!chlg) { + infof(data, "GSSAPI handshake failure (empty security message)\n"); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Get our response size information */ + status = s_pSecFn->QueryContextAttributes(krb5->context, + SECPKG_ATTR_SIZES, + &sizes); + if(status != SEC_E_OK) { + free(chlg); + + return CURLE_OUT_OF_MEMORY; + } + + /* Get the fully qualified username back from the context */ + status = s_pSecFn->QueryCredentialsAttributes(krb5->credentials, + SECPKG_CRED_ATTR_NAMES, + &names); + if(status != SEC_E_OK) { + free(chlg); + + return CURLE_RECV_ERROR; + } + + /* Setup the "input" security buffer */ + input_desc.ulVersion = SECBUFFER_VERSION; + input_desc.cBuffers = 2; + input_desc.pBuffers = input_buf; + input_buf[0].BufferType = SECBUFFER_STREAM; + input_buf[0].pvBuffer = chlg; + input_buf[0].cbBuffer = curlx_uztoul(chlglen); + input_buf[1].BufferType = SECBUFFER_DATA; + input_buf[1].pvBuffer = NULL; + input_buf[1].cbBuffer = 0; + + /* Decrypt the inbound challenge and obtain the qop */ + status = s_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop); + if(status != SEC_E_OK) { + infof(data, "GSSAPI handshake failure (empty security message)\n"); + + free(chlg); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Not 4 octets long so fail as per RFC4752 Section 3.1 */ + if(input_buf[1].cbBuffer != 4) { + infof(data, "GSSAPI handshake failure (invalid security data)\n"); + + free(chlg); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Copy the data out and free the challenge as it is not required anymore */ + memcpy(&indata, input_buf[1].pvBuffer, 4); + s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer); + free(chlg); + + /* Extract the security layer */ + sec_layer = indata & 0x000000FF; + if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) { + infof(data, "GSSAPI handshake failure (invalid security layer)\n"); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Extract the maximum message size the server can receive */ + max_size = ntohl(indata & 0xFFFFFF00); + if(max_size > 0) { + /* The server has told us it supports a maximum receive buffer, however, as + we don't require one unless we are encrypting data, we tell the server + our receive buffer is zero. */ + max_size = 0; + } + + /* Allocate the trailer */ + trailer = malloc(sizes.cbSecurityTrailer); + if(!trailer) + return CURLE_OUT_OF_MEMORY; + + /* Convert the user name to UTF8 when operating with Unicode */ + user_name = Curl_convert_tchar_to_UTF8(names.sUserName); + if(!user_name) { + free(trailer); + + return CURLE_OUT_OF_MEMORY; + } + + /* Allocate our message */ + messagelen = sizeof(outdata) + strlen(user_name) + 1; + message = malloc(messagelen); + if(!message) { + free(trailer); + Curl_unicodefree(user_name); + + return CURLE_OUT_OF_MEMORY; + } + + /* Populate the message with the security layer, client supported receive + message size and authorization identity including the 0x00 based + terminator. Note: Despite RFC4752 Section 3.1 stating "The authorization + identity is not terminated with the zero-valued (%x00) octet." it seems + necessary to include it. */ + outdata = htonl(max_size) | sec_layer; + memcpy(message, &outdata, sizeof(outdata)); + strcpy((char *) message + sizeof(outdata), user_name); + Curl_unicodefree(user_name); + + /* Allocate the padding */ + padding = malloc(sizes.cbBlockSize); + if(!padding) { + free(message); + free(trailer); + + return CURLE_OUT_OF_MEMORY; + } + + /* Setup the "authentication data" security buffer */ + wrap_desc.ulVersion = SECBUFFER_VERSION; + wrap_desc.cBuffers = 3; + wrap_desc.pBuffers = wrap_buf; + wrap_buf[0].BufferType = SECBUFFER_TOKEN; + wrap_buf[0].pvBuffer = trailer; + wrap_buf[0].cbBuffer = sizes.cbSecurityTrailer; + wrap_buf[1].BufferType = SECBUFFER_DATA; + wrap_buf[1].pvBuffer = message; + wrap_buf[1].cbBuffer = curlx_uztoul(messagelen); + wrap_buf[2].BufferType = SECBUFFER_PADDING; + wrap_buf[2].pvBuffer = padding; + wrap_buf[2].cbBuffer = sizes.cbBlockSize; + + /* Encrypt the data */ + status = s_pSecFn->EncryptMessage(krb5->context, KERB_WRAP_NO_ENCRYPT, + &wrap_desc, 0); + if(status != SEC_E_OK) { + free(padding); + free(message); + free(trailer); + + return CURLE_OUT_OF_MEMORY; + } + + /* Allocate the encryption (wrap) buffer */ + appdatalen = wrap_buf[0].cbBuffer + wrap_buf[1].cbBuffer + + wrap_buf[2].cbBuffer; + appdata = malloc(appdatalen); + if(!appdata) { + free(padding); + free(message); + free(trailer); + + return CURLE_OUT_OF_MEMORY; + } + + /* Populate the encryption buffer */ + memcpy(appdata, wrap_buf[0].pvBuffer, wrap_buf[0].cbBuffer); + offset += wrap_buf[0].cbBuffer; + memcpy(appdata + offset, wrap_buf[1].pvBuffer, wrap_buf[1].cbBuffer); + offset += wrap_buf[1].cbBuffer; + memcpy(appdata + offset, wrap_buf[2].pvBuffer, wrap_buf[2].cbBuffer); + + /* Base64 encode the response */ + result = Curl_base64_encode(data, (char *) appdata, appdatalen, outptr, + outlen); + + /* Free all of our local buffers */ + free(appdata); + free(padding); + free(message); + free(trailer); + + return result; +} + +/* + * Curl_auth_cleanup_gssapi() + * + * This is used to clean up the GSSAPI (Kerberos V5) specific data. + * + * Parameters: + * + * krb5 [in/out] - The Kerberos 5 data struct being cleaned up. + * + */ +void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5) +{ + /* Free our security context */ + if(krb5->context) { + s_pSecFn->DeleteSecurityContext(krb5->context); + free(krb5->context); + krb5->context = NULL; + } + + /* Free our credentials handle */ + if(krb5->credentials) { + s_pSecFn->FreeCredentialsHandle(krb5->credentials); + free(krb5->credentials); + krb5->credentials = NULL; + } + + /* Free our identity */ + Curl_sspi_free_identity(krb5->p_identity); + krb5->p_identity = NULL; + + /* Free the SPN and output token */ + Curl_safefree(krb5->spn); + Curl_safefree(krb5->output_token); + + /* Reset any variables */ + krb5->token_max = 0; +} + +#endif /* USE_WINDOWS_SSPI && USE_KERBEROS5*/ diff --git a/libcurl/lib/vauth/ntlm.c b/libcurl/lib/vauth/ntlm.c new file mode 100644 index 0000000..047c2b5 --- /dev/null +++ b/libcurl/lib/vauth/ntlm.c @@ -0,0 +1,871 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI) + +/* + * NTLM details: + * + * https://davenport.sourceforge.io/ntlm.html + * https://www.innovation.ch/java/ntlm.html + */ + +#define DEBUG_ME 0 + +#include "urldata.h" +#include "non-ascii.h" +#include "sendf.h" +#include "curl_base64.h" +#include "curl_ntlm_core.h" +#include "curl_gethostname.h" +#include "curl_multibyte.h" +#include "warnless.h" +#include "rand.h" +#include "vtls/vtls.h" + +/* SSL backend-specific #if branches in this file must be kept in the order + documented in curl_ntlm_core. */ +#if defined(NTLM_NEEDS_NSS_INIT) +#include "vtls/nssg.h" /* for Curl_nss_force_init() */ +#endif + +#define BUILDING_CURL_NTLM_MSGS_C +#include "vauth/vauth.h" +#include "vauth/ntlm.h" +#include "curl_endian.h" +#include "curl_printf.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* "NTLMSSP" signature is always in ASCII regardless of the platform */ +#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50" + +#define SHORTPAIR(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)) +#define LONGQUARTET(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)), \ + ((int)(((x) >> 16) & 0xff)), ((int)(((x) >> 24) & 0xff)) + +#if DEBUG_ME +# define DEBUG_OUT(x) x +static void ntlm_print_flags(FILE *handle, unsigned long flags) +{ + if(flags & NTLMFLAG_NEGOTIATE_UNICODE) + fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE "); + if(flags & NTLMFLAG_NEGOTIATE_OEM) + fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM "); + if(flags & NTLMFLAG_REQUEST_TARGET) + fprintf(handle, "NTLMFLAG_REQUEST_TARGET "); + if(flags & (1<<3)) + fprintf(handle, "NTLMFLAG_UNKNOWN_3 "); + if(flags & NTLMFLAG_NEGOTIATE_SIGN) + fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN "); + if(flags & NTLMFLAG_NEGOTIATE_SEAL) + fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL "); + if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE) + fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE "); + if(flags & NTLMFLAG_NEGOTIATE_LM_KEY) + fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY "); + if(flags & NTLMFLAG_NEGOTIATE_NETWARE) + fprintf(handle, "NTLMFLAG_NEGOTIATE_NETWARE "); + if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY) + fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY "); + if(flags & (1<<10)) + fprintf(handle, "NTLMFLAG_UNKNOWN_10 "); + if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS) + fprintf(handle, "NTLMFLAG_NEGOTIATE_ANONYMOUS "); + if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED) + fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED "); + if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED) + fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED "); + if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL) + fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL "); + if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN) + fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN "); + if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN) + fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN "); + if(flags & NTLMFLAG_TARGET_TYPE_SERVER) + fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER "); + if(flags & NTLMFLAG_TARGET_TYPE_SHARE) + fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE "); + if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) + fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY "); + if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE) + fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE "); + if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE) + fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE "); + if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY) + fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY "); + if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) + fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO "); + if(flags & (1<<24)) + fprintf(handle, "NTLMFLAG_UNKNOWN_24 "); + if(flags & (1<<25)) + fprintf(handle, "NTLMFLAG_UNKNOWN_25 "); + if(flags & (1<<26)) + fprintf(handle, "NTLMFLAG_UNKNOWN_26 "); + if(flags & (1<<27)) + fprintf(handle, "NTLMFLAG_UNKNOWN_27 "); + if(flags & (1<<28)) + fprintf(handle, "NTLMFLAG_UNKNOWN_28 "); + if(flags & NTLMFLAG_NEGOTIATE_128) + fprintf(handle, "NTLMFLAG_NEGOTIATE_128 "); + if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE) + fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE "); + if(flags & NTLMFLAG_NEGOTIATE_56) + fprintf(handle, "NTLMFLAG_NEGOTIATE_56 "); +} + +static void ntlm_print_hex(FILE *handle, const char *buf, size_t len) +{ + const char *p = buf; + + (void) handle; + + fprintf(stderr, "0x"); + while(len-- > 0) + fprintf(stderr, "%02.2x", (unsigned int)*p++); +} +#else +# define DEBUG_OUT(x) Curl_nop_stmt +#endif + +/* + * ntlm_decode_type2_target() + * + * This is used to decode the "target info" in the NTLM type-2 message + * received. + * + * Parameters: + * + * data [in] - The session handle. + * buffer [in] - The decoded type-2 message. + * size [in] - The input buffer size, at least 32 bytes. + * ntlm [in/out] - The NTLM data struct being used and modified. + * + * Returns CURLE_OK on success. + */ +static CURLcode ntlm_decode_type2_target(struct Curl_easy *data, + unsigned char *buffer, + size_t size, + struct ntlmdata *ntlm) +{ + unsigned short target_info_len = 0; + unsigned int target_info_offset = 0; + +#if defined(CURL_DISABLE_VERBOSE_STRINGS) + (void) data; +#endif + + if(size >= 48) { + target_info_len = Curl_read16_le(&buffer[40]); + target_info_offset = Curl_read32_le(&buffer[44]); + if(target_info_len > 0) { + if((target_info_offset >= size) || + ((target_info_offset + target_info_len) > size) || + (target_info_offset < 48)) { + infof(data, "NTLM handshake failure (bad type-2 message). " + "Target Info Offset Len is set incorrect by the peer\n"); + return CURLE_BAD_CONTENT_ENCODING; + } + + ntlm->target_info = malloc(target_info_len); + if(!ntlm->target_info) + return CURLE_OUT_OF_MEMORY; + + memcpy(ntlm->target_info, &buffer[target_info_offset], target_info_len); + } + } + + ntlm->target_info_len = target_info_len; + + return CURLE_OK; +} + +/* + NTLM message structure notes: + + A 'short' is a 'network short', a little-endian 16-bit unsigned value. + + A 'long' is a 'network long', a little-endian, 32-bit unsigned value. + + A 'security buffer' represents a triplet used to point to a buffer, + consisting of two shorts and one long: + + 1. A 'short' containing the length of the buffer content in bytes. + 2. A 'short' containing the allocated space for the buffer in bytes. + 3. A 'long' containing the offset to the start of the buffer in bytes, + from the beginning of the NTLM message. +*/ + +/* + * Curl_auth_is_ntlm_supported() + * + * This is used to evaluate if NTLM is supported. + * + * Parameters: None + * + * Returns TRUE as NTLM as handled by libcurl. + */ +bool Curl_auth_is_ntlm_supported(void) +{ + return TRUE; +} + +/* + * Curl_auth_decode_ntlm_type2_message() + * + * This is used to decode an already encoded NTLM type-2 message. The message + * is first decoded from a base64 string into a raw NTLM message and checked + * for validity before the appropriate data for creating a type-3 message is + * written to the given NTLM data structure. + * + * Parameters: + * + * data [in] - The session handle. + * type2msg [in] - The base64 encoded type-2 message. + * ntlm [in/out] - The NTLM data struct being used and modified. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, + const char *type2msg, + struct ntlmdata *ntlm) +{ + static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 }; + + /* NTLM type-2 message structure: + + Index Description Content + 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" + (0x4e544c4d53535000) + 8 NTLM Message Type long (0x02000000) + 12 Target Name security buffer + 20 Flags long + 24 Challenge 8 bytes + (32) Context 8 bytes (two consecutive longs) (*) + (40) Target Information security buffer (*) + (48) OS Version Structure 8 bytes (*) + 32 (48) (56) Start of data block (*) + (*) -> Optional + */ + + CURLcode result = CURLE_OK; + unsigned char *type2 = NULL; + size_t type2_len = 0; + +#if defined(NTLM_NEEDS_NSS_INIT) + /* Make sure the crypto backend is initialized */ + result = Curl_nss_force_init(data); + if(result) + return result; +#elif defined(CURL_DISABLE_VERBOSE_STRINGS) + (void)data; +#endif + + /* Decode the base-64 encoded type-2 message */ + if(strlen(type2msg) && *type2msg != '=') { + result = Curl_base64_decode(type2msg, &type2, &type2_len); + if(result) + return result; + } + + /* Ensure we have a valid type-2 message */ + if(!type2) { + infof(data, "NTLM handshake failure (empty type-2 message)\n"); + return CURLE_BAD_CONTENT_ENCODING; + } + + ntlm->flags = 0; + + if((type2_len < 32) || + (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) || + (memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) { + /* This was not a good enough type-2 message */ + free(type2); + infof(data, "NTLM handshake failure (bad type-2 message)\n"); + return CURLE_BAD_CONTENT_ENCODING; + } + + ntlm->flags = Curl_read32_le(&type2[20]); + memcpy(ntlm->nonce, &type2[24], 8); + + if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) { + result = ntlm_decode_type2_target(data, type2, type2_len, ntlm); + if(result) { + free(type2); + infof(data, "NTLM handshake failure (bad type-2 message)\n"); + return result; + } + } + + DEBUG_OUT({ + fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags); + ntlm_print_flags(stderr, ntlm->flags); + fprintf(stderr, "\n nonce="); + ntlm_print_hex(stderr, (char *)ntlm->nonce, 8); + fprintf(stderr, "\n****\n"); + fprintf(stderr, "**** Header %s\n ", header); + }); + + free(type2); + + return result; +} + +/* copy the source to the destination and fill in zeroes in every + other destination byte! */ +static void unicodecpy(unsigned char *dest, const char *src, size_t length) +{ + size_t i; + for(i = 0; i < length; i++) { + dest[2 * i] = (unsigned char)src[i]; + dest[2 * i + 1] = '\0'; + } +} + +/* + * Curl_auth_create_ntlm_type1_message() + * + * This is used to generate an already encoded NTLM type-1 message ready for + * sending to the recipient using the appropriate compile time crypto API. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name in the format User or Domain\User. + * passwdp [in] - The user's password. + * service [in] - The service type such as http, smtp, pop or imap. + * host [in] - The host name. + * ntlm [in/out] - The NTLM data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, + const char *userp, + const char *passwdp, + const char *service, + const char *hostname, + struct ntlmdata *ntlm, + char **outptr, size_t *outlen) +{ + /* NTLM type-1 message structure: + + Index Description Content + 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" + (0x4e544c4d53535000) + 8 NTLM Message Type long (0x01000000) + 12 Flags long + (16) Supplied Domain security buffer (*) + (24) Supplied Workstation security buffer (*) + (32) OS Version Structure 8 bytes (*) + (32) (40) Start of data block (*) + (*) -> Optional + */ + + size_t size; + + unsigned char ntlmbuf[NTLM_BUFSIZE]; + const char *host = ""; /* empty */ + const char *domain = ""; /* empty */ + size_t hostlen = 0; + size_t domlen = 0; + size_t hostoff = 0; + size_t domoff = hostoff + hostlen; /* This is 0: remember that host and + domain are empty */ + (void)userp; + (void)passwdp; + (void)service, + (void)hostname, + + /* Clean up any former leftovers and initialise to defaults */ + Curl_auth_cleanup_ntlm(ntlm); + +#if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION) +#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY +#else +#define NTLM2FLAG 0 +#endif + msnprintf((char *)ntlmbuf, NTLM_BUFSIZE, + NTLMSSP_SIGNATURE "%c" + "\x01%c%c%c" /* 32-bit type = 1 */ + "%c%c%c%c" /* 32-bit NTLM flag field */ + "%c%c" /* domain length */ + "%c%c" /* domain allocated space */ + "%c%c" /* domain name offset */ + "%c%c" /* 2 zeroes */ + "%c%c" /* host length */ + "%c%c" /* host allocated space */ + "%c%c" /* host name offset */ + "%c%c" /* 2 zeroes */ + "%s" /* host name */ + "%s", /* domain string */ + 0, /* trailing zero */ + 0, 0, 0, /* part of type-1 long */ + + LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), + SHORTPAIR(domlen), + SHORTPAIR(domlen), + SHORTPAIR(domoff), + 0, 0, + SHORTPAIR(hostlen), + SHORTPAIR(hostlen), + SHORTPAIR(hostoff), + 0, 0, + host, /* this is empty */ + domain /* this is empty */); + + /* Initial packet length */ + size = 32 + hostlen + domlen; + + DEBUG_OUT({ + fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x " + "0x%08.8x ", + LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), + NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); + ntlm_print_flags(stderr, + NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); + fprintf(stderr, "\n****\n"); + }); + + /* Return with binary blob encoded into base64 */ + return Curl_base64_encode(data, (char *)ntlmbuf, size, outptr, outlen); +} + +/* + * Curl_auth_create_ntlm_type3_message() + * + * This is used to generate an already encoded NTLM type-3 message ready for + * sending to the recipient using the appropriate compile time crypto API. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name in the format User or Domain\User. + * passwdp [in] - The user's password. + * ntlm [in/out] - The NTLM data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, + const char *userp, + const char *passwdp, + struct ntlmdata *ntlm, + char **outptr, size_t *outlen) + +{ + /* NTLM type-3 message structure: + + Index Description Content + 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" + (0x4e544c4d53535000) + 8 NTLM Message Type long (0x03000000) + 12 LM/LMv2 Response security buffer + 20 NTLM/NTLMv2 Response security buffer + 28 Target Name security buffer + 36 User Name security buffer + 44 Workstation Name security buffer + (52) Session Key security buffer (*) + (60) Flags long (*) + (64) OS Version Structure 8 bytes (*) + 52 (64) (72) Start of data block + (*) -> Optional + */ + + CURLcode result = CURLE_OK; + size_t size; + unsigned char ntlmbuf[NTLM_BUFSIZE]; + int lmrespoff; + unsigned char lmresp[24]; /* fixed-size */ +#ifdef USE_NTRESPONSES + int ntrespoff; + unsigned int ntresplen = 24; + unsigned char ntresp[24]; /* fixed-size */ + unsigned char *ptr_ntresp = &ntresp[0]; + unsigned char *ntlmv2resp = NULL; +#endif + bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE) ? TRUE : FALSE; + char host[HOSTNAME_MAX + 1] = ""; + const char *user; + const char *domain = ""; + size_t hostoff = 0; + size_t useroff = 0; + size_t domoff = 0; + size_t hostlen = 0; + size_t userlen = 0; + size_t domlen = 0; + + user = strchr(userp, '\\'); + if(!user) + user = strchr(userp, '/'); + + if(user) { + domain = userp; + domlen = (user - domain); + user++; + } + else + user = userp; + + userlen = strlen(user); + + /* Get the machine's un-qualified host name as NTLM doesn't like the fully + qualified domain name */ + if(Curl_gethostname(host, sizeof(host))) { + infof(data, "gethostname() failed, continuing without!\n"); + hostlen = 0; + } + else { + hostlen = strlen(host); + } + +#if defined(USE_NTRESPONSES) && defined(USE_NTLM_V2) + if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) { + unsigned char ntbuffer[0x18]; + unsigned char entropy[8]; + unsigned char ntlmv2hash[0x18]; + + result = Curl_rand(data, entropy, 8); + if(result) + return result; + + result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer); + if(result) + return result; + + result = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen, + ntbuffer, ntlmv2hash); + if(result) + return result; + + /* LMv2 response */ + result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash, entropy, + &ntlm->nonce[0], lmresp); + if(result) + return result; + + /* NTLMv2 response */ + result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash, entropy, + ntlm, &ntlmv2resp, &ntresplen); + if(result) + return result; + + ptr_ntresp = ntlmv2resp; + } + else +#endif + +#if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION) + /* We don't support NTLM2 if we don't have USE_NTRESPONSES */ + if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM_KEY) { + unsigned char ntbuffer[0x18]; + unsigned char tmp[0x18]; + unsigned char md5sum[MD5_DIGEST_LENGTH]; + unsigned char entropy[8]; + + /* Need to create 8 bytes random data */ + result = Curl_rand(data, entropy, 8); + if(result) + return result; + + /* 8 bytes random data as challenge in lmresp */ + memcpy(lmresp, entropy, 8); + + /* Pad with zeros */ + memset(lmresp + 8, 0, 0x10); + + /* Fill tmp with challenge(nonce?) + entropy */ + memcpy(tmp, &ntlm->nonce[0], 8); + memcpy(tmp + 8, entropy, 8); + + result = Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH); + if(!result) + /* We shall only use the first 8 bytes of md5sum, but the des code in + Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */ + result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer); + if(result) + return result; + + Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp); + + /* End of NTLM2 Session code */ + /* NTLM v2 session security is a misnomer because it is not NTLM v2. + It is NTLM v1 using the extended session security that is also + in NTLM v2 */ + } + else +#endif + { + +#ifdef USE_NTRESPONSES + unsigned char ntbuffer[0x18]; +#endif + unsigned char lmbuffer[0x18]; + +#ifdef USE_NTRESPONSES + result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer); + if(result) + return result; + + Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp); +#endif + + result = Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer); + if(result) + return result; + + Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp); + + /* A safer but less compatible alternative is: + * Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp); + * See https://davenport.sourceforge.io/ntlm.html#ntlmVersion2 */ + } + + if(unicode) { + domlen = domlen * 2; + userlen = userlen * 2; + hostlen = hostlen * 2; + } + + lmrespoff = 64; /* size of the message header */ +#ifdef USE_NTRESPONSES + ntrespoff = lmrespoff + 0x18; + domoff = ntrespoff + ntresplen; +#else + domoff = lmrespoff + 0x18; +#endif + useroff = domoff + domlen; + hostoff = useroff + userlen; + + /* Create the big type-3 message binary blob */ + size = msnprintf((char *)ntlmbuf, NTLM_BUFSIZE, + NTLMSSP_SIGNATURE "%c" + "\x03%c%c%c" /* 32-bit type = 3 */ + + "%c%c" /* LanManager length */ + "%c%c" /* LanManager allocated space */ + "%c%c" /* LanManager offset */ + "%c%c" /* 2 zeroes */ + + "%c%c" /* NT-response length */ + "%c%c" /* NT-response allocated space */ + "%c%c" /* NT-response offset */ + "%c%c" /* 2 zeroes */ + + "%c%c" /* domain length */ + "%c%c" /* domain allocated space */ + "%c%c" /* domain name offset */ + "%c%c" /* 2 zeroes */ + + "%c%c" /* user length */ + "%c%c" /* user allocated space */ + "%c%c" /* user offset */ + "%c%c" /* 2 zeroes */ + + "%c%c" /* host length */ + "%c%c" /* host allocated space */ + "%c%c" /* host offset */ + "%c%c" /* 2 zeroes */ + + "%c%c" /* session key length (unknown purpose) */ + "%c%c" /* session key allocated space (unknown purpose) */ + "%c%c" /* session key offset (unknown purpose) */ + "%c%c" /* 2 zeroes */ + + "%c%c%c%c", /* flags */ + + /* domain string */ + /* user string */ + /* host string */ + /* LanManager response */ + /* NT response */ + + 0, /* zero termination */ + 0, 0, 0, /* type-3 long, the 24 upper bits */ + + SHORTPAIR(0x18), /* LanManager response length, twice */ + SHORTPAIR(0x18), + SHORTPAIR(lmrespoff), + 0x0, 0x0, + +#ifdef USE_NTRESPONSES + SHORTPAIR(ntresplen), /* NT-response length, twice */ + SHORTPAIR(ntresplen), + SHORTPAIR(ntrespoff), + 0x0, 0x0, +#else + 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, +#endif + SHORTPAIR(domlen), + SHORTPAIR(domlen), + SHORTPAIR(domoff), + 0x0, 0x0, + + SHORTPAIR(userlen), + SHORTPAIR(userlen), + SHORTPAIR(useroff), + 0x0, 0x0, + + SHORTPAIR(hostlen), + SHORTPAIR(hostlen), + SHORTPAIR(hostoff), + 0x0, 0x0, + + 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, + + LONGQUARTET(ntlm->flags)); + + DEBUGASSERT(size == 64); + DEBUGASSERT(size == (size_t)lmrespoff); + + /* We append the binary hashes */ + if(size < (NTLM_BUFSIZE - 0x18)) { + memcpy(&ntlmbuf[size], lmresp, 0x18); + size += 0x18; + } + + DEBUG_OUT({ + fprintf(stderr, "**** TYPE3 header lmresp="); + ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18); + }); + +#ifdef USE_NTRESPONSES + /* ntresplen + size should not be risking an integer overflow here */ + if(ntresplen + size > sizeof(ntlmbuf)) { + failf(data, "incoming NTLM message too big"); + return CURLE_OUT_OF_MEMORY; + } + DEBUGASSERT(size == (size_t)ntrespoff); + memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen); + size += ntresplen; + + DEBUG_OUT({ + fprintf(stderr, "\n ntresp="); + ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], ntresplen); + }); + + free(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */ + +#endif + + DEBUG_OUT({ + fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ", + LONGQUARTET(ntlm->flags), ntlm->flags); + ntlm_print_flags(stderr, ntlm->flags); + fprintf(stderr, "\n****\n"); + }); + + /* Make sure that the domain, user and host strings fit in the + buffer before we copy them there. */ + if(size + userlen + domlen + hostlen >= NTLM_BUFSIZE) { + failf(data, "user + domain + host name too big"); + return CURLE_OUT_OF_MEMORY; + } + + DEBUGASSERT(size == domoff); + if(unicode) + unicodecpy(&ntlmbuf[size], domain, domlen / 2); + else + memcpy(&ntlmbuf[size], domain, domlen); + + size += domlen; + + DEBUGASSERT(size == useroff); + if(unicode) + unicodecpy(&ntlmbuf[size], user, userlen / 2); + else + memcpy(&ntlmbuf[size], user, userlen); + + size += userlen; + + DEBUGASSERT(size == hostoff); + if(unicode) + unicodecpy(&ntlmbuf[size], host, hostlen / 2); + else + memcpy(&ntlmbuf[size], host, hostlen); + + size += hostlen; + + /* Convert domain, user, and host to ASCII but leave the rest as-is */ + result = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff], + size - domoff); + if(result) + return CURLE_CONV_FAILED; + + /* Return with binary blob encoded into base64 */ + result = Curl_base64_encode(data, (char *)ntlmbuf, size, outptr, outlen); + + Curl_auth_cleanup_ntlm(ntlm); + + return result; +} + +/* + * Curl_auth_cleanup_ntlm() + * + * This is used to clean up the NTLM specific data. + * + * Parameters: + * + * ntlm [in/out] - The NTLM data struct being cleaned up. + * + */ +void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm) +{ + /* Free the target info */ + Curl_safefree(ntlm->target_info); + + /* Reset any variables */ + ntlm->target_info_len = 0; +} + +#endif /* USE_NTLM && !USE_WINDOWS_SSPI */ diff --git a/libcurl/lib/vauth/ntlm.h b/libcurl/lib/vauth/ntlm.h new file mode 100644 index 0000000..1136b0f --- /dev/null +++ b/libcurl/lib/vauth/ntlm.h @@ -0,0 +1,143 @@ +#ifndef HEADER_VAUTH_NTLM_H +#define HEADER_VAUTH_NTLM_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_NTLM + +/* NTLM buffer fixed size, large enough for long user + host + domain */ +#define NTLM_BUFSIZE 1024 + +/* Stuff only required for curl_ntlm_msgs.c */ +#ifdef BUILDING_CURL_NTLM_MSGS_C + +/* Flag bits definitions based on https://davenport.sourceforge.io/ntlm.html */ + +#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0) +/* Indicates that Unicode strings are supported for use in security buffer + data. */ + +#define NTLMFLAG_NEGOTIATE_OEM (1<<1) +/* Indicates that OEM strings are supported for use in security buffer data. */ + +#define NTLMFLAG_REQUEST_TARGET (1<<2) +/* Requests that the server's authentication realm be included in the Type 2 + message. */ + +/* unknown (1<<3) */ +#define NTLMFLAG_NEGOTIATE_SIGN (1<<4) +/* Specifies that authenticated communication between the client and server + should carry a digital signature (message integrity). */ + +#define NTLMFLAG_NEGOTIATE_SEAL (1<<5) +/* Specifies that authenticated communication between the client and server + should be encrypted (message confidentiality). */ + +#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE (1<<6) +/* Indicates that datagram authentication is being used. */ + +#define NTLMFLAG_NEGOTIATE_LM_KEY (1<<7) +/* Indicates that the LAN Manager session key should be used for signing and + sealing authenticated communications. */ + +#define NTLMFLAG_NEGOTIATE_NETWARE (1<<8) +/* unknown purpose */ + +#define NTLMFLAG_NEGOTIATE_NTLM_KEY (1<<9) +/* Indicates that NTLM authentication is being used. */ + +/* unknown (1<<10) */ + +#define NTLMFLAG_NEGOTIATE_ANONYMOUS (1<<11) +/* Sent by the client in the Type 3 message to indicate that an anonymous + context has been established. This also affects the response fields. */ + +#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED (1<<12) +/* Sent by the client in the Type 1 message to indicate that a desired + authentication realm is included in the message. */ + +#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED (1<<13) +/* Sent by the client in the Type 1 message to indicate that the client + workstation's name is included in the message. */ + +#define NTLMFLAG_NEGOTIATE_LOCAL_CALL (1<<14) +/* Sent by the server to indicate that the server and client are on the same + machine. Implies that the client may use a pre-established local security + context rather than responding to the challenge. */ + +#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN (1<<15) +/* Indicates that authenticated communication between the client and server + should be signed with a "dummy" signature. */ + +#define NTLMFLAG_TARGET_TYPE_DOMAIN (1<<16) +/* Sent by the server in the Type 2 message to indicate that the target + authentication realm is a domain. */ + +#define NTLMFLAG_TARGET_TYPE_SERVER (1<<17) +/* Sent by the server in the Type 2 message to indicate that the target + authentication realm is a server. */ + +#define NTLMFLAG_TARGET_TYPE_SHARE (1<<18) +/* Sent by the server in the Type 2 message to indicate that the target + authentication realm is a share. Presumably, this is for share-level + authentication. Usage is unclear. */ + +#define NTLMFLAG_NEGOTIATE_NTLM2_KEY (1<<19) +/* Indicates that the NTLM2 signing and sealing scheme should be used for + protecting authenticated communications. */ + +#define NTLMFLAG_REQUEST_INIT_RESPONSE (1<<20) +/* unknown purpose */ + +#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE (1<<21) +/* unknown purpose */ + +#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY (1<<22) +/* unknown purpose */ + +#define NTLMFLAG_NEGOTIATE_TARGET_INFO (1<<23) +/* Sent by the server in the Type 2 message to indicate that it is including a + Target Information block in the message. */ + +/* unknown (1<24) */ +/* unknown (1<25) */ +/* unknown (1<26) */ +/* unknown (1<27) */ +/* unknown (1<28) */ + +#define NTLMFLAG_NEGOTIATE_128 (1<<29) +/* Indicates that 128-bit encryption is supported. */ + +#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE (1<<30) +/* Indicates that the client will provide an encrypted master key in + the "Session Key" field of the Type 3 message. */ + +#define NTLMFLAG_NEGOTIATE_56 (1<<31) +/* Indicates that 56-bit encryption is supported. */ + +#endif /* BUILDING_CURL_NTLM_MSGS_C */ + +#endif /* USE_NTLM */ + +#endif /* HEADER_VAUTH_NTLM_H */ diff --git a/libcurl/lib/vauth/ntlm_sspi.c b/libcurl/lib/vauth/ntlm_sspi.c new file mode 100644 index 0000000..589cca1 --- /dev/null +++ b/libcurl/lib/vauth/ntlm_sspi.c @@ -0,0 +1,371 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_WINDOWS_SSPI) && defined(USE_NTLM) + +#include + +#include "vauth/vauth.h" +#include "urldata.h" +#include "curl_base64.h" +#include "curl_ntlm_core.h" +#include "warnless.h" +#include "curl_multibyte.h" +#include "sendf.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Curl_auth_is_ntlm_supported() + * + * This is used to evaluate if NTLM is supported. + * + * Parameters: None + * + * Returns TRUE if NTLM is supported by Windows SSPI. + */ +bool Curl_auth_is_ntlm_supported(void) +{ + PSecPkgInfo SecurityPackage; + SECURITY_STATUS status; + + /* Query the security package for NTLM */ + status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM), + &SecurityPackage); + + return (status == SEC_E_OK ? TRUE : FALSE); +} + +/* + * Curl_auth_create_ntlm_type1_message() + * + * This is used to generate an already encoded NTLM type-1 message ready for + * sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name in the format User or Domain\User. + * passwdp [in] - The user's password. + * service [in] - The service type such as http, smtp, pop or imap. + * host [in] - The host name. + * ntlm [in/out] - The NTLM data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, + const char *userp, + const char *passwdp, + const char *service, + const char *host, + struct ntlmdata *ntlm, + char **outptr, size_t *outlen) +{ + PSecPkgInfo SecurityPackage; + SecBuffer type_1_buf; + SecBufferDesc type_1_desc; + SECURITY_STATUS status; + unsigned long attrs; + TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ + + /* Clean up any former leftovers and initialise to defaults */ + Curl_auth_cleanup_ntlm(ntlm); + + /* Query the security package for NTLM */ + status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM), + &SecurityPackage); + if(status != SEC_E_OK) + return CURLE_NOT_BUILT_IN; + + ntlm->token_max = SecurityPackage->cbMaxToken; + + /* Release the package buffer as it is not required anymore */ + s_pSecFn->FreeContextBuffer(SecurityPackage); + + /* Allocate our output buffer */ + ntlm->output_token = malloc(ntlm->token_max); + if(!ntlm->output_token) + return CURLE_OUT_OF_MEMORY; + + if(userp && *userp) { + CURLcode result; + + /* Populate our identity structure */ + result = Curl_create_sspi_identity(userp, passwdp, &ntlm->identity); + if(result) + return result; + + /* Allow proper cleanup of the identity structure */ + ntlm->p_identity = &ntlm->identity; + } + else + /* Use the current Windows user */ + ntlm->p_identity = NULL; + + /* Allocate our credentials handle */ + ntlm->credentials = calloc(1, sizeof(CredHandle)); + if(!ntlm->credentials) + return CURLE_OUT_OF_MEMORY; + + /* Acquire our credentials handle */ + status = s_pSecFn->AcquireCredentialsHandle(NULL, + (TCHAR *) TEXT(SP_NAME_NTLM), + SECPKG_CRED_OUTBOUND, NULL, + ntlm->p_identity, NULL, NULL, + ntlm->credentials, &expiry); + if(status != SEC_E_OK) + return CURLE_LOGIN_DENIED; + + /* Allocate our new context handle */ + ntlm->context = calloc(1, sizeof(CtxtHandle)); + if(!ntlm->context) + return CURLE_OUT_OF_MEMORY; + + ntlm->spn = Curl_auth_build_spn(service, host, NULL); + if(!ntlm->spn) + return CURLE_OUT_OF_MEMORY; + + /* Setup the type-1 "output" security buffer */ + type_1_desc.ulVersion = SECBUFFER_VERSION; + type_1_desc.cBuffers = 1; + type_1_desc.pBuffers = &type_1_buf; + type_1_buf.BufferType = SECBUFFER_TOKEN; + type_1_buf.pvBuffer = ntlm->output_token; + type_1_buf.cbBuffer = curlx_uztoul(ntlm->token_max); + + /* Generate our type-1 message */ + status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, NULL, + ntlm->spn, + 0, 0, SECURITY_NETWORK_DREP, + NULL, 0, + ntlm->context, &type_1_desc, + &attrs, &expiry); + if(status == SEC_I_COMPLETE_NEEDED || + status == SEC_I_COMPLETE_AND_CONTINUE) + s_pSecFn->CompleteAuthToken(ntlm->context, &type_1_desc); + else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) + return CURLE_RECV_ERROR; + + /* Base64 encode the response */ + return Curl_base64_encode(data, (char *) ntlm->output_token, + type_1_buf.cbBuffer, outptr, outlen); +} + +/* + * Curl_auth_decode_ntlm_type2_message() + * + * This is used to decode an already encoded NTLM type-2 message. + * + * Parameters: + * + * data [in] - The session handle. + * type2msg [in] - The base64 encoded type-2 message. + * ntlm [in/out] - The NTLM data struct being used and modified. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, + const char *type2msg, + struct ntlmdata *ntlm) +{ + CURLcode result = CURLE_OK; + unsigned char *type2 = NULL; + size_t type2_len = 0; + +#if defined(CURL_DISABLE_VERBOSE_STRINGS) + (void) data; +#endif + + /* Decode the base-64 encoded type-2 message */ + if(strlen(type2msg) && *type2msg != '=') { + result = Curl_base64_decode(type2msg, &type2, &type2_len); + if(result) + return result; + } + + /* Ensure we have a valid type-2 message */ + if(!type2) { + infof(data, "NTLM handshake failure (empty type-2 message)\n"); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Simply store the challenge for use later */ + ntlm->input_token = type2; + ntlm->input_token_len = type2_len; + + return result; +} + +/* +* Curl_auth_create_ntlm_type3_message() + * Curl_auth_create_ntlm_type3_message() + * + * This is used to generate an already encoded NTLM type-3 message ready for + * sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name in the format User or Domain\User. + * passwdp [in] - The user's password. + * ntlm [in/out] - The NTLM data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, + const char *userp, + const char *passwdp, + struct ntlmdata *ntlm, + char **outptr, size_t *outlen) +{ + CURLcode result = CURLE_OK; + SecBuffer type_2_bufs[2]; + SecBuffer type_3_buf; + SecBufferDesc type_2_desc; + SecBufferDesc type_3_desc; + SECURITY_STATUS status; + unsigned long attrs; + TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ + + (void) passwdp; + (void) userp; + + /* Setup the type-2 "input" security buffer */ + type_2_desc.ulVersion = SECBUFFER_VERSION; + type_2_desc.cBuffers = 1; + type_2_desc.pBuffers = &type_2_bufs[0]; + type_2_bufs[0].BufferType = SECBUFFER_TOKEN; + type_2_bufs[0].pvBuffer = ntlm->input_token; + type_2_bufs[0].cbBuffer = curlx_uztoul(ntlm->input_token_len); + +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + /* ssl context comes from schannel. + * When extended protection is used in IIS server, + * we have to pass a second SecBuffer to the SecBufferDesc + * otherwise IIS will not pass the authentication (401 response). + * Minimum supported version is Windows 7. + * https://docs.microsoft.com/en-us/security-updates + * /SecurityAdvisories/2009/973811 + */ + if(ntlm->sslContext) { + SEC_CHANNEL_BINDINGS channelBindings; + SecPkgContext_Bindings pkgBindings; + pkgBindings.Bindings = &channelBindings; + status = s_pSecFn->QueryContextAttributes( + ntlm->sslContext, + SECPKG_ATTR_ENDPOINT_BINDINGS, + &pkgBindings + ); + if(status == SEC_E_OK) { + type_2_desc.cBuffers++; + type_2_bufs[1].BufferType = SECBUFFER_CHANNEL_BINDINGS; + type_2_bufs[1].cbBuffer = pkgBindings.BindingsLength; + type_2_bufs[1].pvBuffer = pkgBindings.Bindings; + } + } +#endif + + /* Setup the type-3 "output" security buffer */ + type_3_desc.ulVersion = SECBUFFER_VERSION; + type_3_desc.cBuffers = 1; + type_3_desc.pBuffers = &type_3_buf; + type_3_buf.BufferType = SECBUFFER_TOKEN; + type_3_buf.pvBuffer = ntlm->output_token; + type_3_buf.cbBuffer = curlx_uztoul(ntlm->token_max); + + /* Generate our type-3 message */ + status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, + ntlm->context, + ntlm->spn, + 0, 0, SECURITY_NETWORK_DREP, + &type_2_desc, + 0, ntlm->context, + &type_3_desc, + &attrs, &expiry); + if(status != SEC_E_OK) { + infof(data, "NTLM handshake failure (type-3 message): Status=%x\n", + status); + + return CURLE_RECV_ERROR; + } + + /* Base64 encode the response */ + result = Curl_base64_encode(data, (char *) ntlm->output_token, + type_3_buf.cbBuffer, outptr, outlen); + + Curl_auth_cleanup_ntlm(ntlm); + + return result; +} + +/* + * Curl_auth_cleanup_ntlm() + * + * This is used to clean up the NTLM specific data. + * + * Parameters: + * + * ntlm [in/out] - The NTLM data struct being cleaned up. + * + */ +void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm) +{ + /* Free our security context */ + if(ntlm->context) { + s_pSecFn->DeleteSecurityContext(ntlm->context); + free(ntlm->context); + ntlm->context = NULL; + } + + /* Free our credentials handle */ + if(ntlm->credentials) { + s_pSecFn->FreeCredentialsHandle(ntlm->credentials); + free(ntlm->credentials); + ntlm->credentials = NULL; + } + + /* Free our identity */ + Curl_sspi_free_identity(ntlm->p_identity); + ntlm->p_identity = NULL; + + /* Free the input and output tokens */ + Curl_safefree(ntlm->input_token); + Curl_safefree(ntlm->output_token); + + /* Reset any variables */ + ntlm->token_max = 0; + + Curl_safefree(ntlm->spn); +} + +#endif /* USE_WINDOWS_SSPI && USE_NTLM */ diff --git a/libcurl/lib/vauth/oauth2.c b/libcurl/lib/vauth/oauth2.c new file mode 100644 index 0000000..b4e9f8e --- /dev/null +++ b/libcurl/lib/vauth/oauth2.c @@ -0,0 +1,126 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC6749 OAuth 2.0 Authorization Framework + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \ + !defined(CURL_DISABLE_POP3) + +#include +#include "urldata.h" + +#include "vauth/vauth.h" +#include "curl_base64.h" +#include "warnless.h" +#include "curl_printf.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Curl_auth_create_oauth_bearer_message() + * + * This is used to generate an already encoded OAuth 2.0 message ready for + * sending to the recipient. + * + * Parameters: + * + * data[in] - The session handle. + * user[in] - The user name. + * host[in] - The host name. + * port[in] - The port(when not Port 80). + * bearer[in] - The bearer token. + * outptr[in / out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen[out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data, + const char *user, + const char *host, + const long port, + const char *bearer, + char **outptr, size_t *outlen) +{ + CURLcode result = CURLE_OK; + char *oauth = NULL; + + /* Generate the message */ + if(port == 0 || port == 80) + oauth = aprintf("n,a=%s,\1host=%s\1auth=Bearer %s\1\1", user, host, + bearer); + else + oauth = aprintf("n,a=%s,\1host=%s\1port=%ld\1auth=Bearer %s\1\1", user, + host, port, bearer); + if(!oauth) + return CURLE_OUT_OF_MEMORY; + + /* Base64 encode the reply */ + result = Curl_base64_encode(data, oauth, strlen(oauth), outptr, outlen); + + free(oauth); + + return result; +} + +/* + * Curl_auth_create_xoauth_bearer_message() + * + * This is used to generate an already encoded XOAuth 2.0 message ready for + * sending to the recipient. + * + * Parameters: + * + * data[in] - The session handle. + * user[in] - The user name. + * bearer[in] - The bearer token. + * outptr[in / out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen[out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data, + const char *user, + const char *bearer, + char **outptr, size_t *outlen) +{ + CURLcode result = CURLE_OK; + + /* Generate the message */ + char *xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer); + if(!xoauth) + return CURLE_OUT_OF_MEMORY; + + /* Base64 encode the reply */ + result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen); + + free(xoauth); + + return result; +} +#endif /* disabled, no users */ + diff --git a/libcurl/lib/vauth/spnego_gssapi.c b/libcurl/lib/vauth/spnego_gssapi.c new file mode 100644 index 0000000..5d43e11 --- /dev/null +++ b/libcurl/lib/vauth/spnego_gssapi.c @@ -0,0 +1,282 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC4178 Simple and Protected GSS-API Negotiation Mechanism + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(HAVE_GSSAPI) && defined(USE_SPNEGO) + +#include + +#include "vauth/vauth.h" +#include "urldata.h" +#include "curl_base64.h" +#include "curl_gssapi.h" +#include "warnless.h" +#include "curl_multibyte.h" +#include "sendf.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Curl_auth_is_spnego_supported() + * + * This is used to evaluate if SPNEGO (Negotiate) is supported. + * + * Parameters: None + * + * Returns TRUE if Negotiate supported by the GSS-API library. + */ +bool Curl_auth_is_spnego_supported(void) +{ + return TRUE; +} + +/* + * Curl_auth_decode_spnego_message() + * + * This is used to decode an already encoded SPNEGO (Negotiate) challenge + * message. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name in the format User or Domain\User. + * passwdp [in] - The user's password. + * service [in] - The service type such as http, smtp, pop or imap. + * host [in] - The host name. + * chlg64 [in] - The optional base64 encoded challenge message. + * nego [in/out] - The Negotiate data struct being used and modified. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, + const char *user, + const char *password, + const char *service, + const char *host, + const char *chlg64, + struct negotiatedata *nego) +{ + CURLcode result = CURLE_OK; + size_t chlglen = 0; + unsigned char *chlg = NULL; + OM_uint32 major_status; + OM_uint32 minor_status; + OM_uint32 unused_status; + gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; + + (void) user; + (void) password; + + if(nego->context && nego->status == GSS_S_COMPLETE) { + /* We finished successfully our part of authentication, but server + * rejected it (since we're again here). Exit with an error since we + * can't invent anything better */ + Curl_auth_cleanup_spnego(nego); + return CURLE_LOGIN_DENIED; + } + + if(!nego->spn) { + /* Generate our SPN */ + char *spn = Curl_auth_build_spn(service, NULL, host); + if(!spn) + return CURLE_OUT_OF_MEMORY; + + /* Populate the SPN structure */ + spn_token.value = spn; + spn_token.length = strlen(spn); + + /* Import the SPN */ + major_status = gss_import_name(&minor_status, &spn_token, + GSS_C_NT_HOSTBASED_SERVICE, + &nego->spn); + if(GSS_ERROR(major_status)) { + Curl_gss_log_error(data, "gss_import_name() failed: ", + major_status, minor_status); + + free(spn); + + return CURLE_OUT_OF_MEMORY; + } + + free(spn); + } + + if(chlg64 && *chlg64) { + /* Decode the base-64 encoded challenge message */ + if(*chlg64 != '=') { + result = Curl_base64_decode(chlg64, &chlg, &chlglen); + if(result) + return result; + } + + /* Ensure we have a valid challenge message */ + if(!chlg) { + infof(data, "SPNEGO handshake failure (empty challenge message)\n"); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Setup the challenge "input" security buffer */ + input_token.value = chlg; + input_token.length = chlglen; + } + + /* Generate our challenge-response message */ + major_status = Curl_gss_init_sec_context(data, + &minor_status, + &nego->context, + nego->spn, + &Curl_spnego_mech_oid, + GSS_C_NO_CHANNEL_BINDINGS, + &input_token, + &output_token, + TRUE, + NULL); + + /* Free the decoded challenge as it is not required anymore */ + Curl_safefree(input_token.value); + + nego->status = major_status; + if(GSS_ERROR(major_status)) { + if(output_token.value) + gss_release_buffer(&unused_status, &output_token); + + Curl_gss_log_error(data, "gss_init_sec_context() failed: ", + major_status, minor_status); + + return CURLE_LOGIN_DENIED; + } + + if(!output_token.value || !output_token.length) { + if(output_token.value) + gss_release_buffer(&unused_status, &output_token); + + return CURLE_OUT_OF_MEMORY; + } + + /* Free previous token */ + if(nego->output_token.length && nego->output_token.value) + gss_release_buffer(&unused_status, &nego->output_token); + + nego->output_token = output_token; + + return CURLE_OK; +} + +/* + * Curl_auth_create_spnego_message() + * + * This is used to generate an already encoded SPNEGO (Negotiate) response + * message ready for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * nego [in/out] - The Negotiate data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data, + struct negotiatedata *nego, + char **outptr, size_t *outlen) +{ + CURLcode result; + OM_uint32 minor_status; + + /* Base64 encode the already generated response */ + result = Curl_base64_encode(data, + nego->output_token.value, + nego->output_token.length, + outptr, outlen); + + if(result) { + gss_release_buffer(&minor_status, &nego->output_token); + nego->output_token.value = NULL; + nego->output_token.length = 0; + + return result; + } + + if(!*outptr || !*outlen) { + gss_release_buffer(&minor_status, &nego->output_token); + nego->output_token.value = NULL; + nego->output_token.length = 0; + + return CURLE_REMOTE_ACCESS_DENIED; + } + + return CURLE_OK; +} + +/* + * Curl_auth_cleanup_spnego() + * + * This is used to clean up the SPNEGO (Negotiate) specific data. + * + * Parameters: + * + * nego [in/out] - The Negotiate data struct being cleaned up. + * + */ +void Curl_auth_cleanup_spnego(struct negotiatedata *nego) +{ + OM_uint32 minor_status; + + /* Free our security context */ + if(nego->context != GSS_C_NO_CONTEXT) { + gss_delete_sec_context(&minor_status, &nego->context, GSS_C_NO_BUFFER); + nego->context = GSS_C_NO_CONTEXT; + } + + /* Free the output token */ + if(nego->output_token.value) { + gss_release_buffer(&minor_status, &nego->output_token); + nego->output_token.value = NULL; + nego->output_token.length = 0; + + } + + /* Free the SPN */ + if(nego->spn != GSS_C_NO_NAME) { + gss_release_name(&minor_status, &nego->spn); + nego->spn = GSS_C_NO_NAME; + } + + /* Reset any variables */ + nego->status = 0; + nego->noauthpersist = FALSE; + nego->havenoauthpersist = FALSE; + nego->havenegdata = FALSE; + nego->havemultiplerequests = FALSE; +} + +#endif /* HAVE_GSSAPI && USE_SPNEGO */ diff --git a/libcurl/lib/vauth/spnego_sspi.c b/libcurl/lib/vauth/spnego_sspi.c new file mode 100644 index 0000000..4b21cc7 --- /dev/null +++ b/libcurl/lib/vauth/spnego_sspi.c @@ -0,0 +1,352 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC4178 Simple and Protected GSS-API Negotiation Mechanism + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_WINDOWS_SSPI) && defined(USE_SPNEGO) + +#include + +#include "vauth/vauth.h" +#include "urldata.h" +#include "curl_base64.h" +#include "warnless.h" +#include "curl_multibyte.h" +#include "sendf.h" +#include "strerror.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Curl_auth_is_spnego_supported() + * + * This is used to evaluate if SPNEGO (Negotiate) is supported. + * + * Parameters: None + * + * Returns TRUE if Negotiate is supported by Windows SSPI. + */ +bool Curl_auth_is_spnego_supported(void) +{ + PSecPkgInfo SecurityPackage; + SECURITY_STATUS status; + + /* Query the security package for Negotiate */ + status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) + TEXT(SP_NAME_NEGOTIATE), + &SecurityPackage); + + return (status == SEC_E_OK ? TRUE : FALSE); +} + +/* + * Curl_auth_decode_spnego_message() + * + * This is used to decode an already encoded SPNEGO (Negotiate) challenge + * message. + * + * Parameters: + * + * data [in] - The session handle. + * user [in] - The user name in the format User or Domain\User. + * password [in] - The user's password. + * service [in] - The service type such as http, smtp, pop or imap. + * host [in] - The host name. + * chlg64 [in] - The optional base64 encoded challenge message. + * nego [in/out] - The Negotiate data struct being used and modified. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, + const char *user, + const char *password, + const char *service, + const char *host, + const char *chlg64, + struct negotiatedata *nego) +{ + CURLcode result = CURLE_OK; + size_t chlglen = 0; + unsigned char *chlg = NULL; + PSecPkgInfo SecurityPackage; + SecBuffer chlg_buf[2]; + SecBuffer resp_buf; + SecBufferDesc chlg_desc; + SecBufferDesc resp_desc; + unsigned long attrs; + TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ + +#if defined(CURL_DISABLE_VERBOSE_STRINGS) + (void) data; +#endif + + if(nego->context && nego->status == SEC_E_OK) { + /* We finished successfully our part of authentication, but server + * rejected it (since we're again here). Exit with an error since we + * can't invent anything better */ + Curl_auth_cleanup_spnego(nego); + return CURLE_LOGIN_DENIED; + } + + if(!nego->spn) { + /* Generate our SPN */ + nego->spn = Curl_auth_build_spn(service, host, NULL); + if(!nego->spn) + return CURLE_OUT_OF_MEMORY; + } + + if(!nego->output_token) { + /* Query the security package for Negotiate */ + nego->status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) + TEXT(SP_NAME_NEGOTIATE), + &SecurityPackage); + if(nego->status != SEC_E_OK) + return CURLE_NOT_BUILT_IN; + + nego->token_max = SecurityPackage->cbMaxToken; + + /* Release the package buffer as it is not required anymore */ + s_pSecFn->FreeContextBuffer(SecurityPackage); + + /* Allocate our output buffer */ + nego->output_token = malloc(nego->token_max); + if(!nego->output_token) + return CURLE_OUT_OF_MEMORY; + } + + if(!nego->credentials) { + /* Do we have credentials to use or are we using single sign-on? */ + if(user && *user) { + /* Populate our identity structure */ + result = Curl_create_sspi_identity(user, password, &nego->identity); + if(result) + return result; + + /* Allow proper cleanup of the identity structure */ + nego->p_identity = &nego->identity; + } + else + /* Use the current Windows user */ + nego->p_identity = NULL; + + /* Allocate our credentials handle */ + nego->credentials = calloc(1, sizeof(CredHandle)); + if(!nego->credentials) + return CURLE_OUT_OF_MEMORY; + + /* Acquire our credentials handle */ + nego->status = + s_pSecFn->AcquireCredentialsHandle(NULL, + (TCHAR *)TEXT(SP_NAME_NEGOTIATE), + SECPKG_CRED_OUTBOUND, NULL, + nego->p_identity, NULL, NULL, + nego->credentials, &expiry); + if(nego->status != SEC_E_OK) + return CURLE_LOGIN_DENIED; + + /* Allocate our new context handle */ + nego->context = calloc(1, sizeof(CtxtHandle)); + if(!nego->context) + return CURLE_OUT_OF_MEMORY; + } + + if(chlg64 && *chlg64) { + /* Decode the base-64 encoded challenge message */ + if(*chlg64 != '=') { + result = Curl_base64_decode(chlg64, &chlg, &chlglen); + if(result) + return result; + } + + /* Ensure we have a valid challenge message */ + if(!chlg) { + infof(data, "SPNEGO handshake failure (empty challenge message)\n"); + + return CURLE_BAD_CONTENT_ENCODING; + } + + /* Setup the challenge "input" security buffer */ + chlg_desc.ulVersion = SECBUFFER_VERSION; + chlg_desc.cBuffers = 1; + chlg_desc.pBuffers = &chlg_buf[0]; + chlg_buf[0].BufferType = SECBUFFER_TOKEN; + chlg_buf[0].pvBuffer = chlg; + chlg_buf[0].cbBuffer = curlx_uztoul(chlglen); + +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + /* ssl context comes from Schannel. + * When extended protection is used in IIS server, + * we have to pass a second SecBuffer to the SecBufferDesc + * otherwise IIS will not pass the authentication (401 response). + * Minimum supported version is Windows 7. + * https://docs.microsoft.com/en-us/security-updates + * /SecurityAdvisories/2009/973811 + */ + if(nego->sslContext) { + SEC_CHANNEL_BINDINGS channelBindings; + SecPkgContext_Bindings pkgBindings; + pkgBindings.Bindings = &channelBindings; + nego->status = s_pSecFn->QueryContextAttributes( + nego->sslContext, + SECPKG_ATTR_ENDPOINT_BINDINGS, + &pkgBindings + ); + if(nego->status == SEC_E_OK) { + chlg_desc.cBuffers++; + chlg_buf[1].BufferType = SECBUFFER_CHANNEL_BINDINGS; + chlg_buf[1].cbBuffer = pkgBindings.BindingsLength; + chlg_buf[1].pvBuffer = pkgBindings.Bindings; + } + } +#endif + } + + /* Setup the response "output" security buffer */ + resp_desc.ulVersion = SECBUFFER_VERSION; + resp_desc.cBuffers = 1; + resp_desc.pBuffers = &resp_buf; + resp_buf.BufferType = SECBUFFER_TOKEN; + resp_buf.pvBuffer = nego->output_token; + resp_buf.cbBuffer = curlx_uztoul(nego->token_max); + + /* Generate our challenge-response message */ + nego->status = s_pSecFn->InitializeSecurityContext(nego->credentials, + chlg ? nego->context : + NULL, + nego->spn, + ISC_REQ_CONFIDENTIALITY, + 0, SECURITY_NATIVE_DREP, + chlg ? &chlg_desc : NULL, + 0, nego->context, + &resp_desc, &attrs, + &expiry); + + /* Free the decoded challenge as it is not required anymore */ + free(chlg); + + if(GSS_ERROR(nego->status)) { + char buffer[STRERROR_LEN]; + failf(data, "InitializeSecurityContext failed: %s", + Curl_sspi_strerror(nego->status, buffer, sizeof(buffer))); + return CURLE_OUT_OF_MEMORY; + } + + if(nego->status == SEC_I_COMPLETE_NEEDED || + nego->status == SEC_I_COMPLETE_AND_CONTINUE) { + nego->status = s_pSecFn->CompleteAuthToken(nego->context, &resp_desc); + if(GSS_ERROR(nego->status)) { + return CURLE_RECV_ERROR; + } + } + + nego->output_token_length = resp_buf.cbBuffer; + + return result; +} + +/* + * Curl_auth_create_spnego_message() + * + * This is used to generate an already encoded SPNEGO (Negotiate) response + * message ready for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * nego [in/out] - The Negotiate data struct being used and modified. + * outptr [in/out] - The address where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data, + struct negotiatedata *nego, + char **outptr, size_t *outlen) +{ + CURLcode result; + + /* Base64 encode the already generated response */ + result = Curl_base64_encode(data, + (const char *) nego->output_token, + nego->output_token_length, + outptr, outlen); + + if(result) + return result; + + if(!*outptr || !*outlen) { + free(*outptr); + return CURLE_REMOTE_ACCESS_DENIED; + } + + return CURLE_OK; +} + +/* + * Curl_auth_cleanup_spnego() + * + * This is used to clean up the SPNEGO (Negotiate) specific data. + * + * Parameters: + * + * nego [in/out] - The Negotiate data struct being cleaned up. + * + */ +void Curl_auth_cleanup_spnego(struct negotiatedata *nego) +{ + /* Free our security context */ + if(nego->context) { + s_pSecFn->DeleteSecurityContext(nego->context); + free(nego->context); + nego->context = NULL; + } + + /* Free our credentials handle */ + if(nego->credentials) { + s_pSecFn->FreeCredentialsHandle(nego->credentials); + free(nego->credentials); + nego->credentials = NULL; + } + + /* Free our identity */ + Curl_sspi_free_identity(nego->p_identity); + nego->p_identity = NULL; + + /* Free the SPN and output token */ + Curl_safefree(nego->spn); + Curl_safefree(nego->output_token); + + /* Reset any variables */ + nego->status = 0; + nego->token_max = 0; + nego->noauthpersist = FALSE; + nego->havenoauthpersist = FALSE; + nego->havenegdata = FALSE; + nego->havemultiplerequests = FALSE; +} + +#endif /* USE_WINDOWS_SSPI && USE_SPNEGO */ diff --git a/libcurl/lib/vauth/vauth.c b/libcurl/lib/vauth/vauth.c new file mode 100644 index 0000000..a9c5c9c --- /dev/null +++ b/libcurl/lib/vauth/vauth.c @@ -0,0 +1,147 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2014 - 2019, Steve Holme, . + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include + +#include "vauth.h" +#include "curl_multibyte.h" +#include "curl_printf.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Curl_auth_build_spn() + * + * This is used to build a SPN string in the following formats: + * + * service/host@realm (Not currently used) + * service/host (Not used by GSS-API) + * service@realm (Not used by Windows SSPI) + * + * Parameters: + * + * service [in] - The service type such as http, smtp, pop or imap. + * host [in] - The host name. + * realm [in] - The realm. + * + * Returns a pointer to the newly allocated SPN. + */ +#if !defined(USE_WINDOWS_SSPI) +char *Curl_auth_build_spn(const char *service, const char *host, + const char *realm) +{ + char *spn = NULL; + + /* Generate our SPN */ + if(host && realm) + spn = aprintf("%s/%s@%s", service, host, realm); + else if(host) + spn = aprintf("%s/%s", service, host); + else if(realm) + spn = aprintf("%s@%s", service, realm); + + /* Return our newly allocated SPN */ + return spn; +} +#else +TCHAR *Curl_auth_build_spn(const char *service, const char *host, + const char *realm) +{ + char *utf8_spn = NULL; + TCHAR *tchar_spn = NULL; + + (void) realm; + + /* Note: We could use DsMakeSPN() or DsClientMakeSpnForTargetServer() rather + than doing this ourselves but the first is only available in Windows XP + and Windows Server 2003 and the latter is only available in Windows 2000 + but not Windows95/98/ME or Windows NT4.0 unless the Active Directory + Client Extensions are installed. As such it is far simpler for us to + formulate the SPN instead. */ + + /* Generate our UTF8 based SPN */ + utf8_spn = aprintf("%s/%s", service, host); + if(!utf8_spn) { + return NULL; + } + + /* Allocate our TCHAR based SPN */ + tchar_spn = Curl_convert_UTF8_to_tchar(utf8_spn); + if(!tchar_spn) { + free(utf8_spn); + + return NULL; + } + + /* Release the UTF8 variant when operating with Unicode */ + Curl_unicodefree(utf8_spn); + + /* Return our newly allocated SPN */ + return tchar_spn; +} +#endif /* USE_WINDOWS_SSPI */ + +/* + * Curl_auth_user_contains_domain() + * + * This is used to test if the specified user contains a Windows domain name as + * follows: + * + * Domain\User (Down-level Logon Name) + * Domain/User (curl Down-level format - for compatibility with existing code) + * User@Domain (User Principal Name) + * + * Note: The user name may be empty when using a GSS-API library or Windows + * SSPI as the user and domain are either obtained from the credentials cache + * when using GSS-API or via the currently logged in user's credentials when + * using Windows SSPI. + * + * Parameters: + * + * user [in] - The user name. + * + * Returns TRUE on success; otherwise FALSE. + */ +bool Curl_auth_user_contains_domain(const char *user) +{ + bool valid = FALSE; + + if(user && *user) { + /* Check we have a domain name or UPN present */ + char *p = strpbrk(user, "\\/@"); + + valid = (p != NULL && p > user && p < user + strlen(user) - 1 ? TRUE : + FALSE); + } +#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) + else + /* User and domain are obtained from the GSS-API credentials cache or the + currently logged in user from Windows */ + valid = TRUE; +#endif + + return valid; +} diff --git a/libcurl/lib/vauth/vauth.h b/libcurl/lib/vauth/vauth.h new file mode 100644 index 0000000..73bd25e --- /dev/null +++ b/libcurl/lib/vauth/vauth.h @@ -0,0 +1,215 @@ +#ifndef HEADER_CURL_VAUTH_H +#define HEADER_CURL_VAUTH_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2014 - 2019, Steve Holme, . + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include + +struct Curl_easy; + +#if !defined(CURL_DISABLE_CRYPTO_AUTH) +struct digestdata; +#endif + +#if defined(USE_NTLM) +struct ntlmdata; +#endif + +#if defined(USE_KERBEROS5) +struct kerberos5data; +#endif + +#if (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) && defined(USE_SPNEGO) +struct negotiatedata; +#endif + +#if defined(USE_WINDOWS_SSPI) +#define GSS_ERROR(status) (status & 0x80000000) +#endif + +/* This is used to build a SPN string */ +#if !defined(USE_WINDOWS_SSPI) +char *Curl_auth_build_spn(const char *service, const char *host, + const char *realm); +#else +TCHAR *Curl_auth_build_spn(const char *service, const char *host, + const char *realm); +#endif + +/* This is used to test if the user contains a Windows domain name */ +bool Curl_auth_user_contains_domain(const char *user); + +/* This is used to generate a base64 encoded PLAIN cleartext message */ +CURLcode Curl_auth_create_plain_message(struct Curl_easy *data, + const char *authzid, + const char *authcid, + const char *passwd, + char **outptr, size_t *outlen); + +/* This is used to generate a base64 encoded LOGIN cleartext message */ +CURLcode Curl_auth_create_login_message(struct Curl_easy *data, + const char *valuep, char **outptr, + size_t *outlen); + +/* This is used to generate a base64 encoded EXTERNAL cleartext message */ +CURLcode Curl_auth_create_external_message(struct Curl_easy *data, + const char *user, char **outptr, + size_t *outlen); + +#if !defined(CURL_DISABLE_CRYPTO_AUTH) +/* This is used to decode a CRAM-MD5 challenge message */ +CURLcode Curl_auth_decode_cram_md5_message(const char *chlg64, char **outptr, + size_t *outlen); + +/* This is used to generate a CRAM-MD5 response message */ +CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data, + const char *chlg, + const char *userp, + const char *passwdp, + char **outptr, size_t *outlen); + +/* This is used to evaluate if DIGEST is supported */ +bool Curl_auth_is_digest_supported(void); + +/* This is used to generate a base64 encoded DIGEST-MD5 response message */ +CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, + const char *chlg64, + const char *userp, + const char *passwdp, + const char *service, + char **outptr, size_t *outlen); + +/* This is used to decode a HTTP DIGEST challenge message */ +CURLcode Curl_auth_decode_digest_http_message(const char *chlg, + struct digestdata *digest); + +/* This is used to generate a HTTP DIGEST response message */ +CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, + const char *userp, + const char *passwdp, + const unsigned char *request, + const unsigned char *uri, + struct digestdata *digest, + char **outptr, size_t *outlen); + +/* This is used to clean up the digest specific data */ +void Curl_auth_digest_cleanup(struct digestdata *digest); +#endif /* !CURL_DISABLE_CRYPTO_AUTH */ + +#if defined(USE_NTLM) +/* This is used to evaluate if NTLM is supported */ +bool Curl_auth_is_ntlm_supported(void); + +/* This is used to generate a base64 encoded NTLM type-1 message */ +CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, + const char *userp, + const char *passwdp, + const char *service, + const char *host, + struct ntlmdata *ntlm, + char **outptr, + size_t *outlen); + +/* This is used to decode a base64 encoded NTLM type-2 message */ +CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, + const char *type2msg, + struct ntlmdata *ntlm); + +/* This is used to generate a base64 encoded NTLM type-3 message */ +CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, + const char *userp, + const char *passwdp, + struct ntlmdata *ntlm, + char **outptr, size_t *outlen); + +/* This is used to clean up the NTLM specific data */ +void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm); +#endif /* USE_NTLM */ + +/* This is used to generate a base64 encoded OAuth 2.0 message */ +CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data, + const char *user, + const char *host, + const long port, + const char *bearer, + char **outptr, size_t *outlen); + +/* This is used to generate a base64 encoded XOAuth 2.0 message */ +CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data, + const char *user, + const char *bearer, + char **outptr, size_t *outlen); + +#if defined(USE_KERBEROS5) +/* This is used to evaluate if GSSAPI (Kerberos V5) is supported */ +bool Curl_auth_is_gssapi_supported(void); + +/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token + message */ +CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, + const char *userp, + const char *passwdp, + const char *service, + const char *host, + const bool mutual, + const char *chlg64, + struct kerberos5data *krb5, + char **outptr, size_t *outlen); + +/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) security + token message */ +CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, + const char *input, + struct kerberos5data *krb5, + char **outptr, + size_t *outlen); + +/* This is used to clean up the GSSAPI specific data */ +void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5); +#endif /* USE_KERBEROS5 */ + +#if defined(USE_SPNEGO) +/* This is used to evaluate if SPNEGO (Negotiate) is supported */ +bool Curl_auth_is_spnego_supported(void); + +/* This is used to decode a base64 encoded SPNEGO (Negotiate) challenge + message */ +CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, + const char *user, + const char *passwood, + const char *service, + const char *host, + const char *chlg64, + struct negotiatedata *nego); + +/* This is used to generate a base64 encoded SPNEGO (Negotiate) response + message */ +CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data, + struct negotiatedata *nego, + char **outptr, size_t *outlen); + +/* This is used to clean up the SPNEGO specifiec data */ +void Curl_auth_cleanup_spnego(struct negotiatedata *nego); + +#endif /* USE_SPNEGO */ + +#endif /* HEADER_CURL_VAUTH_H */ diff --git a/libcurl/lib/version.c b/libcurl/lib/version.c new file mode 100644 index 0000000..14b0531 --- /dev/null +++ b/libcurl/lib/version.c @@ -0,0 +1,467 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include +#include "urldata.h" +#include "vtls/vtls.h" +#include "http2.h" +#include "ssh.h" +#include "curl_printf.h" + +#ifdef USE_ARES +# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ + (defined(WIN32) || defined(__SYMBIAN32__)) +# define CARES_STATICLIB +# endif +# include +#endif + +#ifdef USE_LIBIDN2 +#include +#endif + +#ifdef USE_LIBPSL +#include +#endif + +#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) +#include +#endif + +#ifdef USE_LIBRTMP +#include +#endif + +#ifdef USE_LIBSSH2 +#include +#endif + +#ifdef HAVE_LIBSSH2_VERSION +/* get it run-time if possible */ +#define CURL_LIBSSH2_VERSION libssh2_version(0) +#else +/* use build-time if run-time not possible */ +#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION +#endif + +#ifdef HAVE_ZLIB_H +#include +#ifdef __SYMBIAN32__ +/* zlib pollutes the namespace with this definition */ +#undef WIN32 +#endif +#endif + +#ifdef HAVE_BROTLI +#include +#endif + +void Curl_version_init(void); + +/* For thread safety purposes this function is called by global_init so that + the static data in both version functions is initialized. */ +void Curl_version_init(void) +{ + curl_version(); + curl_version_info(CURLVERSION_NOW); +} + +#ifdef HAVE_BROTLI +static size_t brotli_version(char *buf, size_t bufsz) +{ + uint32_t brotli_version = BrotliDecoderVersion(); + unsigned int major = brotli_version >> 24; + unsigned int minor = (brotli_version & 0x00FFFFFF) >> 12; + unsigned int patch = brotli_version & 0x00000FFF; + + return msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch); +} +#endif + +char *curl_version(void) +{ + static bool initialized; + static char version[200]; + char *ptr = version; + size_t len; + size_t left = sizeof(version); + + if(initialized) + return version; + + strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION); + len = strlen(ptr); + left -= len; + ptr += len; + + if(left > 1) { + len = Curl_ssl_version(ptr + 1, left - 1); + + if(len > 0) { + *ptr = ' '; + left -= ++len; + ptr += len; + } + } + +#ifdef HAVE_LIBZ + len = msnprintf(ptr, left, " zlib/%s", zlibVersion()); + left -= len; + ptr += len; +#endif +#ifdef HAVE_BROTLI + len = msnprintf(ptr, left, "%s", " brotli/"); + left -= len; + ptr += len; + len = brotli_version(ptr, left); + left -= len; + ptr += len; +#endif +#ifdef USE_ARES + /* this function is only present in c-ares, not in the original ares */ + len = msnprintf(ptr, left, " c-ares/%s", ares_version(NULL)); + left -= len; + ptr += len; +#endif +#ifdef USE_LIBIDN2 + if(idn2_check_version(IDN2_VERSION)) { + len = msnprintf(ptr, left, " libidn2/%s", idn2_check_version(NULL)); + left -= len; + ptr += len; + } +#endif +#ifdef USE_LIBPSL + len = msnprintf(ptr, left, " libpsl/%s", psl_get_version()); + left -= len; + ptr += len; +#endif +#ifdef USE_WIN32_IDN + len = msnprintf(ptr, left, " WinIDN"); + left -= len; + ptr += len; +#endif +#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) +#ifdef _LIBICONV_VERSION + len = msnprintf(ptr, left, " iconv/%d.%d", + _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255); +#else + /* version unknown */ + len = msnprintf(ptr, left, " iconv"); +#endif /* _LIBICONV_VERSION */ + left -= len; + ptr += len; +#endif +#ifdef USE_LIBSSH2 + len = msnprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION); + left -= len; + ptr += len; +#endif +#ifdef USE_LIBSSH + len = msnprintf(ptr, left, " libssh/%s", CURL_LIBSSH_VERSION); + left -= len; + ptr += len; +#endif +#ifdef USE_NGHTTP2 + len = Curl_http2_ver(ptr, left); + left -= len; + ptr += len; +#endif +#ifdef USE_LIBRTMP + { + char suff[2]; + if(RTMP_LIB_VERSION & 0xff) { + suff[0] = (RTMP_LIB_VERSION & 0xff) + 'a' - 1; + suff[1] = '\0'; + } + else + suff[0] = '\0'; + + msnprintf(ptr, left, " librtmp/%d.%d%s", + RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff, + suff); +/* + If another lib version is added below this one, this code would + also have to do: + + len = what msnprintf() returned + + left -= len; + ptr += len; +*/ + } +#endif + + /* Silent scan-build even if librtmp is not enabled. */ + (void) left; + (void) ptr; + + initialized = true; + return version; +} + +/* data for curl_version_info + + Keep the list sorted alphabetically. It is also written so that each + protocol line has its own #if line to make things easier on the eye. + */ + +static const char * const protocols[] = { +#ifndef CURL_DISABLE_DICT + "dict", +#endif +#ifndef CURL_DISABLE_FILE + "file", +#endif +#ifndef CURL_DISABLE_FTP + "ftp", +#endif +#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) + "ftps", +#endif +#ifndef CURL_DISABLE_GOPHER + "gopher", +#endif +#ifndef CURL_DISABLE_HTTP + "http", +#endif +#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) + "https", +#endif +#ifndef CURL_DISABLE_IMAP + "imap", +#endif +#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP) + "imaps", +#endif +#ifndef CURL_DISABLE_LDAP + "ldap", +#if !defined(CURL_DISABLE_LDAPS) && \ + ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ + (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) + "ldaps", +#endif +#endif +#ifndef CURL_DISABLE_POP3 + "pop3", +#endif +#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3) + "pop3s", +#endif +#ifdef USE_LIBRTMP + "rtmp", +#endif +#ifndef CURL_DISABLE_RTSP + "rtsp", +#endif +#if defined(USE_SSH) + "scp", + "sftp", +#endif +#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ + (CURL_SIZEOF_CURL_OFF_T > 4) && \ + (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)) + "smb", +# ifdef USE_SSL + "smbs", +# endif +#endif +#ifndef CURL_DISABLE_SMTP + "smtp", +#endif +#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP) + "smtps", +#endif +#ifndef CURL_DISABLE_TELNET + "telnet", +#endif +#ifndef CURL_DISABLE_TFTP + "tftp", +#endif + + NULL +}; + +static curl_version_info_data version_info = { + CURLVERSION_NOW, + LIBCURL_VERSION, + LIBCURL_VERSION_NUM, + OS, /* as found by configure or set by hand at build-time */ + 0 /* features is 0 by default */ +#ifdef ENABLE_IPV6 + | CURL_VERSION_IPV6 +#endif +#ifdef USE_SSL + | CURL_VERSION_SSL +#endif +#ifdef USE_NTLM + | CURL_VERSION_NTLM +#endif +#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ + defined(NTLM_WB_ENABLED) + | CURL_VERSION_NTLM_WB +#endif +#ifdef USE_SPNEGO + | CURL_VERSION_SPNEGO +#endif +#ifdef USE_KERBEROS5 + | CURL_VERSION_KERBEROS5 +#endif +#ifdef HAVE_GSSAPI + | CURL_VERSION_GSSAPI +#endif +#ifdef USE_WINDOWS_SSPI + | CURL_VERSION_SSPI +#endif +#ifdef HAVE_LIBZ + | CURL_VERSION_LIBZ +#endif +#ifdef DEBUGBUILD + | CURL_VERSION_DEBUG +#endif +#ifdef CURLDEBUG + | CURL_VERSION_CURLDEBUG +#endif +#ifdef CURLRES_ASYNCH + | CURL_VERSION_ASYNCHDNS +#endif +#if (CURL_SIZEOF_CURL_OFF_T > 4) && \ + ( (SIZEOF_OFF_T > 4) || defined(USE_WIN32_LARGE_FILES) ) + | CURL_VERSION_LARGEFILE +#endif +#if defined(CURL_DOES_CONVERSIONS) + | CURL_VERSION_CONV +#endif +#if defined(USE_TLS_SRP) + | CURL_VERSION_TLSAUTH_SRP +#endif +#if defined(USE_NGHTTP2) + | CURL_VERSION_HTTP2 +#endif +#if defined(USE_UNIX_SOCKETS) + | CURL_VERSION_UNIX_SOCKETS +#endif +#if defined(USE_LIBPSL) + | CURL_VERSION_PSL +#endif +#if defined(CURL_WITH_MULTI_SSL) + | CURL_VERSION_MULTI_SSL +#endif +#if defined(HAVE_BROTLI) + | CURL_VERSION_BROTLI +#endif +#if defined(USE_ALTSVC) + | CURL_VERSION_ALTSVC +#endif + , + NULL, /* ssl_version */ + 0, /* ssl_version_num, this is kept at zero */ + NULL, /* zlib_version */ + protocols, + NULL, /* c-ares version */ + 0, /* c-ares version numerical */ + NULL, /* libidn version */ + 0, /* iconv version */ + NULL, /* ssh lib version */ + 0, /* brotli_ver_num */ + NULL, /* brotli version */ +}; + +curl_version_info_data *curl_version_info(CURLversion stamp) +{ + static bool initialized; +#if defined(USE_SSH) + static char ssh_buffer[80]; +#endif +#ifdef USE_SSL +#ifdef CURL_WITH_MULTI_SSL + static char ssl_buffer[200]; +#else + static char ssl_buffer[80]; +#endif +#endif +#ifdef HAVE_BROTLI + static char brotli_buffer[80]; +#endif + + if(initialized) + return &version_info; + +#ifdef USE_SSL + Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer)); + version_info.ssl_version = ssl_buffer; + if(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY) + version_info.features |= CURL_VERSION_HTTPS_PROXY; + else + version_info.features &= ~CURL_VERSION_HTTPS_PROXY; +#endif + +#ifdef HAVE_LIBZ + version_info.libz_version = zlibVersion(); + /* libz left NULL if non-existing */ +#endif +#ifdef USE_ARES + { + int aresnum; + version_info.ares = ares_version(&aresnum); + version_info.ares_num = aresnum; + } +#endif +#ifdef USE_LIBIDN2 + /* This returns a version string if we use the given version or later, + otherwise it returns NULL */ + version_info.libidn = idn2_check_version(IDN2_VERSION); + if(version_info.libidn) + version_info.features |= CURL_VERSION_IDN; +#elif defined(USE_WIN32_IDN) + version_info.features |= CURL_VERSION_IDN; +#endif + +#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) +#ifdef _LIBICONV_VERSION + version_info.iconv_ver_num = _LIBICONV_VERSION; +#else + /* version unknown */ + version_info.iconv_ver_num = -1; +#endif /* _LIBICONV_VERSION */ +#endif + +#if defined(USE_LIBSSH2) + msnprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION); + version_info.libssh_version = ssh_buffer; +#elif defined(USE_LIBSSH) + msnprintf(ssh_buffer, sizeof(ssh_buffer), "libssh/%s", CURL_LIBSSH_VERSION); + version_info.libssh_version = ssh_buffer; +#endif + +#ifdef HAVE_BROTLI + version_info.brotli_ver_num = BrotliDecoderVersion(); + brotli_version(brotli_buffer, sizeof(brotli_buffer)); + version_info.brotli_version = brotli_buffer; +#endif + + (void)stamp; /* avoid compiler warnings, we don't use this */ + + initialized = true; + return &version_info; +} diff --git a/libcurl/lib/vtls/axtls.c b/libcurl/lib/vtls/axtls.c new file mode 100644 index 0000000..f0e3766 --- /dev/null +++ b/libcurl/lib/vtls/axtls.c @@ -0,0 +1,706 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2010, DirecTV, Contact: Eric Hu, . + * Copyright (C) 2010 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all axTLS-specific code for the TLS/SSL layer. No code + * but vtls.c should ever call or use these functions. + */ + +#include "curl_setup.h" + +#ifdef USE_AXTLS +#include +#include +#include "axtls.h" + +#include "sendf.h" +#include "inet_pton.h" +#include "vtls.h" +#include "parsedate.h" +#include "connect.h" /* for the connect timeout */ +#include "select.h" +#include "curl_printf.h" +#include "hostcheck.h" +#include + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + + +/* Global axTLS init, called from Curl_ssl_init() */ +int Curl_axtls_init(void) +{ +/* axTLS has no global init. Everything is done through SSL and SSL_CTX + * structs stored in connectdata structure. Perhaps can move to axtls.h. + */ + return 1; +} + +int Curl_axtls_cleanup(void) +{ + /* axTLS has no global cleanup. Perhaps can move this to axtls.h. */ + return 1; +} + +static CURLcode map_error_to_curl(int axtls_err) +{ + switch(axtls_err) { + case SSL_ERROR_NOT_SUPPORTED: + case SSL_ERROR_INVALID_VERSION: + case -70: /* protocol version alert from server */ + return CURLE_UNSUPPORTED_PROTOCOL; + break; + case SSL_ERROR_NO_CIPHER: + return CURLE_SSL_CIPHER; + break; + case SSL_ERROR_BAD_CERTIFICATE: /* this may be bad server cert too */ + case SSL_ERROR_NO_CERT_DEFINED: + case -42: /* bad certificate alert from server */ + case -43: /* unsupported cert alert from server */ + case -44: /* cert revoked alert from server */ + case -45: /* cert expired alert from server */ + case -46: /* cert unknown alert from server */ + return CURLE_SSL_CERTPROBLEM; + break; + case SSL_X509_ERROR(X509_NOT_OK): + case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT): + case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE): + case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID): + case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED): + case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED): + case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN): + case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST): + case SSL_X509_ERROR(X509_INVALID_PRIV_KEY): + return CURLE_PEER_FAILED_VERIFICATION; + break; + case -48: /* unknown ca alert from server */ + return CURLE_SSL_CACERT; + break; + case -49: /* access denied alert from server */ + return CURLE_REMOTE_ACCESS_DENIED; + break; + case SSL_ERROR_CONN_LOST: + case SSL_ERROR_SOCK_SETUP_FAILURE: + case SSL_ERROR_INVALID_HANDSHAKE: + case SSL_ERROR_INVALID_PROT_MSG: + case SSL_ERROR_INVALID_HMAC: + case SSL_ERROR_INVALID_SESSION: + case SSL_ERROR_INVALID_KEY: /* it's too bad this doesn't map better */ + case SSL_ERROR_FINISHED_INVALID: + case SSL_ERROR_NO_CLIENT_RENOG: + default: + return CURLE_SSL_CONNECT_ERROR; + break; + } +} + +static Curl_recv axtls_recv; +static Curl_send axtls_send; + +static void free_ssl_structs(struct ssl_connect_data *connssl) +{ + if(connssl->ssl) { + ssl_free(connssl->ssl); + connssl->ssl = NULL; + } + if(connssl->ssl_ctx) { + ssl_ctx_free(connssl->ssl_ctx); + connssl->ssl_ctx = NULL; + } +} + +/* + * For both blocking and non-blocking connects, this function sets up the + * ssl context and state. This function is called after the TCP connect + * has completed. + */ +static CURLcode connect_prep(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + SSL_CTX *ssl_ctx; + SSL *ssl = NULL; + int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0}; + int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0}; + int i, ssl_fcn_return; + + /* Assuming users will not compile in custom key/cert to axTLS. + * Also, even for blocking connects, use axTLS non-blocking feature. + */ + uint32_t client_option = SSL_NO_DEFAULT_KEY | + SSL_SERVER_VERIFY_LATER | + SSL_CONNECT_IN_PARTS; + + if(conn->ssl[sockindex].state == ssl_connection_complete) + /* to make us tolerant against being called more than once for the + same connection */ + return CURLE_OK; + + if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) { + failf(data, "axtls does not support CURL_SSLVERSION_MAX"); + return CURLE_SSL_CONNECT_ERROR; + } + + + /* axTLS only supports TLSv1 */ + /* check to see if we've been told to use an explicit SSL/TLS version */ + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + break; + default: + failf(data, "axTLS only supports TLS 1.0 and 1.1, " + "and it cannot be specified which one to use"); + return CURLE_SSL_CONNECT_ERROR; + } + +#ifdef AXTLSDEBUG + client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS; +#endif /* AXTLSDEBUG */ + + /* Allocate an SSL_CTX struct */ + ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS); + if(ssl_ctx == NULL) { + failf(data, "unable to create client SSL context"); + return CURLE_SSL_CONNECT_ERROR; + } + + conn->ssl[sockindex].ssl_ctx = ssl_ctx; + conn->ssl[sockindex].ssl = NULL; + + /* Load the trusted CA cert bundle file */ + if(SSL_CONN_CONFIG(CAfile)) { + if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, + SSL_CONN_CONFIG(CAfile), NULL) != SSL_OK) { + infof(data, "error reading ca cert file %s \n", + SSL_CONN_CONFIG(CAfile)); + if(SSL_CONN_CONFIG(verifypeer)) { + return CURLE_SSL_CACERT_BADFILE; + } + } + else + infof(data, "found certificates in %s\n", SSL_CONN_CONFIG(CAfile)); + } + + /* gtls.c tasks we're skipping for now: + * 1) certificate revocation list checking + * 2) dns name assignment to host + * 3) set protocol priority. axTLS is TLSv1 only, so can probably ignore + * 4) set certificate priority. axTLS ignores type and sends certs in + * order added. can probably ignore this. + */ + + /* Load client certificate */ + if(SSL_SET_OPTION(cert)) { + i=0; + /* Instead of trying to analyze cert type here, let axTLS try them all. */ + while(cert_types[i] != 0) { + ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i], + SSL_SET_OPTION(cert), NULL); + if(ssl_fcn_return == SSL_OK) { + infof(data, "successfully read cert file %s \n", + SSL_SET_OPTION(cert)); + break; + } + i++; + } + /* Tried all cert types, none worked. */ + if(cert_types[i] == 0) { + failf(data, "%s is not x509 or pkcs12 format", + SSL_SET_OPTION(cert)); + return CURLE_SSL_CERTPROBLEM; + } + } + + /* Load client key. + If a pkcs12 file successfully loaded a cert, then there's nothing to do + because the key has already been loaded. */ + if(SSL_SET_OPTION(key) && cert_types[i] != SSL_OBJ_PKCS12) { + i=0; + /* Instead of trying to analyze key type here, let axTLS try them all. */ + while(key_types[i] != 0) { + ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i], + SSL_SET_OPTION(key), NULL); + if(ssl_fcn_return == SSL_OK) { + infof(data, "successfully read key file %s \n", + SSL_SET_OPTION(key)); + break; + } + i++; + } + /* Tried all key types, none worked. */ + if(key_types[i] == 0) { + failf(data, "Failure: %s is not a supported key file", + SSL_SET_OPTION(key)); + return CURLE_SSL_CONNECT_ERROR; + } + } + + /* gtls.c does more here that is being left out for now + * 1) set session credentials. can probably ignore since axtls puts this + * info in the ssl_ctx struct + * 2) setting up callbacks. these seem gnutls specific + */ + + if(SSL_SET_OPTION(primary.sessionid)) { + const uint8_t *ssl_sessionid; + size_t ssl_idsize; + + /* In axTLS, handshaking happens inside ssl_client_new. */ + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize, + sockindex)) { + /* we got a session id, use it! */ + infof(data, "SSL re-using session ID\n"); + ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], + ssl_sessionid, (uint8_t)ssl_idsize, NULL); + } + Curl_ssl_sessionid_unlock(conn); + } + + if(!ssl) + ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0, NULL); + + conn->ssl[sockindex].ssl = ssl; + return CURLE_OK; +} + +/* + * For both blocking and non-blocking connects, this function finalizes the + * SSL connection. + */ +static CURLcode connect_finish(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + SSL *ssl = conn->ssl[sockindex].ssl; + const char *peer_CN; + uint32_t dns_altname_index; + const char *dns_altname; + int8_t found_subject_alt_names = 0; + int8_t found_subject_alt_name_matching_conn = 0; + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const char * const dispname = SSL_IS_PROXY() ? + conn->http_proxy.host.dispname : conn->host.dispname; + + /* Here, gtls.c gets the peer certificates and fails out depending on + * settings in "data." axTLS api doesn't have get cert chain fcn, so omit? + */ + + /* Verify server's certificate */ + if(SSL_CONN_CONFIG(verifypeer)) { + if(ssl_verify_cert(ssl) != SSL_OK) { + Curl_axtls_close(conn, sockindex); + failf(data, "server cert verify failed"); + return CURLE_PEER_FAILED_VERIFICATION; + } + } + else + infof(data, "\t server certificate verification SKIPPED\n"); + + /* Here, gtls.c does issuer verification. axTLS has no straightforward + * equivalent, so omitting for now.*/ + + /* Here, gtls.c does the following + * 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but + * it seems useful. This is now implemented, by Oscar Koeroo + * 2) checks cert validity based on time. axTLS does this in ssl_verify_cert + * 3) displays a bunch of cert information. axTLS doesn't support most of + * this, but a couple fields are available. + */ + + /* There is no (DNS) Altnames count in the version 1.4.8 API. There is a + risk of an inifite loop */ + for(dns_altname_index = 0; ; dns_altname_index++) { + dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index); + if(dns_altname == NULL) { + break; + } + found_subject_alt_names = 1; + + infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n", + dns_altname, hostname); + if(Curl_cert_hostcheck(dns_altname, hostname)) { + found_subject_alt_name_matching_conn = 1; + break; + } + } + + /* RFC2818 checks */ + if(found_subject_alt_names && !found_subject_alt_name_matching_conn) { + if(SSL_CONN_CONFIG(verifyhost)) { + /* Break connection ! */ + Curl_axtls_close(conn, sockindex); + failf(data, "\tsubjectAltName(s) do not match %s\n", dispname); + return CURLE_PEER_FAILED_VERIFICATION; + } + else + infof(data, "\tsubjectAltName(s) do not match %s\n", dispname); + } + else if(found_subject_alt_names == 0) { + /* Per RFC2818, when no Subject Alt Names were available, examine the peer + CN as a legacy fallback */ + peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME); + if(peer_CN == NULL) { + if(SSL_CONN_CONFIG(verifyhost)) { + Curl_axtls_close(conn, sockindex); + failf(data, "unable to obtain common name from peer certificate"); + return CURLE_PEER_FAILED_VERIFICATION; + } + else + infof(data, "unable to obtain common name from peer certificate"); + } + else { + if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) { + if(SSL_CONN_CONFIG(verifyhost)) { + /* Break connection ! */ + Curl_axtls_close(conn, sockindex); + failf(data, "\tcommon name \"%s\" does not match \"%s\"\n", + peer_CN, dispname); + return CURLE_PEER_FAILED_VERIFICATION; + } + else + infof(data, "\tcommon name \"%s\" does not match \"%s\"\n", + peer_CN, dispname); + } + } + } + + /* General housekeeping */ + conn->ssl[sockindex].state = ssl_connection_complete; + conn->recv[sockindex] = axtls_recv; + conn->send[sockindex] = axtls_send; + + /* Put our freshly minted SSL session in cache */ + if(SSL_SET_OPTION(primary.sessionid)) { + const uint8_t *ssl_sessionid = ssl_get_session_id(ssl); + size_t ssl_idsize = ssl_get_session_id_size(ssl); + Curl_ssl_sessionid_lock(conn); + if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize, + sockindex) != CURLE_OK) + infof(data, "failed to add session to cache\n"); + Curl_ssl_sessionid_unlock(conn); + } + + return CURLE_OK; +} + +/* + * Use axTLS's non-blocking connection feature to open an SSL connection. + * This is called after a TCP connection is already established. + */ +CURLcode Curl_axtls_connect_nonblocking( + struct connectdata *conn, + int sockindex, + bool *done) +{ + CURLcode conn_step; + int ssl_fcn_return; + int i; + + *done = FALSE; + /* connectdata is calloc'd and connecting_state is only changed in this + function, so this is safe, as the state is effectively initialized. */ + if(conn->ssl[sockindex].connecting_state == ssl_connect_1) { + conn_step = connect_prep(conn, sockindex); + if(conn_step != CURLE_OK) { + Curl_axtls_close(conn, sockindex); + return conn_step; + } + conn->ssl[sockindex].connecting_state = ssl_connect_2; + } + + if(conn->ssl[sockindex].connecting_state == ssl_connect_2) { + /* Check to make sure handshake was ok. */ + if(ssl_handshake_status(conn->ssl[sockindex].ssl) != SSL_OK) { + /* Loop to perform more work in between sleeps. This is work around the + fact that axtls does not expose any knowledge about when work needs + to be performed. This can save ~25% of time on SSL handshakes. */ + for(i=0; i<5; i++) { + ssl_fcn_return = ssl_read(conn->ssl[sockindex].ssl, NULL); + if(ssl_fcn_return < 0) { + Curl_axtls_close(conn, sockindex); + ssl_display_error(ssl_fcn_return); /* goes to stdout. */ + return map_error_to_curl(ssl_fcn_return); + } + return CURLE_OK; + } + } + infof(conn->data, "handshake completed successfully\n"); + conn->ssl[sockindex].connecting_state = ssl_connect_3; + } + + if(conn->ssl[sockindex].connecting_state == ssl_connect_3) { + conn_step = connect_finish(conn, sockindex); + if(conn_step != CURLE_OK) { + Curl_axtls_close(conn, sockindex); + return conn_step; + } + + /* Reset connect state */ + conn->ssl[sockindex].connecting_state = ssl_connect_1; + + *done = TRUE; + return CURLE_OK; + } + + /* Unrecognized state. Things are very bad. */ + conn->ssl[sockindex].state = ssl_connection_none; + conn->ssl[sockindex].connecting_state = ssl_connect_1; + /* Return value perhaps not strictly correct, but distinguishes the issue.*/ + return CURLE_BAD_FUNCTION_ARGUMENT; +} + + +/* + * This function is called after the TCP connect has completed. Setup the TLS + * layer and do all necessary magic for a blocking connect. + */ +CURLcode +Curl_axtls_connect(struct connectdata *conn, + int sockindex) + +{ + struct Curl_easy *data = conn->data; + CURLcode conn_step = connect_prep(conn, sockindex); + int ssl_fcn_return; + SSL *ssl = conn->ssl[sockindex].ssl; + long timeout_ms; + + if(conn_step != CURLE_OK) { + Curl_axtls_close(conn, sockindex); + return conn_step; + } + + /* Check to make sure handshake was ok. */ + while(ssl_handshake_status(ssl) != SSL_OK) { + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + ssl_fcn_return = ssl_read(ssl, NULL); + if(ssl_fcn_return < 0) { + Curl_axtls_close(conn, sockindex); + ssl_display_error(ssl_fcn_return); /* goes to stdout. */ + return map_error_to_curl(ssl_fcn_return); + } + /* TODO: avoid polling */ + Curl_wait_ms(10); + } + infof(conn->data, "handshake completed successfully\n"); + + conn_step = connect_finish(conn, sockindex); + if(conn_step != CURLE_OK) { + Curl_axtls_close(conn, sockindex); + return conn_step; + } + + return CURLE_OK; +} + +/* return number of sent (non-SSL) bytes */ +static ssize_t axtls_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *err) +{ + /* ssl_write() returns 'int' while write() and send() returns 'size_t' */ + int rc = ssl_write(conn->ssl[sockindex].ssl, mem, (int)len); + + infof(conn->data, " axtls_send\n"); + + if(rc < 0) { + *err = map_error_to_curl(rc); + rc = -1; /* generic error code for send failure */ + } + + *err = CURLE_OK; + return rc; +} + +void Curl_axtls_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + infof(conn->data, " Curl_axtls_close\n"); + + /* line from openssl.c: (void)SSL_shutdown(connssl->ssl); + axTLS compat layer does nothing for SSL_shutdown */ + + /* The following line is from openssl.c. There seems to be no axTLS + equivalent. ssl_free and ssl_ctx_free close things. + SSL_set_connect_state(connssl->handle); */ + + free_ssl_structs(connssl); +} + +/* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) + */ +int Curl_axtls_shutdown(struct connectdata *conn, int sockindex) +{ + /* Outline taken from openssl.c since functions are in axTLS compat layer. + axTLS's error set is much smaller, so a lot of error-handling was removed. + */ + int retval = 0; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct Curl_easy *data = conn->data; + uint8_t *buf; + ssize_t nread; + + infof(conn->data, " Curl_axtls_shutdown\n"); + + /* This has only been tested on the proftpd server, and the mod_tls code + sends a close notify alert without waiting for a close notify alert in + response. Thus we wait for a close notify alert from the server, but + we do not send one. Let's hope other servers do the same... */ + + /* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too + if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) + (void)SSL_shutdown(connssl->ssl); + */ + + if(connssl->ssl) { + int what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT); + if(what > 0) { + /* Something to read, let's do it and hope that it is the close + notify alert from the server. buf is managed internally by + axTLS and will be released upon calling ssl_free via + free_ssl_structs. */ + nread = (ssize_t)ssl_read(connssl->ssl, &buf); + + if(nread < SSL_OK) { + failf(data, "close notify alert not received during shutdown"); + retval = -1; + } + } + else if(0 == what) { + /* timeout */ + failf(data, "SSL shutdown timeout"); + } + else { + /* anything that gets here is fatally bad */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + retval = -1; + } + + free_ssl_structs(connssl); + } + return retval; +} + +static ssize_t axtls_recv(struct connectdata *conn, /* connection data */ + int num, /* socketindex */ + char *buf, /* store read data here */ + size_t buffersize, /* max amount to read */ + CURLcode *err) +{ + struct ssl_connect_data *connssl = &conn->ssl[num]; + ssize_t ret = 0; + uint8_t *read_buf; + + infof(conn->data, " axtls_recv\n"); + + *err = CURLE_OK; + if(connssl) { + ret = ssl_read(connssl->ssl, &read_buf); + if(ret > SSL_OK) { + /* ssl_read returns SSL_OK if there is more data to read, so if it is + larger, then all data has been read already. */ + memcpy(buf, read_buf, + (size_t)ret > buffersize ? buffersize : (size_t)ret); + } + else if(ret == SSL_OK) { + /* more data to be read, signal caller to call again */ + *err = CURLE_AGAIN; + ret = -1; + } + else if(ret == -3) { + /* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS + team approves proposed fix. */ + Curl_axtls_close(conn, num); + } + else { + failf(conn->data, "axTLS recv error (%d)", ret); + *err = map_error_to_curl((int) ret); + ret = -1; + } + } + + return ret; +} + +/* + * Return codes: + * 1 means the connection is still in place + * 0 means the connection has been closed + * -1 means the connection status is unknown + */ +int Curl_axtls_check_cxn(struct connectdata *conn) +{ + /* openssl.c line: rc = SSL_peek(conn->ssl[FIRSTSOCKET].ssl, (void*)&buf, 1); + axTLS compat layer always returns the last argument, so connection is + always alive? */ + + infof(conn->data, " Curl_axtls_check_cxn\n"); + return 1; /* connection still in place */ +} + +void Curl_axtls_session_free(void *ptr) +{ + (void)ptr; + /* free the ID */ + /* both openssl.c and gtls.c do something here, but axTLS's OpenSSL + compatibility layer does nothing, so we do nothing too. */ +} + +size_t Curl_axtls_version(char *buffer, size_t size) +{ + return snprintf(buffer, size, "axTLS/%s", ssl_version()); +} + +CURLcode Curl_axtls_random(struct Curl_easy *data, + unsigned char *entropy, + size_t length) +{ + static bool ssl_seeded = FALSE; + (void)data; + if(!ssl_seeded) { + ssl_seeded = TRUE; + /* Initialize the seed if not already done. This call is not exactly thread + * safe (and neither is the ssl_seeded check), but the worst effect of a + * race condition is that some global resources will leak. */ + RNG_initialize(); + } + get_random((int)length, entropy); + return CURLE_OK; +} + +#endif /* USE_AXTLS */ diff --git a/libcurl/lib/vtls/axtls.h b/libcurl/lib/vtls/axtls.h new file mode 100644 index 0000000..53797ea --- /dev/null +++ b/libcurl/lib/vtls/axtls.h @@ -0,0 +1,71 @@ +#ifndef HEADER_CURL_AXTLS_H +#define HEADER_CURL_AXTLS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2010, DirecTV, Contact: Eric Hu + * Copyright (C) 2010 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#ifdef USE_AXTLS +#include "curl/curl.h" +#include "urldata.h" + +int Curl_axtls_init(void); +int Curl_axtls_cleanup(void); +CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex); +CURLcode Curl_axtls_connect_nonblocking( + struct connectdata *conn, + int sockindex, + bool *done); + + /* close a SSL connection */ +void Curl_axtls_close(struct connectdata *conn, int sockindex); + +void Curl_axtls_session_free(void *ptr); +size_t Curl_axtls_version(char *buffer, size_t size); +int Curl_axtls_shutdown(struct connectdata *conn, int sockindex); +int Curl_axtls_check_cxn(struct connectdata *conn); +CURLcode Curl_axtls_random(struct Curl_easy *data, + unsigned char *entropy, + size_t length); + +/* Set the API backend definition to axTLS */ +#define CURL_SSL_BACKEND CURLSSLBACKEND_AXTLS + +/* API setup for axTLS */ +#define curlssl_init Curl_axtls_init +#define curlssl_cleanup Curl_axtls_cleanup +#define curlssl_connect Curl_axtls_connect +#define curlssl_connect_nonblocking Curl_axtls_connect_nonblocking +#define curlssl_session_free(x) Curl_axtls_session_free(x) +#define curlssl_close_all(x) ((void)x) +#define curlssl_close Curl_axtls_close +#define curlssl_shutdown(x,y) Curl_axtls_shutdown(x,y) +#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN) +#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN) +#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL) +#define curlssl_version Curl_axtls_version +#define curlssl_check_cxn(x) Curl_axtls_check_cxn(x) +#define curlssl_data_pending(x,y) ((void)x, (void)y, 0) +#define curlssl_random(x,y,z) Curl_axtls_random(x,y,z) + +#endif /* USE_AXTLS */ +#endif /* HEADER_CURL_AXTLS_H */ + diff --git a/libcurl/lib/vtls/bearssl.c b/libcurl/lib/vtls/bearssl.c new file mode 100644 index 0000000..81dc0d2 --- /dev/null +++ b/libcurl/lib/vtls/bearssl.c @@ -0,0 +1,1662 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * BearSSL TLS backend for libcurl + * Designed for Xbox (Visual Studio 2003 / C89 compatible) + * + * This file implements the libcurl vtls interface using BearSSL. + * BearSSL is ideal for Xbox because: + * - Written in C89/C90 (VS 2003 compatible) + * - No dynamic memory allocation + * - Small footprint + * - No external dependencies + * + * Xbox-specific enhancements: + * - Trust anchors loaded from embedded CA database (750+ CAs) + * - Session caching for TLS resumption + * - Descriptive error messages + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_BEARSSL + +#include + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "vtls.h" +#include "connect.h" +#include "select.h" +#include "multiif.h" + +/* Xbox-specific BearSSL integration */ +#ifdef _XBOX +#include "bearssl_xbox.h" +#define BEARSSL_XBOX_INTEGRATION 1 +#else +#define BEARSSL_XBOX_INTEGRATION 0 +#endif + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* + * Xbox time validation callback for X.509 certificate checking. + * + * The Xbox's internal RTC is unreliable: no NTP (Xbox Live for original Xbox + * is defunct), CMOS battery may be dead after 20+ years, and the clock can + * reset to 2000-01-01 or similar. A wrong system clock causes BearSSL's + * time(NULL)-based date validation to reject perfectly valid certificates. + * + * We skip date validation entirely. Trust anchor verification and optional + * certificate pinning provide the real security guarantees. + * + * Return: 0 = within validity period (always) + */ +#ifdef _XBOX +static int bearssl_xbox_time_check(void *tctx, + uint32_t not_before_days, uint32_t not_before_seconds, + uint32_t not_after_days, uint32_t not_after_seconds) +{ + (void)tctx; + (void)not_before_days; + (void)not_before_seconds; + (void)not_after_days; + (void)not_after_seconds; + return 0; +} +#endif + +/* Secure cipher suites - ECDHE with AEAD only */ +static const uint16_t bearssl_secure_suites[] = { + BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 +}; +#define BEARSSL_SECURE_SUITES_COUNT 6 + +/* + * ALPN protocol names for HTTP/1.1 + * + * ALPN (Application-Layer Protocol Negotiation) is a TLS extension that allows + * the client and server to negotiate which application protocol to use over + * the encrypted connection. Modern HTTPS servers (especially CDNs like + * Cloudflare) require ALPN to be present in the TLS handshake. + * + * Without ALPN, many servers will: + * - Reject the connection outright + * - Assume HTTP/2 and fail when receiving HTTP/1.1 + * - Reset the connection after handshake completes + * + * We advertise "http/1.1" since this libcurl build doesn't support HTTP/2. + */ +static const char *bearssl_alpn_protocols[] = { "http/1.1" }; +#define BEARSSL_ALPN_PROTOCOLS_COUNT 1 + +/* + * "No Anchor" X509 validator - wraps br_x509_minimal but accepts all certs. + * + * This approach uses BearSSL's proven certificate parsing code (br_x509_minimal) + * but overrides the validation result to always succeed. This is safer than + * implementing our own certificate decoder. + * + * Used when SSL_VERIFYPEER is disabled. + * + * NOTE: We use a POINTER to the minimal context (not embedded) to avoid + * memory layout issues with the union in ssl_backend_data. + */ +typedef struct { + const br_x509_class *vtable; + br_x509_minimal_context *minimal; /* Pointer to minimal validator */ + /* Certificate pinning: hash the leaf (first) certificate */ + br_sha256_context pin_sha256; /* SHA-256 running hash of leaf cert */ + unsigned char leaf_hash[32]; /* Final SHA-256 of leaf certificate */ + int cert_index; /* 0 = leaf cert, increments per cert */ + int leaf_hash_valid; /* 1 if leaf_hash has been computed */ + char pin_hostname[256]; /* Hostname for pin lookup */ +} br_x509_noanchor_context; + +/* Forward the call to minimal validator */ +static void xc_noanchor_start_chain(const br_x509_class **ctx, + const char *server_name) +{ + br_x509_noanchor_context *xc = (br_x509_noanchor_context *)ctx; +#ifdef _XBOX + { + char dbg[256]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: start_chain called, ctx=%p, xc=%p, minimal=%p\n", + (void*)ctx, (void*)xc, (void*)xc->minimal); + OutputDebugStringA(dbg); + if(xc->minimal) { + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: server=%s, minimal->vtable=%p\n", + server_name ? server_name : "(null)", + (void*)xc->minimal->vtable); + OutputDebugStringA(dbg); + } + } +#endif + if(!xc->minimal || !xc->minimal->vtable) { + OutputDebugStringA("BearSSL noanchor X509: ERROR - minimal or vtable is NULL!\n"); + return; + } + + /* Reset pinning state for this new chain */ + xc->cert_index = 0; + xc->leaf_hash_valid = 0; + memset(xc->leaf_hash, 0, sizeof(xc->leaf_hash)); + if(server_name) { + strncpy(xc->pin_hostname, server_name, sizeof(xc->pin_hostname) - 1); + xc->pin_hostname[sizeof(xc->pin_hostname) - 1] = '\0'; + } + else { + xc->pin_hostname[0] = '\0'; + } + + xc->minimal->vtable->start_chain(&xc->minimal->vtable, server_name); + OutputDebugStringA("BearSSL noanchor X509: start_chain forwarded OK\n"); +} + +static void xc_noanchor_start_cert(const br_x509_class **ctx, uint32_t length) +{ + br_x509_noanchor_context *xc = (br_x509_noanchor_context *)ctx; +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL noanchor X509: start_cert[%d], length=%u\n", + xc->cert_index, (unsigned)length); + OutputDebugStringA(dbg); + } +#endif + /* For the leaf certificate (index 0), start hashing for pin check */ + if(xc->cert_index == 0) { + br_sha256_init(&xc->pin_sha256); + } + xc->minimal->vtable->start_cert(&xc->minimal->vtable, length); +} + +static void xc_noanchor_append(const br_x509_class **ctx, + const unsigned char *buf, size_t len) +{ + br_x509_noanchor_context *xc = (br_x509_noanchor_context *)ctx; + /* Feed leaf certificate bytes into SHA-256 for pinning */ + if(xc->cert_index == 0) { + br_sha256_update(&xc->pin_sha256, buf, len); + } + xc->minimal->vtable->append(&xc->minimal->vtable, buf, len); +} + +static void xc_noanchor_end_cert(const br_x509_class **ctx) +{ + br_x509_noanchor_context *xc = (br_x509_noanchor_context *)ctx; +#ifdef _XBOX + { + char dbg[64]; + msnprintf(dbg, sizeof(dbg), "BearSSL noanchor X509: end_cert[%d]\n", + xc->cert_index); + OutputDebugStringA(dbg); + } +#endif + xc->minimal->vtable->end_cert(&xc->minimal->vtable); + + /* Finalize the SHA-256 hash of the leaf certificate */ + if(xc->cert_index == 0) { + br_sha256_out(&xc->pin_sha256, xc->leaf_hash); + xc->leaf_hash_valid = 1; +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: leaf cert SHA-256: " + "%02X%02X%02X%02X%02X%02X%02X%02X...\n", + xc->leaf_hash[0], xc->leaf_hash[1], + xc->leaf_hash[2], xc->leaf_hash[3], + xc->leaf_hash[4], xc->leaf_hash[5], + xc->leaf_hash[6], xc->leaf_hash[7]); + OutputDebugStringA(dbg); + } +#endif + } + xc->cert_index++; + +#ifdef _XBOX + /* Log the minimal validator's state after processing certificate */ + { + char dbg[256]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: minimal->err=%d, pkey.key_type=%d\n", + xc->minimal->err, xc->minimal->pkey.key_type); + OutputDebugStringA(dbg); + + if(xc->minimal->pkey.key_type == BR_KEYTYPE_RSA) { + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: RSA key - n=%p nlen=%u e=%p elen=%u\n", + (void*)xc->minimal->pkey.key.rsa.n, + (unsigned)xc->minimal->pkey.key.rsa.nlen, + (void*)xc->minimal->pkey.key.rsa.e, + (unsigned)xc->minimal->pkey.key.rsa.elen); + OutputDebugStringA(dbg); + } + else if(xc->minimal->pkey.key_type == BR_KEYTYPE_EC) { + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: EC key - curve=%d q=%p qlen=%u\n", + xc->minimal->pkey.key.ec.curve, + (void*)xc->minimal->pkey.key.ec.q, + (unsigned)xc->minimal->pkey.key.ec.qlen); + OutputDebugStringA(dbg); + } + } +#endif +} + +static unsigned xc_noanchor_end_chain(const br_x509_class **ctx) +{ + br_x509_noanchor_context *xc = (br_x509_noanchor_context *)ctx; + unsigned result; + + /* Call the minimal validator's end_chain */ + result = xc->minimal->vtable->end_chain(&xc->minimal->vtable); + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: end_chain, minimal returned %u (err=%d)\n", + result, xc->minimal->err); + OutputDebugStringA(dbg); + } +#endif + + /* + * Override the result: accept certificates in insecure mode. + * + * When SSL_VERIFYPEER is disabled, we accept all validation errors: + * - BR_ERR_X509_OK (32) - success + * - BR_ERR_X509_EXPIRED (54) - certificate expired or not yet valid + * - BR_ERR_X509_DN_MISMATCH (55) - issuer/subject DN mismatch + * - BR_ERR_X509_BAD_SERVER_NAME (56) - server name doesn't match cert + * - BR_ERR_X509_NOT_TRUSTED (62) - no matching trust anchor + * + * We only fail on actual parsing errors (33-52) which indicate a + * malformed certificate that cannot be used. + */ + if(result == BR_ERR_X509_OK || + result == BR_ERR_X509_EXPIRED || + result == BR_ERR_X509_DN_MISMATCH || + result == BR_ERR_X509_BAD_SERVER_NAME || + result == BR_ERR_X509_CRITICAL_EXTENSION || + result == BR_ERR_X509_NOT_CA || + result == BR_ERR_X509_FORBIDDEN_KEY_USAGE || + result == BR_ERR_X509_WEAK_PUBLIC_KEY || + result == BR_ERR_X509_NOT_TRUSTED) { + + /* + * Certificate pinning check: if a pin is registered for this hostname, + * verify the leaf certificate hash matches. This runs even in insecure + * mode because pinning is an explicit trust decision by the application. + */ +#if BEARSSL_XBOX_INTEGRATION + if(xc->leaf_hash_valid && xc->pin_hostname[0] != '\0') { + if(!bearssl_xbox_pin_verify_hash(xc->pin_hostname, xc->leaf_hash)) { +#ifdef _XBOX + OutputDebugStringA("BearSSL noanchor X509: CERTIFICATE PIN MISMATCH - rejecting!\n"); +#endif + return BR_ERR_X509_NOT_TRUSTED; + } + } +#endif + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: accepting certificate (insecure mode, result=%u)\n", + result); + OutputDebugStringA(dbg); + } +#endif + return 0; /* Success */ + } + + /* For actual parsing errors (bad certificate format, etc.), we still fail */ +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: certificate parsing error %u\n", result); + OutputDebugStringA(dbg); + } +#endif + return result; +} + +static const br_x509_pkey *xc_noanchor_get_pkey( + const br_x509_class *const *ctx, unsigned *usages) +{ + br_x509_noanchor_context *xc = (br_x509_noanchor_context *)ctx; + const br_x509_pkey *pk; + + /* Get the public key from the minimal validator */ + pk = xc->minimal->vtable->get_pkey(&xc->minimal->vtable, usages); + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: get_pkey returned %p (err=%d, key_type=%d)\n", + (void*)pk, xc->minimal->err, xc->minimal->pkey.key_type); + OutputDebugStringA(dbg); + } +#endif + + /* + * The minimal validator only returns the key if err is OK (32) or + * NOT_TRUSTED (62). For other validation errors like BAD_SERVER_NAME (56), + * EXPIRED (54), etc., it returns NULL even though the key was parsed. + * + * In insecure mode, we need to return the key for any validation error + * as long as the key itself was successfully parsed. + */ + if(!pk) { + /* + * Minimal validator didn't return key. Check if the key was parsed + * successfully - if so, return it directly. This handles validation + * errors like BAD_SERVER_NAME where the cert is valid but doesn't + * match requirements we're choosing to ignore. + */ + if(xc->minimal->pkey.key_type == BR_KEYTYPE_RSA || + xc->minimal->pkey.key_type == BR_KEYTYPE_EC) { +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL noanchor X509: returning key directly (err=%d bypassed)\n", + xc->minimal->err); + OutputDebugStringA(dbg); + } +#endif + if(usages) + *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN; + return &xc->minimal->pkey; + } +#ifdef _XBOX + OutputDebugStringA("BearSSL noanchor X509: ERROR - no valid key available!\n"); +#endif + } + + return pk; +} + +static const br_x509_class br_x509_noanchor_vtable = { + sizeof(br_x509_noanchor_context), + xc_noanchor_start_chain, + xc_noanchor_start_cert, + xc_noanchor_append, + xc_noanchor_end_cert, + xc_noanchor_end_chain, + xc_noanchor_get_pkey +}; + +/* + * Legacy insecure validator kept for reference but not used. + * The noanchor approach above is preferred. + */ +#if 0 /* DISABLED - using noanchor instead */ + +typedef struct { + const br_x509_class *vtable; + br_x509_decoder_context decoder; + br_x509_pkey pkey; + unsigned char pkey_data[BR_EC_KBUF_PUB_MAX_SIZE]; + unsigned char rsa_n[512]; + unsigned char rsa_e[8]; + int first_cert; + int pkey_valid; + uint32_t expected_len; + uint32_t received_len; +} br_x509_insecure_context; + +static void xc_insecure_start_chain(const br_x509_class **ctx, + const char *server_name) +{ + br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; + (void)server_name; + xc->first_cert = 1; + xc->pkey_valid = 0; +} + +/* ... rest of insecure implementation ... */ + +#endif /* DISABLED */ + +/* BearSSL backend data structure */ +struct ssl_backend_data { + br_ssl_client_context sc; + br_x509_minimal_context xc_minimal; /* Minimal X509 validator */ + br_x509_noanchor_context xc_noanchor; /* Noanchor wrapper (small, just vtable + pointer) */ + int using_noanchor; /* Are we using the noanchor (no-verify) validator? */ + unsigned char iobuf[BR_SSL_BUFSIZE_BIDI]; + br_sslio_context ioc; + int active; /* Is the SSL connection active? */ + int session_resumed; /* Was session resumed? */ + unsigned char resume_master_secret[48]; /* Master secret from resume attempt */ + int io_error; /* Have we had a socket I/O error? Skip graceful close if so */ + unsigned char leaf_cert_hash[32]; /* SHA-256 of leaf cert (from X.509 callback) */ + int leaf_cert_hash_valid; /* 1 if hash was captured */ + char hostname[256]; /* Hostname for session caching */ +#if BEARSSL_XBOX_INTEGRATION + br_x509_trust_anchor *file_anchors; /* Per-connection CAs from CURLOPT_CAINFO */ + size_t file_anchor_count; +#endif +}; + +#define BACKEND connssl->backend + +/* Forward declarations for send/recv functions */ +static Curl_recv bearssl_recv; +static Curl_send bearssl_send; + +/* Global state for trust anchor initialization */ +static int bearssl_trust_anchors_loaded = 0; +#if BEARSSL_XBOX_INTEGRATION +static int bearssl_trust_store_updated = 0; +#endif + +/* Low-level socket read callback for BearSSL */ +static int +sock_read(void *ctx, unsigned char *buf, size_t len) +{ + curl_socket_t fd = *(curl_socket_t *)ctx; + ssize_t rlen; + + /* + * Simple blocking read - no retry loop. + * The socket should already be in blocking mode, and libcurl manages + * timeouts at a higher level. We just do a single recv() call. + */ + rlen = recv(fd, (char *)buf, (int)len, 0); + + if(rlen > 0) { + /* Success - got data */ +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[64]; + msnprintf(dbg, sizeof(dbg), "BearSSL sock_read: got %d bytes\n", (int)rlen); + OutputDebugStringA(dbg); + } +#endif + return (int)rlen; + } + + if(rlen == 0) { + /* Connection closed by peer */ +#ifdef BEARSSL_VERBOSE_DEBUG + OutputDebugStringA("BearSSL sock_read: connection closed by peer\n"); +#endif + return -1; + } + + /* rlen < 0 - error */ + { + int err = SOCKERRNO; +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[64]; + msnprintf(dbg, sizeof(dbg), "BearSSL sock_read: recv error %d\n", err); + OutputDebugStringA(dbg); + } +#endif + + /* For EINTR, we could retry, but it's simpler to let the caller handle it */ + if(err == EWOULDBLOCK || err == EAGAIN) { + /* Would block - return 0 to indicate no data available yet */ + /* BearSSL will handle this appropriately */ + return 0; + } + + /* Real error - return -1 */ + return -1; + } +} + +/* Low-level socket write callback for BearSSL */ +static int +sock_write(void *ctx, const unsigned char *buf, size_t len) +{ + curl_socket_t fd = *(curl_socket_t *)ctx; + ssize_t wlen; + + /* + * Simple blocking write - no retry loop. + * The socket should already be in blocking mode, and libcurl manages + * timeouts at a higher level. We just do a single send() call. + */ + wlen = send(fd, (const char *)buf, (int)len, 0); + + if(wlen > 0) { + /* Success - data sent */ +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[64]; + msnprintf(dbg, sizeof(dbg), "BearSSL sock_write: sent %d bytes\n", (int)wlen); + OutputDebugStringA(dbg); + } +#endif + return (int)wlen; + } + + if(wlen == 0) { + /* No data sent - treat as would-block */ + return 0; + } + + /* wlen < 0 - error */ + { + int err = SOCKERRNO; +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[64]; + msnprintf(dbg, sizeof(dbg), "BearSSL sock_write: send error %d\n", err); + OutputDebugStringA(dbg); + } +#endif + + if(err == EWOULDBLOCK || err == EAGAIN) { + /* Would block - return 0 to indicate no data sent yet */ + return 0; + } + + /* Real error - return -1 */ + return -1; + } +} + +/* Get descriptive error message for BearSSL error code */ +static const char * +bearssl_error_string(int err) +{ +#if BEARSSL_XBOX_INTEGRATION + return bearssl_xbox_error_string(err); +#else + /* Fallback error messages for non-Xbox builds */ + switch(err) { + case BR_ERR_OK: return "Success"; + case BR_ERR_BAD_PARAM: return "Bad parameter"; + case BR_ERR_BAD_STATE: return "Invalid state"; + case BR_ERR_UNSUPPORTED_VERSION: return "Unsupported TLS version"; + case BR_ERR_BAD_VERSION: return "Bad TLS version"; + case BR_ERR_TOO_LARGE: return "Record too large"; + case BR_ERR_BAD_MAC: return "MAC verification failed"; + case BR_ERR_NO_RANDOM: return "No random seed"; + case BR_ERR_UNKNOWN_TYPE: return "Unknown record type"; + case BR_ERR_UNEXPECTED: return "Unexpected message"; + case BR_ERR_BAD_CCS: return "Bad ChangeCipherSpec"; + case BR_ERR_BAD_ALERT: return "Bad alert"; + case BR_ERR_BAD_HANDSHAKE: return "Bad handshake message"; + case BR_ERR_OVERSIZED_ID: return "Oversized ID"; + case BR_ERR_BAD_CIPHER_SUITE: return "Bad cipher suite"; + case BR_ERR_BAD_COMPRESSION: return "Bad compression"; + case BR_ERR_BAD_FRAGLEN: return "Bad fragment length"; + case BR_ERR_BAD_SECRENEG: return "Bad secure renegotiation"; + case BR_ERR_EXTRA_EXTENSION: return "Extra extension"; + case BR_ERR_BAD_SNI: return "Bad SNI"; + case BR_ERR_BAD_HELLO_DONE: return "Bad HelloDone"; + case BR_ERR_LIMIT_EXCEEDED: return "Limit exceeded"; + case BR_ERR_BAD_FINISHED: return "Bad Finished message"; + case BR_ERR_RESUME_MISMATCH: return "Session resume mismatch"; + case BR_ERR_INVALID_ALGORITHM: return "Invalid algorithm"; + case BR_ERR_BAD_SIGNATURE: return "Bad signature"; + case BR_ERR_WRONG_KEY_USAGE: return "Wrong key usage"; + case BR_ERR_NO_CLIENT_AUTH: return "No client auth"; + case BR_ERR_IO: return "I/O error"; + default: + if(err >= 256 && err < 512) + return "Received fatal alert from server"; + if(err >= 512) + return "Sent fatal alert to server"; + return "Unknown SSL error"; + } +#endif +} + +static int Curl_bearssl_init(void) +{ +#if BEARSSL_XBOX_INTEGRATION + /* Initialize trust anchors from Xbox certificate store */ + if(!bearssl_trust_anchors_loaded) { + bearssl_xbox_init_trust_anchors(); + bearssl_xbox_session_init(); + bearssl_trust_anchors_loaded = 1; + } +#endif + return 1; +} + +static void Curl_bearssl_cleanup(void) +{ +#if BEARSSL_XBOX_INTEGRATION + if(bearssl_trust_anchors_loaded) { + bearssl_xbox_session_shutdown(); + bearssl_xbox_cleanup_trust_anchors(); + bearssl_trust_anchors_loaded = 0; + bearssl_trust_store_updated = 0; + } +#endif +} + +static size_t Curl_bearssl_version(char *buffer, size_t size) +{ + return msnprintf(buffer, size, "BearSSL/0.6-Xbox"); +} + +static CURLcode Curl_bearssl_random(struct Curl_easy *data, + unsigned char *entropy, size_t length) +{ + br_hmac_drbg_context rng; + br_prng_seeder seeder; + + (void)data; + + seeder = br_prng_seeder_system(NULL); + if(!seeder) { + return CURLE_SSL_CONNECT_ERROR; + } + + br_hmac_drbg_init(&rng, &br_sha256_vtable, NULL, 0); + if(!seeder(&rng.vtable)) { + return CURLE_SSL_CONNECT_ERROR; + } + + br_hmac_drbg_generate(&rng, entropy, length); + return CURLE_OK; +} + +static CURLcode +bearssl_connect_step1(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + br_x509_trust_anchor *trust_anchors = NULL; + size_t trust_anchor_count = 0; + int session_resume = 0; +#if BEARSSL_XBOX_INTEGRATION + br_ssl_session_parameters session_params; +#endif + + /* + * NOTE: BACKEND memory is pre-allocated by the vtls layer in url.c as part + * of a single contiguous block for all SSL contexts. We must NOT allocate + * or free it ourselves - that would corrupt the heap. + * + * See url.c:allocate_conn() which does: + * conn->ssl[0].backend = (void *)ssl; + * conn->ssl[1].backend = (void *)(ssl + sslsize); + * conn->proxy_ssl[0].backend = (void *)(ssl + 2 * sslsize); + * conn->proxy_ssl[1].backend = (void *)(ssl + 3 * sslsize); + */ + DEBUGASSERT(BACKEND != NULL); + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL step1: Using pre-allocated backend at %p, size=%u bytes\n", + (void*)BACKEND, (unsigned)sizeof(struct ssl_backend_data)); + OutputDebugStringA(dbg); + } +#endif + + /* Clear the backend structure for fresh initialization */ + memset(BACKEND, 0, sizeof(struct ssl_backend_data)); + + /* Store hostname for session caching */ + strncpy(BACKEND->hostname, hostname, sizeof(BACKEND->hostname) - 1); + BACKEND->hostname[sizeof(BACKEND->hostname) - 1] = '\0'; + BACKEND->session_resumed = 0; + +#if BEARSSL_XBOX_INTEGRATION + /* Auto-download cacert.pem on first connection if not on disk. + * Done here (not in Curl_bearssl_init) because XNet needs time + * after DHCP before TCP connects work reliably. */ + if(!bearssl_trust_store_updated) { + bearssl_trust_store_updated = 1; + bearssl_xbox_update_trust_store(); + } +#endif + + /* Check if certificate verification is disabled */ + if(!SSL_CONN_CONFIG(verifypeer)) { + /* + * No verification - use the "noanchor" validator that wraps br_x509_minimal + * but accepts all certificates. This leverages BearSSL's proven certificate + * parsing code while bypassing the trust validation. + */ + OutputDebugStringA("BearSSL: Certificate verification DISABLED - using noanchor validator\n"); + BACKEND->using_noanchor = 1; + +#ifdef _XBOX + { + char dbg[512]; + msnprintf(dbg, sizeof(dbg), + "BearSSL: BACKEND=%p, sizeof(ssl_backend_data)=%u\n", + (void*)BACKEND, (unsigned)sizeof(struct ssl_backend_data)); + OutputDebugStringA(dbg); + msnprintf(dbg, sizeof(dbg), + "BearSSL: sizeof(br_ssl_client_context)=%u\n", + (unsigned)sizeof(br_ssl_client_context)); + OutputDebugStringA(dbg); + msnprintf(dbg, sizeof(dbg), + "BearSSL: sizeof(br_x509_minimal_context)=%u\n", + (unsigned)sizeof(br_x509_minimal_context)); + OutputDebugStringA(dbg); + msnprintf(dbg, sizeof(dbg), + "BearSSL: &BACKEND->sc=%p, &BACKEND->xc_minimal=%p\n", + (void*)&BACKEND->sc, (void*)&BACKEND->xc_minimal); + OutputDebugStringA(dbg); + } +#endif + + OutputDebugStringA("BearSSL: Calling br_ssl_client_init_full...\n"); + + /* + * Initialize the SSL client with the minimal X509 validator. + * We pass NULL trust anchors - the minimal validator will fail with + * NOT_TRUSTED, but our noanchor wrapper overrides that to accept anyway. + */ + br_ssl_client_init_full(&BACKEND->sc, &BACKEND->xc_minimal, NULL, 0); + + OutputDebugStringA("BearSSL: br_ssl_client_init_full done\n"); + +#ifdef _XBOX + { + char dbg[256]; + msnprintf(dbg, sizeof(dbg), + "BearSSL: xc_minimal at %p, xc_minimal.vtable = %p\n", + (void*)&BACKEND->xc_minimal, + (void*)BACKEND->xc_minimal.vtable); + OutputDebugStringA(dbg); + } +#endif + + /* Set up the noanchor wrapper to point to the minimal validator */ + BACKEND->xc_noanchor.vtable = &br_x509_noanchor_vtable; + BACKEND->xc_noanchor.minimal = &BACKEND->xc_minimal; + + OutputDebugStringA("BearSSL: Setting X509 engine to noanchor wrapper...\n"); + +#ifdef _XBOX + { + char dbg[256]; + msnprintf(dbg, sizeof(dbg), + "BearSSL: xc_noanchor at %p, vtable=%p, minimal=%p\n", + (void*)&BACKEND->xc_noanchor, + (void*)BACKEND->xc_noanchor.vtable, + (void*)BACKEND->xc_noanchor.minimal); + OutputDebugStringA(dbg); + } +#endif + + /* Replace the X509 engine with our noanchor validator wrapper */ + br_ssl_engine_set_x509(&BACKEND->sc.eng, &BACKEND->xc_noanchor.vtable); + OutputDebugStringA("BearSSL: Noanchor X509 validator installed\n"); + } + else { +#if BEARSSL_XBOX_INTEGRATION + { + /* Check for CURLOPT_CAINFO or default Xbox CA path */ + const char *cafile = SSL_CONN_CONFIG(CAfile); + + /* If no explicit CA file, try the default Xbox TDATA path */ + if(!cafile || !cafile[0]) { + cafile = BEARSSL_XBOX_DEFAULT_CA_FILE; + } + + /* Try loading CA bundle from PEM file */ + if(bearssl_xbox_load_ca_file(cafile, + &BACKEND->file_anchors, &BACKEND->file_anchor_count) == 0) { + trust_anchors = BACKEND->file_anchors; + trust_anchor_count = BACKEND->file_anchor_count; + infof(data, "BearSSL: Loaded %zu trust anchors from %s\n", + trust_anchor_count, cafile); + } + + /* Fall back to compiled-in trust anchors */ + if(!trust_anchors) { + trust_anchors = bearssl_xbox_get_trust_anchors(); + trust_anchor_count = bearssl_xbox_get_trust_anchor_count(); + } + } + + if(!trust_anchors || trust_anchor_count == 0) { + failf(data, "BearSSL: No trust anchors available for certificate verification"); + return CURLE_SSL_CACERT_BADFILE; + } + infof(data, "BearSSL: Using %zu trust anchors for verification\n", + trust_anchor_count); +#else + /* No trust anchors available - cannot verify */ + failf(data, "BearSSL: Certificate verification requested but no trust anchors available"); + return CURLE_SSL_CACERT_BADFILE; +#endif + + BACKEND->using_noanchor = 0; + /* Initialize the BearSSL client context with trust anchors */ + br_ssl_client_init_full(&BACKEND->sc, &BACKEND->xc_minimal, + trust_anchors, trust_anchor_count); + +#ifdef _XBOX + /* Skip certificate date validation - Xbox clock is unreliable */ + br_x509_minimal_set_time_callback(&BACKEND->xc_minimal, + NULL, bearssl_xbox_time_check); +#endif + } + + OutputDebugStringA("BearSSL: Setting protocol versions...\n"); + + /* Set protocol versions based on CURLOPT_SSLVERSION */ + { + /* + * Default to TLS 1.2 minimum for security. + * TLS 1.0 and 1.1 are deprecated and have known vulnerabilities. + */ + int min_ver = BR_TLS12; + int max_ver = BR_TLS12; + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_DEFAULT: + /* Default: TLS 1.2 only (most compatible + secure) */ + min_ver = BR_TLS12; + break; + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: + /* Allow TLS 1.0 if explicitly requested (legacy support) */ + min_ver = BR_TLS10; + break; + case CURL_SSLVERSION_TLSv1_1: + min_ver = BR_TLS11; + break; + case CURL_SSLVERSION_TLSv1_2: + min_ver = BR_TLS12; + break; + case CURL_SSLVERSION_TLSv1_3: + /* BearSSL doesn't support TLS 1.3 */ + failf(data, "BearSSL does not support TLS 1.3"); + return CURLE_SSL_CONNECT_ERROR; + default: + failf(data, "Unsupported SSL version"); + return CURLE_SSL_CONNECT_ERROR; + } + + br_ssl_engine_set_versions(&BACKEND->sc.eng, min_ver, max_ver); + } + OutputDebugStringA("BearSSL: Protocol versions set\n"); + + /* Use secure cipher suites only */ + br_ssl_engine_set_suites(&BACKEND->sc.eng, + bearssl_secure_suites, BEARSSL_SECURE_SUITES_COUNT); + OutputDebugStringA("BearSSL: Cipher suites set\n"); + + /* + * Set ALPN (Application-Layer Protocol Negotiation) protocols. + * + * This tells the server we want to speak HTTP/1.1. Without ALPN, modern + * servers like Cloudflare may reset the connection after handshake because + * they don't know what protocol the client expects. + */ + br_ssl_engine_set_protocol_names(&BACKEND->sc.eng, + bearssl_alpn_protocols, + BEARSSL_ALPN_PROTOCOLS_COUNT); + OutputDebugStringA("BearSSL: ALPN protocols set (http/1.1)\n"); + + /* Set I/O buffer */ + br_ssl_engine_set_buffer(&BACKEND->sc.eng, BACKEND->iobuf, + sizeof(BACKEND->iobuf), 1); + OutputDebugStringA("BearSSL: I/O buffer set\n"); + +#if BEARSSL_XBOX_INTEGRATION + /* Try to resume previous session */ + if(bearssl_xbox_session_get(hostname, &session_params)) { + br_ssl_engine_set_session_parameters(&BACKEND->sc.eng, &session_params); + memcpy(BACKEND->resume_master_secret, session_params.master_secret, 48); + session_resume = 1; + infof(data, "BearSSL: Attempting session resumption for %s\n", hostname); + } +#endif + + OutputDebugStringA("BearSSL: Calling br_ssl_client_reset...\n"); + + /* Reset the client context for the new connection */ + br_ssl_client_reset(&BACKEND->sc, hostname, session_resume); + + OutputDebugStringA("BearSSL: br_ssl_client_reset done\n"); + +#ifdef _XBOX + { + char dbg[256]; + msnprintf(dbg, sizeof(dbg), + "BearSSL step1: hostname=%s, socket=%d, sockindex=%d\n", + hostname, (int)conn->sock[sockindex], sockindex); + OutputDebugStringA(dbg); + + /* Verify socket is valid */ + if(conn->sock[sockindex] == CURL_SOCKET_BAD) { + OutputDebugStringA("BearSSL step1: ERROR - socket is INVALID!\n"); + } + } +#endif + + OutputDebugStringA("BearSSL: Calling br_sslio_init...\n"); + + /* Initialize the I/O wrapper */ + br_sslio_init(&BACKEND->ioc, &BACKEND->sc.eng, + sock_read, &conn->sock[sockindex], + sock_write, &conn->sock[sockindex]); + + OutputDebugStringA("BearSSL: br_sslio_init done\n"); + + /* Note: BACKEND->active is set in step3 after handshake completes */ + connssl->connecting_state = ssl_connect_2; + + OutputDebugStringA("BearSSL step1: complete, moving to step2\n"); + return CURLE_OK; +} + +static CURLcode +bearssl_connect_step2(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + unsigned state; + int err; + + state = br_ssl_engine_current_state(&BACKEND->sc.eng); + +#ifdef _XBOX + { + static int step2_call_count = 0; + char dbg[256]; + step2_call_count++; + msnprintf(dbg, sizeof(dbg), + "BearSSL step2 [%d]: state=0x%x (CLOSED=%d SENDREC=%d RECVREC=%d SENDAPP=%d)\n", + step2_call_count, state, + (state & BR_SSL_CLOSED) ? 1 : 0, + (state & BR_SSL_SENDREC) ? 1 : 0, + (state & BR_SSL_RECVREC) ? 1 : 0, + (state & BR_SSL_SENDAPP) ? 1 : 0); + OutputDebugStringA(dbg); + } +#endif + + /* Check for errors */ + err = br_ssl_engine_last_error(&BACKEND->sc.eng); + if(err != BR_ERR_OK) { +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL step2: engine error %d\n", err); + OutputDebugStringA(dbg); + } +#endif + failf(data, "BearSSL: %s (error %d)", bearssl_error_string(err), err); + return CURLE_SSL_CONNECT_ERROR; + } + + /* Check if handshake is complete */ + if(state & BR_SSL_SENDAPP) { + /* Handshake complete, application data can be sent */ + connssl->connecting_state = ssl_connect_3; + return CURLE_OK; + } + + /* Handshake still in progress */ + if(state & BR_SSL_SENDREC) { + /* Need to send data */ + int ret; + OutputDebugStringA("BearSSL step2: flushing send buffer...\n"); + ret = br_sslio_flush(&BACKEND->ioc); +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL step2: flush returned %d\n", ret); + OutputDebugStringA(dbg); + } +#endif + if(ret < 0) { + err = br_ssl_engine_last_error(&BACKEND->sc.eng); +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL step2: flush error, engine err=%d\n", err); + OutputDebugStringA(dbg); + } +#endif + if(err != BR_ERR_OK) { + failf(data, "BearSSL handshake: %s (error %d)", + bearssl_error_string(err), err); + return CURLE_SSL_CONNECT_ERROR; + } + } + } + + if(state & BR_SSL_RECVREC) { + /* Need to receive data - handled by sslio layer */ + unsigned char tmp[1]; + int ret; + OutputDebugStringA("BearSSL step2: attempting to receive...\n"); + ret = br_sslio_read(&BACKEND->ioc, tmp, 0); +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL step2: read returned %d\n", ret); + OutputDebugStringA(dbg); + } +#endif + if(ret < 0) { + err = br_ssl_engine_last_error(&BACKEND->sc.eng); +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL step2: read error, engine err=%d\n", err); + OutputDebugStringA(dbg); + } +#endif + if(err != BR_ERR_OK && err != BR_ERR_IO) { + failf(data, "BearSSL handshake: %s (error %d)", + bearssl_error_string(err), err); + return CURLE_SSL_CONNECT_ERROR; + } + } + } + + /* Check state again */ + state = br_ssl_engine_current_state(&BACKEND->sc.eng); + if(state & BR_SSL_SENDAPP) { + connssl->connecting_state = ssl_connect_3; + return CURLE_OK; + } + + /* Still connecting */ + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; +} + +static CURLcode +bearssl_connect_step3(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + br_ssl_session_parameters session_params; + unsigned version; + const char *version_str; + + /* Get negotiated TLS version */ + version = br_ssl_engine_get_version(&BACKEND->sc.eng); + switch(version) { + case BR_TLS10: version_str = "TLS 1.0"; break; + case BR_TLS11: version_str = "TLS 1.1"; break; + case BR_TLS12: version_str = "TLS 1.2"; break; + default: version_str = "Unknown"; break; + } + + /* Log ALPN negotiation result */ + { + const char *alpn_protocol; + alpn_protocol = br_ssl_engine_get_selected_protocol(&BACKEND->sc.eng); + if(alpn_protocol) { + infof(data, "BearSSL: ALPN negotiated protocol: %s\n", alpn_protocol); +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL: ALPN selected: %s\n", alpn_protocol); + OutputDebugStringA(dbg); + } +#endif + } + else { + infof(data, "BearSSL: ALPN not negotiated (server may not support it)\n"); +#ifdef _XBOX + OutputDebugStringA("BearSSL: ALPN not negotiated by server\n"); +#endif + } + } + + /* Check if session was resumed by comparing master secrets. + * Both ID-based and ticket-based (RFC 5077) resumption reuse the + * original master secret; a full handshake always derives a new one. */ + br_ssl_engine_get_session_parameters(&BACKEND->sc.eng, &session_params); + if(memcmp(BACKEND->resume_master_secret, session_params.master_secret, + 48) == 0 + && session_params.master_secret[0] != 0) { + BACKEND->session_resumed = 1; + } + infof(data, "BearSSL: %s connection using %s\n", + BACKEND->session_resumed ? "Resumed" : "New", version_str); +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL: %s connection using %s\n", + BACKEND->session_resumed ? "Resumed" : "New", version_str); + OutputDebugStringA(dbg); + } +#endif + +#if BEARSSL_XBOX_INTEGRATION + /* Store session for future resumption. + * Store if we have a session ID or a session ticket (RFC 5077). */ + if(session_params.session_id_len > 0 + || session_params.session_ticket_len > 0) { + bearssl_xbox_session_store(BACKEND->hostname, &session_params); + } + + /* Copy captured leaf certificate hash from X.509 callback. + * On resumed sessions, no X.509 validation runs so the hash won't + * be available — this is expected and not an error. */ + if(BACKEND->using_noanchor && BACKEND->xc_noanchor.leaf_hash_valid) { + memcpy(BACKEND->leaf_cert_hash, BACKEND->xc_noanchor.leaf_hash, 32); + BACKEND->leaf_cert_hash_valid = 1; +#ifdef _XBOX + { + char dbg[256]; + msnprintf(dbg, sizeof(dbg), + "BearSSL step3: Leaf cert SHA-256: " + "%02X%02X%02X%02X %02X%02X%02X%02X " + "%02X%02X%02X%02X %02X%02X%02X%02X " + "%02X%02X%02X%02X %02X%02X%02X%02X " + "%02X%02X%02X%02X %02X%02X%02X%02X\n", + BACKEND->leaf_cert_hash[0], BACKEND->leaf_cert_hash[1], + BACKEND->leaf_cert_hash[2], BACKEND->leaf_cert_hash[3], + BACKEND->leaf_cert_hash[4], BACKEND->leaf_cert_hash[5], + BACKEND->leaf_cert_hash[6], BACKEND->leaf_cert_hash[7], + BACKEND->leaf_cert_hash[8], BACKEND->leaf_cert_hash[9], + BACKEND->leaf_cert_hash[10], BACKEND->leaf_cert_hash[11], + BACKEND->leaf_cert_hash[12], BACKEND->leaf_cert_hash[13], + BACKEND->leaf_cert_hash[14], BACKEND->leaf_cert_hash[15], + BACKEND->leaf_cert_hash[16], BACKEND->leaf_cert_hash[17], + BACKEND->leaf_cert_hash[18], BACKEND->leaf_cert_hash[19], + BACKEND->leaf_cert_hash[20], BACKEND->leaf_cert_hash[21], + BACKEND->leaf_cert_hash[22], BACKEND->leaf_cert_hash[23], + BACKEND->leaf_cert_hash[24], BACKEND->leaf_cert_hash[25], + BACKEND->leaf_cert_hash[26], BACKEND->leaf_cert_hash[27], + BACKEND->leaf_cert_hash[28], BACKEND->leaf_cert_hash[29], + BACKEND->leaf_cert_hash[30], BACKEND->leaf_cert_hash[31]); + OutputDebugStringA(dbg); + } +#endif + } + else if(BACKEND->session_resumed) { +#ifdef _XBOX + OutputDebugStringA("BearSSL step3: Leaf cert hash not available (resumed session)\n"); +#endif + } +#endif + + /* Connection is now established - mark SSL as active for proper cleanup */ + /* + * CRITICAL: Register our SSL send/recv functions with libcurl. + * + * libcurl uses conn->recv[sockindex] and conn->send[sockindex] for all + * data transfer. If we don't set these to our BearSSL functions, libcurl + * will send raw unencrypted data over the TLS connection, causing the + * server to reset the connection. + * + * This was the root cause of the "connection reset after handshake" bug. + */ + conn->recv[sockindex] = bearssl_recv; + conn->send[sockindex] = bearssl_send; + +#ifdef _XBOX + OutputDebugStringA("BearSSL: Registered send/recv handlers with libcurl\n"); +#endif + + BACKEND->active = 1; + connssl->connecting_state = ssl_connect_done; + connssl->state = ssl_connection_complete; + + return CURLE_OK; +} + +static CURLcode +bearssl_connect_common(struct connectdata *conn, int sockindex, + bool nonblocking, bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + long timeout_ms; + int what; + + /* Check if already connected */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + timeout_ms = Curl_timeleft(data, NULL, TRUE); + if(timeout_ms < 0) { + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + result = bearssl_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state) { + timeout_ms = Curl_timeleft(data, NULL, TRUE); + if(timeout_ms < 0) { + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* Check socket readiness */ + what = Curl_socket_check(sockfd, CURL_SOCKET_BAD, sockfd, + nonblocking ? 0 : timeout_ms); + if(what < 0) { + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + + result = bearssl_connect_step2(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_3 == connssl->connecting_state) { + result = bearssl_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + *done = TRUE; + } + else { + *done = FALSE; + } + + return CURLE_OK; +} + +static CURLcode +Curl_bearssl_connect_blocking(struct connectdata *conn, int sockindex) +{ + bool done = FALSE; + CURLcode result; + + result = bearssl_connect_common(conn, sockindex, FALSE, &done); + if(result) + return result; + + DEBUGASSERT(done); + return CURLE_OK; +} + +static CURLcode +Curl_bearssl_connect_nonblocking(struct connectdata *conn, int sockindex, + bool *done) +{ + return bearssl_connect_common(conn, sockindex, TRUE, done); +} + +static void Curl_bearssl_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL close: sockindex=%d, state=%d, backend=%p\n", + sockindex, (int)connssl->state, (void*)BACKEND); + OutputDebugStringA(dbg); + } +#endif + + /* Free per-connection file-loaded trust anchors even if handshake didn't + * complete (e.g. step1 failed after loading CAs but before connecting). + * Must happen before the early-return guard below. */ +#if BEARSSL_XBOX_INTEGRATION + if(BACKEND && BACKEND->file_anchors) { + bearssl_xbox_free_loaded_anchors(BACKEND->file_anchors, + BACKEND->file_anchor_count); + BACKEND->file_anchors = NULL; + BACKEND->file_anchor_count = 0; + } +#endif + + /* Only cleanup SSL state if it was actually initialized */ + if(connssl->state == ssl_connection_none) + return; + + if(BACKEND) { + if(BACKEND->active) { + /* + * Attempt graceful TLS close only if the connection is still healthy. + * br_sslio_close() sends a close_notify alert, which calls sock_write(). + * If the socket is dead, sock_write() fails and BearSSL's I/O state + * becomes inconsistent, causing heap corruption. Guard against this by + * checking io_error (set by bearssl_send/recv on failure), the engine + * error code, and the engine closed flag. + */ + int err = br_ssl_engine_last_error(&BACKEND->sc.eng); + unsigned state = br_ssl_engine_current_state(&BACKEND->sc.eng); + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL close: io_error=%d, err=%d, state=0x%x\n", + BACKEND->io_error, err, state); + OutputDebugStringA(dbg); + } +#endif + + if(!BACKEND->io_error && err == BR_ERR_OK && !(state & BR_SSL_CLOSED)) { + br_sslio_close(&BACKEND->ioc); + } + BACKEND->active = 0; + } + /* + * NOTE: Do NOT free BACKEND! The vtls layer allocates all backend memory + * as a single block in url.c:allocate_conn(). Freeing BACKEND here would + * corrupt the heap because it's an offset into a larger allocation. + * + * Just clear the backend data to prepare for potential reuse. + */ +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL: Clearing backend at %p (NOT freeing - vtls manages memory)\n", + (void*)BACKEND); + OutputDebugStringA(dbg); + } +#endif + + /* file_anchors already freed above (before early-return guard) */ + + /* Clear backend data but do NOT free (vtls owns the memory) */ + memset(BACKEND, 0, sizeof(struct ssl_backend_data)); + } + + /* Reset state */ + connssl->state = ssl_connection_none; + connssl->connecting_state = ssl_connect_1; +} + +static void Curl_bearssl_close_all(struct Curl_easy *data) +{ + (void)data; +} + +static int Curl_bearssl_shutdown(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + +#ifdef _XBOX + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), + "BearSSL shutdown: sockindex=%d, state=%d, backend=%p\n", + sockindex, (int)connssl->state, (void*)BACKEND); + OutputDebugStringA(dbg); + } +#endif + + /* Only shutdown if SSL was actually initialized */ + if(connssl->state == ssl_connection_none) + return 0; + + /* Check BACKEND exists before accessing it */ + if(!BACKEND) + return 0; + + if(BACKEND->active) { + /* + * Only attempt graceful TLS close if no I/O errors occurred. + * Avoid trying to send close_notify on a dead socket. + */ + int err = br_ssl_engine_last_error(&BACKEND->sc.eng); + unsigned state = br_ssl_engine_current_state(&BACKEND->sc.eng); + + if(!BACKEND->io_error && err == BR_ERR_OK && !(state & BR_SSL_CLOSED)) { + br_sslio_close(&BACKEND->ioc); + } + BACKEND->active = 0; + } + + return 0; +} + +static ssize_t bearssl_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + int ret; + int flush_ret; + + /* Defensive check - BACKEND must be valid */ + if(!BACKEND || !BACKEND->active) { + OutputDebugStringA("bearssl_send: BACKEND invalid, returning error\n"); + *curlcode = CURLE_SEND_ERROR; + return -1; + } + +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL send: len=%u, active=%d\n", + (unsigned)len, BACKEND->active); + OutputDebugStringA(dbg); + } +#endif + + ret = br_sslio_write(&BACKEND->ioc, mem, len); + +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[128]; + int err = br_ssl_engine_last_error(&BACKEND->sc.eng); + unsigned state = br_ssl_engine_current_state(&BACKEND->sc.eng); + msnprintf(dbg, sizeof(dbg), "BearSSL send: write returned %d, err=%d, state=0x%x\n", + ret, err, state); + OutputDebugStringA(dbg); + } +#endif + + if(ret < 0) { + int err = br_ssl_engine_last_error(&BACKEND->sc.eng); + /* Mark that we've had an I/O error - skip graceful close later */ + BACKEND->io_error = 1; + if(err == BR_ERR_OK || err == BR_ERR_IO) { + *curlcode = CURLE_AGAIN; + } + else { + *curlcode = CURLE_SEND_ERROR; + } + return -1; + } + + /* Flush the data to ensure it's sent immediately */ + flush_ret = br_sslio_flush(&BACKEND->ioc); + +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL send: flush returned %d\n", flush_ret); + OutputDebugStringA(dbg); + } +#endif + + if(flush_ret < 0) { + BACKEND->io_error = 1; + } + + return (ssize_t)ret; +} + +static ssize_t bearssl_recv(struct connectdata *conn, int sockindex, + char *buf, size_t buffersize, CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + int ret; + + /* Defensive check - BACKEND must be valid */ + if(!BACKEND || !BACKEND->active) { + OutputDebugStringA("bearssl_recv: BACKEND invalid, returning error\n"); + *curlcode = CURLE_RECV_ERROR; + return -1; + } + +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL recv: buffersize=%u, active=%d\n", + (unsigned)buffersize, BACKEND->active); + OutputDebugStringA(dbg); + } +#endif + + ret = br_sslio_read(&BACKEND->ioc, buf, buffersize); + +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[128]; + int err = br_ssl_engine_last_error(&BACKEND->sc.eng); + unsigned state = br_ssl_engine_current_state(&BACKEND->sc.eng); + msnprintf(dbg, sizeof(dbg), "BearSSL recv: read returned %d, err=%d, state=0x%x\n", + ret, err, state); + OutputDebugStringA(dbg); + } +#endif + + if(ret < 0) { + int err = br_ssl_engine_last_error(&BACKEND->sc.eng); + /* Mark that we've had an I/O error - skip graceful close later */ + BACKEND->io_error = 1; +#ifdef BEARSSL_VERBOSE_DEBUG + { + char dbg[128]; + msnprintf(dbg, sizeof(dbg), "BearSSL recv: ERROR - setting io_error=1, err=%d\n", err); + OutputDebugStringA(dbg); + } +#endif + if(err == BR_ERR_OK || err == BR_ERR_IO) { + *curlcode = CURLE_AGAIN; + } + else { + *curlcode = CURLE_RECV_ERROR; + } + return -1; + } + + return (ssize_t)ret; +} + +static bool Curl_bearssl_data_pending(const struct connectdata *conn, + int sockindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + unsigned state; + + /* Check if SSL was initialized before accessing BACKEND */ + if(connssl->state == ssl_connection_none) + return FALSE; + + if(!BACKEND || !BACKEND->active) + return FALSE; + + state = br_ssl_engine_current_state(&BACKEND->sc.eng); + return (state & BR_SSL_RECVAPP) ? TRUE : FALSE; +} + +static int Curl_bearssl_check_cxn(struct connectdata *conn) +{ + struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; + int err; + + /* Check if SSL was initialized before accessing BACKEND */ + if(connssl->state == ssl_connection_none) + return 0; + + if(!BACKEND || !BACKEND->active) + return 0; + + err = br_ssl_engine_last_error(&BACKEND->sc.eng); + return (err == BR_ERR_OK) ? 1 : 0; +} + +static void *Curl_bearssl_get_internals(struct ssl_connect_data *connssl, + CURLINFO info) +{ + (void)info; + /* Check if SSL was initialized before accessing BACKEND */ + if(connssl->state == ssl_connection_none) + return NULL; + return BACKEND ? &BACKEND->sc : NULL; +} + +static void Curl_bearssl_session_free(void *ptr) +{ + (void)ptr; + /* BearSSL session handling is different; no dynamic session objects */ +} + +const struct Curl_ssl Curl_ssl_bearssl = { + { CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */ + SSLSUPP_CA_PATH | + SSLSUPP_SSL_CTX, /* supports */ + sizeof(struct ssl_backend_data), + + Curl_bearssl_init, /* init */ + Curl_bearssl_cleanup, /* cleanup */ + Curl_bearssl_version, /* version */ + Curl_bearssl_check_cxn, /* check_cxn */ + Curl_bearssl_shutdown, /* shutdown */ + Curl_bearssl_data_pending, /* data_pending */ + Curl_bearssl_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_bearssl_connect_blocking, /* connect_blocking */ + Curl_bearssl_connect_nonblocking, /* connect_nonblocking */ + Curl_bearssl_get_internals, /* get_internals */ + Curl_bearssl_close, /* close_one */ + Curl_bearssl_close_all, /* close_all */ + Curl_bearssl_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_none_md5sum, /* md5sum */ + NULL /* sha256sum */ +}; + +#endif /* USE_BEARSSL */ diff --git a/libcurl/lib/vtls/bearssl.h b/libcurl/lib/vtls/bearssl.h new file mode 100644 index 0000000..a008d58 --- /dev/null +++ b/libcurl/lib/vtls/bearssl.h @@ -0,0 +1,21 @@ +#ifndef HEADER_CURL_BEARSSL_H +#define HEADER_CURL_BEARSSL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * BearSSL TLS backend for libcurl + * Designed for Xbox (Visual Studio 2003 / C89 compatible) + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_BEARSSL + +extern const struct Curl_ssl Curl_ssl_bearssl; + +#endif /* USE_BEARSSL */ +#endif /* HEADER_CURL_BEARSSL_H */ diff --git a/libcurl/lib/vtls/bearssl_ssl.h b/libcurl/lib/vtls/bearssl_ssl.h new file mode 100644 index 0000000..a5911f8 --- /dev/null +++ b/libcurl/lib/vtls/bearssl_ssl.h @@ -0,0 +1,4306 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BR_BEARSSL_SSL_H__ +#define BR_BEARSSL_SSL_H__ + +#include +#include + +#include "bearssl_block.h" +#include "bearssl_hash.h" +#include "bearssl_hmac.h" +#include "bearssl_prf.h" +#include "bearssl_rand.h" +#include "bearssl_x509.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_ssl.h + * + * # SSL + * + * For an overview of the SSL/TLS API, see [the BearSSL Web + * site](https://www.bearssl.org/api1.html). + * + * The `BR_TLS_*` constants correspond to the standard cipher suites and + * their values in the [IANA + * registry](http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4). + * + * The `BR_ALERT_*` constants are for standard TLS alert messages. When + * a fatal alert message is sent of received, then the SSL engine context + * status is set to the sum of that alert value (an integer in the 0..255 + * range) and a fixed offset (`BR_ERR_SEND_FATAL_ALERT` for a sent alert, + * `BR_ERR_RECV_FATAL_ALERT` for a received alert). + */ + +/** \brief Optimal input buffer size. */ +#define BR_SSL_BUFSIZE_INPUT (16384 + 325) + +/** \brief Optimal output buffer size. */ +#define BR_SSL_BUFSIZE_OUTPUT (16384 + 85) + +/** \brief Optimal buffer size for monodirectional engine + (shared input/output buffer). */ +#define BR_SSL_BUFSIZE_MONO BR_SSL_BUFSIZE_INPUT + +/** \brief Optimal buffer size for bidirectional engine + (single buffer split into two separate input/output buffers). */ +#define BR_SSL_BUFSIZE_BIDI (BR_SSL_BUFSIZE_INPUT + BR_SSL_BUFSIZE_OUTPUT) + +/* + * Constants for known SSL/TLS protocol versions (SSL 3.0, TLS 1.0, TLS 1.1 + * and TLS 1.2). Note that though there is a constant for SSL 3.0, that + * protocol version is not actually supported. + */ + +/** \brief Protocol version: SSL 3.0 (unsupported). */ +#define BR_SSL30 0x0300 +/** \brief Protocol version: TLS 1.0. */ +#define BR_TLS10 0x0301 +/** \brief Protocol version: TLS 1.1. */ +#define BR_TLS11 0x0302 +/** \brief Protocol version: TLS 1.2. */ +#define BR_TLS12 0x0303 + +/* + * Error constants. They are used to report the reason why a context has + * been marked as failed. + * + * Implementation note: SSL-level error codes should be in the 1..31 + * range. The 32..63 range is for certificate decoding and validation + * errors. Received fatal alerts imply an error code in the 256..511 range. + */ + +/** \brief SSL status: no error so far (0). */ +#define BR_ERR_OK 0 + +/** \brief SSL status: caller-provided parameter is incorrect. */ +#define BR_ERR_BAD_PARAM 1 + +/** \brief SSL status: operation requested by the caller cannot be applied + with the current context state (e.g. reading data while outgoing data + is waiting to be sent). */ +#define BR_ERR_BAD_STATE 2 + +/** \brief SSL status: incoming protocol or record version is unsupported. */ +#define BR_ERR_UNSUPPORTED_VERSION 3 + +/** \brief SSL status: incoming record version does not match the expected + version. */ +#define BR_ERR_BAD_VERSION 4 + +/** \brief SSL status: incoming record length is invalid. */ +#define BR_ERR_BAD_LENGTH 5 + +/** \brief SSL status: incoming record is too large to be processed, or + buffer is too small for the handshake message to send. */ +#define BR_ERR_TOO_LARGE 6 + +/** \brief SSL status: decryption found an invalid padding, or the record + MAC is not correct. */ +#define BR_ERR_BAD_MAC 7 + +/** \brief SSL status: no initial entropy was provided, and none can be + obtained from the OS. */ +#define BR_ERR_NO_RANDOM 8 + +/** \brief SSL status: incoming record type is unknown. */ +#define BR_ERR_UNKNOWN_TYPE 9 + +/** \brief SSL status: incoming record or message has wrong type with + regards to the current engine state. */ +#define BR_ERR_UNEXPECTED 10 + +/** \brief SSL status: ChangeCipherSpec message from the peer has invalid + contents. */ +#define BR_ERR_BAD_CCS 12 + +/** \brief SSL status: alert message from the peer has invalid contents + (odd length). */ +#define BR_ERR_BAD_ALERT 13 + +/** \brief SSL status: incoming handshake message decoding failed. */ +#define BR_ERR_BAD_HANDSHAKE 14 + +/** \brief SSL status: ServerHello contains a session ID which is larger + than 32 bytes. */ +#define BR_ERR_OVERSIZED_ID 15 + +/** \brief SSL status: server wants to use a cipher suite that we did + not claim to support. This is also reported if we tried to advertise + a cipher suite that we do not support. */ +#define BR_ERR_BAD_CIPHER_SUITE 16 + +/** \brief SSL status: server wants to use a compression that we did not + claim to support. */ +#define BR_ERR_BAD_COMPRESSION 17 + +/** \brief SSL status: server's max fragment length does not match + client's. */ +#define BR_ERR_BAD_FRAGLEN 18 + +/** \brief SSL status: secure renegotiation failed. */ +#define BR_ERR_BAD_SECRENEG 19 + +/** \brief SSL status: server sent an extension type that we did not + announce, or used the same extension type several times in a single + ServerHello. */ +#define BR_ERR_EXTRA_EXTENSION 20 + +/** \brief SSL status: invalid Server Name Indication contents (when + used by the server, this extension shall be empty). */ +#define BR_ERR_BAD_SNI 21 + +/** \brief SSL status: invalid ServerHelloDone from the server (length + is not 0). */ +#define BR_ERR_BAD_HELLO_DONE 22 + +/** \brief SSL status: internal limit exceeded (e.g. server's public key + is too large). */ +#define BR_ERR_LIMIT_EXCEEDED 23 + +/** \brief SSL status: Finished message from peer does not match the + expected value. */ +#define BR_ERR_BAD_FINISHED 24 + +/** \brief SSL status: session resumption attempt with distinct version + or cipher suite. */ +#define BR_ERR_RESUME_MISMATCH 25 + +/** \brief SSL status: unsupported or invalid algorithm (ECDHE curve, + signature algorithm, hash function). */ +#define BR_ERR_INVALID_ALGORITHM 26 + +/** \brief SSL status: invalid signature (on ServerKeyExchange from + server, or in CertificateVerify from client). */ +#define BR_ERR_BAD_SIGNATURE 27 + +/** \brief SSL status: peer's public key does not have the proper type + or is not allowed for requested operation. */ +#define BR_ERR_WRONG_KEY_USAGE 28 + +/** \brief SSL status: client did not send a certificate upon request, + or the client certificate could not be validated. */ +#define BR_ERR_NO_CLIENT_AUTH 29 + +/** \brief SSL status: I/O error or premature close on underlying + transport stream. This error code is set only by the simplified + I/O API ("br_sslio_*"). */ +#define BR_ERR_IO 31 + +/** \brief SSL status: base value for a received fatal alert. + + When a fatal alert is received from the peer, the alert value + is added to this constant. */ +#define BR_ERR_RECV_FATAL_ALERT 256 + +/** \brief SSL status: base value for a sent fatal alert. + + When a fatal alert is sent to the peer, the alert value is added + to this constant. */ +#define BR_ERR_SEND_FATAL_ALERT 512 + +/* ===================================================================== */ + +/** + * \brief Decryption engine for SSL. + * + * When processing incoming records, the SSL engine will use a decryption + * engine that uses a specific context structure, and has a set of + * methods (a vtable) that follows this template. + * + * The decryption engine is responsible for applying decryption, verifying + * MAC, and keeping track of the record sequence number. + */ +typedef struct br_sslrec_in_class_ br_sslrec_in_class; +struct br_sslrec_in_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Test validity of the incoming record length. + * + * This function returns 1 if the announced length for an + * incoming record is valid, 0 otherwise, + * + * \param ctx decryption engine context. + * \param record_len incoming record length. + * \return 1 of a valid length, 0 otherwise. + */ + int (*check_length)(const br_sslrec_in_class *const *ctx, + size_t record_len); + + /** + * \brief Decrypt the incoming record. + * + * This function may assume that the record length is valid + * (it has been previously tested with `check_length()`). + * Decryption is done in place; `*len` is updated with the + * cleartext length, and the address of the first plaintext + * byte is returned. If the record is correct but empty, then + * `*len` is set to 0 and a non-`NULL` pointer is returned. + * + * On decryption/MAC error, `NULL` is returned. + * + * \param ctx decryption engine context. + * \param record_type record type (23 for application data, etc). + * \param version record version. + * \param payload address of encrypted payload. + * \param len pointer to payload length (updated). + * \return pointer to plaintext, or `NULL` on error. + */ + unsigned char *(*decrypt)(const br_sslrec_in_class **ctx, + int record_type, unsigned version, + void *payload, size_t *len); +}; + +/** + * \brief Encryption engine for SSL. + * + * When building outgoing records, the SSL engine will use an encryption + * engine that uses a specific context structure, and has a set of + * methods (a vtable) that follows this template. + * + * The encryption engine is responsible for applying encryption and MAC, + * and keeping track of the record sequence number. + */ +typedef struct br_sslrec_out_class_ br_sslrec_out_class; +struct br_sslrec_out_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Compute maximum plaintext sizes and offsets. + * + * When this function is called, the `*start` and `*end` + * values contain offsets designating the free area in the + * outgoing buffer for plaintext data; that free area is + * preceded by a 5-byte space which will receive the record + * header. + * + * The `max_plaintext()` function is responsible for adjusting + * both `*start` and `*end` to make room for any record-specific + * header, MAC, padding, and possible split. + * + * \param ctx encryption engine context. + * \param start pointer to start of plaintext offset (updated). + * \param end pointer to start of plaintext offset (updated). + */ + void (*max_plaintext)(const br_sslrec_out_class *const *ctx, + size_t *start, size_t *end); + + /** + * \brief Perform record encryption. + * + * This function encrypts the record. The plaintext address and + * length are provided. Returned value is the start of the + * encrypted record (or sequence of records, if a split was + * performed), _including_ the 5-byte header, and `*len` is + * adjusted to the total size of the record(s), there again + * including the header(s). + * + * \param ctx decryption engine context. + * \param record_type record type (23 for application data, etc). + * \param version record version. + * \param plaintext address of plaintext. + * \param len pointer to plaintext length (updated). + * \return pointer to start of built record. + */ + unsigned char *(*encrypt)(const br_sslrec_out_class **ctx, + int record_type, unsigned version, + void *plaintext, size_t *len); +}; + +/** + * \brief Context for a no-encryption engine. + * + * The no-encryption engine processes outgoing records during the initial + * handshake, before encryption is applied. + */ +typedef struct { + /** \brief No-encryption engine vtable. */ + const br_sslrec_out_class *vtable; +} br_sslrec_out_clear_context; + +/** \brief Static, constant vtable for the no-encryption engine. */ +extern const br_sslrec_out_class br_sslrec_out_clear_vtable; + +/* ===================================================================== */ + +/** + * \brief Record decryption engine class, for CBC mode. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for CBC processing: block cipher implementation, block cipher key, + * HMAC parameters (hash function, key, MAC length), and IV. If the + * IV is `NULL`, then a per-record IV will be used (TLS 1.1+). + */ +typedef struct br_sslrec_in_cbc_class_ br_sslrec_in_cbc_class; +struct br_sslrec_in_cbc_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CBC decryption). + * \param bc_key block cipher key. + * \param bc_key_len block cipher key length (in bytes). + * \param dig_impl hash function for HMAC. + * \param mac_key HMAC key. + * \param mac_key_len HMAC key length (in bytes). + * \param mac_out_len HMAC output length (in bytes). + * \param iv initial IV (or `NULL`). + */ + void (*init)(const br_sslrec_in_cbc_class **ctx, + const br_block_cbcdec_class *bc_impl, + const void *bc_key, size_t bc_key_len, + const br_hash_class *dig_impl, + const void *mac_key, size_t mac_key_len, size_t mac_out_len, + const void *iv); +}; + +/** + * \brief Record encryption engine class, for CBC mode. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for CBC processing: block cipher implementation, block cipher key, + * HMAC parameters (hash function, key, MAC length), and IV. If the + * IV is `NULL`, then a per-record IV will be used (TLS 1.1+). + */ +typedef struct br_sslrec_out_cbc_class_ br_sslrec_out_cbc_class; +struct br_sslrec_out_cbc_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CBC encryption). + * \param bc_key block cipher key. + * \param bc_key_len block cipher key length (in bytes). + * \param dig_impl hash function for HMAC. + * \param mac_key HMAC key. + * \param mac_key_len HMAC key length (in bytes). + * \param mac_out_len HMAC output length (in bytes). + * \param iv initial IV (or `NULL`). + */ + void (*init)(const br_sslrec_out_cbc_class **ctx, + const br_block_cbcenc_class *bc_impl, + const void *bc_key, size_t bc_key_len, + const br_hash_class *dig_impl, + const void *mac_key, size_t mac_key_len, size_t mac_out_len, + const void *iv); +}; + +/** + * \brief Context structure for decrypting incoming records with + * CBC + HMAC. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_sslrec_in_cbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_cbcdec_class *vtable; + br_aes_gen_cbcdec_keys aes; + br_des_gen_cbcdec_keys des; + } bc; + br_hmac_key_context mac; + size_t mac_len; + unsigned char iv[16]; + int explicit_IV; +#endif +} br_sslrec_in_cbc_context; + +/** + * \brief Static, constant vtable for record decryption with CBC. + */ +extern const br_sslrec_in_cbc_class br_sslrec_in_cbc_vtable; + +/** + * \brief Context structure for encrypting outgoing records with + * CBC + HMAC. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_sslrec_out_cbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_cbcenc_class *vtable; + br_aes_gen_cbcenc_keys aes; + br_des_gen_cbcenc_keys des; + } bc; + br_hmac_key_context mac; + size_t mac_len; + unsigned char iv[16]; + int explicit_IV; +#endif +} br_sslrec_out_cbc_context; + +/** + * \brief Static, constant vtable for record encryption with CBC. + */ +extern const br_sslrec_out_cbc_class br_sslrec_out_cbc_vtable; + +/* ===================================================================== */ + +/** + * \brief Record decryption engine class, for GCM mode. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for GCM processing: block cipher implementation, block cipher key, + * GHASH implementation, and 4-byte IV. + */ +typedef struct br_sslrec_in_gcm_class_ br_sslrec_in_gcm_class; +struct br_sslrec_in_gcm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param gh_impl GHASH implementation. + * \param iv static IV (4 bytes). + */ + void (*init)(const br_sslrec_in_gcm_class **ctx, + const br_block_ctr_class *bc_impl, + const void *key, size_t key_len, + br_ghash gh_impl, + const void *iv); +}; + +/** + * \brief Record encryption engine class, for GCM mode. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for GCM processing: block cipher implementation, block cipher key, + * GHASH implementation, and 4-byte IV. + */ +typedef struct br_sslrec_out_gcm_class_ br_sslrec_out_gcm_class; +struct br_sslrec_out_gcm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param gh_impl GHASH implementation. + * \param iv static IV (4 bytes). + */ + void (*init)(const br_sslrec_out_gcm_class **ctx, + const br_block_ctr_class *bc_impl, + const void *key, size_t key_len, + br_ghash gh_impl, + const void *iv); +}; + +/** + * \brief Context structure for processing records with GCM. + * + * The same context structure is used for encrypting and decrypting. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + union { + const void *gen; + const br_sslrec_in_gcm_class *in; + const br_sslrec_out_gcm_class *out; + } vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_ctr_class *vtable; + br_aes_gen_ctr_keys aes; + } bc; + br_ghash gh; + unsigned char iv[4]; + unsigned char h[16]; +#endif +} br_sslrec_gcm_context; + +/** + * \brief Static, constant vtable for record decryption with GCM. + */ +extern const br_sslrec_in_gcm_class br_sslrec_in_gcm_vtable; + +/** + * \brief Static, constant vtable for record encryption with GCM. + */ +extern const br_sslrec_out_gcm_class br_sslrec_out_gcm_vtable; + +/* ===================================================================== */ + +/** + * \brief Record decryption engine class, for ChaCha20+Poly1305. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for ChaCha20+Poly1305 processing: ChaCha20 implementation, + * Poly1305 implementation, key, and 12-byte IV. + */ +typedef struct br_sslrec_in_chapol_class_ br_sslrec_in_chapol_class; +struct br_sslrec_in_chapol_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param ichacha ChaCha20 implementation. + * \param ipoly Poly1305 implementation. + * \param key secret key (32 bytes). + * \param iv static IV (12 bytes). + */ + void (*init)(const br_sslrec_in_chapol_class **ctx, + br_chacha20_run ichacha, + br_poly1305_run ipoly, + const void *key, const void *iv); +}; + +/** + * \brief Record encryption engine class, for ChaCha20+Poly1305. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for ChaCha20+Poly1305 processing: ChaCha20 implementation, + * Poly1305 implementation, key, and 12-byte IV. + */ +typedef struct br_sslrec_out_chapol_class_ br_sslrec_out_chapol_class; +struct br_sslrec_out_chapol_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param ichacha ChaCha20 implementation. + * \param ipoly Poly1305 implementation. + * \param key secret key (32 bytes). + * \param iv static IV (12 bytes). + */ + void (*init)(const br_sslrec_out_chapol_class **ctx, + br_chacha20_run ichacha, + br_poly1305_run ipoly, + const void *key, const void *iv); +}; + +/** + * \brief Context structure for processing records with ChaCha20+Poly1305. + * + * The same context structure is used for encrypting and decrypting. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + union { + const void *gen; + const br_sslrec_in_chapol_class *in; + const br_sslrec_out_chapol_class *out; + } vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + unsigned char key[32]; + unsigned char iv[12]; + br_chacha20_run ichacha; + br_poly1305_run ipoly; +#endif +} br_sslrec_chapol_context; + +/** + * \brief Static, constant vtable for record decryption with ChaCha20+Poly1305. + */ +extern const br_sslrec_in_chapol_class br_sslrec_in_chapol_vtable; + +/** + * \brief Static, constant vtable for record encryption with ChaCha20+Poly1305. + */ +extern const br_sslrec_out_chapol_class br_sslrec_out_chapol_vtable; + +/* ===================================================================== */ + +/** + * \brief Record decryption engine class, for CCM mode. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for CCM processing: block cipher implementation, block cipher key, + * and 4-byte IV. + */ +typedef struct br_sslrec_in_ccm_class_ br_sslrec_in_ccm_class; +struct br_sslrec_in_ccm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR+CBC). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param iv static IV (4 bytes). + * \param tag_len tag length (in bytes) + */ + void (*init)(const br_sslrec_in_ccm_class **ctx, + const br_block_ctrcbc_class *bc_impl, + const void *key, size_t key_len, + const void *iv, size_t tag_len); +}; + +/** + * \brief Record encryption engine class, for CCM mode. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for CCM processing: block cipher implementation, block cipher key, + * and 4-byte IV. + */ +typedef struct br_sslrec_out_ccm_class_ br_sslrec_out_ccm_class; +struct br_sslrec_out_ccm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR+CBC). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param iv static IV (4 bytes). + * \param tag_len tag length (in bytes) + */ + void (*init)(const br_sslrec_out_ccm_class **ctx, + const br_block_ctrcbc_class *bc_impl, + const void *key, size_t key_len, + const void *iv, size_t tag_len); +}; + +/** + * \brief Context structure for processing records with CCM. + * + * The same context structure is used for encrypting and decrypting. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + union { + const void *gen; + const br_sslrec_in_ccm_class *in; + const br_sslrec_out_ccm_class *out; + } vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_ctrcbc_class *vtable; + br_aes_gen_ctrcbc_keys aes; + } bc; + unsigned char iv[4]; + size_t tag_len; +#endif +} br_sslrec_ccm_context; + +/** + * \brief Static, constant vtable for record decryption with CCM. + */ +extern const br_sslrec_in_ccm_class br_sslrec_in_ccm_vtable; + +/** + * \brief Static, constant vtable for record encryption with CCM. + */ +extern const br_sslrec_out_ccm_class br_sslrec_out_ccm_vtable; + +/* ===================================================================== */ + +/** + * \brief Type for session parameters, to be saved for session resumption. + */ +typedef struct { + /** \brief Session ID buffer. */ + unsigned char session_id[32]; + /** \brief Session ID length (in bytes, at most 32). */ + unsigned char session_id_len; + /** \brief Protocol version. */ + uint16_t version; + /** \brief Cipher suite. */ + uint16_t cipher_suite; + /** \brief Master secret. */ + unsigned char master_secret[48]; + /** \brief Session ticket (RFC 5077), opaque blob from server. */ + unsigned char session_ticket[1024]; + /** \brief Session ticket length (0 if no ticket). */ + uint16_t session_ticket_len; +} br_ssl_session_parameters; + +#ifndef BR_DOXYGEN_IGNORE +/* + * Maximum number of cipher suites supported by a client or server. + */ +#define BR_MAX_CIPHER_SUITES 48 +#endif + +/** + * \brief Context structure for SSL engine. + * + * This strucuture is common to the client and server; both the client + * context (`br_ssl_client_context`) and the server context + * (`br_ssl_server_context`) include a `br_ssl_engine_context` as their + * first field. + * + * The engine context manages records, including alerts, closures, and + * transitions to new encryption/MAC algorithms. Processing of handshake + * records is delegated to externally provided code. This structure + * should not be used directly. + * + * Structure contents are opaque and shall not be accessed directly. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + /* + * The error code. When non-zero, then the state is "failed" and + * no I/O may occur until reset. + */ + int err; + + /* + * Configured I/O buffers. They are either disjoint, or identical. + */ + unsigned char *ibuf, *obuf; + size_t ibuf_len, obuf_len; + + /* + * Maximum fragment length applies to outgoing records; incoming + * records can be processed as long as they fit in the input + * buffer. It is guaranteed that incoming records at least as big + * as max_frag_len can be processed. + */ + uint16_t max_frag_len; + unsigned char log_max_frag_len; + unsigned char peer_log_max_frag_len; + + /* + * Buffering management registers. + */ + size_t ixa, ixb, ixc; + size_t oxa, oxb, oxc; + unsigned char iomode; + unsigned char incrypt; + + /* + * Shutdown flag: when set to non-zero, incoming record bytes + * will not be accepted anymore. This is used after a close_notify + * has been received: afterwards, the engine no longer claims that + * it could receive bytes from the transport medium. + */ + unsigned char shutdown_recv; + + /* + * 'record_type_in' is set to the incoming record type when the + * record header has been received. + * 'record_type_out' is used to make the next outgoing record + * header when it is ready to go. + */ + unsigned char record_type_in, record_type_out; + + /* + * When a record is received, its version is extracted: + * -- if 'version_in' is 0, then it is set to the received version; + * -- otherwise, if the received version is not identical to + * the 'version_in' contents, then a failure is reported. + * + * This implements the SSL requirement that all records shall + * use the negotiated protocol version, once decided (in the + * ServerHello). It is up to the handshake handler to adjust this + * field when necessary. + */ + uint16_t version_in; + + /* + * 'version_out' is used when the next outgoing record is ready + * to go. + */ + uint16_t version_out; + + /* + * Record handler contexts. + */ + union { + const br_sslrec_in_class *vtable; + br_sslrec_in_cbc_context cbc; + br_sslrec_gcm_context gcm; + br_sslrec_chapol_context chapol; + br_sslrec_ccm_context ccm; + } in; + union { + const br_sslrec_out_class *vtable; + br_sslrec_out_clear_context clear; + br_sslrec_out_cbc_context cbc; + br_sslrec_gcm_context gcm; + br_sslrec_chapol_context chapol; + br_sslrec_ccm_context ccm; + } out; + + /* + * The "application data" flag. Value: + * 0 handshake is in process, no application data acceptable + * 1 application data can be sent and received + * 2 closing, no application data can be sent, but some + * can still be received (and discarded) + */ + unsigned char application_data; + + /* + * Context RNG. + * + * rng_init_done is initially 0. It is set to 1 when the + * basic structure of the RNG is set, and 2 when some + * entropy has been pushed in. The value 2 marks the RNG + * as "properly seeded". + * + * rng_os_rand_done is initially 0. It is set to 1 when + * some seeding from the OS or hardware has been attempted. + */ + br_hmac_drbg_context rng; + int rng_init_done; + int rng_os_rand_done; + + /* + * Supported minimum and maximum versions, and cipher suites. + */ + uint16_t version_min; + uint16_t version_max; + uint16_t suites_buf[BR_MAX_CIPHER_SUITES]; + unsigned char suites_num; + + /* + * For clients, the server name to send as a SNI extension. For + * servers, the name received in the SNI extension (if any). + */ + char server_name[256]; + + /* + * "Security parameters". These are filled by the handshake + * handler, and used when switching encryption state. + */ + unsigned char client_random[32]; + unsigned char server_random[32]; + br_ssl_session_parameters session; + + /* + * ECDHE elements: curve and point from the peer. The server also + * uses that buffer for the point to send to the client. + */ + unsigned char ecdhe_curve; + unsigned char ecdhe_point[133]; + unsigned char ecdhe_point_len; + + /* + * Secure renegotiation (RFC 5746): 'reneg' can be: + * 0 first handshake (server support is not known) + * 1 peer does not support secure renegotiation + * 2 peer supports secure renegotiation + * + * The saved_finished buffer contains the client and the + * server "Finished" values from the last handshake, in + * that order (12 bytes each). + */ + unsigned char reneg; + unsigned char saved_finished[24]; + + /* + * Session ticket (RFC 5077) support flag. Set to 1 when the + * server confirms ticket support in its ServerHello extensions. + */ + unsigned char session_ticket_ok; + + /* + * Behavioural flags. + */ + uint32_t flags; + + /* + * Context variables for the handshake processor. The 'pad' must + * be large enough to accommodate an RSA-encrypted pre-master + * secret, or an RSA signature; since we want to support up to + * RSA-4096, this means at least 512 bytes. (Other pad usages + * require its length to be at least 256.) + */ + struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; + } cpu; + uint32_t dp_stack[32]; + uint32_t rp_stack[32]; + unsigned char pad[512]; + unsigned char *hbuf_in, *hbuf_out, *saved_hbuf_out; + size_t hlen_in, hlen_out; + void (*hsrun)(void *ctx); + + /* + * The 'action' value communicates OOB information between the + * engine and the handshake processor. + * + * From the engine: + * 0 invocation triggered by I/O + * 1 invocation triggered by explicit close + * 2 invocation triggered by explicit renegotiation + */ + unsigned char action; + + /* + * State for alert messages. Value is either 0, or the value of + * the alert level byte (level is either 1 for warning, or 2 for + * fatal; we convert all other values to 'fatal'). + */ + unsigned char alert; + + /* + * Closure flags. This flag is set when a close_notify has been + * received from the peer. + */ + unsigned char close_received; + + /* + * Multi-hasher for the handshake messages. The handshake handler + * is responsible for resetting it when appropriate. + */ + br_multihash_context mhash; + + /* + * Pointer to the X.509 engine. The engine is supposed to be + * already initialized. It is used to validate the peer's + * certificate. + */ + const br_x509_class **x509ctx; + + /* + * Certificate chain to send. This is used by both client and + * server, when they send their respective Certificate messages. + * If chain_len is 0, then chain may be NULL. + */ + const br_x509_certificate *chain; + size_t chain_len; + const unsigned char *cert_cur; + size_t cert_len; + + /* + * List of supported protocol names (ALPN extension). If unset, + * (number of names is 0), then: + * - the client sends no ALPN extension; + * - the server ignores any incoming ALPN extension. + * + * Otherwise: + * - the client sends an ALPN extension with all the names; + * - the server selects the first protocol in its list that + * the client also supports, or fails (fatal alert 120) + * if the client sends an ALPN extension and there is no + * match. + * + * The 'selected_protocol' field contains 1+n if the matching + * name has index n in the list (the value is 0 if no match was + * performed, e.g. the peer did not send an ALPN extension). + */ + const char **protocol_names; + uint16_t protocol_names_num; + uint16_t selected_protocol; + + /* + * Pointers to implementations; left to NULL for unsupported + * functions. For the raw hash functions, implementations are + * referenced from the multihasher (mhash field). + */ + br_tls_prf_impl prf10; + br_tls_prf_impl prf_sha256; + br_tls_prf_impl prf_sha384; + const br_block_cbcenc_class *iaes_cbcenc; + const br_block_cbcdec_class *iaes_cbcdec; + const br_block_ctr_class *iaes_ctr; + const br_block_ctrcbc_class *iaes_ctrcbc; + const br_block_cbcenc_class *ides_cbcenc; + const br_block_cbcdec_class *ides_cbcdec; + br_ghash ighash; + br_chacha20_run ichacha; + br_poly1305_run ipoly; + const br_sslrec_in_cbc_class *icbc_in; + const br_sslrec_out_cbc_class *icbc_out; + const br_sslrec_in_gcm_class *igcm_in; + const br_sslrec_out_gcm_class *igcm_out; + const br_sslrec_in_chapol_class *ichapol_in; + const br_sslrec_out_chapol_class *ichapol_out; + const br_sslrec_in_ccm_class *iccm_in; + const br_sslrec_out_ccm_class *iccm_out; + const br_ec_impl *iec; + br_rsa_pkcs1_vrfy irsavrfy; + br_ecdsa_vrfy iecdsa; +#endif +} br_ssl_engine_context; + +/** + * \brief Get currently defined engine behavioural flags. + * + * \param cc SSL engine context. + * \return the flags. + */ +static __inline uint32_t +br_ssl_engine_get_flags(br_ssl_engine_context *cc) +{ + return cc->flags; +} + +/** + * \brief Set all engine behavioural flags. + * + * \param cc SSL engine context. + * \param flags new value for all flags. + */ +static __inline void +br_ssl_engine_set_all_flags(br_ssl_engine_context *cc, uint32_t flags) +{ + cc->flags = flags; +} + +/** + * \brief Set some engine behavioural flags. + * + * The flags set in the `flags` parameter are set in the context; other + * flags are untouched. + * + * \param cc SSL engine context. + * \param flags additional set flags. + */ +static __inline void +br_ssl_engine_add_flags(br_ssl_engine_context *cc, uint32_t flags) +{ + cc->flags |= flags; +} + +/** + * \brief Clear some engine behavioural flags. + * + * The flags set in the `flags` parameter are cleared from the context; other + * flags are untouched. + * + * \param cc SSL engine context. + * \param flags flags to remove. + */ +static __inline void +br_ssl_engine_remove_flags(br_ssl_engine_context *cc, uint32_t flags) +{ + cc->flags &= ~flags; +} + +/** + * \brief Behavioural flag: enforce server preferences. + * + * If this flag is set, then the server will enforce its own cipher suite + * preference order; otherwise, it follows the client preferences. + */ +#define BR_OPT_ENFORCE_SERVER_PREFERENCES ((uint32_t)1 << 0) + +/** + * \brief Behavioural flag: disable renegotiation. + * + * If this flag is set, then renegotiations are rejected unconditionally: + * they won't be honoured if asked for programmatically, and requests from + * the peer are rejected. + */ +#define BR_OPT_NO_RENEGOTIATION ((uint32_t)1 << 1) + +/** + * \brief Behavioural flag: tolerate lack of client authentication. + * + * If this flag is set in a server and the server requests a client + * certificate, but the authentication fails (the client does not send + * a certificate, or the client's certificate chain cannot be validated), + * then the connection keeps on. Without this flag, a failed client + * authentication terminates the connection. + * + * Notes: + * + * - If the client's certificate can be validated and its public key is + * supported, then a wrong signature value terminates the connection + * regardless of that flag. + * + * - If using full-static ECDH, then a failure to validate the client's + * certificate prevents the handshake from succeeding. + */ +#define BR_OPT_TOLERATE_NO_CLIENT_AUTH ((uint32_t)1 << 2) + +/** + * \brief Behavioural flag: fail on application protocol mismatch. + * + * The ALPN extension ([RFC 7301](https://tools.ietf.org/html/rfc7301)) + * allows the client to send a list of application protocol names, and + * the server to select one. A mismatch is one of the following occurrences: + * + * - On the client: the client sends a list of names, the server + * responds with a protocol name which is _not_ part of the list of + * names sent by the client. + * + * - On the server: the client sends a list of names, and the server + * is also configured with a list of names, but there is no common + * protocol name between the two lists. + * + * Normal behaviour in case of mismatch is to report no matching name + * (`br_ssl_engine_get_selected_protocol()` returns `NULL`) and carry on. + * If the flag is set, then a mismatch implies a protocol failure (if + * the mismatch is detected by the server, it will send a fatal alert). + * + * Note: even with this flag, `br_ssl_engine_get_selected_protocol()` + * may still return `NULL` if the client or the server does not send an + * ALPN extension at all. + */ +#define BR_OPT_FAIL_ON_ALPN_MISMATCH ((uint32_t)1 << 3) + +/** + * \brief Set the minimum and maximum supported protocol versions. + * + * The two provided versions MUST be supported by the implementation + * (i.e. TLS 1.0, 1.1 and 1.2), and `version_max` MUST NOT be lower + * than `version_min`. + * + * \param cc SSL engine context. + * \param version_min minimum supported TLS version. + * \param version_max maximum supported TLS version. + */ +static __inline void +br_ssl_engine_set_versions(br_ssl_engine_context *cc, + unsigned version_min, unsigned version_max) +{ + cc->version_min = (uint16_t)version_min; + cc->version_max = (uint16_t)version_max; +} + +/** + * \brief Set the list of cipher suites advertised by this context. + * + * The provided array is copied into the context. It is the caller + * responsibility to ensure that all provided suites will be supported + * by the context. The engine context has enough room to receive _all_ + * suites supported by the implementation. The provided array MUST NOT + * contain duplicates. + * + * If the engine is for a client, the "signaling" pseudo-cipher suite + * `TLS_FALLBACK_SCSV` can be added at the end of the list, if the + * calling application is performing a voluntary downgrade (voluntary + * downgrades are not recommended, but if such a downgrade is done, then + * adding the fallback pseudo-suite is a good idea). + * + * \param cc SSL engine context. + * \param suites cipher suites. + * \param suites_num number of cipher suites. + */ +void br_ssl_engine_set_suites(br_ssl_engine_context *cc, + const uint16_t *suites, size_t suites_num); + +/** + * \brief Set the X.509 engine. + * + * The caller shall ensure that the X.509 engine is properly initialised. + * + * \param cc SSL engine context. + * \param x509ctx X.509 certificate validation context. + */ +static __inline void +br_ssl_engine_set_x509(br_ssl_engine_context *cc, const br_x509_class **x509ctx) +{ + cc->x509ctx = x509ctx; +} + +/** + * \brief Set the supported protocol names. + * + * Protocol names are part of the ALPN extension ([RFC + * 7301](https://tools.ietf.org/html/rfc7301)). Each protocol name is a + * character string, containing no more than 255 characters (256 with the + * terminating zero). When names are set, then: + * + * - The client will send an ALPN extension, containing the names. If + * the server responds with an ALPN extension, the client will verify + * that the response contains one of its name, and report that name + * through `br_ssl_engine_get_selected_protocol()`. + * + * - The server will parse incoming ALPN extension (from clients), and + * try to find a common protocol; if none is found, the connection + * is aborted with a fatal alert. On match, a response ALPN extension + * is sent, and name is reported through + * `br_ssl_engine_get_selected_protocol()`. + * + * The provided array is linked in, and must remain valid while the + * connection is live. + * + * Names MUST NOT be empty. Names MUST NOT be longer than 255 characters + * (excluding the terminating 0). + * + * \param ctx SSL engine context. + * \param names list of protocol names (zero-terminated). + * \param num number of protocol names (MUST be 1 or more). + */ +static __inline void +br_ssl_engine_set_protocol_names(br_ssl_engine_context *ctx, + const char **names, size_t num) +{ + ctx->protocol_names = names; + ctx->protocol_names_num = (uint16_t)num; +} + +/** + * \brief Get the selected protocol. + * + * If this context was initialised with a non-empty list of protocol + * names, and both client and server sent ALPN extensions during the + * handshake, and a common name was found, then that name is returned. + * Otherwise, `NULL` is returned. + * + * The returned pointer is one of the pointers provided to the context + * with `br_ssl_engine_set_protocol_names()`. + * + * \return the selected protocol, or `NULL`. + */ +static __inline const char * +br_ssl_engine_get_selected_protocol(br_ssl_engine_context *ctx) +{ + unsigned k; + + k = ctx->selected_protocol; + return (k == 0 || k == 0xFFFF) ? NULL : ctx->protocol_names[k - 1]; +} + +/** + * \brief Set a hash function implementation (by ID). + * + * Hash functions set with this call will be used for SSL/TLS specific + * usages, not X.509 certificate validation. Only "standard" hash functions + * may be set (MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512). If `impl` + * is `NULL`, then the hash function support is removed, not added. + * + * \param ctx SSL engine context. + * \param id hash function identifier. + * \param impl hash function implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_hash(br_ssl_engine_context *ctx, + int id, const br_hash_class *impl) +{ + br_multihash_setimpl(&ctx->mhash, id, impl); +} + +/** + * \brief Get a hash function implementation (by ID). + * + * This function retrieves a hash function implementation which was + * set with `br_ssl_engine_set_hash()`. + * + * \param ctx SSL engine context. + * \param id hash function identifier. + * \return the hash function implementation (or `NULL`). + */ +static __inline const br_hash_class * +br_ssl_engine_get_hash(br_ssl_engine_context *ctx, int id) +{ + return br_multihash_getimpl(&ctx->mhash, id); +} + +/** + * \brief Set the PRF implementation (for TLS 1.0 and 1.1). + * + * This function sets (or removes, if `impl` is `NULL`) the implementation + * for the PRF used in TLS 1.0 and 1.1. + * + * \param cc SSL engine context. + * \param impl PRF implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_prf10(br_ssl_engine_context *cc, br_tls_prf_impl impl) +{ + cc->prf10 = impl; +} + +/** + * \brief Set the PRF implementation with SHA-256 (for TLS 1.2). + * + * This function sets (or removes, if `impl` is `NULL`) the implementation + * for the SHA-256 variant of the PRF used in TLS 1.2. + * + * \param cc SSL engine context. + * \param impl PRF implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_prf_sha256(br_ssl_engine_context *cc, br_tls_prf_impl impl) +{ + cc->prf_sha256 = impl; +} + +/** + * \brief Set the PRF implementation with SHA-384 (for TLS 1.2). + * + * This function sets (or removes, if `impl` is `NULL`) the implementation + * for the SHA-384 variant of the PRF used in TLS 1.2. + * + * \param cc SSL engine context. + * \param impl PRF implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_prf_sha384(br_ssl_engine_context *cc, br_tls_prf_impl impl) +{ + cc->prf_sha384 = impl; +} + +/** + * \brief Set the AES/CBC implementations. + * + * \param cc SSL engine context. + * \param impl_enc AES/CBC encryption implementation (or `NULL`). + * \param impl_dec AES/CBC decryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_aes_cbc(br_ssl_engine_context *cc, + const br_block_cbcenc_class *impl_enc, + const br_block_cbcdec_class *impl_dec) +{ + cc->iaes_cbcenc = impl_enc; + cc->iaes_cbcdec = impl_dec; +} + +/** + * \brief Set the "default" AES/CBC implementations. + * + * This function configures in the engine the AES implementations that + * should provide best runtime performance on the local system, while + * still being safe (in particular, constant-time). It also sets the + * handlers for CBC records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_aes_cbc(br_ssl_engine_context *cc); + +/** + * \brief Set the AES/CTR implementation. + * + * \param cc SSL engine context. + * \param impl AES/CTR encryption/decryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_aes_ctr(br_ssl_engine_context *cc, + const br_block_ctr_class *impl) +{ + cc->iaes_ctr = impl; +} + +/** + * \brief Set the "default" implementations for AES/GCM (AES/CTR + GHASH). + * + * This function configures in the engine the AES/CTR and GHASH + * implementation that should provide best runtime performance on the local + * system, while still being safe (in particular, constant-time). It also + * sets the handlers for GCM records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_aes_gcm(br_ssl_engine_context *cc); + +/** + * \brief Set the DES/CBC implementations. + * + * \param cc SSL engine context. + * \param impl_enc DES/CBC encryption implementation (or `NULL`). + * \param impl_dec DES/CBC decryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_des_cbc(br_ssl_engine_context *cc, + const br_block_cbcenc_class *impl_enc, + const br_block_cbcdec_class *impl_dec) +{ + cc->ides_cbcenc = impl_enc; + cc->ides_cbcdec = impl_dec; +} + +/** + * \brief Set the "default" DES/CBC implementations. + * + * This function configures in the engine the DES implementations that + * should provide best runtime performance on the local system, while + * still being safe (in particular, constant-time). It also sets the + * handlers for CBC records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc); + +/** + * \brief Set the GHASH implementation (used in GCM mode). + * + * \param cc SSL engine context. + * \param impl GHASH implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_ghash(br_ssl_engine_context *cc, br_ghash impl) +{ + cc->ighash = impl; +} + +/** + * \brief Set the ChaCha20 implementation. + * + * \param cc SSL engine context. + * \param ichacha ChaCha20 implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_chacha20(br_ssl_engine_context *cc, + br_chacha20_run ichacha) +{ + cc->ichacha = ichacha; +} + +/** + * \brief Set the Poly1305 implementation. + * + * \param cc SSL engine context. + * \param ipoly Poly1305 implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_poly1305(br_ssl_engine_context *cc, + br_poly1305_run ipoly) +{ + cc->ipoly = ipoly; +} + +/** + * \brief Set the "default" ChaCha20 and Poly1305 implementations. + * + * This function configures in the engine the ChaCha20 and Poly1305 + * implementations that should provide best runtime performance on the + * local system, while still being safe (in particular, constant-time). + * It also sets the handlers for ChaCha20+Poly1305 records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_chapol(br_ssl_engine_context *cc); + +/** + * \brief Set the AES/CTR+CBC implementation. + * + * \param cc SSL engine context. + * \param impl AES/CTR+CBC encryption/decryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_aes_ctrcbc(br_ssl_engine_context *cc, + const br_block_ctrcbc_class *impl) +{ + cc->iaes_ctrcbc = impl; +} + +/** + * \brief Set the "default" implementations for AES/CCM. + * + * This function configures in the engine the AES/CTR+CBC + * implementation that should provide best runtime performance on the local + * system, while still being safe (in particular, constant-time). It also + * sets the handlers for CCM records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_aes_ccm(br_ssl_engine_context *cc); + +/** + * \brief Set the record encryption and decryption engines for CBC + HMAC. + * + * \param cc SSL engine context. + * \param impl_in record CBC decryption implementation (or `NULL`). + * \param impl_out record CBC encryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_cbc(br_ssl_engine_context *cc, + const br_sslrec_in_cbc_class *impl_in, + const br_sslrec_out_cbc_class *impl_out) +{ + cc->icbc_in = impl_in; + cc->icbc_out = impl_out; +} + +/** + * \brief Set the record encryption and decryption engines for GCM. + * + * \param cc SSL engine context. + * \param impl_in record GCM decryption implementation (or `NULL`). + * \param impl_out record GCM encryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_gcm(br_ssl_engine_context *cc, + const br_sslrec_in_gcm_class *impl_in, + const br_sslrec_out_gcm_class *impl_out) +{ + cc->igcm_in = impl_in; + cc->igcm_out = impl_out; +} + +/** + * \brief Set the record encryption and decryption engines for CCM. + * + * \param cc SSL engine context. + * \param impl_in record CCM decryption implementation (or `NULL`). + * \param impl_out record CCM encryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_ccm(br_ssl_engine_context *cc, + const br_sslrec_in_ccm_class *impl_in, + const br_sslrec_out_ccm_class *impl_out) +{ + cc->iccm_in = impl_in; + cc->iccm_out = impl_out; +} + +/** + * \brief Set the record encryption and decryption engines for + * ChaCha20+Poly1305. + * + * \param cc SSL engine context. + * \param impl_in record ChaCha20 decryption implementation (or `NULL`). + * \param impl_out record ChaCha20 encryption implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_chapol(br_ssl_engine_context *cc, + const br_sslrec_in_chapol_class *impl_in, + const br_sslrec_out_chapol_class *impl_out) +{ + cc->ichapol_in = impl_in; + cc->ichapol_out = impl_out; +} + +/** + * \brief Set the EC implementation. + * + * The elliptic curve implementation will be used for ECDH and ECDHE + * cipher suites, and for ECDSA support. + * + * \param cc SSL engine context. + * \param iec EC implementation (or `NULL`). + */ +static __inline void +br_ssl_engine_set_ec(br_ssl_engine_context *cc, const br_ec_impl *iec) +{ + cc->iec = iec; +} + +/** + * \brief Set the "default" EC implementation. + * + * This function sets the elliptic curve implementation for ECDH and + * ECDHE cipher suites, and for ECDSA support. It selects the fastest + * implementation on the current system. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_ec(br_ssl_engine_context *cc); + +/** + * \brief Get the EC implementation configured in the provided engine. + * + * \param cc SSL engine context. + * \return the EC implementation. + */ +static __inline const br_ec_impl * +br_ssl_engine_get_ec(br_ssl_engine_context *cc) +{ + return cc->iec; +} + +/** + * \brief Set the RSA signature verification implementation. + * + * On the client, this is used to verify the server's signature on its + * ServerKeyExchange message (for ECDHE_RSA cipher suites). On the server, + * this is used to verify the client's CertificateVerify message (if a + * client certificate is requested, and that certificate contains a RSA key). + * + * \param cc SSL engine context. + * \param irsavrfy RSA signature verification implementation. + */ +static __inline void +br_ssl_engine_set_rsavrfy(br_ssl_engine_context *cc, br_rsa_pkcs1_vrfy irsavrfy) +{ + cc->irsavrfy = irsavrfy; +} + +/** + * \brief Set the "default" RSA implementation (signature verification). + * + * This function sets the RSA implementation (signature verification) + * to the fastest implementation available on the current platform. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_rsavrfy(br_ssl_engine_context *cc); + +/** + * \brief Get the RSA implementation (signature verification) configured + * in the provided engine. + * + * \param cc SSL engine context. + * \return the RSA signature verification implementation. + */ +static __inline br_rsa_pkcs1_vrfy +br_ssl_engine_get_rsavrfy(br_ssl_engine_context *cc) +{ + return cc->irsavrfy; +} + +/* + * \brief Set the ECDSA implementation (signature verification). + * + * On the client, this is used to verify the server's signature on its + * ServerKeyExchange message (for ECDHE_ECDSA cipher suites). On the server, + * this is used to verify the client's CertificateVerify message (if a + * client certificate is requested, that certificate contains an EC key, + * and full-static ECDH is not used). + * + * The ECDSA implementation will use the EC core implementation configured + * in the engine context. + * + * \param cc client context. + * \param iecdsa ECDSA verification implementation. + */ +static __inline void +br_ssl_engine_set_ecdsa(br_ssl_engine_context *cc, br_ecdsa_vrfy iecdsa) +{ + cc->iecdsa = iecdsa; +} + +/** + * \brief Set the "default" ECDSA implementation (signature verification). + * + * This function sets the ECDSA implementation (signature verification) + * to the fastest implementation available on the current platform. This + * call also sets the elliptic curve implementation itself, there again + * to the fastest EC implementation available. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_ecdsa(br_ssl_engine_context *cc); + +/** + * \brief Get the ECDSA implementation (signature verification) configured + * in the provided engine. + * + * \param cc SSL engine context. + * \return the ECDSA signature verification implementation. + */ +static __inline br_ecdsa_vrfy +br_ssl_engine_get_ecdsa(br_ssl_engine_context *cc) +{ + return cc->iecdsa; +} + +/** + * \brief Set the I/O buffer for the SSL engine. + * + * Once this call has been made, `br_ssl_client_reset()` or + * `br_ssl_server_reset()` MUST be called before using the context. + * + * The provided buffer will be used as long as the engine context is + * used. The caller is responsible for keeping it available. + * + * If `bidi` is 0, then the engine will operate in half-duplex mode + * (it won't be able to send data while there is unprocessed incoming + * data in the buffer, and it won't be able to receive data while there + * is unsent data in the buffer). The optimal buffer size in half-duplex + * mode is `BR_SSL_BUFSIZE_MONO`; if the buffer is larger, then extra + * bytes are ignored. If the buffer is smaller, then this limits the + * capacity of the engine to support all allowed record sizes. + * + * If `bidi` is 1, then the engine will split the buffer into two + * parts, for separate handling of outgoing and incoming data. This + * enables full-duplex processing, but requires more RAM. The optimal + * buffer size in full-duplex mode is `BR_SSL_BUFSIZE_BIDI`; if the + * buffer is larger, then extra bytes are ignored. If the buffer is + * smaller, then the split will favour the incoming part, so that + * interoperability is maximised. + * + * \param cc SSL engine context + * \param iobuf I/O buffer. + * \param iobuf_len I/O buffer length (in bytes). + * \param bidi non-zero for full-duplex mode. + */ +void br_ssl_engine_set_buffer(br_ssl_engine_context *cc, + void *iobuf, size_t iobuf_len, int bidi); + +/** + * \brief Set the I/O buffers for the SSL engine. + * + * Once this call has been made, `br_ssl_client_reset()` or + * `br_ssl_server_reset()` MUST be called before using the context. + * + * This function is similar to `br_ssl_engine_set_buffer()`, except + * that it enforces full-duplex mode, and the two I/O buffers are + * provided as separate chunks. + * + * The macros `BR_SSL_BUFSIZE_INPUT` and `BR_SSL_BUFSIZE_OUTPUT` + * evaluate to the optimal (maximum) sizes for the input and output + * buffer, respectively. + * + * \param cc SSL engine context + * \param ibuf input buffer. + * \param ibuf_len input buffer length (in bytes). + * \param obuf output buffer. + * \param obuf_len output buffer length (in bytes). + */ +void br_ssl_engine_set_buffers_bidi(br_ssl_engine_context *cc, + void *ibuf, size_t ibuf_len, void *obuf, size_t obuf_len); + +/** + * \brief Inject some "initial entropy" in the context. + * + * This entropy will be added to what can be obtained from the + * underlying operating system, if that OS is supported. + * + * This function may be called several times; all injected entropy chunks + * are cumulatively mixed. + * + * If entropy gathering from the OS is supported and compiled in, then this + * step is optional. Otherwise, it is mandatory to inject randomness, and + * the caller MUST take care to push (as one or several successive calls) + * enough entropy to achieve cryptographic resistance (at least 80 bits, + * preferably 128 or more). The engine will report an error if no entropy + * was provided and none can be obtained from the OS. + * + * Take care that this function cannot assess the cryptographic quality of + * the provided bytes. + * + * In all generality, "entropy" must here be considered to mean "that + * which the attacker cannot predict". If your OS/architecture does not + * have a suitable source of randomness, then you can make do with the + * combination of a large enough secret value (possibly a copy of an + * asymmetric private key that you also store on the system) AND a + * non-repeating value (e.g. current time, provided that the local clock + * cannot be reset or altered by the attacker). + * + * \param cc SSL engine context. + * \param data extra entropy to inject. + * \param len length of the extra data (in bytes). + */ +void br_ssl_engine_inject_entropy(br_ssl_engine_context *cc, + const void *data, size_t len); + +/** + * \brief Get the "server name" in this engine. + * + * For clients, this is the name provided with `br_ssl_client_reset()`; + * for servers, this is the name received from the client as part of the + * ClientHello message. If there is no such name (e.g. the client did + * not send an SNI extension) then the returned string is empty + * (returned pointer points to a byte of value 0). + * + * The returned pointer refers to a buffer inside the context, which may + * be overwritten as part of normal SSL activity (even within the same + * connection, if a renegotiation occurs). + * + * \param cc SSL engine context. + * \return the server name (possibly empty). + */ +static __inline const char * +br_ssl_engine_get_server_name(const br_ssl_engine_context *cc) +{ + return cc->server_name; +} + +/** + * \brief Get the protocol version. + * + * This function returns the protocol version that is used by the + * engine. That value is set after sending (for a server) or receiving + * (for a client) the ServerHello message. + * + * \param cc SSL engine context. + * \return the protocol version. + */ +static __inline unsigned +br_ssl_engine_get_version(const br_ssl_engine_context *cc) +{ + return cc->session.version; +} + +/** + * \brief Get a copy of the session parameters. + * + * The session parameters are filled during the handshake, so this + * function shall not be called before completion of the handshake. + * The initial handshake is completed when the context first allows + * application data to be injected. + * + * This function copies the current session parameters into the provided + * structure. Beware that the session parameters include the master + * secret, which is sensitive data, to handle with great care. + * + * \param cc SSL engine context. + * \param pp destination structure for the session parameters. + */ +static __inline void +br_ssl_engine_get_session_parameters(const br_ssl_engine_context *cc, + br_ssl_session_parameters *pp) +{ + memcpy(pp, &cc->session, sizeof *pp); +} + +/** + * \brief Set the session parameters to the provided values. + * + * This function is meant to be used in the client, before doing a new + * handshake; a session resumption will be attempted with these + * parameters. In the server, this function has no effect. + * + * \param cc SSL engine context. + * \param pp source structure for the session parameters. + */ +static __inline void +br_ssl_engine_set_session_parameters(br_ssl_engine_context *cc, + const br_ssl_session_parameters *pp) +{ + memcpy(&cc->session, pp, sizeof *pp); +} + +/** + * \brief Get identifier for the curve used for key exchange. + * + * If the cipher suite uses ECDHE, then this function returns the + * identifier for the curve used for transient parameters. This is + * defined during the course of the handshake, when the ServerKeyExchange + * is sent (on the server) or received (on the client). If the + * cipher suite does not use ECDHE (e.g. static ECDH, or RSA key + * exchange), then this value is indeterminate. + * + * @param cc SSL engine context. + * @return the ECDHE curve identifier. + */ +static __inline int +br_ssl_engine_get_ecdhe_curve(br_ssl_engine_context *cc) +{ + return cc->ecdhe_curve; +} + +/** + * \brief Get the current engine state. + * + * An SSL engine (client or server) has, at any time, a state which is + * the combination of zero, one or more of these flags: + * + * - `BR_SSL_CLOSED` + * + * Engine is finished, no more I/O (until next reset). + * + * - `BR_SSL_SENDREC` + * + * Engine has some bytes to send to the peer. + * + * - `BR_SSL_RECVREC` + * + * Engine expects some bytes from the peer. + * + * - `BR_SSL_SENDAPP` + * + * Engine may receive application data to send (or flush). + * + * - `BR_SSL_RECVAPP` + * + * Engine has obtained some application data from the peer, + * that should be read by the caller. + * + * If no flag at all is set (state value is 0), then the engine is not + * fully initialised yet. + * + * The `BR_SSL_CLOSED` flag is exclusive; when it is set, no other flag + * is set. To distinguish between a normal closure and an error, use + * `br_ssl_engine_last_error()`. + * + * Generally speaking, `BR_SSL_SENDREC` and `BR_SSL_SENDAPP` are mutually + * exclusive: the input buffer, at any point, either accumulates + * plaintext data, or contains an assembled record that is being sent. + * Similarly, `BR_SSL_RECVREC` and `BR_SSL_RECVAPP` are mutually exclusive. + * This may change in a future library version. + * + * \param cc SSL engine context. + * \return the current engine state. + */ +unsigned br_ssl_engine_current_state(const br_ssl_engine_context *cc); + +/** \brief SSL engine state: closed or failed. */ +#define BR_SSL_CLOSED 0x0001 +/** \brief SSL engine state: record data is ready to be sent to the peer. */ +#define BR_SSL_SENDREC 0x0002 +/** \brief SSL engine state: engine may receive records from the peer. */ +#define BR_SSL_RECVREC 0x0004 +/** \brief SSL engine state: engine may accept application data to send. */ +#define BR_SSL_SENDAPP 0x0008 +/** \brief SSL engine state: engine has received application data. */ +#define BR_SSL_RECVAPP 0x0010 + +/** + * \brief Get the engine error indicator. + * + * The error indicator is `BR_ERR_OK` (0) if no error was encountered + * since the last call to `br_ssl_client_reset()` or + * `br_ssl_server_reset()`. Other status values are "sticky": they + * remain set, and prevent all I/O activity, until cleared. Only the + * reset calls clear the error indicator. + * + * \param cc SSL engine context. + * \return 0, or a non-zero error code. + */ +static __inline int +br_ssl_engine_last_error(const br_ssl_engine_context *cc) +{ + return cc->err; +} + +/* + * There are four I/O operations, each identified by a symbolic name: + * + * sendapp inject application data in the engine + * recvapp retrieving application data from the engine + * sendrec sending records on the transport medium + * recvrec receiving records from the transport medium + * + * Terminology works thus: in a layered model where the SSL engine sits + * between the application and the network, "send" designates operations + * where bytes flow from application to network, and "recv" for the + * reverse operation. Application data (the plaintext that is to be + * conveyed through SSL) is "app", while encrypted records are "rec". + * Note that from the SSL engine point of view, "sendapp" and "recvrec" + * designate bytes that enter the engine ("inject" operation), while + * "recvapp" and "sendrec" designate bytes that exit the engine + * ("extract" operation). + * + * For the operation 'xxx', two functions are defined: + * + * br_ssl_engine_xxx_buf + * Returns a pointer and length to the buffer to use for that + * operation. '*len' is set to the number of bytes that may be read + * from the buffer (extract operation) or written to the buffer + * (inject operation). If no byte may be exchanged for that operation + * at that point, then '*len' is set to zero, and NULL is returned. + * The engine state is unmodified by this call. + * + * br_ssl_engine_xxx_ack + * Informs the engine that 'len' bytes have been read from the buffer + * (extract operation) or written to the buffer (inject operation). + * The 'len' value MUST NOT be zero. The 'len' value MUST NOT exceed + * that which was obtained from a preceding br_ssl_engine_xxx_buf() + * call. + */ + +/** + * \brief Get buffer for application data to send. + * + * If the engine is ready to accept application data to send to the + * peer, then this call returns a pointer to the buffer where such + * data shall be written, and its length is written in `*len`. + * Otherwise, `*len` is set to 0 and `NULL` is returned. + * + * \param cc SSL engine context. + * \param len receives the application data output buffer length, or 0. + * \return the application data output buffer, or `NULL`. + */ +unsigned char *br_ssl_engine_sendapp_buf( + const br_ssl_engine_context *cc, size_t *len); + +/** + * \brief Inform the engine of some new application data. + * + * After writing `len` bytes in the buffer returned by + * `br_ssl_engine_sendapp_buf()`, the application shall call this + * function to trigger any relevant processing. The `len` parameter + * MUST NOT be 0, and MUST NOT exceed the value obtained in the + * `br_ssl_engine_sendapp_buf()` call. + * + * \param cc SSL engine context. + * \param len number of bytes pushed (not zero). + */ +void br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len); + +/** + * \brief Get buffer for received application data. + * + * If the engine has received application data from the peer, then this + * call returns a pointer to the buffer from where such data shall be + * read, and its length is written in `*len`. Otherwise, `*len` is set + * to 0 and `NULL` is returned. + * + * \param cc SSL engine context. + * \param len receives the application data input buffer length, or 0. + * \return the application data input buffer, or `NULL`. + */ +unsigned char *br_ssl_engine_recvapp_buf( + const br_ssl_engine_context *cc, size_t *len); + +/** + * \brief Acknowledge some received application data. + * + * After reading `len` bytes from the buffer returned by + * `br_ssl_engine_recvapp_buf()`, the application shall call this + * function to trigger any relevant processing. The `len` parameter + * MUST NOT be 0, and MUST NOT exceed the value obtained in the + * `br_ssl_engine_recvapp_buf()` call. + * + * \param cc SSL engine context. + * \param len number of bytes read (not zero). + */ +void br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len); + +/** + * \brief Get buffer for record data to send. + * + * If the engine has prepared some records to send to the peer, then this + * call returns a pointer to the buffer from where such data shall be + * read, and its length is written in `*len`. Otherwise, `*len` is set + * to 0 and `NULL` is returned. + * + * \param cc SSL engine context. + * \param len receives the record data output buffer length, or 0. + * \return the record data output buffer, or `NULL`. + */ +unsigned char *br_ssl_engine_sendrec_buf( + const br_ssl_engine_context *cc, size_t *len); + +/** + * \brief Acknowledge some sent record data. + * + * After reading `len` bytes from the buffer returned by + * `br_ssl_engine_sendrec_buf()`, the application shall call this + * function to trigger any relevant processing. The `len` parameter + * MUST NOT be 0, and MUST NOT exceed the value obtained in the + * `br_ssl_engine_sendrec_buf()` call. + * + * \param cc SSL engine context. + * \param len number of bytes read (not zero). + */ +void br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len); + +/** + * \brief Get buffer for incoming records. + * + * If the engine is ready to accept records from the peer, then this + * call returns a pointer to the buffer where such data shall be + * written, and its length is written in `*len`. Otherwise, `*len` is + * set to 0 and `NULL` is returned. + * + * \param cc SSL engine context. + * \param len receives the record data input buffer length, or 0. + * \return the record data input buffer, or `NULL`. + */ +unsigned char *br_ssl_engine_recvrec_buf( + const br_ssl_engine_context *cc, size_t *len); + +/** + * \brief Inform the engine of some new record data. + * + * After writing `len` bytes in the buffer returned by + * `br_ssl_engine_recvrec_buf()`, the application shall call this + * function to trigger any relevant processing. The `len` parameter + * MUST NOT be 0, and MUST NOT exceed the value obtained in the + * `br_ssl_engine_recvrec_buf()` call. + * + * \param cc SSL engine context. + * \param len number of bytes pushed (not zero). + */ +void br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len); + +/** + * \brief Flush buffered application data. + * + * If some application data has been buffered in the engine, then wrap + * it into a record and mark it for sending. If no application data has + * been buffered but the engine would be ready to accept some, AND the + * `force` parameter is non-zero, then an empty record is assembled and + * marked for sending. In all other cases, this function does nothing. + * + * Empty records are technically legal, but not all existing SSL/TLS + * implementations support them. Empty records can be useful as a + * transparent "keep-alive" mechanism to maintain some low-level + * network activity. + * + * \param cc SSL engine context. + * \param force non-zero to force sending an empty record. + */ +void br_ssl_engine_flush(br_ssl_engine_context *cc, int force); + +/** + * \brief Initiate a closure. + * + * If, at that point, the context is open and in ready state, then a + * `close_notify` alert is assembled and marked for sending; this + * triggers the closure protocol. Otherwise, no such alert is assembled. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_close(br_ssl_engine_context *cc); + +/** + * \brief Initiate a renegotiation. + * + * If the engine is failed or closed, or if the peer is known not to + * support secure renegotiation (RFC 5746), or if renegotiations have + * been disabled with the `BR_OPT_NO_RENEGOTIATION` flag, or if there + * is buffered incoming application data, then this function returns 0 + * and nothing else happens. + * + * Otherwise, this function returns 1, and a renegotiation attempt is + * triggered (if a handshake is already ongoing at that point, then + * no new handshake is triggered). + * + * \param cc SSL engine context. + * \return 1 on success, 0 on error. + */ +int br_ssl_engine_renegotiate(br_ssl_engine_context *cc); + +/** + * \brief Export key material from a connected SSL engine (RFC 5705). + * + * This calls compute a secret key of arbitrary length from the master + * secret of a connected SSL engine. If the provided context is not + * currently in "application data" state (initial handshake is not + * finished, another handshake is ongoing, or the connection failed or + * was closed), then this function returns 0. Otherwise, a secret key of + * length `len` bytes is computed and written in the buffer pointed to + * by `dst`, and 1 is returned. + * + * The computed key follows the specification described in RFC 5705. + * That RFC includes two key computations, with and without a "context + * value". If `context` is `NULL`, then the variant without context is + * used; otherwise, the `context_len` bytes located at the address + * pointed to by `context` are used in the computation. Note that it + * is possible to have a "with context" key with a context length of + * zero bytes, by setting `context` to a non-`NULL` value but + * `context_len` to 0. + * + * When context bytes are used, the context length MUST NOT exceed + * 65535 bytes. + * + * \param cc SSL engine context. + * \param dst destination buffer for exported key. + * \param len exported key length (in bytes). + * \param label disambiguation label. + * \param context context value (or `NULL`). + * \param context_len context length (in bytes). + * \return 1 on success, 0 on error. + */ +int br_ssl_key_export(br_ssl_engine_context *cc, + void *dst, size_t len, const char *label, + const void *context, size_t context_len); + +/* + * Pre-declaration for the SSL client context. + */ +typedef struct br_ssl_client_context_ br_ssl_client_context; + +/** + * \brief Type for the client certificate, if requested by the server. + */ +typedef struct { + /** + * \brief Authentication type. + * + * This is either `BR_AUTH_RSA` (RSA signature), `BR_AUTH_ECDSA` + * (ECDSA signature), or `BR_AUTH_ECDH` (static ECDH key exchange). + */ + int auth_type; + + /** + * \brief Hash function for computing the CertificateVerify. + * + * This is the symbolic identifier for the hash function that + * will be used to produce the hash of handshake messages, to + * be signed into the CertificateVerify. For full static ECDH + * (client and server certificates are both EC in the same + * curve, and static ECDH is used), this value is set to -1. + * + * Take care that with TLS 1.0 and 1.1, that value MUST match + * the protocol requirements: value must be 0 (MD5+SHA-1) for + * a RSA signature, or 2 (SHA-1) for an ECDSA signature. Only + * TLS 1.2 allows for other hash functions. + */ + int hash_id; + + /** + * \brief Certificate chain to send to the server. + * + * This is an array of `br_x509_certificate` objects, each + * normally containing a DER-encoded certificate. The client + * code does not try to decode these elements. If there is no + * chain to send to the server, then this pointer shall be + * set to `NULL`. + */ + const br_x509_certificate *chain; + + /** + * \brief Certificate chain length (number of certificates). + * + * If there is no chain to send to the server, then this value + * shall be set to 0. + */ + size_t chain_len; + +} br_ssl_client_certificate; + +/* + * Note: the constants below for signatures match the TLS constants. + */ + +/** \brief Client authentication type: static ECDH. */ +#define BR_AUTH_ECDH 0 +/** \brief Client authentication type: RSA signature. */ +#define BR_AUTH_RSA 1 +/** \brief Client authentication type: ECDSA signature. */ +#define BR_AUTH_ECDSA 3 + +/** + * \brief Class type for a certificate handler (client side). + * + * A certificate handler selects a client certificate chain to send to + * the server, upon explicit request from that server. It receives + * the list of trust anchor DN from the server, and supported types + * of certificates and signatures, and returns the chain to use. It + * is also invoked to perform the corresponding private key operation + * (a signature, or an ECDH computation). + * + * The SSL client engine will first push the trust anchor DN with + * `start_name_list()`, `start_name()`, `append_name()`, `end_name()` + * and `end_name_list()`. Then it will call `choose()`, to select the + * actual chain (and signature/hash algorithms). Finally, it will call + * either `do_sign()` or `do_keyx()`, depending on the algorithm choices. + */ +typedef struct br_ssl_client_certificate_class_ br_ssl_client_certificate_class; +struct br_ssl_client_certificate_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Begin reception of a list of trust anchor names. This + * is called while parsing the incoming CertificateRequest. + * + * \param pctx certificate handler context. + */ + void (*start_name_list)(const br_ssl_client_certificate_class **pctx); + + /** + * \brief Begin reception of a new trust anchor name. + * + * The total encoded name length is provided; it is less than + * 65535 bytes. + * + * \param pctx certificate handler context. + * \param len encoded name length (in bytes). + */ + void (*start_name)(const br_ssl_client_certificate_class **pctx, + size_t len); + + /** + * \brief Receive some more bytes for the current trust anchor name. + * + * The provided reference (`data`) points to a transient buffer + * they may be reused as soon as this function returns. The chunk + * length (`len`) is never zero. + * + * \param pctx certificate handler context. + * \param data anchor name chunk. + * \param len anchor name chunk length (in bytes). + */ + void (*append_name)(const br_ssl_client_certificate_class **pctx, + const unsigned char *data, size_t len); + + /** + * \brief End current trust anchor name. + * + * This function is called when all the encoded anchor name data + * has been provided. + * + * \param pctx certificate handler context. + */ + void (*end_name)(const br_ssl_client_certificate_class **pctx); + + /** + * \brief End list of trust anchor names. + * + * This function is called when all the anchor names in the + * CertificateRequest message have been obtained. + * + * \param pctx certificate handler context. + */ + void (*end_name_list)(const br_ssl_client_certificate_class **pctx); + + /** + * \brief Select client certificate and algorithms. + * + * This callback function shall fill the provided `choices` + * structure with the selected algorithms and certificate chain. + * The `hash_id`, `chain` and `chain_len` fields must be set. If + * the client cannot or does not wish to send a certificate, + * then it shall set `chain` to `NULL` and `chain_len` to 0. + * + * The `auth_types` parameter describes the authentication types, + * signature algorithms and hash functions that are supported by + * both the client context and the server, and compatible with + * the current protocol version. This is a bit field with the + * following contents: + * + * - If RSA signatures with hash function x are supported, then + * bit x is set. + * + * - If ECDSA signatures with hash function x are supported, + * then bit 8+x is set. + * + * - If static ECDH is supported, with a RSA-signed certificate, + * then bit 16 is set. + * + * - If static ECDH is supported, with an ECDSA-signed certificate, + * then bit 17 is set. + * + * Notes: + * + * - When using TLS 1.0 or 1.1, the hash function for RSA + * signatures is always the special MD5+SHA-1 (id 0), and the + * hash function for ECDSA signatures is always SHA-1 (id 2). + * + * - When using TLS 1.2, the list of hash functions is trimmed + * down to include only hash functions that the client context + * can support. The actual server list can be obtained with + * `br_ssl_client_get_server_hashes()`; that list may be used + * to select the certificate chain to send to the server. + * + * \param pctx certificate handler context. + * \param cc SSL client context. + * \param auth_types supported authentication types and algorithms. + * \param choices destination structure for the policy choices. + */ + void (*choose)(const br_ssl_client_certificate_class **pctx, + const br_ssl_client_context *cc, uint32_t auth_types, + br_ssl_client_certificate *choices); + + /** + * \brief Perform key exchange (client part). + * + * This callback is invoked in case of a full static ECDH key + * exchange: + * + * - the cipher suite uses `ECDH_RSA` or `ECDH_ECDSA`; + * + * - the server requests a client certificate; + * + * - the client has, and sends, a client certificate that + * uses an EC key in the same curve as the server's key, + * and chooses static ECDH (the `hash_id` field in the choice + * structure was set to -1). + * + * In that situation, this callback is invoked to compute the + * client-side ECDH: the provided `data` (of length `*len` bytes) + * is the server's public key point (as decoded from its + * certificate), and the client shall multiply that point with + * its own private key, and write back the X coordinate of the + * resulting point in the same buffer, starting at offset 0. + * The `*len` value shall be modified to designate the actual + * length of the X coordinate. + * + * The callback must uphold the following: + * + * - If the input array does not have the proper length for + * an encoded curve point, then an error (0) shall be reported. + * + * - If the input array has the proper length, then processing + * MUST be constant-time, even if the data is not a valid + * encoded point. + * + * - This callback MUST check that the input point is valid. + * + * Returned value is 1 on success, 0 on error. + * + * \param pctx certificate handler context. + * \param data server public key point. + * \param len public key point length / X coordinate length. + * \return 1 on success, 0 on error. + */ + uint32_t (*do_keyx)(const br_ssl_client_certificate_class **pctx, + unsigned char *data, size_t *len); + + /** + * \brief Perform a signature (client authentication). + * + * This callback is invoked when a client certificate was sent, + * and static ECDH is not used. It shall compute a signature, + * using the client's private key, over the provided hash value + * (which is the hash of all previous handshake messages). + * + * On input, the hash value to sign is in `data`, of size + * `hv_len`; the involved hash function is identified by + * `hash_id`. The signature shall be computed and written + * back into `data`; the total size of that buffer is `len` + * bytes. + * + * This callback shall verify that the signature length does not + * exceed `len` bytes, and abstain from writing the signature if + * it does not fit. + * + * For RSA signatures, the `hash_id` may be 0, in which case + * this is the special header-less signature specified in TLS 1.0 + * and 1.1, with a 36-byte hash value. Otherwise, normal PKCS#1 + * v1.5 signatures shall be computed. + * + * For ECDSA signatures, the signature value shall use the ASN.1 + * based encoding. + * + * Returned value is the signature length (in bytes), or 0 on error. + * + * \param pctx certificate handler context. + * \param hash_id hash function identifier. + * \param hv_len hash value length (in bytes). + * \param data input/output buffer (hash value, then signature). + * \param len total buffer length (in bytes). + * \return signature length (in bytes) on success, or 0 on error. + */ + size_t (*do_sign)(const br_ssl_client_certificate_class **pctx, + int hash_id, size_t hv_len, unsigned char *data, size_t len); +}; + +/** + * \brief A single-chain RSA client certificate handler. + * + * This handler uses a single certificate chain, with a RSA + * signature. The list of trust anchor DN is ignored. + * + * Apart from the first field (vtable pointer), its contents are + * opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_client_certificate_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + const br_x509_certificate *chain; + size_t chain_len; + const br_rsa_private_key *sk; + br_rsa_pkcs1_sign irsasign; +#endif +} br_ssl_client_certificate_rsa_context; + +/** + * \brief A single-chain EC client certificate handler. + * + * This handler uses a single certificate chain, with a RSA + * signature. The list of trust anchor DN is ignored. + * + * This handler may support both static ECDH, and ECDSA signatures + * (either usage may be selectively disabled). + * + * Apart from the first field (vtable pointer), its contents are + * opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_client_certificate_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + const br_x509_certificate *chain; + size_t chain_len; + const br_ec_private_key *sk; + unsigned allowed_usages; + unsigned issuer_key_type; + const br_multihash_context *mhash; + const br_ec_impl *iec; + br_ecdsa_sign iecdsa; +#endif +} br_ssl_client_certificate_ec_context; + +/** + * \brief Context structure for a SSL client. + * + * The first field (called `eng`) is the SSL engine; all functions that + * work on a `br_ssl_engine_context` structure shall take as parameter + * a pointer to that field. The other structure fields are opaque and + * must not be accessed directly. + */ +struct br_ssl_client_context_ { + /** + * \brief The encapsulated engine context. + */ + br_ssl_engine_context eng; + +#ifndef BR_DOXYGEN_IGNORE + /* + * Minimum ClientHello length; padding with an extension (RFC + * 7685) is added if necessary to match at least that length. + * Such padding is nominally unnecessary, but it has been used + * to work around some server implementation bugs. + */ + uint16_t min_clienthello_len; + + /* + * Bit field for algoithms (hash + signature) supported by the + * server when requesting a client certificate. + */ + uint32_t hashes; + + /* + * Server's public key curve. + */ + int server_curve; + + /* + * Context for certificate handler. + */ + const br_ssl_client_certificate_class **client_auth_vtable; + + /* + * Client authentication type. + */ + unsigned char auth_type; + + /* + * Hash function to use for the client signature. This is 0xFF + * if static ECDH is used. + */ + unsigned char hash_id; + + /* + * For the core certificate handlers, thus avoiding (in most + * cases) the need for an externally provided policy context. + */ + union { + const br_ssl_client_certificate_class *vtable; + br_ssl_client_certificate_rsa_context single_rsa; + br_ssl_client_certificate_ec_context single_ec; + } client_auth; + + /* + * Implementations. + */ + br_rsa_public irsapub; +#endif +}; + +/** + * \brief Get the hash functions and signature algorithms supported by + * the server. + * + * This value is a bit field: + * + * - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`, + * then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1, + * or 2 to 6 for the SHA family). + * + * - If ECDSA is supported with hash function of ID `x`, then bit `8+x` + * is set. + * + * - Newer algorithms are symbolic 16-bit identifiers that do not + * represent signature algorithm and hash function separately. If + * the TLS-level identifier is `0x0800+x` for a `x` in the 0..15 + * range, then bit `16+x` is set. + * + * "New algorithms" are currently defined only in draft documents, so + * this support is subject to possible change. Right now (early 2017), + * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA + * on Curve448) to bit 24. If the identifiers on the wire change in + * future document, then the decoding mechanism in BearSSL will be + * amended to keep mapping ed25519 and ed448 on bits 23 and 24, + * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not + * guaranteed yet. + * + * \param cc client context. + * \return the server-supported hash functions and signature algorithms. + */ +static __inline uint32_t +br_ssl_client_get_server_hashes(const br_ssl_client_context *cc) +{ + return cc->hashes; +} + +/** + * \brief Get the server key curve. + * + * This function returns the ID for the curve used by the server's public + * key. This is set when the server's certificate chain is processed; + * this value is 0 if the server's key is not an EC key. + * + * \return the server's public key curve ID, or 0. + */ +static __inline int +br_ssl_client_get_server_curve(const br_ssl_client_context *cc) +{ + return cc->server_curve; +} + +/* + * Each br_ssl_client_init_xxx() function sets the list of supported + * cipher suites and used implementations, as specified by the profile + * name 'xxx'. Defined profile names are: + * + * full all supported versions and suites; constant-time implementations + * TODO: add other profiles + */ + +/** + * \brief SSL client profile: full. + * + * This function initialises the provided SSL client context with + * all supported algorithms and cipher suites. It also initialises + * a companion X.509 validation engine with all supported algorithms, + * and the provided trust anchors; the X.509 engine will be used by + * the client context to validate the server's certificate. + * + * \param cc client context to initialise. + * \param xc X.509 validation context to initialise. + * \param trust_anchors trust anchors to use. + * \param trust_anchors_num number of trust anchors. + */ +void br_ssl_client_init_full(br_ssl_client_context *cc, + br_x509_minimal_context *xc, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); + +/** + * \brief Clear the complete contents of a SSL client context. + * + * Everything is cleared, including the reference to the configured buffer, + * implementations, cipher suites and state. This is a preparatory step + * to assembling a custom profile. + * + * \param cc client context to clear. + */ +void br_ssl_client_zero(br_ssl_client_context *cc); + +/** + * \brief Set an externally provided client certificate handler context. + * + * The handler's methods are invoked when the server requests a client + * certificate. + * + * \param cc client context. + * \param pctx certificate handler context (pointer to its vtable field). + */ +static __inline void +br_ssl_client_set_client_certificate(br_ssl_client_context *cc, + const br_ssl_client_certificate_class **pctx) +{ + cc->client_auth_vtable = pctx; +} + +/** + * \brief Set the RSA public-key operations implementation. + * + * This will be used to encrypt the pre-master secret with the server's + * RSA public key (RSA-encryption cipher suites only). + * + * \param cc client context. + * \param irsapub RSA public-key encryption implementation. + */ +static __inline void +br_ssl_client_set_rsapub(br_ssl_client_context *cc, br_rsa_public irsapub) +{ + cc->irsapub = irsapub; +} + +/** + * \brief Set the "default" RSA implementation for public-key operations. + * + * This sets the RSA implementation in the client context (for encrypting + * the pre-master secret, in `TLS_RSA_*` cipher suites) to the fastest + * available on the current platform. + * + * \param cc client context. + */ +void br_ssl_client_set_default_rsapub(br_ssl_client_context *cc); + +/** + * \brief Set the minimum ClientHello length (RFC 7685 padding). + * + * If this value is set and the ClientHello would be shorter, then + * the Pad ClientHello extension will be added with enough padding bytes + * to reach the target size. Because of the extension header, the resulting + * size will sometimes be slightly more than `len` bytes if the target + * size cannot be exactly met. + * + * The target length relates to the _contents_ of the ClientHello, not + * counting its 4-byte header. For instance, if `len` is set to 512, + * then the padding will bring the ClientHello size to 516 bytes with its + * header, and 521 bytes when counting the 5-byte record header. + * + * \param cc client context. + * \param len minimum ClientHello length (in bytes). + */ +static __inline void +br_ssl_client_set_min_clienthello_len(br_ssl_client_context *cc, uint16_t len) +{ + cc->min_clienthello_len = len; +} + +/** + * \brief Prepare or reset a client context for a new connection. + * + * The `server_name` parameter is used to fill the SNI extension; the + * X.509 "minimal" engine will also match that name against the server + * names included in the server's certificate. If the parameter is + * `NULL` then no SNI extension will be sent, and the X.509 "minimal" + * engine (if used for server certificate validation) will not check + * presence of any specific name in the received certificate. + * + * Therefore, setting the `server_name` to `NULL` shall be reserved + * to cases where alternate or additional methods are used to ascertain + * that the right server public key is used (e.g. a "known key" model). + * + * If `resume_session` is non-zero and the context was previously used + * then the session parameters may be reused (depending on whether the + * server previously sent a non-empty session ID, and accepts the session + * resumption). The session parameters for session resumption can also + * be set explicitly with `br_ssl_engine_set_session_parameters()`. + * + * On failure, the context is marked as failed, and this function + * returns 0. A possible failure condition is when no initial entropy + * was injected, and none could be obtained from the OS (either OS + * randomness gathering is not supported, or it failed). + * + * \param cc client context. + * \param server_name target server name, or `NULL`. + * \param resume_session non-zero to try session resumption. + * \return 0 on failure, 1 on success. + */ +int br_ssl_client_reset(br_ssl_client_context *cc, + const char *server_name, int resume_session); + +/** + * \brief Forget any session in the context. + * + * This means that the next handshake that uses this context will + * necessarily be a full handshake (this applies both to new connections + * and to renegotiations). + * + * \param cc client context. + */ +static __inline void +br_ssl_client_forget_session(br_ssl_client_context *cc) +{ + cc->eng.session.session_id_len = 0; +} + +/** + * \brief Set client certificate chain and key (single RSA case). + * + * This function sets a client certificate chain, that the client will + * send to the server whenever a client certificate is requested. This + * certificate uses an RSA public key; the corresponding private key is + * invoked for authentication. Trust anchor names sent by the server are + * ignored. + * + * The provided chain and private key are linked in the client context; + * they must remain valid as long as they may be used, i.e. normally + * for the duration of the connection, since they might be invoked + * again upon renegotiations. + * + * \param cc SSL client context. + * \param chain client certificate chain (SSL order: EE comes first). + * \param chain_len client chain length (number of certificates). + * \param sk client private key. + * \param irsasign RSA signature implementation (PKCS#1 v1.5). + */ +void br_ssl_client_set_single_rsa(br_ssl_client_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk, br_rsa_pkcs1_sign irsasign); + +/* + * \brief Set the client certificate chain and key (single EC case). + * + * This function sets a client certificate chain, that the client will + * send to the server whenever a client certificate is requested. This + * certificate uses an EC public key; the corresponding private key is + * invoked for authentication. Trust anchor names sent by the server are + * ignored. + * + * The provided chain and private key are linked in the client context; + * they must remain valid as long as they may be used, i.e. normally + * for the duration of the connection, since they might be invoked + * again upon renegotiations. + * + * The `allowed_usages` is a combination of usages, namely + * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`. The `BR_KEYTYPE_KEYX` + * value allows full static ECDH, while the `BR_KEYTYPE_SIGN` value + * allows ECDSA signatures. If ECDSA signatures are used, then an ECDSA + * signature implementation must be provided; otherwise, the `iecdsa` + * parameter may be 0. + * + * The `cert_issuer_key_type` value is either `BR_KEYTYPE_RSA` or + * `BR_KEYTYPE_EC`; it is the type of the public key used the the CA + * that issued (signed) the client certificate. That value is used with + * full static ECDH: support of the certificate by the server depends + * on how the certificate was signed. (Note: when using TLS 1.2, this + * parameter is ignored; but its value matters for TLS 1.0 and 1.1.) + * + * \param cc server context. + * \param chain server certificate chain to send. + * \param chain_len chain length (number of certificates). + * \param sk server private key (EC). + * \param allowed_usages allowed private key usages. + * \param cert_issuer_key_type issuing CA's key type. + * \param iec EC core implementation. + * \param iecdsa ECDSA signature implementation ("asn1" format). + */ +void br_ssl_client_set_single_ec(br_ssl_client_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk, unsigned allowed_usages, + unsigned cert_issuer_key_type, + const br_ec_impl *iec, br_ecdsa_sign iecdsa); + +/** + * \brief Type for a "translated cipher suite", as an array of two + * 16-bit integers. + * + * The first element is the cipher suite identifier (as used on the wire). + * The second element is the concatenation of four 4-bit elements which + * characterise the cipher suite contents. In most to least significant + * order, these 4-bit elements are: + * + * - Bits 12 to 15: key exchange + server key type + * + * | val | symbolic constant | suite type | details | + * | :-- | :----------------------- | :---------- | :----------------------------------------------- | + * | 0 | `BR_SSLKEYX_RSA` | RSA | RSA key exchange, key is RSA (encryption) | + * | 1 | `BR_SSLKEYX_ECDHE_RSA` | ECDHE_RSA | ECDHE key exchange, key is RSA (signature) | + * | 2 | `BR_SSLKEYX_ECDHE_ECDSA` | ECDHE_ECDSA | ECDHE key exchange, key is EC (signature) | + * | 3 | `BR_SSLKEYX_ECDH_RSA` | ECDH_RSA | Key is EC (key exchange), cert signed with RSA | + * | 4 | `BR_SSLKEYX_ECDH_ECDSA` | ECDH_ECDSA | Key is EC (key exchange), cert signed with ECDSA | + * + * - Bits 8 to 11: symmetric encryption algorithm + * + * | val | symbolic constant | symmetric encryption | key strength (bits) | + * | :-- | :--------------------- | :------------------- | :------------------ | + * | 0 | `BR_SSLENC_3DES_CBC` | 3DES/CBC | 168 | + * | 1 | `BR_SSLENC_AES128_CBC` | AES-128/CBC | 128 | + * | 2 | `BR_SSLENC_AES256_CBC` | AES-256/CBC | 256 | + * | 3 | `BR_SSLENC_AES128_GCM` | AES-128/GCM | 128 | + * | 4 | `BR_SSLENC_AES256_GCM` | AES-256/GCM | 256 | + * | 5 | `BR_SSLENC_CHACHA20` | ChaCha20/Poly1305 | 256 | + * + * - Bits 4 to 7: MAC algorithm + * + * | val | symbolic constant | MAC type | details | + * | :-- | :----------------- | :----------- | :------------------------------------ | + * | 0 | `BR_SSLMAC_AEAD` | AEAD | No dedicated MAC (encryption is AEAD) | + * | 2 | `BR_SSLMAC_SHA1` | HMAC/SHA-1 | Value matches `br_sha1_ID` | + * | 4 | `BR_SSLMAC_SHA256` | HMAC/SHA-256 | Value matches `br_sha256_ID` | + * | 5 | `BR_SSLMAC_SHA384` | HMAC/SHA-384 | Value matches `br_sha384_ID` | + * + * - Bits 0 to 3: hash function for PRF when used with TLS-1.2 + * + * | val | symbolic constant | hash function | details | + * | :-- | :----------------- | :------------ | :----------------------------------- | + * | 4 | `BR_SSLPRF_SHA256` | SHA-256 | Value matches `br_sha256_ID` | + * | 5 | `BR_SSLPRF_SHA384` | SHA-384 | Value matches `br_sha384_ID` | + * + * For instance, cipher suite `TLS_RSA_WITH_AES_128_GCM_SHA256` has + * standard identifier 0x009C, and is translated to 0x0304, for, in + * that order: RSA key exchange (0), AES-128/GCM (3), AEAD integrity (0), + * SHA-256 in the TLS PRF (4). + */ +typedef uint16_t br_suite_translated[2]; + +#ifndef BR_DOXYGEN_IGNORE +/* + * Constants are already documented in the br_suite_translated type. + */ + +#define BR_SSLKEYX_RSA 0 +#define BR_SSLKEYX_ECDHE_RSA 1 +#define BR_SSLKEYX_ECDHE_ECDSA 2 +#define BR_SSLKEYX_ECDH_RSA 3 +#define BR_SSLKEYX_ECDH_ECDSA 4 + +#define BR_SSLENC_3DES_CBC 0 +#define BR_SSLENC_AES128_CBC 1 +#define BR_SSLENC_AES256_CBC 2 +#define BR_SSLENC_AES128_GCM 3 +#define BR_SSLENC_AES256_GCM 4 +#define BR_SSLENC_CHACHA20 5 + +#define BR_SSLMAC_AEAD 0 +#define BR_SSLMAC_SHA1 br_sha1_ID +#define BR_SSLMAC_SHA256 br_sha256_ID +#define BR_SSLMAC_SHA384 br_sha384_ID + +#define BR_SSLPRF_SHA256 br_sha256_ID +#define BR_SSLPRF_SHA384 br_sha384_ID + +#endif + +/* + * Pre-declaration for the SSL server context. + */ +typedef struct br_ssl_server_context_ br_ssl_server_context; + +/** + * \brief Type for the server policy choices, taken after analysis of + * the client message (ClientHello). + */ +typedef struct { + /** + * \brief Cipher suite to use with that client. + */ + uint16_t cipher_suite; + + /** + * \brief Hash function or algorithm for signing the ServerKeyExchange. + * + * This parameter is ignored for `TLS_RSA_*` and `TLS_ECDH_*` + * cipher suites; it is used only for `TLS_ECDHE_*` suites, in + * which the server _signs_ the ephemeral EC Diffie-Hellman + * parameters sent to the client. + * + * This identifier must be one of the following values: + * + * - `0xFF00 + id`, where `id` is a hash function identifier + * (0 for MD5+SHA-1, or 2 to 6 for one of the SHA functions); + * + * - a full 16-bit identifier, lower than `0xFF00`. + * + * If the first option is used, then the SSL engine will + * compute the hash of the data that is to be signed, with the + * designated hash function. The `do_sign()` method will be + * invoked with that hash value provided in the the `data` + * buffer. + * + * If the second option is used, then the SSL engine will NOT + * compute a hash on the data; instead, it will provide the + * to-be-signed data itself in `data`, i.e. the concatenation of + * the client random, server random, and encoded ECDH + * parameters. Furthermore, with TLS-1.2 and later, the 16-bit + * identifier will be used "as is" in the protocol, in the + * SignatureAndHashAlgorithm; for instance, `0x0401` stands for + * RSA PKCS#1 v1.5 signature (the `01`) with SHA-256 as hash + * function (the `04`). + * + * Take care that with TLS 1.0 and 1.1, the hash function is + * constrainted by the protocol: RSA signature must use + * MD5+SHA-1 (so use `0xFF00`), while ECDSA must use SHA-1 + * (`0xFF02`). Since TLS 1.0 and 1.1 don't include a + * SignatureAndHashAlgorithm field in their ServerKeyExchange + * messages, any value below `0xFF00` will be usable to send the + * raw ServerKeyExchange data to the `do_sign()` callback, but + * that callback must still follow the protocol requirements + * when generating the signature. + */ + unsigned algo_id; + + /** + * \brief Certificate chain to send to the client. + * + * This is an array of `br_x509_certificate` objects, each + * normally containing a DER-encoded certificate. The server + * code does not try to decode these elements. + */ + const br_x509_certificate *chain; + + /** + * \brief Certificate chain length (number of certificates). + */ + size_t chain_len; + +} br_ssl_server_choices; + +/** + * \brief Class type for a policy handler (server side). + * + * A policy handler selects the policy parameters for a connection + * (cipher suite and other algorithms, and certificate chain to send to + * the client); it also performs the server-side computations involving + * its permanent private key. + * + * The SSL server engine will invoke first `choose()`, once the + * ClientHello message has been received, then either `do_keyx()` + * `do_sign()`, depending on the cipher suite. + */ +typedef struct br_ssl_server_policy_class_ br_ssl_server_policy_class; +struct br_ssl_server_policy_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Select algorithms and certificates for this connection. + * + * This callback function shall fill the provided `choices` + * structure with the policy choices for this connection. This + * entails selecting the cipher suite, hash function for signing + * the ServerKeyExchange (applicable only to ECDHE cipher suites), + * and certificate chain to send. + * + * The callback receives a pointer to the server context that + * contains the relevant data. In particular, the functions + * `br_ssl_server_get_client_suites()`, + * `br_ssl_server_get_client_hashes()` and + * `br_ssl_server_get_client_curves()` can be used to obtain + * the cipher suites, hash functions and elliptic curves + * supported by both the client and server, respectively. The + * `br_ssl_engine_get_version()` and `br_ssl_engine_get_server_name()` + * functions yield the protocol version and requested server name + * (SNI), respectively. + * + * This function may modify its context structure (`pctx`) in + * arbitrary ways to keep track of its own choices. + * + * This function shall return 1 if appropriate policy choices + * could be made, or 0 if this connection cannot be pursued. + * + * \param pctx policy context. + * \param cc SSL server context. + * \param choices destination structure for the policy choices. + * \return 1 on success, 0 on error. + */ + int (*choose)(const br_ssl_server_policy_class **pctx, + const br_ssl_server_context *cc, + br_ssl_server_choices *choices); + + /** + * \brief Perform key exchange (server part). + * + * This callback is invoked to perform the server-side cryptographic + * operation for a key exchange that is not ECDHE. This callback + * uses the private key. + * + * **For RSA key exchange**, the provided `data` (of length `*len` + * bytes) shall be decrypted with the server's private key, and + * the 48-byte premaster secret copied back to the first 48 bytes + * of `data`. + * + * - The caller makes sure that `*len` is at least 59 bytes. + * + * - This callback MUST check that the provided length matches + * that of the key modulus; it shall report an error otherwise. + * + * - If the length matches that of the RSA key modulus, then + * processing MUST be constant-time, even if decryption fails, + * or the padding is incorrect, or the plaintext message length + * is not exactly 48 bytes. + * + * - This callback needs not check the two first bytes of the + * obtained pre-master secret (the caller will do that). + * + * - If an error is reported (0), then what the callback put + * in the first 48 bytes of `data` is unimportant (the caller + * will use random bytes instead). + * + * **For ECDH key exchange**, the provided `data` (of length `*len` + * bytes) is the elliptic curve point from the client. The + * callback shall multiply it with its private key, and store + * the resulting X coordinate in `data`, starting at offset 0, + * and set `*len` to the length of the X coordinate. + * + * - If the input array does not have the proper length for + * an encoded curve point, then an error (0) shall be reported. + * + * - If the input array has the proper length, then processing + * MUST be constant-time, even if the data is not a valid + * encoded point. + * + * - This callback MUST check that the input point is valid. + * + * Returned value is 1 on success, 0 on error. + * + * \param pctx policy context. + * \param data key exchange data from the client. + * \param len key exchange data length (in bytes). + * \return 1 on success, 0 on error. + */ + uint32_t (*do_keyx)(const br_ssl_server_policy_class **pctx, + unsigned char *data, size_t *len); + + /** + * \brief Perform a signature (for a ServerKeyExchange message). + * + * This callback function is invoked for ECDHE cipher suites. On + * input, the hash value or message to sign is in `data`, of + * size `hv_len`; the involved hash function or algorithm is + * identified by `algo_id`. The signature shall be computed and + * written back into `data`; the total size of that buffer is + * `len` bytes. + * + * This callback shall verify that the signature length does not + * exceed `len` bytes, and abstain from writing the signature if + * it does not fit. + * + * The `algo_id` value matches that which was written in the + * `choices` structures by the `choose()` callback. This will be + * one of the following: + * + * - `0xFF00 + id` for a hash function identifier `id`. In + * that case, the `data` buffer contains a hash value + * already computed over the data that is to be signed, + * of length `hv_len`. The `id` may be 0 to designate the + * special MD5+SHA-1 concatenation (old-style RSA signing). + * + * - Another value, lower than `0xFF00`. The `data` buffer + * then contains the raw, non-hashed data to be signed + * (concatenation of the client and server randoms and + * ECDH parameters). The callback is responsible to apply + * any relevant hashing as part of the signing process. + * + * Returned value is the signature length (in bytes), or 0 on error. + * + * \param pctx policy context. + * \param algo_id hash function / algorithm identifier. + * \param data input/output buffer (message/hash, then signature). + * \param hv_len hash value or message length (in bytes). + * \param len total buffer length (in bytes). + * \return signature length (in bytes) on success, or 0 on error. + */ + size_t (*do_sign)(const br_ssl_server_policy_class **pctx, + unsigned algo_id, + unsigned char *data, size_t hv_len, size_t len); +}; + +/** + * \brief A single-chain RSA policy handler. + * + * This policy context uses a single certificate chain, and a RSA + * private key. The context can be restricted to only signatures or + * only key exchange. + * + * Apart from the first field (vtable pointer), its contents are + * opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_server_policy_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + const br_x509_certificate *chain; + size_t chain_len; + const br_rsa_private_key *sk; + unsigned allowed_usages; + br_rsa_private irsacore; + br_rsa_pkcs1_sign irsasign; +#endif +} br_ssl_server_policy_rsa_context; + +/** + * \brief A single-chain EC policy handler. + * + * This policy context uses a single certificate chain, and an EC + * private key. The context can be restricted to only signatures or + * only key exchange. + * + * Due to how TLS is defined, this context must be made aware whether + * the server certificate was itself signed with RSA or ECDSA. The code + * does not try to decode the certificate to obtain that information. + * + * Apart from the first field (vtable pointer), its contents are + * opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_server_policy_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + const br_x509_certificate *chain; + size_t chain_len; + const br_ec_private_key *sk; + unsigned allowed_usages; + unsigned cert_issuer_key_type; + const br_multihash_context *mhash; + const br_ec_impl *iec; + br_ecdsa_sign iecdsa; +#endif +} br_ssl_server_policy_ec_context; + +/** + * \brief Class type for a session parameter cache. + * + * Session parameters are saved in the cache with `save()`, and + * retrieved with `load()`. The cache implementation can apply any + * storage and eviction strategy that it sees fit. The SSL server + * context that performs the request is provided, so that its + * functionalities may be used by the implementation (e.g. hash + * functions or random number generation). + */ +typedef struct br_ssl_session_cache_class_ br_ssl_session_cache_class; +struct br_ssl_session_cache_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Record a session. + * + * This callback should record the provided session parameters. + * The `params` structure is transient, so its contents shall + * be copied into the cache. The session ID has been randomly + * generated and always has length exactly 32 bytes. + * + * \param ctx session cache context. + * \param server_ctx SSL server context. + * \param params session parameters to save. + */ + void (*save)(const br_ssl_session_cache_class **ctx, + br_ssl_server_context *server_ctx, + const br_ssl_session_parameters *params); + + /** + * \brief Lookup a session in the cache. + * + * The session ID to lookup is in `params` and always has length + * exactly 32 bytes. If the session parameters are found in the + * cache, then the parameters shall be copied into the `params` + * structure. Returned value is 1 on successful lookup, 0 + * otherwise. + * + * \param ctx session cache context. + * \param server_ctx SSL server context. + * \param params destination for session parameters. + * \return 1 if found, 0 otherwise. + */ + int (*load)(const br_ssl_session_cache_class **ctx, + br_ssl_server_context *server_ctx, + br_ssl_session_parameters *params); +}; + +/** + * \brief Context for a basic cache system. + * + * The system stores session parameters in a buffer provided at + * initialisation time. Each entry uses exactly 100 bytes, and + * buffer sizes up to 4294967295 bytes are supported. + * + * Entries are evicted with a LRU (Least Recently Used) policy. A + * search tree is maintained to keep lookups fast even with large + * caches. + * + * Apart from the first field (vtable pointer), the structure + * contents are opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_session_cache_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char *store; + size_t store_len, store_ptr; + unsigned char index_key[32]; + const br_hash_class *hash; + int init_done; + uint32_t head, tail, root; +#endif +} br_ssl_session_cache_lru; + +/** + * \brief Initialise a LRU session cache with the provided storage space. + * + * The provided storage space must remain valid as long as the cache + * is used. Arbitrary lengths are supported, up to 4294967295 bytes; + * each entry uses up exactly 100 bytes. + * + * \param cc session cache context. + * \param store storage space for cached entries. + * \param store_len storage space length (in bytes). + */ +void br_ssl_session_cache_lru_init(br_ssl_session_cache_lru *cc, + unsigned char *store, size_t store_len); + +/** + * \brief Forget an entry in an LRU session cache. + * + * The session cache context must have been initialised. The entry + * with the provided session ID (of exactly 32 bytes) is looked for + * in the cache; if located, it is disabled. + * + * \param cc session cache context. + * \param id session ID to forget. + */ +void br_ssl_session_cache_lru_forget( + br_ssl_session_cache_lru *cc, const unsigned char *id); + +/** + * \brief Context structure for a SSL server. + * + * The first field (called `eng`) is the SSL engine; all functions that + * work on a `br_ssl_engine_context` structure shall take as parameter + * a pointer to that field. The other structure fields are opaque and + * must not be accessed directly. + */ +struct br_ssl_server_context_ { + /** + * \brief The encapsulated engine context. + */ + br_ssl_engine_context eng; + +#ifndef BR_DOXYGEN_IGNORE + /* + * Maximum version from the client. + */ + uint16_t client_max_version; + + /* + * Session cache. + */ + const br_ssl_session_cache_class **cache_vtable; + + /* + * Translated cipher suites supported by the client. The list + * is trimmed to include only the cipher suites that the + * server also supports; they are in the same order as in the + * client message. + */ + br_suite_translated client_suites[BR_MAX_CIPHER_SUITES]; + unsigned char client_suites_num; + + /* + * Hash functions supported by the client, with ECDSA and RSA + * (bit mask). For hash function with id 'x', set bit index is + * x for RSA, x+8 for ECDSA. For newer algorithms, with ID + * 0x08**, bit 16+k is set for algorithm 0x0800+k. + */ + uint32_t hashes; + + /* + * Curves supported by the client (bit mask, for named curves). + */ + uint32_t curves; + + /* + * Context for chain handler. + */ + const br_ssl_server_policy_class **policy_vtable; + uint16_t sign_hash_id; + + /* + * For the core handlers, thus avoiding (in most cases) the + * need for an externally provided policy context. + */ + union { + const br_ssl_server_policy_class *vtable; + br_ssl_server_policy_rsa_context single_rsa; + br_ssl_server_policy_ec_context single_ec; + } chain_handler; + + /* + * Buffer for the ECDHE private key. + */ + unsigned char ecdhe_key[70]; + size_t ecdhe_key_len; + + /* + * Trust anchor names for client authentication. "ta_names" and + * "tas" cannot be both non-NULL. + */ + const br_x500_name *ta_names; + const br_x509_trust_anchor *tas; + size_t num_tas; + size_t cur_dn_index; + const unsigned char *cur_dn; + size_t cur_dn_len; + + /* + * Buffer for the hash value computed over all handshake messages + * prior to CertificateVerify, and identifier for the hash function. + */ + unsigned char hash_CV[64]; + size_t hash_CV_len; + int hash_CV_id; + + /* + * Server-specific implementations. + * (none for now) + */ +#endif +}; + +/* + * Each br_ssl_server_init_xxx() function sets the list of supported + * cipher suites and used implementations, as specified by the profile + * name 'xxx'. Defined profile names are: + * + * full_rsa all supported algorithm, server key type is RSA + * full_ec all supported algorithm, server key type is EC + * TODO: add other profiles + * + * Naming scheme for "minimal" profiles: min123 + * + * -- character 1: key exchange + * r = RSA + * e = ECDHE_RSA + * f = ECDHE_ECDSA + * u = ECDH_RSA + * v = ECDH_ECDSA + * -- character 2: version / PRF + * 0 = TLS 1.0 / 1.1 with MD5+SHA-1 + * 2 = TLS 1.2 with SHA-256 + * 3 = TLS 1.2 with SHA-384 + * -- character 3: encryption + * a = AES/CBC + * d = 3DES/CBC + * g = AES/GCM + * c = ChaCha20+Poly1305 + */ + +/** + * \brief SSL server profile: full_rsa. + * + * This function initialises the provided SSL server context with + * all supported algorithms and cipher suites that rely on a RSA + * key pair. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_full_rsa(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: full_ec. + * + * This function initialises the provided SSL server context with + * all supported algorithms and cipher suites that rely on an EC + * key pair. + * + * The key type of the CA that issued the server's certificate must + * be provided, since it matters for ECDH cipher suites (ECDH_RSA + * suites require a RSA-powered CA). The key type is either + * `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len chain length (number of certificates). + * \param cert_issuer_key_type certificate issuer's key type. + * \param sk EC private key. + */ +void br_ssl_server_init_full_ec(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + unsigned cert_issuer_key_type, const br_ec_private_key *sk); + +/** + * \brief SSL server profile: minr2g. + * + * This profile uses only TLS_RSA_WITH_AES_128_GCM_SHA256. Server key is + * RSA, and RSA key exchange is used (not forward secure, but uses little + * CPU in the client). + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_minr2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: mine2g. + * + * This profile uses only TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256. Server key + * is RSA, and ECDHE key exchange is used. This suite provides forward + * security, with a higher CPU expense on the client, and a somewhat + * larger code footprint (compared to "minr2g"). + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_mine2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: minf2g. + * + * This profile uses only TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256. + * Server key is EC, and ECDHE key exchange is used. This suite provides + * forward security, with a higher CPU expense on the client and server + * (by a factor of about 3 to 4), and a somewhat larger code footprint + * (compared to "minu2g" and "minv2g"). + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minf2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + +/** + * \brief SSL server profile: minu2g. + * + * This profile uses only TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256. + * Server key is EC, and ECDH key exchange is used; the issuing CA used + * a RSA key. + * + * The "minu2g" and "minv2g" profiles do not provide forward secrecy, + * but are the lightest on the server (for CPU usage), and are rather + * inexpensive on the client as well. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minu2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + +/** + * \brief SSL server profile: minv2g. + * + * This profile uses only TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256. + * Server key is EC, and ECDH key exchange is used; the issuing CA used + * an EC key. + * + * The "minu2g" and "minv2g" profiles do not provide forward secrecy, + * but are the lightest on the server (for CPU usage), and are rather + * inexpensive on the client as well. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minv2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + +/** + * \brief SSL server profile: mine2c. + * + * This profile uses only TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256. + * Server key is RSA, and ECDHE key exchange is used. This suite + * provides forward security. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_mine2c(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: minf2c. + * + * This profile uses only TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256. + * Server key is EC, and ECDHE key exchange is used. This suite provides + * forward security. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minf2c(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + +/** + * \brief Get the supported client suites. + * + * This function shall be called only after the ClientHello has been + * processed, typically from the policy engine. The returned array + * contains the cipher suites that are supported by both the client + * and the server; these suites are in client preference order, unless + * the `BR_OPT_ENFORCE_SERVER_PREFERENCES` flag was set, in which case + * they are in server preference order. + * + * The suites are _translated_, which means that each suite is given + * as two 16-bit integers: the standard suite identifier, and its + * translated version, broken down into its individual components, + * as explained with the `br_suite_translated` type. + * + * The returned array is allocated in the context and will be rewritten + * by each handshake. + * + * \param cc server context. + * \param num receives the array size (number of suites). + * \return the translated common cipher suites, in preference order. + */ +static __inline const br_suite_translated * +br_ssl_server_get_client_suites(const br_ssl_server_context *cc, size_t *num) +{ + *num = cc->client_suites_num; + return cc->client_suites; +} + +/** + * \brief Get the hash functions and signature algorithms supported by + * the client. + * + * This value is a bit field: + * + * - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`, + * then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1, + * or 2 to 6 for the SHA family). + * + * - If ECDSA is supported with hash function of ID `x`, then bit `8+x` + * is set. + * + * - Newer algorithms are symbolic 16-bit identifiers that do not + * represent signature algorithm and hash function separately. If + * the TLS-level identifier is `0x0800+x` for a `x` in the 0..15 + * range, then bit `16+x` is set. + * + * "New algorithms" are currently defined only in draft documents, so + * this support is subject to possible change. Right now (early 2017), + * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA + * on Curve448) to bit 24. If the identifiers on the wire change in + * future document, then the decoding mechanism in BearSSL will be + * amended to keep mapping ed25519 and ed448 on bits 23 and 24, + * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not + * guaranteed yet. + * + * \param cc server context. + * \return the client-supported hash functions and signature algorithms. + */ +static __inline uint32_t +br_ssl_server_get_client_hashes(const br_ssl_server_context *cc) +{ + return cc->hashes; +} + +/** + * \brief Get the elliptic curves supported by the client. + * + * This is a bit field (bit x is set if curve of ID x is supported). + * + * \param cc server context. + * \return the client-supported elliptic curves. + */ +static __inline uint32_t +br_ssl_server_get_client_curves(const br_ssl_server_context *cc) +{ + return cc->curves; +} + +/** + * \brief Clear the complete contents of a SSL server context. + * + * Everything is cleared, including the reference to the configured buffer, + * implementations, cipher suites and state. This is a preparatory step + * to assembling a custom profile. + * + * \param cc server context to clear. + */ +void br_ssl_server_zero(br_ssl_server_context *cc); + +/** + * \brief Set an externally provided policy context. + * + * The policy context's methods are invoked to decide the cipher suite + * and certificate chain, and to perform operations involving the server's + * private key. + * + * \param cc server context. + * \param pctx policy context (pointer to its vtable field). + */ +static __inline void +br_ssl_server_set_policy(br_ssl_server_context *cc, + const br_ssl_server_policy_class **pctx) +{ + cc->policy_vtable = pctx; +} + +/** + * \brief Set the server certificate chain and key (single RSA case). + * + * This function uses a policy context included in the server context. + * It configures use of a single server certificate chain with a RSA + * private key. The `allowed_usages` is a combination of usages, namely + * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`; this enables or disables + * the corresponding cipher suites (i.e. `TLS_RSA_*` use the RSA key for + * key exchange, while `TLS_ECDHE_RSA_*` use the RSA key for signatures). + * + * \param cc server context. + * \param chain server certificate chain to send to the client. + * \param chain_len chain length (number of certificates). + * \param sk server private key (RSA). + * \param allowed_usages allowed private key usages. + * \param irsacore RSA core implementation. + * \param irsasign RSA signature implementation (PKCS#1 v1.5). + */ +void br_ssl_server_set_single_rsa(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk, unsigned allowed_usages, + br_rsa_private irsacore, br_rsa_pkcs1_sign irsasign); + +/** + * \brief Set the server certificate chain and key (single EC case). + * + * This function uses a policy context included in the server context. + * It configures use of a single server certificate chain with an EC + * private key. The `allowed_usages` is a combination of usages, namely + * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`; this enables or disables + * the corresponding cipher suites (i.e. `TLS_ECDH_*` use the EC key for + * key exchange, while `TLS_ECDHE_ECDSA_*` use the EC key for signatures). + * + * In order to support `TLS_ECDH_*` cipher suites (non-ephemeral ECDH), + * the algorithm type of the key used by the issuing CA to sign the + * server's certificate must be provided, as `cert_issuer_key_type` + * parameter (this value is either `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`). + * + * \param cc server context. + * \param chain server certificate chain to send. + * \param chain_len chain length (number of certificates). + * \param sk server private key (EC). + * \param allowed_usages allowed private key usages. + * \param cert_issuer_key_type issuing CA's key type. + * \param iec EC core implementation. + * \param iecdsa ECDSA signature implementation ("asn1" format). + */ +void br_ssl_server_set_single_ec(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk, unsigned allowed_usages, + unsigned cert_issuer_key_type, + const br_ec_impl *iec, br_ecdsa_sign iecdsa); + +/** + * \brief Activate client certificate authentication. + * + * The trust anchor encoded X.500 names (DN) to send to the client are + * provided. A client certificate will be requested and validated through + * the X.509 validator configured in the SSL engine. If `num` is 0, then + * client certificate authentication is disabled. + * + * If the client does not send a certificate, or on validation failure, + * the handshake aborts. Unauthenticated clients can be tolerated by + * setting the `BR_OPT_TOLERATE_NO_CLIENT_AUTH` flag. + * + * The provided array is linked in, not copied, so that pointer must + * remain valid as long as anchor names may be used. + * + * \param cc server context. + * \param ta_names encoded trust anchor names. + * \param num number of encoded trust anchor names. + */ +static __inline void +br_ssl_server_set_trust_anchor_names(br_ssl_server_context *cc, + const br_x500_name *ta_names, size_t num) +{ + cc->ta_names = ta_names; + cc->tas = NULL; + cc->num_tas = num; +} + +/** + * \brief Activate client certificate authentication. + * + * This is a variant for `br_ssl_server_set_trust_anchor_names()`: the + * trust anchor names are provided not as an array of stand-alone names + * (`br_x500_name` structures), but as an array of trust anchors + * (`br_x509_trust_anchor` structures). The server engine itself will + * only use the `dn` field of each trust anchor. This is meant to allow + * defining a single array of trust anchors, to be used here and in the + * X.509 validation engine itself. + * + * The provided array is linked in, not copied, so that pointer must + * remain valid as long as anchor names may be used. + * + * \param cc server context. + * \param tas trust anchors (only names are used). + * \param num number of trust anchors. + */ +static __inline void +br_ssl_server_set_trust_anchor_names_alt(br_ssl_server_context *cc, + const br_x509_trust_anchor *tas, size_t num) +{ + cc->ta_names = NULL; + cc->tas = tas; + cc->num_tas = num; +} + +/** + * \brief Configure the cache for session parameters. + * + * The cache context is provided as a pointer to its first field (vtable + * pointer). + * + * \param cc server context. + * \param vtable session cache context. + */ +static __inline void +br_ssl_server_set_cache(br_ssl_server_context *cc, + const br_ssl_session_cache_class **vtable) +{ + cc->cache_vtable = vtable; +} + +/** + * \brief Prepare or reset a server context for handling an incoming client. + * + * \param cc server context. + * \return 1 on success, 0 on error. + */ +int br_ssl_server_reset(br_ssl_server_context *cc); + +/* ===================================================================== */ + +/* + * Context for the simplified I/O context. The transport medium is accessed + * through the low_read() and low_write() callback functions, each with + * its own opaque context pointer. + * + * low_read() read some bytes, at most 'len' bytes, into data[]. The + * returned value is the number of read bytes, or -1 on error. + * The 'len' parameter is guaranteed never to exceed 20000, + * so the length always fits in an 'int' on all platforms. + * + * low_write() write up to 'len' bytes, to be read from data[]. The + * returned value is the number of written bytes, or -1 on + * error. The 'len' parameter is guaranteed never to exceed + * 20000, so the length always fits in an 'int' on all + * parameters. + * + * A socket closure (if the transport medium is a socket) should be reported + * as an error (-1). The callbacks shall endeavour to block until at least + * one byte can be read or written; a callback returning 0 at times is + * acceptable, but this normally leads to the callback being immediately + * called again, so the callback should at least always try to block for + * some time if no I/O can take place. + * + * The SSL engine naturally applies some buffering, so the callbacks need + * not apply buffers of their own. + */ +/** + * \brief Context structure for the simplified SSL I/O wrapper. + * + * This structure is initialised with `br_sslio_init()`. Its contents + * are opaque and shall not be accessed directly. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + br_ssl_engine_context *engine; + int (*low_read)(void *read_context, + unsigned char *data, size_t len); + void *read_context; + int (*low_write)(void *write_context, + const unsigned char *data, size_t len); + void *write_context; +#endif +} br_sslio_context; + +/** + * \brief Initialise a simplified I/O wrapper context. + * + * The simplified I/O wrapper offers a simpler read/write API for a SSL + * engine (client or server), using the provided callback functions for + * reading data from, or writing data to, the transport medium. + * + * The callback functions have the following semantics: + * + * - Each callback receives an opaque context value (of type `void *`) + * that the callback may use arbitrarily (or possibly ignore). + * + * - `low_read()` reads at least one byte, at most `len` bytes, from + * the transport medium. Read bytes shall be written in `data`. + * + * - `low_write()` writes at least one byte, at most `len` bytes, unto + * the transport medium. The bytes to write are read from `data`. + * + * - The `len` parameter is never zero, and is always lower than 20000. + * + * - The number of processed bytes (read or written) is returned. Since + * that number is less than 20000, it always fits on an `int`. + * + * - On error, the callbacks return -1. Reaching end-of-stream is an + * error. Errors are permanent: the SSL connection is terminated. + * + * - Callbacks SHOULD NOT return 0. This is tolerated, as long as + * callbacks endeavour to block for some non-negligible amount of + * time until at least one byte can be sent or received (if a + * callback returns 0, then the wrapper invokes it again + * immediately). + * + * - Callbacks MAY return as soon as at least one byte is processed; + * they MAY also insist on reading or writing _all_ requested bytes. + * Since SSL is a self-terminated protocol (each record has a length + * header), this does not change semantics. + * + * - Callbacks need not apply any buffering (for performance) since SSL + * itself uses buffers. + * + * \param ctx wrapper context to initialise. + * \param engine SSL engine to wrap. + * \param low_read callback for reading data from the transport. + * \param read_context context pointer for `low_read()`. + * \param low_write callback for writing data on the transport. + * \param write_context context pointer for `low_write()`. + */ +void br_sslio_init(br_sslio_context *ctx, + br_ssl_engine_context *engine, + int (*low_read)(void *read_context, + unsigned char *data, size_t len), + void *read_context, + int (*low_write)(void *write_context, + const unsigned char *data, size_t len), + void *write_context); + +/** + * \brief Read some application data from a SSL connection. + * + * If `len` is zero, then this function returns 0 immediately. In + * all other cases, it never returns 0. + * + * This call returns only when at least one byte has been obtained. + * Returned value is the number of bytes read, or -1 on error. The + * number of bytes always fits on an 'int' (data from a single SSL/TLS + * record is returned). + * + * On error or SSL closure, this function returns -1. The caller should + * inspect the error status on the SSL engine to distinguish between + * normal closure and error. + * + * \param cc SSL wrapper context. + * \param dst destination buffer for application data. + * \param len maximum number of bytes to obtain. + * \return number of bytes obtained, or -1 on error. + */ +int br_sslio_read(br_sslio_context *cc, void *dst, size_t len); + +/** + * \brief Read application data from a SSL connection. + * + * This calls returns only when _all_ requested `len` bytes are read, + * or an error is reached. Returned value is 0 on success, -1 on error. + * A normal (verified) SSL closure before that many bytes are obtained + * is reported as an error by this function. + * + * \param cc SSL wrapper context. + * \param dst destination buffer for application data. + * \param len number of bytes to obtain. + * \return 0 on success, or -1 on error. + */ +int br_sslio_read_all(br_sslio_context *cc, void *dst, size_t len); + +/** + * \brief Write some application data unto a SSL connection. + * + * If `len` is zero, then this function returns 0 immediately. In + * all other cases, it never returns 0. + * + * This call returns only when at least one byte has been written. + * Returned value is the number of bytes written, or -1 on error. The + * number of bytes always fits on an 'int' (less than 20000). + * + * On error or SSL closure, this function returns -1. The caller should + * inspect the error status on the SSL engine to distinguish between + * normal closure and error. + * + * **Important:** SSL is buffered; a "written" byte is a byte that was + * injected into the wrapped SSL engine, but this does not necessarily mean + * that it has been scheduled for sending. Use `br_sslio_flush()` to + * ensure that all pending data has been sent to the transport medium. + * + * \param cc SSL wrapper context. + * \param src source buffer for application data. + * \param len maximum number of bytes to write. + * \return number of bytes written, or -1 on error. + */ +int br_sslio_write(br_sslio_context *cc, const void *src, size_t len); + +/** + * \brief Write application data unto a SSL connection. + * + * This calls returns only when _all_ requested `len` bytes have been + * written, or an error is reached. Returned value is 0 on success, -1 + * on error. A normal (verified) SSL closure before that many bytes are + * written is reported as an error by this function. + * + * **Important:** SSL is buffered; a "written" byte is a byte that was + * injected into the wrapped SSL engine, but this does not necessarily mean + * that it has been scheduled for sending. Use `br_sslio_flush()` to + * ensure that all pending data has been sent to the transport medium. + * + * \param cc SSL wrapper context. + * \param src source buffer for application data. + * \param len number of bytes to write. + * \return 0 on success, or -1 on error. + */ +int br_sslio_write_all(br_sslio_context *cc, const void *src, size_t len); + +/** + * \brief Flush pending data. + * + * This call makes sure that any buffered application data in the + * provided context (including the wrapped SSL engine) has been sent + * to the transport medium (i.e. accepted by the `low_write()` callback + * method). If there is no such pending data, then this function does + * nothing (and returns a success, i.e. 0). + * + * If the underlying transport medium has its own buffers, then it is + * up to the caller to ensure the corresponding flushing. + * + * Returned value is 0 on success, -1 on error. + * + * \param cc SSL wrapper context. + * \return 0 on success, or -1 on error. + */ +int br_sslio_flush(br_sslio_context *cc); + +/** + * \brief Close the SSL connection. + * + * This call runs the SSL closure protocol (sending a `close_notify`, + * receiving the response `close_notify`). When it returns, the SSL + * connection is finished. It is still up to the caller to manage the + * possible transport-level termination, if applicable (alternatively, + * the underlying transport stream may be reused for non-SSL messages). + * + * Returned value is 0 on success, -1 on error. A failure by the peer + * to process the complete closure protocol (i.e. sending back the + * `close_notify`) is an error. + * + * \param cc SSL wrapper context. + * \return 0 on success, or -1 on error. + */ +int br_sslio_close(br_sslio_context *cc); + +/* ===================================================================== */ + +/* + * Symbolic constants for cipher suites. + */ + +/* From RFC 5246 */ +#define BR_TLS_NULL_WITH_NULL_NULL 0x0000 +#define BR_TLS_RSA_WITH_NULL_MD5 0x0001 +#define BR_TLS_RSA_WITH_NULL_SHA 0x0002 +#define BR_TLS_RSA_WITH_NULL_SHA256 0x003B +#define BR_TLS_RSA_WITH_RC4_128_MD5 0x0004 +#define BR_TLS_RSA_WITH_RC4_128_SHA 0x0005 +#define BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x000A +#define BR_TLS_RSA_WITH_AES_128_CBC_SHA 0x002F +#define BR_TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 +#define BR_TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C +#define BR_TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D +#define BR_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA 0x000D +#define BR_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA 0x0010 +#define BR_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA 0x0013 +#define BR_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016 +#define BR_TLS_DH_DSS_WITH_AES_128_CBC_SHA 0x0030 +#define BR_TLS_DH_RSA_WITH_AES_128_CBC_SHA 0x0031 +#define BR_TLS_DHE_DSS_WITH_AES_128_CBC_SHA 0x0032 +#define BR_TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033 +#define BR_TLS_DH_DSS_WITH_AES_256_CBC_SHA 0x0036 +#define BR_TLS_DH_RSA_WITH_AES_256_CBC_SHA 0x0037 +#define BR_TLS_DHE_DSS_WITH_AES_256_CBC_SHA 0x0038 +#define BR_TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039 +#define BR_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 0x003E +#define BR_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 0x003F +#define BR_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 0x0040 +#define BR_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067 +#define BR_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 0x0068 +#define BR_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 0x0069 +#define BR_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 0x006A +#define BR_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B +#define BR_TLS_DH_anon_WITH_RC4_128_MD5 0x0018 +#define BR_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA 0x001B +#define BR_TLS_DH_anon_WITH_AES_128_CBC_SHA 0x0034 +#define BR_TLS_DH_anon_WITH_AES_256_CBC_SHA 0x003A +#define BR_TLS_DH_anon_WITH_AES_128_CBC_SHA256 0x006C +#define BR_TLS_DH_anon_WITH_AES_256_CBC_SHA256 0x006D + +/* From RFC 4492 */ +#define BR_TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 +#define BR_TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 +#define BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 +#define BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 +#define BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 +#define BR_TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 +#define BR_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 +#define BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A +#define BR_TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B +#define BR_TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C +#define BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D +#define BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E +#define BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F +#define BR_TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 +#define BR_TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 +#define BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 +#define BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 +#define BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 +#define BR_TLS_ECDH_anon_WITH_NULL_SHA 0xC015 +#define BR_TLS_ECDH_anon_WITH_RC4_128_SHA 0xC016 +#define BR_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA 0xC017 +#define BR_TLS_ECDH_anon_WITH_AES_128_CBC_SHA 0xC018 +#define BR_TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019 + +/* From RFC 5288 */ +#define BR_TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C +#define BR_TLS_RSA_WITH_AES_256_GCM_SHA384 0x009D +#define BR_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x009E +#define BR_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x009F +#define BR_TLS_DH_RSA_WITH_AES_128_GCM_SHA256 0x00A0 +#define BR_TLS_DH_RSA_WITH_AES_256_GCM_SHA384 0x00A1 +#define BR_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 0x00A2 +#define BR_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 0x00A3 +#define BR_TLS_DH_DSS_WITH_AES_128_GCM_SHA256 0x00A4 +#define BR_TLS_DH_DSS_WITH_AES_256_GCM_SHA384 0x00A5 +#define BR_TLS_DH_anon_WITH_AES_128_GCM_SHA256 0x00A6 +#define BR_TLS_DH_anon_WITH_AES_256_GCM_SHA384 0x00A7 + +/* From RFC 5289 */ +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 +#define BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 +#define BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 +#define BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 +#define BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 +#define BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 +#define BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C +#define BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D +#define BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E +#define BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F +#define BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 +#define BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 +#define BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 + +/* From RFC 6655 and 7251 */ +#define BR_TLS_RSA_WITH_AES_128_CCM 0xC09C +#define BR_TLS_RSA_WITH_AES_256_CCM 0xC09D +#define BR_TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 +#define BR_TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF + +/* From RFC 7905 */ +#define BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 +#define BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 +#define BR_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA +#define BR_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAB +#define BR_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC +#define BR_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD +#define BR_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE + +/* From RFC 7507 */ +#define BR_TLS_FALLBACK_SCSV 0x5600 + +/* + * Symbolic constants for alerts. + */ +#define BR_ALERT_CLOSE_NOTIFY 0 +#define BR_ALERT_UNEXPECTED_MESSAGE 10 +#define BR_ALERT_BAD_RECORD_MAC 20 +#define BR_ALERT_RECORD_OVERFLOW 22 +#define BR_ALERT_DECOMPRESSION_FAILURE 30 +#define BR_ALERT_HANDSHAKE_FAILURE 40 +#define BR_ALERT_BAD_CERTIFICATE 42 +#define BR_ALERT_UNSUPPORTED_CERTIFICATE 43 +#define BR_ALERT_CERTIFICATE_REVOKED 44 +#define BR_ALERT_CERTIFICATE_EXPIRED 45 +#define BR_ALERT_CERTIFICATE_UNKNOWN 46 +#define BR_ALERT_ILLEGAL_PARAMETER 47 +#define BR_ALERT_UNKNOWN_CA 48 +#define BR_ALERT_ACCESS_DENIED 49 +#define BR_ALERT_DECODE_ERROR 50 +#define BR_ALERT_DECRYPT_ERROR 51 +#define BR_ALERT_PROTOCOL_VERSION 70 +#define BR_ALERT_INSUFFICIENT_SECURITY 71 +#define BR_ALERT_INTERNAL_ERROR 80 +#define BR_ALERT_USER_CANCELED 90 +#define BR_ALERT_NO_RENEGOTIATION 100 +#define BR_ALERT_UNSUPPORTED_EXTENSION 110 +#define BR_ALERT_NO_APPLICATION_PROTOCOL 120 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libcurl/lib/vtls/bearssl_xbox.cpp b/libcurl/lib/vtls/bearssl_xbox.cpp new file mode 100644 index 0000000..bd73a56 --- /dev/null +++ b/libcurl/lib/vtls/bearssl_xbox.cpp @@ -0,0 +1,150 @@ +/* + * BearSSL Xbox Integration Implementation + * C-compatible wrappers for Xbox-specific SSL functionality + */ + +#include "bearssl_xbox.h" +#include "certificates.h" +#include "ca_loader.h" +#include "session_cache.h" +#include "ssl_errors.h" +#include "cert_pinning.h" + +extern "C" { + +/* + * Trust Anchor Management + */ +void bearssl_xbox_init_trust_anchors(void) +{ + certificates::initialize_trust_anchors(); +} + +void bearssl_xbox_cleanup_trust_anchors(void) +{ + certificates::close_trust_anchors(); +} + +br_x509_trust_anchor* bearssl_xbox_get_trust_anchors(void) +{ + return certificates::get_trust_anchors(); +} + +size_t bearssl_xbox_get_trust_anchor_count(void) +{ + return (size_t)certificates::get_num_trust_anchors(); +} + +/* + * Session Cache Management + */ +void bearssl_xbox_session_init(void) +{ + session_cache::initialize(); +} + +void bearssl_xbox_session_shutdown(void) +{ + session_cache::shutdown(); +} + +int bearssl_xbox_session_get(const char* hostname, br_ssl_session_parameters* params) +{ + return session_cache::get(hostname, params) ? 1 : 0; +} + +void bearssl_xbox_session_store(const char* hostname, const br_ssl_session_parameters* params) +{ + session_cache::store(hostname, params); +} + +void bearssl_xbox_session_remove(const char* hostname) +{ + session_cache::remove(hostname); +} + +void bearssl_xbox_session_clear(void) +{ + session_cache::clear(); +} + +/* + * Error Message Utilities + */ +const char* bearssl_xbox_error_string(int error) +{ + return ssl_errors::error_to_string(error); +} + +const char* bearssl_xbox_alert_string(int alert_code) +{ + return ssl_errors::alert_to_string(alert_code); +} + +/* + * CA Loader + */ +int bearssl_xbox_load_ca_file(const char *path, + br_x509_trust_anchor **anchors_out, size_t *count_out) +{ + return ca_loader::load_pem_file(path, anchors_out, count_out); +} + +void bearssl_xbox_free_loaded_anchors(br_x509_trust_anchor *anchors, + size_t count) +{ + ca_loader::free_trust_anchors(anchors, count); +} + +int bearssl_xbox_update_trust_store(void) +{ + return ca_loader::update_trust_store( + BEARSSL_XBOX_DEFAULT_CA_FILE, + certificates::get_trust_anchors(), + (size_t)certificates::get_num_trust_anchors()); +} + +/* + * Certificate Pinning + */ +void bearssl_xbox_pin_init(void) +{ + cert_pinning::initialize(); +} + +void bearssl_xbox_pin_shutdown(void) +{ + cert_pinning::shutdown(); +} + +int bearssl_xbox_pin_add(const char* hostname, const unsigned char* sha256_hash) +{ + return cert_pinning::add_pin(hostname, sha256_hash) ? 1 : 0; +} + +void bearssl_xbox_pin_remove(const char* hostname) +{ + cert_pinning::remove_pin(hostname); +} + +void bearssl_xbox_pin_clear(void) +{ + cert_pinning::clear(); +} + +int bearssl_xbox_pin_has(const char* hostname) +{ + return cert_pinning::has_pin(hostname) ? 1 : 0; +} + +int bearssl_xbox_pin_verify_hash(const char* hostname, const unsigned char* cert_sha256) +{ + return cert_pinning::verify_hash(hostname, cert_sha256) ? 1 : 0; +} + +int bearssl_xbox_pin_get_hash(const char* hostname, unsigned char* hash_out) +{ + return cert_pinning::get_pin_hash(hostname, hash_out) ? 1 : 0; +} + +} /* extern "C" */ diff --git a/libcurl/lib/vtls/bearssl_xbox.h b/libcurl/lib/vtls/bearssl_xbox.h new file mode 100644 index 0000000..6b86866 --- /dev/null +++ b/libcurl/lib/vtls/bearssl_xbox.h @@ -0,0 +1,85 @@ +/* + * BearSSL Xbox Integration Header + * C-compatible wrappers for Xbox-specific SSL functionality + * + * This provides a C interface to the C++ classes for use by libcurl's bearssl.c + */ + +#ifndef BEARSSL_XBOX_H +#define BEARSSL_XBOX_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Default CA bundle path on Xbox HDD. + * T:\ maps to E:\TDATA\\ (title-persistent storage). + * Drop cacert.pem there to use updated root CAs without recompiling. + */ +#define BEARSSL_XBOX_DEFAULT_CA_FILE "T:\\cacert.pem" + +/* + * Trust Anchor Management + * Wraps certificates.cpp functionality + */ +void bearssl_xbox_init_trust_anchors(void); +void bearssl_xbox_cleanup_trust_anchors(void); +br_x509_trust_anchor* bearssl_xbox_get_trust_anchors(void); +size_t bearssl_xbox_get_trust_anchor_count(void); + +/* + * Session Cache Management + * Wraps session_cache.cpp functionality + */ +void bearssl_xbox_session_init(void); +void bearssl_xbox_session_shutdown(void); +int bearssl_xbox_session_get(const char* hostname, br_ssl_session_parameters* params); +void bearssl_xbox_session_store(const char* hostname, const br_ssl_session_parameters* params); +void bearssl_xbox_session_remove(const char* hostname); +void bearssl_xbox_session_clear(void); + +/* + * Error Message Utilities + * Wraps ssl_errors.cpp functionality + */ +const char* bearssl_xbox_error_string(int error); +const char* bearssl_xbox_alert_string(int alert_code); + +/* + * CA Loader - Runtime PEM certificate loading + * Wraps ca_loader.cpp functionality + */ +int bearssl_xbox_load_ca_file(const char *path, + br_x509_trust_anchor **anchors_out, size_t *count_out); +void bearssl_xbox_free_loaded_anchors(br_x509_trust_anchor *anchors, + size_t count); + +/* + * CA Auto-Update + * Downloads cacert.pem from curl.se if not already present on disk. + * Uses the compiled-in trust anchors (must be initialized first). + * Returns 0 on success (file existed or was downloaded), -1 on failure. + */ +int bearssl_xbox_update_trust_store(void); + +/* + * Certificate Pinning + * Wraps cert_pinning.cpp functionality + */ +void bearssl_xbox_pin_init(void); +void bearssl_xbox_pin_shutdown(void); +int bearssl_xbox_pin_add(const char* hostname, const unsigned char* sha256_hash); +void bearssl_xbox_pin_remove(const char* hostname); +void bearssl_xbox_pin_clear(void); +int bearssl_xbox_pin_has(const char* hostname); +int bearssl_xbox_pin_verify_hash(const char* hostname, const unsigned char* cert_sha256); +int bearssl_xbox_pin_get_hash(const char* hostname, unsigned char* hash_out); + +#ifdef __cplusplus +} +#endif + +#endif /* BEARSSL_XBOX_H */ diff --git a/libcurl/lib/vtls/ca_loader.cpp b/libcurl/lib/vtls/ca_loader.cpp new file mode 100644 index 0000000..457154a --- /dev/null +++ b/libcurl/lib/vtls/ca_loader.cpp @@ -0,0 +1,861 @@ +#include "ca_loader.h" +#include "debug_utility.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DOWNLOAD_BUF_SIZE 8192 +#define CA_DNS_TIMEOUT_MS 30000 + +/* ------------------------------------------------------------------ */ +/* Inline socket/network helpers (avoids dependency on BearSSL-OG */ +/* socket_utility / network_utility which aren't in libbearssl) */ +/* ------------------------------------------------------------------ */ + +/* DNS resolution via Xbox XNet async API */ +static uint32_t ca_resolve_host(const char *host) +{ + XNDNS *dns = NULL; + WSAEVENT event_handle; + uint32_t result = 0; + + if (host == NULL || host[0] == '\0') + { + return 0; + } + + event_handle = WSACreateEvent(); + if (event_handle == NULL) + { + return 0; + } + + if (XNetDnsLookup(host, event_handle, &dns) != 0) + { + WSACloseEvent(event_handle); + return 0; + } + + if (WaitForSingleObject(event_handle, CA_DNS_TIMEOUT_MS) == WAIT_TIMEOUT) + { + WSACloseEvent(event_handle); + XNetDnsRelease(dns); + return 0; + } + + WSACloseEvent(event_handle); + + if (dns->iStatus == 0 && dns->cina > 0) + { + result = dns->aina[0].S_un.S_addr; + } + + XNetDnsRelease(dns); + return result; +} + +/* TCP connect to host:port, returns socket or INVALID_SOCKET. + * IMPORTANT: Xbox SOCKET handles are kernel pointers (e.g. 0xD001A828) + * which are negative as signed int -- never check < 0, always use + * INVALID_SOCKET. */ +static SOCKET ca_connect(uint32_t host_ip, uint16_t port) +{ + sockaddr_in addr; + SOCKET sock; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.S_un.S_addr = host_ip; + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == INVALID_SOCKET) + { + return INVALID_SOCKET; + } + + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) + { + closesocket(sock); + return INVALID_SOCKET; + } + + return sock; +} + +/* BearSSL I/O callback: read from socket with 2-second select timeout */ +static int ca_sock_read(void *ctx, unsigned char *buf, size_t len) +{ + SOCKET sock = *(SOCKET *)ctx; + fd_set fds; + struct timeval tv; + int n; + + while (1) + { + FD_ZERO(&fds); + FD_SET(sock, &fds); + tv.tv_sec = 2; + tv.tv_usec = 0; + + if (select(0, &fds, NULL, NULL, &tv) == 0) + { + return -1; /* timeout */ + } + + n = recv(sock, (char *)buf, (len > 0x7FFFFFFF) ? 0x7FFFFFFF : (int)len, 0); + if (n == SOCKET_ERROR) + { + if (WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEWOULDBLOCK) + { + continue; + } + return -1; + } + return n; /* 0 = peer closed, >0 = bytes read */ + } +} + +/* BearSSL I/O callback: write to socket */ +static int ca_sock_write(void *ctx, const unsigned char *buf, size_t len) +{ + SOCKET sock = *(SOCKET *)ctx; + int n; + + while (1) + { + n = send(sock, (const char *)buf, + (len > 0x7FFFFFFF) ? 0x7FFFFFFF : (int)len, 0); + if (n == SOCKET_ERROR) + { + if (WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEWOULDBLOCK) + { + continue; + } + return -1; + } + return n; + } +} + +/* Dynamic byte buffer used for accumulating DER and DN data */ +struct byte_buffer +{ + unsigned char *data; + size_t len; + size_t cap; + int error; /* set to 1 if any append failed (OOM) */ +}; + +static void byte_buffer_init(byte_buffer *bb) +{ + bb->data = NULL; + bb->len = 0; + bb->cap = 0; + bb->error = 0; +} + +static void byte_buffer_reset(byte_buffer *bb) +{ + bb->len = 0; + bb->error = 0; +} + +static void byte_buffer_free(byte_buffer *bb) +{ + free(bb->data); + bb->data = NULL; + bb->len = 0; + bb->cap = 0; + bb->error = 0; +} + +static int byte_buffer_append(byte_buffer *bb, const void *src, size_t len) +{ + if (len == 0) + { + return 0; + } + if (bb->len + len > bb->cap) + { + size_t new_cap = (bb->cap == 0) ? 4096 : bb->cap * 2; + while (new_cap < bb->len + len) + { + if (new_cap > ((size_t)-1) / 2) + { + return -1; + } + new_cap *= 2; + } + unsigned char *new_data = (unsigned char *)realloc(bb->data, new_cap); + if (new_data == NULL) + { + return -1; + } + bb->data = new_data; + bb->cap = new_cap; + } + memcpy(bb->data + bb->len, src, len); + bb->len += len; + return 0; +} + +/* PEM decoder callback: accumulates decoded DER bytes */ +static void pem_dest_callback(void *dest_ctx, const void *src, size_t len) +{ + byte_buffer *bb = (byte_buffer *)dest_ctx; + if (byte_buffer_append(bb, src, len) != 0) + { + bb->error = 1; + } +} + +/* X.509 decoder callback: accumulates subject DN bytes */ +static void dn_append_callback(void *ctx, const void *buf, size_t len) +{ + byte_buffer *bb = (byte_buffer *)ctx; + if (byte_buffer_append(bb, buf, len) != 0) + { + bb->error = 1; + } +} + +/* + * Deep-copy a decoded certificate into a new trust anchor entry. + * Returns 0 on success, -1 on allocation failure. + */ +static int add_trust_anchor( + br_x509_trust_anchor **anchors, size_t *count, size_t *cap, + byte_buffer *dn, br_x509_decoder_context *dc) +{ + br_x509_pkey *pk = br_x509_decoder_get_pkey(dc); + if (pk == NULL) + { + return -1; + } + + /* Grow anchor array if needed */ + if (*count >= *cap) + { + size_t new_cap = (*cap == 0) ? 32 : *cap * 2; + br_x509_trust_anchor *new_arr = (br_x509_trust_anchor *)realloc( + *anchors, new_cap * sizeof(br_x509_trust_anchor)); + if (new_arr == NULL) + { + return -1; + } + *anchors = new_arr; + *cap = new_cap; + } + + br_x509_trust_anchor *ta = &(*anchors)[*count]; + memset(ta, 0, sizeof(*ta)); + + /* Deep-copy DN */ + ta->dn.data = (unsigned char *)malloc(dn->len); + if (ta->dn.data == NULL) + { + return -1; + } + memcpy(ta->dn.data, dn->data, dn->len); + ta->dn.len = dn->len; + + /* Set CA flag */ + ta->flags = br_x509_decoder_isCA(dc) ? BR_X509_TA_CA : 0; + + /* Deep-copy public key */ + ta->pkey.key_type = pk->key_type; + if (pk->key_type == BR_KEYTYPE_RSA) + { + ta->pkey.key.rsa.n = (unsigned char *)malloc(pk->key.rsa.nlen); + ta->pkey.key.rsa.e = (unsigned char *)malloc(pk->key.rsa.elen); + if (ta->pkey.key.rsa.n == NULL || ta->pkey.key.rsa.e == NULL) + { + free(ta->pkey.key.rsa.n); + free(ta->pkey.key.rsa.e); + free(ta->dn.data); + return -1; + } + memcpy(ta->pkey.key.rsa.n, pk->key.rsa.n, pk->key.rsa.nlen); + ta->pkey.key.rsa.nlen = pk->key.rsa.nlen; + memcpy(ta->pkey.key.rsa.e, pk->key.rsa.e, pk->key.rsa.elen); + ta->pkey.key.rsa.elen = pk->key.rsa.elen; + } + else if (pk->key_type == BR_KEYTYPE_EC) + { + ta->pkey.key.ec.q = (unsigned char *)malloc(pk->key.ec.qlen); + if (ta->pkey.key.ec.q == NULL) + { + free(ta->dn.data); + memset(ta, 0, sizeof(*ta)); + return -1; + } + memcpy(ta->pkey.key.ec.q, pk->key.ec.q, pk->key.ec.qlen); + ta->pkey.key.ec.qlen = pk->key.ec.qlen; + ta->pkey.key.ec.curve = pk->key.ec.curve; + } + else + { + /* Unknown key type */ + free(ta->dn.data); + memset(ta, 0, sizeof(*ta)); + return -1; + } + + (*count)++; + return 0; +} + +int ca_loader::load_pem_file(const char *path, + br_x509_trust_anchor **anchors_out, size_t *count_out) +{ + *anchors_out = NULL; + *count_out = 0; + + /* Read entire PEM file into memory */ + FILE *f = fopen(path, "rb"); + if (f == NULL) + { + debug_utility::debug_print("ca_loader: cannot open %s\n", path); + return -1; + } + + fseek(f, 0, SEEK_END); + long file_size = ftell(f); + fseek(f, 0, SEEK_SET); + + if (file_size <= 0 || file_size > 2 * 1024 * 1024) + { + debug_utility::debug_print("ca_loader: file too large or empty (%ld bytes)\n", file_size); + fclose(f); + return -1; + } + + unsigned char *file_data = (unsigned char *)malloc((size_t)file_size); + if (file_data == NULL) + { + debug_utility::debug_print("ca_loader: malloc failed for file data\n"); + fclose(f); + return -1; + } + + size_t bytes_read = fread(file_data, 1, (size_t)file_size, f); + fclose(f); + + if (bytes_read != (size_t)file_size) + { + debug_utility::debug_print("ca_loader: short read (%u of %ld)\n", + (unsigned)bytes_read, file_size); + free(file_data); + return -1; + } + + /* Parse PEM, collecting DER blobs for each CERTIFICATE */ + br_pem_decoder_context pem; + br_pem_decoder_init(&pem); + + br_x509_trust_anchor *anchors = NULL; + size_t anchor_count = 0; + size_t anchor_cap = 0; + + byte_buffer der_buf; + byte_buffer_init(&der_buf); + + byte_buffer dn_buf; + byte_buffer_init(&dn_buf); + + int in_cert = 0; + int certs_parsed = 0; + int certs_failed = 0; + + const unsigned char *pos = file_data; + size_t remaining = bytes_read; + + while (remaining > 0) + { + size_t consumed = br_pem_decoder_push(&pem, pos, remaining); + pos += consumed; + remaining -= consumed; + + int event = br_pem_decoder_event(&pem); + switch (event) + { + case BR_PEM_BEGIN_OBJ: + if (strcmp(br_pem_decoder_name(&pem), "CERTIFICATE") == 0) + { + in_cert = 1; + byte_buffer_reset(&der_buf); + br_pem_decoder_setdest(&pem, pem_dest_callback, &der_buf); + } + else + { + /* Skip non-certificate objects (private keys, etc.) */ + in_cert = 0; + br_pem_decoder_setdest(&pem, NULL, NULL); + } + break; + + case BR_PEM_END_OBJ: + if (in_cert && der_buf.len > 0 && !der_buf.error) + { + /* Decode the DER certificate */ + br_x509_decoder_context dc; + byte_buffer_reset(&dn_buf); + br_x509_decoder_init(&dc, dn_append_callback, &dn_buf); + br_x509_decoder_push(&dc, der_buf.data, der_buf.len); + + int err = br_x509_decoder_last_error(&dc); + if (err == 0 && !dn_buf.error) + { + if (add_trust_anchor(&anchors, &anchor_count, &anchor_cap, + &dn_buf, &dc) == 0) + { + certs_parsed++; + } + else + { + certs_failed++; + } + } + else + { + certs_failed++; + } + } + else if (in_cert && (der_buf.error || dn_buf.error)) + { + certs_failed++; + } + in_cert = 0; + break; + + case BR_PEM_ERROR: + in_cert = 0; + break; + + case 0: + /* No event yet, decoder needs more data but push returned 0. + * This shouldn't happen with complete files, but guard against + * infinite loop by breaking if no progress was made. */ + if (consumed == 0) + { + remaining = 0; + } + break; + } + } + + byte_buffer_free(&der_buf); + byte_buffer_free(&dn_buf); + free(file_data); + + debug_utility::debug_print("ca_loader: loaded %d trust anchors from %s (%d failed)\n", + certs_parsed, path, certs_failed); + + if (anchor_count == 0) + { + free(anchors); + return -1; + } + + *anchors_out = anchors; + *count_out = anchor_count; + return 0; +} + +void ca_loader::free_trust_anchors(br_x509_trust_anchor *anchors, size_t count) +{ + size_t i; + + if (anchors == NULL) + { + return; + } + + for (i = 0; i < count; i++) + { + free(anchors[i].dn.data); + if (anchors[i].pkey.key_type == BR_KEYTYPE_RSA) + { + free(anchors[i].pkey.key.rsa.n); + free(anchors[i].pkey.key.rsa.e); + } + else if (anchors[i].pkey.key_type == BR_KEYTYPE_EC) + { + free(anchors[i].pkey.key.ec.q); + } + } + free(anchors); +} + +/* ------------------------------------------------------------------ */ +/* Auto-update: download CA bundle from curl.se over HTTPS */ +/* ------------------------------------------------------------------ */ + +/* Time check callback: always returns 0 (valid). + * This lets the compiled-in CAs work even if the Xbox clock is wrong. */ +static int download_time_check(void *tctx, + uint32_t not_before_days, uint32_t not_before_seconds, + uint32_t not_after_days, uint32_t not_after_seconds) +{ + (void)tctx; + (void)not_before_days; + (void)not_before_seconds; + (void)not_after_days; + (void)not_after_seconds; + return 0; +} + +/* Find \r\n in a buffer, return offset or -1 */ +static int find_line_end(const unsigned char *buf, size_t len) +{ + size_t i; + if (len < 2) return -1; + for (i = 0; i < len - 1; i++) + { + if (buf[i] == '\r' && buf[i + 1] == '\n') + { + return (int)i; + } + } + return -1; +} + +/* Case-insensitive prefix match */ +static int prefix_icmp(const char *str, const char *prefix) +{ + while (*prefix) + { + char a = *str; + char b = *prefix; + if (a >= 'A' && a <= 'Z') a += 32; + if (b >= 'A' && b <= 'Z') b += 32; + if (a != b) return 0; + str++; + prefix++; + } + return 1; +} + +int ca_loader::download_https(const char *host, const char *path, + uint16_t port, const char *save_path, + br_x509_trust_anchor *anchors, size_t anchor_count, + int max_redirects) +{ + int result = -1; + + /* DNS resolve */ + uint32_t host_ip = ca_resolve_host(host); + if (host_ip == 0) + { + debug_utility::debug_print("ca_loader: DNS failed for %s\n", host); + return -1; + } + + /* TCP connect */ + SOCKET sock = ca_connect(host_ip, port); + if (sock == INVALID_SOCKET) + { + debug_utility::debug_print("ca_loader: connect failed to %s:%u\n", + host, (unsigned)port); + return -1; + } + + /* Allocate BearSSL I/O buffer on the heap (too large for Xbox stack) */ + unsigned char *iobuf = (unsigned char *)malloc(BR_SSL_BUFSIZE_BIDI); + if (iobuf == NULL) + { + closesocket(sock); + return -1; + } + + /* Set up BearSSL with compiled-in CAs + time check bypass */ + br_ssl_client_context sc; + br_x509_minimal_context xc; + br_ssl_client_init_full(&sc, &xc, anchors, anchor_count); + br_x509_minimal_set_time_callback(&xc, NULL, download_time_check); + br_ssl_engine_set_buffer(&sc.eng, iobuf, BR_SSL_BUFSIZE_BIDI, 1); + br_ssl_client_reset(&sc, host, 0); + + br_sslio_context ioc; + br_sslio_init(&ioc, &sc.eng, + ca_sock_read, &sock, + ca_sock_write, &sock); + + /* Send HTTP GET */ + char request[512]; + _snprintf(request, sizeof(request) - 1, + "GET %s HTTP/1.1\r\n" + "Host: %s\r\n" + "Accept-Encoding: identity\r\n" + "Connection: close\r\n" + "\r\n", + path, host); + request[sizeof(request) - 1] = '\0'; + + br_sslio_write_all(&ioc, request, strlen(request)); + br_sslio_flush(&ioc); + + /* Read response into accumulation buffer */ + unsigned char *readbuf = (unsigned char *)malloc(DOWNLOAD_BUF_SIZE); + if (readbuf == NULL) + { + free(iobuf); + closesocket(sock); + return -1; + } + + /* Accumulate headers */ + byte_buffer hdr; + byte_buffer_init(&hdr); + + int status_code = 0; + int64_t content_length = -1; + char redirect_host[256]; + char redirect_path[512]; + int has_redirect = 0; + int headers_done = 0; + + redirect_host[0] = '\0'; + redirect_path[0] = '\0'; + + while (!headers_done) + { + int n = br_sslio_read(&ioc, readbuf, DOWNLOAD_BUF_SIZE); + if (n < 0) break; + byte_buffer_append(&hdr, readbuf, (size_t)n); + + /* Parse complete lines from the accumulated buffer */ + while (hdr.len > 0) + { + int crlf = find_line_end(hdr.data, hdr.len); + if (crlf < 0) break; + + /* Null-terminate the line for string operations */ + char *line = (char *)malloc((size_t)crlf + 1); + if (line == NULL) break; + memcpy(line, hdr.data, (size_t)crlf); + line[crlf] = '\0'; + + /* Remove the line + CRLF from the buffer */ + { + size_t remove_len = (size_t)crlf + 2; + if (remove_len < hdr.len) + { + memmove(hdr.data, hdr.data + remove_len, + hdr.len - remove_len); + } + hdr.len -= remove_len; + } + + /* Empty line = end of headers */ + if (line[0] == '\0') + { + free(line); + headers_done = 1; + break; + } + + /* Parse status line: "HTTP/1.x 200 OK" */ + if (status_code == 0 && strncmp(line, "HTTP/", 5) == 0) + { + char *sp = strchr(line, ' '); + if (sp) status_code = atoi(sp + 1); + } + + /* Parse Content-Length (cap at 10MB - CA bundles are ~250KB) */ + if (prefix_icmp(line, "content-length:")) + { + const char *val = line + 15; + while (*val == ' ') val++; + content_length = 0; + while (*val >= '0' && *val <= '9') + { + content_length = content_length * 10 + (*val - '0'); + if (content_length > 10 * 1024 * 1024) + { + content_length = -1; + break; + } + val++; + } + } + + /* Parse Location for redirects */ + if (prefix_icmp(line, "location:")) + { + const char *url = line + 9; + while (*url == ' ') url++; + + /* Parse "https://host/path" */ + if (strncmp(url, "https://", 8) == 0) + { + const char *hstart = url + 8; + const char *slash = strchr(hstart, '/'); + if (slash) + { + size_t hlen = (size_t)(slash - hstart); + if (hlen < sizeof(redirect_host)) + { + memcpy(redirect_host, hstart, hlen); + redirect_host[hlen] = '\0'; + _snprintf(redirect_path, + sizeof(redirect_path) - 1, "%s", slash); + redirect_path[sizeof(redirect_path) - 1] = '\0'; + has_redirect = 1; + } + } + } + } + + free(line); + } + } + + /* Handle redirect */ + if ((status_code == 301 || status_code == 302 || status_code == 307) + && has_redirect && max_redirects > 0) + { + debug_utility::debug_print("ca_loader: redirect %d -> %s%s\n", + status_code, redirect_host, redirect_path); + + byte_buffer_free(&hdr); + free(readbuf); + free(iobuf); + closesocket(sock); + + return download_https(redirect_host, redirect_path, port, + save_path, anchors, anchor_count, max_redirects - 1); + } + + if (status_code != 200) + { + debug_utility::debug_print("ca_loader: HTTP %d from %s%s\n", + status_code, host, path); + byte_buffer_free(&hdr); + free(readbuf); + free(iobuf); + closesocket(sock); + return -1; + } + + /* Write body to a temp file, then rename on success */ + char temp_path[280]; + _snprintf(temp_path, sizeof(temp_path) - 1, "%s.tmp", save_path); + temp_path[sizeof(temp_path) - 1] = '\0'; + + FILE *fp = fopen(temp_path, "wb"); + if (fp == NULL) + { + debug_utility::debug_print("ca_loader: cannot create %s (err=%lu)\n", + temp_path, GetLastError()); + byte_buffer_free(&hdr); + free(readbuf); + free(iobuf); + closesocket(sock); + return -1; + } + + /* Write any leftover data that was read past the headers */ + int64_t total_written = 0; + int write_error = 0; + if (hdr.len > 0) + { + if (fwrite(hdr.data, 1, hdr.len, fp) != hdr.len) + { + write_error = 1; + } + total_written += (int64_t)hdr.len; + } + byte_buffer_free(&hdr); + + /* Stream the rest of the body to disk */ + while (!write_error) + { + int n = br_sslio_read(&ioc, readbuf, DOWNLOAD_BUF_SIZE); + if (n < 0) break; + if (fwrite(readbuf, 1, (size_t)n, fp) != (size_t)n) + { + write_error = 1; + break; + } + total_written += (int64_t)n; + + if (content_length > 0 && total_written >= content_length) + { + break; + } + } + + fclose(fp); + free(readbuf); + free(iobuf); + closesocket(sock); + + /* Check for disk write errors */ + if (write_error) + { + debug_utility::debug_print("ca_loader: write error saving to %s\n", + temp_path); + remove(temp_path); + return -1; + } + + /* Sanity check: CA bundles are typically 200-300 KB */ + if (total_written < 1024) + { + debug_utility::debug_print("ca_loader: download too small (%I64d bytes)\n", + total_written); + remove(temp_path); + return -1; + } + + /* Atomic-ish replace: delete old, rename temp */ + remove(save_path); + if (rename(temp_path, save_path) != 0) + { + debug_utility::debug_print("ca_loader: rename %s -> %s failed\n", + temp_path, save_path); + remove(temp_path); + return -1; + } + + debug_utility::debug_print("ca_loader: downloaded %I64d bytes to %s\n", + total_written, save_path); + result = 0; + return result; +} + +int ca_loader::update_trust_store(const char *save_path, + br_x509_trust_anchor *anchors, size_t anchor_count) +{ + /* If the CA file already exists on disk, nothing to do */ + FILE *f = fopen(save_path, "rb"); + if (f != NULL) + { + fclose(f); + debug_utility::debug_print("ca_loader: %s already exists, skipping download\n", + save_path); + return 0; + } + + if (anchors == NULL || anchor_count == 0) + { + debug_utility::debug_print("ca_loader: no trust anchors for download\n"); + return -1; + } + + debug_utility::debug_print("ca_loader: downloading CA bundle from %s...\n", + CA_BUNDLE_HOST); + + return download_https(CA_BUNDLE_HOST, CA_BUNDLE_PATH, CA_BUNDLE_PORT, + save_path, anchors, anchor_count, 3); +} diff --git a/libcurl/lib/vtls/ca_loader.h b/libcurl/lib/vtls/ca_loader.h new file mode 100644 index 0000000..6ed4416 --- /dev/null +++ b/libcurl/lib/vtls/ca_loader.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include +#include + +/* + * Runtime CA certificate loader. + * + * Parses PEM-encoded CA bundle files (e.g. cacert.pem from curl.se) + * into br_x509_trust_anchor arrays that BearSSL can use for certificate + * verification. + * + * Also provides auto-update: downloads a fresh CA bundle over HTTPS + * using the compiled-in trust anchors (with time validation bypassed) + * and saves it to title-persistent storage on the Xbox HDD. + */ + +/* Where to download the CA bundle from */ +#define CA_BUNDLE_HOST "curl.se" +#define CA_BUNDLE_PATH "/ca/cacert.pem" +#define CA_BUNDLE_PORT 443 + +class ca_loader +{ +public: + /* + * Load trust anchors from a PEM CA bundle file. + * Returns 0 on success, -1 on failure. + */ + static int load_pem_file(const char *path, + br_x509_trust_anchor **anchors_out, size_t *count_out); + + /* + * Free trust anchors that were loaded from a PEM file. + * Deep-frees DN data and key data, then frees the array. + */ + static void free_trust_anchors(br_x509_trust_anchor *anchors, + size_t count); + + /* + * Auto-update the trust store. + * + * If save_path does not exist, downloads a fresh CA bundle from + * curl.se over HTTPS (using the provided trust anchors with time + * validation disabled) and saves it to save_path. + * + * Returns 0 on success (file already existed or was downloaded). + * Returns -1 on failure (download failed, file I/O error, etc.). + */ + static int update_trust_store(const char *save_path, + br_x509_trust_anchor *anchors, size_t anchor_count); + +private: + /* + * Download an HTTPS resource and save to a file. + * Uses BearSSL with the given trust anchors (time check disabled). + * Follows up to max_redirects HTTP 301/302 redirects. + * Returns 0 on success, -1 on failure. + */ + static int download_https(const char *host, const char *path, + uint16_t port, const char *save_path, + br_x509_trust_anchor *anchors, size_t anchor_count, + int max_redirects); +}; diff --git a/libcurl/lib/vtls/cert_pinning.cpp b/libcurl/lib/vtls/cert_pinning.cpp new file mode 100644 index 0000000..bbc5719 --- /dev/null +++ b/libcurl/lib/vtls/cert_pinning.cpp @@ -0,0 +1,150 @@ +#include "cert_pinning.h" +#include "ssl_debug.h" + +#include +#include + +cert_pinning::pin_entry cert_pinning::pins[MAX_PINNED_HOSTS]; +bool cert_pinning::initialized = false; + +void cert_pinning::initialize() +{ + if (initialized) return; + + memset(pins, 0, sizeof(pins)); + initialized = true; + ssl_debug::log_verbose("Certificate pinning initialized\n"); +} + +void cert_pinning::shutdown() +{ + clear(); + initialized = false; +} + +int cert_pinning::find_pin(const char* hostname) +{ + for (int i = 0; i < MAX_PINNED_HOSTS; i++) { + if (pins[i].valid && strcmp(pins[i].hostname, hostname) == 0) { + return i; + } + } + return -1; +} + +bool cert_pinning::add_pin(const char* hostname, const unsigned char* sha256_hash) +{ + if (!initialized) initialize(); + + // Check if already exists + int idx = find_pin(hostname); + if (idx >= 0) { + // Update existing + memcpy(pins[idx].sha256_hash, sha256_hash, 32); + ssl_debug::log_info("Certificate pin updated for %s\n", hostname); + return true; + } + + // Find free slot + for (int i = 0; i < MAX_PINNED_HOSTS; i++) { + if (!pins[i].valid) { + strncpy(pins[i].hostname, hostname, 255); + pins[i].hostname[255] = '\0'; + memcpy(pins[i].sha256_hash, sha256_hash, 32); + pins[i].valid = true; + ssl_debug::log_info("Certificate pin added for %s\n", hostname); + return true; + } + } + + ssl_debug::log_error("Certificate pin table full, cannot add %s\n", hostname); + return false; +} + +void cert_pinning::remove_pin(const char* hostname) +{ + int idx = find_pin(hostname); + if (idx >= 0) { + pins[idx].valid = false; + ssl_debug::log_info("Certificate pin removed for %s\n", hostname); + } +} + +void cert_pinning::clear() +{ + memset(pins, 0, sizeof(pins)); + ssl_debug::log_verbose("All certificate pins cleared\n"); +} + +bool cert_pinning::has_pin(const char* hostname) +{ + return find_pin(hostname) >= 0; +} + +bool cert_pinning::get_pin_hash(const char* hostname, unsigned char* hash_out) +{ + int idx = find_pin(hostname); + if (idx < 0) { + return false; + } + memcpy(hash_out, pins[idx].sha256_hash, 32); + return true; +} + +void cert_pinning::get_cert_hash(br_ssl_engine_context* engine, unsigned char* hash_out) +{ + /* + * This legacy function is kept for API compatibility but is not the + * recommended path. Use verify_hash() with a hash captured by the + * custom X.509 callback in bearssl.c instead. + */ + (void)engine; + memset(hash_out, 0, 32); +} + +bool cert_pinning::verify_hash(const char* hostname, const unsigned char* cert_sha256) +{ + if (!initialized) initialize(); + + int idx = find_pin(hostname); + if (idx < 0) { + /* No pin for this host - allow connection */ + return true; + } + + /* Compare the captured certificate hash against the stored pin */ + if (memcmp(pins[idx].sha256_hash, cert_sha256, 32) == 0) { + ssl_debug::log_info("Certificate pin MATCH for %s\n", hostname); + return true; + } + + /* Pin mismatch */ + ssl_debug::log_error("Certificate pin MISMATCH for %s!\n", hostname); + ssl_debug::log_error(" Expected: %02X%02X%02X%02X...\n", + pins[idx].sha256_hash[0], pins[idx].sha256_hash[1], + pins[idx].sha256_hash[2], pins[idx].sha256_hash[3]); + ssl_debug::log_error(" Got: %02X%02X%02X%02X...\n", + cert_sha256[0], cert_sha256[1], cert_sha256[2], cert_sha256[3]); + return false; +} + +bool cert_pinning::verify(const char* hostname, br_ssl_engine_context* engine) +{ + if (!initialized) initialize(); + + int idx = find_pin(hostname); + if (idx < 0) { + /* No pin for this host - allow connection */ + return true; + } + + /* + * Legacy path: try to use the engine directly. + * The preferred path is verify_hash() called from the X.509 callback + * in bearssl.c, which captures the leaf cert hash during the handshake. + */ + ssl_debug::log_info("Certificate pin check for %s (via engine - use verify_hash for best results)\n", hostname); + + (void)engine; + return true; +} diff --git a/libcurl/lib/vtls/cert_pinning.h b/libcurl/lib/vtls/cert_pinning.h new file mode 100644 index 0000000..58c25b5 --- /dev/null +++ b/libcurl/lib/vtls/cert_pinning.h @@ -0,0 +1,49 @@ +#pragma once + +#include + +#define MAX_PINNED_HOSTS 8 + +class cert_pinning +{ +public: + static void initialize(); + static void shutdown(); + + // Add a pin: hostname + SHA-256 hash of certificate + static bool add_pin(const char* hostname, const unsigned char* sha256_hash); + + // Remove a pin + static void remove_pin(const char* hostname); + + // Clear all pins + static void clear(); + + // Verify certificate hash matches pin (returns true if no pin exists or if pin matches) + static bool verify(const char* hostname, br_ssl_engine_context* engine); + + // Verify a pre-computed SHA-256 hash against stored pin + // Returns true if no pin exists for hostname, or if pin matches the hash + static bool verify_hash(const char* hostname, const unsigned char* cert_sha256); + + // Check if hostname has a pin + static bool has_pin(const char* hostname); + + // Get the stored pin hash for a hostname (returns false if no pin) + static bool get_pin_hash(const char* hostname, unsigned char* hash_out); + + // Get hash of current certificate (for setting up pins) + static void get_cert_hash(br_ssl_engine_context* engine, unsigned char* hash_out); + +private: + struct pin_entry { + char hostname[256]; + unsigned char sha256_hash[32]; + bool valid; + }; + + static pin_entry pins[MAX_PINNED_HOSTS]; + static bool initialized; + + static int find_pin(const char* hostname); +}; diff --git a/libcurl/lib/vtls/certificates.cpp b/libcurl/lib/vtls/certificates.cpp new file mode 100644 index 0000000..8c4020a --- /dev/null +++ b/libcurl/lib/vtls/certificates.cpp @@ -0,0 +1,858 @@ +#include "certificates.h" +#include "ca_loader.h" +#include +#include + +#include "trust_anchors.h" + +#define NUM_TRUST_ANCHORS 750 + +namespace +{ + br_x509_trust_anchor* trust_anchors = NULL; + int trust_anchor_count = 0; + int loaded_from_file = 0; /* 1 = heap-allocated per-anchor data */ +} + +void certificates::initialize_trust_anchors() +{ + if (trust_anchors != NULL) + { + return; + } + trust_anchors = (br_x509_trust_anchor*)malloc(NUM_TRUST_ANCHORS * sizeof br_x509_trust_anchor); + if (trust_anchors == NULL) + { + OutputDebugStringA("certificates: FATAL - malloc failed for trust anchors!\n"); + return; + } + trust_anchor_count = NUM_TRUST_ANCHORS; + loaded_from_file = 0; + trust_anchors[0] = make_rsa_trust_anchor((unsigned char *)TA0_DN, sizeof TA0_DN, (unsigned char *)TA0_RSA_N, sizeof TA0_RSA_N, (unsigned char *)TA0_RSA_E, sizeof TA0_RSA_E); + trust_anchors[1] = make_ec_trust_anchor((unsigned char *)TA1_DN, sizeof TA1_DN, BR_EC_secp384r1, (unsigned char *)TA1_EC_Q, sizeof TA1_EC_Q); + trust_anchors[2] = make_rsa_trust_anchor((unsigned char *)TA2_DN, sizeof TA2_DN, (unsigned char *)TA2_RSA_N, sizeof TA2_RSA_N, (unsigned char *)TA2_RSA_E, sizeof TA2_RSA_E); + trust_anchors[3] = make_rsa_trust_anchor((unsigned char *)TA3_DN, sizeof TA3_DN, (unsigned char *)TA3_RSA_N, sizeof TA3_RSA_N, (unsigned char *)TA3_RSA_E, sizeof TA3_RSA_E); + trust_anchors[4] = make_ec_trust_anchor((unsigned char *)TA4_DN, sizeof TA4_DN, BR_EC_secp384r1, (unsigned char *)TA4_EC_Q, sizeof TA4_EC_Q); + trust_anchors[5] = make_rsa_trust_anchor((unsigned char *)TA5_DN, sizeof TA5_DN, (unsigned char *)TA5_RSA_N, sizeof TA5_RSA_N, (unsigned char *)TA5_RSA_E, sizeof TA5_RSA_E); + trust_anchors[6] = make_rsa_trust_anchor((unsigned char *)TA6_DN, sizeof TA6_DN, (unsigned char *)TA6_RSA_N, sizeof TA6_RSA_N, (unsigned char *)TA6_RSA_E, sizeof TA6_RSA_E); + trust_anchors[7] = make_ec_trust_anchor((unsigned char *)TA7_DN, sizeof TA7_DN, BR_EC_secp384r1, (unsigned char *)TA7_EC_Q, sizeof TA7_EC_Q); + trust_anchors[8] = make_rsa_trust_anchor((unsigned char *)TA8_DN, sizeof TA8_DN, (unsigned char *)TA8_RSA_N, sizeof TA8_RSA_N, (unsigned char *)TA8_RSA_E, sizeof TA8_RSA_E); + trust_anchors[9] = make_ec_trust_anchor((unsigned char *)TA9_DN, sizeof TA9_DN, BR_EC_secp384r1, (unsigned char *)TA9_EC_Q, sizeof TA9_EC_Q); + trust_anchors[10] = make_rsa_trust_anchor((unsigned char *)TA10_DN, sizeof TA10_DN, (unsigned char *)TA10_RSA_N, sizeof TA10_RSA_N, (unsigned char *)TA10_RSA_E, sizeof TA10_RSA_E); + trust_anchors[11] = make_ec_trust_anchor((unsigned char *)TA11_DN, sizeof TA11_DN, BR_EC_secp384r1, (unsigned char *)TA11_EC_Q, sizeof TA11_EC_Q); + trust_anchors[12] = make_rsa_trust_anchor((unsigned char *)TA12_DN, sizeof TA12_DN, (unsigned char *)TA12_RSA_N, sizeof TA12_RSA_N, (unsigned char *)TA12_RSA_E, sizeof TA12_RSA_E); + trust_anchors[13] = make_ec_trust_anchor((unsigned char *)TA13_DN, sizeof TA13_DN, BR_EC_secp384r1, (unsigned char *)TA13_EC_Q, sizeof TA13_EC_Q); + trust_anchors[14] = make_ec_trust_anchor((unsigned char *)TA14_DN, sizeof TA14_DN, BR_EC_secp384r1, (unsigned char *)TA14_EC_Q, sizeof TA14_EC_Q); + trust_anchors[15] = make_ec_trust_anchor((unsigned char *)TA15_DN, sizeof TA15_DN, BR_EC_secp256r1, (unsigned char *)TA15_EC_Q, sizeof TA15_EC_Q); + trust_anchors[16] = make_rsa_trust_anchor((unsigned char *)TA16_DN, sizeof TA16_DN, (unsigned char *)TA16_RSA_N, sizeof TA16_RSA_N, (unsigned char *)TA16_RSA_E, sizeof TA16_RSA_E); + trust_anchors[17] = make_rsa_trust_anchor((unsigned char *)TA17_DN, sizeof TA17_DN, (unsigned char *)TA17_RSA_N, sizeof TA17_RSA_N, (unsigned char *)TA17_RSA_E, sizeof TA17_RSA_E); + trust_anchors[18] = make_rsa_trust_anchor((unsigned char *)TA18_DN, sizeof TA18_DN, (unsigned char *)TA18_RSA_N, sizeof TA18_RSA_N, (unsigned char *)TA18_RSA_E, sizeof TA18_RSA_E); + trust_anchors[19] = make_rsa_trust_anchor((unsigned char *)TA19_DN, sizeof TA19_DN, (unsigned char *)TA19_RSA_N, sizeof TA19_RSA_N, (unsigned char *)TA19_RSA_E, sizeof TA19_RSA_E); + trust_anchors[20] = make_ec_trust_anchor((unsigned char *)TA20_DN, sizeof TA20_DN, BR_EC_secp384r1, (unsigned char *)TA20_EC_Q, sizeof TA20_EC_Q); + trust_anchors[21] = make_rsa_trust_anchor((unsigned char *)TA21_DN, sizeof TA21_DN, (unsigned char *)TA21_RSA_N, sizeof TA21_RSA_N, (unsigned char *)TA21_RSA_E, sizeof TA21_RSA_E); + trust_anchors[22] = make_ec_trust_anchor((unsigned char *)TA22_DN, sizeof TA22_DN, BR_EC_secp384r1, (unsigned char *)TA22_EC_Q, sizeof TA22_EC_Q); + trust_anchors[23] = make_ec_trust_anchor((unsigned char *)TA23_DN, sizeof TA23_DN, BR_EC_secp256r1, (unsigned char *)TA23_EC_Q, sizeof TA23_EC_Q); + trust_anchors[24] = make_rsa_trust_anchor((unsigned char *)TA24_DN, sizeof TA24_DN, (unsigned char *)TA24_RSA_N, sizeof TA24_RSA_N, (unsigned char *)TA24_RSA_E, sizeof TA24_RSA_E); + trust_anchors[25] = make_ec_trust_anchor((unsigned char *)TA25_DN, sizeof TA25_DN, BR_EC_secp384r1, (unsigned char *)TA25_EC_Q, sizeof TA25_EC_Q); + trust_anchors[26] = make_ec_trust_anchor((unsigned char *)TA26_DN, sizeof TA26_DN, BR_EC_secp384r1, (unsigned char *)TA26_EC_Q, sizeof TA26_EC_Q); + trust_anchors[27] = make_rsa_trust_anchor((unsigned char *)TA27_DN, sizeof TA27_DN, (unsigned char *)TA27_RSA_N, sizeof TA27_RSA_N, (unsigned char *)TA27_RSA_E, sizeof TA27_RSA_E); + trust_anchors[28] = make_rsa_trust_anchor((unsigned char *)TA28_DN, sizeof TA28_DN, (unsigned char *)TA28_RSA_N, sizeof TA28_RSA_N, (unsigned char *)TA28_RSA_E, sizeof TA28_RSA_E); + trust_anchors[29] = make_rsa_trust_anchor((unsigned char *)TA29_DN, sizeof TA29_DN, (unsigned char *)TA29_RSA_N, sizeof TA29_RSA_N, (unsigned char *)TA29_RSA_E, sizeof TA29_RSA_E); + trust_anchors[30] = make_rsa_trust_anchor((unsigned char *)TA30_DN, sizeof TA30_DN, (unsigned char *)TA30_RSA_N, sizeof TA30_RSA_N, (unsigned char *)TA30_RSA_E, sizeof TA30_RSA_E); + trust_anchors[31] = make_rsa_trust_anchor((unsigned char *)TA31_DN, sizeof TA31_DN, (unsigned char *)TA31_RSA_N, sizeof TA31_RSA_N, (unsigned char *)TA31_RSA_E, sizeof TA31_RSA_E); + trust_anchors[32] = make_rsa_trust_anchor((unsigned char *)TA32_DN, sizeof TA32_DN, (unsigned char *)TA32_RSA_N, sizeof TA32_RSA_N, (unsigned char *)TA32_RSA_E, sizeof TA32_RSA_E); + trust_anchors[33] = make_rsa_trust_anchor((unsigned char *)TA33_DN, sizeof TA33_DN, (unsigned char *)TA33_RSA_N, sizeof TA33_RSA_N, (unsigned char *)TA33_RSA_E, sizeof TA33_RSA_E); + trust_anchors[34] = make_rsa_trust_anchor((unsigned char *)TA34_DN, sizeof TA34_DN, (unsigned char *)TA34_RSA_N, sizeof TA34_RSA_N, (unsigned char *)TA34_RSA_E, sizeof TA34_RSA_E); + trust_anchors[35] = make_rsa_trust_anchor((unsigned char *)TA35_DN, sizeof TA35_DN, (unsigned char *)TA35_RSA_N, sizeof TA35_RSA_N, (unsigned char *)TA35_RSA_E, sizeof TA35_RSA_E); + trust_anchors[36] = make_ec_trust_anchor((unsigned char *)TA36_DN, sizeof TA36_DN, BR_EC_secp384r1, (unsigned char *)TA36_EC_Q, sizeof TA36_EC_Q); + trust_anchors[37] = make_rsa_trust_anchor((unsigned char *)TA37_DN, sizeof TA37_DN, (unsigned char *)TA37_RSA_N, sizeof TA37_RSA_N, (unsigned char *)TA37_RSA_E, sizeof TA37_RSA_E); + trust_anchors[38] = make_rsa_trust_anchor((unsigned char *)TA38_DN, sizeof TA38_DN, (unsigned char *)TA38_RSA_N, sizeof TA38_RSA_N, (unsigned char *)TA38_RSA_E, sizeof TA38_RSA_E); + trust_anchors[39] = make_ec_trust_anchor((unsigned char *)TA39_DN, sizeof TA39_DN, BR_EC_secp384r1, (unsigned char *)TA39_EC_Q, sizeof TA39_EC_Q); + trust_anchors[40] = make_rsa_trust_anchor((unsigned char *)TA40_DN, sizeof TA40_DN, (unsigned char *)TA40_RSA_N, sizeof TA40_RSA_N, (unsigned char *)TA40_RSA_E, sizeof TA40_RSA_E); + trust_anchors[41] = make_ec_trust_anchor((unsigned char *)TA41_DN, sizeof TA41_DN, BR_EC_secp384r1, (unsigned char *)TA41_EC_Q, sizeof TA41_EC_Q); + trust_anchors[42] = make_rsa_trust_anchor((unsigned char *)TA42_DN, sizeof TA42_DN, (unsigned char *)TA42_RSA_N, sizeof TA42_RSA_N, (unsigned char *)TA42_RSA_E, sizeof TA42_RSA_E); + trust_anchors[43] = make_rsa_trust_anchor((unsigned char *)TA43_DN, sizeof TA43_DN, (unsigned char *)TA43_RSA_N, sizeof TA43_RSA_N, (unsigned char *)TA43_RSA_E, sizeof TA43_RSA_E); + trust_anchors[44] = make_rsa_trust_anchor((unsigned char *)TA44_DN, sizeof TA44_DN, (unsigned char *)TA44_RSA_N, sizeof TA44_RSA_N, (unsigned char *)TA44_RSA_E, sizeof TA44_RSA_E); + trust_anchors[45] = make_ec_trust_anchor((unsigned char *)TA45_DN, sizeof TA45_DN, BR_EC_secp384r1, (unsigned char *)TA45_EC_Q, sizeof TA45_EC_Q); + trust_anchors[46] = make_rsa_trust_anchor((unsigned char *)TA46_DN, sizeof TA46_DN, (unsigned char *)TA46_RSA_N, sizeof TA46_RSA_N, (unsigned char *)TA46_RSA_E, sizeof TA46_RSA_E); + trust_anchors[47] = make_rsa_trust_anchor((unsigned char *)TA47_DN, sizeof TA47_DN, (unsigned char *)TA47_RSA_N, sizeof TA47_RSA_N, (unsigned char *)TA47_RSA_E, sizeof TA47_RSA_E); + trust_anchors[48] = make_rsa_trust_anchor((unsigned char *)TA48_DN, sizeof TA48_DN, (unsigned char *)TA48_RSA_N, sizeof TA48_RSA_N, (unsigned char *)TA48_RSA_E, sizeof TA48_RSA_E); + trust_anchors[49] = make_rsa_trust_anchor((unsigned char *)TA49_DN, sizeof TA49_DN, (unsigned char *)TA49_RSA_N, sizeof TA49_RSA_N, (unsigned char *)TA49_RSA_E, sizeof TA49_RSA_E); + trust_anchors[50] = make_rsa_trust_anchor((unsigned char *)TA50_DN, sizeof TA50_DN, (unsigned char *)TA50_RSA_N, sizeof TA50_RSA_N, (unsigned char *)TA50_RSA_E, sizeof TA50_RSA_E); + trust_anchors[51] = make_rsa_trust_anchor((unsigned char *)TA51_DN, sizeof TA51_DN, (unsigned char *)TA51_RSA_N, sizeof TA51_RSA_N, (unsigned char *)TA51_RSA_E, sizeof TA51_RSA_E); + trust_anchors[52] = make_ec_trust_anchor((unsigned char *)TA52_DN, sizeof TA52_DN, BR_EC_secp384r1, (unsigned char *)TA52_EC_Q, sizeof TA52_EC_Q); + trust_anchors[53] = make_rsa_trust_anchor((unsigned char *)TA53_DN, sizeof TA53_DN, (unsigned char *)TA53_RSA_N, sizeof TA53_RSA_N, (unsigned char *)TA53_RSA_E, sizeof TA53_RSA_E); + trust_anchors[54] = make_rsa_trust_anchor((unsigned char *)TA54_DN, sizeof TA54_DN, (unsigned char *)TA54_RSA_N, sizeof TA54_RSA_N, (unsigned char *)TA54_RSA_E, sizeof TA54_RSA_E); + trust_anchors[55] = make_rsa_trust_anchor((unsigned char *)TA55_DN, sizeof TA55_DN, (unsigned char *)TA55_RSA_N, sizeof TA55_RSA_N, (unsigned char *)TA55_RSA_E, sizeof TA55_RSA_E); + trust_anchors[56] = make_rsa_trust_anchor((unsigned char *)TA56_DN, sizeof TA56_DN, (unsigned char *)TA56_RSA_N, sizeof TA56_RSA_N, (unsigned char *)TA56_RSA_E, sizeof TA56_RSA_E); + trust_anchors[57] = make_ec_trust_anchor((unsigned char *)TA57_DN, sizeof TA57_DN, BR_EC_secp384r1, (unsigned char *)TA57_EC_Q, sizeof TA57_EC_Q); + trust_anchors[58] = make_rsa_trust_anchor((unsigned char *)TA58_DN, sizeof TA58_DN, (unsigned char *)TA58_RSA_N, sizeof TA58_RSA_N, (unsigned char *)TA58_RSA_E, sizeof TA58_RSA_E); + trust_anchors[59] = make_rsa_trust_anchor((unsigned char *)TA59_DN, sizeof TA59_DN, (unsigned char *)TA59_RSA_N, sizeof TA59_RSA_N, (unsigned char *)TA59_RSA_E, sizeof TA59_RSA_E); + trust_anchors[60] = make_ec_trust_anchor((unsigned char *)TA60_DN, sizeof TA60_DN, BR_EC_secp384r1, (unsigned char *)TA60_EC_Q, sizeof TA60_EC_Q); + trust_anchors[61] = make_rsa_trust_anchor((unsigned char *)TA61_DN, sizeof TA61_DN, (unsigned char *)TA61_RSA_N, sizeof TA61_RSA_N, (unsigned char *)TA61_RSA_E, sizeof TA61_RSA_E); + trust_anchors[62] = make_ec_trust_anchor((unsigned char *)TA62_DN, sizeof TA62_DN, BR_EC_secp384r1, (unsigned char *)TA62_EC_Q, sizeof TA62_EC_Q); + trust_anchors[63] = make_rsa_trust_anchor((unsigned char *)TA63_DN, sizeof TA63_DN, (unsigned char *)TA63_RSA_N, sizeof TA63_RSA_N, (unsigned char *)TA63_RSA_E, sizeof TA63_RSA_E); + trust_anchors[64] = make_rsa_trust_anchor((unsigned char *)TA64_DN, sizeof TA64_DN, (unsigned char *)TA64_RSA_N, sizeof TA64_RSA_N, (unsigned char *)TA64_RSA_E, sizeof TA64_RSA_E); + trust_anchors[65] = make_rsa_trust_anchor((unsigned char *)TA65_DN, sizeof TA65_DN, (unsigned char *)TA65_RSA_N, sizeof TA65_RSA_N, (unsigned char *)TA65_RSA_E, sizeof TA65_RSA_E); + trust_anchors[66] = make_rsa_trust_anchor((unsigned char *)TA66_DN, sizeof TA66_DN, (unsigned char *)TA66_RSA_N, sizeof TA66_RSA_N, (unsigned char *)TA66_RSA_E, sizeof TA66_RSA_E); + trust_anchors[67] = make_rsa_trust_anchor((unsigned char *)TA67_DN, sizeof TA67_DN, (unsigned char *)TA67_RSA_N, sizeof TA67_RSA_N, (unsigned char *)TA67_RSA_E, sizeof TA67_RSA_E); + trust_anchors[68] = make_rsa_trust_anchor((unsigned char *)TA68_DN, sizeof TA68_DN, (unsigned char *)TA68_RSA_N, sizeof TA68_RSA_N, (unsigned char *)TA68_RSA_E, sizeof TA68_RSA_E); + trust_anchors[69] = make_ec_trust_anchor((unsigned char *)TA69_DN, sizeof TA69_DN, BR_EC_secp384r1, (unsigned char *)TA69_EC_Q, sizeof TA69_EC_Q); + trust_anchors[70] = make_rsa_trust_anchor((unsigned char *)TA70_DN, sizeof TA70_DN, (unsigned char *)TA70_RSA_N, sizeof TA70_RSA_N, (unsigned char *)TA70_RSA_E, sizeof TA70_RSA_E); + trust_anchors[71] = make_rsa_trust_anchor((unsigned char *)TA71_DN, sizeof TA71_DN, (unsigned char *)TA71_RSA_N, sizeof TA71_RSA_N, (unsigned char *)TA71_RSA_E, sizeof TA71_RSA_E); + trust_anchors[72] = make_rsa_trust_anchor((unsigned char *)TA72_DN, sizeof TA72_DN, (unsigned char *)TA72_RSA_N, sizeof TA72_RSA_N, (unsigned char *)TA72_RSA_E, sizeof TA72_RSA_E); + trust_anchors[73] = make_rsa_trust_anchor((unsigned char *)TA73_DN, sizeof TA73_DN, (unsigned char *)TA73_RSA_N, sizeof TA73_RSA_N, (unsigned char *)TA73_RSA_E, sizeof TA73_RSA_E); + trust_anchors[74] = make_ec_trust_anchor((unsigned char *)TA74_DN, sizeof TA74_DN, BR_EC_secp384r1, (unsigned char *)TA74_EC_Q, sizeof TA74_EC_Q); + trust_anchors[75] = make_rsa_trust_anchor((unsigned char *)TA75_DN, sizeof TA75_DN, (unsigned char *)TA75_RSA_N, sizeof TA75_RSA_N, (unsigned char *)TA75_RSA_E, sizeof TA75_RSA_E); + trust_anchors[76] = make_rsa_trust_anchor((unsigned char *)TA76_DN, sizeof TA76_DN, (unsigned char *)TA76_RSA_N, sizeof TA76_RSA_N, (unsigned char *)TA76_RSA_E, sizeof TA76_RSA_E); + trust_anchors[77] = make_ec_trust_anchor((unsigned char *)TA77_DN, sizeof TA77_DN, BR_EC_secp384r1, (unsigned char *)TA77_EC_Q, sizeof TA77_EC_Q); + trust_anchors[78] = make_rsa_trust_anchor((unsigned char *)TA78_DN, sizeof TA78_DN, (unsigned char *)TA78_RSA_N, sizeof TA78_RSA_N, (unsigned char *)TA78_RSA_E, sizeof TA78_RSA_E); + trust_anchors[79] = make_rsa_trust_anchor((unsigned char *)TA79_DN, sizeof TA79_DN, (unsigned char *)TA79_RSA_N, sizeof TA79_RSA_N, (unsigned char *)TA79_RSA_E, sizeof TA79_RSA_E); + trust_anchors[80] = make_rsa_trust_anchor((unsigned char *)TA80_DN, sizeof TA80_DN, (unsigned char *)TA80_RSA_N, sizeof TA80_RSA_N, (unsigned char *)TA80_RSA_E, sizeof TA80_RSA_E); + trust_anchors[81] = make_rsa_trust_anchor((unsigned char *)TA81_DN, sizeof TA81_DN, (unsigned char *)TA81_RSA_N, sizeof TA81_RSA_N, (unsigned char *)TA81_RSA_E, sizeof TA81_RSA_E); + trust_anchors[82] = make_rsa_trust_anchor((unsigned char *)TA82_DN, sizeof TA82_DN, (unsigned char *)TA82_RSA_N, sizeof TA82_RSA_N, (unsigned char *)TA82_RSA_E, sizeof TA82_RSA_E); + trust_anchors[83] = make_rsa_trust_anchor((unsigned char *)TA83_DN, sizeof TA83_DN, (unsigned char *)TA83_RSA_N, sizeof TA83_RSA_N, (unsigned char *)TA83_RSA_E, sizeof TA83_RSA_E); + trust_anchors[84] = make_rsa_trust_anchor((unsigned char *)TA84_DN, sizeof TA84_DN, (unsigned char *)TA84_RSA_N, sizeof TA84_RSA_N, (unsigned char *)TA84_RSA_E, sizeof TA84_RSA_E); + trust_anchors[85] = make_ec_trust_anchor((unsigned char *)TA85_DN, sizeof TA85_DN, BR_EC_secp384r1, (unsigned char *)TA85_EC_Q, sizeof TA85_EC_Q); + trust_anchors[86] = make_ec_trust_anchor((unsigned char *)TA86_DN, sizeof TA86_DN, BR_EC_secp384r1, (unsigned char *)TA86_EC_Q, sizeof TA86_EC_Q); + trust_anchors[87] = make_ec_trust_anchor((unsigned char *)TA87_DN, sizeof TA87_DN, BR_EC_secp384r1, (unsigned char *)TA87_EC_Q, sizeof TA87_EC_Q); + trust_anchors[88] = make_rsa_trust_anchor((unsigned char *)TA88_DN, sizeof TA88_DN, (unsigned char *)TA88_RSA_N, sizeof TA88_RSA_N, (unsigned char *)TA88_RSA_E, sizeof TA88_RSA_E); + trust_anchors[89] = make_ec_trust_anchor((unsigned char *)TA89_DN, sizeof TA89_DN, BR_EC_secp384r1, (unsigned char *)TA89_EC_Q, sizeof TA89_EC_Q); + trust_anchors[90] = make_rsa_trust_anchor((unsigned char *)TA90_DN, sizeof TA90_DN, (unsigned char *)TA90_RSA_N, sizeof TA90_RSA_N, (unsigned char *)TA90_RSA_E, sizeof TA90_RSA_E); + trust_anchors[91] = make_rsa_trust_anchor((unsigned char *)TA91_DN, sizeof TA91_DN, (unsigned char *)TA91_RSA_N, sizeof TA91_RSA_N, (unsigned char *)TA91_RSA_E, sizeof TA91_RSA_E); + trust_anchors[92] = make_rsa_trust_anchor((unsigned char *)TA92_DN, sizeof TA92_DN, (unsigned char *)TA92_RSA_N, sizeof TA92_RSA_N, (unsigned char *)TA92_RSA_E, sizeof TA92_RSA_E); + trust_anchors[93] = make_rsa_trust_anchor((unsigned char *)TA93_DN, sizeof TA93_DN, (unsigned char *)TA93_RSA_N, sizeof TA93_RSA_N, (unsigned char *)TA93_RSA_E, sizeof TA93_RSA_E); + trust_anchors[94] = make_rsa_trust_anchor((unsigned char *)TA94_DN, sizeof TA94_DN, (unsigned char *)TA94_RSA_N, sizeof TA94_RSA_N, (unsigned char *)TA94_RSA_E, sizeof TA94_RSA_E); + trust_anchors[95] = make_rsa_trust_anchor((unsigned char *)TA95_DN, sizeof TA95_DN, (unsigned char *)TA95_RSA_N, sizeof TA95_RSA_N, (unsigned char *)TA95_RSA_E, sizeof TA95_RSA_E); + trust_anchors[96] = make_ec_trust_anchor((unsigned char *)TA96_DN, sizeof TA96_DN, BR_EC_secp384r1, (unsigned char *)TA96_EC_Q, sizeof TA96_EC_Q); + trust_anchors[97] = make_ec_trust_anchor((unsigned char *)TA97_DN, sizeof TA97_DN, BR_EC_secp384r1, (unsigned char *)TA97_EC_Q, sizeof TA97_EC_Q); + trust_anchors[98] = make_rsa_trust_anchor((unsigned char *)TA98_DN, sizeof TA98_DN, (unsigned char *)TA98_RSA_N, sizeof TA98_RSA_N, (unsigned char *)TA98_RSA_E, sizeof TA98_RSA_E); + trust_anchors[99] = make_rsa_trust_anchor((unsigned char *)TA99_DN, sizeof TA99_DN, (unsigned char *)TA99_RSA_N, sizeof TA99_RSA_N, (unsigned char *)TA99_RSA_E, sizeof TA99_RSA_E); + trust_anchors[100] = make_rsa_trust_anchor((unsigned char *)TA100_DN, sizeof TA100_DN, (unsigned char *)TA100_RSA_N, sizeof TA100_RSA_N, (unsigned char *)TA100_RSA_E, sizeof TA100_RSA_E); + trust_anchors[101] = make_rsa_trust_anchor((unsigned char *)TA101_DN, sizeof TA101_DN, (unsigned char *)TA101_RSA_N, sizeof TA101_RSA_N, (unsigned char *)TA101_RSA_E, sizeof TA101_RSA_E); + trust_anchors[102] = make_rsa_trust_anchor((unsigned char *)TA102_DN, sizeof TA102_DN, (unsigned char *)TA102_RSA_N, sizeof TA102_RSA_N, (unsigned char *)TA102_RSA_E, sizeof TA102_RSA_E); + trust_anchors[103] = make_rsa_trust_anchor((unsigned char *)TA103_DN, sizeof TA103_DN, (unsigned char *)TA103_RSA_N, sizeof TA103_RSA_N, (unsigned char *)TA103_RSA_E, sizeof TA103_RSA_E); + trust_anchors[104] = make_rsa_trust_anchor((unsigned char *)TA104_DN, sizeof TA104_DN, (unsigned char *)TA104_RSA_N, sizeof TA104_RSA_N, (unsigned char *)TA104_RSA_E, sizeof TA104_RSA_E); + trust_anchors[105] = make_rsa_trust_anchor((unsigned char *)TA105_DN, sizeof TA105_DN, (unsigned char *)TA105_RSA_N, sizeof TA105_RSA_N, (unsigned char *)TA105_RSA_E, sizeof TA105_RSA_E); + trust_anchors[106] = make_rsa_trust_anchor((unsigned char *)TA106_DN, sizeof TA106_DN, (unsigned char *)TA106_RSA_N, sizeof TA106_RSA_N, (unsigned char *)TA106_RSA_E, sizeof TA106_RSA_E); + trust_anchors[107] = make_ec_trust_anchor((unsigned char *)TA107_DN, sizeof TA107_DN, BR_EC_secp384r1, (unsigned char *)TA107_EC_Q, sizeof TA107_EC_Q); + trust_anchors[108] = make_ec_trust_anchor((unsigned char *)TA108_DN, sizeof TA108_DN, BR_EC_secp384r1, (unsigned char *)TA108_EC_Q, sizeof TA108_EC_Q); + trust_anchors[109] = make_ec_trust_anchor((unsigned char *)TA109_DN, sizeof TA109_DN, BR_EC_secp384r1, (unsigned char *)TA109_EC_Q, sizeof TA109_EC_Q); + trust_anchors[110] = make_rsa_trust_anchor((unsigned char *)TA110_DN, sizeof TA110_DN, (unsigned char *)TA110_RSA_N, sizeof TA110_RSA_N, (unsigned char *)TA110_RSA_E, sizeof TA110_RSA_E); + trust_anchors[111] = make_rsa_trust_anchor((unsigned char *)TA111_DN, sizeof TA111_DN, (unsigned char *)TA111_RSA_N, sizeof TA111_RSA_N, (unsigned char *)TA111_RSA_E, sizeof TA111_RSA_E); + trust_anchors[112] = make_rsa_trust_anchor((unsigned char *)TA112_DN, sizeof TA112_DN, (unsigned char *)TA112_RSA_N, sizeof TA112_RSA_N, (unsigned char *)TA112_RSA_E, sizeof TA112_RSA_E); + trust_anchors[113] = make_rsa_trust_anchor((unsigned char *)TA113_DN, sizeof TA113_DN, (unsigned char *)TA113_RSA_N, sizeof TA113_RSA_N, (unsigned char *)TA113_RSA_E, sizeof TA113_RSA_E); + trust_anchors[114] = make_rsa_trust_anchor((unsigned char *)TA114_DN, sizeof TA114_DN, (unsigned char *)TA114_RSA_N, sizeof TA114_RSA_N, (unsigned char *)TA114_RSA_E, sizeof TA114_RSA_E); + trust_anchors[115] = make_rsa_trust_anchor((unsigned char *)TA115_DN, sizeof TA115_DN, (unsigned char *)TA115_RSA_N, sizeof TA115_RSA_N, (unsigned char *)TA115_RSA_E, sizeof TA115_RSA_E); + trust_anchors[116] = make_rsa_trust_anchor((unsigned char *)TA116_DN, sizeof TA116_DN, (unsigned char *)TA116_RSA_N, sizeof TA116_RSA_N, (unsigned char *)TA116_RSA_E, sizeof TA116_RSA_E); + trust_anchors[117] = make_rsa_trust_anchor((unsigned char *)TA117_DN, sizeof TA117_DN, (unsigned char *)TA117_RSA_N, sizeof TA117_RSA_N, (unsigned char *)TA117_RSA_E, sizeof TA117_RSA_E); + trust_anchors[118] = make_rsa_trust_anchor((unsigned char *)TA118_DN, sizeof TA118_DN, (unsigned char *)TA118_RSA_N, sizeof TA118_RSA_N, (unsigned char *)TA118_RSA_E, sizeof TA118_RSA_E); + trust_anchors[119] = make_rsa_trust_anchor((unsigned char *)TA119_DN, sizeof TA119_DN, (unsigned char *)TA119_RSA_N, sizeof TA119_RSA_N, (unsigned char *)TA119_RSA_E, sizeof TA119_RSA_E); + trust_anchors[120] = make_ec_trust_anchor((unsigned char *)TA120_DN, sizeof TA120_DN, BR_EC_secp384r1, (unsigned char *)TA120_EC_Q, sizeof TA120_EC_Q); + trust_anchors[121] = make_ec_trust_anchor((unsigned char *)TA121_DN, sizeof TA121_DN, BR_EC_secp384r1, (unsigned char *)TA121_EC_Q, sizeof TA121_EC_Q); + trust_anchors[122] = make_ec_trust_anchor((unsigned char *)TA122_DN, sizeof TA122_DN, BR_EC_secp384r1, (unsigned char *)TA122_EC_Q, sizeof TA122_EC_Q); + trust_anchors[123] = make_rsa_trust_anchor((unsigned char *)TA123_DN, sizeof TA123_DN, (unsigned char *)TA123_RSA_N, sizeof TA123_RSA_N, (unsigned char *)TA123_RSA_E, sizeof TA123_RSA_E); + trust_anchors[124] = make_rsa_trust_anchor((unsigned char *)TA124_DN, sizeof TA124_DN, (unsigned char *)TA124_RSA_N, sizeof TA124_RSA_N, (unsigned char *)TA124_RSA_E, sizeof TA124_RSA_E); + trust_anchors[125] = make_ec_trust_anchor((unsigned char *)TA125_DN, sizeof TA125_DN, BR_EC_secp384r1, (unsigned char *)TA125_EC_Q, sizeof TA125_EC_Q); + trust_anchors[126] = make_rsa_trust_anchor((unsigned char *)TA126_DN, sizeof TA126_DN, (unsigned char *)TA126_RSA_N, sizeof TA126_RSA_N, (unsigned char *)TA126_RSA_E, sizeof TA126_RSA_E); + trust_anchors[127] = make_ec_trust_anchor((unsigned char *)TA127_DN, sizeof TA127_DN, BR_EC_secp384r1, (unsigned char *)TA127_EC_Q, sizeof TA127_EC_Q); + trust_anchors[128] = make_ec_trust_anchor((unsigned char *)TA128_DN, sizeof TA128_DN, BR_EC_secp384r1, (unsigned char *)TA128_EC_Q, sizeof TA128_EC_Q); + trust_anchors[129] = make_rsa_trust_anchor((unsigned char *)TA129_DN, sizeof TA129_DN, (unsigned char *)TA129_RSA_N, sizeof TA129_RSA_N, (unsigned char *)TA129_RSA_E, sizeof TA129_RSA_E); + trust_anchors[130] = make_rsa_trust_anchor((unsigned char *)TA130_DN, sizeof TA130_DN, (unsigned char *)TA130_RSA_N, sizeof TA130_RSA_N, (unsigned char *)TA130_RSA_E, sizeof TA130_RSA_E); + trust_anchors[131] = make_rsa_trust_anchor((unsigned char *)TA131_DN, sizeof TA131_DN, (unsigned char *)TA131_RSA_N, sizeof TA131_RSA_N, (unsigned char *)TA131_RSA_E, sizeof TA131_RSA_E); + trust_anchors[132] = make_ec_trust_anchor((unsigned char *)TA132_DN, sizeof TA132_DN, BR_EC_secp384r1, (unsigned char *)TA132_EC_Q, sizeof TA132_EC_Q); + trust_anchors[133] = make_rsa_trust_anchor((unsigned char *)TA133_DN, sizeof TA133_DN, (unsigned char *)TA133_RSA_N, sizeof TA133_RSA_N, (unsigned char *)TA133_RSA_E, sizeof TA133_RSA_E); + trust_anchors[134] = make_rsa_trust_anchor((unsigned char *)TA134_DN, sizeof TA134_DN, (unsigned char *)TA134_RSA_N, sizeof TA134_RSA_N, (unsigned char *)TA134_RSA_E, sizeof TA134_RSA_E); + trust_anchors[135] = make_ec_trust_anchor((unsigned char *)TA135_DN, sizeof TA135_DN, BR_EC_secp384r1, (unsigned char *)TA135_EC_Q, sizeof TA135_EC_Q); + trust_anchors[136] = make_ec_trust_anchor((unsigned char *)TA136_DN, sizeof TA136_DN, BR_EC_secp384r1, (unsigned char *)TA136_EC_Q, sizeof TA136_EC_Q); + trust_anchors[137] = make_rsa_trust_anchor((unsigned char *)TA137_DN, sizeof TA137_DN, (unsigned char *)TA137_RSA_N, sizeof TA137_RSA_N, (unsigned char *)TA137_RSA_E, sizeof TA137_RSA_E); + trust_anchors[138] = make_rsa_trust_anchor((unsigned char *)TA138_DN, sizeof TA138_DN, (unsigned char *)TA138_RSA_N, sizeof TA138_RSA_N, (unsigned char *)TA138_RSA_E, sizeof TA138_RSA_E); + trust_anchors[139] = make_ec_trust_anchor((unsigned char *)TA139_DN, sizeof TA139_DN, BR_EC_secp384r1, (unsigned char *)TA139_EC_Q, sizeof TA139_EC_Q); + trust_anchors[140] = make_ec_trust_anchor((unsigned char *)TA140_DN, sizeof TA140_DN, BR_EC_secp384r1, (unsigned char *)TA140_EC_Q, sizeof TA140_EC_Q); + trust_anchors[141] = make_rsa_trust_anchor((unsigned char *)TA141_DN, sizeof TA141_DN, (unsigned char *)TA141_RSA_N, sizeof TA141_RSA_N, (unsigned char *)TA141_RSA_E, sizeof TA141_RSA_E); + trust_anchors[142] = make_rsa_trust_anchor((unsigned char *)TA142_DN, sizeof TA142_DN, (unsigned char *)TA142_RSA_N, sizeof TA142_RSA_N, (unsigned char *)TA142_RSA_E, sizeof TA142_RSA_E); + trust_anchors[143] = make_ec_trust_anchor((unsigned char *)TA143_DN, sizeof TA143_DN, BR_EC_secp384r1, (unsigned char *)TA143_EC_Q, sizeof TA143_EC_Q); + trust_anchors[144] = make_rsa_trust_anchor((unsigned char *)TA144_DN, sizeof TA144_DN, (unsigned char *)TA144_RSA_N, sizeof TA144_RSA_N, (unsigned char *)TA144_RSA_E, sizeof TA144_RSA_E); + trust_anchors[145] = make_ec_trust_anchor((unsigned char *)TA145_DN, sizeof TA145_DN, BR_EC_secp384r1, (unsigned char *)TA145_EC_Q, sizeof TA145_EC_Q); + trust_anchors[146] = make_ec_trust_anchor((unsigned char *)TA146_DN, sizeof TA146_DN, BR_EC_secp384r1, (unsigned char *)TA146_EC_Q, sizeof TA146_EC_Q); + trust_anchors[147] = make_ec_trust_anchor((unsigned char *)TA147_DN, sizeof TA147_DN, BR_EC_secp256r1, (unsigned char *)TA147_EC_Q, sizeof TA147_EC_Q); + trust_anchors[148] = make_rsa_trust_anchor((unsigned char *)TA148_DN, sizeof TA148_DN, (unsigned char *)TA148_RSA_N, sizeof TA148_RSA_N, (unsigned char *)TA148_RSA_E, sizeof TA148_RSA_E); + trust_anchors[149] = make_rsa_trust_anchor((unsigned char *)TA149_DN, sizeof TA149_DN, (unsigned char *)TA149_RSA_N, sizeof TA149_RSA_N, (unsigned char *)TA149_RSA_E, sizeof TA149_RSA_E); + trust_anchors[150] = make_rsa_trust_anchor((unsigned char *)TA150_DN, sizeof TA150_DN, (unsigned char *)TA150_RSA_N, sizeof TA150_RSA_N, (unsigned char *)TA150_RSA_E, sizeof TA150_RSA_E); + trust_anchors[151] = make_ec_trust_anchor((unsigned char *)TA151_DN, sizeof TA151_DN, BR_EC_secp384r1, (unsigned char *)TA151_EC_Q, sizeof TA151_EC_Q); + trust_anchors[152] = make_rsa_trust_anchor((unsigned char *)TA152_DN, sizeof TA152_DN, (unsigned char *)TA152_RSA_N, sizeof TA152_RSA_N, (unsigned char *)TA152_RSA_E, sizeof TA152_RSA_E); + trust_anchors[153] = make_ec_trust_anchor((unsigned char *)TA153_DN, sizeof TA153_DN, BR_EC_secp384r1, (unsigned char *)TA153_EC_Q, sizeof TA153_EC_Q); + trust_anchors[154] = make_rsa_trust_anchor((unsigned char *)TA154_DN, sizeof TA154_DN, (unsigned char *)TA154_RSA_N, sizeof TA154_RSA_N, (unsigned char *)TA154_RSA_E, sizeof TA154_RSA_E); + trust_anchors[155] = make_rsa_trust_anchor((unsigned char *)TA155_DN, sizeof TA155_DN, (unsigned char *)TA155_RSA_N, sizeof TA155_RSA_N, (unsigned char *)TA155_RSA_E, sizeof TA155_RSA_E); + trust_anchors[156] = make_rsa_trust_anchor((unsigned char *)TA156_DN, sizeof TA156_DN, (unsigned char *)TA156_RSA_N, sizeof TA156_RSA_N, (unsigned char *)TA156_RSA_E, sizeof TA156_RSA_E); + trust_anchors[157] = make_rsa_trust_anchor((unsigned char *)TA157_DN, sizeof TA157_DN, (unsigned char *)TA157_RSA_N, sizeof TA157_RSA_N, (unsigned char *)TA157_RSA_E, sizeof TA157_RSA_E); + trust_anchors[158] = make_rsa_trust_anchor((unsigned char *)TA158_DN, sizeof TA158_DN, (unsigned char *)TA158_RSA_N, sizeof TA158_RSA_N, (unsigned char *)TA158_RSA_E, sizeof TA158_RSA_E); + trust_anchors[159] = make_rsa_trust_anchor((unsigned char *)TA159_DN, sizeof TA159_DN, (unsigned char *)TA159_RSA_N, sizeof TA159_RSA_N, (unsigned char *)TA159_RSA_E, sizeof TA159_RSA_E); + trust_anchors[160] = make_rsa_trust_anchor((unsigned char *)TA160_DN, sizeof TA160_DN, (unsigned char *)TA160_RSA_N, sizeof TA160_RSA_N, (unsigned char *)TA160_RSA_E, sizeof TA160_RSA_E); + trust_anchors[161] = make_ec_trust_anchor((unsigned char *)TA161_DN, sizeof TA161_DN, BR_EC_secp384r1, (unsigned char *)TA161_EC_Q, sizeof TA161_EC_Q); + trust_anchors[162] = make_ec_trust_anchor((unsigned char *)TA162_DN, sizeof TA162_DN, BR_EC_secp384r1, (unsigned char *)TA162_EC_Q, sizeof TA162_EC_Q); + trust_anchors[163] = make_rsa_trust_anchor((unsigned char *)TA163_DN, sizeof TA163_DN, (unsigned char *)TA163_RSA_N, sizeof TA163_RSA_N, (unsigned char *)TA163_RSA_E, sizeof TA163_RSA_E); + trust_anchors[164] = make_rsa_trust_anchor((unsigned char *)TA164_DN, sizeof TA164_DN, (unsigned char *)TA164_RSA_N, sizeof TA164_RSA_N, (unsigned char *)TA164_RSA_E, sizeof TA164_RSA_E); + trust_anchors[165] = make_rsa_trust_anchor((unsigned char *)TA165_DN, sizeof TA165_DN, (unsigned char *)TA165_RSA_N, sizeof TA165_RSA_N, (unsigned char *)TA165_RSA_E, sizeof TA165_RSA_E); + trust_anchors[166] = make_ec_trust_anchor((unsigned char *)TA166_DN, sizeof TA166_DN, BR_EC_secp384r1, (unsigned char *)TA166_EC_Q, sizeof TA166_EC_Q); + trust_anchors[167] = make_rsa_trust_anchor((unsigned char *)TA167_DN, sizeof TA167_DN, (unsigned char *)TA167_RSA_N, sizeof TA167_RSA_N, (unsigned char *)TA167_RSA_E, sizeof TA167_RSA_E); + trust_anchors[168] = make_rsa_trust_anchor((unsigned char *)TA168_DN, sizeof TA168_DN, (unsigned char *)TA168_RSA_N, sizeof TA168_RSA_N, (unsigned char *)TA168_RSA_E, sizeof TA168_RSA_E); + trust_anchors[169] = make_rsa_trust_anchor((unsigned char *)TA169_DN, sizeof TA169_DN, (unsigned char *)TA169_RSA_N, sizeof TA169_RSA_N, (unsigned char *)TA169_RSA_E, sizeof TA169_RSA_E); + trust_anchors[170] = make_rsa_trust_anchor((unsigned char *)TA170_DN, sizeof TA170_DN, (unsigned char *)TA170_RSA_N, sizeof TA170_RSA_N, (unsigned char *)TA170_RSA_E, sizeof TA170_RSA_E); + trust_anchors[171] = make_ec_trust_anchor((unsigned char *)TA171_DN, sizeof TA171_DN, BR_EC_secp384r1, (unsigned char *)TA171_EC_Q, sizeof TA171_EC_Q); + trust_anchors[172] = make_rsa_trust_anchor((unsigned char *)TA172_DN, sizeof TA172_DN, (unsigned char *)TA172_RSA_N, sizeof TA172_RSA_N, (unsigned char *)TA172_RSA_E, sizeof TA172_RSA_E); + trust_anchors[173] = make_ec_trust_anchor((unsigned char *)TA173_DN, sizeof TA173_DN, BR_EC_secp256r1, (unsigned char *)TA173_EC_Q, sizeof TA173_EC_Q); + trust_anchors[174] = make_rsa_trust_anchor((unsigned char *)TA174_DN, sizeof TA174_DN, (unsigned char *)TA174_RSA_N, sizeof TA174_RSA_N, (unsigned char *)TA174_RSA_E, sizeof TA174_RSA_E); + trust_anchors[175] = make_ec_trust_anchor((unsigned char *)TA175_DN, sizeof TA175_DN, BR_EC_secp384r1, (unsigned char *)TA175_EC_Q, sizeof TA175_EC_Q); + trust_anchors[176] = make_rsa_trust_anchor((unsigned char *)TA176_DN, sizeof TA176_DN, (unsigned char *)TA176_RSA_N, sizeof TA176_RSA_N, (unsigned char *)TA176_RSA_E, sizeof TA176_RSA_E); + trust_anchors[177] = make_rsa_trust_anchor((unsigned char *)TA177_DN, sizeof TA177_DN, (unsigned char *)TA177_RSA_N, sizeof TA177_RSA_N, (unsigned char *)TA177_RSA_E, sizeof TA177_RSA_E); + trust_anchors[178] = make_ec_trust_anchor((unsigned char *)TA178_DN, sizeof TA178_DN, BR_EC_secp384r1, (unsigned char *)TA178_EC_Q, sizeof TA178_EC_Q); + trust_anchors[179] = make_rsa_trust_anchor((unsigned char *)TA179_DN, sizeof TA179_DN, (unsigned char *)TA179_RSA_N, sizeof TA179_RSA_N, (unsigned char *)TA179_RSA_E, sizeof TA179_RSA_E); + trust_anchors[180] = make_rsa_trust_anchor((unsigned char *)TA180_DN, sizeof TA180_DN, (unsigned char *)TA180_RSA_N, sizeof TA180_RSA_N, (unsigned char *)TA180_RSA_E, sizeof TA180_RSA_E); + trust_anchors[181] = make_rsa_trust_anchor((unsigned char *)TA181_DN, sizeof TA181_DN, (unsigned char *)TA181_RSA_N, sizeof TA181_RSA_N, (unsigned char *)TA181_RSA_E, sizeof TA181_RSA_E); + trust_anchors[182] = make_ec_trust_anchor((unsigned char *)TA182_DN, sizeof TA182_DN, BR_EC_secp384r1, (unsigned char *)TA182_EC_Q, sizeof TA182_EC_Q); + trust_anchors[183] = make_ec_trust_anchor((unsigned char *)TA183_DN, sizeof TA183_DN, BR_EC_secp384r1, (unsigned char *)TA183_EC_Q, sizeof TA183_EC_Q); + trust_anchors[184] = make_rsa_trust_anchor((unsigned char *)TA184_DN, sizeof TA184_DN, (unsigned char *)TA184_RSA_N, sizeof TA184_RSA_N, (unsigned char *)TA184_RSA_E, sizeof TA184_RSA_E); + trust_anchors[185] = make_rsa_trust_anchor((unsigned char *)TA185_DN, sizeof TA185_DN, (unsigned char *)TA185_RSA_N, sizeof TA185_RSA_N, (unsigned char *)TA185_RSA_E, sizeof TA185_RSA_E); + trust_anchors[186] = make_rsa_trust_anchor((unsigned char *)TA186_DN, sizeof TA186_DN, (unsigned char *)TA186_RSA_N, sizeof TA186_RSA_N, (unsigned char *)TA186_RSA_E, sizeof TA186_RSA_E); + trust_anchors[187] = make_rsa_trust_anchor((unsigned char *)TA187_DN, sizeof TA187_DN, (unsigned char *)TA187_RSA_N, sizeof TA187_RSA_N, (unsigned char *)TA187_RSA_E, sizeof TA187_RSA_E); + trust_anchors[188] = make_rsa_trust_anchor((unsigned char *)TA188_DN, sizeof TA188_DN, (unsigned char *)TA188_RSA_N, sizeof TA188_RSA_N, (unsigned char *)TA188_RSA_E, sizeof TA188_RSA_E); + trust_anchors[189] = make_rsa_trust_anchor((unsigned char *)TA189_DN, sizeof TA189_DN, (unsigned char *)TA189_RSA_N, sizeof TA189_RSA_N, (unsigned char *)TA189_RSA_E, sizeof TA189_RSA_E); + trust_anchors[190] = make_rsa_trust_anchor((unsigned char *)TA190_DN, sizeof TA190_DN, (unsigned char *)TA190_RSA_N, sizeof TA190_RSA_N, (unsigned char *)TA190_RSA_E, sizeof TA190_RSA_E); + trust_anchors[191] = make_ec_trust_anchor((unsigned char *)TA191_DN, sizeof TA191_DN, BR_EC_secp384r1, (unsigned char *)TA191_EC_Q, sizeof TA191_EC_Q); + trust_anchors[192] = make_rsa_trust_anchor((unsigned char *)TA192_DN, sizeof TA192_DN, (unsigned char *)TA192_RSA_N, sizeof TA192_RSA_N, (unsigned char *)TA192_RSA_E, sizeof TA192_RSA_E); + trust_anchors[193] = make_rsa_trust_anchor((unsigned char *)TA193_DN, sizeof TA193_DN, (unsigned char *)TA193_RSA_N, sizeof TA193_RSA_N, (unsigned char *)TA193_RSA_E, sizeof TA193_RSA_E); + trust_anchors[194] = make_rsa_trust_anchor((unsigned char *)TA194_DN, sizeof TA194_DN, (unsigned char *)TA194_RSA_N, sizeof TA194_RSA_N, (unsigned char *)TA194_RSA_E, sizeof TA194_RSA_E); + trust_anchors[195] = make_rsa_trust_anchor((unsigned char *)TA195_DN, sizeof TA195_DN, (unsigned char *)TA195_RSA_N, sizeof TA195_RSA_N, (unsigned char *)TA195_RSA_E, sizeof TA195_RSA_E); + trust_anchors[196] = make_ec_trust_anchor((unsigned char *)TA196_DN, sizeof TA196_DN, BR_EC_secp384r1, (unsigned char *)TA196_EC_Q, sizeof TA196_EC_Q); + trust_anchors[197] = make_rsa_trust_anchor((unsigned char *)TA197_DN, sizeof TA197_DN, (unsigned char *)TA197_RSA_N, sizeof TA197_RSA_N, (unsigned char *)TA197_RSA_E, sizeof TA197_RSA_E); + trust_anchors[198] = make_rsa_trust_anchor((unsigned char *)TA198_DN, sizeof TA198_DN, (unsigned char *)TA198_RSA_N, sizeof TA198_RSA_N, (unsigned char *)TA198_RSA_E, sizeof TA198_RSA_E); + trust_anchors[199] = make_rsa_trust_anchor((unsigned char *)TA199_DN, sizeof TA199_DN, (unsigned char *)TA199_RSA_N, sizeof TA199_RSA_N, (unsigned char *)TA199_RSA_E, sizeof TA199_RSA_E); + trust_anchors[200] = make_ec_trust_anchor((unsigned char *)TA200_DN, sizeof TA200_DN, BR_EC_secp256r1, (unsigned char *)TA200_EC_Q, sizeof TA200_EC_Q); + trust_anchors[201] = make_ec_trust_anchor((unsigned char *)TA201_DN, sizeof TA201_DN, BR_EC_secp384r1, (unsigned char *)TA201_EC_Q, sizeof TA201_EC_Q); + trust_anchors[202] = make_rsa_trust_anchor((unsigned char *)TA202_DN, sizeof TA202_DN, (unsigned char *)TA202_RSA_N, sizeof TA202_RSA_N, (unsigned char *)TA202_RSA_E, sizeof TA202_RSA_E); + trust_anchors[203] = make_rsa_trust_anchor((unsigned char *)TA203_DN, sizeof TA203_DN, (unsigned char *)TA203_RSA_N, sizeof TA203_RSA_N, (unsigned char *)TA203_RSA_E, sizeof TA203_RSA_E); + trust_anchors[204] = make_ec_trust_anchor((unsigned char *)TA204_DN, sizeof TA204_DN, BR_EC_secp384r1, (unsigned char *)TA204_EC_Q, sizeof TA204_EC_Q); + trust_anchors[205] = make_rsa_trust_anchor((unsigned char *)TA205_DN, sizeof TA205_DN, (unsigned char *)TA205_RSA_N, sizeof TA205_RSA_N, (unsigned char *)TA205_RSA_E, sizeof TA205_RSA_E); + trust_anchors[206] = make_rsa_trust_anchor((unsigned char *)TA206_DN, sizeof TA206_DN, (unsigned char *)TA206_RSA_N, sizeof TA206_RSA_N, (unsigned char *)TA206_RSA_E, sizeof TA206_RSA_E); + trust_anchors[207] = make_ec_trust_anchor((unsigned char *)TA207_DN, sizeof TA207_DN, BR_EC_secp256r1, (unsigned char *)TA207_EC_Q, sizeof TA207_EC_Q); + trust_anchors[208] = make_rsa_trust_anchor((unsigned char *)TA208_DN, sizeof TA208_DN, (unsigned char *)TA208_RSA_N, sizeof TA208_RSA_N, (unsigned char *)TA208_RSA_E, sizeof TA208_RSA_E); + trust_anchors[209] = make_rsa_trust_anchor((unsigned char *)TA209_DN, sizeof TA209_DN, (unsigned char *)TA209_RSA_N, sizeof TA209_RSA_N, (unsigned char *)TA209_RSA_E, sizeof TA209_RSA_E); + trust_anchors[210] = make_rsa_trust_anchor((unsigned char *)TA210_DN, sizeof TA210_DN, (unsigned char *)TA210_RSA_N, sizeof TA210_RSA_N, (unsigned char *)TA210_RSA_E, sizeof TA210_RSA_E); + trust_anchors[211] = make_ec_trust_anchor((unsigned char *)TA211_DN, sizeof TA211_DN, BR_EC_secp384r1, (unsigned char *)TA211_EC_Q, sizeof TA211_EC_Q); + trust_anchors[212] = make_ec_trust_anchor((unsigned char *)TA212_DN, sizeof TA212_DN, BR_EC_secp384r1, (unsigned char *)TA212_EC_Q, sizeof TA212_EC_Q); + trust_anchors[213] = make_rsa_trust_anchor((unsigned char *)TA213_DN, sizeof TA213_DN, (unsigned char *)TA213_RSA_N, sizeof TA213_RSA_N, (unsigned char *)TA213_RSA_E, sizeof TA213_RSA_E); + trust_anchors[214] = make_rsa_trust_anchor((unsigned char *)TA214_DN, sizeof TA214_DN, (unsigned char *)TA214_RSA_N, sizeof TA214_RSA_N, (unsigned char *)TA214_RSA_E, sizeof TA214_RSA_E); + trust_anchors[215] = make_rsa_trust_anchor((unsigned char *)TA215_DN, sizeof TA215_DN, (unsigned char *)TA215_RSA_N, sizeof TA215_RSA_N, (unsigned char *)TA215_RSA_E, sizeof TA215_RSA_E); + trust_anchors[216] = make_ec_trust_anchor((unsigned char *)TA216_DN, sizeof TA216_DN, BR_EC_secp256r1, (unsigned char *)TA216_EC_Q, sizeof TA216_EC_Q); + trust_anchors[217] = make_rsa_trust_anchor((unsigned char *)TA217_DN, sizeof TA217_DN, (unsigned char *)TA217_RSA_N, sizeof TA217_RSA_N, (unsigned char *)TA217_RSA_E, sizeof TA217_RSA_E); + trust_anchors[218] = make_rsa_trust_anchor((unsigned char *)TA218_DN, sizeof TA218_DN, (unsigned char *)TA218_RSA_N, sizeof TA218_RSA_N, (unsigned char *)TA218_RSA_E, sizeof TA218_RSA_E); + trust_anchors[219] = make_ec_trust_anchor((unsigned char *)TA219_DN, sizeof TA219_DN, BR_EC_secp384r1, (unsigned char *)TA219_EC_Q, sizeof TA219_EC_Q); + trust_anchors[220] = make_rsa_trust_anchor((unsigned char *)TA220_DN, sizeof TA220_DN, (unsigned char *)TA220_RSA_N, sizeof TA220_RSA_N, (unsigned char *)TA220_RSA_E, sizeof TA220_RSA_E); + trust_anchors[221] = make_rsa_trust_anchor((unsigned char *)TA221_DN, sizeof TA221_DN, (unsigned char *)TA221_RSA_N, sizeof TA221_RSA_N, (unsigned char *)TA221_RSA_E, sizeof TA221_RSA_E); + trust_anchors[222] = make_rsa_trust_anchor((unsigned char *)TA222_DN, sizeof TA222_DN, (unsigned char *)TA222_RSA_N, sizeof TA222_RSA_N, (unsigned char *)TA222_RSA_E, sizeof TA222_RSA_E); + trust_anchors[223] = make_rsa_trust_anchor((unsigned char *)TA223_DN, sizeof TA223_DN, (unsigned char *)TA223_RSA_N, sizeof TA223_RSA_N, (unsigned char *)TA223_RSA_E, sizeof TA223_RSA_E); + trust_anchors[224] = make_ec_trust_anchor((unsigned char *)TA224_DN, sizeof TA224_DN, BR_EC_secp384r1, (unsigned char *)TA224_EC_Q, sizeof TA224_EC_Q); + trust_anchors[225] = make_rsa_trust_anchor((unsigned char *)TA225_DN, sizeof TA225_DN, (unsigned char *)TA225_RSA_N, sizeof TA225_RSA_N, (unsigned char *)TA225_RSA_E, sizeof TA225_RSA_E); + trust_anchors[226] = make_rsa_trust_anchor((unsigned char *)TA226_DN, sizeof TA226_DN, (unsigned char *)TA226_RSA_N, sizeof TA226_RSA_N, (unsigned char *)TA226_RSA_E, sizeof TA226_RSA_E); + trust_anchors[227] = make_rsa_trust_anchor((unsigned char *)TA227_DN, sizeof TA227_DN, (unsigned char *)TA227_RSA_N, sizeof TA227_RSA_N, (unsigned char *)TA227_RSA_E, sizeof TA227_RSA_E); + trust_anchors[228] = make_rsa_trust_anchor((unsigned char *)TA228_DN, sizeof TA228_DN, (unsigned char *)TA228_RSA_N, sizeof TA228_RSA_N, (unsigned char *)TA228_RSA_E, sizeof TA228_RSA_E); + trust_anchors[229] = make_rsa_trust_anchor((unsigned char *)TA229_DN, sizeof TA229_DN, (unsigned char *)TA229_RSA_N, sizeof TA229_RSA_N, (unsigned char *)TA229_RSA_E, sizeof TA229_RSA_E); + trust_anchors[230] = make_rsa_trust_anchor((unsigned char *)TA230_DN, sizeof TA230_DN, (unsigned char *)TA230_RSA_N, sizeof TA230_RSA_N, (unsigned char *)TA230_RSA_E, sizeof TA230_RSA_E); + trust_anchors[231] = make_rsa_trust_anchor((unsigned char *)TA231_DN, sizeof TA231_DN, (unsigned char *)TA231_RSA_N, sizeof TA231_RSA_N, (unsigned char *)TA231_RSA_E, sizeof TA231_RSA_E); + trust_anchors[232] = make_ec_trust_anchor((unsigned char *)TA232_DN, sizeof TA232_DN, BR_EC_secp384r1, (unsigned char *)TA232_EC_Q, sizeof TA232_EC_Q); + trust_anchors[233] = make_rsa_trust_anchor((unsigned char *)TA233_DN, sizeof TA233_DN, (unsigned char *)TA233_RSA_N, sizeof TA233_RSA_N, (unsigned char *)TA233_RSA_E, sizeof TA233_RSA_E); + trust_anchors[234] = make_rsa_trust_anchor((unsigned char *)TA234_DN, sizeof TA234_DN, (unsigned char *)TA234_RSA_N, sizeof TA234_RSA_N, (unsigned char *)TA234_RSA_E, sizeof TA234_RSA_E); + trust_anchors[235] = make_rsa_trust_anchor((unsigned char *)TA235_DN, sizeof TA235_DN, (unsigned char *)TA235_RSA_N, sizeof TA235_RSA_N, (unsigned char *)TA235_RSA_E, sizeof TA235_RSA_E); + trust_anchors[236] = make_rsa_trust_anchor((unsigned char *)TA236_DN, sizeof TA236_DN, (unsigned char *)TA236_RSA_N, sizeof TA236_RSA_N, (unsigned char *)TA236_RSA_E, sizeof TA236_RSA_E); + trust_anchors[237] = make_rsa_trust_anchor((unsigned char *)TA237_DN, sizeof TA237_DN, (unsigned char *)TA237_RSA_N, sizeof TA237_RSA_N, (unsigned char *)TA237_RSA_E, sizeof TA237_RSA_E); + trust_anchors[238] = make_ec_trust_anchor((unsigned char *)TA238_DN, sizeof TA238_DN, BR_EC_secp384r1, (unsigned char *)TA238_EC_Q, sizeof TA238_EC_Q); + trust_anchors[239] = make_rsa_trust_anchor((unsigned char *)TA239_DN, sizeof TA239_DN, (unsigned char *)TA239_RSA_N, sizeof TA239_RSA_N, (unsigned char *)TA239_RSA_E, sizeof TA239_RSA_E); + trust_anchors[240] = make_ec_trust_anchor((unsigned char *)TA240_DN, sizeof TA240_DN, BR_EC_secp384r1, (unsigned char *)TA240_EC_Q, sizeof TA240_EC_Q); + trust_anchors[241] = make_rsa_trust_anchor((unsigned char *)TA241_DN, sizeof TA241_DN, (unsigned char *)TA241_RSA_N, sizeof TA241_RSA_N, (unsigned char *)TA241_RSA_E, sizeof TA241_RSA_E); + trust_anchors[242] = make_rsa_trust_anchor((unsigned char *)TA242_DN, sizeof TA242_DN, (unsigned char *)TA242_RSA_N, sizeof TA242_RSA_N, (unsigned char *)TA242_RSA_E, sizeof TA242_RSA_E); + trust_anchors[243] = make_rsa_trust_anchor((unsigned char *)TA243_DN, sizeof TA243_DN, (unsigned char *)TA243_RSA_N, sizeof TA243_RSA_N, (unsigned char *)TA243_RSA_E, sizeof TA243_RSA_E); + trust_anchors[244] = make_rsa_trust_anchor((unsigned char *)TA244_DN, sizeof TA244_DN, (unsigned char *)TA244_RSA_N, sizeof TA244_RSA_N, (unsigned char *)TA244_RSA_E, sizeof TA244_RSA_E); + trust_anchors[245] = make_ec_trust_anchor((unsigned char *)TA245_DN, sizeof TA245_DN, BR_EC_secp384r1, (unsigned char *)TA245_EC_Q, sizeof TA245_EC_Q); + trust_anchors[246] = make_rsa_trust_anchor((unsigned char *)TA246_DN, sizeof TA246_DN, (unsigned char *)TA246_RSA_N, sizeof TA246_RSA_N, (unsigned char *)TA246_RSA_E, sizeof TA246_RSA_E); + trust_anchors[247] = make_rsa_trust_anchor((unsigned char *)TA247_DN, sizeof TA247_DN, (unsigned char *)TA247_RSA_N, sizeof TA247_RSA_N, (unsigned char *)TA247_RSA_E, sizeof TA247_RSA_E); + trust_anchors[248] = make_rsa_trust_anchor((unsigned char *)TA248_DN, sizeof TA248_DN, (unsigned char *)TA248_RSA_N, sizeof TA248_RSA_N, (unsigned char *)TA248_RSA_E, sizeof TA248_RSA_E); + trust_anchors[249] = make_rsa_trust_anchor((unsigned char *)TA249_DN, sizeof TA249_DN, (unsigned char *)TA249_RSA_N, sizeof TA249_RSA_N, (unsigned char *)TA249_RSA_E, sizeof TA249_RSA_E); + trust_anchors[250] = make_rsa_trust_anchor((unsigned char *)TA250_DN, sizeof TA250_DN, (unsigned char *)TA250_RSA_N, sizeof TA250_RSA_N, (unsigned char *)TA250_RSA_E, sizeof TA250_RSA_E); + trust_anchors[251] = make_ec_trust_anchor((unsigned char *)TA251_DN, sizeof TA251_DN, BR_EC_secp384r1, (unsigned char *)TA251_EC_Q, sizeof TA251_EC_Q); + trust_anchors[252] = make_rsa_trust_anchor((unsigned char *)TA252_DN, sizeof TA252_DN, (unsigned char *)TA252_RSA_N, sizeof TA252_RSA_N, (unsigned char *)TA252_RSA_E, sizeof TA252_RSA_E); + trust_anchors[253] = make_rsa_trust_anchor((unsigned char *)TA253_DN, sizeof TA253_DN, (unsigned char *)TA253_RSA_N, sizeof TA253_RSA_N, (unsigned char *)TA253_RSA_E, sizeof TA253_RSA_E); + trust_anchors[254] = make_ec_trust_anchor((unsigned char *)TA254_DN, sizeof TA254_DN, BR_EC_secp256r1, (unsigned char *)TA254_EC_Q, sizeof TA254_EC_Q); + trust_anchors[255] = make_ec_trust_anchor((unsigned char *)TA255_DN, sizeof TA255_DN, BR_EC_secp384r1, (unsigned char *)TA255_EC_Q, sizeof TA255_EC_Q); + trust_anchors[256] = make_rsa_trust_anchor((unsigned char *)TA256_DN, sizeof TA256_DN, (unsigned char *)TA256_RSA_N, sizeof TA256_RSA_N, (unsigned char *)TA256_RSA_E, sizeof TA256_RSA_E); + trust_anchors[257] = make_ec_trust_anchor((unsigned char *)TA257_DN, sizeof TA257_DN, BR_EC_secp384r1, (unsigned char *)TA257_EC_Q, sizeof TA257_EC_Q); + trust_anchors[258] = make_rsa_trust_anchor((unsigned char *)TA258_DN, sizeof TA258_DN, (unsigned char *)TA258_RSA_N, sizeof TA258_RSA_N, (unsigned char *)TA258_RSA_E, sizeof TA258_RSA_E); + trust_anchors[259] = make_rsa_trust_anchor((unsigned char *)TA259_DN, sizeof TA259_DN, (unsigned char *)TA259_RSA_N, sizeof TA259_RSA_N, (unsigned char *)TA259_RSA_E, sizeof TA259_RSA_E); + trust_anchors[260] = make_rsa_trust_anchor((unsigned char *)TA260_DN, sizeof TA260_DN, (unsigned char *)TA260_RSA_N, sizeof TA260_RSA_N, (unsigned char *)TA260_RSA_E, sizeof TA260_RSA_E); + trust_anchors[261] = make_ec_trust_anchor((unsigned char *)TA261_DN, sizeof TA261_DN, BR_EC_secp384r1, (unsigned char *)TA261_EC_Q, sizeof TA261_EC_Q); + trust_anchors[262] = make_rsa_trust_anchor((unsigned char *)TA262_DN, sizeof TA262_DN, (unsigned char *)TA262_RSA_N, sizeof TA262_RSA_N, (unsigned char *)TA262_RSA_E, sizeof TA262_RSA_E); + trust_anchors[263] = make_rsa_trust_anchor((unsigned char *)TA263_DN, sizeof TA263_DN, (unsigned char *)TA263_RSA_N, sizeof TA263_RSA_N, (unsigned char *)TA263_RSA_E, sizeof TA263_RSA_E); + trust_anchors[264] = make_rsa_trust_anchor((unsigned char *)TA264_DN, sizeof TA264_DN, (unsigned char *)TA264_RSA_N, sizeof TA264_RSA_N, (unsigned char *)TA264_RSA_E, sizeof TA264_RSA_E); + trust_anchors[265] = make_rsa_trust_anchor((unsigned char *)TA265_DN, sizeof TA265_DN, (unsigned char *)TA265_RSA_N, sizeof TA265_RSA_N, (unsigned char *)TA265_RSA_E, sizeof TA265_RSA_E); + trust_anchors[266] = make_rsa_trust_anchor((unsigned char *)TA266_DN, sizeof TA266_DN, (unsigned char *)TA266_RSA_N, sizeof TA266_RSA_N, (unsigned char *)TA266_RSA_E, sizeof TA266_RSA_E); + trust_anchors[267] = make_rsa_trust_anchor((unsigned char *)TA267_DN, sizeof TA267_DN, (unsigned char *)TA267_RSA_N, sizeof TA267_RSA_N, (unsigned char *)TA267_RSA_E, sizeof TA267_RSA_E); + trust_anchors[268] = make_ec_trust_anchor((unsigned char *)TA268_DN, sizeof TA268_DN, BR_EC_secp384r1, (unsigned char *)TA268_EC_Q, sizeof TA268_EC_Q); + trust_anchors[269] = make_rsa_trust_anchor((unsigned char *)TA269_DN, sizeof TA269_DN, (unsigned char *)TA269_RSA_N, sizeof TA269_RSA_N, (unsigned char *)TA269_RSA_E, sizeof TA269_RSA_E); + trust_anchors[270] = make_ec_trust_anchor((unsigned char *)TA270_DN, sizeof TA270_DN, BR_EC_secp384r1, (unsigned char *)TA270_EC_Q, sizeof TA270_EC_Q); + trust_anchors[271] = make_rsa_trust_anchor((unsigned char *)TA271_DN, sizeof TA271_DN, (unsigned char *)TA271_RSA_N, sizeof TA271_RSA_N, (unsigned char *)TA271_RSA_E, sizeof TA271_RSA_E); + trust_anchors[272] = make_rsa_trust_anchor((unsigned char *)TA272_DN, sizeof TA272_DN, (unsigned char *)TA272_RSA_N, sizeof TA272_RSA_N, (unsigned char *)TA272_RSA_E, sizeof TA272_RSA_E); + trust_anchors[273] = make_rsa_trust_anchor((unsigned char *)TA273_DN, sizeof TA273_DN, (unsigned char *)TA273_RSA_N, sizeof TA273_RSA_N, (unsigned char *)TA273_RSA_E, sizeof TA273_RSA_E); + trust_anchors[274] = make_ec_trust_anchor((unsigned char *)TA274_DN, sizeof TA274_DN, BR_EC_secp384r1, (unsigned char *)TA274_EC_Q, sizeof TA274_EC_Q); + trust_anchors[275] = make_rsa_trust_anchor((unsigned char *)TA275_DN, sizeof TA275_DN, (unsigned char *)TA275_RSA_N, sizeof TA275_RSA_N, (unsigned char *)TA275_RSA_E, sizeof TA275_RSA_E); + trust_anchors[276] = make_rsa_trust_anchor((unsigned char *)TA276_DN, sizeof TA276_DN, (unsigned char *)TA276_RSA_N, sizeof TA276_RSA_N, (unsigned char *)TA276_RSA_E, sizeof TA276_RSA_E); + trust_anchors[277] = make_rsa_trust_anchor((unsigned char *)TA277_DN, sizeof TA277_DN, (unsigned char *)TA277_RSA_N, sizeof TA277_RSA_N, (unsigned char *)TA277_RSA_E, sizeof TA277_RSA_E); + trust_anchors[278] = make_ec_trust_anchor((unsigned char *)TA278_DN, sizeof TA278_DN, BR_EC_secp384r1, (unsigned char *)TA278_EC_Q, sizeof TA278_EC_Q); + trust_anchors[279] = make_ec_trust_anchor((unsigned char *)TA279_DN, sizeof TA279_DN, BR_EC_secp384r1, (unsigned char *)TA279_EC_Q, sizeof TA279_EC_Q); + trust_anchors[280] = make_rsa_trust_anchor((unsigned char *)TA280_DN, sizeof TA280_DN, (unsigned char *)TA280_RSA_N, sizeof TA280_RSA_N, (unsigned char *)TA280_RSA_E, sizeof TA280_RSA_E); + trust_anchors[281] = make_rsa_trust_anchor((unsigned char *)TA281_DN, sizeof TA281_DN, (unsigned char *)TA281_RSA_N, sizeof TA281_RSA_N, (unsigned char *)TA281_RSA_E, sizeof TA281_RSA_E); + trust_anchors[282] = make_rsa_trust_anchor((unsigned char *)TA282_DN, sizeof TA282_DN, (unsigned char *)TA282_RSA_N, sizeof TA282_RSA_N, (unsigned char *)TA282_RSA_E, sizeof TA282_RSA_E); + trust_anchors[283] = make_ec_trust_anchor((unsigned char *)TA283_DN, sizeof TA283_DN, BR_EC_secp384r1, (unsigned char *)TA283_EC_Q, sizeof TA283_EC_Q); + trust_anchors[284] = make_rsa_trust_anchor((unsigned char *)TA284_DN, sizeof TA284_DN, (unsigned char *)TA284_RSA_N, sizeof TA284_RSA_N, (unsigned char *)TA284_RSA_E, sizeof TA284_RSA_E); + trust_anchors[285] = make_ec_trust_anchor((unsigned char *)TA285_DN, sizeof TA285_DN, BR_EC_secp384r1, (unsigned char *)TA285_EC_Q, sizeof TA285_EC_Q); + trust_anchors[286] = make_rsa_trust_anchor((unsigned char *)TA286_DN, sizeof TA286_DN, (unsigned char *)TA286_RSA_N, sizeof TA286_RSA_N, (unsigned char *)TA286_RSA_E, sizeof TA286_RSA_E); + trust_anchors[287] = make_rsa_trust_anchor((unsigned char *)TA287_DN, sizeof TA287_DN, (unsigned char *)TA287_RSA_N, sizeof TA287_RSA_N, (unsigned char *)TA287_RSA_E, sizeof TA287_RSA_E); + trust_anchors[288] = make_rsa_trust_anchor((unsigned char *)TA288_DN, sizeof TA288_DN, (unsigned char *)TA288_RSA_N, sizeof TA288_RSA_N, (unsigned char *)TA288_RSA_E, sizeof TA288_RSA_E); + trust_anchors[289] = make_rsa_trust_anchor((unsigned char *)TA289_DN, sizeof TA289_DN, (unsigned char *)TA289_RSA_N, sizeof TA289_RSA_N, (unsigned char *)TA289_RSA_E, sizeof TA289_RSA_E); + trust_anchors[290] = make_rsa_trust_anchor((unsigned char *)TA290_DN, sizeof TA290_DN, (unsigned char *)TA290_RSA_N, sizeof TA290_RSA_N, (unsigned char *)TA290_RSA_E, sizeof TA290_RSA_E); + trust_anchors[291] = make_ec_trust_anchor((unsigned char *)TA291_DN, sizeof TA291_DN, BR_EC_secp384r1, (unsigned char *)TA291_EC_Q, sizeof TA291_EC_Q); + trust_anchors[292] = make_rsa_trust_anchor((unsigned char *)TA292_DN, sizeof TA292_DN, (unsigned char *)TA292_RSA_N, sizeof TA292_RSA_N, (unsigned char *)TA292_RSA_E, sizeof TA292_RSA_E); + trust_anchors[293] = make_rsa_trust_anchor((unsigned char *)TA293_DN, sizeof TA293_DN, (unsigned char *)TA293_RSA_N, sizeof TA293_RSA_N, (unsigned char *)TA293_RSA_E, sizeof TA293_RSA_E); + trust_anchors[294] = make_ec_trust_anchor((unsigned char *)TA294_DN, sizeof TA294_DN, BR_EC_secp384r1, (unsigned char *)TA294_EC_Q, sizeof TA294_EC_Q); + trust_anchors[295] = make_rsa_trust_anchor((unsigned char *)TA295_DN, sizeof TA295_DN, (unsigned char *)TA295_RSA_N, sizeof TA295_RSA_N, (unsigned char *)TA295_RSA_E, sizeof TA295_RSA_E); + trust_anchors[296] = make_ec_trust_anchor((unsigned char *)TA296_DN, sizeof TA296_DN, BR_EC_secp384r1, (unsigned char *)TA296_EC_Q, sizeof TA296_EC_Q); + trust_anchors[297] = make_rsa_trust_anchor((unsigned char *)TA297_DN, sizeof TA297_DN, (unsigned char *)TA297_RSA_N, sizeof TA297_RSA_N, (unsigned char *)TA297_RSA_E, sizeof TA297_RSA_E); + trust_anchors[298] = make_rsa_trust_anchor((unsigned char *)TA298_DN, sizeof TA298_DN, (unsigned char *)TA298_RSA_N, sizeof TA298_RSA_N, (unsigned char *)TA298_RSA_E, sizeof TA298_RSA_E); + trust_anchors[299] = make_rsa_trust_anchor((unsigned char *)TA299_DN, sizeof TA299_DN, (unsigned char *)TA299_RSA_N, sizeof TA299_RSA_N, (unsigned char *)TA299_RSA_E, sizeof TA299_RSA_E); + trust_anchors[300] = make_rsa_trust_anchor((unsigned char *)TA300_DN, sizeof TA300_DN, (unsigned char *)TA300_RSA_N, sizeof TA300_RSA_N, (unsigned char *)TA300_RSA_E, sizeof TA300_RSA_E); + trust_anchors[301] = make_ec_trust_anchor((unsigned char *)TA301_DN, sizeof TA301_DN, BR_EC_secp384r1, (unsigned char *)TA301_EC_Q, sizeof TA301_EC_Q); + trust_anchors[302] = make_rsa_trust_anchor((unsigned char *)TA302_DN, sizeof TA302_DN, (unsigned char *)TA302_RSA_N, sizeof TA302_RSA_N, (unsigned char *)TA302_RSA_E, sizeof TA302_RSA_E); + trust_anchors[303] = make_ec_trust_anchor((unsigned char *)TA303_DN, sizeof TA303_DN, BR_EC_secp384r1, (unsigned char *)TA303_EC_Q, sizeof TA303_EC_Q); + trust_anchors[304] = make_rsa_trust_anchor((unsigned char *)TA304_DN, sizeof TA304_DN, (unsigned char *)TA304_RSA_N, sizeof TA304_RSA_N, (unsigned char *)TA304_RSA_E, sizeof TA304_RSA_E); + trust_anchors[305] = make_rsa_trust_anchor((unsigned char *)TA305_DN, sizeof TA305_DN, (unsigned char *)TA305_RSA_N, sizeof TA305_RSA_N, (unsigned char *)TA305_RSA_E, sizeof TA305_RSA_E); + trust_anchors[306] = make_rsa_trust_anchor((unsigned char *)TA306_DN, sizeof TA306_DN, (unsigned char *)TA306_RSA_N, sizeof TA306_RSA_N, (unsigned char *)TA306_RSA_E, sizeof TA306_RSA_E); + trust_anchors[307] = make_rsa_trust_anchor((unsigned char *)TA307_DN, sizeof TA307_DN, (unsigned char *)TA307_RSA_N, sizeof TA307_RSA_N, (unsigned char *)TA307_RSA_E, sizeof TA307_RSA_E); + trust_anchors[308] = make_ec_trust_anchor((unsigned char *)TA308_DN, sizeof TA308_DN, BR_EC_secp384r1, (unsigned char *)TA308_EC_Q, sizeof TA308_EC_Q); + trust_anchors[309] = make_ec_trust_anchor((unsigned char *)TA309_DN, sizeof TA309_DN, BR_EC_secp384r1, (unsigned char *)TA309_EC_Q, sizeof TA309_EC_Q); + trust_anchors[310] = make_ec_trust_anchor((unsigned char *)TA310_DN, sizeof TA310_DN, BR_EC_secp256r1, (unsigned char *)TA310_EC_Q, sizeof TA310_EC_Q); + trust_anchors[311] = make_ec_trust_anchor((unsigned char *)TA311_DN, sizeof TA311_DN, BR_EC_secp384r1, (unsigned char *)TA311_EC_Q, sizeof TA311_EC_Q); + trust_anchors[312] = make_rsa_trust_anchor((unsigned char *)TA312_DN, sizeof TA312_DN, (unsigned char *)TA312_RSA_N, sizeof TA312_RSA_N, (unsigned char *)TA312_RSA_E, sizeof TA312_RSA_E); + trust_anchors[313] = make_rsa_trust_anchor((unsigned char *)TA313_DN, sizeof TA313_DN, (unsigned char *)TA313_RSA_N, sizeof TA313_RSA_N, (unsigned char *)TA313_RSA_E, sizeof TA313_RSA_E); + trust_anchors[314] = make_rsa_trust_anchor((unsigned char *)TA314_DN, sizeof TA314_DN, (unsigned char *)TA314_RSA_N, sizeof TA314_RSA_N, (unsigned char *)TA314_RSA_E, sizeof TA314_RSA_E); + trust_anchors[315] = make_ec_trust_anchor((unsigned char *)TA315_DN, sizeof TA315_DN, BR_EC_secp384r1, (unsigned char *)TA315_EC_Q, sizeof TA315_EC_Q); + trust_anchors[316] = make_rsa_trust_anchor((unsigned char *)TA316_DN, sizeof TA316_DN, (unsigned char *)TA316_RSA_N, sizeof TA316_RSA_N, (unsigned char *)TA316_RSA_E, sizeof TA316_RSA_E); + trust_anchors[317] = make_rsa_trust_anchor((unsigned char *)TA317_DN, sizeof TA317_DN, (unsigned char *)TA317_RSA_N, sizeof TA317_RSA_N, (unsigned char *)TA317_RSA_E, sizeof TA317_RSA_E); + trust_anchors[318] = make_rsa_trust_anchor((unsigned char *)TA318_DN, sizeof TA318_DN, (unsigned char *)TA318_RSA_N, sizeof TA318_RSA_N, (unsigned char *)TA318_RSA_E, sizeof TA318_RSA_E); + trust_anchors[319] = make_ec_trust_anchor((unsigned char *)TA319_DN, sizeof TA319_DN, BR_EC_secp384r1, (unsigned char *)TA319_EC_Q, sizeof TA319_EC_Q); + trust_anchors[320] = make_rsa_trust_anchor((unsigned char *)TA320_DN, sizeof TA320_DN, (unsigned char *)TA320_RSA_N, sizeof TA320_RSA_N, (unsigned char *)TA320_RSA_E, sizeof TA320_RSA_E); + trust_anchors[321] = make_ec_trust_anchor((unsigned char *)TA321_DN, sizeof TA321_DN, BR_EC_secp384r1, (unsigned char *)TA321_EC_Q, sizeof TA321_EC_Q); + trust_anchors[322] = make_rsa_trust_anchor((unsigned char *)TA322_DN, sizeof TA322_DN, (unsigned char *)TA322_RSA_N, sizeof TA322_RSA_N, (unsigned char *)TA322_RSA_E, sizeof TA322_RSA_E); + trust_anchors[323] = make_rsa_trust_anchor((unsigned char *)TA323_DN, sizeof TA323_DN, (unsigned char *)TA323_RSA_N, sizeof TA323_RSA_N, (unsigned char *)TA323_RSA_E, sizeof TA323_RSA_E); + trust_anchors[324] = make_rsa_trust_anchor((unsigned char *)TA324_DN, sizeof TA324_DN, (unsigned char *)TA324_RSA_N, sizeof TA324_RSA_N, (unsigned char *)TA324_RSA_E, sizeof TA324_RSA_E); + trust_anchors[325] = make_rsa_trust_anchor((unsigned char *)TA325_DN, sizeof TA325_DN, (unsigned char *)TA325_RSA_N, sizeof TA325_RSA_N, (unsigned char *)TA325_RSA_E, sizeof TA325_RSA_E); + trust_anchors[326] = make_ec_trust_anchor((unsigned char *)TA326_DN, sizeof TA326_DN, BR_EC_secp384r1, (unsigned char *)TA326_EC_Q, sizeof TA326_EC_Q); + trust_anchors[327] = make_rsa_trust_anchor((unsigned char *)TA327_DN, sizeof TA327_DN, (unsigned char *)TA327_RSA_N, sizeof TA327_RSA_N, (unsigned char *)TA327_RSA_E, sizeof TA327_RSA_E); + trust_anchors[328] = make_rsa_trust_anchor((unsigned char *)TA328_DN, sizeof TA328_DN, (unsigned char *)TA328_RSA_N, sizeof TA328_RSA_N, (unsigned char *)TA328_RSA_E, sizeof TA328_RSA_E); + trust_anchors[329] = make_rsa_trust_anchor((unsigned char *)TA329_DN, sizeof TA329_DN, (unsigned char *)TA329_RSA_N, sizeof TA329_RSA_N, (unsigned char *)TA329_RSA_E, sizeof TA329_RSA_E); + trust_anchors[330] = make_rsa_trust_anchor((unsigned char *)TA330_DN, sizeof TA330_DN, (unsigned char *)TA330_RSA_N, sizeof TA330_RSA_N, (unsigned char *)TA330_RSA_E, sizeof TA330_RSA_E); + trust_anchors[331] = make_ec_trust_anchor((unsigned char *)TA331_DN, sizeof TA331_DN, BR_EC_secp384r1, (unsigned char *)TA331_EC_Q, sizeof TA331_EC_Q); + trust_anchors[332] = make_rsa_trust_anchor((unsigned char *)TA332_DN, sizeof TA332_DN, (unsigned char *)TA332_RSA_N, sizeof TA332_RSA_N, (unsigned char *)TA332_RSA_E, sizeof TA332_RSA_E); + trust_anchors[333] = make_rsa_trust_anchor((unsigned char *)TA333_DN, sizeof TA333_DN, (unsigned char *)TA333_RSA_N, sizeof TA333_RSA_N, (unsigned char *)TA333_RSA_E, sizeof TA333_RSA_E); + trust_anchors[334] = make_rsa_trust_anchor((unsigned char *)TA334_DN, sizeof TA334_DN, (unsigned char *)TA334_RSA_N, sizeof TA334_RSA_N, (unsigned char *)TA334_RSA_E, sizeof TA334_RSA_E); + trust_anchors[335] = make_rsa_trust_anchor((unsigned char *)TA335_DN, sizeof TA335_DN, (unsigned char *)TA335_RSA_N, sizeof TA335_RSA_N, (unsigned char *)TA335_RSA_E, sizeof TA335_RSA_E); + trust_anchors[336] = make_ec_trust_anchor((unsigned char *)TA336_DN, sizeof TA336_DN, BR_EC_secp384r1, (unsigned char *)TA336_EC_Q, sizeof TA336_EC_Q); + trust_anchors[337] = make_rsa_trust_anchor((unsigned char *)TA337_DN, sizeof TA337_DN, (unsigned char *)TA337_RSA_N, sizeof TA337_RSA_N, (unsigned char *)TA337_RSA_E, sizeof TA337_RSA_E); + trust_anchors[338] = make_rsa_trust_anchor((unsigned char *)TA338_DN, sizeof TA338_DN, (unsigned char *)TA338_RSA_N, sizeof TA338_RSA_N, (unsigned char *)TA338_RSA_E, sizeof TA338_RSA_E); + trust_anchors[339] = make_rsa_trust_anchor((unsigned char *)TA339_DN, sizeof TA339_DN, (unsigned char *)TA339_RSA_N, sizeof TA339_RSA_N, (unsigned char *)TA339_RSA_E, sizeof TA339_RSA_E); + trust_anchors[340] = make_rsa_trust_anchor((unsigned char *)TA340_DN, sizeof TA340_DN, (unsigned char *)TA340_RSA_N, sizeof TA340_RSA_N, (unsigned char *)TA340_RSA_E, sizeof TA340_RSA_E); + trust_anchors[341] = make_rsa_trust_anchor((unsigned char *)TA341_DN, sizeof TA341_DN, (unsigned char *)TA341_RSA_N, sizeof TA341_RSA_N, (unsigned char *)TA341_RSA_E, sizeof TA341_RSA_E); + trust_anchors[342] = make_ec_trust_anchor((unsigned char *)TA342_DN, sizeof TA342_DN, BR_EC_secp384r1, (unsigned char *)TA342_EC_Q, sizeof TA342_EC_Q); + trust_anchors[343] = make_rsa_trust_anchor((unsigned char *)TA343_DN, sizeof TA343_DN, (unsigned char *)TA343_RSA_N, sizeof TA343_RSA_N, (unsigned char *)TA343_RSA_E, sizeof TA343_RSA_E); + trust_anchors[344] = make_ec_trust_anchor((unsigned char *)TA344_DN, sizeof TA344_DN, BR_EC_secp384r1, (unsigned char *)TA344_EC_Q, sizeof TA344_EC_Q); + trust_anchors[345] = make_rsa_trust_anchor((unsigned char *)TA345_DN, sizeof TA345_DN, (unsigned char *)TA345_RSA_N, sizeof TA345_RSA_N, (unsigned char *)TA345_RSA_E, sizeof TA345_RSA_E); + trust_anchors[346] = make_ec_trust_anchor((unsigned char *)TA346_DN, sizeof TA346_DN, BR_EC_secp384r1, (unsigned char *)TA346_EC_Q, sizeof TA346_EC_Q); + trust_anchors[347] = make_rsa_trust_anchor((unsigned char *)TA347_DN, sizeof TA347_DN, (unsigned char *)TA347_RSA_N, sizeof TA347_RSA_N, (unsigned char *)TA347_RSA_E, sizeof TA347_RSA_E); + trust_anchors[348] = make_rsa_trust_anchor((unsigned char *)TA348_DN, sizeof TA348_DN, (unsigned char *)TA348_RSA_N, sizeof TA348_RSA_N, (unsigned char *)TA348_RSA_E, sizeof TA348_RSA_E); + trust_anchors[349] = make_ec_trust_anchor((unsigned char *)TA349_DN, sizeof TA349_DN, BR_EC_secp384r1, (unsigned char *)TA349_EC_Q, sizeof TA349_EC_Q); + trust_anchors[350] = make_rsa_trust_anchor((unsigned char *)TA350_DN, sizeof TA350_DN, (unsigned char *)TA350_RSA_N, sizeof TA350_RSA_N, (unsigned char *)TA350_RSA_E, sizeof TA350_RSA_E); + trust_anchors[351] = make_rsa_trust_anchor((unsigned char *)TA351_DN, sizeof TA351_DN, (unsigned char *)TA351_RSA_N, sizeof TA351_RSA_N, (unsigned char *)TA351_RSA_E, sizeof TA351_RSA_E); + trust_anchors[352] = make_rsa_trust_anchor((unsigned char *)TA352_DN, sizeof TA352_DN, (unsigned char *)TA352_RSA_N, sizeof TA352_RSA_N, (unsigned char *)TA352_RSA_E, sizeof TA352_RSA_E); + trust_anchors[353] = make_ec_trust_anchor((unsigned char *)TA353_DN, sizeof TA353_DN, BR_EC_secp384r1, (unsigned char *)TA353_EC_Q, sizeof TA353_EC_Q); + trust_anchors[354] = make_rsa_trust_anchor((unsigned char *)TA354_DN, sizeof TA354_DN, (unsigned char *)TA354_RSA_N, sizeof TA354_RSA_N, (unsigned char *)TA354_RSA_E, sizeof TA354_RSA_E); + trust_anchors[355] = make_rsa_trust_anchor((unsigned char *)TA355_DN, sizeof TA355_DN, (unsigned char *)TA355_RSA_N, sizeof TA355_RSA_N, (unsigned char *)TA355_RSA_E, sizeof TA355_RSA_E); + trust_anchors[356] = make_ec_trust_anchor((unsigned char *)TA356_DN, sizeof TA356_DN, BR_EC_secp384r1, (unsigned char *)TA356_EC_Q, sizeof TA356_EC_Q); + trust_anchors[357] = make_rsa_trust_anchor((unsigned char *)TA357_DN, sizeof TA357_DN, (unsigned char *)TA357_RSA_N, sizeof TA357_RSA_N, (unsigned char *)TA357_RSA_E, sizeof TA357_RSA_E); + trust_anchors[358] = make_rsa_trust_anchor((unsigned char *)TA358_DN, sizeof TA358_DN, (unsigned char *)TA358_RSA_N, sizeof TA358_RSA_N, (unsigned char *)TA358_RSA_E, sizeof TA358_RSA_E); + trust_anchors[359] = make_rsa_trust_anchor((unsigned char *)TA359_DN, sizeof TA359_DN, (unsigned char *)TA359_RSA_N, sizeof TA359_RSA_N, (unsigned char *)TA359_RSA_E, sizeof TA359_RSA_E); + trust_anchors[360] = make_rsa_trust_anchor((unsigned char *)TA360_DN, sizeof TA360_DN, (unsigned char *)TA360_RSA_N, sizeof TA360_RSA_N, (unsigned char *)TA360_RSA_E, sizeof TA360_RSA_E); + trust_anchors[361] = make_rsa_trust_anchor((unsigned char *)TA361_DN, sizeof TA361_DN, (unsigned char *)TA361_RSA_N, sizeof TA361_RSA_N, (unsigned char *)TA361_RSA_E, sizeof TA361_RSA_E); + trust_anchors[362] = make_rsa_trust_anchor((unsigned char *)TA362_DN, sizeof TA362_DN, (unsigned char *)TA362_RSA_N, sizeof TA362_RSA_N, (unsigned char *)TA362_RSA_E, sizeof TA362_RSA_E); + trust_anchors[363] = make_rsa_trust_anchor((unsigned char *)TA363_DN, sizeof TA363_DN, (unsigned char *)TA363_RSA_N, sizeof TA363_RSA_N, (unsigned char *)TA363_RSA_E, sizeof TA363_RSA_E); + trust_anchors[364] = make_rsa_trust_anchor((unsigned char *)TA364_DN, sizeof TA364_DN, (unsigned char *)TA364_RSA_N, sizeof TA364_RSA_N, (unsigned char *)TA364_RSA_E, sizeof TA364_RSA_E); + trust_anchors[365] = make_rsa_trust_anchor((unsigned char *)TA365_DN, sizeof TA365_DN, (unsigned char *)TA365_RSA_N, sizeof TA365_RSA_N, (unsigned char *)TA365_RSA_E, sizeof TA365_RSA_E); + trust_anchors[366] = make_rsa_trust_anchor((unsigned char *)TA366_DN, sizeof TA366_DN, (unsigned char *)TA366_RSA_N, sizeof TA366_RSA_N, (unsigned char *)TA366_RSA_E, sizeof TA366_RSA_E); + trust_anchors[367] = make_rsa_trust_anchor((unsigned char *)TA367_DN, sizeof TA367_DN, (unsigned char *)TA367_RSA_N, sizeof TA367_RSA_N, (unsigned char *)TA367_RSA_E, sizeof TA367_RSA_E); + trust_anchors[368] = make_ec_trust_anchor((unsigned char *)TA368_DN, sizeof TA368_DN, BR_EC_secp384r1, (unsigned char *)TA368_EC_Q, sizeof TA368_EC_Q); + trust_anchors[369] = make_rsa_trust_anchor((unsigned char *)TA369_DN, sizeof TA369_DN, (unsigned char *)TA369_RSA_N, sizeof TA369_RSA_N, (unsigned char *)TA369_RSA_E, sizeof TA369_RSA_E); + trust_anchors[370] = make_rsa_trust_anchor((unsigned char *)TA370_DN, sizeof TA370_DN, (unsigned char *)TA370_RSA_N, sizeof TA370_RSA_N, (unsigned char *)TA370_RSA_E, sizeof TA370_RSA_E); + trust_anchors[371] = make_rsa_trust_anchor((unsigned char *)TA371_DN, sizeof TA371_DN, (unsigned char *)TA371_RSA_N, sizeof TA371_RSA_N, (unsigned char *)TA371_RSA_E, sizeof TA371_RSA_E); + trust_anchors[372] = make_rsa_trust_anchor((unsigned char *)TA372_DN, sizeof TA372_DN, (unsigned char *)TA372_RSA_N, sizeof TA372_RSA_N, (unsigned char *)TA372_RSA_E, sizeof TA372_RSA_E); + trust_anchors[373] = make_ec_trust_anchor((unsigned char *)TA373_DN, sizeof TA373_DN, BR_EC_secp384r1, (unsigned char *)TA373_EC_Q, sizeof TA373_EC_Q); + trust_anchors[374] = make_rsa_trust_anchor((unsigned char *)TA374_DN, sizeof TA374_DN, (unsigned char *)TA374_RSA_N, sizeof TA374_RSA_N, (unsigned char *)TA374_RSA_E, sizeof TA374_RSA_E); + trust_anchors[375] = make_ec_trust_anchor((unsigned char *)TA375_DN, sizeof TA375_DN, BR_EC_secp256r1, (unsigned char *)TA375_EC_Q, sizeof TA375_EC_Q); + trust_anchors[376] = make_ec_trust_anchor((unsigned char *)TA376_DN, sizeof TA376_DN, BR_EC_secp384r1, (unsigned char *)TA376_EC_Q, sizeof TA376_EC_Q); + trust_anchors[377] = make_rsa_trust_anchor((unsigned char *)TA377_DN, sizeof TA377_DN, (unsigned char *)TA377_RSA_N, sizeof TA377_RSA_N, (unsigned char *)TA377_RSA_E, sizeof TA377_RSA_E); + trust_anchors[378] = make_rsa_trust_anchor((unsigned char *)TA378_DN, sizeof TA378_DN, (unsigned char *)TA378_RSA_N, sizeof TA378_RSA_N, (unsigned char *)TA378_RSA_E, sizeof TA378_RSA_E); + trust_anchors[379] = make_rsa_trust_anchor((unsigned char *)TA379_DN, sizeof TA379_DN, (unsigned char *)TA379_RSA_N, sizeof TA379_RSA_N, (unsigned char *)TA379_RSA_E, sizeof TA379_RSA_E); + trust_anchors[380] = make_ec_trust_anchor((unsigned char *)TA380_DN, sizeof TA380_DN, BR_EC_secp384r1, (unsigned char *)TA380_EC_Q, sizeof TA380_EC_Q); + trust_anchors[381] = make_rsa_trust_anchor((unsigned char *)TA381_DN, sizeof TA381_DN, (unsigned char *)TA381_RSA_N, sizeof TA381_RSA_N, (unsigned char *)TA381_RSA_E, sizeof TA381_RSA_E); + trust_anchors[382] = make_rsa_trust_anchor((unsigned char *)TA382_DN, sizeof TA382_DN, (unsigned char *)TA382_RSA_N, sizeof TA382_RSA_N, (unsigned char *)TA382_RSA_E, sizeof TA382_RSA_E); + trust_anchors[383] = make_rsa_trust_anchor((unsigned char *)TA383_DN, sizeof TA383_DN, (unsigned char *)TA383_RSA_N, sizeof TA383_RSA_N, (unsigned char *)TA383_RSA_E, sizeof TA383_RSA_E); + trust_anchors[384] = make_rsa_trust_anchor((unsigned char *)TA384_DN, sizeof TA384_DN, (unsigned char *)TA384_RSA_N, sizeof TA384_RSA_N, (unsigned char *)TA384_RSA_E, sizeof TA384_RSA_E); + trust_anchors[385] = make_ec_trust_anchor((unsigned char *)TA385_DN, sizeof TA385_DN, BR_EC_secp256r1, (unsigned char *)TA385_EC_Q, sizeof TA385_EC_Q); + trust_anchors[386] = make_rsa_trust_anchor((unsigned char *)TA386_DN, sizeof TA386_DN, (unsigned char *)TA386_RSA_N, sizeof TA386_RSA_N, (unsigned char *)TA386_RSA_E, sizeof TA386_RSA_E); + trust_anchors[387] = make_ec_trust_anchor((unsigned char *)TA387_DN, sizeof TA387_DN, BR_EC_secp384r1, (unsigned char *)TA387_EC_Q, sizeof TA387_EC_Q); + trust_anchors[388] = make_ec_trust_anchor((unsigned char *)TA388_DN, sizeof TA388_DN, BR_EC_secp384r1, (unsigned char *)TA388_EC_Q, sizeof TA388_EC_Q); + trust_anchors[389] = make_rsa_trust_anchor((unsigned char *)TA389_DN, sizeof TA389_DN, (unsigned char *)TA389_RSA_N, sizeof TA389_RSA_N, (unsigned char *)TA389_RSA_E, sizeof TA389_RSA_E); + trust_anchors[390] = make_rsa_trust_anchor((unsigned char *)TA390_DN, sizeof TA390_DN, (unsigned char *)TA390_RSA_N, sizeof TA390_RSA_N, (unsigned char *)TA390_RSA_E, sizeof TA390_RSA_E); + trust_anchors[391] = make_ec_trust_anchor((unsigned char *)TA391_DN, sizeof TA391_DN, BR_EC_secp384r1, (unsigned char *)TA391_EC_Q, sizeof TA391_EC_Q); + trust_anchors[392] = make_rsa_trust_anchor((unsigned char *)TA392_DN, sizeof TA392_DN, (unsigned char *)TA392_RSA_N, sizeof TA392_RSA_N, (unsigned char *)TA392_RSA_E, sizeof TA392_RSA_E); + trust_anchors[393] = make_rsa_trust_anchor((unsigned char *)TA393_DN, sizeof TA393_DN, (unsigned char *)TA393_RSA_N, sizeof TA393_RSA_N, (unsigned char *)TA393_RSA_E, sizeof TA393_RSA_E); + trust_anchors[394] = make_rsa_trust_anchor((unsigned char *)TA394_DN, sizeof TA394_DN, (unsigned char *)TA394_RSA_N, sizeof TA394_RSA_N, (unsigned char *)TA394_RSA_E, sizeof TA394_RSA_E); + trust_anchors[395] = make_ec_trust_anchor((unsigned char *)TA395_DN, sizeof TA395_DN, BR_EC_secp384r1, (unsigned char *)TA395_EC_Q, sizeof TA395_EC_Q); + trust_anchors[396] = make_rsa_trust_anchor((unsigned char *)TA396_DN, sizeof TA396_DN, (unsigned char *)TA396_RSA_N, sizeof TA396_RSA_N, (unsigned char *)TA396_RSA_E, sizeof TA396_RSA_E); + trust_anchors[397] = make_rsa_trust_anchor((unsigned char *)TA397_DN, sizeof TA397_DN, (unsigned char *)TA397_RSA_N, sizeof TA397_RSA_N, (unsigned char *)TA397_RSA_E, sizeof TA397_RSA_E); + trust_anchors[398] = make_rsa_trust_anchor((unsigned char *)TA398_DN, sizeof TA398_DN, (unsigned char *)TA398_RSA_N, sizeof TA398_RSA_N, (unsigned char *)TA398_RSA_E, sizeof TA398_RSA_E); + trust_anchors[399] = make_rsa_trust_anchor((unsigned char *)TA399_DN, sizeof TA399_DN, (unsigned char *)TA399_RSA_N, sizeof TA399_RSA_N, (unsigned char *)TA399_RSA_E, sizeof TA399_RSA_E); + trust_anchors[400] = make_rsa_trust_anchor((unsigned char *)TA400_DN, sizeof TA400_DN, (unsigned char *)TA400_RSA_N, sizeof TA400_RSA_N, (unsigned char *)TA400_RSA_E, sizeof TA400_RSA_E); + trust_anchors[401] = make_ec_trust_anchor((unsigned char *)TA401_DN, sizeof TA401_DN, BR_EC_secp384r1, (unsigned char *)TA401_EC_Q, sizeof TA401_EC_Q); + trust_anchors[402] = make_rsa_trust_anchor((unsigned char *)TA402_DN, sizeof TA402_DN, (unsigned char *)TA402_RSA_N, sizeof TA402_RSA_N, (unsigned char *)TA402_RSA_E, sizeof TA402_RSA_E); + trust_anchors[403] = make_rsa_trust_anchor((unsigned char *)TA403_DN, sizeof TA403_DN, (unsigned char *)TA403_RSA_N, sizeof TA403_RSA_N, (unsigned char *)TA403_RSA_E, sizeof TA403_RSA_E); + trust_anchors[404] = make_ec_trust_anchor((unsigned char *)TA404_DN, sizeof TA404_DN, BR_EC_secp256r1, (unsigned char *)TA404_EC_Q, sizeof TA404_EC_Q); + trust_anchors[405] = make_ec_trust_anchor((unsigned char *)TA405_DN, sizeof TA405_DN, BR_EC_secp384r1, (unsigned char *)TA405_EC_Q, sizeof TA405_EC_Q); + trust_anchors[406] = make_rsa_trust_anchor((unsigned char *)TA406_DN, sizeof TA406_DN, (unsigned char *)TA406_RSA_N, sizeof TA406_RSA_N, (unsigned char *)TA406_RSA_E, sizeof TA406_RSA_E); + trust_anchors[407] = make_ec_trust_anchor((unsigned char *)TA407_DN, sizeof TA407_DN, BR_EC_secp384r1, (unsigned char *)TA407_EC_Q, sizeof TA407_EC_Q); + trust_anchors[408] = make_rsa_trust_anchor((unsigned char *)TA408_DN, sizeof TA408_DN, (unsigned char *)TA408_RSA_N, sizeof TA408_RSA_N, (unsigned char *)TA408_RSA_E, sizeof TA408_RSA_E); + trust_anchors[409] = make_rsa_trust_anchor((unsigned char *)TA409_DN, sizeof TA409_DN, (unsigned char *)TA409_RSA_N, sizeof TA409_RSA_N, (unsigned char *)TA409_RSA_E, sizeof TA409_RSA_E); + trust_anchors[410] = make_rsa_trust_anchor((unsigned char *)TA410_DN, sizeof TA410_DN, (unsigned char *)TA410_RSA_N, sizeof TA410_RSA_N, (unsigned char *)TA410_RSA_E, sizeof TA410_RSA_E); + trust_anchors[411] = make_ec_trust_anchor((unsigned char *)TA411_DN, sizeof TA411_DN, BR_EC_secp384r1, (unsigned char *)TA411_EC_Q, sizeof TA411_EC_Q); + trust_anchors[412] = make_rsa_trust_anchor((unsigned char *)TA412_DN, sizeof TA412_DN, (unsigned char *)TA412_RSA_N, sizeof TA412_RSA_N, (unsigned char *)TA412_RSA_E, sizeof TA412_RSA_E); + trust_anchors[413] = make_rsa_trust_anchor((unsigned char *)TA413_DN, sizeof TA413_DN, (unsigned char *)TA413_RSA_N, sizeof TA413_RSA_N, (unsigned char *)TA413_RSA_E, sizeof TA413_RSA_E); + trust_anchors[414] = make_rsa_trust_anchor((unsigned char *)TA414_DN, sizeof TA414_DN, (unsigned char *)TA414_RSA_N, sizeof TA414_RSA_N, (unsigned char *)TA414_RSA_E, sizeof TA414_RSA_E); + trust_anchors[415] = make_rsa_trust_anchor((unsigned char *)TA415_DN, sizeof TA415_DN, (unsigned char *)TA415_RSA_N, sizeof TA415_RSA_N, (unsigned char *)TA415_RSA_E, sizeof TA415_RSA_E); + trust_anchors[416] = make_rsa_trust_anchor((unsigned char *)TA416_DN, sizeof TA416_DN, (unsigned char *)TA416_RSA_N, sizeof TA416_RSA_N, (unsigned char *)TA416_RSA_E, sizeof TA416_RSA_E); + trust_anchors[417] = make_rsa_trust_anchor((unsigned char *)TA417_DN, sizeof TA417_DN, (unsigned char *)TA417_RSA_N, sizeof TA417_RSA_N, (unsigned char *)TA417_RSA_E, sizeof TA417_RSA_E); + trust_anchors[418] = make_ec_trust_anchor((unsigned char *)TA418_DN, sizeof TA418_DN, BR_EC_secp384r1, (unsigned char *)TA418_EC_Q, sizeof TA418_EC_Q); + trust_anchors[419] = make_rsa_trust_anchor((unsigned char *)TA419_DN, sizeof TA419_DN, (unsigned char *)TA419_RSA_N, sizeof TA419_RSA_N, (unsigned char *)TA419_RSA_E, sizeof TA419_RSA_E); + trust_anchors[420] = make_ec_trust_anchor((unsigned char *)TA420_DN, sizeof TA420_DN, BR_EC_secp384r1, (unsigned char *)TA420_EC_Q, sizeof TA420_EC_Q); + trust_anchors[421] = make_rsa_trust_anchor((unsigned char *)TA421_DN, sizeof TA421_DN, (unsigned char *)TA421_RSA_N, sizeof TA421_RSA_N, (unsigned char *)TA421_RSA_E, sizeof TA421_RSA_E); + trust_anchors[422] = make_rsa_trust_anchor((unsigned char *)TA422_DN, sizeof TA422_DN, (unsigned char *)TA422_RSA_N, sizeof TA422_RSA_N, (unsigned char *)TA422_RSA_E, sizeof TA422_RSA_E); + trust_anchors[423] = make_rsa_trust_anchor((unsigned char *)TA423_DN, sizeof TA423_DN, (unsigned char *)TA423_RSA_N, sizeof TA423_RSA_N, (unsigned char *)TA423_RSA_E, sizeof TA423_RSA_E); + trust_anchors[424] = make_ec_trust_anchor((unsigned char *)TA424_DN, sizeof TA424_DN, BR_EC_secp384r1, (unsigned char *)TA424_EC_Q, sizeof TA424_EC_Q); + trust_anchors[425] = make_rsa_trust_anchor((unsigned char *)TA425_DN, sizeof TA425_DN, (unsigned char *)TA425_RSA_N, sizeof TA425_RSA_N, (unsigned char *)TA425_RSA_E, sizeof TA425_RSA_E); + trust_anchors[426] = make_rsa_trust_anchor((unsigned char *)TA426_DN, sizeof TA426_DN, (unsigned char *)TA426_RSA_N, sizeof TA426_RSA_N, (unsigned char *)TA426_RSA_E, sizeof TA426_RSA_E); + trust_anchors[427] = make_rsa_trust_anchor((unsigned char *)TA427_DN, sizeof TA427_DN, (unsigned char *)TA427_RSA_N, sizeof TA427_RSA_N, (unsigned char *)TA427_RSA_E, sizeof TA427_RSA_E); + trust_anchors[428] = make_ec_trust_anchor((unsigned char *)TA428_DN, sizeof TA428_DN, BR_EC_secp384r1, (unsigned char *)TA428_EC_Q, sizeof TA428_EC_Q); + trust_anchors[429] = make_ec_trust_anchor((unsigned char *)TA429_DN, sizeof TA429_DN, BR_EC_secp384r1, (unsigned char *)TA429_EC_Q, sizeof TA429_EC_Q); + trust_anchors[430] = make_rsa_trust_anchor((unsigned char *)TA430_DN, sizeof TA430_DN, (unsigned char *)TA430_RSA_N, sizeof TA430_RSA_N, (unsigned char *)TA430_RSA_E, sizeof TA430_RSA_E); + trust_anchors[431] = make_rsa_trust_anchor((unsigned char *)TA431_DN, sizeof TA431_DN, (unsigned char *)TA431_RSA_N, sizeof TA431_RSA_N, (unsigned char *)TA431_RSA_E, sizeof TA431_RSA_E); + trust_anchors[432] = make_rsa_trust_anchor((unsigned char *)TA432_DN, sizeof TA432_DN, (unsigned char *)TA432_RSA_N, sizeof TA432_RSA_N, (unsigned char *)TA432_RSA_E, sizeof TA432_RSA_E); + trust_anchors[433] = make_ec_trust_anchor((unsigned char *)TA433_DN, sizeof TA433_DN, BR_EC_secp384r1, (unsigned char *)TA433_EC_Q, sizeof TA433_EC_Q); + trust_anchors[434] = make_rsa_trust_anchor((unsigned char *)TA434_DN, sizeof TA434_DN, (unsigned char *)TA434_RSA_N, sizeof TA434_RSA_N, (unsigned char *)TA434_RSA_E, sizeof TA434_RSA_E); + trust_anchors[435] = make_ec_trust_anchor((unsigned char *)TA435_DN, sizeof TA435_DN, BR_EC_secp384r1, (unsigned char *)TA435_EC_Q, sizeof TA435_EC_Q); + trust_anchors[436] = make_rsa_trust_anchor((unsigned char *)TA436_DN, sizeof TA436_DN, (unsigned char *)TA436_RSA_N, sizeof TA436_RSA_N, (unsigned char *)TA436_RSA_E, sizeof TA436_RSA_E); + trust_anchors[437] = make_rsa_trust_anchor((unsigned char *)TA437_DN, sizeof TA437_DN, (unsigned char *)TA437_RSA_N, sizeof TA437_RSA_N, (unsigned char *)TA437_RSA_E, sizeof TA437_RSA_E); + trust_anchors[438] = make_rsa_trust_anchor((unsigned char *)TA438_DN, sizeof TA438_DN, (unsigned char *)TA438_RSA_N, sizeof TA438_RSA_N, (unsigned char *)TA438_RSA_E, sizeof TA438_RSA_E); + trust_anchors[439] = make_rsa_trust_anchor((unsigned char *)TA439_DN, sizeof TA439_DN, (unsigned char *)TA439_RSA_N, sizeof TA439_RSA_N, (unsigned char *)TA439_RSA_E, sizeof TA439_RSA_E); + trust_anchors[440] = make_rsa_trust_anchor((unsigned char *)TA440_DN, sizeof TA440_DN, (unsigned char *)TA440_RSA_N, sizeof TA440_RSA_N, (unsigned char *)TA440_RSA_E, sizeof TA440_RSA_E); + trust_anchors[441] = make_ec_trust_anchor((unsigned char *)TA441_DN, sizeof TA441_DN, BR_EC_secp384r1, (unsigned char *)TA441_EC_Q, sizeof TA441_EC_Q); + trust_anchors[442] = make_rsa_trust_anchor((unsigned char *)TA442_DN, sizeof TA442_DN, (unsigned char *)TA442_RSA_N, sizeof TA442_RSA_N, (unsigned char *)TA442_RSA_E, sizeof TA442_RSA_E); + trust_anchors[443] = make_rsa_trust_anchor((unsigned char *)TA443_DN, sizeof TA443_DN, (unsigned char *)TA443_RSA_N, sizeof TA443_RSA_N, (unsigned char *)TA443_RSA_E, sizeof TA443_RSA_E); + trust_anchors[444] = make_ec_trust_anchor((unsigned char *)TA444_DN, sizeof TA444_DN, BR_EC_secp384r1, (unsigned char *)TA444_EC_Q, sizeof TA444_EC_Q); + trust_anchors[445] = make_rsa_trust_anchor((unsigned char *)TA445_DN, sizeof TA445_DN, (unsigned char *)TA445_RSA_N, sizeof TA445_RSA_N, (unsigned char *)TA445_RSA_E, sizeof TA445_RSA_E); + trust_anchors[446] = make_ec_trust_anchor((unsigned char *)TA446_DN, sizeof TA446_DN, BR_EC_secp384r1, (unsigned char *)TA446_EC_Q, sizeof TA446_EC_Q); + trust_anchors[447] = make_rsa_trust_anchor((unsigned char *)TA447_DN, sizeof TA447_DN, (unsigned char *)TA447_RSA_N, sizeof TA447_RSA_N, (unsigned char *)TA447_RSA_E, sizeof TA447_RSA_E); + trust_anchors[448] = make_rsa_trust_anchor((unsigned char *)TA448_DN, sizeof TA448_DN, (unsigned char *)TA448_RSA_N, sizeof TA448_RSA_N, (unsigned char *)TA448_RSA_E, sizeof TA448_RSA_E); + trust_anchors[449] = make_rsa_trust_anchor((unsigned char *)TA449_DN, sizeof TA449_DN, (unsigned char *)TA449_RSA_N, sizeof TA449_RSA_N, (unsigned char *)TA449_RSA_E, sizeof TA449_RSA_E); + trust_anchors[450] = make_rsa_trust_anchor((unsigned char *)TA450_DN, sizeof TA450_DN, (unsigned char *)TA450_RSA_N, sizeof TA450_RSA_N, (unsigned char *)TA450_RSA_E, sizeof TA450_RSA_E); + trust_anchors[451] = make_ec_trust_anchor((unsigned char *)TA451_DN, sizeof TA451_DN, BR_EC_secp384r1, (unsigned char *)TA451_EC_Q, sizeof TA451_EC_Q); + trust_anchors[452] = make_rsa_trust_anchor((unsigned char *)TA452_DN, sizeof TA452_DN, (unsigned char *)TA452_RSA_N, sizeof TA452_RSA_N, (unsigned char *)TA452_RSA_E, sizeof TA452_RSA_E); + trust_anchors[453] = make_ec_trust_anchor((unsigned char *)TA453_DN, sizeof TA453_DN, BR_EC_secp384r1, (unsigned char *)TA453_EC_Q, sizeof TA453_EC_Q); + trust_anchors[454] = make_rsa_trust_anchor((unsigned char *)TA454_DN, sizeof TA454_DN, (unsigned char *)TA454_RSA_N, sizeof TA454_RSA_N, (unsigned char *)TA454_RSA_E, sizeof TA454_RSA_E); + trust_anchors[455] = make_rsa_trust_anchor((unsigned char *)TA455_DN, sizeof TA455_DN, (unsigned char *)TA455_RSA_N, sizeof TA455_RSA_N, (unsigned char *)TA455_RSA_E, sizeof TA455_RSA_E); + trust_anchors[456] = make_rsa_trust_anchor((unsigned char *)TA456_DN, sizeof TA456_DN, (unsigned char *)TA456_RSA_N, sizeof TA456_RSA_N, (unsigned char *)TA456_RSA_E, sizeof TA456_RSA_E); + trust_anchors[457] = make_rsa_trust_anchor((unsigned char *)TA457_DN, sizeof TA457_DN, (unsigned char *)TA457_RSA_N, sizeof TA457_RSA_N, (unsigned char *)TA457_RSA_E, sizeof TA457_RSA_E); + trust_anchors[458] = make_ec_trust_anchor((unsigned char *)TA458_DN, sizeof TA458_DN, BR_EC_secp384r1, (unsigned char *)TA458_EC_Q, sizeof TA458_EC_Q); + trust_anchors[459] = make_ec_trust_anchor((unsigned char *)TA459_DN, sizeof TA459_DN, BR_EC_secp384r1, (unsigned char *)TA459_EC_Q, sizeof TA459_EC_Q); + trust_anchors[460] = make_ec_trust_anchor((unsigned char *)TA460_DN, sizeof TA460_DN, BR_EC_secp256r1, (unsigned char *)TA460_EC_Q, sizeof TA460_EC_Q); + trust_anchors[461] = make_ec_trust_anchor((unsigned char *)TA461_DN, sizeof TA461_DN, BR_EC_secp384r1, (unsigned char *)TA461_EC_Q, sizeof TA461_EC_Q); + trust_anchors[462] = make_rsa_trust_anchor((unsigned char *)TA462_DN, sizeof TA462_DN, (unsigned char *)TA462_RSA_N, sizeof TA462_RSA_N, (unsigned char *)TA462_RSA_E, sizeof TA462_RSA_E); + trust_anchors[463] = make_rsa_trust_anchor((unsigned char *)TA463_DN, sizeof TA463_DN, (unsigned char *)TA463_RSA_N, sizeof TA463_RSA_N, (unsigned char *)TA463_RSA_E, sizeof TA463_RSA_E); + trust_anchors[464] = make_rsa_trust_anchor((unsigned char *)TA464_DN, sizeof TA464_DN, (unsigned char *)TA464_RSA_N, sizeof TA464_RSA_N, (unsigned char *)TA464_RSA_E, sizeof TA464_RSA_E); + trust_anchors[465] = make_ec_trust_anchor((unsigned char *)TA465_DN, sizeof TA465_DN, BR_EC_secp384r1, (unsigned char *)TA465_EC_Q, sizeof TA465_EC_Q); + trust_anchors[466] = make_rsa_trust_anchor((unsigned char *)TA466_DN, sizeof TA466_DN, (unsigned char *)TA466_RSA_N, sizeof TA466_RSA_N, (unsigned char *)TA466_RSA_E, sizeof TA466_RSA_E); + trust_anchors[467] = make_rsa_trust_anchor((unsigned char *)TA467_DN, sizeof TA467_DN, (unsigned char *)TA467_RSA_N, sizeof TA467_RSA_N, (unsigned char *)TA467_RSA_E, sizeof TA467_RSA_E); + trust_anchors[468] = make_rsa_trust_anchor((unsigned char *)TA468_DN, sizeof TA468_DN, (unsigned char *)TA468_RSA_N, sizeof TA468_RSA_N, (unsigned char *)TA468_RSA_E, sizeof TA468_RSA_E); + trust_anchors[469] = make_ec_trust_anchor((unsigned char *)TA469_DN, sizeof TA469_DN, BR_EC_secp384r1, (unsigned char *)TA469_EC_Q, sizeof TA469_EC_Q); + trust_anchors[470] = make_rsa_trust_anchor((unsigned char *)TA470_DN, sizeof TA470_DN, (unsigned char *)TA470_RSA_N, sizeof TA470_RSA_N, (unsigned char *)TA470_RSA_E, sizeof TA470_RSA_E); + trust_anchors[471] = make_ec_trust_anchor((unsigned char *)TA471_DN, sizeof TA471_DN, BR_EC_secp384r1, (unsigned char *)TA471_EC_Q, sizeof TA471_EC_Q); + trust_anchors[472] = make_rsa_trust_anchor((unsigned char *)TA472_DN, sizeof TA472_DN, (unsigned char *)TA472_RSA_N, sizeof TA472_RSA_N, (unsigned char *)TA472_RSA_E, sizeof TA472_RSA_E); + trust_anchors[473] = make_rsa_trust_anchor((unsigned char *)TA473_DN, sizeof TA473_DN, (unsigned char *)TA473_RSA_N, sizeof TA473_RSA_N, (unsigned char *)TA473_RSA_E, sizeof TA473_RSA_E); + trust_anchors[474] = make_rsa_trust_anchor((unsigned char *)TA474_DN, sizeof TA474_DN, (unsigned char *)TA474_RSA_N, sizeof TA474_RSA_N, (unsigned char *)TA474_RSA_E, sizeof TA474_RSA_E); + trust_anchors[475] = make_rsa_trust_anchor((unsigned char *)TA475_DN, sizeof TA475_DN, (unsigned char *)TA475_RSA_N, sizeof TA475_RSA_N, (unsigned char *)TA475_RSA_E, sizeof TA475_RSA_E); + trust_anchors[476] = make_ec_trust_anchor((unsigned char *)TA476_DN, sizeof TA476_DN, BR_EC_secp384r1, (unsigned char *)TA476_EC_Q, sizeof TA476_EC_Q); + trust_anchors[477] = make_rsa_trust_anchor((unsigned char *)TA477_DN, sizeof TA477_DN, (unsigned char *)TA477_RSA_N, sizeof TA477_RSA_N, (unsigned char *)TA477_RSA_E, sizeof TA477_RSA_E); + trust_anchors[478] = make_rsa_trust_anchor((unsigned char *)TA478_DN, sizeof TA478_DN, (unsigned char *)TA478_RSA_N, sizeof TA478_RSA_N, (unsigned char *)TA478_RSA_E, sizeof TA478_RSA_E); + trust_anchors[479] = make_rsa_trust_anchor((unsigned char *)TA479_DN, sizeof TA479_DN, (unsigned char *)TA479_RSA_N, sizeof TA479_RSA_N, (unsigned char *)TA479_RSA_E, sizeof TA479_RSA_E); + trust_anchors[480] = make_rsa_trust_anchor((unsigned char *)TA480_DN, sizeof TA480_DN, (unsigned char *)TA480_RSA_N, sizeof TA480_RSA_N, (unsigned char *)TA480_RSA_E, sizeof TA480_RSA_E); + trust_anchors[481] = make_ec_trust_anchor((unsigned char *)TA481_DN, sizeof TA481_DN, BR_EC_secp384r1, (unsigned char *)TA481_EC_Q, sizeof TA481_EC_Q); + trust_anchors[482] = make_rsa_trust_anchor((unsigned char *)TA482_DN, sizeof TA482_DN, (unsigned char *)TA482_RSA_N, sizeof TA482_RSA_N, (unsigned char *)TA482_RSA_E, sizeof TA482_RSA_E); + trust_anchors[483] = make_rsa_trust_anchor((unsigned char *)TA483_DN, sizeof TA483_DN, (unsigned char *)TA483_RSA_N, sizeof TA483_RSA_N, (unsigned char *)TA483_RSA_E, sizeof TA483_RSA_E); + trust_anchors[484] = make_rsa_trust_anchor((unsigned char *)TA484_DN, sizeof TA484_DN, (unsigned char *)TA484_RSA_N, sizeof TA484_RSA_N, (unsigned char *)TA484_RSA_E, sizeof TA484_RSA_E); + trust_anchors[485] = make_rsa_trust_anchor((unsigned char *)TA485_DN, sizeof TA485_DN, (unsigned char *)TA485_RSA_N, sizeof TA485_RSA_N, (unsigned char *)TA485_RSA_E, sizeof TA485_RSA_E); + trust_anchors[486] = make_ec_trust_anchor((unsigned char *)TA486_DN, sizeof TA486_DN, BR_EC_secp384r1, (unsigned char *)TA486_EC_Q, sizeof TA486_EC_Q); + trust_anchors[487] = make_rsa_trust_anchor((unsigned char *)TA487_DN, sizeof TA487_DN, (unsigned char *)TA487_RSA_N, sizeof TA487_RSA_N, (unsigned char *)TA487_RSA_E, sizeof TA487_RSA_E); + trust_anchors[488] = make_rsa_trust_anchor((unsigned char *)TA488_DN, sizeof TA488_DN, (unsigned char *)TA488_RSA_N, sizeof TA488_RSA_N, (unsigned char *)TA488_RSA_E, sizeof TA488_RSA_E); + trust_anchors[489] = make_rsa_trust_anchor((unsigned char *)TA489_DN, sizeof TA489_DN, (unsigned char *)TA489_RSA_N, sizeof TA489_RSA_N, (unsigned char *)TA489_RSA_E, sizeof TA489_RSA_E); + trust_anchors[490] = make_rsa_trust_anchor((unsigned char *)TA490_DN, sizeof TA490_DN, (unsigned char *)TA490_RSA_N, sizeof TA490_RSA_N, (unsigned char *)TA490_RSA_E, sizeof TA490_RSA_E); + trust_anchors[491] = make_rsa_trust_anchor((unsigned char *)TA491_DN, sizeof TA491_DN, (unsigned char *)TA491_RSA_N, sizeof TA491_RSA_N, (unsigned char *)TA491_RSA_E, sizeof TA491_RSA_E); + trust_anchors[492] = make_ec_trust_anchor((unsigned char *)TA492_DN, sizeof TA492_DN, BR_EC_secp384r1, (unsigned char *)TA492_EC_Q, sizeof TA492_EC_Q); + trust_anchors[493] = make_rsa_trust_anchor((unsigned char *)TA493_DN, sizeof TA493_DN, (unsigned char *)TA493_RSA_N, sizeof TA493_RSA_N, (unsigned char *)TA493_RSA_E, sizeof TA493_RSA_E); + trust_anchors[494] = make_ec_trust_anchor((unsigned char *)TA494_DN, sizeof TA494_DN, BR_EC_secp384r1, (unsigned char *)TA494_EC_Q, sizeof TA494_EC_Q); + trust_anchors[495] = make_rsa_trust_anchor((unsigned char *)TA495_DN, sizeof TA495_DN, (unsigned char *)TA495_RSA_N, sizeof TA495_RSA_N, (unsigned char *)TA495_RSA_E, sizeof TA495_RSA_E); + trust_anchors[496] = make_ec_trust_anchor((unsigned char *)TA496_DN, sizeof TA496_DN, BR_EC_secp384r1, (unsigned char *)TA496_EC_Q, sizeof TA496_EC_Q); + trust_anchors[497] = make_rsa_trust_anchor((unsigned char *)TA497_DN, sizeof TA497_DN, (unsigned char *)TA497_RSA_N, sizeof TA497_RSA_N, (unsigned char *)TA497_RSA_E, sizeof TA497_RSA_E); + trust_anchors[498] = make_rsa_trust_anchor((unsigned char *)TA498_DN, sizeof TA498_DN, (unsigned char *)TA498_RSA_N, sizeof TA498_RSA_N, (unsigned char *)TA498_RSA_E, sizeof TA498_RSA_E); + trust_anchors[499] = make_ec_trust_anchor((unsigned char *)TA499_DN, sizeof TA499_DN, BR_EC_secp384r1, (unsigned char *)TA499_EC_Q, sizeof TA499_EC_Q); + trust_anchors[500] = make_rsa_trust_anchor((unsigned char *)TA500_DN, sizeof TA500_DN, (unsigned char *)TA500_RSA_N, sizeof TA500_RSA_N, (unsigned char *)TA500_RSA_E, sizeof TA500_RSA_E); + trust_anchors[501] = make_rsa_trust_anchor((unsigned char *)TA501_DN, sizeof TA501_DN, (unsigned char *)TA501_RSA_N, sizeof TA501_RSA_N, (unsigned char *)TA501_RSA_E, sizeof TA501_RSA_E); + trust_anchors[502] = make_rsa_trust_anchor((unsigned char *)TA502_DN, sizeof TA502_DN, (unsigned char *)TA502_RSA_N, sizeof TA502_RSA_N, (unsigned char *)TA502_RSA_E, sizeof TA502_RSA_E); + trust_anchors[503] = make_ec_trust_anchor((unsigned char *)TA503_DN, sizeof TA503_DN, BR_EC_secp384r1, (unsigned char *)TA503_EC_Q, sizeof TA503_EC_Q); + trust_anchors[504] = make_rsa_trust_anchor((unsigned char *)TA504_DN, sizeof TA504_DN, (unsigned char *)TA504_RSA_N, sizeof TA504_RSA_N, (unsigned char *)TA504_RSA_E, sizeof TA504_RSA_E); + trust_anchors[505] = make_rsa_trust_anchor((unsigned char *)TA505_DN, sizeof TA505_DN, (unsigned char *)TA505_RSA_N, sizeof TA505_RSA_N, (unsigned char *)TA505_RSA_E, sizeof TA505_RSA_E); + trust_anchors[506] = make_ec_trust_anchor((unsigned char *)TA506_DN, sizeof TA506_DN, BR_EC_secp384r1, (unsigned char *)TA506_EC_Q, sizeof TA506_EC_Q); + trust_anchors[507] = make_rsa_trust_anchor((unsigned char *)TA507_DN, sizeof TA507_DN, (unsigned char *)TA507_RSA_N, sizeof TA507_RSA_N, (unsigned char *)TA507_RSA_E, sizeof TA507_RSA_E); + trust_anchors[508] = make_rsa_trust_anchor((unsigned char *)TA508_DN, sizeof TA508_DN, (unsigned char *)TA508_RSA_N, sizeof TA508_RSA_N, (unsigned char *)TA508_RSA_E, sizeof TA508_RSA_E); + trust_anchors[509] = make_rsa_trust_anchor((unsigned char *)TA509_DN, sizeof TA509_DN, (unsigned char *)TA509_RSA_N, sizeof TA509_RSA_N, (unsigned char *)TA509_RSA_E, sizeof TA509_RSA_E); + trust_anchors[510] = make_rsa_trust_anchor((unsigned char *)TA510_DN, sizeof TA510_DN, (unsigned char *)TA510_RSA_N, sizeof TA510_RSA_N, (unsigned char *)TA510_RSA_E, sizeof TA510_RSA_E); + trust_anchors[511] = make_rsa_trust_anchor((unsigned char *)TA511_DN, sizeof TA511_DN, (unsigned char *)TA511_RSA_N, sizeof TA511_RSA_N, (unsigned char *)TA511_RSA_E, sizeof TA511_RSA_E); + trust_anchors[512] = make_rsa_trust_anchor((unsigned char *)TA512_DN, sizeof TA512_DN, (unsigned char *)TA512_RSA_N, sizeof TA512_RSA_N, (unsigned char *)TA512_RSA_E, sizeof TA512_RSA_E); + trust_anchors[513] = make_rsa_trust_anchor((unsigned char *)TA513_DN, sizeof TA513_DN, (unsigned char *)TA513_RSA_N, sizeof TA513_RSA_N, (unsigned char *)TA513_RSA_E, sizeof TA513_RSA_E); + trust_anchors[514] = make_rsa_trust_anchor((unsigned char *)TA514_DN, sizeof TA514_DN, (unsigned char *)TA514_RSA_N, sizeof TA514_RSA_N, (unsigned char *)TA514_RSA_E, sizeof TA514_RSA_E); + trust_anchors[515] = make_rsa_trust_anchor((unsigned char *)TA515_DN, sizeof TA515_DN, (unsigned char *)TA515_RSA_N, sizeof TA515_RSA_N, (unsigned char *)TA515_RSA_E, sizeof TA515_RSA_E); + trust_anchors[516] = make_rsa_trust_anchor((unsigned char *)TA516_DN, sizeof TA516_DN, (unsigned char *)TA516_RSA_N, sizeof TA516_RSA_N, (unsigned char *)TA516_RSA_E, sizeof TA516_RSA_E); + trust_anchors[517] = make_rsa_trust_anchor((unsigned char *)TA517_DN, sizeof TA517_DN, (unsigned char *)TA517_RSA_N, sizeof TA517_RSA_N, (unsigned char *)TA517_RSA_E, sizeof TA517_RSA_E); + trust_anchors[518] = make_ec_trust_anchor((unsigned char *)TA518_DN, sizeof TA518_DN, BR_EC_secp384r1, (unsigned char *)TA518_EC_Q, sizeof TA518_EC_Q); + trust_anchors[519] = make_rsa_trust_anchor((unsigned char *)TA519_DN, sizeof TA519_DN, (unsigned char *)TA519_RSA_N, sizeof TA519_RSA_N, (unsigned char *)TA519_RSA_E, sizeof TA519_RSA_E); + trust_anchors[520] = make_rsa_trust_anchor((unsigned char *)TA520_DN, sizeof TA520_DN, (unsigned char *)TA520_RSA_N, sizeof TA520_RSA_N, (unsigned char *)TA520_RSA_E, sizeof TA520_RSA_E); + trust_anchors[521] = make_rsa_trust_anchor((unsigned char *)TA521_DN, sizeof TA521_DN, (unsigned char *)TA521_RSA_N, sizeof TA521_RSA_N, (unsigned char *)TA521_RSA_E, sizeof TA521_RSA_E); + trust_anchors[522] = make_rsa_trust_anchor((unsigned char *)TA522_DN, sizeof TA522_DN, (unsigned char *)TA522_RSA_N, sizeof TA522_RSA_N, (unsigned char *)TA522_RSA_E, sizeof TA522_RSA_E); + trust_anchors[523] = make_ec_trust_anchor((unsigned char *)TA523_DN, sizeof TA523_DN, BR_EC_secp384r1, (unsigned char *)TA523_EC_Q, sizeof TA523_EC_Q); + trust_anchors[524] = make_rsa_trust_anchor((unsigned char *)TA524_DN, sizeof TA524_DN, (unsigned char *)TA524_RSA_N, sizeof TA524_RSA_N, (unsigned char *)TA524_RSA_E, sizeof TA524_RSA_E); + trust_anchors[525] = make_ec_trust_anchor((unsigned char *)TA525_DN, sizeof TA525_DN, BR_EC_secp256r1, (unsigned char *)TA525_EC_Q, sizeof TA525_EC_Q); + trust_anchors[526] = make_ec_trust_anchor((unsigned char *)TA526_DN, sizeof TA526_DN, BR_EC_secp384r1, (unsigned char *)TA526_EC_Q, sizeof TA526_EC_Q); + trust_anchors[527] = make_rsa_trust_anchor((unsigned char *)TA527_DN, sizeof TA527_DN, (unsigned char *)TA527_RSA_N, sizeof TA527_RSA_N, (unsigned char *)TA527_RSA_E, sizeof TA527_RSA_E); + trust_anchors[528] = make_rsa_trust_anchor((unsigned char *)TA528_DN, sizeof TA528_DN, (unsigned char *)TA528_RSA_N, sizeof TA528_RSA_N, (unsigned char *)TA528_RSA_E, sizeof TA528_RSA_E); + trust_anchors[529] = make_rsa_trust_anchor((unsigned char *)TA529_DN, sizeof TA529_DN, (unsigned char *)TA529_RSA_N, sizeof TA529_RSA_N, (unsigned char *)TA529_RSA_E, sizeof TA529_RSA_E); + trust_anchors[530] = make_ec_trust_anchor((unsigned char *)TA530_DN, sizeof TA530_DN, BR_EC_secp384r1, (unsigned char *)TA530_EC_Q, sizeof TA530_EC_Q); + trust_anchors[531] = make_rsa_trust_anchor((unsigned char *)TA531_DN, sizeof TA531_DN, (unsigned char *)TA531_RSA_N, sizeof TA531_RSA_N, (unsigned char *)TA531_RSA_E, sizeof TA531_RSA_E); + trust_anchors[532] = make_rsa_trust_anchor((unsigned char *)TA532_DN, sizeof TA532_DN, (unsigned char *)TA532_RSA_N, sizeof TA532_RSA_N, (unsigned char *)TA532_RSA_E, sizeof TA532_RSA_E); + trust_anchors[533] = make_rsa_trust_anchor((unsigned char *)TA533_DN, sizeof TA533_DN, (unsigned char *)TA533_RSA_N, sizeof TA533_RSA_N, (unsigned char *)TA533_RSA_E, sizeof TA533_RSA_E); + trust_anchors[534] = make_rsa_trust_anchor((unsigned char *)TA534_DN, sizeof TA534_DN, (unsigned char *)TA534_RSA_N, sizeof TA534_RSA_N, (unsigned char *)TA534_RSA_E, sizeof TA534_RSA_E); + trust_anchors[535] = make_ec_trust_anchor((unsigned char *)TA535_DN, sizeof TA535_DN, BR_EC_secp256r1, (unsigned char *)TA535_EC_Q, sizeof TA535_EC_Q); + trust_anchors[536] = make_rsa_trust_anchor((unsigned char *)TA536_DN, sizeof TA536_DN, (unsigned char *)TA536_RSA_N, sizeof TA536_RSA_N, (unsigned char *)TA536_RSA_E, sizeof TA536_RSA_E); + trust_anchors[537] = make_ec_trust_anchor((unsigned char *)TA537_DN, sizeof TA537_DN, BR_EC_secp384r1, (unsigned char *)TA537_EC_Q, sizeof TA537_EC_Q); + trust_anchors[538] = make_ec_trust_anchor((unsigned char *)TA538_DN, sizeof TA538_DN, BR_EC_secp384r1, (unsigned char *)TA538_EC_Q, sizeof TA538_EC_Q); + trust_anchors[539] = make_rsa_trust_anchor((unsigned char *)TA539_DN, sizeof TA539_DN, (unsigned char *)TA539_RSA_N, sizeof TA539_RSA_N, (unsigned char *)TA539_RSA_E, sizeof TA539_RSA_E); + trust_anchors[540] = make_rsa_trust_anchor((unsigned char *)TA540_DN, sizeof TA540_DN, (unsigned char *)TA540_RSA_N, sizeof TA540_RSA_N, (unsigned char *)TA540_RSA_E, sizeof TA540_RSA_E); + trust_anchors[541] = make_ec_trust_anchor((unsigned char *)TA541_DN, sizeof TA541_DN, BR_EC_secp384r1, (unsigned char *)TA541_EC_Q, sizeof TA541_EC_Q); + trust_anchors[542] = make_rsa_trust_anchor((unsigned char *)TA542_DN, sizeof TA542_DN, (unsigned char *)TA542_RSA_N, sizeof TA542_RSA_N, (unsigned char *)TA542_RSA_E, sizeof TA542_RSA_E); + trust_anchors[543] = make_rsa_trust_anchor((unsigned char *)TA543_DN, sizeof TA543_DN, (unsigned char *)TA543_RSA_N, sizeof TA543_RSA_N, (unsigned char *)TA543_RSA_E, sizeof TA543_RSA_E); + trust_anchors[544] = make_rsa_trust_anchor((unsigned char *)TA544_DN, sizeof TA544_DN, (unsigned char *)TA544_RSA_N, sizeof TA544_RSA_N, (unsigned char *)TA544_RSA_E, sizeof TA544_RSA_E); + trust_anchors[545] = make_ec_trust_anchor((unsigned char *)TA545_DN, sizeof TA545_DN, BR_EC_secp384r1, (unsigned char *)TA545_EC_Q, sizeof TA545_EC_Q); + trust_anchors[546] = make_rsa_trust_anchor((unsigned char *)TA546_DN, sizeof TA546_DN, (unsigned char *)TA546_RSA_N, sizeof TA546_RSA_N, (unsigned char *)TA546_RSA_E, sizeof TA546_RSA_E); + trust_anchors[547] = make_rsa_trust_anchor((unsigned char *)TA547_DN, sizeof TA547_DN, (unsigned char *)TA547_RSA_N, sizeof TA547_RSA_N, (unsigned char *)TA547_RSA_E, sizeof TA547_RSA_E); + trust_anchors[548] = make_ec_trust_anchor((unsigned char *)TA548_DN, sizeof TA548_DN, BR_EC_secp384r1, (unsigned char *)TA548_EC_Q, sizeof TA548_EC_Q); + trust_anchors[549] = make_rsa_trust_anchor((unsigned char *)TA549_DN, sizeof TA549_DN, (unsigned char *)TA549_RSA_N, sizeof TA549_RSA_N, (unsigned char *)TA549_RSA_E, sizeof TA549_RSA_E); + trust_anchors[550] = make_rsa_trust_anchor((unsigned char *)TA550_DN, sizeof TA550_DN, (unsigned char *)TA550_RSA_N, sizeof TA550_RSA_N, (unsigned char *)TA550_RSA_E, sizeof TA550_RSA_E); + trust_anchors[551] = make_rsa_trust_anchor((unsigned char *)TA551_DN, sizeof TA551_DN, (unsigned char *)TA551_RSA_N, sizeof TA551_RSA_N, (unsigned char *)TA551_RSA_E, sizeof TA551_RSA_E); + trust_anchors[552] = make_ec_trust_anchor((unsigned char *)TA552_DN, sizeof TA552_DN, BR_EC_secp384r1, (unsigned char *)TA552_EC_Q, sizeof TA552_EC_Q); + trust_anchors[553] = make_rsa_trust_anchor((unsigned char *)TA553_DN, sizeof TA553_DN, (unsigned char *)TA553_RSA_N, sizeof TA553_RSA_N, (unsigned char *)TA553_RSA_E, sizeof TA553_RSA_E); + trust_anchors[554] = make_rsa_trust_anchor((unsigned char *)TA554_DN, sizeof TA554_DN, (unsigned char *)TA554_RSA_N, sizeof TA554_RSA_N, (unsigned char *)TA554_RSA_E, sizeof TA554_RSA_E); + trust_anchors[555] = make_rsa_trust_anchor((unsigned char *)TA555_DN, sizeof TA555_DN, (unsigned char *)TA555_RSA_N, sizeof TA555_RSA_N, (unsigned char *)TA555_RSA_E, sizeof TA555_RSA_E); + trust_anchors[556] = make_rsa_trust_anchor((unsigned char *)TA556_DN, sizeof TA556_DN, (unsigned char *)TA556_RSA_N, sizeof TA556_RSA_N, (unsigned char *)TA556_RSA_E, sizeof TA556_RSA_E); + trust_anchors[557] = make_rsa_trust_anchor((unsigned char *)TA557_DN, sizeof TA557_DN, (unsigned char *)TA557_RSA_N, sizeof TA557_RSA_N, (unsigned char *)TA557_RSA_E, sizeof TA557_RSA_E); + trust_anchors[558] = make_ec_trust_anchor((unsigned char *)TA558_DN, sizeof TA558_DN, BR_EC_secp384r1, (unsigned char *)TA558_EC_Q, sizeof TA558_EC_Q); + trust_anchors[559] = make_rsa_trust_anchor((unsigned char *)TA559_DN, sizeof TA559_DN, (unsigned char *)TA559_RSA_N, sizeof TA559_RSA_N, (unsigned char *)TA559_RSA_E, sizeof TA559_RSA_E); + trust_anchors[560] = make_rsa_trust_anchor((unsigned char *)TA560_DN, sizeof TA560_DN, (unsigned char *)TA560_RSA_N, sizeof TA560_RSA_N, (unsigned char *)TA560_RSA_E, sizeof TA560_RSA_E); + trust_anchors[561] = make_rsa_trust_anchor((unsigned char *)TA561_DN, sizeof TA561_DN, (unsigned char *)TA561_RSA_N, sizeof TA561_RSA_N, (unsigned char *)TA561_RSA_E, sizeof TA561_RSA_E); + trust_anchors[562] = make_rsa_trust_anchor((unsigned char *)TA562_DN, sizeof TA562_DN, (unsigned char *)TA562_RSA_N, sizeof TA562_RSA_N, (unsigned char *)TA562_RSA_E, sizeof TA562_RSA_E); + trust_anchors[563] = make_rsa_trust_anchor((unsigned char *)TA563_DN, sizeof TA563_DN, (unsigned char *)TA563_RSA_N, sizeof TA563_RSA_N, (unsigned char *)TA563_RSA_E, sizeof TA563_RSA_E); + trust_anchors[564] = make_ec_trust_anchor((unsigned char *)TA564_DN, sizeof TA564_DN, BR_EC_secp384r1, (unsigned char *)TA564_EC_Q, sizeof TA564_EC_Q); + trust_anchors[565] = make_ec_trust_anchor((unsigned char *)TA565_DN, sizeof TA565_DN, BR_EC_secp384r1, (unsigned char *)TA565_EC_Q, sizeof TA565_EC_Q); + trust_anchors[566] = make_rsa_trust_anchor((unsigned char *)TA566_DN, sizeof TA566_DN, (unsigned char *)TA566_RSA_N, sizeof TA566_RSA_N, (unsigned char *)TA566_RSA_E, sizeof TA566_RSA_E); + trust_anchors[567] = make_rsa_trust_anchor((unsigned char *)TA567_DN, sizeof TA567_DN, (unsigned char *)TA567_RSA_N, sizeof TA567_RSA_N, (unsigned char *)TA567_RSA_E, sizeof TA567_RSA_E); + trust_anchors[568] = make_rsa_trust_anchor((unsigned char *)TA568_DN, sizeof TA568_DN, (unsigned char *)TA568_RSA_N, sizeof TA568_RSA_N, (unsigned char *)TA568_RSA_E, sizeof TA568_RSA_E); + trust_anchors[569] = make_rsa_trust_anchor((unsigned char *)TA569_DN, sizeof TA569_DN, (unsigned char *)TA569_RSA_N, sizeof TA569_RSA_N, (unsigned char *)TA569_RSA_E, sizeof TA569_RSA_E); + trust_anchors[570] = make_ec_trust_anchor((unsigned char *)TA570_DN, sizeof TA570_DN, BR_EC_secp384r1, (unsigned char *)TA570_EC_Q, sizeof TA570_EC_Q); + trust_anchors[571] = make_rsa_trust_anchor((unsigned char *)TA571_DN, sizeof TA571_DN, (unsigned char *)TA571_RSA_N, sizeof TA571_RSA_N, (unsigned char *)TA571_RSA_E, sizeof TA571_RSA_E); + trust_anchors[572] = make_rsa_trust_anchor((unsigned char *)TA572_DN, sizeof TA572_DN, (unsigned char *)TA572_RSA_N, sizeof TA572_RSA_N, (unsigned char *)TA572_RSA_E, sizeof TA572_RSA_E); + trust_anchors[573] = make_rsa_trust_anchor((unsigned char *)TA573_DN, sizeof TA573_DN, (unsigned char *)TA573_RSA_N, sizeof TA573_RSA_N, (unsigned char *)TA573_RSA_E, sizeof TA573_RSA_E); + trust_anchors[574] = make_rsa_trust_anchor((unsigned char *)TA574_DN, sizeof TA574_DN, (unsigned char *)TA574_RSA_N, sizeof TA574_RSA_N, (unsigned char *)TA574_RSA_E, sizeof TA574_RSA_E); + trust_anchors[575] = make_rsa_trust_anchor((unsigned char *)TA575_DN, sizeof TA575_DN, (unsigned char *)TA575_RSA_N, sizeof TA575_RSA_N, (unsigned char *)TA575_RSA_E, sizeof TA575_RSA_E); + trust_anchors[576] = make_ec_trust_anchor((unsigned char *)TA576_DN, sizeof TA576_DN, BR_EC_secp384r1, (unsigned char *)TA576_EC_Q, sizeof TA576_EC_Q); + trust_anchors[577] = make_rsa_trust_anchor((unsigned char *)TA577_DN, sizeof TA577_DN, (unsigned char *)TA577_RSA_N, sizeof TA577_RSA_N, (unsigned char *)TA577_RSA_E, sizeof TA577_RSA_E); + trust_anchors[578] = make_rsa_trust_anchor((unsigned char *)TA578_DN, sizeof TA578_DN, (unsigned char *)TA578_RSA_N, sizeof TA578_RSA_N, (unsigned char *)TA578_RSA_E, sizeof TA578_RSA_E); + trust_anchors[579] = make_rsa_trust_anchor((unsigned char *)TA579_DN, sizeof TA579_DN, (unsigned char *)TA579_RSA_N, sizeof TA579_RSA_N, (unsigned char *)TA579_RSA_E, sizeof TA579_RSA_E); + trust_anchors[580] = make_rsa_trust_anchor((unsigned char *)TA580_DN, sizeof TA580_DN, (unsigned char *)TA580_RSA_N, sizeof TA580_RSA_N, (unsigned char *)TA580_RSA_E, sizeof TA580_RSA_E); + trust_anchors[581] = make_rsa_trust_anchor((unsigned char *)TA581_DN, sizeof TA581_DN, (unsigned char *)TA581_RSA_N, sizeof TA581_RSA_N, (unsigned char *)TA581_RSA_E, sizeof TA581_RSA_E); + trust_anchors[582] = make_rsa_trust_anchor((unsigned char *)TA582_DN, sizeof TA582_DN, (unsigned char *)TA582_RSA_N, sizeof TA582_RSA_N, (unsigned char *)TA582_RSA_E, sizeof TA582_RSA_E); + trust_anchors[583] = make_rsa_trust_anchor((unsigned char *)TA583_DN, sizeof TA583_DN, (unsigned char *)TA583_RSA_N, sizeof TA583_RSA_N, (unsigned char *)TA583_RSA_E, sizeof TA583_RSA_E); + trust_anchors[584] = make_ec_trust_anchor((unsigned char *)TA584_DN, sizeof TA584_DN, BR_EC_secp384r1, (unsigned char *)TA584_EC_Q, sizeof TA584_EC_Q); + trust_anchors[585] = make_rsa_trust_anchor((unsigned char *)TA585_DN, sizeof TA585_DN, (unsigned char *)TA585_RSA_N, sizeof TA585_RSA_N, (unsigned char *)TA585_RSA_E, sizeof TA585_RSA_E); + trust_anchors[586] = make_ec_trust_anchor((unsigned char *)TA586_DN, sizeof TA586_DN, BR_EC_secp384r1, (unsigned char *)TA586_EC_Q, sizeof TA586_EC_Q); + trust_anchors[587] = make_rsa_trust_anchor((unsigned char *)TA587_DN, sizeof TA587_DN, (unsigned char *)TA587_RSA_N, sizeof TA587_RSA_N, (unsigned char *)TA587_RSA_E, sizeof TA587_RSA_E); + trust_anchors[588] = make_rsa_trust_anchor((unsigned char *)TA588_DN, sizeof TA588_DN, (unsigned char *)TA588_RSA_N, sizeof TA588_RSA_N, (unsigned char *)TA588_RSA_E, sizeof TA588_RSA_E); + trust_anchors[589] = make_rsa_trust_anchor((unsigned char *)TA589_DN, sizeof TA589_DN, (unsigned char *)TA589_RSA_N, sizeof TA589_RSA_N, (unsigned char *)TA589_RSA_E, sizeof TA589_RSA_E); + trust_anchors[590] = make_rsa_trust_anchor((unsigned char *)TA590_DN, sizeof TA590_DN, (unsigned char *)TA590_RSA_N, sizeof TA590_RSA_N, (unsigned char *)TA590_RSA_E, sizeof TA590_RSA_E); + trust_anchors[591] = make_rsa_trust_anchor((unsigned char *)TA591_DN, sizeof TA591_DN, (unsigned char *)TA591_RSA_N, sizeof TA591_RSA_N, (unsigned char *)TA591_RSA_E, sizeof TA591_RSA_E); + trust_anchors[592] = make_ec_trust_anchor((unsigned char *)TA592_DN, sizeof TA592_DN, BR_EC_secp384r1, (unsigned char *)TA592_EC_Q, sizeof TA592_EC_Q); + trust_anchors[593] = make_ec_trust_anchor((unsigned char *)TA593_DN, sizeof TA593_DN, BR_EC_secp384r1, (unsigned char *)TA593_EC_Q, sizeof TA593_EC_Q); + trust_anchors[594] = make_ec_trust_anchor((unsigned char *)TA594_DN, sizeof TA594_DN, BR_EC_secp384r1, (unsigned char *)TA594_EC_Q, sizeof TA594_EC_Q); + trust_anchors[595] = make_rsa_trust_anchor((unsigned char *)TA595_DN, sizeof TA595_DN, (unsigned char *)TA595_RSA_N, sizeof TA595_RSA_N, (unsigned char *)TA595_RSA_E, sizeof TA595_RSA_E); + trust_anchors[596] = make_rsa_trust_anchor((unsigned char *)TA596_DN, sizeof TA596_DN, (unsigned char *)TA596_RSA_N, sizeof TA596_RSA_N, (unsigned char *)TA596_RSA_E, sizeof TA596_RSA_E); + trust_anchors[597] = make_rsa_trust_anchor((unsigned char *)TA597_DN, sizeof TA597_DN, (unsigned char *)TA597_RSA_N, sizeof TA597_RSA_N, (unsigned char *)TA597_RSA_E, sizeof TA597_RSA_E); + trust_anchors[598] = make_ec_trust_anchor((unsigned char *)TA598_DN, sizeof TA598_DN, BR_EC_secp384r1, (unsigned char *)TA598_EC_Q, sizeof TA598_EC_Q); + trust_anchors[599] = make_rsa_trust_anchor((unsigned char *)TA599_DN, sizeof TA599_DN, (unsigned char *)TA599_RSA_N, sizeof TA599_RSA_N, (unsigned char *)TA599_RSA_E, sizeof TA599_RSA_E); + trust_anchors[600] = make_rsa_trust_anchor((unsigned char *)TA600_DN, sizeof TA600_DN, (unsigned char *)TA600_RSA_N, sizeof TA600_RSA_N, (unsigned char *)TA600_RSA_E, sizeof TA600_RSA_E); + trust_anchors[601] = make_ec_trust_anchor((unsigned char *)TA601_DN, sizeof TA601_DN, BR_EC_secp384r1, (unsigned char *)TA601_EC_Q, sizeof TA601_EC_Q); + trust_anchors[602] = make_rsa_trust_anchor((unsigned char *)TA602_DN, sizeof TA602_DN, (unsigned char *)TA602_RSA_N, sizeof TA602_RSA_N, (unsigned char *)TA602_RSA_E, sizeof TA602_RSA_E); + trust_anchors[603] = make_ec_trust_anchor((unsigned char *)TA603_DN, sizeof TA603_DN, BR_EC_secp384r1, (unsigned char *)TA603_EC_Q, sizeof TA603_EC_Q); + trust_anchors[604] = make_rsa_trust_anchor((unsigned char *)TA604_DN, sizeof TA604_DN, (unsigned char *)TA604_RSA_N, sizeof TA604_RSA_N, (unsigned char *)TA604_RSA_E, sizeof TA604_RSA_E); + trust_anchors[605] = make_rsa_trust_anchor((unsigned char *)TA605_DN, sizeof TA605_DN, (unsigned char *)TA605_RSA_N, sizeof TA605_RSA_N, (unsigned char *)TA605_RSA_E, sizeof TA605_RSA_E); + trust_anchors[606] = make_ec_trust_anchor((unsigned char *)TA606_DN, sizeof TA606_DN, BR_EC_secp384r1, (unsigned char *)TA606_EC_Q, sizeof TA606_EC_Q); + trust_anchors[607] = make_rsa_trust_anchor((unsigned char *)TA607_DN, sizeof TA607_DN, (unsigned char *)TA607_RSA_N, sizeof TA607_RSA_N, (unsigned char *)TA607_RSA_E, sizeof TA607_RSA_E); + trust_anchors[608] = make_ec_trust_anchor((unsigned char *)TA608_DN, sizeof TA608_DN, BR_EC_secp384r1, (unsigned char *)TA608_EC_Q, sizeof TA608_EC_Q); + trust_anchors[609] = make_rsa_trust_anchor((unsigned char *)TA609_DN, sizeof TA609_DN, (unsigned char *)TA609_RSA_N, sizeof TA609_RSA_N, (unsigned char *)TA609_RSA_E, sizeof TA609_RSA_E); + trust_anchors[610] = make_rsa_trust_anchor((unsigned char *)TA610_DN, sizeof TA610_DN, (unsigned char *)TA610_RSA_N, sizeof TA610_RSA_N, (unsigned char *)TA610_RSA_E, sizeof TA610_RSA_E); + trust_anchors[611] = make_rsa_trust_anchor((unsigned char *)TA611_DN, sizeof TA611_DN, (unsigned char *)TA611_RSA_N, sizeof TA611_RSA_N, (unsigned char *)TA611_RSA_E, sizeof TA611_RSA_E); + trust_anchors[612] = make_rsa_trust_anchor((unsigned char *)TA612_DN, sizeof TA612_DN, (unsigned char *)TA612_RSA_N, sizeof TA612_RSA_N, (unsigned char *)TA612_RSA_E, sizeof TA612_RSA_E); + trust_anchors[613] = make_rsa_trust_anchor((unsigned char *)TA613_DN, sizeof TA613_DN, (unsigned char *)TA613_RSA_N, sizeof TA613_RSA_N, (unsigned char *)TA613_RSA_E, sizeof TA613_RSA_E); + trust_anchors[614] = make_rsa_trust_anchor((unsigned char *)TA614_DN, sizeof TA614_DN, (unsigned char *)TA614_RSA_N, sizeof TA614_RSA_N, (unsigned char *)TA614_RSA_E, sizeof TA614_RSA_E); + trust_anchors[615] = make_rsa_trust_anchor((unsigned char *)TA615_DN, sizeof TA615_DN, (unsigned char *)TA615_RSA_N, sizeof TA615_RSA_N, (unsigned char *)TA615_RSA_E, sizeof TA615_RSA_E); + trust_anchors[616] = make_rsa_trust_anchor((unsigned char *)TA616_DN, sizeof TA616_DN, (unsigned char *)TA616_RSA_N, sizeof TA616_RSA_N, (unsigned char *)TA616_RSA_E, sizeof TA616_RSA_E); + trust_anchors[617] = make_rsa_trust_anchor((unsigned char *)TA617_DN, sizeof TA617_DN, (unsigned char *)TA617_RSA_N, sizeof TA617_RSA_N, (unsigned char *)TA617_RSA_E, sizeof TA617_RSA_E); + trust_anchors[618] = make_rsa_trust_anchor((unsigned char *)TA618_DN, sizeof TA618_DN, (unsigned char *)TA618_RSA_N, sizeof TA618_RSA_N, (unsigned char *)TA618_RSA_E, sizeof TA618_RSA_E); + trust_anchors[619] = make_rsa_trust_anchor((unsigned char *)TA619_DN, sizeof TA619_DN, (unsigned char *)TA619_RSA_N, sizeof TA619_RSA_N, (unsigned char *)TA619_RSA_E, sizeof TA619_RSA_E); + trust_anchors[620] = make_rsa_trust_anchor((unsigned char *)TA620_DN, sizeof TA620_DN, (unsigned char *)TA620_RSA_N, sizeof TA620_RSA_N, (unsigned char *)TA620_RSA_E, sizeof TA620_RSA_E); + trust_anchors[621] = make_ec_trust_anchor((unsigned char *)TA621_DN, sizeof TA621_DN, BR_EC_secp384r1, (unsigned char *)TA621_EC_Q, sizeof TA621_EC_Q); + trust_anchors[622] = make_rsa_trust_anchor((unsigned char *)TA622_DN, sizeof TA622_DN, (unsigned char *)TA622_RSA_N, sizeof TA622_RSA_N, (unsigned char *)TA622_RSA_E, sizeof TA622_RSA_E); + trust_anchors[623] = make_rsa_trust_anchor((unsigned char *)TA623_DN, sizeof TA623_DN, (unsigned char *)TA623_RSA_N, sizeof TA623_RSA_N, (unsigned char *)TA623_RSA_E, sizeof TA623_RSA_E); + trust_anchors[624] = make_ec_trust_anchor((unsigned char *)TA624_DN, sizeof TA624_DN, BR_EC_secp256r1, (unsigned char *)TA624_EC_Q, sizeof TA624_EC_Q); + trust_anchors[625] = make_rsa_trust_anchor((unsigned char *)TA625_DN, sizeof TA625_DN, (unsigned char *)TA625_RSA_N, sizeof TA625_RSA_N, (unsigned char *)TA625_RSA_E, sizeof TA625_RSA_E); + trust_anchors[626] = make_ec_trust_anchor((unsigned char *)TA626_DN, sizeof TA626_DN, BR_EC_secp384r1, (unsigned char *)TA626_EC_Q, sizeof TA626_EC_Q); + trust_anchors[627] = make_ec_trust_anchor((unsigned char *)TA627_DN, sizeof TA627_DN, BR_EC_secp384r1, (unsigned char *)TA627_EC_Q, sizeof TA627_EC_Q); + trust_anchors[628] = make_ec_trust_anchor((unsigned char *)TA628_DN, sizeof TA628_DN, BR_EC_secp384r1, (unsigned char *)TA628_EC_Q, sizeof TA628_EC_Q); + trust_anchors[629] = make_rsa_trust_anchor((unsigned char *)TA629_DN, sizeof TA629_DN, (unsigned char *)TA629_RSA_N, sizeof TA629_RSA_N, (unsigned char *)TA629_RSA_E, sizeof TA629_RSA_E); + trust_anchors[630] = make_rsa_trust_anchor((unsigned char *)TA630_DN, sizeof TA630_DN, (unsigned char *)TA630_RSA_N, sizeof TA630_RSA_N, (unsigned char *)TA630_RSA_E, sizeof TA630_RSA_E); + trust_anchors[631] = make_ec_trust_anchor((unsigned char *)TA631_DN, sizeof TA631_DN, BR_EC_secp384r1, (unsigned char *)TA631_EC_Q, sizeof TA631_EC_Q); + trust_anchors[632] = make_rsa_trust_anchor((unsigned char *)TA632_DN, sizeof TA632_DN, (unsigned char *)TA632_RSA_N, sizeof TA632_RSA_N, (unsigned char *)TA632_RSA_E, sizeof TA632_RSA_E); + trust_anchors[633] = make_ec_trust_anchor((unsigned char *)TA633_DN, sizeof TA633_DN, BR_EC_secp384r1, (unsigned char *)TA633_EC_Q, sizeof TA633_EC_Q); + trust_anchors[634] = make_rsa_trust_anchor((unsigned char *)TA634_DN, sizeof TA634_DN, (unsigned char *)TA634_RSA_N, sizeof TA634_RSA_N, (unsigned char *)TA634_RSA_E, sizeof TA634_RSA_E); + trust_anchors[635] = make_ec_trust_anchor((unsigned char *)TA635_DN, sizeof TA635_DN, BR_EC_secp384r1, (unsigned char *)TA635_EC_Q, sizeof TA635_EC_Q); + trust_anchors[636] = make_ec_trust_anchor((unsigned char *)TA636_DN, sizeof TA636_DN, BR_EC_secp384r1, (unsigned char *)TA636_EC_Q, sizeof TA636_EC_Q); + trust_anchors[637] = make_rsa_trust_anchor((unsigned char *)TA637_DN, sizeof TA637_DN, (unsigned char *)TA637_RSA_N, sizeof TA637_RSA_N, (unsigned char *)TA637_RSA_E, sizeof TA637_RSA_E); + trust_anchors[638] = make_rsa_trust_anchor((unsigned char *)TA638_DN, sizeof TA638_DN, (unsigned char *)TA638_RSA_N, sizeof TA638_RSA_N, (unsigned char *)TA638_RSA_E, sizeof TA638_RSA_E); + trust_anchors[639] = make_rsa_trust_anchor((unsigned char *)TA639_DN, sizeof TA639_DN, (unsigned char *)TA639_RSA_N, sizeof TA639_RSA_N, (unsigned char *)TA639_RSA_E, sizeof TA639_RSA_E); + trust_anchors[640] = make_ec_trust_anchor((unsigned char *)TA640_DN, sizeof TA640_DN, BR_EC_secp384r1, (unsigned char *)TA640_EC_Q, sizeof TA640_EC_Q); + trust_anchors[641] = make_rsa_trust_anchor((unsigned char *)TA641_DN, sizeof TA641_DN, (unsigned char *)TA641_RSA_N, sizeof TA641_RSA_N, (unsigned char *)TA641_RSA_E, sizeof TA641_RSA_E); + trust_anchors[642] = make_rsa_trust_anchor((unsigned char *)TA642_DN, sizeof TA642_DN, (unsigned char *)TA642_RSA_N, sizeof TA642_RSA_N, (unsigned char *)TA642_RSA_E, sizeof TA642_RSA_E); + trust_anchors[643] = make_rsa_trust_anchor((unsigned char *)TA643_DN, sizeof TA643_DN, (unsigned char *)TA643_RSA_N, sizeof TA643_RSA_N, (unsigned char *)TA643_RSA_E, sizeof TA643_RSA_E); + trust_anchors[644] = make_ec_trust_anchor((unsigned char *)TA644_DN, sizeof TA644_DN, BR_EC_secp256r1, (unsigned char *)TA644_EC_Q, sizeof TA644_EC_Q); + trust_anchors[645] = make_rsa_trust_anchor((unsigned char *)TA645_DN, sizeof TA645_DN, (unsigned char *)TA645_RSA_N, sizeof TA645_RSA_N, (unsigned char *)TA645_RSA_E, sizeof TA645_RSA_E); + trust_anchors[646] = make_rsa_trust_anchor((unsigned char *)TA646_DN, sizeof TA646_DN, (unsigned char *)TA646_RSA_N, sizeof TA646_RSA_N, (unsigned char *)TA646_RSA_E, sizeof TA646_RSA_E); + trust_anchors[647] = make_rsa_trust_anchor((unsigned char *)TA647_DN, sizeof TA647_DN, (unsigned char *)TA647_RSA_N, sizeof TA647_RSA_N, (unsigned char *)TA647_RSA_E, sizeof TA647_RSA_E); + trust_anchors[648] = make_ec_trust_anchor((unsigned char *)TA648_DN, sizeof TA648_DN, BR_EC_secp384r1, (unsigned char *)TA648_EC_Q, sizeof TA648_EC_Q); + trust_anchors[649] = make_rsa_trust_anchor((unsigned char *)TA649_DN, sizeof TA649_DN, (unsigned char *)TA649_RSA_N, sizeof TA649_RSA_N, (unsigned char *)TA649_RSA_E, sizeof TA649_RSA_E); + trust_anchors[650] = make_ec_trust_anchor((unsigned char *)TA650_DN, sizeof TA650_DN, BR_EC_secp384r1, (unsigned char *)TA650_EC_Q, sizeof TA650_EC_Q); + trust_anchors[651] = make_rsa_trust_anchor((unsigned char *)TA651_DN, sizeof TA651_DN, (unsigned char *)TA651_RSA_N, sizeof TA651_RSA_N, (unsigned char *)TA651_RSA_E, sizeof TA651_RSA_E); + trust_anchors[652] = make_rsa_trust_anchor((unsigned char *)TA652_DN, sizeof TA652_DN, (unsigned char *)TA652_RSA_N, sizeof TA652_RSA_N, (unsigned char *)TA652_RSA_E, sizeof TA652_RSA_E); + trust_anchors[653] = make_rsa_trust_anchor((unsigned char *)TA653_DN, sizeof TA653_DN, (unsigned char *)TA653_RSA_N, sizeof TA653_RSA_N, (unsigned char *)TA653_RSA_E, sizeof TA653_RSA_E); + trust_anchors[654] = make_rsa_trust_anchor((unsigned char *)TA654_DN, sizeof TA654_DN, (unsigned char *)TA654_RSA_N, sizeof TA654_RSA_N, (unsigned char *)TA654_RSA_E, sizeof TA654_RSA_E); + trust_anchors[655] = make_rsa_trust_anchor((unsigned char *)TA655_DN, sizeof TA655_DN, (unsigned char *)TA655_RSA_N, sizeof TA655_RSA_N, (unsigned char *)TA655_RSA_E, sizeof TA655_RSA_E); + trust_anchors[656] = make_rsa_trust_anchor((unsigned char *)TA656_DN, sizeof TA656_DN, (unsigned char *)TA656_RSA_N, sizeof TA656_RSA_N, (unsigned char *)TA656_RSA_E, sizeof TA656_RSA_E); + trust_anchors[657] = make_rsa_trust_anchor((unsigned char *)TA657_DN, sizeof TA657_DN, (unsigned char *)TA657_RSA_N, sizeof TA657_RSA_N, (unsigned char *)TA657_RSA_E, sizeof TA657_RSA_E); + trust_anchors[658] = make_ec_trust_anchor((unsigned char *)TA658_DN, sizeof TA658_DN, BR_EC_secp384r1, (unsigned char *)TA658_EC_Q, sizeof TA658_EC_Q); + trust_anchors[659] = make_rsa_trust_anchor((unsigned char *)TA659_DN, sizeof TA659_DN, (unsigned char *)TA659_RSA_N, sizeof TA659_RSA_N, (unsigned char *)TA659_RSA_E, sizeof TA659_RSA_E); + trust_anchors[660] = make_rsa_trust_anchor((unsigned char *)TA660_DN, sizeof TA660_DN, (unsigned char *)TA660_RSA_N, sizeof TA660_RSA_N, (unsigned char *)TA660_RSA_E, sizeof TA660_RSA_E); + trust_anchors[661] = make_rsa_trust_anchor((unsigned char *)TA661_DN, sizeof TA661_DN, (unsigned char *)TA661_RSA_N, sizeof TA661_RSA_N, (unsigned char *)TA661_RSA_E, sizeof TA661_RSA_E); + trust_anchors[662] = make_rsa_trust_anchor((unsigned char *)TA662_DN, sizeof TA662_DN, (unsigned char *)TA662_RSA_N, sizeof TA662_RSA_N, (unsigned char *)TA662_RSA_E, sizeof TA662_RSA_E); + trust_anchors[663] = make_rsa_trust_anchor((unsigned char *)TA663_DN, sizeof TA663_DN, (unsigned char *)TA663_RSA_N, sizeof TA663_RSA_N, (unsigned char *)TA663_RSA_E, sizeof TA663_RSA_E); + trust_anchors[664] = make_ec_trust_anchor((unsigned char *)TA664_DN, sizeof TA664_DN, BR_EC_secp384r1, (unsigned char *)TA664_EC_Q, sizeof TA664_EC_Q); + trust_anchors[665] = make_rsa_trust_anchor((unsigned char *)TA665_DN, sizeof TA665_DN, (unsigned char *)TA665_RSA_N, sizeof TA665_RSA_N, (unsigned char *)TA665_RSA_E, sizeof TA665_RSA_E); + trust_anchors[666] = make_rsa_trust_anchor((unsigned char *)TA666_DN, sizeof TA666_DN, (unsigned char *)TA666_RSA_N, sizeof TA666_RSA_N, (unsigned char *)TA666_RSA_E, sizeof TA666_RSA_E); + trust_anchors[667] = make_rsa_trust_anchor((unsigned char *)TA667_DN, sizeof TA667_DN, (unsigned char *)TA667_RSA_N, sizeof TA667_RSA_N, (unsigned char *)TA667_RSA_E, sizeof TA667_RSA_E); + trust_anchors[668] = make_ec_trust_anchor((unsigned char *)TA668_DN, sizeof TA668_DN, BR_EC_secp384r1, (unsigned char *)TA668_EC_Q, sizeof TA668_EC_Q); + trust_anchors[669] = make_rsa_trust_anchor((unsigned char *)TA669_DN, sizeof TA669_DN, (unsigned char *)TA669_RSA_N, sizeof TA669_RSA_N, (unsigned char *)TA669_RSA_E, sizeof TA669_RSA_E); + trust_anchors[670] = make_ec_trust_anchor((unsigned char *)TA670_DN, sizeof TA670_DN, BR_EC_secp256r1, (unsigned char *)TA670_EC_Q, sizeof TA670_EC_Q); + trust_anchors[671] = make_ec_trust_anchor((unsigned char *)TA671_DN, sizeof TA671_DN, BR_EC_secp384r1, (unsigned char *)TA671_EC_Q, sizeof TA671_EC_Q); + trust_anchors[672] = make_rsa_trust_anchor((unsigned char *)TA672_DN, sizeof TA672_DN, (unsigned char *)TA672_RSA_N, sizeof TA672_RSA_N, (unsigned char *)TA672_RSA_E, sizeof TA672_RSA_E); + trust_anchors[673] = make_rsa_trust_anchor((unsigned char *)TA673_DN, sizeof TA673_DN, (unsigned char *)TA673_RSA_N, sizeof TA673_RSA_N, (unsigned char *)TA673_RSA_E, sizeof TA673_RSA_E); + trust_anchors[674] = make_rsa_trust_anchor((unsigned char *)TA674_DN, sizeof TA674_DN, (unsigned char *)TA674_RSA_N, sizeof TA674_RSA_N, (unsigned char *)TA674_RSA_E, sizeof TA674_RSA_E); + trust_anchors[675] = make_ec_trust_anchor((unsigned char *)TA675_DN, sizeof TA675_DN, BR_EC_secp384r1, (unsigned char *)TA675_EC_Q, sizeof TA675_EC_Q); + trust_anchors[676] = make_rsa_trust_anchor((unsigned char *)TA676_DN, sizeof TA676_DN, (unsigned char *)TA676_RSA_N, sizeof TA676_RSA_N, (unsigned char *)TA676_RSA_E, sizeof TA676_RSA_E); + trust_anchors[677] = make_rsa_trust_anchor((unsigned char *)TA677_DN, sizeof TA677_DN, (unsigned char *)TA677_RSA_N, sizeof TA677_RSA_N, (unsigned char *)TA677_RSA_E, sizeof TA677_RSA_E); + trust_anchors[678] = make_rsa_trust_anchor((unsigned char *)TA678_DN, sizeof TA678_DN, (unsigned char *)TA678_RSA_N, sizeof TA678_RSA_N, (unsigned char *)TA678_RSA_E, sizeof TA678_RSA_E); + trust_anchors[679] = make_rsa_trust_anchor((unsigned char *)TA679_DN, sizeof TA679_DN, (unsigned char *)TA679_RSA_N, sizeof TA679_RSA_N, (unsigned char *)TA679_RSA_E, sizeof TA679_RSA_E); + trust_anchors[680] = make_rsa_trust_anchor((unsigned char *)TA680_DN, sizeof TA680_DN, (unsigned char *)TA680_RSA_N, sizeof TA680_RSA_N, (unsigned char *)TA680_RSA_E, sizeof TA680_RSA_E); + trust_anchors[681] = make_rsa_trust_anchor((unsigned char *)TA681_DN, sizeof TA681_DN, (unsigned char *)TA681_RSA_N, sizeof TA681_RSA_N, (unsigned char *)TA681_RSA_E, sizeof TA681_RSA_E); + trust_anchors[682] = make_ec_trust_anchor((unsigned char *)TA682_DN, sizeof TA682_DN, BR_EC_secp384r1, (unsigned char *)TA682_EC_Q, sizeof TA682_EC_Q); + trust_anchors[683] = make_ec_trust_anchor((unsigned char *)TA683_DN, sizeof TA683_DN, BR_EC_secp384r1, (unsigned char *)TA683_EC_Q, sizeof TA683_EC_Q); + trust_anchors[684] = make_ec_trust_anchor((unsigned char *)TA684_DN, sizeof TA684_DN, BR_EC_secp384r1, (unsigned char *)TA684_EC_Q, sizeof TA684_EC_Q); + trust_anchors[685] = make_rsa_trust_anchor((unsigned char *)TA685_DN, sizeof TA685_DN, (unsigned char *)TA685_RSA_N, sizeof TA685_RSA_N, (unsigned char *)TA685_RSA_E, sizeof TA685_RSA_E); + trust_anchors[686] = make_ec_trust_anchor((unsigned char *)TA686_DN, sizeof TA686_DN, BR_EC_secp384r1, (unsigned char *)TA686_EC_Q, sizeof TA686_EC_Q); + trust_anchors[687] = make_rsa_trust_anchor((unsigned char *)TA687_DN, sizeof TA687_DN, (unsigned char *)TA687_RSA_N, sizeof TA687_RSA_N, (unsigned char *)TA687_RSA_E, sizeof TA687_RSA_E); + trust_anchors[688] = make_rsa_trust_anchor((unsigned char *)TA688_DN, sizeof TA688_DN, (unsigned char *)TA688_RSA_N, sizeof TA688_RSA_N, (unsigned char *)TA688_RSA_E, sizeof TA688_RSA_E); + trust_anchors[689] = make_rsa_trust_anchor((unsigned char *)TA689_DN, sizeof TA689_DN, (unsigned char *)TA689_RSA_N, sizeof TA689_RSA_N, (unsigned char *)TA689_RSA_E, sizeof TA689_RSA_E); + trust_anchors[690] = make_rsa_trust_anchor((unsigned char *)TA690_DN, sizeof TA690_DN, (unsigned char *)TA690_RSA_N, sizeof TA690_RSA_N, (unsigned char *)TA690_RSA_E, sizeof TA690_RSA_E); + trust_anchors[691] = make_rsa_trust_anchor((unsigned char *)TA691_DN, sizeof TA691_DN, (unsigned char *)TA691_RSA_N, sizeof TA691_RSA_N, (unsigned char *)TA691_RSA_E, sizeof TA691_RSA_E); + trust_anchors[692] = make_rsa_trust_anchor((unsigned char *)TA692_DN, sizeof TA692_DN, (unsigned char *)TA692_RSA_N, sizeof TA692_RSA_N, (unsigned char *)TA692_RSA_E, sizeof TA692_RSA_E); + trust_anchors[693] = make_ec_trust_anchor((unsigned char *)TA693_DN, sizeof TA693_DN, BR_EC_secp384r1, (unsigned char *)TA693_EC_Q, sizeof TA693_EC_Q); + trust_anchors[694] = make_rsa_trust_anchor((unsigned char *)TA694_DN, sizeof TA694_DN, (unsigned char *)TA694_RSA_N, sizeof TA694_RSA_N, (unsigned char *)TA694_RSA_E, sizeof TA694_RSA_E); + trust_anchors[695] = make_rsa_trust_anchor((unsigned char *)TA695_DN, sizeof TA695_DN, (unsigned char *)TA695_RSA_N, sizeof TA695_RSA_N, (unsigned char *)TA695_RSA_E, sizeof TA695_RSA_E); + trust_anchors[696] = make_ec_trust_anchor((unsigned char *)TA696_DN, sizeof TA696_DN, BR_EC_secp384r1, (unsigned char *)TA696_EC_Q, sizeof TA696_EC_Q); + trust_anchors[697] = make_rsa_trust_anchor((unsigned char *)TA697_DN, sizeof TA697_DN, (unsigned char *)TA697_RSA_N, sizeof TA697_RSA_N, (unsigned char *)TA697_RSA_E, sizeof TA697_RSA_E); + trust_anchors[698] = make_rsa_trust_anchor((unsigned char *)TA698_DN, sizeof TA698_DN, (unsigned char *)TA698_RSA_N, sizeof TA698_RSA_N, (unsigned char *)TA698_RSA_E, sizeof TA698_RSA_E); + trust_anchors[699] = make_rsa_trust_anchor((unsigned char *)TA699_DN, sizeof TA699_DN, (unsigned char *)TA699_RSA_N, sizeof TA699_RSA_N, (unsigned char *)TA699_RSA_E, sizeof TA699_RSA_E); + trust_anchors[700] = make_rsa_trust_anchor((unsigned char *)TA700_DN, sizeof TA700_DN, (unsigned char *)TA700_RSA_N, sizeof TA700_RSA_N, (unsigned char *)TA700_RSA_E, sizeof TA700_RSA_E); + trust_anchors[701] = make_ec_trust_anchor((unsigned char *)TA701_DN, sizeof TA701_DN, BR_EC_secp384r1, (unsigned char *)TA701_EC_Q, sizeof TA701_EC_Q); + trust_anchors[702] = make_rsa_trust_anchor((unsigned char *)TA702_DN, sizeof TA702_DN, (unsigned char *)TA702_RSA_N, sizeof TA702_RSA_N, (unsigned char *)TA702_RSA_E, sizeof TA702_RSA_E); + trust_anchors[703] = make_rsa_trust_anchor((unsigned char *)TA703_DN, sizeof TA703_DN, (unsigned char *)TA703_RSA_N, sizeof TA703_RSA_N, (unsigned char *)TA703_RSA_E, sizeof TA703_RSA_E); + trust_anchors[704] = make_rsa_trust_anchor((unsigned char *)TA704_DN, sizeof TA704_DN, (unsigned char *)TA704_RSA_N, sizeof TA704_RSA_N, (unsigned char *)TA704_RSA_E, sizeof TA704_RSA_E); + trust_anchors[705] = make_rsa_trust_anchor((unsigned char *)TA705_DN, sizeof TA705_DN, (unsigned char *)TA705_RSA_N, sizeof TA705_RSA_N, (unsigned char *)TA705_RSA_E, sizeof TA705_RSA_E); + trust_anchors[706] = make_rsa_trust_anchor((unsigned char *)TA706_DN, sizeof TA706_DN, (unsigned char *)TA706_RSA_N, sizeof TA706_RSA_N, (unsigned char *)TA706_RSA_E, sizeof TA706_RSA_E); + trust_anchors[707] = make_ec_trust_anchor((unsigned char *)TA707_DN, sizeof TA707_DN, BR_EC_secp384r1, (unsigned char *)TA707_EC_Q, sizeof TA707_EC_Q); + trust_anchors[708] = make_rsa_trust_anchor((unsigned char *)TA708_DN, sizeof TA708_DN, (unsigned char *)TA708_RSA_N, sizeof TA708_RSA_N, (unsigned char *)TA708_RSA_E, sizeof TA708_RSA_E); + trust_anchors[709] = make_rsa_trust_anchor((unsigned char *)TA709_DN, sizeof TA709_DN, (unsigned char *)TA709_RSA_N, sizeof TA709_RSA_N, (unsigned char *)TA709_RSA_E, sizeof TA709_RSA_E); + trust_anchors[710] = make_rsa_trust_anchor((unsigned char *)TA710_DN, sizeof TA710_DN, (unsigned char *)TA710_RSA_N, sizeof TA710_RSA_N, (unsigned char *)TA710_RSA_E, sizeof TA710_RSA_E); + trust_anchors[711] = make_rsa_trust_anchor((unsigned char *)TA711_DN, sizeof TA711_DN, (unsigned char *)TA711_RSA_N, sizeof TA711_RSA_N, (unsigned char *)TA711_RSA_E, sizeof TA711_RSA_E); + trust_anchors[712] = make_ec_trust_anchor((unsigned char *)TA712_DN, sizeof TA712_DN, BR_EC_secp384r1, (unsigned char *)TA712_EC_Q, sizeof TA712_EC_Q); + trust_anchors[713] = make_rsa_trust_anchor((unsigned char *)TA713_DN, sizeof TA713_DN, (unsigned char *)TA713_RSA_N, sizeof TA713_RSA_N, (unsigned char *)TA713_RSA_E, sizeof TA713_RSA_E); + trust_anchors[714] = make_ec_trust_anchor((unsigned char *)TA714_DN, sizeof TA714_DN, BR_EC_secp384r1, (unsigned char *)TA714_EC_Q, sizeof TA714_EC_Q); + trust_anchors[715] = make_rsa_trust_anchor((unsigned char *)TA715_DN, sizeof TA715_DN, (unsigned char *)TA715_RSA_N, sizeof TA715_RSA_N, (unsigned char *)TA715_RSA_E, sizeof TA715_RSA_E); + trust_anchors[716] = make_ec_trust_anchor((unsigned char *)TA716_DN, sizeof TA716_DN, BR_EC_secp384r1, (unsigned char *)TA716_EC_Q, sizeof TA716_EC_Q); + trust_anchors[717] = make_rsa_trust_anchor((unsigned char *)TA717_DN, sizeof TA717_DN, (unsigned char *)TA717_RSA_N, sizeof TA717_RSA_N, (unsigned char *)TA717_RSA_E, sizeof TA717_RSA_E); + trust_anchors[718] = make_ec_trust_anchor((unsigned char *)TA718_DN, sizeof TA718_DN, BR_EC_secp384r1, (unsigned char *)TA718_EC_Q, sizeof TA718_EC_Q); + trust_anchors[719] = make_rsa_trust_anchor((unsigned char *)TA719_DN, sizeof TA719_DN, (unsigned char *)TA719_RSA_N, sizeof TA719_RSA_N, (unsigned char *)TA719_RSA_E, sizeof TA719_RSA_E); + trust_anchors[720] = make_ec_trust_anchor((unsigned char *)TA720_DN, sizeof TA720_DN, BR_EC_secp384r1, (unsigned char *)TA720_EC_Q, sizeof TA720_EC_Q); + trust_anchors[721] = make_rsa_trust_anchor((unsigned char *)TA721_DN, sizeof TA721_DN, (unsigned char *)TA721_RSA_N, sizeof TA721_RSA_N, (unsigned char *)TA721_RSA_E, sizeof TA721_RSA_E); + trust_anchors[722] = make_rsa_trust_anchor((unsigned char *)TA722_DN, sizeof TA722_DN, (unsigned char *)TA722_RSA_N, sizeof TA722_RSA_N, (unsigned char *)TA722_RSA_E, sizeof TA722_RSA_E); + trust_anchors[723] = make_rsa_trust_anchor((unsigned char *)TA723_DN, sizeof TA723_DN, (unsigned char *)TA723_RSA_N, sizeof TA723_RSA_N, (unsigned char *)TA723_RSA_E, sizeof TA723_RSA_E); + trust_anchors[724] = make_rsa_trust_anchor((unsigned char *)TA724_DN, sizeof TA724_DN, (unsigned char *)TA724_RSA_N, sizeof TA724_RSA_N, (unsigned char *)TA724_RSA_E, sizeof TA724_RSA_E); + trust_anchors[725] = make_rsa_trust_anchor((unsigned char *)TA725_DN, sizeof TA725_DN, (unsigned char *)TA725_RSA_N, sizeof TA725_RSA_N, (unsigned char *)TA725_RSA_E, sizeof TA725_RSA_E); + trust_anchors[726] = make_rsa_trust_anchor((unsigned char *)TA726_DN, sizeof TA726_DN, (unsigned char *)TA726_RSA_N, sizeof TA726_RSA_N, (unsigned char *)TA726_RSA_E, sizeof TA726_RSA_E); + trust_anchors[727] = make_ec_trust_anchor((unsigned char *)TA727_DN, sizeof TA727_DN, BR_EC_secp384r1, (unsigned char *)TA727_EC_Q, sizeof TA727_EC_Q); + trust_anchors[728] = make_rsa_trust_anchor((unsigned char *)TA728_DN, sizeof TA728_DN, (unsigned char *)TA728_RSA_N, sizeof TA728_RSA_N, (unsigned char *)TA728_RSA_E, sizeof TA728_RSA_E); + trust_anchors[729] = make_rsa_trust_anchor((unsigned char *)TA729_DN, sizeof TA729_DN, (unsigned char *)TA729_RSA_N, sizeof TA729_RSA_N, (unsigned char *)TA729_RSA_E, sizeof TA729_RSA_E); + trust_anchors[730] = make_rsa_trust_anchor((unsigned char *)TA730_DN, sizeof TA730_DN, (unsigned char *)TA730_RSA_N, sizeof TA730_RSA_N, (unsigned char *)TA730_RSA_E, sizeof TA730_RSA_E); + trust_anchors[731] = make_rsa_trust_anchor((unsigned char *)TA731_DN, sizeof TA731_DN, (unsigned char *)TA731_RSA_N, sizeof TA731_RSA_N, (unsigned char *)TA731_RSA_E, sizeof TA731_RSA_E); + trust_anchors[732] = make_ec_trust_anchor((unsigned char *)TA732_DN, sizeof TA732_DN, BR_EC_secp384r1, (unsigned char *)TA732_EC_Q, sizeof TA732_EC_Q); + trust_anchors[733] = make_rsa_trust_anchor((unsigned char *)TA733_DN, sizeof TA733_DN, (unsigned char *)TA733_RSA_N, sizeof TA733_RSA_N, (unsigned char *)TA733_RSA_E, sizeof TA733_RSA_E); + trust_anchors[734] = make_ec_trust_anchor((unsigned char *)TA734_DN, sizeof TA734_DN, BR_EC_secp256r1, (unsigned char *)TA734_EC_Q, sizeof TA734_EC_Q); + trust_anchors[735] = make_ec_trust_anchor((unsigned char *)TA735_DN, sizeof TA735_DN, BR_EC_secp384r1, (unsigned char *)TA735_EC_Q, sizeof TA735_EC_Q); + trust_anchors[736] = make_rsa_trust_anchor((unsigned char *)TA736_DN, sizeof TA736_DN, (unsigned char *)TA736_RSA_N, sizeof TA736_RSA_N, (unsigned char *)TA736_RSA_E, sizeof TA736_RSA_E); + trust_anchors[737] = make_rsa_trust_anchor((unsigned char *)TA737_DN, sizeof TA737_DN, (unsigned char *)TA737_RSA_N, sizeof TA737_RSA_N, (unsigned char *)TA737_RSA_E, sizeof TA737_RSA_E); + trust_anchors[738] = make_rsa_trust_anchor((unsigned char *)TA738_DN, sizeof TA738_DN, (unsigned char *)TA738_RSA_N, sizeof TA738_RSA_N, (unsigned char *)TA738_RSA_E, sizeof TA738_RSA_E); + trust_anchors[739] = make_rsa_trust_anchor((unsigned char *)TA739_DN, sizeof TA739_DN, (unsigned char *)TA739_RSA_N, sizeof TA739_RSA_N, (unsigned char *)TA739_RSA_E, sizeof TA739_RSA_E); + trust_anchors[740] = make_rsa_trust_anchor((unsigned char *)TA740_DN, sizeof TA740_DN, (unsigned char *)TA740_RSA_N, sizeof TA740_RSA_N, (unsigned char *)TA740_RSA_E, sizeof TA740_RSA_E); + trust_anchors[741] = make_rsa_trust_anchor((unsigned char *)TA741_DN, sizeof TA741_DN, (unsigned char *)TA741_RSA_N, sizeof TA741_RSA_N, (unsigned char *)TA741_RSA_E, sizeof TA741_RSA_E); + trust_anchors[742] = make_rsa_trust_anchor((unsigned char *)TA742_DN, sizeof TA742_DN, (unsigned char *)TA742_RSA_N, sizeof TA742_RSA_N, (unsigned char *)TA742_RSA_E, sizeof TA742_RSA_E); + trust_anchors[743] = make_rsa_trust_anchor((unsigned char *)TA743_DN, sizeof TA743_DN, (unsigned char *)TA743_RSA_N, sizeof TA743_RSA_N, (unsigned char *)TA743_RSA_E, sizeof TA743_RSA_E); + trust_anchors[744] = make_rsa_trust_anchor((unsigned char *)TA744_DN, sizeof TA744_DN, (unsigned char *)TA744_RSA_N, sizeof TA744_RSA_N, (unsigned char *)TA744_RSA_E, sizeof TA744_RSA_E); + trust_anchors[745] = make_ec_trust_anchor((unsigned char *)TA745_DN, sizeof TA745_DN, BR_EC_secp384r1, (unsigned char *)TA745_EC_Q, sizeof TA745_EC_Q); + trust_anchors[746] = make_rsa_trust_anchor((unsigned char *)TA746_DN, sizeof TA746_DN, (unsigned char *)TA746_RSA_N, sizeof TA746_RSA_N, (unsigned char *)TA746_RSA_E, sizeof TA746_RSA_E); + trust_anchors[747] = make_ec_trust_anchor((unsigned char *)TA747_DN, sizeof TA747_DN, BR_EC_secp384r1, (unsigned char *)TA747_EC_Q, sizeof TA747_EC_Q); + trust_anchors[748] = make_rsa_trust_anchor((unsigned char *)TA748_DN, sizeof TA748_DN, (unsigned char *)TA748_RSA_N, sizeof TA748_RSA_N, (unsigned char *)TA748_RSA_E, sizeof TA748_RSA_E); + trust_anchors[749] = make_rsa_trust_anchor((unsigned char *)TA749_DN, sizeof TA749_DN, (unsigned char *)TA749_RSA_N, sizeof TA749_RSA_N, (unsigned char *)TA749_RSA_E, sizeof TA749_RSA_E); +} + +void certificates::close_trust_anchors() +{ + if (trust_anchors == NULL) + { + return; + } + if (loaded_from_file) + { + ca_loader::free_trust_anchors(trust_anchors, (size_t)trust_anchor_count); + } + else + { + free(trust_anchors); + } + trust_anchors = NULL; + trust_anchor_count = 0; + loaded_from_file = 0; +} + +br_x509_trust_anchor* certificates::get_trust_anchors() +{ + return trust_anchors; +} + +int certificates::get_num_trust_anchors() +{ + return trust_anchor_count; +} + +int certificates::load_from_file(const char *path) +{ + br_x509_trust_anchor *file_anchors = NULL; + size_t file_count = 0; + + if (ca_loader::load_pem_file(path, &file_anchors, &file_count) != 0) + { + return -1; + } + + /* Release any existing trust anchors */ + close_trust_anchors(); + + trust_anchors = file_anchors; + trust_anchor_count = (int)file_count; + loaded_from_file = 1; + return 0; +} + +// Private + +br_x509_trust_anchor certificates::make_rsa_trust_anchor(unsigned char *dn, size_t dn_len, unsigned char *n, size_t n_len, unsigned char *e, size_t e_len) +{ + br_x509_trust_anchor ta; + ta.dn.data = dn; + ta.dn.len = dn_len; + ta.flags = BR_X509_TA_CA; + ta.pkey.key_type = BR_KEYTYPE_RSA; + ta.pkey.key.rsa.n = n; + ta.pkey.key.rsa.nlen = n_len; + ta.pkey.key.rsa.e = e; + ta.pkey.key.rsa.elen = e_len; + return ta; +} + +br_x509_trust_anchor certificates::make_ec_trust_anchor(unsigned char *dn, size_t dn_len, int curve, unsigned char *q, size_t q_len) +{ + br_x509_trust_anchor ta; + ta.dn.data = dn; + ta.dn.len = dn_len; + ta.flags = BR_X509_TA_CA; + ta.pkey.key_type = BR_KEYTYPE_EC; + ta.pkey.key.ec.curve = curve; + ta.pkey.key.ec.q = q; + ta.pkey.key.ec.qlen = q_len; + return ta; +} diff --git a/libcurl/lib/vtls/certificates.h b/libcurl/lib/vtls/certificates.h new file mode 100644 index 0000000..def3705 --- /dev/null +++ b/libcurl/lib/vtls/certificates.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +class certificates +{ +public: + static void initialize_trust_anchors(); + static void close_trust_anchors(); + static br_x509_trust_anchor* get_trust_anchors(); + static int get_num_trust_anchors(); + + /* + * Try to load trust anchors from a PEM CA bundle file. + * If successful, replaces the compiled-in trust store. + * Returns 0 on success, -1 on failure (compiled-in CAs unchanged). + */ + static int load_from_file(const char *path); + +private: + static br_x509_trust_anchor make_rsa_trust_anchor(unsigned char *dn, size_t dn_len, unsigned char *n, size_t n_len, unsigned char *e, size_t e_len); + static br_x509_trust_anchor make_ec_trust_anchor(unsigned char *dn, size_t dn_len, int curve, unsigned char *q, size_t q_len); +}; diff --git a/libcurl/lib/vtls/cyassl.c b/libcurl/lib/vtls/cyassl.c new file mode 100644 index 0000000..01bfdab --- /dev/null +++ b/libcurl/lib/vtls/cyassl.c @@ -0,0 +1,954 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all CyaSSL-specific code for the TLS/SSL layer. No code + * but vtls.c should ever call or use these functions. + * + */ + +#include "curl_setup.h" + +#ifdef USE_CYASSL + +#define WOLFSSL_OPTIONS_IGNORE_SYS +/* CyaSSL's version.h, which should contain only the version, should come +before all other CyaSSL includes and be immediately followed by build config +aka options.h. https://curl.haxx.se/mail/lib-2015-04/0069.html */ +#include +#if defined(HAVE_CYASSL_OPTIONS_H) && (LIBCYASSL_VERSION_HEX > 0x03004008) +#if defined(CYASSL_API) || defined(WOLFSSL_API) +/* Safety measure. If either is defined some API include was already included +and that's a problem since options.h hasn't been included yet. */ +#error "CyaSSL API was included before the CyaSSL build options." +#endif +#include +#endif + +/* To determine what functions are available we rely on one or both of: + - the user's options.h generated by CyaSSL/wolfSSL + - the symbols detected by curl's configure + Since they are markedly different from one another, and one or the other may + not be available, we do some checking below to bring things in sync. */ + +/* HAVE_ALPN is wolfSSL's build time symbol for enabling ALPN in options.h. */ +#ifndef HAVE_ALPN +#ifdef HAVE_WOLFSSL_USEALPN +#define HAVE_ALPN +#endif +#endif + +/* WOLFSSL_ALLOW_SSLV3 is wolfSSL's build time symbol for enabling SSLv3 in + options.h, but is only seen in >= 3.6.6 since that's when they started + disabling SSLv3 by default. */ +#ifndef WOLFSSL_ALLOW_SSLV3 +#if (LIBCYASSL_VERSION_HEX < 0x03006006) || \ + defined(HAVE_WOLFSSLV3_CLIENT_METHOD) +#define WOLFSSL_ALLOW_SSLV3 +#endif +#endif + +/* HAVE_SUPPORTED_CURVES is wolfSSL's build time symbol for enabling the ECC + supported curve extension in options.h. Note ECC is enabled separately. */ +#ifndef HAVE_SUPPORTED_CURVES +#if defined(HAVE_CYASSL_CTX_USESUPPORTEDCURVE) || \ + defined(HAVE_WOLFSSL_CTX_USESUPPORTEDCURVE) +#define HAVE_SUPPORTED_CURVES +#endif +#endif + +#ifdef HAVE_LIMITS_H +#include +#endif + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "vtls.h" +#include "parsedate.h" +#include "connect.h" /* for the connect timeout */ +#include "select.h" +#include "strcase.h" +#include "x509asn1.h" +#include "curl_printf.h" + +#include +#ifdef HAVE_CYASSL_ERROR_SSL_H +#include +#else +#include +#endif +#include +#include + +#include "cyassl.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +#if LIBCYASSL_VERSION_HEX < 0x02007002 /* < 2.7.2 */ +#define CYASSL_MAX_ERROR_SZ 80 +#endif + +static Curl_recv cyassl_recv; +static Curl_send cyassl_send; + + +static int do_file_type(const char *type) +{ + if(!type || !type[0]) + return SSL_FILETYPE_PEM; + if(strcasecompare(type, "PEM")) + return SSL_FILETYPE_PEM; + if(strcasecompare(type, "DER")) + return SSL_FILETYPE_ASN1; + return -1; +} + +/* + * This function loads all the client/CA certificates and CRLs. Setup the TLS + * layer and do all necessary magic. + */ +static CURLcode +cyassl_connect_step1(struct connectdata *conn, + int sockindex) +{ + char error_buffer[CYASSL_MAX_ERROR_SZ]; + char *ciphers; + struct Curl_easy *data = conn->data; + struct ssl_connect_data* conssl = &conn->ssl[sockindex]; + SSL_METHOD* req_method = NULL; + curl_socket_t sockfd = conn->sock[sockindex]; +#ifdef HAVE_SNI + bool sni = FALSE; +#define use_sni(x) sni = (x) +#else +#define use_sni(x) Curl_nop_stmt +#endif + + if(conssl->state == ssl_connection_complete) + return CURLE_OK; + + if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) { + failf(data, "CyaSSL does not support to set maximum SSL/TLS version"); + return CURLE_SSL_CONNECT_ERROR; + } + + /* check to see if we've been told to use an explicit SSL/TLS version */ + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: +#if LIBCYASSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */ + /* minimum protocol version is set later after the CTX object is created */ + req_method = SSLv23_client_method(); +#else + infof(data, "CyaSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, " + "TLS 1.0 is used exclusively\n"); + req_method = TLSv1_client_method(); +#endif + use_sni(TRUE); + break; + case CURL_SSLVERSION_TLSv1_0: + req_method = TLSv1_client_method(); + use_sni(TRUE); + break; + case CURL_SSLVERSION_TLSv1_1: + req_method = TLSv1_1_client_method(); + use_sni(TRUE); + break; + case CURL_SSLVERSION_TLSv1_2: + req_method = TLSv1_2_client_method(); + use_sni(TRUE); + break; + case CURL_SSLVERSION_TLSv1_3: + failf(data, "CyaSSL: TLS 1.3 is not yet supported"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_SSLv3: +#ifdef WOLFSSL_ALLOW_SSLV3 + req_method = SSLv3_client_method(); + use_sni(FALSE); +#else + failf(data, "CyaSSL does not support SSLv3"); + return CURLE_NOT_BUILT_IN; +#endif + break; + case CURL_SSLVERSION_SSLv2: + failf(data, "CyaSSL does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + if(!req_method) { + failf(data, "SSL: couldn't create a method!"); + return CURLE_OUT_OF_MEMORY; + } + + if(conssl->ctx) + SSL_CTX_free(conssl->ctx); + conssl->ctx = SSL_CTX_new(req_method); + + if(!conssl->ctx) { + failf(data, "SSL: couldn't create a context!"); + return CURLE_OUT_OF_MEMORY; + } + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: +#if LIBCYASSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */ + /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is whatever + minimum version of TLS was built in and at least TLS 1.0. For later library + versions that could change (eg TLS 1.0 built in but defaults to TLS 1.1) so + we have this short circuit evaluation to find the minimum supported TLS + version. We use wolfSSL_CTX_SetMinVersion and not CyaSSL_SetMinVersion + because only the former will work before the user's CTX callback is called. + */ + if((wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1) != 1) && + (wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1_1) != 1) && + (wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1_2) != 1)) { + failf(data, "SSL: couldn't set the minimum protocol version"); + return CURLE_SSL_CONNECT_ERROR; + } +#endif + break; + } + + ciphers = SSL_CONN_CONFIG(cipher_list); + if(ciphers) { + if(!SSL_CTX_set_cipher_list(conssl->ctx, ciphers)) { + failf(data, "failed setting cipher list: %s", ciphers); + return CURLE_SSL_CIPHER; + } + infof(data, "Cipher selection: %s\n", ciphers); + } + +#ifndef NO_FILESYSTEM + /* load trusted cacert */ + if(SSL_CONN_CONFIG(CAfile)) { + if(1 != SSL_CTX_load_verify_locations(conssl->ctx, + SSL_CONN_CONFIG(CAfile), + SSL_CONN_CONFIG(CApath))) { + if(SSL_CONN_CONFIG(verifypeer)) { + /* Fail if we insist on successfully verifying the server. */ + failf(data, "error setting certificate verify locations:\n" + " CAfile: %s\n CApath: %s", + SSL_CONN_CONFIG(CAfile)? + SSL_CONN_CONFIG(CAfile): "none", + SSL_CONN_CONFIG(CApath)? + SSL_CONN_CONFIG(CApath) : "none"); + return CURLE_SSL_CACERT_BADFILE; + } + else { + /* Just continue with a warning if no strict certificate + verification is required. */ + infof(data, "error setting certificate verify locations," + " continuing anyway:\n"); + } + } + else { + /* Everything is fine. */ + infof(data, "successfully set certificate verify locations:\n"); + } + infof(data, + " CAfile: %s\n" + " CApath: %s\n", + SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile): + "none", + SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath): + "none"); + } + + /* Load the client certificate, and private key */ + if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) { + int file_type = do_file_type(SSL_SET_OPTION(cert_type)); + + if(SSL_CTX_use_certificate_file(conssl->ctx, SSL_SET_OPTION(cert), + file_type) != 1) { + failf(data, "unable to use client certificate (no key or wrong pass" + " phrase?)"); + return CURLE_SSL_CONNECT_ERROR; + } + + file_type = do_file_type(SSL_SET_OPTION(key_type)); + if(SSL_CTX_use_PrivateKey_file(conssl->ctx, SSL_SET_OPTION(key), + file_type) != 1) { + failf(data, "unable to set private key"); + return CURLE_SSL_CONNECT_ERROR; + } + } +#endif /* !NO_FILESYSTEM */ + + /* SSL always tries to verify the peer, this only says whether it should + * fail to connect if the verification fails, or if it should continue + * anyway. In the latter case the result of the verification is checked with + * SSL_get_verify_result() below. */ + SSL_CTX_set_verify(conssl->ctx, + SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER: + SSL_VERIFY_NONE, + NULL); + +#ifdef HAVE_SNI + if(sni) { + struct in_addr addr4; +#ifdef ENABLE_IPV6 + struct in6_addr addr6; +#endif + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + size_t hostname_len = strlen(hostname); + if((hostname_len < USHRT_MAX) && + (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) && +#ifdef ENABLE_IPV6 + (0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) && +#endif + (CyaSSL_CTX_UseSNI(conssl->ctx, CYASSL_SNI_HOST_NAME, hostname, + (unsigned short)hostname_len) != 1)) { + infof(data, "WARNING: failed to configure server name indication (SNI) " + "TLS extension\n"); + } + } +#endif + +#ifdef HAVE_SUPPORTED_CURVES + /* CyaSSL/wolfSSL does not send the supported ECC curves ext automatically: + https://github.com/wolfSSL/wolfssl/issues/366 + The supported curves below are those also supported by OpenSSL 1.0.2 and + in the same order. */ + CyaSSL_CTX_UseSupportedCurve(conssl->ctx, 0x17); /* secp256r1 */ + CyaSSL_CTX_UseSupportedCurve(conssl->ctx, 0x19); /* secp521r1 */ + CyaSSL_CTX_UseSupportedCurve(conssl->ctx, 0x18); /* secp384r1 */ +#endif + + /* give application a chance to interfere with SSL set up. */ + if(data->set.ssl.fsslctx) { + CURLcode result = CURLE_OK; + result = (*data->set.ssl.fsslctx)(data, conssl->ctx, + data->set.ssl.fsslctxp); + if(result) { + failf(data, "error signaled by ssl ctx callback"); + return result; + } + } +#ifdef NO_FILESYSTEM + else if(SSL_CONN_CONFIG(verifypeer)) { + failf(data, "SSL: Certificates couldn't be loaded because CyaSSL was built" + " with \"no filesystem\". Either disable peer verification" + " (insecure) or if you are building an application with libcurl you" + " can load certificates via CURLOPT_SSL_CTX_FUNCTION."); + return CURLE_SSL_CONNECT_ERROR; + } +#endif + + /* Let's make an SSL structure */ + if(conssl->handle) + SSL_free(conssl->handle); + conssl->handle = SSL_new(conssl->ctx); + if(!conssl->handle) { + failf(data, "SSL: couldn't create a context (handle)!"); + return CURLE_OUT_OF_MEMORY; + } + +#ifdef HAVE_ALPN + if(conn->bits.tls_enable_alpn) { + char protocols[128]; + *protocols = '\0'; + + /* wolfSSL's ALPN protocol name list format is a comma separated string of + protocols in descending order of preference, eg: "h2,http/1.1" */ + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2) { + strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ","); + infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1); + infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + + if(wolfSSL_UseALPN(conssl->handle, protocols, + (unsigned)strlen(protocols), + WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) { + failf(data, "SSL: failed setting ALPN protocols"); + return CURLE_SSL_CONNECT_ERROR; + } + } +#endif /* HAVE_ALPN */ + + /* Check if there's a cached ID we can/should use here! */ + if(SSL_SET_OPTION(primary.sessionid)) { + void *ssl_sessionid = NULL; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { + /* we got a session id, use it! */ + if(!SSL_set_session(conssl->handle, ssl_sessionid)) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "SSL: SSL_set_session failed: %s", + ERR_error_string(SSL_get_error(conssl->handle, 0), + error_buffer)); + return CURLE_SSL_CONNECT_ERROR; + } + /* Informational message */ + infof(data, "SSL re-using session ID\n"); + } + Curl_ssl_sessionid_unlock(conn); + } + + /* pass the raw socket into the SSL layer */ + if(!SSL_set_fd(conssl->handle, (int)sockfd)) { + failf(data, "SSL: SSL_set_fd failed"); + return CURLE_SSL_CONNECT_ERROR; + } + + conssl->connecting_state = ssl_connect_2; + return CURLE_OK; +} + + +static CURLcode +cyassl_connect_step2(struct connectdata *conn, + int sockindex) +{ + int ret = -1; + struct Curl_easy *data = conn->data; + struct ssl_connect_data* conssl = &conn->ssl[sockindex]; + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const char * const dispname = SSL_IS_PROXY() ? + conn->http_proxy.host.dispname : conn->host.dispname; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + + conn->recv[sockindex] = cyassl_recv; + conn->send[sockindex] = cyassl_send; + + /* Enable RFC2818 checks */ + if(SSL_CONN_CONFIG(verifyhost)) { + ret = CyaSSL_check_domain_name(conssl->handle, hostname); + if(ret == SSL_FAILURE) + return CURLE_OUT_OF_MEMORY; + } + + ret = SSL_connect(conssl->handle); + if(ret != 1) { + char error_buffer[CYASSL_MAX_ERROR_SZ]; + int detail = SSL_get_error(conssl->handle, ret); + + if(SSL_ERROR_WANT_READ == detail) { + conssl->connecting_state = ssl_connect_2_reading; + return CURLE_OK; + } + else if(SSL_ERROR_WANT_WRITE == detail) { + conssl->connecting_state = ssl_connect_2_writing; + return CURLE_OK; + } + /* There is no easy way to override only the CN matching. + * This will enable the override of both mismatching SubjectAltNames + * as also mismatching CN fields */ + else if(DOMAIN_NAME_MISMATCH == detail) { +#if 1 + failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n", + dispname); + return CURLE_PEER_FAILED_VERIFICATION; +#else + /* When the CyaSSL_check_domain_name() is used and you desire to continue + * on a DOMAIN_NAME_MISMATCH, i.e. 'conn->ssl_config.verifyhost == 0', + * CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA error. The only + * way to do this is currently to switch the CyaSSL_check_domain_name() + * in and out based on the 'conn->ssl_config.verifyhost' value. */ + if(SSL_CONN_CONFIG(verifyhost)) { + failf(data, + "\tsubject alt name(s) or common name do not match \"%s\"\n", + dispname); + return CURLE_PEER_FAILED_VERIFICATION; + } + else { + infof(data, + "\tsubject alt name(s) and/or common name do not match \"%s\"\n", + dispname); + return CURLE_OK; + } +#endif + } +#if LIBCYASSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */ + else if(ASN_NO_SIGNER_E == detail) { + if(SSL_CONN_CONFIG(verifypeer)) { + failf(data, "\tCA signer not available for verification\n"); + return CURLE_SSL_CACERT_BADFILE; + } + else { + /* Just continue with a warning if no strict certificate + verification is required. */ + infof(data, "CA signer not available for verification, " + "continuing anyway\n"); + } + } +#endif + else { + failf(data, "SSL_connect failed with error %d: %s", detail, + ERR_error_string(detail, error_buffer)); + return CURLE_SSL_CONNECT_ERROR; + } + } + + if(pinnedpubkey) { +#ifdef KEEP_PEER_CERT + X509 *x509; + const char *x509_der; + int x509_der_len; + curl_X509certificate x509_parsed; + curl_asn1Element *pubkey; + CURLcode result; + + x509 = SSL_get_peer_certificate(conssl->handle); + if(!x509) { + failf(data, "SSL: failed retrieving server certificate"); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + x509_der = (const char *)CyaSSL_X509_get_der(x509, &x509_der_len); + if(!x509_der) { + failf(data, "SSL: failed retrieving ASN.1 server certificate"); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + memset(&x509_parsed, 0, sizeof x509_parsed); + if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len)) + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + + pubkey = &x509_parsed.subjectPublicKeyInfo; + if(!pubkey->header || pubkey->end <= pubkey->header) { + failf(data, "SSL: failed retrieving public key from server certificate"); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + result = Curl_pin_peer_pubkey(data, + pinnedpubkey, + (const unsigned char *)pubkey->header, + (size_t)(pubkey->end - pubkey->header)); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + return result; + } +#else + failf(data, "Library lacks pinning support built-in"); + return CURLE_NOT_BUILT_IN; +#endif + } + +#ifdef HAVE_ALPN + if(conn->bits.tls_enable_alpn) { + int rc; + char *protocol = NULL; + unsigned short protocol_len = 0; + + rc = wolfSSL_ALPN_GetProtocol(conssl->handle, &protocol, &protocol_len); + + if(rc == SSL_SUCCESS) { + infof(data, "ALPN, server accepted to use %.*s\n", protocol_len, + protocol); + + if(protocol_len == ALPN_HTTP_1_1_LENGTH && + !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) + conn->negnpn = CURL_HTTP_VERSION_1_1; +#ifdef USE_NGHTTP2 + else if(data->set.httpversion >= CURL_HTTP_VERSION_2 && + protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN && + !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID, + NGHTTP2_PROTO_VERSION_ID_LEN)) + conn->negnpn = CURL_HTTP_VERSION_2; +#endif + else + infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len, + protocol); + } + else if(rc == SSL_ALPN_NOT_FOUND) + infof(data, "ALPN, server did not agree to a protocol\n"); + else { + failf(data, "ALPN, failure getting protocol, error %d", rc); + return CURLE_SSL_CONNECT_ERROR; + } + } +#endif /* HAVE_ALPN */ + + conssl->connecting_state = ssl_connect_3; +#if (LIBCYASSL_VERSION_HEX >= 0x03009010) + infof(data, "SSL connection using %s / %s\n", + wolfSSL_get_version(conssl->handle), + wolfSSL_get_cipher_name(conssl->handle)); +#else + infof(data, "SSL connected\n"); +#endif + + return CURLE_OK; +} + + +static CURLcode +cyassl_connect_step3(struct connectdata *conn, + int sockindex) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); + + if(SSL_SET_OPTION(primary.sessionid)) { + bool incache; + SSL_SESSION *our_ssl_sessionid; + void *old_ssl_sessionid = NULL; + + our_ssl_sessionid = SSL_get_session(connssl->handle); + + Curl_ssl_sessionid_lock(conn); + incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, + sockindex)); + if(incache) { + if(old_ssl_sessionid != our_ssl_sessionid) { + infof(data, "old SSL session ID is stale, removing\n"); + Curl_ssl_delsessionid(conn, old_ssl_sessionid); + incache = FALSE; + } + } + + if(!incache) { + result = Curl_ssl_addsessionid(conn, our_ssl_sessionid, + 0 /* unknown size */, sockindex); + if(result) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "failed to store ssl session"); + return result; + } + } + Curl_ssl_sessionid_unlock(conn); + } + + connssl->connecting_state = ssl_connect_done; + + return result; +} + + +static ssize_t cyassl_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) +{ + char error_buffer[CYASSL_MAX_ERROR_SZ]; + int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; + int rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen); + + if(rc < 0) { + int err = SSL_get_error(conn->ssl[sockindex].handle, rc); + + switch(err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /* there's data pending, re-invoke SSL_write() */ + *curlcode = CURLE_AGAIN; + return -1; + default: + failf(conn->data, "SSL write: %s, errno %d", + ERR_error_string(err, error_buffer), + SOCKERRNO); + *curlcode = CURLE_SEND_ERROR; + return -1; + } + } + return rc; +} + +void Curl_cyassl_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *conssl = &conn->ssl[sockindex]; + + if(conssl->handle) { + (void)SSL_shutdown(conssl->handle); + SSL_free(conssl->handle); + conssl->handle = NULL; + } + if(conssl->ctx) { + SSL_CTX_free(conssl->ctx); + conssl->ctx = NULL; + } +} + +static ssize_t cyassl_recv(struct connectdata *conn, + int num, + char *buf, + size_t buffersize, + CURLcode *curlcode) +{ + char error_buffer[CYASSL_MAX_ERROR_SZ]; + int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; + int nread = SSL_read(conn->ssl[num].handle, buf, buffsize); + + if(nread < 0) { + int err = SSL_get_error(conn->ssl[num].handle, nread); + + switch(err) { + case SSL_ERROR_ZERO_RETURN: /* no more data */ + break; + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /* there's data pending, re-invoke SSL_read() */ + *curlcode = CURLE_AGAIN; + return -1; + default: + failf(conn->data, "SSL read: %s, errno %d", + ERR_error_string(err, error_buffer), + SOCKERRNO); + *curlcode = CURLE_RECV_ERROR; + return -1; + } + } + return nread; +} + + +void Curl_cyassl_session_free(void *ptr) +{ + (void)ptr; + /* CyaSSL reuses sessions on own, no free */ +} + + +size_t Curl_cyassl_version(char *buffer, size_t size) +{ +#if LIBCYASSL_VERSION_HEX >= 0x03006000 + return snprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version()); +#elif defined(WOLFSSL_VERSION) + return snprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION); +#elif defined(CYASSL_VERSION) + return snprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION); +#else + return snprintf(buffer, size, "CyaSSL/%s", "<1.8.8"); +#endif +} + + +int Curl_cyassl_init(void) +{ + return (CyaSSL_Init() == SSL_SUCCESS); +} + + +bool Curl_cyassl_data_pending(const struct connectdata* conn, int connindex) +{ + if(conn->ssl[connindex].handle) /* SSL is in use */ + return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE; + else + return FALSE; +} + + +/* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) + */ +int Curl_cyassl_shutdown(struct connectdata *conn, int sockindex) +{ + int retval = 0; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + if(connssl->handle) { + SSL_free(connssl->handle); + connssl->handle = NULL; + } + return retval; +} + + +static CURLcode +cyassl_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + time_t timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1==connssl->connecting_state) { + /* Find out how much more time we're allowed */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + result = cyassl_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading + || connssl->connecting_state == ssl_connect_2_writing) { + + curl_socket_t writefd = ssl_connect_2_writing== + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading== + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking?0:timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if + * this connection is part of a multi handle and this loop would + * execute again. This permits the owner of a multi handle to + * abort a connection attempt before step2 has completed while + * ensuring that a client using select() or epoll() will always + * have a valid fdset to wait on. + */ + result = cyassl_connect_step2(conn, sockindex); + if(result || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return result; + } /* repeat step2 until all transactions are done. */ + + if(ssl_connect_3 == connssl->connecting_state) { + result = cyassl_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = cyassl_recv; + conn->send[sockindex] = cyassl_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + + +CURLcode +Curl_cyassl_connect_nonblocking(struct connectdata *conn, + int sockindex, + bool *done) +{ + return cyassl_connect_common(conn, sockindex, TRUE, done); +} + + +CURLcode +Curl_cyassl_connect(struct connectdata *conn, + int sockindex) +{ + CURLcode result; + bool done = FALSE; + + result = cyassl_connect_common(conn, sockindex, FALSE, &done); + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +CURLcode Curl_cyassl_random(struct Curl_easy *data, + unsigned char *entropy, + size_t length) +{ + RNG rng; + (void)data; + if(InitRng(&rng)) + return CURLE_FAILED_INIT; + if(length > UINT_MAX) + return CURLE_FAILED_INIT; + if(RNG_GenerateBlock(&rng, entropy, (unsigned)length)) + return CURLE_FAILED_INIT; + return CURLE_OK; +} + +void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *sha256sum /* output */, + size_t unused) +{ + Sha256 SHA256pw; + (void)unused; + InitSha256(&SHA256pw); + Sha256Update(&SHA256pw, tmp, (word32)tmplen); + Sha256Final(&SHA256pw, sha256sum); +} + +#endif diff --git a/libcurl/lib/vtls/cyassl.h b/libcurl/lib/vtls/cyassl.h new file mode 100644 index 0000000..f47719e --- /dev/null +++ b/libcurl/lib/vtls/cyassl.h @@ -0,0 +1,92 @@ +#ifndef HEADER_CURL_CYASSL_H +#define HEADER_CURL_CYASSL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_CYASSL + +/* KEEP_PEER_CERT is a product of the presence of build time symbol + OPENSSL_EXTRA without NO_CERTS, depending on the version. KEEP_PEER_CERT is + in wolfSSL's settings.h, and the latter two are build time symbols in + options.h. */ +#ifndef KEEP_PEER_CERT +#if defined(HAVE_CYASSL_GET_PEER_CERTIFICATE) || \ + defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \ + (defined(OPENSSL_EXTRA) && !defined(NO_CERTS)) +#define KEEP_PEER_CERT +#endif +#endif + +CURLcode Curl_cyassl_connect(struct connectdata *conn, int sockindex); +bool Curl_cyassl_data_pending(const struct connectdata* conn, int connindex); +int Curl_cyassl_shutdown(struct connectdata* conn, int sockindex); + + /* close a SSL connection */ +void Curl_cyassl_close(struct connectdata *conn, int sockindex); + +void Curl_cyassl_session_free(void *ptr); +size_t Curl_cyassl_version(char *buffer, size_t size); +int Curl_cyassl_shutdown(struct connectdata *conn, int sockindex); +int Curl_cyassl_init(void); +CURLcode Curl_cyassl_connect_nonblocking(struct connectdata *conn, + int sockindex, + bool *done); +CURLcode Curl_cyassl_random(struct Curl_easy *data, + unsigned char *entropy, + size_t length); +void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *sha256sum, /* output */ + size_t unused); + +/* Set the API backend definition to CyaSSL */ +#define CURL_SSL_BACKEND CURLSSLBACKEND_CYASSL + +/* this backend supports CURLOPT_SSL_CTX_* */ +#define have_curlssl_ssl_ctx 1 + +#ifdef KEEP_PEER_CERT +/* this backend supports CURLOPT_PINNEDPUBLICKEY */ +#define have_curlssl_pinnedpubkey 1 +#endif + +/* API setup for CyaSSL */ +#define curlssl_init Curl_cyassl_init +#define curlssl_cleanup() Curl_nop_stmt +#define curlssl_connect Curl_cyassl_connect +#define curlssl_connect_nonblocking Curl_cyassl_connect_nonblocking +#define curlssl_session_free(x) Curl_cyassl_session_free(x) +#define curlssl_close_all(x) ((void)x) +#define curlssl_close Curl_cyassl_close +#define curlssl_shutdown(x,y) Curl_cyassl_shutdown(x,y) +#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN) +#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN) +#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL) +#define curlssl_version Curl_cyassl_version +#define curlssl_check_cxn(x) ((void)x, -1) +#define curlssl_data_pending(x,y) Curl_cyassl_data_pending(x,y) +#define curlssl_random(x,y,z) Curl_cyassl_random(x,y,z) +#define curlssl_sha256sum(a,b,c,d) Curl_cyassl_sha256sum(a,b,c,d) + +#endif /* USE_CYASSL */ +#endif /* HEADER_CURL_CYASSL_H */ diff --git a/libcurl/lib/vtls/darwinssl.c b/libcurl/lib/vtls/darwinssl.c new file mode 100644 index 0000000..6f9c601 --- /dev/null +++ b/libcurl/lib/vtls/darwinssl.c @@ -0,0 +1,2858 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2014, Nick Zitzmann, . + * Copyright (C) 2012 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all iOS and Mac OS X SecureTransport-specific code for the + * TLS/SSL layer. No code but vtls.c should ever call or use these functions. + */ + +#include "curl_setup.h" + +#include "urldata.h" /* for the Curl_easy definition */ +#include "curl_base64.h" +#include "strtok.h" + +#ifdef USE_DARWINSSL + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wtautological-pointer-compare" +#endif /* __clang__ */ + +#ifdef HAVE_LIMITS_H +#include +#endif + +#include +#include +#include +#include + +/* The Security framework has changed greatly between iOS and different OS X + versions, and we will try to support as many of them as we can (back to + Leopard and iOS 5) by using macros and weak-linking. + + IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then + you must build this project against the 10.8 SDK or later. */ +#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) + +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 +#error "The darwinssl back-end requires Leopard or later." +#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */ + +#define CURL_BUILD_IOS 0 +#define CURL_BUILD_IOS_7 0 +#define CURL_BUILD_MAC 1 +/* This is the maximum API level we are allowed to use when building: */ +#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 +#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 +#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 +#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 +#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 +/* These macros mean "the following code is present to allow runtime backward + compatibility with at least this cat or earlier": + (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET + environmental variable.) */ +#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050 +#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060 +#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070 +#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080 +#define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090 + +#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE +#define CURL_BUILD_IOS 1 +#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 +#define CURL_BUILD_MAC 0 +#define CURL_BUILD_MAC_10_5 0 +#define CURL_BUILD_MAC_10_6 0 +#define CURL_BUILD_MAC_10_7 0 +#define CURL_BUILD_MAC_10_8 0 +#define CURL_SUPPORT_MAC_10_5 0 +#define CURL_SUPPORT_MAC_10_6 0 +#define CURL_SUPPORT_MAC_10_7 0 +#define CURL_SUPPORT_MAC_10_8 0 +#define CURL_SUPPORT_MAC_10_9 0 + +#else +#error "The darwinssl back-end requires iOS or OS X." +#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */ + +#if CURL_BUILD_MAC +#include +#endif /* CURL_BUILD_MAC */ + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "connect.h" +#include "select.h" +#include "vtls.h" +#include "darwinssl.h" +#include "curl_printf.h" + +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* From MacTypes.h (which we can't include because it isn't present in iOS: */ +#define ioErr -36 +#define paramErr -50 + +#ifdef DARWIN_SSL_PINNEDPUBKEY +/* both new and old APIs return rsa keys missing the spki header (not DER) */ +static const unsigned char rsa4096SpkiHeader[] = { + 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00}; + +static const unsigned char rsa2048SpkiHeader[] = { + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00}; +#ifdef DARWIN_SSL_PINNEDPUBKEY_V1 +/* the *new* version doesn't return DER encoded ecdsa certs like the old... */ +static const unsigned char ecDsaSecp256r1SpkiHeader[] = { + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, + 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, + 0x42, 0x00}; + +static const unsigned char ecDsaSecp384r1SpkiHeader[] = { + 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, + 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, + 0x00, 0x22, 0x03, 0x62, 0x00}; +#endif /* DARWIN_SSL_PINNEDPUBKEY_V1 */ +#endif /* DARWIN_SSL_PINNEDPUBKEY */ + +/* The following two functions were ripped from Apple sample code, + * with some modifications: */ +static OSStatus SocketRead(SSLConnectionRef connection, + void *data, /* owned by + * caller, data + * RETURNED */ + size_t *dataLength) /* IN/OUT */ +{ + size_t bytesToGo = *dataLength; + size_t initLen = bytesToGo; + UInt8 *currData = (UInt8 *)data; + /*int sock = *(int *)connection;*/ + struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; + int sock = connssl->ssl_sockfd; + OSStatus rtn = noErr; + size_t bytesRead; + ssize_t rrtn; + int theErr; + + *dataLength = 0; + + for(;;) { + bytesRead = 0; + rrtn = read(sock, currData, bytesToGo); + if(rrtn <= 0) { + /* this is guesswork... */ + theErr = errno; + if(rrtn == 0) { /* EOF = server hung up */ + /* the framework will turn this into errSSLClosedNoNotify */ + rtn = errSSLClosedGraceful; + } + else /* do the switch */ + switch(theErr) { + case ENOENT: + /* connection closed */ + rtn = errSSLClosedGraceful; + break; + case ECONNRESET: + rtn = errSSLClosedAbort; + break; + case EAGAIN: + rtn = errSSLWouldBlock; + connssl->ssl_direction = false; + break; + default: + rtn = ioErr; + break; + } + break; + } + else { + bytesRead = rrtn; + } + bytesToGo -= bytesRead; + currData += bytesRead; + + if(bytesToGo == 0) { + /* filled buffer with incoming data, done */ + break; + } + } + *dataLength = initLen - bytesToGo; + + return rtn; +} + +static OSStatus SocketWrite(SSLConnectionRef connection, + const void *data, + size_t *dataLength) /* IN/OUT */ +{ + size_t bytesSent = 0; + /*int sock = *(int *)connection;*/ + struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; + int sock = connssl->ssl_sockfd; + ssize_t length; + size_t dataLen = *dataLength; + const UInt8 *dataPtr = (UInt8 *)data; + OSStatus ortn; + int theErr; + + *dataLength = 0; + + do { + length = write(sock, + (char *)dataPtr + bytesSent, + dataLen - bytesSent); + } while((length > 0) && + ( (bytesSent += length) < dataLen) ); + + if(length <= 0) { + theErr = errno; + if(theErr == EAGAIN) { + ortn = errSSLWouldBlock; + connssl->ssl_direction = true; + } + else { + ortn = ioErr; + } + } + else { + ortn = noErr; + } + *dataLength = bytesSent; + return ortn; +} + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) +{ + switch(cipher) { + /* SSL version 3.0 */ + case SSL_RSA_WITH_NULL_MD5: + return "SSL_RSA_WITH_NULL_MD5"; + break; + case SSL_RSA_WITH_NULL_SHA: + return "SSL_RSA_WITH_NULL_SHA"; + break; + case SSL_RSA_EXPORT_WITH_RC4_40_MD5: + return "SSL_RSA_EXPORT_WITH_RC4_40_MD5"; + break; + case SSL_RSA_WITH_RC4_128_MD5: + return "SSL_RSA_WITH_RC4_128_MD5"; + break; + case SSL_RSA_WITH_RC4_128_SHA: + return "SSL_RSA_WITH_RC4_128_SHA"; + break; + case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: + return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"; + break; + case SSL_RSA_WITH_IDEA_CBC_SHA: + return "SSL_RSA_WITH_IDEA_CBC_SHA"; + break; + case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_RSA_WITH_DES_CBC_SHA: + return "SSL_RSA_WITH_DES_CBC_SHA"; + break; + case SSL_RSA_WITH_3DES_EDE_CBC_SHA: + return "SSL_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DH_DSS_WITH_DES_CBC_SHA: + return "SSL_DH_DSS_WITH_DES_CBC_SHA"; + break; + case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA: + return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DH_RSA_WITH_DES_CBC_SHA: + return "SSL_DH_RSA_WITH_DES_CBC_SHA"; + break; + case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA: + return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DHE_DSS_WITH_DES_CBC_SHA: + return "SSL_DHE_DSS_WITH_DES_CBC_SHA"; + break; + case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DHE_RSA_WITH_DES_CBC_SHA: + return "SSL_DHE_RSA_WITH_DES_CBC_SHA"; + break; + case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: + return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"; + break; + case SSL_DH_anon_WITH_RC4_128_MD5: + return "SSL_DH_anon_WITH_RC4_128_MD5"; + break; + case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DH_anon_WITH_DES_CBC_SHA: + return "SSL_DH_anon_WITH_DES_CBC_SHA"; + break; + case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: + return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_FORTEZZA_DMS_WITH_NULL_SHA: + return "SSL_FORTEZZA_DMS_WITH_NULL_SHA"; + break; + case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA: + return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"; + break; + /* TLS 1.0 with AES (RFC 3268) + (Apparently these are used in SSLv3 implementations as well.) */ + case TLS_RSA_WITH_AES_128_CBC_SHA: + return "TLS_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_128_CBC_SHA: + return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_AES_128_CBC_SHA: + return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_128_CBC_SHA: + return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; + break; + case TLS_RSA_WITH_AES_256_CBC_SHA: + return "TLS_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_256_CBC_SHA: + return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_AES_256_CBC_SHA: + return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_256_CBC_SHA: + return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; + break; + /* SSL version 2.0 */ + case SSL_RSA_WITH_RC2_CBC_MD5: + return "SSL_RSA_WITH_RC2_CBC_MD5"; + break; + case SSL_RSA_WITH_IDEA_CBC_MD5: + return "SSL_RSA_WITH_IDEA_CBC_MD5"; + break; + case SSL_RSA_WITH_DES_CBC_MD5: + return "SSL_RSA_WITH_DES_CBC_MD5"; + break; + case SSL_RSA_WITH_3DES_EDE_CBC_MD5: + return "SSL_RSA_WITH_3DES_EDE_CBC_MD5"; + break; + } + return "SSL_NULL_WITH_NULL_NULL"; +} + +CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) +{ + switch(cipher) { + /* TLS 1.0 with AES (RFC 3268) */ + case TLS_RSA_WITH_AES_128_CBC_SHA: + return "TLS_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_128_CBC_SHA: + return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_AES_128_CBC_SHA: + return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_128_CBC_SHA: + return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; + break; + case TLS_RSA_WITH_AES_256_CBC_SHA: + return "TLS_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_256_CBC_SHA: + return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_AES_256_CBC_SHA: + return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_256_CBC_SHA: + return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; + break; +#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS + /* TLS 1.0 with ECDSA (RFC 4492) */ + case TLS_ECDH_ECDSA_WITH_NULL_SHA: + return "TLS_ECDH_ECDSA_WITH_NULL_SHA"; + break; + case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"; + break; + case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_NULL_SHA: + return "TLS_ECDHE_ECDSA_WITH_NULL_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_ECDH_RSA_WITH_NULL_SHA: + return "TLS_ECDH_RSA_WITH_NULL_SHA"; + break; + case TLS_ECDH_RSA_WITH_RC4_128_SHA: + return "TLS_ECDH_RSA_WITH_RC4_128_SHA"; + break; + case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_ECDHE_RSA_WITH_NULL_SHA: + return "TLS_ECDHE_RSA_WITH_NULL_SHA"; + break; + case TLS_ECDHE_RSA_WITH_RC4_128_SHA: + return "TLS_ECDHE_RSA_WITH_RC4_128_SHA"; + break; + case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_ECDH_anon_WITH_NULL_SHA: + return "TLS_ECDH_anon_WITH_NULL_SHA"; + break; + case TLS_ECDH_anon_WITH_RC4_128_SHA: + return "TLS_ECDH_anon_WITH_RC4_128_SHA"; + break; + case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"; + break; +#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + /* TLS 1.2 (RFC 5246) */ + case TLS_RSA_WITH_NULL_MD5: + return "TLS_RSA_WITH_NULL_MD5"; + break; + case TLS_RSA_WITH_NULL_SHA: + return "TLS_RSA_WITH_NULL_SHA"; + break; + case TLS_RSA_WITH_RC4_128_MD5: + return "TLS_RSA_WITH_RC4_128_MD5"; + break; + case TLS_RSA_WITH_RC4_128_SHA: + return "TLS_RSA_WITH_RC4_128_SHA"; + break; + case TLS_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_RSA_WITH_NULL_SHA256: + return "TLS_RSA_WITH_NULL_SHA256"; + break; + case TLS_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_RSA_WITH_AES_256_CBC_SHA256: + return "TLS_RSA_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DH_anon_WITH_RC4_128_MD5: + return "TLS_DH_anon_WITH_RC4_128_MD5"; + break; + case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_128_CBC_SHA256: + return "TLS_DH_anon_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DH_anon_WITH_AES_256_CBC_SHA256: + return "TLS_DH_anon_WITH_AES_256_CBC_SHA256"; + break; + /* TLS 1.2 with AES GCM (RFC 5288) */ + case TLS_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DH_anon_WITH_AES_128_GCM_SHA256: + return "TLS_DH_anon_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DH_anon_WITH_AES_256_GCM_SHA384: + return "TLS_DH_anon_WITH_AES_256_GCM_SHA384"; + break; + /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */ + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_EMPTY_RENEGOTIATION_INFO_SCSV: + return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; + break; +#else + case SSL_RSA_WITH_NULL_MD5: + return "TLS_RSA_WITH_NULL_MD5"; + break; + case SSL_RSA_WITH_NULL_SHA: + return "TLS_RSA_WITH_NULL_SHA"; + break; + case SSL_RSA_WITH_RC4_128_MD5: + return "TLS_RSA_WITH_RC4_128_MD5"; + break; + case SSL_RSA_WITH_RC4_128_SHA: + return "TLS_RSA_WITH_RC4_128_SHA"; + break; + case SSL_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DH_anon_WITH_RC4_128_MD5: + return "TLS_DH_anon_WITH_RC4_128_MD5"; + break; + case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; + break; +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + /* TLS PSK (RFC 4279): */ + case TLS_PSK_WITH_RC4_128_SHA: + return "TLS_PSK_WITH_RC4_128_SHA"; + break; + case TLS_PSK_WITH_3DES_EDE_CBC_SHA: + return "TLS_PSK_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_PSK_WITH_AES_128_CBC_SHA: + return "TLS_PSK_WITH_AES_128_CBC_SHA"; + break; + case TLS_PSK_WITH_AES_256_CBC_SHA: + return "TLS_PSK_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_PSK_WITH_RC4_128_SHA: + return "TLS_DHE_PSK_WITH_RC4_128_SHA"; + break; + case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"; + break; + case TLS_RSA_PSK_WITH_RC4_128_SHA: + return "TLS_RSA_PSK_WITH_RC4_128_SHA"; + break; + case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"; + break; + case TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"; + break; + /* More TLS PSK (RFC 4785): */ + case TLS_PSK_WITH_NULL_SHA: + return "TLS_PSK_WITH_NULL_SHA"; + break; + case TLS_DHE_PSK_WITH_NULL_SHA: + return "TLS_DHE_PSK_WITH_NULL_SHA"; + break; + case TLS_RSA_PSK_WITH_NULL_SHA: + return "TLS_RSA_PSK_WITH_NULL_SHA"; + break; + /* Even more TLS PSK (RFC 5487): */ + case TLS_PSK_WITH_AES_128_GCM_SHA256: + return "TLS_PSK_WITH_AES_128_GCM_SHA256"; + break; + case TLS_PSK_WITH_AES_256_GCM_SHA384: + return "TLS_PSK_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"; + break; + case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"; + break; + case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + return "TLS_PSK_WITH_AES_256_GCM_SHA384"; + break; + case TLS_PSK_WITH_AES_128_CBC_SHA256: + return "TLS_PSK_WITH_AES_128_CBC_SHA256"; + break; + case TLS_PSK_WITH_AES_256_CBC_SHA384: + return "TLS_PSK_WITH_AES_256_CBC_SHA384"; + break; + case TLS_PSK_WITH_NULL_SHA256: + return "TLS_PSK_WITH_NULL_SHA256"; + break; + case TLS_PSK_WITH_NULL_SHA384: + return "TLS_PSK_WITH_NULL_SHA384"; + break; + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"; + break; + case TLS_DHE_PSK_WITH_NULL_SHA256: + return "TLS_DHE_PSK_WITH_NULL_SHA256"; + break; + case TLS_DHE_PSK_WITH_NULL_SHA384: + return "TLS_RSA_PSK_WITH_NULL_SHA384"; + break; + case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"; + break; + case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"; + break; + case TLS_RSA_PSK_WITH_NULL_SHA256: + return "TLS_RSA_PSK_WITH_NULL_SHA256"; + break; + case TLS_RSA_PSK_WITH_NULL_SHA384: + return "TLS_RSA_PSK_WITH_NULL_SHA384"; + break; +#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ + } + return "TLS_NULL_WITH_NULL_NULL"; +} +#endif /* !CURL_DISABLE_VERBOSE_STRINGS */ + +#if CURL_BUILD_MAC +CF_INLINE void GetDarwinVersionNumber(int *major, int *minor) +{ + int mib[2]; + char *os_version; + size_t os_version_len; + char *os_version_major, *os_version_minor; + char *tok_buf; + + /* Get the Darwin kernel version from the kernel using sysctl(): */ + mib[0] = CTL_KERN; + mib[1] = KERN_OSRELEASE; + if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1) + return; + os_version = malloc(os_version_len*sizeof(char)); + if(!os_version) + return; + if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) { + free(os_version); + return; + } + + /* Parse the version: */ + os_version_major = strtok_r(os_version, ".", &tok_buf); + os_version_minor = strtok_r(NULL, ".", &tok_buf); + *major = atoi(os_version_major); + *minor = atoi(os_version_minor); + free(os_version); +} +#endif /* CURL_BUILD_MAC */ + +/* Apple provides a myriad of ways of getting information about a certificate + into a string. Some aren't available under iOS or newer cats. So here's + a unified function for getting a string describing the certificate that + ought to work in all cats starting with Leopard. */ +CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert) +{ + CFStringRef server_cert_summary = CFSTR("(null)"); + +#if CURL_BUILD_IOS + /* iOS: There's only one way to do this. */ + server_cert_summary = SecCertificateCopySubjectSummary(cert); +#else +#if CURL_BUILD_MAC_10_7 + /* Lion & later: Get the long description if we can. */ + if(SecCertificateCopyLongDescription != NULL) + server_cert_summary = + SecCertificateCopyLongDescription(NULL, cert, NULL); + else +#endif /* CURL_BUILD_MAC_10_7 */ +#if CURL_BUILD_MAC_10_6 + /* Snow Leopard: Get the certificate summary. */ + if(SecCertificateCopySubjectSummary != NULL) + server_cert_summary = SecCertificateCopySubjectSummary(cert); + else +#endif /* CURL_BUILD_MAC_10_6 */ + /* Leopard is as far back as we go... */ + (void)SecCertificateCopyCommonName(cert, &server_cert_summary); +#endif /* CURL_BUILD_IOS */ + return server_cert_summary; +} + +#if CURL_SUPPORT_MAC_10_6 +/* The SecKeychainSearch API was deprecated in Lion, and using it will raise + deprecation warnings, so let's not compile this unless it's necessary: */ +static OSStatus CopyIdentityWithLabelOldSchool(char *label, + SecIdentityRef *out_c_a_k) +{ + OSStatus status = errSecItemNotFound; + SecKeychainAttributeList attr_list; + SecKeychainAttribute attr; + SecKeychainSearchRef search = NULL; + SecCertificateRef cert = NULL; + + /* Set up the attribute list: */ + attr_list.count = 1L; + attr_list.attr = &attr; + + /* Set up our lone search criterion: */ + attr.tag = kSecLabelItemAttr; + attr.data = label; + attr.length = (UInt32)strlen(label); + + /* Start searching: */ + status = SecKeychainSearchCreateFromAttributes(NULL, + kSecCertificateItemClass, + &attr_list, + &search); + if(status == noErr) { + status = SecKeychainSearchCopyNext(search, + (SecKeychainItemRef *)&cert); + if(status == noErr && cert) { + /* If we found a certificate, does it have a private key? */ + status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k); + CFRelease(cert); + } + } + + if(search) + CFRelease(search); + return status; +} +#endif /* CURL_SUPPORT_MAC_10_6 */ + +static OSStatus CopyIdentityWithLabel(char *label, + SecIdentityRef *out_cert_and_key) +{ + OSStatus status = errSecItemNotFound; + +#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS + CFArrayRef keys_list; + CFIndex keys_list_count; + CFIndex i; + CFStringRef common_name; + + /* SecItemCopyMatching() was introduced in iOS and Snow Leopard. + kSecClassIdentity was introduced in Lion. If both exist, let's use them + to find the certificate. */ + if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) { + CFTypeRef keys[5]; + CFTypeRef values[5]; + CFDictionaryRef query_dict; + CFStringRef label_cf = CFStringCreateWithCString(NULL, label, + kCFStringEncodingUTF8); + + /* Set up our search criteria and expected results: */ + values[0] = kSecClassIdentity; /* we want a certificate and a key */ + keys[0] = kSecClass; + values[1] = kCFBooleanTrue; /* we want a reference */ + keys[1] = kSecReturnRef; + values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the + * label matching below worked correctly */ + keys[2] = kSecMatchLimit; + /* identity searches need a SecPolicyRef in order to work */ + values[3] = SecPolicyCreateSSL(false, NULL); + keys[3] = kSecMatchPolicy; + /* match the name of the certificate (doesn't work in macOS 10.12.1) */ + values[4] = label_cf; + keys[4] = kSecAttrLabel; + query_dict = CFDictionaryCreate(NULL, (const void **)keys, + (const void **)values, 5L, + &kCFCopyStringDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFRelease(values[3]); + + /* Do we have a match? */ + status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list); + + /* Because kSecAttrLabel matching doesn't work with kSecClassIdentity, + * we need to find the correct identity ourselves */ + if(status == noErr) { + keys_list_count = CFArrayGetCount(keys_list); + *out_cert_and_key = NULL; + status = 1; + for(i=0; idata; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + long ssl_version = SSL_CONN_CONFIG(version); + long ssl_version_max = SSL_CONN_CONFIG(version_max); + + switch(ssl_version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + ssl_version = CURL_SSLVERSION_TLSv1_0; + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; + break; + } + + switch(ssl_version_max) { + case CURL_SSLVERSION_MAX_NONE: + ssl_version_max = ssl_version << 16; + break; + case CURL_SSLVERSION_MAX_DEFAULT: + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; + break; + } + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + if(SSLSetProtocolVersionMax != NULL) { + SSLProtocol darwin_ver_min = kTLSProtocol1; + SSLProtocol darwin_ver_max = kTLSProtocol1; + CURLcode result = darwinssl_version_from_curl(&darwin_ver_min, + ssl_version); + if(result) { + failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); + return result; + } + result = darwinssl_version_from_curl(&darwin_ver_max, + ssl_version_max >> 16); + if(result) { + failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); + return result; + } + + (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, darwin_ver_min); + (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, darwin_ver_max); + return result; + } + else { +#if CURL_SUPPORT_MAC_10_8 + long i = ssl_version; + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kSSLProtocolAll, + false); + for(; i <= (ssl_version_max >> 16); i++) { + switch(i) { + case CURL_SSLVERSION_TLSv1_0: + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol1, + true); + break; + case CURL_SSLVERSION_TLSv1_1: + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol11, + true); + break; + case CURL_SSLVERSION_TLSv1_2: + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol12, + true); + break; + case CURL_SSLVERSION_TLSv1_3: + failf(data, "DarwinSSL: TLS 1.3 is not yet supported"); + return CURLE_SSL_CONNECT_ERROR; + } + } + return CURLE_OK; +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + failf(data, "DarwinSSL: cannot set SSL protocol"); + return CURLE_SSL_CONNECT_ERROR; +} + + +static CURLcode darwinssl_connect_step1(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + curl_socket_t sockfd = conn->sock[sockindex]; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); + char * const ssl_cert = SSL_SET_OPTION(cert); + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; +#ifdef ENABLE_IPV6 + struct in6_addr addr; +#else + struct in_addr addr; +#endif /* ENABLE_IPV6 */ + size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i; + SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL; + OSStatus err = noErr; +#if CURL_BUILD_MAC + int darwinver_maj = 0, darwinver_min = 0; + + GetDarwinVersionNumber(&darwinver_maj, &darwinver_min); +#endif /* CURL_BUILD_MAC */ + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + if(SSLCreateContext != NULL) { /* use the newer API if avaialble */ + if(connssl->ssl_ctx) + CFRelease(connssl->ssl_ctx); + connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType); + if(!connssl->ssl_ctx) { + failf(data, "SSL: couldn't create a context!"); + return CURLE_OUT_OF_MEMORY; + } + } + else { + /* The old ST API does not exist under iOS, so don't compile it: */ +#if CURL_SUPPORT_MAC_10_8 + if(connssl->ssl_ctx) + (void)SSLDisposeContext(connssl->ssl_ctx); + err = SSLNewContext(false, &(connssl->ssl_ctx)); + if(err != noErr) { + failf(data, "SSL: couldn't create a context: OSStatus %d", err); + return CURLE_OUT_OF_MEMORY; + } +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#else + if(connssl->ssl_ctx) + (void)SSLDisposeContext(connssl->ssl_ctx); + err = SSLNewContext(false, &(connssl->ssl_ctx)); + if(err != noErr) { + failf(data, "SSL: couldn't create a context: OSStatus %d", err); + return CURLE_OUT_OF_MEMORY; + } +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */ + + /* check to see if we've been told to use an explicit SSL/TLS version */ +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + if(SSLSetProtocolVersionMax != NULL) { + switch(conn->ssl_config.version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1); + (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12); + break; + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + { + CURLcode result = set_ssl_version_min_max(conn, sockindex); + if(result != CURLE_OK) + return result; + break; + } + case CURL_SSLVERSION_SSLv3: + err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + } + (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3); + break; + case CURL_SSLVERSION_SSLv2: + err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + } + (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2); + break; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + } + else { +#if CURL_SUPPORT_MAC_10_8 + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kSSLProtocolAll, + false); + switch(conn->ssl_config.version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol1, + true); + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol11, + true); + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol12, + true); + break; + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + { + CURLcode result = set_ssl_version_min_max(conn, sockindex); + if(result != CURLE_OK) + return result; + break; + } + case CURL_SSLVERSION_SSLv3: + err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kSSLProtocol3, + true); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + } + break; + case CURL_SSLVERSION_SSLv2: + err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kSSLProtocol2, + true); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + } + break; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#else + if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) { + failf(data, "Your version of the OS does not support to set maximum" + " SSL/TLS version"); + return CURLE_SSL_CONNECT_ERROR; + } + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false); + switch(conn->ssl_config.version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol1, + true); + break; + case CURL_SSLVERSION_TLSv1_1: + failf(data, "Your version of the OS does not support TLSv1.1"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_TLSv1_2: + failf(data, "Your version of the OS does not support TLSv1.2"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_TLSv1_3: + failf(data, "Your version of the OS does not support TLSv1.3"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_SSLv2: + err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kSSLProtocol2, + true); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + } + break; + case CURL_SSLVERSION_SSLv3: + err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kSSLProtocol3, + true); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + } + break; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + + if(SSL_SET_OPTION(key)) { + infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure " + "Transport. The private key must be in the Keychain.\n"); + } + + if(ssl_cert) { + SecIdentityRef cert_and_key = NULL; + bool is_cert_file = is_file(ssl_cert); + + /* User wants to authenticate with a client cert. Look for it: + If we detect that this is a file on disk, then let's load it. + Otherwise, assume that the user wants to use an identity loaded + from the Keychain. */ + if(is_cert_file) { + if(!SSL_SET_OPTION(cert_type)) + infof(data, "WARNING: SSL: Certificate type not set, assuming " + "PKCS#12 format.\n"); + else if(strncmp(SSL_SET_OPTION(cert_type), "P12", + strlen(SSL_SET_OPTION(cert_type))) != 0) + infof(data, "WARNING: SSL: The Security framework only supports " + "loading identities that are in PKCS#12 format.\n"); + + err = CopyIdentityFromPKCS12File(ssl_cert, + SSL_SET_OPTION(key_passwd), &cert_and_key); + } + else + err = CopyIdentityWithLabel(ssl_cert, &cert_and_key); + + if(err == noErr && cert_and_key) { + SecCertificateRef cert = NULL; + CFTypeRef certs_c[1]; + CFArrayRef certs; + + /* If we found one, print it out: */ + err = SecIdentityCopyCertificate(cert_and_key, &cert); + if(err == noErr) { + CFStringRef cert_summary = CopyCertSubject(cert); + char cert_summary_c[128]; + + if(cert_summary) { + memset(cert_summary_c, 0, 128); + if(CFStringGetCString(cert_summary, + cert_summary_c, + 128, + kCFStringEncodingUTF8)) { + infof(data, "Client certificate: %s\n", cert_summary_c); + } + CFRelease(cert_summary); + CFRelease(cert); + } + } + certs_c[0] = cert_and_key; + certs = CFArrayCreate(NULL, (const void **)certs_c, 1L, + &kCFTypeArrayCallBacks); + err = SSLSetCertificate(connssl->ssl_ctx, certs); + if(certs) + CFRelease(certs); + if(err != noErr) { + failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err); + return CURLE_SSL_CERTPROBLEM; + } + CFRelease(cert_and_key); + } + else { + switch(err) { + case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */ + failf(data, "SSL: Incorrect password for the certificate \"%s\" " + "and its private key.", ssl_cert); + break; + case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */ + failf(data, "SSL: Couldn't make sense of the data in the " + "certificate \"%s\" and its private key.", + ssl_cert); + break; + case -25260: /* errSecPassphraseRequired */ + failf(data, "SSL The certificate \"%s\" requires a password.", + ssl_cert); + break; + case errSecItemNotFound: + failf(data, "SSL: Can't find the certificate \"%s\" and its private " + "key in the Keychain.", ssl_cert); + break; + default: + failf(data, "SSL: Can't load the certificate \"%s\" and its private " + "key: OSStatus %d", ssl_cert, err); + break; + } + return CURLE_SSL_CERTPROBLEM; + } + } + + /* SSL always tries to verify the peer, this only says whether it should + * fail to connect if the verification fails, or if it should continue + * anyway. In the latter case the result of the verification is checked with + * SSL_get_verify_result() below. */ +#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS + /* Snow Leopard introduced the SSLSetSessionOption() function, but due to + a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag + works, it doesn't work as expected under Snow Leopard, Lion or + Mountain Lion. + So we need to call SSLSetEnableCertVerify() on those older cats in order + to disable certificate validation if the user turned that off. + (SecureTransport will always validate the certificate chain by + default.) + Note: + Darwin 11.x.x is Lion (10.7) + Darwin 12.x.x is Mountain Lion (10.8) + Darwin 13.x.x is Mavericks (10.9) + Darwin 14.x.x is Yosemite (10.10) + Darwin 15.x.x is El Capitan (10.11) + */ +#if CURL_BUILD_MAC + if(SSLSetSessionOption != NULL && darwinver_maj >= 13) { +#else + if(SSLSetSessionOption != NULL) { +#endif /* CURL_BUILD_MAC */ + bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile; + err = SSLSetSessionOption(connssl->ssl_ctx, + kSSLSessionOptionBreakOnServerAuth, + break_on_auth); + if(err != noErr) { + failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + } + else { +#if CURL_SUPPORT_MAC_10_8 + err = SSLSetEnableCertVerify(connssl->ssl_ctx, + conn->ssl_config.verifypeer?true:false); + if(err != noErr) { + failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#else + err = SSLSetEnableCertVerify(connssl->ssl_ctx, + conn->ssl_config.verifypeer?true:false); + if(err != noErr) { + failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } +#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ + + if(ssl_cafile && verifypeer) { + bool is_cert_file = is_file(ssl_cafile); + + if(!is_cert_file) { + failf(data, "SSL: can't load CA certificate file %s", ssl_cafile); + return CURLE_SSL_CACERT_BADFILE; + } + } + + /* Configure hostname check. SNI is used if available. + * Both hostname check and SNI require SSLSetPeerDomainName(). + * Also: the verifyhost setting influences SNI usage */ + if(conn->ssl_config.verifyhost) { + err = SSLSetPeerDomainName(connssl->ssl_ctx, hostname, + strlen(hostname)); + + if(err != noErr) { + infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n", + err); + } + + if((Curl_inet_pton(AF_INET, hostname, &addr)) + #ifdef ENABLE_IPV6 + || (Curl_inet_pton(AF_INET6, hostname, &addr)) + #endif + ) { + infof(data, "WARNING: using IP address, SNI is being disabled by " + "the OS.\n"); + } + } + else { + infof(data, "WARNING: disabling hostname validation also disables SNI.\n"); + } + + /* Disable cipher suites that ST supports but are not safe. These ciphers + are unlikely to be used in any case since ST gives other ciphers a much + higher priority, but it's probably better that we not connect at all than + to give the user a false sense of security if the server only supports + insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */ + (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count); + all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); + allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); + if(all_ciphers && allowed_ciphers && + SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers, + &all_ciphers_count) == noErr) { + for(i = 0UL ; i < all_ciphers_count ; i++) { +#if CURL_BUILD_MAC + /* There's a known bug in early versions of Mountain Lion where ST's ECC + ciphers (cipher suite 0xC001 through 0xC032) simply do not work. + Work around the problem here by disabling those ciphers if we are + running in an affected version of OS X. */ + if(darwinver_maj == 12 && darwinver_min <= 3 && + all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) { + continue; + } +#endif /* CURL_BUILD_MAC */ + switch(all_ciphers[i]) { + /* Disable NULL ciphersuites: */ + case SSL_NULL_WITH_NULL_NULL: + case SSL_RSA_WITH_NULL_MD5: + case SSL_RSA_WITH_NULL_SHA: + case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */ + case SSL_FORTEZZA_DMS_WITH_NULL_SHA: + case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */ + case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */ + case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */ + case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */ + case 0x002C: /* TLS_PSK_WITH_NULL_SHA */ + case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */ + case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */ + case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */ + case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */ + case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */ + case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */ + case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */ + case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */ + /* Disable anonymous ciphersuites: */ + case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: + case SSL_DH_anon_WITH_RC4_128_MD5: + case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DH_anon_WITH_DES_CBC_SHA: + case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: + case TLS_DH_anon_WITH_AES_128_CBC_SHA: + case TLS_DH_anon_WITH_AES_256_CBC_SHA: + case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */ + case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */ + case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */ + case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */ + case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */ + case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */ + case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */ + case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */ + case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */ + /* Disable weak key ciphersuites: */ + case SSL_RSA_EXPORT_WITH_RC4_40_MD5: + case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: + case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: + case SSL_RSA_WITH_DES_CBC_SHA: + case SSL_DH_DSS_WITH_DES_CBC_SHA: + case SSL_DH_RSA_WITH_DES_CBC_SHA: + case SSL_DHE_DSS_WITH_DES_CBC_SHA: + case SSL_DHE_RSA_WITH_DES_CBC_SHA: + /* Disable IDEA: */ + case SSL_RSA_WITH_IDEA_CBC_SHA: + case SSL_RSA_WITH_IDEA_CBC_MD5: + /* Disable RC4: */ + case SSL_RSA_WITH_RC4_128_MD5: + case SSL_RSA_WITH_RC4_128_SHA: + case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */ + case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/ + case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */ + case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */ + case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */ + case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */ + case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */ + break; + default: /* enable everything else */ + allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i]; + break; + } + } + err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers, + allowed_ciphers_count); + if(err != noErr) { + failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + } + else { + Curl_safefree(all_ciphers); + Curl_safefree(allowed_ciphers); + failf(data, "SSL: Failed to allocate memory for allowed ciphers"); + return CURLE_OUT_OF_MEMORY; + } + Curl_safefree(all_ciphers); + Curl_safefree(allowed_ciphers); + +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + /* We want to enable 1/n-1 when using a CBC cipher unless the user + specifically doesn't want us doing that: */ + if(SSLSetSessionOption != NULL) { + /* TODO s/data->set.ssl.enable_beast/SSL_SET_OPTION(enable_beast)/g */ + SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord, + !data->set.ssl.enable_beast); + SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionFalseStart, + data->set.ssl.falsestart); /* false start support */ + } +#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ + + /* Check if there's a cached ID we can/should use here! */ + if(SSL_SET_OPTION(primary.sessionid)) { + char *ssl_sessionid; + size_t ssl_sessionid_len; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid, + &ssl_sessionid_len, sockindex)) { + /* we got a session id, use it! */ + err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len); + Curl_ssl_sessionid_unlock(conn); + if(err != noErr) { + failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + /* Informational message */ + infof(data, "SSL re-using session ID\n"); + } + /* If there isn't one, then let's make one up! This has to be done prior + to starting the handshake. */ + else { + CURLcode result; + ssl_sessionid = + aprintf("%s:%d:%d:%s:%hu", ssl_cafile, + verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port); + ssl_sessionid_len = strlen(ssl_sessionid); + + err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len); + if(err != noErr) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + + result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len, + sockindex); + Curl_ssl_sessionid_unlock(conn); + if(result) { + failf(data, "failed to store ssl session"); + return result; + } + } + } + + err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite); + if(err != noErr) { + failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + + /* pass the raw socket into the SSL layers */ + /* We need to store the FD in a constant memory address, because + * SSLSetConnection() will not copy that address. I've found that + * conn->sock[sockindex] may change on its own. */ + connssl->ssl_sockfd = sockfd; + err = SSLSetConnection(connssl->ssl_ctx, connssl); + if(err != noErr) { + failf(data, "SSL: SSLSetConnection() failed: %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; +} + +static long pem_to_der(const char *in, unsigned char **out, size_t *outlen) +{ + char *sep_start, *sep_end, *cert_start, *cert_end; + size_t i, j, err; + size_t len; + unsigned char *b64; + + /* Jump through the separators at the beginning of the certificate. */ + sep_start = strstr(in, "-----"); + if(sep_start == NULL) + return 0; + cert_start = strstr(sep_start + 1, "-----"); + if(cert_start == NULL) + return -1; + + cert_start += 5; + + /* Find separator after the end of the certificate. */ + cert_end = strstr(cert_start, "-----"); + if(cert_end == NULL) + return -1; + + sep_end = strstr(cert_end + 1, "-----"); + if(sep_end == NULL) + return -1; + sep_end += 5; + + len = cert_end - cert_start; + b64 = malloc(len + 1); + if(!b64) + return -1; + + /* Create base64 string without linefeeds. */ + for(i = 0, j = 0; i < len; i++) { + if(cert_start[i] != '\r' && cert_start[i] != '\n') + b64[j++] = cert_start[i]; + } + b64[j] = '\0'; + + err = Curl_base64_decode((const char *)b64, out, outlen); + free(b64); + if(err) { + free(*out); + return -1; + } + + return sep_end - in; +} + +static int read_cert(const char *file, unsigned char **out, size_t *outlen) +{ + int fd; + ssize_t n, len = 0, cap = 512; + unsigned char buf[cap], *data; + + fd = open(file, 0); + if(fd < 0) + return -1; + + data = malloc(cap); + if(!data) { + close(fd); + return -1; + } + + for(;;) { + n = read(fd, buf, sizeof(buf)); + if(n < 0) { + close(fd); + free(data); + return -1; + } + else if(n == 0) { + close(fd); + break; + } + + if(len + n >= cap) { + cap *= 2; + data = realloc(data, cap); + if(!data) { + close(fd); + return -1; + } + } + + memcpy(data + len, buf, n); + len += n; + } + data[len] = '\0'; + + *out = data; + *outlen = len; + + return 0; +} + +static int sslerr_to_curlerr(struct Curl_easy *data, int err) +{ + switch(err) { + case errSSLXCertChainInvalid: + failf(data, "SSL certificate problem: Invalid certificate chain"); + return CURLE_SSL_CACERT; + case errSSLUnknownRootCert: + failf(data, "SSL certificate problem: Untrusted root certificate"); + return CURLE_SSL_CACERT; + case errSSLNoRootCert: + failf(data, "SSL certificate problem: No root certificate"); + return CURLE_SSL_CACERT; + case errSSLCertExpired: + failf(data, "SSL certificate problem: Certificate chain had an " + "expired certificate"); + return CURLE_SSL_CACERT; + case errSSLBadCert: + failf(data, "SSL certificate problem: Couldn't understand the server " + "certificate format"); + return CURLE_SSL_CONNECT_ERROR; + case errSSLHostNameMismatch: + failf(data, "SSL certificate peer hostname mismatch"); + return CURLE_PEER_FAILED_VERIFICATION; + default: + failf(data, "SSL unexpected certificate error %d", err); + return CURLE_SSL_CACERT; + } +} + +static int append_cert_to_array(struct Curl_easy *data, + unsigned char *buf, size_t buflen, + CFMutableArrayRef array) +{ + CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen); + if(!certdata) { + failf(data, "SSL: failed to allocate array for CA certificate"); + return CURLE_OUT_OF_MEMORY; + } + + SecCertificateRef cacert = + SecCertificateCreateWithData(kCFAllocatorDefault, certdata); + CFRelease(certdata); + if(!cacert) { + failf(data, "SSL: failed to create SecCertificate from CA certificate"); + return CURLE_SSL_CACERT; + } + + /* Check if cacert is valid. */ + CFStringRef subject = CopyCertSubject(cacert); + if(subject) { + char subject_cbuf[128]; + memset(subject_cbuf, 0, 128); + if(!CFStringGetCString(subject, + subject_cbuf, + 128, + kCFStringEncodingUTF8)) { + CFRelease(cacert); + failf(data, "SSL: invalid CA certificate subject"); + return CURLE_SSL_CACERT; + } + CFRelease(subject); + } + else { + CFRelease(cacert); + failf(data, "SSL: invalid CA certificate"); + return CURLE_SSL_CACERT; + } + + CFArrayAppendValue(array, cacert); + CFRelease(cacert); + + return CURLE_OK; +} + +static int verify_cert(const char *cafile, struct Curl_easy *data, + SSLContextRef ctx) +{ + int n = 0, rc; + long res; + unsigned char *certbuf, *der; + size_t buflen, derlen, offset = 0; + + if(read_cert(cafile, &certbuf, &buflen) < 0) { + failf(data, "SSL: failed to read or invalid CA certificate"); + return CURLE_SSL_CACERT; + } + + /* + * Certbuf now contains the contents of the certificate file, which can be + * - a single DER certificate, + * - a single PEM certificate or + * - a bunch of PEM certificates (certificate bundle). + * + * Go through certbuf, and convert any PEM certificate in it into DER + * format. + */ + CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeArrayCallBacks); + if(array == NULL) { + free(certbuf); + failf(data, "SSL: out of memory creating CA certificate array"); + return CURLE_OUT_OF_MEMORY; + } + + while(offset < buflen) { + n++; + + /* + * Check if the certificate is in PEM format, and convert it to DER. If + * this fails, we assume the certificate is in DER format. + */ + res = pem_to_der((const char *)certbuf + offset, &der, &derlen); + if(res < 0) { + free(certbuf); + CFRelease(array); + failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle", + n, offset); + return CURLE_SSL_CACERT; + } + offset += res; + + if(res == 0 && offset == 0) { + /* This is not a PEM file, probably a certificate in DER format. */ + rc = append_cert_to_array(data, certbuf, buflen, array); + free(certbuf); + if(rc != CURLE_OK) { + CFRelease(array); + return rc; + } + break; + } + else if(res == 0) { + /* No more certificates in the bundle. */ + free(certbuf); + break; + } + + rc = append_cert_to_array(data, der, derlen, array); + free(der); + if(rc != CURLE_OK) { + free(certbuf); + CFRelease(array); + return rc; + } + } + + SecTrustRef trust; + OSStatus ret = SSLCopyPeerTrust(ctx, &trust); + if(trust == NULL) { + failf(data, "SSL: error getting certificate chain"); + CFRelease(array); + return CURLE_OUT_OF_MEMORY; + } + else if(ret != noErr) { + CFRelease(array); + return sslerr_to_curlerr(data, ret); + } + + ret = SecTrustSetAnchorCertificates(trust, array); + if(ret != noErr) { + CFRelease(trust); + return sslerr_to_curlerr(data, ret); + } + ret = SecTrustSetAnchorCertificatesOnly(trust, true); + if(ret != noErr) { + CFRelease(trust); + return sslerr_to_curlerr(data, ret); + } + + SecTrustResultType trust_eval = 0; + ret = SecTrustEvaluate(trust, &trust_eval); + CFRelease(array); + CFRelease(trust); + if(ret != noErr) { + return sslerr_to_curlerr(data, ret); + } + + switch(trust_eval) { + case kSecTrustResultUnspecified: + case kSecTrustResultProceed: + return CURLE_OK; + + case kSecTrustResultRecoverableTrustFailure: + case kSecTrustResultDeny: + default: + failf(data, "SSL: certificate verification failed (result: %d)", + trust_eval); + return CURLE_PEER_FAILED_VERIFICATION; + } +} + +#ifdef DARWIN_SSL_PINNEDPUBKEY +static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, + SSLContextRef ctx, + const char *pinnedpubkey) +{ /* Scratch */ + size_t pubkeylen, realpubkeylen, spkiHeaderLength = 24; + unsigned char *pubkey = NULL, *realpubkey = NULL; + const unsigned char *spkiHeader = NULL; + CFDataRef publicKeyBits = NULL; + + /* Result is returned to caller */ + CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + + /* if a path wasn't specified, don't pin */ + if(!pinnedpubkey) + return CURLE_OK; + + + if(!ctx) + return result; + + do { + SecTrustRef trust; + OSStatus ret = SSLCopyPeerTrust(ctx, &trust); + if(ret != noErr || trust == NULL) + break; + + SecKeyRef keyRef = SecTrustCopyPublicKey(trust); + CFRelease(trust); + if(keyRef == NULL) + break; + +#ifdef DARWIN_SSL_PINNEDPUBKEY_V1 + + publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL); + CFRelease(keyRef); + if(publicKeyBits == NULL) + break; + +#elif DARWIN_SSL_PINNEDPUBKEY_V2 + + OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL, + &publicKeyBits); + CFRelease(keyRef); + if(success != errSecSuccess || publicKeyBits == NULL) + break; + +#endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */ + + pubkeylen = CFDataGetLength(publicKeyBits); + pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits); + + switch(pubkeylen) { + case 526: + /* 4096 bit RSA pubkeylen == 526 */ + spkiHeader = rsa4096SpkiHeader; + break; + case 270: + /* 2048 bit RSA pubkeylen == 270 */ + spkiHeader = rsa2048SpkiHeader; + break; +#ifdef DARWIN_SSL_PINNEDPUBKEY_V1 + case 65: + /* ecDSA secp256r1 pubkeylen == 65 */ + spkiHeader = ecDsaSecp256r1SpkiHeader; + spkiHeaderLength = 26; + break; + case 97: + /* ecDSA secp384r1 pubkeylen == 97 */ + spkiHeader = ecDsaSecp384r1SpkiHeader; + spkiHeaderLength = 23; + break; + default: + infof(data, "SSL: unhandled public key length: %d\n", pubkeylen); +#elif DARWIN_SSL_PINNEDPUBKEY_V2 + default: + /* ecDSA secp256r1 pubkeylen == 91 header already included? + * ecDSA secp384r1 header already included too + * we assume rest of algorithms do same, so do nothing + */ + result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey, + pubkeylen); +#endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */ + continue; /* break from loop */ + } + + realpubkeylen = pubkeylen + spkiHeaderLength; + realpubkey = malloc(realpubkeylen); + if(!realpubkey) + break; + + memcpy(realpubkey, spkiHeader, spkiHeaderLength); + memcpy(realpubkey + spkiHeaderLength, pubkey, pubkeylen); + + result = Curl_pin_peer_pubkey(data, pinnedpubkey, realpubkey, + realpubkeylen); + + } while(0); + + Curl_safefree(realpubkey); + if(publicKeyBits != NULL) + CFRelease(publicKeyBits); + + return result; +} +#endif /* DARWIN_SSL_PINNEDPUBKEY */ + +static CURLcode +darwinssl_connect_step2(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + OSStatus err; + SSLCipherSuite cipher; + SSLProtocol protocol = 0; + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + + DEBUGASSERT(ssl_connect_2 == connssl->connecting_state + || ssl_connect_2_reading == connssl->connecting_state + || ssl_connect_2_writing == connssl->connecting_state); + + /* Here goes nothing: */ + err = SSLHandshake(connssl->ssl_ctx); + + if(err != noErr) { + switch(err) { + case errSSLWouldBlock: /* they're not done with us yet */ + connssl->connecting_state = connssl->ssl_direction ? + ssl_connect_2_writing : ssl_connect_2_reading; + return CURLE_OK; + + /* The below is errSSLServerAuthCompleted; it's not defined in + Leopard's headers */ + case -9841: + if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { + int res = verify_cert(SSL_CONN_CONFIG(CAfile), data, + connssl->ssl_ctx); + if(res != CURLE_OK) + return res; + } + /* the documentation says we need to call SSLHandshake() again */ + return darwinssl_connect_step2(conn, sockindex); + + /* These are all certificate problems with the server: */ + case errSSLXCertChainInvalid: + failf(data, "SSL certificate problem: Invalid certificate chain"); + return CURLE_SSL_CACERT; + case errSSLUnknownRootCert: + failf(data, "SSL certificate problem: Untrusted root certificate"); + return CURLE_SSL_CACERT; + case errSSLNoRootCert: + failf(data, "SSL certificate problem: No root certificate"); + return CURLE_SSL_CACERT; + case errSSLCertExpired: + failf(data, "SSL certificate problem: Certificate chain had an " + "expired certificate"); + return CURLE_SSL_CACERT; + case errSSLBadCert: + failf(data, "SSL certificate problem: Couldn't understand the server " + "certificate format"); + return CURLE_SSL_CONNECT_ERROR; + + /* These are all certificate problems with the client: */ + case errSecAuthFailed: + failf(data, "SSL authentication failed"); + return CURLE_SSL_CONNECT_ERROR; + case errSSLPeerHandshakeFail: + failf(data, "SSL peer handshake failed, the server most likely " + "requires a client certificate to connect"); + return CURLE_SSL_CONNECT_ERROR; + case errSSLPeerUnknownCA: + failf(data, "SSL server rejected the client certificate due to " + "the certificate being signed by an unknown certificate " + "authority"); + return CURLE_SSL_CONNECT_ERROR; + + /* This error is raised if the server's cert didn't match the server's + host name: */ + case errSSLHostNameMismatch: + failf(data, "SSL certificate peer verification failed, the " + "certificate did not match \"%s\"\n", conn->host.dispname); + return CURLE_PEER_FAILED_VERIFICATION; + + /* Generic handshake errors: */ + case errSSLConnectionRefused: + failf(data, "Server dropped the connection during the SSL handshake"); + return CURLE_SSL_CONNECT_ERROR; + case errSSLClosedAbort: + failf(data, "Server aborted the SSL handshake"); + return CURLE_SSL_CONNECT_ERROR; + case errSSLNegotiation: + failf(data, "Could not negotiate an SSL cipher suite with the server"); + return CURLE_SSL_CONNECT_ERROR; + /* Sometimes paramErr happens with buggy ciphers: */ + case paramErr: case errSSLInternal: + failf(data, "Internal SSL engine error encountered during the " + "SSL handshake"); + return CURLE_SSL_CONNECT_ERROR; + case errSSLFatalAlert: + failf(data, "Fatal SSL engine error encountered during the SSL " + "handshake"); + return CURLE_SSL_CONNECT_ERROR; + default: + failf(data, "Unknown SSL protocol error in connection to %s:%d", + hostname, err); + return CURLE_SSL_CONNECT_ERROR; + } + } + else { + /* we have been connected fine, we're not waiting for anything else. */ + connssl->connecting_state = ssl_connect_3; + +#ifdef DARWIN_SSL_PINNEDPUBKEY + if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) { + CURLcode result = pkp_pin_peer_pubkey(data, connssl->ssl_ctx, + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + return result; + } + } +#endif /* DARWIN_SSL_PINNEDPUBKEY */ + + /* Informational message */ + (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher); + (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol); + switch(protocol) { + case kSSLProtocol2: + infof(data, "SSL 2.0 connection using %s\n", + SSLCipherNameForNumber(cipher)); + break; + case kSSLProtocol3: + infof(data, "SSL 3.0 connection using %s\n", + SSLCipherNameForNumber(cipher)); + break; + case kTLSProtocol1: + infof(data, "TLS 1.0 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + case kTLSProtocol11: + infof(data, "TLS 1.1 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; + case kTLSProtocol12: + infof(data, "TLS 1.2 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; +#endif + default: + infof(data, "Unknown protocol connection\n"); + break; + } + + return CURLE_OK; + } +} + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +/* This should be called during step3 of the connection at the earliest */ +static void +show_verbose_server_cert(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + CFStringRef server_cert_summary; + char server_cert_summary_c[128]; + CFArrayRef server_certs = NULL; + SecCertificateRef server_cert; + OSStatus err; + CFIndex i, count; + SecTrustRef trust = NULL; + + if(!connssl->ssl_ctx) + return; + +#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS +#if CURL_BUILD_IOS +#pragma unused(server_certs) + err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust); + /* For some reason, SSLCopyPeerTrust() can return noErr and yet return + a null trust, so be on guard for that: */ + if(err == noErr && trust) { + count = SecTrustGetCertificateCount(trust); + for(i = 0L ; i < count ; i++) { + server_cert = SecTrustGetCertificateAtIndex(trust, i); + server_cert_summary = CopyCertSubject(server_cert); + memset(server_cert_summary_c, 0, 128); + if(CFStringGetCString(server_cert_summary, + server_cert_summary_c, + 128, + kCFStringEncodingUTF8)) { + infof(data, "Server certificate: %s\n", server_cert_summary_c); + } + CFRelease(server_cert_summary); + } + CFRelease(trust); + } +#else + /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion. + The function SecTrustGetCertificateAtIndex() is officially present + in Lion, but it is unfortunately also present in Snow Leopard as + private API and doesn't work as expected. So we have to look for + a different symbol to make sure this code is only executed under + Lion or later. */ + if(SecTrustEvaluateAsync != NULL) { +#pragma unused(server_certs) + err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust); + /* For some reason, SSLCopyPeerTrust() can return noErr and yet return + a null trust, so be on guard for that: */ + if(err == noErr && trust) { + count = SecTrustGetCertificateCount(trust); + for(i = 0L ; i < count ; i++) { + server_cert = SecTrustGetCertificateAtIndex(trust, i); + server_cert_summary = CopyCertSubject(server_cert); + memset(server_cert_summary_c, 0, 128); + if(CFStringGetCString(server_cert_summary, + server_cert_summary_c, + 128, + kCFStringEncodingUTF8)) { + infof(data, "Server certificate: %s\n", server_cert_summary_c); + } + CFRelease(server_cert_summary); + } + CFRelease(trust); + } + } + else { +#if CURL_SUPPORT_MAC_10_8 + err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs); + /* Just in case SSLCopyPeerCertificates() returns null too... */ + if(err == noErr && server_certs) { + count = CFArrayGetCount(server_certs); + for(i = 0L ; i < count ; i++) { + server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, + i); + + server_cert_summary = CopyCertSubject(server_cert); + memset(server_cert_summary_c, 0, 128); + if(CFStringGetCString(server_cert_summary, + server_cert_summary_c, + 128, + kCFStringEncodingUTF8)) { + infof(data, "Server certificate: %s\n", server_cert_summary_c); + } + CFRelease(server_cert_summary); + } + CFRelease(server_certs); + } +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#endif /* CURL_BUILD_IOS */ +#else +#pragma unused(trust) + err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs); + if(err == noErr) { + count = CFArrayGetCount(server_certs); + for(i = 0L ; i < count ; i++) { + server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i); + server_cert_summary = CopyCertSubject(server_cert); + memset(server_cert_summary_c, 0, 128); + if(CFStringGetCString(server_cert_summary, + server_cert_summary_c, + 128, + kCFStringEncodingUTF8)) { + infof(data, "Server certificate: %s\n", server_cert_summary_c); + } + CFRelease(server_cert_summary); + } + CFRelease(server_certs); + } +#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ +} +#endif /* !CURL_DISABLE_VERBOSE_STRINGS */ + +static CURLcode +darwinssl_connect_step3(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + /* There is no step 3! + * Well, okay, if verbose mode is on, let's print the details of the + * server certificates. */ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(data->set.verbose) + show_verbose_server_cert(conn, sockindex); +#endif + + connssl->connecting_state = ssl_connect_done; + return CURLE_OK; +} + +static Curl_recv darwinssl_recv; +static Curl_send darwinssl_send; + +static CURLcode +darwinssl_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + long timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1==connssl->connecting_state) { + /* Find out how much more time we're allowed */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + result = darwinssl_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading || + connssl->connecting_state == ssl_connect_2_writing) { + + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking?0:timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if this + * connection is done nonblocking and this loop would execute again. This + * permits the owner of a multi handle to abort a connection attempt + * before step2 has completed while ensuring that a client using select() + * or epoll() will always have a valid fdset to wait on. + */ + result = darwinssl_connect_step2(conn, sockindex); + if(result || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return result; + + } /* repeat step2 until all transactions are done. */ + + + if(ssl_connect_3 == connssl->connecting_state) { + result = darwinssl_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = darwinssl_recv; + conn->send[sockindex] = darwinssl_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +CURLcode +Curl_darwinssl_connect_nonblocking(struct connectdata *conn, + int sockindex, + bool *done) +{ + return darwinssl_connect_common(conn, sockindex, TRUE, done); +} + +CURLcode +Curl_darwinssl_connect(struct connectdata *conn, + int sockindex) +{ + CURLcode result; + bool done = FALSE; + + result = darwinssl_connect_common(conn, sockindex, FALSE, &done); + + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +void Curl_darwinssl_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + if(connssl->ssl_ctx) { + (void)SSLClose(connssl->ssl_ctx); +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + if(SSLCreateContext != NULL) + CFRelease(connssl->ssl_ctx); +#if CURL_SUPPORT_MAC_10_8 + else + (void)SSLDisposeContext(connssl->ssl_ctx); +#endif /* CURL_SUPPORT_MAC_10_8 */ +#else + (void)SSLDisposeContext(connssl->ssl_ctx); +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + connssl->ssl_ctx = NULL; + } + connssl->ssl_sockfd = 0; +} + +int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct Curl_easy *data = conn->data; + ssize_t nread; + int what; + int rc; + char buf[120]; + + if(!connssl->ssl_ctx) + return 0; + + if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE) + return 0; + + Curl_darwinssl_close(conn, sockindex); + + rc = 0; + + what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT); + + for(;;) { + if(what < 0) { + /* anything that gets here is fatally bad */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + rc = -1; + break; + } + + if(!what) { /* timeout */ + failf(data, "SSL shutdown timeout"); + break; + } + + /* Something to read, let's do it and hope that it is the close + notify alert from the server. No way to SSL_Read now, so use read(). */ + + nread = read(conn->sock[sockindex], buf, sizeof(buf)); + + if(nread < 0) { + failf(data, "read: %s", strerror(errno)); + rc = -1; + } + + if(nread <= 0) + break; + + what = SOCKET_READABLE(conn->sock[sockindex], 0); + } + + return rc; +} + +void Curl_darwinssl_session_free(void *ptr) +{ + /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a + cached session ID inside the Security framework. There is a private + function that does this, but I don't want to have to explain to you why I + got your application rejected from the App Store due to the use of a + private API, so the best we can do is free up our own char array that we + created way back in darwinssl_connect_step1... */ + Curl_safefree(ptr); +} + +size_t Curl_darwinssl_version(char *buffer, size_t size) +{ + return snprintf(buffer, size, "SecureTransport"); +} + +/* + * This function uses SSLGetSessionState to determine connection status. + * + * Return codes: + * 1 means the connection is still in place + * 0 means the connection has been closed + * -1 means the connection status is unknown + */ +int Curl_darwinssl_check_cxn(struct connectdata *conn) +{ + struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; + OSStatus err; + SSLSessionState state; + + if(connssl->ssl_ctx) { + err = SSLGetSessionState(connssl->ssl_ctx, &state); + if(err == noErr) + return state == kSSLConnected || state == kSSLHandshake; + return -1; + } + return 0; +} + +bool Curl_darwinssl_data_pending(const struct connectdata *conn, + int connindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[connindex]; + OSStatus err; + size_t buffer; + + if(connssl->ssl_ctx) { /* SSL is in use */ + err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer); + if(err == noErr) + return buffer > 0UL; + return false; + } + else + return false; +} + +CURLcode Curl_darwinssl_random(unsigned char *entropy, + size_t length) +{ + /* arc4random_buf() isn't available on cats older than Lion, so let's + do this manually for the benefit of the older cats. */ + size_t i; + u_int32_t random_number = 0; + + for(i = 0 ; i < length ; i++) { + if(i % sizeof(u_int32_t) == 0) + random_number = arc4random(); + entropy[i] = random_number & 0xFF; + random_number >>= 8; + } + i = random_number = 0; + return CURLE_OK; +} + +void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *md5sum, /* output */ + size_t md5len) +{ + (void)md5len; + (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum); +} + +void Curl_darwinssl_sha256sum(unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *sha256sum, /* output */ + size_t sha256len) +{ + assert(sha256len >= SHA256_DIGEST_LENGTH); + (void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum); +} + +bool Curl_darwinssl_false_start(void) +{ +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + if(SSLSetSessionOption != NULL) + return TRUE; +#endif + return FALSE; +} + +static ssize_t darwinssl_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) +{ + /*struct Curl_easy *data = conn->data;*/ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + size_t processed = 0UL; + OSStatus err; + + /* The SSLWrite() function works a little differently than expected. The + fourth argument (processed) is currently documented in Apple's + documentation as: "On return, the length, in bytes, of the data actually + written." + + Now, one could interpret that as "written to the socket," but actually, + it returns the amount of data that was written to a buffer internal to + the SSLContextRef instead. So it's possible for SSLWrite() to return + errSSLWouldBlock and a number of bytes "written" because those bytes were + encrypted and written to a buffer, not to the socket. + + So if this happens, then we need to keep calling SSLWrite() over and + over again with no new data until it quits returning errSSLWouldBlock. */ + + /* Do we have buffered data to write from the last time we were called? */ + if(connssl->ssl_write_buffered_length) { + /* Write the buffered data: */ + err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed); + switch(err) { + case noErr: + /* processed is always going to be 0 because we didn't write to + the buffer, so return how much was written to the socket */ + processed = connssl->ssl_write_buffered_length; + connssl->ssl_write_buffered_length = 0UL; + break; + case errSSLWouldBlock: /* argh, try again */ + *curlcode = CURLE_AGAIN; + return -1L; + default: + failf(conn->data, "SSLWrite() returned error %d", err); + *curlcode = CURLE_SEND_ERROR; + return -1L; + } + } + else { + /* We've got new data to write: */ + err = SSLWrite(connssl->ssl_ctx, mem, len, &processed); + if(err != noErr) { + switch(err) { + case errSSLWouldBlock: + /* Data was buffered but not sent, we have to tell the caller + to try sending again, and remember how much was buffered */ + connssl->ssl_write_buffered_length = len; + *curlcode = CURLE_AGAIN; + return -1L; + default: + failf(conn->data, "SSLWrite() returned error %d", err); + *curlcode = CURLE_SEND_ERROR; + return -1L; + } + } + } + return (ssize_t)processed; +} + +static ssize_t darwinssl_recv(struct connectdata *conn, + int num, + char *buf, + size_t buffersize, + CURLcode *curlcode) +{ + /*struct Curl_easy *data = conn->data;*/ + struct ssl_connect_data *connssl = &conn->ssl[num]; + size_t processed = 0UL; + OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed); + + if(err != noErr) { + switch(err) { + case errSSLWouldBlock: /* return how much we read (if anything) */ + if(processed) + return (ssize_t)processed; + *curlcode = CURLE_AGAIN; + return -1L; + break; + + /* errSSLClosedGraceful - server gracefully shut down the SSL session + errSSLClosedNoNotify - server hung up on us instead of sending a + closure alert notice, read() is returning 0 + Either way, inform the caller that the server disconnected. */ + case errSSLClosedGraceful: + case errSSLClosedNoNotify: + *curlcode = CURLE_OK; + return -1L; + break; + + default: + failf(conn->data, "SSLRead() return error %d", err); + *curlcode = CURLE_RECV_ERROR; + return -1L; + break; + } + } + return (ssize_t)processed; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif /* USE_DARWINSSL */ diff --git a/libcurl/lib/vtls/darwinssl.h b/libcurl/lib/vtls/darwinssl.h new file mode 100644 index 0000000..13e7851 --- /dev/null +++ b/libcurl/lib/vtls/darwinssl.h @@ -0,0 +1,101 @@ +#ifndef HEADER_CURL_DARWINSSL_H +#define HEADER_CURL_DARWINSSL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2014, Nick Zitzmann, . + * Copyright (C) 2012 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_DARWINSSL + +CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex); + +CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn, + int sockindex, + bool *done); + +/* close a SSL connection */ +void Curl_darwinssl_close(struct connectdata *conn, int sockindex); + +void Curl_darwinssl_session_free(void *ptr); +size_t Curl_darwinssl_version(char *buffer, size_t size); +int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex); +int Curl_darwinssl_check_cxn(struct connectdata *conn); +bool Curl_darwinssl_data_pending(const struct connectdata *conn, + int connindex); + +CURLcode Curl_darwinssl_random(unsigned char *entropy, + size_t length); +void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *md5sum, /* output */ + size_t md5len); +void Curl_darwinssl_sha256sum(unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *sha256sum, /* output */ + size_t sha256len); +bool Curl_darwinssl_false_start(void); + +/* Set the API backend definition to SecureTransport */ +#define CURL_SSL_BACKEND CURLSSLBACKEND_DARWINSSL + +/* pinned public key support tests */ + +/* version 1 supports macOS 10.12+ and iOS 10+ */ +#if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \ + (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)) +#define DARWIN_SSL_PINNEDPUBKEY_V1 1 +#endif + +/* version 2 supports MacOSX 10.7+ */ +#if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) +#define DARWIN_SSL_PINNEDPUBKEY_V2 1 +#endif + +#if defined(DARWIN_SSL_PINNEDPUBKEY_V1) || defined(DARWIN_SSL_PINNEDPUBKEY_V2) +/* this backend supports CURLOPT_PINNEDPUBLICKEY */ +#define DARWIN_SSL_PINNEDPUBKEY 1 +#define have_curlssl_pinnedpubkey 1 +#endif /* DARWIN_SSL_PINNEDPUBKEY */ + +/* API setup for SecureTransport */ +#define curlssl_init() (1) +#define curlssl_cleanup() Curl_nop_stmt +#define curlssl_connect Curl_darwinssl_connect +#define curlssl_connect_nonblocking Curl_darwinssl_connect_nonblocking +#define curlssl_session_free(x) Curl_darwinssl_session_free(x) +#define curlssl_close_all(x) ((void)x) +#define curlssl_close Curl_darwinssl_close +#define curlssl_shutdown(x,y) 0 +#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN) +#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN) +#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL) +#define curlssl_version Curl_darwinssl_version +#define curlssl_check_cxn Curl_darwinssl_check_cxn +#define curlssl_data_pending(x,y) Curl_darwinssl_data_pending(x, y) +#define curlssl_random(x,y,z) ((void)x, Curl_darwinssl_random(y,z)) +#define curlssl_md5sum(a,b,c,d) Curl_darwinssl_md5sum(a,b,c,d) +#define curlssl_sha256sum(a,b,c,d) \ + Curl_darwinssl_sha256sum((unsigned char *)a, b, c, d) +#define curlssl_false_start() Curl_darwinssl_false_start() + +#endif /* USE_DARWINSSL */ +#endif /* HEADER_CURL_DARWINSSL_H */ diff --git a/libcurl/lib/vtls/debug_utility.cpp b/libcurl/lib/vtls/debug_utility.cpp new file mode 100644 index 0000000..6ba3c4b --- /dev/null +++ b/libcurl/lib/vtls/debug_utility.cpp @@ -0,0 +1,28 @@ +#include "debug_utility.h" + +#include +#include +#include + +int debug_utility::debug_print(const char* format, ...) +{ + /* Use a fixed buffer since VS2003 doesn't support va_copy */ + char message[512]; + va_list args; + int length; + + va_start(args, format); + length = _vsnprintf(message, sizeof(message) - 1, format, args); + va_end(args); + + /* Ensure null termination */ + if (length < 0 || length >= (int)sizeof(message)) { + message[sizeof(message) - 1] = '\0'; + length = (int)sizeof(message) - 1; + } else { + message[length] = '\0'; + } + + OutputDebugStringA(message); + return length; +} \ No newline at end of file diff --git a/libcurl/lib/vtls/debug_utility.h b/libcurl/lib/vtls/debug_utility.h new file mode 100644 index 0000000..62c7817 --- /dev/null +++ b/libcurl/lib/vtls/debug_utility.h @@ -0,0 +1,7 @@ +#pragma once + +class debug_utility +{ +public: + static int debug_print(const char* format, ...); +}; diff --git a/libcurl/lib/vtls/gskit.c b/libcurl/lib/vtls/gskit.c new file mode 100644 index 0000000..b93ff5d --- /dev/null +++ b/libcurl/lib/vtls/gskit.c @@ -0,0 +1,1381 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_GSKIT + +#include +#include + +/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */ +#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST +#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230 +#endif + +#ifndef GSK_TLSV10_CIPHER_SPECS +#define GSK_TLSV10_CIPHER_SPECS 236 +#endif + +#ifndef GSK_TLSV11_CIPHER_SPECS +#define GSK_TLSV11_CIPHER_SPECS 237 +#endif + +#ifndef GSK_TLSV12_CIPHER_SPECS +#define GSK_TLSV12_CIPHER_SPECS 238 +#endif + +#ifndef GSK_PROTOCOL_TLSV11 +#define GSK_PROTOCOL_TLSV11 437 +#endif + +#ifndef GSK_PROTOCOL_TLSV12 +#define GSK_PROTOCOL_TLSV12 438 +#endif + +#ifndef GSK_FALSE +#define GSK_FALSE 0 +#endif + +#ifndef GSK_TRUE +#define GSK_TRUE 1 +#endif + + +#include + +#include +#include "urldata.h" +#include "sendf.h" +#include "gskit.h" +#include "vtls.h" +#include "connect.h" /* for the connect timeout */ +#include "select.h" +#include "strcase.h" +#include "x509asn1.h" +#include "curl_printf.h" + +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + + +/* Directions. */ +#define SOS_READ 0x01 +#define SOS_WRITE 0x02 + +/* SSL version flags. */ +#define CURL_GSKPROTO_SSLV2 0 +#define CURL_GSKPROTO_SSLV2_MASK (1 << CURL_GSKPROTO_SSLV2) +#define CURL_GSKPROTO_SSLV3 1 +#define CURL_GSKPROTO_SSLV3_MASK (1 << CURL_GSKPROTO_SSLV3) +#define CURL_GSKPROTO_TLSV10 2 +#define CURL_GSKPROTO_TLSV10_MASK (1 << CURL_GSKPROTO_TLSV10) +#define CURL_GSKPROTO_TLSV11 3 +#define CURL_GSKPROTO_TLSV11_MASK (1 << CURL_GSKPROTO_TLSV11) +#define CURL_GSKPROTO_TLSV12 4 +#define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12) +#define CURL_GSKPROTO_LAST 5 + +struct ssl_backend_data { + gsk_handle handle; + int iocport; + int localfd; + int remotefd; +}; + +#define BACKEND connssl->backend + +/* Supported ciphers. */ +typedef struct { + const char *name; /* Cipher name. */ + const char *gsktoken; /* Corresponding token for GSKit String. */ + unsigned int versions; /* SSL version flags. */ +} gskit_cipher; + +static const gskit_cipher ciphertable[] = { + { "null-md5", "01", + CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | + CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK }, + { "null-sha", "02", + CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | + CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK }, + { "exp-rc4-md5", "03", + CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK }, + { "rc4-md5", "04", + CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | + CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK }, + { "rc4-sha", "05", + CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | + CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK }, + { "exp-rc2-cbc-md5", "06", + CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK }, + { "exp-des-cbc-sha", "09", + CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | + CURL_GSKPROTO_TLSV11_MASK }, + { "des-cbc3-sha", "0A", + CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | + CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK }, + { "aes128-sha", "2F", + CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK | + CURL_GSKPROTO_TLSV12_MASK }, + { "aes256-sha", "35", + CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK | + CURL_GSKPROTO_TLSV12_MASK }, + { "null-sha256", "3B", CURL_GSKPROTO_TLSV12_MASK }, + { "aes128-sha256", "3C", CURL_GSKPROTO_TLSV12_MASK }, + { "aes256-sha256", "3D", CURL_GSKPROTO_TLSV12_MASK }, + { "aes128-gcm-sha256", + "9C", CURL_GSKPROTO_TLSV12_MASK }, + { "aes256-gcm-sha384", + "9D", CURL_GSKPROTO_TLSV12_MASK }, + { "rc4-md5", "1", CURL_GSKPROTO_SSLV2_MASK }, + { "exp-rc4-md5", "2", CURL_GSKPROTO_SSLV2_MASK }, + { "rc2-md5", "3", CURL_GSKPROTO_SSLV2_MASK }, + { "exp-rc2-md5", "4", CURL_GSKPROTO_SSLV2_MASK }, + { "des-cbc-md5", "6", CURL_GSKPROTO_SSLV2_MASK }, + { "des-cbc3-md5", "7", CURL_GSKPROTO_SSLV2_MASK }, + { (const char *) NULL, (const char *) NULL, 0 } +}; + + +static bool is_separator(char c) +{ + /* Return whether character is a cipher list separator. */ + switch(c) { + case ' ': + case '\t': + case ':': + case ',': + case ';': + return true; + } + return false; +} + + +static CURLcode gskit_status(struct Curl_easy *data, int rc, + const char *procname, CURLcode defcode) +{ + /* Process GSKit status and map it to a CURLcode. */ + switch(rc) { + case GSK_OK: + case GSK_OS400_ASYNCHRONOUS_SOC_INIT: + return CURLE_OK; + case GSK_KEYRING_OPEN_ERROR: + case GSK_OS400_ERROR_NO_ACCESS: + return CURLE_SSL_CACERT_BADFILE; + case GSK_INSUFFICIENT_STORAGE: + return CURLE_OUT_OF_MEMORY; + case GSK_ERROR_BAD_V2_CIPHER: + case GSK_ERROR_BAD_V3_CIPHER: + case GSK_ERROR_NO_CIPHERS: + return CURLE_SSL_CIPHER; + case GSK_OS400_ERROR_NOT_TRUSTED_ROOT: + case GSK_ERROR_CERT_VALIDATION: + return CURLE_PEER_FAILED_VERIFICATION; + case GSK_OS400_ERROR_TIMED_OUT: + return CURLE_OPERATION_TIMEDOUT; + case GSK_WOULD_BLOCK: + return CURLE_AGAIN; + case GSK_OS400_ERROR_NOT_REGISTERED: + break; + case GSK_ERROR_IO: + switch(errno) { + case ENOMEM: + return CURLE_OUT_OF_MEMORY; + default: + failf(data, "%s I/O error: %s", procname, strerror(errno)); + break; + } + break; + default: + failf(data, "%s: %s", procname, gsk_strerror(rc)); + break; + } + return defcode; +} + + +static CURLcode set_enum(struct Curl_easy *data, gsk_handle h, + GSK_ENUM_ID id, GSK_ENUM_VALUE value, bool unsupported_ok) +{ + int rc = gsk_attribute_set_enum(h, id, value); + + switch(rc) { + case GSK_OK: + return CURLE_OK; + case GSK_ERROR_IO: + failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno)); + break; + case GSK_ATTRIBUTE_INVALID_ID: + if(unsupported_ok) + return CURLE_UNSUPPORTED_PROTOCOL; + default: + failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc)); + break; + } + return CURLE_SSL_CONNECT_ERROR; +} + + +static CURLcode set_buffer(struct Curl_easy *data, gsk_handle h, + GSK_BUF_ID id, const char *buffer, bool unsupported_ok) +{ + int rc = gsk_attribute_set_buffer(h, id, buffer, 0); + + switch(rc) { + case GSK_OK: + return CURLE_OK; + case GSK_ERROR_IO: + failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno)); + break; + case GSK_ATTRIBUTE_INVALID_ID: + if(unsupported_ok) + return CURLE_UNSUPPORTED_PROTOCOL; + default: + failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc)); + break; + } + return CURLE_SSL_CONNECT_ERROR; +} + + +static CURLcode set_numeric(struct Curl_easy *data, + gsk_handle h, GSK_NUM_ID id, int value) +{ + int rc = gsk_attribute_set_numeric_value(h, id, value); + + switch(rc) { + case GSK_OK: + return CURLE_OK; + case GSK_ERROR_IO: + failf(data, "gsk_attribute_set_numeric_value() I/O error: %s", + strerror(errno)); + break; + default: + failf(data, "gsk_attribute_set_numeric_value(): %s", gsk_strerror(rc)); + break; + } + return CURLE_SSL_CONNECT_ERROR; +} + + +static CURLcode set_callback(struct Curl_easy *data, + gsk_handle h, GSK_CALLBACK_ID id, void *info) +{ + int rc = gsk_attribute_set_callback(h, id, info); + + switch(rc) { + case GSK_OK: + return CURLE_OK; + case GSK_ERROR_IO: + failf(data, "gsk_attribute_set_callback() I/O error: %s", strerror(errno)); + break; + default: + failf(data, "gsk_attribute_set_callback(): %s", gsk_strerror(rc)); + break; + } + return CURLE_SSL_CONNECT_ERROR; +} + + +static CURLcode set_ciphers(struct connectdata *conn, + gsk_handle h, unsigned int *protoflags) +{ + struct Curl_easy *data = conn->data; + const char *cipherlist = SSL_CONN_CONFIG(cipher_list); + const char *clp; + const gskit_cipher *ctp; + int i; + int l; + bool unsupported; + CURLcode result; + struct { + char *buf; + char *ptr; + } ciphers[CURL_GSKPROTO_LAST]; + + /* Compile cipher list into GSKit-compatible cipher lists. */ + + if(!cipherlist) + return CURLE_OK; + while(is_separator(*cipherlist)) /* Skip initial separators. */ + cipherlist++; + if(!*cipherlist) + return CURLE_OK; + + /* We allocate GSKit buffers of the same size as the input string: since + GSKit tokens are always shorter than their cipher names, allocated buffers + will always be large enough to accommodate the result. */ + l = strlen(cipherlist) + 1; + memset((char *) ciphers, 0, sizeof(ciphers)); + for(i = 0; i < CURL_GSKPROTO_LAST; i++) { + ciphers[i].buf = malloc(l); + if(!ciphers[i].buf) { + while(i--) + free(ciphers[i].buf); + return CURLE_OUT_OF_MEMORY; + } + ciphers[i].ptr = ciphers[i].buf; + *ciphers[i].ptr = '\0'; + } + + /* Process each cipher in input string. */ + unsupported = FALSE; + result = CURLE_OK; + for(;;) { + for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);) + cipherlist++; + l = cipherlist - clp; + if(!l) + break; + /* Search the cipher in our table. */ + for(ctp = ciphertable; ctp->name; ctp++) + if(strncasecompare(ctp->name, clp, l) && !ctp->name[l]) + break; + if(!ctp->name) { + failf(data, "Unknown cipher %.*s", l, clp); + result = CURLE_SSL_CIPHER; + } + else { + unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK | + CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK)); + for(i = 0; i < CURL_GSKPROTO_LAST; i++) { + if(ctp->versions & (1 << i)) { + strcpy(ciphers[i].ptr, ctp->gsktoken); + ciphers[i].ptr += strlen(ctp->gsktoken); + } + } + } + + /* Advance to next cipher name or end of string. */ + while(is_separator(*cipherlist)) + cipherlist++; + } + + /* Disable protocols with empty cipher lists. */ + for(i = 0; i < CURL_GSKPROTO_LAST; i++) { + if(!(*protoflags & (1 << i)) || !ciphers[i].buf[0]) { + *protoflags &= ~(1 << i); + ciphers[i].buf[0] = '\0'; + } + } + + /* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */ + if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) { + result = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS, + ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE); + if(result == CURLE_UNSUPPORTED_PROTOCOL) { + result = CURLE_OK; + if(unsupported) { + failf(data, "TLSv1.1-only ciphers are not yet supported"); + result = CURLE_SSL_CIPHER; + } + } + } + if(!result && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) { + result = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS, + ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE); + if(result == CURLE_UNSUPPORTED_PROTOCOL) { + result = CURLE_OK; + if(unsupported) { + failf(data, "TLSv1.2-only ciphers are not yet supported"); + result = CURLE_SSL_CIPHER; + } + } + } + + /* Try to set-up TLSv1.0 ciphers. If not successful, concatenate them to + the SSLv3 ciphers. OS/400 prior to version 7.1 will understand it. */ + if(!result && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) { + result = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS, + ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE); + if(result == CURLE_UNSUPPORTED_PROTOCOL) { + result = CURLE_OK; + strcpy(ciphers[CURL_GSKPROTO_SSLV3].ptr, + ciphers[CURL_GSKPROTO_TLSV10].ptr); + } + } + + /* Set-up other ciphers. */ + if(!result && (*protoflags & CURL_GSKPROTO_SSLV3_MASK)) + result = set_buffer(data, h, GSK_V3_CIPHER_SPECS, + ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE); + if(!result && (*protoflags & CURL_GSKPROTO_SSLV2_MASK)) + result = set_buffer(data, h, GSK_V2_CIPHER_SPECS, + ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE); + + /* Clean-up. */ + for(i = 0; i < CURL_GSKPROTO_LAST; i++) + free(ciphers[i].buf); + + return result; +} + + +static int Curl_gskit_init(void) +{ + /* No initialisation needed. */ + + return 1; +} + + +static void Curl_gskit_cleanup(void) +{ + /* Nothing to do. */ +} + + +static CURLcode init_environment(struct Curl_easy *data, + gsk_handle *envir, const char *appid, + const char *file, const char *label, + const char *password) +{ + int rc; + CURLcode result; + gsk_handle h; + + /* Creates the GSKit environment. */ + + rc = gsk_environment_open(&h); + switch(rc) { + case GSK_OK: + break; + case GSK_INSUFFICIENT_STORAGE: + return CURLE_OUT_OF_MEMORY; + default: + failf(data, "gsk_environment_open(): %s", gsk_strerror(rc)); + return CURLE_SSL_CONNECT_ERROR; + } + + result = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE); + if(!result && appid) + result = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE); + if(!result && file) + result = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE); + if(!result && label) + result = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE); + if(!result && password) + result = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE); + + if(!result) { + /* Locate CAs, Client certificate and key according to our settings. + Note: this call may be blocking for some tenths of seconds. */ + result = gskit_status(data, gsk_environment_init(h), + "gsk_environment_init()", CURLE_SSL_CERTPROBLEM); + if(!result) { + *envir = h; + return result; + } + } + /* Error: rollback. */ + gsk_environment_close(&h); + return result; +} + + +static void cancel_async_handshake(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + Qso_OverlappedIO_t cstat; + + if(QsoCancelOperation(conn->sock[sockindex], 0) > 0) + QsoWaitForIOCompletion(BACKEND->iocport, &cstat, (struct timeval *) NULL); +} + + +static void close_async_handshake(struct ssl_connect_data *connssl) +{ + QsoDestroyIOCompletionPort(BACKEND->iocport); + BACKEND->iocport = -1; +} + +/* SSL over SSL + * Problems: + * 1) GSKit can only perform SSL on an AF_INET or AF_INET6 stream socket. To + * pipe an SSL stream into another, it is therefore needed to have a pair + * of such communicating sockets and handle the pipelining explicitly. + * 2) OS/400 socketpair() is only implemented for domain AF_UNIX, thus cannot + * be used to produce the pipeline. + * The solution is to simulate socketpair() for AF_INET with low-level API + * listen(), bind() and connect(). + */ + +static int +inetsocketpair(int sv[2]) +{ + int lfd; /* Listening socket. */ + int sfd; /* Server socket. */ + int cfd; /* Client socket. */ + int len; + struct sockaddr_in addr1; + struct sockaddr_in addr2; + + /* Create listening socket on a local dynamic port. */ + lfd = socket(AF_INET, SOCK_STREAM, 0); + if(lfd < 0) + return -1; + memset((char *) &addr1, 0, sizeof(addr1)); + addr1.sin_family = AF_INET; + addr1.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr1.sin_port = 0; + if(bind(lfd, (struct sockaddr *) &addr1, sizeof(addr1)) || + listen(lfd, 2) < 0) { + close(lfd); + return -1; + } + + /* Get the allocated port. */ + len = sizeof(addr1); + if(getsockname(lfd, (struct sockaddr *) &addr1, &len) < 0) { + close(lfd); + return -1; + } + + /* Create the client socket. */ + cfd = socket(AF_INET, SOCK_STREAM, 0); + if(cfd < 0) { + close(lfd); + return -1; + } + + /* Request unblocking connection to the listening socket. */ + curlx_nonblock(cfd, TRUE); + if(connect(cfd, (struct sockaddr *) &addr1, sizeof(addr1)) < 0 && + errno != EINPROGRESS) { + close(lfd); + close(cfd); + return -1; + } + + /* Get the client dynamic port for intrusion check below. */ + len = sizeof(addr2); + if(getsockname(cfd, (struct sockaddr *) &addr2, &len) < 0) { + close(lfd); + close(cfd); + return -1; + } + + /* Accept the incoming connection and get the server socket. */ + curlx_nonblock(lfd, TRUE); + for(;;) { + len = sizeof(addr1); + sfd = accept(lfd, (struct sockaddr *) &addr1, &len); + if(sfd < 0) { + close(lfd); + close(cfd); + return -1; + } + + /* Check for possible intrusion from an external process. */ + if(addr1.sin_addr.s_addr == addr2.sin_addr.s_addr && + addr1.sin_port == addr2.sin_port) + break; + + /* Intrusion: reject incoming connection. */ + close(sfd); + } + + /* Done, return sockets and succeed. */ + close(lfd); + curlx_nonblock(cfd, FALSE); + sv[0] = cfd; + sv[1] = sfd; + return 0; +} + +static int pipe_ssloverssl(struct connectdata *conn, int sockindex, + int directions) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_connect_data *connproxyssl = &conn->proxy_ssl[sockindex]; + fd_set fds_read; + fd_set fds_write; + int n; + int m; + int i; + int ret = 0; + struct timeval tv = {0, 0}; + char buf[CURL_MAX_WRITE_SIZE]; + + if(!connssl->use || !connproxyssl->use) + return 0; /* No SSL over SSL: OK. */ + + FD_ZERO(&fds_read); + FD_ZERO(&fds_write); + n = -1; + if(directions & SOS_READ) { + FD_SET(BACKEND->remotefd, &fds_write); + n = BACKEND->remotefd; + } + if(directions & SOS_WRITE) { + FD_SET(BACKEND->remotefd, &fds_read); + n = BACKEND->remotefd; + FD_SET(conn->sock[sockindex], &fds_write); + if(n < conn->sock[sockindex]) + n = conn->sock[sockindex]; + } + i = select(n + 1, &fds_read, &fds_write, NULL, &tv); + if(i < 0) + return -1; /* Select error. */ + + if(FD_ISSET(BACKEND->remotefd, &fds_write)) { + /* Try getting data from HTTPS proxy and pipe it upstream. */ + n = 0; + i = gsk_secure_soc_read(connproxyssl->backend->handle, + buf, sizeof(buf), &n); + switch(i) { + case GSK_OK: + if(n) { + i = write(BACKEND->remotefd, buf, n); + if(i < 0) + return -1; + ret = 1; + } + break; + case GSK_OS400_ERROR_TIMED_OUT: + case GSK_WOULD_BLOCK: + break; + default: + return -1; + } + } + + if(FD_ISSET(BACKEND->remotefd, &fds_read) && + FD_ISSET(conn->sock[sockindex], &fds_write)) { + /* Pipe data to HTTPS proxy. */ + n = read(BACKEND->remotefd, buf, sizeof(buf)); + if(n < 0) + return -1; + if(n) { + i = gsk_secure_soc_write(connproxyssl->backend->handle, buf, n, &m); + if(i != GSK_OK || n != m) + return -1; + ret = 1; + } + } + + return ret; /* OK */ +} + + +static void close_one(struct ssl_connect_data *connssl, + struct connectdata *conn, int sockindex) +{ + if(BACKEND->handle) { + gskit_status(conn->data, gsk_secure_soc_close(&BACKEND->handle), + "gsk_secure_soc_close()", 0); + /* Last chance to drain output. */ + while(pipe_ssloverssl(conn, sockindex, SOS_WRITE) > 0) + ; + BACKEND->handle = (gsk_handle) NULL; + if(BACKEND->localfd >= 0) { + close(BACKEND->localfd); + BACKEND->localfd = -1; + } + if(BACKEND->remotefd >= 0) { + close(BACKEND->remotefd); + BACKEND->remotefd = -1; + } + } + if(BACKEND->iocport >= 0) + close_async_handshake(connssl); +} + + +static ssize_t gskit_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct Curl_easy *data = conn->data; + CURLcode cc = CURLE_SEND_ERROR; + int written; + + if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) >= 0) { + cc = gskit_status(data, + gsk_secure_soc_write(BACKEND->handle, + (char *) mem, (int) len, &written), + "gsk_secure_soc_write()", CURLE_SEND_ERROR); + if(cc == CURLE_OK) + if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) < 0) + cc = CURLE_SEND_ERROR; + } + if(cc != CURLE_OK) { + *curlcode = cc; + written = -1; + } + return (ssize_t) written; /* number of bytes */ +} + + +static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf, + size_t buffersize, CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[num]; + struct Curl_easy *data = conn->data; + int nread; + CURLcode cc = CURLE_RECV_ERROR; + + if(pipe_ssloverssl(conn, num, SOS_READ) >= 0) { + int buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize; + cc = gskit_status(data, gsk_secure_soc_read(BACKEND->handle, + buf, buffsize, &nread), + "gsk_secure_soc_read()", CURLE_RECV_ERROR); + } + switch(cc) { + case CURLE_OK: + break; + case CURLE_OPERATION_TIMEDOUT: + cc = CURLE_AGAIN; + default: + *curlcode = cc; + nread = -1; + break; + } + return (ssize_t) nread; +} + +static CURLcode +set_ssl_version_min_max(unsigned int *protoflags, struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + long ssl_version = SSL_CONN_CONFIG(version); + long ssl_version_max = SSL_CONN_CONFIG(version_max); + long i = ssl_version; + switch(ssl_version_max) { + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_DEFAULT: + ssl_version_max = CURL_SSLVERSION_TLSv1_2; + break; + } + for(; i <= (ssl_version_max >> 16); ++i) { + switch(i) { + case CURL_SSLVERSION_TLSv1_0: + *protoflags |= CURL_GSKPROTO_TLSV10_MASK; + break; + case CURL_SSLVERSION_TLSv1_1: + *protoflags |= CURL_GSKPROTO_TLSV11_MASK; + break; + case CURL_SSLVERSION_TLSv1_2: + *protoflags |= CURL_GSKPROTO_TLSV11_MASK; + break; + case CURL_SSLVERSION_TLSv1_3: + failf(data, "GSKit: TLS 1.3 is not yet supported"); + return CURLE_SSL_CONNECT_ERROR; + } + } + + return CURLE_OK; +} + +static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + gsk_handle envir; + CURLcode result; + int rc; + const char * const keyringfile = SSL_CONN_CONFIG(CAfile); + const char * const keyringpwd = SSL_SET_OPTION(key_passwd); + const char * const keyringlabel = SSL_SET_OPTION(cert); + const long int ssl_version = SSL_CONN_CONFIG(version); + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); + const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name: + conn->host.name; + const char *sni; + unsigned int protoflags = 0; + Qso_OverlappedIO_t commarea; + int sockpair[2]; + static const int sobufsize = CURL_MAX_WRITE_SIZE; + + /* Create SSL environment, start (preferably asynchronous) handshake. */ + + BACKEND->handle = (gsk_handle) NULL; + BACKEND->iocport = -1; + BACKEND->localfd = -1; + BACKEND->remotefd = -1; + + /* GSKit supports two ways of specifying an SSL context: either by + * application identifier (that should have been defined at the system + * level) or by keyring file, password and certificate label. + * Local certificate name (CURLOPT_SSLCERT) is used to hold either the + * application identifier of the certificate label. + * Key password (CURLOPT_KEYPASSWD) holds the keyring password. + * It is not possible to have different keyrings for the CAs and the + * local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify + * the keyring file. + * If no key password is given and the keyring is the system keyring, + * application identifier mode is tried first, as recommended in IBM doc. + */ + + envir = (gsk_handle) NULL; + + if(keyringlabel && *keyringlabel && !keyringpwd && + !strcmp(keyringfile, CURL_CA_BUNDLE)) { + /* Try application identifier mode. */ + init_environment(data, &envir, keyringlabel, (const char *) NULL, + (const char *) NULL, (const char *) NULL); + } + + if(!envir) { + /* Use keyring mode. */ + result = init_environment(data, &envir, (const char *) NULL, + keyringfile, keyringlabel, keyringpwd); + if(result) + return result; + } + + /* Create secure session. */ + result = gskit_status(data, gsk_secure_soc_open(envir, &BACKEND->handle), + "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR); + gsk_environment_close(&envir); + if(result) + return result; + + /* Establish a pipelining socket pair for SSL over SSL. */ + if(conn->proxy_ssl[sockindex].use) { + if(inetsocketpair(sockpair)) + return CURLE_SSL_CONNECT_ERROR; + BACKEND->localfd = sockpair[0]; + BACKEND->remotefd = sockpair[1]; + setsockopt(BACKEND->localfd, SOL_SOCKET, SO_RCVBUF, + (void *) sobufsize, sizeof(sobufsize)); + setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_RCVBUF, + (void *) sobufsize, sizeof(sobufsize)); + setsockopt(BACKEND->localfd, SOL_SOCKET, SO_SNDBUF, + (void *) sobufsize, sizeof(sobufsize)); + setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_SNDBUF, + (void *) sobufsize, sizeof(sobufsize)); + curlx_nonblock(BACKEND->localfd, TRUE); + curlx_nonblock(BACKEND->remotefd, TRUE); + } + + /* Determine which SSL/TLS version should be enabled. */ + sni = hostname; + switch(ssl_version) { + case CURL_SSLVERSION_SSLv2: + protoflags = CURL_GSKPROTO_SSLV2_MASK; + sni = NULL; + break; + case CURL_SSLVERSION_SSLv3: + protoflags = CURL_GSKPROTO_SSLV3_MASK; + sni = NULL; + break; + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + protoflags = CURL_GSKPROTO_TLSV10_MASK | + CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK; + break; + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + result = set_ssl_version_min_max(&protoflags, conn); + if(result != CURLE_OK) + return result; + break; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + /* Process SNI. Ignore if not supported (on OS400 < V7R1). */ + if(sni) { + result = set_buffer(data, BACKEND->handle, + GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE); + if(result == CURLE_UNSUPPORTED_PROTOCOL) + result = CURLE_OK; + } + + /* Set session parameters. */ + if(!result) { + /* Compute the handshake timeout. Since GSKit granularity is 1 second, + we round up the required value. */ + long timeout = Curl_timeleft(data, NULL, TRUE); + if(timeout < 0) + result = CURLE_OPERATION_TIMEDOUT; + else + result = set_numeric(data, BACKEND->handle, GSK_HANDSHAKE_TIMEOUT, + (timeout + 999) / 1000); + } + if(!result) + result = set_numeric(data, BACKEND->handle, GSK_OS400_READ_TIMEOUT, 1); + if(!result) + result = set_numeric(data, BACKEND->handle, GSK_FD, BACKEND->localfd >= 0? + BACKEND->localfd: conn->sock[sockindex]); + if(!result) + result = set_ciphers(conn, BACKEND->handle, &protoflags); + if(!protoflags) { + failf(data, "No SSL protocol/cipher combination enabled"); + result = CURLE_SSL_CIPHER; + } + if(!result) + result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_SSLV2, + (protoflags & CURL_GSKPROTO_SSLV2_MASK)? + GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE); + if(!result) + result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_SSLV3, + (protoflags & CURL_GSKPROTO_SSLV3_MASK)? + GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE); + if(!result) + result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV1, + (protoflags & CURL_GSKPROTO_TLSV10_MASK)? + GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE); + if(!result) { + result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV11, + (protoflags & CURL_GSKPROTO_TLSV11_MASK)? + GSK_TRUE: GSK_FALSE, TRUE); + if(result == CURLE_UNSUPPORTED_PROTOCOL) { + result = CURLE_OK; + if(protoflags == CURL_GSKPROTO_TLSV11_MASK) { + failf(data, "TLS 1.1 not yet supported"); + result = CURLE_SSL_CIPHER; + } + } + } + if(!result) { + result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV12, + (protoflags & CURL_GSKPROTO_TLSV12_MASK)? + GSK_TRUE: GSK_FALSE, TRUE); + if(result == CURLE_UNSUPPORTED_PROTOCOL) { + result = CURLE_OK; + if(protoflags == CURL_GSKPROTO_TLSV12_MASK) { + failf(data, "TLS 1.2 not yet supported"); + result = CURLE_SSL_CIPHER; + } + } + } + if(!result) + result = set_enum(data, BACKEND->handle, GSK_SERVER_AUTH_TYPE, + verifypeer? GSK_SERVER_AUTH_FULL: + GSK_SERVER_AUTH_PASSTHRU, FALSE); + + if(!result) { + /* Start handshake. Try asynchronous first. */ + memset(&commarea, 0, sizeof(commarea)); + BACKEND->iocport = QsoCreateIOCompletionPort(); + if(BACKEND->iocport != -1) { + result = gskit_status(data, + gsk_secure_soc_startInit(BACKEND->handle, + BACKEND->iocport, + &commarea), + "gsk_secure_soc_startInit()", + CURLE_SSL_CONNECT_ERROR); + if(!result) { + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; + } + else + close_async_handshake(connssl); + } + else if(errno != ENOBUFS) + result = gskit_status(data, GSK_ERROR_IO, + "QsoCreateIOCompletionPort()", 0); + else if(conn->proxy_ssl[sockindex].use) { + /* Cannot pipeline while handshaking synchronously. */ + result = CURLE_SSL_CONNECT_ERROR; + } + else { + /* No more completion port available. Use synchronous IO. */ + result = gskit_status(data, gsk_secure_soc_init(BACKEND->handle), + "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR); + if(!result) { + connssl->connecting_state = ssl_connect_3; + return CURLE_OK; + } + } + } + + /* Error: rollback. */ + close_one(connssl, conn, sockindex); + return result; +} + + +static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex, + bool nonblocking) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + Qso_OverlappedIO_t cstat; + struct timeval stmv; + CURLcode result; + + /* Poll or wait for end of SSL asynchronous handshake. */ + + for(;;) { + long timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE); + if(timeout_ms < 0) + timeout_ms = 0; + stmv.tv_sec = timeout_ms / 1000; + stmv.tv_usec = (timeout_ms - stmv.tv_sec * 1000) * 1000; + switch(QsoWaitForIOCompletion(BACKEND->iocport, &cstat, &stmv)) { + case 1: /* Operation complete. */ + break; + case -1: /* An error occurred: handshake still in progress. */ + if(errno == EINTR) { + if(nonblocking) + return CURLE_OK; + continue; /* Retry. */ + } + if(errno != ETIME) { + failf(data, "QsoWaitForIOCompletion() I/O error: %s", strerror(errno)); + cancel_async_handshake(conn, sockindex); + close_async_handshake(connssl); + return CURLE_SSL_CONNECT_ERROR; + } + /* FALL INTO... */ + case 0: /* Handshake in progress, timeout occurred. */ + if(nonblocking) + return CURLE_OK; + cancel_async_handshake(conn, sockindex); + close_async_handshake(connssl); + return CURLE_OPERATION_TIMEDOUT; + } + break; + } + result = gskit_status(data, cstat.returnValue, "SSL handshake", + CURLE_SSL_CONNECT_ERROR); + if(!result) + connssl->connecting_state = ssl_connect_3; + close_async_handshake(connssl); + return result; +} + + +static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + const gsk_cert_data_elem *cdev; + int cdec; + const gsk_cert_data_elem *p; + const char *cert = (const char *) NULL; + const char *certend; + const char *ptr; + CURLcode result; + + /* SSL handshake done: gather certificate info and verify host. */ + + if(gskit_status(data, gsk_attribute_get_cert_info(BACKEND->handle, + GSK_PARTNER_CERT_INFO, + &cdev, &cdec), + "gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) == + CURLE_OK) { + int i; + + infof(data, "Server certificate:\n"); + p = cdev; + for(i = 0; i++ < cdec; p++) + switch(p->cert_data_id) { + case CERT_BODY_DER: + cert = p->cert_data_p; + certend = cert + cdev->cert_data_l; + break; + case CERT_DN_PRINTABLE: + infof(data, "\t subject: %.*s\n", p->cert_data_l, p->cert_data_p); + break; + case CERT_ISSUER_DN_PRINTABLE: + infof(data, "\t issuer: %.*s\n", p->cert_data_l, p->cert_data_p); + break; + case CERT_VALID_FROM: + infof(data, "\t start date: %.*s\n", p->cert_data_l, p->cert_data_p); + break; + case CERT_VALID_TO: + infof(data, "\t expire date: %.*s\n", p->cert_data_l, p->cert_data_p); + break; + } + } + + /* Verify host. */ + result = Curl_verifyhost(conn, cert, certend); + if(result) + return result; + + /* The only place GSKit can get the whole CA chain is a validation + callback where no user data pointer is available. Therefore it's not + possible to copy this chain into our structures for CAINFO. + However the server certificate may be available, thus we can return + info about it. */ + if(data->set.ssl.certinfo) { + result = Curl_ssl_init_certinfo(data, 1); + if(result) + return result; + + if(cert) { + result = Curl_extract_certinfo(conn, 0, cert, certend); + if(result) + return result; + } + } + + /* Check pinned public key. */ + ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + if(!result && ptr) { + curl_X509certificate x509; + curl_asn1Element *p; + + if(Curl_parseX509(&x509, cert, certend)) + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + p = &x509.subjectPublicKeyInfo; + result = Curl_pin_peer_pubkey(data, ptr, p->header, p->end - p->header); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + return result; + } + } + + connssl->connecting_state = ssl_connect_done; + return CURLE_OK; +} + + +static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex, + bool nonblocking, bool *done) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + long timeout_ms; + CURLcode result = CURLE_OK; + + *done = connssl->state == ssl_connection_complete; + if(*done) + return CURLE_OK; + + /* Step 1: create session, start handshake. */ + if(connssl->connecting_state == ssl_connect_1) { + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + result = CURLE_OPERATION_TIMEDOUT; + } + else + result = gskit_connect_step1(conn, sockindex); + } + + /* Handle handshake pipelining. */ + if(!result) + if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0) + result = CURLE_SSL_CONNECT_ERROR; + + /* Step 2: check if handshake is over. */ + if(!result && connssl->connecting_state == ssl_connect_2) { + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + result = CURLE_OPERATION_TIMEDOUT; + } + else + result = gskit_connect_step2(conn, sockindex, nonblocking); + } + + /* Handle handshake pipelining. */ + if(!result) + if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0) + result = CURLE_SSL_CONNECT_ERROR; + + /* Step 3: gather certificate info, verify host. */ + if(!result && connssl->connecting_state == ssl_connect_3) + result = gskit_connect_step3(conn, sockindex); + + if(result) + close_one(connssl, conn, sockindex); + else if(connssl->connecting_state == ssl_connect_done) { + connssl->state = ssl_connection_complete; + connssl->connecting_state = ssl_connect_1; + conn->recv[sockindex] = gskit_recv; + conn->send[sockindex] = gskit_send; + *done = TRUE; + } + + return result; +} + + +static CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + CURLcode result; + + result = gskit_connect_common(conn, sockindex, TRUE, done); + if(*done || result) + conn->ssl[sockindex].connecting_state = ssl_connect_1; + return result; +} + + +static CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex) +{ + CURLcode result; + bool done; + + conn->ssl[sockindex].connecting_state = ssl_connect_1; + result = gskit_connect_common(conn, sockindex, FALSE, &done); + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + + +static void Curl_gskit_close(struct connectdata *conn, int sockindex) +{ + close_one(&conn->ssl[sockindex], conn, sockindex); + close_one(&conn->proxy_ssl[sockindex], conn, sockindex); +} + + +static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct Curl_easy *data = conn->data; + int what; + int rc; + char buf[120]; + + if(!BACKEND->handle) + return 0; + +#ifndef CURL_DISABLE_FTP + if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE) + return 0; +#endif + + close_one(connssl, conn, sockindex); + rc = 0; + what = SOCKET_READABLE(conn->sock[sockindex], + SSL_SHUTDOWN_TIMEOUT); + + for(;;) { + ssize_t nread; + + if(what < 0) { + /* anything that gets here is fatally bad */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + rc = -1; + break; + } + + if(!what) { /* timeout */ + failf(data, "SSL shutdown timeout"); + break; + } + + /* Something to read, let's do it and hope that it is the close + notify alert from the server. No way to gsk_secure_soc_read() now, so + use read(). */ + + nread = read(conn->sock[sockindex], buf, sizeof(buf)); + + if(nread < 0) { + failf(data, "read: %s", strerror(errno)); + rc = -1; + } + + if(nread <= 0) + break; + + what = SOCKET_READABLE(conn->sock[sockindex], 0); + } + + return rc; +} + + +static size_t Curl_gskit_version(char *buffer, size_t size) +{ + return msnprintf(buffer, size, "GSKit"); +} + + +static int Curl_gskit_check_cxn(struct connectdata *cxn) +{ + struct ssl_connect_data *connssl = &cxn->ssl[FIRSTSOCKET]; + int err; + int errlen; + + /* The only thing that can be tested here is at the socket level. */ + + if(!BACKEND->handle) + return 0; /* connection has been closed */ + + err = 0; + errlen = sizeof(err); + + if(getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR, + (unsigned char *) &err, &errlen) || + errlen != sizeof(err) || err) + return 0; /* connection has been closed */ + + return -1; /* connection status unknown */ +} + +static void *Curl_gskit_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + (void)info; + return BACKEND->handle; +} + +const struct Curl_ssl Curl_ssl_gskit = { + { CURLSSLBACKEND_GSKIT, "gskit" }, /* info */ + + SSLSUPP_CERTINFO | + SSLSUPP_PINNEDPUBKEY, + + sizeof(struct ssl_backend_data), + + Curl_gskit_init, /* init */ + Curl_gskit_cleanup, /* cleanup */ + Curl_gskit_version, /* version */ + Curl_gskit_check_cxn, /* check_cxn */ + Curl_gskit_shutdown, /* shutdown */ + Curl_none_data_pending, /* data_pending */ + Curl_none_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_gskit_connect, /* connect */ + Curl_gskit_connect_nonblocking, /* connect_nonblocking */ + Curl_gskit_get_internals, /* get_internals */ + Curl_gskit_close, /* close_one */ + Curl_none_close_all, /* close_all */ + /* No session handling for GSKit */ + Curl_none_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_none_md5sum, /* md5sum */ + NULL /* sha256sum */ +}; + +#endif /* USE_GSKIT */ diff --git a/libcurl/lib/vtls/gskit.h b/libcurl/lib/vtls/gskit.h new file mode 100644 index 0000000..466ee4d --- /dev/null +++ b/libcurl/lib/vtls/gskit.h @@ -0,0 +1,38 @@ +#ifndef HEADER_CURL_GSKIT_H +#define HEADER_CURL_GSKIT_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +/* + * This header should only be needed to get included by vtls.c and gskit.c + */ + +#include "urldata.h" + +#ifdef USE_GSKIT + +extern const struct Curl_ssl Curl_ssl_gskit; + +#endif /* USE_GSKIT */ + +#endif /* HEADER_CURL_GSKIT_H */ diff --git a/libcurl/lib/vtls/gtls.c b/libcurl/lib/vtls/gtls.c new file mode 100644 index 0000000..8693cdc --- /dev/null +++ b/libcurl/lib/vtls/gtls.c @@ -0,0 +1,1881 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all GnuTLS-specific code for the TLS/SSL layer. No code + * but vtls.c should ever call or use these functions. + * + * Note: don't use the GnuTLS' *_t variable type names in this source code, + * since they were not present in 1.0.X. + */ + +#include "curl_setup.h" + +#ifdef USE_GNUTLS + +#include +#include +#include + +#ifdef USE_GNUTLS_NETTLE +#include +#include +#include +#else +#include +#endif + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "gtls.h" +#include "vtls.h" +#include "parsedate.h" +#include "connect.h" /* for the connect timeout */ +#include "select.h" +#include "strcase.h" +#include "warnless.h" +#include "x509asn1.h" +#include "multiif.h" +#include "curl_printf.h" +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* Enable GnuTLS debugging by defining GTLSDEBUG */ +/*#define GTLSDEBUG */ + +#ifdef GTLSDEBUG +static void tls_log_func(int level, const char *str) +{ + fprintf(stderr, "|<%d>| %s", level, str); +} +#endif +static bool gtls_inited = FALSE; + +#if defined(GNUTLS_VERSION_NUMBER) +# if (GNUTLS_VERSION_NUMBER >= 0x020c00) +# undef gnutls_transport_set_lowat +# define gnutls_transport_set_lowat(A,B) Curl_nop_stmt +# define USE_GNUTLS_PRIORITY_SET_DIRECT 1 +# endif +# if (GNUTLS_VERSION_NUMBER >= 0x020c03) +# define GNUTLS_MAPS_WINSOCK_ERRORS 1 +# endif + +# if HAVE_GNUTLS_ALPN_SET_PROTOCOLS +# define HAS_ALPN +# endif + +# if HAVE_GNUTLS_OCSP_REQ_INIT +# define HAS_OCSP +# endif + +# if (GNUTLS_VERSION_NUMBER >= 0x030306) +# define HAS_CAPATH +# endif +#endif + +#if (GNUTLS_VERSION_NUMBER >= 0x030603) +#define HAS_TLS13 +#endif + +#ifdef HAS_OCSP +# include +#endif + +struct ssl_backend_data { + gnutls_session_t session; + gnutls_certificate_credentials_t cred; +#ifdef USE_TLS_SRP + gnutls_srp_client_credentials_t srp_client_cred; +#endif +}; + +#define BACKEND connssl->backend + +/* + * Custom push and pull callback functions used by GNU TLS to read and write + * to the socket. These functions are simple wrappers to send() and recv() + * (although here using the sread/swrite macros as defined by + * curl_setup_once.h). + * We use custom functions rather than the GNU TLS defaults because it allows + * us to get specific about the fourth "flags" argument, and to use arbitrary + * private data with gnutls_transport_set_ptr if we wish. + * + * When these custom push and pull callbacks fail, GNU TLS checks its own + * session-specific error variable, and when not set also its own global + * errno variable, in order to take appropriate action. GNU TLS does not + * require that the transport is actually a socket. This implies that for + * Windows builds these callbacks should ideally set the session-specific + * error variable using function gnutls_transport_set_errno or as a last + * resort global errno variable using gnutls_transport_set_global_errno, + * with a transport agnostic error value. This implies that some winsock + * error translation must take place in these callbacks. + * + * Paragraph above applies to GNU TLS versions older than 2.12.3, since + * this version GNU TLS does its own internal winsock error translation + * using system_errno() function. + */ + +#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS) +# define gtls_EINTR 4 +# define gtls_EIO 5 +# define gtls_EAGAIN 11 +static int gtls_mapped_sockerrno(void) +{ + switch(SOCKERRNO) { + case WSAEWOULDBLOCK: + return gtls_EAGAIN; + case WSAEINTR: + return gtls_EINTR; + default: + break; + } + return gtls_EIO; +} +#endif + +static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len) +{ + curl_socket_t sock = *(curl_socket_t *)s; + ssize_t ret = swrite(sock, buf, len); +#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS) + if(ret < 0) + gnutls_transport_set_global_errno(gtls_mapped_sockerrno()); +#endif + return ret; +} + +static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len) +{ + curl_socket_t sock = *(curl_socket_t *)s; + ssize_t ret = sread(sock, buf, len); +#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS) + if(ret < 0) + gnutls_transport_set_global_errno(gtls_mapped_sockerrno()); +#endif + return ret; +} + +static ssize_t Curl_gtls_push_ssl(void *s, const void *buf, size_t len) +{ + return gnutls_record_send((gnutls_session_t) s, buf, len); +} + +static ssize_t Curl_gtls_pull_ssl(void *s, void *buf, size_t len) +{ + return gnutls_record_recv((gnutls_session_t) s, buf, len); +} + +/* Curl_gtls_init() + * + * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that + * are not thread-safe and thus this function itself is not thread-safe and + * must only be called from within curl_global_init() to keep the thread + * situation under control! + */ +static int Curl_gtls_init(void) +{ + int ret = 1; + if(!gtls_inited) { + ret = gnutls_global_init()?0:1; +#ifdef GTLSDEBUG + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_log_level(2); +#endif + gtls_inited = TRUE; + } + return ret; +} + +static void Curl_gtls_cleanup(void) +{ + if(gtls_inited) { + gnutls_global_deinit(); + gtls_inited = FALSE; + } +} + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static void showtime(struct Curl_easy *data, + const char *text, + time_t stamp) +{ + struct tm buffer; + const struct tm *tm = &buffer; + char str[96]; + CURLcode result = Curl_gmtime(stamp, &buffer); + if(result) + return; + + msnprintf(str, + sizeof(str), + "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT", + text, + Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], + tm->tm_mday, + Curl_month[tm->tm_mon], + tm->tm_year + 1900, + tm->tm_hour, + tm->tm_min, + tm->tm_sec); + infof(data, "%s\n", str); +} +#endif + +static gnutls_datum_t load_file(const char *file) +{ + FILE *f; + gnutls_datum_t loaded_file = { NULL, 0 }; + long filelen; + void *ptr; + + f = fopen(file, "rb"); + if(!f) + return loaded_file; + if(fseek(f, 0, SEEK_END) != 0 + || (filelen = ftell(f)) < 0 + || fseek(f, 0, SEEK_SET) != 0 + || !(ptr = malloc((size_t)filelen))) + goto out; + if(fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen) { + free(ptr); + goto out; + } + + loaded_file.data = ptr; + loaded_file.size = (unsigned int)filelen; +out: + fclose(f); + return loaded_file; +} + +static void unload_file(gnutls_datum_t data) +{ + free(data.data); +} + + +/* this function does a SSL/TLS (re-)handshake */ +static CURLcode handshake(struct connectdata *conn, + int sockindex, + bool duringconnect, + bool nonblocking) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + gnutls_session_t session = BACKEND->session; + curl_socket_t sockfd = conn->sock[sockindex]; + + for(;;) { + time_t timeout_ms; + int rc; + + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, duringconnect); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading + || connssl->connecting_state == ssl_connect_2_writing) { + int what; + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking?0: + timeout_ms?timeout_ms:1000); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) + return CURLE_OK; + else if(timeout_ms) { + /* timeout */ + failf(data, "SSL connection timeout at %ld", (long)timeout_ms); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + rc = gnutls_handshake(session); + + if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) { + connssl->connecting_state = + gnutls_record_get_direction(session)? + ssl_connect_2_writing:ssl_connect_2_reading; + continue; + } + else if((rc < 0) && !gnutls_error_is_fatal(rc)) { + const char *strerr = NULL; + + if(rc == GNUTLS_E_WARNING_ALERT_RECEIVED) { + int alert = gnutls_alert_get(session); + strerr = gnutls_alert_get_name(alert); + } + + if(strerr == NULL) + strerr = gnutls_strerror(rc); + + infof(data, "gnutls_handshake() warning: %s\n", strerr); + continue; + } + else if(rc < 0) { + const char *strerr = NULL; + + if(rc == GNUTLS_E_FATAL_ALERT_RECEIVED) { + int alert = gnutls_alert_get(session); + strerr = gnutls_alert_get_name(alert); + } + + if(strerr == NULL) + strerr = gnutls_strerror(rc); + + failf(data, "gnutls_handshake() failed: %s", strerr); + return CURLE_SSL_CONNECT_ERROR; + } + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + return CURLE_OK; + } +} + +static gnutls_x509_crt_fmt_t do_file_type(const char *type) +{ + if(!type || !type[0]) + return GNUTLS_X509_FMT_PEM; + if(strcasecompare(type, "PEM")) + return GNUTLS_X509_FMT_PEM; + if(strcasecompare(type, "DER")) + return GNUTLS_X509_FMT_DER; + return -1; +} + +#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT +static CURLcode +set_ssl_version_min_max(int *list, size_t list_size, struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + long ssl_version = SSL_CONN_CONFIG(version); + long ssl_version_max = SSL_CONN_CONFIG(version_max); + long i = ssl_version; + long protocol_priority_idx = 0; + + switch(ssl_version_max) { + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_DEFAULT: +#ifdef HAS_TLS13 + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3; +#endif + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; + break; + } + + for(; i <= (ssl_version_max >> 16) && + protocol_priority_idx < list_size; ++i) { + switch(i) { + case CURL_SSLVERSION_TLSv1_0: + protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_0; + break; + case CURL_SSLVERSION_TLSv1_1: + protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_1; + break; + case CURL_SSLVERSION_TLSv1_2: + protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_2; + break; + case CURL_SSLVERSION_TLSv1_3: +#ifdef HAS_TLS13 + protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_3; + break; +#else + failf(data, "GnuTLS: TLS 1.3 is not yet supported"); + return CURLE_SSL_CONNECT_ERROR; +#endif + } + } + return CURLE_OK; +} +#else +#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509" +/* If GnuTLS was compiled without support for SRP it will error out if SRP is + requested in the priority string, so treat it specially + */ +#define GNUTLS_SRP "+SRP" + +static CURLcode +set_ssl_version_min_max(const char **prioritylist, struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + long ssl_version = SSL_CONN_CONFIG(version); + long ssl_version_max = SSL_CONN_CONFIG(version_max); + + if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) { + ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT; + } + switch(ssl_version | ssl_version_max) { + case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.0:" GNUTLS_SRP; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.0:+VERS-TLS1.1:" GNUTLS_SRP; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.1:" GNUTLS_SRP; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.2:" GNUTLS_SRP; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_TLSv1_3: +#ifdef HAS_TLS13 + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.3:" GNUTLS_SRP; + return CURLE_OK; +#else + failf(data, "GnuTLS: TLS 1.3 is not yet supported"); + return CURLE_SSL_CONNECT_ERROR; +#endif + case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:" +#ifdef HAS_TLS13 + "+VERS-TLS1.3:" +#endif + GNUTLS_SRP; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.1:+VERS-TLS1.2:" +#ifdef HAS_TLS13 + "+VERS-TLS1.3:" +#endif + GNUTLS_SRP; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.2:" +#ifdef HAS_TLS13 + "+VERS-TLS1.3:" +#endif + GNUTLS_SRP; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_DEFAULT: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.2:" +#ifdef HAS_TLS13 + "+VERS-TLS1.3:" +#endif + GNUTLS_SRP; + return CURLE_OK; + } + + failf(data, "GnuTLS: cannot set ssl protocol"); + return CURLE_SSL_CONNECT_ERROR; +} +#endif + +static CURLcode +gtls_connect_step1(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + unsigned int init_flags; + gnutls_session_t session; + int rc; + bool sni = TRUE; /* default is SNI enabled */ + void *transport_ptr = NULL; + gnutls_push_func gnutls_transport_push = NULL; + gnutls_pull_func gnutls_transport_pull = NULL; +#ifdef ENABLE_IPV6 + struct in6_addr addr; +#else + struct in_addr addr; +#endif +#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT + static const int cipher_priority[] = { + /* These two ciphers were added to GnuTLS as late as ver. 3.0.1, + but this code path is only ever used for ver. < 2.12.0. + GNUTLS_CIPHER_AES_128_GCM, + GNUTLS_CIPHER_AES_256_GCM, + */ + GNUTLS_CIPHER_AES_128_CBC, + GNUTLS_CIPHER_AES_256_CBC, + GNUTLS_CIPHER_CAMELLIA_128_CBC, + GNUTLS_CIPHER_CAMELLIA_256_CBC, + GNUTLS_CIPHER_3DES_CBC, + }; + static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 }; + int protocol_priority[] = { 0, 0, 0, 0 }; +#else + const char *prioritylist; + const char *err = NULL; +#endif + + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + + if(connssl->state == ssl_connection_complete) + /* to make us tolerant against being called more than once for the + same connection */ + return CURLE_OK; + + if(!gtls_inited) + Curl_gtls_init(); + + if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) { + failf(data, "GnuTLS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + } + else if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3) + sni = FALSE; /* SSLv3 has no SNI */ + + /* allocate a cred struct */ + rc = gnutls_certificate_allocate_credentials(&BACKEND->cred); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc)); + return CURLE_SSL_CONNECT_ERROR; + } + +#ifdef USE_TLS_SRP + if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { + infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username)); + + rc = gnutls_srp_allocate_client_credentials( + &BACKEND->srp_client_cred); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, "gnutls_srp_allocate_client_cred() failed: %s", + gnutls_strerror(rc)); + return CURLE_OUT_OF_MEMORY; + } + + rc = gnutls_srp_set_client_credentials(BACKEND->srp_client_cred, + SSL_SET_OPTION(username), + SSL_SET_OPTION(password)); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, "gnutls_srp_set_client_cred() failed: %s", + gnutls_strerror(rc)); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + } +#endif + + if(SSL_CONN_CONFIG(CAfile)) { + /* set the trusted CA cert bundle file */ + gnutls_certificate_set_verify_flags(BACKEND->cred, + GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT); + + rc = gnutls_certificate_set_x509_trust_file(BACKEND->cred, + SSL_CONN_CONFIG(CAfile), + GNUTLS_X509_FMT_PEM); + if(rc < 0) { + infof(data, "error reading ca cert file %s (%s)\n", + SSL_CONN_CONFIG(CAfile), gnutls_strerror(rc)); + if(SSL_CONN_CONFIG(verifypeer)) + return CURLE_SSL_CACERT_BADFILE; + } + else + infof(data, "found %d certificates in %s\n", rc, + SSL_CONN_CONFIG(CAfile)); + } + +#ifdef HAS_CAPATH + if(SSL_CONN_CONFIG(CApath)) { + /* set the trusted CA cert directory */ + rc = gnutls_certificate_set_x509_trust_dir(BACKEND->cred, + SSL_CONN_CONFIG(CApath), + GNUTLS_X509_FMT_PEM); + if(rc < 0) { + infof(data, "error reading ca cert file %s (%s)\n", + SSL_CONN_CONFIG(CApath), gnutls_strerror(rc)); + if(SSL_CONN_CONFIG(verifypeer)) + return CURLE_SSL_CACERT_BADFILE; + } + else + infof(data, "found %d certificates in %s\n", + rc, SSL_CONN_CONFIG(CApath)); + } +#endif + +#ifdef CURL_CA_FALLBACK + /* use system ca certificate store as fallback */ + if(SSL_CONN_CONFIG(verifypeer) && + !(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) { + gnutls_certificate_set_x509_system_trust(BACKEND->cred); + } +#endif + + if(SSL_SET_OPTION(CRLfile)) { + /* set the CRL list file */ + rc = gnutls_certificate_set_x509_crl_file(BACKEND->cred, + SSL_SET_OPTION(CRLfile), + GNUTLS_X509_FMT_PEM); + if(rc < 0) { + failf(data, "error reading crl file %s (%s)", + SSL_SET_OPTION(CRLfile), gnutls_strerror(rc)); + return CURLE_SSL_CRL_BADFILE; + } + else + infof(data, "found %d CRL in %s\n", + rc, SSL_SET_OPTION(CRLfile)); + } + + /* Initialize TLS session as a client */ + init_flags = GNUTLS_CLIENT; + +#if defined(GNUTLS_NO_TICKETS) + /* Disable TLS session tickets */ + init_flags |= GNUTLS_NO_TICKETS; +#endif + + rc = gnutls_init(&BACKEND->session, init_flags); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, "gnutls_init() failed: %d", rc); + return CURLE_SSL_CONNECT_ERROR; + } + + /* convenient assign */ + session = BACKEND->session; + + if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) && +#ifdef ENABLE_IPV6 + (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) && +#endif + sni && + (gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname, + strlen(hostname)) < 0)) + infof(data, "WARNING: failed to configure server name indication (SNI) " + "TLS extension\n"); + + /* Use default priorities */ + rc = gnutls_set_default_priority(session); + if(rc != GNUTLS_E_SUCCESS) + return CURLE_SSL_CONNECT_ERROR; + +#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT + rc = gnutls_cipher_set_priority(session, cipher_priority); + if(rc != GNUTLS_E_SUCCESS) + return CURLE_SSL_CONNECT_ERROR; + + /* Sets the priority on the certificate types supported by gnutls. Priority + is higher for types specified before others. After specifying the types + you want, you must append a 0. */ + rc = gnutls_certificate_type_set_priority(session, cert_type_priority); + if(rc != GNUTLS_E_SUCCESS) + return CURLE_SSL_CONNECT_ERROR; + + if(SSL_CONN_CONFIG(cipher_list) != NULL) { + failf(data, "can't pass a custom cipher list to older GnuTLS" + " versions"); + return CURLE_SSL_CONNECT_ERROR; + } + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_SSLv3: + protocol_priority[0] = GNUTLS_SSL3; + break; + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + protocol_priority[0] = GNUTLS_TLS1_0; + protocol_priority[1] = GNUTLS_TLS1_1; + protocol_priority[2] = GNUTLS_TLS1_2; +#ifdef HAS_TLS13 + protocol_priority[3] = GNUTLS_TLS1_3; +#endif + break; + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + { + CURLcode result = set_ssl_version_min_max(protocol_priority, + sizeof(protocol_priority)/sizeof(protocol_priority[0]), conn); + if(result != CURLE_OK) + return result; + break; + } + case CURL_SSLVERSION_SSLv2: + failf(data, "GnuTLS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + rc = gnutls_protocol_set_priority(session, protocol_priority); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, "Did you pass a valid GnuTLS cipher list?"); + return CURLE_SSL_CONNECT_ERROR; + } + +#else + /* Ensure +SRP comes at the *end* of all relevant strings so that it can be + * removed if a run-time error indicates that SRP is not supported by this + * GnuTLS version */ + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_SSLv3: + prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0"; + break; + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" +#ifdef HAS_TLS13 + "+VERS-TLS1.3:" +#endif + GNUTLS_SRP; + break; + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + { + CURLcode result = set_ssl_version_min_max(&prioritylist, conn); + if(result != CURLE_OK) + return result; + break; + } + case CURL_SSLVERSION_SSLv2: + failf(data, "GnuTLS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + rc = gnutls_priority_set_direct(session, prioritylist, &err); + if((rc == GNUTLS_E_INVALID_REQUEST) && err) { + if(!strcmp(err, GNUTLS_SRP)) { + /* This GnuTLS was probably compiled without support for SRP. + * Note that fact and try again without it. */ + int validprioritylen = curlx_uztosi(err - prioritylist); + char *prioritycopy = strdup(prioritylist); + if(!prioritycopy) + return CURLE_OUT_OF_MEMORY; + + infof(data, "This GnuTLS does not support SRP\n"); + if(validprioritylen) + /* Remove the :+SRP */ + prioritycopy[validprioritylen - 1] = 0; + rc = gnutls_priority_set_direct(session, prioritycopy, &err); + free(prioritycopy); + } + } + if(rc != GNUTLS_E_SUCCESS) { + failf(data, "Error %d setting GnuTLS cipher list starting with %s", + rc, err); + return CURLE_SSL_CONNECT_ERROR; + } +#endif + +#ifdef HAS_ALPN + if(conn->bits.tls_enable_alpn) { + int cur = 0; + gnutls_datum_t protocols[2]; + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2 && + (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) { + protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID; + protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN; + cur++; + infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1; + protocols[cur].size = ALPN_HTTP_1_1_LENGTH; + cur++; + infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + + gnutls_alpn_set_protocols(session, protocols, cur, 0); + } +#endif + + if(SSL_SET_OPTION(cert)) { + if(SSL_SET_OPTION(key_passwd)) { +#if HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 + const unsigned int supported_key_encryption_algorithms = + GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR | + GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES | + GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 | + GNUTLS_PKCS_USE_PBES2_AES_256; + rc = gnutls_certificate_set_x509_key_file2( + BACKEND->cred, + SSL_SET_OPTION(cert), + SSL_SET_OPTION(key) ? + SSL_SET_OPTION(key) : SSL_SET_OPTION(cert), + do_file_type(SSL_SET_OPTION(cert_type)), + SSL_SET_OPTION(key_passwd), + supported_key_encryption_algorithms); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, + "error reading X.509 potentially-encrypted key file: %s", + gnutls_strerror(rc)); + return CURLE_SSL_CONNECT_ERROR; + } +#else + failf(data, "gnutls lacks support for encrypted key files"); + return CURLE_SSL_CONNECT_ERROR; +#endif + } + else { + if(gnutls_certificate_set_x509_key_file( + BACKEND->cred, + SSL_SET_OPTION(cert), + SSL_SET_OPTION(key) ? + SSL_SET_OPTION(key) : SSL_SET_OPTION(cert), + do_file_type(SSL_SET_OPTION(cert_type)) ) != + GNUTLS_E_SUCCESS) { + failf(data, "error reading X.509 key or certificate file"); + return CURLE_SSL_CONNECT_ERROR; + } + } + } + +#ifdef USE_TLS_SRP + /* put the credentials to the current session */ + if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { + rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP, + BACKEND->srp_client_cred); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); + return CURLE_SSL_CONNECT_ERROR; + } + } + else +#endif + { + rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, + BACKEND->cred); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); + return CURLE_SSL_CONNECT_ERROR; + } + } + + if(conn->proxy_ssl[sockindex].use) { + transport_ptr = conn->proxy_ssl[sockindex].backend->session; + gnutls_transport_push = Curl_gtls_push_ssl; + gnutls_transport_pull = Curl_gtls_pull_ssl; + } + else { + /* file descriptor for the socket */ + transport_ptr = &conn->sock[sockindex]; + gnutls_transport_push = Curl_gtls_push; + gnutls_transport_pull = Curl_gtls_pull; + } + + /* set the connection handle */ + gnutls_transport_set_ptr(session, transport_ptr); + + /* register callback functions to send and receive data. */ + gnutls_transport_set_push_function(session, gnutls_transport_push); + gnutls_transport_set_pull_function(session, gnutls_transport_pull); + + /* lowat must be set to zero when using custom push and pull functions. */ + gnutls_transport_set_lowat(session, 0); + +#ifdef HAS_OCSP + if(SSL_CONN_CONFIG(verifystatus)) { + rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL); + if(rc != GNUTLS_E_SUCCESS) { + failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc); + return CURLE_SSL_CONNECT_ERROR; + } + } +#endif + + /* This might be a reconnect, so we check for a session ID in the cache + to speed up things */ + if(SSL_SET_OPTION(primary.sessionid)) { + void *ssl_sessionid; + size_t ssl_idsize; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize, sockindex)) { + /* we got a session id, use it! */ + gnutls_session_set_data(session, ssl_sessionid, ssl_idsize); + + /* Informational message */ + infof(data, "SSL re-using session ID\n"); + } + Curl_ssl_sessionid_unlock(conn); + } + + return CURLE_OK; +} + +static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, + gnutls_x509_crt_t cert, + const char *pinnedpubkey) +{ + /* Scratch */ + size_t len1 = 0, len2 = 0; + unsigned char *buff1 = NULL; + + gnutls_pubkey_t key = NULL; + + /* Result is returned to caller */ + CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + + /* if a path wasn't specified, don't pin */ + if(NULL == pinnedpubkey) + return CURLE_OK; + + if(NULL == cert) + return result; + + do { + int ret; + + /* Begin Gyrations to get the public key */ + gnutls_pubkey_init(&key); + + ret = gnutls_pubkey_import_x509(key, cert, 0); + if(ret < 0) + break; /* failed */ + + ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1); + if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0) + break; /* failed */ + + buff1 = malloc(len1); + if(NULL == buff1) + break; /* failed */ + + len2 = len1; + + ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2); + if(ret < 0 || len1 != len2) + break; /* failed */ + + /* End Gyrations */ + + /* The one good exit point */ + result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); + } while(0); + + if(NULL != key) + gnutls_pubkey_deinit(key); + + Curl_safefree(buff1); + + return result; +} + +static Curl_recv gtls_recv; +static Curl_send gtls_send; + +static CURLcode +gtls_connect_step3(struct connectdata *conn, + int sockindex) +{ + unsigned int cert_list_size; + const gnutls_datum_t *chainp; + unsigned int verify_status = 0; + gnutls_x509_crt_t x509_cert, x509_issuer; + gnutls_datum_t issuerp; + char certbuf[256] = ""; /* big enough? */ + size_t size; + time_t certclock; + const char *ptr; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + gnutls_session_t session = BACKEND->session; + int rc; +#ifdef HAS_ALPN + gnutls_datum_t proto; +#endif + CURLcode result = CURLE_OK; +#ifndef CURL_DISABLE_VERBOSE_STRINGS + unsigned int algo; + unsigned int bits; + gnutls_protocol_t version = gnutls_protocol_get_version(session); +#endif + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + + /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ + ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session), + gnutls_cipher_get(session), + gnutls_mac_get(session)); + + infof(data, "SSL connection using %s / %s\n", + gnutls_protocol_get_name(version), ptr); + + /* This function will return the peer's raw certificate (chain) as sent by + the peer. These certificates are in raw format (DER encoded for + X.509). In case of a X.509 then a certificate list may be present. The + first certificate in the list is the peer's certificate, following the + issuer's certificate, then the issuer's issuer etc. */ + + chainp = gnutls_certificate_get_peers(session, &cert_list_size); + if(!chainp) { + if(SSL_CONN_CONFIG(verifypeer) || + SSL_CONN_CONFIG(verifyhost) || + SSL_SET_OPTION(issuercert)) { +#ifdef USE_TLS_SRP + if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP + && SSL_SET_OPTION(username) != NULL + && !SSL_CONN_CONFIG(verifypeer) + && gnutls_cipher_get(session)) { + /* no peer cert, but auth is ok if we have SRP user and cipher and no + peer verify */ + } + else { +#endif + failf(data, "failed to get server cert"); + return CURLE_PEER_FAILED_VERIFICATION; +#ifdef USE_TLS_SRP + } +#endif + } + infof(data, "\t common name: WARNING couldn't obtain\n"); + } + + if(data->set.ssl.certinfo && chainp) { + unsigned int i; + + result = Curl_ssl_init_certinfo(data, cert_list_size); + if(result) + return result; + + for(i = 0; i < cert_list_size; i++) { + const char *beg = (const char *) chainp[i].data; + const char *end = beg + chainp[i].size; + + result = Curl_extract_certinfo(conn, i, beg, end); + if(result) + return result; + } + } + + if(SSL_CONN_CONFIG(verifypeer)) { + /* This function will try to verify the peer's certificate and return its + status (trusted, invalid etc.). The value of status should be one or + more of the gnutls_certificate_status_t enumerated elements bitwise + or'd. To avoid denial of service attacks some default upper limits + regarding the certificate key size and chain size are set. To override + them use gnutls_certificate_set_verify_limits(). */ + + rc = gnutls_certificate_verify_peers2(session, &verify_status); + if(rc < 0) { + failf(data, "server cert verify failed: %d", rc); + return CURLE_SSL_CONNECT_ERROR; + } + + /* verify_status is a bitmask of gnutls_certificate_status bits */ + if(verify_status & GNUTLS_CERT_INVALID) { + if(SSL_CONN_CONFIG(verifypeer)) { + failf(data, "server certificate verification failed. CAfile: %s " + "CRLfile: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile): + "none", + SSL_SET_OPTION(CRLfile)?SSL_SET_OPTION(CRLfile):"none"); + return CURLE_PEER_FAILED_VERIFICATION; + } + else + infof(data, "\t server certificate verification FAILED\n"); + } + else + infof(data, "\t server certificate verification OK\n"); + } + else + infof(data, "\t server certificate verification SKIPPED\n"); + +#ifdef HAS_OCSP + if(SSL_CONN_CONFIG(verifystatus)) { + if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) { + gnutls_datum_t status_request; + gnutls_ocsp_resp_t ocsp_resp; + + gnutls_ocsp_cert_status_t status; + gnutls_x509_crl_reason_t reason; + + rc = gnutls_ocsp_status_request_get(session, &status_request); + + infof(data, "\t server certificate status verification FAILED\n"); + + if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { + failf(data, "No OCSP response received"); + return CURLE_SSL_INVALIDCERTSTATUS; + } + + if(rc < 0) { + failf(data, "Invalid OCSP response received"); + return CURLE_SSL_INVALIDCERTSTATUS; + } + + gnutls_ocsp_resp_init(&ocsp_resp); + + rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request); + if(rc < 0) { + failf(data, "Invalid OCSP response received"); + return CURLE_SSL_INVALIDCERTSTATUS; + } + + (void)gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, + &status, NULL, NULL, NULL, &reason); + + switch(status) { + case GNUTLS_OCSP_CERT_GOOD: + break; + + case GNUTLS_OCSP_CERT_REVOKED: { + const char *crl_reason; + + switch(reason) { + default: + case GNUTLS_X509_CRLREASON_UNSPECIFIED: + crl_reason = "unspecified reason"; + break; + + case GNUTLS_X509_CRLREASON_KEYCOMPROMISE: + crl_reason = "private key compromised"; + break; + + case GNUTLS_X509_CRLREASON_CACOMPROMISE: + crl_reason = "CA compromised"; + break; + + case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED: + crl_reason = "affiliation has changed"; + break; + + case GNUTLS_X509_CRLREASON_SUPERSEDED: + crl_reason = "certificate superseded"; + break; + + case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION: + crl_reason = "operation has ceased"; + break; + + case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD: + crl_reason = "certificate is on hold"; + break; + + case GNUTLS_X509_CRLREASON_REMOVEFROMCRL: + crl_reason = "will be removed from delta CRL"; + break; + + case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN: + crl_reason = "privilege withdrawn"; + break; + + case GNUTLS_X509_CRLREASON_AACOMPROMISE: + crl_reason = "AA compromised"; + break; + } + + failf(data, "Server certificate was revoked: %s", crl_reason); + break; + } + + default: + case GNUTLS_OCSP_CERT_UNKNOWN: + failf(data, "Server certificate status is unknown"); + break; + } + + gnutls_ocsp_resp_deinit(ocsp_resp); + + return CURLE_SSL_INVALIDCERTSTATUS; + } + else + infof(data, "\t server certificate status verification OK\n"); + } + else + infof(data, "\t server certificate status verification SKIPPED\n"); +#endif + + /* initialize an X.509 certificate structure. */ + gnutls_x509_crt_init(&x509_cert); + + if(chainp) + /* convert the given DER or PEM encoded Certificate to the native + gnutls_x509_crt_t format */ + gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER); + + if(SSL_SET_OPTION(issuercert)) { + gnutls_x509_crt_init(&x509_issuer); + issuerp = load_file(SSL_SET_OPTION(issuercert)); + gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM); + rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer); + gnutls_x509_crt_deinit(x509_issuer); + unload_file(issuerp); + if(rc <= 0) { + failf(data, "server certificate issuer check failed (IssuerCert: %s)", + SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_SSL_ISSUER_ERROR; + } + infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n", + SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); + } + + size = sizeof(certbuf); + rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME, + 0, /* the first and only one */ + FALSE, + certbuf, + &size); + if(rc) { + infof(data, "error fetching CN from cert:%s\n", + gnutls_strerror(rc)); + } + + /* This function will check if the given certificate's subject matches the + given hostname. This is a basic implementation of the matching described + in RFC2818 (HTTPS), which takes into account wildcards, and the subject + alternative name PKIX extension. Returns non zero on success, and zero on + failure. */ + rc = gnutls_x509_crt_check_hostname(x509_cert, hostname); +#if GNUTLS_VERSION_NUMBER < 0x030306 + /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP + addresses. */ + if(!rc) { +#ifdef ENABLE_IPV6 + #define use_addr in6_addr +#else + #define use_addr in_addr +#endif + unsigned char addrbuf[sizeof(struct use_addr)]; + size_t addrlen = 0; + + if(Curl_inet_pton(AF_INET, hostname, addrbuf) > 0) + addrlen = 4; +#ifdef ENABLE_IPV6 + else if(Curl_inet_pton(AF_INET6, hostname, addrbuf) > 0) + addrlen = 16; +#endif + + if(addrlen) { + unsigned char certaddr[sizeof(struct use_addr)]; + int i; + + for(i = 0; ; i++) { + size_t certaddrlen = sizeof(certaddr); + int ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr, + &certaddrlen, NULL); + /* If this happens, it wasn't an IP address. */ + if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER) + continue; + if(ret < 0) + break; + if(ret != GNUTLS_SAN_IPADDRESS) + continue; + if(certaddrlen == addrlen && !memcmp(addrbuf, certaddr, addrlen)) { + rc = 1; + break; + } + } + } + } +#endif + if(!rc) { + const char * const dispname = SSL_IS_PROXY() ? + conn->http_proxy.host.dispname : conn->host.dispname; + + if(SSL_CONN_CONFIG(verifyhost)) { + failf(data, "SSL: certificate subject name (%s) does not match " + "target host name '%s'", certbuf, dispname); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_PEER_FAILED_VERIFICATION; + } + else + infof(data, "\t common name: %s (does not match '%s')\n", + certbuf, dispname); + } + else + infof(data, "\t common name: %s (matched)\n", certbuf); + + /* Check for time-based validity */ + certclock = gnutls_x509_crt_get_expiration_time(x509_cert); + + if(certclock == (time_t)-1) { + if(SSL_CONN_CONFIG(verifypeer)) { + failf(data, "server cert expiration date verify failed"); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_SSL_CONNECT_ERROR; + } + else + infof(data, "\t server certificate expiration date verify FAILED\n"); + } + else { + if(certclock < time(NULL)) { + if(SSL_CONN_CONFIG(verifypeer)) { + failf(data, "server certificate expiration date has passed."); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_PEER_FAILED_VERIFICATION; + } + else + infof(data, "\t server certificate expiration date FAILED\n"); + } + else + infof(data, "\t server certificate expiration date OK\n"); + } + + certclock = gnutls_x509_crt_get_activation_time(x509_cert); + + if(certclock == (time_t)-1) { + if(SSL_CONN_CONFIG(verifypeer)) { + failf(data, "server cert activation date verify failed"); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_SSL_CONNECT_ERROR; + } + else + infof(data, "\t server certificate activation date verify FAILED\n"); + } + else { + if(certclock > time(NULL)) { + if(SSL_CONN_CONFIG(verifypeer)) { + failf(data, "server certificate not activated yet."); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_PEER_FAILED_VERIFICATION; + } + else + infof(data, "\t server certificate activation date FAILED\n"); + } + else + infof(data, "\t server certificate activation date OK\n"); + } + + ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + if(ptr) { + result = pkp_pin_peer_pubkey(data, x509_cert, ptr); + if(result != CURLE_OK) { + failf(data, "SSL: public key does not match pinned public key!"); + gnutls_x509_crt_deinit(x509_cert); + return result; + } + } + + /* Show: + + - subject + - start date + - expire date + - common name + - issuer + + */ + +#ifndef CURL_DISABLE_VERBOSE_STRINGS + /* public key algorithm's parameters */ + algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits); + infof(data, "\t certificate public key: %s\n", + gnutls_pk_algorithm_get_name(algo)); + + /* version of the X.509 certificate. */ + infof(data, "\t certificate version: #%d\n", + gnutls_x509_crt_get_version(x509_cert)); + + + size = sizeof(certbuf); + gnutls_x509_crt_get_dn(x509_cert, certbuf, &size); + infof(data, "\t subject: %s\n", certbuf); + + certclock = gnutls_x509_crt_get_activation_time(x509_cert); + showtime(data, "start date", certclock); + + certclock = gnutls_x509_crt_get_expiration_time(x509_cert); + showtime(data, "expire date", certclock); + + size = sizeof(certbuf); + gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size); + infof(data, "\t issuer: %s\n", certbuf); +#endif + + gnutls_x509_crt_deinit(x509_cert); + +#ifdef HAS_ALPN + if(conn->bits.tls_enable_alpn) { + rc = gnutls_alpn_get_selected_protocol(session, &proto); + if(rc == 0) { + infof(data, "ALPN, server accepted to use %.*s\n", proto.size, + proto.data); + +#ifdef USE_NGHTTP2 + if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN && + !memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data, + NGHTTP2_PROTO_VERSION_ID_LEN)) { + conn->negnpn = CURL_HTTP_VERSION_2; + } + else +#endif + if(proto.size == ALPN_HTTP_1_1_LENGTH && + !memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) { + conn->negnpn = CURL_HTTP_VERSION_1_1; + } + } + else + infof(data, "ALPN, server did not agree to a protocol\n"); + + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + } +#endif + + conn->ssl[sockindex].state = ssl_connection_complete; + conn->recv[sockindex] = gtls_recv; + conn->send[sockindex] = gtls_send; + + if(SSL_SET_OPTION(primary.sessionid)) { + /* we always unconditionally get the session id here, as even if we + already got it from the cache and asked to use it in the connection, it + might've been rejected and then a new one is in use now and we need to + detect that. */ + void *connect_sessionid; + size_t connect_idsize = 0; + + /* get the session ID data size */ + gnutls_session_get_data(session, NULL, &connect_idsize); + connect_sessionid = malloc(connect_idsize); /* get a buffer for it */ + + if(connect_sessionid) { + bool incache; + void *ssl_sessionid; + + /* extract session ID to the allocated buffer */ + gnutls_session_get_data(session, connect_sessionid, &connect_idsize); + + Curl_ssl_sessionid_lock(conn); + incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, + sockindex)); + if(incache) { + /* there was one before in the cache, so instead of risking that the + previous one was rejected, we just kill that and store the new */ + Curl_ssl_delsessionid(conn, ssl_sessionid); + } + + /* store this session id */ + result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize, + sockindex); + Curl_ssl_sessionid_unlock(conn); + if(result) { + free(connect_sessionid); + result = CURLE_OUT_OF_MEMORY; + } + } + else + result = CURLE_OUT_OF_MEMORY; + } + + return result; +} + + +/* + * This function is called after the TCP connect has completed. Setup the TLS + * layer and do all necessary magic. + */ +/* We use connssl->connecting_state to keep track of the connection status; + there are three states: 'ssl_connect_1' (not started yet or complete), + 'ssl_connect_2_reading' (waiting for data from server), and + 'ssl_connect_2_writing' (waiting to be able to write). + */ +static CURLcode +gtls_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + int rc; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + /* Initiate the connection, if not already done */ + if(ssl_connect_1 == connssl->connecting_state) { + rc = gtls_connect_step1(conn, sockindex); + if(rc) + return rc; + } + + rc = handshake(conn, sockindex, TRUE, nonblocking); + if(rc) + /* handshake() sets its own error message with failf() */ + return rc; + + /* Finish connecting once the handshake is done */ + if(ssl_connect_1 == connssl->connecting_state) { + rc = gtls_connect_step3(conn, sockindex); + if(rc) + return rc; + } + + *done = ssl_connect_1 == connssl->connecting_state; + + return CURLE_OK; +} + +static CURLcode Curl_gtls_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + return gtls_connect_common(conn, sockindex, TRUE, done); +} + +static CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex) +{ + CURLcode result; + bool done = FALSE; + + result = gtls_connect_common(conn, sockindex, FALSE, &done); + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +static bool Curl_gtls_data_pending(const struct connectdata *conn, + int connindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[connindex]; + bool res = FALSE; + if(BACKEND->session && + 0 != gnutls_record_check_pending(BACKEND->session)) + res = TRUE; + + connssl = &conn->proxy_ssl[connindex]; + if(BACKEND->session && + 0 != gnutls_record_check_pending(BACKEND->session)) + res = TRUE; + + return res; +} + +static ssize_t gtls_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + ssize_t rc = gnutls_record_send(BACKEND->session, mem, len); + + if(rc < 0) { + *curlcode = (rc == GNUTLS_E_AGAIN) + ? CURLE_AGAIN + : CURLE_SEND_ERROR; + + rc = -1; + } + + return rc; +} + +static void close_one(struct ssl_connect_data *connssl) +{ + if(BACKEND->session) { + gnutls_bye(BACKEND->session, GNUTLS_SHUT_RDWR); + gnutls_deinit(BACKEND->session); + BACKEND->session = NULL; + } + if(BACKEND->cred) { + gnutls_certificate_free_credentials(BACKEND->cred); + BACKEND->cred = NULL; + } +#ifdef USE_TLS_SRP + if(BACKEND->srp_client_cred) { + gnutls_srp_free_client_credentials(BACKEND->srp_client_cred); + BACKEND->srp_client_cred = NULL; + } +#endif +} + +static void Curl_gtls_close(struct connectdata *conn, int sockindex) +{ + close_one(&conn->ssl[sockindex]); + close_one(&conn->proxy_ssl[sockindex]); +} + +/* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) + */ +static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + int retval = 0; + struct Curl_easy *data = conn->data; + +#ifndef CURL_DISABLE_FTP + /* This has only been tested on the proftpd server, and the mod_tls code + sends a close notify alert without waiting for a close notify alert in + response. Thus we wait for a close notify alert from the server, but + we do not send one. Let's hope other servers do the same... */ + + if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) + gnutls_bye(BACKEND->session, GNUTLS_SHUT_WR); +#endif + + if(BACKEND->session) { + ssize_t result; + bool done = FALSE; + char buf[120]; + + while(!done) { + int what = SOCKET_READABLE(conn->sock[sockindex], + SSL_SHUTDOWN_TIMEOUT); + if(what > 0) { + /* Something to read, let's do it and hope that it is the close + notify alert from the server */ + result = gnutls_record_recv(BACKEND->session, + buf, sizeof(buf)); + switch(result) { + case 0: + /* This is the expected response. There was no data but only + the close notify alert */ + done = TRUE; + break; + case GNUTLS_E_AGAIN: + case GNUTLS_E_INTERRUPTED: + infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n"); + break; + default: + retval = -1; + done = TRUE; + break; + } + } + else if(0 == what) { + /* timeout */ + failf(data, "SSL shutdown timeout"); + done = TRUE; + } + else { + /* anything that gets here is fatally bad */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + retval = -1; + done = TRUE; + } + } + gnutls_deinit(BACKEND->session); + } + gnutls_certificate_free_credentials(BACKEND->cred); + +#ifdef USE_TLS_SRP + if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP + && SSL_SET_OPTION(username) != NULL) + gnutls_srp_free_client_credentials(BACKEND->srp_client_cred); +#endif + + BACKEND->cred = NULL; + BACKEND->session = NULL; + + return retval; +} + +static ssize_t gtls_recv(struct connectdata *conn, /* connection data */ + int num, /* socketindex */ + char *buf, /* store read data here */ + size_t buffersize, /* max amount to read */ + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[num]; + ssize_t ret; + + ret = gnutls_record_recv(BACKEND->session, buf, buffersize); + if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) { + *curlcode = CURLE_AGAIN; + return -1; + } + + if(ret == GNUTLS_E_REHANDSHAKE) { + /* BLOCKING call, this is bad but a work-around for now. Fixing this "the + proper way" takes a whole lot of work. */ + CURLcode result = handshake(conn, num, FALSE, FALSE); + if(result) + /* handshake() writes error message on its own */ + *curlcode = result; + else + *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */ + return -1; + } + + if(ret < 0) { + failf(conn->data, "GnuTLS recv error (%d): %s", + + (int)ret, gnutls_strerror((int)ret)); + *curlcode = CURLE_RECV_ERROR; + return -1; + } + + return ret; +} + +static void Curl_gtls_session_free(void *ptr) +{ + free(ptr); +} + +static size_t Curl_gtls_version(char *buffer, size_t size) +{ + return msnprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL)); +} + +#ifndef USE_GNUTLS_NETTLE +static int Curl_gtls_seed(struct Curl_easy *data) +{ + /* we have the "SSL is seeded" boolean static to prevent multiple + time-consuming seedings in vain */ + static bool ssl_seeded = FALSE; + + /* Quickly add a bit of entropy */ + gcry_fast_random_poll(); + + if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] || + data->set.str[STRING_SSL_EGDSOCKET]) { + ssl_seeded = TRUE; + } + return 0; +} +#endif + +/* data might be NULL! */ +static CURLcode Curl_gtls_random(struct Curl_easy *data, + unsigned char *entropy, size_t length) +{ +#if defined(USE_GNUTLS_NETTLE) + int rc; + (void)data; + rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length); + return rc?CURLE_FAILED_INIT:CURLE_OK; +#elif defined(USE_GNUTLS) + if(data) + Curl_gtls_seed(data); /* Initiate the seed if not already done */ + gcry_randomize(entropy, length, GCRY_STRONG_RANDOM); +#endif + return CURLE_OK; +} + +static CURLcode Curl_gtls_md5sum(unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *md5sum, /* output */ + size_t md5len) +{ +#if defined(USE_GNUTLS_NETTLE) + struct md5_ctx MD5pw; + md5_init(&MD5pw); + md5_update(&MD5pw, (unsigned int)tmplen, tmp); + md5_digest(&MD5pw, (unsigned int)md5len, md5sum); +#elif defined(USE_GNUTLS) + gcry_md_hd_t MD5pw; + gcry_md_open(&MD5pw, GCRY_MD_MD5, 0); + gcry_md_write(MD5pw, tmp, tmplen); + memcpy(md5sum, gcry_md_read(MD5pw, 0), md5len); + gcry_md_close(MD5pw); +#endif + return CURLE_OK; +} + +static CURLcode Curl_gtls_sha256sum(const unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *sha256sum, /* output */ + size_t sha256len) +{ +#if defined(USE_GNUTLS_NETTLE) + struct sha256_ctx SHA256pw; + sha256_init(&SHA256pw); + sha256_update(&SHA256pw, (unsigned int)tmplen, tmp); + sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum); +#elif defined(USE_GNUTLS) + gcry_md_hd_t SHA256pw; + gcry_md_open(&SHA256pw, GCRY_MD_SHA256, 0); + gcry_md_write(SHA256pw, tmp, tmplen); + memcpy(sha256sum, gcry_md_read(SHA256pw, 0), sha256len); + gcry_md_close(SHA256pw); +#endif + return CURLE_OK; +} + +static bool Curl_gtls_cert_status_request(void) +{ +#ifdef HAS_OCSP + return TRUE; +#else + return FALSE; +#endif +} + +static void *Curl_gtls_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + (void)info; + return BACKEND->session; +} + +const struct Curl_ssl Curl_ssl_gnutls = { + { CURLSSLBACKEND_GNUTLS, "gnutls" }, /* info */ + + SSLSUPP_CA_PATH | + SSLSUPP_CERTINFO | + SSLSUPP_PINNEDPUBKEY | + SSLSUPP_HTTPS_PROXY, + + sizeof(struct ssl_backend_data), + + Curl_gtls_init, /* init */ + Curl_gtls_cleanup, /* cleanup */ + Curl_gtls_version, /* version */ + Curl_none_check_cxn, /* check_cxn */ + Curl_gtls_shutdown, /* shutdown */ + Curl_gtls_data_pending, /* data_pending */ + Curl_gtls_random, /* random */ + Curl_gtls_cert_status_request, /* cert_status_request */ + Curl_gtls_connect, /* connect */ + Curl_gtls_connect_nonblocking, /* connect_nonblocking */ + Curl_gtls_get_internals, /* get_internals */ + Curl_gtls_close, /* close_one */ + Curl_none_close_all, /* close_all */ + Curl_gtls_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_gtls_md5sum, /* md5sum */ + Curl_gtls_sha256sum /* sha256sum */ +}; + +#endif /* USE_GNUTLS */ diff --git a/libcurl/lib/vtls/gtls.h b/libcurl/lib/vtls/gtls.h new file mode 100644 index 0000000..780fc10 --- /dev/null +++ b/libcurl/lib/vtls/gtls.h @@ -0,0 +1,34 @@ +#ifndef HEADER_CURL_GTLS_H +#define HEADER_CURL_GTLS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_GNUTLS + +#include "urldata.h" + +extern const struct Curl_ssl Curl_ssl_gnutls; + +#endif /* USE_GNUTLS */ +#endif /* HEADER_CURL_GTLS_H */ diff --git a/libcurl/lib/vtls/mbedtls.c b/libcurl/lib/vtls/mbedtls.c new file mode 100644 index 0000000..63d1f4c --- /dev/null +++ b/libcurl/lib/vtls/mbedtls.c @@ -0,0 +1,1086 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2010 - 2011, Hoi-Ho Chan, + * Copyright (C) 2012 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all mbedTLS-specific code for the TLS/SSL layer. No code + * but vtls.c should ever call or use these functions. + * + */ + +#include "curl_setup.h" + +#ifdef USE_MBEDTLS + +#include +#if MBEDTLS_VERSION_NUMBER >= 0x02040000 +#include +#else +#include +#endif +#include +#include +#include + +#include +#include +#include +#include + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "mbedtls.h" +#include "vtls.h" +#include "parsedate.h" +#include "connect.h" /* for the connect timeout */ +#include "select.h" +#include "multiif.h" +#include "polarssl_threadlock.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +struct ssl_backend_data { + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_entropy_context entropy; + mbedtls_ssl_context ssl; + int server_fd; + mbedtls_x509_crt cacert; + mbedtls_x509_crt clicert; + mbedtls_x509_crl crl; + mbedtls_pk_context pk; + mbedtls_ssl_config config; + const char *protocols[3]; +}; + +#define BACKEND connssl->backend + +/* apply threading? */ +#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) +#define THREADING_SUPPORT +#endif + +#if defined(THREADING_SUPPORT) +static mbedtls_entropy_context ts_entropy; + +static int entropy_init_initialized = 0; + +/* start of entropy_init_mutex() */ +static void entropy_init_mutex(mbedtls_entropy_context *ctx) +{ + /* lock 0 = entropy_init_mutex() */ + Curl_polarsslthreadlock_lock_function(0); + if(entropy_init_initialized == 0) { + mbedtls_entropy_init(ctx); + entropy_init_initialized = 1; + } + Curl_polarsslthreadlock_unlock_function(0); +} +/* end of entropy_init_mutex() */ + +/* start of entropy_func_mutex() */ +static int entropy_func_mutex(void *data, unsigned char *output, size_t len) +{ + int ret; + /* lock 1 = entropy_func_mutex() */ + Curl_polarsslthreadlock_lock_function(1); + ret = mbedtls_entropy_func(data, output, len); + Curl_polarsslthreadlock_unlock_function(1); + + return ret; +} +/* end of entropy_func_mutex() */ + +#endif /* THREADING_SUPPORT */ + +/* Define this to enable lots of debugging for mbedTLS */ +#undef MBEDTLS_DEBUG + +#ifdef MBEDTLS_DEBUG +static void mbed_debug(void *context, int level, const char *f_name, + int line_nb, const char *line) +{ + struct Curl_easy *data = NULL; + + if(!context) + return; + + data = (struct Curl_easy *)context; + + infof(data, "%s", line); + (void) level; +} +#else +#endif + +/* ALPN for http2? */ +#ifdef USE_NGHTTP2 +# undef HAS_ALPN +# ifdef MBEDTLS_SSL_ALPN +# define HAS_ALPN +# endif +#endif + + +/* + * profile + */ +static const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr = +{ + /* Hashes from SHA-1 and above */ + MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) | + MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_RIPEMD160) | + MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA224) | + MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) | + MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) | + MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512), + 0xFFFFFFF, /* Any PK alg */ + 0xFFFFFFF, /* Any curve */ + 1024, /* RSA min key len */ +}; + +/* See https://tls.mbed.org/discussions/generic/ + howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der +*/ +#define RSA_PUB_DER_MAX_BYTES (38 + 2 * MBEDTLS_MPI_MAX_SIZE) +#define ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_ECP_MAX_BYTES) + +#define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ + RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES) + +static Curl_recv mbed_recv; +static Curl_send mbed_send; + +static CURLcode mbedtls_version_from_curl(int *mbedver, long version) +{ + switch(version) { + case CURL_SSLVERSION_TLSv1_0: + *mbedver = MBEDTLS_SSL_MINOR_VERSION_1; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_1: + *mbedver = MBEDTLS_SSL_MINOR_VERSION_2; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_2: + *mbedver = MBEDTLS_SSL_MINOR_VERSION_3; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_3: + break; + } + return CURLE_SSL_CONNECT_ERROR; +} + +static CURLcode +set_ssl_version_min_max(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_1; + int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_1; + long ssl_version = SSL_CONN_CONFIG(version); + long ssl_version_max = SSL_CONN_CONFIG(version_max); + CURLcode result = CURLE_OK; + + switch(ssl_version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + ssl_version = CURL_SSLVERSION_TLSv1_0; + break; + } + + switch(ssl_version_max) { + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_DEFAULT: + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; + break; + } + + result = mbedtls_version_from_curl(&mbedtls_ver_min, ssl_version); + if(result) { + failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); + return result; + } + result = mbedtls_version_from_curl(&mbedtls_ver_max, ssl_version_max >> 16); + if(result) { + failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); + return result; + } + + mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3, + mbedtls_ver_min); + mbedtls_ssl_conf_max_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3, + mbedtls_ver_max); + + return result; +} + +static CURLcode +mbed_connect_step1(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data* connssl = &conn->ssl[sockindex]; + const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); + const char * const ssl_capath = SSL_CONN_CONFIG(CApath); + char * const ssl_cert = SSL_SET_OPTION(cert); + const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; + int ret = -1; + char errorbuf[128]; + errorbuf[0] = 0; + + /* mbedTLS only supports SSLv3 and TLSv1 */ + if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) { + failf(data, "mbedTLS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + } + +#ifdef THREADING_SUPPORT + entropy_init_mutex(&ts_entropy); + mbedtls_ctr_drbg_init(&BACKEND->ctr_drbg); + + ret = mbedtls_ctr_drbg_seed(&BACKEND->ctr_drbg, entropy_func_mutex, + &ts_entropy, NULL, 0); + if(ret) { +#ifdef MBEDTLS_ERROR_C + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); +#endif /* MBEDTLS_ERROR_C */ + failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n", + -ret, errorbuf); + } +#else + mbedtls_entropy_init(&BACKEND->entropy); + mbedtls_ctr_drbg_init(&BACKEND->ctr_drbg); + + ret = mbedtls_ctr_drbg_seed(&BACKEND->ctr_drbg, mbedtls_entropy_func, + &BACKEND->entropy, NULL, 0); + if(ret) { +#ifdef MBEDTLS_ERROR_C + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); +#endif /* MBEDTLS_ERROR_C */ + failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n", + -ret, errorbuf); + } +#endif /* THREADING_SUPPORT */ + + /* Load the trusted CA */ + mbedtls_x509_crt_init(&BACKEND->cacert); + + if(ssl_cafile) { + ret = mbedtls_x509_crt_parse_file(&BACKEND->cacert, ssl_cafile); + + if(ret<0) { +#ifdef MBEDTLS_ERROR_C + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); +#endif /* MBEDTLS_ERROR_C */ + failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s", + ssl_cafile, -ret, errorbuf); + + if(verifypeer) + return CURLE_SSL_CACERT_BADFILE; + } + } + + if(ssl_capath) { + ret = mbedtls_x509_crt_parse_path(&BACKEND->cacert, ssl_capath); + + if(ret<0) { +#ifdef MBEDTLS_ERROR_C + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); +#endif /* MBEDTLS_ERROR_C */ + failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s", + ssl_capath, -ret, errorbuf); + + if(verifypeer) + return CURLE_SSL_CACERT_BADFILE; + } + } + + /* Load the client certificate */ + mbedtls_x509_crt_init(&BACKEND->clicert); + + if(ssl_cert) { + ret = mbedtls_x509_crt_parse_file(&BACKEND->clicert, ssl_cert); + + if(ret) { +#ifdef MBEDTLS_ERROR_C + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); +#endif /* MBEDTLS_ERROR_C */ + failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s", + ssl_cert, -ret, errorbuf); + + return CURLE_SSL_CERTPROBLEM; + } + } + + /* Load the client private key */ + mbedtls_pk_init(&BACKEND->pk); + + if(SSL_SET_OPTION(key)) { + ret = mbedtls_pk_parse_keyfile(&BACKEND->pk, SSL_SET_OPTION(key), + SSL_SET_OPTION(key_passwd)); + if(ret == 0 && !(mbedtls_pk_can_do(&BACKEND->pk, MBEDTLS_PK_RSA) || + mbedtls_pk_can_do(&BACKEND->pk, MBEDTLS_PK_ECKEY))) + ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; + + if(ret) { +#ifdef MBEDTLS_ERROR_C + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); +#endif /* MBEDTLS_ERROR_C */ + failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s", + SSL_SET_OPTION(key), -ret, errorbuf); + + return CURLE_SSL_CERTPROBLEM; + } + } + + /* Load the CRL */ + mbedtls_x509_crl_init(&BACKEND->crl); + + if(ssl_crlfile) { + ret = mbedtls_x509_crl_parse_file(&BACKEND->crl, ssl_crlfile); + + if(ret) { +#ifdef MBEDTLS_ERROR_C + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); +#endif /* MBEDTLS_ERROR_C */ + failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s", + ssl_crlfile, -ret, errorbuf); + + return CURLE_SSL_CRL_BADFILE; + } + } + + infof(data, "mbedTLS: Connecting to %s:%ld\n", hostname, port); + + mbedtls_ssl_config_init(&BACKEND->config); + + mbedtls_ssl_init(&BACKEND->ssl); + if(mbedtls_ssl_setup(&BACKEND->ssl, &BACKEND->config)) { + failf(data, "mbedTLS: ssl_init failed"); + return CURLE_SSL_CONNECT_ERROR; + } + ret = mbedtls_ssl_config_defaults(&BACKEND->config, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT); + if(ret) { + failf(data, "mbedTLS: ssl_config failed"); + return CURLE_SSL_CONNECT_ERROR; + } + + /* new profile with RSA min key len = 1024 ... */ + mbedtls_ssl_conf_cert_profile(&BACKEND->config, + &mbedtls_x509_crt_profile_fr); + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3, + MBEDTLS_SSL_MINOR_VERSION_1); + infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n"); + break; + case CURL_SSLVERSION_SSLv3: + mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3, + MBEDTLS_SSL_MINOR_VERSION_0); + mbedtls_ssl_conf_max_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3, + MBEDTLS_SSL_MINOR_VERSION_0); + infof(data, "mbedTLS: Set SSL version to SSLv3\n"); + break; + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + { + CURLcode result = set_ssl_version_min_max(conn, sockindex); + if(result != CURLE_OK) + return result; + break; + } + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + mbedtls_ssl_conf_authmode(&BACKEND->config, MBEDTLS_SSL_VERIFY_OPTIONAL); + + mbedtls_ssl_conf_rng(&BACKEND->config, mbedtls_ctr_drbg_random, + &BACKEND->ctr_drbg); + mbedtls_ssl_set_bio(&BACKEND->ssl, &conn->sock[sockindex], + mbedtls_net_send, + mbedtls_net_recv, + NULL /* rev_timeout() */); + + mbedtls_ssl_conf_ciphersuites(&BACKEND->config, + mbedtls_ssl_list_ciphersuites()); + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + mbedtls_ssl_conf_renegotiation(&BACKEND->config, + MBEDTLS_SSL_RENEGOTIATION_ENABLED); +#endif + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + mbedtls_ssl_conf_session_tickets(&BACKEND->config, + MBEDTLS_SSL_SESSION_TICKETS_DISABLED); +#endif + + /* Check if there's a cached ID we can/should use here! */ + if(SSL_SET_OPTION(primary.sessionid)) { + void *old_session = NULL; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) { + ret = mbedtls_ssl_set_session(&BACKEND->ssl, old_session); + if(ret) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret); + return CURLE_SSL_CONNECT_ERROR; + } + infof(data, "mbedTLS re-using session\n"); + } + Curl_ssl_sessionid_unlock(conn); + } + + mbedtls_ssl_conf_ca_chain(&BACKEND->config, + &BACKEND->cacert, + &BACKEND->crl); + + if(SSL_SET_OPTION(key)) { + mbedtls_ssl_conf_own_cert(&BACKEND->config, + &BACKEND->clicert, &BACKEND->pk); + } + if(mbedtls_ssl_set_hostname(&BACKEND->ssl, hostname)) { + /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and* + the name to set in the SNI extension. So even if curl connects to a + host specified as an IP address, this function must be used. */ + failf(data, "couldn't set hostname in mbedTLS"); + return CURLE_SSL_CONNECT_ERROR; + } + +#ifdef HAS_ALPN + if(conn->bits.tls_enable_alpn) { + const char **p = &BACKEND->protocols[0]; +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2) + *p++ = NGHTTP2_PROTO_VERSION_ID; +#endif + *p++ = ALPN_HTTP_1_1; + *p = NULL; + /* this function doesn't clone the protocols array, which is why we need + to keep it around */ + if(mbedtls_ssl_conf_alpn_protocols(&BACKEND->config, + &BACKEND->protocols[0])) { + failf(data, "Failed setting ALPN protocols"); + return CURLE_SSL_CONNECT_ERROR; + } + for(p = &BACKEND->protocols[0]; *p; ++p) + infof(data, "ALPN, offering %s\n", *p); + } +#endif + +#ifdef MBEDTLS_DEBUG + /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */ + mbedtls_ssl_conf_dbg(&BACKEND->config, mbed_debug, data); + /* - 0 No debug + * - 1 Error + * - 2 State change + * - 3 Informational + * - 4 Verbose + */ + mbedtls_debug_set_threshold(4); +#endif + + /* give application a chance to interfere with mbedTLS set up. */ + if(data->set.ssl.fsslctx) { + ret = (*data->set.ssl.fsslctx)(data, &BACKEND->config, + data->set.ssl.fsslctxp); + if(ret) { + failf(data, "error signaled by ssl ctx callback"); + return ret; + } + } + + connssl->connecting_state = ssl_connect_2; + + return CURLE_OK; +} + +static CURLcode +mbed_connect_step2(struct connectdata *conn, + int sockindex) +{ + int ret; + struct Curl_easy *data = conn->data; + struct ssl_connect_data* connssl = &conn->ssl[sockindex]; + const mbedtls_x509_crt *peercert; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + + conn->recv[sockindex] = mbed_recv; + conn->send[sockindex] = mbed_send; + + ret = mbedtls_ssl_handshake(&BACKEND->ssl); + + if(ret == MBEDTLS_ERR_SSL_WANT_READ) { + connssl->connecting_state = ssl_connect_2_reading; + return CURLE_OK; + } + else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + connssl->connecting_state = ssl_connect_2_writing; + return CURLE_OK; + } + else if(ret) { + char errorbuf[128]; + errorbuf[0] = 0; +#ifdef MBEDTLS_ERROR_C + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); +#endif /* MBEDTLS_ERROR_C */ + failf(data, "ssl_handshake returned - mbedTLS: (-0x%04X) %s", + -ret, errorbuf); + return CURLE_SSL_CONNECT_ERROR; + } + + infof(data, "mbedTLS: Handshake complete, cipher is %s\n", + mbedtls_ssl_get_ciphersuite(&BACKEND->ssl) + ); + + ret = mbedtls_ssl_get_verify_result(&BACKEND->ssl); + + if(!SSL_CONN_CONFIG(verifyhost)) + /* Ignore hostname errors if verifyhost is disabled */ + ret &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH; + + if(ret && SSL_CONN_CONFIG(verifypeer)) { + if(ret & MBEDTLS_X509_BADCERT_EXPIRED) + failf(data, "Cert verify failed: BADCERT_EXPIRED"); + + else if(ret & MBEDTLS_X509_BADCERT_REVOKED) + failf(data, "Cert verify failed: BADCERT_REVOKED"); + + else if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH) + failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); + + else if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED) + failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); + + return CURLE_PEER_FAILED_VERIFICATION; + } + + peercert = mbedtls_ssl_get_peer_cert(&BACKEND->ssl); + + if(peercert && data->set.verbose) { + const size_t bufsize = 16384; + char *buffer = malloc(bufsize); + + if(!buffer) + return CURLE_OUT_OF_MEMORY; + + if(mbedtls_x509_crt_info(buffer, bufsize, "* ", peercert) > 0) + infof(data, "Dumping cert info:\n%s\n", buffer); + else + infof(data, "Unable to dump certificate information.\n"); + + free(buffer); + } + + if(pinnedpubkey) { + int size; + CURLcode result; + mbedtls_x509_crt *p; + unsigned char pubkey[PUB_DER_MAX_BYTES]; + + if(!peercert || !peercert->raw.p || !peercert->raw.len) { + failf(data, "Failed due to missing peer certificate"); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + p = calloc(1, sizeof(*p)); + + if(!p) + return CURLE_OUT_OF_MEMORY; + + mbedtls_x509_crt_init(p); + + /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der + needs a non-const key, for now. + https://github.com/ARMmbed/mbedtls/issues/396 */ + if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) { + failf(data, "Failed copying peer certificate"); + mbedtls_x509_crt_free(p); + free(p); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES); + + if(size <= 0) { + failf(data, "Failed copying public key from peer certificate"); + mbedtls_x509_crt_free(p); + free(p); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */ + result = Curl_pin_peer_pubkey(data, + pinnedpubkey, + &pubkey[PUB_DER_MAX_BYTES - size], size); + if(result) { + mbedtls_x509_crt_free(p); + free(p); + return result; + } + + mbedtls_x509_crt_free(p); + free(p); + } + +#ifdef HAS_ALPN + if(conn->bits.tls_enable_alpn) { + const char *next_protocol = mbedtls_ssl_get_alpn_protocol(&BACKEND->ssl); + + if(next_protocol) { + infof(data, "ALPN, server accepted to use %s\n", next_protocol); +#ifdef USE_NGHTTP2 + if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID, + NGHTTP2_PROTO_VERSION_ID_LEN) && + !next_protocol[NGHTTP2_PROTO_VERSION_ID_LEN]) { + conn->negnpn = CURL_HTTP_VERSION_2; + } + else +#endif + if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH) && + !next_protocol[ALPN_HTTP_1_1_LENGTH]) { + conn->negnpn = CURL_HTTP_VERSION_1_1; + } + } + else { + infof(data, "ALPN, server did not agree to a protocol\n"); + } + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + } +#endif + + connssl->connecting_state = ssl_connect_3; + infof(data, "SSL connected\n"); + + return CURLE_OK; +} + +static CURLcode +mbed_connect_step3(struct connectdata *conn, + int sockindex) +{ + CURLcode retcode = CURLE_OK; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct Curl_easy *data = conn->data; + + DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); + + if(SSL_SET_OPTION(primary.sessionid)) { + int ret; + mbedtls_ssl_session *our_ssl_sessionid; + void *old_ssl_sessionid = NULL; + + our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session)); + if(!our_ssl_sessionid) + return CURLE_OUT_OF_MEMORY; + + mbedtls_ssl_session_init(our_ssl_sessionid); + + ret = mbedtls_ssl_get_session(&BACKEND->ssl, our_ssl_sessionid); + if(ret) { + if(ret != MBEDTLS_ERR_SSL_ALLOC_FAILED) + mbedtls_ssl_session_free(our_ssl_sessionid); + free(our_ssl_sessionid); + failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret); + return CURLE_SSL_CONNECT_ERROR; + } + + /* If there's already a matching session in the cache, delete it */ + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex)) + Curl_ssl_delsessionid(conn, old_ssl_sessionid); + + retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex); + Curl_ssl_sessionid_unlock(conn); + if(retcode) { + mbedtls_ssl_session_free(our_ssl_sessionid); + free(our_ssl_sessionid); + failf(data, "failed to store ssl session"); + return retcode; + } + } + + connssl->connecting_state = ssl_connect_done; + + return CURLE_OK; +} + +static ssize_t mbed_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + int ret = -1; + + ret = mbedtls_ssl_write(&BACKEND->ssl, + (unsigned char *)mem, len); + + if(ret < 0) { + *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_WRITE) ? + CURLE_AGAIN : CURLE_SEND_ERROR; + ret = -1; + } + + return ret; +} + +static void Curl_mbedtls_close_all(struct Curl_easy *data) +{ + (void)data; +} + +static void Curl_mbedtls_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + mbedtls_pk_free(&BACKEND->pk); + mbedtls_x509_crt_free(&BACKEND->clicert); + mbedtls_x509_crt_free(&BACKEND->cacert); + mbedtls_x509_crl_free(&BACKEND->crl); + mbedtls_ssl_config_free(&BACKEND->config); + mbedtls_ssl_free(&BACKEND->ssl); + mbedtls_ctr_drbg_free(&BACKEND->ctr_drbg); +#ifndef THREADING_SUPPORT + mbedtls_entropy_free(&BACKEND->entropy); +#endif /* THREADING_SUPPORT */ +} + +static ssize_t mbed_recv(struct connectdata *conn, int num, + char *buf, size_t buffersize, + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[num]; + int ret = -1; + ssize_t len = -1; + + memset(buf, 0, buffersize); + ret = mbedtls_ssl_read(&BACKEND->ssl, (unsigned char *)buf, + buffersize); + + if(ret <= 0) { + if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) + return 0; + + *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_READ) ? + CURLE_AGAIN : CURLE_RECV_ERROR; + return -1; + } + + len = ret; + + return len; +} + +static void Curl_mbedtls_session_free(void *ptr) +{ + mbedtls_ssl_session_free(ptr); + free(ptr); +} + +static size_t Curl_mbedtls_version(char *buffer, size_t size) +{ +#ifdef MBEDTLS_VERSION_C + /* if mbedtls_version_get_number() is available it is better */ + unsigned int version = mbedtls_version_get_number(); + return msnprintf(buffer, size, "mbedTLS/%u.%u.%u", version>>24, + (version>>16)&0xff, (version>>8)&0xff); +#else + return msnprintf(buffer, size, "mbedTLS/%s", MBEDTLS_VERSION_STRING); +#endif +} + +static CURLcode Curl_mbedtls_random(struct Curl_easy *data, + unsigned char *entropy, size_t length) +{ +#if defined(MBEDTLS_CTR_DRBG_C) + int ret = -1; + char errorbuf[128]; + mbedtls_entropy_context ctr_entropy; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_entropy_init(&ctr_entropy); + mbedtls_ctr_drbg_init(&ctr_drbg); + errorbuf[0] = 0; + + ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, + &ctr_entropy, NULL, 0); + + if(ret) { +#ifdef MBEDTLS_ERROR_C + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); +#endif /* MBEDTLS_ERROR_C */ + failf(data, "Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s\n", + -ret, errorbuf); + } + else { + ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length); + + if(ret) { +#ifdef MBEDTLS_ERROR_C + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); +#endif /* MBEDTLS_ERROR_C */ + failf(data, "mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n", + -ret, errorbuf); + } + } + + mbedtls_ctr_drbg_free(&ctr_drbg); + mbedtls_entropy_free(&ctr_entropy); + + return ret == 0 ? CURLE_OK : CURLE_FAILED_INIT; +#elif defined(MBEDTLS_HAVEGE_C) + mbedtls_havege_state hs; + mbedtls_havege_init(&hs); + mbedtls_havege_random(&hs, entropy, length); + mbedtls_havege_free(&hs); + return CURLE_OK; +#else + return CURLE_NOT_BUILT_IN; +#endif +} + +static CURLcode +mbed_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + CURLcode retcode; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + long timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + /* Find out how much more time we're allowed */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + retcode = mbed_connect_step1(conn, sockindex); + if(retcode) + return retcode; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading + || connssl->connecting_state == ssl_connect_2_writing) { + + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking ? 0 : timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if + * this connection is part of a multi handle and this loop would + * execute again. This permits the owner of a multi handle to + * abort a connection attempt before step2 has completed while + * ensuring that a client using select() or epoll() will always + * have a valid fdset to wait on. + */ + retcode = mbed_connect_step2(conn, sockindex); + if(retcode || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return retcode; + + } /* repeat step2 until all transactions are done. */ + + if(ssl_connect_3 == connssl->connecting_state) { + retcode = mbed_connect_step3(conn, sockindex); + if(retcode) + return retcode; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = mbed_recv; + conn->send[sockindex] = mbed_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +static CURLcode Curl_mbedtls_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + return mbed_connect_common(conn, sockindex, TRUE, done); +} + + +static CURLcode Curl_mbedtls_connect(struct connectdata *conn, int sockindex) +{ + CURLcode retcode; + bool done = FALSE; + + retcode = mbed_connect_common(conn, sockindex, FALSE, &done); + if(retcode) + return retcode; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +/* + * return 0 error initializing SSL + * return 1 SSL initialized successfully + */ +static int Curl_mbedtls_init(void) +{ + return Curl_polarsslthreadlock_thread_setup(); +} + +static void Curl_mbedtls_cleanup(void) +{ + (void)Curl_polarsslthreadlock_thread_cleanup(); +} + +static bool Curl_mbedtls_data_pending(const struct connectdata *conn, + int sockindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + return mbedtls_ssl_get_bytes_avail(&BACKEND->ssl) != 0; +} + +static CURLcode Curl_mbedtls_sha256sum(const unsigned char *input, + size_t inputlen, + unsigned char *sha256sum, + size_t sha256len UNUSED_PARAM) +{ + (void)sha256len; +#if MBEDTLS_VERSION_NUMBER < 0x02070000 + mbedtls_sha256(input, inputlen, sha256sum, 0); +#else + /* returns 0 on success, otherwise failure */ + if(mbedtls_sha256_ret(input, inputlen, sha256sum, 0) != 0) + return CURLE_BAD_FUNCTION_ARGUMENT; +#endif + return CURLE_OK; +} + +static void *Curl_mbedtls_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + (void)info; + return &BACKEND->ssl; +} + +const struct Curl_ssl Curl_ssl_mbedtls = { + { CURLSSLBACKEND_MBEDTLS, "mbedtls" }, /* info */ + + SSLSUPP_CA_PATH | + SSLSUPP_PINNEDPUBKEY | + SSLSUPP_SSL_CTX, + + sizeof(struct ssl_backend_data), + + Curl_mbedtls_init, /* init */ + Curl_mbedtls_cleanup, /* cleanup */ + Curl_mbedtls_version, /* version */ + Curl_none_check_cxn, /* check_cxn */ + Curl_none_shutdown, /* shutdown */ + Curl_mbedtls_data_pending, /* data_pending */ + Curl_mbedtls_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_mbedtls_connect, /* connect */ + Curl_mbedtls_connect_nonblocking, /* connect_nonblocking */ + Curl_mbedtls_get_internals, /* get_internals */ + Curl_mbedtls_close, /* close_one */ + Curl_mbedtls_close_all, /* close_all */ + Curl_mbedtls_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_none_md5sum, /* md5sum */ + Curl_mbedtls_sha256sum /* sha256sum */ +}; + +#endif /* USE_MBEDTLS */ diff --git a/libcurl/lib/vtls/mbedtls.h b/libcurl/lib/vtls/mbedtls.h new file mode 100644 index 0000000..4a93860 --- /dev/null +++ b/libcurl/lib/vtls/mbedtls.h @@ -0,0 +1,32 @@ +#ifndef HEADER_CURL_MBEDTLS_H +#define HEADER_CURL_MBEDTLS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2016, Daniel Stenberg, , et al. + * Copyright (C) 2010, Hoi-Ho Chan, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_MBEDTLS + +extern const struct Curl_ssl Curl_ssl_mbedtls; + +#endif /* USE_MBEDTLS */ +#endif /* HEADER_CURL_MBEDTLS_H */ diff --git a/libcurl/lib/vtls/mesalink.c b/libcurl/lib/vtls/mesalink.c new file mode 100644 index 0000000..7ca4f0e --- /dev/null +++ b/libcurl/lib/vtls/mesalink.c @@ -0,0 +1,627 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2017 - 2018, Yiming Jing, + * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all MesaLink-specific code for the TLS/SSL layer. No code + * but vtls.c should ever call or use these functions. + * + */ + +/* + * Based upon the CyaSSL implementation in cyassl.c and cyassl.h: + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * Thanks for code and inspiration! + */ + +#include "curl_setup.h" + +#ifdef USE_MESALINK + +#include +#include + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "vtls.h" +#include "parsedate.h" +#include "connect.h" /* for the connect timeout */ +#include "select.h" +#include "strcase.h" +#include "x509asn1.h" +#include "curl_printf.h" + +#include "mesalink.h" +#include +#include + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +#define MESALINK_MAX_ERROR_SZ 80 + +struct ssl_backend_data +{ + SSL_CTX *ctx; + SSL *handle; +}; + +#define BACKEND connssl->backend + +static Curl_recv mesalink_recv; +static Curl_send mesalink_send; + +/* + * This function loads all the client/CA certificates and CRLs. Setup the TLS + * layer and do all necessary magic. + */ +static CURLcode +mesalink_connect_step1(struct connectdata *conn, int sockindex) +{ + char *ciphers; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); + const char *const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const char *const ssl_capath = SSL_CONN_CONFIG(CApath); + struct in_addr addr4; +#ifdef ENABLE_IPV6 + struct in6_addr addr6; +#endif + const char *const hostname = + SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; + size_t hostname_len = strlen(hostname); + + SSL_METHOD *req_method = NULL; + curl_socket_t sockfd = conn->sock[sockindex]; + + if(connssl->state == ssl_connection_complete) + return CURLE_OK; + + if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) { + failf(data, "MesaLink does not support to set maximum SSL/TLS version"); + return CURLE_SSL_CONNECT_ERROR; + } + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_SSLv3: + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + failf(data, "MesaLink does not support SSL 3.0, TLS 1.0, or TLS 1.1"); + return CURLE_NOT_BUILT_IN; + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1_2: + req_method = TLSv1_2_client_method(); + break; + case CURL_SSLVERSION_TLSv1_3: + req_method = TLSv1_3_client_method(); + break; + case CURL_SSLVERSION_SSLv2: + failf(data, "MesaLink does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + if(!req_method) { + failf(data, "SSL: couldn't create a method!"); + return CURLE_OUT_OF_MEMORY; + } + + if(BACKEND->ctx) + SSL_CTX_free(BACKEND->ctx); + BACKEND->ctx = SSL_CTX_new(req_method); + + if(!BACKEND->ctx) { + failf(data, "SSL: couldn't create a context!"); + return CURLE_OUT_OF_MEMORY; + } + + SSL_CTX_set_verify( + BACKEND->ctx, verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); + + if(ssl_cafile || ssl_capath) { + if(!SSL_CTX_load_verify_locations(BACKEND->ctx, ssl_cafile, ssl_capath)) { + if(verifypeer) { + failf(data, + "error setting certificate verify locations:\n" + " CAfile: %s\n CApath: %s", + ssl_cafile ? ssl_cafile : "none", + ssl_capath ? ssl_capath : "none"); + return CURLE_SSL_CACERT_BADFILE; + } + infof(data, + "error setting certificate verify locations," + " continuing anyway:\n"); + } + else { + infof(data, "successfully set certificate verify locations:\n"); + } + infof(data, + " CAfile: %s\n" + " CApath: %s\n", + ssl_cafile ? ssl_cafile : "none", + ssl_capath ? ssl_capath : "none"); + } + + ciphers = SSL_CONN_CONFIG(cipher_list); + if(ciphers) { +#ifdef MESALINK_HAVE_CIPHER + if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) { + failf(data, "failed setting cipher list: %s", ciphers); + return CURLE_SSL_CIPHER; + } +#endif + infof(data, "Cipher selection: %s\n", ciphers); + } + + if(BACKEND->handle) + SSL_free(BACKEND->handle); + BACKEND->handle = SSL_new(BACKEND->ctx); + if(!BACKEND->handle) { + failf(data, "SSL: couldn't create a context (handle)!"); + return CURLE_OUT_OF_MEMORY; + } + + if((hostname_len < USHRT_MAX) && + (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) +#ifdef ENABLE_IPV6 + && (0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) +#endif + ) { + /* hostname is not a valid IP address */ + if(SSL_set_tlsext_host_name(BACKEND->handle, hostname) != SSL_SUCCESS) { + failf(data, + "WARNING: failed to configure server name indication (SNI) " + "TLS extension\n"); + return CURLE_SSL_CONNECT_ERROR; + } + } + else { +#ifdef CURLDEBUG + /* Check if the hostname is 127.0.0.1 or [::1]; + * otherwise reject because MesaLink always wants a valid DNS Name + * specified in RFC 5280 Section 7.2 */ + if(strncmp(hostname, "127.0.0.1", 9) == 0 +#ifdef ENABLE_IPV6 + || strncmp(hostname, "[::1]", 5) == 0 +#endif + ) { + SSL_set_tlsext_host_name(BACKEND->handle, "localhost"); + } + else +#endif + { + failf(data, + "ERROR: MesaLink does not accept an IP address as a hostname\n"); + return CURLE_SSL_CONNECT_ERROR; + } + } + +#ifdef MESALINK_HAVE_SESSION + if(SSL_SET_OPTION(primary.sessionid)) { + void *ssl_sessionid = NULL; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { + /* we got a session id, use it! */ + if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) { + Curl_ssl_sessionid_unlock(conn); + failf( + data, + "SSL: SSL_set_session failed: %s", + ERR_error_string(SSL_get_error(BACKEND->handle, 0), error_buffer)); + return CURLE_SSL_CONNECT_ERROR; + } + /* Informational message */ + infof(data, "SSL re-using session ID\n"); + } + Curl_ssl_sessionid_unlock(conn); + } +#endif /* MESALINK_HAVE_SESSION */ + + if(SSL_set_fd(BACKEND->handle, (int)sockfd) != SSL_SUCCESS) { + failf(data, "SSL: SSL_set_fd failed"); + return CURLE_SSL_CONNECT_ERROR; + } + + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; +} + +static CURLcode +mesalink_connect_step2(struct connectdata *conn, int sockindex) +{ + int ret = -1; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + conn->recv[sockindex] = mesalink_recv; + conn->send[sockindex] = mesalink_send; + + ret = SSL_connect(BACKEND->handle); + if(ret != SSL_SUCCESS) { + int detail = SSL_get_error(BACKEND->handle, ret); + + if(SSL_ERROR_WANT_CONNECT == detail || SSL_ERROR_WANT_READ == detail) { + connssl->connecting_state = ssl_connect_2_reading; + return CURLE_OK; + } + else { + char error_buffer[MESALINK_MAX_ERROR_SZ]; + failf(data, + "SSL_connect failed with error %d: %s", + detail, + ERR_error_string_n(detail, error_buffer, sizeof(error_buffer))); + ERR_print_errors_fp(stderr); + if(detail && SSL_CONN_CONFIG(verifypeer)) { + detail &= ~0xFF; + if(detail == TLS_ERROR_WEBPKI_ERRORS) { + failf(data, "Cert verify failed"); + return CURLE_PEER_FAILED_VERIFICATION; + } + } + return CURLE_SSL_CONNECT_ERROR; + } + } + + connssl->connecting_state = ssl_connect_3; + infof(data, + "SSL connection using %s / %s\n", + SSL_get_version(BACKEND->handle), + SSL_get_cipher_name(BACKEND->handle)); + + return CURLE_OK; +} + +static CURLcode +mesalink_connect_step3(struct connectdata *conn, int sockindex) +{ + CURLcode result = CURLE_OK; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); + +#ifdef MESALINK_HAVE_SESSION + if(SSL_SET_OPTION(primary.sessionid)) { + bool incache; + SSL_SESSION *our_ssl_sessionid; + void *old_ssl_sessionid = NULL; + + our_ssl_sessionid = SSL_get_session(BACKEND->handle); + + Curl_ssl_sessionid_lock(conn); + incache = + !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex)); + if(incache) { + if(old_ssl_sessionid != our_ssl_sessionid) { + infof(data, "old SSL session ID is stale, removing\n"); + Curl_ssl_delsessionid(conn, old_ssl_sessionid); + incache = FALSE; + } + } + + if(!incache) { + result = Curl_ssl_addsessionid( + conn, our_ssl_sessionid, 0 /* unknown size */, sockindex); + if(result) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "failed to store ssl session"); + return result; + } + } + Curl_ssl_sessionid_unlock(conn); + } +#endif /* MESALINK_HAVE_SESSION */ + + connssl->connecting_state = ssl_connect_done; + + return result; +} + +static ssize_t +mesalink_send(struct connectdata *conn, int sockindex, const void *mem, + size_t len, CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + char error_buffer[MESALINK_MAX_ERROR_SZ]; + int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; + int rc = SSL_write(BACKEND->handle, mem, memlen); + + if(rc < 0) { + int err = SSL_get_error(BACKEND->handle, rc); + switch(err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /* there's data pending, re-invoke SSL_write() */ + *curlcode = CURLE_AGAIN; + return -1; + default: + failf(conn->data, + "SSL write: %s, errno %d", + ERR_error_string_n(err, error_buffer, sizeof(error_buffer)), + SOCKERRNO); + *curlcode = CURLE_SEND_ERROR; + return -1; + } + } + return rc; +} + +static void +Curl_mesalink_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + if(BACKEND->handle) { + (void)SSL_shutdown(BACKEND->handle); + SSL_free(BACKEND->handle); + BACKEND->handle = NULL; + } + if(BACKEND->ctx) { + SSL_CTX_free(BACKEND->ctx); + BACKEND->ctx = NULL; + } +} + +static ssize_t +mesalink_recv(struct connectdata *conn, int num, char *buf, size_t buffersize, + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[num]; + char error_buffer[MESALINK_MAX_ERROR_SZ]; + int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; + int nread = SSL_read(BACKEND->handle, buf, buffsize); + + if(nread <= 0) { + int err = SSL_get_error(BACKEND->handle, nread); + + switch(err) { + case SSL_ERROR_ZERO_RETURN: /* no more data */ + case IO_ERROR_CONNECTION_ABORTED: + break; + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /* there's data pending, re-invoke SSL_read() */ + *curlcode = CURLE_AGAIN; + return -1; + default: + failf(conn->data, + "SSL read: %s, errno %d", + ERR_error_string_n(err, error_buffer, sizeof(error_buffer)), + SOCKERRNO); + *curlcode = CURLE_RECV_ERROR; + return -1; + } + } + return nread; +} + +static size_t +Curl_mesalink_version(char *buffer, size_t size) +{ + return msnprintf(buffer, size, "MesaLink/%s", MESALINK_VERSION_STRING); +} + +static int +Curl_mesalink_init(void) +{ + return (SSL_library_init() == SSL_SUCCESS); +} + +/* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) + */ +static int +Curl_mesalink_shutdown(struct connectdata *conn, int sockindex) +{ + int retval = 0; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + if(BACKEND->handle) { + SSL_free(BACKEND->handle); + BACKEND->handle = NULL; + } + return retval; +} + +static CURLcode +mesalink_connect_common(struct connectdata *conn, int sockindex, + bool nonblocking, bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + time_t timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + /* Find out how much more time we're allowed */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + result = mesalink_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading || + connssl->connecting_state == ssl_connect_2_writing) { + + curl_socket_t writefd = + ssl_connect_2_writing == connssl->connecting_state ? sockfd + : CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == connssl->connecting_state + ? sockfd + : CURL_SOCKET_BAD; + + what = Curl_socket_check( + readfd, CURL_SOCKET_BAD, writefd, nonblocking ? 0 : timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if + * this connection is part of a multi handle and this loop would + * execute again. This permits the owner of a multi handle to + * abort a connection attempt before step2 has completed while + * ensuring that a client using select() or epoll() will always + * have a valid fdset to wait on. + */ + result = mesalink_connect_step2(conn, sockindex); + + if(result || + (nonblocking && (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) { + return result; + } + } /* repeat step2 until all transactions are done. */ + + if(ssl_connect_3 == connssl->connecting_state) { + result = mesalink_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = mesalink_recv; + conn->send[sockindex] = mesalink_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +static CURLcode +Curl_mesalink_connect_nonblocking(struct connectdata *conn, int sockindex, + bool *done) +{ + return mesalink_connect_common(conn, sockindex, TRUE, done); +} + +static CURLcode +Curl_mesalink_connect(struct connectdata *conn, int sockindex) +{ + CURLcode result; + bool done = FALSE; + + result = mesalink_connect_common(conn, sockindex, FALSE, &done); + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +static void * +Curl_mesalink_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + (void)info; + return BACKEND->handle; +} + +const struct Curl_ssl Curl_ssl_mesalink = { + { CURLSSLBACKEND_MESALINK, "MesaLink" }, /* info */ + + SSLSUPP_SSL_CTX, + + sizeof(struct ssl_backend_data), + + Curl_mesalink_init, /* init */ + Curl_none_cleanup, /* cleanup */ + Curl_mesalink_version, /* version */ + Curl_none_check_cxn, /* check_cxn */ + Curl_mesalink_shutdown, /* shutdown */ + Curl_none_data_pending, /* data_pending */ + Curl_none_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_mesalink_connect, /* connect */ + Curl_mesalink_connect_nonblocking, /* connect_nonblocking */ + Curl_mesalink_get_internals, /* get_internals */ + Curl_mesalink_close, /* close_one */ + Curl_none_close_all, /* close_all */ + Curl_none_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_none_md5sum, /* md5sum */ + NULL /* sha256sum */ +}; + +#endif diff --git a/libcurl/lib/vtls/mesalink.h b/libcurl/lib/vtls/mesalink.h new file mode 100644 index 0000000..54cb94a --- /dev/null +++ b/libcurl/lib/vtls/mesalink.h @@ -0,0 +1,32 @@ +#ifndef HEADER_CURL_MESALINK_H +#define HEADER_CURL_MESALINK_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2017-2018, Yiming Jing, + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_MESALINK + +extern const struct Curl_ssl Curl_ssl_mesalink; + +#endif /* USE_MESALINK */ +#endif /* HEADER_CURL_MESALINK_H */ diff --git a/libcurl/lib/vtls/nss.c b/libcurl/lib/vtls/nss.c new file mode 100644 index 0000000..482fd5e --- /dev/null +++ b/libcurl/lib/vtls/nss.c @@ -0,0 +1,2452 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all NSS-specific code for the TLS/SSL layer. No code + * but vtls.c should ever call or use these functions. + */ + +#include "curl_setup.h" + +#ifdef USE_NSS + +#include "urldata.h" +#include "sendf.h" +#include "formdata.h" /* for the boundary function */ +#include "url.h" /* for the ssl config check function */ +#include "connect.h" +#include "strcase.h" +#include "select.h" +#include "vtls.h" +#include "llist.h" +#include "multiif.h" +#include "curl_printf.h" +#include "nssg.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for SECKEY_DestroyPublicKey() */ +#include /* for PR_ImportTCPSocket */ + +#define NSSVERNUM ((NSS_VMAJOR<<16)|(NSS_VMINOR<<8)|NSS_VPATCH) + +#if NSSVERNUM >= 0x030f00 /* 3.15.0 */ +#include +#endif + +#include "strcase.h" +#include "warnless.h" +#include "x509asn1.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +#define SSL_DIR "/etc/pki/nssdb" + +/* enough to fit the string "PEM Token #[0|1]" */ +#define SLOTSIZE 13 + +struct ssl_backend_data { + PRFileDesc *handle; + char *client_nickname; + struct Curl_easy *data; + struct curl_llist obj_list; + PK11GenericObject *obj_clicert; +}; + +#define BACKEND connssl->backend + +static PRLock *nss_initlock = NULL; +static PRLock *nss_crllock = NULL; +static PRLock *nss_findslot_lock = NULL; +static PRLock *nss_trustload_lock = NULL; +static struct curl_llist nss_crl_list; +static NSSInitContext *nss_context = NULL; +static volatile int initialized = 0; + +/* type used to wrap pointers as list nodes */ +struct ptr_list_wrap { + void *ptr; + struct curl_llist_element node; +}; + +typedef struct { + const char *name; + int num; +} cipher_s; + +#define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do { \ + CK_ATTRIBUTE *ptr = (_attr) + ((_idx)++); \ + ptr->type = (_type); \ + ptr->pValue = (_val); \ + ptr->ulValueLen = (_len); \ +} WHILE_FALSE + +#define CERT_NewTempCertificate __CERT_NewTempCertificate + +#define NUM_OF_CIPHERS sizeof(cipherlist)/sizeof(cipherlist[0]) +static const cipher_s cipherlist[] = { + /* SSL2 cipher suites */ + {"rc4", SSL_EN_RC4_128_WITH_MD5}, + {"rc4-md5", SSL_EN_RC4_128_WITH_MD5}, + {"rc4export", SSL_EN_RC4_128_EXPORT40_WITH_MD5}, + {"rc2", SSL_EN_RC2_128_CBC_WITH_MD5}, + {"rc2export", SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5}, + {"des", SSL_EN_DES_64_CBC_WITH_MD5}, + {"desede3", SSL_EN_DES_192_EDE3_CBC_WITH_MD5}, + /* SSL3/TLS cipher suites */ + {"rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5}, + {"rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA}, + {"rsa_3des_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA}, + {"rsa_des_sha", SSL_RSA_WITH_DES_CBC_SHA}, + {"rsa_rc4_40_md5", SSL_RSA_EXPORT_WITH_RC4_40_MD5}, + {"rsa_rc2_40_md5", SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5}, + {"rsa_null_md5", SSL_RSA_WITH_NULL_MD5}, + {"rsa_null_sha", SSL_RSA_WITH_NULL_SHA}, + {"fips_3des_sha", SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA}, + {"fips_des_sha", SSL_RSA_FIPS_WITH_DES_CBC_SHA}, + {"fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA}, + {"fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA}, + {"fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA}, + /* TLS 1.0: Exportable 56-bit Cipher Suites. */ + {"rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA}, + {"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA}, + /* AES ciphers. */ + {"dhe_dss_aes_128_cbc_sha", TLS_DHE_DSS_WITH_AES_128_CBC_SHA}, + {"dhe_dss_aes_256_cbc_sha", TLS_DHE_DSS_WITH_AES_256_CBC_SHA}, + {"dhe_rsa_aes_128_cbc_sha", TLS_DHE_RSA_WITH_AES_128_CBC_SHA}, + {"dhe_rsa_aes_256_cbc_sha", TLS_DHE_RSA_WITH_AES_256_CBC_SHA}, + {"rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA}, + {"rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA}, + /* ECC ciphers. */ + {"ecdh_ecdsa_null_sha", TLS_ECDH_ECDSA_WITH_NULL_SHA}, + {"ecdh_ecdsa_rc4_128_sha", TLS_ECDH_ECDSA_WITH_RC4_128_SHA}, + {"ecdh_ecdsa_3des_sha", TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA}, + {"ecdh_ecdsa_aes_128_sha", TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA}, + {"ecdh_ecdsa_aes_256_sha", TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA}, + {"ecdhe_ecdsa_null_sha", TLS_ECDHE_ECDSA_WITH_NULL_SHA}, + {"ecdhe_ecdsa_rc4_128_sha", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA}, + {"ecdhe_ecdsa_3des_sha", TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA}, + {"ecdhe_ecdsa_aes_128_sha", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA}, + {"ecdhe_ecdsa_aes_256_sha", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}, + {"ecdh_rsa_null_sha", TLS_ECDH_RSA_WITH_NULL_SHA}, + {"ecdh_rsa_128_sha", TLS_ECDH_RSA_WITH_RC4_128_SHA}, + {"ecdh_rsa_3des_sha", TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA}, + {"ecdh_rsa_aes_128_sha", TLS_ECDH_RSA_WITH_AES_128_CBC_SHA}, + {"ecdh_rsa_aes_256_sha", TLS_ECDH_RSA_WITH_AES_256_CBC_SHA}, + {"ecdhe_rsa_null", TLS_ECDHE_RSA_WITH_NULL_SHA}, + {"ecdhe_rsa_rc4_128_sha", TLS_ECDHE_RSA_WITH_RC4_128_SHA}, + {"ecdhe_rsa_3des_sha", TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA}, + {"ecdhe_rsa_aes_128_sha", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, + {"ecdhe_rsa_aes_256_sha", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, + {"ecdh_anon_null_sha", TLS_ECDH_anon_WITH_NULL_SHA}, + {"ecdh_anon_rc4_128sha", TLS_ECDH_anon_WITH_RC4_128_SHA}, + {"ecdh_anon_3des_sha", TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA}, + {"ecdh_anon_aes_128_sha", TLS_ECDH_anon_WITH_AES_128_CBC_SHA}, + {"ecdh_anon_aes_256_sha", TLS_ECDH_anon_WITH_AES_256_CBC_SHA}, +#ifdef TLS_RSA_WITH_NULL_SHA256 + /* new HMAC-SHA256 cipher suites specified in RFC */ + {"rsa_null_sha_256", TLS_RSA_WITH_NULL_SHA256}, + {"rsa_aes_128_cbc_sha_256", TLS_RSA_WITH_AES_128_CBC_SHA256}, + {"rsa_aes_256_cbc_sha_256", TLS_RSA_WITH_AES_256_CBC_SHA256}, + {"dhe_rsa_aes_128_cbc_sha_256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256}, + {"dhe_rsa_aes_256_cbc_sha_256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256}, + {"ecdhe_ecdsa_aes_128_cbc_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256}, + {"ecdhe_rsa_aes_128_cbc_sha_256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256}, +#endif +#ifdef TLS_RSA_WITH_AES_128_GCM_SHA256 + /* AES GCM cipher suites in RFC 5288 and RFC 5289 */ + {"rsa_aes_128_gcm_sha_256", TLS_RSA_WITH_AES_128_GCM_SHA256}, + {"dhe_rsa_aes_128_gcm_sha_256", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, + {"dhe_dss_aes_128_gcm_sha_256", TLS_DHE_DSS_WITH_AES_128_GCM_SHA256}, + {"ecdhe_ecdsa_aes_128_gcm_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + {"ecdh_ecdsa_aes_128_gcm_sha_256", TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256}, + {"ecdhe_rsa_aes_128_gcm_sha_256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + {"ecdh_rsa_aes_128_gcm_sha_256", TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256}, +#endif +#ifdef TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + /* cipher suites using SHA384 */ + {"rsa_aes_256_gcm_sha_384", TLS_RSA_WITH_AES_256_GCM_SHA384}, + {"dhe_rsa_aes_256_gcm_sha_384", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384}, + {"dhe_dss_aes_256_gcm_sha_384", TLS_DHE_DSS_WITH_AES_256_GCM_SHA384}, + {"ecdhe_ecdsa_aes_256_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384}, + {"ecdhe_rsa_aes_256_sha_384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384}, + {"ecdhe_ecdsa_aes_256_gcm_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}, + {"ecdhe_rsa_aes_256_gcm_sha_384", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, +#endif +#ifdef TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + /* chacha20-poly1305 cipher suites */ + {"ecdhe_rsa_chacha20_poly1305_sha_256", + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, + {"ecdhe_ecdsa_chacha20_poly1305_sha_256", + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, + {"dhe_rsa_chacha20_poly1305_sha_256", + TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, +#endif +#ifdef TLS_AES_256_GCM_SHA384 + {"aes_128_gcm_sha_256", TLS_AES_128_GCM_SHA256}, + {"aes_256_gcm_sha_384", TLS_AES_256_GCM_SHA384}, + {"chacha20_poly1305_sha_256", TLS_CHACHA20_POLY1305_SHA256}, +#endif +}; + +#if defined(WIN32) +static const char *pem_library = "nsspem.dll"; +static const char *trust_library = "nssckbi.dll"; +#elif defined(__APPLE__) +static const char *pem_library = "libnsspem.dylib"; +static const char *trust_library = "libnssckbi.dylib"; +#else +static const char *pem_library = "libnsspem.so"; +static const char *trust_library = "libnssckbi.so"; +#endif + +static SECMODModule *pem_module = NULL; +static SECMODModule *trust_module = NULL; + +/* NSPR I/O layer we use to detect blocking direction during SSL handshake */ +static PRDescIdentity nspr_io_identity = PR_INVALID_IO_LAYER; +static PRIOMethods nspr_io_methods; + +static const char *nss_error_to_name(PRErrorCode code) +{ + const char *name = PR_ErrorToName(code); + if(name) + return name; + + return "unknown error"; +} + +static void nss_print_error_message(struct Curl_easy *data, PRUint32 err) +{ + failf(data, "%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT)); +} + +static char *nss_sslver_to_name(PRUint16 nssver) +{ + switch(nssver) { + case SSL_LIBRARY_VERSION_2: + return strdup("SSLv2"); + case SSL_LIBRARY_VERSION_3_0: + return strdup("SSLv3"); + case SSL_LIBRARY_VERSION_TLS_1_0: + return strdup("TLSv1.0"); +#ifdef SSL_LIBRARY_VERSION_TLS_1_1 + case SSL_LIBRARY_VERSION_TLS_1_1: + return strdup("TLSv1.1"); +#endif +#ifdef SSL_LIBRARY_VERSION_TLS_1_2 + case SSL_LIBRARY_VERSION_TLS_1_2: + return strdup("TLSv1.2"); +#endif +#ifdef SSL_LIBRARY_VERSION_TLS_1_3 + case SSL_LIBRARY_VERSION_TLS_1_3: + return strdup("TLSv1.3"); +#endif + default: + return curl_maprintf("0x%04x", nssver); + } +} + +static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model, + char *cipher_list) +{ + unsigned int i; + PRBool cipher_state[NUM_OF_CIPHERS]; + PRBool found; + char *cipher; + + /* use accessors to avoid dynamic linking issues after an update of NSS */ + const PRUint16 num_implemented_ciphers = SSL_GetNumImplementedCiphers(); + const PRUint16 *implemented_ciphers = SSL_GetImplementedCiphers(); + if(!implemented_ciphers) + return SECFailure; + + /* First disable all ciphers. This uses a different max value in case + * NSS adds more ciphers later we don't want them available by + * accident + */ + for(i = 0; i < num_implemented_ciphers; i++) { + SSL_CipherPrefSet(model, implemented_ciphers[i], PR_FALSE); + } + + /* Set every entry in our list to false */ + for(i = 0; i < NUM_OF_CIPHERS; i++) { + cipher_state[i] = PR_FALSE; + } + + cipher = cipher_list; + + while(cipher_list && (cipher_list[0])) { + while((*cipher) && (ISSPACE(*cipher))) + ++cipher; + + cipher_list = strchr(cipher, ','); + if(cipher_list) { + *cipher_list++ = '\0'; + } + + found = PR_FALSE; + + for(i = 0; i. + */ +static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name) +{ + PK11SlotInfo *slot; + PR_Lock(nss_findslot_lock); + slot = PK11_FindSlotByName(slot_name); + PR_Unlock(nss_findslot_lock); + return slot; +} + +/* wrap 'ptr' as list node and tail-insert into 'list' */ +static CURLcode insert_wrapped_ptr(struct curl_llist *list, void *ptr) +{ + struct ptr_list_wrap *wrap = malloc(sizeof(*wrap)); + if(!wrap) + return CURLE_OUT_OF_MEMORY; + + wrap->ptr = ptr; + Curl_llist_insert_next(list, list->tail, wrap, &wrap->node); + return CURLE_OK; +} + +/* Call PK11_CreateGenericObject() with the given obj_class and filename. If + * the call succeeds, append the object handle to the list of objects so that + * the object can be destroyed in Curl_nss_close(). */ +static CURLcode nss_create_object(struct ssl_connect_data *connssl, + CK_OBJECT_CLASS obj_class, + const char *filename, bool cacert) +{ + PK11SlotInfo *slot; + PK11GenericObject *obj; + CK_BBOOL cktrue = CK_TRUE; + CK_BBOOL ckfalse = CK_FALSE; + CK_ATTRIBUTE attrs[/* max count of attributes */ 4]; + int attr_cnt = 0; + CURLcode result = (cacert) + ? CURLE_SSL_CACERT_BADFILE + : CURLE_SSL_CERTPROBLEM; + + const int slot_id = (cacert) ? 0 : 1; + char *slot_name = aprintf("PEM Token #%d", slot_id); + if(!slot_name) + return CURLE_OUT_OF_MEMORY; + + slot = nss_find_slot_by_name(slot_name); + free(slot_name); + if(!slot) + return result; + + PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class, sizeof(obj_class)); + PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); + PK11_SETATTRS(attrs, attr_cnt, CKA_LABEL, (unsigned char *)filename, + (CK_ULONG)strlen(filename) + 1); + + if(CKO_CERTIFICATE == obj_class) { + CK_BBOOL *pval = (cacert) ? (&cktrue) : (&ckfalse); + PK11_SETATTRS(attrs, attr_cnt, CKA_TRUST, pval, sizeof(*pval)); + } + + /* PK11_CreateManagedGenericObject() was introduced in NSS 3.34 because + * PK11_DestroyGenericObject() does not release resources allocated by + * PK11_CreateGenericObject() early enough. */ + obj = +#ifdef HAVE_PK11_CREATEMANAGEDGENERICOBJECT + PK11_CreateManagedGenericObject +#else + PK11_CreateGenericObject +#endif + (slot, attrs, attr_cnt, PR_FALSE); + + PK11_FreeSlot(slot); + if(!obj) + return result; + + if(insert_wrapped_ptr(&BACKEND->obj_list, obj) != CURLE_OK) { + PK11_DestroyGenericObject(obj); + return CURLE_OUT_OF_MEMORY; + } + + if(!cacert && CKO_CERTIFICATE == obj_class) + /* store reference to a client certificate */ + BACKEND->obj_clicert = obj; + + return CURLE_OK; +} + +/* Destroy the NSS object whose handle is given by ptr. This function is + * a callback of Curl_llist_alloc() used by Curl_llist_destroy() to destroy + * NSS objects in Curl_nss_close() */ +static void nss_destroy_object(void *user, void *ptr) +{ + struct ptr_list_wrap *wrap = (struct ptr_list_wrap *) ptr; + PK11GenericObject *obj = (PK11GenericObject *) wrap->ptr; + (void) user; + PK11_DestroyGenericObject(obj); + free(wrap); +} + +/* same as nss_destroy_object() but for CRL items */ +static void nss_destroy_crl_item(void *user, void *ptr) +{ + struct ptr_list_wrap *wrap = (struct ptr_list_wrap *) ptr; + SECItem *crl_der = (SECItem *) wrap->ptr; + (void) user; + SECITEM_FreeItem(crl_der, PR_TRUE); + free(wrap); +} + +static CURLcode nss_load_cert(struct ssl_connect_data *ssl, + const char *filename, PRBool cacert) +{ + CURLcode result = (cacert) + ? CURLE_SSL_CACERT_BADFILE + : CURLE_SSL_CERTPROBLEM; + + /* libnsspem.so leaks memory if the requested file does not exist. For more + * details, go to . */ + if(is_file(filename)) + result = nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert); + + if(!result && !cacert) { + /* we have successfully loaded a client certificate */ + CERTCertificate *cert; + char *nickname = NULL; + char *n = strrchr(filename, '/'); + if(n) + n++; + + /* The following undocumented magic helps to avoid a SIGSEGV on call + * of PK11_ReadRawAttribute() from SelectClientCert() when using an + * immature version of libnsspem.so. For more details, go to + * . */ + nickname = aprintf("PEM Token #1:%s", n); + if(nickname) { + cert = PK11_FindCertFromNickname(nickname, NULL); + if(cert) + CERT_DestroyCertificate(cert); + + free(nickname); + } + } + + return result; +} + +/* add given CRL to cache if it is not already there */ +static CURLcode nss_cache_crl(SECItem *crl_der) +{ + CERTCertDBHandle *db = CERT_GetDefaultCertDB(); + CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0); + if(crl) { + /* CRL already cached */ + SEC_DestroyCrl(crl); + SECITEM_FreeItem(crl_der, PR_TRUE); + return CURLE_OK; + } + + /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */ + PR_Lock(nss_crllock); + + if(SECSuccess != CERT_CacheCRL(db, crl_der)) { + /* unable to cache CRL */ + SECITEM_FreeItem(crl_der, PR_TRUE); + PR_Unlock(nss_crllock); + return CURLE_SSL_CRL_BADFILE; + } + + /* store the CRL item so that we can free it in Curl_nss_cleanup() */ + if(insert_wrapped_ptr(&nss_crl_list, crl_der) != CURLE_OK) { + if(SECSuccess == CERT_UncacheCRL(db, crl_der)) + SECITEM_FreeItem(crl_der, PR_TRUE); + PR_Unlock(nss_crllock); + return CURLE_OUT_OF_MEMORY; + } + + /* we need to clear session cache, so that the CRL could take effect */ + SSL_ClearSessionCache(); + PR_Unlock(nss_crllock); + return CURLE_OK; +} + +static CURLcode nss_load_crl(const char *crlfilename) +{ + PRFileDesc *infile; + PRFileInfo info; + SECItem filedata = { 0, NULL, 0 }; + SECItem *crl_der = NULL; + char *body; + + infile = PR_Open(crlfilename, PR_RDONLY, 0); + if(!infile) + return CURLE_SSL_CRL_BADFILE; + + if(PR_SUCCESS != PR_GetOpenFileInfo(infile, &info)) + goto fail; + + if(!SECITEM_AllocItem(NULL, &filedata, info.size + /* zero ended */ 1)) + goto fail; + + if(info.size != PR_Read(infile, filedata.data, info.size)) + goto fail; + + crl_der = SECITEM_AllocItem(NULL, NULL, 0U); + if(!crl_der) + goto fail; + + /* place a trailing zero right after the visible data */ + body = (char *)filedata.data; + body[--filedata.len] = '\0'; + + body = strstr(body, "-----BEGIN"); + if(body) { + /* assume ASCII */ + char *trailer; + char *begin = PORT_Strchr(body, '\n'); + if(!begin) + begin = PORT_Strchr(body, '\r'); + if(!begin) + goto fail; + + trailer = strstr(++begin, "-----END"); + if(!trailer) + goto fail; + + /* retrieve DER from ASCII */ + *trailer = '\0'; + if(ATOB_ConvertAsciiToItem(crl_der, begin)) + goto fail; + + SECITEM_FreeItem(&filedata, PR_FALSE); + } + else + /* assume DER */ + *crl_der = filedata; + + PR_Close(infile); + return nss_cache_crl(crl_der); + +fail: + PR_Close(infile); + SECITEM_FreeItem(crl_der, PR_TRUE); + SECITEM_FreeItem(&filedata, PR_FALSE); + return CURLE_SSL_CRL_BADFILE; +} + +static CURLcode nss_load_key(struct connectdata *conn, int sockindex, + char *key_file) +{ + PK11SlotInfo *slot, *tmp; + SECStatus status; + CURLcode result; + struct ssl_connect_data *ssl = conn->ssl; + struct Curl_easy *data = conn->data; + + (void)sockindex; /* unused */ + + result = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE); + if(result) { + PR_SetError(SEC_ERROR_BAD_KEY, 0); + return result; + } + + slot = nss_find_slot_by_name("PEM Token #1"); + if(!slot) + return CURLE_SSL_CERTPROBLEM; + + /* This will force the token to be seen as re-inserted */ + tmp = SECMOD_WaitForAnyTokenEvent(pem_module, 0, 0); + if(tmp) + PK11_FreeSlot(tmp); + if(!PK11_IsPresent(slot)) { + PK11_FreeSlot(slot); + return CURLE_SSL_CERTPROBLEM; + } + + status = PK11_Authenticate(slot, PR_TRUE, SSL_SET_OPTION(key_passwd)); + PK11_FreeSlot(slot); + + return (SECSuccess == status) ? CURLE_OK : CURLE_SSL_CERTPROBLEM; +} + +static int display_error(struct connectdata *conn, PRInt32 err, + const char *filename) +{ + switch(err) { + case SEC_ERROR_BAD_PASSWORD: + failf(conn->data, "Unable to load client key: Incorrect password"); + return 1; + case SEC_ERROR_UNKNOWN_CERT: + failf(conn->data, "Unable to load certificate %s", filename); + return 1; + default: + break; + } + return 0; /* The caller will print a generic error */ +} + +static CURLcode cert_stuff(struct connectdata *conn, int sockindex, + char *cert_file, char *key_file) +{ + struct Curl_easy *data = conn->data; + CURLcode result; + + if(cert_file) { + result = nss_load_cert(&conn->ssl[sockindex], cert_file, PR_FALSE); + if(result) { + const PRErrorCode err = PR_GetError(); + if(!display_error(conn, err, cert_file)) { + const char *err_name = nss_error_to_name(err); + failf(data, "unable to load client cert: %d (%s)", err, err_name); + } + + return result; + } + } + + if(key_file || (is_file(cert_file))) { + if(key_file) + result = nss_load_key(conn, sockindex, key_file); + else + /* In case the cert file also has the key */ + result = nss_load_key(conn, sockindex, cert_file); + if(result) { + const PRErrorCode err = PR_GetError(); + if(!display_error(conn, err, key_file)) { + const char *err_name = nss_error_to_name(err); + failf(data, "unable to load client key: %d (%s)", err, err_name); + } + + return result; + } + } + + return CURLE_OK; +} + +static char *nss_get_password(PK11SlotInfo *slot, PRBool retry, void *arg) +{ + (void)slot; /* unused */ + + if(retry || NULL == arg) + return NULL; + else + return (char *)PORT_Strdup((char *)arg); +} + +/* bypass the default SSL_AuthCertificate() hook in case we do not want to + * verify peer */ +static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig, + PRBool isServer) +{ + struct connectdata *conn = (struct connectdata *)arg; + +#ifdef SSL_ENABLE_OCSP_STAPLING + if(SSL_CONN_CONFIG(verifystatus)) { + SECStatus cacheResult; + + const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd); + if(!csa) { + failf(conn->data, "Invalid OCSP response"); + return SECFailure; + } + + if(csa->len == 0) { + failf(conn->data, "No OCSP response received"); + return SECFailure; + } + + cacheResult = CERT_CacheOCSPResponseFromSideChannel( + CERT_GetDefaultCertDB(), SSL_PeerCertificate(fd), + PR_Now(), &csa->items[0], arg + ); + + if(cacheResult != SECSuccess) { + failf(conn->data, "Invalid OCSP response"); + return cacheResult; + } + } +#endif + + if(!SSL_CONN_CONFIG(verifypeer)) { + infof(conn->data, "skipping SSL peer certificate verification\n"); + return SECSuccess; + } + + return SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer); +} + +/** + * Inform the application that the handshake is complete. + */ +static void HandshakeCallback(PRFileDesc *sock, void *arg) +{ + struct connectdata *conn = (struct connectdata*) arg; + unsigned int buflenmax = 50; + unsigned char buf[50]; + unsigned int buflen; + SSLNextProtoState state; + + if(!conn->bits.tls_enable_npn && !conn->bits.tls_enable_alpn) { + return; + } + + if(SSL_GetNextProto(sock, &state, buf, &buflen, buflenmax) == SECSuccess) { + + switch(state) { +#if NSSVERNUM >= 0x031a00 /* 3.26.0 */ + /* used by NSS internally to implement 0-RTT */ + case SSL_NEXT_PROTO_EARLY_VALUE: + /* fall through! */ +#endif + case SSL_NEXT_PROTO_NO_SUPPORT: + case SSL_NEXT_PROTO_NO_OVERLAP: + infof(conn->data, "ALPN/NPN, server did not agree to a protocol\n"); + return; +#ifdef SSL_ENABLE_ALPN + case SSL_NEXT_PROTO_SELECTED: + infof(conn->data, "ALPN, server accepted to use %.*s\n", buflen, buf); + break; +#endif + case SSL_NEXT_PROTO_NEGOTIATED: + infof(conn->data, "NPN, server accepted to use %.*s\n", buflen, buf); + break; + } + +#ifdef USE_NGHTTP2 + if(buflen == NGHTTP2_PROTO_VERSION_ID_LEN && + !memcmp(NGHTTP2_PROTO_VERSION_ID, buf, NGHTTP2_PROTO_VERSION_ID_LEN)) { + conn->negnpn = CURL_HTTP_VERSION_2; + } + else +#endif + if(buflen == ALPN_HTTP_1_1_LENGTH && + !memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) { + conn->negnpn = CURL_HTTP_VERSION_1_1; + } + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + } +} + +#if NSSVERNUM >= 0x030f04 /* 3.15.4 */ +static SECStatus CanFalseStartCallback(PRFileDesc *sock, void *client_data, + PRBool *canFalseStart) +{ + struct connectdata *conn = client_data; + struct Curl_easy *data = conn->data; + + SSLChannelInfo channelInfo; + SSLCipherSuiteInfo cipherInfo; + + SECStatus rv; + PRBool negotiatedExtension; + + *canFalseStart = PR_FALSE; + + if(SSL_GetChannelInfo(sock, &channelInfo, sizeof(channelInfo)) != SECSuccess) + return SECFailure; + + if(SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo, + sizeof(cipherInfo)) != SECSuccess) + return SECFailure; + + /* Prevent version downgrade attacks from TLS 1.2, and avoid False Start for + * TLS 1.3 and later. See https://bugzilla.mozilla.org/show_bug.cgi?id=861310 + */ + if(channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_2) + goto end; + + /* Only allow ECDHE key exchange algorithm. + * See https://bugzilla.mozilla.org/show_bug.cgi?id=952863 */ + if(cipherInfo.keaType != ssl_kea_ecdh) + goto end; + + /* Prevent downgrade attacks on the symmetric cipher. We do not allow CBC + * mode due to BEAST, POODLE, and other attacks on the MAC-then-Encrypt + * design. See https://bugzilla.mozilla.org/show_bug.cgi?id=1109766 */ + if(cipherInfo.symCipher != ssl_calg_aes_gcm) + goto end; + + /* Enforce ALPN or NPN to do False Start, as an indicator of server + * compatibility. */ + rv = SSL_HandshakeNegotiatedExtension(sock, ssl_app_layer_protocol_xtn, + &negotiatedExtension); + if(rv != SECSuccess || !negotiatedExtension) { + rv = SSL_HandshakeNegotiatedExtension(sock, ssl_next_proto_nego_xtn, + &negotiatedExtension); + } + + if(rv != SECSuccess || !negotiatedExtension) + goto end; + + *canFalseStart = PR_TRUE; + + infof(data, "Trying TLS False Start\n"); + +end: + return SECSuccess; +} +#endif + +static void display_cert_info(struct Curl_easy *data, + CERTCertificate *cert) +{ + char *subject, *issuer, *common_name; + PRExplodedTime printableTime; + char timeString[256]; + PRTime notBefore, notAfter; + + subject = CERT_NameToAscii(&cert->subject); + issuer = CERT_NameToAscii(&cert->issuer); + common_name = CERT_GetCommonName(&cert->subject); + infof(data, "\tsubject: %s\n", subject); + + CERT_GetCertTimes(cert, ¬Before, ¬After); + PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime); + PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime); + infof(data, "\tstart date: %s\n", timeString); + PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime); + PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime); + infof(data, "\texpire date: %s\n", timeString); + infof(data, "\tcommon name: %s\n", common_name); + infof(data, "\tissuer: %s\n", issuer); + + PR_Free(subject); + PR_Free(issuer); + PR_Free(common_name); +} + +static CURLcode display_conn_info(struct connectdata *conn, PRFileDesc *sock) +{ + CURLcode result = CURLE_OK; + SSLChannelInfo channel; + SSLCipherSuiteInfo suite; + CERTCertificate *cert; + CERTCertificate *cert2; + CERTCertificate *cert3; + PRTime now; + int i; + + if(SSL_GetChannelInfo(sock, &channel, sizeof(channel)) == + SECSuccess && channel.length == sizeof(channel) && + channel.cipherSuite) { + if(SSL_GetCipherSuiteInfo(channel.cipherSuite, + &suite, sizeof(suite)) == SECSuccess) { + infof(conn->data, "SSL connection using %s\n", suite.cipherSuiteName); + } + } + + cert = SSL_PeerCertificate(sock); + if(cert) { + infof(conn->data, "Server certificate:\n"); + + if(!conn->data->set.ssl.certinfo) { + display_cert_info(conn->data, cert); + CERT_DestroyCertificate(cert); + } + else { + /* Count certificates in chain. */ + now = PR_Now(); + i = 1; + if(!cert->isRoot) { + cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA); + while(cert2) { + i++; + if(cert2->isRoot) { + CERT_DestroyCertificate(cert2); + break; + } + cert3 = CERT_FindCertIssuer(cert2, now, certUsageSSLCA); + CERT_DestroyCertificate(cert2); + cert2 = cert3; + } + } + + result = Curl_ssl_init_certinfo(conn->data, i); + if(!result) { + for(i = 0; cert; cert = cert2) { + result = Curl_extract_certinfo(conn, i++, (char *)cert->derCert.data, + (char *)cert->derCert.data + + cert->derCert.len); + if(result) + break; + + if(cert->isRoot) { + CERT_DestroyCertificate(cert); + break; + } + + cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA); + CERT_DestroyCertificate(cert); + } + } + } + } + + return result; +} + +static SECStatus BadCertHandler(void *arg, PRFileDesc *sock) +{ + struct connectdata *conn = (struct connectdata *)arg; + struct Curl_easy *data = conn->data; + PRErrorCode err = PR_GetError(); + CERTCertificate *cert; + + /* remember the cert verification result */ + if(SSL_IS_PROXY()) + data->set.proxy_ssl.certverifyresult = err; + else + data->set.ssl.certverifyresult = err; + + if(err == SSL_ERROR_BAD_CERT_DOMAIN && !SSL_CONN_CONFIG(verifyhost)) + /* we are asked not to verify the host name */ + return SECSuccess; + + /* print only info about the cert, the error is printed off the callback */ + cert = SSL_PeerCertificate(sock); + if(cert) { + infof(data, "Server certificate:\n"); + display_cert_info(data, cert); + CERT_DestroyCertificate(cert); + } + + return SECFailure; +} + +/** + * + * Check that the Peer certificate's issuer certificate matches the one found + * by issuer_nickname. This is not exactly the way OpenSSL and GNU TLS do the + * issuer check, so we provide comments that mimic the OpenSSL + * X509_check_issued function (in x509v3/v3_purp.c) + */ +static SECStatus check_issuer_cert(PRFileDesc *sock, + char *issuer_nickname) +{ + CERTCertificate *cert, *cert_issuer, *issuer; + SECStatus res = SECSuccess; + void *proto_win = NULL; + + cert = SSL_PeerCertificate(sock); + cert_issuer = CERT_FindCertIssuer(cert, PR_Now(), certUsageObjectSigner); + + proto_win = SSL_RevealPinArg(sock); + issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win); + + if((!cert_issuer) || (!issuer)) + res = SECFailure; + else if(SECITEM_CompareItem(&cert_issuer->derCert, + &issuer->derCert) != SECEqual) + res = SECFailure; + + CERT_DestroyCertificate(cert); + CERT_DestroyCertificate(issuer); + CERT_DestroyCertificate(cert_issuer); + return res; +} + +static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl, + const char *pinnedpubkey) +{ + CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + struct Curl_easy *data = BACKEND->data; + CERTCertificate *cert; + + if(!pinnedpubkey) + /* no pinned public key specified */ + return CURLE_OK; + + /* get peer certificate */ + cert = SSL_PeerCertificate(BACKEND->handle); + if(cert) { + /* extract public key from peer certificate */ + SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert); + if(pubkey) { + /* encode the public key as DER */ + SECItem *cert_der = PK11_DEREncodePublicKey(pubkey); + if(cert_der) { + /* compare the public key with the pinned public key */ + result = Curl_pin_peer_pubkey(data, pinnedpubkey, cert_der->data, + cert_der->len); + SECITEM_FreeItem(cert_der, PR_TRUE); + } + SECKEY_DestroyPublicKey(pubkey); + } + CERT_DestroyCertificate(cert); + } + + /* report the resulting status */ + switch(result) { + case CURLE_OK: + infof(data, "pinned public key verified successfully!\n"); + break; + case CURLE_SSL_PINNEDPUBKEYNOTMATCH: + failf(data, "failed to verify pinned public key"); + break; + default: + /* OOM, etc. */ + break; + } + + return result; +} + +/** + * + * Callback to pick the SSL client certificate. + */ +static SECStatus SelectClientCert(void *arg, PRFileDesc *sock, + struct CERTDistNamesStr *caNames, + struct CERTCertificateStr **pRetCert, + struct SECKEYPrivateKeyStr **pRetKey) +{ + struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg; + struct Curl_easy *data = BACKEND->data; + const char *nickname = BACKEND->client_nickname; + static const char pem_slotname[] = "PEM Token #1"; + + if(BACKEND->obj_clicert) { + /* use the cert/key provided by PEM reader */ + SECItem cert_der = { 0, NULL, 0 }; + void *proto_win = SSL_RevealPinArg(sock); + struct CERTCertificateStr *cert; + struct SECKEYPrivateKeyStr *key; + + PK11SlotInfo *slot = nss_find_slot_by_name(pem_slotname); + if(NULL == slot) { + failf(data, "NSS: PK11 slot not found: %s", pem_slotname); + return SECFailure; + } + + if(PK11_ReadRawAttribute(PK11_TypeGeneric, BACKEND->obj_clicert, CKA_VALUE, + &cert_der) != SECSuccess) { + failf(data, "NSS: CKA_VALUE not found in PK11 generic object"); + PK11_FreeSlot(slot); + return SECFailure; + } + + cert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win); + SECITEM_FreeItem(&cert_der, PR_FALSE); + if(NULL == cert) { + failf(data, "NSS: client certificate from file not found"); + PK11_FreeSlot(slot); + return SECFailure; + } + + key = PK11_FindPrivateKeyFromCert(slot, cert, NULL); + PK11_FreeSlot(slot); + if(NULL == key) { + failf(data, "NSS: private key from file not found"); + CERT_DestroyCertificate(cert); + return SECFailure; + } + + infof(data, "NSS: client certificate from file\n"); + display_cert_info(data, cert); + + *pRetCert = cert; + *pRetKey = key; + return SECSuccess; + } + + /* use the default NSS hook */ + if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames, + pRetCert, pRetKey) + || NULL == *pRetCert) { + + if(NULL == nickname) + failf(data, "NSS: client certificate not found (nickname not " + "specified)"); + else + failf(data, "NSS: client certificate not found: %s", nickname); + + return SECFailure; + } + + /* get certificate nickname if any */ + nickname = (*pRetCert)->nickname; + if(NULL == nickname) + nickname = "[unknown]"; + + if(!strncmp(nickname, pem_slotname, sizeof(pem_slotname) - 1U)) { + failf(data, "NSS: refusing previously loaded certificate from file: %s", + nickname); + return SECFailure; + } + + if(NULL == *pRetKey) { + failf(data, "NSS: private key not found for certificate: %s", nickname); + return SECFailure; + } + + infof(data, "NSS: using client certificate: %s\n", nickname); + display_cert_info(data, *pRetCert); + return SECSuccess; +} + +/* update blocking direction in case of PR_WOULD_BLOCK_ERROR */ +static void nss_update_connecting_state(ssl_connect_state state, void *secret) +{ + struct ssl_connect_data *connssl = (struct ssl_connect_data *)secret; + if(PR_GetError() != PR_WOULD_BLOCK_ERROR) + /* an unrelated error is passing by */ + return; + + switch(connssl->connecting_state) { + case ssl_connect_2: + case ssl_connect_2_reading: + case ssl_connect_2_writing: + break; + default: + /* we are not called from an SSL handshake */ + return; + } + + /* update the state accordingly */ + connssl->connecting_state = state; +} + +/* recv() wrapper we use to detect blocking direction during SSL handshake */ +static PRInt32 nspr_io_recv(PRFileDesc *fd, void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout) +{ + const PRRecvFN recv_fn = fd->lower->methods->recv; + const PRInt32 rv = recv_fn(fd->lower, buf, amount, flags, timeout); + if(rv < 0) + /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */ + nss_update_connecting_state(ssl_connect_2_reading, fd->secret); + return rv; +} + +/* send() wrapper we use to detect blocking direction during SSL handshake */ +static PRInt32 nspr_io_send(PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, PRIntervalTime timeout) +{ + const PRSendFN send_fn = fd->lower->methods->send; + const PRInt32 rv = send_fn(fd->lower, buf, amount, flags, timeout); + if(rv < 0) + /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */ + nss_update_connecting_state(ssl_connect_2_writing, fd->secret); + return rv; +} + +/* close() wrapper to avoid assertion failure due to fd->secret != NULL */ +static PRStatus nspr_io_close(PRFileDesc *fd) +{ + const PRCloseFN close_fn = PR_GetDefaultIOMethods()->close; + fd->secret = NULL; + return close_fn(fd); +} + +/* load a PKCS #11 module */ +static CURLcode nss_load_module(SECMODModule **pmod, const char *library, + const char *name) +{ + char *config_string; + SECMODModule *module = *pmod; + if(module) + /* already loaded */ + return CURLE_OK; + + config_string = aprintf("library=%s name=%s", library, name); + if(!config_string) + return CURLE_OUT_OF_MEMORY; + + module = SECMOD_LoadUserModule(config_string, NULL, PR_FALSE); + free(config_string); + + if(module && module->loaded) { + /* loaded successfully */ + *pmod = module; + return CURLE_OK; + } + + if(module) + SECMOD_DestroyModule(module); + return CURLE_FAILED_INIT; +} + +/* unload a PKCS #11 module */ +static void nss_unload_module(SECMODModule **pmod) +{ + SECMODModule *module = *pmod; + if(!module) + /* not loaded */ + return; + + if(SECMOD_UnloadUserModule(module) != SECSuccess) + /* unload failed */ + return; + + SECMOD_DestroyModule(module); + *pmod = NULL; +} + +/* data might be NULL */ +static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir) +{ + NSSInitParameters initparams; + PRErrorCode err; + const char *err_name; + + if(nss_context != NULL) + return CURLE_OK; + + memset((void *) &initparams, '\0', sizeof(initparams)); + initparams.length = sizeof(initparams); + + if(cert_dir) { + char *certpath = aprintf("sql:%s", cert_dir); + if(!certpath) + return CURLE_OUT_OF_MEMORY; + + infof(data, "Initializing NSS with certpath: %s\n", certpath); + nss_context = NSS_InitContext(certpath, "", "", "", &initparams, + NSS_INIT_READONLY | NSS_INIT_PK11RELOAD); + free(certpath); + + if(nss_context != NULL) + return CURLE_OK; + + err = PR_GetError(); + err_name = nss_error_to_name(err); + infof(data, "Unable to initialize NSS database: %d (%s)\n", err, err_name); + } + + infof(data, "Initializing NSS with certpath: none\n"); + nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY + | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN + | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD); + if(nss_context != NULL) + return CURLE_OK; + + err = PR_GetError(); + err_name = nss_error_to_name(err); + failf(data, "Unable to initialize NSS: %d (%s)", err, err_name); + return CURLE_SSL_CACERT_BADFILE; +} + +/* data might be NULL */ +static CURLcode nss_init(struct Curl_easy *data) +{ + char *cert_dir; + struct_stat st; + CURLcode result; + + if(initialized) + return CURLE_OK; + + /* list of all CRL items we need to destroy in Curl_nss_cleanup() */ + Curl_llist_init(&nss_crl_list, nss_destroy_crl_item); + + /* First we check if $SSL_DIR points to a valid dir */ + cert_dir = getenv("SSL_DIR"); + if(cert_dir) { + if((stat(cert_dir, &st) != 0) || + (!S_ISDIR(st.st_mode))) { + cert_dir = NULL; + } + } + + /* Now we check if the default location is a valid dir */ + if(!cert_dir) { + if((stat(SSL_DIR, &st) == 0) && + (S_ISDIR(st.st_mode))) { + cert_dir = (char *)SSL_DIR; + } + } + + if(nspr_io_identity == PR_INVALID_IO_LAYER) { + /* allocate an identity for our own NSPR I/O layer */ + nspr_io_identity = PR_GetUniqueIdentity("libcurl"); + if(nspr_io_identity == PR_INVALID_IO_LAYER) + return CURLE_OUT_OF_MEMORY; + + /* the default methods just call down to the lower I/O layer */ + memcpy(&nspr_io_methods, PR_GetDefaultIOMethods(), + sizeof(nspr_io_methods)); + + /* override certain methods in the table by our wrappers */ + nspr_io_methods.recv = nspr_io_recv; + nspr_io_methods.send = nspr_io_send; + nspr_io_methods.close = nspr_io_close; + } + + result = nss_init_core(data, cert_dir); + if(result) + return result; + + if(!any_cipher_enabled()) + NSS_SetDomesticPolicy(); + + initialized = 1; + + return CURLE_OK; +} + +/** + * Global SSL init + * + * @retval 0 error initializing SSL + * @retval 1 SSL initialized successfully + */ +static int Curl_nss_init(void) +{ + /* curl_global_init() is not thread-safe so this test is ok */ + if(nss_initlock == NULL) { + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + nss_initlock = PR_NewLock(); + nss_crllock = PR_NewLock(); + nss_findslot_lock = PR_NewLock(); + nss_trustload_lock = PR_NewLock(); + } + + /* We will actually initialize NSS later */ + + return 1; +} + +/* data might be NULL */ +CURLcode Curl_nss_force_init(struct Curl_easy *data) +{ + CURLcode result; + if(!nss_initlock) { + if(data) + failf(data, "unable to initialize NSS, curl_global_init() should have " + "been called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL"); + return CURLE_FAILED_INIT; + } + + PR_Lock(nss_initlock); + result = nss_init(data); + PR_Unlock(nss_initlock); + + return result; +} + +/* Global cleanup */ +static void Curl_nss_cleanup(void) +{ + /* This function isn't required to be threadsafe and this is only done + * as a safety feature. + */ + PR_Lock(nss_initlock); + if(initialized) { + /* Free references to client certificates held in the SSL session cache. + * Omitting this hampers destruction of the security module owning + * the certificates. */ + SSL_ClearSessionCache(); + + nss_unload_module(&pem_module); + nss_unload_module(&trust_module); + NSS_ShutdownContext(nss_context); + nss_context = NULL; + } + + /* destroy all CRL items */ + Curl_llist_destroy(&nss_crl_list, NULL); + + PR_Unlock(nss_initlock); + + PR_DestroyLock(nss_initlock); + PR_DestroyLock(nss_crllock); + PR_DestroyLock(nss_findslot_lock); + PR_DestroyLock(nss_trustload_lock); + nss_initlock = NULL; + + initialized = 0; +} + +/* + * This function uses SSL_peek to determine connection status. + * + * Return codes: + * 1 means the connection is still in place + * 0 means the connection has been closed + * -1 means the connection status is unknown + */ +static int Curl_nss_check_cxn(struct connectdata *conn) +{ + struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; + int rc; + char buf; + + rc = + PR_Recv(BACKEND->handle, (void *)&buf, 1, PR_MSG_PEEK, + PR_SecondsToInterval(1)); + if(rc > 0) + return 1; /* connection still in place */ + + if(rc == 0) + return 0; /* connection has been closed */ + + return -1; /* connection status unknown */ +} + +static void nss_close(struct ssl_connect_data *connssl) +{ + /* before the cleanup, check whether we are using a client certificate */ + const bool client_cert = (BACKEND->client_nickname != NULL) + || (BACKEND->obj_clicert != NULL); + + free(BACKEND->client_nickname); + BACKEND->client_nickname = NULL; + + /* destroy all NSS objects in order to avoid failure of NSS shutdown */ + Curl_llist_destroy(&BACKEND->obj_list, NULL); + BACKEND->obj_clicert = NULL; + + if(BACKEND->handle) { + if(client_cert) + /* A server might require different authentication based on the + * particular path being requested by the client. To support this + * scenario, we must ensure that a connection will never reuse the + * authentication data from a previous connection. */ + SSL_InvalidateSession(BACKEND->handle); + + PR_Close(BACKEND->handle); + BACKEND->handle = NULL; + } +} + +/* + * This function is called when an SSL connection is closed. + */ +static void Curl_nss_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex]; + + if(BACKEND->handle || connssl_proxy->backend->handle) { + /* NSS closes the socket we previously handed to it, so we must mark it + as closed to avoid double close */ + fake_sclose(conn->sock[sockindex]); + conn->sock[sockindex] = CURL_SOCKET_BAD; + } + + if(BACKEND->handle) + /* nss_close(connssl) will transitively close also + connssl_proxy->backend->handle if both are used. Clear it to avoid + a double close leading to crash. */ + connssl_proxy->backend->handle = NULL; + + nss_close(connssl); + nss_close(connssl_proxy); +} + +/* return true if NSS can provide error code (and possibly msg) for the + error */ +static bool is_nss_error(CURLcode err) +{ + switch(err) { + case CURLE_PEER_FAILED_VERIFICATION: + case CURLE_SSL_CERTPROBLEM: + case CURLE_SSL_CONNECT_ERROR: + case CURLE_SSL_ISSUER_ERROR: + return true; + + default: + return false; + } +} + +/* return true if the given error code is related to a client certificate */ +static bool is_cc_error(PRInt32 err) +{ + switch(err) { + case SSL_ERROR_BAD_CERT_ALERT: + case SSL_ERROR_EXPIRED_CERT_ALERT: + case SSL_ERROR_REVOKED_CERT_ALERT: + return true; + + default: + return false; + } +} + +static Curl_recv nss_recv; +static Curl_send nss_send; + +static CURLcode nss_load_ca_certificates(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + const char *cafile = SSL_CONN_CONFIG(CAfile); + const char *capath = SSL_CONN_CONFIG(CApath); + bool use_trust_module; + CURLcode result = CURLE_OK; + + /* treat empty string as unset */ + if(cafile && !cafile[0]) + cafile = NULL; + if(capath && !capath[0]) + capath = NULL; + + infof(data, " CAfile: %s\n CApath: %s\n", + cafile ? cafile : "none", + capath ? capath : "none"); + + /* load libnssckbi.so if no other trust roots were specified */ + use_trust_module = !cafile && !capath; + + PR_Lock(nss_trustload_lock); + if(use_trust_module && !trust_module) { + /* libnssckbi.so needed but not yet loaded --> load it! */ + result = nss_load_module(&trust_module, trust_library, "trust"); + infof(data, "%s %s\n", (result) ? "failed to load" : "loaded", + trust_library); + if(result == CURLE_FAILED_INIT) + /* If libnssckbi.so is not available (or fails to load), one can still + use CA certificates stored in NSS database. Ignore the failure. */ + result = CURLE_OK; + } + else if(!use_trust_module && trust_module) { + /* libnssckbi.so not needed but already loaded --> unload it! */ + infof(data, "unloading %s\n", trust_library); + nss_unload_module(&trust_module); + } + PR_Unlock(nss_trustload_lock); + + if(cafile) + result = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE); + + if(result) + return result; + + if(capath) { + struct_stat st; + if(stat(capath, &st) == -1) + return CURLE_SSL_CACERT_BADFILE; + + if(S_ISDIR(st.st_mode)) { + PRDirEntry *entry; + PRDir *dir = PR_OpenDir(capath); + if(!dir) + return CURLE_SSL_CACERT_BADFILE; + + while((entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN))) { + char *fullpath = aprintf("%s/%s", capath, entry->name); + if(!fullpath) { + PR_CloseDir(dir); + return CURLE_OUT_OF_MEMORY; + } + + if(CURLE_OK != nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE)) + /* This is purposefully tolerant of errors so non-PEM files can + * be in the same directory */ + infof(data, "failed to load '%s' from CURLOPT_CAPATH\n", fullpath); + + free(fullpath); + } + + PR_CloseDir(dir); + } + else + infof(data, "warning: CURLOPT_CAPATH not a directory (%s)\n", capath); + } + + return CURLE_OK; +} + +static CURLcode nss_sslver_from_curl(PRUint16 *nssver, long version) +{ + switch(version) { + case CURL_SSLVERSION_SSLv2: + *nssver = SSL_LIBRARY_VERSION_2; + return CURLE_OK; + + case CURL_SSLVERSION_SSLv3: + *nssver = SSL_LIBRARY_VERSION_3_0; + return CURLE_OK; + + case CURL_SSLVERSION_TLSv1_0: + *nssver = SSL_LIBRARY_VERSION_TLS_1_0; + return CURLE_OK; + + case CURL_SSLVERSION_TLSv1_1: +#ifdef SSL_LIBRARY_VERSION_TLS_1_1 + *nssver = SSL_LIBRARY_VERSION_TLS_1_1; + return CURLE_OK; +#else + return CURLE_SSL_CONNECT_ERROR; +#endif + + case CURL_SSLVERSION_TLSv1_2: +#ifdef SSL_LIBRARY_VERSION_TLS_1_2 + *nssver = SSL_LIBRARY_VERSION_TLS_1_2; + return CURLE_OK; +#else + return CURLE_SSL_CONNECT_ERROR; +#endif + + case CURL_SSLVERSION_TLSv1_3: +#ifdef SSL_LIBRARY_VERSION_TLS_1_3 + *nssver = SSL_LIBRARY_VERSION_TLS_1_3; + return CURLE_OK; +#else + return CURLE_SSL_CONNECT_ERROR; +#endif + + default: + return CURLE_SSL_CONNECT_ERROR; + } +} + +static CURLcode nss_init_sslver(SSLVersionRange *sslver, + struct Curl_easy *data, + struct connectdata *conn) +{ + CURLcode result; + const long min = SSL_CONN_CONFIG(version); + const long max = SSL_CONN_CONFIG(version_max); + + /* map CURL_SSLVERSION_DEFAULT to NSS default */ + if(min == CURL_SSLVERSION_DEFAULT || max == CURL_SSLVERSION_MAX_DEFAULT) { + /* map CURL_SSLVERSION_DEFAULT to NSS default */ + if(SSL_VersionRangeGetDefault(ssl_variant_stream, sslver) != SECSuccess) + return CURLE_SSL_CONNECT_ERROR; + /* ... but make sure we use at least TLSv1.0 according to libcurl API */ + if(sslver->min < SSL_LIBRARY_VERSION_TLS_1_0) + sslver->min = SSL_LIBRARY_VERSION_TLS_1_0; + } + + switch(min) { + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_DEFAULT: + break; + default: + result = nss_sslver_from_curl(&sslver->min, min); + if(result) { + failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); + return result; + } + } + + switch(max) { + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_DEFAULT: + break; + default: + result = nss_sslver_from_curl(&sslver->max, max >> 16); + if(result) { + failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); + return result; + } + } + + return CURLE_OK; +} + +static CURLcode nss_fail_connect(struct ssl_connect_data *connssl, + struct Curl_easy *data, + CURLcode curlerr) +{ + PRErrorCode err = 0; + + if(is_nss_error(curlerr)) { + /* read NSPR error code */ + err = PR_GetError(); + if(is_cc_error(err)) + curlerr = CURLE_SSL_CERTPROBLEM; + + /* print the error number and error string */ + infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err)); + + /* print a human-readable message describing the error if available */ + nss_print_error_message(data, err); + } + + /* cleanup on connection failure */ + Curl_llist_destroy(&BACKEND->obj_list, NULL); + + return curlerr; +} + +/* Switch the SSL socket into blocking or non-blocking mode. */ +static CURLcode nss_set_blocking(struct ssl_connect_data *connssl, + struct Curl_easy *data, + bool blocking) +{ + static PRSocketOptionData sock_opt; + sock_opt.option = PR_SockOpt_Nonblocking; + sock_opt.value.non_blocking = !blocking; + + if(PR_SetSocketOption(BACKEND->handle, &sock_opt) != PR_SUCCESS) + return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR); + + return CURLE_OK; +} + +static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) +{ + PRFileDesc *model = NULL; + PRFileDesc *nspr_io = NULL; + PRFileDesc *nspr_io_stub = NULL; + PRBool ssl_no_cache; + PRBool ssl_cbc_random_iv; + struct Curl_easy *data = conn->data; + curl_socket_t sockfd = conn->sock[sockindex]; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + CURLcode result; + bool second_layer = FALSE; + SSLVersionRange sslver_supported; + + SSLVersionRange sslver = { + SSL_LIBRARY_VERSION_TLS_1_0, /* min */ +#ifdef SSL_LIBRARY_VERSION_TLS_1_3 + SSL_LIBRARY_VERSION_TLS_1_3 /* max */ +#elif defined SSL_LIBRARY_VERSION_TLS_1_2 + SSL_LIBRARY_VERSION_TLS_1_2 +#elif defined SSL_LIBRARY_VERSION_TLS_1_1 + SSL_LIBRARY_VERSION_TLS_1_1 +#else + SSL_LIBRARY_VERSION_TLS_1_0 +#endif + }; + + BACKEND->data = data; + + /* list of all NSS objects we need to destroy in Curl_nss_close() */ + Curl_llist_init(&BACKEND->obj_list, nss_destroy_object); + + PR_Lock(nss_initlock); + result = nss_init(conn->data); + if(result) { + PR_Unlock(nss_initlock); + goto error; + } + + PK11_SetPasswordFunc(nss_get_password); + + result = nss_load_module(&pem_module, pem_library, "PEM"); + PR_Unlock(nss_initlock); + if(result == CURLE_FAILED_INIT) + infof(data, "WARNING: failed to load NSS PEM library %s. Using " + "OpenSSL PEM certificates will not work.\n", pem_library); + else if(result) + goto error; + + result = CURLE_SSL_CONNECT_ERROR; + + model = PR_NewTCPSocket(); + if(!model) + goto error; + model = SSL_ImportFD(NULL, model); + + if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess) + goto error; + if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess) + goto error; + if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess) + goto error; + + /* do not use SSL cache if disabled or we are not going to verify peer */ + ssl_no_cache = (SSL_SET_OPTION(primary.sessionid) + && SSL_CONN_CONFIG(verifypeer)) ? PR_FALSE : PR_TRUE; + if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess) + goto error; + + /* enable/disable the requested SSL version(s) */ + if(nss_init_sslver(&sslver, data, conn) != CURLE_OK) + goto error; + if(SSL_VersionRangeGetSupported(ssl_variant_stream, + &sslver_supported) != SECSuccess) + goto error; + if(sslver_supported.max < sslver.max && sslver_supported.max >= sslver.min) { + char *sslver_req_str, *sslver_supp_str; + sslver_req_str = nss_sslver_to_name(sslver.max); + sslver_supp_str = nss_sslver_to_name(sslver_supported.max); + if(sslver_req_str && sslver_supp_str) + infof(data, "Falling back from %s to max supported SSL version (%s)\n", + sslver_req_str, sslver_supp_str); + free(sslver_req_str); + free(sslver_supp_str); + sslver.max = sslver_supported.max; + } + if(SSL_VersionRangeSet(model, &sslver) != SECSuccess) + goto error; + + ssl_cbc_random_iv = !SSL_SET_OPTION(enable_beast); +#ifdef SSL_CBC_RANDOM_IV + /* unless the user explicitly asks to allow the protocol vulnerability, we + use the work-around */ + if(SSL_OptionSet(model, SSL_CBC_RANDOM_IV, ssl_cbc_random_iv) != SECSuccess) + infof(data, "warning: failed to set SSL_CBC_RANDOM_IV = %d\n", + ssl_cbc_random_iv); +#else + if(ssl_cbc_random_iv) + infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in\n"); +#endif + + if(SSL_CONN_CONFIG(cipher_list)) { + if(set_ciphers(data, model, SSL_CONN_CONFIG(cipher_list)) != SECSuccess) { + result = CURLE_SSL_CIPHER; + goto error; + } + } + + if(!SSL_CONN_CONFIG(verifypeer) && SSL_CONN_CONFIG(verifyhost)) + infof(data, "warning: ignoring value of ssl.verifyhost\n"); + + /* bypass the default SSL_AuthCertificate() hook in case we do not want to + * verify peer */ + if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, conn) != SECSuccess) + goto error; + + /* not checked yet */ + if(SSL_IS_PROXY()) + data->set.proxy_ssl.certverifyresult = 0; + else + data->set.ssl.certverifyresult = 0; + + if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess) + goto error; + + if(SSL_HandshakeCallback(model, HandshakeCallback, conn) != SECSuccess) + goto error; + + { + const CURLcode rv = nss_load_ca_certificates(conn, sockindex); + if((rv == CURLE_SSL_CACERT_BADFILE) && !SSL_CONN_CONFIG(verifypeer)) + /* not a fatal error because we are not going to verify the peer */ + infof(data, "warning: CA certificates failed to load\n"); + else if(rv) { + result = rv; + goto error; + } + } + + if(SSL_SET_OPTION(CRLfile)) { + const CURLcode rv = nss_load_crl(SSL_SET_OPTION(CRLfile)); + if(rv) { + result = rv; + goto error; + } + infof(data, " CRLfile: %s\n", SSL_SET_OPTION(CRLfile)); + } + + if(SSL_SET_OPTION(cert)) { + char *nickname = dup_nickname(data, SSL_SET_OPTION(cert)); + if(nickname) { + /* we are not going to use libnsspem.so to read the client cert */ + BACKEND->obj_clicert = NULL; + } + else { + CURLcode rv = cert_stuff(conn, sockindex, SSL_SET_OPTION(cert), + SSL_SET_OPTION(key)); + if(rv) { + /* failf() is already done in cert_stuff() */ + result = rv; + goto error; + } + } + + /* store the nickname for SelectClientCert() called during handshake */ + BACKEND->client_nickname = nickname; + } + else + BACKEND->client_nickname = NULL; + + if(SSL_GetClientAuthDataHook(model, SelectClientCert, + (void *)connssl) != SECSuccess) { + result = CURLE_SSL_CERTPROBLEM; + goto error; + } + + if(conn->proxy_ssl[sockindex].use) { + DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state); + DEBUGASSERT(conn->proxy_ssl[sockindex].backend->handle != NULL); + nspr_io = conn->proxy_ssl[sockindex].backend->handle; + second_layer = TRUE; + } + else { + /* wrap OS file descriptor by NSPR's file descriptor abstraction */ + nspr_io = PR_ImportTCPSocket(sockfd); + if(!nspr_io) + goto error; + } + + /* create our own NSPR I/O layer */ + nspr_io_stub = PR_CreateIOLayerStub(nspr_io_identity, &nspr_io_methods); + if(!nspr_io_stub) { + if(!second_layer) + PR_Close(nspr_io); + goto error; + } + + /* make the per-connection data accessible from NSPR I/O callbacks */ + nspr_io_stub->secret = (void *)connssl; + + /* push our new layer to the NSPR I/O stack */ + if(PR_PushIOLayer(nspr_io, PR_TOP_IO_LAYER, nspr_io_stub) != PR_SUCCESS) { + if(!second_layer) + PR_Close(nspr_io); + PR_Close(nspr_io_stub); + goto error; + } + + /* import our model socket onto the current I/O stack */ + BACKEND->handle = SSL_ImportFD(model, nspr_io); + if(!BACKEND->handle) { + if(!second_layer) + PR_Close(nspr_io); + goto error; + } + + PR_Close(model); /* We don't need this any more */ + model = NULL; + + /* This is the password associated with the cert that we're using */ + if(SSL_SET_OPTION(key_passwd)) { + SSL_SetPKCS11PinArg(BACKEND->handle, SSL_SET_OPTION(key_passwd)); + } + +#ifdef SSL_ENABLE_OCSP_STAPLING + if(SSL_CONN_CONFIG(verifystatus)) { + if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE) + != SECSuccess) + goto error; + } +#endif + +#ifdef SSL_ENABLE_NPN + if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn + ? PR_TRUE : PR_FALSE) != SECSuccess) + goto error; +#endif + +#ifdef SSL_ENABLE_ALPN + if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn + ? PR_TRUE : PR_FALSE) != SECSuccess) + goto error; +#endif + +#if NSSVERNUM >= 0x030f04 /* 3.15.4 */ + if(data->set.ssl.falsestart) { + if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_FALSE_START, PR_TRUE) + != SECSuccess) + goto error; + + if(SSL_SetCanFalseStartCallback(BACKEND->handle, CanFalseStartCallback, + conn) != SECSuccess) + goto error; + } +#endif + +#if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN) + if(conn->bits.tls_enable_npn || conn->bits.tls_enable_alpn) { + int cur = 0; + unsigned char protocols[128]; + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2 && + (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) { + protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN; + memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID, + NGHTTP2_PROTO_VERSION_ID_LEN); + cur += NGHTTP2_PROTO_VERSION_ID_LEN; + } +#endif + protocols[cur++] = ALPN_HTTP_1_1_LENGTH; + memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH); + cur += ALPN_HTTP_1_1_LENGTH; + + if(SSL_SetNextProtoNego(BACKEND->handle, protocols, cur) != SECSuccess) + goto error; + } +#endif + + + /* Force handshake on next I/O */ + if(SSL_ResetHandshake(BACKEND->handle, /* asServer */ PR_FALSE) + != SECSuccess) + goto error; + + /* propagate hostname to the TLS layer */ + if(SSL_SetURL(BACKEND->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name) != SECSuccess) + goto error; + + /* prevent NSS from re-using the session for a different hostname */ + if(SSL_SetSockPeerID(BACKEND->handle, SSL_IS_PROXY() ? + conn->http_proxy.host.name : conn->host.name) + != SECSuccess) + goto error; + + return CURLE_OK; + +error: + if(model) + PR_Close(model); + + return nss_fail_connect(connssl, data, result); +} + +static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct Curl_easy *data = conn->data; + CURLcode result = CURLE_SSL_CONNECT_ERROR; + PRUint32 timeout; + long * const certverifyresult = SSL_IS_PROXY() ? + &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + + + /* check timeout situation */ + const time_t time_left = Curl_timeleft(data, NULL, TRUE); + if(time_left < 0) { + failf(data, "timed out before SSL handshake"); + result = CURLE_OPERATION_TIMEDOUT; + goto error; + } + + /* Force the handshake now */ + timeout = PR_MillisecondsToInterval((PRUint32) time_left); + if(SSL_ForceHandshakeWithTimeout(BACKEND->handle, timeout) != SECSuccess) { + if(PR_GetError() == PR_WOULD_BLOCK_ERROR) + /* blocking direction is updated by nss_update_connecting_state() */ + return CURLE_AGAIN; + else if(*certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN) + result = CURLE_PEER_FAILED_VERIFICATION; + else if(*certverifyresult != 0) + result = CURLE_PEER_FAILED_VERIFICATION; + goto error; + } + + result = display_conn_info(conn, BACKEND->handle); + if(result) + goto error; + + if(SSL_SET_OPTION(issuercert)) { + SECStatus ret = SECFailure; + char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert)); + if(nickname) { + /* we support only nicknames in case of issuercert for now */ + ret = check_issuer_cert(BACKEND->handle, nickname); + free(nickname); + } + + if(SECFailure == ret) { + infof(data, "SSL certificate issuer check failed\n"); + result = CURLE_SSL_ISSUER_ERROR; + goto error; + } + else { + infof(data, "SSL certificate issuer check ok\n"); + } + } + + result = cmp_peer_pubkey(connssl, pinnedpubkey); + if(result) + /* status already printed */ + goto error; + + return CURLE_OK; + +error: + return nss_fail_connect(connssl, data, result); +} + +static CURLcode nss_connect_common(struct connectdata *conn, int sockindex, + bool *done) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct Curl_easy *data = conn->data; + const bool blocking = (done == NULL); + CURLcode result; + + if(connssl->state == ssl_connection_complete) { + if(!blocking) + *done = TRUE; + return CURLE_OK; + } + + if(connssl->connecting_state == ssl_connect_1) { + result = nss_setup_connect(conn, sockindex); + if(result) + /* we do not expect CURLE_AGAIN from nss_setup_connect() */ + return result; + + connssl->connecting_state = ssl_connect_2; + } + + /* enable/disable blocking mode before handshake */ + result = nss_set_blocking(connssl, data, blocking); + if(result) + return result; + + result = nss_do_connect(conn, sockindex); + switch(result) { + case CURLE_OK: + break; + case CURLE_AGAIN: + if(!blocking) + /* CURLE_AGAIN in non-blocking mode is not an error */ + return CURLE_OK; + /* FALLTHROUGH */ + default: + return result; + } + + if(blocking) { + /* in blocking mode, set NSS non-blocking mode _after_ SSL handshake */ + result = nss_set_blocking(connssl, data, /* blocking */ FALSE); + if(result) + return result; + } + else + /* signal completed SSL handshake */ + *done = TRUE; + + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = nss_recv; + conn->send[sockindex] = nss_send; + + /* ssl_connect_done is never used outside, go back to the initial state */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +static CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) +{ + return nss_connect_common(conn, sockindex, /* blocking */ NULL); +} + +static CURLcode Curl_nss_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + return nss_connect_common(conn, sockindex, done); +} + +static ssize_t nss_send(struct connectdata *conn, /* connection data */ + int sockindex, /* socketindex */ + const void *mem, /* send this data */ + size_t len, /* amount to write */ + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + ssize_t rc; + + /* The SelectClientCert() hook uses this for infof() and failf() but the + handle stored in nss_setup_connect() could have already been freed. */ + BACKEND->data = conn->data; + + rc = PR_Send(BACKEND->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT); + if(rc < 0) { + PRInt32 err = PR_GetError(); + if(err == PR_WOULD_BLOCK_ERROR) + *curlcode = CURLE_AGAIN; + else { + /* print the error number and error string */ + const char *err_name = nss_error_to_name(err); + infof(conn->data, "SSL write: error %d (%s)\n", err, err_name); + + /* print a human-readable message describing the error if available */ + nss_print_error_message(conn->data, err); + + *curlcode = (is_cc_error(err)) + ? CURLE_SSL_CERTPROBLEM + : CURLE_SEND_ERROR; + } + + return -1; + } + + return rc; /* number of bytes */ +} + +static ssize_t nss_recv(struct connectdata *conn, /* connection data */ + int sockindex, /* socketindex */ + char *buf, /* store read data here */ + size_t buffersize, /* max amount to read */ + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + ssize_t nread; + + /* The SelectClientCert() hook uses this for infof() and failf() but the + handle stored in nss_setup_connect() could have already been freed. */ + BACKEND->data = conn->data; + + nread = PR_Recv(BACKEND->handle, buf, (int)buffersize, 0, + PR_INTERVAL_NO_WAIT); + if(nread < 0) { + /* failed SSL read */ + PRInt32 err = PR_GetError(); + + if(err == PR_WOULD_BLOCK_ERROR) + *curlcode = CURLE_AGAIN; + else { + /* print the error number and error string */ + const char *err_name = nss_error_to_name(err); + infof(conn->data, "SSL read: errno %d (%s)\n", err, err_name); + + /* print a human-readable message describing the error if available */ + nss_print_error_message(conn->data, err); + + *curlcode = (is_cc_error(err)) + ? CURLE_SSL_CERTPROBLEM + : CURLE_RECV_ERROR; + } + + return -1; + } + + return nread; +} + +static size_t Curl_nss_version(char *buffer, size_t size) +{ + return msnprintf(buffer, size, "NSS/%s", NSS_VERSION); +} + +/* data might be NULL */ +static int Curl_nss_seed(struct Curl_easy *data) +{ + /* make sure that NSS is initialized */ + return !!Curl_nss_force_init(data); +} + +/* data might be NULL */ +static CURLcode Curl_nss_random(struct Curl_easy *data, + unsigned char *entropy, + size_t length) +{ + Curl_nss_seed(data); /* Initiate the seed if not already done */ + + if(SECSuccess != PK11_GenerateRandom(entropy, curlx_uztosi(length))) + /* signal a failure */ + return CURLE_FAILED_INIT; + + return CURLE_OK; +} + +static CURLcode Curl_nss_md5sum(unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *md5sum, /* output */ + size_t md5len) +{ + PK11Context *MD5pw = PK11_CreateDigestContext(SEC_OID_MD5); + unsigned int MD5out; + + PK11_DigestOp(MD5pw, tmp, curlx_uztoui(tmplen)); + PK11_DigestFinal(MD5pw, md5sum, &MD5out, curlx_uztoui(md5len)); + PK11_DestroyContext(MD5pw, PR_TRUE); + + return CURLE_OK; +} + +static CURLcode Curl_nss_sha256sum(const unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *sha256sum, /* output */ + size_t sha256len) +{ + PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256); + unsigned int SHA256out; + + PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen)); + PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len)); + PK11_DestroyContext(SHA256pw, PR_TRUE); + + return CURLE_OK; +} + +static bool Curl_nss_cert_status_request(void) +{ +#ifdef SSL_ENABLE_OCSP_STAPLING + return TRUE; +#else + return FALSE; +#endif +} + +static bool Curl_nss_false_start(void) +{ +#if NSSVERNUM >= 0x030f04 /* 3.15.4 */ + return TRUE; +#else + return FALSE; +#endif +} + +static void *Curl_nss_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + (void)info; + return BACKEND->handle; +} + +const struct Curl_ssl Curl_ssl_nss = { + { CURLSSLBACKEND_NSS, "nss" }, /* info */ + + SSLSUPP_CA_PATH | + SSLSUPP_CERTINFO | + SSLSUPP_PINNEDPUBKEY | + SSLSUPP_HTTPS_PROXY, + + sizeof(struct ssl_backend_data), + + Curl_nss_init, /* init */ + Curl_nss_cleanup, /* cleanup */ + Curl_nss_version, /* version */ + Curl_nss_check_cxn, /* check_cxn */ + /* NSS has no shutdown function provided and thus always fail */ + Curl_none_shutdown, /* shutdown */ + Curl_none_data_pending, /* data_pending */ + Curl_nss_random, /* random */ + Curl_nss_cert_status_request, /* cert_status_request */ + Curl_nss_connect, /* connect */ + Curl_nss_connect_nonblocking, /* connect_nonblocking */ + Curl_nss_get_internals, /* get_internals */ + Curl_nss_close, /* close_one */ + Curl_none_close_all, /* close_all */ + /* NSS has its own session ID cache */ + Curl_none_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_nss_false_start, /* false_start */ + Curl_nss_md5sum, /* md5sum */ + Curl_nss_sha256sum /* sha256sum */ +}; + +#endif /* USE_NSS */ diff --git a/libcurl/lib/vtls/nssg.h b/libcurl/lib/vtls/nssg.h new file mode 100644 index 0000000..41e51b0 --- /dev/null +++ b/libcurl/lib/vtls/nssg.h @@ -0,0 +1,39 @@ +#ifndef HEADER_CURL_NSSG_H +#define HEADER_CURL_NSSG_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_NSS +/* + * This header should only be needed to get included by vtls.c and nss.c + */ + +#include "urldata.h" + +/* initialize NSS library if not already */ +CURLcode Curl_nss_force_init(struct Curl_easy *data); + +extern const struct Curl_ssl Curl_ssl_nss; + +#endif /* USE_NSS */ +#endif /* HEADER_CURL_NSSG_H */ diff --git a/libcurl/lib/vtls/openssl.c b/libcurl/lib/vtls/openssl.c new file mode 100644 index 0000000..fb9f271 --- /dev/null +++ b/libcurl/lib/vtls/openssl.c @@ -0,0 +1,3954 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all OpenSSL-specific code for the TLS/SSL layer. No code + * but vtls.c should ever call or use these functions. + */ + +/* + * The original SSLeay-using code for curl was written by Linas Vepstas and + * Sampo Kellomaki 1998. + */ + +#include "curl_setup.h" + +#ifdef USE_OPENSSL + +#include + +#include "urldata.h" +#include "sendf.h" +#include "formdata.h" /* for the boundary function */ +#include "url.h" /* for the ssl config check function */ +#include "inet_pton.h" +#include "openssl.h" +#include "connect.h" +#include "slist.h" +#include "select.h" +#include "vtls.h" +#include "strcase.h" +#include "hostcheck.h" +#include "multiif.h" +#include "curl_printf.h" +#include +#include +#include +#ifndef OPENSSL_NO_DSA +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_AMISSL +#include "amigaos.h" +#endif + +#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP) +#include +#endif + +#if (OPENSSL_VERSION_NUMBER >= 0x0090700fL) && /* 0.9.7 or later */ \ + !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_UI_CONSOLE) +#define USE_OPENSSL_ENGINE +#include +#endif + +#include "warnless.h" +#include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */ + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* Uncomment the ALLOW_RENEG line to a real #define if you want to allow TLS + renegotiations when built with BoringSSL. Renegotiating is non-compliant + with HTTP/2 and "an extremely dangerous protocol feature". Beware. + +#define ALLOW_RENEG 1 + */ + +#ifndef OPENSSL_VERSION_NUMBER +#error "OPENSSL_VERSION_NUMBER not defined" +#endif + +#ifdef USE_OPENSSL_ENGINE +#include +#endif + +#if OPENSSL_VERSION_NUMBER >= 0x00909000L +#define SSL_METHOD_QUAL const +#else +#define SSL_METHOD_QUAL +#endif + +#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) +#define HAVE_ERR_REMOVE_THREAD_STATE 1 +#endif + +#if !defined(HAVE_SSLV2_CLIENT_METHOD) || \ + OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0+ has no SSLv2 */ +#undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */ +#define OPENSSL_NO_SSL2 +#endif + +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && /* OpenSSL 1.1.0+ */ \ + !(defined(LIBRESSL_VERSION_NUMBER) && \ + LIBRESSL_VERSION_NUMBER < 0x20700000L) +#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER +#define HAVE_X509_GET0_EXTENSIONS 1 /* added in 1.1.0 -pre1 */ +#define HAVE_OPAQUE_EVP_PKEY 1 /* since 1.1.0 -pre3 */ +#define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */ +#define CONST_EXTS const +#define HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED 1 + +/* funny typecast define due to difference in API */ +#ifdef LIBRESSL_VERSION_NUMBER +#define ARG2_X509_signature_print (X509_ALGOR *) +#else +#define ARG2_X509_signature_print +#endif + +#else +/* For OpenSSL before 1.1.0 */ +#define ASN1_STRING_get0_data(x) ASN1_STRING_data(x) +#define X509_get0_notBefore(x) X509_get_notBefore(x) +#define X509_get0_notAfter(x) X509_get_notAfter(x) +#define CONST_EXTS /* nope */ +#ifndef LIBRESSL_VERSION_NUMBER +#define OpenSSL_version_num() SSLeay() +#endif +#endif + +#ifdef LIBRESSL_VERSION_NUMBER +#define OpenSSL_version_num() LIBRESSL_VERSION_NUMBER +#endif + +#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \ + !(defined(LIBRESSL_VERSION_NUMBER) && \ + LIBRESSL_VERSION_NUMBER < 0x20700000L) +#define HAVE_X509_GET0_SIGNATURE 1 +#endif + +#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) /* 1.0.2 or later */ +#define HAVE_SSL_GET_SHUTDOWN 1 +#endif + +#if OPENSSL_VERSION_NUMBER >= 0x10002003L && \ + OPENSSL_VERSION_NUMBER <= 0x10002FFFL && \ + !defined(OPENSSL_NO_COMP) +#define HAVE_SSL_COMP_FREE_COMPRESSION_METHODS 1 +#endif + +#if (OPENSSL_VERSION_NUMBER < 0x0090808fL) +/* not present in older OpenSSL */ +#define OPENSSL_load_builtin_modules(x) +#endif + +/* + * Whether SSL_CTX_set_keylog_callback is available. + * OpenSSL: supported since 1.1.1 https://github.com/openssl/openssl/pull/2287 + * BoringSSL: supported since d28f59c27bac (committed 2015-11-19) + * LibreSSL: unsupported in at least 2.7.2 (explicitly check for it since it + * lies and pretends to be OpenSSL 2.0.0). + */ +#if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \ + !defined(LIBRESSL_VERSION_NUMBER)) || \ + defined(OPENSSL_IS_BORINGSSL) +#define HAVE_KEYLOG_CALLBACK +#endif + +/* Whether SSL_CTX_set_ciphersuites is available. + * OpenSSL: supported since 1.1.1 (commit a53b5be6a05) + * BoringSSL: no + * LibreSSL: no + */ +#if ((OPENSSL_VERSION_NUMBER >= 0x10101000L) && \ + !defined(LIBRESSL_VERSION_NUMBER) && \ + !defined(OPENSSL_IS_BORINGSSL)) +#define HAVE_SSL_CTX_SET_CIPHERSUITES +#define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH +#endif + +#if defined(LIBRESSL_VERSION_NUMBER) +#define OSSL_PACKAGE "LibreSSL" +#elif defined(OPENSSL_IS_BORINGSSL) +#define OSSL_PACKAGE "BoringSSL" +#else +#define OSSL_PACKAGE "OpenSSL" +#endif + +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) +/* up2date versions of OpenSSL maintain the default reasonably secure without + * breaking compatibility, so it is better not to override the default by curl + */ +#define DEFAULT_CIPHER_SELECTION NULL +#else +/* ... but it is not the case with old versions of OpenSSL */ +#define DEFAULT_CIPHER_SELECTION \ + "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH" +#endif + +#define ENABLE_SSLKEYLOGFILE + +#ifdef ENABLE_SSLKEYLOGFILE +typedef struct ssl_tap_state { + int master_key_length; + unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; + unsigned char client_random[SSL3_RANDOM_SIZE]; +} ssl_tap_state_t; +#endif /* ENABLE_SSLKEYLOGFILE */ + +struct ssl_backend_data { + /* these ones requires specific SSL-types */ + SSL_CTX* ctx; + SSL* handle; + X509* server_cert; +#ifdef ENABLE_SSLKEYLOGFILE + /* tap_state holds the last seen master key if we're logging them */ + ssl_tap_state_t tap_state; +#endif +}; + +#define BACKEND connssl->backend + +/* + * Number of bytes to read from the random number seed file. This must be + * a finite value (because some entropy "files" like /dev/urandom have + * an infinite length), but must be large enough to provide enough + * entropy to properly seed OpenSSL's PRNG. + */ +#define RAND_LOAD_LENGTH 1024 + +#ifdef ENABLE_SSLKEYLOGFILE +/* The fp for the open SSLKEYLOGFILE, or NULL if not open */ +static FILE *keylog_file_fp; + +#ifdef HAVE_KEYLOG_CALLBACK +static void ossl_keylog_callback(const SSL *ssl, const char *line) +{ + (void)ssl; + + /* Using fputs here instead of fprintf since libcurl's fprintf replacement + may not be thread-safe. */ + if(keylog_file_fp && line && *line) { + char stackbuf[256]; + char *buf; + size_t linelen = strlen(line); + + if(linelen <= sizeof(stackbuf) - 2) + buf = stackbuf; + else { + buf = malloc(linelen + 2); + if(!buf) + return; + } + memcpy(buf, line, linelen); + buf[linelen] = '\n'; + buf[linelen + 1] = '\0'; + + fputs(buf, keylog_file_fp); + if(buf != stackbuf) + free(buf); + } +} +#else +#define KEYLOG_PREFIX "CLIENT_RANDOM " +#define KEYLOG_PREFIX_LEN (sizeof(KEYLOG_PREFIX) - 1) +/* + * tap_ssl_key is called by libcurl to make the CLIENT_RANDOMs if the OpenSSL + * being used doesn't have native support for doing that. + */ +static void tap_ssl_key(const SSL *ssl, ssl_tap_state_t *state) +{ + const char *hex = "0123456789ABCDEF"; + int pos, i; + char line[KEYLOG_PREFIX_LEN + 2 * SSL3_RANDOM_SIZE + 1 + + 2 * SSL_MAX_MASTER_KEY_LENGTH + 1 + 1]; + const SSL_SESSION *session = SSL_get_session(ssl); + unsigned char client_random[SSL3_RANDOM_SIZE]; + unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; + int master_key_length = 0; + + if(!session || !keylog_file_fp) + return; + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !(defined(LIBRESSL_VERSION_NUMBER) && \ + LIBRESSL_VERSION_NUMBER < 0x20700000L) + /* ssl->s3 is not checked in openssl 1.1.0-pre6, but let's assume that + * we have a valid SSL context if we have a non-NULL session. */ + SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE); + master_key_length = (int) + SSL_SESSION_get_master_key(session, master_key, SSL_MAX_MASTER_KEY_LENGTH); +#else + if(ssl->s3 && session->master_key_length > 0) { + master_key_length = session->master_key_length; + memcpy(master_key, session->master_key, session->master_key_length); + memcpy(client_random, ssl->s3->client_random, SSL3_RANDOM_SIZE); + } +#endif + + if(master_key_length <= 0) + return; + + /* Skip writing keys if there is no key or it did not change. */ + if(state->master_key_length == master_key_length && + !memcmp(state->master_key, master_key, master_key_length) && + !memcmp(state->client_random, client_random, SSL3_RANDOM_SIZE)) { + return; + } + + state->master_key_length = master_key_length; + memcpy(state->master_key, master_key, master_key_length); + memcpy(state->client_random, client_random, SSL3_RANDOM_SIZE); + + memcpy(line, KEYLOG_PREFIX, KEYLOG_PREFIX_LEN); + pos = KEYLOG_PREFIX_LEN; + + /* Client Random for SSLv3/TLS */ + for(i = 0; i < SSL3_RANDOM_SIZE; i++) { + line[pos++] = hex[client_random[i] >> 4]; + line[pos++] = hex[client_random[i] & 0xF]; + } + line[pos++] = ' '; + + /* Master Secret (size is at most SSL_MAX_MASTER_KEY_LENGTH) */ + for(i = 0; i < master_key_length; i++) { + line[pos++] = hex[master_key[i] >> 4]; + line[pos++] = hex[master_key[i] & 0xF]; + } + line[pos++] = '\n'; + line[pos] = '\0'; + + /* Using fputs here instead of fprintf since libcurl's fprintf replacement + may not be thread-safe. */ + fputs(line, keylog_file_fp); +} +#endif /* !HAVE_KEYLOG_CALLBACK */ +#endif /* ENABLE_SSLKEYLOGFILE */ + +static const char *SSL_ERROR_to_str(int err) +{ + switch(err) { + case SSL_ERROR_NONE: + return "SSL_ERROR_NONE"; + case SSL_ERROR_SSL: + return "SSL_ERROR_SSL"; + case SSL_ERROR_WANT_READ: + return "SSL_ERROR_WANT_READ"; + case SSL_ERROR_WANT_WRITE: + return "SSL_ERROR_WANT_WRITE"; + case SSL_ERROR_WANT_X509_LOOKUP: + return "SSL_ERROR_WANT_X509_LOOKUP"; + case SSL_ERROR_SYSCALL: + return "SSL_ERROR_SYSCALL"; + case SSL_ERROR_ZERO_RETURN: + return "SSL_ERROR_ZERO_RETURN"; + case SSL_ERROR_WANT_CONNECT: + return "SSL_ERROR_WANT_CONNECT"; + case SSL_ERROR_WANT_ACCEPT: + return "SSL_ERROR_WANT_ACCEPT"; +#if defined(SSL_ERROR_WANT_ASYNC) + case SSL_ERROR_WANT_ASYNC: + return "SSL_ERROR_WANT_ASYNC"; +#endif +#if defined(SSL_ERROR_WANT_ASYNC_JOB) + case SSL_ERROR_WANT_ASYNC_JOB: + return "SSL_ERROR_WANT_ASYNC_JOB"; +#endif +#if defined(SSL_ERROR_WANT_EARLY) + case SSL_ERROR_WANT_EARLY: + return "SSL_ERROR_WANT_EARLY"; +#endif + default: + return "SSL_ERROR unknown"; + } +} + +/* Return error string for last OpenSSL error + */ +static char *ossl_strerror(unsigned long error, char *buf, size_t size) +{ + ERR_error_string_n(error, buf, size); + return buf; +} + +/* Return an extra data index for the connection data. + * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). + */ +static int ossl_get_ssl_conn_index(void) +{ + static int ssl_ex_data_conn_index = -1; + if(ssl_ex_data_conn_index < 0) { + ssl_ex_data_conn_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); + } + return ssl_ex_data_conn_index; +} + +/* Return an extra data index for the sockindex. + * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). + */ +static int ossl_get_ssl_sockindex_index(void) +{ + static int ssl_ex_data_sockindex_index = -1; + if(ssl_ex_data_sockindex_index < 0) { + ssl_ex_data_sockindex_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, + NULL); + } + return ssl_ex_data_sockindex_index; +} + +static int passwd_callback(char *buf, int num, int encrypting, + void *global_passwd) +{ + DEBUGASSERT(0 == encrypting); + + if(!encrypting) { + int klen = curlx_uztosi(strlen((char *)global_passwd)); + if(num > klen) { + memcpy(buf, global_passwd, klen + 1); + return klen; + } + } + return 0; +} + +/* + * rand_enough() returns TRUE if we have seeded the random engine properly. + */ +static bool rand_enough(void) +{ + return (0 != RAND_status()) ? TRUE : FALSE; +} + +static CURLcode Curl_ossl_seed(struct Curl_easy *data) +{ + /* we have the "SSL is seeded" boolean static to prevent multiple + time-consuming seedings in vain */ + static bool ssl_seeded = FALSE; + char fname[256]; + + if(ssl_seeded) + return CURLE_OK; + + if(rand_enough()) { + /* OpenSSL 1.1.0+ will return here */ + ssl_seeded = TRUE; + return CURLE_OK; + } + +#ifndef RANDOM_FILE + /* if RANDOM_FILE isn't defined, we only perform this if an option tells + us to! */ + if(data->set.str[STRING_SSL_RANDOM_FILE]) +#define RANDOM_FILE "" /* doesn't matter won't be used */ +#endif + { + /* let the option override the define */ + RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]? + data->set.str[STRING_SSL_RANDOM_FILE]: + RANDOM_FILE), + RAND_LOAD_LENGTH); + if(rand_enough()) + return CURLE_OK; + } + +#if defined(HAVE_RAND_EGD) + /* only available in OpenSSL 0.9.5 and later */ + /* EGD_SOCKET is set at configure time or not at all */ +#ifndef EGD_SOCKET + /* If we don't have the define set, we only do this if the egd-option + is set */ + if(data->set.str[STRING_SSL_EGDSOCKET]) +#define EGD_SOCKET "" /* doesn't matter won't be used */ +#endif + { + /* If there's an option and a define, the option overrides the + define */ + int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]? + data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET); + if(-1 != ret) { + if(rand_enough()) + return CURLE_OK; + } + } +#endif + + /* fallback to a custom seeding of the PRNG using a hash based on a current + time */ + do { + unsigned char randb[64]; + size_t len = sizeof(randb); + size_t i, i_max; + for(i = 0, i_max = len / sizeof(struct curltime); i < i_max; ++i) { + struct curltime tv = Curl_now(); + Curl_wait_ms(1); + tv.tv_sec *= i + 1; + tv.tv_usec *= (unsigned int)i + 2; + tv.tv_sec ^= ((Curl_now().tv_sec + Curl_now().tv_usec) * + (i + 3)) << 8; + tv.tv_usec ^= (unsigned int) ((Curl_now().tv_sec + + Curl_now().tv_usec) * + (i + 4)) << 16; + memcpy(&randb[i * sizeof(struct curltime)], &tv, + sizeof(struct curltime)); + } + RAND_add(randb, (int)len, (double)len/2); + } while(!rand_enough()); + + /* generates a default path for the random seed file */ + fname[0] = 0; /* blank it first */ + RAND_file_name(fname, sizeof(fname)); + if(fname[0]) { + /* we got a file name to try */ + RAND_load_file(fname, RAND_LOAD_LENGTH); + if(rand_enough()) + return CURLE_OK; + } + + infof(data, "libcurl is now using a weak random seed!\n"); + return (rand_enough() ? CURLE_OK : + CURLE_SSL_CONNECT_ERROR /* confusing error code */); +} + +#ifndef SSL_FILETYPE_ENGINE +#define SSL_FILETYPE_ENGINE 42 +#endif +#ifndef SSL_FILETYPE_PKCS12 +#define SSL_FILETYPE_PKCS12 43 +#endif +static int do_file_type(const char *type) +{ + if(!type || !type[0]) + return SSL_FILETYPE_PEM; + if(strcasecompare(type, "PEM")) + return SSL_FILETYPE_PEM; + if(strcasecompare(type, "DER")) + return SSL_FILETYPE_ASN1; + if(strcasecompare(type, "ENG")) + return SSL_FILETYPE_ENGINE; + if(strcasecompare(type, "P12")) + return SSL_FILETYPE_PKCS12; + return -1; +} + +#ifdef USE_OPENSSL_ENGINE +/* + * Supply default password to the engine user interface conversation. + * The password is passed by OpenSSL engine from ENGINE_load_private_key() + * last argument to the ui and can be obtained by UI_get0_user_data(ui) here. + */ +static int ssl_ui_reader(UI *ui, UI_STRING *uis) +{ + const char *password; + switch(UI_get_string_type(uis)) { + case UIT_PROMPT: + case UIT_VERIFY: + password = (const char *)UI_get0_user_data(ui); + if(password && (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) { + UI_set_result(ui, uis, password); + return 1; + } + default: + break; + } + return (UI_method_get_reader(UI_OpenSSL()))(ui, uis); +} + +/* + * Suppress interactive request for a default password if available. + */ +static int ssl_ui_writer(UI *ui, UI_STRING *uis) +{ + switch(UI_get_string_type(uis)) { + case UIT_PROMPT: + case UIT_VERIFY: + if(UI_get0_user_data(ui) && + (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) { + return 1; + } + default: + break; + } + return (UI_method_get_writer(UI_OpenSSL()))(ui, uis); +} + +/* + * Check if a given string is a PKCS#11 URI + */ +static bool is_pkcs11_uri(const char *string) +{ + return (string && strncasecompare(string, "pkcs11:", 7)); +} + +#endif + +static CURLcode Curl_ossl_set_engine(struct Curl_easy *data, + const char *engine); + +static +int cert_stuff(struct connectdata *conn, + SSL_CTX* ctx, + char *cert_file, + const char *cert_type, + char *key_file, + const char *key_type, + char *key_passwd) +{ + struct Curl_easy *data = conn->data; + char error_buffer[256]; + bool check_privkey = TRUE; + + int file_type = do_file_type(cert_type); + + if(cert_file || (file_type == SSL_FILETYPE_ENGINE)) { + SSL *ssl; + X509 *x509; + int cert_done = 0; + + if(key_passwd) { + /* set the password in the callback userdata */ + SSL_CTX_set_default_passwd_cb_userdata(ctx, key_passwd); + /* Set passwd callback: */ + SSL_CTX_set_default_passwd_cb(ctx, passwd_callback); + } + + + switch(file_type) { + case SSL_FILETYPE_PEM: + /* SSL_CTX_use_certificate_chain_file() only works on PEM files */ + if(SSL_CTX_use_certificate_chain_file(ctx, + cert_file) != 1) { + failf(data, + "could not load PEM client certificate, " OSSL_PACKAGE + " error %s, " + "(no key found, wrong pass phrase, or wrong file format?)", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + return 0; + } + break; + + case SSL_FILETYPE_ASN1: + /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but + we use the case above for PEM so this can only be performed with + ASN1 files. */ + if(SSL_CTX_use_certificate_file(ctx, + cert_file, + file_type) != 1) { + failf(data, + "could not load ASN1 client certificate, " OSSL_PACKAGE + " error %s, " + "(no key found, wrong pass phrase, or wrong file format?)", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + return 0; + } + break; + case SSL_FILETYPE_ENGINE: +#if defined(USE_OPENSSL_ENGINE) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME) + { + /* Implicitly use pkcs11 engine if none was provided and the + * cert_file is a PKCS#11 URI */ + if(!data->state.engine) { + if(is_pkcs11_uri(cert_file)) { + if(Curl_ossl_set_engine(data, "pkcs11") != CURLE_OK) { + return 0; + } + } + } + + if(data->state.engine) { + const char *cmd_name = "LOAD_CERT_CTRL"; + struct { + const char *cert_id; + X509 *cert; + } params; + + params.cert_id = cert_file; + params.cert = NULL; + + /* Does the engine supports LOAD_CERT_CTRL ? */ + if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME, + 0, (void *)cmd_name, NULL)) { + failf(data, "ssl engine does not support loading certificates"); + return 0; + } + + /* Load the certificate from the engine */ + if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name, + 0, ¶ms, NULL, 1)) { + failf(data, "ssl engine cannot load client cert with id" + " '%s' [%s]", cert_file, + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return 0; + } + + if(!params.cert) { + failf(data, "ssl engine didn't initialized the certificate " + "properly."); + return 0; + } + + if(SSL_CTX_use_certificate(ctx, params.cert) != 1) { + failf(data, "unable to set client certificate"); + X509_free(params.cert); + return 0; + } + X509_free(params.cert); /* we don't need the handle any more... */ + } + else { + failf(data, "crypto engine not set, can't load certificate"); + return 0; + } + } + break; +#else + failf(data, "file type ENG for certificate not implemented"); + return 0; +#endif + + case SSL_FILETYPE_PKCS12: + { + BIO *fp = NULL; + PKCS12 *p12 = NULL; + EVP_PKEY *pri; + STACK_OF(X509) *ca = NULL; + + fp = BIO_new(BIO_s_file()); + if(fp == NULL) { + failf(data, + "BIO_new return NULL, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + return 0; + } + + if(BIO_read_filename(fp, cert_file) <= 0) { + failf(data, "could not open PKCS12 file '%s'", cert_file); + BIO_free(fp); + return 0; + } + p12 = d2i_PKCS12_bio(fp, NULL); + BIO_free(fp); + + if(!p12) { + failf(data, "error reading PKCS12 file '%s'", cert_file); + return 0; + } + + PKCS12_PBE_add(); + + if(!PKCS12_parse(p12, key_passwd, &pri, &x509, + &ca)) { + failf(data, + "could not parse PKCS12 file, check password, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + PKCS12_free(p12); + return 0; + } + + PKCS12_free(p12); + + if(SSL_CTX_use_certificate(ctx, x509) != 1) { + failf(data, + "could not load PKCS12 client certificate, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + goto fail; + } + + if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) { + failf(data, "unable to use private key from PKCS12 file '%s'", + cert_file); + goto fail; + } + + if(!SSL_CTX_check_private_key (ctx)) { + failf(data, "private key from PKCS12 file '%s' " + "does not match certificate in same file", cert_file); + goto fail; + } + /* Set Certificate Verification chain */ + if(ca) { + while(sk_X509_num(ca)) { + /* + * Note that sk_X509_pop() is used below to make sure the cert is + * removed from the stack properly before getting passed to + * SSL_CTX_add_extra_chain_cert(), which takes ownership. Previously + * we used sk_X509_value() instead, but then we'd clean it in the + * subsequent sk_X509_pop_free() call. + */ + X509 *x = sk_X509_pop(ca); + if(!SSL_CTX_add_client_CA(ctx, x)) { + X509_free(x); + failf(data, "cannot add certificate to client CA list"); + goto fail; + } + if(!SSL_CTX_add_extra_chain_cert(ctx, x)) { + X509_free(x); + failf(data, "cannot add certificate to certificate chain"); + goto fail; + } + } + } + + cert_done = 1; + fail: + EVP_PKEY_free(pri); + X509_free(x509); +#ifdef USE_AMISSL + sk_X509_pop_free(ca, Curl_amiga_X509_free); +#else + sk_X509_pop_free(ca, X509_free); +#endif + if(!cert_done) + return 0; /* failure! */ + break; + } + default: + failf(data, "not supported file type '%s' for certificate", cert_type); + return 0; + } + + if(!key_file) + key_file = cert_file; + else + file_type = do_file_type(key_type); + + switch(file_type) { + case SSL_FILETYPE_PEM: + if(cert_done) + break; + /* FALLTHROUGH */ + case SSL_FILETYPE_ASN1: + if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) { + failf(data, "unable to set private key file: '%s' type %s", + key_file, key_type?key_type:"PEM"); + return 0; + } + break; + case SSL_FILETYPE_ENGINE: +#ifdef USE_OPENSSL_ENGINE + { /* XXXX still needs some work */ + EVP_PKEY *priv_key = NULL; + + /* Implicitly use pkcs11 engine if none was provided and the + * key_file is a PKCS#11 URI */ + if(!data->state.engine) { + if(is_pkcs11_uri(key_file)) { + if(Curl_ossl_set_engine(data, "pkcs11") != CURLE_OK) { + return 0; + } + } + } + + if(data->state.engine) { + UI_METHOD *ui_method = + UI_create_method((char *)"curl user interface"); + if(!ui_method) { + failf(data, "unable do create " OSSL_PACKAGE + " user-interface method"); + return 0; + } + UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); + UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); + UI_method_set_reader(ui_method, ssl_ui_reader); + UI_method_set_writer(ui_method, ssl_ui_writer); + /* the typecast below was added to please mingw32 */ + priv_key = (EVP_PKEY *) + ENGINE_load_private_key(data->state.engine, key_file, + ui_method, + key_passwd); + UI_destroy_method(ui_method); + if(!priv_key) { + failf(data, "failed to load private key from crypto engine"); + return 0; + } + if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) { + failf(data, "unable to set private key"); + EVP_PKEY_free(priv_key); + return 0; + } + EVP_PKEY_free(priv_key); /* we don't need the handle any more... */ + } + else { + failf(data, "crypto engine not set, can't load private key"); + return 0; + } + } + break; +#else + failf(data, "file type ENG for private key not supported"); + return 0; +#endif + case SSL_FILETYPE_PKCS12: + if(!cert_done) { + failf(data, "file type P12 for private key not supported"); + return 0; + } + break; + default: + failf(data, "not supported file type for private key"); + return 0; + } + + ssl = SSL_new(ctx); + if(!ssl) { + failf(data, "unable to create an SSL structure"); + return 0; + } + + x509 = SSL_get_certificate(ssl); + + /* This version was provided by Evan Jordan and is supposed to not + leak memory as the previous version: */ + if(x509) { + EVP_PKEY *pktmp = X509_get_pubkey(x509); + EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl)); + EVP_PKEY_free(pktmp); + } + +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_IS_BORINGSSL) + { + /* If RSA is used, don't check the private key if its flags indicate + * it doesn't support it. */ + EVP_PKEY *priv_key = SSL_get_privatekey(ssl); + int pktype; +#ifdef HAVE_OPAQUE_EVP_PKEY + pktype = EVP_PKEY_id(priv_key); +#else + pktype = priv_key->type; +#endif + if(pktype == EVP_PKEY_RSA) { + RSA *rsa = EVP_PKEY_get1_RSA(priv_key); + if(RSA_flags(rsa) & RSA_METHOD_FLAG_NO_CHECK) + check_privkey = FALSE; + RSA_free(rsa); /* Decrement reference count */ + } + } +#endif + + SSL_free(ssl); + + /* If we are using DSA, we can copy the parameters from + * the private key */ + + if(check_privkey == TRUE) { + /* Now we know that a key and cert have been set against + * the SSL context */ + if(!SSL_CTX_check_private_key(ctx)) { + failf(data, "Private key does not match the certificate public key"); + return 0; + } + } + } + return 1; +} + +/* returns non-zero on failure */ +static int x509_name_oneline(X509_NAME *a, char *buf, size_t size) +{ +#if 0 + return X509_NAME_oneline(a, buf, size); +#else + BIO *bio_out = BIO_new(BIO_s_mem()); + BUF_MEM *biomem; + int rc; + + if(!bio_out) + return 1; /* alloc failed! */ + + rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC); + BIO_get_mem_ptr(bio_out, &biomem); + + if((size_t)biomem->length < size) + size = biomem->length; + else + size--; /* don't overwrite the buffer end */ + + memcpy(buf, biomem->data, size); + buf[size] = 0; + + BIO_free(bio_out); + + return !rc; +#endif +} + +/** + * Global SSL init + * + * @retval 0 error initializing SSL + * @retval 1 SSL initialized successfully + */ +static int Curl_ossl_init(void) +{ +#ifdef ENABLE_SSLKEYLOGFILE + char *keylog_file_name; +#endif + + OPENSSL_load_builtin_modules(); + +#ifdef USE_OPENSSL_ENGINE + ENGINE_load_builtin_engines(); +#endif + +/* CONF_MFLAGS_DEFAULT_SECTION was introduced some time between 0.9.8b and + 0.9.8e */ +#ifndef CONF_MFLAGS_DEFAULT_SECTION +#define CONF_MFLAGS_DEFAULT_SECTION 0x0 +#endif + +#ifndef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG + CONF_modules_load_file(NULL, NULL, + CONF_MFLAGS_DEFAULT_SECTION| + CONF_MFLAGS_IGNORE_MISSING_FILE); +#endif + +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \ + !defined(LIBRESSL_VERSION_NUMBER) + /* OpenSSL 1.1.0+ takes care of initialization itself */ +#else + /* Lets get nice error messages */ + SSL_load_error_strings(); + + /* Init the global ciphers and digests */ + if(!SSLeay_add_ssl_algorithms()) + return 0; + + OpenSSL_add_all_algorithms(); +#endif + +#ifdef ENABLE_SSLKEYLOGFILE + if(!keylog_file_fp) { + keylog_file_name = curl_getenv("SSLKEYLOGFILE"); + if(keylog_file_name) { + keylog_file_fp = fopen(keylog_file_name, FOPEN_APPENDTEXT); + if(keylog_file_fp) { +#ifdef WIN32 + if(setvbuf(keylog_file_fp, NULL, _IONBF, 0)) +#else + if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096)) +#endif + { + fclose(keylog_file_fp); + keylog_file_fp = NULL; + } + } + Curl_safefree(keylog_file_name); + } + } +#endif + + /* Initialize the extra data indexes */ + if(ossl_get_ssl_conn_index() < 0 || ossl_get_ssl_sockindex_index() < 0) + return 0; + + return 1; +} + +/* Global cleanup */ +static void Curl_ossl_cleanup(void) +{ +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \ + !defined(LIBRESSL_VERSION_NUMBER) + /* OpenSSL 1.1 deprecates all these cleanup functions and + turns them into no-ops in OpenSSL 1.0 compatibility mode */ +#else + /* Free ciphers and digests lists */ + EVP_cleanup(); + +#ifdef USE_OPENSSL_ENGINE + /* Free engine list */ + ENGINE_cleanup(); +#endif + + /* Free OpenSSL error strings */ + ERR_free_strings(); + + /* Free thread local error state, destroying hash upon zero refcount */ +#ifdef HAVE_ERR_REMOVE_THREAD_STATE + ERR_remove_thread_state(NULL); +#else + ERR_remove_state(0); +#endif + + /* Free all memory allocated by all configuration modules */ + CONF_modules_free(); + +#ifdef HAVE_SSL_COMP_FREE_COMPRESSION_METHODS + SSL_COMP_free_compression_methods(); +#endif +#endif + +#ifdef ENABLE_SSLKEYLOGFILE + if(keylog_file_fp) { + fclose(keylog_file_fp); + keylog_file_fp = NULL; + } +#endif +} + +/* + * This function is used to determine connection status. + * + * Return codes: + * 1 means the connection is still in place + * 0 means the connection has been closed + * -1 means the connection status is unknown + */ +static int Curl_ossl_check_cxn(struct connectdata *conn) +{ + /* SSL_peek takes data out of the raw recv buffer without peeking so we use + recv MSG_PEEK instead. Bug #795 */ +#ifdef MSG_PEEK + char buf; + ssize_t nread; + nread = recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf, + (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK); + if(nread == 0) + return 0; /* connection has been closed */ + if(nread == 1) + return 1; /* connection still in place */ + else if(nread == -1) { + int err = SOCKERRNO; + if(err == EINPROGRESS || +#if defined(EAGAIN) && (EAGAIN != EWOULDBLOCK) + err == EAGAIN || +#endif + err == EWOULDBLOCK) + return 1; /* connection still in place */ + if(err == ECONNRESET || +#ifdef ECONNABORTED + err == ECONNABORTED || +#endif +#ifdef ENETDOWN + err == ENETDOWN || +#endif +#ifdef ENETRESET + err == ENETRESET || +#endif +#ifdef ESHUTDOWN + err == ESHUTDOWN || +#endif +#ifdef ETIMEDOUT + err == ETIMEDOUT || +#endif + err == ENOTCONN) + return 0; /* connection has been closed */ + } +#endif + return -1; /* connection status unknown */ +} + +/* Selects an OpenSSL crypto engine + */ +static CURLcode Curl_ossl_set_engine(struct Curl_easy *data, + const char *engine) +{ +#ifdef USE_OPENSSL_ENGINE + ENGINE *e; + +#if OPENSSL_VERSION_NUMBER >= 0x00909000L + e = ENGINE_by_id(engine); +#else + /* avoid memory leak */ + for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) { + const char *e_id = ENGINE_get_id(e); + if(!strcmp(engine, e_id)) + break; + } +#endif + + if(!e) { + failf(data, "SSL Engine '%s' not found", engine); + return CURLE_SSL_ENGINE_NOTFOUND; + } + + if(data->state.engine) { + ENGINE_finish(data->state.engine); + ENGINE_free(data->state.engine); + data->state.engine = NULL; + } + if(!ENGINE_init(e)) { + char buf[256]; + + ENGINE_free(e); + failf(data, "Failed to initialise SSL Engine '%s':\n%s", + engine, ossl_strerror(ERR_get_error(), buf, sizeof(buf))); + return CURLE_SSL_ENGINE_INITFAILED; + } + data->state.engine = e; + return CURLE_OK; +#else + (void)engine; + failf(data, "SSL Engine not supported"); + return CURLE_SSL_ENGINE_NOTFOUND; +#endif +} + +/* Sets engine as default for all SSL operations + */ +static CURLcode Curl_ossl_set_engine_default(struct Curl_easy *data) +{ +#ifdef USE_OPENSSL_ENGINE + if(data->state.engine) { + if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) { + infof(data, "set default crypto engine '%s'\n", + ENGINE_get_id(data->state.engine)); + } + else { + failf(data, "set default crypto engine '%s' failed", + ENGINE_get_id(data->state.engine)); + return CURLE_SSL_ENGINE_SETFAILED; + } + } +#else + (void) data; +#endif + return CURLE_OK; +} + +/* Return list of OpenSSL crypto engine names. + */ +static struct curl_slist *Curl_ossl_engines_list(struct Curl_easy *data) +{ + struct curl_slist *list = NULL; +#ifdef USE_OPENSSL_ENGINE + struct curl_slist *beg; + ENGINE *e; + + for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) { + beg = curl_slist_append(list, ENGINE_get_id(e)); + if(!beg) { + curl_slist_free_all(list); + return NULL; + } + list = beg; + } +#endif + (void) data; + return list; +} + + +static void ossl_close(struct ssl_connect_data *connssl) +{ + if(BACKEND->handle) { + (void)SSL_shutdown(BACKEND->handle); + SSL_set_connect_state(BACKEND->handle); + + SSL_free(BACKEND->handle); + BACKEND->handle = NULL; + } + if(BACKEND->ctx) { + SSL_CTX_free(BACKEND->ctx); + BACKEND->ctx = NULL; + } +} + +/* + * This function is called when an SSL connection is closed. + */ +static void Curl_ossl_close(struct connectdata *conn, int sockindex) +{ + ossl_close(&conn->ssl[sockindex]); + ossl_close(&conn->proxy_ssl[sockindex]); +} + +/* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) + */ +static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) +{ + int retval = 0; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct Curl_easy *data = conn->data; + char buf[256]; /* We will use this for the OpenSSL error buffer, so it has + to be at least 256 bytes long. */ + unsigned long sslerror; + ssize_t nread; + int buffsize; + int err; + bool done = FALSE; + +#ifndef CURL_DISABLE_FTP + /* This has only been tested on the proftpd server, and the mod_tls code + sends a close notify alert without waiting for a close notify alert in + response. Thus we wait for a close notify alert from the server, but + we do not send one. Let's hope other servers do the same... */ + + if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) + (void)SSL_shutdown(BACKEND->handle); +#endif + + if(BACKEND->handle) { + buffsize = (int)sizeof(buf); + while(!done) { + int what = SOCKET_READABLE(conn->sock[sockindex], + SSL_SHUTDOWN_TIMEOUT); + if(what > 0) { + ERR_clear_error(); + + /* Something to read, let's do it and hope that it is the close + notify alert from the server */ + nread = (ssize_t)SSL_read(BACKEND->handle, buf, buffsize); + err = SSL_get_error(BACKEND->handle, (int)nread); + + switch(err) { + case SSL_ERROR_NONE: /* this is not an error */ + case SSL_ERROR_ZERO_RETURN: /* no more data */ + /* This is the expected response. There was no data but only + the close notify alert */ + done = TRUE; + break; + case SSL_ERROR_WANT_READ: + /* there's data pending, re-invoke SSL_read() */ + infof(data, "SSL_ERROR_WANT_READ\n"); + break; + case SSL_ERROR_WANT_WRITE: + /* SSL wants a write. Really odd. Let's bail out. */ + infof(data, "SSL_ERROR_WANT_WRITE\n"); + done = TRUE; + break; + default: + /* openssl/ssl.h says "look at error stack/return value/errno" */ + sslerror = ERR_get_error(); + failf(conn->data, OSSL_PACKAGE " SSL_read on shutdown: %s, errno %d", + (sslerror ? + ossl_strerror(sslerror, buf, sizeof(buf)) : + SSL_ERROR_to_str(err)), + SOCKERRNO); + done = TRUE; + break; + } + } + else if(0 == what) { + /* timeout */ + failf(data, "SSL shutdown timeout"); + done = TRUE; + } + else { + /* anything that gets here is fatally bad */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + retval = -1; + done = TRUE; + } + } /* while()-loop for the select() */ + + if(data->set.verbose) { +#ifdef HAVE_SSL_GET_SHUTDOWN + switch(SSL_get_shutdown(BACKEND->handle)) { + case SSL_SENT_SHUTDOWN: + infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n"); + break; + case SSL_RECEIVED_SHUTDOWN: + infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n"); + break; + case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN: + infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|" + "SSL_RECEIVED__SHUTDOWN\n"); + break; + } +#endif + } + + SSL_free(BACKEND->handle); + BACKEND->handle = NULL; + } + return retval; +} + +static void Curl_ossl_session_free(void *ptr) +{ + /* free the ID */ + SSL_SESSION_free(ptr); +} + +/* + * This function is called when the 'data' struct is going away. Close + * down everything and free all resources! + */ +static void Curl_ossl_close_all(struct Curl_easy *data) +{ +#ifdef USE_OPENSSL_ENGINE + if(data->state.engine) { + ENGINE_finish(data->state.engine); + ENGINE_free(data->state.engine); + data->state.engine = NULL; + } +#else + (void)data; +#endif +#if !defined(HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED) && \ + defined(HAVE_ERR_REMOVE_THREAD_STATE) + /* OpenSSL 1.0.1 and 1.0.2 build an error queue that is stored per-thread + so we need to clean it here in case the thread will be killed. All OpenSSL + code should extract the error in association with the error so clearing + this queue here should be harmless at worst. */ + ERR_remove_thread_state(NULL); +#endif +} + +/* ====================================================== */ + +/* + * Match subjectAltName against the host name. This requires a conversion + * in CURL_DOES_CONVERSIONS builds. + */ +static bool subj_alt_hostcheck(struct Curl_easy *data, + const char *match_pattern, const char *hostname, + const char *dispname) +#ifdef CURL_DOES_CONVERSIONS +{ + bool res = FALSE; + + /* Curl_cert_hostcheck uses host encoding, but we get ASCII from + OpenSSl. + */ + char *match_pattern2 = strdup(match_pattern); + + if(match_pattern2) { + if(Curl_convert_from_network(data, match_pattern2, + strlen(match_pattern2)) == CURLE_OK) { + if(Curl_cert_hostcheck(match_pattern2, hostname)) { + res = TRUE; + infof(data, + " subjectAltName: host \"%s\" matched cert's \"%s\"\n", + dispname, match_pattern2); + } + } + free(match_pattern2); + } + else { + failf(data, + "SSL: out of memory when allocating temporary for subjectAltName"); + } + return res; +} +#else +{ +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)dispname; + (void)data; +#endif + if(Curl_cert_hostcheck(match_pattern, hostname)) { + infof(data, " subjectAltName: host \"%s\" matched cert's \"%s\"\n", + dispname, match_pattern); + return TRUE; + } + return FALSE; +} +#endif + + +/* Quote from RFC2818 section 3.1 "Server Identity" + + If a subjectAltName extension of type dNSName is present, that MUST + be used as the identity. Otherwise, the (most specific) Common Name + field in the Subject field of the certificate MUST be used. Although + the use of the Common Name is existing practice, it is deprecated and + Certification Authorities are encouraged to use the dNSName instead. + + Matching is performed using the matching rules specified by + [RFC2459]. If more than one identity of a given type is present in + the certificate (e.g., more than one dNSName name, a match in any one + of the set is considered acceptable.) Names may contain the wildcard + character * which is considered to match any single domain name + component or component fragment. E.g., *.a.com matches foo.a.com but + not bar.foo.a.com. f*.com matches foo.com but not bar.com. + + In some cases, the URI is specified as an IP address rather than a + hostname. In this case, the iPAddress subjectAltName must be present + in the certificate and must exactly match the IP in the URI. + +*/ +static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert) +{ + bool matched = FALSE; + int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */ + size_t addrlen = 0; + struct Curl_easy *data = conn->data; + STACK_OF(GENERAL_NAME) *altnames; +#ifdef ENABLE_IPV6 + struct in6_addr addr; +#else + struct in_addr addr; +#endif + CURLcode result = CURLE_OK; + bool dNSName = FALSE; /* if a dNSName field exists in the cert */ + bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */ + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const char * const dispname = SSL_IS_PROXY() ? + conn->http_proxy.host.dispname : conn->host.dispname; + +#ifdef ENABLE_IPV6 + if(conn->bits.ipv6_ip && + Curl_inet_pton(AF_INET6, hostname, &addr)) { + target = GEN_IPADD; + addrlen = sizeof(struct in6_addr); + } + else +#endif + if(Curl_inet_pton(AF_INET, hostname, &addr)) { + target = GEN_IPADD; + addrlen = sizeof(struct in_addr); + } + + /* get a "list" of alternative names */ + altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL); + + if(altnames) { + int numalts; + int i; + bool dnsmatched = FALSE; + bool ipmatched = FALSE; + + /* get amount of alternatives, RFC2459 claims there MUST be at least + one, but we don't depend on it... */ + numalts = sk_GENERAL_NAME_num(altnames); + + /* loop through all alternatives - until a dnsmatch */ + for(i = 0; (i < numalts) && !dnsmatched; i++) { + /* get a handle to alternative name number i */ + const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i); + + if(check->type == GEN_DNS) + dNSName = TRUE; + else if(check->type == GEN_IPADD) + iPAddress = TRUE; + + /* only check alternatives of the same type the target is */ + if(check->type == target) { + /* get data and length */ + const char *altptr = (char *)ASN1_STRING_get0_data(check->d.ia5); + size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5); + + switch(target) { + case GEN_DNS: /* name/pattern comparison */ + /* The OpenSSL man page explicitly says: "In general it cannot be + assumed that the data returned by ASN1_STRING_data() is null + terminated or does not contain embedded nulls." But also that + "The actual format of the data will depend on the actual string + type itself: for example for and IA5String the data will be ASCII" + + Gisle researched the OpenSSL sources: + "I checked the 0.9.6 and 0.9.8 sources before my patch and + it always 0-terminates an IA5String." + */ + if((altlen == strlen(altptr)) && + /* if this isn't true, there was an embedded zero in the name + string and we cannot match it. */ + subj_alt_hostcheck(data, altptr, hostname, dispname)) { + dnsmatched = TRUE; + } + break; + + case GEN_IPADD: /* IP address comparison */ + /* compare alternative IP address if the data chunk is the same size + our server IP address is */ + if((altlen == addrlen) && !memcmp(altptr, &addr, altlen)) { + ipmatched = TRUE; + infof(data, + " subjectAltName: host \"%s\" matched cert's IP address!\n", + dispname); + } + break; + } + } + } + GENERAL_NAMES_free(altnames); + + if(dnsmatched || ipmatched) + matched = TRUE; + } + + if(matched) + /* an alternative name matched */ + ; + else if(dNSName || iPAddress) { + infof(data, " subjectAltName does not match %s\n", dispname); + failf(data, "SSL: no alternative certificate subject name matches " + "target host name '%s'", dispname); + result = CURLE_PEER_FAILED_VERIFICATION; + } + else { + /* we have to look to the last occurrence of a commonName in the + distinguished one to get the most significant one. */ + int j, i = -1; + + /* The following is done because of a bug in 0.9.6b */ + + unsigned char *nulstr = (unsigned char *)""; + unsigned char *peer_CN = nulstr; + + X509_NAME *name = X509_get_subject_name(server_cert); + if(name) + while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0) + i = j; + + /* we have the name entry and we will now convert this to a string + that we can use for comparison. Doing this we support BMPstring, + UTF8 etc. */ + + if(i >= 0) { + ASN1_STRING *tmp = + X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); + + /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input + is already UTF-8 encoded. We check for this case and copy the raw + string manually to avoid the problem. This code can be made + conditional in the future when OpenSSL has been fixed. Work-around + brought by Alexis S. L. Carvalho. */ + if(tmp) { + if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) { + j = ASN1_STRING_length(tmp); + if(j >= 0) { + peer_CN = OPENSSL_malloc(j + 1); + if(peer_CN) { + memcpy(peer_CN, ASN1_STRING_get0_data(tmp), j); + peer_CN[j] = '\0'; + } + } + } + else /* not a UTF8 name */ + j = ASN1_STRING_to_UTF8(&peer_CN, tmp); + + if(peer_CN && (curlx_uztosi(strlen((char *)peer_CN)) != j)) { + /* there was a terminating zero before the end of string, this + cannot match and we return failure! */ + failf(data, "SSL: illegal cert name field"); + result = CURLE_PEER_FAILED_VERIFICATION; + } + } + } + + if(peer_CN == nulstr) + peer_CN = NULL; + else { + /* convert peer_CN from UTF8 */ + CURLcode rc = Curl_convert_from_utf8(data, (char *)peer_CN, + strlen((char *)peer_CN)); + /* Curl_convert_from_utf8 calls failf if unsuccessful */ + if(rc) { + OPENSSL_free(peer_CN); + return rc; + } + } + + if(result) + /* error already detected, pass through */ + ; + else if(!peer_CN) { + failf(data, + "SSL: unable to obtain common name from peer certificate"); + result = CURLE_PEER_FAILED_VERIFICATION; + } + else if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) { + failf(data, "SSL: certificate subject name '%s' does not match " + "target host name '%s'", peer_CN, dispname); + result = CURLE_PEER_FAILED_VERIFICATION; + } + else { + infof(data, " common name: %s (matched)\n", peer_CN); + } + if(peer_CN) + OPENSSL_free(peer_CN); + } + + return result; +} + +#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ + !defined(OPENSSL_NO_OCSP) +static CURLcode verifystatus(struct connectdata *conn, + struct ssl_connect_data *connssl) +{ + int i, ocsp_status; + unsigned char *status; + const unsigned char *p; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + OCSP_RESPONSE *rsp = NULL; + OCSP_BASICRESP *br = NULL; + X509_STORE *st = NULL; + STACK_OF(X509) *ch = NULL; + + long len = SSL_get_tlsext_status_ocsp_resp(BACKEND->handle, &status); + + if(!status) { + failf(data, "No OCSP response received"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; + } + p = status; + rsp = d2i_OCSP_RESPONSE(NULL, &p, len); + if(!rsp) { + failf(data, "Invalid OCSP response"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; + } + + ocsp_status = OCSP_response_status(rsp); + if(ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { + failf(data, "Invalid OCSP response status: %s (%d)", + OCSP_response_status_str(ocsp_status), ocsp_status); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; + } + + br = OCSP_response_get1_basic(rsp); + if(!br) { + failf(data, "Invalid OCSP response"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; + } + + ch = SSL_get_peer_cert_chain(BACKEND->handle); + st = SSL_CTX_get_cert_store(BACKEND->ctx); + +#if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \ + (defined(LIBRESSL_VERSION_NUMBER) && \ + LIBRESSL_VERSION_NUMBER <= 0x2040200fL)) + /* The authorized responder cert in the OCSP response MUST be signed by the + peer cert's issuer (see RFC6960 section 4.2.2.2). If that's a root cert, + no problem, but if it's an intermediate cert OpenSSL has a bug where it + expects this issuer to be present in the chain embedded in the OCSP + response. So we add it if necessary. */ + + /* First make sure the peer cert chain includes both a peer and an issuer, + and the OCSP response contains a responder cert. */ + if(sk_X509_num(ch) >= 2 && sk_X509_num(br->certs) >= 1) { + X509 *responder = sk_X509_value(br->certs, sk_X509_num(br->certs) - 1); + + /* Find issuer of responder cert and add it to the OCSP response chain */ + for(i = 0; i < sk_X509_num(ch); i++) { + X509 *issuer = sk_X509_value(ch, i); + if(X509_check_issued(issuer, responder) == X509_V_OK) { + if(!OCSP_basic_add1_cert(br, issuer)) { + failf(data, "Could not add issuer cert to OCSP response"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; + } + } + } + } +#endif + + if(OCSP_basic_verify(br, ch, st, 0) <= 0) { + failf(data, "OCSP response verification failed"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; + } + + for(i = 0; i < OCSP_resp_count(br); i++) { + int cert_status, crl_reason; + OCSP_SINGLERESP *single = NULL; + + ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; + + single = OCSP_resp_get0(br, i); + if(!single) + continue; + + cert_status = OCSP_single_get0_status(single, &crl_reason, &rev, + &thisupd, &nextupd); + + if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) { + failf(data, "OCSP response has expired"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; + } + + infof(data, "SSL certificate status: %s (%d)\n", + OCSP_cert_status_str(cert_status), cert_status); + + switch(cert_status) { + case V_OCSP_CERTSTATUS_GOOD: + break; + + case V_OCSP_CERTSTATUS_REVOKED: + result = CURLE_SSL_INVALIDCERTSTATUS; + + failf(data, "SSL certificate revocation reason: %s (%d)", + OCSP_crl_reason_str(crl_reason), crl_reason); + goto end; + + case V_OCSP_CERTSTATUS_UNKNOWN: + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; + } + } + +end: + if(br) OCSP_BASICRESP_free(br); + OCSP_RESPONSE_free(rsp); + + return result; +} +#endif + +#endif /* USE_OPENSSL */ + +/* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions + and thus this cannot be done there. */ +#ifdef SSL_CTRL_SET_MSG_CALLBACK + +static const char *ssl_msg_type(int ssl_ver, int msg) +{ +#ifdef SSL2_VERSION_MAJOR + if(ssl_ver == SSL2_VERSION_MAJOR) { + switch(msg) { + case SSL2_MT_ERROR: + return "Error"; + case SSL2_MT_CLIENT_HELLO: + return "Client hello"; + case SSL2_MT_CLIENT_MASTER_KEY: + return "Client key"; + case SSL2_MT_CLIENT_FINISHED: + return "Client finished"; + case SSL2_MT_SERVER_HELLO: + return "Server hello"; + case SSL2_MT_SERVER_VERIFY: + return "Server verify"; + case SSL2_MT_SERVER_FINISHED: + return "Server finished"; + case SSL2_MT_REQUEST_CERTIFICATE: + return "Request CERT"; + case SSL2_MT_CLIENT_CERTIFICATE: + return "Client CERT"; + } + } + else +#endif + if(ssl_ver == SSL3_VERSION_MAJOR) { + switch(msg) { + case SSL3_MT_HELLO_REQUEST: + return "Hello request"; + case SSL3_MT_CLIENT_HELLO: + return "Client hello"; + case SSL3_MT_SERVER_HELLO: + return "Server hello"; +#ifdef SSL3_MT_NEWSESSION_TICKET + case SSL3_MT_NEWSESSION_TICKET: + return "Newsession Ticket"; +#endif + case SSL3_MT_CERTIFICATE: + return "Certificate"; + case SSL3_MT_SERVER_KEY_EXCHANGE: + return "Server key exchange"; + case SSL3_MT_CLIENT_KEY_EXCHANGE: + return "Client key exchange"; + case SSL3_MT_CERTIFICATE_REQUEST: + return "Request CERT"; + case SSL3_MT_SERVER_DONE: + return "Server finished"; + case SSL3_MT_CERTIFICATE_VERIFY: + return "CERT verify"; + case SSL3_MT_FINISHED: + return "Finished"; +#ifdef SSL3_MT_CERTIFICATE_STATUS + case SSL3_MT_CERTIFICATE_STATUS: + return "Certificate Status"; +#endif +#ifdef SSL3_MT_ENCRYPTED_EXTENSIONS + case SSL3_MT_ENCRYPTED_EXTENSIONS: + return "Encrypted Extensions"; +#endif +#ifdef SSL3_MT_END_OF_EARLY_DATA + case SSL3_MT_END_OF_EARLY_DATA: + return "End of early data"; +#endif +#ifdef SSL3_MT_KEY_UPDATE + case SSL3_MT_KEY_UPDATE: + return "Key update"; +#endif +#ifdef SSL3_MT_NEXT_PROTO + case SSL3_MT_NEXT_PROTO: + return "Next protocol"; +#endif +#ifdef SSL3_MT_MESSAGE_HASH + case SSL3_MT_MESSAGE_HASH: + return "Message hash"; +#endif + } + } + return "Unknown"; +} + +static const char *tls_rt_type(int type) +{ + switch(type) { +#ifdef SSL3_RT_HEADER + case SSL3_RT_HEADER: + return "TLS header"; +#endif + case SSL3_RT_CHANGE_CIPHER_SPEC: + return "TLS change cipher"; + case SSL3_RT_ALERT: + return "TLS alert"; + case SSL3_RT_HANDSHAKE: + return "TLS handshake"; + case SSL3_RT_APPLICATION_DATA: + return "TLS app data"; + default: + return "TLS Unknown"; + } +} + + +/* + * Our callback from the SSL/TLS layers. + */ +static void ssl_tls_trace(int direction, int ssl_ver, int content_type, + const void *buf, size_t len, SSL *ssl, + void *userp) +{ + struct Curl_easy *data; + char unknown[32]; + const char *verstr = NULL; + struct connectdata *conn = userp; + + if(!conn || !conn->data || !conn->data->set.fdebug || + (direction != 0 && direction != 1)) + return; + + data = conn->data; + + switch(ssl_ver) { +#ifdef SSL2_VERSION /* removed in recent versions */ + case SSL2_VERSION: + verstr = "SSLv2"; + break; +#endif +#ifdef SSL3_VERSION + case SSL3_VERSION: + verstr = "SSLv3"; + break; +#endif + case TLS1_VERSION: + verstr = "TLSv1.0"; + break; +#ifdef TLS1_1_VERSION + case TLS1_1_VERSION: + verstr = "TLSv1.1"; + break; +#endif +#ifdef TLS1_2_VERSION + case TLS1_2_VERSION: + verstr = "TLSv1.2"; + break; +#endif +#ifdef TLS1_3_VERSION + case TLS1_3_VERSION: + verstr = "TLSv1.3"; + break; +#endif + case 0: + break; + default: + msnprintf(unknown, sizeof(unknown), "(%x)", ssl_ver); + verstr = unknown; + break; + } + + /* Log progress for interesting records only (like Handshake or Alert), skip + * all raw record headers (content_type == SSL3_RT_HEADER or ssl_ver == 0). + * For TLS 1.3, skip notification of the decrypted inner Content Type. + */ + if(ssl_ver +#ifdef SSL3_RT_INNER_CONTENT_TYPE + && content_type != SSL3_RT_INNER_CONTENT_TYPE +#endif + ) { + const char *msg_name, *tls_rt_name; + char ssl_buf[1024]; + int msg_type, txt_len; + + /* the info given when the version is zero is not that useful for us */ + + ssl_ver >>= 8; /* check the upper 8 bits only below */ + + /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL + * always pass-up content-type as 0. But the interesting message-type + * is at 'buf[0]'. + */ + if(ssl_ver == SSL3_VERSION_MAJOR && content_type) + tls_rt_name = tls_rt_type(content_type); + else + tls_rt_name = ""; + + if(content_type == SSL3_RT_CHANGE_CIPHER_SPEC) { + msg_type = *(char *)buf; + msg_name = "Change cipher spec"; + } + else if(content_type == SSL3_RT_ALERT) { + msg_type = (((char *)buf)[0] << 8) + ((char *)buf)[1]; + msg_name = SSL_alert_desc_string_long(msg_type); + } + else { + msg_type = *(char *)buf; + msg_name = ssl_msg_type(ssl_ver, msg_type); + } + + txt_len = msnprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n", + verstr, direction?"OUT":"IN", + tls_rt_name, msg_name, msg_type); + if(0 <= txt_len && (unsigned)txt_len < sizeof(ssl_buf)) { + Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len); + } + } + + Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT : + CURLINFO_SSL_DATA_IN, (char *)buf, len); + (void) ssl; +} +#endif + +#ifdef USE_OPENSSL +/* ====================================================== */ + +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME +# define use_sni(x) sni = (x) +#else +# define use_sni(x) Curl_nop_stmt +#endif + +/* Check for OpenSSL 1.0.2 which has ALPN support. */ +#undef HAS_ALPN +#if OPENSSL_VERSION_NUMBER >= 0x10002000L \ + && !defined(OPENSSL_NO_TLSEXT) +# define HAS_ALPN 1 +#endif + +/* Check for OpenSSL 1.0.1 which has NPN support. */ +#undef HAS_NPN +#if OPENSSL_VERSION_NUMBER >= 0x10001000L \ + && !defined(OPENSSL_NO_TLSEXT) \ + && !defined(OPENSSL_NO_NEXTPROTONEG) +# define HAS_NPN 1 +#endif + +#ifdef HAS_NPN + +/* + * in is a list of length prefixed strings. this function has to select + * the protocol we want to use from the list and write its string into out. + */ + +static int +select_next_protocol(unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + const char *key, unsigned int keylen) +{ + unsigned int i; + for(i = 0; i + keylen <= inlen; i += in[i] + 1) { + if(memcmp(&in[i + 1], key, keylen) == 0) { + *out = (unsigned char *) &in[i + 1]; + *outlen = in[i]; + return 0; + } + } + return -1; +} + +static int +select_next_proto_cb(SSL *ssl, + unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + void *arg) +{ + struct connectdata *conn = (struct connectdata*) arg; + + (void)ssl; + +#ifdef USE_NGHTTP2 + if(conn->data->set.httpversion >= CURL_HTTP_VERSION_2 && + !select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID, + NGHTTP2_PROTO_VERSION_ID_LEN)) { + infof(conn->data, "NPN, negotiated HTTP2 (%s)\n", + NGHTTP2_PROTO_VERSION_ID); + conn->negnpn = CURL_HTTP_VERSION_2; + return SSL_TLSEXT_ERR_OK; + } +#endif + + if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1, + ALPN_HTTP_1_1_LENGTH)) { + infof(conn->data, "NPN, negotiated HTTP1.1\n"); + conn->negnpn = CURL_HTTP_VERSION_1_1; + return SSL_TLSEXT_ERR_OK; + } + + infof(conn->data, "NPN, no overlap, use HTTP1.1\n"); + *out = (unsigned char *)ALPN_HTTP_1_1; + *outlen = ALPN_HTTP_1_1_LENGTH; + conn->negnpn = CURL_HTTP_VERSION_1_1; + + return SSL_TLSEXT_ERR_OK; +} +#endif /* HAS_NPN */ + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static const char * +get_ssl_version_txt(SSL *ssl) +{ + if(!ssl) + return ""; + + switch(SSL_version(ssl)) { +#ifdef TLS1_3_VERSION + case TLS1_3_VERSION: + return "TLSv1.3"; +#endif +#if OPENSSL_VERSION_NUMBER >= 0x1000100FL + case TLS1_2_VERSION: + return "TLSv1.2"; + case TLS1_1_VERSION: + return "TLSv1.1"; +#endif + case TLS1_VERSION: + return "TLSv1.0"; + case SSL3_VERSION: + return "SSLv3"; + case SSL2_VERSION: + return "SSLv2"; + } + return "unknown"; +} +#endif + +static CURLcode +set_ssl_version_min_max(long *ctx_options, struct connectdata *conn, + int sockindex) +{ +#if (OPENSSL_VERSION_NUMBER < 0x1000100FL) || !defined(TLS1_3_VERSION) + /* convoluted #if condition just to avoid compiler warnings on unused + variable */ + struct Curl_easy *data = conn->data; +#endif + long ssl_version = SSL_CONN_CONFIG(version); + long ssl_version_max = SSL_CONN_CONFIG(version_max); + + switch(ssl_version) { + case CURL_SSLVERSION_TLSv1_3: +#ifdef TLS1_3_VERSION + { + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + SSL_CTX_set_max_proto_version(BACKEND->ctx, TLS1_3_VERSION); + *ctx_options |= SSL_OP_NO_TLSv1_2; + } +#else + (void)sockindex; + (void)ctx_options; + failf(data, OSSL_PACKAGE " was built without TLS 1.3 support"); + return CURLE_NOT_BUILT_IN; +#endif + /* FALLTHROUGH */ + case CURL_SSLVERSION_TLSv1_2: +#if OPENSSL_VERSION_NUMBER >= 0x1000100FL + *ctx_options |= SSL_OP_NO_TLSv1_1; +#else + failf(data, OSSL_PACKAGE " was built without TLS 1.2 support"); + return CURLE_NOT_BUILT_IN; +#endif + /* FALLTHROUGH */ + case CURL_SSLVERSION_TLSv1_1: +#if OPENSSL_VERSION_NUMBER >= 0x1000100FL + *ctx_options |= SSL_OP_NO_TLSv1; +#else + failf(data, OSSL_PACKAGE " was built without TLS 1.1 support"); + return CURLE_NOT_BUILT_IN; +#endif + /* FALLTHROUGH */ + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1: + break; + } + + switch(ssl_version_max) { + case CURL_SSLVERSION_MAX_TLSv1_0: +#if OPENSSL_VERSION_NUMBER >= 0x1000100FL + *ctx_options |= SSL_OP_NO_TLSv1_1; +#endif + /* FALLTHROUGH */ + case CURL_SSLVERSION_MAX_TLSv1_1: +#if OPENSSL_VERSION_NUMBER >= 0x1000100FL + *ctx_options |= SSL_OP_NO_TLSv1_2; +#endif + /* FALLTHROUGH */ + case CURL_SSLVERSION_MAX_TLSv1_2: +#ifdef TLS1_3_VERSION + *ctx_options |= SSL_OP_NO_TLSv1_3; +#endif + break; + case CURL_SSLVERSION_MAX_TLSv1_3: +#ifdef TLS1_3_VERSION + break; +#else + failf(data, OSSL_PACKAGE " was built without TLS 1.3 support"); + return CURLE_NOT_BUILT_IN; +#endif + } + return CURLE_OK; +} + +/* The "new session" callback must return zero if the session can be removed + * or non-zero if the session has been put into the session cache. + */ +static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) +{ + int res = 0; + struct connectdata *conn; + struct Curl_easy *data; + int sockindex; + curl_socket_t *sockindex_ptr; + int connectdata_idx = ossl_get_ssl_conn_index(); + int sockindex_idx = ossl_get_ssl_sockindex_index(); + + if(connectdata_idx < 0 || sockindex_idx < 0) + return 0; + + conn = (struct connectdata*) SSL_get_ex_data(ssl, connectdata_idx); + if(!conn) + return 0; + + data = conn->data; + + /* The sockindex has been stored as a pointer to an array element */ + sockindex_ptr = (curl_socket_t*) SSL_get_ex_data(ssl, sockindex_idx); + sockindex = (int)(sockindex_ptr - conn->sock); + + if(SSL_SET_OPTION(primary.sessionid)) { + bool incache; + void *old_ssl_sessionid = NULL; + + Curl_ssl_sessionid_lock(conn); + incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, + sockindex)); + if(incache) { + if(old_ssl_sessionid != ssl_sessionid) { + infof(data, "old SSL session ID is stale, removing\n"); + Curl_ssl_delsessionid(conn, old_ssl_sessionid); + incache = FALSE; + } + } + + if(!incache) { + if(!Curl_ssl_addsessionid(conn, ssl_sessionid, + 0 /* unknown size */, sockindex)) { + /* the session has been put into the session cache */ + res = 1; + } + else + failf(data, "failed to store ssl session"); + } + Curl_ssl_sessionid_unlock(conn); + } + + return res; +} + +static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) +{ + CURLcode result = CURLE_OK; + char *ciphers; + struct Curl_easy *data = conn->data; + SSL_METHOD_QUAL SSL_METHOD *req_method = NULL; + X509_LOOKUP *lookup = NULL; + curl_socket_t sockfd = conn->sock[sockindex]; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + long ctx_options = 0; +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + bool sni; + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; +#ifdef ENABLE_IPV6 + struct in6_addr addr; +#else + struct in_addr addr; +#endif +#endif + long * const certverifyresult = SSL_IS_PROXY() ? + &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; + const long int ssl_version = SSL_CONN_CONFIG(version); +#ifdef USE_TLS_SRP + const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype); +#endif + char * const ssl_cert = SSL_SET_OPTION(cert); + const char * const ssl_cert_type = SSL_SET_OPTION(cert_type); + const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const char * const ssl_capath = SSL_CONN_CONFIG(CApath); + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); + const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); + char error_buffer[256]; + + DEBUGASSERT(ssl_connect_1 == connssl->connecting_state); + + /* Make funny stuff to get random input */ + result = Curl_ossl_seed(data); + if(result) + return result; + + *certverifyresult = !X509_V_OK; + + /* check to see if we've been told to use an explicit SSL/TLS version */ + + switch(ssl_version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + /* it will be handled later with the context options */ +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) + req_method = TLS_client_method(); +#else + req_method = SSLv23_client_method(); +#endif + use_sni(TRUE); + break; + case CURL_SSLVERSION_SSLv2: +#ifdef OPENSSL_NO_SSL2 + failf(data, OSSL_PACKAGE " was built without SSLv2 support"); + return CURLE_NOT_BUILT_IN; +#else +#ifdef USE_TLS_SRP + if(ssl_authtype == CURL_TLSAUTH_SRP) + return CURLE_SSL_CONNECT_ERROR; +#endif + req_method = SSLv2_client_method(); + use_sni(FALSE); + break; +#endif + case CURL_SSLVERSION_SSLv3: +#ifdef OPENSSL_NO_SSL3_METHOD + failf(data, OSSL_PACKAGE " was built without SSLv3 support"); + return CURLE_NOT_BUILT_IN; +#else +#ifdef USE_TLS_SRP + if(ssl_authtype == CURL_TLSAUTH_SRP) + return CURLE_SSL_CONNECT_ERROR; +#endif + req_method = SSLv3_client_method(); + use_sni(FALSE); + break; +#endif + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + if(BACKEND->ctx) + SSL_CTX_free(BACKEND->ctx); + BACKEND->ctx = SSL_CTX_new(req_method); + + if(!BACKEND->ctx) { + failf(data, "SSL: couldn't create a context: %s", + ossl_strerror(ERR_peek_error(), error_buffer, sizeof(error_buffer))); + return CURLE_OUT_OF_MEMORY; + } + +#ifdef SSL_MODE_RELEASE_BUFFERS + SSL_CTX_set_mode(BACKEND->ctx, SSL_MODE_RELEASE_BUFFERS); +#endif + +#ifdef SSL_CTRL_SET_MSG_CALLBACK + if(data->set.fdebug && data->set.verbose) { + /* the SSL trace callback is only used for verbose logging */ + SSL_CTX_set_msg_callback(BACKEND->ctx, ssl_tls_trace); + SSL_CTX_set_msg_callback_arg(BACKEND->ctx, conn); + } +#endif + + /* OpenSSL contains code to work-around lots of bugs and flaws in various + SSL-implementations. SSL_CTX_set_options() is used to enabled those + work-arounds. The man page for this option states that SSL_OP_ALL enables + all the work-arounds and that "It is usually safe to use SSL_OP_ALL to + enable the bug workaround options if compatibility with somewhat broken + implementations is desired." + + The "-no_ticket" option was introduced in Openssl0.9.8j. It's a flag to + disable "rfc4507bis session ticket support". rfc4507bis was later turned + into the proper RFC5077 it seems: https://tools.ietf.org/html/rfc5077 + + The enabled extension concerns the session management. I wonder how often + libcurl stops a connection and then resumes a TLS session. also, sending + the session data is some overhead. .I suggest that you just use your + proposed patch (which explicitly disables TICKET). + + If someone writes an application with libcurl and openssl who wants to + enable the feature, one can do this in the SSL callback. + + SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper + interoperability with web server Netscape Enterprise Server 2.0.1 which + was released back in 1996. + + Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has + become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate + CVE-2010-4180 when using previous OpenSSL versions we no longer enable + this option regardless of OpenSSL version and SSL_OP_ALL definition. + + OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability + (https://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to + SSL_OP_ALL that _disables_ that work-around despite the fact that + SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to + keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit + must not be set. + */ + + ctx_options = SSL_OP_ALL; + +#ifdef SSL_OP_NO_TICKET + ctx_options |= SSL_OP_NO_TICKET; +#endif + +#ifdef SSL_OP_NO_COMPRESSION + ctx_options |= SSL_OP_NO_COMPRESSION; +#endif + +#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG + /* mitigate CVE-2010-4180 */ + ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; +#endif + +#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS + /* unless the user explicitly ask to allow the protocol vulnerability we + use the work-around */ + if(!SSL_SET_OPTION(enable_beast)) + ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; +#endif + + switch(ssl_version) { + case CURL_SSLVERSION_SSLv3: + ctx_options |= SSL_OP_NO_SSLv2; + ctx_options |= SSL_OP_NO_TLSv1; +#if OPENSSL_VERSION_NUMBER >= 0x1000100FL + ctx_options |= SSL_OP_NO_TLSv1_1; + ctx_options |= SSL_OP_NO_TLSv1_2; +#ifdef TLS1_3_VERSION + ctx_options |= SSL_OP_NO_TLSv1_3; +#endif +#endif + break; + + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + /* asking for any TLS version as the minimum, means no SSL versions + allowed */ + ctx_options |= SSL_OP_NO_SSLv2; + ctx_options |= SSL_OP_NO_SSLv3; + result = set_ssl_version_min_max(&ctx_options, conn, sockindex); + if(result != CURLE_OK) + return result; + break; + + case CURL_SSLVERSION_SSLv2: + ctx_options |= SSL_OP_NO_SSLv3; + ctx_options |= SSL_OP_NO_TLSv1; +#if OPENSSL_VERSION_NUMBER >= 0x1000100FL + ctx_options |= SSL_OP_NO_TLSv1_1; + ctx_options |= SSL_OP_NO_TLSv1_2; +#ifdef TLS1_3_VERSION + ctx_options |= SSL_OP_NO_TLSv1_3; +#endif +#endif + break; + + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + SSL_CTX_set_options(BACKEND->ctx, ctx_options); + +#ifdef HAS_NPN + if(conn->bits.tls_enable_npn) + SSL_CTX_set_next_proto_select_cb(BACKEND->ctx, select_next_proto_cb, conn); +#endif + +#ifdef HAS_ALPN + if(conn->bits.tls_enable_alpn) { + int cur = 0; + unsigned char protocols[128]; + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2 && + (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) { + protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN; + + memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID, + NGHTTP2_PROTO_VERSION_ID_LEN); + cur += NGHTTP2_PROTO_VERSION_ID_LEN; + infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + protocols[cur++] = ALPN_HTTP_1_1_LENGTH; + memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH); + cur += ALPN_HTTP_1_1_LENGTH; + infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + + /* expects length prefixed preference ordered list of protocols in wire + * format + */ + SSL_CTX_set_alpn_protos(BACKEND->ctx, protocols, cur); + } +#endif + + if(ssl_cert || ssl_cert_type) { + if(!cert_stuff(conn, BACKEND->ctx, ssl_cert, ssl_cert_type, + SSL_SET_OPTION(key), SSL_SET_OPTION(key_type), + SSL_SET_OPTION(key_passwd))) { + /* failf() is already done in cert_stuff() */ + return CURLE_SSL_CERTPROBLEM; + } + } + + ciphers = SSL_CONN_CONFIG(cipher_list); + if(!ciphers) + ciphers = (char *)DEFAULT_CIPHER_SELECTION; + if(ciphers) { + if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) { + failf(data, "failed setting cipher list: %s", ciphers); + return CURLE_SSL_CIPHER; + } + infof(data, "Cipher selection: %s\n", ciphers); + } + +#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES + { + char *ciphers13 = SSL_CONN_CONFIG(cipher_list13); + if(ciphers13) { + if(!SSL_CTX_set_ciphersuites(BACKEND->ctx, ciphers13)) { + failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13); + return CURLE_SSL_CIPHER; + } + infof(data, "TLS 1.3 cipher selection: %s\n", ciphers13); + } + } +#endif + +#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH + /* OpenSSL 1.1.1 requires clients to opt-in for PHA */ + SSL_CTX_set_post_handshake_auth(BACKEND->ctx, 1); +#endif + +#ifdef USE_TLS_SRP + if(ssl_authtype == CURL_TLSAUTH_SRP) { + char * const ssl_username = SSL_SET_OPTION(username); + + infof(data, "Using TLS-SRP username: %s\n", ssl_username); + + if(!SSL_CTX_set_srp_username(BACKEND->ctx, ssl_username)) { + failf(data, "Unable to set SRP user name"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + if(!SSL_CTX_set_srp_password(BACKEND->ctx, SSL_SET_OPTION(password))) { + failf(data, "failed setting SRP password"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } + if(!SSL_CONN_CONFIG(cipher_list)) { + infof(data, "Setting cipher list SRP\n"); + + if(!SSL_CTX_set_cipher_list(BACKEND->ctx, "SRP")) { + failf(data, "failed setting SRP cipher list"); + return CURLE_SSL_CIPHER; + } + } + } +#endif + + if(ssl_cafile || ssl_capath) { + /* tell SSL where to find CA certificates that are used to verify + the servers certificate. */ + if(!SSL_CTX_load_verify_locations(BACKEND->ctx, ssl_cafile, ssl_capath)) { + if(verifypeer) { + /* Fail if we insist on successfully verifying the server. */ + failf(data, "error setting certificate verify locations:\n" + " CAfile: %s\n CApath: %s", + ssl_cafile ? ssl_cafile : "none", + ssl_capath ? ssl_capath : "none"); + return CURLE_SSL_CACERT_BADFILE; + } + /* Just continue with a warning if no strict certificate verification + is required. */ + infof(data, "error setting certificate verify locations," + " continuing anyway:\n"); + } + else { + /* Everything is fine. */ + infof(data, "successfully set certificate verify locations:\n"); + } + infof(data, + " CAfile: %s\n" + " CApath: %s\n", + ssl_cafile ? ssl_cafile : "none", + ssl_capath ? ssl_capath : "none"); + } +#ifdef CURL_CA_FALLBACK + else if(verifypeer) { + /* verifying the peer without any CA certificates won't + work so use openssl's built in default as fallback */ + SSL_CTX_set_default_verify_paths(BACKEND->ctx); + } +#endif + + if(ssl_crlfile) { + /* tell SSL where to find CRL file that is used to check certificate + * revocation */ + lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(BACKEND->ctx), + X509_LOOKUP_file()); + if(!lookup || + (!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) { + failf(data, "error loading CRL file: %s", ssl_crlfile); + return CURLE_SSL_CRL_BADFILE; + } + /* Everything is fine. */ + infof(data, "successfully load CRL file:\n"); + X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), + X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); + + infof(data, " CRLfile: %s\n", ssl_crlfile); + } + + /* Try building a chain using issuers in the trusted store first to avoid + problems with server-sent legacy intermediates. + Newer versions of OpenSSL do alternate chain checking by default which + gives us the same fix without as much of a performance hit (slight), so we + prefer that if available. + https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest + */ +#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS) + if(verifypeer) { + X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), + X509_V_FLAG_TRUSTED_FIRST); + } +#endif + + /* SSL always tries to verify the peer, this only says whether it should + * fail to connect if the verification fails, or if it should continue + * anyway. In the latter case the result of the verification is checked with + * SSL_get_verify_result() below. */ + SSL_CTX_set_verify(BACKEND->ctx, + verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); + + /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */ +#if defined(ENABLE_SSLKEYLOGFILE) && defined(HAVE_KEYLOG_CALLBACK) + if(keylog_file_fp) { + SSL_CTX_set_keylog_callback(BACKEND->ctx, ossl_keylog_callback); + } +#endif + + /* Enable the session cache because it's a prerequisite for the "new session" + * callback. Use the "external storage" mode to avoid that OpenSSL creates + * an internal session cache. + */ + SSL_CTX_set_session_cache_mode(BACKEND->ctx, + SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL); + SSL_CTX_sess_set_new_cb(BACKEND->ctx, ossl_new_session_cb); + + /* give application a chance to interfere with SSL set up. */ + if(data->set.ssl.fsslctx) { + result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx, + data->set.ssl.fsslctxp); + if(result) { + failf(data, "error signaled by ssl ctx callback"); + return result; + } + } + + /* Lets make an SSL structure */ + if(BACKEND->handle) + SSL_free(BACKEND->handle); + BACKEND->handle = SSL_new(BACKEND->ctx); + if(!BACKEND->handle) { + failf(data, "SSL: couldn't create a context (handle)!"); + return CURLE_OUT_OF_MEMORY; + } + +#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ + !defined(OPENSSL_NO_OCSP) + if(SSL_CONN_CONFIG(verifystatus)) + SSL_set_tlsext_status_type(BACKEND->handle, TLSEXT_STATUSTYPE_ocsp); +#endif + +#if defined(OPENSSL_IS_BORINGSSL) && defined(ALLOW_RENEG) + SSL_set_renegotiate_mode(BACKEND->handle, ssl_renegotiate_freely); +#endif + + SSL_set_connect_state(BACKEND->handle); + + BACKEND->server_cert = 0x0; +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) && +#ifdef ENABLE_IPV6 + (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) && +#endif + sni && + !SSL_set_tlsext_host_name(BACKEND->handle, hostname)) + infof(data, "WARNING: failed to configure server name indication (SNI) " + "TLS extension\n"); +#endif + + /* Check if there's a cached ID we can/should use here! */ + if(SSL_SET_OPTION(primary.sessionid)) { + void *ssl_sessionid = NULL; + int connectdata_idx = ossl_get_ssl_conn_index(); + int sockindex_idx = ossl_get_ssl_sockindex_index(); + + if(connectdata_idx >= 0 && sockindex_idx >= 0) { + /* Store the data needed for the "new session" callback. + * The sockindex is stored as a pointer to an array element. */ + SSL_set_ex_data(BACKEND->handle, connectdata_idx, conn); + SSL_set_ex_data(BACKEND->handle, sockindex_idx, conn->sock + sockindex); + } + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { + /* we got a session id, use it! */ + if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "SSL: SSL_set_session failed: %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return CURLE_SSL_CONNECT_ERROR; + } + /* Informational message */ + infof(data, "SSL re-using session ID\n"); + } + Curl_ssl_sessionid_unlock(conn); + } + + if(conn->proxy_ssl[sockindex].use) { + BIO *const bio = BIO_new(BIO_f_ssl()); + SSL *handle = conn->proxy_ssl[sockindex].backend->handle; + DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state); + DEBUGASSERT(handle != NULL); + DEBUGASSERT(bio != NULL); + BIO_set_ssl(bio, handle, FALSE); + SSL_set_bio(BACKEND->handle, bio, bio); + } + else if(!SSL_set_fd(BACKEND->handle, (int)sockfd)) { + /* pass the raw socket into the SSL layers */ + failf(data, "SSL: SSL_set_fd failed: %s", + ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer))); + return CURLE_SSL_CONNECT_ERROR; + } + + connssl->connecting_state = ssl_connect_2; + + return CURLE_OK; +} + +static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + int err; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + long * const certverifyresult = SSL_IS_PROXY() ? + &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; + DEBUGASSERT(ssl_connect_2 == connssl->connecting_state + || ssl_connect_2_reading == connssl->connecting_state + || ssl_connect_2_writing == connssl->connecting_state); + + ERR_clear_error(); + + err = SSL_connect(BACKEND->handle); + /* If keylogging is enabled but the keylog callback is not supported then log + secrets here, immediately after SSL_connect by using tap_ssl_key. */ +#if defined(ENABLE_SSLKEYLOGFILE) && !defined(HAVE_KEYLOG_CALLBACK) + tap_ssl_key(BACKEND->handle, &BACKEND->tap_state); +#endif + + /* 1 is fine + 0 is "not successful but was shut down controlled" + <0 is "handshake was not successful, because a fatal error occurred" */ + if(1 != err) { + int detail = SSL_get_error(BACKEND->handle, err); + + if(SSL_ERROR_WANT_READ == detail) { + connssl->connecting_state = ssl_connect_2_reading; + return CURLE_OK; + } + if(SSL_ERROR_WANT_WRITE == detail) { + connssl->connecting_state = ssl_connect_2_writing; + return CURLE_OK; + } +#ifdef SSL_ERROR_WANT_ASYNC + if(SSL_ERROR_WANT_ASYNC == detail) { + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; + } +#endif + else { + /* untreated error */ + unsigned long errdetail; + char error_buffer[256]=""; + CURLcode result; + long lerr; + int lib; + int reason; + + /* the connection failed, we're not waiting for anything else. */ + connssl->connecting_state = ssl_connect_2; + + /* Get the earliest error code from the thread's error queue and removes + the entry. */ + errdetail = ERR_get_error(); + + /* Extract which lib and reason */ + lib = ERR_GET_LIB(errdetail); + reason = ERR_GET_REASON(errdetail); + + if((lib == ERR_LIB_SSL) && + (reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) { + result = CURLE_PEER_FAILED_VERIFICATION; + + lerr = SSL_get_verify_result(BACKEND->handle); + if(lerr != X509_V_OK) { + *certverifyresult = lerr; + msnprintf(error_buffer, sizeof(error_buffer), + "SSL certificate problem: %s", + X509_verify_cert_error_string(lerr)); + } + else + /* strcpy() is fine here as long as the string fits within + error_buffer */ + strcpy(error_buffer, "SSL certificate verification failed"); + } + else { + result = CURLE_SSL_CONNECT_ERROR; + ossl_strerror(errdetail, error_buffer, sizeof(error_buffer)); + } + + /* detail is already set to the SSL error above */ + + /* If we e.g. use SSLv2 request-method and the server doesn't like us + * (RST connection etc.), OpenSSL gives no explanation whatsoever and + * the SO_ERROR is also lost. + */ + if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) { + const char * const hostname = SSL_IS_PROXY() ? + conn->http_proxy.host.name : conn->host.name; + const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; + failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%ld ", + SSL_ERROR_to_str(detail), hostname, port); + return result; + } + + /* Could be a CERT problem */ + failf(data, "%s", error_buffer); + + return result; + } + } + else { + /* we have been connected fine, we're not waiting for anything else. */ + connssl->connecting_state = ssl_connect_3; + + /* Informational message */ + infof(data, "SSL connection using %s / %s\n", + get_ssl_version_txt(BACKEND->handle), + SSL_get_cipher(BACKEND->handle)); + +#ifdef HAS_ALPN + /* Sets data and len to negotiated protocol, len is 0 if no protocol was + * negotiated + */ + if(conn->bits.tls_enable_alpn) { + const unsigned char *neg_protocol; + unsigned int len; + SSL_get0_alpn_selected(BACKEND->handle, &neg_protocol, &len); + if(len != 0) { + infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol); + +#ifdef USE_NGHTTP2 + if(len == NGHTTP2_PROTO_VERSION_ID_LEN && + !memcmp(NGHTTP2_PROTO_VERSION_ID, neg_protocol, len)) { + conn->negnpn = CURL_HTTP_VERSION_2; + } + else +#endif + if(len == ALPN_HTTP_1_1_LENGTH && + !memcmp(ALPN_HTTP_1_1, neg_protocol, ALPN_HTTP_1_1_LENGTH)) { + conn->negnpn = CURL_HTTP_VERSION_1_1; + } + } + else + infof(data, "ALPN, server did not agree to a protocol\n"); + + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + } +#endif + + return CURLE_OK; + } +} + +static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len) +{ + int i, ilen; + + ilen = (int)len; + if(ilen < 0) + return 1; /* buffer too big */ + + i = i2t_ASN1_OBJECT(buf, ilen, a); + + if(i >= ilen) + return 1; /* buffer too small */ + + return 0; +} + +#define push_certinfo(_label, _num) \ +do { \ + long info_len = BIO_get_mem_data(mem, &ptr); \ + Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \ + if(1 != BIO_reset(mem)) \ + break; \ +} WHILE_FALSE + +static void pubkey_show(struct Curl_easy *data, + BIO *mem, + int num, + const char *type, + const char *name, +#ifdef HAVE_OPAQUE_RSA_DSA_DH + const +#endif + BIGNUM *bn) +{ + char *ptr; + char namebuf[32]; + + msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name); + + if(bn) + BN_print(mem, bn); + push_certinfo(namebuf, num); +} + +#ifdef HAVE_OPAQUE_RSA_DSA_DH +#define print_pubkey_BN(_type, _name, _num) \ + pubkey_show(data, mem, _num, #_type, #_name, _name) + +#else +#define print_pubkey_BN(_type, _name, _num) \ +do { \ + if(_type->_name) { \ + pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \ + } \ +} WHILE_FALSE +#endif + +static int X509V3_ext(struct Curl_easy *data, + int certnum, + CONST_EXTS STACK_OF(X509_EXTENSION) *exts) +{ + int i; + size_t j; + + if((int)sk_X509_EXTENSION_num(exts) <= 0) + /* no extensions, bail out */ + return 1; + + for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) { + ASN1_OBJECT *obj; + X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); + BUF_MEM *biomem; + char buf[512]; + char *ptr = buf; + char namebuf[128]; + BIO *bio_out = BIO_new(BIO_s_mem()); + + if(!bio_out) + return 1; + + obj = X509_EXTENSION_get_object(ext); + + asn1_object_dump(obj, namebuf, sizeof(namebuf)); + + if(!X509V3_EXT_print(bio_out, ext, 0, 0)) + ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext)); + + BIO_get_mem_ptr(bio_out, &biomem); + + for(j = 0; j < (size_t)biomem->length; j++) { + const char *sep = ""; + if(biomem->data[j] == '\n') { + sep = ", "; + j++; /* skip the newline */ + }; + while((j<(size_t)biomem->length) && (biomem->data[j] == ' ')) + j++; + if(j<(size_t)biomem->length) + ptr += msnprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep, + biomem->data[j]); + } + + Curl_ssl_push_certinfo(data, certnum, namebuf, buf); + + BIO_free(bio_out); + + } + return 0; /* all is fine */ +} + +static CURLcode get_cert_chain(struct connectdata *conn, + struct ssl_connect_data *connssl) + +{ + CURLcode result; + STACK_OF(X509) *sk; + int i; + struct Curl_easy *data = conn->data; + int numcerts; + BIO *mem; + + sk = SSL_get_peer_cert_chain(BACKEND->handle); + if(!sk) { + return CURLE_OUT_OF_MEMORY; + } + + numcerts = sk_X509_num(sk); + + result = Curl_ssl_init_certinfo(data, numcerts); + if(result) { + return result; + } + + mem = BIO_new(BIO_s_mem()); + + for(i = 0; i < numcerts; i++) { + ASN1_INTEGER *num; + X509 *x = sk_X509_value(sk, i); + EVP_PKEY *pubkey = NULL; + int j; + char *ptr; + const ASN1_BIT_STRING *psig = NULL; + + X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); + push_certinfo("Subject", i); + + X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE); + push_certinfo("Issuer", i); + + BIO_printf(mem, "%lx", X509_get_version(x)); + push_certinfo("Version", i); + + num = X509_get_serialNumber(x); + if(num->type == V_ASN1_NEG_INTEGER) + BIO_puts(mem, "-"); + for(j = 0; j < num->length; j++) + BIO_printf(mem, "%02x", num->data[j]); + push_certinfo("Serial Number", i); + +#if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS) + { + const X509_ALGOR *sigalg = NULL; + X509_PUBKEY *xpubkey = NULL; + ASN1_OBJECT *pubkeyoid = NULL; + + X509_get0_signature(&psig, &sigalg, x); + if(sigalg) { + i2a_ASN1_OBJECT(mem, sigalg->algorithm); + push_certinfo("Signature Algorithm", i); + } + + xpubkey = X509_get_X509_PUBKEY(x); + if(xpubkey) { + X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey); + if(pubkeyoid) { + i2a_ASN1_OBJECT(mem, pubkeyoid); + push_certinfo("Public Key Algorithm", i); + } + } + + X509V3_ext(data, i, X509_get0_extensions(x)); + } +#else + { + /* before OpenSSL 1.0.2 */ + X509_CINF *cinf = x->cert_info; + + i2a_ASN1_OBJECT(mem, cinf->signature->algorithm); + push_certinfo("Signature Algorithm", i); + + i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm); + push_certinfo("Public Key Algorithm", i); + + X509V3_ext(data, i, cinf->extensions); + + psig = x->signature; + } +#endif + + ASN1_TIME_print(mem, X509_get0_notBefore(x)); + push_certinfo("Start date", i); + + ASN1_TIME_print(mem, X509_get0_notAfter(x)); + push_certinfo("Expire date", i); + + pubkey = X509_get_pubkey(x); + if(!pubkey) + infof(data, " Unable to load public key\n"); + else { + int pktype; +#ifdef HAVE_OPAQUE_EVP_PKEY + pktype = EVP_PKEY_id(pubkey); +#else + pktype = pubkey->type; +#endif + switch(pktype) { + case EVP_PKEY_RSA: + { + RSA *rsa; +#ifdef HAVE_OPAQUE_EVP_PKEY + rsa = EVP_PKEY_get0_RSA(pubkey); +#else + rsa = pubkey->pkey.rsa; +#endif + +#ifdef HAVE_OPAQUE_RSA_DSA_DH + { + const BIGNUM *n; + const BIGNUM *e; + + RSA_get0_key(rsa, &n, &e, NULL); + BIO_printf(mem, "%d", BN_num_bits(n)); + push_certinfo("RSA Public Key", i); + print_pubkey_BN(rsa, n, i); + print_pubkey_BN(rsa, e, i); + } +#else + BIO_printf(mem, "%d", BN_num_bits(rsa->n)); + push_certinfo("RSA Public Key", i); + print_pubkey_BN(rsa, n, i); + print_pubkey_BN(rsa, e, i); +#endif + + break; + } + case EVP_PKEY_DSA: + { +#ifndef OPENSSL_NO_DSA + DSA *dsa; +#ifdef HAVE_OPAQUE_EVP_PKEY + dsa = EVP_PKEY_get0_DSA(pubkey); +#else + dsa = pubkey->pkey.dsa; +#endif +#ifdef HAVE_OPAQUE_RSA_DSA_DH + { + const BIGNUM *p; + const BIGNUM *q; + const BIGNUM *g; + const BIGNUM *pub_key; + + DSA_get0_pqg(dsa, &p, &q, &g); + DSA_get0_key(dsa, &pub_key, NULL); + + print_pubkey_BN(dsa, p, i); + print_pubkey_BN(dsa, q, i); + print_pubkey_BN(dsa, g, i); + print_pubkey_BN(dsa, pub_key, i); + } +#else + print_pubkey_BN(dsa, p, i); + print_pubkey_BN(dsa, q, i); + print_pubkey_BN(dsa, g, i); + print_pubkey_BN(dsa, pub_key, i); +#endif +#endif /* !OPENSSL_NO_DSA */ + break; + } + case EVP_PKEY_DH: + { + DH *dh; +#ifdef HAVE_OPAQUE_EVP_PKEY + dh = EVP_PKEY_get0_DH(pubkey); +#else + dh = pubkey->pkey.dh; +#endif +#ifdef HAVE_OPAQUE_RSA_DSA_DH + { + const BIGNUM *p; + const BIGNUM *q; + const BIGNUM *g; + const BIGNUM *pub_key; + DH_get0_pqg(dh, &p, &q, &g); + DH_get0_key(dh, &pub_key, NULL); + print_pubkey_BN(dh, p, i); + print_pubkey_BN(dh, q, i); + print_pubkey_BN(dh, g, i); + print_pubkey_BN(dh, pub_key, i); + } +#else + print_pubkey_BN(dh, p, i); + print_pubkey_BN(dh, g, i); + print_pubkey_BN(dh, pub_key, i); +#endif + break; + } + } + EVP_PKEY_free(pubkey); + } + + if(psig) { + for(j = 0; j < psig->length; j++) + BIO_printf(mem, "%02x:", psig->data[j]); + push_certinfo("Signature", i); + } + + PEM_write_bio_X509(mem, x); + push_certinfo("Cert", i); + } + + BIO_free(mem); + + return CURLE_OK; +} + +/* + * Heavily modified from: + * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL + */ +static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert, + const char *pinnedpubkey) +{ + /* Scratch */ + int len1 = 0, len2 = 0; + unsigned char *buff1 = NULL, *temp = NULL; + + /* Result is returned to caller */ + CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + + /* if a path wasn't specified, don't pin */ + if(!pinnedpubkey) + return CURLE_OK; + + if(!cert) + return result; + + do { + /* Begin Gyrations to get the subjectPublicKeyInfo */ + /* Thanks to Viktor Dukhovni on the OpenSSL mailing list */ + + /* https://groups.google.com/group/mailing.openssl.users/browse_thread + /thread/d61858dae102c6c7 */ + len1 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL); + if(len1 < 1) + break; /* failed */ + + buff1 = temp = malloc(len1); + if(!buff1) + break; /* failed */ + + /* https://www.openssl.org/docs/crypto/d2i_X509.html */ + len2 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp); + + /* + * These checks are verifying we got back the same values as when we + * sized the buffer. It's pretty weak since they should always be the + * same. But it gives us something to test. + */ + if((len1 != len2) || !temp || ((temp - buff1) != len1)) + break; /* failed */ + + /* End Gyrations */ + + /* The one good exit point */ + result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); + } while(0); + + if(buff1) + free(buff1); + + return result; +} + +/* + * Get the server cert, verify it and show it etc, only call failf() if the + * 'strict' argument is TRUE as otherwise all this is for informational + * purposes only! + * + * We check certificates to authenticate the server; otherwise we risk + * man-in-the-middle attack. + */ +static CURLcode servercert(struct connectdata *conn, + struct ssl_connect_data *connssl, + bool strict) +{ + CURLcode result = CURLE_OK; + int rc; + long lerr; + struct Curl_easy *data = conn->data; + X509 *issuer; + BIO *fp = NULL; + char error_buffer[256]=""; + char buffer[2048]; + const char *ptr; + long * const certverifyresult = SSL_IS_PROXY() ? + &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; + BIO *mem = BIO_new(BIO_s_mem()); + + if(data->set.ssl.certinfo) + /* we've been asked to gather certificate info! */ + (void)get_cert_chain(conn, connssl); + + BACKEND->server_cert = SSL_get_peer_certificate(BACKEND->handle); + if(!BACKEND->server_cert) { + BIO_free(mem); + if(!strict) + return CURLE_OK; + + failf(data, "SSL: couldn't get peer certificate!"); + return CURLE_PEER_FAILED_VERIFICATION; + } + + infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server"); + + rc = x509_name_oneline(X509_get_subject_name(BACKEND->server_cert), + buffer, sizeof(buffer)); + infof(data, " subject: %s\n", rc?"[NONE]":buffer); + +#ifndef CURL_DISABLE_VERBOSE_STRINGS + { + long len; + ASN1_TIME_print(mem, X509_get0_notBefore(BACKEND->server_cert)); + len = BIO_get_mem_data(mem, (char **) &ptr); + infof(data, " start date: %.*s\n", len, ptr); + (void)BIO_reset(mem); + + ASN1_TIME_print(mem, X509_get0_notAfter(BACKEND->server_cert)); + len = BIO_get_mem_data(mem, (char **) &ptr); + infof(data, " expire date: %.*s\n", len, ptr); + (void)BIO_reset(mem); + } +#endif + + BIO_free(mem); + + if(SSL_CONN_CONFIG(verifyhost)) { + result = verifyhost(conn, BACKEND->server_cert); + if(result) { + X509_free(BACKEND->server_cert); + BACKEND->server_cert = NULL; + return result; + } + } + + rc = x509_name_oneline(X509_get_issuer_name(BACKEND->server_cert), + buffer, sizeof(buffer)); + if(rc) { + if(strict) + failf(data, "SSL: couldn't get X509-issuer name!"); + result = CURLE_PEER_FAILED_VERIFICATION; + } + else { + infof(data, " issuer: %s\n", buffer); + + /* We could do all sorts of certificate verification stuff here before + deallocating the certificate. */ + + /* e.g. match issuer name with provided issuer certificate */ + if(SSL_SET_OPTION(issuercert)) { + fp = BIO_new(BIO_s_file()); + if(fp == NULL) { + failf(data, + "BIO_new return NULL, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + X509_free(BACKEND->server_cert); + BACKEND->server_cert = NULL; + return CURLE_OUT_OF_MEMORY; + } + + if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) { + if(strict) + failf(data, "SSL: Unable to open issuer cert (%s)", + SSL_SET_OPTION(issuercert)); + BIO_free(fp); + X509_free(BACKEND->server_cert); + BACKEND->server_cert = NULL; + return CURLE_SSL_ISSUER_ERROR; + } + + issuer = PEM_read_bio_X509(fp, NULL, ZERO_NULL, NULL); + if(!issuer) { + if(strict) + failf(data, "SSL: Unable to read issuer cert (%s)", + SSL_SET_OPTION(issuercert)); + BIO_free(fp); + X509_free(issuer); + X509_free(BACKEND->server_cert); + BACKEND->server_cert = NULL; + return CURLE_SSL_ISSUER_ERROR; + } + + if(X509_check_issued(issuer, BACKEND->server_cert) != X509_V_OK) { + if(strict) + failf(data, "SSL: Certificate issuer check failed (%s)", + SSL_SET_OPTION(issuercert)); + BIO_free(fp); + X509_free(issuer); + X509_free(BACKEND->server_cert); + BACKEND->server_cert = NULL; + return CURLE_SSL_ISSUER_ERROR; + } + + infof(data, " SSL certificate issuer check ok (%s)\n", + SSL_SET_OPTION(issuercert)); + BIO_free(fp); + X509_free(issuer); + } + + lerr = *certverifyresult = SSL_get_verify_result(BACKEND->handle); + + if(*certverifyresult != X509_V_OK) { + if(SSL_CONN_CONFIG(verifypeer)) { + /* We probably never reach this, because SSL_connect() will fail + and we return earlier if verifypeer is set? */ + if(strict) + failf(data, "SSL certificate verify result: %s (%ld)", + X509_verify_cert_error_string(lerr), lerr); + result = CURLE_PEER_FAILED_VERIFICATION; + } + else + infof(data, " SSL certificate verify result: %s (%ld)," + " continuing anyway.\n", + X509_verify_cert_error_string(lerr), lerr); + } + else + infof(data, " SSL certificate verify ok.\n"); + } + +#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ + !defined(OPENSSL_NO_OCSP) + if(SSL_CONN_CONFIG(verifystatus)) { + result = verifystatus(conn, connssl); + if(result) { + X509_free(BACKEND->server_cert); + BACKEND->server_cert = NULL; + return result; + } + } +#endif + + if(!strict) + /* when not strict, we don't bother about the verify cert problems */ + result = CURLE_OK; + + ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + if(!result && ptr) { + result = pkp_pin_peer_pubkey(data, BACKEND->server_cert, ptr); + if(result) + failf(data, "SSL: public key does not match pinned public key!"); + } + + X509_free(BACKEND->server_cert); + BACKEND->server_cert = NULL; + connssl->connecting_state = ssl_connect_done; + + return result; +} + +static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex) +{ + CURLcode result = CURLE_OK; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); + + /* + * We check certificates to authenticate the server; otherwise we risk + * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to + * verify the peer ignore faults and failures from the server cert + * operations. + */ + + result = servercert(conn, connssl, (SSL_CONN_CONFIG(verifypeer) || + SSL_CONN_CONFIG(verifyhost))); + + if(!result) + connssl->connecting_state = ssl_connect_done; + + return result; +} + +static Curl_recv ossl_recv; +static Curl_send ossl_send; + +static CURLcode ossl_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + time_t timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + /* Find out how much more time we're allowed */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + result = ossl_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading || + connssl->connecting_state == ssl_connect_2_writing) { + + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking?0:timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if this + * connection is done nonblocking and this loop would execute again. This + * permits the owner of a multi handle to abort a connection attempt + * before step2 has completed while ensuring that a client using select() + * or epoll() will always have a valid fdset to wait on. + */ + result = ossl_connect_step2(conn, sockindex); + if(result || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return result; + + } /* repeat step2 until all transactions are done. */ + + if(ssl_connect_3 == connssl->connecting_state) { + result = ossl_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = ossl_recv; + conn->send[sockindex] = ossl_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +static CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn, + int sockindex, + bool *done) +{ + return ossl_connect_common(conn, sockindex, TRUE, done); +} + +static CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex) +{ + CURLcode result; + bool done = FALSE; + + result = ossl_connect_common(conn, sockindex, FALSE, &done); + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +static bool Curl_ossl_data_pending(const struct connectdata *conn, + int connindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[connindex]; + const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex]; + + if(connssl->backend->handle && SSL_pending(connssl->backend->handle)) + return TRUE; + + if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle)) + return TRUE; + + return FALSE; +} + +static size_t Curl_ossl_version(char *buffer, size_t size); + +static ssize_t ossl_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) +{ + /* SSL_write() is said to return 'int' while write() and send() returns + 'size_t' */ + int err; + char error_buffer[256]; + unsigned long sslerror; + int memlen; + int rc; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + ERR_clear_error(); + + memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; + rc = SSL_write(BACKEND->handle, mem, memlen); + + if(rc <= 0) { + err = SSL_get_error(BACKEND->handle, rc); + + switch(err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /* The operation did not complete; the same TLS/SSL I/O function + should be called again later. This is basically an EWOULDBLOCK + equivalent. */ + *curlcode = CURLE_AGAIN; + return -1; + case SSL_ERROR_SYSCALL: + failf(conn->data, "SSL_write() returned SYSCALL, errno = %d", + SOCKERRNO); + *curlcode = CURLE_SEND_ERROR; + return -1; + case SSL_ERROR_SSL: + /* A failure in the SSL library occurred, usually a protocol error. + The OpenSSL error queue contains more information on the error. */ + sslerror = ERR_get_error(); + if(ERR_GET_LIB(sslerror) == ERR_LIB_SSL && + ERR_GET_REASON(sslerror) == SSL_R_BIO_NOT_SET && + conn->ssl[sockindex].state == ssl_connection_complete && + conn->proxy_ssl[sockindex].state == ssl_connection_complete) { + char ver[120]; + Curl_ossl_version(ver, 120); + failf(conn->data, "Error: %s does not support double SSL tunneling.", + ver); + } + else + failf(conn->data, "SSL_write() error: %s", + ossl_strerror(sslerror, error_buffer, sizeof(error_buffer))); + *curlcode = CURLE_SEND_ERROR; + return -1; + } + /* a true error */ + failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d", + SSL_ERROR_to_str(err), SOCKERRNO); + *curlcode = CURLE_SEND_ERROR; + return -1; + } + *curlcode = CURLE_OK; + return (ssize_t)rc; /* number of bytes */ +} + +static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ + int num, /* socketindex */ + char *buf, /* store read data here */ + size_t buffersize, /* max amount to read */ + CURLcode *curlcode) +{ + char error_buffer[256]; + unsigned long sslerror; + ssize_t nread; + int buffsize; + struct ssl_connect_data *connssl = &conn->ssl[num]; + + ERR_clear_error(); + + buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; + nread = (ssize_t)SSL_read(BACKEND->handle, buf, buffsize); + if(nread <= 0) { + /* failed SSL_read */ + int err = SSL_get_error(BACKEND->handle, (int)nread); + + switch(err) { + case SSL_ERROR_NONE: /* this is not an error */ + break; + case SSL_ERROR_ZERO_RETURN: /* no more data */ + /* close_notify alert */ + connclose(conn, "TLS close_notify"); + break; + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /* there's data pending, re-invoke SSL_read() */ + *curlcode = CURLE_AGAIN; + return -1; + default: + /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return + value/errno" */ + /* https://www.openssl.org/docs/crypto/ERR_get_error.html */ + sslerror = ERR_get_error(); + if((nread < 0) || sslerror) { + /* If the return code was negative or there actually is an error in the + queue */ + failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d", + (sslerror ? + ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)) : + SSL_ERROR_to_str(err)), + SOCKERRNO); + *curlcode = CURLE_RECV_ERROR; + return -1; + } + } + } + return nread; +} + +static size_t Curl_ossl_version(char *buffer, size_t size) +{ +#ifdef OPENSSL_IS_BORINGSSL + return msnprintf(buffer, size, OSSL_PACKAGE); +#elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING) + return msnprintf(buffer, size, "%s/%s", + OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); +#else + /* not BoringSSL and not using OpenSSL_version */ + + char sub[3]; + unsigned long ssleay_value; + sub[2]='\0'; + sub[1]='\0'; + ssleay_value = OpenSSL_version_num(); + if(ssleay_value < 0x906000) { + ssleay_value = SSLEAY_VERSION_NUMBER; + sub[0]='\0'; + } + else { + if(ssleay_value&0xff0) { + int minor_ver = (ssleay_value >> 4) & 0xff; + if(minor_ver > 26) { + /* handle extended version introduced for 0.9.8za */ + sub[1] = (char) ((minor_ver - 1) % 26 + 'a' + 1); + sub[0] = 'z'; + } + else { + sub[0] = (char) (minor_ver + 'a' - 1); + } + } + else + sub[0]='\0'; + } + + return msnprintf(buffer, size, "%s/%lx.%lx.%lx%s" +#ifdef OPENSSL_FIPS + "-fips" +#endif + , + OSSL_PACKAGE, + (ssleay_value>>28)&0xf, + (ssleay_value>>20)&0xff, + (ssleay_value>>12)&0xff, + sub); +#endif /* OPENSSL_IS_BORINGSSL */ +} + +/* can be called with data == NULL */ +static CURLcode Curl_ossl_random(struct Curl_easy *data, + unsigned char *entropy, size_t length) +{ + int rc; + if(data) { + if(Curl_ossl_seed(data)) /* Initiate the seed if not already done */ + return CURLE_FAILED_INIT; /* couldn't seed for some reason */ + } + else { + if(!rand_enough()) + return CURLE_FAILED_INIT; + } + /* RAND_bytes() returns 1 on success, 0 otherwise. */ + rc = RAND_bytes(entropy, curlx_uztosi(length)); + return (rc == 1 ? CURLE_OK : CURLE_FAILED_INIT); +} + +static CURLcode Curl_ossl_md5sum(unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *md5sum /* output */, + size_t unused) +{ + EVP_MD_CTX *mdctx; + unsigned int len = 0; + (void) unused; + + mdctx = EVP_MD_CTX_create(); + EVP_DigestInit_ex(mdctx, EVP_md5(), NULL); + EVP_DigestUpdate(mdctx, tmp, tmplen); + EVP_DigestFinal_ex(mdctx, md5sum, &len); + EVP_MD_CTX_destroy(mdctx); + return CURLE_OK; +} + +#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) +static CURLcode Curl_ossl_sha256sum(const unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *sha256sum /* output */, + size_t unused) +{ + EVP_MD_CTX *mdctx; + unsigned int len = 0; + (void) unused; + + mdctx = EVP_MD_CTX_create(); + EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL); + EVP_DigestUpdate(mdctx, tmp, tmplen); + EVP_DigestFinal_ex(mdctx, sha256sum, &len); + EVP_MD_CTX_destroy(mdctx); + return CURLE_OK; +} +#endif + +static bool Curl_ossl_cert_status_request(void) +{ +#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ + !defined(OPENSSL_NO_OCSP) + return TRUE; +#else + return FALSE; +#endif +} + +static void *Curl_ossl_get_internals(struct ssl_connect_data *connssl, + CURLINFO info) +{ + /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */ + return info == CURLINFO_TLS_SESSION ? + (void *)BACKEND->ctx : (void *)BACKEND->handle; +} + +const struct Curl_ssl Curl_ssl_openssl = { + { CURLSSLBACKEND_OPENSSL, "openssl" }, /* info */ + + SSLSUPP_CA_PATH | + SSLSUPP_CERTINFO | + SSLSUPP_PINNEDPUBKEY | + SSLSUPP_SSL_CTX | +#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES + SSLSUPP_TLS13_CIPHERSUITES | +#endif + SSLSUPP_HTTPS_PROXY, + + sizeof(struct ssl_backend_data), + + Curl_ossl_init, /* init */ + Curl_ossl_cleanup, /* cleanup */ + Curl_ossl_version, /* version */ + Curl_ossl_check_cxn, /* check_cxn */ + Curl_ossl_shutdown, /* shutdown */ + Curl_ossl_data_pending, /* data_pending */ + Curl_ossl_random, /* random */ + Curl_ossl_cert_status_request, /* cert_status_request */ + Curl_ossl_connect, /* connect */ + Curl_ossl_connect_nonblocking, /* connect_nonblocking */ + Curl_ossl_get_internals, /* get_internals */ + Curl_ossl_close, /* close_one */ + Curl_ossl_close_all, /* close_all */ + Curl_ossl_session_free, /* session_free */ + Curl_ossl_set_engine, /* set_engine */ + Curl_ossl_set_engine_default, /* set_engine_default */ + Curl_ossl_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_ossl_md5sum, /* md5sum */ +#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) + Curl_ossl_sha256sum /* sha256sum */ +#else + NULL /* sha256sum */ +#endif +}; + +#endif /* USE_OPENSSL */ diff --git a/libcurl/lib/vtls/openssl.h b/libcurl/lib/vtls/openssl.h new file mode 100644 index 0000000..114dc4b --- /dev/null +++ b/libcurl/lib/vtls/openssl.h @@ -0,0 +1,37 @@ +#ifndef HEADER_CURL_SSLUSE_H +#define HEADER_CURL_SSLUSE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_OPENSSL +/* + * This header should only be needed to get included by vtls.c and openssl.c + */ + +#include "urldata.h" + +extern const struct Curl_ssl Curl_ssl_openssl; + +#endif /* USE_OPENSSL */ +#endif /* HEADER_CURL_SSLUSE_H */ diff --git a/libcurl/lib/vtls/polarssl.c b/libcurl/lib/vtls/polarssl.c new file mode 100644 index 0000000..7ea26b4 --- /dev/null +++ b/libcurl/lib/vtls/polarssl.c @@ -0,0 +1,931 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2019, Daniel Stenberg, , et al. + * Copyright (C) 2010 - 2011, Hoi-Ho Chan, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all PolarSSL-specific code for the TLS/SSL layer. No code + * but vtls.c should ever call or use these functions. + * + */ + +#include "curl_setup.h" + +#ifdef USE_POLARSSL +#include +#include +#include +#include +#include +#include + +#if POLARSSL_VERSION_NUMBER < 0x01030000 +#error too old PolarSSL +#endif + +#include +#include +#include + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "polarssl.h" +#include "vtls.h" +#include "parsedate.h" +#include "connect.h" /* for the connect timeout */ +#include "select.h" +#include "strcase.h" +#include "polarssl_threadlock.h" +#include "multiif.h" +#include "curl_printf.h" +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* See https://tls.mbed.org/discussions/generic/ + howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der +*/ +#define RSA_PUB_DER_MAX_BYTES (38 + 2 * POLARSSL_MPI_MAX_SIZE) +#define ECP_PUB_DER_MAX_BYTES (30 + 2 * POLARSSL_ECP_MAX_BYTES) + +#define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ + RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES) + +struct ssl_backend_data { + ctr_drbg_context ctr_drbg; + entropy_context entropy; + ssl_context ssl; + int server_fd; + x509_crt cacert; + x509_crt clicert; + x509_crl crl; + rsa_context rsa; +}; + +#define BACKEND connssl->backend + +/* apply threading? */ +#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) +#define THREADING_SUPPORT +#endif + +#ifndef POLARSSL_ERROR_C +#define error_strerror(x,y,z) +#endif /* POLARSSL_ERROR_C */ + + +#if defined(THREADING_SUPPORT) +static entropy_context entropy; + +static int entropy_init_initialized = 0; + +/* start of entropy_init_mutex() */ +static void entropy_init_mutex(entropy_context *ctx) +{ + /* lock 0 = entropy_init_mutex() */ + Curl_polarsslthreadlock_lock_function(0); + if(entropy_init_initialized == 0) { + entropy_init(ctx); + entropy_init_initialized = 1; + } + Curl_polarsslthreadlock_unlock_function(0); +} +/* end of entropy_init_mutex() */ + +/* start of entropy_func_mutex() */ +static int entropy_func_mutex(void *data, unsigned char *output, size_t len) +{ + int ret; + /* lock 1 = entropy_func_mutex() */ + Curl_polarsslthreadlock_lock_function(1); + ret = entropy_func(data, output, len); + Curl_polarsslthreadlock_unlock_function(1); + + return ret; +} +/* end of entropy_func_mutex() */ + +#endif /* THREADING_SUPPORT */ + +/* Define this to enable lots of debugging for PolarSSL */ +#undef POLARSSL_DEBUG + +#ifdef POLARSSL_DEBUG +static void polarssl_debug(void *context, int level, const char *line) +{ + struct Curl_easy *data = NULL; + + if(!context) + return; + + data = (struct Curl_easy *)context; + + infof(data, "%s", line); + (void) level; +} +#else +#endif + +/* ALPN for http2? */ +#ifdef POLARSSL_SSL_ALPN +# define HAS_ALPN +#endif + +static Curl_recv polarssl_recv; +static Curl_send polarssl_send; + +static CURLcode polarssl_version_from_curl(int *polarver, long ssl_version) +{ + switch(ssl_version) { + case CURL_SSLVERSION_TLSv1_0: + *polarver = SSL_MINOR_VERSION_1; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_1: + *polarver = SSL_MINOR_VERSION_2; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_2: + *polarver = SSL_MINOR_VERSION_3; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_3: + break; + } + return CURLE_SSL_CONNECT_ERROR; +} + +static CURLcode +set_ssl_version_min_max(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data* connssl = &conn->ssl[sockindex]; + long ssl_version = SSL_CONN_CONFIG(version); + long ssl_version_max = SSL_CONN_CONFIG(version_max); + int ssl_min_ver = SSL_MINOR_VERSION_1; + int ssl_max_ver = SSL_MINOR_VERSION_1; + CURLcode result = CURLE_OK; + + switch(ssl_version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + ssl_version = CURL_SSLVERSION_TLSv1_0; + break; + } + + switch(ssl_version_max) { + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_DEFAULT: + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; + break; + } + + result = polarssl_version_from_curl(&ssl_min_ver, ssl_version); + if(result) { + failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); + return result; + } + result = polarssl_version_from_curl(&ssl_max_ver, ssl_version_max >> 16); + if(result) { + failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); + return result; + } + + ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_min_ver); + ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_max_ver); + + return result; +} + +static CURLcode +polarssl_connect_step1(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data* connssl = &conn->ssl[sockindex]; + const char *capath = SSL_CONN_CONFIG(CApath); + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; + int ret = -1; + char errorbuf[128]; + errorbuf[0] = 0; + + /* PolarSSL only supports SSLv3 and TLSv1 */ + if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) { + failf(data, "PolarSSL does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + } + +#ifdef THREADING_SUPPORT + entropy_init_mutex(&entropy); + + if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func_mutex, &entropy, + NULL, 0)) != 0) { + error_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", + -ret, errorbuf); + } +#else + entropy_init(&BACKEND->entropy); + + if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func, &BACKEND->entropy, + NULL, 0)) != 0) { + error_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", + -ret, errorbuf); + } +#endif /* THREADING_SUPPORT */ + + /* Load the trusted CA */ + memset(&BACKEND->cacert, 0, sizeof(x509_crt)); + + if(SSL_CONN_CONFIG(CAfile)) { + ret = x509_crt_parse_file(&BACKEND->cacert, + SSL_CONN_CONFIG(CAfile)); + + if(ret<0) { + error_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s", + SSL_CONN_CONFIG(CAfile), -ret, errorbuf); + + if(SSL_CONN_CONFIG(verifypeer)) + return CURLE_SSL_CACERT_BADFILE; + } + } + + if(capath) { + ret = x509_crt_parse_path(&BACKEND->cacert, capath); + + if(ret<0) { + error_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s", + capath, -ret, errorbuf); + + if(SSL_CONN_CONFIG(verifypeer)) + return CURLE_SSL_CACERT_BADFILE; + } + } + + /* Load the client certificate */ + memset(&BACKEND->clicert, 0, sizeof(x509_crt)); + + if(SSL_SET_OPTION(cert)) { + ret = x509_crt_parse_file(&BACKEND->clicert, + SSL_SET_OPTION(cert)); + + if(ret) { + error_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s", + SSL_SET_OPTION(cert), -ret, errorbuf); + + return CURLE_SSL_CERTPROBLEM; + } + } + + /* Load the client private key */ + if(SSL_SET_OPTION(key)) { + pk_context pk; + pk_init(&pk); + ret = pk_parse_keyfile(&pk, SSL_SET_OPTION(key), + SSL_SET_OPTION(key_passwd)); + if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA)) + ret = POLARSSL_ERR_PK_TYPE_MISMATCH; + if(ret == 0) + rsa_copy(&BACKEND->rsa, pk_rsa(pk)); + else + rsa_free(&BACKEND->rsa); + pk_free(&pk); + + if(ret) { + error_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s", + SSL_SET_OPTION(key), -ret, errorbuf); + + return CURLE_SSL_CERTPROBLEM; + } + } + + /* Load the CRL */ + memset(&BACKEND->crl, 0, sizeof(x509_crl)); + + if(SSL_SET_OPTION(CRLfile)) { + ret = x509_crl_parse_file(&BACKEND->crl, + SSL_SET_OPTION(CRLfile)); + + if(ret) { + error_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s", + SSL_SET_OPTION(CRLfile), -ret, errorbuf); + + return CURLE_SSL_CRL_BADFILE; + } + } + + infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port); + + if(ssl_init(&BACKEND->ssl)) { + failf(data, "PolarSSL: ssl_init failed"); + return CURLE_SSL_CONNECT_ERROR; + } + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, + SSL_MINOR_VERSION_1); + break; + case CURL_SSLVERSION_SSLv3: + ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, + SSL_MINOR_VERSION_0); + ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, + SSL_MINOR_VERSION_0); + infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n"); + break; + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + { + CURLcode result = set_ssl_version_min_max(conn, sockindex); + if(result != CURLE_OK) + return result; + break; + } + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + ssl_set_endpoint(&BACKEND->ssl, SSL_IS_CLIENT); + ssl_set_authmode(&BACKEND->ssl, SSL_VERIFY_OPTIONAL); + + ssl_set_rng(&BACKEND->ssl, ctr_drbg_random, + &BACKEND->ctr_drbg); + ssl_set_bio(&BACKEND->ssl, + net_recv, &conn->sock[sockindex], + net_send, &conn->sock[sockindex]); + + ssl_set_ciphersuites(&BACKEND->ssl, ssl_list_ciphersuites()); + + /* Check if there's a cached ID we can/should use here! */ + if(SSL_SET_OPTION(primary.sessionid)) { + void *old_session = NULL; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) { + ret = ssl_set_session(&BACKEND->ssl, old_session); + if(ret) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "ssl_set_session returned -0x%x", -ret); + return CURLE_SSL_CONNECT_ERROR; + } + infof(data, "PolarSSL re-using session\n"); + } + Curl_ssl_sessionid_unlock(conn); + } + + ssl_set_ca_chain(&BACKEND->ssl, + &BACKEND->cacert, + &BACKEND->crl, + hostname); + + ssl_set_own_cert_rsa(&BACKEND->ssl, + &BACKEND->clicert, &BACKEND->rsa); + + if(ssl_set_hostname(&BACKEND->ssl, hostname)) { + /* ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name + to set in the SNI extension. So even if curl connects to a host + specified as an IP address, this function must be used. */ + failf(data, "couldn't set hostname in PolarSSL"); + return CURLE_SSL_CONNECT_ERROR; + } + +#ifdef HAS_ALPN + if(conn->bits.tls_enable_alpn) { + static const char *protocols[3]; + int cur = 0; + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2) { + protocols[cur++] = NGHTTP2_PROTO_VERSION_ID; + infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + protocols[cur++] = ALPN_HTTP_1_1; + infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + + protocols[cur] = NULL; + + ssl_set_alpn_protocols(&BACKEND->ssl, protocols); + } +#endif + +#ifdef POLARSSL_DEBUG + ssl_set_dbg(&BACKEND->ssl, polarssl_debug, data); +#endif + + connssl->connecting_state = ssl_connect_2; + + return CURLE_OK; +} + +static CURLcode +polarssl_connect_step2(struct connectdata *conn, + int sockindex) +{ + int ret; + struct Curl_easy *data = conn->data; + struct ssl_connect_data* connssl = &conn->ssl[sockindex]; + char buffer[1024]; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + + + char errorbuf[128]; + errorbuf[0] = 0; + + conn->recv[sockindex] = polarssl_recv; + conn->send[sockindex] = polarssl_send; + + ret = ssl_handshake(&BACKEND->ssl); + + switch(ret) { + case 0: + break; + + case POLARSSL_ERR_NET_WANT_READ: + connssl->connecting_state = ssl_connect_2_reading; + return CURLE_OK; + + case POLARSSL_ERR_NET_WANT_WRITE: + connssl->connecting_state = ssl_connect_2_writing; + return CURLE_OK; + + default: + error_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s", + -ret, errorbuf); + return CURLE_SSL_CONNECT_ERROR; + } + + infof(data, "PolarSSL: Handshake complete, cipher is %s\n", + ssl_get_ciphersuite(&BACKEND->ssl) ); + + ret = ssl_get_verify_result(&BACKEND->ssl); + + if(ret && SSL_CONN_CONFIG(verifypeer)) { + if(ret & BADCERT_EXPIRED) + failf(data, "Cert verify failed: BADCERT_EXPIRED"); + + if(ret & BADCERT_REVOKED) { + failf(data, "Cert verify failed: BADCERT_REVOKED"); + return CURLE_PEER_FAILED_VERIFICATION; + } + + if(ret & BADCERT_CN_MISMATCH) + failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); + + if(ret & BADCERT_NOT_TRUSTED) + failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); + + return CURLE_PEER_FAILED_VERIFICATION; + } + + if(ssl_get_peer_cert(&(BACKEND->ssl))) { + /* If the session was resumed, there will be no peer certs */ + memset(buffer, 0, sizeof(buffer)); + + if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ", + ssl_get_peer_cert(&(BACKEND->ssl))) != -1) + infof(data, "Dumping cert info:\n%s\n", buffer); + } + + /* adapted from mbedtls.c */ + if(pinnedpubkey) { + int size; + CURLcode result; + x509_crt *p; + unsigned char pubkey[PUB_DER_MAX_BYTES]; + const x509_crt *peercert; + + peercert = ssl_get_peer_cert(&BACKEND->ssl); + + if(!peercert || !peercert->raw.p || !peercert->raw.len) { + failf(data, "Failed due to missing peer certificate"); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + p = calloc(1, sizeof(*p)); + + if(!p) + return CURLE_OUT_OF_MEMORY; + + x509_crt_init(p); + + /* Make a copy of our const peercert because pk_write_pubkey_der + needs a non-const key, for now. + https://github.com/ARMmbed/mbedtls/issues/396 */ + if(x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) { + failf(data, "Failed copying peer certificate"); + x509_crt_free(p); + free(p); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + size = pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES); + + if(size <= 0) { + failf(data, "Failed copying public key from peer certificate"); + x509_crt_free(p); + free(p); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + /* pk_write_pubkey_der writes data at the end of the buffer. */ + result = Curl_pin_peer_pubkey(data, + pinnedpubkey, + &pubkey[PUB_DER_MAX_BYTES - size], size); + if(result) { + x509_crt_free(p); + free(p); + return result; + } + + x509_crt_free(p); + free(p); + } + +#ifdef HAS_ALPN + if(conn->bits.tls_enable_alpn) { + const char *next_protocol = ssl_get_alpn_protocol(&BACKEND->ssl); + + if(next_protocol != NULL) { + infof(data, "ALPN, server accepted to use %s\n", next_protocol); + +#ifdef USE_NGHTTP2 + if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID, + NGHTTP2_PROTO_VERSION_ID_LEN)) { + conn->negnpn = CURL_HTTP_VERSION_2; + } + else +#endif + if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) { + conn->negnpn = CURL_HTTP_VERSION_1_1; + } + } + else + infof(data, "ALPN, server did not agree to a protocol\n"); + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + } +#endif + + connssl->connecting_state = ssl_connect_3; + infof(data, "SSL connected\n"); + + return CURLE_OK; +} + +static CURLcode +polarssl_connect_step3(struct connectdata *conn, + int sockindex) +{ + CURLcode retcode = CURLE_OK; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct Curl_easy *data = conn->data; + + DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); + + if(SSL_SET_OPTION(primary.sessionid)) { + int ret; + ssl_session *our_ssl_sessionid; + void *old_ssl_sessionid = NULL; + + our_ssl_sessionid = calloc(1, sizeof(ssl_session)); + if(!our_ssl_sessionid) + return CURLE_OUT_OF_MEMORY; + + ret = ssl_get_session(&BACKEND->ssl, our_ssl_sessionid); + if(ret) { + failf(data, "ssl_get_session returned -0x%x", -ret); + return CURLE_SSL_CONNECT_ERROR; + } + + /* If there's already a matching session in the cache, delete it */ + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex)) + Curl_ssl_delsessionid(conn, old_ssl_sessionid); + + retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex); + Curl_ssl_sessionid_unlock(conn); + if(retcode) { + free(our_ssl_sessionid); + failf(data, "failed to store ssl session"); + return retcode; + } + } + + connssl->connecting_state = ssl_connect_done; + + return CURLE_OK; +} + +static ssize_t polarssl_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + int ret = -1; + + ret = ssl_write(&BACKEND->ssl, + (unsigned char *)mem, len); + + if(ret < 0) { + *curlcode = (ret == POLARSSL_ERR_NET_WANT_WRITE) ? + CURLE_AGAIN : CURLE_SEND_ERROR; + ret = -1; + } + + return ret; +} + +static void Curl_polarssl_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + rsa_free(&BACKEND->rsa); + x509_crt_free(&BACKEND->clicert); + x509_crt_free(&BACKEND->cacert); + x509_crl_free(&BACKEND->crl); + ssl_free(&BACKEND->ssl); +} + +static ssize_t polarssl_recv(struct connectdata *conn, + int num, + char *buf, + size_t buffersize, + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[num]; + int ret = -1; + ssize_t len = -1; + + memset(buf, 0, buffersize); + ret = ssl_read(&BACKEND->ssl, (unsigned char *)buf, buffersize); + + if(ret <= 0) { + if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) + return 0; + + *curlcode = (ret == POLARSSL_ERR_NET_WANT_READ) ? + CURLE_AGAIN : CURLE_RECV_ERROR; + return -1; + } + + len = ret; + + return len; +} + +static void Curl_polarssl_session_free(void *ptr) +{ + ssl_session_free(ptr); + free(ptr); +} + +/* 1.3.10 was the first rebranded version. All new releases (in 1.3 branch and + higher) will be mbed TLS branded.. */ + +static size_t Curl_polarssl_version(char *buffer, size_t size) +{ + unsigned int version = version_get_number(); + return msnprintf(buffer, size, "%s/%d.%d.%d", + version >= 0x01030A00?"mbedTLS":"PolarSSL", + version>>24, (version>>16)&0xff, (version>>8)&0xff); +} + +static CURLcode +polarssl_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + long timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + /* Find out how much more time we're allowed */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + result = polarssl_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading || + connssl->connecting_state == ssl_connect_2_writing) { + + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking?0:timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if + * this connection is part of a multi handle and this loop would + * execute again. This permits the owner of a multi handle to + * abort a connection attempt before step2 has completed while + * ensuring that a client using select() or epoll() will always + * have a valid fdset to wait on. + */ + result = polarssl_connect_step2(conn, sockindex); + if(result || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return result; + + } /* repeat step2 until all transactions are done. */ + + if(ssl_connect_3 == connssl->connecting_state) { + result = polarssl_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = polarssl_recv; + conn->send[sockindex] = polarssl_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +static CURLcode Curl_polarssl_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + return polarssl_connect_common(conn, sockindex, TRUE, done); +} + + +static CURLcode Curl_polarssl_connect(struct connectdata *conn, int sockindex) +{ + CURLcode result; + bool done = FALSE; + + result = polarssl_connect_common(conn, sockindex, FALSE, &done); + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +/* + * return 0 error initializing SSL + * return 1 SSL initialized successfully + */ +static int Curl_polarssl_init(void) +{ + return Curl_polarsslthreadlock_thread_setup(); +} + +static void Curl_polarssl_cleanup(void) +{ + (void)Curl_polarsslthreadlock_thread_cleanup(); +} + +static bool Curl_polarssl_data_pending(const struct connectdata *conn, + int sockindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + return ssl_get_bytes_avail(&BACKEND->ssl) != 0; +} + +static CURLcode Curl_polarssl_sha256sum(const unsigned char *input, + size_t inputlen, + unsigned char *sha256sum, + size_t sha256len UNUSED_PARAM) +{ + (void)sha256len; + sha256(input, inputlen, sha256sum, 0); + return CURLE_OK; +} + +static void *Curl_polarssl_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + (void)info; + return &BACKEND->ssl; +} + +const struct Curl_ssl Curl_ssl_polarssl = { + { CURLSSLBACKEND_POLARSSL, "polarssl" }, /* info */ + + SSLSUPP_CA_PATH | + SSLSUPP_PINNEDPUBKEY, + + sizeof(struct ssl_backend_data), + + Curl_polarssl_init, /* init */ + Curl_polarssl_cleanup, /* cleanup */ + Curl_polarssl_version, /* version */ + Curl_none_check_cxn, /* check_cxn */ + Curl_none_shutdown, /* shutdown */ + Curl_polarssl_data_pending, /* data_pending */ + /* This might cause libcurl to use a weeker random! */ + Curl_none_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_polarssl_connect, /* connect */ + Curl_polarssl_connect_nonblocking, /* connect_nonblocking */ + Curl_polarssl_get_internals, /* get_internals */ + Curl_polarssl_close, /* close_one */ + Curl_none_close_all, /* close_all */ + Curl_polarssl_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_none_md5sum, /* md5sum */ + Curl_polarssl_sha256sum /* sha256sum */ +}; + +#endif /* USE_POLARSSL */ diff --git a/libcurl/lib/vtls/polarssl.h b/libcurl/lib/vtls/polarssl.h new file mode 100644 index 0000000..23c3636 --- /dev/null +++ b/libcurl/lib/vtls/polarssl.h @@ -0,0 +1,32 @@ +#ifndef HEADER_CURL_POLARSSL_H +#define HEADER_CURL_POLARSSL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2016, Daniel Stenberg, , et al. + * Copyright (C) 2010, Hoi-Ho Chan, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_POLARSSL + +extern const struct Curl_ssl Curl_ssl_polarssl; + +#endif /* USE_POLARSSL */ +#endif /* HEADER_CURL_POLARSSL_H */ diff --git a/libcurl/lib/vtls/polarssl_threadlock.c b/libcurl/lib/vtls/polarssl_threadlock.c new file mode 100644 index 0000000..27c94b1 --- /dev/null +++ b/libcurl/lib/vtls/polarssl_threadlock.c @@ -0,0 +1,144 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2013-2017, Daniel Stenberg, , et al. + * Copyright (C) 2010, 2011, Hoi-Ho Chan, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#if (defined(USE_POLARSSL) || defined(USE_MBEDTLS)) && \ + ((defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \ + (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H))) + +#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) +# include +# define POLARSSL_MUTEX_T pthread_mutex_t +#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) +# include +# define POLARSSL_MUTEX_T HANDLE +#endif + +#include "polarssl_threadlock.h" +#include "curl_printf.h" +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* number of thread locks */ +#define NUMT 2 + +/* This array will store all of the mutexes available to PolarSSL. */ +static POLARSSL_MUTEX_T *mutex_buf = NULL; + +int Curl_polarsslthreadlock_thread_setup(void) +{ + int i; + + mutex_buf = calloc(NUMT * sizeof(POLARSSL_MUTEX_T), 1); + if(!mutex_buf) + return 0; /* error, no number of threads defined */ + + for(i = 0; i < NUMT; i++) { + int ret; +#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) + ret = pthread_mutex_init(&mutex_buf[i], NULL); + if(ret) + return 0; /* pthread_mutex_init failed */ +#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) + mutex_buf[i] = CreateMutex(0, FALSE, 0); + if(mutex_buf[i] == 0) + return 0; /* CreateMutex failed */ +#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ + } + + return 1; /* OK */ +} + +int Curl_polarsslthreadlock_thread_cleanup(void) +{ + int i; + + if(!mutex_buf) + return 0; /* error, no threads locks defined */ + + for(i = 0; i < NUMT; i++) { + int ret; +#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) + ret = pthread_mutex_destroy(&mutex_buf[i]); + if(ret) + return 0; /* pthread_mutex_destroy failed */ +#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) + ret = CloseHandle(mutex_buf[i]); + if(!ret) + return 0; /* CloseHandle failed */ +#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ + } + free(mutex_buf); + mutex_buf = NULL; + + return 1; /* OK */ +} + +int Curl_polarsslthreadlock_lock_function(int n) +{ + if(n < NUMT) { + int ret; +#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) + ret = pthread_mutex_lock(&mutex_buf[n]); + if(ret) { + DEBUGF(fprintf(stderr, + "Error: polarsslthreadlock_lock_function failed\n")); + return 0; /* pthread_mutex_lock failed */ + } +#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) + ret = (WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED?1:0); + if(ret) { + DEBUGF(fprintf(stderr, + "Error: polarsslthreadlock_lock_function failed\n")); + return 0; /* pthread_mutex_lock failed */ + } +#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ + } + return 1; /* OK */ +} + +int Curl_polarsslthreadlock_unlock_function(int n) +{ + if(n < NUMT) { + int ret; +#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) + ret = pthread_mutex_unlock(&mutex_buf[n]); + if(ret) { + DEBUGF(fprintf(stderr, + "Error: polarsslthreadlock_unlock_function failed\n")); + return 0; /* pthread_mutex_unlock failed */ + } +#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) + ret = ReleaseMutex(mutex_buf[n]); + if(!ret) { + DEBUGF(fprintf(stderr, + "Error: polarsslthreadlock_unlock_function failed\n")); + return 0; /* pthread_mutex_lock failed */ + } +#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ + } + return 1; /* OK */ +} + +#endif /* USE_POLARSSL || USE_MBEDTLS */ diff --git a/libcurl/lib/vtls/polarssl_threadlock.h b/libcurl/lib/vtls/polarssl_threadlock.h new file mode 100644 index 0000000..1226475 --- /dev/null +++ b/libcurl/lib/vtls/polarssl_threadlock.h @@ -0,0 +1,48 @@ +#ifndef HEADER_CURL_POLARSSL_THREADLOCK_H +#define HEADER_CURL_POLARSSL_THREADLOCK_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2013-2015, Daniel Stenberg, , et al. + * Copyright (C) 2010, Hoi-Ho Chan, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#if (defined USE_POLARSSL) || (defined USE_MBEDTLS) + +#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \ + (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)) + +int Curl_polarsslthreadlock_thread_setup(void); +int Curl_polarsslthreadlock_thread_cleanup(void); +int Curl_polarsslthreadlock_lock_function(int n); +int Curl_polarsslthreadlock_unlock_function(int n); + +#else + +#define Curl_polarsslthreadlock_thread_setup() 1 +#define Curl_polarsslthreadlock_thread_cleanup() 1 +#define Curl_polarsslthreadlock_lock_function(x) 1 +#define Curl_polarsslthreadlock_unlock_function(x) 1 + +#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */ + +#endif /* USE_POLARSSL */ + +#endif /* HEADER_CURL_POLARSSL_THREADLOCK_H */ diff --git a/libcurl/lib/vtls/schannel.c b/libcurl/lib/vtls/schannel.c new file mode 100644 index 0000000..0f6f734 --- /dev/null +++ b/libcurl/lib/vtls/schannel.c @@ -0,0 +1,2302 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2016, Marc Hoersken, + * Copyright (C) 2012, Mark Salisbury, + * Copyright (C) 2012 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all Schannel-specific code for the TLS/SSL layer. No code + * but vtls.c should ever call or use these functions. + */ + +/* + * Based upon the PolarSSL implementation in polarssl.c and polarssl.h: + * Copyright (C) 2010, 2011, Hoi-Ho Chan, + * + * Based upon the CyaSSL implementation in cyassl.c and cyassl.h: + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * Thanks for code and inspiration! + */ + +#include "curl_setup.h" + +#ifdef USE_SCHANNEL + +#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS + +#ifndef USE_WINDOWS_SSPI +# error "Can't compile SCHANNEL support without SSPI." +#endif + +#include "schannel.h" +#include "vtls.h" +#include "sendf.h" +#include "connect.h" /* for the connect timeout */ +#include "strerror.h" +#include "select.h" /* for the socket readyness */ +#include "inet_pton.h" /* for IP addr SNI check */ +#include "curl_multibyte.h" +#include "warnless.h" +#include "x509asn1.h" +#include "curl_printf.h" +#include "multiif.h" +#include "system_win32.h" + + /* The last #include file should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* ALPN requires version 8.1 of the Windows SDK, which was + shipped with Visual Studio 2013, aka _MSC_VER 1800: + + https://technet.microsoft.com/en-us/library/hh831771%28v=ws.11%29.aspx +*/ +#if defined(_MSC_VER) && (_MSC_VER >= 1800) && !defined(_USING_V110_SDK71_) +# define HAS_ALPN 1 +#endif + +#ifndef UNISP_NAME_A +#define UNISP_NAME_A "Microsoft Unified Security Protocol Provider" +#endif + +#ifndef UNISP_NAME_W +#define UNISP_NAME_W L"Microsoft Unified Security Protocol Provider" +#endif + +#ifndef UNISP_NAME +#ifdef UNICODE +#define UNISP_NAME UNISP_NAME_W +#else +#define UNISP_NAME UNISP_NAME_A +#endif +#endif + +#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) +#define HAS_CLIENT_CERT_PATH +#endif + +#ifdef HAS_CLIENT_CERT_PATH +#ifdef UNICODE +#define CURL_CERT_STORE_PROV_SYSTEM CERT_STORE_PROV_SYSTEM_W +#else +#define CURL_CERT_STORE_PROV_SYSTEM CERT_STORE_PROV_SYSTEM_A +#endif +#endif + +#ifndef SP_PROT_SSL2_CLIENT +#define SP_PROT_SSL2_CLIENT 0x00000008 +#endif + +#ifndef SP_PROT_SSL3_CLIENT +#define SP_PROT_SSL3_CLIENT 0x00000008 +#endif + +#ifndef SP_PROT_TLS1_CLIENT +#define SP_PROT_TLS1_CLIENT 0x00000080 +#endif + +#ifndef SP_PROT_TLS1_0_CLIENT +#define SP_PROT_TLS1_0_CLIENT SP_PROT_TLS1_CLIENT +#endif + +#ifndef SP_PROT_TLS1_1_CLIENT +#define SP_PROT_TLS1_1_CLIENT 0x00000200 +#endif + +#ifndef SP_PROT_TLS1_2_CLIENT +#define SP_PROT_TLS1_2_CLIENT 0x00000800 +#endif + +#ifndef SECBUFFER_ALERT +#define SECBUFFER_ALERT 17 +#endif + +/* Both schannel buffer sizes must be > 0 */ +#define CURL_SCHANNEL_BUFFER_INIT_SIZE 4096 +#define CURL_SCHANNEL_BUFFER_FREE_SIZE 1024 + +#define CERT_THUMBPRINT_STR_LEN 40 +#define CERT_THUMBPRINT_DATA_LEN 20 + +/* Uncomment to force verbose output + * #define infof(x, y, ...) printf(y, __VA_ARGS__) + * #define failf(x, y, ...) printf(y, __VA_ARGS__) + */ + +#ifndef CALG_SHA_256 +# define CALG_SHA_256 0x0000800c +#endif + +#define BACKEND connssl->backend + +static Curl_recv schannel_recv; +static Curl_send schannel_send; + +static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, + const char *pinnedpubkey); + +static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType, + void *BufDataPtr, unsigned long BufByteSize) +{ + buffer->cbBuffer = BufByteSize; + buffer->BufferType = BufType; + buffer->pvBuffer = BufDataPtr; +} + +static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr, + unsigned long NumArrElem) +{ + desc->ulVersion = SECBUFFER_VERSION; + desc->pBuffers = BufArr; + desc->cBuffers = NumArrElem; +} + +static CURLcode +set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + long ssl_version = SSL_CONN_CONFIG(version); + long ssl_version_max = SSL_CONN_CONFIG(version_max); + long i = ssl_version; + + switch(ssl_version_max) { + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_DEFAULT: + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; + break; + } + for(; i <= (ssl_version_max >> 16); ++i) { + switch(i) { + case CURL_SSLVERSION_TLSv1_0: + schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_0_CLIENT; + break; + case CURL_SSLVERSION_TLSv1_1: + schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT; + break; + case CURL_SSLVERSION_TLSv1_2: + schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT; + break; + case CURL_SSLVERSION_TLSv1_3: + failf(data, "schannel: TLS 1.3 is not yet supported"); + return CURLE_SSL_CONNECT_ERROR; + } + } + return CURLE_OK; +} + +/*longest is 26, buffer is slightly bigger*/ +#define LONGEST_ALG_ID 32 +#define CIPHEROPTION(X) \ +if(strcmp(#X, tmp) == 0) \ + return X + +static int +get_alg_id_by_name(char *name) +{ + char tmp[LONGEST_ALG_ID] = { 0 }; + char *nameEnd = strchr(name, ':'); + size_t n = nameEnd ? min((size_t)(nameEnd - name), LONGEST_ALG_ID - 1) : \ + min(strlen(name), LONGEST_ALG_ID - 1); + strncpy(tmp, name, n); + tmp[n] = 0; + CIPHEROPTION(CALG_MD2); + CIPHEROPTION(CALG_MD4); + CIPHEROPTION(CALG_MD5); + CIPHEROPTION(CALG_SHA); + CIPHEROPTION(CALG_SHA1); + CIPHEROPTION(CALG_MAC); + CIPHEROPTION(CALG_RSA_SIGN); + CIPHEROPTION(CALG_DSS_SIGN); +/*ifdefs for the options that are defined conditionally in wincrypt.h*/ +#ifdef CALG_NO_SIGN + CIPHEROPTION(CALG_NO_SIGN); +#endif + CIPHEROPTION(CALG_RSA_KEYX); + CIPHEROPTION(CALG_DES); +#ifdef CALG_3DES_112 + CIPHEROPTION(CALG_3DES_112); +#endif + CIPHEROPTION(CALG_3DES); + CIPHEROPTION(CALG_DESX); + CIPHEROPTION(CALG_RC2); + CIPHEROPTION(CALG_RC4); + CIPHEROPTION(CALG_SEAL); +#ifdef CALG_DH_SF + CIPHEROPTION(CALG_DH_SF); +#endif + CIPHEROPTION(CALG_DH_EPHEM); +#ifdef CALG_AGREEDKEY_ANY + CIPHEROPTION(CALG_AGREEDKEY_ANY); +#endif +#ifdef CALG_HUGHES_MD5 + CIPHEROPTION(CALG_HUGHES_MD5); +#endif + CIPHEROPTION(CALG_SKIPJACK); +#ifdef CALG_TEK + CIPHEROPTION(CALG_TEK); +#endif + CIPHEROPTION(CALG_CYLINK_MEK); + CIPHEROPTION(CALG_SSL3_SHAMD5); +#ifdef CALG_SSL3_MASTER + CIPHEROPTION(CALG_SSL3_MASTER); +#endif +#ifdef CALG_SCHANNEL_MASTER_HASH + CIPHEROPTION(CALG_SCHANNEL_MASTER_HASH); +#endif +#ifdef CALG_SCHANNEL_MAC_KEY + CIPHEROPTION(CALG_SCHANNEL_MAC_KEY); +#endif +#ifdef CALG_SCHANNEL_ENC_KEY + CIPHEROPTION(CALG_SCHANNEL_ENC_KEY); +#endif +#ifdef CALG_PCT1_MASTER + CIPHEROPTION(CALG_PCT1_MASTER); +#endif +#ifdef CALG_SSL2_MASTER + CIPHEROPTION(CALG_SSL2_MASTER); +#endif +#ifdef CALG_TLS1_MASTER + CIPHEROPTION(CALG_TLS1_MASTER); +#endif +#ifdef CALG_RC5 + CIPHEROPTION(CALG_RC5); +#endif +#ifdef CALG_HMAC + CIPHEROPTION(CALG_HMAC); +#endif +#if !defined(__W32API_MAJOR_VERSION) || \ + !defined(__W32API_MINOR_VERSION) || \ + defined(__MINGW64_VERSION_MAJOR) || \ + (__W32API_MAJOR_VERSION > 5) || \ + ((__W32API_MAJOR_VERSION == 5) && (__W32API_MINOR_VERSION > 0)) + /* CALG_TLS1PRF has a syntax error in MinGW's w32api up to version 5.0, + see https://osdn.net/projects/mingw/ticket/38391 */ + CIPHEROPTION(CALG_TLS1PRF); +#endif +#ifdef CALG_HASH_REPLACE_OWF + CIPHEROPTION(CALG_HASH_REPLACE_OWF); +#endif +#ifdef CALG_AES_128 + CIPHEROPTION(CALG_AES_128); +#endif +#ifdef CALG_AES_192 + CIPHEROPTION(CALG_AES_192); +#endif +#ifdef CALG_AES_256 + CIPHEROPTION(CALG_AES_256); +#endif +#ifdef CALG_AES + CIPHEROPTION(CALG_AES); +#endif +#ifdef CALG_SHA_256 + CIPHEROPTION(CALG_SHA_256); +#endif +#ifdef CALG_SHA_384 + CIPHEROPTION(CALG_SHA_384); +#endif +#ifdef CALG_SHA_512 + CIPHEROPTION(CALG_SHA_512); +#endif +#ifdef CALG_ECDH + CIPHEROPTION(CALG_ECDH); +#endif +#ifdef CALG_ECMQV + CIPHEROPTION(CALG_ECMQV); +#endif +#ifdef CALG_ECDSA + CIPHEROPTION(CALG_ECDSA); +#endif +#ifdef CALG_ECDH_EPHEM + CIPHEROPTION(CALG_ECDH_EPHEM); +#endif + return 0; +} + +static CURLcode +set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers) +{ + char *startCur = ciphers; + int algCount = 0; + static ALG_ID algIds[45]; /*There are 45 listed in the MS headers*/ + while(startCur && (0 != *startCur) && (algCount < 45)) { + long alg = strtol(startCur, 0, 0); + if(!alg) + alg = get_alg_id_by_name(startCur); + if(alg) + algIds[algCount++] = alg; + else + return CURLE_SSL_CIPHER; + startCur = strchr(startCur, ':'); + if(startCur) + startCur++; + } + schannel_cred->palgSupportedAlgs = algIds; + schannel_cred->cSupportedAlgs = algCount; + return CURLE_OK; +} + +#ifdef HAS_CLIENT_CERT_PATH +static CURLcode +get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, + TCHAR **thumbprint) +{ + TCHAR *sep; + TCHAR *store_path_start; + size_t store_name_len; + + sep = _tcschr(path, TEXT('\\')); + if(sep == NULL) + return CURLE_SSL_CERTPROBLEM; + + store_name_len = sep - path; + + if(_tcsnccmp(path, TEXT("CurrentUser"), store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_CURRENT_USER; + else if(_tcsnccmp(path, TEXT("LocalMachine"), store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE; + else if(_tcsnccmp(path, TEXT("CurrentService"), store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_CURRENT_SERVICE; + else if(_tcsnccmp(path, TEXT("Services"), store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_SERVICES; + else if(_tcsnccmp(path, TEXT("Users"), store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_USERS; + else if(_tcsnccmp(path, TEXT("CurrentUserGroupPolicy"), + store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY; + else if(_tcsnccmp(path, TEXT("LocalMachineGroupPolicy"), + store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY; + else if(_tcsnccmp(path, TEXT("LocalMachineEnterprise"), + store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE; + else + return CURLE_SSL_CERTPROBLEM; + + store_path_start = sep + 1; + + sep = _tcschr(store_path_start, TEXT('\\')); + if(sep == NULL) + return CURLE_SSL_CERTPROBLEM; + + *sep = TEXT('\0'); + *store_path = _tcsdup(store_path_start); + *sep = TEXT('\\'); + if(*store_path == NULL) + return CURLE_OUT_OF_MEMORY; + + *thumbprint = sep + 1; + if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN) + return CURLE_SSL_CERTPROBLEM; + + return CURLE_OK; +} +#endif + +static CURLcode +schannel_connect_step1(struct connectdata *conn, int sockindex) +{ + ssize_t written = -1; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + SecBuffer outbuf; + SecBufferDesc outbuf_desc; + SecBuffer inbuf; + SecBufferDesc inbuf_desc; +#ifdef HAS_ALPN + unsigned char alpn_buffer[128]; +#endif + SCHANNEL_CRED schannel_cred; + PCCERT_CONTEXT client_certs[1] = { NULL }; + SECURITY_STATUS sspi_status = SEC_E_OK; + struct curl_schannel_cred *old_cred = NULL; + struct in_addr addr; +#ifdef ENABLE_IPV6 + struct in6_addr addr6; +#endif + TCHAR *host_name; + CURLcode result; + char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + + DEBUGF(infof(data, + "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n", + hostname, conn->remote_port)); + + if(Curl_verify_windows_version(5, 1, PLATFORM_WINNT, + VERSION_LESS_THAN_EQUAL)) { + /* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and + algorithms that may not be supported by all servers. */ + infof(data, "schannel: Windows version is old and may not be able to " + "connect to some servers due to lack of SNI, algorithms, etc.\n"); + } + +#ifdef HAS_ALPN + /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above. + Also it doesn't seem to be supported for Wine, see curl bug #983. */ + BACKEND->use_alpn = conn->bits.tls_enable_alpn && + !GetProcAddress(GetModuleHandleA("ntdll"), + "wine_get_version") && + Curl_verify_windows_version(6, 3, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL); +#else + BACKEND->use_alpn = false; +#endif + +#ifdef _WIN32_WCE +#ifdef HAS_MANUAL_VERIFY_API + /* certificate validation on CE doesn't seem to work right; we'll + * do it following a more manual process. */ + BACKEND->use_manual_cred_validation = true; +#else +#error "compiler too old to support requisite manual cert verify for Win CE" +#endif +#else +#ifdef HAS_MANUAL_VERIFY_API + if(SSL_CONN_CONFIG(CAfile)) { + if(Curl_verify_windows_version(6, 1, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) { + BACKEND->use_manual_cred_validation = true; + } + else { + failf(data, "schannel: this version of Windows is too old to support " + "certificate verification via CA bundle file."); + return CURLE_SSL_CACERT_BADFILE; + } + } + else + BACKEND->use_manual_cred_validation = false; +#else + if(SSL_CONN_CONFIG(CAfile)) { + failf(data, "schannel: CA cert support not built in"); + return CURLE_NOT_BUILT_IN; + } +#endif +#endif + + BACKEND->cred = NULL; + + /* check for an existing re-usable credential handle */ + if(SSL_SET_OPTION(primary.sessionid)) { + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) { + BACKEND->cred = old_cred; + DEBUGF(infof(data, "schannel: re-using existing credential handle\n")); + + /* increment the reference counter of the credential/session handle */ + BACKEND->cred->refcount++; + DEBUGF(infof(data, + "schannel: incremented credential handle refcount = %d\n", + BACKEND->cred->refcount)); + } + Curl_ssl_sessionid_unlock(conn); + } + + if(!BACKEND->cred) { + /* setup Schannel API options */ + memset(&schannel_cred, 0, sizeof(schannel_cred)); + schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; + + if(conn->ssl_config.verifypeer) { +#ifdef HAS_MANUAL_VERIFY_API + if(BACKEND->use_manual_cred_validation) + schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION; + else +#endif + schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION; + + if(data->set.ssl.no_revoke) { + schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | + SCH_CRED_IGNORE_REVOCATION_OFFLINE; + + DEBUGF(infof(data, "schannel: disabled server certificate revocation " + "checks\n")); + } + else { + schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN; + DEBUGF(infof(data, + "schannel: checking server certificate revocation\n")); + } + } + else { + schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | + SCH_CRED_IGNORE_NO_REVOCATION_CHECK | + SCH_CRED_IGNORE_REVOCATION_OFFLINE; + DEBUGF(infof(data, + "schannel: disabled server cert revocation checks\n")); + } + + if(!conn->ssl_config.verifyhost) { + schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK; + DEBUGF(infof(data, "schannel: verifyhost setting prevents Schannel from " + "comparing the supplied target name with the subject " + "names in server certificates.\n")); + } + + switch(conn->ssl_config.version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT | + SP_PROT_TLS1_1_CLIENT | + SP_PROT_TLS1_2_CLIENT; + break; + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + { + result = set_ssl_version_min_max(&schannel_cred, conn); + if(result != CURLE_OK) + return result; + break; + } + case CURL_SSLVERSION_SSLv3: + schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT; + break; + case CURL_SSLVERSION_SSLv2: + schannel_cred.grbitEnabledProtocols = SP_PROT_SSL2_CLIENT; + break; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + if(SSL_CONN_CONFIG(cipher_list)) { + result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list)); + if(CURLE_OK != result) { + failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG"); + return result; + } + } + + +#ifdef HAS_CLIENT_CERT_PATH + /* client certificate */ + if(data->set.ssl.cert) { + DWORD cert_store_name; + TCHAR *cert_store_path; + TCHAR *cert_thumbprint_str; + CRYPT_HASH_BLOB cert_thumbprint; + BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN]; + HCERTSTORE cert_store; + + TCHAR *cert_path = Curl_convert_UTF8_to_tchar(data->set.ssl.cert); + if(!cert_path) + return CURLE_OUT_OF_MEMORY; + + result = get_cert_location(cert_path, &cert_store_name, + &cert_store_path, &cert_thumbprint_str); + if(result != CURLE_OK) { + failf(data, "schannel: Failed to get certificate location for %s", + cert_path); + Curl_unicodefree(cert_path); + return result; + } + + cert_store = + CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0, + (HCRYPTPROV)NULL, + CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name, + cert_store_path); + if(!cert_store) { + failf(data, "schannel: Failed to open cert store %x %s, " + "last error is %x", + cert_store_name, cert_store_path, GetLastError()); + free(cert_store_path); + Curl_unicodefree(cert_path); + return CURLE_SSL_CERTPROBLEM; + } + free(cert_store_path); + + cert_thumbprint.pbData = cert_thumbprint_data; + cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN; + + if(!CryptStringToBinary(cert_thumbprint_str, CERT_THUMBPRINT_STR_LEN, + CRYPT_STRING_HEX, + cert_thumbprint_data, &cert_thumbprint.cbData, + NULL, NULL)) { + Curl_unicodefree(cert_path); + return CURLE_SSL_CERTPROBLEM; + } + + client_certs[0] = CertFindCertificateInStore( + cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, + CERT_FIND_HASH, &cert_thumbprint, NULL); + + Curl_unicodefree(cert_path); + + if(client_certs[0]) { + schannel_cred.cCreds = 1; + schannel_cred.paCred = client_certs; + } + else { + /* CRYPT_E_NOT_FOUND / E_INVALIDARG */ + return CURLE_SSL_CERTPROBLEM; + } + + CertCloseStore(cert_store, 0); + } +#else + if(data->set.ssl.cert) { + failf(data, "schannel: client cert support not built in"); + return CURLE_NOT_BUILT_IN; + } +#endif + + /* allocate memory for the re-usable credential handle */ + BACKEND->cred = (struct curl_schannel_cred *) + calloc(1, sizeof(struct curl_schannel_cred)); + if(!BACKEND->cred) { + failf(data, "schannel: unable to allocate memory"); + + if(client_certs[0]) + CertFreeCertificateContext(client_certs[0]); + + return CURLE_OUT_OF_MEMORY; + } + BACKEND->cred->refcount = 1; + + /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx + */ + sspi_status = + s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME, + SECPKG_CRED_OUTBOUND, NULL, + &schannel_cred, NULL, NULL, + &BACKEND->cred->cred_handle, + &BACKEND->cred->time_stamp); + + if(client_certs[0]) + CertFreeCertificateContext(client_certs[0]); + + if(sspi_status != SEC_E_OK) { + char buffer[STRERROR_LEN]; + failf(data, "schannel: AcquireCredentialsHandle failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + Curl_safefree(BACKEND->cred); + switch(sspi_status) { + case SEC_E_INSUFFICIENT_MEMORY: + return CURLE_OUT_OF_MEMORY; + case SEC_E_NO_CREDENTIALS: + case SEC_E_SECPKG_NOT_FOUND: + case SEC_E_NOT_OWNER: + case SEC_E_UNKNOWN_CREDENTIALS: + case SEC_E_INTERNAL_ERROR: + default: + return CURLE_SSL_CONNECT_ERROR; + } + } + } + + /* Warn if SNI is disabled due to use of an IP address */ + if(Curl_inet_pton(AF_INET, hostname, &addr) +#ifdef ENABLE_IPV6 + || Curl_inet_pton(AF_INET6, hostname, &addr6) +#endif + ) { + infof(data, "schannel: using IP address, SNI is not supported by OS.\n"); + } + +#ifdef HAS_ALPN + if(BACKEND->use_alpn) { + int cur = 0; + int list_start_index = 0; + unsigned int *extension_len = NULL; + unsigned short* list_len = NULL; + + /* The first four bytes will be an unsigned int indicating number + of bytes of data in the rest of the the buffer. */ + extension_len = (unsigned int *)(&alpn_buffer[cur]); + cur += sizeof(unsigned int); + + /* The next four bytes are an indicator that this buffer will contain + ALPN data, as opposed to NPN, for example. */ + *(unsigned int *)&alpn_buffer[cur] = + SecApplicationProtocolNegotiationExt_ALPN; + cur += sizeof(unsigned int); + + /* The next two bytes will be an unsigned short indicating the number + of bytes used to list the preferred protocols. */ + list_len = (unsigned short*)(&alpn_buffer[cur]); + cur += sizeof(unsigned short); + + list_start_index = cur; + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2) { + memcpy(&alpn_buffer[cur], NGHTTP2_PROTO_ALPN, NGHTTP2_PROTO_ALPN_LEN); + cur += NGHTTP2_PROTO_ALPN_LEN; + infof(data, "schannel: ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + alpn_buffer[cur++] = ALPN_HTTP_1_1_LENGTH; + memcpy(&alpn_buffer[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH); + cur += ALPN_HTTP_1_1_LENGTH; + infof(data, "schannel: ALPN, offering %s\n", ALPN_HTTP_1_1); + + *list_len = curlx_uitous(cur - list_start_index); + *extension_len = *list_len + sizeof(unsigned int) + sizeof(unsigned short); + + InitSecBuffer(&inbuf, SECBUFFER_APPLICATION_PROTOCOLS, alpn_buffer, cur); + InitSecBufferDesc(&inbuf_desc, &inbuf, 1); + } + else { + InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0); + InitSecBufferDesc(&inbuf_desc, &inbuf, 1); + } +#else /* HAS_ALPN */ + InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0); + InitSecBufferDesc(&inbuf_desc, &inbuf, 1); +#endif + + /* setup output buffer */ + InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0); + InitSecBufferDesc(&outbuf_desc, &outbuf, 1); + + /* setup request flags */ + BACKEND->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | + ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY | + ISC_REQ_STREAM; + + /* allocate memory for the security context handle */ + BACKEND->ctxt = (struct curl_schannel_ctxt *) + calloc(1, sizeof(struct curl_schannel_ctxt)); + if(!BACKEND->ctxt) { + failf(data, "schannel: unable to allocate memory"); + return CURLE_OUT_OF_MEMORY; + } + + host_name = Curl_convert_UTF8_to_tchar(hostname); + if(!host_name) + return CURLE_OUT_OF_MEMORY; + + /* Schannel InitializeSecurityContext: + https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx + + At the moment we don't pass inbuf unless we're using ALPN since we only + use it for that, and Wine (for which we currently disable ALPN) is giving + us problems with inbuf regardless. https://github.com/curl/curl/issues/983 + */ + sspi_status = s_pSecFn->InitializeSecurityContext( + &BACKEND->cred->cred_handle, NULL, host_name, BACKEND->req_flags, 0, 0, + (BACKEND->use_alpn ? &inbuf_desc : NULL), + 0, &BACKEND->ctxt->ctxt_handle, + &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp); + + Curl_unicodefree(host_name); + + if(sspi_status != SEC_I_CONTINUE_NEEDED) { + char buffer[STRERROR_LEN]; + Curl_safefree(BACKEND->ctxt); + switch(sspi_status) { + case SEC_E_INSUFFICIENT_MEMORY: + failf(data, "schannel: initial InitializeSecurityContext failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_OUT_OF_MEMORY; + case SEC_E_WRONG_PRINCIPAL: + failf(data, "schannel: SNI or certificate check failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_PEER_FAILED_VERIFICATION; + /* + case SEC_E_INVALID_HANDLE: + case SEC_E_INVALID_TOKEN: + case SEC_E_LOGON_DENIED: + case SEC_E_TARGET_UNKNOWN: + case SEC_E_NO_AUTHENTICATING_AUTHORITY: + case SEC_E_INTERNAL_ERROR: + case SEC_E_NO_CREDENTIALS: + case SEC_E_UNSUPPORTED_FUNCTION: + case SEC_E_APPLICATION_PROTOCOL_MISMATCH: + */ + default: + failf(data, "schannel: initial InitializeSecurityContext failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_SSL_CONNECT_ERROR; + } + } + + DEBUGF(infof(data, "schannel: sending initial handshake data: " + "sending %lu bytes...\n", outbuf.cbBuffer)); + + /* send initial handshake data which is now stored in output buffer */ + result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer, + outbuf.cbBuffer, &written); + s_pSecFn->FreeContextBuffer(outbuf.pvBuffer); + if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) { + failf(data, "schannel: failed to send initial handshake data: " + "sent %zd of %lu bytes", written, outbuf.cbBuffer); + return CURLE_SSL_CONNECT_ERROR; + } + + DEBUGF(infof(data, "schannel: sent initial handshake data: " + "sent %zd bytes\n", written)); + + BACKEND->recv_unrecoverable_err = CURLE_OK; + BACKEND->recv_sspi_close_notify = false; + BACKEND->recv_connection_closed = false; + BACKEND->encdata_is_incomplete = false; + + /* continue to second handshake step */ + connssl->connecting_state = ssl_connect_2; + + return CURLE_OK; +} + +static CURLcode +schannel_connect_step2(struct connectdata *conn, int sockindex) +{ + int i; + ssize_t nread = -1, written = -1; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + unsigned char *reallocated_buffer; + SecBuffer outbuf[3]; + SecBufferDesc outbuf_desc; + SecBuffer inbuf[2]; + SecBufferDesc inbuf_desc; + SECURITY_STATUS sspi_status = SEC_E_OK; + CURLcode result; + bool doread; + char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const char *pubkey_ptr; + + doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE; + + DEBUGF(infof(data, + "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n", + hostname, conn->remote_port)); + + if(!BACKEND->cred || !BACKEND->ctxt) + return CURLE_SSL_CONNECT_ERROR; + + /* buffer to store previously received and decrypted data */ + if(BACKEND->decdata_buffer == NULL) { + BACKEND->decdata_offset = 0; + BACKEND->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE; + BACKEND->decdata_buffer = malloc(BACKEND->decdata_length); + if(BACKEND->decdata_buffer == NULL) { + failf(data, "schannel: unable to allocate memory"); + return CURLE_OUT_OF_MEMORY; + } + } + + /* buffer to store previously received and encrypted data */ + if(BACKEND->encdata_buffer == NULL) { + BACKEND->encdata_is_incomplete = false; + BACKEND->encdata_offset = 0; + BACKEND->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE; + BACKEND->encdata_buffer = malloc(BACKEND->encdata_length); + if(BACKEND->encdata_buffer == NULL) { + failf(data, "schannel: unable to allocate memory"); + return CURLE_OUT_OF_MEMORY; + } + } + + /* if we need a bigger buffer to read a full message, increase buffer now */ + if(BACKEND->encdata_length - BACKEND->encdata_offset < + CURL_SCHANNEL_BUFFER_FREE_SIZE) { + /* increase internal encrypted data buffer */ + size_t reallocated_length = BACKEND->encdata_offset + + CURL_SCHANNEL_BUFFER_FREE_SIZE; + reallocated_buffer = realloc(BACKEND->encdata_buffer, + reallocated_length); + + if(reallocated_buffer == NULL) { + failf(data, "schannel: unable to re-allocate memory"); + return CURLE_OUT_OF_MEMORY; + } + else { + BACKEND->encdata_buffer = reallocated_buffer; + BACKEND->encdata_length = reallocated_length; + } + } + + for(;;) { + TCHAR *host_name; + if(doread) { + /* read encrypted handshake data from socket */ + result = Curl_read_plain(conn->sock[sockindex], + (char *) (BACKEND->encdata_buffer + + BACKEND->encdata_offset), + BACKEND->encdata_length - + BACKEND->encdata_offset, + &nread); + if(result == CURLE_AGAIN) { + if(connssl->connecting_state != ssl_connect_2_writing) + connssl->connecting_state = ssl_connect_2_reading; + DEBUGF(infof(data, "schannel: failed to receive handshake, " + "need more data\n")); + return CURLE_OK; + } + else if((result != CURLE_OK) || (nread == 0)) { + failf(data, "schannel: failed to receive handshake, " + "SSL/TLS connection failed"); + return CURLE_SSL_CONNECT_ERROR; + } + + /* increase encrypted data buffer offset */ + BACKEND->encdata_offset += nread; + BACKEND->encdata_is_incomplete = false; + DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread)); + } + + DEBUGF(infof(data, + "schannel: encrypted data buffer: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); + + /* setup input buffers */ + InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(BACKEND->encdata_offset), + curlx_uztoul(BACKEND->encdata_offset)); + InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0); + InitSecBufferDesc(&inbuf_desc, inbuf, 2); + + /* setup output buffers */ + InitSecBuffer(&outbuf[0], SECBUFFER_TOKEN, NULL, 0); + InitSecBuffer(&outbuf[1], SECBUFFER_ALERT, NULL, 0); + InitSecBuffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0); + InitSecBufferDesc(&outbuf_desc, outbuf, 3); + + if(inbuf[0].pvBuffer == NULL) { + failf(data, "schannel: unable to allocate memory"); + return CURLE_OUT_OF_MEMORY; + } + + /* copy received handshake data into input buffer */ + memcpy(inbuf[0].pvBuffer, BACKEND->encdata_buffer, + BACKEND->encdata_offset); + + host_name = Curl_convert_UTF8_to_tchar(hostname); + if(!host_name) + return CURLE_OUT_OF_MEMORY; + + /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx + */ + sspi_status = s_pSecFn->InitializeSecurityContext( + &BACKEND->cred->cred_handle, &BACKEND->ctxt->ctxt_handle, + host_name, BACKEND->req_flags, 0, 0, &inbuf_desc, 0, NULL, + &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp); + + Curl_unicodefree(host_name); + + /* free buffer for received handshake data */ + Curl_safefree(inbuf[0].pvBuffer); + + /* check if the handshake was incomplete */ + if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) { + BACKEND->encdata_is_incomplete = true; + connssl->connecting_state = ssl_connect_2_reading; + DEBUGF(infof(data, + "schannel: received incomplete message, need more data\n")); + return CURLE_OK; + } + + /* If the server has requested a client certificate, attempt to continue + the handshake without one. This will allow connections to servers which + request a client certificate but do not require it. */ + if(sspi_status == SEC_I_INCOMPLETE_CREDENTIALS && + !(BACKEND->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) { + BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS; + connssl->connecting_state = ssl_connect_2_writing; + DEBUGF(infof(data, + "schannel: a client certificate has been requested\n")); + return CURLE_OK; + } + + /* check if the handshake needs to be continued */ + if(sspi_status == SEC_I_CONTINUE_NEEDED || sspi_status == SEC_E_OK) { + for(i = 0; i < 3; i++) { + /* search for handshake tokens that need to be send */ + if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) { + DEBUGF(infof(data, "schannel: sending next handshake data: " + "sending %lu bytes...\n", outbuf[i].cbBuffer)); + + /* send handshake token to server */ + result = Curl_write_plain(conn, conn->sock[sockindex], + outbuf[i].pvBuffer, outbuf[i].cbBuffer, + &written); + if((result != CURLE_OK) || + (outbuf[i].cbBuffer != (size_t) written)) { + failf(data, "schannel: failed to send next handshake data: " + "sent %zd of %lu bytes", written, outbuf[i].cbBuffer); + return CURLE_SSL_CONNECT_ERROR; + } + } + + /* free obsolete buffer */ + if(outbuf[i].pvBuffer != NULL) { + s_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer); + } + } + } + else { + char buffer[STRERROR_LEN]; + switch(sspi_status) { + case SEC_E_INSUFFICIENT_MEMORY: + failf(data, "schannel: next InitializeSecurityContext failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_OUT_OF_MEMORY; + case SEC_E_WRONG_PRINCIPAL: + failf(data, "schannel: SNI or certificate check failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_PEER_FAILED_VERIFICATION; + /* + case SEC_E_INVALID_HANDLE: + case SEC_E_INVALID_TOKEN: + case SEC_E_LOGON_DENIED: + case SEC_E_TARGET_UNKNOWN: + case SEC_E_NO_AUTHENTICATING_AUTHORITY: + case SEC_E_INTERNAL_ERROR: + case SEC_E_NO_CREDENTIALS: + case SEC_E_UNSUPPORTED_FUNCTION: + case SEC_E_APPLICATION_PROTOCOL_MISMATCH: + */ + default: + failf(data, "schannel: next InitializeSecurityContext failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_SSL_CONNECT_ERROR; + } + } + + /* check if there was additional remaining encrypted data */ + if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) { + DEBUGF(infof(data, "schannel: encrypted data length: %lu\n", + inbuf[1].cbBuffer)); + /* + There are two cases where we could be getting extra data here: + 1) If we're renegotiating a connection and the handshake is already + complete (from the server perspective), it can encrypted app data + (not handshake data) in an extra buffer at this point. + 2) (sspi_status == SEC_I_CONTINUE_NEEDED) We are negotiating a + connection and this extra data is part of the handshake. + We should process the data immediately; waiting for the socket to + be ready may fail since the server is done sending handshake data. + */ + /* check if the remaining data is less than the total amount + and therefore begins after the already processed data */ + if(BACKEND->encdata_offset > inbuf[1].cbBuffer) { + memmove(BACKEND->encdata_buffer, + (BACKEND->encdata_buffer + BACKEND->encdata_offset) - + inbuf[1].cbBuffer, inbuf[1].cbBuffer); + BACKEND->encdata_offset = inbuf[1].cbBuffer; + if(sspi_status == SEC_I_CONTINUE_NEEDED) { + doread = FALSE; + continue; + } + } + } + else { + BACKEND->encdata_offset = 0; + } + break; + } + + /* check if the handshake needs to be continued */ + if(sspi_status == SEC_I_CONTINUE_NEEDED) { + connssl->connecting_state = ssl_connect_2_reading; + return CURLE_OK; + } + + /* check if the handshake is complete */ + if(sspi_status == SEC_E_OK) { + connssl->connecting_state = ssl_connect_3; + DEBUGF(infof(data, "schannel: SSL/TLS handshake complete\n")); + } + + pubkey_ptr = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + if(pubkey_ptr) { + result = pkp_pin_peer_pubkey(conn, sockindex, pubkey_ptr); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + return result; + } + } + +#ifdef HAS_MANUAL_VERIFY_API + if(conn->ssl_config.verifypeer && BACKEND->use_manual_cred_validation) { + return Curl_verify_certificate(conn, sockindex); + } +#endif + + return CURLE_OK; +} + +static bool +valid_cert_encoding(const CERT_CONTEXT *cert_context) +{ + return (cert_context != NULL) && + ((cert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) && + (cert_context->pbCertEncoded != NULL) && + (cert_context->cbCertEncoded > 0); +} + +typedef bool(*Read_crt_func)(const CERT_CONTEXT *ccert_context, void *arg); + +static void +traverse_cert_store(const CERT_CONTEXT *context, Read_crt_func func, + void *arg) +{ + const CERT_CONTEXT *current_context = NULL; + bool should_continue = true; + while(should_continue && + (current_context = CertEnumCertificatesInStore( + context->hCertStore, + current_context)) != NULL) + should_continue = func(current_context, arg); + + if(current_context) + CertFreeCertificateContext(current_context); +} + +static bool +cert_counter_callback(const CERT_CONTEXT *ccert_context, void *certs_count) +{ + if(valid_cert_encoding(ccert_context)) + (*(int *)certs_count)++; + return true; +} + +struct Adder_args +{ + struct connectdata *conn; + CURLcode result; + int idx; +}; + +static bool +add_cert_to_certinfo(const CERT_CONTEXT *ccert_context, void *raw_arg) +{ + struct Adder_args *args = (struct Adder_args*)raw_arg; + args->result = CURLE_OK; + if(valid_cert_encoding(ccert_context)) { + const char *beg = (const char *) ccert_context->pbCertEncoded; + const char *end = beg + ccert_context->cbCertEncoded; + args->result = Curl_extract_certinfo(args->conn, (args->idx)++, beg, end); + } + return args->result == CURLE_OK; +} + +static CURLcode +schannel_connect_step3(struct connectdata *conn, int sockindex) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + SECURITY_STATUS sspi_status = SEC_E_OK; + CERT_CONTEXT *ccert_context = NULL; +#ifdef DEBUGBUILD + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; +#endif +#ifdef HAS_ALPN + SecPkgContext_ApplicationProtocol alpn_result; +#endif + + DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); + + DEBUGF(infof(data, + "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n", + hostname, conn->remote_port)); + + if(!BACKEND->cred) + return CURLE_SSL_CONNECT_ERROR; + + /* check if the required context attributes are met */ + if(BACKEND->ret_flags != BACKEND->req_flags) { + if(!(BACKEND->ret_flags & ISC_RET_SEQUENCE_DETECT)) + failf(data, "schannel: failed to setup sequence detection"); + if(!(BACKEND->ret_flags & ISC_RET_REPLAY_DETECT)) + failf(data, "schannel: failed to setup replay detection"); + if(!(BACKEND->ret_flags & ISC_RET_CONFIDENTIALITY)) + failf(data, "schannel: failed to setup confidentiality"); + if(!(BACKEND->ret_flags & ISC_RET_ALLOCATED_MEMORY)) + failf(data, "schannel: failed to setup memory allocation"); + if(!(BACKEND->ret_flags & ISC_RET_STREAM)) + failf(data, "schannel: failed to setup stream orientation"); + return CURLE_SSL_CONNECT_ERROR; + } + +#ifdef HAS_ALPN + if(BACKEND->use_alpn) { + sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_APPLICATION_PROTOCOL, &alpn_result); + + if(sspi_status != SEC_E_OK) { + failf(data, "schannel: failed to retrieve ALPN result"); + return CURLE_SSL_CONNECT_ERROR; + } + + if(alpn_result.ProtoNegoStatus == + SecApplicationProtocolNegotiationStatus_Success) { + + infof(data, "schannel: ALPN, server accepted to use %.*s\n", + alpn_result.ProtocolIdSize, alpn_result.ProtocolId); + +#ifdef USE_NGHTTP2 + if(alpn_result.ProtocolIdSize == NGHTTP2_PROTO_VERSION_ID_LEN && + !memcmp(NGHTTP2_PROTO_VERSION_ID, alpn_result.ProtocolId, + NGHTTP2_PROTO_VERSION_ID_LEN)) { + conn->negnpn = CURL_HTTP_VERSION_2; + } + else +#endif + if(alpn_result.ProtocolIdSize == ALPN_HTTP_1_1_LENGTH && + !memcmp(ALPN_HTTP_1_1, alpn_result.ProtocolId, + ALPN_HTTP_1_1_LENGTH)) { + conn->negnpn = CURL_HTTP_VERSION_1_1; + } + } + else + infof(data, "ALPN, server did not agree to a protocol\n"); + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + } +#endif + + /* save the current session data for possible re-use */ + if(SSL_SET_OPTION(primary.sessionid)) { + bool incache; + struct curl_schannel_cred *old_cred = NULL; + + Curl_ssl_sessionid_lock(conn); + incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, + sockindex)); + if(incache) { + if(old_cred != BACKEND->cred) { + DEBUGF(infof(data, + "schannel: old credential handle is stale, removing\n")); + /* we're not taking old_cred ownership here, no refcount++ is needed */ + Curl_ssl_delsessionid(conn, (void *)old_cred); + incache = FALSE; + } + } + if(!incache) { + result = Curl_ssl_addsessionid(conn, (void *)BACKEND->cred, + sizeof(struct curl_schannel_cred), + sockindex); + if(result) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "schannel: failed to store credential handle"); + return result; + } + else { + /* this cred session is now also referenced by sessionid cache */ + BACKEND->cred->refcount++; + DEBUGF(infof(data, + "schannel: stored credential handle in session cache\n")); + } + } + Curl_ssl_sessionid_unlock(conn); + } + + if(data->set.ssl.certinfo) { + int certs_count = 0; + sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context); + + if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) { + failf(data, "schannel: failed to retrieve remote cert context"); + return CURLE_PEER_FAILED_VERIFICATION; + } + + traverse_cert_store(ccert_context, cert_counter_callback, &certs_count); + + result = Curl_ssl_init_certinfo(data, certs_count); + if(!result) { + struct Adder_args args; + args.conn = conn; + args.idx = 0; + traverse_cert_store(ccert_context, add_cert_to_certinfo, &args); + result = args.result; + } + CertFreeCertificateContext(ccert_context); + if(result) + return result; + } + + connssl->connecting_state = ssl_connect_done; + + return CURLE_OK; +} + +static CURLcode +schannel_connect_common(struct connectdata *conn, int sockindex, + bool nonblocking, bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + time_t timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + /* check out how much more time we're allowed */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL/TLS connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + result = schannel_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + /* check out how much more time we're allowed */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL/TLS connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading + || connssl->connecting_state == ssl_connect_2_writing) { + + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state ? sockfd : CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state ? sockfd : CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking ? 0 : timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL/TLS socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL/TLS connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if + * this connection is part of a multi handle and this loop would + * execute again. This permits the owner of a multi handle to + * abort a connection attempt before step2 has completed while + * ensuring that a client using select() or epoll() will always + * have a valid fdset to wait on. + */ + result = schannel_connect_step2(conn, sockindex); + if(result || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return result; + + } /* repeat step2 until all transactions are done. */ + + if(ssl_connect_3 == connssl->connecting_state) { + result = schannel_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = schannel_recv; + conn->send[sockindex] = schannel_send; + +#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS + /* When SSPI is used in combination with Schannel + * we need the Schannel context to create the Schannel + * binding to pass the IIS extended protection checks. + * Available on Windows 7 or later. + */ + conn->sslContext = &BACKEND->ctxt->ctxt_handle; +#endif + + *done = TRUE; + } + else + *done = FALSE; + + /* reset our connection state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +static ssize_t +schannel_send(struct connectdata *conn, int sockindex, + const void *buf, size_t len, CURLcode *err) +{ + ssize_t written = -1; + size_t data_len = 0; + unsigned char *data = NULL; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + SecBuffer outbuf[4]; + SecBufferDesc outbuf_desc; + SECURITY_STATUS sspi_status = SEC_E_OK; + CURLcode result; + + /* check if the maximum stream sizes were queried */ + if(BACKEND->stream_sizes.cbMaximumMessage == 0) { + sspi_status = s_pSecFn->QueryContextAttributes( + &BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_STREAM_SIZES, + &BACKEND->stream_sizes); + if(sspi_status != SEC_E_OK) { + *err = CURLE_SEND_ERROR; + return -1; + } + } + + /* check if the buffer is longer than the maximum message length */ + if(len > BACKEND->stream_sizes.cbMaximumMessage) { + len = BACKEND->stream_sizes.cbMaximumMessage; + } + + /* calculate the complete message length and allocate a buffer for it */ + data_len = BACKEND->stream_sizes.cbHeader + len + + BACKEND->stream_sizes.cbTrailer; + data = (unsigned char *) malloc(data_len); + if(data == NULL) { + *err = CURLE_OUT_OF_MEMORY; + return -1; + } + + /* setup output buffers (header, data, trailer, empty) */ + InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER, + data, BACKEND->stream_sizes.cbHeader); + InitSecBuffer(&outbuf[1], SECBUFFER_DATA, + data + BACKEND->stream_sizes.cbHeader, curlx_uztoul(len)); + InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER, + data + BACKEND->stream_sizes.cbHeader + len, + BACKEND->stream_sizes.cbTrailer); + InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0); + InitSecBufferDesc(&outbuf_desc, outbuf, 4); + + /* copy data into output buffer */ + memcpy(outbuf[1].pvBuffer, buf, len); + + /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */ + sspi_status = s_pSecFn->EncryptMessage(&BACKEND->ctxt->ctxt_handle, 0, + &outbuf_desc, 0); + + /* check if the message was encrypted */ + if(sspi_status == SEC_E_OK) { + written = 0; + + /* send the encrypted message including header, data and trailer */ + len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer; + + /* + It's important to send the full message which includes the header, + encrypted payload, and trailer. Until the client receives all the + data a coherent message has not been delivered and the client + can't read any of it. + + If we wanted to buffer the unwritten encrypted bytes, we would + tell the client that all data it has requested to be sent has been + sent. The unwritten encrypted bytes would be the first bytes to + send on the next invocation. + Here's the catch with this - if we tell the client that all the + bytes have been sent, will the client call this method again to + send the buffered data? Looking at who calls this function, it + seems the answer is NO. + */ + + /* send entire message or fail */ + while(len > (size_t)written) { + ssize_t this_write; + time_t timeleft; + int what; + + this_write = 0; + + timeleft = Curl_timeleft(conn->data, NULL, FALSE); + if(timeleft < 0) { + /* we already got the timeout */ + failf(conn->data, "schannel: timed out sending data " + "(bytes sent: %zd)", written); + *err = CURLE_OPERATION_TIMEDOUT; + written = -1; + break; + } + + what = SOCKET_WRITABLE(conn->sock[sockindex], timeleft); + if(what < 0) { + /* fatal error */ + failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + *err = CURLE_SEND_ERROR; + written = -1; + break; + } + else if(0 == what) { + failf(conn->data, "schannel: timed out sending data " + "(bytes sent: %zd)", written); + *err = CURLE_OPERATION_TIMEDOUT; + written = -1; + break; + } + /* socket is writable */ + + result = Curl_write_plain(conn, conn->sock[sockindex], data + written, + len - written, &this_write); + if(result == CURLE_AGAIN) + continue; + else if(result != CURLE_OK) { + *err = result; + written = -1; + break; + } + + written += this_write; + } + } + else if(sspi_status == SEC_E_INSUFFICIENT_MEMORY) { + *err = CURLE_OUT_OF_MEMORY; + } + else{ + *err = CURLE_SEND_ERROR; + } + + Curl_safefree(data); + + if(len == (size_t)written) + /* Encrypted message including header, data and trailer entirely sent. + The return value is the number of unencrypted bytes that were sent. */ + written = outbuf[1].cbBuffer; + + return written; +} + +static ssize_t +schannel_recv(struct connectdata *conn, int sockindex, + char *buf, size_t len, CURLcode *err) +{ + size_t size = 0; + ssize_t nread = -1; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + unsigned char *reallocated_buffer; + size_t reallocated_length; + bool done = FALSE; + SecBuffer inbuf[4]; + SecBufferDesc inbuf_desc; + SECURITY_STATUS sspi_status = SEC_E_OK; + /* we want the length of the encrypted buffer to be at least large enough + that it can hold all the bytes requested and some TLS record overhead. */ + size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE; + + /**************************************************************************** + * Don't return or set BACKEND->recv_unrecoverable_err unless in the cleanup. + * The pattern for return error is set *err, optional infof, goto cleanup. + * + * Our priority is to always return as much decrypted data to the caller as + * possible, even if an error occurs. The state of the decrypted buffer must + * always be valid. Transfer of decrypted data to the caller's buffer is + * handled in the cleanup. + */ + + DEBUGF(infof(data, "schannel: client wants to read %zu bytes\n", len)); + *err = CURLE_OK; + + if(len && len <= BACKEND->decdata_offset) { + infof(data, "schannel: enough decrypted data is already available\n"); + goto cleanup; + } + else if(BACKEND->recv_unrecoverable_err) { + *err = BACKEND->recv_unrecoverable_err; + infof(data, "schannel: an unrecoverable error occurred in a prior call\n"); + goto cleanup; + } + else if(BACKEND->recv_sspi_close_notify) { + /* once a server has indicated shutdown there is no more encrypted data */ + infof(data, "schannel: server indicated shutdown in a prior call\n"); + goto cleanup; + } + else if(!len) { + /* It's debatable what to return when !len. Regardless we can't return + immediately because there may be data to decrypt (in the case we want to + decrypt all encrypted cached data) so handle !len later in cleanup. + */ + ; /* do nothing */ + } + else if(!BACKEND->recv_connection_closed) { + /* increase enc buffer in order to fit the requested amount of data */ + size = BACKEND->encdata_length - BACKEND->encdata_offset; + if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE || + BACKEND->encdata_length < min_encdata_length) { + reallocated_length = BACKEND->encdata_offset + + CURL_SCHANNEL_BUFFER_FREE_SIZE; + if(reallocated_length < min_encdata_length) { + reallocated_length = min_encdata_length; + } + reallocated_buffer = realloc(BACKEND->encdata_buffer, + reallocated_length); + if(reallocated_buffer == NULL) { + *err = CURLE_OUT_OF_MEMORY; + failf(data, "schannel: unable to re-allocate memory"); + goto cleanup; + } + + BACKEND->encdata_buffer = reallocated_buffer; + BACKEND->encdata_length = reallocated_length; + size = BACKEND->encdata_length - BACKEND->encdata_offset; + DEBUGF(infof(data, "schannel: encdata_buffer resized %zu\n", + BACKEND->encdata_length)); + } + + DEBUGF(infof(data, + "schannel: encrypted data buffer: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); + + /* read encrypted data from socket */ + *err = Curl_read_plain(conn->sock[sockindex], + (char *)(BACKEND->encdata_buffer + + BACKEND->encdata_offset), + size, &nread); + if(*err) { + nread = -1; + if(*err == CURLE_AGAIN) + DEBUGF(infof(data, + "schannel: Curl_read_plain returned CURLE_AGAIN\n")); + else if(*err == CURLE_RECV_ERROR) + infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR\n"); + else + infof(data, "schannel: Curl_read_plain returned error %d\n", *err); + } + else if(nread == 0) { + BACKEND->recv_connection_closed = true; + DEBUGF(infof(data, "schannel: server closed the connection\n")); + } + else if(nread > 0) { + BACKEND->encdata_offset += (size_t)nread; + BACKEND->encdata_is_incomplete = false; + DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread)); + } + } + + DEBUGF(infof(data, + "schannel: encrypted data buffer: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); + + /* decrypt loop */ + while(BACKEND->encdata_offset > 0 && sspi_status == SEC_E_OK && + (!len || BACKEND->decdata_offset < len || + BACKEND->recv_connection_closed)) { + /* prepare data buffer for DecryptMessage call */ + InitSecBuffer(&inbuf[0], SECBUFFER_DATA, BACKEND->encdata_buffer, + curlx_uztoul(BACKEND->encdata_offset)); + + /* we need 3 more empty input buffers for possible output */ + InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0); + InitSecBuffer(&inbuf[2], SECBUFFER_EMPTY, NULL, 0); + InitSecBuffer(&inbuf[3], SECBUFFER_EMPTY, NULL, 0); + InitSecBufferDesc(&inbuf_desc, inbuf, 4); + + /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx + */ + sspi_status = s_pSecFn->DecryptMessage(&BACKEND->ctxt->ctxt_handle, + &inbuf_desc, 0, NULL); + + /* check if everything went fine (server may want to renegotiate + or shutdown the connection context) */ + if(sspi_status == SEC_E_OK || sspi_status == SEC_I_RENEGOTIATE || + sspi_status == SEC_I_CONTEXT_EXPIRED) { + /* check for successfully decrypted data, even before actual + renegotiation or shutdown of the connection context */ + if(inbuf[1].BufferType == SECBUFFER_DATA) { + DEBUGF(infof(data, "schannel: decrypted data length: %lu\n", + inbuf[1].cbBuffer)); + + /* increase buffer in order to fit the received amount of data */ + size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ? + inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE; + if(BACKEND->decdata_length - BACKEND->decdata_offset < size || + BACKEND->decdata_length < len) { + /* increase internal decrypted data buffer */ + reallocated_length = BACKEND->decdata_offset + size; + /* make sure that the requested amount of data fits */ + if(reallocated_length < len) { + reallocated_length = len; + } + reallocated_buffer = realloc(BACKEND->decdata_buffer, + reallocated_length); + if(reallocated_buffer == NULL) { + *err = CURLE_OUT_OF_MEMORY; + failf(data, "schannel: unable to re-allocate memory"); + goto cleanup; + } + BACKEND->decdata_buffer = reallocated_buffer; + BACKEND->decdata_length = reallocated_length; + } + + /* copy decrypted data to internal buffer */ + size = inbuf[1].cbBuffer; + if(size) { + memcpy(BACKEND->decdata_buffer + BACKEND->decdata_offset, + inbuf[1].pvBuffer, size); + BACKEND->decdata_offset += size; + } + + DEBUGF(infof(data, "schannel: decrypted data added: %zu\n", size)); + DEBUGF(infof(data, + "schannel: decrypted cached: offset %zu length %zu\n", + BACKEND->decdata_offset, BACKEND->decdata_length)); + } + + /* check for remaining encrypted data */ + if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) { + DEBUGF(infof(data, "schannel: encrypted data length: %lu\n", + inbuf[3].cbBuffer)); + + /* check if the remaining data is less than the total amount + * and therefore begins after the already processed data + */ + if(BACKEND->encdata_offset > inbuf[3].cbBuffer) { + /* move remaining encrypted data forward to the beginning of + buffer */ + memmove(BACKEND->encdata_buffer, + (BACKEND->encdata_buffer + BACKEND->encdata_offset) - + inbuf[3].cbBuffer, inbuf[3].cbBuffer); + BACKEND->encdata_offset = inbuf[3].cbBuffer; + } + + DEBUGF(infof(data, + "schannel: encrypted cached: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); + } + else { + /* reset encrypted buffer offset, because there is no data remaining */ + BACKEND->encdata_offset = 0; + } + + /* check if server wants to renegotiate the connection context */ + if(sspi_status == SEC_I_RENEGOTIATE) { + infof(data, "schannel: remote party requests renegotiation\n"); + if(*err && *err != CURLE_AGAIN) { + infof(data, "schannel: can't renogotiate, an error is pending\n"); + goto cleanup; + } + if(BACKEND->encdata_offset) { + *err = CURLE_RECV_ERROR; + infof(data, "schannel: can't renogotiate, " + "encrypted data available\n"); + goto cleanup; + } + /* begin renegotiation */ + infof(data, "schannel: renegotiating SSL/TLS connection\n"); + connssl->state = ssl_connection_negotiating; + connssl->connecting_state = ssl_connect_2_writing; + *err = schannel_connect_common(conn, sockindex, FALSE, &done); + if(*err) { + infof(data, "schannel: renegotiation failed\n"); + goto cleanup; + } + /* now retry receiving data */ + sspi_status = SEC_E_OK; + infof(data, "schannel: SSL/TLS connection renegotiated\n"); + continue; + } + /* check if the server closed the connection */ + else if(sspi_status == SEC_I_CONTEXT_EXPIRED) { + /* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not + returned so we have to work around that in cleanup. */ + BACKEND->recv_sspi_close_notify = true; + if(!BACKEND->recv_connection_closed) { + BACKEND->recv_connection_closed = true; + infof(data, "schannel: server closed the connection\n"); + } + goto cleanup; + } + } + else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) { + BACKEND->encdata_is_incomplete = true; + if(!*err) + *err = CURLE_AGAIN; + infof(data, "schannel: failed to decrypt data, need more data\n"); + goto cleanup; + } + else { + char buffer[STRERROR_LEN]; + *err = CURLE_RECV_ERROR; + infof(data, "schannel: failed to read data from server: %s\n", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + goto cleanup; + } + } + + DEBUGF(infof(data, + "schannel: encrypted data buffer: offset %zu length %zu\n", + BACKEND->encdata_offset, BACKEND->encdata_length)); + + DEBUGF(infof(data, + "schannel: decrypted data buffer: offset %zu length %zu\n", + BACKEND->decdata_offset, BACKEND->decdata_length)); + +cleanup: + /* Warning- there is no guarantee the encdata state is valid at this point */ + DEBUGF(infof(data, "schannel: schannel_recv cleanup\n")); + + /* Error if the connection has closed without a close_notify. + Behavior here is a matter of debate. We don't want to be vulnerable to a + truncation attack however there's some browser precedent for ignoring the + close_notify for compatibility reasons. + Additionally, Windows 2000 (v5.0) is a special case since it seems it doesn't + return close_notify. In that case if the connection was closed we assume it + was graceful (close_notify) since there doesn't seem to be a way to tell. + */ + if(len && !BACKEND->decdata_offset && BACKEND->recv_connection_closed && + !BACKEND->recv_sspi_close_notify) { + bool isWin2k = Curl_verify_windows_version(5, 0, PLATFORM_WINNT, + VERSION_EQUAL); + + if(isWin2k && sspi_status == SEC_E_OK) + BACKEND->recv_sspi_close_notify = true; + else { + *err = CURLE_RECV_ERROR; + infof(data, "schannel: server closed abruptly (missing close_notify)\n"); + } + } + + /* Any error other than CURLE_AGAIN is an unrecoverable error. */ + if(*err && *err != CURLE_AGAIN) + BACKEND->recv_unrecoverable_err = *err; + + size = len < BACKEND->decdata_offset ? len : BACKEND->decdata_offset; + if(size) { + memcpy(buf, BACKEND->decdata_buffer, size); + memmove(BACKEND->decdata_buffer, BACKEND->decdata_buffer + size, + BACKEND->decdata_offset - size); + BACKEND->decdata_offset -= size; + DEBUGF(infof(data, "schannel: decrypted data returned %zu\n", size)); + DEBUGF(infof(data, + "schannel: decrypted data buffer: offset %zu length %zu\n", + BACKEND->decdata_offset, BACKEND->decdata_length)); + *err = CURLE_OK; + return (ssize_t)size; + } + + if(!*err && !BACKEND->recv_connection_closed) + *err = CURLE_AGAIN; + + /* It's debatable what to return when !len. We could return whatever error we + got from decryption but instead we override here so the return is consistent. + */ + if(!len) + *err = CURLE_OK; + + return *err ? -1 : 0; +} + +static CURLcode Curl_schannel_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + return schannel_connect_common(conn, sockindex, TRUE, done); +} + +static CURLcode Curl_schannel_connect(struct connectdata *conn, int sockindex) +{ + CURLcode result; + bool done = FALSE; + + result = schannel_connect_common(conn, sockindex, FALSE, &done); + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +static bool Curl_schannel_data_pending(const struct connectdata *conn, + int sockindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + if(connssl->use) /* SSL/TLS is in use */ + return (BACKEND->decdata_offset > 0 || + (BACKEND->encdata_offset > 0 && !BACKEND->encdata_is_incomplete)); + else + return FALSE; +} + +static void Curl_schannel_close(struct connectdata *conn, int sockindex) +{ + if(conn->ssl[sockindex].use) + /* if the SSL/TLS channel hasn't been shut down yet, do that now. */ + Curl_ssl_shutdown(conn, sockindex); +} + +static void Curl_schannel_session_free(void *ptr) +{ + /* this is expected to be called under sessionid lock */ + struct curl_schannel_cred *cred = ptr; + + cred->refcount--; + if(cred->refcount == 0) { + s_pSecFn->FreeCredentialsHandle(&cred->cred_handle); + Curl_safefree(cred); + } +} + +static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) +{ + /* See https://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx + * Shutting Down an Schannel Connection + */ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + + DEBUGASSERT(data); + + infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n", + hostname, conn->remote_port); + + if(BACKEND->cred && BACKEND->ctxt) { + SecBufferDesc BuffDesc; + SecBuffer Buffer; + SECURITY_STATUS sspi_status; + SecBuffer outbuf; + SecBufferDesc outbuf_desc; + CURLcode result; + TCHAR *host_name; + DWORD dwshut = SCHANNEL_SHUTDOWN; + + InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut)); + InitSecBufferDesc(&BuffDesc, &Buffer, 1); + + sspi_status = s_pSecFn->ApplyControlToken(&BACKEND->ctxt->ctxt_handle, + &BuffDesc); + + if(sspi_status != SEC_E_OK) { + char buffer[STRERROR_LEN]; + failf(data, "schannel: ApplyControlToken failure: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + } + + host_name = Curl_convert_UTF8_to_tchar(hostname); + if(!host_name) + return CURLE_OUT_OF_MEMORY; + + /* setup output buffer */ + InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0); + InitSecBufferDesc(&outbuf_desc, &outbuf, 1); + + sspi_status = s_pSecFn->InitializeSecurityContext( + &BACKEND->cred->cred_handle, + &BACKEND->ctxt->ctxt_handle, + host_name, + BACKEND->req_flags, + 0, + 0, + NULL, + 0, + &BACKEND->ctxt->ctxt_handle, + &outbuf_desc, + &BACKEND->ret_flags, + &BACKEND->ctxt->time_stamp); + + Curl_unicodefree(host_name); + + if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) { + /* send close message which is in output buffer */ + ssize_t written; + result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer, + outbuf.cbBuffer, &written); + + s_pSecFn->FreeContextBuffer(outbuf.pvBuffer); + if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) { + infof(data, "schannel: failed to send close msg: %s" + " (bytes written: %zd)\n", curl_easy_strerror(result), written); + } + } + } + + /* free SSPI Schannel API security context handle */ + if(BACKEND->ctxt) { + DEBUGF(infof(data, "schannel: clear security context handle\n")); + s_pSecFn->DeleteSecurityContext(&BACKEND->ctxt->ctxt_handle); + Curl_safefree(BACKEND->ctxt); + } + + /* free SSPI Schannel API credential handle */ + if(BACKEND->cred) { + /* + * When this function is called from Curl_schannel_close() the connection + * might not have an associated transfer so the check for conn->data is + * necessary. + */ + Curl_ssl_sessionid_lock(conn); + Curl_schannel_session_free(BACKEND->cred); + Curl_ssl_sessionid_unlock(conn); + BACKEND->cred = NULL; + } + + /* free internal buffer for received encrypted data */ + if(BACKEND->encdata_buffer != NULL) { + Curl_safefree(BACKEND->encdata_buffer); + BACKEND->encdata_length = 0; + BACKEND->encdata_offset = 0; + BACKEND->encdata_is_incomplete = false; + } + + /* free internal buffer for received decrypted data */ + if(BACKEND->decdata_buffer != NULL) { + Curl_safefree(BACKEND->decdata_buffer); + BACKEND->decdata_length = 0; + BACKEND->decdata_offset = 0; + } + + return CURLE_OK; +} + +static int Curl_schannel_init(void) +{ + return (Curl_sspi_global_init() == CURLE_OK ? 1 : 0); +} + +static void Curl_schannel_cleanup(void) +{ + Curl_sspi_global_cleanup(); +} + +static size_t Curl_schannel_version(char *buffer, size_t size) +{ + size = msnprintf(buffer, size, "Schannel"); + + return size; +} + +static CURLcode Curl_schannel_random(struct Curl_easy *data UNUSED_PARAM, + unsigned char *entropy, size_t length) +{ + HCRYPTPROV hCryptProv = 0; + + (void)data; + + if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + return CURLE_FAILED_INIT; + + if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) { + CryptReleaseContext(hCryptProv, 0UL); + return CURLE_FAILED_INIT; + } + + CryptReleaseContext(hCryptProv, 0UL); + return CURLE_OK; +} + +static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, + const char *pinnedpubkey) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + CERT_CONTEXT *pCertContextServer = NULL; + + /* Result is returned to caller */ + CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + + /* if a path wasn't specified, don't pin */ + if(!pinnedpubkey) + return CURLE_OK; + + do { + SECURITY_STATUS sspi_status; + const char *x509_der; + DWORD x509_der_len; + curl_X509certificate x509_parsed; + curl_asn1Element *pubkey; + + sspi_status = + s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, + &pCertContextServer); + + if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { + char buffer[STRERROR_LEN]; + failf(data, "schannel: Failed to read remote certificate context: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + break; /* failed */ + } + + + if(!(((pCertContextServer->dwCertEncodingType & X509_ASN_ENCODING) != 0) && + (pCertContextServer->cbCertEncoded > 0))) + break; + + x509_der = (const char *)pCertContextServer->pbCertEncoded; + x509_der_len = pCertContextServer->cbCertEncoded; + memset(&x509_parsed, 0, sizeof(x509_parsed)); + if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len)) + break; + + pubkey = &x509_parsed.subjectPublicKeyInfo; + if(!pubkey->header || pubkey->end <= pubkey->header) { + failf(data, "SSL: failed retrieving public key from server certificate"); + break; + } + + result = Curl_pin_peer_pubkey(data, + pinnedpubkey, + (const unsigned char *)pubkey->header, + (size_t)(pubkey->end - pubkey->header)); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + } + } while(0); + + if(pCertContextServer) + CertFreeCertificateContext(pCertContextServer); + + return result; +} + +static void Curl_schannel_checksum(const unsigned char *input, + size_t inputlen, + unsigned char *checksum, + size_t checksumlen, + DWORD provType, + const unsigned int algId) +{ + HCRYPTPROV hProv = 0; + HCRYPTHASH hHash = 0; + DWORD cbHashSize = 0; + DWORD dwHashSizeLen = (DWORD)sizeof(cbHashSize); + DWORD dwChecksumLen = (DWORD)checksumlen; + + /* since this can fail in multiple ways, zero memory first so we never + * return old data + */ + memset(checksum, 0, checksumlen); + + if(!CryptAcquireContext(&hProv, NULL, NULL, provType, + CRYPT_VERIFYCONTEXT)) + return; /* failed */ + + do { + if(!CryptCreateHash(hProv, algId, 0, 0, &hHash)) + break; /* failed */ + + /* workaround for original MinGW, should be (const BYTE*) */ + if(!CryptHashData(hHash, (BYTE*)input, (DWORD)inputlen, 0)) + break; /* failed */ + + /* get hash size */ + if(!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&cbHashSize, + &dwHashSizeLen, 0)) + break; /* failed */ + + /* check hash size */ + if(checksumlen < cbHashSize) + break; /* failed */ + + if(CryptGetHashParam(hHash, HP_HASHVAL, checksum, &dwChecksumLen, 0)) + break; /* failed */ + } while(0); + + if(hHash) + CryptDestroyHash(hHash); + + if(hProv) + CryptReleaseContext(hProv, 0); +} + +static CURLcode Curl_schannel_md5sum(unsigned char *input, + size_t inputlen, + unsigned char *md5sum, + size_t md5len) +{ + Curl_schannel_checksum(input, inputlen, md5sum, md5len, + PROV_RSA_FULL, CALG_MD5); + return CURLE_OK; +} + +static CURLcode Curl_schannel_sha256sum(const unsigned char *input, + size_t inputlen, + unsigned char *sha256sum, + size_t sha256len) +{ + Curl_schannel_checksum(input, inputlen, sha256sum, sha256len, + PROV_RSA_AES, CALG_SHA_256); + return CURLE_OK; +} + +static void *Curl_schannel_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + (void)info; + return &BACKEND->ctxt->ctxt_handle; +} + +const struct Curl_ssl Curl_ssl_schannel = { + { CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */ + + SSLSUPP_CERTINFO | + SSLSUPP_PINNEDPUBKEY, + + sizeof(struct ssl_backend_data), + + Curl_schannel_init, /* init */ + Curl_schannel_cleanup, /* cleanup */ + Curl_schannel_version, /* version */ + Curl_none_check_cxn, /* check_cxn */ + Curl_schannel_shutdown, /* shutdown */ + Curl_schannel_data_pending, /* data_pending */ + Curl_schannel_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_schannel_connect, /* connect */ + Curl_schannel_connect_nonblocking, /* connect_nonblocking */ + Curl_schannel_get_internals, /* get_internals */ + Curl_schannel_close, /* close_one */ + Curl_none_close_all, /* close_all */ + Curl_schannel_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_schannel_md5sum, /* md5sum */ + Curl_schannel_sha256sum /* sha256sum */ +}; + +#endif /* USE_SCHANNEL */ diff --git a/libcurl/lib/vtls/schannel.h b/libcurl/lib/vtls/schannel.h new file mode 100644 index 0000000..ee8d7d4 --- /dev/null +++ b/libcurl/lib/vtls/schannel.h @@ -0,0 +1,108 @@ +#ifndef HEADER_CURL_SCHANNEL_H +#define HEADER_CURL_SCHANNEL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012, Marc Hoersken, , et al. + * Copyright (C) 2012 - 2018, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_SCHANNEL + +#include +#include +#include "curl_sspi.h" + +#include "urldata.h" + +/* has been included via the above . + * Or in case of ldap.c, it was included via . + * And since has this: + * #define X509_NAME ((LPCSTR) 7) + * + * And in BoringSSL's there is: + * typedef struct X509_name_st X509_NAME; + * etc. + * + * this will cause all kinds of C-preprocessing paste errors in + * BoringSSL's : So just undefine those defines here + * (and only here). + */ +#if defined(HAVE_BORINGSSL) || defined(OPENSSL_IS_BORINGSSL) +# undef X509_NAME +# undef X509_CERT_PAIR +# undef X509_EXTENSIONS +#endif + +extern const struct Curl_ssl Curl_ssl_schannel; + +CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex); + +/* structs to expose only in schannel.c and schannel_verify.c */ +#ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS + +#ifdef __MINGW32__ +#include <_mingw.h> +#ifdef __MINGW64_VERSION_MAJOR +#define HAS_MANUAL_VERIFY_API +#endif +#else +#include +#ifdef CERT_CHAIN_REVOCATION_CHECK_CHAIN +#define HAS_MANUAL_VERIFY_API +#endif +#endif + +struct curl_schannel_cred { + CredHandle cred_handle; + TimeStamp time_stamp; + int refcount; +}; + +struct curl_schannel_ctxt { + CtxtHandle ctxt_handle; + TimeStamp time_stamp; +}; + +struct ssl_backend_data { + struct curl_schannel_cred *cred; + struct curl_schannel_ctxt *ctxt; + SecPkgContext_StreamSizes stream_sizes; + size_t encdata_length, decdata_length; + size_t encdata_offset, decdata_offset; + unsigned char *encdata_buffer, *decdata_buffer; + /* encdata_is_incomplete: if encdata contains only a partial record that + can't be decrypted without another Curl_read_plain (that is, status is + SEC_E_INCOMPLETE_MESSAGE) then set this true. after Curl_read_plain writes + more bytes into encdata then set this back to false. */ + bool encdata_is_incomplete; + unsigned long req_flags, ret_flags; + CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */ + bool recv_sspi_close_notify; /* true if connection closed by close_notify */ + bool recv_connection_closed; /* true if connection closed, regardless how */ + bool use_alpn; /* true if ALPN is used for this connection */ +#ifdef HAS_MANUAL_VERIFY_API + bool use_manual_cred_validation; /* true if manual cred validation is used */ +#endif +}; +#endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */ + +#endif /* USE_SCHANNEL */ +#endif /* HEADER_CURL_SCHANNEL_H */ diff --git a/libcurl/lib/vtls/schannel_verify.c b/libcurl/lib/vtls/schannel_verify.c new file mode 100644 index 0000000..5a09e96 --- /dev/null +++ b/libcurl/lib/vtls/schannel_verify.c @@ -0,0 +1,572 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2016, Marc Hoersken, + * Copyright (C) 2012, Mark Salisbury, + * Copyright (C) 2012 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for Schannel-specific certificate verification. This code should + * only be invoked by code in schannel.c. + */ + +#include "curl_setup.h" + +#ifdef USE_SCHANNEL +#ifndef USE_WINDOWS_SSPI +# error "Can't compile SCHANNEL support without SSPI." +#endif + +#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS +#include "schannel.h" + +#ifdef HAS_MANUAL_VERIFY_API + +#include "vtls.h" +#include "sendf.h" +#include "strerror.h" +#include "curl_multibyte.h" +#include "curl_printf.h" +#include "hostcheck.h" +#include "system_win32.h" + +/* The last #include file should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +#define BACKEND connssl->backend + +#define MAX_CAFILE_SIZE 1048576 /* 1 MiB */ +#define BEGIN_CERT "-----BEGIN CERTIFICATE-----" +#define END_CERT "\n-----END CERTIFICATE-----" + +typedef struct { + DWORD cbSize; + HCERTSTORE hRestrictedRoot; + HCERTSTORE hRestrictedTrust; + HCERTSTORE hRestrictedOther; + DWORD cAdditionalStore; + HCERTSTORE *rghAdditionalStore; + DWORD dwFlags; + DWORD dwUrlRetrievalTimeout; + DWORD MaximumCachedCertificates; + DWORD CycleDetectionModulus; + HCERTSTORE hExclusiveRoot; + HCERTSTORE hExclusiveTrustedPeople; +} CERT_CHAIN_ENGINE_CONFIG_WIN7, *PCERT_CHAIN_ENGINE_CONFIG_WIN7; + +static int is_cr_or_lf(char c) +{ + return c == '\r' || c == '\n'; +} + +static CURLcode add_certs_to_store(HCERTSTORE trust_store, + const char *ca_file, + struct connectdata *conn) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + HANDLE ca_file_handle = INVALID_HANDLE_VALUE; + LARGE_INTEGER file_size; + char *ca_file_buffer = NULL; + char *current_ca_file_ptr = NULL; + TCHAR *ca_file_tstr = NULL; + size_t ca_file_bufsize = 0; + DWORD total_bytes_read = 0; + bool more_certs = 0; + int num_certs = 0; + size_t END_CERT_LEN; + + ca_file_tstr = Curl_convert_UTF8_to_tchar((char *)ca_file); + if(!ca_file_tstr) { + char buffer[STRERROR_LEN]; + failf(data, + "schannel: invalid path name for CA file '%s': %s", + ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + result = CURLE_SSL_CACERT_BADFILE; + goto cleanup; + } + + /* + * Read the CA file completely into memory before parsing it. This + * optimizes for the common case where the CA file will be relatively + * small ( < 1 MiB ). + */ + ca_file_handle = CreateFile(ca_file_tstr, + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if(ca_file_handle == INVALID_HANDLE_VALUE) { + char buffer[STRERROR_LEN]; + failf(data, + "schannel: failed to open CA file '%s': %s", + ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + result = CURLE_SSL_CACERT_BADFILE; + goto cleanup; + } + + if(!GetFileSizeEx(ca_file_handle, &file_size)) { + char buffer[STRERROR_LEN]; + failf(data, + "schannel: failed to determine size of CA file '%s': %s", + ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + result = CURLE_SSL_CACERT_BADFILE; + goto cleanup; + } + + if(file_size.QuadPart > MAX_CAFILE_SIZE) { + failf(data, + "schannel: CA file exceeds max size of %u bytes", + MAX_CAFILE_SIZE); + result = CURLE_SSL_CACERT_BADFILE; + goto cleanup; + } + + ca_file_bufsize = (size_t)file_size.QuadPart; + ca_file_buffer = (char *)malloc(ca_file_bufsize + 1); + if(!ca_file_buffer) { + result = CURLE_OUT_OF_MEMORY; + goto cleanup; + } + + result = CURLE_OK; + while(total_bytes_read < ca_file_bufsize) { + DWORD bytes_to_read = (DWORD)(ca_file_bufsize - total_bytes_read); + DWORD bytes_read = 0; + + if(!ReadFile(ca_file_handle, ca_file_buffer + total_bytes_read, + bytes_to_read, &bytes_read, NULL)) { + char buffer[STRERROR_LEN]; + failf(data, + "schannel: failed to read from CA file '%s': %s", + ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + result = CURLE_SSL_CACERT_BADFILE; + goto cleanup; + } + if(bytes_read == 0) { + /* Premature EOF -- adjust the bufsize to the new value */ + ca_file_bufsize = total_bytes_read; + } + else { + total_bytes_read += bytes_read; + } + } + + /* Null terminate the buffer */ + ca_file_buffer[ca_file_bufsize] = '\0'; + + if(result != CURLE_OK) { + goto cleanup; + } + + END_CERT_LEN = strlen(END_CERT); + + more_certs = 1; + current_ca_file_ptr = ca_file_buffer; + while(more_certs && *current_ca_file_ptr != '\0') { + char *begin_cert_ptr = strstr(current_ca_file_ptr, BEGIN_CERT); + if(!begin_cert_ptr || !is_cr_or_lf(begin_cert_ptr[strlen(BEGIN_CERT)])) { + more_certs = 0; + } + else { + char *end_cert_ptr = strstr(begin_cert_ptr, END_CERT); + if(!end_cert_ptr) { + failf(data, + "schannel: CA file '%s' is not correctly formatted", + ca_file); + result = CURLE_SSL_CACERT_BADFILE; + more_certs = 0; + } + else { + CERT_BLOB cert_blob; + CERT_CONTEXT *cert_context = NULL; + BOOL add_cert_result = FALSE; + DWORD actual_content_type = 0; + DWORD cert_size = (DWORD) + ((end_cert_ptr + END_CERT_LEN) - begin_cert_ptr); + + cert_blob.pbData = (BYTE *)begin_cert_ptr; + cert_blob.cbData = cert_size; + if(!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, + &cert_blob, + CERT_QUERY_CONTENT_FLAG_CERT, + CERT_QUERY_FORMAT_FLAG_ALL, + 0, + NULL, + &actual_content_type, + NULL, + NULL, + NULL, + (const void **)&cert_context)) { + char buffer[STRERROR_LEN]; + failf(data, + "schannel: failed to extract certificate from CA file " + "'%s': %s", + ca_file, + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + result = CURLE_SSL_CACERT_BADFILE; + more_certs = 0; + } + else { + current_ca_file_ptr = begin_cert_ptr + cert_size; + + /* Sanity check that the cert_context object is the right type */ + if(CERT_QUERY_CONTENT_CERT != actual_content_type) { + failf(data, + "schannel: unexpected content type '%d' when extracting " + "certificate from CA file '%s'", + actual_content_type, ca_file); + result = CURLE_SSL_CACERT_BADFILE; + more_certs = 0; + } + else { + add_cert_result = + CertAddCertificateContextToStore(trust_store, + cert_context, + CERT_STORE_ADD_ALWAYS, + NULL); + CertFreeCertificateContext(cert_context); + if(!add_cert_result) { + char buffer[STRERROR_LEN]; + failf(data, + "schannel: failed to add certificate from CA file '%s' " + "to certificate store: %s", + ca_file, + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + result = CURLE_SSL_CACERT_BADFILE; + more_certs = 0; + } + else { + num_certs++; + } + } + } + } + } + } + + if(result == CURLE_OK) { + if(!num_certs) { + infof(data, + "schannel: did not add any certificates from CA file '%s'\n", + ca_file); + } + else { + infof(data, + "schannel: added %d certificate(s) from CA file '%s'\n", + num_certs, ca_file); + } + } + +cleanup: + if(ca_file_handle != INVALID_HANDLE_VALUE) { + CloseHandle(ca_file_handle); + } + Curl_safefree(ca_file_buffer); + Curl_unicodefree(ca_file_tstr); + + return result; +} + +static CURLcode verify_host(struct Curl_easy *data, + CERT_CONTEXT *pCertContextServer, + const char * const conn_hostname) +{ + CURLcode result = CURLE_PEER_FAILED_VERIFICATION; + TCHAR *cert_hostname_buff = NULL; + size_t cert_hostname_buff_index = 0; + DWORD len = 0; + DWORD actual_len = 0; + + /* CertGetNameString will provide the 8-bit character string without + * any decoding */ + DWORD name_flags = CERT_NAME_DISABLE_IE4_UTF8_FLAG; + +#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG + name_flags |= CERT_NAME_SEARCH_ALL_NAMES_FLAG; +#endif + + /* Determine the size of the string needed for the cert hostname */ + len = CertGetNameString(pCertContextServer, + CERT_NAME_DNS_TYPE, + name_flags, + NULL, + NULL, + 0); + if(len == 0) { + failf(data, + "schannel: CertGetNameString() returned no " + "certificate name information"); + result = CURLE_PEER_FAILED_VERIFICATION; + goto cleanup; + } + + /* CertGetNameString guarantees that the returned name will not contain + * embedded null bytes. This appears to be undocumented behavior. + */ + cert_hostname_buff = (LPTSTR)malloc(len * sizeof(TCHAR)); + if(!cert_hostname_buff) { + result = CURLE_OUT_OF_MEMORY; + goto cleanup; + } + actual_len = CertGetNameString(pCertContextServer, + CERT_NAME_DNS_TYPE, + name_flags, + NULL, + (LPTSTR) cert_hostname_buff, + len); + + /* Sanity check */ + if(actual_len != len) { + failf(data, + "schannel: CertGetNameString() returned certificate " + "name information of unexpected size"); + result = CURLE_PEER_FAILED_VERIFICATION; + goto cleanup; + } + + /* If HAVE_CERT_NAME_SEARCH_ALL_NAMES is available, the output + * will contain all DNS names, where each name is null-terminated + * and the last DNS name is double null-terminated. Due to this + * encoding, use the length of the buffer to iterate over all names. + */ + result = CURLE_PEER_FAILED_VERIFICATION; + while(cert_hostname_buff_index < len && + cert_hostname_buff[cert_hostname_buff_index] != TEXT('\0') && + result == CURLE_PEER_FAILED_VERIFICATION) { + + char *cert_hostname; + + /* Comparing the cert name and the connection hostname encoded as UTF-8 + * is acceptable since both values are assumed to use ASCII + * (or some equivalent) encoding + */ + cert_hostname = Curl_convert_tchar_to_UTF8( + &cert_hostname_buff[cert_hostname_buff_index]); + if(!cert_hostname) { + result = CURLE_OUT_OF_MEMORY; + } + else { + int match_result; + + match_result = Curl_cert_hostcheck(cert_hostname, conn_hostname); + if(match_result == CURL_HOST_MATCH) { + infof(data, + "schannel: connection hostname (%s) validated " + "against certificate name (%s)\n", + conn_hostname, cert_hostname); + result = CURLE_OK; + } + else { + size_t cert_hostname_len; + + infof(data, + "schannel: connection hostname (%s) did not match " + "against certificate name (%s)\n", + conn_hostname, cert_hostname); + + cert_hostname_len = _tcslen( + &cert_hostname_buff[cert_hostname_buff_index]); + + /* Move on to next cert name */ + cert_hostname_buff_index += cert_hostname_len + 1; + + result = CURLE_PEER_FAILED_VERIFICATION; + } + Curl_unicodefree(cert_hostname); + } + } + + if(result == CURLE_PEER_FAILED_VERIFICATION) { + failf(data, + "schannel: CertGetNameString() failed to match " + "connection hostname (%s) against server certificate names", + conn_hostname); + } + else if(result != CURLE_OK) + failf(data, "schannel: server certificate name verification failed"); + +cleanup: + Curl_unicodefree(cert_hostname_buff); + + return result; +} + +CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) +{ + SECURITY_STATUS sspi_status; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + CURLcode result = CURLE_OK; + CERT_CONTEXT *pCertContextServer = NULL; + const CERT_CHAIN_CONTEXT *pChainContext = NULL; + HCERTCHAINENGINE cert_chain_engine = NULL; + HCERTSTORE trust_store = NULL; + const char * const conn_hostname = SSL_IS_PROXY() ? + conn->http_proxy.host.name : + conn->host.name; + + sspi_status = + s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, + &pCertContextServer); + + if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { + char buffer[STRERROR_LEN]; + failf(data, "schannel: Failed to read remote certificate context: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + result = CURLE_PEER_FAILED_VERIFICATION; + } + + if(result == CURLE_OK && SSL_CONN_CONFIG(CAfile) && + BACKEND->use_manual_cred_validation) { + /* + * Create a chain engine that uses the certificates in the CA file as + * trusted certificates. This is only supported on Windows 7+. + */ + + if(Curl_verify_windows_version(6, 1, PLATFORM_WINNT, VERSION_LESS_THAN)) { + failf(data, "schannel: this version of Windows is too old to support " + "certificate verification via CA bundle file."); + result = CURLE_SSL_CACERT_BADFILE; + } + else { + /* Open the certificate store */ + trust_store = CertOpenStore(CERT_STORE_PROV_MEMORY, + 0, + (HCRYPTPROV)NULL, + CERT_STORE_CREATE_NEW_FLAG, + NULL); + if(!trust_store) { + char buffer[STRERROR_LEN]; + failf(data, "schannel: failed to create certificate store: %s", + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + result = CURLE_SSL_CACERT_BADFILE; + } + else { + result = add_certs_to_store(trust_store, SSL_CONN_CONFIG(CAfile), + conn); + } + } + + if(result == CURLE_OK) { + CERT_CHAIN_ENGINE_CONFIG_WIN7 engine_config; + BOOL create_engine_result; + + memset(&engine_config, 0, sizeof(engine_config)); + engine_config.cbSize = sizeof(engine_config); + engine_config.hExclusiveRoot = trust_store; + + /* CertCreateCertificateChainEngine will check the expected size of the + * CERT_CHAIN_ENGINE_CONFIG structure and fail if the specified size + * does not match the expected size. When this occurs, it indicates that + * CAINFO is not supported on the version of Windows in use. + */ + create_engine_result = + CertCreateCertificateChainEngine( + (CERT_CHAIN_ENGINE_CONFIG *)&engine_config, &cert_chain_engine); + if(!create_engine_result) { + char buffer[STRERROR_LEN]; + failf(data, + "schannel: failed to create certificate chain engine: %s", + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + result = CURLE_SSL_CACERT_BADFILE; + } + } + } + + if(result == CURLE_OK) { + CERT_CHAIN_PARA ChainPara; + + memset(&ChainPara, 0, sizeof(ChainPara)); + ChainPara.cbSize = sizeof(ChainPara); + + if(!CertGetCertificateChain(cert_chain_engine, + pCertContextServer, + NULL, + pCertContextServer->hCertStore, + &ChainPara, + (data->set.ssl.no_revoke ? 0 : + CERT_CHAIN_REVOCATION_CHECK_CHAIN), + NULL, + &pChainContext)) { + char buffer[STRERROR_LEN]; + failf(data, "schannel: CertGetCertificateChain failed: %s", + Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + pChainContext = NULL; + result = CURLE_PEER_FAILED_VERIFICATION; + } + + if(result == CURLE_OK) { + CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0]; + DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED); + dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus; + if(dwTrustErrorMask) { + if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED) + failf(data, "schannel: CertGetCertificateChain trust error" + " CERT_TRUST_IS_REVOKED"); + else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN) + failf(data, "schannel: CertGetCertificateChain trust error" + " CERT_TRUST_IS_PARTIAL_CHAIN"); + else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT) + failf(data, "schannel: CertGetCertificateChain trust error" + " CERT_TRUST_IS_UNTRUSTED_ROOT"); + else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID) + failf(data, "schannel: CertGetCertificateChain trust error" + " CERT_TRUST_IS_NOT_TIME_VALID"); + else if(dwTrustErrorMask & CERT_TRUST_REVOCATION_STATUS_UNKNOWN) + failf(data, "schannel: CertGetCertificateChain trust error" + " CERT_TRUST_REVOCATION_STATUS_UNKNOWN"); + else + failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x", + dwTrustErrorMask); + result = CURLE_PEER_FAILED_VERIFICATION; + } + } + } + + if(result == CURLE_OK) { + if(SSL_CONN_CONFIG(verifyhost)) { + result = verify_host(conn->data, pCertContextServer, conn_hostname); + } + } + + if(cert_chain_engine) { + CertFreeCertificateChainEngine(cert_chain_engine); + } + + if(trust_store) { + CertCloseStore(trust_store, 0); + } + + if(pChainContext) + CertFreeCertificateChain(pChainContext); + + if(pCertContextServer) + CertFreeCertificateContext(pCertContextServer); + + return result; +} + +#endif /* HAS_MANUAL_VERIFY_API */ +#endif /* USE_SCHANNEL */ diff --git a/libcurl/lib/vtls/sectransp.c b/libcurl/lib/vtls/sectransp.c new file mode 100644 index 0000000..3fb125a --- /dev/null +++ b/libcurl/lib/vtls/sectransp.c @@ -0,0 +1,3277 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2017, Nick Zitzmann, . + * Copyright (C) 2012 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all iOS and macOS SecureTransport-specific code for the + * TLS/SSL layer. No code but vtls.c should ever call or use these functions. + */ + +#include "curl_setup.h" + +#include "urldata.h" /* for the Curl_easy definition */ +#include "curl_base64.h" +#include "strtok.h" +#include "multiif.h" + +#ifdef USE_SECTRANSP + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wtautological-pointer-compare" +#endif /* __clang__ */ + +#include + +#include +/* For some reason, when building for iOS, the omnibus header above does + * not include SecureTransport.h as of iOS SDK 5.1. */ +#include +#include +#include + +/* The Security framework has changed greatly between iOS and different macOS + versions, and we will try to support as many of them as we can (back to + Leopard and iOS 5) by using macros and weak-linking. + + In general, you want to build this using the most recent OS SDK, since some + features require curl to be built against the latest SDK. TLS 1.1 and 1.2 + support, for instance, require the macOS 10.8 SDK or later. TLS 1.3 + requires the macOS 10.13 or iOS 11 SDK or later. */ +#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) + +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 +#error "The Secure Transport back-end requires Leopard or later." +#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */ + +#define CURL_BUILD_IOS 0 +#define CURL_BUILD_IOS_7 0 +#define CURL_BUILD_IOS_9 0 +#define CURL_BUILD_IOS_11 0 +#define CURL_BUILD_MAC 1 +/* This is the maximum API level we are allowed to use when building: */ +#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 +#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 +#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 +#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 +#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 +#define CURL_BUILD_MAC_10_11 MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 +#define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 +/* These macros mean "the following code is present to allow runtime backward + compatibility with at least this cat or earlier": + (You set this at build-time using the compiler command line option + "-mmacos-version-min.") */ +#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050 +#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060 +#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070 +#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080 +#define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090 + +#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE +#define CURL_BUILD_IOS 1 +#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 +#define CURL_BUILD_IOS_9 __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 +#define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 +#define CURL_BUILD_MAC 0 +#define CURL_BUILD_MAC_10_5 0 +#define CURL_BUILD_MAC_10_6 0 +#define CURL_BUILD_MAC_10_7 0 +#define CURL_BUILD_MAC_10_8 0 +#define CURL_BUILD_MAC_10_9 0 +#define CURL_BUILD_MAC_10_11 0 +#define CURL_BUILD_MAC_10_13 0 +#define CURL_SUPPORT_MAC_10_5 0 +#define CURL_SUPPORT_MAC_10_6 0 +#define CURL_SUPPORT_MAC_10_7 0 +#define CURL_SUPPORT_MAC_10_8 0 +#define CURL_SUPPORT_MAC_10_9 0 + +#else +#error "The Secure Transport back-end requires iOS or macOS." +#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */ + +#if CURL_BUILD_MAC +#include +#endif /* CURL_BUILD_MAC */ + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "connect.h" +#include "select.h" +#include "vtls.h" +#include "sectransp.h" +#include "curl_printf.h" +#include "strdup.h" + +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* From MacTypes.h (which we can't include because it isn't present in iOS: */ +#define ioErr -36 +#define paramErr -50 + +struct ssl_backend_data { + SSLContextRef ssl_ctx; + curl_socket_t ssl_sockfd; + bool ssl_direction; /* true if writing, false if reading */ + size_t ssl_write_buffered_length; +}; + +#define BACKEND connssl->backend + +/* pinned public key support tests */ + +/* version 1 supports macOS 10.12+ and iOS 10+ */ +#if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \ + (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)) +#define SECTRANSP_PINNEDPUBKEY_V1 1 +#endif + +/* version 2 supports MacOSX 10.7+ */ +#if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) +#define SECTRANSP_PINNEDPUBKEY_V2 1 +#endif + +#if defined(SECTRANSP_PINNEDPUBKEY_V1) || defined(SECTRANSP_PINNEDPUBKEY_V2) +/* this backend supports CURLOPT_PINNEDPUBLICKEY */ +#define SECTRANSP_PINNEDPUBKEY 1 +#endif /* SECTRANSP_PINNEDPUBKEY */ + +#ifdef SECTRANSP_PINNEDPUBKEY +/* both new and old APIs return rsa keys missing the spki header (not DER) */ +static const unsigned char rsa4096SpkiHeader[] = { + 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00}; + +static const unsigned char rsa2048SpkiHeader[] = { + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00}; +#ifdef SECTRANSP_PINNEDPUBKEY_V1 +/* the *new* version doesn't return DER encoded ecdsa certs like the old... */ +static const unsigned char ecDsaSecp256r1SpkiHeader[] = { + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, + 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, + 0x42, 0x00}; + +static const unsigned char ecDsaSecp384r1SpkiHeader[] = { + 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, + 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, + 0x00, 0x22, 0x03, 0x62, 0x00}; +#endif /* SECTRANSP_PINNEDPUBKEY_V1 */ +#endif /* SECTRANSP_PINNEDPUBKEY */ + +/* The following two functions were ripped from Apple sample code, + * with some modifications: */ +static OSStatus SocketRead(SSLConnectionRef connection, + void *data, /* owned by + * caller, data + * RETURNED */ + size_t *dataLength) /* IN/OUT */ +{ + size_t bytesToGo = *dataLength; + size_t initLen = bytesToGo; + UInt8 *currData = (UInt8 *)data; + /*int sock = *(int *)connection;*/ + struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; + int sock = BACKEND->ssl_sockfd; + OSStatus rtn = noErr; + size_t bytesRead; + ssize_t rrtn; + int theErr; + + *dataLength = 0; + + for(;;) { + bytesRead = 0; + rrtn = read(sock, currData, bytesToGo); + if(rrtn <= 0) { + /* this is guesswork... */ + theErr = errno; + if(rrtn == 0) { /* EOF = server hung up */ + /* the framework will turn this into errSSLClosedNoNotify */ + rtn = errSSLClosedGraceful; + } + else /* do the switch */ + switch(theErr) { + case ENOENT: + /* connection closed */ + rtn = errSSLClosedGraceful; + break; + case ECONNRESET: + rtn = errSSLClosedAbort; + break; + case EAGAIN: + rtn = errSSLWouldBlock; + BACKEND->ssl_direction = false; + break; + default: + rtn = ioErr; + break; + } + break; + } + else { + bytesRead = rrtn; + } + bytesToGo -= bytesRead; + currData += bytesRead; + + if(bytesToGo == 0) { + /* filled buffer with incoming data, done */ + break; + } + } + *dataLength = initLen - bytesToGo; + + return rtn; +} + +static OSStatus SocketWrite(SSLConnectionRef connection, + const void *data, + size_t *dataLength) /* IN/OUT */ +{ + size_t bytesSent = 0; + /*int sock = *(int *)connection;*/ + struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; + int sock = BACKEND->ssl_sockfd; + ssize_t length; + size_t dataLen = *dataLength; + const UInt8 *dataPtr = (UInt8 *)data; + OSStatus ortn; + int theErr; + + *dataLength = 0; + + do { + length = write(sock, + (char *)dataPtr + bytesSent, + dataLen - bytesSent); + } while((length > 0) && + ( (bytesSent += length) < dataLen) ); + + if(length <= 0) { + theErr = errno; + if(theErr == EAGAIN) { + ortn = errSSLWouldBlock; + BACKEND->ssl_direction = true; + } + else { + ortn = ioErr; + } + } + else { + ortn = noErr; + } + *dataLength = bytesSent; + return ortn; +} + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) +{ + switch(cipher) { + /* SSL version 3.0 */ + case SSL_RSA_WITH_NULL_MD5: + return "SSL_RSA_WITH_NULL_MD5"; + break; + case SSL_RSA_WITH_NULL_SHA: + return "SSL_RSA_WITH_NULL_SHA"; + break; + case SSL_RSA_EXPORT_WITH_RC4_40_MD5: + return "SSL_RSA_EXPORT_WITH_RC4_40_MD5"; + break; + case SSL_RSA_WITH_RC4_128_MD5: + return "SSL_RSA_WITH_RC4_128_MD5"; + break; + case SSL_RSA_WITH_RC4_128_SHA: + return "SSL_RSA_WITH_RC4_128_SHA"; + break; + case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: + return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"; + break; + case SSL_RSA_WITH_IDEA_CBC_SHA: + return "SSL_RSA_WITH_IDEA_CBC_SHA"; + break; + case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_RSA_WITH_DES_CBC_SHA: + return "SSL_RSA_WITH_DES_CBC_SHA"; + break; + case SSL_RSA_WITH_3DES_EDE_CBC_SHA: + return "SSL_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DH_DSS_WITH_DES_CBC_SHA: + return "SSL_DH_DSS_WITH_DES_CBC_SHA"; + break; + case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA: + return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DH_RSA_WITH_DES_CBC_SHA: + return "SSL_DH_RSA_WITH_DES_CBC_SHA"; + break; + case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA: + return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DHE_DSS_WITH_DES_CBC_SHA: + return "SSL_DHE_DSS_WITH_DES_CBC_SHA"; + break; + case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DHE_RSA_WITH_DES_CBC_SHA: + return "SSL_DHE_RSA_WITH_DES_CBC_SHA"; + break; + case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: + return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"; + break; + case SSL_DH_anon_WITH_RC4_128_MD5: + return "SSL_DH_anon_WITH_RC4_128_MD5"; + break; + case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: + return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"; + break; + case SSL_DH_anon_WITH_DES_CBC_SHA: + return "SSL_DH_anon_WITH_DES_CBC_SHA"; + break; + case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: + return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_FORTEZZA_DMS_WITH_NULL_SHA: + return "SSL_FORTEZZA_DMS_WITH_NULL_SHA"; + break; + case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA: + return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"; + break; + /* TLS 1.0 with AES (RFC 3268) + (Apparently these are used in SSLv3 implementations as well.) */ + case TLS_RSA_WITH_AES_128_CBC_SHA: + return "TLS_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_128_CBC_SHA: + return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_AES_128_CBC_SHA: + return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_128_CBC_SHA: + return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; + break; + case TLS_RSA_WITH_AES_256_CBC_SHA: + return "TLS_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_256_CBC_SHA: + return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_AES_256_CBC_SHA: + return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_256_CBC_SHA: + return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; + break; + /* SSL version 2.0 */ + case SSL_RSA_WITH_RC2_CBC_MD5: + return "SSL_RSA_WITH_RC2_CBC_MD5"; + break; + case SSL_RSA_WITH_IDEA_CBC_MD5: + return "SSL_RSA_WITH_IDEA_CBC_MD5"; + break; + case SSL_RSA_WITH_DES_CBC_MD5: + return "SSL_RSA_WITH_DES_CBC_MD5"; + break; + case SSL_RSA_WITH_3DES_EDE_CBC_MD5: + return "SSL_RSA_WITH_3DES_EDE_CBC_MD5"; + break; + } + return "SSL_NULL_WITH_NULL_NULL"; +} + +CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) +{ + switch(cipher) { + /* TLS 1.0 with AES (RFC 3268) */ + case TLS_RSA_WITH_AES_128_CBC_SHA: + return "TLS_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_128_CBC_SHA: + return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_AES_128_CBC_SHA: + return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_128_CBC_SHA: + return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; + break; + case TLS_RSA_WITH_AES_256_CBC_SHA: + return "TLS_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_256_CBC_SHA: + return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_AES_256_CBC_SHA: + return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_256_CBC_SHA: + return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; + break; +#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS + /* TLS 1.0 with ECDSA (RFC 4492) */ + case TLS_ECDH_ECDSA_WITH_NULL_SHA: + return "TLS_ECDH_ECDSA_WITH_NULL_SHA"; + break; + case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"; + break; + case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_NULL_SHA: + return "TLS_ECDHE_ECDSA_WITH_NULL_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_ECDH_RSA_WITH_NULL_SHA: + return "TLS_ECDH_RSA_WITH_NULL_SHA"; + break; + case TLS_ECDH_RSA_WITH_RC4_128_SHA: + return "TLS_ECDH_RSA_WITH_RC4_128_SHA"; + break; + case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_ECDHE_RSA_WITH_NULL_SHA: + return "TLS_ECDHE_RSA_WITH_NULL_SHA"; + break; + case TLS_ECDHE_RSA_WITH_RC4_128_SHA: + return "TLS_ECDHE_RSA_WITH_RC4_128_SHA"; + break; + case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"; + break; + case TLS_ECDH_anon_WITH_NULL_SHA: + return "TLS_ECDH_anon_WITH_NULL_SHA"; + break; + case TLS_ECDH_anon_WITH_RC4_128_SHA: + return "TLS_ECDH_anon_WITH_RC4_128_SHA"; + break; + case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: + return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: + return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"; + break; + case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: + return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"; + break; +#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + /* TLS 1.2 (RFC 5246) */ + case TLS_RSA_WITH_NULL_MD5: + return "TLS_RSA_WITH_NULL_MD5"; + break; + case TLS_RSA_WITH_NULL_SHA: + return "TLS_RSA_WITH_NULL_SHA"; + break; + case TLS_RSA_WITH_RC4_128_MD5: + return "TLS_RSA_WITH_RC4_128_MD5"; + break; + case TLS_RSA_WITH_RC4_128_SHA: + return "TLS_RSA_WITH_RC4_128_SHA"; + break; + case TLS_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_RSA_WITH_NULL_SHA256: + return "TLS_RSA_WITH_NULL_SHA256"; + break; + case TLS_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_RSA_WITH_AES_256_CBC_SHA256: + return "TLS_RSA_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: + return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: + return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: + return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: + return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: + return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: + return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"; + break; + case TLS_DH_anon_WITH_RC4_128_MD5: + return "TLS_DH_anon_WITH_RC4_128_MD5"; + break; + case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DH_anon_WITH_AES_128_CBC_SHA256: + return "TLS_DH_anon_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DH_anon_WITH_AES_256_CBC_SHA256: + return "TLS_DH_anon_WITH_AES_256_CBC_SHA256"; + break; + /* TLS 1.2 with AES GCM (RFC 5288) */ + case TLS_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: + return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: + return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: + return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: + return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DH_anon_WITH_AES_128_GCM_SHA256: + return "TLS_DH_anon_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DH_anon_WITH_AES_256_GCM_SHA384: + return "TLS_DH_anon_WITH_AES_256_GCM_SHA384"; + break; + /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */ + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: + return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"; + break; + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: + return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: + return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"; + break; + case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: + return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"; + break; + case TLS_EMPTY_RENEGOTIATION_INFO_SCSV: + return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; + break; +#else + case SSL_RSA_WITH_NULL_MD5: + return "TLS_RSA_WITH_NULL_MD5"; + break; + case SSL_RSA_WITH_NULL_SHA: + return "TLS_RSA_WITH_NULL_SHA"; + break; + case SSL_RSA_WITH_RC4_128_MD5: + return "TLS_RSA_WITH_RC4_128_MD5"; + break; + case SSL_RSA_WITH_RC4_128_SHA: + return "TLS_RSA_WITH_RC4_128_SHA"; + break; + case SSL_RSA_WITH_3DES_EDE_CBC_SHA: + return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; + break; + case SSL_DH_anon_WITH_RC4_128_MD5: + return "TLS_DH_anon_WITH_RC4_128_MD5"; + break; + case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: + return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; + break; +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + /* TLS PSK (RFC 4279): */ + case TLS_PSK_WITH_RC4_128_SHA: + return "TLS_PSK_WITH_RC4_128_SHA"; + break; + case TLS_PSK_WITH_3DES_EDE_CBC_SHA: + return "TLS_PSK_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_PSK_WITH_AES_128_CBC_SHA: + return "TLS_PSK_WITH_AES_128_CBC_SHA"; + break; + case TLS_PSK_WITH_AES_256_CBC_SHA: + return "TLS_PSK_WITH_AES_256_CBC_SHA"; + break; + case TLS_DHE_PSK_WITH_RC4_128_SHA: + return "TLS_DHE_PSK_WITH_RC4_128_SHA"; + break; + case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: + return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA: + return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"; + break; + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA: + return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"; + break; + case TLS_RSA_PSK_WITH_RC4_128_SHA: + return "TLS_RSA_PSK_WITH_RC4_128_SHA"; + break; + case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: + return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"; + break; + case TLS_RSA_PSK_WITH_AES_128_CBC_SHA: + return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"; + break; + case TLS_RSA_PSK_WITH_AES_256_CBC_SHA: + return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"; + break; + /* More TLS PSK (RFC 4785): */ + case TLS_PSK_WITH_NULL_SHA: + return "TLS_PSK_WITH_NULL_SHA"; + break; + case TLS_DHE_PSK_WITH_NULL_SHA: + return "TLS_DHE_PSK_WITH_NULL_SHA"; + break; + case TLS_RSA_PSK_WITH_NULL_SHA: + return "TLS_RSA_PSK_WITH_NULL_SHA"; + break; + /* Even more TLS PSK (RFC 5487): */ + case TLS_PSK_WITH_AES_128_GCM_SHA256: + return "TLS_PSK_WITH_AES_128_GCM_SHA256"; + break; + case TLS_PSK_WITH_AES_256_GCM_SHA384: + return "TLS_PSK_WITH_AES_256_GCM_SHA384"; + break; + case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: + return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"; + break; + case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: + return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"; + break; + case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: + return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"; + break; + case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: + return "TLS_PSK_WITH_AES_256_GCM_SHA384"; + break; + case TLS_PSK_WITH_AES_128_CBC_SHA256: + return "TLS_PSK_WITH_AES_128_CBC_SHA256"; + break; + case TLS_PSK_WITH_AES_256_CBC_SHA384: + return "TLS_PSK_WITH_AES_256_CBC_SHA384"; + break; + case TLS_PSK_WITH_NULL_SHA256: + return "TLS_PSK_WITH_NULL_SHA256"; + break; + case TLS_PSK_WITH_NULL_SHA384: + return "TLS_PSK_WITH_NULL_SHA384"; + break; + case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: + return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"; + break; + case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: + return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"; + break; + case TLS_DHE_PSK_WITH_NULL_SHA256: + return "TLS_DHE_PSK_WITH_NULL_SHA256"; + break; + case TLS_DHE_PSK_WITH_NULL_SHA384: + return "TLS_RSA_PSK_WITH_NULL_SHA384"; + break; + case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: + return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"; + break; + case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: + return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"; + break; + case TLS_RSA_PSK_WITH_NULL_SHA256: + return "TLS_RSA_PSK_WITH_NULL_SHA256"; + break; + case TLS_RSA_PSK_WITH_NULL_SHA384: + return "TLS_RSA_PSK_WITH_NULL_SHA384"; + break; +#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ +#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 + /* New ChaCha20+Poly1305 cipher-suites used by TLS 1.3: */ + case TLS_AES_128_GCM_SHA256: + return "TLS_AES_128_GCM_SHA256"; + break; + case TLS_AES_256_GCM_SHA384: + return "TLS_AES_256_GCM_SHA384"; + break; + case TLS_CHACHA20_POLY1305_SHA256: + return "TLS_CHACHA20_POLY1305_SHA256"; + break; + case TLS_AES_128_CCM_SHA256: + return "TLS_AES_128_CCM_SHA256"; + break; + case TLS_AES_128_CCM_8_SHA256: + return "TLS_AES_128_CCM_8_SHA256"; + break; + case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"; + break; + case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"; + break; +#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */ + } + return "TLS_NULL_WITH_NULL_NULL"; +} +#endif /* !CURL_DISABLE_VERBOSE_STRINGS */ + +#if CURL_BUILD_MAC +CF_INLINE void GetDarwinVersionNumber(int *major, int *minor) +{ + int mib[2]; + char *os_version; + size_t os_version_len; + char *os_version_major, *os_version_minor; + char *tok_buf; + + /* Get the Darwin kernel version from the kernel using sysctl(): */ + mib[0] = CTL_KERN; + mib[1] = KERN_OSRELEASE; + if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1) + return; + os_version = malloc(os_version_len*sizeof(char)); + if(!os_version) + return; + if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) { + free(os_version); + return; + } + + /* Parse the version: */ + os_version_major = strtok_r(os_version, ".", &tok_buf); + os_version_minor = strtok_r(NULL, ".", &tok_buf); + *major = atoi(os_version_major); + *minor = atoi(os_version_minor); + free(os_version); +} +#endif /* CURL_BUILD_MAC */ + +/* Apple provides a myriad of ways of getting information about a certificate + into a string. Some aren't available under iOS or newer cats. So here's + a unified function for getting a string describing the certificate that + ought to work in all cats starting with Leopard. */ +CF_INLINE CFStringRef getsubject(SecCertificateRef cert) +{ + CFStringRef server_cert_summary = CFSTR("(null)"); + +#if CURL_BUILD_IOS + /* iOS: There's only one way to do this. */ + server_cert_summary = SecCertificateCopySubjectSummary(cert); +#else +#if CURL_BUILD_MAC_10_7 + /* Lion & later: Get the long description if we can. */ + if(SecCertificateCopyLongDescription != NULL) + server_cert_summary = + SecCertificateCopyLongDescription(NULL, cert, NULL); + else +#endif /* CURL_BUILD_MAC_10_7 */ +#if CURL_BUILD_MAC_10_6 + /* Snow Leopard: Get the certificate summary. */ + if(SecCertificateCopySubjectSummary != NULL) + server_cert_summary = SecCertificateCopySubjectSummary(cert); + else +#endif /* CURL_BUILD_MAC_10_6 */ + /* Leopard is as far back as we go... */ + (void)SecCertificateCopyCommonName(cert, &server_cert_summary); +#endif /* CURL_BUILD_IOS */ + return server_cert_summary; +} + +static CURLcode CopyCertSubject(struct Curl_easy *data, + SecCertificateRef cert, char **certp) +{ + CFStringRef c = getsubject(cert); + CURLcode result = CURLE_OK; + const char *direct; + char *cbuf = NULL; + *certp = NULL; + + if(!c) { + failf(data, "SSL: invalid CA certificate subject"); + return CURLE_PEER_FAILED_VERIFICATION; + } + + /* If the subject is already available as UTF-8 encoded (ie 'direct') then + use that, else convert it. */ + direct = CFStringGetCStringPtr(c, kCFStringEncodingUTF8); + if(direct) { + *certp = strdup(direct); + if(!*certp) { + failf(data, "SSL: out of memory"); + result = CURLE_OUT_OF_MEMORY; + } + } + else { + size_t cbuf_size = ((size_t)CFStringGetLength(c) * 4) + 1; + cbuf = calloc(cbuf_size, 1); + if(cbuf) { + if(!CFStringGetCString(c, cbuf, cbuf_size, + kCFStringEncodingUTF8)) { + failf(data, "SSL: invalid CA certificate subject"); + result = CURLE_PEER_FAILED_VERIFICATION; + } + else + /* pass back the buffer */ + *certp = cbuf; + } + else { + failf(data, "SSL: couldn't allocate %zu bytes of memory", cbuf_size); + result = CURLE_OUT_OF_MEMORY; + } + } + if(result) + free(cbuf); + CFRelease(c); + return result; +} + +#if CURL_SUPPORT_MAC_10_6 +/* The SecKeychainSearch API was deprecated in Lion, and using it will raise + deprecation warnings, so let's not compile this unless it's necessary: */ +static OSStatus CopyIdentityWithLabelOldSchool(char *label, + SecIdentityRef *out_c_a_k) +{ + OSStatus status = errSecItemNotFound; + SecKeychainAttributeList attr_list; + SecKeychainAttribute attr; + SecKeychainSearchRef search = NULL; + SecCertificateRef cert = NULL; + + /* Set up the attribute list: */ + attr_list.count = 1L; + attr_list.attr = &attr; + + /* Set up our lone search criterion: */ + attr.tag = kSecLabelItemAttr; + attr.data = label; + attr.length = (UInt32)strlen(label); + + /* Start searching: */ + status = SecKeychainSearchCreateFromAttributes(NULL, + kSecCertificateItemClass, + &attr_list, + &search); + if(status == noErr) { + status = SecKeychainSearchCopyNext(search, + (SecKeychainItemRef *)&cert); + if(status == noErr && cert) { + /* If we found a certificate, does it have a private key? */ + status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k); + CFRelease(cert); + } + } + + if(search) + CFRelease(search); + return status; +} +#endif /* CURL_SUPPORT_MAC_10_6 */ + +static OSStatus CopyIdentityWithLabel(char *label, + SecIdentityRef *out_cert_and_key) +{ + OSStatus status = errSecItemNotFound; + +#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS + CFArrayRef keys_list; + CFIndex keys_list_count; + CFIndex i; + CFStringRef common_name; + + /* SecItemCopyMatching() was introduced in iOS and Snow Leopard. + kSecClassIdentity was introduced in Lion. If both exist, let's use them + to find the certificate. */ + if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) { + CFTypeRef keys[5]; + CFTypeRef values[5]; + CFDictionaryRef query_dict; + CFStringRef label_cf = CFStringCreateWithCString(NULL, label, + kCFStringEncodingUTF8); + + /* Set up our search criteria and expected results: */ + values[0] = kSecClassIdentity; /* we want a certificate and a key */ + keys[0] = kSecClass; + values[1] = kCFBooleanTrue; /* we want a reference */ + keys[1] = kSecReturnRef; + values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the + * label matching below worked correctly */ + keys[2] = kSecMatchLimit; + /* identity searches need a SecPolicyRef in order to work */ + values[3] = SecPolicyCreateSSL(false, NULL); + keys[3] = kSecMatchPolicy; + /* match the name of the certificate (doesn't work in macOS 10.12.1) */ + values[4] = label_cf; + keys[4] = kSecAttrLabel; + query_dict = CFDictionaryCreate(NULL, (const void **)keys, + (const void **)values, 5L, + &kCFCopyStringDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFRelease(values[3]); + + /* Do we have a match? */ + status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list); + + /* Because kSecAttrLabel matching doesn't work with kSecClassIdentity, + * we need to find the correct identity ourselves */ + if(status == noErr) { + keys_list_count = CFArrayGetCount(keys_list); + *out_cert_and_key = NULL; + status = 1; + for(i = 0; idata; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + long ssl_version = SSL_CONN_CONFIG(version); + long ssl_version_max = SSL_CONN_CONFIG(version_max); + long max_supported_version_by_os; + + /* macOS 10.5-10.7 supported TLS 1.0 only. + macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2. + macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */ +#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 + if(__builtin_available(macOS 10.13, iOS 11.0, *)) { + max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3; + } + else { + max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2; + } +#else + max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2; +#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && + HAVE_BUILTIN_AVAILABLE == 1 */ + + switch(ssl_version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + ssl_version = CURL_SSLVERSION_TLSv1_0; + break; + } + + switch(ssl_version_max) { + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_DEFAULT: + ssl_version_max = max_supported_version_by_os; + break; + } + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + if(SSLSetProtocolVersionMax != NULL) { + SSLProtocol darwin_ver_min = kTLSProtocol1; + SSLProtocol darwin_ver_max = kTLSProtocol1; + CURLcode result = sectransp_version_from_curl(&darwin_ver_min, + ssl_version); + if(result) { + failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); + return result; + } + result = sectransp_version_from_curl(&darwin_ver_max, + ssl_version_max >> 16); + if(result) { + failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); + return result; + } + + (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, darwin_ver_min); + (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, darwin_ver_max); + return result; + } + else { +#if CURL_SUPPORT_MAC_10_8 + long i = ssl_version; + (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kSSLProtocolAll, + false); + for(; i <= (ssl_version_max >> 16); i++) { + switch(i) { + case CURL_SSLVERSION_TLSv1_0: + (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kTLSProtocol1, + true); + break; + case CURL_SSLVERSION_TLSv1_1: + (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kTLSProtocol11, + true); + break; + case CURL_SSLVERSION_TLSv1_2: + (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kTLSProtocol12, + true); + break; + case CURL_SSLVERSION_TLSv1_3: + failf(data, "Your version of the OS does not support TLSv1.3"); + return CURLE_SSL_CONNECT_ERROR; + } + } + return CURLE_OK; +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + failf(data, "Secure Transport: cannot set SSL protocol"); + return CURLE_SSL_CONNECT_ERROR; +} + + +static CURLcode sectransp_connect_step1(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + curl_socket_t sockfd = conn->sock[sockindex]; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); + char * const ssl_cert = SSL_SET_OPTION(cert); + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; +#ifdef ENABLE_IPV6 + struct in6_addr addr; +#else + struct in_addr addr; +#endif /* ENABLE_IPV6 */ + size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i; + SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL; + OSStatus err = noErr; +#if CURL_BUILD_MAC + int darwinver_maj = 0, darwinver_min = 0; + + GetDarwinVersionNumber(&darwinver_maj, &darwinver_min); +#endif /* CURL_BUILD_MAC */ + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + if(SSLCreateContext != NULL) { /* use the newer API if available */ + if(BACKEND->ssl_ctx) + CFRelease(BACKEND->ssl_ctx); + BACKEND->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType); + if(!BACKEND->ssl_ctx) { + failf(data, "SSL: couldn't create a context!"); + return CURLE_OUT_OF_MEMORY; + } + } + else { + /* The old ST API does not exist under iOS, so don't compile it: */ +#if CURL_SUPPORT_MAC_10_8 + if(BACKEND->ssl_ctx) + (void)SSLDisposeContext(BACKEND->ssl_ctx); + err = SSLNewContext(false, &(BACKEND->ssl_ctx)); + if(err != noErr) { + failf(data, "SSL: couldn't create a context: OSStatus %d", err); + return CURLE_OUT_OF_MEMORY; + } +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#else + if(BACKEND->ssl_ctx) + (void)SSLDisposeContext(BACKEND->ssl_ctx); + err = SSLNewContext(false, &(BACKEND->ssl_ctx)); + if(err != noErr) { + failf(data, "SSL: couldn't create a context: OSStatus %d", err); + return CURLE_OUT_OF_MEMORY; + } +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + BACKEND->ssl_write_buffered_length = 0UL; /* reset buffered write length */ + + /* check to see if we've been told to use an explicit SSL/TLS version */ +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + if(SSLSetProtocolVersionMax != NULL) { + switch(conn->ssl_config.version) { + case CURL_SSLVERSION_TLSv1: + (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kTLSProtocol1); +#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 + if(__builtin_available(macOS 10.13, iOS 11.0, *)) { + (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol13); + } + else { + (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12); + } +#else + (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12); +#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && + HAVE_BUILTIN_AVAILABLE == 1 */ + break; + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + { + CURLcode result = set_ssl_version_min_max(conn, sockindex); + if(result != CURLE_OK) + return result; + break; + } + case CURL_SSLVERSION_SSLv3: + err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol3); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + } + (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol3); + break; + case CURL_SSLVERSION_SSLv2: + err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol2); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + } + (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol2); + break; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + } + else { +#if CURL_SUPPORT_MAC_10_8 + (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kSSLProtocolAll, + false); + switch(conn->ssl_config.version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kTLSProtocol1, + true); + (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kTLSProtocol11, + true); + (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kTLSProtocol12, + true); + break; + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + { + CURLcode result = set_ssl_version_min_max(conn, sockindex); + if(result != CURLE_OK) + return result; + break; + } + case CURL_SSLVERSION_SSLv3: + err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kSSLProtocol3, + true); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + } + break; + case CURL_SSLVERSION_SSLv2: + err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kSSLProtocol2, + true); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + } + break; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#else + if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) { + failf(data, "Your version of the OS does not support to set maximum" + " SSL/TLS version"); + return CURLE_SSL_CONNECT_ERROR; + } + (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, kSSLProtocolAll, false); + switch(conn->ssl_config.version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: + (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kTLSProtocol1, + true); + break; + case CURL_SSLVERSION_TLSv1_1: + failf(data, "Your version of the OS does not support TLSv1.1"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_TLSv1_2: + failf(data, "Your version of the OS does not support TLSv1.2"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_TLSv1_3: + failf(data, "Your version of the OS does not support TLSv1.3"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_SSLv2: + err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kSSLProtocol2, + true); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + } + break; + case CURL_SSLVERSION_SSLv3: + err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, + kSSLProtocol3, + true); + if(err != noErr) { + failf(data, "Your version of the OS does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + } + break; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + +#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 + if(conn->bits.tls_enable_alpn) { + if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) { + CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0, + &kCFTypeArrayCallBacks); + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2 && + (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) { + CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID)); + infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + CFArrayAppendValue(alpnArr, CFSTR(ALPN_HTTP_1_1)); + infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + + /* expects length prefixed preference ordered list of protocols in wire + * format + */ + err = SSLSetALPNProtocols(BACKEND->ssl_ctx, alpnArr); + if(err != noErr) + infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d\n", + err); + CFRelease(alpnArr); + } + } +#endif + + if(SSL_SET_OPTION(key)) { + infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure " + "Transport. The private key must be in the Keychain.\n"); + } + + if(ssl_cert) { + SecIdentityRef cert_and_key = NULL; + bool is_cert_file = is_file(ssl_cert); + + /* User wants to authenticate with a client cert. Look for it: + If we detect that this is a file on disk, then let's load it. + Otherwise, assume that the user wants to use an identity loaded + from the Keychain. */ + if(is_cert_file) { + if(!SSL_SET_OPTION(cert_type)) + infof(data, "WARNING: SSL: Certificate type not set, assuming " + "PKCS#12 format.\n"); + else if(strncmp(SSL_SET_OPTION(cert_type), "P12", + strlen(SSL_SET_OPTION(cert_type))) != 0) + infof(data, "WARNING: SSL: The Security framework only supports " + "loading identities that are in PKCS#12 format.\n"); + + err = CopyIdentityFromPKCS12File(ssl_cert, + SSL_SET_OPTION(key_passwd), &cert_and_key); + } + else + err = CopyIdentityWithLabel(ssl_cert, &cert_and_key); + + if(err == noErr && cert_and_key) { + SecCertificateRef cert = NULL; + CFTypeRef certs_c[1]; + CFArrayRef certs; + + /* If we found one, print it out: */ + err = SecIdentityCopyCertificate(cert_and_key, &cert); + if(err == noErr) { + char *certp; + CURLcode result = CopyCertSubject(data, cert, &certp); + if(!result) { + infof(data, "Client certificate: %s\n", certp); + free(certp); + } + + CFRelease(cert); + if(result == CURLE_PEER_FAILED_VERIFICATION) + return CURLE_SSL_CERTPROBLEM; + if(result) + return result; + } + certs_c[0] = cert_and_key; + certs = CFArrayCreate(NULL, (const void **)certs_c, 1L, + &kCFTypeArrayCallBacks); + err = SSLSetCertificate(BACKEND->ssl_ctx, certs); + if(certs) + CFRelease(certs); + if(err != noErr) { + failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err); + return CURLE_SSL_CERTPROBLEM; + } + CFRelease(cert_and_key); + } + else { + switch(err) { + case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */ + failf(data, "SSL: Incorrect password for the certificate \"%s\" " + "and its private key.", ssl_cert); + break; + case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */ + failf(data, "SSL: Couldn't make sense of the data in the " + "certificate \"%s\" and its private key.", + ssl_cert); + break; + case -25260: /* errSecPassphraseRequired */ + failf(data, "SSL The certificate \"%s\" requires a password.", + ssl_cert); + break; + case errSecItemNotFound: + failf(data, "SSL: Can't find the certificate \"%s\" and its private " + "key in the Keychain.", ssl_cert); + break; + default: + failf(data, "SSL: Can't load the certificate \"%s\" and its private " + "key: OSStatus %d", ssl_cert, err); + break; + } + return CURLE_SSL_CERTPROBLEM; + } + } + + /* SSL always tries to verify the peer, this only says whether it should + * fail to connect if the verification fails, or if it should continue + * anyway. In the latter case the result of the verification is checked with + * SSL_get_verify_result() below. */ +#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS + /* Snow Leopard introduced the SSLSetSessionOption() function, but due to + a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag + works, it doesn't work as expected under Snow Leopard, Lion or + Mountain Lion. + So we need to call SSLSetEnableCertVerify() on those older cats in order + to disable certificate validation if the user turned that off. + (SecureTransport will always validate the certificate chain by + default.) + Note: + Darwin 11.x.x is Lion (10.7) + Darwin 12.x.x is Mountain Lion (10.8) + Darwin 13.x.x is Mavericks (10.9) + Darwin 14.x.x is Yosemite (10.10) + Darwin 15.x.x is El Capitan (10.11) + */ +#if CURL_BUILD_MAC + if(SSLSetSessionOption != NULL && darwinver_maj >= 13) { +#else + if(SSLSetSessionOption != NULL) { +#endif /* CURL_BUILD_MAC */ + bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile; + err = SSLSetSessionOption(BACKEND->ssl_ctx, + kSSLSessionOptionBreakOnServerAuth, + break_on_auth); + if(err != noErr) { + failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + } + else { +#if CURL_SUPPORT_MAC_10_8 + err = SSLSetEnableCertVerify(BACKEND->ssl_ctx, + conn->ssl_config.verifypeer?true:false); + if(err != noErr) { + failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#else + err = SSLSetEnableCertVerify(BACKEND->ssl_ctx, + conn->ssl_config.verifypeer?true:false); + if(err != noErr) { + failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } +#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ + + if(ssl_cafile && verifypeer) { + bool is_cert_file = is_file(ssl_cafile); + + if(!is_cert_file) { + failf(data, "SSL: can't load CA certificate file %s", ssl_cafile); + return CURLE_SSL_CACERT_BADFILE; + } + } + + /* Configure hostname check. SNI is used if available. + * Both hostname check and SNI require SSLSetPeerDomainName(). + * Also: the verifyhost setting influences SNI usage */ + if(conn->ssl_config.verifyhost) { + err = SSLSetPeerDomainName(BACKEND->ssl_ctx, hostname, + strlen(hostname)); + + if(err != noErr) { + infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n", + err); + } + + if((Curl_inet_pton(AF_INET, hostname, &addr)) + #ifdef ENABLE_IPV6 + || (Curl_inet_pton(AF_INET6, hostname, &addr)) + #endif + ) { + infof(data, "WARNING: using IP address, SNI is being disabled by " + "the OS.\n"); + } + } + else { + infof(data, "WARNING: disabling hostname validation also disables SNI.\n"); + } + + /* Disable cipher suites that ST supports but are not safe. These ciphers + are unlikely to be used in any case since ST gives other ciphers a much + higher priority, but it's probably better that we not connect at all than + to give the user a false sense of security if the server only supports + insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */ + err = SSLGetNumberSupportedCiphers(BACKEND->ssl_ctx, &all_ciphers_count); + if(err != noErr) { + failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d", + err); + return CURLE_SSL_CIPHER; + } + all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); + if(!all_ciphers) { + failf(data, "SSL: Failed to allocate memory for all ciphers"); + return CURLE_OUT_OF_MEMORY; + } + allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); + if(!allowed_ciphers) { + Curl_safefree(all_ciphers); + failf(data, "SSL: Failed to allocate memory for allowed ciphers"); + return CURLE_OUT_OF_MEMORY; + } + err = SSLGetSupportedCiphers(BACKEND->ssl_ctx, all_ciphers, + &all_ciphers_count); + if(err != noErr) { + Curl_safefree(all_ciphers); + Curl_safefree(allowed_ciphers); + return CURLE_SSL_CIPHER; + } + for(i = 0UL ; i < all_ciphers_count ; i++) { +#if CURL_BUILD_MAC + /* There's a known bug in early versions of Mountain Lion where ST's ECC + ciphers (cipher suite 0xC001 through 0xC032) simply do not work. + Work around the problem here by disabling those ciphers if we are + running in an affected version of OS X. */ + if(darwinver_maj == 12 && darwinver_min <= 3 && + all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) { + continue; + } +#endif /* CURL_BUILD_MAC */ + switch(all_ciphers[i]) { + /* Disable NULL ciphersuites: */ + case SSL_NULL_WITH_NULL_NULL: + case SSL_RSA_WITH_NULL_MD5: + case SSL_RSA_WITH_NULL_SHA: + case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */ + case SSL_FORTEZZA_DMS_WITH_NULL_SHA: + case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */ + case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */ + case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */ + case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */ + case 0x002C: /* TLS_PSK_WITH_NULL_SHA */ + case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */ + case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */ + case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */ + case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */ + case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */ + case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */ + case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */ + case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */ + /* Disable anonymous ciphersuites: */ + case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: + case SSL_DH_anon_WITH_RC4_128_MD5: + case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DH_anon_WITH_DES_CBC_SHA: + case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: + case TLS_DH_anon_WITH_AES_128_CBC_SHA: + case TLS_DH_anon_WITH_AES_256_CBC_SHA: + case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */ + case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */ + case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */ + case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */ + case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */ + case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */ + case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */ + case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */ + case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */ + /* Disable weak key ciphersuites: */ + case SSL_RSA_EXPORT_WITH_RC4_40_MD5: + case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: + case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: + case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: + case SSL_RSA_WITH_DES_CBC_SHA: + case SSL_DH_DSS_WITH_DES_CBC_SHA: + case SSL_DH_RSA_WITH_DES_CBC_SHA: + case SSL_DHE_DSS_WITH_DES_CBC_SHA: + case SSL_DHE_RSA_WITH_DES_CBC_SHA: + /* Disable IDEA: */ + case SSL_RSA_WITH_IDEA_CBC_SHA: + case SSL_RSA_WITH_IDEA_CBC_MD5: + /* Disable RC4: */ + case SSL_RSA_WITH_RC4_128_MD5: + case SSL_RSA_WITH_RC4_128_SHA: + case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */ + case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/ + case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */ + case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */ + case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */ + case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */ + case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */ + break; + default: /* enable everything else */ + allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i]; + break; + } + } + err = SSLSetEnabledCiphers(BACKEND->ssl_ctx, allowed_ciphers, + allowed_ciphers_count); + Curl_safefree(all_ciphers); + Curl_safefree(allowed_ciphers); + if(err != noErr) { + failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); + return CURLE_SSL_CIPHER; + } + +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + /* We want to enable 1/n-1 when using a CBC cipher unless the user + specifically doesn't want us doing that: */ + if(SSLSetSessionOption != NULL) { + SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionSendOneByteRecord, + !data->set.ssl.enable_beast); + SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionFalseStart, + data->set.ssl.falsestart); /* false start support */ + } +#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ + + /* Check if there's a cached ID we can/should use here! */ + if(SSL_SET_OPTION(primary.sessionid)) { + char *ssl_sessionid; + size_t ssl_sessionid_len; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid, + &ssl_sessionid_len, sockindex)) { + /* we got a session id, use it! */ + err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len); + Curl_ssl_sessionid_unlock(conn); + if(err != noErr) { + failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + /* Informational message */ + infof(data, "SSL re-using session ID\n"); + } + /* If there isn't one, then let's make one up! This has to be done prior + to starting the handshake. */ + else { + CURLcode result; + ssl_sessionid = + aprintf("%s:%d:%d:%s:%hu", ssl_cafile, + verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port); + ssl_sessionid_len = strlen(ssl_sessionid); + + err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len); + if(err != noErr) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + + result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len, + sockindex); + Curl_ssl_sessionid_unlock(conn); + if(result) { + failf(data, "failed to store ssl session"); + return result; + } + } + } + + err = SSLSetIOFuncs(BACKEND->ssl_ctx, SocketRead, SocketWrite); + if(err != noErr) { + failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + + /* pass the raw socket into the SSL layers */ + /* We need to store the FD in a constant memory address, because + * SSLSetConnection() will not copy that address. I've found that + * conn->sock[sockindex] may change on its own. */ + BACKEND->ssl_sockfd = sockfd; + err = SSLSetConnection(BACKEND->ssl_ctx, connssl); + if(err != noErr) { + failf(data, "SSL: SSLSetConnection() failed: %d", err); + return CURLE_SSL_CONNECT_ERROR; + } + + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; +} + +static long pem_to_der(const char *in, unsigned char **out, size_t *outlen) +{ + char *sep_start, *sep_end, *cert_start, *cert_end; + size_t i, j, err; + size_t len; + unsigned char *b64; + + /* Jump through the separators at the beginning of the certificate. */ + sep_start = strstr(in, "-----"); + if(sep_start == NULL) + return 0; + cert_start = strstr(sep_start + 1, "-----"); + if(cert_start == NULL) + return -1; + + cert_start += 5; + + /* Find separator after the end of the certificate. */ + cert_end = strstr(cert_start, "-----"); + if(cert_end == NULL) + return -1; + + sep_end = strstr(cert_end + 1, "-----"); + if(sep_end == NULL) + return -1; + sep_end += 5; + + len = cert_end - cert_start; + b64 = malloc(len + 1); + if(!b64) + return -1; + + /* Create base64 string without linefeeds. */ + for(i = 0, j = 0; i < len; i++) { + if(cert_start[i] != '\r' && cert_start[i] != '\n') + b64[j++] = cert_start[i]; + } + b64[j] = '\0'; + + err = Curl_base64_decode((const char *)b64, out, outlen); + free(b64); + if(err) { + free(*out); + return -1; + } + + return sep_end - in; +} + +static int read_cert(const char *file, unsigned char **out, size_t *outlen) +{ + int fd; + ssize_t n, len = 0, cap = 512; + unsigned char buf[512], *data; + + fd = open(file, 0); + if(fd < 0) + return -1; + + data = malloc(cap); + if(!data) { + close(fd); + return -1; + } + + for(;;) { + n = read(fd, buf, sizeof(buf)); + if(n < 0) { + close(fd); + free(data); + return -1; + } + else if(n == 0) { + close(fd); + break; + } + + if(len + n >= cap) { + cap *= 2; + data = Curl_saferealloc(data, cap); + if(!data) { + close(fd); + return -1; + } + } + + memcpy(data + len, buf, n); + len += n; + } + data[len] = '\0'; + + *out = data; + *outlen = len; + + return 0; +} + +static int append_cert_to_array(struct Curl_easy *data, + unsigned char *buf, size_t buflen, + CFMutableArrayRef array) +{ + CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen); + char *certp; + CURLcode result; + if(!certdata) { + failf(data, "SSL: failed to allocate array for CA certificate"); + return CURLE_OUT_OF_MEMORY; + } + + SecCertificateRef cacert = + SecCertificateCreateWithData(kCFAllocatorDefault, certdata); + CFRelease(certdata); + if(!cacert) { + failf(data, "SSL: failed to create SecCertificate from CA certificate"); + return CURLE_SSL_CACERT_BADFILE; + } + + /* Check if cacert is valid. */ + result = CopyCertSubject(data, cacert, &certp); + switch(result) { + case CURLE_OK: + break; + case CURLE_PEER_FAILED_VERIFICATION: + return CURLE_SSL_CACERT_BADFILE; + case CURLE_OUT_OF_MEMORY: + default: + return result; + } + free(certp); + + CFArrayAppendValue(array, cacert); + CFRelease(cacert); + + return CURLE_OK; +} + +static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, + SSLContextRef ctx) +{ + int n = 0, rc; + long res; + unsigned char *certbuf, *der; + size_t buflen, derlen, offset = 0; + + if(read_cert(cafile, &certbuf, &buflen) < 0) { + failf(data, "SSL: failed to read or invalid CA certificate"); + return CURLE_SSL_CACERT_BADFILE; + } + + /* + * Certbuf now contains the contents of the certificate file, which can be + * - a single DER certificate, + * - a single PEM certificate or + * - a bunch of PEM certificates (certificate bundle). + * + * Go through certbuf, and convert any PEM certificate in it into DER + * format. + */ + CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeArrayCallBacks); + if(array == NULL) { + free(certbuf); + failf(data, "SSL: out of memory creating CA certificate array"); + return CURLE_OUT_OF_MEMORY; + } + + while(offset < buflen) { + n++; + + /* + * Check if the certificate is in PEM format, and convert it to DER. If + * this fails, we assume the certificate is in DER format. + */ + res = pem_to_der((const char *)certbuf + offset, &der, &derlen); + if(res < 0) { + free(certbuf); + CFRelease(array); + failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle", + n, offset); + return CURLE_SSL_CACERT_BADFILE; + } + offset += res; + + if(res == 0 && offset == 0) { + /* This is not a PEM file, probably a certificate in DER format. */ + rc = append_cert_to_array(data, certbuf, buflen, array); + free(certbuf); + if(rc != CURLE_OK) { + CFRelease(array); + return rc; + } + break; + } + else if(res == 0) { + /* No more certificates in the bundle. */ + free(certbuf); + break; + } + + rc = append_cert_to_array(data, der, derlen, array); + free(der); + if(rc != CURLE_OK) { + free(certbuf); + CFRelease(array); + return rc; + } + } + + SecTrustRef trust; + OSStatus ret = SSLCopyPeerTrust(ctx, &trust); + if(trust == NULL) { + failf(data, "SSL: error getting certificate chain"); + CFRelease(array); + return CURLE_PEER_FAILED_VERIFICATION; + } + else if(ret != noErr) { + CFRelease(array); + failf(data, "SSLCopyPeerTrust() returned error %d", ret); + return CURLE_PEER_FAILED_VERIFICATION; + } + + ret = SecTrustSetAnchorCertificates(trust, array); + if(ret != noErr) { + CFRelease(array); + CFRelease(trust); + failf(data, "SecTrustSetAnchorCertificates() returned error %d", ret); + return CURLE_PEER_FAILED_VERIFICATION; + } + ret = SecTrustSetAnchorCertificatesOnly(trust, true); + if(ret != noErr) { + CFRelease(array); + CFRelease(trust); + failf(data, "SecTrustSetAnchorCertificatesOnly() returned error %d", ret); + return CURLE_PEER_FAILED_VERIFICATION; + } + + SecTrustResultType trust_eval = 0; + ret = SecTrustEvaluate(trust, &trust_eval); + CFRelease(array); + CFRelease(trust); + if(ret != noErr) { + failf(data, "SecTrustEvaluate() returned error %d", ret); + return CURLE_PEER_FAILED_VERIFICATION; + } + + switch(trust_eval) { + case kSecTrustResultUnspecified: + case kSecTrustResultProceed: + return CURLE_OK; + + case kSecTrustResultRecoverableTrustFailure: + case kSecTrustResultDeny: + default: + failf(data, "SSL: certificate verification failed (result: %d)", + trust_eval); + return CURLE_PEER_FAILED_VERIFICATION; + } +} + +#ifdef SECTRANSP_PINNEDPUBKEY +static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, + SSLContextRef ctx, + const char *pinnedpubkey) +{ /* Scratch */ + size_t pubkeylen, realpubkeylen, spkiHeaderLength = 24; + unsigned char *pubkey = NULL, *realpubkey = NULL; + const unsigned char *spkiHeader = NULL; + CFDataRef publicKeyBits = NULL; + + /* Result is returned to caller */ + CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + + /* if a path wasn't specified, don't pin */ + if(!pinnedpubkey) + return CURLE_OK; + + + if(!ctx) + return result; + + do { + SecTrustRef trust; + OSStatus ret = SSLCopyPeerTrust(ctx, &trust); + if(ret != noErr || trust == NULL) + break; + + SecKeyRef keyRef = SecTrustCopyPublicKey(trust); + CFRelease(trust); + if(keyRef == NULL) + break; + +#ifdef SECTRANSP_PINNEDPUBKEY_V1 + + publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL); + CFRelease(keyRef); + if(publicKeyBits == NULL) + break; + +#elif SECTRANSP_PINNEDPUBKEY_V2 + + OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL, + &publicKeyBits); + CFRelease(keyRef); + if(success != errSecSuccess || publicKeyBits == NULL) + break; + +#endif /* SECTRANSP_PINNEDPUBKEY_V2 */ + + pubkeylen = CFDataGetLength(publicKeyBits); + pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits); + + switch(pubkeylen) { + case 526: + /* 4096 bit RSA pubkeylen == 526 */ + spkiHeader = rsa4096SpkiHeader; + break; + case 270: + /* 2048 bit RSA pubkeylen == 270 */ + spkiHeader = rsa2048SpkiHeader; + break; +#ifdef SECTRANSP_PINNEDPUBKEY_V1 + case 65: + /* ecDSA secp256r1 pubkeylen == 65 */ + spkiHeader = ecDsaSecp256r1SpkiHeader; + spkiHeaderLength = 26; + break; + case 97: + /* ecDSA secp384r1 pubkeylen == 97 */ + spkiHeader = ecDsaSecp384r1SpkiHeader; + spkiHeaderLength = 23; + break; + default: + infof(data, "SSL: unhandled public key length: %d\n", pubkeylen); +#elif SECTRANSP_PINNEDPUBKEY_V2 + default: + /* ecDSA secp256r1 pubkeylen == 91 header already included? + * ecDSA secp384r1 header already included too + * we assume rest of algorithms do same, so do nothing + */ + result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey, + pubkeylen); +#endif /* SECTRANSP_PINNEDPUBKEY_V2 */ + continue; /* break from loop */ + } + + realpubkeylen = pubkeylen + spkiHeaderLength; + realpubkey = malloc(realpubkeylen); + if(!realpubkey) + break; + + memcpy(realpubkey, spkiHeader, spkiHeaderLength); + memcpy(realpubkey + spkiHeaderLength, pubkey, pubkeylen); + + result = Curl_pin_peer_pubkey(data, pinnedpubkey, realpubkey, + realpubkeylen); + + } while(0); + + Curl_safefree(realpubkey); + if(publicKeyBits != NULL) + CFRelease(publicKeyBits); + + return result; +} +#endif /* SECTRANSP_PINNEDPUBKEY */ + +static CURLcode +sectransp_connect_step2(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + OSStatus err; + SSLCipherSuite cipher; + SSLProtocol protocol = 0; + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + + DEBUGASSERT(ssl_connect_2 == connssl->connecting_state + || ssl_connect_2_reading == connssl->connecting_state + || ssl_connect_2_writing == connssl->connecting_state); + + /* Here goes nothing: */ + err = SSLHandshake(BACKEND->ssl_ctx); + + if(err != noErr) { + switch(err) { + case errSSLWouldBlock: /* they're not done with us yet */ + connssl->connecting_state = BACKEND->ssl_direction ? + ssl_connect_2_writing : ssl_connect_2_reading; + return CURLE_OK; + + /* The below is errSSLServerAuthCompleted; it's not defined in + Leopard's headers */ + case -9841: + if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { + CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data, + BACKEND->ssl_ctx); + if(result) + return result; + } + /* the documentation says we need to call SSLHandshake() again */ + return sectransp_connect_step2(conn, sockindex); + + /* Problem with encrypt / decrypt */ + case errSSLPeerDecodeError: + failf(data, "Decode failed"); + break; + case errSSLDecryptionFail: + case errSSLPeerDecryptionFail: + failf(data, "Decryption failed"); + break; + case errSSLPeerDecryptError: + failf(data, "A decryption error occurred"); + break; + case errSSLBadCipherSuite: + failf(data, "A bad SSL cipher suite was encountered"); + break; + case errSSLCrypto: + failf(data, "An underlying cryptographic error was encountered"); + break; +#if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9 + case errSSLWeakPeerEphemeralDHKey: + failf(data, "Indicates a weak ephemeral Diffie-Hellman key"); + break; +#endif + + /* Problem with the message record validation */ + case errSSLBadRecordMac: + case errSSLPeerBadRecordMac: + failf(data, "A record with a bad message authentication code (MAC) " + "was encountered"); + break; + case errSSLRecordOverflow: + case errSSLPeerRecordOverflow: + failf(data, "A record overflow occurred"); + break; + + /* Problem with zlib decompression */ + case errSSLPeerDecompressFail: + failf(data, "Decompression failed"); + break; + + /* Problem with access */ + case errSSLPeerAccessDenied: + failf(data, "Access was denied"); + break; + case errSSLPeerInsufficientSecurity: + failf(data, "There is insufficient security for this operation"); + break; + + /* These are all certificate problems with the server: */ + case errSSLXCertChainInvalid: + failf(data, "SSL certificate problem: Invalid certificate chain"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLUnknownRootCert: + failf(data, "SSL certificate problem: Untrusted root certificate"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLNoRootCert: + failf(data, "SSL certificate problem: No root certificate"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLCertNotYetValid: + failf(data, "SSL certificate problem: The certificate chain had a " + "certificate that is not yet valid"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLCertExpired: + case errSSLPeerCertExpired: + failf(data, "SSL certificate problem: Certificate chain had an " + "expired certificate"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLBadCert: + case errSSLPeerBadCert: + failf(data, "SSL certificate problem: Couldn't understand the server " + "certificate format"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLPeerUnsupportedCert: + failf(data, "SSL certificate problem: An unsupported certificate " + "format was encountered"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLPeerCertRevoked: + failf(data, "SSL certificate problem: The certificate was revoked"); + return CURLE_PEER_FAILED_VERIFICATION; + case errSSLPeerCertUnknown: + failf(data, "SSL certificate problem: The certificate is unknown"); + return CURLE_PEER_FAILED_VERIFICATION; + + /* These are all certificate problems with the client: */ + case errSecAuthFailed: + failf(data, "SSL authentication failed"); + break; + case errSSLPeerHandshakeFail: + failf(data, "SSL peer handshake failed, the server most likely " + "requires a client certificate to connect"); + break; + case errSSLPeerUnknownCA: + failf(data, "SSL server rejected the client certificate due to " + "the certificate being signed by an unknown certificate " + "authority"); + break; + + /* This error is raised if the server's cert didn't match the server's + host name: */ + case errSSLHostNameMismatch: + failf(data, "SSL certificate peer verification failed, the " + "certificate did not match \"%s\"\n", conn->host.dispname); + return CURLE_PEER_FAILED_VERIFICATION; + + /* Problem with SSL / TLS negotiation */ + case errSSLNegotiation: + failf(data, "Could not negotiate an SSL cipher suite with the server"); + break; + case errSSLBadConfiguration: + failf(data, "A configuration error occurred"); + break; + case errSSLProtocol: + failf(data, "SSL protocol error"); + break; + case errSSLPeerProtocolVersion: + failf(data, "A bad protocol version was encountered"); + break; + case errSSLPeerNoRenegotiation: + failf(data, "No renegotiation is allowed"); + break; + + /* Generic handshake errors: */ + case errSSLConnectionRefused: + failf(data, "Server dropped the connection during the SSL handshake"); + break; + case errSSLClosedAbort: + failf(data, "Server aborted the SSL handshake"); + break; + case errSSLClosedGraceful: + failf(data, "The connection closed gracefully"); + break; + case errSSLClosedNoNotify: + failf(data, "The server closed the session with no notification"); + break; + /* Sometimes paramErr happens with buggy ciphers: */ + case paramErr: + case errSSLInternal: + case errSSLPeerInternalError: + failf(data, "Internal SSL engine error encountered during the " + "SSL handshake"); + break; + case errSSLFatalAlert: + failf(data, "Fatal SSL engine error encountered during the SSL " + "handshake"); + break; + /* Unclassified error */ + case errSSLBufferOverflow: + failf(data, "An insufficient buffer was provided"); + break; + case errSSLIllegalParam: + failf(data, "An illegal parameter was encountered"); + break; + case errSSLModuleAttach: + failf(data, "Module attach failure"); + break; + case errSSLSessionNotFound: + failf(data, "An attempt to restore an unknown session failed"); + break; + case errSSLPeerExportRestriction: + failf(data, "An export restriction occurred"); + break; + case errSSLPeerUserCancelled: + failf(data, "The user canceled the operation"); + break; + case errSSLPeerUnexpectedMsg: + failf(data, "Peer rejected unexpected message"); + break; +#if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9 + /* Treaing non-fatal error as fatal like before */ + case errSSLClientHelloReceived: + failf(data, "A non-fatal result for providing a server name " + "indication"); + break; +#endif + + /* Error codes defined in the enum but should never be returned. + We list them here just in case. */ +#if CURL_BUILD_MAC_10_6 + /* Only returned when kSSLSessionOptionBreakOnCertRequested is set */ + case errSSLClientCertRequested: + failf(data, "The server has requested a client certificate"); + break; +#endif +#if CURL_BUILD_MAC_10_9 + /* Alias for errSSLLast, end of error range */ + case errSSLUnexpectedRecord: + failf(data, "Unexpected (skipped) record in DTLS"); + break; +#endif + default: + /* May also return codes listed in Security Framework Result Codes */ + failf(data, "Unknown SSL protocol error in connection to %s:%d", + hostname, err); + break; + } + return CURLE_SSL_CONNECT_ERROR; + } + else { + /* we have been connected fine, we're not waiting for anything else. */ + connssl->connecting_state = ssl_connect_3; + +#ifdef SECTRANSP_PINNEDPUBKEY + if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) { + CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx, + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + return result; + } + } +#endif /* SECTRANSP_PINNEDPUBKEY */ + + /* Informational message */ + (void)SSLGetNegotiatedCipher(BACKEND->ssl_ctx, &cipher); + (void)SSLGetNegotiatedProtocolVersion(BACKEND->ssl_ctx, &protocol); + switch(protocol) { + case kSSLProtocol2: + infof(data, "SSL 2.0 connection using %s\n", + SSLCipherNameForNumber(cipher)); + break; + case kSSLProtocol3: + infof(data, "SSL 3.0 connection using %s\n", + SSLCipherNameForNumber(cipher)); + break; + case kTLSProtocol1: + infof(data, "TLS 1.0 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + case kTLSProtocol11: + infof(data, "TLS 1.1 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; + case kTLSProtocol12: + infof(data, "TLS 1.2 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ +#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 + case kTLSProtocol13: + infof(data, "TLS 1.3 connection using %s\n", + TLSCipherNameForNumber(cipher)); + break; +#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */ + default: + infof(data, "Unknown protocol connection\n"); + break; + } + +#if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 + if(conn->bits.tls_enable_alpn) { + if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) { + CFArrayRef alpnArr = NULL; + CFStringRef chosenProtocol = NULL; + err = SSLCopyALPNProtocols(BACKEND->ssl_ctx, &alpnArr); + + if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1) + chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0); + +#ifdef USE_NGHTTP2 + if(chosenProtocol && + !CFStringCompare(chosenProtocol, CFSTR(NGHTTP2_PROTO_VERSION_ID), + 0)) { + conn->negnpn = CURL_HTTP_VERSION_2; + } + else +#endif + if(chosenProtocol && + !CFStringCompare(chosenProtocol, CFSTR(ALPN_HTTP_1_1), 0)) { + conn->negnpn = CURL_HTTP_VERSION_1_1; + } + else + infof(data, "ALPN, server did not agree to a protocol\n"); + + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + + /* chosenProtocol is a reference to the string within alpnArr + and doesn't need to be freed separately */ + if(alpnArr) + CFRelease(alpnArr); + } + } +#endif + + return CURLE_OK; + } +} + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +/* This should be called during step3 of the connection at the earliest */ +static void +show_verbose_server_cert(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + CFArrayRef server_certs = NULL; + SecCertificateRef server_cert; + OSStatus err; + CFIndex i, count; + SecTrustRef trust = NULL; + + if(!BACKEND->ssl_ctx) + return; + +#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS +#if CURL_BUILD_IOS +#pragma unused(server_certs) + err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust); + /* For some reason, SSLCopyPeerTrust() can return noErr and yet return + a null trust, so be on guard for that: */ + if(err == noErr && trust) { + count = SecTrustGetCertificateCount(trust); + for(i = 0L ; i < count ; i++) { + CURLcode result; + char *certp; + server_cert = SecTrustGetCertificateAtIndex(trust, i); + result = CopyCertSubject(data, server_cert, &certp); + if(!result) { + infof(data, "Server certificate: %s\n", certp); + free(certp); + } + } + CFRelease(trust); + } +#else + /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion. + The function SecTrustGetCertificateAtIndex() is officially present + in Lion, but it is unfortunately also present in Snow Leopard as + private API and doesn't work as expected. So we have to look for + a different symbol to make sure this code is only executed under + Lion or later. */ + if(SecTrustEvaluateAsync != NULL) { +#pragma unused(server_certs) + err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust); + /* For some reason, SSLCopyPeerTrust() can return noErr and yet return + a null trust, so be on guard for that: */ + if(err == noErr && trust) { + count = SecTrustGetCertificateCount(trust); + for(i = 0L ; i < count ; i++) { + char *certp; + CURLcode result; + server_cert = SecTrustGetCertificateAtIndex(trust, i); + result = CopyCertSubject(data, server_cert, &certp); + if(!result) { + infof(data, "Server certificate: %s\n", certp); + free(certp); + } + } + CFRelease(trust); + } + } + else { +#if CURL_SUPPORT_MAC_10_8 + err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs); + /* Just in case SSLCopyPeerCertificates() returns null too... */ + if(err == noErr && server_certs) { + count = CFArrayGetCount(server_certs); + for(i = 0L ; i < count ; i++) { + char *certp; + CURLcode result; + server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, + i); + result = CopyCertSubject(data, server_cert, &certp); + if(!result) { + infof(data, "Server certificate: %s\n", certp); + free(certp); + } + } + CFRelease(server_certs); + } +#endif /* CURL_SUPPORT_MAC_10_8 */ + } +#endif /* CURL_BUILD_IOS */ +#else +#pragma unused(trust) + err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs); + if(err == noErr) { + count = CFArrayGetCount(server_certs); + for(i = 0L ; i < count ; i++) { + CURLcode result; + char *certp; + server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i); + result = CopyCertSubject(data, server_cert, &certp); + if(!result) { + infof(data, "Server certificate: %s\n", certp); + free(certp); + } + } + CFRelease(server_certs); + } +#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ +} +#endif /* !CURL_DISABLE_VERBOSE_STRINGS */ + +static CURLcode +sectransp_connect_step3(struct connectdata *conn, + int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + /* There is no step 3! + * Well, okay, if verbose mode is on, let's print the details of the + * server certificates. */ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(data->set.verbose) + show_verbose_server_cert(conn, sockindex); +#endif + + connssl->connecting_state = ssl_connect_done; + return CURLE_OK; +} + +static Curl_recv sectransp_recv; +static Curl_send sectransp_send; + +static CURLcode +sectransp_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + long timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + /* Find out how much more time we're allowed */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + result = sectransp_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading || + connssl->connecting_state == ssl_connect_2_writing) { + + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking?0:timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if this + * connection is done nonblocking and this loop would execute again. This + * permits the owner of a multi handle to abort a connection attempt + * before step2 has completed while ensuring that a client using select() + * or epoll() will always have a valid fdset to wait on. + */ + result = sectransp_connect_step2(conn, sockindex); + if(result || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return result; + + } /* repeat step2 until all transactions are done. */ + + + if(ssl_connect_3 == connssl->connecting_state) { + result = sectransp_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = sectransp_recv; + conn->send[sockindex] = sectransp_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +static CURLcode Curl_sectransp_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + return sectransp_connect_common(conn, sockindex, TRUE, done); +} + +static CURLcode Curl_sectransp_connect(struct connectdata *conn, int sockindex) +{ + CURLcode result; + bool done = FALSE; + + result = sectransp_connect_common(conn, sockindex, FALSE, &done); + + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +static void Curl_sectransp_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + if(BACKEND->ssl_ctx) { + (void)SSLClose(BACKEND->ssl_ctx); +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + if(SSLCreateContext != NULL) + CFRelease(BACKEND->ssl_ctx); +#if CURL_SUPPORT_MAC_10_8 + else + (void)SSLDisposeContext(BACKEND->ssl_ctx); +#endif /* CURL_SUPPORT_MAC_10_8 */ +#else + (void)SSLDisposeContext(BACKEND->ssl_ctx); +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + BACKEND->ssl_ctx = NULL; + } + BACKEND->ssl_sockfd = 0; +} + +static int Curl_sectransp_shutdown(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct Curl_easy *data = conn->data; + ssize_t nread; + int what; + int rc; + char buf[120]; + + if(!BACKEND->ssl_ctx) + return 0; + +#ifndef CURL_DISABLE_FTP + if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE) + return 0; +#endif + + Curl_sectransp_close(conn, sockindex); + + rc = 0; + + what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT); + + for(;;) { + if(what < 0) { + /* anything that gets here is fatally bad */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + rc = -1; + break; + } + + if(!what) { /* timeout */ + failf(data, "SSL shutdown timeout"); + break; + } + + /* Something to read, let's do it and hope that it is the close + notify alert from the server. No way to SSL_Read now, so use read(). */ + + nread = read(conn->sock[sockindex], buf, sizeof(buf)); + + if(nread < 0) { + failf(data, "read: %s", strerror(errno)); + rc = -1; + } + + if(nread <= 0) + break; + + what = SOCKET_READABLE(conn->sock[sockindex], 0); + } + + return rc; +} + +static void Curl_sectransp_session_free(void *ptr) +{ + /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a + cached session ID inside the Security framework. There is a private + function that does this, but I don't want to have to explain to you why I + got your application rejected from the App Store due to the use of a + private API, so the best we can do is free up our own char array that we + created way back in sectransp_connect_step1... */ + Curl_safefree(ptr); +} + +static size_t Curl_sectransp_version(char *buffer, size_t size) +{ + return msnprintf(buffer, size, "SecureTransport"); +} + +/* + * This function uses SSLGetSessionState to determine connection status. + * + * Return codes: + * 1 means the connection is still in place + * 0 means the connection has been closed + * -1 means the connection status is unknown + */ +static int Curl_sectransp_check_cxn(struct connectdata *conn) +{ + struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; + OSStatus err; + SSLSessionState state; + + if(BACKEND->ssl_ctx) { + err = SSLGetSessionState(BACKEND->ssl_ctx, &state); + if(err == noErr) + return state == kSSLConnected || state == kSSLHandshake; + return -1; + } + return 0; +} + +static bool Curl_sectransp_data_pending(const struct connectdata *conn, + int connindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[connindex]; + OSStatus err; + size_t buffer; + + if(BACKEND->ssl_ctx) { /* SSL is in use */ + err = SSLGetBufferedReadSize(BACKEND->ssl_ctx, &buffer); + if(err == noErr) + return buffer > 0UL; + return false; + } + else + return false; +} + +static CURLcode Curl_sectransp_random(struct Curl_easy *data UNUSED_PARAM, + unsigned char *entropy, size_t length) +{ + /* arc4random_buf() isn't available on cats older than Lion, so let's + do this manually for the benefit of the older cats. */ + size_t i; + u_int32_t random_number = 0; + + (void)data; + + for(i = 0 ; i < length ; i++) { + if(i % sizeof(u_int32_t) == 0) + random_number = arc4random(); + entropy[i] = random_number & 0xFF; + random_number >>= 8; + } + i = random_number = 0; + return CURLE_OK; +} + +static CURLcode Curl_sectransp_md5sum(unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *md5sum, /* output */ + size_t md5len) +{ + (void)md5len; + (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum); + return CURLE_OK; +} + +static CURLcode Curl_sectransp_sha256sum(const unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *sha256sum, /* output */ + size_t sha256len) +{ + assert(sha256len >= CURL_SHA256_DIGEST_LENGTH); + (void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum); + return CURLE_OK; +} + +static bool Curl_sectransp_false_start(void) +{ +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + if(SSLSetSessionOption != NULL) + return TRUE; +#endif + return FALSE; +} + +static ssize_t sectransp_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) +{ + /*struct Curl_easy *data = conn->data;*/ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + size_t processed = 0UL; + OSStatus err; + + /* The SSLWrite() function works a little differently than expected. The + fourth argument (processed) is currently documented in Apple's + documentation as: "On return, the length, in bytes, of the data actually + written." + + Now, one could interpret that as "written to the socket," but actually, + it returns the amount of data that was written to a buffer internal to + the SSLContextRef instead. So it's possible for SSLWrite() to return + errSSLWouldBlock and a number of bytes "written" because those bytes were + encrypted and written to a buffer, not to the socket. + + So if this happens, then we need to keep calling SSLWrite() over and + over again with no new data until it quits returning errSSLWouldBlock. */ + + /* Do we have buffered data to write from the last time we were called? */ + if(BACKEND->ssl_write_buffered_length) { + /* Write the buffered data: */ + err = SSLWrite(BACKEND->ssl_ctx, NULL, 0UL, &processed); + switch(err) { + case noErr: + /* processed is always going to be 0 because we didn't write to + the buffer, so return how much was written to the socket */ + processed = BACKEND->ssl_write_buffered_length; + BACKEND->ssl_write_buffered_length = 0UL; + break; + case errSSLWouldBlock: /* argh, try again */ + *curlcode = CURLE_AGAIN; + return -1L; + default: + failf(conn->data, "SSLWrite() returned error %d", err); + *curlcode = CURLE_SEND_ERROR; + return -1L; + } + } + else { + /* We've got new data to write: */ + err = SSLWrite(BACKEND->ssl_ctx, mem, len, &processed); + if(err != noErr) { + switch(err) { + case errSSLWouldBlock: + /* Data was buffered but not sent, we have to tell the caller + to try sending again, and remember how much was buffered */ + BACKEND->ssl_write_buffered_length = len; + *curlcode = CURLE_AGAIN; + return -1L; + default: + failf(conn->data, "SSLWrite() returned error %d", err); + *curlcode = CURLE_SEND_ERROR; + return -1L; + } + } + } + return (ssize_t)processed; +} + +static ssize_t sectransp_recv(struct connectdata *conn, + int num, + char *buf, + size_t buffersize, + CURLcode *curlcode) +{ + /*struct Curl_easy *data = conn->data;*/ + struct ssl_connect_data *connssl = &conn->ssl[num]; + size_t processed = 0UL; + OSStatus err; + + again: + err = SSLRead(BACKEND->ssl_ctx, buf, buffersize, &processed); + + if(err != noErr) { + switch(err) { + case errSSLWouldBlock: /* return how much we read (if anything) */ + if(processed) + return (ssize_t)processed; + *curlcode = CURLE_AGAIN; + return -1L; + break; + + /* errSSLClosedGraceful - server gracefully shut down the SSL session + errSSLClosedNoNotify - server hung up on us instead of sending a + closure alert notice, read() is returning 0 + Either way, inform the caller that the server disconnected. */ + case errSSLClosedGraceful: + case errSSLClosedNoNotify: + *curlcode = CURLE_OK; + return -1L; + break; + + /* The below is errSSLPeerAuthCompleted; it's not defined in + Leopard's headers */ + case -9841: + if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { + CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), conn->data, + BACKEND->ssl_ctx); + if(result) + return result; + } + goto again; + default: + failf(conn->data, "SSLRead() return error %d", err); + *curlcode = CURLE_RECV_ERROR; + return -1L; + break; + } + } + return (ssize_t)processed; +} + +static void *Curl_sectransp_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + (void)info; + return BACKEND->ssl_ctx; +} + +const struct Curl_ssl Curl_ssl_sectransp = { + { CURLSSLBACKEND_SECURETRANSPORT, "secure-transport" }, /* info */ + +#ifdef SECTRANSP_PINNEDPUBKEY + SSLSUPP_PINNEDPUBKEY, +#else + 0, +#endif /* SECTRANSP_PINNEDPUBKEY */ + + sizeof(struct ssl_backend_data), + + Curl_none_init, /* init */ + Curl_none_cleanup, /* cleanup */ + Curl_sectransp_version, /* version */ + Curl_sectransp_check_cxn, /* check_cxn */ + Curl_sectransp_shutdown, /* shutdown */ + Curl_sectransp_data_pending, /* data_pending */ + Curl_sectransp_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_sectransp_connect, /* connect */ + Curl_sectransp_connect_nonblocking, /* connect_nonblocking */ + Curl_sectransp_get_internals, /* get_internals */ + Curl_sectransp_close, /* close_one */ + Curl_none_close_all, /* close_all */ + Curl_sectransp_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_sectransp_false_start, /* false_start */ + Curl_sectransp_md5sum, /* md5sum */ + Curl_sectransp_sha256sum /* sha256sum */ +}; + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif /* USE_SECTRANSP */ diff --git a/libcurl/lib/vtls/sectransp.h b/libcurl/lib/vtls/sectransp.h new file mode 100644 index 0000000..5cec797 --- /dev/null +++ b/libcurl/lib/vtls/sectransp.h @@ -0,0 +1,32 @@ +#ifndef HEADER_CURL_SECTRANSP_H +#define HEADER_CURL_SECTRANSP_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2014, Nick Zitzmann, . + * Copyright (C) 2012 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_SECTRANSP + +extern const struct Curl_ssl Curl_ssl_sectransp; + +#endif /* USE_SECTRANSP */ +#endif /* HEADER_CURL_SECTRANSP_H */ diff --git a/libcurl/lib/vtls/session_cache.cpp b/libcurl/lib/vtls/session_cache.cpp new file mode 100644 index 0000000..87a0934 --- /dev/null +++ b/libcurl/lib/vtls/session_cache.cpp @@ -0,0 +1,155 @@ +#include "session_cache.h" +#include "ssl_debug.h" + +#include +#include + +// KeQuerySystemTime is exported by the Xbox kernel (xboxkrnl.lib) +#ifdef __cplusplus +extern "C" +#endif +void WINAPI KeQuerySystemTime(PLARGE_INTEGER CurrentTime); + +session_cache::session_entry session_cache::entries[SESSION_CACHE_SIZE]; +bool session_cache::initialized = false; + +void session_cache::initialize() +{ + if (initialized) return; + + memset(entries, 0, sizeof(entries)); + initialized = true; + ssl_debug::log_verbose("Session cache initialized (%d slots)\n", SESSION_CACHE_SIZE); +} + +void session_cache::shutdown() +{ + clear(); + initialized = false; +} + +uint32_t session_cache::get_current_time() +{ + LARGE_INTEGER system_time; + KeQuerySystemTime(&system_time); + // Convert 100-nanosecond intervals to seconds + return (uint32_t)(system_time.QuadPart / 10000000ULL); +} + +int session_cache::find_entry(const char* hostname) +{ + for (int i = 0; i < SESSION_CACHE_SIZE; i++) { + if (entries[i].valid && strcmp(entries[i].hostname, hostname) == 0) { + return i; + } + } + return -1; +} + +int session_cache::find_free_slot() +{ + uint32_t current_time = get_current_time(); + int oldest_idx = -1; + uint32_t oldest_time = 0xFFFFFFFF; + + for (int i = 0; i < SESSION_CACHE_SIZE; i++) { + // Free slot + if (!entries[i].valid) { + return i; + } + + // Expired entry - reuse it (guard against RTC going backwards) + if (current_time >= entries[i].timestamp + && current_time - entries[i].timestamp > SESSION_MAX_AGE_SECONDS) { + entries[i].valid = false; + return i; + } + + // Track oldest for LRU eviction + if (entries[i].timestamp < oldest_time) { + oldest_time = entries[i].timestamp; + oldest_idx = i; + } + } + + // Evict oldest entry + if (oldest_idx >= 0) { + ssl_debug::log_verbose("Session cache: evicting entry for %s\n", entries[oldest_idx].hostname); + entries[oldest_idx].valid = false; + return oldest_idx; + } + + return 0; // Fallback to first slot +} + +bool session_cache::get(const char* hostname, br_ssl_session_parameters* params) +{ + if (!initialized) initialize(); + + int idx = find_entry(hostname); + if (idx < 0) { + ssl_debug::log_verbose("Session cache: miss for %s\n", hostname); + return false; + } + + uint32_t current_time = get_current_time(); + if (current_time >= entries[idx].timestamp + && current_time - entries[idx].timestamp > SESSION_MAX_AGE_SECONDS) { + ssl_debug::log_verbose("Session cache: expired entry for %s\n", hostname); + entries[idx].valid = false; + return false; + } + + /* Update timestamp on access for proper LRU eviction */ + entries[idx].timestamp = current_time; + memcpy(params, &entries[idx].params, sizeof(br_ssl_session_parameters)); + ssl_debug::log_info("Session cache: hit for %s\n", hostname); + return true; +} + +void session_cache::store(const char* hostname, const br_ssl_session_parameters* params) +{ + if (!initialized) initialize(); + + // Don't cache if no session ID and no session ticket + if (params->session_id_len == 0 && params->session_ticket_len == 0) { + return; + } + + int idx = find_entry(hostname); + if (idx < 0) { + idx = find_free_slot(); + } + + strncpy(entries[idx].hostname, hostname, 255); + entries[idx].hostname[255] = '\0'; + memcpy(&entries[idx].params, params, sizeof(br_ssl_session_parameters)); + entries[idx].timestamp = get_current_time(); + entries[idx].valid = true; + + ssl_debug::log_info("Session cache: stored session for %s\n", hostname); +} + +void session_cache::remove(const char* hostname) +{ + int idx = find_entry(hostname); + if (idx >= 0) { + entries[idx].valid = false; + ssl_debug::log_verbose("Session cache: removed entry for %s\n", hostname); + } +} + +void session_cache::clear() +{ + memset(entries, 0, sizeof(entries)); + ssl_debug::log_verbose("Session cache: cleared\n"); +} + +int session_cache::get_count() +{ + int count = 0; + for (int i = 0; i < SESSION_CACHE_SIZE; i++) { + if (entries[i].valid) count++; + } + return count; +} diff --git a/libcurl/lib/vtls/session_cache.h b/libcurl/lib/vtls/session_cache.h new file mode 100644 index 0000000..3411892 --- /dev/null +++ b/libcurl/lib/vtls/session_cache.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +#define SESSION_CACHE_SIZE 8 +#define SESSION_MAX_AGE_SECONDS 3600 + +class session_cache +{ +public: + static void initialize(); + static void shutdown(); + + static bool get(const char* hostname, br_ssl_session_parameters* params); + static void store(const char* hostname, const br_ssl_session_parameters* params); + static void remove(const char* hostname); + static void clear(); + + static int get_count(); + +private: + struct session_entry { + char hostname[256]; + br_ssl_session_parameters params; + uint32_t timestamp; + bool valid; + }; + + static session_entry entries[SESSION_CACHE_SIZE]; + static bool initialized; + + static int find_entry(const char* hostname); + static int find_free_slot(); + static uint32_t get_current_time(); +}; diff --git a/libcurl/lib/vtls/ssl_debug.cpp b/libcurl/lib/vtls/ssl_debug.cpp new file mode 100644 index 0000000..569437d --- /dev/null +++ b/libcurl/lib/vtls/ssl_debug.cpp @@ -0,0 +1,147 @@ +#include "ssl_debug.h" +#include "ssl_errors.h" +#include "debug_utility.h" + +#include +#include +#include + +ssl_debug_level ssl_debug::current_level = SSL_DEBUG_ERROR; + +void ssl_debug::set_level(ssl_debug_level level) +{ + current_level = level; +} + +ssl_debug_level ssl_debug::get_level() +{ + return current_level; +} + +void ssl_debug::log_error(const char* format, ...) +{ + if (current_level < SSL_DEBUG_ERROR) return; + + debug_utility::debug_print("[SSL ERROR] "); + va_list args; + va_start(args, format); + char buffer[256]; + _vsnprintf(buffer, sizeof(buffer) - 1, format, args); + buffer[sizeof(buffer) - 1] = '\0'; + va_end(args); + debug_utility::debug_print("%s", buffer); +} + +void ssl_debug::log_info(const char* format, ...) +{ + if (current_level < SSL_DEBUG_INFO) return; + + debug_utility::debug_print("[SSL] "); + va_list args; + va_start(args, format); + char buffer[256]; + _vsnprintf(buffer, sizeof(buffer) - 1, format, args); + buffer[sizeof(buffer) - 1] = '\0'; + va_end(args); + debug_utility::debug_print("%s", buffer); +} + +void ssl_debug::log_verbose(const char* format, ...) +{ + if (current_level < SSL_DEBUG_VERBOSE) return; + + debug_utility::debug_print("[SSL DEBUG] "); + va_list args; + va_start(args, format); + char buffer[256]; + _vsnprintf(buffer, sizeof(buffer) - 1, format, args); + buffer[sizeof(buffer) - 1] = '\0'; + va_end(args); + debug_utility::debug_print("%s", buffer); +} + +const char* ssl_debug::version_to_string(unsigned version) +{ + switch (version) { + case BR_TLS10: return "TLS 1.0"; + case BR_TLS11: return "TLS 1.1"; + case BR_TLS12: return "TLS 1.2"; + default: return "Unknown"; + } +} + +const char* ssl_debug::cipher_suite_to_string(uint16_t suite) +{ + switch (suite) { + case BR_TLS_RSA_WITH_AES_128_CBC_SHA: + return "RSA-AES128-CBC-SHA"; + case BR_TLS_RSA_WITH_AES_256_CBC_SHA: + return "RSA-AES256-CBC-SHA"; + case BR_TLS_RSA_WITH_AES_128_CBC_SHA256: + return "RSA-AES128-CBC-SHA256"; + case BR_TLS_RSA_WITH_AES_256_CBC_SHA256: + return "RSA-AES256-CBC-SHA256"; + case BR_TLS_RSA_WITH_AES_128_GCM_SHA256: + return "RSA-AES128-GCM-SHA256"; + case BR_TLS_RSA_WITH_AES_256_GCM_SHA384: + return "RSA-AES256-GCM-SHA384"; + case BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + return "ECDHE-RSA-AES128-CBC-SHA"; + case BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + return "ECDHE-RSA-AES256-CBC-SHA"; + case BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + return "ECDHE-RSA-AES128-CBC-SHA256"; + case BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: + return "ECDHE-RSA-AES256-CBC-SHA384"; + case BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + return "ECDHE-RSA-AES128-GCM-SHA256"; + case BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + return "ECDHE-RSA-AES256-GCM-SHA384"; + case BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + return "ECDHE-RSA-CHACHA20-POLY1305"; + case BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + return "ECDHE-ECDSA-AES128-GCM-SHA256"; + case BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + return "ECDHE-ECDSA-AES256-GCM-SHA384"; + case BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + return "ECDHE-ECDSA-CHACHA20-POLY1305"; + default: + return "Unknown"; + } +} + +void ssl_debug::log_handshake_result(br_ssl_engine_context* engine) +{ + if (current_level < SSL_DEBUG_INFO) return; + + unsigned version = br_ssl_engine_get_version(engine); + log_info("Handshake complete\n"); + log_info(" Version: %s\n", version_to_string(version)); + + br_ssl_session_parameters params; + br_ssl_engine_get_session_parameters(engine, ¶ms); + log_info(" Cipher: %s\n", cipher_suite_to_string(params.cipher_suite)); + log_info(" Session resumed: %s\n", params.session_id_len > 0 ? "yes" : "no"); +} + +void ssl_debug::log_ssl_error(int error) +{ + if (error == 0) return; + + log_error("SSL error %d: %s\n", error, ssl_errors::error_to_string(error)); + + if (error >= 256 && error < 512) { + int alert = error - 256; + log_error(" Alert: %s\n", ssl_errors::alert_to_string(alert)); + } +} + +void ssl_debug::log_peer_certificate(br_ssl_engine_context* engine) +{ + // Note: BearSSL does not provide a direct API to retrieve the peer certificate + // chain after handshake completion. Certificate inspection would require + // custom X.509 callbacks during validation. This function is a placeholder. + if (current_level < SSL_DEBUG_VERBOSE) return; + log_verbose("Certificate inspection not available (requires X.509 callback)\n"); + (void)engine; // Suppress unused parameter warning +} diff --git a/libcurl/lib/vtls/ssl_debug.h b/libcurl/lib/vtls/ssl_debug.h new file mode 100644 index 0000000..a3541ac --- /dev/null +++ b/libcurl/lib/vtls/ssl_debug.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +enum ssl_debug_level { + SSL_DEBUG_NONE = 0, + SSL_DEBUG_ERROR = 1, + SSL_DEBUG_INFO = 2, + SSL_DEBUG_VERBOSE = 3 +}; + +class ssl_debug +{ +public: + static void set_level(ssl_debug_level level); + static ssl_debug_level get_level(); + + static void log_error(const char* format, ...); + static void log_info(const char* format, ...); + static void log_verbose(const char* format, ...); + + static void log_handshake_result(br_ssl_engine_context* engine); + static void log_ssl_error(int error); + static void log_peer_certificate(br_ssl_engine_context* engine); + + static const char* version_to_string(unsigned version); + static const char* cipher_suite_to_string(uint16_t suite); + +private: + static ssl_debug_level current_level; +}; diff --git a/libcurl/lib/vtls/ssl_errors.cpp b/libcurl/lib/vtls/ssl_errors.cpp new file mode 100644 index 0000000..a72a52c --- /dev/null +++ b/libcurl/lib/vtls/ssl_errors.cpp @@ -0,0 +1,73 @@ +#include "ssl_errors.h" +#include + +const char* ssl_errors::error_to_string(int error) +{ + switch (error) { + case BR_ERR_OK: return "Success"; + case BR_ERR_BAD_PARAM: return "Bad parameter"; + case BR_ERR_BAD_STATE: return "Invalid state"; + case BR_ERR_UNSUPPORTED_VERSION: return "Unsupported TLS version"; + case BR_ERR_BAD_VERSION: return "Bad TLS version"; + case BR_ERR_TOO_LARGE: return "Record too large"; + case BR_ERR_BAD_MAC: return "MAC verification failed"; + case BR_ERR_NO_RANDOM: return "No random seed"; + case BR_ERR_UNKNOWN_TYPE: return "Unknown record type"; + case BR_ERR_UNEXPECTED: return "Unexpected message"; + case BR_ERR_BAD_CCS: return "Bad ChangeCipherSpec"; + case BR_ERR_BAD_ALERT: return "Bad alert"; + case BR_ERR_BAD_HANDSHAKE: return "Bad handshake message"; + case BR_ERR_OVERSIZED_ID: return "Oversized ID"; + case BR_ERR_BAD_CIPHER_SUITE: return "Bad cipher suite"; + case BR_ERR_BAD_COMPRESSION: return "Bad compression"; + case BR_ERR_BAD_FRAGLEN: return "Bad fragment length"; + case BR_ERR_BAD_SECRENEG: return "Bad secure renegotiation"; + case BR_ERR_EXTRA_EXTENSION: return "Extra extension"; + case BR_ERR_BAD_SNI: return "Bad SNI"; + case BR_ERR_BAD_HELLO_DONE: return "Bad HelloDone"; + case BR_ERR_LIMIT_EXCEEDED: return "Limit exceeded"; + case BR_ERR_BAD_FINISHED: return "Bad Finished message"; + case BR_ERR_RESUME_MISMATCH: return "Session resume mismatch"; + case BR_ERR_INVALID_ALGORITHM: return "Invalid algorithm"; + case BR_ERR_BAD_SIGNATURE: return "Bad signature"; + case BR_ERR_WRONG_KEY_USAGE: return "Wrong key usage"; + case BR_ERR_NO_CLIENT_AUTH: return "No client auth"; + case BR_ERR_IO: return "I/O error"; + default: + if (error >= 256 && error < 512) + return "Received fatal alert from server"; + if (error >= 512) + return "Sent fatal alert to server"; + return "Unknown SSL error"; + } +} + +const char* ssl_errors::alert_to_string(int alert_code) +{ + switch (alert_code) { + case 0: return "close_notify"; + case 10: return "unexpected_message"; + case 20: return "bad_record_mac"; + case 21: return "decryption_failed"; + case 22: return "record_overflow"; + case 30: return "decompression_failure"; + case 40: return "handshake_failure"; + case 42: return "bad_certificate"; + case 43: return "unsupported_certificate"; + case 44: return "certificate_revoked"; + case 45: return "certificate_expired"; + case 46: return "certificate_unknown"; + case 47: return "illegal_parameter"; + case 48: return "unknown_ca"; + case 49: return "access_denied"; + case 50: return "decode_error"; + case 51: return "decrypt_error"; + case 70: return "protocol_version"; + case 71: return "insufficient_security"; + case 80: return "internal_error"; + case 90: return "user_canceled"; + case 100: return "no_renegotiation"; + case 110: return "unsupported_extension"; + default: return "unknown_alert"; + } +} diff --git a/libcurl/lib/vtls/ssl_errors.h b/libcurl/lib/vtls/ssl_errors.h new file mode 100644 index 0000000..d764b85 --- /dev/null +++ b/libcurl/lib/vtls/ssl_errors.h @@ -0,0 +1,8 @@ +#pragma once + +class ssl_errors +{ +public: + static const char* error_to_string(int error); + static const char* alert_to_string(int alert_code); +}; diff --git a/libcurl/lib/vtls/ssl_hs_client.c b/libcurl/lib/vtls/ssl_hs_client.c new file mode 100644 index 0000000..3fc96d0 --- /dev/null +++ b/libcurl/lib/vtls/ssl_hs_client.c @@ -0,0 +1,1967 @@ +/* Automatically generated code; do not modify directly. */ + +#include +#include + +typedef struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; +} t0_context; + +static uint32_t +t0_parse7E_unsigned(const unsigned char **p) +{ + uint32_t x; + + x = 0; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + return x; + } + } +} + +static int32_t +t0_parse7E_signed(const unsigned char **p) +{ + int neg; + uint32_t x; + + neg = ((**p) >> 6) & 1; + x = (uint32_t)-neg; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + if (neg) { + return -(int32_t)~x - 1; + } else { + return (int32_t)x; + } + } + } +} + +#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) +#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) +#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) +#define T0_INT1(x) T0_FBYTE(x, 0) +#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) + +/* static const unsigned char t0_datablock[]; */ + + +void br_ssl_hs_client_init_main(void *t0ctx); + +void br_ssl_hs_client_run(void *t0ctx); + + + +#include +#include + +#include "inner.h" + +/* + * This macro evaluates to a pointer to the current engine context. + */ +#define ENG ((br_ssl_engine_context *)(void *)((unsigned char *)t0ctx - offsetof(br_ssl_engine_context, cpu))) + + + + + +/* + * This macro evaluates to a pointer to the client context, under that + * specific name. It must be noted that since the engine context is the + * first field of the br_ssl_client_context structure ('eng'), then + * pointers values of both types are interchangeable, modulo an + * appropriate cast. This also means that "addresses" computed as offsets + * within the structure work for both kinds of context. + */ +#define CTX ((br_ssl_client_context *)ENG) + +/* + * Generate the pre-master secret for RSA key exchange, and encrypt it + * with the server's public key. Returned value is either the encrypted + * data length (in bytes), or -x on error, with 'x' being an error code. + * + * This code assumes that the public key has been already verified (it + * was properly obtained by the X.509 engine, and it has the right type, + * i.e. it is of type RSA and suitable for encryption). + */ +static int +make_pms_rsa(br_ssl_client_context *ctx, int prf_id) +{ + const br_x509_class **xc; + const br_x509_pkey *pk; + const unsigned char *n; + unsigned char *pms; + size_t nlen, u; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + + /* + * Compute actual RSA key length, in case there are leading zeros. + */ + n = pk->key.rsa.n; + nlen = pk->key.rsa.nlen; + while (nlen > 0 && *n == 0) { + n ++; + nlen --; + } + + /* + * We need at least 59 bytes (48 bytes for pre-master secret, and + * 11 bytes for the PKCS#1 type 2 padding). Note that the X.509 + * minimal engine normally blocks RSA keys shorter than 128 bytes, + * so this is mostly for public keys provided explicitly by the + * caller. + */ + if (nlen < 59) { + return -BR_ERR_X509_WEAK_PUBLIC_KEY; + } + if (nlen > sizeof ctx->eng.pad) { + return -BR_ERR_LIMIT_EXCEEDED; + } + + /* + * Make PMS. + */ + pms = ctx->eng.pad + nlen - 48; + br_enc16be(pms, ctx->eng.version_max); + br_hmac_drbg_generate(&ctx->eng.rng, pms + 2, 46); + br_ssl_engine_compute_master(&ctx->eng, prf_id, pms, 48); + + /* + * Apply PKCS#1 type 2 padding. + */ + ctx->eng.pad[0] = 0x00; + ctx->eng.pad[1] = 0x02; + ctx->eng.pad[nlen - 49] = 0x00; + br_hmac_drbg_generate(&ctx->eng.rng, ctx->eng.pad + 2, nlen - 51); + for (u = 2; u < nlen - 49; u ++) { + while (ctx->eng.pad[u] == 0) { + br_hmac_drbg_generate(&ctx->eng.rng, + &ctx->eng.pad[u], 1); + } + } + + /* + * Compute RSA encryption. + */ + if (!ctx->irsapub(ctx->eng.pad, nlen, &pk->key.rsa)) { + return -BR_ERR_LIMIT_EXCEEDED; + } + return (int)nlen; +} + +/* + * OID for hash functions in RSA signatures. + */ +static const unsigned char *HASH_OID[] = { + BR_HASH_OID_SHA1, + BR_HASH_OID_SHA224, + BR_HASH_OID_SHA256, + BR_HASH_OID_SHA384, + BR_HASH_OID_SHA512 +}; + +/* + * Check the RSA signature on the ServerKeyExchange message. + * + * hash hash function ID (2 to 6), or 0 for MD5+SHA-1 (with RSA only) + * use_rsa non-zero for RSA signature, zero for ECDSA + * sig_len signature length (in bytes); signature value is in the pad + * + * Returned value is 0 on success, or an error code. + */ +static int +verify_SKE_sig(br_ssl_client_context *ctx, + int hash, int use_rsa, size_t sig_len) +{ + const br_x509_class **xc; + const br_x509_pkey *pk; + br_multihash_context mhc; + unsigned char hv[64], head[4]; + size_t hv_len; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + br_multihash_zero(&mhc); + br_multihash_copyimpl(&mhc, &ctx->eng.mhash); + br_multihash_init(&mhc); + br_multihash_update(&mhc, + ctx->eng.client_random, sizeof ctx->eng.client_random); + br_multihash_update(&mhc, + ctx->eng.server_random, sizeof ctx->eng.server_random); + head[0] = 3; + head[1] = 0; + head[2] = ctx->eng.ecdhe_curve; + head[3] = ctx->eng.ecdhe_point_len; + br_multihash_update(&mhc, head, sizeof head); + br_multihash_update(&mhc, + ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len); + if (hash) { + hv_len = br_multihash_out(&mhc, hash, hv); + if (hv_len == 0) { + return BR_ERR_INVALID_ALGORITHM; + } + } else { + if (!br_multihash_out(&mhc, br_md5_ID, hv) + || !br_multihash_out(&mhc, br_sha1_ID, hv + 16)) + { + return BR_ERR_INVALID_ALGORITHM; + } + hv_len = 36; + } + if (use_rsa) { + unsigned char tmp[64]; + const unsigned char *hash_oid; + + if (hash) { + hash_oid = HASH_OID[hash - 2]; + } else { + hash_oid = NULL; + } + if (!ctx->eng.irsavrfy(ctx->eng.pad, sig_len, + hash_oid, hv_len, &pk->key.rsa, tmp) + || memcmp(tmp, hv, hv_len) != 0) + { + return BR_ERR_BAD_SIGNATURE; + } + } else { + if (!ctx->eng.iecdsa(ctx->eng.iec, hv, hv_len, &pk->key.ec, + ctx->eng.pad, sig_len)) + { + return BR_ERR_BAD_SIGNATURE; + } + } + return 0; +} + +/* + * Perform client-side ECDH (or ECDHE). The point that should be sent to + * the server is written in the pad; returned value is either the point + * length (in bytes), or -x on error, with 'x' being an error code. + * + * The point _from_ the server is taken from ecdhe_point[] if 'ecdhe' + * is non-zero, or from the X.509 engine context if 'ecdhe' is zero + * (for static ECDH). + */ +static int +make_pms_ecdh(br_ssl_client_context *ctx, unsigned ecdhe, int prf_id) +{ + int curve; + unsigned char key[66], point[133]; + const unsigned char *order, *point_src; + size_t glen, olen, point_len, xoff, xlen; + unsigned char mask; + + if (ecdhe) { + curve = ctx->eng.ecdhe_curve; + point_src = ctx->eng.ecdhe_point; + point_len = ctx->eng.ecdhe_point_len; + } else { + const br_x509_class **xc; + const br_x509_pkey *pk; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + curve = pk->key.ec.curve; + point_src = pk->key.ec.q; + point_len = pk->key.ec.qlen; + } + if ((ctx->eng.iec->supported_curves & ((uint32_t)1 << curve)) == 0) { + return -BR_ERR_INVALID_ALGORITHM; + } + + /* + * We need to generate our key, as a non-zero random value which + * is lower than the curve order, in a "large enough" range. We + * force top bit to 0 and bottom bit to 1, which guarantees that + * the value is in the proper range. + */ + order = ctx->eng.iec->order(curve, &olen); + mask = 0xFF; + while (mask >= order[0]) { + mask >>= 1; + } + br_hmac_drbg_generate(&ctx->eng.rng, key, olen); + key[0] &= mask; + key[olen - 1] |= 0x01; + + /* + * Compute the common ECDH point, whose X coordinate is the + * pre-master secret. + */ + ctx->eng.iec->generator(curve, &glen); + if (glen != point_len) { + return -BR_ERR_INVALID_ALGORITHM; + } + + memcpy(point, point_src, glen); + if (!ctx->eng.iec->mul(point, glen, key, olen, curve)) { + return -BR_ERR_INVALID_ALGORITHM; + } + + /* + * The pre-master secret is the X coordinate. + */ + xoff = ctx->eng.iec->xoff(curve, &xlen); + br_ssl_engine_compute_master(&ctx->eng, prf_id, point + xoff, xlen); + + ctx->eng.iec->mulgen(point, key, olen, curve); + memcpy(ctx->eng.pad, point, glen); + return (int)glen; +} + +/* + * Perform full static ECDH. This occurs only in the context of client + * authentication with certificates: the server uses an EC public key, + * the cipher suite is of type ECDH (not ECDHE), the server requested a + * client certificate and accepts static ECDH, the client has a + * certificate with an EC public key in the same curve, and accepts + * static ECDH as well. + * + * Returned value is 0 on success, -1 on error. + */ +static int +make_pms_static_ecdh(br_ssl_client_context *ctx, int prf_id) +{ + unsigned char point[133]; + size_t point_len; + const br_x509_class **xc; + const br_x509_pkey *pk; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + point_len = pk->key.ec.qlen; + if (point_len > sizeof point) { + return -1; + } + memcpy(point, pk->key.ec.q, point_len); + if (!(*ctx->client_auth_vtable)->do_keyx( + ctx->client_auth_vtable, point, &point_len)) + { + return -1; + } + br_ssl_engine_compute_master(&ctx->eng, + prf_id, point, point_len); + return 0; +} + +/* + * Compute the client-side signature. This is invoked only when a + * signature-based client authentication was selected. The computed + * signature is in the pad; its length (in bytes) is returned. On + * error, 0 is returned. + */ +static size_t +make_client_sign(br_ssl_client_context *ctx) +{ + size_t hv_len; + + /* + * Compute hash of handshake messages so far. This "cannot" fail + * because the list of supported hash functions provided to the + * client certificate handler was trimmed to include only the + * hash functions that the multi-hasher supports. + */ + if (ctx->hash_id) { + hv_len = br_multihash_out(&ctx->eng.mhash, + ctx->hash_id, ctx->eng.pad); + } else { + br_multihash_out(&ctx->eng.mhash, + br_md5_ID, ctx->eng.pad); + br_multihash_out(&ctx->eng.mhash, + br_sha1_ID, ctx->eng.pad + 16); + hv_len = 36; + } + return (*ctx->client_auth_vtable)->do_sign( + ctx->client_auth_vtable, ctx->hash_id, hv_len, + ctx->eng.pad, sizeof ctx->eng.pad); +} + + + +static const unsigned char t0_datablock[] = { + 0x00, 0x00, 0x0A, 0x00, 0x24, 0x00, 0x2F, 0x01, 0x24, 0x00, 0x35, 0x02, + 0x24, 0x00, 0x3C, 0x01, 0x44, 0x00, 0x3D, 0x02, 0x44, 0x00, 0x9C, 0x03, + 0x04, 0x00, 0x9D, 0x04, 0x05, 0xC0, 0x03, 0x40, 0x24, 0xC0, 0x04, 0x41, + 0x24, 0xC0, 0x05, 0x42, 0x24, 0xC0, 0x08, 0x20, 0x24, 0xC0, 0x09, 0x21, + 0x24, 0xC0, 0x0A, 0x22, 0x24, 0xC0, 0x0D, 0x30, 0x24, 0xC0, 0x0E, 0x31, + 0x24, 0xC0, 0x0F, 0x32, 0x24, 0xC0, 0x12, 0x10, 0x24, 0xC0, 0x13, 0x11, + 0x24, 0xC0, 0x14, 0x12, 0x24, 0xC0, 0x23, 0x21, 0x44, 0xC0, 0x24, 0x22, + 0x55, 0xC0, 0x25, 0x41, 0x44, 0xC0, 0x26, 0x42, 0x55, 0xC0, 0x27, 0x11, + 0x44, 0xC0, 0x28, 0x12, 0x55, 0xC0, 0x29, 0x31, 0x44, 0xC0, 0x2A, 0x32, + 0x55, 0xC0, 0x2B, 0x23, 0x04, 0xC0, 0x2C, 0x24, 0x05, 0xC0, 0x2D, 0x43, + 0x04, 0xC0, 0x2E, 0x44, 0x05, 0xC0, 0x2F, 0x13, 0x04, 0xC0, 0x30, 0x14, + 0x05, 0xC0, 0x31, 0x33, 0x04, 0xC0, 0x32, 0x34, 0x05, 0xC0, 0x9C, 0x06, + 0x04, 0xC0, 0x9D, 0x07, 0x04, 0xC0, 0xA0, 0x08, 0x04, 0xC0, 0xA1, 0x09, + 0x04, 0xC0, 0xAC, 0x26, 0x04, 0xC0, 0xAD, 0x27, 0x04, 0xC0, 0xAE, 0x28, + 0x04, 0xC0, 0xAF, 0x29, 0x04, 0xCC, 0xA8, 0x15, 0x04, 0xCC, 0xA9, 0x25, + 0x04, 0x00, 0x00 +}; + +static const unsigned char t0_codeblock[] = { + 0x00, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x01, + 0x00, 0x0E, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x01, 0x01, 0x08, + 0x00, 0x00, 0x01, 0x01, 0x09, 0x00, 0x00, 0x01, 0x02, 0x08, 0x00, 0x00, + 0x01, 0x02, 0x09, 0x00, 0x00, 0x26, 0x26, 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_CCS), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_CIPHER_SUITE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_COMPRESSION), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_FINISHED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_FRAGLEN), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_HANDSHAKE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_HELLO_DONE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_PARAM), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_SECRENEG), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_BAD_SNI), 0x00, 0x00, 0x01, T0_INT1(BR_ERR_BAD_VERSION), + 0x00, 0x00, 0x01, T0_INT1(BR_ERR_EXTRA_EXTENSION), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_INVALID_ALGORITHM), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, T0_INT1(BR_ERR_OK), + 0x00, 0x00, 0x01, T0_INT1(BR_ERR_OVERSIZED_ID), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_RESUME_MISMATCH), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_UNEXPECTED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_UNSUPPORTED_VERSION), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_WRONG_KEY_USAGE), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, action)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, alert)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, application_data)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_client_context, auth_type)), 0x00, 0x00, + 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, cipher_suite)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, client_random)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, close_received)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, ecdhe_curve)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, ecdhe_point)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, ecdhe_point_len)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, flags)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_client_context, hash_id)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_client_context, hashes)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, log_max_frag_len)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_client_context, min_clienthello_len)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, pad)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, protocol_names_num)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, record_type_in)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, record_type_out)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, reneg)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, saved_finished)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, selected_protocol)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, server_name)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, server_random)), 0x00, 0x00, + 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_id)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_id_len)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_ticket)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, session_ticket_len)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session_ticket_ok)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, shutdown_recv)), + 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, suites_buf)), + 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, suites_num)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, session) + offsetof(br_ssl_session_parameters, version)), + 0x00, 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_in)), + 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_ssl_engine_context, version_max)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_min)), 0x00, + 0x00, 0x01, T0_INT2(offsetof(br_ssl_engine_context, version_out)), + 0x00, 0x00, 0x09, 0x27, 0x5A, 0x06, 0x02, 0x6A, 0x29, 0x00, 0x00, 0x06, + 0x08, 0x2D, 0x0E, 0x05, 0x02, 0x73, 0x29, 0x04, 0x01, 0x3E, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x01, 0x03, 0x00, 0x9E, 0x27, 0x60, 0x46, 0xA2, 0x27, + 0x05, 0x04, 0x62, 0x01, 0x00, 0x00, 0x02, 0x00, 0x0E, 0x06, 0x02, 0xA2, + 0x00, 0x60, 0x04, 0x6B, 0x00, 0x06, 0x02, 0x6A, 0x29, 0x00, 0x00, 0x27, + 0x8B, 0x46, 0x05, 0x03, 0x01, 0x0C, 0x08, 0x46, 0x7B, 0x2D, 0xB1, 0x1C, + 0x86, 0x01, 0x0C, 0x32, 0x00, 0x00, 0x27, 0x1F, 0x01, 0x08, 0x0B, 0x46, + 0x5E, 0x1F, 0x08, 0x00, 0x01, 0x03, 0x00, 0x79, 0x2F, 0x02, 0x00, 0x37, + 0x17, 0x01, 0x01, 0x0B, 0x79, 0x40, 0x2A, 0x1A, 0x37, 0x06, 0x07, 0x02, + 0x00, 0xD7, 0x03, 0x00, 0x04, 0x75, 0x01, 0x00, 0xCD, 0x02, 0x00, 0x27, + 0x1A, 0x17, 0x06, 0x02, 0x71, 0x29, 0xD7, 0x04, 0x76, 0x02, 0x01, 0x00, + 0x79, 0x40, 0x01, 0x16, 0x89, 0x40, 0x01, 0x00, 0x8C, 0x3E, 0x01, 0x00, + 0x93, 0x40, 0x35, 0xDD, 0x2A, 0xBC, 0x01, 0x00, 0x03, 0x00, 0x05, 0x34, + 0x93, 0x2F, 0x92, 0x2D, 0x01, 0x00, 0x0F, 0x17, 0x06, 0x28, 0x30, 0x37, + 0x06, 0x0C, 0xD6, 0x01, 0x07, 0x17, 0x27, 0x5C, 0x06, 0x03, 0x26, 0x04, + 0x75, 0x26, 0x88, 0x2F, 0x01, 0x14, 0x0E, 0x06, 0x06, 0x01, 0x7F, 0x03, + 0x00, 0x04, 0x0B, 0x3A, 0x01, 0x04, 0x0E, 0x06, 0x05, 0xBB, 0x01, 0x7F, + 0x03, 0x00, 0x04, 0x04, 0x01, 0x7F, 0x03, 0x00, 0x02, 0x00, 0x06, 0x09, + 0x01, 0x7F, 0xB6, 0x01, 0x7F, 0xDA, 0x04, 0x80, 0x53, 0xB8, 0x7B, 0x2D, + 0xA6, 0x01, T0_INT1(BR_KEYTYPE_SIGN), 0x17, 0x06, 0x01, 0xBD, 0xC0, + 0x27, 0x01, 0x0D, 0x0E, 0x06, 0x07, 0x26, 0xBF, 0xC0, 0x01, 0x7F, 0x04, + 0x02, 0x01, 0x00, 0x03, 0x01, 0x01, 0x0E, 0x0E, 0x05, 0x02, 0x74, 0x29, + 0x06, 0x02, 0x69, 0x29, 0x34, 0x06, 0x02, 0x74, 0x29, 0x02, 0x01, 0x06, + 0x1C, 0xDB, 0x82, 0x2F, 0x01, 0x81, 0x7F, 0x0E, 0x06, 0x0D, 0x26, 0x01, + 0x10, 0xE6, 0x01, 0x00, 0xE5, 0x7B, 0x2D, 0xB1, 0x25, 0x04, 0x04, 0xDE, + 0x06, 0x01, 0xDC, 0x04, 0x01, 0xDE, 0x01, 0x7F, 0xDA, 0x01, 0x7F, 0xB6, + 0x01, 0x01, 0x79, 0x40, 0x01, 0x17, 0x89, 0x40, 0x00, 0x00, 0x39, 0x39, + 0x00, 0x00, 0x9F, 0x01, 0x0C, 0x11, 0x01, 0x00, 0x39, 0x0E, 0x06, 0x05, + 0x26, 0x01, T0_INT1(BR_KEYTYPE_RSA | BR_KEYTYPE_KEYX), 0x04, 0x30, + 0x01, 0x01, 0x39, 0x0E, 0x06, 0x05, 0x26, 0x01, + T0_INT1(BR_KEYTYPE_RSA | BR_KEYTYPE_SIGN), 0x04, 0x25, 0x01, 0x02, + 0x39, 0x0E, 0x06, 0x05, 0x26, 0x01, + T0_INT1(BR_KEYTYPE_EC | BR_KEYTYPE_SIGN), 0x04, 0x1A, 0x01, 0x03, + 0x39, 0x0E, 0x06, 0x05, 0x26, 0x01, + T0_INT1(BR_KEYTYPE_EC | BR_KEYTYPE_KEYX), 0x04, 0x0F, 0x01, 0x04, + 0x39, 0x0E, 0x06, 0x05, 0x26, 0x01, + T0_INT1(BR_KEYTYPE_EC | BR_KEYTYPE_KEYX), 0x04, 0x04, 0x01, 0x00, + 0x46, 0x26, 0x00, 0x00, 0x84, 0x2F, 0x01, 0x0E, 0x0E, 0x06, 0x04, 0x01, + 0x00, 0x04, 0x02, 0x01, 0x05, 0x00, 0x00, 0x42, 0x06, 0x04, 0x01, 0x06, + 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x8A, 0x2F, 0x27, 0x06, 0x08, 0x01, + 0x01, 0x09, 0x01, 0x11, 0x07, 0x04, 0x03, 0x26, 0x01, 0x05, 0x00, 0x00, + 0x92, 0x2D, 0x01, 0x04, 0x08, 0x00, 0x01, 0x43, 0x03, 0x00, 0x26, 0x01, + 0x00, 0x45, 0x06, 0x03, 0x02, 0x00, 0x08, 0x44, 0x06, 0x03, 0x02, 0x00, + 0x08, 0x27, 0x06, 0x06, 0x01, 0x01, 0x0B, 0x01, 0x06, 0x08, 0x00, 0x00, + 0x8D, 0x41, 0x27, 0x06, 0x03, 0x01, 0x09, 0x08, 0x00, 0x01, 0x42, 0x27, + 0x06, 0x1E, 0x01, 0x00, 0x03, 0x00, 0x27, 0x06, 0x0E, 0x27, 0x01, 0x01, + 0x17, 0x02, 0x00, 0x08, 0x03, 0x00, 0x01, 0x01, 0x11, 0x04, 0x6F, 0x26, + 0x02, 0x00, 0x01, 0x01, 0x0B, 0x01, 0x06, 0x08, 0x00, 0x00, 0x81, 0x2E, + 0x46, 0x11, 0x01, 0x01, 0x17, 0x36, 0x00, 0x00, 0xA4, 0xD6, 0x27, 0x01, + 0x07, 0x17, 0x01, 0x00, 0x39, 0x0E, 0x06, 0x09, 0x26, 0x01, 0x10, 0x17, + 0x06, 0x01, 0xA4, 0x04, 0x35, 0x01, 0x01, 0x39, 0x0E, 0x06, 0x2C, 0x26, + 0x26, 0x01, 0x00, 0x79, 0x40, 0xBA, 0x8A, 0x2F, 0x01, 0x01, 0x0E, 0x01, + 0x01, 0xAE, 0x38, 0x06, 0x17, 0x2A, 0x1A, 0x37, 0x06, 0x04, 0xD6, 0x26, + 0x04, 0x78, 0x01, 0x80, 0x64, 0xCD, 0x01, 0x01, 0x79, 0x40, 0x01, 0x17, + 0x89, 0x40, 0x04, 0x01, 0xA4, 0x04, 0x03, 0x74, 0x29, 0x26, 0x04, 0xFF, + 0x34, 0x01, 0x27, 0x03, 0x00, 0x09, 0x27, 0x5A, 0x06, 0x02, 0x6A, 0x29, + 0x02, 0x00, 0x00, 0x00, 0x9F, 0x01, 0x0F, 0x17, 0x00, 0x00, 0x78, 0x2F, + 0x01, 0x00, 0x39, 0x0E, 0x06, 0x10, 0x26, 0x27, 0x01, 0x01, 0x0D, 0x06, + 0x03, 0x26, 0x01, 0x02, 0x78, 0x40, 0x01, 0x00, 0x04, 0x21, 0x01, 0x01, + 0x39, 0x0E, 0x06, 0x14, 0x26, 0x01, 0x00, 0x78, 0x40, 0x27, 0x01, 0x80, + 0x64, 0x0E, 0x06, 0x05, 0x01, 0x82, 0x00, 0x08, 0x29, 0x5C, 0x04, 0x07, + 0x26, 0x01, 0x82, 0x00, 0x08, 0x29, 0x26, 0x00, 0x00, 0x01, 0x00, 0x30, + 0x06, 0x05, 0x3C, 0xB2, 0x38, 0x04, 0x78, 0x27, 0x06, 0x04, 0x01, 0x01, + 0x94, 0x40, 0x00, 0x01, 0xC7, 0xB0, 0xC7, 0xB0, 0xC9, 0x86, 0x46, 0x27, + 0x03, 0x00, 0xBE, 0xA0, 0xA0, 0x02, 0x00, 0x4F, 0x27, 0x5A, 0x06, 0x0A, + 0x01, 0x03, 0xAE, 0x06, 0x02, 0x74, 0x29, 0x26, 0x04, 0x03, 0x5E, 0x8C, + 0x3E, 0x00, 0x00, 0x30, 0x06, 0x0B, 0x88, 0x2F, 0x01, 0x14, 0x0D, 0x06, + 0x02, 0x74, 0x29, 0x04, 0x11, 0xD6, 0x01, 0x07, 0x17, 0x27, 0x01, 0x02, + 0x0D, 0x06, 0x06, 0x06, 0x02, 0x74, 0x29, 0x04, 0x70, 0x26, 0xCA, 0x01, + 0x01, 0x0D, 0x34, 0x38, 0x06, 0x02, 0x63, 0x29, 0x27, 0x01, 0x01, 0xD0, + 0x37, 0xB9, 0x00, 0x00, 0x93, 0x2F, 0x06, 0x2A, 0x30, 0x06, 0x0A, 0x88, + 0x2F, 0x01, 0x16, 0x0E, 0x06, 0x01, 0xBB, 0x04, 0x1D, 0xD6, 0x01, 0x07, + 0x17, 0x27, 0x01, 0x01, 0x0E, 0x06, 0x04, 0x26, 0xBB, 0x01, 0x00, 0x27, + 0x01, 0x02, 0x0D, 0x06, 0x08, 0x27, 0x06, 0x02, 0x74, 0x29, 0x26, 0x04, + 0x64, 0x26, 0xB5, 0x00, 0x01, 0xC0, 0x01, 0x0B, 0x0E, 0x05, 0x02, 0x74, + 0x29, 0x27, 0x01, 0x03, 0x0E, 0x06, 0x08, 0xC8, 0x06, 0x02, 0x6A, 0x29, + 0x46, 0x26, 0x00, 0x46, 0x59, 0xC8, 0xB0, 0x27, 0x06, 0x23, 0xC8, 0xB0, + 0x27, 0x58, 0x27, 0x06, 0x18, 0x27, 0x01, 0x82, 0x00, 0x0F, 0x06, 0x05, + 0x01, 0x82, 0x00, 0x04, 0x01, 0x27, 0x03, 0x00, 0x86, 0x02, 0x00, 0xBE, + 0x02, 0x00, 0x55, 0x04, 0x65, 0xA0, 0x56, 0x04, 0x5A, 0xA0, 0xA0, 0x57, + 0x27, 0x06, 0x02, 0x36, 0x00, 0x26, 0x2C, 0x00, 0x00, 0x7B, 0x2D, 0xA6, + 0x01, 0x7F, 0xB7, 0x27, 0x5A, 0x06, 0x02, 0x36, 0x29, 0x27, 0x05, 0x02, + 0x74, 0x29, 0x39, 0x17, 0x0D, 0x06, 0x02, 0x76, 0x29, 0x3D, 0x00, 0x00, + 0xA1, 0xC0, 0x01, 0x14, 0x0D, 0x06, 0x02, 0x74, 0x29, 0x86, 0x01, 0x0C, + 0x08, 0x01, 0x0C, 0xBE, 0xA0, 0x86, 0x27, 0x01, 0x0C, 0x08, 0x01, 0x0C, + 0x31, 0x05, 0x02, 0x66, 0x29, 0x00, 0x00, 0xC1, 0x06, 0x02, 0x74, 0x29, + 0x06, 0x02, 0x68, 0x29, 0x00, 0x01, 0xC0, 0x01, 0x04, 0x0E, 0x05, 0x02, + 0x74, 0x29, 0xC7, 0x26, 0xC7, 0x26, 0xC7, 0x03, 0x00, 0x02, 0x00, 0x01, + 0x88, 0x00, 0x0F, 0x06, 0x09, 0x02, 0x00, 0xCE, 0x01, 0x00, 0x92, 0x3E, + 0x04, 0x08, 0x91, 0x02, 0x00, 0xBE, 0x02, 0x00, 0x92, 0x3E, 0x02, 0x00, + 0x20, 0xA0, 0x00, 0x0B, 0xC0, 0x01, 0x02, 0x0E, 0x05, 0x02, 0x74, 0x29, + 0xC7, 0x03, 0x00, 0x02, 0x00, 0x9A, 0x2D, 0x0A, 0x02, 0x00, 0x99, 0x2D, + 0x0F, 0x38, 0x06, 0x02, 0x75, 0x29, 0x02, 0x00, 0x98, 0x2D, 0x0D, 0x06, + 0x02, 0x6D, 0x29, 0x02, 0x00, 0x9B, 0x3E, 0x8E, 0x01, 0x20, 0xBE, 0x01, + 0x00, 0x03, 0x01, 0xC9, 0x03, 0x02, 0x02, 0x02, 0x01, 0x20, 0x0F, 0x06, + 0x02, 0x72, 0x29, 0x86, 0x02, 0x02, 0xBE, 0x02, 0x02, 0x90, 0x2F, 0x0E, + 0x02, 0x02, 0x01, 0x00, 0x0F, 0x17, 0x06, 0x0B, 0x8F, 0x86, 0x02, 0x02, + 0x31, 0x06, 0x04, 0x01, 0x7F, 0x03, 0x01, 0x8F, 0x86, 0x02, 0x02, 0x32, + 0x02, 0x02, 0x90, 0x40, 0x02, 0x00, 0x97, 0x02, 0x01, 0x9D, 0xC7, 0x27, + 0xCB, 0x5A, 0x06, 0x02, 0x64, 0x29, 0x27, 0xD5, 0x02, 0x00, 0x01, 0x86, + 0x03, 0x0A, 0x17, 0x06, 0x02, 0x64, 0x29, 0x7B, 0x02, 0x01, 0x9D, 0xC9, + 0x06, 0x02, 0x65, 0x29, 0x27, 0x06, 0x81, 0x64, 0xC7, 0xB0, 0xAC, 0x03, + 0x03, 0xA9, 0x03, 0x04, 0xA7, 0x03, 0x05, 0xAB, 0x03, 0x06, 0xAD, 0x03, + 0x07, 0xA8, 0x03, 0x08, 0xAA, 0x03, 0x09, 0x28, 0x03, 0x0A, 0x27, 0x06, + 0x81, 0x32, 0xC7, 0x01, 0x00, 0x39, 0x0E, 0x06, 0x0F, 0x26, 0x02, 0x03, + 0x05, 0x02, 0x6E, 0x29, 0x01, 0x00, 0x03, 0x03, 0xC6, 0x04, 0x81, 0x19, + 0x01, 0x01, 0x39, 0x0E, 0x06, 0x0F, 0x26, 0x02, 0x05, 0x05, 0x02, 0x6E, + 0x29, 0x01, 0x00, 0x03, 0x05, 0xC4, 0x04, 0x81, 0x04, 0x01, 0x83, 0xFE, + 0x01, 0x39, 0x0E, 0x06, 0x0F, 0x26, 0x02, 0x04, 0x05, 0x02, 0x6E, 0x29, + 0x01, 0x00, 0x03, 0x04, 0xC5, 0x04, 0x80, 0x6D, 0x01, 0x0D, 0x39, 0x0E, + 0x06, 0x0F, 0x26, 0x02, 0x06, 0x05, 0x02, 0x6E, 0x29, 0x01, 0x00, 0x03, + 0x06, 0xC2, 0x04, 0x80, 0x58, 0x01, 0x0A, 0x39, 0x0E, 0x06, 0x0F, 0x26, + 0x02, 0x07, 0x05, 0x02, 0x6E, 0x29, 0x01, 0x00, 0x03, 0x07, 0xC2, 0x04, + 0x80, 0x43, 0x01, 0x0B, 0x39, 0x0E, 0x06, 0x0E, 0x26, 0x02, 0x08, 0x05, + 0x02, 0x6E, 0x29, 0x01, 0x00, 0x03, 0x08, 0xC2, 0x04, 0x2F, 0x01, 0x10, + 0x39, 0x0E, 0x06, 0x0E, 0x26, 0x02, 0x0A, 0x05, 0x02, 0x6E, 0x29, 0x01, + 0x00, 0x03, 0x0A, 0xB4, 0x04, 0x1B, 0x01, 0x23, 0x39, 0x0E, 0x06, 0x12, + 0x26, 0x02, 0x09, 0x05, 0x02, 0x6E, 0x29, 0x01, 0x00, 0x03, 0x09, 0xC2, + 0x01, 0x01, 0x93, 0x40, 0x04, 0x03, 0x6E, 0x29, 0x26, 0x04, 0xFE, 0x4A, + 0x02, 0x04, 0x06, 0x0D, 0x02, 0x04, 0x01, 0x05, 0x0F, 0x06, 0x02, 0x6B, + 0x29, 0x01, 0x01, 0x8A, 0x40, 0xA0, 0x04, 0x0C, 0xA9, 0x01, 0x05, 0x0F, + 0x06, 0x02, 0x6B, 0x29, 0x01, 0x01, 0x8A, 0x40, 0xA0, 0x02, 0x01, 0x00, + 0x04, 0xC0, 0x01, 0x0C, 0x0E, 0x05, 0x02, 0x74, 0x29, 0xC9, 0x01, 0x03, + 0x0E, 0x05, 0x02, 0x6F, 0x29, 0xC7, 0x27, 0x7E, 0x40, 0x27, 0x01, 0x20, + 0x10, 0x06, 0x02, 0x6F, 0x29, 0x42, 0x46, 0x11, 0x01, 0x01, 0x17, 0x05, + 0x02, 0x6F, 0x29, 0xC9, 0x27, 0x01, 0x81, 0x05, 0x0F, 0x06, 0x02, 0x6F, + 0x29, 0x27, 0x80, 0x40, 0x7F, 0x46, 0xBE, 0x97, 0x2D, 0x01, 0x86, 0x03, + 0x10, 0x03, 0x00, 0x7B, 0x2D, 0xD3, 0x03, 0x01, 0x01, 0x02, 0x03, 0x02, + 0x02, 0x00, 0x06, 0x21, 0xC9, 0x27, 0x27, 0x01, 0x02, 0x0A, 0x46, 0x01, + 0x06, 0x0F, 0x38, 0x06, 0x02, 0x6F, 0x29, 0x03, 0x02, 0xC9, 0x02, 0x01, + 0x01, 0x01, 0x0B, 0x01, 0x03, 0x08, 0x0E, 0x05, 0x02, 0x6F, 0x29, 0x04, + 0x08, 0x02, 0x01, 0x06, 0x04, 0x01, 0x00, 0x03, 0x02, 0xC7, 0x27, 0x03, + 0x03, 0x27, 0x01, 0x84, 0x00, 0x0F, 0x06, 0x02, 0x70, 0x29, 0x86, 0x46, + 0xBE, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x52, 0x27, 0x06, 0x01, 0x29, + 0x26, 0xA0, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0x02, 0x00, 0x9C, 0x02, + 0x01, 0x02, 0x00, 0x3B, 0x27, 0x01, 0x00, 0x0E, 0x06, 0x02, 0x62, 0x00, + 0xD8, 0x04, 0x74, 0x02, 0x01, 0x00, 0x03, 0x00, 0xC9, 0xB0, 0x27, 0x06, + 0x80, 0x43, 0xC9, 0x01, 0x01, 0x39, 0x0E, 0x06, 0x06, 0x26, 0x01, 0x81, + 0x7F, 0x04, 0x2E, 0x01, 0x80, 0x40, 0x39, 0x0E, 0x06, 0x07, 0x26, 0x01, + 0x83, 0xFE, 0x00, 0x04, 0x20, 0x01, 0x80, 0x41, 0x39, 0x0E, 0x06, 0x07, + 0x26, 0x01, 0x84, 0x80, 0x00, 0x04, 0x12, 0x01, 0x80, 0x42, 0x39, 0x0E, + 0x06, 0x07, 0x26, 0x01, 0x88, 0x80, 0x00, 0x04, 0x04, 0x01, 0x00, 0x46, + 0x26, 0x02, 0x00, 0x38, 0x03, 0x00, 0x04, 0xFF, 0x39, 0xA0, 0x7B, 0x2D, + 0xD1, 0x05, 0x09, 0x02, 0x00, 0x01, 0x83, 0xFF, 0x7F, 0x17, 0x03, 0x00, + 0x97, 0x2D, 0x01, 0x86, 0x03, 0x10, 0x06, 0x3A, 0xC3, 0x27, 0x83, 0x3F, + 0x43, 0x26, 0x27, 0x01, 0x08, 0x0B, 0x38, 0x01, 0x8C, 0x80, 0x00, 0x38, + 0x17, 0x02, 0x00, 0x17, 0x02, 0x00, 0x01, 0x8C, 0x80, 0x00, 0x17, 0x06, + 0x19, 0x27, 0x01, 0x81, 0x7F, 0x17, 0x06, 0x05, 0x01, 0x84, 0x80, 0x00, + 0x38, 0x27, 0x01, 0x83, 0xFE, 0x00, 0x17, 0x06, 0x05, 0x01, 0x88, 0x80, + 0x00, 0x38, 0x03, 0x00, 0x04, 0x09, 0x02, 0x00, 0x01, 0x8C, 0x88, 0x01, + 0x17, 0x03, 0x00, 0x16, 0xC7, 0xB0, 0x27, 0x06, 0x23, 0xC7, 0xB0, 0x27, + 0x15, 0x27, 0x06, 0x18, 0x27, 0x01, 0x82, 0x00, 0x0F, 0x06, 0x05, 0x01, + 0x82, 0x00, 0x04, 0x01, 0x27, 0x03, 0x01, 0x86, 0x02, 0x01, 0xBE, 0x02, + 0x01, 0x12, 0x04, 0x65, 0xA0, 0x13, 0x04, 0x5A, 0xA0, 0x14, 0xA0, 0x02, + 0x00, 0x2B, 0x00, 0x00, 0xC1, 0x27, 0x5C, 0x06, 0x07, 0x26, 0x06, 0x02, + 0x68, 0x29, 0x04, 0x74, 0x00, 0x00, 0xCA, 0x01, 0x03, 0xC8, 0x46, 0x26, + 0x46, 0x00, 0x00, 0xC7, 0xCE, 0x00, 0x03, 0x01, 0x00, 0x03, 0x00, 0xC7, + 0xB0, 0x27, 0x06, 0x80, 0x50, 0xC9, 0x03, 0x01, 0xC9, 0x03, 0x02, 0x02, + 0x01, 0x01, 0x08, 0x0E, 0x06, 0x16, 0x02, 0x02, 0x01, 0x0F, 0x0C, 0x06, + 0x0D, 0x01, 0x01, 0x02, 0x02, 0x01, 0x10, 0x08, 0x0B, 0x02, 0x00, 0x38, + 0x03, 0x00, 0x04, 0x2A, 0x02, 0x01, 0x01, 0x02, 0x10, 0x02, 0x01, 0x01, + 0x06, 0x0C, 0x17, 0x02, 0x02, 0x01, 0x01, 0x0E, 0x02, 0x02, 0x01, 0x03, + 0x0E, 0x38, 0x17, 0x06, 0x11, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x5F, + 0x01, 0x02, 0x0B, 0x02, 0x01, 0x08, 0x0B, 0x38, 0x03, 0x00, 0x04, 0xFF, + 0x2C, 0xA0, 0x02, 0x00, 0x00, 0x00, 0xC7, 0x01, 0x01, 0x0E, 0x05, 0x02, + 0x67, 0x29, 0xC9, 0x01, 0x08, 0x08, 0x84, 0x2F, 0x0E, 0x05, 0x02, 0x67, + 0x29, 0x00, 0x00, 0xC7, 0x8A, 0x2F, 0x05, 0x15, 0x01, 0x01, 0x0E, 0x05, + 0x02, 0x6B, 0x29, 0xC9, 0x01, 0x00, 0x0E, 0x05, 0x02, 0x6B, 0x29, 0x01, + 0x02, 0x8A, 0x40, 0x04, 0x1C, 0x01, 0x19, 0x0E, 0x05, 0x02, 0x6B, 0x29, + 0xC9, 0x01, 0x18, 0x0E, 0x05, 0x02, 0x6B, 0x29, 0x86, 0x01, 0x18, 0xBE, + 0x8B, 0x86, 0x01, 0x18, 0x31, 0x05, 0x02, 0x6B, 0x29, 0x00, 0x00, 0xC7, + 0x06, 0x02, 0x6C, 0x29, 0x00, 0x00, 0x01, 0x02, 0x9C, 0xCA, 0x01, 0x08, + 0x0B, 0xCA, 0x08, 0x00, 0x00, 0x01, 0x03, 0x9C, 0xCA, 0x01, 0x08, 0x0B, + 0xCA, 0x08, 0x01, 0x08, 0x0B, 0xCA, 0x08, 0x00, 0x00, 0x01, 0x01, 0x9C, + 0xCA, 0x00, 0x00, 0x3C, 0x27, 0x5A, 0x05, 0x01, 0x00, 0x26, 0xD8, 0x04, + 0x76, 0x02, 0x03, 0x00, 0x96, 0x2F, 0x03, 0x01, 0x01, 0x00, 0x27, 0x02, + 0x01, 0x0A, 0x06, 0x10, 0x27, 0x01, 0x01, 0x0B, 0x95, 0x08, 0x2D, 0x02, + 0x00, 0x0E, 0x06, 0x01, 0x00, 0x5E, 0x04, 0x6A, 0x26, 0x01, 0x7F, 0x00, + 0x00, 0x01, 0x15, 0x89, 0x40, 0x46, 0x54, 0x26, 0x54, 0x26, 0x2A, 0x00, + 0x00, 0x01, 0x01, 0x46, 0xCC, 0x00, 0x00, 0x46, 0x39, 0x9C, 0x46, 0x27, + 0x06, 0x05, 0xCA, 0x26, 0x5F, 0x04, 0x78, 0x26, 0x00, 0x00, 0x27, 0x01, + 0x81, 0xAC, 0x00, 0x0E, 0x06, 0x04, 0x26, 0x01, 0x7F, 0x00, 0x9F, 0x5B, + 0x00, 0x02, 0x03, 0x00, 0x7B, 0x2D, 0x9F, 0x03, 0x01, 0x02, 0x01, 0x01, + 0x0F, 0x17, 0x02, 0x01, 0x01, 0x04, 0x11, 0x01, 0x0F, 0x17, 0x02, 0x01, + 0x01, 0x08, 0x11, 0x01, 0x0F, 0x17, 0x01, 0x00, 0x39, 0x0E, 0x06, 0x10, + 0x26, 0x01, 0x00, 0x01, 0x18, 0x02, 0x00, 0x06, 0x03, 0x4B, 0x04, 0x01, + 0x4C, 0x04, 0x81, 0x0D, 0x01, 0x01, 0x39, 0x0E, 0x06, 0x10, 0x26, 0x01, + 0x01, 0x01, 0x10, 0x02, 0x00, 0x06, 0x03, 0x4B, 0x04, 0x01, 0x4C, 0x04, + 0x80, 0x77, 0x01, 0x02, 0x39, 0x0E, 0x06, 0x10, 0x26, 0x01, 0x01, 0x01, + 0x20, 0x02, 0x00, 0x06, 0x03, 0x4B, 0x04, 0x01, 0x4C, 0x04, 0x80, 0x61, + 0x01, 0x03, 0x39, 0x0E, 0x06, 0x0F, 0x26, 0x26, 0x01, 0x10, 0x02, 0x00, + 0x06, 0x03, 0x49, 0x04, 0x01, 0x4A, 0x04, 0x80, 0x4C, 0x01, 0x04, 0x39, + 0x0E, 0x06, 0x0E, 0x26, 0x26, 0x01, 0x20, 0x02, 0x00, 0x06, 0x03, 0x49, + 0x04, 0x01, 0x4A, 0x04, 0x38, 0x01, 0x05, 0x39, 0x0E, 0x06, 0x0C, 0x26, + 0x26, 0x02, 0x00, 0x06, 0x03, 0x4D, 0x04, 0x01, 0x4E, 0x04, 0x26, 0x27, + 0x01, 0x09, 0x0F, 0x06, 0x02, 0x6A, 0x29, 0x46, 0x26, 0x27, 0x01, 0x01, + 0x17, 0x01, 0x04, 0x0B, 0x01, 0x10, 0x08, 0x46, 0x01, 0x08, 0x17, 0x01, + 0x10, 0x46, 0x09, 0x02, 0x00, 0x06, 0x03, 0x47, 0x04, 0x01, 0x48, 0x00, + 0x26, 0x00, 0x00, 0x9F, 0x01, 0x0C, 0x11, 0x01, 0x02, 0x0F, 0x00, 0x00, + 0x9F, 0x01, 0x0C, 0x11, 0x27, 0x5D, 0x46, 0x01, 0x03, 0x0A, 0x17, 0x00, + 0x00, 0x9F, 0x01, 0x0C, 0x11, 0x01, 0x01, 0x0E, 0x00, 0x00, 0x9F, 0x01, + 0x0C, 0x11, 0x5C, 0x00, 0x00, 0x9F, 0x01, 0x81, 0x70, 0x17, 0x01, 0x20, + 0x0D, 0x00, 0x00, 0x1B, 0x01, 0x00, 0x77, 0x2F, 0x27, 0x06, 0x22, 0x01, + 0x01, 0x39, 0x0E, 0x06, 0x06, 0x26, 0x01, 0x00, 0xA3, 0x04, 0x14, 0x01, + 0x02, 0x39, 0x0E, 0x06, 0x0D, 0x26, 0x79, 0x2F, 0x01, 0x01, 0x0E, 0x06, + 0x03, 0x01, 0x10, 0x38, 0x04, 0x01, 0x26, 0x04, 0x01, 0x26, 0x7D, 0x2F, + 0x05, 0x33, 0x30, 0x06, 0x30, 0x88, 0x2F, 0x01, 0x14, 0x39, 0x0E, 0x06, + 0x06, 0x26, 0x01, 0x02, 0x38, 0x04, 0x22, 0x01, 0x15, 0x39, 0x0E, 0x06, + 0x09, 0x26, 0xB3, 0x06, 0x03, 0x01, 0x7F, 0xA3, 0x04, 0x13, 0x01, 0x16, + 0x39, 0x0E, 0x06, 0x06, 0x26, 0x01, 0x01, 0x38, 0x04, 0x07, 0x26, 0x01, + 0x04, 0x38, 0x01, 0x00, 0x26, 0x1A, 0x06, 0x03, 0x01, 0x08, 0x38, 0x00, + 0x00, 0x1B, 0x27, 0x05, 0x13, 0x30, 0x06, 0x10, 0x88, 0x2F, 0x01, 0x15, + 0x0E, 0x06, 0x08, 0x26, 0xB3, 0x01, 0x00, 0x79, 0x40, 0x04, 0x01, 0x21, + 0x00, 0x00, 0xD6, 0x01, 0x07, 0x17, 0x01, 0x01, 0x0F, 0x06, 0x02, 0x74, + 0x29, 0x00, 0x01, 0x03, 0x00, 0x2A, 0x1A, 0x06, 0x05, 0x02, 0x00, 0x89, + 0x40, 0x00, 0xD6, 0x26, 0x04, 0x74, 0x00, 0x01, 0x14, 0xD9, 0x01, 0x01, + 0xE6, 0x2A, 0x27, 0x01, 0x00, 0xD0, 0x01, 0x16, 0xD9, 0xDF, 0x2A, 0x00, + 0x00, 0x01, 0x0B, 0xE6, 0x50, 0x27, 0x27, 0x01, 0x03, 0x08, 0xE5, 0xE5, + 0x18, 0x27, 0x5A, 0x06, 0x02, 0x26, 0x00, 0xE5, 0x1D, 0x27, 0x06, 0x05, + 0x86, 0x46, 0xE0, 0x04, 0x77, 0x26, 0x04, 0x6C, 0x00, 0x22, 0x01, 0x0F, + 0xE6, 0x27, 0x97, 0x2D, 0x01, 0x86, 0x03, 0x10, 0x06, 0x0C, 0x01, 0x04, + 0x08, 0xE5, 0x82, 0x2F, 0xE6, 0x7A, 0x2F, 0xE6, 0x04, 0x02, 0x60, 0xE5, + 0x27, 0xE4, 0x86, 0x46, 0xE0, 0x00, 0x02, 0xA9, 0xAC, 0x08, 0xA7, 0x08, + 0xAB, 0x08, 0xAD, 0x08, 0xA8, 0x08, 0x28, 0x08, 0xAA, 0x08, 0x03, 0x00, + 0x01, 0x01, 0xE6, 0x01, 0x27, 0x90, 0x2F, 0x08, 0x96, 0x2F, 0x01, 0x01, + 0x0B, 0x08, 0x02, 0x00, 0x06, 0x04, 0x60, 0x02, 0x00, 0x08, 0x85, 0x2D, + 0x39, 0x09, 0x27, 0x5D, 0x06, 0x24, 0x02, 0x00, 0x05, 0x04, 0x46, 0x60, + 0x46, 0x61, 0x01, 0x04, 0x09, 0x27, 0x5A, 0x06, 0x03, 0x26, 0x01, 0x00, + 0x27, 0x01, 0x04, 0x08, 0x02, 0x00, 0x08, 0x03, 0x00, 0x46, 0x01, 0x04, + 0x08, 0x39, 0x08, 0x46, 0x04, 0x03, 0x26, 0x01, 0x7F, 0x03, 0x01, 0xE5, + 0x99, 0x2D, 0xE4, 0x7C, 0x01, 0x04, 0x19, 0x7C, 0x01, 0x04, 0x08, 0x01, + 0x1C, 0x33, 0x7C, 0x01, 0x20, 0xE0, 0x8F, 0x90, 0x2F, 0xE2, 0x96, 0x2F, + 0x27, 0x01, 0x01, 0x0B, 0xE4, 0x95, 0x46, 0x27, 0x06, 0x0F, 0x5F, 0x39, + 0x2D, 0x27, 0xCF, 0x05, 0x02, 0x64, 0x29, 0xE4, 0x46, 0x60, 0x46, 0x04, + 0x6E, 0x62, 0x01, 0x01, 0xE6, 0x01, 0x00, 0xE6, 0x02, 0x00, 0x06, 0x81, + 0x6A, 0x02, 0x00, 0xE4, 0xA9, 0x06, 0x0E, 0x01, 0x83, 0xFE, 0x01, 0xE4, + 0x8B, 0xA9, 0x01, 0x04, 0x09, 0x27, 0xE4, 0x5F, 0xE2, 0xAC, 0x06, 0x16, + 0x01, 0x00, 0xE4, 0x8D, 0xAC, 0x01, 0x04, 0x09, 0x27, 0xE4, 0x01, 0x02, + 0x09, 0x27, 0xE4, 0x01, 0x00, 0xE6, 0x01, 0x03, 0x09, 0xE1, 0xA7, 0x06, + 0x0C, 0x01, 0x01, 0xE4, 0x01, 0x01, 0xE4, 0x84, 0x2F, 0x01, 0x08, 0x09, + 0xE6, 0xAB, 0x06, 0x19, 0x01, 0x0D, 0xE4, 0xAB, 0x01, 0x04, 0x09, 0x27, + 0xE4, 0x01, 0x02, 0x09, 0xE4, 0x44, 0x06, 0x03, 0x01, 0x03, 0xE3, 0x45, + 0x06, 0x03, 0x01, 0x01, 0xE3, 0xAD, 0x27, 0x06, 0x36, 0x01, 0x0A, 0xE4, + 0x01, 0x04, 0x09, 0x27, 0xE4, 0x61, 0xE4, 0x42, 0x01, 0x00, 0x27, 0x01, + 0x82, 0x80, 0x80, 0x80, 0x00, 0x17, 0x06, 0x0A, 0x01, 0xFD, 0xFF, 0xFF, + 0xFF, 0x7F, 0x17, 0x01, 0x1D, 0xE4, 0x27, 0x01, 0x20, 0x0A, 0x06, 0x0C, + 0xA5, 0x11, 0x01, 0x01, 0x17, 0x06, 0x02, 0x27, 0xE4, 0x5E, 0x04, 0x6E, + 0x62, 0x04, 0x01, 0x26, 0xA8, 0x06, 0x0A, 0x01, 0x0B, 0xE4, 0x01, 0x02, + 0xE4, 0x01, 0x82, 0x00, 0xE4, 0x28, 0x27, 0x06, 0x1F, 0x01, 0x10, 0xE4, + 0x01, 0x04, 0x09, 0x27, 0xE4, 0x61, 0xE4, 0x87, 0x2D, 0x01, 0x00, 0xA5, + 0x0F, 0x06, 0x0A, 0x27, 0x1E, 0x27, 0xE6, 0x86, 0x46, 0xE0, 0x5E, 0x04, + 0x72, 0x62, 0x04, 0x01, 0x26, 0x01, 0x23, 0xE4, 0x92, 0x2D, 0x27, 0xE4, + 0x27, 0x06, 0x05, 0x91, 0x46, 0xE0, 0x04, 0x01, 0x26, 0x02, 0x01, 0x5A, + 0x05, 0x11, 0x01, 0x15, 0xE4, 0x02, 0x01, 0x27, 0xE4, 0x27, 0x06, 0x06, + 0x5F, 0x01, 0x00, 0xE6, 0x04, 0x77, 0x26, 0x00, 0x00, 0x01, 0x10, 0xE6, + 0x7B, 0x2D, 0x27, 0xD4, 0x06, 0x0C, 0xB1, 0x24, 0x27, 0x60, 0xE5, 0x27, + 0xE4, 0x86, 0x46, 0xE0, 0x04, 0x0D, 0x27, 0xD2, 0x46, 0xB1, 0x23, 0x27, + 0x5E, 0xE5, 0x27, 0xE6, 0x86, 0x46, 0xE0, 0x00, 0x00, 0xA1, 0x01, 0x14, + 0xE6, 0x01, 0x0C, 0xE5, 0x86, 0x01, 0x0C, 0xE0, 0x00, 0x00, 0x53, 0x27, + 0x01, 0x00, 0x0E, 0x06, 0x02, 0x62, 0x00, 0xD6, 0x26, 0x04, 0x73, 0x00, + 0x27, 0xE4, 0xE0, 0x00, 0x00, 0x27, 0xE6, 0xE0, 0x00, 0x01, 0x03, 0x00, + 0x43, 0x26, 0x27, 0x01, 0x10, 0x17, 0x06, 0x06, 0x01, 0x04, 0xE6, 0x02, + 0x00, 0xE6, 0x27, 0x01, 0x08, 0x17, 0x06, 0x06, 0x01, 0x03, 0xE6, 0x02, + 0x00, 0xE6, 0x27, 0x01, 0x20, 0x17, 0x06, 0x06, 0x01, 0x05, 0xE6, 0x02, + 0x00, 0xE6, 0x27, 0x01, 0x80, 0x40, 0x17, 0x06, 0x06, 0x01, 0x06, 0xE6, + 0x02, 0x00, 0xE6, 0x01, 0x04, 0x17, 0x06, 0x06, 0x01, 0x02, 0xE6, 0x02, + 0x00, 0xE6, 0x00, 0x00, 0x27, 0x01, 0x08, 0x51, 0xE6, 0xE6, 0x00, 0x00, + 0x27, 0x01, 0x10, 0x51, 0xE6, 0xE4, 0x00, 0x00, 0x27, 0x54, 0x06, 0x02, + 0x26, 0x00, 0xD6, 0x26, 0x04, 0x76 +}; + +static const uint16_t t0_caddr[] = { + 0, + 5, + 10, + 15, + 20, + 25, + 30, + 35, + 40, + 44, + 48, + 52, + 56, + 60, + 64, + 68, + 72, + 76, + 80, + 84, + 88, + 92, + 96, + 100, + 104, + 108, + 112, + 116, + 120, + 124, + 129, + 134, + 139, + 144, + 149, + 154, + 159, + 164, + 169, + 174, + 179, + 184, + 189, + 194, + 199, + 204, + 209, + 214, + 219, + 224, + 229, + 234, + 239, + 244, + 249, + 254, + 259, + 264, + 269, + 274, + 279, + 284, + 289, + 294, + 299, + 304, + 309, + 318, + 331, + 335, + 360, + 366, + 385, + 396, + 437, + 625, + 629, + 694, + 709, + 720, + 738, + 745, + 774, + 784, + 820, + 830, + 908, + 922, + 928, + 987, + 1006, + 1041, + 1090, + 1139, + 1215, + 1242, + 1273, + 1284, + 1330, + 1711, + 1858, + 1882, + 2098, + 2112, + 2121, + 2125, + 2220, + 2241, + 2297, + 2304, + 2315, + 2331, + 2337, + 2348, + 2383, + 2395, + 2401, + 2416, + 2432, + 2625, + 2634, + 2647, + 2656, + 2663, + 2673, + 2779, + 2804, + 2817, + 2833, + 2851, + 2883, + 2917, + 3303, + 3339, + 3352, + 3366, + 3371, + 3376, + 3442, + 3450, + 3458 +}; + +#define T0_INTERPRETED 90 + +#define T0_ENTER(ip, rp, slot) do { \ + const unsigned char *t0_newip; \ + uint32_t t0_lnum; \ + t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ + t0_lnum = t0_parse7E_unsigned(&t0_newip); \ + (rp) += t0_lnum; \ + *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ + (ip) = t0_newip; \ + } while (0) + +#define T0_DEFENTRY(name, slot) \ +void \ +name(void *ctx) \ +{ \ + t0_context *t0ctx = ctx; \ + t0ctx->ip = &t0_codeblock[0]; \ + T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ +} + +T0_DEFENTRY(br_ssl_hs_client_init_main, 175) + +#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) + +void +br_ssl_hs_client_run(void *t0ctx) +{ + uint32_t *dp, *rp; + const unsigned char *ip; + +#define T0_LOCAL(x) (*(rp - 2 - (x))) +#define T0_POP() (*-- dp) +#define T0_POPi() (*(int32_t *)(-- dp)) +#define T0_PEEK(x) (*(dp - 1 - (x))) +#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) +#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) +#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) +#define T0_RPOP() (*-- rp) +#define T0_RPOPi() (*(int32_t *)(-- rp)) +#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) +#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) +#define T0_ROLL(x) do { \ + size_t t0len = (size_t)(x); \ + uint32_t t0tmp = *(dp - 1 - t0len); \ + memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_SWAP() do { \ + uint32_t t0tmp = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_ROT() do { \ + uint32_t t0tmp = *(dp - 3); \ + *(dp - 3) = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_NROT() do { \ + uint32_t t0tmp = *(dp - 1); \ + *(dp - 1) = *(dp - 2); \ + *(dp - 2) = *(dp - 3); \ + *(dp - 3) = t0tmp; \ +} while (0) +#define T0_PICK(x) do { \ + uint32_t t0depth = (x); \ + T0_PUSH(T0_PEEK(t0depth)); \ +} while (0) +#define T0_CO() do { \ + goto t0_exit; \ +} while (0) +#define T0_RET() goto t0_next + + dp = ((t0_context *)t0ctx)->dp; + rp = ((t0_context *)t0ctx)->rp; + ip = ((t0_context *)t0ctx)->ip; + goto t0_next; + for (;;) { + uint32_t t0x; + + t0_next: + t0x = T0_NEXT(&ip); + if (t0x < T0_INTERPRETED) { + switch (t0x) { + int32_t t0off; + + case 0: /* ret */ + t0x = T0_RPOP(); + rp -= (t0x >> 16); + t0x &= 0xFFFF; + if (t0x == 0) { + ip = NULL; + goto t0_exit; + } + ip = &t0_codeblock[t0x]; + break; + case 1: /* literal constant */ + T0_PUSHi(t0_parse7E_signed(&ip)); + break; + case 2: /* read local */ + T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); + break; + case 3: /* write local */ + T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); + break; + case 4: /* jump */ + t0off = t0_parse7E_signed(&ip); + ip += t0off; + break; + case 5: /* jump if */ + t0off = t0_parse7E_signed(&ip); + if (T0_POP()) { + ip += t0off; + } + break; + case 6: /* jump if not */ + t0off = t0_parse7E_signed(&ip); + if (!T0_POP()) { + ip += t0off; + } + break; + case 7: { + /* * */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a * b); + + } + break; + case 8: { + /* + */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a + b); + + } + break; + case 9: { + /* - */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a - b); + + } + break; + case 10: { + /* < */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a < b)); + + } + break; + case 11: { + /* << */ + + int c = (int)T0_POPi(); + uint32_t x = T0_POP(); + T0_PUSH(x << c); + + } + break; + case 12: { + /* <= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a <= b)); + + } + break; + case 13: { + /* <> */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a != b)); + + } + break; + case 14: { + /* = */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a == b)); + + } + break; + case 15: { + /* > */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a > b)); + + } + break; + case 16: { + /* >= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a >= b)); + + } + break; + case 17: { + /* >> */ + + int c = (int)T0_POPi(); + int32_t x = T0_POPi(); + T0_PUSHi(x >> c); + + } + break; + case 18: { + /* anchor-dn-append-name */ + + size_t len; + + len = T0_POP(); + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->append_name( + CTX->client_auth_vtable, ENG->pad, len); + } + + } + break; + case 19: { + /* anchor-dn-end-name */ + + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->end_name( + CTX->client_auth_vtable); + } + + } + break; + case 20: { + /* anchor-dn-end-name-list */ + + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->end_name_list( + CTX->client_auth_vtable); + } + + } + break; + case 21: { + /* anchor-dn-start-name */ + + size_t len; + + len = T0_POP(); + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->start_name( + CTX->client_auth_vtable, len); + } + + } + break; + case 22: { + /* anchor-dn-start-name-list */ + + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->start_name_list( + CTX->client_auth_vtable); + } + + } + break; + case 23: { + /* and */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a & b); + + } + break; + case 24: { + /* begin-cert */ + + if (ENG->chain_len == 0) { + T0_PUSHi(-1); + } else { + ENG->cert_cur = ENG->chain->data; + ENG->cert_len = ENG->chain->data_len; + ENG->chain ++; + ENG->chain_len --; + T0_PUSH(ENG->cert_len); + } + + } + break; + case 25: { + /* bzero */ + + size_t len = (size_t)T0_POP(); + void *addr = (unsigned char *)ENG + (size_t)T0_POP(); + memset(addr, 0, len); + + } + break; + case 26: { + /* can-output? */ + + T0_PUSHi(-(ENG->hlen_out > 0)); + + } + break; + case 27: { + /* co */ + T0_CO(); + } + break; + case 28: { + /* compute-Finished-inner */ + + int prf_id = T0_POP(); + int from_client = T0_POPi(); + unsigned char tmp[48]; + br_tls_prf_seed_chunk seed; + + br_tls_prf_impl prf = br_ssl_engine_get_PRF(ENG, prf_id); + seed.data = tmp; + if (ENG->session.version >= BR_TLS12) { + seed.len = br_multihash_out(&ENG->mhash, prf_id, tmp); + } else { + br_multihash_out(&ENG->mhash, br_md5_ID, tmp); + br_multihash_out(&ENG->mhash, br_sha1_ID, tmp + 16); + seed.len = 36; + } + prf(ENG->pad, 12, ENG->session.master_secret, + sizeof ENG->session.master_secret, + from_client ? "client finished" : "server finished", + 1, &seed); + + } + break; + case 29: { + /* copy-cert-chunk */ + + size_t clen; + + clen = ENG->cert_len; + if (clen > sizeof ENG->pad) { + clen = sizeof ENG->pad; + } + memcpy(ENG->pad, ENG->cert_cur, clen); + ENG->cert_cur += clen; + ENG->cert_len -= clen; + T0_PUSH(clen); + + } + break; + case 30: { + /* copy-protocol-name */ + + size_t idx = T0_POP(); + size_t len = strlen(ENG->protocol_names[idx]); + memcpy(ENG->pad, ENG->protocol_names[idx], len); + T0_PUSH(len); + + } + break; + case 31: { + /* data-get8 */ + + size_t addr = T0_POP(); + T0_PUSH(t0_datablock[addr]); + + } + break; + case 32: { + /* debug-session-ticket */ + + extern void __stdcall OutputDebugStringA(const char *); + extern int sprintf(char *, const char *, ...); + char buf[80]; + size_t len = T0_POP(); + sprintf(buf, "BearSSL: NewSessionTicket received (%u bytes)\r\n", + (unsigned)len); + OutputDebugStringA(buf); + + } + break; + case 33: { + /* discard-input */ + + ENG->hlen_in = 0; + + } + break; + case 34: { + /* do-client-sign */ + + size_t sig_len; + + sig_len = make_client_sign(CTX); + if (sig_len == 0) { + br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM); + T0_CO(); + } + T0_PUSH(sig_len); + + } + break; + case 35: { + /* do-ecdh */ + + unsigned prf_id = T0_POP(); + unsigned ecdhe = T0_POP(); + int x; + + x = make_pms_ecdh(CTX, ecdhe, prf_id); + if (x < 0) { + br_ssl_engine_fail(ENG, -x); + T0_CO(); + } else { + T0_PUSH(x); + } + + } + break; + case 36: { + /* do-rsa-encrypt */ + + int x; + + x = make_pms_rsa(CTX, T0_POP()); + if (x < 0) { + br_ssl_engine_fail(ENG, -x); + T0_CO(); + } else { + T0_PUSH(x); + } + + } + break; + case 37: { + /* do-static-ecdh */ + + unsigned prf_id = T0_POP(); + + if (make_pms_static_ecdh(CTX, prf_id) < 0) { + br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM); + T0_CO(); + } + + } + break; + case 38: { + /* drop */ + (void)T0_POP(); + } + break; + case 39: { + /* dup */ + T0_PUSH(T0_PEEK(0)); + } + break; + case 40: { + /* ext-ALPN-length */ + + size_t u, len; + + if (ENG->protocol_names_num == 0) { + T0_PUSH(0); + T0_RET(); + } + len = 6; + for (u = 0; u < ENG->protocol_names_num; u ++) { + len += 1 + strlen(ENG->protocol_names[u]); + } + T0_PUSH(len); + + } + break; + case 41: { + /* fail */ + + br_ssl_engine_fail(ENG, (int)T0_POPi()); + T0_CO(); + + } + break; + case 42: { + /* flush-record */ + + br_ssl_engine_flush_record(ENG); + + } + break; + case 43: { + /* get-client-chain */ + + uint32_t auth_types; + + auth_types = T0_POP(); + if (CTX->client_auth_vtable != NULL) { + br_ssl_client_certificate ux; + + (*CTX->client_auth_vtable)->choose(CTX->client_auth_vtable, + CTX, auth_types, &ux); + CTX->auth_type = (unsigned char)ux.auth_type; + CTX->hash_id = (unsigned char)ux.hash_id; + ENG->chain = ux.chain; + ENG->chain_len = ux.chain_len; + } else { + CTX->hash_id = 0; + ENG->chain_len = 0; + } + + } + break; + case 44: { + /* get-key-type-usages */ + + const br_x509_class *xc; + const br_x509_pkey *pk; + unsigned usages; + + xc = *(ENG->x509ctx); + pk = xc->get_pkey(ENG->x509ctx, &usages); + if (pk == NULL) { + T0_PUSH(0); + } else { + T0_PUSH(pk->key_type | usages); + } + + } + break; + case 45: { + /* get16 */ + + size_t addr = (size_t)T0_POP(); + T0_PUSH(*(uint16_t *)(void *)((unsigned char *)ENG + addr)); + + } + break; + case 46: { + /* get32 */ + + size_t addr = (size_t)T0_POP(); + T0_PUSH(*(uint32_t *)(void *)((unsigned char *)ENG + addr)); + + } + break; + case 47: { + /* get8 */ + + size_t addr = (size_t)T0_POP(); + T0_PUSH(*((unsigned char *)ENG + addr)); + + } + break; + case 48: { + /* has-input? */ + + T0_PUSHi(-(ENG->hlen_in != 0)); + + } + break; + case 49: { + /* memcmp */ + + size_t len = (size_t)T0_POP(); + void *addr2 = (unsigned char *)ENG + (size_t)T0_POP(); + void *addr1 = (unsigned char *)ENG + (size_t)T0_POP(); + int x = memcmp(addr1, addr2, len); + T0_PUSH((uint32_t)-(x == 0)); + + } + break; + case 50: { + /* memcpy */ + + size_t len = (size_t)T0_POP(); + void *src = (unsigned char *)ENG + (size_t)T0_POP(); + void *dst = (unsigned char *)ENG + (size_t)T0_POP(); + memcpy(dst, src, len); + + } + break; + case 51: { + /* mkrand */ + + size_t len = (size_t)T0_POP(); + void *addr = (unsigned char *)ENG + (size_t)T0_POP(); + br_hmac_drbg_generate(&ENG->rng, addr, len); + + } + break; + case 52: { + /* more-incoming-bytes? */ + + T0_PUSHi(ENG->hlen_in != 0 || !br_ssl_engine_recvrec_finished(ENG)); + + } + break; + case 53: { + /* multihash-init */ + + br_multihash_init(&ENG->mhash); + + } + break; + case 54: { + /* neg */ + + uint32_t a = T0_POP(); + T0_PUSH(-a); + + } + break; + case 55: { + /* not */ + + uint32_t a = T0_POP(); + T0_PUSH(~a); + + } + break; + case 56: { + /* or */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a | b); + + } + break; + case 57: { + /* over */ + T0_PUSH(T0_PEEK(1)); + } + break; + case 58: { + /* peek-hs-msg-type */ + + if (ENG->hlen_in > 0) { + T0_PUSH(*ENG->hbuf_in); + } else { + T0_PUSHi(-1); + } + + } + break; + case 59: { + /* read-chunk-native */ + + size_t clen = ENG->hlen_in; + if (clen > 0) { + uint32_t addr, len; + + len = T0_POP(); + addr = T0_POP(); + if ((size_t)len < clen) { + clen = (size_t)len; + } + memcpy((unsigned char *)ENG + addr, ENG->hbuf_in, clen); + if (ENG->record_type_in == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, ENG->hbuf_in, clen); + } + T0_PUSH(addr + (uint32_t)clen); + T0_PUSH(len - (uint32_t)clen); + ENG->hbuf_in += clen; + ENG->hlen_in -= clen; + } + + } + break; + case 60: { + /* read8-native */ + + if (ENG->hlen_in > 0) { + unsigned char x; + + x = *ENG->hbuf_in ++; + if (ENG->record_type_in == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, &x, 1); + } + T0_PUSH(x); + ENG->hlen_in --; + } else { + T0_PUSHi(-1); + } + + } + break; + case 61: { + /* set-server-curve */ + + const br_x509_class *xc; + const br_x509_pkey *pk; + + xc = *(ENG->x509ctx); + pk = xc->get_pkey(ENG->x509ctx, NULL); + CTX->server_curve = + (pk->key_type == BR_KEYTYPE_EC) ? pk->key.ec.curve : 0; + + } + break; + case 62: { + /* set16 */ + + size_t addr = (size_t)T0_POP(); + *(uint16_t *)(void *)((unsigned char *)ENG + addr) = (uint16_t)T0_POP(); + + } + break; + case 63: { + /* set32 */ + + size_t addr = (size_t)T0_POP(); + *(uint32_t *)(void *)((unsigned char *)ENG + addr) = (uint32_t)T0_POP(); + + } + break; + case 64: { + /* set8 */ + + size_t addr = (size_t)T0_POP(); + *((unsigned char *)ENG + addr) = (unsigned char)T0_POP(); + + } + break; + case 65: { + /* strlen */ + + void *str = (unsigned char *)ENG + (size_t)T0_POP(); + T0_PUSH((uint32_t)strlen(str)); + + } + break; + case 66: { + /* supported-curves */ + + uint32_t x = ENG->iec == NULL ? 0 : ENG->iec->supported_curves; + T0_PUSH(x); + + } + break; + case 67: { + /* supported-hash-functions */ + + int i; + unsigned x, num; + + x = 0; + num = 0; + for (i = br_sha1_ID; i <= br_sha512_ID; i ++) { + if (br_multihash_getimpl(&ENG->mhash, i)) { + x |= 1U << i; + num ++; + } + } + T0_PUSH(x); + T0_PUSH(num); + + } + break; + case 68: { + /* supports-ecdsa? */ + + T0_PUSHi(-(ENG->iecdsa != 0)); + + } + break; + case 69: { + /* supports-rsa-sign? */ + + T0_PUSHi(-(ENG->irsavrfy != 0)); + + } + break; + case 70: { + /* swap */ + T0_SWAP(); + } + break; + case 71: { + /* switch-aesccm-in */ + + int is_client, prf_id; + unsigned cipher_key_len, tag_len; + + tag_len = T0_POP(); + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_ccm_in(ENG, is_client, prf_id, + ENG->iaes_ctrcbc, cipher_key_len, tag_len); + + } + break; + case 72: { + /* switch-aesccm-out */ + + int is_client, prf_id; + unsigned cipher_key_len, tag_len; + + tag_len = T0_POP(); + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_ccm_out(ENG, is_client, prf_id, + ENG->iaes_ctrcbc, cipher_key_len, tag_len); + + } + break; + case 73: { + /* switch-aesgcm-in */ + + int is_client, prf_id; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_gcm_in(ENG, is_client, prf_id, + ENG->iaes_ctr, cipher_key_len); + + } + break; + case 74: { + /* switch-aesgcm-out */ + + int is_client, prf_id; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_gcm_out(ENG, is_client, prf_id, + ENG->iaes_ctr, cipher_key_len); + + } + break; + case 75: { + /* switch-cbc-in */ + + int is_client, prf_id, mac_id, aes; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + aes = T0_POP(); + mac_id = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_cbc_in(ENG, is_client, prf_id, mac_id, + aes ? ENG->iaes_cbcdec : ENG->ides_cbcdec, cipher_key_len); + + } + break; + case 76: { + /* switch-cbc-out */ + + int is_client, prf_id, mac_id, aes; + unsigned cipher_key_len; + + cipher_key_len = T0_POP(); + aes = T0_POP(); + mac_id = T0_POP(); + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_cbc_out(ENG, is_client, prf_id, mac_id, + aes ? ENG->iaes_cbcenc : ENG->ides_cbcenc, cipher_key_len); + + } + break; + case 77: { + /* switch-chapol-in */ + + int is_client, prf_id; + + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_chapol_in(ENG, is_client, prf_id); + + } + break; + case 78: { + /* switch-chapol-out */ + + int is_client, prf_id; + + prf_id = T0_POP(); + is_client = T0_POP(); + br_ssl_engine_switch_chapol_out(ENG, is_client, prf_id); + + } + break; + case 79: { + /* test-protocol-name */ + + size_t len = T0_POP(); + size_t u; + + for (u = 0; u < ENG->protocol_names_num; u ++) { + const char *name; + + name = ENG->protocol_names[u]; + if (len == strlen(name) && memcmp(ENG->pad, name, len) == 0) { + T0_PUSH(u); + T0_RET(); + } + } + T0_PUSHi(-1); + + } + break; + case 80: { + /* total-chain-length */ + + size_t u; + uint32_t total; + + total = 0; + for (u = 0; u < ENG->chain_len; u ++) { + total += 3 + (uint32_t)ENG->chain[u].data_len; + } + T0_PUSH(total); + + } + break; + case 81: { + /* u>> */ + + int c = (int)T0_POPi(); + uint32_t x = T0_POP(); + T0_PUSH(x >> c); + + } + break; + case 82: { + /* verify-SKE-sig */ + + size_t sig_len = T0_POP(); + int use_rsa = T0_POPi(); + int hash = T0_POPi(); + + T0_PUSH(verify_SKE_sig(CTX, hash, use_rsa, sig_len)); + + } + break; + case 83: { + /* write-blob-chunk */ + + size_t clen = ENG->hlen_out; + if (clen > 0) { + uint32_t addr, len; + + len = T0_POP(); + addr = T0_POP(); + if ((size_t)len < clen) { + clen = (size_t)len; + } + memcpy(ENG->hbuf_out, (unsigned char *)ENG + addr, clen); + if (ENG->record_type_out == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, ENG->hbuf_out, clen); + } + T0_PUSH(addr + (uint32_t)clen); + T0_PUSH(len - (uint32_t)clen); + ENG->hbuf_out += clen; + ENG->hlen_out -= clen; + } + + } + break; + case 84: { + /* write8-native */ + + unsigned char x; + + x = (unsigned char)T0_POP(); + if (ENG->hlen_out > 0) { + if (ENG->record_type_out == BR_SSL_HANDSHAKE) { + br_multihash_update(&ENG->mhash, &x, 1); + } + *ENG->hbuf_out ++ = x; + ENG->hlen_out --; + T0_PUSHi(-1); + } else { + T0_PUSHi(0); + } + + } + break; + case 85: { + /* x509-append */ + + const br_x509_class *xc; + size_t len; + + xc = *(ENG->x509ctx); + len = T0_POP(); + xc->append(ENG->x509ctx, ENG->pad, len); + + } + break; + case 86: { + /* x509-end-cert */ + + const br_x509_class *xc; + + xc = *(ENG->x509ctx); + xc->end_cert(ENG->x509ctx); + + } + break; + case 87: { + /* x509-end-chain */ + + const br_x509_class *xc; + + xc = *(ENG->x509ctx); + T0_PUSH(xc->end_chain(ENG->x509ctx)); + + } + break; + case 88: { + /* x509-start-cert */ + + const br_x509_class *xc; + + xc = *(ENG->x509ctx); + xc->start_cert(ENG->x509ctx, T0_POP()); + + } + break; + case 89: { + /* x509-start-chain */ + + const br_x509_class *xc; + uint32_t bc; + + bc = T0_POP(); + xc = *(ENG->x509ctx); + xc->start_chain(ENG->x509ctx, bc ? ENG->server_name : NULL); + + } + break; + } + + } else { + T0_ENTER(ip, rp, t0x); + } + } +t0_exit: + ((t0_context *)t0ctx)->dp = dp; + ((t0_context *)t0ctx)->rp = rp; + ((t0_context *)t0ctx)->ip = ip; +} diff --git a/libcurl/lib/vtls/ssl_hs_client.t0 b/libcurl/lib/vtls/ssl_hs_client.t0 new file mode 100644 index 0000000..69a1d94 --- /dev/null +++ b/libcurl/lib/vtls/ssl_hs_client.t0 @@ -0,0 +1,1398 @@ +\ Copyright (c) 2016 Thomas Pornin +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +\ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +\ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +\ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +\ SOFTWARE. + +\ ---------------------------------------------------------------------- +\ Handshake processing code, for the client. +\ The common T0 code (ssl_hs_common.t0) shall be read first. + +preamble { + +/* + * This macro evaluates to a pointer to the client context, under that + * specific name. It must be noted that since the engine context is the + * first field of the br_ssl_client_context structure ('eng'), then + * pointers values of both types are interchangeable, modulo an + * appropriate cast. This also means that "addresses" computed as offsets + * within the structure work for both kinds of context. + */ +#define CTX ((br_ssl_client_context *)ENG) + +/* + * Generate the pre-master secret for RSA key exchange, and encrypt it + * with the server's public key. Returned value is either the encrypted + * data length (in bytes), or -x on error, with 'x' being an error code. + * + * This code assumes that the public key has been already verified (it + * was properly obtained by the X.509 engine, and it has the right type, + * i.e. it is of type RSA and suitable for encryption). + */ +static int +make_pms_rsa(br_ssl_client_context *ctx, int prf_id) +{ + const br_x509_class **xc; + const br_x509_pkey *pk; + const unsigned char *n; + unsigned char *pms; + size_t nlen, u; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + + /* + * Compute actual RSA key length, in case there are leading zeros. + */ + n = pk->key.rsa.n; + nlen = pk->key.rsa.nlen; + while (nlen > 0 && *n == 0) { + n ++; + nlen --; + } + + /* + * We need at least 59 bytes (48 bytes for pre-master secret, and + * 11 bytes for the PKCS#1 type 2 padding). Note that the X.509 + * minimal engine normally blocks RSA keys shorter than 128 bytes, + * so this is mostly for public keys provided explicitly by the + * caller. + */ + if (nlen < 59) { + return -BR_ERR_X509_WEAK_PUBLIC_KEY; + } + if (nlen > sizeof ctx->eng.pad) { + return -BR_ERR_LIMIT_EXCEEDED; + } + + /* + * Make PMS. + */ + pms = ctx->eng.pad + nlen - 48; + br_enc16be(pms, ctx->eng.version_max); + br_hmac_drbg_generate(&ctx->eng.rng, pms + 2, 46); + br_ssl_engine_compute_master(&ctx->eng, prf_id, pms, 48); + + /* + * Apply PKCS#1 type 2 padding. + */ + ctx->eng.pad[0] = 0x00; + ctx->eng.pad[1] = 0x02; + ctx->eng.pad[nlen - 49] = 0x00; + br_hmac_drbg_generate(&ctx->eng.rng, ctx->eng.pad + 2, nlen - 51); + for (u = 2; u < nlen - 49; u ++) { + while (ctx->eng.pad[u] == 0) { + br_hmac_drbg_generate(&ctx->eng.rng, + &ctx->eng.pad[u], 1); + } + } + + /* + * Compute RSA encryption. + */ + if (!ctx->irsapub(ctx->eng.pad, nlen, &pk->key.rsa)) { + return -BR_ERR_LIMIT_EXCEEDED; + } + return (int)nlen; +} + +/* + * OID for hash functions in RSA signatures. + */ +static const unsigned char *HASH_OID[] = { + BR_HASH_OID_SHA1, + BR_HASH_OID_SHA224, + BR_HASH_OID_SHA256, + BR_HASH_OID_SHA384, + BR_HASH_OID_SHA512 +}; + +/* + * Check the RSA signature on the ServerKeyExchange message. + * + * hash hash function ID (2 to 6), or 0 for MD5+SHA-1 (with RSA only) + * use_rsa non-zero for RSA signature, zero for ECDSA + * sig_len signature length (in bytes); signature value is in the pad + * + * Returned value is 0 on success, or an error code. + */ +static int +verify_SKE_sig(br_ssl_client_context *ctx, + int hash, int use_rsa, size_t sig_len) +{ + const br_x509_class **xc; + const br_x509_pkey *pk; + br_multihash_context mhc; + unsigned char hv[64], head[4]; + size_t hv_len; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + br_multihash_zero(&mhc); + br_multihash_copyimpl(&mhc, &ctx->eng.mhash); + br_multihash_init(&mhc); + br_multihash_update(&mhc, + ctx->eng.client_random, sizeof ctx->eng.client_random); + br_multihash_update(&mhc, + ctx->eng.server_random, sizeof ctx->eng.server_random); + head[0] = 3; + head[1] = 0; + head[2] = ctx->eng.ecdhe_curve; + head[3] = ctx->eng.ecdhe_point_len; + br_multihash_update(&mhc, head, sizeof head); + br_multihash_update(&mhc, + ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len); + if (hash) { + hv_len = br_multihash_out(&mhc, hash, hv); + if (hv_len == 0) { + return BR_ERR_INVALID_ALGORITHM; + } + } else { + if (!br_multihash_out(&mhc, br_md5_ID, hv) + || !br_multihash_out(&mhc, br_sha1_ID, hv + 16)) + { + return BR_ERR_INVALID_ALGORITHM; + } + hv_len = 36; + } + if (use_rsa) { + unsigned char tmp[64]; + const unsigned char *hash_oid; + + if (hash) { + hash_oid = HASH_OID[hash - 2]; + } else { + hash_oid = NULL; + } + if (!ctx->eng.irsavrfy(ctx->eng.pad, sig_len, + hash_oid, hv_len, &pk->key.rsa, tmp) + || memcmp(tmp, hv, hv_len) != 0) + { + return BR_ERR_BAD_SIGNATURE; + } + } else { + if (!ctx->eng.iecdsa(ctx->eng.iec, hv, hv_len, &pk->key.ec, + ctx->eng.pad, sig_len)) + { + return BR_ERR_BAD_SIGNATURE; + } + } + return 0; +} + +/* + * Perform client-side ECDH (or ECDHE). The point that should be sent to + * the server is written in the pad; returned value is either the point + * length (in bytes), or -x on error, with 'x' being an error code. + * + * The point _from_ the server is taken from ecdhe_point[] if 'ecdhe' + * is non-zero, or from the X.509 engine context if 'ecdhe' is zero + * (for static ECDH). + */ +static int +make_pms_ecdh(br_ssl_client_context *ctx, unsigned ecdhe, int prf_id) +{ + int curve; + unsigned char key[66], point[133]; + const unsigned char *order, *point_src; + size_t glen, olen, point_len, xoff, xlen; + unsigned char mask; + + if (ecdhe) { + curve = ctx->eng.ecdhe_curve; + point_src = ctx->eng.ecdhe_point; + point_len = ctx->eng.ecdhe_point_len; + } else { + const br_x509_class **xc; + const br_x509_pkey *pk; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + curve = pk->key.ec.curve; + point_src = pk->key.ec.q; + point_len = pk->key.ec.qlen; + } + if ((ctx->eng.iec->supported_curves & ((uint32_t)1 << curve)) == 0) { + return -BR_ERR_INVALID_ALGORITHM; + } + + /* + * We need to generate our key, as a non-zero random value which + * is lower than the curve order, in a "large enough" range. We + * force top bit to 0 and bottom bit to 1, which guarantees that + * the value is in the proper range. + */ + order = ctx->eng.iec->order(curve, &olen); + mask = 0xFF; + while (mask >= order[0]) { + mask >>= 1; + } + br_hmac_drbg_generate(&ctx->eng.rng, key, olen); + key[0] &= mask; + key[olen - 1] |= 0x01; + + /* + * Compute the common ECDH point, whose X coordinate is the + * pre-master secret. + */ + ctx->eng.iec->generator(curve, &glen); + if (glen != point_len) { + return -BR_ERR_INVALID_ALGORITHM; + } + + memcpy(point, point_src, glen); + if (!ctx->eng.iec->mul(point, glen, key, olen, curve)) { + return -BR_ERR_INVALID_ALGORITHM; + } + + /* + * The pre-master secret is the X coordinate. + */ + xoff = ctx->eng.iec->xoff(curve, &xlen); + br_ssl_engine_compute_master(&ctx->eng, prf_id, point + xoff, xlen); + + ctx->eng.iec->mulgen(point, key, olen, curve); + memcpy(ctx->eng.pad, point, glen); + return (int)glen; +} + +/* + * Perform full static ECDH. This occurs only in the context of client + * authentication with certificates: the server uses an EC public key, + * the cipher suite is of type ECDH (not ECDHE), the server requested a + * client certificate and accepts static ECDH, the client has a + * certificate with an EC public key in the same curve, and accepts + * static ECDH as well. + * + * Returned value is 0 on success, -1 on error. + */ +static int +make_pms_static_ecdh(br_ssl_client_context *ctx, int prf_id) +{ + unsigned char point[133]; + size_t point_len; + const br_x509_class **xc; + const br_x509_pkey *pk; + + xc = ctx->eng.x509ctx; + pk = (*xc)->get_pkey(xc, NULL); + point_len = pk->key.ec.qlen; + if (point_len > sizeof point) { + return -1; + } + memcpy(point, pk->key.ec.q, point_len); + if (!(*ctx->client_auth_vtable)->do_keyx( + ctx->client_auth_vtable, point, &point_len)) + { + return -1; + } + br_ssl_engine_compute_master(&ctx->eng, + prf_id, point, point_len); + return 0; +} + +/* + * Compute the client-side signature. This is invoked only when a + * signature-based client authentication was selected. The computed + * signature is in the pad; its length (in bytes) is returned. On + * error, 0 is returned. + */ +static size_t +make_client_sign(br_ssl_client_context *ctx) +{ + size_t hv_len; + + /* + * Compute hash of handshake messages so far. This "cannot" fail + * because the list of supported hash functions provided to the + * client certificate handler was trimmed to include only the + * hash functions that the multi-hasher supports. + */ + if (ctx->hash_id) { + hv_len = br_multihash_out(&ctx->eng.mhash, + ctx->hash_id, ctx->eng.pad); + } else { + br_multihash_out(&ctx->eng.mhash, + br_md5_ID, ctx->eng.pad); + br_multihash_out(&ctx->eng.mhash, + br_sha1_ID, ctx->eng.pad + 16); + hv_len = 36; + } + return (*ctx->client_auth_vtable)->do_sign( + ctx->client_auth_vtable, ctx->hash_id, hv_len, + ctx->eng.pad, sizeof ctx->eng.pad); +} + +} + +\ ======================================================================= + +: addr-ctx: + next-word { field } + "addr-" field + 0 1 define-word + 0 8191 "offsetof(br_ssl_client_context, " field + ")" + make-CX + postpone literal postpone ; ; + +addr-ctx: min_clienthello_len +addr-ctx: hashes +addr-ctx: auth_type +addr-ctx: hash_id + +\ Length of the Secure Renegotiation extension. This is 5 for the +\ first handshake, 17 for a renegotiation (if the server supports the +\ extension), or 0 if we know that the server does not support the +\ extension. +: ext-reneg-length ( -- n ) + addr-reneg get8 dup if 1 - 17 * else drop 5 then ; + +\ Length of SNI extension. +: ext-sni-length ( -- len ) + addr-server_name strlen dup if 9 + then ; + +\ Length of Maximum Fragment Length extension. +: ext-frag-length ( -- len ) + addr-log_max_frag_len get8 14 = if 0 else 5 then ; + +\ Length of Signatures extension. +: ext-signatures-length ( -- len ) + supported-hash-functions { num } drop 0 + supports-rsa-sign? if num + then + supports-ecdsa? if num + then + dup if 1 << 6 + then ; + +\ Write supported hash functions ( sign -- ) +: write-hashes + { sign } + supported-hash-functions drop + \ We advertise hash functions in the following preference order: + \ SHA-256 SHA-224 SHA-384 SHA-512 SHA-1 + \ Rationale: + \ -- SHA-256 and SHA-224 are more efficient on 32-bit architectures + \ -- SHA-1 is less than ideally collision-resistant + dup 0x10 and if 4 write8 sign write8 then + dup 0x08 and if 3 write8 sign write8 then + dup 0x20 and if 5 write8 sign write8 then + dup 0x40 and if 6 write8 sign write8 then + 0x04 and if 2 write8 sign write8 then ; + +\ Length of Supported Curves extension. +: ext-supported-curves-length ( -- len ) + supported-curves dup if + 0 { x } + begin dup while + dup 1 and x + >x + 1 >> + repeat + drop x 1 << 6 + + then ; + +\ Length of Supported Point Formats extension. +: ext-point-format-length ( -- len ) + supported-curves if 6 else 0 then ; + +\ Length of ALPN extension. +cc: ext-ALPN-length ( -- len ) { + size_t u, len; + + if (ENG->protocol_names_num == 0) { + T0_PUSH(0); + T0_RET(); + } + len = 6; + for (u = 0; u < ENG->protocol_names_num; u ++) { + len += 1 + strlen(ENG->protocol_names[u]); + } + T0_PUSH(len); +} + +\ Length of Session Ticket extension (RFC 5077). +\ Always sent (to signal support). If we have a stored ticket, include it. +: ext-session-ticket-length ( -- len ) + addr-session_ticket_len get16 4 + ; + +\ Write handshake message: ClientHello +: write-ClientHello ( -- ) + { ; total-ext-length } + + \ Compute length for extensions (without the general two-byte header). + \ This does not take padding extension into account. + ext-reneg-length ext-sni-length + ext-frag-length + + ext-signatures-length + + ext-supported-curves-length + ext-point-format-length + + ext-ALPN-length + + ext-session-ticket-length + + >total-ext-length + + \ ClientHello type + 1 write8 + + \ Compute and write length + 39 addr-session_id_len get8 + addr-suites_num get8 1 << + + total-ext-length if 2+ total-ext-length + then + \ Compute padding (if requested). + addr-min_clienthello_len get16 over - dup 0> if + \ We well add a Pad ClientHello extension, which has its + \ own header (4 bytes) and might be the only extension + \ (2 extra bytes for the extension list header). + total-ext-length ifnot swap 2+ swap 2- then + \ Account for the extension header. + 4 - dup 0< if drop 0 then + \ Adjust total extension length. + dup 4 + total-ext-length + >total-ext-length + \ Adjust ClientHello length. + swap 4 + over + swap + else + drop + -1 + then + { ext-padding-amount } + write24 + + \ Protocol version + addr-version_max get16 write16 + + \ Client random + addr-client_random 4 bzero + addr-client_random 4 + 28 mkrand + addr-client_random 32 write-blob + + \ Session ID + addr-session_id addr-session_id_len get8 write-blob-head8 + + \ Supported cipher suites. We also check here that we indeed + \ support all these suites. + addr-suites_num get8 dup 1 << write16 + addr-suites_buf swap + begin + dup while 1- + over get16 + dup suite-supported? ifnot ERR_BAD_CIPHER_SUITE fail then + write16 + swap 2+ swap + repeat + 2drop + + \ Compression methods (only "null" compression) + 1 write8 0 write8 + + \ Extensions + total-ext-length if + total-ext-length write16 + ext-reneg-length if + 0xFF01 write16 \ extension type (0xFF01) + addr-saved_finished + ext-reneg-length 4 - dup write16 \ extension length + 1- write-blob-head8 \ verify data + then + ext-sni-length if + 0x0000 write16 \ extension type (0) + addr-server_name + ext-sni-length 4 - dup write16 \ extension length + 2 - dup write16 \ ServerNameList length + 0 write8 \ name type: host_name + 3 - write-blob-head16 \ the name itself + then + ext-frag-length if + 0x0001 write16 \ extension type (1) + 0x0001 write16 \ extension length + addr-log_max_frag_len get8 8 - write8 + then + ext-signatures-length if + 0x000D write16 \ extension type (13) + ext-signatures-length 4 - dup write16 \ extension length + 2 - write16 \ list length + supports-ecdsa? if 3 write-hashes then + supports-rsa-sign? if 1 write-hashes then + then + \ TODO: add an API to specify preference order for curves. + \ Right now we send Curve25519 first, then other curves in + \ increasing ID values (hence P-256 in second). + ext-supported-curves-length dup if + 0x000A write16 \ extension type (10) + 4 - dup write16 \ extension length + 2- write16 \ list length + supported-curves 0 + dup 0x20000000 and if + 0xDFFFFFFF and 29 write16 + then + begin dup 32 < while + dup2 >> 1 and if dup write16 then + 1+ + repeat + 2drop + else + drop + then + ext-point-format-length if + 0x000B write16 \ extension type (11) + 0x0002 write16 \ extension length + 0x0100 write16 \ value: 1 format: uncompressed + then + ext-ALPN-length dup if + 0x0010 write16 \ extension type (16) + 4 - dup write16 \ extension length + 2- write16 \ list length + addr-protocol_names_num get16 0 + begin + dup2 > while + dup copy-protocol-name + dup write8 addr-pad swap write-blob + 1+ + repeat + 2drop + else + drop + then + \ Session Ticket extension (RFC 5077). + 0x0023 write16 \ extension type (35) + addr-session_ticket_len get16 + dup write16 \ extension data length + dup if + addr-session_ticket swap write-blob + else + drop + then + ext-padding-amount 0< ifnot + 0x0015 write16 \ extension value (21) + ext-padding-amount + dup write16 \ extension length + begin dup while + 1- 0 write8 repeat \ value (only zeros) + drop + then + then + ; + +\ ======================================================================= + +\ Parse server SNI extension. If present, then it should be empty. +: read-server-sni ( lim -- lim ) + read16 if ERR_BAD_SNI fail then ; + +\ Parse server Max Fragment Length extension. If present, then it should +\ advertise the same length as the client. Note that whether the server +\ sends it or not changes nothing for us: we won't send any record larger +\ than the advertised value anyway, and we will accept incoming records +\ up to our input buffer length. +: read-server-frag ( lim -- lim ) + read16 1 = ifnot ERR_BAD_FRAGLEN fail then + read8 8 + addr-log_max_frag_len get8 = ifnot ERR_BAD_FRAGLEN fail then ; + +\ Parse server Secure Renegotiation extension. This is called only if +\ the client sent that extension, so we only have two cases to +\ distinguish: first handshake, and renegotiation; in the latter case, +\ we know that the server supports the extension, otherwise the client +\ would not have sent it. +: read-server-reneg ( lim -- lim ) + read16 + addr-reneg get8 ifnot + \ "reneg" is 0, so this is a first handshake. The server's + \ extension MUST be empty. We also learn that the server + \ supports the extension. + 1 = ifnot ERR_BAD_SECRENEG fail then + read8 0 = ifnot ERR_BAD_SECRENEG fail then + 2 addr-reneg set8 + else + \ "reneg" is non-zero, and we sent an extension, so it must + \ be 2 and this is a renegotiation. We must verify that + \ the extension contents have length exactly 24 bytes and + \ match the saved client and server "Finished". + 25 = ifnot ERR_BAD_SECRENEG fail then + read8 24 = ifnot ERR_BAD_SECRENEG fail then + addr-pad 24 read-blob + addr-saved_finished addr-pad 24 memcmp ifnot + ERR_BAD_SECRENEG fail + then + then ; + +\ Read the ALPN extension from the server. It must contain a single name, +\ and that name must match one of our names. +: read-ALPN-from-server ( lim -- lim ) + \ Extension contents length. + read16 open-elt + \ Length of list of names. + read16 open-elt + \ There should be a single name. + read8 addr-pad swap dup { len } read-blob + close-elt + close-elt + len test-protocol-name dup 0< if + 3 flag? if ERR_UNEXPECTED fail then + drop + else + 1+ addr-selected_protocol set16 + then ; + +\ Save a value in a 16-bit field, or check it in case of session resumption. +: check-resume ( val addr resume -- ) + if get16 = ifnot ERR_RESUME_MISMATCH fail then else set16 then ; + +cc: DEBUG-BLOB ( addr len -- ) { + extern int printf(const char *fmt, ...); + + size_t len = T0_POP(); + unsigned char *buf = (unsigned char *)CTX + T0_POP(); + size_t u; + + printf("BLOB:"); + for (u = 0; u < len; u ++) { + if (u % 16 == 0) { + printf("\n "); + } + printf(" %02x", buf[u]); + } + printf("\n"); +} + +\ Parse incoming ServerHello. Returned value is true (-1) on session +\ resumption. +: read-ServerHello ( -- bool ) + \ Get header, and check message type. + read-handshake-header 2 = ifnot ERR_UNEXPECTED fail then + + \ Get protocol version. + read16 { version } + version addr-version_min get16 < version addr-version_max get16 > or if + ERR_UNSUPPORTED_VERSION fail + then + + \ Enforce chosen version for subsequent records in both directions. + version addr-version_in get16 <> if ERR_BAD_VERSION fail then + version addr-version_out set16 + + \ Server random. + addr-server_random 32 read-blob + + \ The "session resumption" flag. + 0 { resume } + + \ Session ID. + read8 { idlen } + idlen 32 > if ERR_OVERSIZED_ID fail then + addr-pad idlen read-blob + idlen addr-session_id_len get8 = idlen 0 > and if + addr-session_id addr-pad idlen memcmp if + \ Server session ID is non-empty and matches what + \ we sent, so this is a session resumption. + -1 >resume + then + then + addr-session_id addr-pad idlen memcpy + idlen addr-session_id_len set8 + + \ Record version. + version addr-version resume check-resume + + \ Cipher suite. We check that it is part of the list of cipher + \ suites that we advertised. + read16 + dup scan-suite 0< if ERR_BAD_CIPHER_SUITE fail then + \ Also check that the cipher suite is compatible with the + \ announced version: suites that don't use HMAC/SHA-1 are + \ for TLS-1.2 only, not older versions. + dup use-tls12? version 0x0303 < and if ERR_BAD_CIPHER_SUITE fail then + addr-cipher_suite resume check-resume + + \ Compression method. Should be 0 (no compression). + read8 if ERR_BAD_COMPRESSION fail then + + \ Parse extensions (if any). If there is no extension, then the + \ read limit (on the TOS) should be 0 at that point. + dup if + \ Length of extension list. + \ message size. + read16 open-elt + + \ Enumerate extensions. For each of them, check that we + \ sent an extension of that type, and did not see it + \ yet; and then process it. + ext-sni-length { ok-sni } + ext-reneg-length { ok-reneg } + ext-frag-length { ok-frag } + ext-signatures-length { ok-signatures } + ext-supported-curves-length { ok-curves } + ext-point-format-length { ok-points } + ext-session-ticket-length { ok-session-ticket } + ext-ALPN-length { ok-ALPN } + begin dup while + read16 + case + \ Server Name Indication. The server may + \ send such an extension if it uses the SNI + \ from the client, but that "response + \ extension" is supposed to be empty. + 0x0000 of + ok-sni ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-sni + read-server-sni + endof + + \ Max Frag Length. The contents shall be + \ a single byte whose value matches the one + \ sent by the client. + 0x0001 of + ok-frag ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-frag + read-server-frag + endof + + \ Secure Renegotiation. + 0xFF01 of + ok-reneg ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-reneg + read-server-reneg + endof + + \ Signature Algorithms. + \ Normally, the server should never send this + \ extension (so says RFC 5246 #7.4.1.4.1), + \ but some existing servers do. + 0x000D of + ok-signatures ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-signatures + read-ignore-16 + endof + + \ Supported Curves. + 0x000A of + ok-curves ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-curves + read-ignore-16 + endof + + \ Supported Point Formats. + 0x000B of + ok-points ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-points + read-ignore-16 + endof + + \ ALPN. + 0x0010 of + ok-ALPN ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-ALPN + read-ALPN-from-server + endof + + \ Session Ticket (RFC 5077). + 0x0023 of + ok-session-ticket ifnot + ERR_EXTRA_EXTENSION fail + then + 0 >ok-session-ticket + read-ignore-16 + 1 addr-session_ticket_ok set8 + endof + + ERR_EXTRA_EXTENSION fail + endcase + repeat + + \ If we sent a secure renegotiation extension but did not + \ receive a response, then the server does not support + \ secure renegotiation. This is a hard failure if this + \ is a renegotiation. + ok-reneg if + ok-reneg 5 > if ERR_BAD_SECRENEG fail then + 1 addr-reneg set8 + then + close-elt + else + \ No extension received at all, so the server does not + \ support secure renegotiation. This is a hard failure + \ if the server was previously known to support it (i.e. + \ this is a renegotiation). + ext-reneg-length 5 > if ERR_BAD_SECRENEG fail then + 1 addr-reneg set8 + then + close-elt + resume + ; + +cc: set-server-curve ( -- ) { + const br_x509_class *xc; + const br_x509_pkey *pk; + + xc = *(ENG->x509ctx); + pk = xc->get_pkey(ENG->x509ctx, NULL); + CTX->server_curve = + (pk->key_type == BR_KEYTYPE_EC) ? pk->key.ec.curve : 0; +} + +\ Read Certificate message from server. +: read-Certificate-from-server ( -- ) + addr-cipher_suite get16 expected-key-type + -1 read-Certificate + dup 0< if neg fail then + dup ifnot ERR_UNEXPECTED fail then + over and <> if ERR_WRONG_KEY_USAGE fail then + + \ Set server curve (used for static ECDH). + set-server-curve ; + +\ Verify signature on ECDHE point sent by the server. +\ 'hash' is the hash function to use (1 to 6, or 0 for RSA with MD5+SHA-1) +\ 'use-rsa' is 0 for ECDSA, -1 for for RSA +\ 'sig-len' is the signature length (in bytes) +\ The signature itself is in the pad. +cc: verify-SKE-sig ( hash use-rsa sig-len -- err ) { + size_t sig_len = T0_POP(); + int use_rsa = T0_POPi(); + int hash = T0_POPi(); + + T0_PUSH(verify_SKE_sig(CTX, hash, use_rsa, sig_len)); +} + +\ Parse ServerKeyExchange +: read-ServerKeyExchange ( -- ) + \ Get header, and check message type. + read-handshake-header 12 = ifnot ERR_UNEXPECTED fail then + + \ We expect a named curve, and we must support it. + read8 3 = ifnot ERR_INVALID_ALGORITHM fail then + read16 dup addr-ecdhe_curve set8 + dup 32 >= if ERR_INVALID_ALGORITHM fail then + supported-curves swap >> 1 and ifnot ERR_INVALID_ALGORITHM fail then + + \ Read the server point. + read8 + dup 133 > if ERR_INVALID_ALGORITHM fail then + dup addr-ecdhe_point_len set8 + addr-ecdhe_point swap read-blob + + \ If using TLS-1.2+, then the hash function and signature algorithm + \ are explicitly provided; the signature algorithm must match what + \ the cipher suite specifies. With TLS-1.0 and 1.1, the signature + \ algorithm is inferred from the cipher suite, and the hash is + \ either MD5+SHA-1 (for RSA signatures) or SHA-1 (for ECDSA). + addr-version get16 0x0303 >= { tls1.2+ } + addr-cipher_suite get16 use-rsa-ecdhe? { use-rsa } + 2 { hash } + tls1.2+ if + \ Read hash function; accept only the SHA-* identifiers + \ (from SHA-1 to SHA-512, no MD5 here). + read8 + dup dup 2 < swap 6 > or if ERR_INVALID_ALGORITHM fail then + >hash + read8 + \ Get expected signature algorithm and compare with what + \ the server just sent. Expected value is 1 for RSA, 3 + \ for ECDSA. Note that 'use-rsa' evaluates to -1 for RSA, + \ 0 for ECDSA. + use-rsa 1 << 3 + = ifnot ERR_INVALID_ALGORITHM fail then + else + \ For MD5+SHA-1, we set 'hash' to 0. + use-rsa if 0 >hash then + then + + \ Read signature into the pad. + read16 dup { sig-len } + + dup 512 > if ERR_LIMIT_EXCEEDED fail then + addr-pad swap read-blob + + \ Verify signature. + hash use-rsa sig-len verify-SKE-sig + dup if fail then drop + + close-elt ; + +\ Client certificate: start processing of anchor names. +cc: anchor-dn-start-name-list ( -- ) { + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->start_name_list( + CTX->client_auth_vtable); + } +} + +\ Client certificate: start a new anchor DN (length is 16-bit). +cc: anchor-dn-start-name ( length -- ) { + size_t len; + + len = T0_POP(); + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->start_name( + CTX->client_auth_vtable, len); + } +} + +\ Client certificate: push some data for current anchor DN. +cc: anchor-dn-append-name ( length -- ) { + size_t len; + + len = T0_POP(); + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->append_name( + CTX->client_auth_vtable, ENG->pad, len); + } +} + +\ Client certificate: end current anchor DN. +cc: anchor-dn-end-name ( -- ) { + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->end_name( + CTX->client_auth_vtable); + } +} + +\ Client certificate: end list of anchor DN. +cc: anchor-dn-end-name-list ( -- ) { + if (CTX->client_auth_vtable != NULL) { + (*CTX->client_auth_vtable)->end_name_list( + CTX->client_auth_vtable); + } +} + +\ Client certificate: obtain the client certificate chain. +cc: get-client-chain ( auth_types -- ) { + uint32_t auth_types; + + auth_types = T0_POP(); + if (CTX->client_auth_vtable != NULL) { + br_ssl_client_certificate ux; + + (*CTX->client_auth_vtable)->choose(CTX->client_auth_vtable, + CTX, auth_types, &ux); + CTX->auth_type = (unsigned char)ux.auth_type; + CTX->hash_id = (unsigned char)ux.hash_id; + ENG->chain = ux.chain; + ENG->chain_len = ux.chain_len; + } else { + CTX->hash_id = 0; + ENG->chain_len = 0; + } +} + +\ Parse CertificateRequest. Header has already been read. +: read-contents-CertificateRequest ( lim -- ) + \ Read supported client authentication types. We keep only + \ RSA, ECDSA, and ECDH. + 0 { auth_types } + read8 open-elt + begin dup while + read8 case + 1 of 0x0000FF endof + 64 of 0x00FF00 endof + 65 of 0x010000 endof + 66 of 0x020000 endof + 0 swap + endcase + auth_types or >auth_types + repeat + close-elt + + \ Full static ECDH is allowed only if the cipher suite is ECDH + \ (not ECDHE). It would be theoretically feasible to use static + \ ECDH on the client side with an ephemeral key pair from the + \ server, but RFC 4492 (section 3) forbids it because ECDHE suites + \ are supposed to provide forward secrecy, and static ECDH would + \ negate that property. + addr-cipher_suite get16 use-ecdh? ifnot + auth_types 0xFFFF and >auth_types + then + + \ Note: if the cipher suite is ECDH, then the X.509 validation + \ engine was invoked with the BR_KEYTYPE_EC | BR_KEYTYPE_KEYX + \ combination, so the server's public key has already been + \ checked to be fit for a key exchange. + + \ With TLS 1.2: + \ - rsa_fixed_ecdh and ecdsa_fixed_ecdh are synoymous. + \ - There is an explicit list of supported sign+hash. + \ With TLS 1.0, + addr-version get16 0x0303 >= if + \ With TLS 1.2: + \ - There is an explicit list of supported sign+hash. + \ - The ECDH flags must be adjusted for RSA/ECDSA + \ support. + read-list-sign-algos dup addr-hashes set32 + + \ Trim down the list depending on what hash functions + \ we support (since the hashing itself is done by the SSL + \ engine, not by the certificate handler). + supported-hash-functions drop dup 8 << or 0x030000 or and + + auth_types and + auth_types 0x030000 and if + dup 0x0000FF and if 0x010000 or then + dup 0x00FF00 and if 0x020000 or then + then + >auth_types + else + \ TLS 1.0 or 1.1. The hash function is fixed for signatures + \ (MD5+SHA-1 for RSA, SHA-1 for ECDSA). + auth_types 0x030401 and >auth_types + then + + \ Parse list of anchor DN. + anchor-dn-start-name-list + read16 open-elt + begin dup while + read16 open-elt + dup anchor-dn-start-name + + \ We read the DN by chunks through the pad, so + \ as to use the existing reading function (read-blob) + \ that also ensures proper hashing. + begin + dup while + dup 256 > if 256 else dup then { len } + addr-pad len read-blob + len anchor-dn-append-name + repeat + close-elt + anchor-dn-end-name + repeat + close-elt + anchor-dn-end-name-list + + \ We should have reached the message end. + close-elt + + \ Obtain the client chain. + auth_types get-client-chain + ; + +\ (obsolete) +\ Write an empty Certificate message. +\ : write-empty-Certificate ( -- ) +\ 11 write8 3 write24 0 write24 ; + +cc: do-rsa-encrypt ( prf_id -- nlen ) { + int x; + + x = make_pms_rsa(CTX, T0_POP()); + if (x < 0) { + br_ssl_engine_fail(ENG, -x); + T0_CO(); + } else { + T0_PUSH(x); + } +} + +cc: do-ecdh ( echde prf_id -- ulen ) { + unsigned prf_id = T0_POP(); + unsigned ecdhe = T0_POP(); + int x; + + x = make_pms_ecdh(CTX, ecdhe, prf_id); + if (x < 0) { + br_ssl_engine_fail(ENG, -x); + T0_CO(); + } else { + T0_PUSH(x); + } +} + +cc: do-static-ecdh ( prf-id -- ) { + unsigned prf_id = T0_POP(); + + if (make_pms_static_ecdh(CTX, prf_id) < 0) { + br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM); + T0_CO(); + } +} + +cc: do-client-sign ( -- sig_len ) { + size_t sig_len; + + sig_len = make_client_sign(CTX); + if (sig_len == 0) { + br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM); + T0_CO(); + } + T0_PUSH(sig_len); +} + +\ Write ClientKeyExchange. +: write-ClientKeyExchange ( -- ) + 16 write8 + addr-cipher_suite get16 + dup use-rsa-keyx? if + prf-id do-rsa-encrypt + dup 2+ write24 + dup write16 + addr-pad swap write-blob + else + dup use-ecdhe? swap prf-id do-ecdh + dup 1+ write24 + dup write8 + addr-pad swap write-blob + then ; + +\ Write CertificateVerify. This is invoked only if a client certificate +\ was requested and sent, and the authentication is not full static ECDH. +: write-CertificateVerify ( -- ) + do-client-sign + 15 write8 dup + addr-version get16 0x0303 >= if + 4 + write24 + addr-hash_id get8 write8 + addr-auth_type get8 write8 + else + 2+ write24 + then + dup write16 addr-pad swap write-blob ; + +\ ======================================================================= + +\ Peek at the first byte of the handshake input buffer without consuming +\ it. Returns the byte value, or -1 if the buffer is empty. +cc: peek-hs-msg-type ( -- type ) { + if (ENG->hlen_in > 0) { + T0_PUSH(*ENG->hbuf_in); + } else { + T0_PUSHi(-1); + } +} + +\ Read a NewSessionTicket message (handshake type 4, RFC 5077). +\ Format: uint32 lifetime_hint, opaque ticket<0..2^16-1> +cc: debug-session-ticket ( len -- ) { + extern void __stdcall OutputDebugStringA(const char *); + extern int sprintf(char *, const char *, ...); + char buf[80]; + size_t len = T0_POP(); + sprintf(buf, "BearSSL: NewSessionTicket received (%u bytes)\r\n", + (unsigned)len); + OutputDebugStringA(buf); +} + +: read-NewSessionTicket-message ( -- ) + read-handshake-header 4 = ifnot ERR_UNEXPECTED fail then + \ Skip the 4-byte lifetime_hint. + read16 drop read16 drop + \ Read ticket length, then ticket data. + read16 { tlen } + tlen 1024 > if + \ Ticket too large for our buffer; skip it. + tlen skip-blob + 0 addr-session_ticket_len set16 + else + addr-session_ticket tlen read-blob + tlen addr-session_ticket_len set16 + then + tlen debug-session-ticket + close-elt ; + +\ Read optional NewSessionTicket (RFC 5077) then CCS+Finished. +\ During abbreviated handshakes the server MAY send a renewed ticket +\ before CCS, but it is not guaranteed. We peek at the next record +\ type: if it is a handshake record we read the ticket; if it is CCS +\ we skip straight to read-CCS-Finished. +: read-CCS-Finished-with-ticket ( is-client -- ) + addr-session_ticket_ok get8 if + has-input? if + addr-record_type_in get8 22 = if + read-NewSessionTicket-message + then + else + begin + wait-co 0x07 and + dup 0x01 = if + drop read-NewSessionTicket-message 0 + then + dup 0x02 <> while + dup if ERR_UNEXPECTED fail then + drop + repeat + drop + then + then + read-CCS-Finished ; + +\ Perform a handshake. +: do-handshake ( -- ) + 0 addr-application_data set8 + 22 addr-record_type_out set8 + 0 addr-selected_protocol set16 + 0 addr-session_ticket_ok set8 + multihash-init + + write-ClientHello + flush-record + read-ServerHello + + \ Track whether this is a ticket-based resumption detected by + \ peeking at the next server message (RFC 5077). + 0 { ticket-resume } + + ifnot + \ Not a session ID resumption. Check for ticket-based + \ resumption: if we sent a ticket and the server confirmed + \ ticket support, peek at the next record to decide. + addr-session_ticket_ok get8 + addr-session_ticket_len get16 0 > and if + \ Wait for data from server. + has-input? not if + begin wait-co 0x07 and dup 0= while + drop repeat drop + then + addr-record_type_in get8 20 = if + \ CCS → ticket resumption, no renewed ticket. + -1 >ticket-resume + else + \ Handshake record. Peek at message type. + peek-hs-msg-type 4 = if + \ NewSessionTicket → ticket resumption + \ with a renewed ticket. + read-NewSessionTicket-message + -1 >ticket-resume + then + then + then + else + -1 >ticket-resume + then + + ticket-resume if + \ Session resumption (session-ID or ticket-based). + -1 read-CCS-Finished-with-ticket + -1 write-CCS-Finished + else + \ Full handshake. + + \ Read certificate; then check key type and usages against + \ cipher suite. + read-Certificate-from-server + + \ Depending on cipher suite, we may now expect a + \ ServerKeyExchange. + addr-cipher_suite get16 expected-key-type + CX 0 63 { BR_KEYTYPE_SIGN } and if + read-ServerKeyExchange + then + + \ Get next header. + read-handshake-header + + \ If this is a CertificateRequest, parse it, then read + \ next header. + dup 13 = if + drop read-contents-CertificateRequest + read-handshake-header + -1 + else + 0 + then + { seen-CR } + + \ At that point, we should have a ServerHelloDone, + \ whose length must be 0. + 14 = ifnot ERR_UNEXPECTED fail then + if ERR_BAD_HELLO_DONE fail then + + \ There should not be more bytes in the record at that point. + more-incoming-bytes? if ERR_UNEXPECTED fail then + + seen-CR if + \ If the server requested a client certificate, then + \ we must write a Certificate message (it may be + \ empty). + write-Certificate + + \ If using static ECDH, then the ClientKeyExchange + \ is empty, and there is no CertificateVerify. + \ Otherwise, there is a ClientKeyExchange; there + \ will then be a CertificateVerify if a client chain + \ was indeed sent. + addr-hash_id get8 0xFF = if + drop + 16 write8 0 write24 + addr-cipher_suite get16 prf-id do-static-ecdh + else + write-ClientKeyExchange + if write-CertificateVerify then + then + else + write-ClientKeyExchange + then + + -1 write-CCS-Finished + -1 read-CCS-Finished-with-ticket + then + + \ Now we should be invoked only in case of renegotiation. + 1 addr-application_data set8 + 23 addr-record_type_out set8 ; + +\ Read a HelloRequest message. +: read-HelloRequest ( -- ) + \ A HelloRequest has length 0 and type 0. + read-handshake-header-core + if ERR_UNEXPECTED fail then + if ERR_BAD_HANDSHAKE fail then ; + +\ Entry point. +: main ( -- ! ) + \ Perform initial handshake. + do-handshake + + begin + \ Wait for further invocation. At that point, we should + \ get either an explicit call for renegotiation, or + \ an incoming HelloRequest handshake message. + wait-co + dup 0x07 and case + 0x00 of + 0x10 and if + do-handshake + then + endof + 0x01 of + drop + 0 addr-application_data set8 + read-HelloRequest + \ Reject renegotiations if the peer does not + \ support secure renegotiation, or if the + \ "no renegotiation" flag is set. + addr-reneg get8 1 = 1 flag? or if + flush-record + begin can-output? not while + wait-co drop + repeat + 100 send-warning + \ We rejected the renegotiation, + \ but the connection is not dead. + \ We must set back things into + \ working "application data" state. + 1 addr-application_data set8 + 23 addr-record_type_out set8 + else + do-handshake + then + endof + ERR_UNEXPECTED fail + endcase + again + ; diff --git a/libcurl/lib/vtls/trust_anchors.h b/libcurl/lib/vtls/trust_anchors.h new file mode 100644 index 0000000..9ee13fb --- /dev/null +++ b/libcurl/lib/vtls/trust_anchors.h @@ -0,0 +1,33591 @@ +#pragma once + +static const unsigned char TA0_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x36 +}; + +static const unsigned char TA0_RSA_N[] = { + 0xAC, 0xAC, 0x74, 0x32, 0xE8, 0xB3, 0x65, 0xE5, 0xBA, 0xED, 0x43, 0x26, + 0x1D, 0xA6, 0x89, 0x0D, 0x45, 0xBA, 0x29, 0x88, 0xB2, 0xA4, 0x1D, 0x63, + 0xDD, 0xD3, 0xC1, 0x2C, 0x09, 0x57, 0x89, 0x39, 0xA1, 0x55, 0xE9, 0x67, + 0x34, 0x77, 0x0C, 0x6E, 0xE4, 0x55, 0x1D, 0x52, 0x25, 0xD2, 0x13, 0x6B, + 0x5E, 0xE1, 0x1D, 0xA9, 0xB7, 0x7D, 0x89, 0x32, 0x5F, 0x0D, 0x9E, 0x9F, + 0x2C, 0x7A, 0x63, 0x60, 0x40, 0x1F, 0xA6, 0xB0, 0xB6, 0x78, 0x8F, 0x99, + 0x54, 0x96, 0x08, 0x58, 0xAE, 0xE4, 0x06, 0xBC, 0x62, 0x05, 0x02, 0x16, + 0xBF, 0xAF, 0xA8, 0x23, 0x03, 0xB6, 0x94, 0x0F, 0xBC, 0x6E, 0x6C, 0xC2, + 0xCB, 0xD5, 0xA6, 0xBB, 0x0C, 0xE9, 0xF6, 0xC1, 0x02, 0xFB, 0x21, 0xDE, + 0x66, 0xDD, 0x17, 0xAB, 0x74, 0x42, 0xEF, 0xF0, 0x74, 0x2F, 0x25, 0xF4, + 0xEA, 0x6B, 0x55, 0x5B, 0x90, 0xDB, 0x9D, 0xDF, 0x5E, 0x87, 0x0A, 0x40, + 0xFB, 0xAD, 0x19, 0x6B, 0xFB, 0xF7, 0xCA, 0x60, 0x88, 0xDE, 0xDA, 0xC1, + 0x8F, 0xD6, 0xAE, 0xD5, 0x7F, 0xD4, 0x3C, 0x83, 0xEE, 0xD7, 0x16, 0x4C, + 0x83, 0x45, 0x33, 0x6B, 0x27, 0xD0, 0x86, 0xD0, 0x1C, 0x2D, 0x6B, 0xF3, + 0xAB, 0x7D, 0xF1, 0x85, 0xA9, 0xF5, 0x28, 0xD2, 0xAD, 0xEF, 0xF3, 0x84, + 0x4B, 0x1C, 0x87, 0xFC, 0x13, 0xA3, 0x3A, 0x72, 0xA2, 0x5A, 0x11, 0x2B, + 0xD6, 0x27, 0x71, 0x27, 0xED, 0x81, 0x2D, 0x6D, 0x66, 0x81, 0x92, 0x87, + 0xB4, 0x1B, 0x58, 0x7A, 0xCC, 0x3F, 0x0A, 0xFA, 0x46, 0x4F, 0x4D, 0x78, + 0x5C, 0xF8, 0x2B, 0x48, 0xE3, 0x04, 0x84, 0xCB, 0x5D, 0xF6, 0xB4, 0x6A, + 0xB3, 0x65, 0xFC, 0x42, 0x9E, 0x51, 0x26, 0x23, 0x20, 0xCB, 0x3D, 0x14, + 0xF9, 0x81, 0xED, 0x65, 0x16, 0x00, 0x4F, 0x1A, 0x64, 0x97, 0x66, 0x08, + 0xCF, 0x8C, 0x7B, 0xE3, 0x2B, 0xC0, 0x9D, 0xF9, 0x14, 0xF2, 0x1B, 0xF1, + 0x56, 0x6A, 0x16, 0xBF, 0x2C, 0x85, 0x85, 0xCD, 0x78, 0x38, 0x9A, 0xEB, + 0x42, 0x6A, 0x02, 0x34, 0x18, 0x83, 0x17, 0x4E, 0x94, 0x56, 0xF8, 0xB6, + 0x82, 0xB5, 0xF3, 0x96, 0xDD, 0x3D, 0xF3, 0xBE, 0x7F, 0x20, 0x77, 0x3E, + 0x7B, 0x19, 0x23, 0x6B, 0x2C, 0xD4, 0x72, 0x73, 0x43, 0x57, 0x7D, 0xE0, + 0xF8, 0xD7, 0x69, 0x4F, 0x17, 0x36, 0x04, 0xF9, 0xC0, 0x90, 0x60, 0x37, + 0x45, 0xDE, 0xE6, 0x0C, 0xD8, 0x74, 0x8D, 0xAE, 0x9C, 0xA2, 0x6D, 0x74, + 0x5D, 0x42, 0xBE, 0x06, 0xF5, 0xD9, 0x64, 0x6E, 0x02, 0x10, 0xAC, 0x89, + 0xB0, 0x4C, 0x3B, 0x07, 0x4D, 0x40, 0x7E, 0x24, 0xC5, 0x8A, 0x98, 0x82, + 0x79, 0x8E, 0xA4, 0xA7, 0x82, 0x20, 0x8D, 0x23, 0xFA, 0x27, 0x71, 0xC9, + 0xDF, 0xC6, 0x41, 0x74, 0xA0, 0x4D, 0xF6, 0x91, 0x16, 0xDC, 0x46, 0x8C, + 0x5F, 0x29, 0x63, 0x31, 0x59, 0x71, 0x0C, 0xD8, 0x6F, 0xC2, 0xB6, 0x32, + 0x7D, 0xFB, 0xE6, 0x5D, 0x53, 0xA6, 0x7E, 0x15, 0xFC, 0xBB, 0x75, 0x7C, + 0x5D, 0xEC, 0xF8, 0xF6, 0x17, 0x1C, 0xEC, 0xC7, 0x6B, 0x19, 0xCB, 0xF3, + 0x7B, 0xF0, 0x2B, 0x07, 0xA5, 0xD9, 0x6C, 0x79, 0x54, 0x76, 0x6C, 0x9D, + 0x1C, 0xA6, 0x6E, 0x0E, 0xE9, 0x79, 0x0C, 0xA8, 0x23, 0x6A, 0xA3, 0xDF, + 0x1B, 0x30, 0x31, 0x9F, 0xB1, 0x54, 0x7B, 0xFE, 0x6A, 0xCB, 0x66, 0xAA, + 0xDC, 0x65, 0xD0, 0xA2, 0x9E, 0x4A, 0x9A, 0x07, 0x21, 0x6B, 0x81, 0x8F, + 0xDB, 0xC4, 0x59, 0xFA, 0xDE, 0x22, 0xC0, 0x04, 0x9C, 0xE3, 0xAA, 0x5B, + 0x36, 0x93, 0xE8, 0x3D, 0xBD, 0x7A, 0xA1, 0x9D, 0x0B, 0x76, 0xB1, 0x0B, + 0xC7, 0x9D, 0xFD, 0xCF, 0x98, 0xA8, 0x06, 0xC2, 0xF8, 0x2A, 0xA3, 0xA1, + 0x83, 0xA0, 0xB7, 0x25, 0x72, 0xA5, 0x02, 0xE3 +}; + +static const unsigned char TA0_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA1_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA1_EC_Q[] = { + 0x04, 0xD4, 0xBC, 0x3D, 0x02, 0x42, 0x75, 0x41, 0x13, 0x23, 0xCD, 0x80, + 0x04, 0x86, 0x02, 0x51, 0x2F, 0x6A, 0xA8, 0x81, 0x62, 0x0B, 0x65, 0xCC, + 0xF6, 0xCA, 0x9D, 0x1E, 0x6F, 0x4A, 0x66, 0x51, 0xA2, 0x03, 0xD9, 0x9D, + 0x91, 0xFA, 0xB6, 0x16, 0xB1, 0x8C, 0x6E, 0xDE, 0x7C, 0xCD, 0xDB, 0x79, + 0xA6, 0x2F, 0xCE, 0xBB, 0xCE, 0x71, 0x2F, 0xE5, 0xA5, 0xAB, 0x28, 0xEC, + 0x63, 0x04, 0x66, 0x99, 0xF8, 0xFA, 0xF2, 0x93, 0x10, 0x05, 0xE1, 0x81, + 0x28, 0x42, 0xE3, 0xC6, 0x68, 0xF4, 0xE6, 0x1B, 0x84, 0x60, 0x4A, 0x89, + 0xAF, 0xED, 0x79, 0x0F, 0x3B, 0xCE, 0xF1, 0xF6, 0x44, 0xF5, 0x01, 0x78, + 0xC0 +}; + +static const unsigned char TA2_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x31 +}; + +static const unsigned char TA2_RSA_N[] = { + 0xF1, 0x66, 0x08, 0xBD, 0xD9, 0xC5, 0x15, 0x61, 0xCB, 0x84, 0x04, 0x41, + 0xA5, 0x69, 0x37, 0x77, 0x1D, 0xC1, 0xB0, 0x7B, 0xFA, 0xC3, 0x77, 0x48, + 0x90, 0x13, 0x72, 0x64, 0xD1, 0xB8, 0x7C, 0x90, 0x35, 0x9D, 0x18, 0x79, + 0x88, 0xE3, 0x97, 0x01, 0x3C, 0x47, 0x81, 0xF2, 0x0E, 0xA2, 0x98, 0x0D, + 0x9E, 0x3F, 0x37, 0xE0, 0x19, 0xB2, 0x90, 0xF2, 0x46, 0x1C, 0x92, 0xB1, + 0x3A, 0x61, 0xCE, 0xFA, 0xB7, 0x46, 0x9E, 0x03, 0x86, 0xD7, 0x33, 0x6E, + 0xED, 0xF7, 0x45, 0x8C, 0x76, 0x37, 0xDE, 0x6E, 0x96, 0x91, 0xF7, 0xD7, + 0x7E, 0x2B, 0x87, 0x17, 0xD5, 0x8B, 0x35, 0xEE, 0x84, 0x91, 0x72, 0x57, + 0xDC, 0x60, 0xC3, 0xC3, 0xB9, 0xE7, 0xC7, 0x67, 0x24, 0x23, 0x4F, 0x63, + 0x0A, 0x63, 0xF6, 0x66, 0x7D, 0x4B, 0x55, 0xA7, 0x3F, 0x78, 0x64, 0x49, + 0x69, 0x12, 0x97, 0xE0, 0x4C, 0x0D, 0xD3, 0x09, 0xA0, 0x32, 0x30, 0x3A, + 0xFA, 0x9F, 0xC0, 0xF2, 0x9C, 0xC5, 0x12, 0x2A, 0x2E, 0x1C, 0xB5, 0x04, + 0x33, 0xDA, 0xA4, 0x38, 0x11, 0x6A, 0xDE, 0xC6, 0x18, 0xF6, 0x47, 0x3A, + 0x22, 0x41, 0x87, 0x22, 0xFC, 0xC4, 0x89, 0x28, 0x54, 0xD8, 0x8C, 0xA5, + 0x30, 0x0A, 0xF8, 0x17, 0x16, 0xCA, 0xAC, 0x37, 0xFD, 0x79, 0xA7, 0x91, + 0x17, 0x78, 0x38, 0x99, 0xAD, 0x58, 0xED, 0xB2, 0xDE, 0xCC, 0x89, 0x7D, + 0x03, 0x9C, 0xB3, 0x89, 0x65, 0xE7, 0xE3, 0x3B, 0xB1, 0x22, 0x86, 0x8F, + 0x06, 0x6D, 0x78, 0x07, 0xFD, 0x91, 0x12, 0x7F, 0xB0, 0x6B, 0x1C, 0x89, + 0x0D, 0xF9, 0xB8, 0xCB, 0x74, 0x5B, 0x07, 0xC2, 0xC8, 0xF4, 0x35, 0xD1, + 0x64, 0x63, 0x7A, 0xE9, 0x6E, 0x9A, 0x28, 0xD6, 0x30, 0xBD, 0xE6, 0x1B, + 0xDD, 0x15, 0xAF, 0x84, 0xEA, 0x9C, 0xC7, 0xCA, 0xF5, 0x0E, 0xEA, 0xF2, + 0x5D, 0x29, 0x87, 0x8F, 0x69, 0x73, 0x39, 0xBE, 0x2E, 0x24, 0x6F, 0x45, + 0x21, 0xAC, 0xC5, 0xD4, 0x69, 0x25, 0x06, 0x83, 0xAD, 0x7A, 0x48, 0x85, + 0x13, 0x2C, 0x0D, 0x06, 0xB8, 0x6C, 0x79, 0x56, 0xFC, 0xA3, 0x67, 0x32, + 0x81, 0xF5, 0x57, 0xA5, 0xCA, 0x57, 0x42, 0x69, 0xE9, 0x5C, 0x24, 0x61, + 0xEF, 0xE2, 0x30, 0x18, 0x4E, 0x44, 0x98, 0x55, 0x6F, 0x7A, 0xC2, 0x93, + 0xD8, 0x19, 0xB6, 0xDE, 0x7C, 0x47, 0x8A, 0x11, 0x4E, 0x49, 0x47, 0xDB, + 0x28, 0x94, 0x02, 0x0B, 0x94, 0x4A, 0x2C, 0xF9, 0x12, 0xD0, 0x4F, 0xE8, + 0x31, 0x7E, 0x6C, 0x7A, 0xBF, 0xA6, 0x3F, 0x9B, 0x39, 0x3D, 0x02, 0x16, + 0xA3, 0x18, 0xB3, 0x67, 0xAC, 0x5B, 0x3F, 0x2C, 0x83, 0x2B, 0x67, 0x39, + 0x81, 0x5C, 0xB9, 0x7E, 0x94, 0xD5, 0x64, 0xDD, 0x9E, 0x8F, 0x6E, 0xAE, + 0xE8, 0x7C, 0x5B, 0xB4, 0xD7, 0x6A, 0x47, 0x48, 0xD7, 0x7E, 0xB3, 0xD4, + 0x2D, 0x8E, 0x56, 0x76, 0x4E, 0xCF, 0x69, 0xF1, 0x6E, 0x44, 0x6C, 0xD4, + 0x24, 0xEA, 0x8D, 0x24, 0xA1, 0x18, 0xBF, 0xBD, 0x57, 0xFE, 0xA9, 0x99, + 0x35, 0xB5, 0xDB, 0x10, 0x77, 0xB8, 0x3D, 0x48, 0xBA, 0xD6, 0xC1, 0xE7, + 0xF1, 0x23, 0x3E, 0xD7, 0xDF, 0x85, 0x9D, 0x27, 0x3C, 0xD4, 0x40, 0xBD, + 0x0A, 0x0C, 0xBD, 0xF5, 0xE7, 0x8D, 0x25, 0xD6, 0x81, 0x74, 0x87, 0x46, + 0xD4, 0x29, 0x75, 0xA2, 0x42, 0x6C, 0xF7, 0x73, 0x89, 0xE7, 0x7D, 0xBF, + 0x7A, 0x4A, 0x1F, 0xD3, 0x22, 0xC9, 0x15, 0x55, 0xCF, 0xDF, 0x6F, 0x7C, + 0x55, 0xD0, 0xA4, 0x8B, 0x07, 0x11, 0x37, 0x5F, 0x83, 0xA6, 0x26, 0x57, + 0xA6, 0x01, 0x5B, 0x7E, 0xFE, 0x58, 0x68, 0x07, 0xA9, 0xE9, 0x7A, 0xD9, + 0xB9, 0xE8, 0xFF, 0x50, 0x1F, 0xAB, 0xC2, 0xB4, 0xC0, 0xCE, 0xE8, 0xEA, + 0xFD, 0x0F, 0xBD, 0x8D, 0x4D, 0xB8, 0xBC, 0x71 +}; + +static const unsigned char TA2_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA3_DN[] = { + 0x30, 0x81, 0xBE, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x32, 0x30, + 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, + 0x32 +}; + +static const unsigned char TA3_RSA_N[] = { + 0xBA, 0x84, 0xB6, 0x72, 0xDB, 0x9E, 0x0C, 0x6B, 0xE2, 0x99, 0xE9, 0x30, + 0x01, 0xA7, 0x76, 0xEA, 0x32, 0xB8, 0x95, 0x41, 0x1A, 0xC9, 0xDA, 0x61, + 0x4E, 0x58, 0x72, 0xCF, 0xFE, 0xF6, 0x82, 0x79, 0xBF, 0x73, 0x61, 0x06, + 0x0A, 0xA5, 0x27, 0xD8, 0xB3, 0x5F, 0xD3, 0x45, 0x4E, 0x1C, 0x72, 0xD6, + 0x4E, 0x32, 0xF2, 0x72, 0x8A, 0x0F, 0xF7, 0x83, 0x19, 0xD0, 0x6A, 0x80, + 0x80, 0x00, 0x45, 0x1E, 0xB0, 0xC7, 0xE7, 0x9A, 0xBF, 0x12, 0x57, 0x27, + 0x1C, 0xA3, 0x68, 0x2F, 0x0A, 0x87, 0xBD, 0x6A, 0x6B, 0x0E, 0x5E, 0x65, + 0xF3, 0x1C, 0x77, 0xD5, 0xD4, 0x85, 0x8D, 0x70, 0x21, 0xB4, 0xB3, 0x32, + 0xE7, 0x8B, 0xA2, 0xD5, 0x86, 0x39, 0x02, 0xB1, 0xB8, 0xD2, 0x47, 0xCE, + 0xE4, 0xC9, 0x49, 0xC4, 0x3B, 0xA7, 0xDE, 0xFB, 0x54, 0x7D, 0x57, 0xBE, + 0xF0, 0xE8, 0x6E, 0xC2, 0x79, 0xB2, 0x3A, 0x0B, 0x55, 0xE2, 0x50, 0x98, + 0x16, 0x32, 0x13, 0x5C, 0x2F, 0x78, 0x56, 0xC1, 0xC2, 0x94, 0xB3, 0xF2, + 0x5A, 0xE4, 0x27, 0x9A, 0x9F, 0x24, 0xD7, 0xC6, 0xEC, 0xD0, 0x9B, 0x25, + 0x82, 0xE3, 0xCC, 0xC2, 0xC4, 0x45, 0xC5, 0x8C, 0x97, 0x7A, 0x06, 0x6B, + 0x2A, 0x11, 0x9F, 0xA9, 0x0A, 0x6E, 0x48, 0x3B, 0x6F, 0xDB, 0xD4, 0x11, + 0x19, 0x42, 0xF7, 0x8F, 0x07, 0xBF, 0xF5, 0x53, 0x5F, 0x9C, 0x3E, 0xF4, + 0x17, 0x2C, 0xE6, 0x69, 0xAC, 0x4E, 0x32, 0x4C, 0x62, 0x77, 0xEA, 0xB7, + 0xE8, 0xE5, 0xBB, 0x34, 0xBC, 0x19, 0x8B, 0xAE, 0x9C, 0x51, 0xE7, 0xB7, + 0x7E, 0xB5, 0x53, 0xB1, 0x33, 0x22, 0xE5, 0x6D, 0xCF, 0x70, 0x3C, 0x1A, + 0xFA, 0xE2, 0x9B, 0x67, 0xB6, 0x83, 0xF4, 0x8D, 0xA5, 0xAF, 0x62, 0x4C, + 0x4D, 0xE0, 0x58, 0xAC, 0x64, 0x34, 0x12, 0x03, 0xF8, 0xB6, 0x8D, 0x94, + 0x63, 0x24, 0xA4, 0x71 +}; + +static const unsigned char TA3_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA4_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA4_EC_Q[] = { + 0x04, 0x1A, 0xAC, 0x54, 0x5A, 0xA9, 0xF9, 0x68, 0x23, 0xE7, 0x7A, 0xD5, + 0x24, 0x6F, 0x53, 0xC6, 0x5A, 0xD8, 0x4B, 0xAB, 0xC6, 0xD5, 0xB6, 0xD1, + 0xE6, 0x73, 0x71, 0xAE, 0xDD, 0x9C, 0xD6, 0x0C, 0x61, 0xFD, 0xDB, 0xA0, + 0x89, 0x03, 0xB8, 0x05, 0x14, 0xEC, 0x57, 0xCE, 0xEE, 0x5D, 0x3F, 0xE2, + 0x21, 0xB3, 0xCE, 0xF7, 0xD4, 0x8A, 0x79, 0xE0, 0xA3, 0x83, 0x7E, 0x2D, + 0x97, 0xD0, 0x61, 0xC4, 0xF1, 0x99, 0xDC, 0x25, 0x91, 0x63, 0xAB, 0x7F, + 0x30, 0xA3, 0xB4, 0x70, 0xE2, 0xC7, 0xA1, 0x33, 0x9C, 0xF3, 0xBF, 0x2E, + 0x5C, 0x53, 0xB1, 0x5F, 0xB3, 0x7D, 0x32, 0x7F, 0x8A, 0x34, 0xE3, 0x79, + 0x79 +}; + +static const unsigned char TA5_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x33, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA5_RSA_N[] = { + 0xCC, 0x25, 0x76, 0x90, 0x79, 0x06, 0x78, 0x22, 0x16, 0xF5, 0xC0, 0x83, + 0xB6, 0x84, 0xCA, 0x28, 0x9E, 0xFD, 0x05, 0x76, 0x11, 0xC5, 0xAD, 0x88, + 0x72, 0xFC, 0x46, 0x02, 0x43, 0xC7, 0xB2, 0x8A, 0x9D, 0x04, 0x5F, 0x24, + 0xCB, 0x2E, 0x4B, 0xE1, 0x60, 0x82, 0x46, 0xE1, 0x52, 0xAB, 0x0C, 0x81, + 0x47, 0x70, 0x6C, 0xDD, 0x64, 0xD1, 0xEB, 0xF5, 0x2C, 0xA3, 0x0F, 0x82, + 0x3D, 0x0C, 0x2B, 0xAE, 0x97, 0xD7, 0xB6, 0x14, 0x86, 0x10, 0x79, 0xBB, + 0x3B, 0x13, 0x80, 0x77, 0x8C, 0x08, 0xE1, 0x49, 0xD2, 0x6A, 0x62, 0x2F, + 0x1F, 0x5E, 0xFA, 0x96, 0x68, 0xDF, 0x89, 0x27, 0x95, 0x38, 0x9F, 0x06, + 0xD7, 0x3E, 0xC9, 0xCB, 0x26, 0x59, 0x0D, 0x73, 0xDE, 0xB0, 0xC8, 0xE9, + 0x26, 0x0E, 0x83, 0x15, 0xC6, 0xEF, 0x5B, 0x8B, 0xD2, 0x04, 0x60, 0xCA, + 0x49, 0xA6, 0x28, 0xF6, 0x69, 0x3B, 0xF6, 0xCB, 0xC8, 0x28, 0x91, 0xE5, + 0x9D, 0x8A, 0x61, 0x57, 0x37, 0xAC, 0x74, 0x14, 0xDC, 0x74, 0xE0, 0x3A, + 0xEE, 0x72, 0x2F, 0x2E, 0x9C, 0xFB, 0xD0, 0xBB, 0xBF, 0xF5, 0x3D, 0x00, + 0xE1, 0x06, 0x33, 0xE8, 0x82, 0x2B, 0xAE, 0x53, 0xA6, 0x3A, 0x16, 0x73, + 0x8C, 0xDD, 0x41, 0x0E, 0x20, 0x3A, 0xC0, 0xB4, 0xA7, 0xA1, 0xE9, 0xB2, + 0x4F, 0x90, 0x2E, 0x32, 0x60, 0xE9, 0x57, 0xCB, 0xB9, 0x04, 0x92, 0x68, + 0x68, 0xE5, 0x38, 0x26, 0x60, 0x75, 0xB2, 0x9F, 0x77, 0xFF, 0x91, 0x14, + 0xEF, 0xAE, 0x20, 0x49, 0xFC, 0xAD, 0x40, 0x15, 0x48, 0xD1, 0x02, 0x31, + 0x61, 0x19, 0x5E, 0xB8, 0x97, 0xEF, 0xAD, 0x77, 0xB7, 0x64, 0x9A, 0x7A, + 0xBF, 0x5F, 0xC1, 0x13, 0xEF, 0x9B, 0x62, 0xFB, 0x0D, 0x6C, 0xE0, 0x54, + 0x69, 0x16, 0xA9, 0x03, 0xDA, 0x6E, 0xE9, 0x83, 0x93, 0x71, 0x76, 0xC6, + 0x69, 0x85, 0x82, 0x17 +}; + +static const unsigned char TA5_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA6_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA6_RSA_N[] = { + 0xA1, 0xAE, 0x25, 0xB2, 0x01, 0x18, 0xDC, 0x57, 0x88, 0x3F, 0x46, 0xEB, + 0xF9, 0xAF, 0xE2, 0xEB, 0x23, 0x71, 0xE2, 0x9A, 0xD1, 0x61, 0x66, 0x21, + 0x5F, 0xAA, 0xAF, 0x27, 0x51, 0xE5, 0x6E, 0x1B, 0x16, 0xD4, 0x2D, 0x7D, + 0x50, 0xB0, 0x53, 0x77, 0xBD, 0x78, 0x3A, 0x60, 0xE2, 0x64, 0x02, 0x9B, + 0x7C, 0x86, 0x9B, 0xD6, 0x1A, 0x8E, 0xAD, 0xFF, 0x1F, 0x15, 0x7F, 0xD5, + 0x95, 0x1E, 0x12, 0xCB, 0xE6, 0x14, 0x84, 0x04, 0xC1, 0xDF, 0x36, 0xB3, + 0x16, 0x9F, 0x8A, 0xE3, 0xC9, 0xDB, 0x98, 0x34, 0xCE, 0xD8, 0x33, 0x17, + 0x28, 0x46, 0xFC, 0xA7, 0xC9, 0xF0, 0xD2, 0xB4, 0xD5, 0x4D, 0x09, 0x72, + 0x49, 0xF9, 0xF2, 0x87, 0xE3, 0xA9, 0xDA, 0x7D, 0xA1, 0x7D, 0x6B, 0xB2, + 0x3A, 0x25, 0xA9, 0x6D, 0x52, 0x44, 0xAC, 0xF8, 0xBE, 0x6E, 0xFB, 0xDC, + 0xA6, 0x73, 0x91, 0x90, 0x61, 0xA6, 0x03, 0x14, 0x20, 0xF2, 0xE7, 0x87, + 0xA3, 0x88, 0xAD, 0xAD, 0xA0, 0x8C, 0xFF, 0xA6, 0x0B, 0x25, 0x52, 0x25, + 0xE7, 0x16, 0x01, 0xD5, 0xCB, 0xB8, 0x35, 0x81, 0x0C, 0xA3, 0x3B, 0xF0, + 0xE1, 0xE1, 0xFC, 0x5A, 0x5D, 0xCE, 0x80, 0x71, 0x6D, 0xF8, 0x49, 0xAB, + 0x3E, 0x3B, 0xBA, 0xB8, 0xD7, 0x80, 0x01, 0xFB, 0xA5, 0xEB, 0x5B, 0xB3, + 0xC5, 0x5E, 0x60, 0x2A, 0x31, 0xA0, 0xAF, 0x37, 0xE8, 0x20, 0x3A, 0x9F, + 0xA8, 0x32, 0x2C, 0x0C, 0xCC, 0x09, 0x1D, 0xD3, 0x9E, 0x8E, 0x5D, 0xBC, + 0x4C, 0x98, 0xEE, 0xC5, 0x1A, 0x68, 0x7B, 0xEC, 0x53, 0xA6, 0xE9, 0x14, + 0x35, 0xA3, 0xDF, 0xCD, 0x80, 0x9F, 0x0C, 0x48, 0xFB, 0x1C, 0xF4, 0xF1, + 0xBF, 0x4A, 0xB8, 0xFA, 0xD5, 0x8C, 0x71, 0x4A, 0xC7, 0x1F, 0xAD, 0xFE, + 0x41, 0x9A, 0xB3, 0x83, 0x5D, 0xF2, 0x84, 0x56, 0xEF, 0xA5, 0x57, 0x43, + 0xCE, 0x29, 0xAD, 0x8C, 0xAB, 0x55, 0xBF, 0xC4, 0xFB, 0x5B, 0x01, 0xDD, + 0x23, 0x21, 0xA1, 0x58, 0x00, 0x8E, 0xC3, 0xD0, 0x6A, 0x13, 0xED, 0x13, + 0xE3, 0x12, 0x2B, 0x80, 0xDC, 0x67, 0xE6, 0x95, 0xB2, 0xCD, 0x1E, 0x22, + 0x6E, 0x2A, 0xF8, 0x41, 0xD4, 0xF2, 0xCA, 0x14, 0x07, 0x8D, 0x8A, 0x55, + 0x12, 0xC6, 0x69, 0xF5, 0xB8, 0x86, 0x68, 0x2F, 0x53, 0x5E, 0xB0, 0xD2, + 0xAA, 0x21, 0xC1, 0x98, 0xE6, 0x30, 0xE3, 0x67, 0x55, 0xC7, 0x9B, 0x6E, + 0xAC, 0x19, 0xA8, 0x55, 0xA6, 0x45, 0x06, 0xD0, 0x23, 0x3A, 0xDB, 0xEB, + 0x65, 0x5D, 0x2A, 0x11, 0x11, 0xF0, 0x3B, 0x4F, 0xCA, 0x6D, 0xF4, 0x34, + 0xC4, 0x71, 0xE4, 0xFF, 0x00, 0x5A, 0xF6, 0x5C, 0xAE, 0x23, 0x60, 0x85, + 0x73, 0xF1, 0xE4, 0x10, 0xB1, 0x25, 0xAE, 0xD5, 0x92, 0xBB, 0x13, 0xC1, + 0x0C, 0xE0, 0x39, 0xDA, 0xB4, 0x39, 0x57, 0xB5, 0xAB, 0x35, 0xAA, 0x72, + 0x21, 0x3B, 0x83, 0x35, 0xE7, 0x31, 0xDF, 0x7A, 0x21, 0x6E, 0xB8, 0x32, + 0x08, 0x7D, 0x1D, 0x32, 0x91, 0x15, 0x4A, 0x62, 0x72, 0xCF, 0xE3, 0x77, + 0xA1, 0xBC, 0xD5, 0x11, 0x1B, 0x76, 0x01, 0x67, 0x08, 0xE0, 0x41, 0x0B, + 0xC3, 0xEB, 0x15, 0x6E, 0xF8, 0xA4, 0x19, 0xD9, 0xA2, 0xAB, 0xAF, 0xE2, + 0x27, 0x52, 0x56, 0x2B, 0x02, 0x8A, 0x2C, 0x14, 0x24, 0xF9, 0xBF, 0x42, + 0x02, 0xBF, 0x26, 0xC8, 0xC6, 0x8F, 0xE0, 0x6E, 0x38, 0x7D, 0x53, 0x2D, + 0xE5, 0xED, 0x98, 0xB3, 0x95, 0x63, 0x68, 0x7F, 0xF9, 0x35, 0xF4, 0xDF, + 0x88, 0xC5, 0x60, 0x35, 0x92, 0xC0, 0x7C, 0x69, 0x1C, 0x61, 0x95, 0x16, + 0xD0, 0xEB, 0xDE, 0x0B, 0xAF, 0x3E, 0x04, 0x10, 0x45, 0x65, 0x58, 0x50, + 0x38, 0xAF, 0x48, 0xF2, 0x59, 0xB6, 0x16, 0xF2, 0x3C, 0x0D, 0x90, 0x02, + 0xC6, 0x70, 0x2E, 0x01, 0xAD, 0x3C, 0x15, 0xD7 +}; + +static const unsigned char TA6_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA7_DN[] = { + 0x30, 0x6E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x13, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, 0x6F, 0x66, 0x65, + 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x53, 0x41, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0F, 0x56, 0x41, 0x54, 0x45, + 0x53, 0x2D, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x46, 0x49, + 0x52, 0x4D, 0x41, 0x50, 0x52, 0x4F, 0x46, 0x45, 0x53, 0x49, 0x4F, 0x4E, + 0x41, 0x4C, 0x20, 0x43, 0x41, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x2D, 0x41, + 0x20, 0x57, 0x45, 0x42 +}; + +static const unsigned char TA7_EC_Q[] = { + 0x04, 0x47, 0x53, 0xEA, 0x2C, 0x11, 0xA4, 0x77, 0xC7, 0x2A, 0xEA, 0xF3, + 0xD6, 0x5F, 0x7B, 0xD3, 0x04, 0x91, 0x5C, 0xFA, 0x88, 0xC6, 0x22, 0xB9, + 0x83, 0x10, 0x62, 0x77, 0x84, 0x33, 0x2D, 0xE9, 0x03, 0x88, 0xD4, 0xE0, + 0x33, 0xF7, 0xED, 0x77, 0x2C, 0x4A, 0x60, 0xEA, 0xE4, 0x6F, 0xAD, 0x6D, + 0xB4, 0xF8, 0x4C, 0x8A, 0xA4, 0xE4, 0x1F, 0xCA, 0xEA, 0x4F, 0x38, 0x4A, + 0x2E, 0x82, 0x73, 0x2B, 0xC7, 0x66, 0x9B, 0x0A, 0x8C, 0x40, 0x9C, 0x7C, + 0x8A, 0xF6, 0xF2, 0x39, 0x60, 0xB2, 0xDE, 0xCB, 0xEC, 0xB8, 0xE4, 0x6F, + 0xEA, 0x9B, 0x5D, 0xB7, 0x53, 0x90, 0x18, 0x32, 0x55, 0xC5, 0x20, 0xB7, + 0x94 +}; + +static const unsigned char TA8_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, + 0x6F, 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x2E, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, + 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA8_RSA_N[] = { + 0x8F, 0x36, 0x65, 0x40, 0xE1, 0xD6, 0x4D, 0xC0, 0xD7, 0xB4, 0xE9, 0x46, + 0xDA, 0x6B, 0xEA, 0x33, 0x47, 0xCD, 0x4C, 0xF9, 0x7D, 0x7D, 0xBE, 0xBD, + 0x2D, 0x3D, 0xF0, 0xDB, 0x78, 0xE1, 0x86, 0xA5, 0xD9, 0xBA, 0x09, 0x57, + 0x68, 0xED, 0x57, 0x3E, 0xA0, 0xD0, 0x08, 0x41, 0x83, 0xE7, 0x28, 0x41, + 0x24, 0x1F, 0xE3, 0x72, 0x15, 0xD0, 0x01, 0x1A, 0xFB, 0x5E, 0x70, 0x23, + 0xB2, 0xCB, 0x9F, 0x39, 0xE3, 0xCF, 0xC5, 0x4E, 0xC6, 0x92, 0x6D, 0x26, + 0xC6, 0x7B, 0xBB, 0xB3, 0xDA, 0x27, 0x9D, 0x0A, 0x86, 0xE9, 0x81, 0x37, + 0x05, 0xFE, 0xF0, 0x71, 0x71, 0xEC, 0xC3, 0x1C, 0xE9, 0x63, 0xA2, 0x17, + 0x14, 0x9D, 0xEF, 0x1B, 0x67, 0xD3, 0x85, 0x55, 0x02, 0x02, 0xD6, 0x49, + 0xC9, 0xCC, 0x5A, 0xE1, 0xB1, 0xF7, 0x6F, 0x32, 0x9F, 0xC9, 0xD4, 0x3B, + 0x88, 0x41, 0xA8, 0x9C, 0xBD, 0xCB, 0xAB, 0xDB, 0x6D, 0x7B, 0x09, 0x1F, + 0xA2, 0x4C, 0x72, 0x90, 0xDA, 0x2B, 0x08, 0xFC, 0xCF, 0x3C, 0x54, 0xCE, + 0x67, 0x0F, 0xA8, 0xCF, 0x5D, 0x96, 0x19, 0x0B, 0xC4, 0xE3, 0x72, 0xEB, + 0xAD, 0xD1, 0x7D, 0x1D, 0x27, 0xEF, 0x92, 0xEB, 0x10, 0xBF, 0x5B, 0xEB, + 0x3B, 0xAF, 0xCF, 0x80, 0xDD, 0xC1, 0xD2, 0x96, 0x04, 0x5B, 0x7A, 0x7E, + 0xA4, 0xA9, 0x3C, 0x38, 0x76, 0xA4, 0x62, 0x8E, 0xA0, 0x39, 0x5E, 0xEA, + 0x77, 0xCF, 0x5D, 0x00, 0x59, 0x8F, 0x66, 0x2C, 0x3E, 0x07, 0xA2, 0xA3, + 0x05, 0x26, 0x11, 0x69, 0x97, 0xEA, 0x85, 0xB7, 0x0F, 0x96, 0x0B, 0x4B, + 0xC8, 0x40, 0xE1, 0x50, 0xBA, 0x2E, 0x8A, 0xCB, 0xF7, 0x0F, 0x9A, 0x22, + 0xE7, 0x7F, 0x9A, 0x37, 0x13, 0xCD, 0xF2, 0x4D, 0x13, 0x6B, 0x21, 0xD1, + 0xC0, 0xCC, 0x22, 0xF2, 0xA1, 0x46, 0xF6, 0x44, 0x69, 0x9C, 0xCA, 0x61, + 0x35, 0x07, 0x00, 0x6F, 0xD6, 0x61, 0x08, 0x11, 0xEA, 0xBA, 0xB8, 0xF6, + 0xE9, 0xB3, 0x60, 0xE5, 0x4D, 0xB9, 0xEC, 0x9F, 0x14, 0x66, 0xC9, 0x57, + 0x58, 0xDB, 0xCD, 0x87, 0x69, 0xF8, 0x8A, 0x86, 0x12, 0x03, 0x47, 0xBF, + 0x66, 0x13, 0x76, 0xAC, 0x77, 0x7D, 0x34, 0x24, 0x85, 0x83, 0xCD, 0xD7, + 0xAA, 0x9C, 0x90, 0x1A, 0x9F, 0x21, 0x2C, 0x7F, 0x78, 0xB7, 0x64, 0xB8, + 0xD8, 0xE8, 0xA6, 0xF4, 0x78, 0xB3, 0x55, 0xCB, 0x84, 0xD2, 0x32, 0xC4, + 0x78, 0xAE, 0xA3, 0x8F, 0x61, 0xDD, 0xCE, 0x08, 0x53, 0xAD, 0xEC, 0x88, + 0xFC, 0x15, 0xE4, 0x9A, 0x0D, 0xE6, 0x9F, 0x1A, 0x77, 0xCE, 0x4C, 0x8F, + 0xB8, 0x14, 0x15, 0x3D, 0x62, 0x9C, 0x86, 0x38, 0x06, 0x00, 0x66, 0x12, + 0xE4, 0x59, 0x76, 0x5A, 0x53, 0xC0, 0x02, 0x98, 0xA2, 0x10, 0x2B, 0x68, + 0x44, 0x7B, 0x8E, 0x79, 0xCE, 0x33, 0x4A, 0x76, 0xAA, 0x5B, 0x81, 0x16, + 0x1B, 0xB5, 0x8A, 0xD8, 0xD0, 0x00, 0x7B, 0x5E, 0x62, 0xB4, 0x09, 0xD6, + 0x86, 0x63, 0x0E, 0xA6, 0x05, 0x95, 0x49, 0xBA, 0x28, 0x8B, 0x88, 0x93, + 0xB2, 0x34, 0x1C, 0xD8, 0xA4, 0x55, 0x6E, 0xB7, 0x1C, 0xD0, 0xDE, 0x99, + 0x55, 0x3B, 0x23, 0xF4, 0x22, 0xE0, 0xF9, 0x29, 0x66, 0x26, 0xEC, 0x20, + 0x50, 0x77, 0xDB, 0x4A, 0x0B, 0x8F, 0xBE, 0xE5, 0x02, 0x60, 0x70, 0x41, + 0x5E, 0xD4, 0xAE, 0x50, 0x39, 0x22, 0x14, 0x26, 0xCB, 0xB2, 0x3B, 0x73, + 0x74, 0x55, 0x47, 0x07, 0x79, 0x81, 0x39, 0xA8, 0x30, 0x13, 0x44, 0xE5, + 0x04, 0x8A, 0xAE, 0x96, 0x13, 0x25, 0x42, 0x0F, 0xB9, 0x53, 0xC4, 0x9B, + 0xFC, 0xCD, 0xE4, 0x1C, 0xDE, 0x3C, 0xFA, 0xAB, 0xD6, 0x06, 0x4A, 0x1F, + 0x67, 0xA6, 0x98, 0x30, 0x1C, 0xDD, 0x2C, 0xDB, 0xDC, 0x18, 0x95, 0x57, + 0x66, 0xC6, 0xFF, 0x5C, 0x8B, 0x56, 0xF5, 0x77 +}; + +static const unsigned char TA8_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA9_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA9_EC_Q[] = { + 0x04, 0xF1, 0xB3, 0xCD, 0x38, 0xE4, 0x25, 0x43, 0xE5, 0xDE, 0x19, 0x09, + 0xBB, 0x81, 0x79, 0xA2, 0x15, 0x5F, 0x15, 0x63, 0x01, 0xDE, 0xC2, 0xAB, + 0xDD, 0xB3, 0xA6, 0x1B, 0x67, 0x4B, 0x80, 0x83, 0xAF, 0x99, 0xCB, 0xAC, + 0x17, 0xDB, 0x2B, 0x96, 0xCA, 0x7C, 0x52, 0x55, 0xE2, 0x1A, 0xE1, 0x3D, + 0x56, 0xF0, 0x2F, 0x16, 0x08, 0xFA, 0x15, 0xBC, 0x9B, 0xBB, 0x47, 0xE6, + 0x3F, 0xEE, 0xA8, 0xE1, 0x4C, 0x8C, 0xF5, 0xD3, 0x36, 0xF9, 0x38, 0x5D, + 0xAB, 0x70, 0x9A, 0x47, 0x0D, 0xE2, 0x81, 0x41, 0x06, 0xEB, 0x49, 0xF9, + 0xB0, 0x29, 0xDD, 0x33, 0xEC, 0x50, 0xA5, 0x7F, 0x79, 0x29, 0xB8, 0x20, + 0x98 +}; + +static const unsigned char TA10_DN[] = { + 0x30, 0x81, 0x98, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3B, + 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA10_RSA_N[] = { + 0xD5, 0x0C, 0x3A, 0xC4, 0x2A, 0xF9, 0x4E, 0xE2, 0xF5, 0xBE, 0x19, 0x97, + 0x5F, 0x8E, 0x88, 0x53, 0xB1, 0x1F, 0x3F, 0xCB, 0xCF, 0x9F, 0x20, 0x13, + 0x6D, 0x29, 0x3A, 0xC8, 0x0F, 0x7D, 0x3C, 0xF7, 0x6B, 0x76, 0x38, 0x63, + 0xD9, 0x36, 0x60, 0xA8, 0x9B, 0x5E, 0x5C, 0x00, 0x80, 0xB2, 0x2F, 0x59, + 0x7F, 0xF6, 0x87, 0xF9, 0x25, 0x43, 0x86, 0xE7, 0x69, 0x1B, 0x52, 0x9A, + 0x90, 0xE1, 0x71, 0xE3, 0xD8, 0x2D, 0x0D, 0x4E, 0x6F, 0xF6, 0xC8, 0x49, + 0xD9, 0xB6, 0xF3, 0x1A, 0x56, 0xAE, 0x2B, 0xB6, 0x74, 0x14, 0xEB, 0xCF, + 0xFB, 0x26, 0xE3, 0x1A, 0xBA, 0x1D, 0x96, 0x2E, 0x6A, 0x3B, 0x58, 0x94, + 0x89, 0x47, 0x56, 0xFF, 0x25, 0xA0, 0x93, 0x70, 0x53, 0x83, 0xDA, 0x84, + 0x74, 0x14, 0xC3, 0x67, 0x9E, 0x04, 0x68, 0x3A, 0xDF, 0x8E, 0x40, 0x5A, + 0x1D, 0x4A, 0x4E, 0xCF, 0x43, 0x91, 0x3B, 0xE7, 0x56, 0xD6, 0x00, 0x70, + 0xCB, 0x52, 0xEE, 0x7B, 0x7D, 0xAE, 0x3A, 0xE7, 0xBC, 0x31, 0xF9, 0x45, + 0xF6, 0xC2, 0x60, 0xCF, 0x13, 0x59, 0x02, 0x2B, 0x80, 0xCC, 0x34, 0x47, + 0xDF, 0xB9, 0xDE, 0x90, 0x65, 0x6D, 0x02, 0xCF, 0x2C, 0x91, 0xA6, 0xA6, + 0xE7, 0xDE, 0x85, 0x18, 0x49, 0x7C, 0x66, 0x4E, 0xA3, 0x3A, 0x6D, 0xA9, + 0xB5, 0xEE, 0x34, 0x2E, 0xBA, 0x0D, 0x03, 0xB8, 0x33, 0xDF, 0x47, 0xEB, + 0xB1, 0x6B, 0x8D, 0x25, 0xD9, 0x9B, 0xCE, 0x81, 0xD1, 0x45, 0x46, 0x32, + 0x96, 0x70, 0x87, 0xDE, 0x02, 0x0E, 0x49, 0x43, 0x85, 0xB6, 0x6C, 0x73, + 0xBB, 0x64, 0xEA, 0x61, 0x41, 0xAC, 0xC9, 0xD4, 0x54, 0xDF, 0x87, 0x2F, + 0xC7, 0x22, 0xB2, 0x26, 0xCC, 0x9F, 0x59, 0x54, 0x68, 0x9F, 0xFC, 0xBE, + 0x2A, 0x2F, 0xC4, 0x55, 0x1C, 0x75, 0x40, 0x60, 0x17, 0x85, 0x02, 0x55, + 0x39, 0x8B, 0x7F, 0x05 +}; + +static const unsigned char TA10_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA11_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x33 +}; + +static const unsigned char TA11_EC_Q[] = { + 0x04, 0x1F, 0x4F, 0x33, 0x87, 0x33, 0x29, 0x8A, 0xA1, 0x84, 0xDE, 0xCB, + 0xC7, 0x21, 0x58, 0x41, 0x89, 0xEA, 0x56, 0x9D, 0x2B, 0x4B, 0x85, 0xC6, + 0x1D, 0x4C, 0x27, 0xBC, 0x7F, 0x26, 0x51, 0x72, 0x6F, 0xE2, 0x9F, 0xD6, + 0xA3, 0xCA, 0xCC, 0x45, 0x14, 0x46, 0x8B, 0xAD, 0xEF, 0x7E, 0x86, 0x8C, + 0xEC, 0xB1, 0x7E, 0x2F, 0xFF, 0xA9, 0x71, 0x9D, 0x18, 0x84, 0x45, 0x04, + 0x41, 0x55, 0x6E, 0x2B, 0xEA, 0x26, 0x7F, 0xBB, 0x90, 0x01, 0xE3, 0x4B, + 0x19, 0xBA, 0xE4, 0x54, 0x96, 0x45, 0x09, 0xB1, 0xD5, 0x6C, 0x91, 0x44, + 0xAD, 0x84, 0x13, 0x8E, 0x9A, 0x8C, 0x0D, 0x80, 0x0C, 0x32, 0xF6, 0xE0, + 0x27 +}; + +static const unsigned char TA12_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x30, 0x30, 0x2E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x27, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x61, + 0x6E, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0C, 0x43, 0x46, 0x43, 0x41, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA12_RSA_N[] = { + 0xD7, 0x5D, 0x6B, 0xCD, 0x10, 0x3F, 0x1F, 0x05, 0x59, 0xD5, 0x05, 0x4D, + 0x37, 0xB1, 0x0E, 0xEC, 0x98, 0x2B, 0x8E, 0x15, 0x1D, 0xFA, 0x93, 0x4B, + 0x17, 0x82, 0x21, 0x71, 0x10, 0x52, 0xD7, 0x51, 0x64, 0x70, 0x16, 0xC2, + 0x55, 0x69, 0x4D, 0x8E, 0x15, 0x6D, 0x9F, 0xBF, 0x0C, 0x1B, 0xC2, 0xE0, + 0xA3, 0x67, 0xD6, 0x0C, 0xAC, 0xCF, 0x22, 0xAE, 0xAF, 0x77, 0x54, 0x2A, + 0x4B, 0x4C, 0x8A, 0x53, 0x52, 0x7A, 0xC3, 0xEE, 0x2E, 0xDE, 0xB3, 0x71, + 0x25, 0xC1, 0xE9, 0x5D, 0x3D, 0xEE, 0xA1, 0x2F, 0xA3, 0xF7, 0x2A, 0x3C, + 0xC9, 0x23, 0x1D, 0x6A, 0xAB, 0x1D, 0xA1, 0xA7, 0xF1, 0xF3, 0xEC, 0xA0, + 0xD5, 0x44, 0xCF, 0x15, 0xCF, 0x72, 0x2F, 0x1D, 0x63, 0x97, 0xE8, 0x99, + 0xF9, 0xFD, 0x93, 0xA4, 0x54, 0x80, 0x4C, 0x52, 0xD4, 0x52, 0xAB, 0x2E, + 0x49, 0xDF, 0x90, 0xCD, 0xB8, 0x5F, 0xBE, 0x3F, 0xDE, 0xA1, 0xCA, 0x4D, + 0x20, 0xD4, 0x25, 0xE8, 0x84, 0x29, 0x53, 0xB7, 0xB1, 0x88, 0x1F, 0xFF, + 0xFA, 0xDA, 0x90, 0x9F, 0x0A, 0xA9, 0x2D, 0x41, 0x3F, 0xB1, 0xF1, 0x18, + 0x29, 0xEE, 0x16, 0x59, 0x2C, 0x34, 0x49, 0x1A, 0xA8, 0x06, 0xD7, 0xA8, + 0x88, 0xD2, 0x03, 0x72, 0x7A, 0x32, 0xE2, 0xEA, 0x68, 0x4D, 0x6E, 0x2C, + 0x96, 0x65, 0x7B, 0xCA, 0x59, 0xFA, 0xF2, 0xE2, 0xDD, 0xEE, 0x30, 0x2C, + 0xFB, 0xCC, 0x46, 0xAC, 0xC4, 0x63, 0xEB, 0x6F, 0x7F, 0x36, 0x2B, 0x34, + 0x73, 0x12, 0x94, 0x7F, 0xDF, 0xCC, 0x26, 0x9E, 0xF1, 0x72, 0x5D, 0x50, + 0x65, 0x59, 0x8F, 0x69, 0xB3, 0x87, 0x5E, 0x32, 0x6F, 0xC3, 0x18, 0x8A, + 0xB5, 0x95, 0x8F, 0xB0, 0x7A, 0x37, 0xDE, 0x5A, 0x45, 0x3B, 0xC7, 0x36, + 0xE1, 0xEF, 0x67, 0xD1, 0x39, 0xD3, 0x97, 0x5B, 0x73, 0x62, 0x19, 0x48, + 0x2D, 0x87, 0x1C, 0x06, 0xFB, 0x74, 0x98, 0x20, 0x49, 0x73, 0xF0, 0x05, + 0xD2, 0x1B, 0xB1, 0xA0, 0xA3, 0xB7, 0x1B, 0x70, 0xD3, 0x88, 0x69, 0xB9, + 0x5A, 0xD6, 0x38, 0xF4, 0x62, 0xDC, 0x25, 0x8B, 0x78, 0xBF, 0xF8, 0xE8, + 0x7E, 0xB8, 0x5C, 0xC9, 0x95, 0x4F, 0x5F, 0xA7, 0x2D, 0xB9, 0x20, 0x6B, + 0xCF, 0x6B, 0xDD, 0xF5, 0x0D, 0xF4, 0x82, 0xB7, 0xF4, 0xB2, 0x66, 0x2E, + 0x10, 0x28, 0xF6, 0x97, 0x5A, 0x7B, 0x96, 0x16, 0x8F, 0x01, 0x19, 0x2D, + 0x6C, 0x6E, 0x7F, 0x39, 0x58, 0x06, 0x64, 0x83, 0x01, 0x83, 0x83, 0xC3, + 0x4D, 0x92, 0xDD, 0x32, 0xC6, 0x87, 0xA4, 0x37, 0xE9, 0x16, 0xCE, 0xAA, + 0x2D, 0x68, 0xAF, 0x0A, 0x81, 0x65, 0x3A, 0x70, 0xC1, 0x9B, 0xAD, 0x4D, + 0x6D, 0x54, 0xCA, 0x2A, 0x2D, 0x4B, 0x85, 0x1B, 0xB3, 0x80, 0xE6, 0x70, + 0x45, 0x0D, 0x6B, 0x5E, 0x35, 0xF0, 0x7F, 0x3B, 0xB8, 0x9C, 0xE4, 0x04, + 0x70, 0x89, 0x12, 0x25, 0x93, 0xDA, 0x0A, 0x99, 0x22, 0x60, 0x6A, 0x63, + 0x60, 0x4E, 0x76, 0x06, 0x98, 0x4E, 0xBD, 0x83, 0xAD, 0x1D, 0x58, 0x8A, + 0x25, 0x85, 0xD2, 0xC7, 0x65, 0x1E, 0x2D, 0x8E, 0xC6, 0xDF, 0xB6, 0xC6, + 0xE1, 0x7F, 0x8A, 0x04, 0x21, 0x15, 0x29, 0x74, 0xF0, 0x3E, 0x9C, 0x90, + 0x9D, 0x0C, 0x2E, 0xF1, 0x8A, 0x3E, 0x5A, 0xAA, 0x0C, 0x09, 0x1E, 0xC7, + 0xD5, 0x3C, 0xA3, 0xED, 0x97, 0xC3, 0x1E, 0x34, 0xFA, 0x38, 0xF9, 0x08, + 0x0E, 0xE3, 0xC0, 0x5D, 0x2B, 0x83, 0xD1, 0x56, 0x6A, 0xC9, 0xB6, 0xA8, + 0x54, 0x53, 0x2E, 0x78, 0x32, 0x67, 0x3D, 0x82, 0x7F, 0x74, 0xD0, 0xFB, + 0xE1, 0xB6, 0x05, 0x60, 0xB9, 0x70, 0xDB, 0x8E, 0x0B, 0xF9, 0x13, 0x58, + 0x6F, 0x71, 0x60, 0x10, 0x52, 0x10, 0xB9, 0xC1, 0x41, 0x09, 0xEF, 0x72, + 0x1F, 0x67, 0x31, 0x78, 0xFF, 0x96, 0x05, 0x8D +}; + +static const unsigned char TA12_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA13_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x32 +}; + +static const unsigned char TA13_EC_Q[] = { + 0x04, 0xCD, 0x9B, 0xD5, 0x9F, 0x80, 0x83, 0x0A, 0xEC, 0x09, 0x4A, 0xF3, + 0x16, 0x4A, 0x3E, 0x5C, 0xCF, 0x77, 0xAC, 0xDE, 0x67, 0x05, 0x0D, 0x1D, + 0x07, 0xB6, 0xDC, 0x16, 0xFB, 0x5A, 0x8B, 0x14, 0xDB, 0xE2, 0x71, 0x60, + 0xC4, 0xBA, 0x45, 0x95, 0x11, 0x89, 0x8E, 0xEA, 0x06, 0xDF, 0xF7, 0x2A, + 0x16, 0x1C, 0xA4, 0xB9, 0xC5, 0xC5, 0x32, 0xE0, 0x03, 0xE0, 0x1E, 0x82, + 0x18, 0x38, 0x8B, 0xD7, 0x45, 0xD8, 0x0A, 0x6A, 0x6E, 0xE6, 0x00, 0x77, + 0xFB, 0x02, 0x51, 0x7D, 0x22, 0xD8, 0x0A, 0x6E, 0x9A, 0x5B, 0x77, 0xDF, + 0xF0, 0xFA, 0x41, 0xEC, 0x39, 0xDC, 0x75, 0xCA, 0x68, 0x07, 0x0C, 0x1F, + 0xEA +}; + +static const unsigned char TA14_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA14_EC_Q[] = { + 0x04, 0x45, 0x6E, 0xA9, 0x50, 0xC4, 0xA6, 0x23, 0x36, 0x9E, 0x5F, 0x28, + 0x8D, 0x17, 0xCB, 0x96, 0x22, 0x64, 0x3F, 0xDC, 0x7A, 0x8E, 0x1D, 0xCC, + 0x08, 0xB3, 0xA2, 0x71, 0x24, 0xBA, 0x8E, 0x49, 0xB9, 0x04, 0x1B, 0x47, + 0x96, 0x58, 0xAB, 0x2D, 0x95, 0xC8, 0xED, 0x9E, 0x08, 0x35, 0xC8, 0x27, + 0xEB, 0x89, 0x8C, 0x53, 0x58, 0xEB, 0x62, 0x8A, 0xFE, 0xF0, 0x5B, 0x0F, + 0x6B, 0x31, 0x52, 0x63, 0x41, 0x3B, 0x89, 0xCD, 0xEC, 0xEC, 0xB6, 0x8D, + 0x19, 0xD3, 0x34, 0x07, 0xDC, 0xBB, 0xC6, 0x06, 0x7F, 0xC2, 0x45, 0x95, + 0xEC, 0xCB, 0x7F, 0xA8, 0x23, 0xE0, 0x09, 0xE9, 0x81, 0xFA, 0xF3, 0x47, + 0xD3 +}; + +static const unsigned char TA15_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x34, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA15_EC_Q[] = { + 0x04, 0xB8, 0xC6, 0x79, 0xD3, 0x8F, 0x6C, 0x25, 0x0E, 0x9F, 0x2E, 0x39, + 0x19, 0x1C, 0x03, 0xA4, 0xAE, 0x9A, 0xE5, 0x39, 0x07, 0x09, 0x16, 0xCA, + 0x63, 0xB1, 0xB9, 0x86, 0xF8, 0x8A, 0x57, 0xC1, 0x57, 0xCE, 0x42, 0xFA, + 0x73, 0xA1, 0xF7, 0x65, 0x42, 0xFF, 0x1E, 0xC1, 0x00, 0xB2, 0x6E, 0x73, + 0x0E, 0xFF, 0xC7, 0x21, 0xE5, 0x18, 0xA4, 0xAA, 0xD9, 0x71, 0x3F, 0xA8, + 0xD4, 0xB9, 0xCE, 0x8C, 0x1D +}; + +static const unsigned char TA16_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x55, 0x43, 0x41, + 0x20, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, + 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74 +}; + +static const unsigned char TA16_RSA_N[] = { + 0xA9, 0x09, 0x07, 0x28, 0x13, 0x02, 0xB0, 0x99, 0xE0, 0x64, 0xAA, 0x1E, + 0x43, 0x16, 0x7A, 0x73, 0xB1, 0x91, 0xA0, 0x75, 0x3E, 0xA8, 0xFA, 0xE3, + 0x38, 0x00, 0x7A, 0xEC, 0x89, 0x6A, 0x20, 0x0F, 0x8B, 0xC5, 0xB0, 0x9B, + 0x33, 0x03, 0x5A, 0x86, 0xC6, 0x58, 0x86, 0xD5, 0xC1, 0x85, 0xBB, 0x4F, + 0xC6, 0x9C, 0x40, 0x4D, 0xCA, 0xBE, 0xEE, 0x69, 0x96, 0xB8, 0xAD, 0x81, + 0x30, 0x9A, 0x7C, 0x92, 0x05, 0xEB, 0x05, 0x2B, 0x9A, 0x48, 0xD0, 0xB8, + 0x76, 0x3E, 0x96, 0xC8, 0x20, 0xBB, 0xD2, 0xB0, 0xF1, 0x8F, 0xD8, 0xAC, + 0x45, 0x46, 0xFF, 0xAA, 0x67, 0x60, 0xB4, 0x77, 0x7E, 0x6A, 0x1F, 0x3C, + 0x1A, 0x52, 0x7A, 0x04, 0x3D, 0x07, 0x3C, 0x85, 0x0D, 0x84, 0xD0, 0x1F, + 0x76, 0x0A, 0xF7, 0x6A, 0x14, 0xDF, 0x72, 0xE3, 0x34, 0x7C, 0x57, 0x4E, + 0x56, 0x01, 0x3E, 0x79, 0xF1, 0xAA, 0x29, 0x3B, 0x6C, 0xFA, 0xF8, 0x8F, + 0x6D, 0x4D, 0xC8, 0x35, 0xDF, 0xAE, 0xEB, 0xDC, 0x24, 0xEE, 0x79, 0x45, + 0xA7, 0x85, 0xB6, 0x05, 0x88, 0xDE, 0x88, 0x5D, 0x25, 0x7C, 0x97, 0x64, + 0x67, 0x09, 0xD9, 0xBF, 0x5A, 0x15, 0x05, 0x86, 0xF3, 0x09, 0x1E, 0xEC, + 0x58, 0x32, 0x33, 0x11, 0xF3, 0x77, 0x64, 0xB0, 0x76, 0x1F, 0xE4, 0x10, + 0x35, 0x17, 0x1B, 0xF2, 0x0E, 0xB1, 0x6C, 0xA4, 0x2A, 0xA3, 0x73, 0xFC, + 0x09, 0x1F, 0x1E, 0x32, 0x19, 0x53, 0x11, 0xE7, 0xD9, 0xB3, 0x2C, 0x2E, + 0x76, 0x2E, 0xA1, 0xA3, 0xDE, 0x7E, 0x6A, 0x88, 0x09, 0xE8, 0xF2, 0x07, + 0x8A, 0xF8, 0xB2, 0xCD, 0x10, 0xE7, 0xE2, 0x73, 0x40, 0x93, 0xBB, 0x08, + 0xD1, 0x3F, 0xE1, 0xFC, 0x0B, 0x94, 0xB3, 0x25, 0xEF, 0x7C, 0xA6, 0xD7, + 0xD1, 0xAF, 0x9F, 0xFF, 0x96, 0x9A, 0xF5, 0x91, 0x7B, 0x98, 0x0B, 0x77, + 0xD4, 0x7E, 0xE8, 0x07, 0xD2, 0x62, 0xB5, 0x95, 0x39, 0xE3, 0xF3, 0xF1, + 0x6D, 0x0F, 0x0E, 0x65, 0x84, 0x8A, 0x63, 0x54, 0xC5, 0x80, 0xB6, 0xE0, + 0x9E, 0x4B, 0x7D, 0x47, 0x26, 0xA7, 0x01, 0x08, 0x5D, 0xD1, 0x88, 0x9E, + 0xD7, 0xC3, 0x32, 0x44, 0xFA, 0x82, 0x4A, 0x0A, 0x68, 0x54, 0x7F, 0x38, + 0x53, 0x03, 0xCC, 0xA4, 0x00, 0x33, 0x64, 0x51, 0x59, 0x0B, 0xA3, 0x82, + 0x91, 0x7A, 0x5E, 0xEC, 0x16, 0xC2, 0xF3, 0x2A, 0xE6, 0x62, 0xDA, 0x2A, + 0xDB, 0x59, 0x62, 0x10, 0x25, 0x4A, 0x2A, 0x81, 0x0B, 0x47, 0x07, 0x43, + 0x06, 0x70, 0x87, 0xD2, 0xFA, 0x93, 0x11, 0x29, 0x7A, 0x48, 0x4D, 0xEB, + 0x94, 0xC7, 0x70, 0x4D, 0xAF, 0x67, 0xD5, 0x51, 0xB1, 0x80, 0x20, 0x01, + 0x01, 0xB4, 0x7A, 0x08, 0xA6, 0x90, 0x7F, 0x4E, 0xE0, 0xEF, 0x07, 0x41, + 0x87, 0xAF, 0x6A, 0xA5, 0x5E, 0x8B, 0xFB, 0xCF, 0x50, 0xB2, 0x9A, 0x54, + 0xAF, 0xC3, 0x89, 0xBA, 0x58, 0x2D, 0xF5, 0x30, 0x98, 0xB1, 0x36, 0x72, + 0x39, 0x7E, 0x49, 0x04, 0xFD, 0x29, 0xA7, 0x4C, 0x79, 0xE4, 0x05, 0x57, + 0xDB, 0x94, 0xB9, 0x16, 0x53, 0x8D, 0x46, 0xB3, 0x1D, 0x95, 0x61, 0x57, + 0x56, 0x7F, 0xAF, 0xF0, 0x16, 0x5B, 0x61, 0x58, 0x6F, 0x36, 0x50, 0x11, + 0x0B, 0xD8, 0xAC, 0x2B, 0x95, 0x16, 0x1A, 0x0E, 0x1F, 0x08, 0xCD, 0x36, + 0x34, 0x65, 0x10, 0x62, 0x66, 0xD5, 0x80, 0x5F, 0x14, 0x20, 0x5F, 0x2D, + 0x0C, 0xA0, 0x78, 0x0A, 0x68, 0xD6, 0x2C, 0xD7, 0xE9, 0x6F, 0x2B, 0xD2, + 0x4A, 0x05, 0x93, 0xFC, 0x9E, 0x6F, 0x6B, 0x67, 0xFF, 0x88, 0xF1, 0x4E, + 0xA5, 0x69, 0x4A, 0x52, 0x37, 0x05, 0xEA, 0xC6, 0x16, 0x8D, 0xD2, 0xC4, + 0x99, 0xD1, 0x82, 0x2B, 0x3B, 0xBA, 0x35, 0x75, 0xF7, 0x51, 0x51, 0x58, + 0xF3, 0xC8, 0x07, 0xDD, 0xE4, 0xB4, 0x03, 0x7F +}; + +static const unsigned char TA16_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA17_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x29, 0x47, 0x55, 0x41, 0x4E, 0x47, 0x20, 0x44, 0x4F, 0x4E, 0x47, + 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, + 0x20, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x20, 0x43, + 0x4F, 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x47, 0x44, 0x43, 0x41, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x41, 0x55, 0x54, 0x48, 0x20, 0x52, 0x35, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA17_RSA_N[] = { + 0xD9, 0xA3, 0x16, 0xF0, 0xC8, 0x74, 0x74, 0x77, 0x9B, 0xEF, 0x33, 0x0D, + 0x3B, 0x06, 0x7E, 0x55, 0xFC, 0xB5, 0x60, 0x8F, 0x76, 0x86, 0x12, 0x42, + 0x7D, 0x56, 0x66, 0x3E, 0x88, 0x82, 0xED, 0x72, 0x63, 0x0E, 0x9E, 0x8B, + 0xDD, 0x34, 0x2C, 0x02, 0x51, 0x51, 0xC3, 0x19, 0xFD, 0x59, 0x54, 0x84, + 0xC9, 0xF1, 0x6B, 0xB3, 0x4C, 0xB0, 0xE9, 0xE8, 0x46, 0x5D, 0x38, 0xC6, + 0xA2, 0xA7, 0x2E, 0x11, 0x57, 0xBA, 0x82, 0x15, 0xA2, 0x9C, 0x8F, 0x6D, + 0xB0, 0x99, 0x4A, 0x0A, 0xF2, 0xEB, 0x89, 0x70, 0x63, 0x4E, 0x79, 0xC4, + 0xB7, 0x5B, 0xBD, 0xA2, 0x5D, 0xB1, 0xF2, 0x41, 0x02, 0x2B, 0xAD, 0xA9, + 0x3A, 0xA3, 0xEC, 0x79, 0x0A, 0xEC, 0x5F, 0x3A, 0xE3, 0xFD, 0xEF, 0x80, + 0x3C, 0xAD, 0x34, 0x9B, 0x1A, 0xAB, 0x88, 0x26, 0x7B, 0x56, 0xA2, 0x82, + 0x86, 0x1F, 0xEB, 0x35, 0x89, 0x83, 0x7F, 0x5F, 0xAE, 0x29, 0x4E, 0x3D, + 0xB6, 0x6E, 0xEC, 0xAE, 0xC1, 0xF0, 0x27, 0x9B, 0xAE, 0xE3, 0xF4, 0xEC, + 0xEF, 0xAE, 0x7F, 0xF7, 0x86, 0x3D, 0x72, 0x7A, 0xEB, 0xA5, 0xFB, 0x59, + 0x4E, 0xA7, 0xEB, 0x95, 0x8C, 0x22, 0x39, 0x79, 0xE1, 0x2D, 0x08, 0x8F, + 0xCC, 0xBC, 0x91, 0xB8, 0x41, 0xF7, 0x14, 0xC1, 0x23, 0xA9, 0xC3, 0xAD, + 0x9A, 0x45, 0x44, 0xB3, 0xB2, 0xD7, 0x2C, 0xCD, 0xC6, 0x29, 0xE2, 0x50, + 0x10, 0xAE, 0x5C, 0xCB, 0x82, 0x8E, 0x17, 0x18, 0x36, 0x7D, 0x97, 0xE6, + 0x88, 0x9A, 0xB0, 0x4D, 0x34, 0x09, 0xF4, 0x2C, 0xB9, 0x5A, 0x66, 0x2A, + 0xB0, 0x17, 0x9B, 0x9E, 0x1E, 0x76, 0x9D, 0x4A, 0x66, 0x31, 0x41, 0xDF, + 0x3F, 0xFB, 0xC5, 0x06, 0xEF, 0x1B, 0xB6, 0x7E, 0x1A, 0x46, 0x36, 0xF7, + 0x64, 0x63, 0x3B, 0xE3, 0x39, 0x18, 0x23, 0xE7, 0x67, 0x75, 0x14, 0xD5, + 0x75, 0x57, 0x92, 0x37, 0xBD, 0xBE, 0x6A, 0x1B, 0x26, 0x50, 0xF2, 0x36, + 0x26, 0x06, 0x90, 0xC5, 0x70, 0x01, 0x64, 0x6D, 0x76, 0x66, 0xE1, 0x91, + 0xDB, 0x6E, 0x07, 0xC0, 0x61, 0x80, 0x2E, 0xB2, 0x2E, 0x2F, 0x8C, 0x70, + 0xA7, 0xD1, 0x3B, 0x3C, 0xB3, 0x91, 0xE4, 0x6E, 0xB6, 0xC4, 0x3B, 0x70, + 0xF2, 0x6C, 0x92, 0x97, 0x09, 0xCD, 0x47, 0x7D, 0x18, 0xC0, 0xF3, 0xBB, + 0x9E, 0x0F, 0xD6, 0x8B, 0xAE, 0x07, 0xB6, 0x5A, 0x0F, 0xCE, 0x0B, 0x0C, + 0x47, 0xA7, 0xE5, 0x3E, 0xB8, 0xBD, 0x7D, 0xC7, 0x9B, 0x35, 0xA0, 0x61, + 0x97, 0x3A, 0x41, 0x75, 0x17, 0xCC, 0x2B, 0x96, 0x77, 0x2A, 0x92, 0x21, + 0x1E, 0xD9, 0x95, 0x76, 0x20, 0x67, 0x68, 0xCF, 0x0D, 0xBD, 0xDF, 0xD6, + 0x1F, 0x09, 0x6A, 0x9A, 0xE2, 0xCC, 0x73, 0x71, 0xA4, 0x2F, 0x7D, 0x12, + 0x80, 0xB7, 0x53, 0x30, 0x46, 0x5E, 0x4B, 0x54, 0x99, 0x0F, 0x67, 0xC9, + 0xA5, 0xC8, 0xF2, 0x20, 0xC1, 0x82, 0xEC, 0x9D, 0x11, 0xDF, 0xC2, 0x02, + 0xFB, 0x1A, 0x3B, 0xD1, 0xED, 0x20, 0x9A, 0xEF, 0x65, 0x64, 0x92, 0x10, + 0x0D, 0x2A, 0xE2, 0xDE, 0x70, 0xF1, 0x18, 0x67, 0x82, 0x8C, 0x61, 0xDE, + 0xB8, 0xBC, 0xD1, 0x2F, 0x9C, 0xFB, 0x0F, 0xD0, 0x2B, 0xED, 0x1B, 0x76, + 0xB9, 0xE4, 0x39, 0x55, 0xF8, 0xF8, 0xA1, 0x1D, 0xB8, 0xAA, 0x80, 0x00, + 0x4C, 0x82, 0xE7, 0xB2, 0x7F, 0x09, 0xB8, 0xBC, 0x30, 0xA0, 0x2F, 0x0D, + 0xF5, 0x52, 0x9E, 0x8E, 0xF7, 0x92, 0xB3, 0x0A, 0x00, 0x1D, 0x00, 0x54, + 0x97, 0x06, 0xE0, 0xB1, 0x07, 0xD9, 0xC7, 0x0F, 0x5C, 0x65, 0x7D, 0x3C, + 0x6D, 0x59, 0x57, 0xE4, 0xED, 0xA5, 0x8D, 0xE9, 0x40, 0x53, 0x9F, 0x15, + 0x4B, 0xA0, 0x71, 0xF6, 0x1A, 0x21, 0xE3, 0xDA, 0x70, 0x06, 0x21, 0x58, + 0x14, 0x87, 0x85, 0x77, 0x79, 0xAA, 0x82, 0x79 +}; + +static const unsigned char TA17_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA18_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x31 +}; + +static const unsigned char TA18_RSA_N[] = { + 0xB6, 0x11, 0x02, 0x8B, 0x1E, 0xE3, 0xA1, 0x77, 0x9B, 0x3B, 0xDC, 0xBF, + 0x94, 0x3E, 0xB7, 0x95, 0xA7, 0x40, 0x3C, 0xA1, 0xFD, 0x82, 0xF9, 0x7D, + 0x32, 0x06, 0x82, 0x71, 0xF6, 0xF6, 0x8C, 0x7F, 0xFB, 0xE8, 0xDB, 0xBC, + 0x6A, 0x2E, 0x97, 0x97, 0xA3, 0x8C, 0x4B, 0xF9, 0x2B, 0xF6, 0xB1, 0xF9, + 0xCE, 0x84, 0x1D, 0xB1, 0xF9, 0xC5, 0x97, 0xDE, 0xEF, 0xB9, 0xF2, 0xA3, + 0xE9, 0xBC, 0x12, 0x89, 0x5E, 0xA7, 0xAA, 0x52, 0xAB, 0xF8, 0x23, 0x27, + 0xCB, 0xA4, 0xB1, 0x9C, 0x63, 0xDB, 0xD7, 0x99, 0x7E, 0xF0, 0x0A, 0x5E, + 0xEB, 0x68, 0xA6, 0xF4, 0xC6, 0x5A, 0x47, 0x0D, 0x4D, 0x10, 0x33, 0xE3, + 0x4E, 0xB1, 0x13, 0xA3, 0xC8, 0x18, 0x6C, 0x4B, 0xEC, 0xFC, 0x09, 0x90, + 0xDF, 0x9D, 0x64, 0x29, 0x25, 0x23, 0x07, 0xA1, 0xB4, 0xD2, 0x3D, 0x2E, + 0x60, 0xE0, 0xCF, 0xD2, 0x09, 0x87, 0xBB, 0xCD, 0x48, 0xF0, 0x4D, 0xC2, + 0xC2, 0x7A, 0x88, 0x8A, 0xBB, 0xBA, 0xCF, 0x59, 0x19, 0xD6, 0xAF, 0x8F, + 0xB0, 0x07, 0xB0, 0x9E, 0x31, 0xF1, 0x82, 0xC1, 0xC0, 0xDF, 0x2E, 0xA6, + 0x6D, 0x6C, 0x19, 0x0E, 0xB5, 0xD8, 0x7E, 0x26, 0x1A, 0x45, 0x03, 0x3D, + 0xB0, 0x79, 0xA4, 0x94, 0x28, 0xAD, 0x0F, 0x7F, 0x26, 0xE5, 0xA8, 0x08, + 0xFE, 0x96, 0xE8, 0x3C, 0x68, 0x94, 0x53, 0xEE, 0x83, 0x3A, 0x88, 0x2B, + 0x15, 0x96, 0x09, 0xB2, 0xE0, 0x7A, 0x8C, 0x2E, 0x75, 0xD6, 0x9C, 0xEB, + 0xA7, 0x56, 0x64, 0x8F, 0x96, 0x4F, 0x68, 0xAE, 0x3D, 0x97, 0xC2, 0x84, + 0x8F, 0xC0, 0xBC, 0x40, 0xC0, 0x0B, 0x5C, 0xBD, 0xF6, 0x87, 0xB3, 0x35, + 0x6C, 0xAC, 0x18, 0x50, 0x7F, 0x84, 0xE0, 0x4C, 0xCD, 0x92, 0xD3, 0x20, + 0xE9, 0x33, 0xBC, 0x52, 0x99, 0xAF, 0x32, 0xB5, 0x29, 0xB3, 0x25, 0x2A, + 0xB4, 0x48, 0xF9, 0x72, 0xE1, 0xCA, 0x64, 0xF7, 0xE6, 0x82, 0x10, 0x8D, + 0xE8, 0x9D, 0xC2, 0x8A, 0x88, 0xFA, 0x38, 0x66, 0x8A, 0xFC, 0x63, 0xF9, + 0x01, 0xF9, 0x78, 0xFD, 0x7B, 0x5C, 0x77, 0xFA, 0x76, 0x87, 0xFA, 0xEC, + 0xDF, 0xB1, 0x0E, 0x79, 0x95, 0x57, 0xB4, 0xBD, 0x26, 0xEF, 0xD6, 0x01, + 0xD1, 0xEB, 0x16, 0x0A, 0xBB, 0x8E, 0x0B, 0xB5, 0xC5, 0xC5, 0x8A, 0x55, + 0xAB, 0xD3, 0xAC, 0xEA, 0x91, 0x4B, 0x29, 0xCC, 0x19, 0xA4, 0x32, 0x25, + 0x4E, 0x2A, 0xF1, 0x65, 0x44, 0xD0, 0x02, 0xCE, 0xAA, 0xCE, 0x49, 0xB4, + 0xEA, 0x9F, 0x7C, 0x83, 0xB0, 0x40, 0x7B, 0xE7, 0x43, 0xAB, 0xA7, 0x6C, + 0xA3, 0x8F, 0x7D, 0x89, 0x81, 0xFA, 0x4C, 0xA5, 0xFF, 0xD5, 0x8E, 0xC3, + 0xCE, 0x4B, 0xE0, 0xB5, 0xD8, 0xB3, 0x8E, 0x45, 0xCF, 0x76, 0xC0, 0xED, + 0x40, 0x2B, 0xFD, 0x53, 0x0F, 0xB0, 0xA7, 0xD5, 0x3B, 0x0D, 0xB1, 0x8A, + 0xA2, 0x03, 0xDE, 0x31, 0xAD, 0xCC, 0x77, 0xEA, 0x6F, 0x7B, 0x3E, 0xD6, + 0xDF, 0x91, 0x22, 0x12, 0xE6, 0xBE, 0xFA, 0xD8, 0x32, 0xFC, 0x10, 0x63, + 0x14, 0x51, 0x72, 0xDE, 0x5D, 0xD6, 0x16, 0x93, 0xBD, 0x29, 0x68, 0x33, + 0xEF, 0x3A, 0x66, 0xEC, 0x07, 0x8A, 0x26, 0xDF, 0x13, 0xD7, 0x57, 0x65, + 0x78, 0x27, 0xDE, 0x5E, 0x49, 0x14, 0x00, 0xA2, 0x00, 0x7F, 0x9A, 0xA8, + 0x21, 0xB6, 0xA9, 0xB1, 0x95, 0xB0, 0xA5, 0xB9, 0x0D, 0x16, 0x11, 0xDA, + 0xC7, 0x6C, 0x48, 0x3C, 0x40, 0xE0, 0x7E, 0x0D, 0x5A, 0xCD, 0x56, 0x3C, + 0xD1, 0x97, 0x05, 0xB9, 0xCB, 0x4B, 0xED, 0x39, 0x4B, 0x9C, 0xC4, 0x3F, + 0xD2, 0x55, 0x13, 0x6E, 0x24, 0xB0, 0xD6, 0x71, 0xFA, 0xF4, 0xC1, 0xBA, + 0xCC, 0xED, 0x1B, 0xF5, 0xFE, 0x81, 0x41, 0xD8, 0x00, 0x98, 0x3D, 0x3A, + 0xC8, 0xAE, 0x7A, 0x98, 0x37, 0x18, 0x05, 0x95 +}; + +static const unsigned char TA18_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA19_DN[] = { + 0x30, 0x81, 0x98, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3B, + 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA19_RSA_N[] = { + 0xD5, 0x0C, 0x3A, 0xC4, 0x2A, 0xF9, 0x4E, 0xE2, 0xF5, 0xBE, 0x19, 0x97, + 0x5F, 0x8E, 0x88, 0x53, 0xB1, 0x1F, 0x3F, 0xCB, 0xCF, 0x9F, 0x20, 0x13, + 0x6D, 0x29, 0x3A, 0xC8, 0x0F, 0x7D, 0x3C, 0xF7, 0x6B, 0x76, 0x38, 0x63, + 0xD9, 0x36, 0x60, 0xA8, 0x9B, 0x5E, 0x5C, 0x00, 0x80, 0xB2, 0x2F, 0x59, + 0x7F, 0xF6, 0x87, 0xF9, 0x25, 0x43, 0x86, 0xE7, 0x69, 0x1B, 0x52, 0x9A, + 0x90, 0xE1, 0x71, 0xE3, 0xD8, 0x2D, 0x0D, 0x4E, 0x6F, 0xF6, 0xC8, 0x49, + 0xD9, 0xB6, 0xF3, 0x1A, 0x56, 0xAE, 0x2B, 0xB6, 0x74, 0x14, 0xEB, 0xCF, + 0xFB, 0x26, 0xE3, 0x1A, 0xBA, 0x1D, 0x96, 0x2E, 0x6A, 0x3B, 0x58, 0x94, + 0x89, 0x47, 0x56, 0xFF, 0x25, 0xA0, 0x93, 0x70, 0x53, 0x83, 0xDA, 0x84, + 0x74, 0x14, 0xC3, 0x67, 0x9E, 0x04, 0x68, 0x3A, 0xDF, 0x8E, 0x40, 0x5A, + 0x1D, 0x4A, 0x4E, 0xCF, 0x43, 0x91, 0x3B, 0xE7, 0x56, 0xD6, 0x00, 0x70, + 0xCB, 0x52, 0xEE, 0x7B, 0x7D, 0xAE, 0x3A, 0xE7, 0xBC, 0x31, 0xF9, 0x45, + 0xF6, 0xC2, 0x60, 0xCF, 0x13, 0x59, 0x02, 0x2B, 0x80, 0xCC, 0x34, 0x47, + 0xDF, 0xB9, 0xDE, 0x90, 0x65, 0x6D, 0x02, 0xCF, 0x2C, 0x91, 0xA6, 0xA6, + 0xE7, 0xDE, 0x85, 0x18, 0x49, 0x7C, 0x66, 0x4E, 0xA3, 0x3A, 0x6D, 0xA9, + 0xB5, 0xEE, 0x34, 0x2E, 0xBA, 0x0D, 0x03, 0xB8, 0x33, 0xDF, 0x47, 0xEB, + 0xB1, 0x6B, 0x8D, 0x25, 0xD9, 0x9B, 0xCE, 0x81, 0xD1, 0x45, 0x46, 0x32, + 0x96, 0x70, 0x87, 0xDE, 0x02, 0x0E, 0x49, 0x43, 0x85, 0xB6, 0x6C, 0x73, + 0xBB, 0x64, 0xEA, 0x61, 0x41, 0xAC, 0xC9, 0xD4, 0x54, 0xDF, 0x87, 0x2F, + 0xC7, 0x22, 0xB2, 0x26, 0xCC, 0x9F, 0x59, 0x54, 0x68, 0x9F, 0xFC, 0xBE, + 0x2A, 0x2F, 0xC4, 0x55, 0x1C, 0x75, 0x40, 0x60, 0x17, 0x85, 0x02, 0x55, + 0x39, 0x8B, 0x7F, 0x05 +}; + +static const unsigned char TA19_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA20_DN[] = { + 0x30, 0x81, 0xBF, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x33, 0x30, + 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x45, + 0x43, 0x31 +}; + +static const unsigned char TA20_EC_Q[] = { + 0x04, 0x84, 0x13, 0xC9, 0xD0, 0xBA, 0x6D, 0x41, 0x7B, 0xE2, 0x6C, 0xD0, + 0xEB, 0x55, 0x5F, 0x66, 0x02, 0x1A, 0x24, 0xF4, 0x5B, 0x89, 0x69, 0x47, + 0xE3, 0xB8, 0xC2, 0x7D, 0xF1, 0xF2, 0x02, 0xC5, 0x9F, 0xA0, 0xF6, 0x5B, + 0xD5, 0x8B, 0x06, 0x19, 0x86, 0x4F, 0x53, 0x10, 0x6D, 0x07, 0x24, 0x27, + 0xA1, 0xA0, 0xF8, 0xD5, 0x47, 0x19, 0x61, 0x4C, 0x7D, 0xCA, 0x93, 0x27, + 0xEA, 0x74, 0x0C, 0xEF, 0x6F, 0x96, 0x09, 0xFE, 0x63, 0xEC, 0x70, 0x5D, + 0x36, 0xAD, 0x67, 0x77, 0xAE, 0xC9, 0x9D, 0x7C, 0x55, 0x44, 0x3A, 0xA2, + 0x63, 0x51, 0x1F, 0xF5, 0xE3, 0x62, 0xD4, 0xA9, 0x47, 0x07, 0x3E, 0xCC, + 0x20 +}; + +static const unsigned char TA21_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA21_RSA_N[] = { + 0xB6, 0x80, 0x0E, 0xC4, 0x79, 0xBD, 0x05, 0x8C, 0x7D, 0xB0, 0xA3, 0x9D, + 0x4D, 0x22, 0x4D, 0xCB, 0xF0, 0x41, 0x97, 0x4D, 0x59, 0xE0, 0xD1, 0xFE, + 0x56, 0x8C, 0x97, 0xF2, 0xD7, 0xBD, 0x8F, 0x6C, 0xB7, 0x23, 0x8F, 0x5F, + 0xD5, 0xC4, 0xD8, 0x41, 0xCB, 0xF2, 0x02, 0x1E, 0x71, 0xE5, 0xE9, 0xF6, + 0x5E, 0xCB, 0x08, 0x2A, 0x5E, 0x30, 0xF2, 0x2D, 0x66, 0xC7, 0x84, 0x1B, + 0x64, 0x57, 0x38, 0x9D, 0x75, 0x2D, 0x56, 0xC6, 0x2F, 0x61, 0xEF, 0x96, + 0xFC, 0x20, 0x46, 0xBD, 0xEB, 0xD4, 0x7B, 0x3F, 0x3F, 0x7C, 0x47, 0x38, + 0x04, 0xA9, 0x1B, 0xAA, 0x52, 0xDF, 0x13, 0x37, 0xD3, 0x15, 0x15, 0x4E, + 0xBD, 0x5F, 0x7C, 0xAF, 0xAD, 0x63, 0xC7, 0x79, 0xDC, 0x08, 0x7B, 0xD5, + 0xA0, 0xE5, 0xF7, 0x5B, 0x75, 0xAC, 0x80, 0x55, 0x99, 0x92, 0x61, 0x9B, + 0xCD, 0x2A, 0x17, 0x7D, 0xDB, 0x8F, 0xF4, 0xB5, 0x6A, 0xEA, 0x17, 0x4A, + 0x64, 0x28, 0x66, 0x15, 0x29, 0x6C, 0x02, 0xF1, 0x6B, 0xD5, 0xBA, 0xA3, + 0x33, 0xDC, 0x5A, 0x67, 0xA7, 0x05, 0xE2, 0xBF, 0x65, 0xB6, 0x16, 0xB0, + 0x10, 0xED, 0xCD, 0x50, 0x33, 0xC9, 0x70, 0x50, 0xEC, 0x19, 0x8E, 0xB0, + 0xC7, 0xF2, 0x74, 0x5B, 0x6B, 0x44, 0xC6, 0x7D, 0x96, 0xB9, 0x98, 0x08, + 0x59, 0x66, 0xDE, 0x29, 0x01, 0x9B, 0xF4, 0x2A, 0x6D, 0xD3, 0x15, 0x3A, + 0x90, 0x6A, 0x67, 0xF1, 0xB4, 0x6B, 0x66, 0xD9, 0x21, 0xEB, 0xCA, 0xD9, + 0x62, 0x7C, 0x46, 0x10, 0x5C, 0xDE, 0x75, 0x49, 0x67, 0x9E, 0x42, 0xF9, + 0xFE, 0x75, 0xA9, 0xA3, 0xAD, 0xFF, 0x76, 0x0A, 0x67, 0x40, 0xE3, 0xC5, + 0xF7, 0x8D, 0xC7, 0x85, 0x9A, 0x59, 0x9E, 0x62, 0x9A, 0x6A, 0xED, 0x45, + 0x87, 0x98, 0x67, 0xB2, 0xD5, 0x4A, 0x3C, 0xD7, 0xB4, 0x3B, 0x00, 0x0D, + 0xC0, 0x8F, 0x1F, 0xE1, 0x40, 0xC4, 0xAE, 0x6C, 0x21, 0xDC, 0x49, 0x7E, + 0x7E, 0xCA, 0xB2, 0x8D, 0x6D, 0xB6, 0xBF, 0x93, 0x2F, 0xA1, 0x5C, 0x3E, + 0x8F, 0xCA, 0xED, 0x80, 0x8E, 0x58, 0xE1, 0xDB, 0x57, 0xCF, 0x85, 0x36, + 0x38, 0xB2, 0x71, 0xA4, 0x09, 0x8C, 0x92, 0x89, 0x08, 0x88, 0x48, 0xF1, + 0x40, 0x63, 0x18, 0xB2, 0x5B, 0x8C, 0x5A, 0xE3, 0xC3, 0xD3, 0x17, 0xAA, + 0xAB, 0x19, 0xA3, 0x2C, 0x1B, 0xE4, 0xD5, 0xC6, 0xE2, 0x66, 0x7A, 0xD7, + 0x82, 0x19, 0xA6, 0x3B, 0x16, 0x2C, 0x2F, 0x71, 0x87, 0x5F, 0x45, 0x9E, + 0x95, 0x73, 0x93, 0xC2, 0x42, 0x81, 0x21, 0x13, 0x96, 0xD7, 0x9D, 0xBB, + 0x93, 0x68, 0x15, 0xFA, 0x9D, 0xA4, 0x1D, 0x8C, 0xF2, 0x81, 0xE0, 0x58, + 0x06, 0xBD, 0xC9, 0xB6, 0xE3, 0xF6, 0x89, 0x5D, 0x89, 0xF9, 0xAC, 0x44, + 0xA1, 0xCB, 0x6B, 0xFA, 0x16, 0xF1, 0xC7, 0x50, 0x3D, 0x24, 0xDA, 0xF7, + 0xC3, 0xE4, 0x87, 0xD5, 0x56, 0xF1, 0x4F, 0x90, 0x30, 0xFA, 0x45, 0x09, + 0x59, 0xDA, 0x34, 0xCE, 0xE0, 0x13, 0x1C, 0x04, 0x7C, 0x00, 0xD4, 0x9B, + 0x86, 0xA4, 0x40, 0xBC, 0xD9, 0xDC, 0x4C, 0x57, 0x7E, 0xAE, 0xB7, 0x33, + 0xB6, 0x5E, 0x76, 0xE1, 0x65, 0x8B, 0x66, 0xDF, 0x8D, 0xCA, 0xD7, 0x98, + 0xAF, 0xCE, 0x36, 0x98, 0x8C, 0x9C, 0x83, 0x99, 0x03, 0x70, 0xF3, 0xAF, + 0x74, 0xED, 0xC6, 0x0E, 0x36, 0xE7, 0xBD, 0xEC, 0xC1, 0x73, 0xA7, 0x94, + 0x5A, 0xCB, 0x92, 0x64, 0x82, 0xA6, 0x00, 0xC1, 0x70, 0xA1, 0x6E, 0x2C, + 0x29, 0xE1, 0x58, 0x57, 0xEC, 0x5A, 0x7C, 0x99, 0x6B, 0x25, 0xA4, 0x90, + 0x3A, 0x80, 0xF4, 0x20, 0x9D, 0x9A, 0xCE, 0xC7, 0x2D, 0xF9, 0xB2, 0x4B, + 0x29, 0x95, 0x83, 0xE9, 0x35, 0x8D, 0xA7, 0x49, 0x48, 0xA7, 0x0F, 0x4C, + 0x19, 0x91, 0xD0, 0xF5, 0xBF, 0x10, 0xE0, 0x71 +}; + +static const unsigned char TA21_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA22_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x17, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, + 0x33 +}; + +static const unsigned char TA22_EC_Q[] = { + 0x04, 0x23, 0xA5, 0x0C, 0xB8, 0x2D, 0x12, 0xF5, 0x28, 0xF3, 0xB1, 0xB2, + 0xDD, 0xE2, 0x02, 0x12, 0x80, 0x9E, 0x39, 0x5F, 0x49, 0x4D, 0x9F, 0xC9, + 0x25, 0x34, 0x59, 0x74, 0xEC, 0xBB, 0x06, 0x1C, 0xE7, 0xC0, 0x72, 0xAF, + 0xE8, 0xAE, 0x2F, 0xE1, 0x41, 0x54, 0x87, 0x14, 0xA8, 0x4A, 0xB2, 0xE8, + 0x7C, 0x82, 0xE6, 0x5B, 0x6A, 0xB5, 0xDC, 0xB3, 0x75, 0xCE, 0x8B, 0x06, + 0xD0, 0x86, 0x23, 0xBF, 0x46, 0xD5, 0x8E, 0x0F, 0x3F, 0x04, 0xF4, 0xD7, + 0x1C, 0x92, 0x7E, 0xF6, 0xA5, 0x63, 0xC2, 0xF5, 0x5F, 0x8E, 0x2E, 0x4F, + 0xA1, 0x18, 0x19, 0x02, 0x2B, 0x32, 0x0A, 0x82, 0x64, 0x7D, 0x16, 0x93, + 0xD1 +}; + +static const unsigned char TA23_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x32, 0x35, 0x36, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA23_EC_Q[] = { + 0x04, 0x7E, 0xFB, 0x6C, 0xE6, 0x23, 0xE3, 0x73, 0x32, 0x08, 0xCA, 0x60, + 0xE6, 0x53, 0x9C, 0xBA, 0x74, 0x8D, 0x18, 0xB0, 0x78, 0x90, 0x52, 0x80, + 0xDD, 0x38, 0xC0, 0x4A, 0x1D, 0xD1, 0xA8, 0xCC, 0x93, 0xA4, 0x97, 0x06, + 0x38, 0xCA, 0x0D, 0x15, 0x62, 0xC6, 0x8E, 0x01, 0x2A, 0x65, 0x9D, 0xAA, + 0xDF, 0x34, 0x91, 0x2E, 0x81, 0xC1, 0xE4, 0x33, 0x92, 0x31, 0xC4, 0xFD, + 0x09, 0x3A, 0xA6, 0x3F, 0xAD +}; + +static const unsigned char TA24_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x36 +}; + +static const unsigned char TA24_RSA_N[] = { + 0xAC, 0xAC, 0x74, 0x32, 0xE8, 0xB3, 0x65, 0xE5, 0xBA, 0xED, 0x43, 0x26, + 0x1D, 0xA6, 0x89, 0x0D, 0x45, 0xBA, 0x29, 0x88, 0xB2, 0xA4, 0x1D, 0x63, + 0xDD, 0xD3, 0xC1, 0x2C, 0x09, 0x57, 0x89, 0x39, 0xA1, 0x55, 0xE9, 0x67, + 0x34, 0x77, 0x0C, 0x6E, 0xE4, 0x55, 0x1D, 0x52, 0x25, 0xD2, 0x13, 0x6B, + 0x5E, 0xE1, 0x1D, 0xA9, 0xB7, 0x7D, 0x89, 0x32, 0x5F, 0x0D, 0x9E, 0x9F, + 0x2C, 0x7A, 0x63, 0x60, 0x40, 0x1F, 0xA6, 0xB0, 0xB6, 0x78, 0x8F, 0x99, + 0x54, 0x96, 0x08, 0x58, 0xAE, 0xE4, 0x06, 0xBC, 0x62, 0x05, 0x02, 0x16, + 0xBF, 0xAF, 0xA8, 0x23, 0x03, 0xB6, 0x94, 0x0F, 0xBC, 0x6E, 0x6C, 0xC2, + 0xCB, 0xD5, 0xA6, 0xBB, 0x0C, 0xE9, 0xF6, 0xC1, 0x02, 0xFB, 0x21, 0xDE, + 0x66, 0xDD, 0x17, 0xAB, 0x74, 0x42, 0xEF, 0xF0, 0x74, 0x2F, 0x25, 0xF4, + 0xEA, 0x6B, 0x55, 0x5B, 0x90, 0xDB, 0x9D, 0xDF, 0x5E, 0x87, 0x0A, 0x40, + 0xFB, 0xAD, 0x19, 0x6B, 0xFB, 0xF7, 0xCA, 0x60, 0x88, 0xDE, 0xDA, 0xC1, + 0x8F, 0xD6, 0xAE, 0xD5, 0x7F, 0xD4, 0x3C, 0x83, 0xEE, 0xD7, 0x16, 0x4C, + 0x83, 0x45, 0x33, 0x6B, 0x27, 0xD0, 0x86, 0xD0, 0x1C, 0x2D, 0x6B, 0xF3, + 0xAB, 0x7D, 0xF1, 0x85, 0xA9, 0xF5, 0x28, 0xD2, 0xAD, 0xEF, 0xF3, 0x84, + 0x4B, 0x1C, 0x87, 0xFC, 0x13, 0xA3, 0x3A, 0x72, 0xA2, 0x5A, 0x11, 0x2B, + 0xD6, 0x27, 0x71, 0x27, 0xED, 0x81, 0x2D, 0x6D, 0x66, 0x81, 0x92, 0x87, + 0xB4, 0x1B, 0x58, 0x7A, 0xCC, 0x3F, 0x0A, 0xFA, 0x46, 0x4F, 0x4D, 0x78, + 0x5C, 0xF8, 0x2B, 0x48, 0xE3, 0x04, 0x84, 0xCB, 0x5D, 0xF6, 0xB4, 0x6A, + 0xB3, 0x65, 0xFC, 0x42, 0x9E, 0x51, 0x26, 0x23, 0x20, 0xCB, 0x3D, 0x14, + 0xF9, 0x81, 0xED, 0x65, 0x16, 0x00, 0x4F, 0x1A, 0x64, 0x97, 0x66, 0x08, + 0xCF, 0x8C, 0x7B, 0xE3, 0x2B, 0xC0, 0x9D, 0xF9, 0x14, 0xF2, 0x1B, 0xF1, + 0x56, 0x6A, 0x16, 0xBF, 0x2C, 0x85, 0x85, 0xCD, 0x78, 0x38, 0x9A, 0xEB, + 0x42, 0x6A, 0x02, 0x34, 0x18, 0x83, 0x17, 0x4E, 0x94, 0x56, 0xF8, 0xB6, + 0x82, 0xB5, 0xF3, 0x96, 0xDD, 0x3D, 0xF3, 0xBE, 0x7F, 0x20, 0x77, 0x3E, + 0x7B, 0x19, 0x23, 0x6B, 0x2C, 0xD4, 0x72, 0x73, 0x43, 0x57, 0x7D, 0xE0, + 0xF8, 0xD7, 0x69, 0x4F, 0x17, 0x36, 0x04, 0xF9, 0xC0, 0x90, 0x60, 0x37, + 0x45, 0xDE, 0xE6, 0x0C, 0xD8, 0x74, 0x8D, 0xAE, 0x9C, 0xA2, 0x6D, 0x74, + 0x5D, 0x42, 0xBE, 0x06, 0xF5, 0xD9, 0x64, 0x6E, 0x02, 0x10, 0xAC, 0x89, + 0xB0, 0x4C, 0x3B, 0x07, 0x4D, 0x40, 0x7E, 0x24, 0xC5, 0x8A, 0x98, 0x82, + 0x79, 0x8E, 0xA4, 0xA7, 0x82, 0x20, 0x8D, 0x23, 0xFA, 0x27, 0x71, 0xC9, + 0xDF, 0xC6, 0x41, 0x74, 0xA0, 0x4D, 0xF6, 0x91, 0x16, 0xDC, 0x46, 0x8C, + 0x5F, 0x29, 0x63, 0x31, 0x59, 0x71, 0x0C, 0xD8, 0x6F, 0xC2, 0xB6, 0x32, + 0x7D, 0xFB, 0xE6, 0x5D, 0x53, 0xA6, 0x7E, 0x15, 0xFC, 0xBB, 0x75, 0x7C, + 0x5D, 0xEC, 0xF8, 0xF6, 0x17, 0x1C, 0xEC, 0xC7, 0x6B, 0x19, 0xCB, 0xF3, + 0x7B, 0xF0, 0x2B, 0x07, 0xA5, 0xD9, 0x6C, 0x79, 0x54, 0x76, 0x6C, 0x9D, + 0x1C, 0xA6, 0x6E, 0x0E, 0xE9, 0x79, 0x0C, 0xA8, 0x23, 0x6A, 0xA3, 0xDF, + 0x1B, 0x30, 0x31, 0x9F, 0xB1, 0x54, 0x7B, 0xFE, 0x6A, 0xCB, 0x66, 0xAA, + 0xDC, 0x65, 0xD0, 0xA2, 0x9E, 0x4A, 0x9A, 0x07, 0x21, 0x6B, 0x81, 0x8F, + 0xDB, 0xC4, 0x59, 0xFA, 0xDE, 0x22, 0xC0, 0x04, 0x9C, 0xE3, 0xAA, 0x5B, + 0x36, 0x93, 0xE8, 0x3D, 0xBD, 0x7A, 0xA1, 0x9D, 0x0B, 0x76, 0xB1, 0x0B, + 0xC7, 0x9D, 0xFD, 0xCF, 0x98, 0xA8, 0x06, 0xC2, 0xF8, 0x2A, 0xA3, 0xA1, + 0x83, 0xA0, 0xB7, 0x25, 0x72, 0xA5, 0x02, 0xE3 +}; + +static const unsigned char TA24_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA25_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA25_EC_Q[] = { + 0x04, 0xF1, 0xB3, 0xCD, 0x38, 0xE4, 0x25, 0x43, 0xE5, 0xDE, 0x19, 0x09, + 0xBB, 0x81, 0x79, 0xA2, 0x15, 0x5F, 0x15, 0x63, 0x01, 0xDE, 0xC2, 0xAB, + 0xDD, 0xB3, 0xA6, 0x1B, 0x67, 0x4B, 0x80, 0x83, 0xAF, 0x99, 0xCB, 0xAC, + 0x17, 0xDB, 0x2B, 0x96, 0xCA, 0x7C, 0x52, 0x55, 0xE2, 0x1A, 0xE1, 0x3D, + 0x56, 0xF0, 0x2F, 0x16, 0x08, 0xFA, 0x15, 0xBC, 0x9B, 0xBB, 0x47, 0xE6, + 0x3F, 0xEE, 0xA8, 0xE1, 0x4C, 0x8C, 0xF5, 0xD3, 0x36, 0xF9, 0x38, 0x5D, + 0xAB, 0x70, 0x9A, 0x47, 0x0D, 0xE2, 0x81, 0x41, 0x06, 0xEB, 0x49, 0xF9, + 0xB0, 0x29, 0xDD, 0x33, 0xEC, 0x50, 0xA5, 0x7F, 0x79, 0x29, 0xB8, 0x20, + 0x98 +}; + +static const unsigned char TA26_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x35, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA26_EC_Q[] = { + 0x04, 0x47, 0x45, 0x0E, 0x96, 0xFB, 0x7D, 0x5D, 0xBF, 0xE9, 0x39, 0xD1, + 0x21, 0xF8, 0x9F, 0x0B, 0xB6, 0xD5, 0x7B, 0x1E, 0x92, 0x3A, 0x48, 0x59, + 0x1C, 0xF0, 0x62, 0x31, 0x2D, 0xC0, 0x7A, 0x28, 0xFE, 0x1A, 0xA7, 0x5C, + 0xB3, 0xB6, 0xCC, 0x97, 0xE7, 0x45, 0xD4, 0x58, 0xFA, 0xD1, 0x77, 0x6D, + 0x43, 0xA2, 0xC0, 0x87, 0x65, 0x34, 0x0A, 0x1F, 0x7A, 0xDD, 0xEB, 0x3C, + 0x33, 0xA1, 0xC5, 0x9D, 0x4D, 0xA4, 0x6F, 0x41, 0x95, 0x38, 0x7F, 0xC9, + 0x1E, 0x84, 0xEB, 0xD1, 0x9E, 0x49, 0x92, 0x87, 0x94, 0x87, 0x0C, 0x3A, + 0x85, 0x4A, 0x66, 0x9F, 0x9D, 0x59, 0x93, 0x4D, 0x97, 0x61, 0x06, 0x86, + 0x4A +}; + +static const unsigned char TA27_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x1E, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA27_RSA_N[] = { + 0xD3, 0xB2, 0x4A, 0xCF, 0x7A, 0x47, 0xEF, 0x75, 0x9B, 0x23, 0xFA, 0x3A, + 0x2F, 0xD6, 0x50, 0x45, 0x89, 0x35, 0x3A, 0xC6, 0x6B, 0xDB, 0xFE, 0xDB, + 0x00, 0x68, 0xA8, 0xE0, 0x03, 0x11, 0x1D, 0x37, 0x50, 0x08, 0x9F, 0x4D, + 0x4A, 0x68, 0x94, 0x35, 0xB3, 0x53, 0xD1, 0x94, 0x63, 0xA7, 0x20, 0x56, + 0xAF, 0xDE, 0x51, 0x78, 0xEC, 0x2A, 0x3D, 0xF3, 0x48, 0x48, 0x50, 0x3E, + 0x0A, 0xDF, 0x46, 0x55, 0x8B, 0x27, 0x6D, 0xC3, 0x10, 0x4D, 0x0D, 0x91, + 0x52, 0x43, 0xD8, 0x87, 0xE0, 0x5D, 0x4E, 0x36, 0xB5, 0x21, 0xCA, 0x5F, + 0x39, 0x40, 0x04, 0x5F, 0x5B, 0x7E, 0xCC, 0xA3, 0xC6, 0x2B, 0xA9, 0x40, + 0x1E, 0xD9, 0x36, 0x84, 0xD6, 0x48, 0xF3, 0x92, 0x1E, 0x34, 0x46, 0x20, + 0x24, 0xC1, 0xA4, 0x51, 0x8E, 0x4A, 0x1A, 0xEF, 0x50, 0x3F, 0x69, 0x5D, + 0x19, 0x7F, 0x45, 0xC3, 0xC7, 0x01, 0x8F, 0x51, 0xC9, 0x23, 0xE8, 0x72, + 0xAE, 0xB4, 0xBC, 0x56, 0x09, 0x7F, 0x12, 0xCB, 0x1C, 0xB1, 0xAF, 0x29, + 0x90, 0x0A, 0xC9, 0x55, 0xCC, 0x0F, 0xD3, 0xB4, 0x1A, 0xED, 0x47, 0x35, + 0x5A, 0x4A, 0xED, 0x9C, 0x73, 0x04, 0x21, 0xD0, 0xAA, 0xBD, 0x0C, 0x13, + 0xB5, 0x00, 0xCA, 0x26, 0x6C, 0xC4, 0x6B, 0x0C, 0x94, 0x5A, 0x95, 0x94, + 0xDA, 0x50, 0x9A, 0xF1, 0xFF, 0xA5, 0x2B, 0x66, 0x31, 0xA4, 0xC9, 0x38, + 0xA0, 0xDF, 0x1D, 0x1F, 0xB8, 0x09, 0x2E, 0xF3, 0xA7, 0xE8, 0x67, 0x52, + 0xAB, 0x95, 0x1F, 0xE0, 0x46, 0x3E, 0xD8, 0xA4, 0xC3, 0xCA, 0x5A, 0xC5, + 0x31, 0x80, 0xE8, 0x48, 0x9A, 0x9F, 0x94, 0x69, 0xFE, 0x19, 0xDD, 0xD8, + 0x73, 0x7C, 0x81, 0xCA, 0x96, 0xDE, 0x8E, 0xED, 0xB3, 0x32, 0x05, 0x65, + 0x84, 0x34, 0xE6, 0xE6, 0xFD, 0x57, 0x10, 0xB5, 0x5F, 0x76, 0xBF, 0x2F, + 0xB0, 0x10, 0x0D, 0xC5 +}; + +static const unsigned char TA27_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA28_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x53, 0x65, 0x63, 0x74, 0x6F, 0x72, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA28_RSA_N[] = { + 0xB6, 0x22, 0x94, 0xFC, 0xA4, 0x48, 0xAF, 0xE8, 0x47, 0x6B, 0x0A, 0xFB, + 0x27, 0x76, 0xE4, 0xF2, 0x3F, 0x8A, 0x3B, 0x7A, 0x4A, 0x2C, 0x31, 0x2A, + 0x8C, 0x8D, 0xB0, 0xA9, 0xC3, 0x31, 0x6B, 0xA8, 0x77, 0x76, 0x84, 0x26, + 0xB6, 0xAC, 0x81, 0x42, 0x0D, 0x08, 0xEB, 0x55, 0x58, 0xBB, 0x7A, 0xF8, + 0xBC, 0x65, 0x7D, 0xF2, 0xA0, 0x6D, 0x8B, 0xA8, 0x47, 0xE9, 0x62, 0x76, + 0x1E, 0x11, 0xEE, 0x08, 0x14, 0xD1, 0xB2, 0x44, 0x16, 0xF4, 0xEA, 0xD0, + 0xFA, 0x1E, 0x2F, 0x5E, 0xDB, 0xCB, 0x73, 0x41, 0xAE, 0xBC, 0x00, 0xB0, + 0x4A, 0x2B, 0x40, 0xB2, 0xAC, 0xE1, 0x3B, 0x4B, 0xC2, 0x2D, 0x9D, 0xE4, + 0xA1, 0x9B, 0xEC, 0x1A, 0x3A, 0x1E, 0xF0, 0x08, 0xB3, 0xD0, 0xE4, 0x24, + 0x35, 0x07, 0x9F, 0x9C, 0xB4, 0xC9, 0x52, 0x6D, 0xDB, 0x07, 0xCA, 0x8F, + 0xB5, 0x5B, 0xF0, 0x83, 0xF3, 0x4F, 0xC7, 0x2D, 0xA5, 0xC8, 0xAD, 0xCB, + 0x95, 0x20, 0xA4, 0x31, 0x28, 0x57, 0x58, 0x5A, 0xE4, 0x8D, 0x1B, 0x9A, + 0xAB, 0x9E, 0x0D, 0x0C, 0xF2, 0x0A, 0x33, 0x39, 0x22, 0x39, 0x0A, 0x97, + 0x2E, 0xF3, 0x53, 0x77, 0xB9, 0x44, 0x45, 0xFD, 0x84, 0xCB, 0x36, 0x20, + 0x81, 0x59, 0x2D, 0x9A, 0x6F, 0x6D, 0x48, 0x48, 0x61, 0xCA, 0x4C, 0xDF, + 0x53, 0xD1, 0xAF, 0x52, 0xBC, 0x44, 0x9F, 0xAB, 0x2F, 0x6B, 0x83, 0x72, + 0xEF, 0x75, 0x80, 0xDA, 0x06, 0x33, 0x1B, 0x5D, 0xC8, 0xDA, 0x63, 0xC6, + 0x4D, 0xCD, 0xAC, 0x66, 0x31, 0xCD, 0xD1, 0xDE, 0x3E, 0x87, 0x10, 0x36, + 0xE1, 0xB9, 0xA4, 0x7A, 0xEF, 0x60, 0x50, 0xB2, 0xCB, 0xCA, 0xA6, 0x56, + 0xE0, 0x37, 0xAF, 0xAB, 0x34, 0x13, 0x39, 0x25, 0xE8, 0x39, 0x66, 0xE4, + 0x98, 0x7A, 0xAA, 0x12, 0x98, 0x9C, 0x59, 0x66, 0x86, 0x3E, 0xAD, 0xF1, + 0xB0, 0xCA, 0x3E, 0x06, 0x0F, 0x7B, 0xF0, 0x11, 0x4B, 0x37, 0xA0, 0x44, + 0x6D, 0x7B, 0xCB, 0xA8, 0x8C, 0x71, 0xF4, 0xD5, 0xB5, 0x91, 0x36, 0xCC, + 0xF0, 0x15, 0xC6, 0x2B, 0xDE, 0x51, 0x17, 0xB1, 0x97, 0x4C, 0x50, 0x3D, + 0xB1, 0x95, 0x59, 0x7C, 0x05, 0x7D, 0x2D, 0x21, 0xD5, 0x00, 0xBF, 0x01, + 0x67, 0xA2, 0x5E, 0x7B, 0xA6, 0x5C, 0xF2, 0xF7, 0x22, 0xF1, 0x90, 0x0D, + 0x93, 0xDB, 0xAA, 0x44, 0x51, 0x66, 0xCC, 0x7D, 0x76, 0x03, 0xEB, 0x6A, + 0xA8, 0x2A, 0x38, 0x19, 0x97, 0x76, 0x0D, 0x6B, 0x8A, 0x61, 0xF9, 0xBC, + 0xF6, 0xEE, 0x76, 0xFD, 0x70, 0x2B, 0xDD, 0x29, 0x3C, 0xF8, 0x0A, 0x1E, + 0x5B, 0x42, 0x1C, 0x8B, 0x56, 0x2F, 0x55, 0x1B, 0x1C, 0xA1, 0x2E, 0xB5, + 0xC7, 0x16, 0xE6, 0xF8, 0xAA, 0x3C, 0x92, 0x8E, 0x69, 0xB6, 0x01, 0xC1, + 0xB5, 0x86, 0x9D, 0x89, 0x0F, 0x0B, 0x38, 0x94, 0x54, 0xE8, 0xEA, 0xDC, + 0x9E, 0x3D, 0x25, 0xBC, 0x53, 0x26, 0xED, 0xD5, 0xAB, 0x39, 0xAA, 0xC5, + 0x40, 0x4C, 0x54, 0xAB, 0xB2, 0xB4, 0xD9, 0xD9, 0xF8, 0xD7, 0x72, 0xDB, + 0x1C, 0xBC, 0x6D, 0xBD, 0x65, 0x5F, 0xEF, 0x88, 0x35, 0x2A, 0x66, 0x2F, + 0xEE, 0xF6, 0xB3, 0x65, 0xF0, 0x33, 0x8D, 0x7C, 0x98, 0x41, 0x69, 0x46, + 0x0F, 0x43, 0x1C, 0x69, 0xFA, 0x9B, 0xB5, 0xD0, 0x61, 0x6A, 0xCD, 0xCA, + 0x4B, 0xD9, 0x4C, 0x90, 0x46, 0xAB, 0x15, 0x59, 0xA1, 0x47, 0x54, 0x29, + 0x2E, 0x83, 0x28, 0x5F, 0x1C, 0xC2, 0xA2, 0xAB, 0x72, 0x17, 0x00, 0x06, + 0x8E, 0x45, 0xEC, 0x8B, 0xE2, 0x33, 0x3D, 0x7F, 0xDA, 0x19, 0x44, 0xE4, + 0x62, 0x72, 0xC3, 0xDF, 0x22, 0xC6, 0xF2, 0x56, 0xD4, 0xDD, 0x5F, 0x95, + 0x72, 0xED, 0x6D, 0x5F, 0xF7, 0x48, 0x03, 0x5B, 0xFD, 0xC5, 0x2A, 0xA0, + 0xF6, 0x73, 0x23, 0x84, 0x10, 0x1B, 0x01, 0xE7 +}; + +static const unsigned char TA28_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA29_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x32 +}; + +static const unsigned char TA29_RSA_N[] = { + 0xAA, 0x5F, 0xDA, 0x1B, 0x5F, 0xE8, 0x73, 0x91, 0xE5, 0xDA, 0x5C, 0xF4, + 0xA2, 0xE6, 0x47, 0xE5, 0xF3, 0x68, 0x55, 0x60, 0x05, 0x1D, 0x02, 0xA4, + 0xB3, 0x9B, 0x59, 0xF3, 0x1E, 0x8A, 0xAF, 0x34, 0xAD, 0xFC, 0x0D, 0xC2, + 0xD9, 0x48, 0x19, 0xEE, 0x69, 0x8F, 0xC9, 0x20, 0xFC, 0x21, 0xAA, 0x07, + 0x19, 0xED, 0xB0, 0x5C, 0xAC, 0x65, 0xC7, 0x5F, 0xED, 0x02, 0x7C, 0x7B, + 0x7C, 0x2D, 0x1B, 0xD6, 0xBA, 0xB9, 0x80, 0xC2, 0x18, 0x82, 0x16, 0x84, + 0xFA, 0x66, 0xB0, 0x08, 0xC6, 0x54, 0x23, 0x81, 0xE4, 0xCD, 0xB9, 0x49, + 0x3F, 0xF6, 0x4F, 0x6E, 0x37, 0x48, 0x28, 0x38, 0x0F, 0xC5, 0xBE, 0xE7, + 0x68, 0x70, 0xFD, 0x39, 0x97, 0x4D, 0xD2, 0xC7, 0x98, 0x91, 0x50, 0xAA, + 0xC4, 0x44, 0xB3, 0x23, 0x7D, 0x39, 0x47, 0xE9, 0x52, 0x62, 0xD6, 0x12, + 0x93, 0x5E, 0xB7, 0x31, 0x96, 0x42, 0x05, 0xFB, 0x76, 0xA7, 0x1E, 0xA3, + 0xF5, 0xC2, 0xFC, 0xE9, 0x7A, 0xC5, 0x6C, 0xA9, 0x71, 0x4F, 0xEA, 0xCB, + 0x78, 0xBC, 0x60, 0xAF, 0xC7, 0xDE, 0xF4, 0xD9, 0xCB, 0xBE, 0x7E, 0x33, + 0xA5, 0x6E, 0x94, 0x83, 0xF0, 0x34, 0xFA, 0x21, 0xAB, 0xEA, 0x8E, 0x72, + 0xA0, 0x3F, 0xA4, 0xDE, 0x30, 0x5B, 0xEF, 0x86, 0x4D, 0x6A, 0x95, 0x5B, + 0x43, 0x44, 0xA8, 0x10, 0x15, 0x1C, 0xE5, 0x01, 0x57, 0xC5, 0x98, 0xF1, + 0xE6, 0x06, 0x28, 0x91, 0xAA, 0x20, 0xC5, 0xB7, 0x53, 0x26, 0x51, 0x43, + 0xB2, 0x0B, 0x11, 0x95, 0x58, 0xE1, 0xC0, 0x0F, 0x76, 0xD9, 0xC0, 0x8D, + 0x7C, 0x81, 0xF3, 0x72, 0x70, 0x9E, 0x6F, 0xFE, 0x1A, 0x8E, 0xD9, 0x5F, + 0x35, 0xC6, 0xB2, 0x6F, 0x34, 0x7C, 0xBE, 0x48, 0x4F, 0xE2, 0x5A, 0x39, + 0xD7, 0xD8, 0x9D, 0x78, 0x9E, 0x9F, 0x86, 0x3E, 0x03, 0x5E, 0x19, 0x8B, + 0x44, 0xA2, 0xD5, 0xC7 +}; + +static const unsigned char TA29_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA30_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x33 +}; + +static const unsigned char TA30_RSA_N[] = { + 0xBD, 0x75, 0x93, 0xF0, 0x62, 0x22, 0x6F, 0x24, 0xAE, 0xE0, 0x7A, 0x76, + 0xAC, 0x7D, 0xBD, 0xD9, 0x24, 0xD5, 0xB8, 0xB7, 0xFC, 0xCD, 0xF0, 0x42, + 0xE0, 0xEB, 0x78, 0x88, 0x56, 0x5E, 0x9B, 0x9A, 0x54, 0x1D, 0x4D, 0x0C, + 0x8A, 0xF6, 0xD3, 0xCF, 0x70, 0xF4, 0x52, 0xB5, 0xD8, 0x93, 0x04, 0xE3, + 0x46, 0x86, 0x71, 0x41, 0x4A, 0x2B, 0xF0, 0x2A, 0x2C, 0x55, 0x03, 0xD6, + 0x48, 0xC3, 0xE0, 0x39, 0x38, 0xED, 0xF2, 0x5C, 0x3C, 0x3F, 0x44, 0xBC, + 0x93, 0x3D, 0x61, 0xAB, 0x4E, 0xCD, 0x0D, 0xBE, 0xF0, 0x20, 0x27, 0x58, + 0x0E, 0x44, 0x7F, 0x04, 0x1A, 0x87, 0xA5, 0xD7, 0x96, 0x14, 0x36, 0x90, + 0xD0, 0x49, 0x7B, 0xA1, 0x75, 0xFB, 0x1A, 0x6B, 0x73, 0xB1, 0xF8, 0xCE, + 0xA9, 0x09, 0x2C, 0xF2, 0x53, 0xD5, 0xC3, 0x14, 0x44, 0xB8, 0x86, 0xA5, + 0xF6, 0x8B, 0x2B, 0x39, 0xDA, 0xA3, 0x33, 0x54, 0xD9, 0xFA, 0x72, 0x1A, + 0xF7, 0x22, 0x15, 0x1C, 0x88, 0x91, 0x6B, 0x7F, 0x66, 0xE5, 0xC3, 0x6A, + 0x80, 0xB0, 0x24, 0xF3, 0xDF, 0x86, 0x45, 0x88, 0xFD, 0x19, 0x7F, 0x75, + 0x87, 0x1F, 0x1F, 0xB1, 0x1B, 0x0A, 0x73, 0x24, 0x5B, 0xB9, 0x65, 0xE0, + 0x2C, 0x54, 0xC8, 0x60, 0xD3, 0x66, 0x17, 0x3F, 0xE1, 0xCC, 0x54, 0x33, + 0x73, 0x91, 0x02, 0x3A, 0xA6, 0x7F, 0x7B, 0x76, 0x39, 0xA2, 0x1F, 0x96, + 0xB6, 0x38, 0xAE, 0xB5, 0xC8, 0x93, 0x74, 0x1D, 0x9E, 0xB9, 0xB4, 0xE5, + 0x60, 0x9D, 0x2F, 0x56, 0xD1, 0xE0, 0xEB, 0x5E, 0x5B, 0x4C, 0x12, 0x70, + 0x0C, 0x6C, 0x44, 0x20, 0xAB, 0x11, 0xD8, 0xF4, 0x19, 0xF6, 0xD2, 0x9C, + 0x52, 0x37, 0xE7, 0xFA, 0xB6, 0xC2, 0x31, 0x3B, 0x4A, 0xD4, 0x14, 0x99, + 0xAD, 0xC7, 0x1A, 0xF5, 0x5D, 0x5F, 0xFA, 0x07, 0xB8, 0x7C, 0x0D, 0x1F, + 0xD6, 0x83, 0x1E, 0xB3 +}; + +static const unsigned char TA30_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA31_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA31_RSA_N[] = { + 0xAE, 0xFF, 0x09, 0x59, 0x91, 0x80, 0x0A, 0x4A, 0x68, 0xE6, 0x24, 0x3F, + 0xB8, 0xA7, 0xE4, 0xC8, 0x3A, 0x0A, 0x3A, 0x16, 0xCD, 0xC9, 0x23, 0x61, + 0xA0, 0x93, 0x71, 0xF2, 0xAB, 0x8B, 0x73, 0x8F, 0xA0, 0x67, 0x65, 0x60, + 0xD2, 0x54, 0x6B, 0x63, 0x51, 0x6F, 0x49, 0x33, 0xE0, 0x72, 0x07, 0x13, + 0x7D, 0x38, 0xCD, 0x06, 0x92, 0x07, 0x29, 0x52, 0x6B, 0x4E, 0x77, 0x6C, + 0x04, 0xD3, 0x95, 0xFA, 0xDD, 0x4C, 0x8C, 0xD9, 0x5D, 0xC1, 0x61, 0x7D, + 0x4B, 0xE7, 0x28, 0xB3, 0x44, 0x81, 0x7B, 0x51, 0xAF, 0xDD, 0x33, 0xB1, + 0x68, 0x7C, 0xD6, 0x4E, 0x4C, 0xFE, 0x2B, 0x68, 0xB9, 0xCA, 0x66, 0x69, + 0xC4, 0xEC, 0x5E, 0x57, 0x7F, 0xF7, 0x0D, 0xC7, 0x9C, 0x36, 0x36, 0xE5, + 0x07, 0x60, 0xAC, 0xC0, 0x4C, 0xEA, 0x08, 0x6C, 0xEF, 0x06, 0x7C, 0x4F, + 0x5B, 0x28, 0x7A, 0x08, 0xFC, 0x93, 0x5D, 0x9B, 0xF6, 0x9C, 0xB4, 0x8B, + 0x86, 0xBA, 0x21, 0xB9, 0xF4, 0xF0, 0xE8, 0x59, 0x5A, 0x28, 0xA1, 0x34, + 0x84, 0x1A, 0x25, 0x91, 0xB6, 0xB5, 0x8F, 0xEF, 0xB2, 0xF9, 0x80, 0xFA, + 0xF9, 0x3D, 0x3C, 0x11, 0x72, 0xD8, 0xE3, 0x2F, 0x86, 0x76, 0xC5, 0x79, + 0x2C, 0xC1, 0xA9, 0x90, 0x93, 0x46, 0x98, 0x67, 0xCB, 0x83, 0x6A, 0xA0, + 0x50, 0x23, 0xA7, 0x3B, 0xF6, 0x81, 0x39, 0xE0, 0xED, 0xF0, 0xB9, 0xBF, + 0x65, 0xF1, 0xD8, 0xCB, 0x7A, 0xFB, 0xEF, 0x73, 0x03, 0xCE, 0x00, 0xF4, + 0x7D, 0xD7, 0xE0, 0x5D, 0x3B, 0x66, 0xB8, 0xDC, 0x8E, 0xBA, 0x83, 0xCB, + 0x87, 0x76, 0x03, 0xFC, 0x25, 0xD9, 0xE7, 0x23, 0x6F, 0x06, 0xFD, 0x67, + 0xF3, 0xE0, 0xFF, 0x84, 0xBC, 0x47, 0xBF, 0xB5, 0x16, 0x18, 0x46, 0x69, + 0x14, 0xCC, 0x05, 0xF7, 0xDB, 0xD3, 0x49, 0xAC, 0x6B, 0xCC, 0xAB, 0xE4, + 0xB5, 0x0B, 0x43, 0x24, 0x5E, 0x4B, 0x6B, 0x4D, 0x67, 0xDF, 0xD6, 0xB5, + 0x3E, 0x4F, 0x78, 0x1F, 0x94, 0x71, 0x24, 0xEA, 0xDE, 0x70, 0xFC, 0xF1, + 0x93, 0xFE, 0x9E, 0x93, 0x5A, 0xE4, 0x94, 0x5A, 0x97, 0x54, 0x0C, 0x35, + 0x7B, 0x5F, 0x6C, 0xEE, 0x00, 0x1F, 0x24, 0xEC, 0x03, 0xBA, 0x02, 0xF5, + 0x76, 0xF4, 0x9F, 0xD4, 0x9A, 0xED, 0x85, 0x2C, 0x38, 0x22, 0x2F, 0xC7, + 0xD8, 0x2F, 0x76, 0x11, 0x4F, 0xFD, 0x6C, 0x5C, 0xE8, 0xF5, 0x8E, 0x27, + 0x87, 0x7F, 0x19, 0x4A, 0x21, 0x47, 0x90, 0x1D, 0x79, 0x8D, 0x1C, 0x5B, + 0xF8, 0xCF, 0x4A, 0x85, 0xE4, 0xED, 0xB3, 0x5B, 0x8D, 0xBE, 0xC4, 0x64, + 0x28, 0x5D, 0x41, 0xC4, 0x6E, 0xAC, 0x38, 0x5A, 0x4F, 0x23, 0x74, 0x74, + 0xA9, 0x12, 0xC3, 0xF6, 0xD2, 0xB9, 0x11, 0x15, 0x33, 0x07, 0x91, 0xD8, + 0x3B, 0x37, 0x3A, 0x63, 0x30, 0x06, 0xD1, 0xC5, 0x22, 0x36, 0x28, 0x62, + 0x23, 0x10, 0xE0, 0x46, 0xCC, 0x97, 0xAC, 0xD6, 0x2B, 0x5D, 0x64, 0x24, + 0xD5, 0xEE, 0x1C, 0x0E, 0xDE, 0xFB, 0x08, 0x5A, 0x75, 0x2A, 0xF6, 0x63, + 0x6D, 0xCE, 0x0B, 0x42, 0xBE, 0xD1, 0xBA, 0x70, 0x1C, 0x9C, 0x21, 0xE5, + 0x0F, 0x31, 0x69, 0x17, 0xD7, 0xFC, 0x0A, 0xB4, 0xDE, 0xED, 0x80, 0x9C, + 0xCB, 0x92, 0xB4, 0x8B, 0xF5, 0xDE, 0x59, 0xA2, 0x58, 0x09, 0xA5, 0x63, + 0x47, 0x0B, 0xE1, 0x41, 0x32, 0x34, 0x41, 0xD9, 0x9A, 0xB1, 0xD9, 0xA8, + 0xB0, 0x1B, 0x5A, 0xDE, 0x0D, 0x0D, 0xF4, 0xE2, 0xB2, 0x5D, 0x35, 0x80, + 0xB9, 0x81, 0xD4, 0x84, 0x69, 0x91, 0x02, 0xCB, 0x75, 0xD0, 0x8D, 0xC5, + 0xB5, 0x3D, 0x09, 0x91, 0x09, 0x8F, 0x14, 0xA1, 0x14, 0x74, 0x79, 0x3E, + 0xD6, 0xC9, 0x15, 0x1D, 0xA4, 0x59, 0x59, 0x22, 0xDC, 0xF6, 0x8A, 0x45, + 0x3D, 0x3C, 0x12, 0xD6, 0x3E, 0x5D, 0x32, 0x2F +}; + +static const unsigned char TA31_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA32_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x33, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA32_RSA_N[] = { + 0xCC, 0x25, 0x76, 0x90, 0x79, 0x06, 0x78, 0x22, 0x16, 0xF5, 0xC0, 0x83, + 0xB6, 0x84, 0xCA, 0x28, 0x9E, 0xFD, 0x05, 0x76, 0x11, 0xC5, 0xAD, 0x88, + 0x72, 0xFC, 0x46, 0x02, 0x43, 0xC7, 0xB2, 0x8A, 0x9D, 0x04, 0x5F, 0x24, + 0xCB, 0x2E, 0x4B, 0xE1, 0x60, 0x82, 0x46, 0xE1, 0x52, 0xAB, 0x0C, 0x81, + 0x47, 0x70, 0x6C, 0xDD, 0x64, 0xD1, 0xEB, 0xF5, 0x2C, 0xA3, 0x0F, 0x82, + 0x3D, 0x0C, 0x2B, 0xAE, 0x97, 0xD7, 0xB6, 0x14, 0x86, 0x10, 0x79, 0xBB, + 0x3B, 0x13, 0x80, 0x77, 0x8C, 0x08, 0xE1, 0x49, 0xD2, 0x6A, 0x62, 0x2F, + 0x1F, 0x5E, 0xFA, 0x96, 0x68, 0xDF, 0x89, 0x27, 0x95, 0x38, 0x9F, 0x06, + 0xD7, 0x3E, 0xC9, 0xCB, 0x26, 0x59, 0x0D, 0x73, 0xDE, 0xB0, 0xC8, 0xE9, + 0x26, 0x0E, 0x83, 0x15, 0xC6, 0xEF, 0x5B, 0x8B, 0xD2, 0x04, 0x60, 0xCA, + 0x49, 0xA6, 0x28, 0xF6, 0x69, 0x3B, 0xF6, 0xCB, 0xC8, 0x28, 0x91, 0xE5, + 0x9D, 0x8A, 0x61, 0x57, 0x37, 0xAC, 0x74, 0x14, 0xDC, 0x74, 0xE0, 0x3A, + 0xEE, 0x72, 0x2F, 0x2E, 0x9C, 0xFB, 0xD0, 0xBB, 0xBF, 0xF5, 0x3D, 0x00, + 0xE1, 0x06, 0x33, 0xE8, 0x82, 0x2B, 0xAE, 0x53, 0xA6, 0x3A, 0x16, 0x73, + 0x8C, 0xDD, 0x41, 0x0E, 0x20, 0x3A, 0xC0, 0xB4, 0xA7, 0xA1, 0xE9, 0xB2, + 0x4F, 0x90, 0x2E, 0x32, 0x60, 0xE9, 0x57, 0xCB, 0xB9, 0x04, 0x92, 0x68, + 0x68, 0xE5, 0x38, 0x26, 0x60, 0x75, 0xB2, 0x9F, 0x77, 0xFF, 0x91, 0x14, + 0xEF, 0xAE, 0x20, 0x49, 0xFC, 0xAD, 0x40, 0x15, 0x48, 0xD1, 0x02, 0x31, + 0x61, 0x19, 0x5E, 0xB8, 0x97, 0xEF, 0xAD, 0x77, 0xB7, 0x64, 0x9A, 0x7A, + 0xBF, 0x5F, 0xC1, 0x13, 0xEF, 0x9B, 0x62, 0xFB, 0x0D, 0x6C, 0xE0, 0x54, + 0x69, 0x16, 0xA9, 0x03, 0xDA, 0x6E, 0xE9, 0x83, 0x93, 0x71, 0x76, 0xC6, + 0x69, 0x85, 0x82, 0x17 +}; + +static const unsigned char TA32_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA33_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x41, 0x54, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x65, 0x2D, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x65, + 0x20, 0x6D, 0x6F, 0x6E, 0x69, 0x74, 0x6F, 0x72, 0x69, 0x6E, 0x67, 0x20, + 0x47, 0x6D, 0x62, 0x48, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x10, 0x47, 0x4C, 0x4F, 0x42, 0x41, 0x4C, 0x54, 0x52, 0x55, + 0x53, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA33_RSA_N[] = { + 0xAE, 0x2E, 0x56, 0xAD, 0x1B, 0x1C, 0xEF, 0xF6, 0x95, 0x8F, 0xA0, 0x77, + 0x1B, 0x2B, 0xD3, 0x63, 0x8F, 0x84, 0x4D, 0x45, 0xA2, 0x0F, 0x9F, 0x5B, + 0x45, 0xAB, 0x59, 0x7B, 0x51, 0x34, 0xF9, 0xEC, 0x8B, 0x8A, 0x78, 0xC5, + 0xDD, 0x6B, 0xAF, 0xBD, 0xC4, 0xDF, 0x93, 0x45, 0x1E, 0xBF, 0x91, 0x38, + 0x0B, 0xAE, 0x0E, 0x16, 0xE7, 0x41, 0x73, 0xF8, 0xDB, 0xBB, 0xD1, 0xB8, + 0x51, 0xE0, 0xCB, 0x83, 0x3B, 0x73, 0x38, 0x6E, 0x77, 0x8A, 0x0F, 0x59, + 0x63, 0x26, 0xCD, 0xA7, 0x2A, 0xCE, 0x54, 0xFB, 0xB8, 0xE2, 0xC0, 0x7C, + 0x47, 0xCE, 0x60, 0x7C, 0x3F, 0xB2, 0x73, 0xF2, 0xC0, 0x19, 0xB6, 0x8A, + 0x92, 0x87, 0x35, 0x0D, 0x90, 0x28, 0xA2, 0xE4, 0x15, 0x04, 0x63, 0x3E, + 0xBA, 0xAF, 0xEE, 0x7C, 0x5E, 0xCC, 0xA6, 0x8B, 0x50, 0xB2, 0x38, 0xF7, + 0x41, 0x63, 0xCA, 0xCE, 0xFF, 0x69, 0x8F, 0x68, 0x0E, 0x95, 0x36, 0xE5, + 0xCC, 0xB9, 0x8C, 0x09, 0xCA, 0x4B, 0xDD, 0x31, 0x90, 0x96, 0xC8, 0xCC, + 0x1F, 0xFD, 0x56, 0x96, 0x34, 0xDB, 0x8E, 0x1C, 0xEA, 0x2C, 0xBE, 0x85, + 0x2E, 0x63, 0xDD, 0xAA, 0xA9, 0x95, 0xD3, 0xFD, 0x29, 0x95, 0x13, 0xF0, + 0xC8, 0x98, 0x93, 0xD9, 0x2D, 0x16, 0x47, 0x90, 0x11, 0x83, 0xA2, 0x3A, + 0x22, 0xA2, 0x28, 0x57, 0xA2, 0xEB, 0xFE, 0xC0, 0x8C, 0x28, 0xA0, 0xA6, + 0x7D, 0xE7, 0x2A, 0x42, 0x3B, 0x82, 0x80, 0x63, 0xA5, 0x63, 0x1F, 0x19, + 0xCC, 0x7C, 0xB2, 0x66, 0xA8, 0xC2, 0xD3, 0x6D, 0x37, 0x6F, 0xE2, 0x7E, + 0x06, 0x51, 0xD9, 0x45, 0x84, 0x1F, 0x12, 0xCE, 0x24, 0x52, 0x64, 0x85, + 0x0B, 0x48, 0x80, 0x4E, 0x87, 0xB1, 0x22, 0x22, 0x30, 0xAA, 0xEB, 0xAE, + 0xBE, 0xE0, 0x02, 0xE0, 0x40, 0xE8, 0xB0, 0x42, 0x80, 0x03, 0x51, 0xAA, + 0xB4, 0x7E, 0xAA, 0x44, 0xD7, 0x43, 0x61, 0xF3, 0xA2, 0x6B, 0x16, 0x89, + 0x49, 0xA4, 0xA3, 0xA4, 0x2B, 0x8A, 0x02, 0xC4, 0x78, 0xF4, 0x68, 0x8A, + 0xC1, 0xE4, 0x7A, 0x36, 0xB1, 0x6F, 0x1B, 0x96, 0x1B, 0x77, 0x49, 0x8D, + 0xD4, 0xC9, 0x06, 0x72, 0x8F, 0xCF, 0x53, 0xE3, 0xDC, 0x17, 0x85, 0x20, + 0x4A, 0xDC, 0x98, 0x27, 0xD3, 0x91, 0x26, 0x2B, 0x47, 0x1E, 0x69, 0x07, + 0xAF, 0xDE, 0xA2, 0xE4, 0xE4, 0xD4, 0x6B, 0x0B, 0xB3, 0x5E, 0x7C, 0xD4, + 0x24, 0x80, 0x47, 0x29, 0x69, 0x3B, 0x6E, 0xE8, 0xAC, 0xFD, 0x40, 0xEB, + 0xD8, 0xED, 0x71, 0x71, 0x2B, 0xF2, 0xE8, 0x58, 0x1D, 0xEB, 0x41, 0x97, + 0x22, 0xC5, 0x1F, 0xD4, 0x39, 0xD0, 0x27, 0x8F, 0x87, 0xE3, 0x18, 0xF4, + 0xE0, 0xA9, 0x46, 0x0D, 0xF5, 0x74, 0x3A, 0x82, 0x2E, 0xD0, 0x6E, 0x2C, + 0x91, 0xA3, 0x31, 0x5C, 0x3B, 0x46, 0xEA, 0x7B, 0x04, 0x10, 0x56, 0x5E, + 0x80, 0x1D, 0xF5, 0xA5, 0x65, 0xE8, 0x82, 0xFC, 0xE2, 0x07, 0x8C, 0x62, + 0x45, 0xF5, 0x20, 0xDE, 0x46, 0x70, 0x86, 0xA1, 0xBC, 0x93, 0xD3, 0x1E, + 0x74, 0xA6, 0x6C, 0xB0, 0x2C, 0xF7, 0x03, 0x0C, 0x88, 0x0C, 0xCB, 0xD4, + 0x72, 0x53, 0x86, 0xBC, 0x60, 0x46, 0xF3, 0x98, 0x6A, 0xC2, 0xF1, 0xBF, + 0x43, 0xF9, 0x70, 0x20, 0x77, 0xCA, 0x37, 0x41, 0x79, 0x55, 0x52, 0x63, + 0x8D, 0x5B, 0x12, 0x9F, 0xC5, 0x68, 0xC4, 0x88, 0x9D, 0xAC, 0xF2, 0x30, + 0xAB, 0xB7, 0xA3, 0x31, 0x97, 0x67, 0xAD, 0x8F, 0x17, 0x0F, 0x6C, 0xC7, + 0x73, 0xED, 0x24, 0x94, 0x6B, 0xC8, 0x83, 0x9A, 0xD0, 0x9A, 0x37, 0x49, + 0x04, 0xAB, 0xB1, 0x16, 0xC8, 0x6C, 0x49, 0x49, 0x2D, 0xAB, 0xA1, 0xD0, + 0x8C, 0x92, 0xF2, 0x41, 0x4A, 0x79, 0x21, 0x25, 0xDB, 0x63, 0xD7, 0xB6, + 0x9C, 0xA7, 0x7E, 0x42, 0x69, 0xFB, 0x3A, 0x63 +}; + +static const unsigned char TA33_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA34_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA34_RSA_N[] = { + 0xA1, 0xAE, 0x25, 0xB2, 0x01, 0x18, 0xDC, 0x57, 0x88, 0x3F, 0x46, 0xEB, + 0xF9, 0xAF, 0xE2, 0xEB, 0x23, 0x71, 0xE2, 0x9A, 0xD1, 0x61, 0x66, 0x21, + 0x5F, 0xAA, 0xAF, 0x27, 0x51, 0xE5, 0x6E, 0x1B, 0x16, 0xD4, 0x2D, 0x7D, + 0x50, 0xB0, 0x53, 0x77, 0xBD, 0x78, 0x3A, 0x60, 0xE2, 0x64, 0x02, 0x9B, + 0x7C, 0x86, 0x9B, 0xD6, 0x1A, 0x8E, 0xAD, 0xFF, 0x1F, 0x15, 0x7F, 0xD5, + 0x95, 0x1E, 0x12, 0xCB, 0xE6, 0x14, 0x84, 0x04, 0xC1, 0xDF, 0x36, 0xB3, + 0x16, 0x9F, 0x8A, 0xE3, 0xC9, 0xDB, 0x98, 0x34, 0xCE, 0xD8, 0x33, 0x17, + 0x28, 0x46, 0xFC, 0xA7, 0xC9, 0xF0, 0xD2, 0xB4, 0xD5, 0x4D, 0x09, 0x72, + 0x49, 0xF9, 0xF2, 0x87, 0xE3, 0xA9, 0xDA, 0x7D, 0xA1, 0x7D, 0x6B, 0xB2, + 0x3A, 0x25, 0xA9, 0x6D, 0x52, 0x44, 0xAC, 0xF8, 0xBE, 0x6E, 0xFB, 0xDC, + 0xA6, 0x73, 0x91, 0x90, 0x61, 0xA6, 0x03, 0x14, 0x20, 0xF2, 0xE7, 0x87, + 0xA3, 0x88, 0xAD, 0xAD, 0xA0, 0x8C, 0xFF, 0xA6, 0x0B, 0x25, 0x52, 0x25, + 0xE7, 0x16, 0x01, 0xD5, 0xCB, 0xB8, 0x35, 0x81, 0x0C, 0xA3, 0x3B, 0xF0, + 0xE1, 0xE1, 0xFC, 0x5A, 0x5D, 0xCE, 0x80, 0x71, 0x6D, 0xF8, 0x49, 0xAB, + 0x3E, 0x3B, 0xBA, 0xB8, 0xD7, 0x80, 0x01, 0xFB, 0xA5, 0xEB, 0x5B, 0xB3, + 0xC5, 0x5E, 0x60, 0x2A, 0x31, 0xA0, 0xAF, 0x37, 0xE8, 0x20, 0x3A, 0x9F, + 0xA8, 0x32, 0x2C, 0x0C, 0xCC, 0x09, 0x1D, 0xD3, 0x9E, 0x8E, 0x5D, 0xBC, + 0x4C, 0x98, 0xEE, 0xC5, 0x1A, 0x68, 0x7B, 0xEC, 0x53, 0xA6, 0xE9, 0x14, + 0x35, 0xA3, 0xDF, 0xCD, 0x80, 0x9F, 0x0C, 0x48, 0xFB, 0x1C, 0xF4, 0xF1, + 0xBF, 0x4A, 0xB8, 0xFA, 0xD5, 0x8C, 0x71, 0x4A, 0xC7, 0x1F, 0xAD, 0xFE, + 0x41, 0x9A, 0xB3, 0x83, 0x5D, 0xF2, 0x84, 0x56, 0xEF, 0xA5, 0x57, 0x43, + 0xCE, 0x29, 0xAD, 0x8C, 0xAB, 0x55, 0xBF, 0xC4, 0xFB, 0x5B, 0x01, 0xDD, + 0x23, 0x21, 0xA1, 0x58, 0x00, 0x8E, 0xC3, 0xD0, 0x6A, 0x13, 0xED, 0x13, + 0xE3, 0x12, 0x2B, 0x80, 0xDC, 0x67, 0xE6, 0x95, 0xB2, 0xCD, 0x1E, 0x22, + 0x6E, 0x2A, 0xF8, 0x41, 0xD4, 0xF2, 0xCA, 0x14, 0x07, 0x8D, 0x8A, 0x55, + 0x12, 0xC6, 0x69, 0xF5, 0xB8, 0x86, 0x68, 0x2F, 0x53, 0x5E, 0xB0, 0xD2, + 0xAA, 0x21, 0xC1, 0x98, 0xE6, 0x30, 0xE3, 0x67, 0x55, 0xC7, 0x9B, 0x6E, + 0xAC, 0x19, 0xA8, 0x55, 0xA6, 0x45, 0x06, 0xD0, 0x23, 0x3A, 0xDB, 0xEB, + 0x65, 0x5D, 0x2A, 0x11, 0x11, 0xF0, 0x3B, 0x4F, 0xCA, 0x6D, 0xF4, 0x34, + 0xC4, 0x71, 0xE4, 0xFF, 0x00, 0x5A, 0xF6, 0x5C, 0xAE, 0x23, 0x60, 0x85, + 0x73, 0xF1, 0xE4, 0x10, 0xB1, 0x25, 0xAE, 0xD5, 0x92, 0xBB, 0x13, 0xC1, + 0x0C, 0xE0, 0x39, 0xDA, 0xB4, 0x39, 0x57, 0xB5, 0xAB, 0x35, 0xAA, 0x72, + 0x21, 0x3B, 0x83, 0x35, 0xE7, 0x31, 0xDF, 0x7A, 0x21, 0x6E, 0xB8, 0x32, + 0x08, 0x7D, 0x1D, 0x32, 0x91, 0x15, 0x4A, 0x62, 0x72, 0xCF, 0xE3, 0x77, + 0xA1, 0xBC, 0xD5, 0x11, 0x1B, 0x76, 0x01, 0x67, 0x08, 0xE0, 0x41, 0x0B, + 0xC3, 0xEB, 0x15, 0x6E, 0xF8, 0xA4, 0x19, 0xD9, 0xA2, 0xAB, 0xAF, 0xE2, + 0x27, 0x52, 0x56, 0x2B, 0x02, 0x8A, 0x2C, 0x14, 0x24, 0xF9, 0xBF, 0x42, + 0x02, 0xBF, 0x26, 0xC8, 0xC6, 0x8F, 0xE0, 0x6E, 0x38, 0x7D, 0x53, 0x2D, + 0xE5, 0xED, 0x98, 0xB3, 0x95, 0x63, 0x68, 0x7F, 0xF9, 0x35, 0xF4, 0xDF, + 0x88, 0xC5, 0x60, 0x35, 0x92, 0xC0, 0x7C, 0x69, 0x1C, 0x61, 0x95, 0x16, + 0xD0, 0xEB, 0xDE, 0x0B, 0xAF, 0x3E, 0x04, 0x10, 0x45, 0x65, 0x58, 0x50, + 0x38, 0xAF, 0x48, 0xF2, 0x59, 0xB6, 0x16, 0xF2, 0x3C, 0x0D, 0x90, 0x02, + 0xC6, 0x70, 0x2E, 0x01, 0xAD, 0x3C, 0x15, 0xD7 +}; + +static const unsigned char TA34_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA35_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, + 0x64, 0x79, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x49, 0x6E, + 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x28, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6C, + 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA35_RSA_N[] = { + 0xDE, 0x9D, 0xD7, 0xEA, 0x57, 0x18, 0x49, 0xA1, 0x5B, 0xEB, 0xD7, 0x5F, + 0x48, 0x86, 0xEA, 0xBE, 0xDD, 0xFF, 0xE4, 0xEF, 0x67, 0x1C, 0xF4, 0x65, + 0x68, 0xB3, 0x57, 0x71, 0xA0, 0x5E, 0x77, 0xBB, 0xED, 0x9B, 0x49, 0xE9, + 0x70, 0x80, 0x3D, 0x56, 0x18, 0x63, 0x08, 0x6F, 0xDA, 0xF2, 0xCC, 0xD0, + 0x3F, 0x7F, 0x02, 0x54, 0x22, 0x54, 0x10, 0xD8, 0xB2, 0x81, 0xD4, 0xC0, + 0x75, 0x3D, 0x4B, 0x7F, 0xC7, 0x77, 0xC3, 0x3E, 0x78, 0xAB, 0x1A, 0x03, + 0xB5, 0x20, 0x6B, 0x2F, 0x6A, 0x2B, 0xB1, 0xC5, 0x88, 0x7E, 0xC4, 0xBB, + 0x1E, 0xB0, 0xC1, 0xD8, 0x45, 0x27, 0x6F, 0xAA, 0x37, 0x58, 0xF7, 0x87, + 0x26, 0xD7, 0xD8, 0x2D, 0xF6, 0xA9, 0x17, 0xB7, 0x1F, 0x72, 0x36, 0x4E, + 0xA6, 0x17, 0x3F, 0x65, 0x98, 0x92, 0xDB, 0x2A, 0x6E, 0x5D, 0xA2, 0xFE, + 0x88, 0xE0, 0x0B, 0xDE, 0x7F, 0xE5, 0x8D, 0x15, 0xE1, 0xEB, 0xCB, 0x3A, + 0xD5, 0xE2, 0x12, 0xA2, 0x13, 0x2D, 0xD8, 0x8E, 0xAF, 0x5F, 0x12, 0x3D, + 0xA0, 0x08, 0x05, 0x08, 0xB6, 0x5C, 0xA5, 0x65, 0x38, 0x04, 0x45, 0x99, + 0x1E, 0xA3, 0x60, 0x60, 0x74, 0xC5, 0x41, 0xA5, 0x72, 0x62, 0x1B, 0x62, + 0xC5, 0x1F, 0x6F, 0x5F, 0x1A, 0x42, 0xBE, 0x02, 0x51, 0x65, 0xA8, 0xAE, + 0x23, 0x18, 0x6A, 0xFC, 0x78, 0x03, 0xA9, 0x4D, 0x7F, 0x80, 0xC3, 0xFA, + 0xAB, 0x5A, 0xFC, 0xA1, 0x40, 0xA4, 0xCA, 0x19, 0x16, 0xFE, 0xB2, 0xC8, + 0xEF, 0x5E, 0x73, 0x0D, 0xEE, 0x77, 0xBD, 0x9A, 0xF6, 0x79, 0x98, 0xBC, + 0xB1, 0x07, 0x67, 0xA2, 0x15, 0x0D, 0xDD, 0xA0, 0x58, 0xC6, 0x44, 0x7B, + 0x0A, 0x3E, 0x62, 0x28, 0x5F, 0xBA, 0x41, 0x07, 0x53, 0x58, 0xCF, 0x11, + 0x7E, 0x38, 0x74, 0xC5, 0xF8, 0xFF, 0xB5, 0x69, 0x90, 0x8F, 0x84, 0x74, + 0xEA, 0x97, 0x1B, 0xAF +}; + +static const unsigned char TA35_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA36_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA36_EC_Q[] = { + 0x04, 0x4B, 0x36, 0xE9, 0xAE, 0x57, 0x5E, 0xA8, 0x70, 0xD7, 0xD0, 0x8F, + 0x74, 0x62, 0x77, 0xC3, 0x5E, 0x7A, 0xAA, 0xE5, 0xB6, 0xA2, 0xF1, 0x78, + 0xFD, 0x02, 0x7E, 0x57, 0xDD, 0x91, 0x79, 0x9C, 0x6C, 0xB9, 0x52, 0x88, + 0x54, 0xBC, 0x2F, 0x04, 0xBE, 0xB8, 0xCD, 0xF6, 0x10, 0xD1, 0x29, 0xEC, + 0xB5, 0xD0, 0xA0, 0xC3, 0xF0, 0x89, 0x70, 0x19, 0xBB, 0x51, 0x65, 0xC5, + 0x43, 0x9C, 0xC3, 0x9B, 0x63, 0x9D, 0x20, 0x83, 0x3E, 0x06, 0x0B, 0xA6, + 0x42, 0x44, 0x85, 0x11, 0xA7, 0x4A, 0x3A, 0x2D, 0xE9, 0xD6, 0x68, 0x2F, + 0x48, 0x4E, 0x53, 0x2B, 0x07, 0x3F, 0x4D, 0xBD, 0xB9, 0xAC, 0x77, 0x39, + 0x57 +}; + +static const unsigned char TA37_DN[] = { + 0x30, 0x68, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, + 0x6C, 0x64, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA37_RSA_N[] = { + 0xB7, 0x32, 0xC8, 0xFE, 0xE9, 0x71, 0xA6, 0x04, 0x85, 0xAD, 0x0C, 0x11, + 0x64, 0xDF, 0xCE, 0x4D, 0xEF, 0xC8, 0x03, 0x18, 0x87, 0x3F, 0xA1, 0xAB, + 0xFB, 0x3C, 0xA6, 0x9F, 0xF0, 0xC3, 0xA1, 0xDA, 0xD4, 0xD8, 0x6E, 0x2B, + 0x53, 0x90, 0xFB, 0x24, 0xA4, 0x3E, 0x84, 0xF0, 0x9E, 0xE8, 0x5F, 0xEC, + 0xE5, 0x27, 0x44, 0xF5, 0x28, 0xA6, 0x3F, 0x7B, 0xDE, 0xE0, 0x2A, 0xF0, + 0xC8, 0xAF, 0x53, 0x2F, 0x9E, 0xCA, 0x05, 0x01, 0x93, 0x1E, 0x8F, 0x66, + 0x1C, 0x39, 0xA7, 0x4D, 0xFA, 0x5A, 0xB6, 0x73, 0x04, 0x25, 0x66, 0xEB, + 0x77, 0x7F, 0xE7, 0x59, 0xC6, 0x4A, 0x99, 0x25, 0x14, 0x54, 0xEB, 0x26, + 0xC7, 0xF3, 0x7F, 0x19, 0xD5, 0x30, 0x70, 0x8F, 0xAF, 0xB0, 0x46, 0x2A, + 0xFF, 0xAD, 0xEB, 0x29, 0xED, 0xD7, 0x9F, 0xAA, 0x04, 0x87, 0xA3, 0xD4, + 0xF9, 0x89, 0xA5, 0x34, 0x5F, 0xDB, 0x43, 0x91, 0x82, 0x36, 0xD9, 0x66, + 0x3C, 0xB1, 0xB8, 0xB9, 0x82, 0xFD, 0x9C, 0x3A, 0x3E, 0x10, 0xC8, 0x3B, + 0xEF, 0x06, 0x65, 0x66, 0x7A, 0x9B, 0x19, 0x18, 0x3D, 0xFF, 0x71, 0x51, + 0x3C, 0x30, 0x2E, 0x5F, 0xBE, 0x3D, 0x77, 0x73, 0xB2, 0x5D, 0x06, 0x6C, + 0xC3, 0x23, 0x56, 0x9A, 0x2B, 0x85, 0x26, 0x92, 0x1C, 0xA7, 0x02, 0xB3, + 0xE4, 0x3F, 0x0D, 0xAF, 0x08, 0x79, 0x82, 0xB8, 0x36, 0x3D, 0xEA, 0x9C, + 0xD3, 0x35, 0xB3, 0xBC, 0x69, 0xCA, 0xF5, 0xCC, 0x9D, 0xE8, 0xFD, 0x64, + 0x8D, 0x17, 0x80, 0x33, 0x6E, 0x5E, 0x4A, 0x5D, 0x99, 0xC9, 0x1E, 0x87, + 0xB4, 0x9D, 0x1A, 0xC0, 0xD5, 0x6E, 0x13, 0x35, 0x23, 0x5E, 0xDF, 0x9B, + 0x5F, 0x3D, 0xEF, 0xD6, 0xF7, 0x76, 0xC2, 0xEA, 0x3E, 0xBB, 0x78, 0x0D, + 0x1C, 0x42, 0x67, 0x6B, 0x04, 0xD8, 0xF8, 0xD6, 0xDA, 0x6F, 0x8B, 0xF2, + 0x44, 0xA0, 0x01, 0xAB +}; + +static const unsigned char TA37_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA38_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, + 0x6E, 0x63, 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA38_RSA_N[] = { + 0xC6, 0xCC, 0xE5, 0x73, 0xE6, 0xFB, 0xD4, 0xBB, 0xE5, 0x2D, 0x2D, 0x32, + 0xA6, 0xDF, 0xE5, 0x81, 0x3F, 0xC9, 0xCD, 0x25, 0x49, 0xB6, 0x71, 0x2A, + 0xC3, 0xD5, 0x94, 0x34, 0x67, 0xA2, 0x0A, 0x1C, 0xB0, 0x5F, 0x69, 0xA6, + 0x40, 0xB1, 0xC4, 0xB7, 0xB2, 0x8F, 0xD0, 0x98, 0xA4, 0xA9, 0x41, 0x59, + 0x3A, 0xD3, 0xDC, 0x94, 0xD6, 0x3C, 0xDB, 0x74, 0x38, 0xA4, 0x4A, 0xCC, + 0x4D, 0x25, 0x82, 0xF7, 0x4A, 0xA5, 0x53, 0x12, 0x38, 0xEE, 0xF3, 0x49, + 0x6D, 0x71, 0x91, 0x7E, 0x63, 0xB6, 0xAB, 0xA6, 0x5F, 0xC3, 0xA4, 0x84, + 0xF8, 0x4F, 0x62, 0x51, 0xBE, 0xF8, 0xC5, 0xEC, 0xDB, 0x38, 0x92, 0xE3, + 0x06, 0xE5, 0x08, 0x91, 0x0C, 0xC4, 0x28, 0x41, 0x55, 0xFB, 0xCB, 0x5A, + 0x89, 0x15, 0x7E, 0x71, 0xE8, 0x35, 0xBF, 0x4D, 0x72, 0x09, 0x3D, 0xBE, + 0x3A, 0x38, 0x50, 0x5B, 0x77, 0x31, 0x1B, 0x8D, 0xB3, 0xC7, 0x24, 0x45, + 0x9A, 0xA7, 0xAC, 0x6D, 0x00, 0x14, 0x5A, 0x04, 0xB7, 0xBA, 0x13, 0xEB, + 0x51, 0x0A, 0x98, 0x41, 0x41, 0x22, 0x4E, 0x65, 0x61, 0x87, 0x81, 0x41, + 0x50, 0xA6, 0x79, 0x5C, 0x89, 0xDE, 0x19, 0x4A, 0x57, 0xD5, 0x2E, 0xE6, + 0x5D, 0x1C, 0x53, 0x2C, 0x7E, 0x98, 0xCD, 0x1A, 0x06, 0x16, 0xA4, 0x68, + 0x73, 0xD0, 0x34, 0x04, 0x13, 0x5C, 0xA1, 0x71, 0xD3, 0x5A, 0x7C, 0x55, + 0xDB, 0x5E, 0x64, 0xE1, 0x37, 0x87, 0x30, 0x56, 0x04, 0xE5, 0x11, 0xB4, + 0x29, 0x80, 0x12, 0xF1, 0x79, 0x39, 0x88, 0xA2, 0x02, 0x11, 0x7C, 0x27, + 0x66, 0xB7, 0x88, 0xB7, 0x78, 0xF2, 0xCA, 0x0A, 0xA8, 0x38, 0xAB, 0x0A, + 0x64, 0xC2, 0xBF, 0x66, 0x5D, 0x95, 0x84, 0xC1, 0xA1, 0x25, 0x1E, 0x87, + 0x5D, 0x1A, 0x50, 0x0B, 0x20, 0x12, 0xCC, 0x41, 0xBB, 0x6E, 0x0B, 0x51, + 0x38, 0xB8, 0x4B, 0xCB +}; + +static const unsigned char TA38_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA39_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1D, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x50, 0x33, 0x38, 0x34, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA39_EC_Q[] = { + 0x04, 0xC1, 0x44, 0xA1, 0xCF, 0x11, 0x97, 0x50, 0x9A, 0xDE, 0x23, 0x82, + 0x35, 0x07, 0xCD, 0xD0, 0xCB, 0x18, 0x9D, 0xD2, 0xF1, 0x7F, 0x77, 0x35, + 0x4F, 0x3B, 0xDD, 0x94, 0x72, 0x52, 0xED, 0xC2, 0x3B, 0xF8, 0xEC, 0xFA, + 0x7B, 0x6B, 0x58, 0x20, 0xEC, 0x99, 0xAE, 0xC9, 0xFC, 0x68, 0xB3, 0x75, + 0xB9, 0xDB, 0x09, 0xEC, 0xC8, 0x13, 0xF5, 0x4E, 0xC6, 0x0A, 0x1D, 0x66, + 0x30, 0x4C, 0xBB, 0x1F, 0x47, 0x0A, 0x3C, 0x61, 0x10, 0x42, 0x29, 0x7C, + 0xA5, 0x08, 0x0E, 0xE0, 0x22, 0xE9, 0xD3, 0x35, 0x68, 0xCE, 0x9B, 0x63, + 0x9F, 0x84, 0xB5, 0x99, 0x4D, 0x58, 0xA0, 0x8E, 0xF5, 0x54, 0xE7, 0x95, + 0xC9 +}; + +static const unsigned char TA40_DN[] = { + 0x30, 0x67, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x13, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA40_RSA_N[] = { + 0x93, 0x4B, 0xBB, 0xE9, 0x66, 0x8A, 0xEE, 0x9D, 0x5B, 0xD5, 0x34, 0x93, + 0xD0, 0x1B, 0x1E, 0xC3, 0xE7, 0x9E, 0xB8, 0x64, 0x33, 0x7F, 0x63, 0x78, + 0x68, 0xB4, 0xCD, 0x2E, 0x71, 0x75, 0xD7, 0x9B, 0x20, 0xC6, 0x4D, 0x29, + 0xBC, 0xB6, 0x68, 0x60, 0x8A, 0xF7, 0x21, 0x9A, 0x56, 0x35, 0x5A, 0xF3, + 0x76, 0xBD, 0xD8, 0xCD, 0x9A, 0xFF, 0x93, 0x56, 0x4B, 0xA5, 0x59, 0x06, + 0xA1, 0x93, 0x34, 0x29, 0xDD, 0x16, 0x34, 0x75, 0x4E, 0xF2, 0x81, 0xB4, + 0xC7, 0x96, 0x4E, 0xAD, 0x19, 0x15, 0x52, 0x4A, 0xFE, 0x3C, 0x70, 0x75, + 0x70, 0xCD, 0xAF, 0x2B, 0xAB, 0x15, 0x9A, 0x33, 0x3C, 0xAA, 0xB3, 0x8B, + 0xAA, 0xCD, 0x43, 0xFD, 0xF5, 0xEA, 0x70, 0xFF, 0xED, 0xCF, 0x11, 0x3B, + 0x94, 0xCE, 0x4E, 0x32, 0x16, 0xD3, 0x23, 0x40, 0x2A, 0x77, 0xB3, 0xAF, + 0x3C, 0x01, 0x2C, 0x6C, 0xED, 0x99, 0x2C, 0x8B, 0xD9, 0x4E, 0x69, 0x98, + 0xB2, 0xF7, 0x8F, 0x41, 0xB0, 0x32, 0x78, 0x61, 0xD6, 0x0D, 0x5F, 0xC3, + 0xFA, 0xA2, 0x40, 0x92, 0x1D, 0x5C, 0x17, 0xE6, 0x70, 0x3E, 0x35, 0xE7, + 0xA2, 0xB7, 0xC2, 0x62, 0xE2, 0xAB, 0xA4, 0x38, 0x4C, 0xB5, 0x39, 0x35, + 0x6F, 0xEA, 0x03, 0x69, 0xFA, 0x3A, 0x54, 0x68, 0x85, 0x6D, 0xD6, 0xF2, + 0x2F, 0x43, 0x55, 0x1E, 0x91, 0x0D, 0x0E, 0xD8, 0xD5, 0x6A, 0xA4, 0x96, + 0xD1, 0x13, 0x3C, 0x2C, 0x78, 0x50, 0xE8, 0x3A, 0x92, 0xD2, 0x17, 0x56, + 0xE5, 0x35, 0x1A, 0x40, 0x1C, 0x3E, 0x8D, 0x2C, 0xED, 0x39, 0xDF, 0x42, + 0xE0, 0x83, 0x41, 0x74, 0xDF, 0xA3, 0xCD, 0xC2, 0x86, 0x60, 0x48, 0x68, + 0xE3, 0x69, 0x0B, 0x54, 0x00, 0x8B, 0xE4, 0x76, 0x69, 0x21, 0x0D, 0x79, + 0x4E, 0x34, 0x08, 0x5E, 0x14, 0xC2, 0xCC, 0xB1, 0xB7, 0xAD, 0xD7, 0x7C, + 0x70, 0x8A, 0xC7, 0x85 +}; + +static const unsigned char TA40_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA41_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x35, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA41_EC_Q[] = { + 0x04, 0x47, 0x45, 0x0E, 0x96, 0xFB, 0x7D, 0x5D, 0xBF, 0xE9, 0x39, 0xD1, + 0x21, 0xF8, 0x9F, 0x0B, 0xB6, 0xD5, 0x7B, 0x1E, 0x92, 0x3A, 0x48, 0x59, + 0x1C, 0xF0, 0x62, 0x31, 0x2D, 0xC0, 0x7A, 0x28, 0xFE, 0x1A, 0xA7, 0x5C, + 0xB3, 0xB6, 0xCC, 0x97, 0xE7, 0x45, 0xD4, 0x58, 0xFA, 0xD1, 0x77, 0x6D, + 0x43, 0xA2, 0xC0, 0x87, 0x65, 0x34, 0x0A, 0x1F, 0x7A, 0xDD, 0xEB, 0x3C, + 0x33, 0xA1, 0xC5, 0x9D, 0x4D, 0xA4, 0x6F, 0x41, 0x95, 0x38, 0x7F, 0xC9, + 0x1E, 0x84, 0xEB, 0xD1, 0x9E, 0x49, 0x92, 0x87, 0x94, 0x87, 0x0C, 0x3A, + 0x85, 0x4A, 0x66, 0x9F, 0x9D, 0x59, 0x93, 0x4D, 0x97, 0x61, 0x06, 0x86, + 0x4A +}; + +static const unsigned char TA42_DN[] = { + 0x30, 0x52, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x53, 0x4B, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x0A, 0x42, 0x72, 0x61, 0x74, 0x69, 0x73, 0x6C, 0x61, 0x76, 0x61, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x61, 0x2E, 0x73, 0x2E, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x41, 0x20, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x32 +}; + +static const unsigned char TA42_RSA_N[] = { + 0xA2, 0xA3, 0xC4, 0x00, 0x09, 0xD6, 0x85, 0x5D, 0x2D, 0x6D, 0x14, 0xF6, + 0xC2, 0xC3, 0x73, 0x9E, 0x35, 0xC2, 0x71, 0x55, 0x7E, 0x81, 0xFB, 0xAB, + 0x46, 0x50, 0xE0, 0xC1, 0x7C, 0x49, 0x78, 0xE6, 0xAB, 0x79, 0x58, 0x3C, + 0xDA, 0xFF, 0x7C, 0x1C, 0x9F, 0xD8, 0x97, 0x02, 0x78, 0x3E, 0x6B, 0x41, + 0x04, 0xE9, 0x41, 0xBD, 0xBE, 0x03, 0x2C, 0x45, 0xF6, 0x2F, 0x64, 0xD4, + 0xAB, 0x5D, 0xA3, 0x47, 0x3D, 0x64, 0x9B, 0xE9, 0x68, 0x9A, 0xC6, 0xCC, + 0x1B, 0x3F, 0xBA, 0xBE, 0xB2, 0x8B, 0x34, 0x02, 0x2E, 0x98, 0x55, 0x19, + 0xFC, 0x8C, 0x6F, 0xAA, 0x5F, 0xDA, 0x4C, 0xCE, 0x4D, 0x03, 0x21, 0xA3, + 0xD8, 0xD2, 0x34, 0x93, 0x56, 0x96, 0xCB, 0x4C, 0x0C, 0x00, 0x16, 0x3C, + 0x5F, 0x1A, 0xCD, 0xC8, 0xC7, 0x6C, 0xA6, 0xAD, 0xD3, 0x31, 0xA7, 0xBC, + 0xE8, 0xE5, 0xE1, 0x66, 0xD6, 0xD2, 0xFB, 0x03, 0xB4, 0x41, 0x65, 0xC9, + 0x10, 0xAE, 0x0E, 0x05, 0x63, 0xC6, 0x80, 0x6A, 0x69, 0x30, 0xFD, 0xD2, + 0xEE, 0x90, 0xEF, 0x0D, 0x27, 0xDF, 0x9F, 0x95, 0x73, 0xF4, 0xE1, 0x25, + 0xDA, 0x6C, 0x16, 0xDE, 0x41, 0x38, 0x34, 0xEA, 0x8B, 0xFC, 0xD1, 0xE8, + 0x04, 0x14, 0x61, 0x2D, 0x41, 0x7E, 0xAC, 0xC7, 0x77, 0x4E, 0xCB, 0x51, + 0x54, 0xFB, 0x5E, 0x92, 0x18, 0x1B, 0x04, 0x5A, 0x68, 0xC6, 0xC9, 0xC4, + 0xFA, 0xB7, 0x13, 0xA0, 0x98, 0xB7, 0x11, 0x2B, 0xB7, 0xD6, 0x57, 0xCC, + 0x7C, 0x9E, 0x17, 0xD1, 0xCB, 0x25, 0xFE, 0x86, 0x4E, 0x24, 0x2E, 0x56, + 0x0C, 0x78, 0x4D, 0x9E, 0x01, 0x12, 0xA6, 0x2B, 0xA7, 0x01, 0x65, 0x6E, + 0x7C, 0x62, 0x1D, 0x84, 0x84, 0xDF, 0xEA, 0xC0, 0x6B, 0xB5, 0xA5, 0x2A, + 0x95, 0x83, 0xC3, 0x53, 0x11, 0x0C, 0x73, 0x1D, 0x0B, 0xB2, 0x46, 0x90, + 0xD1, 0x42, 0x3A, 0xCE, 0x40, 0x6E, 0x95, 0xAD, 0xFF, 0xC6, 0x94, 0xAD, + 0x6E, 0x97, 0x84, 0x8E, 0x7D, 0x6F, 0x9E, 0x8A, 0x80, 0x0D, 0x49, 0x6D, + 0x73, 0xE2, 0x7B, 0x92, 0x1E, 0xC3, 0xF3, 0xC1, 0xF3, 0xEB, 0x2E, 0x05, + 0x6F, 0xD9, 0x1B, 0xCF, 0x37, 0x76, 0x04, 0xC8, 0xB4, 0x5A, 0xE4, 0x17, + 0xA7, 0xCB, 0xDD, 0x76, 0x1F, 0xD0, 0x19, 0x76, 0xE8, 0x2C, 0x05, 0xB3, + 0xD6, 0x9C, 0x34, 0xD8, 0x96, 0xDC, 0x61, 0x87, 0x91, 0x05, 0xE4, 0x44, + 0x08, 0x33, 0xC1, 0xDA, 0xB9, 0x08, 0x65, 0xD4, 0xAE, 0xB2, 0x36, 0x0D, + 0xEB, 0xBA, 0x38, 0xBA, 0x0C, 0xE5, 0x9B, 0x9E, 0xEB, 0x8D, 0x66, 0xDD, + 0x99, 0xCF, 0xD6, 0x89, 0x41, 0xF6, 0x04, 0x92, 0x8A, 0x29, 0x29, 0x6D, + 0x6B, 0x3A, 0x1C, 0xE7, 0x75, 0x7D, 0x02, 0x71, 0x0E, 0xF3, 0xC0, 0xE7, + 0xBD, 0xCB, 0x19, 0xDD, 0x9D, 0x60, 0xB2, 0xC2, 0x66, 0x60, 0xB6, 0xB1, + 0x04, 0xEE, 0xC9, 0xE6, 0x86, 0xB9, 0x9A, 0x66, 0x40, 0xA8, 0xE7, 0x11, + 0xED, 0x81, 0x45, 0x03, 0x8B, 0xF6, 0x67, 0x59, 0xE8, 0xC1, 0x06, 0x11, + 0xBD, 0xDD, 0xCF, 0x80, 0x02, 0x4F, 0x65, 0x40, 0x78, 0x5C, 0x47, 0x50, + 0xC8, 0x9B, 0xE6, 0x1F, 0x81, 0x7B, 0xE4, 0x44, 0xA8, 0x5B, 0x85, 0x9A, + 0xE2, 0xDE, 0x5A, 0xD5, 0xC7, 0xF9, 0x3A, 0x44, 0x66, 0x4B, 0xE4, 0x32, + 0x54, 0x7C, 0xE4, 0x6C, 0x9C, 0xB3, 0x0E, 0x3D, 0x17, 0xA2, 0xB2, 0x34, + 0x12, 0xD6, 0x7E, 0xB2, 0xA8, 0x49, 0xBB, 0xD1, 0x7A, 0x28, 0x40, 0xBE, + 0xA2, 0x16, 0x1F, 0xDF, 0xE4, 0x37, 0x1F, 0x11, 0x73, 0xFB, 0x90, 0x0A, + 0x65, 0x43, 0xA2, 0x0D, 0x7C, 0xF8, 0x06, 0x01, 0x55, 0x33, 0x7D, 0xB0, + 0x0D, 0xB8, 0xF4, 0xF5, 0xAE, 0xA5, 0x42, 0x57, 0x7C, 0x36, 0x11, 0x8C, + 0x7B, 0x5E, 0xC4, 0x03, 0x9D, 0x8C, 0x79, 0x9D +}; + +static const unsigned char TA42_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA43_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C +}; + +static const unsigned char TA43_RSA_N[] = { + 0xF6, 0x1B, 0x4F, 0x67, 0x07, 0x2B, 0xA1, 0x15, 0xF5, 0x06, 0x22, 0xCB, + 0x1F, 0x01, 0xB2, 0xE3, 0x73, 0x45, 0x06, 0x44, 0x49, 0x2C, 0xBB, 0x49, + 0x25, 0x14, 0xD6, 0xCE, 0xC3, 0xB7, 0xAB, 0x2C, 0x4F, 0xC6, 0x41, 0x32, + 0x94, 0x57, 0xFA, 0x12, 0xA7, 0x5B, 0x0E, 0xE2, 0x8F, 0x1F, 0x1E, 0x86, + 0x19, 0xA7, 0xAA, 0xB5, 0x2D, 0xB9, 0x5F, 0x0D, 0x8A, 0xC2, 0xAF, 0x85, + 0x35, 0x79, 0x32, 0x2D, 0xBB, 0x1C, 0x62, 0x37, 0xF2, 0xB1, 0x5B, 0x4A, + 0x3D, 0xCA, 0xCD, 0x71, 0x5F, 0xE9, 0x42, 0xBE, 0x94, 0xE8, 0xC8, 0xDE, + 0xF9, 0x22, 0x48, 0x64, 0xC6, 0xE5, 0xAB, 0xC6, 0x2B, 0x6D, 0xAD, 0x05, + 0xF0, 0xFA, 0xD5, 0x0B, 0xCF, 0x9A, 0xE5, 0xF0, 0x50, 0xA4, 0x8B, 0x3B, + 0x47, 0xA5, 0x23, 0x5B, 0x7A, 0x7A, 0xF8, 0x33, 0x3F, 0xB8, 0xEF, 0x99, + 0x97, 0xE3, 0x20, 0xC1, 0xD6, 0x28, 0x89, 0xCF, 0x94, 0xFB, 0xB9, 0x45, + 0xED, 0xE3, 0x40, 0x17, 0x11, 0xD4, 0x74, 0xF0, 0x0B, 0x31, 0xE2, 0x2B, + 0x26, 0x6A, 0x9B, 0x4C, 0x57, 0xAE, 0xAC, 0x20, 0x3E, 0xBA, 0x45, 0x7A, + 0x05, 0xF3, 0xBD, 0x9B, 0x69, 0x15, 0xAE, 0x7D, 0x4E, 0x20, 0x63, 0xC4, + 0x35, 0x76, 0x3A, 0x07, 0x02, 0xC9, 0x37, 0xFD, 0xC7, 0x47, 0xEE, 0xE8, + 0xF1, 0x76, 0x1D, 0x73, 0x15, 0xF2, 0x97, 0xA4, 0xB5, 0xC8, 0x7A, 0x79, + 0xD9, 0x42, 0xAA, 0x2B, 0x7F, 0x5C, 0xFE, 0xCE, 0x26, 0x4F, 0xA3, 0x66, + 0x81, 0x35, 0xAF, 0x44, 0xBA, 0x54, 0x1E, 0x1C, 0x30, 0x32, 0x65, 0x9D, + 0xE6, 0x3C, 0x93, 0x5E, 0x50, 0x4E, 0x7A, 0xE3, 0x3A, 0xD4, 0x6E, 0xCC, + 0x1A, 0xFB, 0xF9, 0xD2, 0x37, 0xAE, 0x24, 0x2A, 0xAB, 0x57, 0x03, 0x22, + 0x28, 0x0D, 0x49, 0x75, 0x7F, 0xB7, 0x28, 0xDA, 0x75, 0xBF, 0x8E, 0xE3, + 0xDC, 0x0E, 0x79, 0x31 +}; + +static const unsigned char TA43_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA44_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA44_RSA_N[] = { + 0xD0, 0xA4, 0x09, 0x72, 0x4F, 0x40, 0x88, 0x12, 0x61, 0x3E, 0x35, 0x23, + 0x9E, 0xEE, 0xF6, 0x74, 0xCF, 0x2F, 0x7B, 0x58, 0x3D, 0xCE, 0x3C, 0x0D, + 0x10, 0x28, 0x90, 0x2F, 0x97, 0xF7, 0x8C, 0x48, 0xD8, 0xA0, 0xD8, 0x25, + 0xB1, 0x4C, 0xB0, 0x11, 0x4C, 0x17, 0x73, 0x50, 0xD0, 0x22, 0x4A, 0x63, + 0xBB, 0x81, 0xD3, 0x29, 0x6E, 0xD5, 0xB5, 0x09, 0x3E, 0x26, 0x18, 0x7F, + 0xB2, 0x12, 0x7F, 0x93, 0x98, 0xB7, 0xAF, 0xF0, 0x36, 0xBF, 0xF2, 0xEE, + 0x18, 0x9E, 0x9C, 0x3B, 0x52, 0xC5, 0x47, 0x19, 0x5D, 0x74, 0xF3, 0x64, + 0x66, 0xD5, 0x5D, 0xC7, 0x68, 0xB4, 0xBF, 0x1B, 0x1C, 0x06, 0xA3, 0xBC, + 0x8F, 0x40, 0x23, 0xB6, 0x1E, 0xC6, 0x84, 0xBD, 0x51, 0xC4, 0x1B, 0x39, + 0xC1, 0x95, 0xD2, 0x29, 0xEC, 0x4B, 0xAE, 0x7B, 0x2D, 0xBF, 0x39, 0xFD, + 0xB4, 0x62, 0xDE, 0x96, 0x7B, 0x41, 0xC6, 0x9C, 0xA0, 0xE0, 0x06, 0x72, + 0xFB, 0xF0, 0x07, 0x97, 0x09, 0x39, 0x81, 0x74, 0xAF, 0xF7, 0x34, 0x59, + 0x11, 0x57, 0x0A, 0xC2, 0x5B, 0xC1, 0x24, 0xF4, 0x31, 0x73, 0x30, 0x82, + 0xC6, 0x9D, 0xBA, 0x02, 0xF7, 0x3E, 0x7C, 0x44, 0x5F, 0x83, 0x0D, 0xF3, + 0xF1, 0xDD, 0x20, 0x69, 0x16, 0x09, 0x50, 0xE2, 0xD4, 0x55, 0xB6, 0xE0, + 0x80, 0x72, 0x76, 0x6E, 0x4C, 0x47, 0xB7, 0x75, 0x55, 0x59, 0xB4, 0x53, + 0x74, 0xD9, 0x94, 0xC6, 0x41, 0xAD, 0x58, 0x8A, 0x31, 0x66, 0x0F, 0x1E, + 0xA2, 0x1B, 0x29, 0x40, 0x4E, 0x2F, 0xDF, 0x7B, 0xE6, 0x16, 0x2C, 0x2D, + 0xFC, 0xBF, 0xEC, 0xF3, 0xB4, 0xFA, 0xBE, 0x18, 0xF6, 0x9B, 0x49, 0xD4, + 0xEE, 0x05, 0x6E, 0xD9, 0x34, 0xF3, 0x9C, 0xF1, 0xEC, 0x01, 0x8B, 0xD1, + 0x20, 0xC6, 0x0F, 0xA0, 0xB5, 0xBC, 0x17, 0x4E, 0x48, 0x7B, 0x51, 0xC2, + 0xFC, 0xE9, 0x5C, 0x69, 0x37, 0x47, 0x66, 0xB3, 0x68, 0xF8, 0x15, 0x28, + 0xF0, 0xB9, 0xD3, 0xA4, 0x15, 0xCC, 0x5A, 0x4F, 0xBA, 0x52, 0x70, 0xA3, + 0x12, 0x45, 0xDD, 0xC6, 0xBA, 0x4E, 0xFB, 0xC2, 0xD0, 0xF7, 0xA8, 0x52, + 0x27, 0x6D, 0x6E, 0x79, 0xB5, 0x8C, 0xFC, 0x7B, 0x8C, 0xC1, 0x16, 0x4C, + 0xEE, 0x80, 0x7F, 0xBE, 0xF0, 0x76, 0xBE, 0x41, 0x53, 0x12, 0x33, 0xAE, + 0x5A, 0x38, 0x42, 0xAB, 0xD7, 0x0F, 0x3E, 0x41, 0x8D, 0x76, 0x07, 0x32, + 0xD5, 0xAB, 0x89, 0xF6, 0x4E, 0x67, 0xD9, 0xB1, 0x42, 0x75, 0x23, 0x6E, + 0xF3, 0xCD, 0x42, 0xB2, 0xFC, 0x55, 0xF5, 0x53, 0x87, 0x17, 0x3B, 0xC0, + 0x33, 0x58, 0xF1, 0x52, 0xD2, 0xF9, 0x80, 0xA4, 0xF0, 0xE8, 0xF0, 0x3B, + 0x8B, 0x38, 0xCC, 0xA4, 0xC6, 0x90, 0x7F, 0x0F, 0x9C, 0xFD, 0x8B, 0xD1, + 0xA3, 0xCF, 0xDA, 0x83, 0xA7, 0x69, 0xC9, 0x50, 0x36, 0xD5, 0x5C, 0x05, + 0xD2, 0x0A, 0x41, 0x74, 0xDB, 0x63, 0x11, 0x37, 0xC1, 0xA5, 0xA0, 0x96, + 0x4B, 0x1E, 0x8C, 0x16, 0x12, 0x77, 0xAE, 0x94, 0x34, 0x7B, 0x1E, 0x7F, + 0xC2, 0x66, 0x00, 0xE4, 0xAA, 0x83, 0xEA, 0x8A, 0x90, 0xAD, 0xCE, 0x36, + 0x44, 0x4D, 0xD1, 0x51, 0xE9, 0xBC, 0x1F, 0xF3, 0x6A, 0x05, 0xFD, 0xC0, + 0x74, 0x1F, 0x25, 0x19, 0x40, 0x51, 0x6E, 0xEA, 0x82, 0x51, 0x40, 0xDF, + 0x9B, 0xB9, 0x08, 0x2A, 0x06, 0x02, 0xD5, 0x23, 0x1C, 0x13, 0xD6, 0xE9, + 0xDB, 0xDB, 0xC6, 0xB0, 0x7A, 0xCB, 0x7B, 0x27, 0x9B, 0xFB, 0xE0, 0xD5, + 0x46, 0x24, 0xED, 0x10, 0x4B, 0x63, 0x4B, 0xA5, 0x05, 0x8F, 0xBA, 0xB8, + 0x1D, 0x2B, 0xA6, 0xFA, 0x91, 0xE2, 0x92, 0x52, 0xBD, 0xEC, 0xEB, 0x67, + 0x97, 0x6D, 0x9A, 0x2D, 0x9F, 0x81, 0x32, 0x05, 0x67, 0x32, 0xFB, 0x48, + 0x08, 0x3F, 0xD9, 0x25, 0xB8, 0x04, 0x25, 0x2F +}; + +static const unsigned char TA44_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA45_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x45, 0x43, 0x43, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA45_EC_Q[] = { + 0x04, 0x96, 0x86, 0x58, 0x28, 0x37, 0x0A, 0x67, 0xD0, 0xA0, 0xDE, 0x24, + 0x19, 0x19, 0xE1, 0xE4, 0x05, 0x07, 0x1F, 0x97, 0xED, 0xE8, 0x64, 0x82, + 0xB9, 0xF6, 0xC4, 0x71, 0x50, 0xCE, 0x8A, 0x0C, 0xFF, 0xD7, 0xB5, 0x76, + 0xBB, 0xA1, 0x6C, 0x93, 0x6C, 0x83, 0xA2, 0x68, 0x6E, 0xA5, 0xD9, 0xBE, + 0x2C, 0x88, 0x95, 0x41, 0xCD, 0x5D, 0xDD, 0xB1, 0xCA, 0x83, 0x63, 0x83, + 0xCC, 0xC0, 0xBE, 0x74, 0xD9, 0xE0, 0x9D, 0xA4, 0xEE, 0x4A, 0x4E, 0x56, + 0xE0, 0x98, 0x29, 0x41, 0x93, 0x52, 0x10, 0xD5, 0x24, 0x38, 0x02, 0x32, + 0x67, 0xF1, 0x94, 0x12, 0x6F, 0xEF, 0xD7, 0xC5, 0xDE, 0x2E, 0xFD, 0x19, + 0x80 +}; + +static const unsigned char TA46_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA46_RSA_N[] = { + 0xA5, 0xDA, 0x0A, 0x95, 0x16, 0x50, 0xE3, 0x95, 0xF2, 0x5E, 0x9D, 0x76, + 0x31, 0x06, 0x32, 0x7A, 0x9B, 0xF1, 0x10, 0x76, 0xB8, 0x00, 0x9A, 0xB5, + 0x52, 0x36, 0xCD, 0x24, 0x47, 0xB0, 0x9F, 0x18, 0x64, 0xBC, 0x9A, 0xF6, + 0xFA, 0xD5, 0x79, 0xD8, 0x90, 0x62, 0x4C, 0x22, 0x2F, 0xDE, 0x38, 0x3D, + 0xD6, 0xE0, 0xA8, 0xE9, 0x1C, 0x2C, 0xDB, 0x78, 0x11, 0xE9, 0x8E, 0x68, + 0x51, 0x15, 0x72, 0xC7, 0xF3, 0x33, 0x87, 0xE4, 0xA0, 0x5D, 0x0B, 0x5C, + 0xE0, 0x57, 0x07, 0x2A, 0x30, 0xF5, 0xCD, 0xC4, 0x37, 0x77, 0x28, 0x4D, + 0x18, 0x91, 0xE6, 0xBF, 0xD5, 0x52, 0xFD, 0x71, 0x2D, 0x70, 0x3E, 0xE7, + 0xC6, 0xC4, 0x8A, 0xE3, 0xF0, 0x28, 0x0B, 0xF4, 0x76, 0x98, 0xA1, 0x8B, + 0x87, 0x55, 0xB2, 0x3A, 0x13, 0xFC, 0xB7, 0x3E, 0x27, 0x37, 0x8E, 0x22, + 0xE3, 0xA8, 0x4F, 0x2A, 0xEF, 0x60, 0xBB, 0x3D, 0xB7, 0x39, 0xC3, 0x0E, + 0x01, 0x47, 0x99, 0x5D, 0x12, 0x4F, 0xDB, 0x43, 0xFA, 0x57, 0xA1, 0xED, + 0xF9, 0x9D, 0xBE, 0x11, 0x47, 0x26, 0x5B, 0x13, 0x98, 0xAB, 0x5D, 0x16, + 0x8A, 0xB0, 0x37, 0x1C, 0x57, 0x9D, 0x45, 0xFF, 0x88, 0x96, 0x36, 0xBF, + 0xBB, 0xCA, 0x07, 0x7B, 0x6F, 0x87, 0x63, 0xD7, 0xD0, 0x32, 0x6A, 0xD6, + 0x5D, 0x6C, 0x0C, 0xF1, 0xB3, 0x6E, 0x39, 0xE2, 0x6B, 0x31, 0x2E, 0x39, + 0x00, 0x27, 0x14, 0xDE, 0x38, 0xC0, 0xEC, 0x19, 0x66, 0x86, 0x12, 0xE8, + 0x9D, 0x72, 0x16, 0x13, 0x64, 0x52, 0xC7, 0xA9, 0x37, 0x1C, 0xFD, 0x82, + 0x30, 0xED, 0x84, 0x18, 0x1D, 0xF4, 0xAE, 0x5C, 0xFF, 0x70, 0x13, 0x00, + 0xEB, 0xB1, 0xF5, 0x33, 0x7A, 0x4B, 0xD6, 0x55, 0xF8, 0x05, 0x8D, 0x4B, + 0x69, 0xB0, 0xF5, 0xB3, 0x28, 0x36, 0x5C, 0x14, 0xC4, 0x51, 0x73, 0x4D, + 0x6B, 0x0B, 0xF1, 0x34, 0x07, 0xDB, 0x17, 0x39, 0xD7, 0xDC, 0x28, 0x7B, + 0x6B, 0xF5, 0x9F, 0xF3, 0x2E, 0xC1, 0x4F, 0x17, 0x2A, 0x10, 0xF3, 0xCC, + 0xCA, 0xE8, 0xEB, 0xFD, 0x6B, 0xAB, 0x2E, 0x9A, 0x9F, 0x2D, 0x82, 0x6E, + 0x04, 0xD4, 0x52, 0x01, 0x93, 0x2D, 0x3D, 0x86, 0xFC, 0x7E, 0xFC, 0xDF, + 0xEF, 0x42, 0x1D, 0xA6, 0x6B, 0xEF, 0xB9, 0x20, 0xC6, 0xF7, 0xBD, 0xA0, + 0xA7, 0x95, 0xFD, 0xA7, 0xE6, 0x89, 0x24, 0xD8, 0xCC, 0x8C, 0x34, 0x6C, + 0xE2, 0x23, 0x2F, 0xD9, 0x12, 0x1A, 0x21, 0xB9, 0x55, 0x91, 0x6F, 0x0B, + 0x91, 0x79, 0x19, 0x0C, 0xAD, 0x40, 0x88, 0x0B, 0x70, 0xE2, 0x7A, 0xD2, + 0x0E, 0xD8, 0x68, 0x48, 0xBB, 0x82, 0x13, 0x39, 0x10, 0x58, 0xE9, 0xD8, + 0x2A, 0x07, 0xC6, 0x12, 0xDB, 0x58, 0xDB, 0xD2, 0x3B, 0x55, 0x10, 0x47, + 0x05, 0x15, 0x67, 0x62, 0x7E, 0x18, 0x63, 0xA6, 0x46, 0x3F, 0x09, 0x0E, + 0x54, 0x32, 0x5E, 0xBF, 0x0D, 0x62, 0x7A, 0x27, 0xEF, 0x80, 0xE8, 0xDB, + 0xD9, 0x4B, 0x06, 0x5A, 0x37, 0x5A, 0x25, 0xD0, 0x08, 0x12, 0x77, 0xD4, + 0x6F, 0x09, 0x50, 0x97, 0x3D, 0xC8, 0x1D, 0xC3, 0xDF, 0x8C, 0x45, 0x30, + 0x56, 0xC6, 0xD3, 0x64, 0xAB, 0x66, 0xF3, 0xC0, 0x5E, 0x96, 0x9C, 0xC3, + 0xC4, 0xEF, 0xC3, 0x7C, 0x6B, 0x8B, 0x3A, 0x79, 0x7F, 0xB3, 0x49, 0xCF, + 0x3D, 0xE2, 0x89, 0x9F, 0xA0, 0x30, 0x4B, 0x85, 0xB9, 0x9C, 0x94, 0x24, + 0x79, 0x8F, 0x7D, 0x6B, 0xA9, 0x45, 0x68, 0x0F, 0x2B, 0xD0, 0xF1, 0xDA, + 0x1C, 0xCB, 0x69, 0xB8, 0xCA, 0x49, 0x62, 0x6D, 0xC8, 0xD0, 0x63, 0x62, + 0xDD, 0x60, 0x0F, 0x58, 0xAA, 0x8F, 0xA1, 0xBC, 0x05, 0xA5, 0x66, 0xA2, + 0xCF, 0x1B, 0x76, 0xB2, 0x84, 0x64, 0xB1, 0x4C, 0x39, 0x52, 0xC0, 0x30, + 0xBA, 0xF0, 0x8C, 0x4B, 0x02, 0xB0, 0xB6, 0xB7 +}; + +static const unsigned char TA46_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA47_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x13, 0x30, 0x30, + 0x30, 0x32, 0x20, 0x34, 0x38, 0x31, 0x34, 0x36, 0x33, 0x30, 0x38, 0x31, + 0x30, 0x30, 0x30, 0x33, 0x36, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA47_RSA_N[] = { + 0xCD, 0x18, 0x39, 0x65, 0x1A, 0x59, 0xB1, 0xEA, 0x64, 0x16, 0x0E, 0x8C, + 0x94, 0x24, 0x95, 0x7C, 0x83, 0xD3, 0xC5, 0x39, 0x26, 0xDC, 0x0C, 0xEF, + 0x16, 0x57, 0x8D, 0xD7, 0xD8, 0xAC, 0xA3, 0x42, 0x7F, 0x82, 0xCA, 0xED, + 0xCD, 0x5B, 0xDB, 0x0E, 0xB7, 0x2D, 0xED, 0x45, 0x08, 0x17, 0xB2, 0xD9, + 0xB3, 0xCB, 0xD6, 0x17, 0x52, 0x72, 0x28, 0xDB, 0x8E, 0x4E, 0x9E, 0x8A, + 0xB6, 0x0B, 0xF9, 0x9E, 0x84, 0x9A, 0x4D, 0x76, 0xDE, 0x22, 0x29, 0x5C, + 0xD2, 0xB3, 0xD2, 0x06, 0x3E, 0x30, 0x39, 0xA9, 0x74, 0xA3, 0x92, 0x56, + 0x1C, 0xA1, 0x6F, 0x4C, 0x0A, 0x20, 0x6D, 0x9F, 0x23, 0x7A, 0xB4, 0xC6, + 0xDA, 0x2C, 0xE4, 0x1D, 0x2C, 0xDC, 0xB3, 0x28, 0xD0, 0x13, 0xF2, 0x4C, + 0x4E, 0x02, 0x49, 0xA1, 0x54, 0x40, 0x9E, 0xE6, 0xE5, 0x05, 0xA0, 0x2D, + 0x84, 0xC8, 0xFF, 0x98, 0x6C, 0xD0, 0xEB, 0x8A, 0x1A, 0x84, 0x08, 0x1E, + 0xB7, 0x68, 0x23, 0xEE, 0x23, 0xD5, 0x70, 0xCE, 0x6D, 0x51, 0x69, 0x10, + 0xEE, 0xA1, 0x7A, 0xC2, 0xD1, 0x22, 0x31, 0xC2, 0x82, 0x85, 0xD2, 0xF2, + 0x55, 0x76, 0x50, 0x7C, 0x25, 0x7A, 0xC9, 0x84, 0x5C, 0x0B, 0xAC, 0xDD, + 0x42, 0x4E, 0x2B, 0xE7, 0x82, 0xA2, 0x24, 0x89, 0xCB, 0x90, 0xB2, 0xD0, + 0xEE, 0x23, 0xBA, 0x66, 0x4C, 0xBB, 0x62, 0xA4, 0xF9, 0x53, 0x5A, 0x64, + 0x7B, 0x7C, 0x98, 0xFA, 0xA3, 0x48, 0x9E, 0x0F, 0x95, 0xAE, 0xA7, 0x18, + 0xF4, 0x6A, 0xEC, 0x2E, 0x03, 0x45, 0xAF, 0xF0, 0x74, 0xF8, 0x2A, 0xCD, + 0x7A, 0x5D, 0xD1, 0xBE, 0x44, 0x26, 0x32, 0x29, 0xF1, 0xF1, 0xF5, 0x6C, + 0xCC, 0x7E, 0x02, 0x21, 0x0B, 0x9F, 0x6F, 0xA4, 0x3F, 0xBE, 0x9D, 0x53, + 0xE2, 0xCF, 0x7D, 0xA9, 0x2C, 0x7C, 0x58, 0x1A, 0x97, 0xE1, 0x3D, 0x37, + 0x37, 0x18, 0x66, 0x28, 0xD2, 0x40, 0xC5, 0x51, 0x8A, 0x8C, 0xC3, 0x2D, + 0xCE, 0x53, 0x88, 0x24, 0x58, 0x64, 0x30, 0x16, 0xC5, 0xAA, 0xE0, 0xD6, + 0x0A, 0xA6, 0x40, 0xDF, 0x78, 0xF6, 0xF5, 0x04, 0x7C, 0x69, 0x13, 0x84, + 0xBC, 0xD1, 0xD1, 0xA7, 0x06, 0xCF, 0x01, 0xF7, 0x68, 0xC0, 0xA8, 0x57, + 0xBB, 0x3A, 0x61, 0xAD, 0x04, 0x8C, 0x93, 0xE3, 0xAD, 0xFC, 0xF0, 0xDB, + 0x44, 0x6D, 0x59, 0xDC, 0x49, 0x59, 0xAE, 0xAC, 0x9A, 0x99, 0x36, 0x30, + 0x41, 0x7B, 0x76, 0x33, 0x22, 0x87, 0xA3, 0xC2, 0x92, 0x86, 0x6E, 0xF9, + 0x70, 0xEE, 0xAE, 0x87, 0x87, 0x95, 0x1B, 0xC4, 0x7A, 0xBD, 0x31, 0xF3, + 0xD4, 0xD2, 0xE5, 0x99, 0xFF, 0xBE, 0x48, 0xEC, 0x75, 0xF5, 0x78, 0x16, + 0x1D, 0xA6, 0x70, 0xC1, 0x7F, 0x3C, 0x1B, 0xA1, 0x92, 0xFB, 0xCF, 0xC8, + 0x3C, 0xD6, 0xC5, 0x93, 0x0A, 0x8F, 0xF5, 0x55, 0x3A, 0x76, 0x95, 0xCE, + 0x59, 0x98, 0x8A, 0x09, 0x95, 0x77, 0x32, 0x9A, 0x83, 0xBA, 0x2C, 0x04, + 0x3A, 0x97, 0xBD, 0xD4, 0x2F, 0xBE, 0xD7, 0x6C, 0x9B, 0xA2, 0xCA, 0x7D, + 0x6D, 0x26, 0xC9, 0x55, 0xD5, 0xCF, 0xC3, 0x79, 0x52, 0x08, 0x09, 0x99, + 0x07, 0x24, 0x2D, 0x64, 0x25, 0x6B, 0xA6, 0x21, 0x69, 0x9B, 0x6A, 0xDD, + 0x74, 0x4D, 0x6B, 0x97, 0x7A, 0x41, 0xBD, 0xAB, 0x17, 0xF9, 0x90, 0x17, + 0x48, 0x8F, 0x36, 0xF9, 0x2D, 0xD5, 0xC5, 0xDB, 0xEE, 0xAA, 0x85, 0x45, + 0x41, 0xFA, 0xCD, 0x3A, 0x45, 0xB1, 0x68, 0xE6, 0x36, 0x4C, 0x9B, 0x90, + 0x57, 0xEC, 0x23, 0xB9, 0x87, 0x08, 0xC2, 0xC4, 0x09, 0xF1, 0x97, 0x86, + 0x2A, 0x28, 0x4D, 0xE2, 0x74, 0xC0, 0xDA, 0xC4, 0x8C, 0xDB, 0xDF, 0xE2, + 0xA1, 0x17, 0x59, 0xCE, 0x24, 0x59, 0x74, 0x31, 0xDA, 0x7F, 0xFD, 0x30, + 0x6D, 0xD9, 0xDC, 0xE1, 0x6A, 0xE1, 0xFC, 0x5F +}; + +static const unsigned char TA47_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA48_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x1B, + 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x55, 0x43, 0x41, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x47, 0x32, 0x20, 0x52, + 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA48_RSA_N[] = { + 0xC5, 0xE6, 0x2B, 0x6F, 0x7C, 0xEF, 0x26, 0x05, 0x27, 0xA3, 0x81, 0x24, + 0xDA, 0x6F, 0xCB, 0x01, 0xF9, 0x99, 0x9A, 0xA9, 0x32, 0xC2, 0x22, 0x87, + 0x61, 0x41, 0x91, 0x3B, 0xCB, 0xC3, 0x68, 0x1B, 0x06, 0xC5, 0x4C, 0xA9, + 0x2B, 0xC1, 0x67, 0x17, 0x22, 0x1D, 0x2B, 0xED, 0xF9, 0x29, 0x89, 0x93, + 0xA2, 0x78, 0xBD, 0x92, 0x6B, 0xA0, 0xA3, 0x0D, 0xA2, 0x7E, 0xCA, 0x93, + 0xB3, 0xA6, 0xD1, 0x8C, 0x35, 0xD5, 0x75, 0xF9, 0x17, 0xF6, 0xCF, 0x45, + 0xC5, 0xE5, 0x7A, 0xEC, 0x77, 0x93, 0xA0, 0x8F, 0x23, 0xAE, 0x0E, 0x1A, + 0x03, 0x7F, 0xBE, 0xD4, 0xD0, 0xED, 0x2E, 0x7B, 0xAB, 0x46, 0x23, 0x5B, + 0xFF, 0x2C, 0xE6, 0x54, 0x7A, 0x94, 0xC0, 0x2A, 0x15, 0xF0, 0xC9, 0x8D, + 0xB0, 0x7A, 0x3B, 0x24, 0xE1, 0xD7, 0x68, 0xE2, 0x31, 0x3C, 0x06, 0x33, + 0x46, 0xB6, 0x54, 0x11, 0xA6, 0xA5, 0x2F, 0x22, 0x54, 0x2A, 0x58, 0x0D, + 0x01, 0x02, 0xF1, 0xFA, 0x15, 0x51, 0x67, 0x6C, 0xC0, 0xFA, 0xD7, 0xB6, + 0x1B, 0x7F, 0xD1, 0x56, 0x88, 0x2F, 0x1A, 0x3A, 0x8D, 0x3B, 0xBB, 0x82, + 0x11, 0xE0, 0x47, 0x00, 0xD0, 0x52, 0x87, 0xAB, 0xFB, 0x86, 0x7E, 0x0F, + 0x24, 0x6B, 0x40, 0x9D, 0x34, 0x67, 0xBC, 0x8D, 0xC7, 0x2D, 0x86, 0x6F, + 0x79, 0x3E, 0x8E, 0xA9, 0x3C, 0x17, 0x4B, 0x7F, 0xB0, 0x99, 0xE3, 0xB0, + 0x71, 0x60, 0xDC, 0x0B, 0xF5, 0x64, 0xC3, 0xCE, 0x43, 0xBC, 0x6D, 0x71, + 0xB9, 0xD2, 0xDE, 0x27, 0x5B, 0x8A, 0xE8, 0xD8, 0xC6, 0xAE, 0xE1, 0x59, + 0x7D, 0xCF, 0x28, 0x2D, 0x35, 0xB8, 0x95, 0x56, 0x1A, 0xF1, 0xB2, 0x58, + 0x4B, 0xB7, 0x12, 0x37, 0xC8, 0x7C, 0xB3, 0xED, 0x4B, 0x80, 0xE1, 0x8D, + 0xFA, 0x32, 0x23, 0xB6, 0x6F, 0xB7, 0x48, 0x95, 0x08, 0xB1, 0x44, 0x4E, + 0x85, 0x8C, 0x3A, 0x02, 0x54, 0x20, 0x2F, 0xDF, 0xBF, 0x57, 0x4F, 0x3B, + 0x3A, 0x90, 0x21, 0xD7, 0xC1, 0x26, 0x35, 0x54, 0x20, 0xEC, 0xC7, 0x3F, + 0x47, 0xEC, 0xEF, 0x5A, 0xBF, 0x4B, 0x7A, 0xC1, 0xAD, 0x3B, 0x17, 0x50, + 0x5C, 0x62, 0xD8, 0x0F, 0x4B, 0x4A, 0xDC, 0x2B, 0xFA, 0x6E, 0xBC, 0x73, + 0x92, 0xCD, 0xEC, 0xC7, 0x50, 0xE8, 0x41, 0x96, 0xD7, 0xA9, 0x7E, 0x6D, + 0xD8, 0xE9, 0x1D, 0x8F, 0x8A, 0xB5, 0xB9, 0x58, 0x92, 0xBA, 0x4A, 0x92, + 0x2B, 0x0C, 0x56, 0xFD, 0x80, 0xEB, 0x08, 0xF0, 0x5E, 0x29, 0x6E, 0x1B, + 0x1C, 0x0C, 0xAF, 0x8F, 0x93, 0x89, 0xAD, 0xDB, 0xBD, 0xA3, 0x9E, 0x21, + 0xCA, 0x89, 0x19, 0xEC, 0xDF, 0xB5, 0xC3, 0x1A, 0xEB, 0x16, 0xFE, 0x78, + 0x36, 0x4C, 0xD6, 0x6E, 0xD0, 0x3E, 0x17, 0x1C, 0x90, 0x17, 0x6B, 0x26, + 0xBA, 0xFB, 0x7A, 0x2F, 0xBF, 0x11, 0x1C, 0x18, 0x0E, 0x2D, 0x73, 0x03, + 0x8F, 0xA0, 0xE5, 0x35, 0xA0, 0x5A, 0xE2, 0x4C, 0x75, 0x1D, 0x71, 0xE1, + 0x39, 0x38, 0x53, 0x78, 0x40, 0xCC, 0x83, 0x93, 0xD7, 0x0A, 0x9E, 0x9D, + 0x5B, 0x8F, 0x8A, 0xE4, 0xE5, 0xE0, 0x48, 0xE4, 0x48, 0xB2, 0x47, 0xCD, + 0x4E, 0x2A, 0x75, 0x2A, 0x7B, 0xF2, 0x22, 0xF6, 0xC9, 0xBE, 0x09, 0x91, + 0x96, 0x57, 0x7A, 0x88, 0x88, 0xAC, 0xEE, 0x70, 0xAC, 0xF9, 0xDC, 0x29, + 0xE3, 0x0C, 0x1C, 0x3B, 0x12, 0x4E, 0x44, 0xD6, 0xA7, 0x4E, 0xB0, 0x26, + 0xC8, 0xF3, 0xD9, 0x1A, 0x97, 0x91, 0x68, 0xEA, 0xEF, 0x8D, 0x46, 0x06, + 0xD2, 0x56, 0x45, 0x58, 0x9A, 0x3C, 0x0C, 0x0F, 0x83, 0xB8, 0x05, 0x25, + 0xC3, 0x39, 0xCF, 0x3B, 0xA4, 0x34, 0x89, 0xB7, 0x79, 0x12, 0x2F, 0x47, + 0xC5, 0xE7, 0xA9, 0x97, 0x69, 0xFC, 0xA6, 0x77, 0x67, 0xB5, 0xDF, 0x7B, + 0xF1, 0x7A, 0x65, 0x15, 0xE4, 0x61, 0x56, 0x65 +}; + +static const unsigned char TA48_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA49_DN[] = { + 0x30, 0x81, 0xD2, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x54, 0x52, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x0F, 0x47, 0x65, 0x62, 0x7A, 0x65, 0x20, 0x2D, 0x20, 0x4B, + 0x6F, 0x63, 0x61, 0x65, 0x6C, 0x69, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x13, 0x39, 0x54, 0x75, 0x72, 0x6B, 0x69, 0x79, 0x65, + 0x20, 0x42, 0x69, 0x6C, 0x69, 0x6D, 0x73, 0x65, 0x6C, 0x20, 0x76, 0x65, + 0x20, 0x54, 0x65, 0x6B, 0x6E, 0x6F, 0x6C, 0x6F, 0x6A, 0x69, 0x6B, 0x20, + 0x41, 0x72, 0x61, 0x73, 0x74, 0x69, 0x72, 0x6D, 0x61, 0x20, 0x4B, 0x75, + 0x72, 0x75, 0x6D, 0x75, 0x20, 0x2D, 0x20, 0x54, 0x55, 0x42, 0x49, 0x54, + 0x41, 0x4B, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x24, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x6B, 0x61, 0x73, 0x79, 0x6F, 0x6E, 0x20, 0x4D, 0x65, 0x72, 0x6B, + 0x65, 0x7A, 0x69, 0x20, 0x2D, 0x20, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, + 0x4D, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, + 0x54, 0x55, 0x42, 0x49, 0x54, 0x41, 0x4B, 0x20, 0x4B, 0x61, 0x6D, 0x75, + 0x20, 0x53, 0x4D, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x4B, 0x6F, 0x6B, 0x20, + 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6B, 0x61, 0x73, 0x69, 0x20, + 0x2D, 0x20, 0x53, 0x75, 0x72, 0x75, 0x6D, 0x20, 0x31 +}; + +static const unsigned char TA49_RSA_N[] = { + 0xAF, 0x75, 0x30, 0x33, 0xAA, 0xBB, 0x6B, 0xD3, 0x99, 0x2C, 0x12, 0x37, + 0x84, 0xD9, 0x8D, 0x7B, 0x97, 0x80, 0xD3, 0x6E, 0xE7, 0xFF, 0x9B, 0x50, + 0x95, 0x3E, 0x90, 0x95, 0x56, 0x42, 0xD7, 0x19, 0x7C, 0x26, 0x84, 0x8D, + 0x92, 0xFA, 0x01, 0x1D, 0x3A, 0x0F, 0xE2, 0x64, 0x38, 0xB7, 0x8C, 0xBC, + 0xE8, 0x88, 0xF9, 0x8B, 0x24, 0xAB, 0x2E, 0xA3, 0xF5, 0x37, 0xE4, 0x40, + 0x8E, 0x18, 0x25, 0x79, 0x83, 0x75, 0x1F, 0x3B, 0xFF, 0x6C, 0xA8, 0xC5, + 0xC6, 0x56, 0xF8, 0xB4, 0xED, 0x8A, 0x44, 0xA3, 0xAB, 0x6C, 0x4C, 0xFC, + 0x1D, 0xD0, 0xDC, 0xEF, 0x68, 0xBD, 0xCF, 0xE4, 0xAA, 0xCE, 0xF0, 0x55, + 0xF7, 0xA2, 0x34, 0xD4, 0x83, 0x6B, 0x37, 0x7C, 0x1C, 0xC2, 0xFE, 0xB5, + 0x03, 0xEC, 0x57, 0xCE, 0xBC, 0xB4, 0xB5, 0xC5, 0xED, 0x00, 0x0F, 0x53, + 0x37, 0x2A, 0x4D, 0xF4, 0x4F, 0x0C, 0x83, 0xFB, 0x86, 0xCF, 0xCB, 0xFE, + 0x8C, 0x4E, 0xBD, 0x87, 0xF9, 0xA7, 0x8B, 0x21, 0x57, 0x9C, 0x7A, 0xDF, + 0x03, 0x67, 0x89, 0x2C, 0x9D, 0x97, 0x61, 0xA7, 0x10, 0xB8, 0x55, 0x90, + 0x7F, 0x0E, 0x2D, 0x27, 0x38, 0x74, 0xDF, 0xE7, 0xFD, 0xDA, 0x4E, 0x12, + 0xE3, 0x4D, 0x15, 0x22, 0x02, 0xC8, 0xE0, 0xE0, 0xFC, 0x0F, 0xAD, 0x8A, + 0xD7, 0xC9, 0x54, 0x50, 0xCC, 0x3B, 0x0F, 0xCA, 0x16, 0x80, 0x84, 0xD0, + 0x51, 0x56, 0xC3, 0x8E, 0x56, 0x7F, 0x89, 0x22, 0x33, 0x2F, 0xE6, 0x85, + 0x0A, 0xBD, 0xA5, 0xA8, 0x1B, 0x36, 0xDE, 0xD3, 0xDC, 0x2C, 0x6D, 0x3B, + 0xC7, 0x13, 0xBD, 0x59, 0x23, 0x2C, 0xE6, 0xE5, 0xA4, 0xF7, 0xD8, 0x0B, + 0xED, 0xEA, 0x90, 0x40, 0x44, 0xA8, 0x95, 0xBB, 0x93, 0xD5, 0xD0, 0x80, + 0x34, 0xB6, 0x46, 0x78, 0x0E, 0x1F, 0x00, 0x93, 0x46, 0xE1, 0xEE, 0xE9, + 0xF9, 0xEC, 0x4F, 0x17 +}; + +static const unsigned char TA49_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA50_DN[] = { + 0x30, 0x81, 0xA6, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x40, 0x30, 0x3E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x37, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, + 0x35 +}; + +static const unsigned char TA50_RSA_N[] = { + 0xC2, 0xF8, 0xA9, 0x3F, 0x1B, 0x89, 0xFC, 0x3C, 0x3C, 0x04, 0x5D, 0x3D, + 0x90, 0x36, 0xB0, 0x91, 0x3A, 0x79, 0x3C, 0x66, 0x5A, 0xEF, 0x6D, 0x39, + 0x01, 0x49, 0x1A, 0xB4, 0xB7, 0xCF, 0x7F, 0x4D, 0x23, 0x53, 0xB7, 0x90, + 0x00, 0xE3, 0x13, 0x2A, 0x28, 0xA6, 0x31, 0xF1, 0x91, 0x00, 0xE3, 0x28, + 0xEC, 0xAE, 0x21, 0x41, 0xCE, 0x1F, 0xDA, 0xFD, 0x7D, 0x12, 0x5B, 0x01, + 0x83, 0x0F, 0xB9, 0xB0, 0x5F, 0x99, 0xE1, 0xF2, 0x12, 0x83, 0x80, 0x4D, + 0x06, 0x3E, 0xDF, 0xAC, 0xAF, 0xE7, 0xA1, 0x88, 0x6B, 0x31, 0xAF, 0xF0, + 0x8B, 0xD0, 0x18, 0x33, 0xB8, 0xDB, 0x45, 0x6A, 0x34, 0xF4, 0x02, 0x80, + 0x24, 0x28, 0x0A, 0x02, 0x15, 0x95, 0x5E, 0x76, 0x2A, 0x0D, 0x99, 0x3A, + 0x14, 0x5B, 0xF6, 0xCB, 0xCB, 0x53, 0xBC, 0x13, 0x4D, 0x01, 0x88, 0x37, + 0x94, 0x25, 0x1B, 0x42, 0xBC, 0x22, 0xD8, 0x8E, 0xA3, 0x96, 0x5E, 0x3A, + 0xD9, 0x32, 0xDB, 0x3E, 0xE8, 0xF0, 0x10, 0x65, 0xED, 0x74, 0xE1, 0x2F, + 0xA7, 0x7C, 0xAF, 0x27, 0x34, 0xBB, 0x29, 0x7D, 0x9B, 0xB6, 0xCF, 0x09, + 0xC8, 0xE5, 0xD3, 0x0A, 0xFC, 0x88, 0x65, 0x65, 0x74, 0x0A, 0xDC, 0x73, + 0x1C, 0x5C, 0xCD, 0x40, 0xB1, 0x1C, 0xD4, 0xB6, 0x84, 0x8C, 0x4C, 0x50, + 0xCF, 0x68, 0x8E, 0xA8, 0x59, 0xAE, 0xC2, 0x27, 0x4E, 0x82, 0xA2, 0x35, + 0xDD, 0x14, 0xF4, 0x1F, 0xFF, 0xB2, 0x77, 0xD5, 0x87, 0x2F, 0xAA, 0x6E, + 0x7D, 0x24, 0x27, 0xE7, 0xC6, 0xCB, 0x26, 0xE6, 0xE5, 0xFE, 0x67, 0x07, + 0x63, 0xD8, 0x45, 0x0D, 0xDD, 0x3A, 0x59, 0x65, 0x39, 0x58, 0x7A, 0x92, + 0x99, 0x72, 0x3D, 0x9C, 0x84, 0x5E, 0x88, 0x21, 0xB8, 0xD5, 0xF4, 0x2C, + 0xFC, 0xD9, 0x70, 0x52, 0x4F, 0x78, 0xB8, 0xBD, 0x3C, 0x2B, 0x8B, 0x95, + 0x98, 0xF5, 0xB3, 0xD1, 0x68, 0xCF, 0x20, 0x14, 0x7E, 0x4C, 0x5C, 0x5F, + 0xE7, 0x8B, 0xE5, 0xF5, 0x35, 0x81, 0x19, 0x37, 0xD7, 0x11, 0x08, 0xB7, + 0x66, 0xBE, 0xD3, 0x4A, 0xCE, 0x83, 0x57, 0x00, 0x3A, 0xC3, 0x81, 0xF8, + 0x17, 0xCB, 0x92, 0x36, 0x5D, 0xD1, 0xA3, 0xD8, 0x75, 0x1B, 0xE1, 0x8B, + 0x27, 0xEA, 0x7A, 0x48, 0x41, 0xFD, 0x45, 0x19, 0x06, 0xAD, 0x27, 0x99, + 0x4E, 0xC1, 0x70, 0x47, 0xDD, 0xB5, 0x9F, 0x81, 0x53, 0x12, 0xE5, 0xB1, + 0x8C, 0x48, 0x5D, 0x31, 0x43, 0x17, 0xE3, 0x8C, 0xC6, 0x7A, 0x63, 0x96, + 0x4B, 0x29, 0x30, 0x4E, 0x84, 0x4E, 0x62, 0x19, 0x5E, 0x3C, 0xCE, 0x97, + 0x90, 0xA5, 0x7F, 0x01, 0xEB, 0x9D, 0xE0, 0xF8, 0x8B, 0x89, 0xDD, 0x25, + 0x98, 0x3D, 0x92, 0xB6, 0x7E, 0xEF, 0xD9, 0xF1, 0x51, 0x51, 0x7D, 0x2D, + 0x26, 0xC8, 0x69, 0x59, 0x61, 0xE0, 0xAC, 0x6A, 0xB8, 0x2A, 0x36, 0x11, + 0x04, 0x7A, 0x50, 0xBD, 0x32, 0x84, 0xBE, 0x2F, 0xDC, 0x72, 0xD5, 0xD7, + 0x1D, 0x16, 0x47, 0xE4, 0x47, 0x66, 0x20, 0x3F, 0xF4, 0x96, 0xC5, 0xAF, + 0x8E, 0x01, 0x7A, 0xA5, 0x0F, 0x7A, 0x64, 0xF5, 0x0D, 0x18, 0x87, 0xD9, + 0xAE, 0x88, 0xD5, 0xFA, 0x84, 0xC1, 0x3A, 0xC0, 0x69, 0x28, 0x2D, 0xF2, + 0x0D, 0x68, 0x51, 0xAA, 0xE3, 0xA5, 0x77, 0xC6, 0xA4, 0x90, 0x0E, 0xA1, + 0x37, 0x8B, 0x31, 0x23, 0x47, 0xC1, 0x09, 0x08, 0xEB, 0x6E, 0xF7, 0x78, + 0x9B, 0xD7, 0x82, 0xFC, 0x84, 0x20, 0x99, 0x49, 0x19, 0xB6, 0x12, 0x46, + 0xB1, 0xFB, 0x45, 0x55, 0x16, 0xA9, 0xA3, 0x65, 0xAC, 0x9C, 0x07, 0x0F, + 0xEA, 0x6B, 0xDC, 0x1F, 0x2E, 0x06, 0x72, 0xEC, 0x86, 0x88, 0x12, 0xE4, + 0x2D, 0xDB, 0x5F, 0x05, 0x2F, 0xE4, 0xF0, 0x03, 0xD3, 0x26, 0x33, 0xE7, + 0x80, 0xC2, 0xCD, 0x42, 0xA1, 0x17, 0x34, 0x0B +}; + +static const unsigned char TA50_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA51_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x52, 0x53, 0x41 +}; + +static const unsigned char TA51_RSA_N[] = { + 0xF9, 0x0F, 0xDD, 0xA3, 0x2B, 0x7D, 0xCB, 0xD0, 0x2A, 0xFE, 0xEC, 0x67, + 0x85, 0xA6, 0xE7, 0x2E, 0x1B, 0xBA, 0x77, 0xE1, 0xE3, 0xF5, 0xAF, 0xA4, + 0xEC, 0xFA, 0x4A, 0x5D, 0x91, 0xC4, 0x57, 0x47, 0x6B, 0x18, 0x77, 0x6B, + 0x76, 0xF2, 0xFD, 0x93, 0xE4, 0x3D, 0x0F, 0xC2, 0x16, 0x9E, 0x0B, 0x66, + 0xC3, 0x56, 0x94, 0x9E, 0x17, 0x83, 0x85, 0xCE, 0x56, 0xEF, 0xF2, 0x16, + 0xFD, 0x00, 0x62, 0xF5, 0x22, 0x09, 0x54, 0xE8, 0x65, 0x17, 0x4E, 0x41, + 0xB9, 0xE0, 0x4F, 0x46, 0x97, 0xAA, 0x1B, 0xC8, 0xB8, 0x6E, 0x62, 0x5E, + 0x69, 0xB1, 0x5F, 0xDB, 0x2A, 0x02, 0x7E, 0xFC, 0x6C, 0xCA, 0xF3, 0x41, + 0xD8, 0xED, 0xD0, 0xE8, 0xFC, 0x3F, 0x61, 0x48, 0xED, 0xB0, 0x03, 0x14, + 0x1D, 0x10, 0x0E, 0x4B, 0x19, 0xE0, 0xBB, 0x4E, 0xEC, 0x86, 0x65, 0xFF, + 0x36, 0xF3, 0x5E, 0x67, 0x02, 0x0B, 0x9D, 0x86, 0x55, 0x61, 0xFD, 0x7A, + 0x38, 0xED, 0xFE, 0xE2, 0x19, 0x00, 0xB7, 0x6F, 0xA1, 0x50, 0x62, 0x75, + 0x74, 0x3C, 0xA0, 0xFA, 0xC8, 0x25, 0x92, 0xB4, 0x6E, 0x7A, 0x22, 0xC7, + 0xF8, 0x1E, 0xA1, 0xE3, 0xB2, 0xDD, 0x91, 0x31, 0xAB, 0x2B, 0x1D, 0x04, + 0xFF, 0xA5, 0x4A, 0x04, 0x37, 0xE9, 0x85, 0xA4, 0x33, 0x2B, 0xFD, 0xE2, + 0xD6, 0x55, 0x34, 0x7C, 0x19, 0xA4, 0x4A, 0x68, 0xC7, 0xB2, 0xA8, 0xD3, + 0xB7, 0xCA, 0xA1, 0x93, 0x88, 0xEB, 0xC1, 0x97, 0xBC, 0x8C, 0xF9, 0x1D, + 0xD9, 0x22, 0x84, 0x24, 0x74, 0xC7, 0x04, 0x3D, 0x6A, 0xA9, 0x29, 0x93, + 0xCC, 0xEB, 0xB8, 0x5B, 0xE1, 0xFE, 0x5F, 0x25, 0xAA, 0x34, 0x58, 0xC8, + 0xC1, 0x23, 0x54, 0x9D, 0x1B, 0x98, 0x11, 0xC3, 0x38, 0x9C, 0x7E, 0x3D, + 0x86, 0x6C, 0xA5, 0x0F, 0x40, 0x86, 0x7C, 0x02, 0xF4, 0x5C, 0x02, 0x4F, + 0x28, 0xCB, 0xAE, 0x71, 0x9F, 0x0F, 0x3A, 0xC8, 0x33, 0xFE, 0x11, 0x25, + 0x35, 0xEA, 0xFC, 0xBA, 0xC5, 0x60, 0x3D, 0xD9, 0x7C, 0x18, 0xD5, 0xB2, + 0xA9, 0xD3, 0x75, 0x78, 0x03, 0x72, 0x22, 0xCA, 0x3A, 0xC3, 0x1F, 0xEF, + 0x2C, 0xE5, 0x2E, 0xA9, 0xFA, 0x9E, 0x2C, 0xB6, 0x51, 0x46, 0xFD, 0xAF, + 0x03, 0xD6, 0xEA, 0x60, 0x68, 0xEA, 0x85, 0x16, 0x36, 0x6B, 0x85, 0xE9, + 0x1E, 0xC0, 0xB3, 0xDD, 0xC4, 0x24, 0xDC, 0x80, 0x2A, 0x81, 0x41, 0x6D, + 0x94, 0x3E, 0xC8, 0xE0, 0xC9, 0x81, 0x41, 0x00, 0x9E, 0x5E, 0xBF, 0x7F, + 0xC5, 0x08, 0x98, 0xA2, 0x18, 0x2C, 0x42, 0x40, 0xB3, 0xF9, 0x6F, 0x38, + 0x27, 0x4B, 0x4E, 0x80, 0xF4, 0x3D, 0x81, 0x47, 0xE0, 0x88, 0x7C, 0xEA, + 0x1C, 0xCE, 0xB5, 0x75, 0x5C, 0x51, 0x2E, 0x1C, 0x2B, 0x7F, 0x1A, 0x72, + 0x28, 0xE7, 0x00, 0xB5, 0xD1, 0x74, 0xC6, 0xD7, 0xE4, 0x9F, 0xAD, 0x07, + 0x93, 0xB6, 0x53, 0x35, 0x35, 0xFC, 0x37, 0xE4, 0xC3, 0xF6, 0x5D, 0x16, + 0xBE, 0x21, 0x73, 0xDE, 0x92, 0x0A, 0xF8, 0xA0, 0x63, 0x6A, 0xBC, 0x96, + 0x92, 0x6A, 0x3E, 0xF8, 0xBC, 0x65, 0x55, 0x9B, 0xDE, 0xF5, 0x0D, 0x89, + 0x26, 0x04, 0xFC, 0x25, 0x1A, 0xA6, 0x25, 0x69, 0xCB, 0xC2, 0x6D, 0xCA, + 0x7C, 0xE2, 0x59, 0x5F, 0x97, 0xAC, 0xEB, 0xEF, 0x2E, 0xC8, 0xBC, 0xD7, + 0x1B, 0x59, 0x3C, 0x2B, 0xCC, 0xF2, 0x19, 0xC8, 0x93, 0x6B, 0x27, 0x63, + 0x19, 0xCF, 0xFC, 0xE9, 0x26, 0xF8, 0xCA, 0x71, 0x9B, 0x7F, 0x93, 0xFE, + 0x34, 0x67, 0x84, 0x4E, 0x99, 0xEB, 0xFC, 0xB3, 0x78, 0x09, 0x33, 0x70, + 0xBA, 0x66, 0xA6, 0x76, 0xED, 0x1B, 0x73, 0xEB, 0x1A, 0xA5, 0x0D, 0xC4, + 0x22, 0x13, 0x20, 0x94, 0x56, 0x0A, 0x4E, 0x2C, 0x6C, 0x4E, 0xB1, 0xFD, + 0xCF, 0x9C, 0x09, 0xBA, 0xA2, 0x33, 0xED, 0x87 +}; + +static const unsigned char TA51_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA52_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA52_EC_Q[] = { + 0x04, 0x78, 0x30, 0x81, 0xE8, 0x63, 0x1E, 0xE5, 0xEB, 0x71, 0x51, 0x0F, + 0xF7, 0x07, 0x07, 0xCA, 0x39, 0x99, 0x7C, 0x4E, 0xD5, 0x0F, 0xCC, 0x30, + 0x30, 0x0B, 0x8F, 0x66, 0x93, 0x3E, 0xCF, 0xBD, 0xC5, 0x86, 0xBD, 0xF9, + 0xB1, 0xB7, 0xB4, 0x3E, 0xB4, 0x07, 0xC8, 0xF3, 0x96, 0x31, 0xF3, 0xED, + 0xA4, 0x4F, 0xF8, 0xA3, 0x4E, 0x8D, 0x29, 0x15, 0x58, 0xB8, 0xD5, 0x6F, + 0x7F, 0xEE, 0x6C, 0x22, 0xB5, 0xB0, 0xAF, 0x48, 0x45, 0x0A, 0xBD, 0xA8, + 0x49, 0x94, 0xBF, 0x84, 0x43, 0xB0, 0xDB, 0x84, 0x4A, 0x03, 0x23, 0x19, + 0x67, 0x6A, 0x6F, 0xC1, 0x6E, 0xBC, 0x06, 0x39, 0x37, 0xD1, 0x88, 0x22, + 0xF7 +}; + +static const unsigned char TA53_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA53_RSA_N[] = { + 0x80, 0x12, 0x65, 0x17, 0x36, 0x0E, 0xC3, 0xDB, 0x08, 0xB3, 0xD0, 0xAC, + 0x57, 0x0D, 0x76, 0xED, 0xCD, 0x27, 0xD3, 0x4C, 0xAD, 0x50, 0x83, 0x61, + 0xE2, 0xAA, 0x20, 0x4D, 0x09, 0x2D, 0x64, 0x09, 0xDC, 0xCE, 0x89, 0x9F, + 0xCC, 0x3D, 0xA9, 0xEC, 0xF6, 0xCF, 0xC1, 0xDC, 0xF1, 0xD3, 0xB1, 0xD6, + 0x7B, 0x37, 0x28, 0x11, 0x2B, 0x47, 0xDA, 0x39, 0xC6, 0xBC, 0x3A, 0x19, + 0xB4, 0x5F, 0xA6, 0xBD, 0x7D, 0x9D, 0xA3, 0x63, 0x42, 0xB6, 0x76, 0xF2, + 0xA9, 0x3B, 0x2B, 0x91, 0xF8, 0xE2, 0x6F, 0xD0, 0xEC, 0x16, 0x20, 0x90, + 0x09, 0x3E, 0xE2, 0xE8, 0x74, 0xC9, 0x18, 0xB4, 0x91, 0xD4, 0x62, 0x64, + 0xDB, 0x7F, 0xA3, 0x06, 0xF1, 0x88, 0x18, 0x6A, 0x90, 0x22, 0x3C, 0xBC, + 0xFE, 0x13, 0xF0, 0x87, 0x14, 0x7B, 0xF6, 0xE4, 0x1F, 0x8E, 0xD4, 0xE4, + 0x51, 0xC6, 0x11, 0x67, 0x46, 0x08, 0x51, 0xCB, 0x86, 0x14, 0x54, 0x3F, + 0xBC, 0x33, 0xFE, 0x7E, 0x6C, 0x9C, 0xFF, 0x16, 0x9D, 0x18, 0xBD, 0x51, + 0x8E, 0x35, 0xA6, 0xA7, 0x66, 0xC8, 0x72, 0x67, 0xDB, 0x21, 0x66, 0xB1, + 0xD4, 0x9B, 0x78, 0x03, 0xC0, 0x50, 0x3A, 0xE8, 0xCC, 0xF0, 0xDC, 0xBC, + 0x9E, 0x4C, 0xFE, 0xAF, 0x05, 0x96, 0x35, 0x1F, 0x57, 0x5A, 0xB7, 0xFF, + 0xCE, 0xF9, 0x3D, 0xB7, 0x2C, 0xB6, 0xF6, 0x54, 0xDD, 0xC8, 0xE7, 0x12, + 0x3A, 0x4D, 0xAE, 0x4C, 0x8A, 0xB7, 0x5C, 0x9A, 0xB4, 0xB7, 0x20, 0x3D, + 0xCA, 0x7F, 0x22, 0x34, 0xAE, 0x7E, 0x3B, 0x68, 0x66, 0x01, 0x44, 0xE7, + 0x01, 0x4E, 0x46, 0x53, 0x9B, 0x33, 0x60, 0xF7, 0x94, 0xBE, 0x53, 0x37, + 0x90, 0x73, 0x43, 0xF3, 0x32, 0xC3, 0x53, 0xEF, 0xDB, 0xAA, 0xFE, 0x74, + 0x4E, 0x69, 0xC7, 0x6B, 0x8C, 0x60, 0x93, 0xDE, 0xC4, 0xC7, 0x0C, 0xDF, + 0xE1, 0x32, 0xAE, 0xCC, 0x93, 0x3B, 0x51, 0x78, 0x95, 0x67, 0x8B, 0xEE, + 0x3D, 0x56, 0xFE, 0x0C, 0xD0, 0x69, 0x0F, 0x1B, 0x0F, 0xF3, 0x25, 0x26, + 0x6B, 0x33, 0x6D, 0xF7, 0x6E, 0x47, 0xFA, 0x73, 0x43, 0xE5, 0x7E, 0x0E, + 0xA5, 0x66, 0xB1, 0x29, 0x7C, 0x32, 0x84, 0x63, 0x55, 0x89, 0xC4, 0x0D, + 0xC1, 0x93, 0x54, 0x30, 0x19, 0x13, 0xAC, 0xD3, 0x7D, 0x37, 0xA7, 0xEB, + 0x5D, 0x3A, 0x6C, 0x35, 0x5C, 0xDB, 0x41, 0xD7, 0x12, 0xDA, 0xA9, 0x49, + 0x0B, 0xDF, 0xD8, 0x80, 0x8A, 0x09, 0x93, 0x62, 0x8E, 0xB5, 0x66, 0xCF, + 0x25, 0x88, 0xCD, 0x84, 0xB8, 0xB1, 0x3F, 0xA4, 0x39, 0x0F, 0xD9, 0x02, + 0x9E, 0xEB, 0x12, 0x4C, 0x95, 0x7C, 0xF3, 0x6B, 0x05, 0xA9, 0x5E, 0x16, + 0x83, 0xCC, 0xB8, 0x67, 0xE2, 0xE8, 0x13, 0x9D, 0xCC, 0x5B, 0x82, 0xD3, + 0x4C, 0xB3, 0xED, 0x5B, 0xFF, 0xDE, 0xE5, 0x73, 0xAC, 0x23, 0x3B, 0x2D, + 0x00, 0xBF, 0x35, 0x55, 0x74, 0x09, 0x49, 0xD8, 0x49, 0x58, 0x1A, 0x7F, + 0x92, 0x36, 0xE6, 0x51, 0x92, 0x0E, 0xF3, 0x26, 0x7D, 0x1C, 0x4D, 0x17, + 0xBC, 0xC9, 0xEC, 0x43, 0x26, 0xD0, 0xBF, 0x41, 0x5F, 0x40, 0xA9, 0x44, + 0x44, 0xF4, 0x99, 0xE7, 0x57, 0x87, 0x9E, 0x50, 0x1F, 0x57, 0x54, 0xA8, + 0x3E, 0xFD, 0x74, 0x63, 0x2F, 0xB1, 0x50, 0x65, 0x09, 0xE6, 0x58, 0x42, + 0x2E, 0x43, 0x1A, 0x4C, 0xB4, 0xF0, 0x25, 0x47, 0x59, 0xFA, 0x04, 0x1E, + 0x93, 0xD4, 0x26, 0x46, 0x4A, 0x50, 0x81, 0xB2, 0xDE, 0xBE, 0x78, 0xB7, + 0xFC, 0x67, 0x15, 0xE1, 0xC9, 0x57, 0x84, 0x1E, 0x0F, 0x63, 0xD6, 0xE9, + 0x62, 0xBA, 0xD6, 0x5F, 0x55, 0x2E, 0xEA, 0x5C, 0xC6, 0x28, 0x08, 0x04, + 0x25, 0x39, 0xB8, 0x0E, 0x2B, 0xA9, 0xF2, 0x4C, 0x97, 0x1C, 0x07, 0x3F, + 0x0D, 0x52, 0xF5, 0xED, 0xEF, 0x2F, 0x82, 0x0F +}; + +static const unsigned char TA53_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA54_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA54_RSA_N[] = { + 0xE2, 0x3B, 0xE1, 0x11, 0x72, 0xDE, 0xA8, 0xA4, 0xD3, 0xA3, 0x57, 0xAA, + 0x50, 0xA2, 0x8F, 0x0B, 0x77, 0x90, 0xC9, 0xA2, 0xA5, 0xEE, 0x12, 0xCE, + 0x96, 0x5B, 0x01, 0x09, 0x20, 0xCC, 0x01, 0x93, 0xA7, 0x4E, 0x30, 0xB7, + 0x53, 0xF7, 0x43, 0xC4, 0x69, 0x00, 0x57, 0x9D, 0xE2, 0x8D, 0x22, 0xDD, + 0x87, 0x06, 0x40, 0x00, 0x81, 0x09, 0xCE, 0xCE, 0x1B, 0x83, 0xBF, 0xDF, + 0xCD, 0x3B, 0x71, 0x46, 0xE2, 0xD6, 0x66, 0xC7, 0x05, 0xB3, 0x76, 0x27, + 0x16, 0x8F, 0x7B, 0x9E, 0x1E, 0x95, 0x7D, 0xEE, 0xB7, 0x48, 0xA3, 0x08, + 0xDA, 0xD6, 0xAF, 0x7A, 0x0C, 0x39, 0x06, 0x65, 0x7F, 0x4A, 0x5D, 0x1F, + 0xBC, 0x17, 0xF8, 0xAB, 0xBE, 0xEE, 0x28, 0xD7, 0x74, 0x7F, 0x7A, 0x78, + 0x99, 0x59, 0x85, 0x68, 0x6E, 0x5C, 0x23, 0x32, 0x4B, 0xBF, 0x4E, 0xC0, + 0xE8, 0x5A, 0x6D, 0xE3, 0x70, 0xBF, 0x77, 0x10, 0xBF, 0xFC, 0x01, 0xF6, + 0x85, 0xD9, 0xA8, 0x44, 0x10, 0x58, 0x32, 0xA9, 0x75, 0x18, 0xD5, 0xD1, + 0xA2, 0xBE, 0x47, 0xE2, 0x27, 0x6A, 0xF4, 0x9A, 0x33, 0xF8, 0x49, 0x08, + 0x60, 0x8B, 0xD4, 0x5F, 0xB4, 0x3A, 0x84, 0xBF, 0xA1, 0xAA, 0x4A, 0x4C, + 0x7D, 0x3E, 0xCF, 0x4F, 0x5F, 0x6C, 0x76, 0x5E, 0xA0, 0x4B, 0x37, 0x91, + 0x9E, 0xDC, 0x22, 0xE6, 0x6D, 0xCE, 0x14, 0x1A, 0x8E, 0x6A, 0xCB, 0xFE, + 0xCD, 0xB3, 0x14, 0x64, 0x17, 0xC7, 0x5B, 0x29, 0x9E, 0x32, 0xBF, 0xF2, + 0xEE, 0xFA, 0xD3, 0x0B, 0x42, 0xD4, 0xAB, 0xB7, 0x41, 0x32, 0xDA, 0x0C, + 0xD4, 0xEF, 0xF8, 0x81, 0xD5, 0xBB, 0x8D, 0x58, 0x3F, 0xB5, 0x1B, 0xE8, + 0x49, 0x28, 0xA2, 0x70, 0xDA, 0x31, 0x04, 0xDD, 0xF7, 0xB2, 0x16, 0xF2, + 0x4C, 0x0A, 0x4E, 0x07, 0xA8, 0xED, 0x4A, 0x3D, 0x5E, 0xB5, 0x7F, 0xA3, + 0x90, 0xC3, 0xAF, 0x27 +}; + +static const unsigned char TA54_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA55_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA55_RSA_N[] = { + 0xE2, 0x3B, 0xE1, 0x11, 0x72, 0xDE, 0xA8, 0xA4, 0xD3, 0xA3, 0x57, 0xAA, + 0x50, 0xA2, 0x8F, 0x0B, 0x77, 0x90, 0xC9, 0xA2, 0xA5, 0xEE, 0x12, 0xCE, + 0x96, 0x5B, 0x01, 0x09, 0x20, 0xCC, 0x01, 0x93, 0xA7, 0x4E, 0x30, 0xB7, + 0x53, 0xF7, 0x43, 0xC4, 0x69, 0x00, 0x57, 0x9D, 0xE2, 0x8D, 0x22, 0xDD, + 0x87, 0x06, 0x40, 0x00, 0x81, 0x09, 0xCE, 0xCE, 0x1B, 0x83, 0xBF, 0xDF, + 0xCD, 0x3B, 0x71, 0x46, 0xE2, 0xD6, 0x66, 0xC7, 0x05, 0xB3, 0x76, 0x27, + 0x16, 0x8F, 0x7B, 0x9E, 0x1E, 0x95, 0x7D, 0xEE, 0xB7, 0x48, 0xA3, 0x08, + 0xDA, 0xD6, 0xAF, 0x7A, 0x0C, 0x39, 0x06, 0x65, 0x7F, 0x4A, 0x5D, 0x1F, + 0xBC, 0x17, 0xF8, 0xAB, 0xBE, 0xEE, 0x28, 0xD7, 0x74, 0x7F, 0x7A, 0x78, + 0x99, 0x59, 0x85, 0x68, 0x6E, 0x5C, 0x23, 0x32, 0x4B, 0xBF, 0x4E, 0xC0, + 0xE8, 0x5A, 0x6D, 0xE3, 0x70, 0xBF, 0x77, 0x10, 0xBF, 0xFC, 0x01, 0xF6, + 0x85, 0xD9, 0xA8, 0x44, 0x10, 0x58, 0x32, 0xA9, 0x75, 0x18, 0xD5, 0xD1, + 0xA2, 0xBE, 0x47, 0xE2, 0x27, 0x6A, 0xF4, 0x9A, 0x33, 0xF8, 0x49, 0x08, + 0x60, 0x8B, 0xD4, 0x5F, 0xB4, 0x3A, 0x84, 0xBF, 0xA1, 0xAA, 0x4A, 0x4C, + 0x7D, 0x3E, 0xCF, 0x4F, 0x5F, 0x6C, 0x76, 0x5E, 0xA0, 0x4B, 0x37, 0x91, + 0x9E, 0xDC, 0x22, 0xE6, 0x6D, 0xCE, 0x14, 0x1A, 0x8E, 0x6A, 0xCB, 0xFE, + 0xCD, 0xB3, 0x14, 0x64, 0x17, 0xC7, 0x5B, 0x29, 0x9E, 0x32, 0xBF, 0xF2, + 0xEE, 0xFA, 0xD3, 0x0B, 0x42, 0xD4, 0xAB, 0xB7, 0x41, 0x32, 0xDA, 0x0C, + 0xD4, 0xEF, 0xF8, 0x81, 0xD5, 0xBB, 0x8D, 0x58, 0x3F, 0xB5, 0x1B, 0xE8, + 0x49, 0x28, 0xA2, 0x70, 0xDA, 0x31, 0x04, 0xDD, 0xF7, 0xB2, 0x16, 0xF2, + 0x4C, 0x0A, 0x4E, 0x07, 0xA8, 0xED, 0x4A, 0x3D, 0x5E, 0xB5, 0x7F, 0xA3, + 0x90, 0xC3, 0xAF, 0x27 +}; + +static const unsigned char TA55_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA56_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x42, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x6F, 0x72, 0x65, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, 0x43, 0x79, + 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6C, 0x74, 0x69, + 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA56_RSA_N[] = { + 0xA3, 0x04, 0xBB, 0x22, 0xAB, 0x98, 0x3D, 0x57, 0xE8, 0x26, 0x72, 0x9A, + 0xB5, 0x79, 0xD4, 0x29, 0xE2, 0xE1, 0xE8, 0x95, 0x80, 0xB1, 0xB0, 0xE3, + 0x5B, 0x8E, 0x2B, 0x29, 0x9A, 0x64, 0xDF, 0xA1, 0x5D, 0xED, 0xB0, 0x09, + 0x05, 0x6D, 0xDB, 0x28, 0x2E, 0xCE, 0x62, 0xA2, 0x62, 0xFE, 0xB4, 0x88, + 0xDA, 0x12, 0xEB, 0x38, 0xEB, 0x21, 0x9D, 0xC0, 0x41, 0x2B, 0x01, 0x52, + 0x7B, 0x88, 0x77, 0xD3, 0x1C, 0x8F, 0xC7, 0xBA, 0xB9, 0x88, 0xB5, 0x6A, + 0x09, 0xE7, 0x73, 0xE8, 0x11, 0x40, 0xA7, 0xD1, 0xCC, 0xCA, 0x62, 0x8D, + 0x2D, 0xE5, 0x8F, 0x0B, 0xA6, 0x50, 0xD2, 0xA8, 0x50, 0xC3, 0x28, 0xEA, + 0xF5, 0xAB, 0x25, 0x87, 0x8A, 0x9A, 0x96, 0x1C, 0xA9, 0x67, 0xB8, 0x3F, + 0x0C, 0xD5, 0xF7, 0xF9, 0x52, 0x13, 0x2F, 0xC2, 0x1B, 0xD5, 0x70, 0x70, + 0xF0, 0x8F, 0xC0, 0x12, 0xCA, 0x06, 0xCB, 0x9A, 0xE1, 0xD9, 0xCA, 0x33, + 0x7A, 0x77, 0xD6, 0xF8, 0xEC, 0xB9, 0xF1, 0x68, 0x44, 0x42, 0x48, 0x13, + 0xD2, 0xC0, 0xC2, 0xA4, 0xAE, 0x5E, 0x60, 0xFE, 0xB6, 0xA6, 0x05, 0xFC, + 0xB4, 0xDD, 0x07, 0x59, 0x02, 0xD4, 0x59, 0x18, 0x98, 0x63, 0xF5, 0xA5, + 0x63, 0xE0, 0x90, 0x0C, 0x7D, 0x5D, 0xB2, 0x06, 0x7A, 0xF3, 0x85, 0xEA, + 0xEB, 0xD4, 0x03, 0xAE, 0x5E, 0x84, 0x3E, 0x5F, 0xFF, 0x15, 0xED, 0x69, + 0xBC, 0xF9, 0x39, 0x36, 0x72, 0x75, 0xCF, 0x77, 0x52, 0x4D, 0xF3, 0xC9, + 0x90, 0x2C, 0xB9, 0x3D, 0xE5, 0xC9, 0x23, 0x53, 0x3F, 0x1F, 0x24, 0x98, + 0x21, 0x5C, 0x07, 0x99, 0x29, 0xBD, 0xC6, 0x3A, 0xEC, 0xE7, 0x6E, 0x86, + 0x3A, 0x6B, 0x97, 0x74, 0x63, 0x33, 0xBD, 0x68, 0x18, 0x31, 0xF0, 0x78, + 0x8D, 0x76, 0xBF, 0xFC, 0x9E, 0x8E, 0x5D, 0x2A, 0x86, 0xA7, 0x4D, 0x90, + 0xDC, 0x27, 0x1A, 0x39 +}; + +static const unsigned char TA56_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA57_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, + 0x36 +}; + +static const unsigned char TA57_EC_Q[] = { + 0x04, 0x76, 0xFA, 0x99, 0xA9, 0x6E, 0x20, 0xED, 0xF9, 0xD7, 0x77, 0xE3, + 0x07, 0x3B, 0xA8, 0xDB, 0x3D, 0x5F, 0x38, 0xE8, 0xAB, 0x55, 0xA6, 0x56, + 0x4F, 0xD6, 0x48, 0xEA, 0xEC, 0x7F, 0x2D, 0xAA, 0xC3, 0xB2, 0xC5, 0x79, + 0xEC, 0x99, 0x61, 0x7F, 0x10, 0x79, 0xC7, 0x02, 0x5A, 0xF9, 0x04, 0x37, + 0xF5, 0x34, 0x35, 0x2B, 0x77, 0xCE, 0x7F, 0x20, 0x8F, 0x52, 0xA3, 0x00, + 0x89, 0xEC, 0xD5, 0xA7, 0xA2, 0x6D, 0x5B, 0xE3, 0x4B, 0x92, 0x93, 0xA0, + 0x80, 0xF5, 0x01, 0x94, 0xDC, 0xF0, 0x68, 0x07, 0x1E, 0xCD, 0xEE, 0xFE, + 0x25, 0x52, 0xB5, 0x20, 0x43, 0x1C, 0x1B, 0xFE, 0xEB, 0x19, 0xCE, 0x43, + 0xA3 +}; + +static const unsigned char TA58_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x39, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, 0x20, + 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x63, 0x69, 0x6F, 0x6E, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, + 0x6F, 0x66, 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x43, 0x49, + 0x46, 0x20, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38 +}; + +static const unsigned char TA58_RSA_N[] = { + 0xCA, 0x96, 0x6B, 0x8E, 0xEA, 0xF8, 0xFB, 0xF1, 0xA2, 0x35, 0xE0, 0x7F, + 0x4C, 0xDA, 0xE0, 0xC3, 0x52, 0xD7, 0x7D, 0xB6, 0x10, 0xC8, 0x02, 0x5E, + 0xB3, 0x43, 0x2A, 0xC4, 0x4F, 0x6A, 0xB2, 0xCA, 0x1C, 0x5D, 0x28, 0x9A, + 0x78, 0x11, 0x1A, 0x69, 0x59, 0x57, 0xAF, 0xB5, 0x20, 0x42, 0xE4, 0x8B, + 0x0F, 0xE6, 0xDF, 0x5B, 0xA6, 0x03, 0x92, 0x2F, 0xF5, 0x11, 0xE4, 0x62, + 0xD7, 0x32, 0x71, 0x38, 0xD9, 0x04, 0x0C, 0x71, 0xAB, 0x3D, 0x51, 0x7E, + 0x0F, 0x07, 0xDF, 0x63, 0x05, 0x5C, 0xE9, 0xBF, 0x94, 0x6F, 0xC1, 0x29, + 0x82, 0xC0, 0xB4, 0xDA, 0x51, 0xB0, 0xC1, 0x3C, 0xBB, 0xAD, 0x37, 0x4A, + 0x5C, 0xCA, 0xF1, 0x4B, 0x36, 0x0E, 0x24, 0xAB, 0xBF, 0xC3, 0x84, 0x77, + 0xFD, 0xA8, 0x50, 0xF4, 0xB1, 0xE7, 0xC6, 0x2F, 0xD2, 0x2D, 0x59, 0x8D, + 0x7A, 0x0A, 0x4E, 0x96, 0x69, 0x52, 0x02, 0xAA, 0x36, 0x98, 0xEC, 0xFC, + 0xFA, 0x14, 0x83, 0x0C, 0x37, 0x1F, 0xC9, 0x92, 0x37, 0x7F, 0xD7, 0x81, + 0x2D, 0xE5, 0xC4, 0xB9, 0xE0, 0x3E, 0x34, 0xFE, 0x67, 0xF4, 0x3E, 0x66, + 0xD1, 0xD3, 0xF4, 0x40, 0xCF, 0x5E, 0x62, 0x34, 0x0F, 0x70, 0x06, 0x3E, + 0x20, 0x18, 0x5A, 0xCE, 0xF7, 0x72, 0x1B, 0x25, 0x6C, 0x93, 0x74, 0x14, + 0x93, 0xA3, 0x73, 0xB1, 0x0E, 0xAA, 0x87, 0x10, 0x23, 0x59, 0x5F, 0x20, + 0x05, 0x19, 0x47, 0xED, 0x68, 0x8E, 0x92, 0x12, 0xCA, 0x5D, 0xFC, 0xD6, + 0x2B, 0xB2, 0x92, 0x3C, 0x20, 0xCF, 0xE1, 0x5F, 0xAF, 0x20, 0xBE, 0xA0, + 0x76, 0x7F, 0x76, 0xE5, 0xEC, 0x1A, 0x86, 0x61, 0x33, 0x3E, 0xE7, 0x7B, + 0xB4, 0x3F, 0xA0, 0x0F, 0x8E, 0xA2, 0xB9, 0x6A, 0x6F, 0xB9, 0x87, 0x26, + 0x6F, 0x41, 0x6C, 0x88, 0xA6, 0x50, 0xFD, 0x6A, 0x63, 0x0B, 0xF5, 0x93, + 0x16, 0x1B, 0x19, 0x8F, 0xB2, 0xED, 0x9B, 0x9B, 0xC9, 0x90, 0xF5, 0x01, + 0x0C, 0xDF, 0x19, 0x3D, 0x0F, 0x3E, 0x38, 0x23, 0xC9, 0x2F, 0x8F, 0x0C, + 0xD1, 0x02, 0xFE, 0x1B, 0x55, 0xD6, 0x4E, 0xD0, 0x8D, 0x3C, 0xAF, 0x4F, + 0xA4, 0xF3, 0xFE, 0xAF, 0x2A, 0xD3, 0x05, 0x9D, 0x79, 0x08, 0xA1, 0xCB, + 0x57, 0x31, 0xB4, 0x9C, 0xC8, 0x90, 0xB2, 0x67, 0xF4, 0x18, 0x16, 0x93, + 0x3A, 0xFC, 0x47, 0xD8, 0xD1, 0x78, 0x96, 0x31, 0x1F, 0xBA, 0x2B, 0x0C, + 0x5F, 0x5D, 0x99, 0xAD, 0x63, 0x89, 0x5A, 0x24, 0x20, 0x76, 0xD8, 0xDF, + 0xFD, 0xAB, 0x4E, 0xA6, 0x22, 0xAA, 0x9D, 0x5E, 0xE6, 0x27, 0x8A, 0x7D, + 0x68, 0x29, 0xA3, 0xE7, 0x8A, 0xB8, 0xDA, 0x11, 0xBB, 0x17, 0x2D, 0x99, + 0x9D, 0x13, 0x24, 0x46, 0xF7, 0xC5, 0xE2, 0xD8, 0x9F, 0x8E, 0x7F, 0xC7, + 0x8F, 0x74, 0x6D, 0x5A, 0xB2, 0xE8, 0x72, 0xF5, 0xAC, 0xEE, 0x24, 0x10, + 0xAD, 0x2F, 0x14, 0xDA, 0xFF, 0x2D, 0x9A, 0x46, 0x71, 0x47, 0xBE, 0x42, + 0xDF, 0xBB, 0x01, 0xDB, 0xF4, 0x7F, 0xD3, 0x28, 0x8F, 0x31, 0x59, 0x5B, + 0xD3, 0xC9, 0x02, 0xA6, 0xB4, 0x52, 0xCA, 0x6E, 0x97, 0xFB, 0x43, 0xC5, + 0x08, 0x26, 0x6F, 0x8A, 0xF4, 0xBB, 0xFD, 0x9F, 0x28, 0xAA, 0x0D, 0xD5, + 0x45, 0xF3, 0x13, 0x3A, 0x1D, 0xD8, 0xC0, 0x78, 0x8F, 0x41, 0x67, 0x3C, + 0x1E, 0x94, 0x64, 0xAE, 0x7B, 0x0B, 0xC5, 0xE8, 0xD9, 0x01, 0x88, 0x39, + 0x1A, 0x97, 0x86, 0x64, 0x41, 0xD5, 0x3B, 0x87, 0x0C, 0x6E, 0xFA, 0x0F, + 0xC6, 0xBD, 0x48, 0x14, 0xBF, 0x39, 0x4D, 0xD4, 0x9E, 0x41, 0xB6, 0x8F, + 0x96, 0x1D, 0x63, 0x96, 0x93, 0xD9, 0x95, 0x06, 0x78, 0x31, 0x68, 0x9E, + 0x37, 0x06, 0x3B, 0x80, 0x89, 0x45, 0x61, 0x39, 0x23, 0xC7, 0x1B, 0x44, + 0xA3, 0x15, 0xE5, 0x1C, 0xF8, 0x92, 0x30, 0xBB +}; + +static const unsigned char TA58_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA59_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x41, 0x47, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x16, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, + 0x6F, 0x6C, 0x64, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA59_RSA_N[] = { + 0xAF, 0xE4, 0xEE, 0x7E, 0x8B, 0x24, 0x0E, 0x12, 0x6E, 0xA9, 0x50, 0x2D, + 0x16, 0x44, 0x3B, 0x92, 0x92, 0x5C, 0xCA, 0xB8, 0x5D, 0x84, 0x92, 0x42, + 0x13, 0x2A, 0xBC, 0x65, 0x57, 0x82, 0x40, 0x3E, 0x57, 0x24, 0xCD, 0x50, + 0x8B, 0x25, 0x2A, 0xB7, 0x6F, 0xFC, 0xEF, 0xA2, 0xD0, 0xC0, 0x1F, 0x02, + 0x24, 0x4A, 0x13, 0x96, 0x8F, 0x23, 0x13, 0xE6, 0x28, 0x58, 0x00, 0xA3, + 0x47, 0xC7, 0x06, 0xA7, 0x84, 0x23, 0x2B, 0xBB, 0xBD, 0x96, 0x2B, 0x7F, + 0x55, 0xCC, 0x8B, 0xC1, 0x57, 0x1F, 0x0E, 0x62, 0x65, 0x0F, 0xDD, 0x3D, + 0x56, 0x8A, 0x73, 0xDA, 0xAE, 0x7E, 0x6D, 0xBA, 0x81, 0x1C, 0x7E, 0x42, + 0x8C, 0x20, 0x35, 0xD9, 0x43, 0x4D, 0x84, 0xFA, 0x84, 0xDB, 0x52, 0x2C, + 0xF3, 0x0E, 0x27, 0x77, 0x0B, 0x6B, 0xBF, 0x11, 0x2F, 0x72, 0x78, 0x9F, + 0x2E, 0xD8, 0x3E, 0xE6, 0x18, 0x37, 0x5A, 0x2A, 0x72, 0xF9, 0xDA, 0x62, + 0x90, 0x92, 0x95, 0xCA, 0x1F, 0x9C, 0xE9, 0xB3, 0x3C, 0x2B, 0xCB, 0xF3, + 0x01, 0x13, 0xBF, 0x5A, 0xCF, 0xC1, 0xB5, 0x0A, 0x60, 0xBD, 0xDD, 0xB5, + 0x99, 0x64, 0x53, 0xB8, 0xA0, 0x96, 0xB3, 0x6F, 0xE2, 0x26, 0x77, 0x91, + 0x8C, 0xE0, 0x62, 0x10, 0x02, 0x9F, 0x34, 0x0F, 0xA4, 0xD5, 0x92, 0x33, + 0x51, 0xDE, 0xBE, 0x8D, 0xBA, 0x84, 0x7A, 0x60, 0x3C, 0x6A, 0xDB, 0x9F, + 0x2B, 0xEC, 0xDE, 0xDE, 0x01, 0x3F, 0x6E, 0x4D, 0xE5, 0x50, 0x86, 0xCB, + 0xB4, 0xAF, 0xED, 0x44, 0x40, 0xC5, 0xCA, 0x5A, 0x8C, 0xDA, 0xD2, 0x2B, + 0x7C, 0xA8, 0xEE, 0xBE, 0xA6, 0xE5, 0x0A, 0xAA, 0x0E, 0xA5, 0xDF, 0x05, + 0x52, 0xB7, 0x55, 0xC7, 0x22, 0x5D, 0x32, 0x6A, 0x97, 0x97, 0x63, 0x13, + 0xDB, 0xC9, 0xDB, 0x79, 0x36, 0x7B, 0x85, 0x3A, 0x4A, 0xC5, 0x52, 0x89, + 0xF9, 0x24, 0xE7, 0x9D, 0x77, 0xA9, 0x82, 0xFF, 0x55, 0x1C, 0xA5, 0x71, + 0x69, 0x2B, 0xD1, 0x02, 0x24, 0xF2, 0xB3, 0x26, 0xD4, 0x6B, 0xDA, 0x04, + 0x55, 0xE5, 0xC1, 0x0A, 0xC7, 0x6D, 0x30, 0x37, 0x90, 0x2A, 0xE4, 0x9E, + 0x14, 0x33, 0x5E, 0x16, 0x17, 0x55, 0xC5, 0x5B, 0xB5, 0xCB, 0x34, 0x89, + 0x92, 0xF1, 0x9D, 0x26, 0x8F, 0xA1, 0x07, 0xD4, 0xC6, 0xB2, 0x78, 0x50, + 0xDB, 0x0C, 0x0C, 0x0B, 0x7C, 0x0B, 0x8C, 0x41, 0xD7, 0xB9, 0xE9, 0xDD, + 0x8C, 0x88, 0xF7, 0xA3, 0x4D, 0xB2, 0x32, 0xCC, 0xD8, 0x17, 0xDA, 0xCD, + 0xB7, 0xCE, 0x66, 0x9D, 0xD4, 0xFD, 0x5E, 0xFF, 0xBD, 0x97, 0x3E, 0x29, + 0x75, 0xE7, 0x7E, 0xA7, 0x62, 0x58, 0xAF, 0x25, 0x34, 0xA5, 0x41, 0xC7, + 0x3D, 0xBC, 0x0D, 0x50, 0xCA, 0x03, 0x03, 0x0F, 0x08, 0x5A, 0x1F, 0x95, + 0x73, 0x78, 0x62, 0xBF, 0xAF, 0x72, 0x14, 0x69, 0x0E, 0xA5, 0xE5, 0x03, + 0x0E, 0x78, 0x8E, 0x26, 0x28, 0x42, 0xF0, 0x07, 0x0B, 0x62, 0x20, 0x10, + 0x67, 0x39, 0x46, 0xFA, 0xA9, 0x03, 0xCC, 0x04, 0x38, 0x7A, 0x66, 0xEF, + 0x20, 0x83, 0xB5, 0x8C, 0x4A, 0x56, 0x8E, 0x91, 0x00, 0xFC, 0x8E, 0x5C, + 0x82, 0xDE, 0x88, 0xA0, 0xC3, 0xE2, 0x68, 0x6E, 0x7D, 0x8D, 0xEF, 0x3C, + 0xDD, 0x65, 0xF4, 0x5D, 0xAC, 0x51, 0xEF, 0x24, 0x80, 0xAE, 0xAA, 0x56, + 0x97, 0x6F, 0xF9, 0xAD, 0x7D, 0xDA, 0x61, 0x3F, 0x98, 0x77, 0x3C, 0xA5, + 0x91, 0xB6, 0x1C, 0x8C, 0x26, 0xDA, 0x65, 0xA2, 0x09, 0x6D, 0xC1, 0xE2, + 0x54, 0xE3, 0xB9, 0xCA, 0x4C, 0x4C, 0x80, 0x8F, 0x77, 0x7B, 0x60, 0x9A, + 0x1E, 0xDF, 0xB6, 0xF2, 0x48, 0x1E, 0x0E, 0xBA, 0x4E, 0x54, 0x6D, 0x98, + 0xE0, 0xE1, 0xA2, 0x1A, 0xA2, 0x77, 0x50, 0xCF, 0xC4, 0x63, 0x92, 0xEC, + 0x47, 0x19, 0x9D, 0xEB, 0xE6, 0x6B, 0xCE, 0xC1 +}; + +static const unsigned char TA59_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA60_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x43, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA60_EC_Q[] = { + 0x04, 0x4C, 0xE9, 0x50, 0xC0, 0xC6, 0x0F, 0x72, 0x18, 0xBC, 0xD8, 0xF1, + 0xBA, 0xB3, 0x89, 0xE2, 0x79, 0x4A, 0xA3, 0x16, 0xA7, 0x6B, 0x54, 0x24, + 0xDB, 0x51, 0xFF, 0xEA, 0xF4, 0x09, 0x24, 0xC3, 0x0B, 0x22, 0x9F, 0xCB, + 0x6A, 0x27, 0x82, 0x81, 0x0D, 0xD2, 0xC0, 0xAF, 0x31, 0xE4, 0x74, 0x82, + 0x6E, 0xCA, 0x25, 0xD9, 0x8C, 0x75, 0x9D, 0xF1, 0xDB, 0xD0, 0x9A, 0xA2, + 0x4B, 0x21, 0x7E, 0x16, 0xA7, 0x63, 0x90, 0xD2, 0x39, 0xD4, 0xB1, 0x87, + 0x78, 0x5F, 0x18, 0x96, 0x0F, 0x50, 0x1B, 0x35, 0x37, 0x0F, 0x6A, 0xC6, + 0xDC, 0xD9, 0x13, 0x4D, 0xA4, 0x8E, 0x90, 0x37, 0xE6, 0xBD, 0x5B, 0x31, + 0x91 +}; + +static const unsigned char TA61_DN[] = { + 0x30, 0x42, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x09, 0x41, 0x43, 0x43, 0x56, 0x52, 0x41, 0x49, 0x5A, 0x31, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x50, 0x4B, 0x49, + 0x41, 0x43, 0x43, 0x56, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x04, 0x41, 0x43, 0x43, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53 +}; + +static const unsigned char TA61_RSA_N[] = { + 0x9B, 0xA9, 0xAB, 0xBF, 0x61, 0x4A, 0x97, 0xAF, 0x2F, 0x97, 0x66, 0x9A, + 0x74, 0x5F, 0xD0, 0xD9, 0x96, 0xFD, 0xCF, 0xE2, 0xE4, 0x66, 0xEF, 0x1F, + 0x1F, 0x47, 0x33, 0xC2, 0x44, 0xA3, 0xDF, 0x9A, 0xDE, 0x1F, 0xB5, 0x54, + 0xDD, 0x15, 0x7C, 0x69, 0x35, 0x11, 0x6F, 0xBB, 0xC8, 0x0C, 0x8E, 0x6A, + 0x18, 0x1E, 0xD8, 0x8F, 0xD9, 0x16, 0xBC, 0x10, 0x48, 0x36, 0x5C, 0xF0, + 0x63, 0xB3, 0x90, 0x5A, 0x5C, 0x24, 0x37, 0xD7, 0xA3, 0xD6, 0xCB, 0x09, + 0x71, 0xB9, 0xF1, 0x01, 0x72, 0x84, 0xB0, 0x7D, 0xDB, 0x4D, 0x80, 0xCD, + 0xFC, 0xD3, 0x6F, 0xC9, 0xF8, 0xDA, 0xB6, 0x0E, 0x82, 0xD2, 0x45, 0x85, + 0xA8, 0x1B, 0x68, 0xA8, 0x3D, 0xE8, 0xF4, 0x44, 0x6C, 0xBD, 0xA1, 0xC2, + 0xCB, 0x03, 0xBE, 0x8C, 0x3E, 0x13, 0x00, 0x84, 0xDF, 0x4A, 0x48, 0xC0, + 0xE3, 0x22, 0x0A, 0xE8, 0xE9, 0x37, 0xA7, 0x18, 0x4C, 0xB1, 0x09, 0x0D, + 0x23, 0x56, 0x7F, 0x04, 0x4D, 0xD9, 0x17, 0x84, 0x18, 0xA5, 0xC8, 0xDA, + 0x40, 0x94, 0x73, 0xEB, 0xCE, 0x0E, 0x57, 0x3C, 0x03, 0x81, 0x3A, 0x9D, + 0x0A, 0xA1, 0x57, 0x43, 0x69, 0xAC, 0x57, 0x6D, 0x79, 0x90, 0x78, 0xE5, + 0xB5, 0xB4, 0x3B, 0xD8, 0xBC, 0x4C, 0x8D, 0x28, 0xA1, 0xA7, 0xA3, 0xA7, + 0xBA, 0x02, 0x4E, 0x25, 0xD1, 0x2A, 0xAE, 0xED, 0xAE, 0x03, 0x22, 0xB8, + 0x6B, 0x20, 0x0F, 0x30, 0x28, 0x54, 0x95, 0x7F, 0xE0, 0xEE, 0xCE, 0x0A, + 0x66, 0x9D, 0xD1, 0x40, 0x2D, 0x6E, 0x22, 0xAF, 0x9D, 0x1A, 0xC1, 0x05, + 0x19, 0xD2, 0x6F, 0xC0, 0xF2, 0x9F, 0xF8, 0x7B, 0xB3, 0x02, 0x42, 0xFB, + 0x50, 0xA9, 0x1D, 0x2D, 0x93, 0x0F, 0x23, 0xAB, 0xC6, 0xC1, 0x0F, 0x92, + 0xFF, 0xD0, 0xA2, 0x15, 0xF5, 0x53, 0x09, 0x71, 0x1C, 0xFF, 0x45, 0x13, + 0x84, 0xE6, 0x26, 0x5E, 0xF8, 0xE0, 0x88, 0x1C, 0x0A, 0xFC, 0x16, 0xB6, + 0xA8, 0x73, 0x06, 0xB8, 0xF0, 0x63, 0x84, 0x02, 0xA0, 0xC6, 0x5A, 0xEC, + 0xE7, 0x74, 0xDF, 0x70, 0xAE, 0xA3, 0x83, 0x25, 0xEA, 0xD6, 0xC7, 0x97, + 0x87, 0x93, 0xA7, 0xC6, 0x8A, 0x8A, 0x33, 0x97, 0x60, 0x37, 0x10, 0x3E, + 0x97, 0x3E, 0x6E, 0x29, 0x15, 0xD6, 0xA1, 0x0F, 0xD1, 0x88, 0x2C, 0x12, + 0x9F, 0x6F, 0xAA, 0xA4, 0xC6, 0x42, 0xEB, 0x41, 0xA2, 0xE3, 0x95, 0x43, + 0xD3, 0x01, 0x85, 0x6D, 0x8E, 0xBB, 0x3B, 0xF3, 0x23, 0x36, 0xC7, 0xFE, + 0x3B, 0xE0, 0xA1, 0x25, 0x07, 0x48, 0xAB, 0xC9, 0x89, 0x74, 0xFF, 0x08, + 0x8F, 0x80, 0xBF, 0xC0, 0x96, 0x65, 0xF3, 0xEE, 0xEC, 0x4B, 0x68, 0xBD, + 0x9D, 0x88, 0xC3, 0x31, 0xB3, 0x40, 0xF1, 0xE8, 0xCF, 0xF6, 0x38, 0xBB, + 0x9C, 0xE4, 0xD1, 0x7F, 0xD4, 0xE5, 0x58, 0x9B, 0x7C, 0xFA, 0xD4, 0xF3, + 0x0E, 0x9B, 0x75, 0x91, 0xE4, 0xBA, 0x52, 0x2E, 0x19, 0x7E, 0xD1, 0xF5, + 0xCD, 0x5A, 0x19, 0xFC, 0xBA, 0x06, 0xF6, 0xFB, 0x52, 0xA8, 0x4B, 0x99, + 0x04, 0xDD, 0xF8, 0xF9, 0xB4, 0x8B, 0x50, 0xA3, 0x4E, 0x62, 0x89, 0xF0, + 0x87, 0x24, 0xFA, 0x83, 0x42, 0xC1, 0x87, 0xFA, 0xD5, 0x2D, 0x29, 0x2A, + 0x5A, 0x71, 0x7A, 0x64, 0x6A, 0xD7, 0x27, 0x60, 0x63, 0x0D, 0xDB, 0xCE, + 0x49, 0xF5, 0x8D, 0x1F, 0x90, 0x89, 0x32, 0x17, 0xF8, 0x73, 0x43, 0xB8, + 0xD2, 0x5A, 0x93, 0x86, 0x61, 0xD6, 0xE1, 0x75, 0x0A, 0xEA, 0x79, 0x66, + 0x76, 0x88, 0x4F, 0x71, 0xEB, 0x04, 0x25, 0xD6, 0x0A, 0x5A, 0x7A, 0x93, + 0xE5, 0xB9, 0x4B, 0x17, 0x40, 0x0F, 0xB1, 0xB6, 0xB9, 0xF5, 0xDE, 0x4F, + 0xDC, 0xE0, 0xB3, 0xAC, 0x3B, 0x11, 0x70, 0x60, 0x84, 0x4A, 0x43, 0x6E, + 0x99, 0x20, 0xC0, 0x29, 0x71, 0x0A, 0xC0, 0x65 +}; + +static const unsigned char TA61_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA62_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x32 +}; + +static const unsigned char TA62_EC_Q[] = { + 0x04, 0x9D, 0xCB, 0x80, 0x91, 0x8D, 0x53, 0x67, 0xB5, 0xB9, 0x50, 0xB1, + 0x03, 0xF8, 0xE5, 0x49, 0x1F, 0x41, 0x22, 0x09, 0xB0, 0x51, 0x52, 0x58, + 0xD6, 0x2B, 0x34, 0x8F, 0xC5, 0x12, 0x46, 0x14, 0xC5, 0x8B, 0x2F, 0x2C, + 0x84, 0xFF, 0x2C, 0x6E, 0xA8, 0xD5, 0xF1, 0x09, 0xE3, 0x03, 0x21, 0x14, + 0xC4, 0x43, 0x3D, 0x7C, 0xC1, 0x2C, 0xC4, 0x4B, 0x6A, 0x4A, 0xCD, 0xE9, + 0x87, 0xE0, 0x7D, 0xF6, 0x22, 0xBE, 0xFA, 0x4A, 0x51, 0xB8, 0x30, 0x8A, + 0xFD, 0xE1, 0xDE, 0x18, 0x12, 0x0A, 0xF6, 0x47, 0xB7, 0xE7, 0x17, 0xBF, + 0x27, 0x8A, 0xD4, 0x41, 0x4C, 0x96, 0x3C, 0x60, 0x96, 0xC1, 0xFD, 0x15, + 0x1C +}; + +static const unsigned char TA63_DN[] = { + 0x30, 0x81, 0xB4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, + 0x74, 0x31, 0x40, 0x30, 0x3E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x14, 0x37, + 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, + 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x5F, 0x32, 0x30, 0x34, 0x38, + 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x2E, 0x20, 0x62, 0x79, 0x20, + 0x72, 0x65, 0x66, 0x2E, 0x20, 0x28, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x73, + 0x20, 0x6C, 0x69, 0x61, 0x62, 0x2E, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1C, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, + 0x65, 0x74, 0x20, 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, + 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, + 0x34, 0x38, 0x29 +}; + +static const unsigned char TA63_RSA_N[] = { + 0xAD, 0x4D, 0x4B, 0xA9, 0x12, 0x86, 0xB2, 0xEA, 0xA3, 0x20, 0x07, 0x15, + 0x16, 0x64, 0x2A, 0x2B, 0x4B, 0xD1, 0xBF, 0x0B, 0x4A, 0x4D, 0x8E, 0xED, + 0x80, 0x76, 0xA5, 0x67, 0xB7, 0x78, 0x40, 0xC0, 0x73, 0x42, 0xC8, 0x68, + 0xC0, 0xDB, 0x53, 0x2B, 0xDD, 0x5E, 0xB8, 0x76, 0x98, 0x35, 0x93, 0x8B, + 0x1A, 0x9D, 0x7C, 0x13, 0x3A, 0x0E, 0x1F, 0x5B, 0xB7, 0x1E, 0xCF, 0xE5, + 0x24, 0x14, 0x1E, 0xB1, 0x81, 0xA9, 0x8D, 0x7D, 0xB8, 0xCC, 0x6B, 0x4B, + 0x03, 0xF1, 0x02, 0x0C, 0xDC, 0xAB, 0xA5, 0x40, 0x24, 0x00, 0x7F, 0x74, + 0x94, 0xA1, 0x9D, 0x08, 0x29, 0xB3, 0x88, 0x0B, 0xF5, 0x87, 0x77, 0x9D, + 0x55, 0xCD, 0xE4, 0xC3, 0x7E, 0xD7, 0x6A, 0x64, 0xAB, 0x85, 0x14, 0x86, + 0x95, 0x5B, 0x97, 0x32, 0x50, 0x6F, 0x3D, 0xC8, 0xBA, 0x66, 0x0C, 0xE3, + 0xFC, 0xBD, 0xB8, 0x49, 0xC1, 0x76, 0x89, 0x49, 0x19, 0xFD, 0xC0, 0xA8, + 0xBD, 0x89, 0xA3, 0x67, 0x2F, 0xC6, 0x9F, 0xBC, 0x71, 0x19, 0x60, 0xB8, + 0x2D, 0xE9, 0x2C, 0xC9, 0x90, 0x76, 0x66, 0x7B, 0x94, 0xE2, 0xAF, 0x78, + 0xD6, 0x65, 0x53, 0x5D, 0x3C, 0xD6, 0x9C, 0xB2, 0xCF, 0x29, 0x03, 0xF9, + 0x2F, 0xA4, 0x50, 0xB2, 0xD4, 0x48, 0xCE, 0x05, 0x32, 0x55, 0x8A, 0xFD, + 0xB2, 0x64, 0x4C, 0x0E, 0xE4, 0x98, 0x07, 0x75, 0xDB, 0x7F, 0xDF, 0xB9, + 0x08, 0x55, 0x60, 0x85, 0x30, 0x29, 0xF9, 0x7B, 0x48, 0xA4, 0x69, 0x86, + 0xE3, 0x35, 0x3F, 0x1E, 0x86, 0x5D, 0x7A, 0x7A, 0x15, 0xBD, 0xEF, 0x00, + 0x8E, 0x15, 0x22, 0x54, 0x17, 0x00, 0x90, 0x26, 0x93, 0xBC, 0x0E, 0x49, + 0x68, 0x91, 0xBF, 0xF8, 0x47, 0xD3, 0x9D, 0x95, 0x42, 0xC1, 0x0E, 0x4D, + 0xDF, 0x6F, 0x26, 0xCF, 0xC3, 0x18, 0x21, 0x62, 0x66, 0x43, 0x70, 0xD6, + 0xD5, 0xC0, 0x07, 0xE1 +}; + +static const unsigned char TA63_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA64_DN[] = { + 0x30, 0x69, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4B, 0x52, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, 0x42, 0x55, 0x53, 0x49, + 0x4E, 0x45, 0x53, 0x53, 0x20, 0x50, 0x4C, 0x41, 0x54, 0x46, 0x4F, 0x52, + 0x4D, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA64_RSA_N[] = { + 0xB6, 0xD4, 0xF1, 0x93, 0x5C, 0xB5, 0x40, 0x89, 0x0A, 0xAB, 0x0D, 0x90, + 0x5B, 0x50, 0x63, 0xAE, 0x90, 0x94, 0x74, 0x17, 0x45, 0x72, 0xD6, 0x7B, + 0x65, 0x5A, 0x29, 0x4B, 0xA7, 0x56, 0xA0, 0x4B, 0xB8, 0x2F, 0x42, 0x75, + 0xE9, 0xD9, 0x7B, 0x24, 0x5A, 0x31, 0x65, 0xAB, 0x17, 0x17, 0xD1, 0x33, + 0x3A, 0xD9, 0x11, 0xDC, 0x40, 0x36, 0x87, 0xDF, 0xC7, 0x6A, 0xE9, 0x26, + 0x5E, 0x59, 0x8A, 0x77, 0xE3, 0xE8, 0x48, 0x9C, 0x31, 0x16, 0xFA, 0x3E, + 0x91, 0xB1, 0xCA, 0xC9, 0xA3, 0xE2, 0x9F, 0xCE, 0x21, 0x53, 0xA3, 0x02, + 0x36, 0x30, 0xCB, 0x52, 0x02, 0xE5, 0xDA, 0x32, 0x5D, 0xC3, 0xC5, 0xE6, + 0xF9, 0xEE, 0x11, 0xC7, 0x8B, 0xC9, 0x44, 0x1E, 0x84, 0x93, 0x18, 0x4A, + 0xB4, 0x9F, 0xE5, 0x12, 0x64, 0x69, 0xD0, 0x26, 0x85, 0x62, 0x01, 0xB6, + 0xC9, 0x02, 0x1D, 0xBE, 0x83, 0x51, 0xBB, 0x5C, 0xDA, 0xF8, 0xAD, 0x15, + 0x6A, 0x99, 0xF7, 0x92, 0x54, 0xF7, 0x34, 0x5B, 0xE9, 0xBF, 0xEA, 0x29, + 0x81, 0x12, 0xD4, 0x53, 0x91, 0x96, 0xB3, 0x91, 0x5A, 0xDD, 0xFE, 0x90, + 0x73, 0x28, 0xFB, 0x30, 0x46, 0xB5, 0xCA, 0x08, 0x07, 0xC7, 0x71, 0x72, + 0xC9, 0x66, 0xD3, 0x34, 0x97, 0xF6, 0x8C, 0xF4, 0x18, 0x4A, 0xE1, 0xD0, + 0x3D, 0x5A, 0x45, 0xB6, 0x69, 0xA7, 0x29, 0xFB, 0x23, 0xCE, 0x88, 0xD8, + 0x12, 0x9C, 0x00, 0x48, 0xA8, 0xA6, 0x0F, 0xB3, 0x3B, 0x92, 0x8D, 0x71, + 0x0E, 0x74, 0xC5, 0x8B, 0xC8, 0x4C, 0xF9, 0xF4, 0x9B, 0x8E, 0xB8, 0x3C, + 0x69, 0xED, 0x6F, 0x3B, 0x50, 0x2F, 0x58, 0xED, 0xC4, 0xB0, 0xD0, 0x1C, + 0x1B, 0x6A, 0x0C, 0xE2, 0xBC, 0x44, 0xAA, 0xD8, 0xCD, 0x14, 0x5D, 0x94, + 0x78, 0x61, 0xBF, 0x0E, 0x6E, 0xDA, 0x2A, 0xBC, 0x2F, 0x0C, 0x0B, 0x71, + 0xA6, 0xB3, 0x16, 0x3F, 0x9C, 0xE6, 0xF9, 0xCC, 0x9F, 0x53, 0x35, 0xE2, + 0x03, 0xA0, 0xA0, 0x18, 0xBF, 0xBB, 0xF1, 0xBE, 0xF4, 0xD6, 0x8C, 0x87, + 0x0D, 0x42, 0xF7, 0x06, 0xB9, 0xF1, 0x6D, 0xED, 0x04, 0x94, 0xA8, 0xFE, + 0xB6, 0xD3, 0x06, 0xC6, 0x40, 0x61, 0xDF, 0x9D, 0x9D, 0xF3, 0x54, 0x76, + 0xCE, 0x53, 0x3A, 0x01, 0xA6, 0x92, 0x41, 0xEC, 0x04, 0xA3, 0x8F, 0x0D, + 0xA2, 0xD5, 0x09, 0xCA, 0xD6, 0xCB, 0x9A, 0xF1, 0xEF, 0x43, 0x5D, 0xC0, + 0xAB, 0xA5, 0x41, 0xCF, 0x5C, 0x53, 0x70, 0x70, 0xC9, 0x88, 0xA6, 0x2D, + 0xD4, 0x6B, 0x61, 0x73, 0x50, 0x26, 0x86, 0x61, 0x0E, 0x5F, 0x1B, 0xC2, + 0x2B, 0xE2, 0x8C, 0xD5, 0xBB, 0x9D, 0xC1, 0x03, 0x42, 0xBA, 0x94, 0xDA, + 0x5F, 0xA9, 0xB0, 0xCA, 0xCC, 0x4D, 0x0A, 0xEF, 0x47, 0x69, 0x03, 0x2F, + 0x22, 0xFB, 0xF1, 0x28, 0xCE, 0xBF, 0x5D, 0x50, 0x65, 0xA8, 0x90, 0x6D, + 0xB3, 0x74, 0xB0, 0x08, 0xC7, 0xAC, 0xA8, 0xD1, 0xEB, 0x3E, 0x9C, 0xFC, + 0x5D, 0x1A, 0x83, 0x2E, 0x2B, 0xCB, 0xB5, 0xF3, 0x44, 0x9D, 0x3A, 0xA7, + 0x17, 0x61, 0x96, 0xA2, 0x71, 0xD3, 0x70, 0x96, 0x15, 0x4D, 0xB7, 0x4C, + 0x73, 0xEE, 0x19, 0x5C, 0xC5, 0x5B, 0x3E, 0x41, 0xFE, 0xAC, 0x75, 0x60, + 0x3B, 0x1B, 0x63, 0xCE, 0x00, 0xDD, 0xDA, 0x08, 0x90, 0x62, 0xB4, 0xE5, + 0x2D, 0xEE, 0x48, 0xA7, 0x6B, 0x17, 0x99, 0x54, 0xBE, 0x87, 0x4A, 0xE3, + 0xA9, 0x5E, 0x04, 0x4C, 0xEB, 0x10, 0x6D, 0x54, 0xD6, 0xEF, 0xF1, 0xE8, + 0xF2, 0x62, 0x16, 0xCB, 0x80, 0x6B, 0xED, 0x3D, 0xED, 0xF5, 0x1F, 0x30, + 0xA5, 0xAE, 0x4B, 0xC9, 0x13, 0xED, 0x8A, 0x01, 0x01, 0xC9, 0xB8, 0x51, + 0x58, 0xC0, 0x66, 0x3A, 0xB1, 0x66, 0x4B, 0xC4, 0xD5, 0x31, 0x02, 0x62, + 0xE9, 0x74, 0x84, 0x0C, 0xDB, 0x4D, 0x46, 0x2D +}; + +static const unsigned char TA64_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA65_DN[] = { + 0x30, 0x81, 0x80, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, + 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x24, 0x30, + 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x43, 0x65, 0x72, 0x74, + 0x75, 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, + 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA65_RSA_N[] = { + 0xBD, 0xF9, 0x78, 0xF8, 0xE6, 0xD5, 0x80, 0x0C, 0x64, 0x9D, 0x86, 0x1B, + 0x96, 0x64, 0x67, 0x3F, 0x22, 0x3A, 0x1E, 0x75, 0x01, 0x7D, 0xEF, 0xFB, + 0x5C, 0x67, 0x8C, 0xC9, 0xCC, 0x5C, 0x6B, 0xA9, 0x91, 0xE6, 0xB9, 0x42, + 0xE5, 0x20, 0x4B, 0x9B, 0xDA, 0x9B, 0x7B, 0xB9, 0x99, 0x5D, 0xD9, 0x9B, + 0x80, 0x4B, 0xD7, 0x84, 0x40, 0x2B, 0x27, 0xD3, 0xE8, 0xBA, 0x30, 0xBB, + 0x3E, 0x09, 0x1A, 0xA7, 0x49, 0x95, 0xEF, 0x2B, 0x40, 0x24, 0xC2, 0x97, + 0xC7, 0xA7, 0xEE, 0x9B, 0x25, 0xEF, 0xA8, 0x0A, 0x00, 0x97, 0x85, 0x5A, + 0xAA, 0x9D, 0xDC, 0x29, 0xC9, 0xE2, 0x35, 0x07, 0xEB, 0x70, 0x4D, 0x4A, + 0xD6, 0xC1, 0xB3, 0x56, 0xB8, 0xA1, 0x41, 0x38, 0x9B, 0xD1, 0xFB, 0x31, + 0x7F, 0x8F, 0xE0, 0x5F, 0xE1, 0xB1, 0x3F, 0x0F, 0x8E, 0x16, 0x49, 0x60, + 0xD7, 0x06, 0x8D, 0x18, 0xF9, 0xAA, 0x26, 0x10, 0xAB, 0x2A, 0xD3, 0xD0, + 0xD1, 0x67, 0x8D, 0x1B, 0x46, 0xBE, 0x47, 0x30, 0xD5, 0x2E, 0x72, 0xD1, + 0xC5, 0x63, 0xDA, 0xE7, 0x63, 0x79, 0x44, 0x7E, 0x4B, 0x63, 0x24, 0x89, + 0x86, 0x2E, 0x34, 0x3F, 0x29, 0x4C, 0x52, 0x8B, 0x2A, 0xA7, 0xC0, 0xE2, + 0x91, 0x28, 0x89, 0xB9, 0xC0, 0x5B, 0xF9, 0x1D, 0xD9, 0xE7, 0x27, 0xAD, + 0xFF, 0x9A, 0x02, 0x97, 0xC1, 0xC6, 0x50, 0x92, 0x9B, 0x02, 0x2C, 0xBD, + 0xA9, 0xB9, 0x34, 0x59, 0x0A, 0xBF, 0x84, 0x4A, 0xFF, 0xDF, 0xFE, 0xB3, + 0x9F, 0xEB, 0xD9, 0x9E, 0xE0, 0x98, 0x23, 0xEC, 0xA6, 0x6B, 0x77, 0x16, + 0x2A, 0xDB, 0xCC, 0xAD, 0x3B, 0x1C, 0xA4, 0x87, 0xDC, 0x46, 0x73, 0x5E, + 0x19, 0x62, 0x68, 0x45, 0x57, 0xE4, 0x90, 0x82, 0x42, 0xBB, 0x42, 0xD6, + 0xF0, 0x61, 0xE0, 0xC1, 0xA3, 0x3D, 0x66, 0xA3, 0x5D, 0xF4, 0x18, 0xEE, + 0x88, 0xC9, 0x8D, 0x17, 0x45, 0x29, 0x99, 0x32, 0x75, 0x02, 0x31, 0xEE, + 0x29, 0x26, 0xC8, 0x6B, 0x02, 0xE6, 0xB5, 0x62, 0x45, 0x7F, 0x37, 0x15, + 0x5A, 0x23, 0x68, 0x89, 0xD4, 0x3E, 0xDE, 0x4E, 0x27, 0xB0, 0xF0, 0x40, + 0x0C, 0xBC, 0x4D, 0x17, 0xCB, 0x4D, 0xA2, 0xB3, 0x1E, 0xD0, 0x06, 0x5A, + 0xDD, 0xF6, 0x93, 0xCF, 0x57, 0x75, 0x99, 0xF5, 0xFA, 0x86, 0x1A, 0x67, + 0x78, 0xB3, 0xBF, 0x96, 0xFE, 0x34, 0xDC, 0xBD, 0xE7, 0x52, 0x56, 0xE5, + 0xB3, 0xE5, 0x75, 0x7B, 0xD7, 0x41, 0x91, 0x05, 0xDC, 0x5D, 0x69, 0xE3, + 0x95, 0x0D, 0x43, 0xB9, 0xFC, 0x83, 0x96, 0x39, 0x95, 0x7B, 0x6C, 0x80, + 0x5A, 0x4F, 0x13, 0x72, 0xC6, 0xD7, 0x7D, 0x29, 0x7A, 0x44, 0xBA, 0x52, + 0xA4, 0x2A, 0xD5, 0x41, 0x46, 0x09, 0x20, 0xFE, 0x22, 0xA0, 0xB6, 0x5B, + 0x30, 0x8D, 0xBC, 0x89, 0x0C, 0xD5, 0xD7, 0x70, 0xF8, 0x87, 0x52, 0xFD, + 0xDA, 0xEF, 0xAC, 0x51, 0x2E, 0x07, 0xB3, 0x4E, 0xFE, 0xD0, 0x09, 0xDA, + 0x70, 0xEF, 0x98, 0xFA, 0x56, 0xE6, 0x6D, 0xDB, 0xB5, 0x57, 0x4B, 0xDC, + 0xE5, 0x2C, 0x25, 0x15, 0xC8, 0x9E, 0x2E, 0x78, 0x4E, 0xF8, 0xDA, 0x9C, + 0x9E, 0x86, 0x2C, 0xCA, 0x57, 0xF3, 0x1A, 0xE5, 0xC8, 0x92, 0x8B, 0x1A, + 0x82, 0x96, 0x7A, 0xC3, 0xBC, 0x50, 0x12, 0x69, 0xD8, 0x0E, 0x5A, 0x46, + 0x8B, 0x3A, 0xEB, 0x26, 0xFA, 0x23, 0xC9, 0xB6, 0xB0, 0x81, 0xBE, 0x42, + 0x00, 0xA4, 0xF8, 0xD6, 0xFE, 0x30, 0x2E, 0xC7, 0xD2, 0x46, 0xF6, 0xE5, + 0x8E, 0x75, 0xFD, 0xF2, 0xCC, 0xB9, 0xD0, 0x87, 0x5B, 0xCC, 0x06, 0x10, + 0x60, 0xBB, 0x83, 0x35, 0xB7, 0x5E, 0x67, 0xDE, 0x47, 0xEC, 0x99, 0x48, + 0xF1, 0xA4, 0xA1, 0x15, 0xFE, 0xAD, 0x8C, 0x62, 0x8E, 0x39, 0x55, 0x4F, + 0x39, 0x16, 0xB9, 0xB1, 0x63, 0x9D, 0xFF, 0xB7 +}; + +static const unsigned char TA65_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA66_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x31 +}; + +static const unsigned char TA66_RSA_N[] = { + 0xAD, 0xE8, 0x24, 0x73, 0xF4, 0x14, 0x37, 0xF3, 0x9B, 0x9E, 0x2B, 0x57, + 0x28, 0x1C, 0x87, 0xBE, 0xDC, 0xB7, 0xDF, 0x38, 0x90, 0x8C, 0x6E, 0x3C, + 0xE6, 0x57, 0xA0, 0x78, 0xF7, 0x75, 0xC2, 0xA2, 0xFE, 0xF5, 0x6A, 0x6E, + 0xF6, 0x00, 0x4F, 0x28, 0xDB, 0xDE, 0x68, 0x86, 0x6C, 0x44, 0x93, 0xB6, + 0xB1, 0x63, 0xFD, 0x14, 0x12, 0x6B, 0xBF, 0x1F, 0xD2, 0xEA, 0x31, 0x9B, + 0x21, 0x7E, 0xD1, 0x33, 0x3C, 0xBA, 0x48, 0xF5, 0xDD, 0x79, 0xDF, 0xB3, + 0xB8, 0xFF, 0x12, 0xF1, 0x21, 0x9A, 0x4B, 0xC1, 0x8A, 0x86, 0x71, 0x69, + 0x4A, 0x66, 0x66, 0x6C, 0x8F, 0x7E, 0x3C, 0x70, 0xBF, 0xAD, 0x29, 0x22, + 0x06, 0xF3, 0xE4, 0xC0, 0xE6, 0x80, 0xAE, 0xE2, 0x4B, 0x8F, 0xB7, 0x99, + 0x7E, 0x94, 0x03, 0x9F, 0xD3, 0x47, 0x97, 0x7C, 0x99, 0x48, 0x23, 0x53, + 0xE8, 0x38, 0xAE, 0x4F, 0x0A, 0x6F, 0x83, 0x2E, 0xD1, 0x49, 0x57, 0x8C, + 0x80, 0x74, 0xB6, 0xDA, 0x2F, 0xD0, 0x38, 0x8D, 0x7B, 0x03, 0x70, 0x21, + 0x1B, 0x75, 0xF2, 0x30, 0x3C, 0xFA, 0x8F, 0xAE, 0xDD, 0xDA, 0x63, 0xAB, + 0xEB, 0x16, 0x4F, 0xC2, 0x8E, 0x11, 0x4B, 0x7E, 0xCF, 0x0B, 0xE8, 0xFF, + 0xB5, 0x77, 0x2E, 0xF4, 0xB2, 0x7B, 0x4A, 0xE0, 0x4C, 0x12, 0x25, 0x0C, + 0x70, 0x8D, 0x03, 0x29, 0xA0, 0xE1, 0x53, 0x24, 0xEC, 0x13, 0xD9, 0xEE, + 0x19, 0xBF, 0x10, 0xB3, 0x4A, 0x8C, 0x3F, 0x89, 0xA3, 0x61, 0x51, 0xDE, + 0xAC, 0x87, 0x07, 0x94, 0xF4, 0x63, 0x71, 0xEC, 0x2E, 0xE2, 0x6F, 0x5B, + 0x98, 0x81, 0xE1, 0x89, 0x5C, 0x34, 0x79, 0x6C, 0x76, 0xEF, 0x3B, 0x90, + 0x62, 0x79, 0xE6, 0xDB, 0xA4, 0x9A, 0x2F, 0x26, 0xC5, 0xD0, 0x10, 0xE1, + 0x0E, 0xDE, 0xD9, 0x10, 0x8E, 0x16, 0xFB, 0xB7, 0xF7, 0xA8, 0xF7, 0xC7, + 0xE5, 0x02, 0x07, 0x98, 0x8F, 0x36, 0x08, 0x95, 0xE7, 0xE2, 0x37, 0x96, + 0x0D, 0x36, 0x75, 0x9E, 0xFB, 0x0E, 0x72, 0xB1, 0x1D, 0x9B, 0xBC, 0x03, + 0xF9, 0x49, 0x05, 0xD8, 0x81, 0xDD, 0x05, 0xB4, 0x2A, 0xD6, 0x41, 0xE9, + 0xAC, 0x01, 0x76, 0x95, 0x0A, 0x0F, 0xD8, 0xDF, 0xD5, 0xBD, 0x12, 0x1F, + 0x35, 0x2F, 0x28, 0x17, 0x6C, 0xD2, 0x98, 0xC1, 0xA8, 0x09, 0x64, 0x77, + 0x6E, 0x47, 0x37, 0xBA, 0xCE, 0xAC, 0x59, 0x5E, 0x68, 0x9D, 0x7F, 0x72, + 0xD6, 0x89, 0xC5, 0x06, 0x41, 0x29, 0x3E, 0x59, 0x3E, 0xDD, 0x26, 0xF5, + 0x24, 0xC9, 0x11, 0xA7, 0x5A, 0xA3, 0x4C, 0x40, 0x1F, 0x46, 0xA1, 0x99, + 0xB5, 0xA7, 0x3A, 0x51, 0x6E, 0x86, 0x3B, 0x9E, 0x7D, 0x72, 0xA7, 0x12, + 0x05, 0x78, 0x59, 0xED, 0x3E, 0x51, 0x78, 0x15, 0x0B, 0x03, 0x8F, 0x8D, + 0xD0, 0x2F, 0x05, 0xB2, 0x3E, 0x7B, 0x4A, 0x1C, 0x4B, 0x73, 0x05, 0x12, + 0xFC, 0xC6, 0xEA, 0xE0, 0x50, 0x13, 0x7C, 0x43, 0x93, 0x74, 0xB3, 0xCA, + 0x74, 0xE7, 0x8E, 0x1F, 0x01, 0x08, 0xD0, 0x30, 0xD4, 0x5B, 0x71, 0x36, + 0xB4, 0x07, 0xBA, 0xC1, 0x30, 0x30, 0x5C, 0x48, 0xB7, 0x82, 0x3B, 0x98, + 0xA6, 0x7D, 0x60, 0x8A, 0xA2, 0xA3, 0x29, 0x82, 0xCC, 0xBA, 0xBD, 0x83, + 0x04, 0x1B, 0xA2, 0x83, 0x03, 0x41, 0xA1, 0xD6, 0x05, 0xF1, 0x1B, 0xC2, + 0xB6, 0xF0, 0xA8, 0x7C, 0x86, 0x3B, 0x46, 0xA8, 0x48, 0x2A, 0x88, 0xDC, + 0x76, 0x9A, 0x76, 0xBF, 0x1F, 0x6A, 0xA5, 0x3D, 0x19, 0x8F, 0xEB, 0x38, + 0xF3, 0x64, 0xDE, 0xC8, 0x2B, 0x0D, 0x0A, 0x28, 0xFF, 0xF7, 0xDB, 0xE2, + 0x15, 0x42, 0xD4, 0x22, 0xD0, 0x27, 0x5D, 0xE1, 0x79, 0xFE, 0x18, 0xE7, + 0x70, 0x88, 0xAD, 0x4E, 0xE6, 0xD9, 0x8B, 0x3A, 0xC6, 0xDD, 0x27, 0x51, + 0x6E, 0xFF, 0xBC, 0x64, 0xF5, 0x33, 0x43, 0x4F +}; + +static const unsigned char TA66_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA67_DN[] = { + 0x30, 0x81, 0x81, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA67_RSA_N[] = { + 0xD0, 0x40, 0x8B, 0x8B, 0x72, 0xE3, 0x91, 0x1B, 0xF7, 0x51, 0xC1, 0x1B, + 0x54, 0x04, 0x98, 0xD3, 0xA9, 0xBF, 0xC1, 0xE6, 0x8A, 0x5D, 0x3B, 0x87, + 0xFB, 0xBB, 0x88, 0xCE, 0x0D, 0xE3, 0x2F, 0x3F, 0x06, 0x96, 0xF0, 0xA2, + 0x29, 0x50, 0x99, 0xAE, 0xDB, 0x3B, 0xA1, 0x57, 0xB0, 0x74, 0x51, 0x71, + 0xCD, 0xED, 0x42, 0x91, 0x4D, 0x41, 0xFE, 0xA9, 0xC8, 0xD8, 0x6A, 0x86, + 0x77, 0x44, 0xBB, 0x59, 0x66, 0x97, 0x50, 0x5E, 0xB4, 0xD4, 0x2C, 0x70, + 0x44, 0xCF, 0xDA, 0x37, 0x95, 0x42, 0x69, 0x3C, 0x30, 0xC4, 0x71, 0xB3, + 0x52, 0xF0, 0x21, 0x4D, 0xA1, 0xD8, 0xBA, 0x39, 0x7C, 0x1C, 0x9E, 0xA3, + 0x24, 0x9D, 0xF2, 0x83, 0x16, 0x98, 0xAA, 0x16, 0x7C, 0x43, 0x9B, 0x15, + 0x5B, 0xB7, 0xAE, 0x34, 0x91, 0xFE, 0xD4, 0x62, 0x26, 0x18, 0x46, 0x9A, + 0x3F, 0xEB, 0xC1, 0xF9, 0xF1, 0x90, 0x57, 0xEB, 0xAC, 0x7A, 0x0D, 0x8B, + 0xDB, 0x72, 0x30, 0x6A, 0x66, 0xD5, 0xE0, 0x46, 0xA3, 0x70, 0xDC, 0x68, + 0xD9, 0xFF, 0x04, 0x48, 0x89, 0x77, 0xDE, 0xB5, 0xE9, 0xFB, 0x67, 0x6D, + 0x41, 0xE9, 0xBC, 0x39, 0xBD, 0x32, 0xD9, 0x62, 0x02, 0xF1, 0xB1, 0xA8, + 0x3D, 0x6E, 0x37, 0x9C, 0xE2, 0x2F, 0xE2, 0xD3, 0xA2, 0x26, 0x8B, 0xC6, + 0xB8, 0x55, 0x43, 0x88, 0xE1, 0x23, 0x3E, 0xA5, 0xD2, 0x24, 0x39, 0x6A, + 0x47, 0xAB, 0x00, 0xD4, 0xA1, 0xB3, 0xA9, 0x25, 0xFE, 0x0D, 0x3F, 0xA7, + 0x1D, 0xBA, 0xD3, 0x51, 0xC1, 0x0B, 0xA4, 0xDA, 0xAC, 0x38, 0xEF, 0x55, + 0x50, 0x24, 0x05, 0x65, 0x46, 0x93, 0x34, 0x4F, 0x2D, 0x8D, 0xAD, 0xC6, + 0xD4, 0x21, 0x19, 0xD2, 0x8E, 0xCA, 0x05, 0x61, 0x71, 0x07, 0x73, 0x47, + 0xE5, 0x8A, 0x19, 0x12, 0xBD, 0x04, 0x4D, 0xCE, 0x4E, 0x9C, 0xA5, 0x48, + 0xAC, 0xBB, 0x26, 0xF7 +}; + +static const unsigned char TA67_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA68_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x1C, + 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x43, 0x31 +}; + +static const unsigned char TA68_RSA_N[] = { + 0xCF, 0xEB, 0xA9, 0xB9, 0xF1, 0x99, 0x05, 0xCC, 0xD8, 0x28, 0x21, 0x4A, + 0xF3, 0x73, 0x34, 0x51, 0x84, 0x56, 0x10, 0xF5, 0xA0, 0x4F, 0x2C, 0x12, + 0xE3, 0xFA, 0x13, 0x9A, 0x27, 0xD0, 0xCF, 0xF9, 0x79, 0x1A, 0x74, 0x5F, + 0x1D, 0x79, 0x39, 0xFC, 0x5B, 0xF8, 0x70, 0x8E, 0xE0, 0x92, 0x52, 0xF7, + 0xE4, 0x25, 0xF9, 0x54, 0x83, 0xD9, 0x1D, 0xD3, 0xC8, 0x5A, 0x85, 0x3F, + 0x5E, 0xC7, 0xB6, 0x07, 0xEE, 0x3E, 0xC0, 0xCE, 0x9A, 0xAF, 0xAC, 0x56, + 0x42, 0x2A, 0x39, 0x25, 0x70, 0xD6, 0xBF, 0xB5, 0x7B, 0x36, 0xAD, 0xAC, + 0xF6, 0x73, 0xDC, 0xCD, 0xD7, 0x1D, 0x8A, 0x83, 0xA5, 0xFB, 0x2B, 0x90, + 0x15, 0x37, 0x6B, 0x1C, 0x26, 0x47, 0xDC, 0x3B, 0x29, 0x56, 0x93, 0x6A, + 0xB3, 0xC1, 0x6A, 0x3A, 0x9D, 0x3D, 0xF5, 0xC1, 0x97, 0x38, 0x58, 0x05, + 0x8B, 0x1C, 0x11, 0xE3, 0xE4, 0xB4, 0xB8, 0x5D, 0x85, 0x1D, 0x83, 0xFE, + 0x78, 0x5F, 0x0B, 0x45, 0x68, 0x18, 0x48, 0xA5, 0x46, 0x73, 0x34, 0x3B, + 0xFE, 0x0F, 0xC8, 0x76, 0xBB, 0xC7, 0x18, 0xF3, 0x05, 0xD1, 0x86, 0xF3, + 0x85, 0xED, 0xE7, 0xB9, 0xD9, 0x32, 0xAD, 0x55, 0x88, 0xCE, 0xA6, 0xB6, + 0x91, 0xB0, 0x4F, 0xAC, 0x7E, 0x15, 0x23, 0x96, 0xF6, 0x3F, 0xF0, 0x20, + 0x34, 0x16, 0xDE, 0x0A, 0xC6, 0xC4, 0x04, 0x45, 0x79, 0x7F, 0xA7, 0xFD, + 0xBE, 0xD2, 0xA9, 0xA5, 0xAF, 0x9C, 0xC5, 0x23, 0x2A, 0xF7, 0x3C, 0x21, + 0x6C, 0xBD, 0xAF, 0x8F, 0x4E, 0xC5, 0x3A, 0xB2, 0xF3, 0x34, 0x12, 0xFC, + 0xDF, 0x80, 0x1A, 0x49, 0xA4, 0xD4, 0xA9, 0x95, 0xF7, 0x9E, 0x89, 0x5E, + 0xA2, 0x89, 0xAC, 0x94, 0xCB, 0xA8, 0x68, 0x9B, 0xAF, 0x8A, 0x65, 0x27, + 0xCD, 0x89, 0xEE, 0xDD, 0x8C, 0xB5, 0x6B, 0x29, 0x70, 0x43, 0xA0, 0x69, + 0x0B, 0xE4, 0xB9, 0x0F +}; + +static const unsigned char TA68_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA69_DN[] = { + 0x30, 0x74, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x45, 0x43, 0x2D, 0x33, 0x38, 0x34, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA69_EC_Q[] = { + 0x04, 0xC4, 0x28, 0x8E, 0xAB, 0x18, 0x5B, 0x6A, 0xBE, 0x6E, 0x64, 0x37, + 0x63, 0xE4, 0xCD, 0xEC, 0xAB, 0x3A, 0xF7, 0xCC, 0xA1, 0xB8, 0x0E, 0x82, + 0x49, 0xD7, 0x86, 0x29, 0x9F, 0xA1, 0x94, 0xF2, 0xE3, 0x60, 0x78, 0x98, + 0x81, 0x78, 0x06, 0x4D, 0xF2, 0xEC, 0x9A, 0x0E, 0x57, 0x60, 0x83, 0x9F, + 0xB4, 0xE6, 0x17, 0x2F, 0x1A, 0xB3, 0x5D, 0x02, 0x5B, 0x89, 0x23, 0x3C, + 0xC2, 0x11, 0x05, 0x2A, 0xA7, 0x88, 0x13, 0x18, 0xF3, 0x50, 0x84, 0xD7, + 0xBD, 0x34, 0x2C, 0x27, 0x89, 0x55, 0xFF, 0xCE, 0x4C, 0xE7, 0xDF, 0xA6, + 0x1F, 0x28, 0xC4, 0xF0, 0x54, 0xC3, 0xB9, 0x7C, 0xB7, 0x53, 0xAD, 0xEB, + 0xC2 +}; + +static const unsigned char TA70_DN[] = { + 0x30, 0x81, 0xBE, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x32, 0x30, + 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, + 0x32 +}; + +static const unsigned char TA70_RSA_N[] = { + 0xBA, 0x84, 0xB6, 0x72, 0xDB, 0x9E, 0x0C, 0x6B, 0xE2, 0x99, 0xE9, 0x30, + 0x01, 0xA7, 0x76, 0xEA, 0x32, 0xB8, 0x95, 0x41, 0x1A, 0xC9, 0xDA, 0x61, + 0x4E, 0x58, 0x72, 0xCF, 0xFE, 0xF6, 0x82, 0x79, 0xBF, 0x73, 0x61, 0x06, + 0x0A, 0xA5, 0x27, 0xD8, 0xB3, 0x5F, 0xD3, 0x45, 0x4E, 0x1C, 0x72, 0xD6, + 0x4E, 0x32, 0xF2, 0x72, 0x8A, 0x0F, 0xF7, 0x83, 0x19, 0xD0, 0x6A, 0x80, + 0x80, 0x00, 0x45, 0x1E, 0xB0, 0xC7, 0xE7, 0x9A, 0xBF, 0x12, 0x57, 0x27, + 0x1C, 0xA3, 0x68, 0x2F, 0x0A, 0x87, 0xBD, 0x6A, 0x6B, 0x0E, 0x5E, 0x65, + 0xF3, 0x1C, 0x77, 0xD5, 0xD4, 0x85, 0x8D, 0x70, 0x21, 0xB4, 0xB3, 0x32, + 0xE7, 0x8B, 0xA2, 0xD5, 0x86, 0x39, 0x02, 0xB1, 0xB8, 0xD2, 0x47, 0xCE, + 0xE4, 0xC9, 0x49, 0xC4, 0x3B, 0xA7, 0xDE, 0xFB, 0x54, 0x7D, 0x57, 0xBE, + 0xF0, 0xE8, 0x6E, 0xC2, 0x79, 0xB2, 0x3A, 0x0B, 0x55, 0xE2, 0x50, 0x98, + 0x16, 0x32, 0x13, 0x5C, 0x2F, 0x78, 0x56, 0xC1, 0xC2, 0x94, 0xB3, 0xF2, + 0x5A, 0xE4, 0x27, 0x9A, 0x9F, 0x24, 0xD7, 0xC6, 0xEC, 0xD0, 0x9B, 0x25, + 0x82, 0xE3, 0xCC, 0xC2, 0xC4, 0x45, 0xC5, 0x8C, 0x97, 0x7A, 0x06, 0x6B, + 0x2A, 0x11, 0x9F, 0xA9, 0x0A, 0x6E, 0x48, 0x3B, 0x6F, 0xDB, 0xD4, 0x11, + 0x19, 0x42, 0xF7, 0x8F, 0x07, 0xBF, 0xF5, 0x53, 0x5F, 0x9C, 0x3E, 0xF4, + 0x17, 0x2C, 0xE6, 0x69, 0xAC, 0x4E, 0x32, 0x4C, 0x62, 0x77, 0xEA, 0xB7, + 0xE8, 0xE5, 0xBB, 0x34, 0xBC, 0x19, 0x8B, 0xAE, 0x9C, 0x51, 0xE7, 0xB7, + 0x7E, 0xB5, 0x53, 0xB1, 0x33, 0x22, 0xE5, 0x6D, 0xCF, 0x70, 0x3C, 0x1A, + 0xFA, 0xE2, 0x9B, 0x67, 0xB6, 0x83, 0xF4, 0x8D, 0xA5, 0xAF, 0x62, 0x4C, + 0x4D, 0xE0, 0x58, 0xAC, 0x64, 0x34, 0x12, 0x03, 0xF8, 0xB6, 0x8D, 0x94, + 0x63, 0x24, 0xA4, 0x71 +}; + +static const unsigned char TA70_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA71_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x54, 0x57, 0x43, 0x41, 0x20, 0x43, 0x59, 0x42, + 0x45, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA71_RSA_N[] = { + 0xC6, 0xF8, 0xCA, 0x1E, 0xD9, 0x09, 0x20, 0x7E, 0x1D, 0x6C, 0x4E, 0xCE, + 0x8F, 0xE3, 0x47, 0x33, 0x44, 0x9C, 0xC7, 0xC9, 0x69, 0xAA, 0x3A, 0x5B, + 0x78, 0xEE, 0x70, 0xD2, 0x92, 0xF8, 0x04, 0xB3, 0x52, 0x52, 0x1D, 0x67, + 0x72, 0x28, 0xA1, 0xDF, 0x8B, 0x5D, 0x95, 0x0A, 0xFE, 0xEA, 0xCD, 0xED, + 0xF7, 0x29, 0xCE, 0xF0, 0x6F, 0x7F, 0xAC, 0xCD, 0x3D, 0xEF, 0xB3, 0x1C, + 0x45, 0x6A, 0xF7, 0x28, 0x90, 0xF1, 0x61, 0x57, 0xC5, 0x0C, 0xC4, 0xA3, + 0x50, 0x5D, 0xDE, 0xD4, 0xB5, 0xCB, 0x19, 0xCA, 0x80, 0xB9, 0x75, 0xCE, + 0x29, 0xCE, 0xD2, 0x85, 0x22, 0xEC, 0x02, 0x63, 0xCC, 0x44, 0x30, 0x20, + 0xDA, 0xEA, 0x91, 0x5B, 0x56, 0xE6, 0x1D, 0x1C, 0xD5, 0x9D, 0x66, 0xC7, + 0x3F, 0xDF, 0x86, 0xCA, 0x4B, 0x53, 0xC4, 0xD9, 0x8D, 0xB2, 0x1D, 0xEA, + 0xF8, 0xDC, 0x27, 0x53, 0xA3, 0x47, 0xE1, 0x61, 0xCC, 0x7D, 0xB5, 0xB0, + 0xF8, 0xEE, 0x73, 0x91, 0xC5, 0xCE, 0x73, 0x6F, 0xCE, 0xEE, 0x10, 0x1F, + 0x1A, 0x06, 0xCF, 0xE9, 0x27, 0x60, 0xC5, 0x4F, 0x19, 0xE4, 0xEB, 0xCE, + 0x22, 0x26, 0x45, 0xD7, 0x60, 0x99, 0xDD, 0xCE, 0x4F, 0x37, 0xE0, 0x7F, + 0xE7, 0x63, 0xAD, 0xB0, 0xB8, 0x59, 0xB8, 0xD0, 0x06, 0x68, 0x35, 0x60, + 0xD3, 0x36, 0xAE, 0x71, 0x43, 0x04, 0xF1, 0x69, 0x65, 0x78, 0x7C, 0xF3, + 0x1F, 0xF3, 0xCA, 0x28, 0x9F, 0x5A, 0x20, 0x95, 0x66, 0xB4, 0xCD, 0xB7, + 0xEE, 0x8F, 0x78, 0xA4, 0x45, 0x18, 0xE9, 0x26, 0x2F, 0x8D, 0x9B, 0x29, + 0x28, 0xB1, 0xA4, 0xB7, 0x3A, 0x6D, 0xB9, 0xD4, 0x1C, 0x38, 0x72, 0x45, + 0x58, 0xB1, 0x5E, 0xEB, 0xF0, 0x28, 0x9B, 0xB7, 0x82, 0xCA, 0xFD, 0xCF, + 0xD6, 0x33, 0x0F, 0x9F, 0xFB, 0x97, 0x9E, 0xB1, 0x1C, 0x9C, 0x9E, 0xEA, + 0x5F, 0x5E, 0xDB, 0xAA, 0xDD, 0x54, 0xE9, 0x30, 0x21, 0x28, 0x6D, 0x8E, + 0x79, 0xF3, 0x75, 0x92, 0x8C, 0x26, 0xFE, 0xDC, 0xC5, 0xF6, 0xC3, 0xB0, + 0xDF, 0x44, 0x59, 0x43, 0xA3, 0xB6, 0x03, 0x28, 0xF6, 0x08, 0x30, 0xAA, + 0x0D, 0x33, 0xE1, 0xEF, 0x9C, 0xA9, 0x07, 0x22, 0xE3, 0x59, 0x5B, 0x40, + 0x8F, 0xDA, 0x88, 0xB7, 0x69, 0x08, 0xA8, 0xB7, 0x23, 0x2E, 0x44, 0x09, + 0x59, 0x37, 0x5B, 0xC7, 0xE3, 0x17, 0xF2, 0x22, 0xEB, 0x6E, 0x39, 0x52, + 0xC5, 0xDE, 0x54, 0xA7, 0x98, 0xC9, 0x4B, 0x20, 0x95, 0xDC, 0x46, 0x89, + 0x5F, 0xB4, 0x12, 0xF9, 0x85, 0x29, 0x8E, 0xEB, 0xC8, 0x27, 0x15, 0x20, + 0xC0, 0x4B, 0xD4, 0xCC, 0x7C, 0x0C, 0x6C, 0x34, 0x0C, 0x26, 0x9B, 0x26, + 0x31, 0xA6, 0x3C, 0xA7, 0xF6, 0xD9, 0xD0, 0x4B, 0xA2, 0x64, 0xFF, 0x3B, + 0x99, 0x41, 0x72, 0xC1, 0xE0, 0x70, 0x97, 0xF1, 0x24, 0xBB, 0x2B, 0xC4, + 0x74, 0x22, 0xB1, 0xAC, 0x6B, 0x22, 0x32, 0x24, 0xD3, 0x78, 0x2A, 0xC0, + 0xC0, 0xA1, 0x2F, 0xF1, 0x52, 0x05, 0xC9, 0x3F, 0xEF, 0x76, 0x66, 0xE2, + 0x45, 0xD8, 0x0D, 0x3D, 0xAD, 0x95, 0xC8, 0xC7, 0x89, 0x26, 0xC8, 0x0F, + 0xAE, 0xA7, 0x03, 0x2E, 0xFB, 0xC1, 0x5F, 0xFA, 0x20, 0xE1, 0x70, 0xAD, + 0xB0, 0x65, 0x20, 0x37, 0x33, 0x60, 0xB0, 0xD5, 0xAF, 0xD7, 0x0C, 0x1C, + 0xC2, 0x90, 0x70, 0xD7, 0x4A, 0x18, 0xBC, 0x7E, 0x01, 0xB0, 0xB0, 0xEB, + 0x15, 0x1E, 0x44, 0x06, 0xCD, 0xA4, 0x4F, 0xE8, 0x0C, 0xD1, 0xC3, 0x20, + 0x10, 0xE1, 0x54, 0x65, 0x9E, 0xB6, 0x51, 0xD0, 0x1A, 0x76, 0x6B, 0x42, + 0x5A, 0x58, 0x76, 0x34, 0xEA, 0xB7, 0x37, 0x19, 0xAE, 0x2E, 0x75, 0xF9, + 0x96, 0xE5, 0xC1, 0x59, 0xF7, 0x94, 0x57, 0x29, 0x25, 0x8D, 0x3A, 0x4C, + 0xAB, 0x4D, 0x9A, 0x41, 0xD0, 0x5F, 0x26, 0x03 +}; + +static const unsigned char TA71_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA72_DN[] = { + 0x30, 0x38, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x49, 0x5A, 0x45, 0x4E, 0x50, 0x45, 0x20, 0x53, 0x2E, 0x41, + 0x2E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0A, + 0x49, 0x7A, 0x65, 0x6E, 0x70, 0x65, 0x2E, 0x63, 0x6F, 0x6D +}; + +static const unsigned char TA72_RSA_N[] = { + 0xC9, 0xD3, 0x7A, 0xCA, 0x0F, 0x1E, 0xAC, 0xA7, 0x86, 0xE8, 0x16, 0x65, + 0x6A, 0xB1, 0xC2, 0x1B, 0x45, 0x32, 0x71, 0x95, 0xD9, 0xFE, 0x10, 0x5B, + 0xCC, 0xAF, 0xE7, 0xA5, 0x79, 0x01, 0x8F, 0x89, 0xC3, 0xCA, 0xF2, 0x55, + 0x71, 0xF7, 0x77, 0xBE, 0x77, 0x94, 0xF3, 0x72, 0xA4, 0x2C, 0x44, 0xD8, + 0x9E, 0x92, 0x9B, 0x14, 0x3A, 0xA1, 0xE7, 0x24, 0x90, 0x0A, 0x0A, 0x56, + 0x8E, 0xC5, 0xD8, 0x26, 0x94, 0xE1, 0xD9, 0x48, 0xE1, 0x2D, 0x3E, 0xDA, + 0x0A, 0x72, 0xDD, 0xA3, 0x99, 0x15, 0xDA, 0x81, 0xA2, 0x87, 0xF4, 0x7B, + 0x6E, 0x26, 0x77, 0x89, 0x58, 0xAD, 0xD6, 0xEB, 0x0C, 0xB2, 0x41, 0x7A, + 0x73, 0x6E, 0x6D, 0xDB, 0x7A, 0x78, 0x41, 0xE9, 0x08, 0x88, 0x12, 0x7E, + 0x87, 0x2E, 0x66, 0x11, 0x63, 0x6C, 0x54, 0xFB, 0x3C, 0x9D, 0x72, 0xC0, + 0xBC, 0x2E, 0xFF, 0xC2, 0xB7, 0xDD, 0x0D, 0x76, 0xE3, 0x3A, 0xD7, 0xF7, + 0xB4, 0x68, 0xBE, 0xA2, 0xF5, 0xE3, 0x81, 0x6E, 0xC1, 0x46, 0x6F, 0x5D, + 0x8D, 0xE0, 0x4D, 0xC6, 0x54, 0x55, 0x89, 0x1A, 0x33, 0x31, 0x0A, 0xB1, + 0x57, 0xB9, 0xA3, 0x8A, 0x98, 0xC3, 0xEC, 0x3B, 0x34, 0xC5, 0x95, 0x41, + 0x69, 0x7E, 0x75, 0xC2, 0x3C, 0x20, 0xC5, 0x61, 0xBA, 0x51, 0x47, 0xA0, + 0x20, 0x90, 0x93, 0xA1, 0x90, 0x4B, 0xF3, 0x4E, 0x7C, 0x85, 0x45, 0x54, + 0x9A, 0xD1, 0x05, 0x26, 0x41, 0xB0, 0xB5, 0x4D, 0x1D, 0x33, 0xBE, 0xC4, + 0x03, 0xC8, 0x25, 0x7C, 0xC1, 0x70, 0xDB, 0x3B, 0xF4, 0x09, 0x2D, 0x54, + 0x27, 0x48, 0xAC, 0x2F, 0xE1, 0xC4, 0xAC, 0x3E, 0xC8, 0xCB, 0x92, 0x4C, + 0x53, 0x39, 0x37, 0x23, 0xEC, 0xD3, 0x01, 0xF9, 0xE0, 0x09, 0x44, 0x4D, + 0x4D, 0x64, 0xC0, 0xE1, 0x0D, 0x5A, 0x87, 0x22, 0xBC, 0xAD, 0x1B, 0xA3, + 0xFE, 0x26, 0xB5, 0x15, 0xF3, 0xA7, 0xFC, 0x84, 0x19, 0xE9, 0xEC, 0xA1, + 0x88, 0xB4, 0x44, 0x69, 0x84, 0x83, 0xF3, 0x89, 0xD1, 0x74, 0x06, 0xA9, + 0xCC, 0x0B, 0xD6, 0xC2, 0xDE, 0x27, 0x85, 0x50, 0x26, 0xCA, 0x17, 0xB8, + 0xC9, 0x7A, 0x87, 0x56, 0x2C, 0x1A, 0x01, 0x1E, 0x6C, 0xBE, 0x13, 0xAD, + 0x10, 0xAC, 0xB5, 0x24, 0xF5, 0x38, 0x91, 0xA1, 0xD6, 0x4B, 0xDA, 0xF1, + 0xBB, 0xD2, 0xDE, 0x47, 0xB5, 0xF1, 0xBC, 0x81, 0xF6, 0x59, 0x6B, 0xCF, + 0x19, 0x53, 0xE9, 0x8D, 0x15, 0xCB, 0x4A, 0xCB, 0xA9, 0x6F, 0x44, 0xE5, + 0x1B, 0x41, 0xCF, 0xE1, 0x86, 0xA7, 0xCA, 0xD0, 0x6A, 0x9F, 0xBC, 0x4C, + 0x8D, 0x06, 0x33, 0x5A, 0xA2, 0x85, 0xE5, 0x90, 0x35, 0xA0, 0x62, 0x5C, + 0x16, 0x4E, 0xF0, 0xE3, 0xA2, 0xFA, 0x03, 0x1A, 0xB4, 0x2C, 0x71, 0xB3, + 0x58, 0x2C, 0xDE, 0x7B, 0x0B, 0xDB, 0x1A, 0x0F, 0xEB, 0xDE, 0x21, 0x1F, + 0x06, 0x77, 0x06, 0x03, 0xB0, 0xC9, 0xEF, 0x99, 0xFC, 0xC0, 0xB9, 0x4F, + 0x0B, 0x86, 0x28, 0xFE, 0xD2, 0xB9, 0xEA, 0xE3, 0xDA, 0xA5, 0xC3, 0x47, + 0x69, 0x12, 0xE0, 0xDB, 0xF0, 0xF6, 0x19, 0x8B, 0xED, 0x7B, 0x70, 0xD7, + 0x02, 0xD6, 0xED, 0x87, 0x18, 0x28, 0x2C, 0x04, 0x24, 0x4C, 0x77, 0xE4, + 0x48, 0x8A, 0x1A, 0xC6, 0x3B, 0x9A, 0xD4, 0x0F, 0xCA, 0xFA, 0x75, 0xD2, + 0x01, 0x40, 0x5A, 0x8D, 0x79, 0xBF, 0x8B, 0xCF, 0x4B, 0xCF, 0xAA, 0x16, + 0xC1, 0x95, 0xE4, 0xAD, 0x4C, 0x8A, 0x3E, 0x17, 0x91, 0xD4, 0xB1, 0x62, + 0xE5, 0x82, 0xE5, 0x80, 0x04, 0xA4, 0x03, 0x7E, 0x8D, 0xBF, 0xDA, 0x7F, + 0xA2, 0x0F, 0x97, 0x4F, 0x0C, 0xD3, 0x0D, 0xFB, 0xD7, 0xD1, 0xE5, 0x72, + 0x7E, 0x1C, 0xC8, 0x77, 0xFF, 0x5B, 0x9A, 0x0F, 0xB7, 0xAE, 0x05, 0x46, + 0xE5, 0xF1, 0xA8, 0x16, 0xEC, 0x47, 0xA4, 0x17 +}; + +static const unsigned char TA72_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA73_DN[] = { + 0x30, 0x7E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, 0x65, + 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, + 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, + 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, 0x65, + 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA73_RSA_N[] = { + 0xE3, 0xFB, 0x7D, 0xA3, 0x72, 0xBA, 0xC2, 0xF0, 0xC9, 0x14, 0x87, 0xF5, + 0x6B, 0x01, 0x4E, 0xE1, 0x6E, 0x40, 0x07, 0xBA, 0x6D, 0x27, 0x5D, 0x7F, + 0xF7, 0x5B, 0x2D, 0xB3, 0x5A, 0xC7, 0x51, 0x5F, 0xAB, 0xA4, 0x32, 0xA6, + 0x61, 0x87, 0xB6, 0x6E, 0x0F, 0x86, 0xD2, 0x30, 0x02, 0x97, 0xF8, 0xD7, + 0x69, 0x57, 0xA1, 0x18, 0x39, 0x5D, 0x6A, 0x64, 0x79, 0xC6, 0x01, 0x59, + 0xAC, 0x3C, 0x31, 0x4A, 0x38, 0x7C, 0xD2, 0x04, 0xD2, 0x4B, 0x28, 0xE8, + 0x20, 0x5F, 0x3B, 0x07, 0xA2, 0xCC, 0x4D, 0x73, 0xDB, 0xF3, 0xAE, 0x4F, + 0xC7, 0x56, 0xD5, 0x5A, 0xA7, 0x96, 0x89, 0xFA, 0xF3, 0xAB, 0x68, 0xD4, + 0x23, 0x86, 0x59, 0x27, 0xCF, 0x09, 0x27, 0xBC, 0xAC, 0x6E, 0x72, 0x83, + 0x1C, 0x30, 0x72, 0xDF, 0xE0, 0xA2, 0xE9, 0xD2, 0xE1, 0x74, 0x75, 0x19, + 0xBD, 0x2A, 0x9E, 0x7B, 0x15, 0x54, 0x04, 0x1B, 0xD7, 0x43, 0x39, 0xAD, + 0x55, 0x28, 0xC5, 0xE2, 0x1A, 0xBB, 0xF4, 0xC0, 0xE4, 0xAE, 0x38, 0x49, + 0x33, 0xCC, 0x76, 0x85, 0x9F, 0x39, 0x45, 0xD2, 0xA4, 0x9E, 0xF2, 0x12, + 0x8C, 0x51, 0xF8, 0x7C, 0xE4, 0x2D, 0x7F, 0xF5, 0xAC, 0x5F, 0xEB, 0x16, + 0x9F, 0xB1, 0x2D, 0xD1, 0xBA, 0xCC, 0x91, 0x42, 0x77, 0x4C, 0x25, 0xC9, + 0x90, 0x38, 0x6F, 0xDB, 0xF0, 0xCC, 0xFB, 0x8E, 0x1E, 0x97, 0x59, 0x3E, + 0xD5, 0x60, 0x4E, 0xE6, 0x05, 0x28, 0xED, 0x49, 0x79, 0x13, 0x4B, 0xBA, + 0x48, 0xDB, 0x2F, 0xF9, 0x72, 0xD3, 0x39, 0xCA, 0xFE, 0x1F, 0xD8, 0x34, + 0x72, 0xF5, 0xB4, 0x40, 0xCF, 0x31, 0x01, 0xC3, 0xEC, 0xDE, 0x11, 0x2D, + 0x17, 0x5D, 0x1F, 0xB8, 0x50, 0xD1, 0x5E, 0x19, 0xA7, 0x69, 0xDE, 0x07, + 0x33, 0x28, 0xCA, 0x50, 0x95, 0xF9, 0xA7, 0x54, 0xCB, 0x54, 0x86, 0x50, + 0x45, 0xA9, 0xF9, 0x49 +}; + +static const unsigned char TA73_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA74_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x43, 0x33 +}; + +static const unsigned char TA74_EC_Q[] = { + 0x04, 0xFD, 0xA5, 0x61, 0xAE, 0x7B, 0x26, 0x10, 0x1D, 0xE9, 0xB7, 0x22, + 0x30, 0xAE, 0x06, 0xF4, 0x81, 0xB3, 0xB1, 0x42, 0x71, 0x95, 0x39, 0xBC, + 0xD3, 0x52, 0xE3, 0xAF, 0xAF, 0xF9, 0xF2, 0x97, 0x35, 0x92, 0x36, 0x46, + 0x0E, 0x87, 0x95, 0x8D, 0xB9, 0x39, 0x5A, 0xE9, 0xBB, 0xDF, 0xD0, 0xFE, + 0xC8, 0x07, 0x41, 0x3C, 0xBB, 0x55, 0x6F, 0x83, 0xA3, 0x6A, 0xFB, 0x62, + 0xB0, 0x81, 0x89, 0x02, 0x70, 0x7D, 0x48, 0xC5, 0x4A, 0xE3, 0xE9, 0x22, + 0x54, 0x22, 0x4D, 0x93, 0xBB, 0x42, 0x0C, 0xAF, 0x77, 0x9C, 0x23, 0xA6, + 0x7D, 0xD7, 0x61, 0x11, 0xCE, 0x65, 0xC7, 0xF8, 0x7F, 0xFE, 0xF5, 0xF2, + 0xA9 +}; + +static const unsigned char TA75_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x53, 0x65, 0x63, 0x74, 0x6F, 0x72, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA75_RSA_N[] = { + 0xB6, 0x22, 0x94, 0xFC, 0xA4, 0x48, 0xAF, 0xE8, 0x47, 0x6B, 0x0A, 0xFB, + 0x27, 0x76, 0xE4, 0xF2, 0x3F, 0x8A, 0x3B, 0x7A, 0x4A, 0x2C, 0x31, 0x2A, + 0x8C, 0x8D, 0xB0, 0xA9, 0xC3, 0x31, 0x6B, 0xA8, 0x77, 0x76, 0x84, 0x26, + 0xB6, 0xAC, 0x81, 0x42, 0x0D, 0x08, 0xEB, 0x55, 0x58, 0xBB, 0x7A, 0xF8, + 0xBC, 0x65, 0x7D, 0xF2, 0xA0, 0x6D, 0x8B, 0xA8, 0x47, 0xE9, 0x62, 0x76, + 0x1E, 0x11, 0xEE, 0x08, 0x14, 0xD1, 0xB2, 0x44, 0x16, 0xF4, 0xEA, 0xD0, + 0xFA, 0x1E, 0x2F, 0x5E, 0xDB, 0xCB, 0x73, 0x41, 0xAE, 0xBC, 0x00, 0xB0, + 0x4A, 0x2B, 0x40, 0xB2, 0xAC, 0xE1, 0x3B, 0x4B, 0xC2, 0x2D, 0x9D, 0xE4, + 0xA1, 0x9B, 0xEC, 0x1A, 0x3A, 0x1E, 0xF0, 0x08, 0xB3, 0xD0, 0xE4, 0x24, + 0x35, 0x07, 0x9F, 0x9C, 0xB4, 0xC9, 0x52, 0x6D, 0xDB, 0x07, 0xCA, 0x8F, + 0xB5, 0x5B, 0xF0, 0x83, 0xF3, 0x4F, 0xC7, 0x2D, 0xA5, 0xC8, 0xAD, 0xCB, + 0x95, 0x20, 0xA4, 0x31, 0x28, 0x57, 0x58, 0x5A, 0xE4, 0x8D, 0x1B, 0x9A, + 0xAB, 0x9E, 0x0D, 0x0C, 0xF2, 0x0A, 0x33, 0x39, 0x22, 0x39, 0x0A, 0x97, + 0x2E, 0xF3, 0x53, 0x77, 0xB9, 0x44, 0x45, 0xFD, 0x84, 0xCB, 0x36, 0x20, + 0x81, 0x59, 0x2D, 0x9A, 0x6F, 0x6D, 0x48, 0x48, 0x61, 0xCA, 0x4C, 0xDF, + 0x53, 0xD1, 0xAF, 0x52, 0xBC, 0x44, 0x9F, 0xAB, 0x2F, 0x6B, 0x83, 0x72, + 0xEF, 0x75, 0x80, 0xDA, 0x06, 0x33, 0x1B, 0x5D, 0xC8, 0xDA, 0x63, 0xC6, + 0x4D, 0xCD, 0xAC, 0x66, 0x31, 0xCD, 0xD1, 0xDE, 0x3E, 0x87, 0x10, 0x36, + 0xE1, 0xB9, 0xA4, 0x7A, 0xEF, 0x60, 0x50, 0xB2, 0xCB, 0xCA, 0xA6, 0x56, + 0xE0, 0x37, 0xAF, 0xAB, 0x34, 0x13, 0x39, 0x25, 0xE8, 0x39, 0x66, 0xE4, + 0x98, 0x7A, 0xAA, 0x12, 0x98, 0x9C, 0x59, 0x66, 0x86, 0x3E, 0xAD, 0xF1, + 0xB0, 0xCA, 0x3E, 0x06, 0x0F, 0x7B, 0xF0, 0x11, 0x4B, 0x37, 0xA0, 0x44, + 0x6D, 0x7B, 0xCB, 0xA8, 0x8C, 0x71, 0xF4, 0xD5, 0xB5, 0x91, 0x36, 0xCC, + 0xF0, 0x15, 0xC6, 0x2B, 0xDE, 0x51, 0x17, 0xB1, 0x97, 0x4C, 0x50, 0x3D, + 0xB1, 0x95, 0x59, 0x7C, 0x05, 0x7D, 0x2D, 0x21, 0xD5, 0x00, 0xBF, 0x01, + 0x67, 0xA2, 0x5E, 0x7B, 0xA6, 0x5C, 0xF2, 0xF7, 0x22, 0xF1, 0x90, 0x0D, + 0x93, 0xDB, 0xAA, 0x44, 0x51, 0x66, 0xCC, 0x7D, 0x76, 0x03, 0xEB, 0x6A, + 0xA8, 0x2A, 0x38, 0x19, 0x97, 0x76, 0x0D, 0x6B, 0x8A, 0x61, 0xF9, 0xBC, + 0xF6, 0xEE, 0x76, 0xFD, 0x70, 0x2B, 0xDD, 0x29, 0x3C, 0xF8, 0x0A, 0x1E, + 0x5B, 0x42, 0x1C, 0x8B, 0x56, 0x2F, 0x55, 0x1B, 0x1C, 0xA1, 0x2E, 0xB5, + 0xC7, 0x16, 0xE6, 0xF8, 0xAA, 0x3C, 0x92, 0x8E, 0x69, 0xB6, 0x01, 0xC1, + 0xB5, 0x86, 0x9D, 0x89, 0x0F, 0x0B, 0x38, 0x94, 0x54, 0xE8, 0xEA, 0xDC, + 0x9E, 0x3D, 0x25, 0xBC, 0x53, 0x26, 0xED, 0xD5, 0xAB, 0x39, 0xAA, 0xC5, + 0x40, 0x4C, 0x54, 0xAB, 0xB2, 0xB4, 0xD9, 0xD9, 0xF8, 0xD7, 0x72, 0xDB, + 0x1C, 0xBC, 0x6D, 0xBD, 0x65, 0x5F, 0xEF, 0x88, 0x35, 0x2A, 0x66, 0x2F, + 0xEE, 0xF6, 0xB3, 0x65, 0xF0, 0x33, 0x8D, 0x7C, 0x98, 0x41, 0x69, 0x46, + 0x0F, 0x43, 0x1C, 0x69, 0xFA, 0x9B, 0xB5, 0xD0, 0x61, 0x6A, 0xCD, 0xCA, + 0x4B, 0xD9, 0x4C, 0x90, 0x46, 0xAB, 0x15, 0x59, 0xA1, 0x47, 0x54, 0x29, + 0x2E, 0x83, 0x28, 0x5F, 0x1C, 0xC2, 0xA2, 0xAB, 0x72, 0x17, 0x00, 0x06, + 0x8E, 0x45, 0xEC, 0x8B, 0xE2, 0x33, 0x3D, 0x7F, 0xDA, 0x19, 0x44, 0xE4, + 0x62, 0x72, 0xC3, 0xDF, 0x22, 0xC6, 0xF2, 0x56, 0xD4, 0xDD, 0x5F, 0x95, + 0x72, 0xED, 0x6D, 0x5F, 0xF7, 0x48, 0x03, 0x5B, 0xFD, 0xC5, 0x2A, 0xA0, + 0xF6, 0x73, 0x23, 0x84, 0x10, 0x1B, 0x01, 0xE7 +}; + +static const unsigned char TA75_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA76_DN[] = { + 0x30, 0x81, 0x8F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, + 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA76_RSA_N[] = { + 0xBD, 0xED, 0xC1, 0x03, 0xFC, 0xF6, 0x8F, 0xFC, 0x02, 0xB1, 0x6F, 0x5B, + 0x9F, 0x48, 0xD9, 0x9D, 0x79, 0xE2, 0xA2, 0xB7, 0x03, 0x61, 0x56, 0x18, + 0xC3, 0x47, 0xB6, 0xD7, 0xCA, 0x3D, 0x35, 0x2E, 0x89, 0x43, 0xF7, 0xA1, + 0x69, 0x9B, 0xDE, 0x8A, 0x1A, 0xFD, 0x13, 0x20, 0x9C, 0xB4, 0x49, 0x77, + 0x32, 0x29, 0x56, 0xFD, 0xB9, 0xEC, 0x8C, 0xDD, 0x22, 0xFA, 0x72, 0xDC, + 0x27, 0x61, 0x97, 0xEE, 0xF6, 0x5A, 0x84, 0xEC, 0x6E, 0x19, 0xB9, 0x89, + 0x2C, 0xDC, 0x84, 0x5B, 0xD5, 0x74, 0xFB, 0x6B, 0x5F, 0xC5, 0x89, 0xA5, + 0x10, 0x52, 0x89, 0x46, 0x55, 0xF4, 0xB8, 0x75, 0x1C, 0xE6, 0x7F, 0xE4, + 0x54, 0xAE, 0x4B, 0xF8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xF8, 0x17, 0x71, + 0x59, 0xEB, 0x1E, 0x28, 0x07, 0x74, 0xC5, 0x9D, 0x48, 0xBE, 0x6C, 0xB4, + 0xF4, 0xA4, 0xB0, 0xF3, 0x64, 0x37, 0x79, 0x92, 0xC0, 0xEC, 0x46, 0x5E, + 0x7F, 0xE1, 0x6D, 0x53, 0x4C, 0x62, 0xAF, 0xCD, 0x1F, 0x0B, 0x63, 0xBB, + 0x3A, 0x9D, 0xFB, 0xFC, 0x79, 0x00, 0x98, 0x61, 0x74, 0xCF, 0x26, 0x82, + 0x40, 0x63, 0xF3, 0xB2, 0x72, 0x6A, 0x19, 0x0D, 0x99, 0xCA, 0xD4, 0x0E, + 0x75, 0xCC, 0x37, 0xFB, 0x8B, 0x89, 0xC1, 0x59, 0xF1, 0x62, 0x7F, 0x5F, + 0xB3, 0x5F, 0x65, 0x30, 0xF8, 0xA7, 0xB7, 0x4D, 0x76, 0x5A, 0x1E, 0x76, + 0x5E, 0x34, 0xC0, 0xE8, 0x96, 0x56, 0x99, 0x8A, 0xB3, 0xF0, 0x7F, 0xA4, + 0xCD, 0xBD, 0xDC, 0x32, 0x31, 0x7C, 0x91, 0xCF, 0xE0, 0x5F, 0x11, 0xF8, + 0x6B, 0xAA, 0x49, 0x5C, 0xD1, 0x99, 0x94, 0xD1, 0xA2, 0xE3, 0x63, 0x5B, + 0x09, 0x76, 0xB5, 0x56, 0x62, 0xE1, 0x4B, 0x74, 0x1D, 0x96, 0xD4, 0x26, + 0xD4, 0x08, 0x04, 0x59, 0xD0, 0x98, 0x0E, 0x0E, 0xE6, 0xDE, 0xFC, 0xC3, + 0xEC, 0x1F, 0x90, 0xF1 +}; + +static const unsigned char TA76_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA77_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, + 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA77_EC_Q[] = { + 0x04, 0x38, 0x08, 0xFE, 0xB1, 0xA0, 0x96, 0xD2, 0x7A, 0xAC, 0xAF, 0x49, + 0x3A, 0xD0, 0xC0, 0xE0, 0xC3, 0x3B, 0x28, 0xAA, 0xF1, 0x72, 0x6D, 0x65, + 0x00, 0x47, 0x88, 0x84, 0xFC, 0x9A, 0x26, 0x6B, 0xAA, 0x4B, 0xBA, 0x6C, + 0x04, 0x0A, 0x88, 0x5E, 0x17, 0xF2, 0x55, 0x87, 0xFC, 0x30, 0xB0, 0x34, + 0xE2, 0x34, 0x58, 0x57, 0x1A, 0x84, 0x53, 0xE9, 0x30, 0xD9, 0xA9, 0xF2, + 0x96, 0x74, 0xC3, 0x51, 0x1F, 0x58, 0x49, 0x31, 0xCC, 0x98, 0x4E, 0x60, + 0x11, 0x87, 0x75, 0xD3, 0x72, 0x94, 0x90, 0x4F, 0x9B, 0x10, 0x25, 0x2A, + 0xA8, 0x78, 0x2D, 0xBE, 0x90, 0x41, 0x58, 0x90, 0x15, 0x72, 0xA7, 0xA1, + 0xB7 +}; + +static const unsigned char TA78_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x41, 0x47, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x16, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, + 0x6F, 0x6C, 0x64, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA78_RSA_N[] = { + 0xAF, 0xE4, 0xEE, 0x7E, 0x8B, 0x24, 0x0E, 0x12, 0x6E, 0xA9, 0x50, 0x2D, + 0x16, 0x44, 0x3B, 0x92, 0x92, 0x5C, 0xCA, 0xB8, 0x5D, 0x84, 0x92, 0x42, + 0x13, 0x2A, 0xBC, 0x65, 0x57, 0x82, 0x40, 0x3E, 0x57, 0x24, 0xCD, 0x50, + 0x8B, 0x25, 0x2A, 0xB7, 0x6F, 0xFC, 0xEF, 0xA2, 0xD0, 0xC0, 0x1F, 0x02, + 0x24, 0x4A, 0x13, 0x96, 0x8F, 0x23, 0x13, 0xE6, 0x28, 0x58, 0x00, 0xA3, + 0x47, 0xC7, 0x06, 0xA7, 0x84, 0x23, 0x2B, 0xBB, 0xBD, 0x96, 0x2B, 0x7F, + 0x55, 0xCC, 0x8B, 0xC1, 0x57, 0x1F, 0x0E, 0x62, 0x65, 0x0F, 0xDD, 0x3D, + 0x56, 0x8A, 0x73, 0xDA, 0xAE, 0x7E, 0x6D, 0xBA, 0x81, 0x1C, 0x7E, 0x42, + 0x8C, 0x20, 0x35, 0xD9, 0x43, 0x4D, 0x84, 0xFA, 0x84, 0xDB, 0x52, 0x2C, + 0xF3, 0x0E, 0x27, 0x77, 0x0B, 0x6B, 0xBF, 0x11, 0x2F, 0x72, 0x78, 0x9F, + 0x2E, 0xD8, 0x3E, 0xE6, 0x18, 0x37, 0x5A, 0x2A, 0x72, 0xF9, 0xDA, 0x62, + 0x90, 0x92, 0x95, 0xCA, 0x1F, 0x9C, 0xE9, 0xB3, 0x3C, 0x2B, 0xCB, 0xF3, + 0x01, 0x13, 0xBF, 0x5A, 0xCF, 0xC1, 0xB5, 0x0A, 0x60, 0xBD, 0xDD, 0xB5, + 0x99, 0x64, 0x53, 0xB8, 0xA0, 0x96, 0xB3, 0x6F, 0xE2, 0x26, 0x77, 0x91, + 0x8C, 0xE0, 0x62, 0x10, 0x02, 0x9F, 0x34, 0x0F, 0xA4, 0xD5, 0x92, 0x33, + 0x51, 0xDE, 0xBE, 0x8D, 0xBA, 0x84, 0x7A, 0x60, 0x3C, 0x6A, 0xDB, 0x9F, + 0x2B, 0xEC, 0xDE, 0xDE, 0x01, 0x3F, 0x6E, 0x4D, 0xE5, 0x50, 0x86, 0xCB, + 0xB4, 0xAF, 0xED, 0x44, 0x40, 0xC5, 0xCA, 0x5A, 0x8C, 0xDA, 0xD2, 0x2B, + 0x7C, 0xA8, 0xEE, 0xBE, 0xA6, 0xE5, 0x0A, 0xAA, 0x0E, 0xA5, 0xDF, 0x05, + 0x52, 0xB7, 0x55, 0xC7, 0x22, 0x5D, 0x32, 0x6A, 0x97, 0x97, 0x63, 0x13, + 0xDB, 0xC9, 0xDB, 0x79, 0x36, 0x7B, 0x85, 0x3A, 0x4A, 0xC5, 0x52, 0x89, + 0xF9, 0x24, 0xE7, 0x9D, 0x77, 0xA9, 0x82, 0xFF, 0x55, 0x1C, 0xA5, 0x71, + 0x69, 0x2B, 0xD1, 0x02, 0x24, 0xF2, 0xB3, 0x26, 0xD4, 0x6B, 0xDA, 0x04, + 0x55, 0xE5, 0xC1, 0x0A, 0xC7, 0x6D, 0x30, 0x37, 0x90, 0x2A, 0xE4, 0x9E, + 0x14, 0x33, 0x5E, 0x16, 0x17, 0x55, 0xC5, 0x5B, 0xB5, 0xCB, 0x34, 0x89, + 0x92, 0xF1, 0x9D, 0x26, 0x8F, 0xA1, 0x07, 0xD4, 0xC6, 0xB2, 0x78, 0x50, + 0xDB, 0x0C, 0x0C, 0x0B, 0x7C, 0x0B, 0x8C, 0x41, 0xD7, 0xB9, 0xE9, 0xDD, + 0x8C, 0x88, 0xF7, 0xA3, 0x4D, 0xB2, 0x32, 0xCC, 0xD8, 0x17, 0xDA, 0xCD, + 0xB7, 0xCE, 0x66, 0x9D, 0xD4, 0xFD, 0x5E, 0xFF, 0xBD, 0x97, 0x3E, 0x29, + 0x75, 0xE7, 0x7E, 0xA7, 0x62, 0x58, 0xAF, 0x25, 0x34, 0xA5, 0x41, 0xC7, + 0x3D, 0xBC, 0x0D, 0x50, 0xCA, 0x03, 0x03, 0x0F, 0x08, 0x5A, 0x1F, 0x95, + 0x73, 0x78, 0x62, 0xBF, 0xAF, 0x72, 0x14, 0x69, 0x0E, 0xA5, 0xE5, 0x03, + 0x0E, 0x78, 0x8E, 0x26, 0x28, 0x42, 0xF0, 0x07, 0x0B, 0x62, 0x20, 0x10, + 0x67, 0x39, 0x46, 0xFA, 0xA9, 0x03, 0xCC, 0x04, 0x38, 0x7A, 0x66, 0xEF, + 0x20, 0x83, 0xB5, 0x8C, 0x4A, 0x56, 0x8E, 0x91, 0x00, 0xFC, 0x8E, 0x5C, + 0x82, 0xDE, 0x88, 0xA0, 0xC3, 0xE2, 0x68, 0x6E, 0x7D, 0x8D, 0xEF, 0x3C, + 0xDD, 0x65, 0xF4, 0x5D, 0xAC, 0x51, 0xEF, 0x24, 0x80, 0xAE, 0xAA, 0x56, + 0x97, 0x6F, 0xF9, 0xAD, 0x7D, 0xDA, 0x61, 0x3F, 0x98, 0x77, 0x3C, 0xA5, + 0x91, 0xB6, 0x1C, 0x8C, 0x26, 0xDA, 0x65, 0xA2, 0x09, 0x6D, 0xC1, 0xE2, + 0x54, 0xE3, 0xB9, 0xCA, 0x4C, 0x4C, 0x80, 0x8F, 0x77, 0x7B, 0x60, 0x9A, + 0x1E, 0xDF, 0xB6, 0xF2, 0x48, 0x1E, 0x0E, 0xBA, 0x4E, 0x54, 0x6D, 0x98, + 0xE0, 0xE1, 0xA2, 0x1A, 0xA2, 0x77, 0x50, 0xCF, 0xC4, 0x63, 0x92, 0xEC, + 0x47, 0x19, 0x9D, 0xEB, 0xE6, 0x6B, 0xCE, 0xC1 +}; + +static const unsigned char TA78_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA79_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA79_RSA_N[] = { + 0xE1, 0xFA, 0x0E, 0xFB, 0x68, 0x00, 0x12, 0xC8, 0x4D, 0xD5, 0xAC, 0x22, + 0xC4, 0x35, 0x01, 0x3B, 0xC5, 0x54, 0xE5, 0x59, 0x76, 0x63, 0xA5, 0x7F, + 0xEB, 0xC1, 0xC4, 0x6A, 0x98, 0xBD, 0x32, 0x8D, 0x17, 0x80, 0xEB, 0x5D, + 0xBA, 0xD1, 0x62, 0x3D, 0x25, 0x23, 0x19, 0x35, 0x14, 0xE9, 0x7F, 0x89, + 0xA7, 0x1B, 0x62, 0x3C, 0xD6, 0x50, 0xE7, 0x34, 0x95, 0x03, 0x32, 0xB1, + 0xB4, 0x93, 0x22, 0x3D, 0xA7, 0xE2, 0xB1, 0xED, 0xE6, 0x7B, 0x4E, 0x2E, + 0x87, 0x9B, 0x0D, 0x33, 0x75, 0x0A, 0xDE, 0xAA, 0x35, 0xE7, 0x7E, 0xE5, + 0x36, 0x98, 0xA2, 0xAE, 0x25, 0x9E, 0x95, 0xB3, 0x32, 0x96, 0xA4, 0x2B, + 0x58, 0x1E, 0xEF, 0x3F, 0xFE, 0x62, 0x34, 0x48, 0x51, 0xD1, 0xB4, 0x8D, + 0x42, 0xAD, 0x60, 0xDA, 0x49, 0x6A, 0x95, 0x70, 0xDD, 0xD2, 0x00, 0xE2, + 0xCC, 0x57, 0x63, 0x02, 0x7B, 0x96, 0xDD, 0x49, 0x97, 0x5B, 0x92, 0x4E, + 0x95, 0xD3, 0xF9, 0xCB, 0x29, 0x1F, 0x18, 0x4A, 0xF8, 0x01, 0x2A, 0xD2, + 0x63, 0x09, 0x6E, 0x24, 0xE9, 0x89, 0xD2, 0xE5, 0xC7, 0x22, 0x4C, 0xDC, + 0x73, 0x86, 0x47, 0x00, 0xAA, 0x0D, 0x88, 0x8E, 0xAE, 0x85, 0x7D, 0x4A, + 0xE9, 0xBB, 0x33, 0x4F, 0x0E, 0x52, 0x70, 0x9D, 0x95, 0xE3, 0x7C, 0x6D, + 0x96, 0x5B, 0x2D, 0x3D, 0x5F, 0xA1, 0x83, 0x46, 0x5D, 0xB6, 0xE3, 0x25, + 0xB8, 0x7C, 0xA7, 0x19, 0x80, 0x1C, 0xEA, 0x65, 0x43, 0xDC, 0x91, 0x79, + 0x36, 0x2C, 0x74, 0x7C, 0xF2, 0x67, 0x06, 0xC9, 0x89, 0xC9, 0xDB, 0xBF, + 0xDA, 0x68, 0xBF, 0x23, 0xED, 0xDC, 0x6B, 0xAD, 0x28, 0x83, 0x79, 0x2F, + 0xEC, 0x38, 0xA5, 0x0D, 0x37, 0x01, 0x67, 0x27, 0x9A, 0xE9, 0x33, 0xD9, + 0x33, 0x5F, 0x37, 0xA1, 0xC5, 0xF0, 0xAB, 0x3D, 0xFA, 0x78, 0xB0, 0xE7, + 0x2C, 0x9F, 0xF6, 0x3E, 0x9F, 0x60, 0xE0, 0xEF, 0x48, 0xE9, 0x90, 0x45, + 0x1E, 0x05, 0x51, 0x78, 0x1A, 0x2C, 0x12, 0x2C, 0x5C, 0x28, 0xAC, 0x0D, + 0xA2, 0x23, 0x9E, 0x34, 0x8F, 0x05, 0xE6, 0xA2, 0x33, 0xCE, 0x11, 0x77, + 0x13, 0xD4, 0x0E, 0xA4, 0x1E, 0x42, 0x1F, 0x86, 0xCD, 0x70, 0xFE, 0xD9, + 0x2E, 0x15, 0x3D, 0x1D, 0xBB, 0xB8, 0xF2, 0x53, 0x57, 0xDB, 0xCC, 0xC6, + 0x74, 0x29, 0x9C, 0x18, 0xB3, 0x36, 0x75, 0x38, 0x2E, 0x0F, 0x54, 0xA1, + 0xF8, 0x92, 0x1F, 0x89, 0x96, 0x4F, 0xBB, 0xD4, 0xEE, 0x9D, 0xE9, 0x3B, + 0x36, 0x42, 0xB5, 0x0A, 0x3B, 0x2A, 0xD4, 0x64, 0x79, 0x36, 0x10, 0xE1, + 0xF9, 0x91, 0x03, 0x2B, 0x7B, 0x20, 0x54, 0xCD, 0x0D, 0x19, 0x1A, 0xC8, + 0x41, 0x32, 0x34, 0xD1, 0xB0, 0x99, 0xE1, 0x90, 0x1E, 0x01, 0x40, 0x36, + 0xB5, 0xB7, 0xFA, 0xA9, 0xE5, 0x77, 0x75, 0xA4, 0x22, 0x81, 0x5D, 0xB0, + 0x8B, 0xE4, 0x27, 0x12, 0x0F, 0x54, 0x88, 0xC6, 0xDB, 0x85, 0x74, 0xE6, + 0xB7, 0xC0, 0xD7, 0xA6, 0x29, 0xFA, 0xDB, 0xDE, 0xF3, 0x93, 0x97, 0x27, + 0x04, 0x55, 0x2F, 0x0A, 0x6F, 0x37, 0xC5, 0x3D, 0x13, 0xAF, 0x0A, 0x00, + 0xA9, 0x2C, 0x8B, 0x1C, 0x81, 0x28, 0xD7, 0xEF, 0x86, 0x31, 0xA9, 0xAE, + 0xF2, 0x6E, 0xB8, 0xCA, 0x6A, 0x2C, 0x54, 0x47, 0xD8, 0x2A, 0x88, 0x2E, + 0xAF, 0xC1, 0x07, 0x10, 0x78, 0xAC, 0x11, 0xA2, 0x2F, 0x42, 0xF0, 0x37, + 0xC5, 0xF2, 0xB8, 0x56, 0xDD, 0x0E, 0x62, 0x2D, 0xCE, 0x2D, 0x56, 0x7E, + 0x55, 0xF2, 0xA7, 0x44, 0xF6, 0x2B, 0x32, 0xF4, 0x23, 0xA8, 0x47, 0xE8, + 0xD4, 0x2A, 0x01, 0x78, 0xCF, 0x6A, 0xC3, 0x37, 0xA8, 0x9E, 0x65, 0xD2, + 0x2C, 0xE5, 0xFA, 0xBA, 0x33, 0xC1, 0x06, 0x44, 0xF6, 0xE6, 0xCF, 0xA5, + 0x0D, 0xA7, 0x66, 0x08, 0x34, 0x8A, 0x2C, 0xF3 +}; + +static const unsigned char TA79_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA80_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA80_RSA_N[] = { + 0xA0, 0xBE, 0x50, 0x10, 0x8E, 0xE9, 0xF2, 0x6C, 0x40, 0xB4, 0x04, 0x9C, + 0x85, 0xB9, 0x31, 0xCA, 0xDC, 0x2D, 0xE4, 0x11, 0xA9, 0x04, 0x3C, 0x1B, + 0x55, 0xC1, 0xE7, 0x58, 0x30, 0x1D, 0x24, 0xB4, 0xC3, 0xEF, 0x85, 0xDE, + 0x8C, 0x2C, 0xE1, 0xC1, 0x3D, 0xDF, 0x82, 0xE6, 0x4F, 0xAD, 0x47, 0x87, + 0x6C, 0xEC, 0x5B, 0x49, 0xC1, 0x4A, 0xD5, 0xBB, 0x8F, 0xEC, 0x87, 0xAC, + 0x7F, 0x82, 0x9A, 0x86, 0xEC, 0x3D, 0x03, 0x99, 0x52, 0x01, 0xD2, 0x35, + 0x9E, 0xAC, 0xDA, 0xF0, 0x53, 0xC9, 0x66, 0x3C, 0xD4, 0xAC, 0x02, 0x01, + 0xDA, 0x24, 0xD3, 0x3B, 0xA8, 0x02, 0x46, 0xAF, 0xA4, 0x1C, 0xE3, 0xF8, + 0x73, 0x58, 0x76, 0xB7, 0xF6, 0x0E, 0x90, 0x0D, 0xB5, 0xF0, 0xCF, 0xCC, + 0xFA, 0xF9, 0xC6, 0x4C, 0xE5, 0xC3, 0x86, 0x30, 0x0A, 0x8D, 0x17, 0x7E, + 0x35, 0xEB, 0xC5, 0xDF, 0xBB, 0x0E, 0x9C, 0xC0, 0x8D, 0x87, 0xE3, 0x88, + 0x38, 0x85, 0x67, 0xFA, 0x3E, 0xC7, 0xAB, 0xE0, 0x13, 0x9C, 0x05, 0x18, + 0x98, 0xCF, 0x93, 0xF5, 0xB1, 0x92, 0xB4, 0xFC, 0x23, 0xD3, 0xCF, 0xD5, + 0xC4, 0x27, 0x49, 0xE0, 0x9E, 0x3C, 0x9B, 0x08, 0xA3, 0x8B, 0x5D, 0x2A, + 0x21, 0xE0, 0xFC, 0x39, 0xAA, 0x53, 0xDA, 0x7D, 0x7E, 0xCF, 0x1A, 0x09, + 0x53, 0xBC, 0x5D, 0x05, 0x04, 0xCF, 0xA1, 0x4A, 0x8F, 0x8B, 0x76, 0x82, + 0x0D, 0xA1, 0xF8, 0xD2, 0xC7, 0x14, 0x77, 0x5B, 0x90, 0x36, 0x07, 0x81, + 0x9B, 0x3E, 0x06, 0xFA, 0x52, 0x5E, 0x63, 0xC5, 0xA6, 0x00, 0xFE, 0xA5, + 0xE9, 0x52, 0x1B, 0x52, 0xB5, 0x92, 0x39, 0x72, 0x03, 0x09, 0x62, 0xBD, + 0xB0, 0x60, 0x16, 0x6E, 0xA6, 0xDD, 0x25, 0xC2, 0x03, 0x66, 0xDD, 0xF3, + 0x04, 0xD1, 0x40, 0xE2, 0x4E, 0x8B, 0x86, 0xF4, 0x6F, 0xE5, 0x83, 0xA0, + 0x27, 0x84, 0x5E, 0x04, 0xC1, 0xF5, 0x90, 0xBD, 0x30, 0x3D, 0xC4, 0xEF, + 0xA8, 0x69, 0xBC, 0x38, 0x9B, 0xA4, 0xA4, 0x96, 0xD1, 0x62, 0xDA, 0x69, + 0xC0, 0x01, 0x96, 0xAE, 0xCB, 0xC4, 0x51, 0x34, 0xEA, 0x0C, 0xAA, 0xFF, + 0x21, 0x8E, 0x59, 0x8F, 0x4A, 0x5C, 0xE4, 0x61, 0x9A, 0xA7, 0xD2, 0xE9, + 0x2A, 0x78, 0x8D, 0x51, 0x3D, 0x3A, 0x15, 0xEE, 0xA2, 0x59, 0x8E, 0xA9, + 0x5C, 0xDE, 0xC5, 0xF9, 0x90, 0x22, 0xE5, 0x88, 0x45, 0x71, 0xDD, 0x91, + 0x99, 0x6C, 0x7A, 0x9F, 0x3D, 0x3D, 0x98, 0x7C, 0x5E, 0xF6, 0xBE, 0x16, + 0x68, 0xA0, 0x5E, 0xAE, 0x0B, 0x23, 0xFC, 0x5A, 0x0F, 0xAA, 0x22, 0x76, + 0x2D, 0xC9, 0xA1, 0x10, 0x1D, 0xE4, 0xD3, 0x44, 0x23, 0x90, 0x88, 0x9F, + 0xC6, 0x2A, 0xE6, 0xD7, 0xF5, 0x9A, 0xB3, 0x58, 0x1E, 0x2F, 0x30, 0x89, + 0x08, 0x1B, 0x54, 0xA2, 0xB5, 0x98, 0x23, 0xEC, 0x08, 0x77, 0x1C, 0x95, + 0x5D, 0x61, 0xD1, 0xCB, 0x89, 0x9C, 0x5F, 0xA2, 0x4A, 0x91, 0x9A, 0xEF, + 0x21, 0xAA, 0x49, 0x16, 0x08, 0xA8, 0xBD, 0x61, 0x28, 0x31, 0xC9, 0x74, + 0xAD, 0x85, 0xF6, 0xD9, 0xC5, 0xB1, 0x8B, 0xD1, 0xE5, 0x10, 0x32, 0x4D, + 0x5F, 0x8B, 0x20, 0x3A, 0x3C, 0x49, 0x1F, 0x33, 0x85, 0x59, 0x0D, 0xDB, + 0xCB, 0x09, 0x75, 0x43, 0x69, 0x73, 0xFB, 0x6B, 0x71, 0x7D, 0xF0, 0xDF, + 0xC4, 0x4C, 0x7D, 0xC6, 0xA3, 0x2E, 0xC8, 0x95, 0x79, 0xCB, 0x73, 0xA2, + 0x8E, 0x4E, 0x4D, 0x24, 0xFB, 0x5E, 0xE4, 0x04, 0xBE, 0x72, 0x1B, 0xA6, + 0x27, 0x2D, 0x49, 0x5A, 0x99, 0x7A, 0xD7, 0x5C, 0x09, 0x20, 0xB7, 0x7F, + 0x94, 0xB9, 0x4F, 0xF1, 0x0D, 0x1C, 0x5E, 0x88, 0x42, 0x1B, 0x11, 0xB7, + 0xE7, 0x91, 0xDB, 0x9E, 0x6C, 0xF4, 0x6A, 0xDF, 0x8C, 0x06, 0x98, 0x03, + 0xAD, 0xCC, 0x28, 0xEF, 0xA5, 0x47, 0xF3, 0x53 +}; + +static const unsigned char TA80_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA81_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x12, 0x48, 0x69, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA81_RSA_N[] = { + 0xF4, 0x1E, 0x7F, 0x52, 0x73, 0x32, 0x0C, 0x73, 0xE4, 0xBD, 0x13, 0x74, + 0xA3, 0xD4, 0x30, 0xA8, 0xD0, 0xAE, 0x4B, 0xD8, 0xB6, 0xDF, 0x75, 0x47, + 0x66, 0xF4, 0x7C, 0xE7, 0x39, 0x04, 0x1E, 0x6A, 0x70, 0x20, 0xD2, 0x5A, + 0x47, 0x72, 0x67, 0x55, 0xF4, 0xA5, 0xE8, 0x9D, 0xD5, 0x1E, 0x21, 0xA1, + 0xF0, 0x67, 0xBA, 0xCC, 0x21, 0x68, 0xBE, 0x44, 0x53, 0xBF, 0x8D, 0xF9, + 0xE2, 0xDC, 0x2F, 0x55, 0xC8, 0x37, 0x3F, 0x1F, 0xA4, 0xC0, 0x9C, 0xB3, + 0xE4, 0x77, 0x5C, 0xA0, 0x46, 0xFE, 0x77, 0xFA, 0x1A, 0xA0, 0x38, 0xEA, + 0xED, 0x9A, 0x72, 0xDE, 0x2B, 0xBD, 0x94, 0x57, 0x3A, 0xBA, 0xEC, 0x79, + 0xE7, 0x5F, 0x7D, 0x42, 0x64, 0x39, 0x7A, 0x26, 0x36, 0xF7, 0x24, 0xF0, + 0xD5, 0x2F, 0xBA, 0x95, 0x98, 0x11, 0x66, 0xAD, 0x97, 0x35, 0xD6, 0x75, + 0x01, 0x80, 0xE0, 0xAF, 0xF4, 0x84, 0x61, 0x8C, 0x0D, 0x1E, 0x5F, 0x7C, + 0x87, 0x96, 0x5E, 0x41, 0xAF, 0xEB, 0x87, 0xEA, 0xF8, 0x5D, 0xF1, 0x2E, + 0x88, 0x05, 0x3E, 0x4C, 0x22, 0xBB, 0xDA, 0x1F, 0x2A, 0xDD, 0x52, 0x46, + 0x64, 0x39, 0xF3, 0x42, 0xCE, 0xD9, 0x9E, 0x0C, 0xB3, 0xB0, 0x77, 0x97, + 0x64, 0x9C, 0xC0, 0xF4, 0xA3, 0x2E, 0x1F, 0x95, 0x07, 0xB0, 0x17, 0xDF, + 0x30, 0xDB, 0x00, 0x18, 0x96, 0x4C, 0xA1, 0x81, 0x4B, 0xDD, 0x04, 0x6D, + 0x53, 0xA3, 0x3D, 0xFC, 0x07, 0xAC, 0xD4, 0xC5, 0x37, 0x82, 0xEB, 0xE4, + 0x95, 0x08, 0x19, 0x28, 0x82, 0xD2, 0x42, 0x3A, 0xA3, 0xD8, 0x53, 0xEC, + 0x79, 0x89, 0x60, 0x48, 0x60, 0xC8, 0x72, 0x92, 0x50, 0xDC, 0x03, 0x8F, + 0x83, 0x3F, 0xB2, 0x42, 0x57, 0x5A, 0xDB, 0x6A, 0xE9, 0x11, 0x97, 0xDD, + 0x85, 0x28, 0xBC, 0x30, 0x4C, 0xAB, 0xE3, 0xC2, 0xB1, 0x45, 0x44, 0x47, + 0x1F, 0xE0, 0x8A, 0x16, 0x07, 0x96, 0xD2, 0x21, 0x0F, 0x53, 0xC0, 0xED, + 0xA9, 0x7E, 0xD4, 0x4E, 0xEC, 0x9B, 0x09, 0xEC, 0xAF, 0x42, 0xAC, 0x30, + 0xD6, 0xBF, 0xD1, 0x10, 0x45, 0xE0, 0xA6, 0x16, 0xB2, 0xA5, 0xC5, 0xD3, + 0x4F, 0x73, 0x94, 0x33, 0x71, 0x02, 0xA1, 0x6A, 0xA3, 0xD6, 0x33, 0x97, + 0x4F, 0x21, 0x63, 0x1E, 0x5B, 0x8F, 0xD9, 0xC1, 0x5E, 0x45, 0x71, 0x77, + 0x0F, 0x81, 0x5D, 0x5F, 0x21, 0x9A, 0xAD, 0x83, 0xCC, 0xFA, 0x5E, 0xD6, + 0x8D, 0x23, 0x5F, 0x1B, 0x3D, 0x41, 0xAF, 0x20, 0x75, 0x66, 0x5A, 0x4A, + 0xF6, 0x9F, 0xFB, 0xAB, 0x18, 0xF7, 0x71, 0xC0, 0xB6, 0x1D, 0x31, 0xEC, + 0x3B, 0x20, 0xEB, 0xCB, 0xE2, 0xB8, 0xF5, 0xAE, 0x92, 0xB2, 0xF7, 0xE1, + 0x84, 0x4B, 0xF2, 0xA2, 0xF2, 0x93, 0x9A, 0x22, 0x9E, 0xD3, 0x14, 0x6F, + 0x36, 0x54, 0xBD, 0x1F, 0x5E, 0x59, 0x15, 0xB9, 0x73, 0xA8, 0xC1, 0x7C, + 0x6F, 0x7B, 0x62, 0xE9, 0x16, 0x6C, 0x47, 0x5A, 0x65, 0xF3, 0x0E, 0x11, + 0x9B, 0x46, 0xD9, 0xFD, 0x6D, 0xDC, 0xD6, 0x9C, 0xC0, 0xB4, 0x7D, 0xA5, + 0xB0, 0xDD, 0x3F, 0x56, 0x6F, 0xA1, 0xF9, 0xF6, 0xE4, 0x12, 0x48, 0xFD, + 0x06, 0x7F, 0x12, 0x57, 0xB6, 0xA9, 0x23, 0x4F, 0x5B, 0x03, 0xC3, 0xE0, + 0x71, 0x2A, 0x23, 0xB7, 0xF7, 0xB0, 0xB1, 0x3B, 0xBC, 0x98, 0xBD, 0xD6, + 0x98, 0xA8, 0x0C, 0x6B, 0xF6, 0x8E, 0x12, 0x67, 0xA6, 0xF2, 0xB2, 0x58, + 0xE4, 0x02, 0x09, 0x13, 0x3C, 0xA9, 0xBB, 0x10, 0xB4, 0xD2, 0x30, 0x45, + 0xF1, 0xEC, 0xF7, 0x00, 0x11, 0xDF, 0x65, 0xF8, 0xDC, 0x2B, 0x43, 0x55, + 0xBF, 0x16, 0x97, 0xC4, 0x0F, 0xD5, 0x2C, 0x61, 0x84, 0xAA, 0x72, 0x86, + 0xFE, 0xE6, 0x3A, 0x7E, 0xC2, 0x3F, 0x7D, 0xEE, 0xFC, 0x2F, 0x14, 0x3E, + 0xE6, 0x85, 0xDD, 0x50, 0x6F, 0xB7, 0x49, 0xED +}; + +static const unsigned char TA81_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA82_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x33 +}; + +static const unsigned char TA82_RSA_N[] = { + 0xBD, 0x75, 0x93, 0xF0, 0x62, 0x22, 0x6F, 0x24, 0xAE, 0xE0, 0x7A, 0x76, + 0xAC, 0x7D, 0xBD, 0xD9, 0x24, 0xD5, 0xB8, 0xB7, 0xFC, 0xCD, 0xF0, 0x42, + 0xE0, 0xEB, 0x78, 0x88, 0x56, 0x5E, 0x9B, 0x9A, 0x54, 0x1D, 0x4D, 0x0C, + 0x8A, 0xF6, 0xD3, 0xCF, 0x70, 0xF4, 0x52, 0xB5, 0xD8, 0x93, 0x04, 0xE3, + 0x46, 0x86, 0x71, 0x41, 0x4A, 0x2B, 0xF0, 0x2A, 0x2C, 0x55, 0x03, 0xD6, + 0x48, 0xC3, 0xE0, 0x39, 0x38, 0xED, 0xF2, 0x5C, 0x3C, 0x3F, 0x44, 0xBC, + 0x93, 0x3D, 0x61, 0xAB, 0x4E, 0xCD, 0x0D, 0xBE, 0xF0, 0x20, 0x27, 0x58, + 0x0E, 0x44, 0x7F, 0x04, 0x1A, 0x87, 0xA5, 0xD7, 0x96, 0x14, 0x36, 0x90, + 0xD0, 0x49, 0x7B, 0xA1, 0x75, 0xFB, 0x1A, 0x6B, 0x73, 0xB1, 0xF8, 0xCE, + 0xA9, 0x09, 0x2C, 0xF2, 0x53, 0xD5, 0xC3, 0x14, 0x44, 0xB8, 0x86, 0xA5, + 0xF6, 0x8B, 0x2B, 0x39, 0xDA, 0xA3, 0x33, 0x54, 0xD9, 0xFA, 0x72, 0x1A, + 0xF7, 0x22, 0x15, 0x1C, 0x88, 0x91, 0x6B, 0x7F, 0x66, 0xE5, 0xC3, 0x6A, + 0x80, 0xB0, 0x24, 0xF3, 0xDF, 0x86, 0x45, 0x88, 0xFD, 0x19, 0x7F, 0x75, + 0x87, 0x1F, 0x1F, 0xB1, 0x1B, 0x0A, 0x73, 0x24, 0x5B, 0xB9, 0x65, 0xE0, + 0x2C, 0x54, 0xC8, 0x60, 0xD3, 0x66, 0x17, 0x3F, 0xE1, 0xCC, 0x54, 0x33, + 0x73, 0x91, 0x02, 0x3A, 0xA6, 0x7F, 0x7B, 0x76, 0x39, 0xA2, 0x1F, 0x96, + 0xB6, 0x38, 0xAE, 0xB5, 0xC8, 0x93, 0x74, 0x1D, 0x9E, 0xB9, 0xB4, 0xE5, + 0x60, 0x9D, 0x2F, 0x56, 0xD1, 0xE0, 0xEB, 0x5E, 0x5B, 0x4C, 0x12, 0x70, + 0x0C, 0x6C, 0x44, 0x20, 0xAB, 0x11, 0xD8, 0xF4, 0x19, 0xF6, 0xD2, 0x9C, + 0x52, 0x37, 0xE7, 0xFA, 0xB6, 0xC2, 0x31, 0x3B, 0x4A, 0xD4, 0x14, 0x99, + 0xAD, 0xC7, 0x1A, 0xF5, 0x5D, 0x5F, 0xFA, 0x07, 0xB8, 0x7C, 0x0D, 0x1F, + 0xD6, 0x83, 0x1E, 0xB3 +}; + +static const unsigned char TA82_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA83_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA83_RSA_N[] = { + 0xD7, 0xC7, 0x5E, 0xF7, 0xC1, 0x07, 0xD4, 0x77, 0xFB, 0x43, 0x21, 0xF4, + 0xF4, 0xF5, 0x69, 0xE4, 0xEE, 0x32, 0x01, 0xDB, 0xA3, 0x86, 0x1F, 0xE4, + 0x59, 0x0D, 0xBA, 0xE7, 0x75, 0x83, 0x52, 0xEB, 0xEA, 0x1C, 0x61, 0x15, + 0x48, 0xBB, 0x1D, 0x07, 0xCA, 0x8C, 0xAE, 0xB0, 0xDC, 0x96, 0x9D, 0xEA, + 0xC3, 0x60, 0x92, 0x86, 0x82, 0x28, 0x73, 0x9C, 0x56, 0x06, 0xFF, 0x4B, + 0x64, 0xF0, 0x0C, 0x2A, 0x37, 0x49, 0xB5, 0xE5, 0xCF, 0x0C, 0x7C, 0xEE, + 0xF1, 0x4A, 0xBB, 0x73, 0x30, 0x65, 0xF3, 0xD5, 0x2F, 0x83, 0xB6, 0x7E, + 0xE3, 0xE7, 0xF5, 0x9E, 0xAB, 0x60, 0xF9, 0xD3, 0xF1, 0x9D, 0x92, 0x74, + 0x8A, 0xE4, 0x1C, 0x96, 0xAC, 0x5B, 0x80, 0xE9, 0xB5, 0xF4, 0x31, 0x87, + 0xA3, 0x51, 0xFC, 0xC7, 0x7E, 0xA1, 0x6F, 0x8E, 0x53, 0x77, 0xD4, 0x97, + 0xC1, 0x55, 0x33, 0x92, 0x3E, 0x18, 0x2F, 0x75, 0xD4, 0xAD, 0x86, 0x49, + 0xCB, 0x95, 0xAF, 0x54, 0x06, 0x6C, 0xD8, 0x06, 0x13, 0x8D, 0x5B, 0xFF, + 0xE1, 0x26, 0x19, 0x59, 0xC0, 0x24, 0xBA, 0x81, 0x71, 0x79, 0x90, 0x44, + 0x50, 0x68, 0x24, 0x94, 0x5F, 0xB8, 0xB3, 0x11, 0xF1, 0x29, 0x41, 0x61, + 0xA3, 0x41, 0xCB, 0x23, 0x36, 0xD5, 0xC1, 0xF1, 0x32, 0x50, 0x10, 0x4E, + 0x7F, 0xF4, 0x86, 0x93, 0xEC, 0x84, 0xD3, 0x8E, 0xBC, 0x4B, 0xBF, 0x5C, + 0x01, 0x4E, 0x07, 0x3D, 0xDC, 0x14, 0x8A, 0x94, 0x0A, 0xA4, 0xEA, 0x73, + 0xFB, 0x0B, 0x51, 0xE8, 0x13, 0x07, 0x18, 0xFA, 0x0E, 0xF1, 0x2B, 0xD1, + 0x54, 0x15, 0x7D, 0x3C, 0xE1, 0xF7, 0xB4, 0x19, 0x42, 0x67, 0x62, 0x5E, + 0x77, 0xE0, 0xA2, 0x55, 0xEC, 0xB6, 0xD9, 0x69, 0x17, 0xD5, 0x3A, 0xAF, + 0x44, 0xED, 0x4A, 0xC5, 0x9E, 0xE4, 0x7A, 0x27, 0x7C, 0xE5, 0x75, 0xD7, + 0xAA, 0xCB, 0x25, 0xE7, 0xDF, 0x6B, 0x0A, 0xDB, 0x0F, 0x4D, 0x93, 0x4E, + 0xA8, 0xA0, 0xCD, 0x7B, 0x2E, 0xF2, 0x59, 0x01, 0x6A, 0xB7, 0x0D, 0xB8, + 0x07, 0x81, 0x7E, 0x8B, 0x38, 0x1B, 0x38, 0xE6, 0x0A, 0x57, 0x99, 0x3D, + 0xEE, 0x21, 0xE8, 0xA3, 0xF5, 0x0C, 0x16, 0xDD, 0x8B, 0xEC, 0x34, 0x8E, + 0x9C, 0x2A, 0x1C, 0x00, 0x15, 0x17, 0x8D, 0x68, 0x83, 0xD2, 0x70, 0x9F, + 0x18, 0x08, 0xCD, 0x11, 0x68, 0xD5, 0xC9, 0x6B, 0x52, 0xCD, 0xC4, 0x46, + 0x8F, 0xDC, 0xB5, 0xF3, 0xD8, 0x57, 0x73, 0x1E, 0xE9, 0x94, 0x39, 0x04, + 0xBF, 0xD3, 0xDE, 0x38, 0xDE, 0xB4, 0x53, 0xEC, 0x69, 0x1C, 0xA2, 0x7E, + 0xC4, 0x8F, 0xE4, 0x1B, 0x70, 0xAD, 0xF2, 0xA2, 0xF9, 0xFB, 0xF7, 0x16, + 0x64, 0x66, 0x69, 0x9F, 0x49, 0x51, 0xA2, 0xE2, 0x15, 0x18, 0x67, 0x06, + 0x4A, 0x7F, 0xD5, 0x6C, 0xB5, 0x4D, 0xB3, 0x33, 0xE0, 0x61, 0xEB, 0x5D, + 0xBE, 0xE9, 0x98, 0x0F, 0x32, 0xD7, 0x1D, 0x4B, 0x3C, 0x2E, 0x5A, 0x01, + 0x52, 0x91, 0x09, 0xF2, 0xDF, 0xEA, 0x8D, 0xD8, 0x06, 0x40, 0x63, 0xAA, + 0x11, 0xE4, 0xFE, 0xC3, 0x37, 0x9E, 0x14, 0x52, 0x3F, 0xF4, 0xE2, 0xCC, + 0xF2, 0x61, 0x93, 0xD1, 0xFD, 0x67, 0x6B, 0xD7, 0x52, 0xAE, 0xBF, 0x68, + 0xAB, 0x40, 0x43, 0xA0, 0x57, 0x35, 0x53, 0x78, 0xF0, 0x53, 0xF8, 0x61, + 0x42, 0x07, 0x64, 0xC6, 0xD7, 0x6F, 0x9B, 0x4C, 0x38, 0x0D, 0x63, 0xAC, + 0x62, 0xAF, 0x36, 0x8B, 0xA2, 0x73, 0x0A, 0x0D, 0xF5, 0x21, 0xBD, 0x74, + 0xAA, 0x4D, 0xEA, 0x72, 0x03, 0x49, 0xDB, 0xC7, 0x5F, 0x1D, 0x62, 0x63, + 0xC7, 0xFD, 0xDD, 0x91, 0xEC, 0x33, 0xEE, 0xF5, 0x6D, 0xB4, 0x6E, 0x30, + 0x68, 0xDE, 0xC8, 0xD6, 0x26, 0xB0, 0x75, 0x5E, 0x7B, 0xB4, 0x07, 0x20, + 0x98, 0xA1, 0x76, 0x32, 0xB8, 0x4D, 0x6C, 0x4F +}; + +static const unsigned char TA83_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA84_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, + 0x6F, 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x2E, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, + 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA84_RSA_N[] = { + 0x8F, 0x36, 0x65, 0x40, 0xE1, 0xD6, 0x4D, 0xC0, 0xD7, 0xB4, 0xE9, 0x46, + 0xDA, 0x6B, 0xEA, 0x33, 0x47, 0xCD, 0x4C, 0xF9, 0x7D, 0x7D, 0xBE, 0xBD, + 0x2D, 0x3D, 0xF0, 0xDB, 0x78, 0xE1, 0x86, 0xA5, 0xD9, 0xBA, 0x09, 0x57, + 0x68, 0xED, 0x57, 0x3E, 0xA0, 0xD0, 0x08, 0x41, 0x83, 0xE7, 0x28, 0x41, + 0x24, 0x1F, 0xE3, 0x72, 0x15, 0xD0, 0x01, 0x1A, 0xFB, 0x5E, 0x70, 0x23, + 0xB2, 0xCB, 0x9F, 0x39, 0xE3, 0xCF, 0xC5, 0x4E, 0xC6, 0x92, 0x6D, 0x26, + 0xC6, 0x7B, 0xBB, 0xB3, 0xDA, 0x27, 0x9D, 0x0A, 0x86, 0xE9, 0x81, 0x37, + 0x05, 0xFE, 0xF0, 0x71, 0x71, 0xEC, 0xC3, 0x1C, 0xE9, 0x63, 0xA2, 0x17, + 0x14, 0x9D, 0xEF, 0x1B, 0x67, 0xD3, 0x85, 0x55, 0x02, 0x02, 0xD6, 0x49, + 0xC9, 0xCC, 0x5A, 0xE1, 0xB1, 0xF7, 0x6F, 0x32, 0x9F, 0xC9, 0xD4, 0x3B, + 0x88, 0x41, 0xA8, 0x9C, 0xBD, 0xCB, 0xAB, 0xDB, 0x6D, 0x7B, 0x09, 0x1F, + 0xA2, 0x4C, 0x72, 0x90, 0xDA, 0x2B, 0x08, 0xFC, 0xCF, 0x3C, 0x54, 0xCE, + 0x67, 0x0F, 0xA8, 0xCF, 0x5D, 0x96, 0x19, 0x0B, 0xC4, 0xE3, 0x72, 0xEB, + 0xAD, 0xD1, 0x7D, 0x1D, 0x27, 0xEF, 0x92, 0xEB, 0x10, 0xBF, 0x5B, 0xEB, + 0x3B, 0xAF, 0xCF, 0x80, 0xDD, 0xC1, 0xD2, 0x96, 0x04, 0x5B, 0x7A, 0x7E, + 0xA4, 0xA9, 0x3C, 0x38, 0x76, 0xA4, 0x62, 0x8E, 0xA0, 0x39, 0x5E, 0xEA, + 0x77, 0xCF, 0x5D, 0x00, 0x59, 0x8F, 0x66, 0x2C, 0x3E, 0x07, 0xA2, 0xA3, + 0x05, 0x26, 0x11, 0x69, 0x97, 0xEA, 0x85, 0xB7, 0x0F, 0x96, 0x0B, 0x4B, + 0xC8, 0x40, 0xE1, 0x50, 0xBA, 0x2E, 0x8A, 0xCB, 0xF7, 0x0F, 0x9A, 0x22, + 0xE7, 0x7F, 0x9A, 0x37, 0x13, 0xCD, 0xF2, 0x4D, 0x13, 0x6B, 0x21, 0xD1, + 0xC0, 0xCC, 0x22, 0xF2, 0xA1, 0x46, 0xF6, 0x44, 0x69, 0x9C, 0xCA, 0x61, + 0x35, 0x07, 0x00, 0x6F, 0xD6, 0x61, 0x08, 0x11, 0xEA, 0xBA, 0xB8, 0xF6, + 0xE9, 0xB3, 0x60, 0xE5, 0x4D, 0xB9, 0xEC, 0x9F, 0x14, 0x66, 0xC9, 0x57, + 0x58, 0xDB, 0xCD, 0x87, 0x69, 0xF8, 0x8A, 0x86, 0x12, 0x03, 0x47, 0xBF, + 0x66, 0x13, 0x76, 0xAC, 0x77, 0x7D, 0x34, 0x24, 0x85, 0x83, 0xCD, 0xD7, + 0xAA, 0x9C, 0x90, 0x1A, 0x9F, 0x21, 0x2C, 0x7F, 0x78, 0xB7, 0x64, 0xB8, + 0xD8, 0xE8, 0xA6, 0xF4, 0x78, 0xB3, 0x55, 0xCB, 0x84, 0xD2, 0x32, 0xC4, + 0x78, 0xAE, 0xA3, 0x8F, 0x61, 0xDD, 0xCE, 0x08, 0x53, 0xAD, 0xEC, 0x88, + 0xFC, 0x15, 0xE4, 0x9A, 0x0D, 0xE6, 0x9F, 0x1A, 0x77, 0xCE, 0x4C, 0x8F, + 0xB8, 0x14, 0x15, 0x3D, 0x62, 0x9C, 0x86, 0x38, 0x06, 0x00, 0x66, 0x12, + 0xE4, 0x59, 0x76, 0x5A, 0x53, 0xC0, 0x02, 0x98, 0xA2, 0x10, 0x2B, 0x68, + 0x44, 0x7B, 0x8E, 0x79, 0xCE, 0x33, 0x4A, 0x76, 0xAA, 0x5B, 0x81, 0x16, + 0x1B, 0xB5, 0x8A, 0xD8, 0xD0, 0x00, 0x7B, 0x5E, 0x62, 0xB4, 0x09, 0xD6, + 0x86, 0x63, 0x0E, 0xA6, 0x05, 0x95, 0x49, 0xBA, 0x28, 0x8B, 0x88, 0x93, + 0xB2, 0x34, 0x1C, 0xD8, 0xA4, 0x55, 0x6E, 0xB7, 0x1C, 0xD0, 0xDE, 0x99, + 0x55, 0x3B, 0x23, 0xF4, 0x22, 0xE0, 0xF9, 0x29, 0x66, 0x26, 0xEC, 0x20, + 0x50, 0x77, 0xDB, 0x4A, 0x0B, 0x8F, 0xBE, 0xE5, 0x02, 0x60, 0x70, 0x41, + 0x5E, 0xD4, 0xAE, 0x50, 0x39, 0x22, 0x14, 0x26, 0xCB, 0xB2, 0x3B, 0x73, + 0x74, 0x55, 0x47, 0x07, 0x79, 0x81, 0x39, 0xA8, 0x30, 0x13, 0x44, 0xE5, + 0x04, 0x8A, 0xAE, 0x96, 0x13, 0x25, 0x42, 0x0F, 0xB9, 0x53, 0xC4, 0x9B, + 0xFC, 0xCD, 0xE4, 0x1C, 0xDE, 0x3C, 0xFA, 0xAB, 0xD6, 0x06, 0x4A, 0x1F, + 0x67, 0xA6, 0x98, 0x30, 0x1C, 0xDD, 0x2C, 0xDB, 0xDC, 0x18, 0x95, 0x57, + 0x66, 0xC6, 0xFF, 0x5C, 0x8B, 0x56, 0xF5, 0x77 +}; + +static const unsigned char TA84_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA85_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x43, 0x41, 0x31 +}; + +static const unsigned char TA85_EC_Q[] = { + 0x04, 0xA4, 0xA5, 0x6F, 0x60, 0x03, 0x03, 0xC3, 0xBD, 0x31, 0xF4, 0xD3, + 0x17, 0x9C, 0x2B, 0x84, 0x75, 0xAC, 0xE5, 0xFD, 0x3D, 0x57, 0x6E, 0xD7, + 0x63, 0xBF, 0xE6, 0x04, 0x89, 0x92, 0x8E, 0x81, 0x9C, 0xE3, 0xE9, 0x47, + 0x6E, 0xCA, 0x90, 0x12, 0xC8, 0x13, 0xE0, 0xA7, 0x9D, 0xF7, 0x65, 0x74, + 0x1F, 0x6C, 0x10, 0xB2, 0xE8, 0xE4, 0xE9, 0xEF, 0x6D, 0x85, 0x32, 0x99, + 0x44, 0xB1, 0x5E, 0xFD, 0xCC, 0x76, 0x10, 0xD8, 0x5B, 0xBD, 0xA2, 0xC6, + 0xF9, 0xD6, 0x42, 0xE4, 0x57, 0x76, 0xDC, 0x90, 0xC2, 0x35, 0xA9, 0x4B, + 0x88, 0x3C, 0x12, 0x47, 0x6D, 0x5C, 0xFF, 0x49, 0x4F, 0x1A, 0x4A, 0x50, + 0xB1 +}; + +static const unsigned char TA86_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA86_EC_Q[] = { + 0x04, 0xF1, 0x0B, 0xDD, 0x86, 0x43, 0x20, 0x19, 0xDF, 0x97, 0x85, 0xE8, + 0x22, 0x4A, 0x9B, 0xCF, 0x9D, 0x98, 0xBF, 0xB4, 0x05, 0x26, 0xC9, 0xCB, + 0xE3, 0xA6, 0xD2, 0x8F, 0xC5, 0x9E, 0x78, 0x7B, 0x31, 0x89, 0xA9, 0x89, + 0xAD, 0x27, 0x3C, 0x65, 0x10, 0x82, 0xFC, 0xDF, 0xC3, 0x9D, 0x4E, 0xF0, + 0x33, 0x23, 0xC4, 0xD2, 0x32, 0xF5, 0x1C, 0xB0, 0xDF, 0x33, 0x17, 0x5D, + 0xC5, 0xF0, 0xB1, 0x8A, 0xF9, 0xEF, 0xB9, 0xB7, 0x14, 0xCA, 0x29, 0x4A, + 0xC2, 0x0F, 0xA9, 0x7F, 0x75, 0x65, 0x49, 0x2A, 0x30, 0x67, 0xF4, 0x64, + 0xF7, 0xD6, 0x1A, 0x77, 0xDA, 0xC3, 0xC2, 0x97, 0x61, 0x42, 0x7B, 0x49, + 0xAD +}; + +static const unsigned char TA87_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA87_EC_Q[] = { + 0x04, 0x4B, 0x36, 0xE9, 0xAE, 0x57, 0x5E, 0xA8, 0x70, 0xD7, 0xD0, 0x8F, + 0x74, 0x62, 0x77, 0xC3, 0x5E, 0x7A, 0xAA, 0xE5, 0xB6, 0xA2, 0xF1, 0x78, + 0xFD, 0x02, 0x7E, 0x57, 0xDD, 0x91, 0x79, 0x9C, 0x6C, 0xB9, 0x52, 0x88, + 0x54, 0xBC, 0x2F, 0x04, 0xBE, 0xB8, 0xCD, 0xF6, 0x10, 0xD1, 0x29, 0xEC, + 0xB5, 0xD0, 0xA0, 0xC3, 0xF0, 0x89, 0x70, 0x19, 0xBB, 0x51, 0x65, 0xC5, + 0x43, 0x9C, 0xC3, 0x9B, 0x63, 0x9D, 0x20, 0x83, 0x3E, 0x06, 0x0B, 0xA6, + 0x42, 0x44, 0x85, 0x11, 0xA7, 0x4A, 0x3A, 0x2D, 0xE9, 0xD6, 0x68, 0x2F, + 0x48, 0x4E, 0x53, 0x2B, 0x07, 0x3F, 0x4D, 0xBD, 0xB9, 0xAC, 0x77, 0x39, + 0x57 +}; + +static const unsigned char TA88_DN[] = { + 0x30, 0x81, 0x81, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA88_RSA_N[] = { + 0xD0, 0x40, 0x8B, 0x8B, 0x72, 0xE3, 0x91, 0x1B, 0xF7, 0x51, 0xC1, 0x1B, + 0x54, 0x04, 0x98, 0xD3, 0xA9, 0xBF, 0xC1, 0xE6, 0x8A, 0x5D, 0x3B, 0x87, + 0xFB, 0xBB, 0x88, 0xCE, 0x0D, 0xE3, 0x2F, 0x3F, 0x06, 0x96, 0xF0, 0xA2, + 0x29, 0x50, 0x99, 0xAE, 0xDB, 0x3B, 0xA1, 0x57, 0xB0, 0x74, 0x51, 0x71, + 0xCD, 0xED, 0x42, 0x91, 0x4D, 0x41, 0xFE, 0xA9, 0xC8, 0xD8, 0x6A, 0x86, + 0x77, 0x44, 0xBB, 0x59, 0x66, 0x97, 0x50, 0x5E, 0xB4, 0xD4, 0x2C, 0x70, + 0x44, 0xCF, 0xDA, 0x37, 0x95, 0x42, 0x69, 0x3C, 0x30, 0xC4, 0x71, 0xB3, + 0x52, 0xF0, 0x21, 0x4D, 0xA1, 0xD8, 0xBA, 0x39, 0x7C, 0x1C, 0x9E, 0xA3, + 0x24, 0x9D, 0xF2, 0x83, 0x16, 0x98, 0xAA, 0x16, 0x7C, 0x43, 0x9B, 0x15, + 0x5B, 0xB7, 0xAE, 0x34, 0x91, 0xFE, 0xD4, 0x62, 0x26, 0x18, 0x46, 0x9A, + 0x3F, 0xEB, 0xC1, 0xF9, 0xF1, 0x90, 0x57, 0xEB, 0xAC, 0x7A, 0x0D, 0x8B, + 0xDB, 0x72, 0x30, 0x6A, 0x66, 0xD5, 0xE0, 0x46, 0xA3, 0x70, 0xDC, 0x68, + 0xD9, 0xFF, 0x04, 0x48, 0x89, 0x77, 0xDE, 0xB5, 0xE9, 0xFB, 0x67, 0x6D, + 0x41, 0xE9, 0xBC, 0x39, 0xBD, 0x32, 0xD9, 0x62, 0x02, 0xF1, 0xB1, 0xA8, + 0x3D, 0x6E, 0x37, 0x9C, 0xE2, 0x2F, 0xE2, 0xD3, 0xA2, 0x26, 0x8B, 0xC6, + 0xB8, 0x55, 0x43, 0x88, 0xE1, 0x23, 0x3E, 0xA5, 0xD2, 0x24, 0x39, 0x6A, + 0x47, 0xAB, 0x00, 0xD4, 0xA1, 0xB3, 0xA9, 0x25, 0xFE, 0x0D, 0x3F, 0xA7, + 0x1D, 0xBA, 0xD3, 0x51, 0xC1, 0x0B, 0xA4, 0xDA, 0xAC, 0x38, 0xEF, 0x55, + 0x50, 0x24, 0x05, 0x65, 0x46, 0x93, 0x34, 0x4F, 0x2D, 0x8D, 0xAD, 0xC6, + 0xD4, 0x21, 0x19, 0xD2, 0x8E, 0xCA, 0x05, 0x61, 0x71, 0x07, 0x73, 0x47, + 0xE5, 0x8A, 0x19, 0x12, 0xBD, 0x04, 0x4D, 0xCE, 0x4E, 0x9C, 0xA5, 0x48, + 0xAC, 0xBB, 0x26, 0xF7 +}; + +static const unsigned char TA88_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA89_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x34 +}; + +static const unsigned char TA89_EC_Q[] = { + 0x04, 0xF3, 0x74, 0x73, 0xA7, 0x68, 0x8B, 0x60, 0xAE, 0x43, 0xB8, 0x35, + 0xC5, 0x81, 0x30, 0x7B, 0x4B, 0x49, 0x9D, 0xFB, 0xC1, 0x61, 0xCE, 0xE6, + 0xDE, 0x46, 0xBD, 0x6B, 0xD5, 0x61, 0x18, 0x35, 0xAE, 0x40, 0xDD, 0x73, + 0xF7, 0x89, 0x91, 0x30, 0x5A, 0xEB, 0x3C, 0xEE, 0x85, 0x7C, 0xA2, 0x40, + 0x76, 0x3B, 0xA9, 0xC6, 0xB8, 0x47, 0xD8, 0x2A, 0xE7, 0x92, 0x91, 0x6A, + 0x73, 0xE9, 0xB1, 0x72, 0x39, 0x9F, 0x29, 0x9F, 0xA2, 0x98, 0xD3, 0x5F, + 0x5E, 0x58, 0x86, 0x65, 0x0F, 0xA1, 0x84, 0x65, 0x06, 0xD1, 0xDC, 0x8B, + 0xC9, 0xC7, 0x73, 0xC8, 0x8C, 0x6A, 0x2F, 0xE5, 0xC4, 0xAB, 0xD1, 0x1D, + 0x8A +}; + +static const unsigned char TA90_DN[] = { + 0x30, 0x57, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, + 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA90_RSA_N[] = { + 0xDA, 0x0E, 0xE6, 0x99, 0x8D, 0xCE, 0xA3, 0xE3, 0x4F, 0x8A, 0x7E, 0xFB, + 0xF1, 0x8B, 0x83, 0x25, 0x6B, 0xEA, 0x48, 0x1F, 0xF1, 0x2A, 0xB0, 0xB9, + 0x95, 0x11, 0x04, 0xBD, 0xF0, 0x63, 0xD1, 0xE2, 0x67, 0x66, 0xCF, 0x1C, + 0xDD, 0xCF, 0x1B, 0x48, 0x2B, 0xEE, 0x8D, 0x89, 0x8E, 0x9A, 0xAF, 0x29, + 0x80, 0x65, 0xAB, 0xE9, 0xC7, 0x2D, 0x12, 0xCB, 0xAB, 0x1C, 0x4C, 0x70, + 0x07, 0xA1, 0x3D, 0x0A, 0x30, 0xCD, 0x15, 0x8D, 0x4F, 0xF8, 0xDD, 0xD4, + 0x8C, 0x50, 0x15, 0x1C, 0xEF, 0x50, 0xEE, 0xC4, 0x2E, 0xF7, 0xFC, 0xE9, + 0x52, 0xF2, 0x91, 0x7D, 0xE0, 0x6D, 0xD5, 0x35, 0x30, 0x8E, 0x5E, 0x43, + 0x73, 0xF2, 0x41, 0xE9, 0xD5, 0x6A, 0xE3, 0xB2, 0x89, 0x3A, 0x56, 0x39, + 0x38, 0x6F, 0x06, 0x3C, 0x88, 0x69, 0x5B, 0x2A, 0x4D, 0xC5, 0xA7, 0x54, + 0xB8, 0x6C, 0x89, 0xCC, 0x9B, 0xF9, 0x3C, 0xCA, 0xE5, 0xFD, 0x89, 0xF5, + 0x12, 0x3C, 0x92, 0x78, 0x96, 0xD6, 0xDC, 0x74, 0x6E, 0x93, 0x44, 0x61, + 0xD1, 0x8D, 0xC7, 0x46, 0xB2, 0x75, 0x0E, 0x86, 0xE8, 0x19, 0x8A, 0xD5, + 0x6D, 0x6C, 0xD5, 0x78, 0x16, 0x95, 0xA2, 0xE9, 0xC8, 0x0A, 0x38, 0xEB, + 0xF2, 0x24, 0x13, 0x4F, 0x73, 0x54, 0x93, 0x13, 0x85, 0x3A, 0x1B, 0xBC, + 0x1E, 0x34, 0xB5, 0x8B, 0x05, 0x8C, 0xB9, 0x77, 0x8B, 0xB1, 0xDB, 0x1F, + 0x20, 0x91, 0xAB, 0x09, 0x53, 0x6E, 0x90, 0xCE, 0x7B, 0x37, 0x74, 0xB9, + 0x70, 0x47, 0x91, 0x22, 0x51, 0x63, 0x16, 0x79, 0xAE, 0xB1, 0xAE, 0x41, + 0x26, 0x08, 0xC8, 0x19, 0x2B, 0xD1, 0x46, 0xAA, 0x48, 0xD6, 0x64, 0x2A, + 0xD7, 0x83, 0x34, 0xFF, 0x2C, 0x2A, 0xC1, 0x6C, 0x19, 0x43, 0x4A, 0x07, + 0x85, 0xE7, 0xD3, 0x7C, 0xF6, 0x21, 0x68, 0xEF, 0xEA, 0xF2, 0x52, 0x9F, + 0x7F, 0x93, 0x90, 0xCF +}; + +static const unsigned char TA90_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA91_DN[] = { + 0x30, 0x37, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0B, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x54, + 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, 0x20, 0x52, + 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x31 +}; + +static const unsigned char TA91_RSA_N[] = { + 0xC2, 0xBE, 0xEB, 0x27, 0xF0, 0x21, 0xA3, 0xF3, 0x69, 0x26, 0x55, 0x7E, + 0x9D, 0xC5, 0x55, 0x16, 0x91, 0x5C, 0xFD, 0xEF, 0x21, 0xBF, 0x53, 0x80, + 0x7A, 0x2D, 0xD2, 0x91, 0x8C, 0x63, 0x31, 0xF0, 0xEC, 0x24, 0xF0, 0xC3, + 0xA5, 0xD2, 0x72, 0x7C, 0x10, 0x6D, 0xF4, 0x37, 0xB7, 0xE5, 0xE6, 0x7C, + 0x79, 0xEA, 0x8C, 0xB5, 0x82, 0x8B, 0xAE, 0x48, 0xB6, 0xAC, 0x00, 0xDC, + 0x65, 0x75, 0xEC, 0x2A, 0x4D, 0x5F, 0xC1, 0x87, 0xF5, 0x20, 0x65, 0x2B, + 0x81, 0xA8, 0x47, 0x3E, 0x89, 0x23, 0x95, 0x30, 0x16, 0x90, 0x7F, 0xE8, + 0x57, 0x07, 0x48, 0xE7, 0x19, 0xAE, 0xBF, 0x45, 0x67, 0xB1, 0x37, 0x1B, + 0x06, 0x2A, 0xFE, 0xDE, 0xF9, 0xAC, 0x7D, 0x83, 0xFB, 0x5E, 0xBA, 0xE4, + 0x8F, 0x97, 0x67, 0xBE, 0x4B, 0x8E, 0x8D, 0x64, 0x07, 0x57, 0x38, 0x55, + 0x69, 0x34, 0x36, 0x3D, 0x13, 0x48, 0xEF, 0x4F, 0xE2, 0xD3, 0x66, 0x1E, + 0xA4, 0xCF, 0x1A, 0xB7, 0x5E, 0x36, 0x33, 0xD4, 0xB4, 0x06, 0xBD, 0x18, + 0x01, 0xFD, 0x77, 0x84, 0x50, 0x00, 0x45, 0xF5, 0x8C, 0x5D, 0xE8, 0x23, + 0xBC, 0x7E, 0xFE, 0x35, 0xE1, 0xED, 0x50, 0x7B, 0xA9, 0x30, 0x8D, 0x19, + 0xD3, 0x09, 0x8E, 0x68, 0x67, 0x5D, 0xBF, 0x3C, 0x97, 0x18, 0x53, 0xBB, + 0x29, 0x62, 0xC5, 0xCA, 0x5E, 0x72, 0xC1, 0xC7, 0x96, 0xD4, 0xDB, 0x2D, + 0xA0, 0xB4, 0x1F, 0x69, 0x03, 0xEC, 0xEA, 0xE2, 0x50, 0xF1, 0x0C, 0x3C, + 0xF0, 0xAC, 0xF3, 0x53, 0x2D, 0xF0, 0x1C, 0xF5, 0xED, 0x6C, 0x39, 0x39, + 0x73, 0x80, 0x16, 0xC8, 0x52, 0xB0, 0x23, 0xCD, 0xE0, 0x3E, 0xDC, 0xDD, + 0x3C, 0x47, 0xA0, 0xBB, 0x35, 0x8A, 0xE2, 0x98, 0x68, 0x8B, 0xBE, 0xE5, + 0xBF, 0x72, 0xEE, 0xD2, 0xFA, 0xA5, 0xED, 0x12, 0xED, 0xFC, 0x98, 0x18, + 0xA9, 0x26, 0x76, 0xDC, 0x28, 0x4B, 0x10, 0x20, 0x1C, 0xD3, 0x7F, 0x16, + 0x77, 0x2D, 0xED, 0x6F, 0x80, 0xF7, 0x49, 0xBB, 0x53, 0x05, 0xBB, 0x5D, + 0x68, 0xC7, 0xD4, 0xC8, 0x75, 0x16, 0x3F, 0x89, 0x5A, 0x8B, 0xF7, 0x17, + 0x47, 0xD4, 0x4C, 0xF1, 0xD2, 0x89, 0x79, 0x3E, 0x4D, 0x3D, 0x98, 0xA8, + 0x61, 0xDE, 0x3A, 0x1E, 0xD2, 0xF8, 0x5E, 0x03, 0xE0, 0xC1, 0xC9, 0x1C, + 0x8C, 0xD3, 0x8D, 0x4D, 0xD3, 0x95, 0x36, 0xB3, 0x37, 0x5F, 0x63, 0x63, + 0x9B, 0x33, 0x14, 0xF0, 0x2D, 0x26, 0x6B, 0x53, 0x7C, 0x89, 0x8C, 0x32, + 0xC2, 0x6E, 0xEC, 0x3D, 0x21, 0x00, 0x39, 0xC9, 0xA1, 0x68, 0xE2, 0x50, + 0x83, 0x2E, 0xB0, 0x3A, 0x2B, 0xF3, 0x36, 0xA0, 0xAC, 0x2F, 0xE4, 0x6F, + 0x61, 0xC2, 0x51, 0x09, 0x39, 0x3E, 0x8B, 0x53, 0xB9, 0xBB, 0x67, 0xDA, + 0xDC, 0x53, 0xB9, 0x76, 0x59, 0x36, 0x9D, 0x43, 0xE5, 0x20, 0xE0, 0x3D, + 0x32, 0x60, 0x85, 0x22, 0x51, 0xB7, 0xC7, 0x33, 0xBB, 0xDD, 0x15, 0x2F, + 0xA4, 0x78, 0xA6, 0x07, 0x7B, 0x81, 0x46, 0x36, 0x04, 0x86, 0xDD, 0x79, + 0x35, 0xC7, 0x95, 0x2C, 0x3B, 0xB0, 0xA3, 0x17, 0x35, 0xE5, 0x73, 0x1F, + 0xB4, 0x5C, 0x59, 0xEF, 0xDA, 0xEA, 0x10, 0x65, 0x7B, 0x7A, 0xD0, 0x7F, + 0x9F, 0xB3, 0xB4, 0x2A, 0x37, 0x3B, 0x70, 0x8B, 0x9B, 0x5B, 0xB9, 0x2B, + 0xB7, 0xEC, 0xB2, 0x51, 0x12, 0x97, 0x53, 0x29, 0x5A, 0xD4, 0xF0, 0x12, + 0x10, 0xDC, 0x4F, 0x02, 0xBB, 0x12, 0x92, 0x2F, 0x62, 0xD4, 0x3F, 0x69, + 0x43, 0x7C, 0x0D, 0xD6, 0xFC, 0x58, 0x75, 0x01, 0x88, 0x9D, 0x58, 0x16, + 0x4B, 0xDE, 0xBA, 0x90, 0xFF, 0x47, 0x01, 0x89, 0x06, 0x6A, 0xF6, 0x5F, + 0xB2, 0x90, 0x6A, 0xB3, 0x02, 0xA6, 0x02, 0x88, 0xBF, 0xB3, 0x47, 0x7E, + 0x2A, 0xD9, 0xD5, 0xFA, 0x68, 0x78, 0x35, 0x4D +}; + +static const unsigned char TA91_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA92_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x32 +}; + +static const unsigned char TA92_RSA_N[] = { + 0xBA, 0x39, 0xC1, 0x37, 0x7A, 0x68, 0x45, 0x2B, 0x14, 0xB4, 0xEB, 0xE4, + 0x13, 0xEB, 0x57, 0x75, 0x23, 0x4D, 0x8F, 0x24, 0x2D, 0x16, 0xE8, 0xAE, + 0x8E, 0xC9, 0x7D, 0xA4, 0x57, 0x3B, 0x2A, 0x76, 0x25, 0x33, 0x83, 0x6C, + 0xEA, 0x32, 0x8A, 0x94, 0x9B, 0x4E, 0x3C, 0x96, 0xE4, 0xFD, 0x51, 0xBF, + 0x99, 0xC9, 0x93, 0x7E, 0xBF, 0xF9, 0xAD, 0xA7, 0xB2, 0x48, 0x2B, 0x07, + 0x1C, 0x27, 0xF5, 0x4C, 0xBC, 0x70, 0x12, 0x77, 0xA4, 0x85, 0x54, 0xB5, + 0xFD, 0x90, 0x7A, 0xE4, 0xA3, 0xE4, 0x51, 0x58, 0x03, 0xCD, 0x10, 0x79, + 0x79, 0xEE, 0x6B, 0x93, 0x1F, 0x64, 0x8E, 0x6B, 0x64, 0xAB, 0xA3, 0x13, + 0xE3, 0x71, 0xFE, 0x7D, 0xAB, 0x9C, 0xDD, 0x27, 0x53, 0x37, 0xB3, 0xAA, + 0x18, 0xC2, 0x59, 0x26, 0xEC, 0x5B, 0x1F, 0xD2, 0xE6, 0x65, 0x7C, 0xEF, + 0x93, 0xBD, 0xD8, 0x58, 0x5C, 0x0B, 0xC0, 0xE3, 0x65, 0x6F, 0x3C, 0xC7, + 0xCA, 0x59, 0xE3, 0xFE, 0x6E, 0x5F, 0xAC, 0x83, 0xBE, 0xFD, 0x5D, 0x25, + 0x4E, 0x2A, 0x29, 0x3B, 0xD6, 0x0B, 0xAB, 0x17, 0x32, 0x78, 0xA4, 0xE1, + 0x3E, 0x94, 0x46, 0xBE, 0x62, 0x6E, 0x9B, 0xDE, 0x46, 0xA8, 0xB1, 0x16, + 0xE7, 0x85, 0x6E, 0xF4, 0x08, 0x40, 0x45, 0x11, 0xA0, 0x9E, 0x54, 0x44, + 0x84, 0xF7, 0xD8, 0x36, 0xCE, 0xF5, 0x50, 0x47, 0xDC, 0x2C, 0x30, 0x9B, + 0xEE, 0xC0, 0xF5, 0x96, 0xD2, 0xFE, 0x09, 0x86, 0xC7, 0x06, 0x59, 0xAE, + 0x4F, 0xAE, 0x8E, 0x11, 0x98, 0x7B, 0xF3, 0x0B, 0x52, 0xAA, 0x62, 0x26, + 0xAA, 0x21, 0xDF, 0x8E, 0x25, 0x33, 0x79, 0x97, 0x16, 0x49, 0x8D, 0xF5, + 0x3E, 0xD5, 0x47, 0x9F, 0x37, 0x31, 0x49, 0x33, 0x72, 0x05, 0x4D, 0x0C, + 0xB6, 0x55, 0x8C, 0xF1, 0x57, 0x8F, 0x8A, 0x87, 0xD1, 0xAD, 0xC5, 0x11, + 0x12, 0x39, 0xA0, 0xAD +}; + +static const unsigned char TA92_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA93_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x13, 0x54, 0x57, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, + 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA93_RSA_N[] = { + 0xB0, 0x05, 0xDB, 0xC8, 0xEB, 0x8C, 0xC4, 0x6E, 0x8A, 0x21, 0xEF, 0x8E, + 0x4D, 0x9C, 0x71, 0x0A, 0x1F, 0x52, 0x70, 0xED, 0x6D, 0x82, 0x9C, 0x97, + 0xC5, 0xD7, 0x4C, 0x4E, 0x45, 0x49, 0xCB, 0x40, 0x42, 0xB5, 0x12, 0x34, + 0x6C, 0x19, 0xC2, 0x74, 0xA4, 0x31, 0x5F, 0x85, 0x02, 0x97, 0xEC, 0x43, + 0x33, 0x0A, 0x53, 0xD2, 0x9C, 0x8C, 0x8E, 0xB7, 0xB8, 0x79, 0xDB, 0x2B, + 0xD5, 0x6A, 0xF2, 0x8E, 0x66, 0xC4, 0xEE, 0x2B, 0x01, 0x07, 0x92, 0xD4, + 0xB3, 0xD0, 0x02, 0xDF, 0x50, 0xF6, 0x55, 0xAF, 0x66, 0x0E, 0xCB, 0xE0, + 0x47, 0x60, 0x2F, 0x2B, 0x32, 0x39, 0x35, 0x52, 0x3A, 0x28, 0x83, 0xF8, + 0x7B, 0x16, 0xC6, 0x18, 0xB8, 0x62, 0xD6, 0x47, 0x25, 0x91, 0xCE, 0xF0, + 0x19, 0x12, 0x4D, 0xAD, 0x63, 0xF5, 0xD3, 0x3F, 0x75, 0x5F, 0x29, 0xF0, + 0xA1, 0x30, 0x1C, 0x2A, 0xA0, 0x98, 0xA6, 0x15, 0xBD, 0xEE, 0xFD, 0x19, + 0x36, 0xF0, 0xE2, 0x91, 0x43, 0x8F, 0xFA, 0xCA, 0xD6, 0x10, 0x27, 0x49, + 0x4C, 0xEF, 0xDD, 0xC1, 0xF1, 0x85, 0x70, 0x9B, 0xCA, 0xEA, 0xA8, 0x5A, + 0x43, 0xFC, 0x6D, 0x86, 0x6F, 0x73, 0xE9, 0x37, 0x45, 0xA9, 0xF0, 0x36, + 0xC7, 0xCC, 0x88, 0x75, 0x1E, 0xBB, 0x6C, 0x06, 0xFF, 0x9B, 0x6B, 0x3E, + 0x17, 0xEC, 0x61, 0xAA, 0x71, 0x7C, 0xC6, 0x1D, 0xA2, 0xF7, 0x49, 0xE9, + 0x15, 0xB5, 0x3C, 0xD6, 0xA1, 0x61, 0xF5, 0x11, 0xF7, 0x05, 0x6F, 0x1D, + 0xFD, 0x11, 0xBE, 0xD0, 0x30, 0x07, 0xC2, 0x29, 0xB0, 0x09, 0x4E, 0x26, + 0xDC, 0xE3, 0xA2, 0xA8, 0x91, 0x6A, 0x1F, 0xC2, 0x91, 0x45, 0x88, 0x5C, + 0xE5, 0x98, 0xB8, 0x71, 0xA5, 0x15, 0x19, 0xC9, 0x7C, 0x75, 0x11, 0xCC, + 0x70, 0x74, 0x4F, 0x2D, 0x9B, 0x1D, 0x91, 0x44, 0xFD, 0x56, 0x28, 0xA0, + 0xFE, 0xBB, 0x86, 0x6A, 0xC8, 0xFA, 0x5C, 0x0B, 0x58, 0xDC, 0xC6, 0x4B, + 0x76, 0xC8, 0xAB, 0x22, 0xD9, 0x73, 0x0F, 0xA5, 0xF4, 0x5A, 0x02, 0x89, + 0x3F, 0x4F, 0x9E, 0x22, 0x82, 0xEE, 0xA2, 0x74, 0x53, 0x2A, 0x3D, 0x53, + 0x27, 0x69, 0x1D, 0x6C, 0x8E, 0x32, 0x2C, 0x64, 0x00, 0x26, 0x63, 0x61, + 0x36, 0x4E, 0xA3, 0x46, 0xB7, 0x3F, 0x7D, 0xB3, 0x2D, 0xAC, 0x6D, 0x90, + 0xA2, 0x95, 0xA2, 0xCE, 0xCF, 0xDA, 0x82, 0xE7, 0x07, 0x34, 0x19, 0x96, + 0xE9, 0xB8, 0x21, 0xAA, 0x29, 0x7E, 0xA6, 0x38, 0xBE, 0x8E, 0x29, 0x4A, + 0x21, 0x66, 0x79, 0x1F, 0xB3, 0xC3, 0xB5, 0x09, 0x67, 0xDE, 0xD6, 0xD4, + 0x07, 0x46, 0xF3, 0x2A, 0xDA, 0xE6, 0x22, 0x37, 0x60, 0xCB, 0x81, 0xB6, + 0x0F, 0xA0, 0x0F, 0xE9, 0xC8, 0x95, 0x7F, 0xBF, 0x55, 0x91, 0x05, 0x7A, + 0xCF, 0x3D, 0x15, 0xC0, 0x6F, 0xDE, 0x09, 0x94, 0x01, 0x83, 0xD7, 0x34, + 0x1B, 0xCC, 0x40, 0xA5, 0xF0, 0xB8, 0x9B, 0x67, 0xD5, 0x98, 0x91, 0x3B, + 0xA7, 0x84, 0x78, 0x95, 0x26, 0xA4, 0x5A, 0x08, 0xF8, 0x2B, 0x74, 0xB4, + 0x00, 0x04, 0x3C, 0xDF, 0xB8, 0x14, 0x8E, 0xE8, 0xDF, 0xA9, 0x8D, 0x6C, + 0x67, 0x92, 0x33, 0x1D, 0xC0, 0xB7, 0xD2, 0xEC, 0x92, 0xC8, 0xBE, 0x09, + 0xBF, 0x2C, 0x29, 0x05, 0x6F, 0x02, 0x6B, 0x9E, 0xEF, 0xBC, 0xBF, 0x2A, + 0xBC, 0x5B, 0xC0, 0x50, 0x8F, 0x41, 0x70, 0x71, 0x87, 0xB2, 0x4D, 0xB7, + 0x04, 0xA9, 0x84, 0xA3, 0x32, 0xAF, 0xAE, 0xEE, 0x6B, 0x17, 0x8B, 0xB2, + 0xB1, 0xFE, 0x6C, 0xE1, 0x90, 0x8C, 0x88, 0xA8, 0x97, 0x48, 0xCE, 0xC8, + 0x4D, 0xCB, 0xF3, 0x06, 0xCF, 0x5F, 0x6A, 0x0A, 0x42, 0xB1, 0x1E, 0x1E, + 0x77, 0x2F, 0x8E, 0xA0, 0xE6, 0x92, 0x0E, 0x06, 0xFC, 0x05, 0x22, 0xD2, + 0x26, 0xE1, 0x31, 0x51, 0x7D, 0x32, 0xDC, 0x0F +}; + +static const unsigned char TA93_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA94_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x54, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x05, 0x4D, 0x69, 0x6C, 0x61, 0x6E, 0x31, 0x23, 0x30, 0x21, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x1A, 0x41, 0x63, 0x74, 0x61, 0x6C, 0x69, + 0x73, 0x20, 0x53, 0x2E, 0x70, 0x2E, 0x41, 0x2E, 0x2F, 0x30, 0x33, 0x33, + 0x35, 0x38, 0x35, 0x32, 0x30, 0x39, 0x36, 0x37, 0x31, 0x27, 0x30, 0x25, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x41, 0x63, 0x74, 0x61, 0x6C, + 0x69, 0x73, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA94_RSA_N[] = { + 0xA7, 0xC6, 0xC4, 0xA5, 0x29, 0xA4, 0x2C, 0xEF, 0xE5, 0x18, 0xC5, 0xB0, + 0x50, 0xA3, 0x6F, 0x51, 0x3B, 0x9F, 0x0A, 0x5A, 0xC9, 0xC2, 0x48, 0x38, + 0x0A, 0xC2, 0x1C, 0xA0, 0x18, 0x7F, 0x91, 0xB5, 0x87, 0xB9, 0x40, 0x3F, + 0xDD, 0x1D, 0x68, 0x1F, 0x08, 0x83, 0xD5, 0x2D, 0x1E, 0x88, 0xA0, 0xF8, + 0x8F, 0x56, 0x8F, 0x6D, 0x99, 0x02, 0x92, 0x90, 0x16, 0xD5, 0x5F, 0x08, + 0x6C, 0x89, 0xD7, 0xE1, 0xAC, 0xBC, 0x20, 0xC2, 0xB1, 0xE0, 0x83, 0x51, + 0x8A, 0x69, 0x4D, 0x00, 0x96, 0x5A, 0x6F, 0x2F, 0xC0, 0x44, 0x7E, 0xA3, + 0x0E, 0xE4, 0x91, 0xCD, 0x58, 0xEE, 0xDC, 0xFB, 0xC7, 0x1E, 0x45, 0x47, + 0xDD, 0x27, 0xB9, 0x08, 0x01, 0x9F, 0xA6, 0x21, 0x1D, 0xF5, 0x41, 0x2D, + 0x2F, 0x4C, 0xFD, 0x28, 0xAD, 0xE0, 0x8A, 0xAD, 0x22, 0xB4, 0x56, 0x65, + 0x8E, 0x86, 0x54, 0x8F, 0x93, 0x43, 0x29, 0xDE, 0x39, 0x46, 0x78, 0xA3, + 0x30, 0x23, 0xBA, 0xCD, 0xF0, 0x7D, 0x13, 0x57, 0xC0, 0x5D, 0xD2, 0x83, + 0x6B, 0x48, 0x4C, 0xC4, 0xAB, 0x9F, 0x80, 0x5A, 0x5B, 0x3A, 0xBD, 0xC9, + 0xA7, 0x22, 0x3F, 0x80, 0x27, 0x33, 0x5B, 0x0E, 0xB7, 0x8A, 0x0C, 0x5D, + 0x07, 0x37, 0x08, 0xCB, 0x6C, 0xD2, 0x7A, 0x47, 0x22, 0x44, 0x35, 0xC5, + 0xCC, 0xCC, 0x2E, 0x8E, 0xDD, 0x2A, 0xED, 0xB7, 0x7D, 0x66, 0x0D, 0x5F, + 0x61, 0x51, 0x22, 0x55, 0x1B, 0xE3, 0x46, 0xE3, 0xE3, 0x3D, 0xD0, 0x35, + 0x62, 0x9A, 0xDB, 0xAF, 0x14, 0xC8, 0x5B, 0xA1, 0xCC, 0x89, 0x1B, 0xE1, + 0x30, 0x26, 0xFC, 0xA0, 0x9B, 0x1F, 0x81, 0xA7, 0x47, 0x1F, 0x04, 0xEB, + 0xA3, 0x39, 0x92, 0x06, 0x9F, 0x99, 0xD3, 0xBF, 0xD3, 0xEA, 0x4F, 0x50, + 0x9C, 0x19, 0xFE, 0x96, 0x87, 0x1E, 0x3C, 0x65, 0xF6, 0xA3, 0x18, 0x24, + 0x83, 0x86, 0x10, 0xE7, 0x54, 0x3E, 0xA8, 0x3A, 0x76, 0x24, 0x4F, 0x81, + 0x21, 0xC5, 0xE3, 0x0F, 0x02, 0xF8, 0x93, 0x94, 0x47, 0x20, 0xBB, 0xFE, + 0xD4, 0x0E, 0xD3, 0x68, 0xB9, 0xDD, 0xC4, 0x7A, 0x84, 0x82, 0xE3, 0x53, + 0x54, 0x79, 0xDD, 0xDB, 0x9C, 0xD2, 0xF2, 0x07, 0x9B, 0x2E, 0xB6, 0xBC, + 0x3E, 0xED, 0x85, 0x6D, 0xEF, 0x25, 0x11, 0xF2, 0x97, 0x1A, 0x42, 0x61, + 0xF7, 0x4A, 0x97, 0xE8, 0x8B, 0xB1, 0x10, 0x07, 0xFA, 0x65, 0x81, 0xB2, + 0xA2, 0x39, 0xCF, 0xF7, 0x3C, 0xFF, 0x18, 0xFB, 0xC6, 0xF1, 0x5A, 0x8B, + 0x59, 0xE2, 0x02, 0xAC, 0x7B, 0x92, 0xD0, 0x4E, 0x14, 0x4F, 0x59, 0x45, + 0xF6, 0x0C, 0x5E, 0x28, 0x5F, 0xB0, 0xE8, 0x3F, 0x45, 0xCF, 0xCF, 0xAF, + 0x9B, 0x6F, 0xFB, 0x84, 0xD3, 0x77, 0x5A, 0x95, 0x6F, 0xAC, 0x94, 0x84, + 0x9E, 0xEE, 0xBC, 0xC0, 0x4A, 0x8F, 0x4A, 0x93, 0xF8, 0x44, 0x21, 0xE2, + 0x31, 0x45, 0x61, 0x50, 0x4E, 0x10, 0xD8, 0xE3, 0x35, 0x7C, 0x4C, 0x19, + 0xB4, 0xDE, 0x05, 0xBF, 0xA3, 0x06, 0x9F, 0xC8, 0xB5, 0xCD, 0xE4, 0x1F, + 0xD7, 0x17, 0x06, 0x0D, 0x7A, 0x95, 0x74, 0x55, 0x0D, 0x68, 0x1A, 0xFC, + 0x10, 0x1B, 0x62, 0x64, 0x9D, 0x6D, 0xE0, 0x95, 0xA0, 0xC3, 0x94, 0x07, + 0x57, 0x0D, 0x14, 0xE6, 0xBD, 0x05, 0xFB, 0xB8, 0x9F, 0xE6, 0xDF, 0x8B, + 0xE2, 0xC6, 0xE7, 0x7E, 0x96, 0xF6, 0x53, 0xC5, 0x80, 0x34, 0x50, 0x28, + 0x58, 0xF0, 0x12, 0x50, 0x71, 0x17, 0x30, 0xBA, 0xE6, 0x78, 0x63, 0xBC, + 0xF4, 0xB2, 0xAD, 0x9B, 0x2B, 0xB2, 0xFE, 0xE1, 0x39, 0x8C, 0x5E, 0xBA, + 0x0B, 0x20, 0x94, 0xDE, 0x7B, 0x83, 0xB8, 0xFF, 0xE3, 0x56, 0x8D, 0xB7, + 0x11, 0xE9, 0x3B, 0x8C, 0xF2, 0xB1, 0xC1, 0x5D, 0x9D, 0xA4, 0x0B, 0x4C, + 0x2B, 0xD9, 0xB2, 0x18, 0xF5, 0xB5, 0x9F, 0x4B +}; + +static const unsigned char TA94_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA95_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x43, 0x45, 0x52, 0x54, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x53, + 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x13, + 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, + 0x54, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA95_RSA_N[] = { + 0xC0, 0xC5, 0x75, 0x19, 0x91, 0x7D, 0x44, 0x74, 0x74, 0x87, 0xFE, 0x0E, + 0x3B, 0x96, 0xDC, 0xD8, 0x01, 0x16, 0xCC, 0xEE, 0x63, 0x91, 0xE7, 0x0B, + 0x6F, 0xCE, 0x3B, 0x0A, 0x69, 0x1A, 0x7C, 0xC2, 0xE3, 0xAF, 0x82, 0x8E, + 0x86, 0xD7, 0x5E, 0x8F, 0x57, 0xEB, 0xD3, 0x21, 0x59, 0xFD, 0x39, 0x37, + 0x42, 0x30, 0xBE, 0x50, 0xEA, 0xB6, 0x0F, 0xA9, 0x88, 0xD8, 0x2E, 0x2D, + 0x69, 0x21, 0xE7, 0xD1, 0x37, 0x18, 0x4E, 0x7D, 0x91, 0xD5, 0x16, 0x5F, + 0x6B, 0x5B, 0x00, 0xC2, 0x39, 0x43, 0x0D, 0x36, 0x85, 0x52, 0xB9, 0x53, + 0x65, 0x0F, 0x1D, 0x42, 0xE5, 0x8F, 0xCF, 0x05, 0xD3, 0xEE, 0xDC, 0x0C, + 0x1A, 0xD9, 0xB8, 0x8B, 0x78, 0x22, 0x67, 0xE4, 0x69, 0xB0, 0x68, 0xC5, + 0x3C, 0xE4, 0x6C, 0x5A, 0x46, 0xE7, 0xCD, 0xC7, 0xFA, 0xEF, 0xC4, 0xEC, + 0x4B, 0xBD, 0x6A, 0xA4, 0xAC, 0xFD, 0xCC, 0x28, 0x51, 0xEF, 0x92, 0xB4, + 0x29, 0xAB, 0xAB, 0x35, 0x9A, 0x4C, 0xE4, 0xC4, 0x08, 0xC6, 0x26, 0xCC, + 0xF8, 0x69, 0x9F, 0xE4, 0x9C, 0xF0, 0x29, 0xD3, 0x5C, 0xF9, 0xC6, 0x16, + 0x25, 0x9E, 0x23, 0xC3, 0x20, 0xC1, 0x3D, 0x0F, 0x3F, 0x38, 0x40, 0xB0, + 0xFE, 0x82, 0x44, 0x38, 0xAA, 0x5A, 0x1A, 0x8A, 0x6B, 0x63, 0x58, 0x38, + 0xB4, 0x15, 0xD3, 0xB6, 0x11, 0x69, 0x7B, 0x1E, 0x54, 0xEE, 0x8C, 0x1A, + 0x22, 0xAC, 0x72, 0x97, 0x3F, 0x23, 0x59, 0x9B, 0xC9, 0x22, 0x84, 0xC1, + 0x07, 0x4F, 0xCC, 0x7F, 0xE2, 0x57, 0xCA, 0x12, 0x70, 0xBB, 0xA6, 0x65, + 0xF3, 0x69, 0x75, 0x63, 0xBD, 0x95, 0xFB, 0x1B, 0x97, 0xCD, 0xE4, 0xA8, + 0xAF, 0xF6, 0xD1, 0x4E, 0xA8, 0xD9, 0x8A, 0x71, 0x24, 0xCD, 0x36, 0x3D, + 0xBC, 0x96, 0xC4, 0xF1, 0x6C, 0xA9, 0xAE, 0xE5, 0xCF, 0x0D, 0x6E, 0x28, + 0x0D, 0xB0, 0x0E, 0xB5, 0xCA, 0x51, 0x7B, 0x78, 0x14, 0xC3, 0x20, 0x2F, + 0x7F, 0xFB, 0x14, 0x55, 0xE1, 0x11, 0x99, 0xFD, 0xD5, 0x0A, 0xA1, 0x9E, + 0x02, 0xE3, 0x62, 0x5F, 0xEB, 0x35, 0x4B, 0x2C, 0xB8, 0x72, 0xE8, 0x3E, + 0x3D, 0x4F, 0xAC, 0x2C, 0xBB, 0x2E, 0x86, 0xE2, 0xA3, 0x76, 0x8F, 0xE5, + 0x93, 0x2A, 0xCF, 0xA5, 0xAB, 0xC8, 0x5C, 0x8D, 0x4B, 0x06, 0xFF, 0x12, + 0x46, 0xAC, 0x78, 0xCB, 0x14, 0x07, 0x35, 0xE0, 0xA9, 0xDF, 0x8B, 0xE9, + 0xAF, 0x15, 0x4F, 0x16, 0x89, 0x5B, 0xBD, 0xF6, 0x8D, 0xC6, 0x59, 0xAE, + 0x88, 0x85, 0x0E, 0xC1, 0x89, 0xEB, 0x1F, 0x67, 0xC5, 0x45, 0x8E, 0xFF, + 0x6D, 0x37, 0x36, 0x2B, 0x78, 0x66, 0x83, 0x91, 0x51, 0x2B, 0x3D, 0xFF, + 0x51, 0x77, 0x76, 0x62, 0xA1, 0xEC, 0x67, 0x3E, 0x3E, 0x81, 0x83, 0xE0, + 0x56, 0xA9, 0x50, 0x1F, 0x1F, 0x7A, 0x99, 0xAB, 0x63, 0xBF, 0x84, 0x17, + 0x77, 0xF1, 0x0D, 0x3B, 0xDF, 0xF7, 0x9C, 0x61, 0xB3, 0x35, 0x98, 0x8A, + 0x3A, 0xB2, 0xEC, 0x3C, 0x1A, 0x37, 0x3F, 0x7E, 0x8F, 0x92, 0xCF, 0xD9, + 0x12, 0x14, 0x64, 0xDA, 0x10, 0x02, 0x15, 0x41, 0xFF, 0x4F, 0xC4, 0xEB, + 0x1C, 0xA3, 0xC9, 0xFA, 0x99, 0xF7, 0x46, 0xE9, 0xE1, 0x18, 0xD9, 0xB1, + 0xB8, 0x32, 0x2D, 0xCB, 0x14, 0x0C, 0x50, 0xD8, 0x83, 0x65, 0x83, 0xEE, + 0xB9, 0x5C, 0xCF, 0xCB, 0x05, 0x5A, 0x4C, 0xFA, 0x19, 0x97, 0x6B, 0xD6, + 0x5D, 0x13, 0xD3, 0xC2, 0x5C, 0x54, 0xBC, 0x32, 0x73, 0xA0, 0x78, 0xF5, + 0xF1, 0x6D, 0x1E, 0xCB, 0x9F, 0xA5, 0xA6, 0x9F, 0x22, 0xDC, 0xD1, 0x51, + 0x9E, 0x82, 0x79, 0x64, 0x60, 0x29, 0x13, 0x3E, 0xA3, 0xFD, 0x4F, 0x72, + 0x6A, 0xAB, 0xE2, 0xD4, 0xE5, 0xB8, 0x24, 0x55, 0x2C, 0x44, 0x4B, 0x8A, + 0x88, 0x44, 0x9C, 0xCA, 0x84, 0xD3, 0x2A, 0x3B +}; + +static const unsigned char TA95_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA96_DN[] = { + 0x30, 0x78, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x0E, + 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x05, 0x43, 0x65, 0x72, + 0x65, 0x73, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, + 0x0F, 0x56, 0x41, 0x54, 0x45, 0x53, 0x2D, 0x51, 0x32, 0x38, 0x32, 0x36, + 0x30, 0x30, 0x34, 0x4A, 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x23, 0x41, 0x43, 0x20, 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, + 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x20, 0x53, 0x45, 0x52, 0x56, + 0x49, 0x44, 0x4F, 0x52, 0x45, 0x53, 0x20, 0x53, 0x45, 0x47, 0x55, 0x52, + 0x4F, 0x53 +}; + +static const unsigned char TA96_EC_Q[] = { + 0x04, 0xF6, 0xBA, 0x57, 0x53, 0xC8, 0xCA, 0xAB, 0xDF, 0x36, 0x4A, 0x52, + 0x21, 0xE4, 0x97, 0xD2, 0x83, 0x67, 0x9E, 0xF0, 0x65, 0x51, 0xD0, 0x5E, + 0x87, 0xC7, 0x47, 0xB1, 0x59, 0xF2, 0x57, 0x47, 0x9B, 0x00, 0x02, 0x93, + 0x44, 0x17, 0x69, 0xDB, 0x42, 0xC7, 0xB1, 0xB2, 0x3A, 0x18, 0x0E, 0xB4, + 0x5D, 0x8C, 0xB3, 0x66, 0x5D, 0xA1, 0x34, 0xF9, 0x36, 0x2C, 0x49, 0xDB, + 0xF3, 0x46, 0xFC, 0xB3, 0x44, 0x69, 0x44, 0x13, 0x66, 0xFD, 0xD7, 0xC5, + 0xFD, 0xAF, 0x36, 0x4D, 0xCE, 0x03, 0x4D, 0x07, 0x71, 0xCF, 0xAF, 0x6A, + 0x05, 0xD2, 0xA2, 0x43, 0x5A, 0x0A, 0x52, 0x6F, 0x01, 0x03, 0x4E, 0x8E, + 0x8B +}; + +static const unsigned char TA97_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x45, 0x31 +}; + +static const unsigned char TA97_EC_Q[] = { + 0x04, 0xDE, 0x6F, 0xF8, 0x7F, 0x1C, 0xDF, 0xED, 0xF9, 0x47, 0x87, 0x86, + 0xB1, 0xA4, 0xC0, 0x8A, 0xF8, 0x82, 0x97, 0x80, 0xEA, 0x8F, 0xC8, 0x4A, + 0x5E, 0x2A, 0x7D, 0x88, 0x68, 0xA7, 0x01, 0x62, 0x14, 0x91, 0x24, 0x7A, + 0x5C, 0x9E, 0xA3, 0x17, 0x7D, 0x8A, 0x86, 0x21, 0x34, 0x18, 0x50, 0x1B, + 0x10, 0xDE, 0xD0, 0x37, 0x4B, 0x26, 0xC7, 0x19, 0x60, 0x80, 0xE9, 0x34, + 0xBD, 0x60, 0x19, 0x36, 0x40, 0xD6, 0x29, 0x87, 0x09, 0x3C, 0x91, 0x7A, + 0xF6, 0xBC, 0x13, 0x23, 0xDD, 0x59, 0x4E, 0x04, 0x5E, 0xCF, 0xC8, 0x02, + 0x1C, 0x18, 0x53, 0xC1, 0x31, 0xD8, 0xDA, 0x20, 0xE9, 0x44, 0x8D, 0xE4, + 0x76 +}; + +static const unsigned char TA98_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x32 +}; + +static const unsigned char TA98_RSA_N[] = { + 0xBB, 0x37, 0xCD, 0x34, 0xDC, 0x7B, 0x6B, 0xC9, 0xB2, 0x68, 0x90, 0xAD, + 0x4A, 0x75, 0xFF, 0x46, 0xBA, 0x21, 0x0A, 0x08, 0x8D, 0xF5, 0x19, 0x54, + 0xC9, 0xFB, 0x88, 0xDB, 0xF3, 0xAE, 0xF2, 0x3A, 0x89, 0x91, 0x3C, 0x7A, + 0xE6, 0xAB, 0x06, 0x1A, 0x6B, 0xCF, 0xAC, 0x2D, 0xE8, 0x5E, 0x09, 0x24, + 0x44, 0xBA, 0x62, 0x9A, 0x7E, 0xD6, 0xA3, 0xA8, 0x7E, 0xE0, 0x54, 0x75, + 0x20, 0x05, 0xAC, 0x50, 0xB7, 0x9C, 0x63, 0x1A, 0x6C, 0x30, 0xDC, 0xDA, + 0x1F, 0x19, 0xB1, 0xD7, 0x1E, 0xDE, 0xFD, 0xD7, 0xE0, 0xCB, 0x94, 0x83, + 0x37, 0xAE, 0xEC, 0x1F, 0x43, 0x4E, 0xDD, 0x7B, 0x2C, 0xD2, 0xBD, 0x2E, + 0xA5, 0x2F, 0xE4, 0xA9, 0xB8, 0xAD, 0x3A, 0xD4, 0x99, 0xA4, 0xB6, 0x25, + 0xE9, 0x9B, 0x6B, 0x00, 0x60, 0x92, 0x60, 0xFF, 0x4F, 0x21, 0x49, 0x18, + 0xF7, 0x67, 0x90, 0xAB, 0x61, 0x06, 0x9C, 0x8F, 0xF2, 0xBA, 0xE9, 0xB4, + 0xE9, 0x92, 0x32, 0x6B, 0xB5, 0xF3, 0x57, 0xE8, 0x5D, 0x1B, 0xCD, 0x8C, + 0x1D, 0xAB, 0x95, 0x04, 0x95, 0x49, 0xF3, 0x35, 0x2D, 0x96, 0xE3, 0x49, + 0x6D, 0xDD, 0x77, 0xE3, 0xFB, 0x49, 0x4B, 0xB4, 0xAC, 0x55, 0x07, 0xA9, + 0x8F, 0x95, 0xB3, 0xB4, 0x23, 0xBB, 0x4C, 0x6D, 0x45, 0xF0, 0xF6, 0xA9, + 0xB2, 0x95, 0x30, 0xB4, 0xFD, 0x4C, 0x55, 0x8C, 0x27, 0x4A, 0x57, 0x14, + 0x7C, 0x82, 0x9D, 0xCD, 0x73, 0x92, 0xD3, 0x16, 0x4A, 0x06, 0x0C, 0x8C, + 0x50, 0xD1, 0x8F, 0x1E, 0x09, 0xBE, 0x17, 0xA1, 0xE6, 0x21, 0xCA, 0xFD, + 0x83, 0xE5, 0x10, 0xBC, 0x83, 0xA5, 0x0A, 0xC4, 0x67, 0x28, 0xF6, 0x73, + 0x14, 0x14, 0x3D, 0x46, 0x76, 0xC3, 0x87, 0x14, 0x89, 0x21, 0x34, 0x4D, + 0xAF, 0x0F, 0x45, 0x0C, 0xA6, 0x49, 0xA1, 0xBA, 0xBB, 0x9C, 0xC5, 0xB1, + 0x33, 0x83, 0x29, 0x85 +}; + +static const unsigned char TA98_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA99_DN[] = { + 0x30, 0x81, 0xA7, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x4E, 0x65, + 0x74, 0x4C, 0x6F, 0x63, 0x6B, 0x20, 0x4B, 0x66, 0x74, 0x2E, 0x31, 0x37, + 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x2E, 0x54, 0x61, 0x6E, + 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, 0x6E, 0x79, 0x6B, + 0x69, 0x61, 0x64, 0xC3, 0xB3, 0x6B, 0x20, 0x28, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x29, 0x31, 0x35, 0x30, 0x33, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x2C, 0x4E, 0x65, 0x74, 0x4C, 0x6F, 0x63, + 0x6B, 0x20, 0x41, 0x72, 0x61, 0x6E, 0x79, 0x20, 0x28, 0x43, 0x6C, 0x61, + 0x73, 0x73, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x29, 0x20, 0x46, 0xC5, 0x91, + 0x74, 0x61, 0x6E, 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, + 0x6E, 0x79 +}; + +static const unsigned char TA99_RSA_N[] = { + 0xC4, 0x24, 0x5E, 0x73, 0xBE, 0x4B, 0x6D, 0x14, 0xC3, 0xA1, 0xF4, 0xE3, + 0x97, 0x90, 0x6E, 0xD2, 0x30, 0x45, 0x1E, 0x3C, 0xEE, 0x67, 0xD9, 0x64, + 0xE0, 0x1A, 0x8A, 0x7F, 0xCA, 0x30, 0xCA, 0x83, 0xE3, 0x20, 0xC1, 0xE3, + 0xF4, 0x3A, 0xD3, 0x94, 0x5F, 0x1A, 0x7C, 0x5B, 0x6D, 0xBF, 0x30, 0x4F, + 0x84, 0x27, 0xF6, 0x9F, 0x1F, 0x49, 0xBC, 0xC6, 0x99, 0x0A, 0x90, 0xF2, + 0x0F, 0xF5, 0x7F, 0x43, 0x84, 0x37, 0x63, 0x51, 0x8B, 0x7A, 0xA5, 0x70, + 0xFC, 0x7A, 0x58, 0xCD, 0x8E, 0x9B, 0xED, 0xC3, 0x46, 0x6C, 0x84, 0x70, + 0x5D, 0xDA, 0xF3, 0x01, 0x90, 0x23, 0xFC, 0x4E, 0x30, 0xA9, 0x7E, 0xE1, + 0x27, 0x63, 0xE7, 0xED, 0x64, 0x3C, 0xA0, 0xB8, 0xC9, 0x33, 0x63, 0xFE, + 0x16, 0x90, 0xFF, 0xB0, 0xB8, 0xFD, 0xD7, 0xA8, 0xC0, 0xC0, 0x94, 0x43, + 0x0B, 0xB6, 0xD5, 0x59, 0xA6, 0x9E, 0x56, 0xD0, 0x24, 0x1F, 0x70, 0x79, + 0xAF, 0xDB, 0x39, 0x54, 0x0D, 0x65, 0x75, 0xD9, 0x15, 0x41, 0x94, 0x01, + 0xAF, 0x5E, 0xEC, 0xF6, 0x8D, 0xF1, 0xFF, 0xAD, 0x64, 0xFE, 0x20, 0x9A, + 0xD7, 0x5C, 0xEB, 0xFE, 0xA6, 0x1F, 0x08, 0x64, 0xA3, 0x8B, 0x76, 0x55, + 0xAD, 0x1E, 0x3B, 0x28, 0x60, 0x2E, 0x87, 0x25, 0xE8, 0xAA, 0xAF, 0x1F, + 0xC6, 0x64, 0x46, 0x20, 0xB7, 0x70, 0x7F, 0x3C, 0xDE, 0x48, 0xDB, 0x96, + 0x53, 0xB7, 0x39, 0x77, 0xE4, 0x1A, 0xE2, 0xC7, 0x16, 0x84, 0x76, 0x97, + 0x5B, 0x2F, 0xBB, 0x19, 0x15, 0x85, 0xF8, 0x69, 0x85, 0xF5, 0x99, 0xA7, + 0xA9, 0xF2, 0x34, 0xA7, 0xA9, 0xB6, 0xA6, 0x03, 0xFC, 0x6F, 0x86, 0x3D, + 0x54, 0x7C, 0x76, 0x04, 0x9B, 0x6B, 0xF9, 0x40, 0x5D, 0x00, 0x34, 0xC7, + 0x2E, 0x99, 0x75, 0x9D, 0xE5, 0x88, 0x03, 0xAA, 0x4D, 0xF8, 0x03, 0xD2, + 0x42, 0x76, 0xC0, 0x1B +}; + +static const unsigned char TA99_RSA_E[] = { + 0xA8, 0x8B +}; + +static const unsigned char TA100_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x32 +}; + +static const unsigned char TA100_RSA_N[] = { + 0xBA, 0x39, 0xC1, 0x37, 0x7A, 0x68, 0x45, 0x2B, 0x14, 0xB4, 0xEB, 0xE4, + 0x13, 0xEB, 0x57, 0x75, 0x23, 0x4D, 0x8F, 0x24, 0x2D, 0x16, 0xE8, 0xAE, + 0x8E, 0xC9, 0x7D, 0xA4, 0x57, 0x3B, 0x2A, 0x76, 0x25, 0x33, 0x83, 0x6C, + 0xEA, 0x32, 0x8A, 0x94, 0x9B, 0x4E, 0x3C, 0x96, 0xE4, 0xFD, 0x51, 0xBF, + 0x99, 0xC9, 0x93, 0x7E, 0xBF, 0xF9, 0xAD, 0xA7, 0xB2, 0x48, 0x2B, 0x07, + 0x1C, 0x27, 0xF5, 0x4C, 0xBC, 0x70, 0x12, 0x77, 0xA4, 0x85, 0x54, 0xB5, + 0xFD, 0x90, 0x7A, 0xE4, 0xA3, 0xE4, 0x51, 0x58, 0x03, 0xCD, 0x10, 0x79, + 0x79, 0xEE, 0x6B, 0x93, 0x1F, 0x64, 0x8E, 0x6B, 0x64, 0xAB, 0xA3, 0x13, + 0xE3, 0x71, 0xFE, 0x7D, 0xAB, 0x9C, 0xDD, 0x27, 0x53, 0x37, 0xB3, 0xAA, + 0x18, 0xC2, 0x59, 0x26, 0xEC, 0x5B, 0x1F, 0xD2, 0xE6, 0x65, 0x7C, 0xEF, + 0x93, 0xBD, 0xD8, 0x58, 0x5C, 0x0B, 0xC0, 0xE3, 0x65, 0x6F, 0x3C, 0xC7, + 0xCA, 0x59, 0xE3, 0xFE, 0x6E, 0x5F, 0xAC, 0x83, 0xBE, 0xFD, 0x5D, 0x25, + 0x4E, 0x2A, 0x29, 0x3B, 0xD6, 0x0B, 0xAB, 0x17, 0x32, 0x78, 0xA4, 0xE1, + 0x3E, 0x94, 0x46, 0xBE, 0x62, 0x6E, 0x9B, 0xDE, 0x46, 0xA8, 0xB1, 0x16, + 0xE7, 0x85, 0x6E, 0xF4, 0x08, 0x40, 0x45, 0x11, 0xA0, 0x9E, 0x54, 0x44, + 0x84, 0xF7, 0xD8, 0x36, 0xCE, 0xF5, 0x50, 0x47, 0xDC, 0x2C, 0x30, 0x9B, + 0xEE, 0xC0, 0xF5, 0x96, 0xD2, 0xFE, 0x09, 0x86, 0xC7, 0x06, 0x59, 0xAE, + 0x4F, 0xAE, 0x8E, 0x11, 0x98, 0x7B, 0xF3, 0x0B, 0x52, 0xAA, 0x62, 0x26, + 0xAA, 0x21, 0xDF, 0x8E, 0x25, 0x33, 0x79, 0x97, 0x16, 0x49, 0x8D, 0xF5, + 0x3E, 0xD5, 0x47, 0x9F, 0x37, 0x31, 0x49, 0x33, 0x72, 0x05, 0x4D, 0x0C, + 0xB6, 0x55, 0x8C, 0xF1, 0x57, 0x8F, 0x8A, 0x87, 0xD1, 0xAD, 0xC5, 0x11, + 0x12, 0x39, 0xA0, 0xAD +}; + +static const unsigned char TA100_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA101_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x31 +}; + +static const unsigned char TA101_RSA_N[] = { + 0xAD, 0xE8, 0x24, 0x73, 0xF4, 0x14, 0x37, 0xF3, 0x9B, 0x9E, 0x2B, 0x57, + 0x28, 0x1C, 0x87, 0xBE, 0xDC, 0xB7, 0xDF, 0x38, 0x90, 0x8C, 0x6E, 0x3C, + 0xE6, 0x57, 0xA0, 0x78, 0xF7, 0x75, 0xC2, 0xA2, 0xFE, 0xF5, 0x6A, 0x6E, + 0xF6, 0x00, 0x4F, 0x28, 0xDB, 0xDE, 0x68, 0x86, 0x6C, 0x44, 0x93, 0xB6, + 0xB1, 0x63, 0xFD, 0x14, 0x12, 0x6B, 0xBF, 0x1F, 0xD2, 0xEA, 0x31, 0x9B, + 0x21, 0x7E, 0xD1, 0x33, 0x3C, 0xBA, 0x48, 0xF5, 0xDD, 0x79, 0xDF, 0xB3, + 0xB8, 0xFF, 0x12, 0xF1, 0x21, 0x9A, 0x4B, 0xC1, 0x8A, 0x86, 0x71, 0x69, + 0x4A, 0x66, 0x66, 0x6C, 0x8F, 0x7E, 0x3C, 0x70, 0xBF, 0xAD, 0x29, 0x22, + 0x06, 0xF3, 0xE4, 0xC0, 0xE6, 0x80, 0xAE, 0xE2, 0x4B, 0x8F, 0xB7, 0x99, + 0x7E, 0x94, 0x03, 0x9F, 0xD3, 0x47, 0x97, 0x7C, 0x99, 0x48, 0x23, 0x53, + 0xE8, 0x38, 0xAE, 0x4F, 0x0A, 0x6F, 0x83, 0x2E, 0xD1, 0x49, 0x57, 0x8C, + 0x80, 0x74, 0xB6, 0xDA, 0x2F, 0xD0, 0x38, 0x8D, 0x7B, 0x03, 0x70, 0x21, + 0x1B, 0x75, 0xF2, 0x30, 0x3C, 0xFA, 0x8F, 0xAE, 0xDD, 0xDA, 0x63, 0xAB, + 0xEB, 0x16, 0x4F, 0xC2, 0x8E, 0x11, 0x4B, 0x7E, 0xCF, 0x0B, 0xE8, 0xFF, + 0xB5, 0x77, 0x2E, 0xF4, 0xB2, 0x7B, 0x4A, 0xE0, 0x4C, 0x12, 0x25, 0x0C, + 0x70, 0x8D, 0x03, 0x29, 0xA0, 0xE1, 0x53, 0x24, 0xEC, 0x13, 0xD9, 0xEE, + 0x19, 0xBF, 0x10, 0xB3, 0x4A, 0x8C, 0x3F, 0x89, 0xA3, 0x61, 0x51, 0xDE, + 0xAC, 0x87, 0x07, 0x94, 0xF4, 0x63, 0x71, 0xEC, 0x2E, 0xE2, 0x6F, 0x5B, + 0x98, 0x81, 0xE1, 0x89, 0x5C, 0x34, 0x79, 0x6C, 0x76, 0xEF, 0x3B, 0x90, + 0x62, 0x79, 0xE6, 0xDB, 0xA4, 0x9A, 0x2F, 0x26, 0xC5, 0xD0, 0x10, 0xE1, + 0x0E, 0xDE, 0xD9, 0x10, 0x8E, 0x16, 0xFB, 0xB7, 0xF7, 0xA8, 0xF7, 0xC7, + 0xE5, 0x02, 0x07, 0x98, 0x8F, 0x36, 0x08, 0x95, 0xE7, 0xE2, 0x37, 0x96, + 0x0D, 0x36, 0x75, 0x9E, 0xFB, 0x0E, 0x72, 0xB1, 0x1D, 0x9B, 0xBC, 0x03, + 0xF9, 0x49, 0x05, 0xD8, 0x81, 0xDD, 0x05, 0xB4, 0x2A, 0xD6, 0x41, 0xE9, + 0xAC, 0x01, 0x76, 0x95, 0x0A, 0x0F, 0xD8, 0xDF, 0xD5, 0xBD, 0x12, 0x1F, + 0x35, 0x2F, 0x28, 0x17, 0x6C, 0xD2, 0x98, 0xC1, 0xA8, 0x09, 0x64, 0x77, + 0x6E, 0x47, 0x37, 0xBA, 0xCE, 0xAC, 0x59, 0x5E, 0x68, 0x9D, 0x7F, 0x72, + 0xD6, 0x89, 0xC5, 0x06, 0x41, 0x29, 0x3E, 0x59, 0x3E, 0xDD, 0x26, 0xF5, + 0x24, 0xC9, 0x11, 0xA7, 0x5A, 0xA3, 0x4C, 0x40, 0x1F, 0x46, 0xA1, 0x99, + 0xB5, 0xA7, 0x3A, 0x51, 0x6E, 0x86, 0x3B, 0x9E, 0x7D, 0x72, 0xA7, 0x12, + 0x05, 0x78, 0x59, 0xED, 0x3E, 0x51, 0x78, 0x15, 0x0B, 0x03, 0x8F, 0x8D, + 0xD0, 0x2F, 0x05, 0xB2, 0x3E, 0x7B, 0x4A, 0x1C, 0x4B, 0x73, 0x05, 0x12, + 0xFC, 0xC6, 0xEA, 0xE0, 0x50, 0x13, 0x7C, 0x43, 0x93, 0x74, 0xB3, 0xCA, + 0x74, 0xE7, 0x8E, 0x1F, 0x01, 0x08, 0xD0, 0x30, 0xD4, 0x5B, 0x71, 0x36, + 0xB4, 0x07, 0xBA, 0xC1, 0x30, 0x30, 0x5C, 0x48, 0xB7, 0x82, 0x3B, 0x98, + 0xA6, 0x7D, 0x60, 0x8A, 0xA2, 0xA3, 0x29, 0x82, 0xCC, 0xBA, 0xBD, 0x83, + 0x04, 0x1B, 0xA2, 0x83, 0x03, 0x41, 0xA1, 0xD6, 0x05, 0xF1, 0x1B, 0xC2, + 0xB6, 0xF0, 0xA8, 0x7C, 0x86, 0x3B, 0x46, 0xA8, 0x48, 0x2A, 0x88, 0xDC, + 0x76, 0x9A, 0x76, 0xBF, 0x1F, 0x6A, 0xA5, 0x3D, 0x19, 0x8F, 0xEB, 0x38, + 0xF3, 0x64, 0xDE, 0xC8, 0x2B, 0x0D, 0x0A, 0x28, 0xFF, 0xF7, 0xDB, 0xE2, + 0x15, 0x42, 0xD4, 0x22, 0xD0, 0x27, 0x5D, 0xE1, 0x79, 0xFE, 0x18, 0xE7, + 0x70, 0x88, 0xAD, 0x4E, 0xE6, 0xD9, 0x8B, 0x3A, 0xC6, 0xDD, 0x27, 0x51, + 0x6E, 0xFF, 0xBC, 0x64, 0xF5, 0x33, 0x43, 0x4F +}; + +static const unsigned char TA101_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA102_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA102_RSA_N[] = { + 0xCE, 0xDE, 0xFD, 0xA6, 0xFB, 0xEC, 0xEC, 0x14, 0x34, 0x3C, 0x07, 0x06, + 0x5A, 0x6C, 0x59, 0xF7, 0x19, 0x35, 0xDD, 0xF7, 0xC1, 0x9D, 0x55, 0xAA, + 0xD3, 0xCD, 0x3B, 0xA4, 0x93, 0x72, 0xEF, 0x0A, 0xFA, 0x6D, 0x9D, 0xF6, + 0xF0, 0x85, 0x80, 0x5B, 0xA1, 0x48, 0x52, 0x9F, 0x39, 0xC5, 0xB7, 0xEE, + 0x28, 0xAC, 0xEF, 0xCB, 0x76, 0x68, 0x14, 0xB9, 0xDF, 0xAD, 0x01, 0x6C, + 0x99, 0x1F, 0xC4, 0x22, 0x1D, 0x9F, 0xFE, 0x72, 0x77, 0xE0, 0x2C, 0x5B, + 0xAF, 0xE4, 0x04, 0xBF, 0x4F, 0x72, 0xA0, 0x1A, 0x34, 0x98, 0xE8, 0x39, + 0x68, 0xEC, 0x95, 0x25, 0x7B, 0x76, 0xA1, 0xE6, 0x69, 0xB9, 0x85, 0x19, + 0xBD, 0x89, 0x8C, 0xFE, 0xAD, 0xED, 0x36, 0xEA, 0x73, 0xBC, 0xFF, 0x83, + 0xE2, 0xCB, 0x7D, 0xC1, 0xD2, 0xCE, 0x4A, 0xB3, 0x8D, 0x05, 0x9E, 0x8B, + 0x49, 0x93, 0xDF, 0xC1, 0x5B, 0xD0, 0x6E, 0x5E, 0xF0, 0x2E, 0x30, 0x2E, + 0x82, 0xFC, 0xFA, 0xBC, 0xB4, 0x17, 0x0A, 0x48, 0xE5, 0x88, 0x9B, 0xC5, + 0x9B, 0x6B, 0xDE, 0xB0, 0xCA, 0xB4, 0x03, 0xF0, 0xDA, 0xF4, 0x90, 0xB8, + 0x65, 0x64, 0xF7, 0x5C, 0x4C, 0xAD, 0xE8, 0x7E, 0x66, 0x5E, 0x99, 0xD7, + 0xB8, 0xC2, 0x3E, 0xC8, 0xD0, 0x13, 0x9D, 0xAD, 0xEE, 0xE4, 0x45, 0x7B, + 0x89, 0x55, 0xF7, 0x8A, 0x1F, 0x62, 0x52, 0x84, 0x12, 0xB3, 0xC2, 0x40, + 0x97, 0xE3, 0x8A, 0x1F, 0x47, 0x91, 0xA6, 0x74, 0x5A, 0xD2, 0xF8, 0xB1, + 0x63, 0x28, 0x10, 0xB8, 0xB3, 0x09, 0xB8, 0x56, 0x77, 0x40, 0xA2, 0x26, + 0x98, 0x79, 0xC6, 0xFE, 0xDF, 0x25, 0xEE, 0x3E, 0xE5, 0xA0, 0x7F, 0xD4, + 0x61, 0x0F, 0x51, 0x4B, 0x3C, 0x3F, 0x8C, 0xDA, 0xE1, 0x70, 0x74, 0xD8, + 0xC2, 0x68, 0xA1, 0xF9, 0xC1, 0x0C, 0xE9, 0xA1, 0xE2, 0x7F, 0xBB, 0x55, + 0x3C, 0x76, 0x06, 0xEE, 0x6A, 0x4E, 0xCC, 0x92, 0x88, 0x30, 0x4D, 0x9A, + 0xBD, 0x4F, 0x0B, 0x48, 0x9A, 0x84, 0xB5, 0x98, 0xA3, 0xD5, 0xFB, 0x73, + 0xC1, 0x57, 0x61, 0xDD, 0x28, 0x56, 0x75, 0x13, 0xAE, 0x87, 0x8E, 0xE7, + 0x0C, 0x51, 0x09, 0x10, 0x75, 0x88, 0x4C, 0xBC, 0x8D, 0xF9, 0x7B, 0x3C, + 0xD4, 0x22, 0x48, 0x1F, 0x2A, 0xDC, 0xEB, 0x6B, 0xBB, 0x44, 0xB1, 0xCB, + 0x33, 0x71, 0x32, 0x46, 0xAF, 0xAD, 0x4A, 0xF1, 0x8C, 0xE8, 0x74, 0x3A, + 0xAC, 0xE7, 0x1A, 0x22, 0x73, 0x80, 0xD2, 0x30, 0xF7, 0x25, 0x42, 0xC7, + 0x22, 0x3B, 0x3B, 0x12, 0xAD, 0x96, 0x2E, 0xC6, 0xC3, 0x76, 0x07, 0xAA, + 0x20, 0xB7, 0x35, 0x49, 0x57, 0xE9, 0x92, 0x49, 0xE8, 0x76, 0x16, 0x72, + 0x31, 0x67, 0x2B, 0x96, 0x7E, 0x8A, 0xA3, 0xC7, 0x94, 0x56, 0x22, 0xBF, + 0x6A, 0x4B, 0x7E, 0x01, 0x21, 0xB2, 0x23, 0x32, 0xDF, 0xE4, 0x9A, 0x44, + 0x6D, 0x59, 0x5B, 0x5D, 0xF5, 0x00, 0xA0, 0x1C, 0x9B, 0xC6, 0x78, 0x97, + 0x8D, 0x90, 0xFF, 0x9B, 0xC8, 0xAA, 0xB4, 0xAF, 0x11, 0x51, 0x39, 0x5E, + 0xD9, 0xFB, 0x67, 0xAD, 0xD5, 0x5B, 0x11, 0x9D, 0x32, 0x9A, 0x1B, 0xBD, + 0xD5, 0xBA, 0x5B, 0xA5, 0xC9, 0xCB, 0x25, 0x69, 0x53, 0x55, 0x27, 0x5C, + 0xE0, 0xCA, 0x36, 0xCB, 0x88, 0x61, 0xFB, 0x1E, 0xB7, 0xD0, 0xCB, 0xEE, + 0x16, 0xFB, 0xD3, 0xA6, 0x4C, 0xDE, 0x92, 0xA5, 0xD4, 0xE2, 0xDF, 0xF5, + 0x06, 0x54, 0xDE, 0x2E, 0x9D, 0x4B, 0xB4, 0x93, 0x30, 0xAA, 0x81, 0xCE, + 0xDD, 0x1A, 0xDC, 0x51, 0x73, 0x0D, 0x4F, 0x70, 0xE9, 0xE5, 0xB6, 0x16, + 0x21, 0x19, 0x79, 0xB2, 0xE6, 0x89, 0x0B, 0x75, 0x64, 0xCA, 0xD5, 0xAB, + 0xBC, 0x09, 0xC1, 0x18, 0xA1, 0xFF, 0xD4, 0x54, 0xA1, 0x85, 0x3C, 0xFD, + 0x14, 0x24, 0x03, 0xB2, 0x87, 0xD3, 0xA4, 0xB7 +}; + +static const unsigned char TA102_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA103_DN[] = { + 0x30, 0x37, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0B, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x54, + 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, 0x20, 0x52, + 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x31 +}; + +static const unsigned char TA103_RSA_N[] = { + 0xC2, 0xBE, 0xEB, 0x27, 0xF0, 0x21, 0xA3, 0xF3, 0x69, 0x26, 0x55, 0x7E, + 0x9D, 0xC5, 0x55, 0x16, 0x91, 0x5C, 0xFD, 0xEF, 0x21, 0xBF, 0x53, 0x80, + 0x7A, 0x2D, 0xD2, 0x91, 0x8C, 0x63, 0x31, 0xF0, 0xEC, 0x24, 0xF0, 0xC3, + 0xA5, 0xD2, 0x72, 0x7C, 0x10, 0x6D, 0xF4, 0x37, 0xB7, 0xE5, 0xE6, 0x7C, + 0x79, 0xEA, 0x8C, 0xB5, 0x82, 0x8B, 0xAE, 0x48, 0xB6, 0xAC, 0x00, 0xDC, + 0x65, 0x75, 0xEC, 0x2A, 0x4D, 0x5F, 0xC1, 0x87, 0xF5, 0x20, 0x65, 0x2B, + 0x81, 0xA8, 0x47, 0x3E, 0x89, 0x23, 0x95, 0x30, 0x16, 0x90, 0x7F, 0xE8, + 0x57, 0x07, 0x48, 0xE7, 0x19, 0xAE, 0xBF, 0x45, 0x67, 0xB1, 0x37, 0x1B, + 0x06, 0x2A, 0xFE, 0xDE, 0xF9, 0xAC, 0x7D, 0x83, 0xFB, 0x5E, 0xBA, 0xE4, + 0x8F, 0x97, 0x67, 0xBE, 0x4B, 0x8E, 0x8D, 0x64, 0x07, 0x57, 0x38, 0x55, + 0x69, 0x34, 0x36, 0x3D, 0x13, 0x48, 0xEF, 0x4F, 0xE2, 0xD3, 0x66, 0x1E, + 0xA4, 0xCF, 0x1A, 0xB7, 0x5E, 0x36, 0x33, 0xD4, 0xB4, 0x06, 0xBD, 0x18, + 0x01, 0xFD, 0x77, 0x84, 0x50, 0x00, 0x45, 0xF5, 0x8C, 0x5D, 0xE8, 0x23, + 0xBC, 0x7E, 0xFE, 0x35, 0xE1, 0xED, 0x50, 0x7B, 0xA9, 0x30, 0x8D, 0x19, + 0xD3, 0x09, 0x8E, 0x68, 0x67, 0x5D, 0xBF, 0x3C, 0x97, 0x18, 0x53, 0xBB, + 0x29, 0x62, 0xC5, 0xCA, 0x5E, 0x72, 0xC1, 0xC7, 0x96, 0xD4, 0xDB, 0x2D, + 0xA0, 0xB4, 0x1F, 0x69, 0x03, 0xEC, 0xEA, 0xE2, 0x50, 0xF1, 0x0C, 0x3C, + 0xF0, 0xAC, 0xF3, 0x53, 0x2D, 0xF0, 0x1C, 0xF5, 0xED, 0x6C, 0x39, 0x39, + 0x73, 0x80, 0x16, 0xC8, 0x52, 0xB0, 0x23, 0xCD, 0xE0, 0x3E, 0xDC, 0xDD, + 0x3C, 0x47, 0xA0, 0xBB, 0x35, 0x8A, 0xE2, 0x98, 0x68, 0x8B, 0xBE, 0xE5, + 0xBF, 0x72, 0xEE, 0xD2, 0xFA, 0xA5, 0xED, 0x12, 0xED, 0xFC, 0x98, 0x18, + 0xA9, 0x26, 0x76, 0xDC, 0x28, 0x4B, 0x10, 0x20, 0x1C, 0xD3, 0x7F, 0x16, + 0x77, 0x2D, 0xED, 0x6F, 0x80, 0xF7, 0x49, 0xBB, 0x53, 0x05, 0xBB, 0x5D, + 0x68, 0xC7, 0xD4, 0xC8, 0x75, 0x16, 0x3F, 0x89, 0x5A, 0x8B, 0xF7, 0x17, + 0x47, 0xD4, 0x4C, 0xF1, 0xD2, 0x89, 0x79, 0x3E, 0x4D, 0x3D, 0x98, 0xA8, + 0x61, 0xDE, 0x3A, 0x1E, 0xD2, 0xF8, 0x5E, 0x03, 0xE0, 0xC1, 0xC9, 0x1C, + 0x8C, 0xD3, 0x8D, 0x4D, 0xD3, 0x95, 0x36, 0xB3, 0x37, 0x5F, 0x63, 0x63, + 0x9B, 0x33, 0x14, 0xF0, 0x2D, 0x26, 0x6B, 0x53, 0x7C, 0x89, 0x8C, 0x32, + 0xC2, 0x6E, 0xEC, 0x3D, 0x21, 0x00, 0x39, 0xC9, 0xA1, 0x68, 0xE2, 0x50, + 0x83, 0x2E, 0xB0, 0x3A, 0x2B, 0xF3, 0x36, 0xA0, 0xAC, 0x2F, 0xE4, 0x6F, + 0x61, 0xC2, 0x51, 0x09, 0x39, 0x3E, 0x8B, 0x53, 0xB9, 0xBB, 0x67, 0xDA, + 0xDC, 0x53, 0xB9, 0x76, 0x59, 0x36, 0x9D, 0x43, 0xE5, 0x20, 0xE0, 0x3D, + 0x32, 0x60, 0x85, 0x22, 0x51, 0xB7, 0xC7, 0x33, 0xBB, 0xDD, 0x15, 0x2F, + 0xA4, 0x78, 0xA6, 0x07, 0x7B, 0x81, 0x46, 0x36, 0x04, 0x86, 0xDD, 0x79, + 0x35, 0xC7, 0x95, 0x2C, 0x3B, 0xB0, 0xA3, 0x17, 0x35, 0xE5, 0x73, 0x1F, + 0xB4, 0x5C, 0x59, 0xEF, 0xDA, 0xEA, 0x10, 0x65, 0x7B, 0x7A, 0xD0, 0x7F, + 0x9F, 0xB3, 0xB4, 0x2A, 0x37, 0x3B, 0x70, 0x8B, 0x9B, 0x5B, 0xB9, 0x2B, + 0xB7, 0xEC, 0xB2, 0x51, 0x12, 0x97, 0x53, 0x29, 0x5A, 0xD4, 0xF0, 0x12, + 0x10, 0xDC, 0x4F, 0x02, 0xBB, 0x12, 0x92, 0x2F, 0x62, 0xD4, 0x3F, 0x69, + 0x43, 0x7C, 0x0D, 0xD6, 0xFC, 0x58, 0x75, 0x01, 0x88, 0x9D, 0x58, 0x16, + 0x4B, 0xDE, 0xBA, 0x90, 0xFF, 0x47, 0x01, 0x89, 0x06, 0x6A, 0xF6, 0x5F, + 0xB2, 0x90, 0x6A, 0xB3, 0x02, 0xA6, 0x02, 0x88, 0xBF, 0xB3, 0x47, 0x7E, + 0x2A, 0xD9, 0xD5, 0xFA, 0x68, 0x78, 0x35, 0x4D +}; + +static const unsigned char TA103_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA104_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x42, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x6F, 0x72, 0x65, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, 0x43, 0x79, + 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6C, 0x74, 0x69, + 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA104_RSA_N[] = { + 0xA3, 0x04, 0xBB, 0x22, 0xAB, 0x98, 0x3D, 0x57, 0xE8, 0x26, 0x72, 0x9A, + 0xB5, 0x79, 0xD4, 0x29, 0xE2, 0xE1, 0xE8, 0x95, 0x80, 0xB1, 0xB0, 0xE3, + 0x5B, 0x8E, 0x2B, 0x29, 0x9A, 0x64, 0xDF, 0xA1, 0x5D, 0xED, 0xB0, 0x09, + 0x05, 0x6D, 0xDB, 0x28, 0x2E, 0xCE, 0x62, 0xA2, 0x62, 0xFE, 0xB4, 0x88, + 0xDA, 0x12, 0xEB, 0x38, 0xEB, 0x21, 0x9D, 0xC0, 0x41, 0x2B, 0x01, 0x52, + 0x7B, 0x88, 0x77, 0xD3, 0x1C, 0x8F, 0xC7, 0xBA, 0xB9, 0x88, 0xB5, 0x6A, + 0x09, 0xE7, 0x73, 0xE8, 0x11, 0x40, 0xA7, 0xD1, 0xCC, 0xCA, 0x62, 0x8D, + 0x2D, 0xE5, 0x8F, 0x0B, 0xA6, 0x50, 0xD2, 0xA8, 0x50, 0xC3, 0x28, 0xEA, + 0xF5, 0xAB, 0x25, 0x87, 0x8A, 0x9A, 0x96, 0x1C, 0xA9, 0x67, 0xB8, 0x3F, + 0x0C, 0xD5, 0xF7, 0xF9, 0x52, 0x13, 0x2F, 0xC2, 0x1B, 0xD5, 0x70, 0x70, + 0xF0, 0x8F, 0xC0, 0x12, 0xCA, 0x06, 0xCB, 0x9A, 0xE1, 0xD9, 0xCA, 0x33, + 0x7A, 0x77, 0xD6, 0xF8, 0xEC, 0xB9, 0xF1, 0x68, 0x44, 0x42, 0x48, 0x13, + 0xD2, 0xC0, 0xC2, 0xA4, 0xAE, 0x5E, 0x60, 0xFE, 0xB6, 0xA6, 0x05, 0xFC, + 0xB4, 0xDD, 0x07, 0x59, 0x02, 0xD4, 0x59, 0x18, 0x98, 0x63, 0xF5, 0xA5, + 0x63, 0xE0, 0x90, 0x0C, 0x7D, 0x5D, 0xB2, 0x06, 0x7A, 0xF3, 0x85, 0xEA, + 0xEB, 0xD4, 0x03, 0xAE, 0x5E, 0x84, 0x3E, 0x5F, 0xFF, 0x15, 0xED, 0x69, + 0xBC, 0xF9, 0x39, 0x36, 0x72, 0x75, 0xCF, 0x77, 0x52, 0x4D, 0xF3, 0xC9, + 0x90, 0x2C, 0xB9, 0x3D, 0xE5, 0xC9, 0x23, 0x53, 0x3F, 0x1F, 0x24, 0x98, + 0x21, 0x5C, 0x07, 0x99, 0x29, 0xBD, 0xC6, 0x3A, 0xEC, 0xE7, 0x6E, 0x86, + 0x3A, 0x6B, 0x97, 0x74, 0x63, 0x33, 0xBD, 0x68, 0x18, 0x31, 0xF0, 0x78, + 0x8D, 0x76, 0xBF, 0xFC, 0x9E, 0x8E, 0x5D, 0x2A, 0x86, 0xA7, 0x4D, 0x90, + 0xDC, 0x27, 0x1A, 0x39 +}; + +static const unsigned char TA104_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA105_DN[] = { + 0x30, 0x6F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x4B, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x09, 0x48, 0x6F, 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x48, 0x6F, + 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA105_RSA_N[] = { + 0xB3, 0x88, 0xD7, 0xEA, 0xCE, 0x0F, 0x20, 0x4E, 0xBE, 0xE6, 0xD6, 0x03, + 0x6D, 0xEE, 0x59, 0xFC, 0xC2, 0x57, 0xDF, 0x29, 0x68, 0xA1, 0x83, 0x0E, + 0x3E, 0x68, 0xC7, 0x68, 0x58, 0x9C, 0x1C, 0x60, 0x4B, 0x89, 0x43, 0x0C, + 0xB9, 0xD4, 0x15, 0xB2, 0xEE, 0xC1, 0x4E, 0x75, 0xE9, 0xB5, 0xA7, 0xEF, + 0xE5, 0xE9, 0x35, 0x99, 0xE4, 0xCC, 0x1C, 0xE7, 0x4B, 0x5F, 0x8D, 0x33, + 0x30, 0x20, 0x33, 0x53, 0xD9, 0xA6, 0xBB, 0xD5, 0x3E, 0x13, 0x8E, 0xE9, + 0x1F, 0x87, 0x49, 0xAD, 0x50, 0x2D, 0x50, 0xCA, 0x18, 0xBE, 0x01, 0x58, + 0xA2, 0x13, 0x70, 0x96, 0xBB, 0x89, 0x88, 0x56, 0x80, 0x5C, 0xF8, 0xBD, + 0x2C, 0x3C, 0xE1, 0x4C, 0x57, 0x88, 0xBB, 0xD3, 0xB9, 0x95, 0xEF, 0xCB, + 0xC7, 0xF6, 0xDA, 0x31, 0x74, 0x28, 0xA6, 0xE6, 0x54, 0x89, 0xF5, 0x41, + 0x31, 0xCA, 0xE5, 0x26, 0x1A, 0xCD, 0x82, 0xE0, 0x70, 0xDA, 0x3B, 0x29, + 0xBB, 0xD5, 0x03, 0xF5, 0x99, 0xBA, 0x55, 0xF5, 0x64, 0xD1, 0x60, 0x0E, + 0xB3, 0x89, 0x49, 0xB8, 0x8A, 0x2F, 0x05, 0xD2, 0x84, 0x45, 0x28, 0x7C, + 0x8F, 0x68, 0x50, 0x12, 0x78, 0xFC, 0x0B, 0xB5, 0x53, 0xCB, 0xC2, 0x98, + 0x1C, 0x84, 0xA3, 0x9E, 0xB0, 0xBE, 0x23, 0xA4, 0xDA, 0xDC, 0xC8, 0x2B, + 0x1E, 0xDA, 0x6E, 0x45, 0x1E, 0x89, 0x98, 0xDA, 0xF9, 0x00, 0x2E, 0x06, + 0xE9, 0x0C, 0x3B, 0x70, 0xD5, 0x50, 0x25, 0x88, 0x99, 0xCB, 0xCD, 0x73, + 0x60, 0xF7, 0xD5, 0xFF, 0x35, 0x67, 0xC5, 0xA1, 0xBC, 0x5E, 0xAB, 0xCD, + 0x4A, 0xB8, 0x45, 0xEB, 0xC8, 0x68, 0x1E, 0x0D, 0x0D, 0x14, 0x46, 0x12, + 0xE3, 0xD2, 0x64, 0x62, 0x8A, 0x42, 0x98, 0xBC, 0xB4, 0xC6, 0x08, 0x08, + 0xF8, 0xFD, 0xA8, 0x4C, 0x64, 0x9C, 0x76, 0x01, 0xBD, 0x2F, 0xA9, 0x6C, + 0x33, 0x0F, 0xD8, 0x3F, 0x28, 0xB8, 0x3C, 0x69, 0x01, 0x42, 0x86, 0x7E, + 0x69, 0xC1, 0xC9, 0x06, 0xCA, 0xE5, 0x7A, 0x46, 0x65, 0xE9, 0xC2, 0xD6, + 0x50, 0x41, 0x2E, 0x3F, 0xB7, 0xE4, 0xED, 0x6C, 0xD7, 0xBF, 0x26, 0x01, + 0x11, 0xA2, 0x16, 0x29, 0x4A, 0x6B, 0x34, 0x06, 0x90, 0xEC, 0x13, 0xD2, + 0xB6, 0xFB, 0x6A, 0x76, 0xD2, 0x3C, 0xED, 0xF0, 0xD6, 0x2D, 0xDD, 0xE1, + 0x15, 0xEC, 0xA3, 0x9B, 0x2F, 0x2C, 0xC9, 0x3E, 0x2B, 0xE4, 0x69, 0x3B, + 0xFF, 0x72, 0x25, 0xB1, 0x36, 0x86, 0x5B, 0xC7, 0x7F, 0x6B, 0x8B, 0x55, + 0x1B, 0x4A, 0xC5, 0x20, 0x61, 0x3D, 0xAE, 0xCB, 0x50, 0xE1, 0x08, 0x3A, + 0xBE, 0xB0, 0x8F, 0x63, 0x41, 0x53, 0x30, 0x08, 0x59, 0x3C, 0x98, 0x1D, + 0x77, 0xBA, 0x63, 0x91, 0x7A, 0xCA, 0x10, 0x50, 0x60, 0xBF, 0xF0, 0xD7, + 0xBC, 0x95, 0x87, 0x8F, 0x97, 0xC5, 0xFE, 0x97, 0x6A, 0x01, 0x94, 0xA3, + 0x7C, 0x5B, 0x85, 0x1D, 0x2A, 0x39, 0x3A, 0xD0, 0x54, 0xA1, 0xD1, 0x39, + 0x71, 0x9D, 0xFD, 0x21, 0xF9, 0xB5, 0x7B, 0xF0, 0xE2, 0xE0, 0x02, 0x8F, + 0x6E, 0x96, 0x24, 0x25, 0x2C, 0xA0, 0x1E, 0x2C, 0xA8, 0xC4, 0x89, 0xA7, + 0xEF, 0xED, 0x99, 0x06, 0x2F, 0xB6, 0x0A, 0x4C, 0x4F, 0xDB, 0xA2, 0xCC, + 0x37, 0x1A, 0xAF, 0x47, 0x85, 0x2D, 0x8A, 0x5F, 0xC4, 0x34, 0x34, 0x4C, + 0x00, 0xFD, 0x18, 0x93, 0x67, 0x13, 0xD1, 0x37, 0xE6, 0x48, 0xB4, 0x8B, + 0x06, 0xC5, 0x57, 0x7B, 0x19, 0x86, 0x0A, 0x79, 0xCB, 0x00, 0xC9, 0x52, + 0xAF, 0x42, 0xFF, 0x37, 0x8F, 0xE1, 0xA3, 0x1E, 0x7A, 0x3D, 0x50, 0xAB, + 0x63, 0x06, 0xE7, 0x15, 0xB5, 0x3F, 0xB6, 0x45, 0x37, 0x94, 0x37, 0xB1, + 0x7E, 0xF2, 0x48, 0xC3, 0x7F, 0xC5, 0x75, 0xFE, 0x97, 0x8D, 0x45, 0x8F, + 0x1A, 0xA7, 0x1A, 0x72, 0x28, 0x1A, 0x40, 0x0F +}; + +static const unsigned char TA105_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA106_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA106_RSA_N[] = { + 0xAD, 0x0E, 0x15, 0xCE, 0xE4, 0x43, 0x80, 0x5C, 0xB1, 0x87, 0xF3, 0xB7, + 0x60, 0xF9, 0x71, 0x12, 0xA5, 0xAE, 0xDC, 0x26, 0x94, 0x88, 0xAA, 0xF4, + 0xCE, 0xF5, 0x20, 0x39, 0x28, 0x58, 0x60, 0x0C, 0xF8, 0x80, 0xDA, 0xA9, + 0x15, 0x95, 0x32, 0x61, 0x3C, 0xB5, 0xB1, 0x28, 0x84, 0x8A, 0x8A, 0xDC, + 0x9F, 0x0A, 0x0C, 0x83, 0x17, 0x7A, 0x8F, 0x90, 0xAC, 0x8A, 0xE7, 0x79, + 0x53, 0x5C, 0x31, 0x84, 0x2A, 0xF6, 0x0F, 0x98, 0x32, 0x36, 0x76, 0xCC, + 0xDE, 0xDD, 0x3C, 0xA8, 0xA2, 0xEF, 0x6A, 0xFB, 0x21, 0xF2, 0x52, 0x61, + 0xDF, 0x9F, 0x20, 0xD7, 0x1F, 0xE2, 0xB1, 0xD9, 0xFE, 0x18, 0x64, 0xD2, + 0x12, 0x5B, 0x5F, 0xF9, 0x58, 0x18, 0x35, 0xBC, 0x47, 0xCD, 0xA1, 0x36, + 0xF9, 0x6B, 0x7F, 0xD4, 0xB0, 0x38, 0x3E, 0xC1, 0x1B, 0xC3, 0x8C, 0x33, + 0xD9, 0xD8, 0x2F, 0x18, 0xFE, 0x28, 0x0F, 0xB3, 0xA7, 0x83, 0xD6, 0xC3, + 0x6E, 0x44, 0xC0, 0x61, 0x35, 0x96, 0x16, 0xFE, 0x59, 0x9C, 0x8B, 0x76, + 0x6D, 0xD7, 0xF1, 0xA2, 0x4B, 0x0D, 0x2B, 0xFF, 0x0B, 0x72, 0xDA, 0x9E, + 0x60, 0xD0, 0x8E, 0x90, 0x35, 0xC6, 0x78, 0x55, 0x87, 0x20, 0xA1, 0xCF, + 0xE5, 0x6D, 0x0A, 0xC8, 0x49, 0x7C, 0x31, 0x98, 0x33, 0x6C, 0x22, 0xE9, + 0x87, 0xD0, 0x32, 0x5A, 0xA2, 0xBA, 0x13, 0x82, 0x11, 0xED, 0x39, 0x17, + 0x9D, 0x99, 0x3A, 0x72, 0xA1, 0xE6, 0xFA, 0xA4, 0xD9, 0xD5, 0x17, 0x31, + 0x75, 0xAE, 0x85, 0x7D, 0x22, 0xAE, 0x3F, 0x01, 0x46, 0x86, 0xF6, 0x28, + 0x79, 0xC8, 0xB1, 0xDA, 0xE4, 0x57, 0x17, 0xC4, 0x7E, 0x1C, 0x0E, 0xB0, + 0xB4, 0x92, 0xA6, 0x56, 0xB3, 0xBD, 0xB2, 0x97, 0xED, 0xAA, 0xA7, 0xF0, + 0xB7, 0xC5, 0xA8, 0x3F, 0x95, 0x16, 0xD0, 0xFF, 0xA1, 0x96, 0xEB, 0x08, + 0x5F, 0x18, 0x77, 0x4F +}; + +static const unsigned char TA106_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA107_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x35 +}; + +static const unsigned char TA107_EC_Q[] = { + 0x04, 0x0B, 0x50, 0x74, 0x8D, 0x64, 0x32, 0x99, 0x99, 0xB3, 0xD2, 0x60, + 0x08, 0xB8, 0x22, 0x8E, 0x46, 0x74, 0x2C, 0x78, 0xC0, 0x2B, 0x44, 0x2D, + 0x6D, 0x5F, 0x1D, 0xC9, 0xAE, 0x4B, 0x52, 0x20, 0x83, 0x3D, 0xB8, 0x14, + 0x6D, 0x53, 0x87, 0x60, 0x9E, 0x5F, 0x6C, 0x85, 0xDB, 0x06, 0x14, 0x95, + 0xE0, 0xC7, 0x28, 0xFF, 0x9D, 0x5F, 0xE4, 0xAA, 0xF1, 0xB3, 0x8B, 0x6D, + 0xED, 0x4F, 0x2F, 0x4B, 0xC9, 0x4A, 0x94, 0x91, 0x64, 0x75, 0xFE, 0x01, + 0xEC, 0xC1, 0xD8, 0xEB, 0x7A, 0x94, 0x78, 0x56, 0x18, 0x43, 0x5F, 0x6B, + 0x81, 0xCB, 0xF6, 0xBC, 0xDA, 0xB4, 0x0C, 0xB6, 0x29, 0x93, 0x08, 0x69, + 0x8F +}; + +static const unsigned char TA108_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x33 +}; + +static const unsigned char TA108_EC_Q[] = { + 0x04, 0x1F, 0x4F, 0x33, 0x87, 0x33, 0x29, 0x8A, 0xA1, 0x84, 0xDE, 0xCB, + 0xC7, 0x21, 0x58, 0x41, 0x89, 0xEA, 0x56, 0x9D, 0x2B, 0x4B, 0x85, 0xC6, + 0x1D, 0x4C, 0x27, 0xBC, 0x7F, 0x26, 0x51, 0x72, 0x6F, 0xE2, 0x9F, 0xD6, + 0xA3, 0xCA, 0xCC, 0x45, 0x14, 0x46, 0x8B, 0xAD, 0xEF, 0x7E, 0x86, 0x8C, + 0xEC, 0xB1, 0x7E, 0x2F, 0xFF, 0xA9, 0x71, 0x9D, 0x18, 0x84, 0x45, 0x04, + 0x41, 0x55, 0x6E, 0x2B, 0xEA, 0x26, 0x7F, 0xBB, 0x90, 0x01, 0xE3, 0x4B, + 0x19, 0xBA, 0xE4, 0x54, 0x96, 0x45, 0x09, 0xB1, 0xD5, 0x6C, 0x91, 0x44, + 0xAD, 0x84, 0x13, 0x8E, 0x9A, 0x8C, 0x0D, 0x80, 0x0C, 0x32, 0xF6, 0xE0, + 0x27 +}; + +static const unsigned char TA109_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA109_EC_Q[] = { + 0x04, 0xCE, 0xBF, 0xFE, 0x57, 0xA8, 0xBF, 0xD5, 0xAA, 0xF7, 0x10, 0x9A, + 0xCD, 0xBC, 0xD1, 0x11, 0xA2, 0xBD, 0x67, 0x42, 0xCC, 0x90, 0xEB, 0x15, + 0x18, 0x90, 0xD9, 0xA2, 0xCD, 0x0C, 0x2A, 0x25, 0xEB, 0x3E, 0x4F, 0xCE, + 0xB5, 0xD2, 0x8F, 0x0F, 0xF3, 0x35, 0xDA, 0x43, 0x8B, 0x02, 0x80, 0xBE, + 0x6F, 0x51, 0x24, 0x1D, 0x0F, 0x6B, 0x2B, 0xCA, 0x9F, 0xC2, 0x6F, 0x50, + 0x32, 0xE5, 0x37, 0x20, 0xB6, 0x20, 0xFF, 0x88, 0x0D, 0x0F, 0x6D, 0x49, + 0xBB, 0xDB, 0x06, 0xA4, 0x87, 0x90, 0x92, 0x94, 0xF4, 0x09, 0xD0, 0xCF, + 0x7F, 0xC8, 0x80, 0x0B, 0xC1, 0x97, 0xB3, 0xBB, 0x35, 0x27, 0xC9, 0xC2, + 0x1B +}; + +static const unsigned char TA110_DN[] = { + 0x30, 0x81, 0xB0, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x30, 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x20, 0x69, + 0x73, 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6E, 0x63, 0x65, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x16, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, + 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA110_RSA_N[] = { + 0xB6, 0x95, 0xB6, 0x43, 0x42, 0xFA, 0xC6, 0x6D, 0x2A, 0x6F, 0x48, 0xDF, + 0x94, 0x4C, 0x39, 0x57, 0x05, 0xEE, 0xC3, 0x79, 0x11, 0x41, 0x68, 0x36, + 0xED, 0xEC, 0xFE, 0x9A, 0x01, 0x8F, 0xA1, 0x38, 0x28, 0xFC, 0xF7, 0x10, + 0x46, 0x66, 0x2E, 0x4D, 0x1E, 0x1A, 0xB1, 0x1A, 0x4E, 0xC6, 0xD1, 0xC0, + 0x95, 0x88, 0xB0, 0xC9, 0xFF, 0x31, 0x8B, 0x33, 0x03, 0xDB, 0xB7, 0x83, + 0x7B, 0x3E, 0x20, 0x84, 0x5E, 0xED, 0xB2, 0x56, 0x28, 0xA7, 0xF8, 0xE0, + 0xB9, 0x40, 0x71, 0x37, 0xC5, 0xCB, 0x47, 0x0E, 0x97, 0x2A, 0x68, 0xC0, + 0x22, 0x95, 0x62, 0x15, 0xDB, 0x47, 0xD9, 0xF5, 0xD0, 0x2B, 0xFF, 0x82, + 0x4B, 0xC9, 0xAD, 0x3E, 0xDE, 0x4C, 0xDB, 0x90, 0x80, 0x50, 0x3F, 0x09, + 0x8A, 0x84, 0x00, 0xEC, 0x30, 0x0A, 0x3D, 0x18, 0xCD, 0xFB, 0xFD, 0x2A, + 0x59, 0x9A, 0x23, 0x95, 0x17, 0x2C, 0x45, 0x9E, 0x1F, 0x6E, 0x43, 0x79, + 0x6D, 0x0C, 0x5C, 0x98, 0xFE, 0x48, 0xA7, 0xC5, 0x23, 0x47, 0x5C, 0x5E, + 0xFD, 0x6E, 0xE7, 0x1E, 0xB4, 0xF6, 0x68, 0x45, 0xD1, 0x86, 0x83, 0x5B, + 0xA2, 0x8A, 0x8D, 0xB1, 0xE3, 0x29, 0x80, 0xFE, 0x25, 0x71, 0x88, 0xAD, + 0xBE, 0xBC, 0x8F, 0xAC, 0x52, 0x96, 0x4B, 0xAA, 0x51, 0x8D, 0xE4, 0x13, + 0x31, 0x19, 0xE8, 0x4E, 0x4D, 0x9F, 0xDB, 0xAC, 0xB3, 0x6A, 0xD5, 0xBC, + 0x39, 0x54, 0x71, 0xCA, 0x7A, 0x7A, 0x7F, 0x90, 0xDD, 0x7D, 0x1D, 0x80, + 0xD9, 0x81, 0xBB, 0x59, 0x26, 0xC2, 0x11, 0xFE, 0xE6, 0x93, 0xE2, 0xF7, + 0x80, 0xE4, 0x65, 0xFB, 0x34, 0x37, 0x0E, 0x29, 0x80, 0x70, 0x4D, 0xAF, + 0x38, 0x86, 0x2E, 0x9E, 0x7F, 0x57, 0xAF, 0x9E, 0x17, 0xAE, 0xEB, 0x1C, + 0xCB, 0x28, 0x21, 0x5F, 0xB6, 0x1C, 0xD8, 0xE7, 0xA2, 0x04, 0x22, 0xF9, + 0xD3, 0xDA, 0xD8, 0xCB +}; + +static const unsigned char TA110_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA111_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA111_RSA_N[] = { + 0xD8, 0x8E, 0xA3, 0x89, 0x80, 0x0B, 0xB2, 0x57, 0x52, 0xDC, 0xA9, 0x53, + 0x4C, 0x37, 0xB9, 0x7F, 0x63, 0x17, 0x13, 0xEF, 0xA7, 0x5B, 0x23, 0x5B, + 0x69, 0x75, 0xB0, 0x99, 0x0A, 0x17, 0xC1, 0x8B, 0xC4, 0xDB, 0xA8, 0xE0, + 0xCC, 0x31, 0xBA, 0xC2, 0xF2, 0xCD, 0x5D, 0xE9, 0xB7, 0xF8, 0x1D, 0xAF, + 0x6A, 0xC4, 0x95, 0x87, 0xD7, 0x47, 0xC9, 0x95, 0xD8, 0x82, 0x04, 0x50, + 0x3D, 0x81, 0x08, 0xFF, 0xE4, 0x3D, 0xB3, 0xB1, 0xD6, 0xC5, 0xB2, 0xFD, + 0x88, 0x09, 0xDB, 0x9C, 0x84, 0xEC, 0x25, 0x17, 0x14, 0x87, 0x7F, 0x30, + 0x78, 0x9B, 0x6A, 0x58, 0xC9, 0xB6, 0x73, 0x28, 0x3C, 0x34, 0xF7, 0x99, + 0xF7, 0x7F, 0xD3, 0xA6, 0xF8, 0x1C, 0x45, 0x7C, 0xAD, 0x2C, 0x8C, 0x94, + 0x3F, 0xD8, 0x67, 0x10, 0x53, 0x7E, 0x22, 0xCD, 0x4E, 0x25, 0x51, 0xF0, + 0x25, 0x24, 0x35, 0x11, 0x5E, 0x10, 0xC6, 0xEC, 0x87, 0x66, 0x89, 0x81, + 0x68, 0xBA, 0xCC, 0x2B, 0x9D, 0x47, 0x73, 0x1F, 0xBD, 0xCD, 0x91, 0xA4, + 0x72, 0x6A, 0x9C, 0xA2, 0x1B, 0x18, 0xA0, 0x6F, 0xEC, 0x50, 0xF4, 0x7D, + 0x40, 0xC2, 0xA8, 0x30, 0xCF, 0xBD, 0x73, 0xC8, 0x13, 0x2B, 0x10, 0x13, + 0x1E, 0x8B, 0x9A, 0xA8, 0x3A, 0x94, 0x73, 0xD3, 0x18, 0x69, 0x0A, 0x4A, + 0xFF, 0xC1, 0x01, 0x03, 0xFF, 0x79, 0x7F, 0xB5, 0x48, 0x7F, 0x7B, 0xEE, + 0xE8, 0x29, 0x6F, 0x36, 0x4C, 0x95, 0x61, 0x86, 0xD8, 0xF9, 0xA2, 0x73, + 0x8A, 0xEE, 0xAE, 0x2F, 0x96, 0xEE, 0x68, 0xCD, 0x3D, 0x4D, 0x28, 0x42, + 0xF9, 0x45, 0x2B, 0x32, 0x1B, 0x46, 0x55, 0x16, 0x6A, 0xA6, 0x4B, 0x29, + 0xF9, 0xBB, 0x95, 0x56, 0xBF, 0x46, 0x1D, 0xEC, 0x1D, 0x93, 0x1D, 0xC0, + 0x65, 0xB2, 0x1F, 0xA1, 0x43, 0xAE, 0x56, 0x9E, 0xA0, 0xB1, 0x8F, 0x6B, + 0x12, 0xB7, 0x60, 0x6D, 0x78, 0x0B, 0xCA, 0x8A, 0x5C, 0xED, 0x1E, 0x96, + 0x0E, 0x83, 0xA6, 0x48, 0x95, 0x8D, 0x3B, 0xA3, 0x21, 0xC4, 0xAE, 0x58, + 0xC6, 0x00, 0xB2, 0x84, 0xB4, 0x23, 0xA4, 0x96, 0x86, 0x35, 0xB8, 0xD8, + 0x9E, 0xD8, 0xAC, 0x34, 0x49, 0x98, 0x63, 0x95, 0xC5, 0xCB, 0x6D, 0x48, + 0x47, 0xE2, 0xF2, 0x2E, 0x18, 0x1E, 0xD0, 0x31, 0xAB, 0xDD, 0x74, 0xEC, + 0xF9, 0xDC, 0x8C, 0xB8, 0x1C, 0x8E, 0x68, 0x23, 0xBA, 0xD0, 0xF3, 0x50, + 0xDC, 0xCF, 0x65, 0x8F, 0x73, 0x3A, 0x32, 0xC7, 0x7C, 0xFE, 0xCA, 0x82, + 0x22, 0x4F, 0xBE, 0x8E, 0x62, 0x47, 0x66, 0xE5, 0xCD, 0x87, 0xE2, 0xE8, + 0xD5, 0x0F, 0x18, 0x9F, 0xE5, 0x04, 0x72, 0x4B, 0x46, 0x3C, 0x10, 0xF2, + 0x44, 0xC2, 0x64, 0x56, 0x71, 0x4E, 0x75, 0xE8, 0x9C, 0xC9, 0x26, 0x74, + 0xC5, 0x7D, 0x59, 0xD1, 0x0A, 0x5B, 0x0F, 0x6D, 0xFE, 0x9E, 0x75, 0x1C, + 0x18, 0xC6, 0x1A, 0x3A, 0x7C, 0xD8, 0x0D, 0x04, 0xCC, 0xCD, 0xB7, 0x45, + 0x65, 0x7A, 0xB1, 0x8F, 0xB8, 0xAE, 0x84, 0x48, 0x3E, 0xB3, 0x7A, 0x4D, + 0xA8, 0x03, 0xE2, 0xE2, 0x7E, 0x01, 0x16, 0x59, 0x68, 0x18, 0x43, 0x33, + 0xB0, 0xD2, 0xDC, 0xB0, 0x1A, 0x43, 0x35, 0xEE, 0xA5, 0xDA, 0xA9, 0x46, + 0x5C, 0xAE, 0x86, 0x81, 0x41, 0x01, 0x4A, 0x74, 0x26, 0xEC, 0x9F, 0x06, + 0xBF, 0xC2, 0x05, 0x37, 0x64, 0x75, 0x78, 0x29, 0x68, 0xFD, 0xC5, 0xF5, + 0xEB, 0xFE, 0x47, 0xF9, 0xE4, 0x85, 0xB0, 0xE1, 0x7B, 0x31, 0x9D, 0xA6, + 0x7F, 0x72, 0xA3, 0xB9, 0xC4, 0x2C, 0x2E, 0xCC, 0x99, 0x57, 0x0E, 0x21, + 0x0C, 0x45, 0x01, 0x94, 0x65, 0xEB, 0x65, 0x09, 0xC6, 0x63, 0x22, 0x0B, + 0x33, 0x49, 0x92, 0x48, 0x3C, 0xFC, 0xCD, 0xCE, 0xB0, 0x3E, 0x8E, 0x9E, + 0x8B, 0xF8, 0xFE, 0x49, 0xC5, 0x35, 0x72, 0x47 +}; + +static const unsigned char TA111_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA112_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA112_RSA_N[] = { + 0xAD, 0x96, 0x9F, 0x2D, 0x9C, 0x4A, 0x4C, 0x4A, 0x81, 0x79, 0x51, 0x99, + 0xEC, 0x8A, 0xCB, 0x6B, 0x60, 0x51, 0x13, 0xBC, 0x4D, 0x6D, 0x06, 0xFC, + 0xB0, 0x08, 0x8D, 0xDD, 0x19, 0x10, 0x6A, 0xC7, 0x26, 0x0C, 0x35, 0xD8, + 0xC0, 0x6F, 0x20, 0x84, 0xE9, 0x94, 0xB1, 0x9B, 0x85, 0x03, 0xC3, 0x5B, + 0xDB, 0x4A, 0xE8, 0xC8, 0xF8, 0x90, 0x76, 0xD9, 0x5B, 0x4F, 0xE3, 0x4C, + 0xE8, 0x06, 0x36, 0x4D, 0xCC, 0x9A, 0xAC, 0x3D, 0x0C, 0x90, 0x2B, 0x92, + 0xD4, 0x06, 0x19, 0x60, 0xAC, 0x37, 0x44, 0x79, 0x85, 0x81, 0x82, 0xAD, + 0x5A, 0x37, 0xE0, 0x0D, 0xCC, 0x9D, 0xA6, 0x4C, 0x52, 0x76, 0xEA, 0x43, + 0x9D, 0xB7, 0x04, 0xD1, 0x50, 0xF6, 0x55, 0xE0, 0xD5, 0xD2, 0xA6, 0x49, + 0x85, 0xE9, 0x37, 0xE9, 0xCA, 0x7E, 0xAE, 0x5C, 0x95, 0x4D, 0x48, 0x9A, + 0x3F, 0xAE, 0x20, 0x5A, 0x6D, 0x88, 0x95, 0xD9, 0x34, 0xB8, 0x52, 0x1A, + 0x43, 0x90, 0xB0, 0xBF, 0x6C, 0x05, 0xB9, 0xB6, 0x78, 0xB7, 0xEA, 0xD0, + 0xE4, 0x3A, 0x3C, 0x12, 0x53, 0x62, 0xFF, 0x4A, 0xF2, 0x7B, 0xBE, 0x35, + 0x05, 0xA9, 0x12, 0x34, 0xE3, 0xF3, 0x64, 0x74, 0x62, 0x2C, 0x3D, 0x00, + 0x49, 0x5A, 0x28, 0xFE, 0x32, 0x44, 0xBB, 0x87, 0xDD, 0x65, 0x27, 0x02, + 0x71, 0x3B, 0xDA, 0x4A, 0xF7, 0x1F, 0xDA, 0xCD, 0xF7, 0x21, 0x55, 0x90, + 0x4F, 0x0F, 0xEC, 0xAE, 0x82, 0xE1, 0x9F, 0x6B, 0xD9, 0x45, 0xD3, 0xBB, + 0xF0, 0x5F, 0x87, 0xED, 0x3C, 0x2C, 0x39, 0x86, 0xDA, 0x3F, 0xDE, 0xEC, + 0x72, 0x55, 0xEB, 0x79, 0xA3, 0xAD, 0xDB, 0xDD, 0x7C, 0xB0, 0xBA, 0x1C, + 0xCE, 0xFC, 0xDE, 0x4F, 0x35, 0x76, 0xCF, 0x0F, 0xF8, 0x78, 0x1F, 0x6A, + 0x36, 0x51, 0x46, 0x27, 0x61, 0x5B, 0xE9, 0x9E, 0xCF, 0xF0, 0xA2, 0x55, + 0x7D, 0x7C, 0x25, 0x8A, 0x6F, 0x2F, 0xB4, 0xC5, 0xCF, 0x84, 0x2E, 0x2B, + 0xFD, 0x0D, 0x51, 0x10, 0x6C, 0xFB, 0x5F, 0x1B, 0xBC, 0x1B, 0x7E, 0xC5, + 0xAE, 0x3B, 0x98, 0x01, 0x31, 0x92, 0xFF, 0x0B, 0x57, 0xF4, 0x9A, 0xB2, + 0xB9, 0x57, 0xE9, 0xAB, 0xEF, 0x0D, 0x76, 0xD1, 0xF0, 0xEE, 0xF4, 0xCE, + 0x86, 0xA7, 0xE0, 0x6E, 0xE9, 0xB4, 0x69, 0xA1, 0xDF, 0x69, 0xF6, 0x33, + 0xC6, 0x69, 0x2E, 0x97, 0x13, 0x9E, 0xA5, 0x87, 0xB0, 0x57, 0x10, 0x81, + 0x37, 0xC9, 0x53, 0xB3, 0xBB, 0x7F, 0xF6, 0x92, 0xD1, 0x9C, 0xD0, 0x18, + 0xF4, 0x92, 0x6E, 0xDA, 0x83, 0x4F, 0xA6, 0x63, 0x99, 0x4C, 0xA5, 0xFB, + 0x5E, 0xEF, 0x21, 0x64, 0x7A, 0x20, 0x5F, 0x6C, 0x64, 0x85, 0x15, 0xCB, + 0x37, 0xE9, 0x62, 0x0C, 0x0B, 0x2A, 0x16, 0xDC, 0x01, 0x2E, 0x32, 0xDA, + 0x3E, 0x4B, 0xF5, 0x9E, 0x3A, 0xF6, 0x17, 0x40, 0x94, 0xEF, 0x9E, 0x91, + 0x08, 0x86, 0xFA, 0xBE, 0x63, 0xA8, 0x5A, 0x33, 0xEC, 0xCB, 0x74, 0x43, + 0x95, 0xF9, 0x6C, 0x69, 0x52, 0x36, 0xC7, 0x29, 0x6F, 0xFC, 0x55, 0x03, + 0x5C, 0x1F, 0xFB, 0x9F, 0xBD, 0x47, 0xEB, 0xE7, 0x49, 0x47, 0x95, 0x0B, + 0x4E, 0x89, 0x22, 0x09, 0x49, 0xE0, 0xF5, 0x61, 0x1E, 0xF1, 0xBF, 0x2E, + 0x8A, 0x72, 0x6E, 0x80, 0x59, 0xFF, 0x57, 0x3A, 0xF9, 0x75, 0x32, 0xA3, + 0x4E, 0x5F, 0xEC, 0xED, 0x28, 0x62, 0xD9, 0x4D, 0x73, 0xF2, 0xCC, 0x81, + 0x17, 0x60, 0xED, 0xCD, 0xEB, 0xDC, 0xDB, 0xA7, 0xCA, 0xC5, 0x7E, 0x02, + 0xBD, 0xF2, 0x54, 0x08, 0x54, 0xFD, 0xB4, 0x2D, 0x09, 0x2C, 0x17, 0x54, + 0x4A, 0x98, 0xD1, 0x54, 0xE1, 0x51, 0x67, 0x08, 0xD2, 0xED, 0x6E, 0x7E, + 0x6F, 0x3F, 0xD2, 0x2D, 0x81, 0x59, 0x29, 0x66, 0xCB, 0x90, 0x39, 0x95, + 0x11, 0x1E, 0x74, 0x27, 0xFE, 0xDD, 0xEB, 0xAF +}; + +static const unsigned char TA112_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA113_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x52, 0x53, 0x41 +}; + +static const unsigned char TA113_RSA_N[] = { + 0xF9, 0x0F, 0xDD, 0xA3, 0x2B, 0x7D, 0xCB, 0xD0, 0x2A, 0xFE, 0xEC, 0x67, + 0x85, 0xA6, 0xE7, 0x2E, 0x1B, 0xBA, 0x77, 0xE1, 0xE3, 0xF5, 0xAF, 0xA4, + 0xEC, 0xFA, 0x4A, 0x5D, 0x91, 0xC4, 0x57, 0x47, 0x6B, 0x18, 0x77, 0x6B, + 0x76, 0xF2, 0xFD, 0x93, 0xE4, 0x3D, 0x0F, 0xC2, 0x16, 0x9E, 0x0B, 0x66, + 0xC3, 0x56, 0x94, 0x9E, 0x17, 0x83, 0x85, 0xCE, 0x56, 0xEF, 0xF2, 0x16, + 0xFD, 0x00, 0x62, 0xF5, 0x22, 0x09, 0x54, 0xE8, 0x65, 0x17, 0x4E, 0x41, + 0xB9, 0xE0, 0x4F, 0x46, 0x97, 0xAA, 0x1B, 0xC8, 0xB8, 0x6E, 0x62, 0x5E, + 0x69, 0xB1, 0x5F, 0xDB, 0x2A, 0x02, 0x7E, 0xFC, 0x6C, 0xCA, 0xF3, 0x41, + 0xD8, 0xED, 0xD0, 0xE8, 0xFC, 0x3F, 0x61, 0x48, 0xED, 0xB0, 0x03, 0x14, + 0x1D, 0x10, 0x0E, 0x4B, 0x19, 0xE0, 0xBB, 0x4E, 0xEC, 0x86, 0x65, 0xFF, + 0x36, 0xF3, 0x5E, 0x67, 0x02, 0x0B, 0x9D, 0x86, 0x55, 0x61, 0xFD, 0x7A, + 0x38, 0xED, 0xFE, 0xE2, 0x19, 0x00, 0xB7, 0x6F, 0xA1, 0x50, 0x62, 0x75, + 0x74, 0x3C, 0xA0, 0xFA, 0xC8, 0x25, 0x92, 0xB4, 0x6E, 0x7A, 0x22, 0xC7, + 0xF8, 0x1E, 0xA1, 0xE3, 0xB2, 0xDD, 0x91, 0x31, 0xAB, 0x2B, 0x1D, 0x04, + 0xFF, 0xA5, 0x4A, 0x04, 0x37, 0xE9, 0x85, 0xA4, 0x33, 0x2B, 0xFD, 0xE2, + 0xD6, 0x55, 0x34, 0x7C, 0x19, 0xA4, 0x4A, 0x68, 0xC7, 0xB2, 0xA8, 0xD3, + 0xB7, 0xCA, 0xA1, 0x93, 0x88, 0xEB, 0xC1, 0x97, 0xBC, 0x8C, 0xF9, 0x1D, + 0xD9, 0x22, 0x84, 0x24, 0x74, 0xC7, 0x04, 0x3D, 0x6A, 0xA9, 0x29, 0x93, + 0xCC, 0xEB, 0xB8, 0x5B, 0xE1, 0xFE, 0x5F, 0x25, 0xAA, 0x34, 0x58, 0xC8, + 0xC1, 0x23, 0x54, 0x9D, 0x1B, 0x98, 0x11, 0xC3, 0x38, 0x9C, 0x7E, 0x3D, + 0x86, 0x6C, 0xA5, 0x0F, 0x40, 0x86, 0x7C, 0x02, 0xF4, 0x5C, 0x02, 0x4F, + 0x28, 0xCB, 0xAE, 0x71, 0x9F, 0x0F, 0x3A, 0xC8, 0x33, 0xFE, 0x11, 0x25, + 0x35, 0xEA, 0xFC, 0xBA, 0xC5, 0x60, 0x3D, 0xD9, 0x7C, 0x18, 0xD5, 0xB2, + 0xA9, 0xD3, 0x75, 0x78, 0x03, 0x72, 0x22, 0xCA, 0x3A, 0xC3, 0x1F, 0xEF, + 0x2C, 0xE5, 0x2E, 0xA9, 0xFA, 0x9E, 0x2C, 0xB6, 0x51, 0x46, 0xFD, 0xAF, + 0x03, 0xD6, 0xEA, 0x60, 0x68, 0xEA, 0x85, 0x16, 0x36, 0x6B, 0x85, 0xE9, + 0x1E, 0xC0, 0xB3, 0xDD, 0xC4, 0x24, 0xDC, 0x80, 0x2A, 0x81, 0x41, 0x6D, + 0x94, 0x3E, 0xC8, 0xE0, 0xC9, 0x81, 0x41, 0x00, 0x9E, 0x5E, 0xBF, 0x7F, + 0xC5, 0x08, 0x98, 0xA2, 0x18, 0x2C, 0x42, 0x40, 0xB3, 0xF9, 0x6F, 0x38, + 0x27, 0x4B, 0x4E, 0x80, 0xF4, 0x3D, 0x81, 0x47, 0xE0, 0x88, 0x7C, 0xEA, + 0x1C, 0xCE, 0xB5, 0x75, 0x5C, 0x51, 0x2E, 0x1C, 0x2B, 0x7F, 0x1A, 0x72, + 0x28, 0xE7, 0x00, 0xB5, 0xD1, 0x74, 0xC6, 0xD7, 0xE4, 0x9F, 0xAD, 0x07, + 0x93, 0xB6, 0x53, 0x35, 0x35, 0xFC, 0x37, 0xE4, 0xC3, 0xF6, 0x5D, 0x16, + 0xBE, 0x21, 0x73, 0xDE, 0x92, 0x0A, 0xF8, 0xA0, 0x63, 0x6A, 0xBC, 0x96, + 0x92, 0x6A, 0x3E, 0xF8, 0xBC, 0x65, 0x55, 0x9B, 0xDE, 0xF5, 0x0D, 0x89, + 0x26, 0x04, 0xFC, 0x25, 0x1A, 0xA6, 0x25, 0x69, 0xCB, 0xC2, 0x6D, 0xCA, + 0x7C, 0xE2, 0x59, 0x5F, 0x97, 0xAC, 0xEB, 0xEF, 0x2E, 0xC8, 0xBC, 0xD7, + 0x1B, 0x59, 0x3C, 0x2B, 0xCC, 0xF2, 0x19, 0xC8, 0x93, 0x6B, 0x27, 0x63, + 0x19, 0xCF, 0xFC, 0xE9, 0x26, 0xF8, 0xCA, 0x71, 0x9B, 0x7F, 0x93, 0xFE, + 0x34, 0x67, 0x84, 0x4E, 0x99, 0xEB, 0xFC, 0xB3, 0x78, 0x09, 0x33, 0x70, + 0xBA, 0x66, 0xA6, 0x76, 0xED, 0x1B, 0x73, 0xEB, 0x1A, 0xA5, 0x0D, 0xC4, + 0x22, 0x13, 0x20, 0x94, 0x56, 0x0A, 0x4E, 0x2C, 0x6C, 0x4E, 0xB1, 0xFD, + 0xCF, 0x9C, 0x09, 0xBA, 0xA2, 0x33, 0xED, 0x87 +}; + +static const unsigned char TA113_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA114_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x15, 0x77, 0x77, 0x77, 0x2E, 0x78, 0x72, 0x61, 0x6D, 0x70, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x58, + 0x52, 0x61, 0x6D, 0x70, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x24, 0x58, 0x52, 0x61, 0x6D, 0x70, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA114_RSA_N[] = { + 0x98, 0x24, 0x1E, 0xBD, 0x15, 0xB4, 0xBA, 0xDF, 0xC7, 0x8C, 0xA5, 0x27, + 0xB6, 0x38, 0x0B, 0x69, 0xF3, 0xB6, 0x4E, 0xA8, 0x2C, 0x2E, 0x21, 0x1D, + 0x5C, 0x44, 0xDF, 0x21, 0x5D, 0x7E, 0x23, 0x74, 0xFE, 0x5E, 0x7E, 0xB4, + 0x4A, 0xB7, 0xA6, 0xAD, 0x1F, 0xAE, 0xE0, 0x06, 0x16, 0xE2, 0x9B, 0x5B, + 0xD9, 0x67, 0x74, 0x6B, 0x5D, 0x80, 0x8F, 0x29, 0x9D, 0x86, 0x1B, 0xD9, + 0x9C, 0x0D, 0x98, 0x6D, 0x76, 0x10, 0x28, 0x58, 0xE4, 0x65, 0xB0, 0x7F, + 0x4A, 0x98, 0x79, 0x9F, 0xE0, 0xC3, 0x31, 0x7E, 0x80, 0x2B, 0xB5, 0x8C, + 0xC0, 0x40, 0x3B, 0x11, 0x86, 0xD0, 0xCB, 0xA2, 0x86, 0x36, 0x60, 0xA4, + 0xD5, 0x30, 0x82, 0x6D, 0xD9, 0x6E, 0xD0, 0x0F, 0x12, 0x04, 0x33, 0x97, + 0x5F, 0x4F, 0x61, 0x5A, 0xF0, 0xE4, 0xF9, 0x91, 0xAB, 0xE7, 0x1D, 0x3B, + 0xBC, 0xE8, 0xCF, 0xF4, 0x6B, 0x2D, 0x34, 0x7C, 0xE2, 0x48, 0x61, 0x1C, + 0x8E, 0xF3, 0x61, 0x44, 0xCC, 0x6F, 0xA0, 0x4A, 0xA9, 0x94, 0xB0, 0x4D, + 0xDA, 0xE7, 0xA9, 0x34, 0x7A, 0x72, 0x38, 0xA8, 0x41, 0xCC, 0x3C, 0x94, + 0x11, 0x7D, 0xEB, 0xC8, 0xA6, 0x8C, 0xB7, 0x86, 0xCB, 0xCA, 0x33, 0x3B, + 0xD9, 0x3D, 0x37, 0x8B, 0xFB, 0x7A, 0x3E, 0x86, 0x2C, 0xE7, 0x73, 0xD7, + 0x0A, 0x57, 0xAC, 0x64, 0x9B, 0x19, 0xEB, 0xF4, 0x0F, 0x04, 0x08, 0x8A, + 0xAC, 0x03, 0x17, 0x19, 0x64, 0xF4, 0x5A, 0x25, 0x22, 0x8D, 0x34, 0x2C, + 0xB2, 0xF6, 0x68, 0x1D, 0x12, 0x6D, 0xD3, 0x8A, 0x1E, 0x14, 0xDA, 0xC4, + 0x8F, 0xA6, 0xE2, 0x23, 0x85, 0xD5, 0x7A, 0x0D, 0xBD, 0x6A, 0xE0, 0xE9, + 0xEC, 0xEC, 0x17, 0xBB, 0x42, 0x1B, 0x67, 0xAA, 0x25, 0xED, 0x45, 0x83, + 0x21, 0xFC, 0xC1, 0xC9, 0x7C, 0xD5, 0x62, 0x3E, 0xFA, 0xF2, 0xC5, 0x2D, + 0xD3, 0xFD, 0xD4, 0x65 +}; + +static const unsigned char TA114_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA115_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA115_RSA_N[] = { + 0xA0, 0xBE, 0x50, 0x10, 0x8E, 0xE9, 0xF2, 0x6C, 0x40, 0xB4, 0x04, 0x9C, + 0x85, 0xB9, 0x31, 0xCA, 0xDC, 0x2D, 0xE4, 0x11, 0xA9, 0x04, 0x3C, 0x1B, + 0x55, 0xC1, 0xE7, 0x58, 0x30, 0x1D, 0x24, 0xB4, 0xC3, 0xEF, 0x85, 0xDE, + 0x8C, 0x2C, 0xE1, 0xC1, 0x3D, 0xDF, 0x82, 0xE6, 0x4F, 0xAD, 0x47, 0x87, + 0x6C, 0xEC, 0x5B, 0x49, 0xC1, 0x4A, 0xD5, 0xBB, 0x8F, 0xEC, 0x87, 0xAC, + 0x7F, 0x82, 0x9A, 0x86, 0xEC, 0x3D, 0x03, 0x99, 0x52, 0x01, 0xD2, 0x35, + 0x9E, 0xAC, 0xDA, 0xF0, 0x53, 0xC9, 0x66, 0x3C, 0xD4, 0xAC, 0x02, 0x01, + 0xDA, 0x24, 0xD3, 0x3B, 0xA8, 0x02, 0x46, 0xAF, 0xA4, 0x1C, 0xE3, 0xF8, + 0x73, 0x58, 0x76, 0xB7, 0xF6, 0x0E, 0x90, 0x0D, 0xB5, 0xF0, 0xCF, 0xCC, + 0xFA, 0xF9, 0xC6, 0x4C, 0xE5, 0xC3, 0x86, 0x30, 0x0A, 0x8D, 0x17, 0x7E, + 0x35, 0xEB, 0xC5, 0xDF, 0xBB, 0x0E, 0x9C, 0xC0, 0x8D, 0x87, 0xE3, 0x88, + 0x38, 0x85, 0x67, 0xFA, 0x3E, 0xC7, 0xAB, 0xE0, 0x13, 0x9C, 0x05, 0x18, + 0x98, 0xCF, 0x93, 0xF5, 0xB1, 0x92, 0xB4, 0xFC, 0x23, 0xD3, 0xCF, 0xD5, + 0xC4, 0x27, 0x49, 0xE0, 0x9E, 0x3C, 0x9B, 0x08, 0xA3, 0x8B, 0x5D, 0x2A, + 0x21, 0xE0, 0xFC, 0x39, 0xAA, 0x53, 0xDA, 0x7D, 0x7E, 0xCF, 0x1A, 0x09, + 0x53, 0xBC, 0x5D, 0x05, 0x04, 0xCF, 0xA1, 0x4A, 0x8F, 0x8B, 0x76, 0x82, + 0x0D, 0xA1, 0xF8, 0xD2, 0xC7, 0x14, 0x77, 0x5B, 0x90, 0x36, 0x07, 0x81, + 0x9B, 0x3E, 0x06, 0xFA, 0x52, 0x5E, 0x63, 0xC5, 0xA6, 0x00, 0xFE, 0xA5, + 0xE9, 0x52, 0x1B, 0x52, 0xB5, 0x92, 0x39, 0x72, 0x03, 0x09, 0x62, 0xBD, + 0xB0, 0x60, 0x16, 0x6E, 0xA6, 0xDD, 0x25, 0xC2, 0x03, 0x66, 0xDD, 0xF3, + 0x04, 0xD1, 0x40, 0xE2, 0x4E, 0x8B, 0x86, 0xF4, 0x6F, 0xE5, 0x83, 0xA0, + 0x27, 0x84, 0x5E, 0x04, 0xC1, 0xF5, 0x90, 0xBD, 0x30, 0x3D, 0xC4, 0xEF, + 0xA8, 0x69, 0xBC, 0x38, 0x9B, 0xA4, 0xA4, 0x96, 0xD1, 0x62, 0xDA, 0x69, + 0xC0, 0x01, 0x96, 0xAE, 0xCB, 0xC4, 0x51, 0x34, 0xEA, 0x0C, 0xAA, 0xFF, + 0x21, 0x8E, 0x59, 0x8F, 0x4A, 0x5C, 0xE4, 0x61, 0x9A, 0xA7, 0xD2, 0xE9, + 0x2A, 0x78, 0x8D, 0x51, 0x3D, 0x3A, 0x15, 0xEE, 0xA2, 0x59, 0x8E, 0xA9, + 0x5C, 0xDE, 0xC5, 0xF9, 0x90, 0x22, 0xE5, 0x88, 0x45, 0x71, 0xDD, 0x91, + 0x99, 0x6C, 0x7A, 0x9F, 0x3D, 0x3D, 0x98, 0x7C, 0x5E, 0xF6, 0xBE, 0x16, + 0x68, 0xA0, 0x5E, 0xAE, 0x0B, 0x23, 0xFC, 0x5A, 0x0F, 0xAA, 0x22, 0x76, + 0x2D, 0xC9, 0xA1, 0x10, 0x1D, 0xE4, 0xD3, 0x44, 0x23, 0x90, 0x88, 0x9F, + 0xC6, 0x2A, 0xE6, 0xD7, 0xF5, 0x9A, 0xB3, 0x58, 0x1E, 0x2F, 0x30, 0x89, + 0x08, 0x1B, 0x54, 0xA2, 0xB5, 0x98, 0x23, 0xEC, 0x08, 0x77, 0x1C, 0x95, + 0x5D, 0x61, 0xD1, 0xCB, 0x89, 0x9C, 0x5F, 0xA2, 0x4A, 0x91, 0x9A, 0xEF, + 0x21, 0xAA, 0x49, 0x16, 0x08, 0xA8, 0xBD, 0x61, 0x28, 0x31, 0xC9, 0x74, + 0xAD, 0x85, 0xF6, 0xD9, 0xC5, 0xB1, 0x8B, 0xD1, 0xE5, 0x10, 0x32, 0x4D, + 0x5F, 0x8B, 0x20, 0x3A, 0x3C, 0x49, 0x1F, 0x33, 0x85, 0x59, 0x0D, 0xDB, + 0xCB, 0x09, 0x75, 0x43, 0x69, 0x73, 0xFB, 0x6B, 0x71, 0x7D, 0xF0, 0xDF, + 0xC4, 0x4C, 0x7D, 0xC6, 0xA3, 0x2E, 0xC8, 0x95, 0x79, 0xCB, 0x73, 0xA2, + 0x8E, 0x4E, 0x4D, 0x24, 0xFB, 0x5E, 0xE4, 0x04, 0xBE, 0x72, 0x1B, 0xA6, + 0x27, 0x2D, 0x49, 0x5A, 0x99, 0x7A, 0xD7, 0x5C, 0x09, 0x20, 0xB7, 0x7F, + 0x94, 0xB9, 0x4F, 0xF1, 0x0D, 0x1C, 0x5E, 0x88, 0x42, 0x1B, 0x11, 0xB7, + 0xE7, 0x91, 0xDB, 0x9E, 0x6C, 0xF4, 0x6A, 0xDF, 0x8C, 0x06, 0x98, 0x03, + 0xAD, 0xCC, 0x28, 0xEF, 0xA5, 0x47, 0xF3, 0x53 +}; + +static const unsigned char TA115_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA116_DN[] = { + 0x30, 0x7B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, 0x61, + 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x53, 0x61, 0x6C, 0x66, 0x6F, + 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x11, 0x43, 0x6F, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x43, 0x41, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x18, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73 +}; + +static const unsigned char TA116_RSA_N[] = { + 0xBE, 0x40, 0x9D, 0xF4, 0x6E, 0xE1, 0xEA, 0x76, 0x87, 0x1C, 0x4D, 0x45, + 0x44, 0x8E, 0xBE, 0x46, 0xC8, 0x83, 0x06, 0x9D, 0xC1, 0x2A, 0xFE, 0x18, + 0x1F, 0x8E, 0xE4, 0x02, 0xFA, 0xF3, 0xAB, 0x5D, 0x50, 0x8A, 0x16, 0x31, + 0x0B, 0x9A, 0x06, 0xD0, 0xC5, 0x70, 0x22, 0xCD, 0x49, 0x2D, 0x54, 0x63, + 0xCC, 0xB6, 0x6E, 0x68, 0x46, 0x0B, 0x53, 0xEA, 0xCB, 0x4C, 0x24, 0xC0, + 0xBC, 0x72, 0x4E, 0xEA, 0xF1, 0x15, 0xAE, 0xF4, 0x54, 0x9A, 0x12, 0x0A, + 0xC3, 0x7A, 0xB2, 0x33, 0x60, 0xE2, 0xDA, 0x89, 0x55, 0xF3, 0x22, 0x58, + 0xF3, 0xDE, 0xDC, 0xCF, 0xEF, 0x83, 0x86, 0xA2, 0x8C, 0x94, 0x4F, 0x9F, + 0x68, 0xF2, 0x98, 0x90, 0x46, 0x84, 0x27, 0xC7, 0x76, 0xBF, 0xE3, 0xCC, + 0x35, 0x2C, 0x8B, 0x5E, 0x07, 0x64, 0x65, 0x82, 0xC0, 0x48, 0xB0, 0xA8, + 0x91, 0xF9, 0x61, 0x9F, 0x76, 0x20, 0x50, 0xA8, 0x91, 0xC7, 0x66, 0xB5, + 0xEB, 0x78, 0x62, 0x03, 0x56, 0xF0, 0x8A, 0x1A, 0x13, 0xEA, 0x31, 0xA3, + 0x1E, 0xA0, 0x99, 0xFD, 0x38, 0xF6, 0xF6, 0x27, 0x32, 0x58, 0x6F, 0x07, + 0xF5, 0x6B, 0xB8, 0xFB, 0x14, 0x2B, 0xAF, 0xB7, 0xAA, 0xCC, 0xD6, 0x63, + 0x5F, 0x73, 0x8C, 0xDA, 0x05, 0x99, 0xA8, 0x38, 0xA8, 0xCB, 0x17, 0x78, + 0x36, 0x51, 0xAC, 0xE9, 0x9E, 0xF4, 0x78, 0x3A, 0x8D, 0xCF, 0x0F, 0xD9, + 0x42, 0xE2, 0x98, 0x0C, 0xAB, 0x2F, 0x9F, 0x0E, 0x01, 0xDE, 0xEF, 0x9F, + 0x99, 0x49, 0xF1, 0x2D, 0xDF, 0xAC, 0x74, 0x4D, 0x1B, 0x98, 0xB5, 0x47, + 0xC5, 0xE5, 0x29, 0xD1, 0xF9, 0x90, 0x18, 0xC7, 0x62, 0x9C, 0xBE, 0x83, + 0xC7, 0x26, 0x7B, 0x3E, 0x8A, 0x25, 0xC7, 0xC0, 0xDD, 0x9D, 0xE6, 0x35, + 0x68, 0x10, 0x20, 0x9D, 0x8F, 0xD8, 0xDE, 0xD2, 0xC3, 0x84, 0x9C, 0x0D, + 0x5E, 0xE8, 0x2F, 0xC9 +}; + +static const unsigned char TA116_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA117_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x18, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA117_RSA_N[] = { + 0xBF, 0xE6, 0x90, 0x73, 0x68, 0xDE, 0xBB, 0xE4, 0x5D, 0x4A, 0x3C, 0x30, + 0x22, 0x30, 0x69, 0x33, 0xEC, 0xC2, 0xA7, 0x25, 0x2E, 0xC9, 0x21, 0x3D, + 0xF2, 0x8A, 0xD8, 0x59, 0xC2, 0xE1, 0x29, 0xA7, 0x3D, 0x58, 0xAB, 0x76, + 0x9A, 0xCD, 0xAE, 0x7B, 0x1B, 0x84, 0x0D, 0xC4, 0x30, 0x1F, 0xF3, 0x1B, + 0xA4, 0x38, 0x16, 0xEB, 0x56, 0xC6, 0x97, 0x6D, 0x1D, 0xAB, 0xB2, 0x79, + 0xF2, 0xCA, 0x11, 0xD2, 0xE4, 0x5F, 0xD6, 0x05, 0x3C, 0x52, 0x0F, 0x52, + 0x1F, 0xC6, 0x9E, 0x15, 0xA5, 0x7E, 0xBE, 0x9F, 0xA9, 0x57, 0x16, 0x59, + 0x55, 0x72, 0xAF, 0x68, 0x93, 0x70, 0xC2, 0xB2, 0xBA, 0x75, 0x99, 0x6A, + 0x73, 0x32, 0x94, 0xD1, 0x10, 0x44, 0x10, 0x2E, 0xDF, 0x82, 0xF3, 0x07, + 0x84, 0xE6, 0x74, 0x3B, 0x6D, 0x71, 0xE2, 0x2D, 0x0C, 0x1B, 0xEE, 0x20, + 0xD5, 0xC9, 0x20, 0x1D, 0x63, 0x29, 0x2D, 0xCE, 0xEC, 0x5E, 0x4E, 0xC8, + 0x93, 0xF8, 0x21, 0x61, 0x9B, 0x34, 0xEB, 0x05, 0xC6, 0x5E, 0xEC, 0x5B, + 0x1A, 0xBC, 0xEB, 0xC9, 0xCF, 0xCD, 0xAC, 0x34, 0x40, 0x5F, 0xB1, 0x7A, + 0x66, 0xEE, 0x77, 0xC8, 0x48, 0xA8, 0x66, 0x57, 0x57, 0x9F, 0x54, 0x58, + 0x8E, 0x0C, 0x2B, 0xB7, 0x4F, 0xA7, 0x30, 0xD9, 0x56, 0xEE, 0xCA, 0x7B, + 0x5D, 0xE3, 0xAD, 0xC9, 0x4F, 0x5E, 0xE5, 0x35, 0xE7, 0x31, 0xCB, 0xDA, + 0x93, 0x5E, 0xDC, 0x8E, 0x8F, 0x80, 0xDA, 0xB6, 0x91, 0x98, 0x40, 0x90, + 0x79, 0xC3, 0x78, 0xC7, 0xB6, 0xB1, 0xC4, 0xB5, 0x6A, 0x18, 0x38, 0x03, + 0x10, 0x8D, 0xD8, 0xD4, 0x37, 0xA4, 0x2E, 0x05, 0x7D, 0x88, 0xF5, 0x82, + 0x3E, 0x10, 0x91, 0x70, 0xAB, 0x55, 0x82, 0x41, 0x32, 0xD7, 0xDB, 0x04, + 0x73, 0x2A, 0x6E, 0x91, 0x01, 0x7C, 0x21, 0x4C, 0xD4, 0xBC, 0xAE, 0x1B, + 0x03, 0x75, 0x5D, 0x78, 0x66, 0xD9, 0x3A, 0x31, 0x44, 0x9A, 0x33, 0x40, + 0xBF, 0x08, 0xD7, 0x5A, 0x49, 0xA4, 0xC2, 0xE6, 0xA9, 0xA0, 0x67, 0xDD, + 0xA4, 0x27, 0xBC, 0xA1, 0x4F, 0x39, 0xB5, 0x11, 0x58, 0x17, 0xF7, 0x24, + 0x5C, 0x46, 0x8F, 0x64, 0xF7, 0xC1, 0x69, 0x88, 0x76, 0x98, 0x76, 0x3D, + 0x59, 0x5D, 0x42, 0x76, 0x87, 0x89, 0x97, 0x69, 0x7A, 0x48, 0xF0, 0xE0, + 0xA2, 0x12, 0x1B, 0x66, 0x9A, 0x74, 0xCA, 0xDE, 0x4B, 0x1E, 0xE7, 0x0E, + 0x63, 0xAE, 0xE6, 0xD4, 0xEF, 0x92, 0x92, 0x3A, 0x9E, 0x3D, 0xDC, 0x00, + 0xE4, 0x45, 0x25, 0x89, 0xB6, 0x9A, 0x44, 0x19, 0x2B, 0x7E, 0xC0, 0x94, + 0xB4, 0xD2, 0x61, 0x6D, 0xEB, 0x33, 0xD9, 0xC5, 0xDF, 0x4B, 0x04, 0x00, + 0xCC, 0x7D, 0x1C, 0x95, 0xC3, 0x8F, 0xF7, 0x21, 0xB2, 0xB2, 0x11, 0xB7, + 0xBB, 0x7F, 0xF2, 0xD5, 0x8C, 0x70, 0x2C, 0x41, 0x60, 0xAA, 0xB1, 0x63, + 0x18, 0x44, 0x95, 0x1A, 0x76, 0x62, 0x7E, 0xF6, 0x80, 0xB0, 0xFB, 0xE8, + 0x64, 0xA6, 0x33, 0xD1, 0x89, 0x07, 0xE1, 0xBD, 0xB7, 0xE6, 0x43, 0xA4, + 0x18, 0xB8, 0xA6, 0x77, 0x01, 0xE1, 0x0F, 0x94, 0x0C, 0x21, 0x1D, 0xB2, + 0x54, 0x29, 0x25, 0x89, 0x6C, 0xE5, 0x0E, 0x52, 0x51, 0x47, 0x74, 0xBE, + 0x26, 0xAC, 0xB6, 0x41, 0x75, 0xDE, 0x7A, 0xAC, 0x5F, 0x8D, 0x3F, 0xC9, + 0xBC, 0xD3, 0x41, 0x11, 0x12, 0x5B, 0xE5, 0x10, 0x50, 0xEB, 0x31, 0xC5, + 0xCA, 0x72, 0x16, 0x22, 0x09, 0xDF, 0x7C, 0x4C, 0x75, 0x3F, 0x63, 0xEC, + 0x21, 0x5F, 0xC4, 0x20, 0x51, 0x6B, 0x6F, 0xB1, 0xAB, 0x86, 0x8B, 0x4F, + 0xC2, 0xD6, 0x45, 0x5F, 0x9D, 0x20, 0xFC, 0xA1, 0x1E, 0xC5, 0xC0, 0x8F, + 0xA2, 0xB1, 0x7E, 0x0A, 0x26, 0x99, 0xF5, 0xE4, 0x69, 0x2F, 0x98, 0x1D, + 0x2D, 0xF5, 0xD9, 0xA9, 0xB2, 0x1D, 0xE5, 0x1B +}; + +static const unsigned char TA117_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA118_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x15, 0x77, 0x77, 0x77, 0x2E, 0x78, 0x72, 0x61, 0x6D, 0x70, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x58, + 0x52, 0x61, 0x6D, 0x70, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x24, 0x58, 0x52, 0x61, 0x6D, 0x70, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA118_RSA_N[] = { + 0x98, 0x24, 0x1E, 0xBD, 0x15, 0xB4, 0xBA, 0xDF, 0xC7, 0x8C, 0xA5, 0x27, + 0xB6, 0x38, 0x0B, 0x69, 0xF3, 0xB6, 0x4E, 0xA8, 0x2C, 0x2E, 0x21, 0x1D, + 0x5C, 0x44, 0xDF, 0x21, 0x5D, 0x7E, 0x23, 0x74, 0xFE, 0x5E, 0x7E, 0xB4, + 0x4A, 0xB7, 0xA6, 0xAD, 0x1F, 0xAE, 0xE0, 0x06, 0x16, 0xE2, 0x9B, 0x5B, + 0xD9, 0x67, 0x74, 0x6B, 0x5D, 0x80, 0x8F, 0x29, 0x9D, 0x86, 0x1B, 0xD9, + 0x9C, 0x0D, 0x98, 0x6D, 0x76, 0x10, 0x28, 0x58, 0xE4, 0x65, 0xB0, 0x7F, + 0x4A, 0x98, 0x79, 0x9F, 0xE0, 0xC3, 0x31, 0x7E, 0x80, 0x2B, 0xB5, 0x8C, + 0xC0, 0x40, 0x3B, 0x11, 0x86, 0xD0, 0xCB, 0xA2, 0x86, 0x36, 0x60, 0xA4, + 0xD5, 0x30, 0x82, 0x6D, 0xD9, 0x6E, 0xD0, 0x0F, 0x12, 0x04, 0x33, 0x97, + 0x5F, 0x4F, 0x61, 0x5A, 0xF0, 0xE4, 0xF9, 0x91, 0xAB, 0xE7, 0x1D, 0x3B, + 0xBC, 0xE8, 0xCF, 0xF4, 0x6B, 0x2D, 0x34, 0x7C, 0xE2, 0x48, 0x61, 0x1C, + 0x8E, 0xF3, 0x61, 0x44, 0xCC, 0x6F, 0xA0, 0x4A, 0xA9, 0x94, 0xB0, 0x4D, + 0xDA, 0xE7, 0xA9, 0x34, 0x7A, 0x72, 0x38, 0xA8, 0x41, 0xCC, 0x3C, 0x94, + 0x11, 0x7D, 0xEB, 0xC8, 0xA6, 0x8C, 0xB7, 0x86, 0xCB, 0xCA, 0x33, 0x3B, + 0xD9, 0x3D, 0x37, 0x8B, 0xFB, 0x7A, 0x3E, 0x86, 0x2C, 0xE7, 0x73, 0xD7, + 0x0A, 0x57, 0xAC, 0x64, 0x9B, 0x19, 0xEB, 0xF4, 0x0F, 0x04, 0x08, 0x8A, + 0xAC, 0x03, 0x17, 0x19, 0x64, 0xF4, 0x5A, 0x25, 0x22, 0x8D, 0x34, 0x2C, + 0xB2, 0xF6, 0x68, 0x1D, 0x12, 0x6D, 0xD3, 0x8A, 0x1E, 0x14, 0xDA, 0xC4, + 0x8F, 0xA6, 0xE2, 0x23, 0x85, 0xD5, 0x7A, 0x0D, 0xBD, 0x6A, 0xE0, 0xE9, + 0xEC, 0xEC, 0x17, 0xBB, 0x42, 0x1B, 0x67, 0xAA, 0x25, 0xED, 0x45, 0x83, + 0x21, 0xFC, 0xC1, 0xC9, 0x7C, 0xD5, 0x62, 0x3E, 0xFA, 0xF2, 0xC5, 0x2D, + 0xD3, 0xFD, 0xD4, 0x65 +}; + +static const unsigned char TA118_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA119_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA119_RSA_N[] = { + 0xCC, 0x57, 0x42, 0x16, 0x54, 0x9C, 0xE6, 0x98, 0xD3, 0xD3, 0x4D, 0xEE, + 0xFE, 0xED, 0xC7, 0x9F, 0x43, 0x39, 0x4A, 0x65, 0xB3, 0xE8, 0x16, 0x88, + 0x34, 0xDB, 0x0D, 0x59, 0x91, 0x74, 0xCF, 0x92, 0xB8, 0x04, 0x40, 0xAD, + 0x02, 0x4B, 0x31, 0xAB, 0xBC, 0x8D, 0x91, 0x68, 0xD8, 0x20, 0x0E, 0x1A, + 0x01, 0xE2, 0x1A, 0x7B, 0x4E, 0x17, 0x5D, 0xE2, 0x8A, 0xB7, 0x3F, 0x99, + 0x1A, 0xCD, 0xEB, 0x61, 0xAB, 0xC2, 0x65, 0xA6, 0x1F, 0xB7, 0xB7, 0xBD, + 0xB7, 0x8F, 0xFC, 0xFD, 0x70, 0x8F, 0x0B, 0xA0, 0x67, 0xBE, 0x01, 0xA2, + 0x59, 0xCF, 0x71, 0xE6, 0x0F, 0x29, 0x76, 0xFF, 0xB1, 0x56, 0x79, 0x45, + 0x2B, 0x1F, 0x9E, 0x7A, 0x54, 0xE8, 0xA3, 0x29, 0x35, 0x68, 0xA4, 0x01, + 0x4F, 0x0F, 0xA4, 0x2E, 0x37, 0xEF, 0x1B, 0xBF, 0xE3, 0x8F, 0x10, 0xA8, + 0x72, 0xAB, 0x58, 0x57, 0xE7, 0x54, 0x86, 0xC8, 0xC9, 0xF3, 0x5B, 0xDA, + 0x2C, 0xDA, 0x5D, 0x8E, 0x6E, 0x3C, 0xA3, 0x3E, 0xDA, 0xFB, 0x82, 0xE5, + 0xDD, 0xF2, 0x5C, 0xB2, 0x05, 0x33, 0x6F, 0x8A, 0x36, 0xCE, 0xD0, 0x13, + 0x4E, 0xFF, 0xBF, 0x4A, 0x0C, 0x34, 0x4C, 0xA6, 0xC3, 0x21, 0xBD, 0x50, + 0x04, 0x55, 0xEB, 0xB1, 0xBB, 0x9D, 0xFB, 0x45, 0x1E, 0x64, 0x15, 0xDE, + 0x55, 0x01, 0x8C, 0x02, 0x76, 0xB5, 0xCB, 0xA1, 0x3F, 0x42, 0x69, 0xBC, + 0x2F, 0xBD, 0x68, 0x43, 0x16, 0x56, 0x89, 0x2A, 0x37, 0x61, 0x91, 0xFD, + 0xA6, 0xAE, 0x4E, 0xC0, 0xCB, 0x14, 0x65, 0x94, 0x37, 0x4B, 0x92, 0x06, + 0xEF, 0x04, 0xD0, 0xC8, 0x9C, 0x88, 0xDB, 0x0B, 0x7B, 0x81, 0xAF, 0xB1, + 0x3D, 0x2A, 0xC4, 0x65, 0x3A, 0x78, 0xB6, 0xEE, 0xDC, 0x80, 0xB1, 0xD2, + 0xD3, 0x99, 0x9C, 0x3A, 0xEE, 0x6B, 0x5A, 0x6B, 0xB3, 0x8D, 0xB7, 0xD5, + 0xCE, 0x9C, 0xC2, 0xBE, 0xA5, 0x4B, 0x2F, 0x16, 0xB1, 0x9E, 0x68, 0x3B, + 0x06, 0x6F, 0xAE, 0x7D, 0x9F, 0xF8, 0xDE, 0xEC, 0xCC, 0x29, 0xA7, 0x98, + 0xA3, 0x25, 0x43, 0x2F, 0xEF, 0xF1, 0x5F, 0x26, 0xE1, 0x88, 0x4D, 0xF8, + 0x5E, 0x6E, 0xD7, 0xD9, 0x14, 0x6E, 0x19, 0x33, 0x69, 0xA7, 0x3B, 0x84, + 0x89, 0x93, 0xC4, 0x53, 0x55, 0x13, 0xA1, 0x51, 0x78, 0x40, 0xF8, 0xB8, + 0xC9, 0xA2, 0xEE, 0x7B, 0xBA, 0x52, 0x42, 0x83, 0x9E, 0x14, 0xED, 0x05, + 0x52, 0x5A, 0x59, 0x56, 0xA7, 0x97, 0xFC, 0x9D, 0x3F, 0x0A, 0x29, 0xD8, + 0xDC, 0x4F, 0x91, 0x0E, 0x13, 0xBC, 0xDE, 0x95, 0xA4, 0xDF, 0x8B, 0x99, + 0xBE, 0xAC, 0x9B, 0x33, 0x88, 0xEF, 0xB5, 0x81, 0xAF, 0x1B, 0xC6, 0x22, + 0x53, 0xC8, 0xF6, 0xC7, 0xEE, 0x97, 0x14, 0xB0, 0xC5, 0x7C, 0x78, 0x52, + 0xC8, 0xF0, 0xCE, 0x6E, 0x77, 0x60, 0x84, 0xA6, 0xE9, 0x2A, 0x76, 0x20, + 0xED, 0x58, 0x01, 0x17, 0x30, 0x93, 0xE9, 0x1A, 0x8B, 0xE0, 0x73, 0x63, + 0xD9, 0x6A, 0x92, 0x94, 0x49, 0x4E, 0xB4, 0xAD, 0x4A, 0x85, 0xC4, 0xA3, + 0x22, 0x30, 0xFC, 0x09, 0xED, 0x68, 0x22, 0x73, 0xA6, 0x88, 0x0C, 0x55, + 0x21, 0x58, 0xC5, 0xE1, 0x3A, 0x9F, 0x2A, 0xDD, 0xCA, 0xE1, 0x90, 0xE0, + 0xD9, 0x73, 0xAB, 0x6C, 0x80, 0xB8, 0xE8, 0x0B, 0x64, 0x93, 0xA0, 0x9C, + 0x8C, 0x19, 0xFF, 0xB3, 0xD2, 0x0C, 0xEC, 0x91, 0x26, 0x87, 0x8A, 0xB3, + 0xA2, 0xE1, 0x70, 0x8F, 0x2C, 0x0A, 0xE5, 0xCD, 0x6D, 0x68, 0x51, 0xEB, + 0xDA, 0x3F, 0x05, 0x7F, 0x8B, 0x32, 0xE6, 0x13, 0x5C, 0x6B, 0xFE, 0x5F, + 0x40, 0xE2, 0x22, 0xC8, 0xB4, 0xB4, 0x64, 0x4F, 0xD6, 0xBA, 0x7D, 0x48, + 0x3E, 0xA8, 0x69, 0x0C, 0xD7, 0xBB, 0x86, 0x71, 0xC9, 0x73, 0xB8, 0x3F, + 0x3B, 0x9D, 0x25, 0x4B, 0xDA, 0xFF, 0x40, 0xEB +}; + +static const unsigned char TA119_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA120_DN[] = { + 0x30, 0x81, 0xAA, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x44, 0x30, 0x42, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, + 0x20, 0x32, 0x30, 0x31, 0x35 +}; + +static const unsigned char TA120_EC_Q[] = { + 0x04, 0x92, 0xA0, 0x41, 0xE8, 0x4B, 0x82, 0x84, 0x5C, 0xE2, 0xF8, 0x31, + 0x11, 0x99, 0x86, 0x64, 0x4E, 0x09, 0x25, 0x2F, 0x9D, 0x41, 0x2F, 0x0A, + 0xAE, 0x35, 0x4F, 0x74, 0x95, 0xB2, 0x51, 0x64, 0x6B, 0x8D, 0x6B, 0xE6, + 0x3F, 0x70, 0x95, 0xF0, 0x05, 0x44, 0x47, 0xA6, 0x72, 0x38, 0x50, 0x76, + 0x95, 0x02, 0x5A, 0x8E, 0xAE, 0x28, 0x9E, 0xF9, 0x2D, 0x4E, 0x99, 0xEF, + 0x2C, 0x48, 0x6F, 0x4C, 0x25, 0x29, 0xE8, 0xD1, 0x71, 0x5B, 0xDF, 0x1D, + 0xC1, 0x75, 0x37, 0xB4, 0xD7, 0xFA, 0x7B, 0x7A, 0x42, 0x9C, 0x6A, 0x0A, + 0x56, 0x5A, 0x7C, 0x69, 0x0B, 0xAA, 0x80, 0x09, 0x24, 0x6C, 0x7E, 0xC1, + 0x46 +}; + +static const unsigned char TA121_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x43, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA121_EC_Q[] = { + 0x04, 0x4C, 0xE9, 0x50, 0xC0, 0xC6, 0x0F, 0x72, 0x18, 0xBC, 0xD8, 0xF1, + 0xBA, 0xB3, 0x89, 0xE2, 0x79, 0x4A, 0xA3, 0x16, 0xA7, 0x6B, 0x54, 0x24, + 0xDB, 0x51, 0xFF, 0xEA, 0xF4, 0x09, 0x24, 0xC3, 0x0B, 0x22, 0x9F, 0xCB, + 0x6A, 0x27, 0x82, 0x81, 0x0D, 0xD2, 0xC0, 0xAF, 0x31, 0xE4, 0x74, 0x82, + 0x6E, 0xCA, 0x25, 0xD9, 0x8C, 0x75, 0x9D, 0xF1, 0xDB, 0xD0, 0x9A, 0xA2, + 0x4B, 0x21, 0x7E, 0x16, 0xA7, 0x63, 0x90, 0xD2, 0x39, 0xD4, 0xB1, 0x87, + 0x78, 0x5F, 0x18, 0x96, 0x0F, 0x50, 0x1B, 0x35, 0x37, 0x0F, 0x6A, 0xC6, + 0xDC, 0xD9, 0x13, 0x4D, 0xA4, 0x8E, 0x90, 0x37, 0xE6, 0xBD, 0x5B, 0x31, + 0x91 +}; + +static const unsigned char TA122_DN[] = { + 0x30, 0x7F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x2B, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, 0x56, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA122_EC_Q[] = { + 0x04, 0xAA, 0x12, 0x47, 0x90, 0x98, 0x1B, 0xFB, 0xEF, 0xC3, 0x40, 0x07, + 0x83, 0x20, 0x4E, 0xF1, 0x30, 0x82, 0xA2, 0x06, 0xD1, 0xF2, 0x92, 0x86, + 0x61, 0xF2, 0xF6, 0x21, 0x68, 0xCA, 0x00, 0xC4, 0xC7, 0xEA, 0x43, 0x00, + 0x54, 0x86, 0xDC, 0xFD, 0x1F, 0xDF, 0x00, 0xB8, 0x41, 0x62, 0x5C, 0xDC, + 0x70, 0x16, 0x32, 0xDE, 0x1F, 0x99, 0xD4, 0xCC, 0xC5, 0x07, 0xC8, 0x08, + 0x1F, 0x61, 0x16, 0x07, 0x51, 0x3D, 0x7D, 0x5C, 0x07, 0x53, 0xE3, 0x35, + 0x38, 0x8C, 0xDF, 0xCD, 0x9F, 0xD9, 0x2E, 0x0D, 0x4A, 0xB6, 0x19, 0x2E, + 0x5A, 0x70, 0x5A, 0x06, 0xED, 0xBE, 0xF0, 0xA1, 0xB0, 0xCA, 0xD0, 0x09, + 0x29 +}; + +static const unsigned char TA123_DN[] = { + 0x30, 0x43, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, + 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0D, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA123_RSA_N[] = { + 0xBD, 0x55, 0x7C, 0x61, 0xD3, 0xB8, 0x1D, 0x04, 0x62, 0x05, 0xA0, 0xAE, + 0x6C, 0xB7, 0x70, 0xB4, 0x41, 0xEA, 0x4B, 0x03, 0x5E, 0x10, 0x3F, 0x90, + 0x5A, 0x1C, 0x8B, 0x3B, 0xB0, 0x66, 0x8B, 0x6C, 0x48, 0xA6, 0x1C, 0x22, + 0xBA, 0xD5, 0x40, 0x92, 0xEE, 0x33, 0xB2, 0x23, 0x59, 0xC9, 0x8E, 0xBC, + 0x58, 0xDA, 0x8B, 0x9E, 0xD0, 0x19, 0xF2, 0x2F, 0x59, 0xC6, 0x8C, 0x63, + 0x5A, 0xBA, 0x9F, 0xA3, 0x0B, 0xB0, 0xB3, 0x9A, 0x5C, 0xBA, 0x11, 0xB8, + 0x12, 0xE9, 0x0C, 0xBB, 0xCF, 0x6E, 0x6C, 0x80, 0x87, 0x29, 0x14, 0x03, + 0x2C, 0x8D, 0x24, 0x9A, 0xC8, 0x64, 0x83, 0xB5, 0x6A, 0xAC, 0x13, 0x2C, + 0x33, 0xF1, 0x9F, 0xDC, 0x2C, 0x61, 0x3C, 0x1A, 0x3F, 0x70, 0x55, 0x9B, + 0xAD, 0x00, 0x52, 0x7F, 0xCF, 0x04, 0xB9, 0xFE, 0x36, 0xFA, 0x9C, 0xC0, + 0x16, 0xAE, 0x62, 0xFE, 0x96, 0x4C, 0x43, 0x7E, 0x55, 0x14, 0xBE, 0x1A, + 0xB3, 0xD2, 0x6D, 0xC2, 0xAF, 0x76, 0x66, 0x95, 0x6B, 0x2A, 0xB0, 0x94, + 0x77, 0x85, 0x5E, 0x04, 0x0F, 0x62, 0x1D, 0x63, 0x75, 0xF7, 0x6B, 0xE7, + 0xCB, 0x5B, 0x9A, 0x70, 0xEC, 0x3E, 0x67, 0x05, 0xF0, 0xFE, 0x07, 0x08, + 0x80, 0xCF, 0x28, 0xDB, 0x05, 0xC6, 0x14, 0x27, 0x2F, 0x86, 0x7D, 0xF0, + 0x27, 0xDE, 0xFF, 0xE6, 0x7E, 0x33, 0x48, 0xE7, 0x0B, 0x1E, 0x58, 0xD1, + 0x27, 0x2B, 0x53, 0x0E, 0x57, 0x4A, 0x65, 0xD7, 0xFB, 0xA2, 0x80, 0x60, + 0xFC, 0x4C, 0xBC, 0x35, 0x53, 0x01, 0x6A, 0x97, 0x72, 0x82, 0xAF, 0xF1, + 0x1D, 0x70, 0xE8, 0x9C, 0xF5, 0xEF, 0x5E, 0xC2, 0x6C, 0xC7, 0x47, 0x7E, + 0x5A, 0x94, 0x85, 0x26, 0x4D, 0x3B, 0xBA, 0xEB, 0x4C, 0xE8, 0xB0, 0x09, + 0xC2, 0x65, 0xC2, 0x9D, 0x9D, 0x09, 0x9B, 0x4E, 0xB5, 0x97, 0x05, 0xAC, + 0xF5, 0x06, 0xA0, 0xF7, 0x36, 0x05, 0x7E, 0xF4, 0x90, 0xB2, 0x6B, 0xC4, + 0xB4, 0xF9, 0x64, 0xEA, 0xE9, 0x1A, 0x0A, 0xC8, 0x0D, 0xA8, 0xED, 0x27, + 0xC9, 0xD4, 0xE7, 0xB3, 0xB9, 0xAB, 0x82, 0x22, 0x90, 0x27, 0x3D, 0x2A, + 0xE8, 0x7C, 0x90, 0xEF, 0xBC, 0x4F, 0xFD, 0xE2, 0x0A, 0x24, 0xA7, 0xDE, + 0x65, 0x24, 0xA4, 0x5D, 0xEA, 0xC0, 0x76, 0x30, 0xD3, 0x77, 0x50, 0xF8, + 0x0D, 0x04, 0x9B, 0x94, 0x36, 0x01, 0x73, 0xCA, 0x06, 0x58, 0xA6, 0xD3, + 0x3B, 0xDC, 0xFA, 0x04, 0x46, 0x13, 0x55, 0x8A, 0xC9, 0x44, 0x47, 0xB8, + 0x51, 0x39, 0x1A, 0x2E, 0xE8, 0x34, 0xE2, 0x79, 0xCB, 0x59, 0x4A, 0x0A, + 0x7F, 0xBC, 0xA6, 0xEF, 0x1F, 0x03, 0x67, 0x6A, 0x59, 0x2B, 0x25, 0x62, + 0x93, 0xD9, 0x53, 0x19, 0x66, 0x3C, 0x27, 0x62, 0x29, 0x86, 0x4D, 0xA4, + 0x6B, 0xEE, 0xFF, 0xD4, 0x4E, 0xBA, 0xD5, 0xB4, 0xE2, 0x8E, 0x48, 0x5A, + 0x00, 0x19, 0x09, 0xF1, 0x05, 0xD9, 0xCE, 0x91, 0xB1, 0xF7, 0xEB, 0xE9, + 0x39, 0x4F, 0xF6, 0x6F, 0x04, 0x43, 0x9A, 0x55, 0xF5, 0x3E, 0x05, 0x14, + 0xBD, 0xBF, 0xB3, 0x59, 0xB4, 0xD8, 0x8E, 0x33, 0x84, 0xA3, 0x90, 0x52, + 0xAA, 0xB3, 0x02, 0x95, 0x60, 0xF9, 0x0C, 0x4C, 0x68, 0xF9, 0xEE, 0xD5, + 0x17, 0x0D, 0xF8, 0x71, 0x57, 0xB5, 0x25, 0xE4, 0x29, 0xEE, 0x65, 0x5D, + 0xAF, 0xD1, 0xEE, 0x3C, 0x17, 0x0B, 0x5A, 0x43, 0xC5, 0xA5, 0x86, 0xEA, + 0x24, 0x9E, 0xE2, 0x05, 0x07, 0xDC, 0x34, 0x42, 0x12, 0x91, 0xD6, 0x39, + 0x74, 0xAE, 0x4C, 0x41, 0x82, 0xDB, 0xF2, 0xA6, 0x48, 0xD1, 0xB3, 0x9B, + 0xF3, 0x33, 0xAA, 0xF3, 0xA6, 0xC0, 0xC5, 0x4E, 0xF5, 0xF4, 0x9D, 0x76, + 0x63, 0xE6, 0x02, 0xC6, 0x22, 0x4B, 0xC1, 0x95, 0x3F, 0x50, 0x64, 0x2C, + 0x54, 0xE5, 0xB6, 0xF0, 0x3C, 0x29, 0xCF, 0x57 +}; + +static const unsigned char TA123_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA124_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x52, 0x31 +}; + +static const unsigned char TA124_RSA_N[] = { + 0xD0, 0x36, 0xD4, 0x1F, 0xEA, 0xDD, 0xAB, 0xE4, 0xD1, 0xB6, 0xE6, 0xFB, + 0x22, 0xC0, 0xDD, 0x13, 0x0D, 0x6A, 0x7B, 0x22, 0x13, 0x1C, 0x97, 0x3C, + 0x68, 0x63, 0x66, 0x32, 0x9C, 0x03, 0xB5, 0x8D, 0xA4, 0x81, 0x83, 0xDA, + 0x78, 0x30, 0x11, 0xCF, 0xDC, 0xB2, 0x2B, 0xBE, 0x92, 0xBF, 0x8E, 0xE4, + 0xC4, 0x13, 0xBE, 0xA4, 0x68, 0x4C, 0xDA, 0x02, 0x68, 0x16, 0x74, 0xBE, + 0xB2, 0xDD, 0x04, 0xE4, 0x6B, 0x2A, 0xDD, 0x37, 0x1F, 0x60, 0x2C, 0xDB, + 0xF5, 0xF7, 0xA1, 0x7C, 0x95, 0xB7, 0x0C, 0x70, 0x86, 0x2E, 0xF1, 0x3A, + 0xEF, 0x52, 0xF7, 0xCC, 0xD3, 0x9B, 0xF9, 0x8B, 0xBE, 0x0E, 0xDF, 0x31, + 0xB7, 0x9D, 0x68, 0x5C, 0x92, 0xA6, 0xF5, 0xE5, 0xF3, 0x0A, 0x34, 0xB5, + 0xFF, 0x7B, 0xA2, 0xE4, 0x87, 0xA1, 0xC6, 0xAF, 0x17, 0x00, 0xEF, 0x03, + 0x91, 0xED, 0xA9, 0x1C, 0x4E, 0x71, 0x3D, 0xD2, 0x8B, 0x6C, 0x89, 0xF4, + 0x78, 0x86, 0xE6, 0x6A, 0x49, 0xA0, 0xCE, 0xB5, 0xD2, 0xB0, 0xAB, 0x9B, + 0xF6, 0xF4, 0xD4, 0x2E, 0xE3, 0x72, 0xF9, 0x36, 0xC6, 0xEB, 0x15, 0xB7, + 0x25, 0x8C, 0x3A, 0xFC, 0x25, 0x0D, 0xB3, 0x22, 0x73, 0x21, 0x74, 0xC8, + 0x4A, 0x96, 0x61, 0x92, 0xF5, 0x2F, 0x0B, 0x18, 0xA5, 0xF4, 0xAD, 0xE2, + 0xEE, 0x41, 0xBD, 0x01, 0x79, 0xFA, 0x96, 0x8C, 0x8D, 0x17, 0x02, 0x30, + 0xB4, 0xF9, 0xAF, 0x78, 0x1A, 0x8C, 0xB4, 0x36, 0x10, 0x10, 0x07, 0x05, + 0x70, 0xD0, 0xF4, 0x31, 0x90, 0x8A, 0x51, 0xC5, 0x86, 0x26, 0x79, 0xB2, + 0x11, 0x88, 0x5E, 0xC5, 0xF0, 0x0A, 0x54, 0xCD, 0x49, 0xA6, 0xBF, 0x02, + 0x9C, 0xD2, 0x44, 0xA7, 0xED, 0xE3, 0x78, 0xEF, 0x46, 0x5E, 0x6D, 0x71, + 0xD1, 0x79, 0x70, 0x1C, 0x46, 0x5F, 0x51, 0xE9, 0xC9, 0x37, 0xDC, 0x5F, + 0x7E, 0x69, 0x7B, 0x41, 0xDF, 0x34, 0x45, 0xE0, 0x3B, 0x84, 0xF4, 0xA1, + 0x8A, 0x0A, 0x36, 0x9E, 0x37, 0xCC, 0x62, 0x52, 0xE1, 0x89, 0x0D, 0x28, + 0xF9, 0x7A, 0x23, 0xB1, 0x0D, 0x3D, 0x3D, 0x9A, 0xFD, 0x9D, 0x81, 0xEF, + 0x2C, 0x90, 0xC0, 0x7B, 0x44, 0x4E, 0xBB, 0x49, 0xE0, 0x0E, 0x4A, 0x56, + 0x92, 0xBC, 0xCB, 0xB5, 0xDD, 0x79, 0x17, 0x89, 0x91, 0xDE, 0x61, 0x89, + 0x74, 0x92, 0xA8, 0xE3, 0x32, 0x85, 0xBE, 0x4E, 0x85, 0xA4, 0x4B, 0x59, + 0xCB, 0x2B, 0xC5, 0x78, 0x8E, 0x71, 0x54, 0xD0, 0x02, 0x37, 0x99, 0x8C, + 0xE5, 0x49, 0xEA, 0xE0, 0x54, 0x72, 0xA4, 0x11, 0x06, 0x2F, 0x0B, 0x8C, + 0xC1, 0x5B, 0xBE, 0xB5, 0xA1, 0xB0, 0x53, 0x6E, 0x9C, 0xB8, 0x60, 0x91, + 0x1F, 0x59, 0x6B, 0xF9, 0x2D, 0xF4, 0x94, 0x0A, 0x97, 0xB5, 0xEC, 0xC5, + 0x76, 0x03, 0x54, 0x1B, 0x65, 0x52, 0xBA, 0x4C, 0x92, 0x56, 0x51, 0x35, + 0xA0, 0x40, 0xD8, 0x29, 0xDB, 0xAE, 0x52, 0x76, 0x3B, 0x2D, 0x30, 0x40, + 0x9B, 0x8A, 0xD0, 0x42, 0x56, 0xB4, 0xB7, 0x88, 0x01, 0xA4, 0x87, 0x3B, + 0x53, 0x96, 0xCD, 0xA3, 0x16, 0x8F, 0xF3, 0x66, 0xAA, 0x17, 0xB1, 0xC7, + 0x60, 0xE0, 0xC1, 0x43, 0x05, 0x0C, 0xEE, 0x9B, 0x5B, 0x60, 0x6F, 0x06, + 0x5C, 0x87, 0x5B, 0x27, 0xF9, 0x40, 0x11, 0x9E, 0x9C, 0x33, 0xC1, 0xB7, + 0xE5, 0x35, 0x57, 0x05, 0x7F, 0x27, 0xCE, 0x17, 0x20, 0x8C, 0x1C, 0xFC, + 0xF1, 0xFB, 0xDA, 0x31, 0x29, 0x49, 0xED, 0xF5, 0x0B, 0x84, 0xA7, 0x4F, + 0xC1, 0xF6, 0x4E, 0xC2, 0x28, 0x9C, 0xFA, 0xEE, 0xE0, 0xAF, 0x07, 0xFB, + 0x33, 0x11, 0x7A, 0x21, 0x4F, 0x0B, 0x21, 0x10, 0xB6, 0x40, 0x3A, 0xAB, + 0x22, 0x3A, 0x04, 0x9C, 0x8B, 0x9B, 0x84, 0x86, 0x72, 0x9A, 0xD2, 0xA7, + 0xA5, 0xC4, 0xB4, 0x75, 0x91, 0xA9, 0x2B, 0x23 +}; + +static const unsigned char TA124_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA125_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA125_EC_Q[] = { + 0x04, 0x29, 0x97, 0xA7, 0xC6, 0x41, 0x7F, 0xC0, 0x0D, 0x9B, 0xE8, 0x01, + 0x1B, 0x56, 0xC6, 0xF2, 0x52, 0xA5, 0xBA, 0x2D, 0xB2, 0x12, 0xE8, 0xD2, + 0x2E, 0xD7, 0xFA, 0xC9, 0xC5, 0xD8, 0xAA, 0x6D, 0x1F, 0x73, 0x81, 0x3B, + 0x3B, 0x98, 0x6B, 0x39, 0x7C, 0x33, 0xA5, 0xC5, 0x4E, 0x86, 0x8E, 0x80, + 0x17, 0x68, 0x62, 0x45, 0x57, 0x7D, 0x44, 0x58, 0x1D, 0xB3, 0x37, 0xE5, + 0x67, 0x08, 0xEB, 0x66, 0xDE +}; + +static const unsigned char TA126_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA126_RSA_N[] = { + 0x9A, 0x18, 0xCA, 0x4B, 0x94, 0x0D, 0x00, 0x2D, 0xAF, 0x03, 0x29, 0x8A, + 0xF0, 0x0F, 0x81, 0xC8, 0xAE, 0x4C, 0x19, 0x85, 0x1D, 0x08, 0x9F, 0xAB, + 0x29, 0x44, 0x85, 0xF3, 0x2F, 0x81, 0xAD, 0x32, 0x1E, 0x90, 0x46, 0xBF, + 0xA3, 0x86, 0x26, 0x1A, 0x1E, 0xFE, 0x7E, 0x1C, 0x18, 0x3A, 0x5C, 0x9C, + 0x60, 0x17, 0x2A, 0x3A, 0x74, 0x83, 0x33, 0x30, 0x7D, 0x61, 0x54, 0x11, + 0xCB, 0xED, 0xAB, 0xE0, 0xE6, 0xD2, 0xA2, 0x7E, 0xF5, 0x6B, 0x6F, 0x18, + 0xB7, 0x0A, 0x0B, 0x2D, 0xFD, 0xE9, 0x3E, 0xEF, 0x0A, 0xC6, 0xB3, 0x10, + 0xE9, 0xDC, 0xC2, 0x46, 0x17, 0xF8, 0x5D, 0xFD, 0xA4, 0xDA, 0xFF, 0x9E, + 0x49, 0x5A, 0x9C, 0xE6, 0x33, 0xE6, 0x24, 0x96, 0xF7, 0x3F, 0xBA, 0x5B, + 0x2B, 0x1C, 0x7A, 0x35, 0xC2, 0xD6, 0x67, 0xFE, 0xAB, 0x66, 0x50, 0x8B, + 0x6D, 0x28, 0x60, 0x2B, 0xEF, 0xD7, 0x60, 0xC3, 0xC7, 0x93, 0xBC, 0x8D, + 0x36, 0x91, 0xF3, 0x7F, 0xF8, 0xDB, 0x11, 0x13, 0xC4, 0x9C, 0x77, 0x76, + 0xC1, 0xAE, 0xB7, 0x02, 0x6A, 0x81, 0x7A, 0xA9, 0x45, 0x83, 0xE2, 0x05, + 0xE6, 0xB9, 0x56, 0xC1, 0x94, 0x37, 0x8F, 0x48, 0x71, 0x63, 0x22, 0xEC, + 0x17, 0x65, 0x07, 0x95, 0x8A, 0x4B, 0xDF, 0x8F, 0xC6, 0x5A, 0x0A, 0xE5, + 0xB0, 0xE3, 0x5F, 0x5E, 0x6B, 0x11, 0xAB, 0x0C, 0xF9, 0x85, 0xEB, 0x44, + 0xE9, 0xF8, 0x04, 0x73, 0xF2, 0xE9, 0xFE, 0x5C, 0x98, 0x8C, 0xF5, 0x73, + 0xAF, 0x6B, 0xB4, 0x7E, 0xCD, 0xD4, 0x5C, 0x02, 0x2B, 0x4C, 0x39, 0xE1, + 0xB2, 0x95, 0x95, 0x2D, 0x42, 0x87, 0xD7, 0xD5, 0xB3, 0x90, 0x43, 0xB7, + 0x6C, 0x13, 0xF1, 0xDE, 0xDD, 0xF6, 0xC4, 0xF8, 0x89, 0x3F, 0xD1, 0x75, + 0xF5, 0x92, 0xC3, 0x91, 0xD5, 0x8A, 0x88, 0xD0, 0x90, 0xEC, 0xDC, 0x6D, + 0xDE, 0x89, 0xC2, 0x65, 0x71, 0x96, 0x8B, 0x0D, 0x03, 0xFD, 0x9C, 0xBF, + 0x5B, 0x16, 0xAC, 0x92, 0xDB, 0xEA, 0xFE, 0x79, 0x7C, 0xAD, 0xEB, 0xAF, + 0xF7, 0x16, 0xCB, 0xDB, 0xCD, 0x25, 0x2B, 0xE5, 0x1F, 0xFB, 0x9A, 0x9F, + 0xE2, 0x51, 0xCC, 0x3A, 0x53, 0x0C, 0x48, 0xE6, 0x0E, 0xBD, 0xC9, 0xB4, + 0x76, 0x06, 0x52, 0xE6, 0x11, 0x13, 0x85, 0x72, 0x63, 0x03, 0x04, 0xE0, + 0x04, 0x36, 0x2B, 0x20, 0x19, 0x02, 0xE8, 0x74, 0xA7, 0x1F, 0xB6, 0xC9, + 0x56, 0x66, 0xF0, 0x75, 0x25, 0xDC, 0x67, 0xC1, 0x0E, 0x61, 0x60, 0x88, + 0xB3, 0x3E, 0xD1, 0xA8, 0xFC, 0xA3, 0xDA, 0x1D, 0xB0, 0xD1, 0xB1, 0x23, + 0x54, 0xDF, 0x44, 0x76, 0x6D, 0xED, 0x41, 0xD8, 0xC1, 0xB2, 0x22, 0xB6, + 0x53, 0x1C, 0xDF, 0x35, 0x1D, 0xDC, 0xA1, 0x77, 0x2A, 0x31, 0xE4, 0x2D, + 0xF5, 0xE5, 0xE5, 0xDB, 0xC8, 0xE0, 0xFF, 0xE5, 0x80, 0xD7, 0x0B, 0x63, + 0xA0, 0xFF, 0x33, 0xA1, 0x0F, 0xBA, 0x2C, 0x15, 0x15, 0xEA, 0x97, 0xB3, + 0xD2, 0xA2, 0xB5, 0xBE, 0xF2, 0x8C, 0x96, 0x1E, 0x1A, 0x8F, 0x1D, 0x6C, + 0xA4, 0x61, 0x37, 0xB9, 0x86, 0x73, 0x33, 0xD7, 0x97, 0x96, 0x9E, 0x23, + 0x7D, 0x82, 0xA4, 0x4C, 0x81, 0xE2, 0xA1, 0xD1, 0xBA, 0x67, 0x5F, 0x95, + 0x07, 0xA3, 0x27, 0x11, 0xEE, 0x16, 0x10, 0x7B, 0xBC, 0x45, 0x4A, 0x4C, + 0xB2, 0x04, 0xD2, 0xAB, 0xEF, 0xD5, 0xFD, 0x0C, 0x51, 0xCE, 0x50, 0x6A, + 0x08, 0x31, 0xF9, 0x91, 0xDA, 0x0C, 0x8F, 0x64, 0x5C, 0x03, 0xC3, 0x3A, + 0x8B, 0x20, 0x3F, 0x6E, 0x8D, 0x67, 0x3D, 0x3A, 0xD6, 0xFE, 0x7D, 0x5B, + 0x88, 0xC9, 0x5E, 0xFB, 0xCC, 0x61, 0xDC, 0x8B, 0x33, 0x77, 0xD3, 0x44, + 0x32, 0x35, 0x09, 0x62, 0x04, 0x92, 0x16, 0x10, 0xD8, 0x9E, 0x27, 0x47, + 0xFB, 0x3B, 0x21, 0xE3, 0xF8, 0xEB, 0x1D, 0x5B +}; + +static const unsigned char TA126_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA127_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x32 +}; + +static const unsigned char TA127_EC_Q[] = { + 0x04, 0x9D, 0xCB, 0x80, 0x91, 0x8D, 0x53, 0x67, 0xB5, 0xB9, 0x50, 0xB1, + 0x03, 0xF8, 0xE5, 0x49, 0x1F, 0x41, 0x22, 0x09, 0xB0, 0x51, 0x52, 0x58, + 0xD6, 0x2B, 0x34, 0x8F, 0xC5, 0x12, 0x46, 0x14, 0xC5, 0x8B, 0x2F, 0x2C, + 0x84, 0xFF, 0x2C, 0x6E, 0xA8, 0xD5, 0xF1, 0x09, 0xE3, 0x03, 0x21, 0x14, + 0xC4, 0x43, 0x3D, 0x7C, 0xC1, 0x2C, 0xC4, 0x4B, 0x6A, 0x4A, 0xCD, 0xE9, + 0x87, 0xE0, 0x7D, 0xF6, 0x22, 0xBE, 0xFA, 0x4A, 0x51, 0xB8, 0x30, 0x8A, + 0xFD, 0xE1, 0xDE, 0x18, 0x12, 0x0A, 0xF6, 0x47, 0xB7, 0xE7, 0x17, 0xBF, + 0x27, 0x8A, 0xD4, 0x41, 0x4C, 0x96, 0x3C, 0x60, 0x96, 0xC1, 0xFD, 0x15, + 0x1C +}; + +static const unsigned char TA128_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA128_EC_Q[] = { + 0x04, 0x19, 0xE7, 0xBC, 0xAC, 0x44, 0x65, 0xED, 0xCD, 0xB8, 0x3F, 0x58, + 0xFB, 0x8D, 0xB1, 0x57, 0xA9, 0x44, 0x2D, 0x05, 0x15, 0xF2, 0xEF, 0x0B, + 0xFF, 0x10, 0x74, 0x9F, 0xB5, 0x62, 0x52, 0x5F, 0x66, 0x7E, 0x1F, 0xE5, + 0xDC, 0x1B, 0x45, 0x79, 0x0B, 0xCC, 0xC6, 0x53, 0x0A, 0x9D, 0x8D, 0x5D, + 0x02, 0xD9, 0xA9, 0x59, 0xDE, 0x02, 0x5A, 0xF6, 0x95, 0x2A, 0x0E, 0x8D, + 0x38, 0x4A, 0x8A, 0x49, 0xC6, 0xBC, 0xC6, 0x03, 0x38, 0x07, 0x5F, 0x55, + 0xDA, 0x7E, 0x09, 0x6E, 0xE2, 0x7F, 0x5E, 0xD0, 0x45, 0x20, 0x0F, 0x59, + 0x76, 0x10, 0xD6, 0xA0, 0x24, 0xF0, 0x2D, 0xDE, 0x36, 0xF2, 0x6C, 0x29, + 0x39 +}; + +static const unsigned char TA129_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x33 +}; + +static const unsigned char TA129_RSA_N[] = { + 0xED, 0x35, 0xA1, 0x81, 0x80, 0xF3, 0xCB, 0x4A, 0x69, 0x5B, 0xC2, 0xFB, + 0x51, 0x83, 0xAE, 0x26, 0xFD, 0xE1, 0x6E, 0xF3, 0x81, 0x12, 0x7D, 0x71, + 0x40, 0xFF, 0x87, 0x75, 0x42, 0x29, 0x21, 0xED, 0x81, 0x52, 0x2C, 0xDF, + 0x12, 0xC1, 0x19, 0x84, 0x89, 0xC1, 0xBD, 0xC5, 0x28, 0xD5, 0xD5, 0x4B, + 0x6C, 0x44, 0xD6, 0x4C, 0xDB, 0x07, 0x96, 0x4A, 0x55, 0x7A, 0xCA, 0x36, + 0x82, 0x04, 0x36, 0xA8, 0xA5, 0xFC, 0x27, 0xF6, 0x49, 0xF1, 0xD5, 0x72, + 0x9E, 0x91, 0xF9, 0x23, 0xD6, 0x70, 0x7B, 0xBB, 0xF5, 0x9B, 0xC1, 0xEC, + 0x93, 0xCF, 0x19, 0xEA, 0x65, 0x7E, 0x88, 0x70, 0xA0, 0x73, 0xFC, 0xF6, + 0xFF, 0xB5, 0x56, 0x62, 0xE1, 0x73, 0x6A, 0x34, 0x98, 0x3E, 0x82, 0xB8, + 0xAC, 0x95, 0x53, 0xF4, 0x01, 0xA0, 0x27, 0x07, 0x72, 0xA3, 0x00, 0x53, + 0xA0, 0xE4, 0xB2, 0xAB, 0x83, 0x38, 0x57, 0x33, 0x25, 0x94, 0x9F, 0xBE, + 0x48, 0x1D, 0x98, 0xE1, 0xA3, 0xBA, 0x9E, 0x5C, 0xCD, 0x04, 0x71, 0x51, + 0x7D, 0x75, 0x78, 0xAB, 0xF3, 0x59, 0xAA, 0xC4, 0xE0, 0x60, 0xBE, 0x8F, + 0x83, 0x52, 0xB8, 0x75, 0x1A, 0x41, 0x35, 0xED, 0xBC, 0xF3, 0x3A, 0x63, + 0xE9, 0xA9, 0x14, 0x45, 0xD7, 0xE6, 0x52, 0xD1, 0x6E, 0xD2, 0xDE, 0xBC, + 0xE3, 0xF5, 0x0B, 0x3B, 0xE6, 0xE0, 0xC4, 0xBD, 0x43, 0x64, 0x13, 0xA6, + 0xCE, 0xF4, 0x98, 0x37, 0x6C, 0x8A, 0x95, 0xA8, 0x97, 0xC8, 0x47, 0x0F, + 0xF0, 0x5E, 0x10, 0x8B, 0xE7, 0x1D, 0x1C, 0xFE, 0xB1, 0x3B, 0xA0, 0x05, + 0x33, 0x68, 0x05, 0x41, 0x82, 0xC1, 0x03, 0x2B, 0x01, 0xC8, 0xE7, 0x8F, + 0x4D, 0xAB, 0xE8, 0xB5, 0xF6, 0xCD, 0x6B, 0x44, 0xB5, 0xE7, 0xDD, 0x8B, + 0xEC, 0xEA, 0x25, 0xB4, 0x00, 0x22, 0x57, 0x4D, 0xB0, 0xB1, 0xB2, 0x31, + 0xC1, 0x16, 0xCE, 0xFF, 0xFD, 0x14, 0x84, 0xB7, 0x47, 0xFA, 0xB2, 0xF1, + 0x70, 0xDE, 0xDB, 0x8B, 0x6C, 0x36, 0x58, 0xA4, 0x7C, 0xB3, 0x11, 0xD1, + 0xC3, 0x77, 0x7F, 0x5F, 0xB6, 0x25, 0xE0, 0x0D, 0xC5, 0xD2, 0xB3, 0xF9, + 0xB8, 0xB8, 0x77, 0xDB, 0x37, 0x71, 0x71, 0x47, 0xE3, 0x60, 0x18, 0x4F, + 0x24, 0xB6, 0x75, 0x37, 0x78, 0xB9, 0xA3, 0x62, 0xAF, 0xBD, 0xC9, 0x72, + 0x8E, 0x2F, 0xCC, 0xBB, 0xAE, 0xDB, 0xE4, 0x15, 0x52, 0x19, 0x07, 0x33, + 0xFB, 0x6A, 0xB7, 0x2D, 0x4B, 0x90, 0x28, 0x82, 0x73, 0xFE, 0x18, 0x8B, + 0x35, 0x8D, 0xDB, 0xA7, 0x04, 0x6A, 0xBE, 0xEA, 0xC1, 0x4D, 0x36, 0x3B, + 0x16, 0x36, 0x91, 0x32, 0xEF, 0xB6, 0x40, 0x89, 0x91, 0x43, 0xE0, 0xF2, + 0xA2, 0xAB, 0x04, 0x2E, 0xE6, 0xF2, 0x4C, 0x0E, 0x16, 0x34, 0x20, 0xAC, + 0x87, 0xC1, 0x2D, 0x7E, 0xC9, 0x66, 0x47, 0x17, 0x14, 0x11, 0xA4, 0xF3, + 0xF7, 0xA1, 0x24, 0x89, 0xAB, 0xD8, 0x1A, 0xC8, 0xA1, 0x5C, 0xB1, 0xA3, + 0xF7, 0x8C, 0x6D, 0xC8, 0x01, 0xC9, 0x4F, 0xC9, 0xEC, 0xC4, 0xFC, 0xAC, + 0x51, 0x33, 0xD1, 0xC8, 0x83, 0xD1, 0xC9, 0x9F, 0x1D, 0xD4, 0x47, 0x34, + 0x29, 0x3E, 0xCB, 0xB0, 0x0E, 0xFA, 0x83, 0x0B, 0x28, 0x58, 0xE5, 0x29, + 0xDC, 0x3F, 0x7C, 0xA8, 0x9F, 0xC9, 0xB6, 0x0A, 0xBB, 0xA6, 0xE8, 0x46, + 0x16, 0x0F, 0x96, 0xE5, 0x7B, 0xE4, 0x6A, 0x7A, 0x48, 0x6D, 0x76, 0x98, + 0x05, 0xA5, 0xDC, 0x6D, 0x1E, 0x42, 0x1E, 0x42, 0xDA, 0x1A, 0xE0, 0x52, + 0xF7, 0xB5, 0x83, 0xC0, 0x1A, 0x7B, 0x78, 0x35, 0x2C, 0x38, 0xF5, 0x1F, + 0xFD, 0x49, 0xA3, 0x2E, 0xD2, 0x59, 0x63, 0xBF, 0x80, 0xB0, 0x8C, 0x93, + 0x73, 0xCB, 0x35, 0xA6, 0x99, 0x95, 0x22, 0x61, 0x65, 0x03, 0x60, 0xFB, + 0x2F, 0x93, 0x4B, 0xFA, 0x9A, 0x9C, 0x80, 0x3B +}; + +static const unsigned char TA129_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA130_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x65, 0x2D, 0x53, 0x7A, 0x69, + 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x32, 0x30, 0x30, 0x39, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x65, 0x2D, 0x73, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x2E, 0x68, + 0x75 +}; + +static const unsigned char TA130_RSA_N[] = { + 0xE9, 0xF8, 0x8F, 0xF3, 0x63, 0xAD, 0xDA, 0x86, 0xD8, 0xA7, 0xE0, 0x42, + 0xFB, 0xCF, 0x91, 0xDE, 0xA6, 0x26, 0xF8, 0x99, 0xA5, 0x63, 0x70, 0xAD, + 0x9B, 0xAE, 0xCA, 0x33, 0x40, 0x7D, 0x6D, 0x96, 0x6E, 0xA1, 0x0E, 0x44, + 0xEE, 0xE1, 0x13, 0x9D, 0x94, 0x42, 0x52, 0x9A, 0xBD, 0x75, 0x85, 0x74, + 0x2C, 0xA8, 0x0E, 0x1D, 0x93, 0xB6, 0x18, 0xB7, 0x8C, 0x2C, 0xA8, 0xCF, + 0xFB, 0x5C, 0x71, 0xB9, 0xDA, 0xEC, 0xFE, 0xE8, 0x7E, 0x8F, 0xE4, 0x2F, + 0x1D, 0xB2, 0xA8, 0x75, 0x87, 0xD8, 0xB7, 0xA1, 0xE5, 0x3B, 0xCF, 0x99, + 0x4A, 0x46, 0xD0, 0x83, 0x19, 0x7D, 0xC0, 0xA1, 0x12, 0x1C, 0x95, 0x6D, + 0x4A, 0xF4, 0xD8, 0xC7, 0xA5, 0x4D, 0x33, 0x2E, 0x85, 0x39, 0x40, 0x75, + 0x7E, 0x14, 0x7C, 0x80, 0x12, 0x98, 0x50, 0xC7, 0x41, 0x67, 0xB8, 0xA0, + 0x80, 0x61, 0x54, 0xA6, 0x6C, 0x4E, 0x1F, 0xE0, 0x9D, 0x0E, 0x07, 0xE9, + 0xC9, 0xBA, 0x33, 0xE7, 0xFE, 0xC0, 0x55, 0x28, 0x2C, 0x02, 0x80, 0xA7, + 0x19, 0xF5, 0x9E, 0xDC, 0x55, 0x53, 0x03, 0x97, 0x7B, 0x07, 0x48, 0xFF, + 0x99, 0xFB, 0x37, 0x8A, 0x24, 0xC4, 0x59, 0xCC, 0x50, 0x10, 0x63, 0x8E, + 0xAA, 0xA9, 0x1A, 0xB0, 0x84, 0x1A, 0x86, 0xF9, 0x5F, 0xBB, 0xB1, 0x50, + 0x6E, 0xA4, 0xD1, 0x0A, 0xCC, 0xD5, 0x71, 0x7E, 0x1F, 0xA7, 0x1B, 0x7C, + 0xF5, 0x53, 0x6E, 0x22, 0x5F, 0xCB, 0x2B, 0xE6, 0xD4, 0x7C, 0x5D, 0xAE, + 0xD6, 0xC2, 0xC6, 0x4C, 0xE5, 0x05, 0x01, 0xD9, 0xED, 0x57, 0xFC, 0xC1, + 0x23, 0x79, 0xFC, 0xFA, 0xC8, 0x24, 0x83, 0x95, 0xF3, 0xB5, 0x6A, 0x51, + 0x01, 0xD0, 0x77, 0xD6, 0xE9, 0x12, 0xA1, 0xF9, 0x1A, 0x83, 0xFB, 0x82, + 0x1B, 0xB9, 0xB0, 0x97, 0xF4, 0x76, 0x06, 0x33, 0x43, 0x49, 0xA0, 0xFF, + 0x0B, 0xB5, 0xFA, 0xB5 +}; + +static const unsigned char TA130_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA131_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, + 0x6E, 0x63, 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA131_RSA_N[] = { + 0xC6, 0xCC, 0xE5, 0x73, 0xE6, 0xFB, 0xD4, 0xBB, 0xE5, 0x2D, 0x2D, 0x32, + 0xA6, 0xDF, 0xE5, 0x81, 0x3F, 0xC9, 0xCD, 0x25, 0x49, 0xB6, 0x71, 0x2A, + 0xC3, 0xD5, 0x94, 0x34, 0x67, 0xA2, 0x0A, 0x1C, 0xB0, 0x5F, 0x69, 0xA6, + 0x40, 0xB1, 0xC4, 0xB7, 0xB2, 0x8F, 0xD0, 0x98, 0xA4, 0xA9, 0x41, 0x59, + 0x3A, 0xD3, 0xDC, 0x94, 0xD6, 0x3C, 0xDB, 0x74, 0x38, 0xA4, 0x4A, 0xCC, + 0x4D, 0x25, 0x82, 0xF7, 0x4A, 0xA5, 0x53, 0x12, 0x38, 0xEE, 0xF3, 0x49, + 0x6D, 0x71, 0x91, 0x7E, 0x63, 0xB6, 0xAB, 0xA6, 0x5F, 0xC3, 0xA4, 0x84, + 0xF8, 0x4F, 0x62, 0x51, 0xBE, 0xF8, 0xC5, 0xEC, 0xDB, 0x38, 0x92, 0xE3, + 0x06, 0xE5, 0x08, 0x91, 0x0C, 0xC4, 0x28, 0x41, 0x55, 0xFB, 0xCB, 0x5A, + 0x89, 0x15, 0x7E, 0x71, 0xE8, 0x35, 0xBF, 0x4D, 0x72, 0x09, 0x3D, 0xBE, + 0x3A, 0x38, 0x50, 0x5B, 0x77, 0x31, 0x1B, 0x8D, 0xB3, 0xC7, 0x24, 0x45, + 0x9A, 0xA7, 0xAC, 0x6D, 0x00, 0x14, 0x5A, 0x04, 0xB7, 0xBA, 0x13, 0xEB, + 0x51, 0x0A, 0x98, 0x41, 0x41, 0x22, 0x4E, 0x65, 0x61, 0x87, 0x81, 0x41, + 0x50, 0xA6, 0x79, 0x5C, 0x89, 0xDE, 0x19, 0x4A, 0x57, 0xD5, 0x2E, 0xE6, + 0x5D, 0x1C, 0x53, 0x2C, 0x7E, 0x98, 0xCD, 0x1A, 0x06, 0x16, 0xA4, 0x68, + 0x73, 0xD0, 0x34, 0x04, 0x13, 0x5C, 0xA1, 0x71, 0xD3, 0x5A, 0x7C, 0x55, + 0xDB, 0x5E, 0x64, 0xE1, 0x37, 0x87, 0x30, 0x56, 0x04, 0xE5, 0x11, 0xB4, + 0x29, 0x80, 0x12, 0xF1, 0x79, 0x39, 0x88, 0xA2, 0x02, 0x11, 0x7C, 0x27, + 0x66, 0xB7, 0x88, 0xB7, 0x78, 0xF2, 0xCA, 0x0A, 0xA8, 0x38, 0xAB, 0x0A, + 0x64, 0xC2, 0xBF, 0x66, 0x5D, 0x95, 0x84, 0xC1, 0xA1, 0x25, 0x1E, 0x87, + 0x5D, 0x1A, 0x50, 0x0B, 0x20, 0x12, 0xCC, 0x41, 0xBB, 0x6E, 0x0B, 0x51, + 0x38, 0xB8, 0x4B, 0xCB +}; + +static const unsigned char TA131_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA132_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA132_EC_Q[] = { + 0x04, 0x78, 0x30, 0x81, 0xE8, 0x63, 0x1E, 0xE5, 0xEB, 0x71, 0x51, 0x0F, + 0xF7, 0x07, 0x07, 0xCA, 0x39, 0x99, 0x7C, 0x4E, 0xD5, 0x0F, 0xCC, 0x30, + 0x30, 0x0B, 0x8F, 0x66, 0x93, 0x3E, 0xCF, 0xBD, 0xC5, 0x86, 0xBD, 0xF9, + 0xB1, 0xB7, 0xB4, 0x3E, 0xB4, 0x07, 0xC8, 0xF3, 0x96, 0x31, 0xF3, 0xED, + 0xA4, 0x4F, 0xF8, 0xA3, 0x4E, 0x8D, 0x29, 0x15, 0x58, 0xB8, 0xD5, 0x6F, + 0x7F, 0xEE, 0x6C, 0x22, 0xB5, 0xB0, 0xAF, 0x48, 0x45, 0x0A, 0xBD, 0xA8, + 0x49, 0x94, 0xBF, 0x84, 0x43, 0xB0, 0xDB, 0x84, 0x4A, 0x03, 0x23, 0x19, + 0x67, 0x6A, 0x6F, 0xC1, 0x6E, 0xBC, 0x06, 0x39, 0x37, 0xD1, 0x88, 0x22, + 0xF7 +}; + +static const unsigned char TA133_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA133_RSA_N[] = { + 0xD7, 0xC7, 0x5E, 0xF7, 0xC1, 0x07, 0xD4, 0x77, 0xFB, 0x43, 0x21, 0xF4, + 0xF4, 0xF5, 0x69, 0xE4, 0xEE, 0x32, 0x01, 0xDB, 0xA3, 0x86, 0x1F, 0xE4, + 0x59, 0x0D, 0xBA, 0xE7, 0x75, 0x83, 0x52, 0xEB, 0xEA, 0x1C, 0x61, 0x15, + 0x48, 0xBB, 0x1D, 0x07, 0xCA, 0x8C, 0xAE, 0xB0, 0xDC, 0x96, 0x9D, 0xEA, + 0xC3, 0x60, 0x92, 0x86, 0x82, 0x28, 0x73, 0x9C, 0x56, 0x06, 0xFF, 0x4B, + 0x64, 0xF0, 0x0C, 0x2A, 0x37, 0x49, 0xB5, 0xE5, 0xCF, 0x0C, 0x7C, 0xEE, + 0xF1, 0x4A, 0xBB, 0x73, 0x30, 0x65, 0xF3, 0xD5, 0x2F, 0x83, 0xB6, 0x7E, + 0xE3, 0xE7, 0xF5, 0x9E, 0xAB, 0x60, 0xF9, 0xD3, 0xF1, 0x9D, 0x92, 0x74, + 0x8A, 0xE4, 0x1C, 0x96, 0xAC, 0x5B, 0x80, 0xE9, 0xB5, 0xF4, 0x31, 0x87, + 0xA3, 0x51, 0xFC, 0xC7, 0x7E, 0xA1, 0x6F, 0x8E, 0x53, 0x77, 0xD4, 0x97, + 0xC1, 0x55, 0x33, 0x92, 0x3E, 0x18, 0x2F, 0x75, 0xD4, 0xAD, 0x86, 0x49, + 0xCB, 0x95, 0xAF, 0x54, 0x06, 0x6C, 0xD8, 0x06, 0x13, 0x8D, 0x5B, 0xFF, + 0xE1, 0x26, 0x19, 0x59, 0xC0, 0x24, 0xBA, 0x81, 0x71, 0x79, 0x90, 0x44, + 0x50, 0x68, 0x24, 0x94, 0x5F, 0xB8, 0xB3, 0x11, 0xF1, 0x29, 0x41, 0x61, + 0xA3, 0x41, 0xCB, 0x23, 0x36, 0xD5, 0xC1, 0xF1, 0x32, 0x50, 0x10, 0x4E, + 0x7F, 0xF4, 0x86, 0x93, 0xEC, 0x84, 0xD3, 0x8E, 0xBC, 0x4B, 0xBF, 0x5C, + 0x01, 0x4E, 0x07, 0x3D, 0xDC, 0x14, 0x8A, 0x94, 0x0A, 0xA4, 0xEA, 0x73, + 0xFB, 0x0B, 0x51, 0xE8, 0x13, 0x07, 0x18, 0xFA, 0x0E, 0xF1, 0x2B, 0xD1, + 0x54, 0x15, 0x7D, 0x3C, 0xE1, 0xF7, 0xB4, 0x19, 0x42, 0x67, 0x62, 0x5E, + 0x77, 0xE0, 0xA2, 0x55, 0xEC, 0xB6, 0xD9, 0x69, 0x17, 0xD5, 0x3A, 0xAF, + 0x44, 0xED, 0x4A, 0xC5, 0x9E, 0xE4, 0x7A, 0x27, 0x7C, 0xE5, 0x75, 0xD7, + 0xAA, 0xCB, 0x25, 0xE7, 0xDF, 0x6B, 0x0A, 0xDB, 0x0F, 0x4D, 0x93, 0x4E, + 0xA8, 0xA0, 0xCD, 0x7B, 0x2E, 0xF2, 0x59, 0x01, 0x6A, 0xB7, 0x0D, 0xB8, + 0x07, 0x81, 0x7E, 0x8B, 0x38, 0x1B, 0x38, 0xE6, 0x0A, 0x57, 0x99, 0x3D, + 0xEE, 0x21, 0xE8, 0xA3, 0xF5, 0x0C, 0x16, 0xDD, 0x8B, 0xEC, 0x34, 0x8E, + 0x9C, 0x2A, 0x1C, 0x00, 0x15, 0x17, 0x8D, 0x68, 0x83, 0xD2, 0x70, 0x9F, + 0x18, 0x08, 0xCD, 0x11, 0x68, 0xD5, 0xC9, 0x6B, 0x52, 0xCD, 0xC4, 0x46, + 0x8F, 0xDC, 0xB5, 0xF3, 0xD8, 0x57, 0x73, 0x1E, 0xE9, 0x94, 0x39, 0x04, + 0xBF, 0xD3, 0xDE, 0x38, 0xDE, 0xB4, 0x53, 0xEC, 0x69, 0x1C, 0xA2, 0x7E, + 0xC4, 0x8F, 0xE4, 0x1B, 0x70, 0xAD, 0xF2, 0xA2, 0xF9, 0xFB, 0xF7, 0x16, + 0x64, 0x66, 0x69, 0x9F, 0x49, 0x51, 0xA2, 0xE2, 0x15, 0x18, 0x67, 0x06, + 0x4A, 0x7F, 0xD5, 0x6C, 0xB5, 0x4D, 0xB3, 0x33, 0xE0, 0x61, 0xEB, 0x5D, + 0xBE, 0xE9, 0x98, 0x0F, 0x32, 0xD7, 0x1D, 0x4B, 0x3C, 0x2E, 0x5A, 0x01, + 0x52, 0x91, 0x09, 0xF2, 0xDF, 0xEA, 0x8D, 0xD8, 0x06, 0x40, 0x63, 0xAA, + 0x11, 0xE4, 0xFE, 0xC3, 0x37, 0x9E, 0x14, 0x52, 0x3F, 0xF4, 0xE2, 0xCC, + 0xF2, 0x61, 0x93, 0xD1, 0xFD, 0x67, 0x6B, 0xD7, 0x52, 0xAE, 0xBF, 0x68, + 0xAB, 0x40, 0x43, 0xA0, 0x57, 0x35, 0x53, 0x78, 0xF0, 0x53, 0xF8, 0x61, + 0x42, 0x07, 0x64, 0xC6, 0xD7, 0x6F, 0x9B, 0x4C, 0x38, 0x0D, 0x63, 0xAC, + 0x62, 0xAF, 0x36, 0x8B, 0xA2, 0x73, 0x0A, 0x0D, 0xF5, 0x21, 0xBD, 0x74, + 0xAA, 0x4D, 0xEA, 0x72, 0x03, 0x49, 0xDB, 0xC7, 0x5F, 0x1D, 0x62, 0x63, + 0xC7, 0xFD, 0xDD, 0x91, 0xEC, 0x33, 0xEE, 0xF5, 0x6D, 0xB4, 0x6E, 0x30, + 0x68, 0xDE, 0xC8, 0xD6, 0x26, 0xB0, 0x75, 0x5E, 0x7B, 0xB4, 0x07, 0x20, + 0x98, 0xA1, 0x76, 0x32, 0xB8, 0x4D, 0x6C, 0x4F +}; + +static const unsigned char TA133_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA134_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA134_RSA_N[] = { + 0xB0, 0x48, 0x65, 0xA3, 0x0D, 0x1D, 0x42, 0xE3, 0x91, 0x6D, 0x9D, 0x84, + 0xA4, 0x61, 0x96, 0x12, 0xC2, 0xED, 0xC3, 0xDA, 0x23, 0x34, 0x19, 0x76, + 0xF6, 0xEA, 0xFD, 0x55, 0x5A, 0xF6, 0x55, 0x01, 0x53, 0x0F, 0xF2, 0xCC, + 0x8C, 0x97, 0x4F, 0xB9, 0x50, 0xCB, 0xB3, 0x01, 0x44, 0x56, 0x96, 0xFD, + 0x9B, 0x28, 0xEC, 0x7B, 0x74, 0x0B, 0xE7, 0x42, 0x6B, 0x55, 0xCE, 0xC9, + 0x61, 0xB2, 0xE8, 0xAD, 0x40, 0x3C, 0xBA, 0xB9, 0x41, 0x0A, 0x05, 0x4F, + 0x1B, 0x26, 0x85, 0x8F, 0x43, 0xB5, 0x40, 0xB5, 0x85, 0xD1, 0xD4, 0x71, + 0xDC, 0x83, 0x41, 0xF3, 0xF6, 0x45, 0xC7, 0x80, 0xA2, 0x84, 0x50, 0x97, + 0x46, 0xCE, 0xA0, 0x0C, 0xC4, 0x60, 0x56, 0x04, 0x1D, 0x07, 0x5B, 0x46, + 0xA5, 0x0E, 0xB2, 0x4B, 0xA4, 0x0E, 0xA5, 0x7C, 0xEE, 0xF8, 0xD4, 0x62, + 0x03, 0xB9, 0x93, 0x6A, 0x8A, 0x14, 0xB8, 0x70, 0xF8, 0x2E, 0x82, 0x46, + 0x38, 0x23, 0x0E, 0x74, 0xC7, 0x6B, 0x41, 0xB7, 0xD0, 0x29, 0xA3, 0x9D, + 0x80, 0xB0, 0x7E, 0x77, 0x93, 0x63, 0x42, 0xFB, 0x34, 0x83, 0x3B, 0x73, + 0xA3, 0x5A, 0x21, 0x36, 0xEB, 0x47, 0xFA, 0x18, 0x17, 0xD9, 0xBA, 0x66, + 0xC2, 0x93, 0xA4, 0x8F, 0xFC, 0x5D, 0xA4, 0xAD, 0xFC, 0x50, 0x6A, 0x95, + 0xAC, 0xBC, 0x24, 0x33, 0xD1, 0xBD, 0x88, 0x7F, 0x86, 0xF5, 0xF5, 0xB2, + 0x73, 0x2A, 0x8F, 0x7C, 0xAF, 0x08, 0xF2, 0x1A, 0x98, 0x3F, 0xA9, 0x81, + 0x65, 0x3F, 0xC1, 0x8C, 0x89, 0xC5, 0x96, 0x30, 0x9A, 0x0A, 0xCF, 0xF4, + 0xD4, 0xC8, 0x34, 0xED, 0x9D, 0x2F, 0xBC, 0x8D, 0x38, 0x86, 0x53, 0xEE, + 0x97, 0x9F, 0xA9, 0xB2, 0x63, 0x94, 0x17, 0x8D, 0x0F, 0xDC, 0x66, 0x2A, + 0x7C, 0x52, 0x51, 0x75, 0xCB, 0x99, 0x8E, 0xE8, 0x3D, 0x5C, 0xBF, 0x9E, + 0x3B, 0x28, 0x8D, 0x83, 0x02, 0x0F, 0xA9, 0x9F, 0x72, 0xE2, 0x2C, 0x2B, + 0xB3, 0xDC, 0x66, 0x97, 0x00, 0x40, 0xD0, 0xA4, 0x54, 0x8E, 0x9B, 0x5D, + 0x7B, 0x45, 0x36, 0x26, 0xD6, 0x72, 0x43, 0xEB, 0xCF, 0xC0, 0xEA, 0x0D, + 0xDC, 0xCE, 0x12, 0xE6, 0x7D, 0x38, 0x9F, 0x05, 0x27, 0xA8, 0x97, 0x3E, + 0xE9, 0x51, 0xC6, 0x6C, 0x05, 0x28, 0xC1, 0x02, 0x0F, 0xE9, 0x18, 0x6D, + 0xEC, 0xBD, 0x9C, 0x06, 0xD4, 0xA7, 0x49, 0xF4, 0x54, 0x05, 0x6B, 0x6C, + 0x30, 0xF1, 0xEB, 0x03, 0xD5, 0xEA, 0x3D, 0x6A, 0x76, 0xC2, 0xCB, 0x1A, + 0x28, 0x49, 0x4D, 0x7F, 0x64, 0xE0, 0xFA, 0x2B, 0xDA, 0x73, 0x83, 0x81, + 0xFF, 0x91, 0x03, 0xBD, 0x94, 0xBB, 0xE4, 0xB8, 0x8E, 0x9C, 0x32, 0x63, + 0xCD, 0x9F, 0xBB, 0x68, 0x81, 0xB1, 0x84, 0x5B, 0xAF, 0x36, 0xBF, 0x77, + 0xEE, 0x1D, 0x7F, 0xF7, 0x49, 0x9B, 0x52, 0xEC, 0xD2, 0x77, 0x5A, 0x7D, + 0x91, 0x9D, 0x4D, 0xC2, 0x39, 0x2D, 0xE4, 0xBA, 0x82, 0xF8, 0x6F, 0xF2, + 0x4E, 0x1E, 0x0F, 0x4E, 0xE6, 0x3F, 0x59, 0xA5, 0x23, 0xDC, 0x3D, 0x87, + 0xA8, 0x28, 0x58, 0x28, 0xD1, 0xF1, 0x1B, 0x36, 0xDB, 0x4F, 0xC4, 0xFF, + 0xE1, 0x8C, 0x5B, 0x72, 0x8C, 0xC7, 0x26, 0x03, 0x27, 0xA3, 0x39, 0x0A, + 0x01, 0xAA, 0xC0, 0xB2, 0x31, 0x60, 0x83, 0x22, 0xA1, 0x4F, 0x12, 0x09, + 0x01, 0x11, 0xAF, 0x34, 0xD4, 0xCF, 0xD7, 0xAE, 0x62, 0xD3, 0x05, 0x07, + 0xB4, 0x31, 0x75, 0xE0, 0x0D, 0x6D, 0x57, 0x4F, 0x69, 0x87, 0xF9, 0x57, + 0xA9, 0xBA, 0x15, 0xF6, 0xC8, 0x52, 0x6D, 0xA1, 0xCB, 0x9C, 0x1F, 0xE5, + 0xFC, 0x78, 0xA8, 0x35, 0x9A, 0x9F, 0x41, 0x14, 0xCE, 0xA5, 0xB4, 0xCE, + 0x94, 0x08, 0x1C, 0x09, 0xAD, 0x56, 0xE5, 0xDA, 0xB6, 0x49, 0x9A, 0x4A, + 0xEA, 0x63, 0x18, 0x53, 0x9C, 0x2C, 0x2E, 0xC3 +}; + +static const unsigned char TA134_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA135_DN[] = { + 0x30, 0x71, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, 0x63, + 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0E, 0x56, 0x41, 0x54, + 0x48, 0x55, 0x2D, 0x32, 0x33, 0x35, 0x38, 0x34, 0x34, 0x39, 0x37, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x15, 0x65, 0x2D, + 0x53, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA135_EC_Q[] = { + 0x04, 0x96, 0xDC, 0x3D, 0x8A, 0xD8, 0xB0, 0x7B, 0x6F, 0xC6, 0x27, 0xBE, + 0x44, 0x90, 0xB1, 0xB3, 0x56, 0x15, 0x7B, 0x8E, 0x43, 0x24, 0x7D, 0x1A, + 0x84, 0x59, 0xEE, 0x63, 0x68, 0xB2, 0xC6, 0x5E, 0x87, 0xD0, 0x15, 0x48, + 0x1E, 0xA8, 0x90, 0xAD, 0xBD, 0x53, 0xA2, 0xDA, 0xDE, 0x3A, 0x90, 0xA6, + 0x60, 0x5F, 0x68, 0x32, 0xB5, 0x86, 0x41, 0xDF, 0x87, 0x5B, 0x2C, 0x7B, + 0xC5, 0xFE, 0x7C, 0x7A, 0xDA +}; + +static const unsigned char TA136_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x45, 0x31 +}; + +static const unsigned char TA136_EC_Q[] = { + 0x04, 0xDE, 0x6F, 0xF8, 0x7F, 0x1C, 0xDF, 0xED, 0xF9, 0x47, 0x87, 0x86, + 0xB1, 0xA4, 0xC0, 0x8A, 0xF8, 0x82, 0x97, 0x80, 0xEA, 0x8F, 0xC8, 0x4A, + 0x5E, 0x2A, 0x7D, 0x88, 0x68, 0xA7, 0x01, 0x62, 0x14, 0x91, 0x24, 0x7A, + 0x5C, 0x9E, 0xA3, 0x17, 0x7D, 0x8A, 0x86, 0x21, 0x34, 0x18, 0x50, 0x1B, + 0x10, 0xDE, 0xD0, 0x37, 0x4B, 0x26, 0xC7, 0x19, 0x60, 0x80, 0xE9, 0x34, + 0xBD, 0x60, 0x19, 0x36, 0x40, 0xD6, 0x29, 0x87, 0x09, 0x3C, 0x91, 0x7A, + 0xF6, 0xBC, 0x13, 0x23, 0xDD, 0x59, 0x4E, 0x04, 0x5E, 0xCF, 0xC8, 0x02, + 0x1C, 0x18, 0x53, 0xC1, 0x31, 0xD8, 0xDA, 0x20, 0xE9, 0x44, 0x8D, 0xE4, + 0x76 +}; + +static const unsigned char TA137_DN[] = { + 0x30, 0x81, 0x8F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, + 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA137_RSA_N[] = { + 0xBD, 0xED, 0xC1, 0x03, 0xFC, 0xF6, 0x8F, 0xFC, 0x02, 0xB1, 0x6F, 0x5B, + 0x9F, 0x48, 0xD9, 0x9D, 0x79, 0xE2, 0xA2, 0xB7, 0x03, 0x61, 0x56, 0x18, + 0xC3, 0x47, 0xB6, 0xD7, 0xCA, 0x3D, 0x35, 0x2E, 0x89, 0x43, 0xF7, 0xA1, + 0x69, 0x9B, 0xDE, 0x8A, 0x1A, 0xFD, 0x13, 0x20, 0x9C, 0xB4, 0x49, 0x77, + 0x32, 0x29, 0x56, 0xFD, 0xB9, 0xEC, 0x8C, 0xDD, 0x22, 0xFA, 0x72, 0xDC, + 0x27, 0x61, 0x97, 0xEE, 0xF6, 0x5A, 0x84, 0xEC, 0x6E, 0x19, 0xB9, 0x89, + 0x2C, 0xDC, 0x84, 0x5B, 0xD5, 0x74, 0xFB, 0x6B, 0x5F, 0xC5, 0x89, 0xA5, + 0x10, 0x52, 0x89, 0x46, 0x55, 0xF4, 0xB8, 0x75, 0x1C, 0xE6, 0x7F, 0xE4, + 0x54, 0xAE, 0x4B, 0xF8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xF8, 0x17, 0x71, + 0x59, 0xEB, 0x1E, 0x28, 0x07, 0x74, 0xC5, 0x9D, 0x48, 0xBE, 0x6C, 0xB4, + 0xF4, 0xA4, 0xB0, 0xF3, 0x64, 0x37, 0x79, 0x92, 0xC0, 0xEC, 0x46, 0x5E, + 0x7F, 0xE1, 0x6D, 0x53, 0x4C, 0x62, 0xAF, 0xCD, 0x1F, 0x0B, 0x63, 0xBB, + 0x3A, 0x9D, 0xFB, 0xFC, 0x79, 0x00, 0x98, 0x61, 0x74, 0xCF, 0x26, 0x82, + 0x40, 0x63, 0xF3, 0xB2, 0x72, 0x6A, 0x19, 0x0D, 0x99, 0xCA, 0xD4, 0x0E, + 0x75, 0xCC, 0x37, 0xFB, 0x8B, 0x89, 0xC1, 0x59, 0xF1, 0x62, 0x7F, 0x5F, + 0xB3, 0x5F, 0x65, 0x30, 0xF8, 0xA7, 0xB7, 0x4D, 0x76, 0x5A, 0x1E, 0x76, + 0x5E, 0x34, 0xC0, 0xE8, 0x96, 0x56, 0x99, 0x8A, 0xB3, 0xF0, 0x7F, 0xA4, + 0xCD, 0xBD, 0xDC, 0x32, 0x31, 0x7C, 0x91, 0xCF, 0xE0, 0x5F, 0x11, 0xF8, + 0x6B, 0xAA, 0x49, 0x5C, 0xD1, 0x99, 0x94, 0xD1, 0xA2, 0xE3, 0x63, 0x5B, + 0x09, 0x76, 0xB5, 0x56, 0x62, 0xE1, 0x4B, 0x74, 0x1D, 0x96, 0xD4, 0x26, + 0xD4, 0x08, 0x04, 0x59, 0xD0, 0x98, 0x0E, 0x0E, 0xE6, 0xDE, 0xFC, 0xC3, + 0xEC, 0x1F, 0x90, 0xF1 +}; + +static const unsigned char TA137_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA138_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, 0x67 +}; + +static const unsigned char TA138_RSA_N[] = { + 0xB4, 0x84, 0xCC, 0x33, 0x17, 0x2E, 0x6B, 0x94, 0x6C, 0x6B, 0x61, 0x52, + 0xA0, 0xEB, 0xA3, 0xCF, 0x79, 0x94, 0x4C, 0xE5, 0x94, 0x80, 0x99, 0xCB, + 0x55, 0x64, 0x44, 0x65, 0x8F, 0x67, 0x64, 0xE2, 0x06, 0xE3, 0x5C, 0x37, + 0x49, 0xF6, 0x2F, 0x9B, 0x84, 0x84, 0x1E, 0x2D, 0xF2, 0x60, 0x9D, 0x30, + 0x4E, 0xCC, 0x84, 0x85, 0xE2, 0x2C, 0xCF, 0x1E, 0x9E, 0xFE, 0x36, 0xAB, + 0x33, 0x77, 0x35, 0x44, 0xD8, 0x35, 0x96, 0x1A, 0x3D, 0x36, 0xE8, 0x7A, + 0x0E, 0xD8, 0xD5, 0x47, 0xA1, 0x6A, 0x69, 0x8B, 0xD9, 0xFC, 0xBB, 0x3A, + 0xAE, 0x79, 0x5A, 0xD5, 0xF4, 0xD6, 0x71, 0xBB, 0x9A, 0x90, 0x23, 0x6B, + 0x9A, 0xB7, 0x88, 0x74, 0x87, 0x0C, 0x1E, 0x5F, 0xB9, 0x9E, 0x2D, 0xFA, + 0xAB, 0x53, 0x2B, 0xDC, 0xBB, 0x76, 0x3E, 0x93, 0x4C, 0x08, 0x08, 0x8C, + 0x1E, 0xA2, 0x23, 0x1C, 0xD4, 0x6A, 0xAD, 0x22, 0xBA, 0x99, 0x01, 0x2E, + 0x6D, 0x65, 0xCB, 0xBE, 0x24, 0x66, 0x55, 0x24, 0x4B, 0x40, 0x44, 0xB1, + 0x1B, 0xD7, 0xE1, 0xC2, 0x85, 0xC0, 0xDE, 0x10, 0x3F, 0x3D, 0xED, 0xB8, + 0xFC, 0xF1, 0xF1, 0x23, 0x53, 0xDC, 0xBF, 0x65, 0x97, 0x6F, 0xD9, 0xF9, + 0x40, 0x71, 0x8D, 0x7D, 0xBD, 0x95, 0xD4, 0xCE, 0xBE, 0xA0, 0x5E, 0x27, + 0x23, 0xDE, 0xFD, 0xA6, 0xD0, 0x26, 0x0E, 0x00, 0x29, 0xEB, 0x3C, 0x46, + 0xF0, 0x3D, 0x60, 0xBF, 0x3F, 0x50, 0xD2, 0xDC, 0x26, 0x41, 0x51, 0x9E, + 0x14, 0x37, 0x42, 0x04, 0xA3, 0x70, 0x57, 0xA8, 0x1B, 0x87, 0xED, 0x2D, + 0xFA, 0x7B, 0xEE, 0x8C, 0x0A, 0xE3, 0xA9, 0x66, 0x89, 0x19, 0xCB, 0x41, + 0xF9, 0xDD, 0x44, 0x36, 0x61, 0xCF, 0xE2, 0x77, 0x46, 0xC8, 0x7D, 0xF6, + 0xF4, 0x92, 0x81, 0x36, 0xFD, 0xDB, 0x34, 0xF1, 0x72, 0x7E, 0xF3, 0x0C, + 0x16, 0xBD, 0xB4, 0x15 +}; + +static const unsigned char TA138_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA139_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA139_EC_Q[] = { + 0x04, 0x45, 0x29, 0x35, 0x73, 0xFA, 0xC2, 0xB8, 0x23, 0xCE, 0x14, 0x7D, + 0xA8, 0xB1, 0x4D, 0xA0, 0x5B, 0x36, 0xEE, 0x2A, 0x2C, 0x53, 0xC3, 0x60, + 0x09, 0x35, 0xB2, 0x24, 0x66, 0x26, 0x69, 0xC0, 0xB3, 0x95, 0xD6, 0x5D, + 0x92, 0x40, 0x19, 0x0E, 0xC6, 0xA5, 0x13, 0x70, 0xF4, 0xEF, 0x12, 0x51, + 0x28, 0x5D, 0xE7, 0xCC, 0xBD, 0xF9, 0x3C, 0x85, 0xC1, 0xCF, 0x94, 0x90, + 0xC9, 0x2B, 0xCE, 0x92, 0x42, 0x58, 0x59, 0x67, 0xFD, 0x94, 0x27, 0x10, + 0x64, 0x8C, 0x4F, 0x04, 0xB1, 0x4D, 0x49, 0xE4, 0x7B, 0x4F, 0x9B, 0xF5, + 0xE7, 0x08, 0xF8, 0x03, 0x88, 0xF7, 0xA7, 0xC3, 0x92, 0x4B, 0x19, 0x54, + 0x81 +}; + +static const unsigned char TA140_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x43, 0x33 +}; + +static const unsigned char TA140_EC_Q[] = { + 0x04, 0xFD, 0xA5, 0x61, 0xAE, 0x7B, 0x26, 0x10, 0x1D, 0xE9, 0xB7, 0x22, + 0x30, 0xAE, 0x06, 0xF4, 0x81, 0xB3, 0xB1, 0x42, 0x71, 0x95, 0x39, 0xBC, + 0xD3, 0x52, 0xE3, 0xAF, 0xAF, 0xF9, 0xF2, 0x97, 0x35, 0x92, 0x36, 0x46, + 0x0E, 0x87, 0x95, 0x8D, 0xB9, 0x39, 0x5A, 0xE9, 0xBB, 0xDF, 0xD0, 0xFE, + 0xC8, 0x07, 0x41, 0x3C, 0xBB, 0x55, 0x6F, 0x83, 0xA3, 0x6A, 0xFB, 0x62, + 0xB0, 0x81, 0x89, 0x02, 0x70, 0x7D, 0x48, 0xC5, 0x4A, 0xE3, 0xE9, 0x22, + 0x54, 0x22, 0x4D, 0x93, 0xBB, 0x42, 0x0C, 0xAF, 0x77, 0x9C, 0x23, 0xA6, + 0x7D, 0xD7, 0x61, 0x11, 0xCE, 0x65, 0xC7, 0xF8, 0x7F, 0xFE, 0xF5, 0xF2, + 0xA9 +}; + +static const unsigned char TA141_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x34 +}; + +static const unsigned char TA141_RSA_N[] = { + 0xC5, 0xD2, 0x7A, 0xA1, 0xD6, 0x8A, 0xBF, 0x16, 0x31, 0xD0, 0x98, 0xD1, + 0x3A, 0x94, 0xFC, 0x5A, 0xB8, 0x6E, 0x22, 0xC1, 0x62, 0xF7, 0xA7, 0x0A, + 0x27, 0xEF, 0x50, 0xF6, 0x2E, 0xB1, 0x9E, 0x68, 0x12, 0xF0, 0x6C, 0x24, + 0x63, 0x39, 0xF1, 0xF0, 0xDF, 0x10, 0xC6, 0xDE, 0xB7, 0x52, 0x20, 0xD5, + 0x52, 0x5B, 0x42, 0x99, 0x9E, 0xF3, 0xA0, 0xBE, 0x52, 0x1F, 0x5F, 0xCC, + 0x67, 0x6D, 0xA7, 0x2E, 0x50, 0xA2, 0xC1, 0x97, 0x8D, 0xB6, 0xF8, 0x95, + 0xF5, 0xB0, 0xBA, 0xDC, 0x9D, 0xE0, 0xBE, 0xCB, 0xDF, 0xF7, 0x38, 0xF2, + 0x47, 0xF5, 0xA6, 0x9A, 0x92, 0x95, 0x2A, 0x62, 0x59, 0x50, 0x0B, 0xA2, + 0xB1, 0x35, 0xE7, 0x65, 0xB2, 0x61, 0xB2, 0xEA, 0x92, 0x71, 0x69, 0xE4, + 0x29, 0xF0, 0x4F, 0x81, 0x81, 0x04, 0x3C, 0xB2, 0xA5, 0x5B, 0xD4, 0xC5, + 0xA8, 0x59, 0x67, 0x7B, 0x55, 0x1C, 0x49, 0xAB, 0x7A, 0x9D, 0xC2, 0xE7, + 0x73, 0x4D, 0xEF, 0xCD, 0x09, 0xC2, 0xC4, 0x57, 0x12, 0xDB, 0x01, 0x0E, + 0x23, 0x79, 0x09, 0x07, 0x3B, 0xA2, 0xE8, 0xFC, 0x8A, 0xCF, 0x8F, 0xC0, + 0x46, 0x24, 0x9C, 0x38, 0x27, 0xE0, 0x83, 0x9D, 0x1B, 0xA0, 0xBF, 0x78, + 0x15, 0x10, 0xEB, 0x86, 0x4E, 0x0A, 0x5A, 0xFD, 0xDF, 0xDA, 0x2C, 0x82, + 0x7E, 0xEE, 0xCA, 0xF6, 0x29, 0xE1, 0xFA, 0x71, 0xA1, 0xF7, 0x88, 0x68, + 0x9C, 0x9C, 0xF0, 0x8D, 0xBE, 0x0F, 0x49, 0x91, 0xD8, 0xEA, 0x3A, 0xF9, + 0xFD, 0xD0, 0x68, 0x71, 0xDB, 0xE9, 0xB5, 0x2B, 0x4E, 0x82, 0x92, 0x6F, + 0x66, 0x1F, 0xE0, 0xF0, 0xDC, 0x4C, 0xEC, 0xCA, 0xD1, 0xEA, 0xBA, 0x74, + 0x06, 0xF9, 0xB3, 0x84, 0x90, 0x94, 0xD1, 0x5F, 0x8E, 0x73, 0x19, 0x10, + 0x5D, 0x02, 0xE5, 0x70, 0xA5, 0xC0, 0x10, 0xD0, 0x10, 0x7C, 0x6F, 0xC5, + 0x58, 0x49, 0xB4, 0xB0, 0x6E, 0x9A, 0xDA, 0x7D, 0x95, 0xF5, 0xCC, 0xDA, + 0x02, 0xAF, 0xB8, 0x2C, 0x7D, 0x79, 0x8F, 0xBE, 0x43, 0xF1, 0xF9, 0x28, + 0x28, 0x8D, 0x09, 0x43, 0xF8, 0x08, 0xDD, 0x6B, 0xC8, 0x8B, 0x2C, 0x24, + 0xB1, 0x8D, 0x52, 0x07, 0xBD, 0x78, 0x9B, 0xCB, 0xCA, 0x68, 0xB2, 0xA4, + 0xDD, 0x0C, 0x4C, 0x79, 0x60, 0xC6, 0x99, 0xD1, 0x93, 0xF1, 0x30, 0x1A, + 0x07, 0xD3, 0xAE, 0x22, 0xC2, 0xEA, 0xCE, 0xF1, 0x84, 0x09, 0xCC, 0xE0, + 0x14, 0x6E, 0x7F, 0x3F, 0x7E, 0xD2, 0x82, 0x85, 0xAC, 0xDC, 0xA9, 0x16, + 0x4E, 0x85, 0xA0, 0x60, 0xCB, 0xF6, 0x9C, 0xD7, 0xC8, 0xB3, 0x8E, 0xED, + 0xC6, 0x9B, 0x98, 0x75, 0x0D, 0x55, 0xE8, 0x5F, 0xE5, 0x95, 0x8B, 0x02, + 0xA4, 0xAE, 0x43, 0x29, 0x28, 0x11, 0xA4, 0xE6, 0x12, 0x30, 0x01, 0x4B, + 0x75, 0x6B, 0x1E, 0x66, 0x9D, 0x79, 0x2F, 0xA5, 0x76, 0x2F, 0x1D, 0x40, + 0xB4, 0x6D, 0xC9, 0x7D, 0x79, 0x08, 0xEC, 0xD1, 0x6A, 0xB6, 0x5D, 0x2A, + 0xB2, 0xA5, 0x66, 0xBD, 0x6B, 0x85, 0xF4, 0x74, 0x56, 0xC3, 0xF5, 0xE7, + 0x75, 0x52, 0x28, 0x2C, 0xA5, 0xFF, 0x66, 0x47, 0xA5, 0xD4, 0xFE, 0xFE, + 0x9E, 0x54, 0xBF, 0x65, 0x7E, 0x01, 0xD6, 0x30, 0x8F, 0xA5, 0x36, 0x9C, + 0xA2, 0x50, 0x1C, 0xEE, 0x38, 0x80, 0x01, 0x48, 0xC6, 0xC7, 0x74, 0xF4, + 0xC6, 0xAC, 0xC3, 0x40, 0x49, 0x16, 0x61, 0x74, 0x2C, 0xAF, 0x8C, 0x6F, + 0x35, 0xED, 0x7B, 0x18, 0x00, 0x5B, 0x36, 0x3C, 0x9C, 0x50, 0x0D, 0xCA, + 0x92, 0x33, 0x10, 0xF1, 0x26, 0x49, 0x6D, 0xDF, 0x75, 0x24, 0x37, 0x82, + 0x22, 0xD7, 0xE8, 0x96, 0xFD, 0x15, 0x4B, 0x02, 0x96, 0x3E, 0x07, 0x72, + 0x95, 0x7E, 0xAB, 0x3D, 0x4C, 0x2E, 0xD7, 0xCA, 0xF0, 0xDF, 0xE0, 0x58, + 0x3F, 0x2D, 0x2F, 0x04, 0x9A, 0x38, 0xA3, 0x01 +}; + +static const unsigned char TA141_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA142_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x34 +}; + +static const unsigned char TA142_RSA_N[] = { + 0xC5, 0xD2, 0x7A, 0xA1, 0xD6, 0x8A, 0xBF, 0x16, 0x31, 0xD0, 0x98, 0xD1, + 0x3A, 0x94, 0xFC, 0x5A, 0xB8, 0x6E, 0x22, 0xC1, 0x62, 0xF7, 0xA7, 0x0A, + 0x27, 0xEF, 0x50, 0xF6, 0x2E, 0xB1, 0x9E, 0x68, 0x12, 0xF0, 0x6C, 0x24, + 0x63, 0x39, 0xF1, 0xF0, 0xDF, 0x10, 0xC6, 0xDE, 0xB7, 0x52, 0x20, 0xD5, + 0x52, 0x5B, 0x42, 0x99, 0x9E, 0xF3, 0xA0, 0xBE, 0x52, 0x1F, 0x5F, 0xCC, + 0x67, 0x6D, 0xA7, 0x2E, 0x50, 0xA2, 0xC1, 0x97, 0x8D, 0xB6, 0xF8, 0x95, + 0xF5, 0xB0, 0xBA, 0xDC, 0x9D, 0xE0, 0xBE, 0xCB, 0xDF, 0xF7, 0x38, 0xF2, + 0x47, 0xF5, 0xA6, 0x9A, 0x92, 0x95, 0x2A, 0x62, 0x59, 0x50, 0x0B, 0xA2, + 0xB1, 0x35, 0xE7, 0x65, 0xB2, 0x61, 0xB2, 0xEA, 0x92, 0x71, 0x69, 0xE4, + 0x29, 0xF0, 0x4F, 0x81, 0x81, 0x04, 0x3C, 0xB2, 0xA5, 0x5B, 0xD4, 0xC5, + 0xA8, 0x59, 0x67, 0x7B, 0x55, 0x1C, 0x49, 0xAB, 0x7A, 0x9D, 0xC2, 0xE7, + 0x73, 0x4D, 0xEF, 0xCD, 0x09, 0xC2, 0xC4, 0x57, 0x12, 0xDB, 0x01, 0x0E, + 0x23, 0x79, 0x09, 0x07, 0x3B, 0xA2, 0xE8, 0xFC, 0x8A, 0xCF, 0x8F, 0xC0, + 0x46, 0x24, 0x9C, 0x38, 0x27, 0xE0, 0x83, 0x9D, 0x1B, 0xA0, 0xBF, 0x78, + 0x15, 0x10, 0xEB, 0x86, 0x4E, 0x0A, 0x5A, 0xFD, 0xDF, 0xDA, 0x2C, 0x82, + 0x7E, 0xEE, 0xCA, 0xF6, 0x29, 0xE1, 0xFA, 0x71, 0xA1, 0xF7, 0x88, 0x68, + 0x9C, 0x9C, 0xF0, 0x8D, 0xBE, 0x0F, 0x49, 0x91, 0xD8, 0xEA, 0x3A, 0xF9, + 0xFD, 0xD0, 0x68, 0x71, 0xDB, 0xE9, 0xB5, 0x2B, 0x4E, 0x82, 0x92, 0x6F, + 0x66, 0x1F, 0xE0, 0xF0, 0xDC, 0x4C, 0xEC, 0xCA, 0xD1, 0xEA, 0xBA, 0x74, + 0x06, 0xF9, 0xB3, 0x84, 0x90, 0x94, 0xD1, 0x5F, 0x8E, 0x73, 0x19, 0x10, + 0x5D, 0x02, 0xE5, 0x70, 0xA5, 0xC0, 0x10, 0xD0, 0x10, 0x7C, 0x6F, 0xC5, + 0x58, 0x49, 0xB4, 0xB0, 0x6E, 0x9A, 0xDA, 0x7D, 0x95, 0xF5, 0xCC, 0xDA, + 0x02, 0xAF, 0xB8, 0x2C, 0x7D, 0x79, 0x8F, 0xBE, 0x43, 0xF1, 0xF9, 0x28, + 0x28, 0x8D, 0x09, 0x43, 0xF8, 0x08, 0xDD, 0x6B, 0xC8, 0x8B, 0x2C, 0x24, + 0xB1, 0x8D, 0x52, 0x07, 0xBD, 0x78, 0x9B, 0xCB, 0xCA, 0x68, 0xB2, 0xA4, + 0xDD, 0x0C, 0x4C, 0x79, 0x60, 0xC6, 0x99, 0xD1, 0x93, 0xF1, 0x30, 0x1A, + 0x07, 0xD3, 0xAE, 0x22, 0xC2, 0xEA, 0xCE, 0xF1, 0x84, 0x09, 0xCC, 0xE0, + 0x14, 0x6E, 0x7F, 0x3F, 0x7E, 0xD2, 0x82, 0x85, 0xAC, 0xDC, 0xA9, 0x16, + 0x4E, 0x85, 0xA0, 0x60, 0xCB, 0xF6, 0x9C, 0xD7, 0xC8, 0xB3, 0x8E, 0xED, + 0xC6, 0x9B, 0x98, 0x75, 0x0D, 0x55, 0xE8, 0x5F, 0xE5, 0x95, 0x8B, 0x02, + 0xA4, 0xAE, 0x43, 0x29, 0x28, 0x11, 0xA4, 0xE6, 0x12, 0x30, 0x01, 0x4B, + 0x75, 0x6B, 0x1E, 0x66, 0x9D, 0x79, 0x2F, 0xA5, 0x76, 0x2F, 0x1D, 0x40, + 0xB4, 0x6D, 0xC9, 0x7D, 0x79, 0x08, 0xEC, 0xD1, 0x6A, 0xB6, 0x5D, 0x2A, + 0xB2, 0xA5, 0x66, 0xBD, 0x6B, 0x85, 0xF4, 0x74, 0x56, 0xC3, 0xF5, 0xE7, + 0x75, 0x52, 0x28, 0x2C, 0xA5, 0xFF, 0x66, 0x47, 0xA5, 0xD4, 0xFE, 0xFE, + 0x9E, 0x54, 0xBF, 0x65, 0x7E, 0x01, 0xD6, 0x30, 0x8F, 0xA5, 0x36, 0x9C, + 0xA2, 0x50, 0x1C, 0xEE, 0x38, 0x80, 0x01, 0x48, 0xC6, 0xC7, 0x74, 0xF4, + 0xC6, 0xAC, 0xC3, 0x40, 0x49, 0x16, 0x61, 0x74, 0x2C, 0xAF, 0x8C, 0x6F, + 0x35, 0xED, 0x7B, 0x18, 0x00, 0x5B, 0x36, 0x3C, 0x9C, 0x50, 0x0D, 0xCA, + 0x92, 0x33, 0x10, 0xF1, 0x26, 0x49, 0x6D, 0xDF, 0x75, 0x24, 0x37, 0x82, + 0x22, 0xD7, 0xE8, 0x96, 0xFD, 0x15, 0x4B, 0x02, 0x96, 0x3E, 0x07, 0x72, + 0x95, 0x7E, 0xAB, 0x3D, 0x4C, 0x2E, 0xD7, 0xCA, 0xF0, 0xDF, 0xE0, 0x58, + 0x3F, 0x2D, 0x2F, 0x04, 0x9A, 0x38, 0xA3, 0x01 +}; + +static const unsigned char TA142_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA143_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x32 +}; + +static const unsigned char TA143_EC_Q[] = { + 0x04, 0xCD, 0x9B, 0xD5, 0x9F, 0x80, 0x83, 0x0A, 0xEC, 0x09, 0x4A, 0xF3, + 0x16, 0x4A, 0x3E, 0x5C, 0xCF, 0x77, 0xAC, 0xDE, 0x67, 0x05, 0x0D, 0x1D, + 0x07, 0xB6, 0xDC, 0x16, 0xFB, 0x5A, 0x8B, 0x14, 0xDB, 0xE2, 0x71, 0x60, + 0xC4, 0xBA, 0x45, 0x95, 0x11, 0x89, 0x8E, 0xEA, 0x06, 0xDF, 0xF7, 0x2A, + 0x16, 0x1C, 0xA4, 0xB9, 0xC5, 0xC5, 0x32, 0xE0, 0x03, 0xE0, 0x1E, 0x82, + 0x18, 0x38, 0x8B, 0xD7, 0x45, 0xD8, 0x0A, 0x6A, 0x6E, 0xE6, 0x00, 0x77, + 0xFB, 0x02, 0x51, 0x7D, 0x22, 0xD8, 0x0A, 0x6E, 0x9A, 0x5B, 0x77, 0xDF, + 0xF0, 0xFA, 0x41, 0xEC, 0x39, 0xDC, 0x75, 0xCA, 0x68, 0x07, 0x0C, 0x1F, + 0xEA +}; + +static const unsigned char TA144_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x08, 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x10, 0x63, 0x65, 0x72, + 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA144_RSA_N[] = { + 0xB7, 0x33, 0xB9, 0x7E, 0xC8, 0x25, 0x4A, 0x8E, 0xB5, 0xDB, 0xB4, 0x28, + 0x1B, 0xAA, 0x57, 0x90, 0xE8, 0xD1, 0x22, 0xD3, 0x64, 0xBA, 0xD3, 0x93, + 0xE8, 0xD4, 0xAC, 0x86, 0x61, 0x40, 0x6A, 0x60, 0x57, 0x68, 0x54, 0x84, + 0x4D, 0xBC, 0x6A, 0x54, 0x02, 0x05, 0xFF, 0xDF, 0x9B, 0x9A, 0x2A, 0xAE, + 0x5D, 0x07, 0x8F, 0x4A, 0xC3, 0x28, 0x7F, 0xEF, 0xFB, 0x2B, 0xFA, 0x79, + 0xF1, 0xC7, 0xAD, 0xF0, 0x10, 0x53, 0x24, 0x90, 0x8B, 0x66, 0xC9, 0xA8, + 0x88, 0xAB, 0xAF, 0x5A, 0xA3, 0x00, 0xE9, 0xBE, 0xBA, 0x46, 0xEE, 0x5B, + 0x73, 0x7B, 0x2C, 0x17, 0x82, 0x81, 0x5E, 0x62, 0x2C, 0xA1, 0x02, 0x65, + 0xB3, 0xBD, 0xC5, 0x2B, 0x00, 0x7E, 0xC4, 0xFC, 0x03, 0x33, 0x57, 0x0D, + 0xED, 0xE2, 0xFA, 0xCE, 0x5D, 0x45, 0xD6, 0x38, 0xCD, 0x35, 0xB6, 0xB2, + 0xC1, 0xD0, 0x9C, 0x81, 0x4A, 0xAA, 0xE4, 0xB2, 0x01, 0x5C, 0x1D, 0x8F, + 0x5F, 0x99, 0xC4, 0xB1, 0xAD, 0xDB, 0x88, 0x21, 0xEB, 0x90, 0x08, 0x82, + 0x80, 0xF3, 0x30, 0xA3, 0x43, 0xE6, 0x90, 0x82, 0xAE, 0x55, 0x28, 0x49, + 0xED, 0x5B, 0xD7, 0xA9, 0x10, 0x38, 0x0E, 0xFE, 0x8F, 0x4C, 0x5B, 0x9B, + 0x46, 0xEA, 0x41, 0xF5, 0xB0, 0x08, 0x74, 0xC3, 0xD0, 0x88, 0x33, 0xB6, + 0x7C, 0xD7, 0x74, 0xDF, 0xDC, 0x84, 0xD1, 0x43, 0x0E, 0x75, 0x39, 0xA1, + 0x25, 0x40, 0x28, 0xEA, 0x78, 0xCB, 0x0E, 0x2C, 0x2E, 0x39, 0x9D, 0x8C, + 0x8B, 0x6E, 0x16, 0x1C, 0x2F, 0x26, 0x82, 0x10, 0xE2, 0xE3, 0x65, 0x94, + 0x0A, 0x04, 0xC0, 0x5E, 0xF7, 0x5D, 0x5B, 0xF8, 0x10, 0xE2, 0xD0, 0xBA, + 0x7A, 0x4B, 0xFB, 0xDE, 0x37, 0x00, 0x00, 0x1A, 0x5B, 0x28, 0xE3, 0xD2, + 0x9C, 0x73, 0x3E, 0x32, 0x87, 0x98, 0xA1, 0xC9, 0x51, 0x2F, 0xD7, 0xDE, + 0xAC, 0x33, 0xB3, 0x4F +}; + +static const unsigned char TA144_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA145_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA145_EC_Q[] = { + 0x04, 0x45, 0x6E, 0xA9, 0x50, 0xC4, 0xA6, 0x23, 0x36, 0x9E, 0x5F, 0x28, + 0x8D, 0x17, 0xCB, 0x96, 0x22, 0x64, 0x3F, 0xDC, 0x7A, 0x8E, 0x1D, 0xCC, + 0x08, 0xB3, 0xA2, 0x71, 0x24, 0xBA, 0x8E, 0x49, 0xB9, 0x04, 0x1B, 0x47, + 0x96, 0x58, 0xAB, 0x2D, 0x95, 0xC8, 0xED, 0x9E, 0x08, 0x35, 0xC8, 0x27, + 0xEB, 0x89, 0x8C, 0x53, 0x58, 0xEB, 0x62, 0x8A, 0xFE, 0xF0, 0x5B, 0x0F, + 0x6B, 0x31, 0x52, 0x63, 0x41, 0x3B, 0x89, 0xCD, 0xEC, 0xEC, 0xB6, 0x8D, + 0x19, 0xD3, 0x34, 0x07, 0xDC, 0xBB, 0xC6, 0x06, 0x7F, 0xC2, 0x45, 0x95, + 0xEC, 0xCB, 0x7F, 0xA8, 0x23, 0xE0, 0x09, 0xE9, 0x81, 0xFA, 0xF3, 0x47, + 0xD3 +}; + +static const unsigned char TA146_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA146_EC_Q[] = { + 0x04, 0x03, 0x47, 0x7B, 0x2F, 0x75, 0xC9, 0x82, 0x15, 0x85, 0xFB, 0x75, + 0xE4, 0x91, 0x16, 0xD4, 0xAB, 0x62, 0x99, 0xF5, 0x3E, 0x52, 0x0B, 0x06, + 0xCE, 0x41, 0x00, 0x7F, 0x97, 0xE1, 0x0A, 0x24, 0x3C, 0x1D, 0x01, 0x04, + 0xEE, 0x3D, 0xD2, 0x8D, 0x09, 0x97, 0x0C, 0xE0, 0x75, 0xE4, 0xFA, 0xFB, + 0x77, 0x8A, 0x2A, 0xF5, 0x03, 0x60, 0x4B, 0x36, 0x8B, 0x16, 0x23, 0x16, + 0xAD, 0x09, 0x71, 0xF4, 0x4A, 0xF4, 0x28, 0x50, 0xB4, 0xFE, 0x88, 0x1C, + 0x6E, 0x3F, 0x6C, 0x2F, 0x2F, 0x09, 0x59, 0x5B, 0xA5, 0x5B, 0x0B, 0x33, + 0x99, 0xE2, 0xC3, 0x3D, 0x89, 0xF9, 0x6A, 0x2C, 0xEF, 0xB2, 0xD3, 0x06, + 0xE9 +}; + +static const unsigned char TA147_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA147_EC_Q[] = { + 0x04, 0x29, 0x97, 0xA7, 0xC6, 0x41, 0x7F, 0xC0, 0x0D, 0x9B, 0xE8, 0x01, + 0x1B, 0x56, 0xC6, 0xF2, 0x52, 0xA5, 0xBA, 0x2D, 0xB2, 0x12, 0xE8, 0xD2, + 0x2E, 0xD7, 0xFA, 0xC9, 0xC5, 0xD8, 0xAA, 0x6D, 0x1F, 0x73, 0x81, 0x3B, + 0x3B, 0x98, 0x6B, 0x39, 0x7C, 0x33, 0xA5, 0xC5, 0x4E, 0x86, 0x8E, 0x80, + 0x17, 0x68, 0x62, 0x45, 0x57, 0x7D, 0x44, 0x58, 0x1D, 0xB3, 0x37, 0xE5, + 0x67, 0x08, 0xEB, 0x66, 0xDE +}; + +static const unsigned char TA148_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA148_RSA_N[] = { + 0xB0, 0x48, 0x65, 0xA3, 0x0D, 0x1D, 0x42, 0xE3, 0x91, 0x6D, 0x9D, 0x84, + 0xA4, 0x61, 0x96, 0x12, 0xC2, 0xED, 0xC3, 0xDA, 0x23, 0x34, 0x19, 0x76, + 0xF6, 0xEA, 0xFD, 0x55, 0x5A, 0xF6, 0x55, 0x01, 0x53, 0x0F, 0xF2, 0xCC, + 0x8C, 0x97, 0x4F, 0xB9, 0x50, 0xCB, 0xB3, 0x01, 0x44, 0x56, 0x96, 0xFD, + 0x9B, 0x28, 0xEC, 0x7B, 0x74, 0x0B, 0xE7, 0x42, 0x6B, 0x55, 0xCE, 0xC9, + 0x61, 0xB2, 0xE8, 0xAD, 0x40, 0x3C, 0xBA, 0xB9, 0x41, 0x0A, 0x05, 0x4F, + 0x1B, 0x26, 0x85, 0x8F, 0x43, 0xB5, 0x40, 0xB5, 0x85, 0xD1, 0xD4, 0x71, + 0xDC, 0x83, 0x41, 0xF3, 0xF6, 0x45, 0xC7, 0x80, 0xA2, 0x84, 0x50, 0x97, + 0x46, 0xCE, 0xA0, 0x0C, 0xC4, 0x60, 0x56, 0x04, 0x1D, 0x07, 0x5B, 0x46, + 0xA5, 0x0E, 0xB2, 0x4B, 0xA4, 0x0E, 0xA5, 0x7C, 0xEE, 0xF8, 0xD4, 0x62, + 0x03, 0xB9, 0x93, 0x6A, 0x8A, 0x14, 0xB8, 0x70, 0xF8, 0x2E, 0x82, 0x46, + 0x38, 0x23, 0x0E, 0x74, 0xC7, 0x6B, 0x41, 0xB7, 0xD0, 0x29, 0xA3, 0x9D, + 0x80, 0xB0, 0x7E, 0x77, 0x93, 0x63, 0x42, 0xFB, 0x34, 0x83, 0x3B, 0x73, + 0xA3, 0x5A, 0x21, 0x36, 0xEB, 0x47, 0xFA, 0x18, 0x17, 0xD9, 0xBA, 0x66, + 0xC2, 0x93, 0xA4, 0x8F, 0xFC, 0x5D, 0xA4, 0xAD, 0xFC, 0x50, 0x6A, 0x95, + 0xAC, 0xBC, 0x24, 0x33, 0xD1, 0xBD, 0x88, 0x7F, 0x86, 0xF5, 0xF5, 0xB2, + 0x73, 0x2A, 0x8F, 0x7C, 0xAF, 0x08, 0xF2, 0x1A, 0x98, 0x3F, 0xA9, 0x81, + 0x65, 0x3F, 0xC1, 0x8C, 0x89, 0xC5, 0x96, 0x30, 0x9A, 0x0A, 0xCF, 0xF4, + 0xD4, 0xC8, 0x34, 0xED, 0x9D, 0x2F, 0xBC, 0x8D, 0x38, 0x86, 0x53, 0xEE, + 0x97, 0x9F, 0xA9, 0xB2, 0x63, 0x94, 0x17, 0x8D, 0x0F, 0xDC, 0x66, 0x2A, + 0x7C, 0x52, 0x51, 0x75, 0xCB, 0x99, 0x8E, 0xE8, 0x3D, 0x5C, 0xBF, 0x9E, + 0x3B, 0x28, 0x8D, 0x83, 0x02, 0x0F, 0xA9, 0x9F, 0x72, 0xE2, 0x2C, 0x2B, + 0xB3, 0xDC, 0x66, 0x97, 0x00, 0x40, 0xD0, 0xA4, 0x54, 0x8E, 0x9B, 0x5D, + 0x7B, 0x45, 0x36, 0x26, 0xD6, 0x72, 0x43, 0xEB, 0xCF, 0xC0, 0xEA, 0x0D, + 0xDC, 0xCE, 0x12, 0xE6, 0x7D, 0x38, 0x9F, 0x05, 0x27, 0xA8, 0x97, 0x3E, + 0xE9, 0x51, 0xC6, 0x6C, 0x05, 0x28, 0xC1, 0x02, 0x0F, 0xE9, 0x18, 0x6D, + 0xEC, 0xBD, 0x9C, 0x06, 0xD4, 0xA7, 0x49, 0xF4, 0x54, 0x05, 0x6B, 0x6C, + 0x30, 0xF1, 0xEB, 0x03, 0xD5, 0xEA, 0x3D, 0x6A, 0x76, 0xC2, 0xCB, 0x1A, + 0x28, 0x49, 0x4D, 0x7F, 0x64, 0xE0, 0xFA, 0x2B, 0xDA, 0x73, 0x83, 0x81, + 0xFF, 0x91, 0x03, 0xBD, 0x94, 0xBB, 0xE4, 0xB8, 0x8E, 0x9C, 0x32, 0x63, + 0xCD, 0x9F, 0xBB, 0x68, 0x81, 0xB1, 0x84, 0x5B, 0xAF, 0x36, 0xBF, 0x77, + 0xEE, 0x1D, 0x7F, 0xF7, 0x49, 0x9B, 0x52, 0xEC, 0xD2, 0x77, 0x5A, 0x7D, + 0x91, 0x9D, 0x4D, 0xC2, 0x39, 0x2D, 0xE4, 0xBA, 0x82, 0xF8, 0x6F, 0xF2, + 0x4E, 0x1E, 0x0F, 0x4E, 0xE6, 0x3F, 0x59, 0xA5, 0x23, 0xDC, 0x3D, 0x87, + 0xA8, 0x28, 0x58, 0x28, 0xD1, 0xF1, 0x1B, 0x36, 0xDB, 0x4F, 0xC4, 0xFF, + 0xE1, 0x8C, 0x5B, 0x72, 0x8C, 0xC7, 0x26, 0x03, 0x27, 0xA3, 0x39, 0x0A, + 0x01, 0xAA, 0xC0, 0xB2, 0x31, 0x60, 0x83, 0x22, 0xA1, 0x4F, 0x12, 0x09, + 0x01, 0x11, 0xAF, 0x34, 0xD4, 0xCF, 0xD7, 0xAE, 0x62, 0xD3, 0x05, 0x07, + 0xB4, 0x31, 0x75, 0xE0, 0x0D, 0x6D, 0x57, 0x4F, 0x69, 0x87, 0xF9, 0x57, + 0xA9, 0xBA, 0x15, 0xF6, 0xC8, 0x52, 0x6D, 0xA1, 0xCB, 0x9C, 0x1F, 0xE5, + 0xFC, 0x78, 0xA8, 0x35, 0x9A, 0x9F, 0x41, 0x14, 0xCE, 0xA5, 0xB4, 0xCE, + 0x94, 0x08, 0x1C, 0x09, 0xAD, 0x56, 0xE5, 0xDA, 0xB6, 0x49, 0x9A, 0x4A, + 0xEA, 0x63, 0x18, 0x53, 0x9C, 0x2C, 0x2E, 0xC3 +}; + +static const unsigned char TA148_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA149_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA149_RSA_N[] = { + 0xD9, 0xE7, 0x28, 0x2F, 0x52, 0x3F, 0x36, 0x72, 0x49, 0x88, 0x93, 0x34, + 0xF3, 0xF8, 0x6A, 0x1E, 0x31, 0x54, 0x80, 0x9F, 0xAD, 0x54, 0x41, 0xB5, + 0x47, 0xDF, 0x96, 0xA8, 0xD4, 0xAF, 0x80, 0x2D, 0xB9, 0x0A, 0xCF, 0x75, + 0xFD, 0x89, 0xA5, 0x7D, 0x24, 0xFA, 0xE3, 0x22, 0x0C, 0x2B, 0xBC, 0x95, + 0x17, 0x0B, 0x33, 0xBF, 0x19, 0x4D, 0x41, 0x06, 0x90, 0x00, 0xBD, 0x0C, + 0x4D, 0x10, 0xFE, 0x07, 0xB5, 0xE7, 0x1C, 0x6E, 0x22, 0x55, 0x31, 0x65, + 0x97, 0xBD, 0xD3, 0x17, 0xD2, 0x1E, 0x62, 0xF3, 0xDB, 0xEA, 0x6C, 0x50, + 0x8C, 0x3F, 0x84, 0x0C, 0x96, 0xCF, 0xB7, 0xCB, 0x03, 0xE0, 0xCA, 0x6D, + 0xA1, 0x14, 0x4C, 0x1B, 0x89, 0xDD, 0xED, 0x00, 0xB0, 0x52, 0x7C, 0xAF, + 0x91, 0x6C, 0xB1, 0x38, 0x13, 0xD1, 0xE9, 0x12, 0x08, 0xC0, 0x00, 0xB0, + 0x1C, 0x2B, 0x11, 0xDA, 0x77, 0x70, 0x36, 0x9B, 0xAE, 0xCE, 0x79, 0x87, + 0xDC, 0x82, 0x70, 0xE6, 0x09, 0x74, 0x70, 0x55, 0x69, 0xAF, 0xA3, 0x68, + 0x9F, 0xBF, 0xDD, 0xB6, 0x79, 0xB3, 0xF2, 0x9D, 0x70, 0x29, 0x55, 0xF4, + 0xAB, 0xFF, 0x95, 0x61, 0xF3, 0xC9, 0x40, 0x6F, 0x1D, 0xD1, 0xBE, 0x93, + 0xBB, 0xD3, 0x88, 0x2A, 0xBB, 0x9D, 0xBF, 0x72, 0x5A, 0x56, 0x71, 0x3B, + 0x3F, 0xD4, 0xF3, 0xD1, 0x0A, 0xFE, 0x28, 0xEF, 0xA3, 0xEE, 0xD9, 0x99, + 0xAF, 0x03, 0xD3, 0x8F, 0x60, 0xB7, 0xF2, 0x92, 0xA1, 0xB1, 0xBD, 0x89, + 0x89, 0x1F, 0x30, 0xCD, 0xC3, 0xA6, 0x2E, 0x62, 0x33, 0xAE, 0x16, 0x02, + 0x77, 0x44, 0x5A, 0xE7, 0x81, 0x0A, 0x3C, 0xA7, 0x44, 0x2E, 0x79, 0xB8, + 0x3F, 0x04, 0xBC, 0x5C, 0xA0, 0x87, 0xE1, 0x1B, 0xAF, 0x51, 0x8E, 0xCD, + 0xEC, 0x2C, 0xFA, 0xF8, 0xFE, 0x6D, 0xF0, 0x3A, 0x7C, 0xAA, 0x8B, 0xE4, + 0x67, 0x95, 0x31, 0x8D +}; + +static const unsigned char TA149_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA150_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x08, 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x10, 0x63, 0x65, 0x72, + 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA150_RSA_N[] = { + 0xB7, 0x33, 0xB9, 0x7E, 0xC8, 0x25, 0x4A, 0x8E, 0xB5, 0xDB, 0xB4, 0x28, + 0x1B, 0xAA, 0x57, 0x90, 0xE8, 0xD1, 0x22, 0xD3, 0x64, 0xBA, 0xD3, 0x93, + 0xE8, 0xD4, 0xAC, 0x86, 0x61, 0x40, 0x6A, 0x60, 0x57, 0x68, 0x54, 0x84, + 0x4D, 0xBC, 0x6A, 0x54, 0x02, 0x05, 0xFF, 0xDF, 0x9B, 0x9A, 0x2A, 0xAE, + 0x5D, 0x07, 0x8F, 0x4A, 0xC3, 0x28, 0x7F, 0xEF, 0xFB, 0x2B, 0xFA, 0x79, + 0xF1, 0xC7, 0xAD, 0xF0, 0x10, 0x53, 0x24, 0x90, 0x8B, 0x66, 0xC9, 0xA8, + 0x88, 0xAB, 0xAF, 0x5A, 0xA3, 0x00, 0xE9, 0xBE, 0xBA, 0x46, 0xEE, 0x5B, + 0x73, 0x7B, 0x2C, 0x17, 0x82, 0x81, 0x5E, 0x62, 0x2C, 0xA1, 0x02, 0x65, + 0xB3, 0xBD, 0xC5, 0x2B, 0x00, 0x7E, 0xC4, 0xFC, 0x03, 0x33, 0x57, 0x0D, + 0xED, 0xE2, 0xFA, 0xCE, 0x5D, 0x45, 0xD6, 0x38, 0xCD, 0x35, 0xB6, 0xB2, + 0xC1, 0xD0, 0x9C, 0x81, 0x4A, 0xAA, 0xE4, 0xB2, 0x01, 0x5C, 0x1D, 0x8F, + 0x5F, 0x99, 0xC4, 0xB1, 0xAD, 0xDB, 0x88, 0x21, 0xEB, 0x90, 0x08, 0x82, + 0x80, 0xF3, 0x30, 0xA3, 0x43, 0xE6, 0x90, 0x82, 0xAE, 0x55, 0x28, 0x49, + 0xED, 0x5B, 0xD7, 0xA9, 0x10, 0x38, 0x0E, 0xFE, 0x8F, 0x4C, 0x5B, 0x9B, + 0x46, 0xEA, 0x41, 0xF5, 0xB0, 0x08, 0x74, 0xC3, 0xD0, 0x88, 0x33, 0xB6, + 0x7C, 0xD7, 0x74, 0xDF, 0xDC, 0x84, 0xD1, 0x43, 0x0E, 0x75, 0x39, 0xA1, + 0x25, 0x40, 0x28, 0xEA, 0x78, 0xCB, 0x0E, 0x2C, 0x2E, 0x39, 0x9D, 0x8C, + 0x8B, 0x6E, 0x16, 0x1C, 0x2F, 0x26, 0x82, 0x10, 0xE2, 0xE3, 0x65, 0x94, + 0x0A, 0x04, 0xC0, 0x5E, 0xF7, 0x5D, 0x5B, 0xF8, 0x10, 0xE2, 0xD0, 0xBA, + 0x7A, 0x4B, 0xFB, 0xDE, 0x37, 0x00, 0x00, 0x1A, 0x5B, 0x28, 0xE3, 0xD2, + 0x9C, 0x73, 0x3E, 0x32, 0x87, 0x98, 0xA1, 0xC9, 0x51, 0x2F, 0xD7, 0xDE, + 0xAC, 0x33, 0xB3, 0x4F +}; + +static const unsigned char TA150_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA151_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA151_EC_Q[] = { + 0x04, 0xD4, 0xBC, 0x3D, 0x02, 0x42, 0x75, 0x41, 0x13, 0x23, 0xCD, 0x80, + 0x04, 0x86, 0x02, 0x51, 0x2F, 0x6A, 0xA8, 0x81, 0x62, 0x0B, 0x65, 0xCC, + 0xF6, 0xCA, 0x9D, 0x1E, 0x6F, 0x4A, 0x66, 0x51, 0xA2, 0x03, 0xD9, 0x9D, + 0x91, 0xFA, 0xB6, 0x16, 0xB1, 0x8C, 0x6E, 0xDE, 0x7C, 0xCD, 0xDB, 0x79, + 0xA6, 0x2F, 0xCE, 0xBB, 0xCE, 0x71, 0x2F, 0xE5, 0xA5, 0xAB, 0x28, 0xEC, + 0x63, 0x04, 0x66, 0x99, 0xF8, 0xFA, 0xF2, 0x93, 0x10, 0x05, 0xE1, 0x81, + 0x28, 0x42, 0xE3, 0xC6, 0x68, 0xF4, 0xE6, 0x1B, 0x84, 0x60, 0x4A, 0x89, + 0xAF, 0xED, 0x79, 0x0F, 0x3B, 0xCE, 0xF1, 0xF6, 0x44, 0xF5, 0x01, 0x78, + 0xC0 +}; + +static const unsigned char TA152_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x49, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x11, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x6C, + 0x61, 0x6E, 0x64, 0x20, 0x4F, 0x79, 0x6A, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x32 +}; + +static const unsigned char TA152_RSA_N[] = { + 0xB2, 0xD0, 0x3F, 0x07, 0xBC, 0xE2, 0x7B, 0xD0, 0x6B, 0x99, 0xF8, 0xE2, + 0x77, 0x69, 0xE7, 0xCE, 0x9D, 0xA4, 0x03, 0xBC, 0x82, 0x6D, 0xA1, 0xFE, + 0x81, 0x65, 0x1F, 0x4C, 0x27, 0xAC, 0x8E, 0x00, 0xBA, 0x16, 0x7B, 0xEB, + 0x30, 0x6A, 0x00, 0xC0, 0xB3, 0x74, 0x68, 0x7E, 0xB2, 0xAF, 0xC7, 0xD5, + 0x62, 0xB3, 0x7A, 0x3F, 0x50, 0xCA, 0x8C, 0x36, 0x44, 0x24, 0x63, 0xD2, + 0x36, 0xE9, 0x0C, 0x85, 0xF6, 0x43, 0x76, 0xD5, 0x4C, 0xA1, 0x60, 0x72, + 0x67, 0xE2, 0x28, 0x33, 0xA5, 0xCB, 0x31, 0xB8, 0x3A, 0x22, 0x23, 0x34, + 0xB8, 0x7D, 0xBD, 0x56, 0x22, 0x40, 0x9D, 0xEA, 0xF4, 0x7B, 0x03, 0xAD, + 0x68, 0xFC, 0xB2, 0x81, 0x4F, 0x98, 0xD0, 0x74, 0xEA, 0x8D, 0xE5, 0x7D, + 0xCD, 0x63, 0xC3, 0xA3, 0xF6, 0xDE, 0x92, 0xC2, 0x58, 0x19, 0xE0, 0x96, + 0xBB, 0xC5, 0xC4, 0xA9, 0x3D, 0xA5, 0x74, 0x96, 0xFE, 0xAF, 0xF9, 0x89, + 0xAA, 0xBD, 0x95, 0x17, 0x54, 0xD8, 0x78, 0x44, 0xF1, 0x0C, 0x77, 0x15, + 0x92, 0xE0, 0x98, 0x42, 0xA7, 0xA4, 0xD6, 0xAA, 0x20, 0x92, 0xCD, 0xC1, + 0xA0, 0xB3, 0x96, 0xB2, 0x3A, 0x84, 0x42, 0x8D, 0x7D, 0xD5, 0x95, 0xE4, + 0xD6, 0xDB, 0xE9, 0x62, 0xC4, 0x58, 0xB3, 0x79, 0xC5, 0x8C, 0xD3, 0x35, + 0x33, 0x83, 0x9F, 0x75, 0xA1, 0x52, 0x27, 0x61, 0x38, 0xF1, 0x59, 0x3D, + 0x8E, 0x50, 0xE0, 0xBD, 0x79, 0x3C, 0xE7, 0x6C, 0x96, 0xFE, 0x5E, 0xD9, + 0x02, 0x65, 0xB4, 0x8E, 0x5C, 0xD0, 0x11, 0x34, 0xDF, 0x5D, 0xBF, 0x52, + 0xA7, 0x81, 0x00, 0xC3, 0x7F, 0x99, 0x45, 0x99, 0x15, 0xD5, 0x17, 0xC8, + 0x0A, 0x53, 0xEC, 0x63, 0xF3, 0x99, 0x7D, 0xCC, 0x69, 0x12, 0x86, 0xC2, + 0x17, 0xF0, 0x01, 0x9E, 0xBF, 0x84, 0xBC, 0xD1, 0x52, 0xCB, 0x1B, 0x92, + 0x66, 0xCE, 0xA4, 0x53, 0xE5, 0xA1, 0xBF, 0xC4, 0xDB, 0x09, 0xD6, 0xE6, + 0x89, 0x56, 0x2B, 0xC8, 0xE3, 0x7C, 0xDE, 0xE3, 0xFF, 0x89, 0xE5, 0x35, + 0x6E, 0x28, 0xE8, 0x6C, 0x0B, 0x23, 0x51, 0xA9, 0x25, 0x05, 0xEB, 0x48, + 0xF8, 0xDD, 0xB1, 0xCA, 0xFA, 0x6C, 0x08, 0x51, 0xEF, 0xB7, 0x18, 0x6C, + 0x44, 0xCA, 0x26, 0xE1, 0x73, 0xC6, 0x89, 0x06, 0x81, 0xE5, 0x8A, 0xAC, + 0xB0, 0xE2, 0x29, 0xC6, 0xB9, 0x24, 0xB3, 0x6B, 0x44, 0x11, 0xF4, 0xA5, + 0x43, 0xC2, 0x4C, 0x43, 0xE5, 0x70, 0x36, 0x8C, 0xB6, 0x33, 0x57, 0x7A, + 0x95, 0x2E, 0x82, 0xA0, 0xF4, 0x5C, 0x10, 0xB3, 0x61, 0x83, 0xF6, 0x02, + 0x05, 0x86, 0x2E, 0x7C, 0x2D, 0x6C, 0xDC, 0x03, 0x46, 0x6E, 0x35, 0x93, + 0xD5, 0x7A, 0x95, 0x2F, 0xDE, 0x20, 0xD8, 0x5B, 0x7E, 0x94, 0x90, 0x04, + 0x6A, 0xBA, 0x59, 0x3D, 0x04, 0x05, 0x75, 0x9D, 0x37, 0xA2, 0x0E, 0x2E, + 0x3D, 0xEB, 0xC1, 0xA4, 0x52, 0x83, 0xFE, 0xD0, 0x6B, 0xD4, 0x66, 0x8E, + 0xDC, 0xC6, 0xE9, 0x12, 0x4E, 0x1D, 0x2A, 0x57, 0xAA, 0x10, 0xBC, 0x7C, + 0x5E, 0x82, 0x7D, 0xA6, 0xA6, 0xC9, 0xF2, 0x2D, 0xB9, 0xF5, 0x17, 0x27, + 0xAD, 0xD1, 0x0E, 0x89, 0x54, 0x2B, 0x95, 0xFA, 0xC0, 0xAD, 0x1D, 0x98, + 0x14, 0x78, 0x33, 0x42, 0x86, 0x0A, 0xA9, 0x73, 0xB5, 0xFB, 0x74, 0x0D, + 0xB7, 0x1B, 0x30, 0x19, 0xC4, 0x5A, 0x0E, 0x1C, 0x27, 0xB7, 0xDA, 0x18, + 0xD0, 0xFF, 0x8A, 0xC8, 0x05, 0xBA, 0xF1, 0xAA, 0x1C, 0xA2, 0x37, 0xB7, + 0xE6, 0x48, 0xA4, 0x46, 0x2C, 0x94, 0xEA, 0xA8, 0x76, 0x62, 0x47, 0x8B, + 0x10, 0x53, 0x07, 0x48, 0x57, 0x6C, 0xE2, 0x92, 0x4D, 0xB6, 0xAE, 0x05, + 0xCB, 0xDC, 0xC1, 0x4A, 0x5E, 0x8F, 0xAC, 0x3D, 0x19, 0x4E, 0xC2, 0xED, + 0x60, 0x75, 0x2B, 0xDB, 0xC1, 0xCA, 0x42, 0xD5 +}; + +static const unsigned char TA152_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA153_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x35 +}; + +static const unsigned char TA153_EC_Q[] = { + 0x04, 0x0B, 0x50, 0x74, 0x8D, 0x64, 0x32, 0x99, 0x99, 0xB3, 0xD2, 0x60, + 0x08, 0xB8, 0x22, 0x8E, 0x46, 0x74, 0x2C, 0x78, 0xC0, 0x2B, 0x44, 0x2D, + 0x6D, 0x5F, 0x1D, 0xC9, 0xAE, 0x4B, 0x52, 0x20, 0x83, 0x3D, 0xB8, 0x14, + 0x6D, 0x53, 0x87, 0x60, 0x9E, 0x5F, 0x6C, 0x85, 0xDB, 0x06, 0x14, 0x95, + 0xE0, 0xC7, 0x28, 0xFF, 0x9D, 0x5F, 0xE4, 0xAA, 0xF1, 0xB3, 0x8B, 0x6D, + 0xED, 0x4F, 0x2F, 0x4B, 0xC9, 0x4A, 0x94, 0x91, 0x64, 0x75, 0xFE, 0x01, + 0xEC, 0xC1, 0xD8, 0xEB, 0x7A, 0x94, 0x78, 0x56, 0x18, 0x43, 0x5F, 0x6B, + 0x81, 0xCB, 0xF6, 0xBC, 0xDA, 0xB4, 0x0C, 0xB6, 0x29, 0x93, 0x08, 0x69, + 0x8F +}; + +static const unsigned char TA154_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, + 0x36 +}; + +static const unsigned char TA154_RSA_N[] = { + 0x93, 0xBE, 0xD5, 0x36, 0x52, 0x75, 0xD8, 0x01, 0x23, 0xA0, 0x1C, 0x47, + 0x42, 0x49, 0xEE, 0x63, 0xB6, 0xB7, 0x21, 0xFD, 0xC4, 0x95, 0xD5, 0x48, + 0x2B, 0x26, 0x7C, 0x14, 0x53, 0x10, 0xDA, 0x79, 0xFD, 0x2B, 0xB7, 0x2D, + 0xA4, 0xD4, 0x2C, 0xFA, 0xEA, 0x32, 0xDD, 0x49, 0xC2, 0xB9, 0xBD, 0x0F, + 0x48, 0x3D, 0x7B, 0x5A, 0x98, 0x54, 0xAF, 0x9E, 0x5D, 0x31, 0x74, 0x4F, + 0x07, 0xFC, 0x50, 0x21, 0xDD, 0xA4, 0xCF, 0x68, 0x4F, 0x1B, 0x12, 0x63, + 0x6D, 0x25, 0x99, 0x4C, 0x2A, 0x99, 0xF3, 0x48, 0x30, 0x61, 0xFA, 0x81, + 0x7C, 0x1E, 0xA7, 0x08, 0x4A, 0xDC, 0x3E, 0x2B, 0x1C, 0x1F, 0x18, 0x4C, + 0x71, 0xAA, 0x35, 0x8C, 0xAD, 0xF8, 0x6E, 0xE8, 0x3B, 0x4A, 0xD9, 0xE5, + 0x94, 0x02, 0xD6, 0x89, 0x84, 0x13, 0xAA, 0x6D, 0xC8, 0x4F, 0x33, 0xCC, + 0x50, 0x96, 0x37, 0x92, 0x33, 0xDC, 0x5F, 0x88, 0xE7, 0x9F, 0x54, 0xD9, + 0x48, 0xF0, 0x98, 0x43, 0xD6, 0x66, 0xFD, 0x9F, 0x17, 0x38, 0x43, 0xC5, + 0x01, 0x51, 0x0B, 0xD7, 0xE3, 0x23, 0x0F, 0x14, 0x5D, 0x5B, 0x14, 0xE7, + 0x4B, 0xBE, 0xDD, 0xF4, 0xC8, 0xDA, 0x03, 0x37, 0xD1, 0xD6, 0x39, 0xA1, + 0x21, 0x51, 0x30, 0x83, 0xB0, 0x6D, 0xD7, 0x30, 0x4E, 0x96, 0x5B, 0x91, + 0xF0, 0x70, 0x24, 0xAB, 0xBF, 0x45, 0x81, 0x64, 0x43, 0x0D, 0xBD, 0x21, + 0x3A, 0x2F, 0x3C, 0xE9, 0x9E, 0x0D, 0xCB, 0x20, 0xB5, 0x42, 0x27, 0xCC, + 0xDA, 0x6F, 0x9B, 0xEE, 0x64, 0x30, 0x90, 0x39, 0xCD, 0x93, 0x65, 0x81, + 0x21, 0x31, 0xB5, 0x23, 0x50, 0x33, 0x37, 0x22, 0xE3, 0x38, 0xED, 0xF8, + 0x31, 0x30, 0xCC, 0x45, 0xFE, 0x62, 0xF9, 0xD1, 0x5D, 0x32, 0x79, 0x42, + 0x87, 0xDF, 0x6A, 0xCC, 0x56, 0x19, 0x40, 0x4D, 0xCE, 0xAA, 0xBB, 0xF9, + 0xB5, 0x76, 0x49, 0x94, 0xF1, 0x27, 0xF8, 0x91, 0xA5, 0x83, 0xE5, 0x06, + 0xB3, 0x63, 0x0E, 0x80, 0xDC, 0xE0, 0x12, 0x55, 0x80, 0xA6, 0x3B, 0x66, + 0xB4, 0x39, 0x87, 0x2D, 0xC8, 0xF0, 0xD0, 0xD1, 0x14, 0xE9, 0xE4, 0x0D, + 0x4D, 0x0E, 0xF6, 0x5D, 0x57, 0x72, 0xC5, 0x3B, 0x1C, 0x47, 0x56, 0x9D, + 0xE2, 0xD5, 0xFB, 0x81, 0x61, 0x8C, 0xCC, 0x4D, 0x80, 0x90, 0x34, 0x5B, + 0xB7, 0xD7, 0x14, 0x75, 0xDC, 0xD8, 0x04, 0x48, 0x9F, 0xC0, 0xC1, 0x28, + 0x88, 0xB4, 0xE9, 0x1C, 0xCA, 0xA7, 0xB1, 0xF1, 0x56, 0xB7, 0x7B, 0x49, + 0x4C, 0x59, 0xE5, 0x20, 0x15, 0xA8, 0x84, 0x02, 0x29, 0xFA, 0x38, 0x94, + 0x69, 0x9A, 0x49, 0x06, 0x8F, 0xCD, 0x1F, 0x79, 0x14, 0x17, 0x12, 0x0C, + 0x83, 0x7A, 0xDE, 0x1F, 0xB1, 0x97, 0xEE, 0xF9, 0x97, 0x78, 0x28, 0xA4, + 0xC8, 0x44, 0x92, 0xE9, 0x7D, 0x26, 0x05, 0xA6, 0x58, 0x72, 0x9B, 0x79, + 0x13, 0xD8, 0x11, 0x5F, 0xAE, 0xC5, 0x38, 0x62, 0x34, 0x68, 0xB2, 0x86, + 0x30, 0x8E, 0xF8, 0x90, 0x61, 0x9E, 0x32, 0x6C, 0xF5, 0x07, 0x36, 0xCD, + 0xA2, 0x4C, 0x6E, 0xEC, 0x8A, 0x36, 0xED, 0xF2, 0xE6, 0x99, 0x15, 0x44, + 0x70, 0xC3, 0x7C, 0xBC, 0x9C, 0x39, 0xC0, 0xB4, 0xE1, 0x6B, 0xF7, 0x83, + 0x25, 0x23, 0x57, 0xD9, 0x12, 0x80, 0xE5, 0x49, 0xF0, 0x75, 0x0F, 0xEF, + 0x8D, 0xEB, 0x1C, 0x9B, 0x54, 0x28, 0xB4, 0x21, 0x3C, 0xFC, 0x7C, 0x0A, + 0xFF, 0xEF, 0x7B, 0x6B, 0x75, 0xFF, 0x8B, 0x1D, 0xA0, 0x19, 0x05, 0xAB, + 0xFA, 0xF8, 0x2B, 0x81, 0x42, 0xE8, 0x38, 0xBA, 0xBB, 0xFB, 0xAA, 0xFD, + 0x3D, 0xE0, 0xF3, 0xCA, 0xDF, 0x4E, 0x97, 0x97, 0x29, 0xED, 0xF3, 0x18, + 0x56, 0xE9, 0xA5, 0x96, 0xAC, 0xBD, 0xC3, 0x90, 0x98, 0xB2, 0xE0, 0xF9, + 0xA2, 0xD4, 0xA6, 0x47, 0x43, 0x7C, 0x6D, 0xCF +}; + +static const unsigned char TA154_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA155_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x12, 0x48, 0x69, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA155_RSA_N[] = { + 0xF4, 0x1E, 0x7F, 0x52, 0x73, 0x32, 0x0C, 0x73, 0xE4, 0xBD, 0x13, 0x74, + 0xA3, 0xD4, 0x30, 0xA8, 0xD0, 0xAE, 0x4B, 0xD8, 0xB6, 0xDF, 0x75, 0x47, + 0x66, 0xF4, 0x7C, 0xE7, 0x39, 0x04, 0x1E, 0x6A, 0x70, 0x20, 0xD2, 0x5A, + 0x47, 0x72, 0x67, 0x55, 0xF4, 0xA5, 0xE8, 0x9D, 0xD5, 0x1E, 0x21, 0xA1, + 0xF0, 0x67, 0xBA, 0xCC, 0x21, 0x68, 0xBE, 0x44, 0x53, 0xBF, 0x8D, 0xF9, + 0xE2, 0xDC, 0x2F, 0x55, 0xC8, 0x37, 0x3F, 0x1F, 0xA4, 0xC0, 0x9C, 0xB3, + 0xE4, 0x77, 0x5C, 0xA0, 0x46, 0xFE, 0x77, 0xFA, 0x1A, 0xA0, 0x38, 0xEA, + 0xED, 0x9A, 0x72, 0xDE, 0x2B, 0xBD, 0x94, 0x57, 0x3A, 0xBA, 0xEC, 0x79, + 0xE7, 0x5F, 0x7D, 0x42, 0x64, 0x39, 0x7A, 0x26, 0x36, 0xF7, 0x24, 0xF0, + 0xD5, 0x2F, 0xBA, 0x95, 0x98, 0x11, 0x66, 0xAD, 0x97, 0x35, 0xD6, 0x75, + 0x01, 0x80, 0xE0, 0xAF, 0xF4, 0x84, 0x61, 0x8C, 0x0D, 0x1E, 0x5F, 0x7C, + 0x87, 0x96, 0x5E, 0x41, 0xAF, 0xEB, 0x87, 0xEA, 0xF8, 0x5D, 0xF1, 0x2E, + 0x88, 0x05, 0x3E, 0x4C, 0x22, 0xBB, 0xDA, 0x1F, 0x2A, 0xDD, 0x52, 0x46, + 0x64, 0x39, 0xF3, 0x42, 0xCE, 0xD9, 0x9E, 0x0C, 0xB3, 0xB0, 0x77, 0x97, + 0x64, 0x9C, 0xC0, 0xF4, 0xA3, 0x2E, 0x1F, 0x95, 0x07, 0xB0, 0x17, 0xDF, + 0x30, 0xDB, 0x00, 0x18, 0x96, 0x4C, 0xA1, 0x81, 0x4B, 0xDD, 0x04, 0x6D, + 0x53, 0xA3, 0x3D, 0xFC, 0x07, 0xAC, 0xD4, 0xC5, 0x37, 0x82, 0xEB, 0xE4, + 0x95, 0x08, 0x19, 0x28, 0x82, 0xD2, 0x42, 0x3A, 0xA3, 0xD8, 0x53, 0xEC, + 0x79, 0x89, 0x60, 0x48, 0x60, 0xC8, 0x72, 0x92, 0x50, 0xDC, 0x03, 0x8F, + 0x83, 0x3F, 0xB2, 0x42, 0x57, 0x5A, 0xDB, 0x6A, 0xE9, 0x11, 0x97, 0xDD, + 0x85, 0x28, 0xBC, 0x30, 0x4C, 0xAB, 0xE3, 0xC2, 0xB1, 0x45, 0x44, 0x47, + 0x1F, 0xE0, 0x8A, 0x16, 0x07, 0x96, 0xD2, 0x21, 0x0F, 0x53, 0xC0, 0xED, + 0xA9, 0x7E, 0xD4, 0x4E, 0xEC, 0x9B, 0x09, 0xEC, 0xAF, 0x42, 0xAC, 0x30, + 0xD6, 0xBF, 0xD1, 0x10, 0x45, 0xE0, 0xA6, 0x16, 0xB2, 0xA5, 0xC5, 0xD3, + 0x4F, 0x73, 0x94, 0x33, 0x71, 0x02, 0xA1, 0x6A, 0xA3, 0xD6, 0x33, 0x97, + 0x4F, 0x21, 0x63, 0x1E, 0x5B, 0x8F, 0xD9, 0xC1, 0x5E, 0x45, 0x71, 0x77, + 0x0F, 0x81, 0x5D, 0x5F, 0x21, 0x9A, 0xAD, 0x83, 0xCC, 0xFA, 0x5E, 0xD6, + 0x8D, 0x23, 0x5F, 0x1B, 0x3D, 0x41, 0xAF, 0x20, 0x75, 0x66, 0x5A, 0x4A, + 0xF6, 0x9F, 0xFB, 0xAB, 0x18, 0xF7, 0x71, 0xC0, 0xB6, 0x1D, 0x31, 0xEC, + 0x3B, 0x20, 0xEB, 0xCB, 0xE2, 0xB8, 0xF5, 0xAE, 0x92, 0xB2, 0xF7, 0xE1, + 0x84, 0x4B, 0xF2, 0xA2, 0xF2, 0x93, 0x9A, 0x22, 0x9E, 0xD3, 0x14, 0x6F, + 0x36, 0x54, 0xBD, 0x1F, 0x5E, 0x59, 0x15, 0xB9, 0x73, 0xA8, 0xC1, 0x7C, + 0x6F, 0x7B, 0x62, 0xE9, 0x16, 0x6C, 0x47, 0x5A, 0x65, 0xF3, 0x0E, 0x11, + 0x9B, 0x46, 0xD9, 0xFD, 0x6D, 0xDC, 0xD6, 0x9C, 0xC0, 0xB4, 0x7D, 0xA5, + 0xB0, 0xDD, 0x3F, 0x56, 0x6F, 0xA1, 0xF9, 0xF6, 0xE4, 0x12, 0x48, 0xFD, + 0x06, 0x7F, 0x12, 0x57, 0xB6, 0xA9, 0x23, 0x4F, 0x5B, 0x03, 0xC3, 0xE0, + 0x71, 0x2A, 0x23, 0xB7, 0xF7, 0xB0, 0xB1, 0x3B, 0xBC, 0x98, 0xBD, 0xD6, + 0x98, 0xA8, 0x0C, 0x6B, 0xF6, 0x8E, 0x12, 0x67, 0xA6, 0xF2, 0xB2, 0x58, + 0xE4, 0x02, 0x09, 0x13, 0x3C, 0xA9, 0xBB, 0x10, 0xB4, 0xD2, 0x30, 0x45, + 0xF1, 0xEC, 0xF7, 0x00, 0x11, 0xDF, 0x65, 0xF8, 0xDC, 0x2B, 0x43, 0x55, + 0xBF, 0x16, 0x97, 0xC4, 0x0F, 0xD5, 0x2C, 0x61, 0x84, 0xAA, 0x72, 0x86, + 0xFE, 0xE6, 0x3A, 0x7E, 0xC2, 0x3F, 0x7D, 0xEE, 0xFC, 0x2F, 0x14, 0x3E, + 0xE6, 0x85, 0xDD, 0x50, 0x6F, 0xB7, 0x49, 0xED +}; + +static const unsigned char TA155_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA156_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x30, 0x30, 0x2E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x27, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x61, + 0x6E, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0C, 0x43, 0x46, 0x43, 0x41, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA156_RSA_N[] = { + 0xD7, 0x5D, 0x6B, 0xCD, 0x10, 0x3F, 0x1F, 0x05, 0x59, 0xD5, 0x05, 0x4D, + 0x37, 0xB1, 0x0E, 0xEC, 0x98, 0x2B, 0x8E, 0x15, 0x1D, 0xFA, 0x93, 0x4B, + 0x17, 0x82, 0x21, 0x71, 0x10, 0x52, 0xD7, 0x51, 0x64, 0x70, 0x16, 0xC2, + 0x55, 0x69, 0x4D, 0x8E, 0x15, 0x6D, 0x9F, 0xBF, 0x0C, 0x1B, 0xC2, 0xE0, + 0xA3, 0x67, 0xD6, 0x0C, 0xAC, 0xCF, 0x22, 0xAE, 0xAF, 0x77, 0x54, 0x2A, + 0x4B, 0x4C, 0x8A, 0x53, 0x52, 0x7A, 0xC3, 0xEE, 0x2E, 0xDE, 0xB3, 0x71, + 0x25, 0xC1, 0xE9, 0x5D, 0x3D, 0xEE, 0xA1, 0x2F, 0xA3, 0xF7, 0x2A, 0x3C, + 0xC9, 0x23, 0x1D, 0x6A, 0xAB, 0x1D, 0xA1, 0xA7, 0xF1, 0xF3, 0xEC, 0xA0, + 0xD5, 0x44, 0xCF, 0x15, 0xCF, 0x72, 0x2F, 0x1D, 0x63, 0x97, 0xE8, 0x99, + 0xF9, 0xFD, 0x93, 0xA4, 0x54, 0x80, 0x4C, 0x52, 0xD4, 0x52, 0xAB, 0x2E, + 0x49, 0xDF, 0x90, 0xCD, 0xB8, 0x5F, 0xBE, 0x3F, 0xDE, 0xA1, 0xCA, 0x4D, + 0x20, 0xD4, 0x25, 0xE8, 0x84, 0x29, 0x53, 0xB7, 0xB1, 0x88, 0x1F, 0xFF, + 0xFA, 0xDA, 0x90, 0x9F, 0x0A, 0xA9, 0x2D, 0x41, 0x3F, 0xB1, 0xF1, 0x18, + 0x29, 0xEE, 0x16, 0x59, 0x2C, 0x34, 0x49, 0x1A, 0xA8, 0x06, 0xD7, 0xA8, + 0x88, 0xD2, 0x03, 0x72, 0x7A, 0x32, 0xE2, 0xEA, 0x68, 0x4D, 0x6E, 0x2C, + 0x96, 0x65, 0x7B, 0xCA, 0x59, 0xFA, 0xF2, 0xE2, 0xDD, 0xEE, 0x30, 0x2C, + 0xFB, 0xCC, 0x46, 0xAC, 0xC4, 0x63, 0xEB, 0x6F, 0x7F, 0x36, 0x2B, 0x34, + 0x73, 0x12, 0x94, 0x7F, 0xDF, 0xCC, 0x26, 0x9E, 0xF1, 0x72, 0x5D, 0x50, + 0x65, 0x59, 0x8F, 0x69, 0xB3, 0x87, 0x5E, 0x32, 0x6F, 0xC3, 0x18, 0x8A, + 0xB5, 0x95, 0x8F, 0xB0, 0x7A, 0x37, 0xDE, 0x5A, 0x45, 0x3B, 0xC7, 0x36, + 0xE1, 0xEF, 0x67, 0xD1, 0x39, 0xD3, 0x97, 0x5B, 0x73, 0x62, 0x19, 0x48, + 0x2D, 0x87, 0x1C, 0x06, 0xFB, 0x74, 0x98, 0x20, 0x49, 0x73, 0xF0, 0x05, + 0xD2, 0x1B, 0xB1, 0xA0, 0xA3, 0xB7, 0x1B, 0x70, 0xD3, 0x88, 0x69, 0xB9, + 0x5A, 0xD6, 0x38, 0xF4, 0x62, 0xDC, 0x25, 0x8B, 0x78, 0xBF, 0xF8, 0xE8, + 0x7E, 0xB8, 0x5C, 0xC9, 0x95, 0x4F, 0x5F, 0xA7, 0x2D, 0xB9, 0x20, 0x6B, + 0xCF, 0x6B, 0xDD, 0xF5, 0x0D, 0xF4, 0x82, 0xB7, 0xF4, 0xB2, 0x66, 0x2E, + 0x10, 0x28, 0xF6, 0x97, 0x5A, 0x7B, 0x96, 0x16, 0x8F, 0x01, 0x19, 0x2D, + 0x6C, 0x6E, 0x7F, 0x39, 0x58, 0x06, 0x64, 0x83, 0x01, 0x83, 0x83, 0xC3, + 0x4D, 0x92, 0xDD, 0x32, 0xC6, 0x87, 0xA4, 0x37, 0xE9, 0x16, 0xCE, 0xAA, + 0x2D, 0x68, 0xAF, 0x0A, 0x81, 0x65, 0x3A, 0x70, 0xC1, 0x9B, 0xAD, 0x4D, + 0x6D, 0x54, 0xCA, 0x2A, 0x2D, 0x4B, 0x85, 0x1B, 0xB3, 0x80, 0xE6, 0x70, + 0x45, 0x0D, 0x6B, 0x5E, 0x35, 0xF0, 0x7F, 0x3B, 0xB8, 0x9C, 0xE4, 0x04, + 0x70, 0x89, 0x12, 0x25, 0x93, 0xDA, 0x0A, 0x99, 0x22, 0x60, 0x6A, 0x63, + 0x60, 0x4E, 0x76, 0x06, 0x98, 0x4E, 0xBD, 0x83, 0xAD, 0x1D, 0x58, 0x8A, + 0x25, 0x85, 0xD2, 0xC7, 0x65, 0x1E, 0x2D, 0x8E, 0xC6, 0xDF, 0xB6, 0xC6, + 0xE1, 0x7F, 0x8A, 0x04, 0x21, 0x15, 0x29, 0x74, 0xF0, 0x3E, 0x9C, 0x90, + 0x9D, 0x0C, 0x2E, 0xF1, 0x8A, 0x3E, 0x5A, 0xAA, 0x0C, 0x09, 0x1E, 0xC7, + 0xD5, 0x3C, 0xA3, 0xED, 0x97, 0xC3, 0x1E, 0x34, 0xFA, 0x38, 0xF9, 0x08, + 0x0E, 0xE3, 0xC0, 0x5D, 0x2B, 0x83, 0xD1, 0x56, 0x6A, 0xC9, 0xB6, 0xA8, + 0x54, 0x53, 0x2E, 0x78, 0x32, 0x67, 0x3D, 0x82, 0x7F, 0x74, 0xD0, 0xFB, + 0xE1, 0xB6, 0x05, 0x60, 0xB9, 0x70, 0xDB, 0x8E, 0x0B, 0xF9, 0x13, 0x58, + 0x6F, 0x71, 0x60, 0x10, 0x52, 0x10, 0xB9, 0xC1, 0x41, 0x09, 0xEF, 0x72, + 0x1F, 0x67, 0x31, 0x78, 0xFF, 0x96, 0x05, 0x8D +}; + +static const unsigned char TA156_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA157_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x54, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x05, 0x4D, 0x69, 0x6C, 0x61, 0x6E, 0x31, 0x23, 0x30, 0x21, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x1A, 0x41, 0x63, 0x74, 0x61, 0x6C, 0x69, + 0x73, 0x20, 0x53, 0x2E, 0x70, 0x2E, 0x41, 0x2E, 0x2F, 0x30, 0x33, 0x33, + 0x35, 0x38, 0x35, 0x32, 0x30, 0x39, 0x36, 0x37, 0x31, 0x27, 0x30, 0x25, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x41, 0x63, 0x74, 0x61, 0x6C, + 0x69, 0x73, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA157_RSA_N[] = { + 0xA7, 0xC6, 0xC4, 0xA5, 0x29, 0xA4, 0x2C, 0xEF, 0xE5, 0x18, 0xC5, 0xB0, + 0x50, 0xA3, 0x6F, 0x51, 0x3B, 0x9F, 0x0A, 0x5A, 0xC9, 0xC2, 0x48, 0x38, + 0x0A, 0xC2, 0x1C, 0xA0, 0x18, 0x7F, 0x91, 0xB5, 0x87, 0xB9, 0x40, 0x3F, + 0xDD, 0x1D, 0x68, 0x1F, 0x08, 0x83, 0xD5, 0x2D, 0x1E, 0x88, 0xA0, 0xF8, + 0x8F, 0x56, 0x8F, 0x6D, 0x99, 0x02, 0x92, 0x90, 0x16, 0xD5, 0x5F, 0x08, + 0x6C, 0x89, 0xD7, 0xE1, 0xAC, 0xBC, 0x20, 0xC2, 0xB1, 0xE0, 0x83, 0x51, + 0x8A, 0x69, 0x4D, 0x00, 0x96, 0x5A, 0x6F, 0x2F, 0xC0, 0x44, 0x7E, 0xA3, + 0x0E, 0xE4, 0x91, 0xCD, 0x58, 0xEE, 0xDC, 0xFB, 0xC7, 0x1E, 0x45, 0x47, + 0xDD, 0x27, 0xB9, 0x08, 0x01, 0x9F, 0xA6, 0x21, 0x1D, 0xF5, 0x41, 0x2D, + 0x2F, 0x4C, 0xFD, 0x28, 0xAD, 0xE0, 0x8A, 0xAD, 0x22, 0xB4, 0x56, 0x65, + 0x8E, 0x86, 0x54, 0x8F, 0x93, 0x43, 0x29, 0xDE, 0x39, 0x46, 0x78, 0xA3, + 0x30, 0x23, 0xBA, 0xCD, 0xF0, 0x7D, 0x13, 0x57, 0xC0, 0x5D, 0xD2, 0x83, + 0x6B, 0x48, 0x4C, 0xC4, 0xAB, 0x9F, 0x80, 0x5A, 0x5B, 0x3A, 0xBD, 0xC9, + 0xA7, 0x22, 0x3F, 0x80, 0x27, 0x33, 0x5B, 0x0E, 0xB7, 0x8A, 0x0C, 0x5D, + 0x07, 0x37, 0x08, 0xCB, 0x6C, 0xD2, 0x7A, 0x47, 0x22, 0x44, 0x35, 0xC5, + 0xCC, 0xCC, 0x2E, 0x8E, 0xDD, 0x2A, 0xED, 0xB7, 0x7D, 0x66, 0x0D, 0x5F, + 0x61, 0x51, 0x22, 0x55, 0x1B, 0xE3, 0x46, 0xE3, 0xE3, 0x3D, 0xD0, 0x35, + 0x62, 0x9A, 0xDB, 0xAF, 0x14, 0xC8, 0x5B, 0xA1, 0xCC, 0x89, 0x1B, 0xE1, + 0x30, 0x26, 0xFC, 0xA0, 0x9B, 0x1F, 0x81, 0xA7, 0x47, 0x1F, 0x04, 0xEB, + 0xA3, 0x39, 0x92, 0x06, 0x9F, 0x99, 0xD3, 0xBF, 0xD3, 0xEA, 0x4F, 0x50, + 0x9C, 0x19, 0xFE, 0x96, 0x87, 0x1E, 0x3C, 0x65, 0xF6, 0xA3, 0x18, 0x24, + 0x83, 0x86, 0x10, 0xE7, 0x54, 0x3E, 0xA8, 0x3A, 0x76, 0x24, 0x4F, 0x81, + 0x21, 0xC5, 0xE3, 0x0F, 0x02, 0xF8, 0x93, 0x94, 0x47, 0x20, 0xBB, 0xFE, + 0xD4, 0x0E, 0xD3, 0x68, 0xB9, 0xDD, 0xC4, 0x7A, 0x84, 0x82, 0xE3, 0x53, + 0x54, 0x79, 0xDD, 0xDB, 0x9C, 0xD2, 0xF2, 0x07, 0x9B, 0x2E, 0xB6, 0xBC, + 0x3E, 0xED, 0x85, 0x6D, 0xEF, 0x25, 0x11, 0xF2, 0x97, 0x1A, 0x42, 0x61, + 0xF7, 0x4A, 0x97, 0xE8, 0x8B, 0xB1, 0x10, 0x07, 0xFA, 0x65, 0x81, 0xB2, + 0xA2, 0x39, 0xCF, 0xF7, 0x3C, 0xFF, 0x18, 0xFB, 0xC6, 0xF1, 0x5A, 0x8B, + 0x59, 0xE2, 0x02, 0xAC, 0x7B, 0x92, 0xD0, 0x4E, 0x14, 0x4F, 0x59, 0x45, + 0xF6, 0x0C, 0x5E, 0x28, 0x5F, 0xB0, 0xE8, 0x3F, 0x45, 0xCF, 0xCF, 0xAF, + 0x9B, 0x6F, 0xFB, 0x84, 0xD3, 0x77, 0x5A, 0x95, 0x6F, 0xAC, 0x94, 0x84, + 0x9E, 0xEE, 0xBC, 0xC0, 0x4A, 0x8F, 0x4A, 0x93, 0xF8, 0x44, 0x21, 0xE2, + 0x31, 0x45, 0x61, 0x50, 0x4E, 0x10, 0xD8, 0xE3, 0x35, 0x7C, 0x4C, 0x19, + 0xB4, 0xDE, 0x05, 0xBF, 0xA3, 0x06, 0x9F, 0xC8, 0xB5, 0xCD, 0xE4, 0x1F, + 0xD7, 0x17, 0x06, 0x0D, 0x7A, 0x95, 0x74, 0x55, 0x0D, 0x68, 0x1A, 0xFC, + 0x10, 0x1B, 0x62, 0x64, 0x9D, 0x6D, 0xE0, 0x95, 0xA0, 0xC3, 0x94, 0x07, + 0x57, 0x0D, 0x14, 0xE6, 0xBD, 0x05, 0xFB, 0xB8, 0x9F, 0xE6, 0xDF, 0x8B, + 0xE2, 0xC6, 0xE7, 0x7E, 0x96, 0xF6, 0x53, 0xC5, 0x80, 0x34, 0x50, 0x28, + 0x58, 0xF0, 0x12, 0x50, 0x71, 0x17, 0x30, 0xBA, 0xE6, 0x78, 0x63, 0xBC, + 0xF4, 0xB2, 0xAD, 0x9B, 0x2B, 0xB2, 0xFE, 0xE1, 0x39, 0x8C, 0x5E, 0xBA, + 0x0B, 0x20, 0x94, 0xDE, 0x7B, 0x83, 0xB8, 0xFF, 0xE3, 0x56, 0x8D, 0xB7, + 0x11, 0xE9, 0x3B, 0x8C, 0xF2, 0xB1, 0xC1, 0x5D, 0x9D, 0xA4, 0x0B, 0x4C, + 0x2B, 0xD9, 0xB2, 0x18, 0xF5, 0xB5, 0x9F, 0x4B +}; + +static const unsigned char TA157_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA158_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA158_RSA_N[] = { + 0xCC, 0x57, 0x42, 0x16, 0x54, 0x9C, 0xE6, 0x98, 0xD3, 0xD3, 0x4D, 0xEE, + 0xFE, 0xED, 0xC7, 0x9F, 0x43, 0x39, 0x4A, 0x65, 0xB3, 0xE8, 0x16, 0x88, + 0x34, 0xDB, 0x0D, 0x59, 0x91, 0x74, 0xCF, 0x92, 0xB8, 0x04, 0x40, 0xAD, + 0x02, 0x4B, 0x31, 0xAB, 0xBC, 0x8D, 0x91, 0x68, 0xD8, 0x20, 0x0E, 0x1A, + 0x01, 0xE2, 0x1A, 0x7B, 0x4E, 0x17, 0x5D, 0xE2, 0x8A, 0xB7, 0x3F, 0x99, + 0x1A, 0xCD, 0xEB, 0x61, 0xAB, 0xC2, 0x65, 0xA6, 0x1F, 0xB7, 0xB7, 0xBD, + 0xB7, 0x8F, 0xFC, 0xFD, 0x70, 0x8F, 0x0B, 0xA0, 0x67, 0xBE, 0x01, 0xA2, + 0x59, 0xCF, 0x71, 0xE6, 0x0F, 0x29, 0x76, 0xFF, 0xB1, 0x56, 0x79, 0x45, + 0x2B, 0x1F, 0x9E, 0x7A, 0x54, 0xE8, 0xA3, 0x29, 0x35, 0x68, 0xA4, 0x01, + 0x4F, 0x0F, 0xA4, 0x2E, 0x37, 0xEF, 0x1B, 0xBF, 0xE3, 0x8F, 0x10, 0xA8, + 0x72, 0xAB, 0x58, 0x57, 0xE7, 0x54, 0x86, 0xC8, 0xC9, 0xF3, 0x5B, 0xDA, + 0x2C, 0xDA, 0x5D, 0x8E, 0x6E, 0x3C, 0xA3, 0x3E, 0xDA, 0xFB, 0x82, 0xE5, + 0xDD, 0xF2, 0x5C, 0xB2, 0x05, 0x33, 0x6F, 0x8A, 0x36, 0xCE, 0xD0, 0x13, + 0x4E, 0xFF, 0xBF, 0x4A, 0x0C, 0x34, 0x4C, 0xA6, 0xC3, 0x21, 0xBD, 0x50, + 0x04, 0x55, 0xEB, 0xB1, 0xBB, 0x9D, 0xFB, 0x45, 0x1E, 0x64, 0x15, 0xDE, + 0x55, 0x01, 0x8C, 0x02, 0x76, 0xB5, 0xCB, 0xA1, 0x3F, 0x42, 0x69, 0xBC, + 0x2F, 0xBD, 0x68, 0x43, 0x16, 0x56, 0x89, 0x2A, 0x37, 0x61, 0x91, 0xFD, + 0xA6, 0xAE, 0x4E, 0xC0, 0xCB, 0x14, 0x65, 0x94, 0x37, 0x4B, 0x92, 0x06, + 0xEF, 0x04, 0xD0, 0xC8, 0x9C, 0x88, 0xDB, 0x0B, 0x7B, 0x81, 0xAF, 0xB1, + 0x3D, 0x2A, 0xC4, 0x65, 0x3A, 0x78, 0xB6, 0xEE, 0xDC, 0x80, 0xB1, 0xD2, + 0xD3, 0x99, 0x9C, 0x3A, 0xEE, 0x6B, 0x5A, 0x6B, 0xB3, 0x8D, 0xB7, 0xD5, + 0xCE, 0x9C, 0xC2, 0xBE, 0xA5, 0x4B, 0x2F, 0x16, 0xB1, 0x9E, 0x68, 0x3B, + 0x06, 0x6F, 0xAE, 0x7D, 0x9F, 0xF8, 0xDE, 0xEC, 0xCC, 0x29, 0xA7, 0x98, + 0xA3, 0x25, 0x43, 0x2F, 0xEF, 0xF1, 0x5F, 0x26, 0xE1, 0x88, 0x4D, 0xF8, + 0x5E, 0x6E, 0xD7, 0xD9, 0x14, 0x6E, 0x19, 0x33, 0x69, 0xA7, 0x3B, 0x84, + 0x89, 0x93, 0xC4, 0x53, 0x55, 0x13, 0xA1, 0x51, 0x78, 0x40, 0xF8, 0xB8, + 0xC9, 0xA2, 0xEE, 0x7B, 0xBA, 0x52, 0x42, 0x83, 0x9E, 0x14, 0xED, 0x05, + 0x52, 0x5A, 0x59, 0x56, 0xA7, 0x97, 0xFC, 0x9D, 0x3F, 0x0A, 0x29, 0xD8, + 0xDC, 0x4F, 0x91, 0x0E, 0x13, 0xBC, 0xDE, 0x95, 0xA4, 0xDF, 0x8B, 0x99, + 0xBE, 0xAC, 0x9B, 0x33, 0x88, 0xEF, 0xB5, 0x81, 0xAF, 0x1B, 0xC6, 0x22, + 0x53, 0xC8, 0xF6, 0xC7, 0xEE, 0x97, 0x14, 0xB0, 0xC5, 0x7C, 0x78, 0x52, + 0xC8, 0xF0, 0xCE, 0x6E, 0x77, 0x60, 0x84, 0xA6, 0xE9, 0x2A, 0x76, 0x20, + 0xED, 0x58, 0x01, 0x17, 0x30, 0x93, 0xE9, 0x1A, 0x8B, 0xE0, 0x73, 0x63, + 0xD9, 0x6A, 0x92, 0x94, 0x49, 0x4E, 0xB4, 0xAD, 0x4A, 0x85, 0xC4, 0xA3, + 0x22, 0x30, 0xFC, 0x09, 0xED, 0x68, 0x22, 0x73, 0xA6, 0x88, 0x0C, 0x55, + 0x21, 0x58, 0xC5, 0xE1, 0x3A, 0x9F, 0x2A, 0xDD, 0xCA, 0xE1, 0x90, 0xE0, + 0xD9, 0x73, 0xAB, 0x6C, 0x80, 0xB8, 0xE8, 0x0B, 0x64, 0x93, 0xA0, 0x9C, + 0x8C, 0x19, 0xFF, 0xB3, 0xD2, 0x0C, 0xEC, 0x91, 0x26, 0x87, 0x8A, 0xB3, + 0xA2, 0xE1, 0x70, 0x8F, 0x2C, 0x0A, 0xE5, 0xCD, 0x6D, 0x68, 0x51, 0xEB, + 0xDA, 0x3F, 0x05, 0x7F, 0x8B, 0x32, 0xE6, 0x13, 0x5C, 0x6B, 0xFE, 0x5F, + 0x40, 0xE2, 0x22, 0xC8, 0xB4, 0xB4, 0x64, 0x4F, 0xD6, 0xBA, 0x7D, 0x48, + 0x3E, 0xA8, 0x69, 0x0C, 0xD7, 0xBB, 0x86, 0x71, 0xC9, 0x73, 0xB8, 0x3F, + 0x3B, 0x9D, 0x25, 0x4B, 0xDA, 0xFF, 0x40, 0xEB +}; + +static const unsigned char TA158_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA159_DN[] = { + 0x30, 0x81, 0x84, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x05, + 0x13, 0x09, 0x47, 0x36, 0x33, 0x32, 0x38, 0x37, 0x35, 0x31, 0x30, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, + 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1E, 0x41, + 0x4E, 0x46, 0x20, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, + 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x63, 0x69, 0x6F, 0x6E, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x13, 0x0B, 0x41, 0x4E, 0x46, 0x20, 0x43, 0x41, 0x20, 0x52, + 0x61, 0x69, 0x7A, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x19, 0x41, 0x4E, 0x46, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA159_RSA_N[] = { + 0xDB, 0xEB, 0x6B, 0x2B, 0xE6, 0x64, 0x54, 0x95, 0x82, 0x90, 0xA3, 0x72, + 0xA4, 0x19, 0x01, 0x9D, 0x9C, 0x0B, 0x81, 0x5F, 0x73, 0x49, 0xBA, 0xA7, + 0xAC, 0xF3, 0x04, 0x4E, 0x7B, 0x96, 0x0B, 0xEC, 0x11, 0xE0, 0x5B, 0xA6, + 0x1C, 0xCE, 0x1B, 0xD2, 0x0D, 0x83, 0x1C, 0x2B, 0xB8, 0x9E, 0x1D, 0x7E, + 0x45, 0x32, 0x60, 0x0F, 0x07, 0xE9, 0x77, 0x58, 0x7E, 0x9F, 0x6A, 0xC8, + 0x61, 0x4E, 0xB6, 0x26, 0xC1, 0x4C, 0x8D, 0xFF, 0x4C, 0xEF, 0x34, 0xB2, + 0x1F, 0x65, 0xD8, 0xB9, 0x78, 0xF5, 0xAD, 0xA9, 0x71, 0xB9, 0xEF, 0x4F, + 0x58, 0x1D, 0xA5, 0xDE, 0x74, 0x20, 0x97, 0xA1, 0xED, 0x68, 0x4C, 0xDE, + 0x92, 0x17, 0x4B, 0xBC, 0xAB, 0xFF, 0x65, 0x9A, 0x9E, 0xFB, 0x47, 0xD9, + 0x57, 0x72, 0xF3, 0x09, 0xA1, 0xAE, 0x76, 0x44, 0x13, 0x6E, 0x9C, 0x2D, + 0x44, 0x39, 0xBC, 0xF9, 0xC7, 0x3B, 0xA4, 0x58, 0x3D, 0x41, 0xBD, 0xB4, + 0xC2, 0x49, 0xA3, 0xC8, 0x0D, 0xD2, 0x97, 0x2F, 0x07, 0x65, 0x52, 0x00, + 0xA7, 0x6E, 0xC8, 0xAF, 0x68, 0xEC, 0xF4, 0x14, 0x96, 0xB6, 0x57, 0x1F, + 0x56, 0xC3, 0x39, 0x9F, 0x2B, 0x6D, 0xE4, 0xF3, 0x3E, 0xF6, 0x35, 0x64, + 0xDA, 0x0C, 0x1C, 0xA1, 0x84, 0x4B, 0x2F, 0x4B, 0x4B, 0xE2, 0x2C, 0x24, + 0x9D, 0x6D, 0x93, 0x40, 0xEB, 0xB5, 0x23, 0x8E, 0x32, 0xCA, 0x6F, 0x45, + 0xD3, 0xA8, 0x89, 0x7B, 0x1E, 0xCF, 0x1E, 0xFA, 0x5B, 0x43, 0x8B, 0xCD, + 0xCD, 0xA8, 0x0F, 0x6A, 0xCA, 0x0C, 0x5E, 0xB9, 0x9E, 0x47, 0x8F, 0xF0, + 0xD9, 0xB6, 0x0A, 0x0B, 0x58, 0x65, 0x17, 0x33, 0xB9, 0x23, 0xE4, 0x77, + 0x19, 0x7D, 0xCB, 0x4A, 0x2E, 0x92, 0x7B, 0x4F, 0x2F, 0x10, 0x77, 0xB1, + 0x8D, 0x2F, 0x68, 0x9C, 0x62, 0xCC, 0xE0, 0x50, 0xF8, 0xEC, 0x91, 0xA7, + 0x54, 0x4C, 0x57, 0x09, 0xD5, 0x76, 0x63, 0xC5, 0xE8, 0x65, 0x1E, 0xEE, + 0x6D, 0x6A, 0xCF, 0x09, 0x9D, 0xFA, 0x7C, 0x4F, 0xAD, 0x60, 0x08, 0xFD, + 0x56, 0x99, 0x0F, 0x15, 0x2C, 0x7B, 0xA9, 0x80, 0xAB, 0x8C, 0x61, 0x8F, + 0x4A, 0x07, 0x76, 0x42, 0xDE, 0x3D, 0xF4, 0xDD, 0xB2, 0x24, 0x33, 0x5B, + 0xB8, 0xB5, 0xA3, 0x44, 0xC9, 0xAC, 0x7F, 0x77, 0x3C, 0x1D, 0x23, 0xEC, + 0x82, 0xA9, 0xA6, 0xE2, 0xC8, 0x06, 0x4C, 0x02, 0xFE, 0xAC, 0x5C, 0x99, + 0x99, 0x0B, 0x2F, 0x10, 0x8A, 0xA6, 0xF4, 0x7F, 0xD5, 0x87, 0x74, 0x0D, + 0x59, 0x49, 0x45, 0xF6, 0xF0, 0x71, 0x5C, 0x39, 0x29, 0xD6, 0xBF, 0x4A, + 0x23, 0x8B, 0xF5, 0x5F, 0x01, 0x63, 0xD2, 0x87, 0x73, 0x28, 0xB5, 0x4B, + 0x0A, 0xF5, 0xF8, 0xAB, 0x82, 0x2C, 0x7E, 0x73, 0x25, 0x32, 0x1D, 0x0B, + 0x63, 0x0A, 0x17, 0x81, 0x00, 0xFF, 0xB6, 0x76, 0x5E, 0xE7, 0xB4, 0xB1, + 0x40, 0xCA, 0x21, 0xBB, 0xD5, 0x80, 0x51, 0xE5, 0x48, 0x52, 0x67, 0x2C, + 0xD2, 0x61, 0x89, 0x07, 0x0D, 0x0F, 0xCE, 0x42, 0x77, 0xC0, 0x44, 0x73, + 0x9C, 0x44, 0x50, 0xA0, 0xDB, 0x10, 0x0A, 0x2D, 0x95, 0x1C, 0x81, 0xAF, + 0xE4, 0x1C, 0xE5, 0x14, 0x1E, 0xF1, 0x36, 0x41, 0x01, 0x02, 0x2F, 0x7D, + 0x73, 0xA7, 0xDE, 0x42, 0xCC, 0x4C, 0xE9, 0x89, 0x0D, 0x56, 0xF7, 0x9F, + 0x91, 0xD4, 0x03, 0xC6, 0x6C, 0xC9, 0x8F, 0xDB, 0xD8, 0x1C, 0xE0, 0x40, + 0x98, 0x5D, 0x66, 0x99, 0x98, 0x80, 0x6E, 0x2D, 0xFF, 0x01, 0xC5, 0xCE, + 0xCB, 0x46, 0x1F, 0xAC, 0x02, 0xC6, 0x43, 0xE6, 0xAE, 0xA2, 0x84, 0x3C, + 0xC5, 0x4E, 0x1E, 0x3D, 0x6D, 0xC9, 0x14, 0x4C, 0xE3, 0x2E, 0x41, 0xBB, + 0xCA, 0x39, 0xBF, 0x36, 0x3C, 0x2A, 0x19, 0xAA, 0x41, 0x87, 0x4E, 0xA5, + 0xCE, 0x4B, 0x32, 0x79, 0xDD, 0x90, 0x49, 0x7F +}; + +static const unsigned char TA159_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA160_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, 0x67 +}; + +static const unsigned char TA160_RSA_N[] = { + 0xB4, 0x84, 0xCC, 0x33, 0x17, 0x2E, 0x6B, 0x94, 0x6C, 0x6B, 0x61, 0x52, + 0xA0, 0xEB, 0xA3, 0xCF, 0x79, 0x94, 0x4C, 0xE5, 0x94, 0x80, 0x99, 0xCB, + 0x55, 0x64, 0x44, 0x65, 0x8F, 0x67, 0x64, 0xE2, 0x06, 0xE3, 0x5C, 0x37, + 0x49, 0xF6, 0x2F, 0x9B, 0x84, 0x84, 0x1E, 0x2D, 0xF2, 0x60, 0x9D, 0x30, + 0x4E, 0xCC, 0x84, 0x85, 0xE2, 0x2C, 0xCF, 0x1E, 0x9E, 0xFE, 0x36, 0xAB, + 0x33, 0x77, 0x35, 0x44, 0xD8, 0x35, 0x96, 0x1A, 0x3D, 0x36, 0xE8, 0x7A, + 0x0E, 0xD8, 0xD5, 0x47, 0xA1, 0x6A, 0x69, 0x8B, 0xD9, 0xFC, 0xBB, 0x3A, + 0xAE, 0x79, 0x5A, 0xD5, 0xF4, 0xD6, 0x71, 0xBB, 0x9A, 0x90, 0x23, 0x6B, + 0x9A, 0xB7, 0x88, 0x74, 0x87, 0x0C, 0x1E, 0x5F, 0xB9, 0x9E, 0x2D, 0xFA, + 0xAB, 0x53, 0x2B, 0xDC, 0xBB, 0x76, 0x3E, 0x93, 0x4C, 0x08, 0x08, 0x8C, + 0x1E, 0xA2, 0x23, 0x1C, 0xD4, 0x6A, 0xAD, 0x22, 0xBA, 0x99, 0x01, 0x2E, + 0x6D, 0x65, 0xCB, 0xBE, 0x24, 0x66, 0x55, 0x24, 0x4B, 0x40, 0x44, 0xB1, + 0x1B, 0xD7, 0xE1, 0xC2, 0x85, 0xC0, 0xDE, 0x10, 0x3F, 0x3D, 0xED, 0xB8, + 0xFC, 0xF1, 0xF1, 0x23, 0x53, 0xDC, 0xBF, 0x65, 0x97, 0x6F, 0xD9, 0xF9, + 0x40, 0x71, 0x8D, 0x7D, 0xBD, 0x95, 0xD4, 0xCE, 0xBE, 0xA0, 0x5E, 0x27, + 0x23, 0xDE, 0xFD, 0xA6, 0xD0, 0x26, 0x0E, 0x00, 0x29, 0xEB, 0x3C, 0x46, + 0xF0, 0x3D, 0x60, 0xBF, 0x3F, 0x50, 0xD2, 0xDC, 0x26, 0x41, 0x51, 0x9E, + 0x14, 0x37, 0x42, 0x04, 0xA3, 0x70, 0x57, 0xA8, 0x1B, 0x87, 0xED, 0x2D, + 0xFA, 0x7B, 0xEE, 0x8C, 0x0A, 0xE3, 0xA9, 0x66, 0x89, 0x19, 0xCB, 0x41, + 0xF9, 0xDD, 0x44, 0x36, 0x61, 0xCF, 0xE2, 0x77, 0x46, 0xC8, 0x7D, 0xF6, + 0xF4, 0x92, 0x81, 0x36, 0xFD, 0xDB, 0x34, 0xF1, 0x72, 0x7E, 0xF3, 0x0C, + 0x16, 0xBD, 0xB4, 0x15 +}; + +static const unsigned char TA160_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA161_DN[] = { + 0x30, 0x81, 0xAA, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x44, 0x30, 0x42, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, + 0x20, 0x32, 0x30, 0x31, 0x35 +}; + +static const unsigned char TA161_EC_Q[] = { + 0x04, 0x92, 0xA0, 0x41, 0xE8, 0x4B, 0x82, 0x84, 0x5C, 0xE2, 0xF8, 0x31, + 0x11, 0x99, 0x86, 0x64, 0x4E, 0x09, 0x25, 0x2F, 0x9D, 0x41, 0x2F, 0x0A, + 0xAE, 0x35, 0x4F, 0x74, 0x95, 0xB2, 0x51, 0x64, 0x6B, 0x8D, 0x6B, 0xE6, + 0x3F, 0x70, 0x95, 0xF0, 0x05, 0x44, 0x47, 0xA6, 0x72, 0x38, 0x50, 0x76, + 0x95, 0x02, 0x5A, 0x8E, 0xAE, 0x28, 0x9E, 0xF9, 0x2D, 0x4E, 0x99, 0xEF, + 0x2C, 0x48, 0x6F, 0x4C, 0x25, 0x29, 0xE8, 0xD1, 0x71, 0x5B, 0xDF, 0x1D, + 0xC1, 0x75, 0x37, 0xB4, 0xD7, 0xFA, 0x7B, 0x7A, 0x42, 0x9C, 0x6A, 0x0A, + 0x56, 0x5A, 0x7C, 0x69, 0x0B, 0xAA, 0x80, 0x09, 0x24, 0x6C, 0x7E, 0xC1, + 0x46 +}; + +static const unsigned char TA162_DN[] = { + 0x30, 0x74, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x45, 0x43, 0x2D, 0x33, 0x38, 0x34, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA162_EC_Q[] = { + 0x04, 0xC4, 0x28, 0x8E, 0xAB, 0x18, 0x5B, 0x6A, 0xBE, 0x6E, 0x64, 0x37, + 0x63, 0xE4, 0xCD, 0xEC, 0xAB, 0x3A, 0xF7, 0xCC, 0xA1, 0xB8, 0x0E, 0x82, + 0x49, 0xD7, 0x86, 0x29, 0x9F, 0xA1, 0x94, 0xF2, 0xE3, 0x60, 0x78, 0x98, + 0x81, 0x78, 0x06, 0x4D, 0xF2, 0xEC, 0x9A, 0x0E, 0x57, 0x60, 0x83, 0x9F, + 0xB4, 0xE6, 0x17, 0x2F, 0x1A, 0xB3, 0x5D, 0x02, 0x5B, 0x89, 0x23, 0x3C, + 0xC2, 0x11, 0x05, 0x2A, 0xA7, 0x88, 0x13, 0x18, 0xF3, 0x50, 0x84, 0xD7, + 0xBD, 0x34, 0x2C, 0x27, 0x89, 0x55, 0xFF, 0xCE, 0x4C, 0xE7, 0xDF, 0xA6, + 0x1F, 0x28, 0xC4, 0xF0, 0x54, 0xC3, 0xB9, 0x7C, 0xB7, 0x53, 0xAD, 0xEB, + 0xC2 +}; + +static const unsigned char TA163_DN[] = { + 0x30, 0x52, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x53, 0x4B, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x0A, 0x42, 0x72, 0x61, 0x74, 0x69, 0x73, 0x6C, 0x61, 0x76, 0x61, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x61, 0x2E, 0x73, 0x2E, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x41, 0x20, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x32 +}; + +static const unsigned char TA163_RSA_N[] = { + 0xA2, 0xA3, 0xC4, 0x00, 0x09, 0xD6, 0x85, 0x5D, 0x2D, 0x6D, 0x14, 0xF6, + 0xC2, 0xC3, 0x73, 0x9E, 0x35, 0xC2, 0x71, 0x55, 0x7E, 0x81, 0xFB, 0xAB, + 0x46, 0x50, 0xE0, 0xC1, 0x7C, 0x49, 0x78, 0xE6, 0xAB, 0x79, 0x58, 0x3C, + 0xDA, 0xFF, 0x7C, 0x1C, 0x9F, 0xD8, 0x97, 0x02, 0x78, 0x3E, 0x6B, 0x41, + 0x04, 0xE9, 0x41, 0xBD, 0xBE, 0x03, 0x2C, 0x45, 0xF6, 0x2F, 0x64, 0xD4, + 0xAB, 0x5D, 0xA3, 0x47, 0x3D, 0x64, 0x9B, 0xE9, 0x68, 0x9A, 0xC6, 0xCC, + 0x1B, 0x3F, 0xBA, 0xBE, 0xB2, 0x8B, 0x34, 0x02, 0x2E, 0x98, 0x55, 0x19, + 0xFC, 0x8C, 0x6F, 0xAA, 0x5F, 0xDA, 0x4C, 0xCE, 0x4D, 0x03, 0x21, 0xA3, + 0xD8, 0xD2, 0x34, 0x93, 0x56, 0x96, 0xCB, 0x4C, 0x0C, 0x00, 0x16, 0x3C, + 0x5F, 0x1A, 0xCD, 0xC8, 0xC7, 0x6C, 0xA6, 0xAD, 0xD3, 0x31, 0xA7, 0xBC, + 0xE8, 0xE5, 0xE1, 0x66, 0xD6, 0xD2, 0xFB, 0x03, 0xB4, 0x41, 0x65, 0xC9, + 0x10, 0xAE, 0x0E, 0x05, 0x63, 0xC6, 0x80, 0x6A, 0x69, 0x30, 0xFD, 0xD2, + 0xEE, 0x90, 0xEF, 0x0D, 0x27, 0xDF, 0x9F, 0x95, 0x73, 0xF4, 0xE1, 0x25, + 0xDA, 0x6C, 0x16, 0xDE, 0x41, 0x38, 0x34, 0xEA, 0x8B, 0xFC, 0xD1, 0xE8, + 0x04, 0x14, 0x61, 0x2D, 0x41, 0x7E, 0xAC, 0xC7, 0x77, 0x4E, 0xCB, 0x51, + 0x54, 0xFB, 0x5E, 0x92, 0x18, 0x1B, 0x04, 0x5A, 0x68, 0xC6, 0xC9, 0xC4, + 0xFA, 0xB7, 0x13, 0xA0, 0x98, 0xB7, 0x11, 0x2B, 0xB7, 0xD6, 0x57, 0xCC, + 0x7C, 0x9E, 0x17, 0xD1, 0xCB, 0x25, 0xFE, 0x86, 0x4E, 0x24, 0x2E, 0x56, + 0x0C, 0x78, 0x4D, 0x9E, 0x01, 0x12, 0xA6, 0x2B, 0xA7, 0x01, 0x65, 0x6E, + 0x7C, 0x62, 0x1D, 0x84, 0x84, 0xDF, 0xEA, 0xC0, 0x6B, 0xB5, 0xA5, 0x2A, + 0x95, 0x83, 0xC3, 0x53, 0x11, 0x0C, 0x73, 0x1D, 0x0B, 0xB2, 0x46, 0x90, + 0xD1, 0x42, 0x3A, 0xCE, 0x40, 0x6E, 0x95, 0xAD, 0xFF, 0xC6, 0x94, 0xAD, + 0x6E, 0x97, 0x84, 0x8E, 0x7D, 0x6F, 0x9E, 0x8A, 0x80, 0x0D, 0x49, 0x6D, + 0x73, 0xE2, 0x7B, 0x92, 0x1E, 0xC3, 0xF3, 0xC1, 0xF3, 0xEB, 0x2E, 0x05, + 0x6F, 0xD9, 0x1B, 0xCF, 0x37, 0x76, 0x04, 0xC8, 0xB4, 0x5A, 0xE4, 0x17, + 0xA7, 0xCB, 0xDD, 0x76, 0x1F, 0xD0, 0x19, 0x76, 0xE8, 0x2C, 0x05, 0xB3, + 0xD6, 0x9C, 0x34, 0xD8, 0x96, 0xDC, 0x61, 0x87, 0x91, 0x05, 0xE4, 0x44, + 0x08, 0x33, 0xC1, 0xDA, 0xB9, 0x08, 0x65, 0xD4, 0xAE, 0xB2, 0x36, 0x0D, + 0xEB, 0xBA, 0x38, 0xBA, 0x0C, 0xE5, 0x9B, 0x9E, 0xEB, 0x8D, 0x66, 0xDD, + 0x99, 0xCF, 0xD6, 0x89, 0x41, 0xF6, 0x04, 0x92, 0x8A, 0x29, 0x29, 0x6D, + 0x6B, 0x3A, 0x1C, 0xE7, 0x75, 0x7D, 0x02, 0x71, 0x0E, 0xF3, 0xC0, 0xE7, + 0xBD, 0xCB, 0x19, 0xDD, 0x9D, 0x60, 0xB2, 0xC2, 0x66, 0x60, 0xB6, 0xB1, + 0x04, 0xEE, 0xC9, 0xE6, 0x86, 0xB9, 0x9A, 0x66, 0x40, 0xA8, 0xE7, 0x11, + 0xED, 0x81, 0x45, 0x03, 0x8B, 0xF6, 0x67, 0x59, 0xE8, 0xC1, 0x06, 0x11, + 0xBD, 0xDD, 0xCF, 0x80, 0x02, 0x4F, 0x65, 0x40, 0x78, 0x5C, 0x47, 0x50, + 0xC8, 0x9B, 0xE6, 0x1F, 0x81, 0x7B, 0xE4, 0x44, 0xA8, 0x5B, 0x85, 0x9A, + 0xE2, 0xDE, 0x5A, 0xD5, 0xC7, 0xF9, 0x3A, 0x44, 0x66, 0x4B, 0xE4, 0x32, + 0x54, 0x7C, 0xE4, 0x6C, 0x9C, 0xB3, 0x0E, 0x3D, 0x17, 0xA2, 0xB2, 0x34, + 0x12, 0xD6, 0x7E, 0xB2, 0xA8, 0x49, 0xBB, 0xD1, 0x7A, 0x28, 0x40, 0xBE, + 0xA2, 0x16, 0x1F, 0xDF, 0xE4, 0x37, 0x1F, 0x11, 0x73, 0xFB, 0x90, 0x0A, + 0x65, 0x43, 0xA2, 0x0D, 0x7C, 0xF8, 0x06, 0x01, 0x55, 0x33, 0x7D, 0xB0, + 0x0D, 0xB8, 0xF4, 0xF5, 0xAE, 0xA5, 0x42, 0x57, 0x7C, 0x36, 0x11, 0x8C, + 0x7B, 0x5E, 0xC4, 0x03, 0x9D, 0x8C, 0x79, 0x9D +}; + +static const unsigned char TA163_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA164_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA164_RSA_N[] = { + 0xCA, 0x5B, 0xBE, 0x94, 0x33, 0x8C, 0x29, 0x95, 0x91, 0x16, 0x0A, 0x95, + 0xBD, 0x47, 0x62, 0xC1, 0x89, 0xF3, 0x99, 0x36, 0xDF, 0x46, 0x90, 0xC9, + 0xA5, 0xED, 0x78, 0x6A, 0x6F, 0x47, 0x91, 0x68, 0xF8, 0x27, 0x67, 0x50, + 0x33, 0x1D, 0xA1, 0xA6, 0xFB, 0xE0, 0xE5, 0x43, 0xA3, 0x84, 0x02, 0x57, + 0x01, 0x5D, 0x9C, 0x48, 0x40, 0x82, 0x53, 0x10, 0xBC, 0xBF, 0xC7, 0x3B, + 0x68, 0x90, 0xB6, 0x82, 0x2D, 0xE5, 0xF4, 0x65, 0xD0, 0xCC, 0x6D, 0x19, + 0xCC, 0x95, 0xF9, 0x7B, 0xAC, 0x4A, 0x94, 0xAD, 0x0E, 0xDE, 0x4B, 0x43, + 0x1D, 0x87, 0x07, 0x92, 0x13, 0x90, 0x80, 0x83, 0x64, 0x35, 0x39, 0x04, + 0xFC, 0xE5, 0xE9, 0x6C, 0xB3, 0xB6, 0x1F, 0x50, 0x94, 0x38, 0x65, 0x50, + 0x5C, 0x17, 0x46, 0xB9, 0xB6, 0x85, 0xB5, 0x1C, 0xB5, 0x17, 0xE8, 0xD6, + 0x45, 0x9D, 0xD8, 0xB2, 0x26, 0xB0, 0xCA, 0xC4, 0x70, 0x4A, 0xAE, 0x60, + 0xA4, 0xDD, 0xB3, 0xD9, 0xEC, 0xFC, 0x3B, 0xD5, 0x57, 0x72, 0xBC, 0x3F, + 0xC8, 0xC9, 0xB2, 0xDE, 0x4B, 0x6B, 0xF8, 0x23, 0x6C, 0x03, 0xC0, 0x05, + 0xBD, 0x95, 0xC7, 0xCD, 0x73, 0x3B, 0x66, 0x80, 0x64, 0xE3, 0x1A, 0xAC, + 0x2E, 0xF9, 0x47, 0x05, 0xF2, 0x06, 0xB6, 0x9B, 0x73, 0xF5, 0x78, 0x33, + 0x5B, 0xC7, 0xA1, 0xFB, 0x27, 0x2A, 0xA1, 0xB4, 0x9A, 0x91, 0x8C, 0x91, + 0xD3, 0x3A, 0x82, 0x3E, 0x76, 0x40, 0xB4, 0xCD, 0x52, 0x61, 0x51, 0x70, + 0x28, 0x3F, 0xC5, 0xC5, 0x5A, 0xF2, 0xC9, 0x8C, 0x49, 0xBB, 0x14, 0x5B, + 0x4D, 0xC8, 0xFF, 0x67, 0x4D, 0x4C, 0x12, 0x96, 0xAD, 0xF5, 0xFE, 0x78, + 0xA8, 0x97, 0x87, 0xD7, 0xFD, 0x5E, 0x20, 0x80, 0xDC, 0xA1, 0x4B, 0x22, + 0xFB, 0xD4, 0x89, 0xAD, 0xBA, 0xCE, 0x47, 0x97, 0x47, 0x55, 0x7B, 0x8F, + 0x45, 0xC8, 0x67, 0x28, 0x84, 0x95, 0x1C, 0x68, 0x30, 0xEF, 0xEF, 0x49, + 0xE0, 0x35, 0x7B, 0x64, 0xE7, 0x98, 0xB0, 0x94, 0xDA, 0x4D, 0x85, 0x3B, + 0x3E, 0x55, 0xC4, 0x28, 0xAF, 0x57, 0xF3, 0x9E, 0x13, 0xDB, 0x46, 0x27, + 0x9F, 0x1E, 0xA2, 0x5E, 0x44, 0x83, 0xA4, 0xA5, 0xCA, 0xD5, 0x13, 0xB3, + 0x4B, 0x3F, 0xC4, 0xE3, 0xC2, 0xE6, 0x86, 0x61, 0xA4, 0x52, 0x30, 0xB9, + 0x7A, 0x20, 0x4F, 0x6F, 0x0F, 0x38, 0x53, 0xCB, 0x33, 0x0C, 0x13, 0x2B, + 0x8F, 0xD6, 0x9A, 0xBD, 0x2A, 0xC8, 0x2D, 0xB1, 0x1C, 0x7D, 0x4B, 0x51, + 0xCA, 0x47, 0xD1, 0x48, 0x27, 0x72, 0x5D, 0x87, 0xEB, 0xD5, 0x45, 0xE6, + 0x48, 0x65, 0x9D, 0xAF, 0x52, 0x90, 0xBA, 0x5B, 0xA2, 0x18, 0x65, 0x57, + 0x12, 0x9F, 0x68, 0xB9, 0xD4, 0x15, 0x6B, 0x94, 0xC4, 0x69, 0x22, 0x98, + 0xF4, 0x33, 0xE0, 0xED, 0xF9, 0x51, 0x8E, 0x41, 0x50, 0xC9, 0x34, 0x4F, + 0x76, 0x90, 0xAC, 0xFC, 0x38, 0xC1, 0xD8, 0xE1, 0x7B, 0xB9, 0xE3, 0xE3, + 0x94, 0xE1, 0x46, 0x69, 0xCB, 0x0E, 0x0A, 0x50, 0x6B, 0x13, 0xBA, 0xAC, + 0x0F, 0x37, 0x5A, 0xB7, 0x12, 0xB5, 0x90, 0x81, 0x1E, 0x56, 0xAE, 0x57, + 0x22, 0x86, 0xD9, 0xC9, 0xD2, 0xD1, 0xD7, 0x51, 0xE3, 0xAB, 0x3B, 0xC6, + 0x55, 0xFD, 0x1E, 0x0E, 0xD3, 0x74, 0x0A, 0xD1, 0xDA, 0xAA, 0xEA, 0x69, + 0xB8, 0x97, 0x28, 0x8F, 0x48, 0xC4, 0x07, 0xF8, 0x52, 0x43, 0x3A, 0xF4, + 0xCA, 0x55, 0x35, 0x2C, 0xB0, 0xA6, 0x6A, 0xC0, 0x9C, 0xF9, 0xF2, 0x81, + 0xE1, 0x12, 0x6A, 0xC0, 0x45, 0xD9, 0x67, 0xB3, 0xCE, 0xFF, 0x23, 0xA2, + 0x89, 0x0A, 0x54, 0xD4, 0x14, 0xB9, 0x2A, 0xA8, 0xD7, 0xEC, 0xF9, 0xAB, + 0xCD, 0x25, 0x58, 0x32, 0x79, 0x8F, 0x90, 0x5B, 0x98, 0x39, 0xC4, 0x08, + 0x06, 0xC1, 0xAC, 0x7F, 0x0E, 0x3D, 0x00, 0xA5 +}; + +static const unsigned char TA164_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA165_DN[] = { + 0x30, 0x7E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, 0x65, + 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, + 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, + 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, 0x65, + 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA165_RSA_N[] = { + 0xE3, 0xFB, 0x7D, 0xA3, 0x72, 0xBA, 0xC2, 0xF0, 0xC9, 0x14, 0x87, 0xF5, + 0x6B, 0x01, 0x4E, 0xE1, 0x6E, 0x40, 0x07, 0xBA, 0x6D, 0x27, 0x5D, 0x7F, + 0xF7, 0x5B, 0x2D, 0xB3, 0x5A, 0xC7, 0x51, 0x5F, 0xAB, 0xA4, 0x32, 0xA6, + 0x61, 0x87, 0xB6, 0x6E, 0x0F, 0x86, 0xD2, 0x30, 0x02, 0x97, 0xF8, 0xD7, + 0x69, 0x57, 0xA1, 0x18, 0x39, 0x5D, 0x6A, 0x64, 0x79, 0xC6, 0x01, 0x59, + 0xAC, 0x3C, 0x31, 0x4A, 0x38, 0x7C, 0xD2, 0x04, 0xD2, 0x4B, 0x28, 0xE8, + 0x20, 0x5F, 0x3B, 0x07, 0xA2, 0xCC, 0x4D, 0x73, 0xDB, 0xF3, 0xAE, 0x4F, + 0xC7, 0x56, 0xD5, 0x5A, 0xA7, 0x96, 0x89, 0xFA, 0xF3, 0xAB, 0x68, 0xD4, + 0x23, 0x86, 0x59, 0x27, 0xCF, 0x09, 0x27, 0xBC, 0xAC, 0x6E, 0x72, 0x83, + 0x1C, 0x30, 0x72, 0xDF, 0xE0, 0xA2, 0xE9, 0xD2, 0xE1, 0x74, 0x75, 0x19, + 0xBD, 0x2A, 0x9E, 0x7B, 0x15, 0x54, 0x04, 0x1B, 0xD7, 0x43, 0x39, 0xAD, + 0x55, 0x28, 0xC5, 0xE2, 0x1A, 0xBB, 0xF4, 0xC0, 0xE4, 0xAE, 0x38, 0x49, + 0x33, 0xCC, 0x76, 0x85, 0x9F, 0x39, 0x45, 0xD2, 0xA4, 0x9E, 0xF2, 0x12, + 0x8C, 0x51, 0xF8, 0x7C, 0xE4, 0x2D, 0x7F, 0xF5, 0xAC, 0x5F, 0xEB, 0x16, + 0x9F, 0xB1, 0x2D, 0xD1, 0xBA, 0xCC, 0x91, 0x42, 0x77, 0x4C, 0x25, 0xC9, + 0x90, 0x38, 0x6F, 0xDB, 0xF0, 0xCC, 0xFB, 0x8E, 0x1E, 0x97, 0x59, 0x3E, + 0xD5, 0x60, 0x4E, 0xE6, 0x05, 0x28, 0xED, 0x49, 0x79, 0x13, 0x4B, 0xBA, + 0x48, 0xDB, 0x2F, 0xF9, 0x72, 0xD3, 0x39, 0xCA, 0xFE, 0x1F, 0xD8, 0x34, + 0x72, 0xF5, 0xB4, 0x40, 0xCF, 0x31, 0x01, 0xC3, 0xEC, 0xDE, 0x11, 0x2D, + 0x17, 0x5D, 0x1F, 0xB8, 0x50, 0xD1, 0x5E, 0x19, 0xA7, 0x69, 0xDE, 0x07, + 0x33, 0x28, 0xCA, 0x50, 0x95, 0xF9, 0xA7, 0x54, 0xCB, 0x54, 0x86, 0x50, + 0x45, 0xA9, 0xF9, 0x49 +}; + +static const unsigned char TA165_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA166_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1D, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x50, 0x33, 0x38, 0x34, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA166_EC_Q[] = { + 0x04, 0xC1, 0x44, 0xA1, 0xCF, 0x11, 0x97, 0x50, 0x9A, 0xDE, 0x23, 0x82, + 0x35, 0x07, 0xCD, 0xD0, 0xCB, 0x18, 0x9D, 0xD2, 0xF1, 0x7F, 0x77, 0x35, + 0x4F, 0x3B, 0xDD, 0x94, 0x72, 0x52, 0xED, 0xC2, 0x3B, 0xF8, 0xEC, 0xFA, + 0x7B, 0x6B, 0x58, 0x20, 0xEC, 0x99, 0xAE, 0xC9, 0xFC, 0x68, 0xB3, 0x75, + 0xB9, 0xDB, 0x09, 0xEC, 0xC8, 0x13, 0xF5, 0x4E, 0xC6, 0x0A, 0x1D, 0x66, + 0x30, 0x4C, 0xBB, 0x1F, 0x47, 0x0A, 0x3C, 0x61, 0x10, 0x42, 0x29, 0x7C, + 0xA5, 0x08, 0x0E, 0xE0, 0x22, 0xE9, 0xD3, 0x35, 0x68, 0xCE, 0x9B, 0x63, + 0x9F, 0x84, 0xB5, 0x99, 0x4D, 0x58, 0xA0, 0x8E, 0xF5, 0x54, 0xE7, 0x95, + 0xC9 +}; + +static const unsigned char TA167_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x36, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA167_RSA_N[] = { + 0x95, 0x07, 0xE8, 0x73, 0xCA, 0x66, 0xF9, 0xEC, 0x14, 0xCA, 0x7B, 0x3C, + 0xF7, 0x0D, 0x08, 0xF1, 0xB4, 0x45, 0x0B, 0x2C, 0x82, 0xB4, 0x48, 0xC6, + 0xEB, 0x5B, 0x3C, 0xAE, 0x83, 0xB8, 0x41, 0x92, 0x33, 0x14, 0xA4, 0x6F, + 0x7F, 0xE9, 0x2A, 0xCC, 0xC6, 0xB0, 0x88, 0x6B, 0xC5, 0xB6, 0x89, 0xD1, + 0xC6, 0xB2, 0xFF, 0x14, 0xCE, 0x51, 0x14, 0x21, 0xEC, 0x4A, 0xDD, 0x1B, + 0x5A, 0xC6, 0xD6, 0x87, 0xEE, 0x4D, 0x3A, 0x15, 0x06, 0xED, 0x64, 0x66, + 0x0B, 0x92, 0x80, 0xCA, 0x44, 0xDE, 0x73, 0x94, 0x4E, 0xF3, 0xA7, 0x89, + 0x7F, 0x4F, 0x78, 0x63, 0x08, 0xC8, 0x12, 0x50, 0x6D, 0x42, 0x66, 0x2F, + 0x4D, 0xB9, 0x79, 0x28, 0x4D, 0x52, 0x1A, 0x8A, 0x1A, 0x80, 0xB7, 0x19, + 0x81, 0x0E, 0x7E, 0xC4, 0x8A, 0xBC, 0x64, 0x4C, 0x21, 0x1C, 0x43, 0x68, + 0xD7, 0x3D, 0x3C, 0x8A, 0xC5, 0xB2, 0x66, 0xD5, 0x90, 0x9A, 0xB7, 0x31, + 0x06, 0xC5, 0xBE, 0xE2, 0x6D, 0x32, 0x06, 0xA6, 0x1E, 0xF9, 0xB9, 0xEB, + 0xAA, 0xA3, 0xB8, 0xBF, 0xBE, 0x82, 0x63, 0x50, 0xD0, 0xF0, 0x18, 0x89, + 0xDF, 0xE4, 0x0F, 0x79, 0xF5, 0xEA, 0xA2, 0x1F, 0x2A, 0xD2, 0x70, 0x2E, + 0x7B, 0xE7, 0xBC, 0x93, 0xBB, 0x6D, 0x53, 0xE2, 0x48, 0x7C, 0x8C, 0x10, + 0x07, 0x38, 0xFF, 0x66, 0xB2, 0x77, 0x61, 0x7E, 0xE0, 0xEA, 0x8C, 0x3C, + 0xAA, 0xB4, 0xA4, 0xF6, 0xF3, 0x95, 0x4A, 0x12, 0x07, 0x6D, 0xFD, 0x8C, + 0xB2, 0x89, 0xCF, 0xD0, 0xA0, 0x61, 0x77, 0xC8, 0x58, 0x74, 0xB0, 0xD4, + 0x23, 0x3A, 0xF7, 0x5D, 0x3A, 0xCA, 0xA2, 0xDB, 0x9D, 0x09, 0xDE, 0x5D, + 0x44, 0x2D, 0x90, 0xF1, 0x81, 0xCD, 0x57, 0x92, 0xFA, 0x7E, 0xBC, 0x50, + 0x04, 0x63, 0x34, 0xDF, 0x6B, 0x93, 0x18, 0xBE, 0x6B, 0x36, 0xB2, 0x39, + 0xE4, 0xAC, 0x24, 0x36, 0xB7, 0xF0, 0xEF, 0xB6, 0x1C, 0x13, 0x57, 0x93, + 0xB6, 0xDE, 0xB2, 0xF8, 0xE2, 0x85, 0xB7, 0x73, 0xA2, 0xB8, 0x35, 0xAA, + 0x45, 0xF2, 0xE0, 0x9D, 0x36, 0xA1, 0x6F, 0x54, 0x8A, 0xF1, 0x72, 0x56, + 0x6E, 0x2E, 0x88, 0xC5, 0x51, 0x42, 0x44, 0x15, 0x94, 0xEE, 0xA3, 0xC5, + 0x38, 0x96, 0x9B, 0x4E, 0x4E, 0x5A, 0x0B, 0x47, 0xF3, 0x06, 0x36, 0x49, + 0x77, 0x30, 0xBC, 0x71, 0x37, 0xE5, 0xA6, 0xEC, 0x21, 0x08, 0x75, 0xFC, + 0xE6, 0x61, 0x16, 0x3F, 0x77, 0xD5, 0xD9, 0x91, 0x97, 0x84, 0x0A, 0x6C, + 0xD4, 0x02, 0x4D, 0x74, 0xC0, 0x14, 0xED, 0xFD, 0x39, 0xFB, 0x83, 0xF2, + 0x5E, 0x14, 0xA1, 0x04, 0xB0, 0x0B, 0xE9, 0xFE, 0xEE, 0x8F, 0xE1, 0x6E, + 0x0B, 0xB2, 0x08, 0xB3, 0x61, 0x66, 0x09, 0x6A, 0xB1, 0x06, 0x3A, 0x65, + 0x96, 0x59, 0xC0, 0xF0, 0x35, 0xFD, 0xC9, 0xDA, 0x28, 0x8D, 0x1A, 0x11, + 0x87, 0x70, 0x81, 0x0A, 0xA8, 0x9A, 0x75, 0x1D, 0x9E, 0x3A, 0x86, 0x05, + 0x00, 0x9E, 0xDB, 0x80, 0xD6, 0x25, 0xF9, 0xDC, 0x05, 0x9E, 0x27, 0x59, + 0x4C, 0x76, 0x39, 0x5B, 0xEA, 0xF9, 0xA5, 0xA1, 0xD8, 0x83, 0x0F, 0xD1, + 0xFF, 0xDF, 0x30, 0x11, 0xF9, 0x85, 0xCF, 0x33, 0x48, 0xF5, 0xCA, 0x6D, + 0x64, 0x14, 0x2C, 0x7A, 0x58, 0x4F, 0xD3, 0x4B, 0x08, 0x49, 0xC5, 0x95, + 0x64, 0x1A, 0x63, 0x0E, 0x79, 0x3D, 0xF5, 0xB3, 0x8C, 0xCA, 0x58, 0xAD, + 0x9C, 0x42, 0x45, 0x79, 0x6E, 0x0E, 0x87, 0x19, 0x5C, 0x54, 0xB1, 0x65, + 0xB6, 0xBF, 0x8C, 0x9B, 0xDC, 0x13, 0xE9, 0x0D, 0x6F, 0xB8, 0x2E, 0xDC, + 0x67, 0x6E, 0xC9, 0x8B, 0x11, 0xB5, 0x84, 0x14, 0x8A, 0x00, 0x19, 0x70, + 0x83, 0x79, 0x91, 0x97, 0x91, 0xD4, 0x1A, 0x27, 0xBF, 0x37, 0x1E, 0x32, + 0x07, 0xD8, 0x14, 0x63, 0x3C, 0x28, 0x4C, 0xAF +}; + +static const unsigned char TA167_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA168_DN[] = { + 0x30, 0x81, 0xA7, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x4E, 0x65, + 0x74, 0x4C, 0x6F, 0x63, 0x6B, 0x20, 0x4B, 0x66, 0x74, 0x2E, 0x31, 0x37, + 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x2E, 0x54, 0x61, 0x6E, + 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, 0x6E, 0x79, 0x6B, + 0x69, 0x61, 0x64, 0xC3, 0xB3, 0x6B, 0x20, 0x28, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x29, 0x31, 0x35, 0x30, 0x33, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x2C, 0x4E, 0x65, 0x74, 0x4C, 0x6F, 0x63, + 0x6B, 0x20, 0x41, 0x72, 0x61, 0x6E, 0x79, 0x20, 0x28, 0x43, 0x6C, 0x61, + 0x73, 0x73, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x29, 0x20, 0x46, 0xC5, 0x91, + 0x74, 0x61, 0x6E, 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, + 0x6E, 0x79 +}; + +static const unsigned char TA168_RSA_N[] = { + 0xC4, 0x24, 0x5E, 0x73, 0xBE, 0x4B, 0x6D, 0x14, 0xC3, 0xA1, 0xF4, 0xE3, + 0x97, 0x90, 0x6E, 0xD2, 0x30, 0x45, 0x1E, 0x3C, 0xEE, 0x67, 0xD9, 0x64, + 0xE0, 0x1A, 0x8A, 0x7F, 0xCA, 0x30, 0xCA, 0x83, 0xE3, 0x20, 0xC1, 0xE3, + 0xF4, 0x3A, 0xD3, 0x94, 0x5F, 0x1A, 0x7C, 0x5B, 0x6D, 0xBF, 0x30, 0x4F, + 0x84, 0x27, 0xF6, 0x9F, 0x1F, 0x49, 0xBC, 0xC6, 0x99, 0x0A, 0x90, 0xF2, + 0x0F, 0xF5, 0x7F, 0x43, 0x84, 0x37, 0x63, 0x51, 0x8B, 0x7A, 0xA5, 0x70, + 0xFC, 0x7A, 0x58, 0xCD, 0x8E, 0x9B, 0xED, 0xC3, 0x46, 0x6C, 0x84, 0x70, + 0x5D, 0xDA, 0xF3, 0x01, 0x90, 0x23, 0xFC, 0x4E, 0x30, 0xA9, 0x7E, 0xE1, + 0x27, 0x63, 0xE7, 0xED, 0x64, 0x3C, 0xA0, 0xB8, 0xC9, 0x33, 0x63, 0xFE, + 0x16, 0x90, 0xFF, 0xB0, 0xB8, 0xFD, 0xD7, 0xA8, 0xC0, 0xC0, 0x94, 0x43, + 0x0B, 0xB6, 0xD5, 0x59, 0xA6, 0x9E, 0x56, 0xD0, 0x24, 0x1F, 0x70, 0x79, + 0xAF, 0xDB, 0x39, 0x54, 0x0D, 0x65, 0x75, 0xD9, 0x15, 0x41, 0x94, 0x01, + 0xAF, 0x5E, 0xEC, 0xF6, 0x8D, 0xF1, 0xFF, 0xAD, 0x64, 0xFE, 0x20, 0x9A, + 0xD7, 0x5C, 0xEB, 0xFE, 0xA6, 0x1F, 0x08, 0x64, 0xA3, 0x8B, 0x76, 0x55, + 0xAD, 0x1E, 0x3B, 0x28, 0x60, 0x2E, 0x87, 0x25, 0xE8, 0xAA, 0xAF, 0x1F, + 0xC6, 0x64, 0x46, 0x20, 0xB7, 0x70, 0x7F, 0x3C, 0xDE, 0x48, 0xDB, 0x96, + 0x53, 0xB7, 0x39, 0x77, 0xE4, 0x1A, 0xE2, 0xC7, 0x16, 0x84, 0x76, 0x97, + 0x5B, 0x2F, 0xBB, 0x19, 0x15, 0x85, 0xF8, 0x69, 0x85, 0xF5, 0x99, 0xA7, + 0xA9, 0xF2, 0x34, 0xA7, 0xA9, 0xB6, 0xA6, 0x03, 0xFC, 0x6F, 0x86, 0x3D, + 0x54, 0x7C, 0x76, 0x04, 0x9B, 0x6B, 0xF9, 0x40, 0x5D, 0x00, 0x34, 0xC7, + 0x2E, 0x99, 0x75, 0x9D, 0xE5, 0x88, 0x03, 0xAA, 0x4D, 0xF8, 0x03, 0xD2, + 0x42, 0x76, 0xC0, 0x1B +}; + +static const unsigned char TA168_RSA_E[] = { + 0xA8, 0x8B +}; + +static const unsigned char TA169_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA169_RSA_N[] = { + 0xC0, 0x31, 0x82, 0x61, 0x92, 0xE4, 0x94, 0x1B, 0x0A, 0x2A, 0x65, 0xD0, + 0xBE, 0x06, 0xA9, 0x87, 0x3B, 0x51, 0x12, 0xEA, 0x70, 0x41, 0xAE, 0xE2, + 0xFB, 0x74, 0xEA, 0x0A, 0x8D, 0xB9, 0xB3, 0x4C, 0xDC, 0x8F, 0xB7, 0x13, + 0x52, 0x4F, 0x54, 0x18, 0xE1, 0x2C, 0x73, 0x95, 0x91, 0xC5, 0x66, 0x3B, + 0x6A, 0xCF, 0xAC, 0x63, 0x6D, 0x87, 0x53, 0xF0, 0xF7, 0xF1, 0x39, 0xB7, + 0xA0, 0x43, 0x63, 0xB0, 0xC4, 0x03, 0x5D, 0x57, 0xA9, 0xE7, 0x44, 0xCE, + 0xC4, 0xA1, 0x83, 0x65, 0xF6, 0x50, 0x3E, 0xB1, 0x7E, 0x16, 0xB8, 0x3A, + 0x8A, 0x02, 0xD0, 0x96, 0x1F, 0x00, 0xCD, 0x05, 0x21, 0xEF, 0x06, 0x6D, + 0xDD, 0x21, 0x9C, 0x19, 0x43, 0x45, 0xA1, 0xC5, 0xE8, 0x80, 0xCA, 0xC2, + 0xAD, 0x40, 0x62, 0x17, 0x06, 0xC6, 0xAA, 0xBC, 0xF3, 0xD6, 0xE6, 0xFC, + 0x50, 0x7E, 0x66, 0x42, 0x1F, 0x3C, 0x8B, 0xA6, 0x79, 0x79, 0x86, 0x40, + 0x35, 0x9F, 0x20, 0xEF, 0x3F, 0xEB, 0x8B, 0x47, 0x1F, 0x8F, 0x8E, 0xC5, + 0xD4, 0x8E, 0xB6, 0x2C, 0xC9, 0x44, 0x04, 0xE3, 0xD4, 0x43, 0x75, 0x3F, + 0xD5, 0x3F, 0xAF, 0x1C, 0xCC, 0x7E, 0x46, 0x5F, 0xAC, 0xDF, 0x64, 0x10, + 0x8A, 0xEF, 0x46, 0xF0, 0x90, 0xF0, 0x0F, 0x2D, 0xF4, 0x88, 0x0B, 0xB1, + 0x29, 0xAA, 0xAF, 0x85, 0xAA, 0x49, 0x58, 0xA8, 0xBF, 0x63, 0xA0, 0x38, + 0x91, 0xE6, 0xB3, 0xE6, 0x77, 0x68, 0xC4, 0xF9, 0x2A, 0x19, 0x84, 0xBB, + 0x0E, 0xE1, 0xF5, 0xAF, 0x89, 0xEC, 0xA5, 0x2F, 0x50, 0x20, 0x74, 0x1E, + 0x12, 0x41, 0x73, 0x1E, 0x24, 0xD9, 0xCA, 0xCE, 0x2C, 0xA1, 0x59, 0x35, + 0xC0, 0xC8, 0x1D, 0x46, 0x27, 0x61, 0x5A, 0x8F, 0xF9, 0x4D, 0xD3, 0x72, + 0x79, 0x66, 0x1E, 0x9F, 0x15, 0x90, 0x21, 0x2D, 0xFD, 0xED, 0x8B, 0x56, + 0x70, 0x03, 0x4A, 0x49, 0x3E, 0x7F, 0x69, 0x31, 0x12, 0x69, 0xC7, 0x1E, + 0x5C, 0xCA, 0x7A, 0x13, 0x8B, 0xE8, 0xE6, 0xF5, 0x60, 0x0F, 0xCC, 0x93, + 0x2C, 0x84, 0x7F, 0xF1, 0xFC, 0x6A, 0xFC, 0x9B, 0x47, 0x9D, 0xDB, 0xAD, + 0x88, 0x3D, 0xF3, 0x76, 0x75, 0x33, 0xD7, 0x4B, 0xA4, 0xC8, 0x8B, 0xF9, + 0xF5, 0x43, 0x58, 0x4F, 0xCB, 0xC8, 0x03, 0x54, 0x8F, 0xA5, 0x85, 0x78, + 0x04, 0x1A, 0xF3, 0x73, 0xF2, 0xD7, 0x87, 0x1D, 0x41, 0x9F, 0xE7, 0xD8, + 0x17, 0xCE, 0x1A, 0x9C, 0x0F, 0x4A, 0xFC, 0xDC, 0x44, 0x68, 0x54, 0x68, + 0xE2, 0x41, 0x3C, 0xFE, 0x2C, 0x84, 0x86, 0x37, 0x3C, 0xCD, 0x3F, 0x2F, + 0xA2, 0xDB, 0xE7, 0xF7, 0x54, 0x03, 0x5F, 0x59, 0xD3, 0xF7, 0x91, 0x78, + 0xC7, 0x8B, 0x77, 0x6A, 0x16, 0xE5, 0x49, 0x85, 0x90, 0x45, 0x72, 0x70, + 0x2F, 0x91, 0x5D, 0xF8, 0x3E, 0x65, 0x40, 0x0B, 0x19, 0x99, 0xC9, 0x26, + 0x20, 0x5A, 0x68, 0xC1, 0x35, 0xBF, 0x4F, 0xA7, 0x51, 0xF1, 0xD8, 0x11, + 0x2B, 0x5B, 0xE0, 0x9A, 0x9E, 0x28, 0x3B, 0x0A, 0x3A, 0x0A, 0x1F, 0xC1, + 0x81, 0xE5, 0x2E, 0xF0, 0xA6, 0xB9, 0x69, 0xA5, 0x88, 0x94, 0xE6, 0x6B, + 0x13, 0x7F, 0xD1, 0x64, 0x3F, 0x3D, 0x9C, 0x70, 0x46, 0xE5, 0xA2, 0x85, + 0x7B, 0x58, 0x84, 0x27, 0xDC, 0xC4, 0x80, 0x3E, 0x67, 0x9A, 0x9A, 0xC7, + 0x9A, 0x31, 0x0E, 0x30, 0xEC, 0xE6, 0x17, 0x40, 0x95, 0xD9, 0x45, 0xED, + 0x01, 0x96, 0xAA, 0xBF, 0x0C, 0xF3, 0x4B, 0xD1, 0x63, 0xF7, 0x13, 0x58, + 0xC0, 0xB8, 0xF3, 0xFA, 0x67, 0xDD, 0x9B, 0x7D, 0x6D, 0x4A, 0xFF, 0x32, + 0x4C, 0xB5, 0x25, 0x3B, 0xFF, 0x1C, 0x67, 0x0F, 0x85, 0x22, 0x59, 0x05, + 0x91, 0x91, 0x41, 0x77, 0x81, 0xD0, 0x85, 0x4C, 0x87, 0x10, 0x71, 0xFF, + 0x9E, 0x43, 0x1B, 0xAE, 0x95, 0x75, 0x2D, 0x81 +}; + +static const unsigned char TA169_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA170_DN[] = { + 0x30, 0x43, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, + 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0D, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA170_RSA_N[] = { + 0xBD, 0x55, 0x7C, 0x61, 0xD3, 0xB8, 0x1D, 0x04, 0x62, 0x05, 0xA0, 0xAE, + 0x6C, 0xB7, 0x70, 0xB4, 0x41, 0xEA, 0x4B, 0x03, 0x5E, 0x10, 0x3F, 0x90, + 0x5A, 0x1C, 0x8B, 0x3B, 0xB0, 0x66, 0x8B, 0x6C, 0x48, 0xA6, 0x1C, 0x22, + 0xBA, 0xD5, 0x40, 0x92, 0xEE, 0x33, 0xB2, 0x23, 0x59, 0xC9, 0x8E, 0xBC, + 0x58, 0xDA, 0x8B, 0x9E, 0xD0, 0x19, 0xF2, 0x2F, 0x59, 0xC6, 0x8C, 0x63, + 0x5A, 0xBA, 0x9F, 0xA3, 0x0B, 0xB0, 0xB3, 0x9A, 0x5C, 0xBA, 0x11, 0xB8, + 0x12, 0xE9, 0x0C, 0xBB, 0xCF, 0x6E, 0x6C, 0x80, 0x87, 0x29, 0x14, 0x03, + 0x2C, 0x8D, 0x24, 0x9A, 0xC8, 0x64, 0x83, 0xB5, 0x6A, 0xAC, 0x13, 0x2C, + 0x33, 0xF1, 0x9F, 0xDC, 0x2C, 0x61, 0x3C, 0x1A, 0x3F, 0x70, 0x55, 0x9B, + 0xAD, 0x00, 0x52, 0x7F, 0xCF, 0x04, 0xB9, 0xFE, 0x36, 0xFA, 0x9C, 0xC0, + 0x16, 0xAE, 0x62, 0xFE, 0x96, 0x4C, 0x43, 0x7E, 0x55, 0x14, 0xBE, 0x1A, + 0xB3, 0xD2, 0x6D, 0xC2, 0xAF, 0x76, 0x66, 0x95, 0x6B, 0x2A, 0xB0, 0x94, + 0x77, 0x85, 0x5E, 0x04, 0x0F, 0x62, 0x1D, 0x63, 0x75, 0xF7, 0x6B, 0xE7, + 0xCB, 0x5B, 0x9A, 0x70, 0xEC, 0x3E, 0x67, 0x05, 0xF0, 0xFE, 0x07, 0x08, + 0x80, 0xCF, 0x28, 0xDB, 0x05, 0xC6, 0x14, 0x27, 0x2F, 0x86, 0x7D, 0xF0, + 0x27, 0xDE, 0xFF, 0xE6, 0x7E, 0x33, 0x48, 0xE7, 0x0B, 0x1E, 0x58, 0xD1, + 0x27, 0x2B, 0x53, 0x0E, 0x57, 0x4A, 0x65, 0xD7, 0xFB, 0xA2, 0x80, 0x60, + 0xFC, 0x4C, 0xBC, 0x35, 0x53, 0x01, 0x6A, 0x97, 0x72, 0x82, 0xAF, 0xF1, + 0x1D, 0x70, 0xE8, 0x9C, 0xF5, 0xEF, 0x5E, 0xC2, 0x6C, 0xC7, 0x47, 0x7E, + 0x5A, 0x94, 0x85, 0x26, 0x4D, 0x3B, 0xBA, 0xEB, 0x4C, 0xE8, 0xB0, 0x09, + 0xC2, 0x65, 0xC2, 0x9D, 0x9D, 0x09, 0x9B, 0x4E, 0xB5, 0x97, 0x05, 0xAC, + 0xF5, 0x06, 0xA0, 0xF7, 0x36, 0x05, 0x7E, 0xF4, 0x90, 0xB2, 0x6B, 0xC4, + 0xB4, 0xF9, 0x64, 0xEA, 0xE9, 0x1A, 0x0A, 0xC8, 0x0D, 0xA8, 0xED, 0x27, + 0xC9, 0xD4, 0xE7, 0xB3, 0xB9, 0xAB, 0x82, 0x22, 0x90, 0x27, 0x3D, 0x2A, + 0xE8, 0x7C, 0x90, 0xEF, 0xBC, 0x4F, 0xFD, 0xE2, 0x0A, 0x24, 0xA7, 0xDE, + 0x65, 0x24, 0xA4, 0x5D, 0xEA, 0xC0, 0x76, 0x30, 0xD3, 0x77, 0x50, 0xF8, + 0x0D, 0x04, 0x9B, 0x94, 0x36, 0x01, 0x73, 0xCA, 0x06, 0x58, 0xA6, 0xD3, + 0x3B, 0xDC, 0xFA, 0x04, 0x46, 0x13, 0x55, 0x8A, 0xC9, 0x44, 0x47, 0xB8, + 0x51, 0x39, 0x1A, 0x2E, 0xE8, 0x34, 0xE2, 0x79, 0xCB, 0x59, 0x4A, 0x0A, + 0x7F, 0xBC, 0xA6, 0xEF, 0x1F, 0x03, 0x67, 0x6A, 0x59, 0x2B, 0x25, 0x62, + 0x93, 0xD9, 0x53, 0x19, 0x66, 0x3C, 0x27, 0x62, 0x29, 0x86, 0x4D, 0xA4, + 0x6B, 0xEE, 0xFF, 0xD4, 0x4E, 0xBA, 0xD5, 0xB4, 0xE2, 0x8E, 0x48, 0x5A, + 0x00, 0x19, 0x09, 0xF1, 0x05, 0xD9, 0xCE, 0x91, 0xB1, 0xF7, 0xEB, 0xE9, + 0x39, 0x4F, 0xF6, 0x6F, 0x04, 0x43, 0x9A, 0x55, 0xF5, 0x3E, 0x05, 0x14, + 0xBD, 0xBF, 0xB3, 0x59, 0xB4, 0xD8, 0x8E, 0x33, 0x84, 0xA3, 0x90, 0x52, + 0xAA, 0xB3, 0x02, 0x95, 0x60, 0xF9, 0x0C, 0x4C, 0x68, 0xF9, 0xEE, 0xD5, + 0x17, 0x0D, 0xF8, 0x71, 0x57, 0xB5, 0x25, 0xE4, 0x29, 0xEE, 0x65, 0x5D, + 0xAF, 0xD1, 0xEE, 0x3C, 0x17, 0x0B, 0x5A, 0x43, 0xC5, 0xA5, 0x86, 0xEA, + 0x24, 0x9E, 0xE2, 0x05, 0x07, 0xDC, 0x34, 0x42, 0x12, 0x91, 0xD6, 0x39, + 0x74, 0xAE, 0x4C, 0x41, 0x82, 0xDB, 0xF2, 0xA6, 0x48, 0xD1, 0xB3, 0x9B, + 0xF3, 0x33, 0xAA, 0xF3, 0xA6, 0xC0, 0xC5, 0x4E, 0xF5, 0xF4, 0x9D, 0x76, + 0x63, 0xE6, 0x02, 0xC6, 0x22, 0x4B, 0xC1, 0x95, 0x3F, 0x50, 0x64, 0x2C, + 0x54, 0xE5, 0xB6, 0xF0, 0x3C, 0x29, 0xCF, 0x57 +}; + +static const unsigned char TA170_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA171_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA171_EC_Q[] = { + 0x04, 0x6B, 0xDA, 0x0D, 0x75, 0x35, 0x08, 0x31, 0x47, 0x05, 0xAE, 0x45, + 0x99, 0x55, 0xF1, 0x11, 0x13, 0x2E, 0x4A, 0xF8, 0x10, 0x31, 0x23, 0xA3, + 0x7E, 0x83, 0xD3, 0x7F, 0x28, 0x08, 0x3A, 0x26, 0x1A, 0x3A, 0xCF, 0x97, + 0x82, 0x1F, 0x80, 0xB7, 0x27, 0x09, 0x8F, 0xD1, 0x8E, 0x30, 0xC4, 0x0A, + 0x9B, 0x0E, 0xAC, 0x58, 0x04, 0xAB, 0xF7, 0x36, 0x7D, 0x94, 0x23, 0xA4, + 0x9B, 0x0A, 0x8A, 0x8B, 0xAB, 0xEB, 0xFD, 0x39, 0x25, 0x66, 0xF1, 0x5E, + 0xFE, 0x8C, 0xAE, 0x8D, 0x41, 0x79, 0x9D, 0x09, 0x60, 0xCE, 0x28, 0xA9, + 0xD3, 0x8A, 0x6D, 0xF3, 0xD6, 0x45, 0xD4, 0xF2, 0x98, 0x84, 0x38, 0x65, + 0xA0 +}; + +static const unsigned char TA172_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA172_RSA_N[] = { + 0xB6, 0x80, 0x0E, 0xC4, 0x79, 0xBD, 0x05, 0x8C, 0x7D, 0xB0, 0xA3, 0x9D, + 0x4D, 0x22, 0x4D, 0xCB, 0xF0, 0x41, 0x97, 0x4D, 0x59, 0xE0, 0xD1, 0xFE, + 0x56, 0x8C, 0x97, 0xF2, 0xD7, 0xBD, 0x8F, 0x6C, 0xB7, 0x23, 0x8F, 0x5F, + 0xD5, 0xC4, 0xD8, 0x41, 0xCB, 0xF2, 0x02, 0x1E, 0x71, 0xE5, 0xE9, 0xF6, + 0x5E, 0xCB, 0x08, 0x2A, 0x5E, 0x30, 0xF2, 0x2D, 0x66, 0xC7, 0x84, 0x1B, + 0x64, 0x57, 0x38, 0x9D, 0x75, 0x2D, 0x56, 0xC6, 0x2F, 0x61, 0xEF, 0x96, + 0xFC, 0x20, 0x46, 0xBD, 0xEB, 0xD4, 0x7B, 0x3F, 0x3F, 0x7C, 0x47, 0x38, + 0x04, 0xA9, 0x1B, 0xAA, 0x52, 0xDF, 0x13, 0x37, 0xD3, 0x15, 0x15, 0x4E, + 0xBD, 0x5F, 0x7C, 0xAF, 0xAD, 0x63, 0xC7, 0x79, 0xDC, 0x08, 0x7B, 0xD5, + 0xA0, 0xE5, 0xF7, 0x5B, 0x75, 0xAC, 0x80, 0x55, 0x99, 0x92, 0x61, 0x9B, + 0xCD, 0x2A, 0x17, 0x7D, 0xDB, 0x8F, 0xF4, 0xB5, 0x6A, 0xEA, 0x17, 0x4A, + 0x64, 0x28, 0x66, 0x15, 0x29, 0x6C, 0x02, 0xF1, 0x6B, 0xD5, 0xBA, 0xA3, + 0x33, 0xDC, 0x5A, 0x67, 0xA7, 0x05, 0xE2, 0xBF, 0x65, 0xB6, 0x16, 0xB0, + 0x10, 0xED, 0xCD, 0x50, 0x33, 0xC9, 0x70, 0x50, 0xEC, 0x19, 0x8E, 0xB0, + 0xC7, 0xF2, 0x74, 0x5B, 0x6B, 0x44, 0xC6, 0x7D, 0x96, 0xB9, 0x98, 0x08, + 0x59, 0x66, 0xDE, 0x29, 0x01, 0x9B, 0xF4, 0x2A, 0x6D, 0xD3, 0x15, 0x3A, + 0x90, 0x6A, 0x67, 0xF1, 0xB4, 0x6B, 0x66, 0xD9, 0x21, 0xEB, 0xCA, 0xD9, + 0x62, 0x7C, 0x46, 0x10, 0x5C, 0xDE, 0x75, 0x49, 0x67, 0x9E, 0x42, 0xF9, + 0xFE, 0x75, 0xA9, 0xA3, 0xAD, 0xFF, 0x76, 0x0A, 0x67, 0x40, 0xE3, 0xC5, + 0xF7, 0x8D, 0xC7, 0x85, 0x9A, 0x59, 0x9E, 0x62, 0x9A, 0x6A, 0xED, 0x45, + 0x87, 0x98, 0x67, 0xB2, 0xD5, 0x4A, 0x3C, 0xD7, 0xB4, 0x3B, 0x00, 0x0D, + 0xC0, 0x8F, 0x1F, 0xE1, 0x40, 0xC4, 0xAE, 0x6C, 0x21, 0xDC, 0x49, 0x7E, + 0x7E, 0xCA, 0xB2, 0x8D, 0x6D, 0xB6, 0xBF, 0x93, 0x2F, 0xA1, 0x5C, 0x3E, + 0x8F, 0xCA, 0xED, 0x80, 0x8E, 0x58, 0xE1, 0xDB, 0x57, 0xCF, 0x85, 0x36, + 0x38, 0xB2, 0x71, 0xA4, 0x09, 0x8C, 0x92, 0x89, 0x08, 0x88, 0x48, 0xF1, + 0x40, 0x63, 0x18, 0xB2, 0x5B, 0x8C, 0x5A, 0xE3, 0xC3, 0xD3, 0x17, 0xAA, + 0xAB, 0x19, 0xA3, 0x2C, 0x1B, 0xE4, 0xD5, 0xC6, 0xE2, 0x66, 0x7A, 0xD7, + 0x82, 0x19, 0xA6, 0x3B, 0x16, 0x2C, 0x2F, 0x71, 0x87, 0x5F, 0x45, 0x9E, + 0x95, 0x73, 0x93, 0xC2, 0x42, 0x81, 0x21, 0x13, 0x96, 0xD7, 0x9D, 0xBB, + 0x93, 0x68, 0x15, 0xFA, 0x9D, 0xA4, 0x1D, 0x8C, 0xF2, 0x81, 0xE0, 0x58, + 0x06, 0xBD, 0xC9, 0xB6, 0xE3, 0xF6, 0x89, 0x5D, 0x89, 0xF9, 0xAC, 0x44, + 0xA1, 0xCB, 0x6B, 0xFA, 0x16, 0xF1, 0xC7, 0x50, 0x3D, 0x24, 0xDA, 0xF7, + 0xC3, 0xE4, 0x87, 0xD5, 0x56, 0xF1, 0x4F, 0x90, 0x30, 0xFA, 0x45, 0x09, + 0x59, 0xDA, 0x34, 0xCE, 0xE0, 0x13, 0x1C, 0x04, 0x7C, 0x00, 0xD4, 0x9B, + 0x86, 0xA4, 0x40, 0xBC, 0xD9, 0xDC, 0x4C, 0x57, 0x7E, 0xAE, 0xB7, 0x33, + 0xB6, 0x5E, 0x76, 0xE1, 0x65, 0x8B, 0x66, 0xDF, 0x8D, 0xCA, 0xD7, 0x98, + 0xAF, 0xCE, 0x36, 0x98, 0x8C, 0x9C, 0x83, 0x99, 0x03, 0x70, 0xF3, 0xAF, + 0x74, 0xED, 0xC6, 0x0E, 0x36, 0xE7, 0xBD, 0xEC, 0xC1, 0x73, 0xA7, 0x94, + 0x5A, 0xCB, 0x92, 0x64, 0x82, 0xA6, 0x00, 0xC1, 0x70, 0xA1, 0x6E, 0x2C, + 0x29, 0xE1, 0x58, 0x57, 0xEC, 0x5A, 0x7C, 0x99, 0x6B, 0x25, 0xA4, 0x90, + 0x3A, 0x80, 0xF4, 0x20, 0x9D, 0x9A, 0xCE, 0xC7, 0x2D, 0xF9, 0xB2, 0x4B, + 0x29, 0x95, 0x83, 0xE9, 0x35, 0x8D, 0xA7, 0x49, 0x48, 0xA7, 0x0F, 0x4C, + 0x19, 0x91, 0xD0, 0xF5, 0xBF, 0x10, 0xE0, 0x71 +}; + +static const unsigned char TA172_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA173_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x32, 0x35, 0x36, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA173_EC_Q[] = { + 0x04, 0x7E, 0xFB, 0x6C, 0xE6, 0x23, 0xE3, 0x73, 0x32, 0x08, 0xCA, 0x60, + 0xE6, 0x53, 0x9C, 0xBA, 0x74, 0x8D, 0x18, 0xB0, 0x78, 0x90, 0x52, 0x80, + 0xDD, 0x38, 0xC0, 0x4A, 0x1D, 0xD1, 0xA8, 0xCC, 0x93, 0xA4, 0x97, 0x06, + 0x38, 0xCA, 0x0D, 0x15, 0x62, 0xC6, 0x8E, 0x01, 0x2A, 0x65, 0x9D, 0xAA, + 0xDF, 0x34, 0x91, 0x2E, 0x81, 0xC1, 0xE4, 0x33, 0x92, 0x31, 0xC4, 0xFD, + 0x09, 0x3A, 0xA6, 0x3F, 0xAD +}; + +static const unsigned char TA174_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA174_RSA_N[] = { + 0xC0, 0x31, 0x82, 0x61, 0x92, 0xE4, 0x94, 0x1B, 0x0A, 0x2A, 0x65, 0xD0, + 0xBE, 0x06, 0xA9, 0x87, 0x3B, 0x51, 0x12, 0xEA, 0x70, 0x41, 0xAE, 0xE2, + 0xFB, 0x74, 0xEA, 0x0A, 0x8D, 0xB9, 0xB3, 0x4C, 0xDC, 0x8F, 0xB7, 0x13, + 0x52, 0x4F, 0x54, 0x18, 0xE1, 0x2C, 0x73, 0x95, 0x91, 0xC5, 0x66, 0x3B, + 0x6A, 0xCF, 0xAC, 0x63, 0x6D, 0x87, 0x53, 0xF0, 0xF7, 0xF1, 0x39, 0xB7, + 0xA0, 0x43, 0x63, 0xB0, 0xC4, 0x03, 0x5D, 0x57, 0xA9, 0xE7, 0x44, 0xCE, + 0xC4, 0xA1, 0x83, 0x65, 0xF6, 0x50, 0x3E, 0xB1, 0x7E, 0x16, 0xB8, 0x3A, + 0x8A, 0x02, 0xD0, 0x96, 0x1F, 0x00, 0xCD, 0x05, 0x21, 0xEF, 0x06, 0x6D, + 0xDD, 0x21, 0x9C, 0x19, 0x43, 0x45, 0xA1, 0xC5, 0xE8, 0x80, 0xCA, 0xC2, + 0xAD, 0x40, 0x62, 0x17, 0x06, 0xC6, 0xAA, 0xBC, 0xF3, 0xD6, 0xE6, 0xFC, + 0x50, 0x7E, 0x66, 0x42, 0x1F, 0x3C, 0x8B, 0xA6, 0x79, 0x79, 0x86, 0x40, + 0x35, 0x9F, 0x20, 0xEF, 0x3F, 0xEB, 0x8B, 0x47, 0x1F, 0x8F, 0x8E, 0xC5, + 0xD4, 0x8E, 0xB6, 0x2C, 0xC9, 0x44, 0x04, 0xE3, 0xD4, 0x43, 0x75, 0x3F, + 0xD5, 0x3F, 0xAF, 0x1C, 0xCC, 0x7E, 0x46, 0x5F, 0xAC, 0xDF, 0x64, 0x10, + 0x8A, 0xEF, 0x46, 0xF0, 0x90, 0xF0, 0x0F, 0x2D, 0xF4, 0x88, 0x0B, 0xB1, + 0x29, 0xAA, 0xAF, 0x85, 0xAA, 0x49, 0x58, 0xA8, 0xBF, 0x63, 0xA0, 0x38, + 0x91, 0xE6, 0xB3, 0xE6, 0x77, 0x68, 0xC4, 0xF9, 0x2A, 0x19, 0x84, 0xBB, + 0x0E, 0xE1, 0xF5, 0xAF, 0x89, 0xEC, 0xA5, 0x2F, 0x50, 0x20, 0x74, 0x1E, + 0x12, 0x41, 0x73, 0x1E, 0x24, 0xD9, 0xCA, 0xCE, 0x2C, 0xA1, 0x59, 0x35, + 0xC0, 0xC8, 0x1D, 0x46, 0x27, 0x61, 0x5A, 0x8F, 0xF9, 0x4D, 0xD3, 0x72, + 0x79, 0x66, 0x1E, 0x9F, 0x15, 0x90, 0x21, 0x2D, 0xFD, 0xED, 0x8B, 0x56, + 0x70, 0x03, 0x4A, 0x49, 0x3E, 0x7F, 0x69, 0x31, 0x12, 0x69, 0xC7, 0x1E, + 0x5C, 0xCA, 0x7A, 0x13, 0x8B, 0xE8, 0xE6, 0xF5, 0x60, 0x0F, 0xCC, 0x93, + 0x2C, 0x84, 0x7F, 0xF1, 0xFC, 0x6A, 0xFC, 0x9B, 0x47, 0x9D, 0xDB, 0xAD, + 0x88, 0x3D, 0xF3, 0x76, 0x75, 0x33, 0xD7, 0x4B, 0xA4, 0xC8, 0x8B, 0xF9, + 0xF5, 0x43, 0x58, 0x4F, 0xCB, 0xC8, 0x03, 0x54, 0x8F, 0xA5, 0x85, 0x78, + 0x04, 0x1A, 0xF3, 0x73, 0xF2, 0xD7, 0x87, 0x1D, 0x41, 0x9F, 0xE7, 0xD8, + 0x17, 0xCE, 0x1A, 0x9C, 0x0F, 0x4A, 0xFC, 0xDC, 0x44, 0x68, 0x54, 0x68, + 0xE2, 0x41, 0x3C, 0xFE, 0x2C, 0x84, 0x86, 0x37, 0x3C, 0xCD, 0x3F, 0x2F, + 0xA2, 0xDB, 0xE7, 0xF7, 0x54, 0x03, 0x5F, 0x59, 0xD3, 0xF7, 0x91, 0x78, + 0xC7, 0x8B, 0x77, 0x6A, 0x16, 0xE5, 0x49, 0x85, 0x90, 0x45, 0x72, 0x70, + 0x2F, 0x91, 0x5D, 0xF8, 0x3E, 0x65, 0x40, 0x0B, 0x19, 0x99, 0xC9, 0x26, + 0x20, 0x5A, 0x68, 0xC1, 0x35, 0xBF, 0x4F, 0xA7, 0x51, 0xF1, 0xD8, 0x11, + 0x2B, 0x5B, 0xE0, 0x9A, 0x9E, 0x28, 0x3B, 0x0A, 0x3A, 0x0A, 0x1F, 0xC1, + 0x81, 0xE5, 0x2E, 0xF0, 0xA6, 0xB9, 0x69, 0xA5, 0x88, 0x94, 0xE6, 0x6B, + 0x13, 0x7F, 0xD1, 0x64, 0x3F, 0x3D, 0x9C, 0x70, 0x46, 0xE5, 0xA2, 0x85, + 0x7B, 0x58, 0x84, 0x27, 0xDC, 0xC4, 0x80, 0x3E, 0x67, 0x9A, 0x9A, 0xC7, + 0x9A, 0x31, 0x0E, 0x30, 0xEC, 0xE6, 0x17, 0x40, 0x95, 0xD9, 0x45, 0xED, + 0x01, 0x96, 0xAA, 0xBF, 0x0C, 0xF3, 0x4B, 0xD1, 0x63, 0xF7, 0x13, 0x58, + 0xC0, 0xB8, 0xF3, 0xFA, 0x67, 0xDD, 0x9B, 0x7D, 0x6D, 0x4A, 0xFF, 0x32, + 0x4C, 0xB5, 0x25, 0x3B, 0xFF, 0x1C, 0x67, 0x0F, 0x85, 0x22, 0x59, 0x05, + 0x91, 0x91, 0x41, 0x77, 0x81, 0xD0, 0x85, 0x4C, 0x87, 0x10, 0x71, 0xFF, + 0x9E, 0x43, 0x1B, 0xAE, 0x95, 0x75, 0x2D, 0x81 +}; + +static const unsigned char TA174_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA175_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA175_EC_Q[] = { + 0x04, 0x0D, 0x30, 0x5E, 0x1B, 0x15, 0x9D, 0x03, 0xD0, 0xA1, 0x79, 0x35, + 0xB7, 0x3A, 0x3C, 0x92, 0x7A, 0xCA, 0x15, 0x1C, 0xCD, 0x62, 0xF3, 0x9C, + 0x26, 0x5C, 0x07, 0x3D, 0xE5, 0x54, 0xFA, 0xA3, 0xD6, 0xCC, 0x12, 0xEA, + 0xF4, 0x14, 0x5F, 0xE8, 0x8E, 0x19, 0xAB, 0x2F, 0x2E, 0x48, 0xE6, 0xAC, + 0x18, 0x43, 0x78, 0xAC, 0xD0, 0x37, 0xC3, 0xBD, 0xB2, 0xCD, 0x2C, 0xE6, + 0x47, 0xE2, 0x1A, 0xE6, 0x63, 0xB8, 0x3D, 0x2E, 0x2F, 0x78, 0xC4, 0x4F, + 0xDB, 0xF4, 0x0F, 0xA4, 0x68, 0x4C, 0x55, 0x72, 0x6B, 0x95, 0x1D, 0x4E, + 0x18, 0x42, 0x95, 0x78, 0xCC, 0x37, 0x3C, 0x91, 0xE2, 0x9B, 0x65, 0x2B, + 0x29 +}; + +static const unsigned char TA176_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA176_RSA_N[] = { + 0xD9, 0xE7, 0x28, 0x2F, 0x52, 0x3F, 0x36, 0x72, 0x49, 0x88, 0x93, 0x34, + 0xF3, 0xF8, 0x6A, 0x1E, 0x31, 0x54, 0x80, 0x9F, 0xAD, 0x54, 0x41, 0xB5, + 0x47, 0xDF, 0x96, 0xA8, 0xD4, 0xAF, 0x80, 0x2D, 0xB9, 0x0A, 0xCF, 0x75, + 0xFD, 0x89, 0xA5, 0x7D, 0x24, 0xFA, 0xE3, 0x22, 0x0C, 0x2B, 0xBC, 0x95, + 0x17, 0x0B, 0x33, 0xBF, 0x19, 0x4D, 0x41, 0x06, 0x90, 0x00, 0xBD, 0x0C, + 0x4D, 0x10, 0xFE, 0x07, 0xB5, 0xE7, 0x1C, 0x6E, 0x22, 0x55, 0x31, 0x65, + 0x97, 0xBD, 0xD3, 0x17, 0xD2, 0x1E, 0x62, 0xF3, 0xDB, 0xEA, 0x6C, 0x50, + 0x8C, 0x3F, 0x84, 0x0C, 0x96, 0xCF, 0xB7, 0xCB, 0x03, 0xE0, 0xCA, 0x6D, + 0xA1, 0x14, 0x4C, 0x1B, 0x89, 0xDD, 0xED, 0x00, 0xB0, 0x52, 0x7C, 0xAF, + 0x91, 0x6C, 0xB1, 0x38, 0x13, 0xD1, 0xE9, 0x12, 0x08, 0xC0, 0x00, 0xB0, + 0x1C, 0x2B, 0x11, 0xDA, 0x77, 0x70, 0x36, 0x9B, 0xAE, 0xCE, 0x79, 0x87, + 0xDC, 0x82, 0x70, 0xE6, 0x09, 0x74, 0x70, 0x55, 0x69, 0xAF, 0xA3, 0x68, + 0x9F, 0xBF, 0xDD, 0xB6, 0x79, 0xB3, 0xF2, 0x9D, 0x70, 0x29, 0x55, 0xF4, + 0xAB, 0xFF, 0x95, 0x61, 0xF3, 0xC9, 0x40, 0x6F, 0x1D, 0xD1, 0xBE, 0x93, + 0xBB, 0xD3, 0x88, 0x2A, 0xBB, 0x9D, 0xBF, 0x72, 0x5A, 0x56, 0x71, 0x3B, + 0x3F, 0xD4, 0xF3, 0xD1, 0x0A, 0xFE, 0x28, 0xEF, 0xA3, 0xEE, 0xD9, 0x99, + 0xAF, 0x03, 0xD3, 0x8F, 0x60, 0xB7, 0xF2, 0x92, 0xA1, 0xB1, 0xBD, 0x89, + 0x89, 0x1F, 0x30, 0xCD, 0xC3, 0xA6, 0x2E, 0x62, 0x33, 0xAE, 0x16, 0x02, + 0x77, 0x44, 0x5A, 0xE7, 0x81, 0x0A, 0x3C, 0xA7, 0x44, 0x2E, 0x79, 0xB8, + 0x3F, 0x04, 0xBC, 0x5C, 0xA0, 0x87, 0xE1, 0x1B, 0xAF, 0x51, 0x8E, 0xCD, + 0xEC, 0x2C, 0xFA, 0xF8, 0xFE, 0x6D, 0xF0, 0x3A, 0x7C, 0xAA, 0x8B, 0xE4, + 0x67, 0x95, 0x31, 0x8D +}; + +static const unsigned char TA176_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA177_DN[] = { + 0x30, 0x5E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x21, 0x65, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA177_RSA_N[] = { + 0xE1, 0x25, 0x0F, 0xEE, 0x8D, 0xDB, 0x88, 0x33, 0x75, 0x67, 0xCD, 0xAD, + 0x1F, 0x7D, 0x3A, 0x4E, 0x6D, 0x9D, 0xD3, 0x2F, 0x14, 0xF3, 0x63, 0x74, + 0xCB, 0x01, 0x21, 0x6A, 0x37, 0xEA, 0x84, 0x50, 0x07, 0x4B, 0x26, 0x5B, + 0x09, 0x43, 0x6C, 0x21, 0x9E, 0x6A, 0xC8, 0xD5, 0x03, 0xF5, 0x60, 0x69, + 0x8F, 0xCC, 0xF0, 0x22, 0xE4, 0x1F, 0xE7, 0xF7, 0x6A, 0x22, 0x31, 0xB7, + 0x2C, 0x15, 0xF2, 0xE0, 0xFE, 0x00, 0x6A, 0x43, 0xFF, 0x87, 0x65, 0xC6, + 0xB5, 0x1A, 0xC1, 0xA7, 0x4C, 0x6D, 0x22, 0x70, 0x21, 0x8A, 0x31, 0xF2, + 0x97, 0x74, 0x89, 0x09, 0x12, 0x26, 0x1C, 0x9E, 0xCA, 0xD9, 0x12, 0xA2, + 0x95, 0x3C, 0xDA, 0xE9, 0x67, 0xBF, 0x08, 0xA0, 0x64, 0xE3, 0xD6, 0x42, + 0xB7, 0x45, 0xEF, 0x97, 0xF4, 0xF6, 0xF5, 0xD7, 0xB5, 0x4A, 0x15, 0x02, + 0x58, 0x7D, 0x98, 0x58, 0x4B, 0x60, 0xBC, 0xCD, 0xD7, 0x0D, 0x9A, 0x13, + 0x33, 0x53, 0xD1, 0x61, 0xF9, 0x7A, 0xD5, 0xD7, 0x78, 0xB3, 0x9A, 0x33, + 0xF7, 0x00, 0x86, 0xCE, 0x1D, 0x4D, 0x94, 0x38, 0xAF, 0xA8, 0xEC, 0x78, + 0x51, 0x70, 0x8A, 0x5C, 0x10, 0x83, 0x51, 0x21, 0xF7, 0x11, 0x3D, 0x34, + 0x86, 0x5E, 0xE5, 0x48, 0xCD, 0x97, 0x81, 0x82, 0x35, 0x4C, 0x19, 0xEC, + 0x65, 0xF6, 0x6B, 0xC5, 0x05, 0xA1, 0xEE, 0x47, 0x13, 0xD6, 0xB3, 0x21, + 0x27, 0x94, 0x10, 0x0A, 0xD9, 0x24, 0x3B, 0xBA, 0xBE, 0x44, 0x13, 0x46, + 0x30, 0x3F, 0x97, 0x3C, 0xD8, 0xD7, 0xD7, 0x6A, 0xEE, 0x3B, 0x38, 0xE3, + 0x2B, 0xD4, 0x97, 0x0E, 0xB9, 0x1B, 0xE7, 0x07, 0x49, 0x7F, 0x37, 0x2A, + 0xF9, 0x77, 0x78, 0xCF, 0x54, 0xED, 0x5B, 0x46, 0x9D, 0xA3, 0x80, 0x0E, + 0x91, 0x43, 0xC1, 0xD6, 0x5B, 0x5F, 0x14, 0xBA, 0x9F, 0xA6, 0x8D, 0x24, + 0x47, 0x40, 0x59, 0xBF, 0x72, 0x38, 0xB2, 0x36, 0x6C, 0x37, 0xFF, 0x99, + 0xD1, 0x5D, 0x0E, 0x59, 0x0A, 0xAB, 0x69, 0xF7, 0xC0, 0xB2, 0x04, 0x45, + 0x7A, 0x54, 0x00, 0xAE, 0xBE, 0x53, 0xF6, 0xB5, 0xE7, 0xE1, 0xF8, 0x3C, + 0xA3, 0x31, 0xD2, 0xA9, 0xFE, 0x21, 0x52, 0x64, 0xC5, 0xA6, 0x67, 0xF0, + 0x75, 0x07, 0x06, 0x94, 0x14, 0x81, 0x55, 0xC6, 0x27, 0xE4, 0x01, 0x8F, + 0x17, 0xC1, 0x6A, 0x71, 0xD7, 0xBE, 0x4B, 0xFB, 0x94, 0x58, 0x7D, 0x7E, + 0x11, 0x33, 0xB1, 0x42, 0xF7, 0x62, 0x6C, 0x18, 0xD6, 0xCF, 0x09, 0x68, + 0x3E, 0x7F, 0x6C, 0xF6, 0x1E, 0x8F, 0x62, 0xAD, 0xA5, 0x63, 0xDB, 0x09, + 0xA7, 0x1F, 0x22, 0x42, 0x41, 0x1E, 0x6F, 0x99, 0x8A, 0x3E, 0xD7, 0xF9, + 0x3F, 0x40, 0x7A, 0x79, 0xB0, 0xA5, 0x01, 0x92, 0xD2, 0x9D, 0x3D, 0x08, + 0x15, 0xA5, 0x10, 0x01, 0x2D, 0xB3, 0x32, 0x76, 0xA8, 0x95, 0x0D, 0xB3, + 0x7A, 0x9A, 0xFB, 0x07, 0x10, 0x78, 0x11, 0x6F, 0xE1, 0x8F, 0xC7, 0xBA, + 0x0F, 0x25, 0x1A, 0x74, 0x2A, 0xE5, 0x1C, 0x98, 0x41, 0x99, 0xDF, 0x21, + 0x87, 0xE8, 0x95, 0x06, 0x6A, 0x0A, 0xB3, 0x6A, 0x47, 0x76, 0x65, 0xF6, + 0x3A, 0xCF, 0x8F, 0x62, 0x17, 0x19, 0x7B, 0x0A, 0x28, 0xCD, 0x1A, 0xD2, + 0x83, 0x1E, 0x21, 0xC7, 0x2C, 0xBF, 0xBE, 0xFF, 0x61, 0x68, 0xB7, 0x67, + 0x1B, 0xBB, 0x78, 0x4D, 0x8D, 0xCE, 0x67, 0xE5, 0xE4, 0xC1, 0x8E, 0xB7, + 0x23, 0x66, 0xE2, 0x9D, 0x90, 0x75, 0x34, 0x98, 0xA9, 0x36, 0x2B, 0x8A, + 0x9A, 0x94, 0xB9, 0x9D, 0xEC, 0xCC, 0x8A, 0xB1, 0xF8, 0x25, 0x89, 0x5C, + 0x5A, 0xB6, 0x2F, 0x8C, 0x1F, 0x6D, 0x79, 0x24, 0xA7, 0x52, 0x68, 0xC3, + 0x84, 0x35, 0xE2, 0x66, 0x8D, 0x63, 0x0E, 0x25, 0x4D, 0xD5, 0x19, 0xB2, + 0xE6, 0x79, 0x37, 0xA7, 0x22, 0x9D, 0x54, 0x31 +}; + +static const unsigned char TA177_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA178_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA178_EC_Q[] = { + 0x04, 0xC6, 0xCB, 0xC7, 0x28, 0xD1, 0xFB, 0x84, 0xF5, 0x9A, 0xEF, 0x42, + 0x14, 0x20, 0xE1, 0x43, 0x6B, 0x6E, 0x75, 0xAD, 0xFC, 0x2B, 0x03, 0x84, + 0xD4, 0x76, 0x93, 0x25, 0xD7, 0x59, 0x3B, 0x41, 0x65, 0x6B, 0x1E, 0xE6, + 0x34, 0x2A, 0xBB, 0x74, 0xF6, 0x12, 0xCE, 0xE8, 0x6D, 0xE7, 0xAB, 0xE4, + 0x3C, 0x4E, 0x3F, 0x44, 0x08, 0x8B, 0xCD, 0x16, 0x71, 0xCB, 0xBF, 0x92, + 0x99, 0xF4, 0xA4, 0xD7, 0x3C, 0x50, 0x54, 0x52, 0x90, 0x85, 0x83, 0x78, + 0x94, 0x67, 0x67, 0xA3, 0x1C, 0x09, 0x19, 0x3D, 0x75, 0x34, 0x85, 0xDE, + 0xED, 0x60, 0x7D, 0xC7, 0x0C, 0xB4, 0x41, 0x52, 0xB9, 0x6E, 0xE5, 0xEE, + 0x42 +}; + +static const unsigned char TA179_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, + 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA179_RSA_N[] = { + 0x8B, 0xC2, 0xE7, 0xAF, 0x65, 0x9B, 0x05, 0x67, 0x96, 0xC9, 0x0D, 0x24, + 0xB9, 0xD0, 0x0E, 0x64, 0xFC, 0xCE, 0xE2, 0x24, 0x18, 0x2C, 0x84, 0x7F, + 0x77, 0x51, 0xCB, 0x04, 0x11, 0x36, 0xB8, 0x5E, 0xED, 0x69, 0x71, 0xA7, + 0x9E, 0xE4, 0x25, 0x09, 0x97, 0x67, 0xC1, 0x47, 0xC2, 0xCF, 0x91, 0x16, + 0x36, 0x62, 0x3D, 0x38, 0x04, 0xE1, 0x51, 0x82, 0xFF, 0xAC, 0xD2, 0xB4, + 0x69, 0xDD, 0x2E, 0xEC, 0x11, 0xA3, 0x45, 0xEE, 0x6B, 0x6B, 0x3B, 0x4C, + 0xBF, 0x8C, 0x8D, 0xA4, 0x1E, 0x9D, 0x11, 0xB9, 0xE9, 0x38, 0xF9, 0x7A, + 0x0E, 0x0C, 0x98, 0xE2, 0x23, 0x1D, 0xD1, 0x4E, 0x63, 0xD4, 0xE7, 0xB8, + 0x41, 0x44, 0xFB, 0x6B, 0xAF, 0x6B, 0xDA, 0x1F, 0xD3, 0xC5, 0x91, 0x88, + 0x5B, 0xA4, 0x89, 0x92, 0xD1, 0x81, 0xE6, 0x8C, 0x39, 0x58, 0xA0, 0xD6, + 0x69, 0x43, 0xA9, 0xAD, 0x98, 0x52, 0x58, 0x6E, 0xDB, 0x0A, 0xFB, 0x6B, + 0xCF, 0x68, 0xFA, 0xE3, 0xA4, 0x5E, 0x3A, 0x45, 0x73, 0x98, 0x07, 0xEA, + 0x5F, 0x02, 0x72, 0xDE, 0x0C, 0xA5, 0xB3, 0x9F, 0xAE, 0xA9, 0x1D, 0xB7, + 0x1D, 0xB3, 0xFC, 0x8A, 0x59, 0xE7, 0x6E, 0x72, 0x65, 0xAD, 0xF5, 0x30, + 0x94, 0x23, 0x07, 0xF3, 0x82, 0x16, 0x4B, 0x35, 0x98, 0x9C, 0x53, 0xBB, + 0x2F, 0xCA, 0xE4, 0x5A, 0xD9, 0xC7, 0x8D, 0x1D, 0xFC, 0x98, 0x99, 0xFB, + 0x2C, 0xA4, 0x82, 0x6B, 0xF0, 0x2A, 0x1F, 0x8E, 0x0B, 0x5F, 0x71, 0x5C, + 0x5C, 0xAE, 0x42, 0x7B, 0x29, 0x89, 0x81, 0xCB, 0x03, 0xA3, 0x99, 0xCA, + 0x88, 0x9E, 0x0B, 0x40, 0x09, 0x41, 0x33, 0xDB, 0xE6, 0x58, 0x7A, 0xFD, + 0xAE, 0x99, 0x70, 0xC0, 0x5A, 0x0F, 0xD6, 0x13, 0x86, 0x71, 0x2F, 0x76, + 0x69, 0xFC, 0x90, 0xDD, 0xDB, 0x2D, 0x6E, 0xD1, 0xF2, 0x9B, 0xF5, 0x1A, + 0x6B, 0x9E, 0x6F, 0x15, 0x8C, 0x7A, 0xF0, 0x4B, 0x28, 0xA0, 0x22, 0x38, + 0x80, 0x24, 0x6C, 0x36, 0xA4, 0x3B, 0xF2, 0x30, 0x91, 0xF3, 0x78, 0x13, + 0xCF, 0xC1, 0x3F, 0x35, 0xAB, 0xF1, 0x1D, 0x11, 0x23, 0xB5, 0x43, 0x22, + 0x9E, 0x01, 0x92, 0xB7, 0x18, 0x02, 0xE5, 0x11, 0xD1, 0x82, 0xDB, 0x15, + 0x00, 0xCC, 0x61, 0x37, 0xC1, 0x2A, 0x7C, 0x9A, 0xE1, 0xD0, 0xBA, 0xB3, + 0x50, 0x46, 0xEE, 0x82, 0xAC, 0x9D, 0x31, 0xF8, 0xFB, 0x23, 0xE2, 0x03, + 0x00, 0x48, 0x70, 0xA3, 0x09, 0x26, 0x79, 0x15, 0x53, 0x60, 0xF3, 0x38, + 0x5C, 0xAD, 0x38, 0xEA, 0x81, 0x00, 0x63, 0x14, 0xB9, 0x33, 0x5E, 0xDD, + 0x0B, 0xDB, 0xA0, 0x45, 0x07, 0x1A, 0x33, 0x09, 0xF8, 0x4D, 0xB4, 0xA7, + 0x02, 0xA6, 0x69, 0xF4, 0xC2, 0x59, 0x05, 0x88, 0x65, 0x85, 0x56, 0xAE, + 0x4B, 0xCB, 0xE0, 0xDE, 0x3C, 0x7D, 0x2D, 0x1A, 0xC8, 0xE9, 0xFB, 0x1F, + 0xA3, 0x61, 0x4A, 0xD6, 0x2A, 0x13, 0xAD, 0x77, 0x4C, 0x1A, 0x18, 0x9B, + 0x91, 0x0F, 0x58, 0xD8, 0x06, 0x54, 0xC5, 0x97, 0xF8, 0xAA, 0x3F, 0x20, + 0x8A, 0xA6, 0x85, 0xA6, 0x77, 0xF6, 0xA6, 0xFC, 0x1C, 0xE2, 0xEE, 0x6E, + 0x94, 0x33, 0x2A, 0x83, 0x50, 0x84, 0x0A, 0xE5, 0x4F, 0x86, 0xF8, 0x50, + 0x45, 0x78, 0x00, 0x81, 0xEB, 0x5B, 0x68, 0xE3, 0x26, 0x8D, 0xCC, 0x7B, + 0x5C, 0x51, 0xF4, 0x14, 0x2C, 0x40, 0xBE, 0x1A, 0x60, 0x1D, 0x7A, 0x72, + 0x61, 0x1D, 0x1F, 0x63, 0x2D, 0x88, 0xAA, 0xCE, 0xA2, 0x45, 0x90, 0x08, + 0xFC, 0x6B, 0xBE, 0xB3, 0x50, 0x2A, 0x5A, 0xFD, 0xA8, 0x48, 0x18, 0x46, + 0xD6, 0x90, 0x40, 0x92, 0x90, 0x0A, 0x84, 0x5E, 0x68, 0x31, 0xF8, 0xEB, + 0xED, 0x0D, 0xD3, 0x1D, 0xC6, 0x7D, 0x99, 0x18, 0x55, 0x56, 0x27, 0x65, + 0x2E, 0x8D, 0x45, 0xC5, 0x24, 0xEC, 0xCE, 0xE3 +}; + +static const unsigned char TA179_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA180_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA180_RSA_N[] = { + 0xD8, 0x8E, 0xA3, 0x89, 0x80, 0x0B, 0xB2, 0x57, 0x52, 0xDC, 0xA9, 0x53, + 0x4C, 0x37, 0xB9, 0x7F, 0x63, 0x17, 0x13, 0xEF, 0xA7, 0x5B, 0x23, 0x5B, + 0x69, 0x75, 0xB0, 0x99, 0x0A, 0x17, 0xC1, 0x8B, 0xC4, 0xDB, 0xA8, 0xE0, + 0xCC, 0x31, 0xBA, 0xC2, 0xF2, 0xCD, 0x5D, 0xE9, 0xB7, 0xF8, 0x1D, 0xAF, + 0x6A, 0xC4, 0x95, 0x87, 0xD7, 0x47, 0xC9, 0x95, 0xD8, 0x82, 0x04, 0x50, + 0x3D, 0x81, 0x08, 0xFF, 0xE4, 0x3D, 0xB3, 0xB1, 0xD6, 0xC5, 0xB2, 0xFD, + 0x88, 0x09, 0xDB, 0x9C, 0x84, 0xEC, 0x25, 0x17, 0x14, 0x87, 0x7F, 0x30, + 0x78, 0x9B, 0x6A, 0x58, 0xC9, 0xB6, 0x73, 0x28, 0x3C, 0x34, 0xF7, 0x99, + 0xF7, 0x7F, 0xD3, 0xA6, 0xF8, 0x1C, 0x45, 0x7C, 0xAD, 0x2C, 0x8C, 0x94, + 0x3F, 0xD8, 0x67, 0x10, 0x53, 0x7E, 0x22, 0xCD, 0x4E, 0x25, 0x51, 0xF0, + 0x25, 0x24, 0x35, 0x11, 0x5E, 0x10, 0xC6, 0xEC, 0x87, 0x66, 0x89, 0x81, + 0x68, 0xBA, 0xCC, 0x2B, 0x9D, 0x47, 0x73, 0x1F, 0xBD, 0xCD, 0x91, 0xA4, + 0x72, 0x6A, 0x9C, 0xA2, 0x1B, 0x18, 0xA0, 0x6F, 0xEC, 0x50, 0xF4, 0x7D, + 0x40, 0xC2, 0xA8, 0x30, 0xCF, 0xBD, 0x73, 0xC8, 0x13, 0x2B, 0x10, 0x13, + 0x1E, 0x8B, 0x9A, 0xA8, 0x3A, 0x94, 0x73, 0xD3, 0x18, 0x69, 0x0A, 0x4A, + 0xFF, 0xC1, 0x01, 0x03, 0xFF, 0x79, 0x7F, 0xB5, 0x48, 0x7F, 0x7B, 0xEE, + 0xE8, 0x29, 0x6F, 0x36, 0x4C, 0x95, 0x61, 0x86, 0xD8, 0xF9, 0xA2, 0x73, + 0x8A, 0xEE, 0xAE, 0x2F, 0x96, 0xEE, 0x68, 0xCD, 0x3D, 0x4D, 0x28, 0x42, + 0xF9, 0x45, 0x2B, 0x32, 0x1B, 0x46, 0x55, 0x16, 0x6A, 0xA6, 0x4B, 0x29, + 0xF9, 0xBB, 0x95, 0x56, 0xBF, 0x46, 0x1D, 0xEC, 0x1D, 0x93, 0x1D, 0xC0, + 0x65, 0xB2, 0x1F, 0xA1, 0x43, 0xAE, 0x56, 0x9E, 0xA0, 0xB1, 0x8F, 0x6B, + 0x12, 0xB7, 0x60, 0x6D, 0x78, 0x0B, 0xCA, 0x8A, 0x5C, 0xED, 0x1E, 0x96, + 0x0E, 0x83, 0xA6, 0x48, 0x95, 0x8D, 0x3B, 0xA3, 0x21, 0xC4, 0xAE, 0x58, + 0xC6, 0x00, 0xB2, 0x84, 0xB4, 0x23, 0xA4, 0x96, 0x86, 0x35, 0xB8, 0xD8, + 0x9E, 0xD8, 0xAC, 0x34, 0x49, 0x98, 0x63, 0x95, 0xC5, 0xCB, 0x6D, 0x48, + 0x47, 0xE2, 0xF2, 0x2E, 0x18, 0x1E, 0xD0, 0x31, 0xAB, 0xDD, 0x74, 0xEC, + 0xF9, 0xDC, 0x8C, 0xB8, 0x1C, 0x8E, 0x68, 0x23, 0xBA, 0xD0, 0xF3, 0x50, + 0xDC, 0xCF, 0x65, 0x8F, 0x73, 0x3A, 0x32, 0xC7, 0x7C, 0xFE, 0xCA, 0x82, + 0x22, 0x4F, 0xBE, 0x8E, 0x62, 0x47, 0x66, 0xE5, 0xCD, 0x87, 0xE2, 0xE8, + 0xD5, 0x0F, 0x18, 0x9F, 0xE5, 0x04, 0x72, 0x4B, 0x46, 0x3C, 0x10, 0xF2, + 0x44, 0xC2, 0x64, 0x56, 0x71, 0x4E, 0x75, 0xE8, 0x9C, 0xC9, 0x26, 0x74, + 0xC5, 0x7D, 0x59, 0xD1, 0x0A, 0x5B, 0x0F, 0x6D, 0xFE, 0x9E, 0x75, 0x1C, + 0x18, 0xC6, 0x1A, 0x3A, 0x7C, 0xD8, 0x0D, 0x04, 0xCC, 0xCD, 0xB7, 0x45, + 0x65, 0x7A, 0xB1, 0x8F, 0xB8, 0xAE, 0x84, 0x48, 0x3E, 0xB3, 0x7A, 0x4D, + 0xA8, 0x03, 0xE2, 0xE2, 0x7E, 0x01, 0x16, 0x59, 0x68, 0x18, 0x43, 0x33, + 0xB0, 0xD2, 0xDC, 0xB0, 0x1A, 0x43, 0x35, 0xEE, 0xA5, 0xDA, 0xA9, 0x46, + 0x5C, 0xAE, 0x86, 0x81, 0x41, 0x01, 0x4A, 0x74, 0x26, 0xEC, 0x9F, 0x06, + 0xBF, 0xC2, 0x05, 0x37, 0x64, 0x75, 0x78, 0x29, 0x68, 0xFD, 0xC5, 0xF5, + 0xEB, 0xFE, 0x47, 0xF9, 0xE4, 0x85, 0xB0, 0xE1, 0x7B, 0x31, 0x9D, 0xA6, + 0x7F, 0x72, 0xA3, 0xB9, 0xC4, 0x2C, 0x2E, 0xCC, 0x99, 0x57, 0x0E, 0x21, + 0x0C, 0x45, 0x01, 0x94, 0x65, 0xEB, 0x65, 0x09, 0xC6, 0x63, 0x22, 0x0B, + 0x33, 0x49, 0x92, 0x48, 0x3C, 0xFC, 0xCD, 0xCE, 0xB0, 0x3E, 0x8E, 0x9E, + 0x8B, 0xF8, 0xFE, 0x49, 0xC5, 0x35, 0x72, 0x47 +}; + +static const unsigned char TA180_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA181_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x18, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA181_RSA_N[] = { + 0xBF, 0xE6, 0x90, 0x73, 0x68, 0xDE, 0xBB, 0xE4, 0x5D, 0x4A, 0x3C, 0x30, + 0x22, 0x30, 0x69, 0x33, 0xEC, 0xC2, 0xA7, 0x25, 0x2E, 0xC9, 0x21, 0x3D, + 0xF2, 0x8A, 0xD8, 0x59, 0xC2, 0xE1, 0x29, 0xA7, 0x3D, 0x58, 0xAB, 0x76, + 0x9A, 0xCD, 0xAE, 0x7B, 0x1B, 0x84, 0x0D, 0xC4, 0x30, 0x1F, 0xF3, 0x1B, + 0xA4, 0x38, 0x16, 0xEB, 0x56, 0xC6, 0x97, 0x6D, 0x1D, 0xAB, 0xB2, 0x79, + 0xF2, 0xCA, 0x11, 0xD2, 0xE4, 0x5F, 0xD6, 0x05, 0x3C, 0x52, 0x0F, 0x52, + 0x1F, 0xC6, 0x9E, 0x15, 0xA5, 0x7E, 0xBE, 0x9F, 0xA9, 0x57, 0x16, 0x59, + 0x55, 0x72, 0xAF, 0x68, 0x93, 0x70, 0xC2, 0xB2, 0xBA, 0x75, 0x99, 0x6A, + 0x73, 0x32, 0x94, 0xD1, 0x10, 0x44, 0x10, 0x2E, 0xDF, 0x82, 0xF3, 0x07, + 0x84, 0xE6, 0x74, 0x3B, 0x6D, 0x71, 0xE2, 0x2D, 0x0C, 0x1B, 0xEE, 0x20, + 0xD5, 0xC9, 0x20, 0x1D, 0x63, 0x29, 0x2D, 0xCE, 0xEC, 0x5E, 0x4E, 0xC8, + 0x93, 0xF8, 0x21, 0x61, 0x9B, 0x34, 0xEB, 0x05, 0xC6, 0x5E, 0xEC, 0x5B, + 0x1A, 0xBC, 0xEB, 0xC9, 0xCF, 0xCD, 0xAC, 0x34, 0x40, 0x5F, 0xB1, 0x7A, + 0x66, 0xEE, 0x77, 0xC8, 0x48, 0xA8, 0x66, 0x57, 0x57, 0x9F, 0x54, 0x58, + 0x8E, 0x0C, 0x2B, 0xB7, 0x4F, 0xA7, 0x30, 0xD9, 0x56, 0xEE, 0xCA, 0x7B, + 0x5D, 0xE3, 0xAD, 0xC9, 0x4F, 0x5E, 0xE5, 0x35, 0xE7, 0x31, 0xCB, 0xDA, + 0x93, 0x5E, 0xDC, 0x8E, 0x8F, 0x80, 0xDA, 0xB6, 0x91, 0x98, 0x40, 0x90, + 0x79, 0xC3, 0x78, 0xC7, 0xB6, 0xB1, 0xC4, 0xB5, 0x6A, 0x18, 0x38, 0x03, + 0x10, 0x8D, 0xD8, 0xD4, 0x37, 0xA4, 0x2E, 0x05, 0x7D, 0x88, 0xF5, 0x82, + 0x3E, 0x10, 0x91, 0x70, 0xAB, 0x55, 0x82, 0x41, 0x32, 0xD7, 0xDB, 0x04, + 0x73, 0x2A, 0x6E, 0x91, 0x01, 0x7C, 0x21, 0x4C, 0xD4, 0xBC, 0xAE, 0x1B, + 0x03, 0x75, 0x5D, 0x78, 0x66, 0xD9, 0x3A, 0x31, 0x44, 0x9A, 0x33, 0x40, + 0xBF, 0x08, 0xD7, 0x5A, 0x49, 0xA4, 0xC2, 0xE6, 0xA9, 0xA0, 0x67, 0xDD, + 0xA4, 0x27, 0xBC, 0xA1, 0x4F, 0x39, 0xB5, 0x11, 0x58, 0x17, 0xF7, 0x24, + 0x5C, 0x46, 0x8F, 0x64, 0xF7, 0xC1, 0x69, 0x88, 0x76, 0x98, 0x76, 0x3D, + 0x59, 0x5D, 0x42, 0x76, 0x87, 0x89, 0x97, 0x69, 0x7A, 0x48, 0xF0, 0xE0, + 0xA2, 0x12, 0x1B, 0x66, 0x9A, 0x74, 0xCA, 0xDE, 0x4B, 0x1E, 0xE7, 0x0E, + 0x63, 0xAE, 0xE6, 0xD4, 0xEF, 0x92, 0x92, 0x3A, 0x9E, 0x3D, 0xDC, 0x00, + 0xE4, 0x45, 0x25, 0x89, 0xB6, 0x9A, 0x44, 0x19, 0x2B, 0x7E, 0xC0, 0x94, + 0xB4, 0xD2, 0x61, 0x6D, 0xEB, 0x33, 0xD9, 0xC5, 0xDF, 0x4B, 0x04, 0x00, + 0xCC, 0x7D, 0x1C, 0x95, 0xC3, 0x8F, 0xF7, 0x21, 0xB2, 0xB2, 0x11, 0xB7, + 0xBB, 0x7F, 0xF2, 0xD5, 0x8C, 0x70, 0x2C, 0x41, 0x60, 0xAA, 0xB1, 0x63, + 0x18, 0x44, 0x95, 0x1A, 0x76, 0x62, 0x7E, 0xF6, 0x80, 0xB0, 0xFB, 0xE8, + 0x64, 0xA6, 0x33, 0xD1, 0x89, 0x07, 0xE1, 0xBD, 0xB7, 0xE6, 0x43, 0xA4, + 0x18, 0xB8, 0xA6, 0x77, 0x01, 0xE1, 0x0F, 0x94, 0x0C, 0x21, 0x1D, 0xB2, + 0x54, 0x29, 0x25, 0x89, 0x6C, 0xE5, 0x0E, 0x52, 0x51, 0x47, 0x74, 0xBE, + 0x26, 0xAC, 0xB6, 0x41, 0x75, 0xDE, 0x7A, 0xAC, 0x5F, 0x8D, 0x3F, 0xC9, + 0xBC, 0xD3, 0x41, 0x11, 0x12, 0x5B, 0xE5, 0x10, 0x50, 0xEB, 0x31, 0xC5, + 0xCA, 0x72, 0x16, 0x22, 0x09, 0xDF, 0x7C, 0x4C, 0x75, 0x3F, 0x63, 0xEC, + 0x21, 0x5F, 0xC4, 0x20, 0x51, 0x6B, 0x6F, 0xB1, 0xAB, 0x86, 0x8B, 0x4F, + 0xC2, 0xD6, 0x45, 0x5F, 0x9D, 0x20, 0xFC, 0xA1, 0x1E, 0xC5, 0xC0, 0x8F, + 0xA2, 0xB1, 0x7E, 0x0A, 0x26, 0x99, 0xF5, 0xE4, 0x69, 0x2F, 0x98, 0x1D, + 0x2D, 0xF5, 0xD9, 0xA9, 0xB2, 0x1D, 0xE5, 0x1B +}; + +static const unsigned char TA181_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA182_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x34 +}; + +static const unsigned char TA182_EC_Q[] = { + 0x04, 0xF3, 0x74, 0x73, 0xA7, 0x68, 0x8B, 0x60, 0xAE, 0x43, 0xB8, 0x35, + 0xC5, 0x81, 0x30, 0x7B, 0x4B, 0x49, 0x9D, 0xFB, 0xC1, 0x61, 0xCE, 0xE6, + 0xDE, 0x46, 0xBD, 0x6B, 0xD5, 0x61, 0x18, 0x35, 0xAE, 0x40, 0xDD, 0x73, + 0xF7, 0x89, 0x91, 0x30, 0x5A, 0xEB, 0x3C, 0xEE, 0x85, 0x7C, 0xA2, 0x40, + 0x76, 0x3B, 0xA9, 0xC6, 0xB8, 0x47, 0xD8, 0x2A, 0xE7, 0x92, 0x91, 0x6A, + 0x73, 0xE9, 0xB1, 0x72, 0x39, 0x9F, 0x29, 0x9F, 0xA2, 0x98, 0xD3, 0x5F, + 0x5E, 0x58, 0x86, 0x65, 0x0F, 0xA1, 0x84, 0x65, 0x06, 0xD1, 0xDC, 0x8B, + 0xC9, 0xC7, 0x73, 0xC8, 0x8C, 0x6A, 0x2F, 0xE5, 0xC4, 0xAB, 0xD1, 0x1D, + 0x8A +}; + +static const unsigned char TA183_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA183_EC_Q[] = { + 0x04, 0xF1, 0x0B, 0xDD, 0x86, 0x43, 0x20, 0x19, 0xDF, 0x97, 0x85, 0xE8, + 0x22, 0x4A, 0x9B, 0xCF, 0x9D, 0x98, 0xBF, 0xB4, 0x05, 0x26, 0xC9, 0xCB, + 0xE3, 0xA6, 0xD2, 0x8F, 0xC5, 0x9E, 0x78, 0x7B, 0x31, 0x89, 0xA9, 0x89, + 0xAD, 0x27, 0x3C, 0x65, 0x10, 0x82, 0xFC, 0xDF, 0xC3, 0x9D, 0x4E, 0xF0, + 0x33, 0x23, 0xC4, 0xD2, 0x32, 0xF5, 0x1C, 0xB0, 0xDF, 0x33, 0x17, 0x5D, + 0xC5, 0xF0, 0xB1, 0x8A, 0xF9, 0xEF, 0xB9, 0xB7, 0x14, 0xCA, 0x29, 0x4A, + 0xC2, 0x0F, 0xA9, 0x7F, 0x75, 0x65, 0x49, 0x2A, 0x30, 0x67, 0xF4, 0x64, + 0xF7, 0xD6, 0x1A, 0x77, 0xDA, 0xC3, 0xC2, 0x97, 0x61, 0x42, 0x7B, 0x49, + 0xAD +}; + +static const unsigned char TA184_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1F, 0x4B, 0x72, 0x61, 0x6A, 0x6F, 0x77, 0x61, 0x20, 0x49, 0x7A, + 0x62, 0x61, 0x20, 0x52, 0x6F, 0x7A, 0x6C, 0x69, 0x63, 0x7A, 0x65, 0x6E, + 0x69, 0x6F, 0x77, 0x61, 0x20, 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x53, 0x5A, 0x41, 0x46, + 0x49, 0x52, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA184_RSA_N[] = { + 0xB7, 0xBC, 0x3E, 0x50, 0xA8, 0x4B, 0xCD, 0x40, 0xB5, 0xCE, 0x61, 0xE7, + 0x96, 0xCA, 0xB4, 0xA1, 0xDA, 0x0C, 0x22, 0xB0, 0xFA, 0xB5, 0x7B, 0x76, + 0x00, 0x77, 0x8C, 0x0B, 0xCF, 0x7D, 0xA8, 0x86, 0xCC, 0x26, 0x51, 0xE4, + 0x20, 0x3D, 0x85, 0x0C, 0xD6, 0x58, 0xE3, 0xE7, 0xF4, 0x2A, 0x18, 0x9D, + 0xDA, 0xD1, 0xAE, 0x26, 0xEE, 0xEB, 0x53, 0xDC, 0xF4, 0x90, 0xD6, 0x13, + 0x4A, 0x0C, 0x90, 0x3C, 0xC3, 0xF4, 0xDA, 0xD2, 0x8E, 0x0D, 0x92, 0x3A, + 0xDC, 0xB1, 0xB1, 0xFF, 0x38, 0xDE, 0xC3, 0xBA, 0x2D, 0x5F, 0x80, 0xB9, + 0x02, 0xBD, 0x4A, 0x9D, 0x1B, 0x0F, 0xB4, 0xC3, 0xC2, 0xC1, 0x67, 0x03, + 0xDD, 0xDC, 0x1B, 0x9C, 0x3D, 0xB3, 0xB0, 0xDE, 0x00, 0x1E, 0xA8, 0x34, + 0x47, 0xBB, 0x9A, 0xEB, 0xFE, 0x0B, 0x14, 0xBD, 0x36, 0x84, 0xDA, 0x0D, + 0x20, 0xBF, 0xFA, 0x5B, 0xCB, 0xA9, 0x16, 0x20, 0xAD, 0x39, 0x60, 0xEE, + 0x2F, 0x75, 0xB6, 0xE7, 0x97, 0x9C, 0xF9, 0x3E, 0xFD, 0x7E, 0x4D, 0x6F, + 0x4D, 0x2F, 0xEF, 0x88, 0x0D, 0x6A, 0xFA, 0xDD, 0xF1, 0x3D, 0x6E, 0x20, + 0xA5, 0xA0, 0x12, 0xB4, 0x4D, 0x70, 0xB9, 0xCE, 0xD7, 0x72, 0x3B, 0x89, + 0x93, 0xA7, 0x80, 0x84, 0x1C, 0x27, 0x49, 0x72, 0x49, 0xB5, 0xFF, 0x3B, + 0x95, 0x9E, 0xC1, 0xCC, 0xC8, 0x01, 0xEC, 0xE8, 0x0E, 0x8A, 0x0A, 0x96, + 0xE7, 0xB3, 0xA6, 0x87, 0xE5, 0xD6, 0xF9, 0x05, 0x2B, 0x0D, 0x97, 0x40, + 0x70, 0x3C, 0xBA, 0xAC, 0x75, 0x5A, 0x9C, 0xD5, 0x4D, 0x9D, 0x02, 0x0A, + 0xD2, 0x4B, 0x9B, 0x66, 0x4B, 0x46, 0x07, 0x17, 0x65, 0xAD, 0x9F, 0x6C, + 0x88, 0x00, 0xDC, 0x22, 0x89, 0xE0, 0xE1, 0x64, 0xD4, 0x67, 0xBC, 0x31, + 0x79, 0x61, 0x3C, 0xBB, 0xCA, 0x41, 0xCD, 0x5C, 0x6A, 0x00, 0xC8, 0x3C, + 0x38, 0x8E, 0x58, 0xAF +}; + +static const unsigned char TA184_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA185_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA185_RSA_N[] = { + 0xD0, 0xA4, 0x09, 0x72, 0x4F, 0x40, 0x88, 0x12, 0x61, 0x3E, 0x35, 0x23, + 0x9E, 0xEE, 0xF6, 0x74, 0xCF, 0x2F, 0x7B, 0x58, 0x3D, 0xCE, 0x3C, 0x0D, + 0x10, 0x28, 0x90, 0x2F, 0x97, 0xF7, 0x8C, 0x48, 0xD8, 0xA0, 0xD8, 0x25, + 0xB1, 0x4C, 0xB0, 0x11, 0x4C, 0x17, 0x73, 0x50, 0xD0, 0x22, 0x4A, 0x63, + 0xBB, 0x81, 0xD3, 0x29, 0x6E, 0xD5, 0xB5, 0x09, 0x3E, 0x26, 0x18, 0x7F, + 0xB2, 0x12, 0x7F, 0x93, 0x98, 0xB7, 0xAF, 0xF0, 0x36, 0xBF, 0xF2, 0xEE, + 0x18, 0x9E, 0x9C, 0x3B, 0x52, 0xC5, 0x47, 0x19, 0x5D, 0x74, 0xF3, 0x64, + 0x66, 0xD5, 0x5D, 0xC7, 0x68, 0xB4, 0xBF, 0x1B, 0x1C, 0x06, 0xA3, 0xBC, + 0x8F, 0x40, 0x23, 0xB6, 0x1E, 0xC6, 0x84, 0xBD, 0x51, 0xC4, 0x1B, 0x39, + 0xC1, 0x95, 0xD2, 0x29, 0xEC, 0x4B, 0xAE, 0x7B, 0x2D, 0xBF, 0x39, 0xFD, + 0xB4, 0x62, 0xDE, 0x96, 0x7B, 0x41, 0xC6, 0x9C, 0xA0, 0xE0, 0x06, 0x72, + 0xFB, 0xF0, 0x07, 0x97, 0x09, 0x39, 0x81, 0x74, 0xAF, 0xF7, 0x34, 0x59, + 0x11, 0x57, 0x0A, 0xC2, 0x5B, 0xC1, 0x24, 0xF4, 0x31, 0x73, 0x30, 0x82, + 0xC6, 0x9D, 0xBA, 0x02, 0xF7, 0x3E, 0x7C, 0x44, 0x5F, 0x83, 0x0D, 0xF3, + 0xF1, 0xDD, 0x20, 0x69, 0x16, 0x09, 0x50, 0xE2, 0xD4, 0x55, 0xB6, 0xE0, + 0x80, 0x72, 0x76, 0x6E, 0x4C, 0x47, 0xB7, 0x75, 0x55, 0x59, 0xB4, 0x53, + 0x74, 0xD9, 0x94, 0xC6, 0x41, 0xAD, 0x58, 0x8A, 0x31, 0x66, 0x0F, 0x1E, + 0xA2, 0x1B, 0x29, 0x40, 0x4E, 0x2F, 0xDF, 0x7B, 0xE6, 0x16, 0x2C, 0x2D, + 0xFC, 0xBF, 0xEC, 0xF3, 0xB4, 0xFA, 0xBE, 0x18, 0xF6, 0x9B, 0x49, 0xD4, + 0xEE, 0x05, 0x6E, 0xD9, 0x34, 0xF3, 0x9C, 0xF1, 0xEC, 0x01, 0x8B, 0xD1, + 0x20, 0xC6, 0x0F, 0xA0, 0xB5, 0xBC, 0x17, 0x4E, 0x48, 0x7B, 0x51, 0xC2, + 0xFC, 0xE9, 0x5C, 0x69, 0x37, 0x47, 0x66, 0xB3, 0x68, 0xF8, 0x15, 0x28, + 0xF0, 0xB9, 0xD3, 0xA4, 0x15, 0xCC, 0x5A, 0x4F, 0xBA, 0x52, 0x70, 0xA3, + 0x12, 0x45, 0xDD, 0xC6, 0xBA, 0x4E, 0xFB, 0xC2, 0xD0, 0xF7, 0xA8, 0x52, + 0x27, 0x6D, 0x6E, 0x79, 0xB5, 0x8C, 0xFC, 0x7B, 0x8C, 0xC1, 0x16, 0x4C, + 0xEE, 0x80, 0x7F, 0xBE, 0xF0, 0x76, 0xBE, 0x41, 0x53, 0x12, 0x33, 0xAE, + 0x5A, 0x38, 0x42, 0xAB, 0xD7, 0x0F, 0x3E, 0x41, 0x8D, 0x76, 0x07, 0x32, + 0xD5, 0xAB, 0x89, 0xF6, 0x4E, 0x67, 0xD9, 0xB1, 0x42, 0x75, 0x23, 0x6E, + 0xF3, 0xCD, 0x42, 0xB2, 0xFC, 0x55, 0xF5, 0x53, 0x87, 0x17, 0x3B, 0xC0, + 0x33, 0x58, 0xF1, 0x52, 0xD2, 0xF9, 0x80, 0xA4, 0xF0, 0xE8, 0xF0, 0x3B, + 0x8B, 0x38, 0xCC, 0xA4, 0xC6, 0x90, 0x7F, 0x0F, 0x9C, 0xFD, 0x8B, 0xD1, + 0xA3, 0xCF, 0xDA, 0x83, 0xA7, 0x69, 0xC9, 0x50, 0x36, 0xD5, 0x5C, 0x05, + 0xD2, 0x0A, 0x41, 0x74, 0xDB, 0x63, 0x11, 0x37, 0xC1, 0xA5, 0xA0, 0x96, + 0x4B, 0x1E, 0x8C, 0x16, 0x12, 0x77, 0xAE, 0x94, 0x34, 0x7B, 0x1E, 0x7F, + 0xC2, 0x66, 0x00, 0xE4, 0xAA, 0x83, 0xEA, 0x8A, 0x90, 0xAD, 0xCE, 0x36, + 0x44, 0x4D, 0xD1, 0x51, 0xE9, 0xBC, 0x1F, 0xF3, 0x6A, 0x05, 0xFD, 0xC0, + 0x74, 0x1F, 0x25, 0x19, 0x40, 0x51, 0x6E, 0xEA, 0x82, 0x51, 0x40, 0xDF, + 0x9B, 0xB9, 0x08, 0x2A, 0x06, 0x02, 0xD5, 0x23, 0x1C, 0x13, 0xD6, 0xE9, + 0xDB, 0xDB, 0xC6, 0xB0, 0x7A, 0xCB, 0x7B, 0x27, 0x9B, 0xFB, 0xE0, 0xD5, + 0x46, 0x24, 0xED, 0x10, 0x4B, 0x63, 0x4B, 0xA5, 0x05, 0x8F, 0xBA, 0xB8, + 0x1D, 0x2B, 0xA6, 0xFA, 0x91, 0xE2, 0x92, 0x52, 0xBD, 0xEC, 0xEB, 0x67, + 0x97, 0x6D, 0x9A, 0x2D, 0x9F, 0x81, 0x32, 0x05, 0x67, 0x32, 0xFB, 0x48, + 0x08, 0x3F, 0xD9, 0x25, 0xB8, 0x04, 0x25, 0x2F +}; + +static const unsigned char TA185_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA186_DN[] = { + 0x30, 0x42, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x09, 0x41, 0x43, 0x43, 0x56, 0x52, 0x41, 0x49, 0x5A, 0x31, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x50, 0x4B, 0x49, + 0x41, 0x43, 0x43, 0x56, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x04, 0x41, 0x43, 0x43, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53 +}; + +static const unsigned char TA186_RSA_N[] = { + 0x9B, 0xA9, 0xAB, 0xBF, 0x61, 0x4A, 0x97, 0xAF, 0x2F, 0x97, 0x66, 0x9A, + 0x74, 0x5F, 0xD0, 0xD9, 0x96, 0xFD, 0xCF, 0xE2, 0xE4, 0x66, 0xEF, 0x1F, + 0x1F, 0x47, 0x33, 0xC2, 0x44, 0xA3, 0xDF, 0x9A, 0xDE, 0x1F, 0xB5, 0x54, + 0xDD, 0x15, 0x7C, 0x69, 0x35, 0x11, 0x6F, 0xBB, 0xC8, 0x0C, 0x8E, 0x6A, + 0x18, 0x1E, 0xD8, 0x8F, 0xD9, 0x16, 0xBC, 0x10, 0x48, 0x36, 0x5C, 0xF0, + 0x63, 0xB3, 0x90, 0x5A, 0x5C, 0x24, 0x37, 0xD7, 0xA3, 0xD6, 0xCB, 0x09, + 0x71, 0xB9, 0xF1, 0x01, 0x72, 0x84, 0xB0, 0x7D, 0xDB, 0x4D, 0x80, 0xCD, + 0xFC, 0xD3, 0x6F, 0xC9, 0xF8, 0xDA, 0xB6, 0x0E, 0x82, 0xD2, 0x45, 0x85, + 0xA8, 0x1B, 0x68, 0xA8, 0x3D, 0xE8, 0xF4, 0x44, 0x6C, 0xBD, 0xA1, 0xC2, + 0xCB, 0x03, 0xBE, 0x8C, 0x3E, 0x13, 0x00, 0x84, 0xDF, 0x4A, 0x48, 0xC0, + 0xE3, 0x22, 0x0A, 0xE8, 0xE9, 0x37, 0xA7, 0x18, 0x4C, 0xB1, 0x09, 0x0D, + 0x23, 0x56, 0x7F, 0x04, 0x4D, 0xD9, 0x17, 0x84, 0x18, 0xA5, 0xC8, 0xDA, + 0x40, 0x94, 0x73, 0xEB, 0xCE, 0x0E, 0x57, 0x3C, 0x03, 0x81, 0x3A, 0x9D, + 0x0A, 0xA1, 0x57, 0x43, 0x69, 0xAC, 0x57, 0x6D, 0x79, 0x90, 0x78, 0xE5, + 0xB5, 0xB4, 0x3B, 0xD8, 0xBC, 0x4C, 0x8D, 0x28, 0xA1, 0xA7, 0xA3, 0xA7, + 0xBA, 0x02, 0x4E, 0x25, 0xD1, 0x2A, 0xAE, 0xED, 0xAE, 0x03, 0x22, 0xB8, + 0x6B, 0x20, 0x0F, 0x30, 0x28, 0x54, 0x95, 0x7F, 0xE0, 0xEE, 0xCE, 0x0A, + 0x66, 0x9D, 0xD1, 0x40, 0x2D, 0x6E, 0x22, 0xAF, 0x9D, 0x1A, 0xC1, 0x05, + 0x19, 0xD2, 0x6F, 0xC0, 0xF2, 0x9F, 0xF8, 0x7B, 0xB3, 0x02, 0x42, 0xFB, + 0x50, 0xA9, 0x1D, 0x2D, 0x93, 0x0F, 0x23, 0xAB, 0xC6, 0xC1, 0x0F, 0x92, + 0xFF, 0xD0, 0xA2, 0x15, 0xF5, 0x53, 0x09, 0x71, 0x1C, 0xFF, 0x45, 0x13, + 0x84, 0xE6, 0x26, 0x5E, 0xF8, 0xE0, 0x88, 0x1C, 0x0A, 0xFC, 0x16, 0xB6, + 0xA8, 0x73, 0x06, 0xB8, 0xF0, 0x63, 0x84, 0x02, 0xA0, 0xC6, 0x5A, 0xEC, + 0xE7, 0x74, 0xDF, 0x70, 0xAE, 0xA3, 0x83, 0x25, 0xEA, 0xD6, 0xC7, 0x97, + 0x87, 0x93, 0xA7, 0xC6, 0x8A, 0x8A, 0x33, 0x97, 0x60, 0x37, 0x10, 0x3E, + 0x97, 0x3E, 0x6E, 0x29, 0x15, 0xD6, 0xA1, 0x0F, 0xD1, 0x88, 0x2C, 0x12, + 0x9F, 0x6F, 0xAA, 0xA4, 0xC6, 0x42, 0xEB, 0x41, 0xA2, 0xE3, 0x95, 0x43, + 0xD3, 0x01, 0x85, 0x6D, 0x8E, 0xBB, 0x3B, 0xF3, 0x23, 0x36, 0xC7, 0xFE, + 0x3B, 0xE0, 0xA1, 0x25, 0x07, 0x48, 0xAB, 0xC9, 0x89, 0x74, 0xFF, 0x08, + 0x8F, 0x80, 0xBF, 0xC0, 0x96, 0x65, 0xF3, 0xEE, 0xEC, 0x4B, 0x68, 0xBD, + 0x9D, 0x88, 0xC3, 0x31, 0xB3, 0x40, 0xF1, 0xE8, 0xCF, 0xF6, 0x38, 0xBB, + 0x9C, 0xE4, 0xD1, 0x7F, 0xD4, 0xE5, 0x58, 0x9B, 0x7C, 0xFA, 0xD4, 0xF3, + 0x0E, 0x9B, 0x75, 0x91, 0xE4, 0xBA, 0x52, 0x2E, 0x19, 0x7E, 0xD1, 0xF5, + 0xCD, 0x5A, 0x19, 0xFC, 0xBA, 0x06, 0xF6, 0xFB, 0x52, 0xA8, 0x4B, 0x99, + 0x04, 0xDD, 0xF8, 0xF9, 0xB4, 0x8B, 0x50, 0xA3, 0x4E, 0x62, 0x89, 0xF0, + 0x87, 0x24, 0xFA, 0x83, 0x42, 0xC1, 0x87, 0xFA, 0xD5, 0x2D, 0x29, 0x2A, + 0x5A, 0x71, 0x7A, 0x64, 0x6A, 0xD7, 0x27, 0x60, 0x63, 0x0D, 0xDB, 0xCE, + 0x49, 0xF5, 0x8D, 0x1F, 0x90, 0x89, 0x32, 0x17, 0xF8, 0x73, 0x43, 0xB8, + 0xD2, 0x5A, 0x93, 0x86, 0x61, 0xD6, 0xE1, 0x75, 0x0A, 0xEA, 0x79, 0x66, + 0x76, 0x88, 0x4F, 0x71, 0xEB, 0x04, 0x25, 0xD6, 0x0A, 0x5A, 0x7A, 0x93, + 0xE5, 0xB9, 0x4B, 0x17, 0x40, 0x0F, 0xB1, 0xB6, 0xB9, 0xF5, 0xDE, 0x4F, + 0xDC, 0xE0, 0xB3, 0xAC, 0x3B, 0x11, 0x70, 0x60, 0x84, 0x4A, 0x43, 0x6E, + 0x99, 0x20, 0xC0, 0x29, 0x71, 0x0A, 0xC0, 0x65 +}; + +static const unsigned char TA186_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA187_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x43, 0x45, 0x52, 0x54, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x53, + 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x13, + 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, + 0x54, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA187_RSA_N[] = { + 0xC0, 0xC5, 0x75, 0x19, 0x91, 0x7D, 0x44, 0x74, 0x74, 0x87, 0xFE, 0x0E, + 0x3B, 0x96, 0xDC, 0xD8, 0x01, 0x16, 0xCC, 0xEE, 0x63, 0x91, 0xE7, 0x0B, + 0x6F, 0xCE, 0x3B, 0x0A, 0x69, 0x1A, 0x7C, 0xC2, 0xE3, 0xAF, 0x82, 0x8E, + 0x86, 0xD7, 0x5E, 0x8F, 0x57, 0xEB, 0xD3, 0x21, 0x59, 0xFD, 0x39, 0x37, + 0x42, 0x30, 0xBE, 0x50, 0xEA, 0xB6, 0x0F, 0xA9, 0x88, 0xD8, 0x2E, 0x2D, + 0x69, 0x21, 0xE7, 0xD1, 0x37, 0x18, 0x4E, 0x7D, 0x91, 0xD5, 0x16, 0x5F, + 0x6B, 0x5B, 0x00, 0xC2, 0x39, 0x43, 0x0D, 0x36, 0x85, 0x52, 0xB9, 0x53, + 0x65, 0x0F, 0x1D, 0x42, 0xE5, 0x8F, 0xCF, 0x05, 0xD3, 0xEE, 0xDC, 0x0C, + 0x1A, 0xD9, 0xB8, 0x8B, 0x78, 0x22, 0x67, 0xE4, 0x69, 0xB0, 0x68, 0xC5, + 0x3C, 0xE4, 0x6C, 0x5A, 0x46, 0xE7, 0xCD, 0xC7, 0xFA, 0xEF, 0xC4, 0xEC, + 0x4B, 0xBD, 0x6A, 0xA4, 0xAC, 0xFD, 0xCC, 0x28, 0x51, 0xEF, 0x92, 0xB4, + 0x29, 0xAB, 0xAB, 0x35, 0x9A, 0x4C, 0xE4, 0xC4, 0x08, 0xC6, 0x26, 0xCC, + 0xF8, 0x69, 0x9F, 0xE4, 0x9C, 0xF0, 0x29, 0xD3, 0x5C, 0xF9, 0xC6, 0x16, + 0x25, 0x9E, 0x23, 0xC3, 0x20, 0xC1, 0x3D, 0x0F, 0x3F, 0x38, 0x40, 0xB0, + 0xFE, 0x82, 0x44, 0x38, 0xAA, 0x5A, 0x1A, 0x8A, 0x6B, 0x63, 0x58, 0x38, + 0xB4, 0x15, 0xD3, 0xB6, 0x11, 0x69, 0x7B, 0x1E, 0x54, 0xEE, 0x8C, 0x1A, + 0x22, 0xAC, 0x72, 0x97, 0x3F, 0x23, 0x59, 0x9B, 0xC9, 0x22, 0x84, 0xC1, + 0x07, 0x4F, 0xCC, 0x7F, 0xE2, 0x57, 0xCA, 0x12, 0x70, 0xBB, 0xA6, 0x65, + 0xF3, 0x69, 0x75, 0x63, 0xBD, 0x95, 0xFB, 0x1B, 0x97, 0xCD, 0xE4, 0xA8, + 0xAF, 0xF6, 0xD1, 0x4E, 0xA8, 0xD9, 0x8A, 0x71, 0x24, 0xCD, 0x36, 0x3D, + 0xBC, 0x96, 0xC4, 0xF1, 0x6C, 0xA9, 0xAE, 0xE5, 0xCF, 0x0D, 0x6E, 0x28, + 0x0D, 0xB0, 0x0E, 0xB5, 0xCA, 0x51, 0x7B, 0x78, 0x14, 0xC3, 0x20, 0x2F, + 0x7F, 0xFB, 0x14, 0x55, 0xE1, 0x11, 0x99, 0xFD, 0xD5, 0x0A, 0xA1, 0x9E, + 0x02, 0xE3, 0x62, 0x5F, 0xEB, 0x35, 0x4B, 0x2C, 0xB8, 0x72, 0xE8, 0x3E, + 0x3D, 0x4F, 0xAC, 0x2C, 0xBB, 0x2E, 0x86, 0xE2, 0xA3, 0x76, 0x8F, 0xE5, + 0x93, 0x2A, 0xCF, 0xA5, 0xAB, 0xC8, 0x5C, 0x8D, 0x4B, 0x06, 0xFF, 0x12, + 0x46, 0xAC, 0x78, 0xCB, 0x14, 0x07, 0x35, 0xE0, 0xA9, 0xDF, 0x8B, 0xE9, + 0xAF, 0x15, 0x4F, 0x16, 0x89, 0x5B, 0xBD, 0xF6, 0x8D, 0xC6, 0x59, 0xAE, + 0x88, 0x85, 0x0E, 0xC1, 0x89, 0xEB, 0x1F, 0x67, 0xC5, 0x45, 0x8E, 0xFF, + 0x6D, 0x37, 0x36, 0x2B, 0x78, 0x66, 0x83, 0x91, 0x51, 0x2B, 0x3D, 0xFF, + 0x51, 0x77, 0x76, 0x62, 0xA1, 0xEC, 0x67, 0x3E, 0x3E, 0x81, 0x83, 0xE0, + 0x56, 0xA9, 0x50, 0x1F, 0x1F, 0x7A, 0x99, 0xAB, 0x63, 0xBF, 0x84, 0x17, + 0x77, 0xF1, 0x0D, 0x3B, 0xDF, 0xF7, 0x9C, 0x61, 0xB3, 0x35, 0x98, 0x8A, + 0x3A, 0xB2, 0xEC, 0x3C, 0x1A, 0x37, 0x3F, 0x7E, 0x8F, 0x92, 0xCF, 0xD9, + 0x12, 0x14, 0x64, 0xDA, 0x10, 0x02, 0x15, 0x41, 0xFF, 0x4F, 0xC4, 0xEB, + 0x1C, 0xA3, 0xC9, 0xFA, 0x99, 0xF7, 0x46, 0xE9, 0xE1, 0x18, 0xD9, 0xB1, + 0xB8, 0x32, 0x2D, 0xCB, 0x14, 0x0C, 0x50, 0xD8, 0x83, 0x65, 0x83, 0xEE, + 0xB9, 0x5C, 0xCF, 0xCB, 0x05, 0x5A, 0x4C, 0xFA, 0x19, 0x97, 0x6B, 0xD6, + 0x5D, 0x13, 0xD3, 0xC2, 0x5C, 0x54, 0xBC, 0x32, 0x73, 0xA0, 0x78, 0xF5, + 0xF1, 0x6D, 0x1E, 0xCB, 0x9F, 0xA5, 0xA6, 0x9F, 0x22, 0xDC, 0xD1, 0x51, + 0x9E, 0x82, 0x79, 0x64, 0x60, 0x29, 0x13, 0x3E, 0xA3, 0xFD, 0x4F, 0x72, + 0x6A, 0xAB, 0xE2, 0xD4, 0xE5, 0xB8, 0x24, 0x55, 0x2C, 0x44, 0x4B, 0x8A, + 0x88, 0x44, 0x9C, 0xCA, 0x84, 0xD3, 0x2A, 0x3B +}; + +static const unsigned char TA187_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA188_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x29, 0x47, 0x55, 0x41, 0x4E, 0x47, 0x20, 0x44, 0x4F, 0x4E, 0x47, + 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, + 0x20, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x20, 0x43, + 0x4F, 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x47, 0x44, 0x43, 0x41, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x41, 0x55, 0x54, 0x48, 0x20, 0x52, 0x35, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA188_RSA_N[] = { + 0xD9, 0xA3, 0x16, 0xF0, 0xC8, 0x74, 0x74, 0x77, 0x9B, 0xEF, 0x33, 0x0D, + 0x3B, 0x06, 0x7E, 0x55, 0xFC, 0xB5, 0x60, 0x8F, 0x76, 0x86, 0x12, 0x42, + 0x7D, 0x56, 0x66, 0x3E, 0x88, 0x82, 0xED, 0x72, 0x63, 0x0E, 0x9E, 0x8B, + 0xDD, 0x34, 0x2C, 0x02, 0x51, 0x51, 0xC3, 0x19, 0xFD, 0x59, 0x54, 0x84, + 0xC9, 0xF1, 0x6B, 0xB3, 0x4C, 0xB0, 0xE9, 0xE8, 0x46, 0x5D, 0x38, 0xC6, + 0xA2, 0xA7, 0x2E, 0x11, 0x57, 0xBA, 0x82, 0x15, 0xA2, 0x9C, 0x8F, 0x6D, + 0xB0, 0x99, 0x4A, 0x0A, 0xF2, 0xEB, 0x89, 0x70, 0x63, 0x4E, 0x79, 0xC4, + 0xB7, 0x5B, 0xBD, 0xA2, 0x5D, 0xB1, 0xF2, 0x41, 0x02, 0x2B, 0xAD, 0xA9, + 0x3A, 0xA3, 0xEC, 0x79, 0x0A, 0xEC, 0x5F, 0x3A, 0xE3, 0xFD, 0xEF, 0x80, + 0x3C, 0xAD, 0x34, 0x9B, 0x1A, 0xAB, 0x88, 0x26, 0x7B, 0x56, 0xA2, 0x82, + 0x86, 0x1F, 0xEB, 0x35, 0x89, 0x83, 0x7F, 0x5F, 0xAE, 0x29, 0x4E, 0x3D, + 0xB6, 0x6E, 0xEC, 0xAE, 0xC1, 0xF0, 0x27, 0x9B, 0xAE, 0xE3, 0xF4, 0xEC, + 0xEF, 0xAE, 0x7F, 0xF7, 0x86, 0x3D, 0x72, 0x7A, 0xEB, 0xA5, 0xFB, 0x59, + 0x4E, 0xA7, 0xEB, 0x95, 0x8C, 0x22, 0x39, 0x79, 0xE1, 0x2D, 0x08, 0x8F, + 0xCC, 0xBC, 0x91, 0xB8, 0x41, 0xF7, 0x14, 0xC1, 0x23, 0xA9, 0xC3, 0xAD, + 0x9A, 0x45, 0x44, 0xB3, 0xB2, 0xD7, 0x2C, 0xCD, 0xC6, 0x29, 0xE2, 0x50, + 0x10, 0xAE, 0x5C, 0xCB, 0x82, 0x8E, 0x17, 0x18, 0x36, 0x7D, 0x97, 0xE6, + 0x88, 0x9A, 0xB0, 0x4D, 0x34, 0x09, 0xF4, 0x2C, 0xB9, 0x5A, 0x66, 0x2A, + 0xB0, 0x17, 0x9B, 0x9E, 0x1E, 0x76, 0x9D, 0x4A, 0x66, 0x31, 0x41, 0xDF, + 0x3F, 0xFB, 0xC5, 0x06, 0xEF, 0x1B, 0xB6, 0x7E, 0x1A, 0x46, 0x36, 0xF7, + 0x64, 0x63, 0x3B, 0xE3, 0x39, 0x18, 0x23, 0xE7, 0x67, 0x75, 0x14, 0xD5, + 0x75, 0x57, 0x92, 0x37, 0xBD, 0xBE, 0x6A, 0x1B, 0x26, 0x50, 0xF2, 0x36, + 0x26, 0x06, 0x90, 0xC5, 0x70, 0x01, 0x64, 0x6D, 0x76, 0x66, 0xE1, 0x91, + 0xDB, 0x6E, 0x07, 0xC0, 0x61, 0x80, 0x2E, 0xB2, 0x2E, 0x2F, 0x8C, 0x70, + 0xA7, 0xD1, 0x3B, 0x3C, 0xB3, 0x91, 0xE4, 0x6E, 0xB6, 0xC4, 0x3B, 0x70, + 0xF2, 0x6C, 0x92, 0x97, 0x09, 0xCD, 0x47, 0x7D, 0x18, 0xC0, 0xF3, 0xBB, + 0x9E, 0x0F, 0xD6, 0x8B, 0xAE, 0x07, 0xB6, 0x5A, 0x0F, 0xCE, 0x0B, 0x0C, + 0x47, 0xA7, 0xE5, 0x3E, 0xB8, 0xBD, 0x7D, 0xC7, 0x9B, 0x35, 0xA0, 0x61, + 0x97, 0x3A, 0x41, 0x75, 0x17, 0xCC, 0x2B, 0x96, 0x77, 0x2A, 0x92, 0x21, + 0x1E, 0xD9, 0x95, 0x76, 0x20, 0x67, 0x68, 0xCF, 0x0D, 0xBD, 0xDF, 0xD6, + 0x1F, 0x09, 0x6A, 0x9A, 0xE2, 0xCC, 0x73, 0x71, 0xA4, 0x2F, 0x7D, 0x12, + 0x80, 0xB7, 0x53, 0x30, 0x46, 0x5E, 0x4B, 0x54, 0x99, 0x0F, 0x67, 0xC9, + 0xA5, 0xC8, 0xF2, 0x20, 0xC1, 0x82, 0xEC, 0x9D, 0x11, 0xDF, 0xC2, 0x02, + 0xFB, 0x1A, 0x3B, 0xD1, 0xED, 0x20, 0x9A, 0xEF, 0x65, 0x64, 0x92, 0x10, + 0x0D, 0x2A, 0xE2, 0xDE, 0x70, 0xF1, 0x18, 0x67, 0x82, 0x8C, 0x61, 0xDE, + 0xB8, 0xBC, 0xD1, 0x2F, 0x9C, 0xFB, 0x0F, 0xD0, 0x2B, 0xED, 0x1B, 0x76, + 0xB9, 0xE4, 0x39, 0x55, 0xF8, 0xF8, 0xA1, 0x1D, 0xB8, 0xAA, 0x80, 0x00, + 0x4C, 0x82, 0xE7, 0xB2, 0x7F, 0x09, 0xB8, 0xBC, 0x30, 0xA0, 0x2F, 0x0D, + 0xF5, 0x52, 0x9E, 0x8E, 0xF7, 0x92, 0xB3, 0x0A, 0x00, 0x1D, 0x00, 0x54, + 0x97, 0x06, 0xE0, 0xB1, 0x07, 0xD9, 0xC7, 0x0F, 0x5C, 0x65, 0x7D, 0x3C, + 0x6D, 0x59, 0x57, 0xE4, 0xED, 0xA5, 0x8D, 0xE9, 0x40, 0x53, 0x9F, 0x15, + 0x4B, 0xA0, 0x71, 0xF6, 0x1A, 0x21, 0xE3, 0xDA, 0x70, 0x06, 0x21, 0x58, + 0x14, 0x87, 0x85, 0x77, 0x79, 0xAA, 0x82, 0x79 +}; + +static const unsigned char TA188_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA189_DN[] = { + 0x30, 0x42, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x09, 0x41, 0x43, 0x43, 0x56, 0x52, 0x41, 0x49, 0x5A, 0x31, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x50, 0x4B, 0x49, + 0x41, 0x43, 0x43, 0x56, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x04, 0x41, 0x43, 0x43, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53 +}; + +static const unsigned char TA189_RSA_N[] = { + 0x9B, 0xA9, 0xAB, 0xBF, 0x61, 0x4A, 0x97, 0xAF, 0x2F, 0x97, 0x66, 0x9A, + 0x74, 0x5F, 0xD0, 0xD9, 0x96, 0xFD, 0xCF, 0xE2, 0xE4, 0x66, 0xEF, 0x1F, + 0x1F, 0x47, 0x33, 0xC2, 0x44, 0xA3, 0xDF, 0x9A, 0xDE, 0x1F, 0xB5, 0x54, + 0xDD, 0x15, 0x7C, 0x69, 0x35, 0x11, 0x6F, 0xBB, 0xC8, 0x0C, 0x8E, 0x6A, + 0x18, 0x1E, 0xD8, 0x8F, 0xD9, 0x16, 0xBC, 0x10, 0x48, 0x36, 0x5C, 0xF0, + 0x63, 0xB3, 0x90, 0x5A, 0x5C, 0x24, 0x37, 0xD7, 0xA3, 0xD6, 0xCB, 0x09, + 0x71, 0xB9, 0xF1, 0x01, 0x72, 0x84, 0xB0, 0x7D, 0xDB, 0x4D, 0x80, 0xCD, + 0xFC, 0xD3, 0x6F, 0xC9, 0xF8, 0xDA, 0xB6, 0x0E, 0x82, 0xD2, 0x45, 0x85, + 0xA8, 0x1B, 0x68, 0xA8, 0x3D, 0xE8, 0xF4, 0x44, 0x6C, 0xBD, 0xA1, 0xC2, + 0xCB, 0x03, 0xBE, 0x8C, 0x3E, 0x13, 0x00, 0x84, 0xDF, 0x4A, 0x48, 0xC0, + 0xE3, 0x22, 0x0A, 0xE8, 0xE9, 0x37, 0xA7, 0x18, 0x4C, 0xB1, 0x09, 0x0D, + 0x23, 0x56, 0x7F, 0x04, 0x4D, 0xD9, 0x17, 0x84, 0x18, 0xA5, 0xC8, 0xDA, + 0x40, 0x94, 0x73, 0xEB, 0xCE, 0x0E, 0x57, 0x3C, 0x03, 0x81, 0x3A, 0x9D, + 0x0A, 0xA1, 0x57, 0x43, 0x69, 0xAC, 0x57, 0x6D, 0x79, 0x90, 0x78, 0xE5, + 0xB5, 0xB4, 0x3B, 0xD8, 0xBC, 0x4C, 0x8D, 0x28, 0xA1, 0xA7, 0xA3, 0xA7, + 0xBA, 0x02, 0x4E, 0x25, 0xD1, 0x2A, 0xAE, 0xED, 0xAE, 0x03, 0x22, 0xB8, + 0x6B, 0x20, 0x0F, 0x30, 0x28, 0x54, 0x95, 0x7F, 0xE0, 0xEE, 0xCE, 0x0A, + 0x66, 0x9D, 0xD1, 0x40, 0x2D, 0x6E, 0x22, 0xAF, 0x9D, 0x1A, 0xC1, 0x05, + 0x19, 0xD2, 0x6F, 0xC0, 0xF2, 0x9F, 0xF8, 0x7B, 0xB3, 0x02, 0x42, 0xFB, + 0x50, 0xA9, 0x1D, 0x2D, 0x93, 0x0F, 0x23, 0xAB, 0xC6, 0xC1, 0x0F, 0x92, + 0xFF, 0xD0, 0xA2, 0x15, 0xF5, 0x53, 0x09, 0x71, 0x1C, 0xFF, 0x45, 0x13, + 0x84, 0xE6, 0x26, 0x5E, 0xF8, 0xE0, 0x88, 0x1C, 0x0A, 0xFC, 0x16, 0xB6, + 0xA8, 0x73, 0x06, 0xB8, 0xF0, 0x63, 0x84, 0x02, 0xA0, 0xC6, 0x5A, 0xEC, + 0xE7, 0x74, 0xDF, 0x70, 0xAE, 0xA3, 0x83, 0x25, 0xEA, 0xD6, 0xC7, 0x97, + 0x87, 0x93, 0xA7, 0xC6, 0x8A, 0x8A, 0x33, 0x97, 0x60, 0x37, 0x10, 0x3E, + 0x97, 0x3E, 0x6E, 0x29, 0x15, 0xD6, 0xA1, 0x0F, 0xD1, 0x88, 0x2C, 0x12, + 0x9F, 0x6F, 0xAA, 0xA4, 0xC6, 0x42, 0xEB, 0x41, 0xA2, 0xE3, 0x95, 0x43, + 0xD3, 0x01, 0x85, 0x6D, 0x8E, 0xBB, 0x3B, 0xF3, 0x23, 0x36, 0xC7, 0xFE, + 0x3B, 0xE0, 0xA1, 0x25, 0x07, 0x48, 0xAB, 0xC9, 0x89, 0x74, 0xFF, 0x08, + 0x8F, 0x80, 0xBF, 0xC0, 0x96, 0x65, 0xF3, 0xEE, 0xEC, 0x4B, 0x68, 0xBD, + 0x9D, 0x88, 0xC3, 0x31, 0xB3, 0x40, 0xF1, 0xE8, 0xCF, 0xF6, 0x38, 0xBB, + 0x9C, 0xE4, 0xD1, 0x7F, 0xD4, 0xE5, 0x58, 0x9B, 0x7C, 0xFA, 0xD4, 0xF3, + 0x0E, 0x9B, 0x75, 0x91, 0xE4, 0xBA, 0x52, 0x2E, 0x19, 0x7E, 0xD1, 0xF5, + 0xCD, 0x5A, 0x19, 0xFC, 0xBA, 0x06, 0xF6, 0xFB, 0x52, 0xA8, 0x4B, 0x99, + 0x04, 0xDD, 0xF8, 0xF9, 0xB4, 0x8B, 0x50, 0xA3, 0x4E, 0x62, 0x89, 0xF0, + 0x87, 0x24, 0xFA, 0x83, 0x42, 0xC1, 0x87, 0xFA, 0xD5, 0x2D, 0x29, 0x2A, + 0x5A, 0x71, 0x7A, 0x64, 0x6A, 0xD7, 0x27, 0x60, 0x63, 0x0D, 0xDB, 0xCE, + 0x49, 0xF5, 0x8D, 0x1F, 0x90, 0x89, 0x32, 0x17, 0xF8, 0x73, 0x43, 0xB8, + 0xD2, 0x5A, 0x93, 0x86, 0x61, 0xD6, 0xE1, 0x75, 0x0A, 0xEA, 0x79, 0x66, + 0x76, 0x88, 0x4F, 0x71, 0xEB, 0x04, 0x25, 0xD6, 0x0A, 0x5A, 0x7A, 0x93, + 0xE5, 0xB9, 0x4B, 0x17, 0x40, 0x0F, 0xB1, 0xB6, 0xB9, 0xF5, 0xDE, 0x4F, + 0xDC, 0xE0, 0xB3, 0xAC, 0x3B, 0x11, 0x70, 0x60, 0x84, 0x4A, 0x43, 0x6E, + 0x99, 0x20, 0xC0, 0x29, 0x71, 0x0A, 0xC0, 0x65 +}; + +static const unsigned char TA189_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA190_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x41, 0x43, 0x20, + 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, + 0x4D +}; + +static const unsigned char TA190_RSA_N[] = { + 0xBA, 0x71, 0x80, 0x7A, 0x4C, 0x86, 0x6E, 0x7F, 0xC8, 0x13, 0x6D, 0xC0, + 0xC6, 0x7D, 0x1C, 0x00, 0x97, 0x8F, 0x2C, 0x0C, 0x23, 0xBB, 0x10, 0x9A, + 0x40, 0xA9, 0x1A, 0xB7, 0x87, 0x88, 0xF8, 0x9B, 0x56, 0x6A, 0xFB, 0xE6, + 0x7B, 0x8E, 0x8B, 0x92, 0x8E, 0xA7, 0x25, 0x5D, 0x59, 0x11, 0xDB, 0x36, + 0x2E, 0xB7, 0x51, 0x17, 0x1F, 0xA9, 0x08, 0x1F, 0x04, 0x17, 0x24, 0x58, + 0xAA, 0x37, 0x4A, 0x18, 0xDF, 0xE5, 0x39, 0xD4, 0x57, 0xFD, 0xD7, 0xC1, + 0x2C, 0x91, 0x01, 0x91, 0xE2, 0x22, 0xD4, 0x03, 0xC0, 0x58, 0xFC, 0x77, + 0x47, 0xEC, 0x8F, 0x3E, 0x74, 0x43, 0xBA, 0xAC, 0x34, 0x8D, 0x4D, 0x38, + 0x76, 0x67, 0x8E, 0xB0, 0xC8, 0x6F, 0x30, 0x33, 0x58, 0x71, 0x5C, 0xB4, + 0xF5, 0x6B, 0x6E, 0xD4, 0x01, 0x50, 0xB8, 0x13, 0x7E, 0x6C, 0x4A, 0xA3, + 0x49, 0xD1, 0x20, 0x19, 0xEE, 0xBC, 0xC0, 0x29, 0x18, 0x65, 0xA7, 0xDE, + 0xFE, 0xEF, 0xDD, 0x0A, 0x90, 0x21, 0xE7, 0x1A, 0x67, 0x92, 0x42, 0x10, + 0x98, 0x5F, 0x4F, 0x30, 0xBC, 0x3E, 0x1C, 0x45, 0xB4, 0x10, 0xD7, 0x68, + 0x40, 0x14, 0xC0, 0x40, 0xFA, 0xE7, 0x77, 0x17, 0x7A, 0xE6, 0x0B, 0x8F, + 0x65, 0x5B, 0x3C, 0xD9, 0x9A, 0x52, 0xDB, 0xB5, 0xBD, 0x9E, 0x46, 0xCF, + 0x3D, 0xEB, 0x91, 0x05, 0x02, 0xC0, 0x96, 0xB2, 0x76, 0x4C, 0x4D, 0x10, + 0x96, 0x3B, 0x92, 0xFA, 0x9C, 0x7F, 0x0F, 0x99, 0xDF, 0xBE, 0x23, 0x35, + 0x45, 0x1E, 0x02, 0x5C, 0xFE, 0xB5, 0xA8, 0x9B, 0x99, 0x25, 0xDA, 0x5E, + 0xF3, 0x22, 0xC3, 0x39, 0xF5, 0xE4, 0x2A, 0x2E, 0xD3, 0xC6, 0x1F, 0xC4, + 0x6C, 0xAA, 0xC5, 0x1C, 0x6A, 0x01, 0x05, 0x4A, 0x2F, 0xD2, 0xC5, 0xC1, + 0xA8, 0x34, 0x26, 0x5D, 0x66, 0xA5, 0xD2, 0x02, 0x21, 0xF9, 0x18, 0xB7, + 0x06, 0xF5, 0x4E, 0x99, 0x6F, 0xA8, 0xAB, 0x4C, 0x51, 0xE8, 0xCF, 0x50, + 0x18, 0xC5, 0x77, 0xC8, 0x39, 0x09, 0x2C, 0x49, 0x92, 0x32, 0x99, 0xA8, + 0xBB, 0x17, 0x17, 0x79, 0xB0, 0x5A, 0xC5, 0xE6, 0xA3, 0xC4, 0x59, 0x65, + 0x47, 0x35, 0x83, 0x5E, 0xA9, 0xE8, 0x35, 0x0B, 0x99, 0xBB, 0xE4, 0xCD, + 0x20, 0xC6, 0x9B, 0x4A, 0x06, 0x39, 0xB5, 0x68, 0xFC, 0x22, 0xBA, 0xEE, + 0x55, 0x8C, 0x2B, 0x4E, 0xEA, 0xF3, 0xB1, 0xE3, 0xFC, 0xB6, 0x99, 0x9A, + 0xD5, 0x42, 0xFA, 0x71, 0x4D, 0x08, 0xCF, 0x87, 0x1E, 0x6A, 0x71, 0x7D, + 0xF9, 0xD3, 0xB4, 0xE9, 0xA5, 0x71, 0x81, 0x7B, 0xC2, 0x4E, 0x47, 0x96, + 0xA5, 0xF6, 0x76, 0x85, 0xA3, 0x28, 0x8F, 0xE9, 0x80, 0x6E, 0x81, 0x53, + 0xA5, 0x6D, 0x5F, 0xB8, 0x48, 0xF9, 0xC2, 0xF9, 0x36, 0xA6, 0x2E, 0x49, + 0xFF, 0xB8, 0x96, 0xC2, 0x8C, 0x07, 0xB3, 0x9B, 0x88, 0x58, 0xFC, 0xEB, + 0x1B, 0x1C, 0xDE, 0x2D, 0x70, 0xE2, 0x97, 0x92, 0x30, 0xA1, 0x89, 0xE3, + 0xBC, 0x55, 0xA8, 0x27, 0xD6, 0x4B, 0xED, 0x90, 0xAD, 0x8B, 0xFA, 0x63, + 0x25, 0x59, 0x2D, 0xA8, 0x35, 0xDD, 0xCA, 0x97, 0x33, 0xBC, 0xE5, 0xCD, + 0xC7, 0x9D, 0xD1, 0xEC, 0xEF, 0x5E, 0x0E, 0x4A, 0x90, 0x06, 0x26, 0x63, + 0xAD, 0xB9, 0xD9, 0x35, 0x2D, 0x07, 0xBA, 0x76, 0x65, 0x2C, 0xAC, 0x57, + 0x8F, 0x7D, 0xF4, 0x07, 0x94, 0xD7, 0x81, 0x02, 0x96, 0x5D, 0xA3, 0x07, + 0x49, 0xD5, 0x7A, 0xD0, 0x57, 0xF9, 0x1B, 0xE7, 0x53, 0x46, 0x75, 0xAA, + 0xB0, 0x79, 0x42, 0xCB, 0x68, 0x71, 0x08, 0xE9, 0x60, 0xBD, 0x39, 0x69, + 0xCE, 0xF4, 0xAF, 0xC3, 0x56, 0x40, 0xC7, 0xAD, 0x52, 0xA2, 0x09, 0xE4, + 0x6F, 0x86, 0x47, 0x8A, 0x1F, 0xEB, 0x28, 0x27, 0x5D, 0x83, 0x20, 0xAF, + 0x04, 0xC9, 0x6C, 0x56, 0x9A, 0x8B, 0x46, 0xF5 +}; + +static const unsigned char TA190_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA191_DN[] = { + 0x30, 0x78, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x0E, + 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x05, 0x43, 0x65, 0x72, + 0x65, 0x73, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, + 0x0F, 0x56, 0x41, 0x54, 0x45, 0x53, 0x2D, 0x51, 0x32, 0x38, 0x32, 0x36, + 0x30, 0x30, 0x34, 0x4A, 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x23, 0x41, 0x43, 0x20, 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, + 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x20, 0x53, 0x45, 0x52, 0x56, + 0x49, 0x44, 0x4F, 0x52, 0x45, 0x53, 0x20, 0x53, 0x45, 0x47, 0x55, 0x52, + 0x4F, 0x53 +}; + +static const unsigned char TA191_EC_Q[] = { + 0x04, 0xF6, 0xBA, 0x57, 0x53, 0xC8, 0xCA, 0xAB, 0xDF, 0x36, 0x4A, 0x52, + 0x21, 0xE4, 0x97, 0xD2, 0x83, 0x67, 0x9E, 0xF0, 0x65, 0x51, 0xD0, 0x5E, + 0x87, 0xC7, 0x47, 0xB1, 0x59, 0xF2, 0x57, 0x47, 0x9B, 0x00, 0x02, 0x93, + 0x44, 0x17, 0x69, 0xDB, 0x42, 0xC7, 0xB1, 0xB2, 0x3A, 0x18, 0x0E, 0xB4, + 0x5D, 0x8C, 0xB3, 0x66, 0x5D, 0xA1, 0x34, 0xF9, 0x36, 0x2C, 0x49, 0xDB, + 0xF3, 0x46, 0xFC, 0xB3, 0x44, 0x69, 0x44, 0x13, 0x66, 0xFD, 0xD7, 0xC5, + 0xFD, 0xAF, 0x36, 0x4D, 0xCE, 0x03, 0x4D, 0x07, 0x71, 0xCF, 0xAF, 0x6A, + 0x05, 0xD2, 0xA2, 0x43, 0x5A, 0x0A, 0x52, 0x6F, 0x01, 0x03, 0x4E, 0x8E, + 0x8B +}; + +static const unsigned char TA192_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x54, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x05, 0x4D, 0x69, 0x6C, 0x61, 0x6E, 0x31, 0x23, 0x30, 0x21, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x1A, 0x41, 0x63, 0x74, 0x61, 0x6C, 0x69, + 0x73, 0x20, 0x53, 0x2E, 0x70, 0x2E, 0x41, 0x2E, 0x2F, 0x30, 0x33, 0x33, + 0x35, 0x38, 0x35, 0x32, 0x30, 0x39, 0x36, 0x37, 0x31, 0x27, 0x30, 0x25, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x41, 0x63, 0x74, 0x61, 0x6C, + 0x69, 0x73, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA192_RSA_N[] = { + 0xA7, 0xC6, 0xC4, 0xA5, 0x29, 0xA4, 0x2C, 0xEF, 0xE5, 0x18, 0xC5, 0xB0, + 0x50, 0xA3, 0x6F, 0x51, 0x3B, 0x9F, 0x0A, 0x5A, 0xC9, 0xC2, 0x48, 0x38, + 0x0A, 0xC2, 0x1C, 0xA0, 0x18, 0x7F, 0x91, 0xB5, 0x87, 0xB9, 0x40, 0x3F, + 0xDD, 0x1D, 0x68, 0x1F, 0x08, 0x83, 0xD5, 0x2D, 0x1E, 0x88, 0xA0, 0xF8, + 0x8F, 0x56, 0x8F, 0x6D, 0x99, 0x02, 0x92, 0x90, 0x16, 0xD5, 0x5F, 0x08, + 0x6C, 0x89, 0xD7, 0xE1, 0xAC, 0xBC, 0x20, 0xC2, 0xB1, 0xE0, 0x83, 0x51, + 0x8A, 0x69, 0x4D, 0x00, 0x96, 0x5A, 0x6F, 0x2F, 0xC0, 0x44, 0x7E, 0xA3, + 0x0E, 0xE4, 0x91, 0xCD, 0x58, 0xEE, 0xDC, 0xFB, 0xC7, 0x1E, 0x45, 0x47, + 0xDD, 0x27, 0xB9, 0x08, 0x01, 0x9F, 0xA6, 0x21, 0x1D, 0xF5, 0x41, 0x2D, + 0x2F, 0x4C, 0xFD, 0x28, 0xAD, 0xE0, 0x8A, 0xAD, 0x22, 0xB4, 0x56, 0x65, + 0x8E, 0x86, 0x54, 0x8F, 0x93, 0x43, 0x29, 0xDE, 0x39, 0x46, 0x78, 0xA3, + 0x30, 0x23, 0xBA, 0xCD, 0xF0, 0x7D, 0x13, 0x57, 0xC0, 0x5D, 0xD2, 0x83, + 0x6B, 0x48, 0x4C, 0xC4, 0xAB, 0x9F, 0x80, 0x5A, 0x5B, 0x3A, 0xBD, 0xC9, + 0xA7, 0x22, 0x3F, 0x80, 0x27, 0x33, 0x5B, 0x0E, 0xB7, 0x8A, 0x0C, 0x5D, + 0x07, 0x37, 0x08, 0xCB, 0x6C, 0xD2, 0x7A, 0x47, 0x22, 0x44, 0x35, 0xC5, + 0xCC, 0xCC, 0x2E, 0x8E, 0xDD, 0x2A, 0xED, 0xB7, 0x7D, 0x66, 0x0D, 0x5F, + 0x61, 0x51, 0x22, 0x55, 0x1B, 0xE3, 0x46, 0xE3, 0xE3, 0x3D, 0xD0, 0x35, + 0x62, 0x9A, 0xDB, 0xAF, 0x14, 0xC8, 0x5B, 0xA1, 0xCC, 0x89, 0x1B, 0xE1, + 0x30, 0x26, 0xFC, 0xA0, 0x9B, 0x1F, 0x81, 0xA7, 0x47, 0x1F, 0x04, 0xEB, + 0xA3, 0x39, 0x92, 0x06, 0x9F, 0x99, 0xD3, 0xBF, 0xD3, 0xEA, 0x4F, 0x50, + 0x9C, 0x19, 0xFE, 0x96, 0x87, 0x1E, 0x3C, 0x65, 0xF6, 0xA3, 0x18, 0x24, + 0x83, 0x86, 0x10, 0xE7, 0x54, 0x3E, 0xA8, 0x3A, 0x76, 0x24, 0x4F, 0x81, + 0x21, 0xC5, 0xE3, 0x0F, 0x02, 0xF8, 0x93, 0x94, 0x47, 0x20, 0xBB, 0xFE, + 0xD4, 0x0E, 0xD3, 0x68, 0xB9, 0xDD, 0xC4, 0x7A, 0x84, 0x82, 0xE3, 0x53, + 0x54, 0x79, 0xDD, 0xDB, 0x9C, 0xD2, 0xF2, 0x07, 0x9B, 0x2E, 0xB6, 0xBC, + 0x3E, 0xED, 0x85, 0x6D, 0xEF, 0x25, 0x11, 0xF2, 0x97, 0x1A, 0x42, 0x61, + 0xF7, 0x4A, 0x97, 0xE8, 0x8B, 0xB1, 0x10, 0x07, 0xFA, 0x65, 0x81, 0xB2, + 0xA2, 0x39, 0xCF, 0xF7, 0x3C, 0xFF, 0x18, 0xFB, 0xC6, 0xF1, 0x5A, 0x8B, + 0x59, 0xE2, 0x02, 0xAC, 0x7B, 0x92, 0xD0, 0x4E, 0x14, 0x4F, 0x59, 0x45, + 0xF6, 0x0C, 0x5E, 0x28, 0x5F, 0xB0, 0xE8, 0x3F, 0x45, 0xCF, 0xCF, 0xAF, + 0x9B, 0x6F, 0xFB, 0x84, 0xD3, 0x77, 0x5A, 0x95, 0x6F, 0xAC, 0x94, 0x84, + 0x9E, 0xEE, 0xBC, 0xC0, 0x4A, 0x8F, 0x4A, 0x93, 0xF8, 0x44, 0x21, 0xE2, + 0x31, 0x45, 0x61, 0x50, 0x4E, 0x10, 0xD8, 0xE3, 0x35, 0x7C, 0x4C, 0x19, + 0xB4, 0xDE, 0x05, 0xBF, 0xA3, 0x06, 0x9F, 0xC8, 0xB5, 0xCD, 0xE4, 0x1F, + 0xD7, 0x17, 0x06, 0x0D, 0x7A, 0x95, 0x74, 0x55, 0x0D, 0x68, 0x1A, 0xFC, + 0x10, 0x1B, 0x62, 0x64, 0x9D, 0x6D, 0xE0, 0x95, 0xA0, 0xC3, 0x94, 0x07, + 0x57, 0x0D, 0x14, 0xE6, 0xBD, 0x05, 0xFB, 0xB8, 0x9F, 0xE6, 0xDF, 0x8B, + 0xE2, 0xC6, 0xE7, 0x7E, 0x96, 0xF6, 0x53, 0xC5, 0x80, 0x34, 0x50, 0x28, + 0x58, 0xF0, 0x12, 0x50, 0x71, 0x17, 0x30, 0xBA, 0xE6, 0x78, 0x63, 0xBC, + 0xF4, 0xB2, 0xAD, 0x9B, 0x2B, 0xB2, 0xFE, 0xE1, 0x39, 0x8C, 0x5E, 0xBA, + 0x0B, 0x20, 0x94, 0xDE, 0x7B, 0x83, 0xB8, 0xFF, 0xE3, 0x56, 0x8D, 0xB7, + 0x11, 0xE9, 0x3B, 0x8C, 0xF2, 0xB1, 0xC1, 0x5D, 0x9D, 0xA4, 0x0B, 0x4C, + 0x2B, 0xD9, 0xB2, 0x18, 0xF5, 0xB5, 0x9F, 0x4B +}; + +static const unsigned char TA192_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA193_DN[] = { + 0x30, 0x81, 0xB4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, + 0x74, 0x31, 0x40, 0x30, 0x3E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x14, 0x37, + 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, + 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x5F, 0x32, 0x30, 0x34, 0x38, + 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x2E, 0x20, 0x62, 0x79, 0x20, + 0x72, 0x65, 0x66, 0x2E, 0x20, 0x28, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x73, + 0x20, 0x6C, 0x69, 0x61, 0x62, 0x2E, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1C, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, + 0x65, 0x74, 0x20, 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, + 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, + 0x34, 0x38, 0x29 +}; + +static const unsigned char TA193_RSA_N[] = { + 0xAD, 0x4D, 0x4B, 0xA9, 0x12, 0x86, 0xB2, 0xEA, 0xA3, 0x20, 0x07, 0x15, + 0x16, 0x64, 0x2A, 0x2B, 0x4B, 0xD1, 0xBF, 0x0B, 0x4A, 0x4D, 0x8E, 0xED, + 0x80, 0x76, 0xA5, 0x67, 0xB7, 0x78, 0x40, 0xC0, 0x73, 0x42, 0xC8, 0x68, + 0xC0, 0xDB, 0x53, 0x2B, 0xDD, 0x5E, 0xB8, 0x76, 0x98, 0x35, 0x93, 0x8B, + 0x1A, 0x9D, 0x7C, 0x13, 0x3A, 0x0E, 0x1F, 0x5B, 0xB7, 0x1E, 0xCF, 0xE5, + 0x24, 0x14, 0x1E, 0xB1, 0x81, 0xA9, 0x8D, 0x7D, 0xB8, 0xCC, 0x6B, 0x4B, + 0x03, 0xF1, 0x02, 0x0C, 0xDC, 0xAB, 0xA5, 0x40, 0x24, 0x00, 0x7F, 0x74, + 0x94, 0xA1, 0x9D, 0x08, 0x29, 0xB3, 0x88, 0x0B, 0xF5, 0x87, 0x77, 0x9D, + 0x55, 0xCD, 0xE4, 0xC3, 0x7E, 0xD7, 0x6A, 0x64, 0xAB, 0x85, 0x14, 0x86, + 0x95, 0x5B, 0x97, 0x32, 0x50, 0x6F, 0x3D, 0xC8, 0xBA, 0x66, 0x0C, 0xE3, + 0xFC, 0xBD, 0xB8, 0x49, 0xC1, 0x76, 0x89, 0x49, 0x19, 0xFD, 0xC0, 0xA8, + 0xBD, 0x89, 0xA3, 0x67, 0x2F, 0xC6, 0x9F, 0xBC, 0x71, 0x19, 0x60, 0xB8, + 0x2D, 0xE9, 0x2C, 0xC9, 0x90, 0x76, 0x66, 0x7B, 0x94, 0xE2, 0xAF, 0x78, + 0xD6, 0x65, 0x53, 0x5D, 0x3C, 0xD6, 0x9C, 0xB2, 0xCF, 0x29, 0x03, 0xF9, + 0x2F, 0xA4, 0x50, 0xB2, 0xD4, 0x48, 0xCE, 0x05, 0x32, 0x55, 0x8A, 0xFD, + 0xB2, 0x64, 0x4C, 0x0E, 0xE4, 0x98, 0x07, 0x75, 0xDB, 0x7F, 0xDF, 0xB9, + 0x08, 0x55, 0x60, 0x85, 0x30, 0x29, 0xF9, 0x7B, 0x48, 0xA4, 0x69, 0x86, + 0xE3, 0x35, 0x3F, 0x1E, 0x86, 0x5D, 0x7A, 0x7A, 0x15, 0xBD, 0xEF, 0x00, + 0x8E, 0x15, 0x22, 0x54, 0x17, 0x00, 0x90, 0x26, 0x93, 0xBC, 0x0E, 0x49, + 0x68, 0x91, 0xBF, 0xF8, 0x47, 0xD3, 0x9D, 0x95, 0x42, 0xC1, 0x0E, 0x4D, + 0xDF, 0x6F, 0x26, 0xCF, 0xC3, 0x18, 0x21, 0x62, 0x66, 0x43, 0x70, 0xD6, + 0xD5, 0xC0, 0x07, 0xE1 +}; + +static const unsigned char TA193_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA194_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C +}; + +static const unsigned char TA194_RSA_N[] = { + 0xF6, 0x1B, 0x4F, 0x67, 0x07, 0x2B, 0xA1, 0x15, 0xF5, 0x06, 0x22, 0xCB, + 0x1F, 0x01, 0xB2, 0xE3, 0x73, 0x45, 0x06, 0x44, 0x49, 0x2C, 0xBB, 0x49, + 0x25, 0x14, 0xD6, 0xCE, 0xC3, 0xB7, 0xAB, 0x2C, 0x4F, 0xC6, 0x41, 0x32, + 0x94, 0x57, 0xFA, 0x12, 0xA7, 0x5B, 0x0E, 0xE2, 0x8F, 0x1F, 0x1E, 0x86, + 0x19, 0xA7, 0xAA, 0xB5, 0x2D, 0xB9, 0x5F, 0x0D, 0x8A, 0xC2, 0xAF, 0x85, + 0x35, 0x79, 0x32, 0x2D, 0xBB, 0x1C, 0x62, 0x37, 0xF2, 0xB1, 0x5B, 0x4A, + 0x3D, 0xCA, 0xCD, 0x71, 0x5F, 0xE9, 0x42, 0xBE, 0x94, 0xE8, 0xC8, 0xDE, + 0xF9, 0x22, 0x48, 0x64, 0xC6, 0xE5, 0xAB, 0xC6, 0x2B, 0x6D, 0xAD, 0x05, + 0xF0, 0xFA, 0xD5, 0x0B, 0xCF, 0x9A, 0xE5, 0xF0, 0x50, 0xA4, 0x8B, 0x3B, + 0x47, 0xA5, 0x23, 0x5B, 0x7A, 0x7A, 0xF8, 0x33, 0x3F, 0xB8, 0xEF, 0x99, + 0x97, 0xE3, 0x20, 0xC1, 0xD6, 0x28, 0x89, 0xCF, 0x94, 0xFB, 0xB9, 0x45, + 0xED, 0xE3, 0x40, 0x17, 0x11, 0xD4, 0x74, 0xF0, 0x0B, 0x31, 0xE2, 0x2B, + 0x26, 0x6A, 0x9B, 0x4C, 0x57, 0xAE, 0xAC, 0x20, 0x3E, 0xBA, 0x45, 0x7A, + 0x05, 0xF3, 0xBD, 0x9B, 0x69, 0x15, 0xAE, 0x7D, 0x4E, 0x20, 0x63, 0xC4, + 0x35, 0x76, 0x3A, 0x07, 0x02, 0xC9, 0x37, 0xFD, 0xC7, 0x47, 0xEE, 0xE8, + 0xF1, 0x76, 0x1D, 0x73, 0x15, 0xF2, 0x97, 0xA4, 0xB5, 0xC8, 0x7A, 0x79, + 0xD9, 0x42, 0xAA, 0x2B, 0x7F, 0x5C, 0xFE, 0xCE, 0x26, 0x4F, 0xA3, 0x66, + 0x81, 0x35, 0xAF, 0x44, 0xBA, 0x54, 0x1E, 0x1C, 0x30, 0x32, 0x65, 0x9D, + 0xE6, 0x3C, 0x93, 0x5E, 0x50, 0x4E, 0x7A, 0xE3, 0x3A, 0xD4, 0x6E, 0xCC, + 0x1A, 0xFB, 0xF9, 0xD2, 0x37, 0xAE, 0x24, 0x2A, 0xAB, 0x57, 0x03, 0x22, + 0x28, 0x0D, 0x49, 0x75, 0x7F, 0xB7, 0x28, 0xDA, 0x75, 0xBF, 0x8E, 0xE3, + 0xDC, 0x0E, 0x79, 0x31 +}; + +static const unsigned char TA194_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA195_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, 0x67 +}; + +static const unsigned char TA195_RSA_N[] = { + 0xB4, 0x84, 0xCC, 0x33, 0x17, 0x2E, 0x6B, 0x94, 0x6C, 0x6B, 0x61, 0x52, + 0xA0, 0xEB, 0xA3, 0xCF, 0x79, 0x94, 0x4C, 0xE5, 0x94, 0x80, 0x99, 0xCB, + 0x55, 0x64, 0x44, 0x65, 0x8F, 0x67, 0x64, 0xE2, 0x06, 0xE3, 0x5C, 0x37, + 0x49, 0xF6, 0x2F, 0x9B, 0x84, 0x84, 0x1E, 0x2D, 0xF2, 0x60, 0x9D, 0x30, + 0x4E, 0xCC, 0x84, 0x85, 0xE2, 0x2C, 0xCF, 0x1E, 0x9E, 0xFE, 0x36, 0xAB, + 0x33, 0x77, 0x35, 0x44, 0xD8, 0x35, 0x96, 0x1A, 0x3D, 0x36, 0xE8, 0x7A, + 0x0E, 0xD8, 0xD5, 0x47, 0xA1, 0x6A, 0x69, 0x8B, 0xD9, 0xFC, 0xBB, 0x3A, + 0xAE, 0x79, 0x5A, 0xD5, 0xF4, 0xD6, 0x71, 0xBB, 0x9A, 0x90, 0x23, 0x6B, + 0x9A, 0xB7, 0x88, 0x74, 0x87, 0x0C, 0x1E, 0x5F, 0xB9, 0x9E, 0x2D, 0xFA, + 0xAB, 0x53, 0x2B, 0xDC, 0xBB, 0x76, 0x3E, 0x93, 0x4C, 0x08, 0x08, 0x8C, + 0x1E, 0xA2, 0x23, 0x1C, 0xD4, 0x6A, 0xAD, 0x22, 0xBA, 0x99, 0x01, 0x2E, + 0x6D, 0x65, 0xCB, 0xBE, 0x24, 0x66, 0x55, 0x24, 0x4B, 0x40, 0x44, 0xB1, + 0x1B, 0xD7, 0xE1, 0xC2, 0x85, 0xC0, 0xDE, 0x10, 0x3F, 0x3D, 0xED, 0xB8, + 0xFC, 0xF1, 0xF1, 0x23, 0x53, 0xDC, 0xBF, 0x65, 0x97, 0x6F, 0xD9, 0xF9, + 0x40, 0x71, 0x8D, 0x7D, 0xBD, 0x95, 0xD4, 0xCE, 0xBE, 0xA0, 0x5E, 0x27, + 0x23, 0xDE, 0xFD, 0xA6, 0xD0, 0x26, 0x0E, 0x00, 0x29, 0xEB, 0x3C, 0x46, + 0xF0, 0x3D, 0x60, 0xBF, 0x3F, 0x50, 0xD2, 0xDC, 0x26, 0x41, 0x51, 0x9E, + 0x14, 0x37, 0x42, 0x04, 0xA3, 0x70, 0x57, 0xA8, 0x1B, 0x87, 0xED, 0x2D, + 0xFA, 0x7B, 0xEE, 0x8C, 0x0A, 0xE3, 0xA9, 0x66, 0x89, 0x19, 0xCB, 0x41, + 0xF9, 0xDD, 0x44, 0x36, 0x61, 0xCF, 0xE2, 0x77, 0x46, 0xC8, 0x7D, 0xF6, + 0xF4, 0x92, 0x81, 0x36, 0xFD, 0xDB, 0x34, 0xF1, 0x72, 0x7E, 0xF3, 0x0C, + 0x16, 0xBD, 0xB4, 0x15 +}; + +static const unsigned char TA195_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA196_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA196_EC_Q[] = { + 0x04, 0x0D, 0x30, 0x5E, 0x1B, 0x15, 0x9D, 0x03, 0xD0, 0xA1, 0x79, 0x35, + 0xB7, 0x3A, 0x3C, 0x92, 0x7A, 0xCA, 0x15, 0x1C, 0xCD, 0x62, 0xF3, 0x9C, + 0x26, 0x5C, 0x07, 0x3D, 0xE5, 0x54, 0xFA, 0xA3, 0xD6, 0xCC, 0x12, 0xEA, + 0xF4, 0x14, 0x5F, 0xE8, 0x8E, 0x19, 0xAB, 0x2F, 0x2E, 0x48, 0xE6, 0xAC, + 0x18, 0x43, 0x78, 0xAC, 0xD0, 0x37, 0xC3, 0xBD, 0xB2, 0xCD, 0x2C, 0xE6, + 0x47, 0xE2, 0x1A, 0xE6, 0x63, 0xB8, 0x3D, 0x2E, 0x2F, 0x78, 0xC4, 0x4F, + 0xDB, 0xF4, 0x0F, 0xA4, 0x68, 0x4C, 0x55, 0x72, 0x6B, 0x95, 0x1D, 0x4E, + 0x18, 0x42, 0x95, 0x78, 0xCC, 0x37, 0x3C, 0x91, 0xE2, 0x9B, 0x65, 0x2B, + 0x29 +}; + +static const unsigned char TA197_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x13, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D +}; + +static const unsigned char TA197_RSA_N[] = { + 0xC4, 0x12, 0xDF, 0xA9, 0x5F, 0xFE, 0x41, 0xDD, 0xDD, 0xF5, 0x9F, 0x8A, + 0xE3, 0xF6, 0xAC, 0xE1, 0x3C, 0x78, 0x9A, 0xBC, 0xD8, 0xF0, 0x7F, 0x7A, + 0xA0, 0x33, 0x2A, 0xDC, 0x8D, 0x20, 0x5B, 0xAE, 0x2D, 0x6F, 0xE7, 0x93, + 0xD9, 0x36, 0x70, 0x6A, 0x68, 0xCF, 0x8E, 0x51, 0xA3, 0x85, 0x5B, 0x67, + 0x04, 0xA0, 0x10, 0x24, 0x6F, 0x5D, 0x28, 0x82, 0xC1, 0x97, 0x57, 0xD8, + 0x48, 0x29, 0x13, 0xB6, 0xE1, 0xBE, 0x91, 0x4D, 0xDF, 0x85, 0x0C, 0x53, + 0x18, 0x9A, 0x1E, 0x24, 0xA2, 0x4F, 0x8F, 0xF0, 0xA2, 0x85, 0x0B, 0xCB, + 0xF4, 0x29, 0x7F, 0xD2, 0xA4, 0x58, 0xEE, 0x26, 0x4D, 0xC9, 0xAA, 0xA8, + 0x7B, 0x9A, 0xD9, 0xFA, 0x38, 0xDE, 0x44, 0x57, 0x15, 0xE5, 0xF8, 0x8C, + 0xC8, 0xD9, 0x48, 0xE2, 0x0D, 0x16, 0x27, 0x1D, 0x1E, 0xC8, 0x83, 0x85, + 0x25, 0xB7, 0xBA, 0xAA, 0x55, 0x41, 0xCC, 0x03, 0x22, 0x4B, 0x2D, 0x91, + 0x8D, 0x8B, 0xE6, 0x89, 0xAF, 0x66, 0xC7, 0xE9, 0xFF, 0x2B, 0xE9, 0x3C, + 0xAC, 0xDA, 0xD2, 0xB3, 0xC3, 0xE1, 0x68, 0x9C, 0x89, 0xF8, 0x7A, 0x00, + 0x56, 0xDE, 0xF4, 0x55, 0x95, 0x6C, 0xFB, 0xBA, 0x64, 0xDD, 0x62, 0x8B, + 0xDF, 0x0B, 0x77, 0x32, 0xEB, 0x62, 0xCC, 0x26, 0x9A, 0x9B, 0xBB, 0xAA, + 0x62, 0x83, 0x4C, 0xB4, 0x06, 0x7A, 0x30, 0xC8, 0x29, 0xBF, 0xED, 0x06, + 0x4D, 0x97, 0xB9, 0x1C, 0xC4, 0x31, 0x2B, 0xD5, 0x5F, 0xBC, 0x53, 0x12, + 0x17, 0x9C, 0x99, 0x57, 0x29, 0x66, 0x77, 0x61, 0x21, 0x31, 0x07, 0x2E, + 0x25, 0x49, 0x9D, 0x18, 0xF2, 0xEE, 0xF3, 0x2B, 0x71, 0x8C, 0xB5, 0xBA, + 0x39, 0x07, 0x49, 0x77, 0xFC, 0xEF, 0x2E, 0x92, 0x90, 0x05, 0x8D, 0x2D, + 0x2F, 0x77, 0x7B, 0xEF, 0x43, 0xBF, 0x35, 0xBB, 0x9A, 0xD8, 0xF9, 0x73, + 0xA7, 0x2C, 0xF2, 0xD0, 0x57, 0xEE, 0x28, 0x4E, 0x26, 0x5F, 0x8F, 0x90, + 0x68, 0x09, 0x2F, 0xB8, 0xF8, 0xDC, 0x06, 0xE9, 0x2E, 0x9A, 0x3E, 0x51, + 0xA7, 0xD1, 0x22, 0xC4, 0x0A, 0xA7, 0x38, 0x48, 0x6C, 0xB3, 0xF9, 0xFF, + 0x7D, 0xAB, 0x86, 0x57, 0xE3, 0xBA, 0xD6, 0x85, 0x78, 0x77, 0xBA, 0x43, + 0xEA, 0x48, 0x7F, 0xF6, 0xD8, 0xBE, 0x23, 0x6D, 0x1E, 0xBF, 0xD1, 0x36, + 0x6C, 0x58, 0x5C, 0xF1, 0xEE, 0xA4, 0x19, 0x54, 0x1A, 0xF5, 0x03, 0xD2, + 0x76, 0xE6, 0xE1, 0x8C, 0xBD, 0x3C, 0xB3, 0xD3, 0x48, 0x4B, 0xE2, 0xC8, + 0xF8, 0x7F, 0x92, 0xA8, 0x76, 0x46, 0x9C, 0x42, 0x65, 0x3E, 0xA4, 0x1E, + 0xC1, 0x07, 0x03, 0x5A, 0x46, 0x2D, 0xB8, 0x97, 0xF3, 0xB7, 0xD5, 0xB2, + 0x55, 0x21, 0xEF, 0xBA, 0xDC, 0x4C, 0x00, 0x97, 0xFB, 0x14, 0x95, 0x27, + 0x33, 0xBF, 0xE8, 0x43, 0x47, 0x46, 0xD2, 0x08, 0x99, 0x16, 0x60, 0x3B, + 0x9A, 0x7E, 0xD2, 0xE6, 0xED, 0x38, 0xEA, 0xEC, 0x01, 0x1E, 0x3C, 0x48, + 0x56, 0x49, 0x09, 0xC7, 0x4C, 0x37, 0x00, 0x9E, 0x88, 0x0E, 0xC0, 0x73, + 0xE1, 0x6F, 0x66, 0xE9, 0x72, 0x47, 0x30, 0x3E, 0x10, 0xE5, 0x0B, 0x03, + 0xC9, 0x9A, 0x42, 0x00, 0x6C, 0xC5, 0x94, 0x7E, 0x61, 0xC4, 0x8A, 0xDF, + 0x7F, 0x82, 0x1A, 0x0B, 0x59, 0xC4, 0x59, 0x32, 0x77, 0xB3, 0xBC, 0x60, + 0x69, 0x56, 0x39, 0xFD, 0xB4, 0x06, 0x7B, 0x2C, 0xD6, 0x64, 0x36, 0xD9, + 0xBD, 0x48, 0xED, 0x84, 0x1F, 0x7E, 0xA5, 0x22, 0x8F, 0x2A, 0xB8, 0x42, + 0xF4, 0x82, 0xB7, 0xD4, 0x53, 0x90, 0x78, 0x4E, 0x2D, 0x1A, 0xFD, 0x81, + 0x6F, 0x44, 0xD7, 0x3B, 0x01, 0x74, 0x96, 0x42, 0xE0, 0x00, 0xE2, 0x2E, + 0x6B, 0xEA, 0xC5, 0xEE, 0x72, 0xAC, 0xBB, 0xBF, 0xFE, 0xEA, 0xAA, 0xA8, + 0xF8, 0xDC, 0xF6, 0xB2, 0x79, 0x8A, 0xB6, 0x67 +}; + +static const unsigned char TA197_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA198_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA198_RSA_N[] = { + 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80, + 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7, + 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86, + 0xD3, 0xA0, 0x43, 0x7A, 0x4E, 0xB2, 0xA4, 0xD0, 0x36, 0xBA, 0x01, 0xBE, + 0x8D, 0xDB, 0x48, 0xC8, 0x07, 0x17, 0x36, 0x4C, 0xF4, 0xEE, 0x88, 0x23, + 0xC7, 0x3E, 0xEB, 0x37, 0xF5, 0xB5, 0x19, 0xF8, 0x49, 0x68, 0xB0, 0xDE, + 0xD7, 0xB9, 0x76, 0x38, 0x1D, 0x61, 0x9E, 0xA4, 0xFE, 0x82, 0x36, 0xA5, + 0xE5, 0x4A, 0x56, 0xE4, 0x45, 0xE1, 0xF9, 0xFD, 0xB4, 0x16, 0xFA, 0x74, + 0xDA, 0x9C, 0x9B, 0x35, 0x39, 0x2F, 0xFA, 0xB0, 0x20, 0x50, 0x06, 0x6C, + 0x7A, 0xD0, 0x80, 0xB2, 0xA6, 0xF9, 0xAF, 0xEC, 0x47, 0x19, 0x8F, 0x50, + 0x38, 0x07, 0xDC, 0xA2, 0x87, 0x39, 0x58, 0xF8, 0xBA, 0xD5, 0xA9, 0xF9, + 0x48, 0x67, 0x30, 0x96, 0xEE, 0x94, 0x78, 0x5E, 0x6F, 0x89, 0xA3, 0x51, + 0xC0, 0x30, 0x86, 0x66, 0xA1, 0x45, 0x66, 0xBA, 0x54, 0xEB, 0xA3, 0xC3, + 0x91, 0xF9, 0x48, 0xDC, 0xFF, 0xD1, 0xE8, 0x30, 0x2D, 0x7D, 0x2D, 0x74, + 0x70, 0x35, 0xD7, 0x88, 0x24, 0xF7, 0x9E, 0xC4, 0x59, 0x6E, 0xBB, 0x73, + 0x87, 0x17, 0xF2, 0x32, 0x46, 0x28, 0xB8, 0x43, 0xFA, 0xB7, 0x1D, 0xAA, + 0xCA, 0xB4, 0xF2, 0x9F, 0x24, 0x0E, 0x2D, 0x4B, 0xF7, 0x71, 0x5C, 0x5E, + 0x69, 0xFF, 0xEA, 0x95, 0x02, 0xCB, 0x38, 0x8A, 0xAE, 0x50, 0x38, 0x6F, + 0xDB, 0xFB, 0x2D, 0x62, 0x1B, 0xC5, 0xC7, 0x1E, 0x54, 0xE1, 0x77, 0xE0, + 0x67, 0xC8, 0x0F, 0x9C, 0x87, 0x23, 0xD6, 0x3F, 0x40, 0x20, 0x7F, 0x20, + 0x80, 0xC4, 0x80, 0x4C, 0x3E, 0x3B, 0x24, 0x26, 0x8E, 0x04, 0xAE, 0x6C, + 0x9A, 0xC8, 0xAA, 0x0D +}; + +static const unsigned char TA198_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA199_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA199_RSA_N[] = { + 0xAD, 0x96, 0x9F, 0x2D, 0x9C, 0x4A, 0x4C, 0x4A, 0x81, 0x79, 0x51, 0x99, + 0xEC, 0x8A, 0xCB, 0x6B, 0x60, 0x51, 0x13, 0xBC, 0x4D, 0x6D, 0x06, 0xFC, + 0xB0, 0x08, 0x8D, 0xDD, 0x19, 0x10, 0x6A, 0xC7, 0x26, 0x0C, 0x35, 0xD8, + 0xC0, 0x6F, 0x20, 0x84, 0xE9, 0x94, 0xB1, 0x9B, 0x85, 0x03, 0xC3, 0x5B, + 0xDB, 0x4A, 0xE8, 0xC8, 0xF8, 0x90, 0x76, 0xD9, 0x5B, 0x4F, 0xE3, 0x4C, + 0xE8, 0x06, 0x36, 0x4D, 0xCC, 0x9A, 0xAC, 0x3D, 0x0C, 0x90, 0x2B, 0x92, + 0xD4, 0x06, 0x19, 0x60, 0xAC, 0x37, 0x44, 0x79, 0x85, 0x81, 0x82, 0xAD, + 0x5A, 0x37, 0xE0, 0x0D, 0xCC, 0x9D, 0xA6, 0x4C, 0x52, 0x76, 0xEA, 0x43, + 0x9D, 0xB7, 0x04, 0xD1, 0x50, 0xF6, 0x55, 0xE0, 0xD5, 0xD2, 0xA6, 0x49, + 0x85, 0xE9, 0x37, 0xE9, 0xCA, 0x7E, 0xAE, 0x5C, 0x95, 0x4D, 0x48, 0x9A, + 0x3F, 0xAE, 0x20, 0x5A, 0x6D, 0x88, 0x95, 0xD9, 0x34, 0xB8, 0x52, 0x1A, + 0x43, 0x90, 0xB0, 0xBF, 0x6C, 0x05, 0xB9, 0xB6, 0x78, 0xB7, 0xEA, 0xD0, + 0xE4, 0x3A, 0x3C, 0x12, 0x53, 0x62, 0xFF, 0x4A, 0xF2, 0x7B, 0xBE, 0x35, + 0x05, 0xA9, 0x12, 0x34, 0xE3, 0xF3, 0x64, 0x74, 0x62, 0x2C, 0x3D, 0x00, + 0x49, 0x5A, 0x28, 0xFE, 0x32, 0x44, 0xBB, 0x87, 0xDD, 0x65, 0x27, 0x02, + 0x71, 0x3B, 0xDA, 0x4A, 0xF7, 0x1F, 0xDA, 0xCD, 0xF7, 0x21, 0x55, 0x90, + 0x4F, 0x0F, 0xEC, 0xAE, 0x82, 0xE1, 0x9F, 0x6B, 0xD9, 0x45, 0xD3, 0xBB, + 0xF0, 0x5F, 0x87, 0xED, 0x3C, 0x2C, 0x39, 0x86, 0xDA, 0x3F, 0xDE, 0xEC, + 0x72, 0x55, 0xEB, 0x79, 0xA3, 0xAD, 0xDB, 0xDD, 0x7C, 0xB0, 0xBA, 0x1C, + 0xCE, 0xFC, 0xDE, 0x4F, 0x35, 0x76, 0xCF, 0x0F, 0xF8, 0x78, 0x1F, 0x6A, + 0x36, 0x51, 0x46, 0x27, 0x61, 0x5B, 0xE9, 0x9E, 0xCF, 0xF0, 0xA2, 0x55, + 0x7D, 0x7C, 0x25, 0x8A, 0x6F, 0x2F, 0xB4, 0xC5, 0xCF, 0x84, 0x2E, 0x2B, + 0xFD, 0x0D, 0x51, 0x10, 0x6C, 0xFB, 0x5F, 0x1B, 0xBC, 0x1B, 0x7E, 0xC5, + 0xAE, 0x3B, 0x98, 0x01, 0x31, 0x92, 0xFF, 0x0B, 0x57, 0xF4, 0x9A, 0xB2, + 0xB9, 0x57, 0xE9, 0xAB, 0xEF, 0x0D, 0x76, 0xD1, 0xF0, 0xEE, 0xF4, 0xCE, + 0x86, 0xA7, 0xE0, 0x6E, 0xE9, 0xB4, 0x69, 0xA1, 0xDF, 0x69, 0xF6, 0x33, + 0xC6, 0x69, 0x2E, 0x97, 0x13, 0x9E, 0xA5, 0x87, 0xB0, 0x57, 0x10, 0x81, + 0x37, 0xC9, 0x53, 0xB3, 0xBB, 0x7F, 0xF6, 0x92, 0xD1, 0x9C, 0xD0, 0x18, + 0xF4, 0x92, 0x6E, 0xDA, 0x83, 0x4F, 0xA6, 0x63, 0x99, 0x4C, 0xA5, 0xFB, + 0x5E, 0xEF, 0x21, 0x64, 0x7A, 0x20, 0x5F, 0x6C, 0x64, 0x85, 0x15, 0xCB, + 0x37, 0xE9, 0x62, 0x0C, 0x0B, 0x2A, 0x16, 0xDC, 0x01, 0x2E, 0x32, 0xDA, + 0x3E, 0x4B, 0xF5, 0x9E, 0x3A, 0xF6, 0x17, 0x40, 0x94, 0xEF, 0x9E, 0x91, + 0x08, 0x86, 0xFA, 0xBE, 0x63, 0xA8, 0x5A, 0x33, 0xEC, 0xCB, 0x74, 0x43, + 0x95, 0xF9, 0x6C, 0x69, 0x52, 0x36, 0xC7, 0x29, 0x6F, 0xFC, 0x55, 0x03, + 0x5C, 0x1F, 0xFB, 0x9F, 0xBD, 0x47, 0xEB, 0xE7, 0x49, 0x47, 0x95, 0x0B, + 0x4E, 0x89, 0x22, 0x09, 0x49, 0xE0, 0xF5, 0x61, 0x1E, 0xF1, 0xBF, 0x2E, + 0x8A, 0x72, 0x6E, 0x80, 0x59, 0xFF, 0x57, 0x3A, 0xF9, 0x75, 0x32, 0xA3, + 0x4E, 0x5F, 0xEC, 0xED, 0x28, 0x62, 0xD9, 0x4D, 0x73, 0xF2, 0xCC, 0x81, + 0x17, 0x60, 0xED, 0xCD, 0xEB, 0xDC, 0xDB, 0xA7, 0xCA, 0xC5, 0x7E, 0x02, + 0xBD, 0xF2, 0x54, 0x08, 0x54, 0xFD, 0xB4, 0x2D, 0x09, 0x2C, 0x17, 0x54, + 0x4A, 0x98, 0xD1, 0x54, 0xE1, 0x51, 0x67, 0x08, 0xD2, 0xED, 0x6E, 0x7E, + 0x6F, 0x3F, 0xD2, 0x2D, 0x81, 0x59, 0x29, 0x66, 0xCB, 0x90, 0x39, 0x95, + 0x11, 0x1E, 0x74, 0x27, 0xFE, 0xDD, 0xEB, 0xAF +}; + +static const unsigned char TA199_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA200_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA200_EC_Q[] = { + 0x04, 0x29, 0x97, 0xA7, 0xC6, 0x41, 0x7F, 0xC0, 0x0D, 0x9B, 0xE8, 0x01, + 0x1B, 0x56, 0xC6, 0xF2, 0x52, 0xA5, 0xBA, 0x2D, 0xB2, 0x12, 0xE8, 0xD2, + 0x2E, 0xD7, 0xFA, 0xC9, 0xC5, 0xD8, 0xAA, 0x6D, 0x1F, 0x73, 0x81, 0x3B, + 0x3B, 0x98, 0x6B, 0x39, 0x7C, 0x33, 0xA5, 0xC5, 0x4E, 0x86, 0x8E, 0x80, + 0x17, 0x68, 0x62, 0x45, 0x57, 0x7D, 0x44, 0x58, 0x1D, 0xB3, 0x37, 0xE5, + 0x67, 0x08, 0xEB, 0x66, 0xDE +}; + +static const unsigned char TA201_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x34 +}; + +static const unsigned char TA201_EC_Q[] = { + 0x04, 0xD2, 0xAB, 0x8A, 0x37, 0x4F, 0xA3, 0x53, 0x0D, 0xFE, 0xC1, 0x8A, + 0x7B, 0x4B, 0xA8, 0x7B, 0x46, 0x4B, 0x63, 0xB0, 0x62, 0xF6, 0x2D, 0x1B, + 0xDB, 0x08, 0x71, 0x21, 0xD2, 0x00, 0xE8, 0x63, 0xBD, 0x9A, 0x27, 0xFB, + 0xF0, 0x39, 0x6E, 0x5D, 0xEA, 0x3D, 0xA5, 0xC9, 0x81, 0xAA, 0xA3, 0x5B, + 0x20, 0x98, 0x45, 0x5D, 0x16, 0xDB, 0xFD, 0xE8, 0x10, 0x6D, 0xE3, 0x9C, + 0xE0, 0xE3, 0xBD, 0x5F, 0x84, 0x62, 0xF3, 0x70, 0x64, 0x33, 0xA0, 0xCB, + 0x24, 0x2F, 0x70, 0xBA, 0x88, 0xA1, 0x2A, 0xA0, 0x75, 0xF8, 0x81, 0xAE, + 0x62, 0x06, 0xC4, 0x81, 0xDB, 0x39, 0x6E, 0x29, 0xB0, 0x1E, 0xFA, 0x2E, + 0x5C +}; + +static const unsigned char TA202_DN[] = { + 0x30, 0x81, 0x84, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x05, + 0x13, 0x09, 0x47, 0x36, 0x33, 0x32, 0x38, 0x37, 0x35, 0x31, 0x30, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, + 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1E, 0x41, + 0x4E, 0x46, 0x20, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, + 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x63, 0x69, 0x6F, 0x6E, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x13, 0x0B, 0x41, 0x4E, 0x46, 0x20, 0x43, 0x41, 0x20, 0x52, + 0x61, 0x69, 0x7A, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x19, 0x41, 0x4E, 0x46, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA202_RSA_N[] = { + 0xDB, 0xEB, 0x6B, 0x2B, 0xE6, 0x64, 0x54, 0x95, 0x82, 0x90, 0xA3, 0x72, + 0xA4, 0x19, 0x01, 0x9D, 0x9C, 0x0B, 0x81, 0x5F, 0x73, 0x49, 0xBA, 0xA7, + 0xAC, 0xF3, 0x04, 0x4E, 0x7B, 0x96, 0x0B, 0xEC, 0x11, 0xE0, 0x5B, 0xA6, + 0x1C, 0xCE, 0x1B, 0xD2, 0x0D, 0x83, 0x1C, 0x2B, 0xB8, 0x9E, 0x1D, 0x7E, + 0x45, 0x32, 0x60, 0x0F, 0x07, 0xE9, 0x77, 0x58, 0x7E, 0x9F, 0x6A, 0xC8, + 0x61, 0x4E, 0xB6, 0x26, 0xC1, 0x4C, 0x8D, 0xFF, 0x4C, 0xEF, 0x34, 0xB2, + 0x1F, 0x65, 0xD8, 0xB9, 0x78, 0xF5, 0xAD, 0xA9, 0x71, 0xB9, 0xEF, 0x4F, + 0x58, 0x1D, 0xA5, 0xDE, 0x74, 0x20, 0x97, 0xA1, 0xED, 0x68, 0x4C, 0xDE, + 0x92, 0x17, 0x4B, 0xBC, 0xAB, 0xFF, 0x65, 0x9A, 0x9E, 0xFB, 0x47, 0xD9, + 0x57, 0x72, 0xF3, 0x09, 0xA1, 0xAE, 0x76, 0x44, 0x13, 0x6E, 0x9C, 0x2D, + 0x44, 0x39, 0xBC, 0xF9, 0xC7, 0x3B, 0xA4, 0x58, 0x3D, 0x41, 0xBD, 0xB4, + 0xC2, 0x49, 0xA3, 0xC8, 0x0D, 0xD2, 0x97, 0x2F, 0x07, 0x65, 0x52, 0x00, + 0xA7, 0x6E, 0xC8, 0xAF, 0x68, 0xEC, 0xF4, 0x14, 0x96, 0xB6, 0x57, 0x1F, + 0x56, 0xC3, 0x39, 0x9F, 0x2B, 0x6D, 0xE4, 0xF3, 0x3E, 0xF6, 0x35, 0x64, + 0xDA, 0x0C, 0x1C, 0xA1, 0x84, 0x4B, 0x2F, 0x4B, 0x4B, 0xE2, 0x2C, 0x24, + 0x9D, 0x6D, 0x93, 0x40, 0xEB, 0xB5, 0x23, 0x8E, 0x32, 0xCA, 0x6F, 0x45, + 0xD3, 0xA8, 0x89, 0x7B, 0x1E, 0xCF, 0x1E, 0xFA, 0x5B, 0x43, 0x8B, 0xCD, + 0xCD, 0xA8, 0x0F, 0x6A, 0xCA, 0x0C, 0x5E, 0xB9, 0x9E, 0x47, 0x8F, 0xF0, + 0xD9, 0xB6, 0x0A, 0x0B, 0x58, 0x65, 0x17, 0x33, 0xB9, 0x23, 0xE4, 0x77, + 0x19, 0x7D, 0xCB, 0x4A, 0x2E, 0x92, 0x7B, 0x4F, 0x2F, 0x10, 0x77, 0xB1, + 0x8D, 0x2F, 0x68, 0x9C, 0x62, 0xCC, 0xE0, 0x50, 0xF8, 0xEC, 0x91, 0xA7, + 0x54, 0x4C, 0x57, 0x09, 0xD5, 0x76, 0x63, 0xC5, 0xE8, 0x65, 0x1E, 0xEE, + 0x6D, 0x6A, 0xCF, 0x09, 0x9D, 0xFA, 0x7C, 0x4F, 0xAD, 0x60, 0x08, 0xFD, + 0x56, 0x99, 0x0F, 0x15, 0x2C, 0x7B, 0xA9, 0x80, 0xAB, 0x8C, 0x61, 0x8F, + 0x4A, 0x07, 0x76, 0x42, 0xDE, 0x3D, 0xF4, 0xDD, 0xB2, 0x24, 0x33, 0x5B, + 0xB8, 0xB5, 0xA3, 0x44, 0xC9, 0xAC, 0x7F, 0x77, 0x3C, 0x1D, 0x23, 0xEC, + 0x82, 0xA9, 0xA6, 0xE2, 0xC8, 0x06, 0x4C, 0x02, 0xFE, 0xAC, 0x5C, 0x99, + 0x99, 0x0B, 0x2F, 0x10, 0x8A, 0xA6, 0xF4, 0x7F, 0xD5, 0x87, 0x74, 0x0D, + 0x59, 0x49, 0x45, 0xF6, 0xF0, 0x71, 0x5C, 0x39, 0x29, 0xD6, 0xBF, 0x4A, + 0x23, 0x8B, 0xF5, 0x5F, 0x01, 0x63, 0xD2, 0x87, 0x73, 0x28, 0xB5, 0x4B, + 0x0A, 0xF5, 0xF8, 0xAB, 0x82, 0x2C, 0x7E, 0x73, 0x25, 0x32, 0x1D, 0x0B, + 0x63, 0x0A, 0x17, 0x81, 0x00, 0xFF, 0xB6, 0x76, 0x5E, 0xE7, 0xB4, 0xB1, + 0x40, 0xCA, 0x21, 0xBB, 0xD5, 0x80, 0x51, 0xE5, 0x48, 0x52, 0x67, 0x2C, + 0xD2, 0x61, 0x89, 0x07, 0x0D, 0x0F, 0xCE, 0x42, 0x77, 0xC0, 0x44, 0x73, + 0x9C, 0x44, 0x50, 0xA0, 0xDB, 0x10, 0x0A, 0x2D, 0x95, 0x1C, 0x81, 0xAF, + 0xE4, 0x1C, 0xE5, 0x14, 0x1E, 0xF1, 0x36, 0x41, 0x01, 0x02, 0x2F, 0x7D, + 0x73, 0xA7, 0xDE, 0x42, 0xCC, 0x4C, 0xE9, 0x89, 0x0D, 0x56, 0xF7, 0x9F, + 0x91, 0xD4, 0x03, 0xC6, 0x6C, 0xC9, 0x8F, 0xDB, 0xD8, 0x1C, 0xE0, 0x40, + 0x98, 0x5D, 0x66, 0x99, 0x98, 0x80, 0x6E, 0x2D, 0xFF, 0x01, 0xC5, 0xCE, + 0xCB, 0x46, 0x1F, 0xAC, 0x02, 0xC6, 0x43, 0xE6, 0xAE, 0xA2, 0x84, 0x3C, + 0xC5, 0x4E, 0x1E, 0x3D, 0x6D, 0xC9, 0x14, 0x4C, 0xE3, 0x2E, 0x41, 0xBB, + 0xCA, 0x39, 0xBF, 0x36, 0x3C, 0x2A, 0x19, 0xAA, 0x41, 0x87, 0x4E, 0xA5, + 0xCE, 0x4B, 0x32, 0x79, 0xDD, 0x90, 0x49, 0x7F +}; + +static const unsigned char TA202_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA203_DN[] = { + 0x30, 0x3C, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x15, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x0D, + 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x04, 0x41, 0x74, 0x6F, + 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x44, 0x45 +}; + +static const unsigned char TA203_RSA_N[] = { + 0x95, 0x85, 0x3B, 0x97, 0x6F, 0x2A, 0x3B, 0x2E, 0x3B, 0xCF, 0xA6, 0xF3, + 0x29, 0x35, 0xBE, 0xCF, 0x18, 0xAC, 0x3E, 0xAA, 0xD9, 0xF8, 0x4D, 0xA0, + 0x3E, 0x1A, 0x47, 0xB9, 0xBC, 0x9A, 0xDF, 0xF2, 0xFE, 0xCC, 0x3E, 0x47, + 0xE8, 0x7A, 0x96, 0xC2, 0x24, 0x8E, 0x35, 0xF4, 0xA9, 0x0C, 0xFC, 0x82, + 0xFD, 0x6D, 0xC1, 0x72, 0x62, 0x27, 0xBD, 0xEA, 0x6B, 0xEB, 0xE7, 0x8A, + 0xCC, 0x54, 0x3E, 0x90, 0x50, 0xCF, 0x80, 0xD4, 0x95, 0xFB, 0xE8, 0xB5, + 0x82, 0xD4, 0x14, 0xC5, 0xB6, 0xA9, 0x55, 0x25, 0x57, 0xDB, 0xB1, 0x50, + 0xF6, 0xB0, 0x60, 0x64, 0x59, 0x7A, 0x69, 0xCF, 0x03, 0xB7, 0x6F, 0x0D, + 0xBE, 0xCA, 0x3E, 0x6F, 0x74, 0x72, 0xEA, 0xAA, 0x30, 0x2A, 0x73, 0x62, + 0xBE, 0x49, 0x91, 0x61, 0xC8, 0x11, 0xFE, 0x0E, 0x03, 0x2A, 0xF7, 0x6A, + 0x20, 0xDC, 0x02, 0x15, 0x0D, 0x5E, 0x15, 0x6A, 0xFC, 0xE3, 0x82, 0xC1, + 0xB5, 0xC5, 0x9D, 0x64, 0x09, 0x6C, 0xA3, 0x59, 0x98, 0x07, 0x27, 0xC7, + 0x1B, 0x96, 0x2B, 0x61, 0x74, 0x71, 0x6C, 0x43, 0xF1, 0xF7, 0x35, 0x89, + 0x10, 0xE0, 0x9E, 0xEC, 0x55, 0xA1, 0x37, 0x22, 0xA2, 0x87, 0x04, 0x05, + 0x2C, 0x47, 0x7D, 0xB4, 0x1C, 0xB9, 0x62, 0x29, 0x66, 0x28, 0xCA, 0xB7, + 0xE1, 0x93, 0xF5, 0xA4, 0x94, 0x03, 0x99, 0xB9, 0x70, 0x85, 0xB5, 0xE6, + 0x48, 0xEA, 0x8D, 0x50, 0xFC, 0xD9, 0xDE, 0xCC, 0x6F, 0x07, 0x0E, 0xDD, + 0x0B, 0x72, 0x9D, 0x80, 0x30, 0x16, 0x07, 0x95, 0x3F, 0x28, 0x0E, 0xFD, + 0xC5, 0x75, 0x4F, 0x53, 0xD6, 0x74, 0x9A, 0xB4, 0x24, 0x2E, 0x8E, 0x02, + 0x91, 0xCF, 0x76, 0xC5, 0x9B, 0x1E, 0x55, 0x74, 0x9C, 0x78, 0x21, 0xB1, + 0xF0, 0x2D, 0xF1, 0x0B, 0x9F, 0xC2, 0xD5, 0x96, 0x18, 0x1F, 0xF0, 0x54, + 0x22, 0x7A, 0x8C, 0x07 +}; + +static const unsigned char TA203_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA204_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x45, 0x43, 0x43, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA204_EC_Q[] = { + 0x04, 0x96, 0x86, 0x58, 0x28, 0x37, 0x0A, 0x67, 0xD0, 0xA0, 0xDE, 0x24, + 0x19, 0x19, 0xE1, 0xE4, 0x05, 0x07, 0x1F, 0x97, 0xED, 0xE8, 0x64, 0x82, + 0xB9, 0xF6, 0xC4, 0x71, 0x50, 0xCE, 0x8A, 0x0C, 0xFF, 0xD7, 0xB5, 0x76, + 0xBB, 0xA1, 0x6C, 0x93, 0x6C, 0x83, 0xA2, 0x68, 0x6E, 0xA5, 0xD9, 0xBE, + 0x2C, 0x88, 0x95, 0x41, 0xCD, 0x5D, 0xDD, 0xB1, 0xCA, 0x83, 0x63, 0x83, + 0xCC, 0xC0, 0xBE, 0x74, 0xD9, 0xE0, 0x9D, 0xA4, 0xEE, 0x4A, 0x4E, 0x56, + 0xE0, 0x98, 0x29, 0x41, 0x93, 0x52, 0x10, 0xD5, 0x24, 0x38, 0x02, 0x32, + 0x67, 0xF1, 0x94, 0x12, 0x6F, 0xEF, 0xD7, 0xC5, 0xDE, 0x2E, 0xFD, 0x19, + 0x80 +}; + +static const unsigned char TA205_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA205_RSA_N[] = { + 0xB6, 0x80, 0x0E, 0xC4, 0x79, 0xBD, 0x05, 0x8C, 0x7D, 0xB0, 0xA3, 0x9D, + 0x4D, 0x22, 0x4D, 0xCB, 0xF0, 0x41, 0x97, 0x4D, 0x59, 0xE0, 0xD1, 0xFE, + 0x56, 0x8C, 0x97, 0xF2, 0xD7, 0xBD, 0x8F, 0x6C, 0xB7, 0x23, 0x8F, 0x5F, + 0xD5, 0xC4, 0xD8, 0x41, 0xCB, 0xF2, 0x02, 0x1E, 0x71, 0xE5, 0xE9, 0xF6, + 0x5E, 0xCB, 0x08, 0x2A, 0x5E, 0x30, 0xF2, 0x2D, 0x66, 0xC7, 0x84, 0x1B, + 0x64, 0x57, 0x38, 0x9D, 0x75, 0x2D, 0x56, 0xC6, 0x2F, 0x61, 0xEF, 0x96, + 0xFC, 0x20, 0x46, 0xBD, 0xEB, 0xD4, 0x7B, 0x3F, 0x3F, 0x7C, 0x47, 0x38, + 0x04, 0xA9, 0x1B, 0xAA, 0x52, 0xDF, 0x13, 0x37, 0xD3, 0x15, 0x15, 0x4E, + 0xBD, 0x5F, 0x7C, 0xAF, 0xAD, 0x63, 0xC7, 0x79, 0xDC, 0x08, 0x7B, 0xD5, + 0xA0, 0xE5, 0xF7, 0x5B, 0x75, 0xAC, 0x80, 0x55, 0x99, 0x92, 0x61, 0x9B, + 0xCD, 0x2A, 0x17, 0x7D, 0xDB, 0x8F, 0xF4, 0xB5, 0x6A, 0xEA, 0x17, 0x4A, + 0x64, 0x28, 0x66, 0x15, 0x29, 0x6C, 0x02, 0xF1, 0x6B, 0xD5, 0xBA, 0xA3, + 0x33, 0xDC, 0x5A, 0x67, 0xA7, 0x05, 0xE2, 0xBF, 0x65, 0xB6, 0x16, 0xB0, + 0x10, 0xED, 0xCD, 0x50, 0x33, 0xC9, 0x70, 0x50, 0xEC, 0x19, 0x8E, 0xB0, + 0xC7, 0xF2, 0x74, 0x5B, 0x6B, 0x44, 0xC6, 0x7D, 0x96, 0xB9, 0x98, 0x08, + 0x59, 0x66, 0xDE, 0x29, 0x01, 0x9B, 0xF4, 0x2A, 0x6D, 0xD3, 0x15, 0x3A, + 0x90, 0x6A, 0x67, 0xF1, 0xB4, 0x6B, 0x66, 0xD9, 0x21, 0xEB, 0xCA, 0xD9, + 0x62, 0x7C, 0x46, 0x10, 0x5C, 0xDE, 0x75, 0x49, 0x67, 0x9E, 0x42, 0xF9, + 0xFE, 0x75, 0xA9, 0xA3, 0xAD, 0xFF, 0x76, 0x0A, 0x67, 0x40, 0xE3, 0xC5, + 0xF7, 0x8D, 0xC7, 0x85, 0x9A, 0x59, 0x9E, 0x62, 0x9A, 0x6A, 0xED, 0x45, + 0x87, 0x98, 0x67, 0xB2, 0xD5, 0x4A, 0x3C, 0xD7, 0xB4, 0x3B, 0x00, 0x0D, + 0xC0, 0x8F, 0x1F, 0xE1, 0x40, 0xC4, 0xAE, 0x6C, 0x21, 0xDC, 0x49, 0x7E, + 0x7E, 0xCA, 0xB2, 0x8D, 0x6D, 0xB6, 0xBF, 0x93, 0x2F, 0xA1, 0x5C, 0x3E, + 0x8F, 0xCA, 0xED, 0x80, 0x8E, 0x58, 0xE1, 0xDB, 0x57, 0xCF, 0x85, 0x36, + 0x38, 0xB2, 0x71, 0xA4, 0x09, 0x8C, 0x92, 0x89, 0x08, 0x88, 0x48, 0xF1, + 0x40, 0x63, 0x18, 0xB2, 0x5B, 0x8C, 0x5A, 0xE3, 0xC3, 0xD3, 0x17, 0xAA, + 0xAB, 0x19, 0xA3, 0x2C, 0x1B, 0xE4, 0xD5, 0xC6, 0xE2, 0x66, 0x7A, 0xD7, + 0x82, 0x19, 0xA6, 0x3B, 0x16, 0x2C, 0x2F, 0x71, 0x87, 0x5F, 0x45, 0x9E, + 0x95, 0x73, 0x93, 0xC2, 0x42, 0x81, 0x21, 0x13, 0x96, 0xD7, 0x9D, 0xBB, + 0x93, 0x68, 0x15, 0xFA, 0x9D, 0xA4, 0x1D, 0x8C, 0xF2, 0x81, 0xE0, 0x58, + 0x06, 0xBD, 0xC9, 0xB6, 0xE3, 0xF6, 0x89, 0x5D, 0x89, 0xF9, 0xAC, 0x44, + 0xA1, 0xCB, 0x6B, 0xFA, 0x16, 0xF1, 0xC7, 0x50, 0x3D, 0x24, 0xDA, 0xF7, + 0xC3, 0xE4, 0x87, 0xD5, 0x56, 0xF1, 0x4F, 0x90, 0x30, 0xFA, 0x45, 0x09, + 0x59, 0xDA, 0x34, 0xCE, 0xE0, 0x13, 0x1C, 0x04, 0x7C, 0x00, 0xD4, 0x9B, + 0x86, 0xA4, 0x40, 0xBC, 0xD9, 0xDC, 0x4C, 0x57, 0x7E, 0xAE, 0xB7, 0x33, + 0xB6, 0x5E, 0x76, 0xE1, 0x65, 0x8B, 0x66, 0xDF, 0x8D, 0xCA, 0xD7, 0x98, + 0xAF, 0xCE, 0x36, 0x98, 0x8C, 0x9C, 0x83, 0x99, 0x03, 0x70, 0xF3, 0xAF, + 0x74, 0xED, 0xC6, 0x0E, 0x36, 0xE7, 0xBD, 0xEC, 0xC1, 0x73, 0xA7, 0x94, + 0x5A, 0xCB, 0x92, 0x64, 0x82, 0xA6, 0x00, 0xC1, 0x70, 0xA1, 0x6E, 0x2C, + 0x29, 0xE1, 0x58, 0x57, 0xEC, 0x5A, 0x7C, 0x99, 0x6B, 0x25, 0xA4, 0x90, + 0x3A, 0x80, 0xF4, 0x20, 0x9D, 0x9A, 0xCE, 0xC7, 0x2D, 0xF9, 0xB2, 0x4B, + 0x29, 0x95, 0x83, 0xE9, 0x35, 0x8D, 0xA7, 0x49, 0x48, 0xA7, 0x0F, 0x4C, + 0x19, 0x91, 0xD0, 0xF5, 0xBF, 0x10, 0xE0, 0x71 +}; + +static const unsigned char TA205_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA206_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x39, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, 0x20, + 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x63, 0x69, 0x6F, 0x6E, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, + 0x6F, 0x66, 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x43, 0x49, + 0x46, 0x20, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38 +}; + +static const unsigned char TA206_RSA_N[] = { + 0xCA, 0x96, 0x6B, 0x8E, 0xEA, 0xF8, 0xFB, 0xF1, 0xA2, 0x35, 0xE0, 0x7F, + 0x4C, 0xDA, 0xE0, 0xC3, 0x52, 0xD7, 0x7D, 0xB6, 0x10, 0xC8, 0x02, 0x5E, + 0xB3, 0x43, 0x2A, 0xC4, 0x4F, 0x6A, 0xB2, 0xCA, 0x1C, 0x5D, 0x28, 0x9A, + 0x78, 0x11, 0x1A, 0x69, 0x59, 0x57, 0xAF, 0xB5, 0x20, 0x42, 0xE4, 0x8B, + 0x0F, 0xE6, 0xDF, 0x5B, 0xA6, 0x03, 0x92, 0x2F, 0xF5, 0x11, 0xE4, 0x62, + 0xD7, 0x32, 0x71, 0x38, 0xD9, 0x04, 0x0C, 0x71, 0xAB, 0x3D, 0x51, 0x7E, + 0x0F, 0x07, 0xDF, 0x63, 0x05, 0x5C, 0xE9, 0xBF, 0x94, 0x6F, 0xC1, 0x29, + 0x82, 0xC0, 0xB4, 0xDA, 0x51, 0xB0, 0xC1, 0x3C, 0xBB, 0xAD, 0x37, 0x4A, + 0x5C, 0xCA, 0xF1, 0x4B, 0x36, 0x0E, 0x24, 0xAB, 0xBF, 0xC3, 0x84, 0x77, + 0xFD, 0xA8, 0x50, 0xF4, 0xB1, 0xE7, 0xC6, 0x2F, 0xD2, 0x2D, 0x59, 0x8D, + 0x7A, 0x0A, 0x4E, 0x96, 0x69, 0x52, 0x02, 0xAA, 0x36, 0x98, 0xEC, 0xFC, + 0xFA, 0x14, 0x83, 0x0C, 0x37, 0x1F, 0xC9, 0x92, 0x37, 0x7F, 0xD7, 0x81, + 0x2D, 0xE5, 0xC4, 0xB9, 0xE0, 0x3E, 0x34, 0xFE, 0x67, 0xF4, 0x3E, 0x66, + 0xD1, 0xD3, 0xF4, 0x40, 0xCF, 0x5E, 0x62, 0x34, 0x0F, 0x70, 0x06, 0x3E, + 0x20, 0x18, 0x5A, 0xCE, 0xF7, 0x72, 0x1B, 0x25, 0x6C, 0x93, 0x74, 0x14, + 0x93, 0xA3, 0x73, 0xB1, 0x0E, 0xAA, 0x87, 0x10, 0x23, 0x59, 0x5F, 0x20, + 0x05, 0x19, 0x47, 0xED, 0x68, 0x8E, 0x92, 0x12, 0xCA, 0x5D, 0xFC, 0xD6, + 0x2B, 0xB2, 0x92, 0x3C, 0x20, 0xCF, 0xE1, 0x5F, 0xAF, 0x20, 0xBE, 0xA0, + 0x76, 0x7F, 0x76, 0xE5, 0xEC, 0x1A, 0x86, 0x61, 0x33, 0x3E, 0xE7, 0x7B, + 0xB4, 0x3F, 0xA0, 0x0F, 0x8E, 0xA2, 0xB9, 0x6A, 0x6F, 0xB9, 0x87, 0x26, + 0x6F, 0x41, 0x6C, 0x88, 0xA6, 0x50, 0xFD, 0x6A, 0x63, 0x0B, 0xF5, 0x93, + 0x16, 0x1B, 0x19, 0x8F, 0xB2, 0xED, 0x9B, 0x9B, 0xC9, 0x90, 0xF5, 0x01, + 0x0C, 0xDF, 0x19, 0x3D, 0x0F, 0x3E, 0x38, 0x23, 0xC9, 0x2F, 0x8F, 0x0C, + 0xD1, 0x02, 0xFE, 0x1B, 0x55, 0xD6, 0x4E, 0xD0, 0x8D, 0x3C, 0xAF, 0x4F, + 0xA4, 0xF3, 0xFE, 0xAF, 0x2A, 0xD3, 0x05, 0x9D, 0x79, 0x08, 0xA1, 0xCB, + 0x57, 0x31, 0xB4, 0x9C, 0xC8, 0x90, 0xB2, 0x67, 0xF4, 0x18, 0x16, 0x93, + 0x3A, 0xFC, 0x47, 0xD8, 0xD1, 0x78, 0x96, 0x31, 0x1F, 0xBA, 0x2B, 0x0C, + 0x5F, 0x5D, 0x99, 0xAD, 0x63, 0x89, 0x5A, 0x24, 0x20, 0x76, 0xD8, 0xDF, + 0xFD, 0xAB, 0x4E, 0xA6, 0x22, 0xAA, 0x9D, 0x5E, 0xE6, 0x27, 0x8A, 0x7D, + 0x68, 0x29, 0xA3, 0xE7, 0x8A, 0xB8, 0xDA, 0x11, 0xBB, 0x17, 0x2D, 0x99, + 0x9D, 0x13, 0x24, 0x46, 0xF7, 0xC5, 0xE2, 0xD8, 0x9F, 0x8E, 0x7F, 0xC7, + 0x8F, 0x74, 0x6D, 0x5A, 0xB2, 0xE8, 0x72, 0xF5, 0xAC, 0xEE, 0x24, 0x10, + 0xAD, 0x2F, 0x14, 0xDA, 0xFF, 0x2D, 0x9A, 0x46, 0x71, 0x47, 0xBE, 0x42, + 0xDF, 0xBB, 0x01, 0xDB, 0xF4, 0x7F, 0xD3, 0x28, 0x8F, 0x31, 0x59, 0x5B, + 0xD3, 0xC9, 0x02, 0xA6, 0xB4, 0x52, 0xCA, 0x6E, 0x97, 0xFB, 0x43, 0xC5, + 0x08, 0x26, 0x6F, 0x8A, 0xF4, 0xBB, 0xFD, 0x9F, 0x28, 0xAA, 0x0D, 0xD5, + 0x45, 0xF3, 0x13, 0x3A, 0x1D, 0xD8, 0xC0, 0x78, 0x8F, 0x41, 0x67, 0x3C, + 0x1E, 0x94, 0x64, 0xAE, 0x7B, 0x0B, 0xC5, 0xE8, 0xD9, 0x01, 0x88, 0x39, + 0x1A, 0x97, 0x86, 0x64, 0x41, 0xD5, 0x3B, 0x87, 0x0C, 0x6E, 0xFA, 0x0F, + 0xC6, 0xBD, 0x48, 0x14, 0xBF, 0x39, 0x4D, 0xD4, 0x9E, 0x41, 0xB6, 0x8F, + 0x96, 0x1D, 0x63, 0x96, 0x93, 0xD9, 0x95, 0x06, 0x78, 0x31, 0x68, 0x9E, + 0x37, 0x06, 0x3B, 0x80, 0x89, 0x45, 0x61, 0x39, 0x23, 0xC7, 0x1B, 0x44, + 0xA3, 0x15, 0xE5, 0x1C, 0xF8, 0x92, 0x30, 0xBB +}; + +static const unsigned char TA206_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA207_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x34, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA207_EC_Q[] = { + 0x04, 0xB8, 0xC6, 0x79, 0xD3, 0x8F, 0x6C, 0x25, 0x0E, 0x9F, 0x2E, 0x39, + 0x19, 0x1C, 0x03, 0xA4, 0xAE, 0x9A, 0xE5, 0x39, 0x07, 0x09, 0x16, 0xCA, + 0x63, 0xB1, 0xB9, 0x86, 0xF8, 0x8A, 0x57, 0xC1, 0x57, 0xCE, 0x42, 0xFA, + 0x73, 0xA1, 0xF7, 0x65, 0x42, 0xFF, 0x1E, 0xC1, 0x00, 0xB2, 0x6E, 0x73, + 0x0E, 0xFF, 0xC7, 0x21, 0xE5, 0x18, 0xA4, 0xAA, 0xD9, 0x71, 0x3F, 0xA8, + 0xD4, 0xB9, 0xCE, 0x8C, 0x1D +}; + +static const unsigned char TA208_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x13, 0x54, 0x57, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, + 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA208_RSA_N[] = { + 0xB0, 0x05, 0xDB, 0xC8, 0xEB, 0x8C, 0xC4, 0x6E, 0x8A, 0x21, 0xEF, 0x8E, + 0x4D, 0x9C, 0x71, 0x0A, 0x1F, 0x52, 0x70, 0xED, 0x6D, 0x82, 0x9C, 0x97, + 0xC5, 0xD7, 0x4C, 0x4E, 0x45, 0x49, 0xCB, 0x40, 0x42, 0xB5, 0x12, 0x34, + 0x6C, 0x19, 0xC2, 0x74, 0xA4, 0x31, 0x5F, 0x85, 0x02, 0x97, 0xEC, 0x43, + 0x33, 0x0A, 0x53, 0xD2, 0x9C, 0x8C, 0x8E, 0xB7, 0xB8, 0x79, 0xDB, 0x2B, + 0xD5, 0x6A, 0xF2, 0x8E, 0x66, 0xC4, 0xEE, 0x2B, 0x01, 0x07, 0x92, 0xD4, + 0xB3, 0xD0, 0x02, 0xDF, 0x50, 0xF6, 0x55, 0xAF, 0x66, 0x0E, 0xCB, 0xE0, + 0x47, 0x60, 0x2F, 0x2B, 0x32, 0x39, 0x35, 0x52, 0x3A, 0x28, 0x83, 0xF8, + 0x7B, 0x16, 0xC6, 0x18, 0xB8, 0x62, 0xD6, 0x47, 0x25, 0x91, 0xCE, 0xF0, + 0x19, 0x12, 0x4D, 0xAD, 0x63, 0xF5, 0xD3, 0x3F, 0x75, 0x5F, 0x29, 0xF0, + 0xA1, 0x30, 0x1C, 0x2A, 0xA0, 0x98, 0xA6, 0x15, 0xBD, 0xEE, 0xFD, 0x19, + 0x36, 0xF0, 0xE2, 0x91, 0x43, 0x8F, 0xFA, 0xCA, 0xD6, 0x10, 0x27, 0x49, + 0x4C, 0xEF, 0xDD, 0xC1, 0xF1, 0x85, 0x70, 0x9B, 0xCA, 0xEA, 0xA8, 0x5A, + 0x43, 0xFC, 0x6D, 0x86, 0x6F, 0x73, 0xE9, 0x37, 0x45, 0xA9, 0xF0, 0x36, + 0xC7, 0xCC, 0x88, 0x75, 0x1E, 0xBB, 0x6C, 0x06, 0xFF, 0x9B, 0x6B, 0x3E, + 0x17, 0xEC, 0x61, 0xAA, 0x71, 0x7C, 0xC6, 0x1D, 0xA2, 0xF7, 0x49, 0xE9, + 0x15, 0xB5, 0x3C, 0xD6, 0xA1, 0x61, 0xF5, 0x11, 0xF7, 0x05, 0x6F, 0x1D, + 0xFD, 0x11, 0xBE, 0xD0, 0x30, 0x07, 0xC2, 0x29, 0xB0, 0x09, 0x4E, 0x26, + 0xDC, 0xE3, 0xA2, 0xA8, 0x91, 0x6A, 0x1F, 0xC2, 0x91, 0x45, 0x88, 0x5C, + 0xE5, 0x98, 0xB8, 0x71, 0xA5, 0x15, 0x19, 0xC9, 0x7C, 0x75, 0x11, 0xCC, + 0x70, 0x74, 0x4F, 0x2D, 0x9B, 0x1D, 0x91, 0x44, 0xFD, 0x56, 0x28, 0xA0, + 0xFE, 0xBB, 0x86, 0x6A, 0xC8, 0xFA, 0x5C, 0x0B, 0x58, 0xDC, 0xC6, 0x4B, + 0x76, 0xC8, 0xAB, 0x22, 0xD9, 0x73, 0x0F, 0xA5, 0xF4, 0x5A, 0x02, 0x89, + 0x3F, 0x4F, 0x9E, 0x22, 0x82, 0xEE, 0xA2, 0x74, 0x53, 0x2A, 0x3D, 0x53, + 0x27, 0x69, 0x1D, 0x6C, 0x8E, 0x32, 0x2C, 0x64, 0x00, 0x26, 0x63, 0x61, + 0x36, 0x4E, 0xA3, 0x46, 0xB7, 0x3F, 0x7D, 0xB3, 0x2D, 0xAC, 0x6D, 0x90, + 0xA2, 0x95, 0xA2, 0xCE, 0xCF, 0xDA, 0x82, 0xE7, 0x07, 0x34, 0x19, 0x96, + 0xE9, 0xB8, 0x21, 0xAA, 0x29, 0x7E, 0xA6, 0x38, 0xBE, 0x8E, 0x29, 0x4A, + 0x21, 0x66, 0x79, 0x1F, 0xB3, 0xC3, 0xB5, 0x09, 0x67, 0xDE, 0xD6, 0xD4, + 0x07, 0x46, 0xF3, 0x2A, 0xDA, 0xE6, 0x22, 0x37, 0x60, 0xCB, 0x81, 0xB6, + 0x0F, 0xA0, 0x0F, 0xE9, 0xC8, 0x95, 0x7F, 0xBF, 0x55, 0x91, 0x05, 0x7A, + 0xCF, 0x3D, 0x15, 0xC0, 0x6F, 0xDE, 0x09, 0x94, 0x01, 0x83, 0xD7, 0x34, + 0x1B, 0xCC, 0x40, 0xA5, 0xF0, 0xB8, 0x9B, 0x67, 0xD5, 0x98, 0x91, 0x3B, + 0xA7, 0x84, 0x78, 0x95, 0x26, 0xA4, 0x5A, 0x08, 0xF8, 0x2B, 0x74, 0xB4, + 0x00, 0x04, 0x3C, 0xDF, 0xB8, 0x14, 0x8E, 0xE8, 0xDF, 0xA9, 0x8D, 0x6C, + 0x67, 0x92, 0x33, 0x1D, 0xC0, 0xB7, 0xD2, 0xEC, 0x92, 0xC8, 0xBE, 0x09, + 0xBF, 0x2C, 0x29, 0x05, 0x6F, 0x02, 0x6B, 0x9E, 0xEF, 0xBC, 0xBF, 0x2A, + 0xBC, 0x5B, 0xC0, 0x50, 0x8F, 0x41, 0x70, 0x71, 0x87, 0xB2, 0x4D, 0xB7, + 0x04, 0xA9, 0x84, 0xA3, 0x32, 0xAF, 0xAE, 0xEE, 0x6B, 0x17, 0x8B, 0xB2, + 0xB1, 0xFE, 0x6C, 0xE1, 0x90, 0x8C, 0x88, 0xA8, 0x97, 0x48, 0xCE, 0xC8, + 0x4D, 0xCB, 0xF3, 0x06, 0xCF, 0x5F, 0x6A, 0x0A, 0x42, 0xB1, 0x1E, 0x1E, + 0x77, 0x2F, 0x8E, 0xA0, 0xE6, 0x92, 0x0E, 0x06, 0xFC, 0x05, 0x22, 0xD2, + 0x26, 0xE1, 0x31, 0x51, 0x7D, 0x32, 0xDC, 0x0F +}; + +static const unsigned char TA208_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA209_DN[] = { + 0x30, 0x57, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, + 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA209_RSA_N[] = { + 0xDA, 0x0E, 0xE6, 0x99, 0x8D, 0xCE, 0xA3, 0xE3, 0x4F, 0x8A, 0x7E, 0xFB, + 0xF1, 0x8B, 0x83, 0x25, 0x6B, 0xEA, 0x48, 0x1F, 0xF1, 0x2A, 0xB0, 0xB9, + 0x95, 0x11, 0x04, 0xBD, 0xF0, 0x63, 0xD1, 0xE2, 0x67, 0x66, 0xCF, 0x1C, + 0xDD, 0xCF, 0x1B, 0x48, 0x2B, 0xEE, 0x8D, 0x89, 0x8E, 0x9A, 0xAF, 0x29, + 0x80, 0x65, 0xAB, 0xE9, 0xC7, 0x2D, 0x12, 0xCB, 0xAB, 0x1C, 0x4C, 0x70, + 0x07, 0xA1, 0x3D, 0x0A, 0x30, 0xCD, 0x15, 0x8D, 0x4F, 0xF8, 0xDD, 0xD4, + 0x8C, 0x50, 0x15, 0x1C, 0xEF, 0x50, 0xEE, 0xC4, 0x2E, 0xF7, 0xFC, 0xE9, + 0x52, 0xF2, 0x91, 0x7D, 0xE0, 0x6D, 0xD5, 0x35, 0x30, 0x8E, 0x5E, 0x43, + 0x73, 0xF2, 0x41, 0xE9, 0xD5, 0x6A, 0xE3, 0xB2, 0x89, 0x3A, 0x56, 0x39, + 0x38, 0x6F, 0x06, 0x3C, 0x88, 0x69, 0x5B, 0x2A, 0x4D, 0xC5, 0xA7, 0x54, + 0xB8, 0x6C, 0x89, 0xCC, 0x9B, 0xF9, 0x3C, 0xCA, 0xE5, 0xFD, 0x89, 0xF5, + 0x12, 0x3C, 0x92, 0x78, 0x96, 0xD6, 0xDC, 0x74, 0x6E, 0x93, 0x44, 0x61, + 0xD1, 0x8D, 0xC7, 0x46, 0xB2, 0x75, 0x0E, 0x86, 0xE8, 0x19, 0x8A, 0xD5, + 0x6D, 0x6C, 0xD5, 0x78, 0x16, 0x95, 0xA2, 0xE9, 0xC8, 0x0A, 0x38, 0xEB, + 0xF2, 0x24, 0x13, 0x4F, 0x73, 0x54, 0x93, 0x13, 0x85, 0x3A, 0x1B, 0xBC, + 0x1E, 0x34, 0xB5, 0x8B, 0x05, 0x8C, 0xB9, 0x77, 0x8B, 0xB1, 0xDB, 0x1F, + 0x20, 0x91, 0xAB, 0x09, 0x53, 0x6E, 0x90, 0xCE, 0x7B, 0x37, 0x74, 0xB9, + 0x70, 0x47, 0x91, 0x22, 0x51, 0x63, 0x16, 0x79, 0xAE, 0xB1, 0xAE, 0x41, + 0x26, 0x08, 0xC8, 0x19, 0x2B, 0xD1, 0x46, 0xAA, 0x48, 0xD6, 0x64, 0x2A, + 0xD7, 0x83, 0x34, 0xFF, 0x2C, 0x2A, 0xC1, 0x6C, 0x19, 0x43, 0x4A, 0x07, + 0x85, 0xE7, 0xD3, 0x7C, 0xF6, 0x21, 0x68, 0xEF, 0xEA, 0xF2, 0x52, 0x9F, + 0x7F, 0x93, 0x90, 0xCF +}; + +static const unsigned char TA209_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA210_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA210_RSA_N[] = { + 0xAD, 0x0E, 0x15, 0xCE, 0xE4, 0x43, 0x80, 0x5C, 0xB1, 0x87, 0xF3, 0xB7, + 0x60, 0xF9, 0x71, 0x12, 0xA5, 0xAE, 0xDC, 0x26, 0x94, 0x88, 0xAA, 0xF4, + 0xCE, 0xF5, 0x20, 0x39, 0x28, 0x58, 0x60, 0x0C, 0xF8, 0x80, 0xDA, 0xA9, + 0x15, 0x95, 0x32, 0x61, 0x3C, 0xB5, 0xB1, 0x28, 0x84, 0x8A, 0x8A, 0xDC, + 0x9F, 0x0A, 0x0C, 0x83, 0x17, 0x7A, 0x8F, 0x90, 0xAC, 0x8A, 0xE7, 0x79, + 0x53, 0x5C, 0x31, 0x84, 0x2A, 0xF6, 0x0F, 0x98, 0x32, 0x36, 0x76, 0xCC, + 0xDE, 0xDD, 0x3C, 0xA8, 0xA2, 0xEF, 0x6A, 0xFB, 0x21, 0xF2, 0x52, 0x61, + 0xDF, 0x9F, 0x20, 0xD7, 0x1F, 0xE2, 0xB1, 0xD9, 0xFE, 0x18, 0x64, 0xD2, + 0x12, 0x5B, 0x5F, 0xF9, 0x58, 0x18, 0x35, 0xBC, 0x47, 0xCD, 0xA1, 0x36, + 0xF9, 0x6B, 0x7F, 0xD4, 0xB0, 0x38, 0x3E, 0xC1, 0x1B, 0xC3, 0x8C, 0x33, + 0xD9, 0xD8, 0x2F, 0x18, 0xFE, 0x28, 0x0F, 0xB3, 0xA7, 0x83, 0xD6, 0xC3, + 0x6E, 0x44, 0xC0, 0x61, 0x35, 0x96, 0x16, 0xFE, 0x59, 0x9C, 0x8B, 0x76, + 0x6D, 0xD7, 0xF1, 0xA2, 0x4B, 0x0D, 0x2B, 0xFF, 0x0B, 0x72, 0xDA, 0x9E, + 0x60, 0xD0, 0x8E, 0x90, 0x35, 0xC6, 0x78, 0x55, 0x87, 0x20, 0xA1, 0xCF, + 0xE5, 0x6D, 0x0A, 0xC8, 0x49, 0x7C, 0x31, 0x98, 0x33, 0x6C, 0x22, 0xE9, + 0x87, 0xD0, 0x32, 0x5A, 0xA2, 0xBA, 0x13, 0x82, 0x11, 0xED, 0x39, 0x17, + 0x9D, 0x99, 0x3A, 0x72, 0xA1, 0xE6, 0xFA, 0xA4, 0xD9, 0xD5, 0x17, 0x31, + 0x75, 0xAE, 0x85, 0x7D, 0x22, 0xAE, 0x3F, 0x01, 0x46, 0x86, 0xF6, 0x28, + 0x79, 0xC8, 0xB1, 0xDA, 0xE4, 0x57, 0x17, 0xC4, 0x7E, 0x1C, 0x0E, 0xB0, + 0xB4, 0x92, 0xA6, 0x56, 0xB3, 0xBD, 0xB2, 0x97, 0xED, 0xAA, 0xA7, 0xF0, + 0xB7, 0xC5, 0xA8, 0x3F, 0x95, 0x16, 0xD0, 0xFF, 0xA1, 0x96, 0xEB, 0x08, + 0x5F, 0x18, 0x77, 0x4F +}; + +static const unsigned char TA210_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA211_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA211_EC_Q[] = { + 0x04, 0xC6, 0xCB, 0xC7, 0x28, 0xD1, 0xFB, 0x84, 0xF5, 0x9A, 0xEF, 0x42, + 0x14, 0x20, 0xE1, 0x43, 0x6B, 0x6E, 0x75, 0xAD, 0xFC, 0x2B, 0x03, 0x84, + 0xD4, 0x76, 0x93, 0x25, 0xD7, 0x59, 0x3B, 0x41, 0x65, 0x6B, 0x1E, 0xE6, + 0x34, 0x2A, 0xBB, 0x74, 0xF6, 0x12, 0xCE, 0xE8, 0x6D, 0xE7, 0xAB, 0xE4, + 0x3C, 0x4E, 0x3F, 0x44, 0x08, 0x8B, 0xCD, 0x16, 0x71, 0xCB, 0xBF, 0x92, + 0x99, 0xF4, 0xA4, 0xD7, 0x3C, 0x50, 0x54, 0x52, 0x90, 0x85, 0x83, 0x78, + 0x94, 0x67, 0x67, 0xA3, 0x1C, 0x09, 0x19, 0x3D, 0x75, 0x34, 0x85, 0xDE, + 0xED, 0x60, 0x7D, 0xC7, 0x0C, 0xB4, 0x41, 0x52, 0xB9, 0x6E, 0xE5, 0xEE, + 0x42 +}; + +static const unsigned char TA212_DN[] = { + 0x30, 0x81, 0xBF, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x33, 0x30, + 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x45, + 0x43, 0x31 +}; + +static const unsigned char TA212_EC_Q[] = { + 0x04, 0x84, 0x13, 0xC9, 0xD0, 0xBA, 0x6D, 0x41, 0x7B, 0xE2, 0x6C, 0xD0, + 0xEB, 0x55, 0x5F, 0x66, 0x02, 0x1A, 0x24, 0xF4, 0x5B, 0x89, 0x69, 0x47, + 0xE3, 0xB8, 0xC2, 0x7D, 0xF1, 0xF2, 0x02, 0xC5, 0x9F, 0xA0, 0xF6, 0x5B, + 0xD5, 0x8B, 0x06, 0x19, 0x86, 0x4F, 0x53, 0x10, 0x6D, 0x07, 0x24, 0x27, + 0xA1, 0xA0, 0xF8, 0xD5, 0x47, 0x19, 0x61, 0x4C, 0x7D, 0xCA, 0x93, 0x27, + 0xEA, 0x74, 0x0C, 0xEF, 0x6F, 0x96, 0x09, 0xFE, 0x63, 0xEC, 0x70, 0x5D, + 0x36, 0xAD, 0x67, 0x77, 0xAE, 0xC9, 0x9D, 0x7C, 0x55, 0x44, 0x3A, 0xA2, + 0x63, 0x51, 0x1F, 0xF5, 0xE3, 0x62, 0xD4, 0xA9, 0x47, 0x07, 0x3E, 0xCC, + 0x20 +}; + +static const unsigned char TA213_DN[] = { + 0x30, 0x81, 0x84, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x05, + 0x13, 0x09, 0x47, 0x36, 0x33, 0x32, 0x38, 0x37, 0x35, 0x31, 0x30, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, + 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1E, 0x41, + 0x4E, 0x46, 0x20, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, + 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x63, 0x69, 0x6F, 0x6E, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x13, 0x0B, 0x41, 0x4E, 0x46, 0x20, 0x43, 0x41, 0x20, 0x52, + 0x61, 0x69, 0x7A, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x19, 0x41, 0x4E, 0x46, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA213_RSA_N[] = { + 0xDB, 0xEB, 0x6B, 0x2B, 0xE6, 0x64, 0x54, 0x95, 0x82, 0x90, 0xA3, 0x72, + 0xA4, 0x19, 0x01, 0x9D, 0x9C, 0x0B, 0x81, 0x5F, 0x73, 0x49, 0xBA, 0xA7, + 0xAC, 0xF3, 0x04, 0x4E, 0x7B, 0x96, 0x0B, 0xEC, 0x11, 0xE0, 0x5B, 0xA6, + 0x1C, 0xCE, 0x1B, 0xD2, 0x0D, 0x83, 0x1C, 0x2B, 0xB8, 0x9E, 0x1D, 0x7E, + 0x45, 0x32, 0x60, 0x0F, 0x07, 0xE9, 0x77, 0x58, 0x7E, 0x9F, 0x6A, 0xC8, + 0x61, 0x4E, 0xB6, 0x26, 0xC1, 0x4C, 0x8D, 0xFF, 0x4C, 0xEF, 0x34, 0xB2, + 0x1F, 0x65, 0xD8, 0xB9, 0x78, 0xF5, 0xAD, 0xA9, 0x71, 0xB9, 0xEF, 0x4F, + 0x58, 0x1D, 0xA5, 0xDE, 0x74, 0x20, 0x97, 0xA1, 0xED, 0x68, 0x4C, 0xDE, + 0x92, 0x17, 0x4B, 0xBC, 0xAB, 0xFF, 0x65, 0x9A, 0x9E, 0xFB, 0x47, 0xD9, + 0x57, 0x72, 0xF3, 0x09, 0xA1, 0xAE, 0x76, 0x44, 0x13, 0x6E, 0x9C, 0x2D, + 0x44, 0x39, 0xBC, 0xF9, 0xC7, 0x3B, 0xA4, 0x58, 0x3D, 0x41, 0xBD, 0xB4, + 0xC2, 0x49, 0xA3, 0xC8, 0x0D, 0xD2, 0x97, 0x2F, 0x07, 0x65, 0x52, 0x00, + 0xA7, 0x6E, 0xC8, 0xAF, 0x68, 0xEC, 0xF4, 0x14, 0x96, 0xB6, 0x57, 0x1F, + 0x56, 0xC3, 0x39, 0x9F, 0x2B, 0x6D, 0xE4, 0xF3, 0x3E, 0xF6, 0x35, 0x64, + 0xDA, 0x0C, 0x1C, 0xA1, 0x84, 0x4B, 0x2F, 0x4B, 0x4B, 0xE2, 0x2C, 0x24, + 0x9D, 0x6D, 0x93, 0x40, 0xEB, 0xB5, 0x23, 0x8E, 0x32, 0xCA, 0x6F, 0x45, + 0xD3, 0xA8, 0x89, 0x7B, 0x1E, 0xCF, 0x1E, 0xFA, 0x5B, 0x43, 0x8B, 0xCD, + 0xCD, 0xA8, 0x0F, 0x6A, 0xCA, 0x0C, 0x5E, 0xB9, 0x9E, 0x47, 0x8F, 0xF0, + 0xD9, 0xB6, 0x0A, 0x0B, 0x58, 0x65, 0x17, 0x33, 0xB9, 0x23, 0xE4, 0x77, + 0x19, 0x7D, 0xCB, 0x4A, 0x2E, 0x92, 0x7B, 0x4F, 0x2F, 0x10, 0x77, 0xB1, + 0x8D, 0x2F, 0x68, 0x9C, 0x62, 0xCC, 0xE0, 0x50, 0xF8, 0xEC, 0x91, 0xA7, + 0x54, 0x4C, 0x57, 0x09, 0xD5, 0x76, 0x63, 0xC5, 0xE8, 0x65, 0x1E, 0xEE, + 0x6D, 0x6A, 0xCF, 0x09, 0x9D, 0xFA, 0x7C, 0x4F, 0xAD, 0x60, 0x08, 0xFD, + 0x56, 0x99, 0x0F, 0x15, 0x2C, 0x7B, 0xA9, 0x80, 0xAB, 0x8C, 0x61, 0x8F, + 0x4A, 0x07, 0x76, 0x42, 0xDE, 0x3D, 0xF4, 0xDD, 0xB2, 0x24, 0x33, 0x5B, + 0xB8, 0xB5, 0xA3, 0x44, 0xC9, 0xAC, 0x7F, 0x77, 0x3C, 0x1D, 0x23, 0xEC, + 0x82, 0xA9, 0xA6, 0xE2, 0xC8, 0x06, 0x4C, 0x02, 0xFE, 0xAC, 0x5C, 0x99, + 0x99, 0x0B, 0x2F, 0x10, 0x8A, 0xA6, 0xF4, 0x7F, 0xD5, 0x87, 0x74, 0x0D, + 0x59, 0x49, 0x45, 0xF6, 0xF0, 0x71, 0x5C, 0x39, 0x29, 0xD6, 0xBF, 0x4A, + 0x23, 0x8B, 0xF5, 0x5F, 0x01, 0x63, 0xD2, 0x87, 0x73, 0x28, 0xB5, 0x4B, + 0x0A, 0xF5, 0xF8, 0xAB, 0x82, 0x2C, 0x7E, 0x73, 0x25, 0x32, 0x1D, 0x0B, + 0x63, 0x0A, 0x17, 0x81, 0x00, 0xFF, 0xB6, 0x76, 0x5E, 0xE7, 0xB4, 0xB1, + 0x40, 0xCA, 0x21, 0xBB, 0xD5, 0x80, 0x51, 0xE5, 0x48, 0x52, 0x67, 0x2C, + 0xD2, 0x61, 0x89, 0x07, 0x0D, 0x0F, 0xCE, 0x42, 0x77, 0xC0, 0x44, 0x73, + 0x9C, 0x44, 0x50, 0xA0, 0xDB, 0x10, 0x0A, 0x2D, 0x95, 0x1C, 0x81, 0xAF, + 0xE4, 0x1C, 0xE5, 0x14, 0x1E, 0xF1, 0x36, 0x41, 0x01, 0x02, 0x2F, 0x7D, + 0x73, 0xA7, 0xDE, 0x42, 0xCC, 0x4C, 0xE9, 0x89, 0x0D, 0x56, 0xF7, 0x9F, + 0x91, 0xD4, 0x03, 0xC6, 0x6C, 0xC9, 0x8F, 0xDB, 0xD8, 0x1C, 0xE0, 0x40, + 0x98, 0x5D, 0x66, 0x99, 0x98, 0x80, 0x6E, 0x2D, 0xFF, 0x01, 0xC5, 0xCE, + 0xCB, 0x46, 0x1F, 0xAC, 0x02, 0xC6, 0x43, 0xE6, 0xAE, 0xA2, 0x84, 0x3C, + 0xC5, 0x4E, 0x1E, 0x3D, 0x6D, 0xC9, 0x14, 0x4C, 0xE3, 0x2E, 0x41, 0xBB, + 0xCA, 0x39, 0xBF, 0x36, 0x3C, 0x2A, 0x19, 0xAA, 0x41, 0x87, 0x4E, 0xA5, + 0xCE, 0x4B, 0x32, 0x79, 0xDD, 0x90, 0x49, 0x7F +}; + +static const unsigned char TA213_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA214_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA214_RSA_N[] = { + 0xAF, 0x35, 0x2E, 0xD8, 0xAC, 0x6C, 0x55, 0x69, 0x06, 0x71, 0xE5, 0x13, + 0x68, 0x24, 0xB3, 0x4F, 0xD8, 0xCC, 0x21, 0x47, 0xF8, 0xF1, 0x60, 0x38, + 0x89, 0x89, 0x03, 0xE9, 0xBD, 0xEA, 0x5E, 0x46, 0x53, 0x09, 0xDC, 0x5C, + 0xF5, 0x5A, 0xE8, 0xF7, 0x45, 0x2A, 0x02, 0xEB, 0x31, 0x61, 0xD7, 0x29, + 0x33, 0x4C, 0xCE, 0xC7, 0x7C, 0x0A, 0x37, 0x7E, 0x0F, 0xBA, 0x32, 0x98, + 0xE1, 0x1D, 0x97, 0xAF, 0x8F, 0xC7, 0xDC, 0xC9, 0x38, 0x96, 0xF3, 0xDB, + 0x1A, 0xFC, 0x51, 0xED, 0x68, 0xC6, 0xD0, 0x6E, 0xA4, 0x7C, 0x24, 0xD1, + 0xAE, 0x42, 0xC8, 0x96, 0x50, 0x63, 0x2E, 0xE0, 0xFE, 0x75, 0xFE, 0x98, + 0xA7, 0x5F, 0x49, 0x2E, 0x95, 0xE3, 0x39, 0x33, 0x64, 0x8E, 0x1E, 0xA4, + 0x5F, 0x90, 0xD2, 0x67, 0x3C, 0xB2, 0xD9, 0xFE, 0x41, 0xB9, 0x55, 0xA7, + 0x09, 0x8E, 0x72, 0x05, 0x1E, 0x8B, 0xDD, 0x44, 0x85, 0x82, 0x42, 0xD0, + 0x49, 0xC0, 0x1D, 0x60, 0xF0, 0xD1, 0x17, 0x2C, 0x95, 0xEB, 0xF6, 0xA5, + 0xC1, 0x92, 0xA3, 0xC5, 0xC2, 0xA7, 0x08, 0x60, 0x0D, 0x60, 0x04, 0x10, + 0x96, 0x79, 0x9E, 0x16, 0x34, 0xE6, 0xA9, 0xB6, 0xFA, 0x25, 0x45, 0x39, + 0xC8, 0x1E, 0x65, 0xF9, 0x93, 0xF5, 0xAA, 0xF1, 0x52, 0xDC, 0x99, 0x98, + 0x3D, 0xA5, 0x86, 0x1A, 0x0C, 0x35, 0x33, 0xFA, 0x4B, 0xA5, 0x04, 0x06, + 0x15, 0x1C, 0x31, 0x80, 0xEF, 0xAA, 0x18, 0x6B, 0xC2, 0x7B, 0xD7, 0xDA, + 0xCE, 0xF9, 0x33, 0x20, 0xD5, 0xF5, 0xBD, 0x6A, 0x33, 0x2D, 0x81, 0x04, + 0xFB, 0xB0, 0x5C, 0xD4, 0x9C, 0xA3, 0xE2, 0x5C, 0x1D, 0xE3, 0xA9, 0x42, + 0x75, 0x5E, 0x7B, 0xD4, 0x77, 0xEF, 0x39, 0x54, 0xBA, 0xC9, 0x0A, 0x18, + 0x1B, 0x12, 0x99, 0x49, 0x2F, 0x88, 0x4B, 0xFD, 0x50, 0x62, 0xD1, 0x73, + 0xE7, 0x8F, 0x7A, 0x43 +}; + +static const unsigned char TA214_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA215_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x13, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D +}; + +static const unsigned char TA215_RSA_N[] = { + 0xC4, 0x12, 0xDF, 0xA9, 0x5F, 0xFE, 0x41, 0xDD, 0xDD, 0xF5, 0x9F, 0x8A, + 0xE3, 0xF6, 0xAC, 0xE1, 0x3C, 0x78, 0x9A, 0xBC, 0xD8, 0xF0, 0x7F, 0x7A, + 0xA0, 0x33, 0x2A, 0xDC, 0x8D, 0x20, 0x5B, 0xAE, 0x2D, 0x6F, 0xE7, 0x93, + 0xD9, 0x36, 0x70, 0x6A, 0x68, 0xCF, 0x8E, 0x51, 0xA3, 0x85, 0x5B, 0x67, + 0x04, 0xA0, 0x10, 0x24, 0x6F, 0x5D, 0x28, 0x82, 0xC1, 0x97, 0x57, 0xD8, + 0x48, 0x29, 0x13, 0xB6, 0xE1, 0xBE, 0x91, 0x4D, 0xDF, 0x85, 0x0C, 0x53, + 0x18, 0x9A, 0x1E, 0x24, 0xA2, 0x4F, 0x8F, 0xF0, 0xA2, 0x85, 0x0B, 0xCB, + 0xF4, 0x29, 0x7F, 0xD2, 0xA4, 0x58, 0xEE, 0x26, 0x4D, 0xC9, 0xAA, 0xA8, + 0x7B, 0x9A, 0xD9, 0xFA, 0x38, 0xDE, 0x44, 0x57, 0x15, 0xE5, 0xF8, 0x8C, + 0xC8, 0xD9, 0x48, 0xE2, 0x0D, 0x16, 0x27, 0x1D, 0x1E, 0xC8, 0x83, 0x85, + 0x25, 0xB7, 0xBA, 0xAA, 0x55, 0x41, 0xCC, 0x03, 0x22, 0x4B, 0x2D, 0x91, + 0x8D, 0x8B, 0xE6, 0x89, 0xAF, 0x66, 0xC7, 0xE9, 0xFF, 0x2B, 0xE9, 0x3C, + 0xAC, 0xDA, 0xD2, 0xB3, 0xC3, 0xE1, 0x68, 0x9C, 0x89, 0xF8, 0x7A, 0x00, + 0x56, 0xDE, 0xF4, 0x55, 0x95, 0x6C, 0xFB, 0xBA, 0x64, 0xDD, 0x62, 0x8B, + 0xDF, 0x0B, 0x77, 0x32, 0xEB, 0x62, 0xCC, 0x26, 0x9A, 0x9B, 0xBB, 0xAA, + 0x62, 0x83, 0x4C, 0xB4, 0x06, 0x7A, 0x30, 0xC8, 0x29, 0xBF, 0xED, 0x06, + 0x4D, 0x97, 0xB9, 0x1C, 0xC4, 0x31, 0x2B, 0xD5, 0x5F, 0xBC, 0x53, 0x12, + 0x17, 0x9C, 0x99, 0x57, 0x29, 0x66, 0x77, 0x61, 0x21, 0x31, 0x07, 0x2E, + 0x25, 0x49, 0x9D, 0x18, 0xF2, 0xEE, 0xF3, 0x2B, 0x71, 0x8C, 0xB5, 0xBA, + 0x39, 0x07, 0x49, 0x77, 0xFC, 0xEF, 0x2E, 0x92, 0x90, 0x05, 0x8D, 0x2D, + 0x2F, 0x77, 0x7B, 0xEF, 0x43, 0xBF, 0x35, 0xBB, 0x9A, 0xD8, 0xF9, 0x73, + 0xA7, 0x2C, 0xF2, 0xD0, 0x57, 0xEE, 0x28, 0x4E, 0x26, 0x5F, 0x8F, 0x90, + 0x68, 0x09, 0x2F, 0xB8, 0xF8, 0xDC, 0x06, 0xE9, 0x2E, 0x9A, 0x3E, 0x51, + 0xA7, 0xD1, 0x22, 0xC4, 0x0A, 0xA7, 0x38, 0x48, 0x6C, 0xB3, 0xF9, 0xFF, + 0x7D, 0xAB, 0x86, 0x57, 0xE3, 0xBA, 0xD6, 0x85, 0x78, 0x77, 0xBA, 0x43, + 0xEA, 0x48, 0x7F, 0xF6, 0xD8, 0xBE, 0x23, 0x6D, 0x1E, 0xBF, 0xD1, 0x36, + 0x6C, 0x58, 0x5C, 0xF1, 0xEE, 0xA4, 0x19, 0x54, 0x1A, 0xF5, 0x03, 0xD2, + 0x76, 0xE6, 0xE1, 0x8C, 0xBD, 0x3C, 0xB3, 0xD3, 0x48, 0x4B, 0xE2, 0xC8, + 0xF8, 0x7F, 0x92, 0xA8, 0x76, 0x46, 0x9C, 0x42, 0x65, 0x3E, 0xA4, 0x1E, + 0xC1, 0x07, 0x03, 0x5A, 0x46, 0x2D, 0xB8, 0x97, 0xF3, 0xB7, 0xD5, 0xB2, + 0x55, 0x21, 0xEF, 0xBA, 0xDC, 0x4C, 0x00, 0x97, 0xFB, 0x14, 0x95, 0x27, + 0x33, 0xBF, 0xE8, 0x43, 0x47, 0x46, 0xD2, 0x08, 0x99, 0x16, 0x60, 0x3B, + 0x9A, 0x7E, 0xD2, 0xE6, 0xED, 0x38, 0xEA, 0xEC, 0x01, 0x1E, 0x3C, 0x48, + 0x56, 0x49, 0x09, 0xC7, 0x4C, 0x37, 0x00, 0x9E, 0x88, 0x0E, 0xC0, 0x73, + 0xE1, 0x6F, 0x66, 0xE9, 0x72, 0x47, 0x30, 0x3E, 0x10, 0xE5, 0x0B, 0x03, + 0xC9, 0x9A, 0x42, 0x00, 0x6C, 0xC5, 0x94, 0x7E, 0x61, 0xC4, 0x8A, 0xDF, + 0x7F, 0x82, 0x1A, 0x0B, 0x59, 0xC4, 0x59, 0x32, 0x77, 0xB3, 0xBC, 0x60, + 0x69, 0x56, 0x39, 0xFD, 0xB4, 0x06, 0x7B, 0x2C, 0xD6, 0x64, 0x36, 0xD9, + 0xBD, 0x48, 0xED, 0x84, 0x1F, 0x7E, 0xA5, 0x22, 0x8F, 0x2A, 0xB8, 0x42, + 0xF4, 0x82, 0xB7, 0xD4, 0x53, 0x90, 0x78, 0x4E, 0x2D, 0x1A, 0xFD, 0x81, + 0x6F, 0x44, 0xD7, 0x3B, 0x01, 0x74, 0x96, 0x42, 0xE0, 0x00, 0xE2, 0x2E, + 0x6B, 0xEA, 0xC5, 0xEE, 0x72, 0xAC, 0xBB, 0xBF, 0xFE, 0xEA, 0xAA, 0xA8, + 0xF8, 0xDC, 0xF6, 0xB2, 0x79, 0x8A, 0xB6, 0x67 +}; + +static const unsigned char TA215_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA216_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x17, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, + 0x33 +}; + +static const unsigned char TA216_EC_Q[] = { + 0x04, 0x23, 0xA5, 0x0C, 0xB8, 0x2D, 0x12, 0xF5, 0x28, 0xF3, 0xB1, 0xB2, + 0xDD, 0xE2, 0x02, 0x12, 0x80, 0x9E, 0x39, 0x5F, 0x49, 0x4D, 0x9F, 0xC9, + 0x25, 0x34, 0x59, 0x74, 0xEC, 0xBB, 0x06, 0x1C, 0xE7, 0xC0, 0x72, 0xAF, + 0xE8, 0xAE, 0x2F, 0xE1, 0x41, 0x54, 0x87, 0x14, 0xA8, 0x4A, 0xB2, 0xE8, + 0x7C, 0x82, 0xE6, 0x5B, 0x6A, 0xB5, 0xDC, 0xB3, 0x75, 0xCE, 0x8B, 0x06, + 0xD0, 0x86, 0x23, 0xBF, 0x46, 0xD5, 0x8E, 0x0F, 0x3F, 0x04, 0xF4, 0xD7, + 0x1C, 0x92, 0x7E, 0xF6, 0xA5, 0x63, 0xC2, 0xF5, 0x5F, 0x8E, 0x2E, 0x4F, + 0xA1, 0x18, 0x19, 0x02, 0x2B, 0x32, 0x0A, 0x82, 0x64, 0x7D, 0x16, 0x93, + 0xD1 +}; + +static const unsigned char TA217_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x21, 0x54, 0x57, 0x43, 0x41, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA217_RSA_N[] = { + 0xB0, 0x7E, 0x72, 0xB8, 0xA4, 0x03, 0x94, 0xE6, 0xA7, 0xDE, 0x09, 0x38, + 0x91, 0x4A, 0x11, 0x40, 0x87, 0xA7, 0x7C, 0x59, 0x64, 0x14, 0x7B, 0xB5, + 0x11, 0x10, 0xDD, 0xFE, 0xBF, 0xD5, 0xC0, 0xBB, 0x56, 0xE2, 0x85, 0x25, + 0xF4, 0x35, 0x72, 0x0F, 0xF8, 0x53, 0xD0, 0x41, 0xE1, 0x44, 0x01, 0xC2, + 0xB4, 0x1C, 0xC3, 0x31, 0x42, 0x16, 0x47, 0x85, 0x33, 0x22, 0x76, 0xB2, + 0x0A, 0x6F, 0x0F, 0xE5, 0x25, 0x50, 0x4F, 0x85, 0x86, 0xBE, 0xBF, 0x98, + 0x2E, 0x10, 0x67, 0x1E, 0xBE, 0x11, 0x05, 0x86, 0x05, 0x90, 0xC4, 0x59, + 0xD0, 0x7C, 0x78, 0x10, 0xB0, 0x80, 0x5C, 0xB7, 0xE1, 0xC7, 0x2B, 0x75, + 0xCB, 0x7C, 0x9F, 0xAE, 0xB5, 0xD1, 0x9D, 0x23, 0x37, 0x63, 0xA7, 0xDC, + 0x42, 0xA2, 0x2D, 0x92, 0x04, 0x1B, 0x50, 0xC1, 0x7B, 0xB8, 0x3E, 0x1B, + 0xC9, 0x56, 0x04, 0x8B, 0x2F, 0x52, 0x9B, 0xAD, 0xA9, 0x56, 0xE9, 0xC1, + 0xFF, 0xAD, 0xA9, 0x58, 0x87, 0x30, 0xB6, 0x81, 0xF7, 0x97, 0x45, 0xFC, + 0x19, 0x57, 0x3B, 0x2B, 0x6F, 0xE4, 0x47, 0xF4, 0x99, 0x45, 0xFE, 0x1D, + 0xF1, 0xF8, 0x97, 0xA3, 0x88, 0x1D, 0x37, 0x1C, 0x5C, 0x8F, 0xE0, 0x76, + 0x25, 0x9A, 0x50, 0xF8, 0xA0, 0x54, 0xFF, 0x44, 0x90, 0x76, 0x23, 0xD2, + 0x32, 0xC6, 0xC3, 0xAB, 0x06, 0xBF, 0xFC, 0xFB, 0xBF, 0xF3, 0xAD, 0x7D, + 0x92, 0x62, 0x02, 0x5B, 0x29, 0xD3, 0x35, 0xA3, 0x93, 0x9A, 0x43, 0x64, + 0x60, 0x5D, 0xB2, 0xFA, 0x32, 0xFF, 0x3B, 0x04, 0xAF, 0x4D, 0x40, 0x6A, + 0xF9, 0xC7, 0xE3, 0xEF, 0x23, 0xFD, 0x6B, 0xCB, 0xE5, 0x0F, 0x8B, 0x38, + 0x0D, 0xEE, 0x0A, 0xFC, 0xFE, 0x0F, 0x98, 0x9F, 0x30, 0x31, 0xDD, 0x6C, + 0x52, 0x65, 0xF9, 0x8B, 0x81, 0xBE, 0x22, 0xE1, 0x1C, 0x58, 0x03, 0xBA, + 0x91, 0x1B, 0x89, 0x07 +}; + +static const unsigned char TA217_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA218_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x21, 0x54, 0x57, 0x43, 0x41, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA218_RSA_N[] = { + 0xB0, 0x7E, 0x72, 0xB8, 0xA4, 0x03, 0x94, 0xE6, 0xA7, 0xDE, 0x09, 0x38, + 0x91, 0x4A, 0x11, 0x40, 0x87, 0xA7, 0x7C, 0x59, 0x64, 0x14, 0x7B, 0xB5, + 0x11, 0x10, 0xDD, 0xFE, 0xBF, 0xD5, 0xC0, 0xBB, 0x56, 0xE2, 0x85, 0x25, + 0xF4, 0x35, 0x72, 0x0F, 0xF8, 0x53, 0xD0, 0x41, 0xE1, 0x44, 0x01, 0xC2, + 0xB4, 0x1C, 0xC3, 0x31, 0x42, 0x16, 0x47, 0x85, 0x33, 0x22, 0x76, 0xB2, + 0x0A, 0x6F, 0x0F, 0xE5, 0x25, 0x50, 0x4F, 0x85, 0x86, 0xBE, 0xBF, 0x98, + 0x2E, 0x10, 0x67, 0x1E, 0xBE, 0x11, 0x05, 0x86, 0x05, 0x90, 0xC4, 0x59, + 0xD0, 0x7C, 0x78, 0x10, 0xB0, 0x80, 0x5C, 0xB7, 0xE1, 0xC7, 0x2B, 0x75, + 0xCB, 0x7C, 0x9F, 0xAE, 0xB5, 0xD1, 0x9D, 0x23, 0x37, 0x63, 0xA7, 0xDC, + 0x42, 0xA2, 0x2D, 0x92, 0x04, 0x1B, 0x50, 0xC1, 0x7B, 0xB8, 0x3E, 0x1B, + 0xC9, 0x56, 0x04, 0x8B, 0x2F, 0x52, 0x9B, 0xAD, 0xA9, 0x56, 0xE9, 0xC1, + 0xFF, 0xAD, 0xA9, 0x58, 0x87, 0x30, 0xB6, 0x81, 0xF7, 0x97, 0x45, 0xFC, + 0x19, 0x57, 0x3B, 0x2B, 0x6F, 0xE4, 0x47, 0xF4, 0x99, 0x45, 0xFE, 0x1D, + 0xF1, 0xF8, 0x97, 0xA3, 0x88, 0x1D, 0x37, 0x1C, 0x5C, 0x8F, 0xE0, 0x76, + 0x25, 0x9A, 0x50, 0xF8, 0xA0, 0x54, 0xFF, 0x44, 0x90, 0x76, 0x23, 0xD2, + 0x32, 0xC6, 0xC3, 0xAB, 0x06, 0xBF, 0xFC, 0xFB, 0xBF, 0xF3, 0xAD, 0x7D, + 0x92, 0x62, 0x02, 0x5B, 0x29, 0xD3, 0x35, 0xA3, 0x93, 0x9A, 0x43, 0x64, + 0x60, 0x5D, 0xB2, 0xFA, 0x32, 0xFF, 0x3B, 0x04, 0xAF, 0x4D, 0x40, 0x6A, + 0xF9, 0xC7, 0xE3, 0xEF, 0x23, 0xFD, 0x6B, 0xCB, 0xE5, 0x0F, 0x8B, 0x38, + 0x0D, 0xEE, 0x0A, 0xFC, 0xFE, 0x0F, 0x98, 0x9F, 0x30, 0x31, 0xDD, 0x6C, + 0x52, 0x65, 0xF9, 0x8B, 0x81, 0xBE, 0x22, 0xE1, 0x1C, 0x58, 0x03, 0xBA, + 0x91, 0x1B, 0x89, 0x07 +}; + +static const unsigned char TA218_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA219_DN[] = { + 0x30, 0x78, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x0E, + 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x05, 0x43, 0x65, 0x72, + 0x65, 0x73, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, + 0x0F, 0x56, 0x41, 0x54, 0x45, 0x53, 0x2D, 0x51, 0x32, 0x38, 0x32, 0x36, + 0x30, 0x30, 0x34, 0x4A, 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x23, 0x41, 0x43, 0x20, 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, + 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x20, 0x53, 0x45, 0x52, 0x56, + 0x49, 0x44, 0x4F, 0x52, 0x45, 0x53, 0x20, 0x53, 0x45, 0x47, 0x55, 0x52, + 0x4F, 0x53 +}; + +static const unsigned char TA219_EC_Q[] = { + 0x04, 0xF6, 0xBA, 0x57, 0x53, 0xC8, 0xCA, 0xAB, 0xDF, 0x36, 0x4A, 0x52, + 0x21, 0xE4, 0x97, 0xD2, 0x83, 0x67, 0x9E, 0xF0, 0x65, 0x51, 0xD0, 0x5E, + 0x87, 0xC7, 0x47, 0xB1, 0x59, 0xF2, 0x57, 0x47, 0x9B, 0x00, 0x02, 0x93, + 0x44, 0x17, 0x69, 0xDB, 0x42, 0xC7, 0xB1, 0xB2, 0x3A, 0x18, 0x0E, 0xB4, + 0x5D, 0x8C, 0xB3, 0x66, 0x5D, 0xA1, 0x34, 0xF9, 0x36, 0x2C, 0x49, 0xDB, + 0xF3, 0x46, 0xFC, 0xB3, 0x44, 0x69, 0x44, 0x13, 0x66, 0xFD, 0xD7, 0xC5, + 0xFD, 0xAF, 0x36, 0x4D, 0xCE, 0x03, 0x4D, 0x07, 0x71, 0xCF, 0xAF, 0x6A, + 0x05, 0xD2, 0xA2, 0x43, 0x5A, 0x0A, 0x52, 0x6F, 0x01, 0x03, 0x4E, 0x8E, + 0x8B +}; + +static const unsigned char TA220_DN[] = { + 0x30, 0x3C, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x15, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x0D, + 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x04, 0x41, 0x74, 0x6F, + 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x44, 0x45 +}; + +static const unsigned char TA220_RSA_N[] = { + 0x95, 0x85, 0x3B, 0x97, 0x6F, 0x2A, 0x3B, 0x2E, 0x3B, 0xCF, 0xA6, 0xF3, + 0x29, 0x35, 0xBE, 0xCF, 0x18, 0xAC, 0x3E, 0xAA, 0xD9, 0xF8, 0x4D, 0xA0, + 0x3E, 0x1A, 0x47, 0xB9, 0xBC, 0x9A, 0xDF, 0xF2, 0xFE, 0xCC, 0x3E, 0x47, + 0xE8, 0x7A, 0x96, 0xC2, 0x24, 0x8E, 0x35, 0xF4, 0xA9, 0x0C, 0xFC, 0x82, + 0xFD, 0x6D, 0xC1, 0x72, 0x62, 0x27, 0xBD, 0xEA, 0x6B, 0xEB, 0xE7, 0x8A, + 0xCC, 0x54, 0x3E, 0x90, 0x50, 0xCF, 0x80, 0xD4, 0x95, 0xFB, 0xE8, 0xB5, + 0x82, 0xD4, 0x14, 0xC5, 0xB6, 0xA9, 0x55, 0x25, 0x57, 0xDB, 0xB1, 0x50, + 0xF6, 0xB0, 0x60, 0x64, 0x59, 0x7A, 0x69, 0xCF, 0x03, 0xB7, 0x6F, 0x0D, + 0xBE, 0xCA, 0x3E, 0x6F, 0x74, 0x72, 0xEA, 0xAA, 0x30, 0x2A, 0x73, 0x62, + 0xBE, 0x49, 0x91, 0x61, 0xC8, 0x11, 0xFE, 0x0E, 0x03, 0x2A, 0xF7, 0x6A, + 0x20, 0xDC, 0x02, 0x15, 0x0D, 0x5E, 0x15, 0x6A, 0xFC, 0xE3, 0x82, 0xC1, + 0xB5, 0xC5, 0x9D, 0x64, 0x09, 0x6C, 0xA3, 0x59, 0x98, 0x07, 0x27, 0xC7, + 0x1B, 0x96, 0x2B, 0x61, 0x74, 0x71, 0x6C, 0x43, 0xF1, 0xF7, 0x35, 0x89, + 0x10, 0xE0, 0x9E, 0xEC, 0x55, 0xA1, 0x37, 0x22, 0xA2, 0x87, 0x04, 0x05, + 0x2C, 0x47, 0x7D, 0xB4, 0x1C, 0xB9, 0x62, 0x29, 0x66, 0x28, 0xCA, 0xB7, + 0xE1, 0x93, 0xF5, 0xA4, 0x94, 0x03, 0x99, 0xB9, 0x70, 0x85, 0xB5, 0xE6, + 0x48, 0xEA, 0x8D, 0x50, 0xFC, 0xD9, 0xDE, 0xCC, 0x6F, 0x07, 0x0E, 0xDD, + 0x0B, 0x72, 0x9D, 0x80, 0x30, 0x16, 0x07, 0x95, 0x3F, 0x28, 0x0E, 0xFD, + 0xC5, 0x75, 0x4F, 0x53, 0xD6, 0x74, 0x9A, 0xB4, 0x24, 0x2E, 0x8E, 0x02, + 0x91, 0xCF, 0x76, 0xC5, 0x9B, 0x1E, 0x55, 0x74, 0x9C, 0x78, 0x21, 0xB1, + 0xF0, 0x2D, 0xF1, 0x0B, 0x9F, 0xC2, 0xD5, 0x96, 0x18, 0x1F, 0xF0, 0x54, + 0x22, 0x7A, 0x8C, 0x07 +}; + +static const unsigned char TA220_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA221_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x54, 0x57, 0x43, 0x41, 0x20, 0x43, 0x59, 0x42, + 0x45, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA221_RSA_N[] = { + 0xC6, 0xF8, 0xCA, 0x1E, 0xD9, 0x09, 0x20, 0x7E, 0x1D, 0x6C, 0x4E, 0xCE, + 0x8F, 0xE3, 0x47, 0x33, 0x44, 0x9C, 0xC7, 0xC9, 0x69, 0xAA, 0x3A, 0x5B, + 0x78, 0xEE, 0x70, 0xD2, 0x92, 0xF8, 0x04, 0xB3, 0x52, 0x52, 0x1D, 0x67, + 0x72, 0x28, 0xA1, 0xDF, 0x8B, 0x5D, 0x95, 0x0A, 0xFE, 0xEA, 0xCD, 0xED, + 0xF7, 0x29, 0xCE, 0xF0, 0x6F, 0x7F, 0xAC, 0xCD, 0x3D, 0xEF, 0xB3, 0x1C, + 0x45, 0x6A, 0xF7, 0x28, 0x90, 0xF1, 0x61, 0x57, 0xC5, 0x0C, 0xC4, 0xA3, + 0x50, 0x5D, 0xDE, 0xD4, 0xB5, 0xCB, 0x19, 0xCA, 0x80, 0xB9, 0x75, 0xCE, + 0x29, 0xCE, 0xD2, 0x85, 0x22, 0xEC, 0x02, 0x63, 0xCC, 0x44, 0x30, 0x20, + 0xDA, 0xEA, 0x91, 0x5B, 0x56, 0xE6, 0x1D, 0x1C, 0xD5, 0x9D, 0x66, 0xC7, + 0x3F, 0xDF, 0x86, 0xCA, 0x4B, 0x53, 0xC4, 0xD9, 0x8D, 0xB2, 0x1D, 0xEA, + 0xF8, 0xDC, 0x27, 0x53, 0xA3, 0x47, 0xE1, 0x61, 0xCC, 0x7D, 0xB5, 0xB0, + 0xF8, 0xEE, 0x73, 0x91, 0xC5, 0xCE, 0x73, 0x6F, 0xCE, 0xEE, 0x10, 0x1F, + 0x1A, 0x06, 0xCF, 0xE9, 0x27, 0x60, 0xC5, 0x4F, 0x19, 0xE4, 0xEB, 0xCE, + 0x22, 0x26, 0x45, 0xD7, 0x60, 0x99, 0xDD, 0xCE, 0x4F, 0x37, 0xE0, 0x7F, + 0xE7, 0x63, 0xAD, 0xB0, 0xB8, 0x59, 0xB8, 0xD0, 0x06, 0x68, 0x35, 0x60, + 0xD3, 0x36, 0xAE, 0x71, 0x43, 0x04, 0xF1, 0x69, 0x65, 0x78, 0x7C, 0xF3, + 0x1F, 0xF3, 0xCA, 0x28, 0x9F, 0x5A, 0x20, 0x95, 0x66, 0xB4, 0xCD, 0xB7, + 0xEE, 0x8F, 0x78, 0xA4, 0x45, 0x18, 0xE9, 0x26, 0x2F, 0x8D, 0x9B, 0x29, + 0x28, 0xB1, 0xA4, 0xB7, 0x3A, 0x6D, 0xB9, 0xD4, 0x1C, 0x38, 0x72, 0x45, + 0x58, 0xB1, 0x5E, 0xEB, 0xF0, 0x28, 0x9B, 0xB7, 0x82, 0xCA, 0xFD, 0xCF, + 0xD6, 0x33, 0x0F, 0x9F, 0xFB, 0x97, 0x9E, 0xB1, 0x1C, 0x9C, 0x9E, 0xEA, + 0x5F, 0x5E, 0xDB, 0xAA, 0xDD, 0x54, 0xE9, 0x30, 0x21, 0x28, 0x6D, 0x8E, + 0x79, 0xF3, 0x75, 0x92, 0x8C, 0x26, 0xFE, 0xDC, 0xC5, 0xF6, 0xC3, 0xB0, + 0xDF, 0x44, 0x59, 0x43, 0xA3, 0xB6, 0x03, 0x28, 0xF6, 0x08, 0x30, 0xAA, + 0x0D, 0x33, 0xE1, 0xEF, 0x9C, 0xA9, 0x07, 0x22, 0xE3, 0x59, 0x5B, 0x40, + 0x8F, 0xDA, 0x88, 0xB7, 0x69, 0x08, 0xA8, 0xB7, 0x23, 0x2E, 0x44, 0x09, + 0x59, 0x37, 0x5B, 0xC7, 0xE3, 0x17, 0xF2, 0x22, 0xEB, 0x6E, 0x39, 0x52, + 0xC5, 0xDE, 0x54, 0xA7, 0x98, 0xC9, 0x4B, 0x20, 0x95, 0xDC, 0x46, 0x89, + 0x5F, 0xB4, 0x12, 0xF9, 0x85, 0x29, 0x8E, 0xEB, 0xC8, 0x27, 0x15, 0x20, + 0xC0, 0x4B, 0xD4, 0xCC, 0x7C, 0x0C, 0x6C, 0x34, 0x0C, 0x26, 0x9B, 0x26, + 0x31, 0xA6, 0x3C, 0xA7, 0xF6, 0xD9, 0xD0, 0x4B, 0xA2, 0x64, 0xFF, 0x3B, + 0x99, 0x41, 0x72, 0xC1, 0xE0, 0x70, 0x97, 0xF1, 0x24, 0xBB, 0x2B, 0xC4, + 0x74, 0x22, 0xB1, 0xAC, 0x6B, 0x22, 0x32, 0x24, 0xD3, 0x78, 0x2A, 0xC0, + 0xC0, 0xA1, 0x2F, 0xF1, 0x52, 0x05, 0xC9, 0x3F, 0xEF, 0x76, 0x66, 0xE2, + 0x45, 0xD8, 0x0D, 0x3D, 0xAD, 0x95, 0xC8, 0xC7, 0x89, 0x26, 0xC8, 0x0F, + 0xAE, 0xA7, 0x03, 0x2E, 0xFB, 0xC1, 0x5F, 0xFA, 0x20, 0xE1, 0x70, 0xAD, + 0xB0, 0x65, 0x20, 0x37, 0x33, 0x60, 0xB0, 0xD5, 0xAF, 0xD7, 0x0C, 0x1C, + 0xC2, 0x90, 0x70, 0xD7, 0x4A, 0x18, 0xBC, 0x7E, 0x01, 0xB0, 0xB0, 0xEB, + 0x15, 0x1E, 0x44, 0x06, 0xCD, 0xA4, 0x4F, 0xE8, 0x0C, 0xD1, 0xC3, 0x20, + 0x10, 0xE1, 0x54, 0x65, 0x9E, 0xB6, 0x51, 0xD0, 0x1A, 0x76, 0x6B, 0x42, + 0x5A, 0x58, 0x76, 0x34, 0xEA, 0xB7, 0x37, 0x19, 0xAE, 0x2E, 0x75, 0xF9, + 0x96, 0xE5, 0xC1, 0x59, 0xF7, 0x94, 0x57, 0x29, 0x25, 0x8D, 0x3A, 0x4C, + 0xAB, 0x4D, 0x9A, 0x41, 0xD0, 0x5F, 0x26, 0x03 +}; + +static const unsigned char TA221_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA222_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, + 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA222_RSA_N[] = { + 0x8B, 0xC2, 0xE7, 0xAF, 0x65, 0x9B, 0x05, 0x67, 0x96, 0xC9, 0x0D, 0x24, + 0xB9, 0xD0, 0x0E, 0x64, 0xFC, 0xCE, 0xE2, 0x24, 0x18, 0x2C, 0x84, 0x7F, + 0x77, 0x51, 0xCB, 0x04, 0x11, 0x36, 0xB8, 0x5E, 0xED, 0x69, 0x71, 0xA7, + 0x9E, 0xE4, 0x25, 0x09, 0x97, 0x67, 0xC1, 0x47, 0xC2, 0xCF, 0x91, 0x16, + 0x36, 0x62, 0x3D, 0x38, 0x04, 0xE1, 0x51, 0x82, 0xFF, 0xAC, 0xD2, 0xB4, + 0x69, 0xDD, 0x2E, 0xEC, 0x11, 0xA3, 0x45, 0xEE, 0x6B, 0x6B, 0x3B, 0x4C, + 0xBF, 0x8C, 0x8D, 0xA4, 0x1E, 0x9D, 0x11, 0xB9, 0xE9, 0x38, 0xF9, 0x7A, + 0x0E, 0x0C, 0x98, 0xE2, 0x23, 0x1D, 0xD1, 0x4E, 0x63, 0xD4, 0xE7, 0xB8, + 0x41, 0x44, 0xFB, 0x6B, 0xAF, 0x6B, 0xDA, 0x1F, 0xD3, 0xC5, 0x91, 0x88, + 0x5B, 0xA4, 0x89, 0x92, 0xD1, 0x81, 0xE6, 0x8C, 0x39, 0x58, 0xA0, 0xD6, + 0x69, 0x43, 0xA9, 0xAD, 0x98, 0x52, 0x58, 0x6E, 0xDB, 0x0A, 0xFB, 0x6B, + 0xCF, 0x68, 0xFA, 0xE3, 0xA4, 0x5E, 0x3A, 0x45, 0x73, 0x98, 0x07, 0xEA, + 0x5F, 0x02, 0x72, 0xDE, 0x0C, 0xA5, 0xB3, 0x9F, 0xAE, 0xA9, 0x1D, 0xB7, + 0x1D, 0xB3, 0xFC, 0x8A, 0x59, 0xE7, 0x6E, 0x72, 0x65, 0xAD, 0xF5, 0x30, + 0x94, 0x23, 0x07, 0xF3, 0x82, 0x16, 0x4B, 0x35, 0x98, 0x9C, 0x53, 0xBB, + 0x2F, 0xCA, 0xE4, 0x5A, 0xD9, 0xC7, 0x8D, 0x1D, 0xFC, 0x98, 0x99, 0xFB, + 0x2C, 0xA4, 0x82, 0x6B, 0xF0, 0x2A, 0x1F, 0x8E, 0x0B, 0x5F, 0x71, 0x5C, + 0x5C, 0xAE, 0x42, 0x7B, 0x29, 0x89, 0x81, 0xCB, 0x03, 0xA3, 0x99, 0xCA, + 0x88, 0x9E, 0x0B, 0x40, 0x09, 0x41, 0x33, 0xDB, 0xE6, 0x58, 0x7A, 0xFD, + 0xAE, 0x99, 0x70, 0xC0, 0x5A, 0x0F, 0xD6, 0x13, 0x86, 0x71, 0x2F, 0x76, + 0x69, 0xFC, 0x90, 0xDD, 0xDB, 0x2D, 0x6E, 0xD1, 0xF2, 0x9B, 0xF5, 0x1A, + 0x6B, 0x9E, 0x6F, 0x15, 0x8C, 0x7A, 0xF0, 0x4B, 0x28, 0xA0, 0x22, 0x38, + 0x80, 0x24, 0x6C, 0x36, 0xA4, 0x3B, 0xF2, 0x30, 0x91, 0xF3, 0x78, 0x13, + 0xCF, 0xC1, 0x3F, 0x35, 0xAB, 0xF1, 0x1D, 0x11, 0x23, 0xB5, 0x43, 0x22, + 0x9E, 0x01, 0x92, 0xB7, 0x18, 0x02, 0xE5, 0x11, 0xD1, 0x82, 0xDB, 0x15, + 0x00, 0xCC, 0x61, 0x37, 0xC1, 0x2A, 0x7C, 0x9A, 0xE1, 0xD0, 0xBA, 0xB3, + 0x50, 0x46, 0xEE, 0x82, 0xAC, 0x9D, 0x31, 0xF8, 0xFB, 0x23, 0xE2, 0x03, + 0x00, 0x48, 0x70, 0xA3, 0x09, 0x26, 0x79, 0x15, 0x53, 0x60, 0xF3, 0x38, + 0x5C, 0xAD, 0x38, 0xEA, 0x81, 0x00, 0x63, 0x14, 0xB9, 0x33, 0x5E, 0xDD, + 0x0B, 0xDB, 0xA0, 0x45, 0x07, 0x1A, 0x33, 0x09, 0xF8, 0x4D, 0xB4, 0xA7, + 0x02, 0xA6, 0x69, 0xF4, 0xC2, 0x59, 0x05, 0x88, 0x65, 0x85, 0x56, 0xAE, + 0x4B, 0xCB, 0xE0, 0xDE, 0x3C, 0x7D, 0x2D, 0x1A, 0xC8, 0xE9, 0xFB, 0x1F, + 0xA3, 0x61, 0x4A, 0xD6, 0x2A, 0x13, 0xAD, 0x77, 0x4C, 0x1A, 0x18, 0x9B, + 0x91, 0x0F, 0x58, 0xD8, 0x06, 0x54, 0xC5, 0x97, 0xF8, 0xAA, 0x3F, 0x20, + 0x8A, 0xA6, 0x85, 0xA6, 0x77, 0xF6, 0xA6, 0xFC, 0x1C, 0xE2, 0xEE, 0x6E, + 0x94, 0x33, 0x2A, 0x83, 0x50, 0x84, 0x0A, 0xE5, 0x4F, 0x86, 0xF8, 0x50, + 0x45, 0x78, 0x00, 0x81, 0xEB, 0x5B, 0x68, 0xE3, 0x26, 0x8D, 0xCC, 0x7B, + 0x5C, 0x51, 0xF4, 0x14, 0x2C, 0x40, 0xBE, 0x1A, 0x60, 0x1D, 0x7A, 0x72, + 0x61, 0x1D, 0x1F, 0x63, 0x2D, 0x88, 0xAA, 0xCE, 0xA2, 0x45, 0x90, 0x08, + 0xFC, 0x6B, 0xBE, 0xB3, 0x50, 0x2A, 0x5A, 0xFD, 0xA8, 0x48, 0x18, 0x46, + 0xD6, 0x90, 0x40, 0x92, 0x90, 0x0A, 0x84, 0x5E, 0x68, 0x31, 0xF8, 0xEB, + 0xED, 0x0D, 0xD3, 0x1D, 0xC6, 0x7D, 0x99, 0x18, 0x55, 0x56, 0x27, 0x65, + 0x2E, 0x8D, 0x45, 0xC5, 0x24, 0xEC, 0xCE, 0xE3 +}; + +static const unsigned char TA222_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA223_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x41, 0x43, 0x20, + 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, + 0x4D +}; + +static const unsigned char TA223_RSA_N[] = { + 0xBA, 0x71, 0x80, 0x7A, 0x4C, 0x86, 0x6E, 0x7F, 0xC8, 0x13, 0x6D, 0xC0, + 0xC6, 0x7D, 0x1C, 0x00, 0x97, 0x8F, 0x2C, 0x0C, 0x23, 0xBB, 0x10, 0x9A, + 0x40, 0xA9, 0x1A, 0xB7, 0x87, 0x88, 0xF8, 0x9B, 0x56, 0x6A, 0xFB, 0xE6, + 0x7B, 0x8E, 0x8B, 0x92, 0x8E, 0xA7, 0x25, 0x5D, 0x59, 0x11, 0xDB, 0x36, + 0x2E, 0xB7, 0x51, 0x17, 0x1F, 0xA9, 0x08, 0x1F, 0x04, 0x17, 0x24, 0x58, + 0xAA, 0x37, 0x4A, 0x18, 0xDF, 0xE5, 0x39, 0xD4, 0x57, 0xFD, 0xD7, 0xC1, + 0x2C, 0x91, 0x01, 0x91, 0xE2, 0x22, 0xD4, 0x03, 0xC0, 0x58, 0xFC, 0x77, + 0x47, 0xEC, 0x8F, 0x3E, 0x74, 0x43, 0xBA, 0xAC, 0x34, 0x8D, 0x4D, 0x38, + 0x76, 0x67, 0x8E, 0xB0, 0xC8, 0x6F, 0x30, 0x33, 0x58, 0x71, 0x5C, 0xB4, + 0xF5, 0x6B, 0x6E, 0xD4, 0x01, 0x50, 0xB8, 0x13, 0x7E, 0x6C, 0x4A, 0xA3, + 0x49, 0xD1, 0x20, 0x19, 0xEE, 0xBC, 0xC0, 0x29, 0x18, 0x65, 0xA7, 0xDE, + 0xFE, 0xEF, 0xDD, 0x0A, 0x90, 0x21, 0xE7, 0x1A, 0x67, 0x92, 0x42, 0x10, + 0x98, 0x5F, 0x4F, 0x30, 0xBC, 0x3E, 0x1C, 0x45, 0xB4, 0x10, 0xD7, 0x68, + 0x40, 0x14, 0xC0, 0x40, 0xFA, 0xE7, 0x77, 0x17, 0x7A, 0xE6, 0x0B, 0x8F, + 0x65, 0x5B, 0x3C, 0xD9, 0x9A, 0x52, 0xDB, 0xB5, 0xBD, 0x9E, 0x46, 0xCF, + 0x3D, 0xEB, 0x91, 0x05, 0x02, 0xC0, 0x96, 0xB2, 0x76, 0x4C, 0x4D, 0x10, + 0x96, 0x3B, 0x92, 0xFA, 0x9C, 0x7F, 0x0F, 0x99, 0xDF, 0xBE, 0x23, 0x35, + 0x45, 0x1E, 0x02, 0x5C, 0xFE, 0xB5, 0xA8, 0x9B, 0x99, 0x25, 0xDA, 0x5E, + 0xF3, 0x22, 0xC3, 0x39, 0xF5, 0xE4, 0x2A, 0x2E, 0xD3, 0xC6, 0x1F, 0xC4, + 0x6C, 0xAA, 0xC5, 0x1C, 0x6A, 0x01, 0x05, 0x4A, 0x2F, 0xD2, 0xC5, 0xC1, + 0xA8, 0x34, 0x26, 0x5D, 0x66, 0xA5, 0xD2, 0x02, 0x21, 0xF9, 0x18, 0xB7, + 0x06, 0xF5, 0x4E, 0x99, 0x6F, 0xA8, 0xAB, 0x4C, 0x51, 0xE8, 0xCF, 0x50, + 0x18, 0xC5, 0x77, 0xC8, 0x39, 0x09, 0x2C, 0x49, 0x92, 0x32, 0x99, 0xA8, + 0xBB, 0x17, 0x17, 0x79, 0xB0, 0x5A, 0xC5, 0xE6, 0xA3, 0xC4, 0x59, 0x65, + 0x47, 0x35, 0x83, 0x5E, 0xA9, 0xE8, 0x35, 0x0B, 0x99, 0xBB, 0xE4, 0xCD, + 0x20, 0xC6, 0x9B, 0x4A, 0x06, 0x39, 0xB5, 0x68, 0xFC, 0x22, 0xBA, 0xEE, + 0x55, 0x8C, 0x2B, 0x4E, 0xEA, 0xF3, 0xB1, 0xE3, 0xFC, 0xB6, 0x99, 0x9A, + 0xD5, 0x42, 0xFA, 0x71, 0x4D, 0x08, 0xCF, 0x87, 0x1E, 0x6A, 0x71, 0x7D, + 0xF9, 0xD3, 0xB4, 0xE9, 0xA5, 0x71, 0x81, 0x7B, 0xC2, 0x4E, 0x47, 0x96, + 0xA5, 0xF6, 0x76, 0x85, 0xA3, 0x28, 0x8F, 0xE9, 0x80, 0x6E, 0x81, 0x53, + 0xA5, 0x6D, 0x5F, 0xB8, 0x48, 0xF9, 0xC2, 0xF9, 0x36, 0xA6, 0x2E, 0x49, + 0xFF, 0xB8, 0x96, 0xC2, 0x8C, 0x07, 0xB3, 0x9B, 0x88, 0x58, 0xFC, 0xEB, + 0x1B, 0x1C, 0xDE, 0x2D, 0x70, 0xE2, 0x97, 0x92, 0x30, 0xA1, 0x89, 0xE3, + 0xBC, 0x55, 0xA8, 0x27, 0xD6, 0x4B, 0xED, 0x90, 0xAD, 0x8B, 0xFA, 0x63, + 0x25, 0x59, 0x2D, 0xA8, 0x35, 0xDD, 0xCA, 0x97, 0x33, 0xBC, 0xE5, 0xCD, + 0xC7, 0x9D, 0xD1, 0xEC, 0xEF, 0x5E, 0x0E, 0x4A, 0x90, 0x06, 0x26, 0x63, + 0xAD, 0xB9, 0xD9, 0x35, 0x2D, 0x07, 0xBA, 0x76, 0x65, 0x2C, 0xAC, 0x57, + 0x8F, 0x7D, 0xF4, 0x07, 0x94, 0xD7, 0x81, 0x02, 0x96, 0x5D, 0xA3, 0x07, + 0x49, 0xD5, 0x7A, 0xD0, 0x57, 0xF9, 0x1B, 0xE7, 0x53, 0x46, 0x75, 0xAA, + 0xB0, 0x79, 0x42, 0xCB, 0x68, 0x71, 0x08, 0xE9, 0x60, 0xBD, 0x39, 0x69, + 0xCE, 0xF4, 0xAF, 0xC3, 0x56, 0x40, 0xC7, 0xAD, 0x52, 0xA2, 0x09, 0xE4, + 0x6F, 0x86, 0x47, 0x8A, 0x1F, 0xEB, 0x28, 0x27, 0x5D, 0x83, 0x20, 0xAF, + 0x04, 0xC9, 0x6C, 0x56, 0x9A, 0x8B, 0x46, 0xF5 +}; + +static const unsigned char TA223_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA224_DN[] = { + 0x30, 0x6E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x13, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, 0x6F, 0x66, 0x65, + 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x53, 0x41, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0F, 0x56, 0x41, 0x54, 0x45, + 0x53, 0x2D, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x46, 0x49, + 0x52, 0x4D, 0x41, 0x50, 0x52, 0x4F, 0x46, 0x45, 0x53, 0x49, 0x4F, 0x4E, + 0x41, 0x4C, 0x20, 0x43, 0x41, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x2D, 0x41, + 0x20, 0x57, 0x45, 0x42 +}; + +static const unsigned char TA224_EC_Q[] = { + 0x04, 0x47, 0x53, 0xEA, 0x2C, 0x11, 0xA4, 0x77, 0xC7, 0x2A, 0xEA, 0xF3, + 0xD6, 0x5F, 0x7B, 0xD3, 0x04, 0x91, 0x5C, 0xFA, 0x88, 0xC6, 0x22, 0xB9, + 0x83, 0x10, 0x62, 0x77, 0x84, 0x33, 0x2D, 0xE9, 0x03, 0x88, 0xD4, 0xE0, + 0x33, 0xF7, 0xED, 0x77, 0x2C, 0x4A, 0x60, 0xEA, 0xE4, 0x6F, 0xAD, 0x6D, + 0xB4, 0xF8, 0x4C, 0x8A, 0xA4, 0xE4, 0x1F, 0xCA, 0xEA, 0x4F, 0x38, 0x4A, + 0x2E, 0x82, 0x73, 0x2B, 0xC7, 0x66, 0x9B, 0x0A, 0x8C, 0x40, 0x9C, 0x7C, + 0x8A, 0xF6, 0xF2, 0x39, 0x60, 0xB2, 0xDE, 0xCB, 0xEC, 0xB8, 0xE4, 0x6F, + 0xEA, 0x9B, 0x5D, 0xB7, 0x53, 0x90, 0x18, 0x32, 0x55, 0xC5, 0x20, 0xB7, + 0x94 +}; + +static const unsigned char TA225_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x42, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x6F, 0x72, 0x65, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, 0x43, 0x79, + 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6C, 0x74, 0x69, + 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA225_RSA_N[] = { + 0xA3, 0x04, 0xBB, 0x22, 0xAB, 0x98, 0x3D, 0x57, 0xE8, 0x26, 0x72, 0x9A, + 0xB5, 0x79, 0xD4, 0x29, 0xE2, 0xE1, 0xE8, 0x95, 0x80, 0xB1, 0xB0, 0xE3, + 0x5B, 0x8E, 0x2B, 0x29, 0x9A, 0x64, 0xDF, 0xA1, 0x5D, 0xED, 0xB0, 0x09, + 0x05, 0x6D, 0xDB, 0x28, 0x2E, 0xCE, 0x62, 0xA2, 0x62, 0xFE, 0xB4, 0x88, + 0xDA, 0x12, 0xEB, 0x38, 0xEB, 0x21, 0x9D, 0xC0, 0x41, 0x2B, 0x01, 0x52, + 0x7B, 0x88, 0x77, 0xD3, 0x1C, 0x8F, 0xC7, 0xBA, 0xB9, 0x88, 0xB5, 0x6A, + 0x09, 0xE7, 0x73, 0xE8, 0x11, 0x40, 0xA7, 0xD1, 0xCC, 0xCA, 0x62, 0x8D, + 0x2D, 0xE5, 0x8F, 0x0B, 0xA6, 0x50, 0xD2, 0xA8, 0x50, 0xC3, 0x28, 0xEA, + 0xF5, 0xAB, 0x25, 0x87, 0x8A, 0x9A, 0x96, 0x1C, 0xA9, 0x67, 0xB8, 0x3F, + 0x0C, 0xD5, 0xF7, 0xF9, 0x52, 0x13, 0x2F, 0xC2, 0x1B, 0xD5, 0x70, 0x70, + 0xF0, 0x8F, 0xC0, 0x12, 0xCA, 0x06, 0xCB, 0x9A, 0xE1, 0xD9, 0xCA, 0x33, + 0x7A, 0x77, 0xD6, 0xF8, 0xEC, 0xB9, 0xF1, 0x68, 0x44, 0x42, 0x48, 0x13, + 0xD2, 0xC0, 0xC2, 0xA4, 0xAE, 0x5E, 0x60, 0xFE, 0xB6, 0xA6, 0x05, 0xFC, + 0xB4, 0xDD, 0x07, 0x59, 0x02, 0xD4, 0x59, 0x18, 0x98, 0x63, 0xF5, 0xA5, + 0x63, 0xE0, 0x90, 0x0C, 0x7D, 0x5D, 0xB2, 0x06, 0x7A, 0xF3, 0x85, 0xEA, + 0xEB, 0xD4, 0x03, 0xAE, 0x5E, 0x84, 0x3E, 0x5F, 0xFF, 0x15, 0xED, 0x69, + 0xBC, 0xF9, 0x39, 0x36, 0x72, 0x75, 0xCF, 0x77, 0x52, 0x4D, 0xF3, 0xC9, + 0x90, 0x2C, 0xB9, 0x3D, 0xE5, 0xC9, 0x23, 0x53, 0x3F, 0x1F, 0x24, 0x98, + 0x21, 0x5C, 0x07, 0x99, 0x29, 0xBD, 0xC6, 0x3A, 0xEC, 0xE7, 0x6E, 0x86, + 0x3A, 0x6B, 0x97, 0x74, 0x63, 0x33, 0xBD, 0x68, 0x18, 0x31, 0xF0, 0x78, + 0x8D, 0x76, 0xBF, 0xFC, 0x9E, 0x8E, 0x5D, 0x2A, 0x86, 0xA7, 0x4D, 0x90, + 0xDC, 0x27, 0x1A, 0x39 +}; + +static const unsigned char TA225_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA226_DN[] = { + 0x30, 0x81, 0x83, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x1A, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, 0x47, 0x6F, 0x44, 0x61, 0x64, 0x64, + 0x79, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, + 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6F, + 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA226_RSA_N[] = { + 0xBF, 0x71, 0x62, 0x08, 0xF1, 0xFA, 0x59, 0x34, 0xF7, 0x1B, 0xC9, 0x18, + 0xA3, 0xF7, 0x80, 0x49, 0x58, 0xE9, 0x22, 0x83, 0x13, 0xA6, 0xC5, 0x20, + 0x43, 0x01, 0x3B, 0x84, 0xF1, 0xE6, 0x85, 0x49, 0x9F, 0x27, 0xEA, 0xF6, + 0x84, 0x1B, 0x4E, 0xA0, 0xB4, 0xDB, 0x70, 0x98, 0xC7, 0x32, 0x01, 0xB1, + 0x05, 0x3E, 0x07, 0x4E, 0xEE, 0xF4, 0xFA, 0x4F, 0x2F, 0x59, 0x30, 0x22, + 0xE7, 0xAB, 0x19, 0x56, 0x6B, 0xE2, 0x80, 0x07, 0xFC, 0xF3, 0x16, 0x75, + 0x80, 0x39, 0x51, 0x7B, 0xE5, 0xF9, 0x35, 0xB6, 0x74, 0x4E, 0xA9, 0x8D, + 0x82, 0x13, 0xE4, 0xB6, 0x3F, 0xA9, 0x03, 0x83, 0xFA, 0xA2, 0xBE, 0x8A, + 0x15, 0x6A, 0x7F, 0xDE, 0x0B, 0xC3, 0xB6, 0x19, 0x14, 0x05, 0xCA, 0xEA, + 0xC3, 0xA8, 0x04, 0x94, 0x3B, 0x46, 0x7C, 0x32, 0x0D, 0xF3, 0x00, 0x66, + 0x22, 0xC8, 0x8D, 0x69, 0x6D, 0x36, 0x8C, 0x11, 0x18, 0xB7, 0xD3, 0xB2, + 0x1C, 0x60, 0xB4, 0x38, 0xFA, 0x02, 0x8C, 0xCE, 0xD3, 0xDD, 0x46, 0x07, + 0xDE, 0x0A, 0x3E, 0xEB, 0x5D, 0x7C, 0xC8, 0x7C, 0xFB, 0xB0, 0x2B, 0x53, + 0xA4, 0x92, 0x62, 0x69, 0x51, 0x25, 0x05, 0x61, 0x1A, 0x44, 0x81, 0x8C, + 0x2C, 0xA9, 0x43, 0x96, 0x23, 0xDF, 0xAC, 0x3A, 0x81, 0x9A, 0x0E, 0x29, + 0xC5, 0x1C, 0xA9, 0xE9, 0x5D, 0x1E, 0xB6, 0x9E, 0x9E, 0x30, 0x0A, 0x39, + 0xCE, 0xF1, 0x88, 0x80, 0xFB, 0x4B, 0x5D, 0xCC, 0x32, 0xEC, 0x85, 0x62, + 0x43, 0x25, 0x34, 0x02, 0x56, 0x27, 0x01, 0x91, 0xB4, 0x3B, 0x70, 0x2A, + 0x3F, 0x6E, 0xB1, 0xE8, 0x9C, 0x88, 0x01, 0x7D, 0x9F, 0xD4, 0xF9, 0xDB, + 0x53, 0x6D, 0x60, 0x9D, 0xBF, 0x2C, 0xE7, 0x58, 0xAB, 0xB8, 0x5F, 0x46, + 0xFC, 0xCE, 0xC4, 0x1B, 0x03, 0x3C, 0x09, 0xEB, 0x49, 0x31, 0x5C, 0x69, + 0x46, 0xB3, 0xE0, 0x47 +}; + +static const unsigned char TA226_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA227_DN[] = { + 0x30, 0x6F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x4B, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x09, 0x48, 0x6F, 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x48, 0x6F, + 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA227_RSA_N[] = { + 0xB3, 0x88, 0xD7, 0xEA, 0xCE, 0x0F, 0x20, 0x4E, 0xBE, 0xE6, 0xD6, 0x03, + 0x6D, 0xEE, 0x59, 0xFC, 0xC2, 0x57, 0xDF, 0x29, 0x68, 0xA1, 0x83, 0x0E, + 0x3E, 0x68, 0xC7, 0x68, 0x58, 0x9C, 0x1C, 0x60, 0x4B, 0x89, 0x43, 0x0C, + 0xB9, 0xD4, 0x15, 0xB2, 0xEE, 0xC1, 0x4E, 0x75, 0xE9, 0xB5, 0xA7, 0xEF, + 0xE5, 0xE9, 0x35, 0x99, 0xE4, 0xCC, 0x1C, 0xE7, 0x4B, 0x5F, 0x8D, 0x33, + 0x30, 0x20, 0x33, 0x53, 0xD9, 0xA6, 0xBB, 0xD5, 0x3E, 0x13, 0x8E, 0xE9, + 0x1F, 0x87, 0x49, 0xAD, 0x50, 0x2D, 0x50, 0xCA, 0x18, 0xBE, 0x01, 0x58, + 0xA2, 0x13, 0x70, 0x96, 0xBB, 0x89, 0x88, 0x56, 0x80, 0x5C, 0xF8, 0xBD, + 0x2C, 0x3C, 0xE1, 0x4C, 0x57, 0x88, 0xBB, 0xD3, 0xB9, 0x95, 0xEF, 0xCB, + 0xC7, 0xF6, 0xDA, 0x31, 0x74, 0x28, 0xA6, 0xE6, 0x54, 0x89, 0xF5, 0x41, + 0x31, 0xCA, 0xE5, 0x26, 0x1A, 0xCD, 0x82, 0xE0, 0x70, 0xDA, 0x3B, 0x29, + 0xBB, 0xD5, 0x03, 0xF5, 0x99, 0xBA, 0x55, 0xF5, 0x64, 0xD1, 0x60, 0x0E, + 0xB3, 0x89, 0x49, 0xB8, 0x8A, 0x2F, 0x05, 0xD2, 0x84, 0x45, 0x28, 0x7C, + 0x8F, 0x68, 0x50, 0x12, 0x78, 0xFC, 0x0B, 0xB5, 0x53, 0xCB, 0xC2, 0x98, + 0x1C, 0x84, 0xA3, 0x9E, 0xB0, 0xBE, 0x23, 0xA4, 0xDA, 0xDC, 0xC8, 0x2B, + 0x1E, 0xDA, 0x6E, 0x45, 0x1E, 0x89, 0x98, 0xDA, 0xF9, 0x00, 0x2E, 0x06, + 0xE9, 0x0C, 0x3B, 0x70, 0xD5, 0x50, 0x25, 0x88, 0x99, 0xCB, 0xCD, 0x73, + 0x60, 0xF7, 0xD5, 0xFF, 0x35, 0x67, 0xC5, 0xA1, 0xBC, 0x5E, 0xAB, 0xCD, + 0x4A, 0xB8, 0x45, 0xEB, 0xC8, 0x68, 0x1E, 0x0D, 0x0D, 0x14, 0x46, 0x12, + 0xE3, 0xD2, 0x64, 0x62, 0x8A, 0x42, 0x98, 0xBC, 0xB4, 0xC6, 0x08, 0x08, + 0xF8, 0xFD, 0xA8, 0x4C, 0x64, 0x9C, 0x76, 0x01, 0xBD, 0x2F, 0xA9, 0x6C, + 0x33, 0x0F, 0xD8, 0x3F, 0x28, 0xB8, 0x3C, 0x69, 0x01, 0x42, 0x86, 0x7E, + 0x69, 0xC1, 0xC9, 0x06, 0xCA, 0xE5, 0x7A, 0x46, 0x65, 0xE9, 0xC2, 0xD6, + 0x50, 0x41, 0x2E, 0x3F, 0xB7, 0xE4, 0xED, 0x6C, 0xD7, 0xBF, 0x26, 0x01, + 0x11, 0xA2, 0x16, 0x29, 0x4A, 0x6B, 0x34, 0x06, 0x90, 0xEC, 0x13, 0xD2, + 0xB6, 0xFB, 0x6A, 0x76, 0xD2, 0x3C, 0xED, 0xF0, 0xD6, 0x2D, 0xDD, 0xE1, + 0x15, 0xEC, 0xA3, 0x9B, 0x2F, 0x2C, 0xC9, 0x3E, 0x2B, 0xE4, 0x69, 0x3B, + 0xFF, 0x72, 0x25, 0xB1, 0x36, 0x86, 0x5B, 0xC7, 0x7F, 0x6B, 0x8B, 0x55, + 0x1B, 0x4A, 0xC5, 0x20, 0x61, 0x3D, 0xAE, 0xCB, 0x50, 0xE1, 0x08, 0x3A, + 0xBE, 0xB0, 0x8F, 0x63, 0x41, 0x53, 0x30, 0x08, 0x59, 0x3C, 0x98, 0x1D, + 0x77, 0xBA, 0x63, 0x91, 0x7A, 0xCA, 0x10, 0x50, 0x60, 0xBF, 0xF0, 0xD7, + 0xBC, 0x95, 0x87, 0x8F, 0x97, 0xC5, 0xFE, 0x97, 0x6A, 0x01, 0x94, 0xA3, + 0x7C, 0x5B, 0x85, 0x1D, 0x2A, 0x39, 0x3A, 0xD0, 0x54, 0xA1, 0xD1, 0x39, + 0x71, 0x9D, 0xFD, 0x21, 0xF9, 0xB5, 0x7B, 0xF0, 0xE2, 0xE0, 0x02, 0x8F, + 0x6E, 0x96, 0x24, 0x25, 0x2C, 0xA0, 0x1E, 0x2C, 0xA8, 0xC4, 0x89, 0xA7, + 0xEF, 0xED, 0x99, 0x06, 0x2F, 0xB6, 0x0A, 0x4C, 0x4F, 0xDB, 0xA2, 0xCC, + 0x37, 0x1A, 0xAF, 0x47, 0x85, 0x2D, 0x8A, 0x5F, 0xC4, 0x34, 0x34, 0x4C, + 0x00, 0xFD, 0x18, 0x93, 0x67, 0x13, 0xD1, 0x37, 0xE6, 0x48, 0xB4, 0x8B, + 0x06, 0xC5, 0x57, 0x7B, 0x19, 0x86, 0x0A, 0x79, 0xCB, 0x00, 0xC9, 0x52, + 0xAF, 0x42, 0xFF, 0x37, 0x8F, 0xE1, 0xA3, 0x1E, 0x7A, 0x3D, 0x50, 0xAB, + 0x63, 0x06, 0xE7, 0x15, 0xB5, 0x3F, 0xB6, 0x45, 0x37, 0x94, 0x37, 0xB1, + 0x7E, 0xF2, 0x48, 0xC3, 0x7F, 0xC5, 0x75, 0xFE, 0x97, 0x8D, 0x45, 0x8F, + 0x1A, 0xA7, 0x1A, 0x72, 0x28, 0x1A, 0x40, 0x0F +}; + +static const unsigned char TA227_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA228_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA228_RSA_N[] = { + 0xAF, 0x35, 0x2E, 0xD8, 0xAC, 0x6C, 0x55, 0x69, 0x06, 0x71, 0xE5, 0x13, + 0x68, 0x24, 0xB3, 0x4F, 0xD8, 0xCC, 0x21, 0x47, 0xF8, 0xF1, 0x60, 0x38, + 0x89, 0x89, 0x03, 0xE9, 0xBD, 0xEA, 0x5E, 0x46, 0x53, 0x09, 0xDC, 0x5C, + 0xF5, 0x5A, 0xE8, 0xF7, 0x45, 0x2A, 0x02, 0xEB, 0x31, 0x61, 0xD7, 0x29, + 0x33, 0x4C, 0xCE, 0xC7, 0x7C, 0x0A, 0x37, 0x7E, 0x0F, 0xBA, 0x32, 0x98, + 0xE1, 0x1D, 0x97, 0xAF, 0x8F, 0xC7, 0xDC, 0xC9, 0x38, 0x96, 0xF3, 0xDB, + 0x1A, 0xFC, 0x51, 0xED, 0x68, 0xC6, 0xD0, 0x6E, 0xA4, 0x7C, 0x24, 0xD1, + 0xAE, 0x42, 0xC8, 0x96, 0x50, 0x63, 0x2E, 0xE0, 0xFE, 0x75, 0xFE, 0x98, + 0xA7, 0x5F, 0x49, 0x2E, 0x95, 0xE3, 0x39, 0x33, 0x64, 0x8E, 0x1E, 0xA4, + 0x5F, 0x90, 0xD2, 0x67, 0x3C, 0xB2, 0xD9, 0xFE, 0x41, 0xB9, 0x55, 0xA7, + 0x09, 0x8E, 0x72, 0x05, 0x1E, 0x8B, 0xDD, 0x44, 0x85, 0x82, 0x42, 0xD0, + 0x49, 0xC0, 0x1D, 0x60, 0xF0, 0xD1, 0x17, 0x2C, 0x95, 0xEB, 0xF6, 0xA5, + 0xC1, 0x92, 0xA3, 0xC5, 0xC2, 0xA7, 0x08, 0x60, 0x0D, 0x60, 0x04, 0x10, + 0x96, 0x79, 0x9E, 0x16, 0x34, 0xE6, 0xA9, 0xB6, 0xFA, 0x25, 0x45, 0x39, + 0xC8, 0x1E, 0x65, 0xF9, 0x93, 0xF5, 0xAA, 0xF1, 0x52, 0xDC, 0x99, 0x98, + 0x3D, 0xA5, 0x86, 0x1A, 0x0C, 0x35, 0x33, 0xFA, 0x4B, 0xA5, 0x04, 0x06, + 0x15, 0x1C, 0x31, 0x80, 0xEF, 0xAA, 0x18, 0x6B, 0xC2, 0x7B, 0xD7, 0xDA, + 0xCE, 0xF9, 0x33, 0x20, 0xD5, 0xF5, 0xBD, 0x6A, 0x33, 0x2D, 0x81, 0x04, + 0xFB, 0xB0, 0x5C, 0xD4, 0x9C, 0xA3, 0xE2, 0x5C, 0x1D, 0xE3, 0xA9, 0x42, + 0x75, 0x5E, 0x7B, 0xD4, 0x77, 0xEF, 0x39, 0x54, 0xBA, 0xC9, 0x0A, 0x18, + 0x1B, 0x12, 0x99, 0x49, 0x2F, 0x88, 0x4B, 0xFD, 0x50, 0x62, 0xD1, 0x73, + 0xE7, 0x8F, 0x7A, 0x43 +}; + +static const unsigned char TA228_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA229_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA229_RSA_N[] = { + 0xCA, 0x5B, 0xBE, 0x94, 0x33, 0x8C, 0x29, 0x95, 0x91, 0x16, 0x0A, 0x95, + 0xBD, 0x47, 0x62, 0xC1, 0x89, 0xF3, 0x99, 0x36, 0xDF, 0x46, 0x90, 0xC9, + 0xA5, 0xED, 0x78, 0x6A, 0x6F, 0x47, 0x91, 0x68, 0xF8, 0x27, 0x67, 0x50, + 0x33, 0x1D, 0xA1, 0xA6, 0xFB, 0xE0, 0xE5, 0x43, 0xA3, 0x84, 0x02, 0x57, + 0x01, 0x5D, 0x9C, 0x48, 0x40, 0x82, 0x53, 0x10, 0xBC, 0xBF, 0xC7, 0x3B, + 0x68, 0x90, 0xB6, 0x82, 0x2D, 0xE5, 0xF4, 0x65, 0xD0, 0xCC, 0x6D, 0x19, + 0xCC, 0x95, 0xF9, 0x7B, 0xAC, 0x4A, 0x94, 0xAD, 0x0E, 0xDE, 0x4B, 0x43, + 0x1D, 0x87, 0x07, 0x92, 0x13, 0x90, 0x80, 0x83, 0x64, 0x35, 0x39, 0x04, + 0xFC, 0xE5, 0xE9, 0x6C, 0xB3, 0xB6, 0x1F, 0x50, 0x94, 0x38, 0x65, 0x50, + 0x5C, 0x17, 0x46, 0xB9, 0xB6, 0x85, 0xB5, 0x1C, 0xB5, 0x17, 0xE8, 0xD6, + 0x45, 0x9D, 0xD8, 0xB2, 0x26, 0xB0, 0xCA, 0xC4, 0x70, 0x4A, 0xAE, 0x60, + 0xA4, 0xDD, 0xB3, 0xD9, 0xEC, 0xFC, 0x3B, 0xD5, 0x57, 0x72, 0xBC, 0x3F, + 0xC8, 0xC9, 0xB2, 0xDE, 0x4B, 0x6B, 0xF8, 0x23, 0x6C, 0x03, 0xC0, 0x05, + 0xBD, 0x95, 0xC7, 0xCD, 0x73, 0x3B, 0x66, 0x80, 0x64, 0xE3, 0x1A, 0xAC, + 0x2E, 0xF9, 0x47, 0x05, 0xF2, 0x06, 0xB6, 0x9B, 0x73, 0xF5, 0x78, 0x33, + 0x5B, 0xC7, 0xA1, 0xFB, 0x27, 0x2A, 0xA1, 0xB4, 0x9A, 0x91, 0x8C, 0x91, + 0xD3, 0x3A, 0x82, 0x3E, 0x76, 0x40, 0xB4, 0xCD, 0x52, 0x61, 0x51, 0x70, + 0x28, 0x3F, 0xC5, 0xC5, 0x5A, 0xF2, 0xC9, 0x8C, 0x49, 0xBB, 0x14, 0x5B, + 0x4D, 0xC8, 0xFF, 0x67, 0x4D, 0x4C, 0x12, 0x96, 0xAD, 0xF5, 0xFE, 0x78, + 0xA8, 0x97, 0x87, 0xD7, 0xFD, 0x5E, 0x20, 0x80, 0xDC, 0xA1, 0x4B, 0x22, + 0xFB, 0xD4, 0x89, 0xAD, 0xBA, 0xCE, 0x47, 0x97, 0x47, 0x55, 0x7B, 0x8F, + 0x45, 0xC8, 0x67, 0x28, 0x84, 0x95, 0x1C, 0x68, 0x30, 0xEF, 0xEF, 0x49, + 0xE0, 0x35, 0x7B, 0x64, 0xE7, 0x98, 0xB0, 0x94, 0xDA, 0x4D, 0x85, 0x3B, + 0x3E, 0x55, 0xC4, 0x28, 0xAF, 0x57, 0xF3, 0x9E, 0x13, 0xDB, 0x46, 0x27, + 0x9F, 0x1E, 0xA2, 0x5E, 0x44, 0x83, 0xA4, 0xA5, 0xCA, 0xD5, 0x13, 0xB3, + 0x4B, 0x3F, 0xC4, 0xE3, 0xC2, 0xE6, 0x86, 0x61, 0xA4, 0x52, 0x30, 0xB9, + 0x7A, 0x20, 0x4F, 0x6F, 0x0F, 0x38, 0x53, 0xCB, 0x33, 0x0C, 0x13, 0x2B, + 0x8F, 0xD6, 0x9A, 0xBD, 0x2A, 0xC8, 0x2D, 0xB1, 0x1C, 0x7D, 0x4B, 0x51, + 0xCA, 0x47, 0xD1, 0x48, 0x27, 0x72, 0x5D, 0x87, 0xEB, 0xD5, 0x45, 0xE6, + 0x48, 0x65, 0x9D, 0xAF, 0x52, 0x90, 0xBA, 0x5B, 0xA2, 0x18, 0x65, 0x57, + 0x12, 0x9F, 0x68, 0xB9, 0xD4, 0x15, 0x6B, 0x94, 0xC4, 0x69, 0x22, 0x98, + 0xF4, 0x33, 0xE0, 0xED, 0xF9, 0x51, 0x8E, 0x41, 0x50, 0xC9, 0x34, 0x4F, + 0x76, 0x90, 0xAC, 0xFC, 0x38, 0xC1, 0xD8, 0xE1, 0x7B, 0xB9, 0xE3, 0xE3, + 0x94, 0xE1, 0x46, 0x69, 0xCB, 0x0E, 0x0A, 0x50, 0x6B, 0x13, 0xBA, 0xAC, + 0x0F, 0x37, 0x5A, 0xB7, 0x12, 0xB5, 0x90, 0x81, 0x1E, 0x56, 0xAE, 0x57, + 0x22, 0x86, 0xD9, 0xC9, 0xD2, 0xD1, 0xD7, 0x51, 0xE3, 0xAB, 0x3B, 0xC6, + 0x55, 0xFD, 0x1E, 0x0E, 0xD3, 0x74, 0x0A, 0xD1, 0xDA, 0xAA, 0xEA, 0x69, + 0xB8, 0x97, 0x28, 0x8F, 0x48, 0xC4, 0x07, 0xF8, 0x52, 0x43, 0x3A, 0xF4, + 0xCA, 0x55, 0x35, 0x2C, 0xB0, 0xA6, 0x6A, 0xC0, 0x9C, 0xF9, 0xF2, 0x81, + 0xE1, 0x12, 0x6A, 0xC0, 0x45, 0xD9, 0x67, 0xB3, 0xCE, 0xFF, 0x23, 0xA2, + 0x89, 0x0A, 0x54, 0xD4, 0x14, 0xB9, 0x2A, 0xA8, 0xD7, 0xEC, 0xF9, 0xAB, + 0xCD, 0x25, 0x58, 0x32, 0x79, 0x8F, 0x90, 0x5B, 0x98, 0x39, 0xC4, 0x08, + 0x06, 0xC1, 0xAC, 0x7F, 0x0E, 0x3D, 0x00, 0xA5 +}; + +static const unsigned char TA229_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA230_DN[] = { + 0x30, 0x81, 0xB0, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x30, 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x20, 0x69, + 0x73, 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6E, 0x63, 0x65, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x16, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, + 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA230_RSA_N[] = { + 0xB6, 0x95, 0xB6, 0x43, 0x42, 0xFA, 0xC6, 0x6D, 0x2A, 0x6F, 0x48, 0xDF, + 0x94, 0x4C, 0x39, 0x57, 0x05, 0xEE, 0xC3, 0x79, 0x11, 0x41, 0x68, 0x36, + 0xED, 0xEC, 0xFE, 0x9A, 0x01, 0x8F, 0xA1, 0x38, 0x28, 0xFC, 0xF7, 0x10, + 0x46, 0x66, 0x2E, 0x4D, 0x1E, 0x1A, 0xB1, 0x1A, 0x4E, 0xC6, 0xD1, 0xC0, + 0x95, 0x88, 0xB0, 0xC9, 0xFF, 0x31, 0x8B, 0x33, 0x03, 0xDB, 0xB7, 0x83, + 0x7B, 0x3E, 0x20, 0x84, 0x5E, 0xED, 0xB2, 0x56, 0x28, 0xA7, 0xF8, 0xE0, + 0xB9, 0x40, 0x71, 0x37, 0xC5, 0xCB, 0x47, 0x0E, 0x97, 0x2A, 0x68, 0xC0, + 0x22, 0x95, 0x62, 0x15, 0xDB, 0x47, 0xD9, 0xF5, 0xD0, 0x2B, 0xFF, 0x82, + 0x4B, 0xC9, 0xAD, 0x3E, 0xDE, 0x4C, 0xDB, 0x90, 0x80, 0x50, 0x3F, 0x09, + 0x8A, 0x84, 0x00, 0xEC, 0x30, 0x0A, 0x3D, 0x18, 0xCD, 0xFB, 0xFD, 0x2A, + 0x59, 0x9A, 0x23, 0x95, 0x17, 0x2C, 0x45, 0x9E, 0x1F, 0x6E, 0x43, 0x79, + 0x6D, 0x0C, 0x5C, 0x98, 0xFE, 0x48, 0xA7, 0xC5, 0x23, 0x47, 0x5C, 0x5E, + 0xFD, 0x6E, 0xE7, 0x1E, 0xB4, 0xF6, 0x68, 0x45, 0xD1, 0x86, 0x83, 0x5B, + 0xA2, 0x8A, 0x8D, 0xB1, 0xE3, 0x29, 0x80, 0xFE, 0x25, 0x71, 0x88, 0xAD, + 0xBE, 0xBC, 0x8F, 0xAC, 0x52, 0x96, 0x4B, 0xAA, 0x51, 0x8D, 0xE4, 0x13, + 0x31, 0x19, 0xE8, 0x4E, 0x4D, 0x9F, 0xDB, 0xAC, 0xB3, 0x6A, 0xD5, 0xBC, + 0x39, 0x54, 0x71, 0xCA, 0x7A, 0x7A, 0x7F, 0x90, 0xDD, 0x7D, 0x1D, 0x80, + 0xD9, 0x81, 0xBB, 0x59, 0x26, 0xC2, 0x11, 0xFE, 0xE6, 0x93, 0xE2, 0xF7, + 0x80, 0xE4, 0x65, 0xFB, 0x34, 0x37, 0x0E, 0x29, 0x80, 0x70, 0x4D, 0xAF, + 0x38, 0x86, 0x2E, 0x9E, 0x7F, 0x57, 0xAF, 0x9E, 0x17, 0xAE, 0xEB, 0x1C, + 0xCB, 0x28, 0x21, 0x5F, 0xB6, 0x1C, 0xD8, 0xE7, 0xA2, 0x04, 0x22, 0xF9, + 0xD3, 0xDA, 0xD8, 0xCB +}; + +static const unsigned char TA230_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA231_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x31 +}; + +static const unsigned char TA231_RSA_N[] = { + 0xF1, 0x66, 0x08, 0xBD, 0xD9, 0xC5, 0x15, 0x61, 0xCB, 0x84, 0x04, 0x41, + 0xA5, 0x69, 0x37, 0x77, 0x1D, 0xC1, 0xB0, 0x7B, 0xFA, 0xC3, 0x77, 0x48, + 0x90, 0x13, 0x72, 0x64, 0xD1, 0xB8, 0x7C, 0x90, 0x35, 0x9D, 0x18, 0x79, + 0x88, 0xE3, 0x97, 0x01, 0x3C, 0x47, 0x81, 0xF2, 0x0E, 0xA2, 0x98, 0x0D, + 0x9E, 0x3F, 0x37, 0xE0, 0x19, 0xB2, 0x90, 0xF2, 0x46, 0x1C, 0x92, 0xB1, + 0x3A, 0x61, 0xCE, 0xFA, 0xB7, 0x46, 0x9E, 0x03, 0x86, 0xD7, 0x33, 0x6E, + 0xED, 0xF7, 0x45, 0x8C, 0x76, 0x37, 0xDE, 0x6E, 0x96, 0x91, 0xF7, 0xD7, + 0x7E, 0x2B, 0x87, 0x17, 0xD5, 0x8B, 0x35, 0xEE, 0x84, 0x91, 0x72, 0x57, + 0xDC, 0x60, 0xC3, 0xC3, 0xB9, 0xE7, 0xC7, 0x67, 0x24, 0x23, 0x4F, 0x63, + 0x0A, 0x63, 0xF6, 0x66, 0x7D, 0x4B, 0x55, 0xA7, 0x3F, 0x78, 0x64, 0x49, + 0x69, 0x12, 0x97, 0xE0, 0x4C, 0x0D, 0xD3, 0x09, 0xA0, 0x32, 0x30, 0x3A, + 0xFA, 0x9F, 0xC0, 0xF2, 0x9C, 0xC5, 0x12, 0x2A, 0x2E, 0x1C, 0xB5, 0x04, + 0x33, 0xDA, 0xA4, 0x38, 0x11, 0x6A, 0xDE, 0xC6, 0x18, 0xF6, 0x47, 0x3A, + 0x22, 0x41, 0x87, 0x22, 0xFC, 0xC4, 0x89, 0x28, 0x54, 0xD8, 0x8C, 0xA5, + 0x30, 0x0A, 0xF8, 0x17, 0x16, 0xCA, 0xAC, 0x37, 0xFD, 0x79, 0xA7, 0x91, + 0x17, 0x78, 0x38, 0x99, 0xAD, 0x58, 0xED, 0xB2, 0xDE, 0xCC, 0x89, 0x7D, + 0x03, 0x9C, 0xB3, 0x89, 0x65, 0xE7, 0xE3, 0x3B, 0xB1, 0x22, 0x86, 0x8F, + 0x06, 0x6D, 0x78, 0x07, 0xFD, 0x91, 0x12, 0x7F, 0xB0, 0x6B, 0x1C, 0x89, + 0x0D, 0xF9, 0xB8, 0xCB, 0x74, 0x5B, 0x07, 0xC2, 0xC8, 0xF4, 0x35, 0xD1, + 0x64, 0x63, 0x7A, 0xE9, 0x6E, 0x9A, 0x28, 0xD6, 0x30, 0xBD, 0xE6, 0x1B, + 0xDD, 0x15, 0xAF, 0x84, 0xEA, 0x9C, 0xC7, 0xCA, 0xF5, 0x0E, 0xEA, 0xF2, + 0x5D, 0x29, 0x87, 0x8F, 0x69, 0x73, 0x39, 0xBE, 0x2E, 0x24, 0x6F, 0x45, + 0x21, 0xAC, 0xC5, 0xD4, 0x69, 0x25, 0x06, 0x83, 0xAD, 0x7A, 0x48, 0x85, + 0x13, 0x2C, 0x0D, 0x06, 0xB8, 0x6C, 0x79, 0x56, 0xFC, 0xA3, 0x67, 0x32, + 0x81, 0xF5, 0x57, 0xA5, 0xCA, 0x57, 0x42, 0x69, 0xE9, 0x5C, 0x24, 0x61, + 0xEF, 0xE2, 0x30, 0x18, 0x4E, 0x44, 0x98, 0x55, 0x6F, 0x7A, 0xC2, 0x93, + 0xD8, 0x19, 0xB6, 0xDE, 0x7C, 0x47, 0x8A, 0x11, 0x4E, 0x49, 0x47, 0xDB, + 0x28, 0x94, 0x02, 0x0B, 0x94, 0x4A, 0x2C, 0xF9, 0x12, 0xD0, 0x4F, 0xE8, + 0x31, 0x7E, 0x6C, 0x7A, 0xBF, 0xA6, 0x3F, 0x9B, 0x39, 0x3D, 0x02, 0x16, + 0xA3, 0x18, 0xB3, 0x67, 0xAC, 0x5B, 0x3F, 0x2C, 0x83, 0x2B, 0x67, 0x39, + 0x81, 0x5C, 0xB9, 0x7E, 0x94, 0xD5, 0x64, 0xDD, 0x9E, 0x8F, 0x6E, 0xAE, + 0xE8, 0x7C, 0x5B, 0xB4, 0xD7, 0x6A, 0x47, 0x48, 0xD7, 0x7E, 0xB3, 0xD4, + 0x2D, 0x8E, 0x56, 0x76, 0x4E, 0xCF, 0x69, 0xF1, 0x6E, 0x44, 0x6C, 0xD4, + 0x24, 0xEA, 0x8D, 0x24, 0xA1, 0x18, 0xBF, 0xBD, 0x57, 0xFE, 0xA9, 0x99, + 0x35, 0xB5, 0xDB, 0x10, 0x77, 0xB8, 0x3D, 0x48, 0xBA, 0xD6, 0xC1, 0xE7, + 0xF1, 0x23, 0x3E, 0xD7, 0xDF, 0x85, 0x9D, 0x27, 0x3C, 0xD4, 0x40, 0xBD, + 0x0A, 0x0C, 0xBD, 0xF5, 0xE7, 0x8D, 0x25, 0xD6, 0x81, 0x74, 0x87, 0x46, + 0xD4, 0x29, 0x75, 0xA2, 0x42, 0x6C, 0xF7, 0x73, 0x89, 0xE7, 0x7D, 0xBF, + 0x7A, 0x4A, 0x1F, 0xD3, 0x22, 0xC9, 0x15, 0x55, 0xCF, 0xDF, 0x6F, 0x7C, + 0x55, 0xD0, 0xA4, 0x8B, 0x07, 0x11, 0x37, 0x5F, 0x83, 0xA6, 0x26, 0x57, + 0xA6, 0x01, 0x5B, 0x7E, 0xFE, 0x58, 0x68, 0x07, 0xA9, 0xE9, 0x7A, 0xD9, + 0xB9, 0xE8, 0xFF, 0x50, 0x1F, 0xAB, 0xC2, 0xB4, 0xC0, 0xCE, 0xE8, 0xEA, + 0xFD, 0x0F, 0xBD, 0x8D, 0x4D, 0xB8, 0xBC, 0x71 +}; + +static const unsigned char TA231_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA232_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x32 +}; + +static const unsigned char TA232_EC_Q[] = { + 0x04, 0x9D, 0xCB, 0x80, 0x91, 0x8D, 0x53, 0x67, 0xB5, 0xB9, 0x50, 0xB1, + 0x03, 0xF8, 0xE5, 0x49, 0x1F, 0x41, 0x22, 0x09, 0xB0, 0x51, 0x52, 0x58, + 0xD6, 0x2B, 0x34, 0x8F, 0xC5, 0x12, 0x46, 0x14, 0xC5, 0x8B, 0x2F, 0x2C, + 0x84, 0xFF, 0x2C, 0x6E, 0xA8, 0xD5, 0xF1, 0x09, 0xE3, 0x03, 0x21, 0x14, + 0xC4, 0x43, 0x3D, 0x7C, 0xC1, 0x2C, 0xC4, 0x4B, 0x6A, 0x4A, 0xCD, 0xE9, + 0x87, 0xE0, 0x7D, 0xF6, 0x22, 0xBE, 0xFA, 0x4A, 0x51, 0xB8, 0x30, 0x8A, + 0xFD, 0xE1, 0xDE, 0x18, 0x12, 0x0A, 0xF6, 0x47, 0xB7, 0xE7, 0x17, 0xBF, + 0x27, 0x8A, 0xD4, 0x41, 0x4C, 0x96, 0x3C, 0x60, 0x96, 0xC1, 0xFD, 0x15, + 0x1C +}; + +static const unsigned char TA233_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA233_RSA_N[] = { + 0xD7, 0xC7, 0x5E, 0xF7, 0xC1, 0x07, 0xD4, 0x77, 0xFB, 0x43, 0x21, 0xF4, + 0xF4, 0xF5, 0x69, 0xE4, 0xEE, 0x32, 0x01, 0xDB, 0xA3, 0x86, 0x1F, 0xE4, + 0x59, 0x0D, 0xBA, 0xE7, 0x75, 0x83, 0x52, 0xEB, 0xEA, 0x1C, 0x61, 0x15, + 0x48, 0xBB, 0x1D, 0x07, 0xCA, 0x8C, 0xAE, 0xB0, 0xDC, 0x96, 0x9D, 0xEA, + 0xC3, 0x60, 0x92, 0x86, 0x82, 0x28, 0x73, 0x9C, 0x56, 0x06, 0xFF, 0x4B, + 0x64, 0xF0, 0x0C, 0x2A, 0x37, 0x49, 0xB5, 0xE5, 0xCF, 0x0C, 0x7C, 0xEE, + 0xF1, 0x4A, 0xBB, 0x73, 0x30, 0x65, 0xF3, 0xD5, 0x2F, 0x83, 0xB6, 0x7E, + 0xE3, 0xE7, 0xF5, 0x9E, 0xAB, 0x60, 0xF9, 0xD3, 0xF1, 0x9D, 0x92, 0x74, + 0x8A, 0xE4, 0x1C, 0x96, 0xAC, 0x5B, 0x80, 0xE9, 0xB5, 0xF4, 0x31, 0x87, + 0xA3, 0x51, 0xFC, 0xC7, 0x7E, 0xA1, 0x6F, 0x8E, 0x53, 0x77, 0xD4, 0x97, + 0xC1, 0x55, 0x33, 0x92, 0x3E, 0x18, 0x2F, 0x75, 0xD4, 0xAD, 0x86, 0x49, + 0xCB, 0x95, 0xAF, 0x54, 0x06, 0x6C, 0xD8, 0x06, 0x13, 0x8D, 0x5B, 0xFF, + 0xE1, 0x26, 0x19, 0x59, 0xC0, 0x24, 0xBA, 0x81, 0x71, 0x79, 0x90, 0x44, + 0x50, 0x68, 0x24, 0x94, 0x5F, 0xB8, 0xB3, 0x11, 0xF1, 0x29, 0x41, 0x61, + 0xA3, 0x41, 0xCB, 0x23, 0x36, 0xD5, 0xC1, 0xF1, 0x32, 0x50, 0x10, 0x4E, + 0x7F, 0xF4, 0x86, 0x93, 0xEC, 0x84, 0xD3, 0x8E, 0xBC, 0x4B, 0xBF, 0x5C, + 0x01, 0x4E, 0x07, 0x3D, 0xDC, 0x14, 0x8A, 0x94, 0x0A, 0xA4, 0xEA, 0x73, + 0xFB, 0x0B, 0x51, 0xE8, 0x13, 0x07, 0x18, 0xFA, 0x0E, 0xF1, 0x2B, 0xD1, + 0x54, 0x15, 0x7D, 0x3C, 0xE1, 0xF7, 0xB4, 0x19, 0x42, 0x67, 0x62, 0x5E, + 0x77, 0xE0, 0xA2, 0x55, 0xEC, 0xB6, 0xD9, 0x69, 0x17, 0xD5, 0x3A, 0xAF, + 0x44, 0xED, 0x4A, 0xC5, 0x9E, 0xE4, 0x7A, 0x27, 0x7C, 0xE5, 0x75, 0xD7, + 0xAA, 0xCB, 0x25, 0xE7, 0xDF, 0x6B, 0x0A, 0xDB, 0x0F, 0x4D, 0x93, 0x4E, + 0xA8, 0xA0, 0xCD, 0x7B, 0x2E, 0xF2, 0x59, 0x01, 0x6A, 0xB7, 0x0D, 0xB8, + 0x07, 0x81, 0x7E, 0x8B, 0x38, 0x1B, 0x38, 0xE6, 0x0A, 0x57, 0x99, 0x3D, + 0xEE, 0x21, 0xE8, 0xA3, 0xF5, 0x0C, 0x16, 0xDD, 0x8B, 0xEC, 0x34, 0x8E, + 0x9C, 0x2A, 0x1C, 0x00, 0x15, 0x17, 0x8D, 0x68, 0x83, 0xD2, 0x70, 0x9F, + 0x18, 0x08, 0xCD, 0x11, 0x68, 0xD5, 0xC9, 0x6B, 0x52, 0xCD, 0xC4, 0x46, + 0x8F, 0xDC, 0xB5, 0xF3, 0xD8, 0x57, 0x73, 0x1E, 0xE9, 0x94, 0x39, 0x04, + 0xBF, 0xD3, 0xDE, 0x38, 0xDE, 0xB4, 0x53, 0xEC, 0x69, 0x1C, 0xA2, 0x7E, + 0xC4, 0x8F, 0xE4, 0x1B, 0x70, 0xAD, 0xF2, 0xA2, 0xF9, 0xFB, 0xF7, 0x16, + 0x64, 0x66, 0x69, 0x9F, 0x49, 0x51, 0xA2, 0xE2, 0x15, 0x18, 0x67, 0x06, + 0x4A, 0x7F, 0xD5, 0x6C, 0xB5, 0x4D, 0xB3, 0x33, 0xE0, 0x61, 0xEB, 0x5D, + 0xBE, 0xE9, 0x98, 0x0F, 0x32, 0xD7, 0x1D, 0x4B, 0x3C, 0x2E, 0x5A, 0x01, + 0x52, 0x91, 0x09, 0xF2, 0xDF, 0xEA, 0x8D, 0xD8, 0x06, 0x40, 0x63, 0xAA, + 0x11, 0xE4, 0xFE, 0xC3, 0x37, 0x9E, 0x14, 0x52, 0x3F, 0xF4, 0xE2, 0xCC, + 0xF2, 0x61, 0x93, 0xD1, 0xFD, 0x67, 0x6B, 0xD7, 0x52, 0xAE, 0xBF, 0x68, + 0xAB, 0x40, 0x43, 0xA0, 0x57, 0x35, 0x53, 0x78, 0xF0, 0x53, 0xF8, 0x61, + 0x42, 0x07, 0x64, 0xC6, 0xD7, 0x6F, 0x9B, 0x4C, 0x38, 0x0D, 0x63, 0xAC, + 0x62, 0xAF, 0x36, 0x8B, 0xA2, 0x73, 0x0A, 0x0D, 0xF5, 0x21, 0xBD, 0x74, + 0xAA, 0x4D, 0xEA, 0x72, 0x03, 0x49, 0xDB, 0xC7, 0x5F, 0x1D, 0x62, 0x63, + 0xC7, 0xFD, 0xDD, 0x91, 0xEC, 0x33, 0xEE, 0xF5, 0x6D, 0xB4, 0x6E, 0x30, + 0x68, 0xDE, 0xC8, 0xD6, 0x26, 0xB0, 0x75, 0x5E, 0x7B, 0xB4, 0x07, 0x20, + 0x98, 0xA1, 0x76, 0x32, 0xB8, 0x4D, 0x6C, 0x4F +}; + +static const unsigned char TA233_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA234_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA234_RSA_N[] = { + 0xA5, 0xDA, 0x0A, 0x95, 0x16, 0x50, 0xE3, 0x95, 0xF2, 0x5E, 0x9D, 0x76, + 0x31, 0x06, 0x32, 0x7A, 0x9B, 0xF1, 0x10, 0x76, 0xB8, 0x00, 0x9A, 0xB5, + 0x52, 0x36, 0xCD, 0x24, 0x47, 0xB0, 0x9F, 0x18, 0x64, 0xBC, 0x9A, 0xF6, + 0xFA, 0xD5, 0x79, 0xD8, 0x90, 0x62, 0x4C, 0x22, 0x2F, 0xDE, 0x38, 0x3D, + 0xD6, 0xE0, 0xA8, 0xE9, 0x1C, 0x2C, 0xDB, 0x78, 0x11, 0xE9, 0x8E, 0x68, + 0x51, 0x15, 0x72, 0xC7, 0xF3, 0x33, 0x87, 0xE4, 0xA0, 0x5D, 0x0B, 0x5C, + 0xE0, 0x57, 0x07, 0x2A, 0x30, 0xF5, 0xCD, 0xC4, 0x37, 0x77, 0x28, 0x4D, + 0x18, 0x91, 0xE6, 0xBF, 0xD5, 0x52, 0xFD, 0x71, 0x2D, 0x70, 0x3E, 0xE7, + 0xC6, 0xC4, 0x8A, 0xE3, 0xF0, 0x28, 0x0B, 0xF4, 0x76, 0x98, 0xA1, 0x8B, + 0x87, 0x55, 0xB2, 0x3A, 0x13, 0xFC, 0xB7, 0x3E, 0x27, 0x37, 0x8E, 0x22, + 0xE3, 0xA8, 0x4F, 0x2A, 0xEF, 0x60, 0xBB, 0x3D, 0xB7, 0x39, 0xC3, 0x0E, + 0x01, 0x47, 0x99, 0x5D, 0x12, 0x4F, 0xDB, 0x43, 0xFA, 0x57, 0xA1, 0xED, + 0xF9, 0x9D, 0xBE, 0x11, 0x47, 0x26, 0x5B, 0x13, 0x98, 0xAB, 0x5D, 0x16, + 0x8A, 0xB0, 0x37, 0x1C, 0x57, 0x9D, 0x45, 0xFF, 0x88, 0x96, 0x36, 0xBF, + 0xBB, 0xCA, 0x07, 0x7B, 0x6F, 0x87, 0x63, 0xD7, 0xD0, 0x32, 0x6A, 0xD6, + 0x5D, 0x6C, 0x0C, 0xF1, 0xB3, 0x6E, 0x39, 0xE2, 0x6B, 0x31, 0x2E, 0x39, + 0x00, 0x27, 0x14, 0xDE, 0x38, 0xC0, 0xEC, 0x19, 0x66, 0x86, 0x12, 0xE8, + 0x9D, 0x72, 0x16, 0x13, 0x64, 0x52, 0xC7, 0xA9, 0x37, 0x1C, 0xFD, 0x82, + 0x30, 0xED, 0x84, 0x18, 0x1D, 0xF4, 0xAE, 0x5C, 0xFF, 0x70, 0x13, 0x00, + 0xEB, 0xB1, 0xF5, 0x33, 0x7A, 0x4B, 0xD6, 0x55, 0xF8, 0x05, 0x8D, 0x4B, + 0x69, 0xB0, 0xF5, 0xB3, 0x28, 0x36, 0x5C, 0x14, 0xC4, 0x51, 0x73, 0x4D, + 0x6B, 0x0B, 0xF1, 0x34, 0x07, 0xDB, 0x17, 0x39, 0xD7, 0xDC, 0x28, 0x7B, + 0x6B, 0xF5, 0x9F, 0xF3, 0x2E, 0xC1, 0x4F, 0x17, 0x2A, 0x10, 0xF3, 0xCC, + 0xCA, 0xE8, 0xEB, 0xFD, 0x6B, 0xAB, 0x2E, 0x9A, 0x9F, 0x2D, 0x82, 0x6E, + 0x04, 0xD4, 0x52, 0x01, 0x93, 0x2D, 0x3D, 0x86, 0xFC, 0x7E, 0xFC, 0xDF, + 0xEF, 0x42, 0x1D, 0xA6, 0x6B, 0xEF, 0xB9, 0x20, 0xC6, 0xF7, 0xBD, 0xA0, + 0xA7, 0x95, 0xFD, 0xA7, 0xE6, 0x89, 0x24, 0xD8, 0xCC, 0x8C, 0x34, 0x6C, + 0xE2, 0x23, 0x2F, 0xD9, 0x12, 0x1A, 0x21, 0xB9, 0x55, 0x91, 0x6F, 0x0B, + 0x91, 0x79, 0x19, 0x0C, 0xAD, 0x40, 0x88, 0x0B, 0x70, 0xE2, 0x7A, 0xD2, + 0x0E, 0xD8, 0x68, 0x48, 0xBB, 0x82, 0x13, 0x39, 0x10, 0x58, 0xE9, 0xD8, + 0x2A, 0x07, 0xC6, 0x12, 0xDB, 0x58, 0xDB, 0xD2, 0x3B, 0x55, 0x10, 0x47, + 0x05, 0x15, 0x67, 0x62, 0x7E, 0x18, 0x63, 0xA6, 0x46, 0x3F, 0x09, 0x0E, + 0x54, 0x32, 0x5E, 0xBF, 0x0D, 0x62, 0x7A, 0x27, 0xEF, 0x80, 0xE8, 0xDB, + 0xD9, 0x4B, 0x06, 0x5A, 0x37, 0x5A, 0x25, 0xD0, 0x08, 0x12, 0x77, 0xD4, + 0x6F, 0x09, 0x50, 0x97, 0x3D, 0xC8, 0x1D, 0xC3, 0xDF, 0x8C, 0x45, 0x30, + 0x56, 0xC6, 0xD3, 0x64, 0xAB, 0x66, 0xF3, 0xC0, 0x5E, 0x96, 0x9C, 0xC3, + 0xC4, 0xEF, 0xC3, 0x7C, 0x6B, 0x8B, 0x3A, 0x79, 0x7F, 0xB3, 0x49, 0xCF, + 0x3D, 0xE2, 0x89, 0x9F, 0xA0, 0x30, 0x4B, 0x85, 0xB9, 0x9C, 0x94, 0x24, + 0x79, 0x8F, 0x7D, 0x6B, 0xA9, 0x45, 0x68, 0x0F, 0x2B, 0xD0, 0xF1, 0xDA, + 0x1C, 0xCB, 0x69, 0xB8, 0xCA, 0x49, 0x62, 0x6D, 0xC8, 0xD0, 0x63, 0x62, + 0xDD, 0x60, 0x0F, 0x58, 0xAA, 0x8F, 0xA1, 0xBC, 0x05, 0xA5, 0x66, 0xA2, + 0xCF, 0x1B, 0x76, 0xB2, 0x84, 0x64, 0xB1, 0x4C, 0x39, 0x52, 0xC0, 0x30, + 0xBA, 0xF0, 0x8C, 0x4B, 0x02, 0xB0, 0xB6, 0xB7 +}; + +static const unsigned char TA234_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA235_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x1B, + 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x55, 0x43, 0x41, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x47, 0x32, 0x20, 0x52, + 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA235_RSA_N[] = { + 0xC5, 0xE6, 0x2B, 0x6F, 0x7C, 0xEF, 0x26, 0x05, 0x27, 0xA3, 0x81, 0x24, + 0xDA, 0x6F, 0xCB, 0x01, 0xF9, 0x99, 0x9A, 0xA9, 0x32, 0xC2, 0x22, 0x87, + 0x61, 0x41, 0x91, 0x3B, 0xCB, 0xC3, 0x68, 0x1B, 0x06, 0xC5, 0x4C, 0xA9, + 0x2B, 0xC1, 0x67, 0x17, 0x22, 0x1D, 0x2B, 0xED, 0xF9, 0x29, 0x89, 0x93, + 0xA2, 0x78, 0xBD, 0x92, 0x6B, 0xA0, 0xA3, 0x0D, 0xA2, 0x7E, 0xCA, 0x93, + 0xB3, 0xA6, 0xD1, 0x8C, 0x35, 0xD5, 0x75, 0xF9, 0x17, 0xF6, 0xCF, 0x45, + 0xC5, 0xE5, 0x7A, 0xEC, 0x77, 0x93, 0xA0, 0x8F, 0x23, 0xAE, 0x0E, 0x1A, + 0x03, 0x7F, 0xBE, 0xD4, 0xD0, 0xED, 0x2E, 0x7B, 0xAB, 0x46, 0x23, 0x5B, + 0xFF, 0x2C, 0xE6, 0x54, 0x7A, 0x94, 0xC0, 0x2A, 0x15, 0xF0, 0xC9, 0x8D, + 0xB0, 0x7A, 0x3B, 0x24, 0xE1, 0xD7, 0x68, 0xE2, 0x31, 0x3C, 0x06, 0x33, + 0x46, 0xB6, 0x54, 0x11, 0xA6, 0xA5, 0x2F, 0x22, 0x54, 0x2A, 0x58, 0x0D, + 0x01, 0x02, 0xF1, 0xFA, 0x15, 0x51, 0x67, 0x6C, 0xC0, 0xFA, 0xD7, 0xB6, + 0x1B, 0x7F, 0xD1, 0x56, 0x88, 0x2F, 0x1A, 0x3A, 0x8D, 0x3B, 0xBB, 0x82, + 0x11, 0xE0, 0x47, 0x00, 0xD0, 0x52, 0x87, 0xAB, 0xFB, 0x86, 0x7E, 0x0F, + 0x24, 0x6B, 0x40, 0x9D, 0x34, 0x67, 0xBC, 0x8D, 0xC7, 0x2D, 0x86, 0x6F, + 0x79, 0x3E, 0x8E, 0xA9, 0x3C, 0x17, 0x4B, 0x7F, 0xB0, 0x99, 0xE3, 0xB0, + 0x71, 0x60, 0xDC, 0x0B, 0xF5, 0x64, 0xC3, 0xCE, 0x43, 0xBC, 0x6D, 0x71, + 0xB9, 0xD2, 0xDE, 0x27, 0x5B, 0x8A, 0xE8, 0xD8, 0xC6, 0xAE, 0xE1, 0x59, + 0x7D, 0xCF, 0x28, 0x2D, 0x35, 0xB8, 0x95, 0x56, 0x1A, 0xF1, 0xB2, 0x58, + 0x4B, 0xB7, 0x12, 0x37, 0xC8, 0x7C, 0xB3, 0xED, 0x4B, 0x80, 0xE1, 0x8D, + 0xFA, 0x32, 0x23, 0xB6, 0x6F, 0xB7, 0x48, 0x95, 0x08, 0xB1, 0x44, 0x4E, + 0x85, 0x8C, 0x3A, 0x02, 0x54, 0x20, 0x2F, 0xDF, 0xBF, 0x57, 0x4F, 0x3B, + 0x3A, 0x90, 0x21, 0xD7, 0xC1, 0x26, 0x35, 0x54, 0x20, 0xEC, 0xC7, 0x3F, + 0x47, 0xEC, 0xEF, 0x5A, 0xBF, 0x4B, 0x7A, 0xC1, 0xAD, 0x3B, 0x17, 0x50, + 0x5C, 0x62, 0xD8, 0x0F, 0x4B, 0x4A, 0xDC, 0x2B, 0xFA, 0x6E, 0xBC, 0x73, + 0x92, 0xCD, 0xEC, 0xC7, 0x50, 0xE8, 0x41, 0x96, 0xD7, 0xA9, 0x7E, 0x6D, + 0xD8, 0xE9, 0x1D, 0x8F, 0x8A, 0xB5, 0xB9, 0x58, 0x92, 0xBA, 0x4A, 0x92, + 0x2B, 0x0C, 0x56, 0xFD, 0x80, 0xEB, 0x08, 0xF0, 0x5E, 0x29, 0x6E, 0x1B, + 0x1C, 0x0C, 0xAF, 0x8F, 0x93, 0x89, 0xAD, 0xDB, 0xBD, 0xA3, 0x9E, 0x21, + 0xCA, 0x89, 0x19, 0xEC, 0xDF, 0xB5, 0xC3, 0x1A, 0xEB, 0x16, 0xFE, 0x78, + 0x36, 0x4C, 0xD6, 0x6E, 0xD0, 0x3E, 0x17, 0x1C, 0x90, 0x17, 0x6B, 0x26, + 0xBA, 0xFB, 0x7A, 0x2F, 0xBF, 0x11, 0x1C, 0x18, 0x0E, 0x2D, 0x73, 0x03, + 0x8F, 0xA0, 0xE5, 0x35, 0xA0, 0x5A, 0xE2, 0x4C, 0x75, 0x1D, 0x71, 0xE1, + 0x39, 0x38, 0x53, 0x78, 0x40, 0xCC, 0x83, 0x93, 0xD7, 0x0A, 0x9E, 0x9D, + 0x5B, 0x8F, 0x8A, 0xE4, 0xE5, 0xE0, 0x48, 0xE4, 0x48, 0xB2, 0x47, 0xCD, + 0x4E, 0x2A, 0x75, 0x2A, 0x7B, 0xF2, 0x22, 0xF6, 0xC9, 0xBE, 0x09, 0x91, + 0x96, 0x57, 0x7A, 0x88, 0x88, 0xAC, 0xEE, 0x70, 0xAC, 0xF9, 0xDC, 0x29, + 0xE3, 0x0C, 0x1C, 0x3B, 0x12, 0x4E, 0x44, 0xD6, 0xA7, 0x4E, 0xB0, 0x26, + 0xC8, 0xF3, 0xD9, 0x1A, 0x97, 0x91, 0x68, 0xEA, 0xEF, 0x8D, 0x46, 0x06, + 0xD2, 0x56, 0x45, 0x58, 0x9A, 0x3C, 0x0C, 0x0F, 0x83, 0xB8, 0x05, 0x25, + 0xC3, 0x39, 0xCF, 0x3B, 0xA4, 0x34, 0x89, 0xB7, 0x79, 0x12, 0x2F, 0x47, + 0xC5, 0xE7, 0xA9, 0x97, 0x69, 0xFC, 0xA6, 0x77, 0x67, 0xB5, 0xDF, 0x7B, + 0xF1, 0x7A, 0x65, 0x15, 0xE4, 0x61, 0x56, 0x65 +}; + +static const unsigned char TA235_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA236_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x1E, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA236_RSA_N[] = { + 0xD3, 0xB2, 0x4A, 0xCF, 0x7A, 0x47, 0xEF, 0x75, 0x9B, 0x23, 0xFA, 0x3A, + 0x2F, 0xD6, 0x50, 0x45, 0x89, 0x35, 0x3A, 0xC6, 0x6B, 0xDB, 0xFE, 0xDB, + 0x00, 0x68, 0xA8, 0xE0, 0x03, 0x11, 0x1D, 0x37, 0x50, 0x08, 0x9F, 0x4D, + 0x4A, 0x68, 0x94, 0x35, 0xB3, 0x53, 0xD1, 0x94, 0x63, 0xA7, 0x20, 0x56, + 0xAF, 0xDE, 0x51, 0x78, 0xEC, 0x2A, 0x3D, 0xF3, 0x48, 0x48, 0x50, 0x3E, + 0x0A, 0xDF, 0x46, 0x55, 0x8B, 0x27, 0x6D, 0xC3, 0x10, 0x4D, 0x0D, 0x91, + 0x52, 0x43, 0xD8, 0x87, 0xE0, 0x5D, 0x4E, 0x36, 0xB5, 0x21, 0xCA, 0x5F, + 0x39, 0x40, 0x04, 0x5F, 0x5B, 0x7E, 0xCC, 0xA3, 0xC6, 0x2B, 0xA9, 0x40, + 0x1E, 0xD9, 0x36, 0x84, 0xD6, 0x48, 0xF3, 0x92, 0x1E, 0x34, 0x46, 0x20, + 0x24, 0xC1, 0xA4, 0x51, 0x8E, 0x4A, 0x1A, 0xEF, 0x50, 0x3F, 0x69, 0x5D, + 0x19, 0x7F, 0x45, 0xC3, 0xC7, 0x01, 0x8F, 0x51, 0xC9, 0x23, 0xE8, 0x72, + 0xAE, 0xB4, 0xBC, 0x56, 0x09, 0x7F, 0x12, 0xCB, 0x1C, 0xB1, 0xAF, 0x29, + 0x90, 0x0A, 0xC9, 0x55, 0xCC, 0x0F, 0xD3, 0xB4, 0x1A, 0xED, 0x47, 0x35, + 0x5A, 0x4A, 0xED, 0x9C, 0x73, 0x04, 0x21, 0xD0, 0xAA, 0xBD, 0x0C, 0x13, + 0xB5, 0x00, 0xCA, 0x26, 0x6C, 0xC4, 0x6B, 0x0C, 0x94, 0x5A, 0x95, 0x94, + 0xDA, 0x50, 0x9A, 0xF1, 0xFF, 0xA5, 0x2B, 0x66, 0x31, 0xA4, 0xC9, 0x38, + 0xA0, 0xDF, 0x1D, 0x1F, 0xB8, 0x09, 0x2E, 0xF3, 0xA7, 0xE8, 0x67, 0x52, + 0xAB, 0x95, 0x1F, 0xE0, 0x46, 0x3E, 0xD8, 0xA4, 0xC3, 0xCA, 0x5A, 0xC5, + 0x31, 0x80, 0xE8, 0x48, 0x9A, 0x9F, 0x94, 0x69, 0xFE, 0x19, 0xDD, 0xD8, + 0x73, 0x7C, 0x81, 0xCA, 0x96, 0xDE, 0x8E, 0xED, 0xB3, 0x32, 0x05, 0x65, + 0x84, 0x34, 0xE6, 0xE6, 0xFD, 0x57, 0x10, 0xB5, 0x5F, 0x76, 0xBF, 0x2F, + 0xB0, 0x10, 0x0D, 0xC5 +}; + +static const unsigned char TA236_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA237_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x34, 0x30, 0x39, 0x36, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA237_RSA_N[] = { + 0xB3, 0xD0, 0xF4, 0xC9, 0x79, 0x11, 0x9D, 0xFD, 0xFC, 0x66, 0x81, 0xE7, + 0xCC, 0xD5, 0xE4, 0xBC, 0xEC, 0x81, 0x3E, 0x6A, 0x35, 0x8E, 0x2E, 0xB7, + 0xE7, 0xDE, 0xAF, 0xF9, 0x07, 0x4D, 0xCF, 0x30, 0x9D, 0xEA, 0x09, 0x0B, + 0x99, 0xBD, 0x6C, 0x57, 0xDA, 0x18, 0x4A, 0xB8, 0x78, 0xAC, 0x3A, 0x39, + 0xA8, 0xA6, 0x48, 0xAC, 0x2E, 0x72, 0xE5, 0xBD, 0xEB, 0xF1, 0x1A, 0xCD, + 0xE7, 0xA4, 0x03, 0xA9, 0x3F, 0x11, 0xB4, 0xD8, 0x2F, 0x89, 0x16, 0xFB, + 0x94, 0x01, 0x3D, 0xBB, 0x2F, 0xF8, 0x13, 0x05, 0xA1, 0x78, 0x1C, 0x8E, + 0x28, 0xE0, 0x45, 0xE0, 0x83, 0xF4, 0x59, 0x1B, 0x95, 0xB3, 0xAE, 0x7E, + 0x03, 0x45, 0xE5, 0xBE, 0xC2, 0x42, 0xFE, 0xEE, 0xF2, 0x3C, 0xB6, 0x85, + 0x13, 0x98, 0x32, 0x9D, 0x16, 0xA8, 0x29, 0xC2, 0x0B, 0x1C, 0x38, 0xDC, + 0x9F, 0x31, 0x77, 0x5C, 0xBF, 0x27, 0xA3, 0xFC, 0x27, 0xAC, 0xB7, 0x2B, + 0xBD, 0x74, 0x9B, 0x17, 0x2D, 0xF2, 0x81, 0xDA, 0x5D, 0xB0, 0xE1, 0x23, + 0x17, 0x3E, 0x88, 0x4A, 0x12, 0x23, 0xD0, 0xEA, 0xCF, 0x9D, 0xDE, 0x03, + 0x17, 0xB1, 0x42, 0x4A, 0xA0, 0x16, 0x4C, 0xA4, 0x6D, 0x93, 0xE9, 0x3F, + 0x3A, 0xEE, 0x3A, 0x7C, 0x9D, 0x58, 0x9D, 0xF4, 0x4E, 0x8F, 0xFC, 0x3B, + 0x23, 0xC8, 0x6D, 0xB8, 0xE2, 0x05, 0xDA, 0xCC, 0xEB, 0xEC, 0xC3, 0x31, + 0xF4, 0xD7, 0xA7, 0x29, 0x54, 0x80, 0xCF, 0x44, 0x5B, 0x4C, 0x6F, 0x30, + 0x9E, 0xF3, 0xCC, 0xDD, 0x1F, 0x94, 0x43, 0x9D, 0x4D, 0x7F, 0x70, 0x70, + 0x0D, 0xD4, 0x3A, 0xD1, 0x37, 0xF0, 0x6C, 0x9D, 0x9B, 0xC0, 0x14, 0x93, + 0x58, 0xEF, 0xCD, 0x41, 0x38, 0x75, 0xBC, 0x13, 0x03, 0x95, 0x7C, 0x7F, + 0xE3, 0x5C, 0xE9, 0xD5, 0x0D, 0xD5, 0xE2, 0x7C, 0x10, 0x62, 0xAA, 0x6B, + 0xF0, 0x3D, 0x76, 0xF3, 0x3F, 0xA3, 0xE8, 0xB0, 0xC1, 0xFD, 0xEF, 0xAA, + 0x57, 0x4D, 0xAC, 0x86, 0xA7, 0x18, 0xB4, 0x29, 0xC1, 0x2C, 0x0E, 0xBF, + 0x64, 0xBE, 0x29, 0x8C, 0xD8, 0x02, 0x2D, 0xCD, 0x5C, 0x2F, 0xF2, 0x7F, + 0xEF, 0x15, 0xF4, 0x0C, 0x15, 0xAC, 0x0A, 0xB0, 0xF1, 0xD3, 0x0D, 0x4F, + 0x6A, 0x4D, 0x77, 0x97, 0x01, 0xA0, 0xF1, 0x66, 0xB7, 0xB7, 0xCE, 0xEF, + 0xCE, 0xEC, 0xEC, 0xA5, 0x75, 0xCA, 0xAC, 0xE3, 0xE1, 0x63, 0xF7, 0xB8, + 0xA1, 0x04, 0xC8, 0xBC, 0x7B, 0x3F, 0x5D, 0x2D, 0x16, 0x22, 0x56, 0xED, + 0x48, 0x49, 0xFE, 0xA7, 0x2F, 0x79, 0x30, 0x25, 0x9B, 0xBA, 0x6B, 0x2D, + 0x3F, 0x9D, 0x3B, 0xC4, 0x17, 0xE7, 0x1D, 0x2E, 0xFB, 0xF2, 0xCF, 0xA6, + 0xFC, 0xE3, 0x14, 0x2C, 0x96, 0x98, 0x21, 0x8C, 0xB4, 0x91, 0xE9, 0x19, + 0x60, 0x83, 0xF2, 0x30, 0x2B, 0x06, 0x73, 0x50, 0xD5, 0x98, 0x3B, 0x06, + 0xE9, 0xC7, 0x8A, 0x0C, 0x60, 0x8C, 0x28, 0xF8, 0x52, 0x9B, 0x6E, 0xE1, + 0xF6, 0x4D, 0xBB, 0x06, 0x24, 0x9B, 0xD7, 0x2B, 0x26, 0x3F, 0xFD, 0x2A, + 0x2F, 0x71, 0xF5, 0xD6, 0x24, 0xBE, 0x7F, 0x31, 0x9E, 0x0F, 0x6D, 0xE8, + 0x8F, 0x4F, 0x4D, 0xA3, 0x3F, 0xFF, 0x35, 0xEA, 0xDF, 0x49, 0x5E, 0x41, + 0x8F, 0x86, 0xF9, 0xF1, 0x77, 0x79, 0x4B, 0x1B, 0xB4, 0xA3, 0x5E, 0x2F, + 0xFB, 0x46, 0x02, 0xD0, 0x66, 0x13, 0x5E, 0x5E, 0x85, 0x4F, 0xCE, 0xD8, + 0x70, 0x88, 0x7B, 0xCE, 0x01, 0xB5, 0x96, 0x97, 0xD7, 0xCD, 0x7D, 0xFD, + 0x82, 0xF8, 0xC2, 0x24, 0xC1, 0xCA, 0x01, 0x39, 0x4F, 0x8D, 0xA2, 0xC1, + 0x14, 0x40, 0x1F, 0x9C, 0x66, 0xD5, 0x0C, 0x09, 0x46, 0xD6, 0xF2, 0xD0, + 0xD1, 0x48, 0x76, 0x56, 0x3A, 0x43, 0xCB, 0xB6, 0x0A, 0x11, 0x39, 0xBA, + 0x8C, 0x13, 0x6C, 0x06, 0xB5, 0x9E, 0xCF, 0xEB +}; + +static const unsigned char TA237_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA238_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA238_EC_Q[] = { + 0x04, 0x19, 0xE7, 0xBC, 0xAC, 0x44, 0x65, 0xED, 0xCD, 0xB8, 0x3F, 0x58, + 0xFB, 0x8D, 0xB1, 0x57, 0xA9, 0x44, 0x2D, 0x05, 0x15, 0xF2, 0xEF, 0x0B, + 0xFF, 0x10, 0x74, 0x9F, 0xB5, 0x62, 0x52, 0x5F, 0x66, 0x7E, 0x1F, 0xE5, + 0xDC, 0x1B, 0x45, 0x79, 0x0B, 0xCC, 0xC6, 0x53, 0x0A, 0x9D, 0x8D, 0x5D, + 0x02, 0xD9, 0xA9, 0x59, 0xDE, 0x02, 0x5A, 0xF6, 0x95, 0x2A, 0x0E, 0x8D, + 0x38, 0x4A, 0x8A, 0x49, 0xC6, 0xBC, 0xC6, 0x03, 0x38, 0x07, 0x5F, 0x55, + 0xDA, 0x7E, 0x09, 0x6E, 0xE2, 0x7F, 0x5E, 0xD0, 0x45, 0x20, 0x0F, 0x59, + 0x76, 0x10, 0xD6, 0xA0, 0x24, 0xF0, 0x2D, 0xDE, 0x36, 0xF2, 0x6C, 0x29, + 0x39 +}; + +static const unsigned char TA239_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA239_RSA_N[] = { + 0xCE, 0xDE, 0xFD, 0xA6, 0xFB, 0xEC, 0xEC, 0x14, 0x34, 0x3C, 0x07, 0x06, + 0x5A, 0x6C, 0x59, 0xF7, 0x19, 0x35, 0xDD, 0xF7, 0xC1, 0x9D, 0x55, 0xAA, + 0xD3, 0xCD, 0x3B, 0xA4, 0x93, 0x72, 0xEF, 0x0A, 0xFA, 0x6D, 0x9D, 0xF6, + 0xF0, 0x85, 0x80, 0x5B, 0xA1, 0x48, 0x52, 0x9F, 0x39, 0xC5, 0xB7, 0xEE, + 0x28, 0xAC, 0xEF, 0xCB, 0x76, 0x68, 0x14, 0xB9, 0xDF, 0xAD, 0x01, 0x6C, + 0x99, 0x1F, 0xC4, 0x22, 0x1D, 0x9F, 0xFE, 0x72, 0x77, 0xE0, 0x2C, 0x5B, + 0xAF, 0xE4, 0x04, 0xBF, 0x4F, 0x72, 0xA0, 0x1A, 0x34, 0x98, 0xE8, 0x39, + 0x68, 0xEC, 0x95, 0x25, 0x7B, 0x76, 0xA1, 0xE6, 0x69, 0xB9, 0x85, 0x19, + 0xBD, 0x89, 0x8C, 0xFE, 0xAD, 0xED, 0x36, 0xEA, 0x73, 0xBC, 0xFF, 0x83, + 0xE2, 0xCB, 0x7D, 0xC1, 0xD2, 0xCE, 0x4A, 0xB3, 0x8D, 0x05, 0x9E, 0x8B, + 0x49, 0x93, 0xDF, 0xC1, 0x5B, 0xD0, 0x6E, 0x5E, 0xF0, 0x2E, 0x30, 0x2E, + 0x82, 0xFC, 0xFA, 0xBC, 0xB4, 0x17, 0x0A, 0x48, 0xE5, 0x88, 0x9B, 0xC5, + 0x9B, 0x6B, 0xDE, 0xB0, 0xCA, 0xB4, 0x03, 0xF0, 0xDA, 0xF4, 0x90, 0xB8, + 0x65, 0x64, 0xF7, 0x5C, 0x4C, 0xAD, 0xE8, 0x7E, 0x66, 0x5E, 0x99, 0xD7, + 0xB8, 0xC2, 0x3E, 0xC8, 0xD0, 0x13, 0x9D, 0xAD, 0xEE, 0xE4, 0x45, 0x7B, + 0x89, 0x55, 0xF7, 0x8A, 0x1F, 0x62, 0x52, 0x84, 0x12, 0xB3, 0xC2, 0x40, + 0x97, 0xE3, 0x8A, 0x1F, 0x47, 0x91, 0xA6, 0x74, 0x5A, 0xD2, 0xF8, 0xB1, + 0x63, 0x28, 0x10, 0xB8, 0xB3, 0x09, 0xB8, 0x56, 0x77, 0x40, 0xA2, 0x26, + 0x98, 0x79, 0xC6, 0xFE, 0xDF, 0x25, 0xEE, 0x3E, 0xE5, 0xA0, 0x7F, 0xD4, + 0x61, 0x0F, 0x51, 0x4B, 0x3C, 0x3F, 0x8C, 0xDA, 0xE1, 0x70, 0x74, 0xD8, + 0xC2, 0x68, 0xA1, 0xF9, 0xC1, 0x0C, 0xE9, 0xA1, 0xE2, 0x7F, 0xBB, 0x55, + 0x3C, 0x76, 0x06, 0xEE, 0x6A, 0x4E, 0xCC, 0x92, 0x88, 0x30, 0x4D, 0x9A, + 0xBD, 0x4F, 0x0B, 0x48, 0x9A, 0x84, 0xB5, 0x98, 0xA3, 0xD5, 0xFB, 0x73, + 0xC1, 0x57, 0x61, 0xDD, 0x28, 0x56, 0x75, 0x13, 0xAE, 0x87, 0x8E, 0xE7, + 0x0C, 0x51, 0x09, 0x10, 0x75, 0x88, 0x4C, 0xBC, 0x8D, 0xF9, 0x7B, 0x3C, + 0xD4, 0x22, 0x48, 0x1F, 0x2A, 0xDC, 0xEB, 0x6B, 0xBB, 0x44, 0xB1, 0xCB, + 0x33, 0x71, 0x32, 0x46, 0xAF, 0xAD, 0x4A, 0xF1, 0x8C, 0xE8, 0x74, 0x3A, + 0xAC, 0xE7, 0x1A, 0x22, 0x73, 0x80, 0xD2, 0x30, 0xF7, 0x25, 0x42, 0xC7, + 0x22, 0x3B, 0x3B, 0x12, 0xAD, 0x96, 0x2E, 0xC6, 0xC3, 0x76, 0x07, 0xAA, + 0x20, 0xB7, 0x35, 0x49, 0x57, 0xE9, 0x92, 0x49, 0xE8, 0x76, 0x16, 0x72, + 0x31, 0x67, 0x2B, 0x96, 0x7E, 0x8A, 0xA3, 0xC7, 0x94, 0x56, 0x22, 0xBF, + 0x6A, 0x4B, 0x7E, 0x01, 0x21, 0xB2, 0x23, 0x32, 0xDF, 0xE4, 0x9A, 0x44, + 0x6D, 0x59, 0x5B, 0x5D, 0xF5, 0x00, 0xA0, 0x1C, 0x9B, 0xC6, 0x78, 0x97, + 0x8D, 0x90, 0xFF, 0x9B, 0xC8, 0xAA, 0xB4, 0xAF, 0x11, 0x51, 0x39, 0x5E, + 0xD9, 0xFB, 0x67, 0xAD, 0xD5, 0x5B, 0x11, 0x9D, 0x32, 0x9A, 0x1B, 0xBD, + 0xD5, 0xBA, 0x5B, 0xA5, 0xC9, 0xCB, 0x25, 0x69, 0x53, 0x55, 0x27, 0x5C, + 0xE0, 0xCA, 0x36, 0xCB, 0x88, 0x61, 0xFB, 0x1E, 0xB7, 0xD0, 0xCB, 0xEE, + 0x16, 0xFB, 0xD3, 0xA6, 0x4C, 0xDE, 0x92, 0xA5, 0xD4, 0xE2, 0xDF, 0xF5, + 0x06, 0x54, 0xDE, 0x2E, 0x9D, 0x4B, 0xB4, 0x93, 0x30, 0xAA, 0x81, 0xCE, + 0xDD, 0x1A, 0xDC, 0x51, 0x73, 0x0D, 0x4F, 0x70, 0xE9, 0xE5, 0xB6, 0x16, + 0x21, 0x19, 0x79, 0xB2, 0xE6, 0x89, 0x0B, 0x75, 0x64, 0xCA, 0xD5, 0xAB, + 0xBC, 0x09, 0xC1, 0x18, 0xA1, 0xFF, 0xD4, 0x54, 0xA1, 0x85, 0x3C, 0xFD, + 0x14, 0x24, 0x03, 0xB2, 0x87, 0xD3, 0xA4, 0xB7 +}; + +static const unsigned char TA239_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA240_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x43, 0x41, 0x31 +}; + +static const unsigned char TA240_EC_Q[] = { + 0x04, 0xA4, 0xA5, 0x6F, 0x60, 0x03, 0x03, 0xC3, 0xBD, 0x31, 0xF4, 0xD3, + 0x17, 0x9C, 0x2B, 0x84, 0x75, 0xAC, 0xE5, 0xFD, 0x3D, 0x57, 0x6E, 0xD7, + 0x63, 0xBF, 0xE6, 0x04, 0x89, 0x92, 0x8E, 0x81, 0x9C, 0xE3, 0xE9, 0x47, + 0x6E, 0xCA, 0x90, 0x12, 0xC8, 0x13, 0xE0, 0xA7, 0x9D, 0xF7, 0x65, 0x74, + 0x1F, 0x6C, 0x10, 0xB2, 0xE8, 0xE4, 0xE9, 0xEF, 0x6D, 0x85, 0x32, 0x99, + 0x44, 0xB1, 0x5E, 0xFD, 0xCC, 0x76, 0x10, 0xD8, 0x5B, 0xBD, 0xA2, 0xC6, + 0xF9, 0xD6, 0x42, 0xE4, 0x57, 0x76, 0xDC, 0x90, 0xC2, 0x35, 0xA9, 0x4B, + 0x88, 0x3C, 0x12, 0x47, 0x6D, 0x5C, 0xFF, 0x49, 0x4F, 0x1A, 0x4A, 0x50, + 0xB1 +}; + +static const unsigned char TA241_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x32 +}; + +static const unsigned char TA241_RSA_N[] = { + 0xBB, 0x37, 0xCD, 0x34, 0xDC, 0x7B, 0x6B, 0xC9, 0xB2, 0x68, 0x90, 0xAD, + 0x4A, 0x75, 0xFF, 0x46, 0xBA, 0x21, 0x0A, 0x08, 0x8D, 0xF5, 0x19, 0x54, + 0xC9, 0xFB, 0x88, 0xDB, 0xF3, 0xAE, 0xF2, 0x3A, 0x89, 0x91, 0x3C, 0x7A, + 0xE6, 0xAB, 0x06, 0x1A, 0x6B, 0xCF, 0xAC, 0x2D, 0xE8, 0x5E, 0x09, 0x24, + 0x44, 0xBA, 0x62, 0x9A, 0x7E, 0xD6, 0xA3, 0xA8, 0x7E, 0xE0, 0x54, 0x75, + 0x20, 0x05, 0xAC, 0x50, 0xB7, 0x9C, 0x63, 0x1A, 0x6C, 0x30, 0xDC, 0xDA, + 0x1F, 0x19, 0xB1, 0xD7, 0x1E, 0xDE, 0xFD, 0xD7, 0xE0, 0xCB, 0x94, 0x83, + 0x37, 0xAE, 0xEC, 0x1F, 0x43, 0x4E, 0xDD, 0x7B, 0x2C, 0xD2, 0xBD, 0x2E, + 0xA5, 0x2F, 0xE4, 0xA9, 0xB8, 0xAD, 0x3A, 0xD4, 0x99, 0xA4, 0xB6, 0x25, + 0xE9, 0x9B, 0x6B, 0x00, 0x60, 0x92, 0x60, 0xFF, 0x4F, 0x21, 0x49, 0x18, + 0xF7, 0x67, 0x90, 0xAB, 0x61, 0x06, 0x9C, 0x8F, 0xF2, 0xBA, 0xE9, 0xB4, + 0xE9, 0x92, 0x32, 0x6B, 0xB5, 0xF3, 0x57, 0xE8, 0x5D, 0x1B, 0xCD, 0x8C, + 0x1D, 0xAB, 0x95, 0x04, 0x95, 0x49, 0xF3, 0x35, 0x2D, 0x96, 0xE3, 0x49, + 0x6D, 0xDD, 0x77, 0xE3, 0xFB, 0x49, 0x4B, 0xB4, 0xAC, 0x55, 0x07, 0xA9, + 0x8F, 0x95, 0xB3, 0xB4, 0x23, 0xBB, 0x4C, 0x6D, 0x45, 0xF0, 0xF6, 0xA9, + 0xB2, 0x95, 0x30, 0xB4, 0xFD, 0x4C, 0x55, 0x8C, 0x27, 0x4A, 0x57, 0x14, + 0x7C, 0x82, 0x9D, 0xCD, 0x73, 0x92, 0xD3, 0x16, 0x4A, 0x06, 0x0C, 0x8C, + 0x50, 0xD1, 0x8F, 0x1E, 0x09, 0xBE, 0x17, 0xA1, 0xE6, 0x21, 0xCA, 0xFD, + 0x83, 0xE5, 0x10, 0xBC, 0x83, 0xA5, 0x0A, 0xC4, 0x67, 0x28, 0xF6, 0x73, + 0x14, 0x14, 0x3D, 0x46, 0x76, 0xC3, 0x87, 0x14, 0x89, 0x21, 0x34, 0x4D, + 0xAF, 0x0F, 0x45, 0x0C, 0xA6, 0x49, 0xA1, 0xBA, 0xBB, 0x9C, 0xC5, 0xB1, + 0x33, 0x83, 0x29, 0x85 +}; + +static const unsigned char TA241_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA242_DN[] = { + 0x30, 0x5E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x21, 0x65, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA242_RSA_N[] = { + 0xE1, 0x25, 0x0F, 0xEE, 0x8D, 0xDB, 0x88, 0x33, 0x75, 0x67, 0xCD, 0xAD, + 0x1F, 0x7D, 0x3A, 0x4E, 0x6D, 0x9D, 0xD3, 0x2F, 0x14, 0xF3, 0x63, 0x74, + 0xCB, 0x01, 0x21, 0x6A, 0x37, 0xEA, 0x84, 0x50, 0x07, 0x4B, 0x26, 0x5B, + 0x09, 0x43, 0x6C, 0x21, 0x9E, 0x6A, 0xC8, 0xD5, 0x03, 0xF5, 0x60, 0x69, + 0x8F, 0xCC, 0xF0, 0x22, 0xE4, 0x1F, 0xE7, 0xF7, 0x6A, 0x22, 0x31, 0xB7, + 0x2C, 0x15, 0xF2, 0xE0, 0xFE, 0x00, 0x6A, 0x43, 0xFF, 0x87, 0x65, 0xC6, + 0xB5, 0x1A, 0xC1, 0xA7, 0x4C, 0x6D, 0x22, 0x70, 0x21, 0x8A, 0x31, 0xF2, + 0x97, 0x74, 0x89, 0x09, 0x12, 0x26, 0x1C, 0x9E, 0xCA, 0xD9, 0x12, 0xA2, + 0x95, 0x3C, 0xDA, 0xE9, 0x67, 0xBF, 0x08, 0xA0, 0x64, 0xE3, 0xD6, 0x42, + 0xB7, 0x45, 0xEF, 0x97, 0xF4, 0xF6, 0xF5, 0xD7, 0xB5, 0x4A, 0x15, 0x02, + 0x58, 0x7D, 0x98, 0x58, 0x4B, 0x60, 0xBC, 0xCD, 0xD7, 0x0D, 0x9A, 0x13, + 0x33, 0x53, 0xD1, 0x61, 0xF9, 0x7A, 0xD5, 0xD7, 0x78, 0xB3, 0x9A, 0x33, + 0xF7, 0x00, 0x86, 0xCE, 0x1D, 0x4D, 0x94, 0x38, 0xAF, 0xA8, 0xEC, 0x78, + 0x51, 0x70, 0x8A, 0x5C, 0x10, 0x83, 0x51, 0x21, 0xF7, 0x11, 0x3D, 0x34, + 0x86, 0x5E, 0xE5, 0x48, 0xCD, 0x97, 0x81, 0x82, 0x35, 0x4C, 0x19, 0xEC, + 0x65, 0xF6, 0x6B, 0xC5, 0x05, 0xA1, 0xEE, 0x47, 0x13, 0xD6, 0xB3, 0x21, + 0x27, 0x94, 0x10, 0x0A, 0xD9, 0x24, 0x3B, 0xBA, 0xBE, 0x44, 0x13, 0x46, + 0x30, 0x3F, 0x97, 0x3C, 0xD8, 0xD7, 0xD7, 0x6A, 0xEE, 0x3B, 0x38, 0xE3, + 0x2B, 0xD4, 0x97, 0x0E, 0xB9, 0x1B, 0xE7, 0x07, 0x49, 0x7F, 0x37, 0x2A, + 0xF9, 0x77, 0x78, 0xCF, 0x54, 0xED, 0x5B, 0x46, 0x9D, 0xA3, 0x80, 0x0E, + 0x91, 0x43, 0xC1, 0xD6, 0x5B, 0x5F, 0x14, 0xBA, 0x9F, 0xA6, 0x8D, 0x24, + 0x47, 0x40, 0x59, 0xBF, 0x72, 0x38, 0xB2, 0x36, 0x6C, 0x37, 0xFF, 0x99, + 0xD1, 0x5D, 0x0E, 0x59, 0x0A, 0xAB, 0x69, 0xF7, 0xC0, 0xB2, 0x04, 0x45, + 0x7A, 0x54, 0x00, 0xAE, 0xBE, 0x53, 0xF6, 0xB5, 0xE7, 0xE1, 0xF8, 0x3C, + 0xA3, 0x31, 0xD2, 0xA9, 0xFE, 0x21, 0x52, 0x64, 0xC5, 0xA6, 0x67, 0xF0, + 0x75, 0x07, 0x06, 0x94, 0x14, 0x81, 0x55, 0xC6, 0x27, 0xE4, 0x01, 0x8F, + 0x17, 0xC1, 0x6A, 0x71, 0xD7, 0xBE, 0x4B, 0xFB, 0x94, 0x58, 0x7D, 0x7E, + 0x11, 0x33, 0xB1, 0x42, 0xF7, 0x62, 0x6C, 0x18, 0xD6, 0xCF, 0x09, 0x68, + 0x3E, 0x7F, 0x6C, 0xF6, 0x1E, 0x8F, 0x62, 0xAD, 0xA5, 0x63, 0xDB, 0x09, + 0xA7, 0x1F, 0x22, 0x42, 0x41, 0x1E, 0x6F, 0x99, 0x8A, 0x3E, 0xD7, 0xF9, + 0x3F, 0x40, 0x7A, 0x79, 0xB0, 0xA5, 0x01, 0x92, 0xD2, 0x9D, 0x3D, 0x08, + 0x15, 0xA5, 0x10, 0x01, 0x2D, 0xB3, 0x32, 0x76, 0xA8, 0x95, 0x0D, 0xB3, + 0x7A, 0x9A, 0xFB, 0x07, 0x10, 0x78, 0x11, 0x6F, 0xE1, 0x8F, 0xC7, 0xBA, + 0x0F, 0x25, 0x1A, 0x74, 0x2A, 0xE5, 0x1C, 0x98, 0x41, 0x99, 0xDF, 0x21, + 0x87, 0xE8, 0x95, 0x06, 0x6A, 0x0A, 0xB3, 0x6A, 0x47, 0x76, 0x65, 0xF6, + 0x3A, 0xCF, 0x8F, 0x62, 0x17, 0x19, 0x7B, 0x0A, 0x28, 0xCD, 0x1A, 0xD2, + 0x83, 0x1E, 0x21, 0xC7, 0x2C, 0xBF, 0xBE, 0xFF, 0x61, 0x68, 0xB7, 0x67, + 0x1B, 0xBB, 0x78, 0x4D, 0x8D, 0xCE, 0x67, 0xE5, 0xE4, 0xC1, 0x8E, 0xB7, + 0x23, 0x66, 0xE2, 0x9D, 0x90, 0x75, 0x34, 0x98, 0xA9, 0x36, 0x2B, 0x8A, + 0x9A, 0x94, 0xB9, 0x9D, 0xEC, 0xCC, 0x8A, 0xB1, 0xF8, 0x25, 0x89, 0x5C, + 0x5A, 0xB6, 0x2F, 0x8C, 0x1F, 0x6D, 0x79, 0x24, 0xA7, 0x52, 0x68, 0xC3, + 0x84, 0x35, 0xE2, 0x66, 0x8D, 0x63, 0x0E, 0x25, 0x4D, 0xD5, 0x19, 0xB2, + 0xE6, 0x79, 0x37, 0xA7, 0x22, 0x9D, 0x54, 0x31 +}; + +static const unsigned char TA242_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA243_DN[] = { + 0x30, 0x42, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x09, 0x41, 0x43, 0x43, 0x56, 0x52, 0x41, 0x49, 0x5A, 0x31, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x50, 0x4B, 0x49, + 0x41, 0x43, 0x43, 0x56, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x04, 0x41, 0x43, 0x43, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53 +}; + +static const unsigned char TA243_RSA_N[] = { + 0x9B, 0xA9, 0xAB, 0xBF, 0x61, 0x4A, 0x97, 0xAF, 0x2F, 0x97, 0x66, 0x9A, + 0x74, 0x5F, 0xD0, 0xD9, 0x96, 0xFD, 0xCF, 0xE2, 0xE4, 0x66, 0xEF, 0x1F, + 0x1F, 0x47, 0x33, 0xC2, 0x44, 0xA3, 0xDF, 0x9A, 0xDE, 0x1F, 0xB5, 0x54, + 0xDD, 0x15, 0x7C, 0x69, 0x35, 0x11, 0x6F, 0xBB, 0xC8, 0x0C, 0x8E, 0x6A, + 0x18, 0x1E, 0xD8, 0x8F, 0xD9, 0x16, 0xBC, 0x10, 0x48, 0x36, 0x5C, 0xF0, + 0x63, 0xB3, 0x90, 0x5A, 0x5C, 0x24, 0x37, 0xD7, 0xA3, 0xD6, 0xCB, 0x09, + 0x71, 0xB9, 0xF1, 0x01, 0x72, 0x84, 0xB0, 0x7D, 0xDB, 0x4D, 0x80, 0xCD, + 0xFC, 0xD3, 0x6F, 0xC9, 0xF8, 0xDA, 0xB6, 0x0E, 0x82, 0xD2, 0x45, 0x85, + 0xA8, 0x1B, 0x68, 0xA8, 0x3D, 0xE8, 0xF4, 0x44, 0x6C, 0xBD, 0xA1, 0xC2, + 0xCB, 0x03, 0xBE, 0x8C, 0x3E, 0x13, 0x00, 0x84, 0xDF, 0x4A, 0x48, 0xC0, + 0xE3, 0x22, 0x0A, 0xE8, 0xE9, 0x37, 0xA7, 0x18, 0x4C, 0xB1, 0x09, 0x0D, + 0x23, 0x56, 0x7F, 0x04, 0x4D, 0xD9, 0x17, 0x84, 0x18, 0xA5, 0xC8, 0xDA, + 0x40, 0x94, 0x73, 0xEB, 0xCE, 0x0E, 0x57, 0x3C, 0x03, 0x81, 0x3A, 0x9D, + 0x0A, 0xA1, 0x57, 0x43, 0x69, 0xAC, 0x57, 0x6D, 0x79, 0x90, 0x78, 0xE5, + 0xB5, 0xB4, 0x3B, 0xD8, 0xBC, 0x4C, 0x8D, 0x28, 0xA1, 0xA7, 0xA3, 0xA7, + 0xBA, 0x02, 0x4E, 0x25, 0xD1, 0x2A, 0xAE, 0xED, 0xAE, 0x03, 0x22, 0xB8, + 0x6B, 0x20, 0x0F, 0x30, 0x28, 0x54, 0x95, 0x7F, 0xE0, 0xEE, 0xCE, 0x0A, + 0x66, 0x9D, 0xD1, 0x40, 0x2D, 0x6E, 0x22, 0xAF, 0x9D, 0x1A, 0xC1, 0x05, + 0x19, 0xD2, 0x6F, 0xC0, 0xF2, 0x9F, 0xF8, 0x7B, 0xB3, 0x02, 0x42, 0xFB, + 0x50, 0xA9, 0x1D, 0x2D, 0x93, 0x0F, 0x23, 0xAB, 0xC6, 0xC1, 0x0F, 0x92, + 0xFF, 0xD0, 0xA2, 0x15, 0xF5, 0x53, 0x09, 0x71, 0x1C, 0xFF, 0x45, 0x13, + 0x84, 0xE6, 0x26, 0x5E, 0xF8, 0xE0, 0x88, 0x1C, 0x0A, 0xFC, 0x16, 0xB6, + 0xA8, 0x73, 0x06, 0xB8, 0xF0, 0x63, 0x84, 0x02, 0xA0, 0xC6, 0x5A, 0xEC, + 0xE7, 0x74, 0xDF, 0x70, 0xAE, 0xA3, 0x83, 0x25, 0xEA, 0xD6, 0xC7, 0x97, + 0x87, 0x93, 0xA7, 0xC6, 0x8A, 0x8A, 0x33, 0x97, 0x60, 0x37, 0x10, 0x3E, + 0x97, 0x3E, 0x6E, 0x29, 0x15, 0xD6, 0xA1, 0x0F, 0xD1, 0x88, 0x2C, 0x12, + 0x9F, 0x6F, 0xAA, 0xA4, 0xC6, 0x42, 0xEB, 0x41, 0xA2, 0xE3, 0x95, 0x43, + 0xD3, 0x01, 0x85, 0x6D, 0x8E, 0xBB, 0x3B, 0xF3, 0x23, 0x36, 0xC7, 0xFE, + 0x3B, 0xE0, 0xA1, 0x25, 0x07, 0x48, 0xAB, 0xC9, 0x89, 0x74, 0xFF, 0x08, + 0x8F, 0x80, 0xBF, 0xC0, 0x96, 0x65, 0xF3, 0xEE, 0xEC, 0x4B, 0x68, 0xBD, + 0x9D, 0x88, 0xC3, 0x31, 0xB3, 0x40, 0xF1, 0xE8, 0xCF, 0xF6, 0x38, 0xBB, + 0x9C, 0xE4, 0xD1, 0x7F, 0xD4, 0xE5, 0x58, 0x9B, 0x7C, 0xFA, 0xD4, 0xF3, + 0x0E, 0x9B, 0x75, 0x91, 0xE4, 0xBA, 0x52, 0x2E, 0x19, 0x7E, 0xD1, 0xF5, + 0xCD, 0x5A, 0x19, 0xFC, 0xBA, 0x06, 0xF6, 0xFB, 0x52, 0xA8, 0x4B, 0x99, + 0x04, 0xDD, 0xF8, 0xF9, 0xB4, 0x8B, 0x50, 0xA3, 0x4E, 0x62, 0x89, 0xF0, + 0x87, 0x24, 0xFA, 0x83, 0x42, 0xC1, 0x87, 0xFA, 0xD5, 0x2D, 0x29, 0x2A, + 0x5A, 0x71, 0x7A, 0x64, 0x6A, 0xD7, 0x27, 0x60, 0x63, 0x0D, 0xDB, 0xCE, + 0x49, 0xF5, 0x8D, 0x1F, 0x90, 0x89, 0x32, 0x17, 0xF8, 0x73, 0x43, 0xB8, + 0xD2, 0x5A, 0x93, 0x86, 0x61, 0xD6, 0xE1, 0x75, 0x0A, 0xEA, 0x79, 0x66, + 0x76, 0x88, 0x4F, 0x71, 0xEB, 0x04, 0x25, 0xD6, 0x0A, 0x5A, 0x7A, 0x93, + 0xE5, 0xB9, 0x4B, 0x17, 0x40, 0x0F, 0xB1, 0xB6, 0xB9, 0xF5, 0xDE, 0x4F, + 0xDC, 0xE0, 0xB3, 0xAC, 0x3B, 0x11, 0x70, 0x60, 0x84, 0x4A, 0x43, 0x6E, + 0x99, 0x20, 0xC0, 0x29, 0x71, 0x0A, 0xC0, 0x65 +}; + +static const unsigned char TA243_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA244_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x41, 0x43, 0x20, + 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, + 0x4D +}; + +static const unsigned char TA244_RSA_N[] = { + 0xBA, 0x71, 0x80, 0x7A, 0x4C, 0x86, 0x6E, 0x7F, 0xC8, 0x13, 0x6D, 0xC0, + 0xC6, 0x7D, 0x1C, 0x00, 0x97, 0x8F, 0x2C, 0x0C, 0x23, 0xBB, 0x10, 0x9A, + 0x40, 0xA9, 0x1A, 0xB7, 0x87, 0x88, 0xF8, 0x9B, 0x56, 0x6A, 0xFB, 0xE6, + 0x7B, 0x8E, 0x8B, 0x92, 0x8E, 0xA7, 0x25, 0x5D, 0x59, 0x11, 0xDB, 0x36, + 0x2E, 0xB7, 0x51, 0x17, 0x1F, 0xA9, 0x08, 0x1F, 0x04, 0x17, 0x24, 0x58, + 0xAA, 0x37, 0x4A, 0x18, 0xDF, 0xE5, 0x39, 0xD4, 0x57, 0xFD, 0xD7, 0xC1, + 0x2C, 0x91, 0x01, 0x91, 0xE2, 0x22, 0xD4, 0x03, 0xC0, 0x58, 0xFC, 0x77, + 0x47, 0xEC, 0x8F, 0x3E, 0x74, 0x43, 0xBA, 0xAC, 0x34, 0x8D, 0x4D, 0x38, + 0x76, 0x67, 0x8E, 0xB0, 0xC8, 0x6F, 0x30, 0x33, 0x58, 0x71, 0x5C, 0xB4, + 0xF5, 0x6B, 0x6E, 0xD4, 0x01, 0x50, 0xB8, 0x13, 0x7E, 0x6C, 0x4A, 0xA3, + 0x49, 0xD1, 0x20, 0x19, 0xEE, 0xBC, 0xC0, 0x29, 0x18, 0x65, 0xA7, 0xDE, + 0xFE, 0xEF, 0xDD, 0x0A, 0x90, 0x21, 0xE7, 0x1A, 0x67, 0x92, 0x42, 0x10, + 0x98, 0x5F, 0x4F, 0x30, 0xBC, 0x3E, 0x1C, 0x45, 0xB4, 0x10, 0xD7, 0x68, + 0x40, 0x14, 0xC0, 0x40, 0xFA, 0xE7, 0x77, 0x17, 0x7A, 0xE6, 0x0B, 0x8F, + 0x65, 0x5B, 0x3C, 0xD9, 0x9A, 0x52, 0xDB, 0xB5, 0xBD, 0x9E, 0x46, 0xCF, + 0x3D, 0xEB, 0x91, 0x05, 0x02, 0xC0, 0x96, 0xB2, 0x76, 0x4C, 0x4D, 0x10, + 0x96, 0x3B, 0x92, 0xFA, 0x9C, 0x7F, 0x0F, 0x99, 0xDF, 0xBE, 0x23, 0x35, + 0x45, 0x1E, 0x02, 0x5C, 0xFE, 0xB5, 0xA8, 0x9B, 0x99, 0x25, 0xDA, 0x5E, + 0xF3, 0x22, 0xC3, 0x39, 0xF5, 0xE4, 0x2A, 0x2E, 0xD3, 0xC6, 0x1F, 0xC4, + 0x6C, 0xAA, 0xC5, 0x1C, 0x6A, 0x01, 0x05, 0x4A, 0x2F, 0xD2, 0xC5, 0xC1, + 0xA8, 0x34, 0x26, 0x5D, 0x66, 0xA5, 0xD2, 0x02, 0x21, 0xF9, 0x18, 0xB7, + 0x06, 0xF5, 0x4E, 0x99, 0x6F, 0xA8, 0xAB, 0x4C, 0x51, 0xE8, 0xCF, 0x50, + 0x18, 0xC5, 0x77, 0xC8, 0x39, 0x09, 0x2C, 0x49, 0x92, 0x32, 0x99, 0xA8, + 0xBB, 0x17, 0x17, 0x79, 0xB0, 0x5A, 0xC5, 0xE6, 0xA3, 0xC4, 0x59, 0x65, + 0x47, 0x35, 0x83, 0x5E, 0xA9, 0xE8, 0x35, 0x0B, 0x99, 0xBB, 0xE4, 0xCD, + 0x20, 0xC6, 0x9B, 0x4A, 0x06, 0x39, 0xB5, 0x68, 0xFC, 0x22, 0xBA, 0xEE, + 0x55, 0x8C, 0x2B, 0x4E, 0xEA, 0xF3, 0xB1, 0xE3, 0xFC, 0xB6, 0x99, 0x9A, + 0xD5, 0x42, 0xFA, 0x71, 0x4D, 0x08, 0xCF, 0x87, 0x1E, 0x6A, 0x71, 0x7D, + 0xF9, 0xD3, 0xB4, 0xE9, 0xA5, 0x71, 0x81, 0x7B, 0xC2, 0x4E, 0x47, 0x96, + 0xA5, 0xF6, 0x76, 0x85, 0xA3, 0x28, 0x8F, 0xE9, 0x80, 0x6E, 0x81, 0x53, + 0xA5, 0x6D, 0x5F, 0xB8, 0x48, 0xF9, 0xC2, 0xF9, 0x36, 0xA6, 0x2E, 0x49, + 0xFF, 0xB8, 0x96, 0xC2, 0x8C, 0x07, 0xB3, 0x9B, 0x88, 0x58, 0xFC, 0xEB, + 0x1B, 0x1C, 0xDE, 0x2D, 0x70, 0xE2, 0x97, 0x92, 0x30, 0xA1, 0x89, 0xE3, + 0xBC, 0x55, 0xA8, 0x27, 0xD6, 0x4B, 0xED, 0x90, 0xAD, 0x8B, 0xFA, 0x63, + 0x25, 0x59, 0x2D, 0xA8, 0x35, 0xDD, 0xCA, 0x97, 0x33, 0xBC, 0xE5, 0xCD, + 0xC7, 0x9D, 0xD1, 0xEC, 0xEF, 0x5E, 0x0E, 0x4A, 0x90, 0x06, 0x26, 0x63, + 0xAD, 0xB9, 0xD9, 0x35, 0x2D, 0x07, 0xBA, 0x76, 0x65, 0x2C, 0xAC, 0x57, + 0x8F, 0x7D, 0xF4, 0x07, 0x94, 0xD7, 0x81, 0x02, 0x96, 0x5D, 0xA3, 0x07, + 0x49, 0xD5, 0x7A, 0xD0, 0x57, 0xF9, 0x1B, 0xE7, 0x53, 0x46, 0x75, 0xAA, + 0xB0, 0x79, 0x42, 0xCB, 0x68, 0x71, 0x08, 0xE9, 0x60, 0xBD, 0x39, 0x69, + 0xCE, 0xF4, 0xAF, 0xC3, 0x56, 0x40, 0xC7, 0xAD, 0x52, 0xA2, 0x09, 0xE4, + 0x6F, 0x86, 0x47, 0x8A, 0x1F, 0xEB, 0x28, 0x27, 0x5D, 0x83, 0x20, 0xAF, + 0x04, 0xC9, 0x6C, 0x56, 0x9A, 0x8B, 0x46, 0xF5 +}; + +static const unsigned char TA244_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA245_DN[] = { + 0x30, 0x78, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x0E, + 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x05, 0x43, 0x65, 0x72, + 0x65, 0x73, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, + 0x0F, 0x56, 0x41, 0x54, 0x45, 0x53, 0x2D, 0x51, 0x32, 0x38, 0x32, 0x36, + 0x30, 0x30, 0x34, 0x4A, 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x23, 0x41, 0x43, 0x20, 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, + 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x20, 0x53, 0x45, 0x52, 0x56, + 0x49, 0x44, 0x4F, 0x52, 0x45, 0x53, 0x20, 0x53, 0x45, 0x47, 0x55, 0x52, + 0x4F, 0x53 +}; + +static const unsigned char TA245_EC_Q[] = { + 0x04, 0xF6, 0xBA, 0x57, 0x53, 0xC8, 0xCA, 0xAB, 0xDF, 0x36, 0x4A, 0x52, + 0x21, 0xE4, 0x97, 0xD2, 0x83, 0x67, 0x9E, 0xF0, 0x65, 0x51, 0xD0, 0x5E, + 0x87, 0xC7, 0x47, 0xB1, 0x59, 0xF2, 0x57, 0x47, 0x9B, 0x00, 0x02, 0x93, + 0x44, 0x17, 0x69, 0xDB, 0x42, 0xC7, 0xB1, 0xB2, 0x3A, 0x18, 0x0E, 0xB4, + 0x5D, 0x8C, 0xB3, 0x66, 0x5D, 0xA1, 0x34, 0xF9, 0x36, 0x2C, 0x49, 0xDB, + 0xF3, 0x46, 0xFC, 0xB3, 0x44, 0x69, 0x44, 0x13, 0x66, 0xFD, 0xD7, 0xC5, + 0xFD, 0xAF, 0x36, 0x4D, 0xCE, 0x03, 0x4D, 0x07, 0x71, 0xCF, 0xAF, 0x6A, + 0x05, 0xD2, 0xA2, 0x43, 0x5A, 0x0A, 0x52, 0x6F, 0x01, 0x03, 0x4E, 0x8E, + 0x8B +}; + +static const unsigned char TA246_DN[] = { + 0x30, 0x81, 0x84, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x05, + 0x13, 0x09, 0x47, 0x36, 0x33, 0x32, 0x38, 0x37, 0x35, 0x31, 0x30, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, + 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1E, 0x41, + 0x4E, 0x46, 0x20, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, + 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x63, 0x69, 0x6F, 0x6E, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x13, 0x0B, 0x41, 0x4E, 0x46, 0x20, 0x43, 0x41, 0x20, 0x52, + 0x61, 0x69, 0x7A, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x19, 0x41, 0x4E, 0x46, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA246_RSA_N[] = { + 0xDB, 0xEB, 0x6B, 0x2B, 0xE6, 0x64, 0x54, 0x95, 0x82, 0x90, 0xA3, 0x72, + 0xA4, 0x19, 0x01, 0x9D, 0x9C, 0x0B, 0x81, 0x5F, 0x73, 0x49, 0xBA, 0xA7, + 0xAC, 0xF3, 0x04, 0x4E, 0x7B, 0x96, 0x0B, 0xEC, 0x11, 0xE0, 0x5B, 0xA6, + 0x1C, 0xCE, 0x1B, 0xD2, 0x0D, 0x83, 0x1C, 0x2B, 0xB8, 0x9E, 0x1D, 0x7E, + 0x45, 0x32, 0x60, 0x0F, 0x07, 0xE9, 0x77, 0x58, 0x7E, 0x9F, 0x6A, 0xC8, + 0x61, 0x4E, 0xB6, 0x26, 0xC1, 0x4C, 0x8D, 0xFF, 0x4C, 0xEF, 0x34, 0xB2, + 0x1F, 0x65, 0xD8, 0xB9, 0x78, 0xF5, 0xAD, 0xA9, 0x71, 0xB9, 0xEF, 0x4F, + 0x58, 0x1D, 0xA5, 0xDE, 0x74, 0x20, 0x97, 0xA1, 0xED, 0x68, 0x4C, 0xDE, + 0x92, 0x17, 0x4B, 0xBC, 0xAB, 0xFF, 0x65, 0x9A, 0x9E, 0xFB, 0x47, 0xD9, + 0x57, 0x72, 0xF3, 0x09, 0xA1, 0xAE, 0x76, 0x44, 0x13, 0x6E, 0x9C, 0x2D, + 0x44, 0x39, 0xBC, 0xF9, 0xC7, 0x3B, 0xA4, 0x58, 0x3D, 0x41, 0xBD, 0xB4, + 0xC2, 0x49, 0xA3, 0xC8, 0x0D, 0xD2, 0x97, 0x2F, 0x07, 0x65, 0x52, 0x00, + 0xA7, 0x6E, 0xC8, 0xAF, 0x68, 0xEC, 0xF4, 0x14, 0x96, 0xB6, 0x57, 0x1F, + 0x56, 0xC3, 0x39, 0x9F, 0x2B, 0x6D, 0xE4, 0xF3, 0x3E, 0xF6, 0x35, 0x64, + 0xDA, 0x0C, 0x1C, 0xA1, 0x84, 0x4B, 0x2F, 0x4B, 0x4B, 0xE2, 0x2C, 0x24, + 0x9D, 0x6D, 0x93, 0x40, 0xEB, 0xB5, 0x23, 0x8E, 0x32, 0xCA, 0x6F, 0x45, + 0xD3, 0xA8, 0x89, 0x7B, 0x1E, 0xCF, 0x1E, 0xFA, 0x5B, 0x43, 0x8B, 0xCD, + 0xCD, 0xA8, 0x0F, 0x6A, 0xCA, 0x0C, 0x5E, 0xB9, 0x9E, 0x47, 0x8F, 0xF0, + 0xD9, 0xB6, 0x0A, 0x0B, 0x58, 0x65, 0x17, 0x33, 0xB9, 0x23, 0xE4, 0x77, + 0x19, 0x7D, 0xCB, 0x4A, 0x2E, 0x92, 0x7B, 0x4F, 0x2F, 0x10, 0x77, 0xB1, + 0x8D, 0x2F, 0x68, 0x9C, 0x62, 0xCC, 0xE0, 0x50, 0xF8, 0xEC, 0x91, 0xA7, + 0x54, 0x4C, 0x57, 0x09, 0xD5, 0x76, 0x63, 0xC5, 0xE8, 0x65, 0x1E, 0xEE, + 0x6D, 0x6A, 0xCF, 0x09, 0x9D, 0xFA, 0x7C, 0x4F, 0xAD, 0x60, 0x08, 0xFD, + 0x56, 0x99, 0x0F, 0x15, 0x2C, 0x7B, 0xA9, 0x80, 0xAB, 0x8C, 0x61, 0x8F, + 0x4A, 0x07, 0x76, 0x42, 0xDE, 0x3D, 0xF4, 0xDD, 0xB2, 0x24, 0x33, 0x5B, + 0xB8, 0xB5, 0xA3, 0x44, 0xC9, 0xAC, 0x7F, 0x77, 0x3C, 0x1D, 0x23, 0xEC, + 0x82, 0xA9, 0xA6, 0xE2, 0xC8, 0x06, 0x4C, 0x02, 0xFE, 0xAC, 0x5C, 0x99, + 0x99, 0x0B, 0x2F, 0x10, 0x8A, 0xA6, 0xF4, 0x7F, 0xD5, 0x87, 0x74, 0x0D, + 0x59, 0x49, 0x45, 0xF6, 0xF0, 0x71, 0x5C, 0x39, 0x29, 0xD6, 0xBF, 0x4A, + 0x23, 0x8B, 0xF5, 0x5F, 0x01, 0x63, 0xD2, 0x87, 0x73, 0x28, 0xB5, 0x4B, + 0x0A, 0xF5, 0xF8, 0xAB, 0x82, 0x2C, 0x7E, 0x73, 0x25, 0x32, 0x1D, 0x0B, + 0x63, 0x0A, 0x17, 0x81, 0x00, 0xFF, 0xB6, 0x76, 0x5E, 0xE7, 0xB4, 0xB1, + 0x40, 0xCA, 0x21, 0xBB, 0xD5, 0x80, 0x51, 0xE5, 0x48, 0x52, 0x67, 0x2C, + 0xD2, 0x61, 0x89, 0x07, 0x0D, 0x0F, 0xCE, 0x42, 0x77, 0xC0, 0x44, 0x73, + 0x9C, 0x44, 0x50, 0xA0, 0xDB, 0x10, 0x0A, 0x2D, 0x95, 0x1C, 0x81, 0xAF, + 0xE4, 0x1C, 0xE5, 0x14, 0x1E, 0xF1, 0x36, 0x41, 0x01, 0x02, 0x2F, 0x7D, + 0x73, 0xA7, 0xDE, 0x42, 0xCC, 0x4C, 0xE9, 0x89, 0x0D, 0x56, 0xF7, 0x9F, + 0x91, 0xD4, 0x03, 0xC6, 0x6C, 0xC9, 0x8F, 0xDB, 0xD8, 0x1C, 0xE0, 0x40, + 0x98, 0x5D, 0x66, 0x99, 0x98, 0x80, 0x6E, 0x2D, 0xFF, 0x01, 0xC5, 0xCE, + 0xCB, 0x46, 0x1F, 0xAC, 0x02, 0xC6, 0x43, 0xE6, 0xAE, 0xA2, 0x84, 0x3C, + 0xC5, 0x4E, 0x1E, 0x3D, 0x6D, 0xC9, 0x14, 0x4C, 0xE3, 0x2E, 0x41, 0xBB, + 0xCA, 0x39, 0xBF, 0x36, 0x3C, 0x2A, 0x19, 0xAA, 0x41, 0x87, 0x4E, 0xA5, + 0xCE, 0x4B, 0x32, 0x79, 0xDD, 0x90, 0x49, 0x7F +}; + +static const unsigned char TA246_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA247_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x54, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x05, 0x4D, 0x69, 0x6C, 0x61, 0x6E, 0x31, 0x23, 0x30, 0x21, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x1A, 0x41, 0x63, 0x74, 0x61, 0x6C, 0x69, + 0x73, 0x20, 0x53, 0x2E, 0x70, 0x2E, 0x41, 0x2E, 0x2F, 0x30, 0x33, 0x33, + 0x35, 0x38, 0x35, 0x32, 0x30, 0x39, 0x36, 0x37, 0x31, 0x27, 0x30, 0x25, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x41, 0x63, 0x74, 0x61, 0x6C, + 0x69, 0x73, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA247_RSA_N[] = { + 0xA7, 0xC6, 0xC4, 0xA5, 0x29, 0xA4, 0x2C, 0xEF, 0xE5, 0x18, 0xC5, 0xB0, + 0x50, 0xA3, 0x6F, 0x51, 0x3B, 0x9F, 0x0A, 0x5A, 0xC9, 0xC2, 0x48, 0x38, + 0x0A, 0xC2, 0x1C, 0xA0, 0x18, 0x7F, 0x91, 0xB5, 0x87, 0xB9, 0x40, 0x3F, + 0xDD, 0x1D, 0x68, 0x1F, 0x08, 0x83, 0xD5, 0x2D, 0x1E, 0x88, 0xA0, 0xF8, + 0x8F, 0x56, 0x8F, 0x6D, 0x99, 0x02, 0x92, 0x90, 0x16, 0xD5, 0x5F, 0x08, + 0x6C, 0x89, 0xD7, 0xE1, 0xAC, 0xBC, 0x20, 0xC2, 0xB1, 0xE0, 0x83, 0x51, + 0x8A, 0x69, 0x4D, 0x00, 0x96, 0x5A, 0x6F, 0x2F, 0xC0, 0x44, 0x7E, 0xA3, + 0x0E, 0xE4, 0x91, 0xCD, 0x58, 0xEE, 0xDC, 0xFB, 0xC7, 0x1E, 0x45, 0x47, + 0xDD, 0x27, 0xB9, 0x08, 0x01, 0x9F, 0xA6, 0x21, 0x1D, 0xF5, 0x41, 0x2D, + 0x2F, 0x4C, 0xFD, 0x28, 0xAD, 0xE0, 0x8A, 0xAD, 0x22, 0xB4, 0x56, 0x65, + 0x8E, 0x86, 0x54, 0x8F, 0x93, 0x43, 0x29, 0xDE, 0x39, 0x46, 0x78, 0xA3, + 0x30, 0x23, 0xBA, 0xCD, 0xF0, 0x7D, 0x13, 0x57, 0xC0, 0x5D, 0xD2, 0x83, + 0x6B, 0x48, 0x4C, 0xC4, 0xAB, 0x9F, 0x80, 0x5A, 0x5B, 0x3A, 0xBD, 0xC9, + 0xA7, 0x22, 0x3F, 0x80, 0x27, 0x33, 0x5B, 0x0E, 0xB7, 0x8A, 0x0C, 0x5D, + 0x07, 0x37, 0x08, 0xCB, 0x6C, 0xD2, 0x7A, 0x47, 0x22, 0x44, 0x35, 0xC5, + 0xCC, 0xCC, 0x2E, 0x8E, 0xDD, 0x2A, 0xED, 0xB7, 0x7D, 0x66, 0x0D, 0x5F, + 0x61, 0x51, 0x22, 0x55, 0x1B, 0xE3, 0x46, 0xE3, 0xE3, 0x3D, 0xD0, 0x35, + 0x62, 0x9A, 0xDB, 0xAF, 0x14, 0xC8, 0x5B, 0xA1, 0xCC, 0x89, 0x1B, 0xE1, + 0x30, 0x26, 0xFC, 0xA0, 0x9B, 0x1F, 0x81, 0xA7, 0x47, 0x1F, 0x04, 0xEB, + 0xA3, 0x39, 0x92, 0x06, 0x9F, 0x99, 0xD3, 0xBF, 0xD3, 0xEA, 0x4F, 0x50, + 0x9C, 0x19, 0xFE, 0x96, 0x87, 0x1E, 0x3C, 0x65, 0xF6, 0xA3, 0x18, 0x24, + 0x83, 0x86, 0x10, 0xE7, 0x54, 0x3E, 0xA8, 0x3A, 0x76, 0x24, 0x4F, 0x81, + 0x21, 0xC5, 0xE3, 0x0F, 0x02, 0xF8, 0x93, 0x94, 0x47, 0x20, 0xBB, 0xFE, + 0xD4, 0x0E, 0xD3, 0x68, 0xB9, 0xDD, 0xC4, 0x7A, 0x84, 0x82, 0xE3, 0x53, + 0x54, 0x79, 0xDD, 0xDB, 0x9C, 0xD2, 0xF2, 0x07, 0x9B, 0x2E, 0xB6, 0xBC, + 0x3E, 0xED, 0x85, 0x6D, 0xEF, 0x25, 0x11, 0xF2, 0x97, 0x1A, 0x42, 0x61, + 0xF7, 0x4A, 0x97, 0xE8, 0x8B, 0xB1, 0x10, 0x07, 0xFA, 0x65, 0x81, 0xB2, + 0xA2, 0x39, 0xCF, 0xF7, 0x3C, 0xFF, 0x18, 0xFB, 0xC6, 0xF1, 0x5A, 0x8B, + 0x59, 0xE2, 0x02, 0xAC, 0x7B, 0x92, 0xD0, 0x4E, 0x14, 0x4F, 0x59, 0x45, + 0xF6, 0x0C, 0x5E, 0x28, 0x5F, 0xB0, 0xE8, 0x3F, 0x45, 0xCF, 0xCF, 0xAF, + 0x9B, 0x6F, 0xFB, 0x84, 0xD3, 0x77, 0x5A, 0x95, 0x6F, 0xAC, 0x94, 0x84, + 0x9E, 0xEE, 0xBC, 0xC0, 0x4A, 0x8F, 0x4A, 0x93, 0xF8, 0x44, 0x21, 0xE2, + 0x31, 0x45, 0x61, 0x50, 0x4E, 0x10, 0xD8, 0xE3, 0x35, 0x7C, 0x4C, 0x19, + 0xB4, 0xDE, 0x05, 0xBF, 0xA3, 0x06, 0x9F, 0xC8, 0xB5, 0xCD, 0xE4, 0x1F, + 0xD7, 0x17, 0x06, 0x0D, 0x7A, 0x95, 0x74, 0x55, 0x0D, 0x68, 0x1A, 0xFC, + 0x10, 0x1B, 0x62, 0x64, 0x9D, 0x6D, 0xE0, 0x95, 0xA0, 0xC3, 0x94, 0x07, + 0x57, 0x0D, 0x14, 0xE6, 0xBD, 0x05, 0xFB, 0xB8, 0x9F, 0xE6, 0xDF, 0x8B, + 0xE2, 0xC6, 0xE7, 0x7E, 0x96, 0xF6, 0x53, 0xC5, 0x80, 0x34, 0x50, 0x28, + 0x58, 0xF0, 0x12, 0x50, 0x71, 0x17, 0x30, 0xBA, 0xE6, 0x78, 0x63, 0xBC, + 0xF4, 0xB2, 0xAD, 0x9B, 0x2B, 0xB2, 0xFE, 0xE1, 0x39, 0x8C, 0x5E, 0xBA, + 0x0B, 0x20, 0x94, 0xDE, 0x7B, 0x83, 0xB8, 0xFF, 0xE3, 0x56, 0x8D, 0xB7, + 0x11, 0xE9, 0x3B, 0x8C, 0xF2, 0xB1, 0xC1, 0x5D, 0x9D, 0xA4, 0x0B, 0x4C, + 0x2B, 0xD9, 0xB2, 0x18, 0xF5, 0xB5, 0x9F, 0x4B +}; + +static const unsigned char TA247_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA248_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C +}; + +static const unsigned char TA248_RSA_N[] = { + 0xF6, 0x1B, 0x4F, 0x67, 0x07, 0x2B, 0xA1, 0x15, 0xF5, 0x06, 0x22, 0xCB, + 0x1F, 0x01, 0xB2, 0xE3, 0x73, 0x45, 0x06, 0x44, 0x49, 0x2C, 0xBB, 0x49, + 0x25, 0x14, 0xD6, 0xCE, 0xC3, 0xB7, 0xAB, 0x2C, 0x4F, 0xC6, 0x41, 0x32, + 0x94, 0x57, 0xFA, 0x12, 0xA7, 0x5B, 0x0E, 0xE2, 0x8F, 0x1F, 0x1E, 0x86, + 0x19, 0xA7, 0xAA, 0xB5, 0x2D, 0xB9, 0x5F, 0x0D, 0x8A, 0xC2, 0xAF, 0x85, + 0x35, 0x79, 0x32, 0x2D, 0xBB, 0x1C, 0x62, 0x37, 0xF2, 0xB1, 0x5B, 0x4A, + 0x3D, 0xCA, 0xCD, 0x71, 0x5F, 0xE9, 0x42, 0xBE, 0x94, 0xE8, 0xC8, 0xDE, + 0xF9, 0x22, 0x48, 0x64, 0xC6, 0xE5, 0xAB, 0xC6, 0x2B, 0x6D, 0xAD, 0x05, + 0xF0, 0xFA, 0xD5, 0x0B, 0xCF, 0x9A, 0xE5, 0xF0, 0x50, 0xA4, 0x8B, 0x3B, + 0x47, 0xA5, 0x23, 0x5B, 0x7A, 0x7A, 0xF8, 0x33, 0x3F, 0xB8, 0xEF, 0x99, + 0x97, 0xE3, 0x20, 0xC1, 0xD6, 0x28, 0x89, 0xCF, 0x94, 0xFB, 0xB9, 0x45, + 0xED, 0xE3, 0x40, 0x17, 0x11, 0xD4, 0x74, 0xF0, 0x0B, 0x31, 0xE2, 0x2B, + 0x26, 0x6A, 0x9B, 0x4C, 0x57, 0xAE, 0xAC, 0x20, 0x3E, 0xBA, 0x45, 0x7A, + 0x05, 0xF3, 0xBD, 0x9B, 0x69, 0x15, 0xAE, 0x7D, 0x4E, 0x20, 0x63, 0xC4, + 0x35, 0x76, 0x3A, 0x07, 0x02, 0xC9, 0x37, 0xFD, 0xC7, 0x47, 0xEE, 0xE8, + 0xF1, 0x76, 0x1D, 0x73, 0x15, 0xF2, 0x97, 0xA4, 0xB5, 0xC8, 0x7A, 0x79, + 0xD9, 0x42, 0xAA, 0x2B, 0x7F, 0x5C, 0xFE, 0xCE, 0x26, 0x4F, 0xA3, 0x66, + 0x81, 0x35, 0xAF, 0x44, 0xBA, 0x54, 0x1E, 0x1C, 0x30, 0x32, 0x65, 0x9D, + 0xE6, 0x3C, 0x93, 0x5E, 0x50, 0x4E, 0x7A, 0xE3, 0x3A, 0xD4, 0x6E, 0xCC, + 0x1A, 0xFB, 0xF9, 0xD2, 0x37, 0xAE, 0x24, 0x2A, 0xAB, 0x57, 0x03, 0x22, + 0x28, 0x0D, 0x49, 0x75, 0x7F, 0xB7, 0x28, 0xDA, 0x75, 0xBF, 0x8E, 0xE3, + 0xDC, 0x0E, 0x79, 0x31 +}; + +static const unsigned char TA248_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA249_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, 0x67 +}; + +static const unsigned char TA249_RSA_N[] = { + 0xB4, 0x84, 0xCC, 0x33, 0x17, 0x2E, 0x6B, 0x94, 0x6C, 0x6B, 0x61, 0x52, + 0xA0, 0xEB, 0xA3, 0xCF, 0x79, 0x94, 0x4C, 0xE5, 0x94, 0x80, 0x99, 0xCB, + 0x55, 0x64, 0x44, 0x65, 0x8F, 0x67, 0x64, 0xE2, 0x06, 0xE3, 0x5C, 0x37, + 0x49, 0xF6, 0x2F, 0x9B, 0x84, 0x84, 0x1E, 0x2D, 0xF2, 0x60, 0x9D, 0x30, + 0x4E, 0xCC, 0x84, 0x85, 0xE2, 0x2C, 0xCF, 0x1E, 0x9E, 0xFE, 0x36, 0xAB, + 0x33, 0x77, 0x35, 0x44, 0xD8, 0x35, 0x96, 0x1A, 0x3D, 0x36, 0xE8, 0x7A, + 0x0E, 0xD8, 0xD5, 0x47, 0xA1, 0x6A, 0x69, 0x8B, 0xD9, 0xFC, 0xBB, 0x3A, + 0xAE, 0x79, 0x5A, 0xD5, 0xF4, 0xD6, 0x71, 0xBB, 0x9A, 0x90, 0x23, 0x6B, + 0x9A, 0xB7, 0x88, 0x74, 0x87, 0x0C, 0x1E, 0x5F, 0xB9, 0x9E, 0x2D, 0xFA, + 0xAB, 0x53, 0x2B, 0xDC, 0xBB, 0x76, 0x3E, 0x93, 0x4C, 0x08, 0x08, 0x8C, + 0x1E, 0xA2, 0x23, 0x1C, 0xD4, 0x6A, 0xAD, 0x22, 0xBA, 0x99, 0x01, 0x2E, + 0x6D, 0x65, 0xCB, 0xBE, 0x24, 0x66, 0x55, 0x24, 0x4B, 0x40, 0x44, 0xB1, + 0x1B, 0xD7, 0xE1, 0xC2, 0x85, 0xC0, 0xDE, 0x10, 0x3F, 0x3D, 0xED, 0xB8, + 0xFC, 0xF1, 0xF1, 0x23, 0x53, 0xDC, 0xBF, 0x65, 0x97, 0x6F, 0xD9, 0xF9, + 0x40, 0x71, 0x8D, 0x7D, 0xBD, 0x95, 0xD4, 0xCE, 0xBE, 0xA0, 0x5E, 0x27, + 0x23, 0xDE, 0xFD, 0xA6, 0xD0, 0x26, 0x0E, 0x00, 0x29, 0xEB, 0x3C, 0x46, + 0xF0, 0x3D, 0x60, 0xBF, 0x3F, 0x50, 0xD2, 0xDC, 0x26, 0x41, 0x51, 0x9E, + 0x14, 0x37, 0x42, 0x04, 0xA3, 0x70, 0x57, 0xA8, 0x1B, 0x87, 0xED, 0x2D, + 0xFA, 0x7B, 0xEE, 0x8C, 0x0A, 0xE3, 0xA9, 0x66, 0x89, 0x19, 0xCB, 0x41, + 0xF9, 0xDD, 0x44, 0x36, 0x61, 0xCF, 0xE2, 0x77, 0x46, 0xC8, 0x7D, 0xF6, + 0xF4, 0x92, 0x81, 0x36, 0xFD, 0xDB, 0x34, 0xF1, 0x72, 0x7E, 0xF3, 0x0C, + 0x16, 0xBD, 0xB4, 0x15 +}; + +static const unsigned char TA249_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA250_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x13, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D +}; + +static const unsigned char TA250_RSA_N[] = { + 0xC4, 0x12, 0xDF, 0xA9, 0x5F, 0xFE, 0x41, 0xDD, 0xDD, 0xF5, 0x9F, 0x8A, + 0xE3, 0xF6, 0xAC, 0xE1, 0x3C, 0x78, 0x9A, 0xBC, 0xD8, 0xF0, 0x7F, 0x7A, + 0xA0, 0x33, 0x2A, 0xDC, 0x8D, 0x20, 0x5B, 0xAE, 0x2D, 0x6F, 0xE7, 0x93, + 0xD9, 0x36, 0x70, 0x6A, 0x68, 0xCF, 0x8E, 0x51, 0xA3, 0x85, 0x5B, 0x67, + 0x04, 0xA0, 0x10, 0x24, 0x6F, 0x5D, 0x28, 0x82, 0xC1, 0x97, 0x57, 0xD8, + 0x48, 0x29, 0x13, 0xB6, 0xE1, 0xBE, 0x91, 0x4D, 0xDF, 0x85, 0x0C, 0x53, + 0x18, 0x9A, 0x1E, 0x24, 0xA2, 0x4F, 0x8F, 0xF0, 0xA2, 0x85, 0x0B, 0xCB, + 0xF4, 0x29, 0x7F, 0xD2, 0xA4, 0x58, 0xEE, 0x26, 0x4D, 0xC9, 0xAA, 0xA8, + 0x7B, 0x9A, 0xD9, 0xFA, 0x38, 0xDE, 0x44, 0x57, 0x15, 0xE5, 0xF8, 0x8C, + 0xC8, 0xD9, 0x48, 0xE2, 0x0D, 0x16, 0x27, 0x1D, 0x1E, 0xC8, 0x83, 0x85, + 0x25, 0xB7, 0xBA, 0xAA, 0x55, 0x41, 0xCC, 0x03, 0x22, 0x4B, 0x2D, 0x91, + 0x8D, 0x8B, 0xE6, 0x89, 0xAF, 0x66, 0xC7, 0xE9, 0xFF, 0x2B, 0xE9, 0x3C, + 0xAC, 0xDA, 0xD2, 0xB3, 0xC3, 0xE1, 0x68, 0x9C, 0x89, 0xF8, 0x7A, 0x00, + 0x56, 0xDE, 0xF4, 0x55, 0x95, 0x6C, 0xFB, 0xBA, 0x64, 0xDD, 0x62, 0x8B, + 0xDF, 0x0B, 0x77, 0x32, 0xEB, 0x62, 0xCC, 0x26, 0x9A, 0x9B, 0xBB, 0xAA, + 0x62, 0x83, 0x4C, 0xB4, 0x06, 0x7A, 0x30, 0xC8, 0x29, 0xBF, 0xED, 0x06, + 0x4D, 0x97, 0xB9, 0x1C, 0xC4, 0x31, 0x2B, 0xD5, 0x5F, 0xBC, 0x53, 0x12, + 0x17, 0x9C, 0x99, 0x57, 0x29, 0x66, 0x77, 0x61, 0x21, 0x31, 0x07, 0x2E, + 0x25, 0x49, 0x9D, 0x18, 0xF2, 0xEE, 0xF3, 0x2B, 0x71, 0x8C, 0xB5, 0xBA, + 0x39, 0x07, 0x49, 0x77, 0xFC, 0xEF, 0x2E, 0x92, 0x90, 0x05, 0x8D, 0x2D, + 0x2F, 0x77, 0x7B, 0xEF, 0x43, 0xBF, 0x35, 0xBB, 0x9A, 0xD8, 0xF9, 0x73, + 0xA7, 0x2C, 0xF2, 0xD0, 0x57, 0xEE, 0x28, 0x4E, 0x26, 0x5F, 0x8F, 0x90, + 0x68, 0x09, 0x2F, 0xB8, 0xF8, 0xDC, 0x06, 0xE9, 0x2E, 0x9A, 0x3E, 0x51, + 0xA7, 0xD1, 0x22, 0xC4, 0x0A, 0xA7, 0x38, 0x48, 0x6C, 0xB3, 0xF9, 0xFF, + 0x7D, 0xAB, 0x86, 0x57, 0xE3, 0xBA, 0xD6, 0x85, 0x78, 0x77, 0xBA, 0x43, + 0xEA, 0x48, 0x7F, 0xF6, 0xD8, 0xBE, 0x23, 0x6D, 0x1E, 0xBF, 0xD1, 0x36, + 0x6C, 0x58, 0x5C, 0xF1, 0xEE, 0xA4, 0x19, 0x54, 0x1A, 0xF5, 0x03, 0xD2, + 0x76, 0xE6, 0xE1, 0x8C, 0xBD, 0x3C, 0xB3, 0xD3, 0x48, 0x4B, 0xE2, 0xC8, + 0xF8, 0x7F, 0x92, 0xA8, 0x76, 0x46, 0x9C, 0x42, 0x65, 0x3E, 0xA4, 0x1E, + 0xC1, 0x07, 0x03, 0x5A, 0x46, 0x2D, 0xB8, 0x97, 0xF3, 0xB7, 0xD5, 0xB2, + 0x55, 0x21, 0xEF, 0xBA, 0xDC, 0x4C, 0x00, 0x97, 0xFB, 0x14, 0x95, 0x27, + 0x33, 0xBF, 0xE8, 0x43, 0x47, 0x46, 0xD2, 0x08, 0x99, 0x16, 0x60, 0x3B, + 0x9A, 0x7E, 0xD2, 0xE6, 0xED, 0x38, 0xEA, 0xEC, 0x01, 0x1E, 0x3C, 0x48, + 0x56, 0x49, 0x09, 0xC7, 0x4C, 0x37, 0x00, 0x9E, 0x88, 0x0E, 0xC0, 0x73, + 0xE1, 0x6F, 0x66, 0xE9, 0x72, 0x47, 0x30, 0x3E, 0x10, 0xE5, 0x0B, 0x03, + 0xC9, 0x9A, 0x42, 0x00, 0x6C, 0xC5, 0x94, 0x7E, 0x61, 0xC4, 0x8A, 0xDF, + 0x7F, 0x82, 0x1A, 0x0B, 0x59, 0xC4, 0x59, 0x32, 0x77, 0xB3, 0xBC, 0x60, + 0x69, 0x56, 0x39, 0xFD, 0xB4, 0x06, 0x7B, 0x2C, 0xD6, 0x64, 0x36, 0xD9, + 0xBD, 0x48, 0xED, 0x84, 0x1F, 0x7E, 0xA5, 0x22, 0x8F, 0x2A, 0xB8, 0x42, + 0xF4, 0x82, 0xB7, 0xD4, 0x53, 0x90, 0x78, 0x4E, 0x2D, 0x1A, 0xFD, 0x81, + 0x6F, 0x44, 0xD7, 0x3B, 0x01, 0x74, 0x96, 0x42, 0xE0, 0x00, 0xE2, 0x2E, + 0x6B, 0xEA, 0xC5, 0xEE, 0x72, 0xAC, 0xBB, 0xBF, 0xFE, 0xEA, 0xAA, 0xA8, + 0xF8, 0xDC, 0xF6, 0xB2, 0x79, 0x8A, 0xB6, 0x67 +}; + +static const unsigned char TA250_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA251_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA251_EC_Q[] = { + 0x04, 0x0D, 0x30, 0x5E, 0x1B, 0x15, 0x9D, 0x03, 0xD0, 0xA1, 0x79, 0x35, + 0xB7, 0x3A, 0x3C, 0x92, 0x7A, 0xCA, 0x15, 0x1C, 0xCD, 0x62, 0xF3, 0x9C, + 0x26, 0x5C, 0x07, 0x3D, 0xE5, 0x54, 0xFA, 0xA3, 0xD6, 0xCC, 0x12, 0xEA, + 0xF4, 0x14, 0x5F, 0xE8, 0x8E, 0x19, 0xAB, 0x2F, 0x2E, 0x48, 0xE6, 0xAC, + 0x18, 0x43, 0x78, 0xAC, 0xD0, 0x37, 0xC3, 0xBD, 0xB2, 0xCD, 0x2C, 0xE6, + 0x47, 0xE2, 0x1A, 0xE6, 0x63, 0xB8, 0x3D, 0x2E, 0x2F, 0x78, 0xC4, 0x4F, + 0xDB, 0xF4, 0x0F, 0xA4, 0x68, 0x4C, 0x55, 0x72, 0x6B, 0x95, 0x1D, 0x4E, + 0x18, 0x42, 0x95, 0x78, 0xCC, 0x37, 0x3C, 0x91, 0xE2, 0x9B, 0x65, 0x2B, + 0x29 +}; + +static const unsigned char TA252_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA252_RSA_N[] = { + 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80, + 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7, + 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86, + 0xD3, 0xA0, 0x43, 0x7A, 0x4E, 0xB2, 0xA4, 0xD0, 0x36, 0xBA, 0x01, 0xBE, + 0x8D, 0xDB, 0x48, 0xC8, 0x07, 0x17, 0x36, 0x4C, 0xF4, 0xEE, 0x88, 0x23, + 0xC7, 0x3E, 0xEB, 0x37, 0xF5, 0xB5, 0x19, 0xF8, 0x49, 0x68, 0xB0, 0xDE, + 0xD7, 0xB9, 0x76, 0x38, 0x1D, 0x61, 0x9E, 0xA4, 0xFE, 0x82, 0x36, 0xA5, + 0xE5, 0x4A, 0x56, 0xE4, 0x45, 0xE1, 0xF9, 0xFD, 0xB4, 0x16, 0xFA, 0x74, + 0xDA, 0x9C, 0x9B, 0x35, 0x39, 0x2F, 0xFA, 0xB0, 0x20, 0x50, 0x06, 0x6C, + 0x7A, 0xD0, 0x80, 0xB2, 0xA6, 0xF9, 0xAF, 0xEC, 0x47, 0x19, 0x8F, 0x50, + 0x38, 0x07, 0xDC, 0xA2, 0x87, 0x39, 0x58, 0xF8, 0xBA, 0xD5, 0xA9, 0xF9, + 0x48, 0x67, 0x30, 0x96, 0xEE, 0x94, 0x78, 0x5E, 0x6F, 0x89, 0xA3, 0x51, + 0xC0, 0x30, 0x86, 0x66, 0xA1, 0x45, 0x66, 0xBA, 0x54, 0xEB, 0xA3, 0xC3, + 0x91, 0xF9, 0x48, 0xDC, 0xFF, 0xD1, 0xE8, 0x30, 0x2D, 0x7D, 0x2D, 0x74, + 0x70, 0x35, 0xD7, 0x88, 0x24, 0xF7, 0x9E, 0xC4, 0x59, 0x6E, 0xBB, 0x73, + 0x87, 0x17, 0xF2, 0x32, 0x46, 0x28, 0xB8, 0x43, 0xFA, 0xB7, 0x1D, 0xAA, + 0xCA, 0xB4, 0xF2, 0x9F, 0x24, 0x0E, 0x2D, 0x4B, 0xF7, 0x71, 0x5C, 0x5E, + 0x69, 0xFF, 0xEA, 0x95, 0x02, 0xCB, 0x38, 0x8A, 0xAE, 0x50, 0x38, 0x6F, + 0xDB, 0xFB, 0x2D, 0x62, 0x1B, 0xC5, 0xC7, 0x1E, 0x54, 0xE1, 0x77, 0xE0, + 0x67, 0xC8, 0x0F, 0x9C, 0x87, 0x23, 0xD6, 0x3F, 0x40, 0x20, 0x7F, 0x20, + 0x80, 0xC4, 0x80, 0x4C, 0x3E, 0x3B, 0x24, 0x26, 0x8E, 0x04, 0xAE, 0x6C, + 0x9A, 0xC8, 0xAA, 0x0D +}; + +static const unsigned char TA252_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA253_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA253_RSA_N[] = { + 0xAD, 0x96, 0x9F, 0x2D, 0x9C, 0x4A, 0x4C, 0x4A, 0x81, 0x79, 0x51, 0x99, + 0xEC, 0x8A, 0xCB, 0x6B, 0x60, 0x51, 0x13, 0xBC, 0x4D, 0x6D, 0x06, 0xFC, + 0xB0, 0x08, 0x8D, 0xDD, 0x19, 0x10, 0x6A, 0xC7, 0x26, 0x0C, 0x35, 0xD8, + 0xC0, 0x6F, 0x20, 0x84, 0xE9, 0x94, 0xB1, 0x9B, 0x85, 0x03, 0xC3, 0x5B, + 0xDB, 0x4A, 0xE8, 0xC8, 0xF8, 0x90, 0x76, 0xD9, 0x5B, 0x4F, 0xE3, 0x4C, + 0xE8, 0x06, 0x36, 0x4D, 0xCC, 0x9A, 0xAC, 0x3D, 0x0C, 0x90, 0x2B, 0x92, + 0xD4, 0x06, 0x19, 0x60, 0xAC, 0x37, 0x44, 0x79, 0x85, 0x81, 0x82, 0xAD, + 0x5A, 0x37, 0xE0, 0x0D, 0xCC, 0x9D, 0xA6, 0x4C, 0x52, 0x76, 0xEA, 0x43, + 0x9D, 0xB7, 0x04, 0xD1, 0x50, 0xF6, 0x55, 0xE0, 0xD5, 0xD2, 0xA6, 0x49, + 0x85, 0xE9, 0x37, 0xE9, 0xCA, 0x7E, 0xAE, 0x5C, 0x95, 0x4D, 0x48, 0x9A, + 0x3F, 0xAE, 0x20, 0x5A, 0x6D, 0x88, 0x95, 0xD9, 0x34, 0xB8, 0x52, 0x1A, + 0x43, 0x90, 0xB0, 0xBF, 0x6C, 0x05, 0xB9, 0xB6, 0x78, 0xB7, 0xEA, 0xD0, + 0xE4, 0x3A, 0x3C, 0x12, 0x53, 0x62, 0xFF, 0x4A, 0xF2, 0x7B, 0xBE, 0x35, + 0x05, 0xA9, 0x12, 0x34, 0xE3, 0xF3, 0x64, 0x74, 0x62, 0x2C, 0x3D, 0x00, + 0x49, 0x5A, 0x28, 0xFE, 0x32, 0x44, 0xBB, 0x87, 0xDD, 0x65, 0x27, 0x02, + 0x71, 0x3B, 0xDA, 0x4A, 0xF7, 0x1F, 0xDA, 0xCD, 0xF7, 0x21, 0x55, 0x90, + 0x4F, 0x0F, 0xEC, 0xAE, 0x82, 0xE1, 0x9F, 0x6B, 0xD9, 0x45, 0xD3, 0xBB, + 0xF0, 0x5F, 0x87, 0xED, 0x3C, 0x2C, 0x39, 0x86, 0xDA, 0x3F, 0xDE, 0xEC, + 0x72, 0x55, 0xEB, 0x79, 0xA3, 0xAD, 0xDB, 0xDD, 0x7C, 0xB0, 0xBA, 0x1C, + 0xCE, 0xFC, 0xDE, 0x4F, 0x35, 0x76, 0xCF, 0x0F, 0xF8, 0x78, 0x1F, 0x6A, + 0x36, 0x51, 0x46, 0x27, 0x61, 0x5B, 0xE9, 0x9E, 0xCF, 0xF0, 0xA2, 0x55, + 0x7D, 0x7C, 0x25, 0x8A, 0x6F, 0x2F, 0xB4, 0xC5, 0xCF, 0x84, 0x2E, 0x2B, + 0xFD, 0x0D, 0x51, 0x10, 0x6C, 0xFB, 0x5F, 0x1B, 0xBC, 0x1B, 0x7E, 0xC5, + 0xAE, 0x3B, 0x98, 0x01, 0x31, 0x92, 0xFF, 0x0B, 0x57, 0xF4, 0x9A, 0xB2, + 0xB9, 0x57, 0xE9, 0xAB, 0xEF, 0x0D, 0x76, 0xD1, 0xF0, 0xEE, 0xF4, 0xCE, + 0x86, 0xA7, 0xE0, 0x6E, 0xE9, 0xB4, 0x69, 0xA1, 0xDF, 0x69, 0xF6, 0x33, + 0xC6, 0x69, 0x2E, 0x97, 0x13, 0x9E, 0xA5, 0x87, 0xB0, 0x57, 0x10, 0x81, + 0x37, 0xC9, 0x53, 0xB3, 0xBB, 0x7F, 0xF6, 0x92, 0xD1, 0x9C, 0xD0, 0x18, + 0xF4, 0x92, 0x6E, 0xDA, 0x83, 0x4F, 0xA6, 0x63, 0x99, 0x4C, 0xA5, 0xFB, + 0x5E, 0xEF, 0x21, 0x64, 0x7A, 0x20, 0x5F, 0x6C, 0x64, 0x85, 0x15, 0xCB, + 0x37, 0xE9, 0x62, 0x0C, 0x0B, 0x2A, 0x16, 0xDC, 0x01, 0x2E, 0x32, 0xDA, + 0x3E, 0x4B, 0xF5, 0x9E, 0x3A, 0xF6, 0x17, 0x40, 0x94, 0xEF, 0x9E, 0x91, + 0x08, 0x86, 0xFA, 0xBE, 0x63, 0xA8, 0x5A, 0x33, 0xEC, 0xCB, 0x74, 0x43, + 0x95, 0xF9, 0x6C, 0x69, 0x52, 0x36, 0xC7, 0x29, 0x6F, 0xFC, 0x55, 0x03, + 0x5C, 0x1F, 0xFB, 0x9F, 0xBD, 0x47, 0xEB, 0xE7, 0x49, 0x47, 0x95, 0x0B, + 0x4E, 0x89, 0x22, 0x09, 0x49, 0xE0, 0xF5, 0x61, 0x1E, 0xF1, 0xBF, 0x2E, + 0x8A, 0x72, 0x6E, 0x80, 0x59, 0xFF, 0x57, 0x3A, 0xF9, 0x75, 0x32, 0xA3, + 0x4E, 0x5F, 0xEC, 0xED, 0x28, 0x62, 0xD9, 0x4D, 0x73, 0xF2, 0xCC, 0x81, + 0x17, 0x60, 0xED, 0xCD, 0xEB, 0xDC, 0xDB, 0xA7, 0xCA, 0xC5, 0x7E, 0x02, + 0xBD, 0xF2, 0x54, 0x08, 0x54, 0xFD, 0xB4, 0x2D, 0x09, 0x2C, 0x17, 0x54, + 0x4A, 0x98, 0xD1, 0x54, 0xE1, 0x51, 0x67, 0x08, 0xD2, 0xED, 0x6E, 0x7E, + 0x6F, 0x3F, 0xD2, 0x2D, 0x81, 0x59, 0x29, 0x66, 0xCB, 0x90, 0x39, 0x95, + 0x11, 0x1E, 0x74, 0x27, 0xFE, 0xDD, 0xEB, 0xAF +}; + +static const unsigned char TA253_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA254_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA254_EC_Q[] = { + 0x04, 0x29, 0x97, 0xA7, 0xC6, 0x41, 0x7F, 0xC0, 0x0D, 0x9B, 0xE8, 0x01, + 0x1B, 0x56, 0xC6, 0xF2, 0x52, 0xA5, 0xBA, 0x2D, 0xB2, 0x12, 0xE8, 0xD2, + 0x2E, 0xD7, 0xFA, 0xC9, 0xC5, 0xD8, 0xAA, 0x6D, 0x1F, 0x73, 0x81, 0x3B, + 0x3B, 0x98, 0x6B, 0x39, 0x7C, 0x33, 0xA5, 0xC5, 0x4E, 0x86, 0x8E, 0x80, + 0x17, 0x68, 0x62, 0x45, 0x57, 0x7D, 0x44, 0x58, 0x1D, 0xB3, 0x37, 0xE5, + 0x67, 0x08, 0xEB, 0x66, 0xDE +}; + +static const unsigned char TA255_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x34 +}; + +static const unsigned char TA255_EC_Q[] = { + 0x04, 0xD2, 0xAB, 0x8A, 0x37, 0x4F, 0xA3, 0x53, 0x0D, 0xFE, 0xC1, 0x8A, + 0x7B, 0x4B, 0xA8, 0x7B, 0x46, 0x4B, 0x63, 0xB0, 0x62, 0xF6, 0x2D, 0x1B, + 0xDB, 0x08, 0x71, 0x21, 0xD2, 0x00, 0xE8, 0x63, 0xBD, 0x9A, 0x27, 0xFB, + 0xF0, 0x39, 0x6E, 0x5D, 0xEA, 0x3D, 0xA5, 0xC9, 0x81, 0xAA, 0xA3, 0x5B, + 0x20, 0x98, 0x45, 0x5D, 0x16, 0xDB, 0xFD, 0xE8, 0x10, 0x6D, 0xE3, 0x9C, + 0xE0, 0xE3, 0xBD, 0x5F, 0x84, 0x62, 0xF3, 0x70, 0x64, 0x33, 0xA0, 0xCB, + 0x24, 0x2F, 0x70, 0xBA, 0x88, 0xA1, 0x2A, 0xA0, 0x75, 0xF8, 0x81, 0xAE, + 0x62, 0x06, 0xC4, 0x81, 0xDB, 0x39, 0x6E, 0x29, 0xB0, 0x1E, 0xFA, 0x2E, + 0x5C +}; + +static const unsigned char TA256_DN[] = { + 0x30, 0x3C, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x15, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x0D, + 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x04, 0x41, 0x74, 0x6F, + 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x44, 0x45 +}; + +static const unsigned char TA256_RSA_N[] = { + 0x95, 0x85, 0x3B, 0x97, 0x6F, 0x2A, 0x3B, 0x2E, 0x3B, 0xCF, 0xA6, 0xF3, + 0x29, 0x35, 0xBE, 0xCF, 0x18, 0xAC, 0x3E, 0xAA, 0xD9, 0xF8, 0x4D, 0xA0, + 0x3E, 0x1A, 0x47, 0xB9, 0xBC, 0x9A, 0xDF, 0xF2, 0xFE, 0xCC, 0x3E, 0x47, + 0xE8, 0x7A, 0x96, 0xC2, 0x24, 0x8E, 0x35, 0xF4, 0xA9, 0x0C, 0xFC, 0x82, + 0xFD, 0x6D, 0xC1, 0x72, 0x62, 0x27, 0xBD, 0xEA, 0x6B, 0xEB, 0xE7, 0x8A, + 0xCC, 0x54, 0x3E, 0x90, 0x50, 0xCF, 0x80, 0xD4, 0x95, 0xFB, 0xE8, 0xB5, + 0x82, 0xD4, 0x14, 0xC5, 0xB6, 0xA9, 0x55, 0x25, 0x57, 0xDB, 0xB1, 0x50, + 0xF6, 0xB0, 0x60, 0x64, 0x59, 0x7A, 0x69, 0xCF, 0x03, 0xB7, 0x6F, 0x0D, + 0xBE, 0xCA, 0x3E, 0x6F, 0x74, 0x72, 0xEA, 0xAA, 0x30, 0x2A, 0x73, 0x62, + 0xBE, 0x49, 0x91, 0x61, 0xC8, 0x11, 0xFE, 0x0E, 0x03, 0x2A, 0xF7, 0x6A, + 0x20, 0xDC, 0x02, 0x15, 0x0D, 0x5E, 0x15, 0x6A, 0xFC, 0xE3, 0x82, 0xC1, + 0xB5, 0xC5, 0x9D, 0x64, 0x09, 0x6C, 0xA3, 0x59, 0x98, 0x07, 0x27, 0xC7, + 0x1B, 0x96, 0x2B, 0x61, 0x74, 0x71, 0x6C, 0x43, 0xF1, 0xF7, 0x35, 0x89, + 0x10, 0xE0, 0x9E, 0xEC, 0x55, 0xA1, 0x37, 0x22, 0xA2, 0x87, 0x04, 0x05, + 0x2C, 0x47, 0x7D, 0xB4, 0x1C, 0xB9, 0x62, 0x29, 0x66, 0x28, 0xCA, 0xB7, + 0xE1, 0x93, 0xF5, 0xA4, 0x94, 0x03, 0x99, 0xB9, 0x70, 0x85, 0xB5, 0xE6, + 0x48, 0xEA, 0x8D, 0x50, 0xFC, 0xD9, 0xDE, 0xCC, 0x6F, 0x07, 0x0E, 0xDD, + 0x0B, 0x72, 0x9D, 0x80, 0x30, 0x16, 0x07, 0x95, 0x3F, 0x28, 0x0E, 0xFD, + 0xC5, 0x75, 0x4F, 0x53, 0xD6, 0x74, 0x9A, 0xB4, 0x24, 0x2E, 0x8E, 0x02, + 0x91, 0xCF, 0x76, 0xC5, 0x9B, 0x1E, 0x55, 0x74, 0x9C, 0x78, 0x21, 0xB1, + 0xF0, 0x2D, 0xF1, 0x0B, 0x9F, 0xC2, 0xD5, 0x96, 0x18, 0x1F, 0xF0, 0x54, + 0x22, 0x7A, 0x8C, 0x07 +}; + +static const unsigned char TA256_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA257_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x45, 0x43, 0x43, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA257_EC_Q[] = { + 0x04, 0x96, 0x86, 0x58, 0x28, 0x37, 0x0A, 0x67, 0xD0, 0xA0, 0xDE, 0x24, + 0x19, 0x19, 0xE1, 0xE4, 0x05, 0x07, 0x1F, 0x97, 0xED, 0xE8, 0x64, 0x82, + 0xB9, 0xF6, 0xC4, 0x71, 0x50, 0xCE, 0x8A, 0x0C, 0xFF, 0xD7, 0xB5, 0x76, + 0xBB, 0xA1, 0x6C, 0x93, 0x6C, 0x83, 0xA2, 0x68, 0x6E, 0xA5, 0xD9, 0xBE, + 0x2C, 0x88, 0x95, 0x41, 0xCD, 0x5D, 0xDD, 0xB1, 0xCA, 0x83, 0x63, 0x83, + 0xCC, 0xC0, 0xBE, 0x74, 0xD9, 0xE0, 0x9D, 0xA4, 0xEE, 0x4A, 0x4E, 0x56, + 0xE0, 0x98, 0x29, 0x41, 0x93, 0x52, 0x10, 0xD5, 0x24, 0x38, 0x02, 0x32, + 0x67, 0xF1, 0x94, 0x12, 0x6F, 0xEF, 0xD7, 0xC5, 0xDE, 0x2E, 0xFD, 0x19, + 0x80 +}; + +static const unsigned char TA258_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA258_RSA_N[] = { + 0xB6, 0x80, 0x0E, 0xC4, 0x79, 0xBD, 0x05, 0x8C, 0x7D, 0xB0, 0xA3, 0x9D, + 0x4D, 0x22, 0x4D, 0xCB, 0xF0, 0x41, 0x97, 0x4D, 0x59, 0xE0, 0xD1, 0xFE, + 0x56, 0x8C, 0x97, 0xF2, 0xD7, 0xBD, 0x8F, 0x6C, 0xB7, 0x23, 0x8F, 0x5F, + 0xD5, 0xC4, 0xD8, 0x41, 0xCB, 0xF2, 0x02, 0x1E, 0x71, 0xE5, 0xE9, 0xF6, + 0x5E, 0xCB, 0x08, 0x2A, 0x5E, 0x30, 0xF2, 0x2D, 0x66, 0xC7, 0x84, 0x1B, + 0x64, 0x57, 0x38, 0x9D, 0x75, 0x2D, 0x56, 0xC6, 0x2F, 0x61, 0xEF, 0x96, + 0xFC, 0x20, 0x46, 0xBD, 0xEB, 0xD4, 0x7B, 0x3F, 0x3F, 0x7C, 0x47, 0x38, + 0x04, 0xA9, 0x1B, 0xAA, 0x52, 0xDF, 0x13, 0x37, 0xD3, 0x15, 0x15, 0x4E, + 0xBD, 0x5F, 0x7C, 0xAF, 0xAD, 0x63, 0xC7, 0x79, 0xDC, 0x08, 0x7B, 0xD5, + 0xA0, 0xE5, 0xF7, 0x5B, 0x75, 0xAC, 0x80, 0x55, 0x99, 0x92, 0x61, 0x9B, + 0xCD, 0x2A, 0x17, 0x7D, 0xDB, 0x8F, 0xF4, 0xB5, 0x6A, 0xEA, 0x17, 0x4A, + 0x64, 0x28, 0x66, 0x15, 0x29, 0x6C, 0x02, 0xF1, 0x6B, 0xD5, 0xBA, 0xA3, + 0x33, 0xDC, 0x5A, 0x67, 0xA7, 0x05, 0xE2, 0xBF, 0x65, 0xB6, 0x16, 0xB0, + 0x10, 0xED, 0xCD, 0x50, 0x33, 0xC9, 0x70, 0x50, 0xEC, 0x19, 0x8E, 0xB0, + 0xC7, 0xF2, 0x74, 0x5B, 0x6B, 0x44, 0xC6, 0x7D, 0x96, 0xB9, 0x98, 0x08, + 0x59, 0x66, 0xDE, 0x29, 0x01, 0x9B, 0xF4, 0x2A, 0x6D, 0xD3, 0x15, 0x3A, + 0x90, 0x6A, 0x67, 0xF1, 0xB4, 0x6B, 0x66, 0xD9, 0x21, 0xEB, 0xCA, 0xD9, + 0x62, 0x7C, 0x46, 0x10, 0x5C, 0xDE, 0x75, 0x49, 0x67, 0x9E, 0x42, 0xF9, + 0xFE, 0x75, 0xA9, 0xA3, 0xAD, 0xFF, 0x76, 0x0A, 0x67, 0x40, 0xE3, 0xC5, + 0xF7, 0x8D, 0xC7, 0x85, 0x9A, 0x59, 0x9E, 0x62, 0x9A, 0x6A, 0xED, 0x45, + 0x87, 0x98, 0x67, 0xB2, 0xD5, 0x4A, 0x3C, 0xD7, 0xB4, 0x3B, 0x00, 0x0D, + 0xC0, 0x8F, 0x1F, 0xE1, 0x40, 0xC4, 0xAE, 0x6C, 0x21, 0xDC, 0x49, 0x7E, + 0x7E, 0xCA, 0xB2, 0x8D, 0x6D, 0xB6, 0xBF, 0x93, 0x2F, 0xA1, 0x5C, 0x3E, + 0x8F, 0xCA, 0xED, 0x80, 0x8E, 0x58, 0xE1, 0xDB, 0x57, 0xCF, 0x85, 0x36, + 0x38, 0xB2, 0x71, 0xA4, 0x09, 0x8C, 0x92, 0x89, 0x08, 0x88, 0x48, 0xF1, + 0x40, 0x63, 0x18, 0xB2, 0x5B, 0x8C, 0x5A, 0xE3, 0xC3, 0xD3, 0x17, 0xAA, + 0xAB, 0x19, 0xA3, 0x2C, 0x1B, 0xE4, 0xD5, 0xC6, 0xE2, 0x66, 0x7A, 0xD7, + 0x82, 0x19, 0xA6, 0x3B, 0x16, 0x2C, 0x2F, 0x71, 0x87, 0x5F, 0x45, 0x9E, + 0x95, 0x73, 0x93, 0xC2, 0x42, 0x81, 0x21, 0x13, 0x96, 0xD7, 0x9D, 0xBB, + 0x93, 0x68, 0x15, 0xFA, 0x9D, 0xA4, 0x1D, 0x8C, 0xF2, 0x81, 0xE0, 0x58, + 0x06, 0xBD, 0xC9, 0xB6, 0xE3, 0xF6, 0x89, 0x5D, 0x89, 0xF9, 0xAC, 0x44, + 0xA1, 0xCB, 0x6B, 0xFA, 0x16, 0xF1, 0xC7, 0x50, 0x3D, 0x24, 0xDA, 0xF7, + 0xC3, 0xE4, 0x87, 0xD5, 0x56, 0xF1, 0x4F, 0x90, 0x30, 0xFA, 0x45, 0x09, + 0x59, 0xDA, 0x34, 0xCE, 0xE0, 0x13, 0x1C, 0x04, 0x7C, 0x00, 0xD4, 0x9B, + 0x86, 0xA4, 0x40, 0xBC, 0xD9, 0xDC, 0x4C, 0x57, 0x7E, 0xAE, 0xB7, 0x33, + 0xB6, 0x5E, 0x76, 0xE1, 0x65, 0x8B, 0x66, 0xDF, 0x8D, 0xCA, 0xD7, 0x98, + 0xAF, 0xCE, 0x36, 0x98, 0x8C, 0x9C, 0x83, 0x99, 0x03, 0x70, 0xF3, 0xAF, + 0x74, 0xED, 0xC6, 0x0E, 0x36, 0xE7, 0xBD, 0xEC, 0xC1, 0x73, 0xA7, 0x94, + 0x5A, 0xCB, 0x92, 0x64, 0x82, 0xA6, 0x00, 0xC1, 0x70, 0xA1, 0x6E, 0x2C, + 0x29, 0xE1, 0x58, 0x57, 0xEC, 0x5A, 0x7C, 0x99, 0x6B, 0x25, 0xA4, 0x90, + 0x3A, 0x80, 0xF4, 0x20, 0x9D, 0x9A, 0xCE, 0xC7, 0x2D, 0xF9, 0xB2, 0x4B, + 0x29, 0x95, 0x83, 0xE9, 0x35, 0x8D, 0xA7, 0x49, 0x48, 0xA7, 0x0F, 0x4C, + 0x19, 0x91, 0xD0, 0xF5, 0xBF, 0x10, 0xE0, 0x71 +}; + +static const unsigned char TA258_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA259_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x39, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, 0x20, + 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x63, 0x69, 0x6F, 0x6E, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, + 0x6F, 0x66, 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x43, 0x49, + 0x46, 0x20, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38 +}; + +static const unsigned char TA259_RSA_N[] = { + 0xCA, 0x96, 0x6B, 0x8E, 0xEA, 0xF8, 0xFB, 0xF1, 0xA2, 0x35, 0xE0, 0x7F, + 0x4C, 0xDA, 0xE0, 0xC3, 0x52, 0xD7, 0x7D, 0xB6, 0x10, 0xC8, 0x02, 0x5E, + 0xB3, 0x43, 0x2A, 0xC4, 0x4F, 0x6A, 0xB2, 0xCA, 0x1C, 0x5D, 0x28, 0x9A, + 0x78, 0x11, 0x1A, 0x69, 0x59, 0x57, 0xAF, 0xB5, 0x20, 0x42, 0xE4, 0x8B, + 0x0F, 0xE6, 0xDF, 0x5B, 0xA6, 0x03, 0x92, 0x2F, 0xF5, 0x11, 0xE4, 0x62, + 0xD7, 0x32, 0x71, 0x38, 0xD9, 0x04, 0x0C, 0x71, 0xAB, 0x3D, 0x51, 0x7E, + 0x0F, 0x07, 0xDF, 0x63, 0x05, 0x5C, 0xE9, 0xBF, 0x94, 0x6F, 0xC1, 0x29, + 0x82, 0xC0, 0xB4, 0xDA, 0x51, 0xB0, 0xC1, 0x3C, 0xBB, 0xAD, 0x37, 0x4A, + 0x5C, 0xCA, 0xF1, 0x4B, 0x36, 0x0E, 0x24, 0xAB, 0xBF, 0xC3, 0x84, 0x77, + 0xFD, 0xA8, 0x50, 0xF4, 0xB1, 0xE7, 0xC6, 0x2F, 0xD2, 0x2D, 0x59, 0x8D, + 0x7A, 0x0A, 0x4E, 0x96, 0x69, 0x52, 0x02, 0xAA, 0x36, 0x98, 0xEC, 0xFC, + 0xFA, 0x14, 0x83, 0x0C, 0x37, 0x1F, 0xC9, 0x92, 0x37, 0x7F, 0xD7, 0x81, + 0x2D, 0xE5, 0xC4, 0xB9, 0xE0, 0x3E, 0x34, 0xFE, 0x67, 0xF4, 0x3E, 0x66, + 0xD1, 0xD3, 0xF4, 0x40, 0xCF, 0x5E, 0x62, 0x34, 0x0F, 0x70, 0x06, 0x3E, + 0x20, 0x18, 0x5A, 0xCE, 0xF7, 0x72, 0x1B, 0x25, 0x6C, 0x93, 0x74, 0x14, + 0x93, 0xA3, 0x73, 0xB1, 0x0E, 0xAA, 0x87, 0x10, 0x23, 0x59, 0x5F, 0x20, + 0x05, 0x19, 0x47, 0xED, 0x68, 0x8E, 0x92, 0x12, 0xCA, 0x5D, 0xFC, 0xD6, + 0x2B, 0xB2, 0x92, 0x3C, 0x20, 0xCF, 0xE1, 0x5F, 0xAF, 0x20, 0xBE, 0xA0, + 0x76, 0x7F, 0x76, 0xE5, 0xEC, 0x1A, 0x86, 0x61, 0x33, 0x3E, 0xE7, 0x7B, + 0xB4, 0x3F, 0xA0, 0x0F, 0x8E, 0xA2, 0xB9, 0x6A, 0x6F, 0xB9, 0x87, 0x26, + 0x6F, 0x41, 0x6C, 0x88, 0xA6, 0x50, 0xFD, 0x6A, 0x63, 0x0B, 0xF5, 0x93, + 0x16, 0x1B, 0x19, 0x8F, 0xB2, 0xED, 0x9B, 0x9B, 0xC9, 0x90, 0xF5, 0x01, + 0x0C, 0xDF, 0x19, 0x3D, 0x0F, 0x3E, 0x38, 0x23, 0xC9, 0x2F, 0x8F, 0x0C, + 0xD1, 0x02, 0xFE, 0x1B, 0x55, 0xD6, 0x4E, 0xD0, 0x8D, 0x3C, 0xAF, 0x4F, + 0xA4, 0xF3, 0xFE, 0xAF, 0x2A, 0xD3, 0x05, 0x9D, 0x79, 0x08, 0xA1, 0xCB, + 0x57, 0x31, 0xB4, 0x9C, 0xC8, 0x90, 0xB2, 0x67, 0xF4, 0x18, 0x16, 0x93, + 0x3A, 0xFC, 0x47, 0xD8, 0xD1, 0x78, 0x96, 0x31, 0x1F, 0xBA, 0x2B, 0x0C, + 0x5F, 0x5D, 0x99, 0xAD, 0x63, 0x89, 0x5A, 0x24, 0x20, 0x76, 0xD8, 0xDF, + 0xFD, 0xAB, 0x4E, 0xA6, 0x22, 0xAA, 0x9D, 0x5E, 0xE6, 0x27, 0x8A, 0x7D, + 0x68, 0x29, 0xA3, 0xE7, 0x8A, 0xB8, 0xDA, 0x11, 0xBB, 0x17, 0x2D, 0x99, + 0x9D, 0x13, 0x24, 0x46, 0xF7, 0xC5, 0xE2, 0xD8, 0x9F, 0x8E, 0x7F, 0xC7, + 0x8F, 0x74, 0x6D, 0x5A, 0xB2, 0xE8, 0x72, 0xF5, 0xAC, 0xEE, 0x24, 0x10, + 0xAD, 0x2F, 0x14, 0xDA, 0xFF, 0x2D, 0x9A, 0x46, 0x71, 0x47, 0xBE, 0x42, + 0xDF, 0xBB, 0x01, 0xDB, 0xF4, 0x7F, 0xD3, 0x28, 0x8F, 0x31, 0x59, 0x5B, + 0xD3, 0xC9, 0x02, 0xA6, 0xB4, 0x52, 0xCA, 0x6E, 0x97, 0xFB, 0x43, 0xC5, + 0x08, 0x26, 0x6F, 0x8A, 0xF4, 0xBB, 0xFD, 0x9F, 0x28, 0xAA, 0x0D, 0xD5, + 0x45, 0xF3, 0x13, 0x3A, 0x1D, 0xD8, 0xC0, 0x78, 0x8F, 0x41, 0x67, 0x3C, + 0x1E, 0x94, 0x64, 0xAE, 0x7B, 0x0B, 0xC5, 0xE8, 0xD9, 0x01, 0x88, 0x39, + 0x1A, 0x97, 0x86, 0x64, 0x41, 0xD5, 0x3B, 0x87, 0x0C, 0x6E, 0xFA, 0x0F, + 0xC6, 0xBD, 0x48, 0x14, 0xBF, 0x39, 0x4D, 0xD4, 0x9E, 0x41, 0xB6, 0x8F, + 0x96, 0x1D, 0x63, 0x96, 0x93, 0xD9, 0x95, 0x06, 0x78, 0x31, 0x68, 0x9E, + 0x37, 0x06, 0x3B, 0x80, 0x89, 0x45, 0x61, 0x39, 0x23, 0xC7, 0x1B, 0x44, + 0xA3, 0x15, 0xE5, 0x1C, 0xF8, 0x92, 0x30, 0xBB +}; + +static const unsigned char TA259_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA260_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x31 +}; + +static const unsigned char TA260_RSA_N[] = { + 0xF1, 0x66, 0x08, 0xBD, 0xD9, 0xC5, 0x15, 0x61, 0xCB, 0x84, 0x04, 0x41, + 0xA5, 0x69, 0x37, 0x77, 0x1D, 0xC1, 0xB0, 0x7B, 0xFA, 0xC3, 0x77, 0x48, + 0x90, 0x13, 0x72, 0x64, 0xD1, 0xB8, 0x7C, 0x90, 0x35, 0x9D, 0x18, 0x79, + 0x88, 0xE3, 0x97, 0x01, 0x3C, 0x47, 0x81, 0xF2, 0x0E, 0xA2, 0x98, 0x0D, + 0x9E, 0x3F, 0x37, 0xE0, 0x19, 0xB2, 0x90, 0xF2, 0x46, 0x1C, 0x92, 0xB1, + 0x3A, 0x61, 0xCE, 0xFA, 0xB7, 0x46, 0x9E, 0x03, 0x86, 0xD7, 0x33, 0x6E, + 0xED, 0xF7, 0x45, 0x8C, 0x76, 0x37, 0xDE, 0x6E, 0x96, 0x91, 0xF7, 0xD7, + 0x7E, 0x2B, 0x87, 0x17, 0xD5, 0x8B, 0x35, 0xEE, 0x84, 0x91, 0x72, 0x57, + 0xDC, 0x60, 0xC3, 0xC3, 0xB9, 0xE7, 0xC7, 0x67, 0x24, 0x23, 0x4F, 0x63, + 0x0A, 0x63, 0xF6, 0x66, 0x7D, 0x4B, 0x55, 0xA7, 0x3F, 0x78, 0x64, 0x49, + 0x69, 0x12, 0x97, 0xE0, 0x4C, 0x0D, 0xD3, 0x09, 0xA0, 0x32, 0x30, 0x3A, + 0xFA, 0x9F, 0xC0, 0xF2, 0x9C, 0xC5, 0x12, 0x2A, 0x2E, 0x1C, 0xB5, 0x04, + 0x33, 0xDA, 0xA4, 0x38, 0x11, 0x6A, 0xDE, 0xC6, 0x18, 0xF6, 0x47, 0x3A, + 0x22, 0x41, 0x87, 0x22, 0xFC, 0xC4, 0x89, 0x28, 0x54, 0xD8, 0x8C, 0xA5, + 0x30, 0x0A, 0xF8, 0x17, 0x16, 0xCA, 0xAC, 0x37, 0xFD, 0x79, 0xA7, 0x91, + 0x17, 0x78, 0x38, 0x99, 0xAD, 0x58, 0xED, 0xB2, 0xDE, 0xCC, 0x89, 0x7D, + 0x03, 0x9C, 0xB3, 0x89, 0x65, 0xE7, 0xE3, 0x3B, 0xB1, 0x22, 0x86, 0x8F, + 0x06, 0x6D, 0x78, 0x07, 0xFD, 0x91, 0x12, 0x7F, 0xB0, 0x6B, 0x1C, 0x89, + 0x0D, 0xF9, 0xB8, 0xCB, 0x74, 0x5B, 0x07, 0xC2, 0xC8, 0xF4, 0x35, 0xD1, + 0x64, 0x63, 0x7A, 0xE9, 0x6E, 0x9A, 0x28, 0xD6, 0x30, 0xBD, 0xE6, 0x1B, + 0xDD, 0x15, 0xAF, 0x84, 0xEA, 0x9C, 0xC7, 0xCA, 0xF5, 0x0E, 0xEA, 0xF2, + 0x5D, 0x29, 0x87, 0x8F, 0x69, 0x73, 0x39, 0xBE, 0x2E, 0x24, 0x6F, 0x45, + 0x21, 0xAC, 0xC5, 0xD4, 0x69, 0x25, 0x06, 0x83, 0xAD, 0x7A, 0x48, 0x85, + 0x13, 0x2C, 0x0D, 0x06, 0xB8, 0x6C, 0x79, 0x56, 0xFC, 0xA3, 0x67, 0x32, + 0x81, 0xF5, 0x57, 0xA5, 0xCA, 0x57, 0x42, 0x69, 0xE9, 0x5C, 0x24, 0x61, + 0xEF, 0xE2, 0x30, 0x18, 0x4E, 0x44, 0x98, 0x55, 0x6F, 0x7A, 0xC2, 0x93, + 0xD8, 0x19, 0xB6, 0xDE, 0x7C, 0x47, 0x8A, 0x11, 0x4E, 0x49, 0x47, 0xDB, + 0x28, 0x94, 0x02, 0x0B, 0x94, 0x4A, 0x2C, 0xF9, 0x12, 0xD0, 0x4F, 0xE8, + 0x31, 0x7E, 0x6C, 0x7A, 0xBF, 0xA6, 0x3F, 0x9B, 0x39, 0x3D, 0x02, 0x16, + 0xA3, 0x18, 0xB3, 0x67, 0xAC, 0x5B, 0x3F, 0x2C, 0x83, 0x2B, 0x67, 0x39, + 0x81, 0x5C, 0xB9, 0x7E, 0x94, 0xD5, 0x64, 0xDD, 0x9E, 0x8F, 0x6E, 0xAE, + 0xE8, 0x7C, 0x5B, 0xB4, 0xD7, 0x6A, 0x47, 0x48, 0xD7, 0x7E, 0xB3, 0xD4, + 0x2D, 0x8E, 0x56, 0x76, 0x4E, 0xCF, 0x69, 0xF1, 0x6E, 0x44, 0x6C, 0xD4, + 0x24, 0xEA, 0x8D, 0x24, 0xA1, 0x18, 0xBF, 0xBD, 0x57, 0xFE, 0xA9, 0x99, + 0x35, 0xB5, 0xDB, 0x10, 0x77, 0xB8, 0x3D, 0x48, 0xBA, 0xD6, 0xC1, 0xE7, + 0xF1, 0x23, 0x3E, 0xD7, 0xDF, 0x85, 0x9D, 0x27, 0x3C, 0xD4, 0x40, 0xBD, + 0x0A, 0x0C, 0xBD, 0xF5, 0xE7, 0x8D, 0x25, 0xD6, 0x81, 0x74, 0x87, 0x46, + 0xD4, 0x29, 0x75, 0xA2, 0x42, 0x6C, 0xF7, 0x73, 0x89, 0xE7, 0x7D, 0xBF, + 0x7A, 0x4A, 0x1F, 0xD3, 0x22, 0xC9, 0x15, 0x55, 0xCF, 0xDF, 0x6F, 0x7C, + 0x55, 0xD0, 0xA4, 0x8B, 0x07, 0x11, 0x37, 0x5F, 0x83, 0xA6, 0x26, 0x57, + 0xA6, 0x01, 0x5B, 0x7E, 0xFE, 0x58, 0x68, 0x07, 0xA9, 0xE9, 0x7A, 0xD9, + 0xB9, 0xE8, 0xFF, 0x50, 0x1F, 0xAB, 0xC2, 0xB4, 0xC0, 0xCE, 0xE8, 0xEA, + 0xFD, 0x0F, 0xBD, 0x8D, 0x4D, 0xB8, 0xBC, 0x71 +}; + +static const unsigned char TA260_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA261_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x32 +}; + +static const unsigned char TA261_EC_Q[] = { + 0x04, 0x9D, 0xCB, 0x80, 0x91, 0x8D, 0x53, 0x67, 0xB5, 0xB9, 0x50, 0xB1, + 0x03, 0xF8, 0xE5, 0x49, 0x1F, 0x41, 0x22, 0x09, 0xB0, 0x51, 0x52, 0x58, + 0xD6, 0x2B, 0x34, 0x8F, 0xC5, 0x12, 0x46, 0x14, 0xC5, 0x8B, 0x2F, 0x2C, + 0x84, 0xFF, 0x2C, 0x6E, 0xA8, 0xD5, 0xF1, 0x09, 0xE3, 0x03, 0x21, 0x14, + 0xC4, 0x43, 0x3D, 0x7C, 0xC1, 0x2C, 0xC4, 0x4B, 0x6A, 0x4A, 0xCD, 0xE9, + 0x87, 0xE0, 0x7D, 0xF6, 0x22, 0xBE, 0xFA, 0x4A, 0x51, 0xB8, 0x30, 0x8A, + 0xFD, 0xE1, 0xDE, 0x18, 0x12, 0x0A, 0xF6, 0x47, 0xB7, 0xE7, 0x17, 0xBF, + 0x27, 0x8A, 0xD4, 0x41, 0x4C, 0x96, 0x3C, 0x60, 0x96, 0xC1, 0xFD, 0x15, + 0x1C +}; + +static const unsigned char TA262_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x42, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x6F, 0x72, 0x65, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, 0x43, 0x79, + 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6C, 0x74, 0x69, + 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA262_RSA_N[] = { + 0xA3, 0x04, 0xBB, 0x22, 0xAB, 0x98, 0x3D, 0x57, 0xE8, 0x26, 0x72, 0x9A, + 0xB5, 0x79, 0xD4, 0x29, 0xE2, 0xE1, 0xE8, 0x95, 0x80, 0xB1, 0xB0, 0xE3, + 0x5B, 0x8E, 0x2B, 0x29, 0x9A, 0x64, 0xDF, 0xA1, 0x5D, 0xED, 0xB0, 0x09, + 0x05, 0x6D, 0xDB, 0x28, 0x2E, 0xCE, 0x62, 0xA2, 0x62, 0xFE, 0xB4, 0x88, + 0xDA, 0x12, 0xEB, 0x38, 0xEB, 0x21, 0x9D, 0xC0, 0x41, 0x2B, 0x01, 0x52, + 0x7B, 0x88, 0x77, 0xD3, 0x1C, 0x8F, 0xC7, 0xBA, 0xB9, 0x88, 0xB5, 0x6A, + 0x09, 0xE7, 0x73, 0xE8, 0x11, 0x40, 0xA7, 0xD1, 0xCC, 0xCA, 0x62, 0x8D, + 0x2D, 0xE5, 0x8F, 0x0B, 0xA6, 0x50, 0xD2, 0xA8, 0x50, 0xC3, 0x28, 0xEA, + 0xF5, 0xAB, 0x25, 0x87, 0x8A, 0x9A, 0x96, 0x1C, 0xA9, 0x67, 0xB8, 0x3F, + 0x0C, 0xD5, 0xF7, 0xF9, 0x52, 0x13, 0x2F, 0xC2, 0x1B, 0xD5, 0x70, 0x70, + 0xF0, 0x8F, 0xC0, 0x12, 0xCA, 0x06, 0xCB, 0x9A, 0xE1, 0xD9, 0xCA, 0x33, + 0x7A, 0x77, 0xD6, 0xF8, 0xEC, 0xB9, 0xF1, 0x68, 0x44, 0x42, 0x48, 0x13, + 0xD2, 0xC0, 0xC2, 0xA4, 0xAE, 0x5E, 0x60, 0xFE, 0xB6, 0xA6, 0x05, 0xFC, + 0xB4, 0xDD, 0x07, 0x59, 0x02, 0xD4, 0x59, 0x18, 0x98, 0x63, 0xF5, 0xA5, + 0x63, 0xE0, 0x90, 0x0C, 0x7D, 0x5D, 0xB2, 0x06, 0x7A, 0xF3, 0x85, 0xEA, + 0xEB, 0xD4, 0x03, 0xAE, 0x5E, 0x84, 0x3E, 0x5F, 0xFF, 0x15, 0xED, 0x69, + 0xBC, 0xF9, 0x39, 0x36, 0x72, 0x75, 0xCF, 0x77, 0x52, 0x4D, 0xF3, 0xC9, + 0x90, 0x2C, 0xB9, 0x3D, 0xE5, 0xC9, 0x23, 0x53, 0x3F, 0x1F, 0x24, 0x98, + 0x21, 0x5C, 0x07, 0x99, 0x29, 0xBD, 0xC6, 0x3A, 0xEC, 0xE7, 0x6E, 0x86, + 0x3A, 0x6B, 0x97, 0x74, 0x63, 0x33, 0xBD, 0x68, 0x18, 0x31, 0xF0, 0x78, + 0x8D, 0x76, 0xBF, 0xFC, 0x9E, 0x8E, 0x5D, 0x2A, 0x86, 0xA7, 0x4D, 0x90, + 0xDC, 0x27, 0x1A, 0x39 +}; + +static const unsigned char TA262_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA263_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA263_RSA_N[] = { + 0xD7, 0xC7, 0x5E, 0xF7, 0xC1, 0x07, 0xD4, 0x77, 0xFB, 0x43, 0x21, 0xF4, + 0xF4, 0xF5, 0x69, 0xE4, 0xEE, 0x32, 0x01, 0xDB, 0xA3, 0x86, 0x1F, 0xE4, + 0x59, 0x0D, 0xBA, 0xE7, 0x75, 0x83, 0x52, 0xEB, 0xEA, 0x1C, 0x61, 0x15, + 0x48, 0xBB, 0x1D, 0x07, 0xCA, 0x8C, 0xAE, 0xB0, 0xDC, 0x96, 0x9D, 0xEA, + 0xC3, 0x60, 0x92, 0x86, 0x82, 0x28, 0x73, 0x9C, 0x56, 0x06, 0xFF, 0x4B, + 0x64, 0xF0, 0x0C, 0x2A, 0x37, 0x49, 0xB5, 0xE5, 0xCF, 0x0C, 0x7C, 0xEE, + 0xF1, 0x4A, 0xBB, 0x73, 0x30, 0x65, 0xF3, 0xD5, 0x2F, 0x83, 0xB6, 0x7E, + 0xE3, 0xE7, 0xF5, 0x9E, 0xAB, 0x60, 0xF9, 0xD3, 0xF1, 0x9D, 0x92, 0x74, + 0x8A, 0xE4, 0x1C, 0x96, 0xAC, 0x5B, 0x80, 0xE9, 0xB5, 0xF4, 0x31, 0x87, + 0xA3, 0x51, 0xFC, 0xC7, 0x7E, 0xA1, 0x6F, 0x8E, 0x53, 0x77, 0xD4, 0x97, + 0xC1, 0x55, 0x33, 0x92, 0x3E, 0x18, 0x2F, 0x75, 0xD4, 0xAD, 0x86, 0x49, + 0xCB, 0x95, 0xAF, 0x54, 0x06, 0x6C, 0xD8, 0x06, 0x13, 0x8D, 0x5B, 0xFF, + 0xE1, 0x26, 0x19, 0x59, 0xC0, 0x24, 0xBA, 0x81, 0x71, 0x79, 0x90, 0x44, + 0x50, 0x68, 0x24, 0x94, 0x5F, 0xB8, 0xB3, 0x11, 0xF1, 0x29, 0x41, 0x61, + 0xA3, 0x41, 0xCB, 0x23, 0x36, 0xD5, 0xC1, 0xF1, 0x32, 0x50, 0x10, 0x4E, + 0x7F, 0xF4, 0x86, 0x93, 0xEC, 0x84, 0xD3, 0x8E, 0xBC, 0x4B, 0xBF, 0x5C, + 0x01, 0x4E, 0x07, 0x3D, 0xDC, 0x14, 0x8A, 0x94, 0x0A, 0xA4, 0xEA, 0x73, + 0xFB, 0x0B, 0x51, 0xE8, 0x13, 0x07, 0x18, 0xFA, 0x0E, 0xF1, 0x2B, 0xD1, + 0x54, 0x15, 0x7D, 0x3C, 0xE1, 0xF7, 0xB4, 0x19, 0x42, 0x67, 0x62, 0x5E, + 0x77, 0xE0, 0xA2, 0x55, 0xEC, 0xB6, 0xD9, 0x69, 0x17, 0xD5, 0x3A, 0xAF, + 0x44, 0xED, 0x4A, 0xC5, 0x9E, 0xE4, 0x7A, 0x27, 0x7C, 0xE5, 0x75, 0xD7, + 0xAA, 0xCB, 0x25, 0xE7, 0xDF, 0x6B, 0x0A, 0xDB, 0x0F, 0x4D, 0x93, 0x4E, + 0xA8, 0xA0, 0xCD, 0x7B, 0x2E, 0xF2, 0x59, 0x01, 0x6A, 0xB7, 0x0D, 0xB8, + 0x07, 0x81, 0x7E, 0x8B, 0x38, 0x1B, 0x38, 0xE6, 0x0A, 0x57, 0x99, 0x3D, + 0xEE, 0x21, 0xE8, 0xA3, 0xF5, 0x0C, 0x16, 0xDD, 0x8B, 0xEC, 0x34, 0x8E, + 0x9C, 0x2A, 0x1C, 0x00, 0x15, 0x17, 0x8D, 0x68, 0x83, 0xD2, 0x70, 0x9F, + 0x18, 0x08, 0xCD, 0x11, 0x68, 0xD5, 0xC9, 0x6B, 0x52, 0xCD, 0xC4, 0x46, + 0x8F, 0xDC, 0xB5, 0xF3, 0xD8, 0x57, 0x73, 0x1E, 0xE9, 0x94, 0x39, 0x04, + 0xBF, 0xD3, 0xDE, 0x38, 0xDE, 0xB4, 0x53, 0xEC, 0x69, 0x1C, 0xA2, 0x7E, + 0xC4, 0x8F, 0xE4, 0x1B, 0x70, 0xAD, 0xF2, 0xA2, 0xF9, 0xFB, 0xF7, 0x16, + 0x64, 0x66, 0x69, 0x9F, 0x49, 0x51, 0xA2, 0xE2, 0x15, 0x18, 0x67, 0x06, + 0x4A, 0x7F, 0xD5, 0x6C, 0xB5, 0x4D, 0xB3, 0x33, 0xE0, 0x61, 0xEB, 0x5D, + 0xBE, 0xE9, 0x98, 0x0F, 0x32, 0xD7, 0x1D, 0x4B, 0x3C, 0x2E, 0x5A, 0x01, + 0x52, 0x91, 0x09, 0xF2, 0xDF, 0xEA, 0x8D, 0xD8, 0x06, 0x40, 0x63, 0xAA, + 0x11, 0xE4, 0xFE, 0xC3, 0x37, 0x9E, 0x14, 0x52, 0x3F, 0xF4, 0xE2, 0xCC, + 0xF2, 0x61, 0x93, 0xD1, 0xFD, 0x67, 0x6B, 0xD7, 0x52, 0xAE, 0xBF, 0x68, + 0xAB, 0x40, 0x43, 0xA0, 0x57, 0x35, 0x53, 0x78, 0xF0, 0x53, 0xF8, 0x61, + 0x42, 0x07, 0x64, 0xC6, 0xD7, 0x6F, 0x9B, 0x4C, 0x38, 0x0D, 0x63, 0xAC, + 0x62, 0xAF, 0x36, 0x8B, 0xA2, 0x73, 0x0A, 0x0D, 0xF5, 0x21, 0xBD, 0x74, + 0xAA, 0x4D, 0xEA, 0x72, 0x03, 0x49, 0xDB, 0xC7, 0x5F, 0x1D, 0x62, 0x63, + 0xC7, 0xFD, 0xDD, 0x91, 0xEC, 0x33, 0xEE, 0xF5, 0x6D, 0xB4, 0x6E, 0x30, + 0x68, 0xDE, 0xC8, 0xD6, 0x26, 0xB0, 0x75, 0x5E, 0x7B, 0xB4, 0x07, 0x20, + 0x98, 0xA1, 0x76, 0x32, 0xB8, 0x4D, 0x6C, 0x4F +}; + +static const unsigned char TA263_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA264_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA264_RSA_N[] = { + 0xA5, 0xDA, 0x0A, 0x95, 0x16, 0x50, 0xE3, 0x95, 0xF2, 0x5E, 0x9D, 0x76, + 0x31, 0x06, 0x32, 0x7A, 0x9B, 0xF1, 0x10, 0x76, 0xB8, 0x00, 0x9A, 0xB5, + 0x52, 0x36, 0xCD, 0x24, 0x47, 0xB0, 0x9F, 0x18, 0x64, 0xBC, 0x9A, 0xF6, + 0xFA, 0xD5, 0x79, 0xD8, 0x90, 0x62, 0x4C, 0x22, 0x2F, 0xDE, 0x38, 0x3D, + 0xD6, 0xE0, 0xA8, 0xE9, 0x1C, 0x2C, 0xDB, 0x78, 0x11, 0xE9, 0x8E, 0x68, + 0x51, 0x15, 0x72, 0xC7, 0xF3, 0x33, 0x87, 0xE4, 0xA0, 0x5D, 0x0B, 0x5C, + 0xE0, 0x57, 0x07, 0x2A, 0x30, 0xF5, 0xCD, 0xC4, 0x37, 0x77, 0x28, 0x4D, + 0x18, 0x91, 0xE6, 0xBF, 0xD5, 0x52, 0xFD, 0x71, 0x2D, 0x70, 0x3E, 0xE7, + 0xC6, 0xC4, 0x8A, 0xE3, 0xF0, 0x28, 0x0B, 0xF4, 0x76, 0x98, 0xA1, 0x8B, + 0x87, 0x55, 0xB2, 0x3A, 0x13, 0xFC, 0xB7, 0x3E, 0x27, 0x37, 0x8E, 0x22, + 0xE3, 0xA8, 0x4F, 0x2A, 0xEF, 0x60, 0xBB, 0x3D, 0xB7, 0x39, 0xC3, 0x0E, + 0x01, 0x47, 0x99, 0x5D, 0x12, 0x4F, 0xDB, 0x43, 0xFA, 0x57, 0xA1, 0xED, + 0xF9, 0x9D, 0xBE, 0x11, 0x47, 0x26, 0x5B, 0x13, 0x98, 0xAB, 0x5D, 0x16, + 0x8A, 0xB0, 0x37, 0x1C, 0x57, 0x9D, 0x45, 0xFF, 0x88, 0x96, 0x36, 0xBF, + 0xBB, 0xCA, 0x07, 0x7B, 0x6F, 0x87, 0x63, 0xD7, 0xD0, 0x32, 0x6A, 0xD6, + 0x5D, 0x6C, 0x0C, 0xF1, 0xB3, 0x6E, 0x39, 0xE2, 0x6B, 0x31, 0x2E, 0x39, + 0x00, 0x27, 0x14, 0xDE, 0x38, 0xC0, 0xEC, 0x19, 0x66, 0x86, 0x12, 0xE8, + 0x9D, 0x72, 0x16, 0x13, 0x64, 0x52, 0xC7, 0xA9, 0x37, 0x1C, 0xFD, 0x82, + 0x30, 0xED, 0x84, 0x18, 0x1D, 0xF4, 0xAE, 0x5C, 0xFF, 0x70, 0x13, 0x00, + 0xEB, 0xB1, 0xF5, 0x33, 0x7A, 0x4B, 0xD6, 0x55, 0xF8, 0x05, 0x8D, 0x4B, + 0x69, 0xB0, 0xF5, 0xB3, 0x28, 0x36, 0x5C, 0x14, 0xC4, 0x51, 0x73, 0x4D, + 0x6B, 0x0B, 0xF1, 0x34, 0x07, 0xDB, 0x17, 0x39, 0xD7, 0xDC, 0x28, 0x7B, + 0x6B, 0xF5, 0x9F, 0xF3, 0x2E, 0xC1, 0x4F, 0x17, 0x2A, 0x10, 0xF3, 0xCC, + 0xCA, 0xE8, 0xEB, 0xFD, 0x6B, 0xAB, 0x2E, 0x9A, 0x9F, 0x2D, 0x82, 0x6E, + 0x04, 0xD4, 0x52, 0x01, 0x93, 0x2D, 0x3D, 0x86, 0xFC, 0x7E, 0xFC, 0xDF, + 0xEF, 0x42, 0x1D, 0xA6, 0x6B, 0xEF, 0xB9, 0x20, 0xC6, 0xF7, 0xBD, 0xA0, + 0xA7, 0x95, 0xFD, 0xA7, 0xE6, 0x89, 0x24, 0xD8, 0xCC, 0x8C, 0x34, 0x6C, + 0xE2, 0x23, 0x2F, 0xD9, 0x12, 0x1A, 0x21, 0xB9, 0x55, 0x91, 0x6F, 0x0B, + 0x91, 0x79, 0x19, 0x0C, 0xAD, 0x40, 0x88, 0x0B, 0x70, 0xE2, 0x7A, 0xD2, + 0x0E, 0xD8, 0x68, 0x48, 0xBB, 0x82, 0x13, 0x39, 0x10, 0x58, 0xE9, 0xD8, + 0x2A, 0x07, 0xC6, 0x12, 0xDB, 0x58, 0xDB, 0xD2, 0x3B, 0x55, 0x10, 0x47, + 0x05, 0x15, 0x67, 0x62, 0x7E, 0x18, 0x63, 0xA6, 0x46, 0x3F, 0x09, 0x0E, + 0x54, 0x32, 0x5E, 0xBF, 0x0D, 0x62, 0x7A, 0x27, 0xEF, 0x80, 0xE8, 0xDB, + 0xD9, 0x4B, 0x06, 0x5A, 0x37, 0x5A, 0x25, 0xD0, 0x08, 0x12, 0x77, 0xD4, + 0x6F, 0x09, 0x50, 0x97, 0x3D, 0xC8, 0x1D, 0xC3, 0xDF, 0x8C, 0x45, 0x30, + 0x56, 0xC6, 0xD3, 0x64, 0xAB, 0x66, 0xF3, 0xC0, 0x5E, 0x96, 0x9C, 0xC3, + 0xC4, 0xEF, 0xC3, 0x7C, 0x6B, 0x8B, 0x3A, 0x79, 0x7F, 0xB3, 0x49, 0xCF, + 0x3D, 0xE2, 0x89, 0x9F, 0xA0, 0x30, 0x4B, 0x85, 0xB9, 0x9C, 0x94, 0x24, + 0x79, 0x8F, 0x7D, 0x6B, 0xA9, 0x45, 0x68, 0x0F, 0x2B, 0xD0, 0xF1, 0xDA, + 0x1C, 0xCB, 0x69, 0xB8, 0xCA, 0x49, 0x62, 0x6D, 0xC8, 0xD0, 0x63, 0x62, + 0xDD, 0x60, 0x0F, 0x58, 0xAA, 0x8F, 0xA1, 0xBC, 0x05, 0xA5, 0x66, 0xA2, + 0xCF, 0x1B, 0x76, 0xB2, 0x84, 0x64, 0xB1, 0x4C, 0x39, 0x52, 0xC0, 0x30, + 0xBA, 0xF0, 0x8C, 0x4B, 0x02, 0xB0, 0xB6, 0xB7 +}; + +static const unsigned char TA264_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA265_DN[] = { + 0x30, 0x52, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x53, 0x4B, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x0A, 0x42, 0x72, 0x61, 0x74, 0x69, 0x73, 0x6C, 0x61, 0x76, 0x61, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x61, 0x2E, 0x73, 0x2E, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x41, 0x20, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x32 +}; + +static const unsigned char TA265_RSA_N[] = { + 0xA2, 0xA3, 0xC4, 0x00, 0x09, 0xD6, 0x85, 0x5D, 0x2D, 0x6D, 0x14, 0xF6, + 0xC2, 0xC3, 0x73, 0x9E, 0x35, 0xC2, 0x71, 0x55, 0x7E, 0x81, 0xFB, 0xAB, + 0x46, 0x50, 0xE0, 0xC1, 0x7C, 0x49, 0x78, 0xE6, 0xAB, 0x79, 0x58, 0x3C, + 0xDA, 0xFF, 0x7C, 0x1C, 0x9F, 0xD8, 0x97, 0x02, 0x78, 0x3E, 0x6B, 0x41, + 0x04, 0xE9, 0x41, 0xBD, 0xBE, 0x03, 0x2C, 0x45, 0xF6, 0x2F, 0x64, 0xD4, + 0xAB, 0x5D, 0xA3, 0x47, 0x3D, 0x64, 0x9B, 0xE9, 0x68, 0x9A, 0xC6, 0xCC, + 0x1B, 0x3F, 0xBA, 0xBE, 0xB2, 0x8B, 0x34, 0x02, 0x2E, 0x98, 0x55, 0x19, + 0xFC, 0x8C, 0x6F, 0xAA, 0x5F, 0xDA, 0x4C, 0xCE, 0x4D, 0x03, 0x21, 0xA3, + 0xD8, 0xD2, 0x34, 0x93, 0x56, 0x96, 0xCB, 0x4C, 0x0C, 0x00, 0x16, 0x3C, + 0x5F, 0x1A, 0xCD, 0xC8, 0xC7, 0x6C, 0xA6, 0xAD, 0xD3, 0x31, 0xA7, 0xBC, + 0xE8, 0xE5, 0xE1, 0x66, 0xD6, 0xD2, 0xFB, 0x03, 0xB4, 0x41, 0x65, 0xC9, + 0x10, 0xAE, 0x0E, 0x05, 0x63, 0xC6, 0x80, 0x6A, 0x69, 0x30, 0xFD, 0xD2, + 0xEE, 0x90, 0xEF, 0x0D, 0x27, 0xDF, 0x9F, 0x95, 0x73, 0xF4, 0xE1, 0x25, + 0xDA, 0x6C, 0x16, 0xDE, 0x41, 0x38, 0x34, 0xEA, 0x8B, 0xFC, 0xD1, 0xE8, + 0x04, 0x14, 0x61, 0x2D, 0x41, 0x7E, 0xAC, 0xC7, 0x77, 0x4E, 0xCB, 0x51, + 0x54, 0xFB, 0x5E, 0x92, 0x18, 0x1B, 0x04, 0x5A, 0x68, 0xC6, 0xC9, 0xC4, + 0xFA, 0xB7, 0x13, 0xA0, 0x98, 0xB7, 0x11, 0x2B, 0xB7, 0xD6, 0x57, 0xCC, + 0x7C, 0x9E, 0x17, 0xD1, 0xCB, 0x25, 0xFE, 0x86, 0x4E, 0x24, 0x2E, 0x56, + 0x0C, 0x78, 0x4D, 0x9E, 0x01, 0x12, 0xA6, 0x2B, 0xA7, 0x01, 0x65, 0x6E, + 0x7C, 0x62, 0x1D, 0x84, 0x84, 0xDF, 0xEA, 0xC0, 0x6B, 0xB5, 0xA5, 0x2A, + 0x95, 0x83, 0xC3, 0x53, 0x11, 0x0C, 0x73, 0x1D, 0x0B, 0xB2, 0x46, 0x90, + 0xD1, 0x42, 0x3A, 0xCE, 0x40, 0x6E, 0x95, 0xAD, 0xFF, 0xC6, 0x94, 0xAD, + 0x6E, 0x97, 0x84, 0x8E, 0x7D, 0x6F, 0x9E, 0x8A, 0x80, 0x0D, 0x49, 0x6D, + 0x73, 0xE2, 0x7B, 0x92, 0x1E, 0xC3, 0xF3, 0xC1, 0xF3, 0xEB, 0x2E, 0x05, + 0x6F, 0xD9, 0x1B, 0xCF, 0x37, 0x76, 0x04, 0xC8, 0xB4, 0x5A, 0xE4, 0x17, + 0xA7, 0xCB, 0xDD, 0x76, 0x1F, 0xD0, 0x19, 0x76, 0xE8, 0x2C, 0x05, 0xB3, + 0xD6, 0x9C, 0x34, 0xD8, 0x96, 0xDC, 0x61, 0x87, 0x91, 0x05, 0xE4, 0x44, + 0x08, 0x33, 0xC1, 0xDA, 0xB9, 0x08, 0x65, 0xD4, 0xAE, 0xB2, 0x36, 0x0D, + 0xEB, 0xBA, 0x38, 0xBA, 0x0C, 0xE5, 0x9B, 0x9E, 0xEB, 0x8D, 0x66, 0xDD, + 0x99, 0xCF, 0xD6, 0x89, 0x41, 0xF6, 0x04, 0x92, 0x8A, 0x29, 0x29, 0x6D, + 0x6B, 0x3A, 0x1C, 0xE7, 0x75, 0x7D, 0x02, 0x71, 0x0E, 0xF3, 0xC0, 0xE7, + 0xBD, 0xCB, 0x19, 0xDD, 0x9D, 0x60, 0xB2, 0xC2, 0x66, 0x60, 0xB6, 0xB1, + 0x04, 0xEE, 0xC9, 0xE6, 0x86, 0xB9, 0x9A, 0x66, 0x40, 0xA8, 0xE7, 0x11, + 0xED, 0x81, 0x45, 0x03, 0x8B, 0xF6, 0x67, 0x59, 0xE8, 0xC1, 0x06, 0x11, + 0xBD, 0xDD, 0xCF, 0x80, 0x02, 0x4F, 0x65, 0x40, 0x78, 0x5C, 0x47, 0x50, + 0xC8, 0x9B, 0xE6, 0x1F, 0x81, 0x7B, 0xE4, 0x44, 0xA8, 0x5B, 0x85, 0x9A, + 0xE2, 0xDE, 0x5A, 0xD5, 0xC7, 0xF9, 0x3A, 0x44, 0x66, 0x4B, 0xE4, 0x32, + 0x54, 0x7C, 0xE4, 0x6C, 0x9C, 0xB3, 0x0E, 0x3D, 0x17, 0xA2, 0xB2, 0x34, + 0x12, 0xD6, 0x7E, 0xB2, 0xA8, 0x49, 0xBB, 0xD1, 0x7A, 0x28, 0x40, 0xBE, + 0xA2, 0x16, 0x1F, 0xDF, 0xE4, 0x37, 0x1F, 0x11, 0x73, 0xFB, 0x90, 0x0A, + 0x65, 0x43, 0xA2, 0x0D, 0x7C, 0xF8, 0x06, 0x01, 0x55, 0x33, 0x7D, 0xB0, + 0x0D, 0xB8, 0xF4, 0xF5, 0xAE, 0xA5, 0x42, 0x57, 0x7C, 0x36, 0x11, 0x8C, + 0x7B, 0x5E, 0xC4, 0x03, 0x9D, 0x8C, 0x79, 0x9D +}; + +static const unsigned char TA265_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA266_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x30, 0x30, 0x2E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x27, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x61, + 0x6E, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0C, 0x43, 0x46, 0x43, 0x41, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA266_RSA_N[] = { + 0xD7, 0x5D, 0x6B, 0xCD, 0x10, 0x3F, 0x1F, 0x05, 0x59, 0xD5, 0x05, 0x4D, + 0x37, 0xB1, 0x0E, 0xEC, 0x98, 0x2B, 0x8E, 0x15, 0x1D, 0xFA, 0x93, 0x4B, + 0x17, 0x82, 0x21, 0x71, 0x10, 0x52, 0xD7, 0x51, 0x64, 0x70, 0x16, 0xC2, + 0x55, 0x69, 0x4D, 0x8E, 0x15, 0x6D, 0x9F, 0xBF, 0x0C, 0x1B, 0xC2, 0xE0, + 0xA3, 0x67, 0xD6, 0x0C, 0xAC, 0xCF, 0x22, 0xAE, 0xAF, 0x77, 0x54, 0x2A, + 0x4B, 0x4C, 0x8A, 0x53, 0x52, 0x7A, 0xC3, 0xEE, 0x2E, 0xDE, 0xB3, 0x71, + 0x25, 0xC1, 0xE9, 0x5D, 0x3D, 0xEE, 0xA1, 0x2F, 0xA3, 0xF7, 0x2A, 0x3C, + 0xC9, 0x23, 0x1D, 0x6A, 0xAB, 0x1D, 0xA1, 0xA7, 0xF1, 0xF3, 0xEC, 0xA0, + 0xD5, 0x44, 0xCF, 0x15, 0xCF, 0x72, 0x2F, 0x1D, 0x63, 0x97, 0xE8, 0x99, + 0xF9, 0xFD, 0x93, 0xA4, 0x54, 0x80, 0x4C, 0x52, 0xD4, 0x52, 0xAB, 0x2E, + 0x49, 0xDF, 0x90, 0xCD, 0xB8, 0x5F, 0xBE, 0x3F, 0xDE, 0xA1, 0xCA, 0x4D, + 0x20, 0xD4, 0x25, 0xE8, 0x84, 0x29, 0x53, 0xB7, 0xB1, 0x88, 0x1F, 0xFF, + 0xFA, 0xDA, 0x90, 0x9F, 0x0A, 0xA9, 0x2D, 0x41, 0x3F, 0xB1, 0xF1, 0x18, + 0x29, 0xEE, 0x16, 0x59, 0x2C, 0x34, 0x49, 0x1A, 0xA8, 0x06, 0xD7, 0xA8, + 0x88, 0xD2, 0x03, 0x72, 0x7A, 0x32, 0xE2, 0xEA, 0x68, 0x4D, 0x6E, 0x2C, + 0x96, 0x65, 0x7B, 0xCA, 0x59, 0xFA, 0xF2, 0xE2, 0xDD, 0xEE, 0x30, 0x2C, + 0xFB, 0xCC, 0x46, 0xAC, 0xC4, 0x63, 0xEB, 0x6F, 0x7F, 0x36, 0x2B, 0x34, + 0x73, 0x12, 0x94, 0x7F, 0xDF, 0xCC, 0x26, 0x9E, 0xF1, 0x72, 0x5D, 0x50, + 0x65, 0x59, 0x8F, 0x69, 0xB3, 0x87, 0x5E, 0x32, 0x6F, 0xC3, 0x18, 0x8A, + 0xB5, 0x95, 0x8F, 0xB0, 0x7A, 0x37, 0xDE, 0x5A, 0x45, 0x3B, 0xC7, 0x36, + 0xE1, 0xEF, 0x67, 0xD1, 0x39, 0xD3, 0x97, 0x5B, 0x73, 0x62, 0x19, 0x48, + 0x2D, 0x87, 0x1C, 0x06, 0xFB, 0x74, 0x98, 0x20, 0x49, 0x73, 0xF0, 0x05, + 0xD2, 0x1B, 0xB1, 0xA0, 0xA3, 0xB7, 0x1B, 0x70, 0xD3, 0x88, 0x69, 0xB9, + 0x5A, 0xD6, 0x38, 0xF4, 0x62, 0xDC, 0x25, 0x8B, 0x78, 0xBF, 0xF8, 0xE8, + 0x7E, 0xB8, 0x5C, 0xC9, 0x95, 0x4F, 0x5F, 0xA7, 0x2D, 0xB9, 0x20, 0x6B, + 0xCF, 0x6B, 0xDD, 0xF5, 0x0D, 0xF4, 0x82, 0xB7, 0xF4, 0xB2, 0x66, 0x2E, + 0x10, 0x28, 0xF6, 0x97, 0x5A, 0x7B, 0x96, 0x16, 0x8F, 0x01, 0x19, 0x2D, + 0x6C, 0x6E, 0x7F, 0x39, 0x58, 0x06, 0x64, 0x83, 0x01, 0x83, 0x83, 0xC3, + 0x4D, 0x92, 0xDD, 0x32, 0xC6, 0x87, 0xA4, 0x37, 0xE9, 0x16, 0xCE, 0xAA, + 0x2D, 0x68, 0xAF, 0x0A, 0x81, 0x65, 0x3A, 0x70, 0xC1, 0x9B, 0xAD, 0x4D, + 0x6D, 0x54, 0xCA, 0x2A, 0x2D, 0x4B, 0x85, 0x1B, 0xB3, 0x80, 0xE6, 0x70, + 0x45, 0x0D, 0x6B, 0x5E, 0x35, 0xF0, 0x7F, 0x3B, 0xB8, 0x9C, 0xE4, 0x04, + 0x70, 0x89, 0x12, 0x25, 0x93, 0xDA, 0x0A, 0x99, 0x22, 0x60, 0x6A, 0x63, + 0x60, 0x4E, 0x76, 0x06, 0x98, 0x4E, 0xBD, 0x83, 0xAD, 0x1D, 0x58, 0x8A, + 0x25, 0x85, 0xD2, 0xC7, 0x65, 0x1E, 0x2D, 0x8E, 0xC6, 0xDF, 0xB6, 0xC6, + 0xE1, 0x7F, 0x8A, 0x04, 0x21, 0x15, 0x29, 0x74, 0xF0, 0x3E, 0x9C, 0x90, + 0x9D, 0x0C, 0x2E, 0xF1, 0x8A, 0x3E, 0x5A, 0xAA, 0x0C, 0x09, 0x1E, 0xC7, + 0xD5, 0x3C, 0xA3, 0xED, 0x97, 0xC3, 0x1E, 0x34, 0xFA, 0x38, 0xF9, 0x08, + 0x0E, 0xE3, 0xC0, 0x5D, 0x2B, 0x83, 0xD1, 0x56, 0x6A, 0xC9, 0xB6, 0xA8, + 0x54, 0x53, 0x2E, 0x78, 0x32, 0x67, 0x3D, 0x82, 0x7F, 0x74, 0xD0, 0xFB, + 0xE1, 0xB6, 0x05, 0x60, 0xB9, 0x70, 0xDB, 0x8E, 0x0B, 0xF9, 0x13, 0x58, + 0x6F, 0x71, 0x60, 0x10, 0x52, 0x10, 0xB9, 0xC1, 0x41, 0x09, 0xEF, 0x72, + 0x1F, 0x67, 0x31, 0x78, 0xFF, 0x96, 0x05, 0x8D +}; + +static const unsigned char TA266_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA267_DN[] = { + 0x30, 0x81, 0x81, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA267_RSA_N[] = { + 0xD0, 0x40, 0x8B, 0x8B, 0x72, 0xE3, 0x91, 0x1B, 0xF7, 0x51, 0xC1, 0x1B, + 0x54, 0x04, 0x98, 0xD3, 0xA9, 0xBF, 0xC1, 0xE6, 0x8A, 0x5D, 0x3B, 0x87, + 0xFB, 0xBB, 0x88, 0xCE, 0x0D, 0xE3, 0x2F, 0x3F, 0x06, 0x96, 0xF0, 0xA2, + 0x29, 0x50, 0x99, 0xAE, 0xDB, 0x3B, 0xA1, 0x57, 0xB0, 0x74, 0x51, 0x71, + 0xCD, 0xED, 0x42, 0x91, 0x4D, 0x41, 0xFE, 0xA9, 0xC8, 0xD8, 0x6A, 0x86, + 0x77, 0x44, 0xBB, 0x59, 0x66, 0x97, 0x50, 0x5E, 0xB4, 0xD4, 0x2C, 0x70, + 0x44, 0xCF, 0xDA, 0x37, 0x95, 0x42, 0x69, 0x3C, 0x30, 0xC4, 0x71, 0xB3, + 0x52, 0xF0, 0x21, 0x4D, 0xA1, 0xD8, 0xBA, 0x39, 0x7C, 0x1C, 0x9E, 0xA3, + 0x24, 0x9D, 0xF2, 0x83, 0x16, 0x98, 0xAA, 0x16, 0x7C, 0x43, 0x9B, 0x15, + 0x5B, 0xB7, 0xAE, 0x34, 0x91, 0xFE, 0xD4, 0x62, 0x26, 0x18, 0x46, 0x9A, + 0x3F, 0xEB, 0xC1, 0xF9, 0xF1, 0x90, 0x57, 0xEB, 0xAC, 0x7A, 0x0D, 0x8B, + 0xDB, 0x72, 0x30, 0x6A, 0x66, 0xD5, 0xE0, 0x46, 0xA3, 0x70, 0xDC, 0x68, + 0xD9, 0xFF, 0x04, 0x48, 0x89, 0x77, 0xDE, 0xB5, 0xE9, 0xFB, 0x67, 0x6D, + 0x41, 0xE9, 0xBC, 0x39, 0xBD, 0x32, 0xD9, 0x62, 0x02, 0xF1, 0xB1, 0xA8, + 0x3D, 0x6E, 0x37, 0x9C, 0xE2, 0x2F, 0xE2, 0xD3, 0xA2, 0x26, 0x8B, 0xC6, + 0xB8, 0x55, 0x43, 0x88, 0xE1, 0x23, 0x3E, 0xA5, 0xD2, 0x24, 0x39, 0x6A, + 0x47, 0xAB, 0x00, 0xD4, 0xA1, 0xB3, 0xA9, 0x25, 0xFE, 0x0D, 0x3F, 0xA7, + 0x1D, 0xBA, 0xD3, 0x51, 0xC1, 0x0B, 0xA4, 0xDA, 0xAC, 0x38, 0xEF, 0x55, + 0x50, 0x24, 0x05, 0x65, 0x46, 0x93, 0x34, 0x4F, 0x2D, 0x8D, 0xAD, 0xC6, + 0xD4, 0x21, 0x19, 0xD2, 0x8E, 0xCA, 0x05, 0x61, 0x71, 0x07, 0x73, 0x47, + 0xE5, 0x8A, 0x19, 0x12, 0xBD, 0x04, 0x4D, 0xCE, 0x4E, 0x9C, 0xA5, 0x48, + 0xAC, 0xBB, 0x26, 0xF7 +}; + +static const unsigned char TA267_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA268_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA268_EC_Q[] = { + 0x04, 0x03, 0x47, 0x7B, 0x2F, 0x75, 0xC9, 0x82, 0x15, 0x85, 0xFB, 0x75, + 0xE4, 0x91, 0x16, 0xD4, 0xAB, 0x62, 0x99, 0xF5, 0x3E, 0x52, 0x0B, 0x06, + 0xCE, 0x41, 0x00, 0x7F, 0x97, 0xE1, 0x0A, 0x24, 0x3C, 0x1D, 0x01, 0x04, + 0xEE, 0x3D, 0xD2, 0x8D, 0x09, 0x97, 0x0C, 0xE0, 0x75, 0xE4, 0xFA, 0xFB, + 0x77, 0x8A, 0x2A, 0xF5, 0x03, 0x60, 0x4B, 0x36, 0x8B, 0x16, 0x23, 0x16, + 0xAD, 0x09, 0x71, 0xF4, 0x4A, 0xF4, 0x28, 0x50, 0xB4, 0xFE, 0x88, 0x1C, + 0x6E, 0x3F, 0x6C, 0x2F, 0x2F, 0x09, 0x59, 0x5B, 0xA5, 0x5B, 0x0B, 0x33, + 0x99, 0xE2, 0xC3, 0x3D, 0x89, 0xF9, 0x6A, 0x2C, 0xEF, 0xB2, 0xD3, 0x06, + 0xE9 +}; + +static const unsigned char TA269_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA269_RSA_N[] = { + 0x91, 0xE8, 0x54, 0x92, 0xD2, 0x0A, 0x56, 0xB1, 0xAC, 0x0D, 0x24, 0xDD, + 0xC5, 0xCF, 0x44, 0x67, 0x74, 0x99, 0x2B, 0x37, 0xA3, 0x7D, 0x23, 0x70, + 0x00, 0x71, 0xBC, 0x53, 0xDF, 0xC4, 0xFA, 0x2A, 0x12, 0x8F, 0x4B, 0x7F, + 0x10, 0x56, 0xBD, 0x9F, 0x70, 0x72, 0xB7, 0x61, 0x7F, 0xC9, 0x4B, 0x0F, + 0x17, 0xA7, 0x3D, 0xE3, 0xB0, 0x04, 0x61, 0xEE, 0xFF, 0x11, 0x97, 0xC7, + 0xF4, 0x86, 0x3E, 0x0A, 0xFA, 0x3E, 0x5C, 0xF9, 0x93, 0xE6, 0x34, 0x7A, + 0xD9, 0x14, 0x6B, 0xE7, 0x9C, 0xB3, 0x85, 0xA0, 0x82, 0x7A, 0x76, 0xAF, + 0x71, 0x90, 0xD7, 0xEC, 0xFD, 0x0D, 0xFA, 0x9C, 0x6C, 0xFA, 0xDF, 0xB0, + 0x82, 0xF4, 0x14, 0x7E, 0xF9, 0xBE, 0xC4, 0xA6, 0x2F, 0x4F, 0x7F, 0x99, + 0x7F, 0xB5, 0xFC, 0x67, 0x43, 0x72, 0xBD, 0x0C, 0x00, 0xD6, 0x89, 0xEB, + 0x6B, 0x2C, 0xD3, 0xED, 0x8F, 0x98, 0x1C, 0x14, 0xAB, 0x7E, 0xE5, 0xE3, + 0x6E, 0xFC, 0xD8, 0xA8, 0xE4, 0x92, 0x24, 0xDA, 0x43, 0x6B, 0x62, 0xB8, + 0x55, 0xFD, 0xEA, 0xC1, 0xBC, 0x6C, 0xB6, 0x8B, 0xF3, 0x0E, 0x8D, 0x9A, + 0xE4, 0x9B, 0x6C, 0x69, 0x99, 0xF8, 0x78, 0x48, 0x30, 0x45, 0xD5, 0xAD, + 0xE1, 0x0D, 0x3C, 0x45, 0x60, 0xFC, 0x32, 0x96, 0x51, 0x27, 0xBC, 0x67, + 0xC3, 0xCA, 0x2E, 0xB6, 0x6B, 0xEA, 0x46, 0xC7, 0xC7, 0x20, 0xA0, 0xB1, + 0x1F, 0x65, 0xDE, 0x48, 0x08, 0xBA, 0xA4, 0x4E, 0xA9, 0xF2, 0x83, 0x46, + 0x37, 0x84, 0xEB, 0xE8, 0xCC, 0x81, 0x48, 0x43, 0x67, 0x4E, 0x72, 0x2A, + 0x9B, 0x5C, 0xBD, 0x4C, 0x1B, 0x28, 0x8A, 0x5C, 0x22, 0x7B, 0xB4, 0xAB, + 0x98, 0xD9, 0xEE, 0xE0, 0x51, 0x83, 0xC3, 0x09, 0x46, 0x4E, 0x6D, 0x3E, + 0x99, 0xFA, 0x95, 0x17, 0xDA, 0x7C, 0x33, 0x57, 0x41, 0x3C, 0x8D, 0x51, + 0xED, 0x0B, 0xB6, 0x5C, 0xAF, 0x2C, 0x63, 0x1A, 0xDF, 0x57, 0xC8, 0x3F, + 0xBC, 0xE9, 0x5D, 0xC4, 0x9B, 0xAF, 0x45, 0x99, 0xE2, 0xA3, 0x5A, 0x24, + 0xB4, 0xBA, 0xA9, 0x56, 0x3D, 0xCF, 0x6F, 0xAA, 0xFF, 0x49, 0x58, 0xBE, + 0xF0, 0xA8, 0xFF, 0xF4, 0xB8, 0xAD, 0xE9, 0x37, 0xFB, 0xBA, 0xB8, 0xF4, + 0x0B, 0x3A, 0xF9, 0xE8, 0x43, 0x42, 0x1E, 0x89, 0xD8, 0x84, 0xCB, 0x13, + 0xF1, 0xD9, 0xBB, 0xE1, 0x89, 0x60, 0xB8, 0x8C, 0x28, 0x56, 0xAC, 0x14, + 0x1D, 0x9C, 0x0A, 0xE7, 0x71, 0xEB, 0xCF, 0x0E, 0xDD, 0x3D, 0xA9, 0x96, + 0xA1, 0x48, 0xBD, 0x3C, 0xF7, 0xAF, 0xB5, 0x0D, 0x22, 0x4C, 0xC0, 0x11, + 0x81, 0xEC, 0x56, 0x3B, 0xF6, 0xD3, 0xA2, 0xE2, 0x5B, 0xB7, 0xB2, 0x04, + 0x22, 0x52, 0x95, 0x80, 0x93, 0x69, 0xE8, 0x8E, 0x4C, 0x65, 0xF1, 0x91, + 0x03, 0x2D, 0x70, 0x74, 0x02, 0xEA, 0x8B, 0x67, 0x15, 0x29, 0x69, 0x52, + 0x02, 0xBB, 0xD7, 0xDF, 0x50, 0x6A, 0x55, 0x46, 0xBF, 0xA0, 0xA3, 0x28, + 0x61, 0x7F, 0x70, 0xD0, 0xC3, 0xA2, 0xAA, 0x2C, 0x21, 0xAA, 0x47, 0xCE, + 0x28, 0x9C, 0x06, 0x45, 0x76, 0xBF, 0x82, 0x18, 0x27, 0xB4, 0xD5, 0xAE, + 0xB4, 0xCB, 0x50, 0xE6, 0x6B, 0xF4, 0x4C, 0x86, 0x71, 0x30, 0xE9, 0xA6, + 0xDF, 0x16, 0x86, 0xE0, 0xD8, 0xFF, 0x40, 0xDD, 0xFB, 0xD0, 0x42, 0x88, + 0x7F, 0xA3, 0x33, 0x3A, 0x2E, 0x5C, 0x1E, 0x41, 0x11, 0x81, 0x63, 0xCE, + 0x18, 0x71, 0x6B, 0x2B, 0xEC, 0xA6, 0x8A, 0xB7, 0x31, 0x5C, 0x3A, 0x6A, + 0x47, 0xE0, 0xC3, 0x79, 0x59, 0xD6, 0x20, 0x1A, 0xAF, 0xF2, 0x6A, 0x98, + 0xAA, 0x72, 0xBC, 0x57, 0x4A, 0xD2, 0x4B, 0x9D, 0xBB, 0x10, 0xFC, 0xB0, + 0x4C, 0x41, 0xE5, 0xED, 0x1D, 0x3D, 0x5E, 0x28, 0x9D, 0x9C, 0xCC, 0xBF, + 0xB3, 0x51, 0xDA, 0xA7, 0x47, 0xE5, 0x84, 0x53 +}; + +static const unsigned char TA269_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA270_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x45, 0x31 +}; + +static const unsigned char TA270_EC_Q[] = { + 0x04, 0xDE, 0x6F, 0xF8, 0x7F, 0x1C, 0xDF, 0xED, 0xF9, 0x47, 0x87, 0x86, + 0xB1, 0xA4, 0xC0, 0x8A, 0xF8, 0x82, 0x97, 0x80, 0xEA, 0x8F, 0xC8, 0x4A, + 0x5E, 0x2A, 0x7D, 0x88, 0x68, 0xA7, 0x01, 0x62, 0x14, 0x91, 0x24, 0x7A, + 0x5C, 0x9E, 0xA3, 0x17, 0x7D, 0x8A, 0x86, 0x21, 0x34, 0x18, 0x50, 0x1B, + 0x10, 0xDE, 0xD0, 0x37, 0x4B, 0x26, 0xC7, 0x19, 0x60, 0x80, 0xE9, 0x34, + 0xBD, 0x60, 0x19, 0x36, 0x40, 0xD6, 0x29, 0x87, 0x09, 0x3C, 0x91, 0x7A, + 0xF6, 0xBC, 0x13, 0x23, 0xDD, 0x59, 0x4E, 0x04, 0x5E, 0xCF, 0xC8, 0x02, + 0x1C, 0x18, 0x53, 0xC1, 0x31, 0xD8, 0xDA, 0x20, 0xE9, 0x44, 0x8D, 0xE4, + 0x76 +}; + +static const unsigned char TA271_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x52, 0x31 +}; + +static const unsigned char TA271_RSA_N[] = { + 0xD0, 0x36, 0xD4, 0x1F, 0xEA, 0xDD, 0xAB, 0xE4, 0xD1, 0xB6, 0xE6, 0xFB, + 0x22, 0xC0, 0xDD, 0x13, 0x0D, 0x6A, 0x7B, 0x22, 0x13, 0x1C, 0x97, 0x3C, + 0x68, 0x63, 0x66, 0x32, 0x9C, 0x03, 0xB5, 0x8D, 0xA4, 0x81, 0x83, 0xDA, + 0x78, 0x30, 0x11, 0xCF, 0xDC, 0xB2, 0x2B, 0xBE, 0x92, 0xBF, 0x8E, 0xE4, + 0xC4, 0x13, 0xBE, 0xA4, 0x68, 0x4C, 0xDA, 0x02, 0x68, 0x16, 0x74, 0xBE, + 0xB2, 0xDD, 0x04, 0xE4, 0x6B, 0x2A, 0xDD, 0x37, 0x1F, 0x60, 0x2C, 0xDB, + 0xF5, 0xF7, 0xA1, 0x7C, 0x95, 0xB7, 0x0C, 0x70, 0x86, 0x2E, 0xF1, 0x3A, + 0xEF, 0x52, 0xF7, 0xCC, 0xD3, 0x9B, 0xF9, 0x8B, 0xBE, 0x0E, 0xDF, 0x31, + 0xB7, 0x9D, 0x68, 0x5C, 0x92, 0xA6, 0xF5, 0xE5, 0xF3, 0x0A, 0x34, 0xB5, + 0xFF, 0x7B, 0xA2, 0xE4, 0x87, 0xA1, 0xC6, 0xAF, 0x17, 0x00, 0xEF, 0x03, + 0x91, 0xED, 0xA9, 0x1C, 0x4E, 0x71, 0x3D, 0xD2, 0x8B, 0x6C, 0x89, 0xF4, + 0x78, 0x86, 0xE6, 0x6A, 0x49, 0xA0, 0xCE, 0xB5, 0xD2, 0xB0, 0xAB, 0x9B, + 0xF6, 0xF4, 0xD4, 0x2E, 0xE3, 0x72, 0xF9, 0x36, 0xC6, 0xEB, 0x15, 0xB7, + 0x25, 0x8C, 0x3A, 0xFC, 0x25, 0x0D, 0xB3, 0x22, 0x73, 0x21, 0x74, 0xC8, + 0x4A, 0x96, 0x61, 0x92, 0xF5, 0x2F, 0x0B, 0x18, 0xA5, 0xF4, 0xAD, 0xE2, + 0xEE, 0x41, 0xBD, 0x01, 0x79, 0xFA, 0x96, 0x8C, 0x8D, 0x17, 0x02, 0x30, + 0xB4, 0xF9, 0xAF, 0x78, 0x1A, 0x8C, 0xB4, 0x36, 0x10, 0x10, 0x07, 0x05, + 0x70, 0xD0, 0xF4, 0x31, 0x90, 0x8A, 0x51, 0xC5, 0x86, 0x26, 0x79, 0xB2, + 0x11, 0x88, 0x5E, 0xC5, 0xF0, 0x0A, 0x54, 0xCD, 0x49, 0xA6, 0xBF, 0x02, + 0x9C, 0xD2, 0x44, 0xA7, 0xED, 0xE3, 0x78, 0xEF, 0x46, 0x5E, 0x6D, 0x71, + 0xD1, 0x79, 0x70, 0x1C, 0x46, 0x5F, 0x51, 0xE9, 0xC9, 0x37, 0xDC, 0x5F, + 0x7E, 0x69, 0x7B, 0x41, 0xDF, 0x34, 0x45, 0xE0, 0x3B, 0x84, 0xF4, 0xA1, + 0x8A, 0x0A, 0x36, 0x9E, 0x37, 0xCC, 0x62, 0x52, 0xE1, 0x89, 0x0D, 0x28, + 0xF9, 0x7A, 0x23, 0xB1, 0x0D, 0x3D, 0x3D, 0x9A, 0xFD, 0x9D, 0x81, 0xEF, + 0x2C, 0x90, 0xC0, 0x7B, 0x44, 0x4E, 0xBB, 0x49, 0xE0, 0x0E, 0x4A, 0x56, + 0x92, 0xBC, 0xCB, 0xB5, 0xDD, 0x79, 0x17, 0x89, 0x91, 0xDE, 0x61, 0x89, + 0x74, 0x92, 0xA8, 0xE3, 0x32, 0x85, 0xBE, 0x4E, 0x85, 0xA4, 0x4B, 0x59, + 0xCB, 0x2B, 0xC5, 0x78, 0x8E, 0x71, 0x54, 0xD0, 0x02, 0x37, 0x99, 0x8C, + 0xE5, 0x49, 0xEA, 0xE0, 0x54, 0x72, 0xA4, 0x11, 0x06, 0x2F, 0x0B, 0x8C, + 0xC1, 0x5B, 0xBE, 0xB5, 0xA1, 0xB0, 0x53, 0x6E, 0x9C, 0xB8, 0x60, 0x91, + 0x1F, 0x59, 0x6B, 0xF9, 0x2D, 0xF4, 0x94, 0x0A, 0x97, 0xB5, 0xEC, 0xC5, + 0x76, 0x03, 0x54, 0x1B, 0x65, 0x52, 0xBA, 0x4C, 0x92, 0x56, 0x51, 0x35, + 0xA0, 0x40, 0xD8, 0x29, 0xDB, 0xAE, 0x52, 0x76, 0x3B, 0x2D, 0x30, 0x40, + 0x9B, 0x8A, 0xD0, 0x42, 0x56, 0xB4, 0xB7, 0x88, 0x01, 0xA4, 0x87, 0x3B, + 0x53, 0x96, 0xCD, 0xA3, 0x16, 0x8F, 0xF3, 0x66, 0xAA, 0x17, 0xB1, 0xC7, + 0x60, 0xE0, 0xC1, 0x43, 0x05, 0x0C, 0xEE, 0x9B, 0x5B, 0x60, 0x6F, 0x06, + 0x5C, 0x87, 0x5B, 0x27, 0xF9, 0x40, 0x11, 0x9E, 0x9C, 0x33, 0xC1, 0xB7, + 0xE5, 0x35, 0x57, 0x05, 0x7F, 0x27, 0xCE, 0x17, 0x20, 0x8C, 0x1C, 0xFC, + 0xF1, 0xFB, 0xDA, 0x31, 0x29, 0x49, 0xED, 0xF5, 0x0B, 0x84, 0xA7, 0x4F, + 0xC1, 0xF6, 0x4E, 0xC2, 0x28, 0x9C, 0xFA, 0xEE, 0xE0, 0xAF, 0x07, 0xFB, + 0x33, 0x11, 0x7A, 0x21, 0x4F, 0x0B, 0x21, 0x10, 0xB6, 0x40, 0x3A, 0xAB, + 0x22, 0x3A, 0x04, 0x9C, 0x8B, 0x9B, 0x84, 0x86, 0x72, 0x9A, 0xD2, 0xA7, + 0xA5, 0xC4, 0xB4, 0x75, 0x91, 0xA9, 0x2B, 0x23 +}; + +static const unsigned char TA271_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA272_DN[] = { + 0x30, 0x34, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x08, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61 +}; + +static const unsigned char TA272_RSA_N[] = { + 0xC8, 0x68, 0xF1, 0xC9, 0xD6, 0xD6, 0xB3, 0x34, 0x75, 0x26, 0x82, 0x1E, + 0xEC, 0xB4, 0xBE, 0xEA, 0x5C, 0xE1, 0x26, 0xED, 0x11, 0x47, 0x61, 0xE1, + 0xA2, 0x7C, 0x16, 0x78, 0x40, 0x21, 0xE4, 0x60, 0x9E, 0x5A, 0xC8, 0x63, + 0xE1, 0xC4, 0xB1, 0x96, 0x92, 0xFF, 0x18, 0x6D, 0x69, 0x23, 0xE1, 0x2B, + 0x62, 0xF7, 0xDD, 0xE2, 0x36, 0x2F, 0x91, 0x07, 0xB9, 0x48, 0xCF, 0x0E, + 0xEC, 0x79, 0xB6, 0x2C, 0xE7, 0x34, 0x4B, 0x70, 0x08, 0x25, 0xA3, 0x3C, + 0x87, 0x1B, 0x19, 0xF2, 0x81, 0x07, 0x0F, 0x38, 0x90, 0x19, 0xD3, 0x11, + 0xFE, 0x86, 0xB4, 0xF2, 0xD1, 0x5E, 0x1E, 0x1E, 0x96, 0xCD, 0x80, 0x6C, + 0xCE, 0x3B, 0x31, 0x93, 0xB6, 0xF2, 0xA0, 0xD0, 0xA9, 0x95, 0x12, 0x7D, + 0xA5, 0x9A, 0xCC, 0x6B, 0xC8, 0x84, 0x56, 0x8A, 0x33, 0xA9, 0xE7, 0x22, + 0x15, 0x53, 0x16, 0xF0, 0xCC, 0x17, 0xEC, 0x57, 0x5F, 0xE9, 0xA2, 0x0A, + 0x98, 0x09, 0xDE, 0xE3, 0x5F, 0x9C, 0x6F, 0xDC, 0x48, 0xE3, 0x85, 0x0B, + 0x15, 0x5A, 0xA6, 0xBA, 0x9F, 0xAC, 0x48, 0xE3, 0x09, 0xB2, 0xF7, 0xF4, + 0x32, 0xDE, 0x5E, 0x34, 0xBE, 0x1C, 0x78, 0x5D, 0x42, 0x5B, 0xCE, 0x0E, + 0x22, 0x8F, 0x4D, 0x90, 0xD7, 0x7D, 0x32, 0x18, 0xB3, 0x0B, 0x2C, 0x6A, + 0xBF, 0x8E, 0x3F, 0x14, 0x11, 0x89, 0x20, 0x0E, 0x77, 0x14, 0xB5, 0x3D, + 0x94, 0x08, 0x87, 0xF7, 0x25, 0x1E, 0xD5, 0xB2, 0x60, 0x00, 0xEC, 0x6F, + 0x2A, 0x28, 0x25, 0x6E, 0x2A, 0x3E, 0x18, 0x63, 0x17, 0x25, 0x3F, 0x3E, + 0x44, 0x20, 0x16, 0xF6, 0x26, 0xC8, 0x25, 0xAE, 0x05, 0x4A, 0xB4, 0xE7, + 0x63, 0x2C, 0xF3, 0x8C, 0x16, 0x53, 0x7E, 0x5C, 0xFB, 0x11, 0x1A, 0x08, + 0xC1, 0x46, 0x62, 0x9F, 0x22, 0xB8, 0xF1, 0xC2, 0x8D, 0x69, 0xDC, 0xFA, + 0x3A, 0x58, 0x06, 0xDF +}; + +static const unsigned char TA272_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA273_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x13, 0x30, 0x30, + 0x30, 0x32, 0x20, 0x34, 0x38, 0x31, 0x34, 0x36, 0x33, 0x30, 0x38, 0x31, + 0x30, 0x30, 0x30, 0x33, 0x36, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA273_RSA_N[] = { + 0xCD, 0x18, 0x39, 0x65, 0x1A, 0x59, 0xB1, 0xEA, 0x64, 0x16, 0x0E, 0x8C, + 0x94, 0x24, 0x95, 0x7C, 0x83, 0xD3, 0xC5, 0x39, 0x26, 0xDC, 0x0C, 0xEF, + 0x16, 0x57, 0x8D, 0xD7, 0xD8, 0xAC, 0xA3, 0x42, 0x7F, 0x82, 0xCA, 0xED, + 0xCD, 0x5B, 0xDB, 0x0E, 0xB7, 0x2D, 0xED, 0x45, 0x08, 0x17, 0xB2, 0xD9, + 0xB3, 0xCB, 0xD6, 0x17, 0x52, 0x72, 0x28, 0xDB, 0x8E, 0x4E, 0x9E, 0x8A, + 0xB6, 0x0B, 0xF9, 0x9E, 0x84, 0x9A, 0x4D, 0x76, 0xDE, 0x22, 0x29, 0x5C, + 0xD2, 0xB3, 0xD2, 0x06, 0x3E, 0x30, 0x39, 0xA9, 0x74, 0xA3, 0x92, 0x56, + 0x1C, 0xA1, 0x6F, 0x4C, 0x0A, 0x20, 0x6D, 0x9F, 0x23, 0x7A, 0xB4, 0xC6, + 0xDA, 0x2C, 0xE4, 0x1D, 0x2C, 0xDC, 0xB3, 0x28, 0xD0, 0x13, 0xF2, 0x4C, + 0x4E, 0x02, 0x49, 0xA1, 0x54, 0x40, 0x9E, 0xE6, 0xE5, 0x05, 0xA0, 0x2D, + 0x84, 0xC8, 0xFF, 0x98, 0x6C, 0xD0, 0xEB, 0x8A, 0x1A, 0x84, 0x08, 0x1E, + 0xB7, 0x68, 0x23, 0xEE, 0x23, 0xD5, 0x70, 0xCE, 0x6D, 0x51, 0x69, 0x10, + 0xEE, 0xA1, 0x7A, 0xC2, 0xD1, 0x22, 0x31, 0xC2, 0x82, 0x85, 0xD2, 0xF2, + 0x55, 0x76, 0x50, 0x7C, 0x25, 0x7A, 0xC9, 0x84, 0x5C, 0x0B, 0xAC, 0xDD, + 0x42, 0x4E, 0x2B, 0xE7, 0x82, 0xA2, 0x24, 0x89, 0xCB, 0x90, 0xB2, 0xD0, + 0xEE, 0x23, 0xBA, 0x66, 0x4C, 0xBB, 0x62, 0xA4, 0xF9, 0x53, 0x5A, 0x64, + 0x7B, 0x7C, 0x98, 0xFA, 0xA3, 0x48, 0x9E, 0x0F, 0x95, 0xAE, 0xA7, 0x18, + 0xF4, 0x6A, 0xEC, 0x2E, 0x03, 0x45, 0xAF, 0xF0, 0x74, 0xF8, 0x2A, 0xCD, + 0x7A, 0x5D, 0xD1, 0xBE, 0x44, 0x26, 0x32, 0x29, 0xF1, 0xF1, 0xF5, 0x6C, + 0xCC, 0x7E, 0x02, 0x21, 0x0B, 0x9F, 0x6F, 0xA4, 0x3F, 0xBE, 0x9D, 0x53, + 0xE2, 0xCF, 0x7D, 0xA9, 0x2C, 0x7C, 0x58, 0x1A, 0x97, 0xE1, 0x3D, 0x37, + 0x37, 0x18, 0x66, 0x28, 0xD2, 0x40, 0xC5, 0x51, 0x8A, 0x8C, 0xC3, 0x2D, + 0xCE, 0x53, 0x88, 0x24, 0x58, 0x64, 0x30, 0x16, 0xC5, 0xAA, 0xE0, 0xD6, + 0x0A, 0xA6, 0x40, 0xDF, 0x78, 0xF6, 0xF5, 0x04, 0x7C, 0x69, 0x13, 0x84, + 0xBC, 0xD1, 0xD1, 0xA7, 0x06, 0xCF, 0x01, 0xF7, 0x68, 0xC0, 0xA8, 0x57, + 0xBB, 0x3A, 0x61, 0xAD, 0x04, 0x8C, 0x93, 0xE3, 0xAD, 0xFC, 0xF0, 0xDB, + 0x44, 0x6D, 0x59, 0xDC, 0x49, 0x59, 0xAE, 0xAC, 0x9A, 0x99, 0x36, 0x30, + 0x41, 0x7B, 0x76, 0x33, 0x22, 0x87, 0xA3, 0xC2, 0x92, 0x86, 0x6E, 0xF9, + 0x70, 0xEE, 0xAE, 0x87, 0x87, 0x95, 0x1B, 0xC4, 0x7A, 0xBD, 0x31, 0xF3, + 0xD4, 0xD2, 0xE5, 0x99, 0xFF, 0xBE, 0x48, 0xEC, 0x75, 0xF5, 0x78, 0x16, + 0x1D, 0xA6, 0x70, 0xC1, 0x7F, 0x3C, 0x1B, 0xA1, 0x92, 0xFB, 0xCF, 0xC8, + 0x3C, 0xD6, 0xC5, 0x93, 0x0A, 0x8F, 0xF5, 0x55, 0x3A, 0x76, 0x95, 0xCE, + 0x59, 0x98, 0x8A, 0x09, 0x95, 0x77, 0x32, 0x9A, 0x83, 0xBA, 0x2C, 0x04, + 0x3A, 0x97, 0xBD, 0xD4, 0x2F, 0xBE, 0xD7, 0x6C, 0x9B, 0xA2, 0xCA, 0x7D, + 0x6D, 0x26, 0xC9, 0x55, 0xD5, 0xCF, 0xC3, 0x79, 0x52, 0x08, 0x09, 0x99, + 0x07, 0x24, 0x2D, 0x64, 0x25, 0x6B, 0xA6, 0x21, 0x69, 0x9B, 0x6A, 0xDD, + 0x74, 0x4D, 0x6B, 0x97, 0x7A, 0x41, 0xBD, 0xAB, 0x17, 0xF9, 0x90, 0x17, + 0x48, 0x8F, 0x36, 0xF9, 0x2D, 0xD5, 0xC5, 0xDB, 0xEE, 0xAA, 0x85, 0x45, + 0x41, 0xFA, 0xCD, 0x3A, 0x45, 0xB1, 0x68, 0xE6, 0x36, 0x4C, 0x9B, 0x90, + 0x57, 0xEC, 0x23, 0xB9, 0x87, 0x08, 0xC2, 0xC4, 0x09, 0xF1, 0x97, 0x86, + 0x2A, 0x28, 0x4D, 0xE2, 0x74, 0xC0, 0xDA, 0xC4, 0x8C, 0xDB, 0xDF, 0xE2, + 0xA1, 0x17, 0x59, 0xCE, 0x24, 0x59, 0x74, 0x31, 0xDA, 0x7F, 0xFD, 0x30, + 0x6D, 0xD9, 0xDC, 0xE1, 0x6A, 0xE1, 0xFC, 0x5F +}; + +static const unsigned char TA273_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA274_DN[] = { + 0x30, 0x74, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x45, 0x43, 0x2D, 0x33, 0x38, 0x34, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA274_EC_Q[] = { + 0x04, 0xC4, 0x28, 0x8E, 0xAB, 0x18, 0x5B, 0x6A, 0xBE, 0x6E, 0x64, 0x37, + 0x63, 0xE4, 0xCD, 0xEC, 0xAB, 0x3A, 0xF7, 0xCC, 0xA1, 0xB8, 0x0E, 0x82, + 0x49, 0xD7, 0x86, 0x29, 0x9F, 0xA1, 0x94, 0xF2, 0xE3, 0x60, 0x78, 0x98, + 0x81, 0x78, 0x06, 0x4D, 0xF2, 0xEC, 0x9A, 0x0E, 0x57, 0x60, 0x83, 0x9F, + 0xB4, 0xE6, 0x17, 0x2F, 0x1A, 0xB3, 0x5D, 0x02, 0x5B, 0x89, 0x23, 0x3C, + 0xC2, 0x11, 0x05, 0x2A, 0xA7, 0x88, 0x13, 0x18, 0xF3, 0x50, 0x84, 0xD7, + 0xBD, 0x34, 0x2C, 0x27, 0x89, 0x55, 0xFF, 0xCE, 0x4C, 0xE7, 0xDF, 0xA6, + 0x1F, 0x28, 0xC4, 0xF0, 0x54, 0xC3, 0xB9, 0x7C, 0xB7, 0x53, 0xAD, 0xEB, + 0xC2 +}; + +static const unsigned char TA275_DN[] = { + 0x30, 0x7E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, 0x65, + 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, + 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, + 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, 0x65, + 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA275_RSA_N[] = { + 0xE3, 0xFB, 0x7D, 0xA3, 0x72, 0xBA, 0xC2, 0xF0, 0xC9, 0x14, 0x87, 0xF5, + 0x6B, 0x01, 0x4E, 0xE1, 0x6E, 0x40, 0x07, 0xBA, 0x6D, 0x27, 0x5D, 0x7F, + 0xF7, 0x5B, 0x2D, 0xB3, 0x5A, 0xC7, 0x51, 0x5F, 0xAB, 0xA4, 0x32, 0xA6, + 0x61, 0x87, 0xB6, 0x6E, 0x0F, 0x86, 0xD2, 0x30, 0x02, 0x97, 0xF8, 0xD7, + 0x69, 0x57, 0xA1, 0x18, 0x39, 0x5D, 0x6A, 0x64, 0x79, 0xC6, 0x01, 0x59, + 0xAC, 0x3C, 0x31, 0x4A, 0x38, 0x7C, 0xD2, 0x04, 0xD2, 0x4B, 0x28, 0xE8, + 0x20, 0x5F, 0x3B, 0x07, 0xA2, 0xCC, 0x4D, 0x73, 0xDB, 0xF3, 0xAE, 0x4F, + 0xC7, 0x56, 0xD5, 0x5A, 0xA7, 0x96, 0x89, 0xFA, 0xF3, 0xAB, 0x68, 0xD4, + 0x23, 0x86, 0x59, 0x27, 0xCF, 0x09, 0x27, 0xBC, 0xAC, 0x6E, 0x72, 0x83, + 0x1C, 0x30, 0x72, 0xDF, 0xE0, 0xA2, 0xE9, 0xD2, 0xE1, 0x74, 0x75, 0x19, + 0xBD, 0x2A, 0x9E, 0x7B, 0x15, 0x54, 0x04, 0x1B, 0xD7, 0x43, 0x39, 0xAD, + 0x55, 0x28, 0xC5, 0xE2, 0x1A, 0xBB, 0xF4, 0xC0, 0xE4, 0xAE, 0x38, 0x49, + 0x33, 0xCC, 0x76, 0x85, 0x9F, 0x39, 0x45, 0xD2, 0xA4, 0x9E, 0xF2, 0x12, + 0x8C, 0x51, 0xF8, 0x7C, 0xE4, 0x2D, 0x7F, 0xF5, 0xAC, 0x5F, 0xEB, 0x16, + 0x9F, 0xB1, 0x2D, 0xD1, 0xBA, 0xCC, 0x91, 0x42, 0x77, 0x4C, 0x25, 0xC9, + 0x90, 0x38, 0x6F, 0xDB, 0xF0, 0xCC, 0xFB, 0x8E, 0x1E, 0x97, 0x59, 0x3E, + 0xD5, 0x60, 0x4E, 0xE6, 0x05, 0x28, 0xED, 0x49, 0x79, 0x13, 0x4B, 0xBA, + 0x48, 0xDB, 0x2F, 0xF9, 0x72, 0xD3, 0x39, 0xCA, 0xFE, 0x1F, 0xD8, 0x34, + 0x72, 0xF5, 0xB4, 0x40, 0xCF, 0x31, 0x01, 0xC3, 0xEC, 0xDE, 0x11, 0x2D, + 0x17, 0x5D, 0x1F, 0xB8, 0x50, 0xD1, 0x5E, 0x19, 0xA7, 0x69, 0xDE, 0x07, + 0x33, 0x28, 0xCA, 0x50, 0x95, 0xF9, 0xA7, 0x54, 0xCB, 0x54, 0x86, 0x50, + 0x45, 0xA9, 0xF9, 0x49 +}; + +static const unsigned char TA275_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA276_DN[] = { + 0x30, 0x81, 0x80, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, + 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x24, 0x30, + 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x43, 0x65, 0x72, 0x74, + 0x75, 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, + 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA276_RSA_N[] = { + 0xBD, 0xF9, 0x78, 0xF8, 0xE6, 0xD5, 0x80, 0x0C, 0x64, 0x9D, 0x86, 0x1B, + 0x96, 0x64, 0x67, 0x3F, 0x22, 0x3A, 0x1E, 0x75, 0x01, 0x7D, 0xEF, 0xFB, + 0x5C, 0x67, 0x8C, 0xC9, 0xCC, 0x5C, 0x6B, 0xA9, 0x91, 0xE6, 0xB9, 0x42, + 0xE5, 0x20, 0x4B, 0x9B, 0xDA, 0x9B, 0x7B, 0xB9, 0x99, 0x5D, 0xD9, 0x9B, + 0x80, 0x4B, 0xD7, 0x84, 0x40, 0x2B, 0x27, 0xD3, 0xE8, 0xBA, 0x30, 0xBB, + 0x3E, 0x09, 0x1A, 0xA7, 0x49, 0x95, 0xEF, 0x2B, 0x40, 0x24, 0xC2, 0x97, + 0xC7, 0xA7, 0xEE, 0x9B, 0x25, 0xEF, 0xA8, 0x0A, 0x00, 0x97, 0x85, 0x5A, + 0xAA, 0x9D, 0xDC, 0x29, 0xC9, 0xE2, 0x35, 0x07, 0xEB, 0x70, 0x4D, 0x4A, + 0xD6, 0xC1, 0xB3, 0x56, 0xB8, 0xA1, 0x41, 0x38, 0x9B, 0xD1, 0xFB, 0x31, + 0x7F, 0x8F, 0xE0, 0x5F, 0xE1, 0xB1, 0x3F, 0x0F, 0x8E, 0x16, 0x49, 0x60, + 0xD7, 0x06, 0x8D, 0x18, 0xF9, 0xAA, 0x26, 0x10, 0xAB, 0x2A, 0xD3, 0xD0, + 0xD1, 0x67, 0x8D, 0x1B, 0x46, 0xBE, 0x47, 0x30, 0xD5, 0x2E, 0x72, 0xD1, + 0xC5, 0x63, 0xDA, 0xE7, 0x63, 0x79, 0x44, 0x7E, 0x4B, 0x63, 0x24, 0x89, + 0x86, 0x2E, 0x34, 0x3F, 0x29, 0x4C, 0x52, 0x8B, 0x2A, 0xA7, 0xC0, 0xE2, + 0x91, 0x28, 0x89, 0xB9, 0xC0, 0x5B, 0xF9, 0x1D, 0xD9, 0xE7, 0x27, 0xAD, + 0xFF, 0x9A, 0x02, 0x97, 0xC1, 0xC6, 0x50, 0x92, 0x9B, 0x02, 0x2C, 0xBD, + 0xA9, 0xB9, 0x34, 0x59, 0x0A, 0xBF, 0x84, 0x4A, 0xFF, 0xDF, 0xFE, 0xB3, + 0x9F, 0xEB, 0xD9, 0x9E, 0xE0, 0x98, 0x23, 0xEC, 0xA6, 0x6B, 0x77, 0x16, + 0x2A, 0xDB, 0xCC, 0xAD, 0x3B, 0x1C, 0xA4, 0x87, 0xDC, 0x46, 0x73, 0x5E, + 0x19, 0x62, 0x68, 0x45, 0x57, 0xE4, 0x90, 0x82, 0x42, 0xBB, 0x42, 0xD6, + 0xF0, 0x61, 0xE0, 0xC1, 0xA3, 0x3D, 0x66, 0xA3, 0x5D, 0xF4, 0x18, 0xEE, + 0x88, 0xC9, 0x8D, 0x17, 0x45, 0x29, 0x99, 0x32, 0x75, 0x02, 0x31, 0xEE, + 0x29, 0x26, 0xC8, 0x6B, 0x02, 0xE6, 0xB5, 0x62, 0x45, 0x7F, 0x37, 0x15, + 0x5A, 0x23, 0x68, 0x89, 0xD4, 0x3E, 0xDE, 0x4E, 0x27, 0xB0, 0xF0, 0x40, + 0x0C, 0xBC, 0x4D, 0x17, 0xCB, 0x4D, 0xA2, 0xB3, 0x1E, 0xD0, 0x06, 0x5A, + 0xDD, 0xF6, 0x93, 0xCF, 0x57, 0x75, 0x99, 0xF5, 0xFA, 0x86, 0x1A, 0x67, + 0x78, 0xB3, 0xBF, 0x96, 0xFE, 0x34, 0xDC, 0xBD, 0xE7, 0x52, 0x56, 0xE5, + 0xB3, 0xE5, 0x75, 0x7B, 0xD7, 0x41, 0x91, 0x05, 0xDC, 0x5D, 0x69, 0xE3, + 0x95, 0x0D, 0x43, 0xB9, 0xFC, 0x83, 0x96, 0x39, 0x95, 0x7B, 0x6C, 0x80, + 0x5A, 0x4F, 0x13, 0x72, 0xC6, 0xD7, 0x7D, 0x29, 0x7A, 0x44, 0xBA, 0x52, + 0xA4, 0x2A, 0xD5, 0x41, 0x46, 0x09, 0x20, 0xFE, 0x22, 0xA0, 0xB6, 0x5B, + 0x30, 0x8D, 0xBC, 0x89, 0x0C, 0xD5, 0xD7, 0x70, 0xF8, 0x87, 0x52, 0xFD, + 0xDA, 0xEF, 0xAC, 0x51, 0x2E, 0x07, 0xB3, 0x4E, 0xFE, 0xD0, 0x09, 0xDA, + 0x70, 0xEF, 0x98, 0xFA, 0x56, 0xE6, 0x6D, 0xDB, 0xB5, 0x57, 0x4B, 0xDC, + 0xE5, 0x2C, 0x25, 0x15, 0xC8, 0x9E, 0x2E, 0x78, 0x4E, 0xF8, 0xDA, 0x9C, + 0x9E, 0x86, 0x2C, 0xCA, 0x57, 0xF3, 0x1A, 0xE5, 0xC8, 0x92, 0x8B, 0x1A, + 0x82, 0x96, 0x7A, 0xC3, 0xBC, 0x50, 0x12, 0x69, 0xD8, 0x0E, 0x5A, 0x46, + 0x8B, 0x3A, 0xEB, 0x26, 0xFA, 0x23, 0xC9, 0xB6, 0xB0, 0x81, 0xBE, 0x42, + 0x00, 0xA4, 0xF8, 0xD6, 0xFE, 0x30, 0x2E, 0xC7, 0xD2, 0x46, 0xF6, 0xE5, + 0x8E, 0x75, 0xFD, 0xF2, 0xCC, 0xB9, 0xD0, 0x87, 0x5B, 0xCC, 0x06, 0x10, + 0x60, 0xBB, 0x83, 0x35, 0xB7, 0x5E, 0x67, 0xDE, 0x47, 0xEC, 0x99, 0x48, + 0xF1, 0xA4, 0xA1, 0x15, 0xFE, 0xAD, 0x8C, 0x62, 0x8E, 0x39, 0x55, 0x4F, + 0x39, 0x16, 0xB9, 0xB1, 0x63, 0x9D, 0xFF, 0xB7 +}; + +static const unsigned char TA276_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA277_DN[] = { + 0x30, 0x7A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA277_RSA_N[] = { + 0xD1, 0x2D, 0x8E, 0xBB, 0xB7, 0x36, 0xEA, 0x6D, 0x37, 0x91, 0x9F, 0x4E, + 0x93, 0xA7, 0x05, 0xE4, 0x29, 0x03, 0x25, 0xCE, 0x1C, 0x82, 0xF7, 0x7C, + 0x99, 0x9F, 0x41, 0x06, 0xCD, 0xED, 0xA3, 0xBA, 0xC0, 0xDB, 0x09, 0x2C, + 0xC1, 0x7C, 0xDF, 0x29, 0x7E, 0x4B, 0x65, 0x2F, 0x93, 0xA7, 0xD4, 0x01, + 0x6B, 0x03, 0x28, 0x18, 0xA3, 0xD8, 0x9D, 0x05, 0xC1, 0x2A, 0xD8, 0x45, + 0xF1, 0x91, 0xDE, 0xDF, 0x3B, 0xD0, 0x80, 0x02, 0x8C, 0xCF, 0x38, 0x0F, + 0xEA, 0xA7, 0x5C, 0x78, 0x11, 0xA4, 0xC1, 0xC8, 0x85, 0x5C, 0x25, 0xD3, + 0xD3, 0xB2, 0xE7, 0x25, 0xCF, 0x11, 0x54, 0x97, 0xAB, 0x35, 0xC0, 0x1E, + 0x76, 0x1C, 0xEF, 0x00, 0x53, 0x9F, 0x39, 0xDC, 0x14, 0xA5, 0x2C, 0x22, + 0x25, 0xB3, 0x72, 0x72, 0xFC, 0x8D, 0xB3, 0xE5, 0x3E, 0x08, 0x1E, 0x14, + 0x2A, 0x37, 0x0B, 0x88, 0x3C, 0xCA, 0xB0, 0xF4, 0xC8, 0xC2, 0xA1, 0xAE, + 0xBC, 0xC1, 0xBE, 0x29, 0x67, 0x55, 0xE2, 0xFC, 0xAD, 0x59, 0x5C, 0xFE, + 0xBD, 0x57, 0x2C, 0xB0, 0x90, 0x8D, 0xC2, 0xED, 0x37, 0xB6, 0x7C, 0x99, + 0x88, 0xB5, 0xD5, 0x03, 0x9A, 0x3D, 0x15, 0x0D, 0x3D, 0x3A, 0xA8, 0xA8, + 0x45, 0xF0, 0x95, 0x4E, 0x25, 0x59, 0x1D, 0xCD, 0x98, 0x69, 0xBB, 0xD3, + 0xCC, 0x32, 0xC9, 0x8D, 0xEF, 0x81, 0xFE, 0xAD, 0x7D, 0x89, 0xBB, 0xBA, + 0x60, 0x13, 0xCA, 0x65, 0x95, 0x67, 0xA0, 0xF3, 0x19, 0xF6, 0x03, 0x56, + 0xD4, 0x6A, 0xD3, 0x27, 0xE2, 0xA1, 0xAD, 0x83, 0xF0, 0x4A, 0x12, 0x22, + 0x77, 0x1C, 0x05, 0x73, 0xE2, 0x19, 0x71, 0x42, 0xC0, 0xEC, 0x75, 0x46, + 0x9A, 0x90, 0x58, 0xE0, 0x6A, 0x8E, 0x2B, 0xA5, 0x46, 0x30, 0x04, 0x8E, + 0x19, 0xB2, 0x17, 0xE3, 0xBE, 0xA9, 0xBA, 0x7F, 0x56, 0xF1, 0x24, 0x03, + 0xD7, 0xB2, 0x21, 0x28, 0x76, 0x0E, 0x36, 0x30, 0x4C, 0x79, 0xD5, 0x41, + 0x9A, 0x9A, 0xA8, 0xB8, 0x35, 0xBA, 0x0C, 0x3A, 0xF2, 0x44, 0x1B, 0x20, + 0x88, 0xF7, 0xC5, 0x25, 0xD7, 0x3D, 0xC6, 0xE3, 0x3E, 0x43, 0xDD, 0x87, + 0xFE, 0xC4, 0xEA, 0xF5, 0x53, 0x3E, 0x4C, 0x65, 0xFF, 0x3B, 0x4A, 0xCB, + 0x78, 0x5A, 0x6B, 0x17, 0x5F, 0x0D, 0xC7, 0xC3, 0x4F, 0x4E, 0x9A, 0x2A, + 0xA2, 0xED, 0x57, 0x4D, 0x22, 0xE2, 0x46, 0x9A, 0x3F, 0x0F, 0x91, 0x34, + 0x24, 0x7D, 0x55, 0xE3, 0x8C, 0x95, 0x37, 0xD3, 0x1A, 0xF0, 0x09, 0x2B, + 0x2C, 0xD2, 0xC9, 0x8D, 0xB4, 0x0D, 0x00, 0xAB, 0x67, 0x29, 0x28, 0xD8, + 0x01, 0xF5, 0x19, 0x04, 0xB6, 0x1D, 0xBE, 0x76, 0xFE, 0x72, 0x5C, 0xC4, + 0x85, 0xCA, 0xD2, 0x80, 0x41, 0xDF, 0x05, 0xA8, 0xA3, 0xD5, 0x84, 0x90, + 0x4F, 0x0B, 0xF3, 0xE0, 0x3F, 0x9B, 0x19, 0xD2, 0x37, 0x89, 0x3F, 0xF2, + 0x7B, 0x52, 0x1C, 0x8C, 0xF6, 0xE1, 0xF7, 0x3C, 0x07, 0x97, 0x8C, 0x0E, + 0xA2, 0x59, 0x81, 0x0C, 0xB2, 0x90, 0x3D, 0xD3, 0xE3, 0x59, 0x46, 0xED, + 0x0F, 0xA9, 0xA7, 0xDE, 0x80, 0x6B, 0x5A, 0xAA, 0x07, 0xB6, 0x19, 0xCB, + 0xBC, 0x57, 0xF3, 0x97, 0x21, 0x7A, 0x0C, 0xB1, 0x2B, 0x74, 0x3E, 0xEB, + 0xDA, 0xA7, 0x67, 0x2D, 0x4C, 0xC4, 0x98, 0x9E, 0x36, 0x09, 0x76, 0x66, + 0x66, 0xFC, 0x1A, 0x3F, 0xEA, 0x48, 0x54, 0x1C, 0xBE, 0x30, 0xBD, 0x80, + 0x50, 0xBF, 0x7C, 0xB5, 0xCE, 0x00, 0xF6, 0x0C, 0x61, 0xD9, 0xE7, 0x24, + 0x03, 0xE0, 0xE3, 0x01, 0x81, 0x0E, 0xBD, 0xD8, 0x85, 0x34, 0x88, 0xBD, + 0xB2, 0x36, 0xA8, 0x7B, 0x5C, 0x08, 0xE5, 0x44, 0x80, 0x8C, 0x6F, 0xF8, + 0x2F, 0xD5, 0x21, 0xCA, 0x1D, 0x1C, 0xD0, 0xFB, 0xC4, 0xB5, 0x87, 0xD1, + 0x3A, 0x4E, 0xC7, 0x76, 0xB5, 0x35, 0x48, 0xB5 +}; + +static const unsigned char TA277_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA278_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA278_EC_Q[] = { + 0x04, 0x4B, 0x36, 0xE9, 0xAE, 0x57, 0x5E, 0xA8, 0x70, 0xD7, 0xD0, 0x8F, + 0x74, 0x62, 0x77, 0xC3, 0x5E, 0x7A, 0xAA, 0xE5, 0xB6, 0xA2, 0xF1, 0x78, + 0xFD, 0x02, 0x7E, 0x57, 0xDD, 0x91, 0x79, 0x9C, 0x6C, 0xB9, 0x52, 0x88, + 0x54, 0xBC, 0x2F, 0x04, 0xBE, 0xB8, 0xCD, 0xF6, 0x10, 0xD1, 0x29, 0xEC, + 0xB5, 0xD0, 0xA0, 0xC3, 0xF0, 0x89, 0x70, 0x19, 0xBB, 0x51, 0x65, 0xC5, + 0x43, 0x9C, 0xC3, 0x9B, 0x63, 0x9D, 0x20, 0x83, 0x3E, 0x06, 0x0B, 0xA6, + 0x42, 0x44, 0x85, 0x11, 0xA7, 0x4A, 0x3A, 0x2D, 0xE9, 0xD6, 0x68, 0x2F, + 0x48, 0x4E, 0x53, 0x2B, 0x07, 0x3F, 0x4D, 0xBD, 0xB9, 0xAC, 0x77, 0x39, + 0x57 +}; + +static const unsigned char TA279_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA279_EC_Q[] = { + 0x04, 0x78, 0x30, 0x81, 0xE8, 0x63, 0x1E, 0xE5, 0xEB, 0x71, 0x51, 0x0F, + 0xF7, 0x07, 0x07, 0xCA, 0x39, 0x99, 0x7C, 0x4E, 0xD5, 0x0F, 0xCC, 0x30, + 0x30, 0x0B, 0x8F, 0x66, 0x93, 0x3E, 0xCF, 0xBD, 0xC5, 0x86, 0xBD, 0xF9, + 0xB1, 0xB7, 0xB4, 0x3E, 0xB4, 0x07, 0xC8, 0xF3, 0x96, 0x31, 0xF3, 0xED, + 0xA4, 0x4F, 0xF8, 0xA3, 0x4E, 0x8D, 0x29, 0x15, 0x58, 0xB8, 0xD5, 0x6F, + 0x7F, 0xEE, 0x6C, 0x22, 0xB5, 0xB0, 0xAF, 0x48, 0x45, 0x0A, 0xBD, 0xA8, + 0x49, 0x94, 0xBF, 0x84, 0x43, 0xB0, 0xDB, 0x84, 0x4A, 0x03, 0x23, 0x19, + 0x67, 0x6A, 0x6F, 0xC1, 0x6E, 0xBC, 0x06, 0x39, 0x37, 0xD1, 0x88, 0x22, + 0xF7 +}; + +static const unsigned char TA280_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA280_RSA_N[] = { + 0xB0, 0x48, 0x65, 0xA3, 0x0D, 0x1D, 0x42, 0xE3, 0x91, 0x6D, 0x9D, 0x84, + 0xA4, 0x61, 0x96, 0x12, 0xC2, 0xED, 0xC3, 0xDA, 0x23, 0x34, 0x19, 0x76, + 0xF6, 0xEA, 0xFD, 0x55, 0x5A, 0xF6, 0x55, 0x01, 0x53, 0x0F, 0xF2, 0xCC, + 0x8C, 0x97, 0x4F, 0xB9, 0x50, 0xCB, 0xB3, 0x01, 0x44, 0x56, 0x96, 0xFD, + 0x9B, 0x28, 0xEC, 0x7B, 0x74, 0x0B, 0xE7, 0x42, 0x6B, 0x55, 0xCE, 0xC9, + 0x61, 0xB2, 0xE8, 0xAD, 0x40, 0x3C, 0xBA, 0xB9, 0x41, 0x0A, 0x05, 0x4F, + 0x1B, 0x26, 0x85, 0x8F, 0x43, 0xB5, 0x40, 0xB5, 0x85, 0xD1, 0xD4, 0x71, + 0xDC, 0x83, 0x41, 0xF3, 0xF6, 0x45, 0xC7, 0x80, 0xA2, 0x84, 0x50, 0x97, + 0x46, 0xCE, 0xA0, 0x0C, 0xC4, 0x60, 0x56, 0x04, 0x1D, 0x07, 0x5B, 0x46, + 0xA5, 0x0E, 0xB2, 0x4B, 0xA4, 0x0E, 0xA5, 0x7C, 0xEE, 0xF8, 0xD4, 0x62, + 0x03, 0xB9, 0x93, 0x6A, 0x8A, 0x14, 0xB8, 0x70, 0xF8, 0x2E, 0x82, 0x46, + 0x38, 0x23, 0x0E, 0x74, 0xC7, 0x6B, 0x41, 0xB7, 0xD0, 0x29, 0xA3, 0x9D, + 0x80, 0xB0, 0x7E, 0x77, 0x93, 0x63, 0x42, 0xFB, 0x34, 0x83, 0x3B, 0x73, + 0xA3, 0x5A, 0x21, 0x36, 0xEB, 0x47, 0xFA, 0x18, 0x17, 0xD9, 0xBA, 0x66, + 0xC2, 0x93, 0xA4, 0x8F, 0xFC, 0x5D, 0xA4, 0xAD, 0xFC, 0x50, 0x6A, 0x95, + 0xAC, 0xBC, 0x24, 0x33, 0xD1, 0xBD, 0x88, 0x7F, 0x86, 0xF5, 0xF5, 0xB2, + 0x73, 0x2A, 0x8F, 0x7C, 0xAF, 0x08, 0xF2, 0x1A, 0x98, 0x3F, 0xA9, 0x81, + 0x65, 0x3F, 0xC1, 0x8C, 0x89, 0xC5, 0x96, 0x30, 0x9A, 0x0A, 0xCF, 0xF4, + 0xD4, 0xC8, 0x34, 0xED, 0x9D, 0x2F, 0xBC, 0x8D, 0x38, 0x86, 0x53, 0xEE, + 0x97, 0x9F, 0xA9, 0xB2, 0x63, 0x94, 0x17, 0x8D, 0x0F, 0xDC, 0x66, 0x2A, + 0x7C, 0x52, 0x51, 0x75, 0xCB, 0x99, 0x8E, 0xE8, 0x3D, 0x5C, 0xBF, 0x9E, + 0x3B, 0x28, 0x8D, 0x83, 0x02, 0x0F, 0xA9, 0x9F, 0x72, 0xE2, 0x2C, 0x2B, + 0xB3, 0xDC, 0x66, 0x97, 0x00, 0x40, 0xD0, 0xA4, 0x54, 0x8E, 0x9B, 0x5D, + 0x7B, 0x45, 0x36, 0x26, 0xD6, 0x72, 0x43, 0xEB, 0xCF, 0xC0, 0xEA, 0x0D, + 0xDC, 0xCE, 0x12, 0xE6, 0x7D, 0x38, 0x9F, 0x05, 0x27, 0xA8, 0x97, 0x3E, + 0xE9, 0x51, 0xC6, 0x6C, 0x05, 0x28, 0xC1, 0x02, 0x0F, 0xE9, 0x18, 0x6D, + 0xEC, 0xBD, 0x9C, 0x06, 0xD4, 0xA7, 0x49, 0xF4, 0x54, 0x05, 0x6B, 0x6C, + 0x30, 0xF1, 0xEB, 0x03, 0xD5, 0xEA, 0x3D, 0x6A, 0x76, 0xC2, 0xCB, 0x1A, + 0x28, 0x49, 0x4D, 0x7F, 0x64, 0xE0, 0xFA, 0x2B, 0xDA, 0x73, 0x83, 0x81, + 0xFF, 0x91, 0x03, 0xBD, 0x94, 0xBB, 0xE4, 0xB8, 0x8E, 0x9C, 0x32, 0x63, + 0xCD, 0x9F, 0xBB, 0x68, 0x81, 0xB1, 0x84, 0x5B, 0xAF, 0x36, 0xBF, 0x77, + 0xEE, 0x1D, 0x7F, 0xF7, 0x49, 0x9B, 0x52, 0xEC, 0xD2, 0x77, 0x5A, 0x7D, + 0x91, 0x9D, 0x4D, 0xC2, 0x39, 0x2D, 0xE4, 0xBA, 0x82, 0xF8, 0x6F, 0xF2, + 0x4E, 0x1E, 0x0F, 0x4E, 0xE6, 0x3F, 0x59, 0xA5, 0x23, 0xDC, 0x3D, 0x87, + 0xA8, 0x28, 0x58, 0x28, 0xD1, 0xF1, 0x1B, 0x36, 0xDB, 0x4F, 0xC4, 0xFF, + 0xE1, 0x8C, 0x5B, 0x72, 0x8C, 0xC7, 0x26, 0x03, 0x27, 0xA3, 0x39, 0x0A, + 0x01, 0xAA, 0xC0, 0xB2, 0x31, 0x60, 0x83, 0x22, 0xA1, 0x4F, 0x12, 0x09, + 0x01, 0x11, 0xAF, 0x34, 0xD4, 0xCF, 0xD7, 0xAE, 0x62, 0xD3, 0x05, 0x07, + 0xB4, 0x31, 0x75, 0xE0, 0x0D, 0x6D, 0x57, 0x4F, 0x69, 0x87, 0xF9, 0x57, + 0xA9, 0xBA, 0x15, 0xF6, 0xC8, 0x52, 0x6D, 0xA1, 0xCB, 0x9C, 0x1F, 0xE5, + 0xFC, 0x78, 0xA8, 0x35, 0x9A, 0x9F, 0x41, 0x14, 0xCE, 0xA5, 0xB4, 0xCE, + 0x94, 0x08, 0x1C, 0x09, 0xAD, 0x56, 0xE5, 0xDA, 0xB6, 0x49, 0x9A, 0x4A, + 0xEA, 0x63, 0x18, 0x53, 0x9C, 0x2C, 0x2E, 0xC3 +}; + +static const unsigned char TA280_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA281_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA281_RSA_N[] = { + 0xE1, 0xFA, 0x0E, 0xFB, 0x68, 0x00, 0x12, 0xC8, 0x4D, 0xD5, 0xAC, 0x22, + 0xC4, 0x35, 0x01, 0x3B, 0xC5, 0x54, 0xE5, 0x59, 0x76, 0x63, 0xA5, 0x7F, + 0xEB, 0xC1, 0xC4, 0x6A, 0x98, 0xBD, 0x32, 0x8D, 0x17, 0x80, 0xEB, 0x5D, + 0xBA, 0xD1, 0x62, 0x3D, 0x25, 0x23, 0x19, 0x35, 0x14, 0xE9, 0x7F, 0x89, + 0xA7, 0x1B, 0x62, 0x3C, 0xD6, 0x50, 0xE7, 0x34, 0x95, 0x03, 0x32, 0xB1, + 0xB4, 0x93, 0x22, 0x3D, 0xA7, 0xE2, 0xB1, 0xED, 0xE6, 0x7B, 0x4E, 0x2E, + 0x87, 0x9B, 0x0D, 0x33, 0x75, 0x0A, 0xDE, 0xAA, 0x35, 0xE7, 0x7E, 0xE5, + 0x36, 0x98, 0xA2, 0xAE, 0x25, 0x9E, 0x95, 0xB3, 0x32, 0x96, 0xA4, 0x2B, + 0x58, 0x1E, 0xEF, 0x3F, 0xFE, 0x62, 0x34, 0x48, 0x51, 0xD1, 0xB4, 0x8D, + 0x42, 0xAD, 0x60, 0xDA, 0x49, 0x6A, 0x95, 0x70, 0xDD, 0xD2, 0x00, 0xE2, + 0xCC, 0x57, 0x63, 0x02, 0x7B, 0x96, 0xDD, 0x49, 0x97, 0x5B, 0x92, 0x4E, + 0x95, 0xD3, 0xF9, 0xCB, 0x29, 0x1F, 0x18, 0x4A, 0xF8, 0x01, 0x2A, 0xD2, + 0x63, 0x09, 0x6E, 0x24, 0xE9, 0x89, 0xD2, 0xE5, 0xC7, 0x22, 0x4C, 0xDC, + 0x73, 0x86, 0x47, 0x00, 0xAA, 0x0D, 0x88, 0x8E, 0xAE, 0x85, 0x7D, 0x4A, + 0xE9, 0xBB, 0x33, 0x4F, 0x0E, 0x52, 0x70, 0x9D, 0x95, 0xE3, 0x7C, 0x6D, + 0x96, 0x5B, 0x2D, 0x3D, 0x5F, 0xA1, 0x83, 0x46, 0x5D, 0xB6, 0xE3, 0x25, + 0xB8, 0x7C, 0xA7, 0x19, 0x80, 0x1C, 0xEA, 0x65, 0x43, 0xDC, 0x91, 0x79, + 0x36, 0x2C, 0x74, 0x7C, 0xF2, 0x67, 0x06, 0xC9, 0x89, 0xC9, 0xDB, 0xBF, + 0xDA, 0x68, 0xBF, 0x23, 0xED, 0xDC, 0x6B, 0xAD, 0x28, 0x83, 0x79, 0x2F, + 0xEC, 0x38, 0xA5, 0x0D, 0x37, 0x01, 0x67, 0x27, 0x9A, 0xE9, 0x33, 0xD9, + 0x33, 0x5F, 0x37, 0xA1, 0xC5, 0xF0, 0xAB, 0x3D, 0xFA, 0x78, 0xB0, 0xE7, + 0x2C, 0x9F, 0xF6, 0x3E, 0x9F, 0x60, 0xE0, 0xEF, 0x48, 0xE9, 0x90, 0x45, + 0x1E, 0x05, 0x51, 0x78, 0x1A, 0x2C, 0x12, 0x2C, 0x5C, 0x28, 0xAC, 0x0D, + 0xA2, 0x23, 0x9E, 0x34, 0x8F, 0x05, 0xE6, 0xA2, 0x33, 0xCE, 0x11, 0x77, + 0x13, 0xD4, 0x0E, 0xA4, 0x1E, 0x42, 0x1F, 0x86, 0xCD, 0x70, 0xFE, 0xD9, + 0x2E, 0x15, 0x3D, 0x1D, 0xBB, 0xB8, 0xF2, 0x53, 0x57, 0xDB, 0xCC, 0xC6, + 0x74, 0x29, 0x9C, 0x18, 0xB3, 0x36, 0x75, 0x38, 0x2E, 0x0F, 0x54, 0xA1, + 0xF8, 0x92, 0x1F, 0x89, 0x96, 0x4F, 0xBB, 0xD4, 0xEE, 0x9D, 0xE9, 0x3B, + 0x36, 0x42, 0xB5, 0x0A, 0x3B, 0x2A, 0xD4, 0x64, 0x79, 0x36, 0x10, 0xE1, + 0xF9, 0x91, 0x03, 0x2B, 0x7B, 0x20, 0x54, 0xCD, 0x0D, 0x19, 0x1A, 0xC8, + 0x41, 0x32, 0x34, 0xD1, 0xB0, 0x99, 0xE1, 0x90, 0x1E, 0x01, 0x40, 0x36, + 0xB5, 0xB7, 0xFA, 0xA9, 0xE5, 0x77, 0x75, 0xA4, 0x22, 0x81, 0x5D, 0xB0, + 0x8B, 0xE4, 0x27, 0x12, 0x0F, 0x54, 0x88, 0xC6, 0xDB, 0x85, 0x74, 0xE6, + 0xB7, 0xC0, 0xD7, 0xA6, 0x29, 0xFA, 0xDB, 0xDE, 0xF3, 0x93, 0x97, 0x27, + 0x04, 0x55, 0x2F, 0x0A, 0x6F, 0x37, 0xC5, 0x3D, 0x13, 0xAF, 0x0A, 0x00, + 0xA9, 0x2C, 0x8B, 0x1C, 0x81, 0x28, 0xD7, 0xEF, 0x86, 0x31, 0xA9, 0xAE, + 0xF2, 0x6E, 0xB8, 0xCA, 0x6A, 0x2C, 0x54, 0x47, 0xD8, 0x2A, 0x88, 0x2E, + 0xAF, 0xC1, 0x07, 0x10, 0x78, 0xAC, 0x11, 0xA2, 0x2F, 0x42, 0xF0, 0x37, + 0xC5, 0xF2, 0xB8, 0x56, 0xDD, 0x0E, 0x62, 0x2D, 0xCE, 0x2D, 0x56, 0x7E, + 0x55, 0xF2, 0xA7, 0x44, 0xF6, 0x2B, 0x32, 0xF4, 0x23, 0xA8, 0x47, 0xE8, + 0xD4, 0x2A, 0x01, 0x78, 0xCF, 0x6A, 0xC3, 0x37, 0xA8, 0x9E, 0x65, 0xD2, + 0x2C, 0xE5, 0xFA, 0xBA, 0x33, 0xC1, 0x06, 0x44, 0xF6, 0xE6, 0xCF, 0xA5, + 0x0D, 0xA7, 0x66, 0x08, 0x34, 0x8A, 0x2C, 0xF3 +}; + +static const unsigned char TA281_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA282_DN[] = { + 0x30, 0x7B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, 0x61, + 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x53, 0x61, 0x6C, 0x66, 0x6F, + 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x11, 0x43, 0x6F, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x43, 0x41, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x18, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73 +}; + +static const unsigned char TA282_RSA_N[] = { + 0xBE, 0x40, 0x9D, 0xF4, 0x6E, 0xE1, 0xEA, 0x76, 0x87, 0x1C, 0x4D, 0x45, + 0x44, 0x8E, 0xBE, 0x46, 0xC8, 0x83, 0x06, 0x9D, 0xC1, 0x2A, 0xFE, 0x18, + 0x1F, 0x8E, 0xE4, 0x02, 0xFA, 0xF3, 0xAB, 0x5D, 0x50, 0x8A, 0x16, 0x31, + 0x0B, 0x9A, 0x06, 0xD0, 0xC5, 0x70, 0x22, 0xCD, 0x49, 0x2D, 0x54, 0x63, + 0xCC, 0xB6, 0x6E, 0x68, 0x46, 0x0B, 0x53, 0xEA, 0xCB, 0x4C, 0x24, 0xC0, + 0xBC, 0x72, 0x4E, 0xEA, 0xF1, 0x15, 0xAE, 0xF4, 0x54, 0x9A, 0x12, 0x0A, + 0xC3, 0x7A, 0xB2, 0x33, 0x60, 0xE2, 0xDA, 0x89, 0x55, 0xF3, 0x22, 0x58, + 0xF3, 0xDE, 0xDC, 0xCF, 0xEF, 0x83, 0x86, 0xA2, 0x8C, 0x94, 0x4F, 0x9F, + 0x68, 0xF2, 0x98, 0x90, 0x46, 0x84, 0x27, 0xC7, 0x76, 0xBF, 0xE3, 0xCC, + 0x35, 0x2C, 0x8B, 0x5E, 0x07, 0x64, 0x65, 0x82, 0xC0, 0x48, 0xB0, 0xA8, + 0x91, 0xF9, 0x61, 0x9F, 0x76, 0x20, 0x50, 0xA8, 0x91, 0xC7, 0x66, 0xB5, + 0xEB, 0x78, 0x62, 0x03, 0x56, 0xF0, 0x8A, 0x1A, 0x13, 0xEA, 0x31, 0xA3, + 0x1E, 0xA0, 0x99, 0xFD, 0x38, 0xF6, 0xF6, 0x27, 0x32, 0x58, 0x6F, 0x07, + 0xF5, 0x6B, 0xB8, 0xFB, 0x14, 0x2B, 0xAF, 0xB7, 0xAA, 0xCC, 0xD6, 0x63, + 0x5F, 0x73, 0x8C, 0xDA, 0x05, 0x99, 0xA8, 0x38, 0xA8, 0xCB, 0x17, 0x78, + 0x36, 0x51, 0xAC, 0xE9, 0x9E, 0xF4, 0x78, 0x3A, 0x8D, 0xCF, 0x0F, 0xD9, + 0x42, 0xE2, 0x98, 0x0C, 0xAB, 0x2F, 0x9F, 0x0E, 0x01, 0xDE, 0xEF, 0x9F, + 0x99, 0x49, 0xF1, 0x2D, 0xDF, 0xAC, 0x74, 0x4D, 0x1B, 0x98, 0xB5, 0x47, + 0xC5, 0xE5, 0x29, 0xD1, 0xF9, 0x90, 0x18, 0xC7, 0x62, 0x9C, 0xBE, 0x83, + 0xC7, 0x26, 0x7B, 0x3E, 0x8A, 0x25, 0xC7, 0xC0, 0xDD, 0x9D, 0xE6, 0x35, + 0x68, 0x10, 0x20, 0x9D, 0x8F, 0xD8, 0xDE, 0xD2, 0xC3, 0x84, 0x9C, 0x0D, + 0x5E, 0xE8, 0x2F, 0xC9 +}; + +static const unsigned char TA282_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA283_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA283_EC_Q[] = { + 0x04, 0xC6, 0xCB, 0xC7, 0x28, 0xD1, 0xFB, 0x84, 0xF5, 0x9A, 0xEF, 0x42, + 0x14, 0x20, 0xE1, 0x43, 0x6B, 0x6E, 0x75, 0xAD, 0xFC, 0x2B, 0x03, 0x84, + 0xD4, 0x76, 0x93, 0x25, 0xD7, 0x59, 0x3B, 0x41, 0x65, 0x6B, 0x1E, 0xE6, + 0x34, 0x2A, 0xBB, 0x74, 0xF6, 0x12, 0xCE, 0xE8, 0x6D, 0xE7, 0xAB, 0xE4, + 0x3C, 0x4E, 0x3F, 0x44, 0x08, 0x8B, 0xCD, 0x16, 0x71, 0xCB, 0xBF, 0x92, + 0x99, 0xF4, 0xA4, 0xD7, 0x3C, 0x50, 0x54, 0x52, 0x90, 0x85, 0x83, 0x78, + 0x94, 0x67, 0x67, 0xA3, 0x1C, 0x09, 0x19, 0x3D, 0x75, 0x34, 0x85, 0xDE, + 0xED, 0x60, 0x7D, 0xC7, 0x0C, 0xB4, 0x41, 0x52, 0xB9, 0x6E, 0xE5, 0xEE, + 0x42 +}; + +static const unsigned char TA284_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA284_RSA_N[] = { + 0xAE, 0xFF, 0x09, 0x59, 0x91, 0x80, 0x0A, 0x4A, 0x68, 0xE6, 0x24, 0x3F, + 0xB8, 0xA7, 0xE4, 0xC8, 0x3A, 0x0A, 0x3A, 0x16, 0xCD, 0xC9, 0x23, 0x61, + 0xA0, 0x93, 0x71, 0xF2, 0xAB, 0x8B, 0x73, 0x8F, 0xA0, 0x67, 0x65, 0x60, + 0xD2, 0x54, 0x6B, 0x63, 0x51, 0x6F, 0x49, 0x33, 0xE0, 0x72, 0x07, 0x13, + 0x7D, 0x38, 0xCD, 0x06, 0x92, 0x07, 0x29, 0x52, 0x6B, 0x4E, 0x77, 0x6C, + 0x04, 0xD3, 0x95, 0xFA, 0xDD, 0x4C, 0x8C, 0xD9, 0x5D, 0xC1, 0x61, 0x7D, + 0x4B, 0xE7, 0x28, 0xB3, 0x44, 0x81, 0x7B, 0x51, 0xAF, 0xDD, 0x33, 0xB1, + 0x68, 0x7C, 0xD6, 0x4E, 0x4C, 0xFE, 0x2B, 0x68, 0xB9, 0xCA, 0x66, 0x69, + 0xC4, 0xEC, 0x5E, 0x57, 0x7F, 0xF7, 0x0D, 0xC7, 0x9C, 0x36, 0x36, 0xE5, + 0x07, 0x60, 0xAC, 0xC0, 0x4C, 0xEA, 0x08, 0x6C, 0xEF, 0x06, 0x7C, 0x4F, + 0x5B, 0x28, 0x7A, 0x08, 0xFC, 0x93, 0x5D, 0x9B, 0xF6, 0x9C, 0xB4, 0x8B, + 0x86, 0xBA, 0x21, 0xB9, 0xF4, 0xF0, 0xE8, 0x59, 0x5A, 0x28, 0xA1, 0x34, + 0x84, 0x1A, 0x25, 0x91, 0xB6, 0xB5, 0x8F, 0xEF, 0xB2, 0xF9, 0x80, 0xFA, + 0xF9, 0x3D, 0x3C, 0x11, 0x72, 0xD8, 0xE3, 0x2F, 0x86, 0x76, 0xC5, 0x79, + 0x2C, 0xC1, 0xA9, 0x90, 0x93, 0x46, 0x98, 0x67, 0xCB, 0x83, 0x6A, 0xA0, + 0x50, 0x23, 0xA7, 0x3B, 0xF6, 0x81, 0x39, 0xE0, 0xED, 0xF0, 0xB9, 0xBF, + 0x65, 0xF1, 0xD8, 0xCB, 0x7A, 0xFB, 0xEF, 0x73, 0x03, 0xCE, 0x00, 0xF4, + 0x7D, 0xD7, 0xE0, 0x5D, 0x3B, 0x66, 0xB8, 0xDC, 0x8E, 0xBA, 0x83, 0xCB, + 0x87, 0x76, 0x03, 0xFC, 0x25, 0xD9, 0xE7, 0x23, 0x6F, 0x06, 0xFD, 0x67, + 0xF3, 0xE0, 0xFF, 0x84, 0xBC, 0x47, 0xBF, 0xB5, 0x16, 0x18, 0x46, 0x69, + 0x14, 0xCC, 0x05, 0xF7, 0xDB, 0xD3, 0x49, 0xAC, 0x6B, 0xCC, 0xAB, 0xE4, + 0xB5, 0x0B, 0x43, 0x24, 0x5E, 0x4B, 0x6B, 0x4D, 0x67, 0xDF, 0xD6, 0xB5, + 0x3E, 0x4F, 0x78, 0x1F, 0x94, 0x71, 0x24, 0xEA, 0xDE, 0x70, 0xFC, 0xF1, + 0x93, 0xFE, 0x9E, 0x93, 0x5A, 0xE4, 0x94, 0x5A, 0x97, 0x54, 0x0C, 0x35, + 0x7B, 0x5F, 0x6C, 0xEE, 0x00, 0x1F, 0x24, 0xEC, 0x03, 0xBA, 0x02, 0xF5, + 0x76, 0xF4, 0x9F, 0xD4, 0x9A, 0xED, 0x85, 0x2C, 0x38, 0x22, 0x2F, 0xC7, + 0xD8, 0x2F, 0x76, 0x11, 0x4F, 0xFD, 0x6C, 0x5C, 0xE8, 0xF5, 0x8E, 0x27, + 0x87, 0x7F, 0x19, 0x4A, 0x21, 0x47, 0x90, 0x1D, 0x79, 0x8D, 0x1C, 0x5B, + 0xF8, 0xCF, 0x4A, 0x85, 0xE4, 0xED, 0xB3, 0x5B, 0x8D, 0xBE, 0xC4, 0x64, + 0x28, 0x5D, 0x41, 0xC4, 0x6E, 0xAC, 0x38, 0x5A, 0x4F, 0x23, 0x74, 0x74, + 0xA9, 0x12, 0xC3, 0xF6, 0xD2, 0xB9, 0x11, 0x15, 0x33, 0x07, 0x91, 0xD8, + 0x3B, 0x37, 0x3A, 0x63, 0x30, 0x06, 0xD1, 0xC5, 0x22, 0x36, 0x28, 0x62, + 0x23, 0x10, 0xE0, 0x46, 0xCC, 0x97, 0xAC, 0xD6, 0x2B, 0x5D, 0x64, 0x24, + 0xD5, 0xEE, 0x1C, 0x0E, 0xDE, 0xFB, 0x08, 0x5A, 0x75, 0x2A, 0xF6, 0x63, + 0x6D, 0xCE, 0x0B, 0x42, 0xBE, 0xD1, 0xBA, 0x70, 0x1C, 0x9C, 0x21, 0xE5, + 0x0F, 0x31, 0x69, 0x17, 0xD7, 0xFC, 0x0A, 0xB4, 0xDE, 0xED, 0x80, 0x9C, + 0xCB, 0x92, 0xB4, 0x8B, 0xF5, 0xDE, 0x59, 0xA2, 0x58, 0x09, 0xA5, 0x63, + 0x47, 0x0B, 0xE1, 0x41, 0x32, 0x34, 0x41, 0xD9, 0x9A, 0xB1, 0xD9, 0xA8, + 0xB0, 0x1B, 0x5A, 0xDE, 0x0D, 0x0D, 0xF4, 0xE2, 0xB2, 0x5D, 0x35, 0x80, + 0xB9, 0x81, 0xD4, 0x84, 0x69, 0x91, 0x02, 0xCB, 0x75, 0xD0, 0x8D, 0xC5, + 0xB5, 0x3D, 0x09, 0x91, 0x09, 0x8F, 0x14, 0xA1, 0x14, 0x74, 0x79, 0x3E, + 0xD6, 0xC9, 0x15, 0x1D, 0xA4, 0x59, 0x59, 0x22, 0xDC, 0xF6, 0x8A, 0x45, + 0x3D, 0x3C, 0x12, 0xD6, 0x3E, 0x5D, 0x32, 0x2F +}; + +static const unsigned char TA284_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA285_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA285_EC_Q[] = { + 0x04, 0xF1, 0x0B, 0xDD, 0x86, 0x43, 0x20, 0x19, 0xDF, 0x97, 0x85, 0xE8, + 0x22, 0x4A, 0x9B, 0xCF, 0x9D, 0x98, 0xBF, 0xB4, 0x05, 0x26, 0xC9, 0xCB, + 0xE3, 0xA6, 0xD2, 0x8F, 0xC5, 0x9E, 0x78, 0x7B, 0x31, 0x89, 0xA9, 0x89, + 0xAD, 0x27, 0x3C, 0x65, 0x10, 0x82, 0xFC, 0xDF, 0xC3, 0x9D, 0x4E, 0xF0, + 0x33, 0x23, 0xC4, 0xD2, 0x32, 0xF5, 0x1C, 0xB0, 0xDF, 0x33, 0x17, 0x5D, + 0xC5, 0xF0, 0xB1, 0x8A, 0xF9, 0xEF, 0xB9, 0xB7, 0x14, 0xCA, 0x29, 0x4A, + 0xC2, 0x0F, 0xA9, 0x7F, 0x75, 0x65, 0x49, 0x2A, 0x30, 0x67, 0xF4, 0x64, + 0xF7, 0xD6, 0x1A, 0x77, 0xDA, 0xC3, 0xC2, 0x97, 0x61, 0x42, 0x7B, 0x49, + 0xAD +}; + +static const unsigned char TA286_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA286_RSA_N[] = { + 0xD8, 0x8E, 0xA3, 0x89, 0x80, 0x0B, 0xB2, 0x57, 0x52, 0xDC, 0xA9, 0x53, + 0x4C, 0x37, 0xB9, 0x7F, 0x63, 0x17, 0x13, 0xEF, 0xA7, 0x5B, 0x23, 0x5B, + 0x69, 0x75, 0xB0, 0x99, 0x0A, 0x17, 0xC1, 0x8B, 0xC4, 0xDB, 0xA8, 0xE0, + 0xCC, 0x31, 0xBA, 0xC2, 0xF2, 0xCD, 0x5D, 0xE9, 0xB7, 0xF8, 0x1D, 0xAF, + 0x6A, 0xC4, 0x95, 0x87, 0xD7, 0x47, 0xC9, 0x95, 0xD8, 0x82, 0x04, 0x50, + 0x3D, 0x81, 0x08, 0xFF, 0xE4, 0x3D, 0xB3, 0xB1, 0xD6, 0xC5, 0xB2, 0xFD, + 0x88, 0x09, 0xDB, 0x9C, 0x84, 0xEC, 0x25, 0x17, 0x14, 0x87, 0x7F, 0x30, + 0x78, 0x9B, 0x6A, 0x58, 0xC9, 0xB6, 0x73, 0x28, 0x3C, 0x34, 0xF7, 0x99, + 0xF7, 0x7F, 0xD3, 0xA6, 0xF8, 0x1C, 0x45, 0x7C, 0xAD, 0x2C, 0x8C, 0x94, + 0x3F, 0xD8, 0x67, 0x10, 0x53, 0x7E, 0x22, 0xCD, 0x4E, 0x25, 0x51, 0xF0, + 0x25, 0x24, 0x35, 0x11, 0x5E, 0x10, 0xC6, 0xEC, 0x87, 0x66, 0x89, 0x81, + 0x68, 0xBA, 0xCC, 0x2B, 0x9D, 0x47, 0x73, 0x1F, 0xBD, 0xCD, 0x91, 0xA4, + 0x72, 0x6A, 0x9C, 0xA2, 0x1B, 0x18, 0xA0, 0x6F, 0xEC, 0x50, 0xF4, 0x7D, + 0x40, 0xC2, 0xA8, 0x30, 0xCF, 0xBD, 0x73, 0xC8, 0x13, 0x2B, 0x10, 0x13, + 0x1E, 0x8B, 0x9A, 0xA8, 0x3A, 0x94, 0x73, 0xD3, 0x18, 0x69, 0x0A, 0x4A, + 0xFF, 0xC1, 0x01, 0x03, 0xFF, 0x79, 0x7F, 0xB5, 0x48, 0x7F, 0x7B, 0xEE, + 0xE8, 0x29, 0x6F, 0x36, 0x4C, 0x95, 0x61, 0x86, 0xD8, 0xF9, 0xA2, 0x73, + 0x8A, 0xEE, 0xAE, 0x2F, 0x96, 0xEE, 0x68, 0xCD, 0x3D, 0x4D, 0x28, 0x42, + 0xF9, 0x45, 0x2B, 0x32, 0x1B, 0x46, 0x55, 0x16, 0x6A, 0xA6, 0x4B, 0x29, + 0xF9, 0xBB, 0x95, 0x56, 0xBF, 0x46, 0x1D, 0xEC, 0x1D, 0x93, 0x1D, 0xC0, + 0x65, 0xB2, 0x1F, 0xA1, 0x43, 0xAE, 0x56, 0x9E, 0xA0, 0xB1, 0x8F, 0x6B, + 0x12, 0xB7, 0x60, 0x6D, 0x78, 0x0B, 0xCA, 0x8A, 0x5C, 0xED, 0x1E, 0x96, + 0x0E, 0x83, 0xA6, 0x48, 0x95, 0x8D, 0x3B, 0xA3, 0x21, 0xC4, 0xAE, 0x58, + 0xC6, 0x00, 0xB2, 0x84, 0xB4, 0x23, 0xA4, 0x96, 0x86, 0x35, 0xB8, 0xD8, + 0x9E, 0xD8, 0xAC, 0x34, 0x49, 0x98, 0x63, 0x95, 0xC5, 0xCB, 0x6D, 0x48, + 0x47, 0xE2, 0xF2, 0x2E, 0x18, 0x1E, 0xD0, 0x31, 0xAB, 0xDD, 0x74, 0xEC, + 0xF9, 0xDC, 0x8C, 0xB8, 0x1C, 0x8E, 0x68, 0x23, 0xBA, 0xD0, 0xF3, 0x50, + 0xDC, 0xCF, 0x65, 0x8F, 0x73, 0x3A, 0x32, 0xC7, 0x7C, 0xFE, 0xCA, 0x82, + 0x22, 0x4F, 0xBE, 0x8E, 0x62, 0x47, 0x66, 0xE5, 0xCD, 0x87, 0xE2, 0xE8, + 0xD5, 0x0F, 0x18, 0x9F, 0xE5, 0x04, 0x72, 0x4B, 0x46, 0x3C, 0x10, 0xF2, + 0x44, 0xC2, 0x64, 0x56, 0x71, 0x4E, 0x75, 0xE8, 0x9C, 0xC9, 0x26, 0x74, + 0xC5, 0x7D, 0x59, 0xD1, 0x0A, 0x5B, 0x0F, 0x6D, 0xFE, 0x9E, 0x75, 0x1C, + 0x18, 0xC6, 0x1A, 0x3A, 0x7C, 0xD8, 0x0D, 0x04, 0xCC, 0xCD, 0xB7, 0x45, + 0x65, 0x7A, 0xB1, 0x8F, 0xB8, 0xAE, 0x84, 0x48, 0x3E, 0xB3, 0x7A, 0x4D, + 0xA8, 0x03, 0xE2, 0xE2, 0x7E, 0x01, 0x16, 0x59, 0x68, 0x18, 0x43, 0x33, + 0xB0, 0xD2, 0xDC, 0xB0, 0x1A, 0x43, 0x35, 0xEE, 0xA5, 0xDA, 0xA9, 0x46, + 0x5C, 0xAE, 0x86, 0x81, 0x41, 0x01, 0x4A, 0x74, 0x26, 0xEC, 0x9F, 0x06, + 0xBF, 0xC2, 0x05, 0x37, 0x64, 0x75, 0x78, 0x29, 0x68, 0xFD, 0xC5, 0xF5, + 0xEB, 0xFE, 0x47, 0xF9, 0xE4, 0x85, 0xB0, 0xE1, 0x7B, 0x31, 0x9D, 0xA6, + 0x7F, 0x72, 0xA3, 0xB9, 0xC4, 0x2C, 0x2E, 0xCC, 0x99, 0x57, 0x0E, 0x21, + 0x0C, 0x45, 0x01, 0x94, 0x65, 0xEB, 0x65, 0x09, 0xC6, 0x63, 0x22, 0x0B, + 0x33, 0x49, 0x92, 0x48, 0x3C, 0xFC, 0xCD, 0xCE, 0xB0, 0x3E, 0x8E, 0x9E, + 0x8B, 0xF8, 0xFE, 0x49, 0xC5, 0x35, 0x72, 0x47 +}; + +static const unsigned char TA286_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA287_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x1E, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA287_RSA_N[] = { + 0xD3, 0xB2, 0x4A, 0xCF, 0x7A, 0x47, 0xEF, 0x75, 0x9B, 0x23, 0xFA, 0x3A, + 0x2F, 0xD6, 0x50, 0x45, 0x89, 0x35, 0x3A, 0xC6, 0x6B, 0xDB, 0xFE, 0xDB, + 0x00, 0x68, 0xA8, 0xE0, 0x03, 0x11, 0x1D, 0x37, 0x50, 0x08, 0x9F, 0x4D, + 0x4A, 0x68, 0x94, 0x35, 0xB3, 0x53, 0xD1, 0x94, 0x63, 0xA7, 0x20, 0x56, + 0xAF, 0xDE, 0x51, 0x78, 0xEC, 0x2A, 0x3D, 0xF3, 0x48, 0x48, 0x50, 0x3E, + 0x0A, 0xDF, 0x46, 0x55, 0x8B, 0x27, 0x6D, 0xC3, 0x10, 0x4D, 0x0D, 0x91, + 0x52, 0x43, 0xD8, 0x87, 0xE0, 0x5D, 0x4E, 0x36, 0xB5, 0x21, 0xCA, 0x5F, + 0x39, 0x40, 0x04, 0x5F, 0x5B, 0x7E, 0xCC, 0xA3, 0xC6, 0x2B, 0xA9, 0x40, + 0x1E, 0xD9, 0x36, 0x84, 0xD6, 0x48, 0xF3, 0x92, 0x1E, 0x34, 0x46, 0x20, + 0x24, 0xC1, 0xA4, 0x51, 0x8E, 0x4A, 0x1A, 0xEF, 0x50, 0x3F, 0x69, 0x5D, + 0x19, 0x7F, 0x45, 0xC3, 0xC7, 0x01, 0x8F, 0x51, 0xC9, 0x23, 0xE8, 0x72, + 0xAE, 0xB4, 0xBC, 0x56, 0x09, 0x7F, 0x12, 0xCB, 0x1C, 0xB1, 0xAF, 0x29, + 0x90, 0x0A, 0xC9, 0x55, 0xCC, 0x0F, 0xD3, 0xB4, 0x1A, 0xED, 0x47, 0x35, + 0x5A, 0x4A, 0xED, 0x9C, 0x73, 0x04, 0x21, 0xD0, 0xAA, 0xBD, 0x0C, 0x13, + 0xB5, 0x00, 0xCA, 0x26, 0x6C, 0xC4, 0x6B, 0x0C, 0x94, 0x5A, 0x95, 0x94, + 0xDA, 0x50, 0x9A, 0xF1, 0xFF, 0xA5, 0x2B, 0x66, 0x31, 0xA4, 0xC9, 0x38, + 0xA0, 0xDF, 0x1D, 0x1F, 0xB8, 0x09, 0x2E, 0xF3, 0xA7, 0xE8, 0x67, 0x52, + 0xAB, 0x95, 0x1F, 0xE0, 0x46, 0x3E, 0xD8, 0xA4, 0xC3, 0xCA, 0x5A, 0xC5, + 0x31, 0x80, 0xE8, 0x48, 0x9A, 0x9F, 0x94, 0x69, 0xFE, 0x19, 0xDD, 0xD8, + 0x73, 0x7C, 0x81, 0xCA, 0x96, 0xDE, 0x8E, 0xED, 0xB3, 0x32, 0x05, 0x65, + 0x84, 0x34, 0xE6, 0xE6, 0xFD, 0x57, 0x10, 0xB5, 0x5F, 0x76, 0xBF, 0x2F, + 0xB0, 0x10, 0x0D, 0xC5 +}; + +static const unsigned char TA287_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA288_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x21, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x45, 0x56, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA288_RSA_N[] = { + 0x99, 0xF1, 0x84, 0x34, 0x70, 0xBA, 0x2F, 0xB7, 0x30, 0xA0, 0x8E, 0xBD, + 0x7C, 0x04, 0xCF, 0xBE, 0x62, 0xBC, 0x99, 0xFD, 0x82, 0x97, 0xD2, 0x7A, + 0x0A, 0x67, 0x96, 0x38, 0x09, 0xF6, 0x10, 0x4E, 0x95, 0x22, 0x73, 0x99, + 0x8D, 0xDA, 0x15, 0x2D, 0xE7, 0x05, 0xFC, 0x19, 0x73, 0x22, 0xB7, 0x8E, + 0x98, 0x00, 0xBC, 0x3C, 0x3D, 0xAC, 0xA1, 0x6C, 0xFB, 0xD6, 0x79, 0x25, + 0x4B, 0xAD, 0xF0, 0xCC, 0x64, 0xDA, 0x88, 0x3E, 0x29, 0xB8, 0x0F, 0x09, + 0xD3, 0x34, 0xDD, 0x33, 0xF5, 0x62, 0xD1, 0xE1, 0xCD, 0x19, 0xE9, 0xEE, + 0x18, 0x4F, 0x4C, 0x58, 0xAE, 0xE2, 0x1E, 0xD6, 0x0C, 0x5B, 0x15, 0x5A, + 0xD8, 0x3A, 0xB8, 0xC4, 0x18, 0x64, 0x1E, 0xE3, 0x33, 0xB2, 0xB5, 0x89, + 0x77, 0x4E, 0x0C, 0xBF, 0xD9, 0x94, 0x6B, 0x13, 0x97, 0x6F, 0x12, 0xA3, + 0xFE, 0x99, 0xA9, 0x04, 0xCC, 0x15, 0xEC, 0x60, 0x68, 0x36, 0xED, 0x08, + 0x7B, 0xB7, 0xF5, 0xBF, 0x93, 0xED, 0x66, 0x31, 0x83, 0x8C, 0xC6, 0x71, + 0x34, 0x87, 0x4E, 0x17, 0xEA, 0xAF, 0x8B, 0x91, 0x8D, 0x1C, 0x56, 0x41, + 0xAE, 0x22, 0x37, 0x5E, 0x37, 0xF2, 0x1D, 0xD9, 0xD1, 0x2D, 0x0D, 0x2F, + 0x69, 0x51, 0xA7, 0xBE, 0x66, 0xA6, 0x8A, 0x3A, 0x2A, 0xBD, 0xC7, 0x1A, + 0xB1, 0xE1, 0x14, 0xF0, 0xBE, 0x3A, 0x1D, 0xB9, 0xCF, 0x5B, 0xB1, 0x6A, + 0xFE, 0xB4, 0xB1, 0x46, 0x20, 0xA2, 0xFB, 0x1E, 0x3B, 0x70, 0xEF, 0x93, + 0x98, 0x7D, 0x8C, 0x73, 0x96, 0xF2, 0xC5, 0xEF, 0x85, 0x70, 0xAD, 0x29, + 0x26, 0xFC, 0x1E, 0x04, 0x3E, 0x1C, 0xA0, 0xD8, 0x0F, 0xCB, 0x52, 0x83, + 0x62, 0x7C, 0xEE, 0x8B, 0x53, 0x95, 0x90, 0xA9, 0x57, 0xA2, 0xEA, 0x61, + 0x05, 0xD8, 0xF9, 0x4D, 0xC4, 0x27, 0xFA, 0x6E, 0xAD, 0xED, 0xF9, 0xD7, + 0x51, 0xF7, 0x6B, 0xA5 +}; + +static const unsigned char TA288_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA289_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA289_RSA_N[] = { + 0xAD, 0x0E, 0x15, 0xCE, 0xE4, 0x43, 0x80, 0x5C, 0xB1, 0x87, 0xF3, 0xB7, + 0x60, 0xF9, 0x71, 0x12, 0xA5, 0xAE, 0xDC, 0x26, 0x94, 0x88, 0xAA, 0xF4, + 0xCE, 0xF5, 0x20, 0x39, 0x28, 0x58, 0x60, 0x0C, 0xF8, 0x80, 0xDA, 0xA9, + 0x15, 0x95, 0x32, 0x61, 0x3C, 0xB5, 0xB1, 0x28, 0x84, 0x8A, 0x8A, 0xDC, + 0x9F, 0x0A, 0x0C, 0x83, 0x17, 0x7A, 0x8F, 0x90, 0xAC, 0x8A, 0xE7, 0x79, + 0x53, 0x5C, 0x31, 0x84, 0x2A, 0xF6, 0x0F, 0x98, 0x32, 0x36, 0x76, 0xCC, + 0xDE, 0xDD, 0x3C, 0xA8, 0xA2, 0xEF, 0x6A, 0xFB, 0x21, 0xF2, 0x52, 0x61, + 0xDF, 0x9F, 0x20, 0xD7, 0x1F, 0xE2, 0xB1, 0xD9, 0xFE, 0x18, 0x64, 0xD2, + 0x12, 0x5B, 0x5F, 0xF9, 0x58, 0x18, 0x35, 0xBC, 0x47, 0xCD, 0xA1, 0x36, + 0xF9, 0x6B, 0x7F, 0xD4, 0xB0, 0x38, 0x3E, 0xC1, 0x1B, 0xC3, 0x8C, 0x33, + 0xD9, 0xD8, 0x2F, 0x18, 0xFE, 0x28, 0x0F, 0xB3, 0xA7, 0x83, 0xD6, 0xC3, + 0x6E, 0x44, 0xC0, 0x61, 0x35, 0x96, 0x16, 0xFE, 0x59, 0x9C, 0x8B, 0x76, + 0x6D, 0xD7, 0xF1, 0xA2, 0x4B, 0x0D, 0x2B, 0xFF, 0x0B, 0x72, 0xDA, 0x9E, + 0x60, 0xD0, 0x8E, 0x90, 0x35, 0xC6, 0x78, 0x55, 0x87, 0x20, 0xA1, 0xCF, + 0xE5, 0x6D, 0x0A, 0xC8, 0x49, 0x7C, 0x31, 0x98, 0x33, 0x6C, 0x22, 0xE9, + 0x87, 0xD0, 0x32, 0x5A, 0xA2, 0xBA, 0x13, 0x82, 0x11, 0xED, 0x39, 0x17, + 0x9D, 0x99, 0x3A, 0x72, 0xA1, 0xE6, 0xFA, 0xA4, 0xD9, 0xD5, 0x17, 0x31, + 0x75, 0xAE, 0x85, 0x7D, 0x22, 0xAE, 0x3F, 0x01, 0x46, 0x86, 0xF6, 0x28, + 0x79, 0xC8, 0xB1, 0xDA, 0xE4, 0x57, 0x17, 0xC4, 0x7E, 0x1C, 0x0E, 0xB0, + 0xB4, 0x92, 0xA6, 0x56, 0xB3, 0xBD, 0xB2, 0x97, 0xED, 0xAA, 0xA7, 0xF0, + 0xB7, 0xC5, 0xA8, 0x3F, 0x95, 0x16, 0xD0, 0xFF, 0xA1, 0x96, 0xEB, 0x08, + 0x5F, 0x18, 0x77, 0x4F +}; + +static const unsigned char TA289_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA290_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA290_RSA_N[] = { + 0xD9, 0xE7, 0x28, 0x2F, 0x52, 0x3F, 0x36, 0x72, 0x49, 0x88, 0x93, 0x34, + 0xF3, 0xF8, 0x6A, 0x1E, 0x31, 0x54, 0x80, 0x9F, 0xAD, 0x54, 0x41, 0xB5, + 0x47, 0xDF, 0x96, 0xA8, 0xD4, 0xAF, 0x80, 0x2D, 0xB9, 0x0A, 0xCF, 0x75, + 0xFD, 0x89, 0xA5, 0x7D, 0x24, 0xFA, 0xE3, 0x22, 0x0C, 0x2B, 0xBC, 0x95, + 0x17, 0x0B, 0x33, 0xBF, 0x19, 0x4D, 0x41, 0x06, 0x90, 0x00, 0xBD, 0x0C, + 0x4D, 0x10, 0xFE, 0x07, 0xB5, 0xE7, 0x1C, 0x6E, 0x22, 0x55, 0x31, 0x65, + 0x97, 0xBD, 0xD3, 0x17, 0xD2, 0x1E, 0x62, 0xF3, 0xDB, 0xEA, 0x6C, 0x50, + 0x8C, 0x3F, 0x84, 0x0C, 0x96, 0xCF, 0xB7, 0xCB, 0x03, 0xE0, 0xCA, 0x6D, + 0xA1, 0x14, 0x4C, 0x1B, 0x89, 0xDD, 0xED, 0x00, 0xB0, 0x52, 0x7C, 0xAF, + 0x91, 0x6C, 0xB1, 0x38, 0x13, 0xD1, 0xE9, 0x12, 0x08, 0xC0, 0x00, 0xB0, + 0x1C, 0x2B, 0x11, 0xDA, 0x77, 0x70, 0x36, 0x9B, 0xAE, 0xCE, 0x79, 0x87, + 0xDC, 0x82, 0x70, 0xE6, 0x09, 0x74, 0x70, 0x55, 0x69, 0xAF, 0xA3, 0x68, + 0x9F, 0xBF, 0xDD, 0xB6, 0x79, 0xB3, 0xF2, 0x9D, 0x70, 0x29, 0x55, 0xF4, + 0xAB, 0xFF, 0x95, 0x61, 0xF3, 0xC9, 0x40, 0x6F, 0x1D, 0xD1, 0xBE, 0x93, + 0xBB, 0xD3, 0x88, 0x2A, 0xBB, 0x9D, 0xBF, 0x72, 0x5A, 0x56, 0x71, 0x3B, + 0x3F, 0xD4, 0xF3, 0xD1, 0x0A, 0xFE, 0x28, 0xEF, 0xA3, 0xEE, 0xD9, 0x99, + 0xAF, 0x03, 0xD3, 0x8F, 0x60, 0xB7, 0xF2, 0x92, 0xA1, 0xB1, 0xBD, 0x89, + 0x89, 0x1F, 0x30, 0xCD, 0xC3, 0xA6, 0x2E, 0x62, 0x33, 0xAE, 0x16, 0x02, + 0x77, 0x44, 0x5A, 0xE7, 0x81, 0x0A, 0x3C, 0xA7, 0x44, 0x2E, 0x79, 0xB8, + 0x3F, 0x04, 0xBC, 0x5C, 0xA0, 0x87, 0xE1, 0x1B, 0xAF, 0x51, 0x8E, 0xCD, + 0xEC, 0x2C, 0xFA, 0xF8, 0xFE, 0x6D, 0xF0, 0x3A, 0x7C, 0xAA, 0x8B, 0xE4, + 0x67, 0x95, 0x31, 0x8D +}; + +static const unsigned char TA290_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA291_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA291_EC_Q[] = { + 0x04, 0x19, 0xE7, 0xBC, 0xAC, 0x44, 0x65, 0xED, 0xCD, 0xB8, 0x3F, 0x58, + 0xFB, 0x8D, 0xB1, 0x57, 0xA9, 0x44, 0x2D, 0x05, 0x15, 0xF2, 0xEF, 0x0B, + 0xFF, 0x10, 0x74, 0x9F, 0xB5, 0x62, 0x52, 0x5F, 0x66, 0x7E, 0x1F, 0xE5, + 0xDC, 0x1B, 0x45, 0x79, 0x0B, 0xCC, 0xC6, 0x53, 0x0A, 0x9D, 0x8D, 0x5D, + 0x02, 0xD9, 0xA9, 0x59, 0xDE, 0x02, 0x5A, 0xF6, 0x95, 0x2A, 0x0E, 0x8D, + 0x38, 0x4A, 0x8A, 0x49, 0xC6, 0xBC, 0xC6, 0x03, 0x38, 0x07, 0x5F, 0x55, + 0xDA, 0x7E, 0x09, 0x6E, 0xE2, 0x7F, 0x5E, 0xD0, 0x45, 0x20, 0x0F, 0x59, + 0x76, 0x10, 0xD6, 0xA0, 0x24, 0xF0, 0x2D, 0xDE, 0x36, 0xF2, 0x6C, 0x29, + 0x39 +}; + +static const unsigned char TA292_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA292_RSA_N[] = { + 0xE2, 0x3B, 0xE1, 0x11, 0x72, 0xDE, 0xA8, 0xA4, 0xD3, 0xA3, 0x57, 0xAA, + 0x50, 0xA2, 0x8F, 0x0B, 0x77, 0x90, 0xC9, 0xA2, 0xA5, 0xEE, 0x12, 0xCE, + 0x96, 0x5B, 0x01, 0x09, 0x20, 0xCC, 0x01, 0x93, 0xA7, 0x4E, 0x30, 0xB7, + 0x53, 0xF7, 0x43, 0xC4, 0x69, 0x00, 0x57, 0x9D, 0xE2, 0x8D, 0x22, 0xDD, + 0x87, 0x06, 0x40, 0x00, 0x81, 0x09, 0xCE, 0xCE, 0x1B, 0x83, 0xBF, 0xDF, + 0xCD, 0x3B, 0x71, 0x46, 0xE2, 0xD6, 0x66, 0xC7, 0x05, 0xB3, 0x76, 0x27, + 0x16, 0x8F, 0x7B, 0x9E, 0x1E, 0x95, 0x7D, 0xEE, 0xB7, 0x48, 0xA3, 0x08, + 0xDA, 0xD6, 0xAF, 0x7A, 0x0C, 0x39, 0x06, 0x65, 0x7F, 0x4A, 0x5D, 0x1F, + 0xBC, 0x17, 0xF8, 0xAB, 0xBE, 0xEE, 0x28, 0xD7, 0x74, 0x7F, 0x7A, 0x78, + 0x99, 0x59, 0x85, 0x68, 0x6E, 0x5C, 0x23, 0x32, 0x4B, 0xBF, 0x4E, 0xC0, + 0xE8, 0x5A, 0x6D, 0xE3, 0x70, 0xBF, 0x77, 0x10, 0xBF, 0xFC, 0x01, 0xF6, + 0x85, 0xD9, 0xA8, 0x44, 0x10, 0x58, 0x32, 0xA9, 0x75, 0x18, 0xD5, 0xD1, + 0xA2, 0xBE, 0x47, 0xE2, 0x27, 0x6A, 0xF4, 0x9A, 0x33, 0xF8, 0x49, 0x08, + 0x60, 0x8B, 0xD4, 0x5F, 0xB4, 0x3A, 0x84, 0xBF, 0xA1, 0xAA, 0x4A, 0x4C, + 0x7D, 0x3E, 0xCF, 0x4F, 0x5F, 0x6C, 0x76, 0x5E, 0xA0, 0x4B, 0x37, 0x91, + 0x9E, 0xDC, 0x22, 0xE6, 0x6D, 0xCE, 0x14, 0x1A, 0x8E, 0x6A, 0xCB, 0xFE, + 0xCD, 0xB3, 0x14, 0x64, 0x17, 0xC7, 0x5B, 0x29, 0x9E, 0x32, 0xBF, 0xF2, + 0xEE, 0xFA, 0xD3, 0x0B, 0x42, 0xD4, 0xAB, 0xB7, 0x41, 0x32, 0xDA, 0x0C, + 0xD4, 0xEF, 0xF8, 0x81, 0xD5, 0xBB, 0x8D, 0x58, 0x3F, 0xB5, 0x1B, 0xE8, + 0x49, 0x28, 0xA2, 0x70, 0xDA, 0x31, 0x04, 0xDD, 0xF7, 0xB2, 0x16, 0xF2, + 0x4C, 0x0A, 0x4E, 0x07, 0xA8, 0xED, 0x4A, 0x3D, 0x5E, 0xB5, 0x7F, 0xA3, + 0x90, 0xC3, 0xAF, 0x27 +}; + +static const unsigned char TA292_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA293_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x32 +}; + +static const unsigned char TA293_RSA_N[] = { + 0xBB, 0x37, 0xCD, 0x34, 0xDC, 0x7B, 0x6B, 0xC9, 0xB2, 0x68, 0x90, 0xAD, + 0x4A, 0x75, 0xFF, 0x46, 0xBA, 0x21, 0x0A, 0x08, 0x8D, 0xF5, 0x19, 0x54, + 0xC9, 0xFB, 0x88, 0xDB, 0xF3, 0xAE, 0xF2, 0x3A, 0x89, 0x91, 0x3C, 0x7A, + 0xE6, 0xAB, 0x06, 0x1A, 0x6B, 0xCF, 0xAC, 0x2D, 0xE8, 0x5E, 0x09, 0x24, + 0x44, 0xBA, 0x62, 0x9A, 0x7E, 0xD6, 0xA3, 0xA8, 0x7E, 0xE0, 0x54, 0x75, + 0x20, 0x05, 0xAC, 0x50, 0xB7, 0x9C, 0x63, 0x1A, 0x6C, 0x30, 0xDC, 0xDA, + 0x1F, 0x19, 0xB1, 0xD7, 0x1E, 0xDE, 0xFD, 0xD7, 0xE0, 0xCB, 0x94, 0x83, + 0x37, 0xAE, 0xEC, 0x1F, 0x43, 0x4E, 0xDD, 0x7B, 0x2C, 0xD2, 0xBD, 0x2E, + 0xA5, 0x2F, 0xE4, 0xA9, 0xB8, 0xAD, 0x3A, 0xD4, 0x99, 0xA4, 0xB6, 0x25, + 0xE9, 0x9B, 0x6B, 0x00, 0x60, 0x92, 0x60, 0xFF, 0x4F, 0x21, 0x49, 0x18, + 0xF7, 0x67, 0x90, 0xAB, 0x61, 0x06, 0x9C, 0x8F, 0xF2, 0xBA, 0xE9, 0xB4, + 0xE9, 0x92, 0x32, 0x6B, 0xB5, 0xF3, 0x57, 0xE8, 0x5D, 0x1B, 0xCD, 0x8C, + 0x1D, 0xAB, 0x95, 0x04, 0x95, 0x49, 0xF3, 0x35, 0x2D, 0x96, 0xE3, 0x49, + 0x6D, 0xDD, 0x77, 0xE3, 0xFB, 0x49, 0x4B, 0xB4, 0xAC, 0x55, 0x07, 0xA9, + 0x8F, 0x95, 0xB3, 0xB4, 0x23, 0xBB, 0x4C, 0x6D, 0x45, 0xF0, 0xF6, 0xA9, + 0xB2, 0x95, 0x30, 0xB4, 0xFD, 0x4C, 0x55, 0x8C, 0x27, 0x4A, 0x57, 0x14, + 0x7C, 0x82, 0x9D, 0xCD, 0x73, 0x92, 0xD3, 0x16, 0x4A, 0x06, 0x0C, 0x8C, + 0x50, 0xD1, 0x8F, 0x1E, 0x09, 0xBE, 0x17, 0xA1, 0xE6, 0x21, 0xCA, 0xFD, + 0x83, 0xE5, 0x10, 0xBC, 0x83, 0xA5, 0x0A, 0xC4, 0x67, 0x28, 0xF6, 0x73, + 0x14, 0x14, 0x3D, 0x46, 0x76, 0xC3, 0x87, 0x14, 0x89, 0x21, 0x34, 0x4D, + 0xAF, 0x0F, 0x45, 0x0C, 0xA6, 0x49, 0xA1, 0xBA, 0xBB, 0x9C, 0xC5, 0xB1, + 0x33, 0x83, 0x29, 0x85 +}; + +static const unsigned char TA293_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA294_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x33 +}; + +static const unsigned char TA294_EC_Q[] = { + 0x04, 0xDD, 0xA7, 0xD9, 0xBB, 0x8A, 0xB8, 0x0B, 0xFB, 0x0B, 0x7F, 0x21, + 0xD2, 0xF0, 0xBE, 0xBE, 0x73, 0xF3, 0x33, 0x5D, 0x1A, 0xBC, 0x34, 0xEA, + 0xDE, 0xC6, 0x9B, 0xBC, 0xD0, 0x95, 0xF6, 0xF0, 0xCC, 0xD0, 0x0B, 0xBA, + 0x61, 0x5B, 0x51, 0x46, 0x7E, 0x9E, 0x2D, 0x9F, 0xEE, 0x8E, 0x63, 0x0C, + 0x17, 0xEC, 0x07, 0x70, 0xF5, 0xCF, 0x84, 0x2E, 0x40, 0x83, 0x9C, 0xE8, + 0x3F, 0x41, 0x6D, 0x3B, 0xAD, 0xD3, 0xA4, 0x14, 0x59, 0x36, 0x78, 0x9D, + 0x03, 0x43, 0xEE, 0x10, 0x13, 0x6C, 0x72, 0xDE, 0xAE, 0x88, 0xA7, 0xA1, + 0x6B, 0xB5, 0x43, 0xCE, 0x67, 0xDC, 0x23, 0xFF, 0x03, 0x1C, 0xA3, 0xE2, + 0x3E +}; + +static const unsigned char TA295_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, + 0x6E, 0x63, 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA295_RSA_N[] = { + 0xC6, 0xCC, 0xE5, 0x73, 0xE6, 0xFB, 0xD4, 0xBB, 0xE5, 0x2D, 0x2D, 0x32, + 0xA6, 0xDF, 0xE5, 0x81, 0x3F, 0xC9, 0xCD, 0x25, 0x49, 0xB6, 0x71, 0x2A, + 0xC3, 0xD5, 0x94, 0x34, 0x67, 0xA2, 0x0A, 0x1C, 0xB0, 0x5F, 0x69, 0xA6, + 0x40, 0xB1, 0xC4, 0xB7, 0xB2, 0x8F, 0xD0, 0x98, 0xA4, 0xA9, 0x41, 0x59, + 0x3A, 0xD3, 0xDC, 0x94, 0xD6, 0x3C, 0xDB, 0x74, 0x38, 0xA4, 0x4A, 0xCC, + 0x4D, 0x25, 0x82, 0xF7, 0x4A, 0xA5, 0x53, 0x12, 0x38, 0xEE, 0xF3, 0x49, + 0x6D, 0x71, 0x91, 0x7E, 0x63, 0xB6, 0xAB, 0xA6, 0x5F, 0xC3, 0xA4, 0x84, + 0xF8, 0x4F, 0x62, 0x51, 0xBE, 0xF8, 0xC5, 0xEC, 0xDB, 0x38, 0x92, 0xE3, + 0x06, 0xE5, 0x08, 0x91, 0x0C, 0xC4, 0x28, 0x41, 0x55, 0xFB, 0xCB, 0x5A, + 0x89, 0x15, 0x7E, 0x71, 0xE8, 0x35, 0xBF, 0x4D, 0x72, 0x09, 0x3D, 0xBE, + 0x3A, 0x38, 0x50, 0x5B, 0x77, 0x31, 0x1B, 0x8D, 0xB3, 0xC7, 0x24, 0x45, + 0x9A, 0xA7, 0xAC, 0x6D, 0x00, 0x14, 0x5A, 0x04, 0xB7, 0xBA, 0x13, 0xEB, + 0x51, 0x0A, 0x98, 0x41, 0x41, 0x22, 0x4E, 0x65, 0x61, 0x87, 0x81, 0x41, + 0x50, 0xA6, 0x79, 0x5C, 0x89, 0xDE, 0x19, 0x4A, 0x57, 0xD5, 0x2E, 0xE6, + 0x5D, 0x1C, 0x53, 0x2C, 0x7E, 0x98, 0xCD, 0x1A, 0x06, 0x16, 0xA4, 0x68, + 0x73, 0xD0, 0x34, 0x04, 0x13, 0x5C, 0xA1, 0x71, 0xD3, 0x5A, 0x7C, 0x55, + 0xDB, 0x5E, 0x64, 0xE1, 0x37, 0x87, 0x30, 0x56, 0x04, 0xE5, 0x11, 0xB4, + 0x29, 0x80, 0x12, 0xF1, 0x79, 0x39, 0x88, 0xA2, 0x02, 0x11, 0x7C, 0x27, + 0x66, 0xB7, 0x88, 0xB7, 0x78, 0xF2, 0xCA, 0x0A, 0xA8, 0x38, 0xAB, 0x0A, + 0x64, 0xC2, 0xBF, 0x66, 0x5D, 0x95, 0x84, 0xC1, 0xA1, 0x25, 0x1E, 0x87, + 0x5D, 0x1A, 0x50, 0x0B, 0x20, 0x12, 0xCC, 0x41, 0xBB, 0x6E, 0x0B, 0x51, + 0x38, 0xB8, 0x4B, 0xCB +}; + +static const unsigned char TA295_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA296_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1D, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x50, 0x33, 0x38, 0x34, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA296_EC_Q[] = { + 0x04, 0xC1, 0x44, 0xA1, 0xCF, 0x11, 0x97, 0x50, 0x9A, 0xDE, 0x23, 0x82, + 0x35, 0x07, 0xCD, 0xD0, 0xCB, 0x18, 0x9D, 0xD2, 0xF1, 0x7F, 0x77, 0x35, + 0x4F, 0x3B, 0xDD, 0x94, 0x72, 0x52, 0xED, 0xC2, 0x3B, 0xF8, 0xEC, 0xFA, + 0x7B, 0x6B, 0x58, 0x20, 0xEC, 0x99, 0xAE, 0xC9, 0xFC, 0x68, 0xB3, 0x75, + 0xB9, 0xDB, 0x09, 0xEC, 0xC8, 0x13, 0xF5, 0x4E, 0xC6, 0x0A, 0x1D, 0x66, + 0x30, 0x4C, 0xBB, 0x1F, 0x47, 0x0A, 0x3C, 0x61, 0x10, 0x42, 0x29, 0x7C, + 0xA5, 0x08, 0x0E, 0xE0, 0x22, 0xE9, 0xD3, 0x35, 0x68, 0xCE, 0x9B, 0x63, + 0x9F, 0x84, 0xB5, 0x99, 0x4D, 0x58, 0xA0, 0x8E, 0xF5, 0x54, 0xE7, 0x95, + 0xC9 +}; + +static const unsigned char TA297_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x34, 0x30, 0x39, 0x36, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA297_RSA_N[] = { + 0xB3, 0xD0, 0xF4, 0xC9, 0x79, 0x11, 0x9D, 0xFD, 0xFC, 0x66, 0x81, 0xE7, + 0xCC, 0xD5, 0xE4, 0xBC, 0xEC, 0x81, 0x3E, 0x6A, 0x35, 0x8E, 0x2E, 0xB7, + 0xE7, 0xDE, 0xAF, 0xF9, 0x07, 0x4D, 0xCF, 0x30, 0x9D, 0xEA, 0x09, 0x0B, + 0x99, 0xBD, 0x6C, 0x57, 0xDA, 0x18, 0x4A, 0xB8, 0x78, 0xAC, 0x3A, 0x39, + 0xA8, 0xA6, 0x48, 0xAC, 0x2E, 0x72, 0xE5, 0xBD, 0xEB, 0xF1, 0x1A, 0xCD, + 0xE7, 0xA4, 0x03, 0xA9, 0x3F, 0x11, 0xB4, 0xD8, 0x2F, 0x89, 0x16, 0xFB, + 0x94, 0x01, 0x3D, 0xBB, 0x2F, 0xF8, 0x13, 0x05, 0xA1, 0x78, 0x1C, 0x8E, + 0x28, 0xE0, 0x45, 0xE0, 0x83, 0xF4, 0x59, 0x1B, 0x95, 0xB3, 0xAE, 0x7E, + 0x03, 0x45, 0xE5, 0xBE, 0xC2, 0x42, 0xFE, 0xEE, 0xF2, 0x3C, 0xB6, 0x85, + 0x13, 0x98, 0x32, 0x9D, 0x16, 0xA8, 0x29, 0xC2, 0x0B, 0x1C, 0x38, 0xDC, + 0x9F, 0x31, 0x77, 0x5C, 0xBF, 0x27, 0xA3, 0xFC, 0x27, 0xAC, 0xB7, 0x2B, + 0xBD, 0x74, 0x9B, 0x17, 0x2D, 0xF2, 0x81, 0xDA, 0x5D, 0xB0, 0xE1, 0x23, + 0x17, 0x3E, 0x88, 0x4A, 0x12, 0x23, 0xD0, 0xEA, 0xCF, 0x9D, 0xDE, 0x03, + 0x17, 0xB1, 0x42, 0x4A, 0xA0, 0x16, 0x4C, 0xA4, 0x6D, 0x93, 0xE9, 0x3F, + 0x3A, 0xEE, 0x3A, 0x7C, 0x9D, 0x58, 0x9D, 0xF4, 0x4E, 0x8F, 0xFC, 0x3B, + 0x23, 0xC8, 0x6D, 0xB8, 0xE2, 0x05, 0xDA, 0xCC, 0xEB, 0xEC, 0xC3, 0x31, + 0xF4, 0xD7, 0xA7, 0x29, 0x54, 0x80, 0xCF, 0x44, 0x5B, 0x4C, 0x6F, 0x30, + 0x9E, 0xF3, 0xCC, 0xDD, 0x1F, 0x94, 0x43, 0x9D, 0x4D, 0x7F, 0x70, 0x70, + 0x0D, 0xD4, 0x3A, 0xD1, 0x37, 0xF0, 0x6C, 0x9D, 0x9B, 0xC0, 0x14, 0x93, + 0x58, 0xEF, 0xCD, 0x41, 0x38, 0x75, 0xBC, 0x13, 0x03, 0x95, 0x7C, 0x7F, + 0xE3, 0x5C, 0xE9, 0xD5, 0x0D, 0xD5, 0xE2, 0x7C, 0x10, 0x62, 0xAA, 0x6B, + 0xF0, 0x3D, 0x76, 0xF3, 0x3F, 0xA3, 0xE8, 0xB0, 0xC1, 0xFD, 0xEF, 0xAA, + 0x57, 0x4D, 0xAC, 0x86, 0xA7, 0x18, 0xB4, 0x29, 0xC1, 0x2C, 0x0E, 0xBF, + 0x64, 0xBE, 0x29, 0x8C, 0xD8, 0x02, 0x2D, 0xCD, 0x5C, 0x2F, 0xF2, 0x7F, + 0xEF, 0x15, 0xF4, 0x0C, 0x15, 0xAC, 0x0A, 0xB0, 0xF1, 0xD3, 0x0D, 0x4F, + 0x6A, 0x4D, 0x77, 0x97, 0x01, 0xA0, 0xF1, 0x66, 0xB7, 0xB7, 0xCE, 0xEF, + 0xCE, 0xEC, 0xEC, 0xA5, 0x75, 0xCA, 0xAC, 0xE3, 0xE1, 0x63, 0xF7, 0xB8, + 0xA1, 0x04, 0xC8, 0xBC, 0x7B, 0x3F, 0x5D, 0x2D, 0x16, 0x22, 0x56, 0xED, + 0x48, 0x49, 0xFE, 0xA7, 0x2F, 0x79, 0x30, 0x25, 0x9B, 0xBA, 0x6B, 0x2D, + 0x3F, 0x9D, 0x3B, 0xC4, 0x17, 0xE7, 0x1D, 0x2E, 0xFB, 0xF2, 0xCF, 0xA6, + 0xFC, 0xE3, 0x14, 0x2C, 0x96, 0x98, 0x21, 0x8C, 0xB4, 0x91, 0xE9, 0x19, + 0x60, 0x83, 0xF2, 0x30, 0x2B, 0x06, 0x73, 0x50, 0xD5, 0x98, 0x3B, 0x06, + 0xE9, 0xC7, 0x8A, 0x0C, 0x60, 0x8C, 0x28, 0xF8, 0x52, 0x9B, 0x6E, 0xE1, + 0xF6, 0x4D, 0xBB, 0x06, 0x24, 0x9B, 0xD7, 0x2B, 0x26, 0x3F, 0xFD, 0x2A, + 0x2F, 0x71, 0xF5, 0xD6, 0x24, 0xBE, 0x7F, 0x31, 0x9E, 0x0F, 0x6D, 0xE8, + 0x8F, 0x4F, 0x4D, 0xA3, 0x3F, 0xFF, 0x35, 0xEA, 0xDF, 0x49, 0x5E, 0x41, + 0x8F, 0x86, 0xF9, 0xF1, 0x77, 0x79, 0x4B, 0x1B, 0xB4, 0xA3, 0x5E, 0x2F, + 0xFB, 0x46, 0x02, 0xD0, 0x66, 0x13, 0x5E, 0x5E, 0x85, 0x4F, 0xCE, 0xD8, + 0x70, 0x88, 0x7B, 0xCE, 0x01, 0xB5, 0x96, 0x97, 0xD7, 0xCD, 0x7D, 0xFD, + 0x82, 0xF8, 0xC2, 0x24, 0xC1, 0xCA, 0x01, 0x39, 0x4F, 0x8D, 0xA2, 0xC1, + 0x14, 0x40, 0x1F, 0x9C, 0x66, 0xD5, 0x0C, 0x09, 0x46, 0xD6, 0xF2, 0xD0, + 0xD1, 0x48, 0x76, 0x56, 0x3A, 0x43, 0xCB, 0xB6, 0x0A, 0x11, 0x39, 0xBA, + 0x8C, 0x13, 0x6C, 0x06, 0xB5, 0x9E, 0xCF, 0xEB +}; + +static const unsigned char TA297_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA298_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x18, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA298_RSA_N[] = { + 0xBF, 0xE6, 0x90, 0x73, 0x68, 0xDE, 0xBB, 0xE4, 0x5D, 0x4A, 0x3C, 0x30, + 0x22, 0x30, 0x69, 0x33, 0xEC, 0xC2, 0xA7, 0x25, 0x2E, 0xC9, 0x21, 0x3D, + 0xF2, 0x8A, 0xD8, 0x59, 0xC2, 0xE1, 0x29, 0xA7, 0x3D, 0x58, 0xAB, 0x76, + 0x9A, 0xCD, 0xAE, 0x7B, 0x1B, 0x84, 0x0D, 0xC4, 0x30, 0x1F, 0xF3, 0x1B, + 0xA4, 0x38, 0x16, 0xEB, 0x56, 0xC6, 0x97, 0x6D, 0x1D, 0xAB, 0xB2, 0x79, + 0xF2, 0xCA, 0x11, 0xD2, 0xE4, 0x5F, 0xD6, 0x05, 0x3C, 0x52, 0x0F, 0x52, + 0x1F, 0xC6, 0x9E, 0x15, 0xA5, 0x7E, 0xBE, 0x9F, 0xA9, 0x57, 0x16, 0x59, + 0x55, 0x72, 0xAF, 0x68, 0x93, 0x70, 0xC2, 0xB2, 0xBA, 0x75, 0x99, 0x6A, + 0x73, 0x32, 0x94, 0xD1, 0x10, 0x44, 0x10, 0x2E, 0xDF, 0x82, 0xF3, 0x07, + 0x84, 0xE6, 0x74, 0x3B, 0x6D, 0x71, 0xE2, 0x2D, 0x0C, 0x1B, 0xEE, 0x20, + 0xD5, 0xC9, 0x20, 0x1D, 0x63, 0x29, 0x2D, 0xCE, 0xEC, 0x5E, 0x4E, 0xC8, + 0x93, 0xF8, 0x21, 0x61, 0x9B, 0x34, 0xEB, 0x05, 0xC6, 0x5E, 0xEC, 0x5B, + 0x1A, 0xBC, 0xEB, 0xC9, 0xCF, 0xCD, 0xAC, 0x34, 0x40, 0x5F, 0xB1, 0x7A, + 0x66, 0xEE, 0x77, 0xC8, 0x48, 0xA8, 0x66, 0x57, 0x57, 0x9F, 0x54, 0x58, + 0x8E, 0x0C, 0x2B, 0xB7, 0x4F, 0xA7, 0x30, 0xD9, 0x56, 0xEE, 0xCA, 0x7B, + 0x5D, 0xE3, 0xAD, 0xC9, 0x4F, 0x5E, 0xE5, 0x35, 0xE7, 0x31, 0xCB, 0xDA, + 0x93, 0x5E, 0xDC, 0x8E, 0x8F, 0x80, 0xDA, 0xB6, 0x91, 0x98, 0x40, 0x90, + 0x79, 0xC3, 0x78, 0xC7, 0xB6, 0xB1, 0xC4, 0xB5, 0x6A, 0x18, 0x38, 0x03, + 0x10, 0x8D, 0xD8, 0xD4, 0x37, 0xA4, 0x2E, 0x05, 0x7D, 0x88, 0xF5, 0x82, + 0x3E, 0x10, 0x91, 0x70, 0xAB, 0x55, 0x82, 0x41, 0x32, 0xD7, 0xDB, 0x04, + 0x73, 0x2A, 0x6E, 0x91, 0x01, 0x7C, 0x21, 0x4C, 0xD4, 0xBC, 0xAE, 0x1B, + 0x03, 0x75, 0x5D, 0x78, 0x66, 0xD9, 0x3A, 0x31, 0x44, 0x9A, 0x33, 0x40, + 0xBF, 0x08, 0xD7, 0x5A, 0x49, 0xA4, 0xC2, 0xE6, 0xA9, 0xA0, 0x67, 0xDD, + 0xA4, 0x27, 0xBC, 0xA1, 0x4F, 0x39, 0xB5, 0x11, 0x58, 0x17, 0xF7, 0x24, + 0x5C, 0x46, 0x8F, 0x64, 0xF7, 0xC1, 0x69, 0x88, 0x76, 0x98, 0x76, 0x3D, + 0x59, 0x5D, 0x42, 0x76, 0x87, 0x89, 0x97, 0x69, 0x7A, 0x48, 0xF0, 0xE0, + 0xA2, 0x12, 0x1B, 0x66, 0x9A, 0x74, 0xCA, 0xDE, 0x4B, 0x1E, 0xE7, 0x0E, + 0x63, 0xAE, 0xE6, 0xD4, 0xEF, 0x92, 0x92, 0x3A, 0x9E, 0x3D, 0xDC, 0x00, + 0xE4, 0x45, 0x25, 0x89, 0xB6, 0x9A, 0x44, 0x19, 0x2B, 0x7E, 0xC0, 0x94, + 0xB4, 0xD2, 0x61, 0x6D, 0xEB, 0x33, 0xD9, 0xC5, 0xDF, 0x4B, 0x04, 0x00, + 0xCC, 0x7D, 0x1C, 0x95, 0xC3, 0x8F, 0xF7, 0x21, 0xB2, 0xB2, 0x11, 0xB7, + 0xBB, 0x7F, 0xF2, 0xD5, 0x8C, 0x70, 0x2C, 0x41, 0x60, 0xAA, 0xB1, 0x63, + 0x18, 0x44, 0x95, 0x1A, 0x76, 0x62, 0x7E, 0xF6, 0x80, 0xB0, 0xFB, 0xE8, + 0x64, 0xA6, 0x33, 0xD1, 0x89, 0x07, 0xE1, 0xBD, 0xB7, 0xE6, 0x43, 0xA4, + 0x18, 0xB8, 0xA6, 0x77, 0x01, 0xE1, 0x0F, 0x94, 0x0C, 0x21, 0x1D, 0xB2, + 0x54, 0x29, 0x25, 0x89, 0x6C, 0xE5, 0x0E, 0x52, 0x51, 0x47, 0x74, 0xBE, + 0x26, 0xAC, 0xB6, 0x41, 0x75, 0xDE, 0x7A, 0xAC, 0x5F, 0x8D, 0x3F, 0xC9, + 0xBC, 0xD3, 0x41, 0x11, 0x12, 0x5B, 0xE5, 0x10, 0x50, 0xEB, 0x31, 0xC5, + 0xCA, 0x72, 0x16, 0x22, 0x09, 0xDF, 0x7C, 0x4C, 0x75, 0x3F, 0x63, 0xEC, + 0x21, 0x5F, 0xC4, 0x20, 0x51, 0x6B, 0x6F, 0xB1, 0xAB, 0x86, 0x8B, 0x4F, + 0xC2, 0xD6, 0x45, 0x5F, 0x9D, 0x20, 0xFC, 0xA1, 0x1E, 0xC5, 0xC0, 0x8F, + 0xA2, 0xB1, 0x7E, 0x0A, 0x26, 0x99, 0xF5, 0xE4, 0x69, 0x2F, 0x98, 0x1D, + 0x2D, 0xF5, 0xD9, 0xA9, 0xB2, 0x1D, 0xE5, 0x1B +}; + +static const unsigned char TA298_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA299_DN[] = { + 0x30, 0x81, 0xB4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, + 0x74, 0x31, 0x40, 0x30, 0x3E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x14, 0x37, + 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, + 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x5F, 0x32, 0x30, 0x34, 0x38, + 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x2E, 0x20, 0x62, 0x79, 0x20, + 0x72, 0x65, 0x66, 0x2E, 0x20, 0x28, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x73, + 0x20, 0x6C, 0x69, 0x61, 0x62, 0x2E, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1C, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, + 0x65, 0x74, 0x20, 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, + 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, + 0x34, 0x38, 0x29 +}; + +static const unsigned char TA299_RSA_N[] = { + 0xAD, 0x4D, 0x4B, 0xA9, 0x12, 0x86, 0xB2, 0xEA, 0xA3, 0x20, 0x07, 0x15, + 0x16, 0x64, 0x2A, 0x2B, 0x4B, 0xD1, 0xBF, 0x0B, 0x4A, 0x4D, 0x8E, 0xED, + 0x80, 0x76, 0xA5, 0x67, 0xB7, 0x78, 0x40, 0xC0, 0x73, 0x42, 0xC8, 0x68, + 0xC0, 0xDB, 0x53, 0x2B, 0xDD, 0x5E, 0xB8, 0x76, 0x98, 0x35, 0x93, 0x8B, + 0x1A, 0x9D, 0x7C, 0x13, 0x3A, 0x0E, 0x1F, 0x5B, 0xB7, 0x1E, 0xCF, 0xE5, + 0x24, 0x14, 0x1E, 0xB1, 0x81, 0xA9, 0x8D, 0x7D, 0xB8, 0xCC, 0x6B, 0x4B, + 0x03, 0xF1, 0x02, 0x0C, 0xDC, 0xAB, 0xA5, 0x40, 0x24, 0x00, 0x7F, 0x74, + 0x94, 0xA1, 0x9D, 0x08, 0x29, 0xB3, 0x88, 0x0B, 0xF5, 0x87, 0x77, 0x9D, + 0x55, 0xCD, 0xE4, 0xC3, 0x7E, 0xD7, 0x6A, 0x64, 0xAB, 0x85, 0x14, 0x86, + 0x95, 0x5B, 0x97, 0x32, 0x50, 0x6F, 0x3D, 0xC8, 0xBA, 0x66, 0x0C, 0xE3, + 0xFC, 0xBD, 0xB8, 0x49, 0xC1, 0x76, 0x89, 0x49, 0x19, 0xFD, 0xC0, 0xA8, + 0xBD, 0x89, 0xA3, 0x67, 0x2F, 0xC6, 0x9F, 0xBC, 0x71, 0x19, 0x60, 0xB8, + 0x2D, 0xE9, 0x2C, 0xC9, 0x90, 0x76, 0x66, 0x7B, 0x94, 0xE2, 0xAF, 0x78, + 0xD6, 0x65, 0x53, 0x5D, 0x3C, 0xD6, 0x9C, 0xB2, 0xCF, 0x29, 0x03, 0xF9, + 0x2F, 0xA4, 0x50, 0xB2, 0xD4, 0x48, 0xCE, 0x05, 0x32, 0x55, 0x8A, 0xFD, + 0xB2, 0x64, 0x4C, 0x0E, 0xE4, 0x98, 0x07, 0x75, 0xDB, 0x7F, 0xDF, 0xB9, + 0x08, 0x55, 0x60, 0x85, 0x30, 0x29, 0xF9, 0x7B, 0x48, 0xA4, 0x69, 0x86, + 0xE3, 0x35, 0x3F, 0x1E, 0x86, 0x5D, 0x7A, 0x7A, 0x15, 0xBD, 0xEF, 0x00, + 0x8E, 0x15, 0x22, 0x54, 0x17, 0x00, 0x90, 0x26, 0x93, 0xBC, 0x0E, 0x49, + 0x68, 0x91, 0xBF, 0xF8, 0x47, 0xD3, 0x9D, 0x95, 0x42, 0xC1, 0x0E, 0x4D, + 0xDF, 0x6F, 0x26, 0xCF, 0xC3, 0x18, 0x21, 0x62, 0x66, 0x43, 0x70, 0xD6, + 0xD5, 0xC0, 0x07, 0xE1 +}; + +static const unsigned char TA299_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA300_DN[] = { + 0x30, 0x81, 0xB0, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x30, 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x20, 0x69, + 0x73, 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6E, 0x63, 0x65, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x16, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, + 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA300_RSA_N[] = { + 0xB6, 0x95, 0xB6, 0x43, 0x42, 0xFA, 0xC6, 0x6D, 0x2A, 0x6F, 0x48, 0xDF, + 0x94, 0x4C, 0x39, 0x57, 0x05, 0xEE, 0xC3, 0x79, 0x11, 0x41, 0x68, 0x36, + 0xED, 0xEC, 0xFE, 0x9A, 0x01, 0x8F, 0xA1, 0x38, 0x28, 0xFC, 0xF7, 0x10, + 0x46, 0x66, 0x2E, 0x4D, 0x1E, 0x1A, 0xB1, 0x1A, 0x4E, 0xC6, 0xD1, 0xC0, + 0x95, 0x88, 0xB0, 0xC9, 0xFF, 0x31, 0x8B, 0x33, 0x03, 0xDB, 0xB7, 0x83, + 0x7B, 0x3E, 0x20, 0x84, 0x5E, 0xED, 0xB2, 0x56, 0x28, 0xA7, 0xF8, 0xE0, + 0xB9, 0x40, 0x71, 0x37, 0xC5, 0xCB, 0x47, 0x0E, 0x97, 0x2A, 0x68, 0xC0, + 0x22, 0x95, 0x62, 0x15, 0xDB, 0x47, 0xD9, 0xF5, 0xD0, 0x2B, 0xFF, 0x82, + 0x4B, 0xC9, 0xAD, 0x3E, 0xDE, 0x4C, 0xDB, 0x90, 0x80, 0x50, 0x3F, 0x09, + 0x8A, 0x84, 0x00, 0xEC, 0x30, 0x0A, 0x3D, 0x18, 0xCD, 0xFB, 0xFD, 0x2A, + 0x59, 0x9A, 0x23, 0x95, 0x17, 0x2C, 0x45, 0x9E, 0x1F, 0x6E, 0x43, 0x79, + 0x6D, 0x0C, 0x5C, 0x98, 0xFE, 0x48, 0xA7, 0xC5, 0x23, 0x47, 0x5C, 0x5E, + 0xFD, 0x6E, 0xE7, 0x1E, 0xB4, 0xF6, 0x68, 0x45, 0xD1, 0x86, 0x83, 0x5B, + 0xA2, 0x8A, 0x8D, 0xB1, 0xE3, 0x29, 0x80, 0xFE, 0x25, 0x71, 0x88, 0xAD, + 0xBE, 0xBC, 0x8F, 0xAC, 0x52, 0x96, 0x4B, 0xAA, 0x51, 0x8D, 0xE4, 0x13, + 0x31, 0x19, 0xE8, 0x4E, 0x4D, 0x9F, 0xDB, 0xAC, 0xB3, 0x6A, 0xD5, 0xBC, + 0x39, 0x54, 0x71, 0xCA, 0x7A, 0x7A, 0x7F, 0x90, 0xDD, 0x7D, 0x1D, 0x80, + 0xD9, 0x81, 0xBB, 0x59, 0x26, 0xC2, 0x11, 0xFE, 0xE6, 0x93, 0xE2, 0xF7, + 0x80, 0xE4, 0x65, 0xFB, 0x34, 0x37, 0x0E, 0x29, 0x80, 0x70, 0x4D, 0xAF, + 0x38, 0x86, 0x2E, 0x9E, 0x7F, 0x57, 0xAF, 0x9E, 0x17, 0xAE, 0xEB, 0x1C, + 0xCB, 0x28, 0x21, 0x5F, 0xB6, 0x1C, 0xD8, 0xE7, 0xA2, 0x04, 0x22, 0xF9, + 0xD3, 0xDA, 0xD8, 0xCB +}; + +static const unsigned char TA300_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA301_DN[] = { + 0x30, 0x81, 0xBF, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x33, 0x30, + 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x45, + 0x43, 0x31 +}; + +static const unsigned char TA301_EC_Q[] = { + 0x04, 0x84, 0x13, 0xC9, 0xD0, 0xBA, 0x6D, 0x41, 0x7B, 0xE2, 0x6C, 0xD0, + 0xEB, 0x55, 0x5F, 0x66, 0x02, 0x1A, 0x24, 0xF4, 0x5B, 0x89, 0x69, 0x47, + 0xE3, 0xB8, 0xC2, 0x7D, 0xF1, 0xF2, 0x02, 0xC5, 0x9F, 0xA0, 0xF6, 0x5B, + 0xD5, 0x8B, 0x06, 0x19, 0x86, 0x4F, 0x53, 0x10, 0x6D, 0x07, 0x24, 0x27, + 0xA1, 0xA0, 0xF8, 0xD5, 0x47, 0x19, 0x61, 0x4C, 0x7D, 0xCA, 0x93, 0x27, + 0xEA, 0x74, 0x0C, 0xEF, 0x6F, 0x96, 0x09, 0xFE, 0x63, 0xEC, 0x70, 0x5D, + 0x36, 0xAD, 0x67, 0x77, 0xAE, 0xC9, 0x9D, 0x7C, 0x55, 0x44, 0x3A, 0xA2, + 0x63, 0x51, 0x1F, 0xF5, 0xE3, 0x62, 0xD4, 0xA9, 0x47, 0x07, 0x3E, 0xCC, + 0x20 +}; + +static const unsigned char TA302_DN[] = { + 0x30, 0x81, 0xBE, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x32, 0x30, + 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, + 0x32 +}; + +static const unsigned char TA302_RSA_N[] = { + 0xBA, 0x84, 0xB6, 0x72, 0xDB, 0x9E, 0x0C, 0x6B, 0xE2, 0x99, 0xE9, 0x30, + 0x01, 0xA7, 0x76, 0xEA, 0x32, 0xB8, 0x95, 0x41, 0x1A, 0xC9, 0xDA, 0x61, + 0x4E, 0x58, 0x72, 0xCF, 0xFE, 0xF6, 0x82, 0x79, 0xBF, 0x73, 0x61, 0x06, + 0x0A, 0xA5, 0x27, 0xD8, 0xB3, 0x5F, 0xD3, 0x45, 0x4E, 0x1C, 0x72, 0xD6, + 0x4E, 0x32, 0xF2, 0x72, 0x8A, 0x0F, 0xF7, 0x83, 0x19, 0xD0, 0x6A, 0x80, + 0x80, 0x00, 0x45, 0x1E, 0xB0, 0xC7, 0xE7, 0x9A, 0xBF, 0x12, 0x57, 0x27, + 0x1C, 0xA3, 0x68, 0x2F, 0x0A, 0x87, 0xBD, 0x6A, 0x6B, 0x0E, 0x5E, 0x65, + 0xF3, 0x1C, 0x77, 0xD5, 0xD4, 0x85, 0x8D, 0x70, 0x21, 0xB4, 0xB3, 0x32, + 0xE7, 0x8B, 0xA2, 0xD5, 0x86, 0x39, 0x02, 0xB1, 0xB8, 0xD2, 0x47, 0xCE, + 0xE4, 0xC9, 0x49, 0xC4, 0x3B, 0xA7, 0xDE, 0xFB, 0x54, 0x7D, 0x57, 0xBE, + 0xF0, 0xE8, 0x6E, 0xC2, 0x79, 0xB2, 0x3A, 0x0B, 0x55, 0xE2, 0x50, 0x98, + 0x16, 0x32, 0x13, 0x5C, 0x2F, 0x78, 0x56, 0xC1, 0xC2, 0x94, 0xB3, 0xF2, + 0x5A, 0xE4, 0x27, 0x9A, 0x9F, 0x24, 0xD7, 0xC6, 0xEC, 0xD0, 0x9B, 0x25, + 0x82, 0xE3, 0xCC, 0xC2, 0xC4, 0x45, 0xC5, 0x8C, 0x97, 0x7A, 0x06, 0x6B, + 0x2A, 0x11, 0x9F, 0xA9, 0x0A, 0x6E, 0x48, 0x3B, 0x6F, 0xDB, 0xD4, 0x11, + 0x19, 0x42, 0xF7, 0x8F, 0x07, 0xBF, 0xF5, 0x53, 0x5F, 0x9C, 0x3E, 0xF4, + 0x17, 0x2C, 0xE6, 0x69, 0xAC, 0x4E, 0x32, 0x4C, 0x62, 0x77, 0xEA, 0xB7, + 0xE8, 0xE5, 0xBB, 0x34, 0xBC, 0x19, 0x8B, 0xAE, 0x9C, 0x51, 0xE7, 0xB7, + 0x7E, 0xB5, 0x53, 0xB1, 0x33, 0x22, 0xE5, 0x6D, 0xCF, 0x70, 0x3C, 0x1A, + 0xFA, 0xE2, 0x9B, 0x67, 0xB6, 0x83, 0xF4, 0x8D, 0xA5, 0xAF, 0x62, 0x4C, + 0x4D, 0xE0, 0x58, 0xAC, 0x64, 0x34, 0x12, 0x03, 0xF8, 0xB6, 0x8D, 0x94, + 0x63, 0x24, 0xA4, 0x71 +}; + +static const unsigned char TA302_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA303_DN[] = { + 0x30, 0x6E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x13, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, 0x6F, 0x66, 0x65, + 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x53, 0x41, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0F, 0x56, 0x41, 0x54, 0x45, + 0x53, 0x2D, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x46, 0x49, + 0x52, 0x4D, 0x41, 0x50, 0x52, 0x4F, 0x46, 0x45, 0x53, 0x49, 0x4F, 0x4E, + 0x41, 0x4C, 0x20, 0x43, 0x41, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x2D, 0x41, + 0x20, 0x57, 0x45, 0x42 +}; + +static const unsigned char TA303_EC_Q[] = { + 0x04, 0x47, 0x53, 0xEA, 0x2C, 0x11, 0xA4, 0x77, 0xC7, 0x2A, 0xEA, 0xF3, + 0xD6, 0x5F, 0x7B, 0xD3, 0x04, 0x91, 0x5C, 0xFA, 0x88, 0xC6, 0x22, 0xB9, + 0x83, 0x10, 0x62, 0x77, 0x84, 0x33, 0x2D, 0xE9, 0x03, 0x88, 0xD4, 0xE0, + 0x33, 0xF7, 0xED, 0x77, 0x2C, 0x4A, 0x60, 0xEA, 0xE4, 0x6F, 0xAD, 0x6D, + 0xB4, 0xF8, 0x4C, 0x8A, 0xA4, 0xE4, 0x1F, 0xCA, 0xEA, 0x4F, 0x38, 0x4A, + 0x2E, 0x82, 0x73, 0x2B, 0xC7, 0x66, 0x9B, 0x0A, 0x8C, 0x40, 0x9C, 0x7C, + 0x8A, 0xF6, 0xF2, 0x39, 0x60, 0xB2, 0xDE, 0xCB, 0xEC, 0xB8, 0xE4, 0x6F, + 0xEA, 0x9B, 0x5D, 0xB7, 0x53, 0x90, 0x18, 0x32, 0x55, 0xC5, 0x20, 0xB7, + 0x94 +}; + +static const unsigned char TA304_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x29, 0x47, 0x55, 0x41, 0x4E, 0x47, 0x20, 0x44, 0x4F, 0x4E, 0x47, + 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, + 0x20, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x20, 0x43, + 0x4F, 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x47, 0x44, 0x43, 0x41, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x41, 0x55, 0x54, 0x48, 0x20, 0x52, 0x35, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA304_RSA_N[] = { + 0xD9, 0xA3, 0x16, 0xF0, 0xC8, 0x74, 0x74, 0x77, 0x9B, 0xEF, 0x33, 0x0D, + 0x3B, 0x06, 0x7E, 0x55, 0xFC, 0xB5, 0x60, 0x8F, 0x76, 0x86, 0x12, 0x42, + 0x7D, 0x56, 0x66, 0x3E, 0x88, 0x82, 0xED, 0x72, 0x63, 0x0E, 0x9E, 0x8B, + 0xDD, 0x34, 0x2C, 0x02, 0x51, 0x51, 0xC3, 0x19, 0xFD, 0x59, 0x54, 0x84, + 0xC9, 0xF1, 0x6B, 0xB3, 0x4C, 0xB0, 0xE9, 0xE8, 0x46, 0x5D, 0x38, 0xC6, + 0xA2, 0xA7, 0x2E, 0x11, 0x57, 0xBA, 0x82, 0x15, 0xA2, 0x9C, 0x8F, 0x6D, + 0xB0, 0x99, 0x4A, 0x0A, 0xF2, 0xEB, 0x89, 0x70, 0x63, 0x4E, 0x79, 0xC4, + 0xB7, 0x5B, 0xBD, 0xA2, 0x5D, 0xB1, 0xF2, 0x41, 0x02, 0x2B, 0xAD, 0xA9, + 0x3A, 0xA3, 0xEC, 0x79, 0x0A, 0xEC, 0x5F, 0x3A, 0xE3, 0xFD, 0xEF, 0x80, + 0x3C, 0xAD, 0x34, 0x9B, 0x1A, 0xAB, 0x88, 0x26, 0x7B, 0x56, 0xA2, 0x82, + 0x86, 0x1F, 0xEB, 0x35, 0x89, 0x83, 0x7F, 0x5F, 0xAE, 0x29, 0x4E, 0x3D, + 0xB6, 0x6E, 0xEC, 0xAE, 0xC1, 0xF0, 0x27, 0x9B, 0xAE, 0xE3, 0xF4, 0xEC, + 0xEF, 0xAE, 0x7F, 0xF7, 0x86, 0x3D, 0x72, 0x7A, 0xEB, 0xA5, 0xFB, 0x59, + 0x4E, 0xA7, 0xEB, 0x95, 0x8C, 0x22, 0x39, 0x79, 0xE1, 0x2D, 0x08, 0x8F, + 0xCC, 0xBC, 0x91, 0xB8, 0x41, 0xF7, 0x14, 0xC1, 0x23, 0xA9, 0xC3, 0xAD, + 0x9A, 0x45, 0x44, 0xB3, 0xB2, 0xD7, 0x2C, 0xCD, 0xC6, 0x29, 0xE2, 0x50, + 0x10, 0xAE, 0x5C, 0xCB, 0x82, 0x8E, 0x17, 0x18, 0x36, 0x7D, 0x97, 0xE6, + 0x88, 0x9A, 0xB0, 0x4D, 0x34, 0x09, 0xF4, 0x2C, 0xB9, 0x5A, 0x66, 0x2A, + 0xB0, 0x17, 0x9B, 0x9E, 0x1E, 0x76, 0x9D, 0x4A, 0x66, 0x31, 0x41, 0xDF, + 0x3F, 0xFB, 0xC5, 0x06, 0xEF, 0x1B, 0xB6, 0x7E, 0x1A, 0x46, 0x36, 0xF7, + 0x64, 0x63, 0x3B, 0xE3, 0x39, 0x18, 0x23, 0xE7, 0x67, 0x75, 0x14, 0xD5, + 0x75, 0x57, 0x92, 0x37, 0xBD, 0xBE, 0x6A, 0x1B, 0x26, 0x50, 0xF2, 0x36, + 0x26, 0x06, 0x90, 0xC5, 0x70, 0x01, 0x64, 0x6D, 0x76, 0x66, 0xE1, 0x91, + 0xDB, 0x6E, 0x07, 0xC0, 0x61, 0x80, 0x2E, 0xB2, 0x2E, 0x2F, 0x8C, 0x70, + 0xA7, 0xD1, 0x3B, 0x3C, 0xB3, 0x91, 0xE4, 0x6E, 0xB6, 0xC4, 0x3B, 0x70, + 0xF2, 0x6C, 0x92, 0x97, 0x09, 0xCD, 0x47, 0x7D, 0x18, 0xC0, 0xF3, 0xBB, + 0x9E, 0x0F, 0xD6, 0x8B, 0xAE, 0x07, 0xB6, 0x5A, 0x0F, 0xCE, 0x0B, 0x0C, + 0x47, 0xA7, 0xE5, 0x3E, 0xB8, 0xBD, 0x7D, 0xC7, 0x9B, 0x35, 0xA0, 0x61, + 0x97, 0x3A, 0x41, 0x75, 0x17, 0xCC, 0x2B, 0x96, 0x77, 0x2A, 0x92, 0x21, + 0x1E, 0xD9, 0x95, 0x76, 0x20, 0x67, 0x68, 0xCF, 0x0D, 0xBD, 0xDF, 0xD6, + 0x1F, 0x09, 0x6A, 0x9A, 0xE2, 0xCC, 0x73, 0x71, 0xA4, 0x2F, 0x7D, 0x12, + 0x80, 0xB7, 0x53, 0x30, 0x46, 0x5E, 0x4B, 0x54, 0x99, 0x0F, 0x67, 0xC9, + 0xA5, 0xC8, 0xF2, 0x20, 0xC1, 0x82, 0xEC, 0x9D, 0x11, 0xDF, 0xC2, 0x02, + 0xFB, 0x1A, 0x3B, 0xD1, 0xED, 0x20, 0x9A, 0xEF, 0x65, 0x64, 0x92, 0x10, + 0x0D, 0x2A, 0xE2, 0xDE, 0x70, 0xF1, 0x18, 0x67, 0x82, 0x8C, 0x61, 0xDE, + 0xB8, 0xBC, 0xD1, 0x2F, 0x9C, 0xFB, 0x0F, 0xD0, 0x2B, 0xED, 0x1B, 0x76, + 0xB9, 0xE4, 0x39, 0x55, 0xF8, 0xF8, 0xA1, 0x1D, 0xB8, 0xAA, 0x80, 0x00, + 0x4C, 0x82, 0xE7, 0xB2, 0x7F, 0x09, 0xB8, 0xBC, 0x30, 0xA0, 0x2F, 0x0D, + 0xF5, 0x52, 0x9E, 0x8E, 0xF7, 0x92, 0xB3, 0x0A, 0x00, 0x1D, 0x00, 0x54, + 0x97, 0x06, 0xE0, 0xB1, 0x07, 0xD9, 0xC7, 0x0F, 0x5C, 0x65, 0x7D, 0x3C, + 0x6D, 0x59, 0x57, 0xE4, 0xED, 0xA5, 0x8D, 0xE9, 0x40, 0x53, 0x9F, 0x15, + 0x4B, 0xA0, 0x71, 0xF6, 0x1A, 0x21, 0xE3, 0xDA, 0x70, 0x06, 0x21, 0x58, + 0x14, 0x87, 0x85, 0x77, 0x79, 0xAA, 0x82, 0x79 +}; + +static const unsigned char TA304_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA305_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x41, 0x54, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x65, 0x2D, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x65, + 0x20, 0x6D, 0x6F, 0x6E, 0x69, 0x74, 0x6F, 0x72, 0x69, 0x6E, 0x67, 0x20, + 0x47, 0x6D, 0x62, 0x48, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x10, 0x47, 0x4C, 0x4F, 0x42, 0x41, 0x4C, 0x54, 0x52, 0x55, + 0x53, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA305_RSA_N[] = { + 0xAE, 0x2E, 0x56, 0xAD, 0x1B, 0x1C, 0xEF, 0xF6, 0x95, 0x8F, 0xA0, 0x77, + 0x1B, 0x2B, 0xD3, 0x63, 0x8F, 0x84, 0x4D, 0x45, 0xA2, 0x0F, 0x9F, 0x5B, + 0x45, 0xAB, 0x59, 0x7B, 0x51, 0x34, 0xF9, 0xEC, 0x8B, 0x8A, 0x78, 0xC5, + 0xDD, 0x6B, 0xAF, 0xBD, 0xC4, 0xDF, 0x93, 0x45, 0x1E, 0xBF, 0x91, 0x38, + 0x0B, 0xAE, 0x0E, 0x16, 0xE7, 0x41, 0x73, 0xF8, 0xDB, 0xBB, 0xD1, 0xB8, + 0x51, 0xE0, 0xCB, 0x83, 0x3B, 0x73, 0x38, 0x6E, 0x77, 0x8A, 0x0F, 0x59, + 0x63, 0x26, 0xCD, 0xA7, 0x2A, 0xCE, 0x54, 0xFB, 0xB8, 0xE2, 0xC0, 0x7C, + 0x47, 0xCE, 0x60, 0x7C, 0x3F, 0xB2, 0x73, 0xF2, 0xC0, 0x19, 0xB6, 0x8A, + 0x92, 0x87, 0x35, 0x0D, 0x90, 0x28, 0xA2, 0xE4, 0x15, 0x04, 0x63, 0x3E, + 0xBA, 0xAF, 0xEE, 0x7C, 0x5E, 0xCC, 0xA6, 0x8B, 0x50, 0xB2, 0x38, 0xF7, + 0x41, 0x63, 0xCA, 0xCE, 0xFF, 0x69, 0x8F, 0x68, 0x0E, 0x95, 0x36, 0xE5, + 0xCC, 0xB9, 0x8C, 0x09, 0xCA, 0x4B, 0xDD, 0x31, 0x90, 0x96, 0xC8, 0xCC, + 0x1F, 0xFD, 0x56, 0x96, 0x34, 0xDB, 0x8E, 0x1C, 0xEA, 0x2C, 0xBE, 0x85, + 0x2E, 0x63, 0xDD, 0xAA, 0xA9, 0x95, 0xD3, 0xFD, 0x29, 0x95, 0x13, 0xF0, + 0xC8, 0x98, 0x93, 0xD9, 0x2D, 0x16, 0x47, 0x90, 0x11, 0x83, 0xA2, 0x3A, + 0x22, 0xA2, 0x28, 0x57, 0xA2, 0xEB, 0xFE, 0xC0, 0x8C, 0x28, 0xA0, 0xA6, + 0x7D, 0xE7, 0x2A, 0x42, 0x3B, 0x82, 0x80, 0x63, 0xA5, 0x63, 0x1F, 0x19, + 0xCC, 0x7C, 0xB2, 0x66, 0xA8, 0xC2, 0xD3, 0x6D, 0x37, 0x6F, 0xE2, 0x7E, + 0x06, 0x51, 0xD9, 0x45, 0x84, 0x1F, 0x12, 0xCE, 0x24, 0x52, 0x64, 0x85, + 0x0B, 0x48, 0x80, 0x4E, 0x87, 0xB1, 0x22, 0x22, 0x30, 0xAA, 0xEB, 0xAE, + 0xBE, 0xE0, 0x02, 0xE0, 0x40, 0xE8, 0xB0, 0x42, 0x80, 0x03, 0x51, 0xAA, + 0xB4, 0x7E, 0xAA, 0x44, 0xD7, 0x43, 0x61, 0xF3, 0xA2, 0x6B, 0x16, 0x89, + 0x49, 0xA4, 0xA3, 0xA4, 0x2B, 0x8A, 0x02, 0xC4, 0x78, 0xF4, 0x68, 0x8A, + 0xC1, 0xE4, 0x7A, 0x36, 0xB1, 0x6F, 0x1B, 0x96, 0x1B, 0x77, 0x49, 0x8D, + 0xD4, 0xC9, 0x06, 0x72, 0x8F, 0xCF, 0x53, 0xE3, 0xDC, 0x17, 0x85, 0x20, + 0x4A, 0xDC, 0x98, 0x27, 0xD3, 0x91, 0x26, 0x2B, 0x47, 0x1E, 0x69, 0x07, + 0xAF, 0xDE, 0xA2, 0xE4, 0xE4, 0xD4, 0x6B, 0x0B, 0xB3, 0x5E, 0x7C, 0xD4, + 0x24, 0x80, 0x47, 0x29, 0x69, 0x3B, 0x6E, 0xE8, 0xAC, 0xFD, 0x40, 0xEB, + 0xD8, 0xED, 0x71, 0x71, 0x2B, 0xF2, 0xE8, 0x58, 0x1D, 0xEB, 0x41, 0x97, + 0x22, 0xC5, 0x1F, 0xD4, 0x39, 0xD0, 0x27, 0x8F, 0x87, 0xE3, 0x18, 0xF4, + 0xE0, 0xA9, 0x46, 0x0D, 0xF5, 0x74, 0x3A, 0x82, 0x2E, 0xD0, 0x6E, 0x2C, + 0x91, 0xA3, 0x31, 0x5C, 0x3B, 0x46, 0xEA, 0x7B, 0x04, 0x10, 0x56, 0x5E, + 0x80, 0x1D, 0xF5, 0xA5, 0x65, 0xE8, 0x82, 0xFC, 0xE2, 0x07, 0x8C, 0x62, + 0x45, 0xF5, 0x20, 0xDE, 0x46, 0x70, 0x86, 0xA1, 0xBC, 0x93, 0xD3, 0x1E, + 0x74, 0xA6, 0x6C, 0xB0, 0x2C, 0xF7, 0x03, 0x0C, 0x88, 0x0C, 0xCB, 0xD4, + 0x72, 0x53, 0x86, 0xBC, 0x60, 0x46, 0xF3, 0x98, 0x6A, 0xC2, 0xF1, 0xBF, + 0x43, 0xF9, 0x70, 0x20, 0x77, 0xCA, 0x37, 0x41, 0x79, 0x55, 0x52, 0x63, + 0x8D, 0x5B, 0x12, 0x9F, 0xC5, 0x68, 0xC4, 0x88, 0x9D, 0xAC, 0xF2, 0x30, + 0xAB, 0xB7, 0xA3, 0x31, 0x97, 0x67, 0xAD, 0x8F, 0x17, 0x0F, 0x6C, 0xC7, + 0x73, 0xED, 0x24, 0x94, 0x6B, 0xC8, 0x83, 0x9A, 0xD0, 0x9A, 0x37, 0x49, + 0x04, 0xAB, 0xB1, 0x16, 0xC8, 0x6C, 0x49, 0x49, 0x2D, 0xAB, 0xA1, 0xD0, + 0x8C, 0x92, 0xF2, 0x41, 0x4A, 0x79, 0x21, 0x25, 0xDB, 0x63, 0xD7, 0xB6, + 0x9C, 0xA7, 0x7E, 0x42, 0x69, 0xFB, 0x3A, 0x63 +}; + +static const unsigned char TA305_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA306_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x31 +}; + +static const unsigned char TA306_RSA_N[] = { + 0xB6, 0x11, 0x02, 0x8B, 0x1E, 0xE3, 0xA1, 0x77, 0x9B, 0x3B, 0xDC, 0xBF, + 0x94, 0x3E, 0xB7, 0x95, 0xA7, 0x40, 0x3C, 0xA1, 0xFD, 0x82, 0xF9, 0x7D, + 0x32, 0x06, 0x82, 0x71, 0xF6, 0xF6, 0x8C, 0x7F, 0xFB, 0xE8, 0xDB, 0xBC, + 0x6A, 0x2E, 0x97, 0x97, 0xA3, 0x8C, 0x4B, 0xF9, 0x2B, 0xF6, 0xB1, 0xF9, + 0xCE, 0x84, 0x1D, 0xB1, 0xF9, 0xC5, 0x97, 0xDE, 0xEF, 0xB9, 0xF2, 0xA3, + 0xE9, 0xBC, 0x12, 0x89, 0x5E, 0xA7, 0xAA, 0x52, 0xAB, 0xF8, 0x23, 0x27, + 0xCB, 0xA4, 0xB1, 0x9C, 0x63, 0xDB, 0xD7, 0x99, 0x7E, 0xF0, 0x0A, 0x5E, + 0xEB, 0x68, 0xA6, 0xF4, 0xC6, 0x5A, 0x47, 0x0D, 0x4D, 0x10, 0x33, 0xE3, + 0x4E, 0xB1, 0x13, 0xA3, 0xC8, 0x18, 0x6C, 0x4B, 0xEC, 0xFC, 0x09, 0x90, + 0xDF, 0x9D, 0x64, 0x29, 0x25, 0x23, 0x07, 0xA1, 0xB4, 0xD2, 0x3D, 0x2E, + 0x60, 0xE0, 0xCF, 0xD2, 0x09, 0x87, 0xBB, 0xCD, 0x48, 0xF0, 0x4D, 0xC2, + 0xC2, 0x7A, 0x88, 0x8A, 0xBB, 0xBA, 0xCF, 0x59, 0x19, 0xD6, 0xAF, 0x8F, + 0xB0, 0x07, 0xB0, 0x9E, 0x31, 0xF1, 0x82, 0xC1, 0xC0, 0xDF, 0x2E, 0xA6, + 0x6D, 0x6C, 0x19, 0x0E, 0xB5, 0xD8, 0x7E, 0x26, 0x1A, 0x45, 0x03, 0x3D, + 0xB0, 0x79, 0xA4, 0x94, 0x28, 0xAD, 0x0F, 0x7F, 0x26, 0xE5, 0xA8, 0x08, + 0xFE, 0x96, 0xE8, 0x3C, 0x68, 0x94, 0x53, 0xEE, 0x83, 0x3A, 0x88, 0x2B, + 0x15, 0x96, 0x09, 0xB2, 0xE0, 0x7A, 0x8C, 0x2E, 0x75, 0xD6, 0x9C, 0xEB, + 0xA7, 0x56, 0x64, 0x8F, 0x96, 0x4F, 0x68, 0xAE, 0x3D, 0x97, 0xC2, 0x84, + 0x8F, 0xC0, 0xBC, 0x40, 0xC0, 0x0B, 0x5C, 0xBD, 0xF6, 0x87, 0xB3, 0x35, + 0x6C, 0xAC, 0x18, 0x50, 0x7F, 0x84, 0xE0, 0x4C, 0xCD, 0x92, 0xD3, 0x20, + 0xE9, 0x33, 0xBC, 0x52, 0x99, 0xAF, 0x32, 0xB5, 0x29, 0xB3, 0x25, 0x2A, + 0xB4, 0x48, 0xF9, 0x72, 0xE1, 0xCA, 0x64, 0xF7, 0xE6, 0x82, 0x10, 0x8D, + 0xE8, 0x9D, 0xC2, 0x8A, 0x88, 0xFA, 0x38, 0x66, 0x8A, 0xFC, 0x63, 0xF9, + 0x01, 0xF9, 0x78, 0xFD, 0x7B, 0x5C, 0x77, 0xFA, 0x76, 0x87, 0xFA, 0xEC, + 0xDF, 0xB1, 0x0E, 0x79, 0x95, 0x57, 0xB4, 0xBD, 0x26, 0xEF, 0xD6, 0x01, + 0xD1, 0xEB, 0x16, 0x0A, 0xBB, 0x8E, 0x0B, 0xB5, 0xC5, 0xC5, 0x8A, 0x55, + 0xAB, 0xD3, 0xAC, 0xEA, 0x91, 0x4B, 0x29, 0xCC, 0x19, 0xA4, 0x32, 0x25, + 0x4E, 0x2A, 0xF1, 0x65, 0x44, 0xD0, 0x02, 0xCE, 0xAA, 0xCE, 0x49, 0xB4, + 0xEA, 0x9F, 0x7C, 0x83, 0xB0, 0x40, 0x7B, 0xE7, 0x43, 0xAB, 0xA7, 0x6C, + 0xA3, 0x8F, 0x7D, 0x89, 0x81, 0xFA, 0x4C, 0xA5, 0xFF, 0xD5, 0x8E, 0xC3, + 0xCE, 0x4B, 0xE0, 0xB5, 0xD8, 0xB3, 0x8E, 0x45, 0xCF, 0x76, 0xC0, 0xED, + 0x40, 0x2B, 0xFD, 0x53, 0x0F, 0xB0, 0xA7, 0xD5, 0x3B, 0x0D, 0xB1, 0x8A, + 0xA2, 0x03, 0xDE, 0x31, 0xAD, 0xCC, 0x77, 0xEA, 0x6F, 0x7B, 0x3E, 0xD6, + 0xDF, 0x91, 0x22, 0x12, 0xE6, 0xBE, 0xFA, 0xD8, 0x32, 0xFC, 0x10, 0x63, + 0x14, 0x51, 0x72, 0xDE, 0x5D, 0xD6, 0x16, 0x93, 0xBD, 0x29, 0x68, 0x33, + 0xEF, 0x3A, 0x66, 0xEC, 0x07, 0x8A, 0x26, 0xDF, 0x13, 0xD7, 0x57, 0x65, + 0x78, 0x27, 0xDE, 0x5E, 0x49, 0x14, 0x00, 0xA2, 0x00, 0x7F, 0x9A, 0xA8, + 0x21, 0xB6, 0xA9, 0xB1, 0x95, 0xB0, 0xA5, 0xB9, 0x0D, 0x16, 0x11, 0xDA, + 0xC7, 0x6C, 0x48, 0x3C, 0x40, 0xE0, 0x7E, 0x0D, 0x5A, 0xCD, 0x56, 0x3C, + 0xD1, 0x97, 0x05, 0xB9, 0xCB, 0x4B, 0xED, 0x39, 0x4B, 0x9C, 0xC4, 0x3F, + 0xD2, 0x55, 0x13, 0x6E, 0x24, 0xB0, 0xD6, 0x71, 0xFA, 0xF4, 0xC1, 0xBA, + 0xCC, 0xED, 0x1B, 0xF5, 0xFE, 0x81, 0x41, 0xD8, 0x00, 0x98, 0x3D, 0x3A, + 0xC8, 0xAE, 0x7A, 0x98, 0x37, 0x18, 0x05, 0x95 +}; + +static const unsigned char TA306_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA307_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA307_RSA_N[] = { + 0xCE, 0xDE, 0xFD, 0xA6, 0xFB, 0xEC, 0xEC, 0x14, 0x34, 0x3C, 0x07, 0x06, + 0x5A, 0x6C, 0x59, 0xF7, 0x19, 0x35, 0xDD, 0xF7, 0xC1, 0x9D, 0x55, 0xAA, + 0xD3, 0xCD, 0x3B, 0xA4, 0x93, 0x72, 0xEF, 0x0A, 0xFA, 0x6D, 0x9D, 0xF6, + 0xF0, 0x85, 0x80, 0x5B, 0xA1, 0x48, 0x52, 0x9F, 0x39, 0xC5, 0xB7, 0xEE, + 0x28, 0xAC, 0xEF, 0xCB, 0x76, 0x68, 0x14, 0xB9, 0xDF, 0xAD, 0x01, 0x6C, + 0x99, 0x1F, 0xC4, 0x22, 0x1D, 0x9F, 0xFE, 0x72, 0x77, 0xE0, 0x2C, 0x5B, + 0xAF, 0xE4, 0x04, 0xBF, 0x4F, 0x72, 0xA0, 0x1A, 0x34, 0x98, 0xE8, 0x39, + 0x68, 0xEC, 0x95, 0x25, 0x7B, 0x76, 0xA1, 0xE6, 0x69, 0xB9, 0x85, 0x19, + 0xBD, 0x89, 0x8C, 0xFE, 0xAD, 0xED, 0x36, 0xEA, 0x73, 0xBC, 0xFF, 0x83, + 0xE2, 0xCB, 0x7D, 0xC1, 0xD2, 0xCE, 0x4A, 0xB3, 0x8D, 0x05, 0x9E, 0x8B, + 0x49, 0x93, 0xDF, 0xC1, 0x5B, 0xD0, 0x6E, 0x5E, 0xF0, 0x2E, 0x30, 0x2E, + 0x82, 0xFC, 0xFA, 0xBC, 0xB4, 0x17, 0x0A, 0x48, 0xE5, 0x88, 0x9B, 0xC5, + 0x9B, 0x6B, 0xDE, 0xB0, 0xCA, 0xB4, 0x03, 0xF0, 0xDA, 0xF4, 0x90, 0xB8, + 0x65, 0x64, 0xF7, 0x5C, 0x4C, 0xAD, 0xE8, 0x7E, 0x66, 0x5E, 0x99, 0xD7, + 0xB8, 0xC2, 0x3E, 0xC8, 0xD0, 0x13, 0x9D, 0xAD, 0xEE, 0xE4, 0x45, 0x7B, + 0x89, 0x55, 0xF7, 0x8A, 0x1F, 0x62, 0x52, 0x84, 0x12, 0xB3, 0xC2, 0x40, + 0x97, 0xE3, 0x8A, 0x1F, 0x47, 0x91, 0xA6, 0x74, 0x5A, 0xD2, 0xF8, 0xB1, + 0x63, 0x28, 0x10, 0xB8, 0xB3, 0x09, 0xB8, 0x56, 0x77, 0x40, 0xA2, 0x26, + 0x98, 0x79, 0xC6, 0xFE, 0xDF, 0x25, 0xEE, 0x3E, 0xE5, 0xA0, 0x7F, 0xD4, + 0x61, 0x0F, 0x51, 0x4B, 0x3C, 0x3F, 0x8C, 0xDA, 0xE1, 0x70, 0x74, 0xD8, + 0xC2, 0x68, 0xA1, 0xF9, 0xC1, 0x0C, 0xE9, 0xA1, 0xE2, 0x7F, 0xBB, 0x55, + 0x3C, 0x76, 0x06, 0xEE, 0x6A, 0x4E, 0xCC, 0x92, 0x88, 0x30, 0x4D, 0x9A, + 0xBD, 0x4F, 0x0B, 0x48, 0x9A, 0x84, 0xB5, 0x98, 0xA3, 0xD5, 0xFB, 0x73, + 0xC1, 0x57, 0x61, 0xDD, 0x28, 0x56, 0x75, 0x13, 0xAE, 0x87, 0x8E, 0xE7, + 0x0C, 0x51, 0x09, 0x10, 0x75, 0x88, 0x4C, 0xBC, 0x8D, 0xF9, 0x7B, 0x3C, + 0xD4, 0x22, 0x48, 0x1F, 0x2A, 0xDC, 0xEB, 0x6B, 0xBB, 0x44, 0xB1, 0xCB, + 0x33, 0x71, 0x32, 0x46, 0xAF, 0xAD, 0x4A, 0xF1, 0x8C, 0xE8, 0x74, 0x3A, + 0xAC, 0xE7, 0x1A, 0x22, 0x73, 0x80, 0xD2, 0x30, 0xF7, 0x25, 0x42, 0xC7, + 0x22, 0x3B, 0x3B, 0x12, 0xAD, 0x96, 0x2E, 0xC6, 0xC3, 0x76, 0x07, 0xAA, + 0x20, 0xB7, 0x35, 0x49, 0x57, 0xE9, 0x92, 0x49, 0xE8, 0x76, 0x16, 0x72, + 0x31, 0x67, 0x2B, 0x96, 0x7E, 0x8A, 0xA3, 0xC7, 0x94, 0x56, 0x22, 0xBF, + 0x6A, 0x4B, 0x7E, 0x01, 0x21, 0xB2, 0x23, 0x32, 0xDF, 0xE4, 0x9A, 0x44, + 0x6D, 0x59, 0x5B, 0x5D, 0xF5, 0x00, 0xA0, 0x1C, 0x9B, 0xC6, 0x78, 0x97, + 0x8D, 0x90, 0xFF, 0x9B, 0xC8, 0xAA, 0xB4, 0xAF, 0x11, 0x51, 0x39, 0x5E, + 0xD9, 0xFB, 0x67, 0xAD, 0xD5, 0x5B, 0x11, 0x9D, 0x32, 0x9A, 0x1B, 0xBD, + 0xD5, 0xBA, 0x5B, 0xA5, 0xC9, 0xCB, 0x25, 0x69, 0x53, 0x55, 0x27, 0x5C, + 0xE0, 0xCA, 0x36, 0xCB, 0x88, 0x61, 0xFB, 0x1E, 0xB7, 0xD0, 0xCB, 0xEE, + 0x16, 0xFB, 0xD3, 0xA6, 0x4C, 0xDE, 0x92, 0xA5, 0xD4, 0xE2, 0xDF, 0xF5, + 0x06, 0x54, 0xDE, 0x2E, 0x9D, 0x4B, 0xB4, 0x93, 0x30, 0xAA, 0x81, 0xCE, + 0xDD, 0x1A, 0xDC, 0x51, 0x73, 0x0D, 0x4F, 0x70, 0xE9, 0xE5, 0xB6, 0x16, + 0x21, 0x19, 0x79, 0xB2, 0xE6, 0x89, 0x0B, 0x75, 0x64, 0xCA, 0xD5, 0xAB, + 0xBC, 0x09, 0xC1, 0x18, 0xA1, 0xFF, 0xD4, 0x54, 0xA1, 0x85, 0x3C, 0xFD, + 0x14, 0x24, 0x03, 0xB2, 0x87, 0xD3, 0xA4, 0xB7 +}; + +static const unsigned char TA307_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA308_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x33 +}; + +static const unsigned char TA308_EC_Q[] = { + 0x04, 0x1F, 0x4F, 0x33, 0x87, 0x33, 0x29, 0x8A, 0xA1, 0x84, 0xDE, 0xCB, + 0xC7, 0x21, 0x58, 0x41, 0x89, 0xEA, 0x56, 0x9D, 0x2B, 0x4B, 0x85, 0xC6, + 0x1D, 0x4C, 0x27, 0xBC, 0x7F, 0x26, 0x51, 0x72, 0x6F, 0xE2, 0x9F, 0xD6, + 0xA3, 0xCA, 0xCC, 0x45, 0x14, 0x46, 0x8B, 0xAD, 0xEF, 0x7E, 0x86, 0x8C, + 0xEC, 0xB1, 0x7E, 0x2F, 0xFF, 0xA9, 0x71, 0x9D, 0x18, 0x84, 0x45, 0x04, + 0x41, 0x55, 0x6E, 0x2B, 0xEA, 0x26, 0x7F, 0xBB, 0x90, 0x01, 0xE3, 0x4B, + 0x19, 0xBA, 0xE4, 0x54, 0x96, 0x45, 0x09, 0xB1, 0xD5, 0x6C, 0x91, 0x44, + 0xAD, 0x84, 0x13, 0x8E, 0x9A, 0x8C, 0x0D, 0x80, 0x0C, 0x32, 0xF6, 0xE0, + 0x27 +}; + +static const unsigned char TA309_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x34 +}; + +static const unsigned char TA309_EC_Q[] = { + 0x04, 0xF3, 0x74, 0x73, 0xA7, 0x68, 0x8B, 0x60, 0xAE, 0x43, 0xB8, 0x35, + 0xC5, 0x81, 0x30, 0x7B, 0x4B, 0x49, 0x9D, 0xFB, 0xC1, 0x61, 0xCE, 0xE6, + 0xDE, 0x46, 0xBD, 0x6B, 0xD5, 0x61, 0x18, 0x35, 0xAE, 0x40, 0xDD, 0x73, + 0xF7, 0x89, 0x91, 0x30, 0x5A, 0xEB, 0x3C, 0xEE, 0x85, 0x7C, 0xA2, 0x40, + 0x76, 0x3B, 0xA9, 0xC6, 0xB8, 0x47, 0xD8, 0x2A, 0xE7, 0x92, 0x91, 0x6A, + 0x73, 0xE9, 0xB1, 0x72, 0x39, 0x9F, 0x29, 0x9F, 0xA2, 0x98, 0xD3, 0x5F, + 0x5E, 0x58, 0x86, 0x65, 0x0F, 0xA1, 0x84, 0x65, 0x06, 0xD1, 0xDC, 0x8B, + 0xC9, 0xC7, 0x73, 0xC8, 0x8C, 0x6A, 0x2F, 0xE5, 0xC4, 0xAB, 0xD1, 0x1D, + 0x8A +}; + +static const unsigned char TA310_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x34, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA310_EC_Q[] = { + 0x04, 0xB8, 0xC6, 0x79, 0xD3, 0x8F, 0x6C, 0x25, 0x0E, 0x9F, 0x2E, 0x39, + 0x19, 0x1C, 0x03, 0xA4, 0xAE, 0x9A, 0xE5, 0x39, 0x07, 0x09, 0x16, 0xCA, + 0x63, 0xB1, 0xB9, 0x86, 0xF8, 0x8A, 0x57, 0xC1, 0x57, 0xCE, 0x42, 0xFA, + 0x73, 0xA1, 0xF7, 0x65, 0x42, 0xFF, 0x1E, 0xC1, 0x00, 0xB2, 0x6E, 0x73, + 0x0E, 0xFF, 0xC7, 0x21, 0xE5, 0x18, 0xA4, 0xAA, 0xD9, 0x71, 0x3F, 0xA8, + 0xD4, 0xB9, 0xCE, 0x8C, 0x1D +}; + +static const unsigned char TA311_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x35, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA311_EC_Q[] = { + 0x04, 0x47, 0x45, 0x0E, 0x96, 0xFB, 0x7D, 0x5D, 0xBF, 0xE9, 0x39, 0xD1, + 0x21, 0xF8, 0x9F, 0x0B, 0xB6, 0xD5, 0x7B, 0x1E, 0x92, 0x3A, 0x48, 0x59, + 0x1C, 0xF0, 0x62, 0x31, 0x2D, 0xC0, 0x7A, 0x28, 0xFE, 0x1A, 0xA7, 0x5C, + 0xB3, 0xB6, 0xCC, 0x97, 0xE7, 0x45, 0xD4, 0x58, 0xFA, 0xD1, 0x77, 0x6D, + 0x43, 0xA2, 0xC0, 0x87, 0x65, 0x34, 0x0A, 0x1F, 0x7A, 0xDD, 0xEB, 0x3C, + 0x33, 0xA1, 0xC5, 0x9D, 0x4D, 0xA4, 0x6F, 0x41, 0x95, 0x38, 0x7F, 0xC9, + 0x1E, 0x84, 0xEB, 0xD1, 0x9E, 0x49, 0x92, 0x87, 0x94, 0x87, 0x0C, 0x3A, + 0x85, 0x4A, 0x66, 0x9F, 0x9D, 0x59, 0x93, 0x4D, 0x97, 0x61, 0x06, 0x86, + 0x4A +}; + +static const unsigned char TA312_DN[] = { + 0x30, 0x57, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, + 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA312_RSA_N[] = { + 0xDA, 0x0E, 0xE6, 0x99, 0x8D, 0xCE, 0xA3, 0xE3, 0x4F, 0x8A, 0x7E, 0xFB, + 0xF1, 0x8B, 0x83, 0x25, 0x6B, 0xEA, 0x48, 0x1F, 0xF1, 0x2A, 0xB0, 0xB9, + 0x95, 0x11, 0x04, 0xBD, 0xF0, 0x63, 0xD1, 0xE2, 0x67, 0x66, 0xCF, 0x1C, + 0xDD, 0xCF, 0x1B, 0x48, 0x2B, 0xEE, 0x8D, 0x89, 0x8E, 0x9A, 0xAF, 0x29, + 0x80, 0x65, 0xAB, 0xE9, 0xC7, 0x2D, 0x12, 0xCB, 0xAB, 0x1C, 0x4C, 0x70, + 0x07, 0xA1, 0x3D, 0x0A, 0x30, 0xCD, 0x15, 0x8D, 0x4F, 0xF8, 0xDD, 0xD4, + 0x8C, 0x50, 0x15, 0x1C, 0xEF, 0x50, 0xEE, 0xC4, 0x2E, 0xF7, 0xFC, 0xE9, + 0x52, 0xF2, 0x91, 0x7D, 0xE0, 0x6D, 0xD5, 0x35, 0x30, 0x8E, 0x5E, 0x43, + 0x73, 0xF2, 0x41, 0xE9, 0xD5, 0x6A, 0xE3, 0xB2, 0x89, 0x3A, 0x56, 0x39, + 0x38, 0x6F, 0x06, 0x3C, 0x88, 0x69, 0x5B, 0x2A, 0x4D, 0xC5, 0xA7, 0x54, + 0xB8, 0x6C, 0x89, 0xCC, 0x9B, 0xF9, 0x3C, 0xCA, 0xE5, 0xFD, 0x89, 0xF5, + 0x12, 0x3C, 0x92, 0x78, 0x96, 0xD6, 0xDC, 0x74, 0x6E, 0x93, 0x44, 0x61, + 0xD1, 0x8D, 0xC7, 0x46, 0xB2, 0x75, 0x0E, 0x86, 0xE8, 0x19, 0x8A, 0xD5, + 0x6D, 0x6C, 0xD5, 0x78, 0x16, 0x95, 0xA2, 0xE9, 0xC8, 0x0A, 0x38, 0xEB, + 0xF2, 0x24, 0x13, 0x4F, 0x73, 0x54, 0x93, 0x13, 0x85, 0x3A, 0x1B, 0xBC, + 0x1E, 0x34, 0xB5, 0x8B, 0x05, 0x8C, 0xB9, 0x77, 0x8B, 0xB1, 0xDB, 0x1F, + 0x20, 0x91, 0xAB, 0x09, 0x53, 0x6E, 0x90, 0xCE, 0x7B, 0x37, 0x74, 0xB9, + 0x70, 0x47, 0x91, 0x22, 0x51, 0x63, 0x16, 0x79, 0xAE, 0xB1, 0xAE, 0x41, + 0x26, 0x08, 0xC8, 0x19, 0x2B, 0xD1, 0x46, 0xAA, 0x48, 0xD6, 0x64, 0x2A, + 0xD7, 0x83, 0x34, 0xFF, 0x2C, 0x2A, 0xC1, 0x6C, 0x19, 0x43, 0x4A, 0x07, + 0x85, 0xE7, 0xD3, 0x7C, 0xF6, 0x21, 0x68, 0xEF, 0xEA, 0xF2, 0x52, 0x9F, + 0x7F, 0x93, 0x90, 0xCF +}; + +static const unsigned char TA312_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA313_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x33, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA313_RSA_N[] = { + 0xCC, 0x25, 0x76, 0x90, 0x79, 0x06, 0x78, 0x22, 0x16, 0xF5, 0xC0, 0x83, + 0xB6, 0x84, 0xCA, 0x28, 0x9E, 0xFD, 0x05, 0x76, 0x11, 0xC5, 0xAD, 0x88, + 0x72, 0xFC, 0x46, 0x02, 0x43, 0xC7, 0xB2, 0x8A, 0x9D, 0x04, 0x5F, 0x24, + 0xCB, 0x2E, 0x4B, 0xE1, 0x60, 0x82, 0x46, 0xE1, 0x52, 0xAB, 0x0C, 0x81, + 0x47, 0x70, 0x6C, 0xDD, 0x64, 0xD1, 0xEB, 0xF5, 0x2C, 0xA3, 0x0F, 0x82, + 0x3D, 0x0C, 0x2B, 0xAE, 0x97, 0xD7, 0xB6, 0x14, 0x86, 0x10, 0x79, 0xBB, + 0x3B, 0x13, 0x80, 0x77, 0x8C, 0x08, 0xE1, 0x49, 0xD2, 0x6A, 0x62, 0x2F, + 0x1F, 0x5E, 0xFA, 0x96, 0x68, 0xDF, 0x89, 0x27, 0x95, 0x38, 0x9F, 0x06, + 0xD7, 0x3E, 0xC9, 0xCB, 0x26, 0x59, 0x0D, 0x73, 0xDE, 0xB0, 0xC8, 0xE9, + 0x26, 0x0E, 0x83, 0x15, 0xC6, 0xEF, 0x5B, 0x8B, 0xD2, 0x04, 0x60, 0xCA, + 0x49, 0xA6, 0x28, 0xF6, 0x69, 0x3B, 0xF6, 0xCB, 0xC8, 0x28, 0x91, 0xE5, + 0x9D, 0x8A, 0x61, 0x57, 0x37, 0xAC, 0x74, 0x14, 0xDC, 0x74, 0xE0, 0x3A, + 0xEE, 0x72, 0x2F, 0x2E, 0x9C, 0xFB, 0xD0, 0xBB, 0xBF, 0xF5, 0x3D, 0x00, + 0xE1, 0x06, 0x33, 0xE8, 0x82, 0x2B, 0xAE, 0x53, 0xA6, 0x3A, 0x16, 0x73, + 0x8C, 0xDD, 0x41, 0x0E, 0x20, 0x3A, 0xC0, 0xB4, 0xA7, 0xA1, 0xE9, 0xB2, + 0x4F, 0x90, 0x2E, 0x32, 0x60, 0xE9, 0x57, 0xCB, 0xB9, 0x04, 0x92, 0x68, + 0x68, 0xE5, 0x38, 0x26, 0x60, 0x75, 0xB2, 0x9F, 0x77, 0xFF, 0x91, 0x14, + 0xEF, 0xAE, 0x20, 0x49, 0xFC, 0xAD, 0x40, 0x15, 0x48, 0xD1, 0x02, 0x31, + 0x61, 0x19, 0x5E, 0xB8, 0x97, 0xEF, 0xAD, 0x77, 0xB7, 0x64, 0x9A, 0x7A, + 0xBF, 0x5F, 0xC1, 0x13, 0xEF, 0x9B, 0x62, 0xFB, 0x0D, 0x6C, 0xE0, 0x54, + 0x69, 0x16, 0xA9, 0x03, 0xDA, 0x6E, 0xE9, 0x83, 0x93, 0x71, 0x76, 0xC6, + 0x69, 0x85, 0x82, 0x17 +}; + +static const unsigned char TA313_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA314_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x36, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA314_RSA_N[] = { + 0x95, 0x07, 0xE8, 0x73, 0xCA, 0x66, 0xF9, 0xEC, 0x14, 0xCA, 0x7B, 0x3C, + 0xF7, 0x0D, 0x08, 0xF1, 0xB4, 0x45, 0x0B, 0x2C, 0x82, 0xB4, 0x48, 0xC6, + 0xEB, 0x5B, 0x3C, 0xAE, 0x83, 0xB8, 0x41, 0x92, 0x33, 0x14, 0xA4, 0x6F, + 0x7F, 0xE9, 0x2A, 0xCC, 0xC6, 0xB0, 0x88, 0x6B, 0xC5, 0xB6, 0x89, 0xD1, + 0xC6, 0xB2, 0xFF, 0x14, 0xCE, 0x51, 0x14, 0x21, 0xEC, 0x4A, 0xDD, 0x1B, + 0x5A, 0xC6, 0xD6, 0x87, 0xEE, 0x4D, 0x3A, 0x15, 0x06, 0xED, 0x64, 0x66, + 0x0B, 0x92, 0x80, 0xCA, 0x44, 0xDE, 0x73, 0x94, 0x4E, 0xF3, 0xA7, 0x89, + 0x7F, 0x4F, 0x78, 0x63, 0x08, 0xC8, 0x12, 0x50, 0x6D, 0x42, 0x66, 0x2F, + 0x4D, 0xB9, 0x79, 0x28, 0x4D, 0x52, 0x1A, 0x8A, 0x1A, 0x80, 0xB7, 0x19, + 0x81, 0x0E, 0x7E, 0xC4, 0x8A, 0xBC, 0x64, 0x4C, 0x21, 0x1C, 0x43, 0x68, + 0xD7, 0x3D, 0x3C, 0x8A, 0xC5, 0xB2, 0x66, 0xD5, 0x90, 0x9A, 0xB7, 0x31, + 0x06, 0xC5, 0xBE, 0xE2, 0x6D, 0x32, 0x06, 0xA6, 0x1E, 0xF9, 0xB9, 0xEB, + 0xAA, 0xA3, 0xB8, 0xBF, 0xBE, 0x82, 0x63, 0x50, 0xD0, 0xF0, 0x18, 0x89, + 0xDF, 0xE4, 0x0F, 0x79, 0xF5, 0xEA, 0xA2, 0x1F, 0x2A, 0xD2, 0x70, 0x2E, + 0x7B, 0xE7, 0xBC, 0x93, 0xBB, 0x6D, 0x53, 0xE2, 0x48, 0x7C, 0x8C, 0x10, + 0x07, 0x38, 0xFF, 0x66, 0xB2, 0x77, 0x61, 0x7E, 0xE0, 0xEA, 0x8C, 0x3C, + 0xAA, 0xB4, 0xA4, 0xF6, 0xF3, 0x95, 0x4A, 0x12, 0x07, 0x6D, 0xFD, 0x8C, + 0xB2, 0x89, 0xCF, 0xD0, 0xA0, 0x61, 0x77, 0xC8, 0x58, 0x74, 0xB0, 0xD4, + 0x23, 0x3A, 0xF7, 0x5D, 0x3A, 0xCA, 0xA2, 0xDB, 0x9D, 0x09, 0xDE, 0x5D, + 0x44, 0x2D, 0x90, 0xF1, 0x81, 0xCD, 0x57, 0x92, 0xFA, 0x7E, 0xBC, 0x50, + 0x04, 0x63, 0x34, 0xDF, 0x6B, 0x93, 0x18, 0xBE, 0x6B, 0x36, 0xB2, 0x39, + 0xE4, 0xAC, 0x24, 0x36, 0xB7, 0xF0, 0xEF, 0xB6, 0x1C, 0x13, 0x57, 0x93, + 0xB6, 0xDE, 0xB2, 0xF8, 0xE2, 0x85, 0xB7, 0x73, 0xA2, 0xB8, 0x35, 0xAA, + 0x45, 0xF2, 0xE0, 0x9D, 0x36, 0xA1, 0x6F, 0x54, 0x8A, 0xF1, 0x72, 0x56, + 0x6E, 0x2E, 0x88, 0xC5, 0x51, 0x42, 0x44, 0x15, 0x94, 0xEE, 0xA3, 0xC5, + 0x38, 0x96, 0x9B, 0x4E, 0x4E, 0x5A, 0x0B, 0x47, 0xF3, 0x06, 0x36, 0x49, + 0x77, 0x30, 0xBC, 0x71, 0x37, 0xE5, 0xA6, 0xEC, 0x21, 0x08, 0x75, 0xFC, + 0xE6, 0x61, 0x16, 0x3F, 0x77, 0xD5, 0xD9, 0x91, 0x97, 0x84, 0x0A, 0x6C, + 0xD4, 0x02, 0x4D, 0x74, 0xC0, 0x14, 0xED, 0xFD, 0x39, 0xFB, 0x83, 0xF2, + 0x5E, 0x14, 0xA1, 0x04, 0xB0, 0x0B, 0xE9, 0xFE, 0xEE, 0x8F, 0xE1, 0x6E, + 0x0B, 0xB2, 0x08, 0xB3, 0x61, 0x66, 0x09, 0x6A, 0xB1, 0x06, 0x3A, 0x65, + 0x96, 0x59, 0xC0, 0xF0, 0x35, 0xFD, 0xC9, 0xDA, 0x28, 0x8D, 0x1A, 0x11, + 0x87, 0x70, 0x81, 0x0A, 0xA8, 0x9A, 0x75, 0x1D, 0x9E, 0x3A, 0x86, 0x05, + 0x00, 0x9E, 0xDB, 0x80, 0xD6, 0x25, 0xF9, 0xDC, 0x05, 0x9E, 0x27, 0x59, + 0x4C, 0x76, 0x39, 0x5B, 0xEA, 0xF9, 0xA5, 0xA1, 0xD8, 0x83, 0x0F, 0xD1, + 0xFF, 0xDF, 0x30, 0x11, 0xF9, 0x85, 0xCF, 0x33, 0x48, 0xF5, 0xCA, 0x6D, + 0x64, 0x14, 0x2C, 0x7A, 0x58, 0x4F, 0xD3, 0x4B, 0x08, 0x49, 0xC5, 0x95, + 0x64, 0x1A, 0x63, 0x0E, 0x79, 0x3D, 0xF5, 0xB3, 0x8C, 0xCA, 0x58, 0xAD, + 0x9C, 0x42, 0x45, 0x79, 0x6E, 0x0E, 0x87, 0x19, 0x5C, 0x54, 0xB1, 0x65, + 0xB6, 0xBF, 0x8C, 0x9B, 0xDC, 0x13, 0xE9, 0x0D, 0x6F, 0xB8, 0x2E, 0xDC, + 0x67, 0x6E, 0xC9, 0x8B, 0x11, 0xB5, 0x84, 0x14, 0x8A, 0x00, 0x19, 0x70, + 0x83, 0x79, 0x91, 0x97, 0x91, 0xD4, 0x1A, 0x27, 0xBF, 0x37, 0x1E, 0x32, + 0x07, 0xD8, 0x14, 0x63, 0x3C, 0x28, 0x4C, 0xAF +}; + +static const unsigned char TA314_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA315_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, 0x36 +}; + +static const unsigned char TA315_EC_Q[] = { + 0x04, 0x9C, 0x0E, 0xB1, 0xCF, 0xB7, 0xE8, 0x9E, 0x52, 0x77, 0x75, 0x34, + 0xFA, 0xA5, 0x46, 0xA7, 0xAD, 0x32, 0x19, 0x32, 0xB4, 0x07, 0xA9, 0x27, + 0xCA, 0x94, 0xBB, 0x0C, 0xD2, 0x0A, 0x10, 0xC7, 0xDA, 0x89, 0xB0, 0x97, + 0x0C, 0x70, 0x13, 0x09, 0x01, 0x8E, 0xD8, 0xEA, 0x47, 0xEA, 0xBE, 0xB2, + 0x80, 0x2B, 0xCD, 0xFC, 0x28, 0x0D, 0xDB, 0xAC, 0xBC, 0xA4, 0x86, 0x37, + 0xED, 0x70, 0x08, 0x00, 0x75, 0xEA, 0x93, 0x0B, 0x7B, 0x2E, 0x52, 0x9C, + 0x23, 0x68, 0x23, 0x06, 0x43, 0xEC, 0x92, 0x2F, 0x53, 0x84, 0xDB, 0xFB, + 0x47, 0x14, 0x07, 0xE8, 0x5F, 0x94, 0x67, 0x5D, 0xC9, 0x7A, 0x81, 0x3C, + 0x20 +}; + +static const unsigned char TA316_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x36 +}; + +static const unsigned char TA316_RSA_N[] = { + 0xAC, 0xAC, 0x74, 0x32, 0xE8, 0xB3, 0x65, 0xE5, 0xBA, 0xED, 0x43, 0x26, + 0x1D, 0xA6, 0x89, 0x0D, 0x45, 0xBA, 0x29, 0x88, 0xB2, 0xA4, 0x1D, 0x63, + 0xDD, 0xD3, 0xC1, 0x2C, 0x09, 0x57, 0x89, 0x39, 0xA1, 0x55, 0xE9, 0x67, + 0x34, 0x77, 0x0C, 0x6E, 0xE4, 0x55, 0x1D, 0x52, 0x25, 0xD2, 0x13, 0x6B, + 0x5E, 0xE1, 0x1D, 0xA9, 0xB7, 0x7D, 0x89, 0x32, 0x5F, 0x0D, 0x9E, 0x9F, + 0x2C, 0x7A, 0x63, 0x60, 0x40, 0x1F, 0xA6, 0xB0, 0xB6, 0x78, 0x8F, 0x99, + 0x54, 0x96, 0x08, 0x58, 0xAE, 0xE4, 0x06, 0xBC, 0x62, 0x05, 0x02, 0x16, + 0xBF, 0xAF, 0xA8, 0x23, 0x03, 0xB6, 0x94, 0x0F, 0xBC, 0x6E, 0x6C, 0xC2, + 0xCB, 0xD5, 0xA6, 0xBB, 0x0C, 0xE9, 0xF6, 0xC1, 0x02, 0xFB, 0x21, 0xDE, + 0x66, 0xDD, 0x17, 0xAB, 0x74, 0x42, 0xEF, 0xF0, 0x74, 0x2F, 0x25, 0xF4, + 0xEA, 0x6B, 0x55, 0x5B, 0x90, 0xDB, 0x9D, 0xDF, 0x5E, 0x87, 0x0A, 0x40, + 0xFB, 0xAD, 0x19, 0x6B, 0xFB, 0xF7, 0xCA, 0x60, 0x88, 0xDE, 0xDA, 0xC1, + 0x8F, 0xD6, 0xAE, 0xD5, 0x7F, 0xD4, 0x3C, 0x83, 0xEE, 0xD7, 0x16, 0x4C, + 0x83, 0x45, 0x33, 0x6B, 0x27, 0xD0, 0x86, 0xD0, 0x1C, 0x2D, 0x6B, 0xF3, + 0xAB, 0x7D, 0xF1, 0x85, 0xA9, 0xF5, 0x28, 0xD2, 0xAD, 0xEF, 0xF3, 0x84, + 0x4B, 0x1C, 0x87, 0xFC, 0x13, 0xA3, 0x3A, 0x72, 0xA2, 0x5A, 0x11, 0x2B, + 0xD6, 0x27, 0x71, 0x27, 0xED, 0x81, 0x2D, 0x6D, 0x66, 0x81, 0x92, 0x87, + 0xB4, 0x1B, 0x58, 0x7A, 0xCC, 0x3F, 0x0A, 0xFA, 0x46, 0x4F, 0x4D, 0x78, + 0x5C, 0xF8, 0x2B, 0x48, 0xE3, 0x04, 0x84, 0xCB, 0x5D, 0xF6, 0xB4, 0x6A, + 0xB3, 0x65, 0xFC, 0x42, 0x9E, 0x51, 0x26, 0x23, 0x20, 0xCB, 0x3D, 0x14, + 0xF9, 0x81, 0xED, 0x65, 0x16, 0x00, 0x4F, 0x1A, 0x64, 0x97, 0x66, 0x08, + 0xCF, 0x8C, 0x7B, 0xE3, 0x2B, 0xC0, 0x9D, 0xF9, 0x14, 0xF2, 0x1B, 0xF1, + 0x56, 0x6A, 0x16, 0xBF, 0x2C, 0x85, 0x85, 0xCD, 0x78, 0x38, 0x9A, 0xEB, + 0x42, 0x6A, 0x02, 0x34, 0x18, 0x83, 0x17, 0x4E, 0x94, 0x56, 0xF8, 0xB6, + 0x82, 0xB5, 0xF3, 0x96, 0xDD, 0x3D, 0xF3, 0xBE, 0x7F, 0x20, 0x77, 0x3E, + 0x7B, 0x19, 0x23, 0x6B, 0x2C, 0xD4, 0x72, 0x73, 0x43, 0x57, 0x7D, 0xE0, + 0xF8, 0xD7, 0x69, 0x4F, 0x17, 0x36, 0x04, 0xF9, 0xC0, 0x90, 0x60, 0x37, + 0x45, 0xDE, 0xE6, 0x0C, 0xD8, 0x74, 0x8D, 0xAE, 0x9C, 0xA2, 0x6D, 0x74, + 0x5D, 0x42, 0xBE, 0x06, 0xF5, 0xD9, 0x64, 0x6E, 0x02, 0x10, 0xAC, 0x89, + 0xB0, 0x4C, 0x3B, 0x07, 0x4D, 0x40, 0x7E, 0x24, 0xC5, 0x8A, 0x98, 0x82, + 0x79, 0x8E, 0xA4, 0xA7, 0x82, 0x20, 0x8D, 0x23, 0xFA, 0x27, 0x71, 0xC9, + 0xDF, 0xC6, 0x41, 0x74, 0xA0, 0x4D, 0xF6, 0x91, 0x16, 0xDC, 0x46, 0x8C, + 0x5F, 0x29, 0x63, 0x31, 0x59, 0x71, 0x0C, 0xD8, 0x6F, 0xC2, 0xB6, 0x32, + 0x7D, 0xFB, 0xE6, 0x5D, 0x53, 0xA6, 0x7E, 0x15, 0xFC, 0xBB, 0x75, 0x7C, + 0x5D, 0xEC, 0xF8, 0xF6, 0x17, 0x1C, 0xEC, 0xC7, 0x6B, 0x19, 0xCB, 0xF3, + 0x7B, 0xF0, 0x2B, 0x07, 0xA5, 0xD9, 0x6C, 0x79, 0x54, 0x76, 0x6C, 0x9D, + 0x1C, 0xA6, 0x6E, 0x0E, 0xE9, 0x79, 0x0C, 0xA8, 0x23, 0x6A, 0xA3, 0xDF, + 0x1B, 0x30, 0x31, 0x9F, 0xB1, 0x54, 0x7B, 0xFE, 0x6A, 0xCB, 0x66, 0xAA, + 0xDC, 0x65, 0xD0, 0xA2, 0x9E, 0x4A, 0x9A, 0x07, 0x21, 0x6B, 0x81, 0x8F, + 0xDB, 0xC4, 0x59, 0xFA, 0xDE, 0x22, 0xC0, 0x04, 0x9C, 0xE3, 0xAA, 0x5B, + 0x36, 0x93, 0xE8, 0x3D, 0xBD, 0x7A, 0xA1, 0x9D, 0x0B, 0x76, 0xB1, 0x0B, + 0xC7, 0x9D, 0xFD, 0xCF, 0x98, 0xA8, 0x06, 0xC2, 0xF8, 0x2A, 0xA3, 0xA1, + 0x83, 0xA0, 0xB7, 0x25, 0x72, 0xA5, 0x02, 0xE3 +}; + +static const unsigned char TA316_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA317_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, + 0x64, 0x79, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x49, 0x6E, + 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x28, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6C, + 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA317_RSA_N[] = { + 0xDE, 0x9D, 0xD7, 0xEA, 0x57, 0x18, 0x49, 0xA1, 0x5B, 0xEB, 0xD7, 0x5F, + 0x48, 0x86, 0xEA, 0xBE, 0xDD, 0xFF, 0xE4, 0xEF, 0x67, 0x1C, 0xF4, 0x65, + 0x68, 0xB3, 0x57, 0x71, 0xA0, 0x5E, 0x77, 0xBB, 0xED, 0x9B, 0x49, 0xE9, + 0x70, 0x80, 0x3D, 0x56, 0x18, 0x63, 0x08, 0x6F, 0xDA, 0xF2, 0xCC, 0xD0, + 0x3F, 0x7F, 0x02, 0x54, 0x22, 0x54, 0x10, 0xD8, 0xB2, 0x81, 0xD4, 0xC0, + 0x75, 0x3D, 0x4B, 0x7F, 0xC7, 0x77, 0xC3, 0x3E, 0x78, 0xAB, 0x1A, 0x03, + 0xB5, 0x20, 0x6B, 0x2F, 0x6A, 0x2B, 0xB1, 0xC5, 0x88, 0x7E, 0xC4, 0xBB, + 0x1E, 0xB0, 0xC1, 0xD8, 0x45, 0x27, 0x6F, 0xAA, 0x37, 0x58, 0xF7, 0x87, + 0x26, 0xD7, 0xD8, 0x2D, 0xF6, 0xA9, 0x17, 0xB7, 0x1F, 0x72, 0x36, 0x4E, + 0xA6, 0x17, 0x3F, 0x65, 0x98, 0x92, 0xDB, 0x2A, 0x6E, 0x5D, 0xA2, 0xFE, + 0x88, 0xE0, 0x0B, 0xDE, 0x7F, 0xE5, 0x8D, 0x15, 0xE1, 0xEB, 0xCB, 0x3A, + 0xD5, 0xE2, 0x12, 0xA2, 0x13, 0x2D, 0xD8, 0x8E, 0xAF, 0x5F, 0x12, 0x3D, + 0xA0, 0x08, 0x05, 0x08, 0xB6, 0x5C, 0xA5, 0x65, 0x38, 0x04, 0x45, 0x99, + 0x1E, 0xA3, 0x60, 0x60, 0x74, 0xC5, 0x41, 0xA5, 0x72, 0x62, 0x1B, 0x62, + 0xC5, 0x1F, 0x6F, 0x5F, 0x1A, 0x42, 0xBE, 0x02, 0x51, 0x65, 0xA8, 0xAE, + 0x23, 0x18, 0x6A, 0xFC, 0x78, 0x03, 0xA9, 0x4D, 0x7F, 0x80, 0xC3, 0xFA, + 0xAB, 0x5A, 0xFC, 0xA1, 0x40, 0xA4, 0xCA, 0x19, 0x16, 0xFE, 0xB2, 0xC8, + 0xEF, 0x5E, 0x73, 0x0D, 0xEE, 0x77, 0xBD, 0x9A, 0xF6, 0x79, 0x98, 0xBC, + 0xB1, 0x07, 0x67, 0xA2, 0x15, 0x0D, 0xDD, 0xA0, 0x58, 0xC6, 0x44, 0x7B, + 0x0A, 0x3E, 0x62, 0x28, 0x5F, 0xBA, 0x41, 0x07, 0x53, 0x58, 0xCF, 0x11, + 0x7E, 0x38, 0x74, 0xC5, 0xF8, 0xFF, 0xB5, 0x69, 0x90, 0x8F, 0x84, 0x74, + 0xEA, 0x97, 0x1B, 0xAF +}; + +static const unsigned char TA317_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA318_DN[] = { + 0x30, 0x81, 0x83, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x1A, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, 0x47, 0x6F, 0x44, 0x61, 0x64, 0x64, + 0x79, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, + 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6F, + 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA318_RSA_N[] = { + 0xBF, 0x71, 0x62, 0x08, 0xF1, 0xFA, 0x59, 0x34, 0xF7, 0x1B, 0xC9, 0x18, + 0xA3, 0xF7, 0x80, 0x49, 0x58, 0xE9, 0x22, 0x83, 0x13, 0xA6, 0xC5, 0x20, + 0x43, 0x01, 0x3B, 0x84, 0xF1, 0xE6, 0x85, 0x49, 0x9F, 0x27, 0xEA, 0xF6, + 0x84, 0x1B, 0x4E, 0xA0, 0xB4, 0xDB, 0x70, 0x98, 0xC7, 0x32, 0x01, 0xB1, + 0x05, 0x3E, 0x07, 0x4E, 0xEE, 0xF4, 0xFA, 0x4F, 0x2F, 0x59, 0x30, 0x22, + 0xE7, 0xAB, 0x19, 0x56, 0x6B, 0xE2, 0x80, 0x07, 0xFC, 0xF3, 0x16, 0x75, + 0x80, 0x39, 0x51, 0x7B, 0xE5, 0xF9, 0x35, 0xB6, 0x74, 0x4E, 0xA9, 0x8D, + 0x82, 0x13, 0xE4, 0xB6, 0x3F, 0xA9, 0x03, 0x83, 0xFA, 0xA2, 0xBE, 0x8A, + 0x15, 0x6A, 0x7F, 0xDE, 0x0B, 0xC3, 0xB6, 0x19, 0x14, 0x05, 0xCA, 0xEA, + 0xC3, 0xA8, 0x04, 0x94, 0x3B, 0x46, 0x7C, 0x32, 0x0D, 0xF3, 0x00, 0x66, + 0x22, 0xC8, 0x8D, 0x69, 0x6D, 0x36, 0x8C, 0x11, 0x18, 0xB7, 0xD3, 0xB2, + 0x1C, 0x60, 0xB4, 0x38, 0xFA, 0x02, 0x8C, 0xCE, 0xD3, 0xDD, 0x46, 0x07, + 0xDE, 0x0A, 0x3E, 0xEB, 0x5D, 0x7C, 0xC8, 0x7C, 0xFB, 0xB0, 0x2B, 0x53, + 0xA4, 0x92, 0x62, 0x69, 0x51, 0x25, 0x05, 0x61, 0x1A, 0x44, 0x81, 0x8C, + 0x2C, 0xA9, 0x43, 0x96, 0x23, 0xDF, 0xAC, 0x3A, 0x81, 0x9A, 0x0E, 0x29, + 0xC5, 0x1C, 0xA9, 0xE9, 0x5D, 0x1E, 0xB6, 0x9E, 0x9E, 0x30, 0x0A, 0x39, + 0xCE, 0xF1, 0x88, 0x80, 0xFB, 0x4B, 0x5D, 0xCC, 0x32, 0xEC, 0x85, 0x62, + 0x43, 0x25, 0x34, 0x02, 0x56, 0x27, 0x01, 0x91, 0xB4, 0x3B, 0x70, 0x2A, + 0x3F, 0x6E, 0xB1, 0xE8, 0x9C, 0x88, 0x01, 0x7D, 0x9F, 0xD4, 0xF9, 0xDB, + 0x53, 0x6D, 0x60, 0x9D, 0xBF, 0x2C, 0xE7, 0x58, 0xAB, 0xB8, 0x5F, 0x46, + 0xFC, 0xCE, 0xC4, 0x1B, 0x03, 0x3C, 0x09, 0xEB, 0x49, 0x31, 0x5C, 0x69, + 0x46, 0xB3, 0xE0, 0x47 +}; + +static const unsigned char TA318_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA319_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, + 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA319_EC_Q[] = { + 0x04, 0x38, 0x08, 0xFE, 0xB1, 0xA0, 0x96, 0xD2, 0x7A, 0xAC, 0xAF, 0x49, + 0x3A, 0xD0, 0xC0, 0xE0, 0xC3, 0x3B, 0x28, 0xAA, 0xF1, 0x72, 0x6D, 0x65, + 0x00, 0x47, 0x88, 0x84, 0xFC, 0x9A, 0x26, 0x6B, 0xAA, 0x4B, 0xBA, 0x6C, + 0x04, 0x0A, 0x88, 0x5E, 0x17, 0xF2, 0x55, 0x87, 0xFC, 0x30, 0xB0, 0x34, + 0xE2, 0x34, 0x58, 0x57, 0x1A, 0x84, 0x53, 0xE9, 0x30, 0xD9, 0xA9, 0xF2, + 0x96, 0x74, 0xC3, 0x51, 0x1F, 0x58, 0x49, 0x31, 0xCC, 0x98, 0x4E, 0x60, + 0x11, 0x87, 0x75, 0xD3, 0x72, 0x94, 0x90, 0x4F, 0x9B, 0x10, 0x25, 0x2A, + 0xA8, 0x78, 0x2D, 0xBE, 0x90, 0x41, 0x58, 0x90, 0x15, 0x72, 0xA7, 0xA1, + 0xB7 +}; + +static const unsigned char TA320_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, + 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA320_RSA_N[] = { + 0x8B, 0xC2, 0xE7, 0xAF, 0x65, 0x9B, 0x05, 0x67, 0x96, 0xC9, 0x0D, 0x24, + 0xB9, 0xD0, 0x0E, 0x64, 0xFC, 0xCE, 0xE2, 0x24, 0x18, 0x2C, 0x84, 0x7F, + 0x77, 0x51, 0xCB, 0x04, 0x11, 0x36, 0xB8, 0x5E, 0xED, 0x69, 0x71, 0xA7, + 0x9E, 0xE4, 0x25, 0x09, 0x97, 0x67, 0xC1, 0x47, 0xC2, 0xCF, 0x91, 0x16, + 0x36, 0x62, 0x3D, 0x38, 0x04, 0xE1, 0x51, 0x82, 0xFF, 0xAC, 0xD2, 0xB4, + 0x69, 0xDD, 0x2E, 0xEC, 0x11, 0xA3, 0x45, 0xEE, 0x6B, 0x6B, 0x3B, 0x4C, + 0xBF, 0x8C, 0x8D, 0xA4, 0x1E, 0x9D, 0x11, 0xB9, 0xE9, 0x38, 0xF9, 0x7A, + 0x0E, 0x0C, 0x98, 0xE2, 0x23, 0x1D, 0xD1, 0x4E, 0x63, 0xD4, 0xE7, 0xB8, + 0x41, 0x44, 0xFB, 0x6B, 0xAF, 0x6B, 0xDA, 0x1F, 0xD3, 0xC5, 0x91, 0x88, + 0x5B, 0xA4, 0x89, 0x92, 0xD1, 0x81, 0xE6, 0x8C, 0x39, 0x58, 0xA0, 0xD6, + 0x69, 0x43, 0xA9, 0xAD, 0x98, 0x52, 0x58, 0x6E, 0xDB, 0x0A, 0xFB, 0x6B, + 0xCF, 0x68, 0xFA, 0xE3, 0xA4, 0x5E, 0x3A, 0x45, 0x73, 0x98, 0x07, 0xEA, + 0x5F, 0x02, 0x72, 0xDE, 0x0C, 0xA5, 0xB3, 0x9F, 0xAE, 0xA9, 0x1D, 0xB7, + 0x1D, 0xB3, 0xFC, 0x8A, 0x59, 0xE7, 0x6E, 0x72, 0x65, 0xAD, 0xF5, 0x30, + 0x94, 0x23, 0x07, 0xF3, 0x82, 0x16, 0x4B, 0x35, 0x98, 0x9C, 0x53, 0xBB, + 0x2F, 0xCA, 0xE4, 0x5A, 0xD9, 0xC7, 0x8D, 0x1D, 0xFC, 0x98, 0x99, 0xFB, + 0x2C, 0xA4, 0x82, 0x6B, 0xF0, 0x2A, 0x1F, 0x8E, 0x0B, 0x5F, 0x71, 0x5C, + 0x5C, 0xAE, 0x42, 0x7B, 0x29, 0x89, 0x81, 0xCB, 0x03, 0xA3, 0x99, 0xCA, + 0x88, 0x9E, 0x0B, 0x40, 0x09, 0x41, 0x33, 0xDB, 0xE6, 0x58, 0x7A, 0xFD, + 0xAE, 0x99, 0x70, 0xC0, 0x5A, 0x0F, 0xD6, 0x13, 0x86, 0x71, 0x2F, 0x76, + 0x69, 0xFC, 0x90, 0xDD, 0xDB, 0x2D, 0x6E, 0xD1, 0xF2, 0x9B, 0xF5, 0x1A, + 0x6B, 0x9E, 0x6F, 0x15, 0x8C, 0x7A, 0xF0, 0x4B, 0x28, 0xA0, 0x22, 0x38, + 0x80, 0x24, 0x6C, 0x36, 0xA4, 0x3B, 0xF2, 0x30, 0x91, 0xF3, 0x78, 0x13, + 0xCF, 0xC1, 0x3F, 0x35, 0xAB, 0xF1, 0x1D, 0x11, 0x23, 0xB5, 0x43, 0x22, + 0x9E, 0x01, 0x92, 0xB7, 0x18, 0x02, 0xE5, 0x11, 0xD1, 0x82, 0xDB, 0x15, + 0x00, 0xCC, 0x61, 0x37, 0xC1, 0x2A, 0x7C, 0x9A, 0xE1, 0xD0, 0xBA, 0xB3, + 0x50, 0x46, 0xEE, 0x82, 0xAC, 0x9D, 0x31, 0xF8, 0xFB, 0x23, 0xE2, 0x03, + 0x00, 0x48, 0x70, 0xA3, 0x09, 0x26, 0x79, 0x15, 0x53, 0x60, 0xF3, 0x38, + 0x5C, 0xAD, 0x38, 0xEA, 0x81, 0x00, 0x63, 0x14, 0xB9, 0x33, 0x5E, 0xDD, + 0x0B, 0xDB, 0xA0, 0x45, 0x07, 0x1A, 0x33, 0x09, 0xF8, 0x4D, 0xB4, 0xA7, + 0x02, 0xA6, 0x69, 0xF4, 0xC2, 0x59, 0x05, 0x88, 0x65, 0x85, 0x56, 0xAE, + 0x4B, 0xCB, 0xE0, 0xDE, 0x3C, 0x7D, 0x2D, 0x1A, 0xC8, 0xE9, 0xFB, 0x1F, + 0xA3, 0x61, 0x4A, 0xD6, 0x2A, 0x13, 0xAD, 0x77, 0x4C, 0x1A, 0x18, 0x9B, + 0x91, 0x0F, 0x58, 0xD8, 0x06, 0x54, 0xC5, 0x97, 0xF8, 0xAA, 0x3F, 0x20, + 0x8A, 0xA6, 0x85, 0xA6, 0x77, 0xF6, 0xA6, 0xFC, 0x1C, 0xE2, 0xEE, 0x6E, + 0x94, 0x33, 0x2A, 0x83, 0x50, 0x84, 0x0A, 0xE5, 0x4F, 0x86, 0xF8, 0x50, + 0x45, 0x78, 0x00, 0x81, 0xEB, 0x5B, 0x68, 0xE3, 0x26, 0x8D, 0xCC, 0x7B, + 0x5C, 0x51, 0xF4, 0x14, 0x2C, 0x40, 0xBE, 0x1A, 0x60, 0x1D, 0x7A, 0x72, + 0x61, 0x1D, 0x1F, 0x63, 0x2D, 0x88, 0xAA, 0xCE, 0xA2, 0x45, 0x90, 0x08, + 0xFC, 0x6B, 0xBE, 0xB3, 0x50, 0x2A, 0x5A, 0xFD, 0xA8, 0x48, 0x18, 0x46, + 0xD6, 0x90, 0x40, 0x92, 0x90, 0x0A, 0x84, 0x5E, 0x68, 0x31, 0xF8, 0xEB, + 0xED, 0x0D, 0xD3, 0x1D, 0xC6, 0x7D, 0x99, 0x18, 0x55, 0x56, 0x27, 0x65, + 0x2E, 0x8D, 0x45, 0xC5, 0x24, 0xEC, 0xCE, 0xE3 +}; + +static const unsigned char TA320_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA321_DN[] = { + 0x30, 0x81, 0xAA, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x44, 0x30, 0x42, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, + 0x20, 0x32, 0x30, 0x31, 0x35 +}; + +static const unsigned char TA321_EC_Q[] = { + 0x04, 0x92, 0xA0, 0x41, 0xE8, 0x4B, 0x82, 0x84, 0x5C, 0xE2, 0xF8, 0x31, + 0x11, 0x99, 0x86, 0x64, 0x4E, 0x09, 0x25, 0x2F, 0x9D, 0x41, 0x2F, 0x0A, + 0xAE, 0x35, 0x4F, 0x74, 0x95, 0xB2, 0x51, 0x64, 0x6B, 0x8D, 0x6B, 0xE6, + 0x3F, 0x70, 0x95, 0xF0, 0x05, 0x44, 0x47, 0xA6, 0x72, 0x38, 0x50, 0x76, + 0x95, 0x02, 0x5A, 0x8E, 0xAE, 0x28, 0x9E, 0xF9, 0x2D, 0x4E, 0x99, 0xEF, + 0x2C, 0x48, 0x6F, 0x4C, 0x25, 0x29, 0xE8, 0xD1, 0x71, 0x5B, 0xDF, 0x1D, + 0xC1, 0x75, 0x37, 0xB4, 0xD7, 0xFA, 0x7B, 0x7A, 0x42, 0x9C, 0x6A, 0x0A, + 0x56, 0x5A, 0x7C, 0x69, 0x0B, 0xAA, 0x80, 0x09, 0x24, 0x6C, 0x7E, 0xC1, + 0x46 +}; + +static const unsigned char TA322_DN[] = { + 0x30, 0x81, 0xA6, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x40, 0x30, 0x3E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x37, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, + 0x35 +}; + +static const unsigned char TA322_RSA_N[] = { + 0xC2, 0xF8, 0xA9, 0x3F, 0x1B, 0x89, 0xFC, 0x3C, 0x3C, 0x04, 0x5D, 0x3D, + 0x90, 0x36, 0xB0, 0x91, 0x3A, 0x79, 0x3C, 0x66, 0x5A, 0xEF, 0x6D, 0x39, + 0x01, 0x49, 0x1A, 0xB4, 0xB7, 0xCF, 0x7F, 0x4D, 0x23, 0x53, 0xB7, 0x90, + 0x00, 0xE3, 0x13, 0x2A, 0x28, 0xA6, 0x31, 0xF1, 0x91, 0x00, 0xE3, 0x28, + 0xEC, 0xAE, 0x21, 0x41, 0xCE, 0x1F, 0xDA, 0xFD, 0x7D, 0x12, 0x5B, 0x01, + 0x83, 0x0F, 0xB9, 0xB0, 0x5F, 0x99, 0xE1, 0xF2, 0x12, 0x83, 0x80, 0x4D, + 0x06, 0x3E, 0xDF, 0xAC, 0xAF, 0xE7, 0xA1, 0x88, 0x6B, 0x31, 0xAF, 0xF0, + 0x8B, 0xD0, 0x18, 0x33, 0xB8, 0xDB, 0x45, 0x6A, 0x34, 0xF4, 0x02, 0x80, + 0x24, 0x28, 0x0A, 0x02, 0x15, 0x95, 0x5E, 0x76, 0x2A, 0x0D, 0x99, 0x3A, + 0x14, 0x5B, 0xF6, 0xCB, 0xCB, 0x53, 0xBC, 0x13, 0x4D, 0x01, 0x88, 0x37, + 0x94, 0x25, 0x1B, 0x42, 0xBC, 0x22, 0xD8, 0x8E, 0xA3, 0x96, 0x5E, 0x3A, + 0xD9, 0x32, 0xDB, 0x3E, 0xE8, 0xF0, 0x10, 0x65, 0xED, 0x74, 0xE1, 0x2F, + 0xA7, 0x7C, 0xAF, 0x27, 0x34, 0xBB, 0x29, 0x7D, 0x9B, 0xB6, 0xCF, 0x09, + 0xC8, 0xE5, 0xD3, 0x0A, 0xFC, 0x88, 0x65, 0x65, 0x74, 0x0A, 0xDC, 0x73, + 0x1C, 0x5C, 0xCD, 0x40, 0xB1, 0x1C, 0xD4, 0xB6, 0x84, 0x8C, 0x4C, 0x50, + 0xCF, 0x68, 0x8E, 0xA8, 0x59, 0xAE, 0xC2, 0x27, 0x4E, 0x82, 0xA2, 0x35, + 0xDD, 0x14, 0xF4, 0x1F, 0xFF, 0xB2, 0x77, 0xD5, 0x87, 0x2F, 0xAA, 0x6E, + 0x7D, 0x24, 0x27, 0xE7, 0xC6, 0xCB, 0x26, 0xE6, 0xE5, 0xFE, 0x67, 0x07, + 0x63, 0xD8, 0x45, 0x0D, 0xDD, 0x3A, 0x59, 0x65, 0x39, 0x58, 0x7A, 0x92, + 0x99, 0x72, 0x3D, 0x9C, 0x84, 0x5E, 0x88, 0x21, 0xB8, 0xD5, 0xF4, 0x2C, + 0xFC, 0xD9, 0x70, 0x52, 0x4F, 0x78, 0xB8, 0xBD, 0x3C, 0x2B, 0x8B, 0x95, + 0x98, 0xF5, 0xB3, 0xD1, 0x68, 0xCF, 0x20, 0x14, 0x7E, 0x4C, 0x5C, 0x5F, + 0xE7, 0x8B, 0xE5, 0xF5, 0x35, 0x81, 0x19, 0x37, 0xD7, 0x11, 0x08, 0xB7, + 0x66, 0xBE, 0xD3, 0x4A, 0xCE, 0x83, 0x57, 0x00, 0x3A, 0xC3, 0x81, 0xF8, + 0x17, 0xCB, 0x92, 0x36, 0x5D, 0xD1, 0xA3, 0xD8, 0x75, 0x1B, 0xE1, 0x8B, + 0x27, 0xEA, 0x7A, 0x48, 0x41, 0xFD, 0x45, 0x19, 0x06, 0xAD, 0x27, 0x99, + 0x4E, 0xC1, 0x70, 0x47, 0xDD, 0xB5, 0x9F, 0x81, 0x53, 0x12, 0xE5, 0xB1, + 0x8C, 0x48, 0x5D, 0x31, 0x43, 0x17, 0xE3, 0x8C, 0xC6, 0x7A, 0x63, 0x96, + 0x4B, 0x29, 0x30, 0x4E, 0x84, 0x4E, 0x62, 0x19, 0x5E, 0x3C, 0xCE, 0x97, + 0x90, 0xA5, 0x7F, 0x01, 0xEB, 0x9D, 0xE0, 0xF8, 0x8B, 0x89, 0xDD, 0x25, + 0x98, 0x3D, 0x92, 0xB6, 0x7E, 0xEF, 0xD9, 0xF1, 0x51, 0x51, 0x7D, 0x2D, + 0x26, 0xC8, 0x69, 0x59, 0x61, 0xE0, 0xAC, 0x6A, 0xB8, 0x2A, 0x36, 0x11, + 0x04, 0x7A, 0x50, 0xBD, 0x32, 0x84, 0xBE, 0x2F, 0xDC, 0x72, 0xD5, 0xD7, + 0x1D, 0x16, 0x47, 0xE4, 0x47, 0x66, 0x20, 0x3F, 0xF4, 0x96, 0xC5, 0xAF, + 0x8E, 0x01, 0x7A, 0xA5, 0x0F, 0x7A, 0x64, 0xF5, 0x0D, 0x18, 0x87, 0xD9, + 0xAE, 0x88, 0xD5, 0xFA, 0x84, 0xC1, 0x3A, 0xC0, 0x69, 0x28, 0x2D, 0xF2, + 0x0D, 0x68, 0x51, 0xAA, 0xE3, 0xA5, 0x77, 0xC6, 0xA4, 0x90, 0x0E, 0xA1, + 0x37, 0x8B, 0x31, 0x23, 0x47, 0xC1, 0x09, 0x08, 0xEB, 0x6E, 0xF7, 0x78, + 0x9B, 0xD7, 0x82, 0xFC, 0x84, 0x20, 0x99, 0x49, 0x19, 0xB6, 0x12, 0x46, + 0xB1, 0xFB, 0x45, 0x55, 0x16, 0xA9, 0xA3, 0x65, 0xAC, 0x9C, 0x07, 0x0F, + 0xEA, 0x6B, 0xDC, 0x1F, 0x2E, 0x06, 0x72, 0xEC, 0x86, 0x88, 0x12, 0xE4, + 0x2D, 0xDB, 0x5F, 0x05, 0x2F, 0xE4, 0xF0, 0x03, 0xD3, 0x26, 0x33, 0xE7, + 0x80, 0xC2, 0xCD, 0x42, 0xA1, 0x17, 0x34, 0x0B +}; + +static const unsigned char TA322_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA323_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x12, 0x48, 0x69, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA323_RSA_N[] = { + 0xF4, 0x1E, 0x7F, 0x52, 0x73, 0x32, 0x0C, 0x73, 0xE4, 0xBD, 0x13, 0x74, + 0xA3, 0xD4, 0x30, 0xA8, 0xD0, 0xAE, 0x4B, 0xD8, 0xB6, 0xDF, 0x75, 0x47, + 0x66, 0xF4, 0x7C, 0xE7, 0x39, 0x04, 0x1E, 0x6A, 0x70, 0x20, 0xD2, 0x5A, + 0x47, 0x72, 0x67, 0x55, 0xF4, 0xA5, 0xE8, 0x9D, 0xD5, 0x1E, 0x21, 0xA1, + 0xF0, 0x67, 0xBA, 0xCC, 0x21, 0x68, 0xBE, 0x44, 0x53, 0xBF, 0x8D, 0xF9, + 0xE2, 0xDC, 0x2F, 0x55, 0xC8, 0x37, 0x3F, 0x1F, 0xA4, 0xC0, 0x9C, 0xB3, + 0xE4, 0x77, 0x5C, 0xA0, 0x46, 0xFE, 0x77, 0xFA, 0x1A, 0xA0, 0x38, 0xEA, + 0xED, 0x9A, 0x72, 0xDE, 0x2B, 0xBD, 0x94, 0x57, 0x3A, 0xBA, 0xEC, 0x79, + 0xE7, 0x5F, 0x7D, 0x42, 0x64, 0x39, 0x7A, 0x26, 0x36, 0xF7, 0x24, 0xF0, + 0xD5, 0x2F, 0xBA, 0x95, 0x98, 0x11, 0x66, 0xAD, 0x97, 0x35, 0xD6, 0x75, + 0x01, 0x80, 0xE0, 0xAF, 0xF4, 0x84, 0x61, 0x8C, 0x0D, 0x1E, 0x5F, 0x7C, + 0x87, 0x96, 0x5E, 0x41, 0xAF, 0xEB, 0x87, 0xEA, 0xF8, 0x5D, 0xF1, 0x2E, + 0x88, 0x05, 0x3E, 0x4C, 0x22, 0xBB, 0xDA, 0x1F, 0x2A, 0xDD, 0x52, 0x46, + 0x64, 0x39, 0xF3, 0x42, 0xCE, 0xD9, 0x9E, 0x0C, 0xB3, 0xB0, 0x77, 0x97, + 0x64, 0x9C, 0xC0, 0xF4, 0xA3, 0x2E, 0x1F, 0x95, 0x07, 0xB0, 0x17, 0xDF, + 0x30, 0xDB, 0x00, 0x18, 0x96, 0x4C, 0xA1, 0x81, 0x4B, 0xDD, 0x04, 0x6D, + 0x53, 0xA3, 0x3D, 0xFC, 0x07, 0xAC, 0xD4, 0xC5, 0x37, 0x82, 0xEB, 0xE4, + 0x95, 0x08, 0x19, 0x28, 0x82, 0xD2, 0x42, 0x3A, 0xA3, 0xD8, 0x53, 0xEC, + 0x79, 0x89, 0x60, 0x48, 0x60, 0xC8, 0x72, 0x92, 0x50, 0xDC, 0x03, 0x8F, + 0x83, 0x3F, 0xB2, 0x42, 0x57, 0x5A, 0xDB, 0x6A, 0xE9, 0x11, 0x97, 0xDD, + 0x85, 0x28, 0xBC, 0x30, 0x4C, 0xAB, 0xE3, 0xC2, 0xB1, 0x45, 0x44, 0x47, + 0x1F, 0xE0, 0x8A, 0x16, 0x07, 0x96, 0xD2, 0x21, 0x0F, 0x53, 0xC0, 0xED, + 0xA9, 0x7E, 0xD4, 0x4E, 0xEC, 0x9B, 0x09, 0xEC, 0xAF, 0x42, 0xAC, 0x30, + 0xD6, 0xBF, 0xD1, 0x10, 0x45, 0xE0, 0xA6, 0x16, 0xB2, 0xA5, 0xC5, 0xD3, + 0x4F, 0x73, 0x94, 0x33, 0x71, 0x02, 0xA1, 0x6A, 0xA3, 0xD6, 0x33, 0x97, + 0x4F, 0x21, 0x63, 0x1E, 0x5B, 0x8F, 0xD9, 0xC1, 0x5E, 0x45, 0x71, 0x77, + 0x0F, 0x81, 0x5D, 0x5F, 0x21, 0x9A, 0xAD, 0x83, 0xCC, 0xFA, 0x5E, 0xD6, + 0x8D, 0x23, 0x5F, 0x1B, 0x3D, 0x41, 0xAF, 0x20, 0x75, 0x66, 0x5A, 0x4A, + 0xF6, 0x9F, 0xFB, 0xAB, 0x18, 0xF7, 0x71, 0xC0, 0xB6, 0x1D, 0x31, 0xEC, + 0x3B, 0x20, 0xEB, 0xCB, 0xE2, 0xB8, 0xF5, 0xAE, 0x92, 0xB2, 0xF7, 0xE1, + 0x84, 0x4B, 0xF2, 0xA2, 0xF2, 0x93, 0x9A, 0x22, 0x9E, 0xD3, 0x14, 0x6F, + 0x36, 0x54, 0xBD, 0x1F, 0x5E, 0x59, 0x15, 0xB9, 0x73, 0xA8, 0xC1, 0x7C, + 0x6F, 0x7B, 0x62, 0xE9, 0x16, 0x6C, 0x47, 0x5A, 0x65, 0xF3, 0x0E, 0x11, + 0x9B, 0x46, 0xD9, 0xFD, 0x6D, 0xDC, 0xD6, 0x9C, 0xC0, 0xB4, 0x7D, 0xA5, + 0xB0, 0xDD, 0x3F, 0x56, 0x6F, 0xA1, 0xF9, 0xF6, 0xE4, 0x12, 0x48, 0xFD, + 0x06, 0x7F, 0x12, 0x57, 0xB6, 0xA9, 0x23, 0x4F, 0x5B, 0x03, 0xC3, 0xE0, + 0x71, 0x2A, 0x23, 0xB7, 0xF7, 0xB0, 0xB1, 0x3B, 0xBC, 0x98, 0xBD, 0xD6, + 0x98, 0xA8, 0x0C, 0x6B, 0xF6, 0x8E, 0x12, 0x67, 0xA6, 0xF2, 0xB2, 0x58, + 0xE4, 0x02, 0x09, 0x13, 0x3C, 0xA9, 0xBB, 0x10, 0xB4, 0xD2, 0x30, 0x45, + 0xF1, 0xEC, 0xF7, 0x00, 0x11, 0xDF, 0x65, 0xF8, 0xDC, 0x2B, 0x43, 0x55, + 0xBF, 0x16, 0x97, 0xC4, 0x0F, 0xD5, 0x2C, 0x61, 0x84, 0xAA, 0x72, 0x86, + 0xFE, 0xE6, 0x3A, 0x7E, 0xC2, 0x3F, 0x7D, 0xEE, 0xFC, 0x2F, 0x14, 0x3E, + 0xE6, 0x85, 0xDD, 0x50, 0x6F, 0xB7, 0x49, 0xED +}; + +static const unsigned char TA323_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA324_DN[] = { + 0x30, 0x6F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x4B, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x09, 0x48, 0x6F, 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x48, 0x6F, + 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA324_RSA_N[] = { + 0xB3, 0x88, 0xD7, 0xEA, 0xCE, 0x0F, 0x20, 0x4E, 0xBE, 0xE6, 0xD6, 0x03, + 0x6D, 0xEE, 0x59, 0xFC, 0xC2, 0x57, 0xDF, 0x29, 0x68, 0xA1, 0x83, 0x0E, + 0x3E, 0x68, 0xC7, 0x68, 0x58, 0x9C, 0x1C, 0x60, 0x4B, 0x89, 0x43, 0x0C, + 0xB9, 0xD4, 0x15, 0xB2, 0xEE, 0xC1, 0x4E, 0x75, 0xE9, 0xB5, 0xA7, 0xEF, + 0xE5, 0xE9, 0x35, 0x99, 0xE4, 0xCC, 0x1C, 0xE7, 0x4B, 0x5F, 0x8D, 0x33, + 0x30, 0x20, 0x33, 0x53, 0xD9, 0xA6, 0xBB, 0xD5, 0x3E, 0x13, 0x8E, 0xE9, + 0x1F, 0x87, 0x49, 0xAD, 0x50, 0x2D, 0x50, 0xCA, 0x18, 0xBE, 0x01, 0x58, + 0xA2, 0x13, 0x70, 0x96, 0xBB, 0x89, 0x88, 0x56, 0x80, 0x5C, 0xF8, 0xBD, + 0x2C, 0x3C, 0xE1, 0x4C, 0x57, 0x88, 0xBB, 0xD3, 0xB9, 0x95, 0xEF, 0xCB, + 0xC7, 0xF6, 0xDA, 0x31, 0x74, 0x28, 0xA6, 0xE6, 0x54, 0x89, 0xF5, 0x41, + 0x31, 0xCA, 0xE5, 0x26, 0x1A, 0xCD, 0x82, 0xE0, 0x70, 0xDA, 0x3B, 0x29, + 0xBB, 0xD5, 0x03, 0xF5, 0x99, 0xBA, 0x55, 0xF5, 0x64, 0xD1, 0x60, 0x0E, + 0xB3, 0x89, 0x49, 0xB8, 0x8A, 0x2F, 0x05, 0xD2, 0x84, 0x45, 0x28, 0x7C, + 0x8F, 0x68, 0x50, 0x12, 0x78, 0xFC, 0x0B, 0xB5, 0x53, 0xCB, 0xC2, 0x98, + 0x1C, 0x84, 0xA3, 0x9E, 0xB0, 0xBE, 0x23, 0xA4, 0xDA, 0xDC, 0xC8, 0x2B, + 0x1E, 0xDA, 0x6E, 0x45, 0x1E, 0x89, 0x98, 0xDA, 0xF9, 0x00, 0x2E, 0x06, + 0xE9, 0x0C, 0x3B, 0x70, 0xD5, 0x50, 0x25, 0x88, 0x99, 0xCB, 0xCD, 0x73, + 0x60, 0xF7, 0xD5, 0xFF, 0x35, 0x67, 0xC5, 0xA1, 0xBC, 0x5E, 0xAB, 0xCD, + 0x4A, 0xB8, 0x45, 0xEB, 0xC8, 0x68, 0x1E, 0x0D, 0x0D, 0x14, 0x46, 0x12, + 0xE3, 0xD2, 0x64, 0x62, 0x8A, 0x42, 0x98, 0xBC, 0xB4, 0xC6, 0x08, 0x08, + 0xF8, 0xFD, 0xA8, 0x4C, 0x64, 0x9C, 0x76, 0x01, 0xBD, 0x2F, 0xA9, 0x6C, + 0x33, 0x0F, 0xD8, 0x3F, 0x28, 0xB8, 0x3C, 0x69, 0x01, 0x42, 0x86, 0x7E, + 0x69, 0xC1, 0xC9, 0x06, 0xCA, 0xE5, 0x7A, 0x46, 0x65, 0xE9, 0xC2, 0xD6, + 0x50, 0x41, 0x2E, 0x3F, 0xB7, 0xE4, 0xED, 0x6C, 0xD7, 0xBF, 0x26, 0x01, + 0x11, 0xA2, 0x16, 0x29, 0x4A, 0x6B, 0x34, 0x06, 0x90, 0xEC, 0x13, 0xD2, + 0xB6, 0xFB, 0x6A, 0x76, 0xD2, 0x3C, 0xED, 0xF0, 0xD6, 0x2D, 0xDD, 0xE1, + 0x15, 0xEC, 0xA3, 0x9B, 0x2F, 0x2C, 0xC9, 0x3E, 0x2B, 0xE4, 0x69, 0x3B, + 0xFF, 0x72, 0x25, 0xB1, 0x36, 0x86, 0x5B, 0xC7, 0x7F, 0x6B, 0x8B, 0x55, + 0x1B, 0x4A, 0xC5, 0x20, 0x61, 0x3D, 0xAE, 0xCB, 0x50, 0xE1, 0x08, 0x3A, + 0xBE, 0xB0, 0x8F, 0x63, 0x41, 0x53, 0x30, 0x08, 0x59, 0x3C, 0x98, 0x1D, + 0x77, 0xBA, 0x63, 0x91, 0x7A, 0xCA, 0x10, 0x50, 0x60, 0xBF, 0xF0, 0xD7, + 0xBC, 0x95, 0x87, 0x8F, 0x97, 0xC5, 0xFE, 0x97, 0x6A, 0x01, 0x94, 0xA3, + 0x7C, 0x5B, 0x85, 0x1D, 0x2A, 0x39, 0x3A, 0xD0, 0x54, 0xA1, 0xD1, 0x39, + 0x71, 0x9D, 0xFD, 0x21, 0xF9, 0xB5, 0x7B, 0xF0, 0xE2, 0xE0, 0x02, 0x8F, + 0x6E, 0x96, 0x24, 0x25, 0x2C, 0xA0, 0x1E, 0x2C, 0xA8, 0xC4, 0x89, 0xA7, + 0xEF, 0xED, 0x99, 0x06, 0x2F, 0xB6, 0x0A, 0x4C, 0x4F, 0xDB, 0xA2, 0xCC, + 0x37, 0x1A, 0xAF, 0x47, 0x85, 0x2D, 0x8A, 0x5F, 0xC4, 0x34, 0x34, 0x4C, + 0x00, 0xFD, 0x18, 0x93, 0x67, 0x13, 0xD1, 0x37, 0xE6, 0x48, 0xB4, 0x8B, + 0x06, 0xC5, 0x57, 0x7B, 0x19, 0x86, 0x0A, 0x79, 0xCB, 0x00, 0xC9, 0x52, + 0xAF, 0x42, 0xFF, 0x37, 0x8F, 0xE1, 0xA3, 0x1E, 0x7A, 0x3D, 0x50, 0xAB, + 0x63, 0x06, 0xE7, 0x15, 0xB5, 0x3F, 0xB6, 0x45, 0x37, 0x94, 0x37, 0xB1, + 0x7E, 0xF2, 0x48, 0xC3, 0x7F, 0xC5, 0x75, 0xFE, 0x97, 0x8D, 0x45, 0x8F, + 0x1A, 0xA7, 0x1A, 0x72, 0x28, 0x1A, 0x40, 0x0F +}; + +static const unsigned char TA324_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA325_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x31 +}; + +static const unsigned char TA325_RSA_N[] = { + 0xAD, 0xE8, 0x24, 0x73, 0xF4, 0x14, 0x37, 0xF3, 0x9B, 0x9E, 0x2B, 0x57, + 0x28, 0x1C, 0x87, 0xBE, 0xDC, 0xB7, 0xDF, 0x38, 0x90, 0x8C, 0x6E, 0x3C, + 0xE6, 0x57, 0xA0, 0x78, 0xF7, 0x75, 0xC2, 0xA2, 0xFE, 0xF5, 0x6A, 0x6E, + 0xF6, 0x00, 0x4F, 0x28, 0xDB, 0xDE, 0x68, 0x86, 0x6C, 0x44, 0x93, 0xB6, + 0xB1, 0x63, 0xFD, 0x14, 0x12, 0x6B, 0xBF, 0x1F, 0xD2, 0xEA, 0x31, 0x9B, + 0x21, 0x7E, 0xD1, 0x33, 0x3C, 0xBA, 0x48, 0xF5, 0xDD, 0x79, 0xDF, 0xB3, + 0xB8, 0xFF, 0x12, 0xF1, 0x21, 0x9A, 0x4B, 0xC1, 0x8A, 0x86, 0x71, 0x69, + 0x4A, 0x66, 0x66, 0x6C, 0x8F, 0x7E, 0x3C, 0x70, 0xBF, 0xAD, 0x29, 0x22, + 0x06, 0xF3, 0xE4, 0xC0, 0xE6, 0x80, 0xAE, 0xE2, 0x4B, 0x8F, 0xB7, 0x99, + 0x7E, 0x94, 0x03, 0x9F, 0xD3, 0x47, 0x97, 0x7C, 0x99, 0x48, 0x23, 0x53, + 0xE8, 0x38, 0xAE, 0x4F, 0x0A, 0x6F, 0x83, 0x2E, 0xD1, 0x49, 0x57, 0x8C, + 0x80, 0x74, 0xB6, 0xDA, 0x2F, 0xD0, 0x38, 0x8D, 0x7B, 0x03, 0x70, 0x21, + 0x1B, 0x75, 0xF2, 0x30, 0x3C, 0xFA, 0x8F, 0xAE, 0xDD, 0xDA, 0x63, 0xAB, + 0xEB, 0x16, 0x4F, 0xC2, 0x8E, 0x11, 0x4B, 0x7E, 0xCF, 0x0B, 0xE8, 0xFF, + 0xB5, 0x77, 0x2E, 0xF4, 0xB2, 0x7B, 0x4A, 0xE0, 0x4C, 0x12, 0x25, 0x0C, + 0x70, 0x8D, 0x03, 0x29, 0xA0, 0xE1, 0x53, 0x24, 0xEC, 0x13, 0xD9, 0xEE, + 0x19, 0xBF, 0x10, 0xB3, 0x4A, 0x8C, 0x3F, 0x89, 0xA3, 0x61, 0x51, 0xDE, + 0xAC, 0x87, 0x07, 0x94, 0xF4, 0x63, 0x71, 0xEC, 0x2E, 0xE2, 0x6F, 0x5B, + 0x98, 0x81, 0xE1, 0x89, 0x5C, 0x34, 0x79, 0x6C, 0x76, 0xEF, 0x3B, 0x90, + 0x62, 0x79, 0xE6, 0xDB, 0xA4, 0x9A, 0x2F, 0x26, 0xC5, 0xD0, 0x10, 0xE1, + 0x0E, 0xDE, 0xD9, 0x10, 0x8E, 0x16, 0xFB, 0xB7, 0xF7, 0xA8, 0xF7, 0xC7, + 0xE5, 0x02, 0x07, 0x98, 0x8F, 0x36, 0x08, 0x95, 0xE7, 0xE2, 0x37, 0x96, + 0x0D, 0x36, 0x75, 0x9E, 0xFB, 0x0E, 0x72, 0xB1, 0x1D, 0x9B, 0xBC, 0x03, + 0xF9, 0x49, 0x05, 0xD8, 0x81, 0xDD, 0x05, 0xB4, 0x2A, 0xD6, 0x41, 0xE9, + 0xAC, 0x01, 0x76, 0x95, 0x0A, 0x0F, 0xD8, 0xDF, 0xD5, 0xBD, 0x12, 0x1F, + 0x35, 0x2F, 0x28, 0x17, 0x6C, 0xD2, 0x98, 0xC1, 0xA8, 0x09, 0x64, 0x77, + 0x6E, 0x47, 0x37, 0xBA, 0xCE, 0xAC, 0x59, 0x5E, 0x68, 0x9D, 0x7F, 0x72, + 0xD6, 0x89, 0xC5, 0x06, 0x41, 0x29, 0x3E, 0x59, 0x3E, 0xDD, 0x26, 0xF5, + 0x24, 0xC9, 0x11, 0xA7, 0x5A, 0xA3, 0x4C, 0x40, 0x1F, 0x46, 0xA1, 0x99, + 0xB5, 0xA7, 0x3A, 0x51, 0x6E, 0x86, 0x3B, 0x9E, 0x7D, 0x72, 0xA7, 0x12, + 0x05, 0x78, 0x59, 0xED, 0x3E, 0x51, 0x78, 0x15, 0x0B, 0x03, 0x8F, 0x8D, + 0xD0, 0x2F, 0x05, 0xB2, 0x3E, 0x7B, 0x4A, 0x1C, 0x4B, 0x73, 0x05, 0x12, + 0xFC, 0xC6, 0xEA, 0xE0, 0x50, 0x13, 0x7C, 0x43, 0x93, 0x74, 0xB3, 0xCA, + 0x74, 0xE7, 0x8E, 0x1F, 0x01, 0x08, 0xD0, 0x30, 0xD4, 0x5B, 0x71, 0x36, + 0xB4, 0x07, 0xBA, 0xC1, 0x30, 0x30, 0x5C, 0x48, 0xB7, 0x82, 0x3B, 0x98, + 0xA6, 0x7D, 0x60, 0x8A, 0xA2, 0xA3, 0x29, 0x82, 0xCC, 0xBA, 0xBD, 0x83, + 0x04, 0x1B, 0xA2, 0x83, 0x03, 0x41, 0xA1, 0xD6, 0x05, 0xF1, 0x1B, 0xC2, + 0xB6, 0xF0, 0xA8, 0x7C, 0x86, 0x3B, 0x46, 0xA8, 0x48, 0x2A, 0x88, 0xDC, + 0x76, 0x9A, 0x76, 0xBF, 0x1F, 0x6A, 0xA5, 0x3D, 0x19, 0x8F, 0xEB, 0x38, + 0xF3, 0x64, 0xDE, 0xC8, 0x2B, 0x0D, 0x0A, 0x28, 0xFF, 0xF7, 0xDB, 0xE2, + 0x15, 0x42, 0xD4, 0x22, 0xD0, 0x27, 0x5D, 0xE1, 0x79, 0xFE, 0x18, 0xE7, + 0x70, 0x88, 0xAD, 0x4E, 0xE6, 0xD9, 0x8B, 0x3A, 0xC6, 0xDD, 0x27, 0x51, + 0x6E, 0xFF, 0xBC, 0x64, 0xF5, 0x33, 0x43, 0x4F +}; + +static const unsigned char TA325_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA326_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x32 +}; + +static const unsigned char TA326_EC_Q[] = { + 0x04, 0xCD, 0x9B, 0xD5, 0x9F, 0x80, 0x83, 0x0A, 0xEC, 0x09, 0x4A, 0xF3, + 0x16, 0x4A, 0x3E, 0x5C, 0xCF, 0x77, 0xAC, 0xDE, 0x67, 0x05, 0x0D, 0x1D, + 0x07, 0xB6, 0xDC, 0x16, 0xFB, 0x5A, 0x8B, 0x14, 0xDB, 0xE2, 0x71, 0x60, + 0xC4, 0xBA, 0x45, 0x95, 0x11, 0x89, 0x8E, 0xEA, 0x06, 0xDF, 0xF7, 0x2A, + 0x16, 0x1C, 0xA4, 0xB9, 0xC5, 0xC5, 0x32, 0xE0, 0x03, 0xE0, 0x1E, 0x82, + 0x18, 0x38, 0x8B, 0xD7, 0x45, 0xD8, 0x0A, 0x6A, 0x6E, 0xE6, 0x00, 0x77, + 0xFB, 0x02, 0x51, 0x7D, 0x22, 0xD8, 0x0A, 0x6E, 0x9A, 0x5B, 0x77, 0xDF, + 0xF0, 0xFA, 0x41, 0xEC, 0x39, 0xDC, 0x75, 0xCA, 0x68, 0x07, 0x0C, 0x1F, + 0xEA +}; + +static const unsigned char TA327_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6F, 0x6D, 0x6D, + 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA327_RSA_N[] = { + 0xA7, 0x50, 0x19, 0xDE, 0x3F, 0x99, 0x3D, 0xD4, 0x33, 0x46, 0xF1, 0x6F, + 0x51, 0x61, 0x82, 0xB2, 0xA9, 0x4F, 0x8F, 0x67, 0x89, 0x5D, 0x84, 0xD9, + 0x53, 0xDD, 0x0C, 0x28, 0xD9, 0xD7, 0xF0, 0xFF, 0xAE, 0x95, 0x43, 0x72, + 0x99, 0xF9, 0xB5, 0x5D, 0x7C, 0x8A, 0xC1, 0x42, 0xE1, 0x31, 0x50, 0x74, + 0xD1, 0x81, 0x0D, 0x7C, 0xCD, 0x9B, 0x21, 0xAB, 0x43, 0xE2, 0xAC, 0xAD, + 0x5E, 0x86, 0x6E, 0xF3, 0x09, 0x8A, 0x1F, 0x5A, 0x32, 0xBD, 0xA2, 0xEB, + 0x94, 0xF9, 0xE8, 0x5C, 0x0A, 0xEC, 0xFF, 0x98, 0xD2, 0xAF, 0x71, 0xB3, + 0xB4, 0x53, 0x9F, 0x4E, 0x87, 0xEF, 0x92, 0xBC, 0xBD, 0xEC, 0x4F, 0x32, + 0x30, 0x88, 0x4B, 0x17, 0x5E, 0x57, 0xC4, 0x53, 0xC2, 0xF6, 0x02, 0x97, + 0x8D, 0xD9, 0x62, 0x2B, 0xBF, 0x24, 0x1F, 0x62, 0x8D, 0xDF, 0xC3, 0xB8, + 0x29, 0x4B, 0x49, 0x78, 0x3C, 0x93, 0x60, 0x88, 0x22, 0xFC, 0x99, 0xDA, + 0x36, 0xC8, 0xC2, 0xA2, 0xD4, 0x2C, 0x54, 0x00, 0x67, 0x35, 0x6E, 0x73, + 0xBF, 0x02, 0x58, 0xF0, 0xA4, 0xDD, 0xE5, 0xB0, 0xA2, 0x26, 0x7A, 0xCA, + 0xE0, 0x36, 0xA5, 0x19, 0x16, 0xF5, 0xFD, 0xB7, 0xEF, 0xAE, 0x3F, 0x40, + 0xF5, 0x6D, 0x5A, 0x04, 0xFD, 0xCE, 0x34, 0xCA, 0x24, 0xDC, 0x74, 0x23, + 0x1B, 0x5D, 0x33, 0x13, 0x12, 0x5D, 0xC4, 0x01, 0x25, 0xF6, 0x30, 0xDD, + 0x02, 0x5D, 0x9F, 0xE0, 0xD5, 0x47, 0xBD, 0xB4, 0xEB, 0x1B, 0xA1, 0xBB, + 0x49, 0x49, 0xD8, 0x9F, 0x5B, 0x02, 0xF3, 0x8A, 0xE4, 0x24, 0x90, 0xE4, + 0x62, 0x4F, 0x4F, 0xC1, 0xAF, 0x8B, 0x0E, 0x74, 0x17, 0xA8, 0xD1, 0x72, + 0x88, 0x6A, 0x7A, 0x01, 0x49, 0xCC, 0xB4, 0x46, 0x79, 0xC6, 0x17, 0xB1, + 0xDA, 0x98, 0x1E, 0x07, 0x59, 0xFA, 0x75, 0x21, 0x85, 0x65, 0xDD, 0x90, + 0x56, 0xCE, 0xFB, 0xAB, 0xA5, 0x60, 0x9D, 0xC4, 0x9D, 0xF9, 0x52, 0xB0, + 0x8B, 0xBD, 0x87, 0xF9, 0x8F, 0x2B, 0x23, 0x0A, 0x23, 0x76, 0x3B, 0xF7, + 0x33, 0xE1, 0xC9, 0x00, 0xF3, 0x69, 0xF9, 0x4B, 0xA2, 0xE0, 0x4E, 0xBC, + 0x7E, 0x93, 0x39, 0x84, 0x07, 0xF7, 0x44, 0x70, 0x7E, 0xFE, 0x07, 0x5A, + 0xE5, 0xB1, 0xAC, 0xD1, 0x18, 0xCC, 0xF2, 0x35, 0xE5, 0x49, 0x49, 0x08, + 0xCA, 0x56, 0xC9, 0x3D, 0xFB, 0x0F, 0x18, 0x7D, 0x8B, 0x3B, 0xC1, 0x13, + 0xC2, 0x4D, 0x8F, 0xC9, 0x4F, 0x0E, 0x37, 0xE9, 0x1F, 0xA1, 0x0E, 0x6A, + 0xDF, 0x62, 0x2E, 0xCB, 0x35, 0x06, 0x51, 0x79, 0x2C, 0xC8, 0x25, 0x38, + 0xF4, 0xFA, 0x4B, 0xA7, 0x89, 0x5C, 0x9C, 0xD2, 0xE3, 0x0D, 0x39, 0x86, + 0x4A, 0x74, 0x7C, 0xD5, 0x59, 0x87, 0xC2, 0x3F, 0x4E, 0x0C, 0x5C, 0x52, + 0xF4, 0x3D, 0xF7, 0x52, 0x82, 0xF1, 0xEA, 0xA3, 0xAC, 0xFD, 0x49, 0x34, + 0x1A, 0x28, 0xF3, 0x41, 0x88, 0x3A, 0x13, 0xEE, 0xE8, 0xDE, 0xFF, 0x99, + 0x1D, 0x5F, 0xBA, 0xCB, 0xE8, 0x1E, 0xF2, 0xB9, 0x50, 0x60, 0xC0, 0x31, + 0xD3, 0x73, 0xE5, 0xEF, 0xBE, 0xA0, 0xED, 0x33, 0x0B, 0x74, 0xBE, 0x20, + 0x20, 0xC4, 0x67, 0x6C, 0xF0, 0x08, 0x03, 0x7A, 0x55, 0x80, 0x7F, 0x46, + 0x4E, 0x96, 0xA7, 0xF4, 0x1E, 0x3E, 0xE1, 0xF6, 0xD8, 0x09, 0xE1, 0x33, + 0x64, 0x2B, 0x63, 0xD7, 0x32, 0x5E, 0x9F, 0xF9, 0xC0, 0x7B, 0x0F, 0x78, + 0x6F, 0x97, 0xBC, 0x93, 0x9A, 0xF9, 0x9C, 0x12, 0x90, 0x78, 0x7A, 0x80, + 0x87, 0x15, 0xD7, 0x72, 0x74, 0x9C, 0x55, 0x74, 0x78, 0xB1, 0xBA, 0xE1, + 0x6E, 0x70, 0x04, 0xBA, 0x4F, 0xA0, 0xBA, 0x68, 0xC3, 0x7B, 0xFF, 0x31, + 0xF0, 0x73, 0x3D, 0x3D, 0x94, 0x2A, 0xB1, 0x0B, 0x41, 0x0E, 0xA0, 0xFE, + 0x4D, 0x88, 0x65, 0x6B, 0x79, 0x33, 0xB4, 0xD7 +}; + +static const unsigned char TA327_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA328_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x53, 0x65, 0x63, 0x74, 0x6F, 0x72, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA328_RSA_N[] = { + 0xB6, 0x22, 0x94, 0xFC, 0xA4, 0x48, 0xAF, 0xE8, 0x47, 0x6B, 0x0A, 0xFB, + 0x27, 0x76, 0xE4, 0xF2, 0x3F, 0x8A, 0x3B, 0x7A, 0x4A, 0x2C, 0x31, 0x2A, + 0x8C, 0x8D, 0xB0, 0xA9, 0xC3, 0x31, 0x6B, 0xA8, 0x77, 0x76, 0x84, 0x26, + 0xB6, 0xAC, 0x81, 0x42, 0x0D, 0x08, 0xEB, 0x55, 0x58, 0xBB, 0x7A, 0xF8, + 0xBC, 0x65, 0x7D, 0xF2, 0xA0, 0x6D, 0x8B, 0xA8, 0x47, 0xE9, 0x62, 0x76, + 0x1E, 0x11, 0xEE, 0x08, 0x14, 0xD1, 0xB2, 0x44, 0x16, 0xF4, 0xEA, 0xD0, + 0xFA, 0x1E, 0x2F, 0x5E, 0xDB, 0xCB, 0x73, 0x41, 0xAE, 0xBC, 0x00, 0xB0, + 0x4A, 0x2B, 0x40, 0xB2, 0xAC, 0xE1, 0x3B, 0x4B, 0xC2, 0x2D, 0x9D, 0xE4, + 0xA1, 0x9B, 0xEC, 0x1A, 0x3A, 0x1E, 0xF0, 0x08, 0xB3, 0xD0, 0xE4, 0x24, + 0x35, 0x07, 0x9F, 0x9C, 0xB4, 0xC9, 0x52, 0x6D, 0xDB, 0x07, 0xCA, 0x8F, + 0xB5, 0x5B, 0xF0, 0x83, 0xF3, 0x4F, 0xC7, 0x2D, 0xA5, 0xC8, 0xAD, 0xCB, + 0x95, 0x20, 0xA4, 0x31, 0x28, 0x57, 0x58, 0x5A, 0xE4, 0x8D, 0x1B, 0x9A, + 0xAB, 0x9E, 0x0D, 0x0C, 0xF2, 0x0A, 0x33, 0x39, 0x22, 0x39, 0x0A, 0x97, + 0x2E, 0xF3, 0x53, 0x77, 0xB9, 0x44, 0x45, 0xFD, 0x84, 0xCB, 0x36, 0x20, + 0x81, 0x59, 0x2D, 0x9A, 0x6F, 0x6D, 0x48, 0x48, 0x61, 0xCA, 0x4C, 0xDF, + 0x53, 0xD1, 0xAF, 0x52, 0xBC, 0x44, 0x9F, 0xAB, 0x2F, 0x6B, 0x83, 0x72, + 0xEF, 0x75, 0x80, 0xDA, 0x06, 0x33, 0x1B, 0x5D, 0xC8, 0xDA, 0x63, 0xC6, + 0x4D, 0xCD, 0xAC, 0x66, 0x31, 0xCD, 0xD1, 0xDE, 0x3E, 0x87, 0x10, 0x36, + 0xE1, 0xB9, 0xA4, 0x7A, 0xEF, 0x60, 0x50, 0xB2, 0xCB, 0xCA, 0xA6, 0x56, + 0xE0, 0x37, 0xAF, 0xAB, 0x34, 0x13, 0x39, 0x25, 0xE8, 0x39, 0x66, 0xE4, + 0x98, 0x7A, 0xAA, 0x12, 0x98, 0x9C, 0x59, 0x66, 0x86, 0x3E, 0xAD, 0xF1, + 0xB0, 0xCA, 0x3E, 0x06, 0x0F, 0x7B, 0xF0, 0x11, 0x4B, 0x37, 0xA0, 0x44, + 0x6D, 0x7B, 0xCB, 0xA8, 0x8C, 0x71, 0xF4, 0xD5, 0xB5, 0x91, 0x36, 0xCC, + 0xF0, 0x15, 0xC6, 0x2B, 0xDE, 0x51, 0x17, 0xB1, 0x97, 0x4C, 0x50, 0x3D, + 0xB1, 0x95, 0x59, 0x7C, 0x05, 0x7D, 0x2D, 0x21, 0xD5, 0x00, 0xBF, 0x01, + 0x67, 0xA2, 0x5E, 0x7B, 0xA6, 0x5C, 0xF2, 0xF7, 0x22, 0xF1, 0x90, 0x0D, + 0x93, 0xDB, 0xAA, 0x44, 0x51, 0x66, 0xCC, 0x7D, 0x76, 0x03, 0xEB, 0x6A, + 0xA8, 0x2A, 0x38, 0x19, 0x97, 0x76, 0x0D, 0x6B, 0x8A, 0x61, 0xF9, 0xBC, + 0xF6, 0xEE, 0x76, 0xFD, 0x70, 0x2B, 0xDD, 0x29, 0x3C, 0xF8, 0x0A, 0x1E, + 0x5B, 0x42, 0x1C, 0x8B, 0x56, 0x2F, 0x55, 0x1B, 0x1C, 0xA1, 0x2E, 0xB5, + 0xC7, 0x16, 0xE6, 0xF8, 0xAA, 0x3C, 0x92, 0x8E, 0x69, 0xB6, 0x01, 0xC1, + 0xB5, 0x86, 0x9D, 0x89, 0x0F, 0x0B, 0x38, 0x94, 0x54, 0xE8, 0xEA, 0xDC, + 0x9E, 0x3D, 0x25, 0xBC, 0x53, 0x26, 0xED, 0xD5, 0xAB, 0x39, 0xAA, 0xC5, + 0x40, 0x4C, 0x54, 0xAB, 0xB2, 0xB4, 0xD9, 0xD9, 0xF8, 0xD7, 0x72, 0xDB, + 0x1C, 0xBC, 0x6D, 0xBD, 0x65, 0x5F, 0xEF, 0x88, 0x35, 0x2A, 0x66, 0x2F, + 0xEE, 0xF6, 0xB3, 0x65, 0xF0, 0x33, 0x8D, 0x7C, 0x98, 0x41, 0x69, 0x46, + 0x0F, 0x43, 0x1C, 0x69, 0xFA, 0x9B, 0xB5, 0xD0, 0x61, 0x6A, 0xCD, 0xCA, + 0x4B, 0xD9, 0x4C, 0x90, 0x46, 0xAB, 0x15, 0x59, 0xA1, 0x47, 0x54, 0x29, + 0x2E, 0x83, 0x28, 0x5F, 0x1C, 0xC2, 0xA2, 0xAB, 0x72, 0x17, 0x00, 0x06, + 0x8E, 0x45, 0xEC, 0x8B, 0xE2, 0x33, 0x3D, 0x7F, 0xDA, 0x19, 0x44, 0xE4, + 0x62, 0x72, 0xC3, 0xDF, 0x22, 0xC6, 0xF2, 0x56, 0xD4, 0xDD, 0x5F, 0x95, + 0x72, 0xED, 0x6D, 0x5F, 0xF7, 0x48, 0x03, 0x5B, 0xFD, 0xC5, 0x2A, 0xA0, + 0xF6, 0x73, 0x23, 0x84, 0x10, 0x1B, 0x01, 0xE7 +}; + +static const unsigned char TA328_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA329_DN[] = { + 0x30, 0x38, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x49, 0x5A, 0x45, 0x4E, 0x50, 0x45, 0x20, 0x53, 0x2E, 0x41, + 0x2E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0A, + 0x49, 0x7A, 0x65, 0x6E, 0x70, 0x65, 0x2E, 0x63, 0x6F, 0x6D +}; + +static const unsigned char TA329_RSA_N[] = { + 0xC9, 0xD3, 0x7A, 0xCA, 0x0F, 0x1E, 0xAC, 0xA7, 0x86, 0xE8, 0x16, 0x65, + 0x6A, 0xB1, 0xC2, 0x1B, 0x45, 0x32, 0x71, 0x95, 0xD9, 0xFE, 0x10, 0x5B, + 0xCC, 0xAF, 0xE7, 0xA5, 0x79, 0x01, 0x8F, 0x89, 0xC3, 0xCA, 0xF2, 0x55, + 0x71, 0xF7, 0x77, 0xBE, 0x77, 0x94, 0xF3, 0x72, 0xA4, 0x2C, 0x44, 0xD8, + 0x9E, 0x92, 0x9B, 0x14, 0x3A, 0xA1, 0xE7, 0x24, 0x90, 0x0A, 0x0A, 0x56, + 0x8E, 0xC5, 0xD8, 0x26, 0x94, 0xE1, 0xD9, 0x48, 0xE1, 0x2D, 0x3E, 0xDA, + 0x0A, 0x72, 0xDD, 0xA3, 0x99, 0x15, 0xDA, 0x81, 0xA2, 0x87, 0xF4, 0x7B, + 0x6E, 0x26, 0x77, 0x89, 0x58, 0xAD, 0xD6, 0xEB, 0x0C, 0xB2, 0x41, 0x7A, + 0x73, 0x6E, 0x6D, 0xDB, 0x7A, 0x78, 0x41, 0xE9, 0x08, 0x88, 0x12, 0x7E, + 0x87, 0x2E, 0x66, 0x11, 0x63, 0x6C, 0x54, 0xFB, 0x3C, 0x9D, 0x72, 0xC0, + 0xBC, 0x2E, 0xFF, 0xC2, 0xB7, 0xDD, 0x0D, 0x76, 0xE3, 0x3A, 0xD7, 0xF7, + 0xB4, 0x68, 0xBE, 0xA2, 0xF5, 0xE3, 0x81, 0x6E, 0xC1, 0x46, 0x6F, 0x5D, + 0x8D, 0xE0, 0x4D, 0xC6, 0x54, 0x55, 0x89, 0x1A, 0x33, 0x31, 0x0A, 0xB1, + 0x57, 0xB9, 0xA3, 0x8A, 0x98, 0xC3, 0xEC, 0x3B, 0x34, 0xC5, 0x95, 0x41, + 0x69, 0x7E, 0x75, 0xC2, 0x3C, 0x20, 0xC5, 0x61, 0xBA, 0x51, 0x47, 0xA0, + 0x20, 0x90, 0x93, 0xA1, 0x90, 0x4B, 0xF3, 0x4E, 0x7C, 0x85, 0x45, 0x54, + 0x9A, 0xD1, 0x05, 0x26, 0x41, 0xB0, 0xB5, 0x4D, 0x1D, 0x33, 0xBE, 0xC4, + 0x03, 0xC8, 0x25, 0x7C, 0xC1, 0x70, 0xDB, 0x3B, 0xF4, 0x09, 0x2D, 0x54, + 0x27, 0x48, 0xAC, 0x2F, 0xE1, 0xC4, 0xAC, 0x3E, 0xC8, 0xCB, 0x92, 0x4C, + 0x53, 0x39, 0x37, 0x23, 0xEC, 0xD3, 0x01, 0xF9, 0xE0, 0x09, 0x44, 0x4D, + 0x4D, 0x64, 0xC0, 0xE1, 0x0D, 0x5A, 0x87, 0x22, 0xBC, 0xAD, 0x1B, 0xA3, + 0xFE, 0x26, 0xB5, 0x15, 0xF3, 0xA7, 0xFC, 0x84, 0x19, 0xE9, 0xEC, 0xA1, + 0x88, 0xB4, 0x44, 0x69, 0x84, 0x83, 0xF3, 0x89, 0xD1, 0x74, 0x06, 0xA9, + 0xCC, 0x0B, 0xD6, 0xC2, 0xDE, 0x27, 0x85, 0x50, 0x26, 0xCA, 0x17, 0xB8, + 0xC9, 0x7A, 0x87, 0x56, 0x2C, 0x1A, 0x01, 0x1E, 0x6C, 0xBE, 0x13, 0xAD, + 0x10, 0xAC, 0xB5, 0x24, 0xF5, 0x38, 0x91, 0xA1, 0xD6, 0x4B, 0xDA, 0xF1, + 0xBB, 0xD2, 0xDE, 0x47, 0xB5, 0xF1, 0xBC, 0x81, 0xF6, 0x59, 0x6B, 0xCF, + 0x19, 0x53, 0xE9, 0x8D, 0x15, 0xCB, 0x4A, 0xCB, 0xA9, 0x6F, 0x44, 0xE5, + 0x1B, 0x41, 0xCF, 0xE1, 0x86, 0xA7, 0xCA, 0xD0, 0x6A, 0x9F, 0xBC, 0x4C, + 0x8D, 0x06, 0x33, 0x5A, 0xA2, 0x85, 0xE5, 0x90, 0x35, 0xA0, 0x62, 0x5C, + 0x16, 0x4E, 0xF0, 0xE3, 0xA2, 0xFA, 0x03, 0x1A, 0xB4, 0x2C, 0x71, 0xB3, + 0x58, 0x2C, 0xDE, 0x7B, 0x0B, 0xDB, 0x1A, 0x0F, 0xEB, 0xDE, 0x21, 0x1F, + 0x06, 0x77, 0x06, 0x03, 0xB0, 0xC9, 0xEF, 0x99, 0xFC, 0xC0, 0xB9, 0x4F, + 0x0B, 0x86, 0x28, 0xFE, 0xD2, 0xB9, 0xEA, 0xE3, 0xDA, 0xA5, 0xC3, 0x47, + 0x69, 0x12, 0xE0, 0xDB, 0xF0, 0xF6, 0x19, 0x8B, 0xED, 0x7B, 0x70, 0xD7, + 0x02, 0xD6, 0xED, 0x87, 0x18, 0x28, 0x2C, 0x04, 0x24, 0x4C, 0x77, 0xE4, + 0x48, 0x8A, 0x1A, 0xC6, 0x3B, 0x9A, 0xD4, 0x0F, 0xCA, 0xFA, 0x75, 0xD2, + 0x01, 0x40, 0x5A, 0x8D, 0x79, 0xBF, 0x8B, 0xCF, 0x4B, 0xCF, 0xAA, 0x16, + 0xC1, 0x95, 0xE4, 0xAD, 0x4C, 0x8A, 0x3E, 0x17, 0x91, 0xD4, 0xB1, 0x62, + 0xE5, 0x82, 0xE5, 0x80, 0x04, 0xA4, 0x03, 0x7E, 0x8D, 0xBF, 0xDA, 0x7F, + 0xA2, 0x0F, 0x97, 0x4F, 0x0C, 0xD3, 0x0D, 0xFB, 0xD7, 0xD1, 0xE5, 0x72, + 0x7E, 0x1C, 0xC8, 0x77, 0xFF, 0x5B, 0x9A, 0x0F, 0xB7, 0xAE, 0x05, 0x46, + 0xE5, 0xF1, 0xA8, 0x16, 0xEC, 0x47, 0xA4, 0x17 +}; + +static const unsigned char TA329_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA330_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x65, 0x2D, 0x53, 0x7A, 0x69, + 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x32, 0x30, 0x30, 0x39, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x65, 0x2D, 0x73, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x2E, 0x68, + 0x75 +}; + +static const unsigned char TA330_RSA_N[] = { + 0xE9, 0xF8, 0x8F, 0xF3, 0x63, 0xAD, 0xDA, 0x86, 0xD8, 0xA7, 0xE0, 0x42, + 0xFB, 0xCF, 0x91, 0xDE, 0xA6, 0x26, 0xF8, 0x99, 0xA5, 0x63, 0x70, 0xAD, + 0x9B, 0xAE, 0xCA, 0x33, 0x40, 0x7D, 0x6D, 0x96, 0x6E, 0xA1, 0x0E, 0x44, + 0xEE, 0xE1, 0x13, 0x9D, 0x94, 0x42, 0x52, 0x9A, 0xBD, 0x75, 0x85, 0x74, + 0x2C, 0xA8, 0x0E, 0x1D, 0x93, 0xB6, 0x18, 0xB7, 0x8C, 0x2C, 0xA8, 0xCF, + 0xFB, 0x5C, 0x71, 0xB9, 0xDA, 0xEC, 0xFE, 0xE8, 0x7E, 0x8F, 0xE4, 0x2F, + 0x1D, 0xB2, 0xA8, 0x75, 0x87, 0xD8, 0xB7, 0xA1, 0xE5, 0x3B, 0xCF, 0x99, + 0x4A, 0x46, 0xD0, 0x83, 0x19, 0x7D, 0xC0, 0xA1, 0x12, 0x1C, 0x95, 0x6D, + 0x4A, 0xF4, 0xD8, 0xC7, 0xA5, 0x4D, 0x33, 0x2E, 0x85, 0x39, 0x40, 0x75, + 0x7E, 0x14, 0x7C, 0x80, 0x12, 0x98, 0x50, 0xC7, 0x41, 0x67, 0xB8, 0xA0, + 0x80, 0x61, 0x54, 0xA6, 0x6C, 0x4E, 0x1F, 0xE0, 0x9D, 0x0E, 0x07, 0xE9, + 0xC9, 0xBA, 0x33, 0xE7, 0xFE, 0xC0, 0x55, 0x28, 0x2C, 0x02, 0x80, 0xA7, + 0x19, 0xF5, 0x9E, 0xDC, 0x55, 0x53, 0x03, 0x97, 0x7B, 0x07, 0x48, 0xFF, + 0x99, 0xFB, 0x37, 0x8A, 0x24, 0xC4, 0x59, 0xCC, 0x50, 0x10, 0x63, 0x8E, + 0xAA, 0xA9, 0x1A, 0xB0, 0x84, 0x1A, 0x86, 0xF9, 0x5F, 0xBB, 0xB1, 0x50, + 0x6E, 0xA4, 0xD1, 0x0A, 0xCC, 0xD5, 0x71, 0x7E, 0x1F, 0xA7, 0x1B, 0x7C, + 0xF5, 0x53, 0x6E, 0x22, 0x5F, 0xCB, 0x2B, 0xE6, 0xD4, 0x7C, 0x5D, 0xAE, + 0xD6, 0xC2, 0xC6, 0x4C, 0xE5, 0x05, 0x01, 0xD9, 0xED, 0x57, 0xFC, 0xC1, + 0x23, 0x79, 0xFC, 0xFA, 0xC8, 0x24, 0x83, 0x95, 0xF3, 0xB5, 0x6A, 0x51, + 0x01, 0xD0, 0x77, 0xD6, 0xE9, 0x12, 0xA1, 0xF9, 0x1A, 0x83, 0xFB, 0x82, + 0x1B, 0xB9, 0xB0, 0x97, 0xF4, 0x76, 0x06, 0x33, 0x43, 0x49, 0xA0, 0xFF, + 0x0B, 0xB5, 0xFA, 0xB5 +}; + +static const unsigned char TA330_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA331_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA331_EC_Q[] = { + 0x04, 0xD4, 0xBC, 0x3D, 0x02, 0x42, 0x75, 0x41, 0x13, 0x23, 0xCD, 0x80, + 0x04, 0x86, 0x02, 0x51, 0x2F, 0x6A, 0xA8, 0x81, 0x62, 0x0B, 0x65, 0xCC, + 0xF6, 0xCA, 0x9D, 0x1E, 0x6F, 0x4A, 0x66, 0x51, 0xA2, 0x03, 0xD9, 0x9D, + 0x91, 0xFA, 0xB6, 0x16, 0xB1, 0x8C, 0x6E, 0xDE, 0x7C, 0xCD, 0xDB, 0x79, + 0xA6, 0x2F, 0xCE, 0xBB, 0xCE, 0x71, 0x2F, 0xE5, 0xA5, 0xAB, 0x28, 0xEC, + 0x63, 0x04, 0x66, 0x99, 0xF8, 0xFA, 0xF2, 0x93, 0x10, 0x05, 0xE1, 0x81, + 0x28, 0x42, 0xE3, 0xC6, 0x68, 0xF4, 0xE6, 0x1B, 0x84, 0x60, 0x4A, 0x89, + 0xAF, 0xED, 0x79, 0x0F, 0x3B, 0xCE, 0xF1, 0xF6, 0x44, 0xF5, 0x01, 0x78, + 0xC0 +}; + +static const unsigned char TA332_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA332_RSA_N[] = { + 0xCA, 0x5B, 0xBE, 0x94, 0x33, 0x8C, 0x29, 0x95, 0x91, 0x16, 0x0A, 0x95, + 0xBD, 0x47, 0x62, 0xC1, 0x89, 0xF3, 0x99, 0x36, 0xDF, 0x46, 0x90, 0xC9, + 0xA5, 0xED, 0x78, 0x6A, 0x6F, 0x47, 0x91, 0x68, 0xF8, 0x27, 0x67, 0x50, + 0x33, 0x1D, 0xA1, 0xA6, 0xFB, 0xE0, 0xE5, 0x43, 0xA3, 0x84, 0x02, 0x57, + 0x01, 0x5D, 0x9C, 0x48, 0x40, 0x82, 0x53, 0x10, 0xBC, 0xBF, 0xC7, 0x3B, + 0x68, 0x90, 0xB6, 0x82, 0x2D, 0xE5, 0xF4, 0x65, 0xD0, 0xCC, 0x6D, 0x19, + 0xCC, 0x95, 0xF9, 0x7B, 0xAC, 0x4A, 0x94, 0xAD, 0x0E, 0xDE, 0x4B, 0x43, + 0x1D, 0x87, 0x07, 0x92, 0x13, 0x90, 0x80, 0x83, 0x64, 0x35, 0x39, 0x04, + 0xFC, 0xE5, 0xE9, 0x6C, 0xB3, 0xB6, 0x1F, 0x50, 0x94, 0x38, 0x65, 0x50, + 0x5C, 0x17, 0x46, 0xB9, 0xB6, 0x85, 0xB5, 0x1C, 0xB5, 0x17, 0xE8, 0xD6, + 0x45, 0x9D, 0xD8, 0xB2, 0x26, 0xB0, 0xCA, 0xC4, 0x70, 0x4A, 0xAE, 0x60, + 0xA4, 0xDD, 0xB3, 0xD9, 0xEC, 0xFC, 0x3B, 0xD5, 0x57, 0x72, 0xBC, 0x3F, + 0xC8, 0xC9, 0xB2, 0xDE, 0x4B, 0x6B, 0xF8, 0x23, 0x6C, 0x03, 0xC0, 0x05, + 0xBD, 0x95, 0xC7, 0xCD, 0x73, 0x3B, 0x66, 0x80, 0x64, 0xE3, 0x1A, 0xAC, + 0x2E, 0xF9, 0x47, 0x05, 0xF2, 0x06, 0xB6, 0x9B, 0x73, 0xF5, 0x78, 0x33, + 0x5B, 0xC7, 0xA1, 0xFB, 0x27, 0x2A, 0xA1, 0xB4, 0x9A, 0x91, 0x8C, 0x91, + 0xD3, 0x3A, 0x82, 0x3E, 0x76, 0x40, 0xB4, 0xCD, 0x52, 0x61, 0x51, 0x70, + 0x28, 0x3F, 0xC5, 0xC5, 0x5A, 0xF2, 0xC9, 0x8C, 0x49, 0xBB, 0x14, 0x5B, + 0x4D, 0xC8, 0xFF, 0x67, 0x4D, 0x4C, 0x12, 0x96, 0xAD, 0xF5, 0xFE, 0x78, + 0xA8, 0x97, 0x87, 0xD7, 0xFD, 0x5E, 0x20, 0x80, 0xDC, 0xA1, 0x4B, 0x22, + 0xFB, 0xD4, 0x89, 0xAD, 0xBA, 0xCE, 0x47, 0x97, 0x47, 0x55, 0x7B, 0x8F, + 0x45, 0xC8, 0x67, 0x28, 0x84, 0x95, 0x1C, 0x68, 0x30, 0xEF, 0xEF, 0x49, + 0xE0, 0x35, 0x7B, 0x64, 0xE7, 0x98, 0xB0, 0x94, 0xDA, 0x4D, 0x85, 0x3B, + 0x3E, 0x55, 0xC4, 0x28, 0xAF, 0x57, 0xF3, 0x9E, 0x13, 0xDB, 0x46, 0x27, + 0x9F, 0x1E, 0xA2, 0x5E, 0x44, 0x83, 0xA4, 0xA5, 0xCA, 0xD5, 0x13, 0xB3, + 0x4B, 0x3F, 0xC4, 0xE3, 0xC2, 0xE6, 0x86, 0x61, 0xA4, 0x52, 0x30, 0xB9, + 0x7A, 0x20, 0x4F, 0x6F, 0x0F, 0x38, 0x53, 0xCB, 0x33, 0x0C, 0x13, 0x2B, + 0x8F, 0xD6, 0x9A, 0xBD, 0x2A, 0xC8, 0x2D, 0xB1, 0x1C, 0x7D, 0x4B, 0x51, + 0xCA, 0x47, 0xD1, 0x48, 0x27, 0x72, 0x5D, 0x87, 0xEB, 0xD5, 0x45, 0xE6, + 0x48, 0x65, 0x9D, 0xAF, 0x52, 0x90, 0xBA, 0x5B, 0xA2, 0x18, 0x65, 0x57, + 0x12, 0x9F, 0x68, 0xB9, 0xD4, 0x15, 0x6B, 0x94, 0xC4, 0x69, 0x22, 0x98, + 0xF4, 0x33, 0xE0, 0xED, 0xF9, 0x51, 0x8E, 0x41, 0x50, 0xC9, 0x34, 0x4F, + 0x76, 0x90, 0xAC, 0xFC, 0x38, 0xC1, 0xD8, 0xE1, 0x7B, 0xB9, 0xE3, 0xE3, + 0x94, 0xE1, 0x46, 0x69, 0xCB, 0x0E, 0x0A, 0x50, 0x6B, 0x13, 0xBA, 0xAC, + 0x0F, 0x37, 0x5A, 0xB7, 0x12, 0xB5, 0x90, 0x81, 0x1E, 0x56, 0xAE, 0x57, + 0x22, 0x86, 0xD9, 0xC9, 0xD2, 0xD1, 0xD7, 0x51, 0xE3, 0xAB, 0x3B, 0xC6, + 0x55, 0xFD, 0x1E, 0x0E, 0xD3, 0x74, 0x0A, 0xD1, 0xDA, 0xAA, 0xEA, 0x69, + 0xB8, 0x97, 0x28, 0x8F, 0x48, 0xC4, 0x07, 0xF8, 0x52, 0x43, 0x3A, 0xF4, + 0xCA, 0x55, 0x35, 0x2C, 0xB0, 0xA6, 0x6A, 0xC0, 0x9C, 0xF9, 0xF2, 0x81, + 0xE1, 0x12, 0x6A, 0xC0, 0x45, 0xD9, 0x67, 0xB3, 0xCE, 0xFF, 0x23, 0xA2, + 0x89, 0x0A, 0x54, 0xD4, 0x14, 0xB9, 0x2A, 0xA8, 0xD7, 0xEC, 0xF9, 0xAB, + 0xCD, 0x25, 0x58, 0x32, 0x79, 0x8F, 0x90, 0x5B, 0x98, 0x39, 0xC4, 0x08, + 0x06, 0xC1, 0xAC, 0x7F, 0x0E, 0x3D, 0x00, 0xA5 +}; + +static const unsigned char TA332_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA333_DN[] = { + 0x30, 0x69, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4B, 0x52, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, 0x42, 0x55, 0x53, 0x49, + 0x4E, 0x45, 0x53, 0x53, 0x20, 0x50, 0x4C, 0x41, 0x54, 0x46, 0x4F, 0x52, + 0x4D, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA333_RSA_N[] = { + 0xB6, 0xD4, 0xF1, 0x93, 0x5C, 0xB5, 0x40, 0x89, 0x0A, 0xAB, 0x0D, 0x90, + 0x5B, 0x50, 0x63, 0xAE, 0x90, 0x94, 0x74, 0x17, 0x45, 0x72, 0xD6, 0x7B, + 0x65, 0x5A, 0x29, 0x4B, 0xA7, 0x56, 0xA0, 0x4B, 0xB8, 0x2F, 0x42, 0x75, + 0xE9, 0xD9, 0x7B, 0x24, 0x5A, 0x31, 0x65, 0xAB, 0x17, 0x17, 0xD1, 0x33, + 0x3A, 0xD9, 0x11, 0xDC, 0x40, 0x36, 0x87, 0xDF, 0xC7, 0x6A, 0xE9, 0x26, + 0x5E, 0x59, 0x8A, 0x77, 0xE3, 0xE8, 0x48, 0x9C, 0x31, 0x16, 0xFA, 0x3E, + 0x91, 0xB1, 0xCA, 0xC9, 0xA3, 0xE2, 0x9F, 0xCE, 0x21, 0x53, 0xA3, 0x02, + 0x36, 0x30, 0xCB, 0x52, 0x02, 0xE5, 0xDA, 0x32, 0x5D, 0xC3, 0xC5, 0xE6, + 0xF9, 0xEE, 0x11, 0xC7, 0x8B, 0xC9, 0x44, 0x1E, 0x84, 0x93, 0x18, 0x4A, + 0xB4, 0x9F, 0xE5, 0x12, 0x64, 0x69, 0xD0, 0x26, 0x85, 0x62, 0x01, 0xB6, + 0xC9, 0x02, 0x1D, 0xBE, 0x83, 0x51, 0xBB, 0x5C, 0xDA, 0xF8, 0xAD, 0x15, + 0x6A, 0x99, 0xF7, 0x92, 0x54, 0xF7, 0x34, 0x5B, 0xE9, 0xBF, 0xEA, 0x29, + 0x81, 0x12, 0xD4, 0x53, 0x91, 0x96, 0xB3, 0x91, 0x5A, 0xDD, 0xFE, 0x90, + 0x73, 0x28, 0xFB, 0x30, 0x46, 0xB5, 0xCA, 0x08, 0x07, 0xC7, 0x71, 0x72, + 0xC9, 0x66, 0xD3, 0x34, 0x97, 0xF6, 0x8C, 0xF4, 0x18, 0x4A, 0xE1, 0xD0, + 0x3D, 0x5A, 0x45, 0xB6, 0x69, 0xA7, 0x29, 0xFB, 0x23, 0xCE, 0x88, 0xD8, + 0x12, 0x9C, 0x00, 0x48, 0xA8, 0xA6, 0x0F, 0xB3, 0x3B, 0x92, 0x8D, 0x71, + 0x0E, 0x74, 0xC5, 0x8B, 0xC8, 0x4C, 0xF9, 0xF4, 0x9B, 0x8E, 0xB8, 0x3C, + 0x69, 0xED, 0x6F, 0x3B, 0x50, 0x2F, 0x58, 0xED, 0xC4, 0xB0, 0xD0, 0x1C, + 0x1B, 0x6A, 0x0C, 0xE2, 0xBC, 0x44, 0xAA, 0xD8, 0xCD, 0x14, 0x5D, 0x94, + 0x78, 0x61, 0xBF, 0x0E, 0x6E, 0xDA, 0x2A, 0xBC, 0x2F, 0x0C, 0x0B, 0x71, + 0xA6, 0xB3, 0x16, 0x3F, 0x9C, 0xE6, 0xF9, 0xCC, 0x9F, 0x53, 0x35, 0xE2, + 0x03, 0xA0, 0xA0, 0x18, 0xBF, 0xBB, 0xF1, 0xBE, 0xF4, 0xD6, 0x8C, 0x87, + 0x0D, 0x42, 0xF7, 0x06, 0xB9, 0xF1, 0x6D, 0xED, 0x04, 0x94, 0xA8, 0xFE, + 0xB6, 0xD3, 0x06, 0xC6, 0x40, 0x61, 0xDF, 0x9D, 0x9D, 0xF3, 0x54, 0x76, + 0xCE, 0x53, 0x3A, 0x01, 0xA6, 0x92, 0x41, 0xEC, 0x04, 0xA3, 0x8F, 0x0D, + 0xA2, 0xD5, 0x09, 0xCA, 0xD6, 0xCB, 0x9A, 0xF1, 0xEF, 0x43, 0x5D, 0xC0, + 0xAB, 0xA5, 0x41, 0xCF, 0x5C, 0x53, 0x70, 0x70, 0xC9, 0x88, 0xA6, 0x2D, + 0xD4, 0x6B, 0x61, 0x73, 0x50, 0x26, 0x86, 0x61, 0x0E, 0x5F, 0x1B, 0xC2, + 0x2B, 0xE2, 0x8C, 0xD5, 0xBB, 0x9D, 0xC1, 0x03, 0x42, 0xBA, 0x94, 0xDA, + 0x5F, 0xA9, 0xB0, 0xCA, 0xCC, 0x4D, 0x0A, 0xEF, 0x47, 0x69, 0x03, 0x2F, + 0x22, 0xFB, 0xF1, 0x28, 0xCE, 0xBF, 0x5D, 0x50, 0x65, 0xA8, 0x90, 0x6D, + 0xB3, 0x74, 0xB0, 0x08, 0xC7, 0xAC, 0xA8, 0xD1, 0xEB, 0x3E, 0x9C, 0xFC, + 0x5D, 0x1A, 0x83, 0x2E, 0x2B, 0xCB, 0xB5, 0xF3, 0x44, 0x9D, 0x3A, 0xA7, + 0x17, 0x61, 0x96, 0xA2, 0x71, 0xD3, 0x70, 0x96, 0x15, 0x4D, 0xB7, 0x4C, + 0x73, 0xEE, 0x19, 0x5C, 0xC5, 0x5B, 0x3E, 0x41, 0xFE, 0xAC, 0x75, 0x60, + 0x3B, 0x1B, 0x63, 0xCE, 0x00, 0xDD, 0xDA, 0x08, 0x90, 0x62, 0xB4, 0xE5, + 0x2D, 0xEE, 0x48, 0xA7, 0x6B, 0x17, 0x99, 0x54, 0xBE, 0x87, 0x4A, 0xE3, + 0xA9, 0x5E, 0x04, 0x4C, 0xEB, 0x10, 0x6D, 0x54, 0xD6, 0xEF, 0xF1, 0xE8, + 0xF2, 0x62, 0x16, 0xCB, 0x80, 0x6B, 0xED, 0x3D, 0xED, 0xF5, 0x1F, 0x30, + 0xA5, 0xAE, 0x4B, 0xC9, 0x13, 0xED, 0x8A, 0x01, 0x01, 0xC9, 0xB8, 0x51, + 0x58, 0xC0, 0x66, 0x3A, 0xB1, 0x66, 0x4B, 0xC4, 0xD5, 0x31, 0x02, 0x62, + 0xE9, 0x74, 0x84, 0x0C, 0xDB, 0x4D, 0x46, 0x2D +}; + +static const unsigned char TA333_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA334_DN[] = { + 0x30, 0x81, 0xA7, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x4E, 0x65, + 0x74, 0x4C, 0x6F, 0x63, 0x6B, 0x20, 0x4B, 0x66, 0x74, 0x2E, 0x31, 0x37, + 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x2E, 0x54, 0x61, 0x6E, + 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, 0x6E, 0x79, 0x6B, + 0x69, 0x61, 0x64, 0xC3, 0xB3, 0x6B, 0x20, 0x28, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x29, 0x31, 0x35, 0x30, 0x33, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x2C, 0x4E, 0x65, 0x74, 0x4C, 0x6F, 0x63, + 0x6B, 0x20, 0x41, 0x72, 0x61, 0x6E, 0x79, 0x20, 0x28, 0x43, 0x6C, 0x61, + 0x73, 0x73, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x29, 0x20, 0x46, 0xC5, 0x91, + 0x74, 0x61, 0x6E, 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, + 0x6E, 0x79 +}; + +static const unsigned char TA334_RSA_N[] = { + 0xC4, 0x24, 0x5E, 0x73, 0xBE, 0x4B, 0x6D, 0x14, 0xC3, 0xA1, 0xF4, 0xE3, + 0x97, 0x90, 0x6E, 0xD2, 0x30, 0x45, 0x1E, 0x3C, 0xEE, 0x67, 0xD9, 0x64, + 0xE0, 0x1A, 0x8A, 0x7F, 0xCA, 0x30, 0xCA, 0x83, 0xE3, 0x20, 0xC1, 0xE3, + 0xF4, 0x3A, 0xD3, 0x94, 0x5F, 0x1A, 0x7C, 0x5B, 0x6D, 0xBF, 0x30, 0x4F, + 0x84, 0x27, 0xF6, 0x9F, 0x1F, 0x49, 0xBC, 0xC6, 0x99, 0x0A, 0x90, 0xF2, + 0x0F, 0xF5, 0x7F, 0x43, 0x84, 0x37, 0x63, 0x51, 0x8B, 0x7A, 0xA5, 0x70, + 0xFC, 0x7A, 0x58, 0xCD, 0x8E, 0x9B, 0xED, 0xC3, 0x46, 0x6C, 0x84, 0x70, + 0x5D, 0xDA, 0xF3, 0x01, 0x90, 0x23, 0xFC, 0x4E, 0x30, 0xA9, 0x7E, 0xE1, + 0x27, 0x63, 0xE7, 0xED, 0x64, 0x3C, 0xA0, 0xB8, 0xC9, 0x33, 0x63, 0xFE, + 0x16, 0x90, 0xFF, 0xB0, 0xB8, 0xFD, 0xD7, 0xA8, 0xC0, 0xC0, 0x94, 0x43, + 0x0B, 0xB6, 0xD5, 0x59, 0xA6, 0x9E, 0x56, 0xD0, 0x24, 0x1F, 0x70, 0x79, + 0xAF, 0xDB, 0x39, 0x54, 0x0D, 0x65, 0x75, 0xD9, 0x15, 0x41, 0x94, 0x01, + 0xAF, 0x5E, 0xEC, 0xF6, 0x8D, 0xF1, 0xFF, 0xAD, 0x64, 0xFE, 0x20, 0x9A, + 0xD7, 0x5C, 0xEB, 0xFE, 0xA6, 0x1F, 0x08, 0x64, 0xA3, 0x8B, 0x76, 0x55, + 0xAD, 0x1E, 0x3B, 0x28, 0x60, 0x2E, 0x87, 0x25, 0xE8, 0xAA, 0xAF, 0x1F, + 0xC6, 0x64, 0x46, 0x20, 0xB7, 0x70, 0x7F, 0x3C, 0xDE, 0x48, 0xDB, 0x96, + 0x53, 0xB7, 0x39, 0x77, 0xE4, 0x1A, 0xE2, 0xC7, 0x16, 0x84, 0x76, 0x97, + 0x5B, 0x2F, 0xBB, 0x19, 0x15, 0x85, 0xF8, 0x69, 0x85, 0xF5, 0x99, 0xA7, + 0xA9, 0xF2, 0x34, 0xA7, 0xA9, 0xB6, 0xA6, 0x03, 0xFC, 0x6F, 0x86, 0x3D, + 0x54, 0x7C, 0x76, 0x04, 0x9B, 0x6B, 0xF9, 0x40, 0x5D, 0x00, 0x34, 0xC7, + 0x2E, 0x99, 0x75, 0x9D, 0xE5, 0x88, 0x03, 0xAA, 0x4D, 0xF8, 0x03, 0xD2, + 0x42, 0x76, 0xC0, 0x1B +}; + +static const unsigned char TA334_RSA_E[] = { + 0xA8, 0x8B +}; + +static const unsigned char TA335_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x42, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA335_RSA_N[] = { + 0xD8, 0x17, 0xB7, 0x1C, 0x4A, 0x24, 0x2A, 0xD6, 0x97, 0xB1, 0xCA, 0xE2, + 0x1E, 0xFB, 0x7D, 0x38, 0xEF, 0x98, 0xF5, 0xB2, 0x39, 0x98, 0x4E, 0x27, + 0xB8, 0x11, 0x5D, 0x7B, 0xD2, 0x25, 0x94, 0x88, 0x82, 0x15, 0x26, 0x6A, + 0x1B, 0x31, 0xBB, 0xA8, 0x5B, 0x21, 0x21, 0x2B, 0xD8, 0x0F, 0x4E, 0x9F, + 0x5A, 0xF1, 0xB1, 0x5A, 0xE4, 0x79, 0xD6, 0x32, 0x23, 0x2B, 0xE1, 0x53, + 0xCC, 0x99, 0x45, 0x5C, 0x7B, 0x4F, 0xAD, 0xBC, 0xBF, 0x87, 0x4A, 0x0B, + 0x4B, 0x97, 0x5A, 0xA8, 0xF6, 0x48, 0xEC, 0x7D, 0x7B, 0x0D, 0xCD, 0x21, + 0x06, 0xDF, 0x9E, 0x15, 0xFD, 0x41, 0x8A, 0x48, 0xB7, 0x20, 0xF4, 0xA1, + 0x7A, 0x1B, 0x57, 0xD4, 0x5D, 0x50, 0xFF, 0xBA, 0x67, 0xD8, 0x23, 0x99, + 0x1F, 0xC8, 0x3F, 0xE3, 0xDE, 0xFF, 0x6F, 0x5B, 0x77, 0xB1, 0x6B, 0x6E, + 0xB8, 0xC9, 0x64, 0xF7, 0xE1, 0xCA, 0x41, 0x46, 0x0E, 0x29, 0x71, 0xD0, + 0xB9, 0x23, 0xFC, 0xC9, 0x81, 0x5F, 0x4E, 0xF7, 0x6F, 0xDF, 0xBF, 0x84, + 0xAD, 0x73, 0x64, 0xBB, 0xB7, 0x42, 0x8E, 0x69, 0xF6, 0xD4, 0x76, 0x1D, + 0x7E, 0x9D, 0xA7, 0xB8, 0x57, 0x8A, 0x51, 0x67, 0x72, 0xD7, 0xD4, 0xA8, + 0xB8, 0x95, 0x54, 0x40, 0x73, 0x03, 0xF6, 0xEA, 0xF4, 0xEB, 0xFE, 0x28, + 0x42, 0x77, 0x3F, 0x9D, 0x23, 0x1B, 0xB2, 0xB6, 0x3D, 0x80, 0x14, 0x07, + 0x4C, 0x2E, 0x4F, 0xF7, 0xD5, 0x0A, 0x16, 0x0D, 0xBD, 0x66, 0x43, 0x37, + 0x7E, 0x23, 0x43, 0x79, 0xC3, 0x40, 0x86, 0xF5, 0x4C, 0x29, 0xDA, 0x8E, + 0x9A, 0xAD, 0x0D, 0xA5, 0x04, 0x87, 0x88, 0x1E, 0x85, 0xE3, 0xE9, 0x53, + 0xD5, 0x9B, 0xC8, 0x8B, 0x03, 0x63, 0x78, 0xEB, 0xE0, 0x19, 0x4A, 0x6E, + 0xBB, 0x2F, 0x6B, 0x33, 0x64, 0x58, 0x93, 0xAD, 0x69, 0xBF, 0x8F, 0x1B, + 0xEF, 0x82, 0x48, 0xC7 +}; + +static const unsigned char TA335_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA336_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x43, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA336_EC_Q[] = { + 0x04, 0x4C, 0xE9, 0x50, 0xC0, 0xC6, 0x0F, 0x72, 0x18, 0xBC, 0xD8, 0xF1, + 0xBA, 0xB3, 0x89, 0xE2, 0x79, 0x4A, 0xA3, 0x16, 0xA7, 0x6B, 0x54, 0x24, + 0xDB, 0x51, 0xFF, 0xEA, 0xF4, 0x09, 0x24, 0xC3, 0x0B, 0x22, 0x9F, 0xCB, + 0x6A, 0x27, 0x82, 0x81, 0x0D, 0xD2, 0xC0, 0xAF, 0x31, 0xE4, 0x74, 0x82, + 0x6E, 0xCA, 0x25, 0xD9, 0x8C, 0x75, 0x9D, 0xF1, 0xDB, 0xD0, 0x9A, 0xA2, + 0x4B, 0x21, 0x7E, 0x16, 0xA7, 0x63, 0x90, 0xD2, 0x39, 0xD4, 0xB1, 0x87, + 0x78, 0x5F, 0x18, 0x96, 0x0F, 0x50, 0x1B, 0x35, 0x37, 0x0F, 0x6A, 0xC6, + 0xDC, 0xD9, 0x13, 0x4D, 0xA4, 0x8E, 0x90, 0x37, 0xE6, 0xBD, 0x5B, 0x31, + 0x91 +}; + +static const unsigned char TA337_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA337_RSA_N[] = { + 0xA0, 0xBE, 0x50, 0x10, 0x8E, 0xE9, 0xF2, 0x6C, 0x40, 0xB4, 0x04, 0x9C, + 0x85, 0xB9, 0x31, 0xCA, 0xDC, 0x2D, 0xE4, 0x11, 0xA9, 0x04, 0x3C, 0x1B, + 0x55, 0xC1, 0xE7, 0x58, 0x30, 0x1D, 0x24, 0xB4, 0xC3, 0xEF, 0x85, 0xDE, + 0x8C, 0x2C, 0xE1, 0xC1, 0x3D, 0xDF, 0x82, 0xE6, 0x4F, 0xAD, 0x47, 0x87, + 0x6C, 0xEC, 0x5B, 0x49, 0xC1, 0x4A, 0xD5, 0xBB, 0x8F, 0xEC, 0x87, 0xAC, + 0x7F, 0x82, 0x9A, 0x86, 0xEC, 0x3D, 0x03, 0x99, 0x52, 0x01, 0xD2, 0x35, + 0x9E, 0xAC, 0xDA, 0xF0, 0x53, 0xC9, 0x66, 0x3C, 0xD4, 0xAC, 0x02, 0x01, + 0xDA, 0x24, 0xD3, 0x3B, 0xA8, 0x02, 0x46, 0xAF, 0xA4, 0x1C, 0xE3, 0xF8, + 0x73, 0x58, 0x76, 0xB7, 0xF6, 0x0E, 0x90, 0x0D, 0xB5, 0xF0, 0xCF, 0xCC, + 0xFA, 0xF9, 0xC6, 0x4C, 0xE5, 0xC3, 0x86, 0x30, 0x0A, 0x8D, 0x17, 0x7E, + 0x35, 0xEB, 0xC5, 0xDF, 0xBB, 0x0E, 0x9C, 0xC0, 0x8D, 0x87, 0xE3, 0x88, + 0x38, 0x85, 0x67, 0xFA, 0x3E, 0xC7, 0xAB, 0xE0, 0x13, 0x9C, 0x05, 0x18, + 0x98, 0xCF, 0x93, 0xF5, 0xB1, 0x92, 0xB4, 0xFC, 0x23, 0xD3, 0xCF, 0xD5, + 0xC4, 0x27, 0x49, 0xE0, 0x9E, 0x3C, 0x9B, 0x08, 0xA3, 0x8B, 0x5D, 0x2A, + 0x21, 0xE0, 0xFC, 0x39, 0xAA, 0x53, 0xDA, 0x7D, 0x7E, 0xCF, 0x1A, 0x09, + 0x53, 0xBC, 0x5D, 0x05, 0x04, 0xCF, 0xA1, 0x4A, 0x8F, 0x8B, 0x76, 0x82, + 0x0D, 0xA1, 0xF8, 0xD2, 0xC7, 0x14, 0x77, 0x5B, 0x90, 0x36, 0x07, 0x81, + 0x9B, 0x3E, 0x06, 0xFA, 0x52, 0x5E, 0x63, 0xC5, 0xA6, 0x00, 0xFE, 0xA5, + 0xE9, 0x52, 0x1B, 0x52, 0xB5, 0x92, 0x39, 0x72, 0x03, 0x09, 0x62, 0xBD, + 0xB0, 0x60, 0x16, 0x6E, 0xA6, 0xDD, 0x25, 0xC2, 0x03, 0x66, 0xDD, 0xF3, + 0x04, 0xD1, 0x40, 0xE2, 0x4E, 0x8B, 0x86, 0xF4, 0x6F, 0xE5, 0x83, 0xA0, + 0x27, 0x84, 0x5E, 0x04, 0xC1, 0xF5, 0x90, 0xBD, 0x30, 0x3D, 0xC4, 0xEF, + 0xA8, 0x69, 0xBC, 0x38, 0x9B, 0xA4, 0xA4, 0x96, 0xD1, 0x62, 0xDA, 0x69, + 0xC0, 0x01, 0x96, 0xAE, 0xCB, 0xC4, 0x51, 0x34, 0xEA, 0x0C, 0xAA, 0xFF, + 0x21, 0x8E, 0x59, 0x8F, 0x4A, 0x5C, 0xE4, 0x61, 0x9A, 0xA7, 0xD2, 0xE9, + 0x2A, 0x78, 0x8D, 0x51, 0x3D, 0x3A, 0x15, 0xEE, 0xA2, 0x59, 0x8E, 0xA9, + 0x5C, 0xDE, 0xC5, 0xF9, 0x90, 0x22, 0xE5, 0x88, 0x45, 0x71, 0xDD, 0x91, + 0x99, 0x6C, 0x7A, 0x9F, 0x3D, 0x3D, 0x98, 0x7C, 0x5E, 0xF6, 0xBE, 0x16, + 0x68, 0xA0, 0x5E, 0xAE, 0x0B, 0x23, 0xFC, 0x5A, 0x0F, 0xAA, 0x22, 0x76, + 0x2D, 0xC9, 0xA1, 0x10, 0x1D, 0xE4, 0xD3, 0x44, 0x23, 0x90, 0x88, 0x9F, + 0xC6, 0x2A, 0xE6, 0xD7, 0xF5, 0x9A, 0xB3, 0x58, 0x1E, 0x2F, 0x30, 0x89, + 0x08, 0x1B, 0x54, 0xA2, 0xB5, 0x98, 0x23, 0xEC, 0x08, 0x77, 0x1C, 0x95, + 0x5D, 0x61, 0xD1, 0xCB, 0x89, 0x9C, 0x5F, 0xA2, 0x4A, 0x91, 0x9A, 0xEF, + 0x21, 0xAA, 0x49, 0x16, 0x08, 0xA8, 0xBD, 0x61, 0x28, 0x31, 0xC9, 0x74, + 0xAD, 0x85, 0xF6, 0xD9, 0xC5, 0xB1, 0x8B, 0xD1, 0xE5, 0x10, 0x32, 0x4D, + 0x5F, 0x8B, 0x20, 0x3A, 0x3C, 0x49, 0x1F, 0x33, 0x85, 0x59, 0x0D, 0xDB, + 0xCB, 0x09, 0x75, 0x43, 0x69, 0x73, 0xFB, 0x6B, 0x71, 0x7D, 0xF0, 0xDF, + 0xC4, 0x4C, 0x7D, 0xC6, 0xA3, 0x2E, 0xC8, 0x95, 0x79, 0xCB, 0x73, 0xA2, + 0x8E, 0x4E, 0x4D, 0x24, 0xFB, 0x5E, 0xE4, 0x04, 0xBE, 0x72, 0x1B, 0xA6, + 0x27, 0x2D, 0x49, 0x5A, 0x99, 0x7A, 0xD7, 0x5C, 0x09, 0x20, 0xB7, 0x7F, + 0x94, 0xB9, 0x4F, 0xF1, 0x0D, 0x1C, 0x5E, 0x88, 0x42, 0x1B, 0x11, 0xB7, + 0xE7, 0x91, 0xDB, 0x9E, 0x6C, 0xF4, 0x6A, 0xDF, 0x8C, 0x06, 0x98, 0x03, + 0xAD, 0xCC, 0x28, 0xEF, 0xA5, 0x47, 0xF3, 0x53 +}; + +static const unsigned char TA337_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA338_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA338_RSA_N[] = { + 0x9A, 0x18, 0xCA, 0x4B, 0x94, 0x0D, 0x00, 0x2D, 0xAF, 0x03, 0x29, 0x8A, + 0xF0, 0x0F, 0x81, 0xC8, 0xAE, 0x4C, 0x19, 0x85, 0x1D, 0x08, 0x9F, 0xAB, + 0x29, 0x44, 0x85, 0xF3, 0x2F, 0x81, 0xAD, 0x32, 0x1E, 0x90, 0x46, 0xBF, + 0xA3, 0x86, 0x26, 0x1A, 0x1E, 0xFE, 0x7E, 0x1C, 0x18, 0x3A, 0x5C, 0x9C, + 0x60, 0x17, 0x2A, 0x3A, 0x74, 0x83, 0x33, 0x30, 0x7D, 0x61, 0x54, 0x11, + 0xCB, 0xED, 0xAB, 0xE0, 0xE6, 0xD2, 0xA2, 0x7E, 0xF5, 0x6B, 0x6F, 0x18, + 0xB7, 0x0A, 0x0B, 0x2D, 0xFD, 0xE9, 0x3E, 0xEF, 0x0A, 0xC6, 0xB3, 0x10, + 0xE9, 0xDC, 0xC2, 0x46, 0x17, 0xF8, 0x5D, 0xFD, 0xA4, 0xDA, 0xFF, 0x9E, + 0x49, 0x5A, 0x9C, 0xE6, 0x33, 0xE6, 0x24, 0x96, 0xF7, 0x3F, 0xBA, 0x5B, + 0x2B, 0x1C, 0x7A, 0x35, 0xC2, 0xD6, 0x67, 0xFE, 0xAB, 0x66, 0x50, 0x8B, + 0x6D, 0x28, 0x60, 0x2B, 0xEF, 0xD7, 0x60, 0xC3, 0xC7, 0x93, 0xBC, 0x8D, + 0x36, 0x91, 0xF3, 0x7F, 0xF8, 0xDB, 0x11, 0x13, 0xC4, 0x9C, 0x77, 0x76, + 0xC1, 0xAE, 0xB7, 0x02, 0x6A, 0x81, 0x7A, 0xA9, 0x45, 0x83, 0xE2, 0x05, + 0xE6, 0xB9, 0x56, 0xC1, 0x94, 0x37, 0x8F, 0x48, 0x71, 0x63, 0x22, 0xEC, + 0x17, 0x65, 0x07, 0x95, 0x8A, 0x4B, 0xDF, 0x8F, 0xC6, 0x5A, 0x0A, 0xE5, + 0xB0, 0xE3, 0x5F, 0x5E, 0x6B, 0x11, 0xAB, 0x0C, 0xF9, 0x85, 0xEB, 0x44, + 0xE9, 0xF8, 0x04, 0x73, 0xF2, 0xE9, 0xFE, 0x5C, 0x98, 0x8C, 0xF5, 0x73, + 0xAF, 0x6B, 0xB4, 0x7E, 0xCD, 0xD4, 0x5C, 0x02, 0x2B, 0x4C, 0x39, 0xE1, + 0xB2, 0x95, 0x95, 0x2D, 0x42, 0x87, 0xD7, 0xD5, 0xB3, 0x90, 0x43, 0xB7, + 0x6C, 0x13, 0xF1, 0xDE, 0xDD, 0xF6, 0xC4, 0xF8, 0x89, 0x3F, 0xD1, 0x75, + 0xF5, 0x92, 0xC3, 0x91, 0xD5, 0x8A, 0x88, 0xD0, 0x90, 0xEC, 0xDC, 0x6D, + 0xDE, 0x89, 0xC2, 0x65, 0x71, 0x96, 0x8B, 0x0D, 0x03, 0xFD, 0x9C, 0xBF, + 0x5B, 0x16, 0xAC, 0x92, 0xDB, 0xEA, 0xFE, 0x79, 0x7C, 0xAD, 0xEB, 0xAF, + 0xF7, 0x16, 0xCB, 0xDB, 0xCD, 0x25, 0x2B, 0xE5, 0x1F, 0xFB, 0x9A, 0x9F, + 0xE2, 0x51, 0xCC, 0x3A, 0x53, 0x0C, 0x48, 0xE6, 0x0E, 0xBD, 0xC9, 0xB4, + 0x76, 0x06, 0x52, 0xE6, 0x11, 0x13, 0x85, 0x72, 0x63, 0x03, 0x04, 0xE0, + 0x04, 0x36, 0x2B, 0x20, 0x19, 0x02, 0xE8, 0x74, 0xA7, 0x1F, 0xB6, 0xC9, + 0x56, 0x66, 0xF0, 0x75, 0x25, 0xDC, 0x67, 0xC1, 0x0E, 0x61, 0x60, 0x88, + 0xB3, 0x3E, 0xD1, 0xA8, 0xFC, 0xA3, 0xDA, 0x1D, 0xB0, 0xD1, 0xB1, 0x23, + 0x54, 0xDF, 0x44, 0x76, 0x6D, 0xED, 0x41, 0xD8, 0xC1, 0xB2, 0x22, 0xB6, + 0x53, 0x1C, 0xDF, 0x35, 0x1D, 0xDC, 0xA1, 0x77, 0x2A, 0x31, 0xE4, 0x2D, + 0xF5, 0xE5, 0xE5, 0xDB, 0xC8, 0xE0, 0xFF, 0xE5, 0x80, 0xD7, 0x0B, 0x63, + 0xA0, 0xFF, 0x33, 0xA1, 0x0F, 0xBA, 0x2C, 0x15, 0x15, 0xEA, 0x97, 0xB3, + 0xD2, 0xA2, 0xB5, 0xBE, 0xF2, 0x8C, 0x96, 0x1E, 0x1A, 0x8F, 0x1D, 0x6C, + 0xA4, 0x61, 0x37, 0xB9, 0x86, 0x73, 0x33, 0xD7, 0x97, 0x96, 0x9E, 0x23, + 0x7D, 0x82, 0xA4, 0x4C, 0x81, 0xE2, 0xA1, 0xD1, 0xBA, 0x67, 0x5F, 0x95, + 0x07, 0xA3, 0x27, 0x11, 0xEE, 0x16, 0x10, 0x7B, 0xBC, 0x45, 0x4A, 0x4C, + 0xB2, 0x04, 0xD2, 0xAB, 0xEF, 0xD5, 0xFD, 0x0C, 0x51, 0xCE, 0x50, 0x6A, + 0x08, 0x31, 0xF9, 0x91, 0xDA, 0x0C, 0x8F, 0x64, 0x5C, 0x03, 0xC3, 0x3A, + 0x8B, 0x20, 0x3F, 0x6E, 0x8D, 0x67, 0x3D, 0x3A, 0xD6, 0xFE, 0x7D, 0x5B, + 0x88, 0xC9, 0x5E, 0xFB, 0xCC, 0x61, 0xDC, 0x8B, 0x33, 0x77, 0xD3, 0x44, + 0x32, 0x35, 0x09, 0x62, 0x04, 0x92, 0x16, 0x10, 0xD8, 0x9E, 0x27, 0x47, + 0xFB, 0x3B, 0x21, 0xE3, 0xF8, 0xEB, 0x1D, 0x5B +}; + +static const unsigned char TA338_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA339_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA339_RSA_N[] = { + 0xA1, 0xAE, 0x25, 0xB2, 0x01, 0x18, 0xDC, 0x57, 0x88, 0x3F, 0x46, 0xEB, + 0xF9, 0xAF, 0xE2, 0xEB, 0x23, 0x71, 0xE2, 0x9A, 0xD1, 0x61, 0x66, 0x21, + 0x5F, 0xAA, 0xAF, 0x27, 0x51, 0xE5, 0x6E, 0x1B, 0x16, 0xD4, 0x2D, 0x7D, + 0x50, 0xB0, 0x53, 0x77, 0xBD, 0x78, 0x3A, 0x60, 0xE2, 0x64, 0x02, 0x9B, + 0x7C, 0x86, 0x9B, 0xD6, 0x1A, 0x8E, 0xAD, 0xFF, 0x1F, 0x15, 0x7F, 0xD5, + 0x95, 0x1E, 0x12, 0xCB, 0xE6, 0x14, 0x84, 0x04, 0xC1, 0xDF, 0x36, 0xB3, + 0x16, 0x9F, 0x8A, 0xE3, 0xC9, 0xDB, 0x98, 0x34, 0xCE, 0xD8, 0x33, 0x17, + 0x28, 0x46, 0xFC, 0xA7, 0xC9, 0xF0, 0xD2, 0xB4, 0xD5, 0x4D, 0x09, 0x72, + 0x49, 0xF9, 0xF2, 0x87, 0xE3, 0xA9, 0xDA, 0x7D, 0xA1, 0x7D, 0x6B, 0xB2, + 0x3A, 0x25, 0xA9, 0x6D, 0x52, 0x44, 0xAC, 0xF8, 0xBE, 0x6E, 0xFB, 0xDC, + 0xA6, 0x73, 0x91, 0x90, 0x61, 0xA6, 0x03, 0x14, 0x20, 0xF2, 0xE7, 0x87, + 0xA3, 0x88, 0xAD, 0xAD, 0xA0, 0x8C, 0xFF, 0xA6, 0x0B, 0x25, 0x52, 0x25, + 0xE7, 0x16, 0x01, 0xD5, 0xCB, 0xB8, 0x35, 0x81, 0x0C, 0xA3, 0x3B, 0xF0, + 0xE1, 0xE1, 0xFC, 0x5A, 0x5D, 0xCE, 0x80, 0x71, 0x6D, 0xF8, 0x49, 0xAB, + 0x3E, 0x3B, 0xBA, 0xB8, 0xD7, 0x80, 0x01, 0xFB, 0xA5, 0xEB, 0x5B, 0xB3, + 0xC5, 0x5E, 0x60, 0x2A, 0x31, 0xA0, 0xAF, 0x37, 0xE8, 0x20, 0x3A, 0x9F, + 0xA8, 0x32, 0x2C, 0x0C, 0xCC, 0x09, 0x1D, 0xD3, 0x9E, 0x8E, 0x5D, 0xBC, + 0x4C, 0x98, 0xEE, 0xC5, 0x1A, 0x68, 0x7B, 0xEC, 0x53, 0xA6, 0xE9, 0x14, + 0x35, 0xA3, 0xDF, 0xCD, 0x80, 0x9F, 0x0C, 0x48, 0xFB, 0x1C, 0xF4, 0xF1, + 0xBF, 0x4A, 0xB8, 0xFA, 0xD5, 0x8C, 0x71, 0x4A, 0xC7, 0x1F, 0xAD, 0xFE, + 0x41, 0x9A, 0xB3, 0x83, 0x5D, 0xF2, 0x84, 0x56, 0xEF, 0xA5, 0x57, 0x43, + 0xCE, 0x29, 0xAD, 0x8C, 0xAB, 0x55, 0xBF, 0xC4, 0xFB, 0x5B, 0x01, 0xDD, + 0x23, 0x21, 0xA1, 0x58, 0x00, 0x8E, 0xC3, 0xD0, 0x6A, 0x13, 0xED, 0x13, + 0xE3, 0x12, 0x2B, 0x80, 0xDC, 0x67, 0xE6, 0x95, 0xB2, 0xCD, 0x1E, 0x22, + 0x6E, 0x2A, 0xF8, 0x41, 0xD4, 0xF2, 0xCA, 0x14, 0x07, 0x8D, 0x8A, 0x55, + 0x12, 0xC6, 0x69, 0xF5, 0xB8, 0x86, 0x68, 0x2F, 0x53, 0x5E, 0xB0, 0xD2, + 0xAA, 0x21, 0xC1, 0x98, 0xE6, 0x30, 0xE3, 0x67, 0x55, 0xC7, 0x9B, 0x6E, + 0xAC, 0x19, 0xA8, 0x55, 0xA6, 0x45, 0x06, 0xD0, 0x23, 0x3A, 0xDB, 0xEB, + 0x65, 0x5D, 0x2A, 0x11, 0x11, 0xF0, 0x3B, 0x4F, 0xCA, 0x6D, 0xF4, 0x34, + 0xC4, 0x71, 0xE4, 0xFF, 0x00, 0x5A, 0xF6, 0x5C, 0xAE, 0x23, 0x60, 0x85, + 0x73, 0xF1, 0xE4, 0x10, 0xB1, 0x25, 0xAE, 0xD5, 0x92, 0xBB, 0x13, 0xC1, + 0x0C, 0xE0, 0x39, 0xDA, 0xB4, 0x39, 0x57, 0xB5, 0xAB, 0x35, 0xAA, 0x72, + 0x21, 0x3B, 0x83, 0x35, 0xE7, 0x31, 0xDF, 0x7A, 0x21, 0x6E, 0xB8, 0x32, + 0x08, 0x7D, 0x1D, 0x32, 0x91, 0x15, 0x4A, 0x62, 0x72, 0xCF, 0xE3, 0x77, + 0xA1, 0xBC, 0xD5, 0x11, 0x1B, 0x76, 0x01, 0x67, 0x08, 0xE0, 0x41, 0x0B, + 0xC3, 0xEB, 0x15, 0x6E, 0xF8, 0xA4, 0x19, 0xD9, 0xA2, 0xAB, 0xAF, 0xE2, + 0x27, 0x52, 0x56, 0x2B, 0x02, 0x8A, 0x2C, 0x14, 0x24, 0xF9, 0xBF, 0x42, + 0x02, 0xBF, 0x26, 0xC8, 0xC6, 0x8F, 0xE0, 0x6E, 0x38, 0x7D, 0x53, 0x2D, + 0xE5, 0xED, 0x98, 0xB3, 0x95, 0x63, 0x68, 0x7F, 0xF9, 0x35, 0xF4, 0xDF, + 0x88, 0xC5, 0x60, 0x35, 0x92, 0xC0, 0x7C, 0x69, 0x1C, 0x61, 0x95, 0x16, + 0xD0, 0xEB, 0xDE, 0x0B, 0xAF, 0x3E, 0x04, 0x10, 0x45, 0x65, 0x58, 0x50, + 0x38, 0xAF, 0x48, 0xF2, 0x59, 0xB6, 0x16, 0xF2, 0x3C, 0x0D, 0x90, 0x02, + 0xC6, 0x70, 0x2E, 0x01, 0xAD, 0x3C, 0x15, 0xD7 +}; + +static const unsigned char TA339_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA340_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA340_RSA_N[] = { + 0xCC, 0x57, 0x42, 0x16, 0x54, 0x9C, 0xE6, 0x98, 0xD3, 0xD3, 0x4D, 0xEE, + 0xFE, 0xED, 0xC7, 0x9F, 0x43, 0x39, 0x4A, 0x65, 0xB3, 0xE8, 0x16, 0x88, + 0x34, 0xDB, 0x0D, 0x59, 0x91, 0x74, 0xCF, 0x92, 0xB8, 0x04, 0x40, 0xAD, + 0x02, 0x4B, 0x31, 0xAB, 0xBC, 0x8D, 0x91, 0x68, 0xD8, 0x20, 0x0E, 0x1A, + 0x01, 0xE2, 0x1A, 0x7B, 0x4E, 0x17, 0x5D, 0xE2, 0x8A, 0xB7, 0x3F, 0x99, + 0x1A, 0xCD, 0xEB, 0x61, 0xAB, 0xC2, 0x65, 0xA6, 0x1F, 0xB7, 0xB7, 0xBD, + 0xB7, 0x8F, 0xFC, 0xFD, 0x70, 0x8F, 0x0B, 0xA0, 0x67, 0xBE, 0x01, 0xA2, + 0x59, 0xCF, 0x71, 0xE6, 0x0F, 0x29, 0x76, 0xFF, 0xB1, 0x56, 0x79, 0x45, + 0x2B, 0x1F, 0x9E, 0x7A, 0x54, 0xE8, 0xA3, 0x29, 0x35, 0x68, 0xA4, 0x01, + 0x4F, 0x0F, 0xA4, 0x2E, 0x37, 0xEF, 0x1B, 0xBF, 0xE3, 0x8F, 0x10, 0xA8, + 0x72, 0xAB, 0x58, 0x57, 0xE7, 0x54, 0x86, 0xC8, 0xC9, 0xF3, 0x5B, 0xDA, + 0x2C, 0xDA, 0x5D, 0x8E, 0x6E, 0x3C, 0xA3, 0x3E, 0xDA, 0xFB, 0x82, 0xE5, + 0xDD, 0xF2, 0x5C, 0xB2, 0x05, 0x33, 0x6F, 0x8A, 0x36, 0xCE, 0xD0, 0x13, + 0x4E, 0xFF, 0xBF, 0x4A, 0x0C, 0x34, 0x4C, 0xA6, 0xC3, 0x21, 0xBD, 0x50, + 0x04, 0x55, 0xEB, 0xB1, 0xBB, 0x9D, 0xFB, 0x45, 0x1E, 0x64, 0x15, 0xDE, + 0x55, 0x01, 0x8C, 0x02, 0x76, 0xB5, 0xCB, 0xA1, 0x3F, 0x42, 0x69, 0xBC, + 0x2F, 0xBD, 0x68, 0x43, 0x16, 0x56, 0x89, 0x2A, 0x37, 0x61, 0x91, 0xFD, + 0xA6, 0xAE, 0x4E, 0xC0, 0xCB, 0x14, 0x65, 0x94, 0x37, 0x4B, 0x92, 0x06, + 0xEF, 0x04, 0xD0, 0xC8, 0x9C, 0x88, 0xDB, 0x0B, 0x7B, 0x81, 0xAF, 0xB1, + 0x3D, 0x2A, 0xC4, 0x65, 0x3A, 0x78, 0xB6, 0xEE, 0xDC, 0x80, 0xB1, 0xD2, + 0xD3, 0x99, 0x9C, 0x3A, 0xEE, 0x6B, 0x5A, 0x6B, 0xB3, 0x8D, 0xB7, 0xD5, + 0xCE, 0x9C, 0xC2, 0xBE, 0xA5, 0x4B, 0x2F, 0x16, 0xB1, 0x9E, 0x68, 0x3B, + 0x06, 0x6F, 0xAE, 0x7D, 0x9F, 0xF8, 0xDE, 0xEC, 0xCC, 0x29, 0xA7, 0x98, + 0xA3, 0x25, 0x43, 0x2F, 0xEF, 0xF1, 0x5F, 0x26, 0xE1, 0x88, 0x4D, 0xF8, + 0x5E, 0x6E, 0xD7, 0xD9, 0x14, 0x6E, 0x19, 0x33, 0x69, 0xA7, 0x3B, 0x84, + 0x89, 0x93, 0xC4, 0x53, 0x55, 0x13, 0xA1, 0x51, 0x78, 0x40, 0xF8, 0xB8, + 0xC9, 0xA2, 0xEE, 0x7B, 0xBA, 0x52, 0x42, 0x83, 0x9E, 0x14, 0xED, 0x05, + 0x52, 0x5A, 0x59, 0x56, 0xA7, 0x97, 0xFC, 0x9D, 0x3F, 0x0A, 0x29, 0xD8, + 0xDC, 0x4F, 0x91, 0x0E, 0x13, 0xBC, 0xDE, 0x95, 0xA4, 0xDF, 0x8B, 0x99, + 0xBE, 0xAC, 0x9B, 0x33, 0x88, 0xEF, 0xB5, 0x81, 0xAF, 0x1B, 0xC6, 0x22, + 0x53, 0xC8, 0xF6, 0xC7, 0xEE, 0x97, 0x14, 0xB0, 0xC5, 0x7C, 0x78, 0x52, + 0xC8, 0xF0, 0xCE, 0x6E, 0x77, 0x60, 0x84, 0xA6, 0xE9, 0x2A, 0x76, 0x20, + 0xED, 0x58, 0x01, 0x17, 0x30, 0x93, 0xE9, 0x1A, 0x8B, 0xE0, 0x73, 0x63, + 0xD9, 0x6A, 0x92, 0x94, 0x49, 0x4E, 0xB4, 0xAD, 0x4A, 0x85, 0xC4, 0xA3, + 0x22, 0x30, 0xFC, 0x09, 0xED, 0x68, 0x22, 0x73, 0xA6, 0x88, 0x0C, 0x55, + 0x21, 0x58, 0xC5, 0xE1, 0x3A, 0x9F, 0x2A, 0xDD, 0xCA, 0xE1, 0x90, 0xE0, + 0xD9, 0x73, 0xAB, 0x6C, 0x80, 0xB8, 0xE8, 0x0B, 0x64, 0x93, 0xA0, 0x9C, + 0x8C, 0x19, 0xFF, 0xB3, 0xD2, 0x0C, 0xEC, 0x91, 0x26, 0x87, 0x8A, 0xB3, + 0xA2, 0xE1, 0x70, 0x8F, 0x2C, 0x0A, 0xE5, 0xCD, 0x6D, 0x68, 0x51, 0xEB, + 0xDA, 0x3F, 0x05, 0x7F, 0x8B, 0x32, 0xE6, 0x13, 0x5C, 0x6B, 0xFE, 0x5F, + 0x40, 0xE2, 0x22, 0xC8, 0xB4, 0xB4, 0x64, 0x4F, 0xD6, 0xBA, 0x7D, 0x48, + 0x3E, 0xA8, 0x69, 0x0C, 0xD7, 0xBB, 0x86, 0x71, 0xC9, 0x73, 0xB8, 0x3F, + 0x3B, 0x9D, 0x25, 0x4B, 0xDA, 0xFF, 0x40, 0xEB +}; + +static const unsigned char TA340_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA341_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA341_RSA_N[] = { + 0xB3, 0xCB, 0x0E, 0x10, 0x67, 0x8E, 0xEA, 0x14, 0x97, 0xA7, 0x32, 0x2A, + 0x0A, 0x56, 0x36, 0x7F, 0x68, 0x4C, 0xC7, 0xB3, 0x6F, 0x3A, 0x23, 0x14, + 0x91, 0xFF, 0x19, 0x7F, 0xA5, 0xCA, 0xAC, 0xEE, 0xB3, 0x76, 0x9D, 0x7A, + 0xE9, 0x8B, 0x1B, 0xAB, 0x6B, 0x31, 0xDB, 0xFA, 0x0B, 0x53, 0x4C, 0xAF, + 0xC5, 0xA5, 0x1A, 0x79, 0x3C, 0x8A, 0x4C, 0xFF, 0xAC, 0xDF, 0x25, 0xDE, + 0x4E, 0xD9, 0x82, 0x32, 0x0B, 0x44, 0xDE, 0xCA, 0xDB, 0x8C, 0xAC, 0xA3, + 0x6E, 0x16, 0x83, 0x3B, 0xA6, 0x64, 0x4B, 0x32, 0x89, 0xFB, 0x16, 0x16, + 0x38, 0x7E, 0xEB, 0x43, 0xE2, 0xD3, 0x74, 0x4A, 0xC2, 0x62, 0x0A, 0x73, + 0x0A, 0xDD, 0x49, 0xB3, 0x57, 0xD2, 0xB0, 0x0A, 0x85, 0x9D, 0x71, 0x3C, + 0xDE, 0xA3, 0xCB, 0xC0, 0x32, 0xF3, 0x01, 0x39, 0x20, 0x43, 0x1B, 0x35, + 0xD1, 0x53, 0xB3, 0xB1, 0xEE, 0xC5, 0x93, 0x69, 0x82, 0x3E, 0x16, 0xB5, + 0x28, 0x46, 0xA1, 0xDE, 0xEA, 0x89, 0x09, 0xED, 0x43, 0xB8, 0x05, 0x46, + 0x8A, 0x86, 0xF5, 0x59, 0x47, 0xBE, 0x1B, 0x6F, 0x01, 0x21, 0x10, 0xB9, + 0xFD, 0xA9, 0xD2, 0x28, 0xCA, 0x10, 0x39, 0x09, 0xCA, 0x13, 0x36, 0xCF, + 0x9C, 0xAD, 0xAD, 0x40, 0x74, 0x79, 0x2B, 0x02, 0x3F, 0x34, 0xFF, 0xFA, + 0x20, 0x69, 0x7D, 0xD3, 0xEE, 0x61, 0xF5, 0xBA, 0xB3, 0xE7, 0x30, 0xD0, + 0x37, 0x23, 0x86, 0x72, 0x61, 0x45, 0x29, 0x48, 0x59, 0x68, 0x6F, 0x77, + 0xA6, 0x2E, 0x81, 0xBE, 0x07, 0x4D, 0x6F, 0xAF, 0xCE, 0xC4, 0x45, 0x13, + 0x91, 0x14, 0x70, 0x06, 0x8F, 0x1F, 0x9F, 0xF8, 0x87, 0x69, 0xB1, 0x0E, + 0xEF, 0xC3, 0x89, 0x19, 0xEB, 0xEA, 0x1C, 0x61, 0xFC, 0x7A, 0x6C, 0x8A, + 0xDC, 0xD6, 0x03, 0x0B, 0x9E, 0x26, 0xBA, 0x12, 0xDD, 0xD4, 0x54, 0x39, + 0xAB, 0x26, 0xA3, 0x33, 0xEA, 0x75, 0x81, 0xDA, 0x2D, 0xCD, 0x0F, 0x4F, + 0xE4, 0x03, 0xD1, 0xEF, 0x15, 0x97, 0x1B, 0x6B, 0x90, 0xC5, 0x02, 0x90, + 0x93, 0x66, 0x02, 0x21, 0xB1, 0x47, 0xDE, 0x8B, 0x9A, 0x4A, 0x80, 0xB9, + 0x55, 0x8F, 0xB5, 0xA2, 0x2F, 0xC0, 0xD6, 0x33, 0x67, 0xDA, 0x7E, 0xC4, + 0xA7, 0xB4, 0x04, 0x44, 0xEB, 0x47, 0xFB, 0xE6, 0x58, 0xB9, 0xF7, 0x0C, + 0xF0, 0x7B, 0x2B, 0xB1, 0xC0, 0x70, 0x29, 0xC3, 0x40, 0x62, 0x2D, 0x3B, + 0x48, 0x69, 0xDC, 0x23, 0x3C, 0x48, 0xEB, 0x7B, 0x09, 0x79, 0xA9, 0x6D, + 0xDA, 0xA8, 0x30, 0x98, 0xCF, 0x80, 0x72, 0x03, 0x88, 0xA6, 0x5B, 0x46, + 0xAE, 0x72, 0x79, 0x7C, 0x08, 0x03, 0x21, 0x65, 0xAE, 0xB7, 0xE1, 0x1C, + 0xA5, 0xB1, 0x2A, 0xA2, 0x31, 0xDE, 0x66, 0x04, 0xF7, 0xC0, 0x74, 0xE8, + 0x71, 0xDE, 0xFF, 0x3D, 0x59, 0xCC, 0x96, 0x26, 0x12, 0x8B, 0x85, 0x95, + 0x57, 0x1A, 0xAB, 0x6B, 0x75, 0x0B, 0x44, 0x3D, 0x11, 0x28, 0x3C, 0x7B, + 0x61, 0xB7, 0xE2, 0x8F, 0x67, 0x4F, 0xE5, 0xEC, 0x3C, 0x4C, 0x60, 0x80, + 0x69, 0x57, 0x38, 0x1E, 0x01, 0x5B, 0x8D, 0x55, 0xE8, 0xC7, 0xDF, 0xC0, + 0xCC, 0x77, 0x23, 0x34, 0x49, 0x75, 0x7C, 0xF6, 0x98, 0x11, 0xEB, 0x2D, + 0xDE, 0xED, 0x41, 0x2E, 0x14, 0x05, 0x02, 0x7F, 0xE0, 0xFE, 0x20, 0xEB, + 0x35, 0xE7, 0x11, 0xAC, 0x22, 0xCE, 0x57, 0x3D, 0xDE, 0xC9, 0x30, 0x6D, + 0x10, 0x03, 0x85, 0xCD, 0xF1, 0xFF, 0x8C, 0x16, 0xB5, 0xC1, 0xB2, 0x3E, + 0x88, 0x6C, 0x60, 0x7F, 0x90, 0x4F, 0x95, 0xF7, 0xF6, 0x2D, 0xAD, 0x01, + 0x39, 0x07, 0x04, 0xFA, 0x75, 0x80, 0x7D, 0xBF, 0x49, 0x50, 0xED, 0xEF, + 0xC9, 0xC4, 0x7C, 0x1C, 0xEB, 0x80, 0x7E, 0xDB, 0xB6, 0xD0, 0xDD, 0x13, + 0xFE, 0xC9, 0xD3, 0x9C, 0xD7, 0xB2, 0x97, 0xA9 +}; + +static const unsigned char TA341_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA342_DN[] = { + 0x30, 0x7F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x2B, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, 0x56, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA342_EC_Q[] = { + 0x04, 0xAA, 0x12, 0x47, 0x90, 0x98, 0x1B, 0xFB, 0xEF, 0xC3, 0x40, 0x07, + 0x83, 0x20, 0x4E, 0xF1, 0x30, 0x82, 0xA2, 0x06, 0xD1, 0xF2, 0x92, 0x86, + 0x61, 0xF2, 0xF6, 0x21, 0x68, 0xCA, 0x00, 0xC4, 0xC7, 0xEA, 0x43, 0x00, + 0x54, 0x86, 0xDC, 0xFD, 0x1F, 0xDF, 0x00, 0xB8, 0x41, 0x62, 0x5C, 0xDC, + 0x70, 0x16, 0x32, 0xDE, 0x1F, 0x99, 0xD4, 0xCC, 0xC5, 0x07, 0xC8, 0x08, + 0x1F, 0x61, 0x16, 0x07, 0x51, 0x3D, 0x7D, 0x5C, 0x07, 0x53, 0xE3, 0x35, + 0x38, 0x8C, 0xDF, 0xCD, 0x9F, 0xD9, 0x2E, 0x0D, 0x4A, 0xB6, 0x19, 0x2E, + 0x5A, 0x70, 0x5A, 0x06, 0xED, 0xBE, 0xF0, 0xA1, 0xB0, 0xCA, 0xD0, 0x09, + 0x29 +}; + +static const unsigned char TA343_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, + 0x6F, 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x2E, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, + 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA343_RSA_N[] = { + 0x8F, 0x36, 0x65, 0x40, 0xE1, 0xD6, 0x4D, 0xC0, 0xD7, 0xB4, 0xE9, 0x46, + 0xDA, 0x6B, 0xEA, 0x33, 0x47, 0xCD, 0x4C, 0xF9, 0x7D, 0x7D, 0xBE, 0xBD, + 0x2D, 0x3D, 0xF0, 0xDB, 0x78, 0xE1, 0x86, 0xA5, 0xD9, 0xBA, 0x09, 0x57, + 0x68, 0xED, 0x57, 0x3E, 0xA0, 0xD0, 0x08, 0x41, 0x83, 0xE7, 0x28, 0x41, + 0x24, 0x1F, 0xE3, 0x72, 0x15, 0xD0, 0x01, 0x1A, 0xFB, 0x5E, 0x70, 0x23, + 0xB2, 0xCB, 0x9F, 0x39, 0xE3, 0xCF, 0xC5, 0x4E, 0xC6, 0x92, 0x6D, 0x26, + 0xC6, 0x7B, 0xBB, 0xB3, 0xDA, 0x27, 0x9D, 0x0A, 0x86, 0xE9, 0x81, 0x37, + 0x05, 0xFE, 0xF0, 0x71, 0x71, 0xEC, 0xC3, 0x1C, 0xE9, 0x63, 0xA2, 0x17, + 0x14, 0x9D, 0xEF, 0x1B, 0x67, 0xD3, 0x85, 0x55, 0x02, 0x02, 0xD6, 0x49, + 0xC9, 0xCC, 0x5A, 0xE1, 0xB1, 0xF7, 0x6F, 0x32, 0x9F, 0xC9, 0xD4, 0x3B, + 0x88, 0x41, 0xA8, 0x9C, 0xBD, 0xCB, 0xAB, 0xDB, 0x6D, 0x7B, 0x09, 0x1F, + 0xA2, 0x4C, 0x72, 0x90, 0xDA, 0x2B, 0x08, 0xFC, 0xCF, 0x3C, 0x54, 0xCE, + 0x67, 0x0F, 0xA8, 0xCF, 0x5D, 0x96, 0x19, 0x0B, 0xC4, 0xE3, 0x72, 0xEB, + 0xAD, 0xD1, 0x7D, 0x1D, 0x27, 0xEF, 0x92, 0xEB, 0x10, 0xBF, 0x5B, 0xEB, + 0x3B, 0xAF, 0xCF, 0x80, 0xDD, 0xC1, 0xD2, 0x96, 0x04, 0x5B, 0x7A, 0x7E, + 0xA4, 0xA9, 0x3C, 0x38, 0x76, 0xA4, 0x62, 0x8E, 0xA0, 0x39, 0x5E, 0xEA, + 0x77, 0xCF, 0x5D, 0x00, 0x59, 0x8F, 0x66, 0x2C, 0x3E, 0x07, 0xA2, 0xA3, + 0x05, 0x26, 0x11, 0x69, 0x97, 0xEA, 0x85, 0xB7, 0x0F, 0x96, 0x0B, 0x4B, + 0xC8, 0x40, 0xE1, 0x50, 0xBA, 0x2E, 0x8A, 0xCB, 0xF7, 0x0F, 0x9A, 0x22, + 0xE7, 0x7F, 0x9A, 0x37, 0x13, 0xCD, 0xF2, 0x4D, 0x13, 0x6B, 0x21, 0xD1, + 0xC0, 0xCC, 0x22, 0xF2, 0xA1, 0x46, 0xF6, 0x44, 0x69, 0x9C, 0xCA, 0x61, + 0x35, 0x07, 0x00, 0x6F, 0xD6, 0x61, 0x08, 0x11, 0xEA, 0xBA, 0xB8, 0xF6, + 0xE9, 0xB3, 0x60, 0xE5, 0x4D, 0xB9, 0xEC, 0x9F, 0x14, 0x66, 0xC9, 0x57, + 0x58, 0xDB, 0xCD, 0x87, 0x69, 0xF8, 0x8A, 0x86, 0x12, 0x03, 0x47, 0xBF, + 0x66, 0x13, 0x76, 0xAC, 0x77, 0x7D, 0x34, 0x24, 0x85, 0x83, 0xCD, 0xD7, + 0xAA, 0x9C, 0x90, 0x1A, 0x9F, 0x21, 0x2C, 0x7F, 0x78, 0xB7, 0x64, 0xB8, + 0xD8, 0xE8, 0xA6, 0xF4, 0x78, 0xB3, 0x55, 0xCB, 0x84, 0xD2, 0x32, 0xC4, + 0x78, 0xAE, 0xA3, 0x8F, 0x61, 0xDD, 0xCE, 0x08, 0x53, 0xAD, 0xEC, 0x88, + 0xFC, 0x15, 0xE4, 0x9A, 0x0D, 0xE6, 0x9F, 0x1A, 0x77, 0xCE, 0x4C, 0x8F, + 0xB8, 0x14, 0x15, 0x3D, 0x62, 0x9C, 0x86, 0x38, 0x06, 0x00, 0x66, 0x12, + 0xE4, 0x59, 0x76, 0x5A, 0x53, 0xC0, 0x02, 0x98, 0xA2, 0x10, 0x2B, 0x68, + 0x44, 0x7B, 0x8E, 0x79, 0xCE, 0x33, 0x4A, 0x76, 0xAA, 0x5B, 0x81, 0x16, + 0x1B, 0xB5, 0x8A, 0xD8, 0xD0, 0x00, 0x7B, 0x5E, 0x62, 0xB4, 0x09, 0xD6, + 0x86, 0x63, 0x0E, 0xA6, 0x05, 0x95, 0x49, 0xBA, 0x28, 0x8B, 0x88, 0x93, + 0xB2, 0x34, 0x1C, 0xD8, 0xA4, 0x55, 0x6E, 0xB7, 0x1C, 0xD0, 0xDE, 0x99, + 0x55, 0x3B, 0x23, 0xF4, 0x22, 0xE0, 0xF9, 0x29, 0x66, 0x26, 0xEC, 0x20, + 0x50, 0x77, 0xDB, 0x4A, 0x0B, 0x8F, 0xBE, 0xE5, 0x02, 0x60, 0x70, 0x41, + 0x5E, 0xD4, 0xAE, 0x50, 0x39, 0x22, 0x14, 0x26, 0xCB, 0xB2, 0x3B, 0x73, + 0x74, 0x55, 0x47, 0x07, 0x79, 0x81, 0x39, 0xA8, 0x30, 0x13, 0x44, 0xE5, + 0x04, 0x8A, 0xAE, 0x96, 0x13, 0x25, 0x42, 0x0F, 0xB9, 0x53, 0xC4, 0x9B, + 0xFC, 0xCD, 0xE4, 0x1C, 0xDE, 0x3C, 0xFA, 0xAB, 0xD6, 0x06, 0x4A, 0x1F, + 0x67, 0xA6, 0x98, 0x30, 0x1C, 0xDD, 0x2C, 0xDB, 0xDC, 0x18, 0x95, 0x57, + 0x66, 0xC6, 0xFF, 0x5C, 0x8B, 0x56, 0xF5, 0x77 +}; + +static const unsigned char TA343_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA344_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA344_EC_Q[] = { + 0x04, 0x45, 0x6E, 0xA9, 0x50, 0xC4, 0xA6, 0x23, 0x36, 0x9E, 0x5F, 0x28, + 0x8D, 0x17, 0xCB, 0x96, 0x22, 0x64, 0x3F, 0xDC, 0x7A, 0x8E, 0x1D, 0xCC, + 0x08, 0xB3, 0xA2, 0x71, 0x24, 0xBA, 0x8E, 0x49, 0xB9, 0x04, 0x1B, 0x47, + 0x96, 0x58, 0xAB, 0x2D, 0x95, 0xC8, 0xED, 0x9E, 0x08, 0x35, 0xC8, 0x27, + 0xEB, 0x89, 0x8C, 0x53, 0x58, 0xEB, 0x62, 0x8A, 0xFE, 0xF0, 0x5B, 0x0F, + 0x6B, 0x31, 0x52, 0x63, 0x41, 0x3B, 0x89, 0xCD, 0xEC, 0xEC, 0xB6, 0x8D, + 0x19, 0xD3, 0x34, 0x07, 0xDC, 0xBB, 0xC6, 0x06, 0x7F, 0xC2, 0x45, 0x95, + 0xEC, 0xCB, 0x7F, 0xA8, 0x23, 0xE0, 0x09, 0xE9, 0x81, 0xFA, 0xF3, 0x47, + 0xD3 +}; + +static const unsigned char TA345_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x52, 0x53, 0x41 +}; + +static const unsigned char TA345_RSA_N[] = { + 0xF9, 0x0F, 0xDD, 0xA3, 0x2B, 0x7D, 0xCB, 0xD0, 0x2A, 0xFE, 0xEC, 0x67, + 0x85, 0xA6, 0xE7, 0x2E, 0x1B, 0xBA, 0x77, 0xE1, 0xE3, 0xF5, 0xAF, 0xA4, + 0xEC, 0xFA, 0x4A, 0x5D, 0x91, 0xC4, 0x57, 0x47, 0x6B, 0x18, 0x77, 0x6B, + 0x76, 0xF2, 0xFD, 0x93, 0xE4, 0x3D, 0x0F, 0xC2, 0x16, 0x9E, 0x0B, 0x66, + 0xC3, 0x56, 0x94, 0x9E, 0x17, 0x83, 0x85, 0xCE, 0x56, 0xEF, 0xF2, 0x16, + 0xFD, 0x00, 0x62, 0xF5, 0x22, 0x09, 0x54, 0xE8, 0x65, 0x17, 0x4E, 0x41, + 0xB9, 0xE0, 0x4F, 0x46, 0x97, 0xAA, 0x1B, 0xC8, 0xB8, 0x6E, 0x62, 0x5E, + 0x69, 0xB1, 0x5F, 0xDB, 0x2A, 0x02, 0x7E, 0xFC, 0x6C, 0xCA, 0xF3, 0x41, + 0xD8, 0xED, 0xD0, 0xE8, 0xFC, 0x3F, 0x61, 0x48, 0xED, 0xB0, 0x03, 0x14, + 0x1D, 0x10, 0x0E, 0x4B, 0x19, 0xE0, 0xBB, 0x4E, 0xEC, 0x86, 0x65, 0xFF, + 0x36, 0xF3, 0x5E, 0x67, 0x02, 0x0B, 0x9D, 0x86, 0x55, 0x61, 0xFD, 0x7A, + 0x38, 0xED, 0xFE, 0xE2, 0x19, 0x00, 0xB7, 0x6F, 0xA1, 0x50, 0x62, 0x75, + 0x74, 0x3C, 0xA0, 0xFA, 0xC8, 0x25, 0x92, 0xB4, 0x6E, 0x7A, 0x22, 0xC7, + 0xF8, 0x1E, 0xA1, 0xE3, 0xB2, 0xDD, 0x91, 0x31, 0xAB, 0x2B, 0x1D, 0x04, + 0xFF, 0xA5, 0x4A, 0x04, 0x37, 0xE9, 0x85, 0xA4, 0x33, 0x2B, 0xFD, 0xE2, + 0xD6, 0x55, 0x34, 0x7C, 0x19, 0xA4, 0x4A, 0x68, 0xC7, 0xB2, 0xA8, 0xD3, + 0xB7, 0xCA, 0xA1, 0x93, 0x88, 0xEB, 0xC1, 0x97, 0xBC, 0x8C, 0xF9, 0x1D, + 0xD9, 0x22, 0x84, 0x24, 0x74, 0xC7, 0x04, 0x3D, 0x6A, 0xA9, 0x29, 0x93, + 0xCC, 0xEB, 0xB8, 0x5B, 0xE1, 0xFE, 0x5F, 0x25, 0xAA, 0x34, 0x58, 0xC8, + 0xC1, 0x23, 0x54, 0x9D, 0x1B, 0x98, 0x11, 0xC3, 0x38, 0x9C, 0x7E, 0x3D, + 0x86, 0x6C, 0xA5, 0x0F, 0x40, 0x86, 0x7C, 0x02, 0xF4, 0x5C, 0x02, 0x4F, + 0x28, 0xCB, 0xAE, 0x71, 0x9F, 0x0F, 0x3A, 0xC8, 0x33, 0xFE, 0x11, 0x25, + 0x35, 0xEA, 0xFC, 0xBA, 0xC5, 0x60, 0x3D, 0xD9, 0x7C, 0x18, 0xD5, 0xB2, + 0xA9, 0xD3, 0x75, 0x78, 0x03, 0x72, 0x22, 0xCA, 0x3A, 0xC3, 0x1F, 0xEF, + 0x2C, 0xE5, 0x2E, 0xA9, 0xFA, 0x9E, 0x2C, 0xB6, 0x51, 0x46, 0xFD, 0xAF, + 0x03, 0xD6, 0xEA, 0x60, 0x68, 0xEA, 0x85, 0x16, 0x36, 0x6B, 0x85, 0xE9, + 0x1E, 0xC0, 0xB3, 0xDD, 0xC4, 0x24, 0xDC, 0x80, 0x2A, 0x81, 0x41, 0x6D, + 0x94, 0x3E, 0xC8, 0xE0, 0xC9, 0x81, 0x41, 0x00, 0x9E, 0x5E, 0xBF, 0x7F, + 0xC5, 0x08, 0x98, 0xA2, 0x18, 0x2C, 0x42, 0x40, 0xB3, 0xF9, 0x6F, 0x38, + 0x27, 0x4B, 0x4E, 0x80, 0xF4, 0x3D, 0x81, 0x47, 0xE0, 0x88, 0x7C, 0xEA, + 0x1C, 0xCE, 0xB5, 0x75, 0x5C, 0x51, 0x2E, 0x1C, 0x2B, 0x7F, 0x1A, 0x72, + 0x28, 0xE7, 0x00, 0xB5, 0xD1, 0x74, 0xC6, 0xD7, 0xE4, 0x9F, 0xAD, 0x07, + 0x93, 0xB6, 0x53, 0x35, 0x35, 0xFC, 0x37, 0xE4, 0xC3, 0xF6, 0x5D, 0x16, + 0xBE, 0x21, 0x73, 0xDE, 0x92, 0x0A, 0xF8, 0xA0, 0x63, 0x6A, 0xBC, 0x96, + 0x92, 0x6A, 0x3E, 0xF8, 0xBC, 0x65, 0x55, 0x9B, 0xDE, 0xF5, 0x0D, 0x89, + 0x26, 0x04, 0xFC, 0x25, 0x1A, 0xA6, 0x25, 0x69, 0xCB, 0xC2, 0x6D, 0xCA, + 0x7C, 0xE2, 0x59, 0x5F, 0x97, 0xAC, 0xEB, 0xEF, 0x2E, 0xC8, 0xBC, 0xD7, + 0x1B, 0x59, 0x3C, 0x2B, 0xCC, 0xF2, 0x19, 0xC8, 0x93, 0x6B, 0x27, 0x63, + 0x19, 0xCF, 0xFC, 0xE9, 0x26, 0xF8, 0xCA, 0x71, 0x9B, 0x7F, 0x93, 0xFE, + 0x34, 0x67, 0x84, 0x4E, 0x99, 0xEB, 0xFC, 0xB3, 0x78, 0x09, 0x33, 0x70, + 0xBA, 0x66, 0xA6, 0x76, 0xED, 0x1B, 0x73, 0xEB, 0x1A, 0xA5, 0x0D, 0xC4, + 0x22, 0x13, 0x20, 0x94, 0x56, 0x0A, 0x4E, 0x2C, 0x6C, 0x4E, 0xB1, 0xFD, + 0xCF, 0x9C, 0x09, 0xBA, 0xA2, 0x33, 0xED, 0x87 +}; + +static const unsigned char TA345_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA346_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA346_EC_Q[] = { + 0x04, 0x45, 0x29, 0x35, 0x73, 0xFA, 0xC2, 0xB8, 0x23, 0xCE, 0x14, 0x7D, + 0xA8, 0xB1, 0x4D, 0xA0, 0x5B, 0x36, 0xEE, 0x2A, 0x2C, 0x53, 0xC3, 0x60, + 0x09, 0x35, 0xB2, 0x24, 0x66, 0x26, 0x69, 0xC0, 0xB3, 0x95, 0xD6, 0x5D, + 0x92, 0x40, 0x19, 0x0E, 0xC6, 0xA5, 0x13, 0x70, 0xF4, 0xEF, 0x12, 0x51, + 0x28, 0x5D, 0xE7, 0xCC, 0xBD, 0xF9, 0x3C, 0x85, 0xC1, 0xCF, 0x94, 0x90, + 0xC9, 0x2B, 0xCE, 0x92, 0x42, 0x58, 0x59, 0x67, 0xFD, 0x94, 0x27, 0x10, + 0x64, 0x8C, 0x4F, 0x04, 0xB1, 0x4D, 0x49, 0xE4, 0x7B, 0x4F, 0x9B, 0xF5, + 0xE7, 0x08, 0xF8, 0x03, 0x88, 0xF7, 0xA7, 0xC3, 0x92, 0x4B, 0x19, 0x54, + 0x81 +}; + +static const unsigned char TA347_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA347_RSA_N[] = { + 0xD0, 0xA4, 0x09, 0x72, 0x4F, 0x40, 0x88, 0x12, 0x61, 0x3E, 0x35, 0x23, + 0x9E, 0xEE, 0xF6, 0x74, 0xCF, 0x2F, 0x7B, 0x58, 0x3D, 0xCE, 0x3C, 0x0D, + 0x10, 0x28, 0x90, 0x2F, 0x97, 0xF7, 0x8C, 0x48, 0xD8, 0xA0, 0xD8, 0x25, + 0xB1, 0x4C, 0xB0, 0x11, 0x4C, 0x17, 0x73, 0x50, 0xD0, 0x22, 0x4A, 0x63, + 0xBB, 0x81, 0xD3, 0x29, 0x6E, 0xD5, 0xB5, 0x09, 0x3E, 0x26, 0x18, 0x7F, + 0xB2, 0x12, 0x7F, 0x93, 0x98, 0xB7, 0xAF, 0xF0, 0x36, 0xBF, 0xF2, 0xEE, + 0x18, 0x9E, 0x9C, 0x3B, 0x52, 0xC5, 0x47, 0x19, 0x5D, 0x74, 0xF3, 0x64, + 0x66, 0xD5, 0x5D, 0xC7, 0x68, 0xB4, 0xBF, 0x1B, 0x1C, 0x06, 0xA3, 0xBC, + 0x8F, 0x40, 0x23, 0xB6, 0x1E, 0xC6, 0x84, 0xBD, 0x51, 0xC4, 0x1B, 0x39, + 0xC1, 0x95, 0xD2, 0x29, 0xEC, 0x4B, 0xAE, 0x7B, 0x2D, 0xBF, 0x39, 0xFD, + 0xB4, 0x62, 0xDE, 0x96, 0x7B, 0x41, 0xC6, 0x9C, 0xA0, 0xE0, 0x06, 0x72, + 0xFB, 0xF0, 0x07, 0x97, 0x09, 0x39, 0x81, 0x74, 0xAF, 0xF7, 0x34, 0x59, + 0x11, 0x57, 0x0A, 0xC2, 0x5B, 0xC1, 0x24, 0xF4, 0x31, 0x73, 0x30, 0x82, + 0xC6, 0x9D, 0xBA, 0x02, 0xF7, 0x3E, 0x7C, 0x44, 0x5F, 0x83, 0x0D, 0xF3, + 0xF1, 0xDD, 0x20, 0x69, 0x16, 0x09, 0x50, 0xE2, 0xD4, 0x55, 0xB6, 0xE0, + 0x80, 0x72, 0x76, 0x6E, 0x4C, 0x47, 0xB7, 0x75, 0x55, 0x59, 0xB4, 0x53, + 0x74, 0xD9, 0x94, 0xC6, 0x41, 0xAD, 0x58, 0x8A, 0x31, 0x66, 0x0F, 0x1E, + 0xA2, 0x1B, 0x29, 0x40, 0x4E, 0x2F, 0xDF, 0x7B, 0xE6, 0x16, 0x2C, 0x2D, + 0xFC, 0xBF, 0xEC, 0xF3, 0xB4, 0xFA, 0xBE, 0x18, 0xF6, 0x9B, 0x49, 0xD4, + 0xEE, 0x05, 0x6E, 0xD9, 0x34, 0xF3, 0x9C, 0xF1, 0xEC, 0x01, 0x8B, 0xD1, + 0x20, 0xC6, 0x0F, 0xA0, 0xB5, 0xBC, 0x17, 0x4E, 0x48, 0x7B, 0x51, 0xC2, + 0xFC, 0xE9, 0x5C, 0x69, 0x37, 0x47, 0x66, 0xB3, 0x68, 0xF8, 0x15, 0x28, + 0xF0, 0xB9, 0xD3, 0xA4, 0x15, 0xCC, 0x5A, 0x4F, 0xBA, 0x52, 0x70, 0xA3, + 0x12, 0x45, 0xDD, 0xC6, 0xBA, 0x4E, 0xFB, 0xC2, 0xD0, 0xF7, 0xA8, 0x52, + 0x27, 0x6D, 0x6E, 0x79, 0xB5, 0x8C, 0xFC, 0x7B, 0x8C, 0xC1, 0x16, 0x4C, + 0xEE, 0x80, 0x7F, 0xBE, 0xF0, 0x76, 0xBE, 0x41, 0x53, 0x12, 0x33, 0xAE, + 0x5A, 0x38, 0x42, 0xAB, 0xD7, 0x0F, 0x3E, 0x41, 0x8D, 0x76, 0x07, 0x32, + 0xD5, 0xAB, 0x89, 0xF6, 0x4E, 0x67, 0xD9, 0xB1, 0x42, 0x75, 0x23, 0x6E, + 0xF3, 0xCD, 0x42, 0xB2, 0xFC, 0x55, 0xF5, 0x53, 0x87, 0x17, 0x3B, 0xC0, + 0x33, 0x58, 0xF1, 0x52, 0xD2, 0xF9, 0x80, 0xA4, 0xF0, 0xE8, 0xF0, 0x3B, + 0x8B, 0x38, 0xCC, 0xA4, 0xC6, 0x90, 0x7F, 0x0F, 0x9C, 0xFD, 0x8B, 0xD1, + 0xA3, 0xCF, 0xDA, 0x83, 0xA7, 0x69, 0xC9, 0x50, 0x36, 0xD5, 0x5C, 0x05, + 0xD2, 0x0A, 0x41, 0x74, 0xDB, 0x63, 0x11, 0x37, 0xC1, 0xA5, 0xA0, 0x96, + 0x4B, 0x1E, 0x8C, 0x16, 0x12, 0x77, 0xAE, 0x94, 0x34, 0x7B, 0x1E, 0x7F, + 0xC2, 0x66, 0x00, 0xE4, 0xAA, 0x83, 0xEA, 0x8A, 0x90, 0xAD, 0xCE, 0x36, + 0x44, 0x4D, 0xD1, 0x51, 0xE9, 0xBC, 0x1F, 0xF3, 0x6A, 0x05, 0xFD, 0xC0, + 0x74, 0x1F, 0x25, 0x19, 0x40, 0x51, 0x6E, 0xEA, 0x82, 0x51, 0x40, 0xDF, + 0x9B, 0xB9, 0x08, 0x2A, 0x06, 0x02, 0xD5, 0x23, 0x1C, 0x13, 0xD6, 0xE9, + 0xDB, 0xDB, 0xC6, 0xB0, 0x7A, 0xCB, 0x7B, 0x27, 0x9B, 0xFB, 0xE0, 0xD5, + 0x46, 0x24, 0xED, 0x10, 0x4B, 0x63, 0x4B, 0xA5, 0x05, 0x8F, 0xBA, 0xB8, + 0x1D, 0x2B, 0xA6, 0xFA, 0x91, 0xE2, 0x92, 0x52, 0xBD, 0xEC, 0xEB, 0x67, + 0x97, 0x6D, 0x9A, 0x2D, 0x9F, 0x81, 0x32, 0x05, 0x67, 0x32, 0xFB, 0x48, + 0x08, 0x3F, 0xD9, 0x25, 0xB8, 0x04, 0x25, 0x2F +}; + +static const unsigned char TA347_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA348_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1F, 0x4B, 0x72, 0x61, 0x6A, 0x6F, 0x77, 0x61, 0x20, 0x49, 0x7A, + 0x62, 0x61, 0x20, 0x52, 0x6F, 0x7A, 0x6C, 0x69, 0x63, 0x7A, 0x65, 0x6E, + 0x69, 0x6F, 0x77, 0x61, 0x20, 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x53, 0x5A, 0x41, 0x46, + 0x49, 0x52, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA348_RSA_N[] = { + 0xB7, 0xBC, 0x3E, 0x50, 0xA8, 0x4B, 0xCD, 0x40, 0xB5, 0xCE, 0x61, 0xE7, + 0x96, 0xCA, 0xB4, 0xA1, 0xDA, 0x0C, 0x22, 0xB0, 0xFA, 0xB5, 0x7B, 0x76, + 0x00, 0x77, 0x8C, 0x0B, 0xCF, 0x7D, 0xA8, 0x86, 0xCC, 0x26, 0x51, 0xE4, + 0x20, 0x3D, 0x85, 0x0C, 0xD6, 0x58, 0xE3, 0xE7, 0xF4, 0x2A, 0x18, 0x9D, + 0xDA, 0xD1, 0xAE, 0x26, 0xEE, 0xEB, 0x53, 0xDC, 0xF4, 0x90, 0xD6, 0x13, + 0x4A, 0x0C, 0x90, 0x3C, 0xC3, 0xF4, 0xDA, 0xD2, 0x8E, 0x0D, 0x92, 0x3A, + 0xDC, 0xB1, 0xB1, 0xFF, 0x38, 0xDE, 0xC3, 0xBA, 0x2D, 0x5F, 0x80, 0xB9, + 0x02, 0xBD, 0x4A, 0x9D, 0x1B, 0x0F, 0xB4, 0xC3, 0xC2, 0xC1, 0x67, 0x03, + 0xDD, 0xDC, 0x1B, 0x9C, 0x3D, 0xB3, 0xB0, 0xDE, 0x00, 0x1E, 0xA8, 0x34, + 0x47, 0xBB, 0x9A, 0xEB, 0xFE, 0x0B, 0x14, 0xBD, 0x36, 0x84, 0xDA, 0x0D, + 0x20, 0xBF, 0xFA, 0x5B, 0xCB, 0xA9, 0x16, 0x20, 0xAD, 0x39, 0x60, 0xEE, + 0x2F, 0x75, 0xB6, 0xE7, 0x97, 0x9C, 0xF9, 0x3E, 0xFD, 0x7E, 0x4D, 0x6F, + 0x4D, 0x2F, 0xEF, 0x88, 0x0D, 0x6A, 0xFA, 0xDD, 0xF1, 0x3D, 0x6E, 0x20, + 0xA5, 0xA0, 0x12, 0xB4, 0x4D, 0x70, 0xB9, 0xCE, 0xD7, 0x72, 0x3B, 0x89, + 0x93, 0xA7, 0x80, 0x84, 0x1C, 0x27, 0x49, 0x72, 0x49, 0xB5, 0xFF, 0x3B, + 0x95, 0x9E, 0xC1, 0xCC, 0xC8, 0x01, 0xEC, 0xE8, 0x0E, 0x8A, 0x0A, 0x96, + 0xE7, 0xB3, 0xA6, 0x87, 0xE5, 0xD6, 0xF9, 0x05, 0x2B, 0x0D, 0x97, 0x40, + 0x70, 0x3C, 0xBA, 0xAC, 0x75, 0x5A, 0x9C, 0xD5, 0x4D, 0x9D, 0x02, 0x0A, + 0xD2, 0x4B, 0x9B, 0x66, 0x4B, 0x46, 0x07, 0x17, 0x65, 0xAD, 0x9F, 0x6C, + 0x88, 0x00, 0xDC, 0x22, 0x89, 0xE0, 0xE1, 0x64, 0xD4, 0x67, 0xBC, 0x31, + 0x79, 0x61, 0x3C, 0xBB, 0xCA, 0x41, 0xCD, 0x5C, 0x6A, 0x00, 0xC8, 0x3C, + 0x38, 0x8E, 0x58, 0xAF +}; + +static const unsigned char TA348_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA349_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, + 0x36 +}; + +static const unsigned char TA349_EC_Q[] = { + 0x04, 0x76, 0xFA, 0x99, 0xA9, 0x6E, 0x20, 0xED, 0xF9, 0xD7, 0x77, 0xE3, + 0x07, 0x3B, 0xA8, 0xDB, 0x3D, 0x5F, 0x38, 0xE8, 0xAB, 0x55, 0xA6, 0x56, + 0x4F, 0xD6, 0x48, 0xEA, 0xEC, 0x7F, 0x2D, 0xAA, 0xC3, 0xB2, 0xC5, 0x79, + 0xEC, 0x99, 0x61, 0x7F, 0x10, 0x79, 0xC7, 0x02, 0x5A, 0xF9, 0x04, 0x37, + 0xF5, 0x34, 0x35, 0x2B, 0x77, 0xCE, 0x7F, 0x20, 0x8F, 0x52, 0xA3, 0x00, + 0x89, 0xEC, 0xD5, 0xA7, 0xA2, 0x6D, 0x5B, 0xE3, 0x4B, 0x92, 0x93, 0xA0, + 0x80, 0xF5, 0x01, 0x94, 0xDC, 0xF0, 0x68, 0x07, 0x1E, 0xCD, 0xEE, 0xFE, + 0x25, 0x52, 0xB5, 0x20, 0x43, 0x1C, 0x1B, 0xFE, 0xEB, 0x19, 0xCE, 0x43, + 0xA3 +}; + +static const unsigned char TA350_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, + 0x36 +}; + +static const unsigned char TA350_RSA_N[] = { + 0x93, 0xBE, 0xD5, 0x36, 0x52, 0x75, 0xD8, 0x01, 0x23, 0xA0, 0x1C, 0x47, + 0x42, 0x49, 0xEE, 0x63, 0xB6, 0xB7, 0x21, 0xFD, 0xC4, 0x95, 0xD5, 0x48, + 0x2B, 0x26, 0x7C, 0x14, 0x53, 0x10, 0xDA, 0x79, 0xFD, 0x2B, 0xB7, 0x2D, + 0xA4, 0xD4, 0x2C, 0xFA, 0xEA, 0x32, 0xDD, 0x49, 0xC2, 0xB9, 0xBD, 0x0F, + 0x48, 0x3D, 0x7B, 0x5A, 0x98, 0x54, 0xAF, 0x9E, 0x5D, 0x31, 0x74, 0x4F, + 0x07, 0xFC, 0x50, 0x21, 0xDD, 0xA4, 0xCF, 0x68, 0x4F, 0x1B, 0x12, 0x63, + 0x6D, 0x25, 0x99, 0x4C, 0x2A, 0x99, 0xF3, 0x48, 0x30, 0x61, 0xFA, 0x81, + 0x7C, 0x1E, 0xA7, 0x08, 0x4A, 0xDC, 0x3E, 0x2B, 0x1C, 0x1F, 0x18, 0x4C, + 0x71, 0xAA, 0x35, 0x8C, 0xAD, 0xF8, 0x6E, 0xE8, 0x3B, 0x4A, 0xD9, 0xE5, + 0x94, 0x02, 0xD6, 0x89, 0x84, 0x13, 0xAA, 0x6D, 0xC8, 0x4F, 0x33, 0xCC, + 0x50, 0x96, 0x37, 0x92, 0x33, 0xDC, 0x5F, 0x88, 0xE7, 0x9F, 0x54, 0xD9, + 0x48, 0xF0, 0x98, 0x43, 0xD6, 0x66, 0xFD, 0x9F, 0x17, 0x38, 0x43, 0xC5, + 0x01, 0x51, 0x0B, 0xD7, 0xE3, 0x23, 0x0F, 0x14, 0x5D, 0x5B, 0x14, 0xE7, + 0x4B, 0xBE, 0xDD, 0xF4, 0xC8, 0xDA, 0x03, 0x37, 0xD1, 0xD6, 0x39, 0xA1, + 0x21, 0x51, 0x30, 0x83, 0xB0, 0x6D, 0xD7, 0x30, 0x4E, 0x96, 0x5B, 0x91, + 0xF0, 0x70, 0x24, 0xAB, 0xBF, 0x45, 0x81, 0x64, 0x43, 0x0D, 0xBD, 0x21, + 0x3A, 0x2F, 0x3C, 0xE9, 0x9E, 0x0D, 0xCB, 0x20, 0xB5, 0x42, 0x27, 0xCC, + 0xDA, 0x6F, 0x9B, 0xEE, 0x64, 0x30, 0x90, 0x39, 0xCD, 0x93, 0x65, 0x81, + 0x21, 0x31, 0xB5, 0x23, 0x50, 0x33, 0x37, 0x22, 0xE3, 0x38, 0xED, 0xF8, + 0x31, 0x30, 0xCC, 0x45, 0xFE, 0x62, 0xF9, 0xD1, 0x5D, 0x32, 0x79, 0x42, + 0x87, 0xDF, 0x6A, 0xCC, 0x56, 0x19, 0x40, 0x4D, 0xCE, 0xAA, 0xBB, 0xF9, + 0xB5, 0x76, 0x49, 0x94, 0xF1, 0x27, 0xF8, 0x91, 0xA5, 0x83, 0xE5, 0x06, + 0xB3, 0x63, 0x0E, 0x80, 0xDC, 0xE0, 0x12, 0x55, 0x80, 0xA6, 0x3B, 0x66, + 0xB4, 0x39, 0x87, 0x2D, 0xC8, 0xF0, 0xD0, 0xD1, 0x14, 0xE9, 0xE4, 0x0D, + 0x4D, 0x0E, 0xF6, 0x5D, 0x57, 0x72, 0xC5, 0x3B, 0x1C, 0x47, 0x56, 0x9D, + 0xE2, 0xD5, 0xFB, 0x81, 0x61, 0x8C, 0xCC, 0x4D, 0x80, 0x90, 0x34, 0x5B, + 0xB7, 0xD7, 0x14, 0x75, 0xDC, 0xD8, 0x04, 0x48, 0x9F, 0xC0, 0xC1, 0x28, + 0x88, 0xB4, 0xE9, 0x1C, 0xCA, 0xA7, 0xB1, 0xF1, 0x56, 0xB7, 0x7B, 0x49, + 0x4C, 0x59, 0xE5, 0x20, 0x15, 0xA8, 0x84, 0x02, 0x29, 0xFA, 0x38, 0x94, + 0x69, 0x9A, 0x49, 0x06, 0x8F, 0xCD, 0x1F, 0x79, 0x14, 0x17, 0x12, 0x0C, + 0x83, 0x7A, 0xDE, 0x1F, 0xB1, 0x97, 0xEE, 0xF9, 0x97, 0x78, 0x28, 0xA4, + 0xC8, 0x44, 0x92, 0xE9, 0x7D, 0x26, 0x05, 0xA6, 0x58, 0x72, 0x9B, 0x79, + 0x13, 0xD8, 0x11, 0x5F, 0xAE, 0xC5, 0x38, 0x62, 0x34, 0x68, 0xB2, 0x86, + 0x30, 0x8E, 0xF8, 0x90, 0x61, 0x9E, 0x32, 0x6C, 0xF5, 0x07, 0x36, 0xCD, + 0xA2, 0x4C, 0x6E, 0xEC, 0x8A, 0x36, 0xED, 0xF2, 0xE6, 0x99, 0x15, 0x44, + 0x70, 0xC3, 0x7C, 0xBC, 0x9C, 0x39, 0xC0, 0xB4, 0xE1, 0x6B, 0xF7, 0x83, + 0x25, 0x23, 0x57, 0xD9, 0x12, 0x80, 0xE5, 0x49, 0xF0, 0x75, 0x0F, 0xEF, + 0x8D, 0xEB, 0x1C, 0x9B, 0x54, 0x28, 0xB4, 0x21, 0x3C, 0xFC, 0x7C, 0x0A, + 0xFF, 0xEF, 0x7B, 0x6B, 0x75, 0xFF, 0x8B, 0x1D, 0xA0, 0x19, 0x05, 0xAB, + 0xFA, 0xF8, 0x2B, 0x81, 0x42, 0xE8, 0x38, 0xBA, 0xBB, 0xFB, 0xAA, 0xFD, + 0x3D, 0xE0, 0xF3, 0xCA, 0xDF, 0x4E, 0x97, 0x97, 0x29, 0xED, 0xF3, 0x18, + 0x56, 0xE9, 0xA5, 0x96, 0xAC, 0xBD, 0xC3, 0x90, 0x98, 0xB2, 0xE0, 0xF9, + 0xA2, 0xD4, 0xA6, 0x47, 0x43, 0x7C, 0x6D, 0xCF +}; + +static const unsigned char TA350_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA351_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x32 +}; + +static const unsigned char TA351_RSA_N[] = { + 0xBA, 0x39, 0xC1, 0x37, 0x7A, 0x68, 0x45, 0x2B, 0x14, 0xB4, 0xEB, 0xE4, + 0x13, 0xEB, 0x57, 0x75, 0x23, 0x4D, 0x8F, 0x24, 0x2D, 0x16, 0xE8, 0xAE, + 0x8E, 0xC9, 0x7D, 0xA4, 0x57, 0x3B, 0x2A, 0x76, 0x25, 0x33, 0x83, 0x6C, + 0xEA, 0x32, 0x8A, 0x94, 0x9B, 0x4E, 0x3C, 0x96, 0xE4, 0xFD, 0x51, 0xBF, + 0x99, 0xC9, 0x93, 0x7E, 0xBF, 0xF9, 0xAD, 0xA7, 0xB2, 0x48, 0x2B, 0x07, + 0x1C, 0x27, 0xF5, 0x4C, 0xBC, 0x70, 0x12, 0x77, 0xA4, 0x85, 0x54, 0xB5, + 0xFD, 0x90, 0x7A, 0xE4, 0xA3, 0xE4, 0x51, 0x58, 0x03, 0xCD, 0x10, 0x79, + 0x79, 0xEE, 0x6B, 0x93, 0x1F, 0x64, 0x8E, 0x6B, 0x64, 0xAB, 0xA3, 0x13, + 0xE3, 0x71, 0xFE, 0x7D, 0xAB, 0x9C, 0xDD, 0x27, 0x53, 0x37, 0xB3, 0xAA, + 0x18, 0xC2, 0x59, 0x26, 0xEC, 0x5B, 0x1F, 0xD2, 0xE6, 0x65, 0x7C, 0xEF, + 0x93, 0xBD, 0xD8, 0x58, 0x5C, 0x0B, 0xC0, 0xE3, 0x65, 0x6F, 0x3C, 0xC7, + 0xCA, 0x59, 0xE3, 0xFE, 0x6E, 0x5F, 0xAC, 0x83, 0xBE, 0xFD, 0x5D, 0x25, + 0x4E, 0x2A, 0x29, 0x3B, 0xD6, 0x0B, 0xAB, 0x17, 0x32, 0x78, 0xA4, 0xE1, + 0x3E, 0x94, 0x46, 0xBE, 0x62, 0x6E, 0x9B, 0xDE, 0x46, 0xA8, 0xB1, 0x16, + 0xE7, 0x85, 0x6E, 0xF4, 0x08, 0x40, 0x45, 0x11, 0xA0, 0x9E, 0x54, 0x44, + 0x84, 0xF7, 0xD8, 0x36, 0xCE, 0xF5, 0x50, 0x47, 0xDC, 0x2C, 0x30, 0x9B, + 0xEE, 0xC0, 0xF5, 0x96, 0xD2, 0xFE, 0x09, 0x86, 0xC7, 0x06, 0x59, 0xAE, + 0x4F, 0xAE, 0x8E, 0x11, 0x98, 0x7B, 0xF3, 0x0B, 0x52, 0xAA, 0x62, 0x26, + 0xAA, 0x21, 0xDF, 0x8E, 0x25, 0x33, 0x79, 0x97, 0x16, 0x49, 0x8D, 0xF5, + 0x3E, 0xD5, 0x47, 0x9F, 0x37, 0x31, 0x49, 0x33, 0x72, 0x05, 0x4D, 0x0C, + 0xB6, 0x55, 0x8C, 0xF1, 0x57, 0x8F, 0x8A, 0x87, 0xD1, 0xAD, 0xC5, 0x11, + 0x12, 0x39, 0xA0, 0xAD +}; + +static const unsigned char TA351_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA352_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x34 +}; + +static const unsigned char TA352_RSA_N[] = { + 0xC5, 0xD2, 0x7A, 0xA1, 0xD6, 0x8A, 0xBF, 0x16, 0x31, 0xD0, 0x98, 0xD1, + 0x3A, 0x94, 0xFC, 0x5A, 0xB8, 0x6E, 0x22, 0xC1, 0x62, 0xF7, 0xA7, 0x0A, + 0x27, 0xEF, 0x50, 0xF6, 0x2E, 0xB1, 0x9E, 0x68, 0x12, 0xF0, 0x6C, 0x24, + 0x63, 0x39, 0xF1, 0xF0, 0xDF, 0x10, 0xC6, 0xDE, 0xB7, 0x52, 0x20, 0xD5, + 0x52, 0x5B, 0x42, 0x99, 0x9E, 0xF3, 0xA0, 0xBE, 0x52, 0x1F, 0x5F, 0xCC, + 0x67, 0x6D, 0xA7, 0x2E, 0x50, 0xA2, 0xC1, 0x97, 0x8D, 0xB6, 0xF8, 0x95, + 0xF5, 0xB0, 0xBA, 0xDC, 0x9D, 0xE0, 0xBE, 0xCB, 0xDF, 0xF7, 0x38, 0xF2, + 0x47, 0xF5, 0xA6, 0x9A, 0x92, 0x95, 0x2A, 0x62, 0x59, 0x50, 0x0B, 0xA2, + 0xB1, 0x35, 0xE7, 0x65, 0xB2, 0x61, 0xB2, 0xEA, 0x92, 0x71, 0x69, 0xE4, + 0x29, 0xF0, 0x4F, 0x81, 0x81, 0x04, 0x3C, 0xB2, 0xA5, 0x5B, 0xD4, 0xC5, + 0xA8, 0x59, 0x67, 0x7B, 0x55, 0x1C, 0x49, 0xAB, 0x7A, 0x9D, 0xC2, 0xE7, + 0x73, 0x4D, 0xEF, 0xCD, 0x09, 0xC2, 0xC4, 0x57, 0x12, 0xDB, 0x01, 0x0E, + 0x23, 0x79, 0x09, 0x07, 0x3B, 0xA2, 0xE8, 0xFC, 0x8A, 0xCF, 0x8F, 0xC0, + 0x46, 0x24, 0x9C, 0x38, 0x27, 0xE0, 0x83, 0x9D, 0x1B, 0xA0, 0xBF, 0x78, + 0x15, 0x10, 0xEB, 0x86, 0x4E, 0x0A, 0x5A, 0xFD, 0xDF, 0xDA, 0x2C, 0x82, + 0x7E, 0xEE, 0xCA, 0xF6, 0x29, 0xE1, 0xFA, 0x71, 0xA1, 0xF7, 0x88, 0x68, + 0x9C, 0x9C, 0xF0, 0x8D, 0xBE, 0x0F, 0x49, 0x91, 0xD8, 0xEA, 0x3A, 0xF9, + 0xFD, 0xD0, 0x68, 0x71, 0xDB, 0xE9, 0xB5, 0x2B, 0x4E, 0x82, 0x92, 0x6F, + 0x66, 0x1F, 0xE0, 0xF0, 0xDC, 0x4C, 0xEC, 0xCA, 0xD1, 0xEA, 0xBA, 0x74, + 0x06, 0xF9, 0xB3, 0x84, 0x90, 0x94, 0xD1, 0x5F, 0x8E, 0x73, 0x19, 0x10, + 0x5D, 0x02, 0xE5, 0x70, 0xA5, 0xC0, 0x10, 0xD0, 0x10, 0x7C, 0x6F, 0xC5, + 0x58, 0x49, 0xB4, 0xB0, 0x6E, 0x9A, 0xDA, 0x7D, 0x95, 0xF5, 0xCC, 0xDA, + 0x02, 0xAF, 0xB8, 0x2C, 0x7D, 0x79, 0x8F, 0xBE, 0x43, 0xF1, 0xF9, 0x28, + 0x28, 0x8D, 0x09, 0x43, 0xF8, 0x08, 0xDD, 0x6B, 0xC8, 0x8B, 0x2C, 0x24, + 0xB1, 0x8D, 0x52, 0x07, 0xBD, 0x78, 0x9B, 0xCB, 0xCA, 0x68, 0xB2, 0xA4, + 0xDD, 0x0C, 0x4C, 0x79, 0x60, 0xC6, 0x99, 0xD1, 0x93, 0xF1, 0x30, 0x1A, + 0x07, 0xD3, 0xAE, 0x22, 0xC2, 0xEA, 0xCE, 0xF1, 0x84, 0x09, 0xCC, 0xE0, + 0x14, 0x6E, 0x7F, 0x3F, 0x7E, 0xD2, 0x82, 0x85, 0xAC, 0xDC, 0xA9, 0x16, + 0x4E, 0x85, 0xA0, 0x60, 0xCB, 0xF6, 0x9C, 0xD7, 0xC8, 0xB3, 0x8E, 0xED, + 0xC6, 0x9B, 0x98, 0x75, 0x0D, 0x55, 0xE8, 0x5F, 0xE5, 0x95, 0x8B, 0x02, + 0xA4, 0xAE, 0x43, 0x29, 0x28, 0x11, 0xA4, 0xE6, 0x12, 0x30, 0x01, 0x4B, + 0x75, 0x6B, 0x1E, 0x66, 0x9D, 0x79, 0x2F, 0xA5, 0x76, 0x2F, 0x1D, 0x40, + 0xB4, 0x6D, 0xC9, 0x7D, 0x79, 0x08, 0xEC, 0xD1, 0x6A, 0xB6, 0x5D, 0x2A, + 0xB2, 0xA5, 0x66, 0xBD, 0x6B, 0x85, 0xF4, 0x74, 0x56, 0xC3, 0xF5, 0xE7, + 0x75, 0x52, 0x28, 0x2C, 0xA5, 0xFF, 0x66, 0x47, 0xA5, 0xD4, 0xFE, 0xFE, + 0x9E, 0x54, 0xBF, 0x65, 0x7E, 0x01, 0xD6, 0x30, 0x8F, 0xA5, 0x36, 0x9C, + 0xA2, 0x50, 0x1C, 0xEE, 0x38, 0x80, 0x01, 0x48, 0xC6, 0xC7, 0x74, 0xF4, + 0xC6, 0xAC, 0xC3, 0x40, 0x49, 0x16, 0x61, 0x74, 0x2C, 0xAF, 0x8C, 0x6F, + 0x35, 0xED, 0x7B, 0x18, 0x00, 0x5B, 0x36, 0x3C, 0x9C, 0x50, 0x0D, 0xCA, + 0x92, 0x33, 0x10, 0xF1, 0x26, 0x49, 0x6D, 0xDF, 0x75, 0x24, 0x37, 0x82, + 0x22, 0xD7, 0xE8, 0x96, 0xFD, 0x15, 0x4B, 0x02, 0x96, 0x3E, 0x07, 0x72, + 0x95, 0x7E, 0xAB, 0x3D, 0x4C, 0x2E, 0xD7, 0xCA, 0xF0, 0xDF, 0xE0, 0x58, + 0x3F, 0x2D, 0x2F, 0x04, 0x9A, 0x38, 0xA3, 0x01 +}; + +static const unsigned char TA352_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA353_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x35 +}; + +static const unsigned char TA353_EC_Q[] = { + 0x04, 0x0B, 0x50, 0x74, 0x8D, 0x64, 0x32, 0x99, 0x99, 0xB3, 0xD2, 0x60, + 0x08, 0xB8, 0x22, 0x8E, 0x46, 0x74, 0x2C, 0x78, 0xC0, 0x2B, 0x44, 0x2D, + 0x6D, 0x5F, 0x1D, 0xC9, 0xAE, 0x4B, 0x52, 0x20, 0x83, 0x3D, 0xB8, 0x14, + 0x6D, 0x53, 0x87, 0x60, 0x9E, 0x5F, 0x6C, 0x85, 0xDB, 0x06, 0x14, 0x95, + 0xE0, 0xC7, 0x28, 0xFF, 0x9D, 0x5F, 0xE4, 0xAA, 0xF1, 0xB3, 0x8B, 0x6D, + 0xED, 0x4F, 0x2F, 0x4B, 0xC9, 0x4A, 0x94, 0x91, 0x64, 0x75, 0xFE, 0x01, + 0xEC, 0xC1, 0xD8, 0xEB, 0x7A, 0x94, 0x78, 0x56, 0x18, 0x43, 0x5F, 0x6B, + 0x81, 0xCB, 0xF6, 0xBC, 0xDA, 0xB4, 0x0C, 0xB6, 0x29, 0x93, 0x08, 0x69, + 0x8F +}; + +static const unsigned char TA354_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0E, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA354_RSA_N[] = { + 0xAB, 0xA4, 0x81, 0xE5, 0x95, 0xCD, 0xF5, 0xF6, 0x14, 0x8E, 0xC2, 0x4F, + 0xCA, 0xD4, 0xE2, 0x78, 0x95, 0x58, 0x9C, 0x41, 0xE1, 0x0D, 0x99, 0x40, + 0x24, 0x17, 0x39, 0x91, 0x33, 0x66, 0xE9, 0xBE, 0xE1, 0x83, 0xAF, 0x62, + 0x5C, 0x89, 0xD1, 0xFC, 0x24, 0x5B, 0x61, 0xB3, 0xE0, 0x11, 0x11, 0x41, + 0x1C, 0x1D, 0x6E, 0xF0, 0xB8, 0xBB, 0xF8, 0xDE, 0xA7, 0x81, 0xBA, 0xA6, + 0x48, 0xC6, 0x9F, 0x1D, 0xBD, 0xBE, 0x8E, 0xA9, 0x41, 0x3E, 0xB8, 0x94, + 0xED, 0x29, 0x1A, 0xD4, 0x8E, 0xD2, 0x03, 0x1D, 0x03, 0xEF, 0x6D, 0x0D, + 0x67, 0x1C, 0x57, 0xD7, 0x06, 0xAD, 0xCA, 0xC8, 0xF5, 0xFE, 0x0E, 0xAF, + 0x66, 0x25, 0x48, 0x04, 0x96, 0x0B, 0x5D, 0xA3, 0xBA, 0x16, 0xC3, 0x08, + 0x4F, 0xD1, 0x46, 0xF8, 0x14, 0x5C, 0xF2, 0xC8, 0x5E, 0x01, 0x99, 0x6D, + 0xFD, 0x88, 0xCC, 0x86, 0xA8, 0xC1, 0x6F, 0x31, 0x42, 0x6C, 0x52, 0x3E, + 0x68, 0xCB, 0xF3, 0x19, 0x34, 0xDF, 0xBB, 0x87, 0x18, 0x56, 0x80, 0x26, + 0xC4, 0xD0, 0xDC, 0xC0, 0x6F, 0xDF, 0xDE, 0xA0, 0xC2, 0x91, 0x16, 0xA0, + 0x64, 0x11, 0x4B, 0x44, 0xBC, 0x1E, 0xF6, 0xE7, 0xFA, 0x63, 0xDE, 0x66, + 0xAC, 0x76, 0xA4, 0x71, 0xA3, 0xEC, 0x36, 0x94, 0x68, 0x7A, 0x77, 0xA4, + 0xB1, 0xE7, 0x0E, 0x2F, 0x81, 0x7A, 0xE2, 0xB5, 0x72, 0x86, 0xEF, 0xA2, + 0x6B, 0x8B, 0xF0, 0x0F, 0xDB, 0xD3, 0x59, 0x3F, 0xBA, 0x72, 0xBC, 0x44, + 0x24, 0x9C, 0xE3, 0x73, 0xB3, 0xF7, 0xAF, 0x57, 0x2F, 0x42, 0x26, 0x9D, + 0xA9, 0x74, 0xBA, 0x00, 0x52, 0xF2, 0x4B, 0xCD, 0x53, 0x7C, 0x47, 0x0B, + 0x36, 0x85, 0x0E, 0x66, 0xA9, 0x08, 0x97, 0x16, 0x34, 0x57, 0xC1, 0x66, + 0xF7, 0x80, 0xE3, 0xED, 0x70, 0x54, 0xC7, 0x93, 0xE0, 0x2E, 0x28, 0x15, + 0x59, 0x87, 0xBA, 0xBB +}; + +static const unsigned char TA354_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA355_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA355_RSA_N[] = { + 0xAF, 0x35, 0x2E, 0xD8, 0xAC, 0x6C, 0x55, 0x69, 0x06, 0x71, 0xE5, 0x13, + 0x68, 0x24, 0xB3, 0x4F, 0xD8, 0xCC, 0x21, 0x47, 0xF8, 0xF1, 0x60, 0x38, + 0x89, 0x89, 0x03, 0xE9, 0xBD, 0xEA, 0x5E, 0x46, 0x53, 0x09, 0xDC, 0x5C, + 0xF5, 0x5A, 0xE8, 0xF7, 0x45, 0x2A, 0x02, 0xEB, 0x31, 0x61, 0xD7, 0x29, + 0x33, 0x4C, 0xCE, 0xC7, 0x7C, 0x0A, 0x37, 0x7E, 0x0F, 0xBA, 0x32, 0x98, + 0xE1, 0x1D, 0x97, 0xAF, 0x8F, 0xC7, 0xDC, 0xC9, 0x38, 0x96, 0xF3, 0xDB, + 0x1A, 0xFC, 0x51, 0xED, 0x68, 0xC6, 0xD0, 0x6E, 0xA4, 0x7C, 0x24, 0xD1, + 0xAE, 0x42, 0xC8, 0x96, 0x50, 0x63, 0x2E, 0xE0, 0xFE, 0x75, 0xFE, 0x98, + 0xA7, 0x5F, 0x49, 0x2E, 0x95, 0xE3, 0x39, 0x33, 0x64, 0x8E, 0x1E, 0xA4, + 0x5F, 0x90, 0xD2, 0x67, 0x3C, 0xB2, 0xD9, 0xFE, 0x41, 0xB9, 0x55, 0xA7, + 0x09, 0x8E, 0x72, 0x05, 0x1E, 0x8B, 0xDD, 0x44, 0x85, 0x82, 0x42, 0xD0, + 0x49, 0xC0, 0x1D, 0x60, 0xF0, 0xD1, 0x17, 0x2C, 0x95, 0xEB, 0xF6, 0xA5, + 0xC1, 0x92, 0xA3, 0xC5, 0xC2, 0xA7, 0x08, 0x60, 0x0D, 0x60, 0x04, 0x10, + 0x96, 0x79, 0x9E, 0x16, 0x34, 0xE6, 0xA9, 0xB6, 0xFA, 0x25, 0x45, 0x39, + 0xC8, 0x1E, 0x65, 0xF9, 0x93, 0xF5, 0xAA, 0xF1, 0x52, 0xDC, 0x99, 0x98, + 0x3D, 0xA5, 0x86, 0x1A, 0x0C, 0x35, 0x33, 0xFA, 0x4B, 0xA5, 0x04, 0x06, + 0x15, 0x1C, 0x31, 0x80, 0xEF, 0xAA, 0x18, 0x6B, 0xC2, 0x7B, 0xD7, 0xDA, + 0xCE, 0xF9, 0x33, 0x20, 0xD5, 0xF5, 0xBD, 0x6A, 0x33, 0x2D, 0x81, 0x04, + 0xFB, 0xB0, 0x5C, 0xD4, 0x9C, 0xA3, 0xE2, 0x5C, 0x1D, 0xE3, 0xA9, 0x42, + 0x75, 0x5E, 0x7B, 0xD4, 0x77, 0xEF, 0x39, 0x54, 0xBA, 0xC9, 0x0A, 0x18, + 0x1B, 0x12, 0x99, 0x49, 0x2F, 0x88, 0x4B, 0xFD, 0x50, 0x62, 0xD1, 0x73, + 0xE7, 0x8F, 0x7A, 0x43 +}; + +static const unsigned char TA355_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA356_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x43, 0x41, 0x31 +}; + +static const unsigned char TA356_EC_Q[] = { + 0x04, 0xA4, 0xA5, 0x6F, 0x60, 0x03, 0x03, 0xC3, 0xBD, 0x31, 0xF4, 0xD3, + 0x17, 0x9C, 0x2B, 0x84, 0x75, 0xAC, 0xE5, 0xFD, 0x3D, 0x57, 0x6E, 0xD7, + 0x63, 0xBF, 0xE6, 0x04, 0x89, 0x92, 0x8E, 0x81, 0x9C, 0xE3, 0xE9, 0x47, + 0x6E, 0xCA, 0x90, 0x12, 0xC8, 0x13, 0xE0, 0xA7, 0x9D, 0xF7, 0x65, 0x74, + 0x1F, 0x6C, 0x10, 0xB2, 0xE8, 0xE4, 0xE9, 0xEF, 0x6D, 0x85, 0x32, 0x99, + 0x44, 0xB1, 0x5E, 0xFD, 0xCC, 0x76, 0x10, 0xD8, 0x5B, 0xBD, 0xA2, 0xC6, + 0xF9, 0xD6, 0x42, 0xE4, 0x57, 0x76, 0xDC, 0x90, 0xC2, 0x35, 0xA9, 0x4B, + 0x88, 0x3C, 0x12, 0x47, 0x6D, 0x5C, 0xFF, 0x49, 0x4F, 0x1A, 0x4A, 0x50, + 0xB1 +}; + +static const unsigned char TA357_DN[] = { + 0x30, 0x5D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x1E, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA357_RSA_N[] = { + 0xD0, 0x15, 0x39, 0x52, 0xB1, 0x52, 0xB3, 0xBA, 0xC5, 0x59, 0x82, 0xC4, + 0x5D, 0x52, 0xAE, 0x3A, 0x43, 0x65, 0x80, 0x4B, 0xC7, 0xF2, 0x96, 0xBC, + 0xDB, 0x36, 0x97, 0xD6, 0xA6, 0x64, 0x8C, 0xA8, 0x5E, 0xF0, 0xE3, 0x0A, + 0x1C, 0xF7, 0xDF, 0x97, 0x3D, 0x4B, 0xAE, 0xF6, 0x5D, 0xEC, 0x21, 0xB5, + 0x41, 0xAB, 0xCD, 0xB9, 0x7E, 0x76, 0x9F, 0xBE, 0xF9, 0x3E, 0x36, 0x34, + 0xA0, 0x3B, 0xC1, 0xF6, 0x31, 0x11, 0x45, 0x74, 0x93, 0x3D, 0x57, 0x80, + 0xC5, 0xF9, 0x89, 0x99, 0xCA, 0xE5, 0xAB, 0x6A, 0xD4, 0xB5, 0xDA, 0x41, + 0x90, 0x10, 0xC1, 0xD6, 0xD6, 0x42, 0x89, 0xC2, 0xBF, 0xF4, 0x38, 0x12, + 0x95, 0x4C, 0x54, 0x05, 0xF7, 0x36, 0xE4, 0x45, 0x83, 0x7B, 0x14, 0x65, + 0xD6, 0xDC, 0x0C, 0x4D, 0xD1, 0xDE, 0x7E, 0x0C, 0xAB, 0x3B, 0xC4, 0x15, + 0xBE, 0x3A, 0x56, 0xA6, 0x5A, 0x6F, 0x76, 0x69, 0x52, 0xA9, 0x7A, 0xB9, + 0xC8, 0xEB, 0x6A, 0x9A, 0x5D, 0x52, 0xD0, 0x2D, 0x0A, 0x6B, 0x35, 0x16, + 0x09, 0x10, 0x84, 0xD0, 0x6A, 0xCA, 0x3A, 0x06, 0x00, 0x37, 0x47, 0xE4, + 0x7E, 0x57, 0x4F, 0x3F, 0x8B, 0xEB, 0x67, 0xB8, 0x88, 0xAA, 0xC5, 0xBE, + 0x53, 0x55, 0xB2, 0x91, 0xC4, 0x7D, 0xB9, 0xB0, 0x85, 0x19, 0x06, 0x78, + 0x2E, 0xDB, 0x61, 0x1A, 0xFA, 0x85, 0xF5, 0x4A, 0x91, 0xA1, 0xE7, 0x16, + 0xD5, 0x8E, 0xA2, 0x39, 0xDF, 0x94, 0xB8, 0x70, 0x1F, 0x28, 0x3F, 0x8B, + 0xFC, 0x40, 0x5E, 0x63, 0x83, 0x3C, 0x83, 0x2A, 0x1A, 0x99, 0x6B, 0xCF, + 0xDE, 0x59, 0x6A, 0x3B, 0xFC, 0x6F, 0x16, 0xD7, 0x1F, 0xFD, 0x4A, 0x10, + 0xEB, 0x4E, 0x82, 0x16, 0x3A, 0xAC, 0x27, 0x0C, 0x53, 0xF1, 0xAD, 0xD5, + 0x24, 0xB0, 0x6B, 0x03, 0x50, 0xC1, 0x2D, 0x3C, 0x16, 0xDD, 0x44, 0x34, + 0x27, 0x1A, 0x75, 0xFB +}; + +static const unsigned char TA357_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA358_DN[] = { + 0x30, 0x68, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, + 0x6C, 0x64, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA358_RSA_N[] = { + 0xB7, 0x32, 0xC8, 0xFE, 0xE9, 0x71, 0xA6, 0x04, 0x85, 0xAD, 0x0C, 0x11, + 0x64, 0xDF, 0xCE, 0x4D, 0xEF, 0xC8, 0x03, 0x18, 0x87, 0x3F, 0xA1, 0xAB, + 0xFB, 0x3C, 0xA6, 0x9F, 0xF0, 0xC3, 0xA1, 0xDA, 0xD4, 0xD8, 0x6E, 0x2B, + 0x53, 0x90, 0xFB, 0x24, 0xA4, 0x3E, 0x84, 0xF0, 0x9E, 0xE8, 0x5F, 0xEC, + 0xE5, 0x27, 0x44, 0xF5, 0x28, 0xA6, 0x3F, 0x7B, 0xDE, 0xE0, 0x2A, 0xF0, + 0xC8, 0xAF, 0x53, 0x2F, 0x9E, 0xCA, 0x05, 0x01, 0x93, 0x1E, 0x8F, 0x66, + 0x1C, 0x39, 0xA7, 0x4D, 0xFA, 0x5A, 0xB6, 0x73, 0x04, 0x25, 0x66, 0xEB, + 0x77, 0x7F, 0xE7, 0x59, 0xC6, 0x4A, 0x99, 0x25, 0x14, 0x54, 0xEB, 0x26, + 0xC7, 0xF3, 0x7F, 0x19, 0xD5, 0x30, 0x70, 0x8F, 0xAF, 0xB0, 0x46, 0x2A, + 0xFF, 0xAD, 0xEB, 0x29, 0xED, 0xD7, 0x9F, 0xAA, 0x04, 0x87, 0xA3, 0xD4, + 0xF9, 0x89, 0xA5, 0x34, 0x5F, 0xDB, 0x43, 0x91, 0x82, 0x36, 0xD9, 0x66, + 0x3C, 0xB1, 0xB8, 0xB9, 0x82, 0xFD, 0x9C, 0x3A, 0x3E, 0x10, 0xC8, 0x3B, + 0xEF, 0x06, 0x65, 0x66, 0x7A, 0x9B, 0x19, 0x18, 0x3D, 0xFF, 0x71, 0x51, + 0x3C, 0x30, 0x2E, 0x5F, 0xBE, 0x3D, 0x77, 0x73, 0xB2, 0x5D, 0x06, 0x6C, + 0xC3, 0x23, 0x56, 0x9A, 0x2B, 0x85, 0x26, 0x92, 0x1C, 0xA7, 0x02, 0xB3, + 0xE4, 0x3F, 0x0D, 0xAF, 0x08, 0x79, 0x82, 0xB8, 0x36, 0x3D, 0xEA, 0x9C, + 0xD3, 0x35, 0xB3, 0xBC, 0x69, 0xCA, 0xF5, 0xCC, 0x9D, 0xE8, 0xFD, 0x64, + 0x8D, 0x17, 0x80, 0x33, 0x6E, 0x5E, 0x4A, 0x5D, 0x99, 0xC9, 0x1E, 0x87, + 0xB4, 0x9D, 0x1A, 0xC0, 0xD5, 0x6E, 0x13, 0x35, 0x23, 0x5E, 0xDF, 0x9B, + 0x5F, 0x3D, 0xEF, 0xD6, 0xF7, 0x76, 0xC2, 0xEA, 0x3E, 0xBB, 0x78, 0x0D, + 0x1C, 0x42, 0x67, 0x6B, 0x04, 0xD8, 0xF8, 0xD6, 0xDA, 0x6F, 0x8B, 0xF2, + 0x44, 0xA0, 0x01, 0xAB +}; + +static const unsigned char TA358_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA359_DN[] = { + 0x30, 0x81, 0x8F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, + 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA359_RSA_N[] = { + 0xBD, 0xED, 0xC1, 0x03, 0xFC, 0xF6, 0x8F, 0xFC, 0x02, 0xB1, 0x6F, 0x5B, + 0x9F, 0x48, 0xD9, 0x9D, 0x79, 0xE2, 0xA2, 0xB7, 0x03, 0x61, 0x56, 0x18, + 0xC3, 0x47, 0xB6, 0xD7, 0xCA, 0x3D, 0x35, 0x2E, 0x89, 0x43, 0xF7, 0xA1, + 0x69, 0x9B, 0xDE, 0x8A, 0x1A, 0xFD, 0x13, 0x20, 0x9C, 0xB4, 0x49, 0x77, + 0x32, 0x29, 0x56, 0xFD, 0xB9, 0xEC, 0x8C, 0xDD, 0x22, 0xFA, 0x72, 0xDC, + 0x27, 0x61, 0x97, 0xEE, 0xF6, 0x5A, 0x84, 0xEC, 0x6E, 0x19, 0xB9, 0x89, + 0x2C, 0xDC, 0x84, 0x5B, 0xD5, 0x74, 0xFB, 0x6B, 0x5F, 0xC5, 0x89, 0xA5, + 0x10, 0x52, 0x89, 0x46, 0x55, 0xF4, 0xB8, 0x75, 0x1C, 0xE6, 0x7F, 0xE4, + 0x54, 0xAE, 0x4B, 0xF8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xF8, 0x17, 0x71, + 0x59, 0xEB, 0x1E, 0x28, 0x07, 0x74, 0xC5, 0x9D, 0x48, 0xBE, 0x6C, 0xB4, + 0xF4, 0xA4, 0xB0, 0xF3, 0x64, 0x37, 0x79, 0x92, 0xC0, 0xEC, 0x46, 0x5E, + 0x7F, 0xE1, 0x6D, 0x53, 0x4C, 0x62, 0xAF, 0xCD, 0x1F, 0x0B, 0x63, 0xBB, + 0x3A, 0x9D, 0xFB, 0xFC, 0x79, 0x00, 0x98, 0x61, 0x74, 0xCF, 0x26, 0x82, + 0x40, 0x63, 0xF3, 0xB2, 0x72, 0x6A, 0x19, 0x0D, 0x99, 0xCA, 0xD4, 0x0E, + 0x75, 0xCC, 0x37, 0xFB, 0x8B, 0x89, 0xC1, 0x59, 0xF1, 0x62, 0x7F, 0x5F, + 0xB3, 0x5F, 0x65, 0x30, 0xF8, 0xA7, 0xB7, 0x4D, 0x76, 0x5A, 0x1E, 0x76, + 0x5E, 0x34, 0xC0, 0xE8, 0x96, 0x56, 0x99, 0x8A, 0xB3, 0xF0, 0x7F, 0xA4, + 0xCD, 0xBD, 0xDC, 0x32, 0x31, 0x7C, 0x91, 0xCF, 0xE0, 0x5F, 0x11, 0xF8, + 0x6B, 0xAA, 0x49, 0x5C, 0xD1, 0x99, 0x94, 0xD1, 0xA2, 0xE3, 0x63, 0x5B, + 0x09, 0x76, 0xB5, 0x56, 0x62, 0xE1, 0x4B, 0x74, 0x1D, 0x96, 0xD4, 0x26, + 0xD4, 0x08, 0x04, 0x59, 0xD0, 0x98, 0x0E, 0x0E, 0xE6, 0xDE, 0xFC, 0xC3, + 0xEC, 0x1F, 0x90, 0xF1 +}; + +static const unsigned char TA359_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA360_DN[] = { + 0x30, 0x81, 0x98, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3B, + 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA360_RSA_N[] = { + 0xD5, 0x0C, 0x3A, 0xC4, 0x2A, 0xF9, 0x4E, 0xE2, 0xF5, 0xBE, 0x19, 0x97, + 0x5F, 0x8E, 0x88, 0x53, 0xB1, 0x1F, 0x3F, 0xCB, 0xCF, 0x9F, 0x20, 0x13, + 0x6D, 0x29, 0x3A, 0xC8, 0x0F, 0x7D, 0x3C, 0xF7, 0x6B, 0x76, 0x38, 0x63, + 0xD9, 0x36, 0x60, 0xA8, 0x9B, 0x5E, 0x5C, 0x00, 0x80, 0xB2, 0x2F, 0x59, + 0x7F, 0xF6, 0x87, 0xF9, 0x25, 0x43, 0x86, 0xE7, 0x69, 0x1B, 0x52, 0x9A, + 0x90, 0xE1, 0x71, 0xE3, 0xD8, 0x2D, 0x0D, 0x4E, 0x6F, 0xF6, 0xC8, 0x49, + 0xD9, 0xB6, 0xF3, 0x1A, 0x56, 0xAE, 0x2B, 0xB6, 0x74, 0x14, 0xEB, 0xCF, + 0xFB, 0x26, 0xE3, 0x1A, 0xBA, 0x1D, 0x96, 0x2E, 0x6A, 0x3B, 0x58, 0x94, + 0x89, 0x47, 0x56, 0xFF, 0x25, 0xA0, 0x93, 0x70, 0x53, 0x83, 0xDA, 0x84, + 0x74, 0x14, 0xC3, 0x67, 0x9E, 0x04, 0x68, 0x3A, 0xDF, 0x8E, 0x40, 0x5A, + 0x1D, 0x4A, 0x4E, 0xCF, 0x43, 0x91, 0x3B, 0xE7, 0x56, 0xD6, 0x00, 0x70, + 0xCB, 0x52, 0xEE, 0x7B, 0x7D, 0xAE, 0x3A, 0xE7, 0xBC, 0x31, 0xF9, 0x45, + 0xF6, 0xC2, 0x60, 0xCF, 0x13, 0x59, 0x02, 0x2B, 0x80, 0xCC, 0x34, 0x47, + 0xDF, 0xB9, 0xDE, 0x90, 0x65, 0x6D, 0x02, 0xCF, 0x2C, 0x91, 0xA6, 0xA6, + 0xE7, 0xDE, 0x85, 0x18, 0x49, 0x7C, 0x66, 0x4E, 0xA3, 0x3A, 0x6D, 0xA9, + 0xB5, 0xEE, 0x34, 0x2E, 0xBA, 0x0D, 0x03, 0xB8, 0x33, 0xDF, 0x47, 0xEB, + 0xB1, 0x6B, 0x8D, 0x25, 0xD9, 0x9B, 0xCE, 0x81, 0xD1, 0x45, 0x46, 0x32, + 0x96, 0x70, 0x87, 0xDE, 0x02, 0x0E, 0x49, 0x43, 0x85, 0xB6, 0x6C, 0x73, + 0xBB, 0x64, 0xEA, 0x61, 0x41, 0xAC, 0xC9, 0xD4, 0x54, 0xDF, 0x87, 0x2F, + 0xC7, 0x22, 0xB2, 0x26, 0xCC, 0x9F, 0x59, 0x54, 0x68, 0x9F, 0xFC, 0xBE, + 0x2A, 0x2F, 0xC4, 0x55, 0x1C, 0x75, 0x40, 0x60, 0x17, 0x85, 0x02, 0x55, + 0x39, 0x8B, 0x7F, 0x05 +}; + +static const unsigned char TA360_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA361_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x41, 0x47, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x16, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, + 0x6F, 0x6C, 0x64, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA361_RSA_N[] = { + 0xAF, 0xE4, 0xEE, 0x7E, 0x8B, 0x24, 0x0E, 0x12, 0x6E, 0xA9, 0x50, 0x2D, + 0x16, 0x44, 0x3B, 0x92, 0x92, 0x5C, 0xCA, 0xB8, 0x5D, 0x84, 0x92, 0x42, + 0x13, 0x2A, 0xBC, 0x65, 0x57, 0x82, 0x40, 0x3E, 0x57, 0x24, 0xCD, 0x50, + 0x8B, 0x25, 0x2A, 0xB7, 0x6F, 0xFC, 0xEF, 0xA2, 0xD0, 0xC0, 0x1F, 0x02, + 0x24, 0x4A, 0x13, 0x96, 0x8F, 0x23, 0x13, 0xE6, 0x28, 0x58, 0x00, 0xA3, + 0x47, 0xC7, 0x06, 0xA7, 0x84, 0x23, 0x2B, 0xBB, 0xBD, 0x96, 0x2B, 0x7F, + 0x55, 0xCC, 0x8B, 0xC1, 0x57, 0x1F, 0x0E, 0x62, 0x65, 0x0F, 0xDD, 0x3D, + 0x56, 0x8A, 0x73, 0xDA, 0xAE, 0x7E, 0x6D, 0xBA, 0x81, 0x1C, 0x7E, 0x42, + 0x8C, 0x20, 0x35, 0xD9, 0x43, 0x4D, 0x84, 0xFA, 0x84, 0xDB, 0x52, 0x2C, + 0xF3, 0x0E, 0x27, 0x77, 0x0B, 0x6B, 0xBF, 0x11, 0x2F, 0x72, 0x78, 0x9F, + 0x2E, 0xD8, 0x3E, 0xE6, 0x18, 0x37, 0x5A, 0x2A, 0x72, 0xF9, 0xDA, 0x62, + 0x90, 0x92, 0x95, 0xCA, 0x1F, 0x9C, 0xE9, 0xB3, 0x3C, 0x2B, 0xCB, 0xF3, + 0x01, 0x13, 0xBF, 0x5A, 0xCF, 0xC1, 0xB5, 0x0A, 0x60, 0xBD, 0xDD, 0xB5, + 0x99, 0x64, 0x53, 0xB8, 0xA0, 0x96, 0xB3, 0x6F, 0xE2, 0x26, 0x77, 0x91, + 0x8C, 0xE0, 0x62, 0x10, 0x02, 0x9F, 0x34, 0x0F, 0xA4, 0xD5, 0x92, 0x33, + 0x51, 0xDE, 0xBE, 0x8D, 0xBA, 0x84, 0x7A, 0x60, 0x3C, 0x6A, 0xDB, 0x9F, + 0x2B, 0xEC, 0xDE, 0xDE, 0x01, 0x3F, 0x6E, 0x4D, 0xE5, 0x50, 0x86, 0xCB, + 0xB4, 0xAF, 0xED, 0x44, 0x40, 0xC5, 0xCA, 0x5A, 0x8C, 0xDA, 0xD2, 0x2B, + 0x7C, 0xA8, 0xEE, 0xBE, 0xA6, 0xE5, 0x0A, 0xAA, 0x0E, 0xA5, 0xDF, 0x05, + 0x52, 0xB7, 0x55, 0xC7, 0x22, 0x5D, 0x32, 0x6A, 0x97, 0x97, 0x63, 0x13, + 0xDB, 0xC9, 0xDB, 0x79, 0x36, 0x7B, 0x85, 0x3A, 0x4A, 0xC5, 0x52, 0x89, + 0xF9, 0x24, 0xE7, 0x9D, 0x77, 0xA9, 0x82, 0xFF, 0x55, 0x1C, 0xA5, 0x71, + 0x69, 0x2B, 0xD1, 0x02, 0x24, 0xF2, 0xB3, 0x26, 0xD4, 0x6B, 0xDA, 0x04, + 0x55, 0xE5, 0xC1, 0x0A, 0xC7, 0x6D, 0x30, 0x37, 0x90, 0x2A, 0xE4, 0x9E, + 0x14, 0x33, 0x5E, 0x16, 0x17, 0x55, 0xC5, 0x5B, 0xB5, 0xCB, 0x34, 0x89, + 0x92, 0xF1, 0x9D, 0x26, 0x8F, 0xA1, 0x07, 0xD4, 0xC6, 0xB2, 0x78, 0x50, + 0xDB, 0x0C, 0x0C, 0x0B, 0x7C, 0x0B, 0x8C, 0x41, 0xD7, 0xB9, 0xE9, 0xDD, + 0x8C, 0x88, 0xF7, 0xA3, 0x4D, 0xB2, 0x32, 0xCC, 0xD8, 0x17, 0xDA, 0xCD, + 0xB7, 0xCE, 0x66, 0x9D, 0xD4, 0xFD, 0x5E, 0xFF, 0xBD, 0x97, 0x3E, 0x29, + 0x75, 0xE7, 0x7E, 0xA7, 0x62, 0x58, 0xAF, 0x25, 0x34, 0xA5, 0x41, 0xC7, + 0x3D, 0xBC, 0x0D, 0x50, 0xCA, 0x03, 0x03, 0x0F, 0x08, 0x5A, 0x1F, 0x95, + 0x73, 0x78, 0x62, 0xBF, 0xAF, 0x72, 0x14, 0x69, 0x0E, 0xA5, 0xE5, 0x03, + 0x0E, 0x78, 0x8E, 0x26, 0x28, 0x42, 0xF0, 0x07, 0x0B, 0x62, 0x20, 0x10, + 0x67, 0x39, 0x46, 0xFA, 0xA9, 0x03, 0xCC, 0x04, 0x38, 0x7A, 0x66, 0xEF, + 0x20, 0x83, 0xB5, 0x8C, 0x4A, 0x56, 0x8E, 0x91, 0x00, 0xFC, 0x8E, 0x5C, + 0x82, 0xDE, 0x88, 0xA0, 0xC3, 0xE2, 0x68, 0x6E, 0x7D, 0x8D, 0xEF, 0x3C, + 0xDD, 0x65, 0xF4, 0x5D, 0xAC, 0x51, 0xEF, 0x24, 0x80, 0xAE, 0xAA, 0x56, + 0x97, 0x6F, 0xF9, 0xAD, 0x7D, 0xDA, 0x61, 0x3F, 0x98, 0x77, 0x3C, 0xA5, + 0x91, 0xB6, 0x1C, 0x8C, 0x26, 0xDA, 0x65, 0xA2, 0x09, 0x6D, 0xC1, 0xE2, + 0x54, 0xE3, 0xB9, 0xCA, 0x4C, 0x4C, 0x80, 0x8F, 0x77, 0x7B, 0x60, 0x9A, + 0x1E, 0xDF, 0xB6, 0xF2, 0x48, 0x1E, 0x0E, 0xBA, 0x4E, 0x54, 0x6D, 0x98, + 0xE0, 0xE1, 0xA2, 0x1A, 0xA2, 0x77, 0x50, 0xCF, 0xC4, 0x63, 0x92, 0xEC, + 0x47, 0x19, 0x9D, 0xEB, 0xE6, 0x6B, 0xCE, 0xC1 +}; + +static const unsigned char TA361_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA362_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x32 +}; + +static const unsigned char TA362_RSA_N[] = { + 0xAA, 0x5F, 0xDA, 0x1B, 0x5F, 0xE8, 0x73, 0x91, 0xE5, 0xDA, 0x5C, 0xF4, + 0xA2, 0xE6, 0x47, 0xE5, 0xF3, 0x68, 0x55, 0x60, 0x05, 0x1D, 0x02, 0xA4, + 0xB3, 0x9B, 0x59, 0xF3, 0x1E, 0x8A, 0xAF, 0x34, 0xAD, 0xFC, 0x0D, 0xC2, + 0xD9, 0x48, 0x19, 0xEE, 0x69, 0x8F, 0xC9, 0x20, 0xFC, 0x21, 0xAA, 0x07, + 0x19, 0xED, 0xB0, 0x5C, 0xAC, 0x65, 0xC7, 0x5F, 0xED, 0x02, 0x7C, 0x7B, + 0x7C, 0x2D, 0x1B, 0xD6, 0xBA, 0xB9, 0x80, 0xC2, 0x18, 0x82, 0x16, 0x84, + 0xFA, 0x66, 0xB0, 0x08, 0xC6, 0x54, 0x23, 0x81, 0xE4, 0xCD, 0xB9, 0x49, + 0x3F, 0xF6, 0x4F, 0x6E, 0x37, 0x48, 0x28, 0x38, 0x0F, 0xC5, 0xBE, 0xE7, + 0x68, 0x70, 0xFD, 0x39, 0x97, 0x4D, 0xD2, 0xC7, 0x98, 0x91, 0x50, 0xAA, + 0xC4, 0x44, 0xB3, 0x23, 0x7D, 0x39, 0x47, 0xE9, 0x52, 0x62, 0xD6, 0x12, + 0x93, 0x5E, 0xB7, 0x31, 0x96, 0x42, 0x05, 0xFB, 0x76, 0xA7, 0x1E, 0xA3, + 0xF5, 0xC2, 0xFC, 0xE9, 0x7A, 0xC5, 0x6C, 0xA9, 0x71, 0x4F, 0xEA, 0xCB, + 0x78, 0xBC, 0x60, 0xAF, 0xC7, 0xDE, 0xF4, 0xD9, 0xCB, 0xBE, 0x7E, 0x33, + 0xA5, 0x6E, 0x94, 0x83, 0xF0, 0x34, 0xFA, 0x21, 0xAB, 0xEA, 0x8E, 0x72, + 0xA0, 0x3F, 0xA4, 0xDE, 0x30, 0x5B, 0xEF, 0x86, 0x4D, 0x6A, 0x95, 0x5B, + 0x43, 0x44, 0xA8, 0x10, 0x15, 0x1C, 0xE5, 0x01, 0x57, 0xC5, 0x98, 0xF1, + 0xE6, 0x06, 0x28, 0x91, 0xAA, 0x20, 0xC5, 0xB7, 0x53, 0x26, 0x51, 0x43, + 0xB2, 0x0B, 0x11, 0x95, 0x58, 0xE1, 0xC0, 0x0F, 0x76, 0xD9, 0xC0, 0x8D, + 0x7C, 0x81, 0xF3, 0x72, 0x70, 0x9E, 0x6F, 0xFE, 0x1A, 0x8E, 0xD9, 0x5F, + 0x35, 0xC6, 0xB2, 0x6F, 0x34, 0x7C, 0xBE, 0x48, 0x4F, 0xE2, 0x5A, 0x39, + 0xD7, 0xD8, 0x9D, 0x78, 0x9E, 0x9F, 0x86, 0x3E, 0x03, 0x5E, 0x19, 0x8B, + 0x44, 0xA2, 0xD5, 0xC7 +}; + +static const unsigned char TA362_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA363_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x33 +}; + +static const unsigned char TA363_RSA_N[] = { + 0xBD, 0x75, 0x93, 0xF0, 0x62, 0x22, 0x6F, 0x24, 0xAE, 0xE0, 0x7A, 0x76, + 0xAC, 0x7D, 0xBD, 0xD9, 0x24, 0xD5, 0xB8, 0xB7, 0xFC, 0xCD, 0xF0, 0x42, + 0xE0, 0xEB, 0x78, 0x88, 0x56, 0x5E, 0x9B, 0x9A, 0x54, 0x1D, 0x4D, 0x0C, + 0x8A, 0xF6, 0xD3, 0xCF, 0x70, 0xF4, 0x52, 0xB5, 0xD8, 0x93, 0x04, 0xE3, + 0x46, 0x86, 0x71, 0x41, 0x4A, 0x2B, 0xF0, 0x2A, 0x2C, 0x55, 0x03, 0xD6, + 0x48, 0xC3, 0xE0, 0x39, 0x38, 0xED, 0xF2, 0x5C, 0x3C, 0x3F, 0x44, 0xBC, + 0x93, 0x3D, 0x61, 0xAB, 0x4E, 0xCD, 0x0D, 0xBE, 0xF0, 0x20, 0x27, 0x58, + 0x0E, 0x44, 0x7F, 0x04, 0x1A, 0x87, 0xA5, 0xD7, 0x96, 0x14, 0x36, 0x90, + 0xD0, 0x49, 0x7B, 0xA1, 0x75, 0xFB, 0x1A, 0x6B, 0x73, 0xB1, 0xF8, 0xCE, + 0xA9, 0x09, 0x2C, 0xF2, 0x53, 0xD5, 0xC3, 0x14, 0x44, 0xB8, 0x86, 0xA5, + 0xF6, 0x8B, 0x2B, 0x39, 0xDA, 0xA3, 0x33, 0x54, 0xD9, 0xFA, 0x72, 0x1A, + 0xF7, 0x22, 0x15, 0x1C, 0x88, 0x91, 0x6B, 0x7F, 0x66, 0xE5, 0xC3, 0x6A, + 0x80, 0xB0, 0x24, 0xF3, 0xDF, 0x86, 0x45, 0x88, 0xFD, 0x19, 0x7F, 0x75, + 0x87, 0x1F, 0x1F, 0xB1, 0x1B, 0x0A, 0x73, 0x24, 0x5B, 0xB9, 0x65, 0xE0, + 0x2C, 0x54, 0xC8, 0x60, 0xD3, 0x66, 0x17, 0x3F, 0xE1, 0xCC, 0x54, 0x33, + 0x73, 0x91, 0x02, 0x3A, 0xA6, 0x7F, 0x7B, 0x76, 0x39, 0xA2, 0x1F, 0x96, + 0xB6, 0x38, 0xAE, 0xB5, 0xC8, 0x93, 0x74, 0x1D, 0x9E, 0xB9, 0xB4, 0xE5, + 0x60, 0x9D, 0x2F, 0x56, 0xD1, 0xE0, 0xEB, 0x5E, 0x5B, 0x4C, 0x12, 0x70, + 0x0C, 0x6C, 0x44, 0x20, 0xAB, 0x11, 0xD8, 0xF4, 0x19, 0xF6, 0xD2, 0x9C, + 0x52, 0x37, 0xE7, 0xFA, 0xB6, 0xC2, 0x31, 0x3B, 0x4A, 0xD4, 0x14, 0x99, + 0xAD, 0xC7, 0x1A, 0xF5, 0x5D, 0x5F, 0xFA, 0x07, 0xB8, 0x7C, 0x0D, 0x1F, + 0xD6, 0x83, 0x1E, 0xB3 +}; + +static const unsigned char TA363_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA364_DN[] = { + 0x30, 0x81, 0xD2, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x54, 0x52, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x0F, 0x47, 0x65, 0x62, 0x7A, 0x65, 0x20, 0x2D, 0x20, 0x4B, + 0x6F, 0x63, 0x61, 0x65, 0x6C, 0x69, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x13, 0x39, 0x54, 0x75, 0x72, 0x6B, 0x69, 0x79, 0x65, + 0x20, 0x42, 0x69, 0x6C, 0x69, 0x6D, 0x73, 0x65, 0x6C, 0x20, 0x76, 0x65, + 0x20, 0x54, 0x65, 0x6B, 0x6E, 0x6F, 0x6C, 0x6F, 0x6A, 0x69, 0x6B, 0x20, + 0x41, 0x72, 0x61, 0x73, 0x74, 0x69, 0x72, 0x6D, 0x61, 0x20, 0x4B, 0x75, + 0x72, 0x75, 0x6D, 0x75, 0x20, 0x2D, 0x20, 0x54, 0x55, 0x42, 0x49, 0x54, + 0x41, 0x4B, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x24, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x6B, 0x61, 0x73, 0x79, 0x6F, 0x6E, 0x20, 0x4D, 0x65, 0x72, 0x6B, + 0x65, 0x7A, 0x69, 0x20, 0x2D, 0x20, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, + 0x4D, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, + 0x54, 0x55, 0x42, 0x49, 0x54, 0x41, 0x4B, 0x20, 0x4B, 0x61, 0x6D, 0x75, + 0x20, 0x53, 0x4D, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x4B, 0x6F, 0x6B, 0x20, + 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6B, 0x61, 0x73, 0x69, 0x20, + 0x2D, 0x20, 0x53, 0x75, 0x72, 0x75, 0x6D, 0x20, 0x31 +}; + +static const unsigned char TA364_RSA_N[] = { + 0xAF, 0x75, 0x30, 0x33, 0xAA, 0xBB, 0x6B, 0xD3, 0x99, 0x2C, 0x12, 0x37, + 0x84, 0xD9, 0x8D, 0x7B, 0x97, 0x80, 0xD3, 0x6E, 0xE7, 0xFF, 0x9B, 0x50, + 0x95, 0x3E, 0x90, 0x95, 0x56, 0x42, 0xD7, 0x19, 0x7C, 0x26, 0x84, 0x8D, + 0x92, 0xFA, 0x01, 0x1D, 0x3A, 0x0F, 0xE2, 0x64, 0x38, 0xB7, 0x8C, 0xBC, + 0xE8, 0x88, 0xF9, 0x8B, 0x24, 0xAB, 0x2E, 0xA3, 0xF5, 0x37, 0xE4, 0x40, + 0x8E, 0x18, 0x25, 0x79, 0x83, 0x75, 0x1F, 0x3B, 0xFF, 0x6C, 0xA8, 0xC5, + 0xC6, 0x56, 0xF8, 0xB4, 0xED, 0x8A, 0x44, 0xA3, 0xAB, 0x6C, 0x4C, 0xFC, + 0x1D, 0xD0, 0xDC, 0xEF, 0x68, 0xBD, 0xCF, 0xE4, 0xAA, 0xCE, 0xF0, 0x55, + 0xF7, 0xA2, 0x34, 0xD4, 0x83, 0x6B, 0x37, 0x7C, 0x1C, 0xC2, 0xFE, 0xB5, + 0x03, 0xEC, 0x57, 0xCE, 0xBC, 0xB4, 0xB5, 0xC5, 0xED, 0x00, 0x0F, 0x53, + 0x37, 0x2A, 0x4D, 0xF4, 0x4F, 0x0C, 0x83, 0xFB, 0x86, 0xCF, 0xCB, 0xFE, + 0x8C, 0x4E, 0xBD, 0x87, 0xF9, 0xA7, 0x8B, 0x21, 0x57, 0x9C, 0x7A, 0xDF, + 0x03, 0x67, 0x89, 0x2C, 0x9D, 0x97, 0x61, 0xA7, 0x10, 0xB8, 0x55, 0x90, + 0x7F, 0x0E, 0x2D, 0x27, 0x38, 0x74, 0xDF, 0xE7, 0xFD, 0xDA, 0x4E, 0x12, + 0xE3, 0x4D, 0x15, 0x22, 0x02, 0xC8, 0xE0, 0xE0, 0xFC, 0x0F, 0xAD, 0x8A, + 0xD7, 0xC9, 0x54, 0x50, 0xCC, 0x3B, 0x0F, 0xCA, 0x16, 0x80, 0x84, 0xD0, + 0x51, 0x56, 0xC3, 0x8E, 0x56, 0x7F, 0x89, 0x22, 0x33, 0x2F, 0xE6, 0x85, + 0x0A, 0xBD, 0xA5, 0xA8, 0x1B, 0x36, 0xDE, 0xD3, 0xDC, 0x2C, 0x6D, 0x3B, + 0xC7, 0x13, 0xBD, 0x59, 0x23, 0x2C, 0xE6, 0xE5, 0xA4, 0xF7, 0xD8, 0x0B, + 0xED, 0xEA, 0x90, 0x40, 0x44, 0xA8, 0x95, 0xBB, 0x93, 0xD5, 0xD0, 0x80, + 0x34, 0xB6, 0x46, 0x78, 0x0E, 0x1F, 0x00, 0x93, 0x46, 0xE1, 0xEE, 0xE9, + 0xF9, 0xEC, 0x4F, 0x17 +}; + +static const unsigned char TA364_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA365_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x54, 0x57, 0x43, 0x41, 0x20, 0x43, 0x59, 0x42, + 0x45, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA365_RSA_N[] = { + 0xC6, 0xF8, 0xCA, 0x1E, 0xD9, 0x09, 0x20, 0x7E, 0x1D, 0x6C, 0x4E, 0xCE, + 0x8F, 0xE3, 0x47, 0x33, 0x44, 0x9C, 0xC7, 0xC9, 0x69, 0xAA, 0x3A, 0x5B, + 0x78, 0xEE, 0x70, 0xD2, 0x92, 0xF8, 0x04, 0xB3, 0x52, 0x52, 0x1D, 0x67, + 0x72, 0x28, 0xA1, 0xDF, 0x8B, 0x5D, 0x95, 0x0A, 0xFE, 0xEA, 0xCD, 0xED, + 0xF7, 0x29, 0xCE, 0xF0, 0x6F, 0x7F, 0xAC, 0xCD, 0x3D, 0xEF, 0xB3, 0x1C, + 0x45, 0x6A, 0xF7, 0x28, 0x90, 0xF1, 0x61, 0x57, 0xC5, 0x0C, 0xC4, 0xA3, + 0x50, 0x5D, 0xDE, 0xD4, 0xB5, 0xCB, 0x19, 0xCA, 0x80, 0xB9, 0x75, 0xCE, + 0x29, 0xCE, 0xD2, 0x85, 0x22, 0xEC, 0x02, 0x63, 0xCC, 0x44, 0x30, 0x20, + 0xDA, 0xEA, 0x91, 0x5B, 0x56, 0xE6, 0x1D, 0x1C, 0xD5, 0x9D, 0x66, 0xC7, + 0x3F, 0xDF, 0x86, 0xCA, 0x4B, 0x53, 0xC4, 0xD9, 0x8D, 0xB2, 0x1D, 0xEA, + 0xF8, 0xDC, 0x27, 0x53, 0xA3, 0x47, 0xE1, 0x61, 0xCC, 0x7D, 0xB5, 0xB0, + 0xF8, 0xEE, 0x73, 0x91, 0xC5, 0xCE, 0x73, 0x6F, 0xCE, 0xEE, 0x10, 0x1F, + 0x1A, 0x06, 0xCF, 0xE9, 0x27, 0x60, 0xC5, 0x4F, 0x19, 0xE4, 0xEB, 0xCE, + 0x22, 0x26, 0x45, 0xD7, 0x60, 0x99, 0xDD, 0xCE, 0x4F, 0x37, 0xE0, 0x7F, + 0xE7, 0x63, 0xAD, 0xB0, 0xB8, 0x59, 0xB8, 0xD0, 0x06, 0x68, 0x35, 0x60, + 0xD3, 0x36, 0xAE, 0x71, 0x43, 0x04, 0xF1, 0x69, 0x65, 0x78, 0x7C, 0xF3, + 0x1F, 0xF3, 0xCA, 0x28, 0x9F, 0x5A, 0x20, 0x95, 0x66, 0xB4, 0xCD, 0xB7, + 0xEE, 0x8F, 0x78, 0xA4, 0x45, 0x18, 0xE9, 0x26, 0x2F, 0x8D, 0x9B, 0x29, + 0x28, 0xB1, 0xA4, 0xB7, 0x3A, 0x6D, 0xB9, 0xD4, 0x1C, 0x38, 0x72, 0x45, + 0x58, 0xB1, 0x5E, 0xEB, 0xF0, 0x28, 0x9B, 0xB7, 0x82, 0xCA, 0xFD, 0xCF, + 0xD6, 0x33, 0x0F, 0x9F, 0xFB, 0x97, 0x9E, 0xB1, 0x1C, 0x9C, 0x9E, 0xEA, + 0x5F, 0x5E, 0xDB, 0xAA, 0xDD, 0x54, 0xE9, 0x30, 0x21, 0x28, 0x6D, 0x8E, + 0x79, 0xF3, 0x75, 0x92, 0x8C, 0x26, 0xFE, 0xDC, 0xC5, 0xF6, 0xC3, 0xB0, + 0xDF, 0x44, 0x59, 0x43, 0xA3, 0xB6, 0x03, 0x28, 0xF6, 0x08, 0x30, 0xAA, + 0x0D, 0x33, 0xE1, 0xEF, 0x9C, 0xA9, 0x07, 0x22, 0xE3, 0x59, 0x5B, 0x40, + 0x8F, 0xDA, 0x88, 0xB7, 0x69, 0x08, 0xA8, 0xB7, 0x23, 0x2E, 0x44, 0x09, + 0x59, 0x37, 0x5B, 0xC7, 0xE3, 0x17, 0xF2, 0x22, 0xEB, 0x6E, 0x39, 0x52, + 0xC5, 0xDE, 0x54, 0xA7, 0x98, 0xC9, 0x4B, 0x20, 0x95, 0xDC, 0x46, 0x89, + 0x5F, 0xB4, 0x12, 0xF9, 0x85, 0x29, 0x8E, 0xEB, 0xC8, 0x27, 0x15, 0x20, + 0xC0, 0x4B, 0xD4, 0xCC, 0x7C, 0x0C, 0x6C, 0x34, 0x0C, 0x26, 0x9B, 0x26, + 0x31, 0xA6, 0x3C, 0xA7, 0xF6, 0xD9, 0xD0, 0x4B, 0xA2, 0x64, 0xFF, 0x3B, + 0x99, 0x41, 0x72, 0xC1, 0xE0, 0x70, 0x97, 0xF1, 0x24, 0xBB, 0x2B, 0xC4, + 0x74, 0x22, 0xB1, 0xAC, 0x6B, 0x22, 0x32, 0x24, 0xD3, 0x78, 0x2A, 0xC0, + 0xC0, 0xA1, 0x2F, 0xF1, 0x52, 0x05, 0xC9, 0x3F, 0xEF, 0x76, 0x66, 0xE2, + 0x45, 0xD8, 0x0D, 0x3D, 0xAD, 0x95, 0xC8, 0xC7, 0x89, 0x26, 0xC8, 0x0F, + 0xAE, 0xA7, 0x03, 0x2E, 0xFB, 0xC1, 0x5F, 0xFA, 0x20, 0xE1, 0x70, 0xAD, + 0xB0, 0x65, 0x20, 0x37, 0x33, 0x60, 0xB0, 0xD5, 0xAF, 0xD7, 0x0C, 0x1C, + 0xC2, 0x90, 0x70, 0xD7, 0x4A, 0x18, 0xBC, 0x7E, 0x01, 0xB0, 0xB0, 0xEB, + 0x15, 0x1E, 0x44, 0x06, 0xCD, 0xA4, 0x4F, 0xE8, 0x0C, 0xD1, 0xC3, 0x20, + 0x10, 0xE1, 0x54, 0x65, 0x9E, 0xB6, 0x51, 0xD0, 0x1A, 0x76, 0x6B, 0x42, + 0x5A, 0x58, 0x76, 0x34, 0xEA, 0xB7, 0x37, 0x19, 0xAE, 0x2E, 0x75, 0xF9, + 0x96, 0xE5, 0xC1, 0x59, 0xF7, 0x94, 0x57, 0x29, 0x25, 0x8D, 0x3A, 0x4C, + 0xAB, 0x4D, 0x9A, 0x41, 0xD0, 0x5F, 0x26, 0x03 +}; + +static const unsigned char TA365_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA366_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x13, 0x54, 0x57, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, + 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA366_RSA_N[] = { + 0xB0, 0x05, 0xDB, 0xC8, 0xEB, 0x8C, 0xC4, 0x6E, 0x8A, 0x21, 0xEF, 0x8E, + 0x4D, 0x9C, 0x71, 0x0A, 0x1F, 0x52, 0x70, 0xED, 0x6D, 0x82, 0x9C, 0x97, + 0xC5, 0xD7, 0x4C, 0x4E, 0x45, 0x49, 0xCB, 0x40, 0x42, 0xB5, 0x12, 0x34, + 0x6C, 0x19, 0xC2, 0x74, 0xA4, 0x31, 0x5F, 0x85, 0x02, 0x97, 0xEC, 0x43, + 0x33, 0x0A, 0x53, 0xD2, 0x9C, 0x8C, 0x8E, 0xB7, 0xB8, 0x79, 0xDB, 0x2B, + 0xD5, 0x6A, 0xF2, 0x8E, 0x66, 0xC4, 0xEE, 0x2B, 0x01, 0x07, 0x92, 0xD4, + 0xB3, 0xD0, 0x02, 0xDF, 0x50, 0xF6, 0x55, 0xAF, 0x66, 0x0E, 0xCB, 0xE0, + 0x47, 0x60, 0x2F, 0x2B, 0x32, 0x39, 0x35, 0x52, 0x3A, 0x28, 0x83, 0xF8, + 0x7B, 0x16, 0xC6, 0x18, 0xB8, 0x62, 0xD6, 0x47, 0x25, 0x91, 0xCE, 0xF0, + 0x19, 0x12, 0x4D, 0xAD, 0x63, 0xF5, 0xD3, 0x3F, 0x75, 0x5F, 0x29, 0xF0, + 0xA1, 0x30, 0x1C, 0x2A, 0xA0, 0x98, 0xA6, 0x15, 0xBD, 0xEE, 0xFD, 0x19, + 0x36, 0xF0, 0xE2, 0x91, 0x43, 0x8F, 0xFA, 0xCA, 0xD6, 0x10, 0x27, 0x49, + 0x4C, 0xEF, 0xDD, 0xC1, 0xF1, 0x85, 0x70, 0x9B, 0xCA, 0xEA, 0xA8, 0x5A, + 0x43, 0xFC, 0x6D, 0x86, 0x6F, 0x73, 0xE9, 0x37, 0x45, 0xA9, 0xF0, 0x36, + 0xC7, 0xCC, 0x88, 0x75, 0x1E, 0xBB, 0x6C, 0x06, 0xFF, 0x9B, 0x6B, 0x3E, + 0x17, 0xEC, 0x61, 0xAA, 0x71, 0x7C, 0xC6, 0x1D, 0xA2, 0xF7, 0x49, 0xE9, + 0x15, 0xB5, 0x3C, 0xD6, 0xA1, 0x61, 0xF5, 0x11, 0xF7, 0x05, 0x6F, 0x1D, + 0xFD, 0x11, 0xBE, 0xD0, 0x30, 0x07, 0xC2, 0x29, 0xB0, 0x09, 0x4E, 0x26, + 0xDC, 0xE3, 0xA2, 0xA8, 0x91, 0x6A, 0x1F, 0xC2, 0x91, 0x45, 0x88, 0x5C, + 0xE5, 0x98, 0xB8, 0x71, 0xA5, 0x15, 0x19, 0xC9, 0x7C, 0x75, 0x11, 0xCC, + 0x70, 0x74, 0x4F, 0x2D, 0x9B, 0x1D, 0x91, 0x44, 0xFD, 0x56, 0x28, 0xA0, + 0xFE, 0xBB, 0x86, 0x6A, 0xC8, 0xFA, 0x5C, 0x0B, 0x58, 0xDC, 0xC6, 0x4B, + 0x76, 0xC8, 0xAB, 0x22, 0xD9, 0x73, 0x0F, 0xA5, 0xF4, 0x5A, 0x02, 0x89, + 0x3F, 0x4F, 0x9E, 0x22, 0x82, 0xEE, 0xA2, 0x74, 0x53, 0x2A, 0x3D, 0x53, + 0x27, 0x69, 0x1D, 0x6C, 0x8E, 0x32, 0x2C, 0x64, 0x00, 0x26, 0x63, 0x61, + 0x36, 0x4E, 0xA3, 0x46, 0xB7, 0x3F, 0x7D, 0xB3, 0x2D, 0xAC, 0x6D, 0x90, + 0xA2, 0x95, 0xA2, 0xCE, 0xCF, 0xDA, 0x82, 0xE7, 0x07, 0x34, 0x19, 0x96, + 0xE9, 0xB8, 0x21, 0xAA, 0x29, 0x7E, 0xA6, 0x38, 0xBE, 0x8E, 0x29, 0x4A, + 0x21, 0x66, 0x79, 0x1F, 0xB3, 0xC3, 0xB5, 0x09, 0x67, 0xDE, 0xD6, 0xD4, + 0x07, 0x46, 0xF3, 0x2A, 0xDA, 0xE6, 0x22, 0x37, 0x60, 0xCB, 0x81, 0xB6, + 0x0F, 0xA0, 0x0F, 0xE9, 0xC8, 0x95, 0x7F, 0xBF, 0x55, 0x91, 0x05, 0x7A, + 0xCF, 0x3D, 0x15, 0xC0, 0x6F, 0xDE, 0x09, 0x94, 0x01, 0x83, 0xD7, 0x34, + 0x1B, 0xCC, 0x40, 0xA5, 0xF0, 0xB8, 0x9B, 0x67, 0xD5, 0x98, 0x91, 0x3B, + 0xA7, 0x84, 0x78, 0x95, 0x26, 0xA4, 0x5A, 0x08, 0xF8, 0x2B, 0x74, 0xB4, + 0x00, 0x04, 0x3C, 0xDF, 0xB8, 0x14, 0x8E, 0xE8, 0xDF, 0xA9, 0x8D, 0x6C, + 0x67, 0x92, 0x33, 0x1D, 0xC0, 0xB7, 0xD2, 0xEC, 0x92, 0xC8, 0xBE, 0x09, + 0xBF, 0x2C, 0x29, 0x05, 0x6F, 0x02, 0x6B, 0x9E, 0xEF, 0xBC, 0xBF, 0x2A, + 0xBC, 0x5B, 0xC0, 0x50, 0x8F, 0x41, 0x70, 0x71, 0x87, 0xB2, 0x4D, 0xB7, + 0x04, 0xA9, 0x84, 0xA3, 0x32, 0xAF, 0xAE, 0xEE, 0x6B, 0x17, 0x8B, 0xB2, + 0xB1, 0xFE, 0x6C, 0xE1, 0x90, 0x8C, 0x88, 0xA8, 0x97, 0x48, 0xCE, 0xC8, + 0x4D, 0xCB, 0xF3, 0x06, 0xCF, 0x5F, 0x6A, 0x0A, 0x42, 0xB1, 0x1E, 0x1E, + 0x77, 0x2F, 0x8E, 0xA0, 0xE6, 0x92, 0x0E, 0x06, 0xFC, 0x05, 0x22, 0xD2, + 0x26, 0xE1, 0x31, 0x51, 0x7D, 0x32, 0xDC, 0x0F +}; + +static const unsigned char TA366_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA367_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x21, 0x54, 0x57, 0x43, 0x41, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA367_RSA_N[] = { + 0xB0, 0x7E, 0x72, 0xB8, 0xA4, 0x03, 0x94, 0xE6, 0xA7, 0xDE, 0x09, 0x38, + 0x91, 0x4A, 0x11, 0x40, 0x87, 0xA7, 0x7C, 0x59, 0x64, 0x14, 0x7B, 0xB5, + 0x11, 0x10, 0xDD, 0xFE, 0xBF, 0xD5, 0xC0, 0xBB, 0x56, 0xE2, 0x85, 0x25, + 0xF4, 0x35, 0x72, 0x0F, 0xF8, 0x53, 0xD0, 0x41, 0xE1, 0x44, 0x01, 0xC2, + 0xB4, 0x1C, 0xC3, 0x31, 0x42, 0x16, 0x47, 0x85, 0x33, 0x22, 0x76, 0xB2, + 0x0A, 0x6F, 0x0F, 0xE5, 0x25, 0x50, 0x4F, 0x85, 0x86, 0xBE, 0xBF, 0x98, + 0x2E, 0x10, 0x67, 0x1E, 0xBE, 0x11, 0x05, 0x86, 0x05, 0x90, 0xC4, 0x59, + 0xD0, 0x7C, 0x78, 0x10, 0xB0, 0x80, 0x5C, 0xB7, 0xE1, 0xC7, 0x2B, 0x75, + 0xCB, 0x7C, 0x9F, 0xAE, 0xB5, 0xD1, 0x9D, 0x23, 0x37, 0x63, 0xA7, 0xDC, + 0x42, 0xA2, 0x2D, 0x92, 0x04, 0x1B, 0x50, 0xC1, 0x7B, 0xB8, 0x3E, 0x1B, + 0xC9, 0x56, 0x04, 0x8B, 0x2F, 0x52, 0x9B, 0xAD, 0xA9, 0x56, 0xE9, 0xC1, + 0xFF, 0xAD, 0xA9, 0x58, 0x87, 0x30, 0xB6, 0x81, 0xF7, 0x97, 0x45, 0xFC, + 0x19, 0x57, 0x3B, 0x2B, 0x6F, 0xE4, 0x47, 0xF4, 0x99, 0x45, 0xFE, 0x1D, + 0xF1, 0xF8, 0x97, 0xA3, 0x88, 0x1D, 0x37, 0x1C, 0x5C, 0x8F, 0xE0, 0x76, + 0x25, 0x9A, 0x50, 0xF8, 0xA0, 0x54, 0xFF, 0x44, 0x90, 0x76, 0x23, 0xD2, + 0x32, 0xC6, 0xC3, 0xAB, 0x06, 0xBF, 0xFC, 0xFB, 0xBF, 0xF3, 0xAD, 0x7D, + 0x92, 0x62, 0x02, 0x5B, 0x29, 0xD3, 0x35, 0xA3, 0x93, 0x9A, 0x43, 0x64, + 0x60, 0x5D, 0xB2, 0xFA, 0x32, 0xFF, 0x3B, 0x04, 0xAF, 0x4D, 0x40, 0x6A, + 0xF9, 0xC7, 0xE3, 0xEF, 0x23, 0xFD, 0x6B, 0xCB, 0xE5, 0x0F, 0x8B, 0x38, + 0x0D, 0xEE, 0x0A, 0xFC, 0xFE, 0x0F, 0x98, 0x9F, 0x30, 0x31, 0xDD, 0x6C, + 0x52, 0x65, 0xF9, 0x8B, 0x81, 0xBE, 0x22, 0xE1, 0x1C, 0x58, 0x03, 0xBA, + 0x91, 0x1B, 0x89, 0x07 +}; + +static const unsigned char TA367_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA368_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA368_EC_Q[] = { + 0x04, 0xCE, 0xBF, 0xFE, 0x57, 0xA8, 0xBF, 0xD5, 0xAA, 0xF7, 0x10, 0x9A, + 0xCD, 0xBC, 0xD1, 0x11, 0xA2, 0xBD, 0x67, 0x42, 0xCC, 0x90, 0xEB, 0x15, + 0x18, 0x90, 0xD9, 0xA2, 0xCD, 0x0C, 0x2A, 0x25, 0xEB, 0x3E, 0x4F, 0xCE, + 0xB5, 0xD2, 0x8F, 0x0F, 0xF3, 0x35, 0xDA, 0x43, 0x8B, 0x02, 0x80, 0xBE, + 0x6F, 0x51, 0x24, 0x1D, 0x0F, 0x6B, 0x2B, 0xCA, 0x9F, 0xC2, 0x6F, 0x50, + 0x32, 0xE5, 0x37, 0x20, 0xB6, 0x20, 0xFF, 0x88, 0x0D, 0x0F, 0x6D, 0x49, + 0xBB, 0xDB, 0x06, 0xA4, 0x87, 0x90, 0x92, 0x94, 0xF4, 0x09, 0xD0, 0xCF, + 0x7F, 0xC8, 0x80, 0x0B, 0xC1, 0x97, 0xB3, 0xBB, 0x35, 0x27, 0xC9, 0xC2, + 0x1B +}; + +static const unsigned char TA369_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x33 +}; + +static const unsigned char TA369_RSA_N[] = { + 0xED, 0x35, 0xA1, 0x81, 0x80, 0xF3, 0xCB, 0x4A, 0x69, 0x5B, 0xC2, 0xFB, + 0x51, 0x83, 0xAE, 0x26, 0xFD, 0xE1, 0x6E, 0xF3, 0x81, 0x12, 0x7D, 0x71, + 0x40, 0xFF, 0x87, 0x75, 0x42, 0x29, 0x21, 0xED, 0x81, 0x52, 0x2C, 0xDF, + 0x12, 0xC1, 0x19, 0x84, 0x89, 0xC1, 0xBD, 0xC5, 0x28, 0xD5, 0xD5, 0x4B, + 0x6C, 0x44, 0xD6, 0x4C, 0xDB, 0x07, 0x96, 0x4A, 0x55, 0x7A, 0xCA, 0x36, + 0x82, 0x04, 0x36, 0xA8, 0xA5, 0xFC, 0x27, 0xF6, 0x49, 0xF1, 0xD5, 0x72, + 0x9E, 0x91, 0xF9, 0x23, 0xD6, 0x70, 0x7B, 0xBB, 0xF5, 0x9B, 0xC1, 0xEC, + 0x93, 0xCF, 0x19, 0xEA, 0x65, 0x7E, 0x88, 0x70, 0xA0, 0x73, 0xFC, 0xF6, + 0xFF, 0xB5, 0x56, 0x62, 0xE1, 0x73, 0x6A, 0x34, 0x98, 0x3E, 0x82, 0xB8, + 0xAC, 0x95, 0x53, 0xF4, 0x01, 0xA0, 0x27, 0x07, 0x72, 0xA3, 0x00, 0x53, + 0xA0, 0xE4, 0xB2, 0xAB, 0x83, 0x38, 0x57, 0x33, 0x25, 0x94, 0x9F, 0xBE, + 0x48, 0x1D, 0x98, 0xE1, 0xA3, 0xBA, 0x9E, 0x5C, 0xCD, 0x04, 0x71, 0x51, + 0x7D, 0x75, 0x78, 0xAB, 0xF3, 0x59, 0xAA, 0xC4, 0xE0, 0x60, 0xBE, 0x8F, + 0x83, 0x52, 0xB8, 0x75, 0x1A, 0x41, 0x35, 0xED, 0xBC, 0xF3, 0x3A, 0x63, + 0xE9, 0xA9, 0x14, 0x45, 0xD7, 0xE6, 0x52, 0xD1, 0x6E, 0xD2, 0xDE, 0xBC, + 0xE3, 0xF5, 0x0B, 0x3B, 0xE6, 0xE0, 0xC4, 0xBD, 0x43, 0x64, 0x13, 0xA6, + 0xCE, 0xF4, 0x98, 0x37, 0x6C, 0x8A, 0x95, 0xA8, 0x97, 0xC8, 0x47, 0x0F, + 0xF0, 0x5E, 0x10, 0x8B, 0xE7, 0x1D, 0x1C, 0xFE, 0xB1, 0x3B, 0xA0, 0x05, + 0x33, 0x68, 0x05, 0x41, 0x82, 0xC1, 0x03, 0x2B, 0x01, 0xC8, 0xE7, 0x8F, + 0x4D, 0xAB, 0xE8, 0xB5, 0xF6, 0xCD, 0x6B, 0x44, 0xB5, 0xE7, 0xDD, 0x8B, + 0xEC, 0xEA, 0x25, 0xB4, 0x00, 0x22, 0x57, 0x4D, 0xB0, 0xB1, 0xB2, 0x31, + 0xC1, 0x16, 0xCE, 0xFF, 0xFD, 0x14, 0x84, 0xB7, 0x47, 0xFA, 0xB2, 0xF1, + 0x70, 0xDE, 0xDB, 0x8B, 0x6C, 0x36, 0x58, 0xA4, 0x7C, 0xB3, 0x11, 0xD1, + 0xC3, 0x77, 0x7F, 0x5F, 0xB6, 0x25, 0xE0, 0x0D, 0xC5, 0xD2, 0xB3, 0xF9, + 0xB8, 0xB8, 0x77, 0xDB, 0x37, 0x71, 0x71, 0x47, 0xE3, 0x60, 0x18, 0x4F, + 0x24, 0xB6, 0x75, 0x37, 0x78, 0xB9, 0xA3, 0x62, 0xAF, 0xBD, 0xC9, 0x72, + 0x8E, 0x2F, 0xCC, 0xBB, 0xAE, 0xDB, 0xE4, 0x15, 0x52, 0x19, 0x07, 0x33, + 0xFB, 0x6A, 0xB7, 0x2D, 0x4B, 0x90, 0x28, 0x82, 0x73, 0xFE, 0x18, 0x8B, + 0x35, 0x8D, 0xDB, 0xA7, 0x04, 0x6A, 0xBE, 0xEA, 0xC1, 0x4D, 0x36, 0x3B, + 0x16, 0x36, 0x91, 0x32, 0xEF, 0xB6, 0x40, 0x89, 0x91, 0x43, 0xE0, 0xF2, + 0xA2, 0xAB, 0x04, 0x2E, 0xE6, 0xF2, 0x4C, 0x0E, 0x16, 0x34, 0x20, 0xAC, + 0x87, 0xC1, 0x2D, 0x7E, 0xC9, 0x66, 0x47, 0x17, 0x14, 0x11, 0xA4, 0xF3, + 0xF7, 0xA1, 0x24, 0x89, 0xAB, 0xD8, 0x1A, 0xC8, 0xA1, 0x5C, 0xB1, 0xA3, + 0xF7, 0x8C, 0x6D, 0xC8, 0x01, 0xC9, 0x4F, 0xC9, 0xEC, 0xC4, 0xFC, 0xAC, + 0x51, 0x33, 0xD1, 0xC8, 0x83, 0xD1, 0xC9, 0x9F, 0x1D, 0xD4, 0x47, 0x34, + 0x29, 0x3E, 0xCB, 0xB0, 0x0E, 0xFA, 0x83, 0x0B, 0x28, 0x58, 0xE5, 0x29, + 0xDC, 0x3F, 0x7C, 0xA8, 0x9F, 0xC9, 0xB6, 0x0A, 0xBB, 0xA6, 0xE8, 0x46, + 0x16, 0x0F, 0x96, 0xE5, 0x7B, 0xE4, 0x6A, 0x7A, 0x48, 0x6D, 0x76, 0x98, + 0x05, 0xA5, 0xDC, 0x6D, 0x1E, 0x42, 0x1E, 0x42, 0xDA, 0x1A, 0xE0, 0x52, + 0xF7, 0xB5, 0x83, 0xC0, 0x1A, 0x7B, 0x78, 0x35, 0x2C, 0x38, 0xF5, 0x1F, + 0xFD, 0x49, 0xA3, 0x2E, 0xD2, 0x59, 0x63, 0xBF, 0x80, 0xB0, 0x8C, 0x93, + 0x73, 0xCB, 0x35, 0xA6, 0x99, 0x95, 0x22, 0x61, 0x65, 0x03, 0x60, 0xFB, + 0x2F, 0x93, 0x4B, 0xFA, 0x9A, 0x9C, 0x80, 0x3B +}; + +static const unsigned char TA369_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA370_DN[] = { + 0x30, 0x37, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0B, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x54, + 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, 0x20, 0x52, + 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x31 +}; + +static const unsigned char TA370_RSA_N[] = { + 0xC2, 0xBE, 0xEB, 0x27, 0xF0, 0x21, 0xA3, 0xF3, 0x69, 0x26, 0x55, 0x7E, + 0x9D, 0xC5, 0x55, 0x16, 0x91, 0x5C, 0xFD, 0xEF, 0x21, 0xBF, 0x53, 0x80, + 0x7A, 0x2D, 0xD2, 0x91, 0x8C, 0x63, 0x31, 0xF0, 0xEC, 0x24, 0xF0, 0xC3, + 0xA5, 0xD2, 0x72, 0x7C, 0x10, 0x6D, 0xF4, 0x37, 0xB7, 0xE5, 0xE6, 0x7C, + 0x79, 0xEA, 0x8C, 0xB5, 0x82, 0x8B, 0xAE, 0x48, 0xB6, 0xAC, 0x00, 0xDC, + 0x65, 0x75, 0xEC, 0x2A, 0x4D, 0x5F, 0xC1, 0x87, 0xF5, 0x20, 0x65, 0x2B, + 0x81, 0xA8, 0x47, 0x3E, 0x89, 0x23, 0x95, 0x30, 0x16, 0x90, 0x7F, 0xE8, + 0x57, 0x07, 0x48, 0xE7, 0x19, 0xAE, 0xBF, 0x45, 0x67, 0xB1, 0x37, 0x1B, + 0x06, 0x2A, 0xFE, 0xDE, 0xF9, 0xAC, 0x7D, 0x83, 0xFB, 0x5E, 0xBA, 0xE4, + 0x8F, 0x97, 0x67, 0xBE, 0x4B, 0x8E, 0x8D, 0x64, 0x07, 0x57, 0x38, 0x55, + 0x69, 0x34, 0x36, 0x3D, 0x13, 0x48, 0xEF, 0x4F, 0xE2, 0xD3, 0x66, 0x1E, + 0xA4, 0xCF, 0x1A, 0xB7, 0x5E, 0x36, 0x33, 0xD4, 0xB4, 0x06, 0xBD, 0x18, + 0x01, 0xFD, 0x77, 0x84, 0x50, 0x00, 0x45, 0xF5, 0x8C, 0x5D, 0xE8, 0x23, + 0xBC, 0x7E, 0xFE, 0x35, 0xE1, 0xED, 0x50, 0x7B, 0xA9, 0x30, 0x8D, 0x19, + 0xD3, 0x09, 0x8E, 0x68, 0x67, 0x5D, 0xBF, 0x3C, 0x97, 0x18, 0x53, 0xBB, + 0x29, 0x62, 0xC5, 0xCA, 0x5E, 0x72, 0xC1, 0xC7, 0x96, 0xD4, 0xDB, 0x2D, + 0xA0, 0xB4, 0x1F, 0x69, 0x03, 0xEC, 0xEA, 0xE2, 0x50, 0xF1, 0x0C, 0x3C, + 0xF0, 0xAC, 0xF3, 0x53, 0x2D, 0xF0, 0x1C, 0xF5, 0xED, 0x6C, 0x39, 0x39, + 0x73, 0x80, 0x16, 0xC8, 0x52, 0xB0, 0x23, 0xCD, 0xE0, 0x3E, 0xDC, 0xDD, + 0x3C, 0x47, 0xA0, 0xBB, 0x35, 0x8A, 0xE2, 0x98, 0x68, 0x8B, 0xBE, 0xE5, + 0xBF, 0x72, 0xEE, 0xD2, 0xFA, 0xA5, 0xED, 0x12, 0xED, 0xFC, 0x98, 0x18, + 0xA9, 0x26, 0x76, 0xDC, 0x28, 0x4B, 0x10, 0x20, 0x1C, 0xD3, 0x7F, 0x16, + 0x77, 0x2D, 0xED, 0x6F, 0x80, 0xF7, 0x49, 0xBB, 0x53, 0x05, 0xBB, 0x5D, + 0x68, 0xC7, 0xD4, 0xC8, 0x75, 0x16, 0x3F, 0x89, 0x5A, 0x8B, 0xF7, 0x17, + 0x47, 0xD4, 0x4C, 0xF1, 0xD2, 0x89, 0x79, 0x3E, 0x4D, 0x3D, 0x98, 0xA8, + 0x61, 0xDE, 0x3A, 0x1E, 0xD2, 0xF8, 0x5E, 0x03, 0xE0, 0xC1, 0xC9, 0x1C, + 0x8C, 0xD3, 0x8D, 0x4D, 0xD3, 0x95, 0x36, 0xB3, 0x37, 0x5F, 0x63, 0x63, + 0x9B, 0x33, 0x14, 0xF0, 0x2D, 0x26, 0x6B, 0x53, 0x7C, 0x89, 0x8C, 0x32, + 0xC2, 0x6E, 0xEC, 0x3D, 0x21, 0x00, 0x39, 0xC9, 0xA1, 0x68, 0xE2, 0x50, + 0x83, 0x2E, 0xB0, 0x3A, 0x2B, 0xF3, 0x36, 0xA0, 0xAC, 0x2F, 0xE4, 0x6F, + 0x61, 0xC2, 0x51, 0x09, 0x39, 0x3E, 0x8B, 0x53, 0xB9, 0xBB, 0x67, 0xDA, + 0xDC, 0x53, 0xB9, 0x76, 0x59, 0x36, 0x9D, 0x43, 0xE5, 0x20, 0xE0, 0x3D, + 0x32, 0x60, 0x85, 0x22, 0x51, 0xB7, 0xC7, 0x33, 0xBB, 0xDD, 0x15, 0x2F, + 0xA4, 0x78, 0xA6, 0x07, 0x7B, 0x81, 0x46, 0x36, 0x04, 0x86, 0xDD, 0x79, + 0x35, 0xC7, 0x95, 0x2C, 0x3B, 0xB0, 0xA3, 0x17, 0x35, 0xE5, 0x73, 0x1F, + 0xB4, 0x5C, 0x59, 0xEF, 0xDA, 0xEA, 0x10, 0x65, 0x7B, 0x7A, 0xD0, 0x7F, + 0x9F, 0xB3, 0xB4, 0x2A, 0x37, 0x3B, 0x70, 0x8B, 0x9B, 0x5B, 0xB9, 0x2B, + 0xB7, 0xEC, 0xB2, 0x51, 0x12, 0x97, 0x53, 0x29, 0x5A, 0xD4, 0xF0, 0x12, + 0x10, 0xDC, 0x4F, 0x02, 0xBB, 0x12, 0x92, 0x2F, 0x62, 0xD4, 0x3F, 0x69, + 0x43, 0x7C, 0x0D, 0xD6, 0xFC, 0x58, 0x75, 0x01, 0x88, 0x9D, 0x58, 0x16, + 0x4B, 0xDE, 0xBA, 0x90, 0xFF, 0x47, 0x01, 0x89, 0x06, 0x6A, 0xF6, 0x5F, + 0xB2, 0x90, 0x6A, 0xB3, 0x02, 0xA6, 0x02, 0x88, 0xBF, 0xB3, 0x47, 0x7E, + 0x2A, 0xD9, 0xD5, 0xFA, 0x68, 0x78, 0x35, 0x4D +}; + +static const unsigned char TA370_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA371_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x49, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x11, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x6C, + 0x61, 0x6E, 0x64, 0x20, 0x4F, 0x79, 0x6A, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x32 +}; + +static const unsigned char TA371_RSA_N[] = { + 0xB2, 0xD0, 0x3F, 0x07, 0xBC, 0xE2, 0x7B, 0xD0, 0x6B, 0x99, 0xF8, 0xE2, + 0x77, 0x69, 0xE7, 0xCE, 0x9D, 0xA4, 0x03, 0xBC, 0x82, 0x6D, 0xA1, 0xFE, + 0x81, 0x65, 0x1F, 0x4C, 0x27, 0xAC, 0x8E, 0x00, 0xBA, 0x16, 0x7B, 0xEB, + 0x30, 0x6A, 0x00, 0xC0, 0xB3, 0x74, 0x68, 0x7E, 0xB2, 0xAF, 0xC7, 0xD5, + 0x62, 0xB3, 0x7A, 0x3F, 0x50, 0xCA, 0x8C, 0x36, 0x44, 0x24, 0x63, 0xD2, + 0x36, 0xE9, 0x0C, 0x85, 0xF6, 0x43, 0x76, 0xD5, 0x4C, 0xA1, 0x60, 0x72, + 0x67, 0xE2, 0x28, 0x33, 0xA5, 0xCB, 0x31, 0xB8, 0x3A, 0x22, 0x23, 0x34, + 0xB8, 0x7D, 0xBD, 0x56, 0x22, 0x40, 0x9D, 0xEA, 0xF4, 0x7B, 0x03, 0xAD, + 0x68, 0xFC, 0xB2, 0x81, 0x4F, 0x98, 0xD0, 0x74, 0xEA, 0x8D, 0xE5, 0x7D, + 0xCD, 0x63, 0xC3, 0xA3, 0xF6, 0xDE, 0x92, 0xC2, 0x58, 0x19, 0xE0, 0x96, + 0xBB, 0xC5, 0xC4, 0xA9, 0x3D, 0xA5, 0x74, 0x96, 0xFE, 0xAF, 0xF9, 0x89, + 0xAA, 0xBD, 0x95, 0x17, 0x54, 0xD8, 0x78, 0x44, 0xF1, 0x0C, 0x77, 0x15, + 0x92, 0xE0, 0x98, 0x42, 0xA7, 0xA4, 0xD6, 0xAA, 0x20, 0x92, 0xCD, 0xC1, + 0xA0, 0xB3, 0x96, 0xB2, 0x3A, 0x84, 0x42, 0x8D, 0x7D, 0xD5, 0x95, 0xE4, + 0xD6, 0xDB, 0xE9, 0x62, 0xC4, 0x58, 0xB3, 0x79, 0xC5, 0x8C, 0xD3, 0x35, + 0x33, 0x83, 0x9F, 0x75, 0xA1, 0x52, 0x27, 0x61, 0x38, 0xF1, 0x59, 0x3D, + 0x8E, 0x50, 0xE0, 0xBD, 0x79, 0x3C, 0xE7, 0x6C, 0x96, 0xFE, 0x5E, 0xD9, + 0x02, 0x65, 0xB4, 0x8E, 0x5C, 0xD0, 0x11, 0x34, 0xDF, 0x5D, 0xBF, 0x52, + 0xA7, 0x81, 0x00, 0xC3, 0x7F, 0x99, 0x45, 0x99, 0x15, 0xD5, 0x17, 0xC8, + 0x0A, 0x53, 0xEC, 0x63, 0xF3, 0x99, 0x7D, 0xCC, 0x69, 0x12, 0x86, 0xC2, + 0x17, 0xF0, 0x01, 0x9E, 0xBF, 0x84, 0xBC, 0xD1, 0x52, 0xCB, 0x1B, 0x92, + 0x66, 0xCE, 0xA4, 0x53, 0xE5, 0xA1, 0xBF, 0xC4, 0xDB, 0x09, 0xD6, 0xE6, + 0x89, 0x56, 0x2B, 0xC8, 0xE3, 0x7C, 0xDE, 0xE3, 0xFF, 0x89, 0xE5, 0x35, + 0x6E, 0x28, 0xE8, 0x6C, 0x0B, 0x23, 0x51, 0xA9, 0x25, 0x05, 0xEB, 0x48, + 0xF8, 0xDD, 0xB1, 0xCA, 0xFA, 0x6C, 0x08, 0x51, 0xEF, 0xB7, 0x18, 0x6C, + 0x44, 0xCA, 0x26, 0xE1, 0x73, 0xC6, 0x89, 0x06, 0x81, 0xE5, 0x8A, 0xAC, + 0xB0, 0xE2, 0x29, 0xC6, 0xB9, 0x24, 0xB3, 0x6B, 0x44, 0x11, 0xF4, 0xA5, + 0x43, 0xC2, 0x4C, 0x43, 0xE5, 0x70, 0x36, 0x8C, 0xB6, 0x33, 0x57, 0x7A, + 0x95, 0x2E, 0x82, 0xA0, 0xF4, 0x5C, 0x10, 0xB3, 0x61, 0x83, 0xF6, 0x02, + 0x05, 0x86, 0x2E, 0x7C, 0x2D, 0x6C, 0xDC, 0x03, 0x46, 0x6E, 0x35, 0x93, + 0xD5, 0x7A, 0x95, 0x2F, 0xDE, 0x20, 0xD8, 0x5B, 0x7E, 0x94, 0x90, 0x04, + 0x6A, 0xBA, 0x59, 0x3D, 0x04, 0x05, 0x75, 0x9D, 0x37, 0xA2, 0x0E, 0x2E, + 0x3D, 0xEB, 0xC1, 0xA4, 0x52, 0x83, 0xFE, 0xD0, 0x6B, 0xD4, 0x66, 0x8E, + 0xDC, 0xC6, 0xE9, 0x12, 0x4E, 0x1D, 0x2A, 0x57, 0xAA, 0x10, 0xBC, 0x7C, + 0x5E, 0x82, 0x7D, 0xA6, 0xA6, 0xC9, 0xF2, 0x2D, 0xB9, 0xF5, 0x17, 0x27, + 0xAD, 0xD1, 0x0E, 0x89, 0x54, 0x2B, 0x95, 0xFA, 0xC0, 0xAD, 0x1D, 0x98, + 0x14, 0x78, 0x33, 0x42, 0x86, 0x0A, 0xA9, 0x73, 0xB5, 0xFB, 0x74, 0x0D, + 0xB7, 0x1B, 0x30, 0x19, 0xC4, 0x5A, 0x0E, 0x1C, 0x27, 0xB7, 0xDA, 0x18, + 0xD0, 0xFF, 0x8A, 0xC8, 0x05, 0xBA, 0xF1, 0xAA, 0x1C, 0xA2, 0x37, 0xB7, + 0xE6, 0x48, 0xA4, 0x46, 0x2C, 0x94, 0xEA, 0xA8, 0x76, 0x62, 0x47, 0x8B, + 0x10, 0x53, 0x07, 0x48, 0x57, 0x6C, 0xE2, 0x92, 0x4D, 0xB6, 0xAE, 0x05, + 0xCB, 0xDC, 0xC1, 0x4A, 0x5E, 0x8F, 0xAC, 0x3D, 0x19, 0x4E, 0xC2, 0xED, + 0x60, 0x75, 0x2B, 0xDB, 0xC1, 0xCA, 0x42, 0xD5 +}; + +static const unsigned char TA371_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA372_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA372_RSA_N[] = { + 0xC0, 0x31, 0x82, 0x61, 0x92, 0xE4, 0x94, 0x1B, 0x0A, 0x2A, 0x65, 0xD0, + 0xBE, 0x06, 0xA9, 0x87, 0x3B, 0x51, 0x12, 0xEA, 0x70, 0x41, 0xAE, 0xE2, + 0xFB, 0x74, 0xEA, 0x0A, 0x8D, 0xB9, 0xB3, 0x4C, 0xDC, 0x8F, 0xB7, 0x13, + 0x52, 0x4F, 0x54, 0x18, 0xE1, 0x2C, 0x73, 0x95, 0x91, 0xC5, 0x66, 0x3B, + 0x6A, 0xCF, 0xAC, 0x63, 0x6D, 0x87, 0x53, 0xF0, 0xF7, 0xF1, 0x39, 0xB7, + 0xA0, 0x43, 0x63, 0xB0, 0xC4, 0x03, 0x5D, 0x57, 0xA9, 0xE7, 0x44, 0xCE, + 0xC4, 0xA1, 0x83, 0x65, 0xF6, 0x50, 0x3E, 0xB1, 0x7E, 0x16, 0xB8, 0x3A, + 0x8A, 0x02, 0xD0, 0x96, 0x1F, 0x00, 0xCD, 0x05, 0x21, 0xEF, 0x06, 0x6D, + 0xDD, 0x21, 0x9C, 0x19, 0x43, 0x45, 0xA1, 0xC5, 0xE8, 0x80, 0xCA, 0xC2, + 0xAD, 0x40, 0x62, 0x17, 0x06, 0xC6, 0xAA, 0xBC, 0xF3, 0xD6, 0xE6, 0xFC, + 0x50, 0x7E, 0x66, 0x42, 0x1F, 0x3C, 0x8B, 0xA6, 0x79, 0x79, 0x86, 0x40, + 0x35, 0x9F, 0x20, 0xEF, 0x3F, 0xEB, 0x8B, 0x47, 0x1F, 0x8F, 0x8E, 0xC5, + 0xD4, 0x8E, 0xB6, 0x2C, 0xC9, 0x44, 0x04, 0xE3, 0xD4, 0x43, 0x75, 0x3F, + 0xD5, 0x3F, 0xAF, 0x1C, 0xCC, 0x7E, 0x46, 0x5F, 0xAC, 0xDF, 0x64, 0x10, + 0x8A, 0xEF, 0x46, 0xF0, 0x90, 0xF0, 0x0F, 0x2D, 0xF4, 0x88, 0x0B, 0xB1, + 0x29, 0xAA, 0xAF, 0x85, 0xAA, 0x49, 0x58, 0xA8, 0xBF, 0x63, 0xA0, 0x38, + 0x91, 0xE6, 0xB3, 0xE6, 0x77, 0x68, 0xC4, 0xF9, 0x2A, 0x19, 0x84, 0xBB, + 0x0E, 0xE1, 0xF5, 0xAF, 0x89, 0xEC, 0xA5, 0x2F, 0x50, 0x20, 0x74, 0x1E, + 0x12, 0x41, 0x73, 0x1E, 0x24, 0xD9, 0xCA, 0xCE, 0x2C, 0xA1, 0x59, 0x35, + 0xC0, 0xC8, 0x1D, 0x46, 0x27, 0x61, 0x5A, 0x8F, 0xF9, 0x4D, 0xD3, 0x72, + 0x79, 0x66, 0x1E, 0x9F, 0x15, 0x90, 0x21, 0x2D, 0xFD, 0xED, 0x8B, 0x56, + 0x70, 0x03, 0x4A, 0x49, 0x3E, 0x7F, 0x69, 0x31, 0x12, 0x69, 0xC7, 0x1E, + 0x5C, 0xCA, 0x7A, 0x13, 0x8B, 0xE8, 0xE6, 0xF5, 0x60, 0x0F, 0xCC, 0x93, + 0x2C, 0x84, 0x7F, 0xF1, 0xFC, 0x6A, 0xFC, 0x9B, 0x47, 0x9D, 0xDB, 0xAD, + 0x88, 0x3D, 0xF3, 0x76, 0x75, 0x33, 0xD7, 0x4B, 0xA4, 0xC8, 0x8B, 0xF9, + 0xF5, 0x43, 0x58, 0x4F, 0xCB, 0xC8, 0x03, 0x54, 0x8F, 0xA5, 0x85, 0x78, + 0x04, 0x1A, 0xF3, 0x73, 0xF2, 0xD7, 0x87, 0x1D, 0x41, 0x9F, 0xE7, 0xD8, + 0x17, 0xCE, 0x1A, 0x9C, 0x0F, 0x4A, 0xFC, 0xDC, 0x44, 0x68, 0x54, 0x68, + 0xE2, 0x41, 0x3C, 0xFE, 0x2C, 0x84, 0x86, 0x37, 0x3C, 0xCD, 0x3F, 0x2F, + 0xA2, 0xDB, 0xE7, 0xF7, 0x54, 0x03, 0x5F, 0x59, 0xD3, 0xF7, 0x91, 0x78, + 0xC7, 0x8B, 0x77, 0x6A, 0x16, 0xE5, 0x49, 0x85, 0x90, 0x45, 0x72, 0x70, + 0x2F, 0x91, 0x5D, 0xF8, 0x3E, 0x65, 0x40, 0x0B, 0x19, 0x99, 0xC9, 0x26, + 0x20, 0x5A, 0x68, 0xC1, 0x35, 0xBF, 0x4F, 0xA7, 0x51, 0xF1, 0xD8, 0x11, + 0x2B, 0x5B, 0xE0, 0x9A, 0x9E, 0x28, 0x3B, 0x0A, 0x3A, 0x0A, 0x1F, 0xC1, + 0x81, 0xE5, 0x2E, 0xF0, 0xA6, 0xB9, 0x69, 0xA5, 0x88, 0x94, 0xE6, 0x6B, + 0x13, 0x7F, 0xD1, 0x64, 0x3F, 0x3D, 0x9C, 0x70, 0x46, 0xE5, 0xA2, 0x85, + 0x7B, 0x58, 0x84, 0x27, 0xDC, 0xC4, 0x80, 0x3E, 0x67, 0x9A, 0x9A, 0xC7, + 0x9A, 0x31, 0x0E, 0x30, 0xEC, 0xE6, 0x17, 0x40, 0x95, 0xD9, 0x45, 0xED, + 0x01, 0x96, 0xAA, 0xBF, 0x0C, 0xF3, 0x4B, 0xD1, 0x63, 0xF7, 0x13, 0x58, + 0xC0, 0xB8, 0xF3, 0xFA, 0x67, 0xDD, 0x9B, 0x7D, 0x6D, 0x4A, 0xFF, 0x32, + 0x4C, 0xB5, 0x25, 0x3B, 0xFF, 0x1C, 0x67, 0x0F, 0x85, 0x22, 0x59, 0x05, + 0x91, 0x91, 0x41, 0x77, 0x81, 0xD0, 0x85, 0x4C, 0x87, 0x10, 0x71, 0xFF, + 0x9E, 0x43, 0x1B, 0xAE, 0x95, 0x75, 0x2D, 0x81 +}; + +static const unsigned char TA372_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA373_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA373_EC_Q[] = { + 0x04, 0xF1, 0xB3, 0xCD, 0x38, 0xE4, 0x25, 0x43, 0xE5, 0xDE, 0x19, 0x09, + 0xBB, 0x81, 0x79, 0xA2, 0x15, 0x5F, 0x15, 0x63, 0x01, 0xDE, 0xC2, 0xAB, + 0xDD, 0xB3, 0xA6, 0x1B, 0x67, 0x4B, 0x80, 0x83, 0xAF, 0x99, 0xCB, 0xAC, + 0x17, 0xDB, 0x2B, 0x96, 0xCA, 0x7C, 0x52, 0x55, 0xE2, 0x1A, 0xE1, 0x3D, + 0x56, 0xF0, 0x2F, 0x16, 0x08, 0xFA, 0x15, 0xBC, 0x9B, 0xBB, 0x47, 0xE6, + 0x3F, 0xEE, 0xA8, 0xE1, 0x4C, 0x8C, 0xF5, 0xD3, 0x36, 0xF9, 0x38, 0x5D, + 0xAB, 0x70, 0x9A, 0x47, 0x0D, 0xE2, 0x81, 0x41, 0x06, 0xEB, 0x49, 0xF9, + 0xB0, 0x29, 0xDD, 0x33, 0xEC, 0x50, 0xA5, 0x7F, 0x79, 0x29, 0xB8, 0x20, + 0x98 +}; + +static const unsigned char TA374_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x28, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA374_RSA_N[] = { + 0xB9, 0x5D, 0x51, 0x28, 0x4B, 0x3C, 0x37, 0x92, 0xD1, 0x82, 0xCE, 0xBD, + 0x1D, 0xBD, 0xCD, 0xDD, 0xB8, 0xAB, 0xCF, 0x0A, 0x3E, 0xE1, 0x5D, 0xE5, + 0xDC, 0xAA, 0x09, 0xB9, 0x57, 0x02, 0x3E, 0xE6, 0x63, 0x61, 0xDF, 0xF2, + 0x0F, 0x82, 0x63, 0xAE, 0xA3, 0xF7, 0xAC, 0x73, 0xD1, 0x7C, 0xE7, 0xB3, + 0x0B, 0xAF, 0x08, 0x00, 0x09, 0x59, 0x7F, 0xCD, 0x29, 0x2A, 0x88, 0x93, + 0x87, 0x17, 0x18, 0x80, 0xED, 0x88, 0xB2, 0xB4, 0xB6, 0x10, 0x1F, 0x2D, + 0xD6, 0x5F, 0x55, 0xA2, 0x13, 0x5D, 0xD1, 0xC6, 0xEB, 0x06, 0x56, 0x89, + 0x88, 0xFE, 0xAC, 0x32, 0x9D, 0xFD, 0x5C, 0xC3, 0x05, 0xC7, 0x6E, 0xEE, + 0x86, 0x89, 0xBA, 0x88, 0x03, 0x9D, 0x72, 0x21, 0x86, 0x90, 0xAE, 0x8F, + 0x03, 0xA5, 0xDC, 0x9F, 0x88, 0x28, 0xCB, 0xA3, 0x92, 0x49, 0x0F, 0xEC, + 0xD0, 0x0F, 0xE2, 0x6D, 0x44, 0x4F, 0x80, 0x6A, 0xB2, 0xD4, 0xE7, 0xA0, + 0x0A, 0x53, 0x01, 0xBA, 0x8E, 0x97, 0x91, 0x76, 0x6E, 0xBC, 0xFC, 0xD5, + 0x6B, 0x36, 0xE6, 0x40, 0x88, 0xD6, 0x7B, 0x2F, 0x5F, 0x05, 0xE8, 0x2C, + 0x6D, 0x11, 0xF3, 0xE7, 0xB2, 0xBE, 0x92, 0x44, 0x4C, 0xD2, 0x97, 0xA4, + 0xFE, 0xD2, 0x72, 0x81, 0x43, 0x07, 0x9C, 0xE9, 0x11, 0x3E, 0xF5, 0x8B, + 0x1A, 0x59, 0x7D, 0x1F, 0x68, 0x58, 0xDD, 0x04, 0x00, 0x2C, 0x96, 0xF3, + 0x43, 0xB3, 0x7E, 0x98, 0x19, 0x74, 0xD9, 0x9C, 0x73, 0xD9, 0x18, 0xBE, + 0x41, 0xC7, 0x34, 0x79, 0xD9, 0xF4, 0x62, 0xC2, 0x43, 0xB9, 0xB3, 0x27, + 0xB0, 0x22, 0xCB, 0xF9, 0x3D, 0x52, 0xC7, 0x30, 0x47, 0xB3, 0xC9, 0x3E, + 0xB8, 0x6A, 0xE2, 0xE7, 0xE8, 0x81, 0x70, 0x5E, 0x42, 0x8B, 0x4F, 0x26, + 0xA5, 0xFE, 0x3A, 0xC2, 0x20, 0x6E, 0xBB, 0xF8, 0x16, 0x8E, 0xCD, 0x0C, + 0xA9, 0xB4, 0x1B, 0x6C, 0x76, 0x10, 0xE1, 0x58, 0x79, 0x46, 0x3E, 0x54, + 0xCE, 0x80, 0xA8, 0x57, 0x09, 0x37, 0x29, 0x1B, 0x99, 0x13, 0x8F, 0x0C, + 0xC8, 0xD6, 0x2C, 0x1C, 0xFB, 0x05, 0xE8, 0x08, 0x95, 0x3D, 0x65, 0x46, + 0xDC, 0xEE, 0xCD, 0x69, 0xE2, 0x4D, 0x8F, 0x87, 0x28, 0x4E, 0x34, 0x0B, + 0x3E, 0xCF, 0x14, 0xD9, 0xBB, 0xDD, 0xB6, 0x50, 0x9A, 0xAD, 0x77, 0xD4, + 0x19, 0xD6, 0xDA, 0x1A, 0x88, 0xC8, 0x4E, 0x1B, 0x27, 0x75, 0xD8, 0xB2, + 0x08, 0xF1, 0xAE, 0x83, 0x30, 0xB9, 0x11, 0x0E, 0xCD, 0x87, 0xF0, 0x84, + 0x8D, 0x15, 0x72, 0x7C, 0xA1, 0xEF, 0xCC, 0xF2, 0x88, 0x61, 0xBA, 0xF4, + 0x69, 0xBB, 0x0C, 0x8C, 0x0B, 0x75, 0x57, 0x04, 0xB8, 0x4E, 0x2A, 0x14, + 0x2E, 0x3D, 0x0F, 0x1C, 0x1E, 0x32, 0xA6, 0x62, 0x36, 0xEE, 0x66, 0xE2, + 0x22, 0xB8, 0x05, 0x40, 0x63, 0x10, 0x22, 0xF3, 0x33, 0x1D, 0x74, 0x72, + 0x8A, 0x2C, 0xF5, 0x39, 0x29, 0xA0, 0xD3, 0xE7, 0x1B, 0x80, 0x84, 0x2D, + 0xC5, 0x3D, 0xE3, 0x4D, 0xB1, 0xFD, 0x1A, 0x6F, 0xBA, 0x65, 0x07, 0x3B, + 0x58, 0xEC, 0x42, 0x45, 0x26, 0xFB, 0xD8, 0xDA, 0x25, 0x72, 0xC4, 0xF6, + 0x00, 0xB1, 0x22, 0x79, 0xBD, 0xE3, 0x7C, 0x59, 0x62, 0x4A, 0x9C, 0x05, + 0x6F, 0x3D, 0xCE, 0xE6, 0xD6, 0x47, 0x63, 0x99, 0xC6, 0x24, 0x6F, 0x72, + 0x12, 0xC8, 0xAC, 0x7F, 0x90, 0xB4, 0x0B, 0x91, 0x70, 0xE8, 0xB7, 0xE6, + 0x16, 0x10, 0x71, 0x17, 0xCE, 0xDE, 0x06, 0x4F, 0x48, 0x41, 0x7D, 0x35, + 0x4A, 0xA3, 0x89, 0xF2, 0xC9, 0x4B, 0x7B, 0x41, 0x11, 0x6D, 0x67, 0xB7, + 0x08, 0x98, 0x4C, 0xE5, 0x11, 0x19, 0xAE, 0x42, 0x80, 0xDC, 0xFB, 0x90, + 0x05, 0xD4, 0xF8, 0x50, 0xCA, 0xBE, 0xE4, 0xAD, 0xC7, 0xC2, 0x94, 0xD7, + 0x16, 0x9D, 0xE6, 0x17, 0x8F, 0xAF, 0x36, 0xFB +}; + +static const unsigned char TA374_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA375_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x32, 0x35, 0x36, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA375_EC_Q[] = { + 0x04, 0x7E, 0xFB, 0x6C, 0xE6, 0x23, 0xE3, 0x73, 0x32, 0x08, 0xCA, 0x60, + 0xE6, 0x53, 0x9C, 0xBA, 0x74, 0x8D, 0x18, 0xB0, 0x78, 0x90, 0x52, 0x80, + 0xDD, 0x38, 0xC0, 0x4A, 0x1D, 0xD1, 0xA8, 0xCC, 0x93, 0xA4, 0x97, 0x06, + 0x38, 0xCA, 0x0D, 0x15, 0x62, 0xC6, 0x8E, 0x01, 0x2A, 0x65, 0x9D, 0xAA, + 0xDF, 0x34, 0x91, 0x2E, 0x81, 0xC1, 0xE4, 0x33, 0x92, 0x31, 0xC4, 0xFD, + 0x09, 0x3A, 0xA6, 0x3F, 0xAD +}; + +static const unsigned char TA376_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA376_EC_Q[] = { + 0x04, 0x6B, 0xDA, 0x0D, 0x75, 0x35, 0x08, 0x31, 0x47, 0x05, 0xAE, 0x45, + 0x99, 0x55, 0xF1, 0x11, 0x13, 0x2E, 0x4A, 0xF8, 0x10, 0x31, 0x23, 0xA3, + 0x7E, 0x83, 0xD3, 0x7F, 0x28, 0x08, 0x3A, 0x26, 0x1A, 0x3A, 0xCF, 0x97, + 0x82, 0x1F, 0x80, 0xB7, 0x27, 0x09, 0x8F, 0xD1, 0x8E, 0x30, 0xC4, 0x0A, + 0x9B, 0x0E, 0xAC, 0x58, 0x04, 0xAB, 0xF7, 0x36, 0x7D, 0x94, 0x23, 0xA4, + 0x9B, 0x0A, 0x8A, 0x8B, 0xAB, 0xEB, 0xFD, 0x39, 0x25, 0x66, 0xF1, 0x5E, + 0xFE, 0x8C, 0xAE, 0x8D, 0x41, 0x79, 0x9D, 0x09, 0x60, 0xCE, 0x28, 0xA9, + 0xD3, 0x8A, 0x6D, 0xF3, 0xD6, 0x45, 0xD4, 0xF2, 0x98, 0x84, 0x38, 0x65, + 0xA0 +}; + +static const unsigned char TA377_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x4E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4E, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x65, 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x71, 0x75, 0x65, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, + 0x75, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA377_RSA_N[] = { + 0xC3, 0xCD, 0xD3, 0xFC, 0xBD, 0x04, 0x53, 0xDD, 0x0C, 0x20, 0x3A, 0xD5, + 0x88, 0x2E, 0x05, 0x4B, 0x41, 0xF5, 0x83, 0x82, 0x7E, 0xF7, 0x59, 0x9F, + 0x9E, 0x9E, 0x63, 0xE8, 0x73, 0xDA, 0xF6, 0x06, 0xA9, 0x4F, 0x1F, 0xB4, + 0xF9, 0x0B, 0x1F, 0x39, 0x8C, 0x9A, 0x20, 0xD0, 0x7E, 0x06, 0xD4, 0xEC, + 0x34, 0xD9, 0x86, 0xBC, 0x75, 0x5B, 0x87, 0x88, 0xF0, 0xD2, 0xD9, 0xD4, + 0xA3, 0x0A, 0xB2, 0x6C, 0x1B, 0xEB, 0x49, 0x2C, 0x3E, 0xAC, 0x5D, 0xD8, + 0x94, 0x03, 0xA0, 0xEC, 0x34, 0xE5, 0x30, 0xC4, 0x35, 0x7D, 0xFB, 0x26, + 0x4D, 0x1B, 0x6E, 0x30, 0x54, 0xD8, 0xF5, 0x80, 0x45, 0x9C, 0x39, 0xAD, + 0x9C, 0xC9, 0x25, 0x04, 0x4D, 0x9A, 0x90, 0x3E, 0x4E, 0x40, 0x6E, 0x8A, + 0x6B, 0xCD, 0x29, 0x67, 0xC6, 0xCC, 0x2D, 0xE0, 0x74, 0xE8, 0x05, 0x57, + 0x0A, 0x48, 0x50, 0xFA, 0x7A, 0x43, 0xDA, 0x7E, 0xEC, 0x5B, 0x9A, 0x0E, + 0x62, 0x76, 0xFE, 0xEA, 0x9D, 0x1D, 0x85, 0x72, 0xEC, 0x11, 0xBB, 0x35, + 0xE8, 0x1F, 0x27, 0xBF, 0xC1, 0xA1, 0xC7, 0xBB, 0x48, 0x16, 0xDD, 0x56, + 0xD7, 0xCC, 0x4E, 0xA0, 0xE1, 0xB9, 0xAC, 0xDB, 0xD5, 0x83, 0x19, 0x1A, + 0x85, 0xD1, 0x94, 0x97, 0xD7, 0xCA, 0xA3, 0x65, 0x0B, 0xF3, 0x38, 0xF9, + 0x02, 0xAE, 0xDD, 0xF6, 0x67, 0xCF, 0xC9, 0x3F, 0xF5, 0x8A, 0x2C, 0x47, + 0x1A, 0x99, 0x6F, 0x05, 0x0D, 0xFD, 0xD0, 0x1D, 0x82, 0x31, 0xFC, 0x29, + 0xCC, 0x00, 0x58, 0x97, 0x91, 0x4C, 0x80, 0x00, 0x1C, 0x33, 0x85, 0x96, + 0x2F, 0xCB, 0x41, 0xC2, 0x8B, 0x10, 0x84, 0xC3, 0x09, 0x24, 0x89, 0x1F, + 0xB5, 0x0F, 0xD9, 0xD9, 0x77, 0x47, 0x18, 0x92, 0x94, 0x60, 0x5C, 0xC7, + 0x99, 0x03, 0x3C, 0xFE, 0xF7, 0x95, 0xA7, 0x7D, 0x50, 0xA1, 0x80, 0xC2, + 0xA9, 0x83, 0xAD, 0x58, 0x96, 0x55, 0x21, 0xDB, 0x86, 0x59, 0xD4, 0xAF, + 0xC6, 0xBC, 0xDD, 0x81, 0x6E, 0x07, 0xDB, 0x60, 0x62, 0xFE, 0xEC, 0x10, + 0x6E, 0xDA, 0x68, 0x01, 0xF4, 0x83, 0x1B, 0xA9, 0x3E, 0xA2, 0x5B, 0x23, + 0xD7, 0x64, 0xC6, 0xDF, 0xDC, 0xA2, 0x7D, 0xD8, 0x4B, 0xBA, 0x82, 0xD2, + 0x51, 0xF8, 0x66, 0xBF, 0x06, 0x46, 0xE4, 0x79, 0x2A, 0x26, 0x36, 0x79, + 0x8F, 0x1F, 0x4E, 0x99, 0x1D, 0xB2, 0x8F, 0x0C, 0x0E, 0x1C, 0xFF, 0xC9, + 0x5D, 0xC0, 0xFD, 0x90, 0x10, 0xA6, 0xB1, 0x37, 0xF3, 0xCD, 0x3A, 0x24, + 0x6E, 0xB4, 0x85, 0x90, 0xBF, 0x80, 0xB9, 0x0C, 0x8C, 0xD5, 0x9B, 0xD6, + 0xC8, 0xF1, 0x56, 0x3F, 0x1A, 0x80, 0x89, 0x7A, 0xA9, 0xE2, 0x1B, 0x32, + 0x51, 0x2C, 0x3E, 0xF2, 0xDF, 0x7B, 0xF6, 0x5D, 0x7A, 0x29, 0x19, 0x8E, + 0xE5, 0xC8, 0xBD, 0x36, 0x71, 0x8B, 0x5D, 0x4C, 0xC2, 0x1D, 0x3F, 0xAD, + 0x58, 0xA2, 0xCF, 0x3D, 0x70, 0x4D, 0xA6, 0x50, 0x98, 0x25, 0xDC, 0x23, + 0xF9, 0xB8, 0x58, 0x41, 0x08, 0x71, 0xBF, 0x4F, 0xB8, 0x84, 0xA0, 0x8F, + 0x00, 0x54, 0x15, 0xFC, 0x91, 0x6D, 0x58, 0xA7, 0x96, 0x3B, 0xEB, 0x4B, + 0x96, 0x27, 0xCD, 0x6B, 0xA2, 0xA1, 0x86, 0xAC, 0x0D, 0x7C, 0x54, 0xE6, + 0x66, 0x4C, 0x66, 0x5F, 0x90, 0xBE, 0x21, 0x9A, 0x02, 0x46, 0x2D, 0xE4, + 0x83, 0xC2, 0x80, 0xB9, 0xCF, 0x4B, 0x3E, 0xE8, 0x7F, 0x3C, 0x01, 0xEC, + 0x8F, 0x5E, 0xCD, 0x7F, 0xD2, 0x28, 0x42, 0x01, 0x95, 0x8A, 0xE2, 0x97, + 0x3D, 0x10, 0x21, 0x7D, 0xF6, 0x9D, 0x1C, 0xC5, 0x34, 0xA1, 0xEC, 0x2C, + 0x0E, 0x0A, 0x52, 0x2C, 0x12, 0x55, 0x70, 0x24, 0x3D, 0xCB, 0xC2, 0x14, + 0x35, 0x43, 0x5D, 0x27, 0x4E, 0xBE, 0xC0, 0xBD, 0xAA, 0x7C, 0x96, 0xE7, + 0xFC, 0x9E, 0x61, 0xAD, 0x44, 0xD3, 0x00, 0x97 +}; + +static const unsigned char TA377_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA378_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x55, 0x43, 0x41, + 0x20, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, + 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74 +}; + +static const unsigned char TA378_RSA_N[] = { + 0xA9, 0x09, 0x07, 0x28, 0x13, 0x02, 0xB0, 0x99, 0xE0, 0x64, 0xAA, 0x1E, + 0x43, 0x16, 0x7A, 0x73, 0xB1, 0x91, 0xA0, 0x75, 0x3E, 0xA8, 0xFA, 0xE3, + 0x38, 0x00, 0x7A, 0xEC, 0x89, 0x6A, 0x20, 0x0F, 0x8B, 0xC5, 0xB0, 0x9B, + 0x33, 0x03, 0x5A, 0x86, 0xC6, 0x58, 0x86, 0xD5, 0xC1, 0x85, 0xBB, 0x4F, + 0xC6, 0x9C, 0x40, 0x4D, 0xCA, 0xBE, 0xEE, 0x69, 0x96, 0xB8, 0xAD, 0x81, + 0x30, 0x9A, 0x7C, 0x92, 0x05, 0xEB, 0x05, 0x2B, 0x9A, 0x48, 0xD0, 0xB8, + 0x76, 0x3E, 0x96, 0xC8, 0x20, 0xBB, 0xD2, 0xB0, 0xF1, 0x8F, 0xD8, 0xAC, + 0x45, 0x46, 0xFF, 0xAA, 0x67, 0x60, 0xB4, 0x77, 0x7E, 0x6A, 0x1F, 0x3C, + 0x1A, 0x52, 0x7A, 0x04, 0x3D, 0x07, 0x3C, 0x85, 0x0D, 0x84, 0xD0, 0x1F, + 0x76, 0x0A, 0xF7, 0x6A, 0x14, 0xDF, 0x72, 0xE3, 0x34, 0x7C, 0x57, 0x4E, + 0x56, 0x01, 0x3E, 0x79, 0xF1, 0xAA, 0x29, 0x3B, 0x6C, 0xFA, 0xF8, 0x8F, + 0x6D, 0x4D, 0xC8, 0x35, 0xDF, 0xAE, 0xEB, 0xDC, 0x24, 0xEE, 0x79, 0x45, + 0xA7, 0x85, 0xB6, 0x05, 0x88, 0xDE, 0x88, 0x5D, 0x25, 0x7C, 0x97, 0x64, + 0x67, 0x09, 0xD9, 0xBF, 0x5A, 0x15, 0x05, 0x86, 0xF3, 0x09, 0x1E, 0xEC, + 0x58, 0x32, 0x33, 0x11, 0xF3, 0x77, 0x64, 0xB0, 0x76, 0x1F, 0xE4, 0x10, + 0x35, 0x17, 0x1B, 0xF2, 0x0E, 0xB1, 0x6C, 0xA4, 0x2A, 0xA3, 0x73, 0xFC, + 0x09, 0x1F, 0x1E, 0x32, 0x19, 0x53, 0x11, 0xE7, 0xD9, 0xB3, 0x2C, 0x2E, + 0x76, 0x2E, 0xA1, 0xA3, 0xDE, 0x7E, 0x6A, 0x88, 0x09, 0xE8, 0xF2, 0x07, + 0x8A, 0xF8, 0xB2, 0xCD, 0x10, 0xE7, 0xE2, 0x73, 0x40, 0x93, 0xBB, 0x08, + 0xD1, 0x3F, 0xE1, 0xFC, 0x0B, 0x94, 0xB3, 0x25, 0xEF, 0x7C, 0xA6, 0xD7, + 0xD1, 0xAF, 0x9F, 0xFF, 0x96, 0x9A, 0xF5, 0x91, 0x7B, 0x98, 0x0B, 0x77, + 0xD4, 0x7E, 0xE8, 0x07, 0xD2, 0x62, 0xB5, 0x95, 0x39, 0xE3, 0xF3, 0xF1, + 0x6D, 0x0F, 0x0E, 0x65, 0x84, 0x8A, 0x63, 0x54, 0xC5, 0x80, 0xB6, 0xE0, + 0x9E, 0x4B, 0x7D, 0x47, 0x26, 0xA7, 0x01, 0x08, 0x5D, 0xD1, 0x88, 0x9E, + 0xD7, 0xC3, 0x32, 0x44, 0xFA, 0x82, 0x4A, 0x0A, 0x68, 0x54, 0x7F, 0x38, + 0x53, 0x03, 0xCC, 0xA4, 0x00, 0x33, 0x64, 0x51, 0x59, 0x0B, 0xA3, 0x82, + 0x91, 0x7A, 0x5E, 0xEC, 0x16, 0xC2, 0xF3, 0x2A, 0xE6, 0x62, 0xDA, 0x2A, + 0xDB, 0x59, 0x62, 0x10, 0x25, 0x4A, 0x2A, 0x81, 0x0B, 0x47, 0x07, 0x43, + 0x06, 0x70, 0x87, 0xD2, 0xFA, 0x93, 0x11, 0x29, 0x7A, 0x48, 0x4D, 0xEB, + 0x94, 0xC7, 0x70, 0x4D, 0xAF, 0x67, 0xD5, 0x51, 0xB1, 0x80, 0x20, 0x01, + 0x01, 0xB4, 0x7A, 0x08, 0xA6, 0x90, 0x7F, 0x4E, 0xE0, 0xEF, 0x07, 0x41, + 0x87, 0xAF, 0x6A, 0xA5, 0x5E, 0x8B, 0xFB, 0xCF, 0x50, 0xB2, 0x9A, 0x54, + 0xAF, 0xC3, 0x89, 0xBA, 0x58, 0x2D, 0xF5, 0x30, 0x98, 0xB1, 0x36, 0x72, + 0x39, 0x7E, 0x49, 0x04, 0xFD, 0x29, 0xA7, 0x4C, 0x79, 0xE4, 0x05, 0x57, + 0xDB, 0x94, 0xB9, 0x16, 0x53, 0x8D, 0x46, 0xB3, 0x1D, 0x95, 0x61, 0x57, + 0x56, 0x7F, 0xAF, 0xF0, 0x16, 0x5B, 0x61, 0x58, 0x6F, 0x36, 0x50, 0x11, + 0x0B, 0xD8, 0xAC, 0x2B, 0x95, 0x16, 0x1A, 0x0E, 0x1F, 0x08, 0xCD, 0x36, + 0x34, 0x65, 0x10, 0x62, 0x66, 0xD5, 0x80, 0x5F, 0x14, 0x20, 0x5F, 0x2D, + 0x0C, 0xA0, 0x78, 0x0A, 0x68, 0xD6, 0x2C, 0xD7, 0xE9, 0x6F, 0x2B, 0xD2, + 0x4A, 0x05, 0x93, 0xFC, 0x9E, 0x6F, 0x6B, 0x67, 0xFF, 0x88, 0xF1, 0x4E, + 0xA5, 0x69, 0x4A, 0x52, 0x37, 0x05, 0xEA, 0xC6, 0x16, 0x8D, 0xD2, 0xC4, + 0x99, 0xD1, 0x82, 0x2B, 0x3B, 0xBA, 0x35, 0x75, 0xF7, 0x51, 0x51, 0x58, + 0xF3, 0xC8, 0x07, 0xDD, 0xE4, 0xB4, 0x03, 0x7F +}; + +static const unsigned char TA378_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA379_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x1B, + 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x55, 0x43, 0x41, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x47, 0x32, 0x20, 0x52, + 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA379_RSA_N[] = { + 0xC5, 0xE6, 0x2B, 0x6F, 0x7C, 0xEF, 0x26, 0x05, 0x27, 0xA3, 0x81, 0x24, + 0xDA, 0x6F, 0xCB, 0x01, 0xF9, 0x99, 0x9A, 0xA9, 0x32, 0xC2, 0x22, 0x87, + 0x61, 0x41, 0x91, 0x3B, 0xCB, 0xC3, 0x68, 0x1B, 0x06, 0xC5, 0x4C, 0xA9, + 0x2B, 0xC1, 0x67, 0x17, 0x22, 0x1D, 0x2B, 0xED, 0xF9, 0x29, 0x89, 0x93, + 0xA2, 0x78, 0xBD, 0x92, 0x6B, 0xA0, 0xA3, 0x0D, 0xA2, 0x7E, 0xCA, 0x93, + 0xB3, 0xA6, 0xD1, 0x8C, 0x35, 0xD5, 0x75, 0xF9, 0x17, 0xF6, 0xCF, 0x45, + 0xC5, 0xE5, 0x7A, 0xEC, 0x77, 0x93, 0xA0, 0x8F, 0x23, 0xAE, 0x0E, 0x1A, + 0x03, 0x7F, 0xBE, 0xD4, 0xD0, 0xED, 0x2E, 0x7B, 0xAB, 0x46, 0x23, 0x5B, + 0xFF, 0x2C, 0xE6, 0x54, 0x7A, 0x94, 0xC0, 0x2A, 0x15, 0xF0, 0xC9, 0x8D, + 0xB0, 0x7A, 0x3B, 0x24, 0xE1, 0xD7, 0x68, 0xE2, 0x31, 0x3C, 0x06, 0x33, + 0x46, 0xB6, 0x54, 0x11, 0xA6, 0xA5, 0x2F, 0x22, 0x54, 0x2A, 0x58, 0x0D, + 0x01, 0x02, 0xF1, 0xFA, 0x15, 0x51, 0x67, 0x6C, 0xC0, 0xFA, 0xD7, 0xB6, + 0x1B, 0x7F, 0xD1, 0x56, 0x88, 0x2F, 0x1A, 0x3A, 0x8D, 0x3B, 0xBB, 0x82, + 0x11, 0xE0, 0x47, 0x00, 0xD0, 0x52, 0x87, 0xAB, 0xFB, 0x86, 0x7E, 0x0F, + 0x24, 0x6B, 0x40, 0x9D, 0x34, 0x67, 0xBC, 0x8D, 0xC7, 0x2D, 0x86, 0x6F, + 0x79, 0x3E, 0x8E, 0xA9, 0x3C, 0x17, 0x4B, 0x7F, 0xB0, 0x99, 0xE3, 0xB0, + 0x71, 0x60, 0xDC, 0x0B, 0xF5, 0x64, 0xC3, 0xCE, 0x43, 0xBC, 0x6D, 0x71, + 0xB9, 0xD2, 0xDE, 0x27, 0x5B, 0x8A, 0xE8, 0xD8, 0xC6, 0xAE, 0xE1, 0x59, + 0x7D, 0xCF, 0x28, 0x2D, 0x35, 0xB8, 0x95, 0x56, 0x1A, 0xF1, 0xB2, 0x58, + 0x4B, 0xB7, 0x12, 0x37, 0xC8, 0x7C, 0xB3, 0xED, 0x4B, 0x80, 0xE1, 0x8D, + 0xFA, 0x32, 0x23, 0xB6, 0x6F, 0xB7, 0x48, 0x95, 0x08, 0xB1, 0x44, 0x4E, + 0x85, 0x8C, 0x3A, 0x02, 0x54, 0x20, 0x2F, 0xDF, 0xBF, 0x57, 0x4F, 0x3B, + 0x3A, 0x90, 0x21, 0xD7, 0xC1, 0x26, 0x35, 0x54, 0x20, 0xEC, 0xC7, 0x3F, + 0x47, 0xEC, 0xEF, 0x5A, 0xBF, 0x4B, 0x7A, 0xC1, 0xAD, 0x3B, 0x17, 0x50, + 0x5C, 0x62, 0xD8, 0x0F, 0x4B, 0x4A, 0xDC, 0x2B, 0xFA, 0x6E, 0xBC, 0x73, + 0x92, 0xCD, 0xEC, 0xC7, 0x50, 0xE8, 0x41, 0x96, 0xD7, 0xA9, 0x7E, 0x6D, + 0xD8, 0xE9, 0x1D, 0x8F, 0x8A, 0xB5, 0xB9, 0x58, 0x92, 0xBA, 0x4A, 0x92, + 0x2B, 0x0C, 0x56, 0xFD, 0x80, 0xEB, 0x08, 0xF0, 0x5E, 0x29, 0x6E, 0x1B, + 0x1C, 0x0C, 0xAF, 0x8F, 0x93, 0x89, 0xAD, 0xDB, 0xBD, 0xA3, 0x9E, 0x21, + 0xCA, 0x89, 0x19, 0xEC, 0xDF, 0xB5, 0xC3, 0x1A, 0xEB, 0x16, 0xFE, 0x78, + 0x36, 0x4C, 0xD6, 0x6E, 0xD0, 0x3E, 0x17, 0x1C, 0x90, 0x17, 0x6B, 0x26, + 0xBA, 0xFB, 0x7A, 0x2F, 0xBF, 0x11, 0x1C, 0x18, 0x0E, 0x2D, 0x73, 0x03, + 0x8F, 0xA0, 0xE5, 0x35, 0xA0, 0x5A, 0xE2, 0x4C, 0x75, 0x1D, 0x71, 0xE1, + 0x39, 0x38, 0x53, 0x78, 0x40, 0xCC, 0x83, 0x93, 0xD7, 0x0A, 0x9E, 0x9D, + 0x5B, 0x8F, 0x8A, 0xE4, 0xE5, 0xE0, 0x48, 0xE4, 0x48, 0xB2, 0x47, 0xCD, + 0x4E, 0x2A, 0x75, 0x2A, 0x7B, 0xF2, 0x22, 0xF6, 0xC9, 0xBE, 0x09, 0x91, + 0x96, 0x57, 0x7A, 0x88, 0x88, 0xAC, 0xEE, 0x70, 0xAC, 0xF9, 0xDC, 0x29, + 0xE3, 0x0C, 0x1C, 0x3B, 0x12, 0x4E, 0x44, 0xD6, 0xA7, 0x4E, 0xB0, 0x26, + 0xC8, 0xF3, 0xD9, 0x1A, 0x97, 0x91, 0x68, 0xEA, 0xEF, 0x8D, 0x46, 0x06, + 0xD2, 0x56, 0x45, 0x58, 0x9A, 0x3C, 0x0C, 0x0F, 0x83, 0xB8, 0x05, 0x25, + 0xC3, 0x39, 0xCF, 0x3B, 0xA4, 0x34, 0x89, 0xB7, 0x79, 0x12, 0x2F, 0x47, + 0xC5, 0xE7, 0xA9, 0x97, 0x69, 0xFC, 0xA6, 0x77, 0x67, 0xB5, 0xDF, 0x7B, + 0xF1, 0x7A, 0x65, 0x15, 0xE4, 0x61, 0x56, 0x65 +}; + +static const unsigned char TA379_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA380_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA380_EC_Q[] = { + 0x04, 0x1A, 0xAC, 0x54, 0x5A, 0xA9, 0xF9, 0x68, 0x23, 0xE7, 0x7A, 0xD5, + 0x24, 0x6F, 0x53, 0xC6, 0x5A, 0xD8, 0x4B, 0xAB, 0xC6, 0xD5, 0xB6, 0xD1, + 0xE6, 0x73, 0x71, 0xAE, 0xDD, 0x9C, 0xD6, 0x0C, 0x61, 0xFD, 0xDB, 0xA0, + 0x89, 0x03, 0xB8, 0x05, 0x14, 0xEC, 0x57, 0xCE, 0xEE, 0x5D, 0x3F, 0xE2, + 0x21, 0xB3, 0xCE, 0xF7, 0xD4, 0x8A, 0x79, 0xE0, 0xA3, 0x83, 0x7E, 0x2D, + 0x97, 0xD0, 0x61, 0xC4, 0xF1, 0x99, 0xDC, 0x25, 0x91, 0x63, 0xAB, 0x7F, + 0x30, 0xA3, 0xB4, 0x70, 0xE2, 0xC7, 0xA1, 0x33, 0x9C, 0xF3, 0xBF, 0x2E, + 0x5C, 0x53, 0xB1, 0x5F, 0xB3, 0x7D, 0x32, 0x7F, 0x8A, 0x34, 0xE3, 0x79, + 0x79 +}; + +static const unsigned char TA381_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA381_RSA_N[] = { + 0x80, 0x12, 0x65, 0x17, 0x36, 0x0E, 0xC3, 0xDB, 0x08, 0xB3, 0xD0, 0xAC, + 0x57, 0x0D, 0x76, 0xED, 0xCD, 0x27, 0xD3, 0x4C, 0xAD, 0x50, 0x83, 0x61, + 0xE2, 0xAA, 0x20, 0x4D, 0x09, 0x2D, 0x64, 0x09, 0xDC, 0xCE, 0x89, 0x9F, + 0xCC, 0x3D, 0xA9, 0xEC, 0xF6, 0xCF, 0xC1, 0xDC, 0xF1, 0xD3, 0xB1, 0xD6, + 0x7B, 0x37, 0x28, 0x11, 0x2B, 0x47, 0xDA, 0x39, 0xC6, 0xBC, 0x3A, 0x19, + 0xB4, 0x5F, 0xA6, 0xBD, 0x7D, 0x9D, 0xA3, 0x63, 0x42, 0xB6, 0x76, 0xF2, + 0xA9, 0x3B, 0x2B, 0x91, 0xF8, 0xE2, 0x6F, 0xD0, 0xEC, 0x16, 0x20, 0x90, + 0x09, 0x3E, 0xE2, 0xE8, 0x74, 0xC9, 0x18, 0xB4, 0x91, 0xD4, 0x62, 0x64, + 0xDB, 0x7F, 0xA3, 0x06, 0xF1, 0x88, 0x18, 0x6A, 0x90, 0x22, 0x3C, 0xBC, + 0xFE, 0x13, 0xF0, 0x87, 0x14, 0x7B, 0xF6, 0xE4, 0x1F, 0x8E, 0xD4, 0xE4, + 0x51, 0xC6, 0x11, 0x67, 0x46, 0x08, 0x51, 0xCB, 0x86, 0x14, 0x54, 0x3F, + 0xBC, 0x33, 0xFE, 0x7E, 0x6C, 0x9C, 0xFF, 0x16, 0x9D, 0x18, 0xBD, 0x51, + 0x8E, 0x35, 0xA6, 0xA7, 0x66, 0xC8, 0x72, 0x67, 0xDB, 0x21, 0x66, 0xB1, + 0xD4, 0x9B, 0x78, 0x03, 0xC0, 0x50, 0x3A, 0xE8, 0xCC, 0xF0, 0xDC, 0xBC, + 0x9E, 0x4C, 0xFE, 0xAF, 0x05, 0x96, 0x35, 0x1F, 0x57, 0x5A, 0xB7, 0xFF, + 0xCE, 0xF9, 0x3D, 0xB7, 0x2C, 0xB6, 0xF6, 0x54, 0xDD, 0xC8, 0xE7, 0x12, + 0x3A, 0x4D, 0xAE, 0x4C, 0x8A, 0xB7, 0x5C, 0x9A, 0xB4, 0xB7, 0x20, 0x3D, + 0xCA, 0x7F, 0x22, 0x34, 0xAE, 0x7E, 0x3B, 0x68, 0x66, 0x01, 0x44, 0xE7, + 0x01, 0x4E, 0x46, 0x53, 0x9B, 0x33, 0x60, 0xF7, 0x94, 0xBE, 0x53, 0x37, + 0x90, 0x73, 0x43, 0xF3, 0x32, 0xC3, 0x53, 0xEF, 0xDB, 0xAA, 0xFE, 0x74, + 0x4E, 0x69, 0xC7, 0x6B, 0x8C, 0x60, 0x93, 0xDE, 0xC4, 0xC7, 0x0C, 0xDF, + 0xE1, 0x32, 0xAE, 0xCC, 0x93, 0x3B, 0x51, 0x78, 0x95, 0x67, 0x8B, 0xEE, + 0x3D, 0x56, 0xFE, 0x0C, 0xD0, 0x69, 0x0F, 0x1B, 0x0F, 0xF3, 0x25, 0x26, + 0x6B, 0x33, 0x6D, 0xF7, 0x6E, 0x47, 0xFA, 0x73, 0x43, 0xE5, 0x7E, 0x0E, + 0xA5, 0x66, 0xB1, 0x29, 0x7C, 0x32, 0x84, 0x63, 0x55, 0x89, 0xC4, 0x0D, + 0xC1, 0x93, 0x54, 0x30, 0x19, 0x13, 0xAC, 0xD3, 0x7D, 0x37, 0xA7, 0xEB, + 0x5D, 0x3A, 0x6C, 0x35, 0x5C, 0xDB, 0x41, 0xD7, 0x12, 0xDA, 0xA9, 0x49, + 0x0B, 0xDF, 0xD8, 0x80, 0x8A, 0x09, 0x93, 0x62, 0x8E, 0xB5, 0x66, 0xCF, + 0x25, 0x88, 0xCD, 0x84, 0xB8, 0xB1, 0x3F, 0xA4, 0x39, 0x0F, 0xD9, 0x02, + 0x9E, 0xEB, 0x12, 0x4C, 0x95, 0x7C, 0xF3, 0x6B, 0x05, 0xA9, 0x5E, 0x16, + 0x83, 0xCC, 0xB8, 0x67, 0xE2, 0xE8, 0x13, 0x9D, 0xCC, 0x5B, 0x82, 0xD3, + 0x4C, 0xB3, 0xED, 0x5B, 0xFF, 0xDE, 0xE5, 0x73, 0xAC, 0x23, 0x3B, 0x2D, + 0x00, 0xBF, 0x35, 0x55, 0x74, 0x09, 0x49, 0xD8, 0x49, 0x58, 0x1A, 0x7F, + 0x92, 0x36, 0xE6, 0x51, 0x92, 0x0E, 0xF3, 0x26, 0x7D, 0x1C, 0x4D, 0x17, + 0xBC, 0xC9, 0xEC, 0x43, 0x26, 0xD0, 0xBF, 0x41, 0x5F, 0x40, 0xA9, 0x44, + 0x44, 0xF4, 0x99, 0xE7, 0x57, 0x87, 0x9E, 0x50, 0x1F, 0x57, 0x54, 0xA8, + 0x3E, 0xFD, 0x74, 0x63, 0x2F, 0xB1, 0x50, 0x65, 0x09, 0xE6, 0x58, 0x42, + 0x2E, 0x43, 0x1A, 0x4C, 0xB4, 0xF0, 0x25, 0x47, 0x59, 0xFA, 0x04, 0x1E, + 0x93, 0xD4, 0x26, 0x46, 0x4A, 0x50, 0x81, 0xB2, 0xDE, 0xBE, 0x78, 0xB7, + 0xFC, 0x67, 0x15, 0xE1, 0xC9, 0x57, 0x84, 0x1E, 0x0F, 0x63, 0xD6, 0xE9, + 0x62, 0xBA, 0xD6, 0x5F, 0x55, 0x2E, 0xEA, 0x5C, 0xC6, 0x28, 0x08, 0x04, + 0x25, 0x39, 0xB8, 0x0E, 0x2B, 0xA9, 0xF2, 0x4C, 0x97, 0x1C, 0x07, 0x3F, + 0x0D, 0x52, 0xF5, 0xED, 0xEF, 0x2F, 0x82, 0x0F +}; + +static const unsigned char TA381_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA382_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x15, 0x77, 0x77, 0x77, 0x2E, 0x78, 0x72, 0x61, 0x6D, 0x70, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x58, + 0x52, 0x61, 0x6D, 0x70, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x24, 0x58, 0x52, 0x61, 0x6D, 0x70, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA382_RSA_N[] = { + 0x98, 0x24, 0x1E, 0xBD, 0x15, 0xB4, 0xBA, 0xDF, 0xC7, 0x8C, 0xA5, 0x27, + 0xB6, 0x38, 0x0B, 0x69, 0xF3, 0xB6, 0x4E, 0xA8, 0x2C, 0x2E, 0x21, 0x1D, + 0x5C, 0x44, 0xDF, 0x21, 0x5D, 0x7E, 0x23, 0x74, 0xFE, 0x5E, 0x7E, 0xB4, + 0x4A, 0xB7, 0xA6, 0xAD, 0x1F, 0xAE, 0xE0, 0x06, 0x16, 0xE2, 0x9B, 0x5B, + 0xD9, 0x67, 0x74, 0x6B, 0x5D, 0x80, 0x8F, 0x29, 0x9D, 0x86, 0x1B, 0xD9, + 0x9C, 0x0D, 0x98, 0x6D, 0x76, 0x10, 0x28, 0x58, 0xE4, 0x65, 0xB0, 0x7F, + 0x4A, 0x98, 0x79, 0x9F, 0xE0, 0xC3, 0x31, 0x7E, 0x80, 0x2B, 0xB5, 0x8C, + 0xC0, 0x40, 0x3B, 0x11, 0x86, 0xD0, 0xCB, 0xA2, 0x86, 0x36, 0x60, 0xA4, + 0xD5, 0x30, 0x82, 0x6D, 0xD9, 0x6E, 0xD0, 0x0F, 0x12, 0x04, 0x33, 0x97, + 0x5F, 0x4F, 0x61, 0x5A, 0xF0, 0xE4, 0xF9, 0x91, 0xAB, 0xE7, 0x1D, 0x3B, + 0xBC, 0xE8, 0xCF, 0xF4, 0x6B, 0x2D, 0x34, 0x7C, 0xE2, 0x48, 0x61, 0x1C, + 0x8E, 0xF3, 0x61, 0x44, 0xCC, 0x6F, 0xA0, 0x4A, 0xA9, 0x94, 0xB0, 0x4D, + 0xDA, 0xE7, 0xA9, 0x34, 0x7A, 0x72, 0x38, 0xA8, 0x41, 0xCC, 0x3C, 0x94, + 0x11, 0x7D, 0xEB, 0xC8, 0xA6, 0x8C, 0xB7, 0x86, 0xCB, 0xCA, 0x33, 0x3B, + 0xD9, 0x3D, 0x37, 0x8B, 0xFB, 0x7A, 0x3E, 0x86, 0x2C, 0xE7, 0x73, 0xD7, + 0x0A, 0x57, 0xAC, 0x64, 0x9B, 0x19, 0xEB, 0xF4, 0x0F, 0x04, 0x08, 0x8A, + 0xAC, 0x03, 0x17, 0x19, 0x64, 0xF4, 0x5A, 0x25, 0x22, 0x8D, 0x34, 0x2C, + 0xB2, 0xF6, 0x68, 0x1D, 0x12, 0x6D, 0xD3, 0x8A, 0x1E, 0x14, 0xDA, 0xC4, + 0x8F, 0xA6, 0xE2, 0x23, 0x85, 0xD5, 0x7A, 0x0D, 0xBD, 0x6A, 0xE0, 0xE9, + 0xEC, 0xEC, 0x17, 0xBB, 0x42, 0x1B, 0x67, 0xAA, 0x25, 0xED, 0x45, 0x83, + 0x21, 0xFC, 0xC1, 0xC9, 0x7C, 0xD5, 0x62, 0x3E, 0xFA, 0xF2, 0xC5, 0x2D, + 0xD3, 0xFD, 0xD4, 0x65 +}; + +static const unsigned char TA382_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA383_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x08, 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x10, 0x63, 0x65, 0x72, + 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA383_RSA_N[] = { + 0xB7, 0x33, 0xB9, 0x7E, 0xC8, 0x25, 0x4A, 0x8E, 0xB5, 0xDB, 0xB4, 0x28, + 0x1B, 0xAA, 0x57, 0x90, 0xE8, 0xD1, 0x22, 0xD3, 0x64, 0xBA, 0xD3, 0x93, + 0xE8, 0xD4, 0xAC, 0x86, 0x61, 0x40, 0x6A, 0x60, 0x57, 0x68, 0x54, 0x84, + 0x4D, 0xBC, 0x6A, 0x54, 0x02, 0x05, 0xFF, 0xDF, 0x9B, 0x9A, 0x2A, 0xAE, + 0x5D, 0x07, 0x8F, 0x4A, 0xC3, 0x28, 0x7F, 0xEF, 0xFB, 0x2B, 0xFA, 0x79, + 0xF1, 0xC7, 0xAD, 0xF0, 0x10, 0x53, 0x24, 0x90, 0x8B, 0x66, 0xC9, 0xA8, + 0x88, 0xAB, 0xAF, 0x5A, 0xA3, 0x00, 0xE9, 0xBE, 0xBA, 0x46, 0xEE, 0x5B, + 0x73, 0x7B, 0x2C, 0x17, 0x82, 0x81, 0x5E, 0x62, 0x2C, 0xA1, 0x02, 0x65, + 0xB3, 0xBD, 0xC5, 0x2B, 0x00, 0x7E, 0xC4, 0xFC, 0x03, 0x33, 0x57, 0x0D, + 0xED, 0xE2, 0xFA, 0xCE, 0x5D, 0x45, 0xD6, 0x38, 0xCD, 0x35, 0xB6, 0xB2, + 0xC1, 0xD0, 0x9C, 0x81, 0x4A, 0xAA, 0xE4, 0xB2, 0x01, 0x5C, 0x1D, 0x8F, + 0x5F, 0x99, 0xC4, 0xB1, 0xAD, 0xDB, 0x88, 0x21, 0xEB, 0x90, 0x08, 0x82, + 0x80, 0xF3, 0x30, 0xA3, 0x43, 0xE6, 0x90, 0x82, 0xAE, 0x55, 0x28, 0x49, + 0xED, 0x5B, 0xD7, 0xA9, 0x10, 0x38, 0x0E, 0xFE, 0x8F, 0x4C, 0x5B, 0x9B, + 0x46, 0xEA, 0x41, 0xF5, 0xB0, 0x08, 0x74, 0xC3, 0xD0, 0x88, 0x33, 0xB6, + 0x7C, 0xD7, 0x74, 0xDF, 0xDC, 0x84, 0xD1, 0x43, 0x0E, 0x75, 0x39, 0xA1, + 0x25, 0x40, 0x28, 0xEA, 0x78, 0xCB, 0x0E, 0x2C, 0x2E, 0x39, 0x9D, 0x8C, + 0x8B, 0x6E, 0x16, 0x1C, 0x2F, 0x26, 0x82, 0x10, 0xE2, 0xE3, 0x65, 0x94, + 0x0A, 0x04, 0xC0, 0x5E, 0xF7, 0x5D, 0x5B, 0xF8, 0x10, 0xE2, 0xD0, 0xBA, + 0x7A, 0x4B, 0xFB, 0xDE, 0x37, 0x00, 0x00, 0x1A, 0x5B, 0x28, 0xE3, 0xD2, + 0x9C, 0x73, 0x3E, 0x32, 0x87, 0x98, 0xA1, 0xC9, 0x51, 0x2F, 0xD7, 0xDE, + 0xAC, 0x33, 0xB3, 0x4F +}; + +static const unsigned char TA383_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA384_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x43, 0x45, 0x52, 0x54, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x53, + 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x13, + 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, + 0x54, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA384_RSA_N[] = { + 0xC0, 0xC5, 0x75, 0x19, 0x91, 0x7D, 0x44, 0x74, 0x74, 0x87, 0xFE, 0x0E, + 0x3B, 0x96, 0xDC, 0xD8, 0x01, 0x16, 0xCC, 0xEE, 0x63, 0x91, 0xE7, 0x0B, + 0x6F, 0xCE, 0x3B, 0x0A, 0x69, 0x1A, 0x7C, 0xC2, 0xE3, 0xAF, 0x82, 0x8E, + 0x86, 0xD7, 0x5E, 0x8F, 0x57, 0xEB, 0xD3, 0x21, 0x59, 0xFD, 0x39, 0x37, + 0x42, 0x30, 0xBE, 0x50, 0xEA, 0xB6, 0x0F, 0xA9, 0x88, 0xD8, 0x2E, 0x2D, + 0x69, 0x21, 0xE7, 0xD1, 0x37, 0x18, 0x4E, 0x7D, 0x91, 0xD5, 0x16, 0x5F, + 0x6B, 0x5B, 0x00, 0xC2, 0x39, 0x43, 0x0D, 0x36, 0x85, 0x52, 0xB9, 0x53, + 0x65, 0x0F, 0x1D, 0x42, 0xE5, 0x8F, 0xCF, 0x05, 0xD3, 0xEE, 0xDC, 0x0C, + 0x1A, 0xD9, 0xB8, 0x8B, 0x78, 0x22, 0x67, 0xE4, 0x69, 0xB0, 0x68, 0xC5, + 0x3C, 0xE4, 0x6C, 0x5A, 0x46, 0xE7, 0xCD, 0xC7, 0xFA, 0xEF, 0xC4, 0xEC, + 0x4B, 0xBD, 0x6A, 0xA4, 0xAC, 0xFD, 0xCC, 0x28, 0x51, 0xEF, 0x92, 0xB4, + 0x29, 0xAB, 0xAB, 0x35, 0x9A, 0x4C, 0xE4, 0xC4, 0x08, 0xC6, 0x26, 0xCC, + 0xF8, 0x69, 0x9F, 0xE4, 0x9C, 0xF0, 0x29, 0xD3, 0x5C, 0xF9, 0xC6, 0x16, + 0x25, 0x9E, 0x23, 0xC3, 0x20, 0xC1, 0x3D, 0x0F, 0x3F, 0x38, 0x40, 0xB0, + 0xFE, 0x82, 0x44, 0x38, 0xAA, 0x5A, 0x1A, 0x8A, 0x6B, 0x63, 0x58, 0x38, + 0xB4, 0x15, 0xD3, 0xB6, 0x11, 0x69, 0x7B, 0x1E, 0x54, 0xEE, 0x8C, 0x1A, + 0x22, 0xAC, 0x72, 0x97, 0x3F, 0x23, 0x59, 0x9B, 0xC9, 0x22, 0x84, 0xC1, + 0x07, 0x4F, 0xCC, 0x7F, 0xE2, 0x57, 0xCA, 0x12, 0x70, 0xBB, 0xA6, 0x65, + 0xF3, 0x69, 0x75, 0x63, 0xBD, 0x95, 0xFB, 0x1B, 0x97, 0xCD, 0xE4, 0xA8, + 0xAF, 0xF6, 0xD1, 0x4E, 0xA8, 0xD9, 0x8A, 0x71, 0x24, 0xCD, 0x36, 0x3D, + 0xBC, 0x96, 0xC4, 0xF1, 0x6C, 0xA9, 0xAE, 0xE5, 0xCF, 0x0D, 0x6E, 0x28, + 0x0D, 0xB0, 0x0E, 0xB5, 0xCA, 0x51, 0x7B, 0x78, 0x14, 0xC3, 0x20, 0x2F, + 0x7F, 0xFB, 0x14, 0x55, 0xE1, 0x11, 0x99, 0xFD, 0xD5, 0x0A, 0xA1, 0x9E, + 0x02, 0xE3, 0x62, 0x5F, 0xEB, 0x35, 0x4B, 0x2C, 0xB8, 0x72, 0xE8, 0x3E, + 0x3D, 0x4F, 0xAC, 0x2C, 0xBB, 0x2E, 0x86, 0xE2, 0xA3, 0x76, 0x8F, 0xE5, + 0x93, 0x2A, 0xCF, 0xA5, 0xAB, 0xC8, 0x5C, 0x8D, 0x4B, 0x06, 0xFF, 0x12, + 0x46, 0xAC, 0x78, 0xCB, 0x14, 0x07, 0x35, 0xE0, 0xA9, 0xDF, 0x8B, 0xE9, + 0xAF, 0x15, 0x4F, 0x16, 0x89, 0x5B, 0xBD, 0xF6, 0x8D, 0xC6, 0x59, 0xAE, + 0x88, 0x85, 0x0E, 0xC1, 0x89, 0xEB, 0x1F, 0x67, 0xC5, 0x45, 0x8E, 0xFF, + 0x6D, 0x37, 0x36, 0x2B, 0x78, 0x66, 0x83, 0x91, 0x51, 0x2B, 0x3D, 0xFF, + 0x51, 0x77, 0x76, 0x62, 0xA1, 0xEC, 0x67, 0x3E, 0x3E, 0x81, 0x83, 0xE0, + 0x56, 0xA9, 0x50, 0x1F, 0x1F, 0x7A, 0x99, 0xAB, 0x63, 0xBF, 0x84, 0x17, + 0x77, 0xF1, 0x0D, 0x3B, 0xDF, 0xF7, 0x9C, 0x61, 0xB3, 0x35, 0x98, 0x8A, + 0x3A, 0xB2, 0xEC, 0x3C, 0x1A, 0x37, 0x3F, 0x7E, 0x8F, 0x92, 0xCF, 0xD9, + 0x12, 0x14, 0x64, 0xDA, 0x10, 0x02, 0x15, 0x41, 0xFF, 0x4F, 0xC4, 0xEB, + 0x1C, 0xA3, 0xC9, 0xFA, 0x99, 0xF7, 0x46, 0xE9, 0xE1, 0x18, 0xD9, 0xB1, + 0xB8, 0x32, 0x2D, 0xCB, 0x14, 0x0C, 0x50, 0xD8, 0x83, 0x65, 0x83, 0xEE, + 0xB9, 0x5C, 0xCF, 0xCB, 0x05, 0x5A, 0x4C, 0xFA, 0x19, 0x97, 0x6B, 0xD6, + 0x5D, 0x13, 0xD3, 0xC2, 0x5C, 0x54, 0xBC, 0x32, 0x73, 0xA0, 0x78, 0xF5, + 0xF1, 0x6D, 0x1E, 0xCB, 0x9F, 0xA5, 0xA6, 0x9F, 0x22, 0xDC, 0xD1, 0x51, + 0x9E, 0x82, 0x79, 0x64, 0x60, 0x29, 0x13, 0x3E, 0xA3, 0xFD, 0x4F, 0x72, + 0x6A, 0xAB, 0xE2, 0xD4, 0xE5, 0xB8, 0x24, 0x55, 0x2C, 0x44, 0x4B, 0x8A, + 0x88, 0x44, 0x9C, 0xCA, 0x84, 0xD3, 0x2A, 0x3B +}; + +static const unsigned char TA384_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA385_DN[] = { + 0x30, 0x71, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, 0x63, + 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0E, 0x56, 0x41, 0x54, + 0x48, 0x55, 0x2D, 0x32, 0x33, 0x35, 0x38, 0x34, 0x34, 0x39, 0x37, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x15, 0x65, 0x2D, + 0x53, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA385_EC_Q[] = { + 0x04, 0x96, 0xDC, 0x3D, 0x8A, 0xD8, 0xB0, 0x7B, 0x6F, 0xC6, 0x27, 0xBE, + 0x44, 0x90, 0xB1, 0xB3, 0x56, 0x15, 0x7B, 0x8E, 0x43, 0x24, 0x7D, 0x1A, + 0x84, 0x59, 0xEE, 0x63, 0x68, 0xB2, 0xC6, 0x5E, 0x87, 0xD0, 0x15, 0x48, + 0x1E, 0xA8, 0x90, 0xAD, 0xBD, 0x53, 0xA2, 0xDA, 0xDE, 0x3A, 0x90, 0xA6, + 0x60, 0x5F, 0x68, 0x32, 0xB5, 0x86, 0x41, 0xDF, 0x87, 0x5B, 0x2C, 0x7B, + 0xC5, 0xFE, 0x7C, 0x7A, 0xDA +}; + +static const unsigned char TA386_DN[] = { + 0x30, 0x5E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x21, 0x65, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA386_RSA_N[] = { + 0xE1, 0x25, 0x0F, 0xEE, 0x8D, 0xDB, 0x88, 0x33, 0x75, 0x67, 0xCD, 0xAD, + 0x1F, 0x7D, 0x3A, 0x4E, 0x6D, 0x9D, 0xD3, 0x2F, 0x14, 0xF3, 0x63, 0x74, + 0xCB, 0x01, 0x21, 0x6A, 0x37, 0xEA, 0x84, 0x50, 0x07, 0x4B, 0x26, 0x5B, + 0x09, 0x43, 0x6C, 0x21, 0x9E, 0x6A, 0xC8, 0xD5, 0x03, 0xF5, 0x60, 0x69, + 0x8F, 0xCC, 0xF0, 0x22, 0xE4, 0x1F, 0xE7, 0xF7, 0x6A, 0x22, 0x31, 0xB7, + 0x2C, 0x15, 0xF2, 0xE0, 0xFE, 0x00, 0x6A, 0x43, 0xFF, 0x87, 0x65, 0xC6, + 0xB5, 0x1A, 0xC1, 0xA7, 0x4C, 0x6D, 0x22, 0x70, 0x21, 0x8A, 0x31, 0xF2, + 0x97, 0x74, 0x89, 0x09, 0x12, 0x26, 0x1C, 0x9E, 0xCA, 0xD9, 0x12, 0xA2, + 0x95, 0x3C, 0xDA, 0xE9, 0x67, 0xBF, 0x08, 0xA0, 0x64, 0xE3, 0xD6, 0x42, + 0xB7, 0x45, 0xEF, 0x97, 0xF4, 0xF6, 0xF5, 0xD7, 0xB5, 0x4A, 0x15, 0x02, + 0x58, 0x7D, 0x98, 0x58, 0x4B, 0x60, 0xBC, 0xCD, 0xD7, 0x0D, 0x9A, 0x13, + 0x33, 0x53, 0xD1, 0x61, 0xF9, 0x7A, 0xD5, 0xD7, 0x78, 0xB3, 0x9A, 0x33, + 0xF7, 0x00, 0x86, 0xCE, 0x1D, 0x4D, 0x94, 0x38, 0xAF, 0xA8, 0xEC, 0x78, + 0x51, 0x70, 0x8A, 0x5C, 0x10, 0x83, 0x51, 0x21, 0xF7, 0x11, 0x3D, 0x34, + 0x86, 0x5E, 0xE5, 0x48, 0xCD, 0x97, 0x81, 0x82, 0x35, 0x4C, 0x19, 0xEC, + 0x65, 0xF6, 0x6B, 0xC5, 0x05, 0xA1, 0xEE, 0x47, 0x13, 0xD6, 0xB3, 0x21, + 0x27, 0x94, 0x10, 0x0A, 0xD9, 0x24, 0x3B, 0xBA, 0xBE, 0x44, 0x13, 0x46, + 0x30, 0x3F, 0x97, 0x3C, 0xD8, 0xD7, 0xD7, 0x6A, 0xEE, 0x3B, 0x38, 0xE3, + 0x2B, 0xD4, 0x97, 0x0E, 0xB9, 0x1B, 0xE7, 0x07, 0x49, 0x7F, 0x37, 0x2A, + 0xF9, 0x77, 0x78, 0xCF, 0x54, 0xED, 0x5B, 0x46, 0x9D, 0xA3, 0x80, 0x0E, + 0x91, 0x43, 0xC1, 0xD6, 0x5B, 0x5F, 0x14, 0xBA, 0x9F, 0xA6, 0x8D, 0x24, + 0x47, 0x40, 0x59, 0xBF, 0x72, 0x38, 0xB2, 0x36, 0x6C, 0x37, 0xFF, 0x99, + 0xD1, 0x5D, 0x0E, 0x59, 0x0A, 0xAB, 0x69, 0xF7, 0xC0, 0xB2, 0x04, 0x45, + 0x7A, 0x54, 0x00, 0xAE, 0xBE, 0x53, 0xF6, 0xB5, 0xE7, 0xE1, 0xF8, 0x3C, + 0xA3, 0x31, 0xD2, 0xA9, 0xFE, 0x21, 0x52, 0x64, 0xC5, 0xA6, 0x67, 0xF0, + 0x75, 0x07, 0x06, 0x94, 0x14, 0x81, 0x55, 0xC6, 0x27, 0xE4, 0x01, 0x8F, + 0x17, 0xC1, 0x6A, 0x71, 0xD7, 0xBE, 0x4B, 0xFB, 0x94, 0x58, 0x7D, 0x7E, + 0x11, 0x33, 0xB1, 0x42, 0xF7, 0x62, 0x6C, 0x18, 0xD6, 0xCF, 0x09, 0x68, + 0x3E, 0x7F, 0x6C, 0xF6, 0x1E, 0x8F, 0x62, 0xAD, 0xA5, 0x63, 0xDB, 0x09, + 0xA7, 0x1F, 0x22, 0x42, 0x41, 0x1E, 0x6F, 0x99, 0x8A, 0x3E, 0xD7, 0xF9, + 0x3F, 0x40, 0x7A, 0x79, 0xB0, 0xA5, 0x01, 0x92, 0xD2, 0x9D, 0x3D, 0x08, + 0x15, 0xA5, 0x10, 0x01, 0x2D, 0xB3, 0x32, 0x76, 0xA8, 0x95, 0x0D, 0xB3, + 0x7A, 0x9A, 0xFB, 0x07, 0x10, 0x78, 0x11, 0x6F, 0xE1, 0x8F, 0xC7, 0xBA, + 0x0F, 0x25, 0x1A, 0x74, 0x2A, 0xE5, 0x1C, 0x98, 0x41, 0x99, 0xDF, 0x21, + 0x87, 0xE8, 0x95, 0x06, 0x6A, 0x0A, 0xB3, 0x6A, 0x47, 0x76, 0x65, 0xF6, + 0x3A, 0xCF, 0x8F, 0x62, 0x17, 0x19, 0x7B, 0x0A, 0x28, 0xCD, 0x1A, 0xD2, + 0x83, 0x1E, 0x21, 0xC7, 0x2C, 0xBF, 0xBE, 0xFF, 0x61, 0x68, 0xB7, 0x67, + 0x1B, 0xBB, 0x78, 0x4D, 0x8D, 0xCE, 0x67, 0xE5, 0xE4, 0xC1, 0x8E, 0xB7, + 0x23, 0x66, 0xE2, 0x9D, 0x90, 0x75, 0x34, 0x98, 0xA9, 0x36, 0x2B, 0x8A, + 0x9A, 0x94, 0xB9, 0x9D, 0xEC, 0xCC, 0x8A, 0xB1, 0xF8, 0x25, 0x89, 0x5C, + 0x5A, 0xB6, 0x2F, 0x8C, 0x1F, 0x6D, 0x79, 0x24, 0xA7, 0x52, 0x68, 0xC3, + 0x84, 0x35, 0xE2, 0x66, 0x8D, 0x63, 0x0E, 0x25, 0x4D, 0xD5, 0x19, 0xB2, + 0xE6, 0x79, 0x37, 0xA7, 0x22, 0x9D, 0x54, 0x31 +}; + +static const unsigned char TA386_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA387_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x43, 0x33 +}; + +static const unsigned char TA387_EC_Q[] = { + 0x04, 0xFD, 0xA5, 0x61, 0xAE, 0x7B, 0x26, 0x10, 0x1D, 0xE9, 0xB7, 0x22, + 0x30, 0xAE, 0x06, 0xF4, 0x81, 0xB3, 0xB1, 0x42, 0x71, 0x95, 0x39, 0xBC, + 0xD3, 0x52, 0xE3, 0xAF, 0xAF, 0xF9, 0xF2, 0x97, 0x35, 0x92, 0x36, 0x46, + 0x0E, 0x87, 0x95, 0x8D, 0xB9, 0x39, 0x5A, 0xE9, 0xBB, 0xDF, 0xD0, 0xFE, + 0xC8, 0x07, 0x41, 0x3C, 0xBB, 0x55, 0x6F, 0x83, 0xA3, 0x6A, 0xFB, 0x62, + 0xB0, 0x81, 0x89, 0x02, 0x70, 0x7D, 0x48, 0xC5, 0x4A, 0xE3, 0xE9, 0x22, + 0x54, 0x22, 0x4D, 0x93, 0xBB, 0x42, 0x0C, 0xAF, 0x77, 0x9C, 0x23, 0xA6, + 0x7D, 0xD7, 0x61, 0x11, 0xCE, 0x65, 0xC7, 0xF8, 0x7F, 0xFE, 0xF5, 0xF2, + 0xA9 +}; + +static const unsigned char TA388_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x17, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, + 0x33 +}; + +static const unsigned char TA388_EC_Q[] = { + 0x04, 0x23, 0xA5, 0x0C, 0xB8, 0x2D, 0x12, 0xF5, 0x28, 0xF3, 0xB1, 0xB2, + 0xDD, 0xE2, 0x02, 0x12, 0x80, 0x9E, 0x39, 0x5F, 0x49, 0x4D, 0x9F, 0xC9, + 0x25, 0x34, 0x59, 0x74, 0xEC, 0xBB, 0x06, 0x1C, 0xE7, 0xC0, 0x72, 0xAF, + 0xE8, 0xAE, 0x2F, 0xE1, 0x41, 0x54, 0x87, 0x14, 0xA8, 0x4A, 0xB2, 0xE8, + 0x7C, 0x82, 0xE6, 0x5B, 0x6A, 0xB5, 0xDC, 0xB3, 0x75, 0xCE, 0x8B, 0x06, + 0xD0, 0x86, 0x23, 0xBF, 0x46, 0xD5, 0x8E, 0x0F, 0x3F, 0x04, 0xF4, 0xD7, + 0x1C, 0x92, 0x7E, 0xF6, 0xA5, 0x63, 0xC2, 0xF5, 0x5F, 0x8E, 0x2E, 0x4F, + 0xA1, 0x18, 0x19, 0x02, 0x2B, 0x32, 0x0A, 0x82, 0x64, 0x7D, 0x16, 0x93, + 0xD1 +}; + +static const unsigned char TA389_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x1C, + 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x43, 0x31 +}; + +static const unsigned char TA389_RSA_N[] = { + 0xCF, 0xEB, 0xA9, 0xB9, 0xF1, 0x99, 0x05, 0xCC, 0xD8, 0x28, 0x21, 0x4A, + 0xF3, 0x73, 0x34, 0x51, 0x84, 0x56, 0x10, 0xF5, 0xA0, 0x4F, 0x2C, 0x12, + 0xE3, 0xFA, 0x13, 0x9A, 0x27, 0xD0, 0xCF, 0xF9, 0x79, 0x1A, 0x74, 0x5F, + 0x1D, 0x79, 0x39, 0xFC, 0x5B, 0xF8, 0x70, 0x8E, 0xE0, 0x92, 0x52, 0xF7, + 0xE4, 0x25, 0xF9, 0x54, 0x83, 0xD9, 0x1D, 0xD3, 0xC8, 0x5A, 0x85, 0x3F, + 0x5E, 0xC7, 0xB6, 0x07, 0xEE, 0x3E, 0xC0, 0xCE, 0x9A, 0xAF, 0xAC, 0x56, + 0x42, 0x2A, 0x39, 0x25, 0x70, 0xD6, 0xBF, 0xB5, 0x7B, 0x36, 0xAD, 0xAC, + 0xF6, 0x73, 0xDC, 0xCD, 0xD7, 0x1D, 0x8A, 0x83, 0xA5, 0xFB, 0x2B, 0x90, + 0x15, 0x37, 0x6B, 0x1C, 0x26, 0x47, 0xDC, 0x3B, 0x29, 0x56, 0x93, 0x6A, + 0xB3, 0xC1, 0x6A, 0x3A, 0x9D, 0x3D, 0xF5, 0xC1, 0x97, 0x38, 0x58, 0x05, + 0x8B, 0x1C, 0x11, 0xE3, 0xE4, 0xB4, 0xB8, 0x5D, 0x85, 0x1D, 0x83, 0xFE, + 0x78, 0x5F, 0x0B, 0x45, 0x68, 0x18, 0x48, 0xA5, 0x46, 0x73, 0x34, 0x3B, + 0xFE, 0x0F, 0xC8, 0x76, 0xBB, 0xC7, 0x18, 0xF3, 0x05, 0xD1, 0x86, 0xF3, + 0x85, 0xED, 0xE7, 0xB9, 0xD9, 0x32, 0xAD, 0x55, 0x88, 0xCE, 0xA6, 0xB6, + 0x91, 0xB0, 0x4F, 0xAC, 0x7E, 0x15, 0x23, 0x96, 0xF6, 0x3F, 0xF0, 0x20, + 0x34, 0x16, 0xDE, 0x0A, 0xC6, 0xC4, 0x04, 0x45, 0x79, 0x7F, 0xA7, 0xFD, + 0xBE, 0xD2, 0xA9, 0xA5, 0xAF, 0x9C, 0xC5, 0x23, 0x2A, 0xF7, 0x3C, 0x21, + 0x6C, 0xBD, 0xAF, 0x8F, 0x4E, 0xC5, 0x3A, 0xB2, 0xF3, 0x34, 0x12, 0xFC, + 0xDF, 0x80, 0x1A, 0x49, 0xA4, 0xD4, 0xA9, 0x95, 0xF7, 0x9E, 0x89, 0x5E, + 0xA2, 0x89, 0xAC, 0x94, 0xCB, 0xA8, 0x68, 0x9B, 0xAF, 0x8A, 0x65, 0x27, + 0xCD, 0x89, 0xEE, 0xDD, 0x8C, 0xB5, 0x6B, 0x29, 0x70, 0x43, 0xA0, 0x69, + 0x0B, 0xE4, 0xB9, 0x0F +}; + +static const unsigned char TA389_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA390_DN[] = { + 0x30, 0x67, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x13, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA390_RSA_N[] = { + 0x93, 0x4B, 0xBB, 0xE9, 0x66, 0x8A, 0xEE, 0x9D, 0x5B, 0xD5, 0x34, 0x93, + 0xD0, 0x1B, 0x1E, 0xC3, 0xE7, 0x9E, 0xB8, 0x64, 0x33, 0x7F, 0x63, 0x78, + 0x68, 0xB4, 0xCD, 0x2E, 0x71, 0x75, 0xD7, 0x9B, 0x20, 0xC6, 0x4D, 0x29, + 0xBC, 0xB6, 0x68, 0x60, 0x8A, 0xF7, 0x21, 0x9A, 0x56, 0x35, 0x5A, 0xF3, + 0x76, 0xBD, 0xD8, 0xCD, 0x9A, 0xFF, 0x93, 0x56, 0x4B, 0xA5, 0x59, 0x06, + 0xA1, 0x93, 0x34, 0x29, 0xDD, 0x16, 0x34, 0x75, 0x4E, 0xF2, 0x81, 0xB4, + 0xC7, 0x96, 0x4E, 0xAD, 0x19, 0x15, 0x52, 0x4A, 0xFE, 0x3C, 0x70, 0x75, + 0x70, 0xCD, 0xAF, 0x2B, 0xAB, 0x15, 0x9A, 0x33, 0x3C, 0xAA, 0xB3, 0x8B, + 0xAA, 0xCD, 0x43, 0xFD, 0xF5, 0xEA, 0x70, 0xFF, 0xED, 0xCF, 0x11, 0x3B, + 0x94, 0xCE, 0x4E, 0x32, 0x16, 0xD3, 0x23, 0x40, 0x2A, 0x77, 0xB3, 0xAF, + 0x3C, 0x01, 0x2C, 0x6C, 0xED, 0x99, 0x2C, 0x8B, 0xD9, 0x4E, 0x69, 0x98, + 0xB2, 0xF7, 0x8F, 0x41, 0xB0, 0x32, 0x78, 0x61, 0xD6, 0x0D, 0x5F, 0xC3, + 0xFA, 0xA2, 0x40, 0x92, 0x1D, 0x5C, 0x17, 0xE6, 0x70, 0x3E, 0x35, 0xE7, + 0xA2, 0xB7, 0xC2, 0x62, 0xE2, 0xAB, 0xA4, 0x38, 0x4C, 0xB5, 0x39, 0x35, + 0x6F, 0xEA, 0x03, 0x69, 0xFA, 0x3A, 0x54, 0x68, 0x85, 0x6D, 0xD6, 0xF2, + 0x2F, 0x43, 0x55, 0x1E, 0x91, 0x0D, 0x0E, 0xD8, 0xD5, 0x6A, 0xA4, 0x96, + 0xD1, 0x13, 0x3C, 0x2C, 0x78, 0x50, 0xE8, 0x3A, 0x92, 0xD2, 0x17, 0x56, + 0xE5, 0x35, 0x1A, 0x40, 0x1C, 0x3E, 0x8D, 0x2C, 0xED, 0x39, 0xDF, 0x42, + 0xE0, 0x83, 0x41, 0x74, 0xDF, 0xA3, 0xCD, 0xC2, 0x86, 0x60, 0x48, 0x68, + 0xE3, 0x69, 0x0B, 0x54, 0x00, 0x8B, 0xE4, 0x76, 0x69, 0x21, 0x0D, 0x79, + 0x4E, 0x34, 0x08, 0x5E, 0x14, 0xC2, 0xCC, 0xB1, 0xB7, 0xAD, 0xD7, 0x7C, + 0x70, 0x8A, 0xC7, 0x85 +}; + +static const unsigned char TA390_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA391_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1A, 0x30, + 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA391_EC_Q[] = { + 0x04, 0x65, 0x50, 0x4A, 0xAE, 0x8C, 0x79, 0x96, 0x4A, 0xAA, 0x1C, 0x08, + 0xC3, 0xA3, 0xA2, 0xCD, 0xFE, 0x59, 0x56, 0x41, 0x77, 0xFD, 0x26, 0x94, + 0x42, 0xBB, 0x1D, 0xCD, 0x08, 0xDB, 0x73, 0xB2, 0x5B, 0x75, 0xF3, 0xCF, + 0x9C, 0x4E, 0x82, 0xF4, 0xBF, 0xF8, 0x61, 0x26, 0x85, 0x6C, 0xD6, 0x85, + 0x5B, 0x72, 0x70, 0xD2, 0xFD, 0xDB, 0x62, 0xB4, 0xDF, 0x53, 0x8B, 0xBD, + 0xB1, 0x44, 0x58, 0x62, 0x42, 0x09, 0xC7, 0xFA, 0x7F, 0x5B, 0x10, 0xE7, + 0xFE, 0x40, 0xFD, 0xC0, 0xD8, 0xC3, 0x2B, 0x32, 0xE7, 0x70, 0xA6, 0xB7, + 0xA6, 0x20, 0x55, 0x1D, 0x7B, 0x80, 0x5D, 0x4B, 0x8F, 0x67, 0x4C, 0xF1, + 0x10 +}; + +static const unsigned char TA392_DN[] = { + 0x30, 0x43, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, + 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0D, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA392_RSA_N[] = { + 0xBD, 0x55, 0x7C, 0x61, 0xD3, 0xB8, 0x1D, 0x04, 0x62, 0x05, 0xA0, 0xAE, + 0x6C, 0xB7, 0x70, 0xB4, 0x41, 0xEA, 0x4B, 0x03, 0x5E, 0x10, 0x3F, 0x90, + 0x5A, 0x1C, 0x8B, 0x3B, 0xB0, 0x66, 0x8B, 0x6C, 0x48, 0xA6, 0x1C, 0x22, + 0xBA, 0xD5, 0x40, 0x92, 0xEE, 0x33, 0xB2, 0x23, 0x59, 0xC9, 0x8E, 0xBC, + 0x58, 0xDA, 0x8B, 0x9E, 0xD0, 0x19, 0xF2, 0x2F, 0x59, 0xC6, 0x8C, 0x63, + 0x5A, 0xBA, 0x9F, 0xA3, 0x0B, 0xB0, 0xB3, 0x9A, 0x5C, 0xBA, 0x11, 0xB8, + 0x12, 0xE9, 0x0C, 0xBB, 0xCF, 0x6E, 0x6C, 0x80, 0x87, 0x29, 0x14, 0x03, + 0x2C, 0x8D, 0x24, 0x9A, 0xC8, 0x64, 0x83, 0xB5, 0x6A, 0xAC, 0x13, 0x2C, + 0x33, 0xF1, 0x9F, 0xDC, 0x2C, 0x61, 0x3C, 0x1A, 0x3F, 0x70, 0x55, 0x9B, + 0xAD, 0x00, 0x52, 0x7F, 0xCF, 0x04, 0xB9, 0xFE, 0x36, 0xFA, 0x9C, 0xC0, + 0x16, 0xAE, 0x62, 0xFE, 0x96, 0x4C, 0x43, 0x7E, 0x55, 0x14, 0xBE, 0x1A, + 0xB3, 0xD2, 0x6D, 0xC2, 0xAF, 0x76, 0x66, 0x95, 0x6B, 0x2A, 0xB0, 0x94, + 0x77, 0x85, 0x5E, 0x04, 0x0F, 0x62, 0x1D, 0x63, 0x75, 0xF7, 0x6B, 0xE7, + 0xCB, 0x5B, 0x9A, 0x70, 0xEC, 0x3E, 0x67, 0x05, 0xF0, 0xFE, 0x07, 0x08, + 0x80, 0xCF, 0x28, 0xDB, 0x05, 0xC6, 0x14, 0x27, 0x2F, 0x86, 0x7D, 0xF0, + 0x27, 0xDE, 0xFF, 0xE6, 0x7E, 0x33, 0x48, 0xE7, 0x0B, 0x1E, 0x58, 0xD1, + 0x27, 0x2B, 0x53, 0x0E, 0x57, 0x4A, 0x65, 0xD7, 0xFB, 0xA2, 0x80, 0x60, + 0xFC, 0x4C, 0xBC, 0x35, 0x53, 0x01, 0x6A, 0x97, 0x72, 0x82, 0xAF, 0xF1, + 0x1D, 0x70, 0xE8, 0x9C, 0xF5, 0xEF, 0x5E, 0xC2, 0x6C, 0xC7, 0x47, 0x7E, + 0x5A, 0x94, 0x85, 0x26, 0x4D, 0x3B, 0xBA, 0xEB, 0x4C, 0xE8, 0xB0, 0x09, + 0xC2, 0x65, 0xC2, 0x9D, 0x9D, 0x09, 0x9B, 0x4E, 0xB5, 0x97, 0x05, 0xAC, + 0xF5, 0x06, 0xA0, 0xF7, 0x36, 0x05, 0x7E, 0xF4, 0x90, 0xB2, 0x6B, 0xC4, + 0xB4, 0xF9, 0x64, 0xEA, 0xE9, 0x1A, 0x0A, 0xC8, 0x0D, 0xA8, 0xED, 0x27, + 0xC9, 0xD4, 0xE7, 0xB3, 0xB9, 0xAB, 0x82, 0x22, 0x90, 0x27, 0x3D, 0x2A, + 0xE8, 0x7C, 0x90, 0xEF, 0xBC, 0x4F, 0xFD, 0xE2, 0x0A, 0x24, 0xA7, 0xDE, + 0x65, 0x24, 0xA4, 0x5D, 0xEA, 0xC0, 0x76, 0x30, 0xD3, 0x77, 0x50, 0xF8, + 0x0D, 0x04, 0x9B, 0x94, 0x36, 0x01, 0x73, 0xCA, 0x06, 0x58, 0xA6, 0xD3, + 0x3B, 0xDC, 0xFA, 0x04, 0x46, 0x13, 0x55, 0x8A, 0xC9, 0x44, 0x47, 0xB8, + 0x51, 0x39, 0x1A, 0x2E, 0xE8, 0x34, 0xE2, 0x79, 0xCB, 0x59, 0x4A, 0x0A, + 0x7F, 0xBC, 0xA6, 0xEF, 0x1F, 0x03, 0x67, 0x6A, 0x59, 0x2B, 0x25, 0x62, + 0x93, 0xD9, 0x53, 0x19, 0x66, 0x3C, 0x27, 0x62, 0x29, 0x86, 0x4D, 0xA4, + 0x6B, 0xEE, 0xFF, 0xD4, 0x4E, 0xBA, 0xD5, 0xB4, 0xE2, 0x8E, 0x48, 0x5A, + 0x00, 0x19, 0x09, 0xF1, 0x05, 0xD9, 0xCE, 0x91, 0xB1, 0xF7, 0xEB, 0xE9, + 0x39, 0x4F, 0xF6, 0x6F, 0x04, 0x43, 0x9A, 0x55, 0xF5, 0x3E, 0x05, 0x14, + 0xBD, 0xBF, 0xB3, 0x59, 0xB4, 0xD8, 0x8E, 0x33, 0x84, 0xA3, 0x90, 0x52, + 0xAA, 0xB3, 0x02, 0x95, 0x60, 0xF9, 0x0C, 0x4C, 0x68, 0xF9, 0xEE, 0xD5, + 0x17, 0x0D, 0xF8, 0x71, 0x57, 0xB5, 0x25, 0xE4, 0x29, 0xEE, 0x65, 0x5D, + 0xAF, 0xD1, 0xEE, 0x3C, 0x17, 0x0B, 0x5A, 0x43, 0xC5, 0xA5, 0x86, 0xEA, + 0x24, 0x9E, 0xE2, 0x05, 0x07, 0xDC, 0x34, 0x42, 0x12, 0x91, 0xD6, 0x39, + 0x74, 0xAE, 0x4C, 0x41, 0x82, 0xDB, 0xF2, 0xA6, 0x48, 0xD1, 0xB3, 0x9B, + 0xF3, 0x33, 0xAA, 0xF3, 0xA6, 0xC0, 0xC5, 0x4E, 0xF5, 0xF4, 0x9D, 0x76, + 0x63, 0xE6, 0x02, 0xC6, 0x22, 0x4B, 0xC1, 0x95, 0x3F, 0x50, 0x64, 0x2C, + 0x54, 0xE5, 0xB6, 0xF0, 0x3C, 0x29, 0xCF, 0x57 +}; + +static const unsigned char TA392_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA393_DN[] = { + 0x30, 0x42, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x09, 0x41, 0x43, 0x43, 0x56, 0x52, 0x41, 0x49, 0x5A, 0x31, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x50, 0x4B, 0x49, + 0x41, 0x43, 0x43, 0x56, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x04, 0x41, 0x43, 0x43, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53 +}; + +static const unsigned char TA393_RSA_N[] = { + 0x9B, 0xA9, 0xAB, 0xBF, 0x61, 0x4A, 0x97, 0xAF, 0x2F, 0x97, 0x66, 0x9A, + 0x74, 0x5F, 0xD0, 0xD9, 0x96, 0xFD, 0xCF, 0xE2, 0xE4, 0x66, 0xEF, 0x1F, + 0x1F, 0x47, 0x33, 0xC2, 0x44, 0xA3, 0xDF, 0x9A, 0xDE, 0x1F, 0xB5, 0x54, + 0xDD, 0x15, 0x7C, 0x69, 0x35, 0x11, 0x6F, 0xBB, 0xC8, 0x0C, 0x8E, 0x6A, + 0x18, 0x1E, 0xD8, 0x8F, 0xD9, 0x16, 0xBC, 0x10, 0x48, 0x36, 0x5C, 0xF0, + 0x63, 0xB3, 0x90, 0x5A, 0x5C, 0x24, 0x37, 0xD7, 0xA3, 0xD6, 0xCB, 0x09, + 0x71, 0xB9, 0xF1, 0x01, 0x72, 0x84, 0xB0, 0x7D, 0xDB, 0x4D, 0x80, 0xCD, + 0xFC, 0xD3, 0x6F, 0xC9, 0xF8, 0xDA, 0xB6, 0x0E, 0x82, 0xD2, 0x45, 0x85, + 0xA8, 0x1B, 0x68, 0xA8, 0x3D, 0xE8, 0xF4, 0x44, 0x6C, 0xBD, 0xA1, 0xC2, + 0xCB, 0x03, 0xBE, 0x8C, 0x3E, 0x13, 0x00, 0x84, 0xDF, 0x4A, 0x48, 0xC0, + 0xE3, 0x22, 0x0A, 0xE8, 0xE9, 0x37, 0xA7, 0x18, 0x4C, 0xB1, 0x09, 0x0D, + 0x23, 0x56, 0x7F, 0x04, 0x4D, 0xD9, 0x17, 0x84, 0x18, 0xA5, 0xC8, 0xDA, + 0x40, 0x94, 0x73, 0xEB, 0xCE, 0x0E, 0x57, 0x3C, 0x03, 0x81, 0x3A, 0x9D, + 0x0A, 0xA1, 0x57, 0x43, 0x69, 0xAC, 0x57, 0x6D, 0x79, 0x90, 0x78, 0xE5, + 0xB5, 0xB4, 0x3B, 0xD8, 0xBC, 0x4C, 0x8D, 0x28, 0xA1, 0xA7, 0xA3, 0xA7, + 0xBA, 0x02, 0x4E, 0x25, 0xD1, 0x2A, 0xAE, 0xED, 0xAE, 0x03, 0x22, 0xB8, + 0x6B, 0x20, 0x0F, 0x30, 0x28, 0x54, 0x95, 0x7F, 0xE0, 0xEE, 0xCE, 0x0A, + 0x66, 0x9D, 0xD1, 0x40, 0x2D, 0x6E, 0x22, 0xAF, 0x9D, 0x1A, 0xC1, 0x05, + 0x19, 0xD2, 0x6F, 0xC0, 0xF2, 0x9F, 0xF8, 0x7B, 0xB3, 0x02, 0x42, 0xFB, + 0x50, 0xA9, 0x1D, 0x2D, 0x93, 0x0F, 0x23, 0xAB, 0xC6, 0xC1, 0x0F, 0x92, + 0xFF, 0xD0, 0xA2, 0x15, 0xF5, 0x53, 0x09, 0x71, 0x1C, 0xFF, 0x45, 0x13, + 0x84, 0xE6, 0x26, 0x5E, 0xF8, 0xE0, 0x88, 0x1C, 0x0A, 0xFC, 0x16, 0xB6, + 0xA8, 0x73, 0x06, 0xB8, 0xF0, 0x63, 0x84, 0x02, 0xA0, 0xC6, 0x5A, 0xEC, + 0xE7, 0x74, 0xDF, 0x70, 0xAE, 0xA3, 0x83, 0x25, 0xEA, 0xD6, 0xC7, 0x97, + 0x87, 0x93, 0xA7, 0xC6, 0x8A, 0x8A, 0x33, 0x97, 0x60, 0x37, 0x10, 0x3E, + 0x97, 0x3E, 0x6E, 0x29, 0x15, 0xD6, 0xA1, 0x0F, 0xD1, 0x88, 0x2C, 0x12, + 0x9F, 0x6F, 0xAA, 0xA4, 0xC6, 0x42, 0xEB, 0x41, 0xA2, 0xE3, 0x95, 0x43, + 0xD3, 0x01, 0x85, 0x6D, 0x8E, 0xBB, 0x3B, 0xF3, 0x23, 0x36, 0xC7, 0xFE, + 0x3B, 0xE0, 0xA1, 0x25, 0x07, 0x48, 0xAB, 0xC9, 0x89, 0x74, 0xFF, 0x08, + 0x8F, 0x80, 0xBF, 0xC0, 0x96, 0x65, 0xF3, 0xEE, 0xEC, 0x4B, 0x68, 0xBD, + 0x9D, 0x88, 0xC3, 0x31, 0xB3, 0x40, 0xF1, 0xE8, 0xCF, 0xF6, 0x38, 0xBB, + 0x9C, 0xE4, 0xD1, 0x7F, 0xD4, 0xE5, 0x58, 0x9B, 0x7C, 0xFA, 0xD4, 0xF3, + 0x0E, 0x9B, 0x75, 0x91, 0xE4, 0xBA, 0x52, 0x2E, 0x19, 0x7E, 0xD1, 0xF5, + 0xCD, 0x5A, 0x19, 0xFC, 0xBA, 0x06, 0xF6, 0xFB, 0x52, 0xA8, 0x4B, 0x99, + 0x04, 0xDD, 0xF8, 0xF9, 0xB4, 0x8B, 0x50, 0xA3, 0x4E, 0x62, 0x89, 0xF0, + 0x87, 0x24, 0xFA, 0x83, 0x42, 0xC1, 0x87, 0xFA, 0xD5, 0x2D, 0x29, 0x2A, + 0x5A, 0x71, 0x7A, 0x64, 0x6A, 0xD7, 0x27, 0x60, 0x63, 0x0D, 0xDB, 0xCE, + 0x49, 0xF5, 0x8D, 0x1F, 0x90, 0x89, 0x32, 0x17, 0xF8, 0x73, 0x43, 0xB8, + 0xD2, 0x5A, 0x93, 0x86, 0x61, 0xD6, 0xE1, 0x75, 0x0A, 0xEA, 0x79, 0x66, + 0x76, 0x88, 0x4F, 0x71, 0xEB, 0x04, 0x25, 0xD6, 0x0A, 0x5A, 0x7A, 0x93, + 0xE5, 0xB9, 0x4B, 0x17, 0x40, 0x0F, 0xB1, 0xB6, 0xB9, 0xF5, 0xDE, 0x4F, + 0xDC, 0xE0, 0xB3, 0xAC, 0x3B, 0x11, 0x70, 0x60, 0x84, 0x4A, 0x43, 0x6E, + 0x99, 0x20, 0xC0, 0x29, 0x71, 0x0A, 0xC0, 0x65 +}; + +static const unsigned char TA393_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA394_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x41, 0x43, 0x20, + 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, + 0x4D +}; + +static const unsigned char TA394_RSA_N[] = { + 0xBA, 0x71, 0x80, 0x7A, 0x4C, 0x86, 0x6E, 0x7F, 0xC8, 0x13, 0x6D, 0xC0, + 0xC6, 0x7D, 0x1C, 0x00, 0x97, 0x8F, 0x2C, 0x0C, 0x23, 0xBB, 0x10, 0x9A, + 0x40, 0xA9, 0x1A, 0xB7, 0x87, 0x88, 0xF8, 0x9B, 0x56, 0x6A, 0xFB, 0xE6, + 0x7B, 0x8E, 0x8B, 0x92, 0x8E, 0xA7, 0x25, 0x5D, 0x59, 0x11, 0xDB, 0x36, + 0x2E, 0xB7, 0x51, 0x17, 0x1F, 0xA9, 0x08, 0x1F, 0x04, 0x17, 0x24, 0x58, + 0xAA, 0x37, 0x4A, 0x18, 0xDF, 0xE5, 0x39, 0xD4, 0x57, 0xFD, 0xD7, 0xC1, + 0x2C, 0x91, 0x01, 0x91, 0xE2, 0x22, 0xD4, 0x03, 0xC0, 0x58, 0xFC, 0x77, + 0x47, 0xEC, 0x8F, 0x3E, 0x74, 0x43, 0xBA, 0xAC, 0x34, 0x8D, 0x4D, 0x38, + 0x76, 0x67, 0x8E, 0xB0, 0xC8, 0x6F, 0x30, 0x33, 0x58, 0x71, 0x5C, 0xB4, + 0xF5, 0x6B, 0x6E, 0xD4, 0x01, 0x50, 0xB8, 0x13, 0x7E, 0x6C, 0x4A, 0xA3, + 0x49, 0xD1, 0x20, 0x19, 0xEE, 0xBC, 0xC0, 0x29, 0x18, 0x65, 0xA7, 0xDE, + 0xFE, 0xEF, 0xDD, 0x0A, 0x90, 0x21, 0xE7, 0x1A, 0x67, 0x92, 0x42, 0x10, + 0x98, 0x5F, 0x4F, 0x30, 0xBC, 0x3E, 0x1C, 0x45, 0xB4, 0x10, 0xD7, 0x68, + 0x40, 0x14, 0xC0, 0x40, 0xFA, 0xE7, 0x77, 0x17, 0x7A, 0xE6, 0x0B, 0x8F, + 0x65, 0x5B, 0x3C, 0xD9, 0x9A, 0x52, 0xDB, 0xB5, 0xBD, 0x9E, 0x46, 0xCF, + 0x3D, 0xEB, 0x91, 0x05, 0x02, 0xC0, 0x96, 0xB2, 0x76, 0x4C, 0x4D, 0x10, + 0x96, 0x3B, 0x92, 0xFA, 0x9C, 0x7F, 0x0F, 0x99, 0xDF, 0xBE, 0x23, 0x35, + 0x45, 0x1E, 0x02, 0x5C, 0xFE, 0xB5, 0xA8, 0x9B, 0x99, 0x25, 0xDA, 0x5E, + 0xF3, 0x22, 0xC3, 0x39, 0xF5, 0xE4, 0x2A, 0x2E, 0xD3, 0xC6, 0x1F, 0xC4, + 0x6C, 0xAA, 0xC5, 0x1C, 0x6A, 0x01, 0x05, 0x4A, 0x2F, 0xD2, 0xC5, 0xC1, + 0xA8, 0x34, 0x26, 0x5D, 0x66, 0xA5, 0xD2, 0x02, 0x21, 0xF9, 0x18, 0xB7, + 0x06, 0xF5, 0x4E, 0x99, 0x6F, 0xA8, 0xAB, 0x4C, 0x51, 0xE8, 0xCF, 0x50, + 0x18, 0xC5, 0x77, 0xC8, 0x39, 0x09, 0x2C, 0x49, 0x92, 0x32, 0x99, 0xA8, + 0xBB, 0x17, 0x17, 0x79, 0xB0, 0x5A, 0xC5, 0xE6, 0xA3, 0xC4, 0x59, 0x65, + 0x47, 0x35, 0x83, 0x5E, 0xA9, 0xE8, 0x35, 0x0B, 0x99, 0xBB, 0xE4, 0xCD, + 0x20, 0xC6, 0x9B, 0x4A, 0x06, 0x39, 0xB5, 0x68, 0xFC, 0x22, 0xBA, 0xEE, + 0x55, 0x8C, 0x2B, 0x4E, 0xEA, 0xF3, 0xB1, 0xE3, 0xFC, 0xB6, 0x99, 0x9A, + 0xD5, 0x42, 0xFA, 0x71, 0x4D, 0x08, 0xCF, 0x87, 0x1E, 0x6A, 0x71, 0x7D, + 0xF9, 0xD3, 0xB4, 0xE9, 0xA5, 0x71, 0x81, 0x7B, 0xC2, 0x4E, 0x47, 0x96, + 0xA5, 0xF6, 0x76, 0x85, 0xA3, 0x28, 0x8F, 0xE9, 0x80, 0x6E, 0x81, 0x53, + 0xA5, 0x6D, 0x5F, 0xB8, 0x48, 0xF9, 0xC2, 0xF9, 0x36, 0xA6, 0x2E, 0x49, + 0xFF, 0xB8, 0x96, 0xC2, 0x8C, 0x07, 0xB3, 0x9B, 0x88, 0x58, 0xFC, 0xEB, + 0x1B, 0x1C, 0xDE, 0x2D, 0x70, 0xE2, 0x97, 0x92, 0x30, 0xA1, 0x89, 0xE3, + 0xBC, 0x55, 0xA8, 0x27, 0xD6, 0x4B, 0xED, 0x90, 0xAD, 0x8B, 0xFA, 0x63, + 0x25, 0x59, 0x2D, 0xA8, 0x35, 0xDD, 0xCA, 0x97, 0x33, 0xBC, 0xE5, 0xCD, + 0xC7, 0x9D, 0xD1, 0xEC, 0xEF, 0x5E, 0x0E, 0x4A, 0x90, 0x06, 0x26, 0x63, + 0xAD, 0xB9, 0xD9, 0x35, 0x2D, 0x07, 0xBA, 0x76, 0x65, 0x2C, 0xAC, 0x57, + 0x8F, 0x7D, 0xF4, 0x07, 0x94, 0xD7, 0x81, 0x02, 0x96, 0x5D, 0xA3, 0x07, + 0x49, 0xD5, 0x7A, 0xD0, 0x57, 0xF9, 0x1B, 0xE7, 0x53, 0x46, 0x75, 0xAA, + 0xB0, 0x79, 0x42, 0xCB, 0x68, 0x71, 0x08, 0xE9, 0x60, 0xBD, 0x39, 0x69, + 0xCE, 0xF4, 0xAF, 0xC3, 0x56, 0x40, 0xC7, 0xAD, 0x52, 0xA2, 0x09, 0xE4, + 0x6F, 0x86, 0x47, 0x8A, 0x1F, 0xEB, 0x28, 0x27, 0x5D, 0x83, 0x20, 0xAF, + 0x04, 0xC9, 0x6C, 0x56, 0x9A, 0x8B, 0x46, 0xF5 +}; + +static const unsigned char TA394_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA395_DN[] = { + 0x30, 0x78, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x0E, + 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x05, 0x43, 0x65, 0x72, + 0x65, 0x73, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, + 0x0F, 0x56, 0x41, 0x54, 0x45, 0x53, 0x2D, 0x51, 0x32, 0x38, 0x32, 0x36, + 0x30, 0x30, 0x34, 0x4A, 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x23, 0x41, 0x43, 0x20, 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, + 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x20, 0x53, 0x45, 0x52, 0x56, + 0x49, 0x44, 0x4F, 0x52, 0x45, 0x53, 0x20, 0x53, 0x45, 0x47, 0x55, 0x52, + 0x4F, 0x53 +}; + +static const unsigned char TA395_EC_Q[] = { + 0x04, 0xF6, 0xBA, 0x57, 0x53, 0xC8, 0xCA, 0xAB, 0xDF, 0x36, 0x4A, 0x52, + 0x21, 0xE4, 0x97, 0xD2, 0x83, 0x67, 0x9E, 0xF0, 0x65, 0x51, 0xD0, 0x5E, + 0x87, 0xC7, 0x47, 0xB1, 0x59, 0xF2, 0x57, 0x47, 0x9B, 0x00, 0x02, 0x93, + 0x44, 0x17, 0x69, 0xDB, 0x42, 0xC7, 0xB1, 0xB2, 0x3A, 0x18, 0x0E, 0xB4, + 0x5D, 0x8C, 0xB3, 0x66, 0x5D, 0xA1, 0x34, 0xF9, 0x36, 0x2C, 0x49, 0xDB, + 0xF3, 0x46, 0xFC, 0xB3, 0x44, 0x69, 0x44, 0x13, 0x66, 0xFD, 0xD7, 0xC5, + 0xFD, 0xAF, 0x36, 0x4D, 0xCE, 0x03, 0x4D, 0x07, 0x71, 0xCF, 0xAF, 0x6A, + 0x05, 0xD2, 0xA2, 0x43, 0x5A, 0x0A, 0x52, 0x6F, 0x01, 0x03, 0x4E, 0x8E, + 0x8B +}; + +static const unsigned char TA396_DN[] = { + 0x30, 0x81, 0x84, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x05, + 0x13, 0x09, 0x47, 0x36, 0x33, 0x32, 0x38, 0x37, 0x35, 0x31, 0x30, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, + 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1E, 0x41, + 0x4E, 0x46, 0x20, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, + 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x63, 0x69, 0x6F, 0x6E, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x04, 0x0B, 0x13, 0x0B, 0x41, 0x4E, 0x46, 0x20, 0x43, 0x41, 0x20, 0x52, + 0x61, 0x69, 0x7A, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x19, 0x41, 0x4E, 0x46, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA396_RSA_N[] = { + 0xDB, 0xEB, 0x6B, 0x2B, 0xE6, 0x64, 0x54, 0x95, 0x82, 0x90, 0xA3, 0x72, + 0xA4, 0x19, 0x01, 0x9D, 0x9C, 0x0B, 0x81, 0x5F, 0x73, 0x49, 0xBA, 0xA7, + 0xAC, 0xF3, 0x04, 0x4E, 0x7B, 0x96, 0x0B, 0xEC, 0x11, 0xE0, 0x5B, 0xA6, + 0x1C, 0xCE, 0x1B, 0xD2, 0x0D, 0x83, 0x1C, 0x2B, 0xB8, 0x9E, 0x1D, 0x7E, + 0x45, 0x32, 0x60, 0x0F, 0x07, 0xE9, 0x77, 0x58, 0x7E, 0x9F, 0x6A, 0xC8, + 0x61, 0x4E, 0xB6, 0x26, 0xC1, 0x4C, 0x8D, 0xFF, 0x4C, 0xEF, 0x34, 0xB2, + 0x1F, 0x65, 0xD8, 0xB9, 0x78, 0xF5, 0xAD, 0xA9, 0x71, 0xB9, 0xEF, 0x4F, + 0x58, 0x1D, 0xA5, 0xDE, 0x74, 0x20, 0x97, 0xA1, 0xED, 0x68, 0x4C, 0xDE, + 0x92, 0x17, 0x4B, 0xBC, 0xAB, 0xFF, 0x65, 0x9A, 0x9E, 0xFB, 0x47, 0xD9, + 0x57, 0x72, 0xF3, 0x09, 0xA1, 0xAE, 0x76, 0x44, 0x13, 0x6E, 0x9C, 0x2D, + 0x44, 0x39, 0xBC, 0xF9, 0xC7, 0x3B, 0xA4, 0x58, 0x3D, 0x41, 0xBD, 0xB4, + 0xC2, 0x49, 0xA3, 0xC8, 0x0D, 0xD2, 0x97, 0x2F, 0x07, 0x65, 0x52, 0x00, + 0xA7, 0x6E, 0xC8, 0xAF, 0x68, 0xEC, 0xF4, 0x14, 0x96, 0xB6, 0x57, 0x1F, + 0x56, 0xC3, 0x39, 0x9F, 0x2B, 0x6D, 0xE4, 0xF3, 0x3E, 0xF6, 0x35, 0x64, + 0xDA, 0x0C, 0x1C, 0xA1, 0x84, 0x4B, 0x2F, 0x4B, 0x4B, 0xE2, 0x2C, 0x24, + 0x9D, 0x6D, 0x93, 0x40, 0xEB, 0xB5, 0x23, 0x8E, 0x32, 0xCA, 0x6F, 0x45, + 0xD3, 0xA8, 0x89, 0x7B, 0x1E, 0xCF, 0x1E, 0xFA, 0x5B, 0x43, 0x8B, 0xCD, + 0xCD, 0xA8, 0x0F, 0x6A, 0xCA, 0x0C, 0x5E, 0xB9, 0x9E, 0x47, 0x8F, 0xF0, + 0xD9, 0xB6, 0x0A, 0x0B, 0x58, 0x65, 0x17, 0x33, 0xB9, 0x23, 0xE4, 0x77, + 0x19, 0x7D, 0xCB, 0x4A, 0x2E, 0x92, 0x7B, 0x4F, 0x2F, 0x10, 0x77, 0xB1, + 0x8D, 0x2F, 0x68, 0x9C, 0x62, 0xCC, 0xE0, 0x50, 0xF8, 0xEC, 0x91, 0xA7, + 0x54, 0x4C, 0x57, 0x09, 0xD5, 0x76, 0x63, 0xC5, 0xE8, 0x65, 0x1E, 0xEE, + 0x6D, 0x6A, 0xCF, 0x09, 0x9D, 0xFA, 0x7C, 0x4F, 0xAD, 0x60, 0x08, 0xFD, + 0x56, 0x99, 0x0F, 0x15, 0x2C, 0x7B, 0xA9, 0x80, 0xAB, 0x8C, 0x61, 0x8F, + 0x4A, 0x07, 0x76, 0x42, 0xDE, 0x3D, 0xF4, 0xDD, 0xB2, 0x24, 0x33, 0x5B, + 0xB8, 0xB5, 0xA3, 0x44, 0xC9, 0xAC, 0x7F, 0x77, 0x3C, 0x1D, 0x23, 0xEC, + 0x82, 0xA9, 0xA6, 0xE2, 0xC8, 0x06, 0x4C, 0x02, 0xFE, 0xAC, 0x5C, 0x99, + 0x99, 0x0B, 0x2F, 0x10, 0x8A, 0xA6, 0xF4, 0x7F, 0xD5, 0x87, 0x74, 0x0D, + 0x59, 0x49, 0x45, 0xF6, 0xF0, 0x71, 0x5C, 0x39, 0x29, 0xD6, 0xBF, 0x4A, + 0x23, 0x8B, 0xF5, 0x5F, 0x01, 0x63, 0xD2, 0x87, 0x73, 0x28, 0xB5, 0x4B, + 0x0A, 0xF5, 0xF8, 0xAB, 0x82, 0x2C, 0x7E, 0x73, 0x25, 0x32, 0x1D, 0x0B, + 0x63, 0x0A, 0x17, 0x81, 0x00, 0xFF, 0xB6, 0x76, 0x5E, 0xE7, 0xB4, 0xB1, + 0x40, 0xCA, 0x21, 0xBB, 0xD5, 0x80, 0x51, 0xE5, 0x48, 0x52, 0x67, 0x2C, + 0xD2, 0x61, 0x89, 0x07, 0x0D, 0x0F, 0xCE, 0x42, 0x77, 0xC0, 0x44, 0x73, + 0x9C, 0x44, 0x50, 0xA0, 0xDB, 0x10, 0x0A, 0x2D, 0x95, 0x1C, 0x81, 0xAF, + 0xE4, 0x1C, 0xE5, 0x14, 0x1E, 0xF1, 0x36, 0x41, 0x01, 0x02, 0x2F, 0x7D, + 0x73, 0xA7, 0xDE, 0x42, 0xCC, 0x4C, 0xE9, 0x89, 0x0D, 0x56, 0xF7, 0x9F, + 0x91, 0xD4, 0x03, 0xC6, 0x6C, 0xC9, 0x8F, 0xDB, 0xD8, 0x1C, 0xE0, 0x40, + 0x98, 0x5D, 0x66, 0x99, 0x98, 0x80, 0x6E, 0x2D, 0xFF, 0x01, 0xC5, 0xCE, + 0xCB, 0x46, 0x1F, 0xAC, 0x02, 0xC6, 0x43, 0xE6, 0xAE, 0xA2, 0x84, 0x3C, + 0xC5, 0x4E, 0x1E, 0x3D, 0x6D, 0xC9, 0x14, 0x4C, 0xE3, 0x2E, 0x41, 0xBB, + 0xCA, 0x39, 0xBF, 0x36, 0x3C, 0x2A, 0x19, 0xAA, 0x41, 0x87, 0x4E, 0xA5, + 0xCE, 0x4B, 0x32, 0x79, 0xDD, 0x90, 0x49, 0x7F +}; + +static const unsigned char TA396_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA397_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x54, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x05, 0x4D, 0x69, 0x6C, 0x61, 0x6E, 0x31, 0x23, 0x30, 0x21, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x1A, 0x41, 0x63, 0x74, 0x61, 0x6C, 0x69, + 0x73, 0x20, 0x53, 0x2E, 0x70, 0x2E, 0x41, 0x2E, 0x2F, 0x30, 0x33, 0x33, + 0x35, 0x38, 0x35, 0x32, 0x30, 0x39, 0x36, 0x37, 0x31, 0x27, 0x30, 0x25, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x41, 0x63, 0x74, 0x61, 0x6C, + 0x69, 0x73, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA397_RSA_N[] = { + 0xA7, 0xC6, 0xC4, 0xA5, 0x29, 0xA4, 0x2C, 0xEF, 0xE5, 0x18, 0xC5, 0xB0, + 0x50, 0xA3, 0x6F, 0x51, 0x3B, 0x9F, 0x0A, 0x5A, 0xC9, 0xC2, 0x48, 0x38, + 0x0A, 0xC2, 0x1C, 0xA0, 0x18, 0x7F, 0x91, 0xB5, 0x87, 0xB9, 0x40, 0x3F, + 0xDD, 0x1D, 0x68, 0x1F, 0x08, 0x83, 0xD5, 0x2D, 0x1E, 0x88, 0xA0, 0xF8, + 0x8F, 0x56, 0x8F, 0x6D, 0x99, 0x02, 0x92, 0x90, 0x16, 0xD5, 0x5F, 0x08, + 0x6C, 0x89, 0xD7, 0xE1, 0xAC, 0xBC, 0x20, 0xC2, 0xB1, 0xE0, 0x83, 0x51, + 0x8A, 0x69, 0x4D, 0x00, 0x96, 0x5A, 0x6F, 0x2F, 0xC0, 0x44, 0x7E, 0xA3, + 0x0E, 0xE4, 0x91, 0xCD, 0x58, 0xEE, 0xDC, 0xFB, 0xC7, 0x1E, 0x45, 0x47, + 0xDD, 0x27, 0xB9, 0x08, 0x01, 0x9F, 0xA6, 0x21, 0x1D, 0xF5, 0x41, 0x2D, + 0x2F, 0x4C, 0xFD, 0x28, 0xAD, 0xE0, 0x8A, 0xAD, 0x22, 0xB4, 0x56, 0x65, + 0x8E, 0x86, 0x54, 0x8F, 0x93, 0x43, 0x29, 0xDE, 0x39, 0x46, 0x78, 0xA3, + 0x30, 0x23, 0xBA, 0xCD, 0xF0, 0x7D, 0x13, 0x57, 0xC0, 0x5D, 0xD2, 0x83, + 0x6B, 0x48, 0x4C, 0xC4, 0xAB, 0x9F, 0x80, 0x5A, 0x5B, 0x3A, 0xBD, 0xC9, + 0xA7, 0x22, 0x3F, 0x80, 0x27, 0x33, 0x5B, 0x0E, 0xB7, 0x8A, 0x0C, 0x5D, + 0x07, 0x37, 0x08, 0xCB, 0x6C, 0xD2, 0x7A, 0x47, 0x22, 0x44, 0x35, 0xC5, + 0xCC, 0xCC, 0x2E, 0x8E, 0xDD, 0x2A, 0xED, 0xB7, 0x7D, 0x66, 0x0D, 0x5F, + 0x61, 0x51, 0x22, 0x55, 0x1B, 0xE3, 0x46, 0xE3, 0xE3, 0x3D, 0xD0, 0x35, + 0x62, 0x9A, 0xDB, 0xAF, 0x14, 0xC8, 0x5B, 0xA1, 0xCC, 0x89, 0x1B, 0xE1, + 0x30, 0x26, 0xFC, 0xA0, 0x9B, 0x1F, 0x81, 0xA7, 0x47, 0x1F, 0x04, 0xEB, + 0xA3, 0x39, 0x92, 0x06, 0x9F, 0x99, 0xD3, 0xBF, 0xD3, 0xEA, 0x4F, 0x50, + 0x9C, 0x19, 0xFE, 0x96, 0x87, 0x1E, 0x3C, 0x65, 0xF6, 0xA3, 0x18, 0x24, + 0x83, 0x86, 0x10, 0xE7, 0x54, 0x3E, 0xA8, 0x3A, 0x76, 0x24, 0x4F, 0x81, + 0x21, 0xC5, 0xE3, 0x0F, 0x02, 0xF8, 0x93, 0x94, 0x47, 0x20, 0xBB, 0xFE, + 0xD4, 0x0E, 0xD3, 0x68, 0xB9, 0xDD, 0xC4, 0x7A, 0x84, 0x82, 0xE3, 0x53, + 0x54, 0x79, 0xDD, 0xDB, 0x9C, 0xD2, 0xF2, 0x07, 0x9B, 0x2E, 0xB6, 0xBC, + 0x3E, 0xED, 0x85, 0x6D, 0xEF, 0x25, 0x11, 0xF2, 0x97, 0x1A, 0x42, 0x61, + 0xF7, 0x4A, 0x97, 0xE8, 0x8B, 0xB1, 0x10, 0x07, 0xFA, 0x65, 0x81, 0xB2, + 0xA2, 0x39, 0xCF, 0xF7, 0x3C, 0xFF, 0x18, 0xFB, 0xC6, 0xF1, 0x5A, 0x8B, + 0x59, 0xE2, 0x02, 0xAC, 0x7B, 0x92, 0xD0, 0x4E, 0x14, 0x4F, 0x59, 0x45, + 0xF6, 0x0C, 0x5E, 0x28, 0x5F, 0xB0, 0xE8, 0x3F, 0x45, 0xCF, 0xCF, 0xAF, + 0x9B, 0x6F, 0xFB, 0x84, 0xD3, 0x77, 0x5A, 0x95, 0x6F, 0xAC, 0x94, 0x84, + 0x9E, 0xEE, 0xBC, 0xC0, 0x4A, 0x8F, 0x4A, 0x93, 0xF8, 0x44, 0x21, 0xE2, + 0x31, 0x45, 0x61, 0x50, 0x4E, 0x10, 0xD8, 0xE3, 0x35, 0x7C, 0x4C, 0x19, + 0xB4, 0xDE, 0x05, 0xBF, 0xA3, 0x06, 0x9F, 0xC8, 0xB5, 0xCD, 0xE4, 0x1F, + 0xD7, 0x17, 0x06, 0x0D, 0x7A, 0x95, 0x74, 0x55, 0x0D, 0x68, 0x1A, 0xFC, + 0x10, 0x1B, 0x62, 0x64, 0x9D, 0x6D, 0xE0, 0x95, 0xA0, 0xC3, 0x94, 0x07, + 0x57, 0x0D, 0x14, 0xE6, 0xBD, 0x05, 0xFB, 0xB8, 0x9F, 0xE6, 0xDF, 0x8B, + 0xE2, 0xC6, 0xE7, 0x7E, 0x96, 0xF6, 0x53, 0xC5, 0x80, 0x34, 0x50, 0x28, + 0x58, 0xF0, 0x12, 0x50, 0x71, 0x17, 0x30, 0xBA, 0xE6, 0x78, 0x63, 0xBC, + 0xF4, 0xB2, 0xAD, 0x9B, 0x2B, 0xB2, 0xFE, 0xE1, 0x39, 0x8C, 0x5E, 0xBA, + 0x0B, 0x20, 0x94, 0xDE, 0x7B, 0x83, 0xB8, 0xFF, 0xE3, 0x56, 0x8D, 0xB7, + 0x11, 0xE9, 0x3B, 0x8C, 0xF2, 0xB1, 0xC1, 0x5D, 0x9D, 0xA4, 0x0B, 0x4C, + 0x2B, 0xD9, 0xB2, 0x18, 0xF5, 0xB5, 0x9F, 0x4B +}; + +static const unsigned char TA397_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA398_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C +}; + +static const unsigned char TA398_RSA_N[] = { + 0xF6, 0x1B, 0x4F, 0x67, 0x07, 0x2B, 0xA1, 0x15, 0xF5, 0x06, 0x22, 0xCB, + 0x1F, 0x01, 0xB2, 0xE3, 0x73, 0x45, 0x06, 0x44, 0x49, 0x2C, 0xBB, 0x49, + 0x25, 0x14, 0xD6, 0xCE, 0xC3, 0xB7, 0xAB, 0x2C, 0x4F, 0xC6, 0x41, 0x32, + 0x94, 0x57, 0xFA, 0x12, 0xA7, 0x5B, 0x0E, 0xE2, 0x8F, 0x1F, 0x1E, 0x86, + 0x19, 0xA7, 0xAA, 0xB5, 0x2D, 0xB9, 0x5F, 0x0D, 0x8A, 0xC2, 0xAF, 0x85, + 0x35, 0x79, 0x32, 0x2D, 0xBB, 0x1C, 0x62, 0x37, 0xF2, 0xB1, 0x5B, 0x4A, + 0x3D, 0xCA, 0xCD, 0x71, 0x5F, 0xE9, 0x42, 0xBE, 0x94, 0xE8, 0xC8, 0xDE, + 0xF9, 0x22, 0x48, 0x64, 0xC6, 0xE5, 0xAB, 0xC6, 0x2B, 0x6D, 0xAD, 0x05, + 0xF0, 0xFA, 0xD5, 0x0B, 0xCF, 0x9A, 0xE5, 0xF0, 0x50, 0xA4, 0x8B, 0x3B, + 0x47, 0xA5, 0x23, 0x5B, 0x7A, 0x7A, 0xF8, 0x33, 0x3F, 0xB8, 0xEF, 0x99, + 0x97, 0xE3, 0x20, 0xC1, 0xD6, 0x28, 0x89, 0xCF, 0x94, 0xFB, 0xB9, 0x45, + 0xED, 0xE3, 0x40, 0x17, 0x11, 0xD4, 0x74, 0xF0, 0x0B, 0x31, 0xE2, 0x2B, + 0x26, 0x6A, 0x9B, 0x4C, 0x57, 0xAE, 0xAC, 0x20, 0x3E, 0xBA, 0x45, 0x7A, + 0x05, 0xF3, 0xBD, 0x9B, 0x69, 0x15, 0xAE, 0x7D, 0x4E, 0x20, 0x63, 0xC4, + 0x35, 0x76, 0x3A, 0x07, 0x02, 0xC9, 0x37, 0xFD, 0xC7, 0x47, 0xEE, 0xE8, + 0xF1, 0x76, 0x1D, 0x73, 0x15, 0xF2, 0x97, 0xA4, 0xB5, 0xC8, 0x7A, 0x79, + 0xD9, 0x42, 0xAA, 0x2B, 0x7F, 0x5C, 0xFE, 0xCE, 0x26, 0x4F, 0xA3, 0x66, + 0x81, 0x35, 0xAF, 0x44, 0xBA, 0x54, 0x1E, 0x1C, 0x30, 0x32, 0x65, 0x9D, + 0xE6, 0x3C, 0x93, 0x5E, 0x50, 0x4E, 0x7A, 0xE3, 0x3A, 0xD4, 0x6E, 0xCC, + 0x1A, 0xFB, 0xF9, 0xD2, 0x37, 0xAE, 0x24, 0x2A, 0xAB, 0x57, 0x03, 0x22, + 0x28, 0x0D, 0x49, 0x75, 0x7F, 0xB7, 0x28, 0xDA, 0x75, 0xBF, 0x8E, 0xE3, + 0xDC, 0x0E, 0x79, 0x31 +}; + +static const unsigned char TA398_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA399_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x69, 0x6E, 0x67 +}; + +static const unsigned char TA399_RSA_N[] = { + 0xB4, 0x84, 0xCC, 0x33, 0x17, 0x2E, 0x6B, 0x94, 0x6C, 0x6B, 0x61, 0x52, + 0xA0, 0xEB, 0xA3, 0xCF, 0x79, 0x94, 0x4C, 0xE5, 0x94, 0x80, 0x99, 0xCB, + 0x55, 0x64, 0x44, 0x65, 0x8F, 0x67, 0x64, 0xE2, 0x06, 0xE3, 0x5C, 0x37, + 0x49, 0xF6, 0x2F, 0x9B, 0x84, 0x84, 0x1E, 0x2D, 0xF2, 0x60, 0x9D, 0x30, + 0x4E, 0xCC, 0x84, 0x85, 0xE2, 0x2C, 0xCF, 0x1E, 0x9E, 0xFE, 0x36, 0xAB, + 0x33, 0x77, 0x35, 0x44, 0xD8, 0x35, 0x96, 0x1A, 0x3D, 0x36, 0xE8, 0x7A, + 0x0E, 0xD8, 0xD5, 0x47, 0xA1, 0x6A, 0x69, 0x8B, 0xD9, 0xFC, 0xBB, 0x3A, + 0xAE, 0x79, 0x5A, 0xD5, 0xF4, 0xD6, 0x71, 0xBB, 0x9A, 0x90, 0x23, 0x6B, + 0x9A, 0xB7, 0x88, 0x74, 0x87, 0x0C, 0x1E, 0x5F, 0xB9, 0x9E, 0x2D, 0xFA, + 0xAB, 0x53, 0x2B, 0xDC, 0xBB, 0x76, 0x3E, 0x93, 0x4C, 0x08, 0x08, 0x8C, + 0x1E, 0xA2, 0x23, 0x1C, 0xD4, 0x6A, 0xAD, 0x22, 0xBA, 0x99, 0x01, 0x2E, + 0x6D, 0x65, 0xCB, 0xBE, 0x24, 0x66, 0x55, 0x24, 0x4B, 0x40, 0x44, 0xB1, + 0x1B, 0xD7, 0xE1, 0xC2, 0x85, 0xC0, 0xDE, 0x10, 0x3F, 0x3D, 0xED, 0xB8, + 0xFC, 0xF1, 0xF1, 0x23, 0x53, 0xDC, 0xBF, 0x65, 0x97, 0x6F, 0xD9, 0xF9, + 0x40, 0x71, 0x8D, 0x7D, 0xBD, 0x95, 0xD4, 0xCE, 0xBE, 0xA0, 0x5E, 0x27, + 0x23, 0xDE, 0xFD, 0xA6, 0xD0, 0x26, 0x0E, 0x00, 0x29, 0xEB, 0x3C, 0x46, + 0xF0, 0x3D, 0x60, 0xBF, 0x3F, 0x50, 0xD2, 0xDC, 0x26, 0x41, 0x51, 0x9E, + 0x14, 0x37, 0x42, 0x04, 0xA3, 0x70, 0x57, 0xA8, 0x1B, 0x87, 0xED, 0x2D, + 0xFA, 0x7B, 0xEE, 0x8C, 0x0A, 0xE3, 0xA9, 0x66, 0x89, 0x19, 0xCB, 0x41, + 0xF9, 0xDD, 0x44, 0x36, 0x61, 0xCF, 0xE2, 0x77, 0x46, 0xC8, 0x7D, 0xF6, + 0xF4, 0x92, 0x81, 0x36, 0xFD, 0xDB, 0x34, 0xF1, 0x72, 0x7E, 0xF3, 0x0C, + 0x16, 0xBD, 0xB4, 0x15 +}; + +static const unsigned char TA399_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA400_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x13, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D +}; + +static const unsigned char TA400_RSA_N[] = { + 0xC4, 0x12, 0xDF, 0xA9, 0x5F, 0xFE, 0x41, 0xDD, 0xDD, 0xF5, 0x9F, 0x8A, + 0xE3, 0xF6, 0xAC, 0xE1, 0x3C, 0x78, 0x9A, 0xBC, 0xD8, 0xF0, 0x7F, 0x7A, + 0xA0, 0x33, 0x2A, 0xDC, 0x8D, 0x20, 0x5B, 0xAE, 0x2D, 0x6F, 0xE7, 0x93, + 0xD9, 0x36, 0x70, 0x6A, 0x68, 0xCF, 0x8E, 0x51, 0xA3, 0x85, 0x5B, 0x67, + 0x04, 0xA0, 0x10, 0x24, 0x6F, 0x5D, 0x28, 0x82, 0xC1, 0x97, 0x57, 0xD8, + 0x48, 0x29, 0x13, 0xB6, 0xE1, 0xBE, 0x91, 0x4D, 0xDF, 0x85, 0x0C, 0x53, + 0x18, 0x9A, 0x1E, 0x24, 0xA2, 0x4F, 0x8F, 0xF0, 0xA2, 0x85, 0x0B, 0xCB, + 0xF4, 0x29, 0x7F, 0xD2, 0xA4, 0x58, 0xEE, 0x26, 0x4D, 0xC9, 0xAA, 0xA8, + 0x7B, 0x9A, 0xD9, 0xFA, 0x38, 0xDE, 0x44, 0x57, 0x15, 0xE5, 0xF8, 0x8C, + 0xC8, 0xD9, 0x48, 0xE2, 0x0D, 0x16, 0x27, 0x1D, 0x1E, 0xC8, 0x83, 0x85, + 0x25, 0xB7, 0xBA, 0xAA, 0x55, 0x41, 0xCC, 0x03, 0x22, 0x4B, 0x2D, 0x91, + 0x8D, 0x8B, 0xE6, 0x89, 0xAF, 0x66, 0xC7, 0xE9, 0xFF, 0x2B, 0xE9, 0x3C, + 0xAC, 0xDA, 0xD2, 0xB3, 0xC3, 0xE1, 0x68, 0x9C, 0x89, 0xF8, 0x7A, 0x00, + 0x56, 0xDE, 0xF4, 0x55, 0x95, 0x6C, 0xFB, 0xBA, 0x64, 0xDD, 0x62, 0x8B, + 0xDF, 0x0B, 0x77, 0x32, 0xEB, 0x62, 0xCC, 0x26, 0x9A, 0x9B, 0xBB, 0xAA, + 0x62, 0x83, 0x4C, 0xB4, 0x06, 0x7A, 0x30, 0xC8, 0x29, 0xBF, 0xED, 0x06, + 0x4D, 0x97, 0xB9, 0x1C, 0xC4, 0x31, 0x2B, 0xD5, 0x5F, 0xBC, 0x53, 0x12, + 0x17, 0x9C, 0x99, 0x57, 0x29, 0x66, 0x77, 0x61, 0x21, 0x31, 0x07, 0x2E, + 0x25, 0x49, 0x9D, 0x18, 0xF2, 0xEE, 0xF3, 0x2B, 0x71, 0x8C, 0xB5, 0xBA, + 0x39, 0x07, 0x49, 0x77, 0xFC, 0xEF, 0x2E, 0x92, 0x90, 0x05, 0x8D, 0x2D, + 0x2F, 0x77, 0x7B, 0xEF, 0x43, 0xBF, 0x35, 0xBB, 0x9A, 0xD8, 0xF9, 0x73, + 0xA7, 0x2C, 0xF2, 0xD0, 0x57, 0xEE, 0x28, 0x4E, 0x26, 0x5F, 0x8F, 0x90, + 0x68, 0x09, 0x2F, 0xB8, 0xF8, 0xDC, 0x06, 0xE9, 0x2E, 0x9A, 0x3E, 0x51, + 0xA7, 0xD1, 0x22, 0xC4, 0x0A, 0xA7, 0x38, 0x48, 0x6C, 0xB3, 0xF9, 0xFF, + 0x7D, 0xAB, 0x86, 0x57, 0xE3, 0xBA, 0xD6, 0x85, 0x78, 0x77, 0xBA, 0x43, + 0xEA, 0x48, 0x7F, 0xF6, 0xD8, 0xBE, 0x23, 0x6D, 0x1E, 0xBF, 0xD1, 0x36, + 0x6C, 0x58, 0x5C, 0xF1, 0xEE, 0xA4, 0x19, 0x54, 0x1A, 0xF5, 0x03, 0xD2, + 0x76, 0xE6, 0xE1, 0x8C, 0xBD, 0x3C, 0xB3, 0xD3, 0x48, 0x4B, 0xE2, 0xC8, + 0xF8, 0x7F, 0x92, 0xA8, 0x76, 0x46, 0x9C, 0x42, 0x65, 0x3E, 0xA4, 0x1E, + 0xC1, 0x07, 0x03, 0x5A, 0x46, 0x2D, 0xB8, 0x97, 0xF3, 0xB7, 0xD5, 0xB2, + 0x55, 0x21, 0xEF, 0xBA, 0xDC, 0x4C, 0x00, 0x97, 0xFB, 0x14, 0x95, 0x27, + 0x33, 0xBF, 0xE8, 0x43, 0x47, 0x46, 0xD2, 0x08, 0x99, 0x16, 0x60, 0x3B, + 0x9A, 0x7E, 0xD2, 0xE6, 0xED, 0x38, 0xEA, 0xEC, 0x01, 0x1E, 0x3C, 0x48, + 0x56, 0x49, 0x09, 0xC7, 0x4C, 0x37, 0x00, 0x9E, 0x88, 0x0E, 0xC0, 0x73, + 0xE1, 0x6F, 0x66, 0xE9, 0x72, 0x47, 0x30, 0x3E, 0x10, 0xE5, 0x0B, 0x03, + 0xC9, 0x9A, 0x42, 0x00, 0x6C, 0xC5, 0x94, 0x7E, 0x61, 0xC4, 0x8A, 0xDF, + 0x7F, 0x82, 0x1A, 0x0B, 0x59, 0xC4, 0x59, 0x32, 0x77, 0xB3, 0xBC, 0x60, + 0x69, 0x56, 0x39, 0xFD, 0xB4, 0x06, 0x7B, 0x2C, 0xD6, 0x64, 0x36, 0xD9, + 0xBD, 0x48, 0xED, 0x84, 0x1F, 0x7E, 0xA5, 0x22, 0x8F, 0x2A, 0xB8, 0x42, + 0xF4, 0x82, 0xB7, 0xD4, 0x53, 0x90, 0x78, 0x4E, 0x2D, 0x1A, 0xFD, 0x81, + 0x6F, 0x44, 0xD7, 0x3B, 0x01, 0x74, 0x96, 0x42, 0xE0, 0x00, 0xE2, 0x2E, + 0x6B, 0xEA, 0xC5, 0xEE, 0x72, 0xAC, 0xBB, 0xBF, 0xFE, 0xEA, 0xAA, 0xA8, + 0xF8, 0xDC, 0xF6, 0xB2, 0x79, 0x8A, 0xB6, 0x67 +}; + +static const unsigned char TA400_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA401_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA401_EC_Q[] = { + 0x04, 0x0D, 0x30, 0x5E, 0x1B, 0x15, 0x9D, 0x03, 0xD0, 0xA1, 0x79, 0x35, + 0xB7, 0x3A, 0x3C, 0x92, 0x7A, 0xCA, 0x15, 0x1C, 0xCD, 0x62, 0xF3, 0x9C, + 0x26, 0x5C, 0x07, 0x3D, 0xE5, 0x54, 0xFA, 0xA3, 0xD6, 0xCC, 0x12, 0xEA, + 0xF4, 0x14, 0x5F, 0xE8, 0x8E, 0x19, 0xAB, 0x2F, 0x2E, 0x48, 0xE6, 0xAC, + 0x18, 0x43, 0x78, 0xAC, 0xD0, 0x37, 0xC3, 0xBD, 0xB2, 0xCD, 0x2C, 0xE6, + 0x47, 0xE2, 0x1A, 0xE6, 0x63, 0xB8, 0x3D, 0x2E, 0x2F, 0x78, 0xC4, 0x4F, + 0xDB, 0xF4, 0x0F, 0xA4, 0x68, 0x4C, 0x55, 0x72, 0x6B, 0x95, 0x1D, 0x4E, + 0x18, 0x42, 0x95, 0x78, 0xCC, 0x37, 0x3C, 0x91, 0xE2, 0x9B, 0x65, 0x2B, + 0x29 +}; + +static const unsigned char TA402_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA402_RSA_N[] = { + 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80, + 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7, + 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86, + 0xD3, 0xA0, 0x43, 0x7A, 0x4E, 0xB2, 0xA4, 0xD0, 0x36, 0xBA, 0x01, 0xBE, + 0x8D, 0xDB, 0x48, 0xC8, 0x07, 0x17, 0x36, 0x4C, 0xF4, 0xEE, 0x88, 0x23, + 0xC7, 0x3E, 0xEB, 0x37, 0xF5, 0xB5, 0x19, 0xF8, 0x49, 0x68, 0xB0, 0xDE, + 0xD7, 0xB9, 0x76, 0x38, 0x1D, 0x61, 0x9E, 0xA4, 0xFE, 0x82, 0x36, 0xA5, + 0xE5, 0x4A, 0x56, 0xE4, 0x45, 0xE1, 0xF9, 0xFD, 0xB4, 0x16, 0xFA, 0x74, + 0xDA, 0x9C, 0x9B, 0x35, 0x39, 0x2F, 0xFA, 0xB0, 0x20, 0x50, 0x06, 0x6C, + 0x7A, 0xD0, 0x80, 0xB2, 0xA6, 0xF9, 0xAF, 0xEC, 0x47, 0x19, 0x8F, 0x50, + 0x38, 0x07, 0xDC, 0xA2, 0x87, 0x39, 0x58, 0xF8, 0xBA, 0xD5, 0xA9, 0xF9, + 0x48, 0x67, 0x30, 0x96, 0xEE, 0x94, 0x78, 0x5E, 0x6F, 0x89, 0xA3, 0x51, + 0xC0, 0x30, 0x86, 0x66, 0xA1, 0x45, 0x66, 0xBA, 0x54, 0xEB, 0xA3, 0xC3, + 0x91, 0xF9, 0x48, 0xDC, 0xFF, 0xD1, 0xE8, 0x30, 0x2D, 0x7D, 0x2D, 0x74, + 0x70, 0x35, 0xD7, 0x88, 0x24, 0xF7, 0x9E, 0xC4, 0x59, 0x6E, 0xBB, 0x73, + 0x87, 0x17, 0xF2, 0x32, 0x46, 0x28, 0xB8, 0x43, 0xFA, 0xB7, 0x1D, 0xAA, + 0xCA, 0xB4, 0xF2, 0x9F, 0x24, 0x0E, 0x2D, 0x4B, 0xF7, 0x71, 0x5C, 0x5E, + 0x69, 0xFF, 0xEA, 0x95, 0x02, 0xCB, 0x38, 0x8A, 0xAE, 0x50, 0x38, 0x6F, + 0xDB, 0xFB, 0x2D, 0x62, 0x1B, 0xC5, 0xC7, 0x1E, 0x54, 0xE1, 0x77, 0xE0, + 0x67, 0xC8, 0x0F, 0x9C, 0x87, 0x23, 0xD6, 0x3F, 0x40, 0x20, 0x7F, 0x20, + 0x80, 0xC4, 0x80, 0x4C, 0x3E, 0x3B, 0x24, 0x26, 0x8E, 0x04, 0xAE, 0x6C, + 0x9A, 0xC8, 0xAA, 0x0D +}; + +static const unsigned char TA402_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA403_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA403_RSA_N[] = { + 0xAD, 0x96, 0x9F, 0x2D, 0x9C, 0x4A, 0x4C, 0x4A, 0x81, 0x79, 0x51, 0x99, + 0xEC, 0x8A, 0xCB, 0x6B, 0x60, 0x51, 0x13, 0xBC, 0x4D, 0x6D, 0x06, 0xFC, + 0xB0, 0x08, 0x8D, 0xDD, 0x19, 0x10, 0x6A, 0xC7, 0x26, 0x0C, 0x35, 0xD8, + 0xC0, 0x6F, 0x20, 0x84, 0xE9, 0x94, 0xB1, 0x9B, 0x85, 0x03, 0xC3, 0x5B, + 0xDB, 0x4A, 0xE8, 0xC8, 0xF8, 0x90, 0x76, 0xD9, 0x5B, 0x4F, 0xE3, 0x4C, + 0xE8, 0x06, 0x36, 0x4D, 0xCC, 0x9A, 0xAC, 0x3D, 0x0C, 0x90, 0x2B, 0x92, + 0xD4, 0x06, 0x19, 0x60, 0xAC, 0x37, 0x44, 0x79, 0x85, 0x81, 0x82, 0xAD, + 0x5A, 0x37, 0xE0, 0x0D, 0xCC, 0x9D, 0xA6, 0x4C, 0x52, 0x76, 0xEA, 0x43, + 0x9D, 0xB7, 0x04, 0xD1, 0x50, 0xF6, 0x55, 0xE0, 0xD5, 0xD2, 0xA6, 0x49, + 0x85, 0xE9, 0x37, 0xE9, 0xCA, 0x7E, 0xAE, 0x5C, 0x95, 0x4D, 0x48, 0x9A, + 0x3F, 0xAE, 0x20, 0x5A, 0x6D, 0x88, 0x95, 0xD9, 0x34, 0xB8, 0x52, 0x1A, + 0x43, 0x90, 0xB0, 0xBF, 0x6C, 0x05, 0xB9, 0xB6, 0x78, 0xB7, 0xEA, 0xD0, + 0xE4, 0x3A, 0x3C, 0x12, 0x53, 0x62, 0xFF, 0x4A, 0xF2, 0x7B, 0xBE, 0x35, + 0x05, 0xA9, 0x12, 0x34, 0xE3, 0xF3, 0x64, 0x74, 0x62, 0x2C, 0x3D, 0x00, + 0x49, 0x5A, 0x28, 0xFE, 0x32, 0x44, 0xBB, 0x87, 0xDD, 0x65, 0x27, 0x02, + 0x71, 0x3B, 0xDA, 0x4A, 0xF7, 0x1F, 0xDA, 0xCD, 0xF7, 0x21, 0x55, 0x90, + 0x4F, 0x0F, 0xEC, 0xAE, 0x82, 0xE1, 0x9F, 0x6B, 0xD9, 0x45, 0xD3, 0xBB, + 0xF0, 0x5F, 0x87, 0xED, 0x3C, 0x2C, 0x39, 0x86, 0xDA, 0x3F, 0xDE, 0xEC, + 0x72, 0x55, 0xEB, 0x79, 0xA3, 0xAD, 0xDB, 0xDD, 0x7C, 0xB0, 0xBA, 0x1C, + 0xCE, 0xFC, 0xDE, 0x4F, 0x35, 0x76, 0xCF, 0x0F, 0xF8, 0x78, 0x1F, 0x6A, + 0x36, 0x51, 0x46, 0x27, 0x61, 0x5B, 0xE9, 0x9E, 0xCF, 0xF0, 0xA2, 0x55, + 0x7D, 0x7C, 0x25, 0x8A, 0x6F, 0x2F, 0xB4, 0xC5, 0xCF, 0x84, 0x2E, 0x2B, + 0xFD, 0x0D, 0x51, 0x10, 0x6C, 0xFB, 0x5F, 0x1B, 0xBC, 0x1B, 0x7E, 0xC5, + 0xAE, 0x3B, 0x98, 0x01, 0x31, 0x92, 0xFF, 0x0B, 0x57, 0xF4, 0x9A, 0xB2, + 0xB9, 0x57, 0xE9, 0xAB, 0xEF, 0x0D, 0x76, 0xD1, 0xF0, 0xEE, 0xF4, 0xCE, + 0x86, 0xA7, 0xE0, 0x6E, 0xE9, 0xB4, 0x69, 0xA1, 0xDF, 0x69, 0xF6, 0x33, + 0xC6, 0x69, 0x2E, 0x97, 0x13, 0x9E, 0xA5, 0x87, 0xB0, 0x57, 0x10, 0x81, + 0x37, 0xC9, 0x53, 0xB3, 0xBB, 0x7F, 0xF6, 0x92, 0xD1, 0x9C, 0xD0, 0x18, + 0xF4, 0x92, 0x6E, 0xDA, 0x83, 0x4F, 0xA6, 0x63, 0x99, 0x4C, 0xA5, 0xFB, + 0x5E, 0xEF, 0x21, 0x64, 0x7A, 0x20, 0x5F, 0x6C, 0x64, 0x85, 0x15, 0xCB, + 0x37, 0xE9, 0x62, 0x0C, 0x0B, 0x2A, 0x16, 0xDC, 0x01, 0x2E, 0x32, 0xDA, + 0x3E, 0x4B, 0xF5, 0x9E, 0x3A, 0xF6, 0x17, 0x40, 0x94, 0xEF, 0x9E, 0x91, + 0x08, 0x86, 0xFA, 0xBE, 0x63, 0xA8, 0x5A, 0x33, 0xEC, 0xCB, 0x74, 0x43, + 0x95, 0xF9, 0x6C, 0x69, 0x52, 0x36, 0xC7, 0x29, 0x6F, 0xFC, 0x55, 0x03, + 0x5C, 0x1F, 0xFB, 0x9F, 0xBD, 0x47, 0xEB, 0xE7, 0x49, 0x47, 0x95, 0x0B, + 0x4E, 0x89, 0x22, 0x09, 0x49, 0xE0, 0xF5, 0x61, 0x1E, 0xF1, 0xBF, 0x2E, + 0x8A, 0x72, 0x6E, 0x80, 0x59, 0xFF, 0x57, 0x3A, 0xF9, 0x75, 0x32, 0xA3, + 0x4E, 0x5F, 0xEC, 0xED, 0x28, 0x62, 0xD9, 0x4D, 0x73, 0xF2, 0xCC, 0x81, + 0x17, 0x60, 0xED, 0xCD, 0xEB, 0xDC, 0xDB, 0xA7, 0xCA, 0xC5, 0x7E, 0x02, + 0xBD, 0xF2, 0x54, 0x08, 0x54, 0xFD, 0xB4, 0x2D, 0x09, 0x2C, 0x17, 0x54, + 0x4A, 0x98, 0xD1, 0x54, 0xE1, 0x51, 0x67, 0x08, 0xD2, 0xED, 0x6E, 0x7E, + 0x6F, 0x3F, 0xD2, 0x2D, 0x81, 0x59, 0x29, 0x66, 0xCB, 0x90, 0x39, 0x95, + 0x11, 0x1E, 0x74, 0x27, 0xFE, 0xDD, 0xEB, 0xAF +}; + +static const unsigned char TA403_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA404_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA404_EC_Q[] = { + 0x04, 0x29, 0x97, 0xA7, 0xC6, 0x41, 0x7F, 0xC0, 0x0D, 0x9B, 0xE8, 0x01, + 0x1B, 0x56, 0xC6, 0xF2, 0x52, 0xA5, 0xBA, 0x2D, 0xB2, 0x12, 0xE8, 0xD2, + 0x2E, 0xD7, 0xFA, 0xC9, 0xC5, 0xD8, 0xAA, 0x6D, 0x1F, 0x73, 0x81, 0x3B, + 0x3B, 0x98, 0x6B, 0x39, 0x7C, 0x33, 0xA5, 0xC5, 0x4E, 0x86, 0x8E, 0x80, + 0x17, 0x68, 0x62, 0x45, 0x57, 0x7D, 0x44, 0x58, 0x1D, 0xB3, 0x37, 0xE5, + 0x67, 0x08, 0xEB, 0x66, 0xDE +}; + +static const unsigned char TA405_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x34 +}; + +static const unsigned char TA405_EC_Q[] = { + 0x04, 0xD2, 0xAB, 0x8A, 0x37, 0x4F, 0xA3, 0x53, 0x0D, 0xFE, 0xC1, 0x8A, + 0x7B, 0x4B, 0xA8, 0x7B, 0x46, 0x4B, 0x63, 0xB0, 0x62, 0xF6, 0x2D, 0x1B, + 0xDB, 0x08, 0x71, 0x21, 0xD2, 0x00, 0xE8, 0x63, 0xBD, 0x9A, 0x27, 0xFB, + 0xF0, 0x39, 0x6E, 0x5D, 0xEA, 0x3D, 0xA5, 0xC9, 0x81, 0xAA, 0xA3, 0x5B, + 0x20, 0x98, 0x45, 0x5D, 0x16, 0xDB, 0xFD, 0xE8, 0x10, 0x6D, 0xE3, 0x9C, + 0xE0, 0xE3, 0xBD, 0x5F, 0x84, 0x62, 0xF3, 0x70, 0x64, 0x33, 0xA0, 0xCB, + 0x24, 0x2F, 0x70, 0xBA, 0x88, 0xA1, 0x2A, 0xA0, 0x75, 0xF8, 0x81, 0xAE, + 0x62, 0x06, 0xC4, 0x81, 0xDB, 0x39, 0x6E, 0x29, 0xB0, 0x1E, 0xFA, 0x2E, + 0x5C +}; + +static const unsigned char TA406_DN[] = { + 0x30, 0x3C, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x15, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x0D, + 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x04, 0x41, 0x74, 0x6F, + 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x44, 0x45 +}; + +static const unsigned char TA406_RSA_N[] = { + 0x95, 0x85, 0x3B, 0x97, 0x6F, 0x2A, 0x3B, 0x2E, 0x3B, 0xCF, 0xA6, 0xF3, + 0x29, 0x35, 0xBE, 0xCF, 0x18, 0xAC, 0x3E, 0xAA, 0xD9, 0xF8, 0x4D, 0xA0, + 0x3E, 0x1A, 0x47, 0xB9, 0xBC, 0x9A, 0xDF, 0xF2, 0xFE, 0xCC, 0x3E, 0x47, + 0xE8, 0x7A, 0x96, 0xC2, 0x24, 0x8E, 0x35, 0xF4, 0xA9, 0x0C, 0xFC, 0x82, + 0xFD, 0x6D, 0xC1, 0x72, 0x62, 0x27, 0xBD, 0xEA, 0x6B, 0xEB, 0xE7, 0x8A, + 0xCC, 0x54, 0x3E, 0x90, 0x50, 0xCF, 0x80, 0xD4, 0x95, 0xFB, 0xE8, 0xB5, + 0x82, 0xD4, 0x14, 0xC5, 0xB6, 0xA9, 0x55, 0x25, 0x57, 0xDB, 0xB1, 0x50, + 0xF6, 0xB0, 0x60, 0x64, 0x59, 0x7A, 0x69, 0xCF, 0x03, 0xB7, 0x6F, 0x0D, + 0xBE, 0xCA, 0x3E, 0x6F, 0x74, 0x72, 0xEA, 0xAA, 0x30, 0x2A, 0x73, 0x62, + 0xBE, 0x49, 0x91, 0x61, 0xC8, 0x11, 0xFE, 0x0E, 0x03, 0x2A, 0xF7, 0x6A, + 0x20, 0xDC, 0x02, 0x15, 0x0D, 0x5E, 0x15, 0x6A, 0xFC, 0xE3, 0x82, 0xC1, + 0xB5, 0xC5, 0x9D, 0x64, 0x09, 0x6C, 0xA3, 0x59, 0x98, 0x07, 0x27, 0xC7, + 0x1B, 0x96, 0x2B, 0x61, 0x74, 0x71, 0x6C, 0x43, 0xF1, 0xF7, 0x35, 0x89, + 0x10, 0xE0, 0x9E, 0xEC, 0x55, 0xA1, 0x37, 0x22, 0xA2, 0x87, 0x04, 0x05, + 0x2C, 0x47, 0x7D, 0xB4, 0x1C, 0xB9, 0x62, 0x29, 0x66, 0x28, 0xCA, 0xB7, + 0xE1, 0x93, 0xF5, 0xA4, 0x94, 0x03, 0x99, 0xB9, 0x70, 0x85, 0xB5, 0xE6, + 0x48, 0xEA, 0x8D, 0x50, 0xFC, 0xD9, 0xDE, 0xCC, 0x6F, 0x07, 0x0E, 0xDD, + 0x0B, 0x72, 0x9D, 0x80, 0x30, 0x16, 0x07, 0x95, 0x3F, 0x28, 0x0E, 0xFD, + 0xC5, 0x75, 0x4F, 0x53, 0xD6, 0x74, 0x9A, 0xB4, 0x24, 0x2E, 0x8E, 0x02, + 0x91, 0xCF, 0x76, 0xC5, 0x9B, 0x1E, 0x55, 0x74, 0x9C, 0x78, 0x21, 0xB1, + 0xF0, 0x2D, 0xF1, 0x0B, 0x9F, 0xC2, 0xD5, 0x96, 0x18, 0x1F, 0xF0, 0x54, + 0x22, 0x7A, 0x8C, 0x07 +}; + +static const unsigned char TA406_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA407_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x45, 0x43, 0x43, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA407_EC_Q[] = { + 0x04, 0x96, 0x86, 0x58, 0x28, 0x37, 0x0A, 0x67, 0xD0, 0xA0, 0xDE, 0x24, + 0x19, 0x19, 0xE1, 0xE4, 0x05, 0x07, 0x1F, 0x97, 0xED, 0xE8, 0x64, 0x82, + 0xB9, 0xF6, 0xC4, 0x71, 0x50, 0xCE, 0x8A, 0x0C, 0xFF, 0xD7, 0xB5, 0x76, + 0xBB, 0xA1, 0x6C, 0x93, 0x6C, 0x83, 0xA2, 0x68, 0x6E, 0xA5, 0xD9, 0xBE, + 0x2C, 0x88, 0x95, 0x41, 0xCD, 0x5D, 0xDD, 0xB1, 0xCA, 0x83, 0x63, 0x83, + 0xCC, 0xC0, 0xBE, 0x74, 0xD9, 0xE0, 0x9D, 0xA4, 0xEE, 0x4A, 0x4E, 0x56, + 0xE0, 0x98, 0x29, 0x41, 0x93, 0x52, 0x10, 0xD5, 0x24, 0x38, 0x02, 0x32, + 0x67, 0xF1, 0x94, 0x12, 0x6F, 0xEF, 0xD7, 0xC5, 0xDE, 0x2E, 0xFD, 0x19, + 0x80 +}; + +static const unsigned char TA408_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA408_RSA_N[] = { + 0xB6, 0x80, 0x0E, 0xC4, 0x79, 0xBD, 0x05, 0x8C, 0x7D, 0xB0, 0xA3, 0x9D, + 0x4D, 0x22, 0x4D, 0xCB, 0xF0, 0x41, 0x97, 0x4D, 0x59, 0xE0, 0xD1, 0xFE, + 0x56, 0x8C, 0x97, 0xF2, 0xD7, 0xBD, 0x8F, 0x6C, 0xB7, 0x23, 0x8F, 0x5F, + 0xD5, 0xC4, 0xD8, 0x41, 0xCB, 0xF2, 0x02, 0x1E, 0x71, 0xE5, 0xE9, 0xF6, + 0x5E, 0xCB, 0x08, 0x2A, 0x5E, 0x30, 0xF2, 0x2D, 0x66, 0xC7, 0x84, 0x1B, + 0x64, 0x57, 0x38, 0x9D, 0x75, 0x2D, 0x56, 0xC6, 0x2F, 0x61, 0xEF, 0x96, + 0xFC, 0x20, 0x46, 0xBD, 0xEB, 0xD4, 0x7B, 0x3F, 0x3F, 0x7C, 0x47, 0x38, + 0x04, 0xA9, 0x1B, 0xAA, 0x52, 0xDF, 0x13, 0x37, 0xD3, 0x15, 0x15, 0x4E, + 0xBD, 0x5F, 0x7C, 0xAF, 0xAD, 0x63, 0xC7, 0x79, 0xDC, 0x08, 0x7B, 0xD5, + 0xA0, 0xE5, 0xF7, 0x5B, 0x75, 0xAC, 0x80, 0x55, 0x99, 0x92, 0x61, 0x9B, + 0xCD, 0x2A, 0x17, 0x7D, 0xDB, 0x8F, 0xF4, 0xB5, 0x6A, 0xEA, 0x17, 0x4A, + 0x64, 0x28, 0x66, 0x15, 0x29, 0x6C, 0x02, 0xF1, 0x6B, 0xD5, 0xBA, 0xA3, + 0x33, 0xDC, 0x5A, 0x67, 0xA7, 0x05, 0xE2, 0xBF, 0x65, 0xB6, 0x16, 0xB0, + 0x10, 0xED, 0xCD, 0x50, 0x33, 0xC9, 0x70, 0x50, 0xEC, 0x19, 0x8E, 0xB0, + 0xC7, 0xF2, 0x74, 0x5B, 0x6B, 0x44, 0xC6, 0x7D, 0x96, 0xB9, 0x98, 0x08, + 0x59, 0x66, 0xDE, 0x29, 0x01, 0x9B, 0xF4, 0x2A, 0x6D, 0xD3, 0x15, 0x3A, + 0x90, 0x6A, 0x67, 0xF1, 0xB4, 0x6B, 0x66, 0xD9, 0x21, 0xEB, 0xCA, 0xD9, + 0x62, 0x7C, 0x46, 0x10, 0x5C, 0xDE, 0x75, 0x49, 0x67, 0x9E, 0x42, 0xF9, + 0xFE, 0x75, 0xA9, 0xA3, 0xAD, 0xFF, 0x76, 0x0A, 0x67, 0x40, 0xE3, 0xC5, + 0xF7, 0x8D, 0xC7, 0x85, 0x9A, 0x59, 0x9E, 0x62, 0x9A, 0x6A, 0xED, 0x45, + 0x87, 0x98, 0x67, 0xB2, 0xD5, 0x4A, 0x3C, 0xD7, 0xB4, 0x3B, 0x00, 0x0D, + 0xC0, 0x8F, 0x1F, 0xE1, 0x40, 0xC4, 0xAE, 0x6C, 0x21, 0xDC, 0x49, 0x7E, + 0x7E, 0xCA, 0xB2, 0x8D, 0x6D, 0xB6, 0xBF, 0x93, 0x2F, 0xA1, 0x5C, 0x3E, + 0x8F, 0xCA, 0xED, 0x80, 0x8E, 0x58, 0xE1, 0xDB, 0x57, 0xCF, 0x85, 0x36, + 0x38, 0xB2, 0x71, 0xA4, 0x09, 0x8C, 0x92, 0x89, 0x08, 0x88, 0x48, 0xF1, + 0x40, 0x63, 0x18, 0xB2, 0x5B, 0x8C, 0x5A, 0xE3, 0xC3, 0xD3, 0x17, 0xAA, + 0xAB, 0x19, 0xA3, 0x2C, 0x1B, 0xE4, 0xD5, 0xC6, 0xE2, 0x66, 0x7A, 0xD7, + 0x82, 0x19, 0xA6, 0x3B, 0x16, 0x2C, 0x2F, 0x71, 0x87, 0x5F, 0x45, 0x9E, + 0x95, 0x73, 0x93, 0xC2, 0x42, 0x81, 0x21, 0x13, 0x96, 0xD7, 0x9D, 0xBB, + 0x93, 0x68, 0x15, 0xFA, 0x9D, 0xA4, 0x1D, 0x8C, 0xF2, 0x81, 0xE0, 0x58, + 0x06, 0xBD, 0xC9, 0xB6, 0xE3, 0xF6, 0x89, 0x5D, 0x89, 0xF9, 0xAC, 0x44, + 0xA1, 0xCB, 0x6B, 0xFA, 0x16, 0xF1, 0xC7, 0x50, 0x3D, 0x24, 0xDA, 0xF7, + 0xC3, 0xE4, 0x87, 0xD5, 0x56, 0xF1, 0x4F, 0x90, 0x30, 0xFA, 0x45, 0x09, + 0x59, 0xDA, 0x34, 0xCE, 0xE0, 0x13, 0x1C, 0x04, 0x7C, 0x00, 0xD4, 0x9B, + 0x86, 0xA4, 0x40, 0xBC, 0xD9, 0xDC, 0x4C, 0x57, 0x7E, 0xAE, 0xB7, 0x33, + 0xB6, 0x5E, 0x76, 0xE1, 0x65, 0x8B, 0x66, 0xDF, 0x8D, 0xCA, 0xD7, 0x98, + 0xAF, 0xCE, 0x36, 0x98, 0x8C, 0x9C, 0x83, 0x99, 0x03, 0x70, 0xF3, 0xAF, + 0x74, 0xED, 0xC6, 0x0E, 0x36, 0xE7, 0xBD, 0xEC, 0xC1, 0x73, 0xA7, 0x94, + 0x5A, 0xCB, 0x92, 0x64, 0x82, 0xA6, 0x00, 0xC1, 0x70, 0xA1, 0x6E, 0x2C, + 0x29, 0xE1, 0x58, 0x57, 0xEC, 0x5A, 0x7C, 0x99, 0x6B, 0x25, 0xA4, 0x90, + 0x3A, 0x80, 0xF4, 0x20, 0x9D, 0x9A, 0xCE, 0xC7, 0x2D, 0xF9, 0xB2, 0x4B, + 0x29, 0x95, 0x83, 0xE9, 0x35, 0x8D, 0xA7, 0x49, 0x48, 0xA7, 0x0F, 0x4C, + 0x19, 0x91, 0xD0, 0xF5, 0xBF, 0x10, 0xE0, 0x71 +}; + +static const unsigned char TA408_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA409_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x39, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, 0x20, + 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x63, 0x69, 0x6F, 0x6E, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, + 0x6F, 0x66, 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x43, 0x49, + 0x46, 0x20, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38 +}; + +static const unsigned char TA409_RSA_N[] = { + 0xCA, 0x96, 0x6B, 0x8E, 0xEA, 0xF8, 0xFB, 0xF1, 0xA2, 0x35, 0xE0, 0x7F, + 0x4C, 0xDA, 0xE0, 0xC3, 0x52, 0xD7, 0x7D, 0xB6, 0x10, 0xC8, 0x02, 0x5E, + 0xB3, 0x43, 0x2A, 0xC4, 0x4F, 0x6A, 0xB2, 0xCA, 0x1C, 0x5D, 0x28, 0x9A, + 0x78, 0x11, 0x1A, 0x69, 0x59, 0x57, 0xAF, 0xB5, 0x20, 0x42, 0xE4, 0x8B, + 0x0F, 0xE6, 0xDF, 0x5B, 0xA6, 0x03, 0x92, 0x2F, 0xF5, 0x11, 0xE4, 0x62, + 0xD7, 0x32, 0x71, 0x38, 0xD9, 0x04, 0x0C, 0x71, 0xAB, 0x3D, 0x51, 0x7E, + 0x0F, 0x07, 0xDF, 0x63, 0x05, 0x5C, 0xE9, 0xBF, 0x94, 0x6F, 0xC1, 0x29, + 0x82, 0xC0, 0xB4, 0xDA, 0x51, 0xB0, 0xC1, 0x3C, 0xBB, 0xAD, 0x37, 0x4A, + 0x5C, 0xCA, 0xF1, 0x4B, 0x36, 0x0E, 0x24, 0xAB, 0xBF, 0xC3, 0x84, 0x77, + 0xFD, 0xA8, 0x50, 0xF4, 0xB1, 0xE7, 0xC6, 0x2F, 0xD2, 0x2D, 0x59, 0x8D, + 0x7A, 0x0A, 0x4E, 0x96, 0x69, 0x52, 0x02, 0xAA, 0x36, 0x98, 0xEC, 0xFC, + 0xFA, 0x14, 0x83, 0x0C, 0x37, 0x1F, 0xC9, 0x92, 0x37, 0x7F, 0xD7, 0x81, + 0x2D, 0xE5, 0xC4, 0xB9, 0xE0, 0x3E, 0x34, 0xFE, 0x67, 0xF4, 0x3E, 0x66, + 0xD1, 0xD3, 0xF4, 0x40, 0xCF, 0x5E, 0x62, 0x34, 0x0F, 0x70, 0x06, 0x3E, + 0x20, 0x18, 0x5A, 0xCE, 0xF7, 0x72, 0x1B, 0x25, 0x6C, 0x93, 0x74, 0x14, + 0x93, 0xA3, 0x73, 0xB1, 0x0E, 0xAA, 0x87, 0x10, 0x23, 0x59, 0x5F, 0x20, + 0x05, 0x19, 0x47, 0xED, 0x68, 0x8E, 0x92, 0x12, 0xCA, 0x5D, 0xFC, 0xD6, + 0x2B, 0xB2, 0x92, 0x3C, 0x20, 0xCF, 0xE1, 0x5F, 0xAF, 0x20, 0xBE, 0xA0, + 0x76, 0x7F, 0x76, 0xE5, 0xEC, 0x1A, 0x86, 0x61, 0x33, 0x3E, 0xE7, 0x7B, + 0xB4, 0x3F, 0xA0, 0x0F, 0x8E, 0xA2, 0xB9, 0x6A, 0x6F, 0xB9, 0x87, 0x26, + 0x6F, 0x41, 0x6C, 0x88, 0xA6, 0x50, 0xFD, 0x6A, 0x63, 0x0B, 0xF5, 0x93, + 0x16, 0x1B, 0x19, 0x8F, 0xB2, 0xED, 0x9B, 0x9B, 0xC9, 0x90, 0xF5, 0x01, + 0x0C, 0xDF, 0x19, 0x3D, 0x0F, 0x3E, 0x38, 0x23, 0xC9, 0x2F, 0x8F, 0x0C, + 0xD1, 0x02, 0xFE, 0x1B, 0x55, 0xD6, 0x4E, 0xD0, 0x8D, 0x3C, 0xAF, 0x4F, + 0xA4, 0xF3, 0xFE, 0xAF, 0x2A, 0xD3, 0x05, 0x9D, 0x79, 0x08, 0xA1, 0xCB, + 0x57, 0x31, 0xB4, 0x9C, 0xC8, 0x90, 0xB2, 0x67, 0xF4, 0x18, 0x16, 0x93, + 0x3A, 0xFC, 0x47, 0xD8, 0xD1, 0x78, 0x96, 0x31, 0x1F, 0xBA, 0x2B, 0x0C, + 0x5F, 0x5D, 0x99, 0xAD, 0x63, 0x89, 0x5A, 0x24, 0x20, 0x76, 0xD8, 0xDF, + 0xFD, 0xAB, 0x4E, 0xA6, 0x22, 0xAA, 0x9D, 0x5E, 0xE6, 0x27, 0x8A, 0x7D, + 0x68, 0x29, 0xA3, 0xE7, 0x8A, 0xB8, 0xDA, 0x11, 0xBB, 0x17, 0x2D, 0x99, + 0x9D, 0x13, 0x24, 0x46, 0xF7, 0xC5, 0xE2, 0xD8, 0x9F, 0x8E, 0x7F, 0xC7, + 0x8F, 0x74, 0x6D, 0x5A, 0xB2, 0xE8, 0x72, 0xF5, 0xAC, 0xEE, 0x24, 0x10, + 0xAD, 0x2F, 0x14, 0xDA, 0xFF, 0x2D, 0x9A, 0x46, 0x71, 0x47, 0xBE, 0x42, + 0xDF, 0xBB, 0x01, 0xDB, 0xF4, 0x7F, 0xD3, 0x28, 0x8F, 0x31, 0x59, 0x5B, + 0xD3, 0xC9, 0x02, 0xA6, 0xB4, 0x52, 0xCA, 0x6E, 0x97, 0xFB, 0x43, 0xC5, + 0x08, 0x26, 0x6F, 0x8A, 0xF4, 0xBB, 0xFD, 0x9F, 0x28, 0xAA, 0x0D, 0xD5, + 0x45, 0xF3, 0x13, 0x3A, 0x1D, 0xD8, 0xC0, 0x78, 0x8F, 0x41, 0x67, 0x3C, + 0x1E, 0x94, 0x64, 0xAE, 0x7B, 0x0B, 0xC5, 0xE8, 0xD9, 0x01, 0x88, 0x39, + 0x1A, 0x97, 0x86, 0x64, 0x41, 0xD5, 0x3B, 0x87, 0x0C, 0x6E, 0xFA, 0x0F, + 0xC6, 0xBD, 0x48, 0x14, 0xBF, 0x39, 0x4D, 0xD4, 0x9E, 0x41, 0xB6, 0x8F, + 0x96, 0x1D, 0x63, 0x96, 0x93, 0xD9, 0x95, 0x06, 0x78, 0x31, 0x68, 0x9E, + 0x37, 0x06, 0x3B, 0x80, 0x89, 0x45, 0x61, 0x39, 0x23, 0xC7, 0x1B, 0x44, + 0xA3, 0x15, 0xE5, 0x1C, 0xF8, 0x92, 0x30, 0xBB +}; + +static const unsigned char TA409_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA410_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x31 +}; + +static const unsigned char TA410_RSA_N[] = { + 0xF1, 0x66, 0x08, 0xBD, 0xD9, 0xC5, 0x15, 0x61, 0xCB, 0x84, 0x04, 0x41, + 0xA5, 0x69, 0x37, 0x77, 0x1D, 0xC1, 0xB0, 0x7B, 0xFA, 0xC3, 0x77, 0x48, + 0x90, 0x13, 0x72, 0x64, 0xD1, 0xB8, 0x7C, 0x90, 0x35, 0x9D, 0x18, 0x79, + 0x88, 0xE3, 0x97, 0x01, 0x3C, 0x47, 0x81, 0xF2, 0x0E, 0xA2, 0x98, 0x0D, + 0x9E, 0x3F, 0x37, 0xE0, 0x19, 0xB2, 0x90, 0xF2, 0x46, 0x1C, 0x92, 0xB1, + 0x3A, 0x61, 0xCE, 0xFA, 0xB7, 0x46, 0x9E, 0x03, 0x86, 0xD7, 0x33, 0x6E, + 0xED, 0xF7, 0x45, 0x8C, 0x76, 0x37, 0xDE, 0x6E, 0x96, 0x91, 0xF7, 0xD7, + 0x7E, 0x2B, 0x87, 0x17, 0xD5, 0x8B, 0x35, 0xEE, 0x84, 0x91, 0x72, 0x57, + 0xDC, 0x60, 0xC3, 0xC3, 0xB9, 0xE7, 0xC7, 0x67, 0x24, 0x23, 0x4F, 0x63, + 0x0A, 0x63, 0xF6, 0x66, 0x7D, 0x4B, 0x55, 0xA7, 0x3F, 0x78, 0x64, 0x49, + 0x69, 0x12, 0x97, 0xE0, 0x4C, 0x0D, 0xD3, 0x09, 0xA0, 0x32, 0x30, 0x3A, + 0xFA, 0x9F, 0xC0, 0xF2, 0x9C, 0xC5, 0x12, 0x2A, 0x2E, 0x1C, 0xB5, 0x04, + 0x33, 0xDA, 0xA4, 0x38, 0x11, 0x6A, 0xDE, 0xC6, 0x18, 0xF6, 0x47, 0x3A, + 0x22, 0x41, 0x87, 0x22, 0xFC, 0xC4, 0x89, 0x28, 0x54, 0xD8, 0x8C, 0xA5, + 0x30, 0x0A, 0xF8, 0x17, 0x16, 0xCA, 0xAC, 0x37, 0xFD, 0x79, 0xA7, 0x91, + 0x17, 0x78, 0x38, 0x99, 0xAD, 0x58, 0xED, 0xB2, 0xDE, 0xCC, 0x89, 0x7D, + 0x03, 0x9C, 0xB3, 0x89, 0x65, 0xE7, 0xE3, 0x3B, 0xB1, 0x22, 0x86, 0x8F, + 0x06, 0x6D, 0x78, 0x07, 0xFD, 0x91, 0x12, 0x7F, 0xB0, 0x6B, 0x1C, 0x89, + 0x0D, 0xF9, 0xB8, 0xCB, 0x74, 0x5B, 0x07, 0xC2, 0xC8, 0xF4, 0x35, 0xD1, + 0x64, 0x63, 0x7A, 0xE9, 0x6E, 0x9A, 0x28, 0xD6, 0x30, 0xBD, 0xE6, 0x1B, + 0xDD, 0x15, 0xAF, 0x84, 0xEA, 0x9C, 0xC7, 0xCA, 0xF5, 0x0E, 0xEA, 0xF2, + 0x5D, 0x29, 0x87, 0x8F, 0x69, 0x73, 0x39, 0xBE, 0x2E, 0x24, 0x6F, 0x45, + 0x21, 0xAC, 0xC5, 0xD4, 0x69, 0x25, 0x06, 0x83, 0xAD, 0x7A, 0x48, 0x85, + 0x13, 0x2C, 0x0D, 0x06, 0xB8, 0x6C, 0x79, 0x56, 0xFC, 0xA3, 0x67, 0x32, + 0x81, 0xF5, 0x57, 0xA5, 0xCA, 0x57, 0x42, 0x69, 0xE9, 0x5C, 0x24, 0x61, + 0xEF, 0xE2, 0x30, 0x18, 0x4E, 0x44, 0x98, 0x55, 0x6F, 0x7A, 0xC2, 0x93, + 0xD8, 0x19, 0xB6, 0xDE, 0x7C, 0x47, 0x8A, 0x11, 0x4E, 0x49, 0x47, 0xDB, + 0x28, 0x94, 0x02, 0x0B, 0x94, 0x4A, 0x2C, 0xF9, 0x12, 0xD0, 0x4F, 0xE8, + 0x31, 0x7E, 0x6C, 0x7A, 0xBF, 0xA6, 0x3F, 0x9B, 0x39, 0x3D, 0x02, 0x16, + 0xA3, 0x18, 0xB3, 0x67, 0xAC, 0x5B, 0x3F, 0x2C, 0x83, 0x2B, 0x67, 0x39, + 0x81, 0x5C, 0xB9, 0x7E, 0x94, 0xD5, 0x64, 0xDD, 0x9E, 0x8F, 0x6E, 0xAE, + 0xE8, 0x7C, 0x5B, 0xB4, 0xD7, 0x6A, 0x47, 0x48, 0xD7, 0x7E, 0xB3, 0xD4, + 0x2D, 0x8E, 0x56, 0x76, 0x4E, 0xCF, 0x69, 0xF1, 0x6E, 0x44, 0x6C, 0xD4, + 0x24, 0xEA, 0x8D, 0x24, 0xA1, 0x18, 0xBF, 0xBD, 0x57, 0xFE, 0xA9, 0x99, + 0x35, 0xB5, 0xDB, 0x10, 0x77, 0xB8, 0x3D, 0x48, 0xBA, 0xD6, 0xC1, 0xE7, + 0xF1, 0x23, 0x3E, 0xD7, 0xDF, 0x85, 0x9D, 0x27, 0x3C, 0xD4, 0x40, 0xBD, + 0x0A, 0x0C, 0xBD, 0xF5, 0xE7, 0x8D, 0x25, 0xD6, 0x81, 0x74, 0x87, 0x46, + 0xD4, 0x29, 0x75, 0xA2, 0x42, 0x6C, 0xF7, 0x73, 0x89, 0xE7, 0x7D, 0xBF, + 0x7A, 0x4A, 0x1F, 0xD3, 0x22, 0xC9, 0x15, 0x55, 0xCF, 0xDF, 0x6F, 0x7C, + 0x55, 0xD0, 0xA4, 0x8B, 0x07, 0x11, 0x37, 0x5F, 0x83, 0xA6, 0x26, 0x57, + 0xA6, 0x01, 0x5B, 0x7E, 0xFE, 0x58, 0x68, 0x07, 0xA9, 0xE9, 0x7A, 0xD9, + 0xB9, 0xE8, 0xFF, 0x50, 0x1F, 0xAB, 0xC2, 0xB4, 0xC0, 0xCE, 0xE8, 0xEA, + 0xFD, 0x0F, 0xBD, 0x8D, 0x4D, 0xB8, 0xBC, 0x71 +}; + +static const unsigned char TA410_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA411_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x32 +}; + +static const unsigned char TA411_EC_Q[] = { + 0x04, 0x9D, 0xCB, 0x80, 0x91, 0x8D, 0x53, 0x67, 0xB5, 0xB9, 0x50, 0xB1, + 0x03, 0xF8, 0xE5, 0x49, 0x1F, 0x41, 0x22, 0x09, 0xB0, 0x51, 0x52, 0x58, + 0xD6, 0x2B, 0x34, 0x8F, 0xC5, 0x12, 0x46, 0x14, 0xC5, 0x8B, 0x2F, 0x2C, + 0x84, 0xFF, 0x2C, 0x6E, 0xA8, 0xD5, 0xF1, 0x09, 0xE3, 0x03, 0x21, 0x14, + 0xC4, 0x43, 0x3D, 0x7C, 0xC1, 0x2C, 0xC4, 0x4B, 0x6A, 0x4A, 0xCD, 0xE9, + 0x87, 0xE0, 0x7D, 0xF6, 0x22, 0xBE, 0xFA, 0x4A, 0x51, 0xB8, 0x30, 0x8A, + 0xFD, 0xE1, 0xDE, 0x18, 0x12, 0x0A, 0xF6, 0x47, 0xB7, 0xE7, 0x17, 0xBF, + 0x27, 0x8A, 0xD4, 0x41, 0x4C, 0x96, 0x3C, 0x60, 0x96, 0xC1, 0xFD, 0x15, + 0x1C +}; + +static const unsigned char TA412_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x42, 0x61, 0x6C, 0x74, 0x69, 0x6D, 0x6F, 0x72, 0x65, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x0A, 0x43, 0x79, + 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6C, 0x74, 0x69, + 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA412_RSA_N[] = { + 0xA3, 0x04, 0xBB, 0x22, 0xAB, 0x98, 0x3D, 0x57, 0xE8, 0x26, 0x72, 0x9A, + 0xB5, 0x79, 0xD4, 0x29, 0xE2, 0xE1, 0xE8, 0x95, 0x80, 0xB1, 0xB0, 0xE3, + 0x5B, 0x8E, 0x2B, 0x29, 0x9A, 0x64, 0xDF, 0xA1, 0x5D, 0xED, 0xB0, 0x09, + 0x05, 0x6D, 0xDB, 0x28, 0x2E, 0xCE, 0x62, 0xA2, 0x62, 0xFE, 0xB4, 0x88, + 0xDA, 0x12, 0xEB, 0x38, 0xEB, 0x21, 0x9D, 0xC0, 0x41, 0x2B, 0x01, 0x52, + 0x7B, 0x88, 0x77, 0xD3, 0x1C, 0x8F, 0xC7, 0xBA, 0xB9, 0x88, 0xB5, 0x6A, + 0x09, 0xE7, 0x73, 0xE8, 0x11, 0x40, 0xA7, 0xD1, 0xCC, 0xCA, 0x62, 0x8D, + 0x2D, 0xE5, 0x8F, 0x0B, 0xA6, 0x50, 0xD2, 0xA8, 0x50, 0xC3, 0x28, 0xEA, + 0xF5, 0xAB, 0x25, 0x87, 0x8A, 0x9A, 0x96, 0x1C, 0xA9, 0x67, 0xB8, 0x3F, + 0x0C, 0xD5, 0xF7, 0xF9, 0x52, 0x13, 0x2F, 0xC2, 0x1B, 0xD5, 0x70, 0x70, + 0xF0, 0x8F, 0xC0, 0x12, 0xCA, 0x06, 0xCB, 0x9A, 0xE1, 0xD9, 0xCA, 0x33, + 0x7A, 0x77, 0xD6, 0xF8, 0xEC, 0xB9, 0xF1, 0x68, 0x44, 0x42, 0x48, 0x13, + 0xD2, 0xC0, 0xC2, 0xA4, 0xAE, 0x5E, 0x60, 0xFE, 0xB6, 0xA6, 0x05, 0xFC, + 0xB4, 0xDD, 0x07, 0x59, 0x02, 0xD4, 0x59, 0x18, 0x98, 0x63, 0xF5, 0xA5, + 0x63, 0xE0, 0x90, 0x0C, 0x7D, 0x5D, 0xB2, 0x06, 0x7A, 0xF3, 0x85, 0xEA, + 0xEB, 0xD4, 0x03, 0xAE, 0x5E, 0x84, 0x3E, 0x5F, 0xFF, 0x15, 0xED, 0x69, + 0xBC, 0xF9, 0x39, 0x36, 0x72, 0x75, 0xCF, 0x77, 0x52, 0x4D, 0xF3, 0xC9, + 0x90, 0x2C, 0xB9, 0x3D, 0xE5, 0xC9, 0x23, 0x53, 0x3F, 0x1F, 0x24, 0x98, + 0x21, 0x5C, 0x07, 0x99, 0x29, 0xBD, 0xC6, 0x3A, 0xEC, 0xE7, 0x6E, 0x86, + 0x3A, 0x6B, 0x97, 0x74, 0x63, 0x33, 0xBD, 0x68, 0x18, 0x31, 0xF0, 0x78, + 0x8D, 0x76, 0xBF, 0xFC, 0x9E, 0x8E, 0x5D, 0x2A, 0x86, 0xA7, 0x4D, 0x90, + 0xDC, 0x27, 0x1A, 0x39 +}; + +static const unsigned char TA412_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA413_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA413_RSA_N[] = { + 0xD7, 0xC7, 0x5E, 0xF7, 0xC1, 0x07, 0xD4, 0x77, 0xFB, 0x43, 0x21, 0xF4, + 0xF4, 0xF5, 0x69, 0xE4, 0xEE, 0x32, 0x01, 0xDB, 0xA3, 0x86, 0x1F, 0xE4, + 0x59, 0x0D, 0xBA, 0xE7, 0x75, 0x83, 0x52, 0xEB, 0xEA, 0x1C, 0x61, 0x15, + 0x48, 0xBB, 0x1D, 0x07, 0xCA, 0x8C, 0xAE, 0xB0, 0xDC, 0x96, 0x9D, 0xEA, + 0xC3, 0x60, 0x92, 0x86, 0x82, 0x28, 0x73, 0x9C, 0x56, 0x06, 0xFF, 0x4B, + 0x64, 0xF0, 0x0C, 0x2A, 0x37, 0x49, 0xB5, 0xE5, 0xCF, 0x0C, 0x7C, 0xEE, + 0xF1, 0x4A, 0xBB, 0x73, 0x30, 0x65, 0xF3, 0xD5, 0x2F, 0x83, 0xB6, 0x7E, + 0xE3, 0xE7, 0xF5, 0x9E, 0xAB, 0x60, 0xF9, 0xD3, 0xF1, 0x9D, 0x92, 0x74, + 0x8A, 0xE4, 0x1C, 0x96, 0xAC, 0x5B, 0x80, 0xE9, 0xB5, 0xF4, 0x31, 0x87, + 0xA3, 0x51, 0xFC, 0xC7, 0x7E, 0xA1, 0x6F, 0x8E, 0x53, 0x77, 0xD4, 0x97, + 0xC1, 0x55, 0x33, 0x92, 0x3E, 0x18, 0x2F, 0x75, 0xD4, 0xAD, 0x86, 0x49, + 0xCB, 0x95, 0xAF, 0x54, 0x06, 0x6C, 0xD8, 0x06, 0x13, 0x8D, 0x5B, 0xFF, + 0xE1, 0x26, 0x19, 0x59, 0xC0, 0x24, 0xBA, 0x81, 0x71, 0x79, 0x90, 0x44, + 0x50, 0x68, 0x24, 0x94, 0x5F, 0xB8, 0xB3, 0x11, 0xF1, 0x29, 0x41, 0x61, + 0xA3, 0x41, 0xCB, 0x23, 0x36, 0xD5, 0xC1, 0xF1, 0x32, 0x50, 0x10, 0x4E, + 0x7F, 0xF4, 0x86, 0x93, 0xEC, 0x84, 0xD3, 0x8E, 0xBC, 0x4B, 0xBF, 0x5C, + 0x01, 0x4E, 0x07, 0x3D, 0xDC, 0x14, 0x8A, 0x94, 0x0A, 0xA4, 0xEA, 0x73, + 0xFB, 0x0B, 0x51, 0xE8, 0x13, 0x07, 0x18, 0xFA, 0x0E, 0xF1, 0x2B, 0xD1, + 0x54, 0x15, 0x7D, 0x3C, 0xE1, 0xF7, 0xB4, 0x19, 0x42, 0x67, 0x62, 0x5E, + 0x77, 0xE0, 0xA2, 0x55, 0xEC, 0xB6, 0xD9, 0x69, 0x17, 0xD5, 0x3A, 0xAF, + 0x44, 0xED, 0x4A, 0xC5, 0x9E, 0xE4, 0x7A, 0x27, 0x7C, 0xE5, 0x75, 0xD7, + 0xAA, 0xCB, 0x25, 0xE7, 0xDF, 0x6B, 0x0A, 0xDB, 0x0F, 0x4D, 0x93, 0x4E, + 0xA8, 0xA0, 0xCD, 0x7B, 0x2E, 0xF2, 0x59, 0x01, 0x6A, 0xB7, 0x0D, 0xB8, + 0x07, 0x81, 0x7E, 0x8B, 0x38, 0x1B, 0x38, 0xE6, 0x0A, 0x57, 0x99, 0x3D, + 0xEE, 0x21, 0xE8, 0xA3, 0xF5, 0x0C, 0x16, 0xDD, 0x8B, 0xEC, 0x34, 0x8E, + 0x9C, 0x2A, 0x1C, 0x00, 0x15, 0x17, 0x8D, 0x68, 0x83, 0xD2, 0x70, 0x9F, + 0x18, 0x08, 0xCD, 0x11, 0x68, 0xD5, 0xC9, 0x6B, 0x52, 0xCD, 0xC4, 0x46, + 0x8F, 0xDC, 0xB5, 0xF3, 0xD8, 0x57, 0x73, 0x1E, 0xE9, 0x94, 0x39, 0x04, + 0xBF, 0xD3, 0xDE, 0x38, 0xDE, 0xB4, 0x53, 0xEC, 0x69, 0x1C, 0xA2, 0x7E, + 0xC4, 0x8F, 0xE4, 0x1B, 0x70, 0xAD, 0xF2, 0xA2, 0xF9, 0xFB, 0xF7, 0x16, + 0x64, 0x66, 0x69, 0x9F, 0x49, 0x51, 0xA2, 0xE2, 0x15, 0x18, 0x67, 0x06, + 0x4A, 0x7F, 0xD5, 0x6C, 0xB5, 0x4D, 0xB3, 0x33, 0xE0, 0x61, 0xEB, 0x5D, + 0xBE, 0xE9, 0x98, 0x0F, 0x32, 0xD7, 0x1D, 0x4B, 0x3C, 0x2E, 0x5A, 0x01, + 0x52, 0x91, 0x09, 0xF2, 0xDF, 0xEA, 0x8D, 0xD8, 0x06, 0x40, 0x63, 0xAA, + 0x11, 0xE4, 0xFE, 0xC3, 0x37, 0x9E, 0x14, 0x52, 0x3F, 0xF4, 0xE2, 0xCC, + 0xF2, 0x61, 0x93, 0xD1, 0xFD, 0x67, 0x6B, 0xD7, 0x52, 0xAE, 0xBF, 0x68, + 0xAB, 0x40, 0x43, 0xA0, 0x57, 0x35, 0x53, 0x78, 0xF0, 0x53, 0xF8, 0x61, + 0x42, 0x07, 0x64, 0xC6, 0xD7, 0x6F, 0x9B, 0x4C, 0x38, 0x0D, 0x63, 0xAC, + 0x62, 0xAF, 0x36, 0x8B, 0xA2, 0x73, 0x0A, 0x0D, 0xF5, 0x21, 0xBD, 0x74, + 0xAA, 0x4D, 0xEA, 0x72, 0x03, 0x49, 0xDB, 0xC7, 0x5F, 0x1D, 0x62, 0x63, + 0xC7, 0xFD, 0xDD, 0x91, 0xEC, 0x33, 0xEE, 0xF5, 0x6D, 0xB4, 0x6E, 0x30, + 0x68, 0xDE, 0xC8, 0xD6, 0x26, 0xB0, 0x75, 0x5E, 0x7B, 0xB4, 0x07, 0x20, + 0x98, 0xA1, 0x76, 0x32, 0xB8, 0x4D, 0x6C, 0x4F +}; + +static const unsigned char TA413_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA414_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA414_RSA_N[] = { + 0xA5, 0xDA, 0x0A, 0x95, 0x16, 0x50, 0xE3, 0x95, 0xF2, 0x5E, 0x9D, 0x76, + 0x31, 0x06, 0x32, 0x7A, 0x9B, 0xF1, 0x10, 0x76, 0xB8, 0x00, 0x9A, 0xB5, + 0x52, 0x36, 0xCD, 0x24, 0x47, 0xB0, 0x9F, 0x18, 0x64, 0xBC, 0x9A, 0xF6, + 0xFA, 0xD5, 0x79, 0xD8, 0x90, 0x62, 0x4C, 0x22, 0x2F, 0xDE, 0x38, 0x3D, + 0xD6, 0xE0, 0xA8, 0xE9, 0x1C, 0x2C, 0xDB, 0x78, 0x11, 0xE9, 0x8E, 0x68, + 0x51, 0x15, 0x72, 0xC7, 0xF3, 0x33, 0x87, 0xE4, 0xA0, 0x5D, 0x0B, 0x5C, + 0xE0, 0x57, 0x07, 0x2A, 0x30, 0xF5, 0xCD, 0xC4, 0x37, 0x77, 0x28, 0x4D, + 0x18, 0x91, 0xE6, 0xBF, 0xD5, 0x52, 0xFD, 0x71, 0x2D, 0x70, 0x3E, 0xE7, + 0xC6, 0xC4, 0x8A, 0xE3, 0xF0, 0x28, 0x0B, 0xF4, 0x76, 0x98, 0xA1, 0x8B, + 0x87, 0x55, 0xB2, 0x3A, 0x13, 0xFC, 0xB7, 0x3E, 0x27, 0x37, 0x8E, 0x22, + 0xE3, 0xA8, 0x4F, 0x2A, 0xEF, 0x60, 0xBB, 0x3D, 0xB7, 0x39, 0xC3, 0x0E, + 0x01, 0x47, 0x99, 0x5D, 0x12, 0x4F, 0xDB, 0x43, 0xFA, 0x57, 0xA1, 0xED, + 0xF9, 0x9D, 0xBE, 0x11, 0x47, 0x26, 0x5B, 0x13, 0x98, 0xAB, 0x5D, 0x16, + 0x8A, 0xB0, 0x37, 0x1C, 0x57, 0x9D, 0x45, 0xFF, 0x88, 0x96, 0x36, 0xBF, + 0xBB, 0xCA, 0x07, 0x7B, 0x6F, 0x87, 0x63, 0xD7, 0xD0, 0x32, 0x6A, 0xD6, + 0x5D, 0x6C, 0x0C, 0xF1, 0xB3, 0x6E, 0x39, 0xE2, 0x6B, 0x31, 0x2E, 0x39, + 0x00, 0x27, 0x14, 0xDE, 0x38, 0xC0, 0xEC, 0x19, 0x66, 0x86, 0x12, 0xE8, + 0x9D, 0x72, 0x16, 0x13, 0x64, 0x52, 0xC7, 0xA9, 0x37, 0x1C, 0xFD, 0x82, + 0x30, 0xED, 0x84, 0x18, 0x1D, 0xF4, 0xAE, 0x5C, 0xFF, 0x70, 0x13, 0x00, + 0xEB, 0xB1, 0xF5, 0x33, 0x7A, 0x4B, 0xD6, 0x55, 0xF8, 0x05, 0x8D, 0x4B, + 0x69, 0xB0, 0xF5, 0xB3, 0x28, 0x36, 0x5C, 0x14, 0xC4, 0x51, 0x73, 0x4D, + 0x6B, 0x0B, 0xF1, 0x34, 0x07, 0xDB, 0x17, 0x39, 0xD7, 0xDC, 0x28, 0x7B, + 0x6B, 0xF5, 0x9F, 0xF3, 0x2E, 0xC1, 0x4F, 0x17, 0x2A, 0x10, 0xF3, 0xCC, + 0xCA, 0xE8, 0xEB, 0xFD, 0x6B, 0xAB, 0x2E, 0x9A, 0x9F, 0x2D, 0x82, 0x6E, + 0x04, 0xD4, 0x52, 0x01, 0x93, 0x2D, 0x3D, 0x86, 0xFC, 0x7E, 0xFC, 0xDF, + 0xEF, 0x42, 0x1D, 0xA6, 0x6B, 0xEF, 0xB9, 0x20, 0xC6, 0xF7, 0xBD, 0xA0, + 0xA7, 0x95, 0xFD, 0xA7, 0xE6, 0x89, 0x24, 0xD8, 0xCC, 0x8C, 0x34, 0x6C, + 0xE2, 0x23, 0x2F, 0xD9, 0x12, 0x1A, 0x21, 0xB9, 0x55, 0x91, 0x6F, 0x0B, + 0x91, 0x79, 0x19, 0x0C, 0xAD, 0x40, 0x88, 0x0B, 0x70, 0xE2, 0x7A, 0xD2, + 0x0E, 0xD8, 0x68, 0x48, 0xBB, 0x82, 0x13, 0x39, 0x10, 0x58, 0xE9, 0xD8, + 0x2A, 0x07, 0xC6, 0x12, 0xDB, 0x58, 0xDB, 0xD2, 0x3B, 0x55, 0x10, 0x47, + 0x05, 0x15, 0x67, 0x62, 0x7E, 0x18, 0x63, 0xA6, 0x46, 0x3F, 0x09, 0x0E, + 0x54, 0x32, 0x5E, 0xBF, 0x0D, 0x62, 0x7A, 0x27, 0xEF, 0x80, 0xE8, 0xDB, + 0xD9, 0x4B, 0x06, 0x5A, 0x37, 0x5A, 0x25, 0xD0, 0x08, 0x12, 0x77, 0xD4, + 0x6F, 0x09, 0x50, 0x97, 0x3D, 0xC8, 0x1D, 0xC3, 0xDF, 0x8C, 0x45, 0x30, + 0x56, 0xC6, 0xD3, 0x64, 0xAB, 0x66, 0xF3, 0xC0, 0x5E, 0x96, 0x9C, 0xC3, + 0xC4, 0xEF, 0xC3, 0x7C, 0x6B, 0x8B, 0x3A, 0x79, 0x7F, 0xB3, 0x49, 0xCF, + 0x3D, 0xE2, 0x89, 0x9F, 0xA0, 0x30, 0x4B, 0x85, 0xB9, 0x9C, 0x94, 0x24, + 0x79, 0x8F, 0x7D, 0x6B, 0xA9, 0x45, 0x68, 0x0F, 0x2B, 0xD0, 0xF1, 0xDA, + 0x1C, 0xCB, 0x69, 0xB8, 0xCA, 0x49, 0x62, 0x6D, 0xC8, 0xD0, 0x63, 0x62, + 0xDD, 0x60, 0x0F, 0x58, 0xAA, 0x8F, 0xA1, 0xBC, 0x05, 0xA5, 0x66, 0xA2, + 0xCF, 0x1B, 0x76, 0xB2, 0x84, 0x64, 0xB1, 0x4C, 0x39, 0x52, 0xC0, 0x30, + 0xBA, 0xF0, 0x8C, 0x4B, 0x02, 0xB0, 0xB6, 0xB7 +}; + +static const unsigned char TA414_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA415_DN[] = { + 0x30, 0x52, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x53, 0x4B, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x0A, 0x42, 0x72, 0x61, 0x74, 0x69, 0x73, 0x6C, 0x61, 0x76, 0x61, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x61, 0x2E, 0x73, 0x2E, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x41, 0x20, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x32 +}; + +static const unsigned char TA415_RSA_N[] = { + 0xA2, 0xA3, 0xC4, 0x00, 0x09, 0xD6, 0x85, 0x5D, 0x2D, 0x6D, 0x14, 0xF6, + 0xC2, 0xC3, 0x73, 0x9E, 0x35, 0xC2, 0x71, 0x55, 0x7E, 0x81, 0xFB, 0xAB, + 0x46, 0x50, 0xE0, 0xC1, 0x7C, 0x49, 0x78, 0xE6, 0xAB, 0x79, 0x58, 0x3C, + 0xDA, 0xFF, 0x7C, 0x1C, 0x9F, 0xD8, 0x97, 0x02, 0x78, 0x3E, 0x6B, 0x41, + 0x04, 0xE9, 0x41, 0xBD, 0xBE, 0x03, 0x2C, 0x45, 0xF6, 0x2F, 0x64, 0xD4, + 0xAB, 0x5D, 0xA3, 0x47, 0x3D, 0x64, 0x9B, 0xE9, 0x68, 0x9A, 0xC6, 0xCC, + 0x1B, 0x3F, 0xBA, 0xBE, 0xB2, 0x8B, 0x34, 0x02, 0x2E, 0x98, 0x55, 0x19, + 0xFC, 0x8C, 0x6F, 0xAA, 0x5F, 0xDA, 0x4C, 0xCE, 0x4D, 0x03, 0x21, 0xA3, + 0xD8, 0xD2, 0x34, 0x93, 0x56, 0x96, 0xCB, 0x4C, 0x0C, 0x00, 0x16, 0x3C, + 0x5F, 0x1A, 0xCD, 0xC8, 0xC7, 0x6C, 0xA6, 0xAD, 0xD3, 0x31, 0xA7, 0xBC, + 0xE8, 0xE5, 0xE1, 0x66, 0xD6, 0xD2, 0xFB, 0x03, 0xB4, 0x41, 0x65, 0xC9, + 0x10, 0xAE, 0x0E, 0x05, 0x63, 0xC6, 0x80, 0x6A, 0x69, 0x30, 0xFD, 0xD2, + 0xEE, 0x90, 0xEF, 0x0D, 0x27, 0xDF, 0x9F, 0x95, 0x73, 0xF4, 0xE1, 0x25, + 0xDA, 0x6C, 0x16, 0xDE, 0x41, 0x38, 0x34, 0xEA, 0x8B, 0xFC, 0xD1, 0xE8, + 0x04, 0x14, 0x61, 0x2D, 0x41, 0x7E, 0xAC, 0xC7, 0x77, 0x4E, 0xCB, 0x51, + 0x54, 0xFB, 0x5E, 0x92, 0x18, 0x1B, 0x04, 0x5A, 0x68, 0xC6, 0xC9, 0xC4, + 0xFA, 0xB7, 0x13, 0xA0, 0x98, 0xB7, 0x11, 0x2B, 0xB7, 0xD6, 0x57, 0xCC, + 0x7C, 0x9E, 0x17, 0xD1, 0xCB, 0x25, 0xFE, 0x86, 0x4E, 0x24, 0x2E, 0x56, + 0x0C, 0x78, 0x4D, 0x9E, 0x01, 0x12, 0xA6, 0x2B, 0xA7, 0x01, 0x65, 0x6E, + 0x7C, 0x62, 0x1D, 0x84, 0x84, 0xDF, 0xEA, 0xC0, 0x6B, 0xB5, 0xA5, 0x2A, + 0x95, 0x83, 0xC3, 0x53, 0x11, 0x0C, 0x73, 0x1D, 0x0B, 0xB2, 0x46, 0x90, + 0xD1, 0x42, 0x3A, 0xCE, 0x40, 0x6E, 0x95, 0xAD, 0xFF, 0xC6, 0x94, 0xAD, + 0x6E, 0x97, 0x84, 0x8E, 0x7D, 0x6F, 0x9E, 0x8A, 0x80, 0x0D, 0x49, 0x6D, + 0x73, 0xE2, 0x7B, 0x92, 0x1E, 0xC3, 0xF3, 0xC1, 0xF3, 0xEB, 0x2E, 0x05, + 0x6F, 0xD9, 0x1B, 0xCF, 0x37, 0x76, 0x04, 0xC8, 0xB4, 0x5A, 0xE4, 0x17, + 0xA7, 0xCB, 0xDD, 0x76, 0x1F, 0xD0, 0x19, 0x76, 0xE8, 0x2C, 0x05, 0xB3, + 0xD6, 0x9C, 0x34, 0xD8, 0x96, 0xDC, 0x61, 0x87, 0x91, 0x05, 0xE4, 0x44, + 0x08, 0x33, 0xC1, 0xDA, 0xB9, 0x08, 0x65, 0xD4, 0xAE, 0xB2, 0x36, 0x0D, + 0xEB, 0xBA, 0x38, 0xBA, 0x0C, 0xE5, 0x9B, 0x9E, 0xEB, 0x8D, 0x66, 0xDD, + 0x99, 0xCF, 0xD6, 0x89, 0x41, 0xF6, 0x04, 0x92, 0x8A, 0x29, 0x29, 0x6D, + 0x6B, 0x3A, 0x1C, 0xE7, 0x75, 0x7D, 0x02, 0x71, 0x0E, 0xF3, 0xC0, 0xE7, + 0xBD, 0xCB, 0x19, 0xDD, 0x9D, 0x60, 0xB2, 0xC2, 0x66, 0x60, 0xB6, 0xB1, + 0x04, 0xEE, 0xC9, 0xE6, 0x86, 0xB9, 0x9A, 0x66, 0x40, 0xA8, 0xE7, 0x11, + 0xED, 0x81, 0x45, 0x03, 0x8B, 0xF6, 0x67, 0x59, 0xE8, 0xC1, 0x06, 0x11, + 0xBD, 0xDD, 0xCF, 0x80, 0x02, 0x4F, 0x65, 0x40, 0x78, 0x5C, 0x47, 0x50, + 0xC8, 0x9B, 0xE6, 0x1F, 0x81, 0x7B, 0xE4, 0x44, 0xA8, 0x5B, 0x85, 0x9A, + 0xE2, 0xDE, 0x5A, 0xD5, 0xC7, 0xF9, 0x3A, 0x44, 0x66, 0x4B, 0xE4, 0x32, + 0x54, 0x7C, 0xE4, 0x6C, 0x9C, 0xB3, 0x0E, 0x3D, 0x17, 0xA2, 0xB2, 0x34, + 0x12, 0xD6, 0x7E, 0xB2, 0xA8, 0x49, 0xBB, 0xD1, 0x7A, 0x28, 0x40, 0xBE, + 0xA2, 0x16, 0x1F, 0xDF, 0xE4, 0x37, 0x1F, 0x11, 0x73, 0xFB, 0x90, 0x0A, + 0x65, 0x43, 0xA2, 0x0D, 0x7C, 0xF8, 0x06, 0x01, 0x55, 0x33, 0x7D, 0xB0, + 0x0D, 0xB8, 0xF4, 0xF5, 0xAE, 0xA5, 0x42, 0x57, 0x7C, 0x36, 0x11, 0x8C, + 0x7B, 0x5E, 0xC4, 0x03, 0x9D, 0x8C, 0x79, 0x9D +}; + +static const unsigned char TA415_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA416_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x30, 0x30, 0x2E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x27, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x61, + 0x6E, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0C, 0x43, 0x46, 0x43, 0x41, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA416_RSA_N[] = { + 0xD7, 0x5D, 0x6B, 0xCD, 0x10, 0x3F, 0x1F, 0x05, 0x59, 0xD5, 0x05, 0x4D, + 0x37, 0xB1, 0x0E, 0xEC, 0x98, 0x2B, 0x8E, 0x15, 0x1D, 0xFA, 0x93, 0x4B, + 0x17, 0x82, 0x21, 0x71, 0x10, 0x52, 0xD7, 0x51, 0x64, 0x70, 0x16, 0xC2, + 0x55, 0x69, 0x4D, 0x8E, 0x15, 0x6D, 0x9F, 0xBF, 0x0C, 0x1B, 0xC2, 0xE0, + 0xA3, 0x67, 0xD6, 0x0C, 0xAC, 0xCF, 0x22, 0xAE, 0xAF, 0x77, 0x54, 0x2A, + 0x4B, 0x4C, 0x8A, 0x53, 0x52, 0x7A, 0xC3, 0xEE, 0x2E, 0xDE, 0xB3, 0x71, + 0x25, 0xC1, 0xE9, 0x5D, 0x3D, 0xEE, 0xA1, 0x2F, 0xA3, 0xF7, 0x2A, 0x3C, + 0xC9, 0x23, 0x1D, 0x6A, 0xAB, 0x1D, 0xA1, 0xA7, 0xF1, 0xF3, 0xEC, 0xA0, + 0xD5, 0x44, 0xCF, 0x15, 0xCF, 0x72, 0x2F, 0x1D, 0x63, 0x97, 0xE8, 0x99, + 0xF9, 0xFD, 0x93, 0xA4, 0x54, 0x80, 0x4C, 0x52, 0xD4, 0x52, 0xAB, 0x2E, + 0x49, 0xDF, 0x90, 0xCD, 0xB8, 0x5F, 0xBE, 0x3F, 0xDE, 0xA1, 0xCA, 0x4D, + 0x20, 0xD4, 0x25, 0xE8, 0x84, 0x29, 0x53, 0xB7, 0xB1, 0x88, 0x1F, 0xFF, + 0xFA, 0xDA, 0x90, 0x9F, 0x0A, 0xA9, 0x2D, 0x41, 0x3F, 0xB1, 0xF1, 0x18, + 0x29, 0xEE, 0x16, 0x59, 0x2C, 0x34, 0x49, 0x1A, 0xA8, 0x06, 0xD7, 0xA8, + 0x88, 0xD2, 0x03, 0x72, 0x7A, 0x32, 0xE2, 0xEA, 0x68, 0x4D, 0x6E, 0x2C, + 0x96, 0x65, 0x7B, 0xCA, 0x59, 0xFA, 0xF2, 0xE2, 0xDD, 0xEE, 0x30, 0x2C, + 0xFB, 0xCC, 0x46, 0xAC, 0xC4, 0x63, 0xEB, 0x6F, 0x7F, 0x36, 0x2B, 0x34, + 0x73, 0x12, 0x94, 0x7F, 0xDF, 0xCC, 0x26, 0x9E, 0xF1, 0x72, 0x5D, 0x50, + 0x65, 0x59, 0x8F, 0x69, 0xB3, 0x87, 0x5E, 0x32, 0x6F, 0xC3, 0x18, 0x8A, + 0xB5, 0x95, 0x8F, 0xB0, 0x7A, 0x37, 0xDE, 0x5A, 0x45, 0x3B, 0xC7, 0x36, + 0xE1, 0xEF, 0x67, 0xD1, 0x39, 0xD3, 0x97, 0x5B, 0x73, 0x62, 0x19, 0x48, + 0x2D, 0x87, 0x1C, 0x06, 0xFB, 0x74, 0x98, 0x20, 0x49, 0x73, 0xF0, 0x05, + 0xD2, 0x1B, 0xB1, 0xA0, 0xA3, 0xB7, 0x1B, 0x70, 0xD3, 0x88, 0x69, 0xB9, + 0x5A, 0xD6, 0x38, 0xF4, 0x62, 0xDC, 0x25, 0x8B, 0x78, 0xBF, 0xF8, 0xE8, + 0x7E, 0xB8, 0x5C, 0xC9, 0x95, 0x4F, 0x5F, 0xA7, 0x2D, 0xB9, 0x20, 0x6B, + 0xCF, 0x6B, 0xDD, 0xF5, 0x0D, 0xF4, 0x82, 0xB7, 0xF4, 0xB2, 0x66, 0x2E, + 0x10, 0x28, 0xF6, 0x97, 0x5A, 0x7B, 0x96, 0x16, 0x8F, 0x01, 0x19, 0x2D, + 0x6C, 0x6E, 0x7F, 0x39, 0x58, 0x06, 0x64, 0x83, 0x01, 0x83, 0x83, 0xC3, + 0x4D, 0x92, 0xDD, 0x32, 0xC6, 0x87, 0xA4, 0x37, 0xE9, 0x16, 0xCE, 0xAA, + 0x2D, 0x68, 0xAF, 0x0A, 0x81, 0x65, 0x3A, 0x70, 0xC1, 0x9B, 0xAD, 0x4D, + 0x6D, 0x54, 0xCA, 0x2A, 0x2D, 0x4B, 0x85, 0x1B, 0xB3, 0x80, 0xE6, 0x70, + 0x45, 0x0D, 0x6B, 0x5E, 0x35, 0xF0, 0x7F, 0x3B, 0xB8, 0x9C, 0xE4, 0x04, + 0x70, 0x89, 0x12, 0x25, 0x93, 0xDA, 0x0A, 0x99, 0x22, 0x60, 0x6A, 0x63, + 0x60, 0x4E, 0x76, 0x06, 0x98, 0x4E, 0xBD, 0x83, 0xAD, 0x1D, 0x58, 0x8A, + 0x25, 0x85, 0xD2, 0xC7, 0x65, 0x1E, 0x2D, 0x8E, 0xC6, 0xDF, 0xB6, 0xC6, + 0xE1, 0x7F, 0x8A, 0x04, 0x21, 0x15, 0x29, 0x74, 0xF0, 0x3E, 0x9C, 0x90, + 0x9D, 0x0C, 0x2E, 0xF1, 0x8A, 0x3E, 0x5A, 0xAA, 0x0C, 0x09, 0x1E, 0xC7, + 0xD5, 0x3C, 0xA3, 0xED, 0x97, 0xC3, 0x1E, 0x34, 0xFA, 0x38, 0xF9, 0x08, + 0x0E, 0xE3, 0xC0, 0x5D, 0x2B, 0x83, 0xD1, 0x56, 0x6A, 0xC9, 0xB6, 0xA8, + 0x54, 0x53, 0x2E, 0x78, 0x32, 0x67, 0x3D, 0x82, 0x7F, 0x74, 0xD0, 0xFB, + 0xE1, 0xB6, 0x05, 0x60, 0xB9, 0x70, 0xDB, 0x8E, 0x0B, 0xF9, 0x13, 0x58, + 0x6F, 0x71, 0x60, 0x10, 0x52, 0x10, 0xB9, 0xC1, 0x41, 0x09, 0xEF, 0x72, + 0x1F, 0x67, 0x31, 0x78, 0xFF, 0x96, 0x05, 0x8D +}; + +static const unsigned char TA416_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA417_DN[] = { + 0x30, 0x81, 0x81, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA417_RSA_N[] = { + 0xD0, 0x40, 0x8B, 0x8B, 0x72, 0xE3, 0x91, 0x1B, 0xF7, 0x51, 0xC1, 0x1B, + 0x54, 0x04, 0x98, 0xD3, 0xA9, 0xBF, 0xC1, 0xE6, 0x8A, 0x5D, 0x3B, 0x87, + 0xFB, 0xBB, 0x88, 0xCE, 0x0D, 0xE3, 0x2F, 0x3F, 0x06, 0x96, 0xF0, 0xA2, + 0x29, 0x50, 0x99, 0xAE, 0xDB, 0x3B, 0xA1, 0x57, 0xB0, 0x74, 0x51, 0x71, + 0xCD, 0xED, 0x42, 0x91, 0x4D, 0x41, 0xFE, 0xA9, 0xC8, 0xD8, 0x6A, 0x86, + 0x77, 0x44, 0xBB, 0x59, 0x66, 0x97, 0x50, 0x5E, 0xB4, 0xD4, 0x2C, 0x70, + 0x44, 0xCF, 0xDA, 0x37, 0x95, 0x42, 0x69, 0x3C, 0x30, 0xC4, 0x71, 0xB3, + 0x52, 0xF0, 0x21, 0x4D, 0xA1, 0xD8, 0xBA, 0x39, 0x7C, 0x1C, 0x9E, 0xA3, + 0x24, 0x9D, 0xF2, 0x83, 0x16, 0x98, 0xAA, 0x16, 0x7C, 0x43, 0x9B, 0x15, + 0x5B, 0xB7, 0xAE, 0x34, 0x91, 0xFE, 0xD4, 0x62, 0x26, 0x18, 0x46, 0x9A, + 0x3F, 0xEB, 0xC1, 0xF9, 0xF1, 0x90, 0x57, 0xEB, 0xAC, 0x7A, 0x0D, 0x8B, + 0xDB, 0x72, 0x30, 0x6A, 0x66, 0xD5, 0xE0, 0x46, 0xA3, 0x70, 0xDC, 0x68, + 0xD9, 0xFF, 0x04, 0x48, 0x89, 0x77, 0xDE, 0xB5, 0xE9, 0xFB, 0x67, 0x6D, + 0x41, 0xE9, 0xBC, 0x39, 0xBD, 0x32, 0xD9, 0x62, 0x02, 0xF1, 0xB1, 0xA8, + 0x3D, 0x6E, 0x37, 0x9C, 0xE2, 0x2F, 0xE2, 0xD3, 0xA2, 0x26, 0x8B, 0xC6, + 0xB8, 0x55, 0x43, 0x88, 0xE1, 0x23, 0x3E, 0xA5, 0xD2, 0x24, 0x39, 0x6A, + 0x47, 0xAB, 0x00, 0xD4, 0xA1, 0xB3, 0xA9, 0x25, 0xFE, 0x0D, 0x3F, 0xA7, + 0x1D, 0xBA, 0xD3, 0x51, 0xC1, 0x0B, 0xA4, 0xDA, 0xAC, 0x38, 0xEF, 0x55, + 0x50, 0x24, 0x05, 0x65, 0x46, 0x93, 0x34, 0x4F, 0x2D, 0x8D, 0xAD, 0xC6, + 0xD4, 0x21, 0x19, 0xD2, 0x8E, 0xCA, 0x05, 0x61, 0x71, 0x07, 0x73, 0x47, + 0xE5, 0x8A, 0x19, 0x12, 0xBD, 0x04, 0x4D, 0xCE, 0x4E, 0x9C, 0xA5, 0x48, + 0xAC, 0xBB, 0x26, 0xF7 +}; + +static const unsigned char TA417_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA418_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA418_EC_Q[] = { + 0x04, 0x03, 0x47, 0x7B, 0x2F, 0x75, 0xC9, 0x82, 0x15, 0x85, 0xFB, 0x75, + 0xE4, 0x91, 0x16, 0xD4, 0xAB, 0x62, 0x99, 0xF5, 0x3E, 0x52, 0x0B, 0x06, + 0xCE, 0x41, 0x00, 0x7F, 0x97, 0xE1, 0x0A, 0x24, 0x3C, 0x1D, 0x01, 0x04, + 0xEE, 0x3D, 0xD2, 0x8D, 0x09, 0x97, 0x0C, 0xE0, 0x75, 0xE4, 0xFA, 0xFB, + 0x77, 0x8A, 0x2A, 0xF5, 0x03, 0x60, 0x4B, 0x36, 0x8B, 0x16, 0x23, 0x16, + 0xAD, 0x09, 0x71, 0xF4, 0x4A, 0xF4, 0x28, 0x50, 0xB4, 0xFE, 0x88, 0x1C, + 0x6E, 0x3F, 0x6C, 0x2F, 0x2F, 0x09, 0x59, 0x5B, 0xA5, 0x5B, 0x0B, 0x33, + 0x99, 0xE2, 0xC3, 0x3D, 0x89, 0xF9, 0x6A, 0x2C, 0xEF, 0xB2, 0xD3, 0x06, + 0xE9 +}; + +static const unsigned char TA419_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA419_RSA_N[] = { + 0x91, 0xE8, 0x54, 0x92, 0xD2, 0x0A, 0x56, 0xB1, 0xAC, 0x0D, 0x24, 0xDD, + 0xC5, 0xCF, 0x44, 0x67, 0x74, 0x99, 0x2B, 0x37, 0xA3, 0x7D, 0x23, 0x70, + 0x00, 0x71, 0xBC, 0x53, 0xDF, 0xC4, 0xFA, 0x2A, 0x12, 0x8F, 0x4B, 0x7F, + 0x10, 0x56, 0xBD, 0x9F, 0x70, 0x72, 0xB7, 0x61, 0x7F, 0xC9, 0x4B, 0x0F, + 0x17, 0xA7, 0x3D, 0xE3, 0xB0, 0x04, 0x61, 0xEE, 0xFF, 0x11, 0x97, 0xC7, + 0xF4, 0x86, 0x3E, 0x0A, 0xFA, 0x3E, 0x5C, 0xF9, 0x93, 0xE6, 0x34, 0x7A, + 0xD9, 0x14, 0x6B, 0xE7, 0x9C, 0xB3, 0x85, 0xA0, 0x82, 0x7A, 0x76, 0xAF, + 0x71, 0x90, 0xD7, 0xEC, 0xFD, 0x0D, 0xFA, 0x9C, 0x6C, 0xFA, 0xDF, 0xB0, + 0x82, 0xF4, 0x14, 0x7E, 0xF9, 0xBE, 0xC4, 0xA6, 0x2F, 0x4F, 0x7F, 0x99, + 0x7F, 0xB5, 0xFC, 0x67, 0x43, 0x72, 0xBD, 0x0C, 0x00, 0xD6, 0x89, 0xEB, + 0x6B, 0x2C, 0xD3, 0xED, 0x8F, 0x98, 0x1C, 0x14, 0xAB, 0x7E, 0xE5, 0xE3, + 0x6E, 0xFC, 0xD8, 0xA8, 0xE4, 0x92, 0x24, 0xDA, 0x43, 0x6B, 0x62, 0xB8, + 0x55, 0xFD, 0xEA, 0xC1, 0xBC, 0x6C, 0xB6, 0x8B, 0xF3, 0x0E, 0x8D, 0x9A, + 0xE4, 0x9B, 0x6C, 0x69, 0x99, 0xF8, 0x78, 0x48, 0x30, 0x45, 0xD5, 0xAD, + 0xE1, 0x0D, 0x3C, 0x45, 0x60, 0xFC, 0x32, 0x96, 0x51, 0x27, 0xBC, 0x67, + 0xC3, 0xCA, 0x2E, 0xB6, 0x6B, 0xEA, 0x46, 0xC7, 0xC7, 0x20, 0xA0, 0xB1, + 0x1F, 0x65, 0xDE, 0x48, 0x08, 0xBA, 0xA4, 0x4E, 0xA9, 0xF2, 0x83, 0x46, + 0x37, 0x84, 0xEB, 0xE8, 0xCC, 0x81, 0x48, 0x43, 0x67, 0x4E, 0x72, 0x2A, + 0x9B, 0x5C, 0xBD, 0x4C, 0x1B, 0x28, 0x8A, 0x5C, 0x22, 0x7B, 0xB4, 0xAB, + 0x98, 0xD9, 0xEE, 0xE0, 0x51, 0x83, 0xC3, 0x09, 0x46, 0x4E, 0x6D, 0x3E, + 0x99, 0xFA, 0x95, 0x17, 0xDA, 0x7C, 0x33, 0x57, 0x41, 0x3C, 0x8D, 0x51, + 0xED, 0x0B, 0xB6, 0x5C, 0xAF, 0x2C, 0x63, 0x1A, 0xDF, 0x57, 0xC8, 0x3F, + 0xBC, 0xE9, 0x5D, 0xC4, 0x9B, 0xAF, 0x45, 0x99, 0xE2, 0xA3, 0x5A, 0x24, + 0xB4, 0xBA, 0xA9, 0x56, 0x3D, 0xCF, 0x6F, 0xAA, 0xFF, 0x49, 0x58, 0xBE, + 0xF0, 0xA8, 0xFF, 0xF4, 0xB8, 0xAD, 0xE9, 0x37, 0xFB, 0xBA, 0xB8, 0xF4, + 0x0B, 0x3A, 0xF9, 0xE8, 0x43, 0x42, 0x1E, 0x89, 0xD8, 0x84, 0xCB, 0x13, + 0xF1, 0xD9, 0xBB, 0xE1, 0x89, 0x60, 0xB8, 0x8C, 0x28, 0x56, 0xAC, 0x14, + 0x1D, 0x9C, 0x0A, 0xE7, 0x71, 0xEB, 0xCF, 0x0E, 0xDD, 0x3D, 0xA9, 0x96, + 0xA1, 0x48, 0xBD, 0x3C, 0xF7, 0xAF, 0xB5, 0x0D, 0x22, 0x4C, 0xC0, 0x11, + 0x81, 0xEC, 0x56, 0x3B, 0xF6, 0xD3, 0xA2, 0xE2, 0x5B, 0xB7, 0xB2, 0x04, + 0x22, 0x52, 0x95, 0x80, 0x93, 0x69, 0xE8, 0x8E, 0x4C, 0x65, 0xF1, 0x91, + 0x03, 0x2D, 0x70, 0x74, 0x02, 0xEA, 0x8B, 0x67, 0x15, 0x29, 0x69, 0x52, + 0x02, 0xBB, 0xD7, 0xDF, 0x50, 0x6A, 0x55, 0x46, 0xBF, 0xA0, 0xA3, 0x28, + 0x61, 0x7F, 0x70, 0xD0, 0xC3, 0xA2, 0xAA, 0x2C, 0x21, 0xAA, 0x47, 0xCE, + 0x28, 0x9C, 0x06, 0x45, 0x76, 0xBF, 0x82, 0x18, 0x27, 0xB4, 0xD5, 0xAE, + 0xB4, 0xCB, 0x50, 0xE6, 0x6B, 0xF4, 0x4C, 0x86, 0x71, 0x30, 0xE9, 0xA6, + 0xDF, 0x16, 0x86, 0xE0, 0xD8, 0xFF, 0x40, 0xDD, 0xFB, 0xD0, 0x42, 0x88, + 0x7F, 0xA3, 0x33, 0x3A, 0x2E, 0x5C, 0x1E, 0x41, 0x11, 0x81, 0x63, 0xCE, + 0x18, 0x71, 0x6B, 0x2B, 0xEC, 0xA6, 0x8A, 0xB7, 0x31, 0x5C, 0x3A, 0x6A, + 0x47, 0xE0, 0xC3, 0x79, 0x59, 0xD6, 0x20, 0x1A, 0xAF, 0xF2, 0x6A, 0x98, + 0xAA, 0x72, 0xBC, 0x57, 0x4A, 0xD2, 0x4B, 0x9D, 0xBB, 0x10, 0xFC, 0xB0, + 0x4C, 0x41, 0xE5, 0xED, 0x1D, 0x3D, 0x5E, 0x28, 0x9D, 0x9C, 0xCC, 0xBF, + 0xB3, 0x51, 0xDA, 0xA7, 0x47, 0xE5, 0x84, 0x53 +}; + +static const unsigned char TA419_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA420_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x45, 0x31 +}; + +static const unsigned char TA420_EC_Q[] = { + 0x04, 0xDE, 0x6F, 0xF8, 0x7F, 0x1C, 0xDF, 0xED, 0xF9, 0x47, 0x87, 0x86, + 0xB1, 0xA4, 0xC0, 0x8A, 0xF8, 0x82, 0x97, 0x80, 0xEA, 0x8F, 0xC8, 0x4A, + 0x5E, 0x2A, 0x7D, 0x88, 0x68, 0xA7, 0x01, 0x62, 0x14, 0x91, 0x24, 0x7A, + 0x5C, 0x9E, 0xA3, 0x17, 0x7D, 0x8A, 0x86, 0x21, 0x34, 0x18, 0x50, 0x1B, + 0x10, 0xDE, 0xD0, 0x37, 0x4B, 0x26, 0xC7, 0x19, 0x60, 0x80, 0xE9, 0x34, + 0xBD, 0x60, 0x19, 0x36, 0x40, 0xD6, 0x29, 0x87, 0x09, 0x3C, 0x91, 0x7A, + 0xF6, 0xBC, 0x13, 0x23, 0xDD, 0x59, 0x4E, 0x04, 0x5E, 0xCF, 0xC8, 0x02, + 0x1C, 0x18, 0x53, 0xC1, 0x31, 0xD8, 0xDA, 0x20, 0xE9, 0x44, 0x8D, 0xE4, + 0x76 +}; + +static const unsigned char TA421_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x52, 0x31 +}; + +static const unsigned char TA421_RSA_N[] = { + 0xD0, 0x36, 0xD4, 0x1F, 0xEA, 0xDD, 0xAB, 0xE4, 0xD1, 0xB6, 0xE6, 0xFB, + 0x22, 0xC0, 0xDD, 0x13, 0x0D, 0x6A, 0x7B, 0x22, 0x13, 0x1C, 0x97, 0x3C, + 0x68, 0x63, 0x66, 0x32, 0x9C, 0x03, 0xB5, 0x8D, 0xA4, 0x81, 0x83, 0xDA, + 0x78, 0x30, 0x11, 0xCF, 0xDC, 0xB2, 0x2B, 0xBE, 0x92, 0xBF, 0x8E, 0xE4, + 0xC4, 0x13, 0xBE, 0xA4, 0x68, 0x4C, 0xDA, 0x02, 0x68, 0x16, 0x74, 0xBE, + 0xB2, 0xDD, 0x04, 0xE4, 0x6B, 0x2A, 0xDD, 0x37, 0x1F, 0x60, 0x2C, 0xDB, + 0xF5, 0xF7, 0xA1, 0x7C, 0x95, 0xB7, 0x0C, 0x70, 0x86, 0x2E, 0xF1, 0x3A, + 0xEF, 0x52, 0xF7, 0xCC, 0xD3, 0x9B, 0xF9, 0x8B, 0xBE, 0x0E, 0xDF, 0x31, + 0xB7, 0x9D, 0x68, 0x5C, 0x92, 0xA6, 0xF5, 0xE5, 0xF3, 0x0A, 0x34, 0xB5, + 0xFF, 0x7B, 0xA2, 0xE4, 0x87, 0xA1, 0xC6, 0xAF, 0x17, 0x00, 0xEF, 0x03, + 0x91, 0xED, 0xA9, 0x1C, 0x4E, 0x71, 0x3D, 0xD2, 0x8B, 0x6C, 0x89, 0xF4, + 0x78, 0x86, 0xE6, 0x6A, 0x49, 0xA0, 0xCE, 0xB5, 0xD2, 0xB0, 0xAB, 0x9B, + 0xF6, 0xF4, 0xD4, 0x2E, 0xE3, 0x72, 0xF9, 0x36, 0xC6, 0xEB, 0x15, 0xB7, + 0x25, 0x8C, 0x3A, 0xFC, 0x25, 0x0D, 0xB3, 0x22, 0x73, 0x21, 0x74, 0xC8, + 0x4A, 0x96, 0x61, 0x92, 0xF5, 0x2F, 0x0B, 0x18, 0xA5, 0xF4, 0xAD, 0xE2, + 0xEE, 0x41, 0xBD, 0x01, 0x79, 0xFA, 0x96, 0x8C, 0x8D, 0x17, 0x02, 0x30, + 0xB4, 0xF9, 0xAF, 0x78, 0x1A, 0x8C, 0xB4, 0x36, 0x10, 0x10, 0x07, 0x05, + 0x70, 0xD0, 0xF4, 0x31, 0x90, 0x8A, 0x51, 0xC5, 0x86, 0x26, 0x79, 0xB2, + 0x11, 0x88, 0x5E, 0xC5, 0xF0, 0x0A, 0x54, 0xCD, 0x49, 0xA6, 0xBF, 0x02, + 0x9C, 0xD2, 0x44, 0xA7, 0xED, 0xE3, 0x78, 0xEF, 0x46, 0x5E, 0x6D, 0x71, + 0xD1, 0x79, 0x70, 0x1C, 0x46, 0x5F, 0x51, 0xE9, 0xC9, 0x37, 0xDC, 0x5F, + 0x7E, 0x69, 0x7B, 0x41, 0xDF, 0x34, 0x45, 0xE0, 0x3B, 0x84, 0xF4, 0xA1, + 0x8A, 0x0A, 0x36, 0x9E, 0x37, 0xCC, 0x62, 0x52, 0xE1, 0x89, 0x0D, 0x28, + 0xF9, 0x7A, 0x23, 0xB1, 0x0D, 0x3D, 0x3D, 0x9A, 0xFD, 0x9D, 0x81, 0xEF, + 0x2C, 0x90, 0xC0, 0x7B, 0x44, 0x4E, 0xBB, 0x49, 0xE0, 0x0E, 0x4A, 0x56, + 0x92, 0xBC, 0xCB, 0xB5, 0xDD, 0x79, 0x17, 0x89, 0x91, 0xDE, 0x61, 0x89, + 0x74, 0x92, 0xA8, 0xE3, 0x32, 0x85, 0xBE, 0x4E, 0x85, 0xA4, 0x4B, 0x59, + 0xCB, 0x2B, 0xC5, 0x78, 0x8E, 0x71, 0x54, 0xD0, 0x02, 0x37, 0x99, 0x8C, + 0xE5, 0x49, 0xEA, 0xE0, 0x54, 0x72, 0xA4, 0x11, 0x06, 0x2F, 0x0B, 0x8C, + 0xC1, 0x5B, 0xBE, 0xB5, 0xA1, 0xB0, 0x53, 0x6E, 0x9C, 0xB8, 0x60, 0x91, + 0x1F, 0x59, 0x6B, 0xF9, 0x2D, 0xF4, 0x94, 0x0A, 0x97, 0xB5, 0xEC, 0xC5, + 0x76, 0x03, 0x54, 0x1B, 0x65, 0x52, 0xBA, 0x4C, 0x92, 0x56, 0x51, 0x35, + 0xA0, 0x40, 0xD8, 0x29, 0xDB, 0xAE, 0x52, 0x76, 0x3B, 0x2D, 0x30, 0x40, + 0x9B, 0x8A, 0xD0, 0x42, 0x56, 0xB4, 0xB7, 0x88, 0x01, 0xA4, 0x87, 0x3B, + 0x53, 0x96, 0xCD, 0xA3, 0x16, 0x8F, 0xF3, 0x66, 0xAA, 0x17, 0xB1, 0xC7, + 0x60, 0xE0, 0xC1, 0x43, 0x05, 0x0C, 0xEE, 0x9B, 0x5B, 0x60, 0x6F, 0x06, + 0x5C, 0x87, 0x5B, 0x27, 0xF9, 0x40, 0x11, 0x9E, 0x9C, 0x33, 0xC1, 0xB7, + 0xE5, 0x35, 0x57, 0x05, 0x7F, 0x27, 0xCE, 0x17, 0x20, 0x8C, 0x1C, 0xFC, + 0xF1, 0xFB, 0xDA, 0x31, 0x29, 0x49, 0xED, 0xF5, 0x0B, 0x84, 0xA7, 0x4F, + 0xC1, 0xF6, 0x4E, 0xC2, 0x28, 0x9C, 0xFA, 0xEE, 0xE0, 0xAF, 0x07, 0xFB, + 0x33, 0x11, 0x7A, 0x21, 0x4F, 0x0B, 0x21, 0x10, 0xB6, 0x40, 0x3A, 0xAB, + 0x22, 0x3A, 0x04, 0x9C, 0x8B, 0x9B, 0x84, 0x86, 0x72, 0x9A, 0xD2, 0xA7, + 0xA5, 0xC4, 0xB4, 0x75, 0x91, 0xA9, 0x2B, 0x23 +}; + +static const unsigned char TA421_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA422_DN[] = { + 0x30, 0x34, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x08, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61 +}; + +static const unsigned char TA422_RSA_N[] = { + 0xC8, 0x68, 0xF1, 0xC9, 0xD6, 0xD6, 0xB3, 0x34, 0x75, 0x26, 0x82, 0x1E, + 0xEC, 0xB4, 0xBE, 0xEA, 0x5C, 0xE1, 0x26, 0xED, 0x11, 0x47, 0x61, 0xE1, + 0xA2, 0x7C, 0x16, 0x78, 0x40, 0x21, 0xE4, 0x60, 0x9E, 0x5A, 0xC8, 0x63, + 0xE1, 0xC4, 0xB1, 0x96, 0x92, 0xFF, 0x18, 0x6D, 0x69, 0x23, 0xE1, 0x2B, + 0x62, 0xF7, 0xDD, 0xE2, 0x36, 0x2F, 0x91, 0x07, 0xB9, 0x48, 0xCF, 0x0E, + 0xEC, 0x79, 0xB6, 0x2C, 0xE7, 0x34, 0x4B, 0x70, 0x08, 0x25, 0xA3, 0x3C, + 0x87, 0x1B, 0x19, 0xF2, 0x81, 0x07, 0x0F, 0x38, 0x90, 0x19, 0xD3, 0x11, + 0xFE, 0x86, 0xB4, 0xF2, 0xD1, 0x5E, 0x1E, 0x1E, 0x96, 0xCD, 0x80, 0x6C, + 0xCE, 0x3B, 0x31, 0x93, 0xB6, 0xF2, 0xA0, 0xD0, 0xA9, 0x95, 0x12, 0x7D, + 0xA5, 0x9A, 0xCC, 0x6B, 0xC8, 0x84, 0x56, 0x8A, 0x33, 0xA9, 0xE7, 0x22, + 0x15, 0x53, 0x16, 0xF0, 0xCC, 0x17, 0xEC, 0x57, 0x5F, 0xE9, 0xA2, 0x0A, + 0x98, 0x09, 0xDE, 0xE3, 0x5F, 0x9C, 0x6F, 0xDC, 0x48, 0xE3, 0x85, 0x0B, + 0x15, 0x5A, 0xA6, 0xBA, 0x9F, 0xAC, 0x48, 0xE3, 0x09, 0xB2, 0xF7, 0xF4, + 0x32, 0xDE, 0x5E, 0x34, 0xBE, 0x1C, 0x78, 0x5D, 0x42, 0x5B, 0xCE, 0x0E, + 0x22, 0x8F, 0x4D, 0x90, 0xD7, 0x7D, 0x32, 0x18, 0xB3, 0x0B, 0x2C, 0x6A, + 0xBF, 0x8E, 0x3F, 0x14, 0x11, 0x89, 0x20, 0x0E, 0x77, 0x14, 0xB5, 0x3D, + 0x94, 0x08, 0x87, 0xF7, 0x25, 0x1E, 0xD5, 0xB2, 0x60, 0x00, 0xEC, 0x6F, + 0x2A, 0x28, 0x25, 0x6E, 0x2A, 0x3E, 0x18, 0x63, 0x17, 0x25, 0x3F, 0x3E, + 0x44, 0x20, 0x16, 0xF6, 0x26, 0xC8, 0x25, 0xAE, 0x05, 0x4A, 0xB4, 0xE7, + 0x63, 0x2C, 0xF3, 0x8C, 0x16, 0x53, 0x7E, 0x5C, 0xFB, 0x11, 0x1A, 0x08, + 0xC1, 0x46, 0x62, 0x9F, 0x22, 0xB8, 0xF1, 0xC2, 0x8D, 0x69, 0xDC, 0xFA, + 0x3A, 0x58, 0x06, 0xDF +}; + +static const unsigned char TA422_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA423_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x13, 0x30, 0x30, + 0x30, 0x32, 0x20, 0x34, 0x38, 0x31, 0x34, 0x36, 0x33, 0x30, 0x38, 0x31, + 0x30, 0x30, 0x30, 0x33, 0x36, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA423_RSA_N[] = { + 0xCD, 0x18, 0x39, 0x65, 0x1A, 0x59, 0xB1, 0xEA, 0x64, 0x16, 0x0E, 0x8C, + 0x94, 0x24, 0x95, 0x7C, 0x83, 0xD3, 0xC5, 0x39, 0x26, 0xDC, 0x0C, 0xEF, + 0x16, 0x57, 0x8D, 0xD7, 0xD8, 0xAC, 0xA3, 0x42, 0x7F, 0x82, 0xCA, 0xED, + 0xCD, 0x5B, 0xDB, 0x0E, 0xB7, 0x2D, 0xED, 0x45, 0x08, 0x17, 0xB2, 0xD9, + 0xB3, 0xCB, 0xD6, 0x17, 0x52, 0x72, 0x28, 0xDB, 0x8E, 0x4E, 0x9E, 0x8A, + 0xB6, 0x0B, 0xF9, 0x9E, 0x84, 0x9A, 0x4D, 0x76, 0xDE, 0x22, 0x29, 0x5C, + 0xD2, 0xB3, 0xD2, 0x06, 0x3E, 0x30, 0x39, 0xA9, 0x74, 0xA3, 0x92, 0x56, + 0x1C, 0xA1, 0x6F, 0x4C, 0x0A, 0x20, 0x6D, 0x9F, 0x23, 0x7A, 0xB4, 0xC6, + 0xDA, 0x2C, 0xE4, 0x1D, 0x2C, 0xDC, 0xB3, 0x28, 0xD0, 0x13, 0xF2, 0x4C, + 0x4E, 0x02, 0x49, 0xA1, 0x54, 0x40, 0x9E, 0xE6, 0xE5, 0x05, 0xA0, 0x2D, + 0x84, 0xC8, 0xFF, 0x98, 0x6C, 0xD0, 0xEB, 0x8A, 0x1A, 0x84, 0x08, 0x1E, + 0xB7, 0x68, 0x23, 0xEE, 0x23, 0xD5, 0x70, 0xCE, 0x6D, 0x51, 0x69, 0x10, + 0xEE, 0xA1, 0x7A, 0xC2, 0xD1, 0x22, 0x31, 0xC2, 0x82, 0x85, 0xD2, 0xF2, + 0x55, 0x76, 0x50, 0x7C, 0x25, 0x7A, 0xC9, 0x84, 0x5C, 0x0B, 0xAC, 0xDD, + 0x42, 0x4E, 0x2B, 0xE7, 0x82, 0xA2, 0x24, 0x89, 0xCB, 0x90, 0xB2, 0xD0, + 0xEE, 0x23, 0xBA, 0x66, 0x4C, 0xBB, 0x62, 0xA4, 0xF9, 0x53, 0x5A, 0x64, + 0x7B, 0x7C, 0x98, 0xFA, 0xA3, 0x48, 0x9E, 0x0F, 0x95, 0xAE, 0xA7, 0x18, + 0xF4, 0x6A, 0xEC, 0x2E, 0x03, 0x45, 0xAF, 0xF0, 0x74, 0xF8, 0x2A, 0xCD, + 0x7A, 0x5D, 0xD1, 0xBE, 0x44, 0x26, 0x32, 0x29, 0xF1, 0xF1, 0xF5, 0x6C, + 0xCC, 0x7E, 0x02, 0x21, 0x0B, 0x9F, 0x6F, 0xA4, 0x3F, 0xBE, 0x9D, 0x53, + 0xE2, 0xCF, 0x7D, 0xA9, 0x2C, 0x7C, 0x58, 0x1A, 0x97, 0xE1, 0x3D, 0x37, + 0x37, 0x18, 0x66, 0x28, 0xD2, 0x40, 0xC5, 0x51, 0x8A, 0x8C, 0xC3, 0x2D, + 0xCE, 0x53, 0x88, 0x24, 0x58, 0x64, 0x30, 0x16, 0xC5, 0xAA, 0xE0, 0xD6, + 0x0A, 0xA6, 0x40, 0xDF, 0x78, 0xF6, 0xF5, 0x04, 0x7C, 0x69, 0x13, 0x84, + 0xBC, 0xD1, 0xD1, 0xA7, 0x06, 0xCF, 0x01, 0xF7, 0x68, 0xC0, 0xA8, 0x57, + 0xBB, 0x3A, 0x61, 0xAD, 0x04, 0x8C, 0x93, 0xE3, 0xAD, 0xFC, 0xF0, 0xDB, + 0x44, 0x6D, 0x59, 0xDC, 0x49, 0x59, 0xAE, 0xAC, 0x9A, 0x99, 0x36, 0x30, + 0x41, 0x7B, 0x76, 0x33, 0x22, 0x87, 0xA3, 0xC2, 0x92, 0x86, 0x6E, 0xF9, + 0x70, 0xEE, 0xAE, 0x87, 0x87, 0x95, 0x1B, 0xC4, 0x7A, 0xBD, 0x31, 0xF3, + 0xD4, 0xD2, 0xE5, 0x99, 0xFF, 0xBE, 0x48, 0xEC, 0x75, 0xF5, 0x78, 0x16, + 0x1D, 0xA6, 0x70, 0xC1, 0x7F, 0x3C, 0x1B, 0xA1, 0x92, 0xFB, 0xCF, 0xC8, + 0x3C, 0xD6, 0xC5, 0x93, 0x0A, 0x8F, 0xF5, 0x55, 0x3A, 0x76, 0x95, 0xCE, + 0x59, 0x98, 0x8A, 0x09, 0x95, 0x77, 0x32, 0x9A, 0x83, 0xBA, 0x2C, 0x04, + 0x3A, 0x97, 0xBD, 0xD4, 0x2F, 0xBE, 0xD7, 0x6C, 0x9B, 0xA2, 0xCA, 0x7D, + 0x6D, 0x26, 0xC9, 0x55, 0xD5, 0xCF, 0xC3, 0x79, 0x52, 0x08, 0x09, 0x99, + 0x07, 0x24, 0x2D, 0x64, 0x25, 0x6B, 0xA6, 0x21, 0x69, 0x9B, 0x6A, 0xDD, + 0x74, 0x4D, 0x6B, 0x97, 0x7A, 0x41, 0xBD, 0xAB, 0x17, 0xF9, 0x90, 0x17, + 0x48, 0x8F, 0x36, 0xF9, 0x2D, 0xD5, 0xC5, 0xDB, 0xEE, 0xAA, 0x85, 0x45, + 0x41, 0xFA, 0xCD, 0x3A, 0x45, 0xB1, 0x68, 0xE6, 0x36, 0x4C, 0x9B, 0x90, + 0x57, 0xEC, 0x23, 0xB9, 0x87, 0x08, 0xC2, 0xC4, 0x09, 0xF1, 0x97, 0x86, + 0x2A, 0x28, 0x4D, 0xE2, 0x74, 0xC0, 0xDA, 0xC4, 0x8C, 0xDB, 0xDF, 0xE2, + 0xA1, 0x17, 0x59, 0xCE, 0x24, 0x59, 0x74, 0x31, 0xDA, 0x7F, 0xFD, 0x30, + 0x6D, 0xD9, 0xDC, 0xE1, 0x6A, 0xE1, 0xFC, 0x5F +}; + +static const unsigned char TA423_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA424_DN[] = { + 0x30, 0x74, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x45, 0x43, 0x2D, 0x33, 0x38, 0x34, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA424_EC_Q[] = { + 0x04, 0xC4, 0x28, 0x8E, 0xAB, 0x18, 0x5B, 0x6A, 0xBE, 0x6E, 0x64, 0x37, + 0x63, 0xE4, 0xCD, 0xEC, 0xAB, 0x3A, 0xF7, 0xCC, 0xA1, 0xB8, 0x0E, 0x82, + 0x49, 0xD7, 0x86, 0x29, 0x9F, 0xA1, 0x94, 0xF2, 0xE3, 0x60, 0x78, 0x98, + 0x81, 0x78, 0x06, 0x4D, 0xF2, 0xEC, 0x9A, 0x0E, 0x57, 0x60, 0x83, 0x9F, + 0xB4, 0xE6, 0x17, 0x2F, 0x1A, 0xB3, 0x5D, 0x02, 0x5B, 0x89, 0x23, 0x3C, + 0xC2, 0x11, 0x05, 0x2A, 0xA7, 0x88, 0x13, 0x18, 0xF3, 0x50, 0x84, 0xD7, + 0xBD, 0x34, 0x2C, 0x27, 0x89, 0x55, 0xFF, 0xCE, 0x4C, 0xE7, 0xDF, 0xA6, + 0x1F, 0x28, 0xC4, 0xF0, 0x54, 0xC3, 0xB9, 0x7C, 0xB7, 0x53, 0xAD, 0xEB, + 0xC2 +}; + +static const unsigned char TA425_DN[] = { + 0x30, 0x7E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, 0x65, + 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, + 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, + 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, 0x65, + 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA425_RSA_N[] = { + 0xE3, 0xFB, 0x7D, 0xA3, 0x72, 0xBA, 0xC2, 0xF0, 0xC9, 0x14, 0x87, 0xF5, + 0x6B, 0x01, 0x4E, 0xE1, 0x6E, 0x40, 0x07, 0xBA, 0x6D, 0x27, 0x5D, 0x7F, + 0xF7, 0x5B, 0x2D, 0xB3, 0x5A, 0xC7, 0x51, 0x5F, 0xAB, 0xA4, 0x32, 0xA6, + 0x61, 0x87, 0xB6, 0x6E, 0x0F, 0x86, 0xD2, 0x30, 0x02, 0x97, 0xF8, 0xD7, + 0x69, 0x57, 0xA1, 0x18, 0x39, 0x5D, 0x6A, 0x64, 0x79, 0xC6, 0x01, 0x59, + 0xAC, 0x3C, 0x31, 0x4A, 0x38, 0x7C, 0xD2, 0x04, 0xD2, 0x4B, 0x28, 0xE8, + 0x20, 0x5F, 0x3B, 0x07, 0xA2, 0xCC, 0x4D, 0x73, 0xDB, 0xF3, 0xAE, 0x4F, + 0xC7, 0x56, 0xD5, 0x5A, 0xA7, 0x96, 0x89, 0xFA, 0xF3, 0xAB, 0x68, 0xD4, + 0x23, 0x86, 0x59, 0x27, 0xCF, 0x09, 0x27, 0xBC, 0xAC, 0x6E, 0x72, 0x83, + 0x1C, 0x30, 0x72, 0xDF, 0xE0, 0xA2, 0xE9, 0xD2, 0xE1, 0x74, 0x75, 0x19, + 0xBD, 0x2A, 0x9E, 0x7B, 0x15, 0x54, 0x04, 0x1B, 0xD7, 0x43, 0x39, 0xAD, + 0x55, 0x28, 0xC5, 0xE2, 0x1A, 0xBB, 0xF4, 0xC0, 0xE4, 0xAE, 0x38, 0x49, + 0x33, 0xCC, 0x76, 0x85, 0x9F, 0x39, 0x45, 0xD2, 0xA4, 0x9E, 0xF2, 0x12, + 0x8C, 0x51, 0xF8, 0x7C, 0xE4, 0x2D, 0x7F, 0xF5, 0xAC, 0x5F, 0xEB, 0x16, + 0x9F, 0xB1, 0x2D, 0xD1, 0xBA, 0xCC, 0x91, 0x42, 0x77, 0x4C, 0x25, 0xC9, + 0x90, 0x38, 0x6F, 0xDB, 0xF0, 0xCC, 0xFB, 0x8E, 0x1E, 0x97, 0x59, 0x3E, + 0xD5, 0x60, 0x4E, 0xE6, 0x05, 0x28, 0xED, 0x49, 0x79, 0x13, 0x4B, 0xBA, + 0x48, 0xDB, 0x2F, 0xF9, 0x72, 0xD3, 0x39, 0xCA, 0xFE, 0x1F, 0xD8, 0x34, + 0x72, 0xF5, 0xB4, 0x40, 0xCF, 0x31, 0x01, 0xC3, 0xEC, 0xDE, 0x11, 0x2D, + 0x17, 0x5D, 0x1F, 0xB8, 0x50, 0xD1, 0x5E, 0x19, 0xA7, 0x69, 0xDE, 0x07, + 0x33, 0x28, 0xCA, 0x50, 0x95, 0xF9, 0xA7, 0x54, 0xCB, 0x54, 0x86, 0x50, + 0x45, 0xA9, 0xF9, 0x49 +}; + +static const unsigned char TA425_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA426_DN[] = { + 0x30, 0x81, 0x80, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, + 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x24, 0x30, + 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x43, 0x65, 0x72, 0x74, + 0x75, 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, + 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA426_RSA_N[] = { + 0xBD, 0xF9, 0x78, 0xF8, 0xE6, 0xD5, 0x80, 0x0C, 0x64, 0x9D, 0x86, 0x1B, + 0x96, 0x64, 0x67, 0x3F, 0x22, 0x3A, 0x1E, 0x75, 0x01, 0x7D, 0xEF, 0xFB, + 0x5C, 0x67, 0x8C, 0xC9, 0xCC, 0x5C, 0x6B, 0xA9, 0x91, 0xE6, 0xB9, 0x42, + 0xE5, 0x20, 0x4B, 0x9B, 0xDA, 0x9B, 0x7B, 0xB9, 0x99, 0x5D, 0xD9, 0x9B, + 0x80, 0x4B, 0xD7, 0x84, 0x40, 0x2B, 0x27, 0xD3, 0xE8, 0xBA, 0x30, 0xBB, + 0x3E, 0x09, 0x1A, 0xA7, 0x49, 0x95, 0xEF, 0x2B, 0x40, 0x24, 0xC2, 0x97, + 0xC7, 0xA7, 0xEE, 0x9B, 0x25, 0xEF, 0xA8, 0x0A, 0x00, 0x97, 0x85, 0x5A, + 0xAA, 0x9D, 0xDC, 0x29, 0xC9, 0xE2, 0x35, 0x07, 0xEB, 0x70, 0x4D, 0x4A, + 0xD6, 0xC1, 0xB3, 0x56, 0xB8, 0xA1, 0x41, 0x38, 0x9B, 0xD1, 0xFB, 0x31, + 0x7F, 0x8F, 0xE0, 0x5F, 0xE1, 0xB1, 0x3F, 0x0F, 0x8E, 0x16, 0x49, 0x60, + 0xD7, 0x06, 0x8D, 0x18, 0xF9, 0xAA, 0x26, 0x10, 0xAB, 0x2A, 0xD3, 0xD0, + 0xD1, 0x67, 0x8D, 0x1B, 0x46, 0xBE, 0x47, 0x30, 0xD5, 0x2E, 0x72, 0xD1, + 0xC5, 0x63, 0xDA, 0xE7, 0x63, 0x79, 0x44, 0x7E, 0x4B, 0x63, 0x24, 0x89, + 0x86, 0x2E, 0x34, 0x3F, 0x29, 0x4C, 0x52, 0x8B, 0x2A, 0xA7, 0xC0, 0xE2, + 0x91, 0x28, 0x89, 0xB9, 0xC0, 0x5B, 0xF9, 0x1D, 0xD9, 0xE7, 0x27, 0xAD, + 0xFF, 0x9A, 0x02, 0x97, 0xC1, 0xC6, 0x50, 0x92, 0x9B, 0x02, 0x2C, 0xBD, + 0xA9, 0xB9, 0x34, 0x59, 0x0A, 0xBF, 0x84, 0x4A, 0xFF, 0xDF, 0xFE, 0xB3, + 0x9F, 0xEB, 0xD9, 0x9E, 0xE0, 0x98, 0x23, 0xEC, 0xA6, 0x6B, 0x77, 0x16, + 0x2A, 0xDB, 0xCC, 0xAD, 0x3B, 0x1C, 0xA4, 0x87, 0xDC, 0x46, 0x73, 0x5E, + 0x19, 0x62, 0x68, 0x45, 0x57, 0xE4, 0x90, 0x82, 0x42, 0xBB, 0x42, 0xD6, + 0xF0, 0x61, 0xE0, 0xC1, 0xA3, 0x3D, 0x66, 0xA3, 0x5D, 0xF4, 0x18, 0xEE, + 0x88, 0xC9, 0x8D, 0x17, 0x45, 0x29, 0x99, 0x32, 0x75, 0x02, 0x31, 0xEE, + 0x29, 0x26, 0xC8, 0x6B, 0x02, 0xE6, 0xB5, 0x62, 0x45, 0x7F, 0x37, 0x15, + 0x5A, 0x23, 0x68, 0x89, 0xD4, 0x3E, 0xDE, 0x4E, 0x27, 0xB0, 0xF0, 0x40, + 0x0C, 0xBC, 0x4D, 0x17, 0xCB, 0x4D, 0xA2, 0xB3, 0x1E, 0xD0, 0x06, 0x5A, + 0xDD, 0xF6, 0x93, 0xCF, 0x57, 0x75, 0x99, 0xF5, 0xFA, 0x86, 0x1A, 0x67, + 0x78, 0xB3, 0xBF, 0x96, 0xFE, 0x34, 0xDC, 0xBD, 0xE7, 0x52, 0x56, 0xE5, + 0xB3, 0xE5, 0x75, 0x7B, 0xD7, 0x41, 0x91, 0x05, 0xDC, 0x5D, 0x69, 0xE3, + 0x95, 0x0D, 0x43, 0xB9, 0xFC, 0x83, 0x96, 0x39, 0x95, 0x7B, 0x6C, 0x80, + 0x5A, 0x4F, 0x13, 0x72, 0xC6, 0xD7, 0x7D, 0x29, 0x7A, 0x44, 0xBA, 0x52, + 0xA4, 0x2A, 0xD5, 0x41, 0x46, 0x09, 0x20, 0xFE, 0x22, 0xA0, 0xB6, 0x5B, + 0x30, 0x8D, 0xBC, 0x89, 0x0C, 0xD5, 0xD7, 0x70, 0xF8, 0x87, 0x52, 0xFD, + 0xDA, 0xEF, 0xAC, 0x51, 0x2E, 0x07, 0xB3, 0x4E, 0xFE, 0xD0, 0x09, 0xDA, + 0x70, 0xEF, 0x98, 0xFA, 0x56, 0xE6, 0x6D, 0xDB, 0xB5, 0x57, 0x4B, 0xDC, + 0xE5, 0x2C, 0x25, 0x15, 0xC8, 0x9E, 0x2E, 0x78, 0x4E, 0xF8, 0xDA, 0x9C, + 0x9E, 0x86, 0x2C, 0xCA, 0x57, 0xF3, 0x1A, 0xE5, 0xC8, 0x92, 0x8B, 0x1A, + 0x82, 0x96, 0x7A, 0xC3, 0xBC, 0x50, 0x12, 0x69, 0xD8, 0x0E, 0x5A, 0x46, + 0x8B, 0x3A, 0xEB, 0x26, 0xFA, 0x23, 0xC9, 0xB6, 0xB0, 0x81, 0xBE, 0x42, + 0x00, 0xA4, 0xF8, 0xD6, 0xFE, 0x30, 0x2E, 0xC7, 0xD2, 0x46, 0xF6, 0xE5, + 0x8E, 0x75, 0xFD, 0xF2, 0xCC, 0xB9, 0xD0, 0x87, 0x5B, 0xCC, 0x06, 0x10, + 0x60, 0xBB, 0x83, 0x35, 0xB7, 0x5E, 0x67, 0xDE, 0x47, 0xEC, 0x99, 0x48, + 0xF1, 0xA4, 0xA1, 0x15, 0xFE, 0xAD, 0x8C, 0x62, 0x8E, 0x39, 0x55, 0x4F, + 0x39, 0x16, 0xB9, 0xB1, 0x63, 0x9D, 0xFF, 0xB7 +}; + +static const unsigned char TA426_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA427_DN[] = { + 0x30, 0x7A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA427_RSA_N[] = { + 0xD1, 0x2D, 0x8E, 0xBB, 0xB7, 0x36, 0xEA, 0x6D, 0x37, 0x91, 0x9F, 0x4E, + 0x93, 0xA7, 0x05, 0xE4, 0x29, 0x03, 0x25, 0xCE, 0x1C, 0x82, 0xF7, 0x7C, + 0x99, 0x9F, 0x41, 0x06, 0xCD, 0xED, 0xA3, 0xBA, 0xC0, 0xDB, 0x09, 0x2C, + 0xC1, 0x7C, 0xDF, 0x29, 0x7E, 0x4B, 0x65, 0x2F, 0x93, 0xA7, 0xD4, 0x01, + 0x6B, 0x03, 0x28, 0x18, 0xA3, 0xD8, 0x9D, 0x05, 0xC1, 0x2A, 0xD8, 0x45, + 0xF1, 0x91, 0xDE, 0xDF, 0x3B, 0xD0, 0x80, 0x02, 0x8C, 0xCF, 0x38, 0x0F, + 0xEA, 0xA7, 0x5C, 0x78, 0x11, 0xA4, 0xC1, 0xC8, 0x85, 0x5C, 0x25, 0xD3, + 0xD3, 0xB2, 0xE7, 0x25, 0xCF, 0x11, 0x54, 0x97, 0xAB, 0x35, 0xC0, 0x1E, + 0x76, 0x1C, 0xEF, 0x00, 0x53, 0x9F, 0x39, 0xDC, 0x14, 0xA5, 0x2C, 0x22, + 0x25, 0xB3, 0x72, 0x72, 0xFC, 0x8D, 0xB3, 0xE5, 0x3E, 0x08, 0x1E, 0x14, + 0x2A, 0x37, 0x0B, 0x88, 0x3C, 0xCA, 0xB0, 0xF4, 0xC8, 0xC2, 0xA1, 0xAE, + 0xBC, 0xC1, 0xBE, 0x29, 0x67, 0x55, 0xE2, 0xFC, 0xAD, 0x59, 0x5C, 0xFE, + 0xBD, 0x57, 0x2C, 0xB0, 0x90, 0x8D, 0xC2, 0xED, 0x37, 0xB6, 0x7C, 0x99, + 0x88, 0xB5, 0xD5, 0x03, 0x9A, 0x3D, 0x15, 0x0D, 0x3D, 0x3A, 0xA8, 0xA8, + 0x45, 0xF0, 0x95, 0x4E, 0x25, 0x59, 0x1D, 0xCD, 0x98, 0x69, 0xBB, 0xD3, + 0xCC, 0x32, 0xC9, 0x8D, 0xEF, 0x81, 0xFE, 0xAD, 0x7D, 0x89, 0xBB, 0xBA, + 0x60, 0x13, 0xCA, 0x65, 0x95, 0x67, 0xA0, 0xF3, 0x19, 0xF6, 0x03, 0x56, + 0xD4, 0x6A, 0xD3, 0x27, 0xE2, 0xA1, 0xAD, 0x83, 0xF0, 0x4A, 0x12, 0x22, + 0x77, 0x1C, 0x05, 0x73, 0xE2, 0x19, 0x71, 0x42, 0xC0, 0xEC, 0x75, 0x46, + 0x9A, 0x90, 0x58, 0xE0, 0x6A, 0x8E, 0x2B, 0xA5, 0x46, 0x30, 0x04, 0x8E, + 0x19, 0xB2, 0x17, 0xE3, 0xBE, 0xA9, 0xBA, 0x7F, 0x56, 0xF1, 0x24, 0x03, + 0xD7, 0xB2, 0x21, 0x28, 0x76, 0x0E, 0x36, 0x30, 0x4C, 0x79, 0xD5, 0x41, + 0x9A, 0x9A, 0xA8, 0xB8, 0x35, 0xBA, 0x0C, 0x3A, 0xF2, 0x44, 0x1B, 0x20, + 0x88, 0xF7, 0xC5, 0x25, 0xD7, 0x3D, 0xC6, 0xE3, 0x3E, 0x43, 0xDD, 0x87, + 0xFE, 0xC4, 0xEA, 0xF5, 0x53, 0x3E, 0x4C, 0x65, 0xFF, 0x3B, 0x4A, 0xCB, + 0x78, 0x5A, 0x6B, 0x17, 0x5F, 0x0D, 0xC7, 0xC3, 0x4F, 0x4E, 0x9A, 0x2A, + 0xA2, 0xED, 0x57, 0x4D, 0x22, 0xE2, 0x46, 0x9A, 0x3F, 0x0F, 0x91, 0x34, + 0x24, 0x7D, 0x55, 0xE3, 0x8C, 0x95, 0x37, 0xD3, 0x1A, 0xF0, 0x09, 0x2B, + 0x2C, 0xD2, 0xC9, 0x8D, 0xB4, 0x0D, 0x00, 0xAB, 0x67, 0x29, 0x28, 0xD8, + 0x01, 0xF5, 0x19, 0x04, 0xB6, 0x1D, 0xBE, 0x76, 0xFE, 0x72, 0x5C, 0xC4, + 0x85, 0xCA, 0xD2, 0x80, 0x41, 0xDF, 0x05, 0xA8, 0xA3, 0xD5, 0x84, 0x90, + 0x4F, 0x0B, 0xF3, 0xE0, 0x3F, 0x9B, 0x19, 0xD2, 0x37, 0x89, 0x3F, 0xF2, + 0x7B, 0x52, 0x1C, 0x8C, 0xF6, 0xE1, 0xF7, 0x3C, 0x07, 0x97, 0x8C, 0x0E, + 0xA2, 0x59, 0x81, 0x0C, 0xB2, 0x90, 0x3D, 0xD3, 0xE3, 0x59, 0x46, 0xED, + 0x0F, 0xA9, 0xA7, 0xDE, 0x80, 0x6B, 0x5A, 0xAA, 0x07, 0xB6, 0x19, 0xCB, + 0xBC, 0x57, 0xF3, 0x97, 0x21, 0x7A, 0x0C, 0xB1, 0x2B, 0x74, 0x3E, 0xEB, + 0xDA, 0xA7, 0x67, 0x2D, 0x4C, 0xC4, 0x98, 0x9E, 0x36, 0x09, 0x76, 0x66, + 0x66, 0xFC, 0x1A, 0x3F, 0xEA, 0x48, 0x54, 0x1C, 0xBE, 0x30, 0xBD, 0x80, + 0x50, 0xBF, 0x7C, 0xB5, 0xCE, 0x00, 0xF6, 0x0C, 0x61, 0xD9, 0xE7, 0x24, + 0x03, 0xE0, 0xE3, 0x01, 0x81, 0x0E, 0xBD, 0xD8, 0x85, 0x34, 0x88, 0xBD, + 0xB2, 0x36, 0xA8, 0x7B, 0x5C, 0x08, 0xE5, 0x44, 0x80, 0x8C, 0x6F, 0xF8, + 0x2F, 0xD5, 0x21, 0xCA, 0x1D, 0x1C, 0xD0, 0xFB, 0xC4, 0xB5, 0x87, 0xD1, + 0x3A, 0x4E, 0xC7, 0x76, 0xB5, 0x35, 0x48, 0xB5 +}; + +static const unsigned char TA427_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA428_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA428_EC_Q[] = { + 0x04, 0x4B, 0x36, 0xE9, 0xAE, 0x57, 0x5E, 0xA8, 0x70, 0xD7, 0xD0, 0x8F, + 0x74, 0x62, 0x77, 0xC3, 0x5E, 0x7A, 0xAA, 0xE5, 0xB6, 0xA2, 0xF1, 0x78, + 0xFD, 0x02, 0x7E, 0x57, 0xDD, 0x91, 0x79, 0x9C, 0x6C, 0xB9, 0x52, 0x88, + 0x54, 0xBC, 0x2F, 0x04, 0xBE, 0xB8, 0xCD, 0xF6, 0x10, 0xD1, 0x29, 0xEC, + 0xB5, 0xD0, 0xA0, 0xC3, 0xF0, 0x89, 0x70, 0x19, 0xBB, 0x51, 0x65, 0xC5, + 0x43, 0x9C, 0xC3, 0x9B, 0x63, 0x9D, 0x20, 0x83, 0x3E, 0x06, 0x0B, 0xA6, + 0x42, 0x44, 0x85, 0x11, 0xA7, 0x4A, 0x3A, 0x2D, 0xE9, 0xD6, 0x68, 0x2F, + 0x48, 0x4E, 0x53, 0x2B, 0x07, 0x3F, 0x4D, 0xBD, 0xB9, 0xAC, 0x77, 0x39, + 0x57 +}; + +static const unsigned char TA429_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA429_EC_Q[] = { + 0x04, 0x78, 0x30, 0x81, 0xE8, 0x63, 0x1E, 0xE5, 0xEB, 0x71, 0x51, 0x0F, + 0xF7, 0x07, 0x07, 0xCA, 0x39, 0x99, 0x7C, 0x4E, 0xD5, 0x0F, 0xCC, 0x30, + 0x30, 0x0B, 0x8F, 0x66, 0x93, 0x3E, 0xCF, 0xBD, 0xC5, 0x86, 0xBD, 0xF9, + 0xB1, 0xB7, 0xB4, 0x3E, 0xB4, 0x07, 0xC8, 0xF3, 0x96, 0x31, 0xF3, 0xED, + 0xA4, 0x4F, 0xF8, 0xA3, 0x4E, 0x8D, 0x29, 0x15, 0x58, 0xB8, 0xD5, 0x6F, + 0x7F, 0xEE, 0x6C, 0x22, 0xB5, 0xB0, 0xAF, 0x48, 0x45, 0x0A, 0xBD, 0xA8, + 0x49, 0x94, 0xBF, 0x84, 0x43, 0xB0, 0xDB, 0x84, 0x4A, 0x03, 0x23, 0x19, + 0x67, 0x6A, 0x6F, 0xC1, 0x6E, 0xBC, 0x06, 0x39, 0x37, 0xD1, 0x88, 0x22, + 0xF7 +}; + +static const unsigned char TA430_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA430_RSA_N[] = { + 0xB0, 0x48, 0x65, 0xA3, 0x0D, 0x1D, 0x42, 0xE3, 0x91, 0x6D, 0x9D, 0x84, + 0xA4, 0x61, 0x96, 0x12, 0xC2, 0xED, 0xC3, 0xDA, 0x23, 0x34, 0x19, 0x76, + 0xF6, 0xEA, 0xFD, 0x55, 0x5A, 0xF6, 0x55, 0x01, 0x53, 0x0F, 0xF2, 0xCC, + 0x8C, 0x97, 0x4F, 0xB9, 0x50, 0xCB, 0xB3, 0x01, 0x44, 0x56, 0x96, 0xFD, + 0x9B, 0x28, 0xEC, 0x7B, 0x74, 0x0B, 0xE7, 0x42, 0x6B, 0x55, 0xCE, 0xC9, + 0x61, 0xB2, 0xE8, 0xAD, 0x40, 0x3C, 0xBA, 0xB9, 0x41, 0x0A, 0x05, 0x4F, + 0x1B, 0x26, 0x85, 0x8F, 0x43, 0xB5, 0x40, 0xB5, 0x85, 0xD1, 0xD4, 0x71, + 0xDC, 0x83, 0x41, 0xF3, 0xF6, 0x45, 0xC7, 0x80, 0xA2, 0x84, 0x50, 0x97, + 0x46, 0xCE, 0xA0, 0x0C, 0xC4, 0x60, 0x56, 0x04, 0x1D, 0x07, 0x5B, 0x46, + 0xA5, 0x0E, 0xB2, 0x4B, 0xA4, 0x0E, 0xA5, 0x7C, 0xEE, 0xF8, 0xD4, 0x62, + 0x03, 0xB9, 0x93, 0x6A, 0x8A, 0x14, 0xB8, 0x70, 0xF8, 0x2E, 0x82, 0x46, + 0x38, 0x23, 0x0E, 0x74, 0xC7, 0x6B, 0x41, 0xB7, 0xD0, 0x29, 0xA3, 0x9D, + 0x80, 0xB0, 0x7E, 0x77, 0x93, 0x63, 0x42, 0xFB, 0x34, 0x83, 0x3B, 0x73, + 0xA3, 0x5A, 0x21, 0x36, 0xEB, 0x47, 0xFA, 0x18, 0x17, 0xD9, 0xBA, 0x66, + 0xC2, 0x93, 0xA4, 0x8F, 0xFC, 0x5D, 0xA4, 0xAD, 0xFC, 0x50, 0x6A, 0x95, + 0xAC, 0xBC, 0x24, 0x33, 0xD1, 0xBD, 0x88, 0x7F, 0x86, 0xF5, 0xF5, 0xB2, + 0x73, 0x2A, 0x8F, 0x7C, 0xAF, 0x08, 0xF2, 0x1A, 0x98, 0x3F, 0xA9, 0x81, + 0x65, 0x3F, 0xC1, 0x8C, 0x89, 0xC5, 0x96, 0x30, 0x9A, 0x0A, 0xCF, 0xF4, + 0xD4, 0xC8, 0x34, 0xED, 0x9D, 0x2F, 0xBC, 0x8D, 0x38, 0x86, 0x53, 0xEE, + 0x97, 0x9F, 0xA9, 0xB2, 0x63, 0x94, 0x17, 0x8D, 0x0F, 0xDC, 0x66, 0x2A, + 0x7C, 0x52, 0x51, 0x75, 0xCB, 0x99, 0x8E, 0xE8, 0x3D, 0x5C, 0xBF, 0x9E, + 0x3B, 0x28, 0x8D, 0x83, 0x02, 0x0F, 0xA9, 0x9F, 0x72, 0xE2, 0x2C, 0x2B, + 0xB3, 0xDC, 0x66, 0x97, 0x00, 0x40, 0xD0, 0xA4, 0x54, 0x8E, 0x9B, 0x5D, + 0x7B, 0x45, 0x36, 0x26, 0xD6, 0x72, 0x43, 0xEB, 0xCF, 0xC0, 0xEA, 0x0D, + 0xDC, 0xCE, 0x12, 0xE6, 0x7D, 0x38, 0x9F, 0x05, 0x27, 0xA8, 0x97, 0x3E, + 0xE9, 0x51, 0xC6, 0x6C, 0x05, 0x28, 0xC1, 0x02, 0x0F, 0xE9, 0x18, 0x6D, + 0xEC, 0xBD, 0x9C, 0x06, 0xD4, 0xA7, 0x49, 0xF4, 0x54, 0x05, 0x6B, 0x6C, + 0x30, 0xF1, 0xEB, 0x03, 0xD5, 0xEA, 0x3D, 0x6A, 0x76, 0xC2, 0xCB, 0x1A, + 0x28, 0x49, 0x4D, 0x7F, 0x64, 0xE0, 0xFA, 0x2B, 0xDA, 0x73, 0x83, 0x81, + 0xFF, 0x91, 0x03, 0xBD, 0x94, 0xBB, 0xE4, 0xB8, 0x8E, 0x9C, 0x32, 0x63, + 0xCD, 0x9F, 0xBB, 0x68, 0x81, 0xB1, 0x84, 0x5B, 0xAF, 0x36, 0xBF, 0x77, + 0xEE, 0x1D, 0x7F, 0xF7, 0x49, 0x9B, 0x52, 0xEC, 0xD2, 0x77, 0x5A, 0x7D, + 0x91, 0x9D, 0x4D, 0xC2, 0x39, 0x2D, 0xE4, 0xBA, 0x82, 0xF8, 0x6F, 0xF2, + 0x4E, 0x1E, 0x0F, 0x4E, 0xE6, 0x3F, 0x59, 0xA5, 0x23, 0xDC, 0x3D, 0x87, + 0xA8, 0x28, 0x58, 0x28, 0xD1, 0xF1, 0x1B, 0x36, 0xDB, 0x4F, 0xC4, 0xFF, + 0xE1, 0x8C, 0x5B, 0x72, 0x8C, 0xC7, 0x26, 0x03, 0x27, 0xA3, 0x39, 0x0A, + 0x01, 0xAA, 0xC0, 0xB2, 0x31, 0x60, 0x83, 0x22, 0xA1, 0x4F, 0x12, 0x09, + 0x01, 0x11, 0xAF, 0x34, 0xD4, 0xCF, 0xD7, 0xAE, 0x62, 0xD3, 0x05, 0x07, + 0xB4, 0x31, 0x75, 0xE0, 0x0D, 0x6D, 0x57, 0x4F, 0x69, 0x87, 0xF9, 0x57, + 0xA9, 0xBA, 0x15, 0xF6, 0xC8, 0x52, 0x6D, 0xA1, 0xCB, 0x9C, 0x1F, 0xE5, + 0xFC, 0x78, 0xA8, 0x35, 0x9A, 0x9F, 0x41, 0x14, 0xCE, 0xA5, 0xB4, 0xCE, + 0x94, 0x08, 0x1C, 0x09, 0xAD, 0x56, 0xE5, 0xDA, 0xB6, 0x49, 0x9A, 0x4A, + 0xEA, 0x63, 0x18, 0x53, 0x9C, 0x2C, 0x2E, 0xC3 +}; + +static const unsigned char TA430_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA431_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA431_RSA_N[] = { + 0xE1, 0xFA, 0x0E, 0xFB, 0x68, 0x00, 0x12, 0xC8, 0x4D, 0xD5, 0xAC, 0x22, + 0xC4, 0x35, 0x01, 0x3B, 0xC5, 0x54, 0xE5, 0x59, 0x76, 0x63, 0xA5, 0x7F, + 0xEB, 0xC1, 0xC4, 0x6A, 0x98, 0xBD, 0x32, 0x8D, 0x17, 0x80, 0xEB, 0x5D, + 0xBA, 0xD1, 0x62, 0x3D, 0x25, 0x23, 0x19, 0x35, 0x14, 0xE9, 0x7F, 0x89, + 0xA7, 0x1B, 0x62, 0x3C, 0xD6, 0x50, 0xE7, 0x34, 0x95, 0x03, 0x32, 0xB1, + 0xB4, 0x93, 0x22, 0x3D, 0xA7, 0xE2, 0xB1, 0xED, 0xE6, 0x7B, 0x4E, 0x2E, + 0x87, 0x9B, 0x0D, 0x33, 0x75, 0x0A, 0xDE, 0xAA, 0x35, 0xE7, 0x7E, 0xE5, + 0x36, 0x98, 0xA2, 0xAE, 0x25, 0x9E, 0x95, 0xB3, 0x32, 0x96, 0xA4, 0x2B, + 0x58, 0x1E, 0xEF, 0x3F, 0xFE, 0x62, 0x34, 0x48, 0x51, 0xD1, 0xB4, 0x8D, + 0x42, 0xAD, 0x60, 0xDA, 0x49, 0x6A, 0x95, 0x70, 0xDD, 0xD2, 0x00, 0xE2, + 0xCC, 0x57, 0x63, 0x02, 0x7B, 0x96, 0xDD, 0x49, 0x97, 0x5B, 0x92, 0x4E, + 0x95, 0xD3, 0xF9, 0xCB, 0x29, 0x1F, 0x18, 0x4A, 0xF8, 0x01, 0x2A, 0xD2, + 0x63, 0x09, 0x6E, 0x24, 0xE9, 0x89, 0xD2, 0xE5, 0xC7, 0x22, 0x4C, 0xDC, + 0x73, 0x86, 0x47, 0x00, 0xAA, 0x0D, 0x88, 0x8E, 0xAE, 0x85, 0x7D, 0x4A, + 0xE9, 0xBB, 0x33, 0x4F, 0x0E, 0x52, 0x70, 0x9D, 0x95, 0xE3, 0x7C, 0x6D, + 0x96, 0x5B, 0x2D, 0x3D, 0x5F, 0xA1, 0x83, 0x46, 0x5D, 0xB6, 0xE3, 0x25, + 0xB8, 0x7C, 0xA7, 0x19, 0x80, 0x1C, 0xEA, 0x65, 0x43, 0xDC, 0x91, 0x79, + 0x36, 0x2C, 0x74, 0x7C, 0xF2, 0x67, 0x06, 0xC9, 0x89, 0xC9, 0xDB, 0xBF, + 0xDA, 0x68, 0xBF, 0x23, 0xED, 0xDC, 0x6B, 0xAD, 0x28, 0x83, 0x79, 0x2F, + 0xEC, 0x38, 0xA5, 0x0D, 0x37, 0x01, 0x67, 0x27, 0x9A, 0xE9, 0x33, 0xD9, + 0x33, 0x5F, 0x37, 0xA1, 0xC5, 0xF0, 0xAB, 0x3D, 0xFA, 0x78, 0xB0, 0xE7, + 0x2C, 0x9F, 0xF6, 0x3E, 0x9F, 0x60, 0xE0, 0xEF, 0x48, 0xE9, 0x90, 0x45, + 0x1E, 0x05, 0x51, 0x78, 0x1A, 0x2C, 0x12, 0x2C, 0x5C, 0x28, 0xAC, 0x0D, + 0xA2, 0x23, 0x9E, 0x34, 0x8F, 0x05, 0xE6, 0xA2, 0x33, 0xCE, 0x11, 0x77, + 0x13, 0xD4, 0x0E, 0xA4, 0x1E, 0x42, 0x1F, 0x86, 0xCD, 0x70, 0xFE, 0xD9, + 0x2E, 0x15, 0x3D, 0x1D, 0xBB, 0xB8, 0xF2, 0x53, 0x57, 0xDB, 0xCC, 0xC6, + 0x74, 0x29, 0x9C, 0x18, 0xB3, 0x36, 0x75, 0x38, 0x2E, 0x0F, 0x54, 0xA1, + 0xF8, 0x92, 0x1F, 0x89, 0x96, 0x4F, 0xBB, 0xD4, 0xEE, 0x9D, 0xE9, 0x3B, + 0x36, 0x42, 0xB5, 0x0A, 0x3B, 0x2A, 0xD4, 0x64, 0x79, 0x36, 0x10, 0xE1, + 0xF9, 0x91, 0x03, 0x2B, 0x7B, 0x20, 0x54, 0xCD, 0x0D, 0x19, 0x1A, 0xC8, + 0x41, 0x32, 0x34, 0xD1, 0xB0, 0x99, 0xE1, 0x90, 0x1E, 0x01, 0x40, 0x36, + 0xB5, 0xB7, 0xFA, 0xA9, 0xE5, 0x77, 0x75, 0xA4, 0x22, 0x81, 0x5D, 0xB0, + 0x8B, 0xE4, 0x27, 0x12, 0x0F, 0x54, 0x88, 0xC6, 0xDB, 0x85, 0x74, 0xE6, + 0xB7, 0xC0, 0xD7, 0xA6, 0x29, 0xFA, 0xDB, 0xDE, 0xF3, 0x93, 0x97, 0x27, + 0x04, 0x55, 0x2F, 0x0A, 0x6F, 0x37, 0xC5, 0x3D, 0x13, 0xAF, 0x0A, 0x00, + 0xA9, 0x2C, 0x8B, 0x1C, 0x81, 0x28, 0xD7, 0xEF, 0x86, 0x31, 0xA9, 0xAE, + 0xF2, 0x6E, 0xB8, 0xCA, 0x6A, 0x2C, 0x54, 0x47, 0xD8, 0x2A, 0x88, 0x2E, + 0xAF, 0xC1, 0x07, 0x10, 0x78, 0xAC, 0x11, 0xA2, 0x2F, 0x42, 0xF0, 0x37, + 0xC5, 0xF2, 0xB8, 0x56, 0xDD, 0x0E, 0x62, 0x2D, 0xCE, 0x2D, 0x56, 0x7E, + 0x55, 0xF2, 0xA7, 0x44, 0xF6, 0x2B, 0x32, 0xF4, 0x23, 0xA8, 0x47, 0xE8, + 0xD4, 0x2A, 0x01, 0x78, 0xCF, 0x6A, 0xC3, 0x37, 0xA8, 0x9E, 0x65, 0xD2, + 0x2C, 0xE5, 0xFA, 0xBA, 0x33, 0xC1, 0x06, 0x44, 0xF6, 0xE6, 0xCF, 0xA5, + 0x0D, 0xA7, 0x66, 0x08, 0x34, 0x8A, 0x2C, 0xF3 +}; + +static const unsigned char TA431_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA432_DN[] = { + 0x30, 0x7B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, 0x61, + 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x53, 0x61, 0x6C, 0x66, 0x6F, + 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x11, 0x43, 0x6F, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x43, 0x41, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x18, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73 +}; + +static const unsigned char TA432_RSA_N[] = { + 0xBE, 0x40, 0x9D, 0xF4, 0x6E, 0xE1, 0xEA, 0x76, 0x87, 0x1C, 0x4D, 0x45, + 0x44, 0x8E, 0xBE, 0x46, 0xC8, 0x83, 0x06, 0x9D, 0xC1, 0x2A, 0xFE, 0x18, + 0x1F, 0x8E, 0xE4, 0x02, 0xFA, 0xF3, 0xAB, 0x5D, 0x50, 0x8A, 0x16, 0x31, + 0x0B, 0x9A, 0x06, 0xD0, 0xC5, 0x70, 0x22, 0xCD, 0x49, 0x2D, 0x54, 0x63, + 0xCC, 0xB6, 0x6E, 0x68, 0x46, 0x0B, 0x53, 0xEA, 0xCB, 0x4C, 0x24, 0xC0, + 0xBC, 0x72, 0x4E, 0xEA, 0xF1, 0x15, 0xAE, 0xF4, 0x54, 0x9A, 0x12, 0x0A, + 0xC3, 0x7A, 0xB2, 0x33, 0x60, 0xE2, 0xDA, 0x89, 0x55, 0xF3, 0x22, 0x58, + 0xF3, 0xDE, 0xDC, 0xCF, 0xEF, 0x83, 0x86, 0xA2, 0x8C, 0x94, 0x4F, 0x9F, + 0x68, 0xF2, 0x98, 0x90, 0x46, 0x84, 0x27, 0xC7, 0x76, 0xBF, 0xE3, 0xCC, + 0x35, 0x2C, 0x8B, 0x5E, 0x07, 0x64, 0x65, 0x82, 0xC0, 0x48, 0xB0, 0xA8, + 0x91, 0xF9, 0x61, 0x9F, 0x76, 0x20, 0x50, 0xA8, 0x91, 0xC7, 0x66, 0xB5, + 0xEB, 0x78, 0x62, 0x03, 0x56, 0xF0, 0x8A, 0x1A, 0x13, 0xEA, 0x31, 0xA3, + 0x1E, 0xA0, 0x99, 0xFD, 0x38, 0xF6, 0xF6, 0x27, 0x32, 0x58, 0x6F, 0x07, + 0xF5, 0x6B, 0xB8, 0xFB, 0x14, 0x2B, 0xAF, 0xB7, 0xAA, 0xCC, 0xD6, 0x63, + 0x5F, 0x73, 0x8C, 0xDA, 0x05, 0x99, 0xA8, 0x38, 0xA8, 0xCB, 0x17, 0x78, + 0x36, 0x51, 0xAC, 0xE9, 0x9E, 0xF4, 0x78, 0x3A, 0x8D, 0xCF, 0x0F, 0xD9, + 0x42, 0xE2, 0x98, 0x0C, 0xAB, 0x2F, 0x9F, 0x0E, 0x01, 0xDE, 0xEF, 0x9F, + 0x99, 0x49, 0xF1, 0x2D, 0xDF, 0xAC, 0x74, 0x4D, 0x1B, 0x98, 0xB5, 0x47, + 0xC5, 0xE5, 0x29, 0xD1, 0xF9, 0x90, 0x18, 0xC7, 0x62, 0x9C, 0xBE, 0x83, + 0xC7, 0x26, 0x7B, 0x3E, 0x8A, 0x25, 0xC7, 0xC0, 0xDD, 0x9D, 0xE6, 0x35, + 0x68, 0x10, 0x20, 0x9D, 0x8F, 0xD8, 0xDE, 0xD2, 0xC3, 0x84, 0x9C, 0x0D, + 0x5E, 0xE8, 0x2F, 0xC9 +}; + +static const unsigned char TA432_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA433_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA433_EC_Q[] = { + 0x04, 0xC6, 0xCB, 0xC7, 0x28, 0xD1, 0xFB, 0x84, 0xF5, 0x9A, 0xEF, 0x42, + 0x14, 0x20, 0xE1, 0x43, 0x6B, 0x6E, 0x75, 0xAD, 0xFC, 0x2B, 0x03, 0x84, + 0xD4, 0x76, 0x93, 0x25, 0xD7, 0x59, 0x3B, 0x41, 0x65, 0x6B, 0x1E, 0xE6, + 0x34, 0x2A, 0xBB, 0x74, 0xF6, 0x12, 0xCE, 0xE8, 0x6D, 0xE7, 0xAB, 0xE4, + 0x3C, 0x4E, 0x3F, 0x44, 0x08, 0x8B, 0xCD, 0x16, 0x71, 0xCB, 0xBF, 0x92, + 0x99, 0xF4, 0xA4, 0xD7, 0x3C, 0x50, 0x54, 0x52, 0x90, 0x85, 0x83, 0x78, + 0x94, 0x67, 0x67, 0xA3, 0x1C, 0x09, 0x19, 0x3D, 0x75, 0x34, 0x85, 0xDE, + 0xED, 0x60, 0x7D, 0xC7, 0x0C, 0xB4, 0x41, 0x52, 0xB9, 0x6E, 0xE5, 0xEE, + 0x42 +}; + +static const unsigned char TA434_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA434_RSA_N[] = { + 0xAE, 0xFF, 0x09, 0x59, 0x91, 0x80, 0x0A, 0x4A, 0x68, 0xE6, 0x24, 0x3F, + 0xB8, 0xA7, 0xE4, 0xC8, 0x3A, 0x0A, 0x3A, 0x16, 0xCD, 0xC9, 0x23, 0x61, + 0xA0, 0x93, 0x71, 0xF2, 0xAB, 0x8B, 0x73, 0x8F, 0xA0, 0x67, 0x65, 0x60, + 0xD2, 0x54, 0x6B, 0x63, 0x51, 0x6F, 0x49, 0x33, 0xE0, 0x72, 0x07, 0x13, + 0x7D, 0x38, 0xCD, 0x06, 0x92, 0x07, 0x29, 0x52, 0x6B, 0x4E, 0x77, 0x6C, + 0x04, 0xD3, 0x95, 0xFA, 0xDD, 0x4C, 0x8C, 0xD9, 0x5D, 0xC1, 0x61, 0x7D, + 0x4B, 0xE7, 0x28, 0xB3, 0x44, 0x81, 0x7B, 0x51, 0xAF, 0xDD, 0x33, 0xB1, + 0x68, 0x7C, 0xD6, 0x4E, 0x4C, 0xFE, 0x2B, 0x68, 0xB9, 0xCA, 0x66, 0x69, + 0xC4, 0xEC, 0x5E, 0x57, 0x7F, 0xF7, 0x0D, 0xC7, 0x9C, 0x36, 0x36, 0xE5, + 0x07, 0x60, 0xAC, 0xC0, 0x4C, 0xEA, 0x08, 0x6C, 0xEF, 0x06, 0x7C, 0x4F, + 0x5B, 0x28, 0x7A, 0x08, 0xFC, 0x93, 0x5D, 0x9B, 0xF6, 0x9C, 0xB4, 0x8B, + 0x86, 0xBA, 0x21, 0xB9, 0xF4, 0xF0, 0xE8, 0x59, 0x5A, 0x28, 0xA1, 0x34, + 0x84, 0x1A, 0x25, 0x91, 0xB6, 0xB5, 0x8F, 0xEF, 0xB2, 0xF9, 0x80, 0xFA, + 0xF9, 0x3D, 0x3C, 0x11, 0x72, 0xD8, 0xE3, 0x2F, 0x86, 0x76, 0xC5, 0x79, + 0x2C, 0xC1, 0xA9, 0x90, 0x93, 0x46, 0x98, 0x67, 0xCB, 0x83, 0x6A, 0xA0, + 0x50, 0x23, 0xA7, 0x3B, 0xF6, 0x81, 0x39, 0xE0, 0xED, 0xF0, 0xB9, 0xBF, + 0x65, 0xF1, 0xD8, 0xCB, 0x7A, 0xFB, 0xEF, 0x73, 0x03, 0xCE, 0x00, 0xF4, + 0x7D, 0xD7, 0xE0, 0x5D, 0x3B, 0x66, 0xB8, 0xDC, 0x8E, 0xBA, 0x83, 0xCB, + 0x87, 0x76, 0x03, 0xFC, 0x25, 0xD9, 0xE7, 0x23, 0x6F, 0x06, 0xFD, 0x67, + 0xF3, 0xE0, 0xFF, 0x84, 0xBC, 0x47, 0xBF, 0xB5, 0x16, 0x18, 0x46, 0x69, + 0x14, 0xCC, 0x05, 0xF7, 0xDB, 0xD3, 0x49, 0xAC, 0x6B, 0xCC, 0xAB, 0xE4, + 0xB5, 0x0B, 0x43, 0x24, 0x5E, 0x4B, 0x6B, 0x4D, 0x67, 0xDF, 0xD6, 0xB5, + 0x3E, 0x4F, 0x78, 0x1F, 0x94, 0x71, 0x24, 0xEA, 0xDE, 0x70, 0xFC, 0xF1, + 0x93, 0xFE, 0x9E, 0x93, 0x5A, 0xE4, 0x94, 0x5A, 0x97, 0x54, 0x0C, 0x35, + 0x7B, 0x5F, 0x6C, 0xEE, 0x00, 0x1F, 0x24, 0xEC, 0x03, 0xBA, 0x02, 0xF5, + 0x76, 0xF4, 0x9F, 0xD4, 0x9A, 0xED, 0x85, 0x2C, 0x38, 0x22, 0x2F, 0xC7, + 0xD8, 0x2F, 0x76, 0x11, 0x4F, 0xFD, 0x6C, 0x5C, 0xE8, 0xF5, 0x8E, 0x27, + 0x87, 0x7F, 0x19, 0x4A, 0x21, 0x47, 0x90, 0x1D, 0x79, 0x8D, 0x1C, 0x5B, + 0xF8, 0xCF, 0x4A, 0x85, 0xE4, 0xED, 0xB3, 0x5B, 0x8D, 0xBE, 0xC4, 0x64, + 0x28, 0x5D, 0x41, 0xC4, 0x6E, 0xAC, 0x38, 0x5A, 0x4F, 0x23, 0x74, 0x74, + 0xA9, 0x12, 0xC3, 0xF6, 0xD2, 0xB9, 0x11, 0x15, 0x33, 0x07, 0x91, 0xD8, + 0x3B, 0x37, 0x3A, 0x63, 0x30, 0x06, 0xD1, 0xC5, 0x22, 0x36, 0x28, 0x62, + 0x23, 0x10, 0xE0, 0x46, 0xCC, 0x97, 0xAC, 0xD6, 0x2B, 0x5D, 0x64, 0x24, + 0xD5, 0xEE, 0x1C, 0x0E, 0xDE, 0xFB, 0x08, 0x5A, 0x75, 0x2A, 0xF6, 0x63, + 0x6D, 0xCE, 0x0B, 0x42, 0xBE, 0xD1, 0xBA, 0x70, 0x1C, 0x9C, 0x21, 0xE5, + 0x0F, 0x31, 0x69, 0x17, 0xD7, 0xFC, 0x0A, 0xB4, 0xDE, 0xED, 0x80, 0x9C, + 0xCB, 0x92, 0xB4, 0x8B, 0xF5, 0xDE, 0x59, 0xA2, 0x58, 0x09, 0xA5, 0x63, + 0x47, 0x0B, 0xE1, 0x41, 0x32, 0x34, 0x41, 0xD9, 0x9A, 0xB1, 0xD9, 0xA8, + 0xB0, 0x1B, 0x5A, 0xDE, 0x0D, 0x0D, 0xF4, 0xE2, 0xB2, 0x5D, 0x35, 0x80, + 0xB9, 0x81, 0xD4, 0x84, 0x69, 0x91, 0x02, 0xCB, 0x75, 0xD0, 0x8D, 0xC5, + 0xB5, 0x3D, 0x09, 0x91, 0x09, 0x8F, 0x14, 0xA1, 0x14, 0x74, 0x79, 0x3E, + 0xD6, 0xC9, 0x15, 0x1D, 0xA4, 0x59, 0x59, 0x22, 0xDC, 0xF6, 0x8A, 0x45, + 0x3D, 0x3C, 0x12, 0xD6, 0x3E, 0x5D, 0x32, 0x2F +}; + +static const unsigned char TA434_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA435_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA435_EC_Q[] = { + 0x04, 0xF1, 0x0B, 0xDD, 0x86, 0x43, 0x20, 0x19, 0xDF, 0x97, 0x85, 0xE8, + 0x22, 0x4A, 0x9B, 0xCF, 0x9D, 0x98, 0xBF, 0xB4, 0x05, 0x26, 0xC9, 0xCB, + 0xE3, 0xA6, 0xD2, 0x8F, 0xC5, 0x9E, 0x78, 0x7B, 0x31, 0x89, 0xA9, 0x89, + 0xAD, 0x27, 0x3C, 0x65, 0x10, 0x82, 0xFC, 0xDF, 0xC3, 0x9D, 0x4E, 0xF0, + 0x33, 0x23, 0xC4, 0xD2, 0x32, 0xF5, 0x1C, 0xB0, 0xDF, 0x33, 0x17, 0x5D, + 0xC5, 0xF0, 0xB1, 0x8A, 0xF9, 0xEF, 0xB9, 0xB7, 0x14, 0xCA, 0x29, 0x4A, + 0xC2, 0x0F, 0xA9, 0x7F, 0x75, 0x65, 0x49, 0x2A, 0x30, 0x67, 0xF4, 0x64, + 0xF7, 0xD6, 0x1A, 0x77, 0xDA, 0xC3, 0xC2, 0x97, 0x61, 0x42, 0x7B, 0x49, + 0xAD +}; + +static const unsigned char TA436_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA436_RSA_N[] = { + 0xD8, 0x8E, 0xA3, 0x89, 0x80, 0x0B, 0xB2, 0x57, 0x52, 0xDC, 0xA9, 0x53, + 0x4C, 0x37, 0xB9, 0x7F, 0x63, 0x17, 0x13, 0xEF, 0xA7, 0x5B, 0x23, 0x5B, + 0x69, 0x75, 0xB0, 0x99, 0x0A, 0x17, 0xC1, 0x8B, 0xC4, 0xDB, 0xA8, 0xE0, + 0xCC, 0x31, 0xBA, 0xC2, 0xF2, 0xCD, 0x5D, 0xE9, 0xB7, 0xF8, 0x1D, 0xAF, + 0x6A, 0xC4, 0x95, 0x87, 0xD7, 0x47, 0xC9, 0x95, 0xD8, 0x82, 0x04, 0x50, + 0x3D, 0x81, 0x08, 0xFF, 0xE4, 0x3D, 0xB3, 0xB1, 0xD6, 0xC5, 0xB2, 0xFD, + 0x88, 0x09, 0xDB, 0x9C, 0x84, 0xEC, 0x25, 0x17, 0x14, 0x87, 0x7F, 0x30, + 0x78, 0x9B, 0x6A, 0x58, 0xC9, 0xB6, 0x73, 0x28, 0x3C, 0x34, 0xF7, 0x99, + 0xF7, 0x7F, 0xD3, 0xA6, 0xF8, 0x1C, 0x45, 0x7C, 0xAD, 0x2C, 0x8C, 0x94, + 0x3F, 0xD8, 0x67, 0x10, 0x53, 0x7E, 0x22, 0xCD, 0x4E, 0x25, 0x51, 0xF0, + 0x25, 0x24, 0x35, 0x11, 0x5E, 0x10, 0xC6, 0xEC, 0x87, 0x66, 0x89, 0x81, + 0x68, 0xBA, 0xCC, 0x2B, 0x9D, 0x47, 0x73, 0x1F, 0xBD, 0xCD, 0x91, 0xA4, + 0x72, 0x6A, 0x9C, 0xA2, 0x1B, 0x18, 0xA0, 0x6F, 0xEC, 0x50, 0xF4, 0x7D, + 0x40, 0xC2, 0xA8, 0x30, 0xCF, 0xBD, 0x73, 0xC8, 0x13, 0x2B, 0x10, 0x13, + 0x1E, 0x8B, 0x9A, 0xA8, 0x3A, 0x94, 0x73, 0xD3, 0x18, 0x69, 0x0A, 0x4A, + 0xFF, 0xC1, 0x01, 0x03, 0xFF, 0x79, 0x7F, 0xB5, 0x48, 0x7F, 0x7B, 0xEE, + 0xE8, 0x29, 0x6F, 0x36, 0x4C, 0x95, 0x61, 0x86, 0xD8, 0xF9, 0xA2, 0x73, + 0x8A, 0xEE, 0xAE, 0x2F, 0x96, 0xEE, 0x68, 0xCD, 0x3D, 0x4D, 0x28, 0x42, + 0xF9, 0x45, 0x2B, 0x32, 0x1B, 0x46, 0x55, 0x16, 0x6A, 0xA6, 0x4B, 0x29, + 0xF9, 0xBB, 0x95, 0x56, 0xBF, 0x46, 0x1D, 0xEC, 0x1D, 0x93, 0x1D, 0xC0, + 0x65, 0xB2, 0x1F, 0xA1, 0x43, 0xAE, 0x56, 0x9E, 0xA0, 0xB1, 0x8F, 0x6B, + 0x12, 0xB7, 0x60, 0x6D, 0x78, 0x0B, 0xCA, 0x8A, 0x5C, 0xED, 0x1E, 0x96, + 0x0E, 0x83, 0xA6, 0x48, 0x95, 0x8D, 0x3B, 0xA3, 0x21, 0xC4, 0xAE, 0x58, + 0xC6, 0x00, 0xB2, 0x84, 0xB4, 0x23, 0xA4, 0x96, 0x86, 0x35, 0xB8, 0xD8, + 0x9E, 0xD8, 0xAC, 0x34, 0x49, 0x98, 0x63, 0x95, 0xC5, 0xCB, 0x6D, 0x48, + 0x47, 0xE2, 0xF2, 0x2E, 0x18, 0x1E, 0xD0, 0x31, 0xAB, 0xDD, 0x74, 0xEC, + 0xF9, 0xDC, 0x8C, 0xB8, 0x1C, 0x8E, 0x68, 0x23, 0xBA, 0xD0, 0xF3, 0x50, + 0xDC, 0xCF, 0x65, 0x8F, 0x73, 0x3A, 0x32, 0xC7, 0x7C, 0xFE, 0xCA, 0x82, + 0x22, 0x4F, 0xBE, 0x8E, 0x62, 0x47, 0x66, 0xE5, 0xCD, 0x87, 0xE2, 0xE8, + 0xD5, 0x0F, 0x18, 0x9F, 0xE5, 0x04, 0x72, 0x4B, 0x46, 0x3C, 0x10, 0xF2, + 0x44, 0xC2, 0x64, 0x56, 0x71, 0x4E, 0x75, 0xE8, 0x9C, 0xC9, 0x26, 0x74, + 0xC5, 0x7D, 0x59, 0xD1, 0x0A, 0x5B, 0x0F, 0x6D, 0xFE, 0x9E, 0x75, 0x1C, + 0x18, 0xC6, 0x1A, 0x3A, 0x7C, 0xD8, 0x0D, 0x04, 0xCC, 0xCD, 0xB7, 0x45, + 0x65, 0x7A, 0xB1, 0x8F, 0xB8, 0xAE, 0x84, 0x48, 0x3E, 0xB3, 0x7A, 0x4D, + 0xA8, 0x03, 0xE2, 0xE2, 0x7E, 0x01, 0x16, 0x59, 0x68, 0x18, 0x43, 0x33, + 0xB0, 0xD2, 0xDC, 0xB0, 0x1A, 0x43, 0x35, 0xEE, 0xA5, 0xDA, 0xA9, 0x46, + 0x5C, 0xAE, 0x86, 0x81, 0x41, 0x01, 0x4A, 0x74, 0x26, 0xEC, 0x9F, 0x06, + 0xBF, 0xC2, 0x05, 0x37, 0x64, 0x75, 0x78, 0x29, 0x68, 0xFD, 0xC5, 0xF5, + 0xEB, 0xFE, 0x47, 0xF9, 0xE4, 0x85, 0xB0, 0xE1, 0x7B, 0x31, 0x9D, 0xA6, + 0x7F, 0x72, 0xA3, 0xB9, 0xC4, 0x2C, 0x2E, 0xCC, 0x99, 0x57, 0x0E, 0x21, + 0x0C, 0x45, 0x01, 0x94, 0x65, 0xEB, 0x65, 0x09, 0xC6, 0x63, 0x22, 0x0B, + 0x33, 0x49, 0x92, 0x48, 0x3C, 0xFC, 0xCD, 0xCE, 0xB0, 0x3E, 0x8E, 0x9E, + 0x8B, 0xF8, 0xFE, 0x49, 0xC5, 0x35, 0x72, 0x47 +}; + +static const unsigned char TA436_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA437_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x1E, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA437_RSA_N[] = { + 0xD3, 0xB2, 0x4A, 0xCF, 0x7A, 0x47, 0xEF, 0x75, 0x9B, 0x23, 0xFA, 0x3A, + 0x2F, 0xD6, 0x50, 0x45, 0x89, 0x35, 0x3A, 0xC6, 0x6B, 0xDB, 0xFE, 0xDB, + 0x00, 0x68, 0xA8, 0xE0, 0x03, 0x11, 0x1D, 0x37, 0x50, 0x08, 0x9F, 0x4D, + 0x4A, 0x68, 0x94, 0x35, 0xB3, 0x53, 0xD1, 0x94, 0x63, 0xA7, 0x20, 0x56, + 0xAF, 0xDE, 0x51, 0x78, 0xEC, 0x2A, 0x3D, 0xF3, 0x48, 0x48, 0x50, 0x3E, + 0x0A, 0xDF, 0x46, 0x55, 0x8B, 0x27, 0x6D, 0xC3, 0x10, 0x4D, 0x0D, 0x91, + 0x52, 0x43, 0xD8, 0x87, 0xE0, 0x5D, 0x4E, 0x36, 0xB5, 0x21, 0xCA, 0x5F, + 0x39, 0x40, 0x04, 0x5F, 0x5B, 0x7E, 0xCC, 0xA3, 0xC6, 0x2B, 0xA9, 0x40, + 0x1E, 0xD9, 0x36, 0x84, 0xD6, 0x48, 0xF3, 0x92, 0x1E, 0x34, 0x46, 0x20, + 0x24, 0xC1, 0xA4, 0x51, 0x8E, 0x4A, 0x1A, 0xEF, 0x50, 0x3F, 0x69, 0x5D, + 0x19, 0x7F, 0x45, 0xC3, 0xC7, 0x01, 0x8F, 0x51, 0xC9, 0x23, 0xE8, 0x72, + 0xAE, 0xB4, 0xBC, 0x56, 0x09, 0x7F, 0x12, 0xCB, 0x1C, 0xB1, 0xAF, 0x29, + 0x90, 0x0A, 0xC9, 0x55, 0xCC, 0x0F, 0xD3, 0xB4, 0x1A, 0xED, 0x47, 0x35, + 0x5A, 0x4A, 0xED, 0x9C, 0x73, 0x04, 0x21, 0xD0, 0xAA, 0xBD, 0x0C, 0x13, + 0xB5, 0x00, 0xCA, 0x26, 0x6C, 0xC4, 0x6B, 0x0C, 0x94, 0x5A, 0x95, 0x94, + 0xDA, 0x50, 0x9A, 0xF1, 0xFF, 0xA5, 0x2B, 0x66, 0x31, 0xA4, 0xC9, 0x38, + 0xA0, 0xDF, 0x1D, 0x1F, 0xB8, 0x09, 0x2E, 0xF3, 0xA7, 0xE8, 0x67, 0x52, + 0xAB, 0x95, 0x1F, 0xE0, 0x46, 0x3E, 0xD8, 0xA4, 0xC3, 0xCA, 0x5A, 0xC5, + 0x31, 0x80, 0xE8, 0x48, 0x9A, 0x9F, 0x94, 0x69, 0xFE, 0x19, 0xDD, 0xD8, + 0x73, 0x7C, 0x81, 0xCA, 0x96, 0xDE, 0x8E, 0xED, 0xB3, 0x32, 0x05, 0x65, + 0x84, 0x34, 0xE6, 0xE6, 0xFD, 0x57, 0x10, 0xB5, 0x5F, 0x76, 0xBF, 0x2F, + 0xB0, 0x10, 0x0D, 0xC5 +}; + +static const unsigned char TA437_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA438_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x21, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x45, 0x56, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA438_RSA_N[] = { + 0x99, 0xF1, 0x84, 0x34, 0x70, 0xBA, 0x2F, 0xB7, 0x30, 0xA0, 0x8E, 0xBD, + 0x7C, 0x04, 0xCF, 0xBE, 0x62, 0xBC, 0x99, 0xFD, 0x82, 0x97, 0xD2, 0x7A, + 0x0A, 0x67, 0x96, 0x38, 0x09, 0xF6, 0x10, 0x4E, 0x95, 0x22, 0x73, 0x99, + 0x8D, 0xDA, 0x15, 0x2D, 0xE7, 0x05, 0xFC, 0x19, 0x73, 0x22, 0xB7, 0x8E, + 0x98, 0x00, 0xBC, 0x3C, 0x3D, 0xAC, 0xA1, 0x6C, 0xFB, 0xD6, 0x79, 0x25, + 0x4B, 0xAD, 0xF0, 0xCC, 0x64, 0xDA, 0x88, 0x3E, 0x29, 0xB8, 0x0F, 0x09, + 0xD3, 0x34, 0xDD, 0x33, 0xF5, 0x62, 0xD1, 0xE1, 0xCD, 0x19, 0xE9, 0xEE, + 0x18, 0x4F, 0x4C, 0x58, 0xAE, 0xE2, 0x1E, 0xD6, 0x0C, 0x5B, 0x15, 0x5A, + 0xD8, 0x3A, 0xB8, 0xC4, 0x18, 0x64, 0x1E, 0xE3, 0x33, 0xB2, 0xB5, 0x89, + 0x77, 0x4E, 0x0C, 0xBF, 0xD9, 0x94, 0x6B, 0x13, 0x97, 0x6F, 0x12, 0xA3, + 0xFE, 0x99, 0xA9, 0x04, 0xCC, 0x15, 0xEC, 0x60, 0x68, 0x36, 0xED, 0x08, + 0x7B, 0xB7, 0xF5, 0xBF, 0x93, 0xED, 0x66, 0x31, 0x83, 0x8C, 0xC6, 0x71, + 0x34, 0x87, 0x4E, 0x17, 0xEA, 0xAF, 0x8B, 0x91, 0x8D, 0x1C, 0x56, 0x41, + 0xAE, 0x22, 0x37, 0x5E, 0x37, 0xF2, 0x1D, 0xD9, 0xD1, 0x2D, 0x0D, 0x2F, + 0x69, 0x51, 0xA7, 0xBE, 0x66, 0xA6, 0x8A, 0x3A, 0x2A, 0xBD, 0xC7, 0x1A, + 0xB1, 0xE1, 0x14, 0xF0, 0xBE, 0x3A, 0x1D, 0xB9, 0xCF, 0x5B, 0xB1, 0x6A, + 0xFE, 0xB4, 0xB1, 0x46, 0x20, 0xA2, 0xFB, 0x1E, 0x3B, 0x70, 0xEF, 0x93, + 0x98, 0x7D, 0x8C, 0x73, 0x96, 0xF2, 0xC5, 0xEF, 0x85, 0x70, 0xAD, 0x29, + 0x26, 0xFC, 0x1E, 0x04, 0x3E, 0x1C, 0xA0, 0xD8, 0x0F, 0xCB, 0x52, 0x83, + 0x62, 0x7C, 0xEE, 0x8B, 0x53, 0x95, 0x90, 0xA9, 0x57, 0xA2, 0xEA, 0x61, + 0x05, 0xD8, 0xF9, 0x4D, 0xC4, 0x27, 0xFA, 0x6E, 0xAD, 0xED, 0xF9, 0xD7, + 0x51, 0xF7, 0x6B, 0xA5 +}; + +static const unsigned char TA438_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA439_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA439_RSA_N[] = { + 0xAD, 0x0E, 0x15, 0xCE, 0xE4, 0x43, 0x80, 0x5C, 0xB1, 0x87, 0xF3, 0xB7, + 0x60, 0xF9, 0x71, 0x12, 0xA5, 0xAE, 0xDC, 0x26, 0x94, 0x88, 0xAA, 0xF4, + 0xCE, 0xF5, 0x20, 0x39, 0x28, 0x58, 0x60, 0x0C, 0xF8, 0x80, 0xDA, 0xA9, + 0x15, 0x95, 0x32, 0x61, 0x3C, 0xB5, 0xB1, 0x28, 0x84, 0x8A, 0x8A, 0xDC, + 0x9F, 0x0A, 0x0C, 0x83, 0x17, 0x7A, 0x8F, 0x90, 0xAC, 0x8A, 0xE7, 0x79, + 0x53, 0x5C, 0x31, 0x84, 0x2A, 0xF6, 0x0F, 0x98, 0x32, 0x36, 0x76, 0xCC, + 0xDE, 0xDD, 0x3C, 0xA8, 0xA2, 0xEF, 0x6A, 0xFB, 0x21, 0xF2, 0x52, 0x61, + 0xDF, 0x9F, 0x20, 0xD7, 0x1F, 0xE2, 0xB1, 0xD9, 0xFE, 0x18, 0x64, 0xD2, + 0x12, 0x5B, 0x5F, 0xF9, 0x58, 0x18, 0x35, 0xBC, 0x47, 0xCD, 0xA1, 0x36, + 0xF9, 0x6B, 0x7F, 0xD4, 0xB0, 0x38, 0x3E, 0xC1, 0x1B, 0xC3, 0x8C, 0x33, + 0xD9, 0xD8, 0x2F, 0x18, 0xFE, 0x28, 0x0F, 0xB3, 0xA7, 0x83, 0xD6, 0xC3, + 0x6E, 0x44, 0xC0, 0x61, 0x35, 0x96, 0x16, 0xFE, 0x59, 0x9C, 0x8B, 0x76, + 0x6D, 0xD7, 0xF1, 0xA2, 0x4B, 0x0D, 0x2B, 0xFF, 0x0B, 0x72, 0xDA, 0x9E, + 0x60, 0xD0, 0x8E, 0x90, 0x35, 0xC6, 0x78, 0x55, 0x87, 0x20, 0xA1, 0xCF, + 0xE5, 0x6D, 0x0A, 0xC8, 0x49, 0x7C, 0x31, 0x98, 0x33, 0x6C, 0x22, 0xE9, + 0x87, 0xD0, 0x32, 0x5A, 0xA2, 0xBA, 0x13, 0x82, 0x11, 0xED, 0x39, 0x17, + 0x9D, 0x99, 0x3A, 0x72, 0xA1, 0xE6, 0xFA, 0xA4, 0xD9, 0xD5, 0x17, 0x31, + 0x75, 0xAE, 0x85, 0x7D, 0x22, 0xAE, 0x3F, 0x01, 0x46, 0x86, 0xF6, 0x28, + 0x79, 0xC8, 0xB1, 0xDA, 0xE4, 0x57, 0x17, 0xC4, 0x7E, 0x1C, 0x0E, 0xB0, + 0xB4, 0x92, 0xA6, 0x56, 0xB3, 0xBD, 0xB2, 0x97, 0xED, 0xAA, 0xA7, 0xF0, + 0xB7, 0xC5, 0xA8, 0x3F, 0x95, 0x16, 0xD0, 0xFF, 0xA1, 0x96, 0xEB, 0x08, + 0x5F, 0x18, 0x77, 0x4F +}; + +static const unsigned char TA439_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA440_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA440_RSA_N[] = { + 0xD9, 0xE7, 0x28, 0x2F, 0x52, 0x3F, 0x36, 0x72, 0x49, 0x88, 0x93, 0x34, + 0xF3, 0xF8, 0x6A, 0x1E, 0x31, 0x54, 0x80, 0x9F, 0xAD, 0x54, 0x41, 0xB5, + 0x47, 0xDF, 0x96, 0xA8, 0xD4, 0xAF, 0x80, 0x2D, 0xB9, 0x0A, 0xCF, 0x75, + 0xFD, 0x89, 0xA5, 0x7D, 0x24, 0xFA, 0xE3, 0x22, 0x0C, 0x2B, 0xBC, 0x95, + 0x17, 0x0B, 0x33, 0xBF, 0x19, 0x4D, 0x41, 0x06, 0x90, 0x00, 0xBD, 0x0C, + 0x4D, 0x10, 0xFE, 0x07, 0xB5, 0xE7, 0x1C, 0x6E, 0x22, 0x55, 0x31, 0x65, + 0x97, 0xBD, 0xD3, 0x17, 0xD2, 0x1E, 0x62, 0xF3, 0xDB, 0xEA, 0x6C, 0x50, + 0x8C, 0x3F, 0x84, 0x0C, 0x96, 0xCF, 0xB7, 0xCB, 0x03, 0xE0, 0xCA, 0x6D, + 0xA1, 0x14, 0x4C, 0x1B, 0x89, 0xDD, 0xED, 0x00, 0xB0, 0x52, 0x7C, 0xAF, + 0x91, 0x6C, 0xB1, 0x38, 0x13, 0xD1, 0xE9, 0x12, 0x08, 0xC0, 0x00, 0xB0, + 0x1C, 0x2B, 0x11, 0xDA, 0x77, 0x70, 0x36, 0x9B, 0xAE, 0xCE, 0x79, 0x87, + 0xDC, 0x82, 0x70, 0xE6, 0x09, 0x74, 0x70, 0x55, 0x69, 0xAF, 0xA3, 0x68, + 0x9F, 0xBF, 0xDD, 0xB6, 0x79, 0xB3, 0xF2, 0x9D, 0x70, 0x29, 0x55, 0xF4, + 0xAB, 0xFF, 0x95, 0x61, 0xF3, 0xC9, 0x40, 0x6F, 0x1D, 0xD1, 0xBE, 0x93, + 0xBB, 0xD3, 0x88, 0x2A, 0xBB, 0x9D, 0xBF, 0x72, 0x5A, 0x56, 0x71, 0x3B, + 0x3F, 0xD4, 0xF3, 0xD1, 0x0A, 0xFE, 0x28, 0xEF, 0xA3, 0xEE, 0xD9, 0x99, + 0xAF, 0x03, 0xD3, 0x8F, 0x60, 0xB7, 0xF2, 0x92, 0xA1, 0xB1, 0xBD, 0x89, + 0x89, 0x1F, 0x30, 0xCD, 0xC3, 0xA6, 0x2E, 0x62, 0x33, 0xAE, 0x16, 0x02, + 0x77, 0x44, 0x5A, 0xE7, 0x81, 0x0A, 0x3C, 0xA7, 0x44, 0x2E, 0x79, 0xB8, + 0x3F, 0x04, 0xBC, 0x5C, 0xA0, 0x87, 0xE1, 0x1B, 0xAF, 0x51, 0x8E, 0xCD, + 0xEC, 0x2C, 0xFA, 0xF8, 0xFE, 0x6D, 0xF0, 0x3A, 0x7C, 0xAA, 0x8B, 0xE4, + 0x67, 0x95, 0x31, 0x8D +}; + +static const unsigned char TA440_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA441_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA441_EC_Q[] = { + 0x04, 0x19, 0xE7, 0xBC, 0xAC, 0x44, 0x65, 0xED, 0xCD, 0xB8, 0x3F, 0x58, + 0xFB, 0x8D, 0xB1, 0x57, 0xA9, 0x44, 0x2D, 0x05, 0x15, 0xF2, 0xEF, 0x0B, + 0xFF, 0x10, 0x74, 0x9F, 0xB5, 0x62, 0x52, 0x5F, 0x66, 0x7E, 0x1F, 0xE5, + 0xDC, 0x1B, 0x45, 0x79, 0x0B, 0xCC, 0xC6, 0x53, 0x0A, 0x9D, 0x8D, 0x5D, + 0x02, 0xD9, 0xA9, 0x59, 0xDE, 0x02, 0x5A, 0xF6, 0x95, 0x2A, 0x0E, 0x8D, + 0x38, 0x4A, 0x8A, 0x49, 0xC6, 0xBC, 0xC6, 0x03, 0x38, 0x07, 0x5F, 0x55, + 0xDA, 0x7E, 0x09, 0x6E, 0xE2, 0x7F, 0x5E, 0xD0, 0x45, 0x20, 0x0F, 0x59, + 0x76, 0x10, 0xD6, 0xA0, 0x24, 0xF0, 0x2D, 0xDE, 0x36, 0xF2, 0x6C, 0x29, + 0x39 +}; + +static const unsigned char TA442_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA442_RSA_N[] = { + 0xE2, 0x3B, 0xE1, 0x11, 0x72, 0xDE, 0xA8, 0xA4, 0xD3, 0xA3, 0x57, 0xAA, + 0x50, 0xA2, 0x8F, 0x0B, 0x77, 0x90, 0xC9, 0xA2, 0xA5, 0xEE, 0x12, 0xCE, + 0x96, 0x5B, 0x01, 0x09, 0x20, 0xCC, 0x01, 0x93, 0xA7, 0x4E, 0x30, 0xB7, + 0x53, 0xF7, 0x43, 0xC4, 0x69, 0x00, 0x57, 0x9D, 0xE2, 0x8D, 0x22, 0xDD, + 0x87, 0x06, 0x40, 0x00, 0x81, 0x09, 0xCE, 0xCE, 0x1B, 0x83, 0xBF, 0xDF, + 0xCD, 0x3B, 0x71, 0x46, 0xE2, 0xD6, 0x66, 0xC7, 0x05, 0xB3, 0x76, 0x27, + 0x16, 0x8F, 0x7B, 0x9E, 0x1E, 0x95, 0x7D, 0xEE, 0xB7, 0x48, 0xA3, 0x08, + 0xDA, 0xD6, 0xAF, 0x7A, 0x0C, 0x39, 0x06, 0x65, 0x7F, 0x4A, 0x5D, 0x1F, + 0xBC, 0x17, 0xF8, 0xAB, 0xBE, 0xEE, 0x28, 0xD7, 0x74, 0x7F, 0x7A, 0x78, + 0x99, 0x59, 0x85, 0x68, 0x6E, 0x5C, 0x23, 0x32, 0x4B, 0xBF, 0x4E, 0xC0, + 0xE8, 0x5A, 0x6D, 0xE3, 0x70, 0xBF, 0x77, 0x10, 0xBF, 0xFC, 0x01, 0xF6, + 0x85, 0xD9, 0xA8, 0x44, 0x10, 0x58, 0x32, 0xA9, 0x75, 0x18, 0xD5, 0xD1, + 0xA2, 0xBE, 0x47, 0xE2, 0x27, 0x6A, 0xF4, 0x9A, 0x33, 0xF8, 0x49, 0x08, + 0x60, 0x8B, 0xD4, 0x5F, 0xB4, 0x3A, 0x84, 0xBF, 0xA1, 0xAA, 0x4A, 0x4C, + 0x7D, 0x3E, 0xCF, 0x4F, 0x5F, 0x6C, 0x76, 0x5E, 0xA0, 0x4B, 0x37, 0x91, + 0x9E, 0xDC, 0x22, 0xE6, 0x6D, 0xCE, 0x14, 0x1A, 0x8E, 0x6A, 0xCB, 0xFE, + 0xCD, 0xB3, 0x14, 0x64, 0x17, 0xC7, 0x5B, 0x29, 0x9E, 0x32, 0xBF, 0xF2, + 0xEE, 0xFA, 0xD3, 0x0B, 0x42, 0xD4, 0xAB, 0xB7, 0x41, 0x32, 0xDA, 0x0C, + 0xD4, 0xEF, 0xF8, 0x81, 0xD5, 0xBB, 0x8D, 0x58, 0x3F, 0xB5, 0x1B, 0xE8, + 0x49, 0x28, 0xA2, 0x70, 0xDA, 0x31, 0x04, 0xDD, 0xF7, 0xB2, 0x16, 0xF2, + 0x4C, 0x0A, 0x4E, 0x07, 0xA8, 0xED, 0x4A, 0x3D, 0x5E, 0xB5, 0x7F, 0xA3, + 0x90, 0xC3, 0xAF, 0x27 +}; + +static const unsigned char TA442_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA443_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x32 +}; + +static const unsigned char TA443_RSA_N[] = { + 0xBB, 0x37, 0xCD, 0x34, 0xDC, 0x7B, 0x6B, 0xC9, 0xB2, 0x68, 0x90, 0xAD, + 0x4A, 0x75, 0xFF, 0x46, 0xBA, 0x21, 0x0A, 0x08, 0x8D, 0xF5, 0x19, 0x54, + 0xC9, 0xFB, 0x88, 0xDB, 0xF3, 0xAE, 0xF2, 0x3A, 0x89, 0x91, 0x3C, 0x7A, + 0xE6, 0xAB, 0x06, 0x1A, 0x6B, 0xCF, 0xAC, 0x2D, 0xE8, 0x5E, 0x09, 0x24, + 0x44, 0xBA, 0x62, 0x9A, 0x7E, 0xD6, 0xA3, 0xA8, 0x7E, 0xE0, 0x54, 0x75, + 0x20, 0x05, 0xAC, 0x50, 0xB7, 0x9C, 0x63, 0x1A, 0x6C, 0x30, 0xDC, 0xDA, + 0x1F, 0x19, 0xB1, 0xD7, 0x1E, 0xDE, 0xFD, 0xD7, 0xE0, 0xCB, 0x94, 0x83, + 0x37, 0xAE, 0xEC, 0x1F, 0x43, 0x4E, 0xDD, 0x7B, 0x2C, 0xD2, 0xBD, 0x2E, + 0xA5, 0x2F, 0xE4, 0xA9, 0xB8, 0xAD, 0x3A, 0xD4, 0x99, 0xA4, 0xB6, 0x25, + 0xE9, 0x9B, 0x6B, 0x00, 0x60, 0x92, 0x60, 0xFF, 0x4F, 0x21, 0x49, 0x18, + 0xF7, 0x67, 0x90, 0xAB, 0x61, 0x06, 0x9C, 0x8F, 0xF2, 0xBA, 0xE9, 0xB4, + 0xE9, 0x92, 0x32, 0x6B, 0xB5, 0xF3, 0x57, 0xE8, 0x5D, 0x1B, 0xCD, 0x8C, + 0x1D, 0xAB, 0x95, 0x04, 0x95, 0x49, 0xF3, 0x35, 0x2D, 0x96, 0xE3, 0x49, + 0x6D, 0xDD, 0x77, 0xE3, 0xFB, 0x49, 0x4B, 0xB4, 0xAC, 0x55, 0x07, 0xA9, + 0x8F, 0x95, 0xB3, 0xB4, 0x23, 0xBB, 0x4C, 0x6D, 0x45, 0xF0, 0xF6, 0xA9, + 0xB2, 0x95, 0x30, 0xB4, 0xFD, 0x4C, 0x55, 0x8C, 0x27, 0x4A, 0x57, 0x14, + 0x7C, 0x82, 0x9D, 0xCD, 0x73, 0x92, 0xD3, 0x16, 0x4A, 0x06, 0x0C, 0x8C, + 0x50, 0xD1, 0x8F, 0x1E, 0x09, 0xBE, 0x17, 0xA1, 0xE6, 0x21, 0xCA, 0xFD, + 0x83, 0xE5, 0x10, 0xBC, 0x83, 0xA5, 0x0A, 0xC4, 0x67, 0x28, 0xF6, 0x73, + 0x14, 0x14, 0x3D, 0x46, 0x76, 0xC3, 0x87, 0x14, 0x89, 0x21, 0x34, 0x4D, + 0xAF, 0x0F, 0x45, 0x0C, 0xA6, 0x49, 0xA1, 0xBA, 0xBB, 0x9C, 0xC5, 0xB1, + 0x33, 0x83, 0x29, 0x85 +}; + +static const unsigned char TA443_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA444_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x33 +}; + +static const unsigned char TA444_EC_Q[] = { + 0x04, 0xDD, 0xA7, 0xD9, 0xBB, 0x8A, 0xB8, 0x0B, 0xFB, 0x0B, 0x7F, 0x21, + 0xD2, 0xF0, 0xBE, 0xBE, 0x73, 0xF3, 0x33, 0x5D, 0x1A, 0xBC, 0x34, 0xEA, + 0xDE, 0xC6, 0x9B, 0xBC, 0xD0, 0x95, 0xF6, 0xF0, 0xCC, 0xD0, 0x0B, 0xBA, + 0x61, 0x5B, 0x51, 0x46, 0x7E, 0x9E, 0x2D, 0x9F, 0xEE, 0x8E, 0x63, 0x0C, + 0x17, 0xEC, 0x07, 0x70, 0xF5, 0xCF, 0x84, 0x2E, 0x40, 0x83, 0x9C, 0xE8, + 0x3F, 0x41, 0x6D, 0x3B, 0xAD, 0xD3, 0xA4, 0x14, 0x59, 0x36, 0x78, 0x9D, + 0x03, 0x43, 0xEE, 0x10, 0x13, 0x6C, 0x72, 0xDE, 0xAE, 0x88, 0xA7, 0xA1, + 0x6B, 0xB5, 0x43, 0xCE, 0x67, 0xDC, 0x23, 0xFF, 0x03, 0x1C, 0xA3, 0xE2, + 0x3E +}; + +static const unsigned char TA445_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, + 0x6E, 0x63, 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA445_RSA_N[] = { + 0xC6, 0xCC, 0xE5, 0x73, 0xE6, 0xFB, 0xD4, 0xBB, 0xE5, 0x2D, 0x2D, 0x32, + 0xA6, 0xDF, 0xE5, 0x81, 0x3F, 0xC9, 0xCD, 0x25, 0x49, 0xB6, 0x71, 0x2A, + 0xC3, 0xD5, 0x94, 0x34, 0x67, 0xA2, 0x0A, 0x1C, 0xB0, 0x5F, 0x69, 0xA6, + 0x40, 0xB1, 0xC4, 0xB7, 0xB2, 0x8F, 0xD0, 0x98, 0xA4, 0xA9, 0x41, 0x59, + 0x3A, 0xD3, 0xDC, 0x94, 0xD6, 0x3C, 0xDB, 0x74, 0x38, 0xA4, 0x4A, 0xCC, + 0x4D, 0x25, 0x82, 0xF7, 0x4A, 0xA5, 0x53, 0x12, 0x38, 0xEE, 0xF3, 0x49, + 0x6D, 0x71, 0x91, 0x7E, 0x63, 0xB6, 0xAB, 0xA6, 0x5F, 0xC3, 0xA4, 0x84, + 0xF8, 0x4F, 0x62, 0x51, 0xBE, 0xF8, 0xC5, 0xEC, 0xDB, 0x38, 0x92, 0xE3, + 0x06, 0xE5, 0x08, 0x91, 0x0C, 0xC4, 0x28, 0x41, 0x55, 0xFB, 0xCB, 0x5A, + 0x89, 0x15, 0x7E, 0x71, 0xE8, 0x35, 0xBF, 0x4D, 0x72, 0x09, 0x3D, 0xBE, + 0x3A, 0x38, 0x50, 0x5B, 0x77, 0x31, 0x1B, 0x8D, 0xB3, 0xC7, 0x24, 0x45, + 0x9A, 0xA7, 0xAC, 0x6D, 0x00, 0x14, 0x5A, 0x04, 0xB7, 0xBA, 0x13, 0xEB, + 0x51, 0x0A, 0x98, 0x41, 0x41, 0x22, 0x4E, 0x65, 0x61, 0x87, 0x81, 0x41, + 0x50, 0xA6, 0x79, 0x5C, 0x89, 0xDE, 0x19, 0x4A, 0x57, 0xD5, 0x2E, 0xE6, + 0x5D, 0x1C, 0x53, 0x2C, 0x7E, 0x98, 0xCD, 0x1A, 0x06, 0x16, 0xA4, 0x68, + 0x73, 0xD0, 0x34, 0x04, 0x13, 0x5C, 0xA1, 0x71, 0xD3, 0x5A, 0x7C, 0x55, + 0xDB, 0x5E, 0x64, 0xE1, 0x37, 0x87, 0x30, 0x56, 0x04, 0xE5, 0x11, 0xB4, + 0x29, 0x80, 0x12, 0xF1, 0x79, 0x39, 0x88, 0xA2, 0x02, 0x11, 0x7C, 0x27, + 0x66, 0xB7, 0x88, 0xB7, 0x78, 0xF2, 0xCA, 0x0A, 0xA8, 0x38, 0xAB, 0x0A, + 0x64, 0xC2, 0xBF, 0x66, 0x5D, 0x95, 0x84, 0xC1, 0xA1, 0x25, 0x1E, 0x87, + 0x5D, 0x1A, 0x50, 0x0B, 0x20, 0x12, 0xCC, 0x41, 0xBB, 0x6E, 0x0B, 0x51, + 0x38, 0xB8, 0x4B, 0xCB +}; + +static const unsigned char TA445_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA446_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1D, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x50, 0x33, 0x38, 0x34, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA446_EC_Q[] = { + 0x04, 0xC1, 0x44, 0xA1, 0xCF, 0x11, 0x97, 0x50, 0x9A, 0xDE, 0x23, 0x82, + 0x35, 0x07, 0xCD, 0xD0, 0xCB, 0x18, 0x9D, 0xD2, 0xF1, 0x7F, 0x77, 0x35, + 0x4F, 0x3B, 0xDD, 0x94, 0x72, 0x52, 0xED, 0xC2, 0x3B, 0xF8, 0xEC, 0xFA, + 0x7B, 0x6B, 0x58, 0x20, 0xEC, 0x99, 0xAE, 0xC9, 0xFC, 0x68, 0xB3, 0x75, + 0xB9, 0xDB, 0x09, 0xEC, 0xC8, 0x13, 0xF5, 0x4E, 0xC6, 0x0A, 0x1D, 0x66, + 0x30, 0x4C, 0xBB, 0x1F, 0x47, 0x0A, 0x3C, 0x61, 0x10, 0x42, 0x29, 0x7C, + 0xA5, 0x08, 0x0E, 0xE0, 0x22, 0xE9, 0xD3, 0x35, 0x68, 0xCE, 0x9B, 0x63, + 0x9F, 0x84, 0xB5, 0x99, 0x4D, 0x58, 0xA0, 0x8E, 0xF5, 0x54, 0xE7, 0x95, + 0xC9 +}; + +static const unsigned char TA447_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x34, 0x30, 0x39, 0x36, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA447_RSA_N[] = { + 0xB3, 0xD0, 0xF4, 0xC9, 0x79, 0x11, 0x9D, 0xFD, 0xFC, 0x66, 0x81, 0xE7, + 0xCC, 0xD5, 0xE4, 0xBC, 0xEC, 0x81, 0x3E, 0x6A, 0x35, 0x8E, 0x2E, 0xB7, + 0xE7, 0xDE, 0xAF, 0xF9, 0x07, 0x4D, 0xCF, 0x30, 0x9D, 0xEA, 0x09, 0x0B, + 0x99, 0xBD, 0x6C, 0x57, 0xDA, 0x18, 0x4A, 0xB8, 0x78, 0xAC, 0x3A, 0x39, + 0xA8, 0xA6, 0x48, 0xAC, 0x2E, 0x72, 0xE5, 0xBD, 0xEB, 0xF1, 0x1A, 0xCD, + 0xE7, 0xA4, 0x03, 0xA9, 0x3F, 0x11, 0xB4, 0xD8, 0x2F, 0x89, 0x16, 0xFB, + 0x94, 0x01, 0x3D, 0xBB, 0x2F, 0xF8, 0x13, 0x05, 0xA1, 0x78, 0x1C, 0x8E, + 0x28, 0xE0, 0x45, 0xE0, 0x83, 0xF4, 0x59, 0x1B, 0x95, 0xB3, 0xAE, 0x7E, + 0x03, 0x45, 0xE5, 0xBE, 0xC2, 0x42, 0xFE, 0xEE, 0xF2, 0x3C, 0xB6, 0x85, + 0x13, 0x98, 0x32, 0x9D, 0x16, 0xA8, 0x29, 0xC2, 0x0B, 0x1C, 0x38, 0xDC, + 0x9F, 0x31, 0x77, 0x5C, 0xBF, 0x27, 0xA3, 0xFC, 0x27, 0xAC, 0xB7, 0x2B, + 0xBD, 0x74, 0x9B, 0x17, 0x2D, 0xF2, 0x81, 0xDA, 0x5D, 0xB0, 0xE1, 0x23, + 0x17, 0x3E, 0x88, 0x4A, 0x12, 0x23, 0xD0, 0xEA, 0xCF, 0x9D, 0xDE, 0x03, + 0x17, 0xB1, 0x42, 0x4A, 0xA0, 0x16, 0x4C, 0xA4, 0x6D, 0x93, 0xE9, 0x3F, + 0x3A, 0xEE, 0x3A, 0x7C, 0x9D, 0x58, 0x9D, 0xF4, 0x4E, 0x8F, 0xFC, 0x3B, + 0x23, 0xC8, 0x6D, 0xB8, 0xE2, 0x05, 0xDA, 0xCC, 0xEB, 0xEC, 0xC3, 0x31, + 0xF4, 0xD7, 0xA7, 0x29, 0x54, 0x80, 0xCF, 0x44, 0x5B, 0x4C, 0x6F, 0x30, + 0x9E, 0xF3, 0xCC, 0xDD, 0x1F, 0x94, 0x43, 0x9D, 0x4D, 0x7F, 0x70, 0x70, + 0x0D, 0xD4, 0x3A, 0xD1, 0x37, 0xF0, 0x6C, 0x9D, 0x9B, 0xC0, 0x14, 0x93, + 0x58, 0xEF, 0xCD, 0x41, 0x38, 0x75, 0xBC, 0x13, 0x03, 0x95, 0x7C, 0x7F, + 0xE3, 0x5C, 0xE9, 0xD5, 0x0D, 0xD5, 0xE2, 0x7C, 0x10, 0x62, 0xAA, 0x6B, + 0xF0, 0x3D, 0x76, 0xF3, 0x3F, 0xA3, 0xE8, 0xB0, 0xC1, 0xFD, 0xEF, 0xAA, + 0x57, 0x4D, 0xAC, 0x86, 0xA7, 0x18, 0xB4, 0x29, 0xC1, 0x2C, 0x0E, 0xBF, + 0x64, 0xBE, 0x29, 0x8C, 0xD8, 0x02, 0x2D, 0xCD, 0x5C, 0x2F, 0xF2, 0x7F, + 0xEF, 0x15, 0xF4, 0x0C, 0x15, 0xAC, 0x0A, 0xB0, 0xF1, 0xD3, 0x0D, 0x4F, + 0x6A, 0x4D, 0x77, 0x97, 0x01, 0xA0, 0xF1, 0x66, 0xB7, 0xB7, 0xCE, 0xEF, + 0xCE, 0xEC, 0xEC, 0xA5, 0x75, 0xCA, 0xAC, 0xE3, 0xE1, 0x63, 0xF7, 0xB8, + 0xA1, 0x04, 0xC8, 0xBC, 0x7B, 0x3F, 0x5D, 0x2D, 0x16, 0x22, 0x56, 0xED, + 0x48, 0x49, 0xFE, 0xA7, 0x2F, 0x79, 0x30, 0x25, 0x9B, 0xBA, 0x6B, 0x2D, + 0x3F, 0x9D, 0x3B, 0xC4, 0x17, 0xE7, 0x1D, 0x2E, 0xFB, 0xF2, 0xCF, 0xA6, + 0xFC, 0xE3, 0x14, 0x2C, 0x96, 0x98, 0x21, 0x8C, 0xB4, 0x91, 0xE9, 0x19, + 0x60, 0x83, 0xF2, 0x30, 0x2B, 0x06, 0x73, 0x50, 0xD5, 0x98, 0x3B, 0x06, + 0xE9, 0xC7, 0x8A, 0x0C, 0x60, 0x8C, 0x28, 0xF8, 0x52, 0x9B, 0x6E, 0xE1, + 0xF6, 0x4D, 0xBB, 0x06, 0x24, 0x9B, 0xD7, 0x2B, 0x26, 0x3F, 0xFD, 0x2A, + 0x2F, 0x71, 0xF5, 0xD6, 0x24, 0xBE, 0x7F, 0x31, 0x9E, 0x0F, 0x6D, 0xE8, + 0x8F, 0x4F, 0x4D, 0xA3, 0x3F, 0xFF, 0x35, 0xEA, 0xDF, 0x49, 0x5E, 0x41, + 0x8F, 0x86, 0xF9, 0xF1, 0x77, 0x79, 0x4B, 0x1B, 0xB4, 0xA3, 0x5E, 0x2F, + 0xFB, 0x46, 0x02, 0xD0, 0x66, 0x13, 0x5E, 0x5E, 0x85, 0x4F, 0xCE, 0xD8, + 0x70, 0x88, 0x7B, 0xCE, 0x01, 0xB5, 0x96, 0x97, 0xD7, 0xCD, 0x7D, 0xFD, + 0x82, 0xF8, 0xC2, 0x24, 0xC1, 0xCA, 0x01, 0x39, 0x4F, 0x8D, 0xA2, 0xC1, + 0x14, 0x40, 0x1F, 0x9C, 0x66, 0xD5, 0x0C, 0x09, 0x46, 0xD6, 0xF2, 0xD0, + 0xD1, 0x48, 0x76, 0x56, 0x3A, 0x43, 0xCB, 0xB6, 0x0A, 0x11, 0x39, 0xBA, + 0x8C, 0x13, 0x6C, 0x06, 0xB5, 0x9E, 0xCF, 0xEB +}; + +static const unsigned char TA447_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA448_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x18, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA448_RSA_N[] = { + 0xBF, 0xE6, 0x90, 0x73, 0x68, 0xDE, 0xBB, 0xE4, 0x5D, 0x4A, 0x3C, 0x30, + 0x22, 0x30, 0x69, 0x33, 0xEC, 0xC2, 0xA7, 0x25, 0x2E, 0xC9, 0x21, 0x3D, + 0xF2, 0x8A, 0xD8, 0x59, 0xC2, 0xE1, 0x29, 0xA7, 0x3D, 0x58, 0xAB, 0x76, + 0x9A, 0xCD, 0xAE, 0x7B, 0x1B, 0x84, 0x0D, 0xC4, 0x30, 0x1F, 0xF3, 0x1B, + 0xA4, 0x38, 0x16, 0xEB, 0x56, 0xC6, 0x97, 0x6D, 0x1D, 0xAB, 0xB2, 0x79, + 0xF2, 0xCA, 0x11, 0xD2, 0xE4, 0x5F, 0xD6, 0x05, 0x3C, 0x52, 0x0F, 0x52, + 0x1F, 0xC6, 0x9E, 0x15, 0xA5, 0x7E, 0xBE, 0x9F, 0xA9, 0x57, 0x16, 0x59, + 0x55, 0x72, 0xAF, 0x68, 0x93, 0x70, 0xC2, 0xB2, 0xBA, 0x75, 0x99, 0x6A, + 0x73, 0x32, 0x94, 0xD1, 0x10, 0x44, 0x10, 0x2E, 0xDF, 0x82, 0xF3, 0x07, + 0x84, 0xE6, 0x74, 0x3B, 0x6D, 0x71, 0xE2, 0x2D, 0x0C, 0x1B, 0xEE, 0x20, + 0xD5, 0xC9, 0x20, 0x1D, 0x63, 0x29, 0x2D, 0xCE, 0xEC, 0x5E, 0x4E, 0xC8, + 0x93, 0xF8, 0x21, 0x61, 0x9B, 0x34, 0xEB, 0x05, 0xC6, 0x5E, 0xEC, 0x5B, + 0x1A, 0xBC, 0xEB, 0xC9, 0xCF, 0xCD, 0xAC, 0x34, 0x40, 0x5F, 0xB1, 0x7A, + 0x66, 0xEE, 0x77, 0xC8, 0x48, 0xA8, 0x66, 0x57, 0x57, 0x9F, 0x54, 0x58, + 0x8E, 0x0C, 0x2B, 0xB7, 0x4F, 0xA7, 0x30, 0xD9, 0x56, 0xEE, 0xCA, 0x7B, + 0x5D, 0xE3, 0xAD, 0xC9, 0x4F, 0x5E, 0xE5, 0x35, 0xE7, 0x31, 0xCB, 0xDA, + 0x93, 0x5E, 0xDC, 0x8E, 0x8F, 0x80, 0xDA, 0xB6, 0x91, 0x98, 0x40, 0x90, + 0x79, 0xC3, 0x78, 0xC7, 0xB6, 0xB1, 0xC4, 0xB5, 0x6A, 0x18, 0x38, 0x03, + 0x10, 0x8D, 0xD8, 0xD4, 0x37, 0xA4, 0x2E, 0x05, 0x7D, 0x88, 0xF5, 0x82, + 0x3E, 0x10, 0x91, 0x70, 0xAB, 0x55, 0x82, 0x41, 0x32, 0xD7, 0xDB, 0x04, + 0x73, 0x2A, 0x6E, 0x91, 0x01, 0x7C, 0x21, 0x4C, 0xD4, 0xBC, 0xAE, 0x1B, + 0x03, 0x75, 0x5D, 0x78, 0x66, 0xD9, 0x3A, 0x31, 0x44, 0x9A, 0x33, 0x40, + 0xBF, 0x08, 0xD7, 0x5A, 0x49, 0xA4, 0xC2, 0xE6, 0xA9, 0xA0, 0x67, 0xDD, + 0xA4, 0x27, 0xBC, 0xA1, 0x4F, 0x39, 0xB5, 0x11, 0x58, 0x17, 0xF7, 0x24, + 0x5C, 0x46, 0x8F, 0x64, 0xF7, 0xC1, 0x69, 0x88, 0x76, 0x98, 0x76, 0x3D, + 0x59, 0x5D, 0x42, 0x76, 0x87, 0x89, 0x97, 0x69, 0x7A, 0x48, 0xF0, 0xE0, + 0xA2, 0x12, 0x1B, 0x66, 0x9A, 0x74, 0xCA, 0xDE, 0x4B, 0x1E, 0xE7, 0x0E, + 0x63, 0xAE, 0xE6, 0xD4, 0xEF, 0x92, 0x92, 0x3A, 0x9E, 0x3D, 0xDC, 0x00, + 0xE4, 0x45, 0x25, 0x89, 0xB6, 0x9A, 0x44, 0x19, 0x2B, 0x7E, 0xC0, 0x94, + 0xB4, 0xD2, 0x61, 0x6D, 0xEB, 0x33, 0xD9, 0xC5, 0xDF, 0x4B, 0x04, 0x00, + 0xCC, 0x7D, 0x1C, 0x95, 0xC3, 0x8F, 0xF7, 0x21, 0xB2, 0xB2, 0x11, 0xB7, + 0xBB, 0x7F, 0xF2, 0xD5, 0x8C, 0x70, 0x2C, 0x41, 0x60, 0xAA, 0xB1, 0x63, + 0x18, 0x44, 0x95, 0x1A, 0x76, 0x62, 0x7E, 0xF6, 0x80, 0xB0, 0xFB, 0xE8, + 0x64, 0xA6, 0x33, 0xD1, 0x89, 0x07, 0xE1, 0xBD, 0xB7, 0xE6, 0x43, 0xA4, + 0x18, 0xB8, 0xA6, 0x77, 0x01, 0xE1, 0x0F, 0x94, 0x0C, 0x21, 0x1D, 0xB2, + 0x54, 0x29, 0x25, 0x89, 0x6C, 0xE5, 0x0E, 0x52, 0x51, 0x47, 0x74, 0xBE, + 0x26, 0xAC, 0xB6, 0x41, 0x75, 0xDE, 0x7A, 0xAC, 0x5F, 0x8D, 0x3F, 0xC9, + 0xBC, 0xD3, 0x41, 0x11, 0x12, 0x5B, 0xE5, 0x10, 0x50, 0xEB, 0x31, 0xC5, + 0xCA, 0x72, 0x16, 0x22, 0x09, 0xDF, 0x7C, 0x4C, 0x75, 0x3F, 0x63, 0xEC, + 0x21, 0x5F, 0xC4, 0x20, 0x51, 0x6B, 0x6F, 0xB1, 0xAB, 0x86, 0x8B, 0x4F, + 0xC2, 0xD6, 0x45, 0x5F, 0x9D, 0x20, 0xFC, 0xA1, 0x1E, 0xC5, 0xC0, 0x8F, + 0xA2, 0xB1, 0x7E, 0x0A, 0x26, 0x99, 0xF5, 0xE4, 0x69, 0x2F, 0x98, 0x1D, + 0x2D, 0xF5, 0xD9, 0xA9, 0xB2, 0x1D, 0xE5, 0x1B +}; + +static const unsigned char TA448_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA449_DN[] = { + 0x30, 0x81, 0xB4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, + 0x74, 0x31, 0x40, 0x30, 0x3E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x14, 0x37, + 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, + 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x5F, 0x32, 0x30, 0x34, 0x38, + 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x2E, 0x20, 0x62, 0x79, 0x20, + 0x72, 0x65, 0x66, 0x2E, 0x20, 0x28, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x73, + 0x20, 0x6C, 0x69, 0x61, 0x62, 0x2E, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1C, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, + 0x65, 0x74, 0x20, 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, + 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, + 0x34, 0x38, 0x29 +}; + +static const unsigned char TA449_RSA_N[] = { + 0xAD, 0x4D, 0x4B, 0xA9, 0x12, 0x86, 0xB2, 0xEA, 0xA3, 0x20, 0x07, 0x15, + 0x16, 0x64, 0x2A, 0x2B, 0x4B, 0xD1, 0xBF, 0x0B, 0x4A, 0x4D, 0x8E, 0xED, + 0x80, 0x76, 0xA5, 0x67, 0xB7, 0x78, 0x40, 0xC0, 0x73, 0x42, 0xC8, 0x68, + 0xC0, 0xDB, 0x53, 0x2B, 0xDD, 0x5E, 0xB8, 0x76, 0x98, 0x35, 0x93, 0x8B, + 0x1A, 0x9D, 0x7C, 0x13, 0x3A, 0x0E, 0x1F, 0x5B, 0xB7, 0x1E, 0xCF, 0xE5, + 0x24, 0x14, 0x1E, 0xB1, 0x81, 0xA9, 0x8D, 0x7D, 0xB8, 0xCC, 0x6B, 0x4B, + 0x03, 0xF1, 0x02, 0x0C, 0xDC, 0xAB, 0xA5, 0x40, 0x24, 0x00, 0x7F, 0x74, + 0x94, 0xA1, 0x9D, 0x08, 0x29, 0xB3, 0x88, 0x0B, 0xF5, 0x87, 0x77, 0x9D, + 0x55, 0xCD, 0xE4, 0xC3, 0x7E, 0xD7, 0x6A, 0x64, 0xAB, 0x85, 0x14, 0x86, + 0x95, 0x5B, 0x97, 0x32, 0x50, 0x6F, 0x3D, 0xC8, 0xBA, 0x66, 0x0C, 0xE3, + 0xFC, 0xBD, 0xB8, 0x49, 0xC1, 0x76, 0x89, 0x49, 0x19, 0xFD, 0xC0, 0xA8, + 0xBD, 0x89, 0xA3, 0x67, 0x2F, 0xC6, 0x9F, 0xBC, 0x71, 0x19, 0x60, 0xB8, + 0x2D, 0xE9, 0x2C, 0xC9, 0x90, 0x76, 0x66, 0x7B, 0x94, 0xE2, 0xAF, 0x78, + 0xD6, 0x65, 0x53, 0x5D, 0x3C, 0xD6, 0x9C, 0xB2, 0xCF, 0x29, 0x03, 0xF9, + 0x2F, 0xA4, 0x50, 0xB2, 0xD4, 0x48, 0xCE, 0x05, 0x32, 0x55, 0x8A, 0xFD, + 0xB2, 0x64, 0x4C, 0x0E, 0xE4, 0x98, 0x07, 0x75, 0xDB, 0x7F, 0xDF, 0xB9, + 0x08, 0x55, 0x60, 0x85, 0x30, 0x29, 0xF9, 0x7B, 0x48, 0xA4, 0x69, 0x86, + 0xE3, 0x35, 0x3F, 0x1E, 0x86, 0x5D, 0x7A, 0x7A, 0x15, 0xBD, 0xEF, 0x00, + 0x8E, 0x15, 0x22, 0x54, 0x17, 0x00, 0x90, 0x26, 0x93, 0xBC, 0x0E, 0x49, + 0x68, 0x91, 0xBF, 0xF8, 0x47, 0xD3, 0x9D, 0x95, 0x42, 0xC1, 0x0E, 0x4D, + 0xDF, 0x6F, 0x26, 0xCF, 0xC3, 0x18, 0x21, 0x62, 0x66, 0x43, 0x70, 0xD6, + 0xD5, 0xC0, 0x07, 0xE1 +}; + +static const unsigned char TA449_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA450_DN[] = { + 0x30, 0x81, 0xB0, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x30, 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x20, 0x69, + 0x73, 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6E, 0x63, 0x65, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x16, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, + 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA450_RSA_N[] = { + 0xB6, 0x95, 0xB6, 0x43, 0x42, 0xFA, 0xC6, 0x6D, 0x2A, 0x6F, 0x48, 0xDF, + 0x94, 0x4C, 0x39, 0x57, 0x05, 0xEE, 0xC3, 0x79, 0x11, 0x41, 0x68, 0x36, + 0xED, 0xEC, 0xFE, 0x9A, 0x01, 0x8F, 0xA1, 0x38, 0x28, 0xFC, 0xF7, 0x10, + 0x46, 0x66, 0x2E, 0x4D, 0x1E, 0x1A, 0xB1, 0x1A, 0x4E, 0xC6, 0xD1, 0xC0, + 0x95, 0x88, 0xB0, 0xC9, 0xFF, 0x31, 0x8B, 0x33, 0x03, 0xDB, 0xB7, 0x83, + 0x7B, 0x3E, 0x20, 0x84, 0x5E, 0xED, 0xB2, 0x56, 0x28, 0xA7, 0xF8, 0xE0, + 0xB9, 0x40, 0x71, 0x37, 0xC5, 0xCB, 0x47, 0x0E, 0x97, 0x2A, 0x68, 0xC0, + 0x22, 0x95, 0x62, 0x15, 0xDB, 0x47, 0xD9, 0xF5, 0xD0, 0x2B, 0xFF, 0x82, + 0x4B, 0xC9, 0xAD, 0x3E, 0xDE, 0x4C, 0xDB, 0x90, 0x80, 0x50, 0x3F, 0x09, + 0x8A, 0x84, 0x00, 0xEC, 0x30, 0x0A, 0x3D, 0x18, 0xCD, 0xFB, 0xFD, 0x2A, + 0x59, 0x9A, 0x23, 0x95, 0x17, 0x2C, 0x45, 0x9E, 0x1F, 0x6E, 0x43, 0x79, + 0x6D, 0x0C, 0x5C, 0x98, 0xFE, 0x48, 0xA7, 0xC5, 0x23, 0x47, 0x5C, 0x5E, + 0xFD, 0x6E, 0xE7, 0x1E, 0xB4, 0xF6, 0x68, 0x45, 0xD1, 0x86, 0x83, 0x5B, + 0xA2, 0x8A, 0x8D, 0xB1, 0xE3, 0x29, 0x80, 0xFE, 0x25, 0x71, 0x88, 0xAD, + 0xBE, 0xBC, 0x8F, 0xAC, 0x52, 0x96, 0x4B, 0xAA, 0x51, 0x8D, 0xE4, 0x13, + 0x31, 0x19, 0xE8, 0x4E, 0x4D, 0x9F, 0xDB, 0xAC, 0xB3, 0x6A, 0xD5, 0xBC, + 0x39, 0x54, 0x71, 0xCA, 0x7A, 0x7A, 0x7F, 0x90, 0xDD, 0x7D, 0x1D, 0x80, + 0xD9, 0x81, 0xBB, 0x59, 0x26, 0xC2, 0x11, 0xFE, 0xE6, 0x93, 0xE2, 0xF7, + 0x80, 0xE4, 0x65, 0xFB, 0x34, 0x37, 0x0E, 0x29, 0x80, 0x70, 0x4D, 0xAF, + 0x38, 0x86, 0x2E, 0x9E, 0x7F, 0x57, 0xAF, 0x9E, 0x17, 0xAE, 0xEB, 0x1C, + 0xCB, 0x28, 0x21, 0x5F, 0xB6, 0x1C, 0xD8, 0xE7, 0xA2, 0x04, 0x22, 0xF9, + 0xD3, 0xDA, 0xD8, 0xCB +}; + +static const unsigned char TA450_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA451_DN[] = { + 0x30, 0x81, 0xBF, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x33, 0x30, + 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x45, + 0x43, 0x31 +}; + +static const unsigned char TA451_EC_Q[] = { + 0x04, 0x84, 0x13, 0xC9, 0xD0, 0xBA, 0x6D, 0x41, 0x7B, 0xE2, 0x6C, 0xD0, + 0xEB, 0x55, 0x5F, 0x66, 0x02, 0x1A, 0x24, 0xF4, 0x5B, 0x89, 0x69, 0x47, + 0xE3, 0xB8, 0xC2, 0x7D, 0xF1, 0xF2, 0x02, 0xC5, 0x9F, 0xA0, 0xF6, 0x5B, + 0xD5, 0x8B, 0x06, 0x19, 0x86, 0x4F, 0x53, 0x10, 0x6D, 0x07, 0x24, 0x27, + 0xA1, 0xA0, 0xF8, 0xD5, 0x47, 0x19, 0x61, 0x4C, 0x7D, 0xCA, 0x93, 0x27, + 0xEA, 0x74, 0x0C, 0xEF, 0x6F, 0x96, 0x09, 0xFE, 0x63, 0xEC, 0x70, 0x5D, + 0x36, 0xAD, 0x67, 0x77, 0xAE, 0xC9, 0x9D, 0x7C, 0x55, 0x44, 0x3A, 0xA2, + 0x63, 0x51, 0x1F, 0xF5, 0xE3, 0x62, 0xD4, 0xA9, 0x47, 0x07, 0x3E, 0xCC, + 0x20 +}; + +static const unsigned char TA452_DN[] = { + 0x30, 0x81, 0xBE, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x32, 0x30, + 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, + 0x32 +}; + +static const unsigned char TA452_RSA_N[] = { + 0xBA, 0x84, 0xB6, 0x72, 0xDB, 0x9E, 0x0C, 0x6B, 0xE2, 0x99, 0xE9, 0x30, + 0x01, 0xA7, 0x76, 0xEA, 0x32, 0xB8, 0x95, 0x41, 0x1A, 0xC9, 0xDA, 0x61, + 0x4E, 0x58, 0x72, 0xCF, 0xFE, 0xF6, 0x82, 0x79, 0xBF, 0x73, 0x61, 0x06, + 0x0A, 0xA5, 0x27, 0xD8, 0xB3, 0x5F, 0xD3, 0x45, 0x4E, 0x1C, 0x72, 0xD6, + 0x4E, 0x32, 0xF2, 0x72, 0x8A, 0x0F, 0xF7, 0x83, 0x19, 0xD0, 0x6A, 0x80, + 0x80, 0x00, 0x45, 0x1E, 0xB0, 0xC7, 0xE7, 0x9A, 0xBF, 0x12, 0x57, 0x27, + 0x1C, 0xA3, 0x68, 0x2F, 0x0A, 0x87, 0xBD, 0x6A, 0x6B, 0x0E, 0x5E, 0x65, + 0xF3, 0x1C, 0x77, 0xD5, 0xD4, 0x85, 0x8D, 0x70, 0x21, 0xB4, 0xB3, 0x32, + 0xE7, 0x8B, 0xA2, 0xD5, 0x86, 0x39, 0x02, 0xB1, 0xB8, 0xD2, 0x47, 0xCE, + 0xE4, 0xC9, 0x49, 0xC4, 0x3B, 0xA7, 0xDE, 0xFB, 0x54, 0x7D, 0x57, 0xBE, + 0xF0, 0xE8, 0x6E, 0xC2, 0x79, 0xB2, 0x3A, 0x0B, 0x55, 0xE2, 0x50, 0x98, + 0x16, 0x32, 0x13, 0x5C, 0x2F, 0x78, 0x56, 0xC1, 0xC2, 0x94, 0xB3, 0xF2, + 0x5A, 0xE4, 0x27, 0x9A, 0x9F, 0x24, 0xD7, 0xC6, 0xEC, 0xD0, 0x9B, 0x25, + 0x82, 0xE3, 0xCC, 0xC2, 0xC4, 0x45, 0xC5, 0x8C, 0x97, 0x7A, 0x06, 0x6B, + 0x2A, 0x11, 0x9F, 0xA9, 0x0A, 0x6E, 0x48, 0x3B, 0x6F, 0xDB, 0xD4, 0x11, + 0x19, 0x42, 0xF7, 0x8F, 0x07, 0xBF, 0xF5, 0x53, 0x5F, 0x9C, 0x3E, 0xF4, + 0x17, 0x2C, 0xE6, 0x69, 0xAC, 0x4E, 0x32, 0x4C, 0x62, 0x77, 0xEA, 0xB7, + 0xE8, 0xE5, 0xBB, 0x34, 0xBC, 0x19, 0x8B, 0xAE, 0x9C, 0x51, 0xE7, 0xB7, + 0x7E, 0xB5, 0x53, 0xB1, 0x33, 0x22, 0xE5, 0x6D, 0xCF, 0x70, 0x3C, 0x1A, + 0xFA, 0xE2, 0x9B, 0x67, 0xB6, 0x83, 0xF4, 0x8D, 0xA5, 0xAF, 0x62, 0x4C, + 0x4D, 0xE0, 0x58, 0xAC, 0x64, 0x34, 0x12, 0x03, 0xF8, 0xB6, 0x8D, 0x94, + 0x63, 0x24, 0xA4, 0x71 +}; + +static const unsigned char TA452_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA453_DN[] = { + 0x30, 0x6E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x13, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, 0x6F, 0x66, 0x65, + 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x53, 0x41, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0F, 0x56, 0x41, 0x54, 0x45, + 0x53, 0x2D, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x46, 0x49, + 0x52, 0x4D, 0x41, 0x50, 0x52, 0x4F, 0x46, 0x45, 0x53, 0x49, 0x4F, 0x4E, + 0x41, 0x4C, 0x20, 0x43, 0x41, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x2D, 0x41, + 0x20, 0x57, 0x45, 0x42 +}; + +static const unsigned char TA453_EC_Q[] = { + 0x04, 0x47, 0x53, 0xEA, 0x2C, 0x11, 0xA4, 0x77, 0xC7, 0x2A, 0xEA, 0xF3, + 0xD6, 0x5F, 0x7B, 0xD3, 0x04, 0x91, 0x5C, 0xFA, 0x88, 0xC6, 0x22, 0xB9, + 0x83, 0x10, 0x62, 0x77, 0x84, 0x33, 0x2D, 0xE9, 0x03, 0x88, 0xD4, 0xE0, + 0x33, 0xF7, 0xED, 0x77, 0x2C, 0x4A, 0x60, 0xEA, 0xE4, 0x6F, 0xAD, 0x6D, + 0xB4, 0xF8, 0x4C, 0x8A, 0xA4, 0xE4, 0x1F, 0xCA, 0xEA, 0x4F, 0x38, 0x4A, + 0x2E, 0x82, 0x73, 0x2B, 0xC7, 0x66, 0x9B, 0x0A, 0x8C, 0x40, 0x9C, 0x7C, + 0x8A, 0xF6, 0xF2, 0x39, 0x60, 0xB2, 0xDE, 0xCB, 0xEC, 0xB8, 0xE4, 0x6F, + 0xEA, 0x9B, 0x5D, 0xB7, 0x53, 0x90, 0x18, 0x32, 0x55, 0xC5, 0x20, 0xB7, + 0x94 +}; + +static const unsigned char TA454_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x29, 0x47, 0x55, 0x41, 0x4E, 0x47, 0x20, 0x44, 0x4F, 0x4E, 0x47, + 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, + 0x20, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x20, 0x43, + 0x4F, 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x47, 0x44, 0x43, 0x41, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x41, 0x55, 0x54, 0x48, 0x20, 0x52, 0x35, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA454_RSA_N[] = { + 0xD9, 0xA3, 0x16, 0xF0, 0xC8, 0x74, 0x74, 0x77, 0x9B, 0xEF, 0x33, 0x0D, + 0x3B, 0x06, 0x7E, 0x55, 0xFC, 0xB5, 0x60, 0x8F, 0x76, 0x86, 0x12, 0x42, + 0x7D, 0x56, 0x66, 0x3E, 0x88, 0x82, 0xED, 0x72, 0x63, 0x0E, 0x9E, 0x8B, + 0xDD, 0x34, 0x2C, 0x02, 0x51, 0x51, 0xC3, 0x19, 0xFD, 0x59, 0x54, 0x84, + 0xC9, 0xF1, 0x6B, 0xB3, 0x4C, 0xB0, 0xE9, 0xE8, 0x46, 0x5D, 0x38, 0xC6, + 0xA2, 0xA7, 0x2E, 0x11, 0x57, 0xBA, 0x82, 0x15, 0xA2, 0x9C, 0x8F, 0x6D, + 0xB0, 0x99, 0x4A, 0x0A, 0xF2, 0xEB, 0x89, 0x70, 0x63, 0x4E, 0x79, 0xC4, + 0xB7, 0x5B, 0xBD, 0xA2, 0x5D, 0xB1, 0xF2, 0x41, 0x02, 0x2B, 0xAD, 0xA9, + 0x3A, 0xA3, 0xEC, 0x79, 0x0A, 0xEC, 0x5F, 0x3A, 0xE3, 0xFD, 0xEF, 0x80, + 0x3C, 0xAD, 0x34, 0x9B, 0x1A, 0xAB, 0x88, 0x26, 0x7B, 0x56, 0xA2, 0x82, + 0x86, 0x1F, 0xEB, 0x35, 0x89, 0x83, 0x7F, 0x5F, 0xAE, 0x29, 0x4E, 0x3D, + 0xB6, 0x6E, 0xEC, 0xAE, 0xC1, 0xF0, 0x27, 0x9B, 0xAE, 0xE3, 0xF4, 0xEC, + 0xEF, 0xAE, 0x7F, 0xF7, 0x86, 0x3D, 0x72, 0x7A, 0xEB, 0xA5, 0xFB, 0x59, + 0x4E, 0xA7, 0xEB, 0x95, 0x8C, 0x22, 0x39, 0x79, 0xE1, 0x2D, 0x08, 0x8F, + 0xCC, 0xBC, 0x91, 0xB8, 0x41, 0xF7, 0x14, 0xC1, 0x23, 0xA9, 0xC3, 0xAD, + 0x9A, 0x45, 0x44, 0xB3, 0xB2, 0xD7, 0x2C, 0xCD, 0xC6, 0x29, 0xE2, 0x50, + 0x10, 0xAE, 0x5C, 0xCB, 0x82, 0x8E, 0x17, 0x18, 0x36, 0x7D, 0x97, 0xE6, + 0x88, 0x9A, 0xB0, 0x4D, 0x34, 0x09, 0xF4, 0x2C, 0xB9, 0x5A, 0x66, 0x2A, + 0xB0, 0x17, 0x9B, 0x9E, 0x1E, 0x76, 0x9D, 0x4A, 0x66, 0x31, 0x41, 0xDF, + 0x3F, 0xFB, 0xC5, 0x06, 0xEF, 0x1B, 0xB6, 0x7E, 0x1A, 0x46, 0x36, 0xF7, + 0x64, 0x63, 0x3B, 0xE3, 0x39, 0x18, 0x23, 0xE7, 0x67, 0x75, 0x14, 0xD5, + 0x75, 0x57, 0x92, 0x37, 0xBD, 0xBE, 0x6A, 0x1B, 0x26, 0x50, 0xF2, 0x36, + 0x26, 0x06, 0x90, 0xC5, 0x70, 0x01, 0x64, 0x6D, 0x76, 0x66, 0xE1, 0x91, + 0xDB, 0x6E, 0x07, 0xC0, 0x61, 0x80, 0x2E, 0xB2, 0x2E, 0x2F, 0x8C, 0x70, + 0xA7, 0xD1, 0x3B, 0x3C, 0xB3, 0x91, 0xE4, 0x6E, 0xB6, 0xC4, 0x3B, 0x70, + 0xF2, 0x6C, 0x92, 0x97, 0x09, 0xCD, 0x47, 0x7D, 0x18, 0xC0, 0xF3, 0xBB, + 0x9E, 0x0F, 0xD6, 0x8B, 0xAE, 0x07, 0xB6, 0x5A, 0x0F, 0xCE, 0x0B, 0x0C, + 0x47, 0xA7, 0xE5, 0x3E, 0xB8, 0xBD, 0x7D, 0xC7, 0x9B, 0x35, 0xA0, 0x61, + 0x97, 0x3A, 0x41, 0x75, 0x17, 0xCC, 0x2B, 0x96, 0x77, 0x2A, 0x92, 0x21, + 0x1E, 0xD9, 0x95, 0x76, 0x20, 0x67, 0x68, 0xCF, 0x0D, 0xBD, 0xDF, 0xD6, + 0x1F, 0x09, 0x6A, 0x9A, 0xE2, 0xCC, 0x73, 0x71, 0xA4, 0x2F, 0x7D, 0x12, + 0x80, 0xB7, 0x53, 0x30, 0x46, 0x5E, 0x4B, 0x54, 0x99, 0x0F, 0x67, 0xC9, + 0xA5, 0xC8, 0xF2, 0x20, 0xC1, 0x82, 0xEC, 0x9D, 0x11, 0xDF, 0xC2, 0x02, + 0xFB, 0x1A, 0x3B, 0xD1, 0xED, 0x20, 0x9A, 0xEF, 0x65, 0x64, 0x92, 0x10, + 0x0D, 0x2A, 0xE2, 0xDE, 0x70, 0xF1, 0x18, 0x67, 0x82, 0x8C, 0x61, 0xDE, + 0xB8, 0xBC, 0xD1, 0x2F, 0x9C, 0xFB, 0x0F, 0xD0, 0x2B, 0xED, 0x1B, 0x76, + 0xB9, 0xE4, 0x39, 0x55, 0xF8, 0xF8, 0xA1, 0x1D, 0xB8, 0xAA, 0x80, 0x00, + 0x4C, 0x82, 0xE7, 0xB2, 0x7F, 0x09, 0xB8, 0xBC, 0x30, 0xA0, 0x2F, 0x0D, + 0xF5, 0x52, 0x9E, 0x8E, 0xF7, 0x92, 0xB3, 0x0A, 0x00, 0x1D, 0x00, 0x54, + 0x97, 0x06, 0xE0, 0xB1, 0x07, 0xD9, 0xC7, 0x0F, 0x5C, 0x65, 0x7D, 0x3C, + 0x6D, 0x59, 0x57, 0xE4, 0xED, 0xA5, 0x8D, 0xE9, 0x40, 0x53, 0x9F, 0x15, + 0x4B, 0xA0, 0x71, 0xF6, 0x1A, 0x21, 0xE3, 0xDA, 0x70, 0x06, 0x21, 0x58, + 0x14, 0x87, 0x85, 0x77, 0x79, 0xAA, 0x82, 0x79 +}; + +static const unsigned char TA454_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA455_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x41, 0x54, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x65, 0x2D, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x65, + 0x20, 0x6D, 0x6F, 0x6E, 0x69, 0x74, 0x6F, 0x72, 0x69, 0x6E, 0x67, 0x20, + 0x47, 0x6D, 0x62, 0x48, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x10, 0x47, 0x4C, 0x4F, 0x42, 0x41, 0x4C, 0x54, 0x52, 0x55, + 0x53, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA455_RSA_N[] = { + 0xAE, 0x2E, 0x56, 0xAD, 0x1B, 0x1C, 0xEF, 0xF6, 0x95, 0x8F, 0xA0, 0x77, + 0x1B, 0x2B, 0xD3, 0x63, 0x8F, 0x84, 0x4D, 0x45, 0xA2, 0x0F, 0x9F, 0x5B, + 0x45, 0xAB, 0x59, 0x7B, 0x51, 0x34, 0xF9, 0xEC, 0x8B, 0x8A, 0x78, 0xC5, + 0xDD, 0x6B, 0xAF, 0xBD, 0xC4, 0xDF, 0x93, 0x45, 0x1E, 0xBF, 0x91, 0x38, + 0x0B, 0xAE, 0x0E, 0x16, 0xE7, 0x41, 0x73, 0xF8, 0xDB, 0xBB, 0xD1, 0xB8, + 0x51, 0xE0, 0xCB, 0x83, 0x3B, 0x73, 0x38, 0x6E, 0x77, 0x8A, 0x0F, 0x59, + 0x63, 0x26, 0xCD, 0xA7, 0x2A, 0xCE, 0x54, 0xFB, 0xB8, 0xE2, 0xC0, 0x7C, + 0x47, 0xCE, 0x60, 0x7C, 0x3F, 0xB2, 0x73, 0xF2, 0xC0, 0x19, 0xB6, 0x8A, + 0x92, 0x87, 0x35, 0x0D, 0x90, 0x28, 0xA2, 0xE4, 0x15, 0x04, 0x63, 0x3E, + 0xBA, 0xAF, 0xEE, 0x7C, 0x5E, 0xCC, 0xA6, 0x8B, 0x50, 0xB2, 0x38, 0xF7, + 0x41, 0x63, 0xCA, 0xCE, 0xFF, 0x69, 0x8F, 0x68, 0x0E, 0x95, 0x36, 0xE5, + 0xCC, 0xB9, 0x8C, 0x09, 0xCA, 0x4B, 0xDD, 0x31, 0x90, 0x96, 0xC8, 0xCC, + 0x1F, 0xFD, 0x56, 0x96, 0x34, 0xDB, 0x8E, 0x1C, 0xEA, 0x2C, 0xBE, 0x85, + 0x2E, 0x63, 0xDD, 0xAA, 0xA9, 0x95, 0xD3, 0xFD, 0x29, 0x95, 0x13, 0xF0, + 0xC8, 0x98, 0x93, 0xD9, 0x2D, 0x16, 0x47, 0x90, 0x11, 0x83, 0xA2, 0x3A, + 0x22, 0xA2, 0x28, 0x57, 0xA2, 0xEB, 0xFE, 0xC0, 0x8C, 0x28, 0xA0, 0xA6, + 0x7D, 0xE7, 0x2A, 0x42, 0x3B, 0x82, 0x80, 0x63, 0xA5, 0x63, 0x1F, 0x19, + 0xCC, 0x7C, 0xB2, 0x66, 0xA8, 0xC2, 0xD3, 0x6D, 0x37, 0x6F, 0xE2, 0x7E, + 0x06, 0x51, 0xD9, 0x45, 0x84, 0x1F, 0x12, 0xCE, 0x24, 0x52, 0x64, 0x85, + 0x0B, 0x48, 0x80, 0x4E, 0x87, 0xB1, 0x22, 0x22, 0x30, 0xAA, 0xEB, 0xAE, + 0xBE, 0xE0, 0x02, 0xE0, 0x40, 0xE8, 0xB0, 0x42, 0x80, 0x03, 0x51, 0xAA, + 0xB4, 0x7E, 0xAA, 0x44, 0xD7, 0x43, 0x61, 0xF3, 0xA2, 0x6B, 0x16, 0x89, + 0x49, 0xA4, 0xA3, 0xA4, 0x2B, 0x8A, 0x02, 0xC4, 0x78, 0xF4, 0x68, 0x8A, + 0xC1, 0xE4, 0x7A, 0x36, 0xB1, 0x6F, 0x1B, 0x96, 0x1B, 0x77, 0x49, 0x8D, + 0xD4, 0xC9, 0x06, 0x72, 0x8F, 0xCF, 0x53, 0xE3, 0xDC, 0x17, 0x85, 0x20, + 0x4A, 0xDC, 0x98, 0x27, 0xD3, 0x91, 0x26, 0x2B, 0x47, 0x1E, 0x69, 0x07, + 0xAF, 0xDE, 0xA2, 0xE4, 0xE4, 0xD4, 0x6B, 0x0B, 0xB3, 0x5E, 0x7C, 0xD4, + 0x24, 0x80, 0x47, 0x29, 0x69, 0x3B, 0x6E, 0xE8, 0xAC, 0xFD, 0x40, 0xEB, + 0xD8, 0xED, 0x71, 0x71, 0x2B, 0xF2, 0xE8, 0x58, 0x1D, 0xEB, 0x41, 0x97, + 0x22, 0xC5, 0x1F, 0xD4, 0x39, 0xD0, 0x27, 0x8F, 0x87, 0xE3, 0x18, 0xF4, + 0xE0, 0xA9, 0x46, 0x0D, 0xF5, 0x74, 0x3A, 0x82, 0x2E, 0xD0, 0x6E, 0x2C, + 0x91, 0xA3, 0x31, 0x5C, 0x3B, 0x46, 0xEA, 0x7B, 0x04, 0x10, 0x56, 0x5E, + 0x80, 0x1D, 0xF5, 0xA5, 0x65, 0xE8, 0x82, 0xFC, 0xE2, 0x07, 0x8C, 0x62, + 0x45, 0xF5, 0x20, 0xDE, 0x46, 0x70, 0x86, 0xA1, 0xBC, 0x93, 0xD3, 0x1E, + 0x74, 0xA6, 0x6C, 0xB0, 0x2C, 0xF7, 0x03, 0x0C, 0x88, 0x0C, 0xCB, 0xD4, + 0x72, 0x53, 0x86, 0xBC, 0x60, 0x46, 0xF3, 0x98, 0x6A, 0xC2, 0xF1, 0xBF, + 0x43, 0xF9, 0x70, 0x20, 0x77, 0xCA, 0x37, 0x41, 0x79, 0x55, 0x52, 0x63, + 0x8D, 0x5B, 0x12, 0x9F, 0xC5, 0x68, 0xC4, 0x88, 0x9D, 0xAC, 0xF2, 0x30, + 0xAB, 0xB7, 0xA3, 0x31, 0x97, 0x67, 0xAD, 0x8F, 0x17, 0x0F, 0x6C, 0xC7, + 0x73, 0xED, 0x24, 0x94, 0x6B, 0xC8, 0x83, 0x9A, 0xD0, 0x9A, 0x37, 0x49, + 0x04, 0xAB, 0xB1, 0x16, 0xC8, 0x6C, 0x49, 0x49, 0x2D, 0xAB, 0xA1, 0xD0, + 0x8C, 0x92, 0xF2, 0x41, 0x4A, 0x79, 0x21, 0x25, 0xDB, 0x63, 0xD7, 0xB6, + 0x9C, 0xA7, 0x7E, 0x42, 0x69, 0xFB, 0x3A, 0x63 +}; + +static const unsigned char TA455_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA456_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x31 +}; + +static const unsigned char TA456_RSA_N[] = { + 0xB6, 0x11, 0x02, 0x8B, 0x1E, 0xE3, 0xA1, 0x77, 0x9B, 0x3B, 0xDC, 0xBF, + 0x94, 0x3E, 0xB7, 0x95, 0xA7, 0x40, 0x3C, 0xA1, 0xFD, 0x82, 0xF9, 0x7D, + 0x32, 0x06, 0x82, 0x71, 0xF6, 0xF6, 0x8C, 0x7F, 0xFB, 0xE8, 0xDB, 0xBC, + 0x6A, 0x2E, 0x97, 0x97, 0xA3, 0x8C, 0x4B, 0xF9, 0x2B, 0xF6, 0xB1, 0xF9, + 0xCE, 0x84, 0x1D, 0xB1, 0xF9, 0xC5, 0x97, 0xDE, 0xEF, 0xB9, 0xF2, 0xA3, + 0xE9, 0xBC, 0x12, 0x89, 0x5E, 0xA7, 0xAA, 0x52, 0xAB, 0xF8, 0x23, 0x27, + 0xCB, 0xA4, 0xB1, 0x9C, 0x63, 0xDB, 0xD7, 0x99, 0x7E, 0xF0, 0x0A, 0x5E, + 0xEB, 0x68, 0xA6, 0xF4, 0xC6, 0x5A, 0x47, 0x0D, 0x4D, 0x10, 0x33, 0xE3, + 0x4E, 0xB1, 0x13, 0xA3, 0xC8, 0x18, 0x6C, 0x4B, 0xEC, 0xFC, 0x09, 0x90, + 0xDF, 0x9D, 0x64, 0x29, 0x25, 0x23, 0x07, 0xA1, 0xB4, 0xD2, 0x3D, 0x2E, + 0x60, 0xE0, 0xCF, 0xD2, 0x09, 0x87, 0xBB, 0xCD, 0x48, 0xF0, 0x4D, 0xC2, + 0xC2, 0x7A, 0x88, 0x8A, 0xBB, 0xBA, 0xCF, 0x59, 0x19, 0xD6, 0xAF, 0x8F, + 0xB0, 0x07, 0xB0, 0x9E, 0x31, 0xF1, 0x82, 0xC1, 0xC0, 0xDF, 0x2E, 0xA6, + 0x6D, 0x6C, 0x19, 0x0E, 0xB5, 0xD8, 0x7E, 0x26, 0x1A, 0x45, 0x03, 0x3D, + 0xB0, 0x79, 0xA4, 0x94, 0x28, 0xAD, 0x0F, 0x7F, 0x26, 0xE5, 0xA8, 0x08, + 0xFE, 0x96, 0xE8, 0x3C, 0x68, 0x94, 0x53, 0xEE, 0x83, 0x3A, 0x88, 0x2B, + 0x15, 0x96, 0x09, 0xB2, 0xE0, 0x7A, 0x8C, 0x2E, 0x75, 0xD6, 0x9C, 0xEB, + 0xA7, 0x56, 0x64, 0x8F, 0x96, 0x4F, 0x68, 0xAE, 0x3D, 0x97, 0xC2, 0x84, + 0x8F, 0xC0, 0xBC, 0x40, 0xC0, 0x0B, 0x5C, 0xBD, 0xF6, 0x87, 0xB3, 0x35, + 0x6C, 0xAC, 0x18, 0x50, 0x7F, 0x84, 0xE0, 0x4C, 0xCD, 0x92, 0xD3, 0x20, + 0xE9, 0x33, 0xBC, 0x52, 0x99, 0xAF, 0x32, 0xB5, 0x29, 0xB3, 0x25, 0x2A, + 0xB4, 0x48, 0xF9, 0x72, 0xE1, 0xCA, 0x64, 0xF7, 0xE6, 0x82, 0x10, 0x8D, + 0xE8, 0x9D, 0xC2, 0x8A, 0x88, 0xFA, 0x38, 0x66, 0x8A, 0xFC, 0x63, 0xF9, + 0x01, 0xF9, 0x78, 0xFD, 0x7B, 0x5C, 0x77, 0xFA, 0x76, 0x87, 0xFA, 0xEC, + 0xDF, 0xB1, 0x0E, 0x79, 0x95, 0x57, 0xB4, 0xBD, 0x26, 0xEF, 0xD6, 0x01, + 0xD1, 0xEB, 0x16, 0x0A, 0xBB, 0x8E, 0x0B, 0xB5, 0xC5, 0xC5, 0x8A, 0x55, + 0xAB, 0xD3, 0xAC, 0xEA, 0x91, 0x4B, 0x29, 0xCC, 0x19, 0xA4, 0x32, 0x25, + 0x4E, 0x2A, 0xF1, 0x65, 0x44, 0xD0, 0x02, 0xCE, 0xAA, 0xCE, 0x49, 0xB4, + 0xEA, 0x9F, 0x7C, 0x83, 0xB0, 0x40, 0x7B, 0xE7, 0x43, 0xAB, 0xA7, 0x6C, + 0xA3, 0x8F, 0x7D, 0x89, 0x81, 0xFA, 0x4C, 0xA5, 0xFF, 0xD5, 0x8E, 0xC3, + 0xCE, 0x4B, 0xE0, 0xB5, 0xD8, 0xB3, 0x8E, 0x45, 0xCF, 0x76, 0xC0, 0xED, + 0x40, 0x2B, 0xFD, 0x53, 0x0F, 0xB0, 0xA7, 0xD5, 0x3B, 0x0D, 0xB1, 0x8A, + 0xA2, 0x03, 0xDE, 0x31, 0xAD, 0xCC, 0x77, 0xEA, 0x6F, 0x7B, 0x3E, 0xD6, + 0xDF, 0x91, 0x22, 0x12, 0xE6, 0xBE, 0xFA, 0xD8, 0x32, 0xFC, 0x10, 0x63, + 0x14, 0x51, 0x72, 0xDE, 0x5D, 0xD6, 0x16, 0x93, 0xBD, 0x29, 0x68, 0x33, + 0xEF, 0x3A, 0x66, 0xEC, 0x07, 0x8A, 0x26, 0xDF, 0x13, 0xD7, 0x57, 0x65, + 0x78, 0x27, 0xDE, 0x5E, 0x49, 0x14, 0x00, 0xA2, 0x00, 0x7F, 0x9A, 0xA8, + 0x21, 0xB6, 0xA9, 0xB1, 0x95, 0xB0, 0xA5, 0xB9, 0x0D, 0x16, 0x11, 0xDA, + 0xC7, 0x6C, 0x48, 0x3C, 0x40, 0xE0, 0x7E, 0x0D, 0x5A, 0xCD, 0x56, 0x3C, + 0xD1, 0x97, 0x05, 0xB9, 0xCB, 0x4B, 0xED, 0x39, 0x4B, 0x9C, 0xC4, 0x3F, + 0xD2, 0x55, 0x13, 0x6E, 0x24, 0xB0, 0xD6, 0x71, 0xFA, 0xF4, 0xC1, 0xBA, + 0xCC, 0xED, 0x1B, 0xF5, 0xFE, 0x81, 0x41, 0xD8, 0x00, 0x98, 0x3D, 0x3A, + 0xC8, 0xAE, 0x7A, 0x98, 0x37, 0x18, 0x05, 0x95 +}; + +static const unsigned char TA456_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA457_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA457_RSA_N[] = { + 0xCE, 0xDE, 0xFD, 0xA6, 0xFB, 0xEC, 0xEC, 0x14, 0x34, 0x3C, 0x07, 0x06, + 0x5A, 0x6C, 0x59, 0xF7, 0x19, 0x35, 0xDD, 0xF7, 0xC1, 0x9D, 0x55, 0xAA, + 0xD3, 0xCD, 0x3B, 0xA4, 0x93, 0x72, 0xEF, 0x0A, 0xFA, 0x6D, 0x9D, 0xF6, + 0xF0, 0x85, 0x80, 0x5B, 0xA1, 0x48, 0x52, 0x9F, 0x39, 0xC5, 0xB7, 0xEE, + 0x28, 0xAC, 0xEF, 0xCB, 0x76, 0x68, 0x14, 0xB9, 0xDF, 0xAD, 0x01, 0x6C, + 0x99, 0x1F, 0xC4, 0x22, 0x1D, 0x9F, 0xFE, 0x72, 0x77, 0xE0, 0x2C, 0x5B, + 0xAF, 0xE4, 0x04, 0xBF, 0x4F, 0x72, 0xA0, 0x1A, 0x34, 0x98, 0xE8, 0x39, + 0x68, 0xEC, 0x95, 0x25, 0x7B, 0x76, 0xA1, 0xE6, 0x69, 0xB9, 0x85, 0x19, + 0xBD, 0x89, 0x8C, 0xFE, 0xAD, 0xED, 0x36, 0xEA, 0x73, 0xBC, 0xFF, 0x83, + 0xE2, 0xCB, 0x7D, 0xC1, 0xD2, 0xCE, 0x4A, 0xB3, 0x8D, 0x05, 0x9E, 0x8B, + 0x49, 0x93, 0xDF, 0xC1, 0x5B, 0xD0, 0x6E, 0x5E, 0xF0, 0x2E, 0x30, 0x2E, + 0x82, 0xFC, 0xFA, 0xBC, 0xB4, 0x17, 0x0A, 0x48, 0xE5, 0x88, 0x9B, 0xC5, + 0x9B, 0x6B, 0xDE, 0xB0, 0xCA, 0xB4, 0x03, 0xF0, 0xDA, 0xF4, 0x90, 0xB8, + 0x65, 0x64, 0xF7, 0x5C, 0x4C, 0xAD, 0xE8, 0x7E, 0x66, 0x5E, 0x99, 0xD7, + 0xB8, 0xC2, 0x3E, 0xC8, 0xD0, 0x13, 0x9D, 0xAD, 0xEE, 0xE4, 0x45, 0x7B, + 0x89, 0x55, 0xF7, 0x8A, 0x1F, 0x62, 0x52, 0x84, 0x12, 0xB3, 0xC2, 0x40, + 0x97, 0xE3, 0x8A, 0x1F, 0x47, 0x91, 0xA6, 0x74, 0x5A, 0xD2, 0xF8, 0xB1, + 0x63, 0x28, 0x10, 0xB8, 0xB3, 0x09, 0xB8, 0x56, 0x77, 0x40, 0xA2, 0x26, + 0x98, 0x79, 0xC6, 0xFE, 0xDF, 0x25, 0xEE, 0x3E, 0xE5, 0xA0, 0x7F, 0xD4, + 0x61, 0x0F, 0x51, 0x4B, 0x3C, 0x3F, 0x8C, 0xDA, 0xE1, 0x70, 0x74, 0xD8, + 0xC2, 0x68, 0xA1, 0xF9, 0xC1, 0x0C, 0xE9, 0xA1, 0xE2, 0x7F, 0xBB, 0x55, + 0x3C, 0x76, 0x06, 0xEE, 0x6A, 0x4E, 0xCC, 0x92, 0x88, 0x30, 0x4D, 0x9A, + 0xBD, 0x4F, 0x0B, 0x48, 0x9A, 0x84, 0xB5, 0x98, 0xA3, 0xD5, 0xFB, 0x73, + 0xC1, 0x57, 0x61, 0xDD, 0x28, 0x56, 0x75, 0x13, 0xAE, 0x87, 0x8E, 0xE7, + 0x0C, 0x51, 0x09, 0x10, 0x75, 0x88, 0x4C, 0xBC, 0x8D, 0xF9, 0x7B, 0x3C, + 0xD4, 0x22, 0x48, 0x1F, 0x2A, 0xDC, 0xEB, 0x6B, 0xBB, 0x44, 0xB1, 0xCB, + 0x33, 0x71, 0x32, 0x46, 0xAF, 0xAD, 0x4A, 0xF1, 0x8C, 0xE8, 0x74, 0x3A, + 0xAC, 0xE7, 0x1A, 0x22, 0x73, 0x80, 0xD2, 0x30, 0xF7, 0x25, 0x42, 0xC7, + 0x22, 0x3B, 0x3B, 0x12, 0xAD, 0x96, 0x2E, 0xC6, 0xC3, 0x76, 0x07, 0xAA, + 0x20, 0xB7, 0x35, 0x49, 0x57, 0xE9, 0x92, 0x49, 0xE8, 0x76, 0x16, 0x72, + 0x31, 0x67, 0x2B, 0x96, 0x7E, 0x8A, 0xA3, 0xC7, 0x94, 0x56, 0x22, 0xBF, + 0x6A, 0x4B, 0x7E, 0x01, 0x21, 0xB2, 0x23, 0x32, 0xDF, 0xE4, 0x9A, 0x44, + 0x6D, 0x59, 0x5B, 0x5D, 0xF5, 0x00, 0xA0, 0x1C, 0x9B, 0xC6, 0x78, 0x97, + 0x8D, 0x90, 0xFF, 0x9B, 0xC8, 0xAA, 0xB4, 0xAF, 0x11, 0x51, 0x39, 0x5E, + 0xD9, 0xFB, 0x67, 0xAD, 0xD5, 0x5B, 0x11, 0x9D, 0x32, 0x9A, 0x1B, 0xBD, + 0xD5, 0xBA, 0x5B, 0xA5, 0xC9, 0xCB, 0x25, 0x69, 0x53, 0x55, 0x27, 0x5C, + 0xE0, 0xCA, 0x36, 0xCB, 0x88, 0x61, 0xFB, 0x1E, 0xB7, 0xD0, 0xCB, 0xEE, + 0x16, 0xFB, 0xD3, 0xA6, 0x4C, 0xDE, 0x92, 0xA5, 0xD4, 0xE2, 0xDF, 0xF5, + 0x06, 0x54, 0xDE, 0x2E, 0x9D, 0x4B, 0xB4, 0x93, 0x30, 0xAA, 0x81, 0xCE, + 0xDD, 0x1A, 0xDC, 0x51, 0x73, 0x0D, 0x4F, 0x70, 0xE9, 0xE5, 0xB6, 0x16, + 0x21, 0x19, 0x79, 0xB2, 0xE6, 0x89, 0x0B, 0x75, 0x64, 0xCA, 0xD5, 0xAB, + 0xBC, 0x09, 0xC1, 0x18, 0xA1, 0xFF, 0xD4, 0x54, 0xA1, 0x85, 0x3C, 0xFD, + 0x14, 0x24, 0x03, 0xB2, 0x87, 0xD3, 0xA4, 0xB7 +}; + +static const unsigned char TA457_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA458_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x33 +}; + +static const unsigned char TA458_EC_Q[] = { + 0x04, 0x1F, 0x4F, 0x33, 0x87, 0x33, 0x29, 0x8A, 0xA1, 0x84, 0xDE, 0xCB, + 0xC7, 0x21, 0x58, 0x41, 0x89, 0xEA, 0x56, 0x9D, 0x2B, 0x4B, 0x85, 0xC6, + 0x1D, 0x4C, 0x27, 0xBC, 0x7F, 0x26, 0x51, 0x72, 0x6F, 0xE2, 0x9F, 0xD6, + 0xA3, 0xCA, 0xCC, 0x45, 0x14, 0x46, 0x8B, 0xAD, 0xEF, 0x7E, 0x86, 0x8C, + 0xEC, 0xB1, 0x7E, 0x2F, 0xFF, 0xA9, 0x71, 0x9D, 0x18, 0x84, 0x45, 0x04, + 0x41, 0x55, 0x6E, 0x2B, 0xEA, 0x26, 0x7F, 0xBB, 0x90, 0x01, 0xE3, 0x4B, + 0x19, 0xBA, 0xE4, 0x54, 0x96, 0x45, 0x09, 0xB1, 0xD5, 0x6C, 0x91, 0x44, + 0xAD, 0x84, 0x13, 0x8E, 0x9A, 0x8C, 0x0D, 0x80, 0x0C, 0x32, 0xF6, 0xE0, + 0x27 +}; + +static const unsigned char TA459_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x34 +}; + +static const unsigned char TA459_EC_Q[] = { + 0x04, 0xF3, 0x74, 0x73, 0xA7, 0x68, 0x8B, 0x60, 0xAE, 0x43, 0xB8, 0x35, + 0xC5, 0x81, 0x30, 0x7B, 0x4B, 0x49, 0x9D, 0xFB, 0xC1, 0x61, 0xCE, 0xE6, + 0xDE, 0x46, 0xBD, 0x6B, 0xD5, 0x61, 0x18, 0x35, 0xAE, 0x40, 0xDD, 0x73, + 0xF7, 0x89, 0x91, 0x30, 0x5A, 0xEB, 0x3C, 0xEE, 0x85, 0x7C, 0xA2, 0x40, + 0x76, 0x3B, 0xA9, 0xC6, 0xB8, 0x47, 0xD8, 0x2A, 0xE7, 0x92, 0x91, 0x6A, + 0x73, 0xE9, 0xB1, 0x72, 0x39, 0x9F, 0x29, 0x9F, 0xA2, 0x98, 0xD3, 0x5F, + 0x5E, 0x58, 0x86, 0x65, 0x0F, 0xA1, 0x84, 0x65, 0x06, 0xD1, 0xDC, 0x8B, + 0xC9, 0xC7, 0x73, 0xC8, 0x8C, 0x6A, 0x2F, 0xE5, 0xC4, 0xAB, 0xD1, 0x1D, + 0x8A +}; + +static const unsigned char TA460_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x34, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA460_EC_Q[] = { + 0x04, 0xB8, 0xC6, 0x79, 0xD3, 0x8F, 0x6C, 0x25, 0x0E, 0x9F, 0x2E, 0x39, + 0x19, 0x1C, 0x03, 0xA4, 0xAE, 0x9A, 0xE5, 0x39, 0x07, 0x09, 0x16, 0xCA, + 0x63, 0xB1, 0xB9, 0x86, 0xF8, 0x8A, 0x57, 0xC1, 0x57, 0xCE, 0x42, 0xFA, + 0x73, 0xA1, 0xF7, 0x65, 0x42, 0xFF, 0x1E, 0xC1, 0x00, 0xB2, 0x6E, 0x73, + 0x0E, 0xFF, 0xC7, 0x21, 0xE5, 0x18, 0xA4, 0xAA, 0xD9, 0x71, 0x3F, 0xA8, + 0xD4, 0xB9, 0xCE, 0x8C, 0x1D +}; + +static const unsigned char TA461_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x35, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA461_EC_Q[] = { + 0x04, 0x47, 0x45, 0x0E, 0x96, 0xFB, 0x7D, 0x5D, 0xBF, 0xE9, 0x39, 0xD1, + 0x21, 0xF8, 0x9F, 0x0B, 0xB6, 0xD5, 0x7B, 0x1E, 0x92, 0x3A, 0x48, 0x59, + 0x1C, 0xF0, 0x62, 0x31, 0x2D, 0xC0, 0x7A, 0x28, 0xFE, 0x1A, 0xA7, 0x5C, + 0xB3, 0xB6, 0xCC, 0x97, 0xE7, 0x45, 0xD4, 0x58, 0xFA, 0xD1, 0x77, 0x6D, + 0x43, 0xA2, 0xC0, 0x87, 0x65, 0x34, 0x0A, 0x1F, 0x7A, 0xDD, 0xEB, 0x3C, + 0x33, 0xA1, 0xC5, 0x9D, 0x4D, 0xA4, 0x6F, 0x41, 0x95, 0x38, 0x7F, 0xC9, + 0x1E, 0x84, 0xEB, 0xD1, 0x9E, 0x49, 0x92, 0x87, 0x94, 0x87, 0x0C, 0x3A, + 0x85, 0x4A, 0x66, 0x9F, 0x9D, 0x59, 0x93, 0x4D, 0x97, 0x61, 0x06, 0x86, + 0x4A +}; + +static const unsigned char TA462_DN[] = { + 0x30, 0x57, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, + 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA462_RSA_N[] = { + 0xDA, 0x0E, 0xE6, 0x99, 0x8D, 0xCE, 0xA3, 0xE3, 0x4F, 0x8A, 0x7E, 0xFB, + 0xF1, 0x8B, 0x83, 0x25, 0x6B, 0xEA, 0x48, 0x1F, 0xF1, 0x2A, 0xB0, 0xB9, + 0x95, 0x11, 0x04, 0xBD, 0xF0, 0x63, 0xD1, 0xE2, 0x67, 0x66, 0xCF, 0x1C, + 0xDD, 0xCF, 0x1B, 0x48, 0x2B, 0xEE, 0x8D, 0x89, 0x8E, 0x9A, 0xAF, 0x29, + 0x80, 0x65, 0xAB, 0xE9, 0xC7, 0x2D, 0x12, 0xCB, 0xAB, 0x1C, 0x4C, 0x70, + 0x07, 0xA1, 0x3D, 0x0A, 0x30, 0xCD, 0x15, 0x8D, 0x4F, 0xF8, 0xDD, 0xD4, + 0x8C, 0x50, 0x15, 0x1C, 0xEF, 0x50, 0xEE, 0xC4, 0x2E, 0xF7, 0xFC, 0xE9, + 0x52, 0xF2, 0x91, 0x7D, 0xE0, 0x6D, 0xD5, 0x35, 0x30, 0x8E, 0x5E, 0x43, + 0x73, 0xF2, 0x41, 0xE9, 0xD5, 0x6A, 0xE3, 0xB2, 0x89, 0x3A, 0x56, 0x39, + 0x38, 0x6F, 0x06, 0x3C, 0x88, 0x69, 0x5B, 0x2A, 0x4D, 0xC5, 0xA7, 0x54, + 0xB8, 0x6C, 0x89, 0xCC, 0x9B, 0xF9, 0x3C, 0xCA, 0xE5, 0xFD, 0x89, 0xF5, + 0x12, 0x3C, 0x92, 0x78, 0x96, 0xD6, 0xDC, 0x74, 0x6E, 0x93, 0x44, 0x61, + 0xD1, 0x8D, 0xC7, 0x46, 0xB2, 0x75, 0x0E, 0x86, 0xE8, 0x19, 0x8A, 0xD5, + 0x6D, 0x6C, 0xD5, 0x78, 0x16, 0x95, 0xA2, 0xE9, 0xC8, 0x0A, 0x38, 0xEB, + 0xF2, 0x24, 0x13, 0x4F, 0x73, 0x54, 0x93, 0x13, 0x85, 0x3A, 0x1B, 0xBC, + 0x1E, 0x34, 0xB5, 0x8B, 0x05, 0x8C, 0xB9, 0x77, 0x8B, 0xB1, 0xDB, 0x1F, + 0x20, 0x91, 0xAB, 0x09, 0x53, 0x6E, 0x90, 0xCE, 0x7B, 0x37, 0x74, 0xB9, + 0x70, 0x47, 0x91, 0x22, 0x51, 0x63, 0x16, 0x79, 0xAE, 0xB1, 0xAE, 0x41, + 0x26, 0x08, 0xC8, 0x19, 0x2B, 0xD1, 0x46, 0xAA, 0x48, 0xD6, 0x64, 0x2A, + 0xD7, 0x83, 0x34, 0xFF, 0x2C, 0x2A, 0xC1, 0x6C, 0x19, 0x43, 0x4A, 0x07, + 0x85, 0xE7, 0xD3, 0x7C, 0xF6, 0x21, 0x68, 0xEF, 0xEA, 0xF2, 0x52, 0x9F, + 0x7F, 0x93, 0x90, 0xCF +}; + +static const unsigned char TA462_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA463_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x33, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA463_RSA_N[] = { + 0xCC, 0x25, 0x76, 0x90, 0x79, 0x06, 0x78, 0x22, 0x16, 0xF5, 0xC0, 0x83, + 0xB6, 0x84, 0xCA, 0x28, 0x9E, 0xFD, 0x05, 0x76, 0x11, 0xC5, 0xAD, 0x88, + 0x72, 0xFC, 0x46, 0x02, 0x43, 0xC7, 0xB2, 0x8A, 0x9D, 0x04, 0x5F, 0x24, + 0xCB, 0x2E, 0x4B, 0xE1, 0x60, 0x82, 0x46, 0xE1, 0x52, 0xAB, 0x0C, 0x81, + 0x47, 0x70, 0x6C, 0xDD, 0x64, 0xD1, 0xEB, 0xF5, 0x2C, 0xA3, 0x0F, 0x82, + 0x3D, 0x0C, 0x2B, 0xAE, 0x97, 0xD7, 0xB6, 0x14, 0x86, 0x10, 0x79, 0xBB, + 0x3B, 0x13, 0x80, 0x77, 0x8C, 0x08, 0xE1, 0x49, 0xD2, 0x6A, 0x62, 0x2F, + 0x1F, 0x5E, 0xFA, 0x96, 0x68, 0xDF, 0x89, 0x27, 0x95, 0x38, 0x9F, 0x06, + 0xD7, 0x3E, 0xC9, 0xCB, 0x26, 0x59, 0x0D, 0x73, 0xDE, 0xB0, 0xC8, 0xE9, + 0x26, 0x0E, 0x83, 0x15, 0xC6, 0xEF, 0x5B, 0x8B, 0xD2, 0x04, 0x60, 0xCA, + 0x49, 0xA6, 0x28, 0xF6, 0x69, 0x3B, 0xF6, 0xCB, 0xC8, 0x28, 0x91, 0xE5, + 0x9D, 0x8A, 0x61, 0x57, 0x37, 0xAC, 0x74, 0x14, 0xDC, 0x74, 0xE0, 0x3A, + 0xEE, 0x72, 0x2F, 0x2E, 0x9C, 0xFB, 0xD0, 0xBB, 0xBF, 0xF5, 0x3D, 0x00, + 0xE1, 0x06, 0x33, 0xE8, 0x82, 0x2B, 0xAE, 0x53, 0xA6, 0x3A, 0x16, 0x73, + 0x8C, 0xDD, 0x41, 0x0E, 0x20, 0x3A, 0xC0, 0xB4, 0xA7, 0xA1, 0xE9, 0xB2, + 0x4F, 0x90, 0x2E, 0x32, 0x60, 0xE9, 0x57, 0xCB, 0xB9, 0x04, 0x92, 0x68, + 0x68, 0xE5, 0x38, 0x26, 0x60, 0x75, 0xB2, 0x9F, 0x77, 0xFF, 0x91, 0x14, + 0xEF, 0xAE, 0x20, 0x49, 0xFC, 0xAD, 0x40, 0x15, 0x48, 0xD1, 0x02, 0x31, + 0x61, 0x19, 0x5E, 0xB8, 0x97, 0xEF, 0xAD, 0x77, 0xB7, 0x64, 0x9A, 0x7A, + 0xBF, 0x5F, 0xC1, 0x13, 0xEF, 0x9B, 0x62, 0xFB, 0x0D, 0x6C, 0xE0, 0x54, + 0x69, 0x16, 0xA9, 0x03, 0xDA, 0x6E, 0xE9, 0x83, 0x93, 0x71, 0x76, 0xC6, + 0x69, 0x85, 0x82, 0x17 +}; + +static const unsigned char TA463_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA464_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x36, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA464_RSA_N[] = { + 0x95, 0x07, 0xE8, 0x73, 0xCA, 0x66, 0xF9, 0xEC, 0x14, 0xCA, 0x7B, 0x3C, + 0xF7, 0x0D, 0x08, 0xF1, 0xB4, 0x45, 0x0B, 0x2C, 0x82, 0xB4, 0x48, 0xC6, + 0xEB, 0x5B, 0x3C, 0xAE, 0x83, 0xB8, 0x41, 0x92, 0x33, 0x14, 0xA4, 0x6F, + 0x7F, 0xE9, 0x2A, 0xCC, 0xC6, 0xB0, 0x88, 0x6B, 0xC5, 0xB6, 0x89, 0xD1, + 0xC6, 0xB2, 0xFF, 0x14, 0xCE, 0x51, 0x14, 0x21, 0xEC, 0x4A, 0xDD, 0x1B, + 0x5A, 0xC6, 0xD6, 0x87, 0xEE, 0x4D, 0x3A, 0x15, 0x06, 0xED, 0x64, 0x66, + 0x0B, 0x92, 0x80, 0xCA, 0x44, 0xDE, 0x73, 0x94, 0x4E, 0xF3, 0xA7, 0x89, + 0x7F, 0x4F, 0x78, 0x63, 0x08, 0xC8, 0x12, 0x50, 0x6D, 0x42, 0x66, 0x2F, + 0x4D, 0xB9, 0x79, 0x28, 0x4D, 0x52, 0x1A, 0x8A, 0x1A, 0x80, 0xB7, 0x19, + 0x81, 0x0E, 0x7E, 0xC4, 0x8A, 0xBC, 0x64, 0x4C, 0x21, 0x1C, 0x43, 0x68, + 0xD7, 0x3D, 0x3C, 0x8A, 0xC5, 0xB2, 0x66, 0xD5, 0x90, 0x9A, 0xB7, 0x31, + 0x06, 0xC5, 0xBE, 0xE2, 0x6D, 0x32, 0x06, 0xA6, 0x1E, 0xF9, 0xB9, 0xEB, + 0xAA, 0xA3, 0xB8, 0xBF, 0xBE, 0x82, 0x63, 0x50, 0xD0, 0xF0, 0x18, 0x89, + 0xDF, 0xE4, 0x0F, 0x79, 0xF5, 0xEA, 0xA2, 0x1F, 0x2A, 0xD2, 0x70, 0x2E, + 0x7B, 0xE7, 0xBC, 0x93, 0xBB, 0x6D, 0x53, 0xE2, 0x48, 0x7C, 0x8C, 0x10, + 0x07, 0x38, 0xFF, 0x66, 0xB2, 0x77, 0x61, 0x7E, 0xE0, 0xEA, 0x8C, 0x3C, + 0xAA, 0xB4, 0xA4, 0xF6, 0xF3, 0x95, 0x4A, 0x12, 0x07, 0x6D, 0xFD, 0x8C, + 0xB2, 0x89, 0xCF, 0xD0, 0xA0, 0x61, 0x77, 0xC8, 0x58, 0x74, 0xB0, 0xD4, + 0x23, 0x3A, 0xF7, 0x5D, 0x3A, 0xCA, 0xA2, 0xDB, 0x9D, 0x09, 0xDE, 0x5D, + 0x44, 0x2D, 0x90, 0xF1, 0x81, 0xCD, 0x57, 0x92, 0xFA, 0x7E, 0xBC, 0x50, + 0x04, 0x63, 0x34, 0xDF, 0x6B, 0x93, 0x18, 0xBE, 0x6B, 0x36, 0xB2, 0x39, + 0xE4, 0xAC, 0x24, 0x36, 0xB7, 0xF0, 0xEF, 0xB6, 0x1C, 0x13, 0x57, 0x93, + 0xB6, 0xDE, 0xB2, 0xF8, 0xE2, 0x85, 0xB7, 0x73, 0xA2, 0xB8, 0x35, 0xAA, + 0x45, 0xF2, 0xE0, 0x9D, 0x36, 0xA1, 0x6F, 0x54, 0x8A, 0xF1, 0x72, 0x56, + 0x6E, 0x2E, 0x88, 0xC5, 0x51, 0x42, 0x44, 0x15, 0x94, 0xEE, 0xA3, 0xC5, + 0x38, 0x96, 0x9B, 0x4E, 0x4E, 0x5A, 0x0B, 0x47, 0xF3, 0x06, 0x36, 0x49, + 0x77, 0x30, 0xBC, 0x71, 0x37, 0xE5, 0xA6, 0xEC, 0x21, 0x08, 0x75, 0xFC, + 0xE6, 0x61, 0x16, 0x3F, 0x77, 0xD5, 0xD9, 0x91, 0x97, 0x84, 0x0A, 0x6C, + 0xD4, 0x02, 0x4D, 0x74, 0xC0, 0x14, 0xED, 0xFD, 0x39, 0xFB, 0x83, 0xF2, + 0x5E, 0x14, 0xA1, 0x04, 0xB0, 0x0B, 0xE9, 0xFE, 0xEE, 0x8F, 0xE1, 0x6E, + 0x0B, 0xB2, 0x08, 0xB3, 0x61, 0x66, 0x09, 0x6A, 0xB1, 0x06, 0x3A, 0x65, + 0x96, 0x59, 0xC0, 0xF0, 0x35, 0xFD, 0xC9, 0xDA, 0x28, 0x8D, 0x1A, 0x11, + 0x87, 0x70, 0x81, 0x0A, 0xA8, 0x9A, 0x75, 0x1D, 0x9E, 0x3A, 0x86, 0x05, + 0x00, 0x9E, 0xDB, 0x80, 0xD6, 0x25, 0xF9, 0xDC, 0x05, 0x9E, 0x27, 0x59, + 0x4C, 0x76, 0x39, 0x5B, 0xEA, 0xF9, 0xA5, 0xA1, 0xD8, 0x83, 0x0F, 0xD1, + 0xFF, 0xDF, 0x30, 0x11, 0xF9, 0x85, 0xCF, 0x33, 0x48, 0xF5, 0xCA, 0x6D, + 0x64, 0x14, 0x2C, 0x7A, 0x58, 0x4F, 0xD3, 0x4B, 0x08, 0x49, 0xC5, 0x95, + 0x64, 0x1A, 0x63, 0x0E, 0x79, 0x3D, 0xF5, 0xB3, 0x8C, 0xCA, 0x58, 0xAD, + 0x9C, 0x42, 0x45, 0x79, 0x6E, 0x0E, 0x87, 0x19, 0x5C, 0x54, 0xB1, 0x65, + 0xB6, 0xBF, 0x8C, 0x9B, 0xDC, 0x13, 0xE9, 0x0D, 0x6F, 0xB8, 0x2E, 0xDC, + 0x67, 0x6E, 0xC9, 0x8B, 0x11, 0xB5, 0x84, 0x14, 0x8A, 0x00, 0x19, 0x70, + 0x83, 0x79, 0x91, 0x97, 0x91, 0xD4, 0x1A, 0x27, 0xBF, 0x37, 0x1E, 0x32, + 0x07, 0xD8, 0x14, 0x63, 0x3C, 0x28, 0x4C, 0xAF +}; + +static const unsigned char TA464_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA465_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, 0x36 +}; + +static const unsigned char TA465_EC_Q[] = { + 0x04, 0x9C, 0x0E, 0xB1, 0xCF, 0xB7, 0xE8, 0x9E, 0x52, 0x77, 0x75, 0x34, + 0xFA, 0xA5, 0x46, 0xA7, 0xAD, 0x32, 0x19, 0x32, 0xB4, 0x07, 0xA9, 0x27, + 0xCA, 0x94, 0xBB, 0x0C, 0xD2, 0x0A, 0x10, 0xC7, 0xDA, 0x89, 0xB0, 0x97, + 0x0C, 0x70, 0x13, 0x09, 0x01, 0x8E, 0xD8, 0xEA, 0x47, 0xEA, 0xBE, 0xB2, + 0x80, 0x2B, 0xCD, 0xFC, 0x28, 0x0D, 0xDB, 0xAC, 0xBC, 0xA4, 0x86, 0x37, + 0xED, 0x70, 0x08, 0x00, 0x75, 0xEA, 0x93, 0x0B, 0x7B, 0x2E, 0x52, 0x9C, + 0x23, 0x68, 0x23, 0x06, 0x43, 0xEC, 0x92, 0x2F, 0x53, 0x84, 0xDB, 0xFB, + 0x47, 0x14, 0x07, 0xE8, 0x5F, 0x94, 0x67, 0x5D, 0xC9, 0x7A, 0x81, 0x3C, + 0x20 +}; + +static const unsigned char TA466_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x36 +}; + +static const unsigned char TA466_RSA_N[] = { + 0xAC, 0xAC, 0x74, 0x32, 0xE8, 0xB3, 0x65, 0xE5, 0xBA, 0xED, 0x43, 0x26, + 0x1D, 0xA6, 0x89, 0x0D, 0x45, 0xBA, 0x29, 0x88, 0xB2, 0xA4, 0x1D, 0x63, + 0xDD, 0xD3, 0xC1, 0x2C, 0x09, 0x57, 0x89, 0x39, 0xA1, 0x55, 0xE9, 0x67, + 0x34, 0x77, 0x0C, 0x6E, 0xE4, 0x55, 0x1D, 0x52, 0x25, 0xD2, 0x13, 0x6B, + 0x5E, 0xE1, 0x1D, 0xA9, 0xB7, 0x7D, 0x89, 0x32, 0x5F, 0x0D, 0x9E, 0x9F, + 0x2C, 0x7A, 0x63, 0x60, 0x40, 0x1F, 0xA6, 0xB0, 0xB6, 0x78, 0x8F, 0x99, + 0x54, 0x96, 0x08, 0x58, 0xAE, 0xE4, 0x06, 0xBC, 0x62, 0x05, 0x02, 0x16, + 0xBF, 0xAF, 0xA8, 0x23, 0x03, 0xB6, 0x94, 0x0F, 0xBC, 0x6E, 0x6C, 0xC2, + 0xCB, 0xD5, 0xA6, 0xBB, 0x0C, 0xE9, 0xF6, 0xC1, 0x02, 0xFB, 0x21, 0xDE, + 0x66, 0xDD, 0x17, 0xAB, 0x74, 0x42, 0xEF, 0xF0, 0x74, 0x2F, 0x25, 0xF4, + 0xEA, 0x6B, 0x55, 0x5B, 0x90, 0xDB, 0x9D, 0xDF, 0x5E, 0x87, 0x0A, 0x40, + 0xFB, 0xAD, 0x19, 0x6B, 0xFB, 0xF7, 0xCA, 0x60, 0x88, 0xDE, 0xDA, 0xC1, + 0x8F, 0xD6, 0xAE, 0xD5, 0x7F, 0xD4, 0x3C, 0x83, 0xEE, 0xD7, 0x16, 0x4C, + 0x83, 0x45, 0x33, 0x6B, 0x27, 0xD0, 0x86, 0xD0, 0x1C, 0x2D, 0x6B, 0xF3, + 0xAB, 0x7D, 0xF1, 0x85, 0xA9, 0xF5, 0x28, 0xD2, 0xAD, 0xEF, 0xF3, 0x84, + 0x4B, 0x1C, 0x87, 0xFC, 0x13, 0xA3, 0x3A, 0x72, 0xA2, 0x5A, 0x11, 0x2B, + 0xD6, 0x27, 0x71, 0x27, 0xED, 0x81, 0x2D, 0x6D, 0x66, 0x81, 0x92, 0x87, + 0xB4, 0x1B, 0x58, 0x7A, 0xCC, 0x3F, 0x0A, 0xFA, 0x46, 0x4F, 0x4D, 0x78, + 0x5C, 0xF8, 0x2B, 0x48, 0xE3, 0x04, 0x84, 0xCB, 0x5D, 0xF6, 0xB4, 0x6A, + 0xB3, 0x65, 0xFC, 0x42, 0x9E, 0x51, 0x26, 0x23, 0x20, 0xCB, 0x3D, 0x14, + 0xF9, 0x81, 0xED, 0x65, 0x16, 0x00, 0x4F, 0x1A, 0x64, 0x97, 0x66, 0x08, + 0xCF, 0x8C, 0x7B, 0xE3, 0x2B, 0xC0, 0x9D, 0xF9, 0x14, 0xF2, 0x1B, 0xF1, + 0x56, 0x6A, 0x16, 0xBF, 0x2C, 0x85, 0x85, 0xCD, 0x78, 0x38, 0x9A, 0xEB, + 0x42, 0x6A, 0x02, 0x34, 0x18, 0x83, 0x17, 0x4E, 0x94, 0x56, 0xF8, 0xB6, + 0x82, 0xB5, 0xF3, 0x96, 0xDD, 0x3D, 0xF3, 0xBE, 0x7F, 0x20, 0x77, 0x3E, + 0x7B, 0x19, 0x23, 0x6B, 0x2C, 0xD4, 0x72, 0x73, 0x43, 0x57, 0x7D, 0xE0, + 0xF8, 0xD7, 0x69, 0x4F, 0x17, 0x36, 0x04, 0xF9, 0xC0, 0x90, 0x60, 0x37, + 0x45, 0xDE, 0xE6, 0x0C, 0xD8, 0x74, 0x8D, 0xAE, 0x9C, 0xA2, 0x6D, 0x74, + 0x5D, 0x42, 0xBE, 0x06, 0xF5, 0xD9, 0x64, 0x6E, 0x02, 0x10, 0xAC, 0x89, + 0xB0, 0x4C, 0x3B, 0x07, 0x4D, 0x40, 0x7E, 0x24, 0xC5, 0x8A, 0x98, 0x82, + 0x79, 0x8E, 0xA4, 0xA7, 0x82, 0x20, 0x8D, 0x23, 0xFA, 0x27, 0x71, 0xC9, + 0xDF, 0xC6, 0x41, 0x74, 0xA0, 0x4D, 0xF6, 0x91, 0x16, 0xDC, 0x46, 0x8C, + 0x5F, 0x29, 0x63, 0x31, 0x59, 0x71, 0x0C, 0xD8, 0x6F, 0xC2, 0xB6, 0x32, + 0x7D, 0xFB, 0xE6, 0x5D, 0x53, 0xA6, 0x7E, 0x15, 0xFC, 0xBB, 0x75, 0x7C, + 0x5D, 0xEC, 0xF8, 0xF6, 0x17, 0x1C, 0xEC, 0xC7, 0x6B, 0x19, 0xCB, 0xF3, + 0x7B, 0xF0, 0x2B, 0x07, 0xA5, 0xD9, 0x6C, 0x79, 0x54, 0x76, 0x6C, 0x9D, + 0x1C, 0xA6, 0x6E, 0x0E, 0xE9, 0x79, 0x0C, 0xA8, 0x23, 0x6A, 0xA3, 0xDF, + 0x1B, 0x30, 0x31, 0x9F, 0xB1, 0x54, 0x7B, 0xFE, 0x6A, 0xCB, 0x66, 0xAA, + 0xDC, 0x65, 0xD0, 0xA2, 0x9E, 0x4A, 0x9A, 0x07, 0x21, 0x6B, 0x81, 0x8F, + 0xDB, 0xC4, 0x59, 0xFA, 0xDE, 0x22, 0xC0, 0x04, 0x9C, 0xE3, 0xAA, 0x5B, + 0x36, 0x93, 0xE8, 0x3D, 0xBD, 0x7A, 0xA1, 0x9D, 0x0B, 0x76, 0xB1, 0x0B, + 0xC7, 0x9D, 0xFD, 0xCF, 0x98, 0xA8, 0x06, 0xC2, 0xF8, 0x2A, 0xA3, 0xA1, + 0x83, 0xA0, 0xB7, 0x25, 0x72, 0xA5, 0x02, 0xE3 +}; + +static const unsigned char TA466_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA467_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, + 0x64, 0x79, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x49, 0x6E, + 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x28, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6C, + 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA467_RSA_N[] = { + 0xDE, 0x9D, 0xD7, 0xEA, 0x57, 0x18, 0x49, 0xA1, 0x5B, 0xEB, 0xD7, 0x5F, + 0x48, 0x86, 0xEA, 0xBE, 0xDD, 0xFF, 0xE4, 0xEF, 0x67, 0x1C, 0xF4, 0x65, + 0x68, 0xB3, 0x57, 0x71, 0xA0, 0x5E, 0x77, 0xBB, 0xED, 0x9B, 0x49, 0xE9, + 0x70, 0x80, 0x3D, 0x56, 0x18, 0x63, 0x08, 0x6F, 0xDA, 0xF2, 0xCC, 0xD0, + 0x3F, 0x7F, 0x02, 0x54, 0x22, 0x54, 0x10, 0xD8, 0xB2, 0x81, 0xD4, 0xC0, + 0x75, 0x3D, 0x4B, 0x7F, 0xC7, 0x77, 0xC3, 0x3E, 0x78, 0xAB, 0x1A, 0x03, + 0xB5, 0x20, 0x6B, 0x2F, 0x6A, 0x2B, 0xB1, 0xC5, 0x88, 0x7E, 0xC4, 0xBB, + 0x1E, 0xB0, 0xC1, 0xD8, 0x45, 0x27, 0x6F, 0xAA, 0x37, 0x58, 0xF7, 0x87, + 0x26, 0xD7, 0xD8, 0x2D, 0xF6, 0xA9, 0x17, 0xB7, 0x1F, 0x72, 0x36, 0x4E, + 0xA6, 0x17, 0x3F, 0x65, 0x98, 0x92, 0xDB, 0x2A, 0x6E, 0x5D, 0xA2, 0xFE, + 0x88, 0xE0, 0x0B, 0xDE, 0x7F, 0xE5, 0x8D, 0x15, 0xE1, 0xEB, 0xCB, 0x3A, + 0xD5, 0xE2, 0x12, 0xA2, 0x13, 0x2D, 0xD8, 0x8E, 0xAF, 0x5F, 0x12, 0x3D, + 0xA0, 0x08, 0x05, 0x08, 0xB6, 0x5C, 0xA5, 0x65, 0x38, 0x04, 0x45, 0x99, + 0x1E, 0xA3, 0x60, 0x60, 0x74, 0xC5, 0x41, 0xA5, 0x72, 0x62, 0x1B, 0x62, + 0xC5, 0x1F, 0x6F, 0x5F, 0x1A, 0x42, 0xBE, 0x02, 0x51, 0x65, 0xA8, 0xAE, + 0x23, 0x18, 0x6A, 0xFC, 0x78, 0x03, 0xA9, 0x4D, 0x7F, 0x80, 0xC3, 0xFA, + 0xAB, 0x5A, 0xFC, 0xA1, 0x40, 0xA4, 0xCA, 0x19, 0x16, 0xFE, 0xB2, 0xC8, + 0xEF, 0x5E, 0x73, 0x0D, 0xEE, 0x77, 0xBD, 0x9A, 0xF6, 0x79, 0x98, 0xBC, + 0xB1, 0x07, 0x67, 0xA2, 0x15, 0x0D, 0xDD, 0xA0, 0x58, 0xC6, 0x44, 0x7B, + 0x0A, 0x3E, 0x62, 0x28, 0x5F, 0xBA, 0x41, 0x07, 0x53, 0x58, 0xCF, 0x11, + 0x7E, 0x38, 0x74, 0xC5, 0xF8, 0xFF, 0xB5, 0x69, 0x90, 0x8F, 0x84, 0x74, + 0xEA, 0x97, 0x1B, 0xAF +}; + +static const unsigned char TA467_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA468_DN[] = { + 0x30, 0x81, 0x83, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x1A, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, 0x47, 0x6F, 0x44, 0x61, 0x64, 0x64, + 0x79, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, + 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6F, + 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA468_RSA_N[] = { + 0xBF, 0x71, 0x62, 0x08, 0xF1, 0xFA, 0x59, 0x34, 0xF7, 0x1B, 0xC9, 0x18, + 0xA3, 0xF7, 0x80, 0x49, 0x58, 0xE9, 0x22, 0x83, 0x13, 0xA6, 0xC5, 0x20, + 0x43, 0x01, 0x3B, 0x84, 0xF1, 0xE6, 0x85, 0x49, 0x9F, 0x27, 0xEA, 0xF6, + 0x84, 0x1B, 0x4E, 0xA0, 0xB4, 0xDB, 0x70, 0x98, 0xC7, 0x32, 0x01, 0xB1, + 0x05, 0x3E, 0x07, 0x4E, 0xEE, 0xF4, 0xFA, 0x4F, 0x2F, 0x59, 0x30, 0x22, + 0xE7, 0xAB, 0x19, 0x56, 0x6B, 0xE2, 0x80, 0x07, 0xFC, 0xF3, 0x16, 0x75, + 0x80, 0x39, 0x51, 0x7B, 0xE5, 0xF9, 0x35, 0xB6, 0x74, 0x4E, 0xA9, 0x8D, + 0x82, 0x13, 0xE4, 0xB6, 0x3F, 0xA9, 0x03, 0x83, 0xFA, 0xA2, 0xBE, 0x8A, + 0x15, 0x6A, 0x7F, 0xDE, 0x0B, 0xC3, 0xB6, 0x19, 0x14, 0x05, 0xCA, 0xEA, + 0xC3, 0xA8, 0x04, 0x94, 0x3B, 0x46, 0x7C, 0x32, 0x0D, 0xF3, 0x00, 0x66, + 0x22, 0xC8, 0x8D, 0x69, 0x6D, 0x36, 0x8C, 0x11, 0x18, 0xB7, 0xD3, 0xB2, + 0x1C, 0x60, 0xB4, 0x38, 0xFA, 0x02, 0x8C, 0xCE, 0xD3, 0xDD, 0x46, 0x07, + 0xDE, 0x0A, 0x3E, 0xEB, 0x5D, 0x7C, 0xC8, 0x7C, 0xFB, 0xB0, 0x2B, 0x53, + 0xA4, 0x92, 0x62, 0x69, 0x51, 0x25, 0x05, 0x61, 0x1A, 0x44, 0x81, 0x8C, + 0x2C, 0xA9, 0x43, 0x96, 0x23, 0xDF, 0xAC, 0x3A, 0x81, 0x9A, 0x0E, 0x29, + 0xC5, 0x1C, 0xA9, 0xE9, 0x5D, 0x1E, 0xB6, 0x9E, 0x9E, 0x30, 0x0A, 0x39, + 0xCE, 0xF1, 0x88, 0x80, 0xFB, 0x4B, 0x5D, 0xCC, 0x32, 0xEC, 0x85, 0x62, + 0x43, 0x25, 0x34, 0x02, 0x56, 0x27, 0x01, 0x91, 0xB4, 0x3B, 0x70, 0x2A, + 0x3F, 0x6E, 0xB1, 0xE8, 0x9C, 0x88, 0x01, 0x7D, 0x9F, 0xD4, 0xF9, 0xDB, + 0x53, 0x6D, 0x60, 0x9D, 0xBF, 0x2C, 0xE7, 0x58, 0xAB, 0xB8, 0x5F, 0x46, + 0xFC, 0xCE, 0xC4, 0x1B, 0x03, 0x3C, 0x09, 0xEB, 0x49, 0x31, 0x5C, 0x69, + 0x46, 0xB3, 0xE0, 0x47 +}; + +static const unsigned char TA468_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA469_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, + 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA469_EC_Q[] = { + 0x04, 0x38, 0x08, 0xFE, 0xB1, 0xA0, 0x96, 0xD2, 0x7A, 0xAC, 0xAF, 0x49, + 0x3A, 0xD0, 0xC0, 0xE0, 0xC3, 0x3B, 0x28, 0xAA, 0xF1, 0x72, 0x6D, 0x65, + 0x00, 0x47, 0x88, 0x84, 0xFC, 0x9A, 0x26, 0x6B, 0xAA, 0x4B, 0xBA, 0x6C, + 0x04, 0x0A, 0x88, 0x5E, 0x17, 0xF2, 0x55, 0x87, 0xFC, 0x30, 0xB0, 0x34, + 0xE2, 0x34, 0x58, 0x57, 0x1A, 0x84, 0x53, 0xE9, 0x30, 0xD9, 0xA9, 0xF2, + 0x96, 0x74, 0xC3, 0x51, 0x1F, 0x58, 0x49, 0x31, 0xCC, 0x98, 0x4E, 0x60, + 0x11, 0x87, 0x75, 0xD3, 0x72, 0x94, 0x90, 0x4F, 0x9B, 0x10, 0x25, 0x2A, + 0xA8, 0x78, 0x2D, 0xBE, 0x90, 0x41, 0x58, 0x90, 0x15, 0x72, 0xA7, 0xA1, + 0xB7 +}; + +static const unsigned char TA470_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, + 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA470_RSA_N[] = { + 0x8B, 0xC2, 0xE7, 0xAF, 0x65, 0x9B, 0x05, 0x67, 0x96, 0xC9, 0x0D, 0x24, + 0xB9, 0xD0, 0x0E, 0x64, 0xFC, 0xCE, 0xE2, 0x24, 0x18, 0x2C, 0x84, 0x7F, + 0x77, 0x51, 0xCB, 0x04, 0x11, 0x36, 0xB8, 0x5E, 0xED, 0x69, 0x71, 0xA7, + 0x9E, 0xE4, 0x25, 0x09, 0x97, 0x67, 0xC1, 0x47, 0xC2, 0xCF, 0x91, 0x16, + 0x36, 0x62, 0x3D, 0x38, 0x04, 0xE1, 0x51, 0x82, 0xFF, 0xAC, 0xD2, 0xB4, + 0x69, 0xDD, 0x2E, 0xEC, 0x11, 0xA3, 0x45, 0xEE, 0x6B, 0x6B, 0x3B, 0x4C, + 0xBF, 0x8C, 0x8D, 0xA4, 0x1E, 0x9D, 0x11, 0xB9, 0xE9, 0x38, 0xF9, 0x7A, + 0x0E, 0x0C, 0x98, 0xE2, 0x23, 0x1D, 0xD1, 0x4E, 0x63, 0xD4, 0xE7, 0xB8, + 0x41, 0x44, 0xFB, 0x6B, 0xAF, 0x6B, 0xDA, 0x1F, 0xD3, 0xC5, 0x91, 0x88, + 0x5B, 0xA4, 0x89, 0x92, 0xD1, 0x81, 0xE6, 0x8C, 0x39, 0x58, 0xA0, 0xD6, + 0x69, 0x43, 0xA9, 0xAD, 0x98, 0x52, 0x58, 0x6E, 0xDB, 0x0A, 0xFB, 0x6B, + 0xCF, 0x68, 0xFA, 0xE3, 0xA4, 0x5E, 0x3A, 0x45, 0x73, 0x98, 0x07, 0xEA, + 0x5F, 0x02, 0x72, 0xDE, 0x0C, 0xA5, 0xB3, 0x9F, 0xAE, 0xA9, 0x1D, 0xB7, + 0x1D, 0xB3, 0xFC, 0x8A, 0x59, 0xE7, 0x6E, 0x72, 0x65, 0xAD, 0xF5, 0x30, + 0x94, 0x23, 0x07, 0xF3, 0x82, 0x16, 0x4B, 0x35, 0x98, 0x9C, 0x53, 0xBB, + 0x2F, 0xCA, 0xE4, 0x5A, 0xD9, 0xC7, 0x8D, 0x1D, 0xFC, 0x98, 0x99, 0xFB, + 0x2C, 0xA4, 0x82, 0x6B, 0xF0, 0x2A, 0x1F, 0x8E, 0x0B, 0x5F, 0x71, 0x5C, + 0x5C, 0xAE, 0x42, 0x7B, 0x29, 0x89, 0x81, 0xCB, 0x03, 0xA3, 0x99, 0xCA, + 0x88, 0x9E, 0x0B, 0x40, 0x09, 0x41, 0x33, 0xDB, 0xE6, 0x58, 0x7A, 0xFD, + 0xAE, 0x99, 0x70, 0xC0, 0x5A, 0x0F, 0xD6, 0x13, 0x86, 0x71, 0x2F, 0x76, + 0x69, 0xFC, 0x90, 0xDD, 0xDB, 0x2D, 0x6E, 0xD1, 0xF2, 0x9B, 0xF5, 0x1A, + 0x6B, 0x9E, 0x6F, 0x15, 0x8C, 0x7A, 0xF0, 0x4B, 0x28, 0xA0, 0x22, 0x38, + 0x80, 0x24, 0x6C, 0x36, 0xA4, 0x3B, 0xF2, 0x30, 0x91, 0xF3, 0x78, 0x13, + 0xCF, 0xC1, 0x3F, 0x35, 0xAB, 0xF1, 0x1D, 0x11, 0x23, 0xB5, 0x43, 0x22, + 0x9E, 0x01, 0x92, 0xB7, 0x18, 0x02, 0xE5, 0x11, 0xD1, 0x82, 0xDB, 0x15, + 0x00, 0xCC, 0x61, 0x37, 0xC1, 0x2A, 0x7C, 0x9A, 0xE1, 0xD0, 0xBA, 0xB3, + 0x50, 0x46, 0xEE, 0x82, 0xAC, 0x9D, 0x31, 0xF8, 0xFB, 0x23, 0xE2, 0x03, + 0x00, 0x48, 0x70, 0xA3, 0x09, 0x26, 0x79, 0x15, 0x53, 0x60, 0xF3, 0x38, + 0x5C, 0xAD, 0x38, 0xEA, 0x81, 0x00, 0x63, 0x14, 0xB9, 0x33, 0x5E, 0xDD, + 0x0B, 0xDB, 0xA0, 0x45, 0x07, 0x1A, 0x33, 0x09, 0xF8, 0x4D, 0xB4, 0xA7, + 0x02, 0xA6, 0x69, 0xF4, 0xC2, 0x59, 0x05, 0x88, 0x65, 0x85, 0x56, 0xAE, + 0x4B, 0xCB, 0xE0, 0xDE, 0x3C, 0x7D, 0x2D, 0x1A, 0xC8, 0xE9, 0xFB, 0x1F, + 0xA3, 0x61, 0x4A, 0xD6, 0x2A, 0x13, 0xAD, 0x77, 0x4C, 0x1A, 0x18, 0x9B, + 0x91, 0x0F, 0x58, 0xD8, 0x06, 0x54, 0xC5, 0x97, 0xF8, 0xAA, 0x3F, 0x20, + 0x8A, 0xA6, 0x85, 0xA6, 0x77, 0xF6, 0xA6, 0xFC, 0x1C, 0xE2, 0xEE, 0x6E, + 0x94, 0x33, 0x2A, 0x83, 0x50, 0x84, 0x0A, 0xE5, 0x4F, 0x86, 0xF8, 0x50, + 0x45, 0x78, 0x00, 0x81, 0xEB, 0x5B, 0x68, 0xE3, 0x26, 0x8D, 0xCC, 0x7B, + 0x5C, 0x51, 0xF4, 0x14, 0x2C, 0x40, 0xBE, 0x1A, 0x60, 0x1D, 0x7A, 0x72, + 0x61, 0x1D, 0x1F, 0x63, 0x2D, 0x88, 0xAA, 0xCE, 0xA2, 0x45, 0x90, 0x08, + 0xFC, 0x6B, 0xBE, 0xB3, 0x50, 0x2A, 0x5A, 0xFD, 0xA8, 0x48, 0x18, 0x46, + 0xD6, 0x90, 0x40, 0x92, 0x90, 0x0A, 0x84, 0x5E, 0x68, 0x31, 0xF8, 0xEB, + 0xED, 0x0D, 0xD3, 0x1D, 0xC6, 0x7D, 0x99, 0x18, 0x55, 0x56, 0x27, 0x65, + 0x2E, 0x8D, 0x45, 0xC5, 0x24, 0xEC, 0xCE, 0xE3 +}; + +static const unsigned char TA470_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA471_DN[] = { + 0x30, 0x81, 0xAA, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x44, 0x30, 0x42, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, + 0x20, 0x32, 0x30, 0x31, 0x35 +}; + +static const unsigned char TA471_EC_Q[] = { + 0x04, 0x92, 0xA0, 0x41, 0xE8, 0x4B, 0x82, 0x84, 0x5C, 0xE2, 0xF8, 0x31, + 0x11, 0x99, 0x86, 0x64, 0x4E, 0x09, 0x25, 0x2F, 0x9D, 0x41, 0x2F, 0x0A, + 0xAE, 0x35, 0x4F, 0x74, 0x95, 0xB2, 0x51, 0x64, 0x6B, 0x8D, 0x6B, 0xE6, + 0x3F, 0x70, 0x95, 0xF0, 0x05, 0x44, 0x47, 0xA6, 0x72, 0x38, 0x50, 0x76, + 0x95, 0x02, 0x5A, 0x8E, 0xAE, 0x28, 0x9E, 0xF9, 0x2D, 0x4E, 0x99, 0xEF, + 0x2C, 0x48, 0x6F, 0x4C, 0x25, 0x29, 0xE8, 0xD1, 0x71, 0x5B, 0xDF, 0x1D, + 0xC1, 0x75, 0x37, 0xB4, 0xD7, 0xFA, 0x7B, 0x7A, 0x42, 0x9C, 0x6A, 0x0A, + 0x56, 0x5A, 0x7C, 0x69, 0x0B, 0xAA, 0x80, 0x09, 0x24, 0x6C, 0x7E, 0xC1, + 0x46 +}; + +static const unsigned char TA472_DN[] = { + 0x30, 0x81, 0xA6, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x40, 0x30, 0x3E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x37, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, + 0x35 +}; + +static const unsigned char TA472_RSA_N[] = { + 0xC2, 0xF8, 0xA9, 0x3F, 0x1B, 0x89, 0xFC, 0x3C, 0x3C, 0x04, 0x5D, 0x3D, + 0x90, 0x36, 0xB0, 0x91, 0x3A, 0x79, 0x3C, 0x66, 0x5A, 0xEF, 0x6D, 0x39, + 0x01, 0x49, 0x1A, 0xB4, 0xB7, 0xCF, 0x7F, 0x4D, 0x23, 0x53, 0xB7, 0x90, + 0x00, 0xE3, 0x13, 0x2A, 0x28, 0xA6, 0x31, 0xF1, 0x91, 0x00, 0xE3, 0x28, + 0xEC, 0xAE, 0x21, 0x41, 0xCE, 0x1F, 0xDA, 0xFD, 0x7D, 0x12, 0x5B, 0x01, + 0x83, 0x0F, 0xB9, 0xB0, 0x5F, 0x99, 0xE1, 0xF2, 0x12, 0x83, 0x80, 0x4D, + 0x06, 0x3E, 0xDF, 0xAC, 0xAF, 0xE7, 0xA1, 0x88, 0x6B, 0x31, 0xAF, 0xF0, + 0x8B, 0xD0, 0x18, 0x33, 0xB8, 0xDB, 0x45, 0x6A, 0x34, 0xF4, 0x02, 0x80, + 0x24, 0x28, 0x0A, 0x02, 0x15, 0x95, 0x5E, 0x76, 0x2A, 0x0D, 0x99, 0x3A, + 0x14, 0x5B, 0xF6, 0xCB, 0xCB, 0x53, 0xBC, 0x13, 0x4D, 0x01, 0x88, 0x37, + 0x94, 0x25, 0x1B, 0x42, 0xBC, 0x22, 0xD8, 0x8E, 0xA3, 0x96, 0x5E, 0x3A, + 0xD9, 0x32, 0xDB, 0x3E, 0xE8, 0xF0, 0x10, 0x65, 0xED, 0x74, 0xE1, 0x2F, + 0xA7, 0x7C, 0xAF, 0x27, 0x34, 0xBB, 0x29, 0x7D, 0x9B, 0xB6, 0xCF, 0x09, + 0xC8, 0xE5, 0xD3, 0x0A, 0xFC, 0x88, 0x65, 0x65, 0x74, 0x0A, 0xDC, 0x73, + 0x1C, 0x5C, 0xCD, 0x40, 0xB1, 0x1C, 0xD4, 0xB6, 0x84, 0x8C, 0x4C, 0x50, + 0xCF, 0x68, 0x8E, 0xA8, 0x59, 0xAE, 0xC2, 0x27, 0x4E, 0x82, 0xA2, 0x35, + 0xDD, 0x14, 0xF4, 0x1F, 0xFF, 0xB2, 0x77, 0xD5, 0x87, 0x2F, 0xAA, 0x6E, + 0x7D, 0x24, 0x27, 0xE7, 0xC6, 0xCB, 0x26, 0xE6, 0xE5, 0xFE, 0x67, 0x07, + 0x63, 0xD8, 0x45, 0x0D, 0xDD, 0x3A, 0x59, 0x65, 0x39, 0x58, 0x7A, 0x92, + 0x99, 0x72, 0x3D, 0x9C, 0x84, 0x5E, 0x88, 0x21, 0xB8, 0xD5, 0xF4, 0x2C, + 0xFC, 0xD9, 0x70, 0x52, 0x4F, 0x78, 0xB8, 0xBD, 0x3C, 0x2B, 0x8B, 0x95, + 0x98, 0xF5, 0xB3, 0xD1, 0x68, 0xCF, 0x20, 0x14, 0x7E, 0x4C, 0x5C, 0x5F, + 0xE7, 0x8B, 0xE5, 0xF5, 0x35, 0x81, 0x19, 0x37, 0xD7, 0x11, 0x08, 0xB7, + 0x66, 0xBE, 0xD3, 0x4A, 0xCE, 0x83, 0x57, 0x00, 0x3A, 0xC3, 0x81, 0xF8, + 0x17, 0xCB, 0x92, 0x36, 0x5D, 0xD1, 0xA3, 0xD8, 0x75, 0x1B, 0xE1, 0x8B, + 0x27, 0xEA, 0x7A, 0x48, 0x41, 0xFD, 0x45, 0x19, 0x06, 0xAD, 0x27, 0x99, + 0x4E, 0xC1, 0x70, 0x47, 0xDD, 0xB5, 0x9F, 0x81, 0x53, 0x12, 0xE5, 0xB1, + 0x8C, 0x48, 0x5D, 0x31, 0x43, 0x17, 0xE3, 0x8C, 0xC6, 0x7A, 0x63, 0x96, + 0x4B, 0x29, 0x30, 0x4E, 0x84, 0x4E, 0x62, 0x19, 0x5E, 0x3C, 0xCE, 0x97, + 0x90, 0xA5, 0x7F, 0x01, 0xEB, 0x9D, 0xE0, 0xF8, 0x8B, 0x89, 0xDD, 0x25, + 0x98, 0x3D, 0x92, 0xB6, 0x7E, 0xEF, 0xD9, 0xF1, 0x51, 0x51, 0x7D, 0x2D, + 0x26, 0xC8, 0x69, 0x59, 0x61, 0xE0, 0xAC, 0x6A, 0xB8, 0x2A, 0x36, 0x11, + 0x04, 0x7A, 0x50, 0xBD, 0x32, 0x84, 0xBE, 0x2F, 0xDC, 0x72, 0xD5, 0xD7, + 0x1D, 0x16, 0x47, 0xE4, 0x47, 0x66, 0x20, 0x3F, 0xF4, 0x96, 0xC5, 0xAF, + 0x8E, 0x01, 0x7A, 0xA5, 0x0F, 0x7A, 0x64, 0xF5, 0x0D, 0x18, 0x87, 0xD9, + 0xAE, 0x88, 0xD5, 0xFA, 0x84, 0xC1, 0x3A, 0xC0, 0x69, 0x28, 0x2D, 0xF2, + 0x0D, 0x68, 0x51, 0xAA, 0xE3, 0xA5, 0x77, 0xC6, 0xA4, 0x90, 0x0E, 0xA1, + 0x37, 0x8B, 0x31, 0x23, 0x47, 0xC1, 0x09, 0x08, 0xEB, 0x6E, 0xF7, 0x78, + 0x9B, 0xD7, 0x82, 0xFC, 0x84, 0x20, 0x99, 0x49, 0x19, 0xB6, 0x12, 0x46, + 0xB1, 0xFB, 0x45, 0x55, 0x16, 0xA9, 0xA3, 0x65, 0xAC, 0x9C, 0x07, 0x0F, + 0xEA, 0x6B, 0xDC, 0x1F, 0x2E, 0x06, 0x72, 0xEC, 0x86, 0x88, 0x12, 0xE4, + 0x2D, 0xDB, 0x5F, 0x05, 0x2F, 0xE4, 0xF0, 0x03, 0xD3, 0x26, 0x33, 0xE7, + 0x80, 0xC2, 0xCD, 0x42, 0xA1, 0x17, 0x34, 0x0B +}; + +static const unsigned char TA472_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA473_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x12, 0x48, 0x69, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA473_RSA_N[] = { + 0xF4, 0x1E, 0x7F, 0x52, 0x73, 0x32, 0x0C, 0x73, 0xE4, 0xBD, 0x13, 0x74, + 0xA3, 0xD4, 0x30, 0xA8, 0xD0, 0xAE, 0x4B, 0xD8, 0xB6, 0xDF, 0x75, 0x47, + 0x66, 0xF4, 0x7C, 0xE7, 0x39, 0x04, 0x1E, 0x6A, 0x70, 0x20, 0xD2, 0x5A, + 0x47, 0x72, 0x67, 0x55, 0xF4, 0xA5, 0xE8, 0x9D, 0xD5, 0x1E, 0x21, 0xA1, + 0xF0, 0x67, 0xBA, 0xCC, 0x21, 0x68, 0xBE, 0x44, 0x53, 0xBF, 0x8D, 0xF9, + 0xE2, 0xDC, 0x2F, 0x55, 0xC8, 0x37, 0x3F, 0x1F, 0xA4, 0xC0, 0x9C, 0xB3, + 0xE4, 0x77, 0x5C, 0xA0, 0x46, 0xFE, 0x77, 0xFA, 0x1A, 0xA0, 0x38, 0xEA, + 0xED, 0x9A, 0x72, 0xDE, 0x2B, 0xBD, 0x94, 0x57, 0x3A, 0xBA, 0xEC, 0x79, + 0xE7, 0x5F, 0x7D, 0x42, 0x64, 0x39, 0x7A, 0x26, 0x36, 0xF7, 0x24, 0xF0, + 0xD5, 0x2F, 0xBA, 0x95, 0x98, 0x11, 0x66, 0xAD, 0x97, 0x35, 0xD6, 0x75, + 0x01, 0x80, 0xE0, 0xAF, 0xF4, 0x84, 0x61, 0x8C, 0x0D, 0x1E, 0x5F, 0x7C, + 0x87, 0x96, 0x5E, 0x41, 0xAF, 0xEB, 0x87, 0xEA, 0xF8, 0x5D, 0xF1, 0x2E, + 0x88, 0x05, 0x3E, 0x4C, 0x22, 0xBB, 0xDA, 0x1F, 0x2A, 0xDD, 0x52, 0x46, + 0x64, 0x39, 0xF3, 0x42, 0xCE, 0xD9, 0x9E, 0x0C, 0xB3, 0xB0, 0x77, 0x97, + 0x64, 0x9C, 0xC0, 0xF4, 0xA3, 0x2E, 0x1F, 0x95, 0x07, 0xB0, 0x17, 0xDF, + 0x30, 0xDB, 0x00, 0x18, 0x96, 0x4C, 0xA1, 0x81, 0x4B, 0xDD, 0x04, 0x6D, + 0x53, 0xA3, 0x3D, 0xFC, 0x07, 0xAC, 0xD4, 0xC5, 0x37, 0x82, 0xEB, 0xE4, + 0x95, 0x08, 0x19, 0x28, 0x82, 0xD2, 0x42, 0x3A, 0xA3, 0xD8, 0x53, 0xEC, + 0x79, 0x89, 0x60, 0x48, 0x60, 0xC8, 0x72, 0x92, 0x50, 0xDC, 0x03, 0x8F, + 0x83, 0x3F, 0xB2, 0x42, 0x57, 0x5A, 0xDB, 0x6A, 0xE9, 0x11, 0x97, 0xDD, + 0x85, 0x28, 0xBC, 0x30, 0x4C, 0xAB, 0xE3, 0xC2, 0xB1, 0x45, 0x44, 0x47, + 0x1F, 0xE0, 0x8A, 0x16, 0x07, 0x96, 0xD2, 0x21, 0x0F, 0x53, 0xC0, 0xED, + 0xA9, 0x7E, 0xD4, 0x4E, 0xEC, 0x9B, 0x09, 0xEC, 0xAF, 0x42, 0xAC, 0x30, + 0xD6, 0xBF, 0xD1, 0x10, 0x45, 0xE0, 0xA6, 0x16, 0xB2, 0xA5, 0xC5, 0xD3, + 0x4F, 0x73, 0x94, 0x33, 0x71, 0x02, 0xA1, 0x6A, 0xA3, 0xD6, 0x33, 0x97, + 0x4F, 0x21, 0x63, 0x1E, 0x5B, 0x8F, 0xD9, 0xC1, 0x5E, 0x45, 0x71, 0x77, + 0x0F, 0x81, 0x5D, 0x5F, 0x21, 0x9A, 0xAD, 0x83, 0xCC, 0xFA, 0x5E, 0xD6, + 0x8D, 0x23, 0x5F, 0x1B, 0x3D, 0x41, 0xAF, 0x20, 0x75, 0x66, 0x5A, 0x4A, + 0xF6, 0x9F, 0xFB, 0xAB, 0x18, 0xF7, 0x71, 0xC0, 0xB6, 0x1D, 0x31, 0xEC, + 0x3B, 0x20, 0xEB, 0xCB, 0xE2, 0xB8, 0xF5, 0xAE, 0x92, 0xB2, 0xF7, 0xE1, + 0x84, 0x4B, 0xF2, 0xA2, 0xF2, 0x93, 0x9A, 0x22, 0x9E, 0xD3, 0x14, 0x6F, + 0x36, 0x54, 0xBD, 0x1F, 0x5E, 0x59, 0x15, 0xB9, 0x73, 0xA8, 0xC1, 0x7C, + 0x6F, 0x7B, 0x62, 0xE9, 0x16, 0x6C, 0x47, 0x5A, 0x65, 0xF3, 0x0E, 0x11, + 0x9B, 0x46, 0xD9, 0xFD, 0x6D, 0xDC, 0xD6, 0x9C, 0xC0, 0xB4, 0x7D, 0xA5, + 0xB0, 0xDD, 0x3F, 0x56, 0x6F, 0xA1, 0xF9, 0xF6, 0xE4, 0x12, 0x48, 0xFD, + 0x06, 0x7F, 0x12, 0x57, 0xB6, 0xA9, 0x23, 0x4F, 0x5B, 0x03, 0xC3, 0xE0, + 0x71, 0x2A, 0x23, 0xB7, 0xF7, 0xB0, 0xB1, 0x3B, 0xBC, 0x98, 0xBD, 0xD6, + 0x98, 0xA8, 0x0C, 0x6B, 0xF6, 0x8E, 0x12, 0x67, 0xA6, 0xF2, 0xB2, 0x58, + 0xE4, 0x02, 0x09, 0x13, 0x3C, 0xA9, 0xBB, 0x10, 0xB4, 0xD2, 0x30, 0x45, + 0xF1, 0xEC, 0xF7, 0x00, 0x11, 0xDF, 0x65, 0xF8, 0xDC, 0x2B, 0x43, 0x55, + 0xBF, 0x16, 0x97, 0xC4, 0x0F, 0xD5, 0x2C, 0x61, 0x84, 0xAA, 0x72, 0x86, + 0xFE, 0xE6, 0x3A, 0x7E, 0xC2, 0x3F, 0x7D, 0xEE, 0xFC, 0x2F, 0x14, 0x3E, + 0xE6, 0x85, 0xDD, 0x50, 0x6F, 0xB7, 0x49, 0xED +}; + +static const unsigned char TA473_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA474_DN[] = { + 0x30, 0x6F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x4B, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x09, 0x48, 0x6F, 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x48, 0x6F, + 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA474_RSA_N[] = { + 0xB3, 0x88, 0xD7, 0xEA, 0xCE, 0x0F, 0x20, 0x4E, 0xBE, 0xE6, 0xD6, 0x03, + 0x6D, 0xEE, 0x59, 0xFC, 0xC2, 0x57, 0xDF, 0x29, 0x68, 0xA1, 0x83, 0x0E, + 0x3E, 0x68, 0xC7, 0x68, 0x58, 0x9C, 0x1C, 0x60, 0x4B, 0x89, 0x43, 0x0C, + 0xB9, 0xD4, 0x15, 0xB2, 0xEE, 0xC1, 0x4E, 0x75, 0xE9, 0xB5, 0xA7, 0xEF, + 0xE5, 0xE9, 0x35, 0x99, 0xE4, 0xCC, 0x1C, 0xE7, 0x4B, 0x5F, 0x8D, 0x33, + 0x30, 0x20, 0x33, 0x53, 0xD9, 0xA6, 0xBB, 0xD5, 0x3E, 0x13, 0x8E, 0xE9, + 0x1F, 0x87, 0x49, 0xAD, 0x50, 0x2D, 0x50, 0xCA, 0x18, 0xBE, 0x01, 0x58, + 0xA2, 0x13, 0x70, 0x96, 0xBB, 0x89, 0x88, 0x56, 0x80, 0x5C, 0xF8, 0xBD, + 0x2C, 0x3C, 0xE1, 0x4C, 0x57, 0x88, 0xBB, 0xD3, 0xB9, 0x95, 0xEF, 0xCB, + 0xC7, 0xF6, 0xDA, 0x31, 0x74, 0x28, 0xA6, 0xE6, 0x54, 0x89, 0xF5, 0x41, + 0x31, 0xCA, 0xE5, 0x26, 0x1A, 0xCD, 0x82, 0xE0, 0x70, 0xDA, 0x3B, 0x29, + 0xBB, 0xD5, 0x03, 0xF5, 0x99, 0xBA, 0x55, 0xF5, 0x64, 0xD1, 0x60, 0x0E, + 0xB3, 0x89, 0x49, 0xB8, 0x8A, 0x2F, 0x05, 0xD2, 0x84, 0x45, 0x28, 0x7C, + 0x8F, 0x68, 0x50, 0x12, 0x78, 0xFC, 0x0B, 0xB5, 0x53, 0xCB, 0xC2, 0x98, + 0x1C, 0x84, 0xA3, 0x9E, 0xB0, 0xBE, 0x23, 0xA4, 0xDA, 0xDC, 0xC8, 0x2B, + 0x1E, 0xDA, 0x6E, 0x45, 0x1E, 0x89, 0x98, 0xDA, 0xF9, 0x00, 0x2E, 0x06, + 0xE9, 0x0C, 0x3B, 0x70, 0xD5, 0x50, 0x25, 0x88, 0x99, 0xCB, 0xCD, 0x73, + 0x60, 0xF7, 0xD5, 0xFF, 0x35, 0x67, 0xC5, 0xA1, 0xBC, 0x5E, 0xAB, 0xCD, + 0x4A, 0xB8, 0x45, 0xEB, 0xC8, 0x68, 0x1E, 0x0D, 0x0D, 0x14, 0x46, 0x12, + 0xE3, 0xD2, 0x64, 0x62, 0x8A, 0x42, 0x98, 0xBC, 0xB4, 0xC6, 0x08, 0x08, + 0xF8, 0xFD, 0xA8, 0x4C, 0x64, 0x9C, 0x76, 0x01, 0xBD, 0x2F, 0xA9, 0x6C, + 0x33, 0x0F, 0xD8, 0x3F, 0x28, 0xB8, 0x3C, 0x69, 0x01, 0x42, 0x86, 0x7E, + 0x69, 0xC1, 0xC9, 0x06, 0xCA, 0xE5, 0x7A, 0x46, 0x65, 0xE9, 0xC2, 0xD6, + 0x50, 0x41, 0x2E, 0x3F, 0xB7, 0xE4, 0xED, 0x6C, 0xD7, 0xBF, 0x26, 0x01, + 0x11, 0xA2, 0x16, 0x29, 0x4A, 0x6B, 0x34, 0x06, 0x90, 0xEC, 0x13, 0xD2, + 0xB6, 0xFB, 0x6A, 0x76, 0xD2, 0x3C, 0xED, 0xF0, 0xD6, 0x2D, 0xDD, 0xE1, + 0x15, 0xEC, 0xA3, 0x9B, 0x2F, 0x2C, 0xC9, 0x3E, 0x2B, 0xE4, 0x69, 0x3B, + 0xFF, 0x72, 0x25, 0xB1, 0x36, 0x86, 0x5B, 0xC7, 0x7F, 0x6B, 0x8B, 0x55, + 0x1B, 0x4A, 0xC5, 0x20, 0x61, 0x3D, 0xAE, 0xCB, 0x50, 0xE1, 0x08, 0x3A, + 0xBE, 0xB0, 0x8F, 0x63, 0x41, 0x53, 0x30, 0x08, 0x59, 0x3C, 0x98, 0x1D, + 0x77, 0xBA, 0x63, 0x91, 0x7A, 0xCA, 0x10, 0x50, 0x60, 0xBF, 0xF0, 0xD7, + 0xBC, 0x95, 0x87, 0x8F, 0x97, 0xC5, 0xFE, 0x97, 0x6A, 0x01, 0x94, 0xA3, + 0x7C, 0x5B, 0x85, 0x1D, 0x2A, 0x39, 0x3A, 0xD0, 0x54, 0xA1, 0xD1, 0x39, + 0x71, 0x9D, 0xFD, 0x21, 0xF9, 0xB5, 0x7B, 0xF0, 0xE2, 0xE0, 0x02, 0x8F, + 0x6E, 0x96, 0x24, 0x25, 0x2C, 0xA0, 0x1E, 0x2C, 0xA8, 0xC4, 0x89, 0xA7, + 0xEF, 0xED, 0x99, 0x06, 0x2F, 0xB6, 0x0A, 0x4C, 0x4F, 0xDB, 0xA2, 0xCC, + 0x37, 0x1A, 0xAF, 0x47, 0x85, 0x2D, 0x8A, 0x5F, 0xC4, 0x34, 0x34, 0x4C, + 0x00, 0xFD, 0x18, 0x93, 0x67, 0x13, 0xD1, 0x37, 0xE6, 0x48, 0xB4, 0x8B, + 0x06, 0xC5, 0x57, 0x7B, 0x19, 0x86, 0x0A, 0x79, 0xCB, 0x00, 0xC9, 0x52, + 0xAF, 0x42, 0xFF, 0x37, 0x8F, 0xE1, 0xA3, 0x1E, 0x7A, 0x3D, 0x50, 0xAB, + 0x63, 0x06, 0xE7, 0x15, 0xB5, 0x3F, 0xB6, 0x45, 0x37, 0x94, 0x37, 0xB1, + 0x7E, 0xF2, 0x48, 0xC3, 0x7F, 0xC5, 0x75, 0xFE, 0x97, 0x8D, 0x45, 0x8F, + 0x1A, 0xA7, 0x1A, 0x72, 0x28, 0x1A, 0x40, 0x0F +}; + +static const unsigned char TA474_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA475_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x31 +}; + +static const unsigned char TA475_RSA_N[] = { + 0xAD, 0xE8, 0x24, 0x73, 0xF4, 0x14, 0x37, 0xF3, 0x9B, 0x9E, 0x2B, 0x57, + 0x28, 0x1C, 0x87, 0xBE, 0xDC, 0xB7, 0xDF, 0x38, 0x90, 0x8C, 0x6E, 0x3C, + 0xE6, 0x57, 0xA0, 0x78, 0xF7, 0x75, 0xC2, 0xA2, 0xFE, 0xF5, 0x6A, 0x6E, + 0xF6, 0x00, 0x4F, 0x28, 0xDB, 0xDE, 0x68, 0x86, 0x6C, 0x44, 0x93, 0xB6, + 0xB1, 0x63, 0xFD, 0x14, 0x12, 0x6B, 0xBF, 0x1F, 0xD2, 0xEA, 0x31, 0x9B, + 0x21, 0x7E, 0xD1, 0x33, 0x3C, 0xBA, 0x48, 0xF5, 0xDD, 0x79, 0xDF, 0xB3, + 0xB8, 0xFF, 0x12, 0xF1, 0x21, 0x9A, 0x4B, 0xC1, 0x8A, 0x86, 0x71, 0x69, + 0x4A, 0x66, 0x66, 0x6C, 0x8F, 0x7E, 0x3C, 0x70, 0xBF, 0xAD, 0x29, 0x22, + 0x06, 0xF3, 0xE4, 0xC0, 0xE6, 0x80, 0xAE, 0xE2, 0x4B, 0x8F, 0xB7, 0x99, + 0x7E, 0x94, 0x03, 0x9F, 0xD3, 0x47, 0x97, 0x7C, 0x99, 0x48, 0x23, 0x53, + 0xE8, 0x38, 0xAE, 0x4F, 0x0A, 0x6F, 0x83, 0x2E, 0xD1, 0x49, 0x57, 0x8C, + 0x80, 0x74, 0xB6, 0xDA, 0x2F, 0xD0, 0x38, 0x8D, 0x7B, 0x03, 0x70, 0x21, + 0x1B, 0x75, 0xF2, 0x30, 0x3C, 0xFA, 0x8F, 0xAE, 0xDD, 0xDA, 0x63, 0xAB, + 0xEB, 0x16, 0x4F, 0xC2, 0x8E, 0x11, 0x4B, 0x7E, 0xCF, 0x0B, 0xE8, 0xFF, + 0xB5, 0x77, 0x2E, 0xF4, 0xB2, 0x7B, 0x4A, 0xE0, 0x4C, 0x12, 0x25, 0x0C, + 0x70, 0x8D, 0x03, 0x29, 0xA0, 0xE1, 0x53, 0x24, 0xEC, 0x13, 0xD9, 0xEE, + 0x19, 0xBF, 0x10, 0xB3, 0x4A, 0x8C, 0x3F, 0x89, 0xA3, 0x61, 0x51, 0xDE, + 0xAC, 0x87, 0x07, 0x94, 0xF4, 0x63, 0x71, 0xEC, 0x2E, 0xE2, 0x6F, 0x5B, + 0x98, 0x81, 0xE1, 0x89, 0x5C, 0x34, 0x79, 0x6C, 0x76, 0xEF, 0x3B, 0x90, + 0x62, 0x79, 0xE6, 0xDB, 0xA4, 0x9A, 0x2F, 0x26, 0xC5, 0xD0, 0x10, 0xE1, + 0x0E, 0xDE, 0xD9, 0x10, 0x8E, 0x16, 0xFB, 0xB7, 0xF7, 0xA8, 0xF7, 0xC7, + 0xE5, 0x02, 0x07, 0x98, 0x8F, 0x36, 0x08, 0x95, 0xE7, 0xE2, 0x37, 0x96, + 0x0D, 0x36, 0x75, 0x9E, 0xFB, 0x0E, 0x72, 0xB1, 0x1D, 0x9B, 0xBC, 0x03, + 0xF9, 0x49, 0x05, 0xD8, 0x81, 0xDD, 0x05, 0xB4, 0x2A, 0xD6, 0x41, 0xE9, + 0xAC, 0x01, 0x76, 0x95, 0x0A, 0x0F, 0xD8, 0xDF, 0xD5, 0xBD, 0x12, 0x1F, + 0x35, 0x2F, 0x28, 0x17, 0x6C, 0xD2, 0x98, 0xC1, 0xA8, 0x09, 0x64, 0x77, + 0x6E, 0x47, 0x37, 0xBA, 0xCE, 0xAC, 0x59, 0x5E, 0x68, 0x9D, 0x7F, 0x72, + 0xD6, 0x89, 0xC5, 0x06, 0x41, 0x29, 0x3E, 0x59, 0x3E, 0xDD, 0x26, 0xF5, + 0x24, 0xC9, 0x11, 0xA7, 0x5A, 0xA3, 0x4C, 0x40, 0x1F, 0x46, 0xA1, 0x99, + 0xB5, 0xA7, 0x3A, 0x51, 0x6E, 0x86, 0x3B, 0x9E, 0x7D, 0x72, 0xA7, 0x12, + 0x05, 0x78, 0x59, 0xED, 0x3E, 0x51, 0x78, 0x15, 0x0B, 0x03, 0x8F, 0x8D, + 0xD0, 0x2F, 0x05, 0xB2, 0x3E, 0x7B, 0x4A, 0x1C, 0x4B, 0x73, 0x05, 0x12, + 0xFC, 0xC6, 0xEA, 0xE0, 0x50, 0x13, 0x7C, 0x43, 0x93, 0x74, 0xB3, 0xCA, + 0x74, 0xE7, 0x8E, 0x1F, 0x01, 0x08, 0xD0, 0x30, 0xD4, 0x5B, 0x71, 0x36, + 0xB4, 0x07, 0xBA, 0xC1, 0x30, 0x30, 0x5C, 0x48, 0xB7, 0x82, 0x3B, 0x98, + 0xA6, 0x7D, 0x60, 0x8A, 0xA2, 0xA3, 0x29, 0x82, 0xCC, 0xBA, 0xBD, 0x83, + 0x04, 0x1B, 0xA2, 0x83, 0x03, 0x41, 0xA1, 0xD6, 0x05, 0xF1, 0x1B, 0xC2, + 0xB6, 0xF0, 0xA8, 0x7C, 0x86, 0x3B, 0x46, 0xA8, 0x48, 0x2A, 0x88, 0xDC, + 0x76, 0x9A, 0x76, 0xBF, 0x1F, 0x6A, 0xA5, 0x3D, 0x19, 0x8F, 0xEB, 0x38, + 0xF3, 0x64, 0xDE, 0xC8, 0x2B, 0x0D, 0x0A, 0x28, 0xFF, 0xF7, 0xDB, 0xE2, + 0x15, 0x42, 0xD4, 0x22, 0xD0, 0x27, 0x5D, 0xE1, 0x79, 0xFE, 0x18, 0xE7, + 0x70, 0x88, 0xAD, 0x4E, 0xE6, 0xD9, 0x8B, 0x3A, 0xC6, 0xDD, 0x27, 0x51, + 0x6E, 0xFF, 0xBC, 0x64, 0xF5, 0x33, 0x43, 0x4F +}; + +static const unsigned char TA475_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA476_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x32 +}; + +static const unsigned char TA476_EC_Q[] = { + 0x04, 0xCD, 0x9B, 0xD5, 0x9F, 0x80, 0x83, 0x0A, 0xEC, 0x09, 0x4A, 0xF3, + 0x16, 0x4A, 0x3E, 0x5C, 0xCF, 0x77, 0xAC, 0xDE, 0x67, 0x05, 0x0D, 0x1D, + 0x07, 0xB6, 0xDC, 0x16, 0xFB, 0x5A, 0x8B, 0x14, 0xDB, 0xE2, 0x71, 0x60, + 0xC4, 0xBA, 0x45, 0x95, 0x11, 0x89, 0x8E, 0xEA, 0x06, 0xDF, 0xF7, 0x2A, + 0x16, 0x1C, 0xA4, 0xB9, 0xC5, 0xC5, 0x32, 0xE0, 0x03, 0xE0, 0x1E, 0x82, + 0x18, 0x38, 0x8B, 0xD7, 0x45, 0xD8, 0x0A, 0x6A, 0x6E, 0xE6, 0x00, 0x77, + 0xFB, 0x02, 0x51, 0x7D, 0x22, 0xD8, 0x0A, 0x6E, 0x9A, 0x5B, 0x77, 0xDF, + 0xF0, 0xFA, 0x41, 0xEC, 0x39, 0xDC, 0x75, 0xCA, 0x68, 0x07, 0x0C, 0x1F, + 0xEA +}; + +static const unsigned char TA477_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6F, 0x6D, 0x6D, + 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA477_RSA_N[] = { + 0xA7, 0x50, 0x19, 0xDE, 0x3F, 0x99, 0x3D, 0xD4, 0x33, 0x46, 0xF1, 0x6F, + 0x51, 0x61, 0x82, 0xB2, 0xA9, 0x4F, 0x8F, 0x67, 0x89, 0x5D, 0x84, 0xD9, + 0x53, 0xDD, 0x0C, 0x28, 0xD9, 0xD7, 0xF0, 0xFF, 0xAE, 0x95, 0x43, 0x72, + 0x99, 0xF9, 0xB5, 0x5D, 0x7C, 0x8A, 0xC1, 0x42, 0xE1, 0x31, 0x50, 0x74, + 0xD1, 0x81, 0x0D, 0x7C, 0xCD, 0x9B, 0x21, 0xAB, 0x43, 0xE2, 0xAC, 0xAD, + 0x5E, 0x86, 0x6E, 0xF3, 0x09, 0x8A, 0x1F, 0x5A, 0x32, 0xBD, 0xA2, 0xEB, + 0x94, 0xF9, 0xE8, 0x5C, 0x0A, 0xEC, 0xFF, 0x98, 0xD2, 0xAF, 0x71, 0xB3, + 0xB4, 0x53, 0x9F, 0x4E, 0x87, 0xEF, 0x92, 0xBC, 0xBD, 0xEC, 0x4F, 0x32, + 0x30, 0x88, 0x4B, 0x17, 0x5E, 0x57, 0xC4, 0x53, 0xC2, 0xF6, 0x02, 0x97, + 0x8D, 0xD9, 0x62, 0x2B, 0xBF, 0x24, 0x1F, 0x62, 0x8D, 0xDF, 0xC3, 0xB8, + 0x29, 0x4B, 0x49, 0x78, 0x3C, 0x93, 0x60, 0x88, 0x22, 0xFC, 0x99, 0xDA, + 0x36, 0xC8, 0xC2, 0xA2, 0xD4, 0x2C, 0x54, 0x00, 0x67, 0x35, 0x6E, 0x73, + 0xBF, 0x02, 0x58, 0xF0, 0xA4, 0xDD, 0xE5, 0xB0, 0xA2, 0x26, 0x7A, 0xCA, + 0xE0, 0x36, 0xA5, 0x19, 0x16, 0xF5, 0xFD, 0xB7, 0xEF, 0xAE, 0x3F, 0x40, + 0xF5, 0x6D, 0x5A, 0x04, 0xFD, 0xCE, 0x34, 0xCA, 0x24, 0xDC, 0x74, 0x23, + 0x1B, 0x5D, 0x33, 0x13, 0x12, 0x5D, 0xC4, 0x01, 0x25, 0xF6, 0x30, 0xDD, + 0x02, 0x5D, 0x9F, 0xE0, 0xD5, 0x47, 0xBD, 0xB4, 0xEB, 0x1B, 0xA1, 0xBB, + 0x49, 0x49, 0xD8, 0x9F, 0x5B, 0x02, 0xF3, 0x8A, 0xE4, 0x24, 0x90, 0xE4, + 0x62, 0x4F, 0x4F, 0xC1, 0xAF, 0x8B, 0x0E, 0x74, 0x17, 0xA8, 0xD1, 0x72, + 0x88, 0x6A, 0x7A, 0x01, 0x49, 0xCC, 0xB4, 0x46, 0x79, 0xC6, 0x17, 0xB1, + 0xDA, 0x98, 0x1E, 0x07, 0x59, 0xFA, 0x75, 0x21, 0x85, 0x65, 0xDD, 0x90, + 0x56, 0xCE, 0xFB, 0xAB, 0xA5, 0x60, 0x9D, 0xC4, 0x9D, 0xF9, 0x52, 0xB0, + 0x8B, 0xBD, 0x87, 0xF9, 0x8F, 0x2B, 0x23, 0x0A, 0x23, 0x76, 0x3B, 0xF7, + 0x33, 0xE1, 0xC9, 0x00, 0xF3, 0x69, 0xF9, 0x4B, 0xA2, 0xE0, 0x4E, 0xBC, + 0x7E, 0x93, 0x39, 0x84, 0x07, 0xF7, 0x44, 0x70, 0x7E, 0xFE, 0x07, 0x5A, + 0xE5, 0xB1, 0xAC, 0xD1, 0x18, 0xCC, 0xF2, 0x35, 0xE5, 0x49, 0x49, 0x08, + 0xCA, 0x56, 0xC9, 0x3D, 0xFB, 0x0F, 0x18, 0x7D, 0x8B, 0x3B, 0xC1, 0x13, + 0xC2, 0x4D, 0x8F, 0xC9, 0x4F, 0x0E, 0x37, 0xE9, 0x1F, 0xA1, 0x0E, 0x6A, + 0xDF, 0x62, 0x2E, 0xCB, 0x35, 0x06, 0x51, 0x79, 0x2C, 0xC8, 0x25, 0x38, + 0xF4, 0xFA, 0x4B, 0xA7, 0x89, 0x5C, 0x9C, 0xD2, 0xE3, 0x0D, 0x39, 0x86, + 0x4A, 0x74, 0x7C, 0xD5, 0x59, 0x87, 0xC2, 0x3F, 0x4E, 0x0C, 0x5C, 0x52, + 0xF4, 0x3D, 0xF7, 0x52, 0x82, 0xF1, 0xEA, 0xA3, 0xAC, 0xFD, 0x49, 0x34, + 0x1A, 0x28, 0xF3, 0x41, 0x88, 0x3A, 0x13, 0xEE, 0xE8, 0xDE, 0xFF, 0x99, + 0x1D, 0x5F, 0xBA, 0xCB, 0xE8, 0x1E, 0xF2, 0xB9, 0x50, 0x60, 0xC0, 0x31, + 0xD3, 0x73, 0xE5, 0xEF, 0xBE, 0xA0, 0xED, 0x33, 0x0B, 0x74, 0xBE, 0x20, + 0x20, 0xC4, 0x67, 0x6C, 0xF0, 0x08, 0x03, 0x7A, 0x55, 0x80, 0x7F, 0x46, + 0x4E, 0x96, 0xA7, 0xF4, 0x1E, 0x3E, 0xE1, 0xF6, 0xD8, 0x09, 0xE1, 0x33, + 0x64, 0x2B, 0x63, 0xD7, 0x32, 0x5E, 0x9F, 0xF9, 0xC0, 0x7B, 0x0F, 0x78, + 0x6F, 0x97, 0xBC, 0x93, 0x9A, 0xF9, 0x9C, 0x12, 0x90, 0x78, 0x7A, 0x80, + 0x87, 0x15, 0xD7, 0x72, 0x74, 0x9C, 0x55, 0x74, 0x78, 0xB1, 0xBA, 0xE1, + 0x6E, 0x70, 0x04, 0xBA, 0x4F, 0xA0, 0xBA, 0x68, 0xC3, 0x7B, 0xFF, 0x31, + 0xF0, 0x73, 0x3D, 0x3D, 0x94, 0x2A, 0xB1, 0x0B, 0x41, 0x0E, 0xA0, 0xFE, + 0x4D, 0x88, 0x65, 0x6B, 0x79, 0x33, 0xB4, 0xD7 +}; + +static const unsigned char TA477_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA478_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x53, 0x65, 0x63, 0x74, 0x6F, 0x72, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA478_RSA_N[] = { + 0xB6, 0x22, 0x94, 0xFC, 0xA4, 0x48, 0xAF, 0xE8, 0x47, 0x6B, 0x0A, 0xFB, + 0x27, 0x76, 0xE4, 0xF2, 0x3F, 0x8A, 0x3B, 0x7A, 0x4A, 0x2C, 0x31, 0x2A, + 0x8C, 0x8D, 0xB0, 0xA9, 0xC3, 0x31, 0x6B, 0xA8, 0x77, 0x76, 0x84, 0x26, + 0xB6, 0xAC, 0x81, 0x42, 0x0D, 0x08, 0xEB, 0x55, 0x58, 0xBB, 0x7A, 0xF8, + 0xBC, 0x65, 0x7D, 0xF2, 0xA0, 0x6D, 0x8B, 0xA8, 0x47, 0xE9, 0x62, 0x76, + 0x1E, 0x11, 0xEE, 0x08, 0x14, 0xD1, 0xB2, 0x44, 0x16, 0xF4, 0xEA, 0xD0, + 0xFA, 0x1E, 0x2F, 0x5E, 0xDB, 0xCB, 0x73, 0x41, 0xAE, 0xBC, 0x00, 0xB0, + 0x4A, 0x2B, 0x40, 0xB2, 0xAC, 0xE1, 0x3B, 0x4B, 0xC2, 0x2D, 0x9D, 0xE4, + 0xA1, 0x9B, 0xEC, 0x1A, 0x3A, 0x1E, 0xF0, 0x08, 0xB3, 0xD0, 0xE4, 0x24, + 0x35, 0x07, 0x9F, 0x9C, 0xB4, 0xC9, 0x52, 0x6D, 0xDB, 0x07, 0xCA, 0x8F, + 0xB5, 0x5B, 0xF0, 0x83, 0xF3, 0x4F, 0xC7, 0x2D, 0xA5, 0xC8, 0xAD, 0xCB, + 0x95, 0x20, 0xA4, 0x31, 0x28, 0x57, 0x58, 0x5A, 0xE4, 0x8D, 0x1B, 0x9A, + 0xAB, 0x9E, 0x0D, 0x0C, 0xF2, 0x0A, 0x33, 0x39, 0x22, 0x39, 0x0A, 0x97, + 0x2E, 0xF3, 0x53, 0x77, 0xB9, 0x44, 0x45, 0xFD, 0x84, 0xCB, 0x36, 0x20, + 0x81, 0x59, 0x2D, 0x9A, 0x6F, 0x6D, 0x48, 0x48, 0x61, 0xCA, 0x4C, 0xDF, + 0x53, 0xD1, 0xAF, 0x52, 0xBC, 0x44, 0x9F, 0xAB, 0x2F, 0x6B, 0x83, 0x72, + 0xEF, 0x75, 0x80, 0xDA, 0x06, 0x33, 0x1B, 0x5D, 0xC8, 0xDA, 0x63, 0xC6, + 0x4D, 0xCD, 0xAC, 0x66, 0x31, 0xCD, 0xD1, 0xDE, 0x3E, 0x87, 0x10, 0x36, + 0xE1, 0xB9, 0xA4, 0x7A, 0xEF, 0x60, 0x50, 0xB2, 0xCB, 0xCA, 0xA6, 0x56, + 0xE0, 0x37, 0xAF, 0xAB, 0x34, 0x13, 0x39, 0x25, 0xE8, 0x39, 0x66, 0xE4, + 0x98, 0x7A, 0xAA, 0x12, 0x98, 0x9C, 0x59, 0x66, 0x86, 0x3E, 0xAD, 0xF1, + 0xB0, 0xCA, 0x3E, 0x06, 0x0F, 0x7B, 0xF0, 0x11, 0x4B, 0x37, 0xA0, 0x44, + 0x6D, 0x7B, 0xCB, 0xA8, 0x8C, 0x71, 0xF4, 0xD5, 0xB5, 0x91, 0x36, 0xCC, + 0xF0, 0x15, 0xC6, 0x2B, 0xDE, 0x51, 0x17, 0xB1, 0x97, 0x4C, 0x50, 0x3D, + 0xB1, 0x95, 0x59, 0x7C, 0x05, 0x7D, 0x2D, 0x21, 0xD5, 0x00, 0xBF, 0x01, + 0x67, 0xA2, 0x5E, 0x7B, 0xA6, 0x5C, 0xF2, 0xF7, 0x22, 0xF1, 0x90, 0x0D, + 0x93, 0xDB, 0xAA, 0x44, 0x51, 0x66, 0xCC, 0x7D, 0x76, 0x03, 0xEB, 0x6A, + 0xA8, 0x2A, 0x38, 0x19, 0x97, 0x76, 0x0D, 0x6B, 0x8A, 0x61, 0xF9, 0xBC, + 0xF6, 0xEE, 0x76, 0xFD, 0x70, 0x2B, 0xDD, 0x29, 0x3C, 0xF8, 0x0A, 0x1E, + 0x5B, 0x42, 0x1C, 0x8B, 0x56, 0x2F, 0x55, 0x1B, 0x1C, 0xA1, 0x2E, 0xB5, + 0xC7, 0x16, 0xE6, 0xF8, 0xAA, 0x3C, 0x92, 0x8E, 0x69, 0xB6, 0x01, 0xC1, + 0xB5, 0x86, 0x9D, 0x89, 0x0F, 0x0B, 0x38, 0x94, 0x54, 0xE8, 0xEA, 0xDC, + 0x9E, 0x3D, 0x25, 0xBC, 0x53, 0x26, 0xED, 0xD5, 0xAB, 0x39, 0xAA, 0xC5, + 0x40, 0x4C, 0x54, 0xAB, 0xB2, 0xB4, 0xD9, 0xD9, 0xF8, 0xD7, 0x72, 0xDB, + 0x1C, 0xBC, 0x6D, 0xBD, 0x65, 0x5F, 0xEF, 0x88, 0x35, 0x2A, 0x66, 0x2F, + 0xEE, 0xF6, 0xB3, 0x65, 0xF0, 0x33, 0x8D, 0x7C, 0x98, 0x41, 0x69, 0x46, + 0x0F, 0x43, 0x1C, 0x69, 0xFA, 0x9B, 0xB5, 0xD0, 0x61, 0x6A, 0xCD, 0xCA, + 0x4B, 0xD9, 0x4C, 0x90, 0x46, 0xAB, 0x15, 0x59, 0xA1, 0x47, 0x54, 0x29, + 0x2E, 0x83, 0x28, 0x5F, 0x1C, 0xC2, 0xA2, 0xAB, 0x72, 0x17, 0x00, 0x06, + 0x8E, 0x45, 0xEC, 0x8B, 0xE2, 0x33, 0x3D, 0x7F, 0xDA, 0x19, 0x44, 0xE4, + 0x62, 0x72, 0xC3, 0xDF, 0x22, 0xC6, 0xF2, 0x56, 0xD4, 0xDD, 0x5F, 0x95, + 0x72, 0xED, 0x6D, 0x5F, 0xF7, 0x48, 0x03, 0x5B, 0xFD, 0xC5, 0x2A, 0xA0, + 0xF6, 0x73, 0x23, 0x84, 0x10, 0x1B, 0x01, 0xE7 +}; + +static const unsigned char TA478_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA479_DN[] = { + 0x30, 0x38, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x49, 0x5A, 0x45, 0x4E, 0x50, 0x45, 0x20, 0x53, 0x2E, 0x41, + 0x2E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0A, + 0x49, 0x7A, 0x65, 0x6E, 0x70, 0x65, 0x2E, 0x63, 0x6F, 0x6D +}; + +static const unsigned char TA479_RSA_N[] = { + 0xC9, 0xD3, 0x7A, 0xCA, 0x0F, 0x1E, 0xAC, 0xA7, 0x86, 0xE8, 0x16, 0x65, + 0x6A, 0xB1, 0xC2, 0x1B, 0x45, 0x32, 0x71, 0x95, 0xD9, 0xFE, 0x10, 0x5B, + 0xCC, 0xAF, 0xE7, 0xA5, 0x79, 0x01, 0x8F, 0x89, 0xC3, 0xCA, 0xF2, 0x55, + 0x71, 0xF7, 0x77, 0xBE, 0x77, 0x94, 0xF3, 0x72, 0xA4, 0x2C, 0x44, 0xD8, + 0x9E, 0x92, 0x9B, 0x14, 0x3A, 0xA1, 0xE7, 0x24, 0x90, 0x0A, 0x0A, 0x56, + 0x8E, 0xC5, 0xD8, 0x26, 0x94, 0xE1, 0xD9, 0x48, 0xE1, 0x2D, 0x3E, 0xDA, + 0x0A, 0x72, 0xDD, 0xA3, 0x99, 0x15, 0xDA, 0x81, 0xA2, 0x87, 0xF4, 0x7B, + 0x6E, 0x26, 0x77, 0x89, 0x58, 0xAD, 0xD6, 0xEB, 0x0C, 0xB2, 0x41, 0x7A, + 0x73, 0x6E, 0x6D, 0xDB, 0x7A, 0x78, 0x41, 0xE9, 0x08, 0x88, 0x12, 0x7E, + 0x87, 0x2E, 0x66, 0x11, 0x63, 0x6C, 0x54, 0xFB, 0x3C, 0x9D, 0x72, 0xC0, + 0xBC, 0x2E, 0xFF, 0xC2, 0xB7, 0xDD, 0x0D, 0x76, 0xE3, 0x3A, 0xD7, 0xF7, + 0xB4, 0x68, 0xBE, 0xA2, 0xF5, 0xE3, 0x81, 0x6E, 0xC1, 0x46, 0x6F, 0x5D, + 0x8D, 0xE0, 0x4D, 0xC6, 0x54, 0x55, 0x89, 0x1A, 0x33, 0x31, 0x0A, 0xB1, + 0x57, 0xB9, 0xA3, 0x8A, 0x98, 0xC3, 0xEC, 0x3B, 0x34, 0xC5, 0x95, 0x41, + 0x69, 0x7E, 0x75, 0xC2, 0x3C, 0x20, 0xC5, 0x61, 0xBA, 0x51, 0x47, 0xA0, + 0x20, 0x90, 0x93, 0xA1, 0x90, 0x4B, 0xF3, 0x4E, 0x7C, 0x85, 0x45, 0x54, + 0x9A, 0xD1, 0x05, 0x26, 0x41, 0xB0, 0xB5, 0x4D, 0x1D, 0x33, 0xBE, 0xC4, + 0x03, 0xC8, 0x25, 0x7C, 0xC1, 0x70, 0xDB, 0x3B, 0xF4, 0x09, 0x2D, 0x54, + 0x27, 0x48, 0xAC, 0x2F, 0xE1, 0xC4, 0xAC, 0x3E, 0xC8, 0xCB, 0x92, 0x4C, + 0x53, 0x39, 0x37, 0x23, 0xEC, 0xD3, 0x01, 0xF9, 0xE0, 0x09, 0x44, 0x4D, + 0x4D, 0x64, 0xC0, 0xE1, 0x0D, 0x5A, 0x87, 0x22, 0xBC, 0xAD, 0x1B, 0xA3, + 0xFE, 0x26, 0xB5, 0x15, 0xF3, 0xA7, 0xFC, 0x84, 0x19, 0xE9, 0xEC, 0xA1, + 0x88, 0xB4, 0x44, 0x69, 0x84, 0x83, 0xF3, 0x89, 0xD1, 0x74, 0x06, 0xA9, + 0xCC, 0x0B, 0xD6, 0xC2, 0xDE, 0x27, 0x85, 0x50, 0x26, 0xCA, 0x17, 0xB8, + 0xC9, 0x7A, 0x87, 0x56, 0x2C, 0x1A, 0x01, 0x1E, 0x6C, 0xBE, 0x13, 0xAD, + 0x10, 0xAC, 0xB5, 0x24, 0xF5, 0x38, 0x91, 0xA1, 0xD6, 0x4B, 0xDA, 0xF1, + 0xBB, 0xD2, 0xDE, 0x47, 0xB5, 0xF1, 0xBC, 0x81, 0xF6, 0x59, 0x6B, 0xCF, + 0x19, 0x53, 0xE9, 0x8D, 0x15, 0xCB, 0x4A, 0xCB, 0xA9, 0x6F, 0x44, 0xE5, + 0x1B, 0x41, 0xCF, 0xE1, 0x86, 0xA7, 0xCA, 0xD0, 0x6A, 0x9F, 0xBC, 0x4C, + 0x8D, 0x06, 0x33, 0x5A, 0xA2, 0x85, 0xE5, 0x90, 0x35, 0xA0, 0x62, 0x5C, + 0x16, 0x4E, 0xF0, 0xE3, 0xA2, 0xFA, 0x03, 0x1A, 0xB4, 0x2C, 0x71, 0xB3, + 0x58, 0x2C, 0xDE, 0x7B, 0x0B, 0xDB, 0x1A, 0x0F, 0xEB, 0xDE, 0x21, 0x1F, + 0x06, 0x77, 0x06, 0x03, 0xB0, 0xC9, 0xEF, 0x99, 0xFC, 0xC0, 0xB9, 0x4F, + 0x0B, 0x86, 0x28, 0xFE, 0xD2, 0xB9, 0xEA, 0xE3, 0xDA, 0xA5, 0xC3, 0x47, + 0x69, 0x12, 0xE0, 0xDB, 0xF0, 0xF6, 0x19, 0x8B, 0xED, 0x7B, 0x70, 0xD7, + 0x02, 0xD6, 0xED, 0x87, 0x18, 0x28, 0x2C, 0x04, 0x24, 0x4C, 0x77, 0xE4, + 0x48, 0x8A, 0x1A, 0xC6, 0x3B, 0x9A, 0xD4, 0x0F, 0xCA, 0xFA, 0x75, 0xD2, + 0x01, 0x40, 0x5A, 0x8D, 0x79, 0xBF, 0x8B, 0xCF, 0x4B, 0xCF, 0xAA, 0x16, + 0xC1, 0x95, 0xE4, 0xAD, 0x4C, 0x8A, 0x3E, 0x17, 0x91, 0xD4, 0xB1, 0x62, + 0xE5, 0x82, 0xE5, 0x80, 0x04, 0xA4, 0x03, 0x7E, 0x8D, 0xBF, 0xDA, 0x7F, + 0xA2, 0x0F, 0x97, 0x4F, 0x0C, 0xD3, 0x0D, 0xFB, 0xD7, 0xD1, 0xE5, 0x72, + 0x7E, 0x1C, 0xC8, 0x77, 0xFF, 0x5B, 0x9A, 0x0F, 0xB7, 0xAE, 0x05, 0x46, + 0xE5, 0xF1, 0xA8, 0x16, 0xEC, 0x47, 0xA4, 0x17 +}; + +static const unsigned char TA479_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA480_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x65, 0x2D, 0x53, 0x7A, 0x69, + 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x32, 0x30, 0x30, 0x39, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x65, 0x2D, 0x73, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x2E, 0x68, + 0x75 +}; + +static const unsigned char TA480_RSA_N[] = { + 0xE9, 0xF8, 0x8F, 0xF3, 0x63, 0xAD, 0xDA, 0x86, 0xD8, 0xA7, 0xE0, 0x42, + 0xFB, 0xCF, 0x91, 0xDE, 0xA6, 0x26, 0xF8, 0x99, 0xA5, 0x63, 0x70, 0xAD, + 0x9B, 0xAE, 0xCA, 0x33, 0x40, 0x7D, 0x6D, 0x96, 0x6E, 0xA1, 0x0E, 0x44, + 0xEE, 0xE1, 0x13, 0x9D, 0x94, 0x42, 0x52, 0x9A, 0xBD, 0x75, 0x85, 0x74, + 0x2C, 0xA8, 0x0E, 0x1D, 0x93, 0xB6, 0x18, 0xB7, 0x8C, 0x2C, 0xA8, 0xCF, + 0xFB, 0x5C, 0x71, 0xB9, 0xDA, 0xEC, 0xFE, 0xE8, 0x7E, 0x8F, 0xE4, 0x2F, + 0x1D, 0xB2, 0xA8, 0x75, 0x87, 0xD8, 0xB7, 0xA1, 0xE5, 0x3B, 0xCF, 0x99, + 0x4A, 0x46, 0xD0, 0x83, 0x19, 0x7D, 0xC0, 0xA1, 0x12, 0x1C, 0x95, 0x6D, + 0x4A, 0xF4, 0xD8, 0xC7, 0xA5, 0x4D, 0x33, 0x2E, 0x85, 0x39, 0x40, 0x75, + 0x7E, 0x14, 0x7C, 0x80, 0x12, 0x98, 0x50, 0xC7, 0x41, 0x67, 0xB8, 0xA0, + 0x80, 0x61, 0x54, 0xA6, 0x6C, 0x4E, 0x1F, 0xE0, 0x9D, 0x0E, 0x07, 0xE9, + 0xC9, 0xBA, 0x33, 0xE7, 0xFE, 0xC0, 0x55, 0x28, 0x2C, 0x02, 0x80, 0xA7, + 0x19, 0xF5, 0x9E, 0xDC, 0x55, 0x53, 0x03, 0x97, 0x7B, 0x07, 0x48, 0xFF, + 0x99, 0xFB, 0x37, 0x8A, 0x24, 0xC4, 0x59, 0xCC, 0x50, 0x10, 0x63, 0x8E, + 0xAA, 0xA9, 0x1A, 0xB0, 0x84, 0x1A, 0x86, 0xF9, 0x5F, 0xBB, 0xB1, 0x50, + 0x6E, 0xA4, 0xD1, 0x0A, 0xCC, 0xD5, 0x71, 0x7E, 0x1F, 0xA7, 0x1B, 0x7C, + 0xF5, 0x53, 0x6E, 0x22, 0x5F, 0xCB, 0x2B, 0xE6, 0xD4, 0x7C, 0x5D, 0xAE, + 0xD6, 0xC2, 0xC6, 0x4C, 0xE5, 0x05, 0x01, 0xD9, 0xED, 0x57, 0xFC, 0xC1, + 0x23, 0x79, 0xFC, 0xFA, 0xC8, 0x24, 0x83, 0x95, 0xF3, 0xB5, 0x6A, 0x51, + 0x01, 0xD0, 0x77, 0xD6, 0xE9, 0x12, 0xA1, 0xF9, 0x1A, 0x83, 0xFB, 0x82, + 0x1B, 0xB9, 0xB0, 0x97, 0xF4, 0x76, 0x06, 0x33, 0x43, 0x49, 0xA0, 0xFF, + 0x0B, 0xB5, 0xFA, 0xB5 +}; + +static const unsigned char TA480_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA481_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA481_EC_Q[] = { + 0x04, 0xD4, 0xBC, 0x3D, 0x02, 0x42, 0x75, 0x41, 0x13, 0x23, 0xCD, 0x80, + 0x04, 0x86, 0x02, 0x51, 0x2F, 0x6A, 0xA8, 0x81, 0x62, 0x0B, 0x65, 0xCC, + 0xF6, 0xCA, 0x9D, 0x1E, 0x6F, 0x4A, 0x66, 0x51, 0xA2, 0x03, 0xD9, 0x9D, + 0x91, 0xFA, 0xB6, 0x16, 0xB1, 0x8C, 0x6E, 0xDE, 0x7C, 0xCD, 0xDB, 0x79, + 0xA6, 0x2F, 0xCE, 0xBB, 0xCE, 0x71, 0x2F, 0xE5, 0xA5, 0xAB, 0x28, 0xEC, + 0x63, 0x04, 0x66, 0x99, 0xF8, 0xFA, 0xF2, 0x93, 0x10, 0x05, 0xE1, 0x81, + 0x28, 0x42, 0xE3, 0xC6, 0x68, 0xF4, 0xE6, 0x1B, 0x84, 0x60, 0x4A, 0x89, + 0xAF, 0xED, 0x79, 0x0F, 0x3B, 0xCE, 0xF1, 0xF6, 0x44, 0xF5, 0x01, 0x78, + 0xC0 +}; + +static const unsigned char TA482_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA482_RSA_N[] = { + 0xCA, 0x5B, 0xBE, 0x94, 0x33, 0x8C, 0x29, 0x95, 0x91, 0x16, 0x0A, 0x95, + 0xBD, 0x47, 0x62, 0xC1, 0x89, 0xF3, 0x99, 0x36, 0xDF, 0x46, 0x90, 0xC9, + 0xA5, 0xED, 0x78, 0x6A, 0x6F, 0x47, 0x91, 0x68, 0xF8, 0x27, 0x67, 0x50, + 0x33, 0x1D, 0xA1, 0xA6, 0xFB, 0xE0, 0xE5, 0x43, 0xA3, 0x84, 0x02, 0x57, + 0x01, 0x5D, 0x9C, 0x48, 0x40, 0x82, 0x53, 0x10, 0xBC, 0xBF, 0xC7, 0x3B, + 0x68, 0x90, 0xB6, 0x82, 0x2D, 0xE5, 0xF4, 0x65, 0xD0, 0xCC, 0x6D, 0x19, + 0xCC, 0x95, 0xF9, 0x7B, 0xAC, 0x4A, 0x94, 0xAD, 0x0E, 0xDE, 0x4B, 0x43, + 0x1D, 0x87, 0x07, 0x92, 0x13, 0x90, 0x80, 0x83, 0x64, 0x35, 0x39, 0x04, + 0xFC, 0xE5, 0xE9, 0x6C, 0xB3, 0xB6, 0x1F, 0x50, 0x94, 0x38, 0x65, 0x50, + 0x5C, 0x17, 0x46, 0xB9, 0xB6, 0x85, 0xB5, 0x1C, 0xB5, 0x17, 0xE8, 0xD6, + 0x45, 0x9D, 0xD8, 0xB2, 0x26, 0xB0, 0xCA, 0xC4, 0x70, 0x4A, 0xAE, 0x60, + 0xA4, 0xDD, 0xB3, 0xD9, 0xEC, 0xFC, 0x3B, 0xD5, 0x57, 0x72, 0xBC, 0x3F, + 0xC8, 0xC9, 0xB2, 0xDE, 0x4B, 0x6B, 0xF8, 0x23, 0x6C, 0x03, 0xC0, 0x05, + 0xBD, 0x95, 0xC7, 0xCD, 0x73, 0x3B, 0x66, 0x80, 0x64, 0xE3, 0x1A, 0xAC, + 0x2E, 0xF9, 0x47, 0x05, 0xF2, 0x06, 0xB6, 0x9B, 0x73, 0xF5, 0x78, 0x33, + 0x5B, 0xC7, 0xA1, 0xFB, 0x27, 0x2A, 0xA1, 0xB4, 0x9A, 0x91, 0x8C, 0x91, + 0xD3, 0x3A, 0x82, 0x3E, 0x76, 0x40, 0xB4, 0xCD, 0x52, 0x61, 0x51, 0x70, + 0x28, 0x3F, 0xC5, 0xC5, 0x5A, 0xF2, 0xC9, 0x8C, 0x49, 0xBB, 0x14, 0x5B, + 0x4D, 0xC8, 0xFF, 0x67, 0x4D, 0x4C, 0x12, 0x96, 0xAD, 0xF5, 0xFE, 0x78, + 0xA8, 0x97, 0x87, 0xD7, 0xFD, 0x5E, 0x20, 0x80, 0xDC, 0xA1, 0x4B, 0x22, + 0xFB, 0xD4, 0x89, 0xAD, 0xBA, 0xCE, 0x47, 0x97, 0x47, 0x55, 0x7B, 0x8F, + 0x45, 0xC8, 0x67, 0x28, 0x84, 0x95, 0x1C, 0x68, 0x30, 0xEF, 0xEF, 0x49, + 0xE0, 0x35, 0x7B, 0x64, 0xE7, 0x98, 0xB0, 0x94, 0xDA, 0x4D, 0x85, 0x3B, + 0x3E, 0x55, 0xC4, 0x28, 0xAF, 0x57, 0xF3, 0x9E, 0x13, 0xDB, 0x46, 0x27, + 0x9F, 0x1E, 0xA2, 0x5E, 0x44, 0x83, 0xA4, 0xA5, 0xCA, 0xD5, 0x13, 0xB3, + 0x4B, 0x3F, 0xC4, 0xE3, 0xC2, 0xE6, 0x86, 0x61, 0xA4, 0x52, 0x30, 0xB9, + 0x7A, 0x20, 0x4F, 0x6F, 0x0F, 0x38, 0x53, 0xCB, 0x33, 0x0C, 0x13, 0x2B, + 0x8F, 0xD6, 0x9A, 0xBD, 0x2A, 0xC8, 0x2D, 0xB1, 0x1C, 0x7D, 0x4B, 0x51, + 0xCA, 0x47, 0xD1, 0x48, 0x27, 0x72, 0x5D, 0x87, 0xEB, 0xD5, 0x45, 0xE6, + 0x48, 0x65, 0x9D, 0xAF, 0x52, 0x90, 0xBA, 0x5B, 0xA2, 0x18, 0x65, 0x57, + 0x12, 0x9F, 0x68, 0xB9, 0xD4, 0x15, 0x6B, 0x94, 0xC4, 0x69, 0x22, 0x98, + 0xF4, 0x33, 0xE0, 0xED, 0xF9, 0x51, 0x8E, 0x41, 0x50, 0xC9, 0x34, 0x4F, + 0x76, 0x90, 0xAC, 0xFC, 0x38, 0xC1, 0xD8, 0xE1, 0x7B, 0xB9, 0xE3, 0xE3, + 0x94, 0xE1, 0x46, 0x69, 0xCB, 0x0E, 0x0A, 0x50, 0x6B, 0x13, 0xBA, 0xAC, + 0x0F, 0x37, 0x5A, 0xB7, 0x12, 0xB5, 0x90, 0x81, 0x1E, 0x56, 0xAE, 0x57, + 0x22, 0x86, 0xD9, 0xC9, 0xD2, 0xD1, 0xD7, 0x51, 0xE3, 0xAB, 0x3B, 0xC6, + 0x55, 0xFD, 0x1E, 0x0E, 0xD3, 0x74, 0x0A, 0xD1, 0xDA, 0xAA, 0xEA, 0x69, + 0xB8, 0x97, 0x28, 0x8F, 0x48, 0xC4, 0x07, 0xF8, 0x52, 0x43, 0x3A, 0xF4, + 0xCA, 0x55, 0x35, 0x2C, 0xB0, 0xA6, 0x6A, 0xC0, 0x9C, 0xF9, 0xF2, 0x81, + 0xE1, 0x12, 0x6A, 0xC0, 0x45, 0xD9, 0x67, 0xB3, 0xCE, 0xFF, 0x23, 0xA2, + 0x89, 0x0A, 0x54, 0xD4, 0x14, 0xB9, 0x2A, 0xA8, 0xD7, 0xEC, 0xF9, 0xAB, + 0xCD, 0x25, 0x58, 0x32, 0x79, 0x8F, 0x90, 0x5B, 0x98, 0x39, 0xC4, 0x08, + 0x06, 0xC1, 0xAC, 0x7F, 0x0E, 0x3D, 0x00, 0xA5 +}; + +static const unsigned char TA482_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA483_DN[] = { + 0x30, 0x69, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4B, 0x52, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, 0x42, 0x55, 0x53, 0x49, + 0x4E, 0x45, 0x53, 0x53, 0x20, 0x50, 0x4C, 0x41, 0x54, 0x46, 0x4F, 0x52, + 0x4D, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA483_RSA_N[] = { + 0xB6, 0xD4, 0xF1, 0x93, 0x5C, 0xB5, 0x40, 0x89, 0x0A, 0xAB, 0x0D, 0x90, + 0x5B, 0x50, 0x63, 0xAE, 0x90, 0x94, 0x74, 0x17, 0x45, 0x72, 0xD6, 0x7B, + 0x65, 0x5A, 0x29, 0x4B, 0xA7, 0x56, 0xA0, 0x4B, 0xB8, 0x2F, 0x42, 0x75, + 0xE9, 0xD9, 0x7B, 0x24, 0x5A, 0x31, 0x65, 0xAB, 0x17, 0x17, 0xD1, 0x33, + 0x3A, 0xD9, 0x11, 0xDC, 0x40, 0x36, 0x87, 0xDF, 0xC7, 0x6A, 0xE9, 0x26, + 0x5E, 0x59, 0x8A, 0x77, 0xE3, 0xE8, 0x48, 0x9C, 0x31, 0x16, 0xFA, 0x3E, + 0x91, 0xB1, 0xCA, 0xC9, 0xA3, 0xE2, 0x9F, 0xCE, 0x21, 0x53, 0xA3, 0x02, + 0x36, 0x30, 0xCB, 0x52, 0x02, 0xE5, 0xDA, 0x32, 0x5D, 0xC3, 0xC5, 0xE6, + 0xF9, 0xEE, 0x11, 0xC7, 0x8B, 0xC9, 0x44, 0x1E, 0x84, 0x93, 0x18, 0x4A, + 0xB4, 0x9F, 0xE5, 0x12, 0x64, 0x69, 0xD0, 0x26, 0x85, 0x62, 0x01, 0xB6, + 0xC9, 0x02, 0x1D, 0xBE, 0x83, 0x51, 0xBB, 0x5C, 0xDA, 0xF8, 0xAD, 0x15, + 0x6A, 0x99, 0xF7, 0x92, 0x54, 0xF7, 0x34, 0x5B, 0xE9, 0xBF, 0xEA, 0x29, + 0x81, 0x12, 0xD4, 0x53, 0x91, 0x96, 0xB3, 0x91, 0x5A, 0xDD, 0xFE, 0x90, + 0x73, 0x28, 0xFB, 0x30, 0x46, 0xB5, 0xCA, 0x08, 0x07, 0xC7, 0x71, 0x72, + 0xC9, 0x66, 0xD3, 0x34, 0x97, 0xF6, 0x8C, 0xF4, 0x18, 0x4A, 0xE1, 0xD0, + 0x3D, 0x5A, 0x45, 0xB6, 0x69, 0xA7, 0x29, 0xFB, 0x23, 0xCE, 0x88, 0xD8, + 0x12, 0x9C, 0x00, 0x48, 0xA8, 0xA6, 0x0F, 0xB3, 0x3B, 0x92, 0x8D, 0x71, + 0x0E, 0x74, 0xC5, 0x8B, 0xC8, 0x4C, 0xF9, 0xF4, 0x9B, 0x8E, 0xB8, 0x3C, + 0x69, 0xED, 0x6F, 0x3B, 0x50, 0x2F, 0x58, 0xED, 0xC4, 0xB0, 0xD0, 0x1C, + 0x1B, 0x6A, 0x0C, 0xE2, 0xBC, 0x44, 0xAA, 0xD8, 0xCD, 0x14, 0x5D, 0x94, + 0x78, 0x61, 0xBF, 0x0E, 0x6E, 0xDA, 0x2A, 0xBC, 0x2F, 0x0C, 0x0B, 0x71, + 0xA6, 0xB3, 0x16, 0x3F, 0x9C, 0xE6, 0xF9, 0xCC, 0x9F, 0x53, 0x35, 0xE2, + 0x03, 0xA0, 0xA0, 0x18, 0xBF, 0xBB, 0xF1, 0xBE, 0xF4, 0xD6, 0x8C, 0x87, + 0x0D, 0x42, 0xF7, 0x06, 0xB9, 0xF1, 0x6D, 0xED, 0x04, 0x94, 0xA8, 0xFE, + 0xB6, 0xD3, 0x06, 0xC6, 0x40, 0x61, 0xDF, 0x9D, 0x9D, 0xF3, 0x54, 0x76, + 0xCE, 0x53, 0x3A, 0x01, 0xA6, 0x92, 0x41, 0xEC, 0x04, 0xA3, 0x8F, 0x0D, + 0xA2, 0xD5, 0x09, 0xCA, 0xD6, 0xCB, 0x9A, 0xF1, 0xEF, 0x43, 0x5D, 0xC0, + 0xAB, 0xA5, 0x41, 0xCF, 0x5C, 0x53, 0x70, 0x70, 0xC9, 0x88, 0xA6, 0x2D, + 0xD4, 0x6B, 0x61, 0x73, 0x50, 0x26, 0x86, 0x61, 0x0E, 0x5F, 0x1B, 0xC2, + 0x2B, 0xE2, 0x8C, 0xD5, 0xBB, 0x9D, 0xC1, 0x03, 0x42, 0xBA, 0x94, 0xDA, + 0x5F, 0xA9, 0xB0, 0xCA, 0xCC, 0x4D, 0x0A, 0xEF, 0x47, 0x69, 0x03, 0x2F, + 0x22, 0xFB, 0xF1, 0x28, 0xCE, 0xBF, 0x5D, 0x50, 0x65, 0xA8, 0x90, 0x6D, + 0xB3, 0x74, 0xB0, 0x08, 0xC7, 0xAC, 0xA8, 0xD1, 0xEB, 0x3E, 0x9C, 0xFC, + 0x5D, 0x1A, 0x83, 0x2E, 0x2B, 0xCB, 0xB5, 0xF3, 0x44, 0x9D, 0x3A, 0xA7, + 0x17, 0x61, 0x96, 0xA2, 0x71, 0xD3, 0x70, 0x96, 0x15, 0x4D, 0xB7, 0x4C, + 0x73, 0xEE, 0x19, 0x5C, 0xC5, 0x5B, 0x3E, 0x41, 0xFE, 0xAC, 0x75, 0x60, + 0x3B, 0x1B, 0x63, 0xCE, 0x00, 0xDD, 0xDA, 0x08, 0x90, 0x62, 0xB4, 0xE5, + 0x2D, 0xEE, 0x48, 0xA7, 0x6B, 0x17, 0x99, 0x54, 0xBE, 0x87, 0x4A, 0xE3, + 0xA9, 0x5E, 0x04, 0x4C, 0xEB, 0x10, 0x6D, 0x54, 0xD6, 0xEF, 0xF1, 0xE8, + 0xF2, 0x62, 0x16, 0xCB, 0x80, 0x6B, 0xED, 0x3D, 0xED, 0xF5, 0x1F, 0x30, + 0xA5, 0xAE, 0x4B, 0xC9, 0x13, 0xED, 0x8A, 0x01, 0x01, 0xC9, 0xB8, 0x51, + 0x58, 0xC0, 0x66, 0x3A, 0xB1, 0x66, 0x4B, 0xC4, 0xD5, 0x31, 0x02, 0x62, + 0xE9, 0x74, 0x84, 0x0C, 0xDB, 0x4D, 0x46, 0x2D +}; + +static const unsigned char TA483_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA484_DN[] = { + 0x30, 0x81, 0xA7, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x4E, 0x65, + 0x74, 0x4C, 0x6F, 0x63, 0x6B, 0x20, 0x4B, 0x66, 0x74, 0x2E, 0x31, 0x37, + 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x2E, 0x54, 0x61, 0x6E, + 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, 0x6E, 0x79, 0x6B, + 0x69, 0x61, 0x64, 0xC3, 0xB3, 0x6B, 0x20, 0x28, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x29, 0x31, 0x35, 0x30, 0x33, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x2C, 0x4E, 0x65, 0x74, 0x4C, 0x6F, 0x63, + 0x6B, 0x20, 0x41, 0x72, 0x61, 0x6E, 0x79, 0x20, 0x28, 0x43, 0x6C, 0x61, + 0x73, 0x73, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x29, 0x20, 0x46, 0xC5, 0x91, + 0x74, 0x61, 0x6E, 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, + 0x6E, 0x79 +}; + +static const unsigned char TA484_RSA_N[] = { + 0xC4, 0x24, 0x5E, 0x73, 0xBE, 0x4B, 0x6D, 0x14, 0xC3, 0xA1, 0xF4, 0xE3, + 0x97, 0x90, 0x6E, 0xD2, 0x30, 0x45, 0x1E, 0x3C, 0xEE, 0x67, 0xD9, 0x64, + 0xE0, 0x1A, 0x8A, 0x7F, 0xCA, 0x30, 0xCA, 0x83, 0xE3, 0x20, 0xC1, 0xE3, + 0xF4, 0x3A, 0xD3, 0x94, 0x5F, 0x1A, 0x7C, 0x5B, 0x6D, 0xBF, 0x30, 0x4F, + 0x84, 0x27, 0xF6, 0x9F, 0x1F, 0x49, 0xBC, 0xC6, 0x99, 0x0A, 0x90, 0xF2, + 0x0F, 0xF5, 0x7F, 0x43, 0x84, 0x37, 0x63, 0x51, 0x8B, 0x7A, 0xA5, 0x70, + 0xFC, 0x7A, 0x58, 0xCD, 0x8E, 0x9B, 0xED, 0xC3, 0x46, 0x6C, 0x84, 0x70, + 0x5D, 0xDA, 0xF3, 0x01, 0x90, 0x23, 0xFC, 0x4E, 0x30, 0xA9, 0x7E, 0xE1, + 0x27, 0x63, 0xE7, 0xED, 0x64, 0x3C, 0xA0, 0xB8, 0xC9, 0x33, 0x63, 0xFE, + 0x16, 0x90, 0xFF, 0xB0, 0xB8, 0xFD, 0xD7, 0xA8, 0xC0, 0xC0, 0x94, 0x43, + 0x0B, 0xB6, 0xD5, 0x59, 0xA6, 0x9E, 0x56, 0xD0, 0x24, 0x1F, 0x70, 0x79, + 0xAF, 0xDB, 0x39, 0x54, 0x0D, 0x65, 0x75, 0xD9, 0x15, 0x41, 0x94, 0x01, + 0xAF, 0x5E, 0xEC, 0xF6, 0x8D, 0xF1, 0xFF, 0xAD, 0x64, 0xFE, 0x20, 0x9A, + 0xD7, 0x5C, 0xEB, 0xFE, 0xA6, 0x1F, 0x08, 0x64, 0xA3, 0x8B, 0x76, 0x55, + 0xAD, 0x1E, 0x3B, 0x28, 0x60, 0x2E, 0x87, 0x25, 0xE8, 0xAA, 0xAF, 0x1F, + 0xC6, 0x64, 0x46, 0x20, 0xB7, 0x70, 0x7F, 0x3C, 0xDE, 0x48, 0xDB, 0x96, + 0x53, 0xB7, 0x39, 0x77, 0xE4, 0x1A, 0xE2, 0xC7, 0x16, 0x84, 0x76, 0x97, + 0x5B, 0x2F, 0xBB, 0x19, 0x15, 0x85, 0xF8, 0x69, 0x85, 0xF5, 0x99, 0xA7, + 0xA9, 0xF2, 0x34, 0xA7, 0xA9, 0xB6, 0xA6, 0x03, 0xFC, 0x6F, 0x86, 0x3D, + 0x54, 0x7C, 0x76, 0x04, 0x9B, 0x6B, 0xF9, 0x40, 0x5D, 0x00, 0x34, 0xC7, + 0x2E, 0x99, 0x75, 0x9D, 0xE5, 0x88, 0x03, 0xAA, 0x4D, 0xF8, 0x03, 0xD2, + 0x42, 0x76, 0xC0, 0x1B +}; + +static const unsigned char TA484_RSA_E[] = { + 0xA8, 0x8B +}; + +static const unsigned char TA485_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x42, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA485_RSA_N[] = { + 0xD8, 0x17, 0xB7, 0x1C, 0x4A, 0x24, 0x2A, 0xD6, 0x97, 0xB1, 0xCA, 0xE2, + 0x1E, 0xFB, 0x7D, 0x38, 0xEF, 0x98, 0xF5, 0xB2, 0x39, 0x98, 0x4E, 0x27, + 0xB8, 0x11, 0x5D, 0x7B, 0xD2, 0x25, 0x94, 0x88, 0x82, 0x15, 0x26, 0x6A, + 0x1B, 0x31, 0xBB, 0xA8, 0x5B, 0x21, 0x21, 0x2B, 0xD8, 0x0F, 0x4E, 0x9F, + 0x5A, 0xF1, 0xB1, 0x5A, 0xE4, 0x79, 0xD6, 0x32, 0x23, 0x2B, 0xE1, 0x53, + 0xCC, 0x99, 0x45, 0x5C, 0x7B, 0x4F, 0xAD, 0xBC, 0xBF, 0x87, 0x4A, 0x0B, + 0x4B, 0x97, 0x5A, 0xA8, 0xF6, 0x48, 0xEC, 0x7D, 0x7B, 0x0D, 0xCD, 0x21, + 0x06, 0xDF, 0x9E, 0x15, 0xFD, 0x41, 0x8A, 0x48, 0xB7, 0x20, 0xF4, 0xA1, + 0x7A, 0x1B, 0x57, 0xD4, 0x5D, 0x50, 0xFF, 0xBA, 0x67, 0xD8, 0x23, 0x99, + 0x1F, 0xC8, 0x3F, 0xE3, 0xDE, 0xFF, 0x6F, 0x5B, 0x77, 0xB1, 0x6B, 0x6E, + 0xB8, 0xC9, 0x64, 0xF7, 0xE1, 0xCA, 0x41, 0x46, 0x0E, 0x29, 0x71, 0xD0, + 0xB9, 0x23, 0xFC, 0xC9, 0x81, 0x5F, 0x4E, 0xF7, 0x6F, 0xDF, 0xBF, 0x84, + 0xAD, 0x73, 0x64, 0xBB, 0xB7, 0x42, 0x8E, 0x69, 0xF6, 0xD4, 0x76, 0x1D, + 0x7E, 0x9D, 0xA7, 0xB8, 0x57, 0x8A, 0x51, 0x67, 0x72, 0xD7, 0xD4, 0xA8, + 0xB8, 0x95, 0x54, 0x40, 0x73, 0x03, 0xF6, 0xEA, 0xF4, 0xEB, 0xFE, 0x28, + 0x42, 0x77, 0x3F, 0x9D, 0x23, 0x1B, 0xB2, 0xB6, 0x3D, 0x80, 0x14, 0x07, + 0x4C, 0x2E, 0x4F, 0xF7, 0xD5, 0x0A, 0x16, 0x0D, 0xBD, 0x66, 0x43, 0x37, + 0x7E, 0x23, 0x43, 0x79, 0xC3, 0x40, 0x86, 0xF5, 0x4C, 0x29, 0xDA, 0x8E, + 0x9A, 0xAD, 0x0D, 0xA5, 0x04, 0x87, 0x88, 0x1E, 0x85, 0xE3, 0xE9, 0x53, + 0xD5, 0x9B, 0xC8, 0x8B, 0x03, 0x63, 0x78, 0xEB, 0xE0, 0x19, 0x4A, 0x6E, + 0xBB, 0x2F, 0x6B, 0x33, 0x64, 0x58, 0x93, 0xAD, 0x69, 0xBF, 0x8F, 0x1B, + 0xEF, 0x82, 0x48, 0xC7 +}; + +static const unsigned char TA485_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA486_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x43, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA486_EC_Q[] = { + 0x04, 0x4C, 0xE9, 0x50, 0xC0, 0xC6, 0x0F, 0x72, 0x18, 0xBC, 0xD8, 0xF1, + 0xBA, 0xB3, 0x89, 0xE2, 0x79, 0x4A, 0xA3, 0x16, 0xA7, 0x6B, 0x54, 0x24, + 0xDB, 0x51, 0xFF, 0xEA, 0xF4, 0x09, 0x24, 0xC3, 0x0B, 0x22, 0x9F, 0xCB, + 0x6A, 0x27, 0x82, 0x81, 0x0D, 0xD2, 0xC0, 0xAF, 0x31, 0xE4, 0x74, 0x82, + 0x6E, 0xCA, 0x25, 0xD9, 0x8C, 0x75, 0x9D, 0xF1, 0xDB, 0xD0, 0x9A, 0xA2, + 0x4B, 0x21, 0x7E, 0x16, 0xA7, 0x63, 0x90, 0xD2, 0x39, 0xD4, 0xB1, 0x87, + 0x78, 0x5F, 0x18, 0x96, 0x0F, 0x50, 0x1B, 0x35, 0x37, 0x0F, 0x6A, 0xC6, + 0xDC, 0xD9, 0x13, 0x4D, 0xA4, 0x8E, 0x90, 0x37, 0xE6, 0xBD, 0x5B, 0x31, + 0x91 +}; + +static const unsigned char TA487_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA487_RSA_N[] = { + 0xA0, 0xBE, 0x50, 0x10, 0x8E, 0xE9, 0xF2, 0x6C, 0x40, 0xB4, 0x04, 0x9C, + 0x85, 0xB9, 0x31, 0xCA, 0xDC, 0x2D, 0xE4, 0x11, 0xA9, 0x04, 0x3C, 0x1B, + 0x55, 0xC1, 0xE7, 0x58, 0x30, 0x1D, 0x24, 0xB4, 0xC3, 0xEF, 0x85, 0xDE, + 0x8C, 0x2C, 0xE1, 0xC1, 0x3D, 0xDF, 0x82, 0xE6, 0x4F, 0xAD, 0x47, 0x87, + 0x6C, 0xEC, 0x5B, 0x49, 0xC1, 0x4A, 0xD5, 0xBB, 0x8F, 0xEC, 0x87, 0xAC, + 0x7F, 0x82, 0x9A, 0x86, 0xEC, 0x3D, 0x03, 0x99, 0x52, 0x01, 0xD2, 0x35, + 0x9E, 0xAC, 0xDA, 0xF0, 0x53, 0xC9, 0x66, 0x3C, 0xD4, 0xAC, 0x02, 0x01, + 0xDA, 0x24, 0xD3, 0x3B, 0xA8, 0x02, 0x46, 0xAF, 0xA4, 0x1C, 0xE3, 0xF8, + 0x73, 0x58, 0x76, 0xB7, 0xF6, 0x0E, 0x90, 0x0D, 0xB5, 0xF0, 0xCF, 0xCC, + 0xFA, 0xF9, 0xC6, 0x4C, 0xE5, 0xC3, 0x86, 0x30, 0x0A, 0x8D, 0x17, 0x7E, + 0x35, 0xEB, 0xC5, 0xDF, 0xBB, 0x0E, 0x9C, 0xC0, 0x8D, 0x87, 0xE3, 0x88, + 0x38, 0x85, 0x67, 0xFA, 0x3E, 0xC7, 0xAB, 0xE0, 0x13, 0x9C, 0x05, 0x18, + 0x98, 0xCF, 0x93, 0xF5, 0xB1, 0x92, 0xB4, 0xFC, 0x23, 0xD3, 0xCF, 0xD5, + 0xC4, 0x27, 0x49, 0xE0, 0x9E, 0x3C, 0x9B, 0x08, 0xA3, 0x8B, 0x5D, 0x2A, + 0x21, 0xE0, 0xFC, 0x39, 0xAA, 0x53, 0xDA, 0x7D, 0x7E, 0xCF, 0x1A, 0x09, + 0x53, 0xBC, 0x5D, 0x05, 0x04, 0xCF, 0xA1, 0x4A, 0x8F, 0x8B, 0x76, 0x82, + 0x0D, 0xA1, 0xF8, 0xD2, 0xC7, 0x14, 0x77, 0x5B, 0x90, 0x36, 0x07, 0x81, + 0x9B, 0x3E, 0x06, 0xFA, 0x52, 0x5E, 0x63, 0xC5, 0xA6, 0x00, 0xFE, 0xA5, + 0xE9, 0x52, 0x1B, 0x52, 0xB5, 0x92, 0x39, 0x72, 0x03, 0x09, 0x62, 0xBD, + 0xB0, 0x60, 0x16, 0x6E, 0xA6, 0xDD, 0x25, 0xC2, 0x03, 0x66, 0xDD, 0xF3, + 0x04, 0xD1, 0x40, 0xE2, 0x4E, 0x8B, 0x86, 0xF4, 0x6F, 0xE5, 0x83, 0xA0, + 0x27, 0x84, 0x5E, 0x04, 0xC1, 0xF5, 0x90, 0xBD, 0x30, 0x3D, 0xC4, 0xEF, + 0xA8, 0x69, 0xBC, 0x38, 0x9B, 0xA4, 0xA4, 0x96, 0xD1, 0x62, 0xDA, 0x69, + 0xC0, 0x01, 0x96, 0xAE, 0xCB, 0xC4, 0x51, 0x34, 0xEA, 0x0C, 0xAA, 0xFF, + 0x21, 0x8E, 0x59, 0x8F, 0x4A, 0x5C, 0xE4, 0x61, 0x9A, 0xA7, 0xD2, 0xE9, + 0x2A, 0x78, 0x8D, 0x51, 0x3D, 0x3A, 0x15, 0xEE, 0xA2, 0x59, 0x8E, 0xA9, + 0x5C, 0xDE, 0xC5, 0xF9, 0x90, 0x22, 0xE5, 0x88, 0x45, 0x71, 0xDD, 0x91, + 0x99, 0x6C, 0x7A, 0x9F, 0x3D, 0x3D, 0x98, 0x7C, 0x5E, 0xF6, 0xBE, 0x16, + 0x68, 0xA0, 0x5E, 0xAE, 0x0B, 0x23, 0xFC, 0x5A, 0x0F, 0xAA, 0x22, 0x76, + 0x2D, 0xC9, 0xA1, 0x10, 0x1D, 0xE4, 0xD3, 0x44, 0x23, 0x90, 0x88, 0x9F, + 0xC6, 0x2A, 0xE6, 0xD7, 0xF5, 0x9A, 0xB3, 0x58, 0x1E, 0x2F, 0x30, 0x89, + 0x08, 0x1B, 0x54, 0xA2, 0xB5, 0x98, 0x23, 0xEC, 0x08, 0x77, 0x1C, 0x95, + 0x5D, 0x61, 0xD1, 0xCB, 0x89, 0x9C, 0x5F, 0xA2, 0x4A, 0x91, 0x9A, 0xEF, + 0x21, 0xAA, 0x49, 0x16, 0x08, 0xA8, 0xBD, 0x61, 0x28, 0x31, 0xC9, 0x74, + 0xAD, 0x85, 0xF6, 0xD9, 0xC5, 0xB1, 0x8B, 0xD1, 0xE5, 0x10, 0x32, 0x4D, + 0x5F, 0x8B, 0x20, 0x3A, 0x3C, 0x49, 0x1F, 0x33, 0x85, 0x59, 0x0D, 0xDB, + 0xCB, 0x09, 0x75, 0x43, 0x69, 0x73, 0xFB, 0x6B, 0x71, 0x7D, 0xF0, 0xDF, + 0xC4, 0x4C, 0x7D, 0xC6, 0xA3, 0x2E, 0xC8, 0x95, 0x79, 0xCB, 0x73, 0xA2, + 0x8E, 0x4E, 0x4D, 0x24, 0xFB, 0x5E, 0xE4, 0x04, 0xBE, 0x72, 0x1B, 0xA6, + 0x27, 0x2D, 0x49, 0x5A, 0x99, 0x7A, 0xD7, 0x5C, 0x09, 0x20, 0xB7, 0x7F, + 0x94, 0xB9, 0x4F, 0xF1, 0x0D, 0x1C, 0x5E, 0x88, 0x42, 0x1B, 0x11, 0xB7, + 0xE7, 0x91, 0xDB, 0x9E, 0x6C, 0xF4, 0x6A, 0xDF, 0x8C, 0x06, 0x98, 0x03, + 0xAD, 0xCC, 0x28, 0xEF, 0xA5, 0x47, 0xF3, 0x53 +}; + +static const unsigned char TA487_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA488_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA488_RSA_N[] = { + 0x9A, 0x18, 0xCA, 0x4B, 0x94, 0x0D, 0x00, 0x2D, 0xAF, 0x03, 0x29, 0x8A, + 0xF0, 0x0F, 0x81, 0xC8, 0xAE, 0x4C, 0x19, 0x85, 0x1D, 0x08, 0x9F, 0xAB, + 0x29, 0x44, 0x85, 0xF3, 0x2F, 0x81, 0xAD, 0x32, 0x1E, 0x90, 0x46, 0xBF, + 0xA3, 0x86, 0x26, 0x1A, 0x1E, 0xFE, 0x7E, 0x1C, 0x18, 0x3A, 0x5C, 0x9C, + 0x60, 0x17, 0x2A, 0x3A, 0x74, 0x83, 0x33, 0x30, 0x7D, 0x61, 0x54, 0x11, + 0xCB, 0xED, 0xAB, 0xE0, 0xE6, 0xD2, 0xA2, 0x7E, 0xF5, 0x6B, 0x6F, 0x18, + 0xB7, 0x0A, 0x0B, 0x2D, 0xFD, 0xE9, 0x3E, 0xEF, 0x0A, 0xC6, 0xB3, 0x10, + 0xE9, 0xDC, 0xC2, 0x46, 0x17, 0xF8, 0x5D, 0xFD, 0xA4, 0xDA, 0xFF, 0x9E, + 0x49, 0x5A, 0x9C, 0xE6, 0x33, 0xE6, 0x24, 0x96, 0xF7, 0x3F, 0xBA, 0x5B, + 0x2B, 0x1C, 0x7A, 0x35, 0xC2, 0xD6, 0x67, 0xFE, 0xAB, 0x66, 0x50, 0x8B, + 0x6D, 0x28, 0x60, 0x2B, 0xEF, 0xD7, 0x60, 0xC3, 0xC7, 0x93, 0xBC, 0x8D, + 0x36, 0x91, 0xF3, 0x7F, 0xF8, 0xDB, 0x11, 0x13, 0xC4, 0x9C, 0x77, 0x76, + 0xC1, 0xAE, 0xB7, 0x02, 0x6A, 0x81, 0x7A, 0xA9, 0x45, 0x83, 0xE2, 0x05, + 0xE6, 0xB9, 0x56, 0xC1, 0x94, 0x37, 0x8F, 0x48, 0x71, 0x63, 0x22, 0xEC, + 0x17, 0x65, 0x07, 0x95, 0x8A, 0x4B, 0xDF, 0x8F, 0xC6, 0x5A, 0x0A, 0xE5, + 0xB0, 0xE3, 0x5F, 0x5E, 0x6B, 0x11, 0xAB, 0x0C, 0xF9, 0x85, 0xEB, 0x44, + 0xE9, 0xF8, 0x04, 0x73, 0xF2, 0xE9, 0xFE, 0x5C, 0x98, 0x8C, 0xF5, 0x73, + 0xAF, 0x6B, 0xB4, 0x7E, 0xCD, 0xD4, 0x5C, 0x02, 0x2B, 0x4C, 0x39, 0xE1, + 0xB2, 0x95, 0x95, 0x2D, 0x42, 0x87, 0xD7, 0xD5, 0xB3, 0x90, 0x43, 0xB7, + 0x6C, 0x13, 0xF1, 0xDE, 0xDD, 0xF6, 0xC4, 0xF8, 0x89, 0x3F, 0xD1, 0x75, + 0xF5, 0x92, 0xC3, 0x91, 0xD5, 0x8A, 0x88, 0xD0, 0x90, 0xEC, 0xDC, 0x6D, + 0xDE, 0x89, 0xC2, 0x65, 0x71, 0x96, 0x8B, 0x0D, 0x03, 0xFD, 0x9C, 0xBF, + 0x5B, 0x16, 0xAC, 0x92, 0xDB, 0xEA, 0xFE, 0x79, 0x7C, 0xAD, 0xEB, 0xAF, + 0xF7, 0x16, 0xCB, 0xDB, 0xCD, 0x25, 0x2B, 0xE5, 0x1F, 0xFB, 0x9A, 0x9F, + 0xE2, 0x51, 0xCC, 0x3A, 0x53, 0x0C, 0x48, 0xE6, 0x0E, 0xBD, 0xC9, 0xB4, + 0x76, 0x06, 0x52, 0xE6, 0x11, 0x13, 0x85, 0x72, 0x63, 0x03, 0x04, 0xE0, + 0x04, 0x36, 0x2B, 0x20, 0x19, 0x02, 0xE8, 0x74, 0xA7, 0x1F, 0xB6, 0xC9, + 0x56, 0x66, 0xF0, 0x75, 0x25, 0xDC, 0x67, 0xC1, 0x0E, 0x61, 0x60, 0x88, + 0xB3, 0x3E, 0xD1, 0xA8, 0xFC, 0xA3, 0xDA, 0x1D, 0xB0, 0xD1, 0xB1, 0x23, + 0x54, 0xDF, 0x44, 0x76, 0x6D, 0xED, 0x41, 0xD8, 0xC1, 0xB2, 0x22, 0xB6, + 0x53, 0x1C, 0xDF, 0x35, 0x1D, 0xDC, 0xA1, 0x77, 0x2A, 0x31, 0xE4, 0x2D, + 0xF5, 0xE5, 0xE5, 0xDB, 0xC8, 0xE0, 0xFF, 0xE5, 0x80, 0xD7, 0x0B, 0x63, + 0xA0, 0xFF, 0x33, 0xA1, 0x0F, 0xBA, 0x2C, 0x15, 0x15, 0xEA, 0x97, 0xB3, + 0xD2, 0xA2, 0xB5, 0xBE, 0xF2, 0x8C, 0x96, 0x1E, 0x1A, 0x8F, 0x1D, 0x6C, + 0xA4, 0x61, 0x37, 0xB9, 0x86, 0x73, 0x33, 0xD7, 0x97, 0x96, 0x9E, 0x23, + 0x7D, 0x82, 0xA4, 0x4C, 0x81, 0xE2, 0xA1, 0xD1, 0xBA, 0x67, 0x5F, 0x95, + 0x07, 0xA3, 0x27, 0x11, 0xEE, 0x16, 0x10, 0x7B, 0xBC, 0x45, 0x4A, 0x4C, + 0xB2, 0x04, 0xD2, 0xAB, 0xEF, 0xD5, 0xFD, 0x0C, 0x51, 0xCE, 0x50, 0x6A, + 0x08, 0x31, 0xF9, 0x91, 0xDA, 0x0C, 0x8F, 0x64, 0x5C, 0x03, 0xC3, 0x3A, + 0x8B, 0x20, 0x3F, 0x6E, 0x8D, 0x67, 0x3D, 0x3A, 0xD6, 0xFE, 0x7D, 0x5B, + 0x88, 0xC9, 0x5E, 0xFB, 0xCC, 0x61, 0xDC, 0x8B, 0x33, 0x77, 0xD3, 0x44, + 0x32, 0x35, 0x09, 0x62, 0x04, 0x92, 0x16, 0x10, 0xD8, 0x9E, 0x27, 0x47, + 0xFB, 0x3B, 0x21, 0xE3, 0xF8, 0xEB, 0x1D, 0x5B +}; + +static const unsigned char TA488_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA489_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA489_RSA_N[] = { + 0xA1, 0xAE, 0x25, 0xB2, 0x01, 0x18, 0xDC, 0x57, 0x88, 0x3F, 0x46, 0xEB, + 0xF9, 0xAF, 0xE2, 0xEB, 0x23, 0x71, 0xE2, 0x9A, 0xD1, 0x61, 0x66, 0x21, + 0x5F, 0xAA, 0xAF, 0x27, 0x51, 0xE5, 0x6E, 0x1B, 0x16, 0xD4, 0x2D, 0x7D, + 0x50, 0xB0, 0x53, 0x77, 0xBD, 0x78, 0x3A, 0x60, 0xE2, 0x64, 0x02, 0x9B, + 0x7C, 0x86, 0x9B, 0xD6, 0x1A, 0x8E, 0xAD, 0xFF, 0x1F, 0x15, 0x7F, 0xD5, + 0x95, 0x1E, 0x12, 0xCB, 0xE6, 0x14, 0x84, 0x04, 0xC1, 0xDF, 0x36, 0xB3, + 0x16, 0x9F, 0x8A, 0xE3, 0xC9, 0xDB, 0x98, 0x34, 0xCE, 0xD8, 0x33, 0x17, + 0x28, 0x46, 0xFC, 0xA7, 0xC9, 0xF0, 0xD2, 0xB4, 0xD5, 0x4D, 0x09, 0x72, + 0x49, 0xF9, 0xF2, 0x87, 0xE3, 0xA9, 0xDA, 0x7D, 0xA1, 0x7D, 0x6B, 0xB2, + 0x3A, 0x25, 0xA9, 0x6D, 0x52, 0x44, 0xAC, 0xF8, 0xBE, 0x6E, 0xFB, 0xDC, + 0xA6, 0x73, 0x91, 0x90, 0x61, 0xA6, 0x03, 0x14, 0x20, 0xF2, 0xE7, 0x87, + 0xA3, 0x88, 0xAD, 0xAD, 0xA0, 0x8C, 0xFF, 0xA6, 0x0B, 0x25, 0x52, 0x25, + 0xE7, 0x16, 0x01, 0xD5, 0xCB, 0xB8, 0x35, 0x81, 0x0C, 0xA3, 0x3B, 0xF0, + 0xE1, 0xE1, 0xFC, 0x5A, 0x5D, 0xCE, 0x80, 0x71, 0x6D, 0xF8, 0x49, 0xAB, + 0x3E, 0x3B, 0xBA, 0xB8, 0xD7, 0x80, 0x01, 0xFB, 0xA5, 0xEB, 0x5B, 0xB3, + 0xC5, 0x5E, 0x60, 0x2A, 0x31, 0xA0, 0xAF, 0x37, 0xE8, 0x20, 0x3A, 0x9F, + 0xA8, 0x32, 0x2C, 0x0C, 0xCC, 0x09, 0x1D, 0xD3, 0x9E, 0x8E, 0x5D, 0xBC, + 0x4C, 0x98, 0xEE, 0xC5, 0x1A, 0x68, 0x7B, 0xEC, 0x53, 0xA6, 0xE9, 0x14, + 0x35, 0xA3, 0xDF, 0xCD, 0x80, 0x9F, 0x0C, 0x48, 0xFB, 0x1C, 0xF4, 0xF1, + 0xBF, 0x4A, 0xB8, 0xFA, 0xD5, 0x8C, 0x71, 0x4A, 0xC7, 0x1F, 0xAD, 0xFE, + 0x41, 0x9A, 0xB3, 0x83, 0x5D, 0xF2, 0x84, 0x56, 0xEF, 0xA5, 0x57, 0x43, + 0xCE, 0x29, 0xAD, 0x8C, 0xAB, 0x55, 0xBF, 0xC4, 0xFB, 0x5B, 0x01, 0xDD, + 0x23, 0x21, 0xA1, 0x58, 0x00, 0x8E, 0xC3, 0xD0, 0x6A, 0x13, 0xED, 0x13, + 0xE3, 0x12, 0x2B, 0x80, 0xDC, 0x67, 0xE6, 0x95, 0xB2, 0xCD, 0x1E, 0x22, + 0x6E, 0x2A, 0xF8, 0x41, 0xD4, 0xF2, 0xCA, 0x14, 0x07, 0x8D, 0x8A, 0x55, + 0x12, 0xC6, 0x69, 0xF5, 0xB8, 0x86, 0x68, 0x2F, 0x53, 0x5E, 0xB0, 0xD2, + 0xAA, 0x21, 0xC1, 0x98, 0xE6, 0x30, 0xE3, 0x67, 0x55, 0xC7, 0x9B, 0x6E, + 0xAC, 0x19, 0xA8, 0x55, 0xA6, 0x45, 0x06, 0xD0, 0x23, 0x3A, 0xDB, 0xEB, + 0x65, 0x5D, 0x2A, 0x11, 0x11, 0xF0, 0x3B, 0x4F, 0xCA, 0x6D, 0xF4, 0x34, + 0xC4, 0x71, 0xE4, 0xFF, 0x00, 0x5A, 0xF6, 0x5C, 0xAE, 0x23, 0x60, 0x85, + 0x73, 0xF1, 0xE4, 0x10, 0xB1, 0x25, 0xAE, 0xD5, 0x92, 0xBB, 0x13, 0xC1, + 0x0C, 0xE0, 0x39, 0xDA, 0xB4, 0x39, 0x57, 0xB5, 0xAB, 0x35, 0xAA, 0x72, + 0x21, 0x3B, 0x83, 0x35, 0xE7, 0x31, 0xDF, 0x7A, 0x21, 0x6E, 0xB8, 0x32, + 0x08, 0x7D, 0x1D, 0x32, 0x91, 0x15, 0x4A, 0x62, 0x72, 0xCF, 0xE3, 0x77, + 0xA1, 0xBC, 0xD5, 0x11, 0x1B, 0x76, 0x01, 0x67, 0x08, 0xE0, 0x41, 0x0B, + 0xC3, 0xEB, 0x15, 0x6E, 0xF8, 0xA4, 0x19, 0xD9, 0xA2, 0xAB, 0xAF, 0xE2, + 0x27, 0x52, 0x56, 0x2B, 0x02, 0x8A, 0x2C, 0x14, 0x24, 0xF9, 0xBF, 0x42, + 0x02, 0xBF, 0x26, 0xC8, 0xC6, 0x8F, 0xE0, 0x6E, 0x38, 0x7D, 0x53, 0x2D, + 0xE5, 0xED, 0x98, 0xB3, 0x95, 0x63, 0x68, 0x7F, 0xF9, 0x35, 0xF4, 0xDF, + 0x88, 0xC5, 0x60, 0x35, 0x92, 0xC0, 0x7C, 0x69, 0x1C, 0x61, 0x95, 0x16, + 0xD0, 0xEB, 0xDE, 0x0B, 0xAF, 0x3E, 0x04, 0x10, 0x45, 0x65, 0x58, 0x50, + 0x38, 0xAF, 0x48, 0xF2, 0x59, 0xB6, 0x16, 0xF2, 0x3C, 0x0D, 0x90, 0x02, + 0xC6, 0x70, 0x2E, 0x01, 0xAD, 0x3C, 0x15, 0xD7 +}; + +static const unsigned char TA489_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA490_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA490_RSA_N[] = { + 0xCC, 0x57, 0x42, 0x16, 0x54, 0x9C, 0xE6, 0x98, 0xD3, 0xD3, 0x4D, 0xEE, + 0xFE, 0xED, 0xC7, 0x9F, 0x43, 0x39, 0x4A, 0x65, 0xB3, 0xE8, 0x16, 0x88, + 0x34, 0xDB, 0x0D, 0x59, 0x91, 0x74, 0xCF, 0x92, 0xB8, 0x04, 0x40, 0xAD, + 0x02, 0x4B, 0x31, 0xAB, 0xBC, 0x8D, 0x91, 0x68, 0xD8, 0x20, 0x0E, 0x1A, + 0x01, 0xE2, 0x1A, 0x7B, 0x4E, 0x17, 0x5D, 0xE2, 0x8A, 0xB7, 0x3F, 0x99, + 0x1A, 0xCD, 0xEB, 0x61, 0xAB, 0xC2, 0x65, 0xA6, 0x1F, 0xB7, 0xB7, 0xBD, + 0xB7, 0x8F, 0xFC, 0xFD, 0x70, 0x8F, 0x0B, 0xA0, 0x67, 0xBE, 0x01, 0xA2, + 0x59, 0xCF, 0x71, 0xE6, 0x0F, 0x29, 0x76, 0xFF, 0xB1, 0x56, 0x79, 0x45, + 0x2B, 0x1F, 0x9E, 0x7A, 0x54, 0xE8, 0xA3, 0x29, 0x35, 0x68, 0xA4, 0x01, + 0x4F, 0x0F, 0xA4, 0x2E, 0x37, 0xEF, 0x1B, 0xBF, 0xE3, 0x8F, 0x10, 0xA8, + 0x72, 0xAB, 0x58, 0x57, 0xE7, 0x54, 0x86, 0xC8, 0xC9, 0xF3, 0x5B, 0xDA, + 0x2C, 0xDA, 0x5D, 0x8E, 0x6E, 0x3C, 0xA3, 0x3E, 0xDA, 0xFB, 0x82, 0xE5, + 0xDD, 0xF2, 0x5C, 0xB2, 0x05, 0x33, 0x6F, 0x8A, 0x36, 0xCE, 0xD0, 0x13, + 0x4E, 0xFF, 0xBF, 0x4A, 0x0C, 0x34, 0x4C, 0xA6, 0xC3, 0x21, 0xBD, 0x50, + 0x04, 0x55, 0xEB, 0xB1, 0xBB, 0x9D, 0xFB, 0x45, 0x1E, 0x64, 0x15, 0xDE, + 0x55, 0x01, 0x8C, 0x02, 0x76, 0xB5, 0xCB, 0xA1, 0x3F, 0x42, 0x69, 0xBC, + 0x2F, 0xBD, 0x68, 0x43, 0x16, 0x56, 0x89, 0x2A, 0x37, 0x61, 0x91, 0xFD, + 0xA6, 0xAE, 0x4E, 0xC0, 0xCB, 0x14, 0x65, 0x94, 0x37, 0x4B, 0x92, 0x06, + 0xEF, 0x04, 0xD0, 0xC8, 0x9C, 0x88, 0xDB, 0x0B, 0x7B, 0x81, 0xAF, 0xB1, + 0x3D, 0x2A, 0xC4, 0x65, 0x3A, 0x78, 0xB6, 0xEE, 0xDC, 0x80, 0xB1, 0xD2, + 0xD3, 0x99, 0x9C, 0x3A, 0xEE, 0x6B, 0x5A, 0x6B, 0xB3, 0x8D, 0xB7, 0xD5, + 0xCE, 0x9C, 0xC2, 0xBE, 0xA5, 0x4B, 0x2F, 0x16, 0xB1, 0x9E, 0x68, 0x3B, + 0x06, 0x6F, 0xAE, 0x7D, 0x9F, 0xF8, 0xDE, 0xEC, 0xCC, 0x29, 0xA7, 0x98, + 0xA3, 0x25, 0x43, 0x2F, 0xEF, 0xF1, 0x5F, 0x26, 0xE1, 0x88, 0x4D, 0xF8, + 0x5E, 0x6E, 0xD7, 0xD9, 0x14, 0x6E, 0x19, 0x33, 0x69, 0xA7, 0x3B, 0x84, + 0x89, 0x93, 0xC4, 0x53, 0x55, 0x13, 0xA1, 0x51, 0x78, 0x40, 0xF8, 0xB8, + 0xC9, 0xA2, 0xEE, 0x7B, 0xBA, 0x52, 0x42, 0x83, 0x9E, 0x14, 0xED, 0x05, + 0x52, 0x5A, 0x59, 0x56, 0xA7, 0x97, 0xFC, 0x9D, 0x3F, 0x0A, 0x29, 0xD8, + 0xDC, 0x4F, 0x91, 0x0E, 0x13, 0xBC, 0xDE, 0x95, 0xA4, 0xDF, 0x8B, 0x99, + 0xBE, 0xAC, 0x9B, 0x33, 0x88, 0xEF, 0xB5, 0x81, 0xAF, 0x1B, 0xC6, 0x22, + 0x53, 0xC8, 0xF6, 0xC7, 0xEE, 0x97, 0x14, 0xB0, 0xC5, 0x7C, 0x78, 0x52, + 0xC8, 0xF0, 0xCE, 0x6E, 0x77, 0x60, 0x84, 0xA6, 0xE9, 0x2A, 0x76, 0x20, + 0xED, 0x58, 0x01, 0x17, 0x30, 0x93, 0xE9, 0x1A, 0x8B, 0xE0, 0x73, 0x63, + 0xD9, 0x6A, 0x92, 0x94, 0x49, 0x4E, 0xB4, 0xAD, 0x4A, 0x85, 0xC4, 0xA3, + 0x22, 0x30, 0xFC, 0x09, 0xED, 0x68, 0x22, 0x73, 0xA6, 0x88, 0x0C, 0x55, + 0x21, 0x58, 0xC5, 0xE1, 0x3A, 0x9F, 0x2A, 0xDD, 0xCA, 0xE1, 0x90, 0xE0, + 0xD9, 0x73, 0xAB, 0x6C, 0x80, 0xB8, 0xE8, 0x0B, 0x64, 0x93, 0xA0, 0x9C, + 0x8C, 0x19, 0xFF, 0xB3, 0xD2, 0x0C, 0xEC, 0x91, 0x26, 0x87, 0x8A, 0xB3, + 0xA2, 0xE1, 0x70, 0x8F, 0x2C, 0x0A, 0xE5, 0xCD, 0x6D, 0x68, 0x51, 0xEB, + 0xDA, 0x3F, 0x05, 0x7F, 0x8B, 0x32, 0xE6, 0x13, 0x5C, 0x6B, 0xFE, 0x5F, + 0x40, 0xE2, 0x22, 0xC8, 0xB4, 0xB4, 0x64, 0x4F, 0xD6, 0xBA, 0x7D, 0x48, + 0x3E, 0xA8, 0x69, 0x0C, 0xD7, 0xBB, 0x86, 0x71, 0xC9, 0x73, 0xB8, 0x3F, + 0x3B, 0x9D, 0x25, 0x4B, 0xDA, 0xFF, 0x40, 0xEB +}; + +static const unsigned char TA490_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA491_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA491_RSA_N[] = { + 0xB3, 0xCB, 0x0E, 0x10, 0x67, 0x8E, 0xEA, 0x14, 0x97, 0xA7, 0x32, 0x2A, + 0x0A, 0x56, 0x36, 0x7F, 0x68, 0x4C, 0xC7, 0xB3, 0x6F, 0x3A, 0x23, 0x14, + 0x91, 0xFF, 0x19, 0x7F, 0xA5, 0xCA, 0xAC, 0xEE, 0xB3, 0x76, 0x9D, 0x7A, + 0xE9, 0x8B, 0x1B, 0xAB, 0x6B, 0x31, 0xDB, 0xFA, 0x0B, 0x53, 0x4C, 0xAF, + 0xC5, 0xA5, 0x1A, 0x79, 0x3C, 0x8A, 0x4C, 0xFF, 0xAC, 0xDF, 0x25, 0xDE, + 0x4E, 0xD9, 0x82, 0x32, 0x0B, 0x44, 0xDE, 0xCA, 0xDB, 0x8C, 0xAC, 0xA3, + 0x6E, 0x16, 0x83, 0x3B, 0xA6, 0x64, 0x4B, 0x32, 0x89, 0xFB, 0x16, 0x16, + 0x38, 0x7E, 0xEB, 0x43, 0xE2, 0xD3, 0x74, 0x4A, 0xC2, 0x62, 0x0A, 0x73, + 0x0A, 0xDD, 0x49, 0xB3, 0x57, 0xD2, 0xB0, 0x0A, 0x85, 0x9D, 0x71, 0x3C, + 0xDE, 0xA3, 0xCB, 0xC0, 0x32, 0xF3, 0x01, 0x39, 0x20, 0x43, 0x1B, 0x35, + 0xD1, 0x53, 0xB3, 0xB1, 0xEE, 0xC5, 0x93, 0x69, 0x82, 0x3E, 0x16, 0xB5, + 0x28, 0x46, 0xA1, 0xDE, 0xEA, 0x89, 0x09, 0xED, 0x43, 0xB8, 0x05, 0x46, + 0x8A, 0x86, 0xF5, 0x59, 0x47, 0xBE, 0x1B, 0x6F, 0x01, 0x21, 0x10, 0xB9, + 0xFD, 0xA9, 0xD2, 0x28, 0xCA, 0x10, 0x39, 0x09, 0xCA, 0x13, 0x36, 0xCF, + 0x9C, 0xAD, 0xAD, 0x40, 0x74, 0x79, 0x2B, 0x02, 0x3F, 0x34, 0xFF, 0xFA, + 0x20, 0x69, 0x7D, 0xD3, 0xEE, 0x61, 0xF5, 0xBA, 0xB3, 0xE7, 0x30, 0xD0, + 0x37, 0x23, 0x86, 0x72, 0x61, 0x45, 0x29, 0x48, 0x59, 0x68, 0x6F, 0x77, + 0xA6, 0x2E, 0x81, 0xBE, 0x07, 0x4D, 0x6F, 0xAF, 0xCE, 0xC4, 0x45, 0x13, + 0x91, 0x14, 0x70, 0x06, 0x8F, 0x1F, 0x9F, 0xF8, 0x87, 0x69, 0xB1, 0x0E, + 0xEF, 0xC3, 0x89, 0x19, 0xEB, 0xEA, 0x1C, 0x61, 0xFC, 0x7A, 0x6C, 0x8A, + 0xDC, 0xD6, 0x03, 0x0B, 0x9E, 0x26, 0xBA, 0x12, 0xDD, 0xD4, 0x54, 0x39, + 0xAB, 0x26, 0xA3, 0x33, 0xEA, 0x75, 0x81, 0xDA, 0x2D, 0xCD, 0x0F, 0x4F, + 0xE4, 0x03, 0xD1, 0xEF, 0x15, 0x97, 0x1B, 0x6B, 0x90, 0xC5, 0x02, 0x90, + 0x93, 0x66, 0x02, 0x21, 0xB1, 0x47, 0xDE, 0x8B, 0x9A, 0x4A, 0x80, 0xB9, + 0x55, 0x8F, 0xB5, 0xA2, 0x2F, 0xC0, 0xD6, 0x33, 0x67, 0xDA, 0x7E, 0xC4, + 0xA7, 0xB4, 0x04, 0x44, 0xEB, 0x47, 0xFB, 0xE6, 0x58, 0xB9, 0xF7, 0x0C, + 0xF0, 0x7B, 0x2B, 0xB1, 0xC0, 0x70, 0x29, 0xC3, 0x40, 0x62, 0x2D, 0x3B, + 0x48, 0x69, 0xDC, 0x23, 0x3C, 0x48, 0xEB, 0x7B, 0x09, 0x79, 0xA9, 0x6D, + 0xDA, 0xA8, 0x30, 0x98, 0xCF, 0x80, 0x72, 0x03, 0x88, 0xA6, 0x5B, 0x46, + 0xAE, 0x72, 0x79, 0x7C, 0x08, 0x03, 0x21, 0x65, 0xAE, 0xB7, 0xE1, 0x1C, + 0xA5, 0xB1, 0x2A, 0xA2, 0x31, 0xDE, 0x66, 0x04, 0xF7, 0xC0, 0x74, 0xE8, + 0x71, 0xDE, 0xFF, 0x3D, 0x59, 0xCC, 0x96, 0x26, 0x12, 0x8B, 0x85, 0x95, + 0x57, 0x1A, 0xAB, 0x6B, 0x75, 0x0B, 0x44, 0x3D, 0x11, 0x28, 0x3C, 0x7B, + 0x61, 0xB7, 0xE2, 0x8F, 0x67, 0x4F, 0xE5, 0xEC, 0x3C, 0x4C, 0x60, 0x80, + 0x69, 0x57, 0x38, 0x1E, 0x01, 0x5B, 0x8D, 0x55, 0xE8, 0xC7, 0xDF, 0xC0, + 0xCC, 0x77, 0x23, 0x34, 0x49, 0x75, 0x7C, 0xF6, 0x98, 0x11, 0xEB, 0x2D, + 0xDE, 0xED, 0x41, 0x2E, 0x14, 0x05, 0x02, 0x7F, 0xE0, 0xFE, 0x20, 0xEB, + 0x35, 0xE7, 0x11, 0xAC, 0x22, 0xCE, 0x57, 0x3D, 0xDE, 0xC9, 0x30, 0x6D, + 0x10, 0x03, 0x85, 0xCD, 0xF1, 0xFF, 0x8C, 0x16, 0xB5, 0xC1, 0xB2, 0x3E, + 0x88, 0x6C, 0x60, 0x7F, 0x90, 0x4F, 0x95, 0xF7, 0xF6, 0x2D, 0xAD, 0x01, + 0x39, 0x07, 0x04, 0xFA, 0x75, 0x80, 0x7D, 0xBF, 0x49, 0x50, 0xED, 0xEF, + 0xC9, 0xC4, 0x7C, 0x1C, 0xEB, 0x80, 0x7E, 0xDB, 0xB6, 0xD0, 0xDD, 0x13, + 0xFE, 0xC9, 0xD3, 0x9C, 0xD7, 0xB2, 0x97, 0xA9 +}; + +static const unsigned char TA491_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA492_DN[] = { + 0x30, 0x7F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x2B, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, 0x56, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA492_EC_Q[] = { + 0x04, 0xAA, 0x12, 0x47, 0x90, 0x98, 0x1B, 0xFB, 0xEF, 0xC3, 0x40, 0x07, + 0x83, 0x20, 0x4E, 0xF1, 0x30, 0x82, 0xA2, 0x06, 0xD1, 0xF2, 0x92, 0x86, + 0x61, 0xF2, 0xF6, 0x21, 0x68, 0xCA, 0x00, 0xC4, 0xC7, 0xEA, 0x43, 0x00, + 0x54, 0x86, 0xDC, 0xFD, 0x1F, 0xDF, 0x00, 0xB8, 0x41, 0x62, 0x5C, 0xDC, + 0x70, 0x16, 0x32, 0xDE, 0x1F, 0x99, 0xD4, 0xCC, 0xC5, 0x07, 0xC8, 0x08, + 0x1F, 0x61, 0x16, 0x07, 0x51, 0x3D, 0x7D, 0x5C, 0x07, 0x53, 0xE3, 0x35, + 0x38, 0x8C, 0xDF, 0xCD, 0x9F, 0xD9, 0x2E, 0x0D, 0x4A, 0xB6, 0x19, 0x2E, + 0x5A, 0x70, 0x5A, 0x06, 0xED, 0xBE, 0xF0, 0xA1, 0xB0, 0xCA, 0xD0, 0x09, + 0x29 +}; + +static const unsigned char TA493_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, + 0x6F, 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x2E, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, + 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA493_RSA_N[] = { + 0x8F, 0x36, 0x65, 0x40, 0xE1, 0xD6, 0x4D, 0xC0, 0xD7, 0xB4, 0xE9, 0x46, + 0xDA, 0x6B, 0xEA, 0x33, 0x47, 0xCD, 0x4C, 0xF9, 0x7D, 0x7D, 0xBE, 0xBD, + 0x2D, 0x3D, 0xF0, 0xDB, 0x78, 0xE1, 0x86, 0xA5, 0xD9, 0xBA, 0x09, 0x57, + 0x68, 0xED, 0x57, 0x3E, 0xA0, 0xD0, 0x08, 0x41, 0x83, 0xE7, 0x28, 0x41, + 0x24, 0x1F, 0xE3, 0x72, 0x15, 0xD0, 0x01, 0x1A, 0xFB, 0x5E, 0x70, 0x23, + 0xB2, 0xCB, 0x9F, 0x39, 0xE3, 0xCF, 0xC5, 0x4E, 0xC6, 0x92, 0x6D, 0x26, + 0xC6, 0x7B, 0xBB, 0xB3, 0xDA, 0x27, 0x9D, 0x0A, 0x86, 0xE9, 0x81, 0x37, + 0x05, 0xFE, 0xF0, 0x71, 0x71, 0xEC, 0xC3, 0x1C, 0xE9, 0x63, 0xA2, 0x17, + 0x14, 0x9D, 0xEF, 0x1B, 0x67, 0xD3, 0x85, 0x55, 0x02, 0x02, 0xD6, 0x49, + 0xC9, 0xCC, 0x5A, 0xE1, 0xB1, 0xF7, 0x6F, 0x32, 0x9F, 0xC9, 0xD4, 0x3B, + 0x88, 0x41, 0xA8, 0x9C, 0xBD, 0xCB, 0xAB, 0xDB, 0x6D, 0x7B, 0x09, 0x1F, + 0xA2, 0x4C, 0x72, 0x90, 0xDA, 0x2B, 0x08, 0xFC, 0xCF, 0x3C, 0x54, 0xCE, + 0x67, 0x0F, 0xA8, 0xCF, 0x5D, 0x96, 0x19, 0x0B, 0xC4, 0xE3, 0x72, 0xEB, + 0xAD, 0xD1, 0x7D, 0x1D, 0x27, 0xEF, 0x92, 0xEB, 0x10, 0xBF, 0x5B, 0xEB, + 0x3B, 0xAF, 0xCF, 0x80, 0xDD, 0xC1, 0xD2, 0x96, 0x04, 0x5B, 0x7A, 0x7E, + 0xA4, 0xA9, 0x3C, 0x38, 0x76, 0xA4, 0x62, 0x8E, 0xA0, 0x39, 0x5E, 0xEA, + 0x77, 0xCF, 0x5D, 0x00, 0x59, 0x8F, 0x66, 0x2C, 0x3E, 0x07, 0xA2, 0xA3, + 0x05, 0x26, 0x11, 0x69, 0x97, 0xEA, 0x85, 0xB7, 0x0F, 0x96, 0x0B, 0x4B, + 0xC8, 0x40, 0xE1, 0x50, 0xBA, 0x2E, 0x8A, 0xCB, 0xF7, 0x0F, 0x9A, 0x22, + 0xE7, 0x7F, 0x9A, 0x37, 0x13, 0xCD, 0xF2, 0x4D, 0x13, 0x6B, 0x21, 0xD1, + 0xC0, 0xCC, 0x22, 0xF2, 0xA1, 0x46, 0xF6, 0x44, 0x69, 0x9C, 0xCA, 0x61, + 0x35, 0x07, 0x00, 0x6F, 0xD6, 0x61, 0x08, 0x11, 0xEA, 0xBA, 0xB8, 0xF6, + 0xE9, 0xB3, 0x60, 0xE5, 0x4D, 0xB9, 0xEC, 0x9F, 0x14, 0x66, 0xC9, 0x57, + 0x58, 0xDB, 0xCD, 0x87, 0x69, 0xF8, 0x8A, 0x86, 0x12, 0x03, 0x47, 0xBF, + 0x66, 0x13, 0x76, 0xAC, 0x77, 0x7D, 0x34, 0x24, 0x85, 0x83, 0xCD, 0xD7, + 0xAA, 0x9C, 0x90, 0x1A, 0x9F, 0x21, 0x2C, 0x7F, 0x78, 0xB7, 0x64, 0xB8, + 0xD8, 0xE8, 0xA6, 0xF4, 0x78, 0xB3, 0x55, 0xCB, 0x84, 0xD2, 0x32, 0xC4, + 0x78, 0xAE, 0xA3, 0x8F, 0x61, 0xDD, 0xCE, 0x08, 0x53, 0xAD, 0xEC, 0x88, + 0xFC, 0x15, 0xE4, 0x9A, 0x0D, 0xE6, 0x9F, 0x1A, 0x77, 0xCE, 0x4C, 0x8F, + 0xB8, 0x14, 0x15, 0x3D, 0x62, 0x9C, 0x86, 0x38, 0x06, 0x00, 0x66, 0x12, + 0xE4, 0x59, 0x76, 0x5A, 0x53, 0xC0, 0x02, 0x98, 0xA2, 0x10, 0x2B, 0x68, + 0x44, 0x7B, 0x8E, 0x79, 0xCE, 0x33, 0x4A, 0x76, 0xAA, 0x5B, 0x81, 0x16, + 0x1B, 0xB5, 0x8A, 0xD8, 0xD0, 0x00, 0x7B, 0x5E, 0x62, 0xB4, 0x09, 0xD6, + 0x86, 0x63, 0x0E, 0xA6, 0x05, 0x95, 0x49, 0xBA, 0x28, 0x8B, 0x88, 0x93, + 0xB2, 0x34, 0x1C, 0xD8, 0xA4, 0x55, 0x6E, 0xB7, 0x1C, 0xD0, 0xDE, 0x99, + 0x55, 0x3B, 0x23, 0xF4, 0x22, 0xE0, 0xF9, 0x29, 0x66, 0x26, 0xEC, 0x20, + 0x50, 0x77, 0xDB, 0x4A, 0x0B, 0x8F, 0xBE, 0xE5, 0x02, 0x60, 0x70, 0x41, + 0x5E, 0xD4, 0xAE, 0x50, 0x39, 0x22, 0x14, 0x26, 0xCB, 0xB2, 0x3B, 0x73, + 0x74, 0x55, 0x47, 0x07, 0x79, 0x81, 0x39, 0xA8, 0x30, 0x13, 0x44, 0xE5, + 0x04, 0x8A, 0xAE, 0x96, 0x13, 0x25, 0x42, 0x0F, 0xB9, 0x53, 0xC4, 0x9B, + 0xFC, 0xCD, 0xE4, 0x1C, 0xDE, 0x3C, 0xFA, 0xAB, 0xD6, 0x06, 0x4A, 0x1F, + 0x67, 0xA6, 0x98, 0x30, 0x1C, 0xDD, 0x2C, 0xDB, 0xDC, 0x18, 0x95, 0x57, + 0x66, 0xC6, 0xFF, 0x5C, 0x8B, 0x56, 0xF5, 0x77 +}; + +static const unsigned char TA493_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA494_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA494_EC_Q[] = { + 0x04, 0x45, 0x6E, 0xA9, 0x50, 0xC4, 0xA6, 0x23, 0x36, 0x9E, 0x5F, 0x28, + 0x8D, 0x17, 0xCB, 0x96, 0x22, 0x64, 0x3F, 0xDC, 0x7A, 0x8E, 0x1D, 0xCC, + 0x08, 0xB3, 0xA2, 0x71, 0x24, 0xBA, 0x8E, 0x49, 0xB9, 0x04, 0x1B, 0x47, + 0x96, 0x58, 0xAB, 0x2D, 0x95, 0xC8, 0xED, 0x9E, 0x08, 0x35, 0xC8, 0x27, + 0xEB, 0x89, 0x8C, 0x53, 0x58, 0xEB, 0x62, 0x8A, 0xFE, 0xF0, 0x5B, 0x0F, + 0x6B, 0x31, 0x52, 0x63, 0x41, 0x3B, 0x89, 0xCD, 0xEC, 0xEC, 0xB6, 0x8D, + 0x19, 0xD3, 0x34, 0x07, 0xDC, 0xBB, 0xC6, 0x06, 0x7F, 0xC2, 0x45, 0x95, + 0xEC, 0xCB, 0x7F, 0xA8, 0x23, 0xE0, 0x09, 0xE9, 0x81, 0xFA, 0xF3, 0x47, + 0xD3 +}; + +static const unsigned char TA495_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x52, 0x53, 0x41 +}; + +static const unsigned char TA495_RSA_N[] = { + 0xF9, 0x0F, 0xDD, 0xA3, 0x2B, 0x7D, 0xCB, 0xD0, 0x2A, 0xFE, 0xEC, 0x67, + 0x85, 0xA6, 0xE7, 0x2E, 0x1B, 0xBA, 0x77, 0xE1, 0xE3, 0xF5, 0xAF, 0xA4, + 0xEC, 0xFA, 0x4A, 0x5D, 0x91, 0xC4, 0x57, 0x47, 0x6B, 0x18, 0x77, 0x6B, + 0x76, 0xF2, 0xFD, 0x93, 0xE4, 0x3D, 0x0F, 0xC2, 0x16, 0x9E, 0x0B, 0x66, + 0xC3, 0x56, 0x94, 0x9E, 0x17, 0x83, 0x85, 0xCE, 0x56, 0xEF, 0xF2, 0x16, + 0xFD, 0x00, 0x62, 0xF5, 0x22, 0x09, 0x54, 0xE8, 0x65, 0x17, 0x4E, 0x41, + 0xB9, 0xE0, 0x4F, 0x46, 0x97, 0xAA, 0x1B, 0xC8, 0xB8, 0x6E, 0x62, 0x5E, + 0x69, 0xB1, 0x5F, 0xDB, 0x2A, 0x02, 0x7E, 0xFC, 0x6C, 0xCA, 0xF3, 0x41, + 0xD8, 0xED, 0xD0, 0xE8, 0xFC, 0x3F, 0x61, 0x48, 0xED, 0xB0, 0x03, 0x14, + 0x1D, 0x10, 0x0E, 0x4B, 0x19, 0xE0, 0xBB, 0x4E, 0xEC, 0x86, 0x65, 0xFF, + 0x36, 0xF3, 0x5E, 0x67, 0x02, 0x0B, 0x9D, 0x86, 0x55, 0x61, 0xFD, 0x7A, + 0x38, 0xED, 0xFE, 0xE2, 0x19, 0x00, 0xB7, 0x6F, 0xA1, 0x50, 0x62, 0x75, + 0x74, 0x3C, 0xA0, 0xFA, 0xC8, 0x25, 0x92, 0xB4, 0x6E, 0x7A, 0x22, 0xC7, + 0xF8, 0x1E, 0xA1, 0xE3, 0xB2, 0xDD, 0x91, 0x31, 0xAB, 0x2B, 0x1D, 0x04, + 0xFF, 0xA5, 0x4A, 0x04, 0x37, 0xE9, 0x85, 0xA4, 0x33, 0x2B, 0xFD, 0xE2, + 0xD6, 0x55, 0x34, 0x7C, 0x19, 0xA4, 0x4A, 0x68, 0xC7, 0xB2, 0xA8, 0xD3, + 0xB7, 0xCA, 0xA1, 0x93, 0x88, 0xEB, 0xC1, 0x97, 0xBC, 0x8C, 0xF9, 0x1D, + 0xD9, 0x22, 0x84, 0x24, 0x74, 0xC7, 0x04, 0x3D, 0x6A, 0xA9, 0x29, 0x93, + 0xCC, 0xEB, 0xB8, 0x5B, 0xE1, 0xFE, 0x5F, 0x25, 0xAA, 0x34, 0x58, 0xC8, + 0xC1, 0x23, 0x54, 0x9D, 0x1B, 0x98, 0x11, 0xC3, 0x38, 0x9C, 0x7E, 0x3D, + 0x86, 0x6C, 0xA5, 0x0F, 0x40, 0x86, 0x7C, 0x02, 0xF4, 0x5C, 0x02, 0x4F, + 0x28, 0xCB, 0xAE, 0x71, 0x9F, 0x0F, 0x3A, 0xC8, 0x33, 0xFE, 0x11, 0x25, + 0x35, 0xEA, 0xFC, 0xBA, 0xC5, 0x60, 0x3D, 0xD9, 0x7C, 0x18, 0xD5, 0xB2, + 0xA9, 0xD3, 0x75, 0x78, 0x03, 0x72, 0x22, 0xCA, 0x3A, 0xC3, 0x1F, 0xEF, + 0x2C, 0xE5, 0x2E, 0xA9, 0xFA, 0x9E, 0x2C, 0xB6, 0x51, 0x46, 0xFD, 0xAF, + 0x03, 0xD6, 0xEA, 0x60, 0x68, 0xEA, 0x85, 0x16, 0x36, 0x6B, 0x85, 0xE9, + 0x1E, 0xC0, 0xB3, 0xDD, 0xC4, 0x24, 0xDC, 0x80, 0x2A, 0x81, 0x41, 0x6D, + 0x94, 0x3E, 0xC8, 0xE0, 0xC9, 0x81, 0x41, 0x00, 0x9E, 0x5E, 0xBF, 0x7F, + 0xC5, 0x08, 0x98, 0xA2, 0x18, 0x2C, 0x42, 0x40, 0xB3, 0xF9, 0x6F, 0x38, + 0x27, 0x4B, 0x4E, 0x80, 0xF4, 0x3D, 0x81, 0x47, 0xE0, 0x88, 0x7C, 0xEA, + 0x1C, 0xCE, 0xB5, 0x75, 0x5C, 0x51, 0x2E, 0x1C, 0x2B, 0x7F, 0x1A, 0x72, + 0x28, 0xE7, 0x00, 0xB5, 0xD1, 0x74, 0xC6, 0xD7, 0xE4, 0x9F, 0xAD, 0x07, + 0x93, 0xB6, 0x53, 0x35, 0x35, 0xFC, 0x37, 0xE4, 0xC3, 0xF6, 0x5D, 0x16, + 0xBE, 0x21, 0x73, 0xDE, 0x92, 0x0A, 0xF8, 0xA0, 0x63, 0x6A, 0xBC, 0x96, + 0x92, 0x6A, 0x3E, 0xF8, 0xBC, 0x65, 0x55, 0x9B, 0xDE, 0xF5, 0x0D, 0x89, + 0x26, 0x04, 0xFC, 0x25, 0x1A, 0xA6, 0x25, 0x69, 0xCB, 0xC2, 0x6D, 0xCA, + 0x7C, 0xE2, 0x59, 0x5F, 0x97, 0xAC, 0xEB, 0xEF, 0x2E, 0xC8, 0xBC, 0xD7, + 0x1B, 0x59, 0x3C, 0x2B, 0xCC, 0xF2, 0x19, 0xC8, 0x93, 0x6B, 0x27, 0x63, + 0x19, 0xCF, 0xFC, 0xE9, 0x26, 0xF8, 0xCA, 0x71, 0x9B, 0x7F, 0x93, 0xFE, + 0x34, 0x67, 0x84, 0x4E, 0x99, 0xEB, 0xFC, 0xB3, 0x78, 0x09, 0x33, 0x70, + 0xBA, 0x66, 0xA6, 0x76, 0xED, 0x1B, 0x73, 0xEB, 0x1A, 0xA5, 0x0D, 0xC4, + 0x22, 0x13, 0x20, 0x94, 0x56, 0x0A, 0x4E, 0x2C, 0x6C, 0x4E, 0xB1, 0xFD, + 0xCF, 0x9C, 0x09, 0xBA, 0xA2, 0x33, 0xED, 0x87 +}; + +static const unsigned char TA495_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA496_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA496_EC_Q[] = { + 0x04, 0x45, 0x29, 0x35, 0x73, 0xFA, 0xC2, 0xB8, 0x23, 0xCE, 0x14, 0x7D, + 0xA8, 0xB1, 0x4D, 0xA0, 0x5B, 0x36, 0xEE, 0x2A, 0x2C, 0x53, 0xC3, 0x60, + 0x09, 0x35, 0xB2, 0x24, 0x66, 0x26, 0x69, 0xC0, 0xB3, 0x95, 0xD6, 0x5D, + 0x92, 0x40, 0x19, 0x0E, 0xC6, 0xA5, 0x13, 0x70, 0xF4, 0xEF, 0x12, 0x51, + 0x28, 0x5D, 0xE7, 0xCC, 0xBD, 0xF9, 0x3C, 0x85, 0xC1, 0xCF, 0x94, 0x90, + 0xC9, 0x2B, 0xCE, 0x92, 0x42, 0x58, 0x59, 0x67, 0xFD, 0x94, 0x27, 0x10, + 0x64, 0x8C, 0x4F, 0x04, 0xB1, 0x4D, 0x49, 0xE4, 0x7B, 0x4F, 0x9B, 0xF5, + 0xE7, 0x08, 0xF8, 0x03, 0x88, 0xF7, 0xA7, 0xC3, 0x92, 0x4B, 0x19, 0x54, + 0x81 +}; + +static const unsigned char TA497_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA497_RSA_N[] = { + 0xD0, 0xA4, 0x09, 0x72, 0x4F, 0x40, 0x88, 0x12, 0x61, 0x3E, 0x35, 0x23, + 0x9E, 0xEE, 0xF6, 0x74, 0xCF, 0x2F, 0x7B, 0x58, 0x3D, 0xCE, 0x3C, 0x0D, + 0x10, 0x28, 0x90, 0x2F, 0x97, 0xF7, 0x8C, 0x48, 0xD8, 0xA0, 0xD8, 0x25, + 0xB1, 0x4C, 0xB0, 0x11, 0x4C, 0x17, 0x73, 0x50, 0xD0, 0x22, 0x4A, 0x63, + 0xBB, 0x81, 0xD3, 0x29, 0x6E, 0xD5, 0xB5, 0x09, 0x3E, 0x26, 0x18, 0x7F, + 0xB2, 0x12, 0x7F, 0x93, 0x98, 0xB7, 0xAF, 0xF0, 0x36, 0xBF, 0xF2, 0xEE, + 0x18, 0x9E, 0x9C, 0x3B, 0x52, 0xC5, 0x47, 0x19, 0x5D, 0x74, 0xF3, 0x64, + 0x66, 0xD5, 0x5D, 0xC7, 0x68, 0xB4, 0xBF, 0x1B, 0x1C, 0x06, 0xA3, 0xBC, + 0x8F, 0x40, 0x23, 0xB6, 0x1E, 0xC6, 0x84, 0xBD, 0x51, 0xC4, 0x1B, 0x39, + 0xC1, 0x95, 0xD2, 0x29, 0xEC, 0x4B, 0xAE, 0x7B, 0x2D, 0xBF, 0x39, 0xFD, + 0xB4, 0x62, 0xDE, 0x96, 0x7B, 0x41, 0xC6, 0x9C, 0xA0, 0xE0, 0x06, 0x72, + 0xFB, 0xF0, 0x07, 0x97, 0x09, 0x39, 0x81, 0x74, 0xAF, 0xF7, 0x34, 0x59, + 0x11, 0x57, 0x0A, 0xC2, 0x5B, 0xC1, 0x24, 0xF4, 0x31, 0x73, 0x30, 0x82, + 0xC6, 0x9D, 0xBA, 0x02, 0xF7, 0x3E, 0x7C, 0x44, 0x5F, 0x83, 0x0D, 0xF3, + 0xF1, 0xDD, 0x20, 0x69, 0x16, 0x09, 0x50, 0xE2, 0xD4, 0x55, 0xB6, 0xE0, + 0x80, 0x72, 0x76, 0x6E, 0x4C, 0x47, 0xB7, 0x75, 0x55, 0x59, 0xB4, 0x53, + 0x74, 0xD9, 0x94, 0xC6, 0x41, 0xAD, 0x58, 0x8A, 0x31, 0x66, 0x0F, 0x1E, + 0xA2, 0x1B, 0x29, 0x40, 0x4E, 0x2F, 0xDF, 0x7B, 0xE6, 0x16, 0x2C, 0x2D, + 0xFC, 0xBF, 0xEC, 0xF3, 0xB4, 0xFA, 0xBE, 0x18, 0xF6, 0x9B, 0x49, 0xD4, + 0xEE, 0x05, 0x6E, 0xD9, 0x34, 0xF3, 0x9C, 0xF1, 0xEC, 0x01, 0x8B, 0xD1, + 0x20, 0xC6, 0x0F, 0xA0, 0xB5, 0xBC, 0x17, 0x4E, 0x48, 0x7B, 0x51, 0xC2, + 0xFC, 0xE9, 0x5C, 0x69, 0x37, 0x47, 0x66, 0xB3, 0x68, 0xF8, 0x15, 0x28, + 0xF0, 0xB9, 0xD3, 0xA4, 0x15, 0xCC, 0x5A, 0x4F, 0xBA, 0x52, 0x70, 0xA3, + 0x12, 0x45, 0xDD, 0xC6, 0xBA, 0x4E, 0xFB, 0xC2, 0xD0, 0xF7, 0xA8, 0x52, + 0x27, 0x6D, 0x6E, 0x79, 0xB5, 0x8C, 0xFC, 0x7B, 0x8C, 0xC1, 0x16, 0x4C, + 0xEE, 0x80, 0x7F, 0xBE, 0xF0, 0x76, 0xBE, 0x41, 0x53, 0x12, 0x33, 0xAE, + 0x5A, 0x38, 0x42, 0xAB, 0xD7, 0x0F, 0x3E, 0x41, 0x8D, 0x76, 0x07, 0x32, + 0xD5, 0xAB, 0x89, 0xF6, 0x4E, 0x67, 0xD9, 0xB1, 0x42, 0x75, 0x23, 0x6E, + 0xF3, 0xCD, 0x42, 0xB2, 0xFC, 0x55, 0xF5, 0x53, 0x87, 0x17, 0x3B, 0xC0, + 0x33, 0x58, 0xF1, 0x52, 0xD2, 0xF9, 0x80, 0xA4, 0xF0, 0xE8, 0xF0, 0x3B, + 0x8B, 0x38, 0xCC, 0xA4, 0xC6, 0x90, 0x7F, 0x0F, 0x9C, 0xFD, 0x8B, 0xD1, + 0xA3, 0xCF, 0xDA, 0x83, 0xA7, 0x69, 0xC9, 0x50, 0x36, 0xD5, 0x5C, 0x05, + 0xD2, 0x0A, 0x41, 0x74, 0xDB, 0x63, 0x11, 0x37, 0xC1, 0xA5, 0xA0, 0x96, + 0x4B, 0x1E, 0x8C, 0x16, 0x12, 0x77, 0xAE, 0x94, 0x34, 0x7B, 0x1E, 0x7F, + 0xC2, 0x66, 0x00, 0xE4, 0xAA, 0x83, 0xEA, 0x8A, 0x90, 0xAD, 0xCE, 0x36, + 0x44, 0x4D, 0xD1, 0x51, 0xE9, 0xBC, 0x1F, 0xF3, 0x6A, 0x05, 0xFD, 0xC0, + 0x74, 0x1F, 0x25, 0x19, 0x40, 0x51, 0x6E, 0xEA, 0x82, 0x51, 0x40, 0xDF, + 0x9B, 0xB9, 0x08, 0x2A, 0x06, 0x02, 0xD5, 0x23, 0x1C, 0x13, 0xD6, 0xE9, + 0xDB, 0xDB, 0xC6, 0xB0, 0x7A, 0xCB, 0x7B, 0x27, 0x9B, 0xFB, 0xE0, 0xD5, + 0x46, 0x24, 0xED, 0x10, 0x4B, 0x63, 0x4B, 0xA5, 0x05, 0x8F, 0xBA, 0xB8, + 0x1D, 0x2B, 0xA6, 0xFA, 0x91, 0xE2, 0x92, 0x52, 0xBD, 0xEC, 0xEB, 0x67, + 0x97, 0x6D, 0x9A, 0x2D, 0x9F, 0x81, 0x32, 0x05, 0x67, 0x32, 0xFB, 0x48, + 0x08, 0x3F, 0xD9, 0x25, 0xB8, 0x04, 0x25, 0x2F +}; + +static const unsigned char TA497_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA498_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1F, 0x4B, 0x72, 0x61, 0x6A, 0x6F, 0x77, 0x61, 0x20, 0x49, 0x7A, + 0x62, 0x61, 0x20, 0x52, 0x6F, 0x7A, 0x6C, 0x69, 0x63, 0x7A, 0x65, 0x6E, + 0x69, 0x6F, 0x77, 0x61, 0x20, 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x53, 0x5A, 0x41, 0x46, + 0x49, 0x52, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA498_RSA_N[] = { + 0xB7, 0xBC, 0x3E, 0x50, 0xA8, 0x4B, 0xCD, 0x40, 0xB5, 0xCE, 0x61, 0xE7, + 0x96, 0xCA, 0xB4, 0xA1, 0xDA, 0x0C, 0x22, 0xB0, 0xFA, 0xB5, 0x7B, 0x76, + 0x00, 0x77, 0x8C, 0x0B, 0xCF, 0x7D, 0xA8, 0x86, 0xCC, 0x26, 0x51, 0xE4, + 0x20, 0x3D, 0x85, 0x0C, 0xD6, 0x58, 0xE3, 0xE7, 0xF4, 0x2A, 0x18, 0x9D, + 0xDA, 0xD1, 0xAE, 0x26, 0xEE, 0xEB, 0x53, 0xDC, 0xF4, 0x90, 0xD6, 0x13, + 0x4A, 0x0C, 0x90, 0x3C, 0xC3, 0xF4, 0xDA, 0xD2, 0x8E, 0x0D, 0x92, 0x3A, + 0xDC, 0xB1, 0xB1, 0xFF, 0x38, 0xDE, 0xC3, 0xBA, 0x2D, 0x5F, 0x80, 0xB9, + 0x02, 0xBD, 0x4A, 0x9D, 0x1B, 0x0F, 0xB4, 0xC3, 0xC2, 0xC1, 0x67, 0x03, + 0xDD, 0xDC, 0x1B, 0x9C, 0x3D, 0xB3, 0xB0, 0xDE, 0x00, 0x1E, 0xA8, 0x34, + 0x47, 0xBB, 0x9A, 0xEB, 0xFE, 0x0B, 0x14, 0xBD, 0x36, 0x84, 0xDA, 0x0D, + 0x20, 0xBF, 0xFA, 0x5B, 0xCB, 0xA9, 0x16, 0x20, 0xAD, 0x39, 0x60, 0xEE, + 0x2F, 0x75, 0xB6, 0xE7, 0x97, 0x9C, 0xF9, 0x3E, 0xFD, 0x7E, 0x4D, 0x6F, + 0x4D, 0x2F, 0xEF, 0x88, 0x0D, 0x6A, 0xFA, 0xDD, 0xF1, 0x3D, 0x6E, 0x20, + 0xA5, 0xA0, 0x12, 0xB4, 0x4D, 0x70, 0xB9, 0xCE, 0xD7, 0x72, 0x3B, 0x89, + 0x93, 0xA7, 0x80, 0x84, 0x1C, 0x27, 0x49, 0x72, 0x49, 0xB5, 0xFF, 0x3B, + 0x95, 0x9E, 0xC1, 0xCC, 0xC8, 0x01, 0xEC, 0xE8, 0x0E, 0x8A, 0x0A, 0x96, + 0xE7, 0xB3, 0xA6, 0x87, 0xE5, 0xD6, 0xF9, 0x05, 0x2B, 0x0D, 0x97, 0x40, + 0x70, 0x3C, 0xBA, 0xAC, 0x75, 0x5A, 0x9C, 0xD5, 0x4D, 0x9D, 0x02, 0x0A, + 0xD2, 0x4B, 0x9B, 0x66, 0x4B, 0x46, 0x07, 0x17, 0x65, 0xAD, 0x9F, 0x6C, + 0x88, 0x00, 0xDC, 0x22, 0x89, 0xE0, 0xE1, 0x64, 0xD4, 0x67, 0xBC, 0x31, + 0x79, 0x61, 0x3C, 0xBB, 0xCA, 0x41, 0xCD, 0x5C, 0x6A, 0x00, 0xC8, 0x3C, + 0x38, 0x8E, 0x58, 0xAF +}; + +static const unsigned char TA498_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA499_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, + 0x36 +}; + +static const unsigned char TA499_EC_Q[] = { + 0x04, 0x76, 0xFA, 0x99, 0xA9, 0x6E, 0x20, 0xED, 0xF9, 0xD7, 0x77, 0xE3, + 0x07, 0x3B, 0xA8, 0xDB, 0x3D, 0x5F, 0x38, 0xE8, 0xAB, 0x55, 0xA6, 0x56, + 0x4F, 0xD6, 0x48, 0xEA, 0xEC, 0x7F, 0x2D, 0xAA, 0xC3, 0xB2, 0xC5, 0x79, + 0xEC, 0x99, 0x61, 0x7F, 0x10, 0x79, 0xC7, 0x02, 0x5A, 0xF9, 0x04, 0x37, + 0xF5, 0x34, 0x35, 0x2B, 0x77, 0xCE, 0x7F, 0x20, 0x8F, 0x52, 0xA3, 0x00, + 0x89, 0xEC, 0xD5, 0xA7, 0xA2, 0x6D, 0x5B, 0xE3, 0x4B, 0x92, 0x93, 0xA0, + 0x80, 0xF5, 0x01, 0x94, 0xDC, 0xF0, 0x68, 0x07, 0x1E, 0xCD, 0xEE, 0xFE, + 0x25, 0x52, 0xB5, 0x20, 0x43, 0x1C, 0x1B, 0xFE, 0xEB, 0x19, 0xCE, 0x43, + 0xA3 +}; + +static const unsigned char TA500_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, + 0x36 +}; + +static const unsigned char TA500_RSA_N[] = { + 0x93, 0xBE, 0xD5, 0x36, 0x52, 0x75, 0xD8, 0x01, 0x23, 0xA0, 0x1C, 0x47, + 0x42, 0x49, 0xEE, 0x63, 0xB6, 0xB7, 0x21, 0xFD, 0xC4, 0x95, 0xD5, 0x48, + 0x2B, 0x26, 0x7C, 0x14, 0x53, 0x10, 0xDA, 0x79, 0xFD, 0x2B, 0xB7, 0x2D, + 0xA4, 0xD4, 0x2C, 0xFA, 0xEA, 0x32, 0xDD, 0x49, 0xC2, 0xB9, 0xBD, 0x0F, + 0x48, 0x3D, 0x7B, 0x5A, 0x98, 0x54, 0xAF, 0x9E, 0x5D, 0x31, 0x74, 0x4F, + 0x07, 0xFC, 0x50, 0x21, 0xDD, 0xA4, 0xCF, 0x68, 0x4F, 0x1B, 0x12, 0x63, + 0x6D, 0x25, 0x99, 0x4C, 0x2A, 0x99, 0xF3, 0x48, 0x30, 0x61, 0xFA, 0x81, + 0x7C, 0x1E, 0xA7, 0x08, 0x4A, 0xDC, 0x3E, 0x2B, 0x1C, 0x1F, 0x18, 0x4C, + 0x71, 0xAA, 0x35, 0x8C, 0xAD, 0xF8, 0x6E, 0xE8, 0x3B, 0x4A, 0xD9, 0xE5, + 0x94, 0x02, 0xD6, 0x89, 0x84, 0x13, 0xAA, 0x6D, 0xC8, 0x4F, 0x33, 0xCC, + 0x50, 0x96, 0x37, 0x92, 0x33, 0xDC, 0x5F, 0x88, 0xE7, 0x9F, 0x54, 0xD9, + 0x48, 0xF0, 0x98, 0x43, 0xD6, 0x66, 0xFD, 0x9F, 0x17, 0x38, 0x43, 0xC5, + 0x01, 0x51, 0x0B, 0xD7, 0xE3, 0x23, 0x0F, 0x14, 0x5D, 0x5B, 0x14, 0xE7, + 0x4B, 0xBE, 0xDD, 0xF4, 0xC8, 0xDA, 0x03, 0x37, 0xD1, 0xD6, 0x39, 0xA1, + 0x21, 0x51, 0x30, 0x83, 0xB0, 0x6D, 0xD7, 0x30, 0x4E, 0x96, 0x5B, 0x91, + 0xF0, 0x70, 0x24, 0xAB, 0xBF, 0x45, 0x81, 0x64, 0x43, 0x0D, 0xBD, 0x21, + 0x3A, 0x2F, 0x3C, 0xE9, 0x9E, 0x0D, 0xCB, 0x20, 0xB5, 0x42, 0x27, 0xCC, + 0xDA, 0x6F, 0x9B, 0xEE, 0x64, 0x30, 0x90, 0x39, 0xCD, 0x93, 0x65, 0x81, + 0x21, 0x31, 0xB5, 0x23, 0x50, 0x33, 0x37, 0x22, 0xE3, 0x38, 0xED, 0xF8, + 0x31, 0x30, 0xCC, 0x45, 0xFE, 0x62, 0xF9, 0xD1, 0x5D, 0x32, 0x79, 0x42, + 0x87, 0xDF, 0x6A, 0xCC, 0x56, 0x19, 0x40, 0x4D, 0xCE, 0xAA, 0xBB, 0xF9, + 0xB5, 0x76, 0x49, 0x94, 0xF1, 0x27, 0xF8, 0x91, 0xA5, 0x83, 0xE5, 0x06, + 0xB3, 0x63, 0x0E, 0x80, 0xDC, 0xE0, 0x12, 0x55, 0x80, 0xA6, 0x3B, 0x66, + 0xB4, 0x39, 0x87, 0x2D, 0xC8, 0xF0, 0xD0, 0xD1, 0x14, 0xE9, 0xE4, 0x0D, + 0x4D, 0x0E, 0xF6, 0x5D, 0x57, 0x72, 0xC5, 0x3B, 0x1C, 0x47, 0x56, 0x9D, + 0xE2, 0xD5, 0xFB, 0x81, 0x61, 0x8C, 0xCC, 0x4D, 0x80, 0x90, 0x34, 0x5B, + 0xB7, 0xD7, 0x14, 0x75, 0xDC, 0xD8, 0x04, 0x48, 0x9F, 0xC0, 0xC1, 0x28, + 0x88, 0xB4, 0xE9, 0x1C, 0xCA, 0xA7, 0xB1, 0xF1, 0x56, 0xB7, 0x7B, 0x49, + 0x4C, 0x59, 0xE5, 0x20, 0x15, 0xA8, 0x84, 0x02, 0x29, 0xFA, 0x38, 0x94, + 0x69, 0x9A, 0x49, 0x06, 0x8F, 0xCD, 0x1F, 0x79, 0x14, 0x17, 0x12, 0x0C, + 0x83, 0x7A, 0xDE, 0x1F, 0xB1, 0x97, 0xEE, 0xF9, 0x97, 0x78, 0x28, 0xA4, + 0xC8, 0x44, 0x92, 0xE9, 0x7D, 0x26, 0x05, 0xA6, 0x58, 0x72, 0x9B, 0x79, + 0x13, 0xD8, 0x11, 0x5F, 0xAE, 0xC5, 0x38, 0x62, 0x34, 0x68, 0xB2, 0x86, + 0x30, 0x8E, 0xF8, 0x90, 0x61, 0x9E, 0x32, 0x6C, 0xF5, 0x07, 0x36, 0xCD, + 0xA2, 0x4C, 0x6E, 0xEC, 0x8A, 0x36, 0xED, 0xF2, 0xE6, 0x99, 0x15, 0x44, + 0x70, 0xC3, 0x7C, 0xBC, 0x9C, 0x39, 0xC0, 0xB4, 0xE1, 0x6B, 0xF7, 0x83, + 0x25, 0x23, 0x57, 0xD9, 0x12, 0x80, 0xE5, 0x49, 0xF0, 0x75, 0x0F, 0xEF, + 0x8D, 0xEB, 0x1C, 0x9B, 0x54, 0x28, 0xB4, 0x21, 0x3C, 0xFC, 0x7C, 0x0A, + 0xFF, 0xEF, 0x7B, 0x6B, 0x75, 0xFF, 0x8B, 0x1D, 0xA0, 0x19, 0x05, 0xAB, + 0xFA, 0xF8, 0x2B, 0x81, 0x42, 0xE8, 0x38, 0xBA, 0xBB, 0xFB, 0xAA, 0xFD, + 0x3D, 0xE0, 0xF3, 0xCA, 0xDF, 0x4E, 0x97, 0x97, 0x29, 0xED, 0xF3, 0x18, + 0x56, 0xE9, 0xA5, 0x96, 0xAC, 0xBD, 0xC3, 0x90, 0x98, 0xB2, 0xE0, 0xF9, + 0xA2, 0xD4, 0xA6, 0x47, 0x43, 0x7C, 0x6D, 0xCF +}; + +static const unsigned char TA500_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA501_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x32 +}; + +static const unsigned char TA501_RSA_N[] = { + 0xBA, 0x39, 0xC1, 0x37, 0x7A, 0x68, 0x45, 0x2B, 0x14, 0xB4, 0xEB, 0xE4, + 0x13, 0xEB, 0x57, 0x75, 0x23, 0x4D, 0x8F, 0x24, 0x2D, 0x16, 0xE8, 0xAE, + 0x8E, 0xC9, 0x7D, 0xA4, 0x57, 0x3B, 0x2A, 0x76, 0x25, 0x33, 0x83, 0x6C, + 0xEA, 0x32, 0x8A, 0x94, 0x9B, 0x4E, 0x3C, 0x96, 0xE4, 0xFD, 0x51, 0xBF, + 0x99, 0xC9, 0x93, 0x7E, 0xBF, 0xF9, 0xAD, 0xA7, 0xB2, 0x48, 0x2B, 0x07, + 0x1C, 0x27, 0xF5, 0x4C, 0xBC, 0x70, 0x12, 0x77, 0xA4, 0x85, 0x54, 0xB5, + 0xFD, 0x90, 0x7A, 0xE4, 0xA3, 0xE4, 0x51, 0x58, 0x03, 0xCD, 0x10, 0x79, + 0x79, 0xEE, 0x6B, 0x93, 0x1F, 0x64, 0x8E, 0x6B, 0x64, 0xAB, 0xA3, 0x13, + 0xE3, 0x71, 0xFE, 0x7D, 0xAB, 0x9C, 0xDD, 0x27, 0x53, 0x37, 0xB3, 0xAA, + 0x18, 0xC2, 0x59, 0x26, 0xEC, 0x5B, 0x1F, 0xD2, 0xE6, 0x65, 0x7C, 0xEF, + 0x93, 0xBD, 0xD8, 0x58, 0x5C, 0x0B, 0xC0, 0xE3, 0x65, 0x6F, 0x3C, 0xC7, + 0xCA, 0x59, 0xE3, 0xFE, 0x6E, 0x5F, 0xAC, 0x83, 0xBE, 0xFD, 0x5D, 0x25, + 0x4E, 0x2A, 0x29, 0x3B, 0xD6, 0x0B, 0xAB, 0x17, 0x32, 0x78, 0xA4, 0xE1, + 0x3E, 0x94, 0x46, 0xBE, 0x62, 0x6E, 0x9B, 0xDE, 0x46, 0xA8, 0xB1, 0x16, + 0xE7, 0x85, 0x6E, 0xF4, 0x08, 0x40, 0x45, 0x11, 0xA0, 0x9E, 0x54, 0x44, + 0x84, 0xF7, 0xD8, 0x36, 0xCE, 0xF5, 0x50, 0x47, 0xDC, 0x2C, 0x30, 0x9B, + 0xEE, 0xC0, 0xF5, 0x96, 0xD2, 0xFE, 0x09, 0x86, 0xC7, 0x06, 0x59, 0xAE, + 0x4F, 0xAE, 0x8E, 0x11, 0x98, 0x7B, 0xF3, 0x0B, 0x52, 0xAA, 0x62, 0x26, + 0xAA, 0x21, 0xDF, 0x8E, 0x25, 0x33, 0x79, 0x97, 0x16, 0x49, 0x8D, 0xF5, + 0x3E, 0xD5, 0x47, 0x9F, 0x37, 0x31, 0x49, 0x33, 0x72, 0x05, 0x4D, 0x0C, + 0xB6, 0x55, 0x8C, 0xF1, 0x57, 0x8F, 0x8A, 0x87, 0xD1, 0xAD, 0xC5, 0x11, + 0x12, 0x39, 0xA0, 0xAD +}; + +static const unsigned char TA501_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA502_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x34 +}; + +static const unsigned char TA502_RSA_N[] = { + 0xC5, 0xD2, 0x7A, 0xA1, 0xD6, 0x8A, 0xBF, 0x16, 0x31, 0xD0, 0x98, 0xD1, + 0x3A, 0x94, 0xFC, 0x5A, 0xB8, 0x6E, 0x22, 0xC1, 0x62, 0xF7, 0xA7, 0x0A, + 0x27, 0xEF, 0x50, 0xF6, 0x2E, 0xB1, 0x9E, 0x68, 0x12, 0xF0, 0x6C, 0x24, + 0x63, 0x39, 0xF1, 0xF0, 0xDF, 0x10, 0xC6, 0xDE, 0xB7, 0x52, 0x20, 0xD5, + 0x52, 0x5B, 0x42, 0x99, 0x9E, 0xF3, 0xA0, 0xBE, 0x52, 0x1F, 0x5F, 0xCC, + 0x67, 0x6D, 0xA7, 0x2E, 0x50, 0xA2, 0xC1, 0x97, 0x8D, 0xB6, 0xF8, 0x95, + 0xF5, 0xB0, 0xBA, 0xDC, 0x9D, 0xE0, 0xBE, 0xCB, 0xDF, 0xF7, 0x38, 0xF2, + 0x47, 0xF5, 0xA6, 0x9A, 0x92, 0x95, 0x2A, 0x62, 0x59, 0x50, 0x0B, 0xA2, + 0xB1, 0x35, 0xE7, 0x65, 0xB2, 0x61, 0xB2, 0xEA, 0x92, 0x71, 0x69, 0xE4, + 0x29, 0xF0, 0x4F, 0x81, 0x81, 0x04, 0x3C, 0xB2, 0xA5, 0x5B, 0xD4, 0xC5, + 0xA8, 0x59, 0x67, 0x7B, 0x55, 0x1C, 0x49, 0xAB, 0x7A, 0x9D, 0xC2, 0xE7, + 0x73, 0x4D, 0xEF, 0xCD, 0x09, 0xC2, 0xC4, 0x57, 0x12, 0xDB, 0x01, 0x0E, + 0x23, 0x79, 0x09, 0x07, 0x3B, 0xA2, 0xE8, 0xFC, 0x8A, 0xCF, 0x8F, 0xC0, + 0x46, 0x24, 0x9C, 0x38, 0x27, 0xE0, 0x83, 0x9D, 0x1B, 0xA0, 0xBF, 0x78, + 0x15, 0x10, 0xEB, 0x86, 0x4E, 0x0A, 0x5A, 0xFD, 0xDF, 0xDA, 0x2C, 0x82, + 0x7E, 0xEE, 0xCA, 0xF6, 0x29, 0xE1, 0xFA, 0x71, 0xA1, 0xF7, 0x88, 0x68, + 0x9C, 0x9C, 0xF0, 0x8D, 0xBE, 0x0F, 0x49, 0x91, 0xD8, 0xEA, 0x3A, 0xF9, + 0xFD, 0xD0, 0x68, 0x71, 0xDB, 0xE9, 0xB5, 0x2B, 0x4E, 0x82, 0x92, 0x6F, + 0x66, 0x1F, 0xE0, 0xF0, 0xDC, 0x4C, 0xEC, 0xCA, 0xD1, 0xEA, 0xBA, 0x74, + 0x06, 0xF9, 0xB3, 0x84, 0x90, 0x94, 0xD1, 0x5F, 0x8E, 0x73, 0x19, 0x10, + 0x5D, 0x02, 0xE5, 0x70, 0xA5, 0xC0, 0x10, 0xD0, 0x10, 0x7C, 0x6F, 0xC5, + 0x58, 0x49, 0xB4, 0xB0, 0x6E, 0x9A, 0xDA, 0x7D, 0x95, 0xF5, 0xCC, 0xDA, + 0x02, 0xAF, 0xB8, 0x2C, 0x7D, 0x79, 0x8F, 0xBE, 0x43, 0xF1, 0xF9, 0x28, + 0x28, 0x8D, 0x09, 0x43, 0xF8, 0x08, 0xDD, 0x6B, 0xC8, 0x8B, 0x2C, 0x24, + 0xB1, 0x8D, 0x52, 0x07, 0xBD, 0x78, 0x9B, 0xCB, 0xCA, 0x68, 0xB2, 0xA4, + 0xDD, 0x0C, 0x4C, 0x79, 0x60, 0xC6, 0x99, 0xD1, 0x93, 0xF1, 0x30, 0x1A, + 0x07, 0xD3, 0xAE, 0x22, 0xC2, 0xEA, 0xCE, 0xF1, 0x84, 0x09, 0xCC, 0xE0, + 0x14, 0x6E, 0x7F, 0x3F, 0x7E, 0xD2, 0x82, 0x85, 0xAC, 0xDC, 0xA9, 0x16, + 0x4E, 0x85, 0xA0, 0x60, 0xCB, 0xF6, 0x9C, 0xD7, 0xC8, 0xB3, 0x8E, 0xED, + 0xC6, 0x9B, 0x98, 0x75, 0x0D, 0x55, 0xE8, 0x5F, 0xE5, 0x95, 0x8B, 0x02, + 0xA4, 0xAE, 0x43, 0x29, 0x28, 0x11, 0xA4, 0xE6, 0x12, 0x30, 0x01, 0x4B, + 0x75, 0x6B, 0x1E, 0x66, 0x9D, 0x79, 0x2F, 0xA5, 0x76, 0x2F, 0x1D, 0x40, + 0xB4, 0x6D, 0xC9, 0x7D, 0x79, 0x08, 0xEC, 0xD1, 0x6A, 0xB6, 0x5D, 0x2A, + 0xB2, 0xA5, 0x66, 0xBD, 0x6B, 0x85, 0xF4, 0x74, 0x56, 0xC3, 0xF5, 0xE7, + 0x75, 0x52, 0x28, 0x2C, 0xA5, 0xFF, 0x66, 0x47, 0xA5, 0xD4, 0xFE, 0xFE, + 0x9E, 0x54, 0xBF, 0x65, 0x7E, 0x01, 0xD6, 0x30, 0x8F, 0xA5, 0x36, 0x9C, + 0xA2, 0x50, 0x1C, 0xEE, 0x38, 0x80, 0x01, 0x48, 0xC6, 0xC7, 0x74, 0xF4, + 0xC6, 0xAC, 0xC3, 0x40, 0x49, 0x16, 0x61, 0x74, 0x2C, 0xAF, 0x8C, 0x6F, + 0x35, 0xED, 0x7B, 0x18, 0x00, 0x5B, 0x36, 0x3C, 0x9C, 0x50, 0x0D, 0xCA, + 0x92, 0x33, 0x10, 0xF1, 0x26, 0x49, 0x6D, 0xDF, 0x75, 0x24, 0x37, 0x82, + 0x22, 0xD7, 0xE8, 0x96, 0xFD, 0x15, 0x4B, 0x02, 0x96, 0x3E, 0x07, 0x72, + 0x95, 0x7E, 0xAB, 0x3D, 0x4C, 0x2E, 0xD7, 0xCA, 0xF0, 0xDF, 0xE0, 0x58, + 0x3F, 0x2D, 0x2F, 0x04, 0x9A, 0x38, 0xA3, 0x01 +}; + +static const unsigned char TA502_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA503_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x35 +}; + +static const unsigned char TA503_EC_Q[] = { + 0x04, 0x0B, 0x50, 0x74, 0x8D, 0x64, 0x32, 0x99, 0x99, 0xB3, 0xD2, 0x60, + 0x08, 0xB8, 0x22, 0x8E, 0x46, 0x74, 0x2C, 0x78, 0xC0, 0x2B, 0x44, 0x2D, + 0x6D, 0x5F, 0x1D, 0xC9, 0xAE, 0x4B, 0x52, 0x20, 0x83, 0x3D, 0xB8, 0x14, + 0x6D, 0x53, 0x87, 0x60, 0x9E, 0x5F, 0x6C, 0x85, 0xDB, 0x06, 0x14, 0x95, + 0xE0, 0xC7, 0x28, 0xFF, 0x9D, 0x5F, 0xE4, 0xAA, 0xF1, 0xB3, 0x8B, 0x6D, + 0xED, 0x4F, 0x2F, 0x4B, 0xC9, 0x4A, 0x94, 0x91, 0x64, 0x75, 0xFE, 0x01, + 0xEC, 0xC1, 0xD8, 0xEB, 0x7A, 0x94, 0x78, 0x56, 0x18, 0x43, 0x5F, 0x6B, + 0x81, 0xCB, 0xF6, 0xBC, 0xDA, 0xB4, 0x0C, 0xB6, 0x29, 0x93, 0x08, 0x69, + 0x8F +}; + +static const unsigned char TA504_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0E, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA504_RSA_N[] = { + 0xAB, 0xA4, 0x81, 0xE5, 0x95, 0xCD, 0xF5, 0xF6, 0x14, 0x8E, 0xC2, 0x4F, + 0xCA, 0xD4, 0xE2, 0x78, 0x95, 0x58, 0x9C, 0x41, 0xE1, 0x0D, 0x99, 0x40, + 0x24, 0x17, 0x39, 0x91, 0x33, 0x66, 0xE9, 0xBE, 0xE1, 0x83, 0xAF, 0x62, + 0x5C, 0x89, 0xD1, 0xFC, 0x24, 0x5B, 0x61, 0xB3, 0xE0, 0x11, 0x11, 0x41, + 0x1C, 0x1D, 0x6E, 0xF0, 0xB8, 0xBB, 0xF8, 0xDE, 0xA7, 0x81, 0xBA, 0xA6, + 0x48, 0xC6, 0x9F, 0x1D, 0xBD, 0xBE, 0x8E, 0xA9, 0x41, 0x3E, 0xB8, 0x94, + 0xED, 0x29, 0x1A, 0xD4, 0x8E, 0xD2, 0x03, 0x1D, 0x03, 0xEF, 0x6D, 0x0D, + 0x67, 0x1C, 0x57, 0xD7, 0x06, 0xAD, 0xCA, 0xC8, 0xF5, 0xFE, 0x0E, 0xAF, + 0x66, 0x25, 0x48, 0x04, 0x96, 0x0B, 0x5D, 0xA3, 0xBA, 0x16, 0xC3, 0x08, + 0x4F, 0xD1, 0x46, 0xF8, 0x14, 0x5C, 0xF2, 0xC8, 0x5E, 0x01, 0x99, 0x6D, + 0xFD, 0x88, 0xCC, 0x86, 0xA8, 0xC1, 0x6F, 0x31, 0x42, 0x6C, 0x52, 0x3E, + 0x68, 0xCB, 0xF3, 0x19, 0x34, 0xDF, 0xBB, 0x87, 0x18, 0x56, 0x80, 0x26, + 0xC4, 0xD0, 0xDC, 0xC0, 0x6F, 0xDF, 0xDE, 0xA0, 0xC2, 0x91, 0x16, 0xA0, + 0x64, 0x11, 0x4B, 0x44, 0xBC, 0x1E, 0xF6, 0xE7, 0xFA, 0x63, 0xDE, 0x66, + 0xAC, 0x76, 0xA4, 0x71, 0xA3, 0xEC, 0x36, 0x94, 0x68, 0x7A, 0x77, 0xA4, + 0xB1, 0xE7, 0x0E, 0x2F, 0x81, 0x7A, 0xE2, 0xB5, 0x72, 0x86, 0xEF, 0xA2, + 0x6B, 0x8B, 0xF0, 0x0F, 0xDB, 0xD3, 0x59, 0x3F, 0xBA, 0x72, 0xBC, 0x44, + 0x24, 0x9C, 0xE3, 0x73, 0xB3, 0xF7, 0xAF, 0x57, 0x2F, 0x42, 0x26, 0x9D, + 0xA9, 0x74, 0xBA, 0x00, 0x52, 0xF2, 0x4B, 0xCD, 0x53, 0x7C, 0x47, 0x0B, + 0x36, 0x85, 0x0E, 0x66, 0xA9, 0x08, 0x97, 0x16, 0x34, 0x57, 0xC1, 0x66, + 0xF7, 0x80, 0xE3, 0xED, 0x70, 0x54, 0xC7, 0x93, 0xE0, 0x2E, 0x28, 0x15, + 0x59, 0x87, 0xBA, 0xBB +}; + +static const unsigned char TA504_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA505_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA505_RSA_N[] = { + 0xAF, 0x35, 0x2E, 0xD8, 0xAC, 0x6C, 0x55, 0x69, 0x06, 0x71, 0xE5, 0x13, + 0x68, 0x24, 0xB3, 0x4F, 0xD8, 0xCC, 0x21, 0x47, 0xF8, 0xF1, 0x60, 0x38, + 0x89, 0x89, 0x03, 0xE9, 0xBD, 0xEA, 0x5E, 0x46, 0x53, 0x09, 0xDC, 0x5C, + 0xF5, 0x5A, 0xE8, 0xF7, 0x45, 0x2A, 0x02, 0xEB, 0x31, 0x61, 0xD7, 0x29, + 0x33, 0x4C, 0xCE, 0xC7, 0x7C, 0x0A, 0x37, 0x7E, 0x0F, 0xBA, 0x32, 0x98, + 0xE1, 0x1D, 0x97, 0xAF, 0x8F, 0xC7, 0xDC, 0xC9, 0x38, 0x96, 0xF3, 0xDB, + 0x1A, 0xFC, 0x51, 0xED, 0x68, 0xC6, 0xD0, 0x6E, 0xA4, 0x7C, 0x24, 0xD1, + 0xAE, 0x42, 0xC8, 0x96, 0x50, 0x63, 0x2E, 0xE0, 0xFE, 0x75, 0xFE, 0x98, + 0xA7, 0x5F, 0x49, 0x2E, 0x95, 0xE3, 0x39, 0x33, 0x64, 0x8E, 0x1E, 0xA4, + 0x5F, 0x90, 0xD2, 0x67, 0x3C, 0xB2, 0xD9, 0xFE, 0x41, 0xB9, 0x55, 0xA7, + 0x09, 0x8E, 0x72, 0x05, 0x1E, 0x8B, 0xDD, 0x44, 0x85, 0x82, 0x42, 0xD0, + 0x49, 0xC0, 0x1D, 0x60, 0xF0, 0xD1, 0x17, 0x2C, 0x95, 0xEB, 0xF6, 0xA5, + 0xC1, 0x92, 0xA3, 0xC5, 0xC2, 0xA7, 0x08, 0x60, 0x0D, 0x60, 0x04, 0x10, + 0x96, 0x79, 0x9E, 0x16, 0x34, 0xE6, 0xA9, 0xB6, 0xFA, 0x25, 0x45, 0x39, + 0xC8, 0x1E, 0x65, 0xF9, 0x93, 0xF5, 0xAA, 0xF1, 0x52, 0xDC, 0x99, 0x98, + 0x3D, 0xA5, 0x86, 0x1A, 0x0C, 0x35, 0x33, 0xFA, 0x4B, 0xA5, 0x04, 0x06, + 0x15, 0x1C, 0x31, 0x80, 0xEF, 0xAA, 0x18, 0x6B, 0xC2, 0x7B, 0xD7, 0xDA, + 0xCE, 0xF9, 0x33, 0x20, 0xD5, 0xF5, 0xBD, 0x6A, 0x33, 0x2D, 0x81, 0x04, + 0xFB, 0xB0, 0x5C, 0xD4, 0x9C, 0xA3, 0xE2, 0x5C, 0x1D, 0xE3, 0xA9, 0x42, + 0x75, 0x5E, 0x7B, 0xD4, 0x77, 0xEF, 0x39, 0x54, 0xBA, 0xC9, 0x0A, 0x18, + 0x1B, 0x12, 0x99, 0x49, 0x2F, 0x88, 0x4B, 0xFD, 0x50, 0x62, 0xD1, 0x73, + 0xE7, 0x8F, 0x7A, 0x43 +}; + +static const unsigned char TA505_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA506_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x43, 0x41, 0x31 +}; + +static const unsigned char TA506_EC_Q[] = { + 0x04, 0xA4, 0xA5, 0x6F, 0x60, 0x03, 0x03, 0xC3, 0xBD, 0x31, 0xF4, 0xD3, + 0x17, 0x9C, 0x2B, 0x84, 0x75, 0xAC, 0xE5, 0xFD, 0x3D, 0x57, 0x6E, 0xD7, + 0x63, 0xBF, 0xE6, 0x04, 0x89, 0x92, 0x8E, 0x81, 0x9C, 0xE3, 0xE9, 0x47, + 0x6E, 0xCA, 0x90, 0x12, 0xC8, 0x13, 0xE0, 0xA7, 0x9D, 0xF7, 0x65, 0x74, + 0x1F, 0x6C, 0x10, 0xB2, 0xE8, 0xE4, 0xE9, 0xEF, 0x6D, 0x85, 0x32, 0x99, + 0x44, 0xB1, 0x5E, 0xFD, 0xCC, 0x76, 0x10, 0xD8, 0x5B, 0xBD, 0xA2, 0xC6, + 0xF9, 0xD6, 0x42, 0xE4, 0x57, 0x76, 0xDC, 0x90, 0xC2, 0x35, 0xA9, 0x4B, + 0x88, 0x3C, 0x12, 0x47, 0x6D, 0x5C, 0xFF, 0x49, 0x4F, 0x1A, 0x4A, 0x50, + 0xB1 +}; + +static const unsigned char TA507_DN[] = { + 0x30, 0x5D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x1E, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA507_RSA_N[] = { + 0xD0, 0x15, 0x39, 0x52, 0xB1, 0x52, 0xB3, 0xBA, 0xC5, 0x59, 0x82, 0xC4, + 0x5D, 0x52, 0xAE, 0x3A, 0x43, 0x65, 0x80, 0x4B, 0xC7, 0xF2, 0x96, 0xBC, + 0xDB, 0x36, 0x97, 0xD6, 0xA6, 0x64, 0x8C, 0xA8, 0x5E, 0xF0, 0xE3, 0x0A, + 0x1C, 0xF7, 0xDF, 0x97, 0x3D, 0x4B, 0xAE, 0xF6, 0x5D, 0xEC, 0x21, 0xB5, + 0x41, 0xAB, 0xCD, 0xB9, 0x7E, 0x76, 0x9F, 0xBE, 0xF9, 0x3E, 0x36, 0x34, + 0xA0, 0x3B, 0xC1, 0xF6, 0x31, 0x11, 0x45, 0x74, 0x93, 0x3D, 0x57, 0x80, + 0xC5, 0xF9, 0x89, 0x99, 0xCA, 0xE5, 0xAB, 0x6A, 0xD4, 0xB5, 0xDA, 0x41, + 0x90, 0x10, 0xC1, 0xD6, 0xD6, 0x42, 0x89, 0xC2, 0xBF, 0xF4, 0x38, 0x12, + 0x95, 0x4C, 0x54, 0x05, 0xF7, 0x36, 0xE4, 0x45, 0x83, 0x7B, 0x14, 0x65, + 0xD6, 0xDC, 0x0C, 0x4D, 0xD1, 0xDE, 0x7E, 0x0C, 0xAB, 0x3B, 0xC4, 0x15, + 0xBE, 0x3A, 0x56, 0xA6, 0x5A, 0x6F, 0x76, 0x69, 0x52, 0xA9, 0x7A, 0xB9, + 0xC8, 0xEB, 0x6A, 0x9A, 0x5D, 0x52, 0xD0, 0x2D, 0x0A, 0x6B, 0x35, 0x16, + 0x09, 0x10, 0x84, 0xD0, 0x6A, 0xCA, 0x3A, 0x06, 0x00, 0x37, 0x47, 0xE4, + 0x7E, 0x57, 0x4F, 0x3F, 0x8B, 0xEB, 0x67, 0xB8, 0x88, 0xAA, 0xC5, 0xBE, + 0x53, 0x55, 0xB2, 0x91, 0xC4, 0x7D, 0xB9, 0xB0, 0x85, 0x19, 0x06, 0x78, + 0x2E, 0xDB, 0x61, 0x1A, 0xFA, 0x85, 0xF5, 0x4A, 0x91, 0xA1, 0xE7, 0x16, + 0xD5, 0x8E, 0xA2, 0x39, 0xDF, 0x94, 0xB8, 0x70, 0x1F, 0x28, 0x3F, 0x8B, + 0xFC, 0x40, 0x5E, 0x63, 0x83, 0x3C, 0x83, 0x2A, 0x1A, 0x99, 0x6B, 0xCF, + 0xDE, 0x59, 0x6A, 0x3B, 0xFC, 0x6F, 0x16, 0xD7, 0x1F, 0xFD, 0x4A, 0x10, + 0xEB, 0x4E, 0x82, 0x16, 0x3A, 0xAC, 0x27, 0x0C, 0x53, 0xF1, 0xAD, 0xD5, + 0x24, 0xB0, 0x6B, 0x03, 0x50, 0xC1, 0x2D, 0x3C, 0x16, 0xDD, 0x44, 0x34, + 0x27, 0x1A, 0x75, 0xFB +}; + +static const unsigned char TA507_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA508_DN[] = { + 0x30, 0x68, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, + 0x6C, 0x64, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA508_RSA_N[] = { + 0xB7, 0x32, 0xC8, 0xFE, 0xE9, 0x71, 0xA6, 0x04, 0x85, 0xAD, 0x0C, 0x11, + 0x64, 0xDF, 0xCE, 0x4D, 0xEF, 0xC8, 0x03, 0x18, 0x87, 0x3F, 0xA1, 0xAB, + 0xFB, 0x3C, 0xA6, 0x9F, 0xF0, 0xC3, 0xA1, 0xDA, 0xD4, 0xD8, 0x6E, 0x2B, + 0x53, 0x90, 0xFB, 0x24, 0xA4, 0x3E, 0x84, 0xF0, 0x9E, 0xE8, 0x5F, 0xEC, + 0xE5, 0x27, 0x44, 0xF5, 0x28, 0xA6, 0x3F, 0x7B, 0xDE, 0xE0, 0x2A, 0xF0, + 0xC8, 0xAF, 0x53, 0x2F, 0x9E, 0xCA, 0x05, 0x01, 0x93, 0x1E, 0x8F, 0x66, + 0x1C, 0x39, 0xA7, 0x4D, 0xFA, 0x5A, 0xB6, 0x73, 0x04, 0x25, 0x66, 0xEB, + 0x77, 0x7F, 0xE7, 0x59, 0xC6, 0x4A, 0x99, 0x25, 0x14, 0x54, 0xEB, 0x26, + 0xC7, 0xF3, 0x7F, 0x19, 0xD5, 0x30, 0x70, 0x8F, 0xAF, 0xB0, 0x46, 0x2A, + 0xFF, 0xAD, 0xEB, 0x29, 0xED, 0xD7, 0x9F, 0xAA, 0x04, 0x87, 0xA3, 0xD4, + 0xF9, 0x89, 0xA5, 0x34, 0x5F, 0xDB, 0x43, 0x91, 0x82, 0x36, 0xD9, 0x66, + 0x3C, 0xB1, 0xB8, 0xB9, 0x82, 0xFD, 0x9C, 0x3A, 0x3E, 0x10, 0xC8, 0x3B, + 0xEF, 0x06, 0x65, 0x66, 0x7A, 0x9B, 0x19, 0x18, 0x3D, 0xFF, 0x71, 0x51, + 0x3C, 0x30, 0x2E, 0x5F, 0xBE, 0x3D, 0x77, 0x73, 0xB2, 0x5D, 0x06, 0x6C, + 0xC3, 0x23, 0x56, 0x9A, 0x2B, 0x85, 0x26, 0x92, 0x1C, 0xA7, 0x02, 0xB3, + 0xE4, 0x3F, 0x0D, 0xAF, 0x08, 0x79, 0x82, 0xB8, 0x36, 0x3D, 0xEA, 0x9C, + 0xD3, 0x35, 0xB3, 0xBC, 0x69, 0xCA, 0xF5, 0xCC, 0x9D, 0xE8, 0xFD, 0x64, + 0x8D, 0x17, 0x80, 0x33, 0x6E, 0x5E, 0x4A, 0x5D, 0x99, 0xC9, 0x1E, 0x87, + 0xB4, 0x9D, 0x1A, 0xC0, 0xD5, 0x6E, 0x13, 0x35, 0x23, 0x5E, 0xDF, 0x9B, + 0x5F, 0x3D, 0xEF, 0xD6, 0xF7, 0x76, 0xC2, 0xEA, 0x3E, 0xBB, 0x78, 0x0D, + 0x1C, 0x42, 0x67, 0x6B, 0x04, 0xD8, 0xF8, 0xD6, 0xDA, 0x6F, 0x8B, 0xF2, + 0x44, 0xA0, 0x01, 0xAB +}; + +static const unsigned char TA508_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA509_DN[] = { + 0x30, 0x81, 0x8F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, + 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA509_RSA_N[] = { + 0xBD, 0xED, 0xC1, 0x03, 0xFC, 0xF6, 0x8F, 0xFC, 0x02, 0xB1, 0x6F, 0x5B, + 0x9F, 0x48, 0xD9, 0x9D, 0x79, 0xE2, 0xA2, 0xB7, 0x03, 0x61, 0x56, 0x18, + 0xC3, 0x47, 0xB6, 0xD7, 0xCA, 0x3D, 0x35, 0x2E, 0x89, 0x43, 0xF7, 0xA1, + 0x69, 0x9B, 0xDE, 0x8A, 0x1A, 0xFD, 0x13, 0x20, 0x9C, 0xB4, 0x49, 0x77, + 0x32, 0x29, 0x56, 0xFD, 0xB9, 0xEC, 0x8C, 0xDD, 0x22, 0xFA, 0x72, 0xDC, + 0x27, 0x61, 0x97, 0xEE, 0xF6, 0x5A, 0x84, 0xEC, 0x6E, 0x19, 0xB9, 0x89, + 0x2C, 0xDC, 0x84, 0x5B, 0xD5, 0x74, 0xFB, 0x6B, 0x5F, 0xC5, 0x89, 0xA5, + 0x10, 0x52, 0x89, 0x46, 0x55, 0xF4, 0xB8, 0x75, 0x1C, 0xE6, 0x7F, 0xE4, + 0x54, 0xAE, 0x4B, 0xF8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xF8, 0x17, 0x71, + 0x59, 0xEB, 0x1E, 0x28, 0x07, 0x74, 0xC5, 0x9D, 0x48, 0xBE, 0x6C, 0xB4, + 0xF4, 0xA4, 0xB0, 0xF3, 0x64, 0x37, 0x79, 0x92, 0xC0, 0xEC, 0x46, 0x5E, + 0x7F, 0xE1, 0x6D, 0x53, 0x4C, 0x62, 0xAF, 0xCD, 0x1F, 0x0B, 0x63, 0xBB, + 0x3A, 0x9D, 0xFB, 0xFC, 0x79, 0x00, 0x98, 0x61, 0x74, 0xCF, 0x26, 0x82, + 0x40, 0x63, 0xF3, 0xB2, 0x72, 0x6A, 0x19, 0x0D, 0x99, 0xCA, 0xD4, 0x0E, + 0x75, 0xCC, 0x37, 0xFB, 0x8B, 0x89, 0xC1, 0x59, 0xF1, 0x62, 0x7F, 0x5F, + 0xB3, 0x5F, 0x65, 0x30, 0xF8, 0xA7, 0xB7, 0x4D, 0x76, 0x5A, 0x1E, 0x76, + 0x5E, 0x34, 0xC0, 0xE8, 0x96, 0x56, 0x99, 0x8A, 0xB3, 0xF0, 0x7F, 0xA4, + 0xCD, 0xBD, 0xDC, 0x32, 0x31, 0x7C, 0x91, 0xCF, 0xE0, 0x5F, 0x11, 0xF8, + 0x6B, 0xAA, 0x49, 0x5C, 0xD1, 0x99, 0x94, 0xD1, 0xA2, 0xE3, 0x63, 0x5B, + 0x09, 0x76, 0xB5, 0x56, 0x62, 0xE1, 0x4B, 0x74, 0x1D, 0x96, 0xD4, 0x26, + 0xD4, 0x08, 0x04, 0x59, 0xD0, 0x98, 0x0E, 0x0E, 0xE6, 0xDE, 0xFC, 0xC3, + 0xEC, 0x1F, 0x90, 0xF1 +}; + +static const unsigned char TA509_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA510_DN[] = { + 0x30, 0x81, 0x98, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3B, + 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA510_RSA_N[] = { + 0xD5, 0x0C, 0x3A, 0xC4, 0x2A, 0xF9, 0x4E, 0xE2, 0xF5, 0xBE, 0x19, 0x97, + 0x5F, 0x8E, 0x88, 0x53, 0xB1, 0x1F, 0x3F, 0xCB, 0xCF, 0x9F, 0x20, 0x13, + 0x6D, 0x29, 0x3A, 0xC8, 0x0F, 0x7D, 0x3C, 0xF7, 0x6B, 0x76, 0x38, 0x63, + 0xD9, 0x36, 0x60, 0xA8, 0x9B, 0x5E, 0x5C, 0x00, 0x80, 0xB2, 0x2F, 0x59, + 0x7F, 0xF6, 0x87, 0xF9, 0x25, 0x43, 0x86, 0xE7, 0x69, 0x1B, 0x52, 0x9A, + 0x90, 0xE1, 0x71, 0xE3, 0xD8, 0x2D, 0x0D, 0x4E, 0x6F, 0xF6, 0xC8, 0x49, + 0xD9, 0xB6, 0xF3, 0x1A, 0x56, 0xAE, 0x2B, 0xB6, 0x74, 0x14, 0xEB, 0xCF, + 0xFB, 0x26, 0xE3, 0x1A, 0xBA, 0x1D, 0x96, 0x2E, 0x6A, 0x3B, 0x58, 0x94, + 0x89, 0x47, 0x56, 0xFF, 0x25, 0xA0, 0x93, 0x70, 0x53, 0x83, 0xDA, 0x84, + 0x74, 0x14, 0xC3, 0x67, 0x9E, 0x04, 0x68, 0x3A, 0xDF, 0x8E, 0x40, 0x5A, + 0x1D, 0x4A, 0x4E, 0xCF, 0x43, 0x91, 0x3B, 0xE7, 0x56, 0xD6, 0x00, 0x70, + 0xCB, 0x52, 0xEE, 0x7B, 0x7D, 0xAE, 0x3A, 0xE7, 0xBC, 0x31, 0xF9, 0x45, + 0xF6, 0xC2, 0x60, 0xCF, 0x13, 0x59, 0x02, 0x2B, 0x80, 0xCC, 0x34, 0x47, + 0xDF, 0xB9, 0xDE, 0x90, 0x65, 0x6D, 0x02, 0xCF, 0x2C, 0x91, 0xA6, 0xA6, + 0xE7, 0xDE, 0x85, 0x18, 0x49, 0x7C, 0x66, 0x4E, 0xA3, 0x3A, 0x6D, 0xA9, + 0xB5, 0xEE, 0x34, 0x2E, 0xBA, 0x0D, 0x03, 0xB8, 0x33, 0xDF, 0x47, 0xEB, + 0xB1, 0x6B, 0x8D, 0x25, 0xD9, 0x9B, 0xCE, 0x81, 0xD1, 0x45, 0x46, 0x32, + 0x96, 0x70, 0x87, 0xDE, 0x02, 0x0E, 0x49, 0x43, 0x85, 0xB6, 0x6C, 0x73, + 0xBB, 0x64, 0xEA, 0x61, 0x41, 0xAC, 0xC9, 0xD4, 0x54, 0xDF, 0x87, 0x2F, + 0xC7, 0x22, 0xB2, 0x26, 0xCC, 0x9F, 0x59, 0x54, 0x68, 0x9F, 0xFC, 0xBE, + 0x2A, 0x2F, 0xC4, 0x55, 0x1C, 0x75, 0x40, 0x60, 0x17, 0x85, 0x02, 0x55, + 0x39, 0x8B, 0x7F, 0x05 +}; + +static const unsigned char TA510_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA511_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x41, 0x47, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x16, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, + 0x6F, 0x6C, 0x64, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA511_RSA_N[] = { + 0xAF, 0xE4, 0xEE, 0x7E, 0x8B, 0x24, 0x0E, 0x12, 0x6E, 0xA9, 0x50, 0x2D, + 0x16, 0x44, 0x3B, 0x92, 0x92, 0x5C, 0xCA, 0xB8, 0x5D, 0x84, 0x92, 0x42, + 0x13, 0x2A, 0xBC, 0x65, 0x57, 0x82, 0x40, 0x3E, 0x57, 0x24, 0xCD, 0x50, + 0x8B, 0x25, 0x2A, 0xB7, 0x6F, 0xFC, 0xEF, 0xA2, 0xD0, 0xC0, 0x1F, 0x02, + 0x24, 0x4A, 0x13, 0x96, 0x8F, 0x23, 0x13, 0xE6, 0x28, 0x58, 0x00, 0xA3, + 0x47, 0xC7, 0x06, 0xA7, 0x84, 0x23, 0x2B, 0xBB, 0xBD, 0x96, 0x2B, 0x7F, + 0x55, 0xCC, 0x8B, 0xC1, 0x57, 0x1F, 0x0E, 0x62, 0x65, 0x0F, 0xDD, 0x3D, + 0x56, 0x8A, 0x73, 0xDA, 0xAE, 0x7E, 0x6D, 0xBA, 0x81, 0x1C, 0x7E, 0x42, + 0x8C, 0x20, 0x35, 0xD9, 0x43, 0x4D, 0x84, 0xFA, 0x84, 0xDB, 0x52, 0x2C, + 0xF3, 0x0E, 0x27, 0x77, 0x0B, 0x6B, 0xBF, 0x11, 0x2F, 0x72, 0x78, 0x9F, + 0x2E, 0xD8, 0x3E, 0xE6, 0x18, 0x37, 0x5A, 0x2A, 0x72, 0xF9, 0xDA, 0x62, + 0x90, 0x92, 0x95, 0xCA, 0x1F, 0x9C, 0xE9, 0xB3, 0x3C, 0x2B, 0xCB, 0xF3, + 0x01, 0x13, 0xBF, 0x5A, 0xCF, 0xC1, 0xB5, 0x0A, 0x60, 0xBD, 0xDD, 0xB5, + 0x99, 0x64, 0x53, 0xB8, 0xA0, 0x96, 0xB3, 0x6F, 0xE2, 0x26, 0x77, 0x91, + 0x8C, 0xE0, 0x62, 0x10, 0x02, 0x9F, 0x34, 0x0F, 0xA4, 0xD5, 0x92, 0x33, + 0x51, 0xDE, 0xBE, 0x8D, 0xBA, 0x84, 0x7A, 0x60, 0x3C, 0x6A, 0xDB, 0x9F, + 0x2B, 0xEC, 0xDE, 0xDE, 0x01, 0x3F, 0x6E, 0x4D, 0xE5, 0x50, 0x86, 0xCB, + 0xB4, 0xAF, 0xED, 0x44, 0x40, 0xC5, 0xCA, 0x5A, 0x8C, 0xDA, 0xD2, 0x2B, + 0x7C, 0xA8, 0xEE, 0xBE, 0xA6, 0xE5, 0x0A, 0xAA, 0x0E, 0xA5, 0xDF, 0x05, + 0x52, 0xB7, 0x55, 0xC7, 0x22, 0x5D, 0x32, 0x6A, 0x97, 0x97, 0x63, 0x13, + 0xDB, 0xC9, 0xDB, 0x79, 0x36, 0x7B, 0x85, 0x3A, 0x4A, 0xC5, 0x52, 0x89, + 0xF9, 0x24, 0xE7, 0x9D, 0x77, 0xA9, 0x82, 0xFF, 0x55, 0x1C, 0xA5, 0x71, + 0x69, 0x2B, 0xD1, 0x02, 0x24, 0xF2, 0xB3, 0x26, 0xD4, 0x6B, 0xDA, 0x04, + 0x55, 0xE5, 0xC1, 0x0A, 0xC7, 0x6D, 0x30, 0x37, 0x90, 0x2A, 0xE4, 0x9E, + 0x14, 0x33, 0x5E, 0x16, 0x17, 0x55, 0xC5, 0x5B, 0xB5, 0xCB, 0x34, 0x89, + 0x92, 0xF1, 0x9D, 0x26, 0x8F, 0xA1, 0x07, 0xD4, 0xC6, 0xB2, 0x78, 0x50, + 0xDB, 0x0C, 0x0C, 0x0B, 0x7C, 0x0B, 0x8C, 0x41, 0xD7, 0xB9, 0xE9, 0xDD, + 0x8C, 0x88, 0xF7, 0xA3, 0x4D, 0xB2, 0x32, 0xCC, 0xD8, 0x17, 0xDA, 0xCD, + 0xB7, 0xCE, 0x66, 0x9D, 0xD4, 0xFD, 0x5E, 0xFF, 0xBD, 0x97, 0x3E, 0x29, + 0x75, 0xE7, 0x7E, 0xA7, 0x62, 0x58, 0xAF, 0x25, 0x34, 0xA5, 0x41, 0xC7, + 0x3D, 0xBC, 0x0D, 0x50, 0xCA, 0x03, 0x03, 0x0F, 0x08, 0x5A, 0x1F, 0x95, + 0x73, 0x78, 0x62, 0xBF, 0xAF, 0x72, 0x14, 0x69, 0x0E, 0xA5, 0xE5, 0x03, + 0x0E, 0x78, 0x8E, 0x26, 0x28, 0x42, 0xF0, 0x07, 0x0B, 0x62, 0x20, 0x10, + 0x67, 0x39, 0x46, 0xFA, 0xA9, 0x03, 0xCC, 0x04, 0x38, 0x7A, 0x66, 0xEF, + 0x20, 0x83, 0xB5, 0x8C, 0x4A, 0x56, 0x8E, 0x91, 0x00, 0xFC, 0x8E, 0x5C, + 0x82, 0xDE, 0x88, 0xA0, 0xC3, 0xE2, 0x68, 0x6E, 0x7D, 0x8D, 0xEF, 0x3C, + 0xDD, 0x65, 0xF4, 0x5D, 0xAC, 0x51, 0xEF, 0x24, 0x80, 0xAE, 0xAA, 0x56, + 0x97, 0x6F, 0xF9, 0xAD, 0x7D, 0xDA, 0x61, 0x3F, 0x98, 0x77, 0x3C, 0xA5, + 0x91, 0xB6, 0x1C, 0x8C, 0x26, 0xDA, 0x65, 0xA2, 0x09, 0x6D, 0xC1, 0xE2, + 0x54, 0xE3, 0xB9, 0xCA, 0x4C, 0x4C, 0x80, 0x8F, 0x77, 0x7B, 0x60, 0x9A, + 0x1E, 0xDF, 0xB6, 0xF2, 0x48, 0x1E, 0x0E, 0xBA, 0x4E, 0x54, 0x6D, 0x98, + 0xE0, 0xE1, 0xA2, 0x1A, 0xA2, 0x77, 0x50, 0xCF, 0xC4, 0x63, 0x92, 0xEC, + 0x47, 0x19, 0x9D, 0xEB, 0xE6, 0x6B, 0xCE, 0xC1 +}; + +static const unsigned char TA511_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA512_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x32 +}; + +static const unsigned char TA512_RSA_N[] = { + 0xAA, 0x5F, 0xDA, 0x1B, 0x5F, 0xE8, 0x73, 0x91, 0xE5, 0xDA, 0x5C, 0xF4, + 0xA2, 0xE6, 0x47, 0xE5, 0xF3, 0x68, 0x55, 0x60, 0x05, 0x1D, 0x02, 0xA4, + 0xB3, 0x9B, 0x59, 0xF3, 0x1E, 0x8A, 0xAF, 0x34, 0xAD, 0xFC, 0x0D, 0xC2, + 0xD9, 0x48, 0x19, 0xEE, 0x69, 0x8F, 0xC9, 0x20, 0xFC, 0x21, 0xAA, 0x07, + 0x19, 0xED, 0xB0, 0x5C, 0xAC, 0x65, 0xC7, 0x5F, 0xED, 0x02, 0x7C, 0x7B, + 0x7C, 0x2D, 0x1B, 0xD6, 0xBA, 0xB9, 0x80, 0xC2, 0x18, 0x82, 0x16, 0x84, + 0xFA, 0x66, 0xB0, 0x08, 0xC6, 0x54, 0x23, 0x81, 0xE4, 0xCD, 0xB9, 0x49, + 0x3F, 0xF6, 0x4F, 0x6E, 0x37, 0x48, 0x28, 0x38, 0x0F, 0xC5, 0xBE, 0xE7, + 0x68, 0x70, 0xFD, 0x39, 0x97, 0x4D, 0xD2, 0xC7, 0x98, 0x91, 0x50, 0xAA, + 0xC4, 0x44, 0xB3, 0x23, 0x7D, 0x39, 0x47, 0xE9, 0x52, 0x62, 0xD6, 0x12, + 0x93, 0x5E, 0xB7, 0x31, 0x96, 0x42, 0x05, 0xFB, 0x76, 0xA7, 0x1E, 0xA3, + 0xF5, 0xC2, 0xFC, 0xE9, 0x7A, 0xC5, 0x6C, 0xA9, 0x71, 0x4F, 0xEA, 0xCB, + 0x78, 0xBC, 0x60, 0xAF, 0xC7, 0xDE, 0xF4, 0xD9, 0xCB, 0xBE, 0x7E, 0x33, + 0xA5, 0x6E, 0x94, 0x83, 0xF0, 0x34, 0xFA, 0x21, 0xAB, 0xEA, 0x8E, 0x72, + 0xA0, 0x3F, 0xA4, 0xDE, 0x30, 0x5B, 0xEF, 0x86, 0x4D, 0x6A, 0x95, 0x5B, + 0x43, 0x44, 0xA8, 0x10, 0x15, 0x1C, 0xE5, 0x01, 0x57, 0xC5, 0x98, 0xF1, + 0xE6, 0x06, 0x28, 0x91, 0xAA, 0x20, 0xC5, 0xB7, 0x53, 0x26, 0x51, 0x43, + 0xB2, 0x0B, 0x11, 0x95, 0x58, 0xE1, 0xC0, 0x0F, 0x76, 0xD9, 0xC0, 0x8D, + 0x7C, 0x81, 0xF3, 0x72, 0x70, 0x9E, 0x6F, 0xFE, 0x1A, 0x8E, 0xD9, 0x5F, + 0x35, 0xC6, 0xB2, 0x6F, 0x34, 0x7C, 0xBE, 0x48, 0x4F, 0xE2, 0x5A, 0x39, + 0xD7, 0xD8, 0x9D, 0x78, 0x9E, 0x9F, 0x86, 0x3E, 0x03, 0x5E, 0x19, 0x8B, + 0x44, 0xA2, 0xD5, 0xC7 +}; + +static const unsigned char TA512_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA513_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x33 +}; + +static const unsigned char TA513_RSA_N[] = { + 0xBD, 0x75, 0x93, 0xF0, 0x62, 0x22, 0x6F, 0x24, 0xAE, 0xE0, 0x7A, 0x76, + 0xAC, 0x7D, 0xBD, 0xD9, 0x24, 0xD5, 0xB8, 0xB7, 0xFC, 0xCD, 0xF0, 0x42, + 0xE0, 0xEB, 0x78, 0x88, 0x56, 0x5E, 0x9B, 0x9A, 0x54, 0x1D, 0x4D, 0x0C, + 0x8A, 0xF6, 0xD3, 0xCF, 0x70, 0xF4, 0x52, 0xB5, 0xD8, 0x93, 0x04, 0xE3, + 0x46, 0x86, 0x71, 0x41, 0x4A, 0x2B, 0xF0, 0x2A, 0x2C, 0x55, 0x03, 0xD6, + 0x48, 0xC3, 0xE0, 0x39, 0x38, 0xED, 0xF2, 0x5C, 0x3C, 0x3F, 0x44, 0xBC, + 0x93, 0x3D, 0x61, 0xAB, 0x4E, 0xCD, 0x0D, 0xBE, 0xF0, 0x20, 0x27, 0x58, + 0x0E, 0x44, 0x7F, 0x04, 0x1A, 0x87, 0xA5, 0xD7, 0x96, 0x14, 0x36, 0x90, + 0xD0, 0x49, 0x7B, 0xA1, 0x75, 0xFB, 0x1A, 0x6B, 0x73, 0xB1, 0xF8, 0xCE, + 0xA9, 0x09, 0x2C, 0xF2, 0x53, 0xD5, 0xC3, 0x14, 0x44, 0xB8, 0x86, 0xA5, + 0xF6, 0x8B, 0x2B, 0x39, 0xDA, 0xA3, 0x33, 0x54, 0xD9, 0xFA, 0x72, 0x1A, + 0xF7, 0x22, 0x15, 0x1C, 0x88, 0x91, 0x6B, 0x7F, 0x66, 0xE5, 0xC3, 0x6A, + 0x80, 0xB0, 0x24, 0xF3, 0xDF, 0x86, 0x45, 0x88, 0xFD, 0x19, 0x7F, 0x75, + 0x87, 0x1F, 0x1F, 0xB1, 0x1B, 0x0A, 0x73, 0x24, 0x5B, 0xB9, 0x65, 0xE0, + 0x2C, 0x54, 0xC8, 0x60, 0xD3, 0x66, 0x17, 0x3F, 0xE1, 0xCC, 0x54, 0x33, + 0x73, 0x91, 0x02, 0x3A, 0xA6, 0x7F, 0x7B, 0x76, 0x39, 0xA2, 0x1F, 0x96, + 0xB6, 0x38, 0xAE, 0xB5, 0xC8, 0x93, 0x74, 0x1D, 0x9E, 0xB9, 0xB4, 0xE5, + 0x60, 0x9D, 0x2F, 0x56, 0xD1, 0xE0, 0xEB, 0x5E, 0x5B, 0x4C, 0x12, 0x70, + 0x0C, 0x6C, 0x44, 0x20, 0xAB, 0x11, 0xD8, 0xF4, 0x19, 0xF6, 0xD2, 0x9C, + 0x52, 0x37, 0xE7, 0xFA, 0xB6, 0xC2, 0x31, 0x3B, 0x4A, 0xD4, 0x14, 0x99, + 0xAD, 0xC7, 0x1A, 0xF5, 0x5D, 0x5F, 0xFA, 0x07, 0xB8, 0x7C, 0x0D, 0x1F, + 0xD6, 0x83, 0x1E, 0xB3 +}; + +static const unsigned char TA513_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA514_DN[] = { + 0x30, 0x81, 0xD2, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x54, 0x52, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x0F, 0x47, 0x65, 0x62, 0x7A, 0x65, 0x20, 0x2D, 0x20, 0x4B, + 0x6F, 0x63, 0x61, 0x65, 0x6C, 0x69, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x13, 0x39, 0x54, 0x75, 0x72, 0x6B, 0x69, 0x79, 0x65, + 0x20, 0x42, 0x69, 0x6C, 0x69, 0x6D, 0x73, 0x65, 0x6C, 0x20, 0x76, 0x65, + 0x20, 0x54, 0x65, 0x6B, 0x6E, 0x6F, 0x6C, 0x6F, 0x6A, 0x69, 0x6B, 0x20, + 0x41, 0x72, 0x61, 0x73, 0x74, 0x69, 0x72, 0x6D, 0x61, 0x20, 0x4B, 0x75, + 0x72, 0x75, 0x6D, 0x75, 0x20, 0x2D, 0x20, 0x54, 0x55, 0x42, 0x49, 0x54, + 0x41, 0x4B, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x24, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x6B, 0x61, 0x73, 0x79, 0x6F, 0x6E, 0x20, 0x4D, 0x65, 0x72, 0x6B, + 0x65, 0x7A, 0x69, 0x20, 0x2D, 0x20, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, + 0x4D, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, + 0x54, 0x55, 0x42, 0x49, 0x54, 0x41, 0x4B, 0x20, 0x4B, 0x61, 0x6D, 0x75, + 0x20, 0x53, 0x4D, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x4B, 0x6F, 0x6B, 0x20, + 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6B, 0x61, 0x73, 0x69, 0x20, + 0x2D, 0x20, 0x53, 0x75, 0x72, 0x75, 0x6D, 0x20, 0x31 +}; + +static const unsigned char TA514_RSA_N[] = { + 0xAF, 0x75, 0x30, 0x33, 0xAA, 0xBB, 0x6B, 0xD3, 0x99, 0x2C, 0x12, 0x37, + 0x84, 0xD9, 0x8D, 0x7B, 0x97, 0x80, 0xD3, 0x6E, 0xE7, 0xFF, 0x9B, 0x50, + 0x95, 0x3E, 0x90, 0x95, 0x56, 0x42, 0xD7, 0x19, 0x7C, 0x26, 0x84, 0x8D, + 0x92, 0xFA, 0x01, 0x1D, 0x3A, 0x0F, 0xE2, 0x64, 0x38, 0xB7, 0x8C, 0xBC, + 0xE8, 0x88, 0xF9, 0x8B, 0x24, 0xAB, 0x2E, 0xA3, 0xF5, 0x37, 0xE4, 0x40, + 0x8E, 0x18, 0x25, 0x79, 0x83, 0x75, 0x1F, 0x3B, 0xFF, 0x6C, 0xA8, 0xC5, + 0xC6, 0x56, 0xF8, 0xB4, 0xED, 0x8A, 0x44, 0xA3, 0xAB, 0x6C, 0x4C, 0xFC, + 0x1D, 0xD0, 0xDC, 0xEF, 0x68, 0xBD, 0xCF, 0xE4, 0xAA, 0xCE, 0xF0, 0x55, + 0xF7, 0xA2, 0x34, 0xD4, 0x83, 0x6B, 0x37, 0x7C, 0x1C, 0xC2, 0xFE, 0xB5, + 0x03, 0xEC, 0x57, 0xCE, 0xBC, 0xB4, 0xB5, 0xC5, 0xED, 0x00, 0x0F, 0x53, + 0x37, 0x2A, 0x4D, 0xF4, 0x4F, 0x0C, 0x83, 0xFB, 0x86, 0xCF, 0xCB, 0xFE, + 0x8C, 0x4E, 0xBD, 0x87, 0xF9, 0xA7, 0x8B, 0x21, 0x57, 0x9C, 0x7A, 0xDF, + 0x03, 0x67, 0x89, 0x2C, 0x9D, 0x97, 0x61, 0xA7, 0x10, 0xB8, 0x55, 0x90, + 0x7F, 0x0E, 0x2D, 0x27, 0x38, 0x74, 0xDF, 0xE7, 0xFD, 0xDA, 0x4E, 0x12, + 0xE3, 0x4D, 0x15, 0x22, 0x02, 0xC8, 0xE0, 0xE0, 0xFC, 0x0F, 0xAD, 0x8A, + 0xD7, 0xC9, 0x54, 0x50, 0xCC, 0x3B, 0x0F, 0xCA, 0x16, 0x80, 0x84, 0xD0, + 0x51, 0x56, 0xC3, 0x8E, 0x56, 0x7F, 0x89, 0x22, 0x33, 0x2F, 0xE6, 0x85, + 0x0A, 0xBD, 0xA5, 0xA8, 0x1B, 0x36, 0xDE, 0xD3, 0xDC, 0x2C, 0x6D, 0x3B, + 0xC7, 0x13, 0xBD, 0x59, 0x23, 0x2C, 0xE6, 0xE5, 0xA4, 0xF7, 0xD8, 0x0B, + 0xED, 0xEA, 0x90, 0x40, 0x44, 0xA8, 0x95, 0xBB, 0x93, 0xD5, 0xD0, 0x80, + 0x34, 0xB6, 0x46, 0x78, 0x0E, 0x1F, 0x00, 0x93, 0x46, 0xE1, 0xEE, 0xE9, + 0xF9, 0xEC, 0x4F, 0x17 +}; + +static const unsigned char TA514_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA515_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x54, 0x57, 0x43, 0x41, 0x20, 0x43, 0x59, 0x42, + 0x45, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA515_RSA_N[] = { + 0xC6, 0xF8, 0xCA, 0x1E, 0xD9, 0x09, 0x20, 0x7E, 0x1D, 0x6C, 0x4E, 0xCE, + 0x8F, 0xE3, 0x47, 0x33, 0x44, 0x9C, 0xC7, 0xC9, 0x69, 0xAA, 0x3A, 0x5B, + 0x78, 0xEE, 0x70, 0xD2, 0x92, 0xF8, 0x04, 0xB3, 0x52, 0x52, 0x1D, 0x67, + 0x72, 0x28, 0xA1, 0xDF, 0x8B, 0x5D, 0x95, 0x0A, 0xFE, 0xEA, 0xCD, 0xED, + 0xF7, 0x29, 0xCE, 0xF0, 0x6F, 0x7F, 0xAC, 0xCD, 0x3D, 0xEF, 0xB3, 0x1C, + 0x45, 0x6A, 0xF7, 0x28, 0x90, 0xF1, 0x61, 0x57, 0xC5, 0x0C, 0xC4, 0xA3, + 0x50, 0x5D, 0xDE, 0xD4, 0xB5, 0xCB, 0x19, 0xCA, 0x80, 0xB9, 0x75, 0xCE, + 0x29, 0xCE, 0xD2, 0x85, 0x22, 0xEC, 0x02, 0x63, 0xCC, 0x44, 0x30, 0x20, + 0xDA, 0xEA, 0x91, 0x5B, 0x56, 0xE6, 0x1D, 0x1C, 0xD5, 0x9D, 0x66, 0xC7, + 0x3F, 0xDF, 0x86, 0xCA, 0x4B, 0x53, 0xC4, 0xD9, 0x8D, 0xB2, 0x1D, 0xEA, + 0xF8, 0xDC, 0x27, 0x53, 0xA3, 0x47, 0xE1, 0x61, 0xCC, 0x7D, 0xB5, 0xB0, + 0xF8, 0xEE, 0x73, 0x91, 0xC5, 0xCE, 0x73, 0x6F, 0xCE, 0xEE, 0x10, 0x1F, + 0x1A, 0x06, 0xCF, 0xE9, 0x27, 0x60, 0xC5, 0x4F, 0x19, 0xE4, 0xEB, 0xCE, + 0x22, 0x26, 0x45, 0xD7, 0x60, 0x99, 0xDD, 0xCE, 0x4F, 0x37, 0xE0, 0x7F, + 0xE7, 0x63, 0xAD, 0xB0, 0xB8, 0x59, 0xB8, 0xD0, 0x06, 0x68, 0x35, 0x60, + 0xD3, 0x36, 0xAE, 0x71, 0x43, 0x04, 0xF1, 0x69, 0x65, 0x78, 0x7C, 0xF3, + 0x1F, 0xF3, 0xCA, 0x28, 0x9F, 0x5A, 0x20, 0x95, 0x66, 0xB4, 0xCD, 0xB7, + 0xEE, 0x8F, 0x78, 0xA4, 0x45, 0x18, 0xE9, 0x26, 0x2F, 0x8D, 0x9B, 0x29, + 0x28, 0xB1, 0xA4, 0xB7, 0x3A, 0x6D, 0xB9, 0xD4, 0x1C, 0x38, 0x72, 0x45, + 0x58, 0xB1, 0x5E, 0xEB, 0xF0, 0x28, 0x9B, 0xB7, 0x82, 0xCA, 0xFD, 0xCF, + 0xD6, 0x33, 0x0F, 0x9F, 0xFB, 0x97, 0x9E, 0xB1, 0x1C, 0x9C, 0x9E, 0xEA, + 0x5F, 0x5E, 0xDB, 0xAA, 0xDD, 0x54, 0xE9, 0x30, 0x21, 0x28, 0x6D, 0x8E, + 0x79, 0xF3, 0x75, 0x92, 0x8C, 0x26, 0xFE, 0xDC, 0xC5, 0xF6, 0xC3, 0xB0, + 0xDF, 0x44, 0x59, 0x43, 0xA3, 0xB6, 0x03, 0x28, 0xF6, 0x08, 0x30, 0xAA, + 0x0D, 0x33, 0xE1, 0xEF, 0x9C, 0xA9, 0x07, 0x22, 0xE3, 0x59, 0x5B, 0x40, + 0x8F, 0xDA, 0x88, 0xB7, 0x69, 0x08, 0xA8, 0xB7, 0x23, 0x2E, 0x44, 0x09, + 0x59, 0x37, 0x5B, 0xC7, 0xE3, 0x17, 0xF2, 0x22, 0xEB, 0x6E, 0x39, 0x52, + 0xC5, 0xDE, 0x54, 0xA7, 0x98, 0xC9, 0x4B, 0x20, 0x95, 0xDC, 0x46, 0x89, + 0x5F, 0xB4, 0x12, 0xF9, 0x85, 0x29, 0x8E, 0xEB, 0xC8, 0x27, 0x15, 0x20, + 0xC0, 0x4B, 0xD4, 0xCC, 0x7C, 0x0C, 0x6C, 0x34, 0x0C, 0x26, 0x9B, 0x26, + 0x31, 0xA6, 0x3C, 0xA7, 0xF6, 0xD9, 0xD0, 0x4B, 0xA2, 0x64, 0xFF, 0x3B, + 0x99, 0x41, 0x72, 0xC1, 0xE0, 0x70, 0x97, 0xF1, 0x24, 0xBB, 0x2B, 0xC4, + 0x74, 0x22, 0xB1, 0xAC, 0x6B, 0x22, 0x32, 0x24, 0xD3, 0x78, 0x2A, 0xC0, + 0xC0, 0xA1, 0x2F, 0xF1, 0x52, 0x05, 0xC9, 0x3F, 0xEF, 0x76, 0x66, 0xE2, + 0x45, 0xD8, 0x0D, 0x3D, 0xAD, 0x95, 0xC8, 0xC7, 0x89, 0x26, 0xC8, 0x0F, + 0xAE, 0xA7, 0x03, 0x2E, 0xFB, 0xC1, 0x5F, 0xFA, 0x20, 0xE1, 0x70, 0xAD, + 0xB0, 0x65, 0x20, 0x37, 0x33, 0x60, 0xB0, 0xD5, 0xAF, 0xD7, 0x0C, 0x1C, + 0xC2, 0x90, 0x70, 0xD7, 0x4A, 0x18, 0xBC, 0x7E, 0x01, 0xB0, 0xB0, 0xEB, + 0x15, 0x1E, 0x44, 0x06, 0xCD, 0xA4, 0x4F, 0xE8, 0x0C, 0xD1, 0xC3, 0x20, + 0x10, 0xE1, 0x54, 0x65, 0x9E, 0xB6, 0x51, 0xD0, 0x1A, 0x76, 0x6B, 0x42, + 0x5A, 0x58, 0x76, 0x34, 0xEA, 0xB7, 0x37, 0x19, 0xAE, 0x2E, 0x75, 0xF9, + 0x96, 0xE5, 0xC1, 0x59, 0xF7, 0x94, 0x57, 0x29, 0x25, 0x8D, 0x3A, 0x4C, + 0xAB, 0x4D, 0x9A, 0x41, 0xD0, 0x5F, 0x26, 0x03 +}; + +static const unsigned char TA515_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA516_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x13, 0x54, 0x57, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, + 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA516_RSA_N[] = { + 0xB0, 0x05, 0xDB, 0xC8, 0xEB, 0x8C, 0xC4, 0x6E, 0x8A, 0x21, 0xEF, 0x8E, + 0x4D, 0x9C, 0x71, 0x0A, 0x1F, 0x52, 0x70, 0xED, 0x6D, 0x82, 0x9C, 0x97, + 0xC5, 0xD7, 0x4C, 0x4E, 0x45, 0x49, 0xCB, 0x40, 0x42, 0xB5, 0x12, 0x34, + 0x6C, 0x19, 0xC2, 0x74, 0xA4, 0x31, 0x5F, 0x85, 0x02, 0x97, 0xEC, 0x43, + 0x33, 0x0A, 0x53, 0xD2, 0x9C, 0x8C, 0x8E, 0xB7, 0xB8, 0x79, 0xDB, 0x2B, + 0xD5, 0x6A, 0xF2, 0x8E, 0x66, 0xC4, 0xEE, 0x2B, 0x01, 0x07, 0x92, 0xD4, + 0xB3, 0xD0, 0x02, 0xDF, 0x50, 0xF6, 0x55, 0xAF, 0x66, 0x0E, 0xCB, 0xE0, + 0x47, 0x60, 0x2F, 0x2B, 0x32, 0x39, 0x35, 0x52, 0x3A, 0x28, 0x83, 0xF8, + 0x7B, 0x16, 0xC6, 0x18, 0xB8, 0x62, 0xD6, 0x47, 0x25, 0x91, 0xCE, 0xF0, + 0x19, 0x12, 0x4D, 0xAD, 0x63, 0xF5, 0xD3, 0x3F, 0x75, 0x5F, 0x29, 0xF0, + 0xA1, 0x30, 0x1C, 0x2A, 0xA0, 0x98, 0xA6, 0x15, 0xBD, 0xEE, 0xFD, 0x19, + 0x36, 0xF0, 0xE2, 0x91, 0x43, 0x8F, 0xFA, 0xCA, 0xD6, 0x10, 0x27, 0x49, + 0x4C, 0xEF, 0xDD, 0xC1, 0xF1, 0x85, 0x70, 0x9B, 0xCA, 0xEA, 0xA8, 0x5A, + 0x43, 0xFC, 0x6D, 0x86, 0x6F, 0x73, 0xE9, 0x37, 0x45, 0xA9, 0xF0, 0x36, + 0xC7, 0xCC, 0x88, 0x75, 0x1E, 0xBB, 0x6C, 0x06, 0xFF, 0x9B, 0x6B, 0x3E, + 0x17, 0xEC, 0x61, 0xAA, 0x71, 0x7C, 0xC6, 0x1D, 0xA2, 0xF7, 0x49, 0xE9, + 0x15, 0xB5, 0x3C, 0xD6, 0xA1, 0x61, 0xF5, 0x11, 0xF7, 0x05, 0x6F, 0x1D, + 0xFD, 0x11, 0xBE, 0xD0, 0x30, 0x07, 0xC2, 0x29, 0xB0, 0x09, 0x4E, 0x26, + 0xDC, 0xE3, 0xA2, 0xA8, 0x91, 0x6A, 0x1F, 0xC2, 0x91, 0x45, 0x88, 0x5C, + 0xE5, 0x98, 0xB8, 0x71, 0xA5, 0x15, 0x19, 0xC9, 0x7C, 0x75, 0x11, 0xCC, + 0x70, 0x74, 0x4F, 0x2D, 0x9B, 0x1D, 0x91, 0x44, 0xFD, 0x56, 0x28, 0xA0, + 0xFE, 0xBB, 0x86, 0x6A, 0xC8, 0xFA, 0x5C, 0x0B, 0x58, 0xDC, 0xC6, 0x4B, + 0x76, 0xC8, 0xAB, 0x22, 0xD9, 0x73, 0x0F, 0xA5, 0xF4, 0x5A, 0x02, 0x89, + 0x3F, 0x4F, 0x9E, 0x22, 0x82, 0xEE, 0xA2, 0x74, 0x53, 0x2A, 0x3D, 0x53, + 0x27, 0x69, 0x1D, 0x6C, 0x8E, 0x32, 0x2C, 0x64, 0x00, 0x26, 0x63, 0x61, + 0x36, 0x4E, 0xA3, 0x46, 0xB7, 0x3F, 0x7D, 0xB3, 0x2D, 0xAC, 0x6D, 0x90, + 0xA2, 0x95, 0xA2, 0xCE, 0xCF, 0xDA, 0x82, 0xE7, 0x07, 0x34, 0x19, 0x96, + 0xE9, 0xB8, 0x21, 0xAA, 0x29, 0x7E, 0xA6, 0x38, 0xBE, 0x8E, 0x29, 0x4A, + 0x21, 0x66, 0x79, 0x1F, 0xB3, 0xC3, 0xB5, 0x09, 0x67, 0xDE, 0xD6, 0xD4, + 0x07, 0x46, 0xF3, 0x2A, 0xDA, 0xE6, 0x22, 0x37, 0x60, 0xCB, 0x81, 0xB6, + 0x0F, 0xA0, 0x0F, 0xE9, 0xC8, 0x95, 0x7F, 0xBF, 0x55, 0x91, 0x05, 0x7A, + 0xCF, 0x3D, 0x15, 0xC0, 0x6F, 0xDE, 0x09, 0x94, 0x01, 0x83, 0xD7, 0x34, + 0x1B, 0xCC, 0x40, 0xA5, 0xF0, 0xB8, 0x9B, 0x67, 0xD5, 0x98, 0x91, 0x3B, + 0xA7, 0x84, 0x78, 0x95, 0x26, 0xA4, 0x5A, 0x08, 0xF8, 0x2B, 0x74, 0xB4, + 0x00, 0x04, 0x3C, 0xDF, 0xB8, 0x14, 0x8E, 0xE8, 0xDF, 0xA9, 0x8D, 0x6C, + 0x67, 0x92, 0x33, 0x1D, 0xC0, 0xB7, 0xD2, 0xEC, 0x92, 0xC8, 0xBE, 0x09, + 0xBF, 0x2C, 0x29, 0x05, 0x6F, 0x02, 0x6B, 0x9E, 0xEF, 0xBC, 0xBF, 0x2A, + 0xBC, 0x5B, 0xC0, 0x50, 0x8F, 0x41, 0x70, 0x71, 0x87, 0xB2, 0x4D, 0xB7, + 0x04, 0xA9, 0x84, 0xA3, 0x32, 0xAF, 0xAE, 0xEE, 0x6B, 0x17, 0x8B, 0xB2, + 0xB1, 0xFE, 0x6C, 0xE1, 0x90, 0x8C, 0x88, 0xA8, 0x97, 0x48, 0xCE, 0xC8, + 0x4D, 0xCB, 0xF3, 0x06, 0xCF, 0x5F, 0x6A, 0x0A, 0x42, 0xB1, 0x1E, 0x1E, + 0x77, 0x2F, 0x8E, 0xA0, 0xE6, 0x92, 0x0E, 0x06, 0xFC, 0x05, 0x22, 0xD2, + 0x26, 0xE1, 0x31, 0x51, 0x7D, 0x32, 0xDC, 0x0F +}; + +static const unsigned char TA516_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA517_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x21, 0x54, 0x57, 0x43, 0x41, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA517_RSA_N[] = { + 0xB0, 0x7E, 0x72, 0xB8, 0xA4, 0x03, 0x94, 0xE6, 0xA7, 0xDE, 0x09, 0x38, + 0x91, 0x4A, 0x11, 0x40, 0x87, 0xA7, 0x7C, 0x59, 0x64, 0x14, 0x7B, 0xB5, + 0x11, 0x10, 0xDD, 0xFE, 0xBF, 0xD5, 0xC0, 0xBB, 0x56, 0xE2, 0x85, 0x25, + 0xF4, 0x35, 0x72, 0x0F, 0xF8, 0x53, 0xD0, 0x41, 0xE1, 0x44, 0x01, 0xC2, + 0xB4, 0x1C, 0xC3, 0x31, 0x42, 0x16, 0x47, 0x85, 0x33, 0x22, 0x76, 0xB2, + 0x0A, 0x6F, 0x0F, 0xE5, 0x25, 0x50, 0x4F, 0x85, 0x86, 0xBE, 0xBF, 0x98, + 0x2E, 0x10, 0x67, 0x1E, 0xBE, 0x11, 0x05, 0x86, 0x05, 0x90, 0xC4, 0x59, + 0xD0, 0x7C, 0x78, 0x10, 0xB0, 0x80, 0x5C, 0xB7, 0xE1, 0xC7, 0x2B, 0x75, + 0xCB, 0x7C, 0x9F, 0xAE, 0xB5, 0xD1, 0x9D, 0x23, 0x37, 0x63, 0xA7, 0xDC, + 0x42, 0xA2, 0x2D, 0x92, 0x04, 0x1B, 0x50, 0xC1, 0x7B, 0xB8, 0x3E, 0x1B, + 0xC9, 0x56, 0x04, 0x8B, 0x2F, 0x52, 0x9B, 0xAD, 0xA9, 0x56, 0xE9, 0xC1, + 0xFF, 0xAD, 0xA9, 0x58, 0x87, 0x30, 0xB6, 0x81, 0xF7, 0x97, 0x45, 0xFC, + 0x19, 0x57, 0x3B, 0x2B, 0x6F, 0xE4, 0x47, 0xF4, 0x99, 0x45, 0xFE, 0x1D, + 0xF1, 0xF8, 0x97, 0xA3, 0x88, 0x1D, 0x37, 0x1C, 0x5C, 0x8F, 0xE0, 0x76, + 0x25, 0x9A, 0x50, 0xF8, 0xA0, 0x54, 0xFF, 0x44, 0x90, 0x76, 0x23, 0xD2, + 0x32, 0xC6, 0xC3, 0xAB, 0x06, 0xBF, 0xFC, 0xFB, 0xBF, 0xF3, 0xAD, 0x7D, + 0x92, 0x62, 0x02, 0x5B, 0x29, 0xD3, 0x35, 0xA3, 0x93, 0x9A, 0x43, 0x64, + 0x60, 0x5D, 0xB2, 0xFA, 0x32, 0xFF, 0x3B, 0x04, 0xAF, 0x4D, 0x40, 0x6A, + 0xF9, 0xC7, 0xE3, 0xEF, 0x23, 0xFD, 0x6B, 0xCB, 0xE5, 0x0F, 0x8B, 0x38, + 0x0D, 0xEE, 0x0A, 0xFC, 0xFE, 0x0F, 0x98, 0x9F, 0x30, 0x31, 0xDD, 0x6C, + 0x52, 0x65, 0xF9, 0x8B, 0x81, 0xBE, 0x22, 0xE1, 0x1C, 0x58, 0x03, 0xBA, + 0x91, 0x1B, 0x89, 0x07 +}; + +static const unsigned char TA517_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA518_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA518_EC_Q[] = { + 0x04, 0xCE, 0xBF, 0xFE, 0x57, 0xA8, 0xBF, 0xD5, 0xAA, 0xF7, 0x10, 0x9A, + 0xCD, 0xBC, 0xD1, 0x11, 0xA2, 0xBD, 0x67, 0x42, 0xCC, 0x90, 0xEB, 0x15, + 0x18, 0x90, 0xD9, 0xA2, 0xCD, 0x0C, 0x2A, 0x25, 0xEB, 0x3E, 0x4F, 0xCE, + 0xB5, 0xD2, 0x8F, 0x0F, 0xF3, 0x35, 0xDA, 0x43, 0x8B, 0x02, 0x80, 0xBE, + 0x6F, 0x51, 0x24, 0x1D, 0x0F, 0x6B, 0x2B, 0xCA, 0x9F, 0xC2, 0x6F, 0x50, + 0x32, 0xE5, 0x37, 0x20, 0xB6, 0x20, 0xFF, 0x88, 0x0D, 0x0F, 0x6D, 0x49, + 0xBB, 0xDB, 0x06, 0xA4, 0x87, 0x90, 0x92, 0x94, 0xF4, 0x09, 0xD0, 0xCF, + 0x7F, 0xC8, 0x80, 0x0B, 0xC1, 0x97, 0xB3, 0xBB, 0x35, 0x27, 0xC9, 0xC2, + 0x1B +}; + +static const unsigned char TA519_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x33 +}; + +static const unsigned char TA519_RSA_N[] = { + 0xED, 0x35, 0xA1, 0x81, 0x80, 0xF3, 0xCB, 0x4A, 0x69, 0x5B, 0xC2, 0xFB, + 0x51, 0x83, 0xAE, 0x26, 0xFD, 0xE1, 0x6E, 0xF3, 0x81, 0x12, 0x7D, 0x71, + 0x40, 0xFF, 0x87, 0x75, 0x42, 0x29, 0x21, 0xED, 0x81, 0x52, 0x2C, 0xDF, + 0x12, 0xC1, 0x19, 0x84, 0x89, 0xC1, 0xBD, 0xC5, 0x28, 0xD5, 0xD5, 0x4B, + 0x6C, 0x44, 0xD6, 0x4C, 0xDB, 0x07, 0x96, 0x4A, 0x55, 0x7A, 0xCA, 0x36, + 0x82, 0x04, 0x36, 0xA8, 0xA5, 0xFC, 0x27, 0xF6, 0x49, 0xF1, 0xD5, 0x72, + 0x9E, 0x91, 0xF9, 0x23, 0xD6, 0x70, 0x7B, 0xBB, 0xF5, 0x9B, 0xC1, 0xEC, + 0x93, 0xCF, 0x19, 0xEA, 0x65, 0x7E, 0x88, 0x70, 0xA0, 0x73, 0xFC, 0xF6, + 0xFF, 0xB5, 0x56, 0x62, 0xE1, 0x73, 0x6A, 0x34, 0x98, 0x3E, 0x82, 0xB8, + 0xAC, 0x95, 0x53, 0xF4, 0x01, 0xA0, 0x27, 0x07, 0x72, 0xA3, 0x00, 0x53, + 0xA0, 0xE4, 0xB2, 0xAB, 0x83, 0x38, 0x57, 0x33, 0x25, 0x94, 0x9F, 0xBE, + 0x48, 0x1D, 0x98, 0xE1, 0xA3, 0xBA, 0x9E, 0x5C, 0xCD, 0x04, 0x71, 0x51, + 0x7D, 0x75, 0x78, 0xAB, 0xF3, 0x59, 0xAA, 0xC4, 0xE0, 0x60, 0xBE, 0x8F, + 0x83, 0x52, 0xB8, 0x75, 0x1A, 0x41, 0x35, 0xED, 0xBC, 0xF3, 0x3A, 0x63, + 0xE9, 0xA9, 0x14, 0x45, 0xD7, 0xE6, 0x52, 0xD1, 0x6E, 0xD2, 0xDE, 0xBC, + 0xE3, 0xF5, 0x0B, 0x3B, 0xE6, 0xE0, 0xC4, 0xBD, 0x43, 0x64, 0x13, 0xA6, + 0xCE, 0xF4, 0x98, 0x37, 0x6C, 0x8A, 0x95, 0xA8, 0x97, 0xC8, 0x47, 0x0F, + 0xF0, 0x5E, 0x10, 0x8B, 0xE7, 0x1D, 0x1C, 0xFE, 0xB1, 0x3B, 0xA0, 0x05, + 0x33, 0x68, 0x05, 0x41, 0x82, 0xC1, 0x03, 0x2B, 0x01, 0xC8, 0xE7, 0x8F, + 0x4D, 0xAB, 0xE8, 0xB5, 0xF6, 0xCD, 0x6B, 0x44, 0xB5, 0xE7, 0xDD, 0x8B, + 0xEC, 0xEA, 0x25, 0xB4, 0x00, 0x22, 0x57, 0x4D, 0xB0, 0xB1, 0xB2, 0x31, + 0xC1, 0x16, 0xCE, 0xFF, 0xFD, 0x14, 0x84, 0xB7, 0x47, 0xFA, 0xB2, 0xF1, + 0x70, 0xDE, 0xDB, 0x8B, 0x6C, 0x36, 0x58, 0xA4, 0x7C, 0xB3, 0x11, 0xD1, + 0xC3, 0x77, 0x7F, 0x5F, 0xB6, 0x25, 0xE0, 0x0D, 0xC5, 0xD2, 0xB3, 0xF9, + 0xB8, 0xB8, 0x77, 0xDB, 0x37, 0x71, 0x71, 0x47, 0xE3, 0x60, 0x18, 0x4F, + 0x24, 0xB6, 0x75, 0x37, 0x78, 0xB9, 0xA3, 0x62, 0xAF, 0xBD, 0xC9, 0x72, + 0x8E, 0x2F, 0xCC, 0xBB, 0xAE, 0xDB, 0xE4, 0x15, 0x52, 0x19, 0x07, 0x33, + 0xFB, 0x6A, 0xB7, 0x2D, 0x4B, 0x90, 0x28, 0x82, 0x73, 0xFE, 0x18, 0x8B, + 0x35, 0x8D, 0xDB, 0xA7, 0x04, 0x6A, 0xBE, 0xEA, 0xC1, 0x4D, 0x36, 0x3B, + 0x16, 0x36, 0x91, 0x32, 0xEF, 0xB6, 0x40, 0x89, 0x91, 0x43, 0xE0, 0xF2, + 0xA2, 0xAB, 0x04, 0x2E, 0xE6, 0xF2, 0x4C, 0x0E, 0x16, 0x34, 0x20, 0xAC, + 0x87, 0xC1, 0x2D, 0x7E, 0xC9, 0x66, 0x47, 0x17, 0x14, 0x11, 0xA4, 0xF3, + 0xF7, 0xA1, 0x24, 0x89, 0xAB, 0xD8, 0x1A, 0xC8, 0xA1, 0x5C, 0xB1, 0xA3, + 0xF7, 0x8C, 0x6D, 0xC8, 0x01, 0xC9, 0x4F, 0xC9, 0xEC, 0xC4, 0xFC, 0xAC, + 0x51, 0x33, 0xD1, 0xC8, 0x83, 0xD1, 0xC9, 0x9F, 0x1D, 0xD4, 0x47, 0x34, + 0x29, 0x3E, 0xCB, 0xB0, 0x0E, 0xFA, 0x83, 0x0B, 0x28, 0x58, 0xE5, 0x29, + 0xDC, 0x3F, 0x7C, 0xA8, 0x9F, 0xC9, 0xB6, 0x0A, 0xBB, 0xA6, 0xE8, 0x46, + 0x16, 0x0F, 0x96, 0xE5, 0x7B, 0xE4, 0x6A, 0x7A, 0x48, 0x6D, 0x76, 0x98, + 0x05, 0xA5, 0xDC, 0x6D, 0x1E, 0x42, 0x1E, 0x42, 0xDA, 0x1A, 0xE0, 0x52, + 0xF7, 0xB5, 0x83, 0xC0, 0x1A, 0x7B, 0x78, 0x35, 0x2C, 0x38, 0xF5, 0x1F, + 0xFD, 0x49, 0xA3, 0x2E, 0xD2, 0x59, 0x63, 0xBF, 0x80, 0xB0, 0x8C, 0x93, + 0x73, 0xCB, 0x35, 0xA6, 0x99, 0x95, 0x22, 0x61, 0x65, 0x03, 0x60, 0xFB, + 0x2F, 0x93, 0x4B, 0xFA, 0x9A, 0x9C, 0x80, 0x3B +}; + +static const unsigned char TA519_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA520_DN[] = { + 0x30, 0x37, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0B, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x54, + 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, 0x20, 0x52, + 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x31 +}; + +static const unsigned char TA520_RSA_N[] = { + 0xC2, 0xBE, 0xEB, 0x27, 0xF0, 0x21, 0xA3, 0xF3, 0x69, 0x26, 0x55, 0x7E, + 0x9D, 0xC5, 0x55, 0x16, 0x91, 0x5C, 0xFD, 0xEF, 0x21, 0xBF, 0x53, 0x80, + 0x7A, 0x2D, 0xD2, 0x91, 0x8C, 0x63, 0x31, 0xF0, 0xEC, 0x24, 0xF0, 0xC3, + 0xA5, 0xD2, 0x72, 0x7C, 0x10, 0x6D, 0xF4, 0x37, 0xB7, 0xE5, 0xE6, 0x7C, + 0x79, 0xEA, 0x8C, 0xB5, 0x82, 0x8B, 0xAE, 0x48, 0xB6, 0xAC, 0x00, 0xDC, + 0x65, 0x75, 0xEC, 0x2A, 0x4D, 0x5F, 0xC1, 0x87, 0xF5, 0x20, 0x65, 0x2B, + 0x81, 0xA8, 0x47, 0x3E, 0x89, 0x23, 0x95, 0x30, 0x16, 0x90, 0x7F, 0xE8, + 0x57, 0x07, 0x48, 0xE7, 0x19, 0xAE, 0xBF, 0x45, 0x67, 0xB1, 0x37, 0x1B, + 0x06, 0x2A, 0xFE, 0xDE, 0xF9, 0xAC, 0x7D, 0x83, 0xFB, 0x5E, 0xBA, 0xE4, + 0x8F, 0x97, 0x67, 0xBE, 0x4B, 0x8E, 0x8D, 0x64, 0x07, 0x57, 0x38, 0x55, + 0x69, 0x34, 0x36, 0x3D, 0x13, 0x48, 0xEF, 0x4F, 0xE2, 0xD3, 0x66, 0x1E, + 0xA4, 0xCF, 0x1A, 0xB7, 0x5E, 0x36, 0x33, 0xD4, 0xB4, 0x06, 0xBD, 0x18, + 0x01, 0xFD, 0x77, 0x84, 0x50, 0x00, 0x45, 0xF5, 0x8C, 0x5D, 0xE8, 0x23, + 0xBC, 0x7E, 0xFE, 0x35, 0xE1, 0xED, 0x50, 0x7B, 0xA9, 0x30, 0x8D, 0x19, + 0xD3, 0x09, 0x8E, 0x68, 0x67, 0x5D, 0xBF, 0x3C, 0x97, 0x18, 0x53, 0xBB, + 0x29, 0x62, 0xC5, 0xCA, 0x5E, 0x72, 0xC1, 0xC7, 0x96, 0xD4, 0xDB, 0x2D, + 0xA0, 0xB4, 0x1F, 0x69, 0x03, 0xEC, 0xEA, 0xE2, 0x50, 0xF1, 0x0C, 0x3C, + 0xF0, 0xAC, 0xF3, 0x53, 0x2D, 0xF0, 0x1C, 0xF5, 0xED, 0x6C, 0x39, 0x39, + 0x73, 0x80, 0x16, 0xC8, 0x52, 0xB0, 0x23, 0xCD, 0xE0, 0x3E, 0xDC, 0xDD, + 0x3C, 0x47, 0xA0, 0xBB, 0x35, 0x8A, 0xE2, 0x98, 0x68, 0x8B, 0xBE, 0xE5, + 0xBF, 0x72, 0xEE, 0xD2, 0xFA, 0xA5, 0xED, 0x12, 0xED, 0xFC, 0x98, 0x18, + 0xA9, 0x26, 0x76, 0xDC, 0x28, 0x4B, 0x10, 0x20, 0x1C, 0xD3, 0x7F, 0x16, + 0x77, 0x2D, 0xED, 0x6F, 0x80, 0xF7, 0x49, 0xBB, 0x53, 0x05, 0xBB, 0x5D, + 0x68, 0xC7, 0xD4, 0xC8, 0x75, 0x16, 0x3F, 0x89, 0x5A, 0x8B, 0xF7, 0x17, + 0x47, 0xD4, 0x4C, 0xF1, 0xD2, 0x89, 0x79, 0x3E, 0x4D, 0x3D, 0x98, 0xA8, + 0x61, 0xDE, 0x3A, 0x1E, 0xD2, 0xF8, 0x5E, 0x03, 0xE0, 0xC1, 0xC9, 0x1C, + 0x8C, 0xD3, 0x8D, 0x4D, 0xD3, 0x95, 0x36, 0xB3, 0x37, 0x5F, 0x63, 0x63, + 0x9B, 0x33, 0x14, 0xF0, 0x2D, 0x26, 0x6B, 0x53, 0x7C, 0x89, 0x8C, 0x32, + 0xC2, 0x6E, 0xEC, 0x3D, 0x21, 0x00, 0x39, 0xC9, 0xA1, 0x68, 0xE2, 0x50, + 0x83, 0x2E, 0xB0, 0x3A, 0x2B, 0xF3, 0x36, 0xA0, 0xAC, 0x2F, 0xE4, 0x6F, + 0x61, 0xC2, 0x51, 0x09, 0x39, 0x3E, 0x8B, 0x53, 0xB9, 0xBB, 0x67, 0xDA, + 0xDC, 0x53, 0xB9, 0x76, 0x59, 0x36, 0x9D, 0x43, 0xE5, 0x20, 0xE0, 0x3D, + 0x32, 0x60, 0x85, 0x22, 0x51, 0xB7, 0xC7, 0x33, 0xBB, 0xDD, 0x15, 0x2F, + 0xA4, 0x78, 0xA6, 0x07, 0x7B, 0x81, 0x46, 0x36, 0x04, 0x86, 0xDD, 0x79, + 0x35, 0xC7, 0x95, 0x2C, 0x3B, 0xB0, 0xA3, 0x17, 0x35, 0xE5, 0x73, 0x1F, + 0xB4, 0x5C, 0x59, 0xEF, 0xDA, 0xEA, 0x10, 0x65, 0x7B, 0x7A, 0xD0, 0x7F, + 0x9F, 0xB3, 0xB4, 0x2A, 0x37, 0x3B, 0x70, 0x8B, 0x9B, 0x5B, 0xB9, 0x2B, + 0xB7, 0xEC, 0xB2, 0x51, 0x12, 0x97, 0x53, 0x29, 0x5A, 0xD4, 0xF0, 0x12, + 0x10, 0xDC, 0x4F, 0x02, 0xBB, 0x12, 0x92, 0x2F, 0x62, 0xD4, 0x3F, 0x69, + 0x43, 0x7C, 0x0D, 0xD6, 0xFC, 0x58, 0x75, 0x01, 0x88, 0x9D, 0x58, 0x16, + 0x4B, 0xDE, 0xBA, 0x90, 0xFF, 0x47, 0x01, 0x89, 0x06, 0x6A, 0xF6, 0x5F, + 0xB2, 0x90, 0x6A, 0xB3, 0x02, 0xA6, 0x02, 0x88, 0xBF, 0xB3, 0x47, 0x7E, + 0x2A, 0xD9, 0xD5, 0xFA, 0x68, 0x78, 0x35, 0x4D +}; + +static const unsigned char TA520_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA521_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x49, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x11, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x6C, + 0x61, 0x6E, 0x64, 0x20, 0x4F, 0x79, 0x6A, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x32 +}; + +static const unsigned char TA521_RSA_N[] = { + 0xB2, 0xD0, 0x3F, 0x07, 0xBC, 0xE2, 0x7B, 0xD0, 0x6B, 0x99, 0xF8, 0xE2, + 0x77, 0x69, 0xE7, 0xCE, 0x9D, 0xA4, 0x03, 0xBC, 0x82, 0x6D, 0xA1, 0xFE, + 0x81, 0x65, 0x1F, 0x4C, 0x27, 0xAC, 0x8E, 0x00, 0xBA, 0x16, 0x7B, 0xEB, + 0x30, 0x6A, 0x00, 0xC0, 0xB3, 0x74, 0x68, 0x7E, 0xB2, 0xAF, 0xC7, 0xD5, + 0x62, 0xB3, 0x7A, 0x3F, 0x50, 0xCA, 0x8C, 0x36, 0x44, 0x24, 0x63, 0xD2, + 0x36, 0xE9, 0x0C, 0x85, 0xF6, 0x43, 0x76, 0xD5, 0x4C, 0xA1, 0x60, 0x72, + 0x67, 0xE2, 0x28, 0x33, 0xA5, 0xCB, 0x31, 0xB8, 0x3A, 0x22, 0x23, 0x34, + 0xB8, 0x7D, 0xBD, 0x56, 0x22, 0x40, 0x9D, 0xEA, 0xF4, 0x7B, 0x03, 0xAD, + 0x68, 0xFC, 0xB2, 0x81, 0x4F, 0x98, 0xD0, 0x74, 0xEA, 0x8D, 0xE5, 0x7D, + 0xCD, 0x63, 0xC3, 0xA3, 0xF6, 0xDE, 0x92, 0xC2, 0x58, 0x19, 0xE0, 0x96, + 0xBB, 0xC5, 0xC4, 0xA9, 0x3D, 0xA5, 0x74, 0x96, 0xFE, 0xAF, 0xF9, 0x89, + 0xAA, 0xBD, 0x95, 0x17, 0x54, 0xD8, 0x78, 0x44, 0xF1, 0x0C, 0x77, 0x15, + 0x92, 0xE0, 0x98, 0x42, 0xA7, 0xA4, 0xD6, 0xAA, 0x20, 0x92, 0xCD, 0xC1, + 0xA0, 0xB3, 0x96, 0xB2, 0x3A, 0x84, 0x42, 0x8D, 0x7D, 0xD5, 0x95, 0xE4, + 0xD6, 0xDB, 0xE9, 0x62, 0xC4, 0x58, 0xB3, 0x79, 0xC5, 0x8C, 0xD3, 0x35, + 0x33, 0x83, 0x9F, 0x75, 0xA1, 0x52, 0x27, 0x61, 0x38, 0xF1, 0x59, 0x3D, + 0x8E, 0x50, 0xE0, 0xBD, 0x79, 0x3C, 0xE7, 0x6C, 0x96, 0xFE, 0x5E, 0xD9, + 0x02, 0x65, 0xB4, 0x8E, 0x5C, 0xD0, 0x11, 0x34, 0xDF, 0x5D, 0xBF, 0x52, + 0xA7, 0x81, 0x00, 0xC3, 0x7F, 0x99, 0x45, 0x99, 0x15, 0xD5, 0x17, 0xC8, + 0x0A, 0x53, 0xEC, 0x63, 0xF3, 0x99, 0x7D, 0xCC, 0x69, 0x12, 0x86, 0xC2, + 0x17, 0xF0, 0x01, 0x9E, 0xBF, 0x84, 0xBC, 0xD1, 0x52, 0xCB, 0x1B, 0x92, + 0x66, 0xCE, 0xA4, 0x53, 0xE5, 0xA1, 0xBF, 0xC4, 0xDB, 0x09, 0xD6, 0xE6, + 0x89, 0x56, 0x2B, 0xC8, 0xE3, 0x7C, 0xDE, 0xE3, 0xFF, 0x89, 0xE5, 0x35, + 0x6E, 0x28, 0xE8, 0x6C, 0x0B, 0x23, 0x51, 0xA9, 0x25, 0x05, 0xEB, 0x48, + 0xF8, 0xDD, 0xB1, 0xCA, 0xFA, 0x6C, 0x08, 0x51, 0xEF, 0xB7, 0x18, 0x6C, + 0x44, 0xCA, 0x26, 0xE1, 0x73, 0xC6, 0x89, 0x06, 0x81, 0xE5, 0x8A, 0xAC, + 0xB0, 0xE2, 0x29, 0xC6, 0xB9, 0x24, 0xB3, 0x6B, 0x44, 0x11, 0xF4, 0xA5, + 0x43, 0xC2, 0x4C, 0x43, 0xE5, 0x70, 0x36, 0x8C, 0xB6, 0x33, 0x57, 0x7A, + 0x95, 0x2E, 0x82, 0xA0, 0xF4, 0x5C, 0x10, 0xB3, 0x61, 0x83, 0xF6, 0x02, + 0x05, 0x86, 0x2E, 0x7C, 0x2D, 0x6C, 0xDC, 0x03, 0x46, 0x6E, 0x35, 0x93, + 0xD5, 0x7A, 0x95, 0x2F, 0xDE, 0x20, 0xD8, 0x5B, 0x7E, 0x94, 0x90, 0x04, + 0x6A, 0xBA, 0x59, 0x3D, 0x04, 0x05, 0x75, 0x9D, 0x37, 0xA2, 0x0E, 0x2E, + 0x3D, 0xEB, 0xC1, 0xA4, 0x52, 0x83, 0xFE, 0xD0, 0x6B, 0xD4, 0x66, 0x8E, + 0xDC, 0xC6, 0xE9, 0x12, 0x4E, 0x1D, 0x2A, 0x57, 0xAA, 0x10, 0xBC, 0x7C, + 0x5E, 0x82, 0x7D, 0xA6, 0xA6, 0xC9, 0xF2, 0x2D, 0xB9, 0xF5, 0x17, 0x27, + 0xAD, 0xD1, 0x0E, 0x89, 0x54, 0x2B, 0x95, 0xFA, 0xC0, 0xAD, 0x1D, 0x98, + 0x14, 0x78, 0x33, 0x42, 0x86, 0x0A, 0xA9, 0x73, 0xB5, 0xFB, 0x74, 0x0D, + 0xB7, 0x1B, 0x30, 0x19, 0xC4, 0x5A, 0x0E, 0x1C, 0x27, 0xB7, 0xDA, 0x18, + 0xD0, 0xFF, 0x8A, 0xC8, 0x05, 0xBA, 0xF1, 0xAA, 0x1C, 0xA2, 0x37, 0xB7, + 0xE6, 0x48, 0xA4, 0x46, 0x2C, 0x94, 0xEA, 0xA8, 0x76, 0x62, 0x47, 0x8B, + 0x10, 0x53, 0x07, 0x48, 0x57, 0x6C, 0xE2, 0x92, 0x4D, 0xB6, 0xAE, 0x05, + 0xCB, 0xDC, 0xC1, 0x4A, 0x5E, 0x8F, 0xAC, 0x3D, 0x19, 0x4E, 0xC2, 0xED, + 0x60, 0x75, 0x2B, 0xDB, 0xC1, 0xCA, 0x42, 0xD5 +}; + +static const unsigned char TA521_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA522_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA522_RSA_N[] = { + 0xC0, 0x31, 0x82, 0x61, 0x92, 0xE4, 0x94, 0x1B, 0x0A, 0x2A, 0x65, 0xD0, + 0xBE, 0x06, 0xA9, 0x87, 0x3B, 0x51, 0x12, 0xEA, 0x70, 0x41, 0xAE, 0xE2, + 0xFB, 0x74, 0xEA, 0x0A, 0x8D, 0xB9, 0xB3, 0x4C, 0xDC, 0x8F, 0xB7, 0x13, + 0x52, 0x4F, 0x54, 0x18, 0xE1, 0x2C, 0x73, 0x95, 0x91, 0xC5, 0x66, 0x3B, + 0x6A, 0xCF, 0xAC, 0x63, 0x6D, 0x87, 0x53, 0xF0, 0xF7, 0xF1, 0x39, 0xB7, + 0xA0, 0x43, 0x63, 0xB0, 0xC4, 0x03, 0x5D, 0x57, 0xA9, 0xE7, 0x44, 0xCE, + 0xC4, 0xA1, 0x83, 0x65, 0xF6, 0x50, 0x3E, 0xB1, 0x7E, 0x16, 0xB8, 0x3A, + 0x8A, 0x02, 0xD0, 0x96, 0x1F, 0x00, 0xCD, 0x05, 0x21, 0xEF, 0x06, 0x6D, + 0xDD, 0x21, 0x9C, 0x19, 0x43, 0x45, 0xA1, 0xC5, 0xE8, 0x80, 0xCA, 0xC2, + 0xAD, 0x40, 0x62, 0x17, 0x06, 0xC6, 0xAA, 0xBC, 0xF3, 0xD6, 0xE6, 0xFC, + 0x50, 0x7E, 0x66, 0x42, 0x1F, 0x3C, 0x8B, 0xA6, 0x79, 0x79, 0x86, 0x40, + 0x35, 0x9F, 0x20, 0xEF, 0x3F, 0xEB, 0x8B, 0x47, 0x1F, 0x8F, 0x8E, 0xC5, + 0xD4, 0x8E, 0xB6, 0x2C, 0xC9, 0x44, 0x04, 0xE3, 0xD4, 0x43, 0x75, 0x3F, + 0xD5, 0x3F, 0xAF, 0x1C, 0xCC, 0x7E, 0x46, 0x5F, 0xAC, 0xDF, 0x64, 0x10, + 0x8A, 0xEF, 0x46, 0xF0, 0x90, 0xF0, 0x0F, 0x2D, 0xF4, 0x88, 0x0B, 0xB1, + 0x29, 0xAA, 0xAF, 0x85, 0xAA, 0x49, 0x58, 0xA8, 0xBF, 0x63, 0xA0, 0x38, + 0x91, 0xE6, 0xB3, 0xE6, 0x77, 0x68, 0xC4, 0xF9, 0x2A, 0x19, 0x84, 0xBB, + 0x0E, 0xE1, 0xF5, 0xAF, 0x89, 0xEC, 0xA5, 0x2F, 0x50, 0x20, 0x74, 0x1E, + 0x12, 0x41, 0x73, 0x1E, 0x24, 0xD9, 0xCA, 0xCE, 0x2C, 0xA1, 0x59, 0x35, + 0xC0, 0xC8, 0x1D, 0x46, 0x27, 0x61, 0x5A, 0x8F, 0xF9, 0x4D, 0xD3, 0x72, + 0x79, 0x66, 0x1E, 0x9F, 0x15, 0x90, 0x21, 0x2D, 0xFD, 0xED, 0x8B, 0x56, + 0x70, 0x03, 0x4A, 0x49, 0x3E, 0x7F, 0x69, 0x31, 0x12, 0x69, 0xC7, 0x1E, + 0x5C, 0xCA, 0x7A, 0x13, 0x8B, 0xE8, 0xE6, 0xF5, 0x60, 0x0F, 0xCC, 0x93, + 0x2C, 0x84, 0x7F, 0xF1, 0xFC, 0x6A, 0xFC, 0x9B, 0x47, 0x9D, 0xDB, 0xAD, + 0x88, 0x3D, 0xF3, 0x76, 0x75, 0x33, 0xD7, 0x4B, 0xA4, 0xC8, 0x8B, 0xF9, + 0xF5, 0x43, 0x58, 0x4F, 0xCB, 0xC8, 0x03, 0x54, 0x8F, 0xA5, 0x85, 0x78, + 0x04, 0x1A, 0xF3, 0x73, 0xF2, 0xD7, 0x87, 0x1D, 0x41, 0x9F, 0xE7, 0xD8, + 0x17, 0xCE, 0x1A, 0x9C, 0x0F, 0x4A, 0xFC, 0xDC, 0x44, 0x68, 0x54, 0x68, + 0xE2, 0x41, 0x3C, 0xFE, 0x2C, 0x84, 0x86, 0x37, 0x3C, 0xCD, 0x3F, 0x2F, + 0xA2, 0xDB, 0xE7, 0xF7, 0x54, 0x03, 0x5F, 0x59, 0xD3, 0xF7, 0x91, 0x78, + 0xC7, 0x8B, 0x77, 0x6A, 0x16, 0xE5, 0x49, 0x85, 0x90, 0x45, 0x72, 0x70, + 0x2F, 0x91, 0x5D, 0xF8, 0x3E, 0x65, 0x40, 0x0B, 0x19, 0x99, 0xC9, 0x26, + 0x20, 0x5A, 0x68, 0xC1, 0x35, 0xBF, 0x4F, 0xA7, 0x51, 0xF1, 0xD8, 0x11, + 0x2B, 0x5B, 0xE0, 0x9A, 0x9E, 0x28, 0x3B, 0x0A, 0x3A, 0x0A, 0x1F, 0xC1, + 0x81, 0xE5, 0x2E, 0xF0, 0xA6, 0xB9, 0x69, 0xA5, 0x88, 0x94, 0xE6, 0x6B, + 0x13, 0x7F, 0xD1, 0x64, 0x3F, 0x3D, 0x9C, 0x70, 0x46, 0xE5, 0xA2, 0x85, + 0x7B, 0x58, 0x84, 0x27, 0xDC, 0xC4, 0x80, 0x3E, 0x67, 0x9A, 0x9A, 0xC7, + 0x9A, 0x31, 0x0E, 0x30, 0xEC, 0xE6, 0x17, 0x40, 0x95, 0xD9, 0x45, 0xED, + 0x01, 0x96, 0xAA, 0xBF, 0x0C, 0xF3, 0x4B, 0xD1, 0x63, 0xF7, 0x13, 0x58, + 0xC0, 0xB8, 0xF3, 0xFA, 0x67, 0xDD, 0x9B, 0x7D, 0x6D, 0x4A, 0xFF, 0x32, + 0x4C, 0xB5, 0x25, 0x3B, 0xFF, 0x1C, 0x67, 0x0F, 0x85, 0x22, 0x59, 0x05, + 0x91, 0x91, 0x41, 0x77, 0x81, 0xD0, 0x85, 0x4C, 0x87, 0x10, 0x71, 0xFF, + 0x9E, 0x43, 0x1B, 0xAE, 0x95, 0x75, 0x2D, 0x81 +}; + +static const unsigned char TA522_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA523_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA523_EC_Q[] = { + 0x04, 0xF1, 0xB3, 0xCD, 0x38, 0xE4, 0x25, 0x43, 0xE5, 0xDE, 0x19, 0x09, + 0xBB, 0x81, 0x79, 0xA2, 0x15, 0x5F, 0x15, 0x63, 0x01, 0xDE, 0xC2, 0xAB, + 0xDD, 0xB3, 0xA6, 0x1B, 0x67, 0x4B, 0x80, 0x83, 0xAF, 0x99, 0xCB, 0xAC, + 0x17, 0xDB, 0x2B, 0x96, 0xCA, 0x7C, 0x52, 0x55, 0xE2, 0x1A, 0xE1, 0x3D, + 0x56, 0xF0, 0x2F, 0x16, 0x08, 0xFA, 0x15, 0xBC, 0x9B, 0xBB, 0x47, 0xE6, + 0x3F, 0xEE, 0xA8, 0xE1, 0x4C, 0x8C, 0xF5, 0xD3, 0x36, 0xF9, 0x38, 0x5D, + 0xAB, 0x70, 0x9A, 0x47, 0x0D, 0xE2, 0x81, 0x41, 0x06, 0xEB, 0x49, 0xF9, + 0xB0, 0x29, 0xDD, 0x33, 0xEC, 0x50, 0xA5, 0x7F, 0x79, 0x29, 0xB8, 0x20, + 0x98 +}; + +static const unsigned char TA524_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x28, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA524_RSA_N[] = { + 0xB9, 0x5D, 0x51, 0x28, 0x4B, 0x3C, 0x37, 0x92, 0xD1, 0x82, 0xCE, 0xBD, + 0x1D, 0xBD, 0xCD, 0xDD, 0xB8, 0xAB, 0xCF, 0x0A, 0x3E, 0xE1, 0x5D, 0xE5, + 0xDC, 0xAA, 0x09, 0xB9, 0x57, 0x02, 0x3E, 0xE6, 0x63, 0x61, 0xDF, 0xF2, + 0x0F, 0x82, 0x63, 0xAE, 0xA3, 0xF7, 0xAC, 0x73, 0xD1, 0x7C, 0xE7, 0xB3, + 0x0B, 0xAF, 0x08, 0x00, 0x09, 0x59, 0x7F, 0xCD, 0x29, 0x2A, 0x88, 0x93, + 0x87, 0x17, 0x18, 0x80, 0xED, 0x88, 0xB2, 0xB4, 0xB6, 0x10, 0x1F, 0x2D, + 0xD6, 0x5F, 0x55, 0xA2, 0x13, 0x5D, 0xD1, 0xC6, 0xEB, 0x06, 0x56, 0x89, + 0x88, 0xFE, 0xAC, 0x32, 0x9D, 0xFD, 0x5C, 0xC3, 0x05, 0xC7, 0x6E, 0xEE, + 0x86, 0x89, 0xBA, 0x88, 0x03, 0x9D, 0x72, 0x21, 0x86, 0x90, 0xAE, 0x8F, + 0x03, 0xA5, 0xDC, 0x9F, 0x88, 0x28, 0xCB, 0xA3, 0x92, 0x49, 0x0F, 0xEC, + 0xD0, 0x0F, 0xE2, 0x6D, 0x44, 0x4F, 0x80, 0x6A, 0xB2, 0xD4, 0xE7, 0xA0, + 0x0A, 0x53, 0x01, 0xBA, 0x8E, 0x97, 0x91, 0x76, 0x6E, 0xBC, 0xFC, 0xD5, + 0x6B, 0x36, 0xE6, 0x40, 0x88, 0xD6, 0x7B, 0x2F, 0x5F, 0x05, 0xE8, 0x2C, + 0x6D, 0x11, 0xF3, 0xE7, 0xB2, 0xBE, 0x92, 0x44, 0x4C, 0xD2, 0x97, 0xA4, + 0xFE, 0xD2, 0x72, 0x81, 0x43, 0x07, 0x9C, 0xE9, 0x11, 0x3E, 0xF5, 0x8B, + 0x1A, 0x59, 0x7D, 0x1F, 0x68, 0x58, 0xDD, 0x04, 0x00, 0x2C, 0x96, 0xF3, + 0x43, 0xB3, 0x7E, 0x98, 0x19, 0x74, 0xD9, 0x9C, 0x73, 0xD9, 0x18, 0xBE, + 0x41, 0xC7, 0x34, 0x79, 0xD9, 0xF4, 0x62, 0xC2, 0x43, 0xB9, 0xB3, 0x27, + 0xB0, 0x22, 0xCB, 0xF9, 0x3D, 0x52, 0xC7, 0x30, 0x47, 0xB3, 0xC9, 0x3E, + 0xB8, 0x6A, 0xE2, 0xE7, 0xE8, 0x81, 0x70, 0x5E, 0x42, 0x8B, 0x4F, 0x26, + 0xA5, 0xFE, 0x3A, 0xC2, 0x20, 0x6E, 0xBB, 0xF8, 0x16, 0x8E, 0xCD, 0x0C, + 0xA9, 0xB4, 0x1B, 0x6C, 0x76, 0x10, 0xE1, 0x58, 0x79, 0x46, 0x3E, 0x54, + 0xCE, 0x80, 0xA8, 0x57, 0x09, 0x37, 0x29, 0x1B, 0x99, 0x13, 0x8F, 0x0C, + 0xC8, 0xD6, 0x2C, 0x1C, 0xFB, 0x05, 0xE8, 0x08, 0x95, 0x3D, 0x65, 0x46, + 0xDC, 0xEE, 0xCD, 0x69, 0xE2, 0x4D, 0x8F, 0x87, 0x28, 0x4E, 0x34, 0x0B, + 0x3E, 0xCF, 0x14, 0xD9, 0xBB, 0xDD, 0xB6, 0x50, 0x9A, 0xAD, 0x77, 0xD4, + 0x19, 0xD6, 0xDA, 0x1A, 0x88, 0xC8, 0x4E, 0x1B, 0x27, 0x75, 0xD8, 0xB2, + 0x08, 0xF1, 0xAE, 0x83, 0x30, 0xB9, 0x11, 0x0E, 0xCD, 0x87, 0xF0, 0x84, + 0x8D, 0x15, 0x72, 0x7C, 0xA1, 0xEF, 0xCC, 0xF2, 0x88, 0x61, 0xBA, 0xF4, + 0x69, 0xBB, 0x0C, 0x8C, 0x0B, 0x75, 0x57, 0x04, 0xB8, 0x4E, 0x2A, 0x14, + 0x2E, 0x3D, 0x0F, 0x1C, 0x1E, 0x32, 0xA6, 0x62, 0x36, 0xEE, 0x66, 0xE2, + 0x22, 0xB8, 0x05, 0x40, 0x63, 0x10, 0x22, 0xF3, 0x33, 0x1D, 0x74, 0x72, + 0x8A, 0x2C, 0xF5, 0x39, 0x29, 0xA0, 0xD3, 0xE7, 0x1B, 0x80, 0x84, 0x2D, + 0xC5, 0x3D, 0xE3, 0x4D, 0xB1, 0xFD, 0x1A, 0x6F, 0xBA, 0x65, 0x07, 0x3B, + 0x58, 0xEC, 0x42, 0x45, 0x26, 0xFB, 0xD8, 0xDA, 0x25, 0x72, 0xC4, 0xF6, + 0x00, 0xB1, 0x22, 0x79, 0xBD, 0xE3, 0x7C, 0x59, 0x62, 0x4A, 0x9C, 0x05, + 0x6F, 0x3D, 0xCE, 0xE6, 0xD6, 0x47, 0x63, 0x99, 0xC6, 0x24, 0x6F, 0x72, + 0x12, 0xC8, 0xAC, 0x7F, 0x90, 0xB4, 0x0B, 0x91, 0x70, 0xE8, 0xB7, 0xE6, + 0x16, 0x10, 0x71, 0x17, 0xCE, 0xDE, 0x06, 0x4F, 0x48, 0x41, 0x7D, 0x35, + 0x4A, 0xA3, 0x89, 0xF2, 0xC9, 0x4B, 0x7B, 0x41, 0x11, 0x6D, 0x67, 0xB7, + 0x08, 0x98, 0x4C, 0xE5, 0x11, 0x19, 0xAE, 0x42, 0x80, 0xDC, 0xFB, 0x90, + 0x05, 0xD4, 0xF8, 0x50, 0xCA, 0xBE, 0xE4, 0xAD, 0xC7, 0xC2, 0x94, 0xD7, + 0x16, 0x9D, 0xE6, 0x17, 0x8F, 0xAF, 0x36, 0xFB +}; + +static const unsigned char TA524_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA525_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x32, 0x35, 0x36, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA525_EC_Q[] = { + 0x04, 0x7E, 0xFB, 0x6C, 0xE6, 0x23, 0xE3, 0x73, 0x32, 0x08, 0xCA, 0x60, + 0xE6, 0x53, 0x9C, 0xBA, 0x74, 0x8D, 0x18, 0xB0, 0x78, 0x90, 0x52, 0x80, + 0xDD, 0x38, 0xC0, 0x4A, 0x1D, 0xD1, 0xA8, 0xCC, 0x93, 0xA4, 0x97, 0x06, + 0x38, 0xCA, 0x0D, 0x15, 0x62, 0xC6, 0x8E, 0x01, 0x2A, 0x65, 0x9D, 0xAA, + 0xDF, 0x34, 0x91, 0x2E, 0x81, 0xC1, 0xE4, 0x33, 0x92, 0x31, 0xC4, 0xFD, + 0x09, 0x3A, 0xA6, 0x3F, 0xAD +}; + +static const unsigned char TA526_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA526_EC_Q[] = { + 0x04, 0x6B, 0xDA, 0x0D, 0x75, 0x35, 0x08, 0x31, 0x47, 0x05, 0xAE, 0x45, + 0x99, 0x55, 0xF1, 0x11, 0x13, 0x2E, 0x4A, 0xF8, 0x10, 0x31, 0x23, 0xA3, + 0x7E, 0x83, 0xD3, 0x7F, 0x28, 0x08, 0x3A, 0x26, 0x1A, 0x3A, 0xCF, 0x97, + 0x82, 0x1F, 0x80, 0xB7, 0x27, 0x09, 0x8F, 0xD1, 0x8E, 0x30, 0xC4, 0x0A, + 0x9B, 0x0E, 0xAC, 0x58, 0x04, 0xAB, 0xF7, 0x36, 0x7D, 0x94, 0x23, 0xA4, + 0x9B, 0x0A, 0x8A, 0x8B, 0xAB, 0xEB, 0xFD, 0x39, 0x25, 0x66, 0xF1, 0x5E, + 0xFE, 0x8C, 0xAE, 0x8D, 0x41, 0x79, 0x9D, 0x09, 0x60, 0xCE, 0x28, 0xA9, + 0xD3, 0x8A, 0x6D, 0xF3, 0xD6, 0x45, 0xD4, 0xF2, 0x98, 0x84, 0x38, 0x65, + 0xA0 +}; + +static const unsigned char TA527_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x4E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4E, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x65, 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x71, 0x75, 0x65, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, + 0x75, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA527_RSA_N[] = { + 0xC3, 0xCD, 0xD3, 0xFC, 0xBD, 0x04, 0x53, 0xDD, 0x0C, 0x20, 0x3A, 0xD5, + 0x88, 0x2E, 0x05, 0x4B, 0x41, 0xF5, 0x83, 0x82, 0x7E, 0xF7, 0x59, 0x9F, + 0x9E, 0x9E, 0x63, 0xE8, 0x73, 0xDA, 0xF6, 0x06, 0xA9, 0x4F, 0x1F, 0xB4, + 0xF9, 0x0B, 0x1F, 0x39, 0x8C, 0x9A, 0x20, 0xD0, 0x7E, 0x06, 0xD4, 0xEC, + 0x34, 0xD9, 0x86, 0xBC, 0x75, 0x5B, 0x87, 0x88, 0xF0, 0xD2, 0xD9, 0xD4, + 0xA3, 0x0A, 0xB2, 0x6C, 0x1B, 0xEB, 0x49, 0x2C, 0x3E, 0xAC, 0x5D, 0xD8, + 0x94, 0x03, 0xA0, 0xEC, 0x34, 0xE5, 0x30, 0xC4, 0x35, 0x7D, 0xFB, 0x26, + 0x4D, 0x1B, 0x6E, 0x30, 0x54, 0xD8, 0xF5, 0x80, 0x45, 0x9C, 0x39, 0xAD, + 0x9C, 0xC9, 0x25, 0x04, 0x4D, 0x9A, 0x90, 0x3E, 0x4E, 0x40, 0x6E, 0x8A, + 0x6B, 0xCD, 0x29, 0x67, 0xC6, 0xCC, 0x2D, 0xE0, 0x74, 0xE8, 0x05, 0x57, + 0x0A, 0x48, 0x50, 0xFA, 0x7A, 0x43, 0xDA, 0x7E, 0xEC, 0x5B, 0x9A, 0x0E, + 0x62, 0x76, 0xFE, 0xEA, 0x9D, 0x1D, 0x85, 0x72, 0xEC, 0x11, 0xBB, 0x35, + 0xE8, 0x1F, 0x27, 0xBF, 0xC1, 0xA1, 0xC7, 0xBB, 0x48, 0x16, 0xDD, 0x56, + 0xD7, 0xCC, 0x4E, 0xA0, 0xE1, 0xB9, 0xAC, 0xDB, 0xD5, 0x83, 0x19, 0x1A, + 0x85, 0xD1, 0x94, 0x97, 0xD7, 0xCA, 0xA3, 0x65, 0x0B, 0xF3, 0x38, 0xF9, + 0x02, 0xAE, 0xDD, 0xF6, 0x67, 0xCF, 0xC9, 0x3F, 0xF5, 0x8A, 0x2C, 0x47, + 0x1A, 0x99, 0x6F, 0x05, 0x0D, 0xFD, 0xD0, 0x1D, 0x82, 0x31, 0xFC, 0x29, + 0xCC, 0x00, 0x58, 0x97, 0x91, 0x4C, 0x80, 0x00, 0x1C, 0x33, 0x85, 0x96, + 0x2F, 0xCB, 0x41, 0xC2, 0x8B, 0x10, 0x84, 0xC3, 0x09, 0x24, 0x89, 0x1F, + 0xB5, 0x0F, 0xD9, 0xD9, 0x77, 0x47, 0x18, 0x92, 0x94, 0x60, 0x5C, 0xC7, + 0x99, 0x03, 0x3C, 0xFE, 0xF7, 0x95, 0xA7, 0x7D, 0x50, 0xA1, 0x80, 0xC2, + 0xA9, 0x83, 0xAD, 0x58, 0x96, 0x55, 0x21, 0xDB, 0x86, 0x59, 0xD4, 0xAF, + 0xC6, 0xBC, 0xDD, 0x81, 0x6E, 0x07, 0xDB, 0x60, 0x62, 0xFE, 0xEC, 0x10, + 0x6E, 0xDA, 0x68, 0x01, 0xF4, 0x83, 0x1B, 0xA9, 0x3E, 0xA2, 0x5B, 0x23, + 0xD7, 0x64, 0xC6, 0xDF, 0xDC, 0xA2, 0x7D, 0xD8, 0x4B, 0xBA, 0x82, 0xD2, + 0x51, 0xF8, 0x66, 0xBF, 0x06, 0x46, 0xE4, 0x79, 0x2A, 0x26, 0x36, 0x79, + 0x8F, 0x1F, 0x4E, 0x99, 0x1D, 0xB2, 0x8F, 0x0C, 0x0E, 0x1C, 0xFF, 0xC9, + 0x5D, 0xC0, 0xFD, 0x90, 0x10, 0xA6, 0xB1, 0x37, 0xF3, 0xCD, 0x3A, 0x24, + 0x6E, 0xB4, 0x85, 0x90, 0xBF, 0x80, 0xB9, 0x0C, 0x8C, 0xD5, 0x9B, 0xD6, + 0xC8, 0xF1, 0x56, 0x3F, 0x1A, 0x80, 0x89, 0x7A, 0xA9, 0xE2, 0x1B, 0x32, + 0x51, 0x2C, 0x3E, 0xF2, 0xDF, 0x7B, 0xF6, 0x5D, 0x7A, 0x29, 0x19, 0x8E, + 0xE5, 0xC8, 0xBD, 0x36, 0x71, 0x8B, 0x5D, 0x4C, 0xC2, 0x1D, 0x3F, 0xAD, + 0x58, 0xA2, 0xCF, 0x3D, 0x70, 0x4D, 0xA6, 0x50, 0x98, 0x25, 0xDC, 0x23, + 0xF9, 0xB8, 0x58, 0x41, 0x08, 0x71, 0xBF, 0x4F, 0xB8, 0x84, 0xA0, 0x8F, + 0x00, 0x54, 0x15, 0xFC, 0x91, 0x6D, 0x58, 0xA7, 0x96, 0x3B, 0xEB, 0x4B, + 0x96, 0x27, 0xCD, 0x6B, 0xA2, 0xA1, 0x86, 0xAC, 0x0D, 0x7C, 0x54, 0xE6, + 0x66, 0x4C, 0x66, 0x5F, 0x90, 0xBE, 0x21, 0x9A, 0x02, 0x46, 0x2D, 0xE4, + 0x83, 0xC2, 0x80, 0xB9, 0xCF, 0x4B, 0x3E, 0xE8, 0x7F, 0x3C, 0x01, 0xEC, + 0x8F, 0x5E, 0xCD, 0x7F, 0xD2, 0x28, 0x42, 0x01, 0x95, 0x8A, 0xE2, 0x97, + 0x3D, 0x10, 0x21, 0x7D, 0xF6, 0x9D, 0x1C, 0xC5, 0x34, 0xA1, 0xEC, 0x2C, + 0x0E, 0x0A, 0x52, 0x2C, 0x12, 0x55, 0x70, 0x24, 0x3D, 0xCB, 0xC2, 0x14, + 0x35, 0x43, 0x5D, 0x27, 0x4E, 0xBE, 0xC0, 0xBD, 0xAA, 0x7C, 0x96, 0xE7, + 0xFC, 0x9E, 0x61, 0xAD, 0x44, 0xD3, 0x00, 0x97 +}; + +static const unsigned char TA527_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA528_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x55, 0x43, 0x41, + 0x20, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, + 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74 +}; + +static const unsigned char TA528_RSA_N[] = { + 0xA9, 0x09, 0x07, 0x28, 0x13, 0x02, 0xB0, 0x99, 0xE0, 0x64, 0xAA, 0x1E, + 0x43, 0x16, 0x7A, 0x73, 0xB1, 0x91, 0xA0, 0x75, 0x3E, 0xA8, 0xFA, 0xE3, + 0x38, 0x00, 0x7A, 0xEC, 0x89, 0x6A, 0x20, 0x0F, 0x8B, 0xC5, 0xB0, 0x9B, + 0x33, 0x03, 0x5A, 0x86, 0xC6, 0x58, 0x86, 0xD5, 0xC1, 0x85, 0xBB, 0x4F, + 0xC6, 0x9C, 0x40, 0x4D, 0xCA, 0xBE, 0xEE, 0x69, 0x96, 0xB8, 0xAD, 0x81, + 0x30, 0x9A, 0x7C, 0x92, 0x05, 0xEB, 0x05, 0x2B, 0x9A, 0x48, 0xD0, 0xB8, + 0x76, 0x3E, 0x96, 0xC8, 0x20, 0xBB, 0xD2, 0xB0, 0xF1, 0x8F, 0xD8, 0xAC, + 0x45, 0x46, 0xFF, 0xAA, 0x67, 0x60, 0xB4, 0x77, 0x7E, 0x6A, 0x1F, 0x3C, + 0x1A, 0x52, 0x7A, 0x04, 0x3D, 0x07, 0x3C, 0x85, 0x0D, 0x84, 0xD0, 0x1F, + 0x76, 0x0A, 0xF7, 0x6A, 0x14, 0xDF, 0x72, 0xE3, 0x34, 0x7C, 0x57, 0x4E, + 0x56, 0x01, 0x3E, 0x79, 0xF1, 0xAA, 0x29, 0x3B, 0x6C, 0xFA, 0xF8, 0x8F, + 0x6D, 0x4D, 0xC8, 0x35, 0xDF, 0xAE, 0xEB, 0xDC, 0x24, 0xEE, 0x79, 0x45, + 0xA7, 0x85, 0xB6, 0x05, 0x88, 0xDE, 0x88, 0x5D, 0x25, 0x7C, 0x97, 0x64, + 0x67, 0x09, 0xD9, 0xBF, 0x5A, 0x15, 0x05, 0x86, 0xF3, 0x09, 0x1E, 0xEC, + 0x58, 0x32, 0x33, 0x11, 0xF3, 0x77, 0x64, 0xB0, 0x76, 0x1F, 0xE4, 0x10, + 0x35, 0x17, 0x1B, 0xF2, 0x0E, 0xB1, 0x6C, 0xA4, 0x2A, 0xA3, 0x73, 0xFC, + 0x09, 0x1F, 0x1E, 0x32, 0x19, 0x53, 0x11, 0xE7, 0xD9, 0xB3, 0x2C, 0x2E, + 0x76, 0x2E, 0xA1, 0xA3, 0xDE, 0x7E, 0x6A, 0x88, 0x09, 0xE8, 0xF2, 0x07, + 0x8A, 0xF8, 0xB2, 0xCD, 0x10, 0xE7, 0xE2, 0x73, 0x40, 0x93, 0xBB, 0x08, + 0xD1, 0x3F, 0xE1, 0xFC, 0x0B, 0x94, 0xB3, 0x25, 0xEF, 0x7C, 0xA6, 0xD7, + 0xD1, 0xAF, 0x9F, 0xFF, 0x96, 0x9A, 0xF5, 0x91, 0x7B, 0x98, 0x0B, 0x77, + 0xD4, 0x7E, 0xE8, 0x07, 0xD2, 0x62, 0xB5, 0x95, 0x39, 0xE3, 0xF3, 0xF1, + 0x6D, 0x0F, 0x0E, 0x65, 0x84, 0x8A, 0x63, 0x54, 0xC5, 0x80, 0xB6, 0xE0, + 0x9E, 0x4B, 0x7D, 0x47, 0x26, 0xA7, 0x01, 0x08, 0x5D, 0xD1, 0x88, 0x9E, + 0xD7, 0xC3, 0x32, 0x44, 0xFA, 0x82, 0x4A, 0x0A, 0x68, 0x54, 0x7F, 0x38, + 0x53, 0x03, 0xCC, 0xA4, 0x00, 0x33, 0x64, 0x51, 0x59, 0x0B, 0xA3, 0x82, + 0x91, 0x7A, 0x5E, 0xEC, 0x16, 0xC2, 0xF3, 0x2A, 0xE6, 0x62, 0xDA, 0x2A, + 0xDB, 0x59, 0x62, 0x10, 0x25, 0x4A, 0x2A, 0x81, 0x0B, 0x47, 0x07, 0x43, + 0x06, 0x70, 0x87, 0xD2, 0xFA, 0x93, 0x11, 0x29, 0x7A, 0x48, 0x4D, 0xEB, + 0x94, 0xC7, 0x70, 0x4D, 0xAF, 0x67, 0xD5, 0x51, 0xB1, 0x80, 0x20, 0x01, + 0x01, 0xB4, 0x7A, 0x08, 0xA6, 0x90, 0x7F, 0x4E, 0xE0, 0xEF, 0x07, 0x41, + 0x87, 0xAF, 0x6A, 0xA5, 0x5E, 0x8B, 0xFB, 0xCF, 0x50, 0xB2, 0x9A, 0x54, + 0xAF, 0xC3, 0x89, 0xBA, 0x58, 0x2D, 0xF5, 0x30, 0x98, 0xB1, 0x36, 0x72, + 0x39, 0x7E, 0x49, 0x04, 0xFD, 0x29, 0xA7, 0x4C, 0x79, 0xE4, 0x05, 0x57, + 0xDB, 0x94, 0xB9, 0x16, 0x53, 0x8D, 0x46, 0xB3, 0x1D, 0x95, 0x61, 0x57, + 0x56, 0x7F, 0xAF, 0xF0, 0x16, 0x5B, 0x61, 0x58, 0x6F, 0x36, 0x50, 0x11, + 0x0B, 0xD8, 0xAC, 0x2B, 0x95, 0x16, 0x1A, 0x0E, 0x1F, 0x08, 0xCD, 0x36, + 0x34, 0x65, 0x10, 0x62, 0x66, 0xD5, 0x80, 0x5F, 0x14, 0x20, 0x5F, 0x2D, + 0x0C, 0xA0, 0x78, 0x0A, 0x68, 0xD6, 0x2C, 0xD7, 0xE9, 0x6F, 0x2B, 0xD2, + 0x4A, 0x05, 0x93, 0xFC, 0x9E, 0x6F, 0x6B, 0x67, 0xFF, 0x88, 0xF1, 0x4E, + 0xA5, 0x69, 0x4A, 0x52, 0x37, 0x05, 0xEA, 0xC6, 0x16, 0x8D, 0xD2, 0xC4, + 0x99, 0xD1, 0x82, 0x2B, 0x3B, 0xBA, 0x35, 0x75, 0xF7, 0x51, 0x51, 0x58, + 0xF3, 0xC8, 0x07, 0xDD, 0xE4, 0xB4, 0x03, 0x7F +}; + +static const unsigned char TA528_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA529_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x1B, + 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x55, 0x43, 0x41, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x47, 0x32, 0x20, 0x52, + 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA529_RSA_N[] = { + 0xC5, 0xE6, 0x2B, 0x6F, 0x7C, 0xEF, 0x26, 0x05, 0x27, 0xA3, 0x81, 0x24, + 0xDA, 0x6F, 0xCB, 0x01, 0xF9, 0x99, 0x9A, 0xA9, 0x32, 0xC2, 0x22, 0x87, + 0x61, 0x41, 0x91, 0x3B, 0xCB, 0xC3, 0x68, 0x1B, 0x06, 0xC5, 0x4C, 0xA9, + 0x2B, 0xC1, 0x67, 0x17, 0x22, 0x1D, 0x2B, 0xED, 0xF9, 0x29, 0x89, 0x93, + 0xA2, 0x78, 0xBD, 0x92, 0x6B, 0xA0, 0xA3, 0x0D, 0xA2, 0x7E, 0xCA, 0x93, + 0xB3, 0xA6, 0xD1, 0x8C, 0x35, 0xD5, 0x75, 0xF9, 0x17, 0xF6, 0xCF, 0x45, + 0xC5, 0xE5, 0x7A, 0xEC, 0x77, 0x93, 0xA0, 0x8F, 0x23, 0xAE, 0x0E, 0x1A, + 0x03, 0x7F, 0xBE, 0xD4, 0xD0, 0xED, 0x2E, 0x7B, 0xAB, 0x46, 0x23, 0x5B, + 0xFF, 0x2C, 0xE6, 0x54, 0x7A, 0x94, 0xC0, 0x2A, 0x15, 0xF0, 0xC9, 0x8D, + 0xB0, 0x7A, 0x3B, 0x24, 0xE1, 0xD7, 0x68, 0xE2, 0x31, 0x3C, 0x06, 0x33, + 0x46, 0xB6, 0x54, 0x11, 0xA6, 0xA5, 0x2F, 0x22, 0x54, 0x2A, 0x58, 0x0D, + 0x01, 0x02, 0xF1, 0xFA, 0x15, 0x51, 0x67, 0x6C, 0xC0, 0xFA, 0xD7, 0xB6, + 0x1B, 0x7F, 0xD1, 0x56, 0x88, 0x2F, 0x1A, 0x3A, 0x8D, 0x3B, 0xBB, 0x82, + 0x11, 0xE0, 0x47, 0x00, 0xD0, 0x52, 0x87, 0xAB, 0xFB, 0x86, 0x7E, 0x0F, + 0x24, 0x6B, 0x40, 0x9D, 0x34, 0x67, 0xBC, 0x8D, 0xC7, 0x2D, 0x86, 0x6F, + 0x79, 0x3E, 0x8E, 0xA9, 0x3C, 0x17, 0x4B, 0x7F, 0xB0, 0x99, 0xE3, 0xB0, + 0x71, 0x60, 0xDC, 0x0B, 0xF5, 0x64, 0xC3, 0xCE, 0x43, 0xBC, 0x6D, 0x71, + 0xB9, 0xD2, 0xDE, 0x27, 0x5B, 0x8A, 0xE8, 0xD8, 0xC6, 0xAE, 0xE1, 0x59, + 0x7D, 0xCF, 0x28, 0x2D, 0x35, 0xB8, 0x95, 0x56, 0x1A, 0xF1, 0xB2, 0x58, + 0x4B, 0xB7, 0x12, 0x37, 0xC8, 0x7C, 0xB3, 0xED, 0x4B, 0x80, 0xE1, 0x8D, + 0xFA, 0x32, 0x23, 0xB6, 0x6F, 0xB7, 0x48, 0x95, 0x08, 0xB1, 0x44, 0x4E, + 0x85, 0x8C, 0x3A, 0x02, 0x54, 0x20, 0x2F, 0xDF, 0xBF, 0x57, 0x4F, 0x3B, + 0x3A, 0x90, 0x21, 0xD7, 0xC1, 0x26, 0x35, 0x54, 0x20, 0xEC, 0xC7, 0x3F, + 0x47, 0xEC, 0xEF, 0x5A, 0xBF, 0x4B, 0x7A, 0xC1, 0xAD, 0x3B, 0x17, 0x50, + 0x5C, 0x62, 0xD8, 0x0F, 0x4B, 0x4A, 0xDC, 0x2B, 0xFA, 0x6E, 0xBC, 0x73, + 0x92, 0xCD, 0xEC, 0xC7, 0x50, 0xE8, 0x41, 0x96, 0xD7, 0xA9, 0x7E, 0x6D, + 0xD8, 0xE9, 0x1D, 0x8F, 0x8A, 0xB5, 0xB9, 0x58, 0x92, 0xBA, 0x4A, 0x92, + 0x2B, 0x0C, 0x56, 0xFD, 0x80, 0xEB, 0x08, 0xF0, 0x5E, 0x29, 0x6E, 0x1B, + 0x1C, 0x0C, 0xAF, 0x8F, 0x93, 0x89, 0xAD, 0xDB, 0xBD, 0xA3, 0x9E, 0x21, + 0xCA, 0x89, 0x19, 0xEC, 0xDF, 0xB5, 0xC3, 0x1A, 0xEB, 0x16, 0xFE, 0x78, + 0x36, 0x4C, 0xD6, 0x6E, 0xD0, 0x3E, 0x17, 0x1C, 0x90, 0x17, 0x6B, 0x26, + 0xBA, 0xFB, 0x7A, 0x2F, 0xBF, 0x11, 0x1C, 0x18, 0x0E, 0x2D, 0x73, 0x03, + 0x8F, 0xA0, 0xE5, 0x35, 0xA0, 0x5A, 0xE2, 0x4C, 0x75, 0x1D, 0x71, 0xE1, + 0x39, 0x38, 0x53, 0x78, 0x40, 0xCC, 0x83, 0x93, 0xD7, 0x0A, 0x9E, 0x9D, + 0x5B, 0x8F, 0x8A, 0xE4, 0xE5, 0xE0, 0x48, 0xE4, 0x48, 0xB2, 0x47, 0xCD, + 0x4E, 0x2A, 0x75, 0x2A, 0x7B, 0xF2, 0x22, 0xF6, 0xC9, 0xBE, 0x09, 0x91, + 0x96, 0x57, 0x7A, 0x88, 0x88, 0xAC, 0xEE, 0x70, 0xAC, 0xF9, 0xDC, 0x29, + 0xE3, 0x0C, 0x1C, 0x3B, 0x12, 0x4E, 0x44, 0xD6, 0xA7, 0x4E, 0xB0, 0x26, + 0xC8, 0xF3, 0xD9, 0x1A, 0x97, 0x91, 0x68, 0xEA, 0xEF, 0x8D, 0x46, 0x06, + 0xD2, 0x56, 0x45, 0x58, 0x9A, 0x3C, 0x0C, 0x0F, 0x83, 0xB8, 0x05, 0x25, + 0xC3, 0x39, 0xCF, 0x3B, 0xA4, 0x34, 0x89, 0xB7, 0x79, 0x12, 0x2F, 0x47, + 0xC5, 0xE7, 0xA9, 0x97, 0x69, 0xFC, 0xA6, 0x77, 0x67, 0xB5, 0xDF, 0x7B, + 0xF1, 0x7A, 0x65, 0x15, 0xE4, 0x61, 0x56, 0x65 +}; + +static const unsigned char TA529_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA530_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA530_EC_Q[] = { + 0x04, 0x1A, 0xAC, 0x54, 0x5A, 0xA9, 0xF9, 0x68, 0x23, 0xE7, 0x7A, 0xD5, + 0x24, 0x6F, 0x53, 0xC6, 0x5A, 0xD8, 0x4B, 0xAB, 0xC6, 0xD5, 0xB6, 0xD1, + 0xE6, 0x73, 0x71, 0xAE, 0xDD, 0x9C, 0xD6, 0x0C, 0x61, 0xFD, 0xDB, 0xA0, + 0x89, 0x03, 0xB8, 0x05, 0x14, 0xEC, 0x57, 0xCE, 0xEE, 0x5D, 0x3F, 0xE2, + 0x21, 0xB3, 0xCE, 0xF7, 0xD4, 0x8A, 0x79, 0xE0, 0xA3, 0x83, 0x7E, 0x2D, + 0x97, 0xD0, 0x61, 0xC4, 0xF1, 0x99, 0xDC, 0x25, 0x91, 0x63, 0xAB, 0x7F, + 0x30, 0xA3, 0xB4, 0x70, 0xE2, 0xC7, 0xA1, 0x33, 0x9C, 0xF3, 0xBF, 0x2E, + 0x5C, 0x53, 0xB1, 0x5F, 0xB3, 0x7D, 0x32, 0x7F, 0x8A, 0x34, 0xE3, 0x79, + 0x79 +}; + +static const unsigned char TA531_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA531_RSA_N[] = { + 0x80, 0x12, 0x65, 0x17, 0x36, 0x0E, 0xC3, 0xDB, 0x08, 0xB3, 0xD0, 0xAC, + 0x57, 0x0D, 0x76, 0xED, 0xCD, 0x27, 0xD3, 0x4C, 0xAD, 0x50, 0x83, 0x61, + 0xE2, 0xAA, 0x20, 0x4D, 0x09, 0x2D, 0x64, 0x09, 0xDC, 0xCE, 0x89, 0x9F, + 0xCC, 0x3D, 0xA9, 0xEC, 0xF6, 0xCF, 0xC1, 0xDC, 0xF1, 0xD3, 0xB1, 0xD6, + 0x7B, 0x37, 0x28, 0x11, 0x2B, 0x47, 0xDA, 0x39, 0xC6, 0xBC, 0x3A, 0x19, + 0xB4, 0x5F, 0xA6, 0xBD, 0x7D, 0x9D, 0xA3, 0x63, 0x42, 0xB6, 0x76, 0xF2, + 0xA9, 0x3B, 0x2B, 0x91, 0xF8, 0xE2, 0x6F, 0xD0, 0xEC, 0x16, 0x20, 0x90, + 0x09, 0x3E, 0xE2, 0xE8, 0x74, 0xC9, 0x18, 0xB4, 0x91, 0xD4, 0x62, 0x64, + 0xDB, 0x7F, 0xA3, 0x06, 0xF1, 0x88, 0x18, 0x6A, 0x90, 0x22, 0x3C, 0xBC, + 0xFE, 0x13, 0xF0, 0x87, 0x14, 0x7B, 0xF6, 0xE4, 0x1F, 0x8E, 0xD4, 0xE4, + 0x51, 0xC6, 0x11, 0x67, 0x46, 0x08, 0x51, 0xCB, 0x86, 0x14, 0x54, 0x3F, + 0xBC, 0x33, 0xFE, 0x7E, 0x6C, 0x9C, 0xFF, 0x16, 0x9D, 0x18, 0xBD, 0x51, + 0x8E, 0x35, 0xA6, 0xA7, 0x66, 0xC8, 0x72, 0x67, 0xDB, 0x21, 0x66, 0xB1, + 0xD4, 0x9B, 0x78, 0x03, 0xC0, 0x50, 0x3A, 0xE8, 0xCC, 0xF0, 0xDC, 0xBC, + 0x9E, 0x4C, 0xFE, 0xAF, 0x05, 0x96, 0x35, 0x1F, 0x57, 0x5A, 0xB7, 0xFF, + 0xCE, 0xF9, 0x3D, 0xB7, 0x2C, 0xB6, 0xF6, 0x54, 0xDD, 0xC8, 0xE7, 0x12, + 0x3A, 0x4D, 0xAE, 0x4C, 0x8A, 0xB7, 0x5C, 0x9A, 0xB4, 0xB7, 0x20, 0x3D, + 0xCA, 0x7F, 0x22, 0x34, 0xAE, 0x7E, 0x3B, 0x68, 0x66, 0x01, 0x44, 0xE7, + 0x01, 0x4E, 0x46, 0x53, 0x9B, 0x33, 0x60, 0xF7, 0x94, 0xBE, 0x53, 0x37, + 0x90, 0x73, 0x43, 0xF3, 0x32, 0xC3, 0x53, 0xEF, 0xDB, 0xAA, 0xFE, 0x74, + 0x4E, 0x69, 0xC7, 0x6B, 0x8C, 0x60, 0x93, 0xDE, 0xC4, 0xC7, 0x0C, 0xDF, + 0xE1, 0x32, 0xAE, 0xCC, 0x93, 0x3B, 0x51, 0x78, 0x95, 0x67, 0x8B, 0xEE, + 0x3D, 0x56, 0xFE, 0x0C, 0xD0, 0x69, 0x0F, 0x1B, 0x0F, 0xF3, 0x25, 0x26, + 0x6B, 0x33, 0x6D, 0xF7, 0x6E, 0x47, 0xFA, 0x73, 0x43, 0xE5, 0x7E, 0x0E, + 0xA5, 0x66, 0xB1, 0x29, 0x7C, 0x32, 0x84, 0x63, 0x55, 0x89, 0xC4, 0x0D, + 0xC1, 0x93, 0x54, 0x30, 0x19, 0x13, 0xAC, 0xD3, 0x7D, 0x37, 0xA7, 0xEB, + 0x5D, 0x3A, 0x6C, 0x35, 0x5C, 0xDB, 0x41, 0xD7, 0x12, 0xDA, 0xA9, 0x49, + 0x0B, 0xDF, 0xD8, 0x80, 0x8A, 0x09, 0x93, 0x62, 0x8E, 0xB5, 0x66, 0xCF, + 0x25, 0x88, 0xCD, 0x84, 0xB8, 0xB1, 0x3F, 0xA4, 0x39, 0x0F, 0xD9, 0x02, + 0x9E, 0xEB, 0x12, 0x4C, 0x95, 0x7C, 0xF3, 0x6B, 0x05, 0xA9, 0x5E, 0x16, + 0x83, 0xCC, 0xB8, 0x67, 0xE2, 0xE8, 0x13, 0x9D, 0xCC, 0x5B, 0x82, 0xD3, + 0x4C, 0xB3, 0xED, 0x5B, 0xFF, 0xDE, 0xE5, 0x73, 0xAC, 0x23, 0x3B, 0x2D, + 0x00, 0xBF, 0x35, 0x55, 0x74, 0x09, 0x49, 0xD8, 0x49, 0x58, 0x1A, 0x7F, + 0x92, 0x36, 0xE6, 0x51, 0x92, 0x0E, 0xF3, 0x26, 0x7D, 0x1C, 0x4D, 0x17, + 0xBC, 0xC9, 0xEC, 0x43, 0x26, 0xD0, 0xBF, 0x41, 0x5F, 0x40, 0xA9, 0x44, + 0x44, 0xF4, 0x99, 0xE7, 0x57, 0x87, 0x9E, 0x50, 0x1F, 0x57, 0x54, 0xA8, + 0x3E, 0xFD, 0x74, 0x63, 0x2F, 0xB1, 0x50, 0x65, 0x09, 0xE6, 0x58, 0x42, + 0x2E, 0x43, 0x1A, 0x4C, 0xB4, 0xF0, 0x25, 0x47, 0x59, 0xFA, 0x04, 0x1E, + 0x93, 0xD4, 0x26, 0x46, 0x4A, 0x50, 0x81, 0xB2, 0xDE, 0xBE, 0x78, 0xB7, + 0xFC, 0x67, 0x15, 0xE1, 0xC9, 0x57, 0x84, 0x1E, 0x0F, 0x63, 0xD6, 0xE9, + 0x62, 0xBA, 0xD6, 0x5F, 0x55, 0x2E, 0xEA, 0x5C, 0xC6, 0x28, 0x08, 0x04, + 0x25, 0x39, 0xB8, 0x0E, 0x2B, 0xA9, 0xF2, 0x4C, 0x97, 0x1C, 0x07, 0x3F, + 0x0D, 0x52, 0xF5, 0xED, 0xEF, 0x2F, 0x82, 0x0F +}; + +static const unsigned char TA531_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA532_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x15, 0x77, 0x77, 0x77, 0x2E, 0x78, 0x72, 0x61, 0x6D, 0x70, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x58, + 0x52, 0x61, 0x6D, 0x70, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x24, 0x58, 0x52, 0x61, 0x6D, 0x70, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA532_RSA_N[] = { + 0x98, 0x24, 0x1E, 0xBD, 0x15, 0xB4, 0xBA, 0xDF, 0xC7, 0x8C, 0xA5, 0x27, + 0xB6, 0x38, 0x0B, 0x69, 0xF3, 0xB6, 0x4E, 0xA8, 0x2C, 0x2E, 0x21, 0x1D, + 0x5C, 0x44, 0xDF, 0x21, 0x5D, 0x7E, 0x23, 0x74, 0xFE, 0x5E, 0x7E, 0xB4, + 0x4A, 0xB7, 0xA6, 0xAD, 0x1F, 0xAE, 0xE0, 0x06, 0x16, 0xE2, 0x9B, 0x5B, + 0xD9, 0x67, 0x74, 0x6B, 0x5D, 0x80, 0x8F, 0x29, 0x9D, 0x86, 0x1B, 0xD9, + 0x9C, 0x0D, 0x98, 0x6D, 0x76, 0x10, 0x28, 0x58, 0xE4, 0x65, 0xB0, 0x7F, + 0x4A, 0x98, 0x79, 0x9F, 0xE0, 0xC3, 0x31, 0x7E, 0x80, 0x2B, 0xB5, 0x8C, + 0xC0, 0x40, 0x3B, 0x11, 0x86, 0xD0, 0xCB, 0xA2, 0x86, 0x36, 0x60, 0xA4, + 0xD5, 0x30, 0x82, 0x6D, 0xD9, 0x6E, 0xD0, 0x0F, 0x12, 0x04, 0x33, 0x97, + 0x5F, 0x4F, 0x61, 0x5A, 0xF0, 0xE4, 0xF9, 0x91, 0xAB, 0xE7, 0x1D, 0x3B, + 0xBC, 0xE8, 0xCF, 0xF4, 0x6B, 0x2D, 0x34, 0x7C, 0xE2, 0x48, 0x61, 0x1C, + 0x8E, 0xF3, 0x61, 0x44, 0xCC, 0x6F, 0xA0, 0x4A, 0xA9, 0x94, 0xB0, 0x4D, + 0xDA, 0xE7, 0xA9, 0x34, 0x7A, 0x72, 0x38, 0xA8, 0x41, 0xCC, 0x3C, 0x94, + 0x11, 0x7D, 0xEB, 0xC8, 0xA6, 0x8C, 0xB7, 0x86, 0xCB, 0xCA, 0x33, 0x3B, + 0xD9, 0x3D, 0x37, 0x8B, 0xFB, 0x7A, 0x3E, 0x86, 0x2C, 0xE7, 0x73, 0xD7, + 0x0A, 0x57, 0xAC, 0x64, 0x9B, 0x19, 0xEB, 0xF4, 0x0F, 0x04, 0x08, 0x8A, + 0xAC, 0x03, 0x17, 0x19, 0x64, 0xF4, 0x5A, 0x25, 0x22, 0x8D, 0x34, 0x2C, + 0xB2, 0xF6, 0x68, 0x1D, 0x12, 0x6D, 0xD3, 0x8A, 0x1E, 0x14, 0xDA, 0xC4, + 0x8F, 0xA6, 0xE2, 0x23, 0x85, 0xD5, 0x7A, 0x0D, 0xBD, 0x6A, 0xE0, 0xE9, + 0xEC, 0xEC, 0x17, 0xBB, 0x42, 0x1B, 0x67, 0xAA, 0x25, 0xED, 0x45, 0x83, + 0x21, 0xFC, 0xC1, 0xC9, 0x7C, 0xD5, 0x62, 0x3E, 0xFA, 0xF2, 0xC5, 0x2D, + 0xD3, 0xFD, 0xD4, 0x65 +}; + +static const unsigned char TA532_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA533_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x08, 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x10, 0x63, 0x65, 0x72, + 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA533_RSA_N[] = { + 0xB7, 0x33, 0xB9, 0x7E, 0xC8, 0x25, 0x4A, 0x8E, 0xB5, 0xDB, 0xB4, 0x28, + 0x1B, 0xAA, 0x57, 0x90, 0xE8, 0xD1, 0x22, 0xD3, 0x64, 0xBA, 0xD3, 0x93, + 0xE8, 0xD4, 0xAC, 0x86, 0x61, 0x40, 0x6A, 0x60, 0x57, 0x68, 0x54, 0x84, + 0x4D, 0xBC, 0x6A, 0x54, 0x02, 0x05, 0xFF, 0xDF, 0x9B, 0x9A, 0x2A, 0xAE, + 0x5D, 0x07, 0x8F, 0x4A, 0xC3, 0x28, 0x7F, 0xEF, 0xFB, 0x2B, 0xFA, 0x79, + 0xF1, 0xC7, 0xAD, 0xF0, 0x10, 0x53, 0x24, 0x90, 0x8B, 0x66, 0xC9, 0xA8, + 0x88, 0xAB, 0xAF, 0x5A, 0xA3, 0x00, 0xE9, 0xBE, 0xBA, 0x46, 0xEE, 0x5B, + 0x73, 0x7B, 0x2C, 0x17, 0x82, 0x81, 0x5E, 0x62, 0x2C, 0xA1, 0x02, 0x65, + 0xB3, 0xBD, 0xC5, 0x2B, 0x00, 0x7E, 0xC4, 0xFC, 0x03, 0x33, 0x57, 0x0D, + 0xED, 0xE2, 0xFA, 0xCE, 0x5D, 0x45, 0xD6, 0x38, 0xCD, 0x35, 0xB6, 0xB2, + 0xC1, 0xD0, 0x9C, 0x81, 0x4A, 0xAA, 0xE4, 0xB2, 0x01, 0x5C, 0x1D, 0x8F, + 0x5F, 0x99, 0xC4, 0xB1, 0xAD, 0xDB, 0x88, 0x21, 0xEB, 0x90, 0x08, 0x82, + 0x80, 0xF3, 0x30, 0xA3, 0x43, 0xE6, 0x90, 0x82, 0xAE, 0x55, 0x28, 0x49, + 0xED, 0x5B, 0xD7, 0xA9, 0x10, 0x38, 0x0E, 0xFE, 0x8F, 0x4C, 0x5B, 0x9B, + 0x46, 0xEA, 0x41, 0xF5, 0xB0, 0x08, 0x74, 0xC3, 0xD0, 0x88, 0x33, 0xB6, + 0x7C, 0xD7, 0x74, 0xDF, 0xDC, 0x84, 0xD1, 0x43, 0x0E, 0x75, 0x39, 0xA1, + 0x25, 0x40, 0x28, 0xEA, 0x78, 0xCB, 0x0E, 0x2C, 0x2E, 0x39, 0x9D, 0x8C, + 0x8B, 0x6E, 0x16, 0x1C, 0x2F, 0x26, 0x82, 0x10, 0xE2, 0xE3, 0x65, 0x94, + 0x0A, 0x04, 0xC0, 0x5E, 0xF7, 0x5D, 0x5B, 0xF8, 0x10, 0xE2, 0xD0, 0xBA, + 0x7A, 0x4B, 0xFB, 0xDE, 0x37, 0x00, 0x00, 0x1A, 0x5B, 0x28, 0xE3, 0xD2, + 0x9C, 0x73, 0x3E, 0x32, 0x87, 0x98, 0xA1, 0xC9, 0x51, 0x2F, 0xD7, 0xDE, + 0xAC, 0x33, 0xB3, 0x4F +}; + +static const unsigned char TA533_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA534_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x43, 0x45, 0x52, 0x54, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x53, + 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x13, + 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, + 0x54, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA534_RSA_N[] = { + 0xC0, 0xC5, 0x75, 0x19, 0x91, 0x7D, 0x44, 0x74, 0x74, 0x87, 0xFE, 0x0E, + 0x3B, 0x96, 0xDC, 0xD8, 0x01, 0x16, 0xCC, 0xEE, 0x63, 0x91, 0xE7, 0x0B, + 0x6F, 0xCE, 0x3B, 0x0A, 0x69, 0x1A, 0x7C, 0xC2, 0xE3, 0xAF, 0x82, 0x8E, + 0x86, 0xD7, 0x5E, 0x8F, 0x57, 0xEB, 0xD3, 0x21, 0x59, 0xFD, 0x39, 0x37, + 0x42, 0x30, 0xBE, 0x50, 0xEA, 0xB6, 0x0F, 0xA9, 0x88, 0xD8, 0x2E, 0x2D, + 0x69, 0x21, 0xE7, 0xD1, 0x37, 0x18, 0x4E, 0x7D, 0x91, 0xD5, 0x16, 0x5F, + 0x6B, 0x5B, 0x00, 0xC2, 0x39, 0x43, 0x0D, 0x36, 0x85, 0x52, 0xB9, 0x53, + 0x65, 0x0F, 0x1D, 0x42, 0xE5, 0x8F, 0xCF, 0x05, 0xD3, 0xEE, 0xDC, 0x0C, + 0x1A, 0xD9, 0xB8, 0x8B, 0x78, 0x22, 0x67, 0xE4, 0x69, 0xB0, 0x68, 0xC5, + 0x3C, 0xE4, 0x6C, 0x5A, 0x46, 0xE7, 0xCD, 0xC7, 0xFA, 0xEF, 0xC4, 0xEC, + 0x4B, 0xBD, 0x6A, 0xA4, 0xAC, 0xFD, 0xCC, 0x28, 0x51, 0xEF, 0x92, 0xB4, + 0x29, 0xAB, 0xAB, 0x35, 0x9A, 0x4C, 0xE4, 0xC4, 0x08, 0xC6, 0x26, 0xCC, + 0xF8, 0x69, 0x9F, 0xE4, 0x9C, 0xF0, 0x29, 0xD3, 0x5C, 0xF9, 0xC6, 0x16, + 0x25, 0x9E, 0x23, 0xC3, 0x20, 0xC1, 0x3D, 0x0F, 0x3F, 0x38, 0x40, 0xB0, + 0xFE, 0x82, 0x44, 0x38, 0xAA, 0x5A, 0x1A, 0x8A, 0x6B, 0x63, 0x58, 0x38, + 0xB4, 0x15, 0xD3, 0xB6, 0x11, 0x69, 0x7B, 0x1E, 0x54, 0xEE, 0x8C, 0x1A, + 0x22, 0xAC, 0x72, 0x97, 0x3F, 0x23, 0x59, 0x9B, 0xC9, 0x22, 0x84, 0xC1, + 0x07, 0x4F, 0xCC, 0x7F, 0xE2, 0x57, 0xCA, 0x12, 0x70, 0xBB, 0xA6, 0x65, + 0xF3, 0x69, 0x75, 0x63, 0xBD, 0x95, 0xFB, 0x1B, 0x97, 0xCD, 0xE4, 0xA8, + 0xAF, 0xF6, 0xD1, 0x4E, 0xA8, 0xD9, 0x8A, 0x71, 0x24, 0xCD, 0x36, 0x3D, + 0xBC, 0x96, 0xC4, 0xF1, 0x6C, 0xA9, 0xAE, 0xE5, 0xCF, 0x0D, 0x6E, 0x28, + 0x0D, 0xB0, 0x0E, 0xB5, 0xCA, 0x51, 0x7B, 0x78, 0x14, 0xC3, 0x20, 0x2F, + 0x7F, 0xFB, 0x14, 0x55, 0xE1, 0x11, 0x99, 0xFD, 0xD5, 0x0A, 0xA1, 0x9E, + 0x02, 0xE3, 0x62, 0x5F, 0xEB, 0x35, 0x4B, 0x2C, 0xB8, 0x72, 0xE8, 0x3E, + 0x3D, 0x4F, 0xAC, 0x2C, 0xBB, 0x2E, 0x86, 0xE2, 0xA3, 0x76, 0x8F, 0xE5, + 0x93, 0x2A, 0xCF, 0xA5, 0xAB, 0xC8, 0x5C, 0x8D, 0x4B, 0x06, 0xFF, 0x12, + 0x46, 0xAC, 0x78, 0xCB, 0x14, 0x07, 0x35, 0xE0, 0xA9, 0xDF, 0x8B, 0xE9, + 0xAF, 0x15, 0x4F, 0x16, 0x89, 0x5B, 0xBD, 0xF6, 0x8D, 0xC6, 0x59, 0xAE, + 0x88, 0x85, 0x0E, 0xC1, 0x89, 0xEB, 0x1F, 0x67, 0xC5, 0x45, 0x8E, 0xFF, + 0x6D, 0x37, 0x36, 0x2B, 0x78, 0x66, 0x83, 0x91, 0x51, 0x2B, 0x3D, 0xFF, + 0x51, 0x77, 0x76, 0x62, 0xA1, 0xEC, 0x67, 0x3E, 0x3E, 0x81, 0x83, 0xE0, + 0x56, 0xA9, 0x50, 0x1F, 0x1F, 0x7A, 0x99, 0xAB, 0x63, 0xBF, 0x84, 0x17, + 0x77, 0xF1, 0x0D, 0x3B, 0xDF, 0xF7, 0x9C, 0x61, 0xB3, 0x35, 0x98, 0x8A, + 0x3A, 0xB2, 0xEC, 0x3C, 0x1A, 0x37, 0x3F, 0x7E, 0x8F, 0x92, 0xCF, 0xD9, + 0x12, 0x14, 0x64, 0xDA, 0x10, 0x02, 0x15, 0x41, 0xFF, 0x4F, 0xC4, 0xEB, + 0x1C, 0xA3, 0xC9, 0xFA, 0x99, 0xF7, 0x46, 0xE9, 0xE1, 0x18, 0xD9, 0xB1, + 0xB8, 0x32, 0x2D, 0xCB, 0x14, 0x0C, 0x50, 0xD8, 0x83, 0x65, 0x83, 0xEE, + 0xB9, 0x5C, 0xCF, 0xCB, 0x05, 0x5A, 0x4C, 0xFA, 0x19, 0x97, 0x6B, 0xD6, + 0x5D, 0x13, 0xD3, 0xC2, 0x5C, 0x54, 0xBC, 0x32, 0x73, 0xA0, 0x78, 0xF5, + 0xF1, 0x6D, 0x1E, 0xCB, 0x9F, 0xA5, 0xA6, 0x9F, 0x22, 0xDC, 0xD1, 0x51, + 0x9E, 0x82, 0x79, 0x64, 0x60, 0x29, 0x13, 0x3E, 0xA3, 0xFD, 0x4F, 0x72, + 0x6A, 0xAB, 0xE2, 0xD4, 0xE5, 0xB8, 0x24, 0x55, 0x2C, 0x44, 0x4B, 0x8A, + 0x88, 0x44, 0x9C, 0xCA, 0x84, 0xD3, 0x2A, 0x3B +}; + +static const unsigned char TA534_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA535_DN[] = { + 0x30, 0x71, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, 0x63, + 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0E, 0x56, 0x41, 0x54, + 0x48, 0x55, 0x2D, 0x32, 0x33, 0x35, 0x38, 0x34, 0x34, 0x39, 0x37, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x15, 0x65, 0x2D, + 0x53, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA535_EC_Q[] = { + 0x04, 0x96, 0xDC, 0x3D, 0x8A, 0xD8, 0xB0, 0x7B, 0x6F, 0xC6, 0x27, 0xBE, + 0x44, 0x90, 0xB1, 0xB3, 0x56, 0x15, 0x7B, 0x8E, 0x43, 0x24, 0x7D, 0x1A, + 0x84, 0x59, 0xEE, 0x63, 0x68, 0xB2, 0xC6, 0x5E, 0x87, 0xD0, 0x15, 0x48, + 0x1E, 0xA8, 0x90, 0xAD, 0xBD, 0x53, 0xA2, 0xDA, 0xDE, 0x3A, 0x90, 0xA6, + 0x60, 0x5F, 0x68, 0x32, 0xB5, 0x86, 0x41, 0xDF, 0x87, 0x5B, 0x2C, 0x7B, + 0xC5, 0xFE, 0x7C, 0x7A, 0xDA +}; + +static const unsigned char TA536_DN[] = { + 0x30, 0x5E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x21, 0x65, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA536_RSA_N[] = { + 0xE1, 0x25, 0x0F, 0xEE, 0x8D, 0xDB, 0x88, 0x33, 0x75, 0x67, 0xCD, 0xAD, + 0x1F, 0x7D, 0x3A, 0x4E, 0x6D, 0x9D, 0xD3, 0x2F, 0x14, 0xF3, 0x63, 0x74, + 0xCB, 0x01, 0x21, 0x6A, 0x37, 0xEA, 0x84, 0x50, 0x07, 0x4B, 0x26, 0x5B, + 0x09, 0x43, 0x6C, 0x21, 0x9E, 0x6A, 0xC8, 0xD5, 0x03, 0xF5, 0x60, 0x69, + 0x8F, 0xCC, 0xF0, 0x22, 0xE4, 0x1F, 0xE7, 0xF7, 0x6A, 0x22, 0x31, 0xB7, + 0x2C, 0x15, 0xF2, 0xE0, 0xFE, 0x00, 0x6A, 0x43, 0xFF, 0x87, 0x65, 0xC6, + 0xB5, 0x1A, 0xC1, 0xA7, 0x4C, 0x6D, 0x22, 0x70, 0x21, 0x8A, 0x31, 0xF2, + 0x97, 0x74, 0x89, 0x09, 0x12, 0x26, 0x1C, 0x9E, 0xCA, 0xD9, 0x12, 0xA2, + 0x95, 0x3C, 0xDA, 0xE9, 0x67, 0xBF, 0x08, 0xA0, 0x64, 0xE3, 0xD6, 0x42, + 0xB7, 0x45, 0xEF, 0x97, 0xF4, 0xF6, 0xF5, 0xD7, 0xB5, 0x4A, 0x15, 0x02, + 0x58, 0x7D, 0x98, 0x58, 0x4B, 0x60, 0xBC, 0xCD, 0xD7, 0x0D, 0x9A, 0x13, + 0x33, 0x53, 0xD1, 0x61, 0xF9, 0x7A, 0xD5, 0xD7, 0x78, 0xB3, 0x9A, 0x33, + 0xF7, 0x00, 0x86, 0xCE, 0x1D, 0x4D, 0x94, 0x38, 0xAF, 0xA8, 0xEC, 0x78, + 0x51, 0x70, 0x8A, 0x5C, 0x10, 0x83, 0x51, 0x21, 0xF7, 0x11, 0x3D, 0x34, + 0x86, 0x5E, 0xE5, 0x48, 0xCD, 0x97, 0x81, 0x82, 0x35, 0x4C, 0x19, 0xEC, + 0x65, 0xF6, 0x6B, 0xC5, 0x05, 0xA1, 0xEE, 0x47, 0x13, 0xD6, 0xB3, 0x21, + 0x27, 0x94, 0x10, 0x0A, 0xD9, 0x24, 0x3B, 0xBA, 0xBE, 0x44, 0x13, 0x46, + 0x30, 0x3F, 0x97, 0x3C, 0xD8, 0xD7, 0xD7, 0x6A, 0xEE, 0x3B, 0x38, 0xE3, + 0x2B, 0xD4, 0x97, 0x0E, 0xB9, 0x1B, 0xE7, 0x07, 0x49, 0x7F, 0x37, 0x2A, + 0xF9, 0x77, 0x78, 0xCF, 0x54, 0xED, 0x5B, 0x46, 0x9D, 0xA3, 0x80, 0x0E, + 0x91, 0x43, 0xC1, 0xD6, 0x5B, 0x5F, 0x14, 0xBA, 0x9F, 0xA6, 0x8D, 0x24, + 0x47, 0x40, 0x59, 0xBF, 0x72, 0x38, 0xB2, 0x36, 0x6C, 0x37, 0xFF, 0x99, + 0xD1, 0x5D, 0x0E, 0x59, 0x0A, 0xAB, 0x69, 0xF7, 0xC0, 0xB2, 0x04, 0x45, + 0x7A, 0x54, 0x00, 0xAE, 0xBE, 0x53, 0xF6, 0xB5, 0xE7, 0xE1, 0xF8, 0x3C, + 0xA3, 0x31, 0xD2, 0xA9, 0xFE, 0x21, 0x52, 0x64, 0xC5, 0xA6, 0x67, 0xF0, + 0x75, 0x07, 0x06, 0x94, 0x14, 0x81, 0x55, 0xC6, 0x27, 0xE4, 0x01, 0x8F, + 0x17, 0xC1, 0x6A, 0x71, 0xD7, 0xBE, 0x4B, 0xFB, 0x94, 0x58, 0x7D, 0x7E, + 0x11, 0x33, 0xB1, 0x42, 0xF7, 0x62, 0x6C, 0x18, 0xD6, 0xCF, 0x09, 0x68, + 0x3E, 0x7F, 0x6C, 0xF6, 0x1E, 0x8F, 0x62, 0xAD, 0xA5, 0x63, 0xDB, 0x09, + 0xA7, 0x1F, 0x22, 0x42, 0x41, 0x1E, 0x6F, 0x99, 0x8A, 0x3E, 0xD7, 0xF9, + 0x3F, 0x40, 0x7A, 0x79, 0xB0, 0xA5, 0x01, 0x92, 0xD2, 0x9D, 0x3D, 0x08, + 0x15, 0xA5, 0x10, 0x01, 0x2D, 0xB3, 0x32, 0x76, 0xA8, 0x95, 0x0D, 0xB3, + 0x7A, 0x9A, 0xFB, 0x07, 0x10, 0x78, 0x11, 0x6F, 0xE1, 0x8F, 0xC7, 0xBA, + 0x0F, 0x25, 0x1A, 0x74, 0x2A, 0xE5, 0x1C, 0x98, 0x41, 0x99, 0xDF, 0x21, + 0x87, 0xE8, 0x95, 0x06, 0x6A, 0x0A, 0xB3, 0x6A, 0x47, 0x76, 0x65, 0xF6, + 0x3A, 0xCF, 0x8F, 0x62, 0x17, 0x19, 0x7B, 0x0A, 0x28, 0xCD, 0x1A, 0xD2, + 0x83, 0x1E, 0x21, 0xC7, 0x2C, 0xBF, 0xBE, 0xFF, 0x61, 0x68, 0xB7, 0x67, + 0x1B, 0xBB, 0x78, 0x4D, 0x8D, 0xCE, 0x67, 0xE5, 0xE4, 0xC1, 0x8E, 0xB7, + 0x23, 0x66, 0xE2, 0x9D, 0x90, 0x75, 0x34, 0x98, 0xA9, 0x36, 0x2B, 0x8A, + 0x9A, 0x94, 0xB9, 0x9D, 0xEC, 0xCC, 0x8A, 0xB1, 0xF8, 0x25, 0x89, 0x5C, + 0x5A, 0xB6, 0x2F, 0x8C, 0x1F, 0x6D, 0x79, 0x24, 0xA7, 0x52, 0x68, 0xC3, + 0x84, 0x35, 0xE2, 0x66, 0x8D, 0x63, 0x0E, 0x25, 0x4D, 0xD5, 0x19, 0xB2, + 0xE6, 0x79, 0x37, 0xA7, 0x22, 0x9D, 0x54, 0x31 +}; + +static const unsigned char TA536_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA537_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x43, 0x33 +}; + +static const unsigned char TA537_EC_Q[] = { + 0x04, 0xFD, 0xA5, 0x61, 0xAE, 0x7B, 0x26, 0x10, 0x1D, 0xE9, 0xB7, 0x22, + 0x30, 0xAE, 0x06, 0xF4, 0x81, 0xB3, 0xB1, 0x42, 0x71, 0x95, 0x39, 0xBC, + 0xD3, 0x52, 0xE3, 0xAF, 0xAF, 0xF9, 0xF2, 0x97, 0x35, 0x92, 0x36, 0x46, + 0x0E, 0x87, 0x95, 0x8D, 0xB9, 0x39, 0x5A, 0xE9, 0xBB, 0xDF, 0xD0, 0xFE, + 0xC8, 0x07, 0x41, 0x3C, 0xBB, 0x55, 0x6F, 0x83, 0xA3, 0x6A, 0xFB, 0x62, + 0xB0, 0x81, 0x89, 0x02, 0x70, 0x7D, 0x48, 0xC5, 0x4A, 0xE3, 0xE9, 0x22, + 0x54, 0x22, 0x4D, 0x93, 0xBB, 0x42, 0x0C, 0xAF, 0x77, 0x9C, 0x23, 0xA6, + 0x7D, 0xD7, 0x61, 0x11, 0xCE, 0x65, 0xC7, 0xF8, 0x7F, 0xFE, 0xF5, 0xF2, + 0xA9 +}; + +static const unsigned char TA538_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x17, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, + 0x33 +}; + +static const unsigned char TA538_EC_Q[] = { + 0x04, 0x23, 0xA5, 0x0C, 0xB8, 0x2D, 0x12, 0xF5, 0x28, 0xF3, 0xB1, 0xB2, + 0xDD, 0xE2, 0x02, 0x12, 0x80, 0x9E, 0x39, 0x5F, 0x49, 0x4D, 0x9F, 0xC9, + 0x25, 0x34, 0x59, 0x74, 0xEC, 0xBB, 0x06, 0x1C, 0xE7, 0xC0, 0x72, 0xAF, + 0xE8, 0xAE, 0x2F, 0xE1, 0x41, 0x54, 0x87, 0x14, 0xA8, 0x4A, 0xB2, 0xE8, + 0x7C, 0x82, 0xE6, 0x5B, 0x6A, 0xB5, 0xDC, 0xB3, 0x75, 0xCE, 0x8B, 0x06, + 0xD0, 0x86, 0x23, 0xBF, 0x46, 0xD5, 0x8E, 0x0F, 0x3F, 0x04, 0xF4, 0xD7, + 0x1C, 0x92, 0x7E, 0xF6, 0xA5, 0x63, 0xC2, 0xF5, 0x5F, 0x8E, 0x2E, 0x4F, + 0xA1, 0x18, 0x19, 0x02, 0x2B, 0x32, 0x0A, 0x82, 0x64, 0x7D, 0x16, 0x93, + 0xD1 +}; + +static const unsigned char TA539_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x1C, + 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x43, 0x31 +}; + +static const unsigned char TA539_RSA_N[] = { + 0xCF, 0xEB, 0xA9, 0xB9, 0xF1, 0x99, 0x05, 0xCC, 0xD8, 0x28, 0x21, 0x4A, + 0xF3, 0x73, 0x34, 0x51, 0x84, 0x56, 0x10, 0xF5, 0xA0, 0x4F, 0x2C, 0x12, + 0xE3, 0xFA, 0x13, 0x9A, 0x27, 0xD0, 0xCF, 0xF9, 0x79, 0x1A, 0x74, 0x5F, + 0x1D, 0x79, 0x39, 0xFC, 0x5B, 0xF8, 0x70, 0x8E, 0xE0, 0x92, 0x52, 0xF7, + 0xE4, 0x25, 0xF9, 0x54, 0x83, 0xD9, 0x1D, 0xD3, 0xC8, 0x5A, 0x85, 0x3F, + 0x5E, 0xC7, 0xB6, 0x07, 0xEE, 0x3E, 0xC0, 0xCE, 0x9A, 0xAF, 0xAC, 0x56, + 0x42, 0x2A, 0x39, 0x25, 0x70, 0xD6, 0xBF, 0xB5, 0x7B, 0x36, 0xAD, 0xAC, + 0xF6, 0x73, 0xDC, 0xCD, 0xD7, 0x1D, 0x8A, 0x83, 0xA5, 0xFB, 0x2B, 0x90, + 0x15, 0x37, 0x6B, 0x1C, 0x26, 0x47, 0xDC, 0x3B, 0x29, 0x56, 0x93, 0x6A, + 0xB3, 0xC1, 0x6A, 0x3A, 0x9D, 0x3D, 0xF5, 0xC1, 0x97, 0x38, 0x58, 0x05, + 0x8B, 0x1C, 0x11, 0xE3, 0xE4, 0xB4, 0xB8, 0x5D, 0x85, 0x1D, 0x83, 0xFE, + 0x78, 0x5F, 0x0B, 0x45, 0x68, 0x18, 0x48, 0xA5, 0x46, 0x73, 0x34, 0x3B, + 0xFE, 0x0F, 0xC8, 0x76, 0xBB, 0xC7, 0x18, 0xF3, 0x05, 0xD1, 0x86, 0xF3, + 0x85, 0xED, 0xE7, 0xB9, 0xD9, 0x32, 0xAD, 0x55, 0x88, 0xCE, 0xA6, 0xB6, + 0x91, 0xB0, 0x4F, 0xAC, 0x7E, 0x15, 0x23, 0x96, 0xF6, 0x3F, 0xF0, 0x20, + 0x34, 0x16, 0xDE, 0x0A, 0xC6, 0xC4, 0x04, 0x45, 0x79, 0x7F, 0xA7, 0xFD, + 0xBE, 0xD2, 0xA9, 0xA5, 0xAF, 0x9C, 0xC5, 0x23, 0x2A, 0xF7, 0x3C, 0x21, + 0x6C, 0xBD, 0xAF, 0x8F, 0x4E, 0xC5, 0x3A, 0xB2, 0xF3, 0x34, 0x12, 0xFC, + 0xDF, 0x80, 0x1A, 0x49, 0xA4, 0xD4, 0xA9, 0x95, 0xF7, 0x9E, 0x89, 0x5E, + 0xA2, 0x89, 0xAC, 0x94, 0xCB, 0xA8, 0x68, 0x9B, 0xAF, 0x8A, 0x65, 0x27, + 0xCD, 0x89, 0xEE, 0xDD, 0x8C, 0xB5, 0x6B, 0x29, 0x70, 0x43, 0xA0, 0x69, + 0x0B, 0xE4, 0xB9, 0x0F +}; + +static const unsigned char TA539_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA540_DN[] = { + 0x30, 0x67, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x13, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA540_RSA_N[] = { + 0x93, 0x4B, 0xBB, 0xE9, 0x66, 0x8A, 0xEE, 0x9D, 0x5B, 0xD5, 0x34, 0x93, + 0xD0, 0x1B, 0x1E, 0xC3, 0xE7, 0x9E, 0xB8, 0x64, 0x33, 0x7F, 0x63, 0x78, + 0x68, 0xB4, 0xCD, 0x2E, 0x71, 0x75, 0xD7, 0x9B, 0x20, 0xC6, 0x4D, 0x29, + 0xBC, 0xB6, 0x68, 0x60, 0x8A, 0xF7, 0x21, 0x9A, 0x56, 0x35, 0x5A, 0xF3, + 0x76, 0xBD, 0xD8, 0xCD, 0x9A, 0xFF, 0x93, 0x56, 0x4B, 0xA5, 0x59, 0x06, + 0xA1, 0x93, 0x34, 0x29, 0xDD, 0x16, 0x34, 0x75, 0x4E, 0xF2, 0x81, 0xB4, + 0xC7, 0x96, 0x4E, 0xAD, 0x19, 0x15, 0x52, 0x4A, 0xFE, 0x3C, 0x70, 0x75, + 0x70, 0xCD, 0xAF, 0x2B, 0xAB, 0x15, 0x9A, 0x33, 0x3C, 0xAA, 0xB3, 0x8B, + 0xAA, 0xCD, 0x43, 0xFD, 0xF5, 0xEA, 0x70, 0xFF, 0xED, 0xCF, 0x11, 0x3B, + 0x94, 0xCE, 0x4E, 0x32, 0x16, 0xD3, 0x23, 0x40, 0x2A, 0x77, 0xB3, 0xAF, + 0x3C, 0x01, 0x2C, 0x6C, 0xED, 0x99, 0x2C, 0x8B, 0xD9, 0x4E, 0x69, 0x98, + 0xB2, 0xF7, 0x8F, 0x41, 0xB0, 0x32, 0x78, 0x61, 0xD6, 0x0D, 0x5F, 0xC3, + 0xFA, 0xA2, 0x40, 0x92, 0x1D, 0x5C, 0x17, 0xE6, 0x70, 0x3E, 0x35, 0xE7, + 0xA2, 0xB7, 0xC2, 0x62, 0xE2, 0xAB, 0xA4, 0x38, 0x4C, 0xB5, 0x39, 0x35, + 0x6F, 0xEA, 0x03, 0x69, 0xFA, 0x3A, 0x54, 0x68, 0x85, 0x6D, 0xD6, 0xF2, + 0x2F, 0x43, 0x55, 0x1E, 0x91, 0x0D, 0x0E, 0xD8, 0xD5, 0x6A, 0xA4, 0x96, + 0xD1, 0x13, 0x3C, 0x2C, 0x78, 0x50, 0xE8, 0x3A, 0x92, 0xD2, 0x17, 0x56, + 0xE5, 0x35, 0x1A, 0x40, 0x1C, 0x3E, 0x8D, 0x2C, 0xED, 0x39, 0xDF, 0x42, + 0xE0, 0x83, 0x41, 0x74, 0xDF, 0xA3, 0xCD, 0xC2, 0x86, 0x60, 0x48, 0x68, + 0xE3, 0x69, 0x0B, 0x54, 0x00, 0x8B, 0xE4, 0x76, 0x69, 0x21, 0x0D, 0x79, + 0x4E, 0x34, 0x08, 0x5E, 0x14, 0xC2, 0xCC, 0xB1, 0xB7, 0xAD, 0xD7, 0x7C, + 0x70, 0x8A, 0xC7, 0x85 +}; + +static const unsigned char TA540_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA541_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1A, 0x30, + 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA541_EC_Q[] = { + 0x04, 0x65, 0x50, 0x4A, 0xAE, 0x8C, 0x79, 0x96, 0x4A, 0xAA, 0x1C, 0x08, + 0xC3, 0xA3, 0xA2, 0xCD, 0xFE, 0x59, 0x56, 0x41, 0x77, 0xFD, 0x26, 0x94, + 0x42, 0xBB, 0x1D, 0xCD, 0x08, 0xDB, 0x73, 0xB2, 0x5B, 0x75, 0xF3, 0xCF, + 0x9C, 0x4E, 0x82, 0xF4, 0xBF, 0xF8, 0x61, 0x26, 0x85, 0x6C, 0xD6, 0x85, + 0x5B, 0x72, 0x70, 0xD2, 0xFD, 0xDB, 0x62, 0xB4, 0xDF, 0x53, 0x8B, 0xBD, + 0xB1, 0x44, 0x58, 0x62, 0x42, 0x09, 0xC7, 0xFA, 0x7F, 0x5B, 0x10, 0xE7, + 0xFE, 0x40, 0xFD, 0xC0, 0xD8, 0xC3, 0x2B, 0x32, 0xE7, 0x70, 0xA6, 0xB7, + 0xA6, 0x20, 0x55, 0x1D, 0x7B, 0x80, 0x5D, 0x4B, 0x8F, 0x67, 0x4C, 0xF1, + 0x10 +}; + +static const unsigned char TA542_DN[] = { + 0x30, 0x43, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, + 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0D, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA542_RSA_N[] = { + 0xBD, 0x55, 0x7C, 0x61, 0xD3, 0xB8, 0x1D, 0x04, 0x62, 0x05, 0xA0, 0xAE, + 0x6C, 0xB7, 0x70, 0xB4, 0x41, 0xEA, 0x4B, 0x03, 0x5E, 0x10, 0x3F, 0x90, + 0x5A, 0x1C, 0x8B, 0x3B, 0xB0, 0x66, 0x8B, 0x6C, 0x48, 0xA6, 0x1C, 0x22, + 0xBA, 0xD5, 0x40, 0x92, 0xEE, 0x33, 0xB2, 0x23, 0x59, 0xC9, 0x8E, 0xBC, + 0x58, 0xDA, 0x8B, 0x9E, 0xD0, 0x19, 0xF2, 0x2F, 0x59, 0xC6, 0x8C, 0x63, + 0x5A, 0xBA, 0x9F, 0xA3, 0x0B, 0xB0, 0xB3, 0x9A, 0x5C, 0xBA, 0x11, 0xB8, + 0x12, 0xE9, 0x0C, 0xBB, 0xCF, 0x6E, 0x6C, 0x80, 0x87, 0x29, 0x14, 0x03, + 0x2C, 0x8D, 0x24, 0x9A, 0xC8, 0x64, 0x83, 0xB5, 0x6A, 0xAC, 0x13, 0x2C, + 0x33, 0xF1, 0x9F, 0xDC, 0x2C, 0x61, 0x3C, 0x1A, 0x3F, 0x70, 0x55, 0x9B, + 0xAD, 0x00, 0x52, 0x7F, 0xCF, 0x04, 0xB9, 0xFE, 0x36, 0xFA, 0x9C, 0xC0, + 0x16, 0xAE, 0x62, 0xFE, 0x96, 0x4C, 0x43, 0x7E, 0x55, 0x14, 0xBE, 0x1A, + 0xB3, 0xD2, 0x6D, 0xC2, 0xAF, 0x76, 0x66, 0x95, 0x6B, 0x2A, 0xB0, 0x94, + 0x77, 0x85, 0x5E, 0x04, 0x0F, 0x62, 0x1D, 0x63, 0x75, 0xF7, 0x6B, 0xE7, + 0xCB, 0x5B, 0x9A, 0x70, 0xEC, 0x3E, 0x67, 0x05, 0xF0, 0xFE, 0x07, 0x08, + 0x80, 0xCF, 0x28, 0xDB, 0x05, 0xC6, 0x14, 0x27, 0x2F, 0x86, 0x7D, 0xF0, + 0x27, 0xDE, 0xFF, 0xE6, 0x7E, 0x33, 0x48, 0xE7, 0x0B, 0x1E, 0x58, 0xD1, + 0x27, 0x2B, 0x53, 0x0E, 0x57, 0x4A, 0x65, 0xD7, 0xFB, 0xA2, 0x80, 0x60, + 0xFC, 0x4C, 0xBC, 0x35, 0x53, 0x01, 0x6A, 0x97, 0x72, 0x82, 0xAF, 0xF1, + 0x1D, 0x70, 0xE8, 0x9C, 0xF5, 0xEF, 0x5E, 0xC2, 0x6C, 0xC7, 0x47, 0x7E, + 0x5A, 0x94, 0x85, 0x26, 0x4D, 0x3B, 0xBA, 0xEB, 0x4C, 0xE8, 0xB0, 0x09, + 0xC2, 0x65, 0xC2, 0x9D, 0x9D, 0x09, 0x9B, 0x4E, 0xB5, 0x97, 0x05, 0xAC, + 0xF5, 0x06, 0xA0, 0xF7, 0x36, 0x05, 0x7E, 0xF4, 0x90, 0xB2, 0x6B, 0xC4, + 0xB4, 0xF9, 0x64, 0xEA, 0xE9, 0x1A, 0x0A, 0xC8, 0x0D, 0xA8, 0xED, 0x27, + 0xC9, 0xD4, 0xE7, 0xB3, 0xB9, 0xAB, 0x82, 0x22, 0x90, 0x27, 0x3D, 0x2A, + 0xE8, 0x7C, 0x90, 0xEF, 0xBC, 0x4F, 0xFD, 0xE2, 0x0A, 0x24, 0xA7, 0xDE, + 0x65, 0x24, 0xA4, 0x5D, 0xEA, 0xC0, 0x76, 0x30, 0xD3, 0x77, 0x50, 0xF8, + 0x0D, 0x04, 0x9B, 0x94, 0x36, 0x01, 0x73, 0xCA, 0x06, 0x58, 0xA6, 0xD3, + 0x3B, 0xDC, 0xFA, 0x04, 0x46, 0x13, 0x55, 0x8A, 0xC9, 0x44, 0x47, 0xB8, + 0x51, 0x39, 0x1A, 0x2E, 0xE8, 0x34, 0xE2, 0x79, 0xCB, 0x59, 0x4A, 0x0A, + 0x7F, 0xBC, 0xA6, 0xEF, 0x1F, 0x03, 0x67, 0x6A, 0x59, 0x2B, 0x25, 0x62, + 0x93, 0xD9, 0x53, 0x19, 0x66, 0x3C, 0x27, 0x62, 0x29, 0x86, 0x4D, 0xA4, + 0x6B, 0xEE, 0xFF, 0xD4, 0x4E, 0xBA, 0xD5, 0xB4, 0xE2, 0x8E, 0x48, 0x5A, + 0x00, 0x19, 0x09, 0xF1, 0x05, 0xD9, 0xCE, 0x91, 0xB1, 0xF7, 0xEB, 0xE9, + 0x39, 0x4F, 0xF6, 0x6F, 0x04, 0x43, 0x9A, 0x55, 0xF5, 0x3E, 0x05, 0x14, + 0xBD, 0xBF, 0xB3, 0x59, 0xB4, 0xD8, 0x8E, 0x33, 0x84, 0xA3, 0x90, 0x52, + 0xAA, 0xB3, 0x02, 0x95, 0x60, 0xF9, 0x0C, 0x4C, 0x68, 0xF9, 0xEE, 0xD5, + 0x17, 0x0D, 0xF8, 0x71, 0x57, 0xB5, 0x25, 0xE4, 0x29, 0xEE, 0x65, 0x5D, + 0xAF, 0xD1, 0xEE, 0x3C, 0x17, 0x0B, 0x5A, 0x43, 0xC5, 0xA5, 0x86, 0xEA, + 0x24, 0x9E, 0xE2, 0x05, 0x07, 0xDC, 0x34, 0x42, 0x12, 0x91, 0xD6, 0x39, + 0x74, 0xAE, 0x4C, 0x41, 0x82, 0xDB, 0xF2, 0xA6, 0x48, 0xD1, 0xB3, 0x9B, + 0xF3, 0x33, 0xAA, 0xF3, 0xA6, 0xC0, 0xC5, 0x4E, 0xF5, 0xF4, 0x9D, 0x76, + 0x63, 0xE6, 0x02, 0xC6, 0x22, 0x4B, 0xC1, 0x95, 0x3F, 0x50, 0x64, 0x2C, + 0x54, 0xE5, 0xB6, 0xF0, 0x3C, 0x29, 0xCF, 0x57 +}; + +static const unsigned char TA542_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA543_DN[] = { + 0x30, 0x52, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x53, 0x4B, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x0A, 0x42, 0x72, 0x61, 0x74, 0x69, 0x73, 0x6C, 0x61, 0x76, 0x61, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x61, 0x2E, 0x73, 0x2E, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x41, 0x20, 0x44, + 0x69, 0x73, 0x69, 0x67, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x32 +}; + +static const unsigned char TA543_RSA_N[] = { + 0xA2, 0xA3, 0xC4, 0x00, 0x09, 0xD6, 0x85, 0x5D, 0x2D, 0x6D, 0x14, 0xF6, + 0xC2, 0xC3, 0x73, 0x9E, 0x35, 0xC2, 0x71, 0x55, 0x7E, 0x81, 0xFB, 0xAB, + 0x46, 0x50, 0xE0, 0xC1, 0x7C, 0x49, 0x78, 0xE6, 0xAB, 0x79, 0x58, 0x3C, + 0xDA, 0xFF, 0x7C, 0x1C, 0x9F, 0xD8, 0x97, 0x02, 0x78, 0x3E, 0x6B, 0x41, + 0x04, 0xE9, 0x41, 0xBD, 0xBE, 0x03, 0x2C, 0x45, 0xF6, 0x2F, 0x64, 0xD4, + 0xAB, 0x5D, 0xA3, 0x47, 0x3D, 0x64, 0x9B, 0xE9, 0x68, 0x9A, 0xC6, 0xCC, + 0x1B, 0x3F, 0xBA, 0xBE, 0xB2, 0x8B, 0x34, 0x02, 0x2E, 0x98, 0x55, 0x19, + 0xFC, 0x8C, 0x6F, 0xAA, 0x5F, 0xDA, 0x4C, 0xCE, 0x4D, 0x03, 0x21, 0xA3, + 0xD8, 0xD2, 0x34, 0x93, 0x56, 0x96, 0xCB, 0x4C, 0x0C, 0x00, 0x16, 0x3C, + 0x5F, 0x1A, 0xCD, 0xC8, 0xC7, 0x6C, 0xA6, 0xAD, 0xD3, 0x31, 0xA7, 0xBC, + 0xE8, 0xE5, 0xE1, 0x66, 0xD6, 0xD2, 0xFB, 0x03, 0xB4, 0x41, 0x65, 0xC9, + 0x10, 0xAE, 0x0E, 0x05, 0x63, 0xC6, 0x80, 0x6A, 0x69, 0x30, 0xFD, 0xD2, + 0xEE, 0x90, 0xEF, 0x0D, 0x27, 0xDF, 0x9F, 0x95, 0x73, 0xF4, 0xE1, 0x25, + 0xDA, 0x6C, 0x16, 0xDE, 0x41, 0x38, 0x34, 0xEA, 0x8B, 0xFC, 0xD1, 0xE8, + 0x04, 0x14, 0x61, 0x2D, 0x41, 0x7E, 0xAC, 0xC7, 0x77, 0x4E, 0xCB, 0x51, + 0x54, 0xFB, 0x5E, 0x92, 0x18, 0x1B, 0x04, 0x5A, 0x68, 0xC6, 0xC9, 0xC4, + 0xFA, 0xB7, 0x13, 0xA0, 0x98, 0xB7, 0x11, 0x2B, 0xB7, 0xD6, 0x57, 0xCC, + 0x7C, 0x9E, 0x17, 0xD1, 0xCB, 0x25, 0xFE, 0x86, 0x4E, 0x24, 0x2E, 0x56, + 0x0C, 0x78, 0x4D, 0x9E, 0x01, 0x12, 0xA6, 0x2B, 0xA7, 0x01, 0x65, 0x6E, + 0x7C, 0x62, 0x1D, 0x84, 0x84, 0xDF, 0xEA, 0xC0, 0x6B, 0xB5, 0xA5, 0x2A, + 0x95, 0x83, 0xC3, 0x53, 0x11, 0x0C, 0x73, 0x1D, 0x0B, 0xB2, 0x46, 0x90, + 0xD1, 0x42, 0x3A, 0xCE, 0x40, 0x6E, 0x95, 0xAD, 0xFF, 0xC6, 0x94, 0xAD, + 0x6E, 0x97, 0x84, 0x8E, 0x7D, 0x6F, 0x9E, 0x8A, 0x80, 0x0D, 0x49, 0x6D, + 0x73, 0xE2, 0x7B, 0x92, 0x1E, 0xC3, 0xF3, 0xC1, 0xF3, 0xEB, 0x2E, 0x05, + 0x6F, 0xD9, 0x1B, 0xCF, 0x37, 0x76, 0x04, 0xC8, 0xB4, 0x5A, 0xE4, 0x17, + 0xA7, 0xCB, 0xDD, 0x76, 0x1F, 0xD0, 0x19, 0x76, 0xE8, 0x2C, 0x05, 0xB3, + 0xD6, 0x9C, 0x34, 0xD8, 0x96, 0xDC, 0x61, 0x87, 0x91, 0x05, 0xE4, 0x44, + 0x08, 0x33, 0xC1, 0xDA, 0xB9, 0x08, 0x65, 0xD4, 0xAE, 0xB2, 0x36, 0x0D, + 0xEB, 0xBA, 0x38, 0xBA, 0x0C, 0xE5, 0x9B, 0x9E, 0xEB, 0x8D, 0x66, 0xDD, + 0x99, 0xCF, 0xD6, 0x89, 0x41, 0xF6, 0x04, 0x92, 0x8A, 0x29, 0x29, 0x6D, + 0x6B, 0x3A, 0x1C, 0xE7, 0x75, 0x7D, 0x02, 0x71, 0x0E, 0xF3, 0xC0, 0xE7, + 0xBD, 0xCB, 0x19, 0xDD, 0x9D, 0x60, 0xB2, 0xC2, 0x66, 0x60, 0xB6, 0xB1, + 0x04, 0xEE, 0xC9, 0xE6, 0x86, 0xB9, 0x9A, 0x66, 0x40, 0xA8, 0xE7, 0x11, + 0xED, 0x81, 0x45, 0x03, 0x8B, 0xF6, 0x67, 0x59, 0xE8, 0xC1, 0x06, 0x11, + 0xBD, 0xDD, 0xCF, 0x80, 0x02, 0x4F, 0x65, 0x40, 0x78, 0x5C, 0x47, 0x50, + 0xC8, 0x9B, 0xE6, 0x1F, 0x81, 0x7B, 0xE4, 0x44, 0xA8, 0x5B, 0x85, 0x9A, + 0xE2, 0xDE, 0x5A, 0xD5, 0xC7, 0xF9, 0x3A, 0x44, 0x66, 0x4B, 0xE4, 0x32, + 0x54, 0x7C, 0xE4, 0x6C, 0x9C, 0xB3, 0x0E, 0x3D, 0x17, 0xA2, 0xB2, 0x34, + 0x12, 0xD6, 0x7E, 0xB2, 0xA8, 0x49, 0xBB, 0xD1, 0x7A, 0x28, 0x40, 0xBE, + 0xA2, 0x16, 0x1F, 0xDF, 0xE4, 0x37, 0x1F, 0x11, 0x73, 0xFB, 0x90, 0x0A, + 0x65, 0x43, 0xA2, 0x0D, 0x7C, 0xF8, 0x06, 0x01, 0x55, 0x33, 0x7D, 0xB0, + 0x0D, 0xB8, 0xF4, 0xF5, 0xAE, 0xA5, 0x42, 0x57, 0x7C, 0x36, 0x11, 0x8C, + 0x7B, 0x5E, 0xC4, 0x03, 0x9D, 0x8C, 0x79, 0x9D +}; + +static const unsigned char TA543_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA544_DN[] = { + 0x30, 0x81, 0x80, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, + 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x24, 0x30, + 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x43, 0x65, 0x72, 0x74, + 0x75, 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, + 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA544_RSA_N[] = { + 0xBD, 0xF9, 0x78, 0xF8, 0xE6, 0xD5, 0x80, 0x0C, 0x64, 0x9D, 0x86, 0x1B, + 0x96, 0x64, 0x67, 0x3F, 0x22, 0x3A, 0x1E, 0x75, 0x01, 0x7D, 0xEF, 0xFB, + 0x5C, 0x67, 0x8C, 0xC9, 0xCC, 0x5C, 0x6B, 0xA9, 0x91, 0xE6, 0xB9, 0x42, + 0xE5, 0x20, 0x4B, 0x9B, 0xDA, 0x9B, 0x7B, 0xB9, 0x99, 0x5D, 0xD9, 0x9B, + 0x80, 0x4B, 0xD7, 0x84, 0x40, 0x2B, 0x27, 0xD3, 0xE8, 0xBA, 0x30, 0xBB, + 0x3E, 0x09, 0x1A, 0xA7, 0x49, 0x95, 0xEF, 0x2B, 0x40, 0x24, 0xC2, 0x97, + 0xC7, 0xA7, 0xEE, 0x9B, 0x25, 0xEF, 0xA8, 0x0A, 0x00, 0x97, 0x85, 0x5A, + 0xAA, 0x9D, 0xDC, 0x29, 0xC9, 0xE2, 0x35, 0x07, 0xEB, 0x70, 0x4D, 0x4A, + 0xD6, 0xC1, 0xB3, 0x56, 0xB8, 0xA1, 0x41, 0x38, 0x9B, 0xD1, 0xFB, 0x31, + 0x7F, 0x8F, 0xE0, 0x5F, 0xE1, 0xB1, 0x3F, 0x0F, 0x8E, 0x16, 0x49, 0x60, + 0xD7, 0x06, 0x8D, 0x18, 0xF9, 0xAA, 0x26, 0x10, 0xAB, 0x2A, 0xD3, 0xD0, + 0xD1, 0x67, 0x8D, 0x1B, 0x46, 0xBE, 0x47, 0x30, 0xD5, 0x2E, 0x72, 0xD1, + 0xC5, 0x63, 0xDA, 0xE7, 0x63, 0x79, 0x44, 0x7E, 0x4B, 0x63, 0x24, 0x89, + 0x86, 0x2E, 0x34, 0x3F, 0x29, 0x4C, 0x52, 0x8B, 0x2A, 0xA7, 0xC0, 0xE2, + 0x91, 0x28, 0x89, 0xB9, 0xC0, 0x5B, 0xF9, 0x1D, 0xD9, 0xE7, 0x27, 0xAD, + 0xFF, 0x9A, 0x02, 0x97, 0xC1, 0xC6, 0x50, 0x92, 0x9B, 0x02, 0x2C, 0xBD, + 0xA9, 0xB9, 0x34, 0x59, 0x0A, 0xBF, 0x84, 0x4A, 0xFF, 0xDF, 0xFE, 0xB3, + 0x9F, 0xEB, 0xD9, 0x9E, 0xE0, 0x98, 0x23, 0xEC, 0xA6, 0x6B, 0x77, 0x16, + 0x2A, 0xDB, 0xCC, 0xAD, 0x3B, 0x1C, 0xA4, 0x87, 0xDC, 0x46, 0x73, 0x5E, + 0x19, 0x62, 0x68, 0x45, 0x57, 0xE4, 0x90, 0x82, 0x42, 0xBB, 0x42, 0xD6, + 0xF0, 0x61, 0xE0, 0xC1, 0xA3, 0x3D, 0x66, 0xA3, 0x5D, 0xF4, 0x18, 0xEE, + 0x88, 0xC9, 0x8D, 0x17, 0x45, 0x29, 0x99, 0x32, 0x75, 0x02, 0x31, 0xEE, + 0x29, 0x26, 0xC8, 0x6B, 0x02, 0xE6, 0xB5, 0x62, 0x45, 0x7F, 0x37, 0x15, + 0x5A, 0x23, 0x68, 0x89, 0xD4, 0x3E, 0xDE, 0x4E, 0x27, 0xB0, 0xF0, 0x40, + 0x0C, 0xBC, 0x4D, 0x17, 0xCB, 0x4D, 0xA2, 0xB3, 0x1E, 0xD0, 0x06, 0x5A, + 0xDD, 0xF6, 0x93, 0xCF, 0x57, 0x75, 0x99, 0xF5, 0xFA, 0x86, 0x1A, 0x67, + 0x78, 0xB3, 0xBF, 0x96, 0xFE, 0x34, 0xDC, 0xBD, 0xE7, 0x52, 0x56, 0xE5, + 0xB3, 0xE5, 0x75, 0x7B, 0xD7, 0x41, 0x91, 0x05, 0xDC, 0x5D, 0x69, 0xE3, + 0x95, 0x0D, 0x43, 0xB9, 0xFC, 0x83, 0x96, 0x39, 0x95, 0x7B, 0x6C, 0x80, + 0x5A, 0x4F, 0x13, 0x72, 0xC6, 0xD7, 0x7D, 0x29, 0x7A, 0x44, 0xBA, 0x52, + 0xA4, 0x2A, 0xD5, 0x41, 0x46, 0x09, 0x20, 0xFE, 0x22, 0xA0, 0xB6, 0x5B, + 0x30, 0x8D, 0xBC, 0x89, 0x0C, 0xD5, 0xD7, 0x70, 0xF8, 0x87, 0x52, 0xFD, + 0xDA, 0xEF, 0xAC, 0x51, 0x2E, 0x07, 0xB3, 0x4E, 0xFE, 0xD0, 0x09, 0xDA, + 0x70, 0xEF, 0x98, 0xFA, 0x56, 0xE6, 0x6D, 0xDB, 0xB5, 0x57, 0x4B, 0xDC, + 0xE5, 0x2C, 0x25, 0x15, 0xC8, 0x9E, 0x2E, 0x78, 0x4E, 0xF8, 0xDA, 0x9C, + 0x9E, 0x86, 0x2C, 0xCA, 0x57, 0xF3, 0x1A, 0xE5, 0xC8, 0x92, 0x8B, 0x1A, + 0x82, 0x96, 0x7A, 0xC3, 0xBC, 0x50, 0x12, 0x69, 0xD8, 0x0E, 0x5A, 0x46, + 0x8B, 0x3A, 0xEB, 0x26, 0xFA, 0x23, 0xC9, 0xB6, 0xB0, 0x81, 0xBE, 0x42, + 0x00, 0xA4, 0xF8, 0xD6, 0xFE, 0x30, 0x2E, 0xC7, 0xD2, 0x46, 0xF6, 0xE5, + 0x8E, 0x75, 0xFD, 0xF2, 0xCC, 0xB9, 0xD0, 0x87, 0x5B, 0xCC, 0x06, 0x10, + 0x60, 0xBB, 0x83, 0x35, 0xB7, 0x5E, 0x67, 0xDE, 0x47, 0xEC, 0x99, 0x48, + 0xF1, 0xA4, 0xA1, 0x15, 0xFE, 0xAD, 0x8C, 0x62, 0x8E, 0x39, 0x55, 0x4F, + 0x39, 0x16, 0xB9, 0xB1, 0x63, 0x9D, 0xFF, 0xB7 +}; + +static const unsigned char TA544_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA545_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA545_EC_Q[] = { + 0x04, 0x45, 0x29, 0x35, 0x73, 0xFA, 0xC2, 0xB8, 0x23, 0xCE, 0x14, 0x7D, + 0xA8, 0xB1, 0x4D, 0xA0, 0x5B, 0x36, 0xEE, 0x2A, 0x2C, 0x53, 0xC3, 0x60, + 0x09, 0x35, 0xB2, 0x24, 0x66, 0x26, 0x69, 0xC0, 0xB3, 0x95, 0xD6, 0x5D, + 0x92, 0x40, 0x19, 0x0E, 0xC6, 0xA5, 0x13, 0x70, 0xF4, 0xEF, 0x12, 0x51, + 0x28, 0x5D, 0xE7, 0xCC, 0xBD, 0xF9, 0x3C, 0x85, 0xC1, 0xCF, 0x94, 0x90, + 0xC9, 0x2B, 0xCE, 0x92, 0x42, 0x58, 0x59, 0x67, 0xFD, 0x94, 0x27, 0x10, + 0x64, 0x8C, 0x4F, 0x04, 0xB1, 0x4D, 0x49, 0xE4, 0x7B, 0x4F, 0x9B, 0xF5, + 0xE7, 0x08, 0xF8, 0x03, 0x88, 0xF7, 0xA7, 0xC3, 0x92, 0x4B, 0x19, 0x54, + 0x81 +}; + +static const unsigned char TA546_DN[] = { + 0x30, 0x81, 0x83, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x1A, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, 0x47, 0x6F, 0x44, 0x61, 0x64, 0x64, + 0x79, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, + 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6F, + 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA546_RSA_N[] = { + 0xBF, 0x71, 0x62, 0x08, 0xF1, 0xFA, 0x59, 0x34, 0xF7, 0x1B, 0xC9, 0x18, + 0xA3, 0xF7, 0x80, 0x49, 0x58, 0xE9, 0x22, 0x83, 0x13, 0xA6, 0xC5, 0x20, + 0x43, 0x01, 0x3B, 0x84, 0xF1, 0xE6, 0x85, 0x49, 0x9F, 0x27, 0xEA, 0xF6, + 0x84, 0x1B, 0x4E, 0xA0, 0xB4, 0xDB, 0x70, 0x98, 0xC7, 0x32, 0x01, 0xB1, + 0x05, 0x3E, 0x07, 0x4E, 0xEE, 0xF4, 0xFA, 0x4F, 0x2F, 0x59, 0x30, 0x22, + 0xE7, 0xAB, 0x19, 0x56, 0x6B, 0xE2, 0x80, 0x07, 0xFC, 0xF3, 0x16, 0x75, + 0x80, 0x39, 0x51, 0x7B, 0xE5, 0xF9, 0x35, 0xB6, 0x74, 0x4E, 0xA9, 0x8D, + 0x82, 0x13, 0xE4, 0xB6, 0x3F, 0xA9, 0x03, 0x83, 0xFA, 0xA2, 0xBE, 0x8A, + 0x15, 0x6A, 0x7F, 0xDE, 0x0B, 0xC3, 0xB6, 0x19, 0x14, 0x05, 0xCA, 0xEA, + 0xC3, 0xA8, 0x04, 0x94, 0x3B, 0x46, 0x7C, 0x32, 0x0D, 0xF3, 0x00, 0x66, + 0x22, 0xC8, 0x8D, 0x69, 0x6D, 0x36, 0x8C, 0x11, 0x18, 0xB7, 0xD3, 0xB2, + 0x1C, 0x60, 0xB4, 0x38, 0xFA, 0x02, 0x8C, 0xCE, 0xD3, 0xDD, 0x46, 0x07, + 0xDE, 0x0A, 0x3E, 0xEB, 0x5D, 0x7C, 0xC8, 0x7C, 0xFB, 0xB0, 0x2B, 0x53, + 0xA4, 0x92, 0x62, 0x69, 0x51, 0x25, 0x05, 0x61, 0x1A, 0x44, 0x81, 0x8C, + 0x2C, 0xA9, 0x43, 0x96, 0x23, 0xDF, 0xAC, 0x3A, 0x81, 0x9A, 0x0E, 0x29, + 0xC5, 0x1C, 0xA9, 0xE9, 0x5D, 0x1E, 0xB6, 0x9E, 0x9E, 0x30, 0x0A, 0x39, + 0xCE, 0xF1, 0x88, 0x80, 0xFB, 0x4B, 0x5D, 0xCC, 0x32, 0xEC, 0x85, 0x62, + 0x43, 0x25, 0x34, 0x02, 0x56, 0x27, 0x01, 0x91, 0xB4, 0x3B, 0x70, 0x2A, + 0x3F, 0x6E, 0xB1, 0xE8, 0x9C, 0x88, 0x01, 0x7D, 0x9F, 0xD4, 0xF9, 0xDB, + 0x53, 0x6D, 0x60, 0x9D, 0xBF, 0x2C, 0xE7, 0x58, 0xAB, 0xB8, 0x5F, 0x46, + 0xFC, 0xCE, 0xC4, 0x1B, 0x03, 0x3C, 0x09, 0xEB, 0x49, 0x31, 0x5C, 0x69, + 0x46, 0xB3, 0xE0, 0x47 +}; + +static const unsigned char TA546_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA547_DN[] = { + 0x30, 0x38, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x49, 0x5A, 0x45, 0x4E, 0x50, 0x45, 0x20, 0x53, 0x2E, 0x41, + 0x2E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0A, + 0x49, 0x7A, 0x65, 0x6E, 0x70, 0x65, 0x2E, 0x63, 0x6F, 0x6D +}; + +static const unsigned char TA547_RSA_N[] = { + 0xC9, 0xD3, 0x7A, 0xCA, 0x0F, 0x1E, 0xAC, 0xA7, 0x86, 0xE8, 0x16, 0x65, + 0x6A, 0xB1, 0xC2, 0x1B, 0x45, 0x32, 0x71, 0x95, 0xD9, 0xFE, 0x10, 0x5B, + 0xCC, 0xAF, 0xE7, 0xA5, 0x79, 0x01, 0x8F, 0x89, 0xC3, 0xCA, 0xF2, 0x55, + 0x71, 0xF7, 0x77, 0xBE, 0x77, 0x94, 0xF3, 0x72, 0xA4, 0x2C, 0x44, 0xD8, + 0x9E, 0x92, 0x9B, 0x14, 0x3A, 0xA1, 0xE7, 0x24, 0x90, 0x0A, 0x0A, 0x56, + 0x8E, 0xC5, 0xD8, 0x26, 0x94, 0xE1, 0xD9, 0x48, 0xE1, 0x2D, 0x3E, 0xDA, + 0x0A, 0x72, 0xDD, 0xA3, 0x99, 0x15, 0xDA, 0x81, 0xA2, 0x87, 0xF4, 0x7B, + 0x6E, 0x26, 0x77, 0x89, 0x58, 0xAD, 0xD6, 0xEB, 0x0C, 0xB2, 0x41, 0x7A, + 0x73, 0x6E, 0x6D, 0xDB, 0x7A, 0x78, 0x41, 0xE9, 0x08, 0x88, 0x12, 0x7E, + 0x87, 0x2E, 0x66, 0x11, 0x63, 0x6C, 0x54, 0xFB, 0x3C, 0x9D, 0x72, 0xC0, + 0xBC, 0x2E, 0xFF, 0xC2, 0xB7, 0xDD, 0x0D, 0x76, 0xE3, 0x3A, 0xD7, 0xF7, + 0xB4, 0x68, 0xBE, 0xA2, 0xF5, 0xE3, 0x81, 0x6E, 0xC1, 0x46, 0x6F, 0x5D, + 0x8D, 0xE0, 0x4D, 0xC6, 0x54, 0x55, 0x89, 0x1A, 0x33, 0x31, 0x0A, 0xB1, + 0x57, 0xB9, 0xA3, 0x8A, 0x98, 0xC3, 0xEC, 0x3B, 0x34, 0xC5, 0x95, 0x41, + 0x69, 0x7E, 0x75, 0xC2, 0x3C, 0x20, 0xC5, 0x61, 0xBA, 0x51, 0x47, 0xA0, + 0x20, 0x90, 0x93, 0xA1, 0x90, 0x4B, 0xF3, 0x4E, 0x7C, 0x85, 0x45, 0x54, + 0x9A, 0xD1, 0x05, 0x26, 0x41, 0xB0, 0xB5, 0x4D, 0x1D, 0x33, 0xBE, 0xC4, + 0x03, 0xC8, 0x25, 0x7C, 0xC1, 0x70, 0xDB, 0x3B, 0xF4, 0x09, 0x2D, 0x54, + 0x27, 0x48, 0xAC, 0x2F, 0xE1, 0xC4, 0xAC, 0x3E, 0xC8, 0xCB, 0x92, 0x4C, + 0x53, 0x39, 0x37, 0x23, 0xEC, 0xD3, 0x01, 0xF9, 0xE0, 0x09, 0x44, 0x4D, + 0x4D, 0x64, 0xC0, 0xE1, 0x0D, 0x5A, 0x87, 0x22, 0xBC, 0xAD, 0x1B, 0xA3, + 0xFE, 0x26, 0xB5, 0x15, 0xF3, 0xA7, 0xFC, 0x84, 0x19, 0xE9, 0xEC, 0xA1, + 0x88, 0xB4, 0x44, 0x69, 0x84, 0x83, 0xF3, 0x89, 0xD1, 0x74, 0x06, 0xA9, + 0xCC, 0x0B, 0xD6, 0xC2, 0xDE, 0x27, 0x85, 0x50, 0x26, 0xCA, 0x17, 0xB8, + 0xC9, 0x7A, 0x87, 0x56, 0x2C, 0x1A, 0x01, 0x1E, 0x6C, 0xBE, 0x13, 0xAD, + 0x10, 0xAC, 0xB5, 0x24, 0xF5, 0x38, 0x91, 0xA1, 0xD6, 0x4B, 0xDA, 0xF1, + 0xBB, 0xD2, 0xDE, 0x47, 0xB5, 0xF1, 0xBC, 0x81, 0xF6, 0x59, 0x6B, 0xCF, + 0x19, 0x53, 0xE9, 0x8D, 0x15, 0xCB, 0x4A, 0xCB, 0xA9, 0x6F, 0x44, 0xE5, + 0x1B, 0x41, 0xCF, 0xE1, 0x86, 0xA7, 0xCA, 0xD0, 0x6A, 0x9F, 0xBC, 0x4C, + 0x8D, 0x06, 0x33, 0x5A, 0xA2, 0x85, 0xE5, 0x90, 0x35, 0xA0, 0x62, 0x5C, + 0x16, 0x4E, 0xF0, 0xE3, 0xA2, 0xFA, 0x03, 0x1A, 0xB4, 0x2C, 0x71, 0xB3, + 0x58, 0x2C, 0xDE, 0x7B, 0x0B, 0xDB, 0x1A, 0x0F, 0xEB, 0xDE, 0x21, 0x1F, + 0x06, 0x77, 0x06, 0x03, 0xB0, 0xC9, 0xEF, 0x99, 0xFC, 0xC0, 0xB9, 0x4F, + 0x0B, 0x86, 0x28, 0xFE, 0xD2, 0xB9, 0xEA, 0xE3, 0xDA, 0xA5, 0xC3, 0x47, + 0x69, 0x12, 0xE0, 0xDB, 0xF0, 0xF6, 0x19, 0x8B, 0xED, 0x7B, 0x70, 0xD7, + 0x02, 0xD6, 0xED, 0x87, 0x18, 0x28, 0x2C, 0x04, 0x24, 0x4C, 0x77, 0xE4, + 0x48, 0x8A, 0x1A, 0xC6, 0x3B, 0x9A, 0xD4, 0x0F, 0xCA, 0xFA, 0x75, 0xD2, + 0x01, 0x40, 0x5A, 0x8D, 0x79, 0xBF, 0x8B, 0xCF, 0x4B, 0xCF, 0xAA, 0x16, + 0xC1, 0x95, 0xE4, 0xAD, 0x4C, 0x8A, 0x3E, 0x17, 0x91, 0xD4, 0xB1, 0x62, + 0xE5, 0x82, 0xE5, 0x80, 0x04, 0xA4, 0x03, 0x7E, 0x8D, 0xBF, 0xDA, 0x7F, + 0xA2, 0x0F, 0x97, 0x4F, 0x0C, 0xD3, 0x0D, 0xFB, 0xD7, 0xD1, 0xE5, 0x72, + 0x7E, 0x1C, 0xC8, 0x77, 0xFF, 0x5B, 0x9A, 0x0F, 0xB7, 0xAE, 0x05, 0x46, + 0xE5, 0xF1, 0xA8, 0x16, 0xEC, 0x47, 0xA4, 0x17 +}; + +static const unsigned char TA547_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA548_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA548_EC_Q[] = { + 0x04, 0x0D, 0x30, 0x5E, 0x1B, 0x15, 0x9D, 0x03, 0xD0, 0xA1, 0x79, 0x35, + 0xB7, 0x3A, 0x3C, 0x92, 0x7A, 0xCA, 0x15, 0x1C, 0xCD, 0x62, 0xF3, 0x9C, + 0x26, 0x5C, 0x07, 0x3D, 0xE5, 0x54, 0xFA, 0xA3, 0xD6, 0xCC, 0x12, 0xEA, + 0xF4, 0x14, 0x5F, 0xE8, 0x8E, 0x19, 0xAB, 0x2F, 0x2E, 0x48, 0xE6, 0xAC, + 0x18, 0x43, 0x78, 0xAC, 0xD0, 0x37, 0xC3, 0xBD, 0xB2, 0xCD, 0x2C, 0xE6, + 0x47, 0xE2, 0x1A, 0xE6, 0x63, 0xB8, 0x3D, 0x2E, 0x2F, 0x78, 0xC4, 0x4F, + 0xDB, 0xF4, 0x0F, 0xA4, 0x68, 0x4C, 0x55, 0x72, 0x6B, 0x95, 0x1D, 0x4E, + 0x18, 0x42, 0x95, 0x78, 0xCC, 0x37, 0x3C, 0x91, 0xE2, 0x9B, 0x65, 0x2B, + 0x29 +}; + +static const unsigned char TA549_DN[] = { + 0x30, 0x5D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x1E, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA549_RSA_N[] = { + 0xD0, 0x15, 0x39, 0x52, 0xB1, 0x52, 0xB3, 0xBA, 0xC5, 0x59, 0x82, 0xC4, + 0x5D, 0x52, 0xAE, 0x3A, 0x43, 0x65, 0x80, 0x4B, 0xC7, 0xF2, 0x96, 0xBC, + 0xDB, 0x36, 0x97, 0xD6, 0xA6, 0x64, 0x8C, 0xA8, 0x5E, 0xF0, 0xE3, 0x0A, + 0x1C, 0xF7, 0xDF, 0x97, 0x3D, 0x4B, 0xAE, 0xF6, 0x5D, 0xEC, 0x21, 0xB5, + 0x41, 0xAB, 0xCD, 0xB9, 0x7E, 0x76, 0x9F, 0xBE, 0xF9, 0x3E, 0x36, 0x34, + 0xA0, 0x3B, 0xC1, 0xF6, 0x31, 0x11, 0x45, 0x74, 0x93, 0x3D, 0x57, 0x80, + 0xC5, 0xF9, 0x89, 0x99, 0xCA, 0xE5, 0xAB, 0x6A, 0xD4, 0xB5, 0xDA, 0x41, + 0x90, 0x10, 0xC1, 0xD6, 0xD6, 0x42, 0x89, 0xC2, 0xBF, 0xF4, 0x38, 0x12, + 0x95, 0x4C, 0x54, 0x05, 0xF7, 0x36, 0xE4, 0x45, 0x83, 0x7B, 0x14, 0x65, + 0xD6, 0xDC, 0x0C, 0x4D, 0xD1, 0xDE, 0x7E, 0x0C, 0xAB, 0x3B, 0xC4, 0x15, + 0xBE, 0x3A, 0x56, 0xA6, 0x5A, 0x6F, 0x76, 0x69, 0x52, 0xA9, 0x7A, 0xB9, + 0xC8, 0xEB, 0x6A, 0x9A, 0x5D, 0x52, 0xD0, 0x2D, 0x0A, 0x6B, 0x35, 0x16, + 0x09, 0x10, 0x84, 0xD0, 0x6A, 0xCA, 0x3A, 0x06, 0x00, 0x37, 0x47, 0xE4, + 0x7E, 0x57, 0x4F, 0x3F, 0x8B, 0xEB, 0x67, 0xB8, 0x88, 0xAA, 0xC5, 0xBE, + 0x53, 0x55, 0xB2, 0x91, 0xC4, 0x7D, 0xB9, 0xB0, 0x85, 0x19, 0x06, 0x78, + 0x2E, 0xDB, 0x61, 0x1A, 0xFA, 0x85, 0xF5, 0x4A, 0x91, 0xA1, 0xE7, 0x16, + 0xD5, 0x8E, 0xA2, 0x39, 0xDF, 0x94, 0xB8, 0x70, 0x1F, 0x28, 0x3F, 0x8B, + 0xFC, 0x40, 0x5E, 0x63, 0x83, 0x3C, 0x83, 0x2A, 0x1A, 0x99, 0x6B, 0xCF, + 0xDE, 0x59, 0x6A, 0x3B, 0xFC, 0x6F, 0x16, 0xD7, 0x1F, 0xFD, 0x4A, 0x10, + 0xEB, 0x4E, 0x82, 0x16, 0x3A, 0xAC, 0x27, 0x0C, 0x53, 0xF1, 0xAD, 0xD5, + 0x24, 0xB0, 0x6B, 0x03, 0x50, 0xC1, 0x2D, 0x3C, 0x16, 0xDD, 0x44, 0x34, + 0x27, 0x1A, 0x75, 0xFB +}; + +static const unsigned char TA549_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA550_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, 0x4D, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x41, 0x43, 0x20, + 0x52, 0x41, 0x49, 0x5A, 0x20, 0x46, 0x4E, 0x4D, 0x54, 0x2D, 0x52, 0x43, + 0x4D +}; + +static const unsigned char TA550_RSA_N[] = { + 0xBA, 0x71, 0x80, 0x7A, 0x4C, 0x86, 0x6E, 0x7F, 0xC8, 0x13, 0x6D, 0xC0, + 0xC6, 0x7D, 0x1C, 0x00, 0x97, 0x8F, 0x2C, 0x0C, 0x23, 0xBB, 0x10, 0x9A, + 0x40, 0xA9, 0x1A, 0xB7, 0x87, 0x88, 0xF8, 0x9B, 0x56, 0x6A, 0xFB, 0xE6, + 0x7B, 0x8E, 0x8B, 0x92, 0x8E, 0xA7, 0x25, 0x5D, 0x59, 0x11, 0xDB, 0x36, + 0x2E, 0xB7, 0x51, 0x17, 0x1F, 0xA9, 0x08, 0x1F, 0x04, 0x17, 0x24, 0x58, + 0xAA, 0x37, 0x4A, 0x18, 0xDF, 0xE5, 0x39, 0xD4, 0x57, 0xFD, 0xD7, 0xC1, + 0x2C, 0x91, 0x01, 0x91, 0xE2, 0x22, 0xD4, 0x03, 0xC0, 0x58, 0xFC, 0x77, + 0x47, 0xEC, 0x8F, 0x3E, 0x74, 0x43, 0xBA, 0xAC, 0x34, 0x8D, 0x4D, 0x38, + 0x76, 0x67, 0x8E, 0xB0, 0xC8, 0x6F, 0x30, 0x33, 0x58, 0x71, 0x5C, 0xB4, + 0xF5, 0x6B, 0x6E, 0xD4, 0x01, 0x50, 0xB8, 0x13, 0x7E, 0x6C, 0x4A, 0xA3, + 0x49, 0xD1, 0x20, 0x19, 0xEE, 0xBC, 0xC0, 0x29, 0x18, 0x65, 0xA7, 0xDE, + 0xFE, 0xEF, 0xDD, 0x0A, 0x90, 0x21, 0xE7, 0x1A, 0x67, 0x92, 0x42, 0x10, + 0x98, 0x5F, 0x4F, 0x30, 0xBC, 0x3E, 0x1C, 0x45, 0xB4, 0x10, 0xD7, 0x68, + 0x40, 0x14, 0xC0, 0x40, 0xFA, 0xE7, 0x77, 0x17, 0x7A, 0xE6, 0x0B, 0x8F, + 0x65, 0x5B, 0x3C, 0xD9, 0x9A, 0x52, 0xDB, 0xB5, 0xBD, 0x9E, 0x46, 0xCF, + 0x3D, 0xEB, 0x91, 0x05, 0x02, 0xC0, 0x96, 0xB2, 0x76, 0x4C, 0x4D, 0x10, + 0x96, 0x3B, 0x92, 0xFA, 0x9C, 0x7F, 0x0F, 0x99, 0xDF, 0xBE, 0x23, 0x35, + 0x45, 0x1E, 0x02, 0x5C, 0xFE, 0xB5, 0xA8, 0x9B, 0x99, 0x25, 0xDA, 0x5E, + 0xF3, 0x22, 0xC3, 0x39, 0xF5, 0xE4, 0x2A, 0x2E, 0xD3, 0xC6, 0x1F, 0xC4, + 0x6C, 0xAA, 0xC5, 0x1C, 0x6A, 0x01, 0x05, 0x4A, 0x2F, 0xD2, 0xC5, 0xC1, + 0xA8, 0x34, 0x26, 0x5D, 0x66, 0xA5, 0xD2, 0x02, 0x21, 0xF9, 0x18, 0xB7, + 0x06, 0xF5, 0x4E, 0x99, 0x6F, 0xA8, 0xAB, 0x4C, 0x51, 0xE8, 0xCF, 0x50, + 0x18, 0xC5, 0x77, 0xC8, 0x39, 0x09, 0x2C, 0x49, 0x92, 0x32, 0x99, 0xA8, + 0xBB, 0x17, 0x17, 0x79, 0xB0, 0x5A, 0xC5, 0xE6, 0xA3, 0xC4, 0x59, 0x65, + 0x47, 0x35, 0x83, 0x5E, 0xA9, 0xE8, 0x35, 0x0B, 0x99, 0xBB, 0xE4, 0xCD, + 0x20, 0xC6, 0x9B, 0x4A, 0x06, 0x39, 0xB5, 0x68, 0xFC, 0x22, 0xBA, 0xEE, + 0x55, 0x8C, 0x2B, 0x4E, 0xEA, 0xF3, 0xB1, 0xE3, 0xFC, 0xB6, 0x99, 0x9A, + 0xD5, 0x42, 0xFA, 0x71, 0x4D, 0x08, 0xCF, 0x87, 0x1E, 0x6A, 0x71, 0x7D, + 0xF9, 0xD3, 0xB4, 0xE9, 0xA5, 0x71, 0x81, 0x7B, 0xC2, 0x4E, 0x47, 0x96, + 0xA5, 0xF6, 0x76, 0x85, 0xA3, 0x28, 0x8F, 0xE9, 0x80, 0x6E, 0x81, 0x53, + 0xA5, 0x6D, 0x5F, 0xB8, 0x48, 0xF9, 0xC2, 0xF9, 0x36, 0xA6, 0x2E, 0x49, + 0xFF, 0xB8, 0x96, 0xC2, 0x8C, 0x07, 0xB3, 0x9B, 0x88, 0x58, 0xFC, 0xEB, + 0x1B, 0x1C, 0xDE, 0x2D, 0x70, 0xE2, 0x97, 0x92, 0x30, 0xA1, 0x89, 0xE3, + 0xBC, 0x55, 0xA8, 0x27, 0xD6, 0x4B, 0xED, 0x90, 0xAD, 0x8B, 0xFA, 0x63, + 0x25, 0x59, 0x2D, 0xA8, 0x35, 0xDD, 0xCA, 0x97, 0x33, 0xBC, 0xE5, 0xCD, + 0xC7, 0x9D, 0xD1, 0xEC, 0xEF, 0x5E, 0x0E, 0x4A, 0x90, 0x06, 0x26, 0x63, + 0xAD, 0xB9, 0xD9, 0x35, 0x2D, 0x07, 0xBA, 0x76, 0x65, 0x2C, 0xAC, 0x57, + 0x8F, 0x7D, 0xF4, 0x07, 0x94, 0xD7, 0x81, 0x02, 0x96, 0x5D, 0xA3, 0x07, + 0x49, 0xD5, 0x7A, 0xD0, 0x57, 0xF9, 0x1B, 0xE7, 0x53, 0x46, 0x75, 0xAA, + 0xB0, 0x79, 0x42, 0xCB, 0x68, 0x71, 0x08, 0xE9, 0x60, 0xBD, 0x39, 0x69, + 0xCE, 0xF4, 0xAF, 0xC3, 0x56, 0x40, 0xC7, 0xAD, 0x52, 0xA2, 0x09, 0xE4, + 0x6F, 0x86, 0x47, 0x8A, 0x1F, 0xEB, 0x28, 0x27, 0x5D, 0x83, 0x20, 0xAF, + 0x04, 0xC9, 0x6C, 0x56, 0x9A, 0x8B, 0x46, 0xF5 +}; + +static const unsigned char TA550_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA551_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA551_RSA_N[] = { + 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80, + 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7, + 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86, + 0xD3, 0xA0, 0x43, 0x7A, 0x4E, 0xB2, 0xA4, 0xD0, 0x36, 0xBA, 0x01, 0xBE, + 0x8D, 0xDB, 0x48, 0xC8, 0x07, 0x17, 0x36, 0x4C, 0xF4, 0xEE, 0x88, 0x23, + 0xC7, 0x3E, 0xEB, 0x37, 0xF5, 0xB5, 0x19, 0xF8, 0x49, 0x68, 0xB0, 0xDE, + 0xD7, 0xB9, 0x76, 0x38, 0x1D, 0x61, 0x9E, 0xA4, 0xFE, 0x82, 0x36, 0xA5, + 0xE5, 0x4A, 0x56, 0xE4, 0x45, 0xE1, 0xF9, 0xFD, 0xB4, 0x16, 0xFA, 0x74, + 0xDA, 0x9C, 0x9B, 0x35, 0x39, 0x2F, 0xFA, 0xB0, 0x20, 0x50, 0x06, 0x6C, + 0x7A, 0xD0, 0x80, 0xB2, 0xA6, 0xF9, 0xAF, 0xEC, 0x47, 0x19, 0x8F, 0x50, + 0x38, 0x07, 0xDC, 0xA2, 0x87, 0x39, 0x58, 0xF8, 0xBA, 0xD5, 0xA9, 0xF9, + 0x48, 0x67, 0x30, 0x96, 0xEE, 0x94, 0x78, 0x5E, 0x6F, 0x89, 0xA3, 0x51, + 0xC0, 0x30, 0x86, 0x66, 0xA1, 0x45, 0x66, 0xBA, 0x54, 0xEB, 0xA3, 0xC3, + 0x91, 0xF9, 0x48, 0xDC, 0xFF, 0xD1, 0xE8, 0x30, 0x2D, 0x7D, 0x2D, 0x74, + 0x70, 0x35, 0xD7, 0x88, 0x24, 0xF7, 0x9E, 0xC4, 0x59, 0x6E, 0xBB, 0x73, + 0x87, 0x17, 0xF2, 0x32, 0x46, 0x28, 0xB8, 0x43, 0xFA, 0xB7, 0x1D, 0xAA, + 0xCA, 0xB4, 0xF2, 0x9F, 0x24, 0x0E, 0x2D, 0x4B, 0xF7, 0x71, 0x5C, 0x5E, + 0x69, 0xFF, 0xEA, 0x95, 0x02, 0xCB, 0x38, 0x8A, 0xAE, 0x50, 0x38, 0x6F, + 0xDB, 0xFB, 0x2D, 0x62, 0x1B, 0xC5, 0xC7, 0x1E, 0x54, 0xE1, 0x77, 0xE0, + 0x67, 0xC8, 0x0F, 0x9C, 0x87, 0x23, 0xD6, 0x3F, 0x40, 0x20, 0x7F, 0x20, + 0x80, 0xC4, 0x80, 0x4C, 0x3E, 0x3B, 0x24, 0x26, 0x8E, 0x04, 0xAE, 0x6C, + 0x9A, 0xC8, 0xAA, 0x0D +}; + +static const unsigned char TA551_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA552_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x45, 0x31 +}; + +static const unsigned char TA552_EC_Q[] = { + 0x04, 0xDE, 0x6F, 0xF8, 0x7F, 0x1C, 0xDF, 0xED, 0xF9, 0x47, 0x87, 0x86, + 0xB1, 0xA4, 0xC0, 0x8A, 0xF8, 0x82, 0x97, 0x80, 0xEA, 0x8F, 0xC8, 0x4A, + 0x5E, 0x2A, 0x7D, 0x88, 0x68, 0xA7, 0x01, 0x62, 0x14, 0x91, 0x24, 0x7A, + 0x5C, 0x9E, 0xA3, 0x17, 0x7D, 0x8A, 0x86, 0x21, 0x34, 0x18, 0x50, 0x1B, + 0x10, 0xDE, 0xD0, 0x37, 0x4B, 0x26, 0xC7, 0x19, 0x60, 0x80, 0xE9, 0x34, + 0xBD, 0x60, 0x19, 0x36, 0x40, 0xD6, 0x29, 0x87, 0x09, 0x3C, 0x91, 0x7A, + 0xF6, 0xBC, 0x13, 0x23, 0xDD, 0x59, 0x4E, 0x04, 0x5E, 0xCF, 0xC8, 0x02, + 0x1C, 0x18, 0x53, 0xC1, 0x31, 0xD8, 0xDA, 0x20, 0xE9, 0x44, 0x8D, 0xE4, + 0x76 +}; + +static const unsigned char TA553_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x52, 0x31 +}; + +static const unsigned char TA553_RSA_N[] = { + 0xD0, 0x36, 0xD4, 0x1F, 0xEA, 0xDD, 0xAB, 0xE4, 0xD1, 0xB6, 0xE6, 0xFB, + 0x22, 0xC0, 0xDD, 0x13, 0x0D, 0x6A, 0x7B, 0x22, 0x13, 0x1C, 0x97, 0x3C, + 0x68, 0x63, 0x66, 0x32, 0x9C, 0x03, 0xB5, 0x8D, 0xA4, 0x81, 0x83, 0xDA, + 0x78, 0x30, 0x11, 0xCF, 0xDC, 0xB2, 0x2B, 0xBE, 0x92, 0xBF, 0x8E, 0xE4, + 0xC4, 0x13, 0xBE, 0xA4, 0x68, 0x4C, 0xDA, 0x02, 0x68, 0x16, 0x74, 0xBE, + 0xB2, 0xDD, 0x04, 0xE4, 0x6B, 0x2A, 0xDD, 0x37, 0x1F, 0x60, 0x2C, 0xDB, + 0xF5, 0xF7, 0xA1, 0x7C, 0x95, 0xB7, 0x0C, 0x70, 0x86, 0x2E, 0xF1, 0x3A, + 0xEF, 0x52, 0xF7, 0xCC, 0xD3, 0x9B, 0xF9, 0x8B, 0xBE, 0x0E, 0xDF, 0x31, + 0xB7, 0x9D, 0x68, 0x5C, 0x92, 0xA6, 0xF5, 0xE5, 0xF3, 0x0A, 0x34, 0xB5, + 0xFF, 0x7B, 0xA2, 0xE4, 0x87, 0xA1, 0xC6, 0xAF, 0x17, 0x00, 0xEF, 0x03, + 0x91, 0xED, 0xA9, 0x1C, 0x4E, 0x71, 0x3D, 0xD2, 0x8B, 0x6C, 0x89, 0xF4, + 0x78, 0x86, 0xE6, 0x6A, 0x49, 0xA0, 0xCE, 0xB5, 0xD2, 0xB0, 0xAB, 0x9B, + 0xF6, 0xF4, 0xD4, 0x2E, 0xE3, 0x72, 0xF9, 0x36, 0xC6, 0xEB, 0x15, 0xB7, + 0x25, 0x8C, 0x3A, 0xFC, 0x25, 0x0D, 0xB3, 0x22, 0x73, 0x21, 0x74, 0xC8, + 0x4A, 0x96, 0x61, 0x92, 0xF5, 0x2F, 0x0B, 0x18, 0xA5, 0xF4, 0xAD, 0xE2, + 0xEE, 0x41, 0xBD, 0x01, 0x79, 0xFA, 0x96, 0x8C, 0x8D, 0x17, 0x02, 0x30, + 0xB4, 0xF9, 0xAF, 0x78, 0x1A, 0x8C, 0xB4, 0x36, 0x10, 0x10, 0x07, 0x05, + 0x70, 0xD0, 0xF4, 0x31, 0x90, 0x8A, 0x51, 0xC5, 0x86, 0x26, 0x79, 0xB2, + 0x11, 0x88, 0x5E, 0xC5, 0xF0, 0x0A, 0x54, 0xCD, 0x49, 0xA6, 0xBF, 0x02, + 0x9C, 0xD2, 0x44, 0xA7, 0xED, 0xE3, 0x78, 0xEF, 0x46, 0x5E, 0x6D, 0x71, + 0xD1, 0x79, 0x70, 0x1C, 0x46, 0x5F, 0x51, 0xE9, 0xC9, 0x37, 0xDC, 0x5F, + 0x7E, 0x69, 0x7B, 0x41, 0xDF, 0x34, 0x45, 0xE0, 0x3B, 0x84, 0xF4, 0xA1, + 0x8A, 0x0A, 0x36, 0x9E, 0x37, 0xCC, 0x62, 0x52, 0xE1, 0x89, 0x0D, 0x28, + 0xF9, 0x7A, 0x23, 0xB1, 0x0D, 0x3D, 0x3D, 0x9A, 0xFD, 0x9D, 0x81, 0xEF, + 0x2C, 0x90, 0xC0, 0x7B, 0x44, 0x4E, 0xBB, 0x49, 0xE0, 0x0E, 0x4A, 0x56, + 0x92, 0xBC, 0xCB, 0xB5, 0xDD, 0x79, 0x17, 0x89, 0x91, 0xDE, 0x61, 0x89, + 0x74, 0x92, 0xA8, 0xE3, 0x32, 0x85, 0xBE, 0x4E, 0x85, 0xA4, 0x4B, 0x59, + 0xCB, 0x2B, 0xC5, 0x78, 0x8E, 0x71, 0x54, 0xD0, 0x02, 0x37, 0x99, 0x8C, + 0xE5, 0x49, 0xEA, 0xE0, 0x54, 0x72, 0xA4, 0x11, 0x06, 0x2F, 0x0B, 0x8C, + 0xC1, 0x5B, 0xBE, 0xB5, 0xA1, 0xB0, 0x53, 0x6E, 0x9C, 0xB8, 0x60, 0x91, + 0x1F, 0x59, 0x6B, 0xF9, 0x2D, 0xF4, 0x94, 0x0A, 0x97, 0xB5, 0xEC, 0xC5, + 0x76, 0x03, 0x54, 0x1B, 0x65, 0x52, 0xBA, 0x4C, 0x92, 0x56, 0x51, 0x35, + 0xA0, 0x40, 0xD8, 0x29, 0xDB, 0xAE, 0x52, 0x76, 0x3B, 0x2D, 0x30, 0x40, + 0x9B, 0x8A, 0xD0, 0x42, 0x56, 0xB4, 0xB7, 0x88, 0x01, 0xA4, 0x87, 0x3B, + 0x53, 0x96, 0xCD, 0xA3, 0x16, 0x8F, 0xF3, 0x66, 0xAA, 0x17, 0xB1, 0xC7, + 0x60, 0xE0, 0xC1, 0x43, 0x05, 0x0C, 0xEE, 0x9B, 0x5B, 0x60, 0x6F, 0x06, + 0x5C, 0x87, 0x5B, 0x27, 0xF9, 0x40, 0x11, 0x9E, 0x9C, 0x33, 0xC1, 0xB7, + 0xE5, 0x35, 0x57, 0x05, 0x7F, 0x27, 0xCE, 0x17, 0x20, 0x8C, 0x1C, 0xFC, + 0xF1, 0xFB, 0xDA, 0x31, 0x29, 0x49, 0xED, 0xF5, 0x0B, 0x84, 0xA7, 0x4F, + 0xC1, 0xF6, 0x4E, 0xC2, 0x28, 0x9C, 0xFA, 0xEE, 0xE0, 0xAF, 0x07, 0xFB, + 0x33, 0x11, 0x7A, 0x21, 0x4F, 0x0B, 0x21, 0x10, 0xB6, 0x40, 0x3A, 0xAB, + 0x22, 0x3A, 0x04, 0x9C, 0x8B, 0x9B, 0x84, 0x86, 0x72, 0x9A, 0xD2, 0xA7, + 0xA5, 0xC4, 0xB4, 0x75, 0x91, 0xA9, 0x2B, 0x23 +}; + +static const unsigned char TA553_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA554_DN[] = { + 0x30, 0x34, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x08, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61 +}; + +static const unsigned char TA554_RSA_N[] = { + 0xC8, 0x68, 0xF1, 0xC9, 0xD6, 0xD6, 0xB3, 0x34, 0x75, 0x26, 0x82, 0x1E, + 0xEC, 0xB4, 0xBE, 0xEA, 0x5C, 0xE1, 0x26, 0xED, 0x11, 0x47, 0x61, 0xE1, + 0xA2, 0x7C, 0x16, 0x78, 0x40, 0x21, 0xE4, 0x60, 0x9E, 0x5A, 0xC8, 0x63, + 0xE1, 0xC4, 0xB1, 0x96, 0x92, 0xFF, 0x18, 0x6D, 0x69, 0x23, 0xE1, 0x2B, + 0x62, 0xF7, 0xDD, 0xE2, 0x36, 0x2F, 0x91, 0x07, 0xB9, 0x48, 0xCF, 0x0E, + 0xEC, 0x79, 0xB6, 0x2C, 0xE7, 0x34, 0x4B, 0x70, 0x08, 0x25, 0xA3, 0x3C, + 0x87, 0x1B, 0x19, 0xF2, 0x81, 0x07, 0x0F, 0x38, 0x90, 0x19, 0xD3, 0x11, + 0xFE, 0x86, 0xB4, 0xF2, 0xD1, 0x5E, 0x1E, 0x1E, 0x96, 0xCD, 0x80, 0x6C, + 0xCE, 0x3B, 0x31, 0x93, 0xB6, 0xF2, 0xA0, 0xD0, 0xA9, 0x95, 0x12, 0x7D, + 0xA5, 0x9A, 0xCC, 0x6B, 0xC8, 0x84, 0x56, 0x8A, 0x33, 0xA9, 0xE7, 0x22, + 0x15, 0x53, 0x16, 0xF0, 0xCC, 0x17, 0xEC, 0x57, 0x5F, 0xE9, 0xA2, 0x0A, + 0x98, 0x09, 0xDE, 0xE3, 0x5F, 0x9C, 0x6F, 0xDC, 0x48, 0xE3, 0x85, 0x0B, + 0x15, 0x5A, 0xA6, 0xBA, 0x9F, 0xAC, 0x48, 0xE3, 0x09, 0xB2, 0xF7, 0xF4, + 0x32, 0xDE, 0x5E, 0x34, 0xBE, 0x1C, 0x78, 0x5D, 0x42, 0x5B, 0xCE, 0x0E, + 0x22, 0x8F, 0x4D, 0x90, 0xD7, 0x7D, 0x32, 0x18, 0xB3, 0x0B, 0x2C, 0x6A, + 0xBF, 0x8E, 0x3F, 0x14, 0x11, 0x89, 0x20, 0x0E, 0x77, 0x14, 0xB5, 0x3D, + 0x94, 0x08, 0x87, 0xF7, 0x25, 0x1E, 0xD5, 0xB2, 0x60, 0x00, 0xEC, 0x6F, + 0x2A, 0x28, 0x25, 0x6E, 0x2A, 0x3E, 0x18, 0x63, 0x17, 0x25, 0x3F, 0x3E, + 0x44, 0x20, 0x16, 0xF6, 0x26, 0xC8, 0x25, 0xAE, 0x05, 0x4A, 0xB4, 0xE7, + 0x63, 0x2C, 0xF3, 0x8C, 0x16, 0x53, 0x7E, 0x5C, 0xFB, 0x11, 0x1A, 0x08, + 0xC1, 0x46, 0x62, 0x9F, 0x22, 0xB8, 0xF1, 0xC2, 0x8D, 0x69, 0xDC, 0xFA, + 0x3A, 0x58, 0x06, 0xDF +}; + +static const unsigned char TA554_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA555_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x13, 0x30, 0x30, + 0x30, 0x32, 0x20, 0x34, 0x38, 0x31, 0x34, 0x36, 0x33, 0x30, 0x38, 0x31, + 0x30, 0x30, 0x30, 0x33, 0x36, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA555_RSA_N[] = { + 0xCD, 0x18, 0x39, 0x65, 0x1A, 0x59, 0xB1, 0xEA, 0x64, 0x16, 0x0E, 0x8C, + 0x94, 0x24, 0x95, 0x7C, 0x83, 0xD3, 0xC5, 0x39, 0x26, 0xDC, 0x0C, 0xEF, + 0x16, 0x57, 0x8D, 0xD7, 0xD8, 0xAC, 0xA3, 0x42, 0x7F, 0x82, 0xCA, 0xED, + 0xCD, 0x5B, 0xDB, 0x0E, 0xB7, 0x2D, 0xED, 0x45, 0x08, 0x17, 0xB2, 0xD9, + 0xB3, 0xCB, 0xD6, 0x17, 0x52, 0x72, 0x28, 0xDB, 0x8E, 0x4E, 0x9E, 0x8A, + 0xB6, 0x0B, 0xF9, 0x9E, 0x84, 0x9A, 0x4D, 0x76, 0xDE, 0x22, 0x29, 0x5C, + 0xD2, 0xB3, 0xD2, 0x06, 0x3E, 0x30, 0x39, 0xA9, 0x74, 0xA3, 0x92, 0x56, + 0x1C, 0xA1, 0x6F, 0x4C, 0x0A, 0x20, 0x6D, 0x9F, 0x23, 0x7A, 0xB4, 0xC6, + 0xDA, 0x2C, 0xE4, 0x1D, 0x2C, 0xDC, 0xB3, 0x28, 0xD0, 0x13, 0xF2, 0x4C, + 0x4E, 0x02, 0x49, 0xA1, 0x54, 0x40, 0x9E, 0xE6, 0xE5, 0x05, 0xA0, 0x2D, + 0x84, 0xC8, 0xFF, 0x98, 0x6C, 0xD0, 0xEB, 0x8A, 0x1A, 0x84, 0x08, 0x1E, + 0xB7, 0x68, 0x23, 0xEE, 0x23, 0xD5, 0x70, 0xCE, 0x6D, 0x51, 0x69, 0x10, + 0xEE, 0xA1, 0x7A, 0xC2, 0xD1, 0x22, 0x31, 0xC2, 0x82, 0x85, 0xD2, 0xF2, + 0x55, 0x76, 0x50, 0x7C, 0x25, 0x7A, 0xC9, 0x84, 0x5C, 0x0B, 0xAC, 0xDD, + 0x42, 0x4E, 0x2B, 0xE7, 0x82, 0xA2, 0x24, 0x89, 0xCB, 0x90, 0xB2, 0xD0, + 0xEE, 0x23, 0xBA, 0x66, 0x4C, 0xBB, 0x62, 0xA4, 0xF9, 0x53, 0x5A, 0x64, + 0x7B, 0x7C, 0x98, 0xFA, 0xA3, 0x48, 0x9E, 0x0F, 0x95, 0xAE, 0xA7, 0x18, + 0xF4, 0x6A, 0xEC, 0x2E, 0x03, 0x45, 0xAF, 0xF0, 0x74, 0xF8, 0x2A, 0xCD, + 0x7A, 0x5D, 0xD1, 0xBE, 0x44, 0x26, 0x32, 0x29, 0xF1, 0xF1, 0xF5, 0x6C, + 0xCC, 0x7E, 0x02, 0x21, 0x0B, 0x9F, 0x6F, 0xA4, 0x3F, 0xBE, 0x9D, 0x53, + 0xE2, 0xCF, 0x7D, 0xA9, 0x2C, 0x7C, 0x58, 0x1A, 0x97, 0xE1, 0x3D, 0x37, + 0x37, 0x18, 0x66, 0x28, 0xD2, 0x40, 0xC5, 0x51, 0x8A, 0x8C, 0xC3, 0x2D, + 0xCE, 0x53, 0x88, 0x24, 0x58, 0x64, 0x30, 0x16, 0xC5, 0xAA, 0xE0, 0xD6, + 0x0A, 0xA6, 0x40, 0xDF, 0x78, 0xF6, 0xF5, 0x04, 0x7C, 0x69, 0x13, 0x84, + 0xBC, 0xD1, 0xD1, 0xA7, 0x06, 0xCF, 0x01, 0xF7, 0x68, 0xC0, 0xA8, 0x57, + 0xBB, 0x3A, 0x61, 0xAD, 0x04, 0x8C, 0x93, 0xE3, 0xAD, 0xFC, 0xF0, 0xDB, + 0x44, 0x6D, 0x59, 0xDC, 0x49, 0x59, 0xAE, 0xAC, 0x9A, 0x99, 0x36, 0x30, + 0x41, 0x7B, 0x76, 0x33, 0x22, 0x87, 0xA3, 0xC2, 0x92, 0x86, 0x6E, 0xF9, + 0x70, 0xEE, 0xAE, 0x87, 0x87, 0x95, 0x1B, 0xC4, 0x7A, 0xBD, 0x31, 0xF3, + 0xD4, 0xD2, 0xE5, 0x99, 0xFF, 0xBE, 0x48, 0xEC, 0x75, 0xF5, 0x78, 0x16, + 0x1D, 0xA6, 0x70, 0xC1, 0x7F, 0x3C, 0x1B, 0xA1, 0x92, 0xFB, 0xCF, 0xC8, + 0x3C, 0xD6, 0xC5, 0x93, 0x0A, 0x8F, 0xF5, 0x55, 0x3A, 0x76, 0x95, 0xCE, + 0x59, 0x98, 0x8A, 0x09, 0x95, 0x77, 0x32, 0x9A, 0x83, 0xBA, 0x2C, 0x04, + 0x3A, 0x97, 0xBD, 0xD4, 0x2F, 0xBE, 0xD7, 0x6C, 0x9B, 0xA2, 0xCA, 0x7D, + 0x6D, 0x26, 0xC9, 0x55, 0xD5, 0xCF, 0xC3, 0x79, 0x52, 0x08, 0x09, 0x99, + 0x07, 0x24, 0x2D, 0x64, 0x25, 0x6B, 0xA6, 0x21, 0x69, 0x9B, 0x6A, 0xDD, + 0x74, 0x4D, 0x6B, 0x97, 0x7A, 0x41, 0xBD, 0xAB, 0x17, 0xF9, 0x90, 0x17, + 0x48, 0x8F, 0x36, 0xF9, 0x2D, 0xD5, 0xC5, 0xDB, 0xEE, 0xAA, 0x85, 0x45, + 0x41, 0xFA, 0xCD, 0x3A, 0x45, 0xB1, 0x68, 0xE6, 0x36, 0x4C, 0x9B, 0x90, + 0x57, 0xEC, 0x23, 0xB9, 0x87, 0x08, 0xC2, 0xC4, 0x09, 0xF1, 0x97, 0x86, + 0x2A, 0x28, 0x4D, 0xE2, 0x74, 0xC0, 0xDA, 0xC4, 0x8C, 0xDB, 0xDF, 0xE2, + 0xA1, 0x17, 0x59, 0xCE, 0x24, 0x59, 0x74, 0x31, 0xDA, 0x7F, 0xFD, 0x30, + 0x6D, 0xD9, 0xDC, 0xE1, 0x6A, 0xE1, 0xFC, 0x5F +}; + +static const unsigned char TA555_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA556_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x43, 0x45, 0x52, 0x54, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x53, + 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x13, + 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, + 0x54, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA556_RSA_N[] = { + 0xC0, 0xC5, 0x75, 0x19, 0x91, 0x7D, 0x44, 0x74, 0x74, 0x87, 0xFE, 0x0E, + 0x3B, 0x96, 0xDC, 0xD8, 0x01, 0x16, 0xCC, 0xEE, 0x63, 0x91, 0xE7, 0x0B, + 0x6F, 0xCE, 0x3B, 0x0A, 0x69, 0x1A, 0x7C, 0xC2, 0xE3, 0xAF, 0x82, 0x8E, + 0x86, 0xD7, 0x5E, 0x8F, 0x57, 0xEB, 0xD3, 0x21, 0x59, 0xFD, 0x39, 0x37, + 0x42, 0x30, 0xBE, 0x50, 0xEA, 0xB6, 0x0F, 0xA9, 0x88, 0xD8, 0x2E, 0x2D, + 0x69, 0x21, 0xE7, 0xD1, 0x37, 0x18, 0x4E, 0x7D, 0x91, 0xD5, 0x16, 0x5F, + 0x6B, 0x5B, 0x00, 0xC2, 0x39, 0x43, 0x0D, 0x36, 0x85, 0x52, 0xB9, 0x53, + 0x65, 0x0F, 0x1D, 0x42, 0xE5, 0x8F, 0xCF, 0x05, 0xD3, 0xEE, 0xDC, 0x0C, + 0x1A, 0xD9, 0xB8, 0x8B, 0x78, 0x22, 0x67, 0xE4, 0x69, 0xB0, 0x68, 0xC5, + 0x3C, 0xE4, 0x6C, 0x5A, 0x46, 0xE7, 0xCD, 0xC7, 0xFA, 0xEF, 0xC4, 0xEC, + 0x4B, 0xBD, 0x6A, 0xA4, 0xAC, 0xFD, 0xCC, 0x28, 0x51, 0xEF, 0x92, 0xB4, + 0x29, 0xAB, 0xAB, 0x35, 0x9A, 0x4C, 0xE4, 0xC4, 0x08, 0xC6, 0x26, 0xCC, + 0xF8, 0x69, 0x9F, 0xE4, 0x9C, 0xF0, 0x29, 0xD3, 0x5C, 0xF9, 0xC6, 0x16, + 0x25, 0x9E, 0x23, 0xC3, 0x20, 0xC1, 0x3D, 0x0F, 0x3F, 0x38, 0x40, 0xB0, + 0xFE, 0x82, 0x44, 0x38, 0xAA, 0x5A, 0x1A, 0x8A, 0x6B, 0x63, 0x58, 0x38, + 0xB4, 0x15, 0xD3, 0xB6, 0x11, 0x69, 0x7B, 0x1E, 0x54, 0xEE, 0x8C, 0x1A, + 0x22, 0xAC, 0x72, 0x97, 0x3F, 0x23, 0x59, 0x9B, 0xC9, 0x22, 0x84, 0xC1, + 0x07, 0x4F, 0xCC, 0x7F, 0xE2, 0x57, 0xCA, 0x12, 0x70, 0xBB, 0xA6, 0x65, + 0xF3, 0x69, 0x75, 0x63, 0xBD, 0x95, 0xFB, 0x1B, 0x97, 0xCD, 0xE4, 0xA8, + 0xAF, 0xF6, 0xD1, 0x4E, 0xA8, 0xD9, 0x8A, 0x71, 0x24, 0xCD, 0x36, 0x3D, + 0xBC, 0x96, 0xC4, 0xF1, 0x6C, 0xA9, 0xAE, 0xE5, 0xCF, 0x0D, 0x6E, 0x28, + 0x0D, 0xB0, 0x0E, 0xB5, 0xCA, 0x51, 0x7B, 0x78, 0x14, 0xC3, 0x20, 0x2F, + 0x7F, 0xFB, 0x14, 0x55, 0xE1, 0x11, 0x99, 0xFD, 0xD5, 0x0A, 0xA1, 0x9E, + 0x02, 0xE3, 0x62, 0x5F, 0xEB, 0x35, 0x4B, 0x2C, 0xB8, 0x72, 0xE8, 0x3E, + 0x3D, 0x4F, 0xAC, 0x2C, 0xBB, 0x2E, 0x86, 0xE2, 0xA3, 0x76, 0x8F, 0xE5, + 0x93, 0x2A, 0xCF, 0xA5, 0xAB, 0xC8, 0x5C, 0x8D, 0x4B, 0x06, 0xFF, 0x12, + 0x46, 0xAC, 0x78, 0xCB, 0x14, 0x07, 0x35, 0xE0, 0xA9, 0xDF, 0x8B, 0xE9, + 0xAF, 0x15, 0x4F, 0x16, 0x89, 0x5B, 0xBD, 0xF6, 0x8D, 0xC6, 0x59, 0xAE, + 0x88, 0x85, 0x0E, 0xC1, 0x89, 0xEB, 0x1F, 0x67, 0xC5, 0x45, 0x8E, 0xFF, + 0x6D, 0x37, 0x36, 0x2B, 0x78, 0x66, 0x83, 0x91, 0x51, 0x2B, 0x3D, 0xFF, + 0x51, 0x77, 0x76, 0x62, 0xA1, 0xEC, 0x67, 0x3E, 0x3E, 0x81, 0x83, 0xE0, + 0x56, 0xA9, 0x50, 0x1F, 0x1F, 0x7A, 0x99, 0xAB, 0x63, 0xBF, 0x84, 0x17, + 0x77, 0xF1, 0x0D, 0x3B, 0xDF, 0xF7, 0x9C, 0x61, 0xB3, 0x35, 0x98, 0x8A, + 0x3A, 0xB2, 0xEC, 0x3C, 0x1A, 0x37, 0x3F, 0x7E, 0x8F, 0x92, 0xCF, 0xD9, + 0x12, 0x14, 0x64, 0xDA, 0x10, 0x02, 0x15, 0x41, 0xFF, 0x4F, 0xC4, 0xEB, + 0x1C, 0xA3, 0xC9, 0xFA, 0x99, 0xF7, 0x46, 0xE9, 0xE1, 0x18, 0xD9, 0xB1, + 0xB8, 0x32, 0x2D, 0xCB, 0x14, 0x0C, 0x50, 0xD8, 0x83, 0x65, 0x83, 0xEE, + 0xB9, 0x5C, 0xCF, 0xCB, 0x05, 0x5A, 0x4C, 0xFA, 0x19, 0x97, 0x6B, 0xD6, + 0x5D, 0x13, 0xD3, 0xC2, 0x5C, 0x54, 0xBC, 0x32, 0x73, 0xA0, 0x78, 0xF5, + 0xF1, 0x6D, 0x1E, 0xCB, 0x9F, 0xA5, 0xA6, 0x9F, 0x22, 0xDC, 0xD1, 0x51, + 0x9E, 0x82, 0x79, 0x64, 0x60, 0x29, 0x13, 0x3E, 0xA3, 0xFD, 0x4F, 0x72, + 0x6A, 0xAB, 0xE2, 0xD4, 0xE5, 0xB8, 0x24, 0x55, 0x2C, 0x44, 0x4B, 0x8A, + 0x88, 0x44, 0x9C, 0xCA, 0x84, 0xD3, 0x2A, 0x3B +}; + +static const unsigned char TA556_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA557_DN[] = { + 0x30, 0x3B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x52, 0x4F, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x08, 0x63, 0x65, 0x72, 0x74, 0x53, 0x49, 0x47, 0x4E, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x10, 0x63, 0x65, 0x72, + 0x74, 0x53, 0x49, 0x47, 0x4E, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA557_RSA_N[] = { + 0xB7, 0x33, 0xB9, 0x7E, 0xC8, 0x25, 0x4A, 0x8E, 0xB5, 0xDB, 0xB4, 0x28, + 0x1B, 0xAA, 0x57, 0x90, 0xE8, 0xD1, 0x22, 0xD3, 0x64, 0xBA, 0xD3, 0x93, + 0xE8, 0xD4, 0xAC, 0x86, 0x61, 0x40, 0x6A, 0x60, 0x57, 0x68, 0x54, 0x84, + 0x4D, 0xBC, 0x6A, 0x54, 0x02, 0x05, 0xFF, 0xDF, 0x9B, 0x9A, 0x2A, 0xAE, + 0x5D, 0x07, 0x8F, 0x4A, 0xC3, 0x28, 0x7F, 0xEF, 0xFB, 0x2B, 0xFA, 0x79, + 0xF1, 0xC7, 0xAD, 0xF0, 0x10, 0x53, 0x24, 0x90, 0x8B, 0x66, 0xC9, 0xA8, + 0x88, 0xAB, 0xAF, 0x5A, 0xA3, 0x00, 0xE9, 0xBE, 0xBA, 0x46, 0xEE, 0x5B, + 0x73, 0x7B, 0x2C, 0x17, 0x82, 0x81, 0x5E, 0x62, 0x2C, 0xA1, 0x02, 0x65, + 0xB3, 0xBD, 0xC5, 0x2B, 0x00, 0x7E, 0xC4, 0xFC, 0x03, 0x33, 0x57, 0x0D, + 0xED, 0xE2, 0xFA, 0xCE, 0x5D, 0x45, 0xD6, 0x38, 0xCD, 0x35, 0xB6, 0xB2, + 0xC1, 0xD0, 0x9C, 0x81, 0x4A, 0xAA, 0xE4, 0xB2, 0x01, 0x5C, 0x1D, 0x8F, + 0x5F, 0x99, 0xC4, 0xB1, 0xAD, 0xDB, 0x88, 0x21, 0xEB, 0x90, 0x08, 0x82, + 0x80, 0xF3, 0x30, 0xA3, 0x43, 0xE6, 0x90, 0x82, 0xAE, 0x55, 0x28, 0x49, + 0xED, 0x5B, 0xD7, 0xA9, 0x10, 0x38, 0x0E, 0xFE, 0x8F, 0x4C, 0x5B, 0x9B, + 0x46, 0xEA, 0x41, 0xF5, 0xB0, 0x08, 0x74, 0xC3, 0xD0, 0x88, 0x33, 0xB6, + 0x7C, 0xD7, 0x74, 0xDF, 0xDC, 0x84, 0xD1, 0x43, 0x0E, 0x75, 0x39, 0xA1, + 0x25, 0x40, 0x28, 0xEA, 0x78, 0xCB, 0x0E, 0x2C, 0x2E, 0x39, 0x9D, 0x8C, + 0x8B, 0x6E, 0x16, 0x1C, 0x2F, 0x26, 0x82, 0x10, 0xE2, 0xE3, 0x65, 0x94, + 0x0A, 0x04, 0xC0, 0x5E, 0xF7, 0x5D, 0x5B, 0xF8, 0x10, 0xE2, 0xD0, 0xBA, + 0x7A, 0x4B, 0xFB, 0xDE, 0x37, 0x00, 0x00, 0x1A, 0x5B, 0x28, 0xE3, 0xD2, + 0x9C, 0x73, 0x3E, 0x32, 0x87, 0x98, 0xA1, 0xC9, 0x51, 0x2F, 0xD7, 0xDE, + 0xAC, 0x33, 0xB3, 0x4F +}; + +static const unsigned char TA557_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA558_DN[] = { + 0x30, 0x74, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x45, 0x43, 0x2D, 0x33, 0x38, 0x34, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA558_EC_Q[] = { + 0x04, 0xC4, 0x28, 0x8E, 0xAB, 0x18, 0x5B, 0x6A, 0xBE, 0x6E, 0x64, 0x37, + 0x63, 0xE4, 0xCD, 0xEC, 0xAB, 0x3A, 0xF7, 0xCC, 0xA1, 0xB8, 0x0E, 0x82, + 0x49, 0xD7, 0x86, 0x29, 0x9F, 0xA1, 0x94, 0xF2, 0xE3, 0x60, 0x78, 0x98, + 0x81, 0x78, 0x06, 0x4D, 0xF2, 0xEC, 0x9A, 0x0E, 0x57, 0x60, 0x83, 0x9F, + 0xB4, 0xE6, 0x17, 0x2F, 0x1A, 0xB3, 0x5D, 0x02, 0x5B, 0x89, 0x23, 0x3C, + 0xC2, 0x11, 0x05, 0x2A, 0xA7, 0x88, 0x13, 0x18, 0xF3, 0x50, 0x84, 0xD7, + 0xBD, 0x34, 0x2C, 0x27, 0x89, 0x55, 0xFF, 0xCE, 0x4C, 0xE7, 0xDF, 0xA6, + 0x1F, 0x28, 0xC4, 0xF0, 0x54, 0xC3, 0xB9, 0x7C, 0xB7, 0x53, 0xAD, 0xEB, + 0xC2 +}; + +static const unsigned char TA559_DN[] = { + 0x30, 0x81, 0x80, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, + 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x24, 0x30, + 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1B, 0x43, 0x65, 0x72, 0x74, + 0x75, 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, + 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA559_RSA_N[] = { + 0xBD, 0xF9, 0x78, 0xF8, 0xE6, 0xD5, 0x80, 0x0C, 0x64, 0x9D, 0x86, 0x1B, + 0x96, 0x64, 0x67, 0x3F, 0x22, 0x3A, 0x1E, 0x75, 0x01, 0x7D, 0xEF, 0xFB, + 0x5C, 0x67, 0x8C, 0xC9, 0xCC, 0x5C, 0x6B, 0xA9, 0x91, 0xE6, 0xB9, 0x42, + 0xE5, 0x20, 0x4B, 0x9B, 0xDA, 0x9B, 0x7B, 0xB9, 0x99, 0x5D, 0xD9, 0x9B, + 0x80, 0x4B, 0xD7, 0x84, 0x40, 0x2B, 0x27, 0xD3, 0xE8, 0xBA, 0x30, 0xBB, + 0x3E, 0x09, 0x1A, 0xA7, 0x49, 0x95, 0xEF, 0x2B, 0x40, 0x24, 0xC2, 0x97, + 0xC7, 0xA7, 0xEE, 0x9B, 0x25, 0xEF, 0xA8, 0x0A, 0x00, 0x97, 0x85, 0x5A, + 0xAA, 0x9D, 0xDC, 0x29, 0xC9, 0xE2, 0x35, 0x07, 0xEB, 0x70, 0x4D, 0x4A, + 0xD6, 0xC1, 0xB3, 0x56, 0xB8, 0xA1, 0x41, 0x38, 0x9B, 0xD1, 0xFB, 0x31, + 0x7F, 0x8F, 0xE0, 0x5F, 0xE1, 0xB1, 0x3F, 0x0F, 0x8E, 0x16, 0x49, 0x60, + 0xD7, 0x06, 0x8D, 0x18, 0xF9, 0xAA, 0x26, 0x10, 0xAB, 0x2A, 0xD3, 0xD0, + 0xD1, 0x67, 0x8D, 0x1B, 0x46, 0xBE, 0x47, 0x30, 0xD5, 0x2E, 0x72, 0xD1, + 0xC5, 0x63, 0xDA, 0xE7, 0x63, 0x79, 0x44, 0x7E, 0x4B, 0x63, 0x24, 0x89, + 0x86, 0x2E, 0x34, 0x3F, 0x29, 0x4C, 0x52, 0x8B, 0x2A, 0xA7, 0xC0, 0xE2, + 0x91, 0x28, 0x89, 0xB9, 0xC0, 0x5B, 0xF9, 0x1D, 0xD9, 0xE7, 0x27, 0xAD, + 0xFF, 0x9A, 0x02, 0x97, 0xC1, 0xC6, 0x50, 0x92, 0x9B, 0x02, 0x2C, 0xBD, + 0xA9, 0xB9, 0x34, 0x59, 0x0A, 0xBF, 0x84, 0x4A, 0xFF, 0xDF, 0xFE, 0xB3, + 0x9F, 0xEB, 0xD9, 0x9E, 0xE0, 0x98, 0x23, 0xEC, 0xA6, 0x6B, 0x77, 0x16, + 0x2A, 0xDB, 0xCC, 0xAD, 0x3B, 0x1C, 0xA4, 0x87, 0xDC, 0x46, 0x73, 0x5E, + 0x19, 0x62, 0x68, 0x45, 0x57, 0xE4, 0x90, 0x82, 0x42, 0xBB, 0x42, 0xD6, + 0xF0, 0x61, 0xE0, 0xC1, 0xA3, 0x3D, 0x66, 0xA3, 0x5D, 0xF4, 0x18, 0xEE, + 0x88, 0xC9, 0x8D, 0x17, 0x45, 0x29, 0x99, 0x32, 0x75, 0x02, 0x31, 0xEE, + 0x29, 0x26, 0xC8, 0x6B, 0x02, 0xE6, 0xB5, 0x62, 0x45, 0x7F, 0x37, 0x15, + 0x5A, 0x23, 0x68, 0x89, 0xD4, 0x3E, 0xDE, 0x4E, 0x27, 0xB0, 0xF0, 0x40, + 0x0C, 0xBC, 0x4D, 0x17, 0xCB, 0x4D, 0xA2, 0xB3, 0x1E, 0xD0, 0x06, 0x5A, + 0xDD, 0xF6, 0x93, 0xCF, 0x57, 0x75, 0x99, 0xF5, 0xFA, 0x86, 0x1A, 0x67, + 0x78, 0xB3, 0xBF, 0x96, 0xFE, 0x34, 0xDC, 0xBD, 0xE7, 0x52, 0x56, 0xE5, + 0xB3, 0xE5, 0x75, 0x7B, 0xD7, 0x41, 0x91, 0x05, 0xDC, 0x5D, 0x69, 0xE3, + 0x95, 0x0D, 0x43, 0xB9, 0xFC, 0x83, 0x96, 0x39, 0x95, 0x7B, 0x6C, 0x80, + 0x5A, 0x4F, 0x13, 0x72, 0xC6, 0xD7, 0x7D, 0x29, 0x7A, 0x44, 0xBA, 0x52, + 0xA4, 0x2A, 0xD5, 0x41, 0x46, 0x09, 0x20, 0xFE, 0x22, 0xA0, 0xB6, 0x5B, + 0x30, 0x8D, 0xBC, 0x89, 0x0C, 0xD5, 0xD7, 0x70, 0xF8, 0x87, 0x52, 0xFD, + 0xDA, 0xEF, 0xAC, 0x51, 0x2E, 0x07, 0xB3, 0x4E, 0xFE, 0xD0, 0x09, 0xDA, + 0x70, 0xEF, 0x98, 0xFA, 0x56, 0xE6, 0x6D, 0xDB, 0xB5, 0x57, 0x4B, 0xDC, + 0xE5, 0x2C, 0x25, 0x15, 0xC8, 0x9E, 0x2E, 0x78, 0x4E, 0xF8, 0xDA, 0x9C, + 0x9E, 0x86, 0x2C, 0xCA, 0x57, 0xF3, 0x1A, 0xE5, 0xC8, 0x92, 0x8B, 0x1A, + 0x82, 0x96, 0x7A, 0xC3, 0xBC, 0x50, 0x12, 0x69, 0xD8, 0x0E, 0x5A, 0x46, + 0x8B, 0x3A, 0xEB, 0x26, 0xFA, 0x23, 0xC9, 0xB6, 0xB0, 0x81, 0xBE, 0x42, + 0x00, 0xA4, 0xF8, 0xD6, 0xFE, 0x30, 0x2E, 0xC7, 0xD2, 0x46, 0xF6, 0xE5, + 0x8E, 0x75, 0xFD, 0xF2, 0xCC, 0xB9, 0xD0, 0x87, 0x5B, 0xCC, 0x06, 0x10, + 0x60, 0xBB, 0x83, 0x35, 0xB7, 0x5E, 0x67, 0xDE, 0x47, 0xEC, 0x99, 0x48, + 0xF1, 0xA4, 0xA1, 0x15, 0xFE, 0xAD, 0x8C, 0x62, 0x8E, 0x39, 0x55, 0x4F, + 0x39, 0x16, 0xB9, 0xB1, 0x63, 0x9D, 0xFF, 0xB7 +}; + +static const unsigned char TA559_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA560_DN[] = { + 0x30, 0x7E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x55, 0x6E, 0x69, 0x7A, 0x65, 0x74, 0x6F, 0x20, 0x54, 0x65, + 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, + 0x2E, 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, + 0x6D, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4E, 0x65, + 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA560_RSA_N[] = { + 0xE3, 0xFB, 0x7D, 0xA3, 0x72, 0xBA, 0xC2, 0xF0, 0xC9, 0x14, 0x87, 0xF5, + 0x6B, 0x01, 0x4E, 0xE1, 0x6E, 0x40, 0x07, 0xBA, 0x6D, 0x27, 0x5D, 0x7F, + 0xF7, 0x5B, 0x2D, 0xB3, 0x5A, 0xC7, 0x51, 0x5F, 0xAB, 0xA4, 0x32, 0xA6, + 0x61, 0x87, 0xB6, 0x6E, 0x0F, 0x86, 0xD2, 0x30, 0x02, 0x97, 0xF8, 0xD7, + 0x69, 0x57, 0xA1, 0x18, 0x39, 0x5D, 0x6A, 0x64, 0x79, 0xC6, 0x01, 0x59, + 0xAC, 0x3C, 0x31, 0x4A, 0x38, 0x7C, 0xD2, 0x04, 0xD2, 0x4B, 0x28, 0xE8, + 0x20, 0x5F, 0x3B, 0x07, 0xA2, 0xCC, 0x4D, 0x73, 0xDB, 0xF3, 0xAE, 0x4F, + 0xC7, 0x56, 0xD5, 0x5A, 0xA7, 0x96, 0x89, 0xFA, 0xF3, 0xAB, 0x68, 0xD4, + 0x23, 0x86, 0x59, 0x27, 0xCF, 0x09, 0x27, 0xBC, 0xAC, 0x6E, 0x72, 0x83, + 0x1C, 0x30, 0x72, 0xDF, 0xE0, 0xA2, 0xE9, 0xD2, 0xE1, 0x74, 0x75, 0x19, + 0xBD, 0x2A, 0x9E, 0x7B, 0x15, 0x54, 0x04, 0x1B, 0xD7, 0x43, 0x39, 0xAD, + 0x55, 0x28, 0xC5, 0xE2, 0x1A, 0xBB, 0xF4, 0xC0, 0xE4, 0xAE, 0x38, 0x49, + 0x33, 0xCC, 0x76, 0x85, 0x9F, 0x39, 0x45, 0xD2, 0xA4, 0x9E, 0xF2, 0x12, + 0x8C, 0x51, 0xF8, 0x7C, 0xE4, 0x2D, 0x7F, 0xF5, 0xAC, 0x5F, 0xEB, 0x16, + 0x9F, 0xB1, 0x2D, 0xD1, 0xBA, 0xCC, 0x91, 0x42, 0x77, 0x4C, 0x25, 0xC9, + 0x90, 0x38, 0x6F, 0xDB, 0xF0, 0xCC, 0xFB, 0x8E, 0x1E, 0x97, 0x59, 0x3E, + 0xD5, 0x60, 0x4E, 0xE6, 0x05, 0x28, 0xED, 0x49, 0x79, 0x13, 0x4B, 0xBA, + 0x48, 0xDB, 0x2F, 0xF9, 0x72, 0xD3, 0x39, 0xCA, 0xFE, 0x1F, 0xD8, 0x34, + 0x72, 0xF5, 0xB4, 0x40, 0xCF, 0x31, 0x01, 0xC3, 0xEC, 0xDE, 0x11, 0x2D, + 0x17, 0x5D, 0x1F, 0xB8, 0x50, 0xD1, 0x5E, 0x19, 0xA7, 0x69, 0xDE, 0x07, + 0x33, 0x28, 0xCA, 0x50, 0x95, 0xF9, 0xA7, 0x54, 0xCB, 0x54, 0x86, 0x50, + 0x45, 0xA9, 0xF9, 0x49 +}; + +static const unsigned char TA560_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA561_DN[] = { + 0x30, 0x7A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA561_RSA_N[] = { + 0xD1, 0x2D, 0x8E, 0xBB, 0xB7, 0x36, 0xEA, 0x6D, 0x37, 0x91, 0x9F, 0x4E, + 0x93, 0xA7, 0x05, 0xE4, 0x29, 0x03, 0x25, 0xCE, 0x1C, 0x82, 0xF7, 0x7C, + 0x99, 0x9F, 0x41, 0x06, 0xCD, 0xED, 0xA3, 0xBA, 0xC0, 0xDB, 0x09, 0x2C, + 0xC1, 0x7C, 0xDF, 0x29, 0x7E, 0x4B, 0x65, 0x2F, 0x93, 0xA7, 0xD4, 0x01, + 0x6B, 0x03, 0x28, 0x18, 0xA3, 0xD8, 0x9D, 0x05, 0xC1, 0x2A, 0xD8, 0x45, + 0xF1, 0x91, 0xDE, 0xDF, 0x3B, 0xD0, 0x80, 0x02, 0x8C, 0xCF, 0x38, 0x0F, + 0xEA, 0xA7, 0x5C, 0x78, 0x11, 0xA4, 0xC1, 0xC8, 0x85, 0x5C, 0x25, 0xD3, + 0xD3, 0xB2, 0xE7, 0x25, 0xCF, 0x11, 0x54, 0x97, 0xAB, 0x35, 0xC0, 0x1E, + 0x76, 0x1C, 0xEF, 0x00, 0x53, 0x9F, 0x39, 0xDC, 0x14, 0xA5, 0x2C, 0x22, + 0x25, 0xB3, 0x72, 0x72, 0xFC, 0x8D, 0xB3, 0xE5, 0x3E, 0x08, 0x1E, 0x14, + 0x2A, 0x37, 0x0B, 0x88, 0x3C, 0xCA, 0xB0, 0xF4, 0xC8, 0xC2, 0xA1, 0xAE, + 0xBC, 0xC1, 0xBE, 0x29, 0x67, 0x55, 0xE2, 0xFC, 0xAD, 0x59, 0x5C, 0xFE, + 0xBD, 0x57, 0x2C, 0xB0, 0x90, 0x8D, 0xC2, 0xED, 0x37, 0xB6, 0x7C, 0x99, + 0x88, 0xB5, 0xD5, 0x03, 0x9A, 0x3D, 0x15, 0x0D, 0x3D, 0x3A, 0xA8, 0xA8, + 0x45, 0xF0, 0x95, 0x4E, 0x25, 0x59, 0x1D, 0xCD, 0x98, 0x69, 0xBB, 0xD3, + 0xCC, 0x32, 0xC9, 0x8D, 0xEF, 0x81, 0xFE, 0xAD, 0x7D, 0x89, 0xBB, 0xBA, + 0x60, 0x13, 0xCA, 0x65, 0x95, 0x67, 0xA0, 0xF3, 0x19, 0xF6, 0x03, 0x56, + 0xD4, 0x6A, 0xD3, 0x27, 0xE2, 0xA1, 0xAD, 0x83, 0xF0, 0x4A, 0x12, 0x22, + 0x77, 0x1C, 0x05, 0x73, 0xE2, 0x19, 0x71, 0x42, 0xC0, 0xEC, 0x75, 0x46, + 0x9A, 0x90, 0x58, 0xE0, 0x6A, 0x8E, 0x2B, 0xA5, 0x46, 0x30, 0x04, 0x8E, + 0x19, 0xB2, 0x17, 0xE3, 0xBE, 0xA9, 0xBA, 0x7F, 0x56, 0xF1, 0x24, 0x03, + 0xD7, 0xB2, 0x21, 0x28, 0x76, 0x0E, 0x36, 0x30, 0x4C, 0x79, 0xD5, 0x41, + 0x9A, 0x9A, 0xA8, 0xB8, 0x35, 0xBA, 0x0C, 0x3A, 0xF2, 0x44, 0x1B, 0x20, + 0x88, 0xF7, 0xC5, 0x25, 0xD7, 0x3D, 0xC6, 0xE3, 0x3E, 0x43, 0xDD, 0x87, + 0xFE, 0xC4, 0xEA, 0xF5, 0x53, 0x3E, 0x4C, 0x65, 0xFF, 0x3B, 0x4A, 0xCB, + 0x78, 0x5A, 0x6B, 0x17, 0x5F, 0x0D, 0xC7, 0xC3, 0x4F, 0x4E, 0x9A, 0x2A, + 0xA2, 0xED, 0x57, 0x4D, 0x22, 0xE2, 0x46, 0x9A, 0x3F, 0x0F, 0x91, 0x34, + 0x24, 0x7D, 0x55, 0xE3, 0x8C, 0x95, 0x37, 0xD3, 0x1A, 0xF0, 0x09, 0x2B, + 0x2C, 0xD2, 0xC9, 0x8D, 0xB4, 0x0D, 0x00, 0xAB, 0x67, 0x29, 0x28, 0xD8, + 0x01, 0xF5, 0x19, 0x04, 0xB6, 0x1D, 0xBE, 0x76, 0xFE, 0x72, 0x5C, 0xC4, + 0x85, 0xCA, 0xD2, 0x80, 0x41, 0xDF, 0x05, 0xA8, 0xA3, 0xD5, 0x84, 0x90, + 0x4F, 0x0B, 0xF3, 0xE0, 0x3F, 0x9B, 0x19, 0xD2, 0x37, 0x89, 0x3F, 0xF2, + 0x7B, 0x52, 0x1C, 0x8C, 0xF6, 0xE1, 0xF7, 0x3C, 0x07, 0x97, 0x8C, 0x0E, + 0xA2, 0x59, 0x81, 0x0C, 0xB2, 0x90, 0x3D, 0xD3, 0xE3, 0x59, 0x46, 0xED, + 0x0F, 0xA9, 0xA7, 0xDE, 0x80, 0x6B, 0x5A, 0xAA, 0x07, 0xB6, 0x19, 0xCB, + 0xBC, 0x57, 0xF3, 0x97, 0x21, 0x7A, 0x0C, 0xB1, 0x2B, 0x74, 0x3E, 0xEB, + 0xDA, 0xA7, 0x67, 0x2D, 0x4C, 0xC4, 0x98, 0x9E, 0x36, 0x09, 0x76, 0x66, + 0x66, 0xFC, 0x1A, 0x3F, 0xEA, 0x48, 0x54, 0x1C, 0xBE, 0x30, 0xBD, 0x80, + 0x50, 0xBF, 0x7C, 0xB5, 0xCE, 0x00, 0xF6, 0x0C, 0x61, 0xD9, 0xE7, 0x24, + 0x03, 0xE0, 0xE3, 0x01, 0x81, 0x0E, 0xBD, 0xD8, 0x85, 0x34, 0x88, 0xBD, + 0xB2, 0x36, 0xA8, 0x7B, 0x5C, 0x08, 0xE5, 0x44, 0x80, 0x8C, 0x6F, 0xF8, + 0x2F, 0xD5, 0x21, 0xCA, 0x1D, 0x1C, 0xD0, 0xFB, 0xC4, 0xB5, 0x87, 0xD1, + 0x3A, 0x4E, 0xC7, 0x76, 0xB5, 0x35, 0x48, 0xB5 +}; + +static const unsigned char TA561_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA562_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0E, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA562_RSA_N[] = { + 0xAB, 0xA4, 0x81, 0xE5, 0x95, 0xCD, 0xF5, 0xF6, 0x14, 0x8E, 0xC2, 0x4F, + 0xCA, 0xD4, 0xE2, 0x78, 0x95, 0x58, 0x9C, 0x41, 0xE1, 0x0D, 0x99, 0x40, + 0x24, 0x17, 0x39, 0x91, 0x33, 0x66, 0xE9, 0xBE, 0xE1, 0x83, 0xAF, 0x62, + 0x5C, 0x89, 0xD1, 0xFC, 0x24, 0x5B, 0x61, 0xB3, 0xE0, 0x11, 0x11, 0x41, + 0x1C, 0x1D, 0x6E, 0xF0, 0xB8, 0xBB, 0xF8, 0xDE, 0xA7, 0x81, 0xBA, 0xA6, + 0x48, 0xC6, 0x9F, 0x1D, 0xBD, 0xBE, 0x8E, 0xA9, 0x41, 0x3E, 0xB8, 0x94, + 0xED, 0x29, 0x1A, 0xD4, 0x8E, 0xD2, 0x03, 0x1D, 0x03, 0xEF, 0x6D, 0x0D, + 0x67, 0x1C, 0x57, 0xD7, 0x06, 0xAD, 0xCA, 0xC8, 0xF5, 0xFE, 0x0E, 0xAF, + 0x66, 0x25, 0x48, 0x04, 0x96, 0x0B, 0x5D, 0xA3, 0xBA, 0x16, 0xC3, 0x08, + 0x4F, 0xD1, 0x46, 0xF8, 0x14, 0x5C, 0xF2, 0xC8, 0x5E, 0x01, 0x99, 0x6D, + 0xFD, 0x88, 0xCC, 0x86, 0xA8, 0xC1, 0x6F, 0x31, 0x42, 0x6C, 0x52, 0x3E, + 0x68, 0xCB, 0xF3, 0x19, 0x34, 0xDF, 0xBB, 0x87, 0x18, 0x56, 0x80, 0x26, + 0xC4, 0xD0, 0xDC, 0xC0, 0x6F, 0xDF, 0xDE, 0xA0, 0xC2, 0x91, 0x16, 0xA0, + 0x64, 0x11, 0x4B, 0x44, 0xBC, 0x1E, 0xF6, 0xE7, 0xFA, 0x63, 0xDE, 0x66, + 0xAC, 0x76, 0xA4, 0x71, 0xA3, 0xEC, 0x36, 0x94, 0x68, 0x7A, 0x77, 0xA4, + 0xB1, 0xE7, 0x0E, 0x2F, 0x81, 0x7A, 0xE2, 0xB5, 0x72, 0x86, 0xEF, 0xA2, + 0x6B, 0x8B, 0xF0, 0x0F, 0xDB, 0xD3, 0x59, 0x3F, 0xBA, 0x72, 0xBC, 0x44, + 0x24, 0x9C, 0xE3, 0x73, 0xB3, 0xF7, 0xAF, 0x57, 0x2F, 0x42, 0x26, 0x9D, + 0xA9, 0x74, 0xBA, 0x00, 0x52, 0xF2, 0x4B, 0xCD, 0x53, 0x7C, 0x47, 0x0B, + 0x36, 0x85, 0x0E, 0x66, 0xA9, 0x08, 0x97, 0x16, 0x34, 0x57, 0xC1, 0x66, + 0xF7, 0x80, 0xE3, 0xED, 0x70, 0x54, 0xC7, 0x93, 0xE0, 0x2E, 0x28, 0x15, + 0x59, 0x87, 0xBA, 0xBB +}; + +static const unsigned char TA562_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA563_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x30, 0x30, 0x2E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x27, 0x43, 0x68, 0x69, 0x6E, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x61, + 0x6E, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0C, 0x43, 0x46, 0x43, 0x41, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA563_RSA_N[] = { + 0xD7, 0x5D, 0x6B, 0xCD, 0x10, 0x3F, 0x1F, 0x05, 0x59, 0xD5, 0x05, 0x4D, + 0x37, 0xB1, 0x0E, 0xEC, 0x98, 0x2B, 0x8E, 0x15, 0x1D, 0xFA, 0x93, 0x4B, + 0x17, 0x82, 0x21, 0x71, 0x10, 0x52, 0xD7, 0x51, 0x64, 0x70, 0x16, 0xC2, + 0x55, 0x69, 0x4D, 0x8E, 0x15, 0x6D, 0x9F, 0xBF, 0x0C, 0x1B, 0xC2, 0xE0, + 0xA3, 0x67, 0xD6, 0x0C, 0xAC, 0xCF, 0x22, 0xAE, 0xAF, 0x77, 0x54, 0x2A, + 0x4B, 0x4C, 0x8A, 0x53, 0x52, 0x7A, 0xC3, 0xEE, 0x2E, 0xDE, 0xB3, 0x71, + 0x25, 0xC1, 0xE9, 0x5D, 0x3D, 0xEE, 0xA1, 0x2F, 0xA3, 0xF7, 0x2A, 0x3C, + 0xC9, 0x23, 0x1D, 0x6A, 0xAB, 0x1D, 0xA1, 0xA7, 0xF1, 0xF3, 0xEC, 0xA0, + 0xD5, 0x44, 0xCF, 0x15, 0xCF, 0x72, 0x2F, 0x1D, 0x63, 0x97, 0xE8, 0x99, + 0xF9, 0xFD, 0x93, 0xA4, 0x54, 0x80, 0x4C, 0x52, 0xD4, 0x52, 0xAB, 0x2E, + 0x49, 0xDF, 0x90, 0xCD, 0xB8, 0x5F, 0xBE, 0x3F, 0xDE, 0xA1, 0xCA, 0x4D, + 0x20, 0xD4, 0x25, 0xE8, 0x84, 0x29, 0x53, 0xB7, 0xB1, 0x88, 0x1F, 0xFF, + 0xFA, 0xDA, 0x90, 0x9F, 0x0A, 0xA9, 0x2D, 0x41, 0x3F, 0xB1, 0xF1, 0x18, + 0x29, 0xEE, 0x16, 0x59, 0x2C, 0x34, 0x49, 0x1A, 0xA8, 0x06, 0xD7, 0xA8, + 0x88, 0xD2, 0x03, 0x72, 0x7A, 0x32, 0xE2, 0xEA, 0x68, 0x4D, 0x6E, 0x2C, + 0x96, 0x65, 0x7B, 0xCA, 0x59, 0xFA, 0xF2, 0xE2, 0xDD, 0xEE, 0x30, 0x2C, + 0xFB, 0xCC, 0x46, 0xAC, 0xC4, 0x63, 0xEB, 0x6F, 0x7F, 0x36, 0x2B, 0x34, + 0x73, 0x12, 0x94, 0x7F, 0xDF, 0xCC, 0x26, 0x9E, 0xF1, 0x72, 0x5D, 0x50, + 0x65, 0x59, 0x8F, 0x69, 0xB3, 0x87, 0x5E, 0x32, 0x6F, 0xC3, 0x18, 0x8A, + 0xB5, 0x95, 0x8F, 0xB0, 0x7A, 0x37, 0xDE, 0x5A, 0x45, 0x3B, 0xC7, 0x36, + 0xE1, 0xEF, 0x67, 0xD1, 0x39, 0xD3, 0x97, 0x5B, 0x73, 0x62, 0x19, 0x48, + 0x2D, 0x87, 0x1C, 0x06, 0xFB, 0x74, 0x98, 0x20, 0x49, 0x73, 0xF0, 0x05, + 0xD2, 0x1B, 0xB1, 0xA0, 0xA3, 0xB7, 0x1B, 0x70, 0xD3, 0x88, 0x69, 0xB9, + 0x5A, 0xD6, 0x38, 0xF4, 0x62, 0xDC, 0x25, 0x8B, 0x78, 0xBF, 0xF8, 0xE8, + 0x7E, 0xB8, 0x5C, 0xC9, 0x95, 0x4F, 0x5F, 0xA7, 0x2D, 0xB9, 0x20, 0x6B, + 0xCF, 0x6B, 0xDD, 0xF5, 0x0D, 0xF4, 0x82, 0xB7, 0xF4, 0xB2, 0x66, 0x2E, + 0x10, 0x28, 0xF6, 0x97, 0x5A, 0x7B, 0x96, 0x16, 0x8F, 0x01, 0x19, 0x2D, + 0x6C, 0x6E, 0x7F, 0x39, 0x58, 0x06, 0x64, 0x83, 0x01, 0x83, 0x83, 0xC3, + 0x4D, 0x92, 0xDD, 0x32, 0xC6, 0x87, 0xA4, 0x37, 0xE9, 0x16, 0xCE, 0xAA, + 0x2D, 0x68, 0xAF, 0x0A, 0x81, 0x65, 0x3A, 0x70, 0xC1, 0x9B, 0xAD, 0x4D, + 0x6D, 0x54, 0xCA, 0x2A, 0x2D, 0x4B, 0x85, 0x1B, 0xB3, 0x80, 0xE6, 0x70, + 0x45, 0x0D, 0x6B, 0x5E, 0x35, 0xF0, 0x7F, 0x3B, 0xB8, 0x9C, 0xE4, 0x04, + 0x70, 0x89, 0x12, 0x25, 0x93, 0xDA, 0x0A, 0x99, 0x22, 0x60, 0x6A, 0x63, + 0x60, 0x4E, 0x76, 0x06, 0x98, 0x4E, 0xBD, 0x83, 0xAD, 0x1D, 0x58, 0x8A, + 0x25, 0x85, 0xD2, 0xC7, 0x65, 0x1E, 0x2D, 0x8E, 0xC6, 0xDF, 0xB6, 0xC6, + 0xE1, 0x7F, 0x8A, 0x04, 0x21, 0x15, 0x29, 0x74, 0xF0, 0x3E, 0x9C, 0x90, + 0x9D, 0x0C, 0x2E, 0xF1, 0x8A, 0x3E, 0x5A, 0xAA, 0x0C, 0x09, 0x1E, 0xC7, + 0xD5, 0x3C, 0xA3, 0xED, 0x97, 0xC3, 0x1E, 0x34, 0xFA, 0x38, 0xF9, 0x08, + 0x0E, 0xE3, 0xC0, 0x5D, 0x2B, 0x83, 0xD1, 0x56, 0x6A, 0xC9, 0xB6, 0xA8, + 0x54, 0x53, 0x2E, 0x78, 0x32, 0x67, 0x3D, 0x82, 0x7F, 0x74, 0xD0, 0xFB, + 0xE1, 0xB6, 0x05, 0x60, 0xB9, 0x70, 0xDB, 0x8E, 0x0B, 0xF9, 0x13, 0x58, + 0x6F, 0x71, 0x60, 0x10, 0x52, 0x10, 0xB9, 0xC1, 0x41, 0x09, 0xEF, 0x72, + 0x1F, 0x67, 0x31, 0x78, 0xFF, 0x96, 0x05, 0x8D +}; + +static const unsigned char TA563_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA564_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA564_EC_Q[] = { + 0x04, 0x4B, 0x36, 0xE9, 0xAE, 0x57, 0x5E, 0xA8, 0x70, 0xD7, 0xD0, 0x8F, + 0x74, 0x62, 0x77, 0xC3, 0x5E, 0x7A, 0xAA, 0xE5, 0xB6, 0xA2, 0xF1, 0x78, + 0xFD, 0x02, 0x7E, 0x57, 0xDD, 0x91, 0x79, 0x9C, 0x6C, 0xB9, 0x52, 0x88, + 0x54, 0xBC, 0x2F, 0x04, 0xBE, 0xB8, 0xCD, 0xF6, 0x10, 0xD1, 0x29, 0xEC, + 0xB5, 0xD0, 0xA0, 0xC3, 0xF0, 0x89, 0x70, 0x19, 0xBB, 0x51, 0x65, 0xC5, + 0x43, 0x9C, 0xC3, 0x9B, 0x63, 0x9D, 0x20, 0x83, 0x3E, 0x06, 0x0B, 0xA6, + 0x42, 0x44, 0x85, 0x11, 0xA7, 0x4A, 0x3A, 0x2D, 0xE9, 0xD6, 0x68, 0x2F, + 0x48, 0x4E, 0x53, 0x2B, 0x07, 0x3F, 0x4D, 0xBD, 0xB9, 0xAC, 0x77, 0x39, + 0x57 +}; + +static const unsigned char TA565_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA565_EC_Q[] = { + 0x04, 0x78, 0x30, 0x81, 0xE8, 0x63, 0x1E, 0xE5, 0xEB, 0x71, 0x51, 0x0F, + 0xF7, 0x07, 0x07, 0xCA, 0x39, 0x99, 0x7C, 0x4E, 0xD5, 0x0F, 0xCC, 0x30, + 0x30, 0x0B, 0x8F, 0x66, 0x93, 0x3E, 0xCF, 0xBD, 0xC5, 0x86, 0xBD, 0xF9, + 0xB1, 0xB7, 0xB4, 0x3E, 0xB4, 0x07, 0xC8, 0xF3, 0x96, 0x31, 0xF3, 0xED, + 0xA4, 0x4F, 0xF8, 0xA3, 0x4E, 0x8D, 0x29, 0x15, 0x58, 0xB8, 0xD5, 0x6F, + 0x7F, 0xEE, 0x6C, 0x22, 0xB5, 0xB0, 0xAF, 0x48, 0x45, 0x0A, 0xBD, 0xA8, + 0x49, 0x94, 0xBF, 0x84, 0x43, 0xB0, 0xDB, 0x84, 0x4A, 0x03, 0x23, 0x19, + 0x67, 0x6A, 0x6F, 0xC1, 0x6E, 0xBC, 0x06, 0x39, 0x37, 0xD1, 0x88, 0x22, + 0xF7 +}; + +static const unsigned char TA566_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x31 +}; + +static const unsigned char TA566_RSA_N[] = { + 0xB0, 0x48, 0x65, 0xA3, 0x0D, 0x1D, 0x42, 0xE3, 0x91, 0x6D, 0x9D, 0x84, + 0xA4, 0x61, 0x96, 0x12, 0xC2, 0xED, 0xC3, 0xDA, 0x23, 0x34, 0x19, 0x76, + 0xF6, 0xEA, 0xFD, 0x55, 0x5A, 0xF6, 0x55, 0x01, 0x53, 0x0F, 0xF2, 0xCC, + 0x8C, 0x97, 0x4F, 0xB9, 0x50, 0xCB, 0xB3, 0x01, 0x44, 0x56, 0x96, 0xFD, + 0x9B, 0x28, 0xEC, 0x7B, 0x74, 0x0B, 0xE7, 0x42, 0x6B, 0x55, 0xCE, 0xC9, + 0x61, 0xB2, 0xE8, 0xAD, 0x40, 0x3C, 0xBA, 0xB9, 0x41, 0x0A, 0x05, 0x4F, + 0x1B, 0x26, 0x85, 0x8F, 0x43, 0xB5, 0x40, 0xB5, 0x85, 0xD1, 0xD4, 0x71, + 0xDC, 0x83, 0x41, 0xF3, 0xF6, 0x45, 0xC7, 0x80, 0xA2, 0x84, 0x50, 0x97, + 0x46, 0xCE, 0xA0, 0x0C, 0xC4, 0x60, 0x56, 0x04, 0x1D, 0x07, 0x5B, 0x46, + 0xA5, 0x0E, 0xB2, 0x4B, 0xA4, 0x0E, 0xA5, 0x7C, 0xEE, 0xF8, 0xD4, 0x62, + 0x03, 0xB9, 0x93, 0x6A, 0x8A, 0x14, 0xB8, 0x70, 0xF8, 0x2E, 0x82, 0x46, + 0x38, 0x23, 0x0E, 0x74, 0xC7, 0x6B, 0x41, 0xB7, 0xD0, 0x29, 0xA3, 0x9D, + 0x80, 0xB0, 0x7E, 0x77, 0x93, 0x63, 0x42, 0xFB, 0x34, 0x83, 0x3B, 0x73, + 0xA3, 0x5A, 0x21, 0x36, 0xEB, 0x47, 0xFA, 0x18, 0x17, 0xD9, 0xBA, 0x66, + 0xC2, 0x93, 0xA4, 0x8F, 0xFC, 0x5D, 0xA4, 0xAD, 0xFC, 0x50, 0x6A, 0x95, + 0xAC, 0xBC, 0x24, 0x33, 0xD1, 0xBD, 0x88, 0x7F, 0x86, 0xF5, 0xF5, 0xB2, + 0x73, 0x2A, 0x8F, 0x7C, 0xAF, 0x08, 0xF2, 0x1A, 0x98, 0x3F, 0xA9, 0x81, + 0x65, 0x3F, 0xC1, 0x8C, 0x89, 0xC5, 0x96, 0x30, 0x9A, 0x0A, 0xCF, 0xF4, + 0xD4, 0xC8, 0x34, 0xED, 0x9D, 0x2F, 0xBC, 0x8D, 0x38, 0x86, 0x53, 0xEE, + 0x97, 0x9F, 0xA9, 0xB2, 0x63, 0x94, 0x17, 0x8D, 0x0F, 0xDC, 0x66, 0x2A, + 0x7C, 0x52, 0x51, 0x75, 0xCB, 0x99, 0x8E, 0xE8, 0x3D, 0x5C, 0xBF, 0x9E, + 0x3B, 0x28, 0x8D, 0x83, 0x02, 0x0F, 0xA9, 0x9F, 0x72, 0xE2, 0x2C, 0x2B, + 0xB3, 0xDC, 0x66, 0x97, 0x00, 0x40, 0xD0, 0xA4, 0x54, 0x8E, 0x9B, 0x5D, + 0x7B, 0x45, 0x36, 0x26, 0xD6, 0x72, 0x43, 0xEB, 0xCF, 0xC0, 0xEA, 0x0D, + 0xDC, 0xCE, 0x12, 0xE6, 0x7D, 0x38, 0x9F, 0x05, 0x27, 0xA8, 0x97, 0x3E, + 0xE9, 0x51, 0xC6, 0x6C, 0x05, 0x28, 0xC1, 0x02, 0x0F, 0xE9, 0x18, 0x6D, + 0xEC, 0xBD, 0x9C, 0x06, 0xD4, 0xA7, 0x49, 0xF4, 0x54, 0x05, 0x6B, 0x6C, + 0x30, 0xF1, 0xEB, 0x03, 0xD5, 0xEA, 0x3D, 0x6A, 0x76, 0xC2, 0xCB, 0x1A, + 0x28, 0x49, 0x4D, 0x7F, 0x64, 0xE0, 0xFA, 0x2B, 0xDA, 0x73, 0x83, 0x81, + 0xFF, 0x91, 0x03, 0xBD, 0x94, 0xBB, 0xE4, 0xB8, 0x8E, 0x9C, 0x32, 0x63, + 0xCD, 0x9F, 0xBB, 0x68, 0x81, 0xB1, 0x84, 0x5B, 0xAF, 0x36, 0xBF, 0x77, + 0xEE, 0x1D, 0x7F, 0xF7, 0x49, 0x9B, 0x52, 0xEC, 0xD2, 0x77, 0x5A, 0x7D, + 0x91, 0x9D, 0x4D, 0xC2, 0x39, 0x2D, 0xE4, 0xBA, 0x82, 0xF8, 0x6F, 0xF2, + 0x4E, 0x1E, 0x0F, 0x4E, 0xE6, 0x3F, 0x59, 0xA5, 0x23, 0xDC, 0x3D, 0x87, + 0xA8, 0x28, 0x58, 0x28, 0xD1, 0xF1, 0x1B, 0x36, 0xDB, 0x4F, 0xC4, 0xFF, + 0xE1, 0x8C, 0x5B, 0x72, 0x8C, 0xC7, 0x26, 0x03, 0x27, 0xA3, 0x39, 0x0A, + 0x01, 0xAA, 0xC0, 0xB2, 0x31, 0x60, 0x83, 0x22, 0xA1, 0x4F, 0x12, 0x09, + 0x01, 0x11, 0xAF, 0x34, 0xD4, 0xCF, 0xD7, 0xAE, 0x62, 0xD3, 0x05, 0x07, + 0xB4, 0x31, 0x75, 0xE0, 0x0D, 0x6D, 0x57, 0x4F, 0x69, 0x87, 0xF9, 0x57, + 0xA9, 0xBA, 0x15, 0xF6, 0xC8, 0x52, 0x6D, 0xA1, 0xCB, 0x9C, 0x1F, 0xE5, + 0xFC, 0x78, 0xA8, 0x35, 0x9A, 0x9F, 0x41, 0x14, 0xCE, 0xA5, 0xB4, 0xCE, + 0x94, 0x08, 0x1C, 0x09, 0xAD, 0x56, 0xE5, 0xDA, 0xB6, 0x49, 0x9A, 0x4A, + 0xEA, 0x63, 0x18, 0x53, 0x9C, 0x2C, 0x2E, 0xC3 +}; + +static const unsigned char TA566_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA567_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA567_RSA_N[] = { + 0xE1, 0xFA, 0x0E, 0xFB, 0x68, 0x00, 0x12, 0xC8, 0x4D, 0xD5, 0xAC, 0x22, + 0xC4, 0x35, 0x01, 0x3B, 0xC5, 0x54, 0xE5, 0x59, 0x76, 0x63, 0xA5, 0x7F, + 0xEB, 0xC1, 0xC4, 0x6A, 0x98, 0xBD, 0x32, 0x8D, 0x17, 0x80, 0xEB, 0x5D, + 0xBA, 0xD1, 0x62, 0x3D, 0x25, 0x23, 0x19, 0x35, 0x14, 0xE9, 0x7F, 0x89, + 0xA7, 0x1B, 0x62, 0x3C, 0xD6, 0x50, 0xE7, 0x34, 0x95, 0x03, 0x32, 0xB1, + 0xB4, 0x93, 0x22, 0x3D, 0xA7, 0xE2, 0xB1, 0xED, 0xE6, 0x7B, 0x4E, 0x2E, + 0x87, 0x9B, 0x0D, 0x33, 0x75, 0x0A, 0xDE, 0xAA, 0x35, 0xE7, 0x7E, 0xE5, + 0x36, 0x98, 0xA2, 0xAE, 0x25, 0x9E, 0x95, 0xB3, 0x32, 0x96, 0xA4, 0x2B, + 0x58, 0x1E, 0xEF, 0x3F, 0xFE, 0x62, 0x34, 0x48, 0x51, 0xD1, 0xB4, 0x8D, + 0x42, 0xAD, 0x60, 0xDA, 0x49, 0x6A, 0x95, 0x70, 0xDD, 0xD2, 0x00, 0xE2, + 0xCC, 0x57, 0x63, 0x02, 0x7B, 0x96, 0xDD, 0x49, 0x97, 0x5B, 0x92, 0x4E, + 0x95, 0xD3, 0xF9, 0xCB, 0x29, 0x1F, 0x18, 0x4A, 0xF8, 0x01, 0x2A, 0xD2, + 0x63, 0x09, 0x6E, 0x24, 0xE9, 0x89, 0xD2, 0xE5, 0xC7, 0x22, 0x4C, 0xDC, + 0x73, 0x86, 0x47, 0x00, 0xAA, 0x0D, 0x88, 0x8E, 0xAE, 0x85, 0x7D, 0x4A, + 0xE9, 0xBB, 0x33, 0x4F, 0x0E, 0x52, 0x70, 0x9D, 0x95, 0xE3, 0x7C, 0x6D, + 0x96, 0x5B, 0x2D, 0x3D, 0x5F, 0xA1, 0x83, 0x46, 0x5D, 0xB6, 0xE3, 0x25, + 0xB8, 0x7C, 0xA7, 0x19, 0x80, 0x1C, 0xEA, 0x65, 0x43, 0xDC, 0x91, 0x79, + 0x36, 0x2C, 0x74, 0x7C, 0xF2, 0x67, 0x06, 0xC9, 0x89, 0xC9, 0xDB, 0xBF, + 0xDA, 0x68, 0xBF, 0x23, 0xED, 0xDC, 0x6B, 0xAD, 0x28, 0x83, 0x79, 0x2F, + 0xEC, 0x38, 0xA5, 0x0D, 0x37, 0x01, 0x67, 0x27, 0x9A, 0xE9, 0x33, 0xD9, + 0x33, 0x5F, 0x37, 0xA1, 0xC5, 0xF0, 0xAB, 0x3D, 0xFA, 0x78, 0xB0, 0xE7, + 0x2C, 0x9F, 0xF6, 0x3E, 0x9F, 0x60, 0xE0, 0xEF, 0x48, 0xE9, 0x90, 0x45, + 0x1E, 0x05, 0x51, 0x78, 0x1A, 0x2C, 0x12, 0x2C, 0x5C, 0x28, 0xAC, 0x0D, + 0xA2, 0x23, 0x9E, 0x34, 0x8F, 0x05, 0xE6, 0xA2, 0x33, 0xCE, 0x11, 0x77, + 0x13, 0xD4, 0x0E, 0xA4, 0x1E, 0x42, 0x1F, 0x86, 0xCD, 0x70, 0xFE, 0xD9, + 0x2E, 0x15, 0x3D, 0x1D, 0xBB, 0xB8, 0xF2, 0x53, 0x57, 0xDB, 0xCC, 0xC6, + 0x74, 0x29, 0x9C, 0x18, 0xB3, 0x36, 0x75, 0x38, 0x2E, 0x0F, 0x54, 0xA1, + 0xF8, 0x92, 0x1F, 0x89, 0x96, 0x4F, 0xBB, 0xD4, 0xEE, 0x9D, 0xE9, 0x3B, + 0x36, 0x42, 0xB5, 0x0A, 0x3B, 0x2A, 0xD4, 0x64, 0x79, 0x36, 0x10, 0xE1, + 0xF9, 0x91, 0x03, 0x2B, 0x7B, 0x20, 0x54, 0xCD, 0x0D, 0x19, 0x1A, 0xC8, + 0x41, 0x32, 0x34, 0xD1, 0xB0, 0x99, 0xE1, 0x90, 0x1E, 0x01, 0x40, 0x36, + 0xB5, 0xB7, 0xFA, 0xA9, 0xE5, 0x77, 0x75, 0xA4, 0x22, 0x81, 0x5D, 0xB0, + 0x8B, 0xE4, 0x27, 0x12, 0x0F, 0x54, 0x88, 0xC6, 0xDB, 0x85, 0x74, 0xE6, + 0xB7, 0xC0, 0xD7, 0xA6, 0x29, 0xFA, 0xDB, 0xDE, 0xF3, 0x93, 0x97, 0x27, + 0x04, 0x55, 0x2F, 0x0A, 0x6F, 0x37, 0xC5, 0x3D, 0x13, 0xAF, 0x0A, 0x00, + 0xA9, 0x2C, 0x8B, 0x1C, 0x81, 0x28, 0xD7, 0xEF, 0x86, 0x31, 0xA9, 0xAE, + 0xF2, 0x6E, 0xB8, 0xCA, 0x6A, 0x2C, 0x54, 0x47, 0xD8, 0x2A, 0x88, 0x2E, + 0xAF, 0xC1, 0x07, 0x10, 0x78, 0xAC, 0x11, 0xA2, 0x2F, 0x42, 0xF0, 0x37, + 0xC5, 0xF2, 0xB8, 0x56, 0xDD, 0x0E, 0x62, 0x2D, 0xCE, 0x2D, 0x56, 0x7E, + 0x55, 0xF2, 0xA7, 0x44, 0xF6, 0x2B, 0x32, 0xF4, 0x23, 0xA8, 0x47, 0xE8, + 0xD4, 0x2A, 0x01, 0x78, 0xCF, 0x6A, 0xC3, 0x37, 0xA8, 0x9E, 0x65, 0xD2, + 0x2C, 0xE5, 0xFA, 0xBA, 0x33, 0xC1, 0x06, 0x44, 0xF6, 0xE6, 0xCF, 0xA5, + 0x0D, 0xA7, 0x66, 0x08, 0x34, 0x8A, 0x2C, 0xF3 +}; + +static const unsigned char TA567_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA568_DN[] = { + 0x30, 0x7B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, 0x61, + 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x53, 0x61, 0x6C, 0x66, 0x6F, + 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x11, 0x43, 0x6F, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x43, 0x41, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x18, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73 +}; + +static const unsigned char TA568_RSA_N[] = { + 0xBE, 0x40, 0x9D, 0xF4, 0x6E, 0xE1, 0xEA, 0x76, 0x87, 0x1C, 0x4D, 0x45, + 0x44, 0x8E, 0xBE, 0x46, 0xC8, 0x83, 0x06, 0x9D, 0xC1, 0x2A, 0xFE, 0x18, + 0x1F, 0x8E, 0xE4, 0x02, 0xFA, 0xF3, 0xAB, 0x5D, 0x50, 0x8A, 0x16, 0x31, + 0x0B, 0x9A, 0x06, 0xD0, 0xC5, 0x70, 0x22, 0xCD, 0x49, 0x2D, 0x54, 0x63, + 0xCC, 0xB6, 0x6E, 0x68, 0x46, 0x0B, 0x53, 0xEA, 0xCB, 0x4C, 0x24, 0xC0, + 0xBC, 0x72, 0x4E, 0xEA, 0xF1, 0x15, 0xAE, 0xF4, 0x54, 0x9A, 0x12, 0x0A, + 0xC3, 0x7A, 0xB2, 0x33, 0x60, 0xE2, 0xDA, 0x89, 0x55, 0xF3, 0x22, 0x58, + 0xF3, 0xDE, 0xDC, 0xCF, 0xEF, 0x83, 0x86, 0xA2, 0x8C, 0x94, 0x4F, 0x9F, + 0x68, 0xF2, 0x98, 0x90, 0x46, 0x84, 0x27, 0xC7, 0x76, 0xBF, 0xE3, 0xCC, + 0x35, 0x2C, 0x8B, 0x5E, 0x07, 0x64, 0x65, 0x82, 0xC0, 0x48, 0xB0, 0xA8, + 0x91, 0xF9, 0x61, 0x9F, 0x76, 0x20, 0x50, 0xA8, 0x91, 0xC7, 0x66, 0xB5, + 0xEB, 0x78, 0x62, 0x03, 0x56, 0xF0, 0x8A, 0x1A, 0x13, 0xEA, 0x31, 0xA3, + 0x1E, 0xA0, 0x99, 0xFD, 0x38, 0xF6, 0xF6, 0x27, 0x32, 0x58, 0x6F, 0x07, + 0xF5, 0x6B, 0xB8, 0xFB, 0x14, 0x2B, 0xAF, 0xB7, 0xAA, 0xCC, 0xD6, 0x63, + 0x5F, 0x73, 0x8C, 0xDA, 0x05, 0x99, 0xA8, 0x38, 0xA8, 0xCB, 0x17, 0x78, + 0x36, 0x51, 0xAC, 0xE9, 0x9E, 0xF4, 0x78, 0x3A, 0x8D, 0xCF, 0x0F, 0xD9, + 0x42, 0xE2, 0x98, 0x0C, 0xAB, 0x2F, 0x9F, 0x0E, 0x01, 0xDE, 0xEF, 0x9F, + 0x99, 0x49, 0xF1, 0x2D, 0xDF, 0xAC, 0x74, 0x4D, 0x1B, 0x98, 0xB5, 0x47, + 0xC5, 0xE5, 0x29, 0xD1, 0xF9, 0x90, 0x18, 0xC7, 0x62, 0x9C, 0xBE, 0x83, + 0xC7, 0x26, 0x7B, 0x3E, 0x8A, 0x25, 0xC7, 0xC0, 0xDD, 0x9D, 0xE6, 0x35, + 0x68, 0x10, 0x20, 0x9D, 0x8F, 0xD8, 0xDE, 0xD2, 0xC3, 0x84, 0x9C, 0x0D, + 0x5E, 0xE8, 0x2F, 0xC9 +}; + +static const unsigned char TA568_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA569_DN[] = { + 0x30, 0x81, 0x81, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA569_RSA_N[] = { + 0xD0, 0x40, 0x8B, 0x8B, 0x72, 0xE3, 0x91, 0x1B, 0xF7, 0x51, 0xC1, 0x1B, + 0x54, 0x04, 0x98, 0xD3, 0xA9, 0xBF, 0xC1, 0xE6, 0x8A, 0x5D, 0x3B, 0x87, + 0xFB, 0xBB, 0x88, 0xCE, 0x0D, 0xE3, 0x2F, 0x3F, 0x06, 0x96, 0xF0, 0xA2, + 0x29, 0x50, 0x99, 0xAE, 0xDB, 0x3B, 0xA1, 0x57, 0xB0, 0x74, 0x51, 0x71, + 0xCD, 0xED, 0x42, 0x91, 0x4D, 0x41, 0xFE, 0xA9, 0xC8, 0xD8, 0x6A, 0x86, + 0x77, 0x44, 0xBB, 0x59, 0x66, 0x97, 0x50, 0x5E, 0xB4, 0xD4, 0x2C, 0x70, + 0x44, 0xCF, 0xDA, 0x37, 0x95, 0x42, 0x69, 0x3C, 0x30, 0xC4, 0x71, 0xB3, + 0x52, 0xF0, 0x21, 0x4D, 0xA1, 0xD8, 0xBA, 0x39, 0x7C, 0x1C, 0x9E, 0xA3, + 0x24, 0x9D, 0xF2, 0x83, 0x16, 0x98, 0xAA, 0x16, 0x7C, 0x43, 0x9B, 0x15, + 0x5B, 0xB7, 0xAE, 0x34, 0x91, 0xFE, 0xD4, 0x62, 0x26, 0x18, 0x46, 0x9A, + 0x3F, 0xEB, 0xC1, 0xF9, 0xF1, 0x90, 0x57, 0xEB, 0xAC, 0x7A, 0x0D, 0x8B, + 0xDB, 0x72, 0x30, 0x6A, 0x66, 0xD5, 0xE0, 0x46, 0xA3, 0x70, 0xDC, 0x68, + 0xD9, 0xFF, 0x04, 0x48, 0x89, 0x77, 0xDE, 0xB5, 0xE9, 0xFB, 0x67, 0x6D, + 0x41, 0xE9, 0xBC, 0x39, 0xBD, 0x32, 0xD9, 0x62, 0x02, 0xF1, 0xB1, 0xA8, + 0x3D, 0x6E, 0x37, 0x9C, 0xE2, 0x2F, 0xE2, 0xD3, 0xA2, 0x26, 0x8B, 0xC6, + 0xB8, 0x55, 0x43, 0x88, 0xE1, 0x23, 0x3E, 0xA5, 0xD2, 0x24, 0x39, 0x6A, + 0x47, 0xAB, 0x00, 0xD4, 0xA1, 0xB3, 0xA9, 0x25, 0xFE, 0x0D, 0x3F, 0xA7, + 0x1D, 0xBA, 0xD3, 0x51, 0xC1, 0x0B, 0xA4, 0xDA, 0xAC, 0x38, 0xEF, 0x55, + 0x50, 0x24, 0x05, 0x65, 0x46, 0x93, 0x34, 0x4F, 0x2D, 0x8D, 0xAD, 0xC6, + 0xD4, 0x21, 0x19, 0xD2, 0x8E, 0xCA, 0x05, 0x61, 0x71, 0x07, 0x73, 0x47, + 0xE5, 0x8A, 0x19, 0x12, 0xBD, 0x04, 0x4D, 0xCE, 0x4E, 0x9C, 0xA5, 0x48, + 0xAC, 0xBB, 0x26, 0xF7 +}; + +static const unsigned char TA569_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA570_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA570_EC_Q[] = { + 0x04, 0x03, 0x47, 0x7B, 0x2F, 0x75, 0xC9, 0x82, 0x15, 0x85, 0xFB, 0x75, + 0xE4, 0x91, 0x16, 0xD4, 0xAB, 0x62, 0x99, 0xF5, 0x3E, 0x52, 0x0B, 0x06, + 0xCE, 0x41, 0x00, 0x7F, 0x97, 0xE1, 0x0A, 0x24, 0x3C, 0x1D, 0x01, 0x04, + 0xEE, 0x3D, 0xD2, 0x8D, 0x09, 0x97, 0x0C, 0xE0, 0x75, 0xE4, 0xFA, 0xFB, + 0x77, 0x8A, 0x2A, 0xF5, 0x03, 0x60, 0x4B, 0x36, 0x8B, 0x16, 0x23, 0x16, + 0xAD, 0x09, 0x71, 0xF4, 0x4A, 0xF4, 0x28, 0x50, 0xB4, 0xFE, 0x88, 0x1C, + 0x6E, 0x3F, 0x6C, 0x2F, 0x2F, 0x09, 0x59, 0x5B, 0xA5, 0x5B, 0x0B, 0x33, + 0x99, 0xE2, 0xC3, 0x3D, 0x89, 0xF9, 0x6A, 0x2C, 0xEF, 0xB2, 0xD3, 0x06, + 0xE9 +}; + +static const unsigned char TA571_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA571_RSA_N[] = { + 0x91, 0xE8, 0x54, 0x92, 0xD2, 0x0A, 0x56, 0xB1, 0xAC, 0x0D, 0x24, 0xDD, + 0xC5, 0xCF, 0x44, 0x67, 0x74, 0x99, 0x2B, 0x37, 0xA3, 0x7D, 0x23, 0x70, + 0x00, 0x71, 0xBC, 0x53, 0xDF, 0xC4, 0xFA, 0x2A, 0x12, 0x8F, 0x4B, 0x7F, + 0x10, 0x56, 0xBD, 0x9F, 0x70, 0x72, 0xB7, 0x61, 0x7F, 0xC9, 0x4B, 0x0F, + 0x17, 0xA7, 0x3D, 0xE3, 0xB0, 0x04, 0x61, 0xEE, 0xFF, 0x11, 0x97, 0xC7, + 0xF4, 0x86, 0x3E, 0x0A, 0xFA, 0x3E, 0x5C, 0xF9, 0x93, 0xE6, 0x34, 0x7A, + 0xD9, 0x14, 0x6B, 0xE7, 0x9C, 0xB3, 0x85, 0xA0, 0x82, 0x7A, 0x76, 0xAF, + 0x71, 0x90, 0xD7, 0xEC, 0xFD, 0x0D, 0xFA, 0x9C, 0x6C, 0xFA, 0xDF, 0xB0, + 0x82, 0xF4, 0x14, 0x7E, 0xF9, 0xBE, 0xC4, 0xA6, 0x2F, 0x4F, 0x7F, 0x99, + 0x7F, 0xB5, 0xFC, 0x67, 0x43, 0x72, 0xBD, 0x0C, 0x00, 0xD6, 0x89, 0xEB, + 0x6B, 0x2C, 0xD3, 0xED, 0x8F, 0x98, 0x1C, 0x14, 0xAB, 0x7E, 0xE5, 0xE3, + 0x6E, 0xFC, 0xD8, 0xA8, 0xE4, 0x92, 0x24, 0xDA, 0x43, 0x6B, 0x62, 0xB8, + 0x55, 0xFD, 0xEA, 0xC1, 0xBC, 0x6C, 0xB6, 0x8B, 0xF3, 0x0E, 0x8D, 0x9A, + 0xE4, 0x9B, 0x6C, 0x69, 0x99, 0xF8, 0x78, 0x48, 0x30, 0x45, 0xD5, 0xAD, + 0xE1, 0x0D, 0x3C, 0x45, 0x60, 0xFC, 0x32, 0x96, 0x51, 0x27, 0xBC, 0x67, + 0xC3, 0xCA, 0x2E, 0xB6, 0x6B, 0xEA, 0x46, 0xC7, 0xC7, 0x20, 0xA0, 0xB1, + 0x1F, 0x65, 0xDE, 0x48, 0x08, 0xBA, 0xA4, 0x4E, 0xA9, 0xF2, 0x83, 0x46, + 0x37, 0x84, 0xEB, 0xE8, 0xCC, 0x81, 0x48, 0x43, 0x67, 0x4E, 0x72, 0x2A, + 0x9B, 0x5C, 0xBD, 0x4C, 0x1B, 0x28, 0x8A, 0x5C, 0x22, 0x7B, 0xB4, 0xAB, + 0x98, 0xD9, 0xEE, 0xE0, 0x51, 0x83, 0xC3, 0x09, 0x46, 0x4E, 0x6D, 0x3E, + 0x99, 0xFA, 0x95, 0x17, 0xDA, 0x7C, 0x33, 0x57, 0x41, 0x3C, 0x8D, 0x51, + 0xED, 0x0B, 0xB6, 0x5C, 0xAF, 0x2C, 0x63, 0x1A, 0xDF, 0x57, 0xC8, 0x3F, + 0xBC, 0xE9, 0x5D, 0xC4, 0x9B, 0xAF, 0x45, 0x99, 0xE2, 0xA3, 0x5A, 0x24, + 0xB4, 0xBA, 0xA9, 0x56, 0x3D, 0xCF, 0x6F, 0xAA, 0xFF, 0x49, 0x58, 0xBE, + 0xF0, 0xA8, 0xFF, 0xF4, 0xB8, 0xAD, 0xE9, 0x37, 0xFB, 0xBA, 0xB8, 0xF4, + 0x0B, 0x3A, 0xF9, 0xE8, 0x43, 0x42, 0x1E, 0x89, 0xD8, 0x84, 0xCB, 0x13, + 0xF1, 0xD9, 0xBB, 0xE1, 0x89, 0x60, 0xB8, 0x8C, 0x28, 0x56, 0xAC, 0x14, + 0x1D, 0x9C, 0x0A, 0xE7, 0x71, 0xEB, 0xCF, 0x0E, 0xDD, 0x3D, 0xA9, 0x96, + 0xA1, 0x48, 0xBD, 0x3C, 0xF7, 0xAF, 0xB5, 0x0D, 0x22, 0x4C, 0xC0, 0x11, + 0x81, 0xEC, 0x56, 0x3B, 0xF6, 0xD3, 0xA2, 0xE2, 0x5B, 0xB7, 0xB2, 0x04, + 0x22, 0x52, 0x95, 0x80, 0x93, 0x69, 0xE8, 0x8E, 0x4C, 0x65, 0xF1, 0x91, + 0x03, 0x2D, 0x70, 0x74, 0x02, 0xEA, 0x8B, 0x67, 0x15, 0x29, 0x69, 0x52, + 0x02, 0xBB, 0xD7, 0xDF, 0x50, 0x6A, 0x55, 0x46, 0xBF, 0xA0, 0xA3, 0x28, + 0x61, 0x7F, 0x70, 0xD0, 0xC3, 0xA2, 0xAA, 0x2C, 0x21, 0xAA, 0x47, 0xCE, + 0x28, 0x9C, 0x06, 0x45, 0x76, 0xBF, 0x82, 0x18, 0x27, 0xB4, 0xD5, 0xAE, + 0xB4, 0xCB, 0x50, 0xE6, 0x6B, 0xF4, 0x4C, 0x86, 0x71, 0x30, 0xE9, 0xA6, + 0xDF, 0x16, 0x86, 0xE0, 0xD8, 0xFF, 0x40, 0xDD, 0xFB, 0xD0, 0x42, 0x88, + 0x7F, 0xA3, 0x33, 0x3A, 0x2E, 0x5C, 0x1E, 0x41, 0x11, 0x81, 0x63, 0xCE, + 0x18, 0x71, 0x6B, 0x2B, 0xEC, 0xA6, 0x8A, 0xB7, 0x31, 0x5C, 0x3A, 0x6A, + 0x47, 0xE0, 0xC3, 0x79, 0x59, 0xD6, 0x20, 0x1A, 0xAF, 0xF2, 0x6A, 0x98, + 0xAA, 0x72, 0xBC, 0x57, 0x4A, 0xD2, 0x4B, 0x9D, 0xBB, 0x10, 0xFC, 0xB0, + 0x4C, 0x41, 0xE5, 0xED, 0x1D, 0x3D, 0x5E, 0x28, 0x9D, 0x9C, 0xCC, 0xBF, + 0xB3, 0x51, 0xDA, 0xA7, 0x47, 0xE5, 0x84, 0x53 +}; + +static const unsigned char TA571_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA572_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x32 +}; + +static const unsigned char TA572_RSA_N[] = { + 0xAA, 0x5F, 0xDA, 0x1B, 0x5F, 0xE8, 0x73, 0x91, 0xE5, 0xDA, 0x5C, 0xF4, + 0xA2, 0xE6, 0x47, 0xE5, 0xF3, 0x68, 0x55, 0x60, 0x05, 0x1D, 0x02, 0xA4, + 0xB3, 0x9B, 0x59, 0xF3, 0x1E, 0x8A, 0xAF, 0x34, 0xAD, 0xFC, 0x0D, 0xC2, + 0xD9, 0x48, 0x19, 0xEE, 0x69, 0x8F, 0xC9, 0x20, 0xFC, 0x21, 0xAA, 0x07, + 0x19, 0xED, 0xB0, 0x5C, 0xAC, 0x65, 0xC7, 0x5F, 0xED, 0x02, 0x7C, 0x7B, + 0x7C, 0x2D, 0x1B, 0xD6, 0xBA, 0xB9, 0x80, 0xC2, 0x18, 0x82, 0x16, 0x84, + 0xFA, 0x66, 0xB0, 0x08, 0xC6, 0x54, 0x23, 0x81, 0xE4, 0xCD, 0xB9, 0x49, + 0x3F, 0xF6, 0x4F, 0x6E, 0x37, 0x48, 0x28, 0x38, 0x0F, 0xC5, 0xBE, 0xE7, + 0x68, 0x70, 0xFD, 0x39, 0x97, 0x4D, 0xD2, 0xC7, 0x98, 0x91, 0x50, 0xAA, + 0xC4, 0x44, 0xB3, 0x23, 0x7D, 0x39, 0x47, 0xE9, 0x52, 0x62, 0xD6, 0x12, + 0x93, 0x5E, 0xB7, 0x31, 0x96, 0x42, 0x05, 0xFB, 0x76, 0xA7, 0x1E, 0xA3, + 0xF5, 0xC2, 0xFC, 0xE9, 0x7A, 0xC5, 0x6C, 0xA9, 0x71, 0x4F, 0xEA, 0xCB, + 0x78, 0xBC, 0x60, 0xAF, 0xC7, 0xDE, 0xF4, 0xD9, 0xCB, 0xBE, 0x7E, 0x33, + 0xA5, 0x6E, 0x94, 0x83, 0xF0, 0x34, 0xFA, 0x21, 0xAB, 0xEA, 0x8E, 0x72, + 0xA0, 0x3F, 0xA4, 0xDE, 0x30, 0x5B, 0xEF, 0x86, 0x4D, 0x6A, 0x95, 0x5B, + 0x43, 0x44, 0xA8, 0x10, 0x15, 0x1C, 0xE5, 0x01, 0x57, 0xC5, 0x98, 0xF1, + 0xE6, 0x06, 0x28, 0x91, 0xAA, 0x20, 0xC5, 0xB7, 0x53, 0x26, 0x51, 0x43, + 0xB2, 0x0B, 0x11, 0x95, 0x58, 0xE1, 0xC0, 0x0F, 0x76, 0xD9, 0xC0, 0x8D, + 0x7C, 0x81, 0xF3, 0x72, 0x70, 0x9E, 0x6F, 0xFE, 0x1A, 0x8E, 0xD9, 0x5F, + 0x35, 0xC6, 0xB2, 0x6F, 0x34, 0x7C, 0xBE, 0x48, 0x4F, 0xE2, 0x5A, 0x39, + 0xD7, 0xD8, 0x9D, 0x78, 0x9E, 0x9F, 0x86, 0x3E, 0x03, 0x5E, 0x19, 0x8B, + 0x44, 0xA2, 0xD5, 0xC7 +}; + +static const unsigned char TA572_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA573_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x39, 0x41, 0x75, 0x74, 0x6F, 0x72, 0x69, 0x64, 0x61, 0x64, 0x20, + 0x64, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x63, 0x69, 0x6F, 0x6E, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, + 0x6F, 0x66, 0x65, 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x43, 0x49, + 0x46, 0x20, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38 +}; + +static const unsigned char TA573_RSA_N[] = { + 0xCA, 0x96, 0x6B, 0x8E, 0xEA, 0xF8, 0xFB, 0xF1, 0xA2, 0x35, 0xE0, 0x7F, + 0x4C, 0xDA, 0xE0, 0xC3, 0x52, 0xD7, 0x7D, 0xB6, 0x10, 0xC8, 0x02, 0x5E, + 0xB3, 0x43, 0x2A, 0xC4, 0x4F, 0x6A, 0xB2, 0xCA, 0x1C, 0x5D, 0x28, 0x9A, + 0x78, 0x11, 0x1A, 0x69, 0x59, 0x57, 0xAF, 0xB5, 0x20, 0x42, 0xE4, 0x8B, + 0x0F, 0xE6, 0xDF, 0x5B, 0xA6, 0x03, 0x92, 0x2F, 0xF5, 0x11, 0xE4, 0x62, + 0xD7, 0x32, 0x71, 0x38, 0xD9, 0x04, 0x0C, 0x71, 0xAB, 0x3D, 0x51, 0x7E, + 0x0F, 0x07, 0xDF, 0x63, 0x05, 0x5C, 0xE9, 0xBF, 0x94, 0x6F, 0xC1, 0x29, + 0x82, 0xC0, 0xB4, 0xDA, 0x51, 0xB0, 0xC1, 0x3C, 0xBB, 0xAD, 0x37, 0x4A, + 0x5C, 0xCA, 0xF1, 0x4B, 0x36, 0x0E, 0x24, 0xAB, 0xBF, 0xC3, 0x84, 0x77, + 0xFD, 0xA8, 0x50, 0xF4, 0xB1, 0xE7, 0xC6, 0x2F, 0xD2, 0x2D, 0x59, 0x8D, + 0x7A, 0x0A, 0x4E, 0x96, 0x69, 0x52, 0x02, 0xAA, 0x36, 0x98, 0xEC, 0xFC, + 0xFA, 0x14, 0x83, 0x0C, 0x37, 0x1F, 0xC9, 0x92, 0x37, 0x7F, 0xD7, 0x81, + 0x2D, 0xE5, 0xC4, 0xB9, 0xE0, 0x3E, 0x34, 0xFE, 0x67, 0xF4, 0x3E, 0x66, + 0xD1, 0xD3, 0xF4, 0x40, 0xCF, 0x5E, 0x62, 0x34, 0x0F, 0x70, 0x06, 0x3E, + 0x20, 0x18, 0x5A, 0xCE, 0xF7, 0x72, 0x1B, 0x25, 0x6C, 0x93, 0x74, 0x14, + 0x93, 0xA3, 0x73, 0xB1, 0x0E, 0xAA, 0x87, 0x10, 0x23, 0x59, 0x5F, 0x20, + 0x05, 0x19, 0x47, 0xED, 0x68, 0x8E, 0x92, 0x12, 0xCA, 0x5D, 0xFC, 0xD6, + 0x2B, 0xB2, 0x92, 0x3C, 0x20, 0xCF, 0xE1, 0x5F, 0xAF, 0x20, 0xBE, 0xA0, + 0x76, 0x7F, 0x76, 0xE5, 0xEC, 0x1A, 0x86, 0x61, 0x33, 0x3E, 0xE7, 0x7B, + 0xB4, 0x3F, 0xA0, 0x0F, 0x8E, 0xA2, 0xB9, 0x6A, 0x6F, 0xB9, 0x87, 0x26, + 0x6F, 0x41, 0x6C, 0x88, 0xA6, 0x50, 0xFD, 0x6A, 0x63, 0x0B, 0xF5, 0x93, + 0x16, 0x1B, 0x19, 0x8F, 0xB2, 0xED, 0x9B, 0x9B, 0xC9, 0x90, 0xF5, 0x01, + 0x0C, 0xDF, 0x19, 0x3D, 0x0F, 0x3E, 0x38, 0x23, 0xC9, 0x2F, 0x8F, 0x0C, + 0xD1, 0x02, 0xFE, 0x1B, 0x55, 0xD6, 0x4E, 0xD0, 0x8D, 0x3C, 0xAF, 0x4F, + 0xA4, 0xF3, 0xFE, 0xAF, 0x2A, 0xD3, 0x05, 0x9D, 0x79, 0x08, 0xA1, 0xCB, + 0x57, 0x31, 0xB4, 0x9C, 0xC8, 0x90, 0xB2, 0x67, 0xF4, 0x18, 0x16, 0x93, + 0x3A, 0xFC, 0x47, 0xD8, 0xD1, 0x78, 0x96, 0x31, 0x1F, 0xBA, 0x2B, 0x0C, + 0x5F, 0x5D, 0x99, 0xAD, 0x63, 0x89, 0x5A, 0x24, 0x20, 0x76, 0xD8, 0xDF, + 0xFD, 0xAB, 0x4E, 0xA6, 0x22, 0xAA, 0x9D, 0x5E, 0xE6, 0x27, 0x8A, 0x7D, + 0x68, 0x29, 0xA3, 0xE7, 0x8A, 0xB8, 0xDA, 0x11, 0xBB, 0x17, 0x2D, 0x99, + 0x9D, 0x13, 0x24, 0x46, 0xF7, 0xC5, 0xE2, 0xD8, 0x9F, 0x8E, 0x7F, 0xC7, + 0x8F, 0x74, 0x6D, 0x5A, 0xB2, 0xE8, 0x72, 0xF5, 0xAC, 0xEE, 0x24, 0x10, + 0xAD, 0x2F, 0x14, 0xDA, 0xFF, 0x2D, 0x9A, 0x46, 0x71, 0x47, 0xBE, 0x42, + 0xDF, 0xBB, 0x01, 0xDB, 0xF4, 0x7F, 0xD3, 0x28, 0x8F, 0x31, 0x59, 0x5B, + 0xD3, 0xC9, 0x02, 0xA6, 0xB4, 0x52, 0xCA, 0x6E, 0x97, 0xFB, 0x43, 0xC5, + 0x08, 0x26, 0x6F, 0x8A, 0xF4, 0xBB, 0xFD, 0x9F, 0x28, 0xAA, 0x0D, 0xD5, + 0x45, 0xF3, 0x13, 0x3A, 0x1D, 0xD8, 0xC0, 0x78, 0x8F, 0x41, 0x67, 0x3C, + 0x1E, 0x94, 0x64, 0xAE, 0x7B, 0x0B, 0xC5, 0xE8, 0xD9, 0x01, 0x88, 0x39, + 0x1A, 0x97, 0x86, 0x64, 0x41, 0xD5, 0x3B, 0x87, 0x0C, 0x6E, 0xFA, 0x0F, + 0xC6, 0xBD, 0x48, 0x14, 0xBF, 0x39, 0x4D, 0xD4, 0x9E, 0x41, 0xB6, 0x8F, + 0x96, 0x1D, 0x63, 0x96, 0x93, 0xD9, 0x95, 0x06, 0x78, 0x31, 0x68, 0x9E, + 0x37, 0x06, 0x3B, 0x80, 0x89, 0x45, 0x61, 0x39, 0x23, 0xC7, 0x1B, 0x44, + 0xA3, 0x15, 0xE5, 0x1C, 0xF8, 0x92, 0x30, 0xBB +}; + +static const unsigned char TA573_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA574_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6F, 0x6D, 0x6D, + 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA574_RSA_N[] = { + 0xA7, 0x50, 0x19, 0xDE, 0x3F, 0x99, 0x3D, 0xD4, 0x33, 0x46, 0xF1, 0x6F, + 0x51, 0x61, 0x82, 0xB2, 0xA9, 0x4F, 0x8F, 0x67, 0x89, 0x5D, 0x84, 0xD9, + 0x53, 0xDD, 0x0C, 0x28, 0xD9, 0xD7, 0xF0, 0xFF, 0xAE, 0x95, 0x43, 0x72, + 0x99, 0xF9, 0xB5, 0x5D, 0x7C, 0x8A, 0xC1, 0x42, 0xE1, 0x31, 0x50, 0x74, + 0xD1, 0x81, 0x0D, 0x7C, 0xCD, 0x9B, 0x21, 0xAB, 0x43, 0xE2, 0xAC, 0xAD, + 0x5E, 0x86, 0x6E, 0xF3, 0x09, 0x8A, 0x1F, 0x5A, 0x32, 0xBD, 0xA2, 0xEB, + 0x94, 0xF9, 0xE8, 0x5C, 0x0A, 0xEC, 0xFF, 0x98, 0xD2, 0xAF, 0x71, 0xB3, + 0xB4, 0x53, 0x9F, 0x4E, 0x87, 0xEF, 0x92, 0xBC, 0xBD, 0xEC, 0x4F, 0x32, + 0x30, 0x88, 0x4B, 0x17, 0x5E, 0x57, 0xC4, 0x53, 0xC2, 0xF6, 0x02, 0x97, + 0x8D, 0xD9, 0x62, 0x2B, 0xBF, 0x24, 0x1F, 0x62, 0x8D, 0xDF, 0xC3, 0xB8, + 0x29, 0x4B, 0x49, 0x78, 0x3C, 0x93, 0x60, 0x88, 0x22, 0xFC, 0x99, 0xDA, + 0x36, 0xC8, 0xC2, 0xA2, 0xD4, 0x2C, 0x54, 0x00, 0x67, 0x35, 0x6E, 0x73, + 0xBF, 0x02, 0x58, 0xF0, 0xA4, 0xDD, 0xE5, 0xB0, 0xA2, 0x26, 0x7A, 0xCA, + 0xE0, 0x36, 0xA5, 0x19, 0x16, 0xF5, 0xFD, 0xB7, 0xEF, 0xAE, 0x3F, 0x40, + 0xF5, 0x6D, 0x5A, 0x04, 0xFD, 0xCE, 0x34, 0xCA, 0x24, 0xDC, 0x74, 0x23, + 0x1B, 0x5D, 0x33, 0x13, 0x12, 0x5D, 0xC4, 0x01, 0x25, 0xF6, 0x30, 0xDD, + 0x02, 0x5D, 0x9F, 0xE0, 0xD5, 0x47, 0xBD, 0xB4, 0xEB, 0x1B, 0xA1, 0xBB, + 0x49, 0x49, 0xD8, 0x9F, 0x5B, 0x02, 0xF3, 0x8A, 0xE4, 0x24, 0x90, 0xE4, + 0x62, 0x4F, 0x4F, 0xC1, 0xAF, 0x8B, 0x0E, 0x74, 0x17, 0xA8, 0xD1, 0x72, + 0x88, 0x6A, 0x7A, 0x01, 0x49, 0xCC, 0xB4, 0x46, 0x79, 0xC6, 0x17, 0xB1, + 0xDA, 0x98, 0x1E, 0x07, 0x59, 0xFA, 0x75, 0x21, 0x85, 0x65, 0xDD, 0x90, + 0x56, 0xCE, 0xFB, 0xAB, 0xA5, 0x60, 0x9D, 0xC4, 0x9D, 0xF9, 0x52, 0xB0, + 0x8B, 0xBD, 0x87, 0xF9, 0x8F, 0x2B, 0x23, 0x0A, 0x23, 0x76, 0x3B, 0xF7, + 0x33, 0xE1, 0xC9, 0x00, 0xF3, 0x69, 0xF9, 0x4B, 0xA2, 0xE0, 0x4E, 0xBC, + 0x7E, 0x93, 0x39, 0x84, 0x07, 0xF7, 0x44, 0x70, 0x7E, 0xFE, 0x07, 0x5A, + 0xE5, 0xB1, 0xAC, 0xD1, 0x18, 0xCC, 0xF2, 0x35, 0xE5, 0x49, 0x49, 0x08, + 0xCA, 0x56, 0xC9, 0x3D, 0xFB, 0x0F, 0x18, 0x7D, 0x8B, 0x3B, 0xC1, 0x13, + 0xC2, 0x4D, 0x8F, 0xC9, 0x4F, 0x0E, 0x37, 0xE9, 0x1F, 0xA1, 0x0E, 0x6A, + 0xDF, 0x62, 0x2E, 0xCB, 0x35, 0x06, 0x51, 0x79, 0x2C, 0xC8, 0x25, 0x38, + 0xF4, 0xFA, 0x4B, 0xA7, 0x89, 0x5C, 0x9C, 0xD2, 0xE3, 0x0D, 0x39, 0x86, + 0x4A, 0x74, 0x7C, 0xD5, 0x59, 0x87, 0xC2, 0x3F, 0x4E, 0x0C, 0x5C, 0x52, + 0xF4, 0x3D, 0xF7, 0x52, 0x82, 0xF1, 0xEA, 0xA3, 0xAC, 0xFD, 0x49, 0x34, + 0x1A, 0x28, 0xF3, 0x41, 0x88, 0x3A, 0x13, 0xEE, 0xE8, 0xDE, 0xFF, 0x99, + 0x1D, 0x5F, 0xBA, 0xCB, 0xE8, 0x1E, 0xF2, 0xB9, 0x50, 0x60, 0xC0, 0x31, + 0xD3, 0x73, 0xE5, 0xEF, 0xBE, 0xA0, 0xED, 0x33, 0x0B, 0x74, 0xBE, 0x20, + 0x20, 0xC4, 0x67, 0x6C, 0xF0, 0x08, 0x03, 0x7A, 0x55, 0x80, 0x7F, 0x46, + 0x4E, 0x96, 0xA7, 0xF4, 0x1E, 0x3E, 0xE1, 0xF6, 0xD8, 0x09, 0xE1, 0x33, + 0x64, 0x2B, 0x63, 0xD7, 0x32, 0x5E, 0x9F, 0xF9, 0xC0, 0x7B, 0x0F, 0x78, + 0x6F, 0x97, 0xBC, 0x93, 0x9A, 0xF9, 0x9C, 0x12, 0x90, 0x78, 0x7A, 0x80, + 0x87, 0x15, 0xD7, 0x72, 0x74, 0x9C, 0x55, 0x74, 0x78, 0xB1, 0xBA, 0xE1, + 0x6E, 0x70, 0x04, 0xBA, 0x4F, 0xA0, 0xBA, 0x68, 0xC3, 0x7B, 0xFF, 0x31, + 0xF0, 0x73, 0x3D, 0x3D, 0x94, 0x2A, 0xB1, 0x0B, 0x41, 0x0E, 0xA0, 0xFE, + 0x4D, 0x88, 0x65, 0x6B, 0x79, 0x33, 0xB4, 0xD7 +}; + +static const unsigned char TA574_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA575_DN[] = { + 0x30, 0x69, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4B, 0x52, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, 0x42, 0x55, 0x53, 0x49, + 0x4E, 0x45, 0x53, 0x53, 0x20, 0x50, 0x4C, 0x41, 0x54, 0x46, 0x4F, 0x52, + 0x4D, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA575_RSA_N[] = { + 0xB6, 0xD4, 0xF1, 0x93, 0x5C, 0xB5, 0x40, 0x89, 0x0A, 0xAB, 0x0D, 0x90, + 0x5B, 0x50, 0x63, 0xAE, 0x90, 0x94, 0x74, 0x17, 0x45, 0x72, 0xD6, 0x7B, + 0x65, 0x5A, 0x29, 0x4B, 0xA7, 0x56, 0xA0, 0x4B, 0xB8, 0x2F, 0x42, 0x75, + 0xE9, 0xD9, 0x7B, 0x24, 0x5A, 0x31, 0x65, 0xAB, 0x17, 0x17, 0xD1, 0x33, + 0x3A, 0xD9, 0x11, 0xDC, 0x40, 0x36, 0x87, 0xDF, 0xC7, 0x6A, 0xE9, 0x26, + 0x5E, 0x59, 0x8A, 0x77, 0xE3, 0xE8, 0x48, 0x9C, 0x31, 0x16, 0xFA, 0x3E, + 0x91, 0xB1, 0xCA, 0xC9, 0xA3, 0xE2, 0x9F, 0xCE, 0x21, 0x53, 0xA3, 0x02, + 0x36, 0x30, 0xCB, 0x52, 0x02, 0xE5, 0xDA, 0x32, 0x5D, 0xC3, 0xC5, 0xE6, + 0xF9, 0xEE, 0x11, 0xC7, 0x8B, 0xC9, 0x44, 0x1E, 0x84, 0x93, 0x18, 0x4A, + 0xB4, 0x9F, 0xE5, 0x12, 0x64, 0x69, 0xD0, 0x26, 0x85, 0x62, 0x01, 0xB6, + 0xC9, 0x02, 0x1D, 0xBE, 0x83, 0x51, 0xBB, 0x5C, 0xDA, 0xF8, 0xAD, 0x15, + 0x6A, 0x99, 0xF7, 0x92, 0x54, 0xF7, 0x34, 0x5B, 0xE9, 0xBF, 0xEA, 0x29, + 0x81, 0x12, 0xD4, 0x53, 0x91, 0x96, 0xB3, 0x91, 0x5A, 0xDD, 0xFE, 0x90, + 0x73, 0x28, 0xFB, 0x30, 0x46, 0xB5, 0xCA, 0x08, 0x07, 0xC7, 0x71, 0x72, + 0xC9, 0x66, 0xD3, 0x34, 0x97, 0xF6, 0x8C, 0xF4, 0x18, 0x4A, 0xE1, 0xD0, + 0x3D, 0x5A, 0x45, 0xB6, 0x69, 0xA7, 0x29, 0xFB, 0x23, 0xCE, 0x88, 0xD8, + 0x12, 0x9C, 0x00, 0x48, 0xA8, 0xA6, 0x0F, 0xB3, 0x3B, 0x92, 0x8D, 0x71, + 0x0E, 0x74, 0xC5, 0x8B, 0xC8, 0x4C, 0xF9, 0xF4, 0x9B, 0x8E, 0xB8, 0x3C, + 0x69, 0xED, 0x6F, 0x3B, 0x50, 0x2F, 0x58, 0xED, 0xC4, 0xB0, 0xD0, 0x1C, + 0x1B, 0x6A, 0x0C, 0xE2, 0xBC, 0x44, 0xAA, 0xD8, 0xCD, 0x14, 0x5D, 0x94, + 0x78, 0x61, 0xBF, 0x0E, 0x6E, 0xDA, 0x2A, 0xBC, 0x2F, 0x0C, 0x0B, 0x71, + 0xA6, 0xB3, 0x16, 0x3F, 0x9C, 0xE6, 0xF9, 0xCC, 0x9F, 0x53, 0x35, 0xE2, + 0x03, 0xA0, 0xA0, 0x18, 0xBF, 0xBB, 0xF1, 0xBE, 0xF4, 0xD6, 0x8C, 0x87, + 0x0D, 0x42, 0xF7, 0x06, 0xB9, 0xF1, 0x6D, 0xED, 0x04, 0x94, 0xA8, 0xFE, + 0xB6, 0xD3, 0x06, 0xC6, 0x40, 0x61, 0xDF, 0x9D, 0x9D, 0xF3, 0x54, 0x76, + 0xCE, 0x53, 0x3A, 0x01, 0xA6, 0x92, 0x41, 0xEC, 0x04, 0xA3, 0x8F, 0x0D, + 0xA2, 0xD5, 0x09, 0xCA, 0xD6, 0xCB, 0x9A, 0xF1, 0xEF, 0x43, 0x5D, 0xC0, + 0xAB, 0xA5, 0x41, 0xCF, 0x5C, 0x53, 0x70, 0x70, 0xC9, 0x88, 0xA6, 0x2D, + 0xD4, 0x6B, 0x61, 0x73, 0x50, 0x26, 0x86, 0x61, 0x0E, 0x5F, 0x1B, 0xC2, + 0x2B, 0xE2, 0x8C, 0xD5, 0xBB, 0x9D, 0xC1, 0x03, 0x42, 0xBA, 0x94, 0xDA, + 0x5F, 0xA9, 0xB0, 0xCA, 0xCC, 0x4D, 0x0A, 0xEF, 0x47, 0x69, 0x03, 0x2F, + 0x22, 0xFB, 0xF1, 0x28, 0xCE, 0xBF, 0x5D, 0x50, 0x65, 0xA8, 0x90, 0x6D, + 0xB3, 0x74, 0xB0, 0x08, 0xC7, 0xAC, 0xA8, 0xD1, 0xEB, 0x3E, 0x9C, 0xFC, + 0x5D, 0x1A, 0x83, 0x2E, 0x2B, 0xCB, 0xB5, 0xF3, 0x44, 0x9D, 0x3A, 0xA7, + 0x17, 0x61, 0x96, 0xA2, 0x71, 0xD3, 0x70, 0x96, 0x15, 0x4D, 0xB7, 0x4C, + 0x73, 0xEE, 0x19, 0x5C, 0xC5, 0x5B, 0x3E, 0x41, 0xFE, 0xAC, 0x75, 0x60, + 0x3B, 0x1B, 0x63, 0xCE, 0x00, 0xDD, 0xDA, 0x08, 0x90, 0x62, 0xB4, 0xE5, + 0x2D, 0xEE, 0x48, 0xA7, 0x6B, 0x17, 0x99, 0x54, 0xBE, 0x87, 0x4A, 0xE3, + 0xA9, 0x5E, 0x04, 0x4C, 0xEB, 0x10, 0x6D, 0x54, 0xD6, 0xEF, 0xF1, 0xE8, + 0xF2, 0x62, 0x16, 0xCB, 0x80, 0x6B, 0xED, 0x3D, 0xED, 0xF5, 0x1F, 0x30, + 0xA5, 0xAE, 0x4B, 0xC9, 0x13, 0xED, 0x8A, 0x01, 0x01, 0xC9, 0xB8, 0x51, + 0x58, 0xC0, 0x66, 0x3A, 0xB1, 0x66, 0x4B, 0xC4, 0xD5, 0x31, 0x02, 0x62, + 0xE9, 0x74, 0x84, 0x0C, 0xDB, 0x4D, 0x46, 0x2D +}; + +static const unsigned char TA575_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA576_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x34 +}; + +static const unsigned char TA576_EC_Q[] = { + 0x04, 0xD2, 0xAB, 0x8A, 0x37, 0x4F, 0xA3, 0x53, 0x0D, 0xFE, 0xC1, 0x8A, + 0x7B, 0x4B, 0xA8, 0x7B, 0x46, 0x4B, 0x63, 0xB0, 0x62, 0xF6, 0x2D, 0x1B, + 0xDB, 0x08, 0x71, 0x21, 0xD2, 0x00, 0xE8, 0x63, 0xBD, 0x9A, 0x27, 0xFB, + 0xF0, 0x39, 0x6E, 0x5D, 0xEA, 0x3D, 0xA5, 0xC9, 0x81, 0xAA, 0xA3, 0x5B, + 0x20, 0x98, 0x45, 0x5D, 0x16, 0xDB, 0xFD, 0xE8, 0x10, 0x6D, 0xE3, 0x9C, + 0xE0, 0xE3, 0xBD, 0x5F, 0x84, 0x62, 0xF3, 0x70, 0x64, 0x33, 0xA0, 0xCB, + 0x24, 0x2F, 0x70, 0xBA, 0x88, 0xA1, 0x2A, 0xA0, 0x75, 0xF8, 0x81, 0xAE, + 0x62, 0x06, 0xC4, 0x81, 0xDB, 0x39, 0x6E, 0x29, 0xB0, 0x1E, 0xFA, 0x2E, + 0x5C +}; + +static const unsigned char TA577_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA577_RSA_N[] = { + 0x91, 0xE8, 0x54, 0x92, 0xD2, 0x0A, 0x56, 0xB1, 0xAC, 0x0D, 0x24, 0xDD, + 0xC5, 0xCF, 0x44, 0x67, 0x74, 0x99, 0x2B, 0x37, 0xA3, 0x7D, 0x23, 0x70, + 0x00, 0x71, 0xBC, 0x53, 0xDF, 0xC4, 0xFA, 0x2A, 0x12, 0x8F, 0x4B, 0x7F, + 0x10, 0x56, 0xBD, 0x9F, 0x70, 0x72, 0xB7, 0x61, 0x7F, 0xC9, 0x4B, 0x0F, + 0x17, 0xA7, 0x3D, 0xE3, 0xB0, 0x04, 0x61, 0xEE, 0xFF, 0x11, 0x97, 0xC7, + 0xF4, 0x86, 0x3E, 0x0A, 0xFA, 0x3E, 0x5C, 0xF9, 0x93, 0xE6, 0x34, 0x7A, + 0xD9, 0x14, 0x6B, 0xE7, 0x9C, 0xB3, 0x85, 0xA0, 0x82, 0x7A, 0x76, 0xAF, + 0x71, 0x90, 0xD7, 0xEC, 0xFD, 0x0D, 0xFA, 0x9C, 0x6C, 0xFA, 0xDF, 0xB0, + 0x82, 0xF4, 0x14, 0x7E, 0xF9, 0xBE, 0xC4, 0xA6, 0x2F, 0x4F, 0x7F, 0x99, + 0x7F, 0xB5, 0xFC, 0x67, 0x43, 0x72, 0xBD, 0x0C, 0x00, 0xD6, 0x89, 0xEB, + 0x6B, 0x2C, 0xD3, 0xED, 0x8F, 0x98, 0x1C, 0x14, 0xAB, 0x7E, 0xE5, 0xE3, + 0x6E, 0xFC, 0xD8, 0xA8, 0xE4, 0x92, 0x24, 0xDA, 0x43, 0x6B, 0x62, 0xB8, + 0x55, 0xFD, 0xEA, 0xC1, 0xBC, 0x6C, 0xB6, 0x8B, 0xF3, 0x0E, 0x8D, 0x9A, + 0xE4, 0x9B, 0x6C, 0x69, 0x99, 0xF8, 0x78, 0x48, 0x30, 0x45, 0xD5, 0xAD, + 0xE1, 0x0D, 0x3C, 0x45, 0x60, 0xFC, 0x32, 0x96, 0x51, 0x27, 0xBC, 0x67, + 0xC3, 0xCA, 0x2E, 0xB6, 0x6B, 0xEA, 0x46, 0xC7, 0xC7, 0x20, 0xA0, 0xB1, + 0x1F, 0x65, 0xDE, 0x48, 0x08, 0xBA, 0xA4, 0x4E, 0xA9, 0xF2, 0x83, 0x46, + 0x37, 0x84, 0xEB, 0xE8, 0xCC, 0x81, 0x48, 0x43, 0x67, 0x4E, 0x72, 0x2A, + 0x9B, 0x5C, 0xBD, 0x4C, 0x1B, 0x28, 0x8A, 0x5C, 0x22, 0x7B, 0xB4, 0xAB, + 0x98, 0xD9, 0xEE, 0xE0, 0x51, 0x83, 0xC3, 0x09, 0x46, 0x4E, 0x6D, 0x3E, + 0x99, 0xFA, 0x95, 0x17, 0xDA, 0x7C, 0x33, 0x57, 0x41, 0x3C, 0x8D, 0x51, + 0xED, 0x0B, 0xB6, 0x5C, 0xAF, 0x2C, 0x63, 0x1A, 0xDF, 0x57, 0xC8, 0x3F, + 0xBC, 0xE9, 0x5D, 0xC4, 0x9B, 0xAF, 0x45, 0x99, 0xE2, 0xA3, 0x5A, 0x24, + 0xB4, 0xBA, 0xA9, 0x56, 0x3D, 0xCF, 0x6F, 0xAA, 0xFF, 0x49, 0x58, 0xBE, + 0xF0, 0xA8, 0xFF, 0xF4, 0xB8, 0xAD, 0xE9, 0x37, 0xFB, 0xBA, 0xB8, 0xF4, + 0x0B, 0x3A, 0xF9, 0xE8, 0x43, 0x42, 0x1E, 0x89, 0xD8, 0x84, 0xCB, 0x13, + 0xF1, 0xD9, 0xBB, 0xE1, 0x89, 0x60, 0xB8, 0x8C, 0x28, 0x56, 0xAC, 0x14, + 0x1D, 0x9C, 0x0A, 0xE7, 0x71, 0xEB, 0xCF, 0x0E, 0xDD, 0x3D, 0xA9, 0x96, + 0xA1, 0x48, 0xBD, 0x3C, 0xF7, 0xAF, 0xB5, 0x0D, 0x22, 0x4C, 0xC0, 0x11, + 0x81, 0xEC, 0x56, 0x3B, 0xF6, 0xD3, 0xA2, 0xE2, 0x5B, 0xB7, 0xB2, 0x04, + 0x22, 0x52, 0x95, 0x80, 0x93, 0x69, 0xE8, 0x8E, 0x4C, 0x65, 0xF1, 0x91, + 0x03, 0x2D, 0x70, 0x74, 0x02, 0xEA, 0x8B, 0x67, 0x15, 0x29, 0x69, 0x52, + 0x02, 0xBB, 0xD7, 0xDF, 0x50, 0x6A, 0x55, 0x46, 0xBF, 0xA0, 0xA3, 0x28, + 0x61, 0x7F, 0x70, 0xD0, 0xC3, 0xA2, 0xAA, 0x2C, 0x21, 0xAA, 0x47, 0xCE, + 0x28, 0x9C, 0x06, 0x45, 0x76, 0xBF, 0x82, 0x18, 0x27, 0xB4, 0xD5, 0xAE, + 0xB4, 0xCB, 0x50, 0xE6, 0x6B, 0xF4, 0x4C, 0x86, 0x71, 0x30, 0xE9, 0xA6, + 0xDF, 0x16, 0x86, 0xE0, 0xD8, 0xFF, 0x40, 0xDD, 0xFB, 0xD0, 0x42, 0x88, + 0x7F, 0xA3, 0x33, 0x3A, 0x2E, 0x5C, 0x1E, 0x41, 0x11, 0x81, 0x63, 0xCE, + 0x18, 0x71, 0x6B, 0x2B, 0xEC, 0xA6, 0x8A, 0xB7, 0x31, 0x5C, 0x3A, 0x6A, + 0x47, 0xE0, 0xC3, 0x79, 0x59, 0xD6, 0x20, 0x1A, 0xAF, 0xF2, 0x6A, 0x98, + 0xAA, 0x72, 0xBC, 0x57, 0x4A, 0xD2, 0x4B, 0x9D, 0xBB, 0x10, 0xFC, 0xB0, + 0x4C, 0x41, 0xE5, 0xED, 0x1D, 0x3D, 0x5E, 0x28, 0x9D, 0x9C, 0xCC, 0xBF, + 0xB3, 0x51, 0xDA, 0xA7, 0x47, 0xE5, 0x84, 0x53 +}; + +static const unsigned char TA577_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA578_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x21, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x45, 0x56, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA578_RSA_N[] = { + 0x99, 0xF1, 0x84, 0x34, 0x70, 0xBA, 0x2F, 0xB7, 0x30, 0xA0, 0x8E, 0xBD, + 0x7C, 0x04, 0xCF, 0xBE, 0x62, 0xBC, 0x99, 0xFD, 0x82, 0x97, 0xD2, 0x7A, + 0x0A, 0x67, 0x96, 0x38, 0x09, 0xF6, 0x10, 0x4E, 0x95, 0x22, 0x73, 0x99, + 0x8D, 0xDA, 0x15, 0x2D, 0xE7, 0x05, 0xFC, 0x19, 0x73, 0x22, 0xB7, 0x8E, + 0x98, 0x00, 0xBC, 0x3C, 0x3D, 0xAC, 0xA1, 0x6C, 0xFB, 0xD6, 0x79, 0x25, + 0x4B, 0xAD, 0xF0, 0xCC, 0x64, 0xDA, 0x88, 0x3E, 0x29, 0xB8, 0x0F, 0x09, + 0xD3, 0x34, 0xDD, 0x33, 0xF5, 0x62, 0xD1, 0xE1, 0xCD, 0x19, 0xE9, 0xEE, + 0x18, 0x4F, 0x4C, 0x58, 0xAE, 0xE2, 0x1E, 0xD6, 0x0C, 0x5B, 0x15, 0x5A, + 0xD8, 0x3A, 0xB8, 0xC4, 0x18, 0x64, 0x1E, 0xE3, 0x33, 0xB2, 0xB5, 0x89, + 0x77, 0x4E, 0x0C, 0xBF, 0xD9, 0x94, 0x6B, 0x13, 0x97, 0x6F, 0x12, 0xA3, + 0xFE, 0x99, 0xA9, 0x04, 0xCC, 0x15, 0xEC, 0x60, 0x68, 0x36, 0xED, 0x08, + 0x7B, 0xB7, 0xF5, 0xBF, 0x93, 0xED, 0x66, 0x31, 0x83, 0x8C, 0xC6, 0x71, + 0x34, 0x87, 0x4E, 0x17, 0xEA, 0xAF, 0x8B, 0x91, 0x8D, 0x1C, 0x56, 0x41, + 0xAE, 0x22, 0x37, 0x5E, 0x37, 0xF2, 0x1D, 0xD9, 0xD1, 0x2D, 0x0D, 0x2F, + 0x69, 0x51, 0xA7, 0xBE, 0x66, 0xA6, 0x8A, 0x3A, 0x2A, 0xBD, 0xC7, 0x1A, + 0xB1, 0xE1, 0x14, 0xF0, 0xBE, 0x3A, 0x1D, 0xB9, 0xCF, 0x5B, 0xB1, 0x6A, + 0xFE, 0xB4, 0xB1, 0x46, 0x20, 0xA2, 0xFB, 0x1E, 0x3B, 0x70, 0xEF, 0x93, + 0x98, 0x7D, 0x8C, 0x73, 0x96, 0xF2, 0xC5, 0xEF, 0x85, 0x70, 0xAD, 0x29, + 0x26, 0xFC, 0x1E, 0x04, 0x3E, 0x1C, 0xA0, 0xD8, 0x0F, 0xCB, 0x52, 0x83, + 0x62, 0x7C, 0xEE, 0x8B, 0x53, 0x95, 0x90, 0xA9, 0x57, 0xA2, 0xEA, 0x61, + 0x05, 0xD8, 0xF9, 0x4D, 0xC4, 0x27, 0xFA, 0x6E, 0xAD, 0xED, 0xF9, 0xD7, + 0x51, 0xF7, 0x6B, 0xA5 +}; + +static const unsigned char TA578_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA579_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x34, 0x30, 0x39, 0x36, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA579_RSA_N[] = { + 0xB3, 0xD0, 0xF4, 0xC9, 0x79, 0x11, 0x9D, 0xFD, 0xFC, 0x66, 0x81, 0xE7, + 0xCC, 0xD5, 0xE4, 0xBC, 0xEC, 0x81, 0x3E, 0x6A, 0x35, 0x8E, 0x2E, 0xB7, + 0xE7, 0xDE, 0xAF, 0xF9, 0x07, 0x4D, 0xCF, 0x30, 0x9D, 0xEA, 0x09, 0x0B, + 0x99, 0xBD, 0x6C, 0x57, 0xDA, 0x18, 0x4A, 0xB8, 0x78, 0xAC, 0x3A, 0x39, + 0xA8, 0xA6, 0x48, 0xAC, 0x2E, 0x72, 0xE5, 0xBD, 0xEB, 0xF1, 0x1A, 0xCD, + 0xE7, 0xA4, 0x03, 0xA9, 0x3F, 0x11, 0xB4, 0xD8, 0x2F, 0x89, 0x16, 0xFB, + 0x94, 0x01, 0x3D, 0xBB, 0x2F, 0xF8, 0x13, 0x05, 0xA1, 0x78, 0x1C, 0x8E, + 0x28, 0xE0, 0x45, 0xE0, 0x83, 0xF4, 0x59, 0x1B, 0x95, 0xB3, 0xAE, 0x7E, + 0x03, 0x45, 0xE5, 0xBE, 0xC2, 0x42, 0xFE, 0xEE, 0xF2, 0x3C, 0xB6, 0x85, + 0x13, 0x98, 0x32, 0x9D, 0x16, 0xA8, 0x29, 0xC2, 0x0B, 0x1C, 0x38, 0xDC, + 0x9F, 0x31, 0x77, 0x5C, 0xBF, 0x27, 0xA3, 0xFC, 0x27, 0xAC, 0xB7, 0x2B, + 0xBD, 0x74, 0x9B, 0x17, 0x2D, 0xF2, 0x81, 0xDA, 0x5D, 0xB0, 0xE1, 0x23, + 0x17, 0x3E, 0x88, 0x4A, 0x12, 0x23, 0xD0, 0xEA, 0xCF, 0x9D, 0xDE, 0x03, + 0x17, 0xB1, 0x42, 0x4A, 0xA0, 0x16, 0x4C, 0xA4, 0x6D, 0x93, 0xE9, 0x3F, + 0x3A, 0xEE, 0x3A, 0x7C, 0x9D, 0x58, 0x9D, 0xF4, 0x4E, 0x8F, 0xFC, 0x3B, + 0x23, 0xC8, 0x6D, 0xB8, 0xE2, 0x05, 0xDA, 0xCC, 0xEB, 0xEC, 0xC3, 0x31, + 0xF4, 0xD7, 0xA7, 0x29, 0x54, 0x80, 0xCF, 0x44, 0x5B, 0x4C, 0x6F, 0x30, + 0x9E, 0xF3, 0xCC, 0xDD, 0x1F, 0x94, 0x43, 0x9D, 0x4D, 0x7F, 0x70, 0x70, + 0x0D, 0xD4, 0x3A, 0xD1, 0x37, 0xF0, 0x6C, 0x9D, 0x9B, 0xC0, 0x14, 0x93, + 0x58, 0xEF, 0xCD, 0x41, 0x38, 0x75, 0xBC, 0x13, 0x03, 0x95, 0x7C, 0x7F, + 0xE3, 0x5C, 0xE9, 0xD5, 0x0D, 0xD5, 0xE2, 0x7C, 0x10, 0x62, 0xAA, 0x6B, + 0xF0, 0x3D, 0x76, 0xF3, 0x3F, 0xA3, 0xE8, 0xB0, 0xC1, 0xFD, 0xEF, 0xAA, + 0x57, 0x4D, 0xAC, 0x86, 0xA7, 0x18, 0xB4, 0x29, 0xC1, 0x2C, 0x0E, 0xBF, + 0x64, 0xBE, 0x29, 0x8C, 0xD8, 0x02, 0x2D, 0xCD, 0x5C, 0x2F, 0xF2, 0x7F, + 0xEF, 0x15, 0xF4, 0x0C, 0x15, 0xAC, 0x0A, 0xB0, 0xF1, 0xD3, 0x0D, 0x4F, + 0x6A, 0x4D, 0x77, 0x97, 0x01, 0xA0, 0xF1, 0x66, 0xB7, 0xB7, 0xCE, 0xEF, + 0xCE, 0xEC, 0xEC, 0xA5, 0x75, 0xCA, 0xAC, 0xE3, 0xE1, 0x63, 0xF7, 0xB8, + 0xA1, 0x04, 0xC8, 0xBC, 0x7B, 0x3F, 0x5D, 0x2D, 0x16, 0x22, 0x56, 0xED, + 0x48, 0x49, 0xFE, 0xA7, 0x2F, 0x79, 0x30, 0x25, 0x9B, 0xBA, 0x6B, 0x2D, + 0x3F, 0x9D, 0x3B, 0xC4, 0x17, 0xE7, 0x1D, 0x2E, 0xFB, 0xF2, 0xCF, 0xA6, + 0xFC, 0xE3, 0x14, 0x2C, 0x96, 0x98, 0x21, 0x8C, 0xB4, 0x91, 0xE9, 0x19, + 0x60, 0x83, 0xF2, 0x30, 0x2B, 0x06, 0x73, 0x50, 0xD5, 0x98, 0x3B, 0x06, + 0xE9, 0xC7, 0x8A, 0x0C, 0x60, 0x8C, 0x28, 0xF8, 0x52, 0x9B, 0x6E, 0xE1, + 0xF6, 0x4D, 0xBB, 0x06, 0x24, 0x9B, 0xD7, 0x2B, 0x26, 0x3F, 0xFD, 0x2A, + 0x2F, 0x71, 0xF5, 0xD6, 0x24, 0xBE, 0x7F, 0x31, 0x9E, 0x0F, 0x6D, 0xE8, + 0x8F, 0x4F, 0x4D, 0xA3, 0x3F, 0xFF, 0x35, 0xEA, 0xDF, 0x49, 0x5E, 0x41, + 0x8F, 0x86, 0xF9, 0xF1, 0x77, 0x79, 0x4B, 0x1B, 0xB4, 0xA3, 0x5E, 0x2F, + 0xFB, 0x46, 0x02, 0xD0, 0x66, 0x13, 0x5E, 0x5E, 0x85, 0x4F, 0xCE, 0xD8, + 0x70, 0x88, 0x7B, 0xCE, 0x01, 0xB5, 0x96, 0x97, 0xD7, 0xCD, 0x7D, 0xFD, + 0x82, 0xF8, 0xC2, 0x24, 0xC1, 0xCA, 0x01, 0x39, 0x4F, 0x8D, 0xA2, 0xC1, + 0x14, 0x40, 0x1F, 0x9C, 0x66, 0xD5, 0x0C, 0x09, 0x46, 0xD6, 0xF2, 0xD0, + 0xD1, 0x48, 0x76, 0x56, 0x3A, 0x43, 0xCB, 0xB6, 0x0A, 0x11, 0x39, 0xBA, + 0x8C, 0x13, 0x6C, 0x06, 0xB5, 0x9E, 0xCF, 0xEB +}; + +static const unsigned char TA579_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA580_DN[] = { + 0x30, 0x5D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x1E, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA580_RSA_N[] = { + 0xD0, 0x15, 0x39, 0x52, 0xB1, 0x52, 0xB3, 0xBA, 0xC5, 0x59, 0x82, 0xC4, + 0x5D, 0x52, 0xAE, 0x3A, 0x43, 0x65, 0x80, 0x4B, 0xC7, 0xF2, 0x96, 0xBC, + 0xDB, 0x36, 0x97, 0xD6, 0xA6, 0x64, 0x8C, 0xA8, 0x5E, 0xF0, 0xE3, 0x0A, + 0x1C, 0xF7, 0xDF, 0x97, 0x3D, 0x4B, 0xAE, 0xF6, 0x5D, 0xEC, 0x21, 0xB5, + 0x41, 0xAB, 0xCD, 0xB9, 0x7E, 0x76, 0x9F, 0xBE, 0xF9, 0x3E, 0x36, 0x34, + 0xA0, 0x3B, 0xC1, 0xF6, 0x31, 0x11, 0x45, 0x74, 0x93, 0x3D, 0x57, 0x80, + 0xC5, 0xF9, 0x89, 0x99, 0xCA, 0xE5, 0xAB, 0x6A, 0xD4, 0xB5, 0xDA, 0x41, + 0x90, 0x10, 0xC1, 0xD6, 0xD6, 0x42, 0x89, 0xC2, 0xBF, 0xF4, 0x38, 0x12, + 0x95, 0x4C, 0x54, 0x05, 0xF7, 0x36, 0xE4, 0x45, 0x83, 0x7B, 0x14, 0x65, + 0xD6, 0xDC, 0x0C, 0x4D, 0xD1, 0xDE, 0x7E, 0x0C, 0xAB, 0x3B, 0xC4, 0x15, + 0xBE, 0x3A, 0x56, 0xA6, 0x5A, 0x6F, 0x76, 0x69, 0x52, 0xA9, 0x7A, 0xB9, + 0xC8, 0xEB, 0x6A, 0x9A, 0x5D, 0x52, 0xD0, 0x2D, 0x0A, 0x6B, 0x35, 0x16, + 0x09, 0x10, 0x84, 0xD0, 0x6A, 0xCA, 0x3A, 0x06, 0x00, 0x37, 0x47, 0xE4, + 0x7E, 0x57, 0x4F, 0x3F, 0x8B, 0xEB, 0x67, 0xB8, 0x88, 0xAA, 0xC5, 0xBE, + 0x53, 0x55, 0xB2, 0x91, 0xC4, 0x7D, 0xB9, 0xB0, 0x85, 0x19, 0x06, 0x78, + 0x2E, 0xDB, 0x61, 0x1A, 0xFA, 0x85, 0xF5, 0x4A, 0x91, 0xA1, 0xE7, 0x16, + 0xD5, 0x8E, 0xA2, 0x39, 0xDF, 0x94, 0xB8, 0x70, 0x1F, 0x28, 0x3F, 0x8B, + 0xFC, 0x40, 0x5E, 0x63, 0x83, 0x3C, 0x83, 0x2A, 0x1A, 0x99, 0x6B, 0xCF, + 0xDE, 0x59, 0x6A, 0x3B, 0xFC, 0x6F, 0x16, 0xD7, 0x1F, 0xFD, 0x4A, 0x10, + 0xEB, 0x4E, 0x82, 0x16, 0x3A, 0xAC, 0x27, 0x0C, 0x53, 0xF1, 0xAD, 0xD5, + 0x24, 0xB0, 0x6B, 0x03, 0x50, 0xC1, 0x2D, 0x3C, 0x16, 0xDD, 0x44, 0x34, + 0x27, 0x1A, 0x75, 0xFB +}; + +static const unsigned char TA580_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA581_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA581_RSA_N[] = { + 0x91, 0xE8, 0x54, 0x92, 0xD2, 0x0A, 0x56, 0xB1, 0xAC, 0x0D, 0x24, 0xDD, + 0xC5, 0xCF, 0x44, 0x67, 0x74, 0x99, 0x2B, 0x37, 0xA3, 0x7D, 0x23, 0x70, + 0x00, 0x71, 0xBC, 0x53, 0xDF, 0xC4, 0xFA, 0x2A, 0x12, 0x8F, 0x4B, 0x7F, + 0x10, 0x56, 0xBD, 0x9F, 0x70, 0x72, 0xB7, 0x61, 0x7F, 0xC9, 0x4B, 0x0F, + 0x17, 0xA7, 0x3D, 0xE3, 0xB0, 0x04, 0x61, 0xEE, 0xFF, 0x11, 0x97, 0xC7, + 0xF4, 0x86, 0x3E, 0x0A, 0xFA, 0x3E, 0x5C, 0xF9, 0x93, 0xE6, 0x34, 0x7A, + 0xD9, 0x14, 0x6B, 0xE7, 0x9C, 0xB3, 0x85, 0xA0, 0x82, 0x7A, 0x76, 0xAF, + 0x71, 0x90, 0xD7, 0xEC, 0xFD, 0x0D, 0xFA, 0x9C, 0x6C, 0xFA, 0xDF, 0xB0, + 0x82, 0xF4, 0x14, 0x7E, 0xF9, 0xBE, 0xC4, 0xA6, 0x2F, 0x4F, 0x7F, 0x99, + 0x7F, 0xB5, 0xFC, 0x67, 0x43, 0x72, 0xBD, 0x0C, 0x00, 0xD6, 0x89, 0xEB, + 0x6B, 0x2C, 0xD3, 0xED, 0x8F, 0x98, 0x1C, 0x14, 0xAB, 0x7E, 0xE5, 0xE3, + 0x6E, 0xFC, 0xD8, 0xA8, 0xE4, 0x92, 0x24, 0xDA, 0x43, 0x6B, 0x62, 0xB8, + 0x55, 0xFD, 0xEA, 0xC1, 0xBC, 0x6C, 0xB6, 0x8B, 0xF3, 0x0E, 0x8D, 0x9A, + 0xE4, 0x9B, 0x6C, 0x69, 0x99, 0xF8, 0x78, 0x48, 0x30, 0x45, 0xD5, 0xAD, + 0xE1, 0x0D, 0x3C, 0x45, 0x60, 0xFC, 0x32, 0x96, 0x51, 0x27, 0xBC, 0x67, + 0xC3, 0xCA, 0x2E, 0xB6, 0x6B, 0xEA, 0x46, 0xC7, 0xC7, 0x20, 0xA0, 0xB1, + 0x1F, 0x65, 0xDE, 0x48, 0x08, 0xBA, 0xA4, 0x4E, 0xA9, 0xF2, 0x83, 0x46, + 0x37, 0x84, 0xEB, 0xE8, 0xCC, 0x81, 0x48, 0x43, 0x67, 0x4E, 0x72, 0x2A, + 0x9B, 0x5C, 0xBD, 0x4C, 0x1B, 0x28, 0x8A, 0x5C, 0x22, 0x7B, 0xB4, 0xAB, + 0x98, 0xD9, 0xEE, 0xE0, 0x51, 0x83, 0xC3, 0x09, 0x46, 0x4E, 0x6D, 0x3E, + 0x99, 0xFA, 0x95, 0x17, 0xDA, 0x7C, 0x33, 0x57, 0x41, 0x3C, 0x8D, 0x51, + 0xED, 0x0B, 0xB6, 0x5C, 0xAF, 0x2C, 0x63, 0x1A, 0xDF, 0x57, 0xC8, 0x3F, + 0xBC, 0xE9, 0x5D, 0xC4, 0x9B, 0xAF, 0x45, 0x99, 0xE2, 0xA3, 0x5A, 0x24, + 0xB4, 0xBA, 0xA9, 0x56, 0x3D, 0xCF, 0x6F, 0xAA, 0xFF, 0x49, 0x58, 0xBE, + 0xF0, 0xA8, 0xFF, 0xF4, 0xB8, 0xAD, 0xE9, 0x37, 0xFB, 0xBA, 0xB8, 0xF4, + 0x0B, 0x3A, 0xF9, 0xE8, 0x43, 0x42, 0x1E, 0x89, 0xD8, 0x84, 0xCB, 0x13, + 0xF1, 0xD9, 0xBB, 0xE1, 0x89, 0x60, 0xB8, 0x8C, 0x28, 0x56, 0xAC, 0x14, + 0x1D, 0x9C, 0x0A, 0xE7, 0x71, 0xEB, 0xCF, 0x0E, 0xDD, 0x3D, 0xA9, 0x96, + 0xA1, 0x48, 0xBD, 0x3C, 0xF7, 0xAF, 0xB5, 0x0D, 0x22, 0x4C, 0xC0, 0x11, + 0x81, 0xEC, 0x56, 0x3B, 0xF6, 0xD3, 0xA2, 0xE2, 0x5B, 0xB7, 0xB2, 0x04, + 0x22, 0x52, 0x95, 0x80, 0x93, 0x69, 0xE8, 0x8E, 0x4C, 0x65, 0xF1, 0x91, + 0x03, 0x2D, 0x70, 0x74, 0x02, 0xEA, 0x8B, 0x67, 0x15, 0x29, 0x69, 0x52, + 0x02, 0xBB, 0xD7, 0xDF, 0x50, 0x6A, 0x55, 0x46, 0xBF, 0xA0, 0xA3, 0x28, + 0x61, 0x7F, 0x70, 0xD0, 0xC3, 0xA2, 0xAA, 0x2C, 0x21, 0xAA, 0x47, 0xCE, + 0x28, 0x9C, 0x06, 0x45, 0x76, 0xBF, 0x82, 0x18, 0x27, 0xB4, 0xD5, 0xAE, + 0xB4, 0xCB, 0x50, 0xE6, 0x6B, 0xF4, 0x4C, 0x86, 0x71, 0x30, 0xE9, 0xA6, + 0xDF, 0x16, 0x86, 0xE0, 0xD8, 0xFF, 0x40, 0xDD, 0xFB, 0xD0, 0x42, 0x88, + 0x7F, 0xA3, 0x33, 0x3A, 0x2E, 0x5C, 0x1E, 0x41, 0x11, 0x81, 0x63, 0xCE, + 0x18, 0x71, 0x6B, 0x2B, 0xEC, 0xA6, 0x8A, 0xB7, 0x31, 0x5C, 0x3A, 0x6A, + 0x47, 0xE0, 0xC3, 0x79, 0x59, 0xD6, 0x20, 0x1A, 0xAF, 0xF2, 0x6A, 0x98, + 0xAA, 0x72, 0xBC, 0x57, 0x4A, 0xD2, 0x4B, 0x9D, 0xBB, 0x10, 0xFC, 0xB0, + 0x4C, 0x41, 0xE5, 0xED, 0x1D, 0x3D, 0x5E, 0x28, 0x9D, 0x9C, 0xCC, 0xBF, + 0xB3, 0x51, 0xDA, 0xA7, 0x47, 0xE5, 0x84, 0x53 +}; + +static const unsigned char TA581_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA582_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x21, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x45, 0x56, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA582_RSA_N[] = { + 0x99, 0xF1, 0x84, 0x34, 0x70, 0xBA, 0x2F, 0xB7, 0x30, 0xA0, 0x8E, 0xBD, + 0x7C, 0x04, 0xCF, 0xBE, 0x62, 0xBC, 0x99, 0xFD, 0x82, 0x97, 0xD2, 0x7A, + 0x0A, 0x67, 0x96, 0x38, 0x09, 0xF6, 0x10, 0x4E, 0x95, 0x22, 0x73, 0x99, + 0x8D, 0xDA, 0x15, 0x2D, 0xE7, 0x05, 0xFC, 0x19, 0x73, 0x22, 0xB7, 0x8E, + 0x98, 0x00, 0xBC, 0x3C, 0x3D, 0xAC, 0xA1, 0x6C, 0xFB, 0xD6, 0x79, 0x25, + 0x4B, 0xAD, 0xF0, 0xCC, 0x64, 0xDA, 0x88, 0x3E, 0x29, 0xB8, 0x0F, 0x09, + 0xD3, 0x34, 0xDD, 0x33, 0xF5, 0x62, 0xD1, 0xE1, 0xCD, 0x19, 0xE9, 0xEE, + 0x18, 0x4F, 0x4C, 0x58, 0xAE, 0xE2, 0x1E, 0xD6, 0x0C, 0x5B, 0x15, 0x5A, + 0xD8, 0x3A, 0xB8, 0xC4, 0x18, 0x64, 0x1E, 0xE3, 0x33, 0xB2, 0xB5, 0x89, + 0x77, 0x4E, 0x0C, 0xBF, 0xD9, 0x94, 0x6B, 0x13, 0x97, 0x6F, 0x12, 0xA3, + 0xFE, 0x99, 0xA9, 0x04, 0xCC, 0x15, 0xEC, 0x60, 0x68, 0x36, 0xED, 0x08, + 0x7B, 0xB7, 0xF5, 0xBF, 0x93, 0xED, 0x66, 0x31, 0x83, 0x8C, 0xC6, 0x71, + 0x34, 0x87, 0x4E, 0x17, 0xEA, 0xAF, 0x8B, 0x91, 0x8D, 0x1C, 0x56, 0x41, + 0xAE, 0x22, 0x37, 0x5E, 0x37, 0xF2, 0x1D, 0xD9, 0xD1, 0x2D, 0x0D, 0x2F, + 0x69, 0x51, 0xA7, 0xBE, 0x66, 0xA6, 0x8A, 0x3A, 0x2A, 0xBD, 0xC7, 0x1A, + 0xB1, 0xE1, 0x14, 0xF0, 0xBE, 0x3A, 0x1D, 0xB9, 0xCF, 0x5B, 0xB1, 0x6A, + 0xFE, 0xB4, 0xB1, 0x46, 0x20, 0xA2, 0xFB, 0x1E, 0x3B, 0x70, 0xEF, 0x93, + 0x98, 0x7D, 0x8C, 0x73, 0x96, 0xF2, 0xC5, 0xEF, 0x85, 0x70, 0xAD, 0x29, + 0x26, 0xFC, 0x1E, 0x04, 0x3E, 0x1C, 0xA0, 0xD8, 0x0F, 0xCB, 0x52, 0x83, + 0x62, 0x7C, 0xEE, 0x8B, 0x53, 0x95, 0x90, 0xA9, 0x57, 0xA2, 0xEA, 0x61, + 0x05, 0xD8, 0xF9, 0x4D, 0xC4, 0x27, 0xFA, 0x6E, 0xAD, 0xED, 0xF9, 0xD7, + 0x51, 0xF7, 0x6B, 0xA5 +}; + +static const unsigned char TA582_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA583_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA583_RSA_N[] = { + 0x9A, 0x18, 0xCA, 0x4B, 0x94, 0x0D, 0x00, 0x2D, 0xAF, 0x03, 0x29, 0x8A, + 0xF0, 0x0F, 0x81, 0xC8, 0xAE, 0x4C, 0x19, 0x85, 0x1D, 0x08, 0x9F, 0xAB, + 0x29, 0x44, 0x85, 0xF3, 0x2F, 0x81, 0xAD, 0x32, 0x1E, 0x90, 0x46, 0xBF, + 0xA3, 0x86, 0x26, 0x1A, 0x1E, 0xFE, 0x7E, 0x1C, 0x18, 0x3A, 0x5C, 0x9C, + 0x60, 0x17, 0x2A, 0x3A, 0x74, 0x83, 0x33, 0x30, 0x7D, 0x61, 0x54, 0x11, + 0xCB, 0xED, 0xAB, 0xE0, 0xE6, 0xD2, 0xA2, 0x7E, 0xF5, 0x6B, 0x6F, 0x18, + 0xB7, 0x0A, 0x0B, 0x2D, 0xFD, 0xE9, 0x3E, 0xEF, 0x0A, 0xC6, 0xB3, 0x10, + 0xE9, 0xDC, 0xC2, 0x46, 0x17, 0xF8, 0x5D, 0xFD, 0xA4, 0xDA, 0xFF, 0x9E, + 0x49, 0x5A, 0x9C, 0xE6, 0x33, 0xE6, 0x24, 0x96, 0xF7, 0x3F, 0xBA, 0x5B, + 0x2B, 0x1C, 0x7A, 0x35, 0xC2, 0xD6, 0x67, 0xFE, 0xAB, 0x66, 0x50, 0x8B, + 0x6D, 0x28, 0x60, 0x2B, 0xEF, 0xD7, 0x60, 0xC3, 0xC7, 0x93, 0xBC, 0x8D, + 0x36, 0x91, 0xF3, 0x7F, 0xF8, 0xDB, 0x11, 0x13, 0xC4, 0x9C, 0x77, 0x76, + 0xC1, 0xAE, 0xB7, 0x02, 0x6A, 0x81, 0x7A, 0xA9, 0x45, 0x83, 0xE2, 0x05, + 0xE6, 0xB9, 0x56, 0xC1, 0x94, 0x37, 0x8F, 0x48, 0x71, 0x63, 0x22, 0xEC, + 0x17, 0x65, 0x07, 0x95, 0x8A, 0x4B, 0xDF, 0x8F, 0xC6, 0x5A, 0x0A, 0xE5, + 0xB0, 0xE3, 0x5F, 0x5E, 0x6B, 0x11, 0xAB, 0x0C, 0xF9, 0x85, 0xEB, 0x44, + 0xE9, 0xF8, 0x04, 0x73, 0xF2, 0xE9, 0xFE, 0x5C, 0x98, 0x8C, 0xF5, 0x73, + 0xAF, 0x6B, 0xB4, 0x7E, 0xCD, 0xD4, 0x5C, 0x02, 0x2B, 0x4C, 0x39, 0xE1, + 0xB2, 0x95, 0x95, 0x2D, 0x42, 0x87, 0xD7, 0xD5, 0xB3, 0x90, 0x43, 0xB7, + 0x6C, 0x13, 0xF1, 0xDE, 0xDD, 0xF6, 0xC4, 0xF8, 0x89, 0x3F, 0xD1, 0x75, + 0xF5, 0x92, 0xC3, 0x91, 0xD5, 0x8A, 0x88, 0xD0, 0x90, 0xEC, 0xDC, 0x6D, + 0xDE, 0x89, 0xC2, 0x65, 0x71, 0x96, 0x8B, 0x0D, 0x03, 0xFD, 0x9C, 0xBF, + 0x5B, 0x16, 0xAC, 0x92, 0xDB, 0xEA, 0xFE, 0x79, 0x7C, 0xAD, 0xEB, 0xAF, + 0xF7, 0x16, 0xCB, 0xDB, 0xCD, 0x25, 0x2B, 0xE5, 0x1F, 0xFB, 0x9A, 0x9F, + 0xE2, 0x51, 0xCC, 0x3A, 0x53, 0x0C, 0x48, 0xE6, 0x0E, 0xBD, 0xC9, 0xB4, + 0x76, 0x06, 0x52, 0xE6, 0x11, 0x13, 0x85, 0x72, 0x63, 0x03, 0x04, 0xE0, + 0x04, 0x36, 0x2B, 0x20, 0x19, 0x02, 0xE8, 0x74, 0xA7, 0x1F, 0xB6, 0xC9, + 0x56, 0x66, 0xF0, 0x75, 0x25, 0xDC, 0x67, 0xC1, 0x0E, 0x61, 0x60, 0x88, + 0xB3, 0x3E, 0xD1, 0xA8, 0xFC, 0xA3, 0xDA, 0x1D, 0xB0, 0xD1, 0xB1, 0x23, + 0x54, 0xDF, 0x44, 0x76, 0x6D, 0xED, 0x41, 0xD8, 0xC1, 0xB2, 0x22, 0xB6, + 0x53, 0x1C, 0xDF, 0x35, 0x1D, 0xDC, 0xA1, 0x77, 0x2A, 0x31, 0xE4, 0x2D, + 0xF5, 0xE5, 0xE5, 0xDB, 0xC8, 0xE0, 0xFF, 0xE5, 0x80, 0xD7, 0x0B, 0x63, + 0xA0, 0xFF, 0x33, 0xA1, 0x0F, 0xBA, 0x2C, 0x15, 0x15, 0xEA, 0x97, 0xB3, + 0xD2, 0xA2, 0xB5, 0xBE, 0xF2, 0x8C, 0x96, 0x1E, 0x1A, 0x8F, 0x1D, 0x6C, + 0xA4, 0x61, 0x37, 0xB9, 0x86, 0x73, 0x33, 0xD7, 0x97, 0x96, 0x9E, 0x23, + 0x7D, 0x82, 0xA4, 0x4C, 0x81, 0xE2, 0xA1, 0xD1, 0xBA, 0x67, 0x5F, 0x95, + 0x07, 0xA3, 0x27, 0x11, 0xEE, 0x16, 0x10, 0x7B, 0xBC, 0x45, 0x4A, 0x4C, + 0xB2, 0x04, 0xD2, 0xAB, 0xEF, 0xD5, 0xFD, 0x0C, 0x51, 0xCE, 0x50, 0x6A, + 0x08, 0x31, 0xF9, 0x91, 0xDA, 0x0C, 0x8F, 0x64, 0x5C, 0x03, 0xC3, 0x3A, + 0x8B, 0x20, 0x3F, 0x6E, 0x8D, 0x67, 0x3D, 0x3A, 0xD6, 0xFE, 0x7D, 0x5B, + 0x88, 0xC9, 0x5E, 0xFB, 0xCC, 0x61, 0xDC, 0x8B, 0x33, 0x77, 0xD3, 0x44, + 0x32, 0x35, 0x09, 0x62, 0x04, 0x92, 0x16, 0x10, 0xD8, 0x9E, 0x27, 0x47, + 0xFB, 0x3B, 0x21, 0xE3, 0xF8, 0xEB, 0x1D, 0x5B +}; + +static const unsigned char TA583_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA584_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA584_EC_Q[] = { + 0x04, 0x6B, 0xDA, 0x0D, 0x75, 0x35, 0x08, 0x31, 0x47, 0x05, 0xAE, 0x45, + 0x99, 0x55, 0xF1, 0x11, 0x13, 0x2E, 0x4A, 0xF8, 0x10, 0x31, 0x23, 0xA3, + 0x7E, 0x83, 0xD3, 0x7F, 0x28, 0x08, 0x3A, 0x26, 0x1A, 0x3A, 0xCF, 0x97, + 0x82, 0x1F, 0x80, 0xB7, 0x27, 0x09, 0x8F, 0xD1, 0x8E, 0x30, 0xC4, 0x0A, + 0x9B, 0x0E, 0xAC, 0x58, 0x04, 0xAB, 0xF7, 0x36, 0x7D, 0x94, 0x23, 0xA4, + 0x9B, 0x0A, 0x8A, 0x8B, 0xAB, 0xEB, 0xFD, 0x39, 0x25, 0x66, 0xF1, 0x5E, + 0xFE, 0x8C, 0xAE, 0x8D, 0x41, 0x79, 0x9D, 0x09, 0x60, 0xCE, 0x28, 0xA9, + 0xD3, 0x8A, 0x6D, 0xF3, 0xD6, 0x45, 0xD4, 0xF2, 0x98, 0x84, 0x38, 0x65, + 0xA0 +}; + +static const unsigned char TA585_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x31, + 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x65, + 0x72, 0x74, 0x61, 0x69, 0x6E, 0x6C, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x52, 0x31 +}; + +static const unsigned char TA585_RSA_N[] = { + 0xD0, 0x36, 0xD4, 0x1F, 0xEA, 0xDD, 0xAB, 0xE4, 0xD1, 0xB6, 0xE6, 0xFB, + 0x22, 0xC0, 0xDD, 0x13, 0x0D, 0x6A, 0x7B, 0x22, 0x13, 0x1C, 0x97, 0x3C, + 0x68, 0x63, 0x66, 0x32, 0x9C, 0x03, 0xB5, 0x8D, 0xA4, 0x81, 0x83, 0xDA, + 0x78, 0x30, 0x11, 0xCF, 0xDC, 0xB2, 0x2B, 0xBE, 0x92, 0xBF, 0x8E, 0xE4, + 0xC4, 0x13, 0xBE, 0xA4, 0x68, 0x4C, 0xDA, 0x02, 0x68, 0x16, 0x74, 0xBE, + 0xB2, 0xDD, 0x04, 0xE4, 0x6B, 0x2A, 0xDD, 0x37, 0x1F, 0x60, 0x2C, 0xDB, + 0xF5, 0xF7, 0xA1, 0x7C, 0x95, 0xB7, 0x0C, 0x70, 0x86, 0x2E, 0xF1, 0x3A, + 0xEF, 0x52, 0xF7, 0xCC, 0xD3, 0x9B, 0xF9, 0x8B, 0xBE, 0x0E, 0xDF, 0x31, + 0xB7, 0x9D, 0x68, 0x5C, 0x92, 0xA6, 0xF5, 0xE5, 0xF3, 0x0A, 0x34, 0xB5, + 0xFF, 0x7B, 0xA2, 0xE4, 0x87, 0xA1, 0xC6, 0xAF, 0x17, 0x00, 0xEF, 0x03, + 0x91, 0xED, 0xA9, 0x1C, 0x4E, 0x71, 0x3D, 0xD2, 0x8B, 0x6C, 0x89, 0xF4, + 0x78, 0x86, 0xE6, 0x6A, 0x49, 0xA0, 0xCE, 0xB5, 0xD2, 0xB0, 0xAB, 0x9B, + 0xF6, 0xF4, 0xD4, 0x2E, 0xE3, 0x72, 0xF9, 0x36, 0xC6, 0xEB, 0x15, 0xB7, + 0x25, 0x8C, 0x3A, 0xFC, 0x25, 0x0D, 0xB3, 0x22, 0x73, 0x21, 0x74, 0xC8, + 0x4A, 0x96, 0x61, 0x92, 0xF5, 0x2F, 0x0B, 0x18, 0xA5, 0xF4, 0xAD, 0xE2, + 0xEE, 0x41, 0xBD, 0x01, 0x79, 0xFA, 0x96, 0x8C, 0x8D, 0x17, 0x02, 0x30, + 0xB4, 0xF9, 0xAF, 0x78, 0x1A, 0x8C, 0xB4, 0x36, 0x10, 0x10, 0x07, 0x05, + 0x70, 0xD0, 0xF4, 0x31, 0x90, 0x8A, 0x51, 0xC5, 0x86, 0x26, 0x79, 0xB2, + 0x11, 0x88, 0x5E, 0xC5, 0xF0, 0x0A, 0x54, 0xCD, 0x49, 0xA6, 0xBF, 0x02, + 0x9C, 0xD2, 0x44, 0xA7, 0xED, 0xE3, 0x78, 0xEF, 0x46, 0x5E, 0x6D, 0x71, + 0xD1, 0x79, 0x70, 0x1C, 0x46, 0x5F, 0x51, 0xE9, 0xC9, 0x37, 0xDC, 0x5F, + 0x7E, 0x69, 0x7B, 0x41, 0xDF, 0x34, 0x45, 0xE0, 0x3B, 0x84, 0xF4, 0xA1, + 0x8A, 0x0A, 0x36, 0x9E, 0x37, 0xCC, 0x62, 0x52, 0xE1, 0x89, 0x0D, 0x28, + 0xF9, 0x7A, 0x23, 0xB1, 0x0D, 0x3D, 0x3D, 0x9A, 0xFD, 0x9D, 0x81, 0xEF, + 0x2C, 0x90, 0xC0, 0x7B, 0x44, 0x4E, 0xBB, 0x49, 0xE0, 0x0E, 0x4A, 0x56, + 0x92, 0xBC, 0xCB, 0xB5, 0xDD, 0x79, 0x17, 0x89, 0x91, 0xDE, 0x61, 0x89, + 0x74, 0x92, 0xA8, 0xE3, 0x32, 0x85, 0xBE, 0x4E, 0x85, 0xA4, 0x4B, 0x59, + 0xCB, 0x2B, 0xC5, 0x78, 0x8E, 0x71, 0x54, 0xD0, 0x02, 0x37, 0x99, 0x8C, + 0xE5, 0x49, 0xEA, 0xE0, 0x54, 0x72, 0xA4, 0x11, 0x06, 0x2F, 0x0B, 0x8C, + 0xC1, 0x5B, 0xBE, 0xB5, 0xA1, 0xB0, 0x53, 0x6E, 0x9C, 0xB8, 0x60, 0x91, + 0x1F, 0x59, 0x6B, 0xF9, 0x2D, 0xF4, 0x94, 0x0A, 0x97, 0xB5, 0xEC, 0xC5, + 0x76, 0x03, 0x54, 0x1B, 0x65, 0x52, 0xBA, 0x4C, 0x92, 0x56, 0x51, 0x35, + 0xA0, 0x40, 0xD8, 0x29, 0xDB, 0xAE, 0x52, 0x76, 0x3B, 0x2D, 0x30, 0x40, + 0x9B, 0x8A, 0xD0, 0x42, 0x56, 0xB4, 0xB7, 0x88, 0x01, 0xA4, 0x87, 0x3B, + 0x53, 0x96, 0xCD, 0xA3, 0x16, 0x8F, 0xF3, 0x66, 0xAA, 0x17, 0xB1, 0xC7, + 0x60, 0xE0, 0xC1, 0x43, 0x05, 0x0C, 0xEE, 0x9B, 0x5B, 0x60, 0x6F, 0x06, + 0x5C, 0x87, 0x5B, 0x27, 0xF9, 0x40, 0x11, 0x9E, 0x9C, 0x33, 0xC1, 0xB7, + 0xE5, 0x35, 0x57, 0x05, 0x7F, 0x27, 0xCE, 0x17, 0x20, 0x8C, 0x1C, 0xFC, + 0xF1, 0xFB, 0xDA, 0x31, 0x29, 0x49, 0xED, 0xF5, 0x0B, 0x84, 0xA7, 0x4F, + 0xC1, 0xF6, 0x4E, 0xC2, 0x28, 0x9C, 0xFA, 0xEE, 0xE0, 0xAF, 0x07, 0xFB, + 0x33, 0x11, 0x7A, 0x21, 0x4F, 0x0B, 0x21, 0x10, 0xB6, 0x40, 0x3A, 0xAB, + 0x22, 0x3A, 0x04, 0x9C, 0x8B, 0x9B, 0x84, 0x86, 0x72, 0x9A, 0xD2, 0xA7, + 0xA5, 0xC4, 0xB4, 0x75, 0x91, 0xA9, 0x2B, 0x23 +}; + +static const unsigned char TA585_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA586_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, + 0x36 +}; + +static const unsigned char TA586_EC_Q[] = { + 0x04, 0x76, 0xFA, 0x99, 0xA9, 0x6E, 0x20, 0xED, 0xF9, 0xD7, 0x77, 0xE3, + 0x07, 0x3B, 0xA8, 0xDB, 0x3D, 0x5F, 0x38, 0xE8, 0xAB, 0x55, 0xA6, 0x56, + 0x4F, 0xD6, 0x48, 0xEA, 0xEC, 0x7F, 0x2D, 0xAA, 0xC3, 0xB2, 0xC5, 0x79, + 0xEC, 0x99, 0x61, 0x7F, 0x10, 0x79, 0xC7, 0x02, 0x5A, 0xF9, 0x04, 0x37, + 0xF5, 0x34, 0x35, 0x2B, 0x77, 0xCE, 0x7F, 0x20, 0x8F, 0x52, 0xA3, 0x00, + 0x89, 0xEC, 0xD5, 0xA7, 0xA2, 0x6D, 0x5B, 0xE3, 0x4B, 0x92, 0x93, 0xA0, + 0x80, 0xF5, 0x01, 0x94, 0xDC, 0xF0, 0x68, 0x07, 0x1E, 0xCD, 0xEE, 0xFE, + 0x25, 0x52, 0xB5, 0x20, 0x43, 0x1C, 0x1B, 0xFE, 0xEB, 0x19, 0xCE, 0x43, + 0xA3 +}; + +static const unsigned char TA587_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x55, 0x43, 0x41, + 0x20, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, + 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74 +}; + +static const unsigned char TA587_RSA_N[] = { + 0xA9, 0x09, 0x07, 0x28, 0x13, 0x02, 0xB0, 0x99, 0xE0, 0x64, 0xAA, 0x1E, + 0x43, 0x16, 0x7A, 0x73, 0xB1, 0x91, 0xA0, 0x75, 0x3E, 0xA8, 0xFA, 0xE3, + 0x38, 0x00, 0x7A, 0xEC, 0x89, 0x6A, 0x20, 0x0F, 0x8B, 0xC5, 0xB0, 0x9B, + 0x33, 0x03, 0x5A, 0x86, 0xC6, 0x58, 0x86, 0xD5, 0xC1, 0x85, 0xBB, 0x4F, + 0xC6, 0x9C, 0x40, 0x4D, 0xCA, 0xBE, 0xEE, 0x69, 0x96, 0xB8, 0xAD, 0x81, + 0x30, 0x9A, 0x7C, 0x92, 0x05, 0xEB, 0x05, 0x2B, 0x9A, 0x48, 0xD0, 0xB8, + 0x76, 0x3E, 0x96, 0xC8, 0x20, 0xBB, 0xD2, 0xB0, 0xF1, 0x8F, 0xD8, 0xAC, + 0x45, 0x46, 0xFF, 0xAA, 0x67, 0x60, 0xB4, 0x77, 0x7E, 0x6A, 0x1F, 0x3C, + 0x1A, 0x52, 0x7A, 0x04, 0x3D, 0x07, 0x3C, 0x85, 0x0D, 0x84, 0xD0, 0x1F, + 0x76, 0x0A, 0xF7, 0x6A, 0x14, 0xDF, 0x72, 0xE3, 0x34, 0x7C, 0x57, 0x4E, + 0x56, 0x01, 0x3E, 0x79, 0xF1, 0xAA, 0x29, 0x3B, 0x6C, 0xFA, 0xF8, 0x8F, + 0x6D, 0x4D, 0xC8, 0x35, 0xDF, 0xAE, 0xEB, 0xDC, 0x24, 0xEE, 0x79, 0x45, + 0xA7, 0x85, 0xB6, 0x05, 0x88, 0xDE, 0x88, 0x5D, 0x25, 0x7C, 0x97, 0x64, + 0x67, 0x09, 0xD9, 0xBF, 0x5A, 0x15, 0x05, 0x86, 0xF3, 0x09, 0x1E, 0xEC, + 0x58, 0x32, 0x33, 0x11, 0xF3, 0x77, 0x64, 0xB0, 0x76, 0x1F, 0xE4, 0x10, + 0x35, 0x17, 0x1B, 0xF2, 0x0E, 0xB1, 0x6C, 0xA4, 0x2A, 0xA3, 0x73, 0xFC, + 0x09, 0x1F, 0x1E, 0x32, 0x19, 0x53, 0x11, 0xE7, 0xD9, 0xB3, 0x2C, 0x2E, + 0x76, 0x2E, 0xA1, 0xA3, 0xDE, 0x7E, 0x6A, 0x88, 0x09, 0xE8, 0xF2, 0x07, + 0x8A, 0xF8, 0xB2, 0xCD, 0x10, 0xE7, 0xE2, 0x73, 0x40, 0x93, 0xBB, 0x08, + 0xD1, 0x3F, 0xE1, 0xFC, 0x0B, 0x94, 0xB3, 0x25, 0xEF, 0x7C, 0xA6, 0xD7, + 0xD1, 0xAF, 0x9F, 0xFF, 0x96, 0x9A, 0xF5, 0x91, 0x7B, 0x98, 0x0B, 0x77, + 0xD4, 0x7E, 0xE8, 0x07, 0xD2, 0x62, 0xB5, 0x95, 0x39, 0xE3, 0xF3, 0xF1, + 0x6D, 0x0F, 0x0E, 0x65, 0x84, 0x8A, 0x63, 0x54, 0xC5, 0x80, 0xB6, 0xE0, + 0x9E, 0x4B, 0x7D, 0x47, 0x26, 0xA7, 0x01, 0x08, 0x5D, 0xD1, 0x88, 0x9E, + 0xD7, 0xC3, 0x32, 0x44, 0xFA, 0x82, 0x4A, 0x0A, 0x68, 0x54, 0x7F, 0x38, + 0x53, 0x03, 0xCC, 0xA4, 0x00, 0x33, 0x64, 0x51, 0x59, 0x0B, 0xA3, 0x82, + 0x91, 0x7A, 0x5E, 0xEC, 0x16, 0xC2, 0xF3, 0x2A, 0xE6, 0x62, 0xDA, 0x2A, + 0xDB, 0x59, 0x62, 0x10, 0x25, 0x4A, 0x2A, 0x81, 0x0B, 0x47, 0x07, 0x43, + 0x06, 0x70, 0x87, 0xD2, 0xFA, 0x93, 0x11, 0x29, 0x7A, 0x48, 0x4D, 0xEB, + 0x94, 0xC7, 0x70, 0x4D, 0xAF, 0x67, 0xD5, 0x51, 0xB1, 0x80, 0x20, 0x01, + 0x01, 0xB4, 0x7A, 0x08, 0xA6, 0x90, 0x7F, 0x4E, 0xE0, 0xEF, 0x07, 0x41, + 0x87, 0xAF, 0x6A, 0xA5, 0x5E, 0x8B, 0xFB, 0xCF, 0x50, 0xB2, 0x9A, 0x54, + 0xAF, 0xC3, 0x89, 0xBA, 0x58, 0x2D, 0xF5, 0x30, 0x98, 0xB1, 0x36, 0x72, + 0x39, 0x7E, 0x49, 0x04, 0xFD, 0x29, 0xA7, 0x4C, 0x79, 0xE4, 0x05, 0x57, + 0xDB, 0x94, 0xB9, 0x16, 0x53, 0x8D, 0x46, 0xB3, 0x1D, 0x95, 0x61, 0x57, + 0x56, 0x7F, 0xAF, 0xF0, 0x16, 0x5B, 0x61, 0x58, 0x6F, 0x36, 0x50, 0x11, + 0x0B, 0xD8, 0xAC, 0x2B, 0x95, 0x16, 0x1A, 0x0E, 0x1F, 0x08, 0xCD, 0x36, + 0x34, 0x65, 0x10, 0x62, 0x66, 0xD5, 0x80, 0x5F, 0x14, 0x20, 0x5F, 0x2D, + 0x0C, 0xA0, 0x78, 0x0A, 0x68, 0xD6, 0x2C, 0xD7, 0xE9, 0x6F, 0x2B, 0xD2, + 0x4A, 0x05, 0x93, 0xFC, 0x9E, 0x6F, 0x6B, 0x67, 0xFF, 0x88, 0xF1, 0x4E, + 0xA5, 0x69, 0x4A, 0x52, 0x37, 0x05, 0xEA, 0xC6, 0x16, 0x8D, 0xD2, 0xC4, + 0x99, 0xD1, 0x82, 0x2B, 0x3B, 0xBA, 0x35, 0x75, 0xF7, 0x51, 0x51, 0x58, + 0xF3, 0xC8, 0x07, 0xDD, 0xE4, 0xB4, 0x03, 0x7F +}; + +static const unsigned char TA587_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA588_DN[] = { + 0x30, 0x41, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x13, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x65, 0x6D, 0x69, 0x75, 0x6D +}; + +static const unsigned char TA588_RSA_N[] = { + 0xC4, 0x12, 0xDF, 0xA9, 0x5F, 0xFE, 0x41, 0xDD, 0xDD, 0xF5, 0x9F, 0x8A, + 0xE3, 0xF6, 0xAC, 0xE1, 0x3C, 0x78, 0x9A, 0xBC, 0xD8, 0xF0, 0x7F, 0x7A, + 0xA0, 0x33, 0x2A, 0xDC, 0x8D, 0x20, 0x5B, 0xAE, 0x2D, 0x6F, 0xE7, 0x93, + 0xD9, 0x36, 0x70, 0x6A, 0x68, 0xCF, 0x8E, 0x51, 0xA3, 0x85, 0x5B, 0x67, + 0x04, 0xA0, 0x10, 0x24, 0x6F, 0x5D, 0x28, 0x82, 0xC1, 0x97, 0x57, 0xD8, + 0x48, 0x29, 0x13, 0xB6, 0xE1, 0xBE, 0x91, 0x4D, 0xDF, 0x85, 0x0C, 0x53, + 0x18, 0x9A, 0x1E, 0x24, 0xA2, 0x4F, 0x8F, 0xF0, 0xA2, 0x85, 0x0B, 0xCB, + 0xF4, 0x29, 0x7F, 0xD2, 0xA4, 0x58, 0xEE, 0x26, 0x4D, 0xC9, 0xAA, 0xA8, + 0x7B, 0x9A, 0xD9, 0xFA, 0x38, 0xDE, 0x44, 0x57, 0x15, 0xE5, 0xF8, 0x8C, + 0xC8, 0xD9, 0x48, 0xE2, 0x0D, 0x16, 0x27, 0x1D, 0x1E, 0xC8, 0x83, 0x85, + 0x25, 0xB7, 0xBA, 0xAA, 0x55, 0x41, 0xCC, 0x03, 0x22, 0x4B, 0x2D, 0x91, + 0x8D, 0x8B, 0xE6, 0x89, 0xAF, 0x66, 0xC7, 0xE9, 0xFF, 0x2B, 0xE9, 0x3C, + 0xAC, 0xDA, 0xD2, 0xB3, 0xC3, 0xE1, 0x68, 0x9C, 0x89, 0xF8, 0x7A, 0x00, + 0x56, 0xDE, 0xF4, 0x55, 0x95, 0x6C, 0xFB, 0xBA, 0x64, 0xDD, 0x62, 0x8B, + 0xDF, 0x0B, 0x77, 0x32, 0xEB, 0x62, 0xCC, 0x26, 0x9A, 0x9B, 0xBB, 0xAA, + 0x62, 0x83, 0x4C, 0xB4, 0x06, 0x7A, 0x30, 0xC8, 0x29, 0xBF, 0xED, 0x06, + 0x4D, 0x97, 0xB9, 0x1C, 0xC4, 0x31, 0x2B, 0xD5, 0x5F, 0xBC, 0x53, 0x12, + 0x17, 0x9C, 0x99, 0x57, 0x29, 0x66, 0x77, 0x61, 0x21, 0x31, 0x07, 0x2E, + 0x25, 0x49, 0x9D, 0x18, 0xF2, 0xEE, 0xF3, 0x2B, 0x71, 0x8C, 0xB5, 0xBA, + 0x39, 0x07, 0x49, 0x77, 0xFC, 0xEF, 0x2E, 0x92, 0x90, 0x05, 0x8D, 0x2D, + 0x2F, 0x77, 0x7B, 0xEF, 0x43, 0xBF, 0x35, 0xBB, 0x9A, 0xD8, 0xF9, 0x73, + 0xA7, 0x2C, 0xF2, 0xD0, 0x57, 0xEE, 0x28, 0x4E, 0x26, 0x5F, 0x8F, 0x90, + 0x68, 0x09, 0x2F, 0xB8, 0xF8, 0xDC, 0x06, 0xE9, 0x2E, 0x9A, 0x3E, 0x51, + 0xA7, 0xD1, 0x22, 0xC4, 0x0A, 0xA7, 0x38, 0x48, 0x6C, 0xB3, 0xF9, 0xFF, + 0x7D, 0xAB, 0x86, 0x57, 0xE3, 0xBA, 0xD6, 0x85, 0x78, 0x77, 0xBA, 0x43, + 0xEA, 0x48, 0x7F, 0xF6, 0xD8, 0xBE, 0x23, 0x6D, 0x1E, 0xBF, 0xD1, 0x36, + 0x6C, 0x58, 0x5C, 0xF1, 0xEE, 0xA4, 0x19, 0x54, 0x1A, 0xF5, 0x03, 0xD2, + 0x76, 0xE6, 0xE1, 0x8C, 0xBD, 0x3C, 0xB3, 0xD3, 0x48, 0x4B, 0xE2, 0xC8, + 0xF8, 0x7F, 0x92, 0xA8, 0x76, 0x46, 0x9C, 0x42, 0x65, 0x3E, 0xA4, 0x1E, + 0xC1, 0x07, 0x03, 0x5A, 0x46, 0x2D, 0xB8, 0x97, 0xF3, 0xB7, 0xD5, 0xB2, + 0x55, 0x21, 0xEF, 0xBA, 0xDC, 0x4C, 0x00, 0x97, 0xFB, 0x14, 0x95, 0x27, + 0x33, 0xBF, 0xE8, 0x43, 0x47, 0x46, 0xD2, 0x08, 0x99, 0x16, 0x60, 0x3B, + 0x9A, 0x7E, 0xD2, 0xE6, 0xED, 0x38, 0xEA, 0xEC, 0x01, 0x1E, 0x3C, 0x48, + 0x56, 0x49, 0x09, 0xC7, 0x4C, 0x37, 0x00, 0x9E, 0x88, 0x0E, 0xC0, 0x73, + 0xE1, 0x6F, 0x66, 0xE9, 0x72, 0x47, 0x30, 0x3E, 0x10, 0xE5, 0x0B, 0x03, + 0xC9, 0x9A, 0x42, 0x00, 0x6C, 0xC5, 0x94, 0x7E, 0x61, 0xC4, 0x8A, 0xDF, + 0x7F, 0x82, 0x1A, 0x0B, 0x59, 0xC4, 0x59, 0x32, 0x77, 0xB3, 0xBC, 0x60, + 0x69, 0x56, 0x39, 0xFD, 0xB4, 0x06, 0x7B, 0x2C, 0xD6, 0x64, 0x36, 0xD9, + 0xBD, 0x48, 0xED, 0x84, 0x1F, 0x7E, 0xA5, 0x22, 0x8F, 0x2A, 0xB8, 0x42, + 0xF4, 0x82, 0xB7, 0xD4, 0x53, 0x90, 0x78, 0x4E, 0x2D, 0x1A, 0xFD, 0x81, + 0x6F, 0x44, 0xD7, 0x3B, 0x01, 0x74, 0x96, 0x42, 0xE0, 0x00, 0xE2, 0x2E, + 0x6B, 0xEA, 0xC5, 0xEE, 0x72, 0xAC, 0xBB, 0xBF, 0xFE, 0xEA, 0xAA, 0xA8, + 0xF8, 0xDC, 0xF6, 0xB2, 0x79, 0x8A, 0xB6, 0x67 +}; + +static const unsigned char TA588_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA589_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x1C, + 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x43, 0x31 +}; + +static const unsigned char TA589_RSA_N[] = { + 0xCF, 0xEB, 0xA9, 0xB9, 0xF1, 0x99, 0x05, 0xCC, 0xD8, 0x28, 0x21, 0x4A, + 0xF3, 0x73, 0x34, 0x51, 0x84, 0x56, 0x10, 0xF5, 0xA0, 0x4F, 0x2C, 0x12, + 0xE3, 0xFA, 0x13, 0x9A, 0x27, 0xD0, 0xCF, 0xF9, 0x79, 0x1A, 0x74, 0x5F, + 0x1D, 0x79, 0x39, 0xFC, 0x5B, 0xF8, 0x70, 0x8E, 0xE0, 0x92, 0x52, 0xF7, + 0xE4, 0x25, 0xF9, 0x54, 0x83, 0xD9, 0x1D, 0xD3, 0xC8, 0x5A, 0x85, 0x3F, + 0x5E, 0xC7, 0xB6, 0x07, 0xEE, 0x3E, 0xC0, 0xCE, 0x9A, 0xAF, 0xAC, 0x56, + 0x42, 0x2A, 0x39, 0x25, 0x70, 0xD6, 0xBF, 0xB5, 0x7B, 0x36, 0xAD, 0xAC, + 0xF6, 0x73, 0xDC, 0xCD, 0xD7, 0x1D, 0x8A, 0x83, 0xA5, 0xFB, 0x2B, 0x90, + 0x15, 0x37, 0x6B, 0x1C, 0x26, 0x47, 0xDC, 0x3B, 0x29, 0x56, 0x93, 0x6A, + 0xB3, 0xC1, 0x6A, 0x3A, 0x9D, 0x3D, 0xF5, 0xC1, 0x97, 0x38, 0x58, 0x05, + 0x8B, 0x1C, 0x11, 0xE3, 0xE4, 0xB4, 0xB8, 0x5D, 0x85, 0x1D, 0x83, 0xFE, + 0x78, 0x5F, 0x0B, 0x45, 0x68, 0x18, 0x48, 0xA5, 0x46, 0x73, 0x34, 0x3B, + 0xFE, 0x0F, 0xC8, 0x76, 0xBB, 0xC7, 0x18, 0xF3, 0x05, 0xD1, 0x86, 0xF3, + 0x85, 0xED, 0xE7, 0xB9, 0xD9, 0x32, 0xAD, 0x55, 0x88, 0xCE, 0xA6, 0xB6, + 0x91, 0xB0, 0x4F, 0xAC, 0x7E, 0x15, 0x23, 0x96, 0xF6, 0x3F, 0xF0, 0x20, + 0x34, 0x16, 0xDE, 0x0A, 0xC6, 0xC4, 0x04, 0x45, 0x79, 0x7F, 0xA7, 0xFD, + 0xBE, 0xD2, 0xA9, 0xA5, 0xAF, 0x9C, 0xC5, 0x23, 0x2A, 0xF7, 0x3C, 0x21, + 0x6C, 0xBD, 0xAF, 0x8F, 0x4E, 0xC5, 0x3A, 0xB2, 0xF3, 0x34, 0x12, 0xFC, + 0xDF, 0x80, 0x1A, 0x49, 0xA4, 0xD4, 0xA9, 0x95, 0xF7, 0x9E, 0x89, 0x5E, + 0xA2, 0x89, 0xAC, 0x94, 0xCB, 0xA8, 0x68, 0x9B, 0xAF, 0x8A, 0x65, 0x27, + 0xCD, 0x89, 0xEE, 0xDD, 0x8C, 0xB5, 0x6B, 0x29, 0x70, 0x43, 0xA0, 0x69, + 0x0B, 0xE4, 0xB9, 0x0F +}; + +static const unsigned char TA589_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA590_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x36, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA590_RSA_N[] = { + 0x95, 0x07, 0xE8, 0x73, 0xCA, 0x66, 0xF9, 0xEC, 0x14, 0xCA, 0x7B, 0x3C, + 0xF7, 0x0D, 0x08, 0xF1, 0xB4, 0x45, 0x0B, 0x2C, 0x82, 0xB4, 0x48, 0xC6, + 0xEB, 0x5B, 0x3C, 0xAE, 0x83, 0xB8, 0x41, 0x92, 0x33, 0x14, 0xA4, 0x6F, + 0x7F, 0xE9, 0x2A, 0xCC, 0xC6, 0xB0, 0x88, 0x6B, 0xC5, 0xB6, 0x89, 0xD1, + 0xC6, 0xB2, 0xFF, 0x14, 0xCE, 0x51, 0x14, 0x21, 0xEC, 0x4A, 0xDD, 0x1B, + 0x5A, 0xC6, 0xD6, 0x87, 0xEE, 0x4D, 0x3A, 0x15, 0x06, 0xED, 0x64, 0x66, + 0x0B, 0x92, 0x80, 0xCA, 0x44, 0xDE, 0x73, 0x94, 0x4E, 0xF3, 0xA7, 0x89, + 0x7F, 0x4F, 0x78, 0x63, 0x08, 0xC8, 0x12, 0x50, 0x6D, 0x42, 0x66, 0x2F, + 0x4D, 0xB9, 0x79, 0x28, 0x4D, 0x52, 0x1A, 0x8A, 0x1A, 0x80, 0xB7, 0x19, + 0x81, 0x0E, 0x7E, 0xC4, 0x8A, 0xBC, 0x64, 0x4C, 0x21, 0x1C, 0x43, 0x68, + 0xD7, 0x3D, 0x3C, 0x8A, 0xC5, 0xB2, 0x66, 0xD5, 0x90, 0x9A, 0xB7, 0x31, + 0x06, 0xC5, 0xBE, 0xE2, 0x6D, 0x32, 0x06, 0xA6, 0x1E, 0xF9, 0xB9, 0xEB, + 0xAA, 0xA3, 0xB8, 0xBF, 0xBE, 0x82, 0x63, 0x50, 0xD0, 0xF0, 0x18, 0x89, + 0xDF, 0xE4, 0x0F, 0x79, 0xF5, 0xEA, 0xA2, 0x1F, 0x2A, 0xD2, 0x70, 0x2E, + 0x7B, 0xE7, 0xBC, 0x93, 0xBB, 0x6D, 0x53, 0xE2, 0x48, 0x7C, 0x8C, 0x10, + 0x07, 0x38, 0xFF, 0x66, 0xB2, 0x77, 0x61, 0x7E, 0xE0, 0xEA, 0x8C, 0x3C, + 0xAA, 0xB4, 0xA4, 0xF6, 0xF3, 0x95, 0x4A, 0x12, 0x07, 0x6D, 0xFD, 0x8C, + 0xB2, 0x89, 0xCF, 0xD0, 0xA0, 0x61, 0x77, 0xC8, 0x58, 0x74, 0xB0, 0xD4, + 0x23, 0x3A, 0xF7, 0x5D, 0x3A, 0xCA, 0xA2, 0xDB, 0x9D, 0x09, 0xDE, 0x5D, + 0x44, 0x2D, 0x90, 0xF1, 0x81, 0xCD, 0x57, 0x92, 0xFA, 0x7E, 0xBC, 0x50, + 0x04, 0x63, 0x34, 0xDF, 0x6B, 0x93, 0x18, 0xBE, 0x6B, 0x36, 0xB2, 0x39, + 0xE4, 0xAC, 0x24, 0x36, 0xB7, 0xF0, 0xEF, 0xB6, 0x1C, 0x13, 0x57, 0x93, + 0xB6, 0xDE, 0xB2, 0xF8, 0xE2, 0x85, 0xB7, 0x73, 0xA2, 0xB8, 0x35, 0xAA, + 0x45, 0xF2, 0xE0, 0x9D, 0x36, 0xA1, 0x6F, 0x54, 0x8A, 0xF1, 0x72, 0x56, + 0x6E, 0x2E, 0x88, 0xC5, 0x51, 0x42, 0x44, 0x15, 0x94, 0xEE, 0xA3, 0xC5, + 0x38, 0x96, 0x9B, 0x4E, 0x4E, 0x5A, 0x0B, 0x47, 0xF3, 0x06, 0x36, 0x49, + 0x77, 0x30, 0xBC, 0x71, 0x37, 0xE5, 0xA6, 0xEC, 0x21, 0x08, 0x75, 0xFC, + 0xE6, 0x61, 0x16, 0x3F, 0x77, 0xD5, 0xD9, 0x91, 0x97, 0x84, 0x0A, 0x6C, + 0xD4, 0x02, 0x4D, 0x74, 0xC0, 0x14, 0xED, 0xFD, 0x39, 0xFB, 0x83, 0xF2, + 0x5E, 0x14, 0xA1, 0x04, 0xB0, 0x0B, 0xE9, 0xFE, 0xEE, 0x8F, 0xE1, 0x6E, + 0x0B, 0xB2, 0x08, 0xB3, 0x61, 0x66, 0x09, 0x6A, 0xB1, 0x06, 0x3A, 0x65, + 0x96, 0x59, 0xC0, 0xF0, 0x35, 0xFD, 0xC9, 0xDA, 0x28, 0x8D, 0x1A, 0x11, + 0x87, 0x70, 0x81, 0x0A, 0xA8, 0x9A, 0x75, 0x1D, 0x9E, 0x3A, 0x86, 0x05, + 0x00, 0x9E, 0xDB, 0x80, 0xD6, 0x25, 0xF9, 0xDC, 0x05, 0x9E, 0x27, 0x59, + 0x4C, 0x76, 0x39, 0x5B, 0xEA, 0xF9, 0xA5, 0xA1, 0xD8, 0x83, 0x0F, 0xD1, + 0xFF, 0xDF, 0x30, 0x11, 0xF9, 0x85, 0xCF, 0x33, 0x48, 0xF5, 0xCA, 0x6D, + 0x64, 0x14, 0x2C, 0x7A, 0x58, 0x4F, 0xD3, 0x4B, 0x08, 0x49, 0xC5, 0x95, + 0x64, 0x1A, 0x63, 0x0E, 0x79, 0x3D, 0xF5, 0xB3, 0x8C, 0xCA, 0x58, 0xAD, + 0x9C, 0x42, 0x45, 0x79, 0x6E, 0x0E, 0x87, 0x19, 0x5C, 0x54, 0xB1, 0x65, + 0xB6, 0xBF, 0x8C, 0x9B, 0xDC, 0x13, 0xE9, 0x0D, 0x6F, 0xB8, 0x2E, 0xDC, + 0x67, 0x6E, 0xC9, 0x8B, 0x11, 0xB5, 0x84, 0x14, 0x8A, 0x00, 0x19, 0x70, + 0x83, 0x79, 0x91, 0x97, 0x91, 0xD4, 0x1A, 0x27, 0xBF, 0x37, 0x1E, 0x32, + 0x07, 0xD8, 0x14, 0x63, 0x3C, 0x28, 0x4C, 0xAF +}; + +static const unsigned char TA590_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA591_DN[] = { + 0x30, 0x81, 0xA6, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x40, 0x30, 0x3E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x37, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, + 0x35 +}; + +static const unsigned char TA591_RSA_N[] = { + 0xC2, 0xF8, 0xA9, 0x3F, 0x1B, 0x89, 0xFC, 0x3C, 0x3C, 0x04, 0x5D, 0x3D, + 0x90, 0x36, 0xB0, 0x91, 0x3A, 0x79, 0x3C, 0x66, 0x5A, 0xEF, 0x6D, 0x39, + 0x01, 0x49, 0x1A, 0xB4, 0xB7, 0xCF, 0x7F, 0x4D, 0x23, 0x53, 0xB7, 0x90, + 0x00, 0xE3, 0x13, 0x2A, 0x28, 0xA6, 0x31, 0xF1, 0x91, 0x00, 0xE3, 0x28, + 0xEC, 0xAE, 0x21, 0x41, 0xCE, 0x1F, 0xDA, 0xFD, 0x7D, 0x12, 0x5B, 0x01, + 0x83, 0x0F, 0xB9, 0xB0, 0x5F, 0x99, 0xE1, 0xF2, 0x12, 0x83, 0x80, 0x4D, + 0x06, 0x3E, 0xDF, 0xAC, 0xAF, 0xE7, 0xA1, 0x88, 0x6B, 0x31, 0xAF, 0xF0, + 0x8B, 0xD0, 0x18, 0x33, 0xB8, 0xDB, 0x45, 0x6A, 0x34, 0xF4, 0x02, 0x80, + 0x24, 0x28, 0x0A, 0x02, 0x15, 0x95, 0x5E, 0x76, 0x2A, 0x0D, 0x99, 0x3A, + 0x14, 0x5B, 0xF6, 0xCB, 0xCB, 0x53, 0xBC, 0x13, 0x4D, 0x01, 0x88, 0x37, + 0x94, 0x25, 0x1B, 0x42, 0xBC, 0x22, 0xD8, 0x8E, 0xA3, 0x96, 0x5E, 0x3A, + 0xD9, 0x32, 0xDB, 0x3E, 0xE8, 0xF0, 0x10, 0x65, 0xED, 0x74, 0xE1, 0x2F, + 0xA7, 0x7C, 0xAF, 0x27, 0x34, 0xBB, 0x29, 0x7D, 0x9B, 0xB6, 0xCF, 0x09, + 0xC8, 0xE5, 0xD3, 0x0A, 0xFC, 0x88, 0x65, 0x65, 0x74, 0x0A, 0xDC, 0x73, + 0x1C, 0x5C, 0xCD, 0x40, 0xB1, 0x1C, 0xD4, 0xB6, 0x84, 0x8C, 0x4C, 0x50, + 0xCF, 0x68, 0x8E, 0xA8, 0x59, 0xAE, 0xC2, 0x27, 0x4E, 0x82, 0xA2, 0x35, + 0xDD, 0x14, 0xF4, 0x1F, 0xFF, 0xB2, 0x77, 0xD5, 0x87, 0x2F, 0xAA, 0x6E, + 0x7D, 0x24, 0x27, 0xE7, 0xC6, 0xCB, 0x26, 0xE6, 0xE5, 0xFE, 0x67, 0x07, + 0x63, 0xD8, 0x45, 0x0D, 0xDD, 0x3A, 0x59, 0x65, 0x39, 0x58, 0x7A, 0x92, + 0x99, 0x72, 0x3D, 0x9C, 0x84, 0x5E, 0x88, 0x21, 0xB8, 0xD5, 0xF4, 0x2C, + 0xFC, 0xD9, 0x70, 0x52, 0x4F, 0x78, 0xB8, 0xBD, 0x3C, 0x2B, 0x8B, 0x95, + 0x98, 0xF5, 0xB3, 0xD1, 0x68, 0xCF, 0x20, 0x14, 0x7E, 0x4C, 0x5C, 0x5F, + 0xE7, 0x8B, 0xE5, 0xF5, 0x35, 0x81, 0x19, 0x37, 0xD7, 0x11, 0x08, 0xB7, + 0x66, 0xBE, 0xD3, 0x4A, 0xCE, 0x83, 0x57, 0x00, 0x3A, 0xC3, 0x81, 0xF8, + 0x17, 0xCB, 0x92, 0x36, 0x5D, 0xD1, 0xA3, 0xD8, 0x75, 0x1B, 0xE1, 0x8B, + 0x27, 0xEA, 0x7A, 0x48, 0x41, 0xFD, 0x45, 0x19, 0x06, 0xAD, 0x27, 0x99, + 0x4E, 0xC1, 0x70, 0x47, 0xDD, 0xB5, 0x9F, 0x81, 0x53, 0x12, 0xE5, 0xB1, + 0x8C, 0x48, 0x5D, 0x31, 0x43, 0x17, 0xE3, 0x8C, 0xC6, 0x7A, 0x63, 0x96, + 0x4B, 0x29, 0x30, 0x4E, 0x84, 0x4E, 0x62, 0x19, 0x5E, 0x3C, 0xCE, 0x97, + 0x90, 0xA5, 0x7F, 0x01, 0xEB, 0x9D, 0xE0, 0xF8, 0x8B, 0x89, 0xDD, 0x25, + 0x98, 0x3D, 0x92, 0xB6, 0x7E, 0xEF, 0xD9, 0xF1, 0x51, 0x51, 0x7D, 0x2D, + 0x26, 0xC8, 0x69, 0x59, 0x61, 0xE0, 0xAC, 0x6A, 0xB8, 0x2A, 0x36, 0x11, + 0x04, 0x7A, 0x50, 0xBD, 0x32, 0x84, 0xBE, 0x2F, 0xDC, 0x72, 0xD5, 0xD7, + 0x1D, 0x16, 0x47, 0xE4, 0x47, 0x66, 0x20, 0x3F, 0xF4, 0x96, 0xC5, 0xAF, + 0x8E, 0x01, 0x7A, 0xA5, 0x0F, 0x7A, 0x64, 0xF5, 0x0D, 0x18, 0x87, 0xD9, + 0xAE, 0x88, 0xD5, 0xFA, 0x84, 0xC1, 0x3A, 0xC0, 0x69, 0x28, 0x2D, 0xF2, + 0x0D, 0x68, 0x51, 0xAA, 0xE3, 0xA5, 0x77, 0xC6, 0xA4, 0x90, 0x0E, 0xA1, + 0x37, 0x8B, 0x31, 0x23, 0x47, 0xC1, 0x09, 0x08, 0xEB, 0x6E, 0xF7, 0x78, + 0x9B, 0xD7, 0x82, 0xFC, 0x84, 0x20, 0x99, 0x49, 0x19, 0xB6, 0x12, 0x46, + 0xB1, 0xFB, 0x45, 0x55, 0x16, 0xA9, 0xA3, 0x65, 0xAC, 0x9C, 0x07, 0x0F, + 0xEA, 0x6B, 0xDC, 0x1F, 0x2E, 0x06, 0x72, 0xEC, 0x86, 0x88, 0x12, 0xE4, + 0x2D, 0xDB, 0x5F, 0x05, 0x2F, 0xE4, 0xF0, 0x03, 0xD3, 0x26, 0x33, 0xE7, + 0x80, 0xC2, 0xCD, 0x42, 0xA1, 0x17, 0x34, 0x0B +}; + +static const unsigned char TA591_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA592_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x33 +}; + +static const unsigned char TA592_EC_Q[] = { + 0x04, 0xDD, 0xA7, 0xD9, 0xBB, 0x8A, 0xB8, 0x0B, 0xFB, 0x0B, 0x7F, 0x21, + 0xD2, 0xF0, 0xBE, 0xBE, 0x73, 0xF3, 0x33, 0x5D, 0x1A, 0xBC, 0x34, 0xEA, + 0xDE, 0xC6, 0x9B, 0xBC, 0xD0, 0x95, 0xF6, 0xF0, 0xCC, 0xD0, 0x0B, 0xBA, + 0x61, 0x5B, 0x51, 0x46, 0x7E, 0x9E, 0x2D, 0x9F, 0xEE, 0x8E, 0x63, 0x0C, + 0x17, 0xEC, 0x07, 0x70, 0xF5, 0xCF, 0x84, 0x2E, 0x40, 0x83, 0x9C, 0xE8, + 0x3F, 0x41, 0x6D, 0x3B, 0xAD, 0xD3, 0xA4, 0x14, 0x59, 0x36, 0x78, 0x9D, + 0x03, 0x43, 0xEE, 0x10, 0x13, 0x6C, 0x72, 0xDE, 0xAE, 0x88, 0xA7, 0xA1, + 0x6B, 0xB5, 0x43, 0xCE, 0x67, 0xDC, 0x23, 0xFF, 0x03, 0x1C, 0xA3, 0xE2, + 0x3E +}; + +static const unsigned char TA593_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA593_EC_Q[] = { + 0x04, 0xCE, 0xBF, 0xFE, 0x57, 0xA8, 0xBF, 0xD5, 0xAA, 0xF7, 0x10, 0x9A, + 0xCD, 0xBC, 0xD1, 0x11, 0xA2, 0xBD, 0x67, 0x42, 0xCC, 0x90, 0xEB, 0x15, + 0x18, 0x90, 0xD9, 0xA2, 0xCD, 0x0C, 0x2A, 0x25, 0xEB, 0x3E, 0x4F, 0xCE, + 0xB5, 0xD2, 0x8F, 0x0F, 0xF3, 0x35, 0xDA, 0x43, 0x8B, 0x02, 0x80, 0xBE, + 0x6F, 0x51, 0x24, 0x1D, 0x0F, 0x6B, 0x2B, 0xCA, 0x9F, 0xC2, 0x6F, 0x50, + 0x32, 0xE5, 0x37, 0x20, 0xB6, 0x20, 0xFF, 0x88, 0x0D, 0x0F, 0x6D, 0x49, + 0xBB, 0xDB, 0x06, 0xA4, 0x87, 0x90, 0x92, 0x94, 0xF4, 0x09, 0xD0, 0xCF, + 0x7F, 0xC8, 0x80, 0x0B, 0xC1, 0x97, 0xB3, 0xBB, 0x35, 0x27, 0xC9, 0xC2, + 0x1B +}; + +static const unsigned char TA594_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x34 +}; + +static const unsigned char TA594_EC_Q[] = { + 0x04, 0xD2, 0xAB, 0x8A, 0x37, 0x4F, 0xA3, 0x53, 0x0D, 0xFE, 0xC1, 0x8A, + 0x7B, 0x4B, 0xA8, 0x7B, 0x46, 0x4B, 0x63, 0xB0, 0x62, 0xF6, 0x2D, 0x1B, + 0xDB, 0x08, 0x71, 0x21, 0xD2, 0x00, 0xE8, 0x63, 0xBD, 0x9A, 0x27, 0xFB, + 0xF0, 0x39, 0x6E, 0x5D, 0xEA, 0x3D, 0xA5, 0xC9, 0x81, 0xAA, 0xA3, 0x5B, + 0x20, 0x98, 0x45, 0x5D, 0x16, 0xDB, 0xFD, 0xE8, 0x10, 0x6D, 0xE3, 0x9C, + 0xE0, 0xE3, 0xBD, 0x5F, 0x84, 0x62, 0xF3, 0x70, 0x64, 0x33, 0xA0, 0xCB, + 0x24, 0x2F, 0x70, 0xBA, 0x88, 0xA1, 0x2A, 0xA0, 0x75, 0xF8, 0x81, 0xAE, + 0x62, 0x06, 0xC4, 0x81, 0xDB, 0x39, 0x6E, 0x29, 0xB0, 0x1E, 0xFA, 0x2E, + 0x5C +}; + +static const unsigned char TA595_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x42, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA595_RSA_N[] = { + 0xD8, 0x17, 0xB7, 0x1C, 0x4A, 0x24, 0x2A, 0xD6, 0x97, 0xB1, 0xCA, 0xE2, + 0x1E, 0xFB, 0x7D, 0x38, 0xEF, 0x98, 0xF5, 0xB2, 0x39, 0x98, 0x4E, 0x27, + 0xB8, 0x11, 0x5D, 0x7B, 0xD2, 0x25, 0x94, 0x88, 0x82, 0x15, 0x26, 0x6A, + 0x1B, 0x31, 0xBB, 0xA8, 0x5B, 0x21, 0x21, 0x2B, 0xD8, 0x0F, 0x4E, 0x9F, + 0x5A, 0xF1, 0xB1, 0x5A, 0xE4, 0x79, 0xD6, 0x32, 0x23, 0x2B, 0xE1, 0x53, + 0xCC, 0x99, 0x45, 0x5C, 0x7B, 0x4F, 0xAD, 0xBC, 0xBF, 0x87, 0x4A, 0x0B, + 0x4B, 0x97, 0x5A, 0xA8, 0xF6, 0x48, 0xEC, 0x7D, 0x7B, 0x0D, 0xCD, 0x21, + 0x06, 0xDF, 0x9E, 0x15, 0xFD, 0x41, 0x8A, 0x48, 0xB7, 0x20, 0xF4, 0xA1, + 0x7A, 0x1B, 0x57, 0xD4, 0x5D, 0x50, 0xFF, 0xBA, 0x67, 0xD8, 0x23, 0x99, + 0x1F, 0xC8, 0x3F, 0xE3, 0xDE, 0xFF, 0x6F, 0x5B, 0x77, 0xB1, 0x6B, 0x6E, + 0xB8, 0xC9, 0x64, 0xF7, 0xE1, 0xCA, 0x41, 0x46, 0x0E, 0x29, 0x71, 0xD0, + 0xB9, 0x23, 0xFC, 0xC9, 0x81, 0x5F, 0x4E, 0xF7, 0x6F, 0xDF, 0xBF, 0x84, + 0xAD, 0x73, 0x64, 0xBB, 0xB7, 0x42, 0x8E, 0x69, 0xF6, 0xD4, 0x76, 0x1D, + 0x7E, 0x9D, 0xA7, 0xB8, 0x57, 0x8A, 0x51, 0x67, 0x72, 0xD7, 0xD4, 0xA8, + 0xB8, 0x95, 0x54, 0x40, 0x73, 0x03, 0xF6, 0xEA, 0xF4, 0xEB, 0xFE, 0x28, + 0x42, 0x77, 0x3F, 0x9D, 0x23, 0x1B, 0xB2, 0xB6, 0x3D, 0x80, 0x14, 0x07, + 0x4C, 0x2E, 0x4F, 0xF7, 0xD5, 0x0A, 0x16, 0x0D, 0xBD, 0x66, 0x43, 0x37, + 0x7E, 0x23, 0x43, 0x79, 0xC3, 0x40, 0x86, 0xF5, 0x4C, 0x29, 0xDA, 0x8E, + 0x9A, 0xAD, 0x0D, 0xA5, 0x04, 0x87, 0x88, 0x1E, 0x85, 0xE3, 0xE9, 0x53, + 0xD5, 0x9B, 0xC8, 0x8B, 0x03, 0x63, 0x78, 0xEB, 0xE0, 0x19, 0x4A, 0x6E, + 0xBB, 0x2F, 0x6B, 0x33, 0x64, 0x58, 0x93, 0xAD, 0x69, 0xBF, 0x8F, 0x1B, + 0xEF, 0x82, 0x48, 0xC7 +}; + +static const unsigned char TA595_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA596_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA596_RSA_N[] = { + 0xAD, 0x0E, 0x15, 0xCE, 0xE4, 0x43, 0x80, 0x5C, 0xB1, 0x87, 0xF3, 0xB7, + 0x60, 0xF9, 0x71, 0x12, 0xA5, 0xAE, 0xDC, 0x26, 0x94, 0x88, 0xAA, 0xF4, + 0xCE, 0xF5, 0x20, 0x39, 0x28, 0x58, 0x60, 0x0C, 0xF8, 0x80, 0xDA, 0xA9, + 0x15, 0x95, 0x32, 0x61, 0x3C, 0xB5, 0xB1, 0x28, 0x84, 0x8A, 0x8A, 0xDC, + 0x9F, 0x0A, 0x0C, 0x83, 0x17, 0x7A, 0x8F, 0x90, 0xAC, 0x8A, 0xE7, 0x79, + 0x53, 0x5C, 0x31, 0x84, 0x2A, 0xF6, 0x0F, 0x98, 0x32, 0x36, 0x76, 0xCC, + 0xDE, 0xDD, 0x3C, 0xA8, 0xA2, 0xEF, 0x6A, 0xFB, 0x21, 0xF2, 0x52, 0x61, + 0xDF, 0x9F, 0x20, 0xD7, 0x1F, 0xE2, 0xB1, 0xD9, 0xFE, 0x18, 0x64, 0xD2, + 0x12, 0x5B, 0x5F, 0xF9, 0x58, 0x18, 0x35, 0xBC, 0x47, 0xCD, 0xA1, 0x36, + 0xF9, 0x6B, 0x7F, 0xD4, 0xB0, 0x38, 0x3E, 0xC1, 0x1B, 0xC3, 0x8C, 0x33, + 0xD9, 0xD8, 0x2F, 0x18, 0xFE, 0x28, 0x0F, 0xB3, 0xA7, 0x83, 0xD6, 0xC3, + 0x6E, 0x44, 0xC0, 0x61, 0x35, 0x96, 0x16, 0xFE, 0x59, 0x9C, 0x8B, 0x76, + 0x6D, 0xD7, 0xF1, 0xA2, 0x4B, 0x0D, 0x2B, 0xFF, 0x0B, 0x72, 0xDA, 0x9E, + 0x60, 0xD0, 0x8E, 0x90, 0x35, 0xC6, 0x78, 0x55, 0x87, 0x20, 0xA1, 0xCF, + 0xE5, 0x6D, 0x0A, 0xC8, 0x49, 0x7C, 0x31, 0x98, 0x33, 0x6C, 0x22, 0xE9, + 0x87, 0xD0, 0x32, 0x5A, 0xA2, 0xBA, 0x13, 0x82, 0x11, 0xED, 0x39, 0x17, + 0x9D, 0x99, 0x3A, 0x72, 0xA1, 0xE6, 0xFA, 0xA4, 0xD9, 0xD5, 0x17, 0x31, + 0x75, 0xAE, 0x85, 0x7D, 0x22, 0xAE, 0x3F, 0x01, 0x46, 0x86, 0xF6, 0x28, + 0x79, 0xC8, 0xB1, 0xDA, 0xE4, 0x57, 0x17, 0xC4, 0x7E, 0x1C, 0x0E, 0xB0, + 0xB4, 0x92, 0xA6, 0x56, 0xB3, 0xBD, 0xB2, 0x97, 0xED, 0xAA, 0xA7, 0xF0, + 0xB7, 0xC5, 0xA8, 0x3F, 0x95, 0x16, 0xD0, 0xFF, 0xA1, 0x96, 0xEB, 0x08, + 0x5F, 0x18, 0x77, 0x4F +}; + +static const unsigned char TA596_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA597_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA597_RSA_N[] = { + 0xD9, 0xE7, 0x28, 0x2F, 0x52, 0x3F, 0x36, 0x72, 0x49, 0x88, 0x93, 0x34, + 0xF3, 0xF8, 0x6A, 0x1E, 0x31, 0x54, 0x80, 0x9F, 0xAD, 0x54, 0x41, 0xB5, + 0x47, 0xDF, 0x96, 0xA8, 0xD4, 0xAF, 0x80, 0x2D, 0xB9, 0x0A, 0xCF, 0x75, + 0xFD, 0x89, 0xA5, 0x7D, 0x24, 0xFA, 0xE3, 0x22, 0x0C, 0x2B, 0xBC, 0x95, + 0x17, 0x0B, 0x33, 0xBF, 0x19, 0x4D, 0x41, 0x06, 0x90, 0x00, 0xBD, 0x0C, + 0x4D, 0x10, 0xFE, 0x07, 0xB5, 0xE7, 0x1C, 0x6E, 0x22, 0x55, 0x31, 0x65, + 0x97, 0xBD, 0xD3, 0x17, 0xD2, 0x1E, 0x62, 0xF3, 0xDB, 0xEA, 0x6C, 0x50, + 0x8C, 0x3F, 0x84, 0x0C, 0x96, 0xCF, 0xB7, 0xCB, 0x03, 0xE0, 0xCA, 0x6D, + 0xA1, 0x14, 0x4C, 0x1B, 0x89, 0xDD, 0xED, 0x00, 0xB0, 0x52, 0x7C, 0xAF, + 0x91, 0x6C, 0xB1, 0x38, 0x13, 0xD1, 0xE9, 0x12, 0x08, 0xC0, 0x00, 0xB0, + 0x1C, 0x2B, 0x11, 0xDA, 0x77, 0x70, 0x36, 0x9B, 0xAE, 0xCE, 0x79, 0x87, + 0xDC, 0x82, 0x70, 0xE6, 0x09, 0x74, 0x70, 0x55, 0x69, 0xAF, 0xA3, 0x68, + 0x9F, 0xBF, 0xDD, 0xB6, 0x79, 0xB3, 0xF2, 0x9D, 0x70, 0x29, 0x55, 0xF4, + 0xAB, 0xFF, 0x95, 0x61, 0xF3, 0xC9, 0x40, 0x6F, 0x1D, 0xD1, 0xBE, 0x93, + 0xBB, 0xD3, 0x88, 0x2A, 0xBB, 0x9D, 0xBF, 0x72, 0x5A, 0x56, 0x71, 0x3B, + 0x3F, 0xD4, 0xF3, 0xD1, 0x0A, 0xFE, 0x28, 0xEF, 0xA3, 0xEE, 0xD9, 0x99, + 0xAF, 0x03, 0xD3, 0x8F, 0x60, 0xB7, 0xF2, 0x92, 0xA1, 0xB1, 0xBD, 0x89, + 0x89, 0x1F, 0x30, 0xCD, 0xC3, 0xA6, 0x2E, 0x62, 0x33, 0xAE, 0x16, 0x02, + 0x77, 0x44, 0x5A, 0xE7, 0x81, 0x0A, 0x3C, 0xA7, 0x44, 0x2E, 0x79, 0xB8, + 0x3F, 0x04, 0xBC, 0x5C, 0xA0, 0x87, 0xE1, 0x1B, 0xAF, 0x51, 0x8E, 0xCD, + 0xEC, 0x2C, 0xFA, 0xF8, 0xFE, 0x6D, 0xF0, 0x3A, 0x7C, 0xAA, 0x8B, 0xE4, + 0x67, 0x95, 0x31, 0x8D +}; + +static const unsigned char TA597_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA598_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1B, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x65, 0x64, 0x20, 0x49, 0x44, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA598_EC_Q[] = { + 0x04, 0x19, 0xE7, 0xBC, 0xAC, 0x44, 0x65, 0xED, 0xCD, 0xB8, 0x3F, 0x58, + 0xFB, 0x8D, 0xB1, 0x57, 0xA9, 0x44, 0x2D, 0x05, 0x15, 0xF2, 0xEF, 0x0B, + 0xFF, 0x10, 0x74, 0x9F, 0xB5, 0x62, 0x52, 0x5F, 0x66, 0x7E, 0x1F, 0xE5, + 0xDC, 0x1B, 0x45, 0x79, 0x0B, 0xCC, 0xC6, 0x53, 0x0A, 0x9D, 0x8D, 0x5D, + 0x02, 0xD9, 0xA9, 0x59, 0xDE, 0x02, 0x5A, 0xF6, 0x95, 0x2A, 0x0E, 0x8D, + 0x38, 0x4A, 0x8A, 0x49, 0xC6, 0xBC, 0xC6, 0x03, 0x38, 0x07, 0x5F, 0x55, + 0xDA, 0x7E, 0x09, 0x6E, 0xE2, 0x7F, 0x5E, 0xD0, 0x45, 0x20, 0x0F, 0x59, + 0x76, 0x10, 0xD6, 0xA0, 0x24, 0xF0, 0x2D, 0xDE, 0x36, 0xF2, 0x6C, 0x29, + 0x39 +}; + +static const unsigned char TA599_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA599_RSA_N[] = { + 0xE2, 0x3B, 0xE1, 0x11, 0x72, 0xDE, 0xA8, 0xA4, 0xD3, 0xA3, 0x57, 0xAA, + 0x50, 0xA2, 0x8F, 0x0B, 0x77, 0x90, 0xC9, 0xA2, 0xA5, 0xEE, 0x12, 0xCE, + 0x96, 0x5B, 0x01, 0x09, 0x20, 0xCC, 0x01, 0x93, 0xA7, 0x4E, 0x30, 0xB7, + 0x53, 0xF7, 0x43, 0xC4, 0x69, 0x00, 0x57, 0x9D, 0xE2, 0x8D, 0x22, 0xDD, + 0x87, 0x06, 0x40, 0x00, 0x81, 0x09, 0xCE, 0xCE, 0x1B, 0x83, 0xBF, 0xDF, + 0xCD, 0x3B, 0x71, 0x46, 0xE2, 0xD6, 0x66, 0xC7, 0x05, 0xB3, 0x76, 0x27, + 0x16, 0x8F, 0x7B, 0x9E, 0x1E, 0x95, 0x7D, 0xEE, 0xB7, 0x48, 0xA3, 0x08, + 0xDA, 0xD6, 0xAF, 0x7A, 0x0C, 0x39, 0x06, 0x65, 0x7F, 0x4A, 0x5D, 0x1F, + 0xBC, 0x17, 0xF8, 0xAB, 0xBE, 0xEE, 0x28, 0xD7, 0x74, 0x7F, 0x7A, 0x78, + 0x99, 0x59, 0x85, 0x68, 0x6E, 0x5C, 0x23, 0x32, 0x4B, 0xBF, 0x4E, 0xC0, + 0xE8, 0x5A, 0x6D, 0xE3, 0x70, 0xBF, 0x77, 0x10, 0xBF, 0xFC, 0x01, 0xF6, + 0x85, 0xD9, 0xA8, 0x44, 0x10, 0x58, 0x32, 0xA9, 0x75, 0x18, 0xD5, 0xD1, + 0xA2, 0xBE, 0x47, 0xE2, 0x27, 0x6A, 0xF4, 0x9A, 0x33, 0xF8, 0x49, 0x08, + 0x60, 0x8B, 0xD4, 0x5F, 0xB4, 0x3A, 0x84, 0xBF, 0xA1, 0xAA, 0x4A, 0x4C, + 0x7D, 0x3E, 0xCF, 0x4F, 0x5F, 0x6C, 0x76, 0x5E, 0xA0, 0x4B, 0x37, 0x91, + 0x9E, 0xDC, 0x22, 0xE6, 0x6D, 0xCE, 0x14, 0x1A, 0x8E, 0x6A, 0xCB, 0xFE, + 0xCD, 0xB3, 0x14, 0x64, 0x17, 0xC7, 0x5B, 0x29, 0x9E, 0x32, 0xBF, 0xF2, + 0xEE, 0xFA, 0xD3, 0x0B, 0x42, 0xD4, 0xAB, 0xB7, 0x41, 0x32, 0xDA, 0x0C, + 0xD4, 0xEF, 0xF8, 0x81, 0xD5, 0xBB, 0x8D, 0x58, 0x3F, 0xB5, 0x1B, 0xE8, + 0x49, 0x28, 0xA2, 0x70, 0xDA, 0x31, 0x04, 0xDD, 0xF7, 0xB2, 0x16, 0xF2, + 0x4C, 0x0A, 0x4E, 0x07, 0xA8, 0xED, 0x4A, 0x3D, 0x5E, 0xB5, 0x7F, 0xA3, + 0x90, 0xC3, 0xAF, 0x27 +}; + +static const unsigned char TA599_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA600_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x32 +}; + +static const unsigned char TA600_RSA_N[] = { + 0xBB, 0x37, 0xCD, 0x34, 0xDC, 0x7B, 0x6B, 0xC9, 0xB2, 0x68, 0x90, 0xAD, + 0x4A, 0x75, 0xFF, 0x46, 0xBA, 0x21, 0x0A, 0x08, 0x8D, 0xF5, 0x19, 0x54, + 0xC9, 0xFB, 0x88, 0xDB, 0xF3, 0xAE, 0xF2, 0x3A, 0x89, 0x91, 0x3C, 0x7A, + 0xE6, 0xAB, 0x06, 0x1A, 0x6B, 0xCF, 0xAC, 0x2D, 0xE8, 0x5E, 0x09, 0x24, + 0x44, 0xBA, 0x62, 0x9A, 0x7E, 0xD6, 0xA3, 0xA8, 0x7E, 0xE0, 0x54, 0x75, + 0x20, 0x05, 0xAC, 0x50, 0xB7, 0x9C, 0x63, 0x1A, 0x6C, 0x30, 0xDC, 0xDA, + 0x1F, 0x19, 0xB1, 0xD7, 0x1E, 0xDE, 0xFD, 0xD7, 0xE0, 0xCB, 0x94, 0x83, + 0x37, 0xAE, 0xEC, 0x1F, 0x43, 0x4E, 0xDD, 0x7B, 0x2C, 0xD2, 0xBD, 0x2E, + 0xA5, 0x2F, 0xE4, 0xA9, 0xB8, 0xAD, 0x3A, 0xD4, 0x99, 0xA4, 0xB6, 0x25, + 0xE9, 0x9B, 0x6B, 0x00, 0x60, 0x92, 0x60, 0xFF, 0x4F, 0x21, 0x49, 0x18, + 0xF7, 0x67, 0x90, 0xAB, 0x61, 0x06, 0x9C, 0x8F, 0xF2, 0xBA, 0xE9, 0xB4, + 0xE9, 0x92, 0x32, 0x6B, 0xB5, 0xF3, 0x57, 0xE8, 0x5D, 0x1B, 0xCD, 0x8C, + 0x1D, 0xAB, 0x95, 0x04, 0x95, 0x49, 0xF3, 0x35, 0x2D, 0x96, 0xE3, 0x49, + 0x6D, 0xDD, 0x77, 0xE3, 0xFB, 0x49, 0x4B, 0xB4, 0xAC, 0x55, 0x07, 0xA9, + 0x8F, 0x95, 0xB3, 0xB4, 0x23, 0xBB, 0x4C, 0x6D, 0x45, 0xF0, 0xF6, 0xA9, + 0xB2, 0x95, 0x30, 0xB4, 0xFD, 0x4C, 0x55, 0x8C, 0x27, 0x4A, 0x57, 0x14, + 0x7C, 0x82, 0x9D, 0xCD, 0x73, 0x92, 0xD3, 0x16, 0x4A, 0x06, 0x0C, 0x8C, + 0x50, 0xD1, 0x8F, 0x1E, 0x09, 0xBE, 0x17, 0xA1, 0xE6, 0x21, 0xCA, 0xFD, + 0x83, 0xE5, 0x10, 0xBC, 0x83, 0xA5, 0x0A, 0xC4, 0x67, 0x28, 0xF6, 0x73, + 0x14, 0x14, 0x3D, 0x46, 0x76, 0xC3, 0x87, 0x14, 0x89, 0x21, 0x34, 0x4D, + 0xAF, 0x0F, 0x45, 0x0C, 0xA6, 0x49, 0xA1, 0xBA, 0xBB, 0x9C, 0xC5, 0xB1, + 0x33, 0x83, 0x29, 0x85 +}; + +static const unsigned char TA600_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA601_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x33 +}; + +static const unsigned char TA601_EC_Q[] = { + 0x04, 0xDD, 0xA7, 0xD9, 0xBB, 0x8A, 0xB8, 0x0B, 0xFB, 0x0B, 0x7F, 0x21, + 0xD2, 0xF0, 0xBE, 0xBE, 0x73, 0xF3, 0x33, 0x5D, 0x1A, 0xBC, 0x34, 0xEA, + 0xDE, 0xC6, 0x9B, 0xBC, 0xD0, 0x95, 0xF6, 0xF0, 0xCC, 0xD0, 0x0B, 0xBA, + 0x61, 0x5B, 0x51, 0x46, 0x7E, 0x9E, 0x2D, 0x9F, 0xEE, 0x8E, 0x63, 0x0C, + 0x17, 0xEC, 0x07, 0x70, 0xF5, 0xCF, 0x84, 0x2E, 0x40, 0x83, 0x9C, 0xE8, + 0x3F, 0x41, 0x6D, 0x3B, 0xAD, 0xD3, 0xA4, 0x14, 0x59, 0x36, 0x78, 0x9D, + 0x03, 0x43, 0xEE, 0x10, 0x13, 0x6C, 0x72, 0xDE, 0xAE, 0x88, 0xA7, 0xA1, + 0x6B, 0xB5, 0x43, 0xCE, 0x67, 0xDC, 0x23, 0xFF, 0x03, 0x1C, 0xA3, 0xE2, + 0x3E +}; + +static const unsigned char TA602_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, + 0x6E, 0x63, 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA602_RSA_N[] = { + 0xC6, 0xCC, 0xE5, 0x73, 0xE6, 0xFB, 0xD4, 0xBB, 0xE5, 0x2D, 0x2D, 0x32, + 0xA6, 0xDF, 0xE5, 0x81, 0x3F, 0xC9, 0xCD, 0x25, 0x49, 0xB6, 0x71, 0x2A, + 0xC3, 0xD5, 0x94, 0x34, 0x67, 0xA2, 0x0A, 0x1C, 0xB0, 0x5F, 0x69, 0xA6, + 0x40, 0xB1, 0xC4, 0xB7, 0xB2, 0x8F, 0xD0, 0x98, 0xA4, 0xA9, 0x41, 0x59, + 0x3A, 0xD3, 0xDC, 0x94, 0xD6, 0x3C, 0xDB, 0x74, 0x38, 0xA4, 0x4A, 0xCC, + 0x4D, 0x25, 0x82, 0xF7, 0x4A, 0xA5, 0x53, 0x12, 0x38, 0xEE, 0xF3, 0x49, + 0x6D, 0x71, 0x91, 0x7E, 0x63, 0xB6, 0xAB, 0xA6, 0x5F, 0xC3, 0xA4, 0x84, + 0xF8, 0x4F, 0x62, 0x51, 0xBE, 0xF8, 0xC5, 0xEC, 0xDB, 0x38, 0x92, 0xE3, + 0x06, 0xE5, 0x08, 0x91, 0x0C, 0xC4, 0x28, 0x41, 0x55, 0xFB, 0xCB, 0x5A, + 0x89, 0x15, 0x7E, 0x71, 0xE8, 0x35, 0xBF, 0x4D, 0x72, 0x09, 0x3D, 0xBE, + 0x3A, 0x38, 0x50, 0x5B, 0x77, 0x31, 0x1B, 0x8D, 0xB3, 0xC7, 0x24, 0x45, + 0x9A, 0xA7, 0xAC, 0x6D, 0x00, 0x14, 0x5A, 0x04, 0xB7, 0xBA, 0x13, 0xEB, + 0x51, 0x0A, 0x98, 0x41, 0x41, 0x22, 0x4E, 0x65, 0x61, 0x87, 0x81, 0x41, + 0x50, 0xA6, 0x79, 0x5C, 0x89, 0xDE, 0x19, 0x4A, 0x57, 0xD5, 0x2E, 0xE6, + 0x5D, 0x1C, 0x53, 0x2C, 0x7E, 0x98, 0xCD, 0x1A, 0x06, 0x16, 0xA4, 0x68, + 0x73, 0xD0, 0x34, 0x04, 0x13, 0x5C, 0xA1, 0x71, 0xD3, 0x5A, 0x7C, 0x55, + 0xDB, 0x5E, 0x64, 0xE1, 0x37, 0x87, 0x30, 0x56, 0x04, 0xE5, 0x11, 0xB4, + 0x29, 0x80, 0x12, 0xF1, 0x79, 0x39, 0x88, 0xA2, 0x02, 0x11, 0x7C, 0x27, + 0x66, 0xB7, 0x88, 0xB7, 0x78, 0xF2, 0xCA, 0x0A, 0xA8, 0x38, 0xAB, 0x0A, + 0x64, 0xC2, 0xBF, 0x66, 0x5D, 0x95, 0x84, 0xC1, 0xA1, 0x25, 0x1E, 0x87, + 0x5D, 0x1A, 0x50, 0x0B, 0x20, 0x12, 0xCC, 0x41, 0xBB, 0x6E, 0x0B, 0x51, + 0x38, 0xB8, 0x4B, 0xCB +}; + +static const unsigned char TA602_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA603_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1D, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x50, 0x33, 0x38, 0x34, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA603_EC_Q[] = { + 0x04, 0xC1, 0x44, 0xA1, 0xCF, 0x11, 0x97, 0x50, 0x9A, 0xDE, 0x23, 0x82, + 0x35, 0x07, 0xCD, 0xD0, 0xCB, 0x18, 0x9D, 0xD2, 0xF1, 0x7F, 0x77, 0x35, + 0x4F, 0x3B, 0xDD, 0x94, 0x72, 0x52, 0xED, 0xC2, 0x3B, 0xF8, 0xEC, 0xFA, + 0x7B, 0x6B, 0x58, 0x20, 0xEC, 0x99, 0xAE, 0xC9, 0xFC, 0x68, 0xB3, 0x75, + 0xB9, 0xDB, 0x09, 0xEC, 0xC8, 0x13, 0xF5, 0x4E, 0xC6, 0x0A, 0x1D, 0x66, + 0x30, 0x4C, 0xBB, 0x1F, 0x47, 0x0A, 0x3C, 0x61, 0x10, 0x42, 0x29, 0x7C, + 0xA5, 0x08, 0x0E, 0xE0, 0x22, 0xE9, 0xD3, 0x35, 0x68, 0xCE, 0x9B, 0x63, + 0x9F, 0x84, 0xB5, 0x99, 0x4D, 0x58, 0xA0, 0x8E, 0xF5, 0x54, 0xE7, 0x95, + 0xC9 +}; + +static const unsigned char TA604_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0E, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x34, 0x30, 0x39, 0x36, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x35 +}; + +static const unsigned char TA604_RSA_N[] = { + 0xB3, 0xD0, 0xF4, 0xC9, 0x79, 0x11, 0x9D, 0xFD, 0xFC, 0x66, 0x81, 0xE7, + 0xCC, 0xD5, 0xE4, 0xBC, 0xEC, 0x81, 0x3E, 0x6A, 0x35, 0x8E, 0x2E, 0xB7, + 0xE7, 0xDE, 0xAF, 0xF9, 0x07, 0x4D, 0xCF, 0x30, 0x9D, 0xEA, 0x09, 0x0B, + 0x99, 0xBD, 0x6C, 0x57, 0xDA, 0x18, 0x4A, 0xB8, 0x78, 0xAC, 0x3A, 0x39, + 0xA8, 0xA6, 0x48, 0xAC, 0x2E, 0x72, 0xE5, 0xBD, 0xEB, 0xF1, 0x1A, 0xCD, + 0xE7, 0xA4, 0x03, 0xA9, 0x3F, 0x11, 0xB4, 0xD8, 0x2F, 0x89, 0x16, 0xFB, + 0x94, 0x01, 0x3D, 0xBB, 0x2F, 0xF8, 0x13, 0x05, 0xA1, 0x78, 0x1C, 0x8E, + 0x28, 0xE0, 0x45, 0xE0, 0x83, 0xF4, 0x59, 0x1B, 0x95, 0xB3, 0xAE, 0x7E, + 0x03, 0x45, 0xE5, 0xBE, 0xC2, 0x42, 0xFE, 0xEE, 0xF2, 0x3C, 0xB6, 0x85, + 0x13, 0x98, 0x32, 0x9D, 0x16, 0xA8, 0x29, 0xC2, 0x0B, 0x1C, 0x38, 0xDC, + 0x9F, 0x31, 0x77, 0x5C, 0xBF, 0x27, 0xA3, 0xFC, 0x27, 0xAC, 0xB7, 0x2B, + 0xBD, 0x74, 0x9B, 0x17, 0x2D, 0xF2, 0x81, 0xDA, 0x5D, 0xB0, 0xE1, 0x23, + 0x17, 0x3E, 0x88, 0x4A, 0x12, 0x23, 0xD0, 0xEA, 0xCF, 0x9D, 0xDE, 0x03, + 0x17, 0xB1, 0x42, 0x4A, 0xA0, 0x16, 0x4C, 0xA4, 0x6D, 0x93, 0xE9, 0x3F, + 0x3A, 0xEE, 0x3A, 0x7C, 0x9D, 0x58, 0x9D, 0xF4, 0x4E, 0x8F, 0xFC, 0x3B, + 0x23, 0xC8, 0x6D, 0xB8, 0xE2, 0x05, 0xDA, 0xCC, 0xEB, 0xEC, 0xC3, 0x31, + 0xF4, 0xD7, 0xA7, 0x29, 0x54, 0x80, 0xCF, 0x44, 0x5B, 0x4C, 0x6F, 0x30, + 0x9E, 0xF3, 0xCC, 0xDD, 0x1F, 0x94, 0x43, 0x9D, 0x4D, 0x7F, 0x70, 0x70, + 0x0D, 0xD4, 0x3A, 0xD1, 0x37, 0xF0, 0x6C, 0x9D, 0x9B, 0xC0, 0x14, 0x93, + 0x58, 0xEF, 0xCD, 0x41, 0x38, 0x75, 0xBC, 0x13, 0x03, 0x95, 0x7C, 0x7F, + 0xE3, 0x5C, 0xE9, 0xD5, 0x0D, 0xD5, 0xE2, 0x7C, 0x10, 0x62, 0xAA, 0x6B, + 0xF0, 0x3D, 0x76, 0xF3, 0x3F, 0xA3, 0xE8, 0xB0, 0xC1, 0xFD, 0xEF, 0xAA, + 0x57, 0x4D, 0xAC, 0x86, 0xA7, 0x18, 0xB4, 0x29, 0xC1, 0x2C, 0x0E, 0xBF, + 0x64, 0xBE, 0x29, 0x8C, 0xD8, 0x02, 0x2D, 0xCD, 0x5C, 0x2F, 0xF2, 0x7F, + 0xEF, 0x15, 0xF4, 0x0C, 0x15, 0xAC, 0x0A, 0xB0, 0xF1, 0xD3, 0x0D, 0x4F, + 0x6A, 0x4D, 0x77, 0x97, 0x01, 0xA0, 0xF1, 0x66, 0xB7, 0xB7, 0xCE, 0xEF, + 0xCE, 0xEC, 0xEC, 0xA5, 0x75, 0xCA, 0xAC, 0xE3, 0xE1, 0x63, 0xF7, 0xB8, + 0xA1, 0x04, 0xC8, 0xBC, 0x7B, 0x3F, 0x5D, 0x2D, 0x16, 0x22, 0x56, 0xED, + 0x48, 0x49, 0xFE, 0xA7, 0x2F, 0x79, 0x30, 0x25, 0x9B, 0xBA, 0x6B, 0x2D, + 0x3F, 0x9D, 0x3B, 0xC4, 0x17, 0xE7, 0x1D, 0x2E, 0xFB, 0xF2, 0xCF, 0xA6, + 0xFC, 0xE3, 0x14, 0x2C, 0x96, 0x98, 0x21, 0x8C, 0xB4, 0x91, 0xE9, 0x19, + 0x60, 0x83, 0xF2, 0x30, 0x2B, 0x06, 0x73, 0x50, 0xD5, 0x98, 0x3B, 0x06, + 0xE9, 0xC7, 0x8A, 0x0C, 0x60, 0x8C, 0x28, 0xF8, 0x52, 0x9B, 0x6E, 0xE1, + 0xF6, 0x4D, 0xBB, 0x06, 0x24, 0x9B, 0xD7, 0x2B, 0x26, 0x3F, 0xFD, 0x2A, + 0x2F, 0x71, 0xF5, 0xD6, 0x24, 0xBE, 0x7F, 0x31, 0x9E, 0x0F, 0x6D, 0xE8, + 0x8F, 0x4F, 0x4D, 0xA3, 0x3F, 0xFF, 0x35, 0xEA, 0xDF, 0x49, 0x5E, 0x41, + 0x8F, 0x86, 0xF9, 0xF1, 0x77, 0x79, 0x4B, 0x1B, 0xB4, 0xA3, 0x5E, 0x2F, + 0xFB, 0x46, 0x02, 0xD0, 0x66, 0x13, 0x5E, 0x5E, 0x85, 0x4F, 0xCE, 0xD8, + 0x70, 0x88, 0x7B, 0xCE, 0x01, 0xB5, 0x96, 0x97, 0xD7, 0xCD, 0x7D, 0xFD, + 0x82, 0xF8, 0xC2, 0x24, 0xC1, 0xCA, 0x01, 0x39, 0x4F, 0x8D, 0xA2, 0xC1, + 0x14, 0x40, 0x1F, 0x9C, 0x66, 0xD5, 0x0C, 0x09, 0x46, 0xD6, 0xF2, 0xD0, + 0xD1, 0x48, 0x76, 0x56, 0x3A, 0x43, 0xCB, 0xB6, 0x0A, 0x11, 0x39, 0xBA, + 0x8C, 0x13, 0x6C, 0x06, 0xB5, 0x9E, 0xCF, 0xEB +}; + +static const unsigned char TA604_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA605_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x18, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA605_RSA_N[] = { + 0xBF, 0xE6, 0x90, 0x73, 0x68, 0xDE, 0xBB, 0xE4, 0x5D, 0x4A, 0x3C, 0x30, + 0x22, 0x30, 0x69, 0x33, 0xEC, 0xC2, 0xA7, 0x25, 0x2E, 0xC9, 0x21, 0x3D, + 0xF2, 0x8A, 0xD8, 0x59, 0xC2, 0xE1, 0x29, 0xA7, 0x3D, 0x58, 0xAB, 0x76, + 0x9A, 0xCD, 0xAE, 0x7B, 0x1B, 0x84, 0x0D, 0xC4, 0x30, 0x1F, 0xF3, 0x1B, + 0xA4, 0x38, 0x16, 0xEB, 0x56, 0xC6, 0x97, 0x6D, 0x1D, 0xAB, 0xB2, 0x79, + 0xF2, 0xCA, 0x11, 0xD2, 0xE4, 0x5F, 0xD6, 0x05, 0x3C, 0x52, 0x0F, 0x52, + 0x1F, 0xC6, 0x9E, 0x15, 0xA5, 0x7E, 0xBE, 0x9F, 0xA9, 0x57, 0x16, 0x59, + 0x55, 0x72, 0xAF, 0x68, 0x93, 0x70, 0xC2, 0xB2, 0xBA, 0x75, 0x99, 0x6A, + 0x73, 0x32, 0x94, 0xD1, 0x10, 0x44, 0x10, 0x2E, 0xDF, 0x82, 0xF3, 0x07, + 0x84, 0xE6, 0x74, 0x3B, 0x6D, 0x71, 0xE2, 0x2D, 0x0C, 0x1B, 0xEE, 0x20, + 0xD5, 0xC9, 0x20, 0x1D, 0x63, 0x29, 0x2D, 0xCE, 0xEC, 0x5E, 0x4E, 0xC8, + 0x93, 0xF8, 0x21, 0x61, 0x9B, 0x34, 0xEB, 0x05, 0xC6, 0x5E, 0xEC, 0x5B, + 0x1A, 0xBC, 0xEB, 0xC9, 0xCF, 0xCD, 0xAC, 0x34, 0x40, 0x5F, 0xB1, 0x7A, + 0x66, 0xEE, 0x77, 0xC8, 0x48, 0xA8, 0x66, 0x57, 0x57, 0x9F, 0x54, 0x58, + 0x8E, 0x0C, 0x2B, 0xB7, 0x4F, 0xA7, 0x30, 0xD9, 0x56, 0xEE, 0xCA, 0x7B, + 0x5D, 0xE3, 0xAD, 0xC9, 0x4F, 0x5E, 0xE5, 0x35, 0xE7, 0x31, 0xCB, 0xDA, + 0x93, 0x5E, 0xDC, 0x8E, 0x8F, 0x80, 0xDA, 0xB6, 0x91, 0x98, 0x40, 0x90, + 0x79, 0xC3, 0x78, 0xC7, 0xB6, 0xB1, 0xC4, 0xB5, 0x6A, 0x18, 0x38, 0x03, + 0x10, 0x8D, 0xD8, 0xD4, 0x37, 0xA4, 0x2E, 0x05, 0x7D, 0x88, 0xF5, 0x82, + 0x3E, 0x10, 0x91, 0x70, 0xAB, 0x55, 0x82, 0x41, 0x32, 0xD7, 0xDB, 0x04, + 0x73, 0x2A, 0x6E, 0x91, 0x01, 0x7C, 0x21, 0x4C, 0xD4, 0xBC, 0xAE, 0x1B, + 0x03, 0x75, 0x5D, 0x78, 0x66, 0xD9, 0x3A, 0x31, 0x44, 0x9A, 0x33, 0x40, + 0xBF, 0x08, 0xD7, 0x5A, 0x49, 0xA4, 0xC2, 0xE6, 0xA9, 0xA0, 0x67, 0xDD, + 0xA4, 0x27, 0xBC, 0xA1, 0x4F, 0x39, 0xB5, 0x11, 0x58, 0x17, 0xF7, 0x24, + 0x5C, 0x46, 0x8F, 0x64, 0xF7, 0xC1, 0x69, 0x88, 0x76, 0x98, 0x76, 0x3D, + 0x59, 0x5D, 0x42, 0x76, 0x87, 0x89, 0x97, 0x69, 0x7A, 0x48, 0xF0, 0xE0, + 0xA2, 0x12, 0x1B, 0x66, 0x9A, 0x74, 0xCA, 0xDE, 0x4B, 0x1E, 0xE7, 0x0E, + 0x63, 0xAE, 0xE6, 0xD4, 0xEF, 0x92, 0x92, 0x3A, 0x9E, 0x3D, 0xDC, 0x00, + 0xE4, 0x45, 0x25, 0x89, 0xB6, 0x9A, 0x44, 0x19, 0x2B, 0x7E, 0xC0, 0x94, + 0xB4, 0xD2, 0x61, 0x6D, 0xEB, 0x33, 0xD9, 0xC5, 0xDF, 0x4B, 0x04, 0x00, + 0xCC, 0x7D, 0x1C, 0x95, 0xC3, 0x8F, 0xF7, 0x21, 0xB2, 0xB2, 0x11, 0xB7, + 0xBB, 0x7F, 0xF2, 0xD5, 0x8C, 0x70, 0x2C, 0x41, 0x60, 0xAA, 0xB1, 0x63, + 0x18, 0x44, 0x95, 0x1A, 0x76, 0x62, 0x7E, 0xF6, 0x80, 0xB0, 0xFB, 0xE8, + 0x64, 0xA6, 0x33, 0xD1, 0x89, 0x07, 0xE1, 0xBD, 0xB7, 0xE6, 0x43, 0xA4, + 0x18, 0xB8, 0xA6, 0x77, 0x01, 0xE1, 0x0F, 0x94, 0x0C, 0x21, 0x1D, 0xB2, + 0x54, 0x29, 0x25, 0x89, 0x6C, 0xE5, 0x0E, 0x52, 0x51, 0x47, 0x74, 0xBE, + 0x26, 0xAC, 0xB6, 0x41, 0x75, 0xDE, 0x7A, 0xAC, 0x5F, 0x8D, 0x3F, 0xC9, + 0xBC, 0xD3, 0x41, 0x11, 0x12, 0x5B, 0xE5, 0x10, 0x50, 0xEB, 0x31, 0xC5, + 0xCA, 0x72, 0x16, 0x22, 0x09, 0xDF, 0x7C, 0x4C, 0x75, 0x3F, 0x63, 0xEC, + 0x21, 0x5F, 0xC4, 0x20, 0x51, 0x6B, 0x6F, 0xB1, 0xAB, 0x86, 0x8B, 0x4F, + 0xC2, 0xD6, 0x45, 0x5F, 0x9D, 0x20, 0xFC, 0xA1, 0x1E, 0xC5, 0xC0, 0x8F, + 0xA2, 0xB1, 0x7E, 0x0A, 0x26, 0x99, 0xF5, 0xE4, 0x69, 0x2F, 0x98, 0x1D, + 0x2D, 0xF5, 0xD9, 0xA9, 0xB2, 0x1D, 0xE5, 0x1B +}; + +static const unsigned char TA605_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA606_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA606_EC_Q[] = { + 0x04, 0xC6, 0xCB, 0xC7, 0x28, 0xD1, 0xFB, 0x84, 0xF5, 0x9A, 0xEF, 0x42, + 0x14, 0x20, 0xE1, 0x43, 0x6B, 0x6E, 0x75, 0xAD, 0xFC, 0x2B, 0x03, 0x84, + 0xD4, 0x76, 0x93, 0x25, 0xD7, 0x59, 0x3B, 0x41, 0x65, 0x6B, 0x1E, 0xE6, + 0x34, 0x2A, 0xBB, 0x74, 0xF6, 0x12, 0xCE, 0xE8, 0x6D, 0xE7, 0xAB, 0xE4, + 0x3C, 0x4E, 0x3F, 0x44, 0x08, 0x8B, 0xCD, 0x16, 0x71, 0xCB, 0xBF, 0x92, + 0x99, 0xF4, 0xA4, 0xD7, 0x3C, 0x50, 0x54, 0x52, 0x90, 0x85, 0x83, 0x78, + 0x94, 0x67, 0x67, 0xA3, 0x1C, 0x09, 0x19, 0x3D, 0x75, 0x34, 0x85, 0xDE, + 0xED, 0x60, 0x7D, 0xC7, 0x0C, 0xB4, 0x41, 0x52, 0xB9, 0x6E, 0xE5, 0xEE, + 0x42 +}; + +static const unsigned char TA607_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA607_RSA_N[] = { + 0xAE, 0xFF, 0x09, 0x59, 0x91, 0x80, 0x0A, 0x4A, 0x68, 0xE6, 0x24, 0x3F, + 0xB8, 0xA7, 0xE4, 0xC8, 0x3A, 0x0A, 0x3A, 0x16, 0xCD, 0xC9, 0x23, 0x61, + 0xA0, 0x93, 0x71, 0xF2, 0xAB, 0x8B, 0x73, 0x8F, 0xA0, 0x67, 0x65, 0x60, + 0xD2, 0x54, 0x6B, 0x63, 0x51, 0x6F, 0x49, 0x33, 0xE0, 0x72, 0x07, 0x13, + 0x7D, 0x38, 0xCD, 0x06, 0x92, 0x07, 0x29, 0x52, 0x6B, 0x4E, 0x77, 0x6C, + 0x04, 0xD3, 0x95, 0xFA, 0xDD, 0x4C, 0x8C, 0xD9, 0x5D, 0xC1, 0x61, 0x7D, + 0x4B, 0xE7, 0x28, 0xB3, 0x44, 0x81, 0x7B, 0x51, 0xAF, 0xDD, 0x33, 0xB1, + 0x68, 0x7C, 0xD6, 0x4E, 0x4C, 0xFE, 0x2B, 0x68, 0xB9, 0xCA, 0x66, 0x69, + 0xC4, 0xEC, 0x5E, 0x57, 0x7F, 0xF7, 0x0D, 0xC7, 0x9C, 0x36, 0x36, 0xE5, + 0x07, 0x60, 0xAC, 0xC0, 0x4C, 0xEA, 0x08, 0x6C, 0xEF, 0x06, 0x7C, 0x4F, + 0x5B, 0x28, 0x7A, 0x08, 0xFC, 0x93, 0x5D, 0x9B, 0xF6, 0x9C, 0xB4, 0x8B, + 0x86, 0xBA, 0x21, 0xB9, 0xF4, 0xF0, 0xE8, 0x59, 0x5A, 0x28, 0xA1, 0x34, + 0x84, 0x1A, 0x25, 0x91, 0xB6, 0xB5, 0x8F, 0xEF, 0xB2, 0xF9, 0x80, 0xFA, + 0xF9, 0x3D, 0x3C, 0x11, 0x72, 0xD8, 0xE3, 0x2F, 0x86, 0x76, 0xC5, 0x79, + 0x2C, 0xC1, 0xA9, 0x90, 0x93, 0x46, 0x98, 0x67, 0xCB, 0x83, 0x6A, 0xA0, + 0x50, 0x23, 0xA7, 0x3B, 0xF6, 0x81, 0x39, 0xE0, 0xED, 0xF0, 0xB9, 0xBF, + 0x65, 0xF1, 0xD8, 0xCB, 0x7A, 0xFB, 0xEF, 0x73, 0x03, 0xCE, 0x00, 0xF4, + 0x7D, 0xD7, 0xE0, 0x5D, 0x3B, 0x66, 0xB8, 0xDC, 0x8E, 0xBA, 0x83, 0xCB, + 0x87, 0x76, 0x03, 0xFC, 0x25, 0xD9, 0xE7, 0x23, 0x6F, 0x06, 0xFD, 0x67, + 0xF3, 0xE0, 0xFF, 0x84, 0xBC, 0x47, 0xBF, 0xB5, 0x16, 0x18, 0x46, 0x69, + 0x14, 0xCC, 0x05, 0xF7, 0xDB, 0xD3, 0x49, 0xAC, 0x6B, 0xCC, 0xAB, 0xE4, + 0xB5, 0x0B, 0x43, 0x24, 0x5E, 0x4B, 0x6B, 0x4D, 0x67, 0xDF, 0xD6, 0xB5, + 0x3E, 0x4F, 0x78, 0x1F, 0x94, 0x71, 0x24, 0xEA, 0xDE, 0x70, 0xFC, 0xF1, + 0x93, 0xFE, 0x9E, 0x93, 0x5A, 0xE4, 0x94, 0x5A, 0x97, 0x54, 0x0C, 0x35, + 0x7B, 0x5F, 0x6C, 0xEE, 0x00, 0x1F, 0x24, 0xEC, 0x03, 0xBA, 0x02, 0xF5, + 0x76, 0xF4, 0x9F, 0xD4, 0x9A, 0xED, 0x85, 0x2C, 0x38, 0x22, 0x2F, 0xC7, + 0xD8, 0x2F, 0x76, 0x11, 0x4F, 0xFD, 0x6C, 0x5C, 0xE8, 0xF5, 0x8E, 0x27, + 0x87, 0x7F, 0x19, 0x4A, 0x21, 0x47, 0x90, 0x1D, 0x79, 0x8D, 0x1C, 0x5B, + 0xF8, 0xCF, 0x4A, 0x85, 0xE4, 0xED, 0xB3, 0x5B, 0x8D, 0xBE, 0xC4, 0x64, + 0x28, 0x5D, 0x41, 0xC4, 0x6E, 0xAC, 0x38, 0x5A, 0x4F, 0x23, 0x74, 0x74, + 0xA9, 0x12, 0xC3, 0xF6, 0xD2, 0xB9, 0x11, 0x15, 0x33, 0x07, 0x91, 0xD8, + 0x3B, 0x37, 0x3A, 0x63, 0x30, 0x06, 0xD1, 0xC5, 0x22, 0x36, 0x28, 0x62, + 0x23, 0x10, 0xE0, 0x46, 0xCC, 0x97, 0xAC, 0xD6, 0x2B, 0x5D, 0x64, 0x24, + 0xD5, 0xEE, 0x1C, 0x0E, 0xDE, 0xFB, 0x08, 0x5A, 0x75, 0x2A, 0xF6, 0x63, + 0x6D, 0xCE, 0x0B, 0x42, 0xBE, 0xD1, 0xBA, 0x70, 0x1C, 0x9C, 0x21, 0xE5, + 0x0F, 0x31, 0x69, 0x17, 0xD7, 0xFC, 0x0A, 0xB4, 0xDE, 0xED, 0x80, 0x9C, + 0xCB, 0x92, 0xB4, 0x8B, 0xF5, 0xDE, 0x59, 0xA2, 0x58, 0x09, 0xA5, 0x63, + 0x47, 0x0B, 0xE1, 0x41, 0x32, 0x34, 0x41, 0xD9, 0x9A, 0xB1, 0xD9, 0xA8, + 0xB0, 0x1B, 0x5A, 0xDE, 0x0D, 0x0D, 0xF4, 0xE2, 0xB2, 0x5D, 0x35, 0x80, + 0xB9, 0x81, 0xD4, 0x84, 0x69, 0x91, 0x02, 0xCB, 0x75, 0xD0, 0x8D, 0xC5, + 0xB5, 0x3D, 0x09, 0x91, 0x09, 0x8F, 0x14, 0xA1, 0x14, 0x74, 0x79, 0x3E, + 0xD6, 0xC9, 0x15, 0x1D, 0xA4, 0x59, 0x59, 0x22, 0xDC, 0xF6, 0x8A, 0x45, + 0x3D, 0x3C, 0x12, 0xD6, 0x3E, 0x5D, 0x32, 0x2F +}; + +static const unsigned char TA607_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA608_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, 0x32, 0x30, + 0x32, 0x30 +}; + +static const unsigned char TA608_EC_Q[] = { + 0x04, 0xF1, 0x0B, 0xDD, 0x86, 0x43, 0x20, 0x19, 0xDF, 0x97, 0x85, 0xE8, + 0x22, 0x4A, 0x9B, 0xCF, 0x9D, 0x98, 0xBF, 0xB4, 0x05, 0x26, 0xC9, 0xCB, + 0xE3, 0xA6, 0xD2, 0x8F, 0xC5, 0x9E, 0x78, 0x7B, 0x31, 0x89, 0xA9, 0x89, + 0xAD, 0x27, 0x3C, 0x65, 0x10, 0x82, 0xFC, 0xDF, 0xC3, 0x9D, 0x4E, 0xF0, + 0x33, 0x23, 0xC4, 0xD2, 0x32, 0xF5, 0x1C, 0xB0, 0xDF, 0x33, 0x17, 0x5D, + 0xC5, 0xF0, 0xB1, 0x8A, 0xF9, 0xEF, 0xB9, 0xB7, 0x14, 0xCA, 0x29, 0x4A, + 0xC2, 0x0F, 0xA9, 0x7F, 0x75, 0x65, 0x49, 0x2A, 0x30, 0x67, 0xF4, 0x64, + 0xF7, 0xD6, 0x1A, 0x77, 0xDA, 0xC3, 0xC2, 0x97, 0x61, 0x42, 0x7B, 0x49, + 0xAD +}; + +static const unsigned char TA609_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x45, 0x56, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA609_RSA_N[] = { + 0xD8, 0x8E, 0xA3, 0x89, 0x80, 0x0B, 0xB2, 0x57, 0x52, 0xDC, 0xA9, 0x53, + 0x4C, 0x37, 0xB9, 0x7F, 0x63, 0x17, 0x13, 0xEF, 0xA7, 0x5B, 0x23, 0x5B, + 0x69, 0x75, 0xB0, 0x99, 0x0A, 0x17, 0xC1, 0x8B, 0xC4, 0xDB, 0xA8, 0xE0, + 0xCC, 0x31, 0xBA, 0xC2, 0xF2, 0xCD, 0x5D, 0xE9, 0xB7, 0xF8, 0x1D, 0xAF, + 0x6A, 0xC4, 0x95, 0x87, 0xD7, 0x47, 0xC9, 0x95, 0xD8, 0x82, 0x04, 0x50, + 0x3D, 0x81, 0x08, 0xFF, 0xE4, 0x3D, 0xB3, 0xB1, 0xD6, 0xC5, 0xB2, 0xFD, + 0x88, 0x09, 0xDB, 0x9C, 0x84, 0xEC, 0x25, 0x17, 0x14, 0x87, 0x7F, 0x30, + 0x78, 0x9B, 0x6A, 0x58, 0xC9, 0xB6, 0x73, 0x28, 0x3C, 0x34, 0xF7, 0x99, + 0xF7, 0x7F, 0xD3, 0xA6, 0xF8, 0x1C, 0x45, 0x7C, 0xAD, 0x2C, 0x8C, 0x94, + 0x3F, 0xD8, 0x67, 0x10, 0x53, 0x7E, 0x22, 0xCD, 0x4E, 0x25, 0x51, 0xF0, + 0x25, 0x24, 0x35, 0x11, 0x5E, 0x10, 0xC6, 0xEC, 0x87, 0x66, 0x89, 0x81, + 0x68, 0xBA, 0xCC, 0x2B, 0x9D, 0x47, 0x73, 0x1F, 0xBD, 0xCD, 0x91, 0xA4, + 0x72, 0x6A, 0x9C, 0xA2, 0x1B, 0x18, 0xA0, 0x6F, 0xEC, 0x50, 0xF4, 0x7D, + 0x40, 0xC2, 0xA8, 0x30, 0xCF, 0xBD, 0x73, 0xC8, 0x13, 0x2B, 0x10, 0x13, + 0x1E, 0x8B, 0x9A, 0xA8, 0x3A, 0x94, 0x73, 0xD3, 0x18, 0x69, 0x0A, 0x4A, + 0xFF, 0xC1, 0x01, 0x03, 0xFF, 0x79, 0x7F, 0xB5, 0x48, 0x7F, 0x7B, 0xEE, + 0xE8, 0x29, 0x6F, 0x36, 0x4C, 0x95, 0x61, 0x86, 0xD8, 0xF9, 0xA2, 0x73, + 0x8A, 0xEE, 0xAE, 0x2F, 0x96, 0xEE, 0x68, 0xCD, 0x3D, 0x4D, 0x28, 0x42, + 0xF9, 0x45, 0x2B, 0x32, 0x1B, 0x46, 0x55, 0x16, 0x6A, 0xA6, 0x4B, 0x29, + 0xF9, 0xBB, 0x95, 0x56, 0xBF, 0x46, 0x1D, 0xEC, 0x1D, 0x93, 0x1D, 0xC0, + 0x65, 0xB2, 0x1F, 0xA1, 0x43, 0xAE, 0x56, 0x9E, 0xA0, 0xB1, 0x8F, 0x6B, + 0x12, 0xB7, 0x60, 0x6D, 0x78, 0x0B, 0xCA, 0x8A, 0x5C, 0xED, 0x1E, 0x96, + 0x0E, 0x83, 0xA6, 0x48, 0x95, 0x8D, 0x3B, 0xA3, 0x21, 0xC4, 0xAE, 0x58, + 0xC6, 0x00, 0xB2, 0x84, 0xB4, 0x23, 0xA4, 0x96, 0x86, 0x35, 0xB8, 0xD8, + 0x9E, 0xD8, 0xAC, 0x34, 0x49, 0x98, 0x63, 0x95, 0xC5, 0xCB, 0x6D, 0x48, + 0x47, 0xE2, 0xF2, 0x2E, 0x18, 0x1E, 0xD0, 0x31, 0xAB, 0xDD, 0x74, 0xEC, + 0xF9, 0xDC, 0x8C, 0xB8, 0x1C, 0x8E, 0x68, 0x23, 0xBA, 0xD0, 0xF3, 0x50, + 0xDC, 0xCF, 0x65, 0x8F, 0x73, 0x3A, 0x32, 0xC7, 0x7C, 0xFE, 0xCA, 0x82, + 0x22, 0x4F, 0xBE, 0x8E, 0x62, 0x47, 0x66, 0xE5, 0xCD, 0x87, 0xE2, 0xE8, + 0xD5, 0x0F, 0x18, 0x9F, 0xE5, 0x04, 0x72, 0x4B, 0x46, 0x3C, 0x10, 0xF2, + 0x44, 0xC2, 0x64, 0x56, 0x71, 0x4E, 0x75, 0xE8, 0x9C, 0xC9, 0x26, 0x74, + 0xC5, 0x7D, 0x59, 0xD1, 0x0A, 0x5B, 0x0F, 0x6D, 0xFE, 0x9E, 0x75, 0x1C, + 0x18, 0xC6, 0x1A, 0x3A, 0x7C, 0xD8, 0x0D, 0x04, 0xCC, 0xCD, 0xB7, 0x45, + 0x65, 0x7A, 0xB1, 0x8F, 0xB8, 0xAE, 0x84, 0x48, 0x3E, 0xB3, 0x7A, 0x4D, + 0xA8, 0x03, 0xE2, 0xE2, 0x7E, 0x01, 0x16, 0x59, 0x68, 0x18, 0x43, 0x33, + 0xB0, 0xD2, 0xDC, 0xB0, 0x1A, 0x43, 0x35, 0xEE, 0xA5, 0xDA, 0xA9, 0x46, + 0x5C, 0xAE, 0x86, 0x81, 0x41, 0x01, 0x4A, 0x74, 0x26, 0xEC, 0x9F, 0x06, + 0xBF, 0xC2, 0x05, 0x37, 0x64, 0x75, 0x78, 0x29, 0x68, 0xFD, 0xC5, 0xF5, + 0xEB, 0xFE, 0x47, 0xF9, 0xE4, 0x85, 0xB0, 0xE1, 0x7B, 0x31, 0x9D, 0xA6, + 0x7F, 0x72, 0xA3, 0xB9, 0xC4, 0x2C, 0x2E, 0xCC, 0x99, 0x57, 0x0E, 0x21, + 0x0C, 0x45, 0x01, 0x94, 0x65, 0xEB, 0x65, 0x09, 0xC6, 0x63, 0x22, 0x0B, + 0x33, 0x49, 0x92, 0x48, 0x3C, 0xFC, 0xCD, 0xCE, 0xB0, 0x3E, 0x8E, 0x9E, + 0x8B, 0xF8, 0xFE, 0x49, 0xC5, 0x35, 0x72, 0x47 +}; + +static const unsigned char TA609_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA610_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x1E, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA610_RSA_N[] = { + 0xD3, 0xB2, 0x4A, 0xCF, 0x7A, 0x47, 0xEF, 0x75, 0x9B, 0x23, 0xFA, 0x3A, + 0x2F, 0xD6, 0x50, 0x45, 0x89, 0x35, 0x3A, 0xC6, 0x6B, 0xDB, 0xFE, 0xDB, + 0x00, 0x68, 0xA8, 0xE0, 0x03, 0x11, 0x1D, 0x37, 0x50, 0x08, 0x9F, 0x4D, + 0x4A, 0x68, 0x94, 0x35, 0xB3, 0x53, 0xD1, 0x94, 0x63, 0xA7, 0x20, 0x56, + 0xAF, 0xDE, 0x51, 0x78, 0xEC, 0x2A, 0x3D, 0xF3, 0x48, 0x48, 0x50, 0x3E, + 0x0A, 0xDF, 0x46, 0x55, 0x8B, 0x27, 0x6D, 0xC3, 0x10, 0x4D, 0x0D, 0x91, + 0x52, 0x43, 0xD8, 0x87, 0xE0, 0x5D, 0x4E, 0x36, 0xB5, 0x21, 0xCA, 0x5F, + 0x39, 0x40, 0x04, 0x5F, 0x5B, 0x7E, 0xCC, 0xA3, 0xC6, 0x2B, 0xA9, 0x40, + 0x1E, 0xD9, 0x36, 0x84, 0xD6, 0x48, 0xF3, 0x92, 0x1E, 0x34, 0x46, 0x20, + 0x24, 0xC1, 0xA4, 0x51, 0x8E, 0x4A, 0x1A, 0xEF, 0x50, 0x3F, 0x69, 0x5D, + 0x19, 0x7F, 0x45, 0xC3, 0xC7, 0x01, 0x8F, 0x51, 0xC9, 0x23, 0xE8, 0x72, + 0xAE, 0xB4, 0xBC, 0x56, 0x09, 0x7F, 0x12, 0xCB, 0x1C, 0xB1, 0xAF, 0x29, + 0x90, 0x0A, 0xC9, 0x55, 0xCC, 0x0F, 0xD3, 0xB4, 0x1A, 0xED, 0x47, 0x35, + 0x5A, 0x4A, 0xED, 0x9C, 0x73, 0x04, 0x21, 0xD0, 0xAA, 0xBD, 0x0C, 0x13, + 0xB5, 0x00, 0xCA, 0x26, 0x6C, 0xC4, 0x6B, 0x0C, 0x94, 0x5A, 0x95, 0x94, + 0xDA, 0x50, 0x9A, 0xF1, 0xFF, 0xA5, 0x2B, 0x66, 0x31, 0xA4, 0xC9, 0x38, + 0xA0, 0xDF, 0x1D, 0x1F, 0xB8, 0x09, 0x2E, 0xF3, 0xA7, 0xE8, 0x67, 0x52, + 0xAB, 0x95, 0x1F, 0xE0, 0x46, 0x3E, 0xD8, 0xA4, 0xC3, 0xCA, 0x5A, 0xC5, + 0x31, 0x80, 0xE8, 0x48, 0x9A, 0x9F, 0x94, 0x69, 0xFE, 0x19, 0xDD, 0xD8, + 0x73, 0x7C, 0x81, 0xCA, 0x96, 0xDE, 0x8E, 0xED, 0xB3, 0x32, 0x05, 0x65, + 0x84, 0x34, 0xE6, 0xE6, 0xFD, 0x57, 0x10, 0xB5, 0x5F, 0x76, 0xBF, 0x2F, + 0xB0, 0x10, 0x0D, 0xC5 +}; + +static const unsigned char TA610_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA611_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x21, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x43, 0x41, + 0x20, 0x32, 0x20, 0x45, 0x56, 0x20, 0x32, 0x30, 0x30, 0x39 +}; + +static const unsigned char TA611_RSA_N[] = { + 0x99, 0xF1, 0x84, 0x34, 0x70, 0xBA, 0x2F, 0xB7, 0x30, 0xA0, 0x8E, 0xBD, + 0x7C, 0x04, 0xCF, 0xBE, 0x62, 0xBC, 0x99, 0xFD, 0x82, 0x97, 0xD2, 0x7A, + 0x0A, 0x67, 0x96, 0x38, 0x09, 0xF6, 0x10, 0x4E, 0x95, 0x22, 0x73, 0x99, + 0x8D, 0xDA, 0x15, 0x2D, 0xE7, 0x05, 0xFC, 0x19, 0x73, 0x22, 0xB7, 0x8E, + 0x98, 0x00, 0xBC, 0x3C, 0x3D, 0xAC, 0xA1, 0x6C, 0xFB, 0xD6, 0x79, 0x25, + 0x4B, 0xAD, 0xF0, 0xCC, 0x64, 0xDA, 0x88, 0x3E, 0x29, 0xB8, 0x0F, 0x09, + 0xD3, 0x34, 0xDD, 0x33, 0xF5, 0x62, 0xD1, 0xE1, 0xCD, 0x19, 0xE9, 0xEE, + 0x18, 0x4F, 0x4C, 0x58, 0xAE, 0xE2, 0x1E, 0xD6, 0x0C, 0x5B, 0x15, 0x5A, + 0xD8, 0x3A, 0xB8, 0xC4, 0x18, 0x64, 0x1E, 0xE3, 0x33, 0xB2, 0xB5, 0x89, + 0x77, 0x4E, 0x0C, 0xBF, 0xD9, 0x94, 0x6B, 0x13, 0x97, 0x6F, 0x12, 0xA3, + 0xFE, 0x99, 0xA9, 0x04, 0xCC, 0x15, 0xEC, 0x60, 0x68, 0x36, 0xED, 0x08, + 0x7B, 0xB7, 0xF5, 0xBF, 0x93, 0xED, 0x66, 0x31, 0x83, 0x8C, 0xC6, 0x71, + 0x34, 0x87, 0x4E, 0x17, 0xEA, 0xAF, 0x8B, 0x91, 0x8D, 0x1C, 0x56, 0x41, + 0xAE, 0x22, 0x37, 0x5E, 0x37, 0xF2, 0x1D, 0xD9, 0xD1, 0x2D, 0x0D, 0x2F, + 0x69, 0x51, 0xA7, 0xBE, 0x66, 0xA6, 0x8A, 0x3A, 0x2A, 0xBD, 0xC7, 0x1A, + 0xB1, 0xE1, 0x14, 0xF0, 0xBE, 0x3A, 0x1D, 0xB9, 0xCF, 0x5B, 0xB1, 0x6A, + 0xFE, 0xB4, 0xB1, 0x46, 0x20, 0xA2, 0xFB, 0x1E, 0x3B, 0x70, 0xEF, 0x93, + 0x98, 0x7D, 0x8C, 0x73, 0x96, 0xF2, 0xC5, 0xEF, 0x85, 0x70, 0xAD, 0x29, + 0x26, 0xFC, 0x1E, 0x04, 0x3E, 0x1C, 0xA0, 0xD8, 0x0F, 0xCB, 0x52, 0x83, + 0x62, 0x7C, 0xEE, 0x8B, 0x53, 0x95, 0x90, 0xA9, 0x57, 0xA2, 0xEA, 0x61, + 0x05, 0xD8, 0xF9, 0x4D, 0xC4, 0x27, 0xFA, 0x6E, 0xAD, 0xED, 0xF9, 0xD7, + 0x51, 0xF7, 0x6B, 0xA5 +}; + +static const unsigned char TA611_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA612_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, + 0x36 +}; + +static const unsigned char TA612_RSA_N[] = { + 0x93, 0xBE, 0xD5, 0x36, 0x52, 0x75, 0xD8, 0x01, 0x23, 0xA0, 0x1C, 0x47, + 0x42, 0x49, 0xEE, 0x63, 0xB6, 0xB7, 0x21, 0xFD, 0xC4, 0x95, 0xD5, 0x48, + 0x2B, 0x26, 0x7C, 0x14, 0x53, 0x10, 0xDA, 0x79, 0xFD, 0x2B, 0xB7, 0x2D, + 0xA4, 0xD4, 0x2C, 0xFA, 0xEA, 0x32, 0xDD, 0x49, 0xC2, 0xB9, 0xBD, 0x0F, + 0x48, 0x3D, 0x7B, 0x5A, 0x98, 0x54, 0xAF, 0x9E, 0x5D, 0x31, 0x74, 0x4F, + 0x07, 0xFC, 0x50, 0x21, 0xDD, 0xA4, 0xCF, 0x68, 0x4F, 0x1B, 0x12, 0x63, + 0x6D, 0x25, 0x99, 0x4C, 0x2A, 0x99, 0xF3, 0x48, 0x30, 0x61, 0xFA, 0x81, + 0x7C, 0x1E, 0xA7, 0x08, 0x4A, 0xDC, 0x3E, 0x2B, 0x1C, 0x1F, 0x18, 0x4C, + 0x71, 0xAA, 0x35, 0x8C, 0xAD, 0xF8, 0x6E, 0xE8, 0x3B, 0x4A, 0xD9, 0xE5, + 0x94, 0x02, 0xD6, 0x89, 0x84, 0x13, 0xAA, 0x6D, 0xC8, 0x4F, 0x33, 0xCC, + 0x50, 0x96, 0x37, 0x92, 0x33, 0xDC, 0x5F, 0x88, 0xE7, 0x9F, 0x54, 0xD9, + 0x48, 0xF0, 0x98, 0x43, 0xD6, 0x66, 0xFD, 0x9F, 0x17, 0x38, 0x43, 0xC5, + 0x01, 0x51, 0x0B, 0xD7, 0xE3, 0x23, 0x0F, 0x14, 0x5D, 0x5B, 0x14, 0xE7, + 0x4B, 0xBE, 0xDD, 0xF4, 0xC8, 0xDA, 0x03, 0x37, 0xD1, 0xD6, 0x39, 0xA1, + 0x21, 0x51, 0x30, 0x83, 0xB0, 0x6D, 0xD7, 0x30, 0x4E, 0x96, 0x5B, 0x91, + 0xF0, 0x70, 0x24, 0xAB, 0xBF, 0x45, 0x81, 0x64, 0x43, 0x0D, 0xBD, 0x21, + 0x3A, 0x2F, 0x3C, 0xE9, 0x9E, 0x0D, 0xCB, 0x20, 0xB5, 0x42, 0x27, 0xCC, + 0xDA, 0x6F, 0x9B, 0xEE, 0x64, 0x30, 0x90, 0x39, 0xCD, 0x93, 0x65, 0x81, + 0x21, 0x31, 0xB5, 0x23, 0x50, 0x33, 0x37, 0x22, 0xE3, 0x38, 0xED, 0xF8, + 0x31, 0x30, 0xCC, 0x45, 0xFE, 0x62, 0xF9, 0xD1, 0x5D, 0x32, 0x79, 0x42, + 0x87, 0xDF, 0x6A, 0xCC, 0x56, 0x19, 0x40, 0x4D, 0xCE, 0xAA, 0xBB, 0xF9, + 0xB5, 0x76, 0x49, 0x94, 0xF1, 0x27, 0xF8, 0x91, 0xA5, 0x83, 0xE5, 0x06, + 0xB3, 0x63, 0x0E, 0x80, 0xDC, 0xE0, 0x12, 0x55, 0x80, 0xA6, 0x3B, 0x66, + 0xB4, 0x39, 0x87, 0x2D, 0xC8, 0xF0, 0xD0, 0xD1, 0x14, 0xE9, 0xE4, 0x0D, + 0x4D, 0x0E, 0xF6, 0x5D, 0x57, 0x72, 0xC5, 0x3B, 0x1C, 0x47, 0x56, 0x9D, + 0xE2, 0xD5, 0xFB, 0x81, 0x61, 0x8C, 0xCC, 0x4D, 0x80, 0x90, 0x34, 0x5B, + 0xB7, 0xD7, 0x14, 0x75, 0xDC, 0xD8, 0x04, 0x48, 0x9F, 0xC0, 0xC1, 0x28, + 0x88, 0xB4, 0xE9, 0x1C, 0xCA, 0xA7, 0xB1, 0xF1, 0x56, 0xB7, 0x7B, 0x49, + 0x4C, 0x59, 0xE5, 0x20, 0x15, 0xA8, 0x84, 0x02, 0x29, 0xFA, 0x38, 0x94, + 0x69, 0x9A, 0x49, 0x06, 0x8F, 0xCD, 0x1F, 0x79, 0x14, 0x17, 0x12, 0x0C, + 0x83, 0x7A, 0xDE, 0x1F, 0xB1, 0x97, 0xEE, 0xF9, 0x97, 0x78, 0x28, 0xA4, + 0xC8, 0x44, 0x92, 0xE9, 0x7D, 0x26, 0x05, 0xA6, 0x58, 0x72, 0x9B, 0x79, + 0x13, 0xD8, 0x11, 0x5F, 0xAE, 0xC5, 0x38, 0x62, 0x34, 0x68, 0xB2, 0x86, + 0x30, 0x8E, 0xF8, 0x90, 0x61, 0x9E, 0x32, 0x6C, 0xF5, 0x07, 0x36, 0xCD, + 0xA2, 0x4C, 0x6E, 0xEC, 0x8A, 0x36, 0xED, 0xF2, 0xE6, 0x99, 0x15, 0x44, + 0x70, 0xC3, 0x7C, 0xBC, 0x9C, 0x39, 0xC0, 0xB4, 0xE1, 0x6B, 0xF7, 0x83, + 0x25, 0x23, 0x57, 0xD9, 0x12, 0x80, 0xE5, 0x49, 0xF0, 0x75, 0x0F, 0xEF, + 0x8D, 0xEB, 0x1C, 0x9B, 0x54, 0x28, 0xB4, 0x21, 0x3C, 0xFC, 0x7C, 0x0A, + 0xFF, 0xEF, 0x7B, 0x6B, 0x75, 0xFF, 0x8B, 0x1D, 0xA0, 0x19, 0x05, 0xAB, + 0xFA, 0xF8, 0x2B, 0x81, 0x42, 0xE8, 0x38, 0xBA, 0xBB, 0xFB, 0xAA, 0xFD, + 0x3D, 0xE0, 0xF3, 0xCA, 0xDF, 0x4E, 0x97, 0x97, 0x29, 0xED, 0xF3, 0x18, + 0x56, 0xE9, 0xA5, 0x96, 0xAC, 0xBD, 0xC3, 0x90, 0x98, 0xB2, 0xE0, 0xF9, + 0xA2, 0xD4, 0xA6, 0x47, 0x43, 0x7C, 0x6D, 0xCF +}; + +static const unsigned char TA612_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA613_DN[] = { + 0x30, 0x34, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x08, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61 +}; + +static const unsigned char TA613_RSA_N[] = { + 0xC8, 0x68, 0xF1, 0xC9, 0xD6, 0xD6, 0xB3, 0x34, 0x75, 0x26, 0x82, 0x1E, + 0xEC, 0xB4, 0xBE, 0xEA, 0x5C, 0xE1, 0x26, 0xED, 0x11, 0x47, 0x61, 0xE1, + 0xA2, 0x7C, 0x16, 0x78, 0x40, 0x21, 0xE4, 0x60, 0x9E, 0x5A, 0xC8, 0x63, + 0xE1, 0xC4, 0xB1, 0x96, 0x92, 0xFF, 0x18, 0x6D, 0x69, 0x23, 0xE1, 0x2B, + 0x62, 0xF7, 0xDD, 0xE2, 0x36, 0x2F, 0x91, 0x07, 0xB9, 0x48, 0xCF, 0x0E, + 0xEC, 0x79, 0xB6, 0x2C, 0xE7, 0x34, 0x4B, 0x70, 0x08, 0x25, 0xA3, 0x3C, + 0x87, 0x1B, 0x19, 0xF2, 0x81, 0x07, 0x0F, 0x38, 0x90, 0x19, 0xD3, 0x11, + 0xFE, 0x86, 0xB4, 0xF2, 0xD1, 0x5E, 0x1E, 0x1E, 0x96, 0xCD, 0x80, 0x6C, + 0xCE, 0x3B, 0x31, 0x93, 0xB6, 0xF2, 0xA0, 0xD0, 0xA9, 0x95, 0x12, 0x7D, + 0xA5, 0x9A, 0xCC, 0x6B, 0xC8, 0x84, 0x56, 0x8A, 0x33, 0xA9, 0xE7, 0x22, + 0x15, 0x53, 0x16, 0xF0, 0xCC, 0x17, 0xEC, 0x57, 0x5F, 0xE9, 0xA2, 0x0A, + 0x98, 0x09, 0xDE, 0xE3, 0x5F, 0x9C, 0x6F, 0xDC, 0x48, 0xE3, 0x85, 0x0B, + 0x15, 0x5A, 0xA6, 0xBA, 0x9F, 0xAC, 0x48, 0xE3, 0x09, 0xB2, 0xF7, 0xF4, + 0x32, 0xDE, 0x5E, 0x34, 0xBE, 0x1C, 0x78, 0x5D, 0x42, 0x5B, 0xCE, 0x0E, + 0x22, 0x8F, 0x4D, 0x90, 0xD7, 0x7D, 0x32, 0x18, 0xB3, 0x0B, 0x2C, 0x6A, + 0xBF, 0x8E, 0x3F, 0x14, 0x11, 0x89, 0x20, 0x0E, 0x77, 0x14, 0xB5, 0x3D, + 0x94, 0x08, 0x87, 0xF7, 0x25, 0x1E, 0xD5, 0xB2, 0x60, 0x00, 0xEC, 0x6F, + 0x2A, 0x28, 0x25, 0x6E, 0x2A, 0x3E, 0x18, 0x63, 0x17, 0x25, 0x3F, 0x3E, + 0x44, 0x20, 0x16, 0xF6, 0x26, 0xC8, 0x25, 0xAE, 0x05, 0x4A, 0xB4, 0xE7, + 0x63, 0x2C, 0xF3, 0x8C, 0x16, 0x53, 0x7E, 0x5C, 0xFB, 0x11, 0x1A, 0x08, + 0xC1, 0x46, 0x62, 0x9F, 0x22, 0xB8, 0xF1, 0xC2, 0x8D, 0x69, 0xDC, 0xFA, + 0x3A, 0x58, 0x06, 0xDF +}; + +static const unsigned char TA613_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA614_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x4E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4E, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x65, 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x71, 0x75, 0x65, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, + 0x75, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA614_RSA_N[] = { + 0xC3, 0xCD, 0xD3, 0xFC, 0xBD, 0x04, 0x53, 0xDD, 0x0C, 0x20, 0x3A, 0xD5, + 0x88, 0x2E, 0x05, 0x4B, 0x41, 0xF5, 0x83, 0x82, 0x7E, 0xF7, 0x59, 0x9F, + 0x9E, 0x9E, 0x63, 0xE8, 0x73, 0xDA, 0xF6, 0x06, 0xA9, 0x4F, 0x1F, 0xB4, + 0xF9, 0x0B, 0x1F, 0x39, 0x8C, 0x9A, 0x20, 0xD0, 0x7E, 0x06, 0xD4, 0xEC, + 0x34, 0xD9, 0x86, 0xBC, 0x75, 0x5B, 0x87, 0x88, 0xF0, 0xD2, 0xD9, 0xD4, + 0xA3, 0x0A, 0xB2, 0x6C, 0x1B, 0xEB, 0x49, 0x2C, 0x3E, 0xAC, 0x5D, 0xD8, + 0x94, 0x03, 0xA0, 0xEC, 0x34, 0xE5, 0x30, 0xC4, 0x35, 0x7D, 0xFB, 0x26, + 0x4D, 0x1B, 0x6E, 0x30, 0x54, 0xD8, 0xF5, 0x80, 0x45, 0x9C, 0x39, 0xAD, + 0x9C, 0xC9, 0x25, 0x04, 0x4D, 0x9A, 0x90, 0x3E, 0x4E, 0x40, 0x6E, 0x8A, + 0x6B, 0xCD, 0x29, 0x67, 0xC6, 0xCC, 0x2D, 0xE0, 0x74, 0xE8, 0x05, 0x57, + 0x0A, 0x48, 0x50, 0xFA, 0x7A, 0x43, 0xDA, 0x7E, 0xEC, 0x5B, 0x9A, 0x0E, + 0x62, 0x76, 0xFE, 0xEA, 0x9D, 0x1D, 0x85, 0x72, 0xEC, 0x11, 0xBB, 0x35, + 0xE8, 0x1F, 0x27, 0xBF, 0xC1, 0xA1, 0xC7, 0xBB, 0x48, 0x16, 0xDD, 0x56, + 0xD7, 0xCC, 0x4E, 0xA0, 0xE1, 0xB9, 0xAC, 0xDB, 0xD5, 0x83, 0x19, 0x1A, + 0x85, 0xD1, 0x94, 0x97, 0xD7, 0xCA, 0xA3, 0x65, 0x0B, 0xF3, 0x38, 0xF9, + 0x02, 0xAE, 0xDD, 0xF6, 0x67, 0xCF, 0xC9, 0x3F, 0xF5, 0x8A, 0x2C, 0x47, + 0x1A, 0x99, 0x6F, 0x05, 0x0D, 0xFD, 0xD0, 0x1D, 0x82, 0x31, 0xFC, 0x29, + 0xCC, 0x00, 0x58, 0x97, 0x91, 0x4C, 0x80, 0x00, 0x1C, 0x33, 0x85, 0x96, + 0x2F, 0xCB, 0x41, 0xC2, 0x8B, 0x10, 0x84, 0xC3, 0x09, 0x24, 0x89, 0x1F, + 0xB5, 0x0F, 0xD9, 0xD9, 0x77, 0x47, 0x18, 0x92, 0x94, 0x60, 0x5C, 0xC7, + 0x99, 0x03, 0x3C, 0xFE, 0xF7, 0x95, 0xA7, 0x7D, 0x50, 0xA1, 0x80, 0xC2, + 0xA9, 0x83, 0xAD, 0x58, 0x96, 0x55, 0x21, 0xDB, 0x86, 0x59, 0xD4, 0xAF, + 0xC6, 0xBC, 0xDD, 0x81, 0x6E, 0x07, 0xDB, 0x60, 0x62, 0xFE, 0xEC, 0x10, + 0x6E, 0xDA, 0x68, 0x01, 0xF4, 0x83, 0x1B, 0xA9, 0x3E, 0xA2, 0x5B, 0x23, + 0xD7, 0x64, 0xC6, 0xDF, 0xDC, 0xA2, 0x7D, 0xD8, 0x4B, 0xBA, 0x82, 0xD2, + 0x51, 0xF8, 0x66, 0xBF, 0x06, 0x46, 0xE4, 0x79, 0x2A, 0x26, 0x36, 0x79, + 0x8F, 0x1F, 0x4E, 0x99, 0x1D, 0xB2, 0x8F, 0x0C, 0x0E, 0x1C, 0xFF, 0xC9, + 0x5D, 0xC0, 0xFD, 0x90, 0x10, 0xA6, 0xB1, 0x37, 0xF3, 0xCD, 0x3A, 0x24, + 0x6E, 0xB4, 0x85, 0x90, 0xBF, 0x80, 0xB9, 0x0C, 0x8C, 0xD5, 0x9B, 0xD6, + 0xC8, 0xF1, 0x56, 0x3F, 0x1A, 0x80, 0x89, 0x7A, 0xA9, 0xE2, 0x1B, 0x32, + 0x51, 0x2C, 0x3E, 0xF2, 0xDF, 0x7B, 0xF6, 0x5D, 0x7A, 0x29, 0x19, 0x8E, + 0xE5, 0xC8, 0xBD, 0x36, 0x71, 0x8B, 0x5D, 0x4C, 0xC2, 0x1D, 0x3F, 0xAD, + 0x58, 0xA2, 0xCF, 0x3D, 0x70, 0x4D, 0xA6, 0x50, 0x98, 0x25, 0xDC, 0x23, + 0xF9, 0xB8, 0x58, 0x41, 0x08, 0x71, 0xBF, 0x4F, 0xB8, 0x84, 0xA0, 0x8F, + 0x00, 0x54, 0x15, 0xFC, 0x91, 0x6D, 0x58, 0xA7, 0x96, 0x3B, 0xEB, 0x4B, + 0x96, 0x27, 0xCD, 0x6B, 0xA2, 0xA1, 0x86, 0xAC, 0x0D, 0x7C, 0x54, 0xE6, + 0x66, 0x4C, 0x66, 0x5F, 0x90, 0xBE, 0x21, 0x9A, 0x02, 0x46, 0x2D, 0xE4, + 0x83, 0xC2, 0x80, 0xB9, 0xCF, 0x4B, 0x3E, 0xE8, 0x7F, 0x3C, 0x01, 0xEC, + 0x8F, 0x5E, 0xCD, 0x7F, 0xD2, 0x28, 0x42, 0x01, 0x95, 0x8A, 0xE2, 0x97, + 0x3D, 0x10, 0x21, 0x7D, 0xF6, 0x9D, 0x1C, 0xC5, 0x34, 0xA1, 0xEC, 0x2C, + 0x0E, 0x0A, 0x52, 0x2C, 0x12, 0x55, 0x70, 0x24, 0x3D, 0xCB, 0xC2, 0x14, + 0x35, 0x43, 0x5D, 0x27, 0x4E, 0xBE, 0xC0, 0xBD, 0xAA, 0x7C, 0x96, 0xE7, + 0xFC, 0x9E, 0x61, 0xAD, 0x44, 0xD3, 0x00, 0x97 +}; + +static const unsigned char TA614_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA615_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA615_RSA_N[] = { + 0xB3, 0xCB, 0x0E, 0x10, 0x67, 0x8E, 0xEA, 0x14, 0x97, 0xA7, 0x32, 0x2A, + 0x0A, 0x56, 0x36, 0x7F, 0x68, 0x4C, 0xC7, 0xB3, 0x6F, 0x3A, 0x23, 0x14, + 0x91, 0xFF, 0x19, 0x7F, 0xA5, 0xCA, 0xAC, 0xEE, 0xB3, 0x76, 0x9D, 0x7A, + 0xE9, 0x8B, 0x1B, 0xAB, 0x6B, 0x31, 0xDB, 0xFA, 0x0B, 0x53, 0x4C, 0xAF, + 0xC5, 0xA5, 0x1A, 0x79, 0x3C, 0x8A, 0x4C, 0xFF, 0xAC, 0xDF, 0x25, 0xDE, + 0x4E, 0xD9, 0x82, 0x32, 0x0B, 0x44, 0xDE, 0xCA, 0xDB, 0x8C, 0xAC, 0xA3, + 0x6E, 0x16, 0x83, 0x3B, 0xA6, 0x64, 0x4B, 0x32, 0x89, 0xFB, 0x16, 0x16, + 0x38, 0x7E, 0xEB, 0x43, 0xE2, 0xD3, 0x74, 0x4A, 0xC2, 0x62, 0x0A, 0x73, + 0x0A, 0xDD, 0x49, 0xB3, 0x57, 0xD2, 0xB0, 0x0A, 0x85, 0x9D, 0x71, 0x3C, + 0xDE, 0xA3, 0xCB, 0xC0, 0x32, 0xF3, 0x01, 0x39, 0x20, 0x43, 0x1B, 0x35, + 0xD1, 0x53, 0xB3, 0xB1, 0xEE, 0xC5, 0x93, 0x69, 0x82, 0x3E, 0x16, 0xB5, + 0x28, 0x46, 0xA1, 0xDE, 0xEA, 0x89, 0x09, 0xED, 0x43, 0xB8, 0x05, 0x46, + 0x8A, 0x86, 0xF5, 0x59, 0x47, 0xBE, 0x1B, 0x6F, 0x01, 0x21, 0x10, 0xB9, + 0xFD, 0xA9, 0xD2, 0x28, 0xCA, 0x10, 0x39, 0x09, 0xCA, 0x13, 0x36, 0xCF, + 0x9C, 0xAD, 0xAD, 0x40, 0x74, 0x79, 0x2B, 0x02, 0x3F, 0x34, 0xFF, 0xFA, + 0x20, 0x69, 0x7D, 0xD3, 0xEE, 0x61, 0xF5, 0xBA, 0xB3, 0xE7, 0x30, 0xD0, + 0x37, 0x23, 0x86, 0x72, 0x61, 0x45, 0x29, 0x48, 0x59, 0x68, 0x6F, 0x77, + 0xA6, 0x2E, 0x81, 0xBE, 0x07, 0x4D, 0x6F, 0xAF, 0xCE, 0xC4, 0x45, 0x13, + 0x91, 0x14, 0x70, 0x06, 0x8F, 0x1F, 0x9F, 0xF8, 0x87, 0x69, 0xB1, 0x0E, + 0xEF, 0xC3, 0x89, 0x19, 0xEB, 0xEA, 0x1C, 0x61, 0xFC, 0x7A, 0x6C, 0x8A, + 0xDC, 0xD6, 0x03, 0x0B, 0x9E, 0x26, 0xBA, 0x12, 0xDD, 0xD4, 0x54, 0x39, + 0xAB, 0x26, 0xA3, 0x33, 0xEA, 0x75, 0x81, 0xDA, 0x2D, 0xCD, 0x0F, 0x4F, + 0xE4, 0x03, 0xD1, 0xEF, 0x15, 0x97, 0x1B, 0x6B, 0x90, 0xC5, 0x02, 0x90, + 0x93, 0x66, 0x02, 0x21, 0xB1, 0x47, 0xDE, 0x8B, 0x9A, 0x4A, 0x80, 0xB9, + 0x55, 0x8F, 0xB5, 0xA2, 0x2F, 0xC0, 0xD6, 0x33, 0x67, 0xDA, 0x7E, 0xC4, + 0xA7, 0xB4, 0x04, 0x44, 0xEB, 0x47, 0xFB, 0xE6, 0x58, 0xB9, 0xF7, 0x0C, + 0xF0, 0x7B, 0x2B, 0xB1, 0xC0, 0x70, 0x29, 0xC3, 0x40, 0x62, 0x2D, 0x3B, + 0x48, 0x69, 0xDC, 0x23, 0x3C, 0x48, 0xEB, 0x7B, 0x09, 0x79, 0xA9, 0x6D, + 0xDA, 0xA8, 0x30, 0x98, 0xCF, 0x80, 0x72, 0x03, 0x88, 0xA6, 0x5B, 0x46, + 0xAE, 0x72, 0x79, 0x7C, 0x08, 0x03, 0x21, 0x65, 0xAE, 0xB7, 0xE1, 0x1C, + 0xA5, 0xB1, 0x2A, 0xA2, 0x31, 0xDE, 0x66, 0x04, 0xF7, 0xC0, 0x74, 0xE8, + 0x71, 0xDE, 0xFF, 0x3D, 0x59, 0xCC, 0x96, 0x26, 0x12, 0x8B, 0x85, 0x95, + 0x57, 0x1A, 0xAB, 0x6B, 0x75, 0x0B, 0x44, 0x3D, 0x11, 0x28, 0x3C, 0x7B, + 0x61, 0xB7, 0xE2, 0x8F, 0x67, 0x4F, 0xE5, 0xEC, 0x3C, 0x4C, 0x60, 0x80, + 0x69, 0x57, 0x38, 0x1E, 0x01, 0x5B, 0x8D, 0x55, 0xE8, 0xC7, 0xDF, 0xC0, + 0xCC, 0x77, 0x23, 0x34, 0x49, 0x75, 0x7C, 0xF6, 0x98, 0x11, 0xEB, 0x2D, + 0xDE, 0xED, 0x41, 0x2E, 0x14, 0x05, 0x02, 0x7F, 0xE0, 0xFE, 0x20, 0xEB, + 0x35, 0xE7, 0x11, 0xAC, 0x22, 0xCE, 0x57, 0x3D, 0xDE, 0xC9, 0x30, 0x6D, + 0x10, 0x03, 0x85, 0xCD, 0xF1, 0xFF, 0x8C, 0x16, 0xB5, 0xC1, 0xB2, 0x3E, + 0x88, 0x6C, 0x60, 0x7F, 0x90, 0x4F, 0x95, 0xF7, 0xF6, 0x2D, 0xAD, 0x01, + 0x39, 0x07, 0x04, 0xFA, 0x75, 0x80, 0x7D, 0xBF, 0x49, 0x50, 0xED, 0xEF, + 0xC9, 0xC4, 0x7C, 0x1C, 0xEB, 0x80, 0x7E, 0xDB, 0xB6, 0xD0, 0xDD, 0x13, + 0xFE, 0xC9, 0xD3, 0x9C, 0xD7, 0xB2, 0x97, 0xA9 +}; + +static const unsigned char TA615_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA616_DN[] = { + 0x30, 0x7A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA616_RSA_N[] = { + 0xD1, 0x2D, 0x8E, 0xBB, 0xB7, 0x36, 0xEA, 0x6D, 0x37, 0x91, 0x9F, 0x4E, + 0x93, 0xA7, 0x05, 0xE4, 0x29, 0x03, 0x25, 0xCE, 0x1C, 0x82, 0xF7, 0x7C, + 0x99, 0x9F, 0x41, 0x06, 0xCD, 0xED, 0xA3, 0xBA, 0xC0, 0xDB, 0x09, 0x2C, + 0xC1, 0x7C, 0xDF, 0x29, 0x7E, 0x4B, 0x65, 0x2F, 0x93, 0xA7, 0xD4, 0x01, + 0x6B, 0x03, 0x28, 0x18, 0xA3, 0xD8, 0x9D, 0x05, 0xC1, 0x2A, 0xD8, 0x45, + 0xF1, 0x91, 0xDE, 0xDF, 0x3B, 0xD0, 0x80, 0x02, 0x8C, 0xCF, 0x38, 0x0F, + 0xEA, 0xA7, 0x5C, 0x78, 0x11, 0xA4, 0xC1, 0xC8, 0x85, 0x5C, 0x25, 0xD3, + 0xD3, 0xB2, 0xE7, 0x25, 0xCF, 0x11, 0x54, 0x97, 0xAB, 0x35, 0xC0, 0x1E, + 0x76, 0x1C, 0xEF, 0x00, 0x53, 0x9F, 0x39, 0xDC, 0x14, 0xA5, 0x2C, 0x22, + 0x25, 0xB3, 0x72, 0x72, 0xFC, 0x8D, 0xB3, 0xE5, 0x3E, 0x08, 0x1E, 0x14, + 0x2A, 0x37, 0x0B, 0x88, 0x3C, 0xCA, 0xB0, 0xF4, 0xC8, 0xC2, 0xA1, 0xAE, + 0xBC, 0xC1, 0xBE, 0x29, 0x67, 0x55, 0xE2, 0xFC, 0xAD, 0x59, 0x5C, 0xFE, + 0xBD, 0x57, 0x2C, 0xB0, 0x90, 0x8D, 0xC2, 0xED, 0x37, 0xB6, 0x7C, 0x99, + 0x88, 0xB5, 0xD5, 0x03, 0x9A, 0x3D, 0x15, 0x0D, 0x3D, 0x3A, 0xA8, 0xA8, + 0x45, 0xF0, 0x95, 0x4E, 0x25, 0x59, 0x1D, 0xCD, 0x98, 0x69, 0xBB, 0xD3, + 0xCC, 0x32, 0xC9, 0x8D, 0xEF, 0x81, 0xFE, 0xAD, 0x7D, 0x89, 0xBB, 0xBA, + 0x60, 0x13, 0xCA, 0x65, 0x95, 0x67, 0xA0, 0xF3, 0x19, 0xF6, 0x03, 0x56, + 0xD4, 0x6A, 0xD3, 0x27, 0xE2, 0xA1, 0xAD, 0x83, 0xF0, 0x4A, 0x12, 0x22, + 0x77, 0x1C, 0x05, 0x73, 0xE2, 0x19, 0x71, 0x42, 0xC0, 0xEC, 0x75, 0x46, + 0x9A, 0x90, 0x58, 0xE0, 0x6A, 0x8E, 0x2B, 0xA5, 0x46, 0x30, 0x04, 0x8E, + 0x19, 0xB2, 0x17, 0xE3, 0xBE, 0xA9, 0xBA, 0x7F, 0x56, 0xF1, 0x24, 0x03, + 0xD7, 0xB2, 0x21, 0x28, 0x76, 0x0E, 0x36, 0x30, 0x4C, 0x79, 0xD5, 0x41, + 0x9A, 0x9A, 0xA8, 0xB8, 0x35, 0xBA, 0x0C, 0x3A, 0xF2, 0x44, 0x1B, 0x20, + 0x88, 0xF7, 0xC5, 0x25, 0xD7, 0x3D, 0xC6, 0xE3, 0x3E, 0x43, 0xDD, 0x87, + 0xFE, 0xC4, 0xEA, 0xF5, 0x53, 0x3E, 0x4C, 0x65, 0xFF, 0x3B, 0x4A, 0xCB, + 0x78, 0x5A, 0x6B, 0x17, 0x5F, 0x0D, 0xC7, 0xC3, 0x4F, 0x4E, 0x9A, 0x2A, + 0xA2, 0xED, 0x57, 0x4D, 0x22, 0xE2, 0x46, 0x9A, 0x3F, 0x0F, 0x91, 0x34, + 0x24, 0x7D, 0x55, 0xE3, 0x8C, 0x95, 0x37, 0xD3, 0x1A, 0xF0, 0x09, 0x2B, + 0x2C, 0xD2, 0xC9, 0x8D, 0xB4, 0x0D, 0x00, 0xAB, 0x67, 0x29, 0x28, 0xD8, + 0x01, 0xF5, 0x19, 0x04, 0xB6, 0x1D, 0xBE, 0x76, 0xFE, 0x72, 0x5C, 0xC4, + 0x85, 0xCA, 0xD2, 0x80, 0x41, 0xDF, 0x05, 0xA8, 0xA3, 0xD5, 0x84, 0x90, + 0x4F, 0x0B, 0xF3, 0xE0, 0x3F, 0x9B, 0x19, 0xD2, 0x37, 0x89, 0x3F, 0xF2, + 0x7B, 0x52, 0x1C, 0x8C, 0xF6, 0xE1, 0xF7, 0x3C, 0x07, 0x97, 0x8C, 0x0E, + 0xA2, 0x59, 0x81, 0x0C, 0xB2, 0x90, 0x3D, 0xD3, 0xE3, 0x59, 0x46, 0xED, + 0x0F, 0xA9, 0xA7, 0xDE, 0x80, 0x6B, 0x5A, 0xAA, 0x07, 0xB6, 0x19, 0xCB, + 0xBC, 0x57, 0xF3, 0x97, 0x21, 0x7A, 0x0C, 0xB1, 0x2B, 0x74, 0x3E, 0xEB, + 0xDA, 0xA7, 0x67, 0x2D, 0x4C, 0xC4, 0x98, 0x9E, 0x36, 0x09, 0x76, 0x66, + 0x66, 0xFC, 0x1A, 0x3F, 0xEA, 0x48, 0x54, 0x1C, 0xBE, 0x30, 0xBD, 0x80, + 0x50, 0xBF, 0x7C, 0xB5, 0xCE, 0x00, 0xF6, 0x0C, 0x61, 0xD9, 0xE7, 0x24, + 0x03, 0xE0, 0xE3, 0x01, 0x81, 0x0E, 0xBD, 0xD8, 0x85, 0x34, 0x88, 0xBD, + 0xB2, 0x36, 0xA8, 0x7B, 0x5C, 0x08, 0xE5, 0x44, 0x80, 0x8C, 0x6F, 0xF8, + 0x2F, 0xD5, 0x21, 0xCA, 0x1D, 0x1C, 0xD0, 0xFB, 0xC4, 0xB5, 0x87, 0xD1, + 0x3A, 0x4E, 0xC7, 0x76, 0xB5, 0x35, 0x48, 0xB5 +}; + +static const unsigned char TA616_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA617_DN[] = { + 0x30, 0x3C, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x15, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x32, 0x30, 0x31, 0x31, 0x31, 0x0D, + 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x04, 0x41, 0x74, 0x6F, + 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x44, 0x45 +}; + +static const unsigned char TA617_RSA_N[] = { + 0x95, 0x85, 0x3B, 0x97, 0x6F, 0x2A, 0x3B, 0x2E, 0x3B, 0xCF, 0xA6, 0xF3, + 0x29, 0x35, 0xBE, 0xCF, 0x18, 0xAC, 0x3E, 0xAA, 0xD9, 0xF8, 0x4D, 0xA0, + 0x3E, 0x1A, 0x47, 0xB9, 0xBC, 0x9A, 0xDF, 0xF2, 0xFE, 0xCC, 0x3E, 0x47, + 0xE8, 0x7A, 0x96, 0xC2, 0x24, 0x8E, 0x35, 0xF4, 0xA9, 0x0C, 0xFC, 0x82, + 0xFD, 0x6D, 0xC1, 0x72, 0x62, 0x27, 0xBD, 0xEA, 0x6B, 0xEB, 0xE7, 0x8A, + 0xCC, 0x54, 0x3E, 0x90, 0x50, 0xCF, 0x80, 0xD4, 0x95, 0xFB, 0xE8, 0xB5, + 0x82, 0xD4, 0x14, 0xC5, 0xB6, 0xA9, 0x55, 0x25, 0x57, 0xDB, 0xB1, 0x50, + 0xF6, 0xB0, 0x60, 0x64, 0x59, 0x7A, 0x69, 0xCF, 0x03, 0xB7, 0x6F, 0x0D, + 0xBE, 0xCA, 0x3E, 0x6F, 0x74, 0x72, 0xEA, 0xAA, 0x30, 0x2A, 0x73, 0x62, + 0xBE, 0x49, 0x91, 0x61, 0xC8, 0x11, 0xFE, 0x0E, 0x03, 0x2A, 0xF7, 0x6A, + 0x20, 0xDC, 0x02, 0x15, 0x0D, 0x5E, 0x15, 0x6A, 0xFC, 0xE3, 0x82, 0xC1, + 0xB5, 0xC5, 0x9D, 0x64, 0x09, 0x6C, 0xA3, 0x59, 0x98, 0x07, 0x27, 0xC7, + 0x1B, 0x96, 0x2B, 0x61, 0x74, 0x71, 0x6C, 0x43, 0xF1, 0xF7, 0x35, 0x89, + 0x10, 0xE0, 0x9E, 0xEC, 0x55, 0xA1, 0x37, 0x22, 0xA2, 0x87, 0x04, 0x05, + 0x2C, 0x47, 0x7D, 0xB4, 0x1C, 0xB9, 0x62, 0x29, 0x66, 0x28, 0xCA, 0xB7, + 0xE1, 0x93, 0xF5, 0xA4, 0x94, 0x03, 0x99, 0xB9, 0x70, 0x85, 0xB5, 0xE6, + 0x48, 0xEA, 0x8D, 0x50, 0xFC, 0xD9, 0xDE, 0xCC, 0x6F, 0x07, 0x0E, 0xDD, + 0x0B, 0x72, 0x9D, 0x80, 0x30, 0x16, 0x07, 0x95, 0x3F, 0x28, 0x0E, 0xFD, + 0xC5, 0x75, 0x4F, 0x53, 0xD6, 0x74, 0x9A, 0xB4, 0x24, 0x2E, 0x8E, 0x02, + 0x91, 0xCF, 0x76, 0xC5, 0x9B, 0x1E, 0x55, 0x74, 0x9C, 0x78, 0x21, 0xB1, + 0xF0, 0x2D, 0xF1, 0x0B, 0x9F, 0xC2, 0xD5, 0x96, 0x18, 0x1F, 0xF0, 0x54, + 0x22, 0x7A, 0x8C, 0x07 +}; + +static const unsigned char TA617_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA618_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA618_RSA_N[] = { + 0xB3, 0xCB, 0x0E, 0x10, 0x67, 0x8E, 0xEA, 0x14, 0x97, 0xA7, 0x32, 0x2A, + 0x0A, 0x56, 0x36, 0x7F, 0x68, 0x4C, 0xC7, 0xB3, 0x6F, 0x3A, 0x23, 0x14, + 0x91, 0xFF, 0x19, 0x7F, 0xA5, 0xCA, 0xAC, 0xEE, 0xB3, 0x76, 0x9D, 0x7A, + 0xE9, 0x8B, 0x1B, 0xAB, 0x6B, 0x31, 0xDB, 0xFA, 0x0B, 0x53, 0x4C, 0xAF, + 0xC5, 0xA5, 0x1A, 0x79, 0x3C, 0x8A, 0x4C, 0xFF, 0xAC, 0xDF, 0x25, 0xDE, + 0x4E, 0xD9, 0x82, 0x32, 0x0B, 0x44, 0xDE, 0xCA, 0xDB, 0x8C, 0xAC, 0xA3, + 0x6E, 0x16, 0x83, 0x3B, 0xA6, 0x64, 0x4B, 0x32, 0x89, 0xFB, 0x16, 0x16, + 0x38, 0x7E, 0xEB, 0x43, 0xE2, 0xD3, 0x74, 0x4A, 0xC2, 0x62, 0x0A, 0x73, + 0x0A, 0xDD, 0x49, 0xB3, 0x57, 0xD2, 0xB0, 0x0A, 0x85, 0x9D, 0x71, 0x3C, + 0xDE, 0xA3, 0xCB, 0xC0, 0x32, 0xF3, 0x01, 0x39, 0x20, 0x43, 0x1B, 0x35, + 0xD1, 0x53, 0xB3, 0xB1, 0xEE, 0xC5, 0x93, 0x69, 0x82, 0x3E, 0x16, 0xB5, + 0x28, 0x46, 0xA1, 0xDE, 0xEA, 0x89, 0x09, 0xED, 0x43, 0xB8, 0x05, 0x46, + 0x8A, 0x86, 0xF5, 0x59, 0x47, 0xBE, 0x1B, 0x6F, 0x01, 0x21, 0x10, 0xB9, + 0xFD, 0xA9, 0xD2, 0x28, 0xCA, 0x10, 0x39, 0x09, 0xCA, 0x13, 0x36, 0xCF, + 0x9C, 0xAD, 0xAD, 0x40, 0x74, 0x79, 0x2B, 0x02, 0x3F, 0x34, 0xFF, 0xFA, + 0x20, 0x69, 0x7D, 0xD3, 0xEE, 0x61, 0xF5, 0xBA, 0xB3, 0xE7, 0x30, 0xD0, + 0x37, 0x23, 0x86, 0x72, 0x61, 0x45, 0x29, 0x48, 0x59, 0x68, 0x6F, 0x77, + 0xA6, 0x2E, 0x81, 0xBE, 0x07, 0x4D, 0x6F, 0xAF, 0xCE, 0xC4, 0x45, 0x13, + 0x91, 0x14, 0x70, 0x06, 0x8F, 0x1F, 0x9F, 0xF8, 0x87, 0x69, 0xB1, 0x0E, + 0xEF, 0xC3, 0x89, 0x19, 0xEB, 0xEA, 0x1C, 0x61, 0xFC, 0x7A, 0x6C, 0x8A, + 0xDC, 0xD6, 0x03, 0x0B, 0x9E, 0x26, 0xBA, 0x12, 0xDD, 0xD4, 0x54, 0x39, + 0xAB, 0x26, 0xA3, 0x33, 0xEA, 0x75, 0x81, 0xDA, 0x2D, 0xCD, 0x0F, 0x4F, + 0xE4, 0x03, 0xD1, 0xEF, 0x15, 0x97, 0x1B, 0x6B, 0x90, 0xC5, 0x02, 0x90, + 0x93, 0x66, 0x02, 0x21, 0xB1, 0x47, 0xDE, 0x8B, 0x9A, 0x4A, 0x80, 0xB9, + 0x55, 0x8F, 0xB5, 0xA2, 0x2F, 0xC0, 0xD6, 0x33, 0x67, 0xDA, 0x7E, 0xC4, + 0xA7, 0xB4, 0x04, 0x44, 0xEB, 0x47, 0xFB, 0xE6, 0x58, 0xB9, 0xF7, 0x0C, + 0xF0, 0x7B, 0x2B, 0xB1, 0xC0, 0x70, 0x29, 0xC3, 0x40, 0x62, 0x2D, 0x3B, + 0x48, 0x69, 0xDC, 0x23, 0x3C, 0x48, 0xEB, 0x7B, 0x09, 0x79, 0xA9, 0x6D, + 0xDA, 0xA8, 0x30, 0x98, 0xCF, 0x80, 0x72, 0x03, 0x88, 0xA6, 0x5B, 0x46, + 0xAE, 0x72, 0x79, 0x7C, 0x08, 0x03, 0x21, 0x65, 0xAE, 0xB7, 0xE1, 0x1C, + 0xA5, 0xB1, 0x2A, 0xA2, 0x31, 0xDE, 0x66, 0x04, 0xF7, 0xC0, 0x74, 0xE8, + 0x71, 0xDE, 0xFF, 0x3D, 0x59, 0xCC, 0x96, 0x26, 0x12, 0x8B, 0x85, 0x95, + 0x57, 0x1A, 0xAB, 0x6B, 0x75, 0x0B, 0x44, 0x3D, 0x11, 0x28, 0x3C, 0x7B, + 0x61, 0xB7, 0xE2, 0x8F, 0x67, 0x4F, 0xE5, 0xEC, 0x3C, 0x4C, 0x60, 0x80, + 0x69, 0x57, 0x38, 0x1E, 0x01, 0x5B, 0x8D, 0x55, 0xE8, 0xC7, 0xDF, 0xC0, + 0xCC, 0x77, 0x23, 0x34, 0x49, 0x75, 0x7C, 0xF6, 0x98, 0x11, 0xEB, 0x2D, + 0xDE, 0xED, 0x41, 0x2E, 0x14, 0x05, 0x02, 0x7F, 0xE0, 0xFE, 0x20, 0xEB, + 0x35, 0xE7, 0x11, 0xAC, 0x22, 0xCE, 0x57, 0x3D, 0xDE, 0xC9, 0x30, 0x6D, + 0x10, 0x03, 0x85, 0xCD, 0xF1, 0xFF, 0x8C, 0x16, 0xB5, 0xC1, 0xB2, 0x3E, + 0x88, 0x6C, 0x60, 0x7F, 0x90, 0x4F, 0x95, 0xF7, 0xF6, 0x2D, 0xAD, 0x01, + 0x39, 0x07, 0x04, 0xFA, 0x75, 0x80, 0x7D, 0xBF, 0x49, 0x50, 0xED, 0xEF, + 0xC9, 0xC4, 0x7C, 0x1C, 0xEB, 0x80, 0x7E, 0xDB, 0xB6, 0xD0, 0xDD, 0x13, + 0xFE, 0xC9, 0xD3, 0x9C, 0xD7, 0xB2, 0x97, 0xA9 +}; + +static const unsigned char TA618_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA619_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, + 0x41, 0x66, 0x66, 0x69, 0x72, 0x6D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C +}; + +static const unsigned char TA619_RSA_N[] = { + 0xF6, 0x1B, 0x4F, 0x67, 0x07, 0x2B, 0xA1, 0x15, 0xF5, 0x06, 0x22, 0xCB, + 0x1F, 0x01, 0xB2, 0xE3, 0x73, 0x45, 0x06, 0x44, 0x49, 0x2C, 0xBB, 0x49, + 0x25, 0x14, 0xD6, 0xCE, 0xC3, 0xB7, 0xAB, 0x2C, 0x4F, 0xC6, 0x41, 0x32, + 0x94, 0x57, 0xFA, 0x12, 0xA7, 0x5B, 0x0E, 0xE2, 0x8F, 0x1F, 0x1E, 0x86, + 0x19, 0xA7, 0xAA, 0xB5, 0x2D, 0xB9, 0x5F, 0x0D, 0x8A, 0xC2, 0xAF, 0x85, + 0x35, 0x79, 0x32, 0x2D, 0xBB, 0x1C, 0x62, 0x37, 0xF2, 0xB1, 0x5B, 0x4A, + 0x3D, 0xCA, 0xCD, 0x71, 0x5F, 0xE9, 0x42, 0xBE, 0x94, 0xE8, 0xC8, 0xDE, + 0xF9, 0x22, 0x48, 0x64, 0xC6, 0xE5, 0xAB, 0xC6, 0x2B, 0x6D, 0xAD, 0x05, + 0xF0, 0xFA, 0xD5, 0x0B, 0xCF, 0x9A, 0xE5, 0xF0, 0x50, 0xA4, 0x8B, 0x3B, + 0x47, 0xA5, 0x23, 0x5B, 0x7A, 0x7A, 0xF8, 0x33, 0x3F, 0xB8, 0xEF, 0x99, + 0x97, 0xE3, 0x20, 0xC1, 0xD6, 0x28, 0x89, 0xCF, 0x94, 0xFB, 0xB9, 0x45, + 0xED, 0xE3, 0x40, 0x17, 0x11, 0xD4, 0x74, 0xF0, 0x0B, 0x31, 0xE2, 0x2B, + 0x26, 0x6A, 0x9B, 0x4C, 0x57, 0xAE, 0xAC, 0x20, 0x3E, 0xBA, 0x45, 0x7A, + 0x05, 0xF3, 0xBD, 0x9B, 0x69, 0x15, 0xAE, 0x7D, 0x4E, 0x20, 0x63, 0xC4, + 0x35, 0x76, 0x3A, 0x07, 0x02, 0xC9, 0x37, 0xFD, 0xC7, 0x47, 0xEE, 0xE8, + 0xF1, 0x76, 0x1D, 0x73, 0x15, 0xF2, 0x97, 0xA4, 0xB5, 0xC8, 0x7A, 0x79, + 0xD9, 0x42, 0xAA, 0x2B, 0x7F, 0x5C, 0xFE, 0xCE, 0x26, 0x4F, 0xA3, 0x66, + 0x81, 0x35, 0xAF, 0x44, 0xBA, 0x54, 0x1E, 0x1C, 0x30, 0x32, 0x65, 0x9D, + 0xE6, 0x3C, 0x93, 0x5E, 0x50, 0x4E, 0x7A, 0xE3, 0x3A, 0xD4, 0x6E, 0xCC, + 0x1A, 0xFB, 0xF9, 0xD2, 0x37, 0xAE, 0x24, 0x2A, 0xAB, 0x57, 0x03, 0x22, + 0x28, 0x0D, 0x49, 0x75, 0x7F, 0xB7, 0x28, 0xDA, 0x75, 0xBF, 0x8E, 0xE3, + 0xDC, 0x0E, 0x79, 0x31 +}; + +static const unsigned char TA619_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA620_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x42, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA620_RSA_N[] = { + 0xD8, 0x17, 0xB7, 0x1C, 0x4A, 0x24, 0x2A, 0xD6, 0x97, 0xB1, 0xCA, 0xE2, + 0x1E, 0xFB, 0x7D, 0x38, 0xEF, 0x98, 0xF5, 0xB2, 0x39, 0x98, 0x4E, 0x27, + 0xB8, 0x11, 0x5D, 0x7B, 0xD2, 0x25, 0x94, 0x88, 0x82, 0x15, 0x26, 0x6A, + 0x1B, 0x31, 0xBB, 0xA8, 0x5B, 0x21, 0x21, 0x2B, 0xD8, 0x0F, 0x4E, 0x9F, + 0x5A, 0xF1, 0xB1, 0x5A, 0xE4, 0x79, 0xD6, 0x32, 0x23, 0x2B, 0xE1, 0x53, + 0xCC, 0x99, 0x45, 0x5C, 0x7B, 0x4F, 0xAD, 0xBC, 0xBF, 0x87, 0x4A, 0x0B, + 0x4B, 0x97, 0x5A, 0xA8, 0xF6, 0x48, 0xEC, 0x7D, 0x7B, 0x0D, 0xCD, 0x21, + 0x06, 0xDF, 0x9E, 0x15, 0xFD, 0x41, 0x8A, 0x48, 0xB7, 0x20, 0xF4, 0xA1, + 0x7A, 0x1B, 0x57, 0xD4, 0x5D, 0x50, 0xFF, 0xBA, 0x67, 0xD8, 0x23, 0x99, + 0x1F, 0xC8, 0x3F, 0xE3, 0xDE, 0xFF, 0x6F, 0x5B, 0x77, 0xB1, 0x6B, 0x6E, + 0xB8, 0xC9, 0x64, 0xF7, 0xE1, 0xCA, 0x41, 0x46, 0x0E, 0x29, 0x71, 0xD0, + 0xB9, 0x23, 0xFC, 0xC9, 0x81, 0x5F, 0x4E, 0xF7, 0x6F, 0xDF, 0xBF, 0x84, + 0xAD, 0x73, 0x64, 0xBB, 0xB7, 0x42, 0x8E, 0x69, 0xF6, 0xD4, 0x76, 0x1D, + 0x7E, 0x9D, 0xA7, 0xB8, 0x57, 0x8A, 0x51, 0x67, 0x72, 0xD7, 0xD4, 0xA8, + 0xB8, 0x95, 0x54, 0x40, 0x73, 0x03, 0xF6, 0xEA, 0xF4, 0xEB, 0xFE, 0x28, + 0x42, 0x77, 0x3F, 0x9D, 0x23, 0x1B, 0xB2, 0xB6, 0x3D, 0x80, 0x14, 0x07, + 0x4C, 0x2E, 0x4F, 0xF7, 0xD5, 0x0A, 0x16, 0x0D, 0xBD, 0x66, 0x43, 0x37, + 0x7E, 0x23, 0x43, 0x79, 0xC3, 0x40, 0x86, 0xF5, 0x4C, 0x29, 0xDA, 0x8E, + 0x9A, 0xAD, 0x0D, 0xA5, 0x04, 0x87, 0x88, 0x1E, 0x85, 0xE3, 0xE9, 0x53, + 0xD5, 0x9B, 0xC8, 0x8B, 0x03, 0x63, 0x78, 0xEB, 0xE0, 0x19, 0x4A, 0x6E, + 0xBB, 0x2F, 0x6B, 0x33, 0x64, 0x58, 0x93, 0xAD, 0x69, 0xBF, 0x8F, 0x1B, + 0xEF, 0x82, 0x48, 0xC7 +}; + +static const unsigned char TA620_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA621_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, 0x36 +}; + +static const unsigned char TA621_EC_Q[] = { + 0x04, 0x9C, 0x0E, 0xB1, 0xCF, 0xB7, 0xE8, 0x9E, 0x52, 0x77, 0x75, 0x34, + 0xFA, 0xA5, 0x46, 0xA7, 0xAD, 0x32, 0x19, 0x32, 0xB4, 0x07, 0xA9, 0x27, + 0xCA, 0x94, 0xBB, 0x0C, 0xD2, 0x0A, 0x10, 0xC7, 0xDA, 0x89, 0xB0, 0x97, + 0x0C, 0x70, 0x13, 0x09, 0x01, 0x8E, 0xD8, 0xEA, 0x47, 0xEA, 0xBE, 0xB2, + 0x80, 0x2B, 0xCD, 0xFC, 0x28, 0x0D, 0xDB, 0xAC, 0xBC, 0xA4, 0x86, 0x37, + 0xED, 0x70, 0x08, 0x00, 0x75, 0xEA, 0x93, 0x0B, 0x7B, 0x2E, 0x52, 0x9C, + 0x23, 0x68, 0x23, 0x06, 0x43, 0xEC, 0x92, 0x2F, 0x53, 0x84, 0xDB, 0xFB, + 0x47, 0x14, 0x07, 0xE8, 0x5F, 0x94, 0x67, 0x5D, 0xC9, 0x7A, 0x81, 0x3C, + 0x20 +}; + +static const unsigned char TA622_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x43, 0x6F, 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x31, + 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x43, 0x6F, + 0x6D, 0x6D, 0x53, 0x63, 0x6F, 0x70, 0x65, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x30, 0x32 +}; + +static const unsigned char TA622_RSA_N[] = { + 0xE1, 0xFA, 0x0E, 0xFB, 0x68, 0x00, 0x12, 0xC8, 0x4D, 0xD5, 0xAC, 0x22, + 0xC4, 0x35, 0x01, 0x3B, 0xC5, 0x54, 0xE5, 0x59, 0x76, 0x63, 0xA5, 0x7F, + 0xEB, 0xC1, 0xC4, 0x6A, 0x98, 0xBD, 0x32, 0x8D, 0x17, 0x80, 0xEB, 0x5D, + 0xBA, 0xD1, 0x62, 0x3D, 0x25, 0x23, 0x19, 0x35, 0x14, 0xE9, 0x7F, 0x89, + 0xA7, 0x1B, 0x62, 0x3C, 0xD6, 0x50, 0xE7, 0x34, 0x95, 0x03, 0x32, 0xB1, + 0xB4, 0x93, 0x22, 0x3D, 0xA7, 0xE2, 0xB1, 0xED, 0xE6, 0x7B, 0x4E, 0x2E, + 0x87, 0x9B, 0x0D, 0x33, 0x75, 0x0A, 0xDE, 0xAA, 0x35, 0xE7, 0x7E, 0xE5, + 0x36, 0x98, 0xA2, 0xAE, 0x25, 0x9E, 0x95, 0xB3, 0x32, 0x96, 0xA4, 0x2B, + 0x58, 0x1E, 0xEF, 0x3F, 0xFE, 0x62, 0x34, 0x48, 0x51, 0xD1, 0xB4, 0x8D, + 0x42, 0xAD, 0x60, 0xDA, 0x49, 0x6A, 0x95, 0x70, 0xDD, 0xD2, 0x00, 0xE2, + 0xCC, 0x57, 0x63, 0x02, 0x7B, 0x96, 0xDD, 0x49, 0x97, 0x5B, 0x92, 0x4E, + 0x95, 0xD3, 0xF9, 0xCB, 0x29, 0x1F, 0x18, 0x4A, 0xF8, 0x01, 0x2A, 0xD2, + 0x63, 0x09, 0x6E, 0x24, 0xE9, 0x89, 0xD2, 0xE5, 0xC7, 0x22, 0x4C, 0xDC, + 0x73, 0x86, 0x47, 0x00, 0xAA, 0x0D, 0x88, 0x8E, 0xAE, 0x85, 0x7D, 0x4A, + 0xE9, 0xBB, 0x33, 0x4F, 0x0E, 0x52, 0x70, 0x9D, 0x95, 0xE3, 0x7C, 0x6D, + 0x96, 0x5B, 0x2D, 0x3D, 0x5F, 0xA1, 0x83, 0x46, 0x5D, 0xB6, 0xE3, 0x25, + 0xB8, 0x7C, 0xA7, 0x19, 0x80, 0x1C, 0xEA, 0x65, 0x43, 0xDC, 0x91, 0x79, + 0x36, 0x2C, 0x74, 0x7C, 0xF2, 0x67, 0x06, 0xC9, 0x89, 0xC9, 0xDB, 0xBF, + 0xDA, 0x68, 0xBF, 0x23, 0xED, 0xDC, 0x6B, 0xAD, 0x28, 0x83, 0x79, 0x2F, + 0xEC, 0x38, 0xA5, 0x0D, 0x37, 0x01, 0x67, 0x27, 0x9A, 0xE9, 0x33, 0xD9, + 0x33, 0x5F, 0x37, 0xA1, 0xC5, 0xF0, 0xAB, 0x3D, 0xFA, 0x78, 0xB0, 0xE7, + 0x2C, 0x9F, 0xF6, 0x3E, 0x9F, 0x60, 0xE0, 0xEF, 0x48, 0xE9, 0x90, 0x45, + 0x1E, 0x05, 0x51, 0x78, 0x1A, 0x2C, 0x12, 0x2C, 0x5C, 0x28, 0xAC, 0x0D, + 0xA2, 0x23, 0x9E, 0x34, 0x8F, 0x05, 0xE6, 0xA2, 0x33, 0xCE, 0x11, 0x77, + 0x13, 0xD4, 0x0E, 0xA4, 0x1E, 0x42, 0x1F, 0x86, 0xCD, 0x70, 0xFE, 0xD9, + 0x2E, 0x15, 0x3D, 0x1D, 0xBB, 0xB8, 0xF2, 0x53, 0x57, 0xDB, 0xCC, 0xC6, + 0x74, 0x29, 0x9C, 0x18, 0xB3, 0x36, 0x75, 0x38, 0x2E, 0x0F, 0x54, 0xA1, + 0xF8, 0x92, 0x1F, 0x89, 0x96, 0x4F, 0xBB, 0xD4, 0xEE, 0x9D, 0xE9, 0x3B, + 0x36, 0x42, 0xB5, 0x0A, 0x3B, 0x2A, 0xD4, 0x64, 0x79, 0x36, 0x10, 0xE1, + 0xF9, 0x91, 0x03, 0x2B, 0x7B, 0x20, 0x54, 0xCD, 0x0D, 0x19, 0x1A, 0xC8, + 0x41, 0x32, 0x34, 0xD1, 0xB0, 0x99, 0xE1, 0x90, 0x1E, 0x01, 0x40, 0x36, + 0xB5, 0xB7, 0xFA, 0xA9, 0xE5, 0x77, 0x75, 0xA4, 0x22, 0x81, 0x5D, 0xB0, + 0x8B, 0xE4, 0x27, 0x12, 0x0F, 0x54, 0x88, 0xC6, 0xDB, 0x85, 0x74, 0xE6, + 0xB7, 0xC0, 0xD7, 0xA6, 0x29, 0xFA, 0xDB, 0xDE, 0xF3, 0x93, 0x97, 0x27, + 0x04, 0x55, 0x2F, 0x0A, 0x6F, 0x37, 0xC5, 0x3D, 0x13, 0xAF, 0x0A, 0x00, + 0xA9, 0x2C, 0x8B, 0x1C, 0x81, 0x28, 0xD7, 0xEF, 0x86, 0x31, 0xA9, 0xAE, + 0xF2, 0x6E, 0xB8, 0xCA, 0x6A, 0x2C, 0x54, 0x47, 0xD8, 0x2A, 0x88, 0x2E, + 0xAF, 0xC1, 0x07, 0x10, 0x78, 0xAC, 0x11, 0xA2, 0x2F, 0x42, 0xF0, 0x37, + 0xC5, 0xF2, 0xB8, 0x56, 0xDD, 0x0E, 0x62, 0x2D, 0xCE, 0x2D, 0x56, 0x7E, + 0x55, 0xF2, 0xA7, 0x44, 0xF6, 0x2B, 0x32, 0xF4, 0x23, 0xA8, 0x47, 0xE8, + 0xD4, 0x2A, 0x01, 0x78, 0xCF, 0x6A, 0xC3, 0x37, 0xA8, 0x9E, 0x65, 0xD2, + 0x2C, 0xE5, 0xFA, 0xBA, 0x33, 0xC1, 0x06, 0x44, 0xF6, 0xE6, 0xCF, 0xA5, + 0x0D, 0xA7, 0x66, 0x08, 0x34, 0x8A, 0x2C, 0xF3 +}; + +static const unsigned char TA622_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA623_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x65, 0x2D, 0x53, 0x7A, 0x69, + 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x32, 0x30, 0x30, 0x39, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x65, 0x2D, 0x73, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x2E, 0x68, + 0x75 +}; + +static const unsigned char TA623_RSA_N[] = { + 0xE9, 0xF8, 0x8F, 0xF3, 0x63, 0xAD, 0xDA, 0x86, 0xD8, 0xA7, 0xE0, 0x42, + 0xFB, 0xCF, 0x91, 0xDE, 0xA6, 0x26, 0xF8, 0x99, 0xA5, 0x63, 0x70, 0xAD, + 0x9B, 0xAE, 0xCA, 0x33, 0x40, 0x7D, 0x6D, 0x96, 0x6E, 0xA1, 0x0E, 0x44, + 0xEE, 0xE1, 0x13, 0x9D, 0x94, 0x42, 0x52, 0x9A, 0xBD, 0x75, 0x85, 0x74, + 0x2C, 0xA8, 0x0E, 0x1D, 0x93, 0xB6, 0x18, 0xB7, 0x8C, 0x2C, 0xA8, 0xCF, + 0xFB, 0x5C, 0x71, 0xB9, 0xDA, 0xEC, 0xFE, 0xE8, 0x7E, 0x8F, 0xE4, 0x2F, + 0x1D, 0xB2, 0xA8, 0x75, 0x87, 0xD8, 0xB7, 0xA1, 0xE5, 0x3B, 0xCF, 0x99, + 0x4A, 0x46, 0xD0, 0x83, 0x19, 0x7D, 0xC0, 0xA1, 0x12, 0x1C, 0x95, 0x6D, + 0x4A, 0xF4, 0xD8, 0xC7, 0xA5, 0x4D, 0x33, 0x2E, 0x85, 0x39, 0x40, 0x75, + 0x7E, 0x14, 0x7C, 0x80, 0x12, 0x98, 0x50, 0xC7, 0x41, 0x67, 0xB8, 0xA0, + 0x80, 0x61, 0x54, 0xA6, 0x6C, 0x4E, 0x1F, 0xE0, 0x9D, 0x0E, 0x07, 0xE9, + 0xC9, 0xBA, 0x33, 0xE7, 0xFE, 0xC0, 0x55, 0x28, 0x2C, 0x02, 0x80, 0xA7, + 0x19, 0xF5, 0x9E, 0xDC, 0x55, 0x53, 0x03, 0x97, 0x7B, 0x07, 0x48, 0xFF, + 0x99, 0xFB, 0x37, 0x8A, 0x24, 0xC4, 0x59, 0xCC, 0x50, 0x10, 0x63, 0x8E, + 0xAA, 0xA9, 0x1A, 0xB0, 0x84, 0x1A, 0x86, 0xF9, 0x5F, 0xBB, 0xB1, 0x50, + 0x6E, 0xA4, 0xD1, 0x0A, 0xCC, 0xD5, 0x71, 0x7E, 0x1F, 0xA7, 0x1B, 0x7C, + 0xF5, 0x53, 0x6E, 0x22, 0x5F, 0xCB, 0x2B, 0xE6, 0xD4, 0x7C, 0x5D, 0xAE, + 0xD6, 0xC2, 0xC6, 0x4C, 0xE5, 0x05, 0x01, 0xD9, 0xED, 0x57, 0xFC, 0xC1, + 0x23, 0x79, 0xFC, 0xFA, 0xC8, 0x24, 0x83, 0x95, 0xF3, 0xB5, 0x6A, 0x51, + 0x01, 0xD0, 0x77, 0xD6, 0xE9, 0x12, 0xA1, 0xF9, 0x1A, 0x83, 0xFB, 0x82, + 0x1B, 0xB9, 0xB0, 0x97, 0xF4, 0x76, 0x06, 0x33, 0x43, 0x49, 0xA0, 0xFF, + 0x0B, 0xB5, 0xFA, 0xB5 +}; + +static const unsigned char TA623_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA624_DN[] = { + 0x30, 0x71, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, 0x63, + 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0E, 0x56, 0x41, 0x54, + 0x48, 0x55, 0x2D, 0x32, 0x33, 0x35, 0x38, 0x34, 0x34, 0x39, 0x37, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x15, 0x65, 0x2D, + 0x53, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA624_EC_Q[] = { + 0x04, 0x96, 0xDC, 0x3D, 0x8A, 0xD8, 0xB0, 0x7B, 0x6F, 0xC6, 0x27, 0xBE, + 0x44, 0x90, 0xB1, 0xB3, 0x56, 0x15, 0x7B, 0x8E, 0x43, 0x24, 0x7D, 0x1A, + 0x84, 0x59, 0xEE, 0x63, 0x68, 0xB2, 0xC6, 0x5E, 0x87, 0xD0, 0x15, 0x48, + 0x1E, 0xA8, 0x90, 0xAD, 0xBD, 0x53, 0xA2, 0xDA, 0xDE, 0x3A, 0x90, 0xA6, + 0x60, 0x5F, 0x68, 0x32, 0xB5, 0x86, 0x41, 0xDF, 0x87, 0x5B, 0x2C, 0x7B, + 0xC5, 0xFE, 0x7C, 0x7A, 0xDA +}; + +static const unsigned char TA625_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4E, 0x4F, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x14, 0x42, 0x75, 0x79, 0x70, 0x61, 0x73, 0x73, 0x20, 0x41, 0x53, + 0x2D, 0x39, 0x38, 0x33, 0x31, 0x36, 0x33, 0x33, 0x32, 0x37, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x17, 0x42, 0x75, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA625_RSA_N[] = { + 0xA5, 0xDA, 0x0A, 0x95, 0x16, 0x50, 0xE3, 0x95, 0xF2, 0x5E, 0x9D, 0x76, + 0x31, 0x06, 0x32, 0x7A, 0x9B, 0xF1, 0x10, 0x76, 0xB8, 0x00, 0x9A, 0xB5, + 0x52, 0x36, 0xCD, 0x24, 0x47, 0xB0, 0x9F, 0x18, 0x64, 0xBC, 0x9A, 0xF6, + 0xFA, 0xD5, 0x79, 0xD8, 0x90, 0x62, 0x4C, 0x22, 0x2F, 0xDE, 0x38, 0x3D, + 0xD6, 0xE0, 0xA8, 0xE9, 0x1C, 0x2C, 0xDB, 0x78, 0x11, 0xE9, 0x8E, 0x68, + 0x51, 0x15, 0x72, 0xC7, 0xF3, 0x33, 0x87, 0xE4, 0xA0, 0x5D, 0x0B, 0x5C, + 0xE0, 0x57, 0x07, 0x2A, 0x30, 0xF5, 0xCD, 0xC4, 0x37, 0x77, 0x28, 0x4D, + 0x18, 0x91, 0xE6, 0xBF, 0xD5, 0x52, 0xFD, 0x71, 0x2D, 0x70, 0x3E, 0xE7, + 0xC6, 0xC4, 0x8A, 0xE3, 0xF0, 0x28, 0x0B, 0xF4, 0x76, 0x98, 0xA1, 0x8B, + 0x87, 0x55, 0xB2, 0x3A, 0x13, 0xFC, 0xB7, 0x3E, 0x27, 0x37, 0x8E, 0x22, + 0xE3, 0xA8, 0x4F, 0x2A, 0xEF, 0x60, 0xBB, 0x3D, 0xB7, 0x39, 0xC3, 0x0E, + 0x01, 0x47, 0x99, 0x5D, 0x12, 0x4F, 0xDB, 0x43, 0xFA, 0x57, 0xA1, 0xED, + 0xF9, 0x9D, 0xBE, 0x11, 0x47, 0x26, 0x5B, 0x13, 0x98, 0xAB, 0x5D, 0x16, + 0x8A, 0xB0, 0x37, 0x1C, 0x57, 0x9D, 0x45, 0xFF, 0x88, 0x96, 0x36, 0xBF, + 0xBB, 0xCA, 0x07, 0x7B, 0x6F, 0x87, 0x63, 0xD7, 0xD0, 0x32, 0x6A, 0xD6, + 0x5D, 0x6C, 0x0C, 0xF1, 0xB3, 0x6E, 0x39, 0xE2, 0x6B, 0x31, 0x2E, 0x39, + 0x00, 0x27, 0x14, 0xDE, 0x38, 0xC0, 0xEC, 0x19, 0x66, 0x86, 0x12, 0xE8, + 0x9D, 0x72, 0x16, 0x13, 0x64, 0x52, 0xC7, 0xA9, 0x37, 0x1C, 0xFD, 0x82, + 0x30, 0xED, 0x84, 0x18, 0x1D, 0xF4, 0xAE, 0x5C, 0xFF, 0x70, 0x13, 0x00, + 0xEB, 0xB1, 0xF5, 0x33, 0x7A, 0x4B, 0xD6, 0x55, 0xF8, 0x05, 0x8D, 0x4B, + 0x69, 0xB0, 0xF5, 0xB3, 0x28, 0x36, 0x5C, 0x14, 0xC4, 0x51, 0x73, 0x4D, + 0x6B, 0x0B, 0xF1, 0x34, 0x07, 0xDB, 0x17, 0x39, 0xD7, 0xDC, 0x28, 0x7B, + 0x6B, 0xF5, 0x9F, 0xF3, 0x2E, 0xC1, 0x4F, 0x17, 0x2A, 0x10, 0xF3, 0xCC, + 0xCA, 0xE8, 0xEB, 0xFD, 0x6B, 0xAB, 0x2E, 0x9A, 0x9F, 0x2D, 0x82, 0x6E, + 0x04, 0xD4, 0x52, 0x01, 0x93, 0x2D, 0x3D, 0x86, 0xFC, 0x7E, 0xFC, 0xDF, + 0xEF, 0x42, 0x1D, 0xA6, 0x6B, 0xEF, 0xB9, 0x20, 0xC6, 0xF7, 0xBD, 0xA0, + 0xA7, 0x95, 0xFD, 0xA7, 0xE6, 0x89, 0x24, 0xD8, 0xCC, 0x8C, 0x34, 0x6C, + 0xE2, 0x23, 0x2F, 0xD9, 0x12, 0x1A, 0x21, 0xB9, 0x55, 0x91, 0x6F, 0x0B, + 0x91, 0x79, 0x19, 0x0C, 0xAD, 0x40, 0x88, 0x0B, 0x70, 0xE2, 0x7A, 0xD2, + 0x0E, 0xD8, 0x68, 0x48, 0xBB, 0x82, 0x13, 0x39, 0x10, 0x58, 0xE9, 0xD8, + 0x2A, 0x07, 0xC6, 0x12, 0xDB, 0x58, 0xDB, 0xD2, 0x3B, 0x55, 0x10, 0x47, + 0x05, 0x15, 0x67, 0x62, 0x7E, 0x18, 0x63, 0xA6, 0x46, 0x3F, 0x09, 0x0E, + 0x54, 0x32, 0x5E, 0xBF, 0x0D, 0x62, 0x7A, 0x27, 0xEF, 0x80, 0xE8, 0xDB, + 0xD9, 0x4B, 0x06, 0x5A, 0x37, 0x5A, 0x25, 0xD0, 0x08, 0x12, 0x77, 0xD4, + 0x6F, 0x09, 0x50, 0x97, 0x3D, 0xC8, 0x1D, 0xC3, 0xDF, 0x8C, 0x45, 0x30, + 0x56, 0xC6, 0xD3, 0x64, 0xAB, 0x66, 0xF3, 0xC0, 0x5E, 0x96, 0x9C, 0xC3, + 0xC4, 0xEF, 0xC3, 0x7C, 0x6B, 0x8B, 0x3A, 0x79, 0x7F, 0xB3, 0x49, 0xCF, + 0x3D, 0xE2, 0x89, 0x9F, 0xA0, 0x30, 0x4B, 0x85, 0xB9, 0x9C, 0x94, 0x24, + 0x79, 0x8F, 0x7D, 0x6B, 0xA9, 0x45, 0x68, 0x0F, 0x2B, 0xD0, 0xF1, 0xDA, + 0x1C, 0xCB, 0x69, 0xB8, 0xCA, 0x49, 0x62, 0x6D, 0xC8, 0xD0, 0x63, 0x62, + 0xDD, 0x60, 0x0F, 0x58, 0xAA, 0x8F, 0xA1, 0xBC, 0x05, 0xA5, 0x66, 0xA2, + 0xCF, 0x1B, 0x76, 0xB2, 0x84, 0x64, 0xB1, 0x4C, 0x39, 0x52, 0xC0, 0x30, + 0xBA, 0xF0, 0x8C, 0x4B, 0x02, 0xB0, 0xB6, 0xB7 +}; + +static const unsigned char TA625_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA626_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, + 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA626_EC_Q[] = { + 0x04, 0x38, 0x08, 0xFE, 0xB1, 0xA0, 0x96, 0xD2, 0x7A, 0xAC, 0xAF, 0x49, + 0x3A, 0xD0, 0xC0, 0xE0, 0xC3, 0x3B, 0x28, 0xAA, 0xF1, 0x72, 0x6D, 0x65, + 0x00, 0x47, 0x88, 0x84, 0xFC, 0x9A, 0x26, 0x6B, 0xAA, 0x4B, 0xBA, 0x6C, + 0x04, 0x0A, 0x88, 0x5E, 0x17, 0xF2, 0x55, 0x87, 0xFC, 0x30, 0xB0, 0x34, + 0xE2, 0x34, 0x58, 0x57, 0x1A, 0x84, 0x53, 0xE9, 0x30, 0xD9, 0xA9, 0xF2, + 0x96, 0x74, 0xC3, 0x51, 0x1F, 0x58, 0x49, 0x31, 0xCC, 0x98, 0x4E, 0x60, + 0x11, 0x87, 0x75, 0xD3, 0x72, 0x94, 0x90, 0x4F, 0x9B, 0x10, 0x25, 0x2A, + 0xA8, 0x78, 0x2D, 0xBE, 0x90, 0x41, 0x58, 0x90, 0x15, 0x72, 0xA7, 0xA1, + 0xB7 +}; + +static const unsigned char TA627_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x10, 0x77, 0x77, 0x77, 0x2E, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x47, 0x33 +}; + +static const unsigned char TA627_EC_Q[] = { + 0x04, 0xDD, 0xA7, 0xD9, 0xBB, 0x8A, 0xB8, 0x0B, 0xFB, 0x0B, 0x7F, 0x21, + 0xD2, 0xF0, 0xBE, 0xBE, 0x73, 0xF3, 0x33, 0x5D, 0x1A, 0xBC, 0x34, 0xEA, + 0xDE, 0xC6, 0x9B, 0xBC, 0xD0, 0x95, 0xF6, 0xF0, 0xCC, 0xD0, 0x0B, 0xBA, + 0x61, 0x5B, 0x51, 0x46, 0x7E, 0x9E, 0x2D, 0x9F, 0xEE, 0x8E, 0x63, 0x0C, + 0x17, 0xEC, 0x07, 0x70, 0xF5, 0xCF, 0x84, 0x2E, 0x40, 0x83, 0x9C, 0xE8, + 0x3F, 0x41, 0x6D, 0x3B, 0xAD, 0xD3, 0xA4, 0x14, 0x59, 0x36, 0x78, 0x9D, + 0x03, 0x43, 0xEE, 0x10, 0x13, 0x6C, 0x72, 0xDE, 0xAE, 0x88, 0xA7, 0xA1, + 0x6B, 0xB5, 0x43, 0xCE, 0x67, 0xDC, 0x23, 0xFF, 0x03, 0x1C, 0xA3, 0xE2, + 0x3E +}; + +static const unsigned char TA628_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1A, 0x30, + 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA628_EC_Q[] = { + 0x04, 0x65, 0x50, 0x4A, 0xAE, 0x8C, 0x79, 0x96, 0x4A, 0xAA, 0x1C, 0x08, + 0xC3, 0xA3, 0xA2, 0xCD, 0xFE, 0x59, 0x56, 0x41, 0x77, 0xFD, 0x26, 0x94, + 0x42, 0xBB, 0x1D, 0xCD, 0x08, 0xDB, 0x73, 0xB2, 0x5B, 0x75, 0xF3, 0xCF, + 0x9C, 0x4E, 0x82, 0xF4, 0xBF, 0xF8, 0x61, 0x26, 0x85, 0x6C, 0xD6, 0x85, + 0x5B, 0x72, 0x70, 0xD2, 0xFD, 0xDB, 0x62, 0xB4, 0xDF, 0x53, 0x8B, 0xBD, + 0xB1, 0x44, 0x58, 0x62, 0x42, 0x09, 0xC7, 0xFA, 0x7F, 0x5B, 0x10, 0xE7, + 0xFE, 0x40, 0xFD, 0xC0, 0xD8, 0xC3, 0x2B, 0x32, 0xE7, 0x70, 0xA6, 0xB7, + 0xA6, 0x20, 0x55, 0x1D, 0x7B, 0x80, 0x5D, 0x4B, 0x8F, 0x67, 0x4C, 0xF1, + 0x10 +}; + +static const unsigned char TA629_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x28, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA629_RSA_N[] = { + 0xB9, 0x5D, 0x51, 0x28, 0x4B, 0x3C, 0x37, 0x92, 0xD1, 0x82, 0xCE, 0xBD, + 0x1D, 0xBD, 0xCD, 0xDD, 0xB8, 0xAB, 0xCF, 0x0A, 0x3E, 0xE1, 0x5D, 0xE5, + 0xDC, 0xAA, 0x09, 0xB9, 0x57, 0x02, 0x3E, 0xE6, 0x63, 0x61, 0xDF, 0xF2, + 0x0F, 0x82, 0x63, 0xAE, 0xA3, 0xF7, 0xAC, 0x73, 0xD1, 0x7C, 0xE7, 0xB3, + 0x0B, 0xAF, 0x08, 0x00, 0x09, 0x59, 0x7F, 0xCD, 0x29, 0x2A, 0x88, 0x93, + 0x87, 0x17, 0x18, 0x80, 0xED, 0x88, 0xB2, 0xB4, 0xB6, 0x10, 0x1F, 0x2D, + 0xD6, 0x5F, 0x55, 0xA2, 0x13, 0x5D, 0xD1, 0xC6, 0xEB, 0x06, 0x56, 0x89, + 0x88, 0xFE, 0xAC, 0x32, 0x9D, 0xFD, 0x5C, 0xC3, 0x05, 0xC7, 0x6E, 0xEE, + 0x86, 0x89, 0xBA, 0x88, 0x03, 0x9D, 0x72, 0x21, 0x86, 0x90, 0xAE, 0x8F, + 0x03, 0xA5, 0xDC, 0x9F, 0x88, 0x28, 0xCB, 0xA3, 0x92, 0x49, 0x0F, 0xEC, + 0xD0, 0x0F, 0xE2, 0x6D, 0x44, 0x4F, 0x80, 0x6A, 0xB2, 0xD4, 0xE7, 0xA0, + 0x0A, 0x53, 0x01, 0xBA, 0x8E, 0x97, 0x91, 0x76, 0x6E, 0xBC, 0xFC, 0xD5, + 0x6B, 0x36, 0xE6, 0x40, 0x88, 0xD6, 0x7B, 0x2F, 0x5F, 0x05, 0xE8, 0x2C, + 0x6D, 0x11, 0xF3, 0xE7, 0xB2, 0xBE, 0x92, 0x44, 0x4C, 0xD2, 0x97, 0xA4, + 0xFE, 0xD2, 0x72, 0x81, 0x43, 0x07, 0x9C, 0xE9, 0x11, 0x3E, 0xF5, 0x8B, + 0x1A, 0x59, 0x7D, 0x1F, 0x68, 0x58, 0xDD, 0x04, 0x00, 0x2C, 0x96, 0xF3, + 0x43, 0xB3, 0x7E, 0x98, 0x19, 0x74, 0xD9, 0x9C, 0x73, 0xD9, 0x18, 0xBE, + 0x41, 0xC7, 0x34, 0x79, 0xD9, 0xF4, 0x62, 0xC2, 0x43, 0xB9, 0xB3, 0x27, + 0xB0, 0x22, 0xCB, 0xF9, 0x3D, 0x52, 0xC7, 0x30, 0x47, 0xB3, 0xC9, 0x3E, + 0xB8, 0x6A, 0xE2, 0xE7, 0xE8, 0x81, 0x70, 0x5E, 0x42, 0x8B, 0x4F, 0x26, + 0xA5, 0xFE, 0x3A, 0xC2, 0x20, 0x6E, 0xBB, 0xF8, 0x16, 0x8E, 0xCD, 0x0C, + 0xA9, 0xB4, 0x1B, 0x6C, 0x76, 0x10, 0xE1, 0x58, 0x79, 0x46, 0x3E, 0x54, + 0xCE, 0x80, 0xA8, 0x57, 0x09, 0x37, 0x29, 0x1B, 0x99, 0x13, 0x8F, 0x0C, + 0xC8, 0xD6, 0x2C, 0x1C, 0xFB, 0x05, 0xE8, 0x08, 0x95, 0x3D, 0x65, 0x46, + 0xDC, 0xEE, 0xCD, 0x69, 0xE2, 0x4D, 0x8F, 0x87, 0x28, 0x4E, 0x34, 0x0B, + 0x3E, 0xCF, 0x14, 0xD9, 0xBB, 0xDD, 0xB6, 0x50, 0x9A, 0xAD, 0x77, 0xD4, + 0x19, 0xD6, 0xDA, 0x1A, 0x88, 0xC8, 0x4E, 0x1B, 0x27, 0x75, 0xD8, 0xB2, + 0x08, 0xF1, 0xAE, 0x83, 0x30, 0xB9, 0x11, 0x0E, 0xCD, 0x87, 0xF0, 0x84, + 0x8D, 0x15, 0x72, 0x7C, 0xA1, 0xEF, 0xCC, 0xF2, 0x88, 0x61, 0xBA, 0xF4, + 0x69, 0xBB, 0x0C, 0x8C, 0x0B, 0x75, 0x57, 0x04, 0xB8, 0x4E, 0x2A, 0x14, + 0x2E, 0x3D, 0x0F, 0x1C, 0x1E, 0x32, 0xA6, 0x62, 0x36, 0xEE, 0x66, 0xE2, + 0x22, 0xB8, 0x05, 0x40, 0x63, 0x10, 0x22, 0xF3, 0x33, 0x1D, 0x74, 0x72, + 0x8A, 0x2C, 0xF5, 0x39, 0x29, 0xA0, 0xD3, 0xE7, 0x1B, 0x80, 0x84, 0x2D, + 0xC5, 0x3D, 0xE3, 0x4D, 0xB1, 0xFD, 0x1A, 0x6F, 0xBA, 0x65, 0x07, 0x3B, + 0x58, 0xEC, 0x42, 0x45, 0x26, 0xFB, 0xD8, 0xDA, 0x25, 0x72, 0xC4, 0xF6, + 0x00, 0xB1, 0x22, 0x79, 0xBD, 0xE3, 0x7C, 0x59, 0x62, 0x4A, 0x9C, 0x05, + 0x6F, 0x3D, 0xCE, 0xE6, 0xD6, 0x47, 0x63, 0x99, 0xC6, 0x24, 0x6F, 0x72, + 0x12, 0xC8, 0xAC, 0x7F, 0x90, 0xB4, 0x0B, 0x91, 0x70, 0xE8, 0xB7, 0xE6, + 0x16, 0x10, 0x71, 0x17, 0xCE, 0xDE, 0x06, 0x4F, 0x48, 0x41, 0x7D, 0x35, + 0x4A, 0xA3, 0x89, 0xF2, 0xC9, 0x4B, 0x7B, 0x41, 0x11, 0x6D, 0x67, 0xB7, + 0x08, 0x98, 0x4C, 0xE5, 0x11, 0x19, 0xAE, 0x42, 0x80, 0xDC, 0xFB, 0x90, + 0x05, 0xD4, 0xF8, 0x50, 0xCA, 0xBE, 0xE4, 0xAD, 0xC7, 0xC2, 0x94, 0xD7, + 0x16, 0x9D, 0xE6, 0x17, 0x8F, 0xAF, 0x36, 0xFB +}; + +static const unsigned char TA629_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA630_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x33 +}; + +static const unsigned char TA630_RSA_N[] = { + 0xED, 0x35, 0xA1, 0x81, 0x80, 0xF3, 0xCB, 0x4A, 0x69, 0x5B, 0xC2, 0xFB, + 0x51, 0x83, 0xAE, 0x26, 0xFD, 0xE1, 0x6E, 0xF3, 0x81, 0x12, 0x7D, 0x71, + 0x40, 0xFF, 0x87, 0x75, 0x42, 0x29, 0x21, 0xED, 0x81, 0x52, 0x2C, 0xDF, + 0x12, 0xC1, 0x19, 0x84, 0x89, 0xC1, 0xBD, 0xC5, 0x28, 0xD5, 0xD5, 0x4B, + 0x6C, 0x44, 0xD6, 0x4C, 0xDB, 0x07, 0x96, 0x4A, 0x55, 0x7A, 0xCA, 0x36, + 0x82, 0x04, 0x36, 0xA8, 0xA5, 0xFC, 0x27, 0xF6, 0x49, 0xF1, 0xD5, 0x72, + 0x9E, 0x91, 0xF9, 0x23, 0xD6, 0x70, 0x7B, 0xBB, 0xF5, 0x9B, 0xC1, 0xEC, + 0x93, 0xCF, 0x19, 0xEA, 0x65, 0x7E, 0x88, 0x70, 0xA0, 0x73, 0xFC, 0xF6, + 0xFF, 0xB5, 0x56, 0x62, 0xE1, 0x73, 0x6A, 0x34, 0x98, 0x3E, 0x82, 0xB8, + 0xAC, 0x95, 0x53, 0xF4, 0x01, 0xA0, 0x27, 0x07, 0x72, 0xA3, 0x00, 0x53, + 0xA0, 0xE4, 0xB2, 0xAB, 0x83, 0x38, 0x57, 0x33, 0x25, 0x94, 0x9F, 0xBE, + 0x48, 0x1D, 0x98, 0xE1, 0xA3, 0xBA, 0x9E, 0x5C, 0xCD, 0x04, 0x71, 0x51, + 0x7D, 0x75, 0x78, 0xAB, 0xF3, 0x59, 0xAA, 0xC4, 0xE0, 0x60, 0xBE, 0x8F, + 0x83, 0x52, 0xB8, 0x75, 0x1A, 0x41, 0x35, 0xED, 0xBC, 0xF3, 0x3A, 0x63, + 0xE9, 0xA9, 0x14, 0x45, 0xD7, 0xE6, 0x52, 0xD1, 0x6E, 0xD2, 0xDE, 0xBC, + 0xE3, 0xF5, 0x0B, 0x3B, 0xE6, 0xE0, 0xC4, 0xBD, 0x43, 0x64, 0x13, 0xA6, + 0xCE, 0xF4, 0x98, 0x37, 0x6C, 0x8A, 0x95, 0xA8, 0x97, 0xC8, 0x47, 0x0F, + 0xF0, 0x5E, 0x10, 0x8B, 0xE7, 0x1D, 0x1C, 0xFE, 0xB1, 0x3B, 0xA0, 0x05, + 0x33, 0x68, 0x05, 0x41, 0x82, 0xC1, 0x03, 0x2B, 0x01, 0xC8, 0xE7, 0x8F, + 0x4D, 0xAB, 0xE8, 0xB5, 0xF6, 0xCD, 0x6B, 0x44, 0xB5, 0xE7, 0xDD, 0x8B, + 0xEC, 0xEA, 0x25, 0xB4, 0x00, 0x22, 0x57, 0x4D, 0xB0, 0xB1, 0xB2, 0x31, + 0xC1, 0x16, 0xCE, 0xFF, 0xFD, 0x14, 0x84, 0xB7, 0x47, 0xFA, 0xB2, 0xF1, + 0x70, 0xDE, 0xDB, 0x8B, 0x6C, 0x36, 0x58, 0xA4, 0x7C, 0xB3, 0x11, 0xD1, + 0xC3, 0x77, 0x7F, 0x5F, 0xB6, 0x25, 0xE0, 0x0D, 0xC5, 0xD2, 0xB3, 0xF9, + 0xB8, 0xB8, 0x77, 0xDB, 0x37, 0x71, 0x71, 0x47, 0xE3, 0x60, 0x18, 0x4F, + 0x24, 0xB6, 0x75, 0x37, 0x78, 0xB9, 0xA3, 0x62, 0xAF, 0xBD, 0xC9, 0x72, + 0x8E, 0x2F, 0xCC, 0xBB, 0xAE, 0xDB, 0xE4, 0x15, 0x52, 0x19, 0x07, 0x33, + 0xFB, 0x6A, 0xB7, 0x2D, 0x4B, 0x90, 0x28, 0x82, 0x73, 0xFE, 0x18, 0x8B, + 0x35, 0x8D, 0xDB, 0xA7, 0x04, 0x6A, 0xBE, 0xEA, 0xC1, 0x4D, 0x36, 0x3B, + 0x16, 0x36, 0x91, 0x32, 0xEF, 0xB6, 0x40, 0x89, 0x91, 0x43, 0xE0, 0xF2, + 0xA2, 0xAB, 0x04, 0x2E, 0xE6, 0xF2, 0x4C, 0x0E, 0x16, 0x34, 0x20, 0xAC, + 0x87, 0xC1, 0x2D, 0x7E, 0xC9, 0x66, 0x47, 0x17, 0x14, 0x11, 0xA4, 0xF3, + 0xF7, 0xA1, 0x24, 0x89, 0xAB, 0xD8, 0x1A, 0xC8, 0xA1, 0x5C, 0xB1, 0xA3, + 0xF7, 0x8C, 0x6D, 0xC8, 0x01, 0xC9, 0x4F, 0xC9, 0xEC, 0xC4, 0xFC, 0xAC, + 0x51, 0x33, 0xD1, 0xC8, 0x83, 0xD1, 0xC9, 0x9F, 0x1D, 0xD4, 0x47, 0x34, + 0x29, 0x3E, 0xCB, 0xB0, 0x0E, 0xFA, 0x83, 0x0B, 0x28, 0x58, 0xE5, 0x29, + 0xDC, 0x3F, 0x7C, 0xA8, 0x9F, 0xC9, 0xB6, 0x0A, 0xBB, 0xA6, 0xE8, 0x46, + 0x16, 0x0F, 0x96, 0xE5, 0x7B, 0xE4, 0x6A, 0x7A, 0x48, 0x6D, 0x76, 0x98, + 0x05, 0xA5, 0xDC, 0x6D, 0x1E, 0x42, 0x1E, 0x42, 0xDA, 0x1A, 0xE0, 0x52, + 0xF7, 0xB5, 0x83, 0xC0, 0x1A, 0x7B, 0x78, 0x35, 0x2C, 0x38, 0xF5, 0x1F, + 0xFD, 0x49, 0xA3, 0x2E, 0xD2, 0x59, 0x63, 0xBF, 0x80, 0xB0, 0x8C, 0x93, + 0x73, 0xCB, 0x35, 0xA6, 0x99, 0x95, 0x22, 0x61, 0x65, 0x03, 0x60, 0xFB, + 0x2F, 0x93, 0x4B, 0xFA, 0x9A, 0x9C, 0x80, 0x3B +}; + +static const unsigned char TA630_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA631_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1A, 0x30, + 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA631_EC_Q[] = { + 0x04, 0x65, 0x50, 0x4A, 0xAE, 0x8C, 0x79, 0x96, 0x4A, 0xAA, 0x1C, 0x08, + 0xC3, 0xA3, 0xA2, 0xCD, 0xFE, 0x59, 0x56, 0x41, 0x77, 0xFD, 0x26, 0x94, + 0x42, 0xBB, 0x1D, 0xCD, 0x08, 0xDB, 0x73, 0xB2, 0x5B, 0x75, 0xF3, 0xCF, + 0x9C, 0x4E, 0x82, 0xF4, 0xBF, 0xF8, 0x61, 0x26, 0x85, 0x6C, 0xD6, 0x85, + 0x5B, 0x72, 0x70, 0xD2, 0xFD, 0xDB, 0x62, 0xB4, 0xDF, 0x53, 0x8B, 0xBD, + 0xB1, 0x44, 0x58, 0x62, 0x42, 0x09, 0xC7, 0xFA, 0x7F, 0x5B, 0x10, 0xE7, + 0xFE, 0x40, 0xFD, 0xC0, 0xD8, 0xC3, 0x2B, 0x32, 0xE7, 0x70, 0xA6, 0xB7, + 0xA6, 0x20, 0x55, 0x1D, 0x7B, 0x80, 0x5D, 0x4B, 0x8F, 0x67, 0x4C, 0xF1, + 0x10 +}; + +static const unsigned char TA632_DN[] = { + 0x30, 0x7B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, 0x61, + 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x53, 0x61, 0x6C, 0x66, 0x6F, + 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x11, 0x43, 0x6F, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x43, 0x41, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x18, 0x41, 0x41, 0x41, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73 +}; + +static const unsigned char TA632_RSA_N[] = { + 0xBE, 0x40, 0x9D, 0xF4, 0x6E, 0xE1, 0xEA, 0x76, 0x87, 0x1C, 0x4D, 0x45, + 0x44, 0x8E, 0xBE, 0x46, 0xC8, 0x83, 0x06, 0x9D, 0xC1, 0x2A, 0xFE, 0x18, + 0x1F, 0x8E, 0xE4, 0x02, 0xFA, 0xF3, 0xAB, 0x5D, 0x50, 0x8A, 0x16, 0x31, + 0x0B, 0x9A, 0x06, 0xD0, 0xC5, 0x70, 0x22, 0xCD, 0x49, 0x2D, 0x54, 0x63, + 0xCC, 0xB6, 0x6E, 0x68, 0x46, 0x0B, 0x53, 0xEA, 0xCB, 0x4C, 0x24, 0xC0, + 0xBC, 0x72, 0x4E, 0xEA, 0xF1, 0x15, 0xAE, 0xF4, 0x54, 0x9A, 0x12, 0x0A, + 0xC3, 0x7A, 0xB2, 0x33, 0x60, 0xE2, 0xDA, 0x89, 0x55, 0xF3, 0x22, 0x58, + 0xF3, 0xDE, 0xDC, 0xCF, 0xEF, 0x83, 0x86, 0xA2, 0x8C, 0x94, 0x4F, 0x9F, + 0x68, 0xF2, 0x98, 0x90, 0x46, 0x84, 0x27, 0xC7, 0x76, 0xBF, 0xE3, 0xCC, + 0x35, 0x2C, 0x8B, 0x5E, 0x07, 0x64, 0x65, 0x82, 0xC0, 0x48, 0xB0, 0xA8, + 0x91, 0xF9, 0x61, 0x9F, 0x76, 0x20, 0x50, 0xA8, 0x91, 0xC7, 0x66, 0xB5, + 0xEB, 0x78, 0x62, 0x03, 0x56, 0xF0, 0x8A, 0x1A, 0x13, 0xEA, 0x31, 0xA3, + 0x1E, 0xA0, 0x99, 0xFD, 0x38, 0xF6, 0xF6, 0x27, 0x32, 0x58, 0x6F, 0x07, + 0xF5, 0x6B, 0xB8, 0xFB, 0x14, 0x2B, 0xAF, 0xB7, 0xAA, 0xCC, 0xD6, 0x63, + 0x5F, 0x73, 0x8C, 0xDA, 0x05, 0x99, 0xA8, 0x38, 0xA8, 0xCB, 0x17, 0x78, + 0x36, 0x51, 0xAC, 0xE9, 0x9E, 0xF4, 0x78, 0x3A, 0x8D, 0xCF, 0x0F, 0xD9, + 0x42, 0xE2, 0x98, 0x0C, 0xAB, 0x2F, 0x9F, 0x0E, 0x01, 0xDE, 0xEF, 0x9F, + 0x99, 0x49, 0xF1, 0x2D, 0xDF, 0xAC, 0x74, 0x4D, 0x1B, 0x98, 0xB5, 0x47, + 0xC5, 0xE5, 0x29, 0xD1, 0xF9, 0x90, 0x18, 0xC7, 0x62, 0x9C, 0xBE, 0x83, + 0xC7, 0x26, 0x7B, 0x3E, 0x8A, 0x25, 0xC7, 0xC0, 0xDD, 0x9D, 0xE6, 0x35, + 0x68, 0x10, 0x20, 0x9D, 0x8F, 0xD8, 0xDE, 0xD2, 0xC3, 0x84, 0x9C, 0x0D, + 0x5E, 0xE8, 0x2F, 0xC9 +}; + +static const unsigned char TA632_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA633_DN[] = { + 0x30, 0x81, 0x85, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x42, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4D, + 0x61, 0x6E, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6C, 0x66, + 0x6F, 0x72, 0x64, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x11, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, 0x20, 0x43, 0x41, 0x20, + 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2B, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4F, 0x4D, 0x4F, 0x44, 0x4F, + 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA633_EC_Q[] = { + 0x04, 0x03, 0x47, 0x7B, 0x2F, 0x75, 0xC9, 0x82, 0x15, 0x85, 0xFB, 0x75, + 0xE4, 0x91, 0x16, 0xD4, 0xAB, 0x62, 0x99, 0xF5, 0x3E, 0x52, 0x0B, 0x06, + 0xCE, 0x41, 0x00, 0x7F, 0x97, 0xE1, 0x0A, 0x24, 0x3C, 0x1D, 0x01, 0x04, + 0xEE, 0x3D, 0xD2, 0x8D, 0x09, 0x97, 0x0C, 0xE0, 0x75, 0xE4, 0xFA, 0xFB, + 0x77, 0x8A, 0x2A, 0xF5, 0x03, 0x60, 0x4B, 0x36, 0x8B, 0x16, 0x23, 0x16, + 0xAD, 0x09, 0x71, 0xF4, 0x4A, 0xF4, 0x28, 0x50, 0xB4, 0xFE, 0x88, 0x1C, + 0x6E, 0x3F, 0x6C, 0x2F, 0x2F, 0x09, 0x59, 0x5B, 0xA5, 0x5B, 0x0B, 0x33, + 0x99, 0xE2, 0xC3, 0x3D, 0x89, 0xF9, 0x6A, 0x2C, 0xEF, 0xB2, 0xD3, 0x06, + 0xE9 +}; + +static const unsigned char TA634_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6F, 0x6D, 0x6D, + 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA634_RSA_N[] = { + 0xA7, 0x50, 0x19, 0xDE, 0x3F, 0x99, 0x3D, 0xD4, 0x33, 0x46, 0xF1, 0x6F, + 0x51, 0x61, 0x82, 0xB2, 0xA9, 0x4F, 0x8F, 0x67, 0x89, 0x5D, 0x84, 0xD9, + 0x53, 0xDD, 0x0C, 0x28, 0xD9, 0xD7, 0xF0, 0xFF, 0xAE, 0x95, 0x43, 0x72, + 0x99, 0xF9, 0xB5, 0x5D, 0x7C, 0x8A, 0xC1, 0x42, 0xE1, 0x31, 0x50, 0x74, + 0xD1, 0x81, 0x0D, 0x7C, 0xCD, 0x9B, 0x21, 0xAB, 0x43, 0xE2, 0xAC, 0xAD, + 0x5E, 0x86, 0x6E, 0xF3, 0x09, 0x8A, 0x1F, 0x5A, 0x32, 0xBD, 0xA2, 0xEB, + 0x94, 0xF9, 0xE8, 0x5C, 0x0A, 0xEC, 0xFF, 0x98, 0xD2, 0xAF, 0x71, 0xB3, + 0xB4, 0x53, 0x9F, 0x4E, 0x87, 0xEF, 0x92, 0xBC, 0xBD, 0xEC, 0x4F, 0x32, + 0x30, 0x88, 0x4B, 0x17, 0x5E, 0x57, 0xC4, 0x53, 0xC2, 0xF6, 0x02, 0x97, + 0x8D, 0xD9, 0x62, 0x2B, 0xBF, 0x24, 0x1F, 0x62, 0x8D, 0xDF, 0xC3, 0xB8, + 0x29, 0x4B, 0x49, 0x78, 0x3C, 0x93, 0x60, 0x88, 0x22, 0xFC, 0x99, 0xDA, + 0x36, 0xC8, 0xC2, 0xA2, 0xD4, 0x2C, 0x54, 0x00, 0x67, 0x35, 0x6E, 0x73, + 0xBF, 0x02, 0x58, 0xF0, 0xA4, 0xDD, 0xE5, 0xB0, 0xA2, 0x26, 0x7A, 0xCA, + 0xE0, 0x36, 0xA5, 0x19, 0x16, 0xF5, 0xFD, 0xB7, 0xEF, 0xAE, 0x3F, 0x40, + 0xF5, 0x6D, 0x5A, 0x04, 0xFD, 0xCE, 0x34, 0xCA, 0x24, 0xDC, 0x74, 0x23, + 0x1B, 0x5D, 0x33, 0x13, 0x12, 0x5D, 0xC4, 0x01, 0x25, 0xF6, 0x30, 0xDD, + 0x02, 0x5D, 0x9F, 0xE0, 0xD5, 0x47, 0xBD, 0xB4, 0xEB, 0x1B, 0xA1, 0xBB, + 0x49, 0x49, 0xD8, 0x9F, 0x5B, 0x02, 0xF3, 0x8A, 0xE4, 0x24, 0x90, 0xE4, + 0x62, 0x4F, 0x4F, 0xC1, 0xAF, 0x8B, 0x0E, 0x74, 0x17, 0xA8, 0xD1, 0x72, + 0x88, 0x6A, 0x7A, 0x01, 0x49, 0xCC, 0xB4, 0x46, 0x79, 0xC6, 0x17, 0xB1, + 0xDA, 0x98, 0x1E, 0x07, 0x59, 0xFA, 0x75, 0x21, 0x85, 0x65, 0xDD, 0x90, + 0x56, 0xCE, 0xFB, 0xAB, 0xA5, 0x60, 0x9D, 0xC4, 0x9D, 0xF9, 0x52, 0xB0, + 0x8B, 0xBD, 0x87, 0xF9, 0x8F, 0x2B, 0x23, 0x0A, 0x23, 0x76, 0x3B, 0xF7, + 0x33, 0xE1, 0xC9, 0x00, 0xF3, 0x69, 0xF9, 0x4B, 0xA2, 0xE0, 0x4E, 0xBC, + 0x7E, 0x93, 0x39, 0x84, 0x07, 0xF7, 0x44, 0x70, 0x7E, 0xFE, 0x07, 0x5A, + 0xE5, 0xB1, 0xAC, 0xD1, 0x18, 0xCC, 0xF2, 0x35, 0xE5, 0x49, 0x49, 0x08, + 0xCA, 0x56, 0xC9, 0x3D, 0xFB, 0x0F, 0x18, 0x7D, 0x8B, 0x3B, 0xC1, 0x13, + 0xC2, 0x4D, 0x8F, 0xC9, 0x4F, 0x0E, 0x37, 0xE9, 0x1F, 0xA1, 0x0E, 0x6A, + 0xDF, 0x62, 0x2E, 0xCB, 0x35, 0x06, 0x51, 0x79, 0x2C, 0xC8, 0x25, 0x38, + 0xF4, 0xFA, 0x4B, 0xA7, 0x89, 0x5C, 0x9C, 0xD2, 0xE3, 0x0D, 0x39, 0x86, + 0x4A, 0x74, 0x7C, 0xD5, 0x59, 0x87, 0xC2, 0x3F, 0x4E, 0x0C, 0x5C, 0x52, + 0xF4, 0x3D, 0xF7, 0x52, 0x82, 0xF1, 0xEA, 0xA3, 0xAC, 0xFD, 0x49, 0x34, + 0x1A, 0x28, 0xF3, 0x41, 0x88, 0x3A, 0x13, 0xEE, 0xE8, 0xDE, 0xFF, 0x99, + 0x1D, 0x5F, 0xBA, 0xCB, 0xE8, 0x1E, 0xF2, 0xB9, 0x50, 0x60, 0xC0, 0x31, + 0xD3, 0x73, 0xE5, 0xEF, 0xBE, 0xA0, 0xED, 0x33, 0x0B, 0x74, 0xBE, 0x20, + 0x20, 0xC4, 0x67, 0x6C, 0xF0, 0x08, 0x03, 0x7A, 0x55, 0x80, 0x7F, 0x46, + 0x4E, 0x96, 0xA7, 0xF4, 0x1E, 0x3E, 0xE1, 0xF6, 0xD8, 0x09, 0xE1, 0x33, + 0x64, 0x2B, 0x63, 0xD7, 0x32, 0x5E, 0x9F, 0xF9, 0xC0, 0x7B, 0x0F, 0x78, + 0x6F, 0x97, 0xBC, 0x93, 0x9A, 0xF9, 0x9C, 0x12, 0x90, 0x78, 0x7A, 0x80, + 0x87, 0x15, 0xD7, 0x72, 0x74, 0x9C, 0x55, 0x74, 0x78, 0xB1, 0xBA, 0xE1, + 0x6E, 0x70, 0x04, 0xBA, 0x4F, 0xA0, 0xBA, 0x68, 0xC3, 0x7B, 0xFF, 0x31, + 0xF0, 0x73, 0x3D, 0x3D, 0x94, 0x2A, 0xB1, 0x0B, 0x41, 0x0E, 0xA0, 0xFE, + 0x4D, 0x88, 0x65, 0x6B, 0x79, 0x33, 0xB4, 0xD7 +}; + +static const unsigned char TA634_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA635_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x20, + 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x43, 0x33 +}; + +static const unsigned char TA635_EC_Q[] = { + 0x04, 0xFD, 0xA5, 0x61, 0xAE, 0x7B, 0x26, 0x10, 0x1D, 0xE9, 0xB7, 0x22, + 0x30, 0xAE, 0x06, 0xF4, 0x81, 0xB3, 0xB1, 0x42, 0x71, 0x95, 0x39, 0xBC, + 0xD3, 0x52, 0xE3, 0xAF, 0xAF, 0xF9, 0xF2, 0x97, 0x35, 0x92, 0x36, 0x46, + 0x0E, 0x87, 0x95, 0x8D, 0xB9, 0x39, 0x5A, 0xE9, 0xBB, 0xDF, 0xD0, 0xFE, + 0xC8, 0x07, 0x41, 0x3C, 0xBB, 0x55, 0x6F, 0x83, 0xA3, 0x6A, 0xFB, 0x62, + 0xB0, 0x81, 0x89, 0x02, 0x70, 0x7D, 0x48, 0xC5, 0x4A, 0xE3, 0xE9, 0x22, + 0x54, 0x22, 0x4D, 0x93, 0xBB, 0x42, 0x0C, 0xAF, 0x77, 0x9C, 0x23, 0xA6, + 0x7D, 0xD7, 0x61, 0x11, 0xCE, 0x65, 0xC7, 0xF8, 0x7F, 0xFE, 0xF5, 0xF2, + 0xA9 +}; + +static const unsigned char TA636_DN[] = { + 0x30, 0x6B, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x17, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45, 0x43, 0x43, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, + 0x33 +}; + +static const unsigned char TA636_EC_Q[] = { + 0x04, 0x23, 0xA5, 0x0C, 0xB8, 0x2D, 0x12, 0xF5, 0x28, 0xF3, 0xB1, 0xB2, + 0xDD, 0xE2, 0x02, 0x12, 0x80, 0x9E, 0x39, 0x5F, 0x49, 0x4D, 0x9F, 0xC9, + 0x25, 0x34, 0x59, 0x74, 0xEC, 0xBB, 0x06, 0x1C, 0xE7, 0xC0, 0x72, 0xAF, + 0xE8, 0xAE, 0x2F, 0xE1, 0x41, 0x54, 0x87, 0x14, 0xA8, 0x4A, 0xB2, 0xE8, + 0x7C, 0x82, 0xE6, 0x5B, 0x6A, 0xB5, 0xDC, 0xB3, 0x75, 0xCE, 0x8B, 0x06, + 0xD0, 0x86, 0x23, 0xBF, 0x46, 0xD5, 0x8E, 0x0F, 0x3F, 0x04, 0xF4, 0xD7, + 0x1C, 0x92, 0x7E, 0xF6, 0xA5, 0x63, 0xC2, 0xF5, 0x5F, 0x8E, 0x2E, 0x4F, + 0xA1, 0x18, 0x19, 0x02, 0x2B, 0x32, 0x0A, 0x82, 0x64, 0x7D, 0x16, 0x93, + 0xD1 +}; + +static const unsigned char TA637_DN[] = { + 0x30, 0x56, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0B, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x1C, + 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x65, 0x6D, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x43, 0x31 +}; + +static const unsigned char TA637_RSA_N[] = { + 0xCF, 0xEB, 0xA9, 0xB9, 0xF1, 0x99, 0x05, 0xCC, 0xD8, 0x28, 0x21, 0x4A, + 0xF3, 0x73, 0x34, 0x51, 0x84, 0x56, 0x10, 0xF5, 0xA0, 0x4F, 0x2C, 0x12, + 0xE3, 0xFA, 0x13, 0x9A, 0x27, 0xD0, 0xCF, 0xF9, 0x79, 0x1A, 0x74, 0x5F, + 0x1D, 0x79, 0x39, 0xFC, 0x5B, 0xF8, 0x70, 0x8E, 0xE0, 0x92, 0x52, 0xF7, + 0xE4, 0x25, 0xF9, 0x54, 0x83, 0xD9, 0x1D, 0xD3, 0xC8, 0x5A, 0x85, 0x3F, + 0x5E, 0xC7, 0xB6, 0x07, 0xEE, 0x3E, 0xC0, 0xCE, 0x9A, 0xAF, 0xAC, 0x56, + 0x42, 0x2A, 0x39, 0x25, 0x70, 0xD6, 0xBF, 0xB5, 0x7B, 0x36, 0xAD, 0xAC, + 0xF6, 0x73, 0xDC, 0xCD, 0xD7, 0x1D, 0x8A, 0x83, 0xA5, 0xFB, 0x2B, 0x90, + 0x15, 0x37, 0x6B, 0x1C, 0x26, 0x47, 0xDC, 0x3B, 0x29, 0x56, 0x93, 0x6A, + 0xB3, 0xC1, 0x6A, 0x3A, 0x9D, 0x3D, 0xF5, 0xC1, 0x97, 0x38, 0x58, 0x05, + 0x8B, 0x1C, 0x11, 0xE3, 0xE4, 0xB4, 0xB8, 0x5D, 0x85, 0x1D, 0x83, 0xFE, + 0x78, 0x5F, 0x0B, 0x45, 0x68, 0x18, 0x48, 0xA5, 0x46, 0x73, 0x34, 0x3B, + 0xFE, 0x0F, 0xC8, 0x76, 0xBB, 0xC7, 0x18, 0xF3, 0x05, 0xD1, 0x86, 0xF3, + 0x85, 0xED, 0xE7, 0xB9, 0xD9, 0x32, 0xAD, 0x55, 0x88, 0xCE, 0xA6, 0xB6, + 0x91, 0xB0, 0x4F, 0xAC, 0x7E, 0x15, 0x23, 0x96, 0xF6, 0x3F, 0xF0, 0x20, + 0x34, 0x16, 0xDE, 0x0A, 0xC6, 0xC4, 0x04, 0x45, 0x79, 0x7F, 0xA7, 0xFD, + 0xBE, 0xD2, 0xA9, 0xA5, 0xAF, 0x9C, 0xC5, 0x23, 0x2A, 0xF7, 0x3C, 0x21, + 0x6C, 0xBD, 0xAF, 0x8F, 0x4E, 0xC5, 0x3A, 0xB2, 0xF3, 0x34, 0x12, 0xFC, + 0xDF, 0x80, 0x1A, 0x49, 0xA4, 0xD4, 0xA9, 0x95, 0xF7, 0x9E, 0x89, 0x5E, + 0xA2, 0x89, 0xAC, 0x94, 0xCB, 0xA8, 0x68, 0x9B, 0xAF, 0x8A, 0x65, 0x27, + 0xCD, 0x89, 0xEE, 0xDD, 0x8C, 0xB5, 0x6B, 0x29, 0x70, 0x43, 0xA0, 0x69, + 0x0B, 0xE4, 0xB9, 0x0F +}; + +static const unsigned char TA637_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA638_DN[] = { + 0x30, 0x67, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x13, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA638_RSA_N[] = { + 0x93, 0x4B, 0xBB, 0xE9, 0x66, 0x8A, 0xEE, 0x9D, 0x5B, 0xD5, 0x34, 0x93, + 0xD0, 0x1B, 0x1E, 0xC3, 0xE7, 0x9E, 0xB8, 0x64, 0x33, 0x7F, 0x63, 0x78, + 0x68, 0xB4, 0xCD, 0x2E, 0x71, 0x75, 0xD7, 0x9B, 0x20, 0xC6, 0x4D, 0x29, + 0xBC, 0xB6, 0x68, 0x60, 0x8A, 0xF7, 0x21, 0x9A, 0x56, 0x35, 0x5A, 0xF3, + 0x76, 0xBD, 0xD8, 0xCD, 0x9A, 0xFF, 0x93, 0x56, 0x4B, 0xA5, 0x59, 0x06, + 0xA1, 0x93, 0x34, 0x29, 0xDD, 0x16, 0x34, 0x75, 0x4E, 0xF2, 0x81, 0xB4, + 0xC7, 0x96, 0x4E, 0xAD, 0x19, 0x15, 0x52, 0x4A, 0xFE, 0x3C, 0x70, 0x75, + 0x70, 0xCD, 0xAF, 0x2B, 0xAB, 0x15, 0x9A, 0x33, 0x3C, 0xAA, 0xB3, 0x8B, + 0xAA, 0xCD, 0x43, 0xFD, 0xF5, 0xEA, 0x70, 0xFF, 0xED, 0xCF, 0x11, 0x3B, + 0x94, 0xCE, 0x4E, 0x32, 0x16, 0xD3, 0x23, 0x40, 0x2A, 0x77, 0xB3, 0xAF, + 0x3C, 0x01, 0x2C, 0x6C, 0xED, 0x99, 0x2C, 0x8B, 0xD9, 0x4E, 0x69, 0x98, + 0xB2, 0xF7, 0x8F, 0x41, 0xB0, 0x32, 0x78, 0x61, 0xD6, 0x0D, 0x5F, 0xC3, + 0xFA, 0xA2, 0x40, 0x92, 0x1D, 0x5C, 0x17, 0xE6, 0x70, 0x3E, 0x35, 0xE7, + 0xA2, 0xB7, 0xC2, 0x62, 0xE2, 0xAB, 0xA4, 0x38, 0x4C, 0xB5, 0x39, 0x35, + 0x6F, 0xEA, 0x03, 0x69, 0xFA, 0x3A, 0x54, 0x68, 0x85, 0x6D, 0xD6, 0xF2, + 0x2F, 0x43, 0x55, 0x1E, 0x91, 0x0D, 0x0E, 0xD8, 0xD5, 0x6A, 0xA4, 0x96, + 0xD1, 0x13, 0x3C, 0x2C, 0x78, 0x50, 0xE8, 0x3A, 0x92, 0xD2, 0x17, 0x56, + 0xE5, 0x35, 0x1A, 0x40, 0x1C, 0x3E, 0x8D, 0x2C, 0xED, 0x39, 0xDF, 0x42, + 0xE0, 0x83, 0x41, 0x74, 0xDF, 0xA3, 0xCD, 0xC2, 0x86, 0x60, 0x48, 0x68, + 0xE3, 0x69, 0x0B, 0x54, 0x00, 0x8B, 0xE4, 0x76, 0x69, 0x21, 0x0D, 0x79, + 0x4E, 0x34, 0x08, 0x5E, 0x14, 0xC2, 0xCC, 0xB1, 0xB7, 0xAD, 0xD7, 0x7C, + 0x70, 0x8A, 0xC7, 0x85 +}; + +static const unsigned char TA638_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA639_DN[] = { + 0x30, 0x81, 0xB4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0B, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, + 0x74, 0x31, 0x40, 0x30, 0x3E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x14, 0x37, + 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, + 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x5F, 0x32, 0x30, 0x34, 0x38, + 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x2E, 0x20, 0x62, 0x79, 0x20, + 0x72, 0x65, 0x66, 0x2E, 0x20, 0x28, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x73, + 0x20, 0x6C, 0x69, 0x61, 0x62, 0x2E, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x13, 0x1C, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, + 0x65, 0x74, 0x20, 0x4C, 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, + 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, + 0x34, 0x38, 0x29 +}; + +static const unsigned char TA639_RSA_N[] = { + 0xAD, 0x4D, 0x4B, 0xA9, 0x12, 0x86, 0xB2, 0xEA, 0xA3, 0x20, 0x07, 0x15, + 0x16, 0x64, 0x2A, 0x2B, 0x4B, 0xD1, 0xBF, 0x0B, 0x4A, 0x4D, 0x8E, 0xED, + 0x80, 0x76, 0xA5, 0x67, 0xB7, 0x78, 0x40, 0xC0, 0x73, 0x42, 0xC8, 0x68, + 0xC0, 0xDB, 0x53, 0x2B, 0xDD, 0x5E, 0xB8, 0x76, 0x98, 0x35, 0x93, 0x8B, + 0x1A, 0x9D, 0x7C, 0x13, 0x3A, 0x0E, 0x1F, 0x5B, 0xB7, 0x1E, 0xCF, 0xE5, + 0x24, 0x14, 0x1E, 0xB1, 0x81, 0xA9, 0x8D, 0x7D, 0xB8, 0xCC, 0x6B, 0x4B, + 0x03, 0xF1, 0x02, 0x0C, 0xDC, 0xAB, 0xA5, 0x40, 0x24, 0x00, 0x7F, 0x74, + 0x94, 0xA1, 0x9D, 0x08, 0x29, 0xB3, 0x88, 0x0B, 0xF5, 0x87, 0x77, 0x9D, + 0x55, 0xCD, 0xE4, 0xC3, 0x7E, 0xD7, 0x6A, 0x64, 0xAB, 0x85, 0x14, 0x86, + 0x95, 0x5B, 0x97, 0x32, 0x50, 0x6F, 0x3D, 0xC8, 0xBA, 0x66, 0x0C, 0xE3, + 0xFC, 0xBD, 0xB8, 0x49, 0xC1, 0x76, 0x89, 0x49, 0x19, 0xFD, 0xC0, 0xA8, + 0xBD, 0x89, 0xA3, 0x67, 0x2F, 0xC6, 0x9F, 0xBC, 0x71, 0x19, 0x60, 0xB8, + 0x2D, 0xE9, 0x2C, 0xC9, 0x90, 0x76, 0x66, 0x7B, 0x94, 0xE2, 0xAF, 0x78, + 0xD6, 0x65, 0x53, 0x5D, 0x3C, 0xD6, 0x9C, 0xB2, 0xCF, 0x29, 0x03, 0xF9, + 0x2F, 0xA4, 0x50, 0xB2, 0xD4, 0x48, 0xCE, 0x05, 0x32, 0x55, 0x8A, 0xFD, + 0xB2, 0x64, 0x4C, 0x0E, 0xE4, 0x98, 0x07, 0x75, 0xDB, 0x7F, 0xDF, 0xB9, + 0x08, 0x55, 0x60, 0x85, 0x30, 0x29, 0xF9, 0x7B, 0x48, 0xA4, 0x69, 0x86, + 0xE3, 0x35, 0x3F, 0x1E, 0x86, 0x5D, 0x7A, 0x7A, 0x15, 0xBD, 0xEF, 0x00, + 0x8E, 0x15, 0x22, 0x54, 0x17, 0x00, 0x90, 0x26, 0x93, 0xBC, 0x0E, 0x49, + 0x68, 0x91, 0xBF, 0xF8, 0x47, 0xD3, 0x9D, 0x95, 0x42, 0xC1, 0x0E, 0x4D, + 0xDF, 0x6F, 0x26, 0xCF, 0xC3, 0x18, 0x21, 0x62, 0x66, 0x43, 0x70, 0xD6, + 0xD5, 0xC0, 0x07, 0xE1 +}; + +static const unsigned char TA639_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA640_DN[] = { + 0x30, 0x81, 0xBF, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x33, 0x30, + 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2A, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x45, + 0x43, 0x31 +}; + +static const unsigned char TA640_EC_Q[] = { + 0x04, 0x84, 0x13, 0xC9, 0xD0, 0xBA, 0x6D, 0x41, 0x7B, 0xE2, 0x6C, 0xD0, + 0xEB, 0x55, 0x5F, 0x66, 0x02, 0x1A, 0x24, 0xF4, 0x5B, 0x89, 0x69, 0x47, + 0xE3, 0xB8, 0xC2, 0x7D, 0xF1, 0xF2, 0x02, 0xC5, 0x9F, 0xA0, 0xF6, 0x5B, + 0xD5, 0x8B, 0x06, 0x19, 0x86, 0x4F, 0x53, 0x10, 0x6D, 0x07, 0x24, 0x27, + 0xA1, 0xA0, 0xF8, 0xD5, 0x47, 0x19, 0x61, 0x4C, 0x7D, 0xCA, 0x93, 0x27, + 0xEA, 0x74, 0x0C, 0xEF, 0x6F, 0x96, 0x09, 0xFE, 0x63, 0xEC, 0x70, 0x5D, + 0x36, 0xAD, 0x67, 0x77, 0xAE, 0xC9, 0x9D, 0x7C, 0x55, 0x44, 0x3A, 0xA2, + 0x63, 0x51, 0x1F, 0xF5, 0xE3, 0x62, 0xD4, 0xA9, 0x47, 0x07, 0x3E, 0xCC, + 0x20 +}; + +static const unsigned char TA641_DN[] = { + 0x30, 0x81, 0xBE, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x1F, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x65, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x6C, + 0x65, 0x67, 0x61, 0x6C, 0x2D, 0x74, 0x65, 0x72, 0x6D, 0x73, 0x31, 0x39, + 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x30, 0x28, 0x63, 0x29, + 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x2D, 0x20, 0x66, 0x6F, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x7A, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x31, 0x32, 0x30, + 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6E, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, + 0x32 +}; + +static const unsigned char TA641_RSA_N[] = { + 0xBA, 0x84, 0xB6, 0x72, 0xDB, 0x9E, 0x0C, 0x6B, 0xE2, 0x99, 0xE9, 0x30, + 0x01, 0xA7, 0x76, 0xEA, 0x32, 0xB8, 0x95, 0x41, 0x1A, 0xC9, 0xDA, 0x61, + 0x4E, 0x58, 0x72, 0xCF, 0xFE, 0xF6, 0x82, 0x79, 0xBF, 0x73, 0x61, 0x06, + 0x0A, 0xA5, 0x27, 0xD8, 0xB3, 0x5F, 0xD3, 0x45, 0x4E, 0x1C, 0x72, 0xD6, + 0x4E, 0x32, 0xF2, 0x72, 0x8A, 0x0F, 0xF7, 0x83, 0x19, 0xD0, 0x6A, 0x80, + 0x80, 0x00, 0x45, 0x1E, 0xB0, 0xC7, 0xE7, 0x9A, 0xBF, 0x12, 0x57, 0x27, + 0x1C, 0xA3, 0x68, 0x2F, 0x0A, 0x87, 0xBD, 0x6A, 0x6B, 0x0E, 0x5E, 0x65, + 0xF3, 0x1C, 0x77, 0xD5, 0xD4, 0x85, 0x8D, 0x70, 0x21, 0xB4, 0xB3, 0x32, + 0xE7, 0x8B, 0xA2, 0xD5, 0x86, 0x39, 0x02, 0xB1, 0xB8, 0xD2, 0x47, 0xCE, + 0xE4, 0xC9, 0x49, 0xC4, 0x3B, 0xA7, 0xDE, 0xFB, 0x54, 0x7D, 0x57, 0xBE, + 0xF0, 0xE8, 0x6E, 0xC2, 0x79, 0xB2, 0x3A, 0x0B, 0x55, 0xE2, 0x50, 0x98, + 0x16, 0x32, 0x13, 0x5C, 0x2F, 0x78, 0x56, 0xC1, 0xC2, 0x94, 0xB3, 0xF2, + 0x5A, 0xE4, 0x27, 0x9A, 0x9F, 0x24, 0xD7, 0xC6, 0xEC, 0xD0, 0x9B, 0x25, + 0x82, 0xE3, 0xCC, 0xC2, 0xC4, 0x45, 0xC5, 0x8C, 0x97, 0x7A, 0x06, 0x6B, + 0x2A, 0x11, 0x9F, 0xA9, 0x0A, 0x6E, 0x48, 0x3B, 0x6F, 0xDB, 0xD4, 0x11, + 0x19, 0x42, 0xF7, 0x8F, 0x07, 0xBF, 0xF5, 0x53, 0x5F, 0x9C, 0x3E, 0xF4, + 0x17, 0x2C, 0xE6, 0x69, 0xAC, 0x4E, 0x32, 0x4C, 0x62, 0x77, 0xEA, 0xB7, + 0xE8, 0xE5, 0xBB, 0x34, 0xBC, 0x19, 0x8B, 0xAE, 0x9C, 0x51, 0xE7, 0xB7, + 0x7E, 0xB5, 0x53, 0xB1, 0x33, 0x22, 0xE5, 0x6D, 0xCF, 0x70, 0x3C, 0x1A, + 0xFA, 0xE2, 0x9B, 0x67, 0xB6, 0x83, 0xF4, 0x8D, 0xA5, 0xAF, 0x62, 0x4C, + 0x4D, 0xE0, 0x58, 0xAC, 0x64, 0x34, 0x12, 0x03, 0xF8, 0xB6, 0x8D, 0x94, + 0x63, 0x24, 0xA4, 0x71 +}; + +static const unsigned char TA641_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA642_DN[] = { + 0x30, 0x81, 0xB0, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0D, 0x45, 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x30, 0x77, 0x77, 0x77, 0x2E, 0x65, 0x6E, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2E, 0x6E, 0x65, 0x74, 0x2F, 0x43, 0x50, 0x53, 0x20, 0x69, + 0x73, 0x20, 0x69, 0x6E, 0x63, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6E, 0x63, 0x65, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x16, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, + 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, + 0x6E, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA642_RSA_N[] = { + 0xB6, 0x95, 0xB6, 0x43, 0x42, 0xFA, 0xC6, 0x6D, 0x2A, 0x6F, 0x48, 0xDF, + 0x94, 0x4C, 0x39, 0x57, 0x05, 0xEE, 0xC3, 0x79, 0x11, 0x41, 0x68, 0x36, + 0xED, 0xEC, 0xFE, 0x9A, 0x01, 0x8F, 0xA1, 0x38, 0x28, 0xFC, 0xF7, 0x10, + 0x46, 0x66, 0x2E, 0x4D, 0x1E, 0x1A, 0xB1, 0x1A, 0x4E, 0xC6, 0xD1, 0xC0, + 0x95, 0x88, 0xB0, 0xC9, 0xFF, 0x31, 0x8B, 0x33, 0x03, 0xDB, 0xB7, 0x83, + 0x7B, 0x3E, 0x20, 0x84, 0x5E, 0xED, 0xB2, 0x56, 0x28, 0xA7, 0xF8, 0xE0, + 0xB9, 0x40, 0x71, 0x37, 0xC5, 0xCB, 0x47, 0x0E, 0x97, 0x2A, 0x68, 0xC0, + 0x22, 0x95, 0x62, 0x15, 0xDB, 0x47, 0xD9, 0xF5, 0xD0, 0x2B, 0xFF, 0x82, + 0x4B, 0xC9, 0xAD, 0x3E, 0xDE, 0x4C, 0xDB, 0x90, 0x80, 0x50, 0x3F, 0x09, + 0x8A, 0x84, 0x00, 0xEC, 0x30, 0x0A, 0x3D, 0x18, 0xCD, 0xFB, 0xFD, 0x2A, + 0x59, 0x9A, 0x23, 0x95, 0x17, 0x2C, 0x45, 0x9E, 0x1F, 0x6E, 0x43, 0x79, + 0x6D, 0x0C, 0x5C, 0x98, 0xFE, 0x48, 0xA7, 0xC5, 0x23, 0x47, 0x5C, 0x5E, + 0xFD, 0x6E, 0xE7, 0x1E, 0xB4, 0xF6, 0x68, 0x45, 0xD1, 0x86, 0x83, 0x5B, + 0xA2, 0x8A, 0x8D, 0xB1, 0xE3, 0x29, 0x80, 0xFE, 0x25, 0x71, 0x88, 0xAD, + 0xBE, 0xBC, 0x8F, 0xAC, 0x52, 0x96, 0x4B, 0xAA, 0x51, 0x8D, 0xE4, 0x13, + 0x31, 0x19, 0xE8, 0x4E, 0x4D, 0x9F, 0xDB, 0xAC, 0xB3, 0x6A, 0xD5, 0xBC, + 0x39, 0x54, 0x71, 0xCA, 0x7A, 0x7A, 0x7F, 0x90, 0xDD, 0x7D, 0x1D, 0x80, + 0xD9, 0x81, 0xBB, 0x59, 0x26, 0xC2, 0x11, 0xFE, 0xE6, 0x93, 0xE2, 0xF7, + 0x80, 0xE4, 0x65, 0xFB, 0x34, 0x37, 0x0E, 0x29, 0x80, 0x70, 0x4D, 0xAF, + 0x38, 0x86, 0x2E, 0x9E, 0x7F, 0x57, 0xAF, 0x9E, 0x17, 0xAE, 0xEB, 0x1C, + 0xCB, 0x28, 0x21, 0x5F, 0xB6, 0x1C, 0xD8, 0xE7, 0xA2, 0x04, 0x22, 0xF9, + 0xD3, 0xDA, 0xD8, 0xCB +}; + +static const unsigned char TA642_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA643_DN[] = { + 0x30, 0x5E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x21, 0x65, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA643_RSA_N[] = { + 0xE1, 0x25, 0x0F, 0xEE, 0x8D, 0xDB, 0x88, 0x33, 0x75, 0x67, 0xCD, 0xAD, + 0x1F, 0x7D, 0x3A, 0x4E, 0x6D, 0x9D, 0xD3, 0x2F, 0x14, 0xF3, 0x63, 0x74, + 0xCB, 0x01, 0x21, 0x6A, 0x37, 0xEA, 0x84, 0x50, 0x07, 0x4B, 0x26, 0x5B, + 0x09, 0x43, 0x6C, 0x21, 0x9E, 0x6A, 0xC8, 0xD5, 0x03, 0xF5, 0x60, 0x69, + 0x8F, 0xCC, 0xF0, 0x22, 0xE4, 0x1F, 0xE7, 0xF7, 0x6A, 0x22, 0x31, 0xB7, + 0x2C, 0x15, 0xF2, 0xE0, 0xFE, 0x00, 0x6A, 0x43, 0xFF, 0x87, 0x65, 0xC6, + 0xB5, 0x1A, 0xC1, 0xA7, 0x4C, 0x6D, 0x22, 0x70, 0x21, 0x8A, 0x31, 0xF2, + 0x97, 0x74, 0x89, 0x09, 0x12, 0x26, 0x1C, 0x9E, 0xCA, 0xD9, 0x12, 0xA2, + 0x95, 0x3C, 0xDA, 0xE9, 0x67, 0xBF, 0x08, 0xA0, 0x64, 0xE3, 0xD6, 0x42, + 0xB7, 0x45, 0xEF, 0x97, 0xF4, 0xF6, 0xF5, 0xD7, 0xB5, 0x4A, 0x15, 0x02, + 0x58, 0x7D, 0x98, 0x58, 0x4B, 0x60, 0xBC, 0xCD, 0xD7, 0x0D, 0x9A, 0x13, + 0x33, 0x53, 0xD1, 0x61, 0xF9, 0x7A, 0xD5, 0xD7, 0x78, 0xB3, 0x9A, 0x33, + 0xF7, 0x00, 0x86, 0xCE, 0x1D, 0x4D, 0x94, 0x38, 0xAF, 0xA8, 0xEC, 0x78, + 0x51, 0x70, 0x8A, 0x5C, 0x10, 0x83, 0x51, 0x21, 0xF7, 0x11, 0x3D, 0x34, + 0x86, 0x5E, 0xE5, 0x48, 0xCD, 0x97, 0x81, 0x82, 0x35, 0x4C, 0x19, 0xEC, + 0x65, 0xF6, 0x6B, 0xC5, 0x05, 0xA1, 0xEE, 0x47, 0x13, 0xD6, 0xB3, 0x21, + 0x27, 0x94, 0x10, 0x0A, 0xD9, 0x24, 0x3B, 0xBA, 0xBE, 0x44, 0x13, 0x46, + 0x30, 0x3F, 0x97, 0x3C, 0xD8, 0xD7, 0xD7, 0x6A, 0xEE, 0x3B, 0x38, 0xE3, + 0x2B, 0xD4, 0x97, 0x0E, 0xB9, 0x1B, 0xE7, 0x07, 0x49, 0x7F, 0x37, 0x2A, + 0xF9, 0x77, 0x78, 0xCF, 0x54, 0xED, 0x5B, 0x46, 0x9D, 0xA3, 0x80, 0x0E, + 0x91, 0x43, 0xC1, 0xD6, 0x5B, 0x5F, 0x14, 0xBA, 0x9F, 0xA6, 0x8D, 0x24, + 0x47, 0x40, 0x59, 0xBF, 0x72, 0x38, 0xB2, 0x36, 0x6C, 0x37, 0xFF, 0x99, + 0xD1, 0x5D, 0x0E, 0x59, 0x0A, 0xAB, 0x69, 0xF7, 0xC0, 0xB2, 0x04, 0x45, + 0x7A, 0x54, 0x00, 0xAE, 0xBE, 0x53, 0xF6, 0xB5, 0xE7, 0xE1, 0xF8, 0x3C, + 0xA3, 0x31, 0xD2, 0xA9, 0xFE, 0x21, 0x52, 0x64, 0xC5, 0xA6, 0x67, 0xF0, + 0x75, 0x07, 0x06, 0x94, 0x14, 0x81, 0x55, 0xC6, 0x27, 0xE4, 0x01, 0x8F, + 0x17, 0xC1, 0x6A, 0x71, 0xD7, 0xBE, 0x4B, 0xFB, 0x94, 0x58, 0x7D, 0x7E, + 0x11, 0x33, 0xB1, 0x42, 0xF7, 0x62, 0x6C, 0x18, 0xD6, 0xCF, 0x09, 0x68, + 0x3E, 0x7F, 0x6C, 0xF6, 0x1E, 0x8F, 0x62, 0xAD, 0xA5, 0x63, 0xDB, 0x09, + 0xA7, 0x1F, 0x22, 0x42, 0x41, 0x1E, 0x6F, 0x99, 0x8A, 0x3E, 0xD7, 0xF9, + 0x3F, 0x40, 0x7A, 0x79, 0xB0, 0xA5, 0x01, 0x92, 0xD2, 0x9D, 0x3D, 0x08, + 0x15, 0xA5, 0x10, 0x01, 0x2D, 0xB3, 0x32, 0x76, 0xA8, 0x95, 0x0D, 0xB3, + 0x7A, 0x9A, 0xFB, 0x07, 0x10, 0x78, 0x11, 0x6F, 0xE1, 0x8F, 0xC7, 0xBA, + 0x0F, 0x25, 0x1A, 0x74, 0x2A, 0xE5, 0x1C, 0x98, 0x41, 0x99, 0xDF, 0x21, + 0x87, 0xE8, 0x95, 0x06, 0x6A, 0x0A, 0xB3, 0x6A, 0x47, 0x76, 0x65, 0xF6, + 0x3A, 0xCF, 0x8F, 0x62, 0x17, 0x19, 0x7B, 0x0A, 0x28, 0xCD, 0x1A, 0xD2, + 0x83, 0x1E, 0x21, 0xC7, 0x2C, 0xBF, 0xBE, 0xFF, 0x61, 0x68, 0xB7, 0x67, + 0x1B, 0xBB, 0x78, 0x4D, 0x8D, 0xCE, 0x67, 0xE5, 0xE4, 0xC1, 0x8E, 0xB7, + 0x23, 0x66, 0xE2, 0x9D, 0x90, 0x75, 0x34, 0x98, 0xA9, 0x36, 0x2B, 0x8A, + 0x9A, 0x94, 0xB9, 0x9D, 0xEC, 0xCC, 0x8A, 0xB1, 0xF8, 0x25, 0x89, 0x5C, + 0x5A, 0xB6, 0x2F, 0x8C, 0x1F, 0x6D, 0x79, 0x24, 0xA7, 0x52, 0x68, 0xC3, + 0x84, 0x35, 0xE2, 0x66, 0x8D, 0x63, 0x0E, 0x25, 0x4D, 0xD5, 0x19, 0xB2, + 0xE6, 0x79, 0x37, 0xA7, 0x22, 0x9D, 0x54, 0x31 +}; + +static const unsigned char TA643_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA644_DN[] = { + 0x30, 0x71, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, 0x63, + 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x17, + 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0E, 0x56, 0x41, 0x54, + 0x48, 0x55, 0x2D, 0x32, 0x33, 0x35, 0x38, 0x34, 0x34, 0x39, 0x37, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x15, 0x65, 0x2D, + 0x53, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA644_EC_Q[] = { + 0x04, 0x96, 0xDC, 0x3D, 0x8A, 0xD8, 0xB0, 0x7B, 0x6F, 0xC6, 0x27, 0xBE, + 0x44, 0x90, 0xB1, 0xB3, 0x56, 0x15, 0x7B, 0x8E, 0x43, 0x24, 0x7D, 0x1A, + 0x84, 0x59, 0xEE, 0x63, 0x68, 0xB2, 0xC6, 0x5E, 0x87, 0xD0, 0x15, 0x48, + 0x1E, 0xA8, 0x90, 0xAD, 0xBD, 0x53, 0xA2, 0xDA, 0xDE, 0x3A, 0x90, 0xA6, + 0x60, 0x5F, 0x68, 0x32, 0xB5, 0x86, 0x41, 0xDF, 0x87, 0x5B, 0x2C, 0x7B, + 0xC5, 0xFE, 0x7C, 0x7A, 0xDA +}; + +static const unsigned char TA645_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x31 +}; + +static const unsigned char TA645_RSA_N[] = { + 0xB6, 0x11, 0x02, 0x8B, 0x1E, 0xE3, 0xA1, 0x77, 0x9B, 0x3B, 0xDC, 0xBF, + 0x94, 0x3E, 0xB7, 0x95, 0xA7, 0x40, 0x3C, 0xA1, 0xFD, 0x82, 0xF9, 0x7D, + 0x32, 0x06, 0x82, 0x71, 0xF6, 0xF6, 0x8C, 0x7F, 0xFB, 0xE8, 0xDB, 0xBC, + 0x6A, 0x2E, 0x97, 0x97, 0xA3, 0x8C, 0x4B, 0xF9, 0x2B, 0xF6, 0xB1, 0xF9, + 0xCE, 0x84, 0x1D, 0xB1, 0xF9, 0xC5, 0x97, 0xDE, 0xEF, 0xB9, 0xF2, 0xA3, + 0xE9, 0xBC, 0x12, 0x89, 0x5E, 0xA7, 0xAA, 0x52, 0xAB, 0xF8, 0x23, 0x27, + 0xCB, 0xA4, 0xB1, 0x9C, 0x63, 0xDB, 0xD7, 0x99, 0x7E, 0xF0, 0x0A, 0x5E, + 0xEB, 0x68, 0xA6, 0xF4, 0xC6, 0x5A, 0x47, 0x0D, 0x4D, 0x10, 0x33, 0xE3, + 0x4E, 0xB1, 0x13, 0xA3, 0xC8, 0x18, 0x6C, 0x4B, 0xEC, 0xFC, 0x09, 0x90, + 0xDF, 0x9D, 0x64, 0x29, 0x25, 0x23, 0x07, 0xA1, 0xB4, 0xD2, 0x3D, 0x2E, + 0x60, 0xE0, 0xCF, 0xD2, 0x09, 0x87, 0xBB, 0xCD, 0x48, 0xF0, 0x4D, 0xC2, + 0xC2, 0x7A, 0x88, 0x8A, 0xBB, 0xBA, 0xCF, 0x59, 0x19, 0xD6, 0xAF, 0x8F, + 0xB0, 0x07, 0xB0, 0x9E, 0x31, 0xF1, 0x82, 0xC1, 0xC0, 0xDF, 0x2E, 0xA6, + 0x6D, 0x6C, 0x19, 0x0E, 0xB5, 0xD8, 0x7E, 0x26, 0x1A, 0x45, 0x03, 0x3D, + 0xB0, 0x79, 0xA4, 0x94, 0x28, 0xAD, 0x0F, 0x7F, 0x26, 0xE5, 0xA8, 0x08, + 0xFE, 0x96, 0xE8, 0x3C, 0x68, 0x94, 0x53, 0xEE, 0x83, 0x3A, 0x88, 0x2B, + 0x15, 0x96, 0x09, 0xB2, 0xE0, 0x7A, 0x8C, 0x2E, 0x75, 0xD6, 0x9C, 0xEB, + 0xA7, 0x56, 0x64, 0x8F, 0x96, 0x4F, 0x68, 0xAE, 0x3D, 0x97, 0xC2, 0x84, + 0x8F, 0xC0, 0xBC, 0x40, 0xC0, 0x0B, 0x5C, 0xBD, 0xF6, 0x87, 0xB3, 0x35, + 0x6C, 0xAC, 0x18, 0x50, 0x7F, 0x84, 0xE0, 0x4C, 0xCD, 0x92, 0xD3, 0x20, + 0xE9, 0x33, 0xBC, 0x52, 0x99, 0xAF, 0x32, 0xB5, 0x29, 0xB3, 0x25, 0x2A, + 0xB4, 0x48, 0xF9, 0x72, 0xE1, 0xCA, 0x64, 0xF7, 0xE6, 0x82, 0x10, 0x8D, + 0xE8, 0x9D, 0xC2, 0x8A, 0x88, 0xFA, 0x38, 0x66, 0x8A, 0xFC, 0x63, 0xF9, + 0x01, 0xF9, 0x78, 0xFD, 0x7B, 0x5C, 0x77, 0xFA, 0x76, 0x87, 0xFA, 0xEC, + 0xDF, 0xB1, 0x0E, 0x79, 0x95, 0x57, 0xB4, 0xBD, 0x26, 0xEF, 0xD6, 0x01, + 0xD1, 0xEB, 0x16, 0x0A, 0xBB, 0x8E, 0x0B, 0xB5, 0xC5, 0xC5, 0x8A, 0x55, + 0xAB, 0xD3, 0xAC, 0xEA, 0x91, 0x4B, 0x29, 0xCC, 0x19, 0xA4, 0x32, 0x25, + 0x4E, 0x2A, 0xF1, 0x65, 0x44, 0xD0, 0x02, 0xCE, 0xAA, 0xCE, 0x49, 0xB4, + 0xEA, 0x9F, 0x7C, 0x83, 0xB0, 0x40, 0x7B, 0xE7, 0x43, 0xAB, 0xA7, 0x6C, + 0xA3, 0x8F, 0x7D, 0x89, 0x81, 0xFA, 0x4C, 0xA5, 0xFF, 0xD5, 0x8E, 0xC3, + 0xCE, 0x4B, 0xE0, 0xB5, 0xD8, 0xB3, 0x8E, 0x45, 0xCF, 0x76, 0xC0, 0xED, + 0x40, 0x2B, 0xFD, 0x53, 0x0F, 0xB0, 0xA7, 0xD5, 0x3B, 0x0D, 0xB1, 0x8A, + 0xA2, 0x03, 0xDE, 0x31, 0xAD, 0xCC, 0x77, 0xEA, 0x6F, 0x7B, 0x3E, 0xD6, + 0xDF, 0x91, 0x22, 0x12, 0xE6, 0xBE, 0xFA, 0xD8, 0x32, 0xFC, 0x10, 0x63, + 0x14, 0x51, 0x72, 0xDE, 0x5D, 0xD6, 0x16, 0x93, 0xBD, 0x29, 0x68, 0x33, + 0xEF, 0x3A, 0x66, 0xEC, 0x07, 0x8A, 0x26, 0xDF, 0x13, 0xD7, 0x57, 0x65, + 0x78, 0x27, 0xDE, 0x5E, 0x49, 0x14, 0x00, 0xA2, 0x00, 0x7F, 0x9A, 0xA8, + 0x21, 0xB6, 0xA9, 0xB1, 0x95, 0xB0, 0xA5, 0xB9, 0x0D, 0x16, 0x11, 0xDA, + 0xC7, 0x6C, 0x48, 0x3C, 0x40, 0xE0, 0x7E, 0x0D, 0x5A, 0xCD, 0x56, 0x3C, + 0xD1, 0x97, 0x05, 0xB9, 0xCB, 0x4B, 0xED, 0x39, 0x4B, 0x9C, 0xC4, 0x3F, + 0xD2, 0x55, 0x13, 0x6E, 0x24, 0xB0, 0xD6, 0x71, 0xFA, 0xF4, 0xC1, 0xBA, + 0xCC, 0xED, 0x1B, 0xF5, 0xFE, 0x81, 0x41, 0xD8, 0x00, 0x98, 0x3D, 0x3A, + 0xC8, 0xAE, 0x7A, 0x98, 0x37, 0x18, 0x05, 0x95 +}; + +static const unsigned char TA645_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA646_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x49, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x11, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x6C, + 0x61, 0x6E, 0x64, 0x20, 0x4F, 0x79, 0x6A, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x32 +}; + +static const unsigned char TA646_RSA_N[] = { + 0xB2, 0xD0, 0x3F, 0x07, 0xBC, 0xE2, 0x7B, 0xD0, 0x6B, 0x99, 0xF8, 0xE2, + 0x77, 0x69, 0xE7, 0xCE, 0x9D, 0xA4, 0x03, 0xBC, 0x82, 0x6D, 0xA1, 0xFE, + 0x81, 0x65, 0x1F, 0x4C, 0x27, 0xAC, 0x8E, 0x00, 0xBA, 0x16, 0x7B, 0xEB, + 0x30, 0x6A, 0x00, 0xC0, 0xB3, 0x74, 0x68, 0x7E, 0xB2, 0xAF, 0xC7, 0xD5, + 0x62, 0xB3, 0x7A, 0x3F, 0x50, 0xCA, 0x8C, 0x36, 0x44, 0x24, 0x63, 0xD2, + 0x36, 0xE9, 0x0C, 0x85, 0xF6, 0x43, 0x76, 0xD5, 0x4C, 0xA1, 0x60, 0x72, + 0x67, 0xE2, 0x28, 0x33, 0xA5, 0xCB, 0x31, 0xB8, 0x3A, 0x22, 0x23, 0x34, + 0xB8, 0x7D, 0xBD, 0x56, 0x22, 0x40, 0x9D, 0xEA, 0xF4, 0x7B, 0x03, 0xAD, + 0x68, 0xFC, 0xB2, 0x81, 0x4F, 0x98, 0xD0, 0x74, 0xEA, 0x8D, 0xE5, 0x7D, + 0xCD, 0x63, 0xC3, 0xA3, 0xF6, 0xDE, 0x92, 0xC2, 0x58, 0x19, 0xE0, 0x96, + 0xBB, 0xC5, 0xC4, 0xA9, 0x3D, 0xA5, 0x74, 0x96, 0xFE, 0xAF, 0xF9, 0x89, + 0xAA, 0xBD, 0x95, 0x17, 0x54, 0xD8, 0x78, 0x44, 0xF1, 0x0C, 0x77, 0x15, + 0x92, 0xE0, 0x98, 0x42, 0xA7, 0xA4, 0xD6, 0xAA, 0x20, 0x92, 0xCD, 0xC1, + 0xA0, 0xB3, 0x96, 0xB2, 0x3A, 0x84, 0x42, 0x8D, 0x7D, 0xD5, 0x95, 0xE4, + 0xD6, 0xDB, 0xE9, 0x62, 0xC4, 0x58, 0xB3, 0x79, 0xC5, 0x8C, 0xD3, 0x35, + 0x33, 0x83, 0x9F, 0x75, 0xA1, 0x52, 0x27, 0x61, 0x38, 0xF1, 0x59, 0x3D, + 0x8E, 0x50, 0xE0, 0xBD, 0x79, 0x3C, 0xE7, 0x6C, 0x96, 0xFE, 0x5E, 0xD9, + 0x02, 0x65, 0xB4, 0x8E, 0x5C, 0xD0, 0x11, 0x34, 0xDF, 0x5D, 0xBF, 0x52, + 0xA7, 0x81, 0x00, 0xC3, 0x7F, 0x99, 0x45, 0x99, 0x15, 0xD5, 0x17, 0xC8, + 0x0A, 0x53, 0xEC, 0x63, 0xF3, 0x99, 0x7D, 0xCC, 0x69, 0x12, 0x86, 0xC2, + 0x17, 0xF0, 0x01, 0x9E, 0xBF, 0x84, 0xBC, 0xD1, 0x52, 0xCB, 0x1B, 0x92, + 0x66, 0xCE, 0xA4, 0x53, 0xE5, 0xA1, 0xBF, 0xC4, 0xDB, 0x09, 0xD6, 0xE6, + 0x89, 0x56, 0x2B, 0xC8, 0xE3, 0x7C, 0xDE, 0xE3, 0xFF, 0x89, 0xE5, 0x35, + 0x6E, 0x28, 0xE8, 0x6C, 0x0B, 0x23, 0x51, 0xA9, 0x25, 0x05, 0xEB, 0x48, + 0xF8, 0xDD, 0xB1, 0xCA, 0xFA, 0x6C, 0x08, 0x51, 0xEF, 0xB7, 0x18, 0x6C, + 0x44, 0xCA, 0x26, 0xE1, 0x73, 0xC6, 0x89, 0x06, 0x81, 0xE5, 0x8A, 0xAC, + 0xB0, 0xE2, 0x29, 0xC6, 0xB9, 0x24, 0xB3, 0x6B, 0x44, 0x11, 0xF4, 0xA5, + 0x43, 0xC2, 0x4C, 0x43, 0xE5, 0x70, 0x36, 0x8C, 0xB6, 0x33, 0x57, 0x7A, + 0x95, 0x2E, 0x82, 0xA0, 0xF4, 0x5C, 0x10, 0xB3, 0x61, 0x83, 0xF6, 0x02, + 0x05, 0x86, 0x2E, 0x7C, 0x2D, 0x6C, 0xDC, 0x03, 0x46, 0x6E, 0x35, 0x93, + 0xD5, 0x7A, 0x95, 0x2F, 0xDE, 0x20, 0xD8, 0x5B, 0x7E, 0x94, 0x90, 0x04, + 0x6A, 0xBA, 0x59, 0x3D, 0x04, 0x05, 0x75, 0x9D, 0x37, 0xA2, 0x0E, 0x2E, + 0x3D, 0xEB, 0xC1, 0xA4, 0x52, 0x83, 0xFE, 0xD0, 0x6B, 0xD4, 0x66, 0x8E, + 0xDC, 0xC6, 0xE9, 0x12, 0x4E, 0x1D, 0x2A, 0x57, 0xAA, 0x10, 0xBC, 0x7C, + 0x5E, 0x82, 0x7D, 0xA6, 0xA6, 0xC9, 0xF2, 0x2D, 0xB9, 0xF5, 0x17, 0x27, + 0xAD, 0xD1, 0x0E, 0x89, 0x54, 0x2B, 0x95, 0xFA, 0xC0, 0xAD, 0x1D, 0x98, + 0x14, 0x78, 0x33, 0x42, 0x86, 0x0A, 0xA9, 0x73, 0xB5, 0xFB, 0x74, 0x0D, + 0xB7, 0x1B, 0x30, 0x19, 0xC4, 0x5A, 0x0E, 0x1C, 0x27, 0xB7, 0xDA, 0x18, + 0xD0, 0xFF, 0x8A, 0xC8, 0x05, 0xBA, 0xF1, 0xAA, 0x1C, 0xA2, 0x37, 0xB7, + 0xE6, 0x48, 0xA4, 0x46, 0x2C, 0x94, 0xEA, 0xA8, 0x76, 0x62, 0x47, 0x8B, + 0x10, 0x53, 0x07, 0x48, 0x57, 0x6C, 0xE2, 0x92, 0x4D, 0xB6, 0xAE, 0x05, + 0xCB, 0xDC, 0xC1, 0x4A, 0x5E, 0x8F, 0xAC, 0x3D, 0x19, 0x4E, 0xC2, 0xED, + 0x60, 0x75, 0x2B, 0xDB, 0xC1, 0xCA, 0x42, 0xD5 +}; + +static const unsigned char TA646_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA647_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, + 0x64, 0x79, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x49, 0x6E, + 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x28, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6C, + 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA647_RSA_N[] = { + 0xDE, 0x9D, 0xD7, 0xEA, 0x57, 0x18, 0x49, 0xA1, 0x5B, 0xEB, 0xD7, 0x5F, + 0x48, 0x86, 0xEA, 0xBE, 0xDD, 0xFF, 0xE4, 0xEF, 0x67, 0x1C, 0xF4, 0x65, + 0x68, 0xB3, 0x57, 0x71, 0xA0, 0x5E, 0x77, 0xBB, 0xED, 0x9B, 0x49, 0xE9, + 0x70, 0x80, 0x3D, 0x56, 0x18, 0x63, 0x08, 0x6F, 0xDA, 0xF2, 0xCC, 0xD0, + 0x3F, 0x7F, 0x02, 0x54, 0x22, 0x54, 0x10, 0xD8, 0xB2, 0x81, 0xD4, 0xC0, + 0x75, 0x3D, 0x4B, 0x7F, 0xC7, 0x77, 0xC3, 0x3E, 0x78, 0xAB, 0x1A, 0x03, + 0xB5, 0x20, 0x6B, 0x2F, 0x6A, 0x2B, 0xB1, 0xC5, 0x88, 0x7E, 0xC4, 0xBB, + 0x1E, 0xB0, 0xC1, 0xD8, 0x45, 0x27, 0x6F, 0xAA, 0x37, 0x58, 0xF7, 0x87, + 0x26, 0xD7, 0xD8, 0x2D, 0xF6, 0xA9, 0x17, 0xB7, 0x1F, 0x72, 0x36, 0x4E, + 0xA6, 0x17, 0x3F, 0x65, 0x98, 0x92, 0xDB, 0x2A, 0x6E, 0x5D, 0xA2, 0xFE, + 0x88, 0xE0, 0x0B, 0xDE, 0x7F, 0xE5, 0x8D, 0x15, 0xE1, 0xEB, 0xCB, 0x3A, + 0xD5, 0xE2, 0x12, 0xA2, 0x13, 0x2D, 0xD8, 0x8E, 0xAF, 0x5F, 0x12, 0x3D, + 0xA0, 0x08, 0x05, 0x08, 0xB6, 0x5C, 0xA5, 0x65, 0x38, 0x04, 0x45, 0x99, + 0x1E, 0xA3, 0x60, 0x60, 0x74, 0xC5, 0x41, 0xA5, 0x72, 0x62, 0x1B, 0x62, + 0xC5, 0x1F, 0x6F, 0x5F, 0x1A, 0x42, 0xBE, 0x02, 0x51, 0x65, 0xA8, 0xAE, + 0x23, 0x18, 0x6A, 0xFC, 0x78, 0x03, 0xA9, 0x4D, 0x7F, 0x80, 0xC3, 0xFA, + 0xAB, 0x5A, 0xFC, 0xA1, 0x40, 0xA4, 0xCA, 0x19, 0x16, 0xFE, 0xB2, 0xC8, + 0xEF, 0x5E, 0x73, 0x0D, 0xEE, 0x77, 0xBD, 0x9A, 0xF6, 0x79, 0x98, 0xBC, + 0xB1, 0x07, 0x67, 0xA2, 0x15, 0x0D, 0xDD, 0xA0, 0x58, 0xC6, 0x44, 0x7B, + 0x0A, 0x3E, 0x62, 0x28, 0x5F, 0xBA, 0x41, 0x07, 0x53, 0x58, 0xCF, 0x11, + 0x7E, 0x38, 0x74, 0xC5, 0xF8, 0xFF, 0xB5, 0x69, 0x90, 0x8F, 0x84, 0x74, + 0xEA, 0x97, 0x1B, 0xAF +}; + +static const unsigned char TA647_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA648_DN[] = { + 0x30, 0x7F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x2B, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, 0x56, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA648_EC_Q[] = { + 0x04, 0xAA, 0x12, 0x47, 0x90, 0x98, 0x1B, 0xFB, 0xEF, 0xC3, 0x40, 0x07, + 0x83, 0x20, 0x4E, 0xF1, 0x30, 0x82, 0xA2, 0x06, 0xD1, 0xF2, 0x92, 0x86, + 0x61, 0xF2, 0xF6, 0x21, 0x68, 0xCA, 0x00, 0xC4, 0xC7, 0xEA, 0x43, 0x00, + 0x54, 0x86, 0xDC, 0xFD, 0x1F, 0xDF, 0x00, 0xB8, 0x41, 0x62, 0x5C, 0xDC, + 0x70, 0x16, 0x32, 0xDE, 0x1F, 0x99, 0xD4, 0xCC, 0xC5, 0x07, 0xC8, 0x08, + 0x1F, 0x61, 0x16, 0x07, 0x51, 0x3D, 0x7D, 0x5C, 0x07, 0x53, 0xE3, 0x35, + 0x38, 0x8C, 0xDF, 0xCD, 0x9F, 0xD9, 0x2E, 0x0D, 0x4A, 0xB6, 0x19, 0x2E, + 0x5A, 0x70, 0x5A, 0x06, 0xED, 0xBE, 0xF0, 0xA1, 0xB0, 0xCA, 0xD0, 0x09, + 0x29 +}; + +static const unsigned char TA649_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x28, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA649_RSA_N[] = { + 0xB9, 0x5D, 0x51, 0x28, 0x4B, 0x3C, 0x37, 0x92, 0xD1, 0x82, 0xCE, 0xBD, + 0x1D, 0xBD, 0xCD, 0xDD, 0xB8, 0xAB, 0xCF, 0x0A, 0x3E, 0xE1, 0x5D, 0xE5, + 0xDC, 0xAA, 0x09, 0xB9, 0x57, 0x02, 0x3E, 0xE6, 0x63, 0x61, 0xDF, 0xF2, + 0x0F, 0x82, 0x63, 0xAE, 0xA3, 0xF7, 0xAC, 0x73, 0xD1, 0x7C, 0xE7, 0xB3, + 0x0B, 0xAF, 0x08, 0x00, 0x09, 0x59, 0x7F, 0xCD, 0x29, 0x2A, 0x88, 0x93, + 0x87, 0x17, 0x18, 0x80, 0xED, 0x88, 0xB2, 0xB4, 0xB6, 0x10, 0x1F, 0x2D, + 0xD6, 0x5F, 0x55, 0xA2, 0x13, 0x5D, 0xD1, 0xC6, 0xEB, 0x06, 0x56, 0x89, + 0x88, 0xFE, 0xAC, 0x32, 0x9D, 0xFD, 0x5C, 0xC3, 0x05, 0xC7, 0x6E, 0xEE, + 0x86, 0x89, 0xBA, 0x88, 0x03, 0x9D, 0x72, 0x21, 0x86, 0x90, 0xAE, 0x8F, + 0x03, 0xA5, 0xDC, 0x9F, 0x88, 0x28, 0xCB, 0xA3, 0x92, 0x49, 0x0F, 0xEC, + 0xD0, 0x0F, 0xE2, 0x6D, 0x44, 0x4F, 0x80, 0x6A, 0xB2, 0xD4, 0xE7, 0xA0, + 0x0A, 0x53, 0x01, 0xBA, 0x8E, 0x97, 0x91, 0x76, 0x6E, 0xBC, 0xFC, 0xD5, + 0x6B, 0x36, 0xE6, 0x40, 0x88, 0xD6, 0x7B, 0x2F, 0x5F, 0x05, 0xE8, 0x2C, + 0x6D, 0x11, 0xF3, 0xE7, 0xB2, 0xBE, 0x92, 0x44, 0x4C, 0xD2, 0x97, 0xA4, + 0xFE, 0xD2, 0x72, 0x81, 0x43, 0x07, 0x9C, 0xE9, 0x11, 0x3E, 0xF5, 0x8B, + 0x1A, 0x59, 0x7D, 0x1F, 0x68, 0x58, 0xDD, 0x04, 0x00, 0x2C, 0x96, 0xF3, + 0x43, 0xB3, 0x7E, 0x98, 0x19, 0x74, 0xD9, 0x9C, 0x73, 0xD9, 0x18, 0xBE, + 0x41, 0xC7, 0x34, 0x79, 0xD9, 0xF4, 0x62, 0xC2, 0x43, 0xB9, 0xB3, 0x27, + 0xB0, 0x22, 0xCB, 0xF9, 0x3D, 0x52, 0xC7, 0x30, 0x47, 0xB3, 0xC9, 0x3E, + 0xB8, 0x6A, 0xE2, 0xE7, 0xE8, 0x81, 0x70, 0x5E, 0x42, 0x8B, 0x4F, 0x26, + 0xA5, 0xFE, 0x3A, 0xC2, 0x20, 0x6E, 0xBB, 0xF8, 0x16, 0x8E, 0xCD, 0x0C, + 0xA9, 0xB4, 0x1B, 0x6C, 0x76, 0x10, 0xE1, 0x58, 0x79, 0x46, 0x3E, 0x54, + 0xCE, 0x80, 0xA8, 0x57, 0x09, 0x37, 0x29, 0x1B, 0x99, 0x13, 0x8F, 0x0C, + 0xC8, 0xD6, 0x2C, 0x1C, 0xFB, 0x05, 0xE8, 0x08, 0x95, 0x3D, 0x65, 0x46, + 0xDC, 0xEE, 0xCD, 0x69, 0xE2, 0x4D, 0x8F, 0x87, 0x28, 0x4E, 0x34, 0x0B, + 0x3E, 0xCF, 0x14, 0xD9, 0xBB, 0xDD, 0xB6, 0x50, 0x9A, 0xAD, 0x77, 0xD4, + 0x19, 0xD6, 0xDA, 0x1A, 0x88, 0xC8, 0x4E, 0x1B, 0x27, 0x75, 0xD8, 0xB2, + 0x08, 0xF1, 0xAE, 0x83, 0x30, 0xB9, 0x11, 0x0E, 0xCD, 0x87, 0xF0, 0x84, + 0x8D, 0x15, 0x72, 0x7C, 0xA1, 0xEF, 0xCC, 0xF2, 0x88, 0x61, 0xBA, 0xF4, + 0x69, 0xBB, 0x0C, 0x8C, 0x0B, 0x75, 0x57, 0x04, 0xB8, 0x4E, 0x2A, 0x14, + 0x2E, 0x3D, 0x0F, 0x1C, 0x1E, 0x32, 0xA6, 0x62, 0x36, 0xEE, 0x66, 0xE2, + 0x22, 0xB8, 0x05, 0x40, 0x63, 0x10, 0x22, 0xF3, 0x33, 0x1D, 0x74, 0x72, + 0x8A, 0x2C, 0xF5, 0x39, 0x29, 0xA0, 0xD3, 0xE7, 0x1B, 0x80, 0x84, 0x2D, + 0xC5, 0x3D, 0xE3, 0x4D, 0xB1, 0xFD, 0x1A, 0x6F, 0xBA, 0x65, 0x07, 0x3B, + 0x58, 0xEC, 0x42, 0x45, 0x26, 0xFB, 0xD8, 0xDA, 0x25, 0x72, 0xC4, 0xF6, + 0x00, 0xB1, 0x22, 0x79, 0xBD, 0xE3, 0x7C, 0x59, 0x62, 0x4A, 0x9C, 0x05, + 0x6F, 0x3D, 0xCE, 0xE6, 0xD6, 0x47, 0x63, 0x99, 0xC6, 0x24, 0x6F, 0x72, + 0x12, 0xC8, 0xAC, 0x7F, 0x90, 0xB4, 0x0B, 0x91, 0x70, 0xE8, 0xB7, 0xE6, + 0x16, 0x10, 0x71, 0x17, 0xCE, 0xDE, 0x06, 0x4F, 0x48, 0x41, 0x7D, 0x35, + 0x4A, 0xA3, 0x89, 0xF2, 0xC9, 0x4B, 0x7B, 0x41, 0x11, 0x6D, 0x67, 0xB7, + 0x08, 0x98, 0x4C, 0xE5, 0x11, 0x19, 0xAE, 0x42, 0x80, 0xDC, 0xFB, 0x90, + 0x05, 0xD4, 0xF8, 0x50, 0xCA, 0xBE, 0xE4, 0xAD, 0xC7, 0xC2, 0x94, 0xD7, + 0x16, 0x9D, 0xE6, 0x17, 0x8F, 0xAF, 0x36, 0xFB +}; + +static const unsigned char TA649_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA650_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA650_EC_Q[] = { + 0x04, 0x1A, 0xAC, 0x54, 0x5A, 0xA9, 0xF9, 0x68, 0x23, 0xE7, 0x7A, 0xD5, + 0x24, 0x6F, 0x53, 0xC6, 0x5A, 0xD8, 0x4B, 0xAB, 0xC6, 0xD5, 0xB6, 0xD1, + 0xE6, 0x73, 0x71, 0xAE, 0xDD, 0x9C, 0xD6, 0x0C, 0x61, 0xFD, 0xDB, 0xA0, + 0x89, 0x03, 0xB8, 0x05, 0x14, 0xEC, 0x57, 0xCE, 0xEE, 0x5D, 0x3F, 0xE2, + 0x21, 0xB3, 0xCE, 0xF7, 0xD4, 0x8A, 0x79, 0xE0, 0xA3, 0x83, 0x7E, 0x2D, + 0x97, 0xD0, 0x61, 0xC4, 0xF1, 0x99, 0xDC, 0x25, 0x91, 0x63, 0xAB, 0x7F, + 0x30, 0xA3, 0xB4, 0x70, 0xE2, 0xC7, 0xA1, 0x33, 0x9C, 0xF3, 0xBF, 0x2E, + 0x5C, 0x53, 0xB1, 0x5F, 0xB3, 0x7D, 0x32, 0x7F, 0x8A, 0x34, 0xE3, 0x79, + 0x79 +}; + +static const unsigned char TA651_DN[] = { + 0x30, 0x68, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, + 0x6C, 0x64, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA651_RSA_N[] = { + 0xB7, 0x32, 0xC8, 0xFE, 0xE9, 0x71, 0xA6, 0x04, 0x85, 0xAD, 0x0C, 0x11, + 0x64, 0xDF, 0xCE, 0x4D, 0xEF, 0xC8, 0x03, 0x18, 0x87, 0x3F, 0xA1, 0xAB, + 0xFB, 0x3C, 0xA6, 0x9F, 0xF0, 0xC3, 0xA1, 0xDA, 0xD4, 0xD8, 0x6E, 0x2B, + 0x53, 0x90, 0xFB, 0x24, 0xA4, 0x3E, 0x84, 0xF0, 0x9E, 0xE8, 0x5F, 0xEC, + 0xE5, 0x27, 0x44, 0xF5, 0x28, 0xA6, 0x3F, 0x7B, 0xDE, 0xE0, 0x2A, 0xF0, + 0xC8, 0xAF, 0x53, 0x2F, 0x9E, 0xCA, 0x05, 0x01, 0x93, 0x1E, 0x8F, 0x66, + 0x1C, 0x39, 0xA7, 0x4D, 0xFA, 0x5A, 0xB6, 0x73, 0x04, 0x25, 0x66, 0xEB, + 0x77, 0x7F, 0xE7, 0x59, 0xC6, 0x4A, 0x99, 0x25, 0x14, 0x54, 0xEB, 0x26, + 0xC7, 0xF3, 0x7F, 0x19, 0xD5, 0x30, 0x70, 0x8F, 0xAF, 0xB0, 0x46, 0x2A, + 0xFF, 0xAD, 0xEB, 0x29, 0xED, 0xD7, 0x9F, 0xAA, 0x04, 0x87, 0xA3, 0xD4, + 0xF9, 0x89, 0xA5, 0x34, 0x5F, 0xDB, 0x43, 0x91, 0x82, 0x36, 0xD9, 0x66, + 0x3C, 0xB1, 0xB8, 0xB9, 0x82, 0xFD, 0x9C, 0x3A, 0x3E, 0x10, 0xC8, 0x3B, + 0xEF, 0x06, 0x65, 0x66, 0x7A, 0x9B, 0x19, 0x18, 0x3D, 0xFF, 0x71, 0x51, + 0x3C, 0x30, 0x2E, 0x5F, 0xBE, 0x3D, 0x77, 0x73, 0xB2, 0x5D, 0x06, 0x6C, + 0xC3, 0x23, 0x56, 0x9A, 0x2B, 0x85, 0x26, 0x92, 0x1C, 0xA7, 0x02, 0xB3, + 0xE4, 0x3F, 0x0D, 0xAF, 0x08, 0x79, 0x82, 0xB8, 0x36, 0x3D, 0xEA, 0x9C, + 0xD3, 0x35, 0xB3, 0xBC, 0x69, 0xCA, 0xF5, 0xCC, 0x9D, 0xE8, 0xFD, 0x64, + 0x8D, 0x17, 0x80, 0x33, 0x6E, 0x5E, 0x4A, 0x5D, 0x99, 0xC9, 0x1E, 0x87, + 0xB4, 0x9D, 0x1A, 0xC0, 0xD5, 0x6E, 0x13, 0x35, 0x23, 0x5E, 0xDF, 0x9B, + 0x5F, 0x3D, 0xEF, 0xD6, 0xF7, 0x76, 0xC2, 0xEA, 0x3E, 0xBB, 0x78, 0x0D, + 0x1C, 0x42, 0x67, 0x6B, 0x04, 0xD8, 0xF8, 0xD6, 0xDA, 0x6F, 0x8B, 0xF2, + 0x44, 0xA0, 0x01, 0xAB +}; + +static const unsigned char TA651_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA652_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0E, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA652_RSA_N[] = { + 0xAB, 0xA4, 0x81, 0xE5, 0x95, 0xCD, 0xF5, 0xF6, 0x14, 0x8E, 0xC2, 0x4F, + 0xCA, 0xD4, 0xE2, 0x78, 0x95, 0x58, 0x9C, 0x41, 0xE1, 0x0D, 0x99, 0x40, + 0x24, 0x17, 0x39, 0x91, 0x33, 0x66, 0xE9, 0xBE, 0xE1, 0x83, 0xAF, 0x62, + 0x5C, 0x89, 0xD1, 0xFC, 0x24, 0x5B, 0x61, 0xB3, 0xE0, 0x11, 0x11, 0x41, + 0x1C, 0x1D, 0x6E, 0xF0, 0xB8, 0xBB, 0xF8, 0xDE, 0xA7, 0x81, 0xBA, 0xA6, + 0x48, 0xC6, 0x9F, 0x1D, 0xBD, 0xBE, 0x8E, 0xA9, 0x41, 0x3E, 0xB8, 0x94, + 0xED, 0x29, 0x1A, 0xD4, 0x8E, 0xD2, 0x03, 0x1D, 0x03, 0xEF, 0x6D, 0x0D, + 0x67, 0x1C, 0x57, 0xD7, 0x06, 0xAD, 0xCA, 0xC8, 0xF5, 0xFE, 0x0E, 0xAF, + 0x66, 0x25, 0x48, 0x04, 0x96, 0x0B, 0x5D, 0xA3, 0xBA, 0x16, 0xC3, 0x08, + 0x4F, 0xD1, 0x46, 0xF8, 0x14, 0x5C, 0xF2, 0xC8, 0x5E, 0x01, 0x99, 0x6D, + 0xFD, 0x88, 0xCC, 0x86, 0xA8, 0xC1, 0x6F, 0x31, 0x42, 0x6C, 0x52, 0x3E, + 0x68, 0xCB, 0xF3, 0x19, 0x34, 0xDF, 0xBB, 0x87, 0x18, 0x56, 0x80, 0x26, + 0xC4, 0xD0, 0xDC, 0xC0, 0x6F, 0xDF, 0xDE, 0xA0, 0xC2, 0x91, 0x16, 0xA0, + 0x64, 0x11, 0x4B, 0x44, 0xBC, 0x1E, 0xF6, 0xE7, 0xFA, 0x63, 0xDE, 0x66, + 0xAC, 0x76, 0xA4, 0x71, 0xA3, 0xEC, 0x36, 0x94, 0x68, 0x7A, 0x77, 0xA4, + 0xB1, 0xE7, 0x0E, 0x2F, 0x81, 0x7A, 0xE2, 0xB5, 0x72, 0x86, 0xEF, 0xA2, + 0x6B, 0x8B, 0xF0, 0x0F, 0xDB, 0xD3, 0x59, 0x3F, 0xBA, 0x72, 0xBC, 0x44, + 0x24, 0x9C, 0xE3, 0x73, 0xB3, 0xF7, 0xAF, 0x57, 0x2F, 0x42, 0x26, 0x9D, + 0xA9, 0x74, 0xBA, 0x00, 0x52, 0xF2, 0x4B, 0xCD, 0x53, 0x7C, 0x47, 0x0B, + 0x36, 0x85, 0x0E, 0x66, 0xA9, 0x08, 0x97, 0x16, 0x34, 0x57, 0xC1, 0x66, + 0xF7, 0x80, 0xE3, 0xED, 0x70, 0x54, 0xC7, 0x93, 0xE0, 0x2E, 0x28, 0x15, + 0x59, 0x87, 0xBA, 0xBB +}; + +static const unsigned char TA652_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA653_DN[] = { + 0x30, 0x67, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x49, 0x4E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x0A, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x50, 0x4B, 0x49, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x65, + 0x4D, 0x75, 0x64, 0x68, 0x72, 0x61, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, + 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, 0x20, 0x4C, 0x69, 0x6D, 0x69, + 0x74, 0x65, 0x64, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x13, 0x65, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA653_RSA_N[] = { + 0x93, 0x4B, 0xBB, 0xE9, 0x66, 0x8A, 0xEE, 0x9D, 0x5B, 0xD5, 0x34, 0x93, + 0xD0, 0x1B, 0x1E, 0xC3, 0xE7, 0x9E, 0xB8, 0x64, 0x33, 0x7F, 0x63, 0x78, + 0x68, 0xB4, 0xCD, 0x2E, 0x71, 0x75, 0xD7, 0x9B, 0x20, 0xC6, 0x4D, 0x29, + 0xBC, 0xB6, 0x68, 0x60, 0x8A, 0xF7, 0x21, 0x9A, 0x56, 0x35, 0x5A, 0xF3, + 0x76, 0xBD, 0xD8, 0xCD, 0x9A, 0xFF, 0x93, 0x56, 0x4B, 0xA5, 0x59, 0x06, + 0xA1, 0x93, 0x34, 0x29, 0xDD, 0x16, 0x34, 0x75, 0x4E, 0xF2, 0x81, 0xB4, + 0xC7, 0x96, 0x4E, 0xAD, 0x19, 0x15, 0x52, 0x4A, 0xFE, 0x3C, 0x70, 0x75, + 0x70, 0xCD, 0xAF, 0x2B, 0xAB, 0x15, 0x9A, 0x33, 0x3C, 0xAA, 0xB3, 0x8B, + 0xAA, 0xCD, 0x43, 0xFD, 0xF5, 0xEA, 0x70, 0xFF, 0xED, 0xCF, 0x11, 0x3B, + 0x94, 0xCE, 0x4E, 0x32, 0x16, 0xD3, 0x23, 0x40, 0x2A, 0x77, 0xB3, 0xAF, + 0x3C, 0x01, 0x2C, 0x6C, 0xED, 0x99, 0x2C, 0x8B, 0xD9, 0x4E, 0x69, 0x98, + 0xB2, 0xF7, 0x8F, 0x41, 0xB0, 0x32, 0x78, 0x61, 0xD6, 0x0D, 0x5F, 0xC3, + 0xFA, 0xA2, 0x40, 0x92, 0x1D, 0x5C, 0x17, 0xE6, 0x70, 0x3E, 0x35, 0xE7, + 0xA2, 0xB7, 0xC2, 0x62, 0xE2, 0xAB, 0xA4, 0x38, 0x4C, 0xB5, 0x39, 0x35, + 0x6F, 0xEA, 0x03, 0x69, 0xFA, 0x3A, 0x54, 0x68, 0x85, 0x6D, 0xD6, 0xF2, + 0x2F, 0x43, 0x55, 0x1E, 0x91, 0x0D, 0x0E, 0xD8, 0xD5, 0x6A, 0xA4, 0x96, + 0xD1, 0x13, 0x3C, 0x2C, 0x78, 0x50, 0xE8, 0x3A, 0x92, 0xD2, 0x17, 0x56, + 0xE5, 0x35, 0x1A, 0x40, 0x1C, 0x3E, 0x8D, 0x2C, 0xED, 0x39, 0xDF, 0x42, + 0xE0, 0x83, 0x41, 0x74, 0xDF, 0xA3, 0xCD, 0xC2, 0x86, 0x60, 0x48, 0x68, + 0xE3, 0x69, 0x0B, 0x54, 0x00, 0x8B, 0xE4, 0x76, 0x69, 0x21, 0x0D, 0x79, + 0x4E, 0x34, 0x08, 0x5E, 0x14, 0xC2, 0xCC, 0xB1, 0xB7, 0xAD, 0xD7, 0x7C, + 0x70, 0x8A, 0xC7, 0x85 +}; + +static const unsigned char TA653_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA654_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x13, 0x30, 0x30, + 0x30, 0x32, 0x20, 0x34, 0x38, 0x31, 0x34, 0x36, 0x33, 0x30, 0x38, 0x31, + 0x30, 0x30, 0x30, 0x33, 0x36, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA654_RSA_N[] = { + 0xCD, 0x18, 0x39, 0x65, 0x1A, 0x59, 0xB1, 0xEA, 0x64, 0x16, 0x0E, 0x8C, + 0x94, 0x24, 0x95, 0x7C, 0x83, 0xD3, 0xC5, 0x39, 0x26, 0xDC, 0x0C, 0xEF, + 0x16, 0x57, 0x8D, 0xD7, 0xD8, 0xAC, 0xA3, 0x42, 0x7F, 0x82, 0xCA, 0xED, + 0xCD, 0x5B, 0xDB, 0x0E, 0xB7, 0x2D, 0xED, 0x45, 0x08, 0x17, 0xB2, 0xD9, + 0xB3, 0xCB, 0xD6, 0x17, 0x52, 0x72, 0x28, 0xDB, 0x8E, 0x4E, 0x9E, 0x8A, + 0xB6, 0x0B, 0xF9, 0x9E, 0x84, 0x9A, 0x4D, 0x76, 0xDE, 0x22, 0x29, 0x5C, + 0xD2, 0xB3, 0xD2, 0x06, 0x3E, 0x30, 0x39, 0xA9, 0x74, 0xA3, 0x92, 0x56, + 0x1C, 0xA1, 0x6F, 0x4C, 0x0A, 0x20, 0x6D, 0x9F, 0x23, 0x7A, 0xB4, 0xC6, + 0xDA, 0x2C, 0xE4, 0x1D, 0x2C, 0xDC, 0xB3, 0x28, 0xD0, 0x13, 0xF2, 0x4C, + 0x4E, 0x02, 0x49, 0xA1, 0x54, 0x40, 0x9E, 0xE6, 0xE5, 0x05, 0xA0, 0x2D, + 0x84, 0xC8, 0xFF, 0x98, 0x6C, 0xD0, 0xEB, 0x8A, 0x1A, 0x84, 0x08, 0x1E, + 0xB7, 0x68, 0x23, 0xEE, 0x23, 0xD5, 0x70, 0xCE, 0x6D, 0x51, 0x69, 0x10, + 0xEE, 0xA1, 0x7A, 0xC2, 0xD1, 0x22, 0x31, 0xC2, 0x82, 0x85, 0xD2, 0xF2, + 0x55, 0x76, 0x50, 0x7C, 0x25, 0x7A, 0xC9, 0x84, 0x5C, 0x0B, 0xAC, 0xDD, + 0x42, 0x4E, 0x2B, 0xE7, 0x82, 0xA2, 0x24, 0x89, 0xCB, 0x90, 0xB2, 0xD0, + 0xEE, 0x23, 0xBA, 0x66, 0x4C, 0xBB, 0x62, 0xA4, 0xF9, 0x53, 0x5A, 0x64, + 0x7B, 0x7C, 0x98, 0xFA, 0xA3, 0x48, 0x9E, 0x0F, 0x95, 0xAE, 0xA7, 0x18, + 0xF4, 0x6A, 0xEC, 0x2E, 0x03, 0x45, 0xAF, 0xF0, 0x74, 0xF8, 0x2A, 0xCD, + 0x7A, 0x5D, 0xD1, 0xBE, 0x44, 0x26, 0x32, 0x29, 0xF1, 0xF1, 0xF5, 0x6C, + 0xCC, 0x7E, 0x02, 0x21, 0x0B, 0x9F, 0x6F, 0xA4, 0x3F, 0xBE, 0x9D, 0x53, + 0xE2, 0xCF, 0x7D, 0xA9, 0x2C, 0x7C, 0x58, 0x1A, 0x97, 0xE1, 0x3D, 0x37, + 0x37, 0x18, 0x66, 0x28, 0xD2, 0x40, 0xC5, 0x51, 0x8A, 0x8C, 0xC3, 0x2D, + 0xCE, 0x53, 0x88, 0x24, 0x58, 0x64, 0x30, 0x16, 0xC5, 0xAA, 0xE0, 0xD6, + 0x0A, 0xA6, 0x40, 0xDF, 0x78, 0xF6, 0xF5, 0x04, 0x7C, 0x69, 0x13, 0x84, + 0xBC, 0xD1, 0xD1, 0xA7, 0x06, 0xCF, 0x01, 0xF7, 0x68, 0xC0, 0xA8, 0x57, + 0xBB, 0x3A, 0x61, 0xAD, 0x04, 0x8C, 0x93, 0xE3, 0xAD, 0xFC, 0xF0, 0xDB, + 0x44, 0x6D, 0x59, 0xDC, 0x49, 0x59, 0xAE, 0xAC, 0x9A, 0x99, 0x36, 0x30, + 0x41, 0x7B, 0x76, 0x33, 0x22, 0x87, 0xA3, 0xC2, 0x92, 0x86, 0x6E, 0xF9, + 0x70, 0xEE, 0xAE, 0x87, 0x87, 0x95, 0x1B, 0xC4, 0x7A, 0xBD, 0x31, 0xF3, + 0xD4, 0xD2, 0xE5, 0x99, 0xFF, 0xBE, 0x48, 0xEC, 0x75, 0xF5, 0x78, 0x16, + 0x1D, 0xA6, 0x70, 0xC1, 0x7F, 0x3C, 0x1B, 0xA1, 0x92, 0xFB, 0xCF, 0xC8, + 0x3C, 0xD6, 0xC5, 0x93, 0x0A, 0x8F, 0xF5, 0x55, 0x3A, 0x76, 0x95, 0xCE, + 0x59, 0x98, 0x8A, 0x09, 0x95, 0x77, 0x32, 0x9A, 0x83, 0xBA, 0x2C, 0x04, + 0x3A, 0x97, 0xBD, 0xD4, 0x2F, 0xBE, 0xD7, 0x6C, 0x9B, 0xA2, 0xCA, 0x7D, + 0x6D, 0x26, 0xC9, 0x55, 0xD5, 0xCF, 0xC3, 0x79, 0x52, 0x08, 0x09, 0x99, + 0x07, 0x24, 0x2D, 0x64, 0x25, 0x6B, 0xA6, 0x21, 0x69, 0x9B, 0x6A, 0xDD, + 0x74, 0x4D, 0x6B, 0x97, 0x7A, 0x41, 0xBD, 0xAB, 0x17, 0xF9, 0x90, 0x17, + 0x48, 0x8F, 0x36, 0xF9, 0x2D, 0xD5, 0xC5, 0xDB, 0xEE, 0xAA, 0x85, 0x45, + 0x41, 0xFA, 0xCD, 0x3A, 0x45, 0xB1, 0x68, 0xE6, 0x36, 0x4C, 0x9B, 0x90, + 0x57, 0xEC, 0x23, 0xB9, 0x87, 0x08, 0xC2, 0xC4, 0x09, 0xF1, 0x97, 0x86, + 0x2A, 0x28, 0x4D, 0xE2, 0x74, 0xC0, 0xDA, 0xC4, 0x8C, 0xDB, 0xDF, 0xE2, + 0xA1, 0x17, 0x59, 0xCE, 0x24, 0x59, 0x74, 0x31, 0xDA, 0x7F, 0xFD, 0x30, + 0x6D, 0xD9, 0xDC, 0xE1, 0x6A, 0xE1, 0xFC, 0x5F +}; + +static const unsigned char TA654_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA655_DN[] = { + 0x30, 0x7A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x41, 0x73, 0x73, 0x65, 0x63, 0x6F, 0x20, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x53, 0x2E, + 0x41, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1E, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6D, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA655_RSA_N[] = { + 0xD1, 0x2D, 0x8E, 0xBB, 0xB7, 0x36, 0xEA, 0x6D, 0x37, 0x91, 0x9F, 0x4E, + 0x93, 0xA7, 0x05, 0xE4, 0x29, 0x03, 0x25, 0xCE, 0x1C, 0x82, 0xF7, 0x7C, + 0x99, 0x9F, 0x41, 0x06, 0xCD, 0xED, 0xA3, 0xBA, 0xC0, 0xDB, 0x09, 0x2C, + 0xC1, 0x7C, 0xDF, 0x29, 0x7E, 0x4B, 0x65, 0x2F, 0x93, 0xA7, 0xD4, 0x01, + 0x6B, 0x03, 0x28, 0x18, 0xA3, 0xD8, 0x9D, 0x05, 0xC1, 0x2A, 0xD8, 0x45, + 0xF1, 0x91, 0xDE, 0xDF, 0x3B, 0xD0, 0x80, 0x02, 0x8C, 0xCF, 0x38, 0x0F, + 0xEA, 0xA7, 0x5C, 0x78, 0x11, 0xA4, 0xC1, 0xC8, 0x85, 0x5C, 0x25, 0xD3, + 0xD3, 0xB2, 0xE7, 0x25, 0xCF, 0x11, 0x54, 0x97, 0xAB, 0x35, 0xC0, 0x1E, + 0x76, 0x1C, 0xEF, 0x00, 0x53, 0x9F, 0x39, 0xDC, 0x14, 0xA5, 0x2C, 0x22, + 0x25, 0xB3, 0x72, 0x72, 0xFC, 0x8D, 0xB3, 0xE5, 0x3E, 0x08, 0x1E, 0x14, + 0x2A, 0x37, 0x0B, 0x88, 0x3C, 0xCA, 0xB0, 0xF4, 0xC8, 0xC2, 0xA1, 0xAE, + 0xBC, 0xC1, 0xBE, 0x29, 0x67, 0x55, 0xE2, 0xFC, 0xAD, 0x59, 0x5C, 0xFE, + 0xBD, 0x57, 0x2C, 0xB0, 0x90, 0x8D, 0xC2, 0xED, 0x37, 0xB6, 0x7C, 0x99, + 0x88, 0xB5, 0xD5, 0x03, 0x9A, 0x3D, 0x15, 0x0D, 0x3D, 0x3A, 0xA8, 0xA8, + 0x45, 0xF0, 0x95, 0x4E, 0x25, 0x59, 0x1D, 0xCD, 0x98, 0x69, 0xBB, 0xD3, + 0xCC, 0x32, 0xC9, 0x8D, 0xEF, 0x81, 0xFE, 0xAD, 0x7D, 0x89, 0xBB, 0xBA, + 0x60, 0x13, 0xCA, 0x65, 0x95, 0x67, 0xA0, 0xF3, 0x19, 0xF6, 0x03, 0x56, + 0xD4, 0x6A, 0xD3, 0x27, 0xE2, 0xA1, 0xAD, 0x83, 0xF0, 0x4A, 0x12, 0x22, + 0x77, 0x1C, 0x05, 0x73, 0xE2, 0x19, 0x71, 0x42, 0xC0, 0xEC, 0x75, 0x46, + 0x9A, 0x90, 0x58, 0xE0, 0x6A, 0x8E, 0x2B, 0xA5, 0x46, 0x30, 0x04, 0x8E, + 0x19, 0xB2, 0x17, 0xE3, 0xBE, 0xA9, 0xBA, 0x7F, 0x56, 0xF1, 0x24, 0x03, + 0xD7, 0xB2, 0x21, 0x28, 0x76, 0x0E, 0x36, 0x30, 0x4C, 0x79, 0xD5, 0x41, + 0x9A, 0x9A, 0xA8, 0xB8, 0x35, 0xBA, 0x0C, 0x3A, 0xF2, 0x44, 0x1B, 0x20, + 0x88, 0xF7, 0xC5, 0x25, 0xD7, 0x3D, 0xC6, 0xE3, 0x3E, 0x43, 0xDD, 0x87, + 0xFE, 0xC4, 0xEA, 0xF5, 0x53, 0x3E, 0x4C, 0x65, 0xFF, 0x3B, 0x4A, 0xCB, + 0x78, 0x5A, 0x6B, 0x17, 0x5F, 0x0D, 0xC7, 0xC3, 0x4F, 0x4E, 0x9A, 0x2A, + 0xA2, 0xED, 0x57, 0x4D, 0x22, 0xE2, 0x46, 0x9A, 0x3F, 0x0F, 0x91, 0x34, + 0x24, 0x7D, 0x55, 0xE3, 0x8C, 0x95, 0x37, 0xD3, 0x1A, 0xF0, 0x09, 0x2B, + 0x2C, 0xD2, 0xC9, 0x8D, 0xB4, 0x0D, 0x00, 0xAB, 0x67, 0x29, 0x28, 0xD8, + 0x01, 0xF5, 0x19, 0x04, 0xB6, 0x1D, 0xBE, 0x76, 0xFE, 0x72, 0x5C, 0xC4, + 0x85, 0xCA, 0xD2, 0x80, 0x41, 0xDF, 0x05, 0xA8, 0xA3, 0xD5, 0x84, 0x90, + 0x4F, 0x0B, 0xF3, 0xE0, 0x3F, 0x9B, 0x19, 0xD2, 0x37, 0x89, 0x3F, 0xF2, + 0x7B, 0x52, 0x1C, 0x8C, 0xF6, 0xE1, 0xF7, 0x3C, 0x07, 0x97, 0x8C, 0x0E, + 0xA2, 0x59, 0x81, 0x0C, 0xB2, 0x90, 0x3D, 0xD3, 0xE3, 0x59, 0x46, 0xED, + 0x0F, 0xA9, 0xA7, 0xDE, 0x80, 0x6B, 0x5A, 0xAA, 0x07, 0xB6, 0x19, 0xCB, + 0xBC, 0x57, 0xF3, 0x97, 0x21, 0x7A, 0x0C, 0xB1, 0x2B, 0x74, 0x3E, 0xEB, + 0xDA, 0xA7, 0x67, 0x2D, 0x4C, 0xC4, 0x98, 0x9E, 0x36, 0x09, 0x76, 0x66, + 0x66, 0xFC, 0x1A, 0x3F, 0xEA, 0x48, 0x54, 0x1C, 0xBE, 0x30, 0xBD, 0x80, + 0x50, 0xBF, 0x7C, 0xB5, 0xCE, 0x00, 0xF6, 0x0C, 0x61, 0xD9, 0xE7, 0x24, + 0x03, 0xE0, 0xE3, 0x01, 0x81, 0x0E, 0xBD, 0xD8, 0x85, 0x34, 0x88, 0xBD, + 0xB2, 0x36, 0xA8, 0x7B, 0x5C, 0x08, 0xE5, 0x44, 0x80, 0x8C, 0x6F, 0xF8, + 0x2F, 0xD5, 0x21, 0xCA, 0x1D, 0x1C, 0xD0, 0xFB, 0xC4, 0xB5, 0x87, 0xD1, + 0x3A, 0x4E, 0xC7, 0x76, 0xB5, 0x35, 0x48, 0xB5 +}; + +static const unsigned char TA655_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA656_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x41, 0x54, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x65, 0x2D, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x65, + 0x20, 0x6D, 0x6F, 0x6E, 0x69, 0x74, 0x6F, 0x72, 0x69, 0x6E, 0x67, 0x20, + 0x47, 0x6D, 0x62, 0x48, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x10, 0x47, 0x4C, 0x4F, 0x42, 0x41, 0x4C, 0x54, 0x52, 0x55, + 0x53, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA656_RSA_N[] = { + 0xAE, 0x2E, 0x56, 0xAD, 0x1B, 0x1C, 0xEF, 0xF6, 0x95, 0x8F, 0xA0, 0x77, + 0x1B, 0x2B, 0xD3, 0x63, 0x8F, 0x84, 0x4D, 0x45, 0xA2, 0x0F, 0x9F, 0x5B, + 0x45, 0xAB, 0x59, 0x7B, 0x51, 0x34, 0xF9, 0xEC, 0x8B, 0x8A, 0x78, 0xC5, + 0xDD, 0x6B, 0xAF, 0xBD, 0xC4, 0xDF, 0x93, 0x45, 0x1E, 0xBF, 0x91, 0x38, + 0x0B, 0xAE, 0x0E, 0x16, 0xE7, 0x41, 0x73, 0xF8, 0xDB, 0xBB, 0xD1, 0xB8, + 0x51, 0xE0, 0xCB, 0x83, 0x3B, 0x73, 0x38, 0x6E, 0x77, 0x8A, 0x0F, 0x59, + 0x63, 0x26, 0xCD, 0xA7, 0x2A, 0xCE, 0x54, 0xFB, 0xB8, 0xE2, 0xC0, 0x7C, + 0x47, 0xCE, 0x60, 0x7C, 0x3F, 0xB2, 0x73, 0xF2, 0xC0, 0x19, 0xB6, 0x8A, + 0x92, 0x87, 0x35, 0x0D, 0x90, 0x28, 0xA2, 0xE4, 0x15, 0x04, 0x63, 0x3E, + 0xBA, 0xAF, 0xEE, 0x7C, 0x5E, 0xCC, 0xA6, 0x8B, 0x50, 0xB2, 0x38, 0xF7, + 0x41, 0x63, 0xCA, 0xCE, 0xFF, 0x69, 0x8F, 0x68, 0x0E, 0x95, 0x36, 0xE5, + 0xCC, 0xB9, 0x8C, 0x09, 0xCA, 0x4B, 0xDD, 0x31, 0x90, 0x96, 0xC8, 0xCC, + 0x1F, 0xFD, 0x56, 0x96, 0x34, 0xDB, 0x8E, 0x1C, 0xEA, 0x2C, 0xBE, 0x85, + 0x2E, 0x63, 0xDD, 0xAA, 0xA9, 0x95, 0xD3, 0xFD, 0x29, 0x95, 0x13, 0xF0, + 0xC8, 0x98, 0x93, 0xD9, 0x2D, 0x16, 0x47, 0x90, 0x11, 0x83, 0xA2, 0x3A, + 0x22, 0xA2, 0x28, 0x57, 0xA2, 0xEB, 0xFE, 0xC0, 0x8C, 0x28, 0xA0, 0xA6, + 0x7D, 0xE7, 0x2A, 0x42, 0x3B, 0x82, 0x80, 0x63, 0xA5, 0x63, 0x1F, 0x19, + 0xCC, 0x7C, 0xB2, 0x66, 0xA8, 0xC2, 0xD3, 0x6D, 0x37, 0x6F, 0xE2, 0x7E, + 0x06, 0x51, 0xD9, 0x45, 0x84, 0x1F, 0x12, 0xCE, 0x24, 0x52, 0x64, 0x85, + 0x0B, 0x48, 0x80, 0x4E, 0x87, 0xB1, 0x22, 0x22, 0x30, 0xAA, 0xEB, 0xAE, + 0xBE, 0xE0, 0x02, 0xE0, 0x40, 0xE8, 0xB0, 0x42, 0x80, 0x03, 0x51, 0xAA, + 0xB4, 0x7E, 0xAA, 0x44, 0xD7, 0x43, 0x61, 0xF3, 0xA2, 0x6B, 0x16, 0x89, + 0x49, 0xA4, 0xA3, 0xA4, 0x2B, 0x8A, 0x02, 0xC4, 0x78, 0xF4, 0x68, 0x8A, + 0xC1, 0xE4, 0x7A, 0x36, 0xB1, 0x6F, 0x1B, 0x96, 0x1B, 0x77, 0x49, 0x8D, + 0xD4, 0xC9, 0x06, 0x72, 0x8F, 0xCF, 0x53, 0xE3, 0xDC, 0x17, 0x85, 0x20, + 0x4A, 0xDC, 0x98, 0x27, 0xD3, 0x91, 0x26, 0x2B, 0x47, 0x1E, 0x69, 0x07, + 0xAF, 0xDE, 0xA2, 0xE4, 0xE4, 0xD4, 0x6B, 0x0B, 0xB3, 0x5E, 0x7C, 0xD4, + 0x24, 0x80, 0x47, 0x29, 0x69, 0x3B, 0x6E, 0xE8, 0xAC, 0xFD, 0x40, 0xEB, + 0xD8, 0xED, 0x71, 0x71, 0x2B, 0xF2, 0xE8, 0x58, 0x1D, 0xEB, 0x41, 0x97, + 0x22, 0xC5, 0x1F, 0xD4, 0x39, 0xD0, 0x27, 0x8F, 0x87, 0xE3, 0x18, 0xF4, + 0xE0, 0xA9, 0x46, 0x0D, 0xF5, 0x74, 0x3A, 0x82, 0x2E, 0xD0, 0x6E, 0x2C, + 0x91, 0xA3, 0x31, 0x5C, 0x3B, 0x46, 0xEA, 0x7B, 0x04, 0x10, 0x56, 0x5E, + 0x80, 0x1D, 0xF5, 0xA5, 0x65, 0xE8, 0x82, 0xFC, 0xE2, 0x07, 0x8C, 0x62, + 0x45, 0xF5, 0x20, 0xDE, 0x46, 0x70, 0x86, 0xA1, 0xBC, 0x93, 0xD3, 0x1E, + 0x74, 0xA6, 0x6C, 0xB0, 0x2C, 0xF7, 0x03, 0x0C, 0x88, 0x0C, 0xCB, 0xD4, + 0x72, 0x53, 0x86, 0xBC, 0x60, 0x46, 0xF3, 0x98, 0x6A, 0xC2, 0xF1, 0xBF, + 0x43, 0xF9, 0x70, 0x20, 0x77, 0xCA, 0x37, 0x41, 0x79, 0x55, 0x52, 0x63, + 0x8D, 0x5B, 0x12, 0x9F, 0xC5, 0x68, 0xC4, 0x88, 0x9D, 0xAC, 0xF2, 0x30, + 0xAB, 0xB7, 0xA3, 0x31, 0x97, 0x67, 0xAD, 0x8F, 0x17, 0x0F, 0x6C, 0xC7, + 0x73, 0xED, 0x24, 0x94, 0x6B, 0xC8, 0x83, 0x9A, 0xD0, 0x9A, 0x37, 0x49, + 0x04, 0xAB, 0xB1, 0x16, 0xC8, 0x6C, 0x49, 0x49, 0x2D, 0xAB, 0xA1, 0xD0, + 0x8C, 0x92, 0xF2, 0x41, 0x4A, 0x79, 0x21, 0x25, 0xDB, 0x63, 0xD7, 0xB6, + 0x9C, 0xA7, 0x7E, 0x42, 0x69, 0xFB, 0x3A, 0x63 +}; + +static const unsigned char TA656_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA657_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA657_RSA_N[] = { + 0xAD, 0x96, 0x9F, 0x2D, 0x9C, 0x4A, 0x4C, 0x4A, 0x81, 0x79, 0x51, 0x99, + 0xEC, 0x8A, 0xCB, 0x6B, 0x60, 0x51, 0x13, 0xBC, 0x4D, 0x6D, 0x06, 0xFC, + 0xB0, 0x08, 0x8D, 0xDD, 0x19, 0x10, 0x6A, 0xC7, 0x26, 0x0C, 0x35, 0xD8, + 0xC0, 0x6F, 0x20, 0x84, 0xE9, 0x94, 0xB1, 0x9B, 0x85, 0x03, 0xC3, 0x5B, + 0xDB, 0x4A, 0xE8, 0xC8, 0xF8, 0x90, 0x76, 0xD9, 0x5B, 0x4F, 0xE3, 0x4C, + 0xE8, 0x06, 0x36, 0x4D, 0xCC, 0x9A, 0xAC, 0x3D, 0x0C, 0x90, 0x2B, 0x92, + 0xD4, 0x06, 0x19, 0x60, 0xAC, 0x37, 0x44, 0x79, 0x85, 0x81, 0x82, 0xAD, + 0x5A, 0x37, 0xE0, 0x0D, 0xCC, 0x9D, 0xA6, 0x4C, 0x52, 0x76, 0xEA, 0x43, + 0x9D, 0xB7, 0x04, 0xD1, 0x50, 0xF6, 0x55, 0xE0, 0xD5, 0xD2, 0xA6, 0x49, + 0x85, 0xE9, 0x37, 0xE9, 0xCA, 0x7E, 0xAE, 0x5C, 0x95, 0x4D, 0x48, 0x9A, + 0x3F, 0xAE, 0x20, 0x5A, 0x6D, 0x88, 0x95, 0xD9, 0x34, 0xB8, 0x52, 0x1A, + 0x43, 0x90, 0xB0, 0xBF, 0x6C, 0x05, 0xB9, 0xB6, 0x78, 0xB7, 0xEA, 0xD0, + 0xE4, 0x3A, 0x3C, 0x12, 0x53, 0x62, 0xFF, 0x4A, 0xF2, 0x7B, 0xBE, 0x35, + 0x05, 0xA9, 0x12, 0x34, 0xE3, 0xF3, 0x64, 0x74, 0x62, 0x2C, 0x3D, 0x00, + 0x49, 0x5A, 0x28, 0xFE, 0x32, 0x44, 0xBB, 0x87, 0xDD, 0x65, 0x27, 0x02, + 0x71, 0x3B, 0xDA, 0x4A, 0xF7, 0x1F, 0xDA, 0xCD, 0xF7, 0x21, 0x55, 0x90, + 0x4F, 0x0F, 0xEC, 0xAE, 0x82, 0xE1, 0x9F, 0x6B, 0xD9, 0x45, 0xD3, 0xBB, + 0xF0, 0x5F, 0x87, 0xED, 0x3C, 0x2C, 0x39, 0x86, 0xDA, 0x3F, 0xDE, 0xEC, + 0x72, 0x55, 0xEB, 0x79, 0xA3, 0xAD, 0xDB, 0xDD, 0x7C, 0xB0, 0xBA, 0x1C, + 0xCE, 0xFC, 0xDE, 0x4F, 0x35, 0x76, 0xCF, 0x0F, 0xF8, 0x78, 0x1F, 0x6A, + 0x36, 0x51, 0x46, 0x27, 0x61, 0x5B, 0xE9, 0x9E, 0xCF, 0xF0, 0xA2, 0x55, + 0x7D, 0x7C, 0x25, 0x8A, 0x6F, 0x2F, 0xB4, 0xC5, 0xCF, 0x84, 0x2E, 0x2B, + 0xFD, 0x0D, 0x51, 0x10, 0x6C, 0xFB, 0x5F, 0x1B, 0xBC, 0x1B, 0x7E, 0xC5, + 0xAE, 0x3B, 0x98, 0x01, 0x31, 0x92, 0xFF, 0x0B, 0x57, 0xF4, 0x9A, 0xB2, + 0xB9, 0x57, 0xE9, 0xAB, 0xEF, 0x0D, 0x76, 0xD1, 0xF0, 0xEE, 0xF4, 0xCE, + 0x86, 0xA7, 0xE0, 0x6E, 0xE9, 0xB4, 0x69, 0xA1, 0xDF, 0x69, 0xF6, 0x33, + 0xC6, 0x69, 0x2E, 0x97, 0x13, 0x9E, 0xA5, 0x87, 0xB0, 0x57, 0x10, 0x81, + 0x37, 0xC9, 0x53, 0xB3, 0xBB, 0x7F, 0xF6, 0x92, 0xD1, 0x9C, 0xD0, 0x18, + 0xF4, 0x92, 0x6E, 0xDA, 0x83, 0x4F, 0xA6, 0x63, 0x99, 0x4C, 0xA5, 0xFB, + 0x5E, 0xEF, 0x21, 0x64, 0x7A, 0x20, 0x5F, 0x6C, 0x64, 0x85, 0x15, 0xCB, + 0x37, 0xE9, 0x62, 0x0C, 0x0B, 0x2A, 0x16, 0xDC, 0x01, 0x2E, 0x32, 0xDA, + 0x3E, 0x4B, 0xF5, 0x9E, 0x3A, 0xF6, 0x17, 0x40, 0x94, 0xEF, 0x9E, 0x91, + 0x08, 0x86, 0xFA, 0xBE, 0x63, 0xA8, 0x5A, 0x33, 0xEC, 0xCB, 0x74, 0x43, + 0x95, 0xF9, 0x6C, 0x69, 0x52, 0x36, 0xC7, 0x29, 0x6F, 0xFC, 0x55, 0x03, + 0x5C, 0x1F, 0xFB, 0x9F, 0xBD, 0x47, 0xEB, 0xE7, 0x49, 0x47, 0x95, 0x0B, + 0x4E, 0x89, 0x22, 0x09, 0x49, 0xE0, 0xF5, 0x61, 0x1E, 0xF1, 0xBF, 0x2E, + 0x8A, 0x72, 0x6E, 0x80, 0x59, 0xFF, 0x57, 0x3A, 0xF9, 0x75, 0x32, 0xA3, + 0x4E, 0x5F, 0xEC, 0xED, 0x28, 0x62, 0xD9, 0x4D, 0x73, 0xF2, 0xCC, 0x81, + 0x17, 0x60, 0xED, 0xCD, 0xEB, 0xDC, 0xDB, 0xA7, 0xCA, 0xC5, 0x7E, 0x02, + 0xBD, 0xF2, 0x54, 0x08, 0x54, 0xFD, 0xB4, 0x2D, 0x09, 0x2C, 0x17, 0x54, + 0x4A, 0x98, 0xD1, 0x54, 0xE1, 0x51, 0x67, 0x08, 0xD2, 0xED, 0x6E, 0x7E, + 0x6F, 0x3F, 0xD2, 0x2D, 0x81, 0x59, 0x29, 0x66, 0xCB, 0x90, 0x39, 0x95, + 0x11, 0x1E, 0x74, 0x27, 0xFE, 0xDD, 0xEB, 0xAF +}; + +static const unsigned char TA657_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA658_DN[] = { + 0x30, 0x4C, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, + 0x25, 0x41, 0x74, 0x6F, 0x73, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x20, 0x45, 0x43, 0x43, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x32, 0x30, + 0x32, 0x31, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x04, 0x41, 0x74, 0x6F, 0x73, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x44, 0x45 +}; + +static const unsigned char TA658_EC_Q[] = { + 0x04, 0x96, 0x86, 0x58, 0x28, 0x37, 0x0A, 0x67, 0xD0, 0xA0, 0xDE, 0x24, + 0x19, 0x19, 0xE1, 0xE4, 0x05, 0x07, 0x1F, 0x97, 0xED, 0xE8, 0x64, 0x82, + 0xB9, 0xF6, 0xC4, 0x71, 0x50, 0xCE, 0x8A, 0x0C, 0xFF, 0xD7, 0xB5, 0x76, + 0xBB, 0xA1, 0x6C, 0x93, 0x6C, 0x83, 0xA2, 0x68, 0x6E, 0xA5, 0xD9, 0xBE, + 0x2C, 0x88, 0x95, 0x41, 0xCD, 0x5D, 0xDD, 0xB1, 0xCA, 0x83, 0x63, 0x83, + 0xCC, 0xC0, 0xBE, 0x74, 0xD9, 0xE0, 0x9D, 0xA4, 0xEE, 0x4A, 0x4E, 0x56, + 0xE0, 0x98, 0x29, 0x41, 0x93, 0x52, 0x10, 0xD5, 0x24, 0x38, 0x02, 0x32, + 0x67, 0xF1, 0x94, 0x12, 0x6F, 0xEF, 0xD7, 0xC5, 0xDE, 0x2E, 0xFD, 0x19, + 0x80 +}; + +static const unsigned char TA659_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA659_RSA_N[] = { + 0x80, 0x12, 0x65, 0x17, 0x36, 0x0E, 0xC3, 0xDB, 0x08, 0xB3, 0xD0, 0xAC, + 0x57, 0x0D, 0x76, 0xED, 0xCD, 0x27, 0xD3, 0x4C, 0xAD, 0x50, 0x83, 0x61, + 0xE2, 0xAA, 0x20, 0x4D, 0x09, 0x2D, 0x64, 0x09, 0xDC, 0xCE, 0x89, 0x9F, + 0xCC, 0x3D, 0xA9, 0xEC, 0xF6, 0xCF, 0xC1, 0xDC, 0xF1, 0xD3, 0xB1, 0xD6, + 0x7B, 0x37, 0x28, 0x11, 0x2B, 0x47, 0xDA, 0x39, 0xC6, 0xBC, 0x3A, 0x19, + 0xB4, 0x5F, 0xA6, 0xBD, 0x7D, 0x9D, 0xA3, 0x63, 0x42, 0xB6, 0x76, 0xF2, + 0xA9, 0x3B, 0x2B, 0x91, 0xF8, 0xE2, 0x6F, 0xD0, 0xEC, 0x16, 0x20, 0x90, + 0x09, 0x3E, 0xE2, 0xE8, 0x74, 0xC9, 0x18, 0xB4, 0x91, 0xD4, 0x62, 0x64, + 0xDB, 0x7F, 0xA3, 0x06, 0xF1, 0x88, 0x18, 0x6A, 0x90, 0x22, 0x3C, 0xBC, + 0xFE, 0x13, 0xF0, 0x87, 0x14, 0x7B, 0xF6, 0xE4, 0x1F, 0x8E, 0xD4, 0xE4, + 0x51, 0xC6, 0x11, 0x67, 0x46, 0x08, 0x51, 0xCB, 0x86, 0x14, 0x54, 0x3F, + 0xBC, 0x33, 0xFE, 0x7E, 0x6C, 0x9C, 0xFF, 0x16, 0x9D, 0x18, 0xBD, 0x51, + 0x8E, 0x35, 0xA6, 0xA7, 0x66, 0xC8, 0x72, 0x67, 0xDB, 0x21, 0x66, 0xB1, + 0xD4, 0x9B, 0x78, 0x03, 0xC0, 0x50, 0x3A, 0xE8, 0xCC, 0xF0, 0xDC, 0xBC, + 0x9E, 0x4C, 0xFE, 0xAF, 0x05, 0x96, 0x35, 0x1F, 0x57, 0x5A, 0xB7, 0xFF, + 0xCE, 0xF9, 0x3D, 0xB7, 0x2C, 0xB6, 0xF6, 0x54, 0xDD, 0xC8, 0xE7, 0x12, + 0x3A, 0x4D, 0xAE, 0x4C, 0x8A, 0xB7, 0x5C, 0x9A, 0xB4, 0xB7, 0x20, 0x3D, + 0xCA, 0x7F, 0x22, 0x34, 0xAE, 0x7E, 0x3B, 0x68, 0x66, 0x01, 0x44, 0xE7, + 0x01, 0x4E, 0x46, 0x53, 0x9B, 0x33, 0x60, 0xF7, 0x94, 0xBE, 0x53, 0x37, + 0x90, 0x73, 0x43, 0xF3, 0x32, 0xC3, 0x53, 0xEF, 0xDB, 0xAA, 0xFE, 0x74, + 0x4E, 0x69, 0xC7, 0x6B, 0x8C, 0x60, 0x93, 0xDE, 0xC4, 0xC7, 0x0C, 0xDF, + 0xE1, 0x32, 0xAE, 0xCC, 0x93, 0x3B, 0x51, 0x78, 0x95, 0x67, 0x8B, 0xEE, + 0x3D, 0x56, 0xFE, 0x0C, 0xD0, 0x69, 0x0F, 0x1B, 0x0F, 0xF3, 0x25, 0x26, + 0x6B, 0x33, 0x6D, 0xF7, 0x6E, 0x47, 0xFA, 0x73, 0x43, 0xE5, 0x7E, 0x0E, + 0xA5, 0x66, 0xB1, 0x29, 0x7C, 0x32, 0x84, 0x63, 0x55, 0x89, 0xC4, 0x0D, + 0xC1, 0x93, 0x54, 0x30, 0x19, 0x13, 0xAC, 0xD3, 0x7D, 0x37, 0xA7, 0xEB, + 0x5D, 0x3A, 0x6C, 0x35, 0x5C, 0xDB, 0x41, 0xD7, 0x12, 0xDA, 0xA9, 0x49, + 0x0B, 0xDF, 0xD8, 0x80, 0x8A, 0x09, 0x93, 0x62, 0x8E, 0xB5, 0x66, 0xCF, + 0x25, 0x88, 0xCD, 0x84, 0xB8, 0xB1, 0x3F, 0xA4, 0x39, 0x0F, 0xD9, 0x02, + 0x9E, 0xEB, 0x12, 0x4C, 0x95, 0x7C, 0xF3, 0x6B, 0x05, 0xA9, 0x5E, 0x16, + 0x83, 0xCC, 0xB8, 0x67, 0xE2, 0xE8, 0x13, 0x9D, 0xCC, 0x5B, 0x82, 0xD3, + 0x4C, 0xB3, 0xED, 0x5B, 0xFF, 0xDE, 0xE5, 0x73, 0xAC, 0x23, 0x3B, 0x2D, + 0x00, 0xBF, 0x35, 0x55, 0x74, 0x09, 0x49, 0xD8, 0x49, 0x58, 0x1A, 0x7F, + 0x92, 0x36, 0xE6, 0x51, 0x92, 0x0E, 0xF3, 0x26, 0x7D, 0x1C, 0x4D, 0x17, + 0xBC, 0xC9, 0xEC, 0x43, 0x26, 0xD0, 0xBF, 0x41, 0x5F, 0x40, 0xA9, 0x44, + 0x44, 0xF4, 0x99, 0xE7, 0x57, 0x87, 0x9E, 0x50, 0x1F, 0x57, 0x54, 0xA8, + 0x3E, 0xFD, 0x74, 0x63, 0x2F, 0xB1, 0x50, 0x65, 0x09, 0xE6, 0x58, 0x42, + 0x2E, 0x43, 0x1A, 0x4C, 0xB4, 0xF0, 0x25, 0x47, 0x59, 0xFA, 0x04, 0x1E, + 0x93, 0xD4, 0x26, 0x46, 0x4A, 0x50, 0x81, 0xB2, 0xDE, 0xBE, 0x78, 0xB7, + 0xFC, 0x67, 0x15, 0xE1, 0xC9, 0x57, 0x84, 0x1E, 0x0F, 0x63, 0xD6, 0xE9, + 0x62, 0xBA, 0xD6, 0x5F, 0x55, 0x2E, 0xEA, 0x5C, 0xC6, 0x28, 0x08, 0x04, + 0x25, 0x39, 0xB8, 0x0E, 0x2B, 0xA9, 0xF2, 0x4C, 0x97, 0x1C, 0x07, 0x3F, + 0x0D, 0x52, 0xF5, 0xED, 0xEF, 0x2F, 0x82, 0x0F +}; + +static const unsigned char TA659_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA660_DN[] = { + 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6D, 0x61, 0x7A, 0x6F, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA660_RSA_N[] = { + 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80, + 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7, + 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86, + 0xD3, 0xA0, 0x43, 0x7A, 0x4E, 0xB2, 0xA4, 0xD0, 0x36, 0xBA, 0x01, 0xBE, + 0x8D, 0xDB, 0x48, 0xC8, 0x07, 0x17, 0x36, 0x4C, 0xF4, 0xEE, 0x88, 0x23, + 0xC7, 0x3E, 0xEB, 0x37, 0xF5, 0xB5, 0x19, 0xF8, 0x49, 0x68, 0xB0, 0xDE, + 0xD7, 0xB9, 0x76, 0x38, 0x1D, 0x61, 0x9E, 0xA4, 0xFE, 0x82, 0x36, 0xA5, + 0xE5, 0x4A, 0x56, 0xE4, 0x45, 0xE1, 0xF9, 0xFD, 0xB4, 0x16, 0xFA, 0x74, + 0xDA, 0x9C, 0x9B, 0x35, 0x39, 0x2F, 0xFA, 0xB0, 0x20, 0x50, 0x06, 0x6C, + 0x7A, 0xD0, 0x80, 0xB2, 0xA6, 0xF9, 0xAF, 0xEC, 0x47, 0x19, 0x8F, 0x50, + 0x38, 0x07, 0xDC, 0xA2, 0x87, 0x39, 0x58, 0xF8, 0xBA, 0xD5, 0xA9, 0xF9, + 0x48, 0x67, 0x30, 0x96, 0xEE, 0x94, 0x78, 0x5E, 0x6F, 0x89, 0xA3, 0x51, + 0xC0, 0x30, 0x86, 0x66, 0xA1, 0x45, 0x66, 0xBA, 0x54, 0xEB, 0xA3, 0xC3, + 0x91, 0xF9, 0x48, 0xDC, 0xFF, 0xD1, 0xE8, 0x30, 0x2D, 0x7D, 0x2D, 0x74, + 0x70, 0x35, 0xD7, 0x88, 0x24, 0xF7, 0x9E, 0xC4, 0x59, 0x6E, 0xBB, 0x73, + 0x87, 0x17, 0xF2, 0x32, 0x46, 0x28, 0xB8, 0x43, 0xFA, 0xB7, 0x1D, 0xAA, + 0xCA, 0xB4, 0xF2, 0x9F, 0x24, 0x0E, 0x2D, 0x4B, 0xF7, 0x71, 0x5C, 0x5E, + 0x69, 0xFF, 0xEA, 0x95, 0x02, 0xCB, 0x38, 0x8A, 0xAE, 0x50, 0x38, 0x6F, + 0xDB, 0xFB, 0x2D, 0x62, 0x1B, 0xC5, 0xC7, 0x1E, 0x54, 0xE1, 0x77, 0xE0, + 0x67, 0xC8, 0x0F, 0x9C, 0x87, 0x23, 0xD6, 0x3F, 0x40, 0x20, 0x7F, 0x20, + 0x80, 0xC4, 0x80, 0x4C, 0x3E, 0x3B, 0x24, 0x26, 0x8E, 0x04, 0xAE, 0x6C, + 0x9A, 0xC8, 0xAA, 0x0D +}; + +static const unsigned char TA660_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA661_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x4E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4E, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x65, 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x71, 0x75, 0x65, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, + 0x75, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA661_RSA_N[] = { + 0xC3, 0xCD, 0xD3, 0xFC, 0xBD, 0x04, 0x53, 0xDD, 0x0C, 0x20, 0x3A, 0xD5, + 0x88, 0x2E, 0x05, 0x4B, 0x41, 0xF5, 0x83, 0x82, 0x7E, 0xF7, 0x59, 0x9F, + 0x9E, 0x9E, 0x63, 0xE8, 0x73, 0xDA, 0xF6, 0x06, 0xA9, 0x4F, 0x1F, 0xB4, + 0xF9, 0x0B, 0x1F, 0x39, 0x8C, 0x9A, 0x20, 0xD0, 0x7E, 0x06, 0xD4, 0xEC, + 0x34, 0xD9, 0x86, 0xBC, 0x75, 0x5B, 0x87, 0x88, 0xF0, 0xD2, 0xD9, 0xD4, + 0xA3, 0x0A, 0xB2, 0x6C, 0x1B, 0xEB, 0x49, 0x2C, 0x3E, 0xAC, 0x5D, 0xD8, + 0x94, 0x03, 0xA0, 0xEC, 0x34, 0xE5, 0x30, 0xC4, 0x35, 0x7D, 0xFB, 0x26, + 0x4D, 0x1B, 0x6E, 0x30, 0x54, 0xD8, 0xF5, 0x80, 0x45, 0x9C, 0x39, 0xAD, + 0x9C, 0xC9, 0x25, 0x04, 0x4D, 0x9A, 0x90, 0x3E, 0x4E, 0x40, 0x6E, 0x8A, + 0x6B, 0xCD, 0x29, 0x67, 0xC6, 0xCC, 0x2D, 0xE0, 0x74, 0xE8, 0x05, 0x57, + 0x0A, 0x48, 0x50, 0xFA, 0x7A, 0x43, 0xDA, 0x7E, 0xEC, 0x5B, 0x9A, 0x0E, + 0x62, 0x76, 0xFE, 0xEA, 0x9D, 0x1D, 0x85, 0x72, 0xEC, 0x11, 0xBB, 0x35, + 0xE8, 0x1F, 0x27, 0xBF, 0xC1, 0xA1, 0xC7, 0xBB, 0x48, 0x16, 0xDD, 0x56, + 0xD7, 0xCC, 0x4E, 0xA0, 0xE1, 0xB9, 0xAC, 0xDB, 0xD5, 0x83, 0x19, 0x1A, + 0x85, 0xD1, 0x94, 0x97, 0xD7, 0xCA, 0xA3, 0x65, 0x0B, 0xF3, 0x38, 0xF9, + 0x02, 0xAE, 0xDD, 0xF6, 0x67, 0xCF, 0xC9, 0x3F, 0xF5, 0x8A, 0x2C, 0x47, + 0x1A, 0x99, 0x6F, 0x05, 0x0D, 0xFD, 0xD0, 0x1D, 0x82, 0x31, 0xFC, 0x29, + 0xCC, 0x00, 0x58, 0x97, 0x91, 0x4C, 0x80, 0x00, 0x1C, 0x33, 0x85, 0x96, + 0x2F, 0xCB, 0x41, 0xC2, 0x8B, 0x10, 0x84, 0xC3, 0x09, 0x24, 0x89, 0x1F, + 0xB5, 0x0F, 0xD9, 0xD9, 0x77, 0x47, 0x18, 0x92, 0x94, 0x60, 0x5C, 0xC7, + 0x99, 0x03, 0x3C, 0xFE, 0xF7, 0x95, 0xA7, 0x7D, 0x50, 0xA1, 0x80, 0xC2, + 0xA9, 0x83, 0xAD, 0x58, 0x96, 0x55, 0x21, 0xDB, 0x86, 0x59, 0xD4, 0xAF, + 0xC6, 0xBC, 0xDD, 0x81, 0x6E, 0x07, 0xDB, 0x60, 0x62, 0xFE, 0xEC, 0x10, + 0x6E, 0xDA, 0x68, 0x01, 0xF4, 0x83, 0x1B, 0xA9, 0x3E, 0xA2, 0x5B, 0x23, + 0xD7, 0x64, 0xC6, 0xDF, 0xDC, 0xA2, 0x7D, 0xD8, 0x4B, 0xBA, 0x82, 0xD2, + 0x51, 0xF8, 0x66, 0xBF, 0x06, 0x46, 0xE4, 0x79, 0x2A, 0x26, 0x36, 0x79, + 0x8F, 0x1F, 0x4E, 0x99, 0x1D, 0xB2, 0x8F, 0x0C, 0x0E, 0x1C, 0xFF, 0xC9, + 0x5D, 0xC0, 0xFD, 0x90, 0x10, 0xA6, 0xB1, 0x37, 0xF3, 0xCD, 0x3A, 0x24, + 0x6E, 0xB4, 0x85, 0x90, 0xBF, 0x80, 0xB9, 0x0C, 0x8C, 0xD5, 0x9B, 0xD6, + 0xC8, 0xF1, 0x56, 0x3F, 0x1A, 0x80, 0x89, 0x7A, 0xA9, 0xE2, 0x1B, 0x32, + 0x51, 0x2C, 0x3E, 0xF2, 0xDF, 0x7B, 0xF6, 0x5D, 0x7A, 0x29, 0x19, 0x8E, + 0xE5, 0xC8, 0xBD, 0x36, 0x71, 0x8B, 0x5D, 0x4C, 0xC2, 0x1D, 0x3F, 0xAD, + 0x58, 0xA2, 0xCF, 0x3D, 0x70, 0x4D, 0xA6, 0x50, 0x98, 0x25, 0xDC, 0x23, + 0xF9, 0xB8, 0x58, 0x41, 0x08, 0x71, 0xBF, 0x4F, 0xB8, 0x84, 0xA0, 0x8F, + 0x00, 0x54, 0x15, 0xFC, 0x91, 0x6D, 0x58, 0xA7, 0x96, 0x3B, 0xEB, 0x4B, + 0x96, 0x27, 0xCD, 0x6B, 0xA2, 0xA1, 0x86, 0xAC, 0x0D, 0x7C, 0x54, 0xE6, + 0x66, 0x4C, 0x66, 0x5F, 0x90, 0xBE, 0x21, 0x9A, 0x02, 0x46, 0x2D, 0xE4, + 0x83, 0xC2, 0x80, 0xB9, 0xCF, 0x4B, 0x3E, 0xE8, 0x7F, 0x3C, 0x01, 0xEC, + 0x8F, 0x5E, 0xCD, 0x7F, 0xD2, 0x28, 0x42, 0x01, 0x95, 0x8A, 0xE2, 0x97, + 0x3D, 0x10, 0x21, 0x7D, 0xF6, 0x9D, 0x1C, 0xC5, 0x34, 0xA1, 0xEC, 0x2C, + 0x0E, 0x0A, 0x52, 0x2C, 0x12, 0x55, 0x70, 0x24, 0x3D, 0xCB, 0xC2, 0x14, + 0x35, 0x43, 0x5D, 0x27, 0x4E, 0xBE, 0xC0, 0xBD, 0xAA, 0x7C, 0x96, 0xE7, + 0xFC, 0x9E, 0x61, 0xAD, 0x44, 0xD3, 0x00, 0x97 +}; + +static const unsigned char TA661_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA662_DN[] = { + 0x30, 0x34, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x44, 0x68, 0x69, 0x6D, 0x79, 0x6F, 0x74, 0x69, 0x73, 0x31, + 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x08, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x67, 0x6E, 0x61 +}; + +static const unsigned char TA662_RSA_N[] = { + 0xC8, 0x68, 0xF1, 0xC9, 0xD6, 0xD6, 0xB3, 0x34, 0x75, 0x26, 0x82, 0x1E, + 0xEC, 0xB4, 0xBE, 0xEA, 0x5C, 0xE1, 0x26, 0xED, 0x11, 0x47, 0x61, 0xE1, + 0xA2, 0x7C, 0x16, 0x78, 0x40, 0x21, 0xE4, 0x60, 0x9E, 0x5A, 0xC8, 0x63, + 0xE1, 0xC4, 0xB1, 0x96, 0x92, 0xFF, 0x18, 0x6D, 0x69, 0x23, 0xE1, 0x2B, + 0x62, 0xF7, 0xDD, 0xE2, 0x36, 0x2F, 0x91, 0x07, 0xB9, 0x48, 0xCF, 0x0E, + 0xEC, 0x79, 0xB6, 0x2C, 0xE7, 0x34, 0x4B, 0x70, 0x08, 0x25, 0xA3, 0x3C, + 0x87, 0x1B, 0x19, 0xF2, 0x81, 0x07, 0x0F, 0x38, 0x90, 0x19, 0xD3, 0x11, + 0xFE, 0x86, 0xB4, 0xF2, 0xD1, 0x5E, 0x1E, 0x1E, 0x96, 0xCD, 0x80, 0x6C, + 0xCE, 0x3B, 0x31, 0x93, 0xB6, 0xF2, 0xA0, 0xD0, 0xA9, 0x95, 0x12, 0x7D, + 0xA5, 0x9A, 0xCC, 0x6B, 0xC8, 0x84, 0x56, 0x8A, 0x33, 0xA9, 0xE7, 0x22, + 0x15, 0x53, 0x16, 0xF0, 0xCC, 0x17, 0xEC, 0x57, 0x5F, 0xE9, 0xA2, 0x0A, + 0x98, 0x09, 0xDE, 0xE3, 0x5F, 0x9C, 0x6F, 0xDC, 0x48, 0xE3, 0x85, 0x0B, + 0x15, 0x5A, 0xA6, 0xBA, 0x9F, 0xAC, 0x48, 0xE3, 0x09, 0xB2, 0xF7, 0xF4, + 0x32, 0xDE, 0x5E, 0x34, 0xBE, 0x1C, 0x78, 0x5D, 0x42, 0x5B, 0xCE, 0x0E, + 0x22, 0x8F, 0x4D, 0x90, 0xD7, 0x7D, 0x32, 0x18, 0xB3, 0x0B, 0x2C, 0x6A, + 0xBF, 0x8E, 0x3F, 0x14, 0x11, 0x89, 0x20, 0x0E, 0x77, 0x14, 0xB5, 0x3D, + 0x94, 0x08, 0x87, 0xF7, 0x25, 0x1E, 0xD5, 0xB2, 0x60, 0x00, 0xEC, 0x6F, + 0x2A, 0x28, 0x25, 0x6E, 0x2A, 0x3E, 0x18, 0x63, 0x17, 0x25, 0x3F, 0x3E, + 0x44, 0x20, 0x16, 0xF6, 0x26, 0xC8, 0x25, 0xAE, 0x05, 0x4A, 0xB4, 0xE7, + 0x63, 0x2C, 0xF3, 0x8C, 0x16, 0x53, 0x7E, 0x5C, 0xFB, 0x11, 0x1A, 0x08, + 0xC1, 0x46, 0x62, 0x9F, 0x22, 0xB8, 0xF1, 0xC2, 0x8D, 0x69, 0xDC, 0xFA, + 0x3A, 0x58, 0x06, 0xDF +}; + +static const unsigned char TA662_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA663_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1F, 0x4B, 0x72, 0x61, 0x6A, 0x6F, 0x77, 0x61, 0x20, 0x49, 0x7A, + 0x62, 0x61, 0x20, 0x52, 0x6F, 0x7A, 0x6C, 0x69, 0x63, 0x7A, 0x65, 0x6E, + 0x69, 0x6F, 0x77, 0x61, 0x20, 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x53, 0x5A, 0x41, 0x46, + 0x49, 0x52, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA663_RSA_N[] = { + 0xB7, 0xBC, 0x3E, 0x50, 0xA8, 0x4B, 0xCD, 0x40, 0xB5, 0xCE, 0x61, 0xE7, + 0x96, 0xCA, 0xB4, 0xA1, 0xDA, 0x0C, 0x22, 0xB0, 0xFA, 0xB5, 0x7B, 0x76, + 0x00, 0x77, 0x8C, 0x0B, 0xCF, 0x7D, 0xA8, 0x86, 0xCC, 0x26, 0x51, 0xE4, + 0x20, 0x3D, 0x85, 0x0C, 0xD6, 0x58, 0xE3, 0xE7, 0xF4, 0x2A, 0x18, 0x9D, + 0xDA, 0xD1, 0xAE, 0x26, 0xEE, 0xEB, 0x53, 0xDC, 0xF4, 0x90, 0xD6, 0x13, + 0x4A, 0x0C, 0x90, 0x3C, 0xC3, 0xF4, 0xDA, 0xD2, 0x8E, 0x0D, 0x92, 0x3A, + 0xDC, 0xB1, 0xB1, 0xFF, 0x38, 0xDE, 0xC3, 0xBA, 0x2D, 0x5F, 0x80, 0xB9, + 0x02, 0xBD, 0x4A, 0x9D, 0x1B, 0x0F, 0xB4, 0xC3, 0xC2, 0xC1, 0x67, 0x03, + 0xDD, 0xDC, 0x1B, 0x9C, 0x3D, 0xB3, 0xB0, 0xDE, 0x00, 0x1E, 0xA8, 0x34, + 0x47, 0xBB, 0x9A, 0xEB, 0xFE, 0x0B, 0x14, 0xBD, 0x36, 0x84, 0xDA, 0x0D, + 0x20, 0xBF, 0xFA, 0x5B, 0xCB, 0xA9, 0x16, 0x20, 0xAD, 0x39, 0x60, 0xEE, + 0x2F, 0x75, 0xB6, 0xE7, 0x97, 0x9C, 0xF9, 0x3E, 0xFD, 0x7E, 0x4D, 0x6F, + 0x4D, 0x2F, 0xEF, 0x88, 0x0D, 0x6A, 0xFA, 0xDD, 0xF1, 0x3D, 0x6E, 0x20, + 0xA5, 0xA0, 0x12, 0xB4, 0x4D, 0x70, 0xB9, 0xCE, 0xD7, 0x72, 0x3B, 0x89, + 0x93, 0xA7, 0x80, 0x84, 0x1C, 0x27, 0x49, 0x72, 0x49, 0xB5, 0xFF, 0x3B, + 0x95, 0x9E, 0xC1, 0xCC, 0xC8, 0x01, 0xEC, 0xE8, 0x0E, 0x8A, 0x0A, 0x96, + 0xE7, 0xB3, 0xA6, 0x87, 0xE5, 0xD6, 0xF9, 0x05, 0x2B, 0x0D, 0x97, 0x40, + 0x70, 0x3C, 0xBA, 0xAC, 0x75, 0x5A, 0x9C, 0xD5, 0x4D, 0x9D, 0x02, 0x0A, + 0xD2, 0x4B, 0x9B, 0x66, 0x4B, 0x46, 0x07, 0x17, 0x65, 0xAD, 0x9F, 0x6C, + 0x88, 0x00, 0xDC, 0x22, 0x89, 0xE0, 0xE1, 0x64, 0xD4, 0x67, 0xBC, 0x31, + 0x79, 0x61, 0x3C, 0xBB, 0xCA, 0x41, 0xCD, 0x5C, 0x6A, 0x00, 0xC8, 0x3C, + 0x38, 0x8E, 0x58, 0xAF +}; + +static const unsigned char TA663_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA664_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, 0x36 +}; + +static const unsigned char TA664_EC_Q[] = { + 0x04, 0x9C, 0x0E, 0xB1, 0xCF, 0xB7, 0xE8, 0x9E, 0x52, 0x77, 0x75, 0x34, + 0xFA, 0xA5, 0x46, 0xA7, 0xAD, 0x32, 0x19, 0x32, 0xB4, 0x07, 0xA9, 0x27, + 0xCA, 0x94, 0xBB, 0x0C, 0xD2, 0x0A, 0x10, 0xC7, 0xDA, 0x89, 0xB0, 0x97, + 0x0C, 0x70, 0x13, 0x09, 0x01, 0x8E, 0xD8, 0xEA, 0x47, 0xEA, 0xBE, 0xB2, + 0x80, 0x2B, 0xCD, 0xFC, 0x28, 0x0D, 0xDB, 0xAC, 0xBC, 0xA4, 0x86, 0x37, + 0xED, 0x70, 0x08, 0x00, 0x75, 0xEA, 0x93, 0x0B, 0x7B, 0x2E, 0x52, 0x9C, + 0x23, 0x68, 0x23, 0x06, 0x43, 0xEC, 0x92, 0x2F, 0x53, 0x84, 0xDB, 0xFB, + 0x47, 0x14, 0x07, 0xE8, 0x5F, 0x94, 0x67, 0x5D, 0xC9, 0x7A, 0x81, 0x3C, + 0x20 +}; + +static const unsigned char TA665_DN[] = { + 0x30, 0x81, 0xD2, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x54, 0x52, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x0F, 0x47, 0x65, 0x62, 0x7A, 0x65, 0x20, 0x2D, 0x20, 0x4B, + 0x6F, 0x63, 0x61, 0x65, 0x6C, 0x69, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x13, 0x39, 0x54, 0x75, 0x72, 0x6B, 0x69, 0x79, 0x65, + 0x20, 0x42, 0x69, 0x6C, 0x69, 0x6D, 0x73, 0x65, 0x6C, 0x20, 0x76, 0x65, + 0x20, 0x54, 0x65, 0x6B, 0x6E, 0x6F, 0x6C, 0x6F, 0x6A, 0x69, 0x6B, 0x20, + 0x41, 0x72, 0x61, 0x73, 0x74, 0x69, 0x72, 0x6D, 0x61, 0x20, 0x4B, 0x75, + 0x72, 0x75, 0x6D, 0x75, 0x20, 0x2D, 0x20, 0x54, 0x55, 0x42, 0x49, 0x54, + 0x41, 0x4B, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x24, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x6B, 0x61, 0x73, 0x79, 0x6F, 0x6E, 0x20, 0x4D, 0x65, 0x72, 0x6B, + 0x65, 0x7A, 0x69, 0x20, 0x2D, 0x20, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, + 0x4D, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, + 0x54, 0x55, 0x42, 0x49, 0x54, 0x41, 0x4B, 0x20, 0x4B, 0x61, 0x6D, 0x75, + 0x20, 0x53, 0x4D, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x4B, 0x6F, 0x6B, 0x20, + 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6B, 0x61, 0x73, 0x69, 0x20, + 0x2D, 0x20, 0x53, 0x75, 0x72, 0x75, 0x6D, 0x20, 0x31 +}; + +static const unsigned char TA665_RSA_N[] = { + 0xAF, 0x75, 0x30, 0x33, 0xAA, 0xBB, 0x6B, 0xD3, 0x99, 0x2C, 0x12, 0x37, + 0x84, 0xD9, 0x8D, 0x7B, 0x97, 0x80, 0xD3, 0x6E, 0xE7, 0xFF, 0x9B, 0x50, + 0x95, 0x3E, 0x90, 0x95, 0x56, 0x42, 0xD7, 0x19, 0x7C, 0x26, 0x84, 0x8D, + 0x92, 0xFA, 0x01, 0x1D, 0x3A, 0x0F, 0xE2, 0x64, 0x38, 0xB7, 0x8C, 0xBC, + 0xE8, 0x88, 0xF9, 0x8B, 0x24, 0xAB, 0x2E, 0xA3, 0xF5, 0x37, 0xE4, 0x40, + 0x8E, 0x18, 0x25, 0x79, 0x83, 0x75, 0x1F, 0x3B, 0xFF, 0x6C, 0xA8, 0xC5, + 0xC6, 0x56, 0xF8, 0xB4, 0xED, 0x8A, 0x44, 0xA3, 0xAB, 0x6C, 0x4C, 0xFC, + 0x1D, 0xD0, 0xDC, 0xEF, 0x68, 0xBD, 0xCF, 0xE4, 0xAA, 0xCE, 0xF0, 0x55, + 0xF7, 0xA2, 0x34, 0xD4, 0x83, 0x6B, 0x37, 0x7C, 0x1C, 0xC2, 0xFE, 0xB5, + 0x03, 0xEC, 0x57, 0xCE, 0xBC, 0xB4, 0xB5, 0xC5, 0xED, 0x00, 0x0F, 0x53, + 0x37, 0x2A, 0x4D, 0xF4, 0x4F, 0x0C, 0x83, 0xFB, 0x86, 0xCF, 0xCB, 0xFE, + 0x8C, 0x4E, 0xBD, 0x87, 0xF9, 0xA7, 0x8B, 0x21, 0x57, 0x9C, 0x7A, 0xDF, + 0x03, 0x67, 0x89, 0x2C, 0x9D, 0x97, 0x61, 0xA7, 0x10, 0xB8, 0x55, 0x90, + 0x7F, 0x0E, 0x2D, 0x27, 0x38, 0x74, 0xDF, 0xE7, 0xFD, 0xDA, 0x4E, 0x12, + 0xE3, 0x4D, 0x15, 0x22, 0x02, 0xC8, 0xE0, 0xE0, 0xFC, 0x0F, 0xAD, 0x8A, + 0xD7, 0xC9, 0x54, 0x50, 0xCC, 0x3B, 0x0F, 0xCA, 0x16, 0x80, 0x84, 0xD0, + 0x51, 0x56, 0xC3, 0x8E, 0x56, 0x7F, 0x89, 0x22, 0x33, 0x2F, 0xE6, 0x85, + 0x0A, 0xBD, 0xA5, 0xA8, 0x1B, 0x36, 0xDE, 0xD3, 0xDC, 0x2C, 0x6D, 0x3B, + 0xC7, 0x13, 0xBD, 0x59, 0x23, 0x2C, 0xE6, 0xE5, 0xA4, 0xF7, 0xD8, 0x0B, + 0xED, 0xEA, 0x90, 0x40, 0x44, 0xA8, 0x95, 0xBB, 0x93, 0xD5, 0xD0, 0x80, + 0x34, 0xB6, 0x46, 0x78, 0x0E, 0x1F, 0x00, 0x93, 0x46, 0xE1, 0xEE, 0xE9, + 0xF9, 0xEC, 0x4F, 0x17 +}; + +static const unsigned char TA665_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA666_DN[] = { + 0x30, 0x54, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x42, 0x45, 0x49, 0x4A, 0x49, 0x4E, 0x47, 0x20, 0x43, 0x45, + 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x41, 0x55, + 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x31, 0x1D, 0x30, 0x1B, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x14, 0x42, 0x4A, 0x43, 0x41, 0x20, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41, 0x31 +}; + +static const unsigned char TA666_RSA_N[] = { + 0xF1, 0x66, 0x08, 0xBD, 0xD9, 0xC5, 0x15, 0x61, 0xCB, 0x84, 0x04, 0x41, + 0xA5, 0x69, 0x37, 0x77, 0x1D, 0xC1, 0xB0, 0x7B, 0xFA, 0xC3, 0x77, 0x48, + 0x90, 0x13, 0x72, 0x64, 0xD1, 0xB8, 0x7C, 0x90, 0x35, 0x9D, 0x18, 0x79, + 0x88, 0xE3, 0x97, 0x01, 0x3C, 0x47, 0x81, 0xF2, 0x0E, 0xA2, 0x98, 0x0D, + 0x9E, 0x3F, 0x37, 0xE0, 0x19, 0xB2, 0x90, 0xF2, 0x46, 0x1C, 0x92, 0xB1, + 0x3A, 0x61, 0xCE, 0xFA, 0xB7, 0x46, 0x9E, 0x03, 0x86, 0xD7, 0x33, 0x6E, + 0xED, 0xF7, 0x45, 0x8C, 0x76, 0x37, 0xDE, 0x6E, 0x96, 0x91, 0xF7, 0xD7, + 0x7E, 0x2B, 0x87, 0x17, 0xD5, 0x8B, 0x35, 0xEE, 0x84, 0x91, 0x72, 0x57, + 0xDC, 0x60, 0xC3, 0xC3, 0xB9, 0xE7, 0xC7, 0x67, 0x24, 0x23, 0x4F, 0x63, + 0x0A, 0x63, 0xF6, 0x66, 0x7D, 0x4B, 0x55, 0xA7, 0x3F, 0x78, 0x64, 0x49, + 0x69, 0x12, 0x97, 0xE0, 0x4C, 0x0D, 0xD3, 0x09, 0xA0, 0x32, 0x30, 0x3A, + 0xFA, 0x9F, 0xC0, 0xF2, 0x9C, 0xC5, 0x12, 0x2A, 0x2E, 0x1C, 0xB5, 0x04, + 0x33, 0xDA, 0xA4, 0x38, 0x11, 0x6A, 0xDE, 0xC6, 0x18, 0xF6, 0x47, 0x3A, + 0x22, 0x41, 0x87, 0x22, 0xFC, 0xC4, 0x89, 0x28, 0x54, 0xD8, 0x8C, 0xA5, + 0x30, 0x0A, 0xF8, 0x17, 0x16, 0xCA, 0xAC, 0x37, 0xFD, 0x79, 0xA7, 0x91, + 0x17, 0x78, 0x38, 0x99, 0xAD, 0x58, 0xED, 0xB2, 0xDE, 0xCC, 0x89, 0x7D, + 0x03, 0x9C, 0xB3, 0x89, 0x65, 0xE7, 0xE3, 0x3B, 0xB1, 0x22, 0x86, 0x8F, + 0x06, 0x6D, 0x78, 0x07, 0xFD, 0x91, 0x12, 0x7F, 0xB0, 0x6B, 0x1C, 0x89, + 0x0D, 0xF9, 0xB8, 0xCB, 0x74, 0x5B, 0x07, 0xC2, 0xC8, 0xF4, 0x35, 0xD1, + 0x64, 0x63, 0x7A, 0xE9, 0x6E, 0x9A, 0x28, 0xD6, 0x30, 0xBD, 0xE6, 0x1B, + 0xDD, 0x15, 0xAF, 0x84, 0xEA, 0x9C, 0xC7, 0xCA, 0xF5, 0x0E, 0xEA, 0xF2, + 0x5D, 0x29, 0x87, 0x8F, 0x69, 0x73, 0x39, 0xBE, 0x2E, 0x24, 0x6F, 0x45, + 0x21, 0xAC, 0xC5, 0xD4, 0x69, 0x25, 0x06, 0x83, 0xAD, 0x7A, 0x48, 0x85, + 0x13, 0x2C, 0x0D, 0x06, 0xB8, 0x6C, 0x79, 0x56, 0xFC, 0xA3, 0x67, 0x32, + 0x81, 0xF5, 0x57, 0xA5, 0xCA, 0x57, 0x42, 0x69, 0xE9, 0x5C, 0x24, 0x61, + 0xEF, 0xE2, 0x30, 0x18, 0x4E, 0x44, 0x98, 0x55, 0x6F, 0x7A, 0xC2, 0x93, + 0xD8, 0x19, 0xB6, 0xDE, 0x7C, 0x47, 0x8A, 0x11, 0x4E, 0x49, 0x47, 0xDB, + 0x28, 0x94, 0x02, 0x0B, 0x94, 0x4A, 0x2C, 0xF9, 0x12, 0xD0, 0x4F, 0xE8, + 0x31, 0x7E, 0x6C, 0x7A, 0xBF, 0xA6, 0x3F, 0x9B, 0x39, 0x3D, 0x02, 0x16, + 0xA3, 0x18, 0xB3, 0x67, 0xAC, 0x5B, 0x3F, 0x2C, 0x83, 0x2B, 0x67, 0x39, + 0x81, 0x5C, 0xB9, 0x7E, 0x94, 0xD5, 0x64, 0xDD, 0x9E, 0x8F, 0x6E, 0xAE, + 0xE8, 0x7C, 0x5B, 0xB4, 0xD7, 0x6A, 0x47, 0x48, 0xD7, 0x7E, 0xB3, 0xD4, + 0x2D, 0x8E, 0x56, 0x76, 0x4E, 0xCF, 0x69, 0xF1, 0x6E, 0x44, 0x6C, 0xD4, + 0x24, 0xEA, 0x8D, 0x24, 0xA1, 0x18, 0xBF, 0xBD, 0x57, 0xFE, 0xA9, 0x99, + 0x35, 0xB5, 0xDB, 0x10, 0x77, 0xB8, 0x3D, 0x48, 0xBA, 0xD6, 0xC1, 0xE7, + 0xF1, 0x23, 0x3E, 0xD7, 0xDF, 0x85, 0x9D, 0x27, 0x3C, 0xD4, 0x40, 0xBD, + 0x0A, 0x0C, 0xBD, 0xF5, 0xE7, 0x8D, 0x25, 0xD6, 0x81, 0x74, 0x87, 0x46, + 0xD4, 0x29, 0x75, 0xA2, 0x42, 0x6C, 0xF7, 0x73, 0x89, 0xE7, 0x7D, 0xBF, + 0x7A, 0x4A, 0x1F, 0xD3, 0x22, 0xC9, 0x15, 0x55, 0xCF, 0xDF, 0x6F, 0x7C, + 0x55, 0xD0, 0xA4, 0x8B, 0x07, 0x11, 0x37, 0x5F, 0x83, 0xA6, 0x26, 0x57, + 0xA6, 0x01, 0x5B, 0x7E, 0xFE, 0x58, 0x68, 0x07, 0xA9, 0xE9, 0x7A, 0xD9, + 0xB9, 0xE8, 0xFF, 0x50, 0x1F, 0xAB, 0xC2, 0xB4, 0xC0, 0xCE, 0xE8, 0xEA, + 0xFD, 0x0F, 0xBD, 0x8D, 0x4D, 0xB8, 0xBC, 0x71 +}; + +static const unsigned char TA666_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA667_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x44, 0x2D, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6D, + 0x62, 0x48, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x19, 0x44, 0x2D, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x42, 0x52, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, 0x32, 0x30, + 0x32, 0x33 +}; + +static const unsigned char TA667_RSA_N[] = { + 0xAE, 0xFF, 0x09, 0x59, 0x91, 0x80, 0x0A, 0x4A, 0x68, 0xE6, 0x24, 0x3F, + 0xB8, 0xA7, 0xE4, 0xC8, 0x3A, 0x0A, 0x3A, 0x16, 0xCD, 0xC9, 0x23, 0x61, + 0xA0, 0x93, 0x71, 0xF2, 0xAB, 0x8B, 0x73, 0x8F, 0xA0, 0x67, 0x65, 0x60, + 0xD2, 0x54, 0x6B, 0x63, 0x51, 0x6F, 0x49, 0x33, 0xE0, 0x72, 0x07, 0x13, + 0x7D, 0x38, 0xCD, 0x06, 0x92, 0x07, 0x29, 0x52, 0x6B, 0x4E, 0x77, 0x6C, + 0x04, 0xD3, 0x95, 0xFA, 0xDD, 0x4C, 0x8C, 0xD9, 0x5D, 0xC1, 0x61, 0x7D, + 0x4B, 0xE7, 0x28, 0xB3, 0x44, 0x81, 0x7B, 0x51, 0xAF, 0xDD, 0x33, 0xB1, + 0x68, 0x7C, 0xD6, 0x4E, 0x4C, 0xFE, 0x2B, 0x68, 0xB9, 0xCA, 0x66, 0x69, + 0xC4, 0xEC, 0x5E, 0x57, 0x7F, 0xF7, 0x0D, 0xC7, 0x9C, 0x36, 0x36, 0xE5, + 0x07, 0x60, 0xAC, 0xC0, 0x4C, 0xEA, 0x08, 0x6C, 0xEF, 0x06, 0x7C, 0x4F, + 0x5B, 0x28, 0x7A, 0x08, 0xFC, 0x93, 0x5D, 0x9B, 0xF6, 0x9C, 0xB4, 0x8B, + 0x86, 0xBA, 0x21, 0xB9, 0xF4, 0xF0, 0xE8, 0x59, 0x5A, 0x28, 0xA1, 0x34, + 0x84, 0x1A, 0x25, 0x91, 0xB6, 0xB5, 0x8F, 0xEF, 0xB2, 0xF9, 0x80, 0xFA, + 0xF9, 0x3D, 0x3C, 0x11, 0x72, 0xD8, 0xE3, 0x2F, 0x86, 0x76, 0xC5, 0x79, + 0x2C, 0xC1, 0xA9, 0x90, 0x93, 0x46, 0x98, 0x67, 0xCB, 0x83, 0x6A, 0xA0, + 0x50, 0x23, 0xA7, 0x3B, 0xF6, 0x81, 0x39, 0xE0, 0xED, 0xF0, 0xB9, 0xBF, + 0x65, 0xF1, 0xD8, 0xCB, 0x7A, 0xFB, 0xEF, 0x73, 0x03, 0xCE, 0x00, 0xF4, + 0x7D, 0xD7, 0xE0, 0x5D, 0x3B, 0x66, 0xB8, 0xDC, 0x8E, 0xBA, 0x83, 0xCB, + 0x87, 0x76, 0x03, 0xFC, 0x25, 0xD9, 0xE7, 0x23, 0x6F, 0x06, 0xFD, 0x67, + 0xF3, 0xE0, 0xFF, 0x84, 0xBC, 0x47, 0xBF, 0xB5, 0x16, 0x18, 0x46, 0x69, + 0x14, 0xCC, 0x05, 0xF7, 0xDB, 0xD3, 0x49, 0xAC, 0x6B, 0xCC, 0xAB, 0xE4, + 0xB5, 0x0B, 0x43, 0x24, 0x5E, 0x4B, 0x6B, 0x4D, 0x67, 0xDF, 0xD6, 0xB5, + 0x3E, 0x4F, 0x78, 0x1F, 0x94, 0x71, 0x24, 0xEA, 0xDE, 0x70, 0xFC, 0xF1, + 0x93, 0xFE, 0x9E, 0x93, 0x5A, 0xE4, 0x94, 0x5A, 0x97, 0x54, 0x0C, 0x35, + 0x7B, 0x5F, 0x6C, 0xEE, 0x00, 0x1F, 0x24, 0xEC, 0x03, 0xBA, 0x02, 0xF5, + 0x76, 0xF4, 0x9F, 0xD4, 0x9A, 0xED, 0x85, 0x2C, 0x38, 0x22, 0x2F, 0xC7, + 0xD8, 0x2F, 0x76, 0x11, 0x4F, 0xFD, 0x6C, 0x5C, 0xE8, 0xF5, 0x8E, 0x27, + 0x87, 0x7F, 0x19, 0x4A, 0x21, 0x47, 0x90, 0x1D, 0x79, 0x8D, 0x1C, 0x5B, + 0xF8, 0xCF, 0x4A, 0x85, 0xE4, 0xED, 0xB3, 0x5B, 0x8D, 0xBE, 0xC4, 0x64, + 0x28, 0x5D, 0x41, 0xC4, 0x6E, 0xAC, 0x38, 0x5A, 0x4F, 0x23, 0x74, 0x74, + 0xA9, 0x12, 0xC3, 0xF6, 0xD2, 0xB9, 0x11, 0x15, 0x33, 0x07, 0x91, 0xD8, + 0x3B, 0x37, 0x3A, 0x63, 0x30, 0x06, 0xD1, 0xC5, 0x22, 0x36, 0x28, 0x62, + 0x23, 0x10, 0xE0, 0x46, 0xCC, 0x97, 0xAC, 0xD6, 0x2B, 0x5D, 0x64, 0x24, + 0xD5, 0xEE, 0x1C, 0x0E, 0xDE, 0xFB, 0x08, 0x5A, 0x75, 0x2A, 0xF6, 0x63, + 0x6D, 0xCE, 0x0B, 0x42, 0xBE, 0xD1, 0xBA, 0x70, 0x1C, 0x9C, 0x21, 0xE5, + 0x0F, 0x31, 0x69, 0x17, 0xD7, 0xFC, 0x0A, 0xB4, 0xDE, 0xED, 0x80, 0x9C, + 0xCB, 0x92, 0xB4, 0x8B, 0xF5, 0xDE, 0x59, 0xA2, 0x58, 0x09, 0xA5, 0x63, + 0x47, 0x0B, 0xE1, 0x41, 0x32, 0x34, 0x41, 0xD9, 0x9A, 0xB1, 0xD9, 0xA8, + 0xB0, 0x1B, 0x5A, 0xDE, 0x0D, 0x0D, 0xF4, 0xE2, 0xB2, 0x5D, 0x35, 0x80, + 0xB9, 0x81, 0xD4, 0x84, 0x69, 0x91, 0x02, 0xCB, 0x75, 0xD0, 0x8D, 0xC5, + 0xB5, 0x3D, 0x09, 0x91, 0x09, 0x8F, 0x14, 0xA1, 0x14, 0x74, 0x79, 0x3E, + 0xD6, 0xC9, 0x15, 0x1D, 0xA4, 0x59, 0x59, 0x22, 0xDC, 0xF6, 0x8A, 0x45, + 0x3D, 0x3C, 0x12, 0xD6, 0x3E, 0x5D, 0x32, 0x2F +}; + +static const unsigned char TA667_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA668_DN[] = { + 0x30, 0x6E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x13, 0x46, 0x69, 0x72, 0x6D, 0x61, 0x70, 0x72, 0x6F, 0x66, 0x65, + 0x73, 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x20, 0x53, 0x41, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x61, 0x0C, 0x0F, 0x56, 0x41, 0x54, 0x45, + 0x53, 0x2D, 0x41, 0x36, 0x32, 0x36, 0x33, 0x34, 0x30, 0x36, 0x38, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x46, 0x49, + 0x52, 0x4D, 0x41, 0x50, 0x52, 0x4F, 0x46, 0x45, 0x53, 0x49, 0x4F, 0x4E, + 0x41, 0x4C, 0x20, 0x43, 0x41, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x2D, 0x41, + 0x20, 0x57, 0x45, 0x42 +}; + +static const unsigned char TA668_EC_Q[] = { + 0x04, 0x47, 0x53, 0xEA, 0x2C, 0x11, 0xA4, 0x77, 0xC7, 0x2A, 0xEA, 0xF3, + 0xD6, 0x5F, 0x7B, 0xD3, 0x04, 0x91, 0x5C, 0xFA, 0x88, 0xC6, 0x22, 0xB9, + 0x83, 0x10, 0x62, 0x77, 0x84, 0x33, 0x2D, 0xE9, 0x03, 0x88, 0xD4, 0xE0, + 0x33, 0xF7, 0xED, 0x77, 0x2C, 0x4A, 0x60, 0xEA, 0xE4, 0x6F, 0xAD, 0x6D, + 0xB4, 0xF8, 0x4C, 0x8A, 0xA4, 0xE4, 0x1F, 0xCA, 0xEA, 0x4F, 0x38, 0x4A, + 0x2E, 0x82, 0x73, 0x2B, 0xC7, 0x66, 0x9B, 0x0A, 0x8C, 0x40, 0x9C, 0x7C, + 0x8A, 0xF6, 0xF2, 0x39, 0x60, 0xB2, 0xDE, 0xCB, 0xEC, 0xB8, 0xE4, 0x6F, + 0xEA, 0x9B, 0x5D, 0xB7, 0x53, 0x90, 0x18, 0x32, 0x55, 0xC5, 0x20, 0xB7, + 0x94 +}; + +static const unsigned char TA669_DN[] = { + 0x30, 0x62, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x29, 0x47, 0x55, 0x41, 0x4E, 0x47, 0x20, 0x44, 0x4F, 0x4E, 0x47, + 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, + 0x20, 0x41, 0x55, 0x54, 0x48, 0x4F, 0x52, 0x49, 0x54, 0x59, 0x20, 0x43, + 0x4F, 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x1F, 0x30, 0x1D, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x47, 0x44, 0x43, 0x41, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x41, 0x55, 0x54, 0x48, 0x20, 0x52, 0x35, 0x20, + 0x52, 0x4F, 0x4F, 0x54 +}; + +static const unsigned char TA669_RSA_N[] = { + 0xD9, 0xA3, 0x16, 0xF0, 0xC8, 0x74, 0x74, 0x77, 0x9B, 0xEF, 0x33, 0x0D, + 0x3B, 0x06, 0x7E, 0x55, 0xFC, 0xB5, 0x60, 0x8F, 0x76, 0x86, 0x12, 0x42, + 0x7D, 0x56, 0x66, 0x3E, 0x88, 0x82, 0xED, 0x72, 0x63, 0x0E, 0x9E, 0x8B, + 0xDD, 0x34, 0x2C, 0x02, 0x51, 0x51, 0xC3, 0x19, 0xFD, 0x59, 0x54, 0x84, + 0xC9, 0xF1, 0x6B, 0xB3, 0x4C, 0xB0, 0xE9, 0xE8, 0x46, 0x5D, 0x38, 0xC6, + 0xA2, 0xA7, 0x2E, 0x11, 0x57, 0xBA, 0x82, 0x15, 0xA2, 0x9C, 0x8F, 0x6D, + 0xB0, 0x99, 0x4A, 0x0A, 0xF2, 0xEB, 0x89, 0x70, 0x63, 0x4E, 0x79, 0xC4, + 0xB7, 0x5B, 0xBD, 0xA2, 0x5D, 0xB1, 0xF2, 0x41, 0x02, 0x2B, 0xAD, 0xA9, + 0x3A, 0xA3, 0xEC, 0x79, 0x0A, 0xEC, 0x5F, 0x3A, 0xE3, 0xFD, 0xEF, 0x80, + 0x3C, 0xAD, 0x34, 0x9B, 0x1A, 0xAB, 0x88, 0x26, 0x7B, 0x56, 0xA2, 0x82, + 0x86, 0x1F, 0xEB, 0x35, 0x89, 0x83, 0x7F, 0x5F, 0xAE, 0x29, 0x4E, 0x3D, + 0xB6, 0x6E, 0xEC, 0xAE, 0xC1, 0xF0, 0x27, 0x9B, 0xAE, 0xE3, 0xF4, 0xEC, + 0xEF, 0xAE, 0x7F, 0xF7, 0x86, 0x3D, 0x72, 0x7A, 0xEB, 0xA5, 0xFB, 0x59, + 0x4E, 0xA7, 0xEB, 0x95, 0x8C, 0x22, 0x39, 0x79, 0xE1, 0x2D, 0x08, 0x8F, + 0xCC, 0xBC, 0x91, 0xB8, 0x41, 0xF7, 0x14, 0xC1, 0x23, 0xA9, 0xC3, 0xAD, + 0x9A, 0x45, 0x44, 0xB3, 0xB2, 0xD7, 0x2C, 0xCD, 0xC6, 0x29, 0xE2, 0x50, + 0x10, 0xAE, 0x5C, 0xCB, 0x82, 0x8E, 0x17, 0x18, 0x36, 0x7D, 0x97, 0xE6, + 0x88, 0x9A, 0xB0, 0x4D, 0x34, 0x09, 0xF4, 0x2C, 0xB9, 0x5A, 0x66, 0x2A, + 0xB0, 0x17, 0x9B, 0x9E, 0x1E, 0x76, 0x9D, 0x4A, 0x66, 0x31, 0x41, 0xDF, + 0x3F, 0xFB, 0xC5, 0x06, 0xEF, 0x1B, 0xB6, 0x7E, 0x1A, 0x46, 0x36, 0xF7, + 0x64, 0x63, 0x3B, 0xE3, 0x39, 0x18, 0x23, 0xE7, 0x67, 0x75, 0x14, 0xD5, + 0x75, 0x57, 0x92, 0x37, 0xBD, 0xBE, 0x6A, 0x1B, 0x26, 0x50, 0xF2, 0x36, + 0x26, 0x06, 0x90, 0xC5, 0x70, 0x01, 0x64, 0x6D, 0x76, 0x66, 0xE1, 0x91, + 0xDB, 0x6E, 0x07, 0xC0, 0x61, 0x80, 0x2E, 0xB2, 0x2E, 0x2F, 0x8C, 0x70, + 0xA7, 0xD1, 0x3B, 0x3C, 0xB3, 0x91, 0xE4, 0x6E, 0xB6, 0xC4, 0x3B, 0x70, + 0xF2, 0x6C, 0x92, 0x97, 0x09, 0xCD, 0x47, 0x7D, 0x18, 0xC0, 0xF3, 0xBB, + 0x9E, 0x0F, 0xD6, 0x8B, 0xAE, 0x07, 0xB6, 0x5A, 0x0F, 0xCE, 0x0B, 0x0C, + 0x47, 0xA7, 0xE5, 0x3E, 0xB8, 0xBD, 0x7D, 0xC7, 0x9B, 0x35, 0xA0, 0x61, + 0x97, 0x3A, 0x41, 0x75, 0x17, 0xCC, 0x2B, 0x96, 0x77, 0x2A, 0x92, 0x21, + 0x1E, 0xD9, 0x95, 0x76, 0x20, 0x67, 0x68, 0xCF, 0x0D, 0xBD, 0xDF, 0xD6, + 0x1F, 0x09, 0x6A, 0x9A, 0xE2, 0xCC, 0x73, 0x71, 0xA4, 0x2F, 0x7D, 0x12, + 0x80, 0xB7, 0x53, 0x30, 0x46, 0x5E, 0x4B, 0x54, 0x99, 0x0F, 0x67, 0xC9, + 0xA5, 0xC8, 0xF2, 0x20, 0xC1, 0x82, 0xEC, 0x9D, 0x11, 0xDF, 0xC2, 0x02, + 0xFB, 0x1A, 0x3B, 0xD1, 0xED, 0x20, 0x9A, 0xEF, 0x65, 0x64, 0x92, 0x10, + 0x0D, 0x2A, 0xE2, 0xDE, 0x70, 0xF1, 0x18, 0x67, 0x82, 0x8C, 0x61, 0xDE, + 0xB8, 0xBC, 0xD1, 0x2F, 0x9C, 0xFB, 0x0F, 0xD0, 0x2B, 0xED, 0x1B, 0x76, + 0xB9, 0xE4, 0x39, 0x55, 0xF8, 0xF8, 0xA1, 0x1D, 0xB8, 0xAA, 0x80, 0x00, + 0x4C, 0x82, 0xE7, 0xB2, 0x7F, 0x09, 0xB8, 0xBC, 0x30, 0xA0, 0x2F, 0x0D, + 0xF5, 0x52, 0x9E, 0x8E, 0xF7, 0x92, 0xB3, 0x0A, 0x00, 0x1D, 0x00, 0x54, + 0x97, 0x06, 0xE0, 0xB1, 0x07, 0xD9, 0xC7, 0x0F, 0x5C, 0x65, 0x7D, 0x3C, + 0x6D, 0x59, 0x57, 0xE4, 0xED, 0xA5, 0x8D, 0xE9, 0x40, 0x53, 0x9F, 0x15, + 0x4B, 0xA0, 0x71, 0xF6, 0x1A, 0x21, 0xE3, 0xDA, 0x70, 0x06, 0x21, 0x58, + 0x14, 0x87, 0x85, 0x77, 0x79, 0xAA, 0x82, 0x79 +}; + +static const unsigned char TA669_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA670_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x34, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA670_EC_Q[] = { + 0x04, 0xB8, 0xC6, 0x79, 0xD3, 0x8F, 0x6C, 0x25, 0x0E, 0x9F, 0x2E, 0x39, + 0x19, 0x1C, 0x03, 0xA4, 0xAE, 0x9A, 0xE5, 0x39, 0x07, 0x09, 0x16, 0xCA, + 0x63, 0xB1, 0xB9, 0x86, 0xF8, 0x8A, 0x57, 0xC1, 0x57, 0xCE, 0x42, 0xFA, + 0x73, 0xA1, 0xF7, 0x65, 0x42, 0xFF, 0x1E, 0xC1, 0x00, 0xB2, 0x6E, 0x73, + 0x0E, 0xFF, 0xC7, 0x21, 0xE5, 0x18, 0xA4, 0xAA, 0xD9, 0x71, 0x3F, 0xA8, + 0xD4, 0xB9, 0xCE, 0x8C, 0x1D +}; + +static const unsigned char TA671_DN[] = { + 0x30, 0x50, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x1B, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x2D, 0x20, 0x52, 0x35, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, + 0x6E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA671_EC_Q[] = { + 0x04, 0x47, 0x45, 0x0E, 0x96, 0xFB, 0x7D, 0x5D, 0xBF, 0xE9, 0x39, 0xD1, + 0x21, 0xF8, 0x9F, 0x0B, 0xB6, 0xD5, 0x7B, 0x1E, 0x92, 0x3A, 0x48, 0x59, + 0x1C, 0xF0, 0x62, 0x31, 0x2D, 0xC0, 0x7A, 0x28, 0xFE, 0x1A, 0xA7, 0x5C, + 0xB3, 0xB6, 0xCC, 0x97, 0xE7, 0x45, 0xD4, 0x58, 0xFA, 0xD1, 0x77, 0x6D, + 0x43, 0xA2, 0xC0, 0x87, 0x65, 0x34, 0x0A, 0x1F, 0x7A, 0xDD, 0xEB, 0x3C, + 0x33, 0xA1, 0xC5, 0x9D, 0x4D, 0xA4, 0x6F, 0x41, 0x95, 0x38, 0x7F, 0xC9, + 0x1E, 0x84, 0xEB, 0xD1, 0x9E, 0x49, 0x92, 0x87, 0x94, 0x87, 0x0C, 0x3A, + 0x85, 0x4A, 0x66, 0x9F, 0x9D, 0x59, 0x93, 0x4D, 0x97, 0x61, 0x06, 0x86, + 0x4A +}; + +static const unsigned char TA672_DN[] = { + 0x30, 0x57, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, + 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA672_RSA_N[] = { + 0xDA, 0x0E, 0xE6, 0x99, 0x8D, 0xCE, 0xA3, 0xE3, 0x4F, 0x8A, 0x7E, 0xFB, + 0xF1, 0x8B, 0x83, 0x25, 0x6B, 0xEA, 0x48, 0x1F, 0xF1, 0x2A, 0xB0, 0xB9, + 0x95, 0x11, 0x04, 0xBD, 0xF0, 0x63, 0xD1, 0xE2, 0x67, 0x66, 0xCF, 0x1C, + 0xDD, 0xCF, 0x1B, 0x48, 0x2B, 0xEE, 0x8D, 0x89, 0x8E, 0x9A, 0xAF, 0x29, + 0x80, 0x65, 0xAB, 0xE9, 0xC7, 0x2D, 0x12, 0xCB, 0xAB, 0x1C, 0x4C, 0x70, + 0x07, 0xA1, 0x3D, 0x0A, 0x30, 0xCD, 0x15, 0x8D, 0x4F, 0xF8, 0xDD, 0xD4, + 0x8C, 0x50, 0x15, 0x1C, 0xEF, 0x50, 0xEE, 0xC4, 0x2E, 0xF7, 0xFC, 0xE9, + 0x52, 0xF2, 0x91, 0x7D, 0xE0, 0x6D, 0xD5, 0x35, 0x30, 0x8E, 0x5E, 0x43, + 0x73, 0xF2, 0x41, 0xE9, 0xD5, 0x6A, 0xE3, 0xB2, 0x89, 0x3A, 0x56, 0x39, + 0x38, 0x6F, 0x06, 0x3C, 0x88, 0x69, 0x5B, 0x2A, 0x4D, 0xC5, 0xA7, 0x54, + 0xB8, 0x6C, 0x89, 0xCC, 0x9B, 0xF9, 0x3C, 0xCA, 0xE5, 0xFD, 0x89, 0xF5, + 0x12, 0x3C, 0x92, 0x78, 0x96, 0xD6, 0xDC, 0x74, 0x6E, 0x93, 0x44, 0x61, + 0xD1, 0x8D, 0xC7, 0x46, 0xB2, 0x75, 0x0E, 0x86, 0xE8, 0x19, 0x8A, 0xD5, + 0x6D, 0x6C, 0xD5, 0x78, 0x16, 0x95, 0xA2, 0xE9, 0xC8, 0x0A, 0x38, 0xEB, + 0xF2, 0x24, 0x13, 0x4F, 0x73, 0x54, 0x93, 0x13, 0x85, 0x3A, 0x1B, 0xBC, + 0x1E, 0x34, 0xB5, 0x8B, 0x05, 0x8C, 0xB9, 0x77, 0x8B, 0xB1, 0xDB, 0x1F, + 0x20, 0x91, 0xAB, 0x09, 0x53, 0x6E, 0x90, 0xCE, 0x7B, 0x37, 0x74, 0xB9, + 0x70, 0x47, 0x91, 0x22, 0x51, 0x63, 0x16, 0x79, 0xAE, 0xB1, 0xAE, 0x41, + 0x26, 0x08, 0xC8, 0x19, 0x2B, 0xD1, 0x46, 0xAA, 0x48, 0xD6, 0x64, 0x2A, + 0xD7, 0x83, 0x34, 0xFF, 0x2C, 0x2A, 0xC1, 0x6C, 0x19, 0x43, 0x4A, 0x07, + 0x85, 0xE7, 0xD3, 0x7C, 0xF6, 0x21, 0x68, 0xEF, 0xEA, 0xF2, 0x52, 0x9F, + 0x7F, 0x93, 0x90, 0xCF +}; + +static const unsigned char TA672_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA673_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x33, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA673_RSA_N[] = { + 0xCC, 0x25, 0x76, 0x90, 0x79, 0x06, 0x78, 0x22, 0x16, 0xF5, 0xC0, 0x83, + 0xB6, 0x84, 0xCA, 0x28, 0x9E, 0xFD, 0x05, 0x76, 0x11, 0xC5, 0xAD, 0x88, + 0x72, 0xFC, 0x46, 0x02, 0x43, 0xC7, 0xB2, 0x8A, 0x9D, 0x04, 0x5F, 0x24, + 0xCB, 0x2E, 0x4B, 0xE1, 0x60, 0x82, 0x46, 0xE1, 0x52, 0xAB, 0x0C, 0x81, + 0x47, 0x70, 0x6C, 0xDD, 0x64, 0xD1, 0xEB, 0xF5, 0x2C, 0xA3, 0x0F, 0x82, + 0x3D, 0x0C, 0x2B, 0xAE, 0x97, 0xD7, 0xB6, 0x14, 0x86, 0x10, 0x79, 0xBB, + 0x3B, 0x13, 0x80, 0x77, 0x8C, 0x08, 0xE1, 0x49, 0xD2, 0x6A, 0x62, 0x2F, + 0x1F, 0x5E, 0xFA, 0x96, 0x68, 0xDF, 0x89, 0x27, 0x95, 0x38, 0x9F, 0x06, + 0xD7, 0x3E, 0xC9, 0xCB, 0x26, 0x59, 0x0D, 0x73, 0xDE, 0xB0, 0xC8, 0xE9, + 0x26, 0x0E, 0x83, 0x15, 0xC6, 0xEF, 0x5B, 0x8B, 0xD2, 0x04, 0x60, 0xCA, + 0x49, 0xA6, 0x28, 0xF6, 0x69, 0x3B, 0xF6, 0xCB, 0xC8, 0x28, 0x91, 0xE5, + 0x9D, 0x8A, 0x61, 0x57, 0x37, 0xAC, 0x74, 0x14, 0xDC, 0x74, 0xE0, 0x3A, + 0xEE, 0x72, 0x2F, 0x2E, 0x9C, 0xFB, 0xD0, 0xBB, 0xBF, 0xF5, 0x3D, 0x00, + 0xE1, 0x06, 0x33, 0xE8, 0x82, 0x2B, 0xAE, 0x53, 0xA6, 0x3A, 0x16, 0x73, + 0x8C, 0xDD, 0x41, 0x0E, 0x20, 0x3A, 0xC0, 0xB4, 0xA7, 0xA1, 0xE9, 0xB2, + 0x4F, 0x90, 0x2E, 0x32, 0x60, 0xE9, 0x57, 0xCB, 0xB9, 0x04, 0x92, 0x68, + 0x68, 0xE5, 0x38, 0x26, 0x60, 0x75, 0xB2, 0x9F, 0x77, 0xFF, 0x91, 0x14, + 0xEF, 0xAE, 0x20, 0x49, 0xFC, 0xAD, 0x40, 0x15, 0x48, 0xD1, 0x02, 0x31, + 0x61, 0x19, 0x5E, 0xB8, 0x97, 0xEF, 0xAD, 0x77, 0xB7, 0x64, 0x9A, 0x7A, + 0xBF, 0x5F, 0xC1, 0x13, 0xEF, 0x9B, 0x62, 0xFB, 0x0D, 0x6C, 0xE0, 0x54, + 0x69, 0x16, 0xA9, 0x03, 0xDA, 0x6E, 0xE9, 0x83, 0x93, 0x71, 0x76, 0xC6, + 0x69, 0x85, 0x82, 0x17 +}; + +static const unsigned char TA673_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA674_DN[] = { + 0x30, 0x4C, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x17, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x52, 0x36, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0A, 0x47, + 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0A, 0x47, 0x6C, 0x6F, 0x62, + 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E +}; + +static const unsigned char TA674_RSA_N[] = { + 0x95, 0x07, 0xE8, 0x73, 0xCA, 0x66, 0xF9, 0xEC, 0x14, 0xCA, 0x7B, 0x3C, + 0xF7, 0x0D, 0x08, 0xF1, 0xB4, 0x45, 0x0B, 0x2C, 0x82, 0xB4, 0x48, 0xC6, + 0xEB, 0x5B, 0x3C, 0xAE, 0x83, 0xB8, 0x41, 0x92, 0x33, 0x14, 0xA4, 0x6F, + 0x7F, 0xE9, 0x2A, 0xCC, 0xC6, 0xB0, 0x88, 0x6B, 0xC5, 0xB6, 0x89, 0xD1, + 0xC6, 0xB2, 0xFF, 0x14, 0xCE, 0x51, 0x14, 0x21, 0xEC, 0x4A, 0xDD, 0x1B, + 0x5A, 0xC6, 0xD6, 0x87, 0xEE, 0x4D, 0x3A, 0x15, 0x06, 0xED, 0x64, 0x66, + 0x0B, 0x92, 0x80, 0xCA, 0x44, 0xDE, 0x73, 0x94, 0x4E, 0xF3, 0xA7, 0x89, + 0x7F, 0x4F, 0x78, 0x63, 0x08, 0xC8, 0x12, 0x50, 0x6D, 0x42, 0x66, 0x2F, + 0x4D, 0xB9, 0x79, 0x28, 0x4D, 0x52, 0x1A, 0x8A, 0x1A, 0x80, 0xB7, 0x19, + 0x81, 0x0E, 0x7E, 0xC4, 0x8A, 0xBC, 0x64, 0x4C, 0x21, 0x1C, 0x43, 0x68, + 0xD7, 0x3D, 0x3C, 0x8A, 0xC5, 0xB2, 0x66, 0xD5, 0x90, 0x9A, 0xB7, 0x31, + 0x06, 0xC5, 0xBE, 0xE2, 0x6D, 0x32, 0x06, 0xA6, 0x1E, 0xF9, 0xB9, 0xEB, + 0xAA, 0xA3, 0xB8, 0xBF, 0xBE, 0x82, 0x63, 0x50, 0xD0, 0xF0, 0x18, 0x89, + 0xDF, 0xE4, 0x0F, 0x79, 0xF5, 0xEA, 0xA2, 0x1F, 0x2A, 0xD2, 0x70, 0x2E, + 0x7B, 0xE7, 0xBC, 0x93, 0xBB, 0x6D, 0x53, 0xE2, 0x48, 0x7C, 0x8C, 0x10, + 0x07, 0x38, 0xFF, 0x66, 0xB2, 0x77, 0x61, 0x7E, 0xE0, 0xEA, 0x8C, 0x3C, + 0xAA, 0xB4, 0xA4, 0xF6, 0xF3, 0x95, 0x4A, 0x12, 0x07, 0x6D, 0xFD, 0x8C, + 0xB2, 0x89, 0xCF, 0xD0, 0xA0, 0x61, 0x77, 0xC8, 0x58, 0x74, 0xB0, 0xD4, + 0x23, 0x3A, 0xF7, 0x5D, 0x3A, 0xCA, 0xA2, 0xDB, 0x9D, 0x09, 0xDE, 0x5D, + 0x44, 0x2D, 0x90, 0xF1, 0x81, 0xCD, 0x57, 0x92, 0xFA, 0x7E, 0xBC, 0x50, + 0x04, 0x63, 0x34, 0xDF, 0x6B, 0x93, 0x18, 0xBE, 0x6B, 0x36, 0xB2, 0x39, + 0xE4, 0xAC, 0x24, 0x36, 0xB7, 0xF0, 0xEF, 0xB6, 0x1C, 0x13, 0x57, 0x93, + 0xB6, 0xDE, 0xB2, 0xF8, 0xE2, 0x85, 0xB7, 0x73, 0xA2, 0xB8, 0x35, 0xAA, + 0x45, 0xF2, 0xE0, 0x9D, 0x36, 0xA1, 0x6F, 0x54, 0x8A, 0xF1, 0x72, 0x56, + 0x6E, 0x2E, 0x88, 0xC5, 0x51, 0x42, 0x44, 0x15, 0x94, 0xEE, 0xA3, 0xC5, + 0x38, 0x96, 0x9B, 0x4E, 0x4E, 0x5A, 0x0B, 0x47, 0xF3, 0x06, 0x36, 0x49, + 0x77, 0x30, 0xBC, 0x71, 0x37, 0xE5, 0xA6, 0xEC, 0x21, 0x08, 0x75, 0xFC, + 0xE6, 0x61, 0x16, 0x3F, 0x77, 0xD5, 0xD9, 0x91, 0x97, 0x84, 0x0A, 0x6C, + 0xD4, 0x02, 0x4D, 0x74, 0xC0, 0x14, 0xED, 0xFD, 0x39, 0xFB, 0x83, 0xF2, + 0x5E, 0x14, 0xA1, 0x04, 0xB0, 0x0B, 0xE9, 0xFE, 0xEE, 0x8F, 0xE1, 0x6E, + 0x0B, 0xB2, 0x08, 0xB3, 0x61, 0x66, 0x09, 0x6A, 0xB1, 0x06, 0x3A, 0x65, + 0x96, 0x59, 0xC0, 0xF0, 0x35, 0xFD, 0xC9, 0xDA, 0x28, 0x8D, 0x1A, 0x11, + 0x87, 0x70, 0x81, 0x0A, 0xA8, 0x9A, 0x75, 0x1D, 0x9E, 0x3A, 0x86, 0x05, + 0x00, 0x9E, 0xDB, 0x80, 0xD6, 0x25, 0xF9, 0xDC, 0x05, 0x9E, 0x27, 0x59, + 0x4C, 0x76, 0x39, 0x5B, 0xEA, 0xF9, 0xA5, 0xA1, 0xD8, 0x83, 0x0F, 0xD1, + 0xFF, 0xDF, 0x30, 0x11, 0xF9, 0x85, 0xCF, 0x33, 0x48, 0xF5, 0xCA, 0x6D, + 0x64, 0x14, 0x2C, 0x7A, 0x58, 0x4F, 0xD3, 0x4B, 0x08, 0x49, 0xC5, 0x95, + 0x64, 0x1A, 0x63, 0x0E, 0x79, 0x3D, 0xF5, 0xB3, 0x8C, 0xCA, 0x58, 0xAD, + 0x9C, 0x42, 0x45, 0x79, 0x6E, 0x0E, 0x87, 0x19, 0x5C, 0x54, 0xB1, 0x65, + 0xB6, 0xBF, 0x8C, 0x9B, 0xDC, 0x13, 0xE9, 0x0D, 0x6F, 0xB8, 0x2E, 0xDC, + 0x67, 0x6E, 0xC9, 0x8B, 0x11, 0xB5, 0x84, 0x14, 0x8A, 0x00, 0x19, 0x70, + 0x83, 0x79, 0x91, 0x97, 0x91, 0xD4, 0x1A, 0x27, 0xBF, 0x37, 0x1E, 0x32, + 0x07, 0xD8, 0x14, 0x63, 0x3C, 0x28, 0x4C, 0xAF +}; + +static const unsigned char TA674_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA675_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, 0x36 +}; + +static const unsigned char TA675_EC_Q[] = { + 0x04, 0x9C, 0x0E, 0xB1, 0xCF, 0xB7, 0xE8, 0x9E, 0x52, 0x77, 0x75, 0x34, + 0xFA, 0xA5, 0x46, 0xA7, 0xAD, 0x32, 0x19, 0x32, 0xB4, 0x07, 0xA9, 0x27, + 0xCA, 0x94, 0xBB, 0x0C, 0xD2, 0x0A, 0x10, 0xC7, 0xDA, 0x89, 0xB0, 0x97, + 0x0C, 0x70, 0x13, 0x09, 0x01, 0x8E, 0xD8, 0xEA, 0x47, 0xEA, 0xBE, 0xB2, + 0x80, 0x2B, 0xCD, 0xFC, 0x28, 0x0D, 0xDB, 0xAC, 0xBC, 0xA4, 0x86, 0x37, + 0xED, 0x70, 0x08, 0x00, 0x75, 0xEA, 0x93, 0x0B, 0x7B, 0x2E, 0x52, 0x9C, + 0x23, 0x68, 0x23, 0x06, 0x43, 0xEC, 0x92, 0x2F, 0x53, 0x84, 0xDB, 0xFB, + 0x47, 0x14, 0x07, 0xE8, 0x5F, 0x94, 0x67, 0x5D, 0xC9, 0x7A, 0x81, 0x3C, + 0x20 +}; + +static const unsigned char TA676_DN[] = { + 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, 0x69, 0x67, 0x6E, + 0x20, 0x6E, 0x76, 0x2D, 0x73, 0x61, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x13, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x53, + 0x69, 0x67, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, 0x36 +}; + +static const unsigned char TA676_RSA_N[] = { + 0xAC, 0xAC, 0x74, 0x32, 0xE8, 0xB3, 0x65, 0xE5, 0xBA, 0xED, 0x43, 0x26, + 0x1D, 0xA6, 0x89, 0x0D, 0x45, 0xBA, 0x29, 0x88, 0xB2, 0xA4, 0x1D, 0x63, + 0xDD, 0xD3, 0xC1, 0x2C, 0x09, 0x57, 0x89, 0x39, 0xA1, 0x55, 0xE9, 0x67, + 0x34, 0x77, 0x0C, 0x6E, 0xE4, 0x55, 0x1D, 0x52, 0x25, 0xD2, 0x13, 0x6B, + 0x5E, 0xE1, 0x1D, 0xA9, 0xB7, 0x7D, 0x89, 0x32, 0x5F, 0x0D, 0x9E, 0x9F, + 0x2C, 0x7A, 0x63, 0x60, 0x40, 0x1F, 0xA6, 0xB0, 0xB6, 0x78, 0x8F, 0x99, + 0x54, 0x96, 0x08, 0x58, 0xAE, 0xE4, 0x06, 0xBC, 0x62, 0x05, 0x02, 0x16, + 0xBF, 0xAF, 0xA8, 0x23, 0x03, 0xB6, 0x94, 0x0F, 0xBC, 0x6E, 0x6C, 0xC2, + 0xCB, 0xD5, 0xA6, 0xBB, 0x0C, 0xE9, 0xF6, 0xC1, 0x02, 0xFB, 0x21, 0xDE, + 0x66, 0xDD, 0x17, 0xAB, 0x74, 0x42, 0xEF, 0xF0, 0x74, 0x2F, 0x25, 0xF4, + 0xEA, 0x6B, 0x55, 0x5B, 0x90, 0xDB, 0x9D, 0xDF, 0x5E, 0x87, 0x0A, 0x40, + 0xFB, 0xAD, 0x19, 0x6B, 0xFB, 0xF7, 0xCA, 0x60, 0x88, 0xDE, 0xDA, 0xC1, + 0x8F, 0xD6, 0xAE, 0xD5, 0x7F, 0xD4, 0x3C, 0x83, 0xEE, 0xD7, 0x16, 0x4C, + 0x83, 0x45, 0x33, 0x6B, 0x27, 0xD0, 0x86, 0xD0, 0x1C, 0x2D, 0x6B, 0xF3, + 0xAB, 0x7D, 0xF1, 0x85, 0xA9, 0xF5, 0x28, 0xD2, 0xAD, 0xEF, 0xF3, 0x84, + 0x4B, 0x1C, 0x87, 0xFC, 0x13, 0xA3, 0x3A, 0x72, 0xA2, 0x5A, 0x11, 0x2B, + 0xD6, 0x27, 0x71, 0x27, 0xED, 0x81, 0x2D, 0x6D, 0x66, 0x81, 0x92, 0x87, + 0xB4, 0x1B, 0x58, 0x7A, 0xCC, 0x3F, 0x0A, 0xFA, 0x46, 0x4F, 0x4D, 0x78, + 0x5C, 0xF8, 0x2B, 0x48, 0xE3, 0x04, 0x84, 0xCB, 0x5D, 0xF6, 0xB4, 0x6A, + 0xB3, 0x65, 0xFC, 0x42, 0x9E, 0x51, 0x26, 0x23, 0x20, 0xCB, 0x3D, 0x14, + 0xF9, 0x81, 0xED, 0x65, 0x16, 0x00, 0x4F, 0x1A, 0x64, 0x97, 0x66, 0x08, + 0xCF, 0x8C, 0x7B, 0xE3, 0x2B, 0xC0, 0x9D, 0xF9, 0x14, 0xF2, 0x1B, 0xF1, + 0x56, 0x6A, 0x16, 0xBF, 0x2C, 0x85, 0x85, 0xCD, 0x78, 0x38, 0x9A, 0xEB, + 0x42, 0x6A, 0x02, 0x34, 0x18, 0x83, 0x17, 0x4E, 0x94, 0x56, 0xF8, 0xB6, + 0x82, 0xB5, 0xF3, 0x96, 0xDD, 0x3D, 0xF3, 0xBE, 0x7F, 0x20, 0x77, 0x3E, + 0x7B, 0x19, 0x23, 0x6B, 0x2C, 0xD4, 0x72, 0x73, 0x43, 0x57, 0x7D, 0xE0, + 0xF8, 0xD7, 0x69, 0x4F, 0x17, 0x36, 0x04, 0xF9, 0xC0, 0x90, 0x60, 0x37, + 0x45, 0xDE, 0xE6, 0x0C, 0xD8, 0x74, 0x8D, 0xAE, 0x9C, 0xA2, 0x6D, 0x74, + 0x5D, 0x42, 0xBE, 0x06, 0xF5, 0xD9, 0x64, 0x6E, 0x02, 0x10, 0xAC, 0x89, + 0xB0, 0x4C, 0x3B, 0x07, 0x4D, 0x40, 0x7E, 0x24, 0xC5, 0x8A, 0x98, 0x82, + 0x79, 0x8E, 0xA4, 0xA7, 0x82, 0x20, 0x8D, 0x23, 0xFA, 0x27, 0x71, 0xC9, + 0xDF, 0xC6, 0x41, 0x74, 0xA0, 0x4D, 0xF6, 0x91, 0x16, 0xDC, 0x46, 0x8C, + 0x5F, 0x29, 0x63, 0x31, 0x59, 0x71, 0x0C, 0xD8, 0x6F, 0xC2, 0xB6, 0x32, + 0x7D, 0xFB, 0xE6, 0x5D, 0x53, 0xA6, 0x7E, 0x15, 0xFC, 0xBB, 0x75, 0x7C, + 0x5D, 0xEC, 0xF8, 0xF6, 0x17, 0x1C, 0xEC, 0xC7, 0x6B, 0x19, 0xCB, 0xF3, + 0x7B, 0xF0, 0x2B, 0x07, 0xA5, 0xD9, 0x6C, 0x79, 0x54, 0x76, 0x6C, 0x9D, + 0x1C, 0xA6, 0x6E, 0x0E, 0xE9, 0x79, 0x0C, 0xA8, 0x23, 0x6A, 0xA3, 0xDF, + 0x1B, 0x30, 0x31, 0x9F, 0xB1, 0x54, 0x7B, 0xFE, 0x6A, 0xCB, 0x66, 0xAA, + 0xDC, 0x65, 0xD0, 0xA2, 0x9E, 0x4A, 0x9A, 0x07, 0x21, 0x6B, 0x81, 0x8F, + 0xDB, 0xC4, 0x59, 0xFA, 0xDE, 0x22, 0xC0, 0x04, 0x9C, 0xE3, 0xAA, 0x5B, + 0x36, 0x93, 0xE8, 0x3D, 0xBD, 0x7A, 0xA1, 0x9D, 0x0B, 0x76, 0xB1, 0x0B, + 0xC7, 0x9D, 0xFD, 0xCF, 0x98, 0xA8, 0x06, 0xC2, 0xF8, 0x2A, 0xA3, 0xA1, + 0x83, 0xA0, 0xB7, 0x25, 0x72, 0xA5, 0x02, 0xE3 +}; + +static const unsigned char TA676_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA677_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x41, 0x54, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x65, 0x2D, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x72, 0x63, 0x65, + 0x20, 0x6D, 0x6F, 0x6E, 0x69, 0x74, 0x6F, 0x72, 0x69, 0x6E, 0x67, 0x20, + 0x47, 0x6D, 0x62, 0x48, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x10, 0x47, 0x4C, 0x4F, 0x42, 0x41, 0x4C, 0x54, 0x52, 0x55, + 0x53, 0x54, 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA677_RSA_N[] = { + 0xAE, 0x2E, 0x56, 0xAD, 0x1B, 0x1C, 0xEF, 0xF6, 0x95, 0x8F, 0xA0, 0x77, + 0x1B, 0x2B, 0xD3, 0x63, 0x8F, 0x84, 0x4D, 0x45, 0xA2, 0x0F, 0x9F, 0x5B, + 0x45, 0xAB, 0x59, 0x7B, 0x51, 0x34, 0xF9, 0xEC, 0x8B, 0x8A, 0x78, 0xC5, + 0xDD, 0x6B, 0xAF, 0xBD, 0xC4, 0xDF, 0x93, 0x45, 0x1E, 0xBF, 0x91, 0x38, + 0x0B, 0xAE, 0x0E, 0x16, 0xE7, 0x41, 0x73, 0xF8, 0xDB, 0xBB, 0xD1, 0xB8, + 0x51, 0xE0, 0xCB, 0x83, 0x3B, 0x73, 0x38, 0x6E, 0x77, 0x8A, 0x0F, 0x59, + 0x63, 0x26, 0xCD, 0xA7, 0x2A, 0xCE, 0x54, 0xFB, 0xB8, 0xE2, 0xC0, 0x7C, + 0x47, 0xCE, 0x60, 0x7C, 0x3F, 0xB2, 0x73, 0xF2, 0xC0, 0x19, 0xB6, 0x8A, + 0x92, 0x87, 0x35, 0x0D, 0x90, 0x28, 0xA2, 0xE4, 0x15, 0x04, 0x63, 0x3E, + 0xBA, 0xAF, 0xEE, 0x7C, 0x5E, 0xCC, 0xA6, 0x8B, 0x50, 0xB2, 0x38, 0xF7, + 0x41, 0x63, 0xCA, 0xCE, 0xFF, 0x69, 0x8F, 0x68, 0x0E, 0x95, 0x36, 0xE5, + 0xCC, 0xB9, 0x8C, 0x09, 0xCA, 0x4B, 0xDD, 0x31, 0x90, 0x96, 0xC8, 0xCC, + 0x1F, 0xFD, 0x56, 0x96, 0x34, 0xDB, 0x8E, 0x1C, 0xEA, 0x2C, 0xBE, 0x85, + 0x2E, 0x63, 0xDD, 0xAA, 0xA9, 0x95, 0xD3, 0xFD, 0x29, 0x95, 0x13, 0xF0, + 0xC8, 0x98, 0x93, 0xD9, 0x2D, 0x16, 0x47, 0x90, 0x11, 0x83, 0xA2, 0x3A, + 0x22, 0xA2, 0x28, 0x57, 0xA2, 0xEB, 0xFE, 0xC0, 0x8C, 0x28, 0xA0, 0xA6, + 0x7D, 0xE7, 0x2A, 0x42, 0x3B, 0x82, 0x80, 0x63, 0xA5, 0x63, 0x1F, 0x19, + 0xCC, 0x7C, 0xB2, 0x66, 0xA8, 0xC2, 0xD3, 0x6D, 0x37, 0x6F, 0xE2, 0x7E, + 0x06, 0x51, 0xD9, 0x45, 0x84, 0x1F, 0x12, 0xCE, 0x24, 0x52, 0x64, 0x85, + 0x0B, 0x48, 0x80, 0x4E, 0x87, 0xB1, 0x22, 0x22, 0x30, 0xAA, 0xEB, 0xAE, + 0xBE, 0xE0, 0x02, 0xE0, 0x40, 0xE8, 0xB0, 0x42, 0x80, 0x03, 0x51, 0xAA, + 0xB4, 0x7E, 0xAA, 0x44, 0xD7, 0x43, 0x61, 0xF3, 0xA2, 0x6B, 0x16, 0x89, + 0x49, 0xA4, 0xA3, 0xA4, 0x2B, 0x8A, 0x02, 0xC4, 0x78, 0xF4, 0x68, 0x8A, + 0xC1, 0xE4, 0x7A, 0x36, 0xB1, 0x6F, 0x1B, 0x96, 0x1B, 0x77, 0x49, 0x8D, + 0xD4, 0xC9, 0x06, 0x72, 0x8F, 0xCF, 0x53, 0xE3, 0xDC, 0x17, 0x85, 0x20, + 0x4A, 0xDC, 0x98, 0x27, 0xD3, 0x91, 0x26, 0x2B, 0x47, 0x1E, 0x69, 0x07, + 0xAF, 0xDE, 0xA2, 0xE4, 0xE4, 0xD4, 0x6B, 0x0B, 0xB3, 0x5E, 0x7C, 0xD4, + 0x24, 0x80, 0x47, 0x29, 0x69, 0x3B, 0x6E, 0xE8, 0xAC, 0xFD, 0x40, 0xEB, + 0xD8, 0xED, 0x71, 0x71, 0x2B, 0xF2, 0xE8, 0x58, 0x1D, 0xEB, 0x41, 0x97, + 0x22, 0xC5, 0x1F, 0xD4, 0x39, 0xD0, 0x27, 0x8F, 0x87, 0xE3, 0x18, 0xF4, + 0xE0, 0xA9, 0x46, 0x0D, 0xF5, 0x74, 0x3A, 0x82, 0x2E, 0xD0, 0x6E, 0x2C, + 0x91, 0xA3, 0x31, 0x5C, 0x3B, 0x46, 0xEA, 0x7B, 0x04, 0x10, 0x56, 0x5E, + 0x80, 0x1D, 0xF5, 0xA5, 0x65, 0xE8, 0x82, 0xFC, 0xE2, 0x07, 0x8C, 0x62, + 0x45, 0xF5, 0x20, 0xDE, 0x46, 0x70, 0x86, 0xA1, 0xBC, 0x93, 0xD3, 0x1E, + 0x74, 0xA6, 0x6C, 0xB0, 0x2C, 0xF7, 0x03, 0x0C, 0x88, 0x0C, 0xCB, 0xD4, + 0x72, 0x53, 0x86, 0xBC, 0x60, 0x46, 0xF3, 0x98, 0x6A, 0xC2, 0xF1, 0xBF, + 0x43, 0xF9, 0x70, 0x20, 0x77, 0xCA, 0x37, 0x41, 0x79, 0x55, 0x52, 0x63, + 0x8D, 0x5B, 0x12, 0x9F, 0xC5, 0x68, 0xC4, 0x88, 0x9D, 0xAC, 0xF2, 0x30, + 0xAB, 0xB7, 0xA3, 0x31, 0x97, 0x67, 0xAD, 0x8F, 0x17, 0x0F, 0x6C, 0xC7, + 0x73, 0xED, 0x24, 0x94, 0x6B, 0xC8, 0x83, 0x9A, 0xD0, 0x9A, 0x37, 0x49, + 0x04, 0xAB, 0xB1, 0x16, 0xC8, 0x6C, 0x49, 0x49, 0x2D, 0xAB, 0xA1, 0xD0, + 0x8C, 0x92, 0xF2, 0x41, 0x4A, 0x79, 0x21, 0x25, 0xDB, 0x63, 0xD7, 0xB6, + 0x9C, 0xA7, 0x7E, 0x42, 0x69, 0xFB, 0x3A, 0x63 +}; + +static const unsigned char TA677_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA678_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x18, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, + 0x64, 0x79, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x2C, 0x20, 0x49, 0x6E, + 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x28, 0x47, 0x6F, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6C, + 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA678_RSA_N[] = { + 0xDE, 0x9D, 0xD7, 0xEA, 0x57, 0x18, 0x49, 0xA1, 0x5B, 0xEB, 0xD7, 0x5F, + 0x48, 0x86, 0xEA, 0xBE, 0xDD, 0xFF, 0xE4, 0xEF, 0x67, 0x1C, 0xF4, 0x65, + 0x68, 0xB3, 0x57, 0x71, 0xA0, 0x5E, 0x77, 0xBB, 0xED, 0x9B, 0x49, 0xE9, + 0x70, 0x80, 0x3D, 0x56, 0x18, 0x63, 0x08, 0x6F, 0xDA, 0xF2, 0xCC, 0xD0, + 0x3F, 0x7F, 0x02, 0x54, 0x22, 0x54, 0x10, 0xD8, 0xB2, 0x81, 0xD4, 0xC0, + 0x75, 0x3D, 0x4B, 0x7F, 0xC7, 0x77, 0xC3, 0x3E, 0x78, 0xAB, 0x1A, 0x03, + 0xB5, 0x20, 0x6B, 0x2F, 0x6A, 0x2B, 0xB1, 0xC5, 0x88, 0x7E, 0xC4, 0xBB, + 0x1E, 0xB0, 0xC1, 0xD8, 0x45, 0x27, 0x6F, 0xAA, 0x37, 0x58, 0xF7, 0x87, + 0x26, 0xD7, 0xD8, 0x2D, 0xF6, 0xA9, 0x17, 0xB7, 0x1F, 0x72, 0x36, 0x4E, + 0xA6, 0x17, 0x3F, 0x65, 0x98, 0x92, 0xDB, 0x2A, 0x6E, 0x5D, 0xA2, 0xFE, + 0x88, 0xE0, 0x0B, 0xDE, 0x7F, 0xE5, 0x8D, 0x15, 0xE1, 0xEB, 0xCB, 0x3A, + 0xD5, 0xE2, 0x12, 0xA2, 0x13, 0x2D, 0xD8, 0x8E, 0xAF, 0x5F, 0x12, 0x3D, + 0xA0, 0x08, 0x05, 0x08, 0xB6, 0x5C, 0xA5, 0x65, 0x38, 0x04, 0x45, 0x99, + 0x1E, 0xA3, 0x60, 0x60, 0x74, 0xC5, 0x41, 0xA5, 0x72, 0x62, 0x1B, 0x62, + 0xC5, 0x1F, 0x6F, 0x5F, 0x1A, 0x42, 0xBE, 0x02, 0x51, 0x65, 0xA8, 0xAE, + 0x23, 0x18, 0x6A, 0xFC, 0x78, 0x03, 0xA9, 0x4D, 0x7F, 0x80, 0xC3, 0xFA, + 0xAB, 0x5A, 0xFC, 0xA1, 0x40, 0xA4, 0xCA, 0x19, 0x16, 0xFE, 0xB2, 0xC8, + 0xEF, 0x5E, 0x73, 0x0D, 0xEE, 0x77, 0xBD, 0x9A, 0xF6, 0x79, 0x98, 0xBC, + 0xB1, 0x07, 0x67, 0xA2, 0x15, 0x0D, 0xDD, 0xA0, 0x58, 0xC6, 0x44, 0x7B, + 0x0A, 0x3E, 0x62, 0x28, 0x5F, 0xBA, 0x41, 0x07, 0x53, 0x58, 0xCF, 0x11, + 0x7E, 0x38, 0x74, 0xC5, 0xF8, 0xFF, 0xB5, 0x69, 0x90, 0x8F, 0x84, 0x74, + 0xEA, 0x97, 0x1B, 0xAF +}; + +static const unsigned char TA678_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA679_DN[] = { + 0x30, 0x81, 0x83, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x1A, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, 0x47, 0x6F, 0x44, 0x61, 0x64, 0x64, + 0x79, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, + 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6F, + 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA679_RSA_N[] = { + 0xBF, 0x71, 0x62, 0x08, 0xF1, 0xFA, 0x59, 0x34, 0xF7, 0x1B, 0xC9, 0x18, + 0xA3, 0xF7, 0x80, 0x49, 0x58, 0xE9, 0x22, 0x83, 0x13, 0xA6, 0xC5, 0x20, + 0x43, 0x01, 0x3B, 0x84, 0xF1, 0xE6, 0x85, 0x49, 0x9F, 0x27, 0xEA, 0xF6, + 0x84, 0x1B, 0x4E, 0xA0, 0xB4, 0xDB, 0x70, 0x98, 0xC7, 0x32, 0x01, 0xB1, + 0x05, 0x3E, 0x07, 0x4E, 0xEE, 0xF4, 0xFA, 0x4F, 0x2F, 0x59, 0x30, 0x22, + 0xE7, 0xAB, 0x19, 0x56, 0x6B, 0xE2, 0x80, 0x07, 0xFC, 0xF3, 0x16, 0x75, + 0x80, 0x39, 0x51, 0x7B, 0xE5, 0xF9, 0x35, 0xB6, 0x74, 0x4E, 0xA9, 0x8D, + 0x82, 0x13, 0xE4, 0xB6, 0x3F, 0xA9, 0x03, 0x83, 0xFA, 0xA2, 0xBE, 0x8A, + 0x15, 0x6A, 0x7F, 0xDE, 0x0B, 0xC3, 0xB6, 0x19, 0x14, 0x05, 0xCA, 0xEA, + 0xC3, 0xA8, 0x04, 0x94, 0x3B, 0x46, 0x7C, 0x32, 0x0D, 0xF3, 0x00, 0x66, + 0x22, 0xC8, 0x8D, 0x69, 0x6D, 0x36, 0x8C, 0x11, 0x18, 0xB7, 0xD3, 0xB2, + 0x1C, 0x60, 0xB4, 0x38, 0xFA, 0x02, 0x8C, 0xCE, 0xD3, 0xDD, 0x46, 0x07, + 0xDE, 0x0A, 0x3E, 0xEB, 0x5D, 0x7C, 0xC8, 0x7C, 0xFB, 0xB0, 0x2B, 0x53, + 0xA4, 0x92, 0x62, 0x69, 0x51, 0x25, 0x05, 0x61, 0x1A, 0x44, 0x81, 0x8C, + 0x2C, 0xA9, 0x43, 0x96, 0x23, 0xDF, 0xAC, 0x3A, 0x81, 0x9A, 0x0E, 0x29, + 0xC5, 0x1C, 0xA9, 0xE9, 0x5D, 0x1E, 0xB6, 0x9E, 0x9E, 0x30, 0x0A, 0x39, + 0xCE, 0xF1, 0x88, 0x80, 0xFB, 0x4B, 0x5D, 0xCC, 0x32, 0xEC, 0x85, 0x62, + 0x43, 0x25, 0x34, 0x02, 0x56, 0x27, 0x01, 0x91, 0xB4, 0x3B, 0x70, 0x2A, + 0x3F, 0x6E, 0xB1, 0xE8, 0x9C, 0x88, 0x01, 0x7D, 0x9F, 0xD4, 0xF9, 0xDB, + 0x53, 0x6D, 0x60, 0x9D, 0xBF, 0x2C, 0xE7, 0x58, 0xAB, 0xB8, 0x5F, 0x46, + 0xFC, 0xCE, 0xC4, 0x1B, 0x03, 0x3C, 0x09, 0xEB, 0x49, 0x31, 0x5C, 0x69, + 0x46, 0xB3, 0xE0, 0x47 +}; + +static const unsigned char TA679_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA680_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x31 +}; + +static const unsigned char TA680_RSA_N[] = { + 0xB6, 0x11, 0x02, 0x8B, 0x1E, 0xE3, 0xA1, 0x77, 0x9B, 0x3B, 0xDC, 0xBF, + 0x94, 0x3E, 0xB7, 0x95, 0xA7, 0x40, 0x3C, 0xA1, 0xFD, 0x82, 0xF9, 0x7D, + 0x32, 0x06, 0x82, 0x71, 0xF6, 0xF6, 0x8C, 0x7F, 0xFB, 0xE8, 0xDB, 0xBC, + 0x6A, 0x2E, 0x97, 0x97, 0xA3, 0x8C, 0x4B, 0xF9, 0x2B, 0xF6, 0xB1, 0xF9, + 0xCE, 0x84, 0x1D, 0xB1, 0xF9, 0xC5, 0x97, 0xDE, 0xEF, 0xB9, 0xF2, 0xA3, + 0xE9, 0xBC, 0x12, 0x89, 0x5E, 0xA7, 0xAA, 0x52, 0xAB, 0xF8, 0x23, 0x27, + 0xCB, 0xA4, 0xB1, 0x9C, 0x63, 0xDB, 0xD7, 0x99, 0x7E, 0xF0, 0x0A, 0x5E, + 0xEB, 0x68, 0xA6, 0xF4, 0xC6, 0x5A, 0x47, 0x0D, 0x4D, 0x10, 0x33, 0xE3, + 0x4E, 0xB1, 0x13, 0xA3, 0xC8, 0x18, 0x6C, 0x4B, 0xEC, 0xFC, 0x09, 0x90, + 0xDF, 0x9D, 0x64, 0x29, 0x25, 0x23, 0x07, 0xA1, 0xB4, 0xD2, 0x3D, 0x2E, + 0x60, 0xE0, 0xCF, 0xD2, 0x09, 0x87, 0xBB, 0xCD, 0x48, 0xF0, 0x4D, 0xC2, + 0xC2, 0x7A, 0x88, 0x8A, 0xBB, 0xBA, 0xCF, 0x59, 0x19, 0xD6, 0xAF, 0x8F, + 0xB0, 0x07, 0xB0, 0x9E, 0x31, 0xF1, 0x82, 0xC1, 0xC0, 0xDF, 0x2E, 0xA6, + 0x6D, 0x6C, 0x19, 0x0E, 0xB5, 0xD8, 0x7E, 0x26, 0x1A, 0x45, 0x03, 0x3D, + 0xB0, 0x79, 0xA4, 0x94, 0x28, 0xAD, 0x0F, 0x7F, 0x26, 0xE5, 0xA8, 0x08, + 0xFE, 0x96, 0xE8, 0x3C, 0x68, 0x94, 0x53, 0xEE, 0x83, 0x3A, 0x88, 0x2B, + 0x15, 0x96, 0x09, 0xB2, 0xE0, 0x7A, 0x8C, 0x2E, 0x75, 0xD6, 0x9C, 0xEB, + 0xA7, 0x56, 0x64, 0x8F, 0x96, 0x4F, 0x68, 0xAE, 0x3D, 0x97, 0xC2, 0x84, + 0x8F, 0xC0, 0xBC, 0x40, 0xC0, 0x0B, 0x5C, 0xBD, 0xF6, 0x87, 0xB3, 0x35, + 0x6C, 0xAC, 0x18, 0x50, 0x7F, 0x84, 0xE0, 0x4C, 0xCD, 0x92, 0xD3, 0x20, + 0xE9, 0x33, 0xBC, 0x52, 0x99, 0xAF, 0x32, 0xB5, 0x29, 0xB3, 0x25, 0x2A, + 0xB4, 0x48, 0xF9, 0x72, 0xE1, 0xCA, 0x64, 0xF7, 0xE6, 0x82, 0x10, 0x8D, + 0xE8, 0x9D, 0xC2, 0x8A, 0x88, 0xFA, 0x38, 0x66, 0x8A, 0xFC, 0x63, 0xF9, + 0x01, 0xF9, 0x78, 0xFD, 0x7B, 0x5C, 0x77, 0xFA, 0x76, 0x87, 0xFA, 0xEC, + 0xDF, 0xB1, 0x0E, 0x79, 0x95, 0x57, 0xB4, 0xBD, 0x26, 0xEF, 0xD6, 0x01, + 0xD1, 0xEB, 0x16, 0x0A, 0xBB, 0x8E, 0x0B, 0xB5, 0xC5, 0xC5, 0x8A, 0x55, + 0xAB, 0xD3, 0xAC, 0xEA, 0x91, 0x4B, 0x29, 0xCC, 0x19, 0xA4, 0x32, 0x25, + 0x4E, 0x2A, 0xF1, 0x65, 0x44, 0xD0, 0x02, 0xCE, 0xAA, 0xCE, 0x49, 0xB4, + 0xEA, 0x9F, 0x7C, 0x83, 0xB0, 0x40, 0x7B, 0xE7, 0x43, 0xAB, 0xA7, 0x6C, + 0xA3, 0x8F, 0x7D, 0x89, 0x81, 0xFA, 0x4C, 0xA5, 0xFF, 0xD5, 0x8E, 0xC3, + 0xCE, 0x4B, 0xE0, 0xB5, 0xD8, 0xB3, 0x8E, 0x45, 0xCF, 0x76, 0xC0, 0xED, + 0x40, 0x2B, 0xFD, 0x53, 0x0F, 0xB0, 0xA7, 0xD5, 0x3B, 0x0D, 0xB1, 0x8A, + 0xA2, 0x03, 0xDE, 0x31, 0xAD, 0xCC, 0x77, 0xEA, 0x6F, 0x7B, 0x3E, 0xD6, + 0xDF, 0x91, 0x22, 0x12, 0xE6, 0xBE, 0xFA, 0xD8, 0x32, 0xFC, 0x10, 0x63, + 0x14, 0x51, 0x72, 0xDE, 0x5D, 0xD6, 0x16, 0x93, 0xBD, 0x29, 0x68, 0x33, + 0xEF, 0x3A, 0x66, 0xEC, 0x07, 0x8A, 0x26, 0xDF, 0x13, 0xD7, 0x57, 0x65, + 0x78, 0x27, 0xDE, 0x5E, 0x49, 0x14, 0x00, 0xA2, 0x00, 0x7F, 0x9A, 0xA8, + 0x21, 0xB6, 0xA9, 0xB1, 0x95, 0xB0, 0xA5, 0xB9, 0x0D, 0x16, 0x11, 0xDA, + 0xC7, 0x6C, 0x48, 0x3C, 0x40, 0xE0, 0x7E, 0x0D, 0x5A, 0xCD, 0x56, 0x3C, + 0xD1, 0x97, 0x05, 0xB9, 0xCB, 0x4B, 0xED, 0x39, 0x4B, 0x9C, 0xC4, 0x3F, + 0xD2, 0x55, 0x13, 0x6E, 0x24, 0xB0, 0xD6, 0x71, 0xFA, 0xF4, 0xC1, 0xBA, + 0xCC, 0xED, 0x1B, 0xF5, 0xFE, 0x81, 0x41, 0xD8, 0x00, 0x98, 0x3D, 0x3A, + 0xC8, 0xAE, 0x7A, 0x98, 0x37, 0x18, 0x05, 0x95 +}; + +static const unsigned char TA680_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA681_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA681_RSA_N[] = { + 0xCE, 0xDE, 0xFD, 0xA6, 0xFB, 0xEC, 0xEC, 0x14, 0x34, 0x3C, 0x07, 0x06, + 0x5A, 0x6C, 0x59, 0xF7, 0x19, 0x35, 0xDD, 0xF7, 0xC1, 0x9D, 0x55, 0xAA, + 0xD3, 0xCD, 0x3B, 0xA4, 0x93, 0x72, 0xEF, 0x0A, 0xFA, 0x6D, 0x9D, 0xF6, + 0xF0, 0x85, 0x80, 0x5B, 0xA1, 0x48, 0x52, 0x9F, 0x39, 0xC5, 0xB7, 0xEE, + 0x28, 0xAC, 0xEF, 0xCB, 0x76, 0x68, 0x14, 0xB9, 0xDF, 0xAD, 0x01, 0x6C, + 0x99, 0x1F, 0xC4, 0x22, 0x1D, 0x9F, 0xFE, 0x72, 0x77, 0xE0, 0x2C, 0x5B, + 0xAF, 0xE4, 0x04, 0xBF, 0x4F, 0x72, 0xA0, 0x1A, 0x34, 0x98, 0xE8, 0x39, + 0x68, 0xEC, 0x95, 0x25, 0x7B, 0x76, 0xA1, 0xE6, 0x69, 0xB9, 0x85, 0x19, + 0xBD, 0x89, 0x8C, 0xFE, 0xAD, 0xED, 0x36, 0xEA, 0x73, 0xBC, 0xFF, 0x83, + 0xE2, 0xCB, 0x7D, 0xC1, 0xD2, 0xCE, 0x4A, 0xB3, 0x8D, 0x05, 0x9E, 0x8B, + 0x49, 0x93, 0xDF, 0xC1, 0x5B, 0xD0, 0x6E, 0x5E, 0xF0, 0x2E, 0x30, 0x2E, + 0x82, 0xFC, 0xFA, 0xBC, 0xB4, 0x17, 0x0A, 0x48, 0xE5, 0x88, 0x9B, 0xC5, + 0x9B, 0x6B, 0xDE, 0xB0, 0xCA, 0xB4, 0x03, 0xF0, 0xDA, 0xF4, 0x90, 0xB8, + 0x65, 0x64, 0xF7, 0x5C, 0x4C, 0xAD, 0xE8, 0x7E, 0x66, 0x5E, 0x99, 0xD7, + 0xB8, 0xC2, 0x3E, 0xC8, 0xD0, 0x13, 0x9D, 0xAD, 0xEE, 0xE4, 0x45, 0x7B, + 0x89, 0x55, 0xF7, 0x8A, 0x1F, 0x62, 0x52, 0x84, 0x12, 0xB3, 0xC2, 0x40, + 0x97, 0xE3, 0x8A, 0x1F, 0x47, 0x91, 0xA6, 0x74, 0x5A, 0xD2, 0xF8, 0xB1, + 0x63, 0x28, 0x10, 0xB8, 0xB3, 0x09, 0xB8, 0x56, 0x77, 0x40, 0xA2, 0x26, + 0x98, 0x79, 0xC6, 0xFE, 0xDF, 0x25, 0xEE, 0x3E, 0xE5, 0xA0, 0x7F, 0xD4, + 0x61, 0x0F, 0x51, 0x4B, 0x3C, 0x3F, 0x8C, 0xDA, 0xE1, 0x70, 0x74, 0xD8, + 0xC2, 0x68, 0xA1, 0xF9, 0xC1, 0x0C, 0xE9, 0xA1, 0xE2, 0x7F, 0xBB, 0x55, + 0x3C, 0x76, 0x06, 0xEE, 0x6A, 0x4E, 0xCC, 0x92, 0x88, 0x30, 0x4D, 0x9A, + 0xBD, 0x4F, 0x0B, 0x48, 0x9A, 0x84, 0xB5, 0x98, 0xA3, 0xD5, 0xFB, 0x73, + 0xC1, 0x57, 0x61, 0xDD, 0x28, 0x56, 0x75, 0x13, 0xAE, 0x87, 0x8E, 0xE7, + 0x0C, 0x51, 0x09, 0x10, 0x75, 0x88, 0x4C, 0xBC, 0x8D, 0xF9, 0x7B, 0x3C, + 0xD4, 0x22, 0x48, 0x1F, 0x2A, 0xDC, 0xEB, 0x6B, 0xBB, 0x44, 0xB1, 0xCB, + 0x33, 0x71, 0x32, 0x46, 0xAF, 0xAD, 0x4A, 0xF1, 0x8C, 0xE8, 0x74, 0x3A, + 0xAC, 0xE7, 0x1A, 0x22, 0x73, 0x80, 0xD2, 0x30, 0xF7, 0x25, 0x42, 0xC7, + 0x22, 0x3B, 0x3B, 0x12, 0xAD, 0x96, 0x2E, 0xC6, 0xC3, 0x76, 0x07, 0xAA, + 0x20, 0xB7, 0x35, 0x49, 0x57, 0xE9, 0x92, 0x49, 0xE8, 0x76, 0x16, 0x72, + 0x31, 0x67, 0x2B, 0x96, 0x7E, 0x8A, 0xA3, 0xC7, 0x94, 0x56, 0x22, 0xBF, + 0x6A, 0x4B, 0x7E, 0x01, 0x21, 0xB2, 0x23, 0x32, 0xDF, 0xE4, 0x9A, 0x44, + 0x6D, 0x59, 0x5B, 0x5D, 0xF5, 0x00, 0xA0, 0x1C, 0x9B, 0xC6, 0x78, 0x97, + 0x8D, 0x90, 0xFF, 0x9B, 0xC8, 0xAA, 0xB4, 0xAF, 0x11, 0x51, 0x39, 0x5E, + 0xD9, 0xFB, 0x67, 0xAD, 0xD5, 0x5B, 0x11, 0x9D, 0x32, 0x9A, 0x1B, 0xBD, + 0xD5, 0xBA, 0x5B, 0xA5, 0xC9, 0xCB, 0x25, 0x69, 0x53, 0x55, 0x27, 0x5C, + 0xE0, 0xCA, 0x36, 0xCB, 0x88, 0x61, 0xFB, 0x1E, 0xB7, 0xD0, 0xCB, 0xEE, + 0x16, 0xFB, 0xD3, 0xA6, 0x4C, 0xDE, 0x92, 0xA5, 0xD4, 0xE2, 0xDF, 0xF5, + 0x06, 0x54, 0xDE, 0x2E, 0x9D, 0x4B, 0xB4, 0x93, 0x30, 0xAA, 0x81, 0xCE, + 0xDD, 0x1A, 0xDC, 0x51, 0x73, 0x0D, 0x4F, 0x70, 0xE9, 0xE5, 0xB6, 0x16, + 0x21, 0x19, 0x79, 0xB2, 0xE6, 0x89, 0x0B, 0x75, 0x64, 0xCA, 0xD5, 0xAB, + 0xBC, 0x09, 0xC1, 0x18, 0xA1, 0xFF, 0xD4, 0x54, 0xA1, 0x85, 0x3C, 0xFD, + 0x14, 0x24, 0x03, 0xB2, 0x87, 0xD3, 0xA4, 0xB7 +}; + +static const unsigned char TA681_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA682_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x33 +}; + +static const unsigned char TA682_EC_Q[] = { + 0x04, 0x1F, 0x4F, 0x33, 0x87, 0x33, 0x29, 0x8A, 0xA1, 0x84, 0xDE, 0xCB, + 0xC7, 0x21, 0x58, 0x41, 0x89, 0xEA, 0x56, 0x9D, 0x2B, 0x4B, 0x85, 0xC6, + 0x1D, 0x4C, 0x27, 0xBC, 0x7F, 0x26, 0x51, 0x72, 0x6F, 0xE2, 0x9F, 0xD6, + 0xA3, 0xCA, 0xCC, 0x45, 0x14, 0x46, 0x8B, 0xAD, 0xEF, 0x7E, 0x86, 0x8C, + 0xEC, 0xB1, 0x7E, 0x2F, 0xFF, 0xA9, 0x71, 0x9D, 0x18, 0x84, 0x45, 0x04, + 0x41, 0x55, 0x6E, 0x2B, 0xEA, 0x26, 0x7F, 0xBB, 0x90, 0x01, 0xE3, 0x4B, + 0x19, 0xBA, 0xE4, 0x54, 0x96, 0x45, 0x09, 0xB1, 0xD5, 0x6C, 0x91, 0x44, + 0xAD, 0x84, 0x13, 0x8E, 0x9A, 0x8C, 0x0D, 0x80, 0x0C, 0x32, 0xF6, 0xE0, + 0x27 +}; + +static const unsigned char TA683_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x19, 0x47, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x4C, 0x4C, 0x43, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0B, 0x47, 0x54, 0x53, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, + 0x34 +}; + +static const unsigned char TA683_EC_Q[] = { + 0x04, 0xF3, 0x74, 0x73, 0xA7, 0x68, 0x8B, 0x60, 0xAE, 0x43, 0xB8, 0x35, + 0xC5, 0x81, 0x30, 0x7B, 0x4B, 0x49, 0x9D, 0xFB, 0xC1, 0x61, 0xCE, 0xE6, + 0xDE, 0x46, 0xBD, 0x6B, 0xD5, 0x61, 0x18, 0x35, 0xAE, 0x40, 0xDD, 0x73, + 0xF7, 0x89, 0x91, 0x30, 0x5A, 0xEB, 0x3C, 0xEE, 0x85, 0x7C, 0xA2, 0x40, + 0x76, 0x3B, 0xA9, 0xC6, 0xB8, 0x47, 0xD8, 0x2A, 0xE7, 0x92, 0x91, 0x6A, + 0x73, 0xE9, 0xB1, 0x72, 0x39, 0x9F, 0x29, 0x9F, 0xA2, 0x98, 0xD3, 0x5F, + 0x5E, 0x58, 0x86, 0x65, 0x0F, 0xA1, 0x84, 0x65, 0x06, 0xD1, 0xDC, 0x8B, + 0xC9, 0xC7, 0x73, 0xC8, 0x8C, 0x6A, 0x2F, 0xE5, 0xC4, 0xAB, 0xD1, 0x1D, + 0x8A +}; + +static const unsigned char TA684_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, + 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA684_EC_Q[] = { + 0x04, 0x38, 0x08, 0xFE, 0xB1, 0xA0, 0x96, 0xD2, 0x7A, 0xAC, 0xAF, 0x49, + 0x3A, 0xD0, 0xC0, 0xE0, 0xC3, 0x3B, 0x28, 0xAA, 0xF1, 0x72, 0x6D, 0x65, + 0x00, 0x47, 0x88, 0x84, 0xFC, 0x9A, 0x26, 0x6B, 0xAA, 0x4B, 0xBA, 0x6C, + 0x04, 0x0A, 0x88, 0x5E, 0x17, 0xF2, 0x55, 0x87, 0xFC, 0x30, 0xB0, 0x34, + 0xE2, 0x34, 0x58, 0x57, 0x1A, 0x84, 0x53, 0xE9, 0x30, 0xD9, 0xA9, 0xF2, + 0x96, 0x74, 0xC3, 0x51, 0x1F, 0x58, 0x49, 0x31, 0xCC, 0x98, 0x4E, 0x60, + 0x11, 0x87, 0x75, 0xD3, 0x72, 0x94, 0x90, 0x4F, 0x9B, 0x10, 0x25, 0x2A, + 0xA8, 0x78, 0x2D, 0xBE, 0x90, 0x41, 0x58, 0x90, 0x15, 0x72, 0xA7, 0xA1, + 0xB7 +}; + +static const unsigned char TA685_DN[] = { + 0x30, 0x6C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x52, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, + 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, + 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, + 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x41, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x48, + 0x41, 0x52, 0x49, 0x43, 0x41, 0x20, 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, + 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, + 0x32, 0x31 +}; + +static const unsigned char TA685_RSA_N[] = { + 0x8B, 0xC2, 0xE7, 0xAF, 0x65, 0x9B, 0x05, 0x67, 0x96, 0xC9, 0x0D, 0x24, + 0xB9, 0xD0, 0x0E, 0x64, 0xFC, 0xCE, 0xE2, 0x24, 0x18, 0x2C, 0x84, 0x7F, + 0x77, 0x51, 0xCB, 0x04, 0x11, 0x36, 0xB8, 0x5E, 0xED, 0x69, 0x71, 0xA7, + 0x9E, 0xE4, 0x25, 0x09, 0x97, 0x67, 0xC1, 0x47, 0xC2, 0xCF, 0x91, 0x16, + 0x36, 0x62, 0x3D, 0x38, 0x04, 0xE1, 0x51, 0x82, 0xFF, 0xAC, 0xD2, 0xB4, + 0x69, 0xDD, 0x2E, 0xEC, 0x11, 0xA3, 0x45, 0xEE, 0x6B, 0x6B, 0x3B, 0x4C, + 0xBF, 0x8C, 0x8D, 0xA4, 0x1E, 0x9D, 0x11, 0xB9, 0xE9, 0x38, 0xF9, 0x7A, + 0x0E, 0x0C, 0x98, 0xE2, 0x23, 0x1D, 0xD1, 0x4E, 0x63, 0xD4, 0xE7, 0xB8, + 0x41, 0x44, 0xFB, 0x6B, 0xAF, 0x6B, 0xDA, 0x1F, 0xD3, 0xC5, 0x91, 0x88, + 0x5B, 0xA4, 0x89, 0x92, 0xD1, 0x81, 0xE6, 0x8C, 0x39, 0x58, 0xA0, 0xD6, + 0x69, 0x43, 0xA9, 0xAD, 0x98, 0x52, 0x58, 0x6E, 0xDB, 0x0A, 0xFB, 0x6B, + 0xCF, 0x68, 0xFA, 0xE3, 0xA4, 0x5E, 0x3A, 0x45, 0x73, 0x98, 0x07, 0xEA, + 0x5F, 0x02, 0x72, 0xDE, 0x0C, 0xA5, 0xB3, 0x9F, 0xAE, 0xA9, 0x1D, 0xB7, + 0x1D, 0xB3, 0xFC, 0x8A, 0x59, 0xE7, 0x6E, 0x72, 0x65, 0xAD, 0xF5, 0x30, + 0x94, 0x23, 0x07, 0xF3, 0x82, 0x16, 0x4B, 0x35, 0x98, 0x9C, 0x53, 0xBB, + 0x2F, 0xCA, 0xE4, 0x5A, 0xD9, 0xC7, 0x8D, 0x1D, 0xFC, 0x98, 0x99, 0xFB, + 0x2C, 0xA4, 0x82, 0x6B, 0xF0, 0x2A, 0x1F, 0x8E, 0x0B, 0x5F, 0x71, 0x5C, + 0x5C, 0xAE, 0x42, 0x7B, 0x29, 0x89, 0x81, 0xCB, 0x03, 0xA3, 0x99, 0xCA, + 0x88, 0x9E, 0x0B, 0x40, 0x09, 0x41, 0x33, 0xDB, 0xE6, 0x58, 0x7A, 0xFD, + 0xAE, 0x99, 0x70, 0xC0, 0x5A, 0x0F, 0xD6, 0x13, 0x86, 0x71, 0x2F, 0x76, + 0x69, 0xFC, 0x90, 0xDD, 0xDB, 0x2D, 0x6E, 0xD1, 0xF2, 0x9B, 0xF5, 0x1A, + 0x6B, 0x9E, 0x6F, 0x15, 0x8C, 0x7A, 0xF0, 0x4B, 0x28, 0xA0, 0x22, 0x38, + 0x80, 0x24, 0x6C, 0x36, 0xA4, 0x3B, 0xF2, 0x30, 0x91, 0xF3, 0x78, 0x13, + 0xCF, 0xC1, 0x3F, 0x35, 0xAB, 0xF1, 0x1D, 0x11, 0x23, 0xB5, 0x43, 0x22, + 0x9E, 0x01, 0x92, 0xB7, 0x18, 0x02, 0xE5, 0x11, 0xD1, 0x82, 0xDB, 0x15, + 0x00, 0xCC, 0x61, 0x37, 0xC1, 0x2A, 0x7C, 0x9A, 0xE1, 0xD0, 0xBA, 0xB3, + 0x50, 0x46, 0xEE, 0x82, 0xAC, 0x9D, 0x31, 0xF8, 0xFB, 0x23, 0xE2, 0x03, + 0x00, 0x48, 0x70, 0xA3, 0x09, 0x26, 0x79, 0x15, 0x53, 0x60, 0xF3, 0x38, + 0x5C, 0xAD, 0x38, 0xEA, 0x81, 0x00, 0x63, 0x14, 0xB9, 0x33, 0x5E, 0xDD, + 0x0B, 0xDB, 0xA0, 0x45, 0x07, 0x1A, 0x33, 0x09, 0xF8, 0x4D, 0xB4, 0xA7, + 0x02, 0xA6, 0x69, 0xF4, 0xC2, 0x59, 0x05, 0x88, 0x65, 0x85, 0x56, 0xAE, + 0x4B, 0xCB, 0xE0, 0xDE, 0x3C, 0x7D, 0x2D, 0x1A, 0xC8, 0xE9, 0xFB, 0x1F, + 0xA3, 0x61, 0x4A, 0xD6, 0x2A, 0x13, 0xAD, 0x77, 0x4C, 0x1A, 0x18, 0x9B, + 0x91, 0x0F, 0x58, 0xD8, 0x06, 0x54, 0xC5, 0x97, 0xF8, 0xAA, 0x3F, 0x20, + 0x8A, 0xA6, 0x85, 0xA6, 0x77, 0xF6, 0xA6, 0xFC, 0x1C, 0xE2, 0xEE, 0x6E, + 0x94, 0x33, 0x2A, 0x83, 0x50, 0x84, 0x0A, 0xE5, 0x4F, 0x86, 0xF8, 0x50, + 0x45, 0x78, 0x00, 0x81, 0xEB, 0x5B, 0x68, 0xE3, 0x26, 0x8D, 0xCC, 0x7B, + 0x5C, 0x51, 0xF4, 0x14, 0x2C, 0x40, 0xBE, 0x1A, 0x60, 0x1D, 0x7A, 0x72, + 0x61, 0x1D, 0x1F, 0x63, 0x2D, 0x88, 0xAA, 0xCE, 0xA2, 0x45, 0x90, 0x08, + 0xFC, 0x6B, 0xBE, 0xB3, 0x50, 0x2A, 0x5A, 0xFD, 0xA8, 0x48, 0x18, 0x46, + 0xD6, 0x90, 0x40, 0x92, 0x90, 0x0A, 0x84, 0x5E, 0x68, 0x31, 0xF8, 0xEB, + 0xED, 0x0D, 0xD3, 0x1D, 0xC6, 0x7D, 0x99, 0x18, 0x55, 0x56, 0x27, 0x65, + 0x2E, 0x8D, 0x45, 0xC5, 0x24, 0xEC, 0xCE, 0xE3 +}; + +static const unsigned char TA685_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA686_DN[] = { + 0x30, 0x81, 0xAA, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x44, 0x30, 0x42, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, + 0x20, 0x32, 0x30, 0x31, 0x35 +}; + +static const unsigned char TA686_EC_Q[] = { + 0x04, 0x92, 0xA0, 0x41, 0xE8, 0x4B, 0x82, 0x84, 0x5C, 0xE2, 0xF8, 0x31, + 0x11, 0x99, 0x86, 0x64, 0x4E, 0x09, 0x25, 0x2F, 0x9D, 0x41, 0x2F, 0x0A, + 0xAE, 0x35, 0x4F, 0x74, 0x95, 0xB2, 0x51, 0x64, 0x6B, 0x8D, 0x6B, 0xE6, + 0x3F, 0x70, 0x95, 0xF0, 0x05, 0x44, 0x47, 0xA6, 0x72, 0x38, 0x50, 0x76, + 0x95, 0x02, 0x5A, 0x8E, 0xAE, 0x28, 0x9E, 0xF9, 0x2D, 0x4E, 0x99, 0xEF, + 0x2C, 0x48, 0x6F, 0x4C, 0x25, 0x29, 0xE8, 0xD1, 0x71, 0x5B, 0xDF, 0x1D, + 0xC1, 0x75, 0x37, 0xB4, 0xD7, 0xFA, 0x7B, 0x7A, 0x42, 0x9C, 0x6A, 0x0A, + 0x56, 0x5A, 0x7C, 0x69, 0x0B, 0xAA, 0x80, 0x09, 0x24, 0x6C, 0x7E, 0xC1, + 0x46 +}; + +static const unsigned char TA687_DN[] = { + 0x30, 0x81, 0xA6, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x47, 0x52, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x06, 0x41, 0x74, 0x68, 0x65, 0x6E, 0x73, 0x31, 0x44, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x3B, 0x48, 0x65, 0x6C, 0x6C, + 0x65, 0x6E, 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, + 0x63, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, + 0x6F, 0x6E, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x2E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x31, 0x40, 0x30, 0x3E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x37, 0x48, 0x65, 0x6C, 0x6C, 0x65, 0x6E, + 0x69, 0x63, 0x20, 0x41, 0x63, 0x61, 0x64, 0x65, 0x6D, 0x69, 0x63, 0x20, + 0x61, 0x6E, 0x64, 0x20, 0x52, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x20, 0x49, 0x6E, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x69, 0x6F, 0x6E, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, + 0x35 +}; + +static const unsigned char TA687_RSA_N[] = { + 0xC2, 0xF8, 0xA9, 0x3F, 0x1B, 0x89, 0xFC, 0x3C, 0x3C, 0x04, 0x5D, 0x3D, + 0x90, 0x36, 0xB0, 0x91, 0x3A, 0x79, 0x3C, 0x66, 0x5A, 0xEF, 0x6D, 0x39, + 0x01, 0x49, 0x1A, 0xB4, 0xB7, 0xCF, 0x7F, 0x4D, 0x23, 0x53, 0xB7, 0x90, + 0x00, 0xE3, 0x13, 0x2A, 0x28, 0xA6, 0x31, 0xF1, 0x91, 0x00, 0xE3, 0x28, + 0xEC, 0xAE, 0x21, 0x41, 0xCE, 0x1F, 0xDA, 0xFD, 0x7D, 0x12, 0x5B, 0x01, + 0x83, 0x0F, 0xB9, 0xB0, 0x5F, 0x99, 0xE1, 0xF2, 0x12, 0x83, 0x80, 0x4D, + 0x06, 0x3E, 0xDF, 0xAC, 0xAF, 0xE7, 0xA1, 0x88, 0x6B, 0x31, 0xAF, 0xF0, + 0x8B, 0xD0, 0x18, 0x33, 0xB8, 0xDB, 0x45, 0x6A, 0x34, 0xF4, 0x02, 0x80, + 0x24, 0x28, 0x0A, 0x02, 0x15, 0x95, 0x5E, 0x76, 0x2A, 0x0D, 0x99, 0x3A, + 0x14, 0x5B, 0xF6, 0xCB, 0xCB, 0x53, 0xBC, 0x13, 0x4D, 0x01, 0x88, 0x37, + 0x94, 0x25, 0x1B, 0x42, 0xBC, 0x22, 0xD8, 0x8E, 0xA3, 0x96, 0x5E, 0x3A, + 0xD9, 0x32, 0xDB, 0x3E, 0xE8, 0xF0, 0x10, 0x65, 0xED, 0x74, 0xE1, 0x2F, + 0xA7, 0x7C, 0xAF, 0x27, 0x34, 0xBB, 0x29, 0x7D, 0x9B, 0xB6, 0xCF, 0x09, + 0xC8, 0xE5, 0xD3, 0x0A, 0xFC, 0x88, 0x65, 0x65, 0x74, 0x0A, 0xDC, 0x73, + 0x1C, 0x5C, 0xCD, 0x40, 0xB1, 0x1C, 0xD4, 0xB6, 0x84, 0x8C, 0x4C, 0x50, + 0xCF, 0x68, 0x8E, 0xA8, 0x59, 0xAE, 0xC2, 0x27, 0x4E, 0x82, 0xA2, 0x35, + 0xDD, 0x14, 0xF4, 0x1F, 0xFF, 0xB2, 0x77, 0xD5, 0x87, 0x2F, 0xAA, 0x6E, + 0x7D, 0x24, 0x27, 0xE7, 0xC6, 0xCB, 0x26, 0xE6, 0xE5, 0xFE, 0x67, 0x07, + 0x63, 0xD8, 0x45, 0x0D, 0xDD, 0x3A, 0x59, 0x65, 0x39, 0x58, 0x7A, 0x92, + 0x99, 0x72, 0x3D, 0x9C, 0x84, 0x5E, 0x88, 0x21, 0xB8, 0xD5, 0xF4, 0x2C, + 0xFC, 0xD9, 0x70, 0x52, 0x4F, 0x78, 0xB8, 0xBD, 0x3C, 0x2B, 0x8B, 0x95, + 0x98, 0xF5, 0xB3, 0xD1, 0x68, 0xCF, 0x20, 0x14, 0x7E, 0x4C, 0x5C, 0x5F, + 0xE7, 0x8B, 0xE5, 0xF5, 0x35, 0x81, 0x19, 0x37, 0xD7, 0x11, 0x08, 0xB7, + 0x66, 0xBE, 0xD3, 0x4A, 0xCE, 0x83, 0x57, 0x00, 0x3A, 0xC3, 0x81, 0xF8, + 0x17, 0xCB, 0x92, 0x36, 0x5D, 0xD1, 0xA3, 0xD8, 0x75, 0x1B, 0xE1, 0x8B, + 0x27, 0xEA, 0x7A, 0x48, 0x41, 0xFD, 0x45, 0x19, 0x06, 0xAD, 0x27, 0x99, + 0x4E, 0xC1, 0x70, 0x47, 0xDD, 0xB5, 0x9F, 0x81, 0x53, 0x12, 0xE5, 0xB1, + 0x8C, 0x48, 0x5D, 0x31, 0x43, 0x17, 0xE3, 0x8C, 0xC6, 0x7A, 0x63, 0x96, + 0x4B, 0x29, 0x30, 0x4E, 0x84, 0x4E, 0x62, 0x19, 0x5E, 0x3C, 0xCE, 0x97, + 0x90, 0xA5, 0x7F, 0x01, 0xEB, 0x9D, 0xE0, 0xF8, 0x8B, 0x89, 0xDD, 0x25, + 0x98, 0x3D, 0x92, 0xB6, 0x7E, 0xEF, 0xD9, 0xF1, 0x51, 0x51, 0x7D, 0x2D, + 0x26, 0xC8, 0x69, 0x59, 0x61, 0xE0, 0xAC, 0x6A, 0xB8, 0x2A, 0x36, 0x11, + 0x04, 0x7A, 0x50, 0xBD, 0x32, 0x84, 0xBE, 0x2F, 0xDC, 0x72, 0xD5, 0xD7, + 0x1D, 0x16, 0x47, 0xE4, 0x47, 0x66, 0x20, 0x3F, 0xF4, 0x96, 0xC5, 0xAF, + 0x8E, 0x01, 0x7A, 0xA5, 0x0F, 0x7A, 0x64, 0xF5, 0x0D, 0x18, 0x87, 0xD9, + 0xAE, 0x88, 0xD5, 0xFA, 0x84, 0xC1, 0x3A, 0xC0, 0x69, 0x28, 0x2D, 0xF2, + 0x0D, 0x68, 0x51, 0xAA, 0xE3, 0xA5, 0x77, 0xC6, 0xA4, 0x90, 0x0E, 0xA1, + 0x37, 0x8B, 0x31, 0x23, 0x47, 0xC1, 0x09, 0x08, 0xEB, 0x6E, 0xF7, 0x78, + 0x9B, 0xD7, 0x82, 0xFC, 0x84, 0x20, 0x99, 0x49, 0x19, 0xB6, 0x12, 0x46, + 0xB1, 0xFB, 0x45, 0x55, 0x16, 0xA9, 0xA3, 0x65, 0xAC, 0x9C, 0x07, 0x0F, + 0xEA, 0x6B, 0xDC, 0x1F, 0x2E, 0x06, 0x72, 0xEC, 0x86, 0x88, 0x12, 0xE4, + 0x2D, 0xDB, 0x5F, 0x05, 0x2F, 0xE4, 0xF0, 0x03, 0xD3, 0x26, 0x33, 0xE7, + 0x80, 0xC2, 0xCD, 0x42, 0xA1, 0x17, 0x34, 0x0B +}; + +static const unsigned char TA687_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA688_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1A, 0x43, 0x68, 0x75, 0x6E, 0x67, 0x68, 0x77, 0x61, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x63, 0x6F, 0x6D, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x12, 0x48, 0x69, 0x50, 0x4B, 0x49, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x31 +}; + +static const unsigned char TA688_RSA_N[] = { + 0xF4, 0x1E, 0x7F, 0x52, 0x73, 0x32, 0x0C, 0x73, 0xE4, 0xBD, 0x13, 0x74, + 0xA3, 0xD4, 0x30, 0xA8, 0xD0, 0xAE, 0x4B, 0xD8, 0xB6, 0xDF, 0x75, 0x47, + 0x66, 0xF4, 0x7C, 0xE7, 0x39, 0x04, 0x1E, 0x6A, 0x70, 0x20, 0xD2, 0x5A, + 0x47, 0x72, 0x67, 0x55, 0xF4, 0xA5, 0xE8, 0x9D, 0xD5, 0x1E, 0x21, 0xA1, + 0xF0, 0x67, 0xBA, 0xCC, 0x21, 0x68, 0xBE, 0x44, 0x53, 0xBF, 0x8D, 0xF9, + 0xE2, 0xDC, 0x2F, 0x55, 0xC8, 0x37, 0x3F, 0x1F, 0xA4, 0xC0, 0x9C, 0xB3, + 0xE4, 0x77, 0x5C, 0xA0, 0x46, 0xFE, 0x77, 0xFA, 0x1A, 0xA0, 0x38, 0xEA, + 0xED, 0x9A, 0x72, 0xDE, 0x2B, 0xBD, 0x94, 0x57, 0x3A, 0xBA, 0xEC, 0x79, + 0xE7, 0x5F, 0x7D, 0x42, 0x64, 0x39, 0x7A, 0x26, 0x36, 0xF7, 0x24, 0xF0, + 0xD5, 0x2F, 0xBA, 0x95, 0x98, 0x11, 0x66, 0xAD, 0x97, 0x35, 0xD6, 0x75, + 0x01, 0x80, 0xE0, 0xAF, 0xF4, 0x84, 0x61, 0x8C, 0x0D, 0x1E, 0x5F, 0x7C, + 0x87, 0x96, 0x5E, 0x41, 0xAF, 0xEB, 0x87, 0xEA, 0xF8, 0x5D, 0xF1, 0x2E, + 0x88, 0x05, 0x3E, 0x4C, 0x22, 0xBB, 0xDA, 0x1F, 0x2A, 0xDD, 0x52, 0x46, + 0x64, 0x39, 0xF3, 0x42, 0xCE, 0xD9, 0x9E, 0x0C, 0xB3, 0xB0, 0x77, 0x97, + 0x64, 0x9C, 0xC0, 0xF4, 0xA3, 0x2E, 0x1F, 0x95, 0x07, 0xB0, 0x17, 0xDF, + 0x30, 0xDB, 0x00, 0x18, 0x96, 0x4C, 0xA1, 0x81, 0x4B, 0xDD, 0x04, 0x6D, + 0x53, 0xA3, 0x3D, 0xFC, 0x07, 0xAC, 0xD4, 0xC5, 0x37, 0x82, 0xEB, 0xE4, + 0x95, 0x08, 0x19, 0x28, 0x82, 0xD2, 0x42, 0x3A, 0xA3, 0xD8, 0x53, 0xEC, + 0x79, 0x89, 0x60, 0x48, 0x60, 0xC8, 0x72, 0x92, 0x50, 0xDC, 0x03, 0x8F, + 0x83, 0x3F, 0xB2, 0x42, 0x57, 0x5A, 0xDB, 0x6A, 0xE9, 0x11, 0x97, 0xDD, + 0x85, 0x28, 0xBC, 0x30, 0x4C, 0xAB, 0xE3, 0xC2, 0xB1, 0x45, 0x44, 0x47, + 0x1F, 0xE0, 0x8A, 0x16, 0x07, 0x96, 0xD2, 0x21, 0x0F, 0x53, 0xC0, 0xED, + 0xA9, 0x7E, 0xD4, 0x4E, 0xEC, 0x9B, 0x09, 0xEC, 0xAF, 0x42, 0xAC, 0x30, + 0xD6, 0xBF, 0xD1, 0x10, 0x45, 0xE0, 0xA6, 0x16, 0xB2, 0xA5, 0xC5, 0xD3, + 0x4F, 0x73, 0x94, 0x33, 0x71, 0x02, 0xA1, 0x6A, 0xA3, 0xD6, 0x33, 0x97, + 0x4F, 0x21, 0x63, 0x1E, 0x5B, 0x8F, 0xD9, 0xC1, 0x5E, 0x45, 0x71, 0x77, + 0x0F, 0x81, 0x5D, 0x5F, 0x21, 0x9A, 0xAD, 0x83, 0xCC, 0xFA, 0x5E, 0xD6, + 0x8D, 0x23, 0x5F, 0x1B, 0x3D, 0x41, 0xAF, 0x20, 0x75, 0x66, 0x5A, 0x4A, + 0xF6, 0x9F, 0xFB, 0xAB, 0x18, 0xF7, 0x71, 0xC0, 0xB6, 0x1D, 0x31, 0xEC, + 0x3B, 0x20, 0xEB, 0xCB, 0xE2, 0xB8, 0xF5, 0xAE, 0x92, 0xB2, 0xF7, 0xE1, + 0x84, 0x4B, 0xF2, 0xA2, 0xF2, 0x93, 0x9A, 0x22, 0x9E, 0xD3, 0x14, 0x6F, + 0x36, 0x54, 0xBD, 0x1F, 0x5E, 0x59, 0x15, 0xB9, 0x73, 0xA8, 0xC1, 0x7C, + 0x6F, 0x7B, 0x62, 0xE9, 0x16, 0x6C, 0x47, 0x5A, 0x65, 0xF3, 0x0E, 0x11, + 0x9B, 0x46, 0xD9, 0xFD, 0x6D, 0xDC, 0xD6, 0x9C, 0xC0, 0xB4, 0x7D, 0xA5, + 0xB0, 0xDD, 0x3F, 0x56, 0x6F, 0xA1, 0xF9, 0xF6, 0xE4, 0x12, 0x48, 0xFD, + 0x06, 0x7F, 0x12, 0x57, 0xB6, 0xA9, 0x23, 0x4F, 0x5B, 0x03, 0xC3, 0xE0, + 0x71, 0x2A, 0x23, 0xB7, 0xF7, 0xB0, 0xB1, 0x3B, 0xBC, 0x98, 0xBD, 0xD6, + 0x98, 0xA8, 0x0C, 0x6B, 0xF6, 0x8E, 0x12, 0x67, 0xA6, 0xF2, 0xB2, 0x58, + 0xE4, 0x02, 0x09, 0x13, 0x3C, 0xA9, 0xBB, 0x10, 0xB4, 0xD2, 0x30, 0x45, + 0xF1, 0xEC, 0xF7, 0x00, 0x11, 0xDF, 0x65, 0xF8, 0xDC, 0x2B, 0x43, 0x55, + 0xBF, 0x16, 0x97, 0xC4, 0x0F, 0xD5, 0x2C, 0x61, 0x84, 0xAA, 0x72, 0x86, + 0xFE, 0xE6, 0x3A, 0x7E, 0xC2, 0x3F, 0x7D, 0xEE, 0xFC, 0x2F, 0x14, 0x3E, + 0xE6, 0x85, 0xDD, 0x50, 0x6F, 0xB7, 0x49, 0xED +}; + +static const unsigned char TA688_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA689_DN[] = { + 0x30, 0x6F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x48, 0x4B, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x09, 0x48, 0x6F, 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x48, 0x6F, + 0x6E, 0x67, 0x20, 0x4B, 0x6F, 0x6E, 0x67, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x31, 0x20, 0x30, 0x1E, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x48, 0x6F, 0x6E, 0x67, 0x6B, 0x6F, + 0x6E, 0x67, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA689_RSA_N[] = { + 0xB3, 0x88, 0xD7, 0xEA, 0xCE, 0x0F, 0x20, 0x4E, 0xBE, 0xE6, 0xD6, 0x03, + 0x6D, 0xEE, 0x59, 0xFC, 0xC2, 0x57, 0xDF, 0x29, 0x68, 0xA1, 0x83, 0x0E, + 0x3E, 0x68, 0xC7, 0x68, 0x58, 0x9C, 0x1C, 0x60, 0x4B, 0x89, 0x43, 0x0C, + 0xB9, 0xD4, 0x15, 0xB2, 0xEE, 0xC1, 0x4E, 0x75, 0xE9, 0xB5, 0xA7, 0xEF, + 0xE5, 0xE9, 0x35, 0x99, 0xE4, 0xCC, 0x1C, 0xE7, 0x4B, 0x5F, 0x8D, 0x33, + 0x30, 0x20, 0x33, 0x53, 0xD9, 0xA6, 0xBB, 0xD5, 0x3E, 0x13, 0x8E, 0xE9, + 0x1F, 0x87, 0x49, 0xAD, 0x50, 0x2D, 0x50, 0xCA, 0x18, 0xBE, 0x01, 0x58, + 0xA2, 0x13, 0x70, 0x96, 0xBB, 0x89, 0x88, 0x56, 0x80, 0x5C, 0xF8, 0xBD, + 0x2C, 0x3C, 0xE1, 0x4C, 0x57, 0x88, 0xBB, 0xD3, 0xB9, 0x95, 0xEF, 0xCB, + 0xC7, 0xF6, 0xDA, 0x31, 0x74, 0x28, 0xA6, 0xE6, 0x54, 0x89, 0xF5, 0x41, + 0x31, 0xCA, 0xE5, 0x26, 0x1A, 0xCD, 0x82, 0xE0, 0x70, 0xDA, 0x3B, 0x29, + 0xBB, 0xD5, 0x03, 0xF5, 0x99, 0xBA, 0x55, 0xF5, 0x64, 0xD1, 0x60, 0x0E, + 0xB3, 0x89, 0x49, 0xB8, 0x8A, 0x2F, 0x05, 0xD2, 0x84, 0x45, 0x28, 0x7C, + 0x8F, 0x68, 0x50, 0x12, 0x78, 0xFC, 0x0B, 0xB5, 0x53, 0xCB, 0xC2, 0x98, + 0x1C, 0x84, 0xA3, 0x9E, 0xB0, 0xBE, 0x23, 0xA4, 0xDA, 0xDC, 0xC8, 0x2B, + 0x1E, 0xDA, 0x6E, 0x45, 0x1E, 0x89, 0x98, 0xDA, 0xF9, 0x00, 0x2E, 0x06, + 0xE9, 0x0C, 0x3B, 0x70, 0xD5, 0x50, 0x25, 0x88, 0x99, 0xCB, 0xCD, 0x73, + 0x60, 0xF7, 0xD5, 0xFF, 0x35, 0x67, 0xC5, 0xA1, 0xBC, 0x5E, 0xAB, 0xCD, + 0x4A, 0xB8, 0x45, 0xEB, 0xC8, 0x68, 0x1E, 0x0D, 0x0D, 0x14, 0x46, 0x12, + 0xE3, 0xD2, 0x64, 0x62, 0x8A, 0x42, 0x98, 0xBC, 0xB4, 0xC6, 0x08, 0x08, + 0xF8, 0xFD, 0xA8, 0x4C, 0x64, 0x9C, 0x76, 0x01, 0xBD, 0x2F, 0xA9, 0x6C, + 0x33, 0x0F, 0xD8, 0x3F, 0x28, 0xB8, 0x3C, 0x69, 0x01, 0x42, 0x86, 0x7E, + 0x69, 0xC1, 0xC9, 0x06, 0xCA, 0xE5, 0x7A, 0x46, 0x65, 0xE9, 0xC2, 0xD6, + 0x50, 0x41, 0x2E, 0x3F, 0xB7, 0xE4, 0xED, 0x6C, 0xD7, 0xBF, 0x26, 0x01, + 0x11, 0xA2, 0x16, 0x29, 0x4A, 0x6B, 0x34, 0x06, 0x90, 0xEC, 0x13, 0xD2, + 0xB6, 0xFB, 0x6A, 0x76, 0xD2, 0x3C, 0xED, 0xF0, 0xD6, 0x2D, 0xDD, 0xE1, + 0x15, 0xEC, 0xA3, 0x9B, 0x2F, 0x2C, 0xC9, 0x3E, 0x2B, 0xE4, 0x69, 0x3B, + 0xFF, 0x72, 0x25, 0xB1, 0x36, 0x86, 0x5B, 0xC7, 0x7F, 0x6B, 0x8B, 0x55, + 0x1B, 0x4A, 0xC5, 0x20, 0x61, 0x3D, 0xAE, 0xCB, 0x50, 0xE1, 0x08, 0x3A, + 0xBE, 0xB0, 0x8F, 0x63, 0x41, 0x53, 0x30, 0x08, 0x59, 0x3C, 0x98, 0x1D, + 0x77, 0xBA, 0x63, 0x91, 0x7A, 0xCA, 0x10, 0x50, 0x60, 0xBF, 0xF0, 0xD7, + 0xBC, 0x95, 0x87, 0x8F, 0x97, 0xC5, 0xFE, 0x97, 0x6A, 0x01, 0x94, 0xA3, + 0x7C, 0x5B, 0x85, 0x1D, 0x2A, 0x39, 0x3A, 0xD0, 0x54, 0xA1, 0xD1, 0x39, + 0x71, 0x9D, 0xFD, 0x21, 0xF9, 0xB5, 0x7B, 0xF0, 0xE2, 0xE0, 0x02, 0x8F, + 0x6E, 0x96, 0x24, 0x25, 0x2C, 0xA0, 0x1E, 0x2C, 0xA8, 0xC4, 0x89, 0xA7, + 0xEF, 0xED, 0x99, 0x06, 0x2F, 0xB6, 0x0A, 0x4C, 0x4F, 0xDB, 0xA2, 0xCC, + 0x37, 0x1A, 0xAF, 0x47, 0x85, 0x2D, 0x8A, 0x5F, 0xC4, 0x34, 0x34, 0x4C, + 0x00, 0xFD, 0x18, 0x93, 0x67, 0x13, 0xD1, 0x37, 0xE6, 0x48, 0xB4, 0x8B, + 0x06, 0xC5, 0x57, 0x7B, 0x19, 0x86, 0x0A, 0x79, 0xCB, 0x00, 0xC9, 0x52, + 0xAF, 0x42, 0xFF, 0x37, 0x8F, 0xE1, 0xA3, 0x1E, 0x7A, 0x3D, 0x50, 0xAB, + 0x63, 0x06, 0xE7, 0x15, 0xB5, 0x3F, 0xB6, 0x45, 0x37, 0x94, 0x37, 0xB1, + 0x7E, 0xF2, 0x48, 0xC3, 0x7F, 0xC5, 0x75, 0xFE, 0x97, 0x8D, 0x45, 0x8F, + 0x1A, 0xA7, 0x1A, 0x72, 0x28, 0x1A, 0x40, 0x0F +}; + +static const unsigned char TA689_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA690_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x6F, 0x6D, 0x6D, + 0x65, 0x72, 0x63, 0x69, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA690_RSA_N[] = { + 0xA7, 0x50, 0x19, 0xDE, 0x3F, 0x99, 0x3D, 0xD4, 0x33, 0x46, 0xF1, 0x6F, + 0x51, 0x61, 0x82, 0xB2, 0xA9, 0x4F, 0x8F, 0x67, 0x89, 0x5D, 0x84, 0xD9, + 0x53, 0xDD, 0x0C, 0x28, 0xD9, 0xD7, 0xF0, 0xFF, 0xAE, 0x95, 0x43, 0x72, + 0x99, 0xF9, 0xB5, 0x5D, 0x7C, 0x8A, 0xC1, 0x42, 0xE1, 0x31, 0x50, 0x74, + 0xD1, 0x81, 0x0D, 0x7C, 0xCD, 0x9B, 0x21, 0xAB, 0x43, 0xE2, 0xAC, 0xAD, + 0x5E, 0x86, 0x6E, 0xF3, 0x09, 0x8A, 0x1F, 0x5A, 0x32, 0xBD, 0xA2, 0xEB, + 0x94, 0xF9, 0xE8, 0x5C, 0x0A, 0xEC, 0xFF, 0x98, 0xD2, 0xAF, 0x71, 0xB3, + 0xB4, 0x53, 0x9F, 0x4E, 0x87, 0xEF, 0x92, 0xBC, 0xBD, 0xEC, 0x4F, 0x32, + 0x30, 0x88, 0x4B, 0x17, 0x5E, 0x57, 0xC4, 0x53, 0xC2, 0xF6, 0x02, 0x97, + 0x8D, 0xD9, 0x62, 0x2B, 0xBF, 0x24, 0x1F, 0x62, 0x8D, 0xDF, 0xC3, 0xB8, + 0x29, 0x4B, 0x49, 0x78, 0x3C, 0x93, 0x60, 0x88, 0x22, 0xFC, 0x99, 0xDA, + 0x36, 0xC8, 0xC2, 0xA2, 0xD4, 0x2C, 0x54, 0x00, 0x67, 0x35, 0x6E, 0x73, + 0xBF, 0x02, 0x58, 0xF0, 0xA4, 0xDD, 0xE5, 0xB0, 0xA2, 0x26, 0x7A, 0xCA, + 0xE0, 0x36, 0xA5, 0x19, 0x16, 0xF5, 0xFD, 0xB7, 0xEF, 0xAE, 0x3F, 0x40, + 0xF5, 0x6D, 0x5A, 0x04, 0xFD, 0xCE, 0x34, 0xCA, 0x24, 0xDC, 0x74, 0x23, + 0x1B, 0x5D, 0x33, 0x13, 0x12, 0x5D, 0xC4, 0x01, 0x25, 0xF6, 0x30, 0xDD, + 0x02, 0x5D, 0x9F, 0xE0, 0xD5, 0x47, 0xBD, 0xB4, 0xEB, 0x1B, 0xA1, 0xBB, + 0x49, 0x49, 0xD8, 0x9F, 0x5B, 0x02, 0xF3, 0x8A, 0xE4, 0x24, 0x90, 0xE4, + 0x62, 0x4F, 0x4F, 0xC1, 0xAF, 0x8B, 0x0E, 0x74, 0x17, 0xA8, 0xD1, 0x72, + 0x88, 0x6A, 0x7A, 0x01, 0x49, 0xCC, 0xB4, 0x46, 0x79, 0xC6, 0x17, 0xB1, + 0xDA, 0x98, 0x1E, 0x07, 0x59, 0xFA, 0x75, 0x21, 0x85, 0x65, 0xDD, 0x90, + 0x56, 0xCE, 0xFB, 0xAB, 0xA5, 0x60, 0x9D, 0xC4, 0x9D, 0xF9, 0x52, 0xB0, + 0x8B, 0xBD, 0x87, 0xF9, 0x8F, 0x2B, 0x23, 0x0A, 0x23, 0x76, 0x3B, 0xF7, + 0x33, 0xE1, 0xC9, 0x00, 0xF3, 0x69, 0xF9, 0x4B, 0xA2, 0xE0, 0x4E, 0xBC, + 0x7E, 0x93, 0x39, 0x84, 0x07, 0xF7, 0x44, 0x70, 0x7E, 0xFE, 0x07, 0x5A, + 0xE5, 0xB1, 0xAC, 0xD1, 0x18, 0xCC, 0xF2, 0x35, 0xE5, 0x49, 0x49, 0x08, + 0xCA, 0x56, 0xC9, 0x3D, 0xFB, 0x0F, 0x18, 0x7D, 0x8B, 0x3B, 0xC1, 0x13, + 0xC2, 0x4D, 0x8F, 0xC9, 0x4F, 0x0E, 0x37, 0xE9, 0x1F, 0xA1, 0x0E, 0x6A, + 0xDF, 0x62, 0x2E, 0xCB, 0x35, 0x06, 0x51, 0x79, 0x2C, 0xC8, 0x25, 0x38, + 0xF4, 0xFA, 0x4B, 0xA7, 0x89, 0x5C, 0x9C, 0xD2, 0xE3, 0x0D, 0x39, 0x86, + 0x4A, 0x74, 0x7C, 0xD5, 0x59, 0x87, 0xC2, 0x3F, 0x4E, 0x0C, 0x5C, 0x52, + 0xF4, 0x3D, 0xF7, 0x52, 0x82, 0xF1, 0xEA, 0xA3, 0xAC, 0xFD, 0x49, 0x34, + 0x1A, 0x28, 0xF3, 0x41, 0x88, 0x3A, 0x13, 0xEE, 0xE8, 0xDE, 0xFF, 0x99, + 0x1D, 0x5F, 0xBA, 0xCB, 0xE8, 0x1E, 0xF2, 0xB9, 0x50, 0x60, 0xC0, 0x31, + 0xD3, 0x73, 0xE5, 0xEF, 0xBE, 0xA0, 0xED, 0x33, 0x0B, 0x74, 0xBE, 0x20, + 0x20, 0xC4, 0x67, 0x6C, 0xF0, 0x08, 0x03, 0x7A, 0x55, 0x80, 0x7F, 0x46, + 0x4E, 0x96, 0xA7, 0xF4, 0x1E, 0x3E, 0xE1, 0xF6, 0xD8, 0x09, 0xE1, 0x33, + 0x64, 0x2B, 0x63, 0xD7, 0x32, 0x5E, 0x9F, 0xF9, 0xC0, 0x7B, 0x0F, 0x78, + 0x6F, 0x97, 0xBC, 0x93, 0x9A, 0xF9, 0x9C, 0x12, 0x90, 0x78, 0x7A, 0x80, + 0x87, 0x15, 0xD7, 0x72, 0x74, 0x9C, 0x55, 0x74, 0x78, 0xB1, 0xBA, 0xE1, + 0x6E, 0x70, 0x04, 0xBA, 0x4F, 0xA0, 0xBA, 0x68, 0xC3, 0x7B, 0xFF, 0x31, + 0xF0, 0x73, 0x3D, 0x3D, 0x94, 0x2A, 0xB1, 0x0B, 0x41, 0x0E, 0xA0, 0xFE, + 0x4D, 0x88, 0x65, 0x6B, 0x79, 0x33, 0xB4, 0xD7 +}; + +static const unsigned char TA690_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA691_DN[] = { + 0x30, 0x4D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x49, 0x64, 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, + 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x49, 0x64, + 0x65, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6C, + 0x69, 0x63, 0x20, 0x53, 0x65, 0x63, 0x74, 0x6F, 0x72, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 +}; + +static const unsigned char TA691_RSA_N[] = { + 0xB6, 0x22, 0x94, 0xFC, 0xA4, 0x48, 0xAF, 0xE8, 0x47, 0x6B, 0x0A, 0xFB, + 0x27, 0x76, 0xE4, 0xF2, 0x3F, 0x8A, 0x3B, 0x7A, 0x4A, 0x2C, 0x31, 0x2A, + 0x8C, 0x8D, 0xB0, 0xA9, 0xC3, 0x31, 0x6B, 0xA8, 0x77, 0x76, 0x84, 0x26, + 0xB6, 0xAC, 0x81, 0x42, 0x0D, 0x08, 0xEB, 0x55, 0x58, 0xBB, 0x7A, 0xF8, + 0xBC, 0x65, 0x7D, 0xF2, 0xA0, 0x6D, 0x8B, 0xA8, 0x47, 0xE9, 0x62, 0x76, + 0x1E, 0x11, 0xEE, 0x08, 0x14, 0xD1, 0xB2, 0x44, 0x16, 0xF4, 0xEA, 0xD0, + 0xFA, 0x1E, 0x2F, 0x5E, 0xDB, 0xCB, 0x73, 0x41, 0xAE, 0xBC, 0x00, 0xB0, + 0x4A, 0x2B, 0x40, 0xB2, 0xAC, 0xE1, 0x3B, 0x4B, 0xC2, 0x2D, 0x9D, 0xE4, + 0xA1, 0x9B, 0xEC, 0x1A, 0x3A, 0x1E, 0xF0, 0x08, 0xB3, 0xD0, 0xE4, 0x24, + 0x35, 0x07, 0x9F, 0x9C, 0xB4, 0xC9, 0x52, 0x6D, 0xDB, 0x07, 0xCA, 0x8F, + 0xB5, 0x5B, 0xF0, 0x83, 0xF3, 0x4F, 0xC7, 0x2D, 0xA5, 0xC8, 0xAD, 0xCB, + 0x95, 0x20, 0xA4, 0x31, 0x28, 0x57, 0x58, 0x5A, 0xE4, 0x8D, 0x1B, 0x9A, + 0xAB, 0x9E, 0x0D, 0x0C, 0xF2, 0x0A, 0x33, 0x39, 0x22, 0x39, 0x0A, 0x97, + 0x2E, 0xF3, 0x53, 0x77, 0xB9, 0x44, 0x45, 0xFD, 0x84, 0xCB, 0x36, 0x20, + 0x81, 0x59, 0x2D, 0x9A, 0x6F, 0x6D, 0x48, 0x48, 0x61, 0xCA, 0x4C, 0xDF, + 0x53, 0xD1, 0xAF, 0x52, 0xBC, 0x44, 0x9F, 0xAB, 0x2F, 0x6B, 0x83, 0x72, + 0xEF, 0x75, 0x80, 0xDA, 0x06, 0x33, 0x1B, 0x5D, 0xC8, 0xDA, 0x63, 0xC6, + 0x4D, 0xCD, 0xAC, 0x66, 0x31, 0xCD, 0xD1, 0xDE, 0x3E, 0x87, 0x10, 0x36, + 0xE1, 0xB9, 0xA4, 0x7A, 0xEF, 0x60, 0x50, 0xB2, 0xCB, 0xCA, 0xA6, 0x56, + 0xE0, 0x37, 0xAF, 0xAB, 0x34, 0x13, 0x39, 0x25, 0xE8, 0x39, 0x66, 0xE4, + 0x98, 0x7A, 0xAA, 0x12, 0x98, 0x9C, 0x59, 0x66, 0x86, 0x3E, 0xAD, 0xF1, + 0xB0, 0xCA, 0x3E, 0x06, 0x0F, 0x7B, 0xF0, 0x11, 0x4B, 0x37, 0xA0, 0x44, + 0x6D, 0x7B, 0xCB, 0xA8, 0x8C, 0x71, 0xF4, 0xD5, 0xB5, 0x91, 0x36, 0xCC, + 0xF0, 0x15, 0xC6, 0x2B, 0xDE, 0x51, 0x17, 0xB1, 0x97, 0x4C, 0x50, 0x3D, + 0xB1, 0x95, 0x59, 0x7C, 0x05, 0x7D, 0x2D, 0x21, 0xD5, 0x00, 0xBF, 0x01, + 0x67, 0xA2, 0x5E, 0x7B, 0xA6, 0x5C, 0xF2, 0xF7, 0x22, 0xF1, 0x90, 0x0D, + 0x93, 0xDB, 0xAA, 0x44, 0x51, 0x66, 0xCC, 0x7D, 0x76, 0x03, 0xEB, 0x6A, + 0xA8, 0x2A, 0x38, 0x19, 0x97, 0x76, 0x0D, 0x6B, 0x8A, 0x61, 0xF9, 0xBC, + 0xF6, 0xEE, 0x76, 0xFD, 0x70, 0x2B, 0xDD, 0x29, 0x3C, 0xF8, 0x0A, 0x1E, + 0x5B, 0x42, 0x1C, 0x8B, 0x56, 0x2F, 0x55, 0x1B, 0x1C, 0xA1, 0x2E, 0xB5, + 0xC7, 0x16, 0xE6, 0xF8, 0xAA, 0x3C, 0x92, 0x8E, 0x69, 0xB6, 0x01, 0xC1, + 0xB5, 0x86, 0x9D, 0x89, 0x0F, 0x0B, 0x38, 0x94, 0x54, 0xE8, 0xEA, 0xDC, + 0x9E, 0x3D, 0x25, 0xBC, 0x53, 0x26, 0xED, 0xD5, 0xAB, 0x39, 0xAA, 0xC5, + 0x40, 0x4C, 0x54, 0xAB, 0xB2, 0xB4, 0xD9, 0xD9, 0xF8, 0xD7, 0x72, 0xDB, + 0x1C, 0xBC, 0x6D, 0xBD, 0x65, 0x5F, 0xEF, 0x88, 0x35, 0x2A, 0x66, 0x2F, + 0xEE, 0xF6, 0xB3, 0x65, 0xF0, 0x33, 0x8D, 0x7C, 0x98, 0x41, 0x69, 0x46, + 0x0F, 0x43, 0x1C, 0x69, 0xFA, 0x9B, 0xB5, 0xD0, 0x61, 0x6A, 0xCD, 0xCA, + 0x4B, 0xD9, 0x4C, 0x90, 0x46, 0xAB, 0x15, 0x59, 0xA1, 0x47, 0x54, 0x29, + 0x2E, 0x83, 0x28, 0x5F, 0x1C, 0xC2, 0xA2, 0xAB, 0x72, 0x17, 0x00, 0x06, + 0x8E, 0x45, 0xEC, 0x8B, 0xE2, 0x33, 0x3D, 0x7F, 0xDA, 0x19, 0x44, 0xE4, + 0x62, 0x72, 0xC3, 0xDF, 0x22, 0xC6, 0xF2, 0x56, 0xD4, 0xDD, 0x5F, 0x95, + 0x72, 0xED, 0x6D, 0x5F, 0xF7, 0x48, 0x03, 0x5B, 0xFD, 0xC5, 0x2A, 0xA0, + 0xF6, 0x73, 0x23, 0x84, 0x10, 0x1B, 0x01, 0xE7 +}; + +static const unsigned char TA691_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA692_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x31 +}; + +static const unsigned char TA692_RSA_N[] = { + 0xAD, 0xE8, 0x24, 0x73, 0xF4, 0x14, 0x37, 0xF3, 0x9B, 0x9E, 0x2B, 0x57, + 0x28, 0x1C, 0x87, 0xBE, 0xDC, 0xB7, 0xDF, 0x38, 0x90, 0x8C, 0x6E, 0x3C, + 0xE6, 0x57, 0xA0, 0x78, 0xF7, 0x75, 0xC2, 0xA2, 0xFE, 0xF5, 0x6A, 0x6E, + 0xF6, 0x00, 0x4F, 0x28, 0xDB, 0xDE, 0x68, 0x86, 0x6C, 0x44, 0x93, 0xB6, + 0xB1, 0x63, 0xFD, 0x14, 0x12, 0x6B, 0xBF, 0x1F, 0xD2, 0xEA, 0x31, 0x9B, + 0x21, 0x7E, 0xD1, 0x33, 0x3C, 0xBA, 0x48, 0xF5, 0xDD, 0x79, 0xDF, 0xB3, + 0xB8, 0xFF, 0x12, 0xF1, 0x21, 0x9A, 0x4B, 0xC1, 0x8A, 0x86, 0x71, 0x69, + 0x4A, 0x66, 0x66, 0x6C, 0x8F, 0x7E, 0x3C, 0x70, 0xBF, 0xAD, 0x29, 0x22, + 0x06, 0xF3, 0xE4, 0xC0, 0xE6, 0x80, 0xAE, 0xE2, 0x4B, 0x8F, 0xB7, 0x99, + 0x7E, 0x94, 0x03, 0x9F, 0xD3, 0x47, 0x97, 0x7C, 0x99, 0x48, 0x23, 0x53, + 0xE8, 0x38, 0xAE, 0x4F, 0x0A, 0x6F, 0x83, 0x2E, 0xD1, 0x49, 0x57, 0x8C, + 0x80, 0x74, 0xB6, 0xDA, 0x2F, 0xD0, 0x38, 0x8D, 0x7B, 0x03, 0x70, 0x21, + 0x1B, 0x75, 0xF2, 0x30, 0x3C, 0xFA, 0x8F, 0xAE, 0xDD, 0xDA, 0x63, 0xAB, + 0xEB, 0x16, 0x4F, 0xC2, 0x8E, 0x11, 0x4B, 0x7E, 0xCF, 0x0B, 0xE8, 0xFF, + 0xB5, 0x77, 0x2E, 0xF4, 0xB2, 0x7B, 0x4A, 0xE0, 0x4C, 0x12, 0x25, 0x0C, + 0x70, 0x8D, 0x03, 0x29, 0xA0, 0xE1, 0x53, 0x24, 0xEC, 0x13, 0xD9, 0xEE, + 0x19, 0xBF, 0x10, 0xB3, 0x4A, 0x8C, 0x3F, 0x89, 0xA3, 0x61, 0x51, 0xDE, + 0xAC, 0x87, 0x07, 0x94, 0xF4, 0x63, 0x71, 0xEC, 0x2E, 0xE2, 0x6F, 0x5B, + 0x98, 0x81, 0xE1, 0x89, 0x5C, 0x34, 0x79, 0x6C, 0x76, 0xEF, 0x3B, 0x90, + 0x62, 0x79, 0xE6, 0xDB, 0xA4, 0x9A, 0x2F, 0x26, 0xC5, 0xD0, 0x10, 0xE1, + 0x0E, 0xDE, 0xD9, 0x10, 0x8E, 0x16, 0xFB, 0xB7, 0xF7, 0xA8, 0xF7, 0xC7, + 0xE5, 0x02, 0x07, 0x98, 0x8F, 0x36, 0x08, 0x95, 0xE7, 0xE2, 0x37, 0x96, + 0x0D, 0x36, 0x75, 0x9E, 0xFB, 0x0E, 0x72, 0xB1, 0x1D, 0x9B, 0xBC, 0x03, + 0xF9, 0x49, 0x05, 0xD8, 0x81, 0xDD, 0x05, 0xB4, 0x2A, 0xD6, 0x41, 0xE9, + 0xAC, 0x01, 0x76, 0x95, 0x0A, 0x0F, 0xD8, 0xDF, 0xD5, 0xBD, 0x12, 0x1F, + 0x35, 0x2F, 0x28, 0x17, 0x6C, 0xD2, 0x98, 0xC1, 0xA8, 0x09, 0x64, 0x77, + 0x6E, 0x47, 0x37, 0xBA, 0xCE, 0xAC, 0x59, 0x5E, 0x68, 0x9D, 0x7F, 0x72, + 0xD6, 0x89, 0xC5, 0x06, 0x41, 0x29, 0x3E, 0x59, 0x3E, 0xDD, 0x26, 0xF5, + 0x24, 0xC9, 0x11, 0xA7, 0x5A, 0xA3, 0x4C, 0x40, 0x1F, 0x46, 0xA1, 0x99, + 0xB5, 0xA7, 0x3A, 0x51, 0x6E, 0x86, 0x3B, 0x9E, 0x7D, 0x72, 0xA7, 0x12, + 0x05, 0x78, 0x59, 0xED, 0x3E, 0x51, 0x78, 0x15, 0x0B, 0x03, 0x8F, 0x8D, + 0xD0, 0x2F, 0x05, 0xB2, 0x3E, 0x7B, 0x4A, 0x1C, 0x4B, 0x73, 0x05, 0x12, + 0xFC, 0xC6, 0xEA, 0xE0, 0x50, 0x13, 0x7C, 0x43, 0x93, 0x74, 0xB3, 0xCA, + 0x74, 0xE7, 0x8E, 0x1F, 0x01, 0x08, 0xD0, 0x30, 0xD4, 0x5B, 0x71, 0x36, + 0xB4, 0x07, 0xBA, 0xC1, 0x30, 0x30, 0x5C, 0x48, 0xB7, 0x82, 0x3B, 0x98, + 0xA6, 0x7D, 0x60, 0x8A, 0xA2, 0xA3, 0x29, 0x82, 0xCC, 0xBA, 0xBD, 0x83, + 0x04, 0x1B, 0xA2, 0x83, 0x03, 0x41, 0xA1, 0xD6, 0x05, 0xF1, 0x1B, 0xC2, + 0xB6, 0xF0, 0xA8, 0x7C, 0x86, 0x3B, 0x46, 0xA8, 0x48, 0x2A, 0x88, 0xDC, + 0x76, 0x9A, 0x76, 0xBF, 0x1F, 0x6A, 0xA5, 0x3D, 0x19, 0x8F, 0xEB, 0x38, + 0xF3, 0x64, 0xDE, 0xC8, 0x2B, 0x0D, 0x0A, 0x28, 0xFF, 0xF7, 0xDB, 0xE2, + 0x15, 0x42, 0xD4, 0x22, 0xD0, 0x27, 0x5D, 0xE1, 0x79, 0xFE, 0x18, 0xE7, + 0x70, 0x88, 0xAD, 0x4E, 0xE6, 0xD9, 0x8B, 0x3A, 0xC6, 0xDD, 0x27, 0x51, + 0x6E, 0xFF, 0xBC, 0x64, 0xF5, 0x33, 0x43, 0x4F +}; + +static const unsigned char TA692_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA693_DN[] = { + 0x30, 0x4F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x20, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x15, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x49, 0x53, 0x52, + 0x47, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x58, 0x32 +}; + +static const unsigned char TA693_EC_Q[] = { + 0x04, 0xCD, 0x9B, 0xD5, 0x9F, 0x80, 0x83, 0x0A, 0xEC, 0x09, 0x4A, 0xF3, + 0x16, 0x4A, 0x3E, 0x5C, 0xCF, 0x77, 0xAC, 0xDE, 0x67, 0x05, 0x0D, 0x1D, + 0x07, 0xB6, 0xDC, 0x16, 0xFB, 0x5A, 0x8B, 0x14, 0xDB, 0xE2, 0x71, 0x60, + 0xC4, 0xBA, 0x45, 0x95, 0x11, 0x89, 0x8E, 0xEA, 0x06, 0xDF, 0xF7, 0x2A, + 0x16, 0x1C, 0xA4, 0xB9, 0xC5, 0xC5, 0x32, 0xE0, 0x03, 0xE0, 0x1E, 0x82, + 0x18, 0x38, 0x8B, 0xD7, 0x45, 0xD8, 0x0A, 0x6A, 0x6E, 0xE6, 0x00, 0x77, + 0xFB, 0x02, 0x51, 0x7D, 0x22, 0xD8, 0x0A, 0x6E, 0x9A, 0x5B, 0x77, 0xDF, + 0xF0, 0xFA, 0x41, 0xEC, 0x39, 0xDC, 0x75, 0xCA, 0x68, 0x07, 0x0C, 0x1F, + 0xEA +}; + +static const unsigned char TA694_DN[] = { + 0x30, 0x38, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x45, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0B, 0x49, 0x5A, 0x45, 0x4E, 0x50, 0x45, 0x20, 0x53, 0x2E, 0x41, + 0x2E, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0A, + 0x49, 0x7A, 0x65, 0x6E, 0x70, 0x65, 0x2E, 0x63, 0x6F, 0x6D +}; + +static const unsigned char TA694_RSA_N[] = { + 0xC9, 0xD3, 0x7A, 0xCA, 0x0F, 0x1E, 0xAC, 0xA7, 0x86, 0xE8, 0x16, 0x65, + 0x6A, 0xB1, 0xC2, 0x1B, 0x45, 0x32, 0x71, 0x95, 0xD9, 0xFE, 0x10, 0x5B, + 0xCC, 0xAF, 0xE7, 0xA5, 0x79, 0x01, 0x8F, 0x89, 0xC3, 0xCA, 0xF2, 0x55, + 0x71, 0xF7, 0x77, 0xBE, 0x77, 0x94, 0xF3, 0x72, 0xA4, 0x2C, 0x44, 0xD8, + 0x9E, 0x92, 0x9B, 0x14, 0x3A, 0xA1, 0xE7, 0x24, 0x90, 0x0A, 0x0A, 0x56, + 0x8E, 0xC5, 0xD8, 0x26, 0x94, 0xE1, 0xD9, 0x48, 0xE1, 0x2D, 0x3E, 0xDA, + 0x0A, 0x72, 0xDD, 0xA3, 0x99, 0x15, 0xDA, 0x81, 0xA2, 0x87, 0xF4, 0x7B, + 0x6E, 0x26, 0x77, 0x89, 0x58, 0xAD, 0xD6, 0xEB, 0x0C, 0xB2, 0x41, 0x7A, + 0x73, 0x6E, 0x6D, 0xDB, 0x7A, 0x78, 0x41, 0xE9, 0x08, 0x88, 0x12, 0x7E, + 0x87, 0x2E, 0x66, 0x11, 0x63, 0x6C, 0x54, 0xFB, 0x3C, 0x9D, 0x72, 0xC0, + 0xBC, 0x2E, 0xFF, 0xC2, 0xB7, 0xDD, 0x0D, 0x76, 0xE3, 0x3A, 0xD7, 0xF7, + 0xB4, 0x68, 0xBE, 0xA2, 0xF5, 0xE3, 0x81, 0x6E, 0xC1, 0x46, 0x6F, 0x5D, + 0x8D, 0xE0, 0x4D, 0xC6, 0x54, 0x55, 0x89, 0x1A, 0x33, 0x31, 0x0A, 0xB1, + 0x57, 0xB9, 0xA3, 0x8A, 0x98, 0xC3, 0xEC, 0x3B, 0x34, 0xC5, 0x95, 0x41, + 0x69, 0x7E, 0x75, 0xC2, 0x3C, 0x20, 0xC5, 0x61, 0xBA, 0x51, 0x47, 0xA0, + 0x20, 0x90, 0x93, 0xA1, 0x90, 0x4B, 0xF3, 0x4E, 0x7C, 0x85, 0x45, 0x54, + 0x9A, 0xD1, 0x05, 0x26, 0x41, 0xB0, 0xB5, 0x4D, 0x1D, 0x33, 0xBE, 0xC4, + 0x03, 0xC8, 0x25, 0x7C, 0xC1, 0x70, 0xDB, 0x3B, 0xF4, 0x09, 0x2D, 0x54, + 0x27, 0x48, 0xAC, 0x2F, 0xE1, 0xC4, 0xAC, 0x3E, 0xC8, 0xCB, 0x92, 0x4C, + 0x53, 0x39, 0x37, 0x23, 0xEC, 0xD3, 0x01, 0xF9, 0xE0, 0x09, 0x44, 0x4D, + 0x4D, 0x64, 0xC0, 0xE1, 0x0D, 0x5A, 0x87, 0x22, 0xBC, 0xAD, 0x1B, 0xA3, + 0xFE, 0x26, 0xB5, 0x15, 0xF3, 0xA7, 0xFC, 0x84, 0x19, 0xE9, 0xEC, 0xA1, + 0x88, 0xB4, 0x44, 0x69, 0x84, 0x83, 0xF3, 0x89, 0xD1, 0x74, 0x06, 0xA9, + 0xCC, 0x0B, 0xD6, 0xC2, 0xDE, 0x27, 0x85, 0x50, 0x26, 0xCA, 0x17, 0xB8, + 0xC9, 0x7A, 0x87, 0x56, 0x2C, 0x1A, 0x01, 0x1E, 0x6C, 0xBE, 0x13, 0xAD, + 0x10, 0xAC, 0xB5, 0x24, 0xF5, 0x38, 0x91, 0xA1, 0xD6, 0x4B, 0xDA, 0xF1, + 0xBB, 0xD2, 0xDE, 0x47, 0xB5, 0xF1, 0xBC, 0x81, 0xF6, 0x59, 0x6B, 0xCF, + 0x19, 0x53, 0xE9, 0x8D, 0x15, 0xCB, 0x4A, 0xCB, 0xA9, 0x6F, 0x44, 0xE5, + 0x1B, 0x41, 0xCF, 0xE1, 0x86, 0xA7, 0xCA, 0xD0, 0x6A, 0x9F, 0xBC, 0x4C, + 0x8D, 0x06, 0x33, 0x5A, 0xA2, 0x85, 0xE5, 0x90, 0x35, 0xA0, 0x62, 0x5C, + 0x16, 0x4E, 0xF0, 0xE3, 0xA2, 0xFA, 0x03, 0x1A, 0xB4, 0x2C, 0x71, 0xB3, + 0x58, 0x2C, 0xDE, 0x7B, 0x0B, 0xDB, 0x1A, 0x0F, 0xEB, 0xDE, 0x21, 0x1F, + 0x06, 0x77, 0x06, 0x03, 0xB0, 0xC9, 0xEF, 0x99, 0xFC, 0xC0, 0xB9, 0x4F, + 0x0B, 0x86, 0x28, 0xFE, 0xD2, 0xB9, 0xEA, 0xE3, 0xDA, 0xA5, 0xC3, 0x47, + 0x69, 0x12, 0xE0, 0xDB, 0xF0, 0xF6, 0x19, 0x8B, 0xED, 0x7B, 0x70, 0xD7, + 0x02, 0xD6, 0xED, 0x87, 0x18, 0x28, 0x2C, 0x04, 0x24, 0x4C, 0x77, 0xE4, + 0x48, 0x8A, 0x1A, 0xC6, 0x3B, 0x9A, 0xD4, 0x0F, 0xCA, 0xFA, 0x75, 0xD2, + 0x01, 0x40, 0x5A, 0x8D, 0x79, 0xBF, 0x8B, 0xCF, 0x4B, 0xCF, 0xAA, 0x16, + 0xC1, 0x95, 0xE4, 0xAD, 0x4C, 0x8A, 0x3E, 0x17, 0x91, 0xD4, 0xB1, 0x62, + 0xE5, 0x82, 0xE5, 0x80, 0x04, 0xA4, 0x03, 0x7E, 0x8D, 0xBF, 0xDA, 0x7F, + 0xA2, 0x0F, 0x97, 0x4F, 0x0C, 0xD3, 0x0D, 0xFB, 0xD7, 0xD1, 0xE5, 0x72, + 0x7E, 0x1C, 0xC8, 0x77, 0xFF, 0x5B, 0x9A, 0x0F, 0xB7, 0xAE, 0x05, 0x46, + 0xE5, 0xF1, 0xA8, 0x16, 0xEC, 0x47, 0xA4, 0x17 +}; + +static const unsigned char TA694_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA695_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x4C, 0x74, 0x64, 0x2E, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1E, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x20, 0x65, 0x2D, 0x53, 0x7A, 0x69, + 0x67, 0x6E, 0x6F, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, + 0x32, 0x30, 0x30, 0x39, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, + 0x6F, 0x40, 0x65, 0x2D, 0x73, 0x7A, 0x69, 0x67, 0x6E, 0x6F, 0x2E, 0x68, + 0x75 +}; + +static const unsigned char TA695_RSA_N[] = { + 0xE9, 0xF8, 0x8F, 0xF3, 0x63, 0xAD, 0xDA, 0x86, 0xD8, 0xA7, 0xE0, 0x42, + 0xFB, 0xCF, 0x91, 0xDE, 0xA6, 0x26, 0xF8, 0x99, 0xA5, 0x63, 0x70, 0xAD, + 0x9B, 0xAE, 0xCA, 0x33, 0x40, 0x7D, 0x6D, 0x96, 0x6E, 0xA1, 0x0E, 0x44, + 0xEE, 0xE1, 0x13, 0x9D, 0x94, 0x42, 0x52, 0x9A, 0xBD, 0x75, 0x85, 0x74, + 0x2C, 0xA8, 0x0E, 0x1D, 0x93, 0xB6, 0x18, 0xB7, 0x8C, 0x2C, 0xA8, 0xCF, + 0xFB, 0x5C, 0x71, 0xB9, 0xDA, 0xEC, 0xFE, 0xE8, 0x7E, 0x8F, 0xE4, 0x2F, + 0x1D, 0xB2, 0xA8, 0x75, 0x87, 0xD8, 0xB7, 0xA1, 0xE5, 0x3B, 0xCF, 0x99, + 0x4A, 0x46, 0xD0, 0x83, 0x19, 0x7D, 0xC0, 0xA1, 0x12, 0x1C, 0x95, 0x6D, + 0x4A, 0xF4, 0xD8, 0xC7, 0xA5, 0x4D, 0x33, 0x2E, 0x85, 0x39, 0x40, 0x75, + 0x7E, 0x14, 0x7C, 0x80, 0x12, 0x98, 0x50, 0xC7, 0x41, 0x67, 0xB8, 0xA0, + 0x80, 0x61, 0x54, 0xA6, 0x6C, 0x4E, 0x1F, 0xE0, 0x9D, 0x0E, 0x07, 0xE9, + 0xC9, 0xBA, 0x33, 0xE7, 0xFE, 0xC0, 0x55, 0x28, 0x2C, 0x02, 0x80, 0xA7, + 0x19, 0xF5, 0x9E, 0xDC, 0x55, 0x53, 0x03, 0x97, 0x7B, 0x07, 0x48, 0xFF, + 0x99, 0xFB, 0x37, 0x8A, 0x24, 0xC4, 0x59, 0xCC, 0x50, 0x10, 0x63, 0x8E, + 0xAA, 0xA9, 0x1A, 0xB0, 0x84, 0x1A, 0x86, 0xF9, 0x5F, 0xBB, 0xB1, 0x50, + 0x6E, 0xA4, 0xD1, 0x0A, 0xCC, 0xD5, 0x71, 0x7E, 0x1F, 0xA7, 0x1B, 0x7C, + 0xF5, 0x53, 0x6E, 0x22, 0x5F, 0xCB, 0x2B, 0xE6, 0xD4, 0x7C, 0x5D, 0xAE, + 0xD6, 0xC2, 0xC6, 0x4C, 0xE5, 0x05, 0x01, 0xD9, 0xED, 0x57, 0xFC, 0xC1, + 0x23, 0x79, 0xFC, 0xFA, 0xC8, 0x24, 0x83, 0x95, 0xF3, 0xB5, 0x6A, 0x51, + 0x01, 0xD0, 0x77, 0xD6, 0xE9, 0x12, 0xA1, 0xF9, 0x1A, 0x83, 0xFB, 0x82, + 0x1B, 0xB9, 0xB0, 0x97, 0xF4, 0x76, 0x06, 0x33, 0x43, 0x49, 0xA0, 0xFF, + 0x0B, 0xB5, 0xFA, 0xB5 +}; + +static const unsigned char TA695_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA696_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA696_EC_Q[] = { + 0x04, 0xD4, 0xBC, 0x3D, 0x02, 0x42, 0x75, 0x41, 0x13, 0x23, 0xCD, 0x80, + 0x04, 0x86, 0x02, 0x51, 0x2F, 0x6A, 0xA8, 0x81, 0x62, 0x0B, 0x65, 0xCC, + 0xF6, 0xCA, 0x9D, 0x1E, 0x6F, 0x4A, 0x66, 0x51, 0xA2, 0x03, 0xD9, 0x9D, + 0x91, 0xFA, 0xB6, 0x16, 0xB1, 0x8C, 0x6E, 0xDE, 0x7C, 0xCD, 0xDB, 0x79, + 0xA6, 0x2F, 0xCE, 0xBB, 0xCE, 0x71, 0x2F, 0xE5, 0xA5, 0xAB, 0x28, 0xEC, + 0x63, 0x04, 0x66, 0x99, 0xF8, 0xFA, 0xF2, 0x93, 0x10, 0x05, 0xE1, 0x81, + 0x28, 0x42, 0xE3, 0xC6, 0x68, 0xF4, 0xE6, 0x1B, 0x84, 0x60, 0x4A, 0x89, + 0xAF, 0xED, 0x79, 0x0F, 0x3B, 0xCE, 0xF1, 0xF6, 0x44, 0xF5, 0x01, 0x78, + 0xC0 +}; + +static const unsigned char TA697_DN[] = { + 0x30, 0x65, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, + 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, + 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, 0x4D, 0x69, + 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x37 +}; + +static const unsigned char TA697_RSA_N[] = { + 0xCA, 0x5B, 0xBE, 0x94, 0x33, 0x8C, 0x29, 0x95, 0x91, 0x16, 0x0A, 0x95, + 0xBD, 0x47, 0x62, 0xC1, 0x89, 0xF3, 0x99, 0x36, 0xDF, 0x46, 0x90, 0xC9, + 0xA5, 0xED, 0x78, 0x6A, 0x6F, 0x47, 0x91, 0x68, 0xF8, 0x27, 0x67, 0x50, + 0x33, 0x1D, 0xA1, 0xA6, 0xFB, 0xE0, 0xE5, 0x43, 0xA3, 0x84, 0x02, 0x57, + 0x01, 0x5D, 0x9C, 0x48, 0x40, 0x82, 0x53, 0x10, 0xBC, 0xBF, 0xC7, 0x3B, + 0x68, 0x90, 0xB6, 0x82, 0x2D, 0xE5, 0xF4, 0x65, 0xD0, 0xCC, 0x6D, 0x19, + 0xCC, 0x95, 0xF9, 0x7B, 0xAC, 0x4A, 0x94, 0xAD, 0x0E, 0xDE, 0x4B, 0x43, + 0x1D, 0x87, 0x07, 0x92, 0x13, 0x90, 0x80, 0x83, 0x64, 0x35, 0x39, 0x04, + 0xFC, 0xE5, 0xE9, 0x6C, 0xB3, 0xB6, 0x1F, 0x50, 0x94, 0x38, 0x65, 0x50, + 0x5C, 0x17, 0x46, 0xB9, 0xB6, 0x85, 0xB5, 0x1C, 0xB5, 0x17, 0xE8, 0xD6, + 0x45, 0x9D, 0xD8, 0xB2, 0x26, 0xB0, 0xCA, 0xC4, 0x70, 0x4A, 0xAE, 0x60, + 0xA4, 0xDD, 0xB3, 0xD9, 0xEC, 0xFC, 0x3B, 0xD5, 0x57, 0x72, 0xBC, 0x3F, + 0xC8, 0xC9, 0xB2, 0xDE, 0x4B, 0x6B, 0xF8, 0x23, 0x6C, 0x03, 0xC0, 0x05, + 0xBD, 0x95, 0xC7, 0xCD, 0x73, 0x3B, 0x66, 0x80, 0x64, 0xE3, 0x1A, 0xAC, + 0x2E, 0xF9, 0x47, 0x05, 0xF2, 0x06, 0xB6, 0x9B, 0x73, 0xF5, 0x78, 0x33, + 0x5B, 0xC7, 0xA1, 0xFB, 0x27, 0x2A, 0xA1, 0xB4, 0x9A, 0x91, 0x8C, 0x91, + 0xD3, 0x3A, 0x82, 0x3E, 0x76, 0x40, 0xB4, 0xCD, 0x52, 0x61, 0x51, 0x70, + 0x28, 0x3F, 0xC5, 0xC5, 0x5A, 0xF2, 0xC9, 0x8C, 0x49, 0xBB, 0x14, 0x5B, + 0x4D, 0xC8, 0xFF, 0x67, 0x4D, 0x4C, 0x12, 0x96, 0xAD, 0xF5, 0xFE, 0x78, + 0xA8, 0x97, 0x87, 0xD7, 0xFD, 0x5E, 0x20, 0x80, 0xDC, 0xA1, 0x4B, 0x22, + 0xFB, 0xD4, 0x89, 0xAD, 0xBA, 0xCE, 0x47, 0x97, 0x47, 0x55, 0x7B, 0x8F, + 0x45, 0xC8, 0x67, 0x28, 0x84, 0x95, 0x1C, 0x68, 0x30, 0xEF, 0xEF, 0x49, + 0xE0, 0x35, 0x7B, 0x64, 0xE7, 0x98, 0xB0, 0x94, 0xDA, 0x4D, 0x85, 0x3B, + 0x3E, 0x55, 0xC4, 0x28, 0xAF, 0x57, 0xF3, 0x9E, 0x13, 0xDB, 0x46, 0x27, + 0x9F, 0x1E, 0xA2, 0x5E, 0x44, 0x83, 0xA4, 0xA5, 0xCA, 0xD5, 0x13, 0xB3, + 0x4B, 0x3F, 0xC4, 0xE3, 0xC2, 0xE6, 0x86, 0x61, 0xA4, 0x52, 0x30, 0xB9, + 0x7A, 0x20, 0x4F, 0x6F, 0x0F, 0x38, 0x53, 0xCB, 0x33, 0x0C, 0x13, 0x2B, + 0x8F, 0xD6, 0x9A, 0xBD, 0x2A, 0xC8, 0x2D, 0xB1, 0x1C, 0x7D, 0x4B, 0x51, + 0xCA, 0x47, 0xD1, 0x48, 0x27, 0x72, 0x5D, 0x87, 0xEB, 0xD5, 0x45, 0xE6, + 0x48, 0x65, 0x9D, 0xAF, 0x52, 0x90, 0xBA, 0x5B, 0xA2, 0x18, 0x65, 0x57, + 0x12, 0x9F, 0x68, 0xB9, 0xD4, 0x15, 0x6B, 0x94, 0xC4, 0x69, 0x22, 0x98, + 0xF4, 0x33, 0xE0, 0xED, 0xF9, 0x51, 0x8E, 0x41, 0x50, 0xC9, 0x34, 0x4F, + 0x76, 0x90, 0xAC, 0xFC, 0x38, 0xC1, 0xD8, 0xE1, 0x7B, 0xB9, 0xE3, 0xE3, + 0x94, 0xE1, 0x46, 0x69, 0xCB, 0x0E, 0x0A, 0x50, 0x6B, 0x13, 0xBA, 0xAC, + 0x0F, 0x37, 0x5A, 0xB7, 0x12, 0xB5, 0x90, 0x81, 0x1E, 0x56, 0xAE, 0x57, + 0x22, 0x86, 0xD9, 0xC9, 0xD2, 0xD1, 0xD7, 0x51, 0xE3, 0xAB, 0x3B, 0xC6, + 0x55, 0xFD, 0x1E, 0x0E, 0xD3, 0x74, 0x0A, 0xD1, 0xDA, 0xAA, 0xEA, 0x69, + 0xB8, 0x97, 0x28, 0x8F, 0x48, 0xC4, 0x07, 0xF8, 0x52, 0x43, 0x3A, 0xF4, + 0xCA, 0x55, 0x35, 0x2C, 0xB0, 0xA6, 0x6A, 0xC0, 0x9C, 0xF9, 0xF2, 0x81, + 0xE1, 0x12, 0x6A, 0xC0, 0x45, 0xD9, 0x67, 0xB3, 0xCE, 0xFF, 0x23, 0xA2, + 0x89, 0x0A, 0x54, 0xD4, 0x14, 0xB9, 0x2A, 0xA8, 0xD7, 0xEC, 0xF9, 0xAB, + 0xCD, 0x25, 0x58, 0x32, 0x79, 0x8F, 0x90, 0x5B, 0x98, 0x39, 0xC4, 0x08, + 0x06, 0xC1, 0xAC, 0x7F, 0x0E, 0x3D, 0x00, 0xA5 +}; + +static const unsigned char TA697_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA698_DN[] = { + 0x30, 0x69, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4B, 0x52, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1D, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, 0x42, 0x55, 0x53, 0x49, + 0x4E, 0x45, 0x53, 0x53, 0x20, 0x50, 0x4C, 0x41, 0x54, 0x46, 0x4F, 0x52, + 0x4D, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x29, 0x4E, 0x41, 0x56, 0x45, 0x52, 0x20, + 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA698_RSA_N[] = { + 0xB6, 0xD4, 0xF1, 0x93, 0x5C, 0xB5, 0x40, 0x89, 0x0A, 0xAB, 0x0D, 0x90, + 0x5B, 0x50, 0x63, 0xAE, 0x90, 0x94, 0x74, 0x17, 0x45, 0x72, 0xD6, 0x7B, + 0x65, 0x5A, 0x29, 0x4B, 0xA7, 0x56, 0xA0, 0x4B, 0xB8, 0x2F, 0x42, 0x75, + 0xE9, 0xD9, 0x7B, 0x24, 0x5A, 0x31, 0x65, 0xAB, 0x17, 0x17, 0xD1, 0x33, + 0x3A, 0xD9, 0x11, 0xDC, 0x40, 0x36, 0x87, 0xDF, 0xC7, 0x6A, 0xE9, 0x26, + 0x5E, 0x59, 0x8A, 0x77, 0xE3, 0xE8, 0x48, 0x9C, 0x31, 0x16, 0xFA, 0x3E, + 0x91, 0xB1, 0xCA, 0xC9, 0xA3, 0xE2, 0x9F, 0xCE, 0x21, 0x53, 0xA3, 0x02, + 0x36, 0x30, 0xCB, 0x52, 0x02, 0xE5, 0xDA, 0x32, 0x5D, 0xC3, 0xC5, 0xE6, + 0xF9, 0xEE, 0x11, 0xC7, 0x8B, 0xC9, 0x44, 0x1E, 0x84, 0x93, 0x18, 0x4A, + 0xB4, 0x9F, 0xE5, 0x12, 0x64, 0x69, 0xD0, 0x26, 0x85, 0x62, 0x01, 0xB6, + 0xC9, 0x02, 0x1D, 0xBE, 0x83, 0x51, 0xBB, 0x5C, 0xDA, 0xF8, 0xAD, 0x15, + 0x6A, 0x99, 0xF7, 0x92, 0x54, 0xF7, 0x34, 0x5B, 0xE9, 0xBF, 0xEA, 0x29, + 0x81, 0x12, 0xD4, 0x53, 0x91, 0x96, 0xB3, 0x91, 0x5A, 0xDD, 0xFE, 0x90, + 0x73, 0x28, 0xFB, 0x30, 0x46, 0xB5, 0xCA, 0x08, 0x07, 0xC7, 0x71, 0x72, + 0xC9, 0x66, 0xD3, 0x34, 0x97, 0xF6, 0x8C, 0xF4, 0x18, 0x4A, 0xE1, 0xD0, + 0x3D, 0x5A, 0x45, 0xB6, 0x69, 0xA7, 0x29, 0xFB, 0x23, 0xCE, 0x88, 0xD8, + 0x12, 0x9C, 0x00, 0x48, 0xA8, 0xA6, 0x0F, 0xB3, 0x3B, 0x92, 0x8D, 0x71, + 0x0E, 0x74, 0xC5, 0x8B, 0xC8, 0x4C, 0xF9, 0xF4, 0x9B, 0x8E, 0xB8, 0x3C, + 0x69, 0xED, 0x6F, 0x3B, 0x50, 0x2F, 0x58, 0xED, 0xC4, 0xB0, 0xD0, 0x1C, + 0x1B, 0x6A, 0x0C, 0xE2, 0xBC, 0x44, 0xAA, 0xD8, 0xCD, 0x14, 0x5D, 0x94, + 0x78, 0x61, 0xBF, 0x0E, 0x6E, 0xDA, 0x2A, 0xBC, 0x2F, 0x0C, 0x0B, 0x71, + 0xA6, 0xB3, 0x16, 0x3F, 0x9C, 0xE6, 0xF9, 0xCC, 0x9F, 0x53, 0x35, 0xE2, + 0x03, 0xA0, 0xA0, 0x18, 0xBF, 0xBB, 0xF1, 0xBE, 0xF4, 0xD6, 0x8C, 0x87, + 0x0D, 0x42, 0xF7, 0x06, 0xB9, 0xF1, 0x6D, 0xED, 0x04, 0x94, 0xA8, 0xFE, + 0xB6, 0xD3, 0x06, 0xC6, 0x40, 0x61, 0xDF, 0x9D, 0x9D, 0xF3, 0x54, 0x76, + 0xCE, 0x53, 0x3A, 0x01, 0xA6, 0x92, 0x41, 0xEC, 0x04, 0xA3, 0x8F, 0x0D, + 0xA2, 0xD5, 0x09, 0xCA, 0xD6, 0xCB, 0x9A, 0xF1, 0xEF, 0x43, 0x5D, 0xC0, + 0xAB, 0xA5, 0x41, 0xCF, 0x5C, 0x53, 0x70, 0x70, 0xC9, 0x88, 0xA6, 0x2D, + 0xD4, 0x6B, 0x61, 0x73, 0x50, 0x26, 0x86, 0x61, 0x0E, 0x5F, 0x1B, 0xC2, + 0x2B, 0xE2, 0x8C, 0xD5, 0xBB, 0x9D, 0xC1, 0x03, 0x42, 0xBA, 0x94, 0xDA, + 0x5F, 0xA9, 0xB0, 0xCA, 0xCC, 0x4D, 0x0A, 0xEF, 0x47, 0x69, 0x03, 0x2F, + 0x22, 0xFB, 0xF1, 0x28, 0xCE, 0xBF, 0x5D, 0x50, 0x65, 0xA8, 0x90, 0x6D, + 0xB3, 0x74, 0xB0, 0x08, 0xC7, 0xAC, 0xA8, 0xD1, 0xEB, 0x3E, 0x9C, 0xFC, + 0x5D, 0x1A, 0x83, 0x2E, 0x2B, 0xCB, 0xB5, 0xF3, 0x44, 0x9D, 0x3A, 0xA7, + 0x17, 0x61, 0x96, 0xA2, 0x71, 0xD3, 0x70, 0x96, 0x15, 0x4D, 0xB7, 0x4C, + 0x73, 0xEE, 0x19, 0x5C, 0xC5, 0x5B, 0x3E, 0x41, 0xFE, 0xAC, 0x75, 0x60, + 0x3B, 0x1B, 0x63, 0xCE, 0x00, 0xDD, 0xDA, 0x08, 0x90, 0x62, 0xB4, 0xE5, + 0x2D, 0xEE, 0x48, 0xA7, 0x6B, 0x17, 0x99, 0x54, 0xBE, 0x87, 0x4A, 0xE3, + 0xA9, 0x5E, 0x04, 0x4C, 0xEB, 0x10, 0x6D, 0x54, 0xD6, 0xEF, 0xF1, 0xE8, + 0xF2, 0x62, 0x16, 0xCB, 0x80, 0x6B, 0xED, 0x3D, 0xED, 0xF5, 0x1F, 0x30, + 0xA5, 0xAE, 0x4B, 0xC9, 0x13, 0xED, 0x8A, 0x01, 0x01, 0xC9, 0xB8, 0x51, + 0x58, 0xC0, 0x66, 0x3A, 0xB1, 0x66, 0x4B, 0xC4, 0xD5, 0x31, 0x02, 0x62, + 0xE9, 0x74, 0x84, 0x0C, 0xDB, 0x4D, 0x46, 0x2D +}; + +static const unsigned char TA698_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA699_DN[] = { + 0x30, 0x81, 0xA7, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x48, 0x55, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0C, 0x08, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0C, 0x4E, 0x65, + 0x74, 0x4C, 0x6F, 0x63, 0x6B, 0x20, 0x4B, 0x66, 0x74, 0x2E, 0x31, 0x37, + 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x2E, 0x54, 0x61, 0x6E, + 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, 0x6E, 0x79, 0x6B, + 0x69, 0x61, 0x64, 0xC3, 0xB3, 0x6B, 0x20, 0x28, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x29, 0x31, 0x35, 0x30, 0x33, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x2C, 0x4E, 0x65, 0x74, 0x4C, 0x6F, 0x63, + 0x6B, 0x20, 0x41, 0x72, 0x61, 0x6E, 0x79, 0x20, 0x28, 0x43, 0x6C, 0x61, + 0x73, 0x73, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x29, 0x20, 0x46, 0xC5, 0x91, + 0x74, 0x61, 0x6E, 0xC3, 0xBA, 0x73, 0xC3, 0xAD, 0x74, 0x76, 0xC3, 0xA1, + 0x6E, 0x79 +}; + +static const unsigned char TA699_RSA_N[] = { + 0xC4, 0x24, 0x5E, 0x73, 0xBE, 0x4B, 0x6D, 0x14, 0xC3, 0xA1, 0xF4, 0xE3, + 0x97, 0x90, 0x6E, 0xD2, 0x30, 0x45, 0x1E, 0x3C, 0xEE, 0x67, 0xD9, 0x64, + 0xE0, 0x1A, 0x8A, 0x7F, 0xCA, 0x30, 0xCA, 0x83, 0xE3, 0x20, 0xC1, 0xE3, + 0xF4, 0x3A, 0xD3, 0x94, 0x5F, 0x1A, 0x7C, 0x5B, 0x6D, 0xBF, 0x30, 0x4F, + 0x84, 0x27, 0xF6, 0x9F, 0x1F, 0x49, 0xBC, 0xC6, 0x99, 0x0A, 0x90, 0xF2, + 0x0F, 0xF5, 0x7F, 0x43, 0x84, 0x37, 0x63, 0x51, 0x8B, 0x7A, 0xA5, 0x70, + 0xFC, 0x7A, 0x58, 0xCD, 0x8E, 0x9B, 0xED, 0xC3, 0x46, 0x6C, 0x84, 0x70, + 0x5D, 0xDA, 0xF3, 0x01, 0x90, 0x23, 0xFC, 0x4E, 0x30, 0xA9, 0x7E, 0xE1, + 0x27, 0x63, 0xE7, 0xED, 0x64, 0x3C, 0xA0, 0xB8, 0xC9, 0x33, 0x63, 0xFE, + 0x16, 0x90, 0xFF, 0xB0, 0xB8, 0xFD, 0xD7, 0xA8, 0xC0, 0xC0, 0x94, 0x43, + 0x0B, 0xB6, 0xD5, 0x59, 0xA6, 0x9E, 0x56, 0xD0, 0x24, 0x1F, 0x70, 0x79, + 0xAF, 0xDB, 0x39, 0x54, 0x0D, 0x65, 0x75, 0xD9, 0x15, 0x41, 0x94, 0x01, + 0xAF, 0x5E, 0xEC, 0xF6, 0x8D, 0xF1, 0xFF, 0xAD, 0x64, 0xFE, 0x20, 0x9A, + 0xD7, 0x5C, 0xEB, 0xFE, 0xA6, 0x1F, 0x08, 0x64, 0xA3, 0x8B, 0x76, 0x55, + 0xAD, 0x1E, 0x3B, 0x28, 0x60, 0x2E, 0x87, 0x25, 0xE8, 0xAA, 0xAF, 0x1F, + 0xC6, 0x64, 0x46, 0x20, 0xB7, 0x70, 0x7F, 0x3C, 0xDE, 0x48, 0xDB, 0x96, + 0x53, 0xB7, 0x39, 0x77, 0xE4, 0x1A, 0xE2, 0xC7, 0x16, 0x84, 0x76, 0x97, + 0x5B, 0x2F, 0xBB, 0x19, 0x15, 0x85, 0xF8, 0x69, 0x85, 0xF5, 0x99, 0xA7, + 0xA9, 0xF2, 0x34, 0xA7, 0xA9, 0xB6, 0xA6, 0x03, 0xFC, 0x6F, 0x86, 0x3D, + 0x54, 0x7C, 0x76, 0x04, 0x9B, 0x6B, 0xF9, 0x40, 0x5D, 0x00, 0x34, 0xC7, + 0x2E, 0x99, 0x75, 0x9D, 0xE5, 0x88, 0x03, 0xAA, 0x4D, 0xF8, 0x03, 0xD2, + 0x42, 0x76, 0xC0, 0x1B +}; + +static const unsigned char TA699_RSA_E[] = { + 0xA8, 0x8B +}; + +static const unsigned char TA700_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x42, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA700_RSA_N[] = { + 0xD8, 0x17, 0xB7, 0x1C, 0x4A, 0x24, 0x2A, 0xD6, 0x97, 0xB1, 0xCA, 0xE2, + 0x1E, 0xFB, 0x7D, 0x38, 0xEF, 0x98, 0xF5, 0xB2, 0x39, 0x98, 0x4E, 0x27, + 0xB8, 0x11, 0x5D, 0x7B, 0xD2, 0x25, 0x94, 0x88, 0x82, 0x15, 0x26, 0x6A, + 0x1B, 0x31, 0xBB, 0xA8, 0x5B, 0x21, 0x21, 0x2B, 0xD8, 0x0F, 0x4E, 0x9F, + 0x5A, 0xF1, 0xB1, 0x5A, 0xE4, 0x79, 0xD6, 0x32, 0x23, 0x2B, 0xE1, 0x53, + 0xCC, 0x99, 0x45, 0x5C, 0x7B, 0x4F, 0xAD, 0xBC, 0xBF, 0x87, 0x4A, 0x0B, + 0x4B, 0x97, 0x5A, 0xA8, 0xF6, 0x48, 0xEC, 0x7D, 0x7B, 0x0D, 0xCD, 0x21, + 0x06, 0xDF, 0x9E, 0x15, 0xFD, 0x41, 0x8A, 0x48, 0xB7, 0x20, 0xF4, 0xA1, + 0x7A, 0x1B, 0x57, 0xD4, 0x5D, 0x50, 0xFF, 0xBA, 0x67, 0xD8, 0x23, 0x99, + 0x1F, 0xC8, 0x3F, 0xE3, 0xDE, 0xFF, 0x6F, 0x5B, 0x77, 0xB1, 0x6B, 0x6E, + 0xB8, 0xC9, 0x64, 0xF7, 0xE1, 0xCA, 0x41, 0x46, 0x0E, 0x29, 0x71, 0xD0, + 0xB9, 0x23, 0xFC, 0xC9, 0x81, 0x5F, 0x4E, 0xF7, 0x6F, 0xDF, 0xBF, 0x84, + 0xAD, 0x73, 0x64, 0xBB, 0xB7, 0x42, 0x8E, 0x69, 0xF6, 0xD4, 0x76, 0x1D, + 0x7E, 0x9D, 0xA7, 0xB8, 0x57, 0x8A, 0x51, 0x67, 0x72, 0xD7, 0xD4, 0xA8, + 0xB8, 0x95, 0x54, 0x40, 0x73, 0x03, 0xF6, 0xEA, 0xF4, 0xEB, 0xFE, 0x28, + 0x42, 0x77, 0x3F, 0x9D, 0x23, 0x1B, 0xB2, 0xB6, 0x3D, 0x80, 0x14, 0x07, + 0x4C, 0x2E, 0x4F, 0xF7, 0xD5, 0x0A, 0x16, 0x0D, 0xBD, 0x66, 0x43, 0x37, + 0x7E, 0x23, 0x43, 0x79, 0xC3, 0x40, 0x86, 0xF5, 0x4C, 0x29, 0xDA, 0x8E, + 0x9A, 0xAD, 0x0D, 0xA5, 0x04, 0x87, 0x88, 0x1E, 0x85, 0xE3, 0xE9, 0x53, + 0xD5, 0x9B, 0xC8, 0x8B, 0x03, 0x63, 0x78, 0xEB, 0xE0, 0x19, 0x4A, 0x6E, + 0xBB, 0x2F, 0x6B, 0x33, 0x64, 0x58, 0x93, 0xAD, 0x69, 0xBF, 0x8F, 0x1B, + 0xEF, 0x82, 0x48, 0xC7 +}; + +static const unsigned char TA700_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA701_DN[] = { + 0x30, 0x6D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x07, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x19, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x46, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x45, 0x6E, 0x64, 0x6F, 0x72, 0x73, 0x65, 0x64, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1F, 0x4F, 0x49, 0x53, 0x54, + 0x45, 0x20, 0x57, 0x49, 0x53, 0x65, 0x4B, 0x65, 0x79, 0x20, 0x47, 0x6C, + 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x47, 0x43, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA701_EC_Q[] = { + 0x04, 0x4C, 0xE9, 0x50, 0xC0, 0xC6, 0x0F, 0x72, 0x18, 0xBC, 0xD8, 0xF1, + 0xBA, 0xB3, 0x89, 0xE2, 0x79, 0x4A, 0xA3, 0x16, 0xA7, 0x6B, 0x54, 0x24, + 0xDB, 0x51, 0xFF, 0xEA, 0xF4, 0x09, 0x24, 0xC3, 0x0B, 0x22, 0x9F, 0xCB, + 0x6A, 0x27, 0x82, 0x81, 0x0D, 0xD2, 0xC0, 0xAF, 0x31, 0xE4, 0x74, 0x82, + 0x6E, 0xCA, 0x25, 0xD9, 0x8C, 0x75, 0x9D, 0xF1, 0xDB, 0xD0, 0x9A, 0xA2, + 0x4B, 0x21, 0x7E, 0x16, 0xA7, 0x63, 0x90, 0xD2, 0x39, 0xD4, 0xB1, 0x87, + 0x78, 0x5F, 0x18, 0x96, 0x0F, 0x50, 0x1B, 0x35, 0x37, 0x0F, 0x6A, 0xC6, + 0xDC, 0xD9, 0x13, 0x4D, 0xA4, 0x8E, 0x90, 0x37, 0xE6, 0xBD, 0x5B, 0x31, + 0x91 +}; + +static const unsigned char TA702_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA702_RSA_N[] = { + 0xA0, 0xBE, 0x50, 0x10, 0x8E, 0xE9, 0xF2, 0x6C, 0x40, 0xB4, 0x04, 0x9C, + 0x85, 0xB9, 0x31, 0xCA, 0xDC, 0x2D, 0xE4, 0x11, 0xA9, 0x04, 0x3C, 0x1B, + 0x55, 0xC1, 0xE7, 0x58, 0x30, 0x1D, 0x24, 0xB4, 0xC3, 0xEF, 0x85, 0xDE, + 0x8C, 0x2C, 0xE1, 0xC1, 0x3D, 0xDF, 0x82, 0xE6, 0x4F, 0xAD, 0x47, 0x87, + 0x6C, 0xEC, 0x5B, 0x49, 0xC1, 0x4A, 0xD5, 0xBB, 0x8F, 0xEC, 0x87, 0xAC, + 0x7F, 0x82, 0x9A, 0x86, 0xEC, 0x3D, 0x03, 0x99, 0x52, 0x01, 0xD2, 0x35, + 0x9E, 0xAC, 0xDA, 0xF0, 0x53, 0xC9, 0x66, 0x3C, 0xD4, 0xAC, 0x02, 0x01, + 0xDA, 0x24, 0xD3, 0x3B, 0xA8, 0x02, 0x46, 0xAF, 0xA4, 0x1C, 0xE3, 0xF8, + 0x73, 0x58, 0x76, 0xB7, 0xF6, 0x0E, 0x90, 0x0D, 0xB5, 0xF0, 0xCF, 0xCC, + 0xFA, 0xF9, 0xC6, 0x4C, 0xE5, 0xC3, 0x86, 0x30, 0x0A, 0x8D, 0x17, 0x7E, + 0x35, 0xEB, 0xC5, 0xDF, 0xBB, 0x0E, 0x9C, 0xC0, 0x8D, 0x87, 0xE3, 0x88, + 0x38, 0x85, 0x67, 0xFA, 0x3E, 0xC7, 0xAB, 0xE0, 0x13, 0x9C, 0x05, 0x18, + 0x98, 0xCF, 0x93, 0xF5, 0xB1, 0x92, 0xB4, 0xFC, 0x23, 0xD3, 0xCF, 0xD5, + 0xC4, 0x27, 0x49, 0xE0, 0x9E, 0x3C, 0x9B, 0x08, 0xA3, 0x8B, 0x5D, 0x2A, + 0x21, 0xE0, 0xFC, 0x39, 0xAA, 0x53, 0xDA, 0x7D, 0x7E, 0xCF, 0x1A, 0x09, + 0x53, 0xBC, 0x5D, 0x05, 0x04, 0xCF, 0xA1, 0x4A, 0x8F, 0x8B, 0x76, 0x82, + 0x0D, 0xA1, 0xF8, 0xD2, 0xC7, 0x14, 0x77, 0x5B, 0x90, 0x36, 0x07, 0x81, + 0x9B, 0x3E, 0x06, 0xFA, 0x52, 0x5E, 0x63, 0xC5, 0xA6, 0x00, 0xFE, 0xA5, + 0xE9, 0x52, 0x1B, 0x52, 0xB5, 0x92, 0x39, 0x72, 0x03, 0x09, 0x62, 0xBD, + 0xB0, 0x60, 0x16, 0x6E, 0xA6, 0xDD, 0x25, 0xC2, 0x03, 0x66, 0xDD, 0xF3, + 0x04, 0xD1, 0x40, 0xE2, 0x4E, 0x8B, 0x86, 0xF4, 0x6F, 0xE5, 0x83, 0xA0, + 0x27, 0x84, 0x5E, 0x04, 0xC1, 0xF5, 0x90, 0xBD, 0x30, 0x3D, 0xC4, 0xEF, + 0xA8, 0x69, 0xBC, 0x38, 0x9B, 0xA4, 0xA4, 0x96, 0xD1, 0x62, 0xDA, 0x69, + 0xC0, 0x01, 0x96, 0xAE, 0xCB, 0xC4, 0x51, 0x34, 0xEA, 0x0C, 0xAA, 0xFF, + 0x21, 0x8E, 0x59, 0x8F, 0x4A, 0x5C, 0xE4, 0x61, 0x9A, 0xA7, 0xD2, 0xE9, + 0x2A, 0x78, 0x8D, 0x51, 0x3D, 0x3A, 0x15, 0xEE, 0xA2, 0x59, 0x8E, 0xA9, + 0x5C, 0xDE, 0xC5, 0xF9, 0x90, 0x22, 0xE5, 0x88, 0x45, 0x71, 0xDD, 0x91, + 0x99, 0x6C, 0x7A, 0x9F, 0x3D, 0x3D, 0x98, 0x7C, 0x5E, 0xF6, 0xBE, 0x16, + 0x68, 0xA0, 0x5E, 0xAE, 0x0B, 0x23, 0xFC, 0x5A, 0x0F, 0xAA, 0x22, 0x76, + 0x2D, 0xC9, 0xA1, 0x10, 0x1D, 0xE4, 0xD3, 0x44, 0x23, 0x90, 0x88, 0x9F, + 0xC6, 0x2A, 0xE6, 0xD7, 0xF5, 0x9A, 0xB3, 0x58, 0x1E, 0x2F, 0x30, 0x89, + 0x08, 0x1B, 0x54, 0xA2, 0xB5, 0x98, 0x23, 0xEC, 0x08, 0x77, 0x1C, 0x95, + 0x5D, 0x61, 0xD1, 0xCB, 0x89, 0x9C, 0x5F, 0xA2, 0x4A, 0x91, 0x9A, 0xEF, + 0x21, 0xAA, 0x49, 0x16, 0x08, 0xA8, 0xBD, 0x61, 0x28, 0x31, 0xC9, 0x74, + 0xAD, 0x85, 0xF6, 0xD9, 0xC5, 0xB1, 0x8B, 0xD1, 0xE5, 0x10, 0x32, 0x4D, + 0x5F, 0x8B, 0x20, 0x3A, 0x3C, 0x49, 0x1F, 0x33, 0x85, 0x59, 0x0D, 0xDB, + 0xCB, 0x09, 0x75, 0x43, 0x69, 0x73, 0xFB, 0x6B, 0x71, 0x7D, 0xF0, 0xDF, + 0xC4, 0x4C, 0x7D, 0xC6, 0xA3, 0x2E, 0xC8, 0x95, 0x79, 0xCB, 0x73, 0xA2, + 0x8E, 0x4E, 0x4D, 0x24, 0xFB, 0x5E, 0xE4, 0x04, 0xBE, 0x72, 0x1B, 0xA6, + 0x27, 0x2D, 0x49, 0x5A, 0x99, 0x7A, 0xD7, 0x5C, 0x09, 0x20, 0xB7, 0x7F, + 0x94, 0xB9, 0x4F, 0xF1, 0x0D, 0x1C, 0x5E, 0x88, 0x42, 0x1B, 0x11, 0xB7, + 0xE7, 0x91, 0xDB, 0x9E, 0x6C, 0xF4, 0x6A, 0xDF, 0x8C, 0x06, 0x98, 0x03, + 0xAD, 0xCC, 0x28, 0xEF, 0xA5, 0x47, 0xF3, 0x53 +}; + +static const unsigned char TA702_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA703_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA703_RSA_N[] = { + 0xA1, 0xAE, 0x25, 0xB2, 0x01, 0x18, 0xDC, 0x57, 0x88, 0x3F, 0x46, 0xEB, + 0xF9, 0xAF, 0xE2, 0xEB, 0x23, 0x71, 0xE2, 0x9A, 0xD1, 0x61, 0x66, 0x21, + 0x5F, 0xAA, 0xAF, 0x27, 0x51, 0xE5, 0x6E, 0x1B, 0x16, 0xD4, 0x2D, 0x7D, + 0x50, 0xB0, 0x53, 0x77, 0xBD, 0x78, 0x3A, 0x60, 0xE2, 0x64, 0x02, 0x9B, + 0x7C, 0x86, 0x9B, 0xD6, 0x1A, 0x8E, 0xAD, 0xFF, 0x1F, 0x15, 0x7F, 0xD5, + 0x95, 0x1E, 0x12, 0xCB, 0xE6, 0x14, 0x84, 0x04, 0xC1, 0xDF, 0x36, 0xB3, + 0x16, 0x9F, 0x8A, 0xE3, 0xC9, 0xDB, 0x98, 0x34, 0xCE, 0xD8, 0x33, 0x17, + 0x28, 0x46, 0xFC, 0xA7, 0xC9, 0xF0, 0xD2, 0xB4, 0xD5, 0x4D, 0x09, 0x72, + 0x49, 0xF9, 0xF2, 0x87, 0xE3, 0xA9, 0xDA, 0x7D, 0xA1, 0x7D, 0x6B, 0xB2, + 0x3A, 0x25, 0xA9, 0x6D, 0x52, 0x44, 0xAC, 0xF8, 0xBE, 0x6E, 0xFB, 0xDC, + 0xA6, 0x73, 0x91, 0x90, 0x61, 0xA6, 0x03, 0x14, 0x20, 0xF2, 0xE7, 0x87, + 0xA3, 0x88, 0xAD, 0xAD, 0xA0, 0x8C, 0xFF, 0xA6, 0x0B, 0x25, 0x52, 0x25, + 0xE7, 0x16, 0x01, 0xD5, 0xCB, 0xB8, 0x35, 0x81, 0x0C, 0xA3, 0x3B, 0xF0, + 0xE1, 0xE1, 0xFC, 0x5A, 0x5D, 0xCE, 0x80, 0x71, 0x6D, 0xF8, 0x49, 0xAB, + 0x3E, 0x3B, 0xBA, 0xB8, 0xD7, 0x80, 0x01, 0xFB, 0xA5, 0xEB, 0x5B, 0xB3, + 0xC5, 0x5E, 0x60, 0x2A, 0x31, 0xA0, 0xAF, 0x37, 0xE8, 0x20, 0x3A, 0x9F, + 0xA8, 0x32, 0x2C, 0x0C, 0xCC, 0x09, 0x1D, 0xD3, 0x9E, 0x8E, 0x5D, 0xBC, + 0x4C, 0x98, 0xEE, 0xC5, 0x1A, 0x68, 0x7B, 0xEC, 0x53, 0xA6, 0xE9, 0x14, + 0x35, 0xA3, 0xDF, 0xCD, 0x80, 0x9F, 0x0C, 0x48, 0xFB, 0x1C, 0xF4, 0xF1, + 0xBF, 0x4A, 0xB8, 0xFA, 0xD5, 0x8C, 0x71, 0x4A, 0xC7, 0x1F, 0xAD, 0xFE, + 0x41, 0x9A, 0xB3, 0x83, 0x5D, 0xF2, 0x84, 0x56, 0xEF, 0xA5, 0x57, 0x43, + 0xCE, 0x29, 0xAD, 0x8C, 0xAB, 0x55, 0xBF, 0xC4, 0xFB, 0x5B, 0x01, 0xDD, + 0x23, 0x21, 0xA1, 0x58, 0x00, 0x8E, 0xC3, 0xD0, 0x6A, 0x13, 0xED, 0x13, + 0xE3, 0x12, 0x2B, 0x80, 0xDC, 0x67, 0xE6, 0x95, 0xB2, 0xCD, 0x1E, 0x22, + 0x6E, 0x2A, 0xF8, 0x41, 0xD4, 0xF2, 0xCA, 0x14, 0x07, 0x8D, 0x8A, 0x55, + 0x12, 0xC6, 0x69, 0xF5, 0xB8, 0x86, 0x68, 0x2F, 0x53, 0x5E, 0xB0, 0xD2, + 0xAA, 0x21, 0xC1, 0x98, 0xE6, 0x30, 0xE3, 0x67, 0x55, 0xC7, 0x9B, 0x6E, + 0xAC, 0x19, 0xA8, 0x55, 0xA6, 0x45, 0x06, 0xD0, 0x23, 0x3A, 0xDB, 0xEB, + 0x65, 0x5D, 0x2A, 0x11, 0x11, 0xF0, 0x3B, 0x4F, 0xCA, 0x6D, 0xF4, 0x34, + 0xC4, 0x71, 0xE4, 0xFF, 0x00, 0x5A, 0xF6, 0x5C, 0xAE, 0x23, 0x60, 0x85, + 0x73, 0xF1, 0xE4, 0x10, 0xB1, 0x25, 0xAE, 0xD5, 0x92, 0xBB, 0x13, 0xC1, + 0x0C, 0xE0, 0x39, 0xDA, 0xB4, 0x39, 0x57, 0xB5, 0xAB, 0x35, 0xAA, 0x72, + 0x21, 0x3B, 0x83, 0x35, 0xE7, 0x31, 0xDF, 0x7A, 0x21, 0x6E, 0xB8, 0x32, + 0x08, 0x7D, 0x1D, 0x32, 0x91, 0x15, 0x4A, 0x62, 0x72, 0xCF, 0xE3, 0x77, + 0xA1, 0xBC, 0xD5, 0x11, 0x1B, 0x76, 0x01, 0x67, 0x08, 0xE0, 0x41, 0x0B, + 0xC3, 0xEB, 0x15, 0x6E, 0xF8, 0xA4, 0x19, 0xD9, 0xA2, 0xAB, 0xAF, 0xE2, + 0x27, 0x52, 0x56, 0x2B, 0x02, 0x8A, 0x2C, 0x14, 0x24, 0xF9, 0xBF, 0x42, + 0x02, 0xBF, 0x26, 0xC8, 0xC6, 0x8F, 0xE0, 0x6E, 0x38, 0x7D, 0x53, 0x2D, + 0xE5, 0xED, 0x98, 0xB3, 0x95, 0x63, 0x68, 0x7F, 0xF9, 0x35, 0xF4, 0xDF, + 0x88, 0xC5, 0x60, 0x35, 0x92, 0xC0, 0x7C, 0x69, 0x1C, 0x61, 0x95, 0x16, + 0xD0, 0xEB, 0xDE, 0x0B, 0xAF, 0x3E, 0x04, 0x10, 0x45, 0x65, 0x58, 0x50, + 0x38, 0xAF, 0x48, 0xF2, 0x59, 0xB6, 0x16, 0xF2, 0x3C, 0x0D, 0x90, 0x02, + 0xC6, 0x70, 0x2E, 0x01, 0xAD, 0x3C, 0x15, 0xD7 +}; + +static const unsigned char TA703_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA704_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32 +}; + +static const unsigned char TA704_RSA_N[] = { + 0x9A, 0x18, 0xCA, 0x4B, 0x94, 0x0D, 0x00, 0x2D, 0xAF, 0x03, 0x29, 0x8A, + 0xF0, 0x0F, 0x81, 0xC8, 0xAE, 0x4C, 0x19, 0x85, 0x1D, 0x08, 0x9F, 0xAB, + 0x29, 0x44, 0x85, 0xF3, 0x2F, 0x81, 0xAD, 0x32, 0x1E, 0x90, 0x46, 0xBF, + 0xA3, 0x86, 0x26, 0x1A, 0x1E, 0xFE, 0x7E, 0x1C, 0x18, 0x3A, 0x5C, 0x9C, + 0x60, 0x17, 0x2A, 0x3A, 0x74, 0x83, 0x33, 0x30, 0x7D, 0x61, 0x54, 0x11, + 0xCB, 0xED, 0xAB, 0xE0, 0xE6, 0xD2, 0xA2, 0x7E, 0xF5, 0x6B, 0x6F, 0x18, + 0xB7, 0x0A, 0x0B, 0x2D, 0xFD, 0xE9, 0x3E, 0xEF, 0x0A, 0xC6, 0xB3, 0x10, + 0xE9, 0xDC, 0xC2, 0x46, 0x17, 0xF8, 0x5D, 0xFD, 0xA4, 0xDA, 0xFF, 0x9E, + 0x49, 0x5A, 0x9C, 0xE6, 0x33, 0xE6, 0x24, 0x96, 0xF7, 0x3F, 0xBA, 0x5B, + 0x2B, 0x1C, 0x7A, 0x35, 0xC2, 0xD6, 0x67, 0xFE, 0xAB, 0x66, 0x50, 0x8B, + 0x6D, 0x28, 0x60, 0x2B, 0xEF, 0xD7, 0x60, 0xC3, 0xC7, 0x93, 0xBC, 0x8D, + 0x36, 0x91, 0xF3, 0x7F, 0xF8, 0xDB, 0x11, 0x13, 0xC4, 0x9C, 0x77, 0x76, + 0xC1, 0xAE, 0xB7, 0x02, 0x6A, 0x81, 0x7A, 0xA9, 0x45, 0x83, 0xE2, 0x05, + 0xE6, 0xB9, 0x56, 0xC1, 0x94, 0x37, 0x8F, 0x48, 0x71, 0x63, 0x22, 0xEC, + 0x17, 0x65, 0x07, 0x95, 0x8A, 0x4B, 0xDF, 0x8F, 0xC6, 0x5A, 0x0A, 0xE5, + 0xB0, 0xE3, 0x5F, 0x5E, 0x6B, 0x11, 0xAB, 0x0C, 0xF9, 0x85, 0xEB, 0x44, + 0xE9, 0xF8, 0x04, 0x73, 0xF2, 0xE9, 0xFE, 0x5C, 0x98, 0x8C, 0xF5, 0x73, + 0xAF, 0x6B, 0xB4, 0x7E, 0xCD, 0xD4, 0x5C, 0x02, 0x2B, 0x4C, 0x39, 0xE1, + 0xB2, 0x95, 0x95, 0x2D, 0x42, 0x87, 0xD7, 0xD5, 0xB3, 0x90, 0x43, 0xB7, + 0x6C, 0x13, 0xF1, 0xDE, 0xDD, 0xF6, 0xC4, 0xF8, 0x89, 0x3F, 0xD1, 0x75, + 0xF5, 0x92, 0xC3, 0x91, 0xD5, 0x8A, 0x88, 0xD0, 0x90, 0xEC, 0xDC, 0x6D, + 0xDE, 0x89, 0xC2, 0x65, 0x71, 0x96, 0x8B, 0x0D, 0x03, 0xFD, 0x9C, 0xBF, + 0x5B, 0x16, 0xAC, 0x92, 0xDB, 0xEA, 0xFE, 0x79, 0x7C, 0xAD, 0xEB, 0xAF, + 0xF7, 0x16, 0xCB, 0xDB, 0xCD, 0x25, 0x2B, 0xE5, 0x1F, 0xFB, 0x9A, 0x9F, + 0xE2, 0x51, 0xCC, 0x3A, 0x53, 0x0C, 0x48, 0xE6, 0x0E, 0xBD, 0xC9, 0xB4, + 0x76, 0x06, 0x52, 0xE6, 0x11, 0x13, 0x85, 0x72, 0x63, 0x03, 0x04, 0xE0, + 0x04, 0x36, 0x2B, 0x20, 0x19, 0x02, 0xE8, 0x74, 0xA7, 0x1F, 0xB6, 0xC9, + 0x56, 0x66, 0xF0, 0x75, 0x25, 0xDC, 0x67, 0xC1, 0x0E, 0x61, 0x60, 0x88, + 0xB3, 0x3E, 0xD1, 0xA8, 0xFC, 0xA3, 0xDA, 0x1D, 0xB0, 0xD1, 0xB1, 0x23, + 0x54, 0xDF, 0x44, 0x76, 0x6D, 0xED, 0x41, 0xD8, 0xC1, 0xB2, 0x22, 0xB6, + 0x53, 0x1C, 0xDF, 0x35, 0x1D, 0xDC, 0xA1, 0x77, 0x2A, 0x31, 0xE4, 0x2D, + 0xF5, 0xE5, 0xE5, 0xDB, 0xC8, 0xE0, 0xFF, 0xE5, 0x80, 0xD7, 0x0B, 0x63, + 0xA0, 0xFF, 0x33, 0xA1, 0x0F, 0xBA, 0x2C, 0x15, 0x15, 0xEA, 0x97, 0xB3, + 0xD2, 0xA2, 0xB5, 0xBE, 0xF2, 0x8C, 0x96, 0x1E, 0x1A, 0x8F, 0x1D, 0x6C, + 0xA4, 0x61, 0x37, 0xB9, 0x86, 0x73, 0x33, 0xD7, 0x97, 0x96, 0x9E, 0x23, + 0x7D, 0x82, 0xA4, 0x4C, 0x81, 0xE2, 0xA1, 0xD1, 0xBA, 0x67, 0x5F, 0x95, + 0x07, 0xA3, 0x27, 0x11, 0xEE, 0x16, 0x10, 0x7B, 0xBC, 0x45, 0x4A, 0x4C, + 0xB2, 0x04, 0xD2, 0xAB, 0xEF, 0xD5, 0xFD, 0x0C, 0x51, 0xCE, 0x50, 0x6A, + 0x08, 0x31, 0xF9, 0x91, 0xDA, 0x0C, 0x8F, 0x64, 0x5C, 0x03, 0xC3, 0x3A, + 0x8B, 0x20, 0x3F, 0x6E, 0x8D, 0x67, 0x3D, 0x3A, 0xD6, 0xFE, 0x7D, 0x5B, + 0x88, 0xC9, 0x5E, 0xFB, 0xCC, 0x61, 0xDC, 0x8B, 0x33, 0x77, 0xD3, 0x44, + 0x32, 0x35, 0x09, 0x62, 0x04, 0x92, 0x16, 0x10, 0xD8, 0x9E, 0x27, 0x47, + 0xFB, 0x3B, 0x21, 0xE3, 0xF8, 0xEB, 0x1D, 0x5B +}; + +static const unsigned char TA704_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA705_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x15, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33, 0x20, + 0x47, 0x33 +}; + +static const unsigned char TA705_RSA_N[] = { + 0xB3, 0xCB, 0x0E, 0x10, 0x67, 0x8E, 0xEA, 0x14, 0x97, 0xA7, 0x32, 0x2A, + 0x0A, 0x56, 0x36, 0x7F, 0x68, 0x4C, 0xC7, 0xB3, 0x6F, 0x3A, 0x23, 0x14, + 0x91, 0xFF, 0x19, 0x7F, 0xA5, 0xCA, 0xAC, 0xEE, 0xB3, 0x76, 0x9D, 0x7A, + 0xE9, 0x8B, 0x1B, 0xAB, 0x6B, 0x31, 0xDB, 0xFA, 0x0B, 0x53, 0x4C, 0xAF, + 0xC5, 0xA5, 0x1A, 0x79, 0x3C, 0x8A, 0x4C, 0xFF, 0xAC, 0xDF, 0x25, 0xDE, + 0x4E, 0xD9, 0x82, 0x32, 0x0B, 0x44, 0xDE, 0xCA, 0xDB, 0x8C, 0xAC, 0xA3, + 0x6E, 0x16, 0x83, 0x3B, 0xA6, 0x64, 0x4B, 0x32, 0x89, 0xFB, 0x16, 0x16, + 0x38, 0x7E, 0xEB, 0x43, 0xE2, 0xD3, 0x74, 0x4A, 0xC2, 0x62, 0x0A, 0x73, + 0x0A, 0xDD, 0x49, 0xB3, 0x57, 0xD2, 0xB0, 0x0A, 0x85, 0x9D, 0x71, 0x3C, + 0xDE, 0xA3, 0xCB, 0xC0, 0x32, 0xF3, 0x01, 0x39, 0x20, 0x43, 0x1B, 0x35, + 0xD1, 0x53, 0xB3, 0xB1, 0xEE, 0xC5, 0x93, 0x69, 0x82, 0x3E, 0x16, 0xB5, + 0x28, 0x46, 0xA1, 0xDE, 0xEA, 0x89, 0x09, 0xED, 0x43, 0xB8, 0x05, 0x46, + 0x8A, 0x86, 0xF5, 0x59, 0x47, 0xBE, 0x1B, 0x6F, 0x01, 0x21, 0x10, 0xB9, + 0xFD, 0xA9, 0xD2, 0x28, 0xCA, 0x10, 0x39, 0x09, 0xCA, 0x13, 0x36, 0xCF, + 0x9C, 0xAD, 0xAD, 0x40, 0x74, 0x79, 0x2B, 0x02, 0x3F, 0x34, 0xFF, 0xFA, + 0x20, 0x69, 0x7D, 0xD3, 0xEE, 0x61, 0xF5, 0xBA, 0xB3, 0xE7, 0x30, 0xD0, + 0x37, 0x23, 0x86, 0x72, 0x61, 0x45, 0x29, 0x48, 0x59, 0x68, 0x6F, 0x77, + 0xA6, 0x2E, 0x81, 0xBE, 0x07, 0x4D, 0x6F, 0xAF, 0xCE, 0xC4, 0x45, 0x13, + 0x91, 0x14, 0x70, 0x06, 0x8F, 0x1F, 0x9F, 0xF8, 0x87, 0x69, 0xB1, 0x0E, + 0xEF, 0xC3, 0x89, 0x19, 0xEB, 0xEA, 0x1C, 0x61, 0xFC, 0x7A, 0x6C, 0x8A, + 0xDC, 0xD6, 0x03, 0x0B, 0x9E, 0x26, 0xBA, 0x12, 0xDD, 0xD4, 0x54, 0x39, + 0xAB, 0x26, 0xA3, 0x33, 0xEA, 0x75, 0x81, 0xDA, 0x2D, 0xCD, 0x0F, 0x4F, + 0xE4, 0x03, 0xD1, 0xEF, 0x15, 0x97, 0x1B, 0x6B, 0x90, 0xC5, 0x02, 0x90, + 0x93, 0x66, 0x02, 0x21, 0xB1, 0x47, 0xDE, 0x8B, 0x9A, 0x4A, 0x80, 0xB9, + 0x55, 0x8F, 0xB5, 0xA2, 0x2F, 0xC0, 0xD6, 0x33, 0x67, 0xDA, 0x7E, 0xC4, + 0xA7, 0xB4, 0x04, 0x44, 0xEB, 0x47, 0xFB, 0xE6, 0x58, 0xB9, 0xF7, 0x0C, + 0xF0, 0x7B, 0x2B, 0xB1, 0xC0, 0x70, 0x29, 0xC3, 0x40, 0x62, 0x2D, 0x3B, + 0x48, 0x69, 0xDC, 0x23, 0x3C, 0x48, 0xEB, 0x7B, 0x09, 0x79, 0xA9, 0x6D, + 0xDA, 0xA8, 0x30, 0x98, 0xCF, 0x80, 0x72, 0x03, 0x88, 0xA6, 0x5B, 0x46, + 0xAE, 0x72, 0x79, 0x7C, 0x08, 0x03, 0x21, 0x65, 0xAE, 0xB7, 0xE1, 0x1C, + 0xA5, 0xB1, 0x2A, 0xA2, 0x31, 0xDE, 0x66, 0x04, 0xF7, 0xC0, 0x74, 0xE8, + 0x71, 0xDE, 0xFF, 0x3D, 0x59, 0xCC, 0x96, 0x26, 0x12, 0x8B, 0x85, 0x95, + 0x57, 0x1A, 0xAB, 0x6B, 0x75, 0x0B, 0x44, 0x3D, 0x11, 0x28, 0x3C, 0x7B, + 0x61, 0xB7, 0xE2, 0x8F, 0x67, 0x4F, 0xE5, 0xEC, 0x3C, 0x4C, 0x60, 0x80, + 0x69, 0x57, 0x38, 0x1E, 0x01, 0x5B, 0x8D, 0x55, 0xE8, 0xC7, 0xDF, 0xC0, + 0xCC, 0x77, 0x23, 0x34, 0x49, 0x75, 0x7C, 0xF6, 0x98, 0x11, 0xEB, 0x2D, + 0xDE, 0xED, 0x41, 0x2E, 0x14, 0x05, 0x02, 0x7F, 0xE0, 0xFE, 0x20, 0xEB, + 0x35, 0xE7, 0x11, 0xAC, 0x22, 0xCE, 0x57, 0x3D, 0xDE, 0xC9, 0x30, 0x6D, + 0x10, 0x03, 0x85, 0xCD, 0xF1, 0xFF, 0x8C, 0x16, 0xB5, 0xC1, 0xB2, 0x3E, + 0x88, 0x6C, 0x60, 0x7F, 0x90, 0x4F, 0x95, 0xF7, 0xF6, 0x2D, 0xAD, 0x01, + 0x39, 0x07, 0x04, 0xFA, 0x75, 0x80, 0x7D, 0xBF, 0x49, 0x50, 0xED, 0xEF, + 0xC9, 0xC4, 0x7C, 0x1C, 0xEB, 0x80, 0x7E, 0xDB, 0xB6, 0xD0, 0xDD, 0x13, + 0xFE, 0xC9, 0xD3, 0x9C, 0xD7, 0xB2, 0x97, 0xA9 +}; + +static const unsigned char TA705_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA706_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x42, 0x4D, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x10, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, 0x73, 0x20, 0x4C, + 0x69, 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x51, 0x75, 0x6F, 0x56, 0x61, 0x64, 0x69, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x33 +}; + +static const unsigned char TA706_RSA_N[] = { + 0xCC, 0x57, 0x42, 0x16, 0x54, 0x9C, 0xE6, 0x98, 0xD3, 0xD3, 0x4D, 0xEE, + 0xFE, 0xED, 0xC7, 0x9F, 0x43, 0x39, 0x4A, 0x65, 0xB3, 0xE8, 0x16, 0x88, + 0x34, 0xDB, 0x0D, 0x59, 0x91, 0x74, 0xCF, 0x92, 0xB8, 0x04, 0x40, 0xAD, + 0x02, 0x4B, 0x31, 0xAB, 0xBC, 0x8D, 0x91, 0x68, 0xD8, 0x20, 0x0E, 0x1A, + 0x01, 0xE2, 0x1A, 0x7B, 0x4E, 0x17, 0x5D, 0xE2, 0x8A, 0xB7, 0x3F, 0x99, + 0x1A, 0xCD, 0xEB, 0x61, 0xAB, 0xC2, 0x65, 0xA6, 0x1F, 0xB7, 0xB7, 0xBD, + 0xB7, 0x8F, 0xFC, 0xFD, 0x70, 0x8F, 0x0B, 0xA0, 0x67, 0xBE, 0x01, 0xA2, + 0x59, 0xCF, 0x71, 0xE6, 0x0F, 0x29, 0x76, 0xFF, 0xB1, 0x56, 0x79, 0x45, + 0x2B, 0x1F, 0x9E, 0x7A, 0x54, 0xE8, 0xA3, 0x29, 0x35, 0x68, 0xA4, 0x01, + 0x4F, 0x0F, 0xA4, 0x2E, 0x37, 0xEF, 0x1B, 0xBF, 0xE3, 0x8F, 0x10, 0xA8, + 0x72, 0xAB, 0x58, 0x57, 0xE7, 0x54, 0x86, 0xC8, 0xC9, 0xF3, 0x5B, 0xDA, + 0x2C, 0xDA, 0x5D, 0x8E, 0x6E, 0x3C, 0xA3, 0x3E, 0xDA, 0xFB, 0x82, 0xE5, + 0xDD, 0xF2, 0x5C, 0xB2, 0x05, 0x33, 0x6F, 0x8A, 0x36, 0xCE, 0xD0, 0x13, + 0x4E, 0xFF, 0xBF, 0x4A, 0x0C, 0x34, 0x4C, 0xA6, 0xC3, 0x21, 0xBD, 0x50, + 0x04, 0x55, 0xEB, 0xB1, 0xBB, 0x9D, 0xFB, 0x45, 0x1E, 0x64, 0x15, 0xDE, + 0x55, 0x01, 0x8C, 0x02, 0x76, 0xB5, 0xCB, 0xA1, 0x3F, 0x42, 0x69, 0xBC, + 0x2F, 0xBD, 0x68, 0x43, 0x16, 0x56, 0x89, 0x2A, 0x37, 0x61, 0x91, 0xFD, + 0xA6, 0xAE, 0x4E, 0xC0, 0xCB, 0x14, 0x65, 0x94, 0x37, 0x4B, 0x92, 0x06, + 0xEF, 0x04, 0xD0, 0xC8, 0x9C, 0x88, 0xDB, 0x0B, 0x7B, 0x81, 0xAF, 0xB1, + 0x3D, 0x2A, 0xC4, 0x65, 0x3A, 0x78, 0xB6, 0xEE, 0xDC, 0x80, 0xB1, 0xD2, + 0xD3, 0x99, 0x9C, 0x3A, 0xEE, 0x6B, 0x5A, 0x6B, 0xB3, 0x8D, 0xB7, 0xD5, + 0xCE, 0x9C, 0xC2, 0xBE, 0xA5, 0x4B, 0x2F, 0x16, 0xB1, 0x9E, 0x68, 0x3B, + 0x06, 0x6F, 0xAE, 0x7D, 0x9F, 0xF8, 0xDE, 0xEC, 0xCC, 0x29, 0xA7, 0x98, + 0xA3, 0x25, 0x43, 0x2F, 0xEF, 0xF1, 0x5F, 0x26, 0xE1, 0x88, 0x4D, 0xF8, + 0x5E, 0x6E, 0xD7, 0xD9, 0x14, 0x6E, 0x19, 0x33, 0x69, 0xA7, 0x3B, 0x84, + 0x89, 0x93, 0xC4, 0x53, 0x55, 0x13, 0xA1, 0x51, 0x78, 0x40, 0xF8, 0xB8, + 0xC9, 0xA2, 0xEE, 0x7B, 0xBA, 0x52, 0x42, 0x83, 0x9E, 0x14, 0xED, 0x05, + 0x52, 0x5A, 0x59, 0x56, 0xA7, 0x97, 0xFC, 0x9D, 0x3F, 0x0A, 0x29, 0xD8, + 0xDC, 0x4F, 0x91, 0x0E, 0x13, 0xBC, 0xDE, 0x95, 0xA4, 0xDF, 0x8B, 0x99, + 0xBE, 0xAC, 0x9B, 0x33, 0x88, 0xEF, 0xB5, 0x81, 0xAF, 0x1B, 0xC6, 0x22, + 0x53, 0xC8, 0xF6, 0xC7, 0xEE, 0x97, 0x14, 0xB0, 0xC5, 0x7C, 0x78, 0x52, + 0xC8, 0xF0, 0xCE, 0x6E, 0x77, 0x60, 0x84, 0xA6, 0xE9, 0x2A, 0x76, 0x20, + 0xED, 0x58, 0x01, 0x17, 0x30, 0x93, 0xE9, 0x1A, 0x8B, 0xE0, 0x73, 0x63, + 0xD9, 0x6A, 0x92, 0x94, 0x49, 0x4E, 0xB4, 0xAD, 0x4A, 0x85, 0xC4, 0xA3, + 0x22, 0x30, 0xFC, 0x09, 0xED, 0x68, 0x22, 0x73, 0xA6, 0x88, 0x0C, 0x55, + 0x21, 0x58, 0xC5, 0xE1, 0x3A, 0x9F, 0x2A, 0xDD, 0xCA, 0xE1, 0x90, 0xE0, + 0xD9, 0x73, 0xAB, 0x6C, 0x80, 0xB8, 0xE8, 0x0B, 0x64, 0x93, 0xA0, 0x9C, + 0x8C, 0x19, 0xFF, 0xB3, 0xD2, 0x0C, 0xEC, 0x91, 0x26, 0x87, 0x8A, 0xB3, + 0xA2, 0xE1, 0x70, 0x8F, 0x2C, 0x0A, 0xE5, 0xCD, 0x6D, 0x68, 0x51, 0xEB, + 0xDA, 0x3F, 0x05, 0x7F, 0x8B, 0x32, 0xE6, 0x13, 0x5C, 0x6B, 0xFE, 0x5F, + 0x40, 0xE2, 0x22, 0xC8, 0xB4, 0xB4, 0x64, 0x4F, 0xD6, 0xBA, 0x7D, 0x48, + 0x3E, 0xA8, 0x69, 0x0C, 0xD7, 0xBB, 0x86, 0x71, 0xC9, 0x73, 0xB8, 0x3F, + 0x3B, 0x9D, 0x25, 0x4B, 0xDA, 0xFF, 0x40, 0xEB +}; + +static const unsigned char TA706_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA707_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x45, 0x34, + 0x36 +}; + +static const unsigned char TA707_EC_Q[] = { + 0x04, 0x76, 0xFA, 0x99, 0xA9, 0x6E, 0x20, 0xED, 0xF9, 0xD7, 0x77, 0xE3, + 0x07, 0x3B, 0xA8, 0xDB, 0x3D, 0x5F, 0x38, 0xE8, 0xAB, 0x55, 0xA6, 0x56, + 0x4F, 0xD6, 0x48, 0xEA, 0xEC, 0x7F, 0x2D, 0xAA, 0xC3, 0xB2, 0xC5, 0x79, + 0xEC, 0x99, 0x61, 0x7F, 0x10, 0x79, 0xC7, 0x02, 0x5A, 0xF9, 0x04, 0x37, + 0xF5, 0x34, 0x35, 0x2B, 0x77, 0xCE, 0x7F, 0x20, 0x8F, 0x52, 0xA3, 0x00, + 0x89, 0xEC, 0xD5, 0xA7, 0xA2, 0x6D, 0x5B, 0xE3, 0x4B, 0x92, 0x93, 0xA0, + 0x80, 0xF5, 0x01, 0x94, 0xDC, 0xF0, 0x68, 0x07, 0x1E, 0xCD, 0xEE, 0xFE, + 0x25, 0x52, 0xB5, 0x20, 0x43, 0x1C, 0x1B, 0xFE, 0xEB, 0x19, 0xCE, 0x43, + 0xA3 +}; + +static const unsigned char TA708_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x47, 0x42, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0F, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, 0x4C, 0x69, + 0x6D, 0x69, 0x74, 0x65, 0x64, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x2D, 0x53, 0x65, 0x63, 0x74, 0x69, 0x67, 0x6F, 0x20, + 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x52, 0x34, + 0x36 +}; + +static const unsigned char TA708_RSA_N[] = { + 0x93, 0xBE, 0xD5, 0x36, 0x52, 0x75, 0xD8, 0x01, 0x23, 0xA0, 0x1C, 0x47, + 0x42, 0x49, 0xEE, 0x63, 0xB6, 0xB7, 0x21, 0xFD, 0xC4, 0x95, 0xD5, 0x48, + 0x2B, 0x26, 0x7C, 0x14, 0x53, 0x10, 0xDA, 0x79, 0xFD, 0x2B, 0xB7, 0x2D, + 0xA4, 0xD4, 0x2C, 0xFA, 0xEA, 0x32, 0xDD, 0x49, 0xC2, 0xB9, 0xBD, 0x0F, + 0x48, 0x3D, 0x7B, 0x5A, 0x98, 0x54, 0xAF, 0x9E, 0x5D, 0x31, 0x74, 0x4F, + 0x07, 0xFC, 0x50, 0x21, 0xDD, 0xA4, 0xCF, 0x68, 0x4F, 0x1B, 0x12, 0x63, + 0x6D, 0x25, 0x99, 0x4C, 0x2A, 0x99, 0xF3, 0x48, 0x30, 0x61, 0xFA, 0x81, + 0x7C, 0x1E, 0xA7, 0x08, 0x4A, 0xDC, 0x3E, 0x2B, 0x1C, 0x1F, 0x18, 0x4C, + 0x71, 0xAA, 0x35, 0x8C, 0xAD, 0xF8, 0x6E, 0xE8, 0x3B, 0x4A, 0xD9, 0xE5, + 0x94, 0x02, 0xD6, 0x89, 0x84, 0x13, 0xAA, 0x6D, 0xC8, 0x4F, 0x33, 0xCC, + 0x50, 0x96, 0x37, 0x92, 0x33, 0xDC, 0x5F, 0x88, 0xE7, 0x9F, 0x54, 0xD9, + 0x48, 0xF0, 0x98, 0x43, 0xD6, 0x66, 0xFD, 0x9F, 0x17, 0x38, 0x43, 0xC5, + 0x01, 0x51, 0x0B, 0xD7, 0xE3, 0x23, 0x0F, 0x14, 0x5D, 0x5B, 0x14, 0xE7, + 0x4B, 0xBE, 0xDD, 0xF4, 0xC8, 0xDA, 0x03, 0x37, 0xD1, 0xD6, 0x39, 0xA1, + 0x21, 0x51, 0x30, 0x83, 0xB0, 0x6D, 0xD7, 0x30, 0x4E, 0x96, 0x5B, 0x91, + 0xF0, 0x70, 0x24, 0xAB, 0xBF, 0x45, 0x81, 0x64, 0x43, 0x0D, 0xBD, 0x21, + 0x3A, 0x2F, 0x3C, 0xE9, 0x9E, 0x0D, 0xCB, 0x20, 0xB5, 0x42, 0x27, 0xCC, + 0xDA, 0x6F, 0x9B, 0xEE, 0x64, 0x30, 0x90, 0x39, 0xCD, 0x93, 0x65, 0x81, + 0x21, 0x31, 0xB5, 0x23, 0x50, 0x33, 0x37, 0x22, 0xE3, 0x38, 0xED, 0xF8, + 0x31, 0x30, 0xCC, 0x45, 0xFE, 0x62, 0xF9, 0xD1, 0x5D, 0x32, 0x79, 0x42, + 0x87, 0xDF, 0x6A, 0xCC, 0x56, 0x19, 0x40, 0x4D, 0xCE, 0xAA, 0xBB, 0xF9, + 0xB5, 0x76, 0x49, 0x94, 0xF1, 0x27, 0xF8, 0x91, 0xA5, 0x83, 0xE5, 0x06, + 0xB3, 0x63, 0x0E, 0x80, 0xDC, 0xE0, 0x12, 0x55, 0x80, 0xA6, 0x3B, 0x66, + 0xB4, 0x39, 0x87, 0x2D, 0xC8, 0xF0, 0xD0, 0xD1, 0x14, 0xE9, 0xE4, 0x0D, + 0x4D, 0x0E, 0xF6, 0x5D, 0x57, 0x72, 0xC5, 0x3B, 0x1C, 0x47, 0x56, 0x9D, + 0xE2, 0xD5, 0xFB, 0x81, 0x61, 0x8C, 0xCC, 0x4D, 0x80, 0x90, 0x34, 0x5B, + 0xB7, 0xD7, 0x14, 0x75, 0xDC, 0xD8, 0x04, 0x48, 0x9F, 0xC0, 0xC1, 0x28, + 0x88, 0xB4, 0xE9, 0x1C, 0xCA, 0xA7, 0xB1, 0xF1, 0x56, 0xB7, 0x7B, 0x49, + 0x4C, 0x59, 0xE5, 0x20, 0x15, 0xA8, 0x84, 0x02, 0x29, 0xFA, 0x38, 0x94, + 0x69, 0x9A, 0x49, 0x06, 0x8F, 0xCD, 0x1F, 0x79, 0x14, 0x17, 0x12, 0x0C, + 0x83, 0x7A, 0xDE, 0x1F, 0xB1, 0x97, 0xEE, 0xF9, 0x97, 0x78, 0x28, 0xA4, + 0xC8, 0x44, 0x92, 0xE9, 0x7D, 0x26, 0x05, 0xA6, 0x58, 0x72, 0x9B, 0x79, + 0x13, 0xD8, 0x11, 0x5F, 0xAE, 0xC5, 0x38, 0x62, 0x34, 0x68, 0xB2, 0x86, + 0x30, 0x8E, 0xF8, 0x90, 0x61, 0x9E, 0x32, 0x6C, 0xF5, 0x07, 0x36, 0xCD, + 0xA2, 0x4C, 0x6E, 0xEC, 0x8A, 0x36, 0xED, 0xF2, 0xE6, 0x99, 0x15, 0x44, + 0x70, 0xC3, 0x7C, 0xBC, 0x9C, 0x39, 0xC0, 0xB4, 0xE1, 0x6B, 0xF7, 0x83, + 0x25, 0x23, 0x57, 0xD9, 0x12, 0x80, 0xE5, 0x49, 0xF0, 0x75, 0x0F, 0xEF, + 0x8D, 0xEB, 0x1C, 0x9B, 0x54, 0x28, 0xB4, 0x21, 0x3C, 0xFC, 0x7C, 0x0A, + 0xFF, 0xEF, 0x7B, 0x6B, 0x75, 0xFF, 0x8B, 0x1D, 0xA0, 0x19, 0x05, 0xAB, + 0xFA, 0xF8, 0x2B, 0x81, 0x42, 0xE8, 0x38, 0xBA, 0xBB, 0xFB, 0xAA, 0xFD, + 0x3D, 0xE0, 0xF3, 0xCA, 0xDF, 0x4E, 0x97, 0x97, 0x29, 0xED, 0xF3, 0x18, + 0x56, 0xE9, 0xA5, 0x96, 0xAC, 0xBD, 0xC3, 0x90, 0x98, 0xB2, 0xE0, 0xF9, + 0xA2, 0xD4, 0xA6, 0x47, 0x43, 0x7C, 0x6D, 0xCF +}; + +static const unsigned char TA708_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA709_DN[] = { + 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA709_RSA_N[] = { + 0xAF, 0x35, 0x2E, 0xD8, 0xAC, 0x6C, 0x55, 0x69, 0x06, 0x71, 0xE5, 0x13, + 0x68, 0x24, 0xB3, 0x4F, 0xD8, 0xCC, 0x21, 0x47, 0xF8, 0xF1, 0x60, 0x38, + 0x89, 0x89, 0x03, 0xE9, 0xBD, 0xEA, 0x5E, 0x46, 0x53, 0x09, 0xDC, 0x5C, + 0xF5, 0x5A, 0xE8, 0xF7, 0x45, 0x2A, 0x02, 0xEB, 0x31, 0x61, 0xD7, 0x29, + 0x33, 0x4C, 0xCE, 0xC7, 0x7C, 0x0A, 0x37, 0x7E, 0x0F, 0xBA, 0x32, 0x98, + 0xE1, 0x1D, 0x97, 0xAF, 0x8F, 0xC7, 0xDC, 0xC9, 0x38, 0x96, 0xF3, 0xDB, + 0x1A, 0xFC, 0x51, 0xED, 0x68, 0xC6, 0xD0, 0x6E, 0xA4, 0x7C, 0x24, 0xD1, + 0xAE, 0x42, 0xC8, 0x96, 0x50, 0x63, 0x2E, 0xE0, 0xFE, 0x75, 0xFE, 0x98, + 0xA7, 0x5F, 0x49, 0x2E, 0x95, 0xE3, 0x39, 0x33, 0x64, 0x8E, 0x1E, 0xA4, + 0x5F, 0x90, 0xD2, 0x67, 0x3C, 0xB2, 0xD9, 0xFE, 0x41, 0xB9, 0x55, 0xA7, + 0x09, 0x8E, 0x72, 0x05, 0x1E, 0x8B, 0xDD, 0x44, 0x85, 0x82, 0x42, 0xD0, + 0x49, 0xC0, 0x1D, 0x60, 0xF0, 0xD1, 0x17, 0x2C, 0x95, 0xEB, 0xF6, 0xA5, + 0xC1, 0x92, 0xA3, 0xC5, 0xC2, 0xA7, 0x08, 0x60, 0x0D, 0x60, 0x04, 0x10, + 0x96, 0x79, 0x9E, 0x16, 0x34, 0xE6, 0xA9, 0xB6, 0xFA, 0x25, 0x45, 0x39, + 0xC8, 0x1E, 0x65, 0xF9, 0x93, 0xF5, 0xAA, 0xF1, 0x52, 0xDC, 0x99, 0x98, + 0x3D, 0xA5, 0x86, 0x1A, 0x0C, 0x35, 0x33, 0xFA, 0x4B, 0xA5, 0x04, 0x06, + 0x15, 0x1C, 0x31, 0x80, 0xEF, 0xAA, 0x18, 0x6B, 0xC2, 0x7B, 0xD7, 0xDA, + 0xCE, 0xF9, 0x33, 0x20, 0xD5, 0xF5, 0xBD, 0x6A, 0x33, 0x2D, 0x81, 0x04, + 0xFB, 0xB0, 0x5C, 0xD4, 0x9C, 0xA3, 0xE2, 0x5C, 0x1D, 0xE3, 0xA9, 0x42, + 0x75, 0x5E, 0x7B, 0xD4, 0x77, 0xEF, 0x39, 0x54, 0xBA, 0xC9, 0x0A, 0x18, + 0x1B, 0x12, 0x99, 0x49, 0x2F, 0x88, 0x4B, 0xFD, 0x50, 0x62, 0xD1, 0x73, + 0xE7, 0x8F, 0x7A, 0x43 +}; + +static const unsigned char TA709_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA710_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x32 +}; + +static const unsigned char TA710_RSA_N[] = { + 0xBA, 0x39, 0xC1, 0x37, 0x7A, 0x68, 0x45, 0x2B, 0x14, 0xB4, 0xEB, 0xE4, + 0x13, 0xEB, 0x57, 0x75, 0x23, 0x4D, 0x8F, 0x24, 0x2D, 0x16, 0xE8, 0xAE, + 0x8E, 0xC9, 0x7D, 0xA4, 0x57, 0x3B, 0x2A, 0x76, 0x25, 0x33, 0x83, 0x6C, + 0xEA, 0x32, 0x8A, 0x94, 0x9B, 0x4E, 0x3C, 0x96, 0xE4, 0xFD, 0x51, 0xBF, + 0x99, 0xC9, 0x93, 0x7E, 0xBF, 0xF9, 0xAD, 0xA7, 0xB2, 0x48, 0x2B, 0x07, + 0x1C, 0x27, 0xF5, 0x4C, 0xBC, 0x70, 0x12, 0x77, 0xA4, 0x85, 0x54, 0xB5, + 0xFD, 0x90, 0x7A, 0xE4, 0xA3, 0xE4, 0x51, 0x58, 0x03, 0xCD, 0x10, 0x79, + 0x79, 0xEE, 0x6B, 0x93, 0x1F, 0x64, 0x8E, 0x6B, 0x64, 0xAB, 0xA3, 0x13, + 0xE3, 0x71, 0xFE, 0x7D, 0xAB, 0x9C, 0xDD, 0x27, 0x53, 0x37, 0xB3, 0xAA, + 0x18, 0xC2, 0x59, 0x26, 0xEC, 0x5B, 0x1F, 0xD2, 0xE6, 0x65, 0x7C, 0xEF, + 0x93, 0xBD, 0xD8, 0x58, 0x5C, 0x0B, 0xC0, 0xE3, 0x65, 0x6F, 0x3C, 0xC7, + 0xCA, 0x59, 0xE3, 0xFE, 0x6E, 0x5F, 0xAC, 0x83, 0xBE, 0xFD, 0x5D, 0x25, + 0x4E, 0x2A, 0x29, 0x3B, 0xD6, 0x0B, 0xAB, 0x17, 0x32, 0x78, 0xA4, 0xE1, + 0x3E, 0x94, 0x46, 0xBE, 0x62, 0x6E, 0x9B, 0xDE, 0x46, 0xA8, 0xB1, 0x16, + 0xE7, 0x85, 0x6E, 0xF4, 0x08, 0x40, 0x45, 0x11, 0xA0, 0x9E, 0x54, 0x44, + 0x84, 0xF7, 0xD8, 0x36, 0xCE, 0xF5, 0x50, 0x47, 0xDC, 0x2C, 0x30, 0x9B, + 0xEE, 0xC0, 0xF5, 0x96, 0xD2, 0xFE, 0x09, 0x86, 0xC7, 0x06, 0x59, 0xAE, + 0x4F, 0xAE, 0x8E, 0x11, 0x98, 0x7B, 0xF3, 0x0B, 0x52, 0xAA, 0x62, 0x26, + 0xAA, 0x21, 0xDF, 0x8E, 0x25, 0x33, 0x79, 0x97, 0x16, 0x49, 0x8D, 0xF5, + 0x3E, 0xD5, 0x47, 0x9F, 0x37, 0x31, 0x49, 0x33, 0x72, 0x05, 0x4D, 0x0C, + 0xB6, 0x55, 0x8C, 0xF1, 0x57, 0x8F, 0x8A, 0x87, 0xD1, 0xAD, 0xC5, 0x11, + 0x12, 0x39, 0xA0, 0xAD +}; + +static const unsigned char TA710_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA711_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x34 +}; + +static const unsigned char TA711_RSA_N[] = { + 0xC5, 0xD2, 0x7A, 0xA1, 0xD6, 0x8A, 0xBF, 0x16, 0x31, 0xD0, 0x98, 0xD1, + 0x3A, 0x94, 0xFC, 0x5A, 0xB8, 0x6E, 0x22, 0xC1, 0x62, 0xF7, 0xA7, 0x0A, + 0x27, 0xEF, 0x50, 0xF6, 0x2E, 0xB1, 0x9E, 0x68, 0x12, 0xF0, 0x6C, 0x24, + 0x63, 0x39, 0xF1, 0xF0, 0xDF, 0x10, 0xC6, 0xDE, 0xB7, 0x52, 0x20, 0xD5, + 0x52, 0x5B, 0x42, 0x99, 0x9E, 0xF3, 0xA0, 0xBE, 0x52, 0x1F, 0x5F, 0xCC, + 0x67, 0x6D, 0xA7, 0x2E, 0x50, 0xA2, 0xC1, 0x97, 0x8D, 0xB6, 0xF8, 0x95, + 0xF5, 0xB0, 0xBA, 0xDC, 0x9D, 0xE0, 0xBE, 0xCB, 0xDF, 0xF7, 0x38, 0xF2, + 0x47, 0xF5, 0xA6, 0x9A, 0x92, 0x95, 0x2A, 0x62, 0x59, 0x50, 0x0B, 0xA2, + 0xB1, 0x35, 0xE7, 0x65, 0xB2, 0x61, 0xB2, 0xEA, 0x92, 0x71, 0x69, 0xE4, + 0x29, 0xF0, 0x4F, 0x81, 0x81, 0x04, 0x3C, 0xB2, 0xA5, 0x5B, 0xD4, 0xC5, + 0xA8, 0x59, 0x67, 0x7B, 0x55, 0x1C, 0x49, 0xAB, 0x7A, 0x9D, 0xC2, 0xE7, + 0x73, 0x4D, 0xEF, 0xCD, 0x09, 0xC2, 0xC4, 0x57, 0x12, 0xDB, 0x01, 0x0E, + 0x23, 0x79, 0x09, 0x07, 0x3B, 0xA2, 0xE8, 0xFC, 0x8A, 0xCF, 0x8F, 0xC0, + 0x46, 0x24, 0x9C, 0x38, 0x27, 0xE0, 0x83, 0x9D, 0x1B, 0xA0, 0xBF, 0x78, + 0x15, 0x10, 0xEB, 0x86, 0x4E, 0x0A, 0x5A, 0xFD, 0xDF, 0xDA, 0x2C, 0x82, + 0x7E, 0xEE, 0xCA, 0xF6, 0x29, 0xE1, 0xFA, 0x71, 0xA1, 0xF7, 0x88, 0x68, + 0x9C, 0x9C, 0xF0, 0x8D, 0xBE, 0x0F, 0x49, 0x91, 0xD8, 0xEA, 0x3A, 0xF9, + 0xFD, 0xD0, 0x68, 0x71, 0xDB, 0xE9, 0xB5, 0x2B, 0x4E, 0x82, 0x92, 0x6F, + 0x66, 0x1F, 0xE0, 0xF0, 0xDC, 0x4C, 0xEC, 0xCA, 0xD1, 0xEA, 0xBA, 0x74, + 0x06, 0xF9, 0xB3, 0x84, 0x90, 0x94, 0xD1, 0x5F, 0x8E, 0x73, 0x19, 0x10, + 0x5D, 0x02, 0xE5, 0x70, 0xA5, 0xC0, 0x10, 0xD0, 0x10, 0x7C, 0x6F, 0xC5, + 0x58, 0x49, 0xB4, 0xB0, 0x6E, 0x9A, 0xDA, 0x7D, 0x95, 0xF5, 0xCC, 0xDA, + 0x02, 0xAF, 0xB8, 0x2C, 0x7D, 0x79, 0x8F, 0xBE, 0x43, 0xF1, 0xF9, 0x28, + 0x28, 0x8D, 0x09, 0x43, 0xF8, 0x08, 0xDD, 0x6B, 0xC8, 0x8B, 0x2C, 0x24, + 0xB1, 0x8D, 0x52, 0x07, 0xBD, 0x78, 0x9B, 0xCB, 0xCA, 0x68, 0xB2, 0xA4, + 0xDD, 0x0C, 0x4C, 0x79, 0x60, 0xC6, 0x99, 0xD1, 0x93, 0xF1, 0x30, 0x1A, + 0x07, 0xD3, 0xAE, 0x22, 0xC2, 0xEA, 0xCE, 0xF1, 0x84, 0x09, 0xCC, 0xE0, + 0x14, 0x6E, 0x7F, 0x3F, 0x7E, 0xD2, 0x82, 0x85, 0xAC, 0xDC, 0xA9, 0x16, + 0x4E, 0x85, 0xA0, 0x60, 0xCB, 0xF6, 0x9C, 0xD7, 0xC8, 0xB3, 0x8E, 0xED, + 0xC6, 0x9B, 0x98, 0x75, 0x0D, 0x55, 0xE8, 0x5F, 0xE5, 0x95, 0x8B, 0x02, + 0xA4, 0xAE, 0x43, 0x29, 0x28, 0x11, 0xA4, 0xE6, 0x12, 0x30, 0x01, 0x4B, + 0x75, 0x6B, 0x1E, 0x66, 0x9D, 0x79, 0x2F, 0xA5, 0x76, 0x2F, 0x1D, 0x40, + 0xB4, 0x6D, 0xC9, 0x7D, 0x79, 0x08, 0xEC, 0xD1, 0x6A, 0xB6, 0x5D, 0x2A, + 0xB2, 0xA5, 0x66, 0xBD, 0x6B, 0x85, 0xF4, 0x74, 0x56, 0xC3, 0xF5, 0xE7, + 0x75, 0x52, 0x28, 0x2C, 0xA5, 0xFF, 0x66, 0x47, 0xA5, 0xD4, 0xFE, 0xFE, + 0x9E, 0x54, 0xBF, 0x65, 0x7E, 0x01, 0xD6, 0x30, 0x8F, 0xA5, 0x36, 0x9C, + 0xA2, 0x50, 0x1C, 0xEE, 0x38, 0x80, 0x01, 0x48, 0xC6, 0xC7, 0x74, 0xF4, + 0xC6, 0xAC, 0xC3, 0x40, 0x49, 0x16, 0x61, 0x74, 0x2C, 0xAF, 0x8C, 0x6F, + 0x35, 0xED, 0x7B, 0x18, 0x00, 0x5B, 0x36, 0x3C, 0x9C, 0x50, 0x0D, 0xCA, + 0x92, 0x33, 0x10, 0xF1, 0x26, 0x49, 0x6D, 0xDF, 0x75, 0x24, 0x37, 0x82, + 0x22, 0xD7, 0xE8, 0x96, 0xFD, 0x15, 0x4B, 0x02, 0x96, 0x3E, 0x07, 0x72, + 0x95, 0x7E, 0xAB, 0x3D, 0x4C, 0x2E, 0xD7, 0xCA, 0xF0, 0xDF, 0xE0, 0x58, + 0x3F, 0x2D, 0x2F, 0x04, 0x9A, 0x38, 0xA3, 0x01 +}; + +static const unsigned char TA711_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA712_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1A, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x20, 0x4A, 0x61, 0x70, 0x61, 0x6E, 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x20, + 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1D, 0x30, 0x1B, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x69, 0x67, + 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x35 +}; + +static const unsigned char TA712_EC_Q[] = { + 0x04, 0x0B, 0x50, 0x74, 0x8D, 0x64, 0x32, 0x99, 0x99, 0xB3, 0xD2, 0x60, + 0x08, 0xB8, 0x22, 0x8E, 0x46, 0x74, 0x2C, 0x78, 0xC0, 0x2B, 0x44, 0x2D, + 0x6D, 0x5F, 0x1D, 0xC9, 0xAE, 0x4B, 0x52, 0x20, 0x83, 0x3D, 0xB8, 0x14, + 0x6D, 0x53, 0x87, 0x60, 0x9E, 0x5F, 0x6C, 0x85, 0xDB, 0x06, 0x14, 0x95, + 0xE0, 0xC7, 0x28, 0xFF, 0x9D, 0x5F, 0xE4, 0xAA, 0xF1, 0xB3, 0x8B, 0x6D, + 0xED, 0x4F, 0x2F, 0x4B, 0xC9, 0x4A, 0x94, 0x91, 0x64, 0x75, 0xFE, 0x01, + 0xEC, 0xC1, 0xD8, 0xEB, 0x7A, 0x94, 0x78, 0x56, 0x18, 0x43, 0x5F, 0x6B, + 0x81, 0xCB, 0xF6, 0xBC, 0xDA, 0xB4, 0x0C, 0xB6, 0x29, 0x93, 0x08, 0x69, + 0x8F +}; + +static const unsigned char TA713_DN[] = { + 0x30, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0E, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x43, 0x41 +}; + +static const unsigned char TA713_RSA_N[] = { + 0xAB, 0xA4, 0x81, 0xE5, 0x95, 0xCD, 0xF5, 0xF6, 0x14, 0x8E, 0xC2, 0x4F, + 0xCA, 0xD4, 0xE2, 0x78, 0x95, 0x58, 0x9C, 0x41, 0xE1, 0x0D, 0x99, 0x40, + 0x24, 0x17, 0x39, 0x91, 0x33, 0x66, 0xE9, 0xBE, 0xE1, 0x83, 0xAF, 0x62, + 0x5C, 0x89, 0xD1, 0xFC, 0x24, 0x5B, 0x61, 0xB3, 0xE0, 0x11, 0x11, 0x41, + 0x1C, 0x1D, 0x6E, 0xF0, 0xB8, 0xBB, 0xF8, 0xDE, 0xA7, 0x81, 0xBA, 0xA6, + 0x48, 0xC6, 0x9F, 0x1D, 0xBD, 0xBE, 0x8E, 0xA9, 0x41, 0x3E, 0xB8, 0x94, + 0xED, 0x29, 0x1A, 0xD4, 0x8E, 0xD2, 0x03, 0x1D, 0x03, 0xEF, 0x6D, 0x0D, + 0x67, 0x1C, 0x57, 0xD7, 0x06, 0xAD, 0xCA, 0xC8, 0xF5, 0xFE, 0x0E, 0xAF, + 0x66, 0x25, 0x48, 0x04, 0x96, 0x0B, 0x5D, 0xA3, 0xBA, 0x16, 0xC3, 0x08, + 0x4F, 0xD1, 0x46, 0xF8, 0x14, 0x5C, 0xF2, 0xC8, 0x5E, 0x01, 0x99, 0x6D, + 0xFD, 0x88, 0xCC, 0x86, 0xA8, 0xC1, 0x6F, 0x31, 0x42, 0x6C, 0x52, 0x3E, + 0x68, 0xCB, 0xF3, 0x19, 0x34, 0xDF, 0xBB, 0x87, 0x18, 0x56, 0x80, 0x26, + 0xC4, 0xD0, 0xDC, 0xC0, 0x6F, 0xDF, 0xDE, 0xA0, 0xC2, 0x91, 0x16, 0xA0, + 0x64, 0x11, 0x4B, 0x44, 0xBC, 0x1E, 0xF6, 0xE7, 0xFA, 0x63, 0xDE, 0x66, + 0xAC, 0x76, 0xA4, 0x71, 0xA3, 0xEC, 0x36, 0x94, 0x68, 0x7A, 0x77, 0xA4, + 0xB1, 0xE7, 0x0E, 0x2F, 0x81, 0x7A, 0xE2, 0xB5, 0x72, 0x86, 0xEF, 0xA2, + 0x6B, 0x8B, 0xF0, 0x0F, 0xDB, 0xD3, 0x59, 0x3F, 0xBA, 0x72, 0xBC, 0x44, + 0x24, 0x9C, 0xE3, 0x73, 0xB3, 0xF7, 0xAF, 0x57, 0x2F, 0x42, 0x26, 0x9D, + 0xA9, 0x74, 0xBA, 0x00, 0x52, 0xF2, 0x4B, 0xCD, 0x53, 0x7C, 0x47, 0x0B, + 0x36, 0x85, 0x0E, 0x66, 0xA9, 0x08, 0x97, 0x16, 0x34, 0x57, 0xC1, 0x66, + 0xF7, 0x80, 0xE3, 0xED, 0x70, 0x54, 0xC7, 0x93, 0xE0, 0x2E, 0x28, 0x15, + 0x59, 0x87, 0xBA, 0xBB +}; + +static const unsigned char TA713_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA714_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x43, 0x41, 0x31 +}; + +static const unsigned char TA714_EC_Q[] = { + 0x04, 0xA4, 0xA5, 0x6F, 0x60, 0x03, 0x03, 0xC3, 0xBD, 0x31, 0xF4, 0xD3, + 0x17, 0x9C, 0x2B, 0x84, 0x75, 0xAC, 0xE5, 0xFD, 0x3D, 0x57, 0x6E, 0xD7, + 0x63, 0xBF, 0xE6, 0x04, 0x89, 0x92, 0x8E, 0x81, 0x9C, 0xE3, 0xE9, 0x47, + 0x6E, 0xCA, 0x90, 0x12, 0xC8, 0x13, 0xE0, 0xA7, 0x9D, 0xF7, 0x65, 0x74, + 0x1F, 0x6C, 0x10, 0xB2, 0xE8, 0xE4, 0xE9, 0xEF, 0x6D, 0x85, 0x32, 0x99, + 0x44, 0xB1, 0x5E, 0xFD, 0xCC, 0x76, 0x10, 0xD8, 0x5B, 0xBD, 0xA2, 0xC6, + 0xF9, 0xD6, 0x42, 0xE4, 0x57, 0x76, 0xDC, 0x90, 0xC2, 0x35, 0xA9, 0x4B, + 0x88, 0x3C, 0x12, 0x47, 0x6D, 0x5C, 0xFF, 0x49, 0x4F, 0x1A, 0x4A, 0x50, + 0xB1 +}; + +static const unsigned char TA715_DN[] = { + 0x30, 0x5D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4A, 0x50, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x45, 0x43, 0x4F, 0x4D, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x43, 0x4F, + 0x2E, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x1E, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x43, 0x6F, 0x6D, 0x6D, 0x75, 0x6E, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA715_RSA_N[] = { + 0xD0, 0x15, 0x39, 0x52, 0xB1, 0x52, 0xB3, 0xBA, 0xC5, 0x59, 0x82, 0xC4, + 0x5D, 0x52, 0xAE, 0x3A, 0x43, 0x65, 0x80, 0x4B, 0xC7, 0xF2, 0x96, 0xBC, + 0xDB, 0x36, 0x97, 0xD6, 0xA6, 0x64, 0x8C, 0xA8, 0x5E, 0xF0, 0xE3, 0x0A, + 0x1C, 0xF7, 0xDF, 0x97, 0x3D, 0x4B, 0xAE, 0xF6, 0x5D, 0xEC, 0x21, 0xB5, + 0x41, 0xAB, 0xCD, 0xB9, 0x7E, 0x76, 0x9F, 0xBE, 0xF9, 0x3E, 0x36, 0x34, + 0xA0, 0x3B, 0xC1, 0xF6, 0x31, 0x11, 0x45, 0x74, 0x93, 0x3D, 0x57, 0x80, + 0xC5, 0xF9, 0x89, 0x99, 0xCA, 0xE5, 0xAB, 0x6A, 0xD4, 0xB5, 0xDA, 0x41, + 0x90, 0x10, 0xC1, 0xD6, 0xD6, 0x42, 0x89, 0xC2, 0xBF, 0xF4, 0x38, 0x12, + 0x95, 0x4C, 0x54, 0x05, 0xF7, 0x36, 0xE4, 0x45, 0x83, 0x7B, 0x14, 0x65, + 0xD6, 0xDC, 0x0C, 0x4D, 0xD1, 0xDE, 0x7E, 0x0C, 0xAB, 0x3B, 0xC4, 0x15, + 0xBE, 0x3A, 0x56, 0xA6, 0x5A, 0x6F, 0x76, 0x69, 0x52, 0xA9, 0x7A, 0xB9, + 0xC8, 0xEB, 0x6A, 0x9A, 0x5D, 0x52, 0xD0, 0x2D, 0x0A, 0x6B, 0x35, 0x16, + 0x09, 0x10, 0x84, 0xD0, 0x6A, 0xCA, 0x3A, 0x06, 0x00, 0x37, 0x47, 0xE4, + 0x7E, 0x57, 0x4F, 0x3F, 0x8B, 0xEB, 0x67, 0xB8, 0x88, 0xAA, 0xC5, 0xBE, + 0x53, 0x55, 0xB2, 0x91, 0xC4, 0x7D, 0xB9, 0xB0, 0x85, 0x19, 0x06, 0x78, + 0x2E, 0xDB, 0x61, 0x1A, 0xFA, 0x85, 0xF5, 0x4A, 0x91, 0xA1, 0xE7, 0x16, + 0xD5, 0x8E, 0xA2, 0x39, 0xDF, 0x94, 0xB8, 0x70, 0x1F, 0x28, 0x3F, 0x8B, + 0xFC, 0x40, 0x5E, 0x63, 0x83, 0x3C, 0x83, 0x2A, 0x1A, 0x99, 0x6B, 0xCF, + 0xDE, 0x59, 0x6A, 0x3B, 0xFC, 0x6F, 0x16, 0xD7, 0x1F, 0xFD, 0x4A, 0x10, + 0xEB, 0x4E, 0x82, 0x16, 0x3A, 0xAC, 0x27, 0x0C, 0x53, 0xF1, 0xAD, 0xD5, + 0x24, 0xB0, 0x6B, 0x03, 0x50, 0xC1, 0x2D, 0x3C, 0x16, 0xDD, 0x44, 0x34, + 0x27, 0x1A, 0x75, 0xFB +}; + +static const unsigned char TA715_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA716_DN[] = { + 0x30, 0x7F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x2B, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, 0x56, + 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA716_EC_Q[] = { + 0x04, 0xAA, 0x12, 0x47, 0x90, 0x98, 0x1B, 0xFB, 0xEF, 0xC3, 0x40, 0x07, + 0x83, 0x20, 0x4E, 0xF1, 0x30, 0x82, 0xA2, 0x06, 0xD1, 0xF2, 0x92, 0x86, + 0x61, 0xF2, 0xF6, 0x21, 0x68, 0xCA, 0x00, 0xC4, 0xC7, 0xEA, 0x43, 0x00, + 0x54, 0x86, 0xDC, 0xFD, 0x1F, 0xDF, 0x00, 0xB8, 0x41, 0x62, 0x5C, 0xDC, + 0x70, 0x16, 0x32, 0xDE, 0x1F, 0x99, 0xD4, 0xCC, 0xC5, 0x07, 0xC8, 0x08, + 0x1F, 0x61, 0x16, 0x07, 0x51, 0x3D, 0x7D, 0x5C, 0x07, 0x53, 0xE3, 0x35, + 0x38, 0x8C, 0xDF, 0xCD, 0x9F, 0xD9, 0x2E, 0x0D, 0x4A, 0xB6, 0x19, 0x2E, + 0x5A, 0x70, 0x5A, 0x06, 0xED, 0xBE, 0xF0, 0xA1, 0xB0, 0xCA, 0xD0, 0x09, + 0x29 +}; + +static const unsigned char TA717_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, + 0x6F, 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x2E, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x45, + 0x56, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, + 0x32 +}; + +static const unsigned char TA717_RSA_N[] = { + 0x8F, 0x36, 0x65, 0x40, 0xE1, 0xD6, 0x4D, 0xC0, 0xD7, 0xB4, 0xE9, 0x46, + 0xDA, 0x6B, 0xEA, 0x33, 0x47, 0xCD, 0x4C, 0xF9, 0x7D, 0x7D, 0xBE, 0xBD, + 0x2D, 0x3D, 0xF0, 0xDB, 0x78, 0xE1, 0x86, 0xA5, 0xD9, 0xBA, 0x09, 0x57, + 0x68, 0xED, 0x57, 0x3E, 0xA0, 0xD0, 0x08, 0x41, 0x83, 0xE7, 0x28, 0x41, + 0x24, 0x1F, 0xE3, 0x72, 0x15, 0xD0, 0x01, 0x1A, 0xFB, 0x5E, 0x70, 0x23, + 0xB2, 0xCB, 0x9F, 0x39, 0xE3, 0xCF, 0xC5, 0x4E, 0xC6, 0x92, 0x6D, 0x26, + 0xC6, 0x7B, 0xBB, 0xB3, 0xDA, 0x27, 0x9D, 0x0A, 0x86, 0xE9, 0x81, 0x37, + 0x05, 0xFE, 0xF0, 0x71, 0x71, 0xEC, 0xC3, 0x1C, 0xE9, 0x63, 0xA2, 0x17, + 0x14, 0x9D, 0xEF, 0x1B, 0x67, 0xD3, 0x85, 0x55, 0x02, 0x02, 0xD6, 0x49, + 0xC9, 0xCC, 0x5A, 0xE1, 0xB1, 0xF7, 0x6F, 0x32, 0x9F, 0xC9, 0xD4, 0x3B, + 0x88, 0x41, 0xA8, 0x9C, 0xBD, 0xCB, 0xAB, 0xDB, 0x6D, 0x7B, 0x09, 0x1F, + 0xA2, 0x4C, 0x72, 0x90, 0xDA, 0x2B, 0x08, 0xFC, 0xCF, 0x3C, 0x54, 0xCE, + 0x67, 0x0F, 0xA8, 0xCF, 0x5D, 0x96, 0x19, 0x0B, 0xC4, 0xE3, 0x72, 0xEB, + 0xAD, 0xD1, 0x7D, 0x1D, 0x27, 0xEF, 0x92, 0xEB, 0x10, 0xBF, 0x5B, 0xEB, + 0x3B, 0xAF, 0xCF, 0x80, 0xDD, 0xC1, 0xD2, 0x96, 0x04, 0x5B, 0x7A, 0x7E, + 0xA4, 0xA9, 0x3C, 0x38, 0x76, 0xA4, 0x62, 0x8E, 0xA0, 0x39, 0x5E, 0xEA, + 0x77, 0xCF, 0x5D, 0x00, 0x59, 0x8F, 0x66, 0x2C, 0x3E, 0x07, 0xA2, 0xA3, + 0x05, 0x26, 0x11, 0x69, 0x97, 0xEA, 0x85, 0xB7, 0x0F, 0x96, 0x0B, 0x4B, + 0xC8, 0x40, 0xE1, 0x50, 0xBA, 0x2E, 0x8A, 0xCB, 0xF7, 0x0F, 0x9A, 0x22, + 0xE7, 0x7F, 0x9A, 0x37, 0x13, 0xCD, 0xF2, 0x4D, 0x13, 0x6B, 0x21, 0xD1, + 0xC0, 0xCC, 0x22, 0xF2, 0xA1, 0x46, 0xF6, 0x44, 0x69, 0x9C, 0xCA, 0x61, + 0x35, 0x07, 0x00, 0x6F, 0xD6, 0x61, 0x08, 0x11, 0xEA, 0xBA, 0xB8, 0xF6, + 0xE9, 0xB3, 0x60, 0xE5, 0x4D, 0xB9, 0xEC, 0x9F, 0x14, 0x66, 0xC9, 0x57, + 0x58, 0xDB, 0xCD, 0x87, 0x69, 0xF8, 0x8A, 0x86, 0x12, 0x03, 0x47, 0xBF, + 0x66, 0x13, 0x76, 0xAC, 0x77, 0x7D, 0x34, 0x24, 0x85, 0x83, 0xCD, 0xD7, + 0xAA, 0x9C, 0x90, 0x1A, 0x9F, 0x21, 0x2C, 0x7F, 0x78, 0xB7, 0x64, 0xB8, + 0xD8, 0xE8, 0xA6, 0xF4, 0x78, 0xB3, 0x55, 0xCB, 0x84, 0xD2, 0x32, 0xC4, + 0x78, 0xAE, 0xA3, 0x8F, 0x61, 0xDD, 0xCE, 0x08, 0x53, 0xAD, 0xEC, 0x88, + 0xFC, 0x15, 0xE4, 0x9A, 0x0D, 0xE6, 0x9F, 0x1A, 0x77, 0xCE, 0x4C, 0x8F, + 0xB8, 0x14, 0x15, 0x3D, 0x62, 0x9C, 0x86, 0x38, 0x06, 0x00, 0x66, 0x12, + 0xE4, 0x59, 0x76, 0x5A, 0x53, 0xC0, 0x02, 0x98, 0xA2, 0x10, 0x2B, 0x68, + 0x44, 0x7B, 0x8E, 0x79, 0xCE, 0x33, 0x4A, 0x76, 0xAA, 0x5B, 0x81, 0x16, + 0x1B, 0xB5, 0x8A, 0xD8, 0xD0, 0x00, 0x7B, 0x5E, 0x62, 0xB4, 0x09, 0xD6, + 0x86, 0x63, 0x0E, 0xA6, 0x05, 0x95, 0x49, 0xBA, 0x28, 0x8B, 0x88, 0x93, + 0xB2, 0x34, 0x1C, 0xD8, 0xA4, 0x55, 0x6E, 0xB7, 0x1C, 0xD0, 0xDE, 0x99, + 0x55, 0x3B, 0x23, 0xF4, 0x22, 0xE0, 0xF9, 0x29, 0x66, 0x26, 0xEC, 0x20, + 0x50, 0x77, 0xDB, 0x4A, 0x0B, 0x8F, 0xBE, 0xE5, 0x02, 0x60, 0x70, 0x41, + 0x5E, 0xD4, 0xAE, 0x50, 0x39, 0x22, 0x14, 0x26, 0xCB, 0xB2, 0x3B, 0x73, + 0x74, 0x55, 0x47, 0x07, 0x79, 0x81, 0x39, 0xA8, 0x30, 0x13, 0x44, 0xE5, + 0x04, 0x8A, 0xAE, 0x96, 0x13, 0x25, 0x42, 0x0F, 0xB9, 0x53, 0xC4, 0x9B, + 0xFC, 0xCD, 0xE4, 0x1C, 0xDE, 0x3C, 0xFA, 0xAB, 0xD6, 0x06, 0x4A, 0x1F, + 0x67, 0xA6, 0x98, 0x30, 0x1C, 0xDD, 0x2C, 0xDB, 0xDC, 0x18, 0x95, 0x57, + 0x66, 0xC6, 0xFF, 0x5C, 0x8B, 0x56, 0xF5, 0x77 +}; + +static const unsigned char TA717_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA718_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x45, 0x43, 0x43 +}; + +static const unsigned char TA718_EC_Q[] = { + 0x04, 0x45, 0x6E, 0xA9, 0x50, 0xC4, 0xA6, 0x23, 0x36, 0x9E, 0x5F, 0x28, + 0x8D, 0x17, 0xCB, 0x96, 0x22, 0x64, 0x3F, 0xDC, 0x7A, 0x8E, 0x1D, 0xCC, + 0x08, 0xB3, 0xA2, 0x71, 0x24, 0xBA, 0x8E, 0x49, 0xB9, 0x04, 0x1B, 0x47, + 0x96, 0x58, 0xAB, 0x2D, 0x95, 0xC8, 0xED, 0x9E, 0x08, 0x35, 0xC8, 0x27, + 0xEB, 0x89, 0x8C, 0x53, 0x58, 0xEB, 0x62, 0x8A, 0xFE, 0xF0, 0x5B, 0x0F, + 0x6B, 0x31, 0x52, 0x63, 0x41, 0x3B, 0x89, 0xCD, 0xEC, 0xEC, 0xB6, 0x8D, + 0x19, 0xD3, 0x34, 0x07, 0xDC, 0xBB, 0xC6, 0x06, 0x7F, 0xC2, 0x45, 0x95, + 0xEC, 0xCB, 0x7F, 0xA8, 0x23, 0xE0, 0x09, 0xE9, 0x81, 0xFA, 0xF3, 0x47, + 0xD3 +}; + +static const unsigned char TA719_DN[] = { + 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x0E, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0C, 0x05, 0x54, 0x65, 0x78, 0x61, 0x73, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x48, 0x6F, 0x75, 0x73, 0x74, 0x6F, + 0x6E, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0F, + 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0C, 0x28, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x52, 0x53, 0x41 +}; + +static const unsigned char TA719_RSA_N[] = { + 0xF9, 0x0F, 0xDD, 0xA3, 0x2B, 0x7D, 0xCB, 0xD0, 0x2A, 0xFE, 0xEC, 0x67, + 0x85, 0xA6, 0xE7, 0x2E, 0x1B, 0xBA, 0x77, 0xE1, 0xE3, 0xF5, 0xAF, 0xA4, + 0xEC, 0xFA, 0x4A, 0x5D, 0x91, 0xC4, 0x57, 0x47, 0x6B, 0x18, 0x77, 0x6B, + 0x76, 0xF2, 0xFD, 0x93, 0xE4, 0x3D, 0x0F, 0xC2, 0x16, 0x9E, 0x0B, 0x66, + 0xC3, 0x56, 0x94, 0x9E, 0x17, 0x83, 0x85, 0xCE, 0x56, 0xEF, 0xF2, 0x16, + 0xFD, 0x00, 0x62, 0xF5, 0x22, 0x09, 0x54, 0xE8, 0x65, 0x17, 0x4E, 0x41, + 0xB9, 0xE0, 0x4F, 0x46, 0x97, 0xAA, 0x1B, 0xC8, 0xB8, 0x6E, 0x62, 0x5E, + 0x69, 0xB1, 0x5F, 0xDB, 0x2A, 0x02, 0x7E, 0xFC, 0x6C, 0xCA, 0xF3, 0x41, + 0xD8, 0xED, 0xD0, 0xE8, 0xFC, 0x3F, 0x61, 0x48, 0xED, 0xB0, 0x03, 0x14, + 0x1D, 0x10, 0x0E, 0x4B, 0x19, 0xE0, 0xBB, 0x4E, 0xEC, 0x86, 0x65, 0xFF, + 0x36, 0xF3, 0x5E, 0x67, 0x02, 0x0B, 0x9D, 0x86, 0x55, 0x61, 0xFD, 0x7A, + 0x38, 0xED, 0xFE, 0xE2, 0x19, 0x00, 0xB7, 0x6F, 0xA1, 0x50, 0x62, 0x75, + 0x74, 0x3C, 0xA0, 0xFA, 0xC8, 0x25, 0x92, 0xB4, 0x6E, 0x7A, 0x22, 0xC7, + 0xF8, 0x1E, 0xA1, 0xE3, 0xB2, 0xDD, 0x91, 0x31, 0xAB, 0x2B, 0x1D, 0x04, + 0xFF, 0xA5, 0x4A, 0x04, 0x37, 0xE9, 0x85, 0xA4, 0x33, 0x2B, 0xFD, 0xE2, + 0xD6, 0x55, 0x34, 0x7C, 0x19, 0xA4, 0x4A, 0x68, 0xC7, 0xB2, 0xA8, 0xD3, + 0xB7, 0xCA, 0xA1, 0x93, 0x88, 0xEB, 0xC1, 0x97, 0xBC, 0x8C, 0xF9, 0x1D, + 0xD9, 0x22, 0x84, 0x24, 0x74, 0xC7, 0x04, 0x3D, 0x6A, 0xA9, 0x29, 0x93, + 0xCC, 0xEB, 0xB8, 0x5B, 0xE1, 0xFE, 0x5F, 0x25, 0xAA, 0x34, 0x58, 0xC8, + 0xC1, 0x23, 0x54, 0x9D, 0x1B, 0x98, 0x11, 0xC3, 0x38, 0x9C, 0x7E, 0x3D, + 0x86, 0x6C, 0xA5, 0x0F, 0x40, 0x86, 0x7C, 0x02, 0xF4, 0x5C, 0x02, 0x4F, + 0x28, 0xCB, 0xAE, 0x71, 0x9F, 0x0F, 0x3A, 0xC8, 0x33, 0xFE, 0x11, 0x25, + 0x35, 0xEA, 0xFC, 0xBA, 0xC5, 0x60, 0x3D, 0xD9, 0x7C, 0x18, 0xD5, 0xB2, + 0xA9, 0xD3, 0x75, 0x78, 0x03, 0x72, 0x22, 0xCA, 0x3A, 0xC3, 0x1F, 0xEF, + 0x2C, 0xE5, 0x2E, 0xA9, 0xFA, 0x9E, 0x2C, 0xB6, 0x51, 0x46, 0xFD, 0xAF, + 0x03, 0xD6, 0xEA, 0x60, 0x68, 0xEA, 0x85, 0x16, 0x36, 0x6B, 0x85, 0xE9, + 0x1E, 0xC0, 0xB3, 0xDD, 0xC4, 0x24, 0xDC, 0x80, 0x2A, 0x81, 0x41, 0x6D, + 0x94, 0x3E, 0xC8, 0xE0, 0xC9, 0x81, 0x41, 0x00, 0x9E, 0x5E, 0xBF, 0x7F, + 0xC5, 0x08, 0x98, 0xA2, 0x18, 0x2C, 0x42, 0x40, 0xB3, 0xF9, 0x6F, 0x38, + 0x27, 0x4B, 0x4E, 0x80, 0xF4, 0x3D, 0x81, 0x47, 0xE0, 0x88, 0x7C, 0xEA, + 0x1C, 0xCE, 0xB5, 0x75, 0x5C, 0x51, 0x2E, 0x1C, 0x2B, 0x7F, 0x1A, 0x72, + 0x28, 0xE7, 0x00, 0xB5, 0xD1, 0x74, 0xC6, 0xD7, 0xE4, 0x9F, 0xAD, 0x07, + 0x93, 0xB6, 0x53, 0x35, 0x35, 0xFC, 0x37, 0xE4, 0xC3, 0xF6, 0x5D, 0x16, + 0xBE, 0x21, 0x73, 0xDE, 0x92, 0x0A, 0xF8, 0xA0, 0x63, 0x6A, 0xBC, 0x96, + 0x92, 0x6A, 0x3E, 0xF8, 0xBC, 0x65, 0x55, 0x9B, 0xDE, 0xF5, 0x0D, 0x89, + 0x26, 0x04, 0xFC, 0x25, 0x1A, 0xA6, 0x25, 0x69, 0xCB, 0xC2, 0x6D, 0xCA, + 0x7C, 0xE2, 0x59, 0x5F, 0x97, 0xAC, 0xEB, 0xEF, 0x2E, 0xC8, 0xBC, 0xD7, + 0x1B, 0x59, 0x3C, 0x2B, 0xCC, 0xF2, 0x19, 0xC8, 0x93, 0x6B, 0x27, 0x63, + 0x19, 0xCF, 0xFC, 0xE9, 0x26, 0xF8, 0xCA, 0x71, 0x9B, 0x7F, 0x93, 0xFE, + 0x34, 0x67, 0x84, 0x4E, 0x99, 0xEB, 0xFC, 0xB3, 0x78, 0x09, 0x33, 0x70, + 0xBA, 0x66, 0xA6, 0x76, 0xED, 0x1B, 0x73, 0xEB, 0x1A, 0xA5, 0x0D, 0xC4, + 0x22, 0x13, 0x20, 0x94, 0x56, 0x0A, 0x4E, 0x2C, 0x6C, 0x4E, 0xB1, 0xFD, + 0xCF, 0x9C, 0x09, 0xBA, 0xA2, 0x33, 0xED, 0x87 +}; + +static const unsigned char TA719_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA720_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA720_EC_Q[] = { + 0x04, 0x45, 0x29, 0x35, 0x73, 0xFA, 0xC2, 0xB8, 0x23, 0xCE, 0x14, 0x7D, + 0xA8, 0xB1, 0x4D, 0xA0, 0x5B, 0x36, 0xEE, 0x2A, 0x2C, 0x53, 0xC3, 0x60, + 0x09, 0x35, 0xB2, 0x24, 0x66, 0x26, 0x69, 0xC0, 0xB3, 0x95, 0xD6, 0x5D, + 0x92, 0x40, 0x19, 0x0E, 0xC6, 0xA5, 0x13, 0x70, 0xF4, 0xEF, 0x12, 0x51, + 0x28, 0x5D, 0xE7, 0xCC, 0xBD, 0xF9, 0x3C, 0x85, 0xC1, 0xCF, 0x94, 0x90, + 0xC9, 0x2B, 0xCE, 0x92, 0x42, 0x58, 0x59, 0x67, 0xFD, 0x94, 0x27, 0x10, + 0x64, 0x8C, 0x4F, 0x04, 0xB1, 0x4D, 0x49, 0xE4, 0x7B, 0x4F, 0x9B, 0xF5, + 0xE7, 0x08, 0xF8, 0x03, 0x88, 0xF7, 0xA7, 0xC3, 0x92, 0x4B, 0x19, 0x54, + 0x81 +}; + +static const unsigned char TA721_DN[] = { + 0x30, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x0F, 0x53, 0x53, 0x4C, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, + 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x1C, 0x53, 0x53, 0x4C, 0x2E, 0x63, 0x6F, 0x6D, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x32, 0x32 +}; + +static const unsigned char TA721_RSA_N[] = { + 0xD0, 0xA4, 0x09, 0x72, 0x4F, 0x40, 0x88, 0x12, 0x61, 0x3E, 0x35, 0x23, + 0x9E, 0xEE, 0xF6, 0x74, 0xCF, 0x2F, 0x7B, 0x58, 0x3D, 0xCE, 0x3C, 0x0D, + 0x10, 0x28, 0x90, 0x2F, 0x97, 0xF7, 0x8C, 0x48, 0xD8, 0xA0, 0xD8, 0x25, + 0xB1, 0x4C, 0xB0, 0x11, 0x4C, 0x17, 0x73, 0x50, 0xD0, 0x22, 0x4A, 0x63, + 0xBB, 0x81, 0xD3, 0x29, 0x6E, 0xD5, 0xB5, 0x09, 0x3E, 0x26, 0x18, 0x7F, + 0xB2, 0x12, 0x7F, 0x93, 0x98, 0xB7, 0xAF, 0xF0, 0x36, 0xBF, 0xF2, 0xEE, + 0x18, 0x9E, 0x9C, 0x3B, 0x52, 0xC5, 0x47, 0x19, 0x5D, 0x74, 0xF3, 0x64, + 0x66, 0xD5, 0x5D, 0xC7, 0x68, 0xB4, 0xBF, 0x1B, 0x1C, 0x06, 0xA3, 0xBC, + 0x8F, 0x40, 0x23, 0xB6, 0x1E, 0xC6, 0x84, 0xBD, 0x51, 0xC4, 0x1B, 0x39, + 0xC1, 0x95, 0xD2, 0x29, 0xEC, 0x4B, 0xAE, 0x7B, 0x2D, 0xBF, 0x39, 0xFD, + 0xB4, 0x62, 0xDE, 0x96, 0x7B, 0x41, 0xC6, 0x9C, 0xA0, 0xE0, 0x06, 0x72, + 0xFB, 0xF0, 0x07, 0x97, 0x09, 0x39, 0x81, 0x74, 0xAF, 0xF7, 0x34, 0x59, + 0x11, 0x57, 0x0A, 0xC2, 0x5B, 0xC1, 0x24, 0xF4, 0x31, 0x73, 0x30, 0x82, + 0xC6, 0x9D, 0xBA, 0x02, 0xF7, 0x3E, 0x7C, 0x44, 0x5F, 0x83, 0x0D, 0xF3, + 0xF1, 0xDD, 0x20, 0x69, 0x16, 0x09, 0x50, 0xE2, 0xD4, 0x55, 0xB6, 0xE0, + 0x80, 0x72, 0x76, 0x6E, 0x4C, 0x47, 0xB7, 0x75, 0x55, 0x59, 0xB4, 0x53, + 0x74, 0xD9, 0x94, 0xC6, 0x41, 0xAD, 0x58, 0x8A, 0x31, 0x66, 0x0F, 0x1E, + 0xA2, 0x1B, 0x29, 0x40, 0x4E, 0x2F, 0xDF, 0x7B, 0xE6, 0x16, 0x2C, 0x2D, + 0xFC, 0xBF, 0xEC, 0xF3, 0xB4, 0xFA, 0xBE, 0x18, 0xF6, 0x9B, 0x49, 0xD4, + 0xEE, 0x05, 0x6E, 0xD9, 0x34, 0xF3, 0x9C, 0xF1, 0xEC, 0x01, 0x8B, 0xD1, + 0x20, 0xC6, 0x0F, 0xA0, 0xB5, 0xBC, 0x17, 0x4E, 0x48, 0x7B, 0x51, 0xC2, + 0xFC, 0xE9, 0x5C, 0x69, 0x37, 0x47, 0x66, 0xB3, 0x68, 0xF8, 0x15, 0x28, + 0xF0, 0xB9, 0xD3, 0xA4, 0x15, 0xCC, 0x5A, 0x4F, 0xBA, 0x52, 0x70, 0xA3, + 0x12, 0x45, 0xDD, 0xC6, 0xBA, 0x4E, 0xFB, 0xC2, 0xD0, 0xF7, 0xA8, 0x52, + 0x27, 0x6D, 0x6E, 0x79, 0xB5, 0x8C, 0xFC, 0x7B, 0x8C, 0xC1, 0x16, 0x4C, + 0xEE, 0x80, 0x7F, 0xBE, 0xF0, 0x76, 0xBE, 0x41, 0x53, 0x12, 0x33, 0xAE, + 0x5A, 0x38, 0x42, 0xAB, 0xD7, 0x0F, 0x3E, 0x41, 0x8D, 0x76, 0x07, 0x32, + 0xD5, 0xAB, 0x89, 0xF6, 0x4E, 0x67, 0xD9, 0xB1, 0x42, 0x75, 0x23, 0x6E, + 0xF3, 0xCD, 0x42, 0xB2, 0xFC, 0x55, 0xF5, 0x53, 0x87, 0x17, 0x3B, 0xC0, + 0x33, 0x58, 0xF1, 0x52, 0xD2, 0xF9, 0x80, 0xA4, 0xF0, 0xE8, 0xF0, 0x3B, + 0x8B, 0x38, 0xCC, 0xA4, 0xC6, 0x90, 0x7F, 0x0F, 0x9C, 0xFD, 0x8B, 0xD1, + 0xA3, 0xCF, 0xDA, 0x83, 0xA7, 0x69, 0xC9, 0x50, 0x36, 0xD5, 0x5C, 0x05, + 0xD2, 0x0A, 0x41, 0x74, 0xDB, 0x63, 0x11, 0x37, 0xC1, 0xA5, 0xA0, 0x96, + 0x4B, 0x1E, 0x8C, 0x16, 0x12, 0x77, 0xAE, 0x94, 0x34, 0x7B, 0x1E, 0x7F, + 0xC2, 0x66, 0x00, 0xE4, 0xAA, 0x83, 0xEA, 0x8A, 0x90, 0xAD, 0xCE, 0x36, + 0x44, 0x4D, 0xD1, 0x51, 0xE9, 0xBC, 0x1F, 0xF3, 0x6A, 0x05, 0xFD, 0xC0, + 0x74, 0x1F, 0x25, 0x19, 0x40, 0x51, 0x6E, 0xEA, 0x82, 0x51, 0x40, 0xDF, + 0x9B, 0xB9, 0x08, 0x2A, 0x06, 0x02, 0xD5, 0x23, 0x1C, 0x13, 0xD6, 0xE9, + 0xDB, 0xDB, 0xC6, 0xB0, 0x7A, 0xCB, 0x7B, 0x27, 0x9B, 0xFB, 0xE0, 0xD5, + 0x46, 0x24, 0xED, 0x10, 0x4B, 0x63, 0x4B, 0xA5, 0x05, 0x8F, 0xBA, 0xB8, + 0x1D, 0x2B, 0xA6, 0xFA, 0x91, 0xE2, 0x92, 0x52, 0xBD, 0xEC, 0xEB, 0x67, + 0x97, 0x6D, 0x9A, 0x2D, 0x9F, 0x81, 0x32, 0x05, 0x67, 0x32, 0xFB, 0x48, + 0x08, 0x3F, 0xD9, 0x25, 0xB8, 0x04, 0x25, 0x2F +}; + +static const unsigned char TA721_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA722_DN[] = { + 0x30, 0x68, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, + 0x6C, 0x64, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA722_RSA_N[] = { + 0xB7, 0x32, 0xC8, 0xFE, 0xE9, 0x71, 0xA6, 0x04, 0x85, 0xAD, 0x0C, 0x11, + 0x64, 0xDF, 0xCE, 0x4D, 0xEF, 0xC8, 0x03, 0x18, 0x87, 0x3F, 0xA1, 0xAB, + 0xFB, 0x3C, 0xA6, 0x9F, 0xF0, 0xC3, 0xA1, 0xDA, 0xD4, 0xD8, 0x6E, 0x2B, + 0x53, 0x90, 0xFB, 0x24, 0xA4, 0x3E, 0x84, 0xF0, 0x9E, 0xE8, 0x5F, 0xEC, + 0xE5, 0x27, 0x44, 0xF5, 0x28, 0xA6, 0x3F, 0x7B, 0xDE, 0xE0, 0x2A, 0xF0, + 0xC8, 0xAF, 0x53, 0x2F, 0x9E, 0xCA, 0x05, 0x01, 0x93, 0x1E, 0x8F, 0x66, + 0x1C, 0x39, 0xA7, 0x4D, 0xFA, 0x5A, 0xB6, 0x73, 0x04, 0x25, 0x66, 0xEB, + 0x77, 0x7F, 0xE7, 0x59, 0xC6, 0x4A, 0x99, 0x25, 0x14, 0x54, 0xEB, 0x26, + 0xC7, 0xF3, 0x7F, 0x19, 0xD5, 0x30, 0x70, 0x8F, 0xAF, 0xB0, 0x46, 0x2A, + 0xFF, 0xAD, 0xEB, 0x29, 0xED, 0xD7, 0x9F, 0xAA, 0x04, 0x87, 0xA3, 0xD4, + 0xF9, 0x89, 0xA5, 0x34, 0x5F, 0xDB, 0x43, 0x91, 0x82, 0x36, 0xD9, 0x66, + 0x3C, 0xB1, 0xB8, 0xB9, 0x82, 0xFD, 0x9C, 0x3A, 0x3E, 0x10, 0xC8, 0x3B, + 0xEF, 0x06, 0x65, 0x66, 0x7A, 0x9B, 0x19, 0x18, 0x3D, 0xFF, 0x71, 0x51, + 0x3C, 0x30, 0x2E, 0x5F, 0xBE, 0x3D, 0x77, 0x73, 0xB2, 0x5D, 0x06, 0x6C, + 0xC3, 0x23, 0x56, 0x9A, 0x2B, 0x85, 0x26, 0x92, 0x1C, 0xA7, 0x02, 0xB3, + 0xE4, 0x3F, 0x0D, 0xAF, 0x08, 0x79, 0x82, 0xB8, 0x36, 0x3D, 0xEA, 0x9C, + 0xD3, 0x35, 0xB3, 0xBC, 0x69, 0xCA, 0xF5, 0xCC, 0x9D, 0xE8, 0xFD, 0x64, + 0x8D, 0x17, 0x80, 0x33, 0x6E, 0x5E, 0x4A, 0x5D, 0x99, 0xC9, 0x1E, 0x87, + 0xB4, 0x9D, 0x1A, 0xC0, 0xD5, 0x6E, 0x13, 0x35, 0x23, 0x5E, 0xDF, 0x9B, + 0x5F, 0x3D, 0xEF, 0xD6, 0xF7, 0x76, 0xC2, 0xEA, 0x3E, 0xBB, 0x78, 0x0D, + 0x1C, 0x42, 0x67, 0x6B, 0x04, 0xD8, 0xF8, 0xD6, 0xDA, 0x6F, 0x8B, 0xF2, + 0x44, 0xA0, 0x01, 0xAB +}; + +static const unsigned char TA722_RSA_E[] = { + 0x03 +}; + +static const unsigned char TA723_DN[] = { + 0x30, 0x81, 0x8F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x32, + 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, + 0x47, 0x32 +}; + +static const unsigned char TA723_RSA_N[] = { + 0xBD, 0xED, 0xC1, 0x03, 0xFC, 0xF6, 0x8F, 0xFC, 0x02, 0xB1, 0x6F, 0x5B, + 0x9F, 0x48, 0xD9, 0x9D, 0x79, 0xE2, 0xA2, 0xB7, 0x03, 0x61, 0x56, 0x18, + 0xC3, 0x47, 0xB6, 0xD7, 0xCA, 0x3D, 0x35, 0x2E, 0x89, 0x43, 0xF7, 0xA1, + 0x69, 0x9B, 0xDE, 0x8A, 0x1A, 0xFD, 0x13, 0x20, 0x9C, 0xB4, 0x49, 0x77, + 0x32, 0x29, 0x56, 0xFD, 0xB9, 0xEC, 0x8C, 0xDD, 0x22, 0xFA, 0x72, 0xDC, + 0x27, 0x61, 0x97, 0xEE, 0xF6, 0x5A, 0x84, 0xEC, 0x6E, 0x19, 0xB9, 0x89, + 0x2C, 0xDC, 0x84, 0x5B, 0xD5, 0x74, 0xFB, 0x6B, 0x5F, 0xC5, 0x89, 0xA5, + 0x10, 0x52, 0x89, 0x46, 0x55, 0xF4, 0xB8, 0x75, 0x1C, 0xE6, 0x7F, 0xE4, + 0x54, 0xAE, 0x4B, 0xF8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xF8, 0x17, 0x71, + 0x59, 0xEB, 0x1E, 0x28, 0x07, 0x74, 0xC5, 0x9D, 0x48, 0xBE, 0x6C, 0xB4, + 0xF4, 0xA4, 0xB0, 0xF3, 0x64, 0x37, 0x79, 0x92, 0xC0, 0xEC, 0x46, 0x5E, + 0x7F, 0xE1, 0x6D, 0x53, 0x4C, 0x62, 0xAF, 0xCD, 0x1F, 0x0B, 0x63, 0xBB, + 0x3A, 0x9D, 0xFB, 0xFC, 0x79, 0x00, 0x98, 0x61, 0x74, 0xCF, 0x26, 0x82, + 0x40, 0x63, 0xF3, 0xB2, 0x72, 0x6A, 0x19, 0x0D, 0x99, 0xCA, 0xD4, 0x0E, + 0x75, 0xCC, 0x37, 0xFB, 0x8B, 0x89, 0xC1, 0x59, 0xF1, 0x62, 0x7F, 0x5F, + 0xB3, 0x5F, 0x65, 0x30, 0xF8, 0xA7, 0xB7, 0x4D, 0x76, 0x5A, 0x1E, 0x76, + 0x5E, 0x34, 0xC0, 0xE8, 0x96, 0x56, 0x99, 0x8A, 0xB3, 0xF0, 0x7F, 0xA4, + 0xCD, 0xBD, 0xDC, 0x32, 0x31, 0x7C, 0x91, 0xCF, 0xE0, 0x5F, 0x11, 0xF8, + 0x6B, 0xAA, 0x49, 0x5C, 0xD1, 0x99, 0x94, 0xD1, 0xA2, 0xE3, 0x63, 0x5B, + 0x09, 0x76, 0xB5, 0x56, 0x62, 0xE1, 0x4B, 0x74, 0x1D, 0x96, 0xD4, 0x26, + 0xD4, 0x08, 0x04, 0x59, 0xD0, 0x98, 0x0E, 0x0E, 0xE6, 0xDE, 0xFC, 0xC3, + 0xEC, 0x1F, 0x90, 0xF1 +}; + +static const unsigned char TA723_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA724_DN[] = { + 0x30, 0x81, 0x98, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0A, 0x53, 0x63, 0x6F, + 0x74, 0x74, 0x73, 0x64, 0x61, 0x6C, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, + 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1C, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6C, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, + 0x67, 0x69, 0x65, 0x73, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3B, + 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA724_RSA_N[] = { + 0xD5, 0x0C, 0x3A, 0xC4, 0x2A, 0xF9, 0x4E, 0xE2, 0xF5, 0xBE, 0x19, 0x97, + 0x5F, 0x8E, 0x88, 0x53, 0xB1, 0x1F, 0x3F, 0xCB, 0xCF, 0x9F, 0x20, 0x13, + 0x6D, 0x29, 0x3A, 0xC8, 0x0F, 0x7D, 0x3C, 0xF7, 0x6B, 0x76, 0x38, 0x63, + 0xD9, 0x36, 0x60, 0xA8, 0x9B, 0x5E, 0x5C, 0x00, 0x80, 0xB2, 0x2F, 0x59, + 0x7F, 0xF6, 0x87, 0xF9, 0x25, 0x43, 0x86, 0xE7, 0x69, 0x1B, 0x52, 0x9A, + 0x90, 0xE1, 0x71, 0xE3, 0xD8, 0x2D, 0x0D, 0x4E, 0x6F, 0xF6, 0xC8, 0x49, + 0xD9, 0xB6, 0xF3, 0x1A, 0x56, 0xAE, 0x2B, 0xB6, 0x74, 0x14, 0xEB, 0xCF, + 0xFB, 0x26, 0xE3, 0x1A, 0xBA, 0x1D, 0x96, 0x2E, 0x6A, 0x3B, 0x58, 0x94, + 0x89, 0x47, 0x56, 0xFF, 0x25, 0xA0, 0x93, 0x70, 0x53, 0x83, 0xDA, 0x84, + 0x74, 0x14, 0xC3, 0x67, 0x9E, 0x04, 0x68, 0x3A, 0xDF, 0x8E, 0x40, 0x5A, + 0x1D, 0x4A, 0x4E, 0xCF, 0x43, 0x91, 0x3B, 0xE7, 0x56, 0xD6, 0x00, 0x70, + 0xCB, 0x52, 0xEE, 0x7B, 0x7D, 0xAE, 0x3A, 0xE7, 0xBC, 0x31, 0xF9, 0x45, + 0xF6, 0xC2, 0x60, 0xCF, 0x13, 0x59, 0x02, 0x2B, 0x80, 0xCC, 0x34, 0x47, + 0xDF, 0xB9, 0xDE, 0x90, 0x65, 0x6D, 0x02, 0xCF, 0x2C, 0x91, 0xA6, 0xA6, + 0xE7, 0xDE, 0x85, 0x18, 0x49, 0x7C, 0x66, 0x4E, 0xA3, 0x3A, 0x6D, 0xA9, + 0xB5, 0xEE, 0x34, 0x2E, 0xBA, 0x0D, 0x03, 0xB8, 0x33, 0xDF, 0x47, 0xEB, + 0xB1, 0x6B, 0x8D, 0x25, 0xD9, 0x9B, 0xCE, 0x81, 0xD1, 0x45, 0x46, 0x32, + 0x96, 0x70, 0x87, 0xDE, 0x02, 0x0E, 0x49, 0x43, 0x85, 0xB6, 0x6C, 0x73, + 0xBB, 0x64, 0xEA, 0x61, 0x41, 0xAC, 0xC9, 0xD4, 0x54, 0xDF, 0x87, 0x2F, + 0xC7, 0x22, 0xB2, 0x26, 0xCC, 0x9F, 0x59, 0x54, 0x68, 0x9F, 0xFC, 0xBE, + 0x2A, 0x2F, 0xC4, 0x55, 0x1C, 0x75, 0x40, 0x60, 0x17, 0x85, 0x02, 0x55, + 0x39, 0x8B, 0x7F, 0x05 +}; + +static const unsigned char TA724_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA725_DN[] = { + 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x48, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x0C, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, + 0x41, 0x47, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x16, 0x53, 0x77, 0x69, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, + 0x6F, 0x6C, 0x64, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32 +}; + +static const unsigned char TA725_RSA_N[] = { + 0xAF, 0xE4, 0xEE, 0x7E, 0x8B, 0x24, 0x0E, 0x12, 0x6E, 0xA9, 0x50, 0x2D, + 0x16, 0x44, 0x3B, 0x92, 0x92, 0x5C, 0xCA, 0xB8, 0x5D, 0x84, 0x92, 0x42, + 0x13, 0x2A, 0xBC, 0x65, 0x57, 0x82, 0x40, 0x3E, 0x57, 0x24, 0xCD, 0x50, + 0x8B, 0x25, 0x2A, 0xB7, 0x6F, 0xFC, 0xEF, 0xA2, 0xD0, 0xC0, 0x1F, 0x02, + 0x24, 0x4A, 0x13, 0x96, 0x8F, 0x23, 0x13, 0xE6, 0x28, 0x58, 0x00, 0xA3, + 0x47, 0xC7, 0x06, 0xA7, 0x84, 0x23, 0x2B, 0xBB, 0xBD, 0x96, 0x2B, 0x7F, + 0x55, 0xCC, 0x8B, 0xC1, 0x57, 0x1F, 0x0E, 0x62, 0x65, 0x0F, 0xDD, 0x3D, + 0x56, 0x8A, 0x73, 0xDA, 0xAE, 0x7E, 0x6D, 0xBA, 0x81, 0x1C, 0x7E, 0x42, + 0x8C, 0x20, 0x35, 0xD9, 0x43, 0x4D, 0x84, 0xFA, 0x84, 0xDB, 0x52, 0x2C, + 0xF3, 0x0E, 0x27, 0x77, 0x0B, 0x6B, 0xBF, 0x11, 0x2F, 0x72, 0x78, 0x9F, + 0x2E, 0xD8, 0x3E, 0xE6, 0x18, 0x37, 0x5A, 0x2A, 0x72, 0xF9, 0xDA, 0x62, + 0x90, 0x92, 0x95, 0xCA, 0x1F, 0x9C, 0xE9, 0xB3, 0x3C, 0x2B, 0xCB, 0xF3, + 0x01, 0x13, 0xBF, 0x5A, 0xCF, 0xC1, 0xB5, 0x0A, 0x60, 0xBD, 0xDD, 0xB5, + 0x99, 0x64, 0x53, 0xB8, 0xA0, 0x96, 0xB3, 0x6F, 0xE2, 0x26, 0x77, 0x91, + 0x8C, 0xE0, 0x62, 0x10, 0x02, 0x9F, 0x34, 0x0F, 0xA4, 0xD5, 0x92, 0x33, + 0x51, 0xDE, 0xBE, 0x8D, 0xBA, 0x84, 0x7A, 0x60, 0x3C, 0x6A, 0xDB, 0x9F, + 0x2B, 0xEC, 0xDE, 0xDE, 0x01, 0x3F, 0x6E, 0x4D, 0xE5, 0x50, 0x86, 0xCB, + 0xB4, 0xAF, 0xED, 0x44, 0x40, 0xC5, 0xCA, 0x5A, 0x8C, 0xDA, 0xD2, 0x2B, + 0x7C, 0xA8, 0xEE, 0xBE, 0xA6, 0xE5, 0x0A, 0xAA, 0x0E, 0xA5, 0xDF, 0x05, + 0x52, 0xB7, 0x55, 0xC7, 0x22, 0x5D, 0x32, 0x6A, 0x97, 0x97, 0x63, 0x13, + 0xDB, 0xC9, 0xDB, 0x79, 0x36, 0x7B, 0x85, 0x3A, 0x4A, 0xC5, 0x52, 0x89, + 0xF9, 0x24, 0xE7, 0x9D, 0x77, 0xA9, 0x82, 0xFF, 0x55, 0x1C, 0xA5, 0x71, + 0x69, 0x2B, 0xD1, 0x02, 0x24, 0xF2, 0xB3, 0x26, 0xD4, 0x6B, 0xDA, 0x04, + 0x55, 0xE5, 0xC1, 0x0A, 0xC7, 0x6D, 0x30, 0x37, 0x90, 0x2A, 0xE4, 0x9E, + 0x14, 0x33, 0x5E, 0x16, 0x17, 0x55, 0xC5, 0x5B, 0xB5, 0xCB, 0x34, 0x89, + 0x92, 0xF1, 0x9D, 0x26, 0x8F, 0xA1, 0x07, 0xD4, 0xC6, 0xB2, 0x78, 0x50, + 0xDB, 0x0C, 0x0C, 0x0B, 0x7C, 0x0B, 0x8C, 0x41, 0xD7, 0xB9, 0xE9, 0xDD, + 0x8C, 0x88, 0xF7, 0xA3, 0x4D, 0xB2, 0x32, 0xCC, 0xD8, 0x17, 0xDA, 0xCD, + 0xB7, 0xCE, 0x66, 0x9D, 0xD4, 0xFD, 0x5E, 0xFF, 0xBD, 0x97, 0x3E, 0x29, + 0x75, 0xE7, 0x7E, 0xA7, 0x62, 0x58, 0xAF, 0x25, 0x34, 0xA5, 0x41, 0xC7, + 0x3D, 0xBC, 0x0D, 0x50, 0xCA, 0x03, 0x03, 0x0F, 0x08, 0x5A, 0x1F, 0x95, + 0x73, 0x78, 0x62, 0xBF, 0xAF, 0x72, 0x14, 0x69, 0x0E, 0xA5, 0xE5, 0x03, + 0x0E, 0x78, 0x8E, 0x26, 0x28, 0x42, 0xF0, 0x07, 0x0B, 0x62, 0x20, 0x10, + 0x67, 0x39, 0x46, 0xFA, 0xA9, 0x03, 0xCC, 0x04, 0x38, 0x7A, 0x66, 0xEF, + 0x20, 0x83, 0xB5, 0x8C, 0x4A, 0x56, 0x8E, 0x91, 0x00, 0xFC, 0x8E, 0x5C, + 0x82, 0xDE, 0x88, 0xA0, 0xC3, 0xE2, 0x68, 0x6E, 0x7D, 0x8D, 0xEF, 0x3C, + 0xDD, 0x65, 0xF4, 0x5D, 0xAC, 0x51, 0xEF, 0x24, 0x80, 0xAE, 0xAA, 0x56, + 0x97, 0x6F, 0xF9, 0xAD, 0x7D, 0xDA, 0x61, 0x3F, 0x98, 0x77, 0x3C, 0xA5, + 0x91, 0xB6, 0x1C, 0x8C, 0x26, 0xDA, 0x65, 0xA2, 0x09, 0x6D, 0xC1, 0xE2, + 0x54, 0xE3, 0xB9, 0xCA, 0x4C, 0x4C, 0x80, 0x8F, 0x77, 0x7B, 0x60, 0x9A, + 0x1E, 0xDF, 0xB6, 0xF2, 0x48, 0x1E, 0x0E, 0xBA, 0x4E, 0x54, 0x6D, 0x98, + 0xE0, 0xE1, 0xA2, 0x1A, 0xA2, 0x77, 0x50, 0xCF, 0xC4, 0x63, 0x92, 0xEC, + 0x47, 0x19, 0x9D, 0xEB, 0xE6, 0x6B, 0xCE, 0xC1 +}; + +static const unsigned char TA725_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA726_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4C, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1F, 0x4B, 0x72, 0x61, 0x6A, 0x6F, 0x77, 0x61, 0x20, 0x49, 0x7A, + 0x62, 0x61, 0x20, 0x52, 0x6F, 0x7A, 0x6C, 0x69, 0x63, 0x7A, 0x65, 0x6E, + 0x69, 0x6F, 0x77, 0x61, 0x20, 0x53, 0x2E, 0x41, 0x2E, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x53, 0x5A, 0x41, 0x46, + 0x49, 0x52, 0x20, 0x52, 0x4F, 0x4F, 0x54, 0x20, 0x43, 0x41, 0x32 +}; + +static const unsigned char TA726_RSA_N[] = { + 0xB7, 0xBC, 0x3E, 0x50, 0xA8, 0x4B, 0xCD, 0x40, 0xB5, 0xCE, 0x61, 0xE7, + 0x96, 0xCA, 0xB4, 0xA1, 0xDA, 0x0C, 0x22, 0xB0, 0xFA, 0xB5, 0x7B, 0x76, + 0x00, 0x77, 0x8C, 0x0B, 0xCF, 0x7D, 0xA8, 0x86, 0xCC, 0x26, 0x51, 0xE4, + 0x20, 0x3D, 0x85, 0x0C, 0xD6, 0x58, 0xE3, 0xE7, 0xF4, 0x2A, 0x18, 0x9D, + 0xDA, 0xD1, 0xAE, 0x26, 0xEE, 0xEB, 0x53, 0xDC, 0xF4, 0x90, 0xD6, 0x13, + 0x4A, 0x0C, 0x90, 0x3C, 0xC3, 0xF4, 0xDA, 0xD2, 0x8E, 0x0D, 0x92, 0x3A, + 0xDC, 0xB1, 0xB1, 0xFF, 0x38, 0xDE, 0xC3, 0xBA, 0x2D, 0x5F, 0x80, 0xB9, + 0x02, 0xBD, 0x4A, 0x9D, 0x1B, 0x0F, 0xB4, 0xC3, 0xC2, 0xC1, 0x67, 0x03, + 0xDD, 0xDC, 0x1B, 0x9C, 0x3D, 0xB3, 0xB0, 0xDE, 0x00, 0x1E, 0xA8, 0x34, + 0x47, 0xBB, 0x9A, 0xEB, 0xFE, 0x0B, 0x14, 0xBD, 0x36, 0x84, 0xDA, 0x0D, + 0x20, 0xBF, 0xFA, 0x5B, 0xCB, 0xA9, 0x16, 0x20, 0xAD, 0x39, 0x60, 0xEE, + 0x2F, 0x75, 0xB6, 0xE7, 0x97, 0x9C, 0xF9, 0x3E, 0xFD, 0x7E, 0x4D, 0x6F, + 0x4D, 0x2F, 0xEF, 0x88, 0x0D, 0x6A, 0xFA, 0xDD, 0xF1, 0x3D, 0x6E, 0x20, + 0xA5, 0xA0, 0x12, 0xB4, 0x4D, 0x70, 0xB9, 0xCE, 0xD7, 0x72, 0x3B, 0x89, + 0x93, 0xA7, 0x80, 0x84, 0x1C, 0x27, 0x49, 0x72, 0x49, 0xB5, 0xFF, 0x3B, + 0x95, 0x9E, 0xC1, 0xCC, 0xC8, 0x01, 0xEC, 0xE8, 0x0E, 0x8A, 0x0A, 0x96, + 0xE7, 0xB3, 0xA6, 0x87, 0xE5, 0xD6, 0xF9, 0x05, 0x2B, 0x0D, 0x97, 0x40, + 0x70, 0x3C, 0xBA, 0xAC, 0x75, 0x5A, 0x9C, 0xD5, 0x4D, 0x9D, 0x02, 0x0A, + 0xD2, 0x4B, 0x9B, 0x66, 0x4B, 0x46, 0x07, 0x17, 0x65, 0xAD, 0x9F, 0x6C, + 0x88, 0x00, 0xDC, 0x22, 0x89, 0xE0, 0xE1, 0x64, 0xD4, 0x67, 0xBC, 0x31, + 0x79, 0x61, 0x3C, 0xBB, 0xCA, 0x41, 0xCD, 0x5C, 0x6A, 0x00, 0xC8, 0x3C, + 0x38, 0x8E, 0x58, 0xAF +}; + +static const unsigned char TA726_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA727_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x30 +}; + +static const unsigned char TA727_EC_Q[] = { + 0x04, 0xCE, 0xBF, 0xFE, 0x57, 0xA8, 0xBF, 0xD5, 0xAA, 0xF7, 0x10, 0x9A, + 0xCD, 0xBC, 0xD1, 0x11, 0xA2, 0xBD, 0x67, 0x42, 0xCC, 0x90, 0xEB, 0x15, + 0x18, 0x90, 0xD9, 0xA2, 0xCD, 0x0C, 0x2A, 0x25, 0xEB, 0x3E, 0x4F, 0xCE, + 0xB5, 0xD2, 0x8F, 0x0F, 0xF3, 0x35, 0xDA, 0x43, 0x8B, 0x02, 0x80, 0xBE, + 0x6F, 0x51, 0x24, 0x1D, 0x0F, 0x6B, 0x2B, 0xCA, 0x9F, 0xC2, 0x6F, 0x50, + 0x32, 0xE5, 0x37, 0x20, 0xB6, 0x20, 0xFF, 0x88, 0x0D, 0x0F, 0x6D, 0x49, + 0xBB, 0xDB, 0x06, 0xA4, 0x87, 0x90, 0x92, 0x94, 0xF4, 0x09, 0xD0, 0xCF, + 0x7F, 0xC8, 0x80, 0x0B, 0xC1, 0x97, 0xB3, 0xBB, 0x35, 0x27, 0xC9, 0xC2, + 0x1B +}; + +static const unsigned char TA728_DN[] = { + 0x30, 0x63, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x44, 0x45, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1E, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, + 0x65, 0x6C, 0x65, 0x6B, 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x47, 0x6D, 0x62, 0x48, 0x31, 0x2B, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x22, 0x54, 0x65, 0x6C, 0x65, 0x6B, + 0x6F, 0x6D, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, + 0x54, 0x4C, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x32, 0x30, 0x32, 0x33 +}; + +static const unsigned char TA728_RSA_N[] = { + 0xED, 0x35, 0xA1, 0x81, 0x80, 0xF3, 0xCB, 0x4A, 0x69, 0x5B, 0xC2, 0xFB, + 0x51, 0x83, 0xAE, 0x26, 0xFD, 0xE1, 0x6E, 0xF3, 0x81, 0x12, 0x7D, 0x71, + 0x40, 0xFF, 0x87, 0x75, 0x42, 0x29, 0x21, 0xED, 0x81, 0x52, 0x2C, 0xDF, + 0x12, 0xC1, 0x19, 0x84, 0x89, 0xC1, 0xBD, 0xC5, 0x28, 0xD5, 0xD5, 0x4B, + 0x6C, 0x44, 0xD6, 0x4C, 0xDB, 0x07, 0x96, 0x4A, 0x55, 0x7A, 0xCA, 0x36, + 0x82, 0x04, 0x36, 0xA8, 0xA5, 0xFC, 0x27, 0xF6, 0x49, 0xF1, 0xD5, 0x72, + 0x9E, 0x91, 0xF9, 0x23, 0xD6, 0x70, 0x7B, 0xBB, 0xF5, 0x9B, 0xC1, 0xEC, + 0x93, 0xCF, 0x19, 0xEA, 0x65, 0x7E, 0x88, 0x70, 0xA0, 0x73, 0xFC, 0xF6, + 0xFF, 0xB5, 0x56, 0x62, 0xE1, 0x73, 0x6A, 0x34, 0x98, 0x3E, 0x82, 0xB8, + 0xAC, 0x95, 0x53, 0xF4, 0x01, 0xA0, 0x27, 0x07, 0x72, 0xA3, 0x00, 0x53, + 0xA0, 0xE4, 0xB2, 0xAB, 0x83, 0x38, 0x57, 0x33, 0x25, 0x94, 0x9F, 0xBE, + 0x48, 0x1D, 0x98, 0xE1, 0xA3, 0xBA, 0x9E, 0x5C, 0xCD, 0x04, 0x71, 0x51, + 0x7D, 0x75, 0x78, 0xAB, 0xF3, 0x59, 0xAA, 0xC4, 0xE0, 0x60, 0xBE, 0x8F, + 0x83, 0x52, 0xB8, 0x75, 0x1A, 0x41, 0x35, 0xED, 0xBC, 0xF3, 0x3A, 0x63, + 0xE9, 0xA9, 0x14, 0x45, 0xD7, 0xE6, 0x52, 0xD1, 0x6E, 0xD2, 0xDE, 0xBC, + 0xE3, 0xF5, 0x0B, 0x3B, 0xE6, 0xE0, 0xC4, 0xBD, 0x43, 0x64, 0x13, 0xA6, + 0xCE, 0xF4, 0x98, 0x37, 0x6C, 0x8A, 0x95, 0xA8, 0x97, 0xC8, 0x47, 0x0F, + 0xF0, 0x5E, 0x10, 0x8B, 0xE7, 0x1D, 0x1C, 0xFE, 0xB1, 0x3B, 0xA0, 0x05, + 0x33, 0x68, 0x05, 0x41, 0x82, 0xC1, 0x03, 0x2B, 0x01, 0xC8, 0xE7, 0x8F, + 0x4D, 0xAB, 0xE8, 0xB5, 0xF6, 0xCD, 0x6B, 0x44, 0xB5, 0xE7, 0xDD, 0x8B, + 0xEC, 0xEA, 0x25, 0xB4, 0x00, 0x22, 0x57, 0x4D, 0xB0, 0xB1, 0xB2, 0x31, + 0xC1, 0x16, 0xCE, 0xFF, 0xFD, 0x14, 0x84, 0xB7, 0x47, 0xFA, 0xB2, 0xF1, + 0x70, 0xDE, 0xDB, 0x8B, 0x6C, 0x36, 0x58, 0xA4, 0x7C, 0xB3, 0x11, 0xD1, + 0xC3, 0x77, 0x7F, 0x5F, 0xB6, 0x25, 0xE0, 0x0D, 0xC5, 0xD2, 0xB3, 0xF9, + 0xB8, 0xB8, 0x77, 0xDB, 0x37, 0x71, 0x71, 0x47, 0xE3, 0x60, 0x18, 0x4F, + 0x24, 0xB6, 0x75, 0x37, 0x78, 0xB9, 0xA3, 0x62, 0xAF, 0xBD, 0xC9, 0x72, + 0x8E, 0x2F, 0xCC, 0xBB, 0xAE, 0xDB, 0xE4, 0x15, 0x52, 0x19, 0x07, 0x33, + 0xFB, 0x6A, 0xB7, 0x2D, 0x4B, 0x90, 0x28, 0x82, 0x73, 0xFE, 0x18, 0x8B, + 0x35, 0x8D, 0xDB, 0xA7, 0x04, 0x6A, 0xBE, 0xEA, 0xC1, 0x4D, 0x36, 0x3B, + 0x16, 0x36, 0x91, 0x32, 0xEF, 0xB6, 0x40, 0x89, 0x91, 0x43, 0xE0, 0xF2, + 0xA2, 0xAB, 0x04, 0x2E, 0xE6, 0xF2, 0x4C, 0x0E, 0x16, 0x34, 0x20, 0xAC, + 0x87, 0xC1, 0x2D, 0x7E, 0xC9, 0x66, 0x47, 0x17, 0x14, 0x11, 0xA4, 0xF3, + 0xF7, 0xA1, 0x24, 0x89, 0xAB, 0xD8, 0x1A, 0xC8, 0xA1, 0x5C, 0xB1, 0xA3, + 0xF7, 0x8C, 0x6D, 0xC8, 0x01, 0xC9, 0x4F, 0xC9, 0xEC, 0xC4, 0xFC, 0xAC, + 0x51, 0x33, 0xD1, 0xC8, 0x83, 0xD1, 0xC9, 0x9F, 0x1D, 0xD4, 0x47, 0x34, + 0x29, 0x3E, 0xCB, 0xB0, 0x0E, 0xFA, 0x83, 0x0B, 0x28, 0x58, 0xE5, 0x29, + 0xDC, 0x3F, 0x7C, 0xA8, 0x9F, 0xC9, 0xB6, 0x0A, 0xBB, 0xA6, 0xE8, 0x46, + 0x16, 0x0F, 0x96, 0xE5, 0x7B, 0xE4, 0x6A, 0x7A, 0x48, 0x6D, 0x76, 0x98, + 0x05, 0xA5, 0xDC, 0x6D, 0x1E, 0x42, 0x1E, 0x42, 0xDA, 0x1A, 0xE0, 0x52, + 0xF7, 0xB5, 0x83, 0xC0, 0x1A, 0x7B, 0x78, 0x35, 0x2C, 0x38, 0xF5, 0x1F, + 0xFD, 0x49, 0xA3, 0x2E, 0xD2, 0x59, 0x63, 0xBF, 0x80, 0xB0, 0x8C, 0x93, + 0x73, 0xCB, 0x35, 0xA6, 0x99, 0x95, 0x22, 0x61, 0x65, 0x03, 0x60, 0xFB, + 0x2F, 0x93, 0x4B, 0xFA, 0x9A, 0x9C, 0x80, 0x3B +}; + +static const unsigned char TA728_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA729_DN[] = { + 0x30, 0x44, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x46, 0x49, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x11, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, 0x46, 0x69, 0x6E, 0x6C, + 0x61, 0x6E, 0x64, 0x20, 0x4F, 0x79, 0x6A, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x20, + 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x32 +}; + +static const unsigned char TA729_RSA_N[] = { + 0xB2, 0xD0, 0x3F, 0x07, 0xBC, 0xE2, 0x7B, 0xD0, 0x6B, 0x99, 0xF8, 0xE2, + 0x77, 0x69, 0xE7, 0xCE, 0x9D, 0xA4, 0x03, 0xBC, 0x82, 0x6D, 0xA1, 0xFE, + 0x81, 0x65, 0x1F, 0x4C, 0x27, 0xAC, 0x8E, 0x00, 0xBA, 0x16, 0x7B, 0xEB, + 0x30, 0x6A, 0x00, 0xC0, 0xB3, 0x74, 0x68, 0x7E, 0xB2, 0xAF, 0xC7, 0xD5, + 0x62, 0xB3, 0x7A, 0x3F, 0x50, 0xCA, 0x8C, 0x36, 0x44, 0x24, 0x63, 0xD2, + 0x36, 0xE9, 0x0C, 0x85, 0xF6, 0x43, 0x76, 0xD5, 0x4C, 0xA1, 0x60, 0x72, + 0x67, 0xE2, 0x28, 0x33, 0xA5, 0xCB, 0x31, 0xB8, 0x3A, 0x22, 0x23, 0x34, + 0xB8, 0x7D, 0xBD, 0x56, 0x22, 0x40, 0x9D, 0xEA, 0xF4, 0x7B, 0x03, 0xAD, + 0x68, 0xFC, 0xB2, 0x81, 0x4F, 0x98, 0xD0, 0x74, 0xEA, 0x8D, 0xE5, 0x7D, + 0xCD, 0x63, 0xC3, 0xA3, 0xF6, 0xDE, 0x92, 0xC2, 0x58, 0x19, 0xE0, 0x96, + 0xBB, 0xC5, 0xC4, 0xA9, 0x3D, 0xA5, 0x74, 0x96, 0xFE, 0xAF, 0xF9, 0x89, + 0xAA, 0xBD, 0x95, 0x17, 0x54, 0xD8, 0x78, 0x44, 0xF1, 0x0C, 0x77, 0x15, + 0x92, 0xE0, 0x98, 0x42, 0xA7, 0xA4, 0xD6, 0xAA, 0x20, 0x92, 0xCD, 0xC1, + 0xA0, 0xB3, 0x96, 0xB2, 0x3A, 0x84, 0x42, 0x8D, 0x7D, 0xD5, 0x95, 0xE4, + 0xD6, 0xDB, 0xE9, 0x62, 0xC4, 0x58, 0xB3, 0x79, 0xC5, 0x8C, 0xD3, 0x35, + 0x33, 0x83, 0x9F, 0x75, 0xA1, 0x52, 0x27, 0x61, 0x38, 0xF1, 0x59, 0x3D, + 0x8E, 0x50, 0xE0, 0xBD, 0x79, 0x3C, 0xE7, 0x6C, 0x96, 0xFE, 0x5E, 0xD9, + 0x02, 0x65, 0xB4, 0x8E, 0x5C, 0xD0, 0x11, 0x34, 0xDF, 0x5D, 0xBF, 0x52, + 0xA7, 0x81, 0x00, 0xC3, 0x7F, 0x99, 0x45, 0x99, 0x15, 0xD5, 0x17, 0xC8, + 0x0A, 0x53, 0xEC, 0x63, 0xF3, 0x99, 0x7D, 0xCC, 0x69, 0x12, 0x86, 0xC2, + 0x17, 0xF0, 0x01, 0x9E, 0xBF, 0x84, 0xBC, 0xD1, 0x52, 0xCB, 0x1B, 0x92, + 0x66, 0xCE, 0xA4, 0x53, 0xE5, 0xA1, 0xBF, 0xC4, 0xDB, 0x09, 0xD6, 0xE6, + 0x89, 0x56, 0x2B, 0xC8, 0xE3, 0x7C, 0xDE, 0xE3, 0xFF, 0x89, 0xE5, 0x35, + 0x6E, 0x28, 0xE8, 0x6C, 0x0B, 0x23, 0x51, 0xA9, 0x25, 0x05, 0xEB, 0x48, + 0xF8, 0xDD, 0xB1, 0xCA, 0xFA, 0x6C, 0x08, 0x51, 0xEF, 0xB7, 0x18, 0x6C, + 0x44, 0xCA, 0x26, 0xE1, 0x73, 0xC6, 0x89, 0x06, 0x81, 0xE5, 0x8A, 0xAC, + 0xB0, 0xE2, 0x29, 0xC6, 0xB9, 0x24, 0xB3, 0x6B, 0x44, 0x11, 0xF4, 0xA5, + 0x43, 0xC2, 0x4C, 0x43, 0xE5, 0x70, 0x36, 0x8C, 0xB6, 0x33, 0x57, 0x7A, + 0x95, 0x2E, 0x82, 0xA0, 0xF4, 0x5C, 0x10, 0xB3, 0x61, 0x83, 0xF6, 0x02, + 0x05, 0x86, 0x2E, 0x7C, 0x2D, 0x6C, 0xDC, 0x03, 0x46, 0x6E, 0x35, 0x93, + 0xD5, 0x7A, 0x95, 0x2F, 0xDE, 0x20, 0xD8, 0x5B, 0x7E, 0x94, 0x90, 0x04, + 0x6A, 0xBA, 0x59, 0x3D, 0x04, 0x05, 0x75, 0x9D, 0x37, 0xA2, 0x0E, 0x2E, + 0x3D, 0xEB, 0xC1, 0xA4, 0x52, 0x83, 0xFE, 0xD0, 0x6B, 0xD4, 0x66, 0x8E, + 0xDC, 0xC6, 0xE9, 0x12, 0x4E, 0x1D, 0x2A, 0x57, 0xAA, 0x10, 0xBC, 0x7C, + 0x5E, 0x82, 0x7D, 0xA6, 0xA6, 0xC9, 0xF2, 0x2D, 0xB9, 0xF5, 0x17, 0x27, + 0xAD, 0xD1, 0x0E, 0x89, 0x54, 0x2B, 0x95, 0xFA, 0xC0, 0xAD, 0x1D, 0x98, + 0x14, 0x78, 0x33, 0x42, 0x86, 0x0A, 0xA9, 0x73, 0xB5, 0xFB, 0x74, 0x0D, + 0xB7, 0x1B, 0x30, 0x19, 0xC4, 0x5A, 0x0E, 0x1C, 0x27, 0xB7, 0xDA, 0x18, + 0xD0, 0xFF, 0x8A, 0xC8, 0x05, 0xBA, 0xF1, 0xAA, 0x1C, 0xA2, 0x37, 0xB7, + 0xE6, 0x48, 0xA4, 0x46, 0x2C, 0x94, 0xEA, 0xA8, 0x76, 0x62, 0x47, 0x8B, + 0x10, 0x53, 0x07, 0x48, 0x57, 0x6C, 0xE2, 0x92, 0x4D, 0xB6, 0xAE, 0x05, + 0xCB, 0xDC, 0xC1, 0x4A, 0x5E, 0x8F, 0xAC, 0x3D, 0x19, 0x4E, 0xC2, 0xED, + 0x60, 0x75, 0x2B, 0xDB, 0xC1, 0xCA, 0x42, 0xD5 +}; + +static const unsigned char TA729_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA730_DN[] = { + 0x30, 0x37, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, + 0x0B, 0x54, 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, + 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x16, 0x54, + 0x65, 0x6C, 0x69, 0x61, 0x53, 0x6F, 0x6E, 0x65, 0x72, 0x61, 0x20, 0x52, + 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x76, 0x31 +}; + +static const unsigned char TA730_RSA_N[] = { + 0xC2, 0xBE, 0xEB, 0x27, 0xF0, 0x21, 0xA3, 0xF3, 0x69, 0x26, 0x55, 0x7E, + 0x9D, 0xC5, 0x55, 0x16, 0x91, 0x5C, 0xFD, 0xEF, 0x21, 0xBF, 0x53, 0x80, + 0x7A, 0x2D, 0xD2, 0x91, 0x8C, 0x63, 0x31, 0xF0, 0xEC, 0x24, 0xF0, 0xC3, + 0xA5, 0xD2, 0x72, 0x7C, 0x10, 0x6D, 0xF4, 0x37, 0xB7, 0xE5, 0xE6, 0x7C, + 0x79, 0xEA, 0x8C, 0xB5, 0x82, 0x8B, 0xAE, 0x48, 0xB6, 0xAC, 0x00, 0xDC, + 0x65, 0x75, 0xEC, 0x2A, 0x4D, 0x5F, 0xC1, 0x87, 0xF5, 0x20, 0x65, 0x2B, + 0x81, 0xA8, 0x47, 0x3E, 0x89, 0x23, 0x95, 0x30, 0x16, 0x90, 0x7F, 0xE8, + 0x57, 0x07, 0x48, 0xE7, 0x19, 0xAE, 0xBF, 0x45, 0x67, 0xB1, 0x37, 0x1B, + 0x06, 0x2A, 0xFE, 0xDE, 0xF9, 0xAC, 0x7D, 0x83, 0xFB, 0x5E, 0xBA, 0xE4, + 0x8F, 0x97, 0x67, 0xBE, 0x4B, 0x8E, 0x8D, 0x64, 0x07, 0x57, 0x38, 0x55, + 0x69, 0x34, 0x36, 0x3D, 0x13, 0x48, 0xEF, 0x4F, 0xE2, 0xD3, 0x66, 0x1E, + 0xA4, 0xCF, 0x1A, 0xB7, 0x5E, 0x36, 0x33, 0xD4, 0xB4, 0x06, 0xBD, 0x18, + 0x01, 0xFD, 0x77, 0x84, 0x50, 0x00, 0x45, 0xF5, 0x8C, 0x5D, 0xE8, 0x23, + 0xBC, 0x7E, 0xFE, 0x35, 0xE1, 0xED, 0x50, 0x7B, 0xA9, 0x30, 0x8D, 0x19, + 0xD3, 0x09, 0x8E, 0x68, 0x67, 0x5D, 0xBF, 0x3C, 0x97, 0x18, 0x53, 0xBB, + 0x29, 0x62, 0xC5, 0xCA, 0x5E, 0x72, 0xC1, 0xC7, 0x96, 0xD4, 0xDB, 0x2D, + 0xA0, 0xB4, 0x1F, 0x69, 0x03, 0xEC, 0xEA, 0xE2, 0x50, 0xF1, 0x0C, 0x3C, + 0xF0, 0xAC, 0xF3, 0x53, 0x2D, 0xF0, 0x1C, 0xF5, 0xED, 0x6C, 0x39, 0x39, + 0x73, 0x80, 0x16, 0xC8, 0x52, 0xB0, 0x23, 0xCD, 0xE0, 0x3E, 0xDC, 0xDD, + 0x3C, 0x47, 0xA0, 0xBB, 0x35, 0x8A, 0xE2, 0x98, 0x68, 0x8B, 0xBE, 0xE5, + 0xBF, 0x72, 0xEE, 0xD2, 0xFA, 0xA5, 0xED, 0x12, 0xED, 0xFC, 0x98, 0x18, + 0xA9, 0x26, 0x76, 0xDC, 0x28, 0x4B, 0x10, 0x20, 0x1C, 0xD3, 0x7F, 0x16, + 0x77, 0x2D, 0xED, 0x6F, 0x80, 0xF7, 0x49, 0xBB, 0x53, 0x05, 0xBB, 0x5D, + 0x68, 0xC7, 0xD4, 0xC8, 0x75, 0x16, 0x3F, 0x89, 0x5A, 0x8B, 0xF7, 0x17, + 0x47, 0xD4, 0x4C, 0xF1, 0xD2, 0x89, 0x79, 0x3E, 0x4D, 0x3D, 0x98, 0xA8, + 0x61, 0xDE, 0x3A, 0x1E, 0xD2, 0xF8, 0x5E, 0x03, 0xE0, 0xC1, 0xC9, 0x1C, + 0x8C, 0xD3, 0x8D, 0x4D, 0xD3, 0x95, 0x36, 0xB3, 0x37, 0x5F, 0x63, 0x63, + 0x9B, 0x33, 0x14, 0xF0, 0x2D, 0x26, 0x6B, 0x53, 0x7C, 0x89, 0x8C, 0x32, + 0xC2, 0x6E, 0xEC, 0x3D, 0x21, 0x00, 0x39, 0xC9, 0xA1, 0x68, 0xE2, 0x50, + 0x83, 0x2E, 0xB0, 0x3A, 0x2B, 0xF3, 0x36, 0xA0, 0xAC, 0x2F, 0xE4, 0x6F, + 0x61, 0xC2, 0x51, 0x09, 0x39, 0x3E, 0x8B, 0x53, 0xB9, 0xBB, 0x67, 0xDA, + 0xDC, 0x53, 0xB9, 0x76, 0x59, 0x36, 0x9D, 0x43, 0xE5, 0x20, 0xE0, 0x3D, + 0x32, 0x60, 0x85, 0x22, 0x51, 0xB7, 0xC7, 0x33, 0xBB, 0xDD, 0x15, 0x2F, + 0xA4, 0x78, 0xA6, 0x07, 0x7B, 0x81, 0x46, 0x36, 0x04, 0x86, 0xDD, 0x79, + 0x35, 0xC7, 0x95, 0x2C, 0x3B, 0xB0, 0xA3, 0x17, 0x35, 0xE5, 0x73, 0x1F, + 0xB4, 0x5C, 0x59, 0xEF, 0xDA, 0xEA, 0x10, 0x65, 0x7B, 0x7A, 0xD0, 0x7F, + 0x9F, 0xB3, 0xB4, 0x2A, 0x37, 0x3B, 0x70, 0x8B, 0x9B, 0x5B, 0xB9, 0x2B, + 0xB7, 0xEC, 0xB2, 0x51, 0x12, 0x97, 0x53, 0x29, 0x5A, 0xD4, 0xF0, 0x12, + 0x10, 0xDC, 0x4F, 0x02, 0xBB, 0x12, 0x92, 0x2F, 0x62, 0xD4, 0x3F, 0x69, + 0x43, 0x7C, 0x0D, 0xD6, 0xFC, 0x58, 0x75, 0x01, 0x88, 0x9D, 0x58, 0x16, + 0x4B, 0xDE, 0xBA, 0x90, 0xFF, 0x47, 0x01, 0x89, 0x06, 0x6A, 0xF6, 0x5F, + 0xB2, 0x90, 0x6A, 0xB3, 0x02, 0xA6, 0x02, 0x88, 0xBF, 0xB3, 0x47, 0x7E, + 0x2A, 0xD9, 0xD5, 0xFA, 0x68, 0x78, 0x35, 0x4D +}; + +static const unsigned char TA730_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA731_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33 +}; + +static const unsigned char TA731_RSA_N[] = { + 0xC0, 0x31, 0x82, 0x61, 0x92, 0xE4, 0x94, 0x1B, 0x0A, 0x2A, 0x65, 0xD0, + 0xBE, 0x06, 0xA9, 0x87, 0x3B, 0x51, 0x12, 0xEA, 0x70, 0x41, 0xAE, 0xE2, + 0xFB, 0x74, 0xEA, 0x0A, 0x8D, 0xB9, 0xB3, 0x4C, 0xDC, 0x8F, 0xB7, 0x13, + 0x52, 0x4F, 0x54, 0x18, 0xE1, 0x2C, 0x73, 0x95, 0x91, 0xC5, 0x66, 0x3B, + 0x6A, 0xCF, 0xAC, 0x63, 0x6D, 0x87, 0x53, 0xF0, 0xF7, 0xF1, 0x39, 0xB7, + 0xA0, 0x43, 0x63, 0xB0, 0xC4, 0x03, 0x5D, 0x57, 0xA9, 0xE7, 0x44, 0xCE, + 0xC4, 0xA1, 0x83, 0x65, 0xF6, 0x50, 0x3E, 0xB1, 0x7E, 0x16, 0xB8, 0x3A, + 0x8A, 0x02, 0xD0, 0x96, 0x1F, 0x00, 0xCD, 0x05, 0x21, 0xEF, 0x06, 0x6D, + 0xDD, 0x21, 0x9C, 0x19, 0x43, 0x45, 0xA1, 0xC5, 0xE8, 0x80, 0xCA, 0xC2, + 0xAD, 0x40, 0x62, 0x17, 0x06, 0xC6, 0xAA, 0xBC, 0xF3, 0xD6, 0xE6, 0xFC, + 0x50, 0x7E, 0x66, 0x42, 0x1F, 0x3C, 0x8B, 0xA6, 0x79, 0x79, 0x86, 0x40, + 0x35, 0x9F, 0x20, 0xEF, 0x3F, 0xEB, 0x8B, 0x47, 0x1F, 0x8F, 0x8E, 0xC5, + 0xD4, 0x8E, 0xB6, 0x2C, 0xC9, 0x44, 0x04, 0xE3, 0xD4, 0x43, 0x75, 0x3F, + 0xD5, 0x3F, 0xAF, 0x1C, 0xCC, 0x7E, 0x46, 0x5F, 0xAC, 0xDF, 0x64, 0x10, + 0x8A, 0xEF, 0x46, 0xF0, 0x90, 0xF0, 0x0F, 0x2D, 0xF4, 0x88, 0x0B, 0xB1, + 0x29, 0xAA, 0xAF, 0x85, 0xAA, 0x49, 0x58, 0xA8, 0xBF, 0x63, 0xA0, 0x38, + 0x91, 0xE6, 0xB3, 0xE6, 0x77, 0x68, 0xC4, 0xF9, 0x2A, 0x19, 0x84, 0xBB, + 0x0E, 0xE1, 0xF5, 0xAF, 0x89, 0xEC, 0xA5, 0x2F, 0x50, 0x20, 0x74, 0x1E, + 0x12, 0x41, 0x73, 0x1E, 0x24, 0xD9, 0xCA, 0xCE, 0x2C, 0xA1, 0x59, 0x35, + 0xC0, 0xC8, 0x1D, 0x46, 0x27, 0x61, 0x5A, 0x8F, 0xF9, 0x4D, 0xD3, 0x72, + 0x79, 0x66, 0x1E, 0x9F, 0x15, 0x90, 0x21, 0x2D, 0xFD, 0xED, 0x8B, 0x56, + 0x70, 0x03, 0x4A, 0x49, 0x3E, 0x7F, 0x69, 0x31, 0x12, 0x69, 0xC7, 0x1E, + 0x5C, 0xCA, 0x7A, 0x13, 0x8B, 0xE8, 0xE6, 0xF5, 0x60, 0x0F, 0xCC, 0x93, + 0x2C, 0x84, 0x7F, 0xF1, 0xFC, 0x6A, 0xFC, 0x9B, 0x47, 0x9D, 0xDB, 0xAD, + 0x88, 0x3D, 0xF3, 0x76, 0x75, 0x33, 0xD7, 0x4B, 0xA4, 0xC8, 0x8B, 0xF9, + 0xF5, 0x43, 0x58, 0x4F, 0xCB, 0xC8, 0x03, 0x54, 0x8F, 0xA5, 0x85, 0x78, + 0x04, 0x1A, 0xF3, 0x73, 0xF2, 0xD7, 0x87, 0x1D, 0x41, 0x9F, 0xE7, 0xD8, + 0x17, 0xCE, 0x1A, 0x9C, 0x0F, 0x4A, 0xFC, 0xDC, 0x44, 0x68, 0x54, 0x68, + 0xE2, 0x41, 0x3C, 0xFE, 0x2C, 0x84, 0x86, 0x37, 0x3C, 0xCD, 0x3F, 0x2F, + 0xA2, 0xDB, 0xE7, 0xF7, 0x54, 0x03, 0x5F, 0x59, 0xD3, 0xF7, 0x91, 0x78, + 0xC7, 0x8B, 0x77, 0x6A, 0x16, 0xE5, 0x49, 0x85, 0x90, 0x45, 0x72, 0x70, + 0x2F, 0x91, 0x5D, 0xF8, 0x3E, 0x65, 0x40, 0x0B, 0x19, 0x99, 0xC9, 0x26, + 0x20, 0x5A, 0x68, 0xC1, 0x35, 0xBF, 0x4F, 0xA7, 0x51, 0xF1, 0xD8, 0x11, + 0x2B, 0x5B, 0xE0, 0x9A, 0x9E, 0x28, 0x3B, 0x0A, 0x3A, 0x0A, 0x1F, 0xC1, + 0x81, 0xE5, 0x2E, 0xF0, 0xA6, 0xB9, 0x69, 0xA5, 0x88, 0x94, 0xE6, 0x6B, + 0x13, 0x7F, 0xD1, 0x64, 0x3F, 0x3D, 0x9C, 0x70, 0x46, 0xE5, 0xA2, 0x85, + 0x7B, 0x58, 0x84, 0x27, 0xDC, 0xC4, 0x80, 0x3E, 0x67, 0x9A, 0x9A, 0xC7, + 0x9A, 0x31, 0x0E, 0x30, 0xEC, 0xE6, 0x17, 0x40, 0x95, 0xD9, 0x45, 0xED, + 0x01, 0x96, 0xAA, 0xBF, 0x0C, 0xF3, 0x4B, 0xD1, 0x63, 0xF7, 0x13, 0x58, + 0xC0, 0xB8, 0xF3, 0xFA, 0x67, 0xDD, 0x9B, 0x7D, 0x6D, 0x4A, 0xFF, 0x32, + 0x4C, 0xB5, 0x25, 0x3B, 0xFF, 0x1C, 0x67, 0x0F, 0x85, 0x22, 0x59, 0x05, + 0x91, 0x91, 0x41, 0x77, 0x81, 0xD0, 0x85, 0x4C, 0x87, 0x10, 0x71, 0xFF, + 0x9E, 0x43, 0x1B, 0xAE, 0x95, 0x75, 0x2D, 0x81 +}; + +static const unsigned char TA731_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA732_DN[] = { + 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x1C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, 0x69, 0x61, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x6E, 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x73, + 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0C, 0x1B, 0x54, 0x72, 0x75, 0x73, 0x74, 0x41, 0x73, + 0x69, 0x61, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x47, 0x34 +}; + +static const unsigned char TA732_EC_Q[] = { + 0x04, 0xF1, 0xB3, 0xCD, 0x38, 0xE4, 0x25, 0x43, 0xE5, 0xDE, 0x19, 0x09, + 0xBB, 0x81, 0x79, 0xA2, 0x15, 0x5F, 0x15, 0x63, 0x01, 0xDE, 0xC2, 0xAB, + 0xDD, 0xB3, 0xA6, 0x1B, 0x67, 0x4B, 0x80, 0x83, 0xAF, 0x99, 0xCB, 0xAC, + 0x17, 0xDB, 0x2B, 0x96, 0xCA, 0x7C, 0x52, 0x55, 0xE2, 0x1A, 0xE1, 0x3D, + 0x56, 0xF0, 0x2F, 0x16, 0x08, 0xFA, 0x15, 0xBC, 0x9B, 0xBB, 0x47, 0xE6, + 0x3F, 0xEE, 0xA8, 0xE1, 0x4C, 0x8C, 0xF5, 0xD3, 0x36, 0xF9, 0x38, 0x5D, + 0xAB, 0x70, 0x9A, 0x47, 0x0D, 0xE2, 0x81, 0x41, 0x06, 0xEB, 0x49, 0xF9, + 0xB0, 0x29, 0xDD, 0x33, 0xEC, 0x50, 0xA5, 0x7F, 0x79, 0x29, 0xB8, 0x20, + 0x98 +}; + +static const unsigned char TA733_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x31, 0x30, 0x2F, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x28, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA733_RSA_N[] = { + 0xB9, 0x5D, 0x51, 0x28, 0x4B, 0x3C, 0x37, 0x92, 0xD1, 0x82, 0xCE, 0xBD, + 0x1D, 0xBD, 0xCD, 0xDD, 0xB8, 0xAB, 0xCF, 0x0A, 0x3E, 0xE1, 0x5D, 0xE5, + 0xDC, 0xAA, 0x09, 0xB9, 0x57, 0x02, 0x3E, 0xE6, 0x63, 0x61, 0xDF, 0xF2, + 0x0F, 0x82, 0x63, 0xAE, 0xA3, 0xF7, 0xAC, 0x73, 0xD1, 0x7C, 0xE7, 0xB3, + 0x0B, 0xAF, 0x08, 0x00, 0x09, 0x59, 0x7F, 0xCD, 0x29, 0x2A, 0x88, 0x93, + 0x87, 0x17, 0x18, 0x80, 0xED, 0x88, 0xB2, 0xB4, 0xB6, 0x10, 0x1F, 0x2D, + 0xD6, 0x5F, 0x55, 0xA2, 0x13, 0x5D, 0xD1, 0xC6, 0xEB, 0x06, 0x56, 0x89, + 0x88, 0xFE, 0xAC, 0x32, 0x9D, 0xFD, 0x5C, 0xC3, 0x05, 0xC7, 0x6E, 0xEE, + 0x86, 0x89, 0xBA, 0x88, 0x03, 0x9D, 0x72, 0x21, 0x86, 0x90, 0xAE, 0x8F, + 0x03, 0xA5, 0xDC, 0x9F, 0x88, 0x28, 0xCB, 0xA3, 0x92, 0x49, 0x0F, 0xEC, + 0xD0, 0x0F, 0xE2, 0x6D, 0x44, 0x4F, 0x80, 0x6A, 0xB2, 0xD4, 0xE7, 0xA0, + 0x0A, 0x53, 0x01, 0xBA, 0x8E, 0x97, 0x91, 0x76, 0x6E, 0xBC, 0xFC, 0xD5, + 0x6B, 0x36, 0xE6, 0x40, 0x88, 0xD6, 0x7B, 0x2F, 0x5F, 0x05, 0xE8, 0x2C, + 0x6D, 0x11, 0xF3, 0xE7, 0xB2, 0xBE, 0x92, 0x44, 0x4C, 0xD2, 0x97, 0xA4, + 0xFE, 0xD2, 0x72, 0x81, 0x43, 0x07, 0x9C, 0xE9, 0x11, 0x3E, 0xF5, 0x8B, + 0x1A, 0x59, 0x7D, 0x1F, 0x68, 0x58, 0xDD, 0x04, 0x00, 0x2C, 0x96, 0xF3, + 0x43, 0xB3, 0x7E, 0x98, 0x19, 0x74, 0xD9, 0x9C, 0x73, 0xD9, 0x18, 0xBE, + 0x41, 0xC7, 0x34, 0x79, 0xD9, 0xF4, 0x62, 0xC2, 0x43, 0xB9, 0xB3, 0x27, + 0xB0, 0x22, 0xCB, 0xF9, 0x3D, 0x52, 0xC7, 0x30, 0x47, 0xB3, 0xC9, 0x3E, + 0xB8, 0x6A, 0xE2, 0xE7, 0xE8, 0x81, 0x70, 0x5E, 0x42, 0x8B, 0x4F, 0x26, + 0xA5, 0xFE, 0x3A, 0xC2, 0x20, 0x6E, 0xBB, 0xF8, 0x16, 0x8E, 0xCD, 0x0C, + 0xA9, 0xB4, 0x1B, 0x6C, 0x76, 0x10, 0xE1, 0x58, 0x79, 0x46, 0x3E, 0x54, + 0xCE, 0x80, 0xA8, 0x57, 0x09, 0x37, 0x29, 0x1B, 0x99, 0x13, 0x8F, 0x0C, + 0xC8, 0xD6, 0x2C, 0x1C, 0xFB, 0x05, 0xE8, 0x08, 0x95, 0x3D, 0x65, 0x46, + 0xDC, 0xEE, 0xCD, 0x69, 0xE2, 0x4D, 0x8F, 0x87, 0x28, 0x4E, 0x34, 0x0B, + 0x3E, 0xCF, 0x14, 0xD9, 0xBB, 0xDD, 0xB6, 0x50, 0x9A, 0xAD, 0x77, 0xD4, + 0x19, 0xD6, 0xDA, 0x1A, 0x88, 0xC8, 0x4E, 0x1B, 0x27, 0x75, 0xD8, 0xB2, + 0x08, 0xF1, 0xAE, 0x83, 0x30, 0xB9, 0x11, 0x0E, 0xCD, 0x87, 0xF0, 0x84, + 0x8D, 0x15, 0x72, 0x7C, 0xA1, 0xEF, 0xCC, 0xF2, 0x88, 0x61, 0xBA, 0xF4, + 0x69, 0xBB, 0x0C, 0x8C, 0x0B, 0x75, 0x57, 0x04, 0xB8, 0x4E, 0x2A, 0x14, + 0x2E, 0x3D, 0x0F, 0x1C, 0x1E, 0x32, 0xA6, 0x62, 0x36, 0xEE, 0x66, 0xE2, + 0x22, 0xB8, 0x05, 0x40, 0x63, 0x10, 0x22, 0xF3, 0x33, 0x1D, 0x74, 0x72, + 0x8A, 0x2C, 0xF5, 0x39, 0x29, 0xA0, 0xD3, 0xE7, 0x1B, 0x80, 0x84, 0x2D, + 0xC5, 0x3D, 0xE3, 0x4D, 0xB1, 0xFD, 0x1A, 0x6F, 0xBA, 0x65, 0x07, 0x3B, + 0x58, 0xEC, 0x42, 0x45, 0x26, 0xFB, 0xD8, 0xDA, 0x25, 0x72, 0xC4, 0xF6, + 0x00, 0xB1, 0x22, 0x79, 0xBD, 0xE3, 0x7C, 0x59, 0x62, 0x4A, 0x9C, 0x05, + 0x6F, 0x3D, 0xCE, 0xE6, 0xD6, 0x47, 0x63, 0x99, 0xC6, 0x24, 0x6F, 0x72, + 0x12, 0xC8, 0xAC, 0x7F, 0x90, 0xB4, 0x0B, 0x91, 0x70, 0xE8, 0xB7, 0xE6, + 0x16, 0x10, 0x71, 0x17, 0xCE, 0xDE, 0x06, 0x4F, 0x48, 0x41, 0x7D, 0x35, + 0x4A, 0xA3, 0x89, 0xF2, 0xC9, 0x4B, 0x7B, 0x41, 0x11, 0x6D, 0x67, 0xB7, + 0x08, 0x98, 0x4C, 0xE5, 0x11, 0x19, 0xAE, 0x42, 0x80, 0xDC, 0xFB, 0x90, + 0x05, 0xD4, 0xF8, 0x50, 0xCA, 0xBE, 0xE4, 0xAD, 0xC7, 0xC2, 0x94, 0xD7, + 0x16, 0x9D, 0xE6, 0x17, 0x8F, 0xAF, 0x36, 0xFB +}; + +static const unsigned char TA733_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA734_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x32, 0x35, 0x36, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA734_EC_Q[] = { + 0x04, 0x7E, 0xFB, 0x6C, 0xE6, 0x23, 0xE3, 0x73, 0x32, 0x08, 0xCA, 0x60, + 0xE6, 0x53, 0x9C, 0xBA, 0x74, 0x8D, 0x18, 0xB0, 0x78, 0x90, 0x52, 0x80, + 0xDD, 0x38, 0xC0, 0x4A, 0x1D, 0xD1, 0xA8, 0xCC, 0x93, 0xA4, 0x97, 0x06, + 0x38, 0xCA, 0x0D, 0x15, 0x62, 0xC6, 0x8E, 0x01, 0x2A, 0x65, 0x9D, 0xAA, + 0xDF, 0x34, 0x91, 0x2E, 0x81, 0xC1, 0xE4, 0x33, 0x92, 0x31, 0xC4, 0xFD, + 0x09, 0x3A, 0xA6, 0x3F, 0xAD +}; + +static const unsigned char TA735_DN[] = { + 0x30, 0x81, 0x91, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x08, 0x49, 0x6C, 0x6C, 0x69, 0x6E, 0x6F, 0x69, 0x73, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x69, 0x63, 0x61, 0x67, 0x6F, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x13, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, + 0x65, 0x20, 0x48, 0x6F, 0x6C, 0x64, 0x69, 0x6E, 0x67, 0x73, 0x2C, 0x20, + 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x3A, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x31, 0x54, 0x72, 0x75, 0x73, 0x74, 0x77, 0x61, 0x76, 0x65, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x45, 0x43, 0x43, 0x20, + 0x50, 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, + 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA735_EC_Q[] = { + 0x04, 0x6B, 0xDA, 0x0D, 0x75, 0x35, 0x08, 0x31, 0x47, 0x05, 0xAE, 0x45, + 0x99, 0x55, 0xF1, 0x11, 0x13, 0x2E, 0x4A, 0xF8, 0x10, 0x31, 0x23, 0xA3, + 0x7E, 0x83, 0xD3, 0x7F, 0x28, 0x08, 0x3A, 0x26, 0x1A, 0x3A, 0xCF, 0x97, + 0x82, 0x1F, 0x80, 0xB7, 0x27, 0x09, 0x8F, 0xD1, 0x8E, 0x30, 0xC4, 0x0A, + 0x9B, 0x0E, 0xAC, 0x58, 0x04, 0xAB, 0xF7, 0x36, 0x7D, 0x94, 0x23, 0xA4, + 0x9B, 0x0A, 0x8A, 0x8B, 0xAB, 0xEB, 0xFD, 0x39, 0x25, 0x66, 0xF1, 0x5E, + 0xFE, 0x8C, 0xAE, 0x8D, 0x41, 0x79, 0x9D, 0x09, 0x60, 0xCE, 0x28, 0xA9, + 0xD3, 0x8A, 0x6D, 0xF3, 0xD6, 0x45, 0xD4, 0xF2, 0x98, 0x84, 0x38, 0x65, + 0xA0 +}; + +static const unsigned char TA736_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x32 +}; + +static const unsigned char TA736_RSA_N[] = { + 0xAA, 0x5F, 0xDA, 0x1B, 0x5F, 0xE8, 0x73, 0x91, 0xE5, 0xDA, 0x5C, 0xF4, + 0xA2, 0xE6, 0x47, 0xE5, 0xF3, 0x68, 0x55, 0x60, 0x05, 0x1D, 0x02, 0xA4, + 0xB3, 0x9B, 0x59, 0xF3, 0x1E, 0x8A, 0xAF, 0x34, 0xAD, 0xFC, 0x0D, 0xC2, + 0xD9, 0x48, 0x19, 0xEE, 0x69, 0x8F, 0xC9, 0x20, 0xFC, 0x21, 0xAA, 0x07, + 0x19, 0xED, 0xB0, 0x5C, 0xAC, 0x65, 0xC7, 0x5F, 0xED, 0x02, 0x7C, 0x7B, + 0x7C, 0x2D, 0x1B, 0xD6, 0xBA, 0xB9, 0x80, 0xC2, 0x18, 0x82, 0x16, 0x84, + 0xFA, 0x66, 0xB0, 0x08, 0xC6, 0x54, 0x23, 0x81, 0xE4, 0xCD, 0xB9, 0x49, + 0x3F, 0xF6, 0x4F, 0x6E, 0x37, 0x48, 0x28, 0x38, 0x0F, 0xC5, 0xBE, 0xE7, + 0x68, 0x70, 0xFD, 0x39, 0x97, 0x4D, 0xD2, 0xC7, 0x98, 0x91, 0x50, 0xAA, + 0xC4, 0x44, 0xB3, 0x23, 0x7D, 0x39, 0x47, 0xE9, 0x52, 0x62, 0xD6, 0x12, + 0x93, 0x5E, 0xB7, 0x31, 0x96, 0x42, 0x05, 0xFB, 0x76, 0xA7, 0x1E, 0xA3, + 0xF5, 0xC2, 0xFC, 0xE9, 0x7A, 0xC5, 0x6C, 0xA9, 0x71, 0x4F, 0xEA, 0xCB, + 0x78, 0xBC, 0x60, 0xAF, 0xC7, 0xDE, 0xF4, 0xD9, 0xCB, 0xBE, 0x7E, 0x33, + 0xA5, 0x6E, 0x94, 0x83, 0xF0, 0x34, 0xFA, 0x21, 0xAB, 0xEA, 0x8E, 0x72, + 0xA0, 0x3F, 0xA4, 0xDE, 0x30, 0x5B, 0xEF, 0x86, 0x4D, 0x6A, 0x95, 0x5B, + 0x43, 0x44, 0xA8, 0x10, 0x15, 0x1C, 0xE5, 0x01, 0x57, 0xC5, 0x98, 0xF1, + 0xE6, 0x06, 0x28, 0x91, 0xAA, 0x20, 0xC5, 0xB7, 0x53, 0x26, 0x51, 0x43, + 0xB2, 0x0B, 0x11, 0x95, 0x58, 0xE1, 0xC0, 0x0F, 0x76, 0xD9, 0xC0, 0x8D, + 0x7C, 0x81, 0xF3, 0x72, 0x70, 0x9E, 0x6F, 0xFE, 0x1A, 0x8E, 0xD9, 0x5F, + 0x35, 0xC6, 0xB2, 0x6F, 0x34, 0x7C, 0xBE, 0x48, 0x4F, 0xE2, 0x5A, 0x39, + 0xD7, 0xD8, 0x9D, 0x78, 0x9E, 0x9F, 0x86, 0x3E, 0x03, 0x5E, 0x19, 0x8B, + 0x44, 0xA2, 0xD5, 0xC7 +}; + +static const unsigned char TA736_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA737_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x44, 0x45, 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0A, 0x0C, 0x22, 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, + 0x20, 0x45, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x47, 0x6D, 0x62, + 0x48, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x16, + 0x54, 0x2D, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x54, 0x2D, 0x54, + 0x65, 0x6C, 0x65, 0x53, 0x65, 0x63, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, + 0x33 +}; + +static const unsigned char TA737_RSA_N[] = { + 0xBD, 0x75, 0x93, 0xF0, 0x62, 0x22, 0x6F, 0x24, 0xAE, 0xE0, 0x7A, 0x76, + 0xAC, 0x7D, 0xBD, 0xD9, 0x24, 0xD5, 0xB8, 0xB7, 0xFC, 0xCD, 0xF0, 0x42, + 0xE0, 0xEB, 0x78, 0x88, 0x56, 0x5E, 0x9B, 0x9A, 0x54, 0x1D, 0x4D, 0x0C, + 0x8A, 0xF6, 0xD3, 0xCF, 0x70, 0xF4, 0x52, 0xB5, 0xD8, 0x93, 0x04, 0xE3, + 0x46, 0x86, 0x71, 0x41, 0x4A, 0x2B, 0xF0, 0x2A, 0x2C, 0x55, 0x03, 0xD6, + 0x48, 0xC3, 0xE0, 0x39, 0x38, 0xED, 0xF2, 0x5C, 0x3C, 0x3F, 0x44, 0xBC, + 0x93, 0x3D, 0x61, 0xAB, 0x4E, 0xCD, 0x0D, 0xBE, 0xF0, 0x20, 0x27, 0x58, + 0x0E, 0x44, 0x7F, 0x04, 0x1A, 0x87, 0xA5, 0xD7, 0x96, 0x14, 0x36, 0x90, + 0xD0, 0x49, 0x7B, 0xA1, 0x75, 0xFB, 0x1A, 0x6B, 0x73, 0xB1, 0xF8, 0xCE, + 0xA9, 0x09, 0x2C, 0xF2, 0x53, 0xD5, 0xC3, 0x14, 0x44, 0xB8, 0x86, 0xA5, + 0xF6, 0x8B, 0x2B, 0x39, 0xDA, 0xA3, 0x33, 0x54, 0xD9, 0xFA, 0x72, 0x1A, + 0xF7, 0x22, 0x15, 0x1C, 0x88, 0x91, 0x6B, 0x7F, 0x66, 0xE5, 0xC3, 0x6A, + 0x80, 0xB0, 0x24, 0xF3, 0xDF, 0x86, 0x45, 0x88, 0xFD, 0x19, 0x7F, 0x75, + 0x87, 0x1F, 0x1F, 0xB1, 0x1B, 0x0A, 0x73, 0x24, 0x5B, 0xB9, 0x65, 0xE0, + 0x2C, 0x54, 0xC8, 0x60, 0xD3, 0x66, 0x17, 0x3F, 0xE1, 0xCC, 0x54, 0x33, + 0x73, 0x91, 0x02, 0x3A, 0xA6, 0x7F, 0x7B, 0x76, 0x39, 0xA2, 0x1F, 0x96, + 0xB6, 0x38, 0xAE, 0xB5, 0xC8, 0x93, 0x74, 0x1D, 0x9E, 0xB9, 0xB4, 0xE5, + 0x60, 0x9D, 0x2F, 0x56, 0xD1, 0xE0, 0xEB, 0x5E, 0x5B, 0x4C, 0x12, 0x70, + 0x0C, 0x6C, 0x44, 0x20, 0xAB, 0x11, 0xD8, 0xF4, 0x19, 0xF6, 0xD2, 0x9C, + 0x52, 0x37, 0xE7, 0xFA, 0xB6, 0xC2, 0x31, 0x3B, 0x4A, 0xD4, 0x14, 0x99, + 0xAD, 0xC7, 0x1A, 0xF5, 0x5D, 0x5F, 0xFA, 0x07, 0xB8, 0x7C, 0x0D, 0x1F, + 0xD6, 0x83, 0x1E, 0xB3 +}; + +static const unsigned char TA737_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA738_DN[] = { + 0x30, 0x81, 0xD2, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x54, 0x52, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x0F, 0x47, 0x65, 0x62, 0x7A, 0x65, 0x20, 0x2D, 0x20, 0x4B, + 0x6F, 0x63, 0x61, 0x65, 0x6C, 0x69, 0x31, 0x42, 0x30, 0x40, 0x06, 0x03, + 0x55, 0x04, 0x0A, 0x13, 0x39, 0x54, 0x75, 0x72, 0x6B, 0x69, 0x79, 0x65, + 0x20, 0x42, 0x69, 0x6C, 0x69, 0x6D, 0x73, 0x65, 0x6C, 0x20, 0x76, 0x65, + 0x20, 0x54, 0x65, 0x6B, 0x6E, 0x6F, 0x6C, 0x6F, 0x6A, 0x69, 0x6B, 0x20, + 0x41, 0x72, 0x61, 0x73, 0x74, 0x69, 0x72, 0x6D, 0x61, 0x20, 0x4B, 0x75, + 0x72, 0x75, 0x6D, 0x75, 0x20, 0x2D, 0x20, 0x54, 0x55, 0x42, 0x49, 0x54, + 0x41, 0x4B, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x24, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x6B, 0x61, 0x73, 0x79, 0x6F, 0x6E, 0x20, 0x4D, 0x65, 0x72, 0x6B, + 0x65, 0x7A, 0x69, 0x20, 0x2D, 0x20, 0x4B, 0x61, 0x6D, 0x75, 0x20, 0x53, + 0x4D, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2D, + 0x54, 0x55, 0x42, 0x49, 0x54, 0x41, 0x4B, 0x20, 0x4B, 0x61, 0x6D, 0x75, + 0x20, 0x53, 0x4D, 0x20, 0x53, 0x53, 0x4C, 0x20, 0x4B, 0x6F, 0x6B, 0x20, + 0x53, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x6B, 0x61, 0x73, 0x69, 0x20, + 0x2D, 0x20, 0x53, 0x75, 0x72, 0x75, 0x6D, 0x20, 0x31 +}; + +static const unsigned char TA738_RSA_N[] = { + 0xAF, 0x75, 0x30, 0x33, 0xAA, 0xBB, 0x6B, 0xD3, 0x99, 0x2C, 0x12, 0x37, + 0x84, 0xD9, 0x8D, 0x7B, 0x97, 0x80, 0xD3, 0x6E, 0xE7, 0xFF, 0x9B, 0x50, + 0x95, 0x3E, 0x90, 0x95, 0x56, 0x42, 0xD7, 0x19, 0x7C, 0x26, 0x84, 0x8D, + 0x92, 0xFA, 0x01, 0x1D, 0x3A, 0x0F, 0xE2, 0x64, 0x38, 0xB7, 0x8C, 0xBC, + 0xE8, 0x88, 0xF9, 0x8B, 0x24, 0xAB, 0x2E, 0xA3, 0xF5, 0x37, 0xE4, 0x40, + 0x8E, 0x18, 0x25, 0x79, 0x83, 0x75, 0x1F, 0x3B, 0xFF, 0x6C, 0xA8, 0xC5, + 0xC6, 0x56, 0xF8, 0xB4, 0xED, 0x8A, 0x44, 0xA3, 0xAB, 0x6C, 0x4C, 0xFC, + 0x1D, 0xD0, 0xDC, 0xEF, 0x68, 0xBD, 0xCF, 0xE4, 0xAA, 0xCE, 0xF0, 0x55, + 0xF7, 0xA2, 0x34, 0xD4, 0x83, 0x6B, 0x37, 0x7C, 0x1C, 0xC2, 0xFE, 0xB5, + 0x03, 0xEC, 0x57, 0xCE, 0xBC, 0xB4, 0xB5, 0xC5, 0xED, 0x00, 0x0F, 0x53, + 0x37, 0x2A, 0x4D, 0xF4, 0x4F, 0x0C, 0x83, 0xFB, 0x86, 0xCF, 0xCB, 0xFE, + 0x8C, 0x4E, 0xBD, 0x87, 0xF9, 0xA7, 0x8B, 0x21, 0x57, 0x9C, 0x7A, 0xDF, + 0x03, 0x67, 0x89, 0x2C, 0x9D, 0x97, 0x61, 0xA7, 0x10, 0xB8, 0x55, 0x90, + 0x7F, 0x0E, 0x2D, 0x27, 0x38, 0x74, 0xDF, 0xE7, 0xFD, 0xDA, 0x4E, 0x12, + 0xE3, 0x4D, 0x15, 0x22, 0x02, 0xC8, 0xE0, 0xE0, 0xFC, 0x0F, 0xAD, 0x8A, + 0xD7, 0xC9, 0x54, 0x50, 0xCC, 0x3B, 0x0F, 0xCA, 0x16, 0x80, 0x84, 0xD0, + 0x51, 0x56, 0xC3, 0x8E, 0x56, 0x7F, 0x89, 0x22, 0x33, 0x2F, 0xE6, 0x85, + 0x0A, 0xBD, 0xA5, 0xA8, 0x1B, 0x36, 0xDE, 0xD3, 0xDC, 0x2C, 0x6D, 0x3B, + 0xC7, 0x13, 0xBD, 0x59, 0x23, 0x2C, 0xE6, 0xE5, 0xA4, 0xF7, 0xD8, 0x0B, + 0xED, 0xEA, 0x90, 0x40, 0x44, 0xA8, 0x95, 0xBB, 0x93, 0xD5, 0xD0, 0x80, + 0x34, 0xB6, 0x46, 0x78, 0x0E, 0x1F, 0x00, 0x93, 0x46, 0xE1, 0xEE, 0xE9, + 0xF9, 0xEC, 0x4F, 0x17 +}; + +static const unsigned char TA738_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA739_DN[] = { + 0x30, 0x61, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x4E, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x2E, 0x41, 0x67, 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4E, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x61, 0x6C, 0x65, 0x20, 0x64, 0x65, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, + 0x45, 0x6C, 0x65, 0x63, 0x74, 0x72, 0x6F, 0x6E, 0x69, 0x71, 0x75, 0x65, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x10, 0x54, + 0x75, 0x6E, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, + 0x20, 0x43, 0x41 +}; + +static const unsigned char TA739_RSA_N[] = { + 0xC3, 0xCD, 0xD3, 0xFC, 0xBD, 0x04, 0x53, 0xDD, 0x0C, 0x20, 0x3A, 0xD5, + 0x88, 0x2E, 0x05, 0x4B, 0x41, 0xF5, 0x83, 0x82, 0x7E, 0xF7, 0x59, 0x9F, + 0x9E, 0x9E, 0x63, 0xE8, 0x73, 0xDA, 0xF6, 0x06, 0xA9, 0x4F, 0x1F, 0xB4, + 0xF9, 0x0B, 0x1F, 0x39, 0x8C, 0x9A, 0x20, 0xD0, 0x7E, 0x06, 0xD4, 0xEC, + 0x34, 0xD9, 0x86, 0xBC, 0x75, 0x5B, 0x87, 0x88, 0xF0, 0xD2, 0xD9, 0xD4, + 0xA3, 0x0A, 0xB2, 0x6C, 0x1B, 0xEB, 0x49, 0x2C, 0x3E, 0xAC, 0x5D, 0xD8, + 0x94, 0x03, 0xA0, 0xEC, 0x34, 0xE5, 0x30, 0xC4, 0x35, 0x7D, 0xFB, 0x26, + 0x4D, 0x1B, 0x6E, 0x30, 0x54, 0xD8, 0xF5, 0x80, 0x45, 0x9C, 0x39, 0xAD, + 0x9C, 0xC9, 0x25, 0x04, 0x4D, 0x9A, 0x90, 0x3E, 0x4E, 0x40, 0x6E, 0x8A, + 0x6B, 0xCD, 0x29, 0x67, 0xC6, 0xCC, 0x2D, 0xE0, 0x74, 0xE8, 0x05, 0x57, + 0x0A, 0x48, 0x50, 0xFA, 0x7A, 0x43, 0xDA, 0x7E, 0xEC, 0x5B, 0x9A, 0x0E, + 0x62, 0x76, 0xFE, 0xEA, 0x9D, 0x1D, 0x85, 0x72, 0xEC, 0x11, 0xBB, 0x35, + 0xE8, 0x1F, 0x27, 0xBF, 0xC1, 0xA1, 0xC7, 0xBB, 0x48, 0x16, 0xDD, 0x56, + 0xD7, 0xCC, 0x4E, 0xA0, 0xE1, 0xB9, 0xAC, 0xDB, 0xD5, 0x83, 0x19, 0x1A, + 0x85, 0xD1, 0x94, 0x97, 0xD7, 0xCA, 0xA3, 0x65, 0x0B, 0xF3, 0x38, 0xF9, + 0x02, 0xAE, 0xDD, 0xF6, 0x67, 0xCF, 0xC9, 0x3F, 0xF5, 0x8A, 0x2C, 0x47, + 0x1A, 0x99, 0x6F, 0x05, 0x0D, 0xFD, 0xD0, 0x1D, 0x82, 0x31, 0xFC, 0x29, + 0xCC, 0x00, 0x58, 0x97, 0x91, 0x4C, 0x80, 0x00, 0x1C, 0x33, 0x85, 0x96, + 0x2F, 0xCB, 0x41, 0xC2, 0x8B, 0x10, 0x84, 0xC3, 0x09, 0x24, 0x89, 0x1F, + 0xB5, 0x0F, 0xD9, 0xD9, 0x77, 0x47, 0x18, 0x92, 0x94, 0x60, 0x5C, 0xC7, + 0x99, 0x03, 0x3C, 0xFE, 0xF7, 0x95, 0xA7, 0x7D, 0x50, 0xA1, 0x80, 0xC2, + 0xA9, 0x83, 0xAD, 0x58, 0x96, 0x55, 0x21, 0xDB, 0x86, 0x59, 0xD4, 0xAF, + 0xC6, 0xBC, 0xDD, 0x81, 0x6E, 0x07, 0xDB, 0x60, 0x62, 0xFE, 0xEC, 0x10, + 0x6E, 0xDA, 0x68, 0x01, 0xF4, 0x83, 0x1B, 0xA9, 0x3E, 0xA2, 0x5B, 0x23, + 0xD7, 0x64, 0xC6, 0xDF, 0xDC, 0xA2, 0x7D, 0xD8, 0x4B, 0xBA, 0x82, 0xD2, + 0x51, 0xF8, 0x66, 0xBF, 0x06, 0x46, 0xE4, 0x79, 0x2A, 0x26, 0x36, 0x79, + 0x8F, 0x1F, 0x4E, 0x99, 0x1D, 0xB2, 0x8F, 0x0C, 0x0E, 0x1C, 0xFF, 0xC9, + 0x5D, 0xC0, 0xFD, 0x90, 0x10, 0xA6, 0xB1, 0x37, 0xF3, 0xCD, 0x3A, 0x24, + 0x6E, 0xB4, 0x85, 0x90, 0xBF, 0x80, 0xB9, 0x0C, 0x8C, 0xD5, 0x9B, 0xD6, + 0xC8, 0xF1, 0x56, 0x3F, 0x1A, 0x80, 0x89, 0x7A, 0xA9, 0xE2, 0x1B, 0x32, + 0x51, 0x2C, 0x3E, 0xF2, 0xDF, 0x7B, 0xF6, 0x5D, 0x7A, 0x29, 0x19, 0x8E, + 0xE5, 0xC8, 0xBD, 0x36, 0x71, 0x8B, 0x5D, 0x4C, 0xC2, 0x1D, 0x3F, 0xAD, + 0x58, 0xA2, 0xCF, 0x3D, 0x70, 0x4D, 0xA6, 0x50, 0x98, 0x25, 0xDC, 0x23, + 0xF9, 0xB8, 0x58, 0x41, 0x08, 0x71, 0xBF, 0x4F, 0xB8, 0x84, 0xA0, 0x8F, + 0x00, 0x54, 0x15, 0xFC, 0x91, 0x6D, 0x58, 0xA7, 0x96, 0x3B, 0xEB, 0x4B, + 0x96, 0x27, 0xCD, 0x6B, 0xA2, 0xA1, 0x86, 0xAC, 0x0D, 0x7C, 0x54, 0xE6, + 0x66, 0x4C, 0x66, 0x5F, 0x90, 0xBE, 0x21, 0x9A, 0x02, 0x46, 0x2D, 0xE4, + 0x83, 0xC2, 0x80, 0xB9, 0xCF, 0x4B, 0x3E, 0xE8, 0x7F, 0x3C, 0x01, 0xEC, + 0x8F, 0x5E, 0xCD, 0x7F, 0xD2, 0x28, 0x42, 0x01, 0x95, 0x8A, 0xE2, 0x97, + 0x3D, 0x10, 0x21, 0x7D, 0xF6, 0x9D, 0x1C, 0xC5, 0x34, 0xA1, 0xEC, 0x2C, + 0x0E, 0x0A, 0x52, 0x2C, 0x12, 0x55, 0x70, 0x24, 0x3D, 0xCB, 0xC2, 0x14, + 0x35, 0x43, 0x5D, 0x27, 0x4E, 0xBE, 0xC0, 0xBD, 0xAA, 0x7C, 0x96, 0xE7, + 0xFC, 0x9E, 0x61, 0xAD, 0x44, 0xD3, 0x00, 0x97 +}; + +static const unsigned char TA739_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA740_DN[] = { + 0x30, 0x50, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x54, 0x57, 0x43, 0x41, 0x20, 0x43, 0x59, 0x42, + 0x45, 0x52, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA740_RSA_N[] = { + 0xC6, 0xF8, 0xCA, 0x1E, 0xD9, 0x09, 0x20, 0x7E, 0x1D, 0x6C, 0x4E, 0xCE, + 0x8F, 0xE3, 0x47, 0x33, 0x44, 0x9C, 0xC7, 0xC9, 0x69, 0xAA, 0x3A, 0x5B, + 0x78, 0xEE, 0x70, 0xD2, 0x92, 0xF8, 0x04, 0xB3, 0x52, 0x52, 0x1D, 0x67, + 0x72, 0x28, 0xA1, 0xDF, 0x8B, 0x5D, 0x95, 0x0A, 0xFE, 0xEA, 0xCD, 0xED, + 0xF7, 0x29, 0xCE, 0xF0, 0x6F, 0x7F, 0xAC, 0xCD, 0x3D, 0xEF, 0xB3, 0x1C, + 0x45, 0x6A, 0xF7, 0x28, 0x90, 0xF1, 0x61, 0x57, 0xC5, 0x0C, 0xC4, 0xA3, + 0x50, 0x5D, 0xDE, 0xD4, 0xB5, 0xCB, 0x19, 0xCA, 0x80, 0xB9, 0x75, 0xCE, + 0x29, 0xCE, 0xD2, 0x85, 0x22, 0xEC, 0x02, 0x63, 0xCC, 0x44, 0x30, 0x20, + 0xDA, 0xEA, 0x91, 0x5B, 0x56, 0xE6, 0x1D, 0x1C, 0xD5, 0x9D, 0x66, 0xC7, + 0x3F, 0xDF, 0x86, 0xCA, 0x4B, 0x53, 0xC4, 0xD9, 0x8D, 0xB2, 0x1D, 0xEA, + 0xF8, 0xDC, 0x27, 0x53, 0xA3, 0x47, 0xE1, 0x61, 0xCC, 0x7D, 0xB5, 0xB0, + 0xF8, 0xEE, 0x73, 0x91, 0xC5, 0xCE, 0x73, 0x6F, 0xCE, 0xEE, 0x10, 0x1F, + 0x1A, 0x06, 0xCF, 0xE9, 0x27, 0x60, 0xC5, 0x4F, 0x19, 0xE4, 0xEB, 0xCE, + 0x22, 0x26, 0x45, 0xD7, 0x60, 0x99, 0xDD, 0xCE, 0x4F, 0x37, 0xE0, 0x7F, + 0xE7, 0x63, 0xAD, 0xB0, 0xB8, 0x59, 0xB8, 0xD0, 0x06, 0x68, 0x35, 0x60, + 0xD3, 0x36, 0xAE, 0x71, 0x43, 0x04, 0xF1, 0x69, 0x65, 0x78, 0x7C, 0xF3, + 0x1F, 0xF3, 0xCA, 0x28, 0x9F, 0x5A, 0x20, 0x95, 0x66, 0xB4, 0xCD, 0xB7, + 0xEE, 0x8F, 0x78, 0xA4, 0x45, 0x18, 0xE9, 0x26, 0x2F, 0x8D, 0x9B, 0x29, + 0x28, 0xB1, 0xA4, 0xB7, 0x3A, 0x6D, 0xB9, 0xD4, 0x1C, 0x38, 0x72, 0x45, + 0x58, 0xB1, 0x5E, 0xEB, 0xF0, 0x28, 0x9B, 0xB7, 0x82, 0xCA, 0xFD, 0xCF, + 0xD6, 0x33, 0x0F, 0x9F, 0xFB, 0x97, 0x9E, 0xB1, 0x1C, 0x9C, 0x9E, 0xEA, + 0x5F, 0x5E, 0xDB, 0xAA, 0xDD, 0x54, 0xE9, 0x30, 0x21, 0x28, 0x6D, 0x8E, + 0x79, 0xF3, 0x75, 0x92, 0x8C, 0x26, 0xFE, 0xDC, 0xC5, 0xF6, 0xC3, 0xB0, + 0xDF, 0x44, 0x59, 0x43, 0xA3, 0xB6, 0x03, 0x28, 0xF6, 0x08, 0x30, 0xAA, + 0x0D, 0x33, 0xE1, 0xEF, 0x9C, 0xA9, 0x07, 0x22, 0xE3, 0x59, 0x5B, 0x40, + 0x8F, 0xDA, 0x88, 0xB7, 0x69, 0x08, 0xA8, 0xB7, 0x23, 0x2E, 0x44, 0x09, + 0x59, 0x37, 0x5B, 0xC7, 0xE3, 0x17, 0xF2, 0x22, 0xEB, 0x6E, 0x39, 0x52, + 0xC5, 0xDE, 0x54, 0xA7, 0x98, 0xC9, 0x4B, 0x20, 0x95, 0xDC, 0x46, 0x89, + 0x5F, 0xB4, 0x12, 0xF9, 0x85, 0x29, 0x8E, 0xEB, 0xC8, 0x27, 0x15, 0x20, + 0xC0, 0x4B, 0xD4, 0xCC, 0x7C, 0x0C, 0x6C, 0x34, 0x0C, 0x26, 0x9B, 0x26, + 0x31, 0xA6, 0x3C, 0xA7, 0xF6, 0xD9, 0xD0, 0x4B, 0xA2, 0x64, 0xFF, 0x3B, + 0x99, 0x41, 0x72, 0xC1, 0xE0, 0x70, 0x97, 0xF1, 0x24, 0xBB, 0x2B, 0xC4, + 0x74, 0x22, 0xB1, 0xAC, 0x6B, 0x22, 0x32, 0x24, 0xD3, 0x78, 0x2A, 0xC0, + 0xC0, 0xA1, 0x2F, 0xF1, 0x52, 0x05, 0xC9, 0x3F, 0xEF, 0x76, 0x66, 0xE2, + 0x45, 0xD8, 0x0D, 0x3D, 0xAD, 0x95, 0xC8, 0xC7, 0x89, 0x26, 0xC8, 0x0F, + 0xAE, 0xA7, 0x03, 0x2E, 0xFB, 0xC1, 0x5F, 0xFA, 0x20, 0xE1, 0x70, 0xAD, + 0xB0, 0x65, 0x20, 0x37, 0x33, 0x60, 0xB0, 0xD5, 0xAF, 0xD7, 0x0C, 0x1C, + 0xC2, 0x90, 0x70, 0xD7, 0x4A, 0x18, 0xBC, 0x7E, 0x01, 0xB0, 0xB0, 0xEB, + 0x15, 0x1E, 0x44, 0x06, 0xCD, 0xA4, 0x4F, 0xE8, 0x0C, 0xD1, 0xC3, 0x20, + 0x10, 0xE1, 0x54, 0x65, 0x9E, 0xB6, 0x51, 0xD0, 0x1A, 0x76, 0x6B, 0x42, + 0x5A, 0x58, 0x76, 0x34, 0xEA, 0xB7, 0x37, 0x19, 0xAE, 0x2E, 0x75, 0xF9, + 0x96, 0xE5, 0xC1, 0x59, 0xF7, 0x94, 0x57, 0x29, 0x25, 0x8D, 0x3A, 0x4C, + 0xAB, 0x4D, 0x9A, 0x41, 0xD0, 0x5F, 0x26, 0x03 +}; + +static const unsigned char TA740_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA741_DN[] = { + 0x30, 0x51, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x13, 0x54, 0x57, 0x43, 0x41, 0x20, 0x47, 0x6C, 0x6F, + 0x62, 0x61, 0x6C, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA741_RSA_N[] = { + 0xB0, 0x05, 0xDB, 0xC8, 0xEB, 0x8C, 0xC4, 0x6E, 0x8A, 0x21, 0xEF, 0x8E, + 0x4D, 0x9C, 0x71, 0x0A, 0x1F, 0x52, 0x70, 0xED, 0x6D, 0x82, 0x9C, 0x97, + 0xC5, 0xD7, 0x4C, 0x4E, 0x45, 0x49, 0xCB, 0x40, 0x42, 0xB5, 0x12, 0x34, + 0x6C, 0x19, 0xC2, 0x74, 0xA4, 0x31, 0x5F, 0x85, 0x02, 0x97, 0xEC, 0x43, + 0x33, 0x0A, 0x53, 0xD2, 0x9C, 0x8C, 0x8E, 0xB7, 0xB8, 0x79, 0xDB, 0x2B, + 0xD5, 0x6A, 0xF2, 0x8E, 0x66, 0xC4, 0xEE, 0x2B, 0x01, 0x07, 0x92, 0xD4, + 0xB3, 0xD0, 0x02, 0xDF, 0x50, 0xF6, 0x55, 0xAF, 0x66, 0x0E, 0xCB, 0xE0, + 0x47, 0x60, 0x2F, 0x2B, 0x32, 0x39, 0x35, 0x52, 0x3A, 0x28, 0x83, 0xF8, + 0x7B, 0x16, 0xC6, 0x18, 0xB8, 0x62, 0xD6, 0x47, 0x25, 0x91, 0xCE, 0xF0, + 0x19, 0x12, 0x4D, 0xAD, 0x63, 0xF5, 0xD3, 0x3F, 0x75, 0x5F, 0x29, 0xF0, + 0xA1, 0x30, 0x1C, 0x2A, 0xA0, 0x98, 0xA6, 0x15, 0xBD, 0xEE, 0xFD, 0x19, + 0x36, 0xF0, 0xE2, 0x91, 0x43, 0x8F, 0xFA, 0xCA, 0xD6, 0x10, 0x27, 0x49, + 0x4C, 0xEF, 0xDD, 0xC1, 0xF1, 0x85, 0x70, 0x9B, 0xCA, 0xEA, 0xA8, 0x5A, + 0x43, 0xFC, 0x6D, 0x86, 0x6F, 0x73, 0xE9, 0x37, 0x45, 0xA9, 0xF0, 0x36, + 0xC7, 0xCC, 0x88, 0x75, 0x1E, 0xBB, 0x6C, 0x06, 0xFF, 0x9B, 0x6B, 0x3E, + 0x17, 0xEC, 0x61, 0xAA, 0x71, 0x7C, 0xC6, 0x1D, 0xA2, 0xF7, 0x49, 0xE9, + 0x15, 0xB5, 0x3C, 0xD6, 0xA1, 0x61, 0xF5, 0x11, 0xF7, 0x05, 0x6F, 0x1D, + 0xFD, 0x11, 0xBE, 0xD0, 0x30, 0x07, 0xC2, 0x29, 0xB0, 0x09, 0x4E, 0x26, + 0xDC, 0xE3, 0xA2, 0xA8, 0x91, 0x6A, 0x1F, 0xC2, 0x91, 0x45, 0x88, 0x5C, + 0xE5, 0x98, 0xB8, 0x71, 0xA5, 0x15, 0x19, 0xC9, 0x7C, 0x75, 0x11, 0xCC, + 0x70, 0x74, 0x4F, 0x2D, 0x9B, 0x1D, 0x91, 0x44, 0xFD, 0x56, 0x28, 0xA0, + 0xFE, 0xBB, 0x86, 0x6A, 0xC8, 0xFA, 0x5C, 0x0B, 0x58, 0xDC, 0xC6, 0x4B, + 0x76, 0xC8, 0xAB, 0x22, 0xD9, 0x73, 0x0F, 0xA5, 0xF4, 0x5A, 0x02, 0x89, + 0x3F, 0x4F, 0x9E, 0x22, 0x82, 0xEE, 0xA2, 0x74, 0x53, 0x2A, 0x3D, 0x53, + 0x27, 0x69, 0x1D, 0x6C, 0x8E, 0x32, 0x2C, 0x64, 0x00, 0x26, 0x63, 0x61, + 0x36, 0x4E, 0xA3, 0x46, 0xB7, 0x3F, 0x7D, 0xB3, 0x2D, 0xAC, 0x6D, 0x90, + 0xA2, 0x95, 0xA2, 0xCE, 0xCF, 0xDA, 0x82, 0xE7, 0x07, 0x34, 0x19, 0x96, + 0xE9, 0xB8, 0x21, 0xAA, 0x29, 0x7E, 0xA6, 0x38, 0xBE, 0x8E, 0x29, 0x4A, + 0x21, 0x66, 0x79, 0x1F, 0xB3, 0xC3, 0xB5, 0x09, 0x67, 0xDE, 0xD6, 0xD4, + 0x07, 0x46, 0xF3, 0x2A, 0xDA, 0xE6, 0x22, 0x37, 0x60, 0xCB, 0x81, 0xB6, + 0x0F, 0xA0, 0x0F, 0xE9, 0xC8, 0x95, 0x7F, 0xBF, 0x55, 0x91, 0x05, 0x7A, + 0xCF, 0x3D, 0x15, 0xC0, 0x6F, 0xDE, 0x09, 0x94, 0x01, 0x83, 0xD7, 0x34, + 0x1B, 0xCC, 0x40, 0xA5, 0xF0, 0xB8, 0x9B, 0x67, 0xD5, 0x98, 0x91, 0x3B, + 0xA7, 0x84, 0x78, 0x95, 0x26, 0xA4, 0x5A, 0x08, 0xF8, 0x2B, 0x74, 0xB4, + 0x00, 0x04, 0x3C, 0xDF, 0xB8, 0x14, 0x8E, 0xE8, 0xDF, 0xA9, 0x8D, 0x6C, + 0x67, 0x92, 0x33, 0x1D, 0xC0, 0xB7, 0xD2, 0xEC, 0x92, 0xC8, 0xBE, 0x09, + 0xBF, 0x2C, 0x29, 0x05, 0x6F, 0x02, 0x6B, 0x9E, 0xEF, 0xBC, 0xBF, 0x2A, + 0xBC, 0x5B, 0xC0, 0x50, 0x8F, 0x41, 0x70, 0x71, 0x87, 0xB2, 0x4D, 0xB7, + 0x04, 0xA9, 0x84, 0xA3, 0x32, 0xAF, 0xAE, 0xEE, 0x6B, 0x17, 0x8B, 0xB2, + 0xB1, 0xFE, 0x6C, 0xE1, 0x90, 0x8C, 0x88, 0xA8, 0x97, 0x48, 0xCE, 0xC8, + 0x4D, 0xCB, 0xF3, 0x06, 0xCF, 0x5F, 0x6A, 0x0A, 0x42, 0xB1, 0x1E, 0x1E, + 0x77, 0x2F, 0x8E, 0xA0, 0xE6, 0x92, 0x0E, 0x06, 0xFC, 0x05, 0x22, 0xD2, + 0x26, 0xE1, 0x31, 0x51, 0x7D, 0x32, 0xDC, 0x0F +}; + +static const unsigned char TA741_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA742_DN[] = { + 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x54, 0x57, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x09, 0x54, 0x41, 0x49, 0x57, 0x41, 0x4E, 0x2D, 0x43, 0x41, 0x31, + 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x52, 0x6F, + 0x6F, 0x74, 0x20, 0x43, 0x41, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x21, 0x54, 0x57, 0x43, 0x41, 0x20, 0x52, 0x6F, 0x6F, + 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA742_RSA_N[] = { + 0xB0, 0x7E, 0x72, 0xB8, 0xA4, 0x03, 0x94, 0xE6, 0xA7, 0xDE, 0x09, 0x38, + 0x91, 0x4A, 0x11, 0x40, 0x87, 0xA7, 0x7C, 0x59, 0x64, 0x14, 0x7B, 0xB5, + 0x11, 0x10, 0xDD, 0xFE, 0xBF, 0xD5, 0xC0, 0xBB, 0x56, 0xE2, 0x85, 0x25, + 0xF4, 0x35, 0x72, 0x0F, 0xF8, 0x53, 0xD0, 0x41, 0xE1, 0x44, 0x01, 0xC2, + 0xB4, 0x1C, 0xC3, 0x31, 0x42, 0x16, 0x47, 0x85, 0x33, 0x22, 0x76, 0xB2, + 0x0A, 0x6F, 0x0F, 0xE5, 0x25, 0x50, 0x4F, 0x85, 0x86, 0xBE, 0xBF, 0x98, + 0x2E, 0x10, 0x67, 0x1E, 0xBE, 0x11, 0x05, 0x86, 0x05, 0x90, 0xC4, 0x59, + 0xD0, 0x7C, 0x78, 0x10, 0xB0, 0x80, 0x5C, 0xB7, 0xE1, 0xC7, 0x2B, 0x75, + 0xCB, 0x7C, 0x9F, 0xAE, 0xB5, 0xD1, 0x9D, 0x23, 0x37, 0x63, 0xA7, 0xDC, + 0x42, 0xA2, 0x2D, 0x92, 0x04, 0x1B, 0x50, 0xC1, 0x7B, 0xB8, 0x3E, 0x1B, + 0xC9, 0x56, 0x04, 0x8B, 0x2F, 0x52, 0x9B, 0xAD, 0xA9, 0x56, 0xE9, 0xC1, + 0xFF, 0xAD, 0xA9, 0x58, 0x87, 0x30, 0xB6, 0x81, 0xF7, 0x97, 0x45, 0xFC, + 0x19, 0x57, 0x3B, 0x2B, 0x6F, 0xE4, 0x47, 0xF4, 0x99, 0x45, 0xFE, 0x1D, + 0xF1, 0xF8, 0x97, 0xA3, 0x88, 0x1D, 0x37, 0x1C, 0x5C, 0x8F, 0xE0, 0x76, + 0x25, 0x9A, 0x50, 0xF8, 0xA0, 0x54, 0xFF, 0x44, 0x90, 0x76, 0x23, 0xD2, + 0x32, 0xC6, 0xC3, 0xAB, 0x06, 0xBF, 0xFC, 0xFB, 0xBF, 0xF3, 0xAD, 0x7D, + 0x92, 0x62, 0x02, 0x5B, 0x29, 0xD3, 0x35, 0xA3, 0x93, 0x9A, 0x43, 0x64, + 0x60, 0x5D, 0xB2, 0xFA, 0x32, 0xFF, 0x3B, 0x04, 0xAF, 0x4D, 0x40, 0x6A, + 0xF9, 0xC7, 0xE3, 0xEF, 0x23, 0xFD, 0x6B, 0xCB, 0xE5, 0x0F, 0x8B, 0x38, + 0x0D, 0xEE, 0x0A, 0xFC, 0xFE, 0x0F, 0x98, 0x9F, 0x30, 0x31, 0xDD, 0x6C, + 0x52, 0x65, 0xF9, 0x8B, 0x81, 0xBE, 0x22, 0xE1, 0x1C, 0x58, 0x03, 0xBA, + 0x91, 0x1B, 0x89, 0x07 +}; + +static const unsigned char TA742_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA743_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x1C, 0x55, 0x43, 0x41, + 0x20, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, + 0x6C, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x52, 0x6F, 0x6F, + 0x74 +}; + +static const unsigned char TA743_RSA_N[] = { + 0xA9, 0x09, 0x07, 0x28, 0x13, 0x02, 0xB0, 0x99, 0xE0, 0x64, 0xAA, 0x1E, + 0x43, 0x16, 0x7A, 0x73, 0xB1, 0x91, 0xA0, 0x75, 0x3E, 0xA8, 0xFA, 0xE3, + 0x38, 0x00, 0x7A, 0xEC, 0x89, 0x6A, 0x20, 0x0F, 0x8B, 0xC5, 0xB0, 0x9B, + 0x33, 0x03, 0x5A, 0x86, 0xC6, 0x58, 0x86, 0xD5, 0xC1, 0x85, 0xBB, 0x4F, + 0xC6, 0x9C, 0x40, 0x4D, 0xCA, 0xBE, 0xEE, 0x69, 0x96, 0xB8, 0xAD, 0x81, + 0x30, 0x9A, 0x7C, 0x92, 0x05, 0xEB, 0x05, 0x2B, 0x9A, 0x48, 0xD0, 0xB8, + 0x76, 0x3E, 0x96, 0xC8, 0x20, 0xBB, 0xD2, 0xB0, 0xF1, 0x8F, 0xD8, 0xAC, + 0x45, 0x46, 0xFF, 0xAA, 0x67, 0x60, 0xB4, 0x77, 0x7E, 0x6A, 0x1F, 0x3C, + 0x1A, 0x52, 0x7A, 0x04, 0x3D, 0x07, 0x3C, 0x85, 0x0D, 0x84, 0xD0, 0x1F, + 0x76, 0x0A, 0xF7, 0x6A, 0x14, 0xDF, 0x72, 0xE3, 0x34, 0x7C, 0x57, 0x4E, + 0x56, 0x01, 0x3E, 0x79, 0xF1, 0xAA, 0x29, 0x3B, 0x6C, 0xFA, 0xF8, 0x8F, + 0x6D, 0x4D, 0xC8, 0x35, 0xDF, 0xAE, 0xEB, 0xDC, 0x24, 0xEE, 0x79, 0x45, + 0xA7, 0x85, 0xB6, 0x05, 0x88, 0xDE, 0x88, 0x5D, 0x25, 0x7C, 0x97, 0x64, + 0x67, 0x09, 0xD9, 0xBF, 0x5A, 0x15, 0x05, 0x86, 0xF3, 0x09, 0x1E, 0xEC, + 0x58, 0x32, 0x33, 0x11, 0xF3, 0x77, 0x64, 0xB0, 0x76, 0x1F, 0xE4, 0x10, + 0x35, 0x17, 0x1B, 0xF2, 0x0E, 0xB1, 0x6C, 0xA4, 0x2A, 0xA3, 0x73, 0xFC, + 0x09, 0x1F, 0x1E, 0x32, 0x19, 0x53, 0x11, 0xE7, 0xD9, 0xB3, 0x2C, 0x2E, + 0x76, 0x2E, 0xA1, 0xA3, 0xDE, 0x7E, 0x6A, 0x88, 0x09, 0xE8, 0xF2, 0x07, + 0x8A, 0xF8, 0xB2, 0xCD, 0x10, 0xE7, 0xE2, 0x73, 0x40, 0x93, 0xBB, 0x08, + 0xD1, 0x3F, 0xE1, 0xFC, 0x0B, 0x94, 0xB3, 0x25, 0xEF, 0x7C, 0xA6, 0xD7, + 0xD1, 0xAF, 0x9F, 0xFF, 0x96, 0x9A, 0xF5, 0x91, 0x7B, 0x98, 0x0B, 0x77, + 0xD4, 0x7E, 0xE8, 0x07, 0xD2, 0x62, 0xB5, 0x95, 0x39, 0xE3, 0xF3, 0xF1, + 0x6D, 0x0F, 0x0E, 0x65, 0x84, 0x8A, 0x63, 0x54, 0xC5, 0x80, 0xB6, 0xE0, + 0x9E, 0x4B, 0x7D, 0x47, 0x26, 0xA7, 0x01, 0x08, 0x5D, 0xD1, 0x88, 0x9E, + 0xD7, 0xC3, 0x32, 0x44, 0xFA, 0x82, 0x4A, 0x0A, 0x68, 0x54, 0x7F, 0x38, + 0x53, 0x03, 0xCC, 0xA4, 0x00, 0x33, 0x64, 0x51, 0x59, 0x0B, 0xA3, 0x82, + 0x91, 0x7A, 0x5E, 0xEC, 0x16, 0xC2, 0xF3, 0x2A, 0xE6, 0x62, 0xDA, 0x2A, + 0xDB, 0x59, 0x62, 0x10, 0x25, 0x4A, 0x2A, 0x81, 0x0B, 0x47, 0x07, 0x43, + 0x06, 0x70, 0x87, 0xD2, 0xFA, 0x93, 0x11, 0x29, 0x7A, 0x48, 0x4D, 0xEB, + 0x94, 0xC7, 0x70, 0x4D, 0xAF, 0x67, 0xD5, 0x51, 0xB1, 0x80, 0x20, 0x01, + 0x01, 0xB4, 0x7A, 0x08, 0xA6, 0x90, 0x7F, 0x4E, 0xE0, 0xEF, 0x07, 0x41, + 0x87, 0xAF, 0x6A, 0xA5, 0x5E, 0x8B, 0xFB, 0xCF, 0x50, 0xB2, 0x9A, 0x54, + 0xAF, 0xC3, 0x89, 0xBA, 0x58, 0x2D, 0xF5, 0x30, 0x98, 0xB1, 0x36, 0x72, + 0x39, 0x7E, 0x49, 0x04, 0xFD, 0x29, 0xA7, 0x4C, 0x79, 0xE4, 0x05, 0x57, + 0xDB, 0x94, 0xB9, 0x16, 0x53, 0x8D, 0x46, 0xB3, 0x1D, 0x95, 0x61, 0x57, + 0x56, 0x7F, 0xAF, 0xF0, 0x16, 0x5B, 0x61, 0x58, 0x6F, 0x36, 0x50, 0x11, + 0x0B, 0xD8, 0xAC, 0x2B, 0x95, 0x16, 0x1A, 0x0E, 0x1F, 0x08, 0xCD, 0x36, + 0x34, 0x65, 0x10, 0x62, 0x66, 0xD5, 0x80, 0x5F, 0x14, 0x20, 0x5F, 0x2D, + 0x0C, 0xA0, 0x78, 0x0A, 0x68, 0xD6, 0x2C, 0xD7, 0xE9, 0x6F, 0x2B, 0xD2, + 0x4A, 0x05, 0x93, 0xFC, 0x9E, 0x6F, 0x6B, 0x67, 0xFF, 0x88, 0xF1, 0x4E, + 0xA5, 0x69, 0x4A, 0x52, 0x37, 0x05, 0xEA, 0xC6, 0x16, 0x8D, 0xD2, 0xC4, + 0x99, 0xD1, 0x82, 0x2B, 0x3B, 0xBA, 0x35, 0x75, 0xF7, 0x51, 0x51, 0x58, + 0xF3, 0xC8, 0x07, 0xDD, 0xE4, 0xB4, 0x03, 0x7F +}; + +static const unsigned char TA743_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA744_DN[] = { + 0x30, 0x3D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x0C, 0x08, 0x55, 0x6E, 0x69, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x1B, + 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x12, 0x55, 0x43, 0x41, + 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x20, 0x47, 0x32, 0x20, 0x52, + 0x6F, 0x6F, 0x74 +}; + +static const unsigned char TA744_RSA_N[] = { + 0xC5, 0xE6, 0x2B, 0x6F, 0x7C, 0xEF, 0x26, 0x05, 0x27, 0xA3, 0x81, 0x24, + 0xDA, 0x6F, 0xCB, 0x01, 0xF9, 0x99, 0x9A, 0xA9, 0x32, 0xC2, 0x22, 0x87, + 0x61, 0x41, 0x91, 0x3B, 0xCB, 0xC3, 0x68, 0x1B, 0x06, 0xC5, 0x4C, 0xA9, + 0x2B, 0xC1, 0x67, 0x17, 0x22, 0x1D, 0x2B, 0xED, 0xF9, 0x29, 0x89, 0x93, + 0xA2, 0x78, 0xBD, 0x92, 0x6B, 0xA0, 0xA3, 0x0D, 0xA2, 0x7E, 0xCA, 0x93, + 0xB3, 0xA6, 0xD1, 0x8C, 0x35, 0xD5, 0x75, 0xF9, 0x17, 0xF6, 0xCF, 0x45, + 0xC5, 0xE5, 0x7A, 0xEC, 0x77, 0x93, 0xA0, 0x8F, 0x23, 0xAE, 0x0E, 0x1A, + 0x03, 0x7F, 0xBE, 0xD4, 0xD0, 0xED, 0x2E, 0x7B, 0xAB, 0x46, 0x23, 0x5B, + 0xFF, 0x2C, 0xE6, 0x54, 0x7A, 0x94, 0xC0, 0x2A, 0x15, 0xF0, 0xC9, 0x8D, + 0xB0, 0x7A, 0x3B, 0x24, 0xE1, 0xD7, 0x68, 0xE2, 0x31, 0x3C, 0x06, 0x33, + 0x46, 0xB6, 0x54, 0x11, 0xA6, 0xA5, 0x2F, 0x22, 0x54, 0x2A, 0x58, 0x0D, + 0x01, 0x02, 0xF1, 0xFA, 0x15, 0x51, 0x67, 0x6C, 0xC0, 0xFA, 0xD7, 0xB6, + 0x1B, 0x7F, 0xD1, 0x56, 0x88, 0x2F, 0x1A, 0x3A, 0x8D, 0x3B, 0xBB, 0x82, + 0x11, 0xE0, 0x47, 0x00, 0xD0, 0x52, 0x87, 0xAB, 0xFB, 0x86, 0x7E, 0x0F, + 0x24, 0x6B, 0x40, 0x9D, 0x34, 0x67, 0xBC, 0x8D, 0xC7, 0x2D, 0x86, 0x6F, + 0x79, 0x3E, 0x8E, 0xA9, 0x3C, 0x17, 0x4B, 0x7F, 0xB0, 0x99, 0xE3, 0xB0, + 0x71, 0x60, 0xDC, 0x0B, 0xF5, 0x64, 0xC3, 0xCE, 0x43, 0xBC, 0x6D, 0x71, + 0xB9, 0xD2, 0xDE, 0x27, 0x5B, 0x8A, 0xE8, 0xD8, 0xC6, 0xAE, 0xE1, 0x59, + 0x7D, 0xCF, 0x28, 0x2D, 0x35, 0xB8, 0x95, 0x56, 0x1A, 0xF1, 0xB2, 0x58, + 0x4B, 0xB7, 0x12, 0x37, 0xC8, 0x7C, 0xB3, 0xED, 0x4B, 0x80, 0xE1, 0x8D, + 0xFA, 0x32, 0x23, 0xB6, 0x6F, 0xB7, 0x48, 0x95, 0x08, 0xB1, 0x44, 0x4E, + 0x85, 0x8C, 0x3A, 0x02, 0x54, 0x20, 0x2F, 0xDF, 0xBF, 0x57, 0x4F, 0x3B, + 0x3A, 0x90, 0x21, 0xD7, 0xC1, 0x26, 0x35, 0x54, 0x20, 0xEC, 0xC7, 0x3F, + 0x47, 0xEC, 0xEF, 0x5A, 0xBF, 0x4B, 0x7A, 0xC1, 0xAD, 0x3B, 0x17, 0x50, + 0x5C, 0x62, 0xD8, 0x0F, 0x4B, 0x4A, 0xDC, 0x2B, 0xFA, 0x6E, 0xBC, 0x73, + 0x92, 0xCD, 0xEC, 0xC7, 0x50, 0xE8, 0x41, 0x96, 0xD7, 0xA9, 0x7E, 0x6D, + 0xD8, 0xE9, 0x1D, 0x8F, 0x8A, 0xB5, 0xB9, 0x58, 0x92, 0xBA, 0x4A, 0x92, + 0x2B, 0x0C, 0x56, 0xFD, 0x80, 0xEB, 0x08, 0xF0, 0x5E, 0x29, 0x6E, 0x1B, + 0x1C, 0x0C, 0xAF, 0x8F, 0x93, 0x89, 0xAD, 0xDB, 0xBD, 0xA3, 0x9E, 0x21, + 0xCA, 0x89, 0x19, 0xEC, 0xDF, 0xB5, 0xC3, 0x1A, 0xEB, 0x16, 0xFE, 0x78, + 0x36, 0x4C, 0xD6, 0x6E, 0xD0, 0x3E, 0x17, 0x1C, 0x90, 0x17, 0x6B, 0x26, + 0xBA, 0xFB, 0x7A, 0x2F, 0xBF, 0x11, 0x1C, 0x18, 0x0E, 0x2D, 0x73, 0x03, + 0x8F, 0xA0, 0xE5, 0x35, 0xA0, 0x5A, 0xE2, 0x4C, 0x75, 0x1D, 0x71, 0xE1, + 0x39, 0x38, 0x53, 0x78, 0x40, 0xCC, 0x83, 0x93, 0xD7, 0x0A, 0x9E, 0x9D, + 0x5B, 0x8F, 0x8A, 0xE4, 0xE5, 0xE0, 0x48, 0xE4, 0x48, 0xB2, 0x47, 0xCD, + 0x4E, 0x2A, 0x75, 0x2A, 0x7B, 0xF2, 0x22, 0xF6, 0xC9, 0xBE, 0x09, 0x91, + 0x96, 0x57, 0x7A, 0x88, 0x88, 0xAC, 0xEE, 0x70, 0xAC, 0xF9, 0xDC, 0x29, + 0xE3, 0x0C, 0x1C, 0x3B, 0x12, 0x4E, 0x44, 0xD6, 0xA7, 0x4E, 0xB0, 0x26, + 0xC8, 0xF3, 0xD9, 0x1A, 0x97, 0x91, 0x68, 0xEA, 0xEF, 0x8D, 0x46, 0x06, + 0xD2, 0x56, 0x45, 0x58, 0x9A, 0x3C, 0x0C, 0x0F, 0x83, 0xB8, 0x05, 0x25, + 0xC3, 0x39, 0xCF, 0x3B, 0xA4, 0x34, 0x89, 0xB7, 0x79, 0x12, 0x2F, 0x47, + 0xC5, 0xE7, 0xA9, 0x97, 0x69, 0xFC, 0xA6, 0x77, 0x67, 0xB5, 0xDF, 0x7B, + 0xF1, 0x7A, 0x65, 0x15, 0xE4, 0x61, 0x56, 0x65 +}; + +static const unsigned char TA744_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA745_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA745_EC_Q[] = { + 0x04, 0x1A, 0xAC, 0x54, 0x5A, 0xA9, 0xF9, 0x68, 0x23, 0xE7, 0x7A, 0xD5, + 0x24, 0x6F, 0x53, 0xC6, 0x5A, 0xD8, 0x4B, 0xAB, 0xC6, 0xD5, 0xB6, 0xD1, + 0xE6, 0x73, 0x71, 0xAE, 0xDD, 0x9C, 0xD6, 0x0C, 0x61, 0xFD, 0xDB, 0xA0, + 0x89, 0x03, 0xB8, 0x05, 0x14, 0xEC, 0x57, 0xCE, 0xEE, 0x5D, 0x3F, 0xE2, + 0x21, 0xB3, 0xCE, 0xF7, 0xD4, 0x8A, 0x79, 0xE0, 0xA3, 0x83, 0x7E, 0x2D, + 0x97, 0xD0, 0x61, 0xC4, 0xF1, 0x99, 0xDC, 0x25, 0x91, 0x63, 0xAB, 0x7F, + 0x30, 0xA3, 0xB4, 0x70, 0xE2, 0xC7, 0xA1, 0x33, 0x9C, 0xF3, 0xBF, 0x2E, + 0x5C, 0x53, 0xB1, 0x5F, 0xB3, 0x7D, 0x32, 0x7F, 0x8A, 0x34, 0xE3, 0x79, + 0x79 +}; + +static const unsigned char TA746_DN[] = { + 0x30, 0x81, 0x88, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0A, 0x4E, 0x65, 0x77, 0x20, 0x4A, 0x65, 0x72, 0x73, 0x65, + 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0B, + 0x4A, 0x65, 0x72, 0x73, 0x65, 0x79, 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, + 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x54, 0x68, + 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, + 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, 0x31, 0x2E, 0x30, 0x2C, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x55, 0x53, 0x45, 0x52, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 +}; + +static const unsigned char TA746_RSA_N[] = { + 0x80, 0x12, 0x65, 0x17, 0x36, 0x0E, 0xC3, 0xDB, 0x08, 0xB3, 0xD0, 0xAC, + 0x57, 0x0D, 0x76, 0xED, 0xCD, 0x27, 0xD3, 0x4C, 0xAD, 0x50, 0x83, 0x61, + 0xE2, 0xAA, 0x20, 0x4D, 0x09, 0x2D, 0x64, 0x09, 0xDC, 0xCE, 0x89, 0x9F, + 0xCC, 0x3D, 0xA9, 0xEC, 0xF6, 0xCF, 0xC1, 0xDC, 0xF1, 0xD3, 0xB1, 0xD6, + 0x7B, 0x37, 0x28, 0x11, 0x2B, 0x47, 0xDA, 0x39, 0xC6, 0xBC, 0x3A, 0x19, + 0xB4, 0x5F, 0xA6, 0xBD, 0x7D, 0x9D, 0xA3, 0x63, 0x42, 0xB6, 0x76, 0xF2, + 0xA9, 0x3B, 0x2B, 0x91, 0xF8, 0xE2, 0x6F, 0xD0, 0xEC, 0x16, 0x20, 0x90, + 0x09, 0x3E, 0xE2, 0xE8, 0x74, 0xC9, 0x18, 0xB4, 0x91, 0xD4, 0x62, 0x64, + 0xDB, 0x7F, 0xA3, 0x06, 0xF1, 0x88, 0x18, 0x6A, 0x90, 0x22, 0x3C, 0xBC, + 0xFE, 0x13, 0xF0, 0x87, 0x14, 0x7B, 0xF6, 0xE4, 0x1F, 0x8E, 0xD4, 0xE4, + 0x51, 0xC6, 0x11, 0x67, 0x46, 0x08, 0x51, 0xCB, 0x86, 0x14, 0x54, 0x3F, + 0xBC, 0x33, 0xFE, 0x7E, 0x6C, 0x9C, 0xFF, 0x16, 0x9D, 0x18, 0xBD, 0x51, + 0x8E, 0x35, 0xA6, 0xA7, 0x66, 0xC8, 0x72, 0x67, 0xDB, 0x21, 0x66, 0xB1, + 0xD4, 0x9B, 0x78, 0x03, 0xC0, 0x50, 0x3A, 0xE8, 0xCC, 0xF0, 0xDC, 0xBC, + 0x9E, 0x4C, 0xFE, 0xAF, 0x05, 0x96, 0x35, 0x1F, 0x57, 0x5A, 0xB7, 0xFF, + 0xCE, 0xF9, 0x3D, 0xB7, 0x2C, 0xB6, 0xF6, 0x54, 0xDD, 0xC8, 0xE7, 0x12, + 0x3A, 0x4D, 0xAE, 0x4C, 0x8A, 0xB7, 0x5C, 0x9A, 0xB4, 0xB7, 0x20, 0x3D, + 0xCA, 0x7F, 0x22, 0x34, 0xAE, 0x7E, 0x3B, 0x68, 0x66, 0x01, 0x44, 0xE7, + 0x01, 0x4E, 0x46, 0x53, 0x9B, 0x33, 0x60, 0xF7, 0x94, 0xBE, 0x53, 0x37, + 0x90, 0x73, 0x43, 0xF3, 0x32, 0xC3, 0x53, 0xEF, 0xDB, 0xAA, 0xFE, 0x74, + 0x4E, 0x69, 0xC7, 0x6B, 0x8C, 0x60, 0x93, 0xDE, 0xC4, 0xC7, 0x0C, 0xDF, + 0xE1, 0x32, 0xAE, 0xCC, 0x93, 0x3B, 0x51, 0x78, 0x95, 0x67, 0x8B, 0xEE, + 0x3D, 0x56, 0xFE, 0x0C, 0xD0, 0x69, 0x0F, 0x1B, 0x0F, 0xF3, 0x25, 0x26, + 0x6B, 0x33, 0x6D, 0xF7, 0x6E, 0x47, 0xFA, 0x73, 0x43, 0xE5, 0x7E, 0x0E, + 0xA5, 0x66, 0xB1, 0x29, 0x7C, 0x32, 0x84, 0x63, 0x55, 0x89, 0xC4, 0x0D, + 0xC1, 0x93, 0x54, 0x30, 0x19, 0x13, 0xAC, 0xD3, 0x7D, 0x37, 0xA7, 0xEB, + 0x5D, 0x3A, 0x6C, 0x35, 0x5C, 0xDB, 0x41, 0xD7, 0x12, 0xDA, 0xA9, 0x49, + 0x0B, 0xDF, 0xD8, 0x80, 0x8A, 0x09, 0x93, 0x62, 0x8E, 0xB5, 0x66, 0xCF, + 0x25, 0x88, 0xCD, 0x84, 0xB8, 0xB1, 0x3F, 0xA4, 0x39, 0x0F, 0xD9, 0x02, + 0x9E, 0xEB, 0x12, 0x4C, 0x95, 0x7C, 0xF3, 0x6B, 0x05, 0xA9, 0x5E, 0x16, + 0x83, 0xCC, 0xB8, 0x67, 0xE2, 0xE8, 0x13, 0x9D, 0xCC, 0x5B, 0x82, 0xD3, + 0x4C, 0xB3, 0xED, 0x5B, 0xFF, 0xDE, 0xE5, 0x73, 0xAC, 0x23, 0x3B, 0x2D, + 0x00, 0xBF, 0x35, 0x55, 0x74, 0x09, 0x49, 0xD8, 0x49, 0x58, 0x1A, 0x7F, + 0x92, 0x36, 0xE6, 0x51, 0x92, 0x0E, 0xF3, 0x26, 0x7D, 0x1C, 0x4D, 0x17, + 0xBC, 0xC9, 0xEC, 0x43, 0x26, 0xD0, 0xBF, 0x41, 0x5F, 0x40, 0xA9, 0x44, + 0x44, 0xF4, 0x99, 0xE7, 0x57, 0x87, 0x9E, 0x50, 0x1F, 0x57, 0x54, 0xA8, + 0x3E, 0xFD, 0x74, 0x63, 0x2F, 0xB1, 0x50, 0x65, 0x09, 0xE6, 0x58, 0x42, + 0x2E, 0x43, 0x1A, 0x4C, 0xB4, 0xF0, 0x25, 0x47, 0x59, 0xFA, 0x04, 0x1E, + 0x93, 0xD4, 0x26, 0x46, 0x4A, 0x50, 0x81, 0xB2, 0xDE, 0xBE, 0x78, 0xB7, + 0xFC, 0x67, 0x15, 0xE1, 0xC9, 0x57, 0x84, 0x1E, 0x0F, 0x63, 0xD6, 0xE9, + 0x62, 0xBA, 0xD6, 0x5F, 0x55, 0x2E, 0xEA, 0x5C, 0xC6, 0x28, 0x08, 0x04, + 0x25, 0x39, 0xB8, 0x0E, 0x2B, 0xA9, 0xF2, 0x4C, 0x97, 0x1C, 0x07, 0x3F, + 0x0D, 0x52, 0xF5, 0xED, 0xEF, 0x2F, 0x82, 0x0F +}; + +static const unsigned char TA746_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA747_DN[] = { + 0x30, 0x47, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x1A, 0x30, + 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x45, 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, + 0x41 +}; + +static const unsigned char TA747_EC_Q[] = { + 0x04, 0x65, 0x50, 0x4A, 0xAE, 0x8C, 0x79, 0x96, 0x4A, 0xAA, 0x1C, 0x08, + 0xC3, 0xA3, 0xA2, 0xCD, 0xFE, 0x59, 0x56, 0x41, 0x77, 0xFD, 0x26, 0x94, + 0x42, 0xBB, 0x1D, 0xCD, 0x08, 0xDB, 0x73, 0xB2, 0x5B, 0x75, 0xF3, 0xCF, + 0x9C, 0x4E, 0x82, 0xF4, 0xBF, 0xF8, 0x61, 0x26, 0x85, 0x6C, 0xD6, 0x85, + 0x5B, 0x72, 0x70, 0xD2, 0xFD, 0xDB, 0x62, 0xB4, 0xDF, 0x53, 0x8B, 0xBD, + 0xB1, 0x44, 0x58, 0x62, 0x42, 0x09, 0xC7, 0xFA, 0x7F, 0x5B, 0x10, 0xE7, + 0xFE, 0x40, 0xFD, 0xC0, 0xD8, 0xC3, 0x2B, 0x32, 0xE7, 0x70, 0xA6, 0xB7, + 0xA6, 0x20, 0x55, 0x1D, 0x7B, 0x80, 0x5D, 0x4B, 0x8F, 0x67, 0x4C, 0xF1, + 0x10 +}; + +static const unsigned char TA748_DN[] = { + 0x30, 0x43, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x43, 0x4E, 0x31, 0x1C, 0x30, 0x1A, 0x06, 0x03, 0x55, 0x04, 0x0A, + 0x13, 0x13, 0x69, 0x54, 0x72, 0x75, 0x73, 0x43, 0x68, 0x69, 0x6E, 0x61, + 0x20, 0x43, 0x6F, 0x2E, 0x2C, 0x4C, 0x74, 0x64, 0x2E, 0x31, 0x16, 0x30, + 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0D, 0x76, 0x54, 0x72, 0x75, + 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41 +}; + +static const unsigned char TA748_RSA_N[] = { + 0xBD, 0x55, 0x7C, 0x61, 0xD3, 0xB8, 0x1D, 0x04, 0x62, 0x05, 0xA0, 0xAE, + 0x6C, 0xB7, 0x70, 0xB4, 0x41, 0xEA, 0x4B, 0x03, 0x5E, 0x10, 0x3F, 0x90, + 0x5A, 0x1C, 0x8B, 0x3B, 0xB0, 0x66, 0x8B, 0x6C, 0x48, 0xA6, 0x1C, 0x22, + 0xBA, 0xD5, 0x40, 0x92, 0xEE, 0x33, 0xB2, 0x23, 0x59, 0xC9, 0x8E, 0xBC, + 0x58, 0xDA, 0x8B, 0x9E, 0xD0, 0x19, 0xF2, 0x2F, 0x59, 0xC6, 0x8C, 0x63, + 0x5A, 0xBA, 0x9F, 0xA3, 0x0B, 0xB0, 0xB3, 0x9A, 0x5C, 0xBA, 0x11, 0xB8, + 0x12, 0xE9, 0x0C, 0xBB, 0xCF, 0x6E, 0x6C, 0x80, 0x87, 0x29, 0x14, 0x03, + 0x2C, 0x8D, 0x24, 0x9A, 0xC8, 0x64, 0x83, 0xB5, 0x6A, 0xAC, 0x13, 0x2C, + 0x33, 0xF1, 0x9F, 0xDC, 0x2C, 0x61, 0x3C, 0x1A, 0x3F, 0x70, 0x55, 0x9B, + 0xAD, 0x00, 0x52, 0x7F, 0xCF, 0x04, 0xB9, 0xFE, 0x36, 0xFA, 0x9C, 0xC0, + 0x16, 0xAE, 0x62, 0xFE, 0x96, 0x4C, 0x43, 0x7E, 0x55, 0x14, 0xBE, 0x1A, + 0xB3, 0xD2, 0x6D, 0xC2, 0xAF, 0x76, 0x66, 0x95, 0x6B, 0x2A, 0xB0, 0x94, + 0x77, 0x85, 0x5E, 0x04, 0x0F, 0x62, 0x1D, 0x63, 0x75, 0xF7, 0x6B, 0xE7, + 0xCB, 0x5B, 0x9A, 0x70, 0xEC, 0x3E, 0x67, 0x05, 0xF0, 0xFE, 0x07, 0x08, + 0x80, 0xCF, 0x28, 0xDB, 0x05, 0xC6, 0x14, 0x27, 0x2F, 0x86, 0x7D, 0xF0, + 0x27, 0xDE, 0xFF, 0xE6, 0x7E, 0x33, 0x48, 0xE7, 0x0B, 0x1E, 0x58, 0xD1, + 0x27, 0x2B, 0x53, 0x0E, 0x57, 0x4A, 0x65, 0xD7, 0xFB, 0xA2, 0x80, 0x60, + 0xFC, 0x4C, 0xBC, 0x35, 0x53, 0x01, 0x6A, 0x97, 0x72, 0x82, 0xAF, 0xF1, + 0x1D, 0x70, 0xE8, 0x9C, 0xF5, 0xEF, 0x5E, 0xC2, 0x6C, 0xC7, 0x47, 0x7E, + 0x5A, 0x94, 0x85, 0x26, 0x4D, 0x3B, 0xBA, 0xEB, 0x4C, 0xE8, 0xB0, 0x09, + 0xC2, 0x65, 0xC2, 0x9D, 0x9D, 0x09, 0x9B, 0x4E, 0xB5, 0x97, 0x05, 0xAC, + 0xF5, 0x06, 0xA0, 0xF7, 0x36, 0x05, 0x7E, 0xF4, 0x90, 0xB2, 0x6B, 0xC4, + 0xB4, 0xF9, 0x64, 0xEA, 0xE9, 0x1A, 0x0A, 0xC8, 0x0D, 0xA8, 0xED, 0x27, + 0xC9, 0xD4, 0xE7, 0xB3, 0xB9, 0xAB, 0x82, 0x22, 0x90, 0x27, 0x3D, 0x2A, + 0xE8, 0x7C, 0x90, 0xEF, 0xBC, 0x4F, 0xFD, 0xE2, 0x0A, 0x24, 0xA7, 0xDE, + 0x65, 0x24, 0xA4, 0x5D, 0xEA, 0xC0, 0x76, 0x30, 0xD3, 0x77, 0x50, 0xF8, + 0x0D, 0x04, 0x9B, 0x94, 0x36, 0x01, 0x73, 0xCA, 0x06, 0x58, 0xA6, 0xD3, + 0x3B, 0xDC, 0xFA, 0x04, 0x46, 0x13, 0x55, 0x8A, 0xC9, 0x44, 0x47, 0xB8, + 0x51, 0x39, 0x1A, 0x2E, 0xE8, 0x34, 0xE2, 0x79, 0xCB, 0x59, 0x4A, 0x0A, + 0x7F, 0xBC, 0xA6, 0xEF, 0x1F, 0x03, 0x67, 0x6A, 0x59, 0x2B, 0x25, 0x62, + 0x93, 0xD9, 0x53, 0x19, 0x66, 0x3C, 0x27, 0x62, 0x29, 0x86, 0x4D, 0xA4, + 0x6B, 0xEE, 0xFF, 0xD4, 0x4E, 0xBA, 0xD5, 0xB4, 0xE2, 0x8E, 0x48, 0x5A, + 0x00, 0x19, 0x09, 0xF1, 0x05, 0xD9, 0xCE, 0x91, 0xB1, 0xF7, 0xEB, 0xE9, + 0x39, 0x4F, 0xF6, 0x6F, 0x04, 0x43, 0x9A, 0x55, 0xF5, 0x3E, 0x05, 0x14, + 0xBD, 0xBF, 0xB3, 0x59, 0xB4, 0xD8, 0x8E, 0x33, 0x84, 0xA3, 0x90, 0x52, + 0xAA, 0xB3, 0x02, 0x95, 0x60, 0xF9, 0x0C, 0x4C, 0x68, 0xF9, 0xEE, 0xD5, + 0x17, 0x0D, 0xF8, 0x71, 0x57, 0xB5, 0x25, 0xE4, 0x29, 0xEE, 0x65, 0x5D, + 0xAF, 0xD1, 0xEE, 0x3C, 0x17, 0x0B, 0x5A, 0x43, 0xC5, 0xA5, 0x86, 0xEA, + 0x24, 0x9E, 0xE2, 0x05, 0x07, 0xDC, 0x34, 0x42, 0x12, 0x91, 0xD6, 0x39, + 0x74, 0xAE, 0x4C, 0x41, 0x82, 0xDB, 0xF2, 0xA6, 0x48, 0xD1, 0xB3, 0x9B, + 0xF3, 0x33, 0xAA, 0xF3, 0xA6, 0xC0, 0xC5, 0x4E, 0xF5, 0xF4, 0x9D, 0x76, + 0x63, 0xE6, 0x02, 0xC6, 0x22, 0x4B, 0xC1, 0x95, 0x3F, 0x50, 0x64, 0x2C, + 0x54, 0xE5, 0xB6, 0xF0, 0x3C, 0x29, 0xCF, 0x57 +}; + +static const unsigned char TA748_RSA_E[] = { + 0x01, 0x00, 0x01 +}; + +static const unsigned char TA749_DN[] = { + 0x30, 0x81, 0x82, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x13, 0x15, 0x77, 0x77, 0x77, 0x2E, 0x78, 0x72, 0x61, 0x6D, 0x70, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2E, 0x63, 0x6F, 0x6D, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x1B, 0x58, + 0x52, 0x61, 0x6D, 0x70, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x49, + 0x6E, 0x63, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x24, 0x58, 0x52, 0x61, 0x6D, 0x70, 0x20, 0x47, 0x6C, 0x6F, 0x62, 0x61, + 0x6C, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, + 0x79 +}; + +static const unsigned char TA749_RSA_N[] = { + 0x98, 0x24, 0x1E, 0xBD, 0x15, 0xB4, 0xBA, 0xDF, 0xC7, 0x8C, 0xA5, 0x27, + 0xB6, 0x38, 0x0B, 0x69, 0xF3, 0xB6, 0x4E, 0xA8, 0x2C, 0x2E, 0x21, 0x1D, + 0x5C, 0x44, 0xDF, 0x21, 0x5D, 0x7E, 0x23, 0x74, 0xFE, 0x5E, 0x7E, 0xB4, + 0x4A, 0xB7, 0xA6, 0xAD, 0x1F, 0xAE, 0xE0, 0x06, 0x16, 0xE2, 0x9B, 0x5B, + 0xD9, 0x67, 0x74, 0x6B, 0x5D, 0x80, 0x8F, 0x29, 0x9D, 0x86, 0x1B, 0xD9, + 0x9C, 0x0D, 0x98, 0x6D, 0x76, 0x10, 0x28, 0x58, 0xE4, 0x65, 0xB0, 0x7F, + 0x4A, 0x98, 0x79, 0x9F, 0xE0, 0xC3, 0x31, 0x7E, 0x80, 0x2B, 0xB5, 0x8C, + 0xC0, 0x40, 0x3B, 0x11, 0x86, 0xD0, 0xCB, 0xA2, 0x86, 0x36, 0x60, 0xA4, + 0xD5, 0x30, 0x82, 0x6D, 0xD9, 0x6E, 0xD0, 0x0F, 0x12, 0x04, 0x33, 0x97, + 0x5F, 0x4F, 0x61, 0x5A, 0xF0, 0xE4, 0xF9, 0x91, 0xAB, 0xE7, 0x1D, 0x3B, + 0xBC, 0xE8, 0xCF, 0xF4, 0x6B, 0x2D, 0x34, 0x7C, 0xE2, 0x48, 0x61, 0x1C, + 0x8E, 0xF3, 0x61, 0x44, 0xCC, 0x6F, 0xA0, 0x4A, 0xA9, 0x94, 0xB0, 0x4D, + 0xDA, 0xE7, 0xA9, 0x34, 0x7A, 0x72, 0x38, 0xA8, 0x41, 0xCC, 0x3C, 0x94, + 0x11, 0x7D, 0xEB, 0xC8, 0xA6, 0x8C, 0xB7, 0x86, 0xCB, 0xCA, 0x33, 0x3B, + 0xD9, 0x3D, 0x37, 0x8B, 0xFB, 0x7A, 0x3E, 0x86, 0x2C, 0xE7, 0x73, 0xD7, + 0x0A, 0x57, 0xAC, 0x64, 0x9B, 0x19, 0xEB, 0xF4, 0x0F, 0x04, 0x08, 0x8A, + 0xAC, 0x03, 0x17, 0x19, 0x64, 0xF4, 0x5A, 0x25, 0x22, 0x8D, 0x34, 0x2C, + 0xB2, 0xF6, 0x68, 0x1D, 0x12, 0x6D, 0xD3, 0x8A, 0x1E, 0x14, 0xDA, 0xC4, + 0x8F, 0xA6, 0xE2, 0x23, 0x85, 0xD5, 0x7A, 0x0D, 0xBD, 0x6A, 0xE0, 0xE9, + 0xEC, 0xEC, 0x17, 0xBB, 0x42, 0x1B, 0x67, 0xAA, 0x25, 0xED, 0x45, 0x83, + 0x21, 0xFC, 0xC1, 0xC9, 0x7C, 0xD5, 0x62, 0x3E, 0xFA, 0xF2, 0xC5, 0x2D, + 0xD3, 0xFD, 0xD4, 0x65 +}; + +static const unsigned char TA749_RSA_E[] = { + 0x01, 0x00, 0x01 +}; diff --git a/libcurl/lib/vtls/vtls.c b/libcurl/lib/vtls/vtls.c new file mode 100644 index 0000000..c293a2e --- /dev/null +++ b/libcurl/lib/vtls/vtls.c @@ -0,0 +1,1354 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This file is for implementing all "generic" SSL functions that all libcurl + internals should use. It is then responsible for calling the proper + "backend" function. + + SSL-functions in libcurl should call functions in this source file, and not + to any specific SSL-layer. + + Curl_ssl_ - prefix for generic ones + + Note that this source code uses the functions of the configured SSL + backend via the global Curl_ssl instance. + + "SSL/TLS Strong Encryption: An Introduction" + https://httpd.apache.org/docs/2.0/ssl/ssl_intro.html +*/ + +#include "curl_setup.h" + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif + +#include "urldata.h" + +#include "vtls.h" /* generic SSL protos etc */ +#include "slist.h" +#include "sendf.h" +#include "strcase.h" +#include "url.h" +#include "progress.h" +#include "share.h" +#include "multiif.h" +#include "timeval.h" +#include "curl_md5.h" +#include "warnless.h" +#include "curl_base64.h" +#include "curl_printf.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* convenience macro to check if this handle is using a shared SSL session */ +#define SSLSESSION_SHARED(data) (data->share && \ + (data->share->specifier & \ + (1<var) { \ + dest->var = strdup(source->var); \ + if(!dest->var) \ + return FALSE; \ + } \ + else \ + dest->var = NULL; + +bool +Curl_ssl_config_matches(struct ssl_primary_config* data, + struct ssl_primary_config* needle) +{ + if((data->version == needle->version) && + (data->version_max == needle->version_max) && + (data->verifypeer == needle->verifypeer) && + (data->verifyhost == needle->verifyhost) && + (data->verifystatus == needle->verifystatus) && + Curl_safe_strcasecompare(data->CApath, needle->CApath) && + Curl_safe_strcasecompare(data->CAfile, needle->CAfile) && + Curl_safe_strcasecompare(data->clientcert, needle->clientcert) && + Curl_safe_strcasecompare(data->random_file, needle->random_file) && + Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) && + Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) && + Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13)) + return TRUE; + + return FALSE; +} + +bool +Curl_clone_primary_ssl_config(struct ssl_primary_config *source, + struct ssl_primary_config *dest) +{ + dest->version = source->version; + dest->version_max = source->version_max; + dest->verifypeer = source->verifypeer; + dest->verifyhost = source->verifyhost; + dest->verifystatus = source->verifystatus; + dest->sessionid = source->sessionid; + + CLONE_STRING(CApath); + CLONE_STRING(CAfile); + CLONE_STRING(clientcert); + CLONE_STRING(random_file); + CLONE_STRING(egdsocket); + CLONE_STRING(cipher_list); + CLONE_STRING(cipher_list13); + + return TRUE; +} + +void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc) +{ + Curl_safefree(sslc->CApath); + Curl_safefree(sslc->CAfile); + Curl_safefree(sslc->clientcert); + Curl_safefree(sslc->random_file); + Curl_safefree(sslc->egdsocket); + Curl_safefree(sslc->cipher_list); + Curl_safefree(sslc->cipher_list13); +} + +#ifdef USE_SSL +static int multissl_init(const struct Curl_ssl *backend); +#endif + +int Curl_ssl_backend(void) +{ +#ifdef USE_SSL + multissl_init(NULL); + return Curl_ssl->info.id; +#else + return (int)CURLSSLBACKEND_NONE; +#endif +} + +#ifdef USE_SSL + +/* "global" init done? */ +static bool init_ssl = FALSE; + +/** + * Global SSL init + * + * @retval 0 error initializing SSL + * @retval 1 SSL initialized successfully + */ +int Curl_ssl_init(void) +{ + /* make sure this is only done once */ + if(init_ssl) + return 1; + init_ssl = TRUE; /* never again */ + + return Curl_ssl->init(); +} + + +/* Global cleanup */ +void Curl_ssl_cleanup(void) +{ + if(init_ssl) { + /* only cleanup if we did a previous init */ + Curl_ssl->cleanup(); + init_ssl = FALSE; + } +} + +static bool ssl_prefs_check(struct Curl_easy *data) +{ + /* check for CURLOPT_SSLVERSION invalid parameter value */ + const long sslver = data->set.ssl.primary.version; + if((sslver < 0) || (sslver >= CURL_SSLVERSION_LAST)) { + failf(data, "Unrecognized parameter value passed via CURLOPT_SSLVERSION"); + return FALSE; + } + + switch(data->set.ssl.primary.version_max) { + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_DEFAULT: + break; + + default: + if((data->set.ssl.primary.version_max >> 16) < sslver) { + failf(data, "CURL_SSLVERSION_MAX incompatible with CURL_SSLVERSION"); + return FALSE; + } + } + + return TRUE; +} + +static CURLcode +ssl_connect_init_proxy(struct connectdata *conn, int sockindex) +{ + DEBUGASSERT(conn->bits.proxy_ssl_connected[sockindex]); + if(ssl_connection_complete == conn->ssl[sockindex].state && + !conn->proxy_ssl[sockindex].use) { + struct ssl_backend_data *pbdata; + + if(!(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY)) + return CURLE_NOT_BUILT_IN; + + /* The pointers to the ssl backend data, which is opaque here, are swapped + rather than move the contents. */ + pbdata = conn->proxy_ssl[sockindex].backend; + conn->proxy_ssl[sockindex] = conn->ssl[sockindex]; + + memset(&conn->ssl[sockindex], 0, sizeof(conn->ssl[sockindex])); + memset(pbdata, 0, Curl_ssl->sizeof_ssl_backend_data); + + conn->ssl[sockindex].backend = pbdata; + } + return CURLE_OK; +} + +CURLcode +Curl_ssl_connect(struct connectdata *conn, int sockindex) +{ + CURLcode result; + + if(conn->bits.proxy_ssl_connected[sockindex]) { + result = ssl_connect_init_proxy(conn, sockindex); + if(result) + return result; + } + + if(!ssl_prefs_check(conn->data)) + return CURLE_SSL_CONNECT_ERROR; + + /* mark this is being ssl-enabled from here on. */ + conn->ssl[sockindex].use = TRUE; + conn->ssl[sockindex].state = ssl_connection_negotiating; + + result = Curl_ssl->connect_blocking(conn, sockindex); + + if(!result) + Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */ + + return result; +} + +CURLcode +Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex, + bool *done) +{ + CURLcode result; + if(conn->bits.proxy_ssl_connected[sockindex]) { + result = ssl_connect_init_proxy(conn, sockindex); + if(result) + return result; + } + + if(!ssl_prefs_check(conn->data)) + return CURLE_SSL_CONNECT_ERROR; + + /* mark this is being ssl requested from here on. */ + conn->ssl[sockindex].use = TRUE; + result = Curl_ssl->connect_nonblocking(conn, sockindex, done); + if(!result && *done) + Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */ + return result; +} + +/* + * Lock shared SSL session data + */ +void Curl_ssl_sessionid_lock(struct connectdata *conn) +{ + if(SSLSESSION_SHARED(conn->data)) + Curl_share_lock(conn->data, + CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); +} + +/* + * Unlock shared SSL session data + */ +void Curl_ssl_sessionid_unlock(struct connectdata *conn) +{ + if(SSLSESSION_SHARED(conn->data)) + Curl_share_unlock(conn->data, CURL_LOCK_DATA_SSL_SESSION); +} + +/* + * Check if there's a session ID for the given connection in the cache, and if + * there's one suitable, it is provided. Returns TRUE when no entry matched. + */ +bool Curl_ssl_getsessionid(struct connectdata *conn, + void **ssl_sessionid, + size_t *idsize, /* set 0 if unknown */ + int sockindex) +{ + struct curl_ssl_session *check; + struct Curl_easy *data = conn->data; + size_t i; + long *general_age; + bool no_match = TRUE; + + const bool isProxy = CONNECT_PROXY_SSL(); + struct ssl_primary_config * const ssl_config = isProxy ? + &conn->proxy_ssl_config : + &conn->ssl_config; + const char * const name = isProxy ? conn->http_proxy.host.name : + conn->host.name; + int port = isProxy ? (int)conn->port : conn->remote_port; + *ssl_sessionid = NULL; + + DEBUGASSERT(SSL_SET_OPTION(primary.sessionid)); + + if(!SSL_SET_OPTION(primary.sessionid)) + /* session ID re-use is disabled */ + return TRUE; + + /* Lock if shared */ + if(SSLSESSION_SHARED(data)) + general_age = &data->share->sessionage; + else + general_age = &data->state.sessionage; + + for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) { + check = &data->state.session[i]; + if(!check->sessionid) + /* not session ID means blank entry */ + continue; + if(strcasecompare(name, check->name) && + ((!conn->bits.conn_to_host && !check->conn_to_host) || + (conn->bits.conn_to_host && check->conn_to_host && + strcasecompare(conn->conn_to_host.name, check->conn_to_host))) && + ((!conn->bits.conn_to_port && check->conn_to_port == -1) || + (conn->bits.conn_to_port && check->conn_to_port != -1 && + conn->conn_to_port == check->conn_to_port)) && + (port == check->remote_port) && + strcasecompare(conn->handler->scheme, check->scheme) && + Curl_ssl_config_matches(ssl_config, &check->ssl_config)) { + /* yes, we have a session ID! */ + (*general_age)++; /* increase general age */ + check->age = *general_age; /* set this as used in this age */ + *ssl_sessionid = check->sessionid; + if(idsize) + *idsize = check->idsize; + no_match = FALSE; + break; + } + } + + return no_match; +} + +/* + * Kill a single session ID entry in the cache. + */ +void Curl_ssl_kill_session(struct curl_ssl_session *session) +{ + if(session->sessionid) { + /* defensive check */ + + /* free the ID the SSL-layer specific way */ + Curl_ssl->session_free(session->sessionid); + + session->sessionid = NULL; + session->age = 0; /* fresh */ + + Curl_free_primary_ssl_config(&session->ssl_config); + + Curl_safefree(session->name); + Curl_safefree(session->conn_to_host); + } +} + +/* + * Delete the given session ID from the cache. + */ +void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid) +{ + size_t i; + struct Curl_easy *data = conn->data; + + for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) { + struct curl_ssl_session *check = &data->state.session[i]; + + if(check->sessionid == ssl_sessionid) { + Curl_ssl_kill_session(check); + break; + } + } +} + +/* + * Store session id in the session cache. The ID passed on to this function + * must already have been extracted and allocated the proper way for the SSL + * layer. Curl_XXXX_session_free() will be called to free/kill the session ID + * later on. + */ +CURLcode Curl_ssl_addsessionid(struct connectdata *conn, + void *ssl_sessionid, + size_t idsize, + int sockindex) +{ + size_t i; + struct Curl_easy *data = conn->data; /* the mother of all structs */ + struct curl_ssl_session *store = &data->state.session[0]; + long oldest_age = data->state.session[0].age; /* zero if unused */ + char *clone_host; + char *clone_conn_to_host; + int conn_to_port; + long *general_age; + const bool isProxy = CONNECT_PROXY_SSL(); + struct ssl_primary_config * const ssl_config = isProxy ? + &conn->proxy_ssl_config : + &conn->ssl_config; + + DEBUGASSERT(SSL_SET_OPTION(primary.sessionid)); + + clone_host = strdup(isProxy ? conn->http_proxy.host.name : conn->host.name); + if(!clone_host) + return CURLE_OUT_OF_MEMORY; /* bail out */ + + if(conn->bits.conn_to_host) { + clone_conn_to_host = strdup(conn->conn_to_host.name); + if(!clone_conn_to_host) { + free(clone_host); + return CURLE_OUT_OF_MEMORY; /* bail out */ + } + } + else + clone_conn_to_host = NULL; + + if(conn->bits.conn_to_port) + conn_to_port = conn->conn_to_port; + else + conn_to_port = -1; + + /* Now we should add the session ID and the host name to the cache, (remove + the oldest if necessary) */ + + /* If using shared SSL session, lock! */ + if(SSLSESSION_SHARED(data)) { + general_age = &data->share->sessionage; + } + else { + general_age = &data->state.sessionage; + } + + /* find an empty slot for us, or find the oldest */ + for(i = 1; (i < data->set.general_ssl.max_ssl_sessions) && + data->state.session[i].sessionid; i++) { + if(data->state.session[i].age < oldest_age) { + oldest_age = data->state.session[i].age; + store = &data->state.session[i]; + } + } + if(i == data->set.general_ssl.max_ssl_sessions) + /* cache is full, we must "kill" the oldest entry! */ + Curl_ssl_kill_session(store); + else + store = &data->state.session[i]; /* use this slot */ + + /* now init the session struct wisely */ + store->sessionid = ssl_sessionid; + store->idsize = idsize; + store->age = *general_age; /* set current age */ + /* free it if there's one already present */ + free(store->name); + free(store->conn_to_host); + store->name = clone_host; /* clone host name */ + store->conn_to_host = clone_conn_to_host; /* clone connect to host name */ + store->conn_to_port = conn_to_port; /* connect to port number */ + /* port number */ + store->remote_port = isProxy ? (int)conn->port : conn->remote_port; + store->scheme = conn->handler->scheme; + + if(!Curl_clone_primary_ssl_config(ssl_config, &store->ssl_config)) { + store->sessionid = NULL; /* let caller free sessionid */ + free(clone_host); + free(clone_conn_to_host); + return CURLE_OUT_OF_MEMORY; + } + + return CURLE_OK; +} + + +void Curl_ssl_close_all(struct Curl_easy *data) +{ + /* kill the session ID cache if not shared */ + if(data->state.session && !SSLSESSION_SHARED(data)) { + size_t i; + for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) + /* the single-killer function handles empty table slots */ + Curl_ssl_kill_session(&data->state.session[i]); + + /* free the cache data */ + Curl_safefree(data->state.session); + } + + Curl_ssl->close_all(data); +} + +#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \ + defined(USE_SECTRANSP) || defined(USE_POLARSSL) || defined(USE_NSS) || \ + defined(USE_MBEDTLS) || defined(USE_WOLFSSL) +int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks) +{ + struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; + + if(!numsocks) + return GETSOCK_BLANK; + + if(connssl->connecting_state == ssl_connect_2_writing) { + /* write mode */ + socks[0] = conn->sock[FIRSTSOCKET]; + return GETSOCK_WRITESOCK(0); + } + if(connssl->connecting_state == ssl_connect_2_reading) { + /* read mode */ + socks[0] = conn->sock[FIRSTSOCKET]; + return GETSOCK_READSOCK(0); + } + + return GETSOCK_BLANK; +} +#else +int Curl_ssl_getsock(struct connectdata *conn, + curl_socket_t *socks, + int numsocks) +{ + (void)conn; + (void)socks; + (void)numsocks; + return GETSOCK_BLANK; +} +/* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_SECTRANSP || USE_NSS */ +#endif + +void Curl_ssl_close(struct connectdata *conn, int sockindex) +{ + DEBUGASSERT((sockindex <= 1) && (sockindex >= -1)); + Curl_ssl->close_one(conn, sockindex); +} + +CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex) +{ + if(Curl_ssl->shut_down(conn, sockindex)) + return CURLE_SSL_SHUTDOWN_FAILED; + + conn->ssl[sockindex].use = FALSE; /* get back to ordinary socket usage */ + conn->ssl[sockindex].state = ssl_connection_none; + + conn->recv[sockindex] = Curl_recv_plain; + conn->send[sockindex] = Curl_send_plain; + + return CURLE_OK; +} + +/* Selects an SSL crypto engine + */ +CURLcode Curl_ssl_set_engine(struct Curl_easy *data, const char *engine) +{ + return Curl_ssl->set_engine(data, engine); +} + +/* Selects the default SSL crypto engine + */ +CURLcode Curl_ssl_set_engine_default(struct Curl_easy *data) +{ + return Curl_ssl->set_engine_default(data); +} + +/* Return list of OpenSSL crypto engine names. */ +struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data) +{ + return Curl_ssl->engines_list(data); +} + +/* + * This sets up a session ID cache to the specified size. Make sure this code + * is agnostic to what underlying SSL technology we use. + */ +CURLcode Curl_ssl_initsessions(struct Curl_easy *data, size_t amount) +{ + struct curl_ssl_session *session; + + if(data->state.session) + /* this is just a precaution to prevent multiple inits */ + return CURLE_OK; + + session = calloc(amount, sizeof(struct curl_ssl_session)); + if(!session) + return CURLE_OUT_OF_MEMORY; + + /* store the info in the SSL section */ + data->set.general_ssl.max_ssl_sessions = amount; + data->state.session = session; + data->state.sessionage = 1; /* this is brand new */ + return CURLE_OK; +} + +static size_t Curl_multissl_version(char *buffer, size_t size); + +size_t Curl_ssl_version(char *buffer, size_t size) +{ +#ifdef CURL_WITH_MULTI_SSL + return Curl_multissl_version(buffer, size); +#else + return Curl_ssl->version(buffer, size); +#endif +} + +/* + * This function tries to determine connection status. + * + * Return codes: + * 1 means the connection is still in place + * 0 means the connection has been closed + * -1 means the connection status is unknown + */ +int Curl_ssl_check_cxn(struct connectdata *conn) +{ + return Curl_ssl->check_cxn(conn); +} + +bool Curl_ssl_data_pending(const struct connectdata *conn, + int connindex) +{ + return Curl_ssl->data_pending(conn, connindex); +} + +void Curl_ssl_free_certinfo(struct Curl_easy *data) +{ + struct curl_certinfo *ci = &data->info.certs; + + if(ci->num_of_certs) { + /* free all individual lists used */ + int i; + for(i = 0; inum_of_certs; i++) { + curl_slist_free_all(ci->certinfo[i]); + ci->certinfo[i] = NULL; + } + + free(ci->certinfo); /* free the actual array too */ + ci->certinfo = NULL; + ci->num_of_certs = 0; + } +} + +CURLcode Curl_ssl_init_certinfo(struct Curl_easy *data, int num) +{ + struct curl_certinfo *ci = &data->info.certs; + struct curl_slist **table; + + /* Free any previous certificate information structures */ + Curl_ssl_free_certinfo(data); + + /* Allocate the required certificate information structures */ + table = calloc((size_t) num, sizeof(struct curl_slist *)); + if(!table) + return CURLE_OUT_OF_MEMORY; + + ci->num_of_certs = num; + ci->certinfo = table; + + return CURLE_OK; +} + +/* + * 'value' is NOT a zero terminated string + */ +CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data, + int certnum, + const char *label, + const char *value, + size_t valuelen) +{ + struct curl_certinfo *ci = &data->info.certs; + char *output; + struct curl_slist *nl; + CURLcode result = CURLE_OK; + size_t labellen = strlen(label); + size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */ + + output = malloc(outlen); + if(!output) + return CURLE_OUT_OF_MEMORY; + + /* sprintf the label and colon */ + msnprintf(output, outlen, "%s:", label); + + /* memcpy the value (it might not be zero terminated) */ + memcpy(&output[labellen + 1], value, valuelen); + + /* zero terminate the output */ + output[labellen + 1 + valuelen] = 0; + + nl = Curl_slist_append_nodup(ci->certinfo[certnum], output); + if(!nl) { + free(output); + curl_slist_free_all(ci->certinfo[certnum]); + result = CURLE_OUT_OF_MEMORY; + } + + ci->certinfo[certnum] = nl; + return result; +} + +/* + * This is a convenience function for push_certinfo_len that takes a zero + * terminated value. + */ +CURLcode Curl_ssl_push_certinfo(struct Curl_easy *data, + int certnum, + const char *label, + const char *value) +{ + size_t valuelen = strlen(value); + + return Curl_ssl_push_certinfo_len(data, certnum, label, value, valuelen); +} + +CURLcode Curl_ssl_random(struct Curl_easy *data, + unsigned char *entropy, + size_t length) +{ + return Curl_ssl->random(data, entropy, length); +} + +/* + * Public key pem to der conversion + */ + +static CURLcode pubkey_pem_to_der(const char *pem, + unsigned char **der, size_t *der_len) +{ + char *stripped_pem, *begin_pos, *end_pos; + size_t pem_count, stripped_pem_count = 0, pem_len; + CURLcode result; + + /* if no pem, exit. */ + if(!pem) + return CURLE_BAD_CONTENT_ENCODING; + + begin_pos = strstr(pem, "-----BEGIN PUBLIC KEY-----"); + if(!begin_pos) + return CURLE_BAD_CONTENT_ENCODING; + + pem_count = begin_pos - pem; + /* Invalid if not at beginning AND not directly following \n */ + if(0 != pem_count && '\n' != pem[pem_count - 1]) + return CURLE_BAD_CONTENT_ENCODING; + + /* 26 is length of "-----BEGIN PUBLIC KEY-----" */ + pem_count += 26; + + /* Invalid if not directly following \n */ + end_pos = strstr(pem + pem_count, "\n-----END PUBLIC KEY-----"); + if(!end_pos) + return CURLE_BAD_CONTENT_ENCODING; + + pem_len = end_pos - pem; + + stripped_pem = malloc(pem_len - pem_count + 1); + if(!stripped_pem) + return CURLE_OUT_OF_MEMORY; + + /* + * Here we loop through the pem array one character at a time between the + * correct indices, and place each character that is not '\n' or '\r' + * into the stripped_pem array, which should represent the raw base64 string + */ + while(pem_count < pem_len) { + if('\n' != pem[pem_count] && '\r' != pem[pem_count]) + stripped_pem[stripped_pem_count++] = pem[pem_count]; + ++pem_count; + } + /* Place the null terminator in the correct place */ + stripped_pem[stripped_pem_count] = '\0'; + + result = Curl_base64_decode(stripped_pem, der, der_len); + + Curl_safefree(stripped_pem); + + return result; +} + +/* + * Generic pinned public key check. + */ + +CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data, + const char *pinnedpubkey, + const unsigned char *pubkey, size_t pubkeylen) +{ + FILE *fp; + unsigned char *buf = NULL, *pem_ptr = NULL; + CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + + /* if a path wasn't specified, don't pin */ + if(!pinnedpubkey) + return CURLE_OK; + if(!pubkey || !pubkeylen) + return result; + + /* only do this if pinnedpubkey starts with "sha256//", length 8 */ + if(strncmp(pinnedpubkey, "sha256//", 8) == 0) { + CURLcode encode; + size_t encodedlen, pinkeylen; + char *encoded, *pinkeycopy, *begin_pos, *end_pos; + unsigned char *sha256sumdigest; + + if(!Curl_ssl->sha256sum) { + /* without sha256 support, this cannot match */ + return result; + } + + /* compute sha256sum of public key */ + sha256sumdigest = malloc(CURL_SHA256_DIGEST_LENGTH); + if(!sha256sumdigest) + return CURLE_OUT_OF_MEMORY; + encode = Curl_ssl->sha256sum(pubkey, pubkeylen, + sha256sumdigest, CURL_SHA256_DIGEST_LENGTH); + + if(encode != CURLE_OK) + return encode; + + encode = Curl_base64_encode(data, (char *)sha256sumdigest, + CURL_SHA256_DIGEST_LENGTH, &encoded, + &encodedlen); + Curl_safefree(sha256sumdigest); + + if(encode) + return encode; + + infof(data, "\t public key hash: sha256//%s\n", encoded); + + /* it starts with sha256//, copy so we can modify it */ + pinkeylen = strlen(pinnedpubkey) + 1; + pinkeycopy = malloc(pinkeylen); + if(!pinkeycopy) { + Curl_safefree(encoded); + return CURLE_OUT_OF_MEMORY; + } + memcpy(pinkeycopy, pinnedpubkey, pinkeylen); + /* point begin_pos to the copy, and start extracting keys */ + begin_pos = pinkeycopy; + do { + end_pos = strstr(begin_pos, ";sha256//"); + /* + * if there is an end_pos, null terminate, + * otherwise it'll go to the end of the original string + */ + if(end_pos) + end_pos[0] = '\0'; + + /* compare base64 sha256 digests, 8 is the length of "sha256//" */ + if(encodedlen == strlen(begin_pos + 8) && + !memcmp(encoded, begin_pos + 8, encodedlen)) { + result = CURLE_OK; + break; + } + + /* + * change back the null-terminator we changed earlier, + * and look for next begin + */ + if(end_pos) { + end_pos[0] = ';'; + begin_pos = strstr(end_pos, "sha256//"); + } + } while(end_pos && begin_pos); + Curl_safefree(encoded); + Curl_safefree(pinkeycopy); + return result; + } + + fp = fopen(pinnedpubkey, "rb"); + if(!fp) + return result; + + do { + long filesize; + size_t size, pem_len; + CURLcode pem_read; + + /* Determine the file's size */ + if(fseek(fp, 0, SEEK_END)) + break; + filesize = ftell(fp); + if(fseek(fp, 0, SEEK_SET)) + break; + if(filesize < 0 || filesize > MAX_PINNED_PUBKEY_SIZE) + break; + + /* + * if the size of our certificate is bigger than the file + * size then it can't match + */ + size = curlx_sotouz((curl_off_t) filesize); + if(pubkeylen > size) + break; + + /* + * Allocate buffer for the pinned key + * With 1 additional byte for null terminator in case of PEM key + */ + buf = malloc(size + 1); + if(!buf) + break; + + /* Returns number of elements read, which should be 1 */ + if((int) fread(buf, size, 1, fp) != 1) + break; + + /* If the sizes are the same, it can't be base64 encoded, must be der */ + if(pubkeylen == size) { + if(!memcmp(pubkey, buf, pubkeylen)) + result = CURLE_OK; + break; + } + + /* + * Otherwise we will assume it's PEM and try to decode it + * after placing null terminator + */ + buf[size] = '\0'; + pem_read = pubkey_pem_to_der((const char *)buf, &pem_ptr, &pem_len); + /* if it wasn't read successfully, exit */ + if(pem_read) + break; + + /* + * if the size of our certificate doesn't match the size of + * the decoded file, they can't be the same, otherwise compare + */ + if(pubkeylen == pem_len && !memcmp(pubkey, pem_ptr, pubkeylen)) + result = CURLE_OK; + } while(0); + + Curl_safefree(buf); + Curl_safefree(pem_ptr); + fclose(fp); + + return result; +} + +#ifndef CURL_DISABLE_CRYPTO_AUTH +CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *md5sum, /* output */ + size_t md5len) +{ + return Curl_ssl->md5sum(tmp, tmplen, md5sum, md5len); +} +#endif + +/* + * Check whether the SSL backend supports the status_request extension. + */ +bool Curl_ssl_cert_status_request(void) +{ + return Curl_ssl->cert_status_request(); +} + +/* + * Check whether the SSL backend supports false start. + */ +bool Curl_ssl_false_start(void) +{ + return Curl_ssl->false_start(); +} + +/* + * Check whether the SSL backend supports setting TLS 1.3 cipher suites + */ +bool Curl_ssl_tls13_ciphersuites(void) +{ + return Curl_ssl->supports & SSLSUPP_TLS13_CIPHERSUITES; +} + +/* + * Default implementations for unsupported functions. + */ + +int Curl_none_init(void) +{ + return 1; +} + +void Curl_none_cleanup(void) +{ } + +int Curl_none_shutdown(struct connectdata *conn UNUSED_PARAM, + int sockindex UNUSED_PARAM) +{ + (void)conn; + (void)sockindex; + return 0; +} + +int Curl_none_check_cxn(struct connectdata *conn UNUSED_PARAM) +{ + (void)conn; + return -1; +} + +CURLcode Curl_none_random(struct Curl_easy *data UNUSED_PARAM, + unsigned char *entropy UNUSED_PARAM, + size_t length UNUSED_PARAM) +{ + (void)data; + (void)entropy; + (void)length; + return CURLE_NOT_BUILT_IN; +} + +void Curl_none_close_all(struct Curl_easy *data UNUSED_PARAM) +{ + (void)data; +} + +void Curl_none_session_free(void *ptr UNUSED_PARAM) +{ + (void)ptr; +} + +bool Curl_none_data_pending(const struct connectdata *conn UNUSED_PARAM, + int connindex UNUSED_PARAM) +{ + (void)conn; + (void)connindex; + return 0; +} + +bool Curl_none_cert_status_request(void) +{ + return FALSE; +} + +CURLcode Curl_none_set_engine(struct Curl_easy *data UNUSED_PARAM, + const char *engine UNUSED_PARAM) +{ + (void)data; + (void)engine; + return CURLE_NOT_BUILT_IN; +} + +CURLcode Curl_none_set_engine_default(struct Curl_easy *data UNUSED_PARAM) +{ + (void)data; + return CURLE_NOT_BUILT_IN; +} + +struct curl_slist *Curl_none_engines_list(struct Curl_easy *data UNUSED_PARAM) +{ + (void)data; + return (struct curl_slist *)NULL; +} + +bool Curl_none_false_start(void) +{ + return FALSE; +} + +#ifndef CURL_DISABLE_CRYPTO_AUTH +CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, + unsigned char *md5sum, size_t md5len UNUSED_PARAM) +{ + MD5_context *MD5pw; + + (void)md5len; + + MD5pw = Curl_MD5_init(Curl_DIGEST_MD5); + if(!MD5pw) + return CURLE_OUT_OF_MEMORY; + Curl_MD5_update(MD5pw, input, curlx_uztoui(inputlen)); + Curl_MD5_final(MD5pw, md5sum); + return CURLE_OK; +} +#else +CURLcode Curl_none_md5sum(unsigned char *input UNUSED_PARAM, + size_t inputlen UNUSED_PARAM, + unsigned char *md5sum UNUSED_PARAM, + size_t md5len UNUSED_PARAM) +{ + (void)input; + (void)inputlen; + (void)md5sum; + (void)md5len; + return CURLE_NOT_BUILT_IN; +} +#endif + +static int Curl_multissl_init(void) +{ + if(multissl_init(NULL)) + return 1; + return Curl_ssl->init(); +} + +static CURLcode Curl_multissl_connect(struct connectdata *conn, int sockindex) +{ + if(multissl_init(NULL)) + return CURLE_FAILED_INIT; + return Curl_ssl->connect_blocking(conn, sockindex); +} + +static CURLcode Curl_multissl_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + if(multissl_init(NULL)) + return CURLE_FAILED_INIT; + return Curl_ssl->connect_nonblocking(conn, sockindex, done); +} + +static void *Curl_multissl_get_internals(struct ssl_connect_data *connssl, + CURLINFO info) +{ + if(multissl_init(NULL)) + return NULL; + return Curl_ssl->get_internals(connssl, info); +} + +static void Curl_multissl_close(struct connectdata *conn, int sockindex) +{ + if(multissl_init(NULL)) + return; + Curl_ssl->close_one(conn, sockindex); +} + +static const struct Curl_ssl Curl_ssl_multi = { + { CURLSSLBACKEND_NONE, "multi" }, /* info */ + 0, /* supports nothing */ + (size_t)-1, /* something insanely large to be on the safe side */ + + Curl_multissl_init, /* init */ + Curl_none_cleanup, /* cleanup */ + Curl_multissl_version, /* version */ + Curl_none_check_cxn, /* check_cxn */ + Curl_none_shutdown, /* shutdown */ + Curl_none_data_pending, /* data_pending */ + Curl_none_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_multissl_connect, /* connect */ + Curl_multissl_connect_nonblocking, /* connect_nonblocking */ + Curl_multissl_get_internals, /* get_internals */ + Curl_multissl_close, /* close_one */ + Curl_none_close_all, /* close_all */ + Curl_none_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_none_md5sum, /* md5sum */ + NULL /* sha256sum */ +}; + +const struct Curl_ssl *Curl_ssl = +#if defined(CURL_WITH_MULTI_SSL) + &Curl_ssl_multi; +#elif defined(USE_WOLFSSL) + &Curl_ssl_wolfssl; +#elif defined(USE_SECTRANSP) + &Curl_ssl_sectransp; +#elif defined(USE_GNUTLS) + &Curl_ssl_gnutls; +#elif defined(USE_GSKIT) + &Curl_ssl_gskit; +#elif defined(USE_MBEDTLS) + &Curl_ssl_mbedtls; +#elif defined(USE_NSS) + &Curl_ssl_nss; +#elif defined(USE_OPENSSL) + &Curl_ssl_openssl; +#elif defined(USE_POLARSSL) + &Curl_ssl_polarssl; +#elif defined(USE_SCHANNEL) + &Curl_ssl_schannel; +#elif defined(USE_MESALINK) + &Curl_ssl_mesalink; +#elif defined(USE_BEARSSL) + &Curl_ssl_bearssl; +#else +#error "Missing struct Curl_ssl for selected SSL backend" +#endif + +static const struct Curl_ssl *available_backends[] = { +#if defined(USE_WOLFSSL) + &Curl_ssl_wolfssl, +#endif +#if defined(USE_SECTRANSP) + &Curl_ssl_sectransp, +#endif +#if defined(USE_GNUTLS) + &Curl_ssl_gnutls, +#endif +#if defined(USE_GSKIT) + &Curl_ssl_gskit, +#endif +#if defined(USE_MBEDTLS) + &Curl_ssl_mbedtls, +#endif +#if defined(USE_NSS) + &Curl_ssl_nss, +#endif +#if defined(USE_OPENSSL) + &Curl_ssl_openssl, +#endif +#if defined(USE_POLARSSL) + &Curl_ssl_polarssl, +#endif +#if defined(USE_SCHANNEL) + &Curl_ssl_schannel, +#endif +#if defined(USE_MESALINK) + &Curl_ssl_mesalink, +#endif +#if defined(USE_BEARSSL) + &Curl_ssl_bearssl, +#endif + NULL +}; + +static size_t Curl_multissl_version(char *buffer, size_t size) +{ + static const struct Curl_ssl *selected; + static char backends[200]; + static size_t total; + const struct Curl_ssl *current; + + current = Curl_ssl == &Curl_ssl_multi ? available_backends[0] : Curl_ssl; + + if(current != selected) { + char *p = backends; + char *end = backends + sizeof(backends); + int i; + + selected = current; + + for(i = 0; available_backends[i] && p < (end - 4); i++) { + if(i) + *(p++) = ' '; + if(selected != available_backends[i]) + *(p++) = '('; + p += available_backends[i]->version(p, end - p - 2); + if(selected != available_backends[i]) + *(p++) = ')'; + } + *p = '\0'; + total = p - backends; + } + + if(size > total) + memcpy(buffer, backends, total + 1); + else { + memcpy(buffer, backends, size - 1); + buffer[size - 1] = '\0'; + } + + return CURLMIN(size - 1, total); +} + +static int multissl_init(const struct Curl_ssl *backend) +{ + const char *env; + char *env_tmp; + + if(Curl_ssl != &Curl_ssl_multi) + return 1; + + if(backend) { + Curl_ssl = backend; + return 0; + } + + if(!available_backends[0]) + return 1; + + env = env_tmp = curl_getenv("CURL_SSL_BACKEND"); +#ifdef CURL_DEFAULT_SSL_BACKEND + if(!env) + env = CURL_DEFAULT_SSL_BACKEND; +#endif + if(env) { + int i; + for(i = 0; available_backends[i]; i++) { + if(strcasecompare(env, available_backends[i]->info.name)) { + Curl_ssl = available_backends[i]; + curl_free(env_tmp); + return 0; + } + } + } + + /* Fall back to first available backend */ + Curl_ssl = available_backends[0]; + curl_free(env_tmp); + return 0; +} + +CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, + const curl_ssl_backend ***avail) +{ + int i; + + if(avail) + *avail = (const curl_ssl_backend **)&available_backends; + + if(Curl_ssl != &Curl_ssl_multi) + return id == Curl_ssl->info.id || + (name && strcasecompare(name, Curl_ssl->info.name)) ? + CURLSSLSET_OK : +#if defined(CURL_WITH_MULTI_SSL) + CURLSSLSET_TOO_LATE; +#else + CURLSSLSET_UNKNOWN_BACKEND; +#endif + + for(i = 0; available_backends[i]; i++) { + if(available_backends[i]->info.id == id || + (name && strcasecompare(available_backends[i]->info.name, name))) { + multissl_init(available_backends[i]); + return CURLSSLSET_OK; + } + } + + return CURLSSLSET_UNKNOWN_BACKEND; +} + +#else /* USE_SSL */ +CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, + const curl_ssl_backend ***avail) +{ + (void)id; + (void)name; + (void)avail; + return CURLSSLSET_NO_BACKENDS; +} + +#endif /* !USE_SSL */ diff --git a/libcurl/lib/vtls/vtls.h b/libcurl/lib/vtls/vtls.h new file mode 100644 index 0000000..eae4ced --- /dev/null +++ b/libcurl/lib/vtls/vtls.h @@ -0,0 +1,279 @@ +#ifndef HEADER_CURL_VTLS_H +#define HEADER_CURL_VTLS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +struct connectdata; +struct ssl_connect_data; + +#define SSLSUPP_CA_PATH (1<<0) /* supports CAPATH */ +#define SSLSUPP_CERTINFO (1<<1) /* supports CURLOPT_CERTINFO */ +#define SSLSUPP_PINNEDPUBKEY (1<<2) /* supports CURLOPT_PINNEDPUBLICKEY */ +#define SSLSUPP_SSL_CTX (1<<3) /* supports CURLOPT_SSL_CTX */ +#define SSLSUPP_HTTPS_PROXY (1<<4) /* supports access via HTTPS proxies */ +#define SSLSUPP_TLS13_CIPHERSUITES (1<<5) /* supports TLS 1.3 ciphersuites */ + +struct Curl_ssl { + /* + * This *must* be the first entry to allow returning the list of available + * backends in curl_global_sslset(). + */ + curl_ssl_backend info; + unsigned int supports; /* bitfield, see above */ + size_t sizeof_ssl_backend_data; + + int (*init)(void); + void (*cleanup)(void); + + size_t (*version)(char *buffer, size_t size); + int (*check_cxn)(struct connectdata *cxn); + int (*shut_down)(struct connectdata *conn, int sockindex); + bool (*data_pending)(const struct connectdata *conn, + int connindex); + + /* return 0 if a find random is filled in */ + CURLcode (*random)(struct Curl_easy *data, unsigned char *entropy, + size_t length); + bool (*cert_status_request)(void); + + CURLcode (*connect_blocking)(struct connectdata *conn, int sockindex); + CURLcode (*connect_nonblocking)(struct connectdata *conn, int sockindex, + bool *done); + void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info); + void (*close_one)(struct connectdata *conn, int sockindex); + void (*close_all)(struct Curl_easy *data); + void (*session_free)(void *ptr); + + CURLcode (*set_engine)(struct Curl_easy *data, const char *engine); + CURLcode (*set_engine_default)(struct Curl_easy *data); + struct curl_slist *(*engines_list)(struct Curl_easy *data); + + bool (*false_start)(void); + + CURLcode (*md5sum)(unsigned char *input, size_t inputlen, + unsigned char *md5sum, size_t md5sumlen); + CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen, + unsigned char *sha256sum, size_t sha256sumlen); +}; + +#ifdef USE_SSL +extern const struct Curl_ssl *Curl_ssl; +#endif + +int Curl_none_init(void); +void Curl_none_cleanup(void); +int Curl_none_shutdown(struct connectdata *conn, int sockindex); +int Curl_none_check_cxn(struct connectdata *conn); +CURLcode Curl_none_random(struct Curl_easy *data, unsigned char *entropy, + size_t length); +void Curl_none_close_all(struct Curl_easy *data); +void Curl_none_session_free(void *ptr); +bool Curl_none_data_pending(const struct connectdata *conn, int connindex); +bool Curl_none_cert_status_request(void); +CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine); +CURLcode Curl_none_set_engine_default(struct Curl_easy *data); +struct curl_slist *Curl_none_engines_list(struct Curl_easy *data); +bool Curl_none_false_start(void); +bool Curl_ssl_tls13_ciphersuites(void); +CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, + unsigned char *md5sum, size_t md5len); + +#include "openssl.h" /* OpenSSL versions */ +#include "gtls.h" /* GnuTLS versions */ +#include "nssg.h" /* NSS versions */ +#include "gskit.h" /* Global Secure ToolKit versions */ +#include "polarssl.h" /* PolarSSL versions */ +#include "wolfssl.h" /* wolfSSL versions */ +#include "schannel.h" /* Schannel SSPI version */ +#include "sectransp.h" /* SecureTransport (Darwin) version */ +#include "mbedtls.h" /* mbedTLS versions */ +#include "mesalink.h" /* MesaLink versions */ +#include "bearssl.h" /* BearSSL versions */ + +#ifndef MAX_PINNED_PUBKEY_SIZE +#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */ +#endif + +#ifndef MD5_DIGEST_LENGTH +#ifndef LIBWOLFSSL_VERSION_HEX /* because WolfSSL borks this */ +#define MD5_DIGEST_LENGTH 16 /* fixed size */ +#endif +#endif + +#ifndef CURL_SHA256_DIGEST_LENGTH +#define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */ +#endif + +/* see https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-04 */ +#define ALPN_HTTP_1_1_LENGTH 8 +#define ALPN_HTTP_1_1 "http/1.1" + +/* set of helper macros for the backends to access the correct fields. For the + proxy or for the remote host - to properly support HTTPS proxy */ + +#define SSL_IS_PROXY() (CURLPROXY_HTTPS == conn->http_proxy.proxytype && \ + ssl_connection_complete != conn->proxy_ssl[conn->sock[SECONDARYSOCKET] == \ + CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state) +#define SSL_SET_OPTION(var) (SSL_IS_PROXY() ? data->set.proxy_ssl.var : \ + data->set.ssl.var) +#define SSL_CONN_CONFIG(var) (SSL_IS_PROXY() ? \ + conn->proxy_ssl_config.var : conn->ssl_config.var) + +bool Curl_ssl_config_matches(struct ssl_primary_config* data, + struct ssl_primary_config* needle); +bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source, + struct ssl_primary_config *dest); +void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc); +int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); + +int Curl_ssl_backend(void); + +#ifdef USE_SSL +int Curl_ssl_init(void); +void Curl_ssl_cleanup(void); +CURLcode Curl_ssl_connect(struct connectdata *conn, int sockindex); +CURLcode Curl_ssl_connect_nonblocking(struct connectdata *conn, + int sockindex, + bool *done); +/* tell the SSL stuff to close down all open information regarding + connections (and thus session ID caching etc) */ +void Curl_ssl_close_all(struct Curl_easy *data); +void Curl_ssl_close(struct connectdata *conn, int sockindex); +CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex); +CURLcode Curl_ssl_set_engine(struct Curl_easy *data, const char *engine); +/* Sets engine as default for all SSL operations */ +CURLcode Curl_ssl_set_engine_default(struct Curl_easy *data); +struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data); + +/* init the SSL session ID cache */ +CURLcode Curl_ssl_initsessions(struct Curl_easy *, size_t); +size_t Curl_ssl_version(char *buffer, size_t size); +bool Curl_ssl_data_pending(const struct connectdata *conn, + int connindex); +int Curl_ssl_check_cxn(struct connectdata *conn); + +/* Certificate information list handling. */ + +void Curl_ssl_free_certinfo(struct Curl_easy *data); +CURLcode Curl_ssl_init_certinfo(struct Curl_easy *data, int num); +CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data, int certnum, + const char *label, const char *value, + size_t valuelen); +CURLcode Curl_ssl_push_certinfo(struct Curl_easy *data, int certnum, + const char *label, const char *value); + +/* Functions to be used by SSL library adaptation functions */ + +/* Lock session cache mutex. + * Call this before calling other Curl_ssl_*session* functions + * Caller should unlock this mutex as soon as possible, as it may block + * other SSL connection from making progress. + * The purpose of explicitly locking SSL session cache data is to allow + * individual SSL engines to manage session lifetime in their specific way. + */ +void Curl_ssl_sessionid_lock(struct connectdata *conn); + +/* Unlock session cache mutex */ +void Curl_ssl_sessionid_unlock(struct connectdata *conn); + +/* extract a session ID + * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock). + * Caller must make sure that the ownership of returned sessionid object + * is properly taken (e.g. its refcount is incremented + * under sessionid mutex). + */ +bool Curl_ssl_getsessionid(struct connectdata *conn, + void **ssl_sessionid, + size_t *idsize, /* set 0 if unknown */ + int sockindex); +/* add a new session ID + * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock). + * Caller must ensure that it has properly shared ownership of this sessionid + * object with cache (e.g. incrementing refcount on success) + */ +CURLcode Curl_ssl_addsessionid(struct connectdata *conn, + void *ssl_sessionid, + size_t idsize, + int sockindex); +/* Kill a single session ID entry in the cache + * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock). + * This will call engine-specific curlssl_session_free function, which must + * take sessionid object ownership from sessionid cache + * (e.g. decrement refcount). + */ +void Curl_ssl_kill_session(struct curl_ssl_session *session); +/* delete a session from the cache + * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock). + * This will call engine-specific curlssl_session_free function, which must + * take sessionid object ownership from sessionid cache + * (e.g. decrement refcount). + */ +void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid); + +/* get N random bytes into the buffer */ +CURLcode Curl_ssl_random(struct Curl_easy *data, unsigned char *buffer, + size_t length); +CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *md5sum, /* output */ + size_t md5len); +/* Check pinned public key. */ +CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data, + const char *pinnedpubkey, + const unsigned char *pubkey, size_t pubkeylen); + +bool Curl_ssl_cert_status_request(void); + +bool Curl_ssl_false_start(void); + +#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */ + +#else /* if not USE_SSL */ + +/* When SSL support is not present, just define away these function calls */ +#define Curl_ssl_init() 1 +#define Curl_ssl_cleanup() Curl_nop_stmt +#define Curl_ssl_connect(x,y) CURLE_NOT_BUILT_IN +#define Curl_ssl_close_all(x) Curl_nop_stmt +#define Curl_ssl_close(x,y) Curl_nop_stmt +#define Curl_ssl_shutdown(x,y) CURLE_NOT_BUILT_IN +#define Curl_ssl_set_engine(x,y) CURLE_NOT_BUILT_IN +#define Curl_ssl_set_engine_default(x) CURLE_NOT_BUILT_IN +#define Curl_ssl_engines_list(x) NULL +#define Curl_ssl_send(a,b,c,d,e) -1 +#define Curl_ssl_recv(a,b,c,d,e) -1 +#define Curl_ssl_initsessions(x,y) CURLE_OK +#define Curl_ssl_version(x,y) 0 +#define Curl_ssl_data_pending(x,y) 0 +#define Curl_ssl_check_cxn(x) 0 +#define Curl_ssl_free_certinfo(x) Curl_nop_stmt +#define Curl_ssl_connect_nonblocking(x,y,z) CURLE_NOT_BUILT_IN +#define Curl_ssl_kill_session(x) Curl_nop_stmt +#define Curl_ssl_random(x,y,z) ((void)x, CURLE_NOT_BUILT_IN) +#define Curl_ssl_cert_status_request() FALSE +#define Curl_ssl_false_start() FALSE +#define Curl_ssl_tls13_ciphersuites() FALSE +#endif + +#endif /* HEADER_CURL_VTLS_H */ diff --git a/libcurl/lib/vtls/wolfssl.c b/libcurl/lib/vtls/wolfssl.c new file mode 100644 index 0000000..890bcbf --- /dev/null +++ b/libcurl/lib/vtls/wolfssl.c @@ -0,0 +1,991 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for all wolfSSL specific code for the TLS/SSL layer. No code + * but vtls.c should ever call or use these functions. + * + */ + +#include "curl_setup.h" + +#ifdef USE_WOLFSSL + +#define WOLFSSL_OPTIONS_IGNORE_SYS +#include +#include + +/* To determine what functions are available we rely on one or both of: + - the user's options.h generated by wolfSSL + - the symbols detected by curl's configure + Since they are markedly different from one another, and one or the other may + not be available, we do some checking below to bring things in sync. */ + +/* HAVE_ALPN is wolfSSL's build time symbol for enabling ALPN in options.h. */ +#ifndef HAVE_ALPN +#ifdef HAVE_WOLFSSL_USEALPN +#define HAVE_ALPN +#endif +#endif + +/* WOLFSSL_ALLOW_SSLV3 is wolfSSL's build time symbol for enabling SSLv3 in + options.h, but is only seen in >= 3.6.6 since that's when they started + disabling SSLv3 by default. */ +#ifndef WOLFSSL_ALLOW_SSLV3 +#if (LIBWOLFSSL_VERSION_HEX < 0x03006006) || \ + defined(HAVE_WOLFSSLV3_CLIENT_METHOD) +#define WOLFSSL_ALLOW_SSLV3 +#endif +#endif + +#include + +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "vtls.h" +#include "parsedate.h" +#include "connect.h" /* for the connect timeout */ +#include "select.h" +#include "strcase.h" +#include "x509asn1.h" +#include "curl_printf.h" +#include "multiif.h" + +#include +#include +#include +#include "wolfssl.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +/* KEEP_PEER_CERT is a product of the presence of build time symbol + OPENSSL_EXTRA without NO_CERTS, depending on the version. KEEP_PEER_CERT is + in wolfSSL's settings.h, and the latter two are build time symbols in + options.h. */ +#ifndef KEEP_PEER_CERT +#if defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \ + (defined(OPENSSL_EXTRA) && !defined(NO_CERTS)) +#define KEEP_PEER_CERT +#endif +#endif + +struct ssl_backend_data { + SSL_CTX* ctx; + SSL* handle; +}; + +#define BACKEND connssl->backend + +static Curl_recv wolfssl_recv; +static Curl_send wolfssl_send; + + +static int do_file_type(const char *type) +{ + if(!type || !type[0]) + return SSL_FILETYPE_PEM; + if(strcasecompare(type, "PEM")) + return SSL_FILETYPE_PEM; + if(strcasecompare(type, "DER")) + return SSL_FILETYPE_ASN1; + return -1; +} + +/* + * This function loads all the client/CA certificates and CRLs. Setup the TLS + * layer and do all necessary magic. + */ +static CURLcode +wolfssl_connect_step1(struct connectdata *conn, + int sockindex) +{ + char *ciphers; + struct Curl_easy *data = conn->data; + struct ssl_connect_data* connssl = &conn->ssl[sockindex]; + SSL_METHOD* req_method = NULL; + curl_socket_t sockfd = conn->sock[sockindex]; +#ifdef HAVE_SNI + bool sni = FALSE; +#define use_sni(x) sni = (x) +#else +#define use_sni(x) Curl_nop_stmt +#endif + + if(connssl->state == ssl_connection_complete) + return CURLE_OK; + + if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) { + failf(data, "wolfSSL does not support to set maximum SSL/TLS version"); + return CURLE_SSL_CONNECT_ERROR; + } + + /* check to see if we've been told to use an explicit SSL/TLS version */ + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: +#if LIBWOLFSSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */ + /* minimum protocol version is set later after the CTX object is created */ + req_method = SSLv23_client_method(); +#else + infof(data, "wolfSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, " + "TLS 1.0 is used exclusively\n"); + req_method = TLSv1_client_method(); +#endif + use_sni(TRUE); + break; + case CURL_SSLVERSION_TLSv1_0: +#ifdef WOLFSSL_ALLOW_TLSV10 + req_method = TLSv1_client_method(); + use_sni(TRUE); +#else + failf(data, "wolfSSL does not support TLS 1.0"); + return CURLE_NOT_BUILT_IN; +#endif + break; + case CURL_SSLVERSION_TLSv1_1: + req_method = TLSv1_1_client_method(); + use_sni(TRUE); + break; + case CURL_SSLVERSION_TLSv1_2: + req_method = TLSv1_2_client_method(); + use_sni(TRUE); + break; + case CURL_SSLVERSION_TLSv1_3: +#ifdef WOLFSSL_TLS13 + req_method = wolfTLSv1_3_client_method(); + use_sni(TRUE); + break; +#else + failf(data, "wolfSSL: TLS 1.3 is not yet supported"); + return CURLE_SSL_CONNECT_ERROR; +#endif + case CURL_SSLVERSION_SSLv3: +#ifdef WOLFSSL_ALLOW_SSLV3 + req_method = SSLv3_client_method(); + use_sni(FALSE); +#else + failf(data, "wolfSSL does not support SSLv3"); + return CURLE_NOT_BUILT_IN; +#endif + break; + case CURL_SSLVERSION_SSLv2: + failf(data, "wolfSSL does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + if(!req_method) { + failf(data, "SSL: couldn't create a method!"); + return CURLE_OUT_OF_MEMORY; + } + + if(BACKEND->ctx) + SSL_CTX_free(BACKEND->ctx); + BACKEND->ctx = SSL_CTX_new(req_method); + + if(!BACKEND->ctx) { + failf(data, "SSL: couldn't create a context!"); + return CURLE_OUT_OF_MEMORY; + } + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: +#if LIBWOLFSSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */ + /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is + * whatever minimum version of TLS was built in and at least TLS 1.0. For + * later library versions that could change (eg TLS 1.0 built in but + * defaults to TLS 1.1) so we have this short circuit evaluation to find + * the minimum supported TLS version. + */ + if((wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1) != 1) && + (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_1) != 1) && + (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_2) != 1) +#ifdef WOLFSSL_TLS13 + && (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_3) != 1) +#endif + ) { + failf(data, "SSL: couldn't set the minimum protocol version"); + return CURLE_SSL_CONNECT_ERROR; + } +#endif + break; + } + + ciphers = SSL_CONN_CONFIG(cipher_list); + if(ciphers) { + if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) { + failf(data, "failed setting cipher list: %s", ciphers); + return CURLE_SSL_CIPHER; + } + infof(data, "Cipher selection: %s\n", ciphers); + } + +#ifndef NO_FILESYSTEM + /* load trusted cacert */ + if(SSL_CONN_CONFIG(CAfile)) { + if(1 != SSL_CTX_load_verify_locations(BACKEND->ctx, + SSL_CONN_CONFIG(CAfile), + SSL_CONN_CONFIG(CApath))) { + if(SSL_CONN_CONFIG(verifypeer)) { + /* Fail if we insist on successfully verifying the server. */ + failf(data, "error setting certificate verify locations:\n" + " CAfile: %s\n CApath: %s", + SSL_CONN_CONFIG(CAfile)? + SSL_CONN_CONFIG(CAfile): "none", + SSL_CONN_CONFIG(CApath)? + SSL_CONN_CONFIG(CApath) : "none"); + return CURLE_SSL_CACERT_BADFILE; + } + else { + /* Just continue with a warning if no strict certificate + verification is required. */ + infof(data, "error setting certificate verify locations," + " continuing anyway:\n"); + } + } + else { + /* Everything is fine. */ + infof(data, "successfully set certificate verify locations:\n"); + } + infof(data, + " CAfile: %s\n" + " CApath: %s\n", + SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile): + "none", + SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath): + "none"); + } + + /* Load the client certificate, and private key */ + if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) { + int file_type = do_file_type(SSL_SET_OPTION(cert_type)); + + if(SSL_CTX_use_certificate_file(BACKEND->ctx, SSL_SET_OPTION(cert), + file_type) != 1) { + failf(data, "unable to use client certificate (no key or wrong pass" + " phrase?)"); + return CURLE_SSL_CONNECT_ERROR; + } + + file_type = do_file_type(SSL_SET_OPTION(key_type)); + if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key), + file_type) != 1) { + failf(data, "unable to set private key"); + return CURLE_SSL_CONNECT_ERROR; + } + } +#endif /* !NO_FILESYSTEM */ + + /* SSL always tries to verify the peer, this only says whether it should + * fail to connect if the verification fails, or if it should continue + * anyway. In the latter case the result of the verification is checked with + * SSL_get_verify_result() below. */ + SSL_CTX_set_verify(BACKEND->ctx, + SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER: + SSL_VERIFY_NONE, + NULL); + +#ifdef HAVE_SNI + if(sni) { + struct in_addr addr4; +#ifdef ENABLE_IPV6 + struct in6_addr addr6; +#endif + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + size_t hostname_len = strlen(hostname); + if((hostname_len < USHRT_MAX) && + (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) && +#ifdef ENABLE_IPV6 + (0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) && +#endif + (wolfSSL_CTX_UseSNI(BACKEND->ctx, WOLFSSL_SNI_HOST_NAME, hostname, + (unsigned short)hostname_len) != 1)) { + infof(data, "WARNING: failed to configure server name indication (SNI) " + "TLS extension\n"); + } + } +#endif + + /* give application a chance to interfere with SSL set up. */ + if(data->set.ssl.fsslctx) { + CURLcode result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx, + data->set.ssl.fsslctxp); + if(result) { + failf(data, "error signaled by ssl ctx callback"); + return result; + } + } +#ifdef NO_FILESYSTEM + else if(SSL_CONN_CONFIG(verifypeer)) { + failf(data, "SSL: Certificates can't be loaded because wolfSSL was built" + " with \"no filesystem\". Either disable peer verification" + " (insecure) or if you are building an application with libcurl you" + " can load certificates via CURLOPT_SSL_CTX_FUNCTION."); + return CURLE_SSL_CONNECT_ERROR; + } +#endif + + /* Let's make an SSL structure */ + if(BACKEND->handle) + SSL_free(BACKEND->handle); + BACKEND->handle = SSL_new(BACKEND->ctx); + if(!BACKEND->handle) { + failf(data, "SSL: couldn't create a context (handle)!"); + return CURLE_OUT_OF_MEMORY; + } + +#ifdef HAVE_ALPN + if(conn->bits.tls_enable_alpn) { + char protocols[128]; + *protocols = '\0'; + + /* wolfSSL's ALPN protocol name list format is a comma separated string of + protocols in descending order of preference, eg: "h2,http/1.1" */ + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2) { + strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ","); + infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1); + infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + + if(wolfSSL_UseALPN(BACKEND->handle, protocols, + (unsigned)strlen(protocols), + WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) { + failf(data, "SSL: failed setting ALPN protocols"); + return CURLE_SSL_CONNECT_ERROR; + } + } +#endif /* HAVE_ALPN */ + + /* Check if there's a cached ID we can/should use here! */ + if(SSL_SET_OPTION(primary.sessionid)) { + void *ssl_sessionid = NULL; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { + /* we got a session id, use it! */ + if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) { + char error_buffer[WOLFSSL_MAX_ERROR_SZ]; + Curl_ssl_sessionid_unlock(conn); + failf(data, "SSL: SSL_set_session failed: %s", + ERR_error_string(SSL_get_error(BACKEND->handle, 0), + error_buffer)); + return CURLE_SSL_CONNECT_ERROR; + } + /* Informational message */ + infof(data, "SSL re-using session ID\n"); + } + Curl_ssl_sessionid_unlock(conn); + } + + /* pass the raw socket into the SSL layer */ + if(!SSL_set_fd(BACKEND->handle, (int)sockfd)) { + failf(data, "SSL: SSL_set_fd failed"); + return CURLE_SSL_CONNECT_ERROR; + } + + connssl->connecting_state = ssl_connect_2; + return CURLE_OK; +} + + +static CURLcode +wolfssl_connect_step2(struct connectdata *conn, + int sockindex) +{ + int ret = -1; + struct Curl_easy *data = conn->data; + struct ssl_connect_data* connssl = &conn->ssl[sockindex]; + const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const char * const dispname = SSL_IS_PROXY() ? + conn->http_proxy.host.dispname : conn->host.dispname; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + + conn->recv[sockindex] = wolfssl_recv; + conn->send[sockindex] = wolfssl_send; + + /* Enable RFC2818 checks */ + if(SSL_CONN_CONFIG(verifyhost)) { + ret = wolfSSL_check_domain_name(BACKEND->handle, hostname); + if(ret == SSL_FAILURE) + return CURLE_OUT_OF_MEMORY; + } + + ret = SSL_connect(BACKEND->handle); + if(ret != 1) { + char error_buffer[WOLFSSL_MAX_ERROR_SZ]; + int detail = SSL_get_error(BACKEND->handle, ret); + + if(SSL_ERROR_WANT_READ == detail) { + connssl->connecting_state = ssl_connect_2_reading; + return CURLE_OK; + } + else if(SSL_ERROR_WANT_WRITE == detail) { + connssl->connecting_state = ssl_connect_2_writing; + return CURLE_OK; + } + /* There is no easy way to override only the CN matching. + * This will enable the override of both mismatching SubjectAltNames + * as also mismatching CN fields */ + else if(DOMAIN_NAME_MISMATCH == detail) { +#if 1 + failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n", + dispname); + return CURLE_PEER_FAILED_VERIFICATION; +#else + /* When the wolfssl_check_domain_name() is used and you desire to + * continue on a DOMAIN_NAME_MISMATCH, i.e. 'conn->ssl_config.verifyhost + * == 0', CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA + * error. The only way to do this is currently to switch the + * Wolfssl_check_domain_name() in and out based on the + * 'conn->ssl_config.verifyhost' value. */ + if(SSL_CONN_CONFIG(verifyhost)) { + failf(data, + "\tsubject alt name(s) or common name do not match \"%s\"\n", + dispname); + return CURLE_PEER_FAILED_VERIFICATION; + } + else { + infof(data, + "\tsubject alt name(s) and/or common name do not match \"%s\"\n", + dispname); + return CURLE_OK; + } +#endif + } +#if LIBWOLFSSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */ + else if(ASN_NO_SIGNER_E == detail) { + if(SSL_CONN_CONFIG(verifypeer)) { + failf(data, "\tCA signer not available for verification\n"); + return CURLE_SSL_CACERT_BADFILE; + } + else { + /* Just continue with a warning if no strict certificate + verification is required. */ + infof(data, "CA signer not available for verification, " + "continuing anyway\n"); + } + } +#endif + else { + failf(data, "SSL_connect failed with error %d: %s", detail, + ERR_error_string(detail, error_buffer)); + return CURLE_SSL_CONNECT_ERROR; + } + } + + if(pinnedpubkey) { +#ifdef KEEP_PEER_CERT + X509 *x509; + const char *x509_der; + int x509_der_len; + curl_X509certificate x509_parsed; + curl_asn1Element *pubkey; + CURLcode result; + + x509 = SSL_get_peer_certificate(BACKEND->handle); + if(!x509) { + failf(data, "SSL: failed retrieving server certificate"); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + x509_der = (const char *)wolfSSL_X509_get_der(x509, &x509_der_len); + if(!x509_der) { + failf(data, "SSL: failed retrieving ASN.1 server certificate"); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + memset(&x509_parsed, 0, sizeof(x509_parsed)); + if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len)) + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + + pubkey = &x509_parsed.subjectPublicKeyInfo; + if(!pubkey->header || pubkey->end <= pubkey->header) { + failf(data, "SSL: failed retrieving public key from server certificate"); + return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + } + + result = Curl_pin_peer_pubkey(data, + pinnedpubkey, + (const unsigned char *)pubkey->header, + (size_t)(pubkey->end - pubkey->header)); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + return result; + } +#else + failf(data, "Library lacks pinning support built-in"); + return CURLE_NOT_BUILT_IN; +#endif + } + +#ifdef HAVE_ALPN + if(conn->bits.tls_enable_alpn) { + int rc; + char *protocol = NULL; + unsigned short protocol_len = 0; + + rc = wolfSSL_ALPN_GetProtocol(BACKEND->handle, &protocol, &protocol_len); + + if(rc == SSL_SUCCESS) { + infof(data, "ALPN, server accepted to use %.*s\n", protocol_len, + protocol); + + if(protocol_len == ALPN_HTTP_1_1_LENGTH && + !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) + conn->negnpn = CURL_HTTP_VERSION_1_1; +#ifdef USE_NGHTTP2 + else if(data->set.httpversion >= CURL_HTTP_VERSION_2 && + protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN && + !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID, + NGHTTP2_PROTO_VERSION_ID_LEN)) + conn->negnpn = CURL_HTTP_VERSION_2; +#endif + else + infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len, + protocol); + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + } + else if(rc == SSL_ALPN_NOT_FOUND) + infof(data, "ALPN, server did not agree to a protocol\n"); + else { + failf(data, "ALPN, failure getting protocol, error %d", rc); + return CURLE_SSL_CONNECT_ERROR; + } + } +#endif /* HAVE_ALPN */ + + connssl->connecting_state = ssl_connect_3; +#if (LIBWOLFSSL_VERSION_HEX >= 0x03009010) + infof(data, "SSL connection using %s / %s\n", + wolfSSL_get_version(BACKEND->handle), + wolfSSL_get_cipher_name(BACKEND->handle)); +#else + infof(data, "SSL connected\n"); +#endif + + return CURLE_OK; +} + + +static CURLcode +wolfssl_connect_step3(struct connectdata *conn, + int sockindex) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); + + if(SSL_SET_OPTION(primary.sessionid)) { + bool incache; + SSL_SESSION *our_ssl_sessionid; + void *old_ssl_sessionid = NULL; + + our_ssl_sessionid = SSL_get_session(BACKEND->handle); + + Curl_ssl_sessionid_lock(conn); + incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, + sockindex)); + if(incache) { + if(old_ssl_sessionid != our_ssl_sessionid) { + infof(data, "old SSL session ID is stale, removing\n"); + Curl_ssl_delsessionid(conn, old_ssl_sessionid); + incache = FALSE; + } + } + + if(!incache) { + result = Curl_ssl_addsessionid(conn, our_ssl_sessionid, + 0 /* unknown size */, sockindex); + if(result) { + Curl_ssl_sessionid_unlock(conn); + failf(data, "failed to store ssl session"); + return result; + } + } + Curl_ssl_sessionid_unlock(conn); + } + + connssl->connecting_state = ssl_connect_done; + + return result; +} + + +static ssize_t wolfssl_send(struct connectdata *conn, + int sockindex, + const void *mem, + size_t len, + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + char error_buffer[WOLFSSL_MAX_ERROR_SZ]; + int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; + int rc = SSL_write(BACKEND->handle, mem, memlen); + + if(rc < 0) { + int err = SSL_get_error(BACKEND->handle, rc); + + switch(err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /* there's data pending, re-invoke SSL_write() */ + *curlcode = CURLE_AGAIN; + return -1; + default: + failf(conn->data, "SSL write: %s, errno %d", + ERR_error_string(err, error_buffer), + SOCKERRNO); + *curlcode = CURLE_SEND_ERROR; + return -1; + } + } + return rc; +} + +static void Curl_wolfssl_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + if(BACKEND->handle) { + (void)SSL_shutdown(BACKEND->handle); + SSL_free(BACKEND->handle); + BACKEND->handle = NULL; + } + if(BACKEND->ctx) { + SSL_CTX_free(BACKEND->ctx); + BACKEND->ctx = NULL; + } +} + +static ssize_t wolfssl_recv(struct connectdata *conn, + int num, + char *buf, + size_t buffersize, + CURLcode *curlcode) +{ + struct ssl_connect_data *connssl = &conn->ssl[num]; + char error_buffer[WOLFSSL_MAX_ERROR_SZ]; + int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; + int nread = SSL_read(BACKEND->handle, buf, buffsize); + + if(nread < 0) { + int err = SSL_get_error(BACKEND->handle, nread); + + switch(err) { + case SSL_ERROR_ZERO_RETURN: /* no more data */ + break; + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + /* there's data pending, re-invoke SSL_read() */ + *curlcode = CURLE_AGAIN; + return -1; + default: + failf(conn->data, "SSL read: %s, errno %d", + ERR_error_string(err, error_buffer), + SOCKERRNO); + *curlcode = CURLE_RECV_ERROR; + return -1; + } + } + return nread; +} + + +static void Curl_wolfssl_session_free(void *ptr) +{ + (void)ptr; + /* wolfSSL reuses sessions on own, no free */ +} + + +static size_t Curl_wolfssl_version(char *buffer, size_t size) +{ +#if LIBWOLFSSL_VERSION_HEX >= 0x03006000 + return msnprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version()); +#elif defined(WOLFSSL_VERSION) + return msnprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION); +#endif +} + + +static int Curl_wolfssl_init(void) +{ + return (wolfSSL_Init() == SSL_SUCCESS); +} + + +static void Curl_wolfssl_cleanup(void) +{ + wolfSSL_Cleanup(); +} + + +static bool Curl_wolfssl_data_pending(const struct connectdata* conn, + int connindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[connindex]; + if(BACKEND->handle) /* SSL is in use */ + return (0 != SSL_pending(BACKEND->handle)) ? TRUE : FALSE; + else + return FALSE; +} + + +/* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) + */ +static int Curl_wolfssl_shutdown(struct connectdata *conn, int sockindex) +{ + int retval = 0; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + + if(BACKEND->handle) { + SSL_free(BACKEND->handle); + BACKEND->handle = NULL; + } + return retval; +} + + +static CURLcode +wolfssl_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + time_t timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + /* Find out how much more time we're allowed */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + result = wolfssl_connect_step1(conn, sockindex); + if(result) + return result; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(connssl->connecting_state == ssl_connect_2_reading + || connssl->connecting_state == ssl_connect_2_writing) { + + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking?0:timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if + * this connection is part of a multi handle and this loop would + * execute again. This permits the owner of a multi handle to + * abort a connection attempt before step2 has completed while + * ensuring that a client using select() or epoll() will always + * have a valid fdset to wait on. + */ + result = wolfssl_connect_step2(conn, sockindex); + if(result || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return result; + } /* repeat step2 until all transactions are done. */ + + if(ssl_connect_3 == connssl->connecting_state) { + result = wolfssl_connect_step3(conn, sockindex); + if(result) + return result; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = wolfssl_recv; + conn->send[sockindex] = wolfssl_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + + +static CURLcode Curl_wolfssl_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + return wolfssl_connect_common(conn, sockindex, TRUE, done); +} + + +static CURLcode Curl_wolfssl_connect(struct connectdata *conn, int sockindex) +{ + CURLcode result; + bool done = FALSE; + + result = wolfssl_connect_common(conn, sockindex, FALSE, &done); + if(result) + return result; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +static CURLcode Curl_wolfssl_random(struct Curl_easy *data, + unsigned char *entropy, size_t length) +{ + RNG rng; + (void)data; + if(wc_InitRng(&rng)) + return CURLE_FAILED_INIT; + if(length > UINT_MAX) + return CURLE_FAILED_INIT; + if(wc_RNG_GenerateBlock(&rng, entropy, (unsigned)length)) + return CURLE_FAILED_INIT; + if(wc_FreeRng(&rng)) + return CURLE_FAILED_INIT; + return CURLE_OK; +} + +static CURLcode Curl_wolfssl_sha256sum(const unsigned char *tmp, /* input */ + size_t tmplen, + unsigned char *sha256sum /* output */, + size_t unused) +{ + Sha256 SHA256pw; + (void)unused; + wc_InitSha256(&SHA256pw); + wc_Sha256Update(&SHA256pw, tmp, (word32)tmplen); + wc_Sha256Final(&SHA256pw, sha256sum); + return CURLE_OK; +} + +static void *Curl_wolfssl_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + (void)info; + return BACKEND->handle; +} + +const struct Curl_ssl Curl_ssl_wolfssl = { + { CURLSSLBACKEND_WOLFSSL, "WolfSSL" }, /* info */ + +#ifdef KEEP_PEER_CERT + SSLSUPP_PINNEDPUBKEY | +#endif + SSLSUPP_SSL_CTX, + + sizeof(struct ssl_backend_data), + + Curl_wolfssl_init, /* init */ + Curl_wolfssl_cleanup, /* cleanup */ + Curl_wolfssl_version, /* version */ + Curl_none_check_cxn, /* check_cxn */ + Curl_wolfssl_shutdown, /* shutdown */ + Curl_wolfssl_data_pending, /* data_pending */ + Curl_wolfssl_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + Curl_wolfssl_connect, /* connect */ + Curl_wolfssl_connect_nonblocking, /* connect_nonblocking */ + Curl_wolfssl_get_internals, /* get_internals */ + Curl_wolfssl_close, /* close_one */ + Curl_none_close_all, /* close_all */ + Curl_wolfssl_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + Curl_none_md5sum, /* md5sum */ + Curl_wolfssl_sha256sum /* sha256sum */ +}; + +#endif diff --git a/libcurl/lib/vtls/wolfssl.h b/libcurl/lib/vtls/wolfssl.h new file mode 100644 index 0000000..2b9673c --- /dev/null +++ b/libcurl/lib/vtls/wolfssl.h @@ -0,0 +1,31 @@ +#ifndef HEADER_CURL_WOLFSSL_H +#define HEADER_CURL_WOLFSSL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_WOLFSSL + +extern const struct Curl_ssl Curl_ssl_wolfssl; + +#endif /* USE_WOLFSSL */ +#endif /* HEADER_CURL_WOLFSSL_H */ diff --git a/libcurl/lib/warnless.c b/libcurl/lib/warnless.c new file mode 100644 index 0000000..cfd5e8e --- /dev/null +++ b/libcurl/lib/warnless.c @@ -0,0 +1,508 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(__INTEL_COMPILER) && defined(__unix__) + +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif + +#endif /* __INTEL_COMPILER && __unix__ */ + +#define BUILDING_WARNLESS_C 1 + +#include "warnless.h" + +#define CURL_MASK_SCHAR 0x7F +#define CURL_MASK_UCHAR 0xFF + +#if (SIZEOF_SHORT == 2) +# define CURL_MASK_SSHORT 0x7FFF +# define CURL_MASK_USHORT 0xFFFF +#elif (SIZEOF_SHORT == 4) +# define CURL_MASK_SSHORT 0x7FFFFFFF +# define CURL_MASK_USHORT 0xFFFFFFFF +#elif (SIZEOF_SHORT == 8) +# define CURL_MASK_SSHORT 0x7FFFFFFFFFFFFFFF +# define CURL_MASK_USHORT 0xFFFFFFFFFFFFFFFF +#else +# error "SIZEOF_SHORT not defined" +#endif + +#if (SIZEOF_INT == 2) +# define CURL_MASK_SINT 0x7FFF +# define CURL_MASK_UINT 0xFFFF +#elif (SIZEOF_INT == 4) +# define CURL_MASK_SINT 0x7FFFFFFF +# define CURL_MASK_UINT 0xFFFFFFFF +#elif (SIZEOF_INT == 8) +# define CURL_MASK_SINT 0x7FFFFFFFFFFFFFFF +# define CURL_MASK_UINT 0xFFFFFFFFFFFFFFFF +#elif (SIZEOF_INT == 16) +# define CURL_MASK_SINT 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +# define CURL_MASK_UINT 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +#else +# error "SIZEOF_INT not defined" +#endif + +#if (SIZEOF_LONG == 2) +# define CURL_MASK_SLONG 0x7FFFL +# define CURL_MASK_ULONG 0xFFFFUL +#elif (SIZEOF_LONG == 4) +# define CURL_MASK_SLONG 0x7FFFFFFFL +# define CURL_MASK_ULONG 0xFFFFFFFFUL +#elif (SIZEOF_LONG == 8) +# define CURL_MASK_SLONG 0x7FFFFFFFFFFFFFFFL +# define CURL_MASK_ULONG 0xFFFFFFFFFFFFFFFFUL +#elif (SIZEOF_LONG == 16) +# define CURL_MASK_SLONG 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFL +# define CURL_MASK_ULONG 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFUL +#else +# error "SIZEOF_LONG not defined" +#endif + +#if (SIZEOF_CURL_OFF_T == 2) +# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFF) +# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFF) +#elif (SIZEOF_CURL_OFF_T == 4) +# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFFFFFF) +# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFFFFFF) +#elif (SIZEOF_CURL_OFF_T == 8) +# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) +# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFFFFFFFFFFFFFF) +#elif (SIZEOF_CURL_OFF_T == 16) +# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) +# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) +#else +# error "SIZEOF_CURL_OFF_T not defined" +#endif + +#if (SIZEOF_SIZE_T == SIZEOF_SHORT) +# define CURL_MASK_SSIZE_T CURL_MASK_SSHORT +# define CURL_MASK_USIZE_T CURL_MASK_USHORT +#elif (SIZEOF_SIZE_T == SIZEOF_INT) +# define CURL_MASK_SSIZE_T CURL_MASK_SINT +# define CURL_MASK_USIZE_T CURL_MASK_UINT +#elif (SIZEOF_SIZE_T == SIZEOF_LONG) +# define CURL_MASK_SSIZE_T CURL_MASK_SLONG +# define CURL_MASK_USIZE_T CURL_MASK_ULONG +#elif (SIZEOF_SIZE_T == SIZEOF_CURL_OFF_T) +# define CURL_MASK_SSIZE_T CURL_MASK_SCOFFT +# define CURL_MASK_USIZE_T CURL_MASK_UCOFFT +#else +# error "SIZEOF_SIZE_T not defined" +#endif + +/* +** unsigned long to unsigned short +*/ + +unsigned short curlx_ultous(unsigned long ulnum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + + DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_USHORT); + return (unsigned short)(ulnum & (unsigned long) CURL_MASK_USHORT); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** unsigned long to unsigned char +*/ + +unsigned char curlx_ultouc(unsigned long ulnum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + + DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_UCHAR); + return (unsigned char)(ulnum & (unsigned long) CURL_MASK_UCHAR); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** unsigned long to signed int +*/ + +int curlx_ultosi(unsigned long ulnum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + + DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_SINT); + return (int)(ulnum & (unsigned long) CURL_MASK_SINT); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** unsigned size_t to signed curl_off_t +*/ + +curl_off_t curlx_uztoso(size_t uznum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#elif defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable:4310) /* cast truncates constant value */ +#endif + + DEBUGASSERT(uznum <= (size_t) CURL_MASK_SCOFFT); + return (curl_off_t)(uznum & (size_t) CURL_MASK_SCOFFT); + +#if defined(__INTEL_COMPILER) || defined(_MSC_VER) +# pragma warning(pop) +#endif +} + +/* +** unsigned size_t to signed int +*/ + +int curlx_uztosi(size_t uznum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + + DEBUGASSERT(uznum <= (size_t) CURL_MASK_SINT); + return (int)(uznum & (size_t) CURL_MASK_SINT); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** unsigned size_t to unsigned long +*/ + +unsigned long curlx_uztoul(size_t uznum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + +#if (SIZEOF_LONG < SIZEOF_SIZE_T) + DEBUGASSERT(uznum <= (size_t) CURL_MASK_ULONG); +#endif + return (unsigned long)(uznum & (size_t) CURL_MASK_ULONG); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** unsigned size_t to unsigned int +*/ + +unsigned int curlx_uztoui(size_t uznum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + +#if (SIZEOF_INT < SIZEOF_SIZE_T) + DEBUGASSERT(uznum <= (size_t) CURL_MASK_UINT); +#endif + return (unsigned int)(uznum & (size_t) CURL_MASK_UINT); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** signed long to signed int +*/ + +int curlx_sltosi(long slnum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + + DEBUGASSERT(slnum >= 0); +#if (SIZEOF_INT < SIZEOF_LONG) + DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_SINT); +#endif + return (int)(slnum & (long) CURL_MASK_SINT); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** signed long to unsigned int +*/ + +unsigned int curlx_sltoui(long slnum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + + DEBUGASSERT(slnum >= 0); +#if (SIZEOF_INT < SIZEOF_LONG) + DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_UINT); +#endif + return (unsigned int)(slnum & (long) CURL_MASK_UINT); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** signed long to unsigned short +*/ + +unsigned short curlx_sltous(long slnum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + + DEBUGASSERT(slnum >= 0); + DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_USHORT); + return (unsigned short)(slnum & (long) CURL_MASK_USHORT); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** unsigned size_t to signed ssize_t +*/ + +ssize_t curlx_uztosz(size_t uznum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + + DEBUGASSERT(uznum <= (size_t) CURL_MASK_SSIZE_T); + return (ssize_t)(uznum & (size_t) CURL_MASK_SSIZE_T); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** signed curl_off_t to unsigned size_t +*/ + +size_t curlx_sotouz(curl_off_t sonum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + + DEBUGASSERT(sonum >= 0); + return (size_t)(sonum & (curl_off_t) CURL_MASK_USIZE_T); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** signed ssize_t to signed int +*/ + +int curlx_sztosi(ssize_t sznum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + + DEBUGASSERT(sznum >= 0); +#if (SIZEOF_INT < SIZEOF_SIZE_T) + DEBUGASSERT((size_t) sznum <= (size_t) CURL_MASK_SINT); +#endif + return (int)(sznum & (ssize_t) CURL_MASK_SINT); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** unsigned int to unsigned short +*/ + +unsigned short curlx_uitous(unsigned int uinum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + + DEBUGASSERT(uinum <= (unsigned int) CURL_MASK_USHORT); + return (unsigned short) (uinum & (unsigned int) CURL_MASK_USHORT); + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +/* +** signed int to unsigned size_t +*/ + +size_t curlx_sitouz(int sinum) +{ +#ifdef __INTEL_COMPILER +# pragma warning(push) +# pragma warning(disable:810) /* conversion may lose significant bits */ +#endif + + DEBUGASSERT(sinum >= 0); + return (size_t) sinum; + +#ifdef __INTEL_COMPILER +# pragma warning(pop) +#endif +} + +#ifdef USE_WINSOCK + +/* +** curl_socket_t to signed int +*/ + +int curlx_sktosi(curl_socket_t s) +{ + return (int)((ssize_t) s); +} + +/* +** signed int to curl_socket_t +*/ + +curl_socket_t curlx_sitosk(int i) +{ + return (curl_socket_t)((ssize_t) i); +} + +#endif /* USE_WINSOCK */ + +#if defined(WIN32) || defined(_WIN32) + +ssize_t curlx_read(int fd, void *buf, size_t count) +{ + return (ssize_t)read(fd, buf, curlx_uztoui(count)); +} + +ssize_t curlx_write(int fd, const void *buf, size_t count) +{ + return (ssize_t)write(fd, buf, curlx_uztoui(count)); +} + +#endif /* WIN32 || _WIN32 */ + +#if defined(__INTEL_COMPILER) && defined(__unix__) + +int curlx_FD_ISSET(int fd, fd_set *fdset) +{ + #pragma warning(push) + #pragma warning(disable:1469) /* clobber ignored */ + return FD_ISSET(fd, fdset); + #pragma warning(pop) +} + +void curlx_FD_SET(int fd, fd_set *fdset) +{ + #pragma warning(push) + #pragma warning(disable:1469) /* clobber ignored */ + FD_SET(fd, fdset); + #pragma warning(pop) +} + +void curlx_FD_ZERO(fd_set *fdset) +{ + #pragma warning(push) + #pragma warning(disable:593) /* variable was set but never used */ + FD_ZERO(fdset); + #pragma warning(pop) +} + +unsigned short curlx_htons(unsigned short usnum) +{ +#if (__INTEL_COMPILER == 910) && defined(__i386__) + return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF)); +#else + #pragma warning(push) + #pragma warning(disable:810) /* conversion may lose significant bits */ + return htons(usnum); + #pragma warning(pop) +#endif +} + +unsigned short curlx_ntohs(unsigned short usnum) +{ +#if (__INTEL_COMPILER == 910) && defined(__i386__) + return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF)); +#else + #pragma warning(push) + #pragma warning(disable:810) /* conversion may lose significant bits */ + return ntohs(usnum); + #pragma warning(pop) +#endif +} + +#endif /* __INTEL_COMPILER && __unix__ */ diff --git a/libcurl/lib/warnless.h b/libcurl/lib/warnless.h new file mode 100644 index 0000000..ea4c439 --- /dev/null +++ b/libcurl/lib/warnless.h @@ -0,0 +1,112 @@ +#ifndef HEADER_CURL_WARNLESS_H +#define HEADER_CURL_WARNLESS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#ifdef USE_WINSOCK +#include /* for curl_socket_t */ +#endif + +#define CURLX_FUNCTION_CAST(target_type, func) \ + (target_type)(void (*) (void))(func) + +unsigned short curlx_ultous(unsigned long ulnum); + +unsigned char curlx_ultouc(unsigned long ulnum); + +int curlx_ultosi(unsigned long ulnum); + +int curlx_uztosi(size_t uznum); + +curl_off_t curlx_uztoso(size_t uznum); + +unsigned long curlx_uztoul(size_t uznum); + +unsigned int curlx_uztoui(size_t uznum); + +int curlx_sltosi(long slnum); + +unsigned int curlx_sltoui(long slnum); + +unsigned short curlx_sltous(long slnum); + +ssize_t curlx_uztosz(size_t uznum); + +size_t curlx_sotouz(curl_off_t sonum); + +int curlx_sztosi(ssize_t sznum); + +unsigned short curlx_uitous(unsigned int uinum); + +size_t curlx_sitouz(int sinum); + +#ifdef USE_WINSOCK + +int curlx_sktosi(curl_socket_t s); + +curl_socket_t curlx_sitosk(int i); + +#endif /* USE_WINSOCK */ + +#if defined(WIN32) || defined(_WIN32) + +ssize_t curlx_read(int fd, void *buf, size_t count); + +ssize_t curlx_write(int fd, const void *buf, size_t count); + +#ifndef BUILDING_WARNLESS_C +# undef read +# define read(fd, buf, count) curlx_read(fd, buf, count) +# undef write +# define write(fd, buf, count) curlx_write(fd, buf, count) +#endif + +#endif /* WIN32 || _WIN32 */ + +#if defined(__INTEL_COMPILER) && defined(__unix__) + +int curlx_FD_ISSET(int fd, fd_set *fdset); + +void curlx_FD_SET(int fd, fd_set *fdset); + +void curlx_FD_ZERO(fd_set *fdset); + +unsigned short curlx_htons(unsigned short usnum); + +unsigned short curlx_ntohs(unsigned short usnum); + +#ifndef BUILDING_WARNLESS_C +# undef FD_ISSET +# define FD_ISSET(a,b) curlx_FD_ISSET((a),(b)) +# undef FD_SET +# define FD_SET(a,b) curlx_FD_SET((a),(b)) +# undef FD_ZERO +# define FD_ZERO(a) curlx_FD_ZERO((a)) +# undef htons +# define htons(a) curlx_htons((a)) +# undef ntohs +# define ntohs(a) curlx_ntohs((a)) +#endif + +#endif /* __INTEL_COMPILER && __unix__ */ + +#endif /* HEADER_CURL_WARNLESS_H */ diff --git a/libcurl/lib/wildcard.c b/libcurl/lib/wildcard.c new file mode 100644 index 0000000..e94d3c5 --- /dev/null +++ b/libcurl/lib/wildcard.c @@ -0,0 +1,73 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_FTP + +#include "wildcard.h" +#include "llist.h" +#include "fileinfo.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +static void fileinfo_dtor(void *user, void *element) +{ + (void)user; + Curl_fileinfo_cleanup(element); +} + +CURLcode Curl_wildcard_init(struct WildcardData *wc) +{ + Curl_llist_init(&wc->filelist, fileinfo_dtor); + wc->state = CURLWC_INIT; + + return CURLE_OK; +} + +void Curl_wildcard_dtor(struct WildcardData *wc) +{ + if(!wc) + return; + + if(wc->dtor) { + wc->dtor(wc->protdata); + wc->dtor = ZERO_NULL; + wc->protdata = NULL; + } + DEBUGASSERT(wc->protdata == NULL); + + Curl_llist_destroy(&wc->filelist, NULL); + + + free(wc->path); + wc->path = NULL; + free(wc->pattern); + wc->pattern = NULL; + + wc->customptr = NULL; + wc->state = CURLWC_INIT; +} + +#endif /* if disabled */ diff --git a/libcurl/lib/wildcard.h b/libcurl/lib/wildcard.h new file mode 100644 index 0000000..306c8c9 --- /dev/null +++ b/libcurl/lib/wildcard.h @@ -0,0 +1,67 @@ +#ifndef HEADER_CURL_WILDCARD_H +#define HEADER_CURL_WILDCARD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2010 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_FTP +#include "llist.h" + +/* list of wildcard process states */ +typedef enum { + CURLWC_CLEAR = 0, + CURLWC_INIT = 1, + CURLWC_MATCHING, /* library is trying to get list of addresses for + downloading */ + CURLWC_DOWNLOADING, + CURLWC_CLEAN, /* deallocate resources and reset settings */ + CURLWC_SKIP, /* skip over concrete file */ + CURLWC_ERROR, /* error cases */ + CURLWC_DONE /* if is wildcard->state == CURLWC_DONE wildcard loop + will end */ +} curl_wildcard_states; + +typedef void (*curl_wildcard_dtor)(void *ptr); + +/* struct keeping information about wildcard download process */ +struct WildcardData { + curl_wildcard_states state; + char *path; /* path to the directory, where we trying wildcard-match */ + char *pattern; /* wildcard pattern */ + struct curl_llist filelist; /* llist with struct Curl_fileinfo */ + void *protdata; /* pointer to protocol specific temporary data */ + curl_wildcard_dtor dtor; + void *customptr; /* for CURLOPT_CHUNK_DATA pointer */ +}; + +CURLcode Curl_wildcard_init(struct WildcardData *wc); +void Curl_wildcard_dtor(struct WildcardData *wc); + +struct Curl_easy; + +#else +/* FTP is disabled */ +#define Curl_wildcard_dtor(x) +#endif + +#endif /* HEADER_CURL_WILDCARD_H */ diff --git a/libcurl/lib/x509asn1.c b/libcurl/lib/x509asn1.c new file mode 100644 index 0000000..ece5364 --- /dev/null +++ b/libcurl/lib/x509asn1.c @@ -0,0 +1,1283 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \ + defined(USE_WOLFSSL) || defined(USE_SCHANNEL) + +#include +#include "urldata.h" +#include "strcase.h" +#include "hostcheck.h" +#include "vtls/vtls.h" +#include "sendf.h" +#include "inet_pton.h" +#include "curl_base64.h" +#include "x509asn1.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +/* ASN.1 OIDs. */ +static const char cnOID[] = "2.5.4.3"; /* Common name. */ +static const char sanOID[] = "2.5.29.17"; /* Subject alternative name. */ + +static const curl_OID OIDtable[] = { + { "1.2.840.10040.4.1", "dsa" }, + { "1.2.840.10040.4.3", "dsa-with-sha1" }, + { "1.2.840.10045.2.1", "ecPublicKey" }, + { "1.2.840.10045.3.0.1", "c2pnb163v1" }, + { "1.2.840.10045.4.1", "ecdsa-with-SHA1" }, + { "1.2.840.10046.2.1", "dhpublicnumber" }, + { "1.2.840.113549.1.1.1", "rsaEncryption" }, + { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" }, + { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" }, + { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" }, + { "1.2.840.113549.1.1.10", "RSASSA-PSS" }, + { "1.2.840.113549.1.1.14", "sha224WithRSAEncryption" }, + { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" }, + { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" }, + { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" }, + { "1.2.840.113549.2.2", "md2" }, + { "1.2.840.113549.2.5", "md5" }, + { "1.3.14.3.2.26", "sha1" }, + { cnOID, "CN" }, + { "2.5.4.4", "SN" }, + { "2.5.4.5", "serialNumber" }, + { "2.5.4.6", "C" }, + { "2.5.4.7", "L" }, + { "2.5.4.8", "ST" }, + { "2.5.4.9", "streetAddress" }, + { "2.5.4.10", "O" }, + { "2.5.4.11", "OU" }, + { "2.5.4.12", "title" }, + { "2.5.4.13", "description" }, + { "2.5.4.17", "postalCode" }, + { "2.5.4.41", "name" }, + { "2.5.4.42", "givenName" }, + { "2.5.4.43", "initials" }, + { "2.5.4.44", "generationQualifier" }, + { "2.5.4.45", "X500UniqueIdentifier" }, + { "2.5.4.46", "dnQualifier" }, + { "2.5.4.65", "pseudonym" }, + { "1.2.840.113549.1.9.1", "emailAddress" }, + { "2.5.4.72", "role" }, + { sanOID, "subjectAltName" }, + { "2.5.29.18", "issuerAltName" }, + { "2.5.29.19", "basicConstraints" }, + { "2.16.840.1.101.3.4.2.4", "sha224" }, + { "2.16.840.1.101.3.4.2.1", "sha256" }, + { "2.16.840.1.101.3.4.2.2", "sha384" }, + { "2.16.840.1.101.3.4.2.3", "sha512" }, + { (const char *) NULL, (const char *) NULL } +}; + +/* + * Lightweight ASN.1 parser. + * In particular, it does not check for syntactic/lexical errors. + * It is intended to support certificate information gathering for SSL backends + * that offer a mean to get certificates as a whole, but do not supply + * entry points to get particular certificate sub-fields. + * Please note there is no pretention here to rewrite a full SSL library. + */ + +static const char *getASN1Element(curl_asn1Element *elem, + const char *beg, const char *end) + WARN_UNUSED_RESULT; + +static const char *getASN1Element(curl_asn1Element *elem, + const char *beg, const char *end) +{ + unsigned char b; + unsigned long len; + curl_asn1Element lelem; + + /* Get a single ASN.1 element into `elem', parse ASN.1 string at `beg' + ending at `end'. + Returns a pointer in source string after the parsed element, or NULL + if an error occurs. */ + if(!beg || !end || beg >= end || !*beg || + (size_t)(end - beg) > CURL_ASN1_MAX) + return NULL; + + /* Process header byte. */ + elem->header = beg; + b = (unsigned char) *beg++; + elem->constructed = (b & 0x20) != 0; + elem->class = (b >> 6) & 3; + b &= 0x1F; + if(b == 0x1F) + return NULL; /* Long tag values not supported here. */ + elem->tag = b; + + /* Process length. */ + if(beg >= end) + return NULL; + b = (unsigned char) *beg++; + if(!(b & 0x80)) + len = b; + else if(!(b &= 0x7F)) { + /* Unspecified length. Since we have all the data, we can determine the + effective length by skipping element until an end element is found. */ + if(!elem->constructed) + return NULL; + elem->beg = beg; + while(beg < end && *beg) { + beg = getASN1Element(&lelem, beg, end); + if(!beg) + return NULL; + } + if(beg >= end) + return NULL; + elem->end = beg; + return beg + 1; + } + else if((unsigned)b > (size_t)(end - beg)) + return NULL; /* Does not fit in source. */ + else { + /* Get long length. */ + len = 0; + do { + if(len & 0xFF000000L) + return NULL; /* Lengths > 32 bits are not supported. */ + len = (len << 8) | (unsigned char) *beg++; + } while(--b); + } + if(len > (size_t)(end - beg)) + return NULL; /* Element data does not fit in source. */ + elem->beg = beg; + elem->end = beg + len; + return elem->end; +} + +/* + * Search the null terminated OID or OID identifier in local table. + * Return the table entry pointer or NULL if not found. + */ +static const curl_OID * searchOID(const char *oid) +{ + const curl_OID *op; + for(op = OIDtable; op->numoid; op++) + if(!strcmp(op->numoid, oid) || strcasecompare(op->textoid, oid)) + return op; + + return NULL; +} + +/* + * Convert an ASN.1 Boolean value into its string representation. Return the + * dynamically allocated string, or NULL if source is not an ASN.1 Boolean + * value. + */ + +static const char *bool2str(const char *beg, const char *end) +{ + if(end - beg != 1) + return NULL; + return strdup(*beg? "TRUE": "FALSE"); +} + +/* + * Convert an ASN.1 octet string to a printable string. + * Return the dynamically allocated string, or NULL if an error occurs. + */ +static const char *octet2str(const char *beg, const char *end) +{ + size_t n = end - beg; + char *buf = NULL; + + if(n <= (SIZE_T_MAX - 1) / 3) { + buf = malloc(3 * n + 1); + if(buf) + for(n = 0; beg < end; n += 3) + msnprintf(buf + n, 4, "%02x:", *(const unsigned char *) beg++); + } + return buf; +} + +static const char *bit2str(const char *beg, const char *end) +{ + /* Convert an ASN.1 bit string to a printable string. + Return the dynamically allocated string, or NULL if an error occurs. */ + + if(++beg > end) + return NULL; + return octet2str(beg, end); +} + +/* + * Convert an ASN.1 integer value into its string representation. + * Return the dynamically allocated string, or NULL if source is not an + * ASN.1 integer value. + */ +static const char *int2str(const char *beg, const char *end) +{ + unsigned long val = 0; + size_t n = end - beg; + + if(!n) + return NULL; + + if(n > 4) + return octet2str(beg, end); + + /* Represent integers <= 32-bit as a single value. */ + if(*beg & 0x80) + val = ~val; + + do + val = (val << 8) | *(const unsigned char *) beg++; + while(beg < end); + return curl_maprintf("%s%lx", val >= 10? "0x": "", val); +} + +/* + * Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the + * destination buffer dynamically. The allocation size will normally be too + * large: this is to avoid buffer overflows. + * Terminate the string with a nul byte and return the converted + * string length. + */ +static ssize_t +utf8asn1str(char **to, int type, const char *from, const char *end) +{ + size_t inlength = end - from; + int size = 1; + size_t outlength; + char *buf; + + *to = NULL; + switch(type) { + case CURL_ASN1_BMP_STRING: + size = 2; + break; + case CURL_ASN1_UNIVERSAL_STRING: + size = 4; + break; + case CURL_ASN1_NUMERIC_STRING: + case CURL_ASN1_PRINTABLE_STRING: + case CURL_ASN1_TELETEX_STRING: + case CURL_ASN1_IA5_STRING: + case CURL_ASN1_VISIBLE_STRING: + case CURL_ASN1_UTF8_STRING: + break; + default: + return -1; /* Conversion not supported. */ + } + + if(inlength % size) + return -1; /* Length inconsistent with character size. */ + if(inlength / size > (SIZE_T_MAX - 1) / 4) + return -1; /* Too big. */ + buf = malloc(4 * (inlength / size) + 1); + if(!buf) + return -1; /* Not enough memory. */ + + if(type == CURL_ASN1_UTF8_STRING) { + /* Just copy. */ + outlength = inlength; + if(outlength) + memcpy(buf, from, outlength); + } + else { + for(outlength = 0; from < end;) { + int charsize; + unsigned int wc; + + wc = 0; + switch(size) { + case 4: + wc = (wc << 8) | *(const unsigned char *) from++; + wc = (wc << 8) | *(const unsigned char *) from++; + /* FALLTHROUGH */ + case 2: + wc = (wc << 8) | *(const unsigned char *) from++; + /* FALLTHROUGH */ + default: /* case 1: */ + wc = (wc << 8) | *(const unsigned char *) from++; + } + charsize = 1; + if(wc >= 0x00000080) { + if(wc >= 0x00000800) { + if(wc >= 0x00010000) { + if(wc >= 0x00200000) { + free(buf); + return -1; /* Invalid char. size for target encoding. */ + } + buf[outlength + 3] = (char) (0x80 | (wc & 0x3F)); + wc = (wc >> 6) | 0x00010000; + charsize++; + } + buf[outlength + 2] = (char) (0x80 | (wc & 0x3F)); + wc = (wc >> 6) | 0x00000800; + charsize++; + } + buf[outlength + 1] = (char) (0x80 | (wc & 0x3F)); + wc = (wc >> 6) | 0x000000C0; + charsize++; + } + buf[outlength] = (char) wc; + outlength += charsize; + } + } + buf[outlength] = '\0'; + *to = buf; + return outlength; +} + +/* + * Convert an ASN.1 String into its UTF-8 string representation. + * Return the dynamically allocated string, or NULL if an error occurs. + */ +static const char *string2str(int type, const char *beg, const char *end) +{ + char *buf; + if(utf8asn1str(&buf, type, beg, end) < 0) + return NULL; + return buf; +} + +/* + * Decimal ASCII encode unsigned integer `x' into the buflen sized buffer at + * buf. Return the total number of encoded digits, even if larger than + * `buflen'. + */ +static size_t encodeUint(char *buf, size_t buflen, unsigned int x) +{ + size_t i = 0; + unsigned int y = x / 10; + + if(y) { + i = encodeUint(buf, buflen, y); + x -= y * 10; + } + if(i < buflen) + buf[i] = (char) ('0' + x); + i++; + if(i < buflen) + buf[i] = '\0'; /* Store a terminator if possible. */ + return i; +} + +/* + * Convert an ASN.1 OID into its dotted string representation. + * Store the result in th `n'-byte buffer at `buf'. + * Return the converted string length, or 0 on errors. + */ +static size_t encodeOID(char *buf, size_t buflen, + const char *beg, const char *end) +{ + size_t i; + unsigned int x; + unsigned int y; + + /* Process the first two numbers. */ + y = *(const unsigned char *) beg++; + x = y / 40; + y -= x * 40; + i = encodeUint(buf, buflen, x); + if(i < buflen) + buf[i] = '.'; + i++; + if(i >= buflen) + i += encodeUint(NULL, 0, y); + else + i += encodeUint(buf + i, buflen - i, y); + + /* Process the trailing numbers. */ + while(beg < end) { + if(i < buflen) + buf[i] = '.'; + i++; + x = 0; + do { + if(x & 0xFF000000) + return 0; + y = *(const unsigned char *) beg++; + x = (x << 7) | (y & 0x7F); + } while(y & 0x80); + if(i >= buflen) + i += encodeUint(NULL, 0, x); + else + i += encodeUint(buf + i, buflen - i, x); + } + if(i < buflen) + buf[i] = '\0'; + return i; +} + +/* + * Convert an ASN.1 OID into its dotted or symbolic string representation. + * Return the dynamically allocated string, or NULL if an error occurs. + */ + +static const char *OID2str(const char *beg, const char *end, bool symbolic) +{ + char *buf = NULL; + if(beg < end) { + size_t buflen = encodeOID(NULL, 0, beg, end); + if(buflen) { + buf = malloc(buflen + 1); /* one extra for the zero byte */ + if(buf) { + encodeOID(buf, buflen, beg, end); + buf[buflen] = '\0'; + + if(symbolic) { + const curl_OID *op = searchOID(buf); + if(op) { + free(buf); + buf = strdup(op->textoid); + } + } + } + } + } + return buf; +} + +static const char *GTime2str(const char *beg, const char *end) +{ + const char *tzp; + const char *fracp; + char sec1, sec2; + size_t fracl; + size_t tzl; + const char *sep = ""; + + /* Convert an ASN.1 Generalized time to a printable string. + Return the dynamically allocated string, or NULL if an error occurs. */ + + for(fracp = beg; fracp < end && *fracp >= '0' && *fracp <= '9'; fracp++) + ; + + /* Get seconds digits. */ + sec1 = '0'; + switch(fracp - beg - 12) { + case 0: + sec2 = '0'; + break; + case 2: + sec1 = fracp[-2]; + /* FALLTHROUGH */ + case 1: + sec2 = fracp[-1]; + break; + default: + return NULL; + } + + /* Scan for timezone, measure fractional seconds. */ + tzp = fracp; + fracl = 0; + if(fracp < end && (*fracp == '.' || *fracp == ',')) { + fracp++; + do + tzp++; + while(tzp < end && *tzp >= '0' && *tzp <= '9'); + /* Strip leading zeroes in fractional seconds. */ + for(fracl = tzp - fracp - 1; fracl && fracp[fracl - 1] == '0'; fracl--) + ; + } + + /* Process timezone. */ + if(tzp >= end) + ; /* Nothing to do. */ + else if(*tzp == 'Z') { + tzp = " GMT"; + end = tzp + 4; + } + else { + sep = " "; + tzp++; + } + + tzl = end - tzp; + return curl_maprintf("%.4s-%.2s-%.2s %.2s:%.2s:%c%c%s%.*s%s%.*s", + beg, beg + 4, beg + 6, + beg + 8, beg + 10, sec1, sec2, + fracl? ".": "", fracl, fracp, + sep, tzl, tzp); +} + +/* + * Convert an ASN.1 UTC time to a printable string. + * Return the dynamically allocated string, or NULL if an error occurs. + */ +static const char *UTime2str(const char *beg, const char *end) +{ + const char *tzp; + size_t tzl; + const char *sec; + + for(tzp = beg; tzp < end && *tzp >= '0' && *tzp <= '9'; tzp++) + ; + /* Get the seconds. */ + sec = beg + 10; + switch(tzp - sec) { + case 0: + sec = "00"; + case 2: + break; + default: + return NULL; + } + + /* Process timezone. */ + if(tzp >= end) + return NULL; + if(*tzp == 'Z') { + tzp = "GMT"; + end = tzp + 3; + } + else + tzp++; + + tzl = end - tzp; + return curl_maprintf("%u%.2s-%.2s-%.2s %.2s:%.2s:%.2s %.*s", + 20 - (*beg >= '5'), beg, beg + 2, beg + 4, + beg + 6, beg + 8, sec, + tzl, tzp); +} + +/* + * Convert an ASN.1 element to a printable string. + * Return the dynamically allocated string, or NULL if an error occurs. + */ +static const char *ASN1tostr(curl_asn1Element *elem, int type) +{ + if(elem->constructed) + return NULL; /* No conversion of structured elements. */ + + if(!type) + type = elem->tag; /* Type not forced: use element tag as type. */ + + switch(type) { + case CURL_ASN1_BOOLEAN: + return bool2str(elem->beg, elem->end); + case CURL_ASN1_INTEGER: + case CURL_ASN1_ENUMERATED: + return int2str(elem->beg, elem->end); + case CURL_ASN1_BIT_STRING: + return bit2str(elem->beg, elem->end); + case CURL_ASN1_OCTET_STRING: + return octet2str(elem->beg, elem->end); + case CURL_ASN1_NULL: + return strdup(""); + case CURL_ASN1_OBJECT_IDENTIFIER: + return OID2str(elem->beg, elem->end, TRUE); + case CURL_ASN1_UTC_TIME: + return UTime2str(elem->beg, elem->end); + case CURL_ASN1_GENERALIZED_TIME: + return GTime2str(elem->beg, elem->end); + case CURL_ASN1_UTF8_STRING: + case CURL_ASN1_NUMERIC_STRING: + case CURL_ASN1_PRINTABLE_STRING: + case CURL_ASN1_TELETEX_STRING: + case CURL_ASN1_IA5_STRING: + case CURL_ASN1_VISIBLE_STRING: + case CURL_ASN1_UNIVERSAL_STRING: + case CURL_ASN1_BMP_STRING: + return string2str(type, elem->beg, elem->end); + } + + return NULL; /* Unsupported. */ +} + +/* + * ASCII encode distinguished name at `dn' into the `buflen'-sized buffer at + * `buf'. Return the total string length, even if larger than `buflen'. + */ +static ssize_t encodeDN(char *buf, size_t buflen, curl_asn1Element *dn) +{ + curl_asn1Element rdn; + curl_asn1Element atv; + curl_asn1Element oid; + curl_asn1Element value; + size_t l = 0; + const char *p1; + const char *p2; + const char *p3; + const char *str; + + for(p1 = dn->beg; p1 < dn->end;) { + p1 = getASN1Element(&rdn, p1, dn->end); + if(!p1) + return -1; + for(p2 = rdn.beg; p2 < rdn.end;) { + p2 = getASN1Element(&atv, p2, rdn.end); + if(!p2) + return -1; + p3 = getASN1Element(&oid, atv.beg, atv.end); + if(!p3) + return -1; + if(!getASN1Element(&value, p3, atv.end)) + return -1; + str = ASN1tostr(&oid, 0); + if(!str) + return -1; + + /* Encode delimiter. + If attribute has a short uppercase name, delimiter is ", ". */ + if(l) { + for(p3 = str; isupper(*p3); p3++) + ; + for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) { + if(l < buflen) + buf[l] = *p3; + l++; + } + } + + /* Encode attribute name. */ + for(p3 = str; *p3; p3++) { + if(l < buflen) + buf[l] = *p3; + l++; + } + free((char *) str); + + /* Generate equal sign. */ + if(l < buflen) + buf[l] = '='; + l++; + + /* Generate value. */ + str = ASN1tostr(&value, 0); + if(!str) + return -1; + for(p3 = str; *p3; p3++) { + if(l < buflen) + buf[l] = *p3; + l++; + } + free((char *) str); + } + } + + return l; +} + +/* + * Convert an ASN.1 distinguished name into a printable string. + * Return the dynamically allocated string, or NULL if an error occurs. + */ +static const char *DNtostr(curl_asn1Element *dn) +{ + char *buf = NULL; + ssize_t buflen = encodeDN(NULL, 0, dn); + + if(buflen >= 0) { + buf = malloc(buflen + 1); + if(buf) { + encodeDN(buf, buflen + 1, dn); + buf[buflen] = '\0'; + } + } + return buf; +} + +/* + * ASN.1 parse an X509 certificate into structure subfields. + * Syntax is assumed to have already been checked by the SSL backend. + * See RFC 5280. + */ +int Curl_parseX509(curl_X509certificate *cert, + const char *beg, const char *end) +{ + curl_asn1Element elem; + curl_asn1Element tbsCertificate; + const char *ccp; + static const char defaultVersion = 0; /* v1. */ + + cert->certificate.header = NULL; + cert->certificate.beg = beg; + cert->certificate.end = end; + + /* Get the sequence content. */ + if(!getASN1Element(&elem, beg, end)) + return -1; /* Invalid bounds/size. */ + beg = elem.beg; + end = elem.end; + + /* Get tbsCertificate. */ + beg = getASN1Element(&tbsCertificate, beg, end); + if(!beg) + return -1; + /* Skip the signatureAlgorithm. */ + beg = getASN1Element(&cert->signatureAlgorithm, beg, end); + if(!beg) + return -1; + /* Get the signatureValue. */ + if(!getASN1Element(&cert->signature, beg, end)) + return -1; + + /* Parse TBSCertificate. */ + beg = tbsCertificate.beg; + end = tbsCertificate.end; + /* Get optional version, get serialNumber. */ + cert->version.header = NULL; + cert->version.beg = &defaultVersion; + cert->version.end = &defaultVersion + sizeof(defaultVersion); + beg = getASN1Element(&elem, beg, end); + if(!beg) + return -1; + if(elem.tag == 0) { + if(!getASN1Element(&cert->version, elem.beg, elem.end)) + return -1; + beg = getASN1Element(&elem, beg, end); + if(!beg) + return -1; + } + cert->serialNumber = elem; + /* Get signature algorithm. */ + beg = getASN1Element(&cert->signatureAlgorithm, beg, end); + /* Get issuer. */ + beg = getASN1Element(&cert->issuer, beg, end); + if(!beg) + return -1; + /* Get notBefore and notAfter. */ + beg = getASN1Element(&elem, beg, end); + if(!beg) + return -1; + ccp = getASN1Element(&cert->notBefore, elem.beg, elem.end); + if(!ccp) + return -1; + if(!getASN1Element(&cert->notAfter, ccp, elem.end)) + return -1; + /* Get subject. */ + beg = getASN1Element(&cert->subject, beg, end); + if(!beg) + return -1; + /* Get subjectPublicKeyAlgorithm and subjectPublicKey. */ + beg = getASN1Element(&cert->subjectPublicKeyInfo, beg, end); + if(!beg) + return -1; + ccp = getASN1Element(&cert->subjectPublicKeyAlgorithm, + cert->subjectPublicKeyInfo.beg, + cert->subjectPublicKeyInfo.end); + if(!ccp) + return -1; + if(!getASN1Element(&cert->subjectPublicKey, ccp, + cert->subjectPublicKeyInfo.end)) + return -1; + /* Get optional issuerUiqueID, subjectUniqueID and extensions. */ + cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0; + cert->extensions.tag = elem.tag = 0; + cert->issuerUniqueID.header = cert->subjectUniqueID.header = NULL; + cert->issuerUniqueID.beg = cert->issuerUniqueID.end = ""; + cert->subjectUniqueID.beg = cert->subjectUniqueID.end = ""; + cert->extensions.header = NULL; + cert->extensions.beg = cert->extensions.end = ""; + if(beg < end) { + beg = getASN1Element(&elem, beg, end); + if(!beg) + return -1; + } + if(elem.tag == 1) { + cert->issuerUniqueID = elem; + if(beg < end) { + beg = getASN1Element(&elem, beg, end); + if(!beg) + return -1; + } + } + if(elem.tag == 2) { + cert->subjectUniqueID = elem; + if(beg < end) { + beg = getASN1Element(&elem, beg, end); + if(!beg) + return -1; + } + } + if(elem.tag == 3) + if(!getASN1Element(&cert->extensions, elem.beg, elem.end)) + return -1; + return 0; +} + + +/* + * Copy at most 64-characters, terminate with a newline and returns the + * effective number of stored characters. + */ +static size_t copySubstring(char *to, const char *from) +{ + size_t i; + for(i = 0; i < 64; i++) { + to[i] = *from; + if(!*from++) + break; + } + + to[i++] = '\n'; + return i; +} + +static const char *dumpAlgo(curl_asn1Element *param, + const char *beg, const char *end) +{ + curl_asn1Element oid; + + /* Get algorithm parameters and return algorithm name. */ + + beg = getASN1Element(&oid, beg, end); + if(!beg) + return NULL; + param->header = NULL; + param->tag = 0; + param->beg = param->end = end; + if(beg < end) + if(!getASN1Element(param, beg, end)) + return NULL; + return OID2str(oid.beg, oid.end, TRUE); +} + +static void do_pubkey_field(struct Curl_easy *data, int certnum, + const char *label, curl_asn1Element *elem) +{ + const char *output; + + /* Generate a certificate information record for the public key. */ + + output = ASN1tostr(elem, 0); + if(output) { + if(data->set.ssl.certinfo) + Curl_ssl_push_certinfo(data, certnum, label, output); + if(!certnum) + infof(data, " %s: %s\n", label, output); + free((char *) output); + } +} + +static void do_pubkey(struct Curl_easy *data, int certnum, + const char *algo, curl_asn1Element *param, + curl_asn1Element *pubkey) +{ + curl_asn1Element elem; + curl_asn1Element pk; + const char *p; + + /* Generate all information records for the public key. */ + + /* Get the public key (single element). */ + if(!getASN1Element(&pk, pubkey->beg + 1, pubkey->end)) + return; + + if(strcasecompare(algo, "rsaEncryption")) { + const char *q; + unsigned long len; + + p = getASN1Element(&elem, pk.beg, pk.end); + if(!p) + return; + + /* Compute key length. */ + for(q = elem.beg; !*q && q < elem.end; q++) + ; + len = (unsigned long)((elem.end - q) * 8); + if(len) { + unsigned int i; + for(i = *(unsigned char *) q; !(i & 0x80); i <<= 1) + len--; + } + if(len > 32) + elem.beg = q; /* Strip leading zero bytes. */ + if(!certnum) + infof(data, " RSA Public Key (%lu bits)\n", len); + if(data->set.ssl.certinfo) { + q = curl_maprintf("%lu", len); + if(q) { + Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q); + free((char *) q); + } + } + /* Generate coefficients. */ + do_pubkey_field(data, certnum, "rsa(n)", &elem); + if(!getASN1Element(&elem, p, pk.end)) + return; + do_pubkey_field(data, certnum, "rsa(e)", &elem); + } + else if(strcasecompare(algo, "dsa")) { + p = getASN1Element(&elem, param->beg, param->end); + if(p) { + do_pubkey_field(data, certnum, "dsa(p)", &elem); + p = getASN1Element(&elem, p, param->end); + if(p) { + do_pubkey_field(data, certnum, "dsa(q)", &elem); + if(getASN1Element(&elem, p, param->end)) { + do_pubkey_field(data, certnum, "dsa(g)", &elem); + do_pubkey_field(data, certnum, "dsa(pub_key)", &pk); + } + } + } + } + else if(strcasecompare(algo, "dhpublicnumber")) { + p = getASN1Element(&elem, param->beg, param->end); + if(p) { + do_pubkey_field(data, certnum, "dh(p)", &elem); + if(getASN1Element(&elem, param->beg, param->end)) { + do_pubkey_field(data, certnum, "dh(g)", &elem); + do_pubkey_field(data, certnum, "dh(pub_key)", &pk); + } + } + } +} + +CURLcode Curl_extract_certinfo(struct connectdata *conn, + int certnum, + const char *beg, + const char *end) +{ + curl_X509certificate cert; + struct Curl_easy *data = conn->data; + curl_asn1Element param; + const char *ccp; + char *cp1; + size_t cl1; + char *cp2; + CURLcode result; + unsigned long version; + size_t i; + size_t j; + + if(!data->set.ssl.certinfo) + if(certnum) + return CURLE_OK; + + /* Prepare the certificate information for curl_easy_getinfo(). */ + + /* Extract the certificate ASN.1 elements. */ + if(Curl_parseX509(&cert, beg, end)) + return CURLE_PEER_FAILED_VERIFICATION; + + /* Subject. */ + ccp = DNtostr(&cert.subject); + if(!ccp) + return CURLE_OUT_OF_MEMORY; + if(data->set.ssl.certinfo) + Curl_ssl_push_certinfo(data, certnum, "Subject", ccp); + if(!certnum) + infof(data, "%2d Subject: %s\n", certnum, ccp); + free((char *) ccp); + + /* Issuer. */ + ccp = DNtostr(&cert.issuer); + if(!ccp) + return CURLE_OUT_OF_MEMORY; + if(data->set.ssl.certinfo) + Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp); + if(!certnum) + infof(data, " Issuer: %s\n", ccp); + free((char *) ccp); + + /* Version (always fits in less than 32 bits). */ + version = 0; + for(ccp = cert.version.beg; ccp < cert.version.end; ccp++) + version = (version << 8) | *(const unsigned char *) ccp; + if(data->set.ssl.certinfo) { + ccp = curl_maprintf("%lx", version); + if(!ccp) + return CURLE_OUT_OF_MEMORY; + Curl_ssl_push_certinfo(data, certnum, "Version", ccp); + free((char *) ccp); + } + if(!certnum) + infof(data, " Version: %lu (0x%lx)\n", version + 1, version); + + /* Serial number. */ + ccp = ASN1tostr(&cert.serialNumber, 0); + if(!ccp) + return CURLE_OUT_OF_MEMORY; + if(data->set.ssl.certinfo) + Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp); + if(!certnum) + infof(data, " Serial Number: %s\n", ccp); + free((char *) ccp); + + /* Signature algorithm .*/ + ccp = dumpAlgo(¶m, cert.signatureAlgorithm.beg, + cert.signatureAlgorithm.end); + if(!ccp) + return CURLE_OUT_OF_MEMORY; + if(data->set.ssl.certinfo) + Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp); + if(!certnum) + infof(data, " Signature Algorithm: %s\n", ccp); + free((char *) ccp); + + /* Start Date. */ + ccp = ASN1tostr(&cert.notBefore, 0); + if(!ccp) + return CURLE_OUT_OF_MEMORY; + if(data->set.ssl.certinfo) + Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp); + if(!certnum) + infof(data, " Start Date: %s\n", ccp); + free((char *) ccp); + + /* Expire Date. */ + ccp = ASN1tostr(&cert.notAfter, 0); + if(!ccp) + return CURLE_OUT_OF_MEMORY; + if(data->set.ssl.certinfo) + Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp); + if(!certnum) + infof(data, " Expire Date: %s\n", ccp); + free((char *) ccp); + + /* Public Key Algorithm. */ + ccp = dumpAlgo(¶m, cert.subjectPublicKeyAlgorithm.beg, + cert.subjectPublicKeyAlgorithm.end); + if(!ccp) + return CURLE_OUT_OF_MEMORY; + if(data->set.ssl.certinfo) + Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp); + if(!certnum) + infof(data, " Public Key Algorithm: %s\n", ccp); + do_pubkey(data, certnum, ccp, ¶m, &cert.subjectPublicKey); + free((char *) ccp); + + /* Signature. */ + ccp = ASN1tostr(&cert.signature, 0); + if(!ccp) + return CURLE_OUT_OF_MEMORY; + if(data->set.ssl.certinfo) + Curl_ssl_push_certinfo(data, certnum, "Signature", ccp); + if(!certnum) + infof(data, " Signature: %s\n", ccp); + free((char *) ccp); + + /* Generate PEM certificate. */ + result = Curl_base64_encode(data, cert.certificate.beg, + cert.certificate.end - cert.certificate.beg, + &cp1, &cl1); + if(result) + return result; + /* Compute the number of characters in final certificate string. Format is: + -----BEGIN CERTIFICATE-----\n + \n + . + . + . + -----END CERTIFICATE-----\n + */ + i = 28 + cl1 + (cl1 + 64 - 1) / 64 + 26; + cp2 = malloc(i + 1); + if(!cp2) { + free(cp1); + return CURLE_OUT_OF_MEMORY; + } + /* Build the certificate string. */ + i = copySubstring(cp2, "-----BEGIN CERTIFICATE-----"); + for(j = 0; j < cl1; j += 64) + i += copySubstring(cp2 + i, cp1 + j); + i += copySubstring(cp2 + i, "-----END CERTIFICATE-----"); + cp2[i] = '\0'; + free(cp1); + if(data->set.ssl.certinfo) + Curl_ssl_push_certinfo(data, certnum, "Cert", cp2); + if(!certnum) + infof(data, "%s\n", cp2); + free(cp2); + return CURLE_OK; +} + +#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL */ + +#if defined(USE_GSKIT) + +static const char *checkOID(const char *beg, const char *end, + const char *oid) +{ + curl_asn1Element e; + const char *ccp; + const char *p; + bool matched; + + /* Check if first ASN.1 element at `beg' is the given OID. + Return a pointer in the source after the OID if found, else NULL. */ + + ccp = getASN1Element(&e, beg, end); + if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER) + return NULL; + + p = OID2str(e.beg, e.end, FALSE); + if(!p) + return NULL; + + matched = !strcmp(p, oid); + free((char *) p); + return matched? ccp: NULL; +} + +CURLcode Curl_verifyhost(struct connectdata *conn, + const char *beg, const char *end) +{ + struct Curl_easy *data = conn->data; + curl_X509certificate cert; + curl_asn1Element dn; + curl_asn1Element elem; + curl_asn1Element ext; + curl_asn1Element name; + const char *p; + const char *q; + char *dnsname; + int matched = -1; + size_t addrlen = (size_t) -1; + ssize_t len; + const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name: + conn->host.name; + const char * const dispname = SSL_IS_PROXY()? + conn->http_proxy.host.dispname: + conn->host.dispname; +#ifdef ENABLE_IPV6 + struct in6_addr addr; +#else + struct in_addr addr; +#endif + + /* Verify that connection server matches info in X509 certificate at + `beg'..`end'. */ + + if(!SSL_CONN_CONFIG(verifyhost)) + return CURLE_OK; + + if(Curl_parseX509(&cert, beg, end)) + return CURLE_PEER_FAILED_VERIFICATION; + + /* Get the server IP address. */ +#ifdef ENABLE_IPV6 + if(conn->bits.ipv6_ip && Curl_inet_pton(AF_INET6, hostname, &addr)) + addrlen = sizeof(struct in6_addr); + else +#endif + if(Curl_inet_pton(AF_INET, hostname, &addr)) + addrlen = sizeof(struct in_addr); + + /* Process extensions. */ + for(p = cert.extensions.beg; p < cert.extensions.end && matched != 1;) { + p = getASN1Element(&ext, p, cert.extensions.end); + if(!p) + return CURLE_PEER_FAILED_VERIFICATION; + + /* Check if extension is a subjectAlternativeName. */ + ext.beg = checkOID(ext.beg, ext.end, sanOID); + if(ext.beg) { + ext.beg = getASN1Element(&elem, ext.beg, ext.end); + if(!ext.beg) + return CURLE_PEER_FAILED_VERIFICATION; + /* Skip critical if present. */ + if(elem.tag == CURL_ASN1_BOOLEAN) { + ext.beg = getASN1Element(&elem, ext.beg, ext.end); + if(!ext.beg) + return CURLE_PEER_FAILED_VERIFICATION; + } + /* Parse the octet string contents: is a single sequence. */ + if(!getASN1Element(&elem, elem.beg, elem.end)) + return CURLE_PEER_FAILED_VERIFICATION; + /* Check all GeneralNames. */ + for(q = elem.beg; matched != 1 && q < elem.end;) { + q = getASN1Element(&name, q, elem.end); + if(!q) + break; + switch(name.tag) { + case 2: /* DNS name. */ + len = utf8asn1str(&dnsname, CURL_ASN1_IA5_STRING, + name.beg, name.end); + if(len > 0 && (size_t)len == strlen(dnsname)) + matched = Curl_cert_hostcheck(dnsname, hostname); + else + matched = 0; + free(dnsname); + break; + + case 7: /* IP address. */ + matched = (size_t) (name.end - name.beg) == addrlen && + !memcmp(&addr, name.beg, addrlen); + break; + } + } + } + } + + switch(matched) { + case 1: + /* an alternative name matched the server hostname */ + infof(data, "\t subjectAltName: %s matched\n", dispname); + return CURLE_OK; + case 0: + /* an alternative name field existed, but didn't match and then + we MUST fail */ + infof(data, "\t subjectAltName does not match %s\n", dispname); + return CURLE_PEER_FAILED_VERIFICATION; + } + + /* Process subject. */ + name.header = NULL; + name.beg = name.end = ""; + q = cert.subject.beg; + /* we have to look to the last occurrence of a commonName in the + distinguished one to get the most significant one. */ + while(q < cert.subject.end) { + q = getASN1Element(&dn, q, cert.subject.end); + if(!q) + break; + for(p = dn.beg; p < dn.end;) { + p = getASN1Element(&elem, p, dn.end); + if(!p) + return CURLE_PEER_FAILED_VERIFICATION; + /* We have a DN's AttributeTypeAndValue: check it in case it's a CN. */ + elem.beg = checkOID(elem.beg, elem.end, cnOID); + if(elem.beg) + name = elem; /* Latch CN. */ + } + } + + /* Check the CN if found. */ + if(!getASN1Element(&elem, name.beg, name.end)) + failf(data, "SSL: unable to obtain common name from peer certificate"); + else { + len = utf8asn1str(&dnsname, elem.tag, elem.beg, elem.end); + if(len < 0) { + free(dnsname); + return CURLE_OUT_OF_MEMORY; + } + if(strlen(dnsname) != (size_t) len) /* Nul byte in string ? */ + failf(data, "SSL: illegal cert name field"); + else if(Curl_cert_hostcheck((const char *) dnsname, hostname)) { + infof(data, "\t common name: %s (matched)\n", dnsname); + free(dnsname); + return CURLE_OK; + } + else + failf(data, "SSL: certificate subject name '%s' does not match " + "target host name '%s'", dnsname, dispname); + free(dnsname); + } + + return CURLE_PEER_FAILED_VERIFICATION; +} + +#endif /* USE_GSKIT */ diff --git a/libcurl/lib/x509asn1.h b/libcurl/lib/x509asn1.h new file mode 100644 index 0000000..205fdc0 --- /dev/null +++ b/libcurl/lib/x509asn1.h @@ -0,0 +1,134 @@ +#ifndef HEADER_CURL_X509ASN1_H +#define HEADER_CURL_X509ASN1_H + +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \ + defined(USE_WOLFSSL) || defined(USE_SCHANNEL) + +#include "urldata.h" + +/* + * Constants. + */ + +/* Largest supported ASN.1 structure. */ +#define CURL_ASN1_MAX ((size_t) 0x40000) /* 256K */ + +/* ASN.1 classes. */ +#define CURL_ASN1_UNIVERSAL 0 +#define CURL_ASN1_APPLICATION 1 +#define CURL_ASN1_CONTEXT_SPECIFIC 2 +#define CURL_ASN1_PRIVATE 3 + +/* ASN.1 types. */ +#define CURL_ASN1_BOOLEAN 1 +#define CURL_ASN1_INTEGER 2 +#define CURL_ASN1_BIT_STRING 3 +#define CURL_ASN1_OCTET_STRING 4 +#define CURL_ASN1_NULL 5 +#define CURL_ASN1_OBJECT_IDENTIFIER 6 +#define CURL_ASN1_OBJECT_DESCRIPTOR 7 +#define CURL_ASN1_INSTANCE_OF 8 +#define CURL_ASN1_REAL 9 +#define CURL_ASN1_ENUMERATED 10 +#define CURL_ASN1_EMBEDDED 11 +#define CURL_ASN1_UTF8_STRING 12 +#define CURL_ASN1_RELATIVE_OID 13 +#define CURL_ASN1_SEQUENCE 16 +#define CURL_ASN1_SET 17 +#define CURL_ASN1_NUMERIC_STRING 18 +#define CURL_ASN1_PRINTABLE_STRING 19 +#define CURL_ASN1_TELETEX_STRING 20 +#define CURL_ASN1_VIDEOTEX_STRING 21 +#define CURL_ASN1_IA5_STRING 22 +#define CURL_ASN1_UTC_TIME 23 +#define CURL_ASN1_GENERALIZED_TIME 24 +#define CURL_ASN1_GRAPHIC_STRING 25 +#define CURL_ASN1_VISIBLE_STRING 26 +#define CURL_ASN1_GENERAL_STRING 27 +#define CURL_ASN1_UNIVERSAL_STRING 28 +#define CURL_ASN1_CHARACTER_STRING 29 +#define CURL_ASN1_BMP_STRING 30 + + +/* + * Types. + */ + +/* ASN.1 parsed element. */ +typedef struct { + const char * header; /* Pointer to header byte. */ + const char * beg; /* Pointer to element data. */ + const char * end; /* Pointer to 1st byte after element. */ + unsigned char class; /* ASN.1 element class. */ + unsigned char tag; /* ASN.1 element tag. */ + bool constructed; /* Element is constructed. */ +} curl_asn1Element; + + +/* ASN.1 OID table entry. */ +typedef struct { + const char * numoid; /* Dotted-numeric OID. */ + const char * textoid; /* OID name. */ +} curl_OID; + + +/* X509 certificate: RFC 5280. */ +typedef struct { + curl_asn1Element certificate; + curl_asn1Element version; + curl_asn1Element serialNumber; + curl_asn1Element signatureAlgorithm; + curl_asn1Element signature; + curl_asn1Element issuer; + curl_asn1Element notBefore; + curl_asn1Element notAfter; + curl_asn1Element subject; + curl_asn1Element subjectPublicKeyInfo; + curl_asn1Element subjectPublicKeyAlgorithm; + curl_asn1Element subjectPublicKey; + curl_asn1Element issuerUniqueID; + curl_asn1Element subjectUniqueID; + curl_asn1Element extensions; +} curl_X509certificate; + + +/* + * Prototypes. + */ + +const char *Curl_getASN1Element(curl_asn1Element *elem, + const char *beg, const char *end); +const char *Curl_ASN1tostr(curl_asn1Element *elem, int type); +const char *Curl_DNtostr(curl_asn1Element *dn); +int Curl_parseX509(curl_X509certificate *cert, + const char *beg, const char *end); +CURLcode Curl_extract_certinfo(struct connectdata *conn, int certnum, + const char *beg, const char *end); +CURLcode Curl_verifyhost(struct connectdata *conn, + const char *beg, const char *end); +#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL */ +#endif /* HEADER_CURL_X509ASN1_H */ diff --git a/libcurl/libcurl.vcproj b/libcurl/libcurl.vcproj new file mode 100644 index 0000000..797aa1e --- /dev/null +++ b/libcurl/libcurl.vcproj @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/test.cpp b/test/test.cpp new file mode 100644 index 0000000..7b62d0e --- /dev/null +++ b/test/test.cpp @@ -0,0 +1,3555 @@ +/* + * Xbox libcurl + BearSSL Comprehensive Test Suite + * + * Features: + * - On-screen text display with CURL logo + * - Visual pass/fail indicators + * - Comprehensive protocol testing + * - Verbose SSL/TLS debugging + * - Debug output to XBDM + */ + +#include +#include +#include +#include +#include +#include "xbox_console.h" + +/* BearSSL debug support */ +#include +#include "../BearSSL-OG/ssl_debug.h" +#include "../BearSSL-OG/debug_utility.h" +#include "../BearSSL-OG/session_cache.h" +#include "../BearSSL-OG/cert_pinning.h" + +/* VS2003 compatibility: use _snprintf instead of snprintf */ +#define snprintf _snprintf + +/* + * XboxCurl ASCII Art Logo + Xbox Controller + * Controller art from https://asciiart.website/art/2237 + */ +static const char *curl_logo[] = { + " __ __ _ ____ _", + " \\ \\/ / | |__ ___ __ __ / ___| _ _ _ __| |", + " \\ / | '_ \\ / _ \\ \\ \\/ /| | | | | || '__| |", + " / \\ | |_) || (_) | > < | |___ | |_| || | | |", + " /_/\\_\\ |_.__/ \\___/ /_/\\_\\ \\____| \\__,_||_| |_|", + "", + " libcurl 7.65.3 + BearSSL/0.6 for Original Xbox", + NULL +}; + +/* + * Test result tracking + */ +static int tests_passed = 0; +static int tests_failed = 0; +static int tests_skipped = 0; +static size_t total_bytes_received = 0; + +/* + * Verbose debug logging control + */ +static int g_verbose_ssl = 1; /* Enable verbose SSL debugging */ + +/* + * Write callback for receiving data + */ +static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) +{ + size_t total = size * nmemb; + total_bytes_received += total; + (void)contents; + (void)userp; + return total; +} + +/* + * Write callback for saving data to a file on disk + */ +struct file_write_data { + FILE *fp; + size_t bytes_written; +}; + +static size_t file_write_callback(void *contents, size_t size, size_t nmemb, void *userp) +{ + struct file_write_data *fwd = (struct file_write_data *)userp; + size_t total = size * nmemb; + size_t written; + + if (!fwd || !fwd->fp) return 0; + + written = fwrite(contents, 1, total, fwd->fp); + fwd->bytes_written += written; + total_bytes_received += written; + return written; +} + +/* + * Write callback that captures response body into a buffer for inspection + */ +struct response_data { + char buffer[8192]; + size_t size; +}; + +static size_t capture_callback(void *contents, size_t size, size_t nmemb, void *userp) +{ + struct response_data *rd = (struct response_data *)userp; + size_t total = size * nmemb; + size_t remaining = sizeof(rd->buffer) - rd->size - 1; + size_t copy_size = total < remaining ? total : remaining; + + if (copy_size > 0) { + memcpy(rd->buffer + rd->size, contents, copy_size); + rd->size += copy_size; + rd->buffer[rd->size] = '\0'; + } + total_bytes_received += total; + return total; +} + +/* + * Debug callback for verbose curl logging + * This captures ALL curl operations including SSL handshake details + */ +static int my_curl_debug_callback(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr) +{ + char buf[512]; + char prefix[16]; + size_t i, print_size; + + (void)handle; + (void)userptr; + + switch (type) { + case CURLINFO_TEXT: + snprintf(prefix, sizeof(prefix), "* "); + break; + case CURLINFO_HEADER_IN: + snprintf(prefix, sizeof(prefix), "< "); + break; + case CURLINFO_HEADER_OUT: + snprintf(prefix, sizeof(prefix), "> "); + break; + case CURLINFO_DATA_IN: + if (g_verbose_ssl) { + snprintf(buf, sizeof(buf), "[DATA IN] %u bytes received\n", (unsigned)size); + OutputDebugStringA(buf); + } + return 0; + case CURLINFO_DATA_OUT: + if (g_verbose_ssl) { + snprintf(buf, sizeof(buf), "[DATA OUT] %u bytes sent\n", (unsigned)size); + OutputDebugStringA(buf); + } + return 0; + case CURLINFO_SSL_DATA_IN: + snprintf(buf, sizeof(buf), "[SSL IN] %u bytes\n", (unsigned)size); + OutputDebugStringA(buf); + /* Print first few bytes as hex for debugging */ + if (size > 0 && g_verbose_ssl) { + char hex[128]; + int hex_len = 0; + for (i = 0; i < size && i < 32 && hex_len < 120; i++) { + hex_len += snprintf(hex + hex_len, sizeof(hex) - hex_len, "%02X ", (unsigned char)data[i]); + } + snprintf(buf, sizeof(buf), " HEX: %s%s\n", hex, size > 32 ? "..." : ""); + OutputDebugStringA(buf); + } + return 0; + case CURLINFO_SSL_DATA_OUT: + snprintf(buf, sizeof(buf), "[SSL OUT] %u bytes\n", (unsigned)size); + OutputDebugStringA(buf); + /* Print first few bytes as hex for debugging */ + if (size > 0 && g_verbose_ssl) { + char hex[128]; + int hex_len = 0; + for (i = 0; i < size && i < 32 && hex_len < 120; i++) { + hex_len += snprintf(hex + hex_len, sizeof(hex) - hex_len, "%02X ", (unsigned char)data[i]); + } + snprintf(buf, sizeof(buf), " HEX: %s%s\n", hex, size > 32 ? "..." : ""); + OutputDebugStringA(buf); + } + return 0; + default: + return 0; + } + + /* Print text/header info - handle multiple lines */ + print_size = size; + if (print_size > 400) print_size = 400; + + /* For HEADER_OUT, log the full request so we can see all headers */ + if (type == CURLINFO_HEADER_OUT) { + char header_log[512]; + snprintf(header_log, sizeof(header_log), "\n=== HTTP REQUEST (%u bytes) ===\n", (unsigned)size); + OutputDebugStringA(header_log); + } + + /* Process each line */ + { + size_t pos = 0; + while (pos < print_size) { + /* Copy one line */ + i = 0; + while (pos < print_size && i < sizeof(buf) - 2) { + char c = data[pos++]; + if (c == '\r') continue; /* Skip CR */ + if (c == '\n') break; /* End of line */ + buf[i++] = c; + } + buf[i] = '\0'; + + if (buf[0] != '\0') { + char out[550]; + snprintf(out, sizeof(out), "%s%s\n", prefix, buf); + OutputDebugStringA(out); + + /* Also show important SSL info on console */ + if (type == CURLINFO_TEXT && g_verbose_ssl) { + /* Check for SSL-related messages */ + if (strstr(buf, "SSL") || strstr(buf, "TLS") || + strstr(buf, "ssl") || strstr(buf, "tls") || + strstr(buf, "certificate") || strstr(buf, "handshake") || + strstr(buf, "cipher") || strstr(buf, "error") || + strstr(buf, "Error") || strstr(buf, "fail")) { + xbox_console_set_colors(CONSOLE_COLOR_MAGENTA, CONSOLE_COLOR_BLACK); + xbox_console_printf(" DBG: %s\n", buf); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + xbox_console_present(); + } + } + } + } + } + + if (type == CURLINFO_HEADER_OUT) { + OutputDebugStringA("=== END HTTP REQUEST ===\n"); + } + + return 0; +} + +/* + * Helper to configure verbose debugging on a curl handle + */ +static void setup_verbose_curl(CURL *curl) +{ + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_curl_debug_callback); + curl_easy_setopt(curl, CURLOPT_DEBUGDATA, NULL); +} + +/* + * Display functions + */ +static void display_logo(void) +{ + int i; + + xbox_console_set_colors(CONSOLE_COLOR_CYAN, CONSOLE_COLOR_BLACK); + for (i = 0; curl_logo[i] != NULL; i++) { + xbox_console_println(curl_logo[i]); + } + xbox_console_println(""); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); +} + +static void display_header(const char *title) +{ + xbox_console_println(""); + xbox_console_set_colors(CONSOLE_COLOR_YELLOW, CONSOLE_COLOR_BLACK); + xbox_console_printf(" %s\n", title); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + xbox_console_println(""); + xbox_console_present(); +} + +static void display_test_start(const char *test_name) +{ + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + xbox_console_printf("[ .... ] %s", test_name); + xbox_console_present(); + OutputDebugStringA("Testing: "); + OutputDebugStringA(test_name); + OutputDebugStringA("\n"); +} + +static void display_test_result(int passed, const char *details) +{ + int x, y; + + /* Move cursor back to result position */ + xbox_console_get_cursor(&x, &y); + xbox_console_set_cursor(0, y); + + if (passed) { + xbox_console_set_colors(CONSOLE_COLOR_GREEN, CONSOLE_COLOR_BLACK); + xbox_console_print("[ PASS ]"); + tests_passed++; + } else { + xbox_console_set_colors(CONSOLE_COLOR_RED, CONSOLE_COLOR_BLACK); + xbox_console_print("[ FAIL ]"); + tests_failed++; + } + + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + xbox_console_set_cursor(x, y); + xbox_console_println(""); + + if (details && details[0]) { + xbox_console_set_colors(CONSOLE_COLOR_GRAY, CONSOLE_COLOR_BLACK); + xbox_console_printf(" %s\n", details); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + } + + xbox_console_present(); +} + +static void display_test_skip(const char *reason) +{ + int x, y; + + xbox_console_get_cursor(&x, &y); + xbox_console_set_cursor(0, y); + + xbox_console_set_colors(CONSOLE_COLOR_YELLOW, CONSOLE_COLOR_BLACK); + xbox_console_print("[ SKIP ]"); + tests_skipped++; + + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + xbox_console_set_cursor(x, y); + xbox_console_println(""); + + if (reason && reason[0]) { + xbox_console_set_colors(CONSOLE_COLOR_GRAY, CONSOLE_COLOR_BLACK); + xbox_console_printf(" %s\n", reason); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + } + + xbox_console_present(); +} + +static void display_section(const char *section_name) +{ + xbox_console_println(""); + xbox_console_set_colors(CONSOLE_COLOR_CYAN, CONSOLE_COLOR_BLACK); + xbox_console_printf(" %s\n", section_name); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + xbox_console_present(); +} + +static void display_summary(void) +{ + xbox_console_println(""); + xbox_console_set_colors(CONSOLE_COLOR_YELLOW, CONSOLE_COLOR_BLACK); + xbox_console_println(" TEST RESULTS SUMMARY"); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + + xbox_console_set_colors(CONSOLE_COLOR_GREEN, CONSOLE_COLOR_BLACK); + xbox_console_printf(" Passed: %d\n", tests_passed); + + xbox_console_set_colors(CONSOLE_COLOR_RED, CONSOLE_COLOR_BLACK); + xbox_console_printf(" Failed: %d\n", tests_failed); + + xbox_console_set_colors(CONSOLE_COLOR_YELLOW, CONSOLE_COLOR_BLACK); + xbox_console_printf(" Skipped: %d\n", tests_skipped); + + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + xbox_console_printf(" Total: %d\n", tests_passed + tests_failed + tests_skipped); + + xbox_console_println(""); + if (tests_failed == 0) { + xbox_console_set_colors(CONSOLE_COLOR_GREEN, CONSOLE_COLOR_BLACK); + xbox_console_println(" ALL TESTS PASSED!"); + } else { + xbox_console_set_colors(CONSOLE_COLOR_RED, CONSOLE_COLOR_BLACK); + xbox_console_println(" SOME TESTS FAILED"); + } + + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + xbox_console_present(); +} + +/* + * Network initialization + */ +static int wait_for_network(void) +{ + XNetStartupParams xnsp; + WSADATA wsaData; + XNADDR xnaddr; + int timeout = 30; + + xbox_console_println("Initializing network..."); + xbox_console_present(); + + /* Initialize XNet */ + memset(&xnsp, 0, sizeof(xnsp)); + xnsp.cfgSizeOfStruct = sizeof(XNetStartupParams); + xnsp.cfgFlags = XNET_STARTUP_BYPASS_SECURITY; + xnsp.cfgPrivatePoolSizeInPages = 64; + xnsp.cfgEnetReceiveQueueLength = 16; + xnsp.cfgIpFragMaxSimultaneous = 16; + xnsp.cfgIpFragMaxPacketDiv256 = 32; + xnsp.cfgSockMaxSockets = 64; + xnsp.cfgSockDefaultRecvBufsizeInK = 64; + xnsp.cfgSockDefaultSendBufsizeInK = 64; + + XNetStartup(&xnsp); + WSAStartup(MAKEWORD(2, 2), &wsaData); + + /* Wait for ethernet link */ + xbox_console_print(" Waiting for ethernet link..."); + xbox_console_present(); + while (XNetGetEthernetLinkStatus() == 0) { + Sleep(100); + } + xbox_console_set_colors(CONSOLE_COLOR_GREEN, CONSOLE_COLOR_BLACK); + xbox_console_println(" OK"); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + + /* Wait for DHCP */ + xbox_console_print(" Waiting for DHCP..."); + xbox_console_present(); + while (timeout > 0) { + memset(&xnaddr, 0, sizeof(xnaddr)); + if (XNetGetTitleXnAddr(&xnaddr) != XNET_GET_XNADDR_PENDING) { + break; + } + Sleep(1000); + timeout--; + } + + if (timeout <= 0) { + xbox_console_set_colors(CONSOLE_COLOR_RED, CONSOLE_COLOR_BLACK); + xbox_console_println(" TIMEOUT"); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + return 0; + } + + xbox_console_set_colors(CONSOLE_COLOR_GREEN, CONSOLE_COLOR_BLACK); + xbox_console_println(" OK"); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + + /* Display IP address */ + xbox_console_printf(" IP Address: %d.%d.%d.%d\n", + xnaddr.ina.S_un.S_un_b.s_b1, + xnaddr.ina.S_un.S_un_b.s_b2, + xnaddr.ina.S_un.S_un_b.s_b3, + xnaddr.ina.S_un.S_un_b.s_b4); + + xbox_console_println(""); + xbox_console_present(); + return 1; +} + +/* + * Individual Tests + */ + +/* Test 1: Version Information - VERBOSE */ +static void test_version_info(void) +{ + const char *version; + curl_version_info_data *vinfo; + char details[256]; + char log[512]; + + display_test_start("libcurl version information"); + + version = curl_version(); + vinfo = curl_version_info(CURLVERSION_NOW); + + if (version && vinfo && vinfo->version) { + /* Log extensive version info */ + snprintf(log, sizeof(log), + "\n======= CURL VERSION INFO =======\n" + " Version string: %s\n" + " curl version: %s\n" + " SSL version: %s\n" + " Features: 0x%08lx\n" + " Host: %s\n" + "================================\n", + version, + vinfo->version, + vinfo->ssl_version ? vinfo->ssl_version : "NONE (no SSL!)", + (unsigned long)vinfo->features, + vinfo->host ? vinfo->host : "unknown"); + OutputDebugStringA(log); + + /* Check for SSL support */ + if (vinfo->features & CURL_VERSION_SSL) { + OutputDebugStringA(" [OK] SSL support is enabled\n"); + } else { + OutputDebugStringA(" [WARNING] SSL support is NOT enabled!\n"); + } + + /* Show on console too */ + xbox_console_set_colors(CONSOLE_COLOR_CYAN, CONSOLE_COLOR_BLACK); + xbox_console_printf(" curl: %s\n", vinfo->version); + xbox_console_printf(" SSL: %s\n", vinfo->ssl_version ? vinfo->ssl_version : "NONE!"); + + if (!(vinfo->features & CURL_VERSION_SSL)) { + xbox_console_set_colors(CONSOLE_COLOR_RED, CONSOLE_COLOR_BLACK); + xbox_console_println(" WARNING: No SSL support compiled in!"); + } + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + xbox_console_present(); + + snprintf(details, sizeof(details), "curl %s, SSL: %s", + vinfo->version, + vinfo->ssl_version ? vinfo->ssl_version : "NONE"); + display_test_result(vinfo->ssl_version != NULL, details); + } else { + display_test_result(0, "Failed to get version info"); + } +} + +/* Test 2: HTTP GET (by IP - no DNS) */ +static void test_http_get_by_ip(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[128]; + + display_test_start("HTTP GET (direct IP, no DNS)"); + OutputDebugStringA("DEBUG: Starting HTTP test\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + OutputDebugStringA("DEBUG: curl_easy_init done\n"); + + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + OutputDebugStringA("DEBUG: Setting options\n"); + curl_easy_setopt(curl, CURLOPT_URL, "http://1.1.1.1/"); /* Cloudflare - reliable */ + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15L); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL); + OutputDebugStringA("DEBUG: Options set, calling curl_easy_perform\n"); + + res = curl_easy_perform(curl); + OutputDebugStringA("DEBUG: curl_easy_perform returned\n"); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && response_code >= 200 && response_code < 400) { + snprintf(details, sizeof(details) - 1, "HTTP %ld, %u bytes received", response_code, (unsigned)total_bytes_received); + details[sizeof(details) - 1] = '\0'; + display_test_result(1, details); + } else { + snprintf(details, sizeof(details) - 1, "Error: %s (HTTP %ld)", curl_easy_strerror(res), response_code); + details[sizeof(details) - 1] = '\0'; + display_test_result(0, details); + } +} + +/* Test 3: HTTP GET with DNS */ +static void test_http_get_dns(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[128]; + + display_test_start("HTTP GET (with DNS resolution)"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/get"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15L); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details) - 1, "HTTP %ld, %u bytes received", response_code, (unsigned)total_bytes_received); + details[sizeof(details) - 1] = '\0'; + display_test_result(1, details); + } else { + snprintf(details, sizeof(details) - 1, "Error: %s (HTTP %ld)", curl_easy_strerror(res), response_code); + details[sizeof(details) - 1] = '\0'; + display_test_result(0, details); + } +} + +/* Test 4: HTTPS GET (certificate verification disabled) - VERBOSE */ +static void test_https_get_no_verify(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + char *effective_url = NULL; + long ssl_verify_result = 0; + DWORD start_time, elapsed; + + display_test_start("HTTPS GET (verify disabled)"); + + xbox_console_set_colors(CONSOLE_COLOR_GRAY, CONSOLE_COLOR_BLACK); + xbox_console_println(" Starting HTTPS connection test..."); + xbox_console_present(); + + OutputDebugStringA("\n========== HTTPS TEST (NO VERIFY) START ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + /* Setup verbose debugging */ + setup_verbose_curl(curl); + + OutputDebugStringA("Setting HTTPS options...\n"); + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/get"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); /* Longer timeout for SSL handshake */ + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + /* Try to get more SSL debugging info */ + curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L); + + xbox_console_println(" Performing SSL handshake..."); + xbox_console_present(); + OutputDebugStringA("Calling curl_easy_perform for HTTPS...\n"); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + + OutputDebugStringA("curl_easy_perform returned.\n"); + + /* Get detailed info */ + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url); + curl_easy_getinfo(curl, CURLINFO_SSL_VERIFYRESULT, &ssl_verify_result); + + /* Log everything */ + { + char log[512]; + snprintf(log, sizeof(log), + "HTTPS Result:\n" + " CURLcode: %d (%s)\n" + " HTTP Code: %ld\n" + " SSL Verify: %ld\n" + " Bytes: %u\n" + " Time: %lu ms\n" + " URL: %s\n", + res, curl_easy_strerror(res), + response_code, + ssl_verify_result, + (unsigned)total_bytes_received, + elapsed, + effective_url ? effective_url : "NULL"); + OutputDebugStringA(log); + } + + curl_easy_cleanup(curl); + OutputDebugStringA("========== HTTPS TEST (NO VERIFY) END ==========\n\n"); + + /* Show result on console */ + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), "HTTPS %ld, %u bytes in %lu ms", response_code, (unsigned)total_bytes_received, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error %d: %s (HTTP %ld, %lu ms)", res, curl_easy_strerror(res), response_code, elapsed); + display_test_result(0, details); + + /* Show error details on console */ + xbox_console_set_colors(CONSOLE_COLOR_RED, CONSOLE_COLOR_BLACK); + xbox_console_printf(" SSL verify result: %ld\n", ssl_verify_result); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + xbox_console_present(); + } +} + +/* Test 5: HTTPS GET (certificate verification enabled) - VERBOSE */ +static void test_https_get_with_verify(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + long ssl_verify_result = 0; + DWORD start_time, elapsed; + + display_test_start("HTTPS GET (verify enabled)"); + + xbox_console_set_colors(CONSOLE_COLOR_GRAY, CONSOLE_COLOR_BLACK); + xbox_console_println(" Testing certificate verification..."); + xbox_console_present(); + + OutputDebugStringA("\n========== HTTPS TEST (WITH VERIFY) START ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + /* Setup verbose debugging */ + setup_verbose_curl(curl); + + OutputDebugStringA("Setting HTTPS options with verification...\n"); + curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); + curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L); + + xbox_console_println(" Performing verified SSL handshake..."); + xbox_console_present(); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_getinfo(curl, CURLINFO_SSL_VERIFYRESULT, &ssl_verify_result); + + /* Log everything */ + { + char log[512]; + snprintf(log, sizeof(log), + "HTTPS (Verify) Result:\n" + " CURLcode: %d (%s)\n" + " HTTP Code: %ld\n" + " SSL Verify: %ld\n" + " Bytes: %u\n" + " Time: %lu ms\n", + res, curl_easy_strerror(res), + response_code, + ssl_verify_result, + (unsigned)total_bytes_received, + elapsed); + OutputDebugStringA(log); + } + + curl_easy_cleanup(curl); + OutputDebugStringA("========== HTTPS TEST (WITH VERIFY) END ==========\n\n"); + + if (res == CURLE_OK && response_code >= 200 && response_code < 400) { + snprintf(details, sizeof(details), "HTTPS %ld, cert verified, %lu ms", response_code, elapsed); + display_test_result(1, details); + } else if (res == CURLE_SSL_CACERT || res == CURLE_PEER_FAILED_VERIFICATION) { + snprintf(details, sizeof(details), "Cert verify failed (SSL result: %ld)", ssl_verify_result); + display_test_skip(details); + } else { + snprintf(details, sizeof(details), "Error %d: %s (%lu ms)", res, curl_easy_strerror(res), elapsed); + display_test_result(0, details); + } +} + +/* Test 5-pre: BearSSL Engine Diagnostics */ +static void test_bearssl_diagnostics(void) +{ + br_ssl_client_context sc; + br_x509_minimal_context xc; + char details[256]; + + display_test_start("BearSSL engine initialization"); + + OutputDebugStringA("\n========== BEARSSL DIAGNOSTICS ==========\n"); + + /* Try to initialize BearSSL client context with no trust anchors (for testing) */ + OutputDebugStringA("Initializing br_ssl_client_init_full with NULL trust anchors...\n"); + br_ssl_client_init_full(&sc, &xc, NULL, 0); + + /* Check engine state */ + { + unsigned state = br_ssl_engine_current_state(&sc.eng); + int err = br_ssl_engine_last_error(&sc.eng); + char log[256]; + + snprintf(log, sizeof(log), + "BearSSL state after init:\n" + " State flags: 0x%08x\n" + " Last error: %d\n" + " CLOSED=%d SENDREC=%d RECVREC=%d SENDAPP=%d RECVAPP=%d\n", + state, err, + (state & BR_SSL_CLOSED) ? 1 : 0, + (state & BR_SSL_SENDREC) ? 1 : 0, + (state & BR_SSL_RECVREC) ? 1 : 0, + (state & BR_SSL_SENDAPP) ? 1 : 0, + (state & BR_SSL_RECVAPP) ? 1 : 0); + OutputDebugStringA(log); + + xbox_console_set_colors(CONSOLE_COLOR_CYAN, CONSOLE_COLOR_BLACK); + xbox_console_printf(" BearSSL state: 0x%08x, err: %d\n", state, err); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + xbox_console_present(); + + if (err == BR_ERR_OK) { + snprintf(details, sizeof(details), "Init OK, state=0x%x", state); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Init error: %d", err); + display_test_result(0, details); + } + } + + OutputDebugStringA("========== BEARSSL DIAGNOSTICS END ==========\n\n"); +} + +/* Test 5a: HTTPS to httpbin.org (lenient test server) */ +static void test_https_by_ip(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + + display_test_start("HTTPS to httpbin.org"); + + OutputDebugStringA("\n========== HTTPS HTTPBIN TEST START ==========\n"); + OutputDebugStringA("Testing HTTPS to httpbin.org/get - lenient HTTP/1.1 test server\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + setup_verbose_curl(curl); + + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/get"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + xbox_console_set_colors(CONSOLE_COLOR_GRAY, CONSOLE_COLOR_BLACK); + xbox_console_println(" Connecting to httpbin.org:443..."); + xbox_console_present(); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== HTTPS HTTPBIN TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code >= 200 && response_code < 400) { + snprintf(details, sizeof(details), "HTTPS %ld, %u bytes, %lu ms", response_code, (unsigned)total_bytes_received, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error %d: %s (%lu ms)", res, curl_easy_strerror(res), elapsed); + display_test_result(0, details); + } +} + +/* Test 5b: HTTPS with explicit TLS options */ +static void test_https_tls_options(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + const char *ssl_version_str = "unknown"; + long ssl_version = 0; + + display_test_start("HTTPS TLS version test"); + + OutputDebugStringA("\n========== HTTPS TLS VERSION TEST START ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + setup_verbose_curl(curl); + + /* Try to force TLS 1.2 */ + curl_easy_setopt(curl, CURLOPT_URL, "https://www.howsmyssl.com/a/check"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); + + xbox_console_set_colors(CONSOLE_COLOR_GRAY, CONSOLE_COLOR_BLACK); + xbox_console_println(" Testing TLS 1.2 connection..."); + xbox_console_present(); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + +#ifdef CURLINFO_SSL_VERSION + if (curl_easy_getinfo(curl, CURLINFO_SSL_VERSION, &ssl_version) == CURLE_OK) { + switch (ssl_version) { + case CURL_SSLVERSION_TLSv1_0: ssl_version_str = "TLS 1.0"; break; + case CURL_SSLVERSION_TLSv1_1: ssl_version_str = "TLS 1.1"; break; + case CURL_SSLVERSION_TLSv1_2: ssl_version_str = "TLS 1.2"; break; + case CURL_SSLVERSION_TLSv1_3: ssl_version_str = "TLS 1.3"; break; + default: ssl_version_str = "unknown"; break; + } + } +#endif + + { + char log[256]; + snprintf(log, sizeof(log), "TLS test: code=%d, HTTP=%ld, SSL version=%s, time=%lu ms\n", + res, response_code, ssl_version_str, elapsed); + OutputDebugStringA(log); + } + + curl_easy_cleanup(curl); + OutputDebugStringA("========== HTTPS TLS VERSION TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), "TLS OK, %s, %lu ms", ssl_version_str, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error %d: %s (%lu ms)", res, curl_easy_strerror(res), elapsed); + display_test_result(0, details); + } +} + +/* Test 5c: Simple HTTPS to a minimal endpoint */ +static void test_https_simple(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + + display_test_start("HTTPS simple (example.com)"); + + OutputDebugStringA("\n========== HTTPS SIMPLE TEST START ==========\n"); + OutputDebugStringA("Testing HTTPS to example.com - minimal, reliable endpoint\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + setup_verbose_curl(curl); + + curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + xbox_console_set_colors(CONSOLE_COLOR_GRAY, CONSOLE_COLOR_BLACK); + xbox_console_println(" Connecting to example.com:443..."); + xbox_console_present(); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== HTTPS SIMPLE TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code >= 200 && response_code < 400) { + snprintf(details, sizeof(details), "HTTPS %ld, %u bytes, %lu ms", response_code, (unsigned)total_bytes_received, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error %d: %s (%lu ms)", res, curl_easy_strerror(res), elapsed); + display_test_result(0, details); + } +} + +/* Test 5d: Raw TCP connection test to port 443 using XNet DNS */ +/* Pattern based on Microsoft Xbox source: dnslookup.c and logon.cpp */ +static void test_tcp_port_443(void) +{ + SOCKET sock = INVALID_SOCKET; + struct sockaddr_in server; + XNDNS *pxndns = NULL; + HANDLE hEvent = NULL; + DWORD start_time, elapsed; + char details[256]; + int result; + INT dns_status; + + display_test_start("TCP connect to port 443"); + + OutputDebugStringA("\n========== TCP PORT 443 TEST START ==========\n"); + + /* Create event for async DNS completion (Xbox pattern) */ + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (hEvent == NULL) { + snprintf(details, sizeof(details), "CreateEvent failed: %d", GetLastError()); + display_test_result(0, details); + return; + } + + xbox_console_set_colors(CONSOLE_COLOR_GRAY, CONSOLE_COLOR_BLACK); + xbox_console_println(" Resolving example.com via XNet..."); + xbox_console_present(); + + /* Use Xbox DNS lookup with event notification */ + dns_status = XNetDnsLookup("example.com", hEvent, &pxndns); + if (dns_status != 0) { + snprintf(details, sizeof(details), "XNetDnsLookup failed: %d", dns_status); + OutputDebugStringA(details); + OutputDebugStringA("\n"); + CloseHandle(hEvent); + display_test_result(0, details); + return; + } + + /* Wait for DNS to complete with 10 second timeout (Xbox pattern) */ + OutputDebugStringA("Waiting for DNS lookup to complete...\n"); + if (WaitForSingleObject(hEvent, 10000) == WAIT_TIMEOUT) { + OutputDebugStringA("DNS lookup timed out\n"); + XNetDnsRelease(pxndns); + CloseHandle(hEvent); + display_test_result(0, "DNS lookup timed out"); + return; + } + + /* Check DNS result status */ + { + char log[128]; + snprintf(log, sizeof(log), "DNS iStatus=%d, cina=%d\n", pxndns->iStatus, pxndns->cina); + OutputDebugStringA(log); + } + + if (pxndns->iStatus != 0) { + snprintf(details, sizeof(details), "DNS failed: status=%d (WSAHOST_NOT_FOUND=%d)", + pxndns->iStatus, WSAHOST_NOT_FOUND); + OutputDebugStringA(details); + OutputDebugStringA("\n"); + XNetDnsRelease(pxndns); + CloseHandle(hEvent); + display_test_result(0, details); + return; + } + + if (pxndns->cina == 0) { + XNetDnsRelease(pxndns); + CloseHandle(hEvent); + display_test_result(0, "DNS returned no addresses"); + return; + } + + { + char log[128]; + snprintf(log, sizeof(log), "Resolved to: %d.%d.%d.%d\n", + pxndns->aina[0].S_un.S_un_b.s_b1, + pxndns->aina[0].S_un.S_un_b.s_b2, + pxndns->aina[0].S_un.S_un_b.s_b3, + pxndns->aina[0].S_un.S_un_b.s_b4); + OutputDebugStringA(log); + + xbox_console_printf(" IP: %d.%d.%d.%d\n", + pxndns->aina[0].S_un.S_un_b.s_b1, + pxndns->aina[0].S_un.S_un_b.s_b2, + pxndns->aina[0].S_un.S_un_b.s_b3, + pxndns->aina[0].S_un.S_un_b.s_b4); + xbox_console_present(); + } + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock == INVALID_SOCKET) { + snprintf(details, sizeof(details), "socket() failed: %d", WSAGetLastError()); + XNetDnsRelease(pxndns); + CloseHandle(hEvent); + display_test_result(0, details); + return; + } + + memset(&server, 0, sizeof(server)); + server.sin_family = AF_INET; + server.sin_port = htons(443); + server.sin_addr = pxndns->aina[0]; + + /* Release DNS resources before connect (Xbox pattern) */ + XNetDnsRelease(pxndns); + pxndns = NULL; + + xbox_console_println(" Connecting to port 443..."); + xbox_console_present(); + + start_time = GetTickCount(); + result = connect(sock, (struct sockaddr *)&server, sizeof(server)); + elapsed = GetTickCount() - start_time; + + if (result == 0) { + snprintf(details, sizeof(details), "Connected in %lu ms", elapsed); + OutputDebugStringA("TCP connect to port 443 succeeded\n"); + display_test_result(1, details); + } else { + int err = WSAGetLastError(); + snprintf(details, sizeof(details), "Connect failed: WSA error %d (%lu ms)", err, elapsed); + OutputDebugStringA(details); + OutputDebugStringA("\n"); + display_test_result(0, details); + } + + /* Cleanup (Xbox pattern: always close socket properly) */ + closesocket(sock); + CloseHandle(hEvent); + OutputDebugStringA("========== TCP PORT 443 TEST END ==========\n\n"); +} + +/* Test 6: HTTP POST */ +static void test_http_post(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[128]; + const char *post_data = "name=XboxCurl&version=1.0&platform=Xbox"; + + display_test_start("HTTP POST request"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/post"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details) - 1, "HTTP %ld, POST data sent successfully", response_code); + details[sizeof(details) - 1] = '\0'; + display_test_result(1, details); + } else { + snprintf(details, sizeof(details) - 1, "Error: %s (HTTP %ld)", curl_easy_strerror(res), response_code); + details[sizeof(details) - 1] = '\0'; + display_test_result(0, details); + } +} + +/* Test 7: Custom Headers */ +static void test_custom_headers(void) +{ + CURL *curl; + CURLcode res; + struct curl_slist *headers = NULL; + long response_code = 0; + char details[128]; + + display_test_start("Custom HTTP headers"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + headers = curl_slist_append(headers, "X-Custom-Header: XboxCurlTest"); + headers = curl_slist_append(headers, "User-Agent: XboxCurl/1.0 (Xbox)"); + headers = curl_slist_append(headers, "Accept: application/json"); + + curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/headers"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details) - 1, "HTTP %ld, custom headers sent", response_code); + details[sizeof(details) - 1] = '\0'; + display_test_result(1, details); + } else { + snprintf(details, sizeof(details) - 1, "Error: %s (HTTP %ld)", curl_easy_strerror(res), response_code); + details[sizeof(details) - 1] = '\0'; + display_test_result(0, details); + } +} + +/* Test 8: HTTP Redirects */ +static void test_http_redirects(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + long redirect_count = 0; + char details[128]; + + display_test_start("HTTP redirect following"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/redirect/2"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5L); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &redirect_count); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && response_code == 200 && redirect_count >= 2) { + snprintf(details, sizeof(details) - 1, "HTTP %ld after %ld redirects", response_code, redirect_count); + details[sizeof(details) - 1] = '\0'; + display_test_result(1, details); + } else { + snprintf(details, sizeof(details) - 1, "Error: %s (HTTP %ld, %ld redirects)", + curl_easy_strerror(res), response_code, redirect_count); + details[sizeof(details) - 1] = '\0'; + display_test_result(0, details); + } +} + +/* Test 9: Connection Timeout */ +static void test_connection_timeout(void) +{ + CURL *curl; + CURLcode res; + char details[128]; + DWORD start_time, elapsed; + + display_test_start("Connection timeout handling"); + + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + /* Use a non-routable IP to trigger timeout */ + curl_easy_setopt(curl, CURLOPT_URL, "http://10.255.255.1/"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3L); /* 3 second timeout */ + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_cleanup(curl); + + /* We expect a timeout error */ + if (res == CURLE_OPERATION_TIMEDOUT || res == CURLE_COULDNT_CONNECT) { + snprintf(details, sizeof(details) - 1, "Timeout after %lu ms (expected)", elapsed); + details[sizeof(details) - 1] = '\0'; + display_test_result(1, details); + } else if (res == CURLE_OK) { + display_test_result(0, "Should have timed out but didn't"); + } else { + snprintf(details, sizeof(details) - 1, "Error: %s (%lu ms)", curl_easy_strerror(res), elapsed); + details[sizeof(details) - 1] = '\0'; + display_test_result(1, details); /* Other errors also acceptable */ + } +} + +/* Test 10: Large File Download */ +static void test_large_download(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + double download_size = 0; + char details[128]; + + display_test_start("Large file download (chunked)"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + /* Request a larger response */ + curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/bytes/10000"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &download_size); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && response_code == 200 && total_bytes_received >= 10000) { + snprintf(details, sizeof(details) - 1, "HTTP %ld, %u bytes downloaded", response_code, (unsigned)total_bytes_received); + details[sizeof(details) - 1] = '\0'; + display_test_result(1, details); + } else { + snprintf(details, sizeof(details) - 1, "Error: %s (%u bytes)", curl_easy_strerror(res), (unsigned)total_bytes_received); + details[sizeof(details) - 1] = '\0'; + display_test_result(0, details); + } +} + +/* Test 11: HTTPS POST - VERBOSE */ +static void test_https_post(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + const char *post_data = "{\"test\":\"XboxCurl\",\"secure\":true}"; + struct curl_slist *headers = NULL; + DWORD start_time, elapsed; + + display_test_start("HTTPS POST with JSON"); + + OutputDebugStringA("\n========== HTTPS POST TEST START ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + /* Setup verbose debugging */ + setup_verbose_curl(curl); + + headers = curl_slist_append(headers, "Content-Type: application/json"); + + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/post"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + xbox_console_set_colors(CONSOLE_COLOR_GRAY, CONSOLE_COLOR_BLACK); + xbox_console_println(" Performing HTTPS POST..."); + xbox_console_present(); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + + { + char log[256]; + snprintf(log, sizeof(log), "HTTPS POST: code=%d (%s), HTTP=%ld, time=%lu ms\n", + res, curl_easy_strerror(res), response_code, elapsed); + OutputDebugStringA(log); + } + + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== HTTPS POST TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), "HTTPS %ld, JSON POST OK, %lu ms", response_code, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error %d: %s (HTTP %ld)", res, curl_easy_strerror(res), response_code); + display_test_result(0, details); + } +} + +/* Test 12: User-Agent String */ +static void test_user_agent(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[128]; + + display_test_start("Custom User-Agent string"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/user-agent"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_USERAGENT, "XboxCurl/1.0 (Xbox; BearSSL)"); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details) - 1, "HTTP %ld, User-Agent sent", response_code); + details[sizeof(details) - 1] = '\0'; + display_test_result(1, details); + } else { + snprintf(details, sizeof(details) - 1, "Error: %s (HTTP %ld)", curl_easy_strerror(res), response_code); + details[sizeof(details) - 1] = '\0'; + display_test_result(0, details); + } +} + +/* + * ============================================================================ + * Session Resumption Tests + * ============================================================================ + * These tests verify that TLS session caching and resumption works correctly. + * Session resumption allows subsequent connections to skip the full TLS + * handshake, significantly reducing connection time. + */ + +/* Test: Session Resumption Basic - Verify cache hit on second connection */ +static void test_session_resumption_basic(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + int cache_count_before, cache_count_after; + const char *test_host = "https://httpbin.org/get"; + + display_test_start("Session resumption (basic)"); + + OutputDebugStringA("\n========== SESSION RESUMPTION BASIC TEST ==========\n"); + + /* Clear session cache to start fresh */ + session_cache::clear(); + cache_count_before = session_cache::get_count(); + + OutputDebugStringA("Session cache cleared, starting fresh\n"); + + /* First connection - should be a full handshake */ + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, test_host); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + OutputDebugStringA("First connection (full handshake expected)...\n"); + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + if (res != CURLE_OK || response_code != 200) { + snprintf(details, sizeof(details), "First connection failed: %s (HTTP %ld)", + curl_easy_strerror(res), response_code); + display_test_result(0, details); + return; + } + + /* Check that session was cached */ + cache_count_after = session_cache::get_count(); + { + char log[128]; + snprintf(log, sizeof(log), "Cache count: before=%d, after=%d\n", + cache_count_before, cache_count_after); + OutputDebugStringA(log); + } + + if (cache_count_after <= cache_count_before) { + display_test_result(0, "Session not cached after first connection"); + return; + } + + /* Second connection - should attempt session resumption */ + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed (2nd)"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, test_host); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + OutputDebugStringA("Second connection (session resumption expected)...\n"); + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== SESSION RESUMPTION BASIC TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), "OK, cache entries: %d", cache_count_after); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Second connection failed: %s", curl_easy_strerror(res)); + display_test_result(0, details); + } +} + +/* Test: Session Resumption Timing - Benchmark first vs resumed handshake */ +static void test_session_resumption_timing(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD time_first, time_resumed; + DWORD start_time; + const char *test_host = "https://httpbin.org/get"; + + display_test_start("Session resumption (timing)"); + + OutputDebugStringA("\n========== SESSION RESUMPTION TIMING TEST ==========\n"); + + /* Clear cache for clean timing measurement */ + session_cache::clear(); + + /* First connection - measure full handshake time */ + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, test_host); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + OutputDebugStringA("First connection timing...\n"); + start_time = GetTickCount(); + res = curl_easy_perform(curl); + time_first = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + if (res != CURLE_OK) { + snprintf(details, sizeof(details), "First connection failed: %s", curl_easy_strerror(res)); + display_test_result(0, details); + return; + } + + { + char log[128]; + snprintf(log, sizeof(log), "First connection: %lu ms\n", time_first); + OutputDebugStringA(log); + } + + /* Second connection - measure resumed handshake time */ + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed (2nd)"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, test_host); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + OutputDebugStringA("Second connection timing (resumed)...\n"); + start_time = GetTickCount(); + res = curl_easy_perform(curl); + time_resumed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + { + char log[256]; + int speedup_pct = 0; + if (time_first > 0) { + speedup_pct = (int)(((time_first - time_resumed) * 100) / time_first); + } + snprintf(log, sizeof(log), + "Session Resumption Timing Results:\n" + " First connection: %lu ms (full handshake)\n" + " Second connection: %lu ms (resumed)\n" + " Speedup: %d%%\n", + time_first, time_resumed, speedup_pct); + OutputDebugStringA(log); + } + + OutputDebugStringA("========== SESSION RESUMPTION TIMING TEST END ==========\n\n"); + + if (res == CURLE_OK) { + int speedup_pct = 0; + if (time_first > 0) { + speedup_pct = (int)(((time_first - time_resumed) * 100) / time_first); + } + snprintf(details, sizeof(details), "1st: %lu ms, 2nd: %lu ms (%d%% speedup)", + time_first, time_resumed, speedup_pct); + /* Pass if second connection succeeded (speedup is informational) */ + display_test_result(1, details); + + /* Show timing info on console */ + xbox_console_set_colors(CONSOLE_COLOR_CYAN, CONSOLE_COLOR_BLACK); + xbox_console_printf(" 1st: %lu ms, 2nd: %lu ms\n", time_first, time_resumed); + xbox_console_set_colors(CONSOLE_COLOR_WHITE, CONSOLE_COLOR_BLACK); + xbox_console_present(); + } else { + snprintf(details, sizeof(details), "Resumed connection failed: %s", curl_easy_strerror(res)); + display_test_result(0, details); + } +} + +/* Test: Session Cache Operations - Test cache management functions */ +static void test_session_cache_operations(void) +{ + char details[256]; + int count; + + display_test_start("Session cache operations"); + + OutputDebugStringA("\n========== SESSION CACHE OPERATIONS TEST ==========\n"); + + /* Initialize if not already */ + session_cache::initialize(); + + /* Test clear operation */ + session_cache::clear(); + count = session_cache::get_count(); + if (count != 0) { + snprintf(details, sizeof(details), "Clear failed, count=%d", count); + display_test_result(0, details); + return; + } + OutputDebugStringA("session_cache::clear() - OK\n"); + + /* Test store and count */ + { + br_ssl_session_parameters params; + memset(¶ms, 0, sizeof(params)); + params.session_id_len = 32; /* Set a valid session ID length */ + memset(params.session_id, 0xAB, 32); /* Fill with test data */ + + session_cache::store("test1.example.com", ¶ms); + count = session_cache::get_count(); + if (count != 1) { + snprintf(details, sizeof(details), "Store failed, count=%d (expected 1)", count); + display_test_result(0, details); + return; + } + OutputDebugStringA("session_cache::store() - OK (count=1)\n"); + + /* Store another */ + session_cache::store("test2.example.com", ¶ms); + count = session_cache::get_count(); + if (count != 2) { + snprintf(details, sizeof(details), "Store 2nd failed, count=%d (expected 2)", count); + display_test_result(0, details); + return; + } + OutputDebugStringA("session_cache::store() 2nd - OK (count=2)\n"); + } + + /* Test get operation */ + { + br_ssl_session_parameters retrieved; + memset(&retrieved, 0, sizeof(retrieved)); + + if (!session_cache::get("test1.example.com", &retrieved)) { + display_test_result(0, "Get failed for existing entry"); + return; + } + if (retrieved.session_id_len != 32 || retrieved.session_id[0] != 0xAB) { + display_test_result(0, "Retrieved data doesn't match stored data"); + return; + } + OutputDebugStringA("session_cache::get() - OK\n"); + } + + /* Test remove operation */ + session_cache::remove("test1.example.com"); + count = session_cache::get_count(); + if (count != 1) { + snprintf(details, sizeof(details), "Remove failed, count=%d (expected 1)", count); + display_test_result(0, details); + return; + } + OutputDebugStringA("session_cache::remove() - OK (count=1)\n"); + + /* Final cleanup */ + session_cache::clear(); + + OutputDebugStringA("========== SESSION CACHE OPERATIONS TEST END ==========\n\n"); + + snprintf(details, sizeof(details), "All cache operations passed"); + display_test_result(1, details); +} + +/* + * ============================================================================ + * Certificate Pinning Tests + * ============================================================================ + * These tests verify the certificate pinning infrastructure. + * Note: Full pin verification requires a custom X.509 callback which is not + * yet implemented. These tests verify the API works correctly. + */ + +/* Test: Certificate Pinning API - Test add/remove/has_pin/clear */ +static void test_cert_pinning_api(void) +{ + char details[256]; + unsigned char test_hash[32]; + + display_test_start("Certificate pinning API"); + + OutputDebugStringA("\n========== CERT PINNING API TEST ==========\n"); + + /* Initialize */ + cert_pinning::initialize(); + cert_pinning::clear(); + + /* Create a test hash */ + memset(test_hash, 0x42, 32); + + /* Test add_pin */ + if (!cert_pinning::add_pin("pintest.example.com", test_hash)) { + display_test_result(0, "add_pin failed"); + return; + } + OutputDebugStringA("cert_pinning::add_pin() - OK\n"); + + /* Test has_pin - should return true */ + if (!cert_pinning::has_pin("pintest.example.com")) { + display_test_result(0, "has_pin returned false for pinned host"); + return; + } + OutputDebugStringA("cert_pinning::has_pin() for pinned host - OK\n"); + + /* Test has_pin - should return false for unpinned host */ + if (cert_pinning::has_pin("unpinned.example.com")) { + display_test_result(0, "has_pin returned true for unpinned host"); + return; + } + OutputDebugStringA("cert_pinning::has_pin() for unpinned host - OK\n"); + + /* Test remove_pin */ + cert_pinning::remove_pin("pintest.example.com"); + if (cert_pinning::has_pin("pintest.example.com")) { + display_test_result(0, "has_pin true after remove"); + return; + } + OutputDebugStringA("cert_pinning::remove_pin() - OK\n"); + + /* Test get_pin_hash */ + { + unsigned char retrieved_hash[32]; + if (!cert_pinning::get_pin_hash("pintest.example.com", retrieved_hash)) { + /* We removed the pin above, so re-add for this test */ + cert_pinning::add_pin("pintest.example.com", test_hash); + if (!cert_pinning::get_pin_hash("pintest.example.com", retrieved_hash)) { + display_test_result(0, "get_pin_hash failed"); + return; + } + } + if (memcmp(retrieved_hash, test_hash, 32) != 0) { + display_test_result(0, "get_pin_hash returned wrong hash"); + return; + } + OutputDebugStringA("cert_pinning::get_pin_hash() - OK\n"); + } + + /* Test verify_hash - matching hash should return true */ + if (!cert_pinning::verify_hash("pintest.example.com", test_hash)) { + display_test_result(0, "verify_hash returned false for correct hash"); + return; + } + OutputDebugStringA("cert_pinning::verify_hash() match - OK\n"); + + /* Test verify_hash - wrong hash should return false */ + { + unsigned char wrong_hash[32]; + memset(wrong_hash, 0xFF, 32); + if (cert_pinning::verify_hash("pintest.example.com", wrong_hash)) { + display_test_result(0, "verify_hash returned true for wrong hash"); + return; + } + } + OutputDebugStringA("cert_pinning::verify_hash() mismatch - OK\n"); + + /* Test verify_hash - unpinned host should return true (allow) */ + if (!cert_pinning::verify_hash("nopins.example.com", test_hash)) { + display_test_result(0, "verify_hash returned false for unpinned host"); + return; + } + OutputDebugStringA("cert_pinning::verify_hash() unpinned - OK\n"); + + cert_pinning::remove_pin("pintest.example.com"); + + /* Test adding multiple pins */ + cert_pinning::add_pin("host1.example.com", test_hash); + cert_pinning::add_pin("host2.example.com", test_hash); + cert_pinning::add_pin("host3.example.com", test_hash); + + if (!cert_pinning::has_pin("host1.example.com") || + !cert_pinning::has_pin("host2.example.com") || + !cert_pinning::has_pin("host3.example.com")) { + display_test_result(0, "Multiple pin add failed"); + return; + } + OutputDebugStringA("Multiple pins added - OK\n"); + + /* Test clear */ + cert_pinning::clear(); + if (cert_pinning::has_pin("host1.example.com") || + cert_pinning::has_pin("host2.example.com") || + cert_pinning::has_pin("host3.example.com")) { + display_test_result(0, "Clear failed, pins still exist"); + return; + } + OutputDebugStringA("cert_pinning::clear() - OK\n"); + + OutputDebugStringA("========== CERT PINNING API TEST END ==========\n\n"); + + snprintf(details, sizeof(details), "All pinning API operations passed"); + display_test_result(1, details); +} + +/* Test: Certificate Pinning Rejection - Wrong pin should block connection */ +static void test_cert_pinning_rejection(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + unsigned char wrong_hash[32]; + + display_test_start("Certificate pinning rejection"); + + OutputDebugStringA("\n========== CERT PINNING REJECTION TEST ==========\n"); + + cert_pinning::initialize(); + cert_pinning::clear(); + + /* Add a pin with the WRONG hash - connection should be rejected */ + memset(wrong_hash, 0xDE, 32); + cert_pinning::add_pin("httpbin.org", wrong_hash); + + OutputDebugStringA("Pin added for httpbin.org with WRONG hash - expect rejection\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/get"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + cert_pinning::clear(); + + OutputDebugStringA("========== CERT PINNING REJECTION TEST END ==========\n\n"); + + if (res != CURLE_OK) { + /* Good - connection was rejected due to pin mismatch */ + snprintf(details, sizeof(details), "Rejected as expected: %s", curl_easy_strerror(res)); + display_test_result(1, details); + } else { + /* Bad - wrong pin was accepted */ + snprintf(details, sizeof(details), "ERROR: Wrong pin accepted! HTTP %ld", response_code); + display_test_result(0, details); + } +} + +/* Test: Certificate Pinning Allow - No pin should allow connection */ +static void test_cert_pinning_allow(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + + display_test_start("Certificate pinning (no pin = allow)"); + + OutputDebugStringA("\n========== CERT PINNING ALLOW TEST ==========\n"); + + /* Make sure no pins are set */ + cert_pinning::initialize(); + cert_pinning::clear(); + + OutputDebugStringA("No pins set - connection should succeed\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/get"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== CERT PINNING ALLOW TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), "Allowed as expected, HTTP %ld", response_code); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Failed: %s (HTTP %ld)", + curl_easy_strerror(res), response_code); + display_test_result(0, details); + } +} + +/* + * ============================================================================ + * Expanded HTTPS Tests + * ============================================================================ + */ + +/* Test: HTTPS PUT Request */ +static void test_https_put(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + const char *put_data = "{\"method\":\"PUT\",\"from\":\"XboxCurl\"}"; + struct curl_slist *headers = NULL; + DWORD start_time, elapsed; + + display_test_start("HTTPS PUT request"); + + OutputDebugStringA("\n========== HTTPS PUT TEST ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + setup_verbose_curl(curl); + + headers = curl_slist_append(headers, "Content-Type: application/json"); + + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/put"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, put_data); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== HTTPS PUT TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), "HTTPS PUT %ld, %lu ms", response_code, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error %d: %s (HTTP %ld)", + res, curl_easy_strerror(res), response_code); + display_test_result(0, details); + } +} + +/* Test: HTTPS with Custom Headers */ +static void test_https_custom_headers(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + struct curl_slist *headers = NULL; + DWORD start_time, elapsed; + + display_test_start("HTTPS custom headers"); + + OutputDebugStringA("\n========== HTTPS CUSTOM HEADERS TEST ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + setup_verbose_curl(curl); + + /* Add multiple custom headers */ + headers = curl_slist_append(headers, "X-Xbox-Client: XboxCurl/1.0"); + headers = curl_slist_append(headers, "X-Test-Header: TestValue123"); + headers = curl_slist_append(headers, "Accept: application/json"); + headers = curl_slist_append(headers, "X-Request-ID: xbox-test-001"); + + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/headers"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== HTTPS CUSTOM HEADERS TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), "HTTPS %ld, headers sent, %lu ms", response_code, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error %d: %s (HTTP %ld)", + res, curl_easy_strerror(res), response_code); + display_test_result(0, details); + } +} + +/* Test: HTTPS DELETE Request */ +static void test_https_delete(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + + display_test_start("HTTPS DELETE request"); + + OutputDebugStringA("\n========== HTTPS DELETE TEST ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + setup_verbose_curl(curl); + + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/delete"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== HTTPS DELETE TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), "HTTPS DELETE %ld, %lu ms", response_code, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error %d: %s (HTTP %ld)", + res, curl_easy_strerror(res), response_code); + display_test_result(0, details); + } +} + +/* + * ============================================================================ + * File Upload Tests + * ============================================================================ + * These tests verify multipart form-data file uploads using curl_mime API. + * Uploads are done from memory buffers for simplicity (no test files needed). + */ + +/* Test: HTTP multipart file upload from memory */ +static void test_http_file_upload(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + curl_mime *mime = NULL; + curl_mimepart *part = NULL; + const char *file_data = "Hello from Xbox!\nThis is a test file uploaded via XboxCurl.\nLine 3 of test data.\n"; + size_t file_size = strlen(file_data); + + display_test_start("HTTP multipart file upload"); + + OutputDebugStringA("\n========== HTTP FILE UPLOAD TEST ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + /* Build multipart form with a file field from memory */ + mime = curl_mime_init(curl); + if (!mime) { + curl_easy_cleanup(curl); + display_test_result(0, "curl_mime_init failed"); + return; + } + + part = curl_mime_addpart(mime); + curl_mime_name(part, "file"); + curl_mime_data(part, file_data, file_size); + curl_mime_filename(part, "xbox_test.txt"); + curl_mime_type(part, "text/plain"); + + /* Add a regular form field alongside the file */ + part = curl_mime_addpart(mime); + curl_mime_name(part, "description"); + curl_mime_data(part, "Uploaded from Original Xbox via XboxCurl", CURL_ZERO_TERMINATED); + + curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/post"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15L); + curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + + curl_mime_free(mime); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== HTTP FILE UPLOAD TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), "HTTP %ld, uploaded %u bytes", + response_code, (unsigned)file_size); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error: %s (HTTP %ld)", + curl_easy_strerror(res), response_code); + display_test_result(0, details); + } +} + +/* Test: HTTPS multipart file upload from memory */ +static void test_https_file_upload(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + curl_mime *mime = NULL; + curl_mimepart *part = NULL; + DWORD start_time, elapsed; + + /* Binary test data (simulates a small binary file) */ + unsigned char bin_data[256]; + int i; + for (i = 0; i < 256; i++) bin_data[i] = (unsigned char)i; + + display_test_start("HTTPS multipart file upload"); + + OutputDebugStringA("\n========== HTTPS FILE UPLOAD TEST ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + setup_verbose_curl(curl); + + mime = curl_mime_init(curl); + if (!mime) { + curl_easy_cleanup(curl); + display_test_result(0, "curl_mime_init failed"); + return; + } + + /* File field: binary data */ + part = curl_mime_addpart(mime); + curl_mime_name(part, "file"); + curl_mime_data(part, (const char *)bin_data, sizeof(bin_data)); + curl_mime_filename(part, "test_binary.bin"); + curl_mime_type(part, "application/octet-stream"); + + /* Text field: text file from memory */ + part = curl_mime_addpart(mime); + curl_mime_name(part, "readme"); + curl_mime_data(part, "XboxCurl HTTPS upload test\n", CURL_ZERO_TERMINATED); + curl_mime_filename(part, "readme.txt"); + curl_mime_type(part, "text/plain"); + + /* Regular form field */ + part = curl_mime_addpart(mime); + curl_mime_name(part, "platform"); + curl_mime_data(part, "Xbox", CURL_ZERO_TERMINATED); + + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/post"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); + + xbox_console_set_colors(CONSOLE_COLOR_GRAY, CONSOLE_COLOR_BLACK); + xbox_console_println(" Uploading via HTTPS..."); + xbox_console_present(); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + + curl_mime_free(mime); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== HTTPS FILE UPLOAD TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), "HTTPS %ld, uploaded 256+27 bytes, %lu ms", + response_code, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error %d: %s (HTTP %ld, %lu ms)", + res, curl_easy_strerror(res), response_code, elapsed); + display_test_result(0, details); + } +} + +/* Test: Large multipart upload with multiple fields */ +static void test_large_file_upload(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + curl_mime *mime = NULL; + curl_mimepart *part = NULL; + DWORD start_time, elapsed; + + /* Generate a 4KB test payload */ + char large_buf[4096]; + int i; + for (i = 0; i < (int)sizeof(large_buf); i++) { + large_buf[i] = 'A' + (i % 26); + } + + display_test_start("Large file upload (4KB)"); + + OutputDebugStringA("\n========== LARGE FILE UPLOAD TEST ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { + display_test_result(0, "curl_easy_init failed"); + return; + } + + mime = curl_mime_init(curl); + if (!mime) { + curl_easy_cleanup(curl); + display_test_result(0, "curl_mime_init failed"); + return; + } + + part = curl_mime_addpart(mime); + curl_mime_name(part, "largefile"); + curl_mime_data(part, large_buf, sizeof(large_buf)); + curl_mime_filename(part, "large_test.dat"); + curl_mime_type(part, "application/octet-stream"); + + curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/post"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15L); + curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + + curl_mime_free(mime); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== LARGE FILE UPLOAD TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), "HTTP %ld, uploaded 4096 bytes, %lu ms", + response_code, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error: %s (HTTP %ld, %lu ms)", + curl_easy_strerror(res), response_code, elapsed); + display_test_result(0, details); + } +} + +/* + * Test: HTTPS file download to disk + * Downloads a file from xbxbx.ams1.ppn.prutzel.com and saves it to T:\ drive + */ +static void test_https_file_download(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + struct file_write_data fwd; + const char *save_path = "T:\\Eeprom Reader Tools.rar"; + const char *url = "https://xbxbx.ams1.ppn.prutzel.com/" + "?file=community_uploads/xbox_software/" + "Eeprom%20Reader%20Tools.rar"; + + display_test_start("HTTPS file download to T:\\"); + + OutputDebugStringA("\n========== HTTPS FILE DOWNLOAD TEST START ==========\n"); + + total_bytes_received = 0; + memset(&fwd, 0, sizeof(fwd)); + + fwd.fp = fopen(save_path, "wb"); + if (!fwd.fp) { + snprintf(details, sizeof(details), "Failed to open %s for writing", save_path); + display_test_result(0, details); + return; + } + + curl = curl_easy_init(); + if (!curl) { + fclose(fwd.fp); + display_test_result(0, "curl_easy_init failed"); + return; + } + + setup_verbose_curl(curl); + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, file_write_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fwd); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 120L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5L); + + xbox_console_set_colors(CONSOLE_COLOR_GRAY, CONSOLE_COLOR_BLACK); + xbox_console_println(" Downloading Eeprom Reader Tools.rar..."); + xbox_console_present(); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + fclose(fwd.fp); + + if (res == CURLE_OK && response_code == 200 && fwd.bytes_written > 0) { + snprintf(details, sizeof(details), + "Saved %u bytes to T:\\ (%lu ms)", + (unsigned)fwd.bytes_written, elapsed); + display_test_result(1, details); + } else { + /* Remove incomplete file */ + remove(save_path); + snprintf(details, sizeof(details), + "Error %d (HTTP %ld): %s (%lu ms)", + res, response_code, curl_easy_strerror(res), elapsed); + display_test_result(0, details); + } + + OutputDebugStringA("========== HTTPS FILE DOWNLOAD TEST END ==========\n\n"); +} + +/* + * ============================================================================ + * Extended Download Tests + * ============================================================================ + */ + +/* Download exact number of random bytes over HTTPS, verify size */ +static void test_download_binary_exact(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + + display_test_start("HTTPS binary download (5000 bytes)"); + + OutputDebugStringA("\n========== BINARY DOWNLOAD TEST START ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/bytes/5000"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== BINARY DOWNLOAD TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200 && total_bytes_received == 5000) { + snprintf(details, sizeof(details), "Got exactly 5000 bytes (%lu ms)", elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Expected 5000, got %u (err %d, HTTP %ld)", + (unsigned)total_bytes_received, res, response_code); + display_test_result(0, details); + } +} + +/* Download streamed bytes (chunked transfer encoding) */ +static void test_download_stream_bytes(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + + display_test_start("HTTPS streamed download (8KB chunked)"); + + OutputDebugStringA("\n========== STREAM BYTES TEST START ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + curl_easy_setopt(curl, CURLOPT_URL, + "https://httpbin.org/stream-bytes/8192?chunk_size=1024"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== STREAM BYTES TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200 && total_bytes_received >= 8192) { + snprintf(details, sizeof(details), "Streamed %u bytes in chunks (%lu ms)", + (unsigned)total_bytes_received, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Got %u bytes (err %d, HTTP %ld)", + (unsigned)total_bytes_received, res, response_code); + display_test_result(0, details); + } +} + +/* Large HTTPS download - 100KB binary, measure throughput */ +static void test_download_large_https(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + double speed; + + display_test_start("HTTPS large download (100KB)"); + + OutputDebugStringA("\n========== LARGE HTTPS DOWNLOAD TEST START ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/bytes/102400"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 120L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== LARGE HTTPS DOWNLOAD TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200 && total_bytes_received >= 102400) { + speed = (elapsed > 0) ? (double)total_bytes_received / elapsed : 0.0; + snprintf(details, sizeof(details), "%u bytes, %lu ms (%.1f KB/s)", + (unsigned)total_bytes_received, elapsed, speed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Got %u of 102400 (err %d, HTTP %ld)", + (unsigned)total_bytes_received, res, response_code); + display_test_result(0, details); + } +} + +/* Download binary to file on T:\ drive */ +static void test_download_binary_to_file(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + struct file_write_data fwd; + const char *save_path = "T:\\download_test.bin"; + + display_test_start("HTTPS download binary to file"); + + OutputDebugStringA("\n========== DOWNLOAD TO FILE TEST START ==========\n"); + + total_bytes_received = 0; + memset(&fwd, 0, sizeof(fwd)); + + fwd.fp = fopen(save_path, "wb"); + if (!fwd.fp) { + display_test_result(0, "Failed to open T:\\download_test.bin"); + return; + } + + curl = curl_easy_init(); + if (!curl) { fclose(fwd.fp); display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/bytes/16384"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, file_write_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fwd); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + fclose(fwd.fp); + + OutputDebugStringA("========== DOWNLOAD TO FILE TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200 && fwd.bytes_written == 16384) { + snprintf(details, sizeof(details), "Wrote 16384 bytes to T:\\ (%lu ms)", elapsed); + display_test_result(1, details); + } else { + remove(save_path); + snprintf(details, sizeof(details), "Wrote %u (err %d, HTTP %ld)", + (unsigned)fwd.bytes_written, res, response_code); + display_test_result(0, details); + } + /* Clean up test file */ + remove(save_path); +} + +/* HTTPS redirect chain - follow 3 redirects to final /get */ +static void test_download_redirect_chain(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + long redirect_count = 0; + char details[256]; + DWORD start_time, elapsed; + + display_test_start("HTTPS redirect chain (3 hops)"); + + OutputDebugStringA("\n========== REDIRECT CHAIN TEST START ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/redirect/3"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10L); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &redirect_count); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== REDIRECT CHAIN TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200 && redirect_count == 3) { + snprintf(details, sizeof(details), + "Followed %ld redirects, %u bytes (%lu ms)", + redirect_count, (unsigned)total_bytes_received, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), + "%ld redirects, HTTP %ld, err %d (%lu ms)", + redirect_count, response_code, res, elapsed); + display_test_result(0, details); + } +} + +/* HTTPS Range request - partial content download (HTTP 206) */ +static void test_download_range_request(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + + display_test_start("HTTPS range request (partial)"); + + OutputDebugStringA("\n========== RANGE REQUEST TEST START ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + /* httpbin /range/1024 supports Range header and returns 206 */ + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/range/1024"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_RANGE, "0-511"); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== RANGE REQUEST TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 206 && total_bytes_received == 512) { + snprintf(details, sizeof(details), "HTTP 206, got 512 of 1024 bytes (%lu ms)", elapsed); + display_test_result(1, details); + } else if (res == CURLE_OK && response_code == 200) { + /* Server may ignore Range header - still a pass if we got data */ + snprintf(details, sizeof(details), "HTTP 200 (Range ignored), %u bytes (%lu ms)", + (unsigned)total_bytes_received, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "HTTP %ld, %u bytes, err %d", + response_code, (unsigned)total_bytes_received, res); + display_test_result(0, details); + } +} + +/* Download and verify content - GET /get echoes request details as JSON */ +static void test_download_verify_content(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + struct response_data rd; + struct curl_slist *headers = NULL; + + display_test_start("HTTPS download + verify content"); + + OutputDebugStringA("\n========== DOWNLOAD VERIFY TEST START ==========\n"); + + memset(&rd, 0, sizeof(rd)); + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + headers = curl_slist_append(headers, "X-Xbox-Verify: TestToken42"); + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/get"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, capture_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rd); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + curl_slist_free_all(headers); + + OutputDebugStringA("========== DOWNLOAD VERIFY TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + /* Verify the server echoed our custom header in the JSON response */ + if (strstr(rd.buffer, "TestToken42") != NULL) { + snprintf(details, sizeof(details), + "Verified echo, %u bytes (%lu ms)", (unsigned)rd.size, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), + "Header not echoed back (%u bytes)", (unsigned)rd.size); + display_test_result(0, details); + } + } else { + snprintf(details, sizeof(details), "Error %d, HTTP %ld", res, response_code); + display_test_result(0, details); + } +} + +/* + * ============================================================================ + * Extended Upload Tests + * ============================================================================ + */ + +/* HTTPS POST with URL-encoded form data */ +static void test_upload_urlencoded(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + struct response_data rd; + + display_test_start("HTTPS POST url-encoded form"); + + OutputDebugStringA("\n========== URLENCODED POST TEST START ==========\n"); + + memset(&rd, 0, sizeof(rd)); + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/post"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, capture_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rd); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, + "platform=Xbox&library=XboxCurl&tls=BearSSL&test=urlencoded"); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== URLENCODED POST TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + /* Verify server parsed our form fields */ + if (strstr(rd.buffer, "XboxCurl") && strstr(rd.buffer, "BearSSL")) { + snprintf(details, sizeof(details), "Form data echoed, %lu ms", elapsed); + display_test_result(1, details); + } else { + display_test_result(0, "Form data not echoed in response"); + } + } else { + snprintf(details, sizeof(details), "Error %d, HTTP %ld", res, response_code); + display_test_result(0, details); + } +} + +/* HTTPS PUT with large binary payload */ +static void test_upload_put_large(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + struct curl_slist *headers = NULL; + + /* Generate 16KB binary payload */ + unsigned char payload[16384]; + int i; + for (i = 0; i < (int)sizeof(payload); i++) + payload[i] = (unsigned char)(i * 7 + 13); + + display_test_start("HTTPS PUT large binary (16KB)"); + + OutputDebugStringA("\n========== LARGE PUT TEST START ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + headers = curl_slist_append(headers, "Content-Type: application/octet-stream"); + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/put"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (char *)payload); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)sizeof(payload)); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + curl_slist_free_all(headers); + + OutputDebugStringA("========== LARGE PUT TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), "PUT 16384 bytes, HTTP %ld (%lu ms)", + response_code, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error %d: %s (HTTP %ld)", + res, curl_easy_strerror(res), response_code); + display_test_result(0, details); + } +} + +/* HTTPS PATCH request */ +static void test_upload_patch(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + struct curl_slist *headers = NULL; + const char *patch_data = "{\"op\":\"replace\",\"path\":\"/name\",\"value\":\"Xbox\"}"; + struct response_data rd; + + display_test_start("HTTPS PATCH request"); + + OutputDebugStringA("\n========== PATCH TEST START ==========\n"); + + memset(&rd, 0, sizeof(rd)); + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + headers = curl_slist_append(headers, "Content-Type: application/json"); + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/patch"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, capture_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rd); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, patch_data); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + curl_slist_free_all(headers); + + OutputDebugStringA("========== PATCH TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200 && strstr(rd.buffer, "replace")) { + snprintf(details, sizeof(details), "PATCH echoed, HTTP %ld (%lu ms)", + response_code, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error %d, HTTP %ld", res, response_code); + display_test_result(0, details); + } +} + +/* HTTPS multipart upload with multiple files + verify echo */ +static void test_upload_multipart_verified(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + curl_mime *mime = NULL; + curl_mimepart *part = NULL; + struct response_data rd; + + /* Generate distinct test payloads */ + char text_file[] = "Line 1: XboxCurl multipart test\n" + "Line 2: This is file A\n" + "Line 3: Verifying multi-file upload\n"; + unsigned char bin_file[512]; + int i; + for (i = 0; i < (int)sizeof(bin_file); i++) + bin_file[i] = (unsigned char)(i ^ 0xAA); + + display_test_start("HTTPS multipart multi-file upload"); + + OutputDebugStringA("\n========== MULTIPART VERIFIED TEST START ==========\n"); + + memset(&rd, 0, sizeof(rd)); + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + + mime = curl_mime_init(curl); + if (!mime) { curl_easy_cleanup(curl); display_test_result(0, "mime_init failed"); return; } + + /* File 1: text file */ + part = curl_mime_addpart(mime); + curl_mime_name(part, "textfile"); + curl_mime_data(part, text_file, CURL_ZERO_TERMINATED); + curl_mime_filename(part, "notes.txt"); + curl_mime_type(part, "text/plain"); + + /* File 2: binary file */ + part = curl_mime_addpart(mime); + curl_mime_name(part, "binfile"); + curl_mime_data(part, (const char *)bin_file, sizeof(bin_file)); + curl_mime_filename(part, "data.bin"); + curl_mime_type(part, "application/octet-stream"); + + /* File 3: JSON config */ + part = curl_mime_addpart(mime); + curl_mime_name(part, "config"); + curl_mime_data(part, "{\"console\":\"Xbox\",\"version\":1}", CURL_ZERO_TERMINATED); + curl_mime_filename(part, "config.json"); + curl_mime_type(part, "application/json"); + + /* Form field */ + part = curl_mime_addpart(mime); + curl_mime_name(part, "uploader"); + curl_mime_data(part, "XboxCurl-TestSuite", CURL_ZERO_TERMINATED); + + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/post"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, capture_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rd); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_mime_free(mime); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== MULTIPART VERIFIED TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + /* httpbin echoes multipart data keyed by field name (not filename). + * Check for field names and content strings in the JSON response. */ + int has_text = (strstr(rd.buffer, "textfile") != NULL); + int has_bin = (strstr(rd.buffer, "binfile") != NULL); + int has_json = (strstr(rd.buffer, "config") != NULL); + int has_form = (strstr(rd.buffer, "XboxCurl-TestSuite") != NULL); + + if (has_text && has_bin && has_json && has_form) { + snprintf(details, sizeof(details), + "3 files + 1 field echoed (%lu ms)", elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), + "Missing: %s%s%s%s", + has_text ? "" : "text ", + has_bin ? "" : "bin ", + has_json ? "" : "json ", + has_form ? "" : "form"); + display_test_result(0, details); + } + } else { + snprintf(details, sizeof(details), "Error %d: %s (HTTP %ld)", + res, curl_easy_strerror(res), response_code); + display_test_result(0, details); + } +} + +/* HTTPS POST large JSON payload (16KB) and verify echo */ +static void test_upload_large_json(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + struct curl_slist *headers = NULL; + struct response_data rd; + + /* Build a ~2KB JSON payload with array of items */ + char json_buf[2048]; + int pos, item; + + pos = snprintf(json_buf, sizeof(json_buf), "{\"source\":\"Xbox\",\"items\":["); + for (item = 0; item < 40 && pos < (int)sizeof(json_buf) - 64; item++) { + if (item > 0) json_buf[pos++] = ','; + pos += snprintf(json_buf + pos, sizeof(json_buf) - pos, + "{\"id\":%d,\"name\":\"item_%d\",\"value\":%d}", + item, item, item * 17 + 42); + } + pos += snprintf(json_buf + pos, sizeof(json_buf) - pos, "]}"); + json_buf[sizeof(json_buf) - 1] = '\0'; + + display_test_start("HTTPS POST large JSON"); + + OutputDebugStringA("\n========== LARGE JSON POST TEST START ==========\n"); + + memset(&rd, 0, sizeof(rd)); + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + headers = curl_slist_append(headers, "Content-Type: application/json"); + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/post"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, capture_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rd); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_buf); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + curl_slist_free_all(headers); + + OutputDebugStringA("========== LARGE JSON POST TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + /* Verify the JSON was echoed (httpbin puts it in "data" or "json" field) */ + if (strstr(rd.buffer, "item_0") && strstr(rd.buffer, "item_39")) { + snprintf(details, sizeof(details), + "Sent %u bytes JSON, echoed OK (%lu ms)", + (unsigned)strlen(json_buf), elapsed); + display_test_result(1, details); + } else { + display_test_result(0, "JSON not fully echoed in response"); + } + } else { + snprintf(details, sizeof(details), "Error %d: %s (HTTP %ld)", + res, curl_easy_strerror(res), response_code); + display_test_result(0, details); + } +} + +/* HTTPS upload from file on disk - read T:\cacert.pem and POST it */ +static void test_upload_from_disk(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + curl_mime *mime = NULL; + curl_mimepart *part = NULL; + FILE *fp; + char read_buf[4096]; + size_t file_bytes; + + display_test_start("HTTPS upload file from T:\\ disk"); + + OutputDebugStringA("\n========== UPLOAD FROM DISK TEST START ==========\n"); + + /* Read first 4KB of cacert.pem from disk */ + fp = fopen("T:\\cacert.pem", "rb"); + if (!fp) { + display_test_result(0, "Cannot open T:\\cacert.pem for reading"); + return; + } + file_bytes = fread(read_buf, 1, sizeof(read_buf), fp); + fclose(fp); + + if (file_bytes == 0) { + display_test_result(0, "T:\\cacert.pem is empty"); + return; + } + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + + mime = curl_mime_init(curl); + if (!mime) { curl_easy_cleanup(curl); display_test_result(0, "mime_init failed"); return; } + + /* Upload the file chunk as a multipart attachment */ + part = curl_mime_addpart(mime); + curl_mime_name(part, "certfile"); + curl_mime_data(part, read_buf, file_bytes); + curl_mime_filename(part, "cacert_snippet.pem"); + curl_mime_type(part, "application/x-pem-file"); + + part = curl_mime_addpart(mime); + curl_mime_name(part, "source"); + curl_mime_data(part, "Xbox T:\\ drive", CURL_ZERO_TERMINATED); + + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/post"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_mime_free(mime); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== UPLOAD FROM DISK TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + snprintf(details, sizeof(details), + "Uploaded %u bytes from disk (%lu ms)", + (unsigned)file_bytes, elapsed); + display_test_result(1, details); + } else { + snprintf(details, sizeof(details), "Error %d: %s (HTTP %ld)", + res, curl_easy_strerror(res), response_code); + display_test_result(0, details); + } +} + +/* HTTP error status handling - verify we handle 404 gracefully */ +static void test_download_error_status(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + + display_test_start("HTTPS error handling (404)"); + + OutputDebugStringA("\n========== ERROR STATUS TEST START ==========\n"); + + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/status/404"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + + OutputDebugStringA("========== ERROR STATUS TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 404) { + display_test_result(1, "Correctly received HTTP 404"); + } else { + snprintf(details, sizeof(details), "Expected 404, got HTTP %ld (err %d)", + response_code, res); + display_test_result(0, details); + } +} + +/* Round-trip test: upload data, capture response, verify it matches */ +static void test_upload_roundtrip_verify(void) +{ + CURL *curl; + CURLcode res; + long response_code = 0; + char details[256]; + DWORD start_time, elapsed; + struct curl_slist *headers = NULL; + struct response_data rd; + const char *test_string = "XboxCurl-RoundTrip-Verification-12345-ABCDE"; + + display_test_start("HTTPS upload round-trip verify"); + + OutputDebugStringA("\n========== ROUNDTRIP VERIFY TEST START ==========\n"); + + memset(&rd, 0, sizeof(rd)); + total_bytes_received = 0; + curl = curl_easy_init(); + if (!curl) { display_test_result(0, "curl_easy_init failed"); return; } + + setup_verbose_curl(curl); + headers = curl_slist_append(headers, "Content-Type: text/plain"); + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/post"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, capture_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rd); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, test_string); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + start_time = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start_time; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + curl_easy_cleanup(curl); + curl_slist_free_all(headers); + + OutputDebugStringA("========== ROUNDTRIP VERIFY TEST END ==========\n\n"); + + if (res == CURLE_OK && response_code == 200) { + /* httpbin echoes POST body in "data" field */ + if (strstr(rd.buffer, test_string) != NULL) { + snprintf(details, sizeof(details), + "Round-trip verified (%u bytes, %lu ms)", + (unsigned)rd.size, elapsed); + display_test_result(1, details); + } else { + display_test_result(0, "Sent data not found in response"); + } + } else { + snprintf(details, sizeof(details), "Error %d: %s (HTTP %ld)", + res, curl_easy_strerror(res), response_code); + display_test_result(0, details); + } +} + +/* + * D3D Diagnostic Test + */ +static void test_d3d_diagnostic(void) +{ + IDirect3D8 *d3d = NULL; + IDirect3DDevice8 *device = NULL; + D3DPRESENT_PARAMETERS d3dpp; + HRESULT hr; + + OutputDebugStringA("\n=== D3D DIAGNOSTIC TEST ===\n"); + + d3d = Direct3DCreate8(D3D_SDK_VERSION); + if (!d3d) { + OutputDebugStringA("[FAIL] Direct3DCreate8 failed\n"); + return; + } + OutputDebugStringA("[PASS] Direct3DCreate8 OK\n"); + + ZeroMemory(&d3dpp, sizeof(d3dpp)); + d3dpp.BackBufferWidth = 640; + d3dpp.BackBufferHeight = 480; + d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; /* Standard swizzled format */ + d3dpp.BackBufferCount = 1; + d3dpp.EnableAutoDepthStencil = FALSE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.FullScreen_RefreshRateInHz = 60; + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; + + hr = d3d->CreateDevice(0, D3DDEVTYPE_HAL, NULL, + D3DCREATE_HARDWARE_VERTEXPROCESSING, + &d3dpp, &device); + if (FAILED(hr)) { + char buf[64]; + _snprintf(buf, sizeof(buf) - 1, "[FAIL] CreateDevice: 0x%08X\n", hr); + buf[sizeof(buf) - 1] = '\0'; + OutputDebugStringA(buf); + d3d->Release(); + return; + } + OutputDebugStringA("[PASS] CreateDevice OK\n"); + + /* Clear with BeginScene/EndScene for proper GPU sync */ + hr = device->BeginScene(); + if (FAILED(hr)) { + char buf[64]; + _snprintf(buf, sizeof(buf) - 1, "[FAIL] BeginScene: 0x%08X\n", hr); + buf[sizeof(buf) - 1] = '\0'; + OutputDebugStringA(buf); + } + + hr = device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0); + if (FAILED(hr)) { + char buf[64]; + _snprintf(buf, sizeof(buf) - 1, "[FAIL] Clear: 0x%08X\n", hr); + buf[sizeof(buf) - 1] = '\0'; + OutputDebugStringA(buf); + } else { + OutputDebugStringA("[PASS] Clear OK\n"); + } + + device->EndScene(); + + hr = device->Present(NULL, NULL, NULL, NULL); + if (FAILED(hr)) { + char buf[64]; + _snprintf(buf, sizeof(buf) - 1, "[FAIL] Present: 0x%08X\n", hr); + buf[sizeof(buf) - 1] = '\0'; + OutputDebugStringA(buf); + } else { + OutputDebugStringA("[PASS] Present OK - should see BLUE screen\n"); + } + + OutputDebugStringA("Waiting 3 seconds to view blue screen...\n"); + Sleep(3000); + + /* Second frame - green */ + device->BeginScene(); + device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0); + device->EndScene(); + device->Present(NULL, NULL, NULL, NULL); + OutputDebugStringA("[INFO] Should see GREEN screen now\n"); + Sleep(2000); + + /* Clean up */ + device->Release(); + d3d->Release(); + OutputDebugStringA("[PASS] D3D cleanup OK\n"); + OutputDebugStringA("D3D diagnostic complete\n\n"); +} + +/* + * Main entry point + */ +void __cdecl main(void) +{ + /* Run D3D diagnostic first */ + test_d3d_diagnostic(); + + /* Initialize console for on-screen display */ + OutputDebugStringA("Initializing xbox_console...\n"); + if (!xbox_console_init(640, 480)) { + OutputDebugStringA("FATAL: Failed to initialize console\n"); + for (;;) Sleep(1000); + } + OutputDebugStringA("xbox_console_init OK\n"); + + /* Clear and show logo */ + xbox_console_clear(CONSOLE_COLOR_BLACK); + display_logo(); + display_header("Xbox libcurl + BearSSL Test Suite"); + + /* Initialize network */ + if (!wait_for_network()) { + xbox_console_set_colors(CONSOLE_COLOR_RED, CONSOLE_COLOR_BLACK); + xbox_console_println("FATAL: Network initialization failed!"); + xbox_console_println("Check ethernet cable and DHCP server."); + xbox_console_present(); + for (;;) Sleep(1000); + } + + /* Initialize libcurl */ + xbox_console_println("Initializing libcurl..."); + xbox_console_present(); + curl_global_init(CURL_GLOBAL_DEFAULT); + + /* Enable verbose BearSSL debugging */ + xbox_console_println("Enabling verbose SSL debugging..."); + xbox_console_present(); + ssl_debug::set_level(SSL_DEBUG_VERBOSE); + OutputDebugStringA("BearSSL debug level set to VERBOSE\n"); + + /* Run test suite */ + display_section("Basic Tests"); + test_version_info(); + test_http_get_by_ip(); + test_http_get_dns(); + + display_section("HTTPS/TLS Tests"); + test_bearssl_diagnostics(); /* BearSSL engine test */ + test_tcp_port_443(); /* First verify raw TCP to 443 works */ + test_https_by_ip(); /* Test HTTPS without DNS/SNI */ + test_https_simple(); /* Test simple endpoint */ + test_https_get_no_verify(); + test_https_tls_options(); /* Test TLS version negotiation */ + test_https_get_with_verify(); + test_https_post(); + + display_section("HTTP Features"); + test_http_post(); + test_custom_headers(); + test_user_agent(); + test_http_redirects(); + + display_section("Advanced Tests"); + test_large_download(); + test_connection_timeout(); + + display_section("Session Resumption Tests"); + test_session_cache_operations(); /* Test cache API first */ + test_session_resumption_basic(); /* Verify cache hit */ + test_session_resumption_timing(); /* Benchmark speedup */ + + display_section("Certificate Pinning Tests"); + test_cert_pinning_api(); /* Test pinning API */ + test_cert_pinning_rejection(); /* Wrong pin should reject */ + test_cert_pinning_allow(); /* No pin should allow */ + + display_section("File Upload Tests"); + test_http_file_upload(); /* HTTP multipart upload */ + test_https_file_upload(); /* HTTPS multipart upload */ + test_large_file_upload(); /* 4KB upload */ + + display_section("Expanded HTTPS Tests"); + test_https_put(); /* HTTPS PUT */ + test_https_custom_headers(); /* HTTPS custom headers */ + test_https_delete(); /* HTTPS DELETE */ + + display_section("Extended Download Tests"); + test_download_binary_exact(); /* Exact byte count download */ + test_download_stream_bytes(); /* Chunked transfer encoding */ + test_download_large_https(); /* 100KB HTTPS throughput */ + test_download_binary_to_file(); /* Binary download to T:\ */ + test_download_redirect_chain(); /* Follow 3 HTTPS redirects */ + test_download_range_request(); /* HTTP 206 partial content */ + test_download_verify_content(); /* Download + verify echo */ + test_download_error_status(); /* Graceful 404 handling */ + + display_section("Extended Upload Tests"); + test_upload_urlencoded(); /* URL-encoded form POST */ + test_upload_put_large(); /* 16KB binary PUT */ + test_upload_patch(); /* HTTPS PATCH method */ + test_upload_multipart_verified(); /* Multi-file upload + verify */ + test_upload_large_json(); /* Large JSON POST */ + test_upload_from_disk(); /* Upload file read from T:\ */ + test_upload_roundtrip_verify(); /* Upload + verify echo match */ + + display_section("External Download Tests"); + test_https_file_download(); /* HTTPS download from xbxbx */ + + /* Show summary */ + display_summary(); + + /* Cleanup */ + curl_global_cleanup(); + WSACleanup(); + XNetCleanup(); + + /* Keep displaying results */ + xbox_console_println(""); + xbox_console_set_colors(CONSOLE_COLOR_GRAY, CONSOLE_COLOR_BLACK); + xbox_console_println("Test complete. Console will remain active."); + xbox_console_present(); + + /* Infinite loop to keep display visible */ + for (;;) { + Sleep(1000); + } +} diff --git a/test/test.vcproj b/test/test.vcproj new file mode 100644 index 0000000..8d1a04c --- /dev/null +++ b/test/test.vcproj @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/test_minimal.cpp b/test/test_minimal.cpp new file mode 100644 index 0000000..548ea6e --- /dev/null +++ b/test/test_minimal.cpp @@ -0,0 +1,578 @@ +/* + * Xbox libcurl + BearSSL Minimal Test + * Uses OutputDebugStringA only - no D3D console + */ + +#include +#include +#include +#include + +/* Test counters */ +static int tests_passed = 0; +static int tests_failed = 0; + +/* Debug print */ +void DebugPrint(const char *fmt, ...) +{ + char buffer[512]; + va_list args; + va_start(args, fmt); + _vsnprintf(buffer, sizeof(buffer) - 1, fmt, args); + buffer[sizeof(buffer) - 1] = '\0'; + va_end(args); + OutputDebugStringA(buffer); +} + +/* Simple write callback */ +static size_t total_bytes = 0; +size_t WriteCallback(char *buf, size_t size, size_t nmemb, void *userdata) +{ + (void)buf; + (void)userdata; + total_bytes += size * nmemb; + return size * nmemb; +} + +/* Initialize networking */ +int InitNetwork(void) +{ + XNetStartupParams xnsp; + WSADATA wsaData; + XNADDR xna; + int timeout = 0; + + memset(&xnsp, 0, sizeof(xnsp)); + xnsp.cfgSizeOfStruct = sizeof(XNetStartupParams); + xnsp.cfgFlags = XNET_STARTUP_BYPASS_SECURITY; + xnsp.cfgPrivatePoolSizeInPages = 128; + xnsp.cfgEnetReceiveQueueLength = 64; + xnsp.cfgSockMaxSockets = 64; + xnsp.cfgSockDefaultRecvBufsizeInK = 128; + xnsp.cfgSockDefaultSendBufsizeInK = 128; + + XNetStartup(&xnsp); + WSAStartup(MAKEWORD(2, 2), &wsaData); + + DebugPrint("Waiting for network...\n"); + + do { + if (XNetGetTitleXnAddr(&xna) != XNET_GET_XNADDR_PENDING) + break; + Sleep(100); + timeout += 100; + } while (timeout < 10000); + + if (timeout >= 10000) { + DebugPrint("Network timeout!\n"); + return -1; + } + + DebugPrint("Network ready. IP: %d.%d.%d.%d\n", + xna.ina.S_un.S_un_b.s_b1, + xna.ina.S_un.S_un_b.s_b2, + xna.ina.S_un.S_un_b.s_b3, + xna.ina.S_un.S_un_b.s_b4); + + return 0; +} + +/* Test helper */ +void TestResult(const char *name, int passed, const char *details) +{ + if (passed) { + DebugPrint("[PASS] %s - %s\n", name, details); + tests_passed++; + } else { + DebugPrint("[FAIL] %s - %s\n", name, details); + tests_failed++; + } +} + +/* Test: HTTP GET by IP */ +void test_http_get_ip(void) +{ + CURL *curl; + CURLcode res; + long http_code = 0; + char details[128] = {0}; + + DebugPrint("\n--- Test: HTTP GET (by IP) ---\n"); + total_bytes = 0; + + curl = curl_easy_init(); + if (!curl) { + TestResult("HTTP GET IP", 0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "http://1.1.1.1/"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15L); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && http_code >= 200 && http_code < 400) { + _snprintf(details, sizeof(details) - 1, "HTTP %ld, %u bytes", http_code, (unsigned)total_bytes); + TestResult("HTTP GET IP", 1, details); + } else { + _snprintf(details, sizeof(details) - 1, "%s (HTTP %ld)", curl_easy_strerror(res), http_code); + TestResult("HTTP GET IP", 0, details); + } +} + +/* Test: HTTP GET with DNS */ +void test_http_get_dns(void) +{ + CURL *curl; + CURLcode res; + long http_code = 0; + char details[128] = {0}; + + DebugPrint("\n--- Test: HTTP GET (DNS) ---\n"); + total_bytes = 0; + + curl = curl_easy_init(); + if (!curl) { + TestResult("HTTP GET DNS", 0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/get"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15L); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && http_code == 200) { + _snprintf(details, sizeof(details) - 1, "HTTP %ld, %u bytes", http_code, (unsigned)total_bytes); + TestResult("HTTP GET DNS", 1, details); + } else { + _snprintf(details, sizeof(details) - 1, "%s (HTTP %ld)", curl_easy_strerror(res), http_code); + TestResult("HTTP GET DNS", 0, details); + } +} + +/* Test: HTTPS GET (no verify) */ +void test_https_get_no_verify(void) +{ + CURL *curl; + CURLcode res; + long http_code = 0; + char details[128] = {0}; + + DebugPrint("\n--- Test: HTTPS GET (no verify) ---\n"); + total_bytes = 0; + + curl = curl_easy_init(); + if (!curl) { + TestResult("HTTPS GET (no verify)", 0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "https://1.1.1.1/"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && http_code >= 200 && http_code < 400) { + _snprintf(details, sizeof(details) - 1, "HTTPS %ld, %u bytes, TLS OK", http_code, (unsigned)total_bytes); + TestResult("HTTPS GET (no verify)", 1, details); + } else { + _snprintf(details, sizeof(details) - 1, "%s (HTTP %ld)", curl_easy_strerror(res), http_code); + TestResult("HTTPS GET (no verify)", 0, details); + } +} + +/* Test: HTTPS GET with DNS (no verify) */ +void test_https_get_dns(void) +{ + CURL *curl; + CURLcode res; + long http_code = 0; + char details[128] = {0}; + + DebugPrint("\n--- Test: HTTPS GET DNS (no verify) ---\n"); + total_bytes = 0; + + curl = curl_easy_init(); + if (!curl) { + TestResult("HTTPS GET DNS", 0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/get"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && http_code == 200) { + _snprintf(details, sizeof(details) - 1, "HTTPS %ld, %u bytes, TLS OK", http_code, (unsigned)total_bytes); + TestResult("HTTPS GET DNS", 1, details); + } else { + _snprintf(details, sizeof(details) - 1, "%s (HTTP %ld)", curl_easy_strerror(res), http_code); + TestResult("HTTPS GET DNS", 0, details); + } +} + +/* Test: HTTP POST */ +void test_http_post(void) +{ + CURL *curl; + CURLcode res; + long http_code = 0; + char details[128] = {0}; + const char *post_data = "name=XboxCurl&test=1"; + + DebugPrint("\n--- Test: HTTP POST ---\n"); + total_bytes = 0; + + curl = curl_easy_init(); + if (!curl) { + TestResult("HTTP POST", 0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/post"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && http_code == 200) { + _snprintf(details, sizeof(details) - 1, "HTTP %ld, %u bytes", http_code, (unsigned)total_bytes); + TestResult("HTTP POST", 1, details); + } else { + _snprintf(details, sizeof(details) - 1, "%s (HTTP %ld)", curl_easy_strerror(res), http_code); + TestResult("HTTP POST", 0, details); + } +} + +/* Test: HTTPS POST */ +void test_https_post(void) +{ + CURL *curl; + CURLcode res; + long http_code = 0; + char details[128] = {0}; + const char *post_data = "{\"test\":\"XboxCurl\",\"secure\":true}"; + struct curl_slist *headers = NULL; + + DebugPrint("\n--- Test: HTTPS POST (JSON) ---\n"); + total_bytes = 0; + + curl = curl_easy_init(); + if (!curl) { + TestResult("HTTPS POST", 0, "curl_easy_init failed"); + return; + } + + headers = curl_slist_append(headers, "Content-Type: application/json"); + + curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/post"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && http_code == 200) { + _snprintf(details, sizeof(details) - 1, "HTTPS %ld, %u bytes, TLS OK", http_code, (unsigned)total_bytes); + TestResult("HTTPS POST", 1, details); + } else { + _snprintf(details, sizeof(details) - 1, "%s (HTTP %ld)", curl_easy_strerror(res), http_code); + TestResult("HTTPS POST", 0, details); + } +} + +/* Test: HTTPS GET with certificate verification ENABLED + * This validates the full trust anchor chain works end-to-end. + * Uses a well-known public site with a standard CA-signed certificate. + */ +void test_https_get_verified(void) +{ + CURL *curl; + CURLcode res; + long http_code = 0; + char details[128] = {0}; + + DebugPrint("\n--- Test: HTTPS GET (verified) ---\n"); + total_bytes = 0; + + curl = curl_easy_init(); + if (!curl) { + TestResult("HTTPS GET (verified)", 0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "https://one.one.one.one/"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15L); + /* Certificate verification ON - this is the whole point of this test */ + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && http_code >= 200 && http_code < 400) { + _snprintf(details, sizeof(details) - 1, "HTTPS %ld, %u bytes, cert VERIFIED", http_code, (unsigned)total_bytes); + TestResult("HTTPS GET (verified)", 1, details); + } else { + _snprintf(details, sizeof(details) - 1, "%s (HTTP %ld)", curl_easy_strerror(res), http_code); + TestResult("HTTPS GET (verified)", 0, details); + } +} + +/* Test: HTTP Redirect */ +void test_http_redirect(void) +{ + CURL *curl; + CURLcode res; + long http_code = 0; + long redirect_count = 0; + char details[128] = {0}; + + DebugPrint("\n--- Test: HTTP Redirect ---\n"); + total_bytes = 0; + + curl = curl_easy_init(); + if (!curl) { + TestResult("HTTP Redirect", 0, "curl_easy_init failed"); + return; + } + + curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/redirect/2"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5L); + + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &redirect_count); + curl_easy_cleanup(curl); + + if (res == CURLE_OK && http_code == 200 && redirect_count >= 2) { + _snprintf(details, sizeof(details) - 1, "HTTP %ld after %ld redirects", http_code, redirect_count); + TestResult("HTTP Redirect", 1, details); + } else { + _snprintf(details, sizeof(details) - 1, "%s (HTTP %ld, %ld redirects)", curl_easy_strerror(res), http_code, redirect_count); + TestResult("HTTP Redirect", 0, details); + } +} + +/* Test: Connection Timeout */ +void test_timeout(void) +{ + CURL *curl; + CURLcode res; + DWORD start, elapsed; + char details[128] = {0}; + + DebugPrint("\n--- Test: Connection Timeout ---\n"); + + curl = curl_easy_init(); + if (!curl) { + TestResult("Timeout", 0, "curl_easy_init failed"); + return; + } + + /* Non-routable IP to force timeout */ + curl_easy_setopt(curl, CURLOPT_URL, "http://10.255.255.1/"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3L); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L); + + start = GetTickCount(); + res = curl_easy_perform(curl); + elapsed = GetTickCount() - start; + curl_easy_cleanup(curl); + + if (res == CURLE_OPERATION_TIMEDOUT || res == CURLE_COULDNT_CONNECT) { + _snprintf(details, sizeof(details) - 1, "Timed out after %lu ms (expected)", elapsed); + TestResult("Timeout", 1, details); + } else { + _snprintf(details, sizeof(details) - 1, "%s (%lu ms)", curl_easy_strerror(res), elapsed); + TestResult("Timeout", 1, details); /* Other errors acceptable */ + } +} + +/* Test: D3D Initialization */ +void test_d3d_init(void) +{ + IDirect3D8 *d3d = NULL; + IDirect3DDevice8 *device = NULL; + D3DPRESENT_PARAMETERS d3dpp; + HRESULT hr; + char details[128] = {0}; + + DebugPrint("\n--- Test: D3D Initialization ---\n"); + + d3d = Direct3DCreate8(D3D_SDK_VERSION); + if (!d3d) { + TestResult("D3D Create", 0, "Direct3DCreate8 failed"); + return; + } + TestResult("D3D Create", 1, "Direct3DCreate8 OK"); + + ZeroMemory(&d3dpp, sizeof(d3dpp)); + d3dpp.BackBufferWidth = 640; + d3dpp.BackBufferHeight = 480; + d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; /* Standard swizzled format */ + d3dpp.BackBufferCount = 1; + d3dpp.EnableAutoDepthStencil = FALSE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.FullScreen_RefreshRateInHz = 60; + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; + + hr = d3d->CreateDevice(0, D3DDEVTYPE_HAL, NULL, + D3DCREATE_HARDWARE_VERTEXPROCESSING, + &d3dpp, &device); + if (FAILED(hr)) { + _snprintf(details, sizeof(details) - 1, "CreateDevice failed: 0x%08X", hr); + TestResult("D3D Device", 0, details); + d3d->Release(); + return; + } + TestResult("D3D Device", 1, "CreateDevice OK"); + + /* Clear with BeginScene/EndScene for proper GPU sync */ + hr = device->BeginScene(); + if (FAILED(hr)) { + _snprintf(details, sizeof(details) - 1, "BeginScene failed: 0x%08X", hr); + TestResult("D3D BeginScene", 0, details); + } + + hr = device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0); + if (FAILED(hr)) { + _snprintf(details, sizeof(details) - 1, "Clear failed: 0x%08X", hr); + TestResult("D3D Clear", 0, details); + } else { + TestResult("D3D Clear", 1, "Clear OK (blue)"); + } + + device->EndScene(); + + hr = device->Present(NULL, NULL, NULL, NULL); + if (FAILED(hr)) { + _snprintf(details, sizeof(details) - 1, "Present failed: 0x%08X", hr); + TestResult("D3D Present", 0, details); + } else { + TestResult("D3D Present", 1, "Present OK - should see BLUE"); + } + + /* Wait to see blue screen */ + Sleep(3000); + + /* Second frame - green */ + device->BeginScene(); + device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0); + device->EndScene(); + device->Present(NULL, NULL, NULL, NULL); + DebugPrint("Should see GREEN now\n"); + Sleep(2000); + + /* Clean up */ + device->Release(); + d3d->Release(); + + TestResult("D3D Cleanup", 1, "Released D3D resources"); +} + +void __cdecl main(void) +{ + DebugPrint("\n"); + DebugPrint("========================================\n"); + DebugPrint(" Xbox libcurl + BearSSL Test Suite\n"); + DebugPrint("========================================\n"); + DebugPrint("libcurl version: %s\n", curl_version()); + + /* D3D Test first */ + DebugPrint("\n=== D3D TESTS ===\n"); + test_d3d_init(); + + /* Network init */ + if (InitNetwork() != 0) { + DebugPrint("FATAL: Network init failed\n"); + goto done; + } + + DebugPrint("\nInitializing libcurl...\n"); + if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) { + DebugPrint("FATAL: curl_global_init failed\n"); + goto done; + } + DebugPrint("curl_global_init OK\n"); + + /* HTTP Tests */ + DebugPrint("\n=== HTTP TESTS ===\n"); + test_http_get_ip(); + test_http_get_dns(); + test_http_post(); + test_http_redirect(); + + /* HTTPS Tests */ + DebugPrint("\n=== HTTPS TESTS ===\n"); + test_https_get_no_verify(); + test_https_get_dns(); + test_https_post(); + test_https_get_verified(); + + /* Other Tests */ + DebugPrint("\n=== OTHER TESTS ===\n"); + test_timeout(); + + curl_global_cleanup(); + +done: + DebugPrint("\n========================================\n"); + DebugPrint(" TEST RESULTS\n"); + DebugPrint("========================================\n"); + DebugPrint(" Passed: %d\n", tests_passed); + DebugPrint(" Failed: %d\n", tests_failed); + DebugPrint(" Total: %d\n", tests_passed + tests_failed); + DebugPrint("========================================\n"); + + if (tests_failed == 0) { + DebugPrint(" ALL TESTS PASSED!\n"); + } else { + DebugPrint(" SOME TESTS FAILED\n"); + } + DebugPrint("========================================\n"); + + DebugPrint("\nTest complete. Looping forever.\n"); + while (1) Sleep(1000); +} diff --git a/test/test_minimal.vcproj b/test/test_minimal.vcproj new file mode 100644 index 0000000..acae4ba --- /dev/null +++ b/test/test_minimal.vcproj @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/xbox_console.cpp b/test/xbox_console.cpp new file mode 100644 index 0000000..b2d37b5 --- /dev/null +++ b/test/xbox_console.cpp @@ -0,0 +1,570 @@ +/* + * Xbox Console Text Renderer Implementation + * Direct framebuffer text rendering for Xbox + * + * Based on Microsoft Xbox SDK patterns for direct surface access + */ + +#include "xbox_console.h" +#include +#include +#include + +/* 8x8 bitmap font - ASCII 32-127 */ +static const unsigned char font_8x8[96][8] = { + /* Space (32) */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* ! (33) */ + {0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00}, + /* " (34) */ + {0x6C, 0x6C, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* # (35) */ + {0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00}, + /* $ (36) */ + {0x18, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x18, 0x00}, + /* % (37) */ + {0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00}, + /* & (38) */ + {0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00}, + /* ' (39) */ + {0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* ( (40) */ + {0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00}, + /* ) (41) */ + {0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00}, + /* * (42) */ + {0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, + /* + (43) */ + {0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00}, + /* , (44) */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30}, + /* - (45) */ + {0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00}, + /* . (46) */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00}, + /* / (47) */ + {0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00}, + /* 0 (48) */ + {0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00}, + /* 1 (49) */ + {0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00}, + /* 2 (50) */ + {0x7C, 0xC6, 0x06, 0x1C, 0x70, 0xC6, 0xFE, 0x00}, + /* 3 (51) */ + {0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00}, + /* 4 (52) */ + {0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00}, + /* 5 (53) */ + {0xFE, 0xC0, 0xFC, 0x06, 0x06, 0xC6, 0x7C, 0x00}, + /* 6 (54) */ + {0x38, 0x60, 0xC0, 0xFC, 0xC6, 0xC6, 0x7C, 0x00}, + /* 7 (55) */ + {0xFE, 0xC6, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00}, + /* 8 (56) */ + {0x7C, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0x7C, 0x00}, + /* 9 (57) */ + {0x7C, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00}, + /* : (58) */ + {0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00}, + /* ; (59) */ + {0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30}, + /* < (60) */ + {0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00}, + /* = (61) */ + {0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00}, + /* > (62) */ + {0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00}, + /* ? (63) */ + {0x7C, 0xC6, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00}, + /* @ (64) */ + {0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00}, + /* A (65) */ + {0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00}, + /* B (66) */ + {0xFC, 0xC6, 0xC6, 0xFC, 0xC6, 0xC6, 0xFC, 0x00}, + /* C (67) */ + {0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00}, + /* D (68) */ + {0xF8, 0xCC, 0xC6, 0xC6, 0xC6, 0xCC, 0xF8, 0x00}, + /* E (69) */ + {0xFE, 0xC0, 0xC0, 0xF8, 0xC0, 0xC0, 0xFE, 0x00}, + /* F (70) */ + {0xFE, 0xC0, 0xC0, 0xF8, 0xC0, 0xC0, 0xC0, 0x00}, + /* G (71) */ + {0x7C, 0xC6, 0xC0, 0xCE, 0xC6, 0xC6, 0x7E, 0x00}, + /* H (72) */ + {0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00}, + /* I (73) */ + {0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00}, + /* J (74) */ + {0x1E, 0x06, 0x06, 0x06, 0xC6, 0xC6, 0x7C, 0x00}, + /* K (75) */ + {0xC6, 0xCC, 0xD8, 0xF0, 0xD8, 0xCC, 0xC6, 0x00}, + /* L (76) */ + {0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0x00}, + /* M (77) */ + {0xC6, 0xEE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0x00}, + /* N (78) */ + {0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00}, + /* O (79) */ + {0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00}, + /* P (80) */ + {0xFC, 0xC6, 0xC6, 0xFC, 0xC0, 0xC0, 0xC0, 0x00}, + /* Q (81) */ + {0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0xDE, 0x7C, 0x06}, + /* R (82) */ + {0xFC, 0xC6, 0xC6, 0xFC, 0xD8, 0xCC, 0xC6, 0x00}, + /* S (83) */ + {0x7C, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0x7C, 0x00}, + /* T (84) */ + {0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00}, + /* U (85) */ + {0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00}, + /* V (86) */ + {0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00}, + /* W (87) */ + {0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00}, + /* X (88) */ + {0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00}, + /* Y (89) */ + {0xC3, 0xC3, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00}, + /* Z (90) */ + {0xFE, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xFE, 0x00}, + /* [ (91) */ + {0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00}, + /* \ (92) */ + {0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00}, + /* ] (93) */ + {0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00}, + /* ^ (94) */ + {0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00}, + /* _ (95) */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, + /* ` (96) */ + {0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* a (97) */ + {0x00, 0x00, 0x7C, 0x06, 0x7E, 0xC6, 0x7E, 0x00}, + /* b (98) */ + {0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xFC, 0x00}, + /* c (99) */ + {0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x00}, + /* d (100) */ + {0x06, 0x06, 0x7E, 0xC6, 0xC6, 0xC6, 0x7E, 0x00}, + /* e (101) */ + {0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0x7C, 0x00}, + /* f (102) */ + {0x1C, 0x36, 0x30, 0x78, 0x30, 0x30, 0x30, 0x00}, + /* g (103) */ + {0x00, 0x00, 0x7E, 0xC6, 0xC6, 0x7E, 0x06, 0x7C}, + /* h (104) */ + {0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x00}, + /* i (105) */ + {0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00}, + /* j (106) */ + {0x06, 0x00, 0x0E, 0x06, 0x06, 0xC6, 0xC6, 0x7C}, + /* k (107) */ + {0xC0, 0xC0, 0xC6, 0xCC, 0xF8, 0xCC, 0xC6, 0x00}, + /* l (108) */ + {0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00}, + /* m (109) */ + {0x00, 0x00, 0xEC, 0xFE, 0xD6, 0xC6, 0xC6, 0x00}, + /* n (110) */ + {0x00, 0x00, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x00}, + /* o (111) */ + {0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00}, + /* p (112) */ + {0x00, 0x00, 0xFC, 0xC6, 0xC6, 0xFC, 0xC0, 0xC0}, + /* q (113) */ + {0x00, 0x00, 0x7E, 0xC6, 0xC6, 0x7E, 0x06, 0x06}, + /* r (114) */ + {0x00, 0x00, 0xDC, 0xE6, 0xC0, 0xC0, 0xC0, 0x00}, + /* s (115) */ + {0x00, 0x00, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x00}, + /* t (116) */ + {0x30, 0x30, 0x7C, 0x30, 0x30, 0x36, 0x1C, 0x00}, + /* u (117) */ + {0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x00}, + /* v (118) */ + {0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00}, + /* w (119) */ + {0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00}, + /* x (120) */ + {0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00}, + /* y (121) */ + {0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x7C}, + /* z (122) */ + {0x00, 0x00, 0xFE, 0x0C, 0x38, 0x60, 0xFE, 0x00}, + /* { (123) */ + {0x0E, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0E, 0x00}, + /* | (124) */ + {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, + /* } (125) */ + {0x70, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x70, 0x00}, + /* ~ (126) */ + {0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* DEL (127) - filled block */ + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} +}; + +/* Console state */ +static struct { + IDirect3D8 *d3d; + IDirect3DDevice8 *device; + int screen_width; + int screen_height; + int cols; + int rows; + int cursor_x; + int cursor_y; + unsigned int fg_color; + unsigned int bg_color; + int initialized; + /* Off-screen buffer for content (we redraw each frame) */ + unsigned int *buffer; + int buffer_size; +} console = {0}; + +#define CHAR_WIDTH 8 +#define CHAR_HEIGHT 8 + +/* Internal: Draw a single character to our buffer */ +static void draw_char_to_buffer(int cx, int cy, char c, unsigned int fg, unsigned int bg) +{ + int idx; + int row, col; + const unsigned char *glyph; + int px, py; + unsigned int *pixel; + + if (!console.buffer) return; + + px = cx * CHAR_WIDTH; + py = cy * CHAR_HEIGHT; + + if (px < 0 || py < 0) return; + if (px + CHAR_WIDTH > console.screen_width) return; + if (py + CHAR_HEIGHT > console.screen_height) return; + + /* Get glyph for character */ + idx = (int)(unsigned char)c - 32; + if (idx < 0 || idx >= 96) idx = 0; /* Default to space */ + glyph = font_8x8[idx]; + + /* Draw the character to buffer */ + for (row = 0; row < CHAR_HEIGHT; row++) { + pixel = console.buffer + (py + row) * console.screen_width + px; + for (col = 0; col < CHAR_WIDTH; col++) { + if (glyph[row] & (0x80 >> col)) { + *pixel = fg; + } else { + *pixel = bg; + } + pixel++; + } + } +} + +int xbox_console_init(int width, int height) +{ + D3DPRESENT_PARAMETERS d3dpp; + HRESULT hr; + + if (console.initialized) return 1; + + console.screen_width = width; + console.screen_height = height; + console.cols = width / CHAR_WIDTH; + console.rows = height / CHAR_HEIGHT; + console.cursor_x = 0; + console.cursor_y = 0; + console.fg_color = CONSOLE_COLOR_WHITE; + console.bg_color = CONSOLE_COLOR_BLACK; + + /* Allocate off-screen buffer */ + console.buffer_size = width * height * sizeof(unsigned int); + console.buffer = (unsigned int *)malloc(console.buffer_size); + if (!console.buffer) { + OutputDebugStringA("Failed to allocate console buffer\n"); + return 0; + } + + /* Create Direct3D object */ + console.d3d = Direct3DCreate8(D3D_SDK_VERSION); + if (!console.d3d) { + OutputDebugStringA("Failed to create Direct3D8\n"); + free(console.buffer); + console.buffer = NULL; + return 0; + } + + /* Setup presentation parameters - match Microsoft SDK patterns */ + ZeroMemory(&d3dpp, sizeof(d3dpp)); + d3dpp.BackBufferWidth = width; + d3dpp.BackBufferHeight = height; + d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; /* Standard swizzled format */ + d3dpp.BackBufferCount = 1; + d3dpp.EnableAutoDepthStencil = FALSE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.FullScreen_RefreshRateInHz = 60; + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; + + /* Create device */ + hr = console.d3d->CreateDevice(0, D3DDEVTYPE_HAL, NULL, + D3DCREATE_HARDWARE_VERTEXPROCESSING, + &d3dpp, &console.device); + if (FAILED(hr)) { + char buf[64]; + _snprintf(buf, sizeof(buf) - 1, "Failed to create D3D device: 0x%08X\n", hr); + buf[sizeof(buf) - 1] = '\0'; + OutputDebugStringA(buf); + console.d3d->Release(); + console.d3d = NULL; + free(console.buffer); + console.buffer = NULL; + return 0; + } + + console.initialized = 1; + + /* Clear buffer to background color */ + xbox_console_clear(console.bg_color); + + return 1; +} + +void xbox_console_shutdown(void) +{ + if (!console.initialized) return; + + if (console.device) { + console.device->Release(); + console.device = NULL; + } + if (console.d3d) { + console.d3d->Release(); + console.d3d = NULL; + } + if (console.buffer) { + free(console.buffer); + console.buffer = NULL; + } + + console.initialized = 0; +} + +void xbox_console_clear(unsigned int color) +{ + int i; + int total_pixels; + + if (!console.initialized || !console.buffer) return; + + total_pixels = console.screen_width * console.screen_height; + for (i = 0; i < total_pixels; i++) { + console.buffer[i] = color; + } + + console.cursor_x = 0; + console.cursor_y = 0; + console.bg_color = color; +} + +void xbox_console_set_colors(unsigned int foreground, unsigned int background) +{ + console.fg_color = foreground; + console.bg_color = background; +} + +void xbox_console_set_cursor(int x, int y) +{ + if (x >= 0 && x < console.cols) console.cursor_x = x; + if (y >= 0 && y < console.rows) console.cursor_y = y; +} + +void xbox_console_get_cursor(int *x, int *y) +{ + if (x) *x = console.cursor_x; + if (y) *y = console.cursor_y; +} + +void xbox_console_scroll(void) +{ + int row; + unsigned int *src, *dst; + int line_bytes; + + if (!console.initialized || !console.buffer) return; + + /* Move all lines up by one character row */ + line_bytes = console.screen_width * CHAR_HEIGHT * sizeof(unsigned int); + for (row = 0; row < console.rows - 1; row++) { + dst = console.buffer + row * CHAR_HEIGHT * console.screen_width; + src = console.buffer + (row + 1) * CHAR_HEIGHT * console.screen_width; + memcpy(dst, src, line_bytes); + } + + /* Clear the last line */ + dst = console.buffer + (console.rows - 1) * CHAR_HEIGHT * console.screen_width; + for (row = 0; row < CHAR_HEIGHT * console.screen_width; row++) { + dst[row] = console.bg_color; + } +} + +void xbox_console_putchar(char c) +{ + if (!console.initialized) return; + + /* Handle special characters */ + switch (c) { + case '\n': + console.cursor_x = 0; + console.cursor_y++; + break; + case '\r': + console.cursor_x = 0; + break; + case '\t': + console.cursor_x = (console.cursor_x + 4) & ~3; + break; + case '\b': + if (console.cursor_x > 0) console.cursor_x--; + break; + default: + if (c >= 32 && c < 127) { + draw_char_to_buffer(console.cursor_x, console.cursor_y, + c, console.fg_color, console.bg_color); + console.cursor_x++; + } + break; + } + + /* Handle line wrap */ + if (console.cursor_x >= console.cols) { + console.cursor_x = 0; + console.cursor_y++; + } + + /* Handle scroll */ + if (console.cursor_y >= console.rows) { + xbox_console_scroll(); + console.cursor_y = console.rows - 1; + } +} + +void xbox_console_print(const char *str) +{ + if (!str) return; + while (*str) { + xbox_console_putchar(*str++); + } +} + +void xbox_console_println(const char *str) +{ + xbox_console_print(str); + xbox_console_putchar('\n'); +} + +void xbox_console_printf(const char *format, ...) +{ + char buffer[512]; + va_list args; + + va_start(args, format); + _vsnprintf(buffer, sizeof(buffer) - 1, format, args); + buffer[sizeof(buffer) - 1] = '\0'; + va_end(args); + + xbox_console_print(buffer); +} + +void xbox_console_draw_line(char c, int count) +{ + int i; + for (i = 0; i < count && console.cursor_x < console.cols; i++) { + xbox_console_putchar(c); + } +} + +void xbox_console_draw_box(int x1, int y1, int x2, int y2) +{ + int i; + + /* Top border */ + xbox_console_set_cursor(x1, y1); + xbox_console_putchar('+'); + for (i = x1 + 1; i < x2; i++) { + xbox_console_putchar('-'); + } + xbox_console_putchar('+'); + + /* Side borders */ + for (i = y1 + 1; i < y2; i++) { + xbox_console_set_cursor(x1, i); + xbox_console_putchar('|'); + xbox_console_set_cursor(x2, i); + xbox_console_putchar('|'); + } + + /* Bottom border */ + xbox_console_set_cursor(x1, y2); + xbox_console_putchar('+'); + for (i = x1 + 1; i < x2; i++) { + xbox_console_putchar('-'); + } + xbox_console_putchar('+'); +} + +void xbox_console_present(void) +{ + IDirect3DSurface8 *backbuffer = NULL; + D3DLOCKED_RECT locked; + HRESULT hr; + int y; + unsigned int *src; + unsigned char *dst; + + if (!console.initialized || !console.device || !console.buffer) return; + + /* Get backbuffer fresh each frame (Microsoft pattern) */ + hr = console.device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); + if (FAILED(hr) || !backbuffer) { + OutputDebugStringA("GetBackBuffer failed\n"); + return; + } + + /* Lock with D3DLOCK_TILED for linear access to swizzled surface */ + hr = backbuffer->LockRect(&locked, NULL, D3DLOCK_TILED); + if (FAILED(hr)) { + char buf[64]; + _snprintf(buf, sizeof(buf) - 1, "LockRect failed: 0x%08X\n", hr); + buf[sizeof(buf) - 1] = '\0'; + OutputDebugStringA(buf); + backbuffer->Release(); + return; + } + + /* Copy our buffer to backbuffer, respecting pitch */ + src = console.buffer; + dst = (unsigned char *)locked.pBits; + for (y = 0; y < console.screen_height; y++) { + memcpy(dst, src, console.screen_width * sizeof(unsigned int)); + src += console.screen_width; + dst += locked.Pitch; + } + + /* Unlock before present */ + backbuffer->UnlockRect(); + + /* Release backbuffer reference */ + backbuffer->Release(); + + /* Present */ + console.device->Present(NULL, NULL, NULL, NULL); +} + +void xbox_console_get_size(int *cols, int *rows) +{ + if (cols) *cols = console.cols; + if (rows) *rows = console.rows; +} diff --git a/test/xbox_console.h b/test/xbox_console.h new file mode 100644 index 0000000..544a1b9 --- /dev/null +++ b/test/xbox_console.h @@ -0,0 +1,85 @@ +/* + * Xbox Console Text Renderer + * Direct framebuffer text rendering for Xbox + * + * Features: + * - 8x8 bitmap font + * - Color support (ARGB) + * - Automatic scrolling + * - No external dependencies + */ + +#ifndef XBOX_CONSOLE_H +#define XBOX_CONSOLE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Color definitions (ARGB format) */ +#define CONSOLE_COLOR_BLACK 0xFF000000 +#define CONSOLE_COLOR_WHITE 0xFFFFFFFF +#define CONSOLE_COLOR_RED 0xFFFF0000 +#define CONSOLE_COLOR_GREEN 0xFF00FF00 +#define CONSOLE_COLOR_BLUE 0xFF0000FF +#define CONSOLE_COLOR_YELLOW 0xFFFFFF00 +#define CONSOLE_COLOR_CYAN 0xFF00FFFF +#define CONSOLE_COLOR_MAGENTA 0xFFFF00FF +#define CONSOLE_COLOR_ORANGE 0xFFFF8000 +#define CONSOLE_COLOR_GRAY 0xFF808080 +#define CONSOLE_COLOR_DARKGRAY 0xFF404040 +#define CONSOLE_COLOR_LIGHTGRAY 0xFFC0C0C0 + +/* Initialize console with specified resolution */ +/* width/height: 640x480 or 720x480 typically */ +int xbox_console_init(int width, int height); + +/* Clean up console resources */ +void xbox_console_shutdown(void); + +/* Clear screen with specified color */ +void xbox_console_clear(unsigned int color); + +/* Set text colors */ +void xbox_console_set_colors(unsigned int foreground, unsigned int background); + +/* Set cursor position (in character cells) */ +void xbox_console_set_cursor(int x, int y); + +/* Get current cursor position */ +void xbox_console_get_cursor(int *x, int *y); + +/* Print a single character */ +void xbox_console_putchar(char c); + +/* Print a string */ +void xbox_console_print(const char *str); + +/* Print a string with newline */ +void xbox_console_println(const char *str); + +/* Printf-style formatted output */ +void xbox_console_printf(const char *format, ...); + +/* Draw a horizontal line of characters */ +void xbox_console_draw_line(char c, int count); + +/* Draw a box around area (x1,y1) to (x2,y2) */ +void xbox_console_draw_box(int x1, int y1, int x2, int y2); + +/* Present/swap buffers (call after drawing to make visible) */ +void xbox_console_present(void); + +/* Scroll the console up by one line */ +void xbox_console_scroll(void); + +/* Get console dimensions in characters */ +void xbox_console_get_size(int *cols, int *rows); + +#ifdef __cplusplus +} +#endif + +#endif /* XBOX_CONSOLE_H */